summaryrefslogtreecommitdiff
path: root/chromium/net/third_party/quiche/src/quic
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/net/third_party/quiche/src/quic')
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/batch_writer/quic_batch_writer_base.cc181
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/batch_writer/quic_batch_writer_base.h154
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/batch_writer/quic_batch_writer_buffer.cc156
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/batch_writer/quic_batch_writer_buffer.h95
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/batch_writer/quic_batch_writer_buffer_test.cc282
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/batch_writer/quic_batch_writer_test.cc77
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/batch_writer/quic_batch_writer_test.h287
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/batch_writer/quic_gso_batch_writer.cc164
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/batch_writer/quic_gso_batch_writer.h117
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/batch_writer/quic_gso_batch_writer_test.cc472
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/batch_writer/quic_sendmmsg_batch_writer.cc84
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/batch_writer/quic_sendmmsg_batch_writer.h35
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/batch_writer/quic_sendmmsg_batch_writer_test.cc15
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/chlo_extractor.cc364
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/chlo_extractor.h45
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/chlo_extractor_test.cc179
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/congestion_control/bandwidth_sampler.cc589
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/congestion_control/bandwidth_sampler.h627
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/congestion_control/bandwidth_sampler_test.cc889
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/congestion_control/bbr2_drain.cc62
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/congestion_control/bbr2_drain.h61
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/congestion_control/bbr2_misc.cc454
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/congestion_control/bbr2_misc.h674
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/congestion_control/bbr2_probe_bw.cc677
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/congestion_control/bbr2_probe_bw.h142
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/congestion_control/bbr2_probe_rtt.cc83
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/congestion_control/bbr2_probe_rtt.h60
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/congestion_control/bbr2_sender.cc578
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/congestion_control/bbr2_sender.h216
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/congestion_control/bbr2_simulator_test.cc2296
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/congestion_control/bbr2_startup.cc157
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/congestion_control/bbr2_startup.h71
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/congestion_control/bbr_sender.cc917
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/congestion_control/bbr_sender.h396
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/congestion_control/bbr_sender_test.cc1332
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/congestion_control/cubic_bytes.cc191
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/congestion_control/cubic_bytes.h102
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/congestion_control/cubic_bytes_test.cc387
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/congestion_control/general_loss_algorithm.cc196
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/congestion_control/general_loss_algorithm.h138
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/congestion_control/general_loss_algorithm_test.cc489
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/congestion_control/hybrid_slow_start.cc104
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/congestion_control/hybrid_slow_start.h83
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/congestion_control/hybrid_slow_start_test.cc76
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/congestion_control/loss_detection_interface.h75
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/congestion_control/pacing_sender.cc177
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/congestion_control/pacing_sender.h116
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/congestion_control/pacing_sender_test.cc597
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/congestion_control/prr_sender.cc62
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/congestion_control/prr_sender.h43
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/congestion_control/prr_sender_test.cc123
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/congestion_control/rtt_stats.cc144
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/congestion_control/rtt_stats.h131
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/congestion_control/rtt_stats_test.cc242
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/congestion_control/send_algorithm_interface.cc61
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/congestion_control/send_algorithm_interface.h177
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/congestion_control/send_algorithm_test.cc373
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/congestion_control/tcp_cubic_sender_bytes.cc431
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/congestion_control/tcp_cubic_sender_bytes.h174
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/congestion_control/tcp_cubic_sender_bytes_test.cc845
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/congestion_control/uber_loss_algorithm.cc215
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/congestion_control/uber_loss_algorithm.h140
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/congestion_control/uber_loss_algorithm_test.cc361
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/congestion_control/windowed_filter.h164
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/congestion_control/windowed_filter_test.cc388
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/aead_base_decrypter.cc214
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/aead_base_decrypter.h74
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/aead_base_encrypter.cc188
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/aead_base_encrypter.h80
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/aes_128_gcm_12_decrypter.cc35
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/aes_128_gcm_12_decrypter.h38
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/aes_128_gcm_12_decrypter_test.cc288
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/aes_128_gcm_12_encrypter.cc30
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/aes_128_gcm_12_encrypter.h34
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/aes_128_gcm_12_encrypter_test.cc244
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/aes_128_gcm_decrypter.cc37
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/aes_128_gcm_decrypter.h36
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/aes_128_gcm_decrypter_test.cc291
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/aes_128_gcm_encrypter.cc30
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/aes_128_gcm_encrypter.h32
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/aes_128_gcm_encrypter_test.cc273
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/aes_256_gcm_decrypter.cc37
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/aes_256_gcm_decrypter.h36
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/aes_256_gcm_decrypter_test.cc297
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/aes_256_gcm_encrypter.cc30
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/aes_256_gcm_encrypter.h32
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/aes_256_gcm_encrypter_test.cc259
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/aes_base_decrypter.cc52
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/aes_base_decrypter.h33
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/aes_base_encrypter.cc48
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/aes_base_encrypter.h32
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/boring_utils.h34
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/cert_compressor.cc660
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/cert_compressor.h56
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/cert_compressor_test.cc137
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/certificate_util.cc280
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/certificate_util.h46
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/certificate_util_test.cc49
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/certificate_view.cc650
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/certificate_view.h151
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/certificate_view_der_fuzzer.cc19
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/certificate_view_pem_fuzzer.cc18
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/certificate_view_test.cc214
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/chacha20_poly1305_decrypter.cc43
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/chacha20_poly1305_decrypter.h41
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/chacha20_poly1305_decrypter_test.cc178
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/chacha20_poly1305_encrypter.cc37
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/chacha20_poly1305_encrypter.h38
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/chacha20_poly1305_encrypter_test.cc159
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/chacha20_poly1305_tls_decrypter.cc45
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/chacha20_poly1305_tls_decrypter.h39
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/chacha20_poly1305_tls_decrypter_test.cc188
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/chacha20_poly1305_tls_encrypter.cc37
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/chacha20_poly1305_tls_encrypter.h36
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/chacha20_poly1305_tls_encrypter_test.cc173
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/chacha_base_decrypter.cc44
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/chacha_base_decrypter.h31
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/chacha_base_encrypter.cc41
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/chacha_base_encrypter.h30
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/channel_id.cc90
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/channel_id.h49
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/channel_id_test.cc287
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/client_proof_source.cc62
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/client_proof_source.h70
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/client_proof_source_test.cc212
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/common_cert_set.cc165
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/common_cert_set.h47
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/common_cert_set_2.c122
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/common_cert_set_2a.inc5622
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/common_cert_set_2b.inc5739
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/common_cert_set_3.c118
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/common_cert_set_3a.inc5033
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/common_cert_set_3b.inc5717
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/common_cert_set_empty.cc52
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/common_cert_set_test.cc253
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/crypto_framer.cc358
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/crypto_framer.h137
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/crypto_framer_test.cc466
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/crypto_handshake.cc41
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/crypto_handshake.h193
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/crypto_handshake_message.cc382
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/crypto_handshake_message.h160
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/crypto_handshake_message_test.cc105
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/crypto_message_parser.h35
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/crypto_message_printer_bin.cc61
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/crypto_protocol.h510
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/crypto_secret_boxer.cc148
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/crypto_secret_boxer.h69
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/crypto_secret_boxer_test.cc82
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/crypto_server_test.cc1132
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/crypto_utils.cc788
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/crypto_utils.h255
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/crypto_utils_test.cc262
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/curve25519_key_exchange.cc87
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/curve25519_key_exchange.h53
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/curve25519_key_exchange_test.cc104
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/key_exchange.cc43
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/key_exchange.h105
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/null_decrypter.cc136
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/null_decrypter.h65
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/null_decrypter_test.cc136
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/null_encrypter.cc103
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/null_encrypter.h56
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/null_encrypter_test.cc102
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/p256_key_exchange.cc122
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/p256_key_exchange.h68
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/p256_key_exchange_test.cc109
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/proof_source.cc59
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/proof_source.h355
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/proof_source_x509.cc148
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/proof_source_x509.h78
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/proof_source_x509_test.cc142
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/proof_verifier.h128
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/quic_client_session_cache.cc174
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/quic_client_session_cache.h82
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/quic_client_session_cache_test.cc440
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/quic_compressed_certs_cache.cc133
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/quic_compressed_certs_cache.h108
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/quic_compressed_certs_cache_test.cc98
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/quic_crypter.cc18
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/quic_crypter.h94
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/quic_crypto_client_config.cc873
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/quic_crypto_client_config.h479
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/quic_crypto_client_config_test.cc550
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/quic_crypto_proof.cc12
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/quic_crypto_proof.h32
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/quic_crypto_server_config.cc1899
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/quic_crypto_server_config.h967
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/quic_crypto_server_config_test.cc513
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/quic_decrypter.cc80
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/quic_decrypter.h95
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/quic_encrypter.cc61
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/quic_encrypter.h71
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/quic_hkdf.cc107
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/quic_hkdf.h76
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/quic_hkdf_test.cc91
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/quic_random.cc100
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/quic_random.h41
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/quic_random_test.cc53
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/tls_client_connection.cc50
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/tls_client_connection.h55
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/tls_connection.cc207
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/tls_connection.h157
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/tls_server_connection.cc186
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/tls_server_connection.h200
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/transport_parameters.cc1604
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/transport_parameters.h314
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/transport_parameters_test.cc1139
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/frames/quic_ack_frame.cc190
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/frames/quic_ack_frame.h148
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/frames/quic_ack_frequency_frame.cc30
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/frames/quic_ack_frequency_frame.h52
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/frames/quic_blocked_frame.cc27
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/frames/quic_blocked_frame.h48
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/frames/quic_connection_close_frame.cc76
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/frames/quic_connection_close_frame.h69
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/frames/quic_crypto_frame.cc40
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/frames/quic_crypto_frame.h51
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/frames/quic_frame.cc531
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/frames/quic_frame.h178
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/frames/quic_frames_test.cc834
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/frames/quic_goaway_frame.cc29
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/frames/quic_goaway_frame.h37
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/frames/quic_handshake_done_frame.cc24
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/frames/quic_handshake_done_frame.h35
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/frames/quic_inlined_frame.h34
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/frames/quic_max_streams_frame.cc28
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/frames/quic_max_streams_frame.h45
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/frames/quic_message_frame.cc41
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/frames/quic_message_frame.h52
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/frames/quic_mtu_discovery_frame.h25
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/frames/quic_new_connection_id_frame.cc32
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/frames/quic_new_connection_id_frame.h40
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/frames/quic_new_token_frame.cc23
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/frames/quic_new_token_frame.h39
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/frames/quic_padding_frame.cc15
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/frames/quic_padding_frame.h37
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/frames/quic_path_challenge_frame.cc31
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/frames/quic_path_challenge_frame.h34
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/frames/quic_path_response_frame.cc30
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/frames/quic_path_response_frame.h34
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/frames/quic_ping_frame.cc19
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/frames/quic_ping_frame.h35
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/frames/quic_retire_connection_id_frame.cc21
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/frames/quic_retire_connection_id_frame.h33
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/frames/quic_rst_stream_frame.cc41
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/frames/quic_rst_stream_frame.h58
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/frames/quic_stop_sending_frame.cc33
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/frames/quic_stop_sending_frame.h49
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/frames/quic_stop_waiting_frame.cc20
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/frames/quic_stop_waiting_frame.h32
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/frames/quic_stream_frame.cc56
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/frames/quic_stream_frame.h58
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/frames/quic_streams_blocked_frame.cc31
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/frames/quic_streams_blocked_frame.h46
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/frames/quic_window_update_frame.cc25
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/frames/quic_window_update_frame.h43
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/handshaker_delegate_interface.h85
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/http/capsule.cc749
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/http/capsule.h291
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/http/capsule_test.cc364
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/http/end_to_end_test.cc6991
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/http/http_constants.cc32
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/http/http_constants.h76
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/http/http_decoder.cc674
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/http/http_decoder.h278
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/http/http_decoder_test.cc1136
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/http/http_encoder.cc279
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/http/http_encoder.h73
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/http/http_encoder_test.cc142
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/http/http_frames.h187
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/http/http_frames_test.cc105
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/http/quic_client_promised_info.cc147
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/http/quic_client_promised_info.h115
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/http/quic_client_promised_info_test.cc356
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/http/quic_client_push_promise_index.cc48
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/http/quic_client_push_promise_index.h99
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/http/quic_client_push_promise_index_test.cc113
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/http/quic_header_list.cc75
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/http/quic_header_list.h89
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/http/quic_header_list_test.cc86
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/http/quic_headers_stream.cc164
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/http/quic_headers_stream.h99
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/http/quic_headers_stream_test.cc953
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/http/quic_receive_control_stream.cc269
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/http/quic_receive_control_stream.h79
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/http/quic_receive_control_stream_test.cc483
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/http/quic_send_control_stream.cc124
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/http/quic_send_control_stream.h64
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/http/quic_send_control_stream_test.cc300
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/http/quic_server_initiated_spdy_stream.cc43
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/http/quic_server_initiated_spdy_stream.h32
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/http/quic_server_session_base.cc409
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/http/quic_server_session_base.h149
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/http/quic_server_session_base_test.cc814
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_client_session.cc223
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_client_session.h127
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_client_session_base.cc278
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_client_session_base.h146
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_client_session_test.cc1345
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_client_stream.cc219
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_client_stream.h102
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_client_stream_test.cc324
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_server_stream_base.cc134
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_server_stream_base.h32
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_server_stream_base_test.cc339
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_session.cc1943
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_session.h710
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_session_test.cc3824
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_stream.cc1939
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_stream.h534
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_stream_body_manager.cc140
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_stream_body_manager.h94
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_stream_body_manager_test.cc286
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_stream_test.cc3454
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/http/spdy_server_push_utils.cc215
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/http/spdy_server_push_utils.h43
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/http/spdy_server_push_utils_test.cc217
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/http/spdy_utils.cc217
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/http/spdy_utils.h77
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/http/spdy_utils_test.cc442
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/http/web_transport_http3.cc545
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/http/web_transport_http3.h197
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/http/web_transport_http3_test.cc52
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/http/web_transport_stream_adapter.cc127
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/http/web_transport_stream_adapter.h66
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/legacy_quic_stream_id_manager.cc142
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/legacy_quic_stream_id_manager.h128
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/legacy_quic_stream_id_manager_test.cc180
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/packet_number_indexed_queue.h252
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/packet_number_indexed_queue_test.cc205
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/proto/cached_network_parameters.proto43
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/proto/cached_network_parameters_proto.h15
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/proto/crypto_server_config.proto34
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/proto/crypto_server_config_proto.h15
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/proto/source_address_token.proto32
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/proto/source_address_token_proto.h15
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/qpack/qpack_blocking_manager.cc159
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/qpack/qpack_blocking_manager.h99
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/qpack/qpack_blocking_manager_test.cc319
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/qpack/qpack_decoded_headers_accumulator.cc101
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/qpack/qpack_decoded_headers_accumulator.h106
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/qpack/qpack_decoded_headers_accumulator_test.cc253
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/qpack/qpack_decoder.cc171
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/qpack/qpack_decoder.h128
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/qpack/qpack_decoder_stream_receiver.cc62
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/qpack/qpack_decoder_stream_receiver.h69
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/qpack/qpack_decoder_stream_receiver_test.cc102
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/qpack/qpack_decoder_stream_sender.cc44
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/qpack/qpack_decoder_stream_sender.h51
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/qpack/qpack_decoder_stream_sender_test.cc101
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/qpack/qpack_decoder_test.cc984
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/qpack/qpack_encoder.cc467
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/qpack/qpack_encoder.h164
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/qpack/qpack_encoder_stream_receiver.cc80
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/qpack/qpack_encoder_stream_receiver.h74
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/qpack/qpack_encoder_stream_receiver_test.cc197
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/qpack/qpack_encoder_stream_sender.cc69
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/qpack/qpack_encoder_stream_sender.h69
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/qpack/qpack_encoder_stream_sender_test.cc179
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/qpack/qpack_encoder_test.cc632
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/qpack/qpack_header_table.cc240
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/qpack/qpack_header_table.h346
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/qpack/qpack_header_table_test.cc655
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/qpack/qpack_index_conversions.cc62
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/qpack/qpack_index_conversions.h59
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/qpack/qpack_index_conversions_test.cc99
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/qpack/qpack_instruction_decoder.cc332
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/qpack/qpack_instruction_decoder.h161
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/qpack/qpack_instruction_decoder_test.cc226
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/qpack/qpack_instruction_encoder.cc177
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/qpack/qpack_instruction_encoder.h84
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/qpack/qpack_instruction_encoder_test.cc204
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/qpack/qpack_instructions.cc333
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/qpack/qpack_instructions.h207
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/qpack/qpack_offline_decoder_bin.cc46
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/qpack/qpack_progressive_decoder.cc428
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/qpack/qpack_progressive_decoder.h183
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/qpack/qpack_receive_stream.cc33
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/qpack/qpack_receive_stream.h42
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/qpack/qpack_receive_stream_test.cc98
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/qpack/qpack_required_insert_count.cc71
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/qpack/qpack_required_insert_count.h33
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/qpack/qpack_required_insert_count_test.cc125
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/qpack/qpack_round_trip_test.cc137
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/qpack/qpack_send_stream.cc52
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/qpack/qpack_send_stream.h60
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/qpack/qpack_send_stream_test.cc136
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/qpack/qpack_static_table.cc139
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/qpack/qpack_static_table.h31
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/qpack/qpack_static_table_test.cc54
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/qpack/qpack_stream_receiver.h24
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/qpack/qpack_stream_sender_delegate.h27
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/qpack/value_splitting_header_list.cc108
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/qpack/value_splitting_header_list.h62
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/qpack/value_splitting_header_list_test.cc158
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_ack_listener_interface.cc11
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_ack_listener_interface.h37
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_alarm.cc107
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_alarm.h125
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_alarm_factory.h36
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_alarm_test.cc261
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_arena_scoped_ptr.h208
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_arena_scoped_ptr_test.cc115
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_bandwidth.cc41
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_bandwidth.h164
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_bandwidth_test.cc151
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_blocked_writer_interface.h29
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_buffer_allocator.cc11
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_buffer_allocator.h114
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_buffered_packet_store.cc283
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_buffered_packet_store.h194
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_buffered_packet_store_test.cc452
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_chaos_protector.cc232
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_chaos_protector.h99
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_chaos_protector_test.cc230
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_clock.cc70
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_clock.h72
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_coalesced_packet.cc185
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_coalesced_packet.h89
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_coalesced_packet_test.cc213
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_config.cc1424
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_config.h665
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_config_test.cc727
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_connection.cc7123
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_connection.h2297
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_connection_context.cc36
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_connection_context.h133
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_connection_context_test.cc173
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_connection_id.cc182
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_connection_id.h141
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_connection_id_manager.cc460
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_connection_id_manager.h195
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_connection_id_manager_test.cc964
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_connection_id_test.cc154
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_connection_stats.cc72
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_connection_stats.h241
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_connection_test.cc15297
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_constants.cc25
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_constants.h310
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_control_frame_manager.cc363
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_control_frame_manager.h192
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_control_frame_manager_test.cc364
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_crypto_client_handshaker.cc629
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_crypto_client_handshaker.h211
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_crypto_client_handshaker_test.cc238
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_crypto_client_stream.cc169
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_crypto_client_stream.h307
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_crypto_client_stream_test.cc371
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_crypto_handshaker.cc53
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_crypto_handshaker.h52
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_crypto_server_stream.cc529
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_crypto_server_stream.h265
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_crypto_server_stream_base.cc51
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_crypto_server_stream_base.h113
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_crypto_server_stream_test.cc400
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_crypto_stream.cc483
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_crypto_stream.h273
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_crypto_stream_test.cc724
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_data_reader.cc176
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_data_reader.h93
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_data_writer.cc260
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_data_writer.h100
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_data_writer_test.cc1281
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_datagram_queue.cc100
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_datagram_queue.h89
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_datagram_queue_test.cc298
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_default_packet_writer.cc71
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_default_packet_writer.h56
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_dispatcher.cc1456
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_dispatcher.h484
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_dispatcher_test.cc2918
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_epoll_alarm_factory.cc89
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_epoll_alarm_factory.h35
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_epoll_alarm_factory_test.cc141
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_epoll_connection_helper.cc39
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_epoll_connection_helper.h57
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_epoll_connection_helper_test.cc41
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_error_codes.cc972
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_error_codes.h765
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_error_codes_test.cc143
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_flags_list.h142
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_flow_controller.cc319
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_flow_controller.h217
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_flow_controller_test.cc408
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_framer.cc7243
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_framer.h1265
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_framer_test.cc16375
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_idle_network_detector.cc145
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_idle_network_detector.h118
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_idle_network_detector_test.cc200
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_interval.h390
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_interval_deque.h393
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_interval_deque_test.cc360
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_interval_set.h896
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_interval_set_test.cc1071
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_interval_test.cc470
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_legacy_version_encapsulator.cc153
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_legacy_version_encapsulator.h74
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_legacy_version_encapsulator_test.cc107
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_linux_socket_utils.cc315
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_linux_socket_utils.h297
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_linux_socket_utils_test.cc329
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_lru_cache.h98
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_lru_cache_test.cc81
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_mtu_discovery.cc139
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_mtu_discovery.h117
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_network_blackhole_detector.cc136
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_network_blackhole_detector.h91
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_network_blackhole_detector_test.cc139
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_one_block_arena.h76
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_one_block_arena_test.cc60
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_packet_creator.cc2251
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_packet_creator.h719
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_packet_creator_test.cc4010
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_packet_number.cc111
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_packet_number.h165
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_packet_number_test.cc67
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_packet_reader.cc135
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_packet_reader.h67
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_packet_writer.h163
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_packet_writer_wrapper.cc79
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_packet_writer_wrapper.h62
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_packets.cc596
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_packets.h463
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_packets_test.cc113
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_path_validator.cc148
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_path_validator.h160
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_path_validator_test.cc254
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_process_packet_interface.h24
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_protocol_flags_list.h290
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_received_packet_manager.cc338
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_received_packet_manager.h218
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_received_packet_manager_test.cc642
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_sent_packet_manager.cc1837
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_sent_packet_manager.h769
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_sent_packet_manager_test.cc4640
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_server_id.cc38
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_server_id.h55
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_server_id_test.cc124
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_session.cc2675
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_session.h1028
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_session_test.cc3144
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_simple_buffer_allocator.cc21
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_simple_buffer_allocator.h27
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_simple_buffer_allocator_test.cc66
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_socket_address_coder.cc90
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_socket_address_coder.h41
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_socket_address_coder_test.cc128
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_stream.cc1457
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_stream.h623
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_stream_frame_data_producer.h39
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_stream_id_manager.cc243
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_stream_id_manager.h186
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_stream_id_manager_test.cc479
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_stream_send_buffer.cc297
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_stream_send_buffer.h177
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_stream_send_buffer_test.cc350
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_stream_sequencer.cc312
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_stream_sequencer.h217
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_stream_sequencer_buffer.cc557
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_stream_sequencer_buffer.h249
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_stream_sequencer_buffer_test.cc1139
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_stream_sequencer_test.cc781
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_stream_test.cc1734
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_sustained_bandwidth_recorder.cc62
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_sustained_bandwidth_recorder.h95
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_sustained_bandwidth_recorder_test.cc133
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_syscall_wrapper.cc49
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_syscall_wrapper.h49
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_tag.cc110
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_tag.h67
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_tag_test.cc80
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_time.cc87
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_time.h294
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_time_accumulator.h69
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_time_accumulator_test.cc82
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_time_test.cc185
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_time_wait_list_manager.cc503
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_time_wait_list_manager.h343
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_time_wait_list_manager_test.cc788
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_trace_visitor.cc350
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_trace_visitor.h79
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_trace_visitor_test.cc184
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_transmission_info.cc55
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_transmission_info.h66
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_types.cc426
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_types.h891
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_udp_socket.h253
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_udp_socket_posix.cc639
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_unacked_packet_map.cc658
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_unacked_packet_map.h338
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_unacked_packet_map_test.cc699
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_utils.cc749
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_utils.h323
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_utils_test.cc404
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_version_manager.cc94
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_version_manager.h95
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_version_manager_test.cc87
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_versions.cc668
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_versions.h652
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_versions_test.cc524
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_write_blocked_list.cc182
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_write_blocked_list.h143
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_write_blocked_list_test.cc269
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/session_notifier_interface.h47
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/stream_delegate_interface.h58
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/tls_chlo_extractor.cc425
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/tls_chlo_extractor.h265
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/tls_chlo_extractor_test.cc253
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/tls_client_handshaker.cc664
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/tls_client_handshaker.h177
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/tls_client_handshaker_test.cc712
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/tls_handshaker.cc372
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/tls_handshaker.h225
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/tls_server_handshaker.cc1161
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/tls_server_handshaker.h385
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/tls_server_handshaker_test.cc1080
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/uber_quic_stream_id_manager.cc176
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/uber_quic_stream_id_manager.h107
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/uber_quic_stream_id_manager_test.cc340
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/uber_received_packet_manager.cc247
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/uber_received_packet_manager.h111
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/uber_received_packet_manager_test.cc527
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/web_transport_interface.h151
-rw-r--r--chromium/net/third_party/quiche/src/quic/masque/README.md4
-rw-r--r--chromium/net/third_party/quiche/src/quic/masque/masque_client_bin.cc118
-rw-r--r--chromium/net/third_party/quiche/src/quic/masque/masque_client_session.cc435
-rw-r--r--chromium/net/third_party/quiche/src/quic/masque/masque_client_session.h186
-rw-r--r--chromium/net/third_party/quiche/src/quic/masque/masque_client_tools.cc107
-rw-r--r--chromium/net/third_party/quiche/src/quic/masque/masque_client_tools.h25
-rw-r--r--chromium/net/third_party/quiche/src/quic/masque/masque_compression_engine.cc525
-rw-r--r--chromium/net/third_party/quiche/src/quic/masque/masque_compression_engine.h120
-rw-r--r--chromium/net/third_party/quiche/src/quic/masque/masque_dispatcher.cc92
-rw-r--r--chromium/net/third_party/quiche/src/quic/masque/masque_dispatcher.h70
-rw-r--r--chromium/net/third_party/quiche/src/quic/masque/masque_encapsulated_client_session.cc49
-rw-r--r--chromium/net/third_party/quiche/src/quic/masque/masque_encapsulated_client_session.h62
-rw-r--r--chromium/net/third_party/quiche/src/quic/masque/masque_encapsulated_epoll_client.cc125
-rw-r--r--chromium/net/third_party/quiche/src/quic/masque/masque_encapsulated_epoll_client.h50
-rw-r--r--chromium/net/third_party/quiche/src/quic/masque/masque_epoll_client.cc156
-rw-r--r--chromium/net/third_party/quiche/src/quic/masque/masque_epoll_client.h72
-rw-r--r--chromium/net/third_party/quiche/src/quic/masque/masque_epoll_server.cc33
-rw-r--r--chromium/net/third_party/quiche/src/quic/masque/masque_epoll_server.h35
-rw-r--r--chromium/net/third_party/quiche/src/quic/masque/masque_server_backend.cc137
-rw-r--r--chromium/net/third_party/quiche/src/quic/masque/masque_server_backend.h76
-rw-r--r--chromium/net/third_party/quiche/src/quic/masque/masque_server_bin.cc72
-rw-r--r--chromium/net/third_party/quiche/src/quic/masque/masque_server_session.cc628
-rw-r--r--chromium/net/third_party/quiche/src/quic/masque/masque_server_session.h156
-rw-r--r--chromium/net/third_party/quiche/src/quic/masque/masque_utils.cc46
-rw-r--r--chromium/net/third_party/quiche/src/quic/masque/masque_utils.h45
-rw-r--r--chromium/net/third_party/quiche/src/quic/platform/README.md12
-rw-r--r--chromium/net/third_party/quiche/src/quic/platform/api/README.md72
-rw-r--r--chromium/net/third_party/quiche/src/quic/platform/api/quic_bug_tracker.h15
-rw-r--r--chromium/net/third_party/quiche/src/quic/platform/api/quic_client_stats.h87
-rw-r--r--chromium/net/third_party/quiche/src/quic/platform/api/quic_containers.h22
-rw-r--r--chromium/net/third_party/quiche/src/quic/platform/api/quic_default_proof_providers.h32
-rw-r--r--chromium/net/third_party/quiche/src/quic/platform/api/quic_epoll.h19
-rw-r--r--chromium/net/third_party/quiche/src/quic/platform/api/quic_epoll_test_tools.h12
-rw-r--r--chromium/net/third_party/quiche/src/quic/platform/api/quic_error_code_wrappers.h14
-rw-r--r--chromium/net/third_party/quiche/src/quic/platform/api/quic_expect_bug.h14
-rw-r--r--chromium/net/third_party/quiche/src/quic/platform/api/quic_export.h21
-rw-r--r--chromium/net/third_party/quiche/src/quic/platform/api/quic_exported_stats.h96
-rw-r--r--chromium/net/third_party/quiche/src/quic/platform/api/quic_flag_utils.h19
-rw-r--r--chromium/net/third_party/quiche/src/quic/platform/api/quic_flags.h22
-rw-r--r--chromium/net/third_party/quiche/src/quic/platform/api/quic_hostname_utils.cc20
-rw-r--r--chromium/net/third_party/quiche/src/quic/platform/api/quic_hostname_utils.h34
-rw-r--r--chromium/net/third_party/quiche/src/quic/platform/api/quic_hostname_utils_test.cc89
-rw-r--r--chromium/net/third_party/quiche/src/quic/platform/api/quic_iovec.h27
-rw-r--r--chromium/net/third_party/quiche/src/quic/platform/api/quic_ip_address.cc241
-rw-r--r--chromium/net/third_party/quiche/src/quic/platform/api/quic_ip_address.h97
-rw-r--r--chromium/net/third_party/quiche/src/quic/platform/api/quic_ip_address_family.h20
-rw-r--r--chromium/net/third_party/quiche/src/quic/platform/api/quic_ip_address_test.cc141
-rw-r--r--chromium/net/third_party/quiche/src/quic/platform/api/quic_logging.h38
-rw-r--r--chromium/net/third_party/quiche/src/quic/platform/api/quic_mem_slice.h92
-rw-r--r--chromium/net/third_party/quiche/src/quic/platform/api/quic_mem_slice_storage.cc35
-rw-r--r--chromium/net/third_party/quiche/src/quic/platform/api/quic_mem_slice_storage.h43
-rw-r--r--chromium/net/third_party/quiche/src/quic/platform/api/quic_mem_slice_storage_test.cc61
-rw-r--r--chromium/net/third_party/quiche/src/quic/platform/api/quic_mem_slice_test.cc76
-rw-r--r--chromium/net/third_party/quiche/src/quic/platform/api/quic_mock_log.h18
-rw-r--r--chromium/net/third_party/quiche/src/quic/platform/api/quic_mutex.cc45
-rw-r--r--chromium/net/third_party/quiche/src/quic/platform/api/quic_mutex.h101
-rw-r--r--chromium/net/third_party/quiche/src/quic/platform/api/quic_port_utils.h23
-rw-r--r--chromium/net/third_party/quiche/src/quic/platform/api/quic_reference_counted.h162
-rw-r--r--chromium/net/third_party/quiche/src/quic/platform/api/quic_reference_counted_test.cc173
-rw-r--r--chromium/net/third_party/quiche/src/quic/platform/api/quic_server_stats.h82
-rw-r--r--chromium/net/third_party/quiche/src/quic/platform/api/quic_sleep.h20
-rw-r--r--chromium/net/third_party/quiche/src/quic/platform/api/quic_socket_address.cc158
-rw-r--r--chromium/net/third_party/quiche/src/quic/platform/api/quic_socket_address.h63
-rw-r--r--chromium/net/third_party/quiche/src/quic/platform/api/quic_socket_address_test.cc133
-rw-r--r--chromium/net/third_party/quiche/src/quic/platform/api/quic_stack_trace.h20
-rw-r--r--chromium/net/third_party/quiche/src/quic/platform/api/quic_stream_buffer_allocator.h16
-rw-r--r--chromium/net/third_party/quiche/src/quic/platform/api/quic_system_event_loop.h16
-rw-r--r--chromium/net/third_party/quiche/src/quic/platform/api/quic_test.h31
-rw-r--r--chromium/net/third_party/quiche/src/quic/platform/api/quic_test_loopback.cc29
-rw-r--r--chromium/net/third_party/quiche/src/quic/platform/api/quic_test_loopback.h32
-rw-r--r--chromium/net/third_party/quiche/src/quic/platform/api/quic_test_output.h39
-rw-r--r--chromium/net/third_party/quiche/src/quic/platform/api/quic_testvalue.h27
-rw-r--r--chromium/net/third_party/quiche/src/quic/platform/api/quic_thread.h28
-rw-r--r--chromium/net/third_party/quiche/src/quic/platform/api/quic_udp_socket_platform_api.h29
-rw-r--r--chromium/net/third_party/quiche/src/quic/qbone/bonnet/icmp_reachable.cc212
-rw-r--r--chromium/net/third_party/quiche/src/quic/qbone/bonnet/icmp_reachable.h140
-rw-r--r--chromium/net/third_party/quiche/src/quic/qbone/bonnet/icmp_reachable_interface.h28
-rw-r--r--chromium/net/third_party/quiche/src/quic/qbone/bonnet/icmp_reachable_test.cc267
-rw-r--r--chromium/net/third_party/quiche/src/quic/qbone/bonnet/mock_icmp_reachable.h20
-rw-r--r--chromium/net/third_party/quiche/src/quic/qbone/bonnet/mock_packet_exchanger_stats_interface.h27
-rw-r--r--chromium/net/third_party/quiche/src/quic/qbone/bonnet/mock_qbone_tunnel.h43
-rw-r--r--chromium/net/third_party/quiche/src/quic/qbone/bonnet/mock_tun_device.h28
-rw-r--r--chromium/net/third_party/quiche/src/quic/qbone/bonnet/mock_tun_device_controller.h27
-rw-r--r--chromium/net/third_party/quiche/src/quic/qbone/bonnet/qbone_tunnel_info.cc37
-rw-r--r--chromium/net/third_party/quiche/src/quic/qbone/bonnet/qbone_tunnel_info.h29
-rw-r--r--chromium/net/third_party/quiche/src/quic/qbone/bonnet/qbone_tunnel_interface.h68
-rw-r--r--chromium/net/third_party/quiche/src/quic/qbone/bonnet/qbone_tunnel_silo.cc31
-rw-r--r--chromium/net/third_party/quiche/src/quic/qbone/bonnet/qbone_tunnel_silo.h48
-rw-r--r--chromium/net/third_party/quiche/src/quic/qbone/bonnet/qbone_tunnel_silo_test.cc78
-rw-r--r--chromium/net/third_party/quiche/src/quic/qbone/bonnet/tun_device.cc219
-rw-r--r--chromium/net/third_party/quiche/src/quic/qbone/bonnet/tun_device.h82
-rw-r--r--chromium/net/third_party/quiche/src/quic/qbone/bonnet/tun_device_controller.cc173
-rw-r--r--chromium/net/third_party/quiche/src/quic/qbone/bonnet/tun_device_controller.h74
-rw-r--r--chromium/net/third_party/quiche/src/quic/qbone/bonnet/tun_device_controller_test.cc262
-rw-r--r--chromium/net/third_party/quiche/src/quic/qbone/bonnet/tun_device_interface.h38
-rw-r--r--chromium/net/third_party/quiche/src/quic/qbone/bonnet/tun_device_packet_exchanger.cc230
-rw-r--r--chromium/net/third_party/quiche/src/quic/qbone/bonnet/tun_device_packet_exchanger.h88
-rw-r--r--chromium/net/third_party/quiche/src/quic/qbone/bonnet/tun_device_packet_exchanger_test.cc119
-rw-r--r--chromium/net/third_party/quiche/src/quic/qbone/bonnet/tun_device_test.cc211
-rw-r--r--chromium/net/third_party/quiche/src/quic/qbone/mock_qbone_client.h24
-rw-r--r--chromium/net/third_party/quiche/src/quic/qbone/mock_qbone_server_session.h36
-rw-r--r--chromium/net/third_party/quiche/src/quic/qbone/platform/icmp_packet.cc90
-rw-r--r--chromium/net/third_party/quiche/src/quic/qbone/platform/icmp_packet.h29
-rw-r--r--chromium/net/third_party/quiche/src/quic/qbone/platform/icmp_packet_test.cc128
-rw-r--r--chromium/net/third_party/quiche/src/quic/qbone/platform/internet_checksum.cc31
-rw-r--r--chromium/net/third_party/quiche/src/quic/qbone/platform/internet_checksum.h32
-rw-r--r--chromium/net/third_party/quiche/src/quic/qbone/platform/internet_checksum_test.cc67
-rw-r--r--chromium/net/third_party/quiche/src/quic/qbone/platform/ip_range.cc101
-rw-r--r--chromium/net/third_party/quiche/src/quic/qbone/platform/ip_range.h60
-rw-r--r--chromium/net/third_party/quiche/src/quic/qbone/platform/ip_range_test.cc65
-rw-r--r--chromium/net/third_party/quiche/src/quic/qbone/platform/kernel_interface.h169
-rw-r--r--chromium/net/third_party/quiche/src/quic/qbone/platform/mock_kernel.h53
-rw-r--r--chromium/net/third_party/quiche/src/quic/qbone/platform/mock_netlink.h51
-rw-r--r--chromium/net/third_party/quiche/src/quic/qbone/platform/netlink.cc837
-rw-r--r--chromium/net/third_party/quiche/src/quic/qbone/platform/netlink.h143
-rw-r--r--chromium/net/third_party/quiche/src/quic/qbone/platform/netlink_interface.h148
-rw-r--r--chromium/net/third_party/quiche/src/quic/qbone/platform/netlink_test.cc784
-rw-r--r--chromium/net/third_party/quiche/src/quic/qbone/platform/rtnetlink_message.cc177
-rw-r--r--chromium/net/third_party/quiche/src/quic/qbone/platform/rtnetlink_message.h125
-rw-r--r--chromium/net/third_party/quiche/src/quic/qbone/platform/rtnetlink_message_test.cc229
-rw-r--r--chromium/net/third_party/quiche/src/quic/qbone/platform/tcp_packet.cc126
-rw-r--r--chromium/net/third_party/quiche/src/quic/qbone/platform/tcp_packet.h25
-rw-r--r--chromium/net/third_party/quiche/src/quic/qbone/platform/tcp_packet_test.cc117
-rw-r--r--chromium/net/third_party/quiche/src/quic/qbone/qbone_client.cc110
-rw-r--r--chromium/net/third_party/quiche/src/quic/qbone/qbone_client.h78
-rw-r--r--chromium/net/third_party/quiche/src/quic/qbone/qbone_client_interface.h25
-rw-r--r--chromium/net/third_party/quiche/src/quic/qbone/qbone_client_session.cc124
-rw-r--r--chromium/net/third_party/quiche/src/quic/qbone/qbone_client_session.h95
-rw-r--r--chromium/net/third_party/quiche/src/quic/qbone/qbone_client_test.cc285
-rw-r--r--chromium/net/third_party/quiche/src/quic/qbone/qbone_constants.cc45
-rw-r--r--chromium/net/third_party/quiche/src/quic/qbone/qbone_constants.h35
-rw-r--r--chromium/net/third_party/quiche/src/quic/qbone/qbone_control.proto13
-rw-r--r--chromium/net/third_party/quiche/src/quic/qbone/qbone_control_placeholder.proto20
-rw-r--r--chromium/net/third_party/quiche/src/quic/qbone/qbone_control_stream.cc86
-rw-r--r--chromium/net/third_party/quiche/src/quic/qbone/qbone_control_stream.h82
-rw-r--r--chromium/net/third_party/quiche/src/quic/qbone/qbone_packet_exchanger.cc73
-rw-r--r--chromium/net/third_party/quiche/src/quic/qbone/qbone_packet_exchanger.h80
-rw-r--r--chromium/net/third_party/quiche/src/quic/qbone/qbone_packet_exchanger_test.cc271
-rw-r--r--chromium/net/third_party/quiche/src/quic/qbone/qbone_packet_processor.cc277
-rw-r--r--chromium/net/third_party/quiche/src/quic/qbone/qbone_packet_processor.h201
-rw-r--r--chromium/net/third_party/quiche/src/quic/qbone/qbone_packet_processor_test.cc287
-rw-r--r--chromium/net/third_party/quiche/src/quic/qbone/qbone_packet_processor_test_tools.cc28
-rw-r--r--chromium/net/third_party/quiche/src/quic/qbone/qbone_packet_processor_test_tools.h52
-rw-r--r--chromium/net/third_party/quiche/src/quic/qbone/qbone_packet_writer.h24
-rw-r--r--chromium/net/third_party/quiche/src/quic/qbone/qbone_server_session.cc133
-rw-r--r--chromium/net/third_party/quiche/src/quic/qbone/qbone_server_session.h105
-rw-r--r--chromium/net/third_party/quiche/src/quic/qbone/qbone_session_base.cc216
-rw-r--r--chromium/net/third_party/quiche/src/quic/qbone/qbone_session_base.h114
-rw-r--r--chromium/net/third_party/quiche/src/quic/qbone/qbone_session_test.cc643
-rw-r--r--chromium/net/third_party/quiche/src/quic/qbone/qbone_stream.cc64
-rw-r--r--chromium/net/third_party/quiche/src/quic/qbone/qbone_stream.h56
-rw-r--r--chromium/net/third_party/quiche/src/quic/qbone/qbone_stream_test.cc255
-rw-r--r--chromium/net/third_party/quiche/src/quic/quic_transport/README.md7
-rw-r--r--chromium/net/third_party/quiche/src/quic/quic_transport/quic_transport_client_session.cc267
-rw-r--r--chromium/net/third_party/quiche/src/quic/quic_transport/quic_transport_client_session.h175
-rw-r--r--chromium/net/third_party/quiche/src/quic/quic_transport/quic_transport_client_session_test.cc182
-rw-r--r--chromium/net/third_party/quiche/src/quic/quic_transport/quic_transport_integration_test.cc418
-rw-r--r--chromium/net/third_party/quiche/src/quic/quic_transport/quic_transport_protocol.h54
-rw-r--r--chromium/net/third_party/quiche/src/quic/quic_transport/quic_transport_server_session.cc215
-rw-r--r--chromium/net/third_party/quiche/src/quic/quic_transport/quic_transport_server_session.h122
-rw-r--r--chromium/net/third_party/quiche/src/quic/quic_transport/quic_transport_server_session_test.cc291
-rw-r--r--chromium/net/third_party/quiche/src/quic/quic_transport/quic_transport_session_interface.h27
-rw-r--r--chromium/net/third_party/quiche/src/quic/quic_transport/quic_transport_stream.cc89
-rw-r--r--chromium/net/third_party/quiche/src/quic/quic_transport/quic_transport_stream.h84
-rw-r--r--chromium/net/third_party/quiche/src/quic/quic_transport/quic_transport_stream_test.cc177
-rw-r--r--chromium/net/third_party/quiche/src/quic/quic_transport/web_transport_fingerprint_proof_verifier.cc229
-rw-r--r--chromium/net/third_party/quiche/src/quic/quic_transport/web_transport_fingerprint_proof_verifier.h135
-rw-r--r--chromium/net/third_party/quiche/src/quic/quic_transport/web_transport_fingerprint_proof_verifier_test.cc183
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/bad_packet_writer.cc36
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/bad_packet_writer.h36
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/crypto_test_utils.cc921
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/crypto_test_utils.h227
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/crypto_test_utils_test.cc187
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/failing_proof_source.cc42
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/failing_proof_source.h48
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/fake_proof_source.cc158
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/fake_proof_source.h135
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/fake_proof_source_handle.cc241
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/fake_proof_source_handle.h201
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/first_flight.cc163
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/first_flight.h119
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/limited_mtu_test_writer.cc30
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/limited_mtu_test_writer.h37
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/mock_clock.cc33
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/mock_clock.h36
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/mock_quic_client_promised_info.cc19
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/mock_quic_client_promised_info.h34
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/mock_quic_dispatcher.cc32
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/mock_quic_dispatcher.h44
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/mock_quic_session_visitor.cc19
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/mock_quic_session_visitor.h74
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/mock_quic_spdy_client_stream.cc19
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/mock_quic_spdy_client_stream.h36
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/mock_quic_time_wait_list_manager.cc32
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/mock_quic_time_wait_list_manager.h76
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/mock_random.cc42
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/mock_random.h47
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/packet_dropping_test_writer.cc262
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/packet_dropping_test_writer.h186
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/packet_reordering_writer.cc54
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/packet_reordering_writer.h45
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/qpack/qpack_decoder_test_utils.cc90
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/qpack/qpack_decoder_test_utils.h115
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/qpack/qpack_encoder_peer.cc30
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/qpack/qpack_encoder_peer.h30
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/qpack/qpack_encoder_test_utils.cc18
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/qpack/qpack_encoder_test_utils.h44
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/qpack/qpack_offline_decoder.cc336
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/qpack/qpack_offline_decoder.h88
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/qpack/qpack_test_utils.cc27
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/qpack/qpack_test_utils.h51
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/quic_buffered_packet_store_peer.cc25
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/quic_buffered_packet_store_peer.h32
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/quic_client_peer.cc35
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/quic_client_peer.h28
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/quic_client_promised_info_peer.cc17
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/quic_client_promised_info_peer.h22
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/quic_client_session_cache_peer.h33
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/quic_config_peer.cc143
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/quic_config_peer.h88
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/quic_connection_id_manager_peer.h29
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/quic_connection_peer.cc539
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/quic_connection_peer.h229
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/quic_crypto_server_config_peer.cc163
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/quic_crypto_server_config_peer.h95
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/quic_dispatcher_peer.cc143
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/quic_dispatcher_peer.h86
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/quic_flow_controller_peer.cc68
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/quic_flow_controller_peer.h45
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/quic_framer_peer.cc129
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/quic_framer_peer.h78
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/quic_interval_deque_peer.h35
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/quic_mock_syscall_wrapper.cc22
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/quic_mock_syscall_wrapper.h37
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/quic_packet_creator_peer.cc166
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/quic_packet_creator_peer.h72
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/quic_path_validator_peer.cc15
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/quic_path_validator_peer.h20
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/quic_sent_packet_manager_peer.cc224
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/quic_sent_packet_manager_peer.h110
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/quic_server_peer.cc32
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/quic_server_peer.h28
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/quic_server_session_base_peer.h34
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/quic_session_peer.cc250
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/quic_session_peer.h96
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/quic_spdy_session_peer.cc118
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/quic_spdy_session_peer.h60
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/quic_spdy_stream_peer.cc37
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/quic_spdy_stream_peer.h34
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/quic_stream_id_manager_peer.cc42
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/quic_stream_id_manager_peer.h38
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/quic_stream_peer.cc120
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/quic_stream_peer.h55
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/quic_stream_send_buffer_peer.cc54
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/quic_stream_send_buffer_peer.h33
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/quic_stream_sequencer_buffer_peer.cc162
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/quic_stream_sequencer_buffer_peer.h65
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/quic_stream_sequencer_peer.cc40
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/quic_stream_sequencer_peer.h33
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/quic_sustained_bandwidth_recorder_peer.cc34
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/quic_sustained_bandwidth_recorder_peer.h35
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/quic_test_backend.cc123
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/quic_test_backend.h50
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/quic_test_client.cc1012
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/quic_test_client.h449
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/quic_test_server.cc272
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/quic_test_server.h117
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/quic_test_utils.cc1617
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/quic_test_utils.h2043
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/quic_test_utils_test.cc79
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/quic_time_wait_list_manager_peer.cc46
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/quic_time_wait_list_manager_peer.h36
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/quic_transport_test_tools.h48
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/quic_unacked_packet_map_peer.cc30
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/quic_unacked_packet_map_peer.h27
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/rtt_stats_peer.cc21
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/rtt_stats_peer.h26
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/send_algorithm_test_result.proto15
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/send_algorithm_test_utils.cc61
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/send_algorithm_test_utils.h29
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/server_thread.cc141
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/server_thread.h96
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/simple_data_producer.cc72
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/simple_data_producer.h83
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/simple_quic_framer.cc444
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/simple_quic_framer.h70
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/simple_session_cache.cc76
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/simple_session_cache.h52
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/simple_session_notifier.cc764
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/simple_session_notifier.h170
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/simple_session_notifier_test.cc367
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/simulator/README.md99
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/simulator/actor.cc31
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/simulator/actor.h66
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/simulator/alarm_factory.cc81
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/simulator/alarm_factory.h39
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/simulator/link.cc127
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/simulator/link.h103
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/simulator/packet_filter.cc40
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/simulator/packet_filter.h75
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/simulator/port.cc21
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/simulator/port.h66
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/simulator/queue.cc129
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/simulator/queue.h121
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/simulator/quic_endpoint.cc258
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/simulator/quic_endpoint.h179
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/simulator/quic_endpoint_base.cc220
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/simulator/quic_endpoint_base.h160
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/simulator/quic_endpoint_test.cc208
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/simulator/simulator.cc170
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/simulator/simulator.h169
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/simulator/simulator_test.cc832
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/simulator/switch.cc83
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/simulator/switch.h90
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/simulator/traffic_policer.cc60
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/simulator/traffic_policer.h54
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/test_certificates.cc734
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/test_certificates.h50
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/test_ticket_crypter.cc83
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/test_ticket_crypter.h52
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/web_transport_resets_backend.cc113
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/web_transport_resets_backend.h23
-rw-r--r--chromium/net/third_party/quiche/src/quic/tools/fake_proof_verifier.h52
-rw-r--r--chromium/net/third_party/quiche/src/quic/tools/quic_backend_response.cc29
-rw-r--r--chromium/net/third_party/quiche/src/quic/tools/quic_backend_response.h92
-rw-r--r--chromium/net/third_party/quiche/src/quic/tools/quic_client.cc179
-rw-r--r--chromium/net/third_party/quiche/src/quic/tools/quic_client.h108
-rw-r--r--chromium/net/third_party/quiche/src/quic/tools/quic_client_base.cc514
-rw-r--r--chromium/net/third_party/quiche/src/quic/tools/quic_client_base.h408
-rw-r--r--chromium/net/third_party/quiche/src/quic/tools/quic_client_bin.cc67
-rw-r--r--chromium/net/third_party/quiche/src/quic/tools/quic_client_epoll_network_helper.cc227
-rw-r--r--chromium/net/third_party/quiche/src/quic/tools/quic_client_epoll_network_helper.h135
-rw-r--r--chromium/net/third_party/quiche/src/quic/tools/quic_client_interop_test_bin.cc467
-rw-r--r--chromium/net/third_party/quiche/src/quic/tools/quic_client_test.cc129
-rw-r--r--chromium/net/third_party/quiche/src/quic/tools/quic_epoll_client_factory.cc41
-rw-r--r--chromium/net/third_party/quiche/src/quic/tools/quic_epoll_client_factory.h32
-rw-r--r--chromium/net/third_party/quiche/src/quic/tools/quic_epoll_server_factory.cc21
-rw-r--r--chromium/net/third_party/quiche/src/quic/tools/quic_epoll_server_factory.h27
-rw-r--r--chromium/net/third_party/quiche/src/quic/tools/quic_memory_cache_backend.cc496
-rw-r--r--chromium/net/third_party/quiche/src/quic/tools/quic_memory_cache_backend.h217
-rw-r--r--chromium/net/third_party/quiche/src/quic/tools/quic_memory_cache_backend_test.cc291
-rw-r--r--chromium/net/third_party/quiche/src/quic/tools/quic_packet_printer_bin.cc283
-rw-r--r--chromium/net/third_party/quiche/src/quic/tools/quic_reject_reason_decoder_bin.cc45
-rw-r--r--chromium/net/third_party/quiche/src/quic/tools/quic_server.cc221
-rw-r--r--chromium/net/third_party/quiche/src/quic/tools/quic_server.h171
-rw-r--r--chromium/net/third_party/quiche/src/quic/tools/quic_server_bin.cc31
-rw-r--r--chromium/net/third_party/quiche/src/quic/tools/quic_server_test.cc214
-rw-r--r--chromium/net/third_party/quiche/src/quic/tools/quic_simple_client_session.cc54
-rw-r--r--chromium/net/third_party/quiche/src/quic/tools/quic_simple_client_session.h44
-rw-r--r--chromium/net/third_party/quiche/src/quic/tools/quic_simple_client_stream.cc29
-rw-r--r--chromium/net/third_party/quiche/src/quic/tools/quic_simple_client_stream.h28
-rw-r--r--chromium/net/third_party/quiche/src/quic/tools/quic_simple_crypto_server_stream_helper.cc26
-rw-r--r--chromium/net/third_party/quiche/src/quic/tools/quic_simple_crypto_server_stream_helper.h31
-rw-r--r--chromium/net/third_party/quiche/src/quic/tools/quic_simple_dispatcher.cc70
-rw-r--r--chromium/net/third_party/quiche/src/quic/tools/quic_simple_dispatcher.h53
-rw-r--r--chromium/net/third_party/quiche/src/quic/tools/quic_simple_server_backend.h76
-rw-r--r--chromium/net/third_party/quiche/src/quic/tools/quic_simple_server_session.cc225
-rw-r--r--chromium/net/third_party/quiche/src/quic/tools/quic_simple_server_session.h160
-rw-r--r--chromium/net/third_party/quiche/src/quic/tools/quic_simple_server_session_test.cc595
-rw-r--r--chromium/net/third_party/quiche/src/quic/tools/quic_simple_server_stream.cc429
-rw-r--r--chromium/net/third_party/quiche/src/quic/tools/quic_simple_server_stream.h109
-rw-r--r--chromium/net/third_party/quiche/src/quic/tools/quic_simple_server_stream_test.cc789
-rw-r--r--chromium/net/third_party/quiche/src/quic/tools/quic_spdy_client_base.cc296
-rw-r--r--chromium/net/third_party/quiche/src/quic/tools/quic_spdy_client_base.h243
-rw-r--r--chromium/net/third_party/quiche/src/quic/tools/quic_spdy_server_base.h30
-rw-r--r--chromium/net/third_party/quiche/src/quic/tools/quic_tcp_like_trace_converter.cc126
-rw-r--r--chromium/net/third_party/quiche/src/quic/tools/quic_tcp_like_trace_converter.h88
-rw-r--r--chromium/net/third_party/quiche/src/quic/tools/quic_tcp_like_trace_converter_test.cc124
-rw-r--r--chromium/net/third_party/quiche/src/quic/tools/quic_toy_client.cc502
-rw-r--r--chromium/net/third_party/quiche/src/quic/tools/quic_toy_client.h51
-rw-r--r--chromium/net/third_party/quiche/src/quic/tools/quic_toy_server.cc103
-rw-r--r--chromium/net/third_party/quiche/src/quic/tools/quic_toy_server.h63
-rw-r--r--chromium/net/third_party/quiche/src/quic/tools/quic_transport_simple_server_dispatcher.cc56
-rw-r--r--chromium/net/third_party/quiche/src/quic/tools/quic_transport_simple_server_dispatcher.h42
-rw-r--r--chromium/net/third_party/quiche/src/quic/tools/quic_transport_simple_server_session.cc177
-rw-r--r--chromium/net/third_party/quiche/src/quic/tools/quic_transport_simple_server_session.h81
-rw-r--r--chromium/net/third_party/quiche/src/quic/tools/quic_url.cc101
-rw-r--r--chromium/net/third_party/quiche/src/quic/tools/quic_url.h61
-rw-r--r--chromium/net/third_party/quiche/src/quic/tools/quic_url_test.cc156
-rw-r--r--chromium/net/third_party/quiche/src/quic/tools/simple_ticket_crypter.cc112
-rw-r--r--chromium/net/third_party/quiche/src/quic/tools/simple_ticket_crypter.h56
-rw-r--r--chromium/net/third_party/quiche/src/quic/tools/simple_ticket_crypter_test.cc111
-rw-r--r--chromium/net/third_party/quiche/src/quic/tools/web_transport_test_visitors.h263
1008 files changed, 0 insertions, 303985 deletions
diff --git a/chromium/net/third_party/quiche/src/quic/core/batch_writer/quic_batch_writer_base.cc b/chromium/net/third_party/quiche/src/quic/core/batch_writer/quic_batch_writer_base.cc
deleted file mode 100644
index 9cdff7e2b6c..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/batch_writer/quic_batch_writer_base.cc
+++ /dev/null
@@ -1,181 +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 "quic/core/batch_writer/quic_batch_writer_base.h"
-#include <cstdint>
-
-#include "quic/platform/api/quic_export.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_server_stats.h"
-
-namespace quic {
-
-QuicBatchWriterBase::QuicBatchWriterBase(
- std::unique_ptr<QuicBatchWriterBuffer> batch_buffer)
- : write_blocked_(false), batch_buffer_(std::move(batch_buffer)) {}
-
-WriteResult QuicBatchWriterBase::WritePacket(
- const char* buffer,
- size_t buf_len,
- const QuicIpAddress& self_address,
- const QuicSocketAddress& peer_address,
- PerPacketOptions* options) {
- const WriteResult result =
- InternalWritePacket(buffer, buf_len, self_address, peer_address, options);
-
- if (IsWriteBlockedStatus(result.status)) {
- write_blocked_ = true;
- }
-
- return result;
-}
-
-WriteResult QuicBatchWriterBase::InternalWritePacket(
- const char* buffer,
- size_t buf_len,
- const QuicIpAddress& self_address,
- const QuicSocketAddress& peer_address,
- PerPacketOptions* options) {
- if (buf_len > kMaxOutgoingPacketSize) {
- return WriteResult(WRITE_STATUS_MSG_TOO_BIG, EMSGSIZE);
- }
-
- ReleaseTime release_time{0, QuicTime::Delta::Zero()};
- if (SupportsReleaseTime()) {
- release_time = GetReleaseTime(options);
- if (release_time.release_time_offset >= QuicTime::Delta::Zero()) {
- QUIC_SERVER_HISTOGRAM_TIMES(
- "batch_writer_positive_release_time_offset",
- release_time.release_time_offset.ToMicroseconds(), 1, 100000, 50,
- "Duration from ideal release time to actual "
- "release time, in microseconds.");
- } else {
- QUIC_SERVER_HISTOGRAM_TIMES(
- "batch_writer_negative_release_time_offset",
- -release_time.release_time_offset.ToMicroseconds(), 1, 100000, 50,
- "Duration from actual release time to ideal "
- "release time, in microseconds.");
- }
- }
-
- const CanBatchResult can_batch_result =
- CanBatch(buffer, buf_len, self_address, peer_address, options,
- release_time.actual_release_time);
-
- bool buffered = false;
- bool flush = can_batch_result.must_flush;
-
- if (can_batch_result.can_batch) {
- QuicBatchWriterBuffer::PushResult push_result =
- batch_buffer_->PushBufferedWrite(buffer, buf_len, self_address,
- peer_address, options,
- release_time.actual_release_time);
- if (push_result.succeeded) {
- buffered = true;
- // If there's no space left after the packet is buffered, force a flush.
- flush = flush || (batch_buffer_->GetNextWriteLocation() == nullptr);
- } else {
- // If there's no space without this packet, force a flush.
- flush = true;
- }
- }
-
- if (!flush) {
- WriteResult result(WRITE_STATUS_OK, 0);
- result.send_time_offset = release_time.release_time_offset;
- return result;
- }
-
- size_t num_buffered_packets = buffered_writes().size();
- const FlushImplResult flush_result = CheckedFlush();
- WriteResult result = flush_result.write_result;
- QUIC_DVLOG(1) << "Internally flushed " << flush_result.num_packets_sent
- << " out of " << num_buffered_packets
- << " packets. WriteResult=" << result;
-
- if (result.status != WRITE_STATUS_OK) {
- if (IsWriteBlockedStatus(result.status)) {
- return WriteResult(
- buffered ? WRITE_STATUS_BLOCKED_DATA_BUFFERED : WRITE_STATUS_BLOCKED,
- result.error_code);
- }
-
- // Drop all packets, including the one being written.
- size_t dropped_packets =
- buffered ? buffered_writes().size() : buffered_writes().size() + 1;
-
- batch_buffer().Clear();
- result.dropped_packets =
- dropped_packets > std::numeric_limits<uint16_t>::max()
- ? std::numeric_limits<uint16_t>::max()
- : static_cast<uint16_t>(dropped_packets);
- return result;
- }
-
- if (!buffered) {
- QuicBatchWriterBuffer::PushResult push_result =
- batch_buffer_->PushBufferedWrite(buffer, buf_len, self_address,
- peer_address, options,
- release_time.actual_release_time);
- buffered = push_result.succeeded;
-
- // Since buffered_writes has been emptied, this write must have been
- // buffered successfully.
- QUIC_BUG_IF(quic_bug_10826_1, !buffered)
- << "Failed to push to an empty batch buffer."
- << " self_addr:" << self_address.ToString()
- << ", peer_addr:" << peer_address.ToString() << ", buf_len:" << buf_len;
- }
-
- result.send_time_offset = release_time.release_time_offset;
- return result;
-}
-
-QuicBatchWriterBase::FlushImplResult QuicBatchWriterBase::CheckedFlush() {
- if (buffered_writes().empty()) {
- return FlushImplResult{WriteResult(WRITE_STATUS_OK, 0),
- /*num_packets_sent=*/0, /*bytes_written=*/0};
- }
-
- const FlushImplResult flush_result = FlushImpl();
-
- // Either flush_result.write_result.status is not WRITE_STATUS_OK, or it is
- // WRITE_STATUS_OK and batch_buffer is empty.
- QUICHE_DCHECK(flush_result.write_result.status != WRITE_STATUS_OK ||
- buffered_writes().empty());
-
- // Flush should never return WRITE_STATUS_BLOCKED_DATA_BUFFERED.
- QUICHE_DCHECK(flush_result.write_result.status !=
- WRITE_STATUS_BLOCKED_DATA_BUFFERED);
-
- return flush_result;
-}
-
-WriteResult QuicBatchWriterBase::Flush() {
- size_t num_buffered_packets = buffered_writes().size();
- FlushImplResult flush_result = CheckedFlush();
- QUIC_DVLOG(1) << "Externally flushed " << flush_result.num_packets_sent
- << " out of " << num_buffered_packets
- << " packets. WriteResult=" << flush_result.write_result;
-
- if (IsWriteError(flush_result.write_result.status)) {
- if (buffered_writes().size() > std::numeric_limits<uint16_t>::max()) {
- flush_result.write_result.dropped_packets =
- std::numeric_limits<uint16_t>::max();
- } else {
- flush_result.write_result.dropped_packets =
- static_cast<uint16_t>(buffered_writes().size());
- }
- // Treat all errors as non-retryable fatal errors. Drop all buffered packets
- // to avoid sending them and getting the same error again.
- batch_buffer().Clear();
- }
-
- if (flush_result.write_result.status == WRITE_STATUS_BLOCKED) {
- write_blocked_ = true;
- }
- return flush_result.write_result;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/batch_writer/quic_batch_writer_base.h b/chromium/net/third_party/quiche/src/quic/core/batch_writer/quic_batch_writer_base.h
deleted file mode 100644
index e7d1f129684..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/batch_writer/quic_batch_writer_base.h
+++ /dev/null
@@ -1,154 +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_IMPL_BATCH_WRITER_QUIC_BATCH_WRITER_BASE_H_
-#define QUICHE_QUIC_PLATFORM_IMPL_BATCH_WRITER_QUIC_BATCH_WRITER_BASE_H_
-
-#include <cstdint>
-#include "quic/core/batch_writer/quic_batch_writer_buffer.h"
-#include "quic/core/quic_packet_writer.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_ip_address.h"
-#include "quic/platform/api/quic_socket_address.h"
-
-namespace quic {
-
-// QuicBatchWriterBase implements logic common to all derived batch writers,
-// including maintaining write blockage state and a skeleton implemention of
-// WritePacket().
-// A derived batch writer must override the FlushImpl() function to send all
-// buffered writes in a batch. It must also override the CanBatch() function
-// to control whether/when a WritePacket() call should flush.
-class QUIC_EXPORT_PRIVATE QuicBatchWriterBase : public QuicPacketWriter {
- public:
- explicit QuicBatchWriterBase(
- std::unique_ptr<QuicBatchWriterBuffer> batch_buffer);
-
- // ATTENTION: If this write triggered a flush, and the flush failed, all
- // buffered packets will be dropped to allow the next write to work. The
- // number of dropped packets can be found in WriteResult.dropped_packets.
- WriteResult WritePacket(const char* buffer,
- size_t buf_len,
- const QuicIpAddress& self_address,
- const QuicSocketAddress& peer_address,
- PerPacketOptions* options) override;
-
- bool IsWriteBlocked() const final { return write_blocked_; }
-
- void SetWritable() final { write_blocked_ = false; }
-
- QuicByteCount GetMaxPacketSize(
- const QuicSocketAddress& /*peer_address*/) const final {
- return kMaxOutgoingPacketSize;
- }
-
- bool SupportsReleaseTime() const override { return false; }
-
- bool IsBatchMode() const final { return true; }
-
- QuicPacketBuffer GetNextWriteLocation(
- const QuicIpAddress& /*self_address*/,
- const QuicSocketAddress& /*peer_address*/) final {
- // No need to explicitly delete QuicBatchWriterBuffer.
- return {batch_buffer_->GetNextWriteLocation(), nullptr};
- }
-
- WriteResult Flush() override;
-
- protected:
- const QuicBatchWriterBuffer& batch_buffer() const { return *batch_buffer_; }
- QuicBatchWriterBuffer& batch_buffer() { return *batch_buffer_; }
-
- const quiche::QuicheCircularDeque<BufferedWrite>& buffered_writes() const {
- return batch_buffer_->buffered_writes();
- }
-
- // Given the release delay in |options| and the state of |batch_buffer_|, get
- // the absolute release time.
- struct QUIC_NO_EXPORT ReleaseTime {
- // The actual (absolute) release time.
- uint64_t actual_release_time = 0;
- // The difference between |actual_release_time| and ideal release time,
- // which is (now + |options->release_time_delay|).
- QuicTime::Delta release_time_offset = QuicTime::Delta::Zero();
- };
- virtual ReleaseTime GetReleaseTime(
- const PerPacketOptions* /*options*/) const {
- QUICHE_DCHECK(false)
- << "Should not be called since release time is unsupported.";
- return ReleaseTime{0, QuicTime::Delta::Zero()};
- }
-
- struct QUIC_EXPORT_PRIVATE CanBatchResult {
- CanBatchResult(bool can_batch, bool must_flush)
- : can_batch(can_batch), must_flush(must_flush) {}
- // Whether this write can be batched with existing buffered writes.
- bool can_batch;
- // If |can_batch|, whether the caller must flush after this packet is
- // buffered.
- // Always true if not |can_batch|.
- bool must_flush;
- };
-
- // Given the existing buffered writes(in buffered_writes()), whether a new
- // write(in the arguments) can be batched.
- virtual CanBatchResult CanBatch(const char* buffer,
- size_t buf_len,
- const QuicIpAddress& self_address,
- const QuicSocketAddress& peer_address,
- const PerPacketOptions* options,
- uint64_t release_time) const = 0;
-
- struct QUIC_EXPORT_PRIVATE FlushImplResult {
- // The return value of the Flush() interface, which is:
- // - WriteResult(WRITE_STATUS_OK, <bytes_flushed>) if all buffered writes
- // were sent successfully.
- // - WRITE_STATUS_BLOCKED or WRITE_STATUS_ERROR, if the batch write is
- // blocked or returned an error while sending. If a portion of buffered
- // writes were sent successfully, |FlushImplResult.num_packets_sent| and
- // |FlushImplResult.bytes_written| contain the number of successfully sent
- // packets and their total bytes.
- WriteResult write_result;
- int num_packets_sent;
- // If write_result.status == WRITE_STATUS_OK, |bytes_written| will be equal
- // to write_result.bytes_written. Otherwise |bytes_written| will be the
- // number of bytes written before WRITE_BLOCK or WRITE_ERROR happened.
- int bytes_written;
- };
-
- // Send all buffered writes(in buffered_writes()) in a batch.
- // buffered_writes() is guaranteed to be non-empty when this function is
- // called.
- virtual FlushImplResult FlushImpl() = 0;
-
- private:
- WriteResult InternalWritePacket(const char* buffer,
- size_t buf_len,
- const QuicIpAddress& self_address,
- const QuicSocketAddress& peer_address,
- PerPacketOptions* options);
-
- // Calls FlushImpl() and check its post condition.
- FlushImplResult CheckedFlush();
-
- bool write_blocked_;
- std::unique_ptr<QuicBatchWriterBuffer> batch_buffer_;
-};
-
-// QuicUdpBatchWriter is a batch writer backed by a UDP socket.
-class QUIC_EXPORT_PRIVATE QuicUdpBatchWriter : public QuicBatchWriterBase {
- public:
- QuicUdpBatchWriter(std::unique_ptr<QuicBatchWriterBuffer> batch_buffer,
- int fd)
- : QuicBatchWriterBase(std::move(batch_buffer)), fd_(fd) {}
-
- int fd() const { return fd_; }
-
- private:
- const int fd_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_PLATFORM_IMPL_BATCH_WRITER_QUIC_BATCH_WRITER_BASE_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/batch_writer/quic_batch_writer_buffer.cc b/chromium/net/third_party/quiche/src/quic/core/batch_writer/quic_batch_writer_buffer.cc
deleted file mode 100644
index 8a450d78114..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/batch_writer/quic_batch_writer_buffer.cc
+++ /dev/null
@@ -1,156 +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 "quic/core/batch_writer/quic_batch_writer_buffer.h"
-
-#include <sstream>
-
-namespace quic {
-
-QuicBatchWriterBuffer::QuicBatchWriterBuffer() {
- memset(buffer_, 0, sizeof(buffer_));
-}
-
-void QuicBatchWriterBuffer::Clear() {
- buffered_writes_.clear();
-}
-
-std::string QuicBatchWriterBuffer::DebugString() const {
- std::ostringstream os;
- os << "{ buffer: " << static_cast<const void*>(buffer_)
- << " buffer_end: " << static_cast<const void*>(buffer_end())
- << " buffered_writes_.size(): " << buffered_writes_.size()
- << " next_write_loc: " << static_cast<const void*>(GetNextWriteLocation())
- << " SizeInUse: " << SizeInUse() << " }";
- return os.str();
-}
-
-bool QuicBatchWriterBuffer::Invariants() const {
- // Buffers in buffered_writes_ should not overlap, and collectively they
- // should cover a continuous prefix of buffer_.
- const char* next_buffer = buffer_;
- for (auto iter = buffered_writes_.begin(); iter != buffered_writes_.end();
- ++iter) {
- if ((iter->buffer != next_buffer) ||
- (iter->buffer + iter->buf_len > buffer_end())) {
- return false;
- }
- next_buffer += iter->buf_len;
- }
-
- return static_cast<size_t>(next_buffer - buffer_) == SizeInUse();
-}
-
-char* QuicBatchWriterBuffer::GetNextWriteLocation() const {
- const char* next_loc =
- buffered_writes_.empty()
- ? buffer_
- : buffered_writes_.back().buffer + buffered_writes_.back().buf_len;
- if (static_cast<size_t>(buffer_end() - next_loc) < kMaxOutgoingPacketSize) {
- return nullptr;
- }
- return const_cast<char*>(next_loc);
-}
-
-QuicBatchWriterBuffer::PushResult QuicBatchWriterBuffer::PushBufferedWrite(
- const char* buffer,
- size_t buf_len,
- const QuicIpAddress& self_address,
- const QuicSocketAddress& peer_address,
- const PerPacketOptions* options,
- uint64_t release_time) {
- QUICHE_DCHECK(Invariants());
- QUICHE_DCHECK_LE(buf_len, kMaxOutgoingPacketSize);
-
- PushResult result = {/*succeeded=*/false, /*buffer_copied=*/false};
- char* next_write_location = GetNextWriteLocation();
- if (next_write_location == nullptr) {
- return result;
- }
-
- if (buffer != next_write_location) {
- if (IsExternalBuffer(buffer, buf_len)) {
- memcpy(next_write_location, buffer, buf_len);
- } else if (IsInternalBuffer(buffer, buf_len)) {
- memmove(next_write_location, buffer, buf_len);
- } else {
- QUIC_BUG(quic_bug_10831_1)
- << "Buffer[" << static_cast<const void*>(buffer) << ", "
- << static_cast<const void*>(buffer + buf_len)
- << ") overlaps with internal buffer["
- << static_cast<const void*>(buffer_) << ", "
- << static_cast<const void*>(buffer_end()) << ")";
- return result;
- }
- result.buffer_copied = true;
- } else {
- // In place push, do nothing.
- }
- buffered_writes_.emplace_back(
- next_write_location, buf_len, self_address, peer_address,
- options ? options->Clone() : std::unique_ptr<PerPacketOptions>(),
- release_time);
-
- QUICHE_DCHECK(Invariants());
-
- result.succeeded = true;
- return result;
-}
-
-void QuicBatchWriterBuffer::UndoLastPush() {
- if (!buffered_writes_.empty()) {
- buffered_writes_.pop_back();
- }
-}
-
-QuicBatchWriterBuffer::PopResult QuicBatchWriterBuffer::PopBufferedWrite(
- int32_t num_buffered_writes) {
- QUICHE_DCHECK(Invariants());
- QUICHE_DCHECK_GE(num_buffered_writes, 0);
- QUICHE_DCHECK_LE(static_cast<size_t>(num_buffered_writes),
- buffered_writes_.size());
-
- PopResult result = {/*num_buffers_popped=*/0,
- /*moved_remaining_buffers=*/false};
-
- result.num_buffers_popped = std::max<int32_t>(num_buffered_writes, 0);
- result.num_buffers_popped =
- std::min<int32_t>(result.num_buffers_popped, buffered_writes_.size());
- buffered_writes_.pop_front_n(result.num_buffers_popped);
-
- if (!buffered_writes_.empty()) {
- // If not all buffered writes are erased, the remaining ones will not cover
- // a continuous prefix of buffer_. We'll fix it by moving the remaining
- // buffers to the beginning of buffer_ and adjust the buffer pointers in all
- // remaining buffered writes.
- // This should happen very rarely, about once per write block.
- result.moved_remaining_buffers = true;
- const char* buffer_before_move = buffered_writes_.front().buffer;
- size_t buffer_len_to_move = buffered_writes_.back().buffer +
- buffered_writes_.back().buf_len -
- buffer_before_move;
- memmove(buffer_, buffer_before_move, buffer_len_to_move);
-
- size_t distance_to_move = buffer_before_move - buffer_;
- for (BufferedWrite& buffered_write : buffered_writes_) {
- buffered_write.buffer -= distance_to_move;
- }
-
- QUICHE_DCHECK_EQ(buffer_, buffered_writes_.front().buffer);
- }
- QUICHE_DCHECK(Invariants());
-
- return result;
-}
-
-size_t QuicBatchWriterBuffer::SizeInUse() const {
- if (buffered_writes_.empty()) {
- return 0;
- }
-
- return buffered_writes_.back().buffer + buffered_writes_.back().buf_len -
- buffer_;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/batch_writer/quic_batch_writer_buffer.h b/chromium/net/third_party/quiche/src/quic/core/batch_writer/quic_batch_writer_buffer.h
deleted file mode 100644
index 4faa3cba4e7..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/batch_writer/quic_batch_writer_buffer.h
+++ /dev/null
@@ -1,95 +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_IMPL_BATCH_WRITER_QUIC_BATCH_WRITER_BUFFER_H_
-#define QUICHE_QUIC_PLATFORM_IMPL_BATCH_WRITER_QUIC_BATCH_WRITER_BUFFER_H_
-
-#include "absl/base/optimization.h"
-#include "quic/core/quic_linux_socket_utils.h"
-#include "quic/core/quic_packet_writer.h"
-#include "quic/platform/api/quic_ip_address.h"
-#include "quic/platform/api/quic_socket_address.h"
-#include "common/quiche_circular_deque.h"
-
-namespace quic {
-
-// QuicBatchWriterBuffer manages an internal buffer to hold data from multiple
-// packets. Packet data are placed continuously within the internal buffer such
-// that they can be sent by a QuicGsoBatchWriter.
-// This class can also be used by a QuicBatchWriter which uses sendmmsg,
-// although it is not optimized for that use case.
-class QUIC_EXPORT_PRIVATE QuicBatchWriterBuffer {
- public:
- QuicBatchWriterBuffer();
-
- // Clear all buffered writes, but leave the internal buffer intact.
- void Clear();
-
- char* GetNextWriteLocation() const;
-
- // Push a buffered write to the back.
- struct QUIC_EXPORT_PRIVATE PushResult {
- bool succeeded;
- // True in one of the following cases:
- // 1) The packet buffer is external and copied to the internal buffer, or
- // 2) The packet buffer is from the internal buffer and moved within it.
- // This only happens if PopBufferedWrite is called in the middle of a
- // in-place push.
- // Only valid if |succeeded| is true.
- bool buffer_copied;
- };
-
- PushResult PushBufferedWrite(const char* buffer,
- size_t buf_len,
- const QuicIpAddress& self_address,
- const QuicSocketAddress& peer_address,
- const PerPacketOptions* options,
- uint64_t release_time);
-
- void UndoLastPush();
-
- // Pop |num_buffered_writes| buffered writes from the front.
- // |num_buffered_writes| will be capped to [0, buffered_writes().size()]
- // before it is used.
- struct QUIC_EXPORT_PRIVATE PopResult {
- int32_t num_buffers_popped;
- // True if after |num_buffers_popped| buffers are popped from front, the
- // remaining buffers are moved to the beginning of the internal buffer.
- // This should normally be false.
- bool moved_remaining_buffers;
- };
- PopResult PopBufferedWrite(int32_t num_buffered_writes);
-
- const quiche::QuicheCircularDeque<BufferedWrite>& buffered_writes() const {
- return buffered_writes_;
- }
-
- bool IsExternalBuffer(const char* buffer, size_t buf_len) const {
- return (buffer + buf_len) <= buffer_ || buffer >= buffer_end();
- }
- bool IsInternalBuffer(const char* buffer, size_t buf_len) const {
- return buffer >= buffer_ && (buffer + buf_len) <= buffer_end();
- }
-
- // Number of bytes used in |buffer_|.
- // PushBufferedWrite() increases this; PopBufferedWrite decreases this.
- size_t SizeInUse() const;
-
- // Rounded up from |kMaxGsoPacketSize|, which is the maximum allowed
- // size of a GSO packet.
- static const size_t kBufferSize = 64 * 1024;
-
- std::string DebugString() const;
-
- protected:
- // Whether the invariants of the buffer are upheld. For debug & test only.
- bool Invariants() const;
- const char* buffer_end() const { return buffer_ + sizeof(buffer_); }
- ABSL_CACHELINE_ALIGNED char buffer_[kBufferSize];
- quiche::QuicheCircularDeque<BufferedWrite> buffered_writes_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_PLATFORM_IMPL_BATCH_WRITER_QUIC_BATCH_WRITER_BUFFER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/batch_writer/quic_batch_writer_buffer_test.cc b/chromium/net/third_party/quiche/src/quic/core/batch_writer/quic_batch_writer_buffer_test.cc
deleted file mode 100644
index a234e5ede3a..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/batch_writer/quic_batch_writer_buffer_test.cc
+++ /dev/null
@@ -1,282 +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 "quic/core/batch_writer/quic_batch_writer_buffer.h"
-#include <memory>
-#include <string>
-
-#include "quic/core/quic_constants.h"
-#include "quic/platform/api/quic_ip_address.h"
-#include "quic/platform/api/quic_socket_address.h"
-#include "quic/platform/api/quic_test.h"
-
-namespace quic {
-namespace test {
-namespace {
-
-class QUIC_EXPORT_PRIVATE TestQuicBatchWriterBuffer
- : public QuicBatchWriterBuffer {
- public:
- using QuicBatchWriterBuffer::buffer_;
- using QuicBatchWriterBuffer::buffered_writes_;
-};
-
-static const size_t kBatchBufferSize = QuicBatchWriterBuffer::kBufferSize;
-
-class QuicBatchWriterBufferTest : public QuicTest {
- public:
- QuicBatchWriterBufferTest() { SwitchToNewBuffer(); }
-
- void SwitchToNewBuffer() {
- batch_buffer_ = std::make_unique<TestQuicBatchWriterBuffer>();
- }
-
- // Fill packet_buffer_ with kMaxOutgoingPacketSize bytes of |c|s.
- char* FillPacketBuffer(char c) {
- return FillPacketBuffer(c, packet_buffer_, kMaxOutgoingPacketSize);
- }
-
- // Fill |packet_buffer| with kMaxOutgoingPacketSize bytes of |c|s.
- char* FillPacketBuffer(char c, char* packet_buffer) {
- return FillPacketBuffer(c, packet_buffer, kMaxOutgoingPacketSize);
- }
-
- // Fill |packet_buffer| with |buf_len| bytes of |c|s.
- char* FillPacketBuffer(char c, char* packet_buffer, size_t buf_len) {
- memset(packet_buffer, c, buf_len);
- return packet_buffer;
- }
-
- void CheckBufferedWriteContent(int buffered_write_index,
- char buffer_content,
- size_t buf_len,
- const QuicIpAddress& self_addr,
- const QuicSocketAddress& peer_addr,
- const PerPacketOptions* options) {
- const BufferedWrite& buffered_write =
- batch_buffer_->buffered_writes()[buffered_write_index];
- EXPECT_EQ(buf_len, buffered_write.buf_len);
- for (size_t i = 0; i < buf_len; ++i) {
- EXPECT_EQ(buffer_content, buffered_write.buffer[i]);
- if (buffer_content != buffered_write.buffer[i]) {
- break;
- }
- }
- EXPECT_EQ(self_addr, buffered_write.self_address);
- EXPECT_EQ(peer_addr, buffered_write.peer_address);
- if (options == nullptr) {
- EXPECT_EQ(nullptr, buffered_write.options);
- } else {
- EXPECT_EQ(options->release_time_delay,
- buffered_write.options->release_time_delay);
- }
- }
-
- protected:
- std::unique_ptr<TestQuicBatchWriterBuffer> batch_buffer_;
- QuicIpAddress self_addr_;
- QuicSocketAddress peer_addr_;
- uint64_t release_time_ = 0;
- char packet_buffer_[kMaxOutgoingPacketSize];
-};
-
-class BufferSizeSequence {
- public:
- explicit BufferSizeSequence(
- std::vector<std::pair<std::vector<size_t>, size_t>> stages)
- : stages_(std::move(stages)),
- total_buf_len_(0),
- stage_index_(0),
- sequence_index_(0) {}
-
- size_t Next() {
- const std::vector<size_t>& seq = stages_[stage_index_].first;
- size_t buf_len = seq[sequence_index_++ % seq.size()];
- total_buf_len_ += buf_len;
- if (stages_[stage_index_].second <= total_buf_len_) {
- stage_index_ = std::min(stage_index_ + 1, stages_.size() - 1);
- }
- return buf_len;
- }
-
- private:
- const std::vector<std::pair<std::vector<size_t>, size_t>> stages_;
- size_t total_buf_len_;
- size_t stage_index_;
- size_t sequence_index_;
-};
-
-// Test in-place pushes. A in-place push is a push with a buffer address that is
-// equal to the result of GetNextWriteLocation().
-TEST_F(QuicBatchWriterBufferTest, InPlacePushes) {
- std::vector<BufferSizeSequence> buffer_size_sequences = {
- // Push large writes until the buffer is near full, then switch to 1-byte
- // writes. This covers the edge cases when detecting insufficient buffer.
- BufferSizeSequence({{{1350}, kBatchBufferSize - 3000}, {{1}, 1e6}}),
- // A sequence that looks real.
- BufferSizeSequence({{{1, 39, 97, 150, 1350, 1350, 1350, 1350}, 1e6}}),
- };
-
- for (auto& buffer_size_sequence : buffer_size_sequences) {
- SwitchToNewBuffer();
- int64_t num_push_failures = 0;
-
- while (batch_buffer_->SizeInUse() < kBatchBufferSize) {
- size_t buf_len = buffer_size_sequence.Next();
- const bool has_enough_space =
- (kBatchBufferSize - batch_buffer_->SizeInUse() >=
- kMaxOutgoingPacketSize);
-
- char* buffer = batch_buffer_->GetNextWriteLocation();
-
- if (has_enough_space) {
- EXPECT_EQ(batch_buffer_->buffer_ + batch_buffer_->SizeInUse(), buffer);
- } else {
- EXPECT_EQ(nullptr, buffer);
- }
-
- SCOPED_TRACE(testing::Message()
- << "Before Push: buf_len=" << buf_len
- << ", has_enough_space=" << has_enough_space
- << ", batch_buffer=" << batch_buffer_->DebugString());
-
- auto push_result = batch_buffer_->PushBufferedWrite(
- buffer, buf_len, self_addr_, peer_addr_, nullptr, release_time_);
- if (!push_result.succeeded) {
- ++num_push_failures;
- }
- EXPECT_EQ(has_enough_space, push_result.succeeded);
- EXPECT_FALSE(push_result.buffer_copied);
- if (!has_enough_space) {
- break;
- }
- }
- // Expect one and only one failure from the final push operation.
- EXPECT_EQ(1, num_push_failures);
- }
-}
-
-// Test some in-place pushes mixed with pushes with external buffers.
-TEST_F(QuicBatchWriterBufferTest, MixedPushes) {
- // First, a in-place push.
- char* buffer = batch_buffer_->GetNextWriteLocation();
- auto push_result = batch_buffer_->PushBufferedWrite(
- FillPacketBuffer('A', buffer), kDefaultMaxPacketSize, self_addr_,
- peer_addr_, nullptr, release_time_);
- EXPECT_TRUE(push_result.succeeded);
- EXPECT_FALSE(push_result.buffer_copied);
- CheckBufferedWriteContent(0, 'A', kDefaultMaxPacketSize, self_addr_,
- peer_addr_, nullptr);
-
- // Then a push with external buffer.
- push_result = batch_buffer_->PushBufferedWrite(
- FillPacketBuffer('B'), kDefaultMaxPacketSize, self_addr_, peer_addr_,
- nullptr, release_time_);
- EXPECT_TRUE(push_result.succeeded);
- EXPECT_TRUE(push_result.buffer_copied);
- CheckBufferedWriteContent(1, 'B', kDefaultMaxPacketSize, self_addr_,
- peer_addr_, nullptr);
-
- // Then another in-place push.
- buffer = batch_buffer_->GetNextWriteLocation();
- push_result = batch_buffer_->PushBufferedWrite(
- FillPacketBuffer('C', buffer), kDefaultMaxPacketSize, self_addr_,
- peer_addr_, nullptr, release_time_);
- EXPECT_TRUE(push_result.succeeded);
- EXPECT_FALSE(push_result.buffer_copied);
- CheckBufferedWriteContent(2, 'C', kDefaultMaxPacketSize, self_addr_,
- peer_addr_, nullptr);
-
- // Then another push with external buffer.
- push_result = batch_buffer_->PushBufferedWrite(
- FillPacketBuffer('D'), kDefaultMaxPacketSize, self_addr_, peer_addr_,
- nullptr, release_time_);
- EXPECT_TRUE(push_result.succeeded);
- EXPECT_TRUE(push_result.buffer_copied);
- CheckBufferedWriteContent(3, 'D', kDefaultMaxPacketSize, self_addr_,
- peer_addr_, nullptr);
-}
-
-TEST_F(QuicBatchWriterBufferTest, PopAll) {
- const int kNumBufferedWrites = 10;
- for (int i = 0; i < kNumBufferedWrites; ++i) {
- EXPECT_TRUE(batch_buffer_
- ->PushBufferedWrite(packet_buffer_, kDefaultMaxPacketSize,
- self_addr_, peer_addr_, nullptr,
- release_time_)
- .succeeded);
- }
- EXPECT_EQ(kNumBufferedWrites,
- static_cast<int>(batch_buffer_->buffered_writes().size()));
-
- auto pop_result = batch_buffer_->PopBufferedWrite(kNumBufferedWrites);
- EXPECT_EQ(0u, batch_buffer_->buffered_writes().size());
- EXPECT_EQ(kNumBufferedWrites, pop_result.num_buffers_popped);
- EXPECT_FALSE(pop_result.moved_remaining_buffers);
-}
-
-TEST_F(QuicBatchWriterBufferTest, PopPartial) {
- const int kNumBufferedWrites = 10;
- for (int i = 0; i < kNumBufferedWrites; ++i) {
- EXPECT_TRUE(batch_buffer_
- ->PushBufferedWrite(FillPacketBuffer('A' + i),
- kDefaultMaxPacketSize - i, self_addr_,
- peer_addr_, nullptr, release_time_)
- .succeeded);
- }
-
- for (size_t i = 0;
- i < kNumBufferedWrites && !batch_buffer_->buffered_writes().empty();
- ++i) {
- const size_t size_before_pop = batch_buffer_->buffered_writes().size();
- const size_t expect_size_after_pop =
- size_before_pop < i ? 0 : size_before_pop - i;
- batch_buffer_->PopBufferedWrite(i);
- ASSERT_EQ(expect_size_after_pop, batch_buffer_->buffered_writes().size());
- const char first_write_content =
- 'A' + kNumBufferedWrites - expect_size_after_pop;
- const size_t first_write_len =
- kDefaultMaxPacketSize - kNumBufferedWrites + expect_size_after_pop;
- for (size_t j = 0; j < expect_size_after_pop; ++j) {
- CheckBufferedWriteContent(j, first_write_content + j, first_write_len - j,
- self_addr_, peer_addr_, nullptr);
- }
- }
-}
-
-TEST_F(QuicBatchWriterBufferTest, InPlacePushWithPops) {
- // First, a in-place push.
- char* buffer = batch_buffer_->GetNextWriteLocation();
- const size_t first_packet_len = 2;
- auto push_result = batch_buffer_->PushBufferedWrite(
- FillPacketBuffer('A', buffer, first_packet_len), first_packet_len,
- self_addr_, peer_addr_, nullptr, release_time_);
- EXPECT_TRUE(push_result.succeeded);
- EXPECT_FALSE(push_result.buffer_copied);
- CheckBufferedWriteContent(0, 'A', first_packet_len, self_addr_, peer_addr_,
- nullptr);
-
- // Simulate the case where the writer wants to do another in-place push, but
- // can't do so because it can't be batched with the first buffer.
- buffer = batch_buffer_->GetNextWriteLocation();
- const size_t second_packet_len = 1350;
-
- // Flush the first buffer.
- auto pop_result = batch_buffer_->PopBufferedWrite(1);
- EXPECT_EQ(1, pop_result.num_buffers_popped);
- EXPECT_FALSE(pop_result.moved_remaining_buffers);
-
- // Now the second push.
- push_result = batch_buffer_->PushBufferedWrite(
- FillPacketBuffer('B', buffer, second_packet_len), second_packet_len,
- self_addr_, peer_addr_, nullptr, release_time_);
- EXPECT_TRUE(push_result.succeeded);
- EXPECT_TRUE(push_result.buffer_copied);
- CheckBufferedWriteContent(0, 'B', second_packet_len, self_addr_, peer_addr_,
- nullptr);
-}
-
-} // namespace
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/batch_writer/quic_batch_writer_test.cc b/chromium/net/third_party/quiche/src/quic/core/batch_writer/quic_batch_writer_test.cc
deleted file mode 100644
index 5f0dc9b0a53..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/batch_writer/quic_batch_writer_test.cc
+++ /dev/null
@@ -1,77 +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 "quic/core/batch_writer/quic_batch_writer_test.h"
-#include "quic/core/batch_writer/quic_gso_batch_writer.h"
-#include "quic/core/batch_writer/quic_sendmmsg_batch_writer.h"
-
-namespace quic {
-namespace test {
-namespace {
-
-class QuicGsoBatchWriterIOTestDelegate
- : public QuicUdpBatchWriterIOTestDelegate {
- public:
- bool ShouldSkip(const QuicUdpBatchWriterIOTestParams& params) override {
- QuicUdpSocketApi socket_api;
- int fd =
- socket_api.Create(params.address_family,
- /*receive_buffer_size=*/kDefaultSocketReceiveBuffer,
- /*send_buffer_size=*/kDefaultSocketReceiveBuffer);
- if (fd < 0) {
- QUIC_LOG(ERROR) << "CreateSocket() failed: " << strerror(errno);
- return false; // Let the test fail rather than skip it.
- }
- const bool gso_not_supported =
- QuicLinuxSocketUtils::GetUDPSegmentSize(fd) < 0;
- socket_api.Destroy(fd);
-
- if (gso_not_supported) {
- QUIC_LOG(WARNING) << "Test skipped since GSO is not supported.";
- return true;
- }
-
- QUIC_LOG(WARNING) << "OK: GSO is supported.";
- return false;
- }
-
- void ResetWriter(int fd) override {
- writer_ = std::make_unique<QuicGsoBatchWriter>(fd);
- }
-
- QuicUdpBatchWriter* GetWriter() override { return writer_.get(); }
-
- private:
- std::unique_ptr<QuicGsoBatchWriter> writer_;
-};
-
-INSTANTIATE_TEST_SUITE_P(
- QuicGsoBatchWriterTest,
- QuicUdpBatchWriterIOTest,
- testing::ValuesIn(
- MakeQuicBatchWriterTestParams<QuicGsoBatchWriterIOTestDelegate>()));
-
-class QuicSendmmsgBatchWriterIOTestDelegate
- : public QuicUdpBatchWriterIOTestDelegate {
- public:
- void ResetWriter(int fd) override {
- writer_ = std::make_unique<QuicSendmmsgBatchWriter>(
- std::make_unique<QuicBatchWriterBuffer>(), fd);
- }
-
- QuicUdpBatchWriter* GetWriter() override { return writer_.get(); }
-
- private:
- std::unique_ptr<QuicSendmmsgBatchWriter> writer_;
-};
-
-INSTANTIATE_TEST_SUITE_P(
- QuicSendmmsgBatchWriterTest,
- QuicUdpBatchWriterIOTest,
- testing::ValuesIn(MakeQuicBatchWriterTestParams<
- QuicSendmmsgBatchWriterIOTestDelegate>()));
-
-} // namespace
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/batch_writer/quic_batch_writer_test.h b/chromium/net/third_party/quiche/src/quic/core/batch_writer/quic_batch_writer_test.h
deleted file mode 100644
index e14040fb39c..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/batch_writer/quic_batch_writer_test.h
+++ /dev/null
@@ -1,287 +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_IMPL_BATCH_WRITER_QUIC_BATCH_WRITER_TEST_H_
-#define QUICHE_QUIC_PLATFORM_IMPL_BATCH_WRITER_QUIC_BATCH_WRITER_TEST_H_
-
-#include <sys/socket.h>
-#include <sys/types.h>
-
-#include <cstddef>
-#include <iostream>
-#include <utility>
-
-#include "absl/base/optimization.h"
-#include "quic/core/batch_writer/quic_batch_writer_base.h"
-#include "quic/core/quic_udp_socket.h"
-#include "quic/platform/api/quic_test.h"
-
-namespace quic {
-namespace test {
-
-static bool IsAddressFamilySupported(int address_family) {
- static auto check_function = [](int address_family) {
- int fd = socket(address_family, SOCK_STREAM, 0);
- if (fd < 0) {
- QUIC_LOG(ERROR) << "address_family not supported: " << address_family
- << ", error: " << strerror(errno);
- EXPECT_EQ(EAFNOSUPPORT, errno);
- return false;
- }
- close(fd);
- return true;
- };
-
- if (address_family == AF_INET) {
- static const bool ipv4_supported = check_function(AF_INET);
- return ipv4_supported;
- }
-
- static const bool ipv6_supported = check_function(AF_INET6);
- return ipv6_supported;
-}
-
-static bool CreateSocket(int family, QuicSocketAddress* address, int* fd) {
- if (family == AF_INET) {
- *address = QuicSocketAddress(QuicIpAddress::Loopback4(), 0);
- } else {
- QUICHE_DCHECK_EQ(family, AF_INET6);
- *address = QuicSocketAddress(QuicIpAddress::Loopback6(), 0);
- }
-
- QuicUdpSocketApi socket_api;
- *fd = socket_api.Create(family,
- /*receive_buffer_size=*/kDefaultSocketReceiveBuffer,
- /*send_buffer_size=*/kDefaultSocketReceiveBuffer);
- if (*fd < 0) {
- QUIC_LOG(ERROR) << "CreateSocket() failed: " << strerror(errno);
- return false;
- }
- socket_api.EnableDroppedPacketCount(*fd);
-
- if (!socket_api.Bind(*fd, *address)) {
- QUIC_LOG(ERROR) << "Bind failed: " << strerror(errno);
- return false;
- }
-
- if (address->FromSocket(*fd) != 0) {
- QUIC_LOG(ERROR) << "Unable to get self address. Error: "
- << strerror(errno);
- return false;
- }
- return true;
-}
-
-struct QuicUdpBatchWriterIOTestParams;
-class QUIC_EXPORT_PRIVATE QuicUdpBatchWriterIOTestDelegate {
- public:
- virtual ~QuicUdpBatchWriterIOTestDelegate() {}
-
- virtual bool ShouldSkip(const QuicUdpBatchWriterIOTestParams& /*params*/) {
- return false;
- }
-
- virtual void ResetWriter(int fd) = 0;
-
- virtual QuicUdpBatchWriter* GetWriter() = 0;
-};
-
-struct QUIC_EXPORT_PRIVATE QuicUdpBatchWriterIOTestParams {
- // Use shared_ptr because gtest makes copies of test params.
- std::shared_ptr<QuicUdpBatchWriterIOTestDelegate> delegate;
- int address_family;
- int data_size;
- int packet_size;
-
- QUIC_EXPORT_PRIVATE friend std::ostream& operator<<(
- std::ostream& os,
- const QuicUdpBatchWriterIOTestParams& p) {
- os << "{ address_family: " << p.address_family
- << " data_size: " << p.data_size << " packet_size: " << p.packet_size
- << " }";
- return os;
- }
-};
-
-template <class QuicUdpBatchWriterIOTestDelegateT>
-static std::vector<QuicUdpBatchWriterIOTestParams>
-MakeQuicBatchWriterTestParams() {
- static_assert(std::is_base_of<QuicUdpBatchWriterIOTestDelegate,
- QuicUdpBatchWriterIOTestDelegateT>::value,
- "<QuicUdpBatchWriterIOTestDelegateT> needs to derive from "
- "QuicUdpBatchWriterIOTestDelegate");
-
- std::vector<QuicUdpBatchWriterIOTestParams> params;
- for (int address_family : {AF_INET, AF_INET6}) {
- for (int data_size : {1, 150, 1500, 15000, 64000, 512 * 1024}) {
- for (int packet_size : {1, 50, 1350, 1452}) {
- if (packet_size <= data_size && (data_size / packet_size < 2000)) {
- params.push_back(
- {std::make_unique<QuicUdpBatchWriterIOTestDelegateT>(),
- address_family, data_size, packet_size});
- }
- }
- }
- }
- return params;
-}
-
-// QuicUdpBatchWriterIOTest is a value parameterized test fixture that can be
-// used by tests of derived classes of QuicUdpBatchWriter, to verify basic
-// packet IO capabilities.
-class QUIC_EXPORT_PRIVATE QuicUdpBatchWriterIOTest
- : public QuicTestWithParam<QuicUdpBatchWriterIOTestParams> {
- protected:
- QuicUdpBatchWriterIOTest()
- : address_family_(GetParam().address_family),
- data_size_(GetParam().data_size),
- packet_size_(GetParam().packet_size),
- self_socket_(-1),
- peer_socket_(-1) {
- QUIC_LOG(INFO) << "QuicUdpBatchWriterIOTestParams: " << GetParam();
- EXPECT_TRUE(address_family_ == AF_INET || address_family_ == AF_INET6);
- EXPECT_LE(packet_size_, data_size_);
- EXPECT_LE(packet_size_, sizeof(packet_buffer_));
- }
-
- ~QuicUdpBatchWriterIOTest() override {
- if (self_socket_ > 0) {
- close(self_socket_);
- }
- if (peer_socket_ > 0) {
- close(peer_socket_);
- }
- }
-
- // Whether this test should be skipped. A test is passed if skipped.
- // A test can be skipped when e.g. it exercises a kernel feature that is not
- // available on the system.
- bool ShouldSkip() {
- if (!IsAddressFamilySupported(address_family_)) {
- QUIC_LOG(WARNING)
- << "Test skipped since address_family is not supported.";
- return true;
- }
-
- return GetParam().delegate->ShouldSkip(GetParam());
- }
-
- // Initialize a test.
- // To fail the test in Initialize, use ASSERT_xx macros.
- void Initialize() {
- ASSERT_TRUE(CreateSocket(address_family_, &self_address_, &self_socket_));
- ASSERT_TRUE(CreateSocket(address_family_, &peer_address_, &peer_socket_));
-
- QUIC_DLOG(INFO) << "Self address: " << self_address_.ToString() << ", fd "
- << self_socket_;
- QUIC_DLOG(INFO) << "Peer address: " << peer_address_.ToString() << ", fd "
- << peer_socket_;
- GetParam().delegate->ResetWriter(self_socket_);
- }
-
- QuicUdpBatchWriter* GetWriter() { return GetParam().delegate->GetWriter(); }
-
- void ValidateWrite() {
- char this_packet_content = '\0';
- int this_packet_size;
- int num_writes = 0;
- size_t bytes_flushed = 0;
- WriteResult result;
-
- for (size_t bytes_sent = 0; bytes_sent < data_size_;
- bytes_sent += this_packet_size, ++this_packet_content) {
- this_packet_size = std::min(packet_size_, data_size_ - bytes_sent);
- memset(&packet_buffer_[0], this_packet_content, this_packet_size);
-
- result = GetWriter()->WritePacket(&packet_buffer_[0], this_packet_size,
- self_address_.host(), peer_address_,
- nullptr);
-
- ASSERT_EQ(WRITE_STATUS_OK, result.status) << strerror(result.error_code);
- bytes_flushed += result.bytes_written;
- ++num_writes;
-
- QUIC_DVLOG(1) << "[write #" << num_writes
- << "] this_packet_size: " << this_packet_size
- << ", total_bytes_sent: " << bytes_sent + this_packet_size
- << ", bytes_flushed: " << bytes_flushed
- << ", pkt content:" << std::hex << int(this_packet_content);
- }
-
- result = GetWriter()->Flush();
- ASSERT_EQ(WRITE_STATUS_OK, result.status) << strerror(result.error_code);
- bytes_flushed += result.bytes_written;
- ASSERT_EQ(data_size_, bytes_flushed);
-
- QUIC_LOG(INFO) << "Sent " << data_size_ << " bytes in " << num_writes
- << " writes.";
- }
-
- void ValidateRead() {
- char this_packet_content = '\0';
- int this_packet_size;
- int packets_received = 0;
- for (size_t bytes_received = 0; bytes_received < data_size_;
- bytes_received += this_packet_size, ++this_packet_content) {
- this_packet_size = std::min(packet_size_, data_size_ - bytes_received);
- SCOPED_TRACE(testing::Message()
- << "Before ReadPacket: bytes_received=" << bytes_received
- << ", this_packet_size=" << this_packet_size);
-
- QuicUdpSocketApi::ReadPacketResult result;
- result.packet_buffer = {&packet_buffer_[0], sizeof(packet_buffer_)};
- result.control_buffer = {&control_buffer_[0], sizeof(control_buffer_)};
- QuicUdpSocketApi().ReadPacket(
- peer_socket_,
- quic::BitMask64(QuicUdpPacketInfoBit::V4_SELF_IP,
- QuicUdpPacketInfoBit::V6_SELF_IP,
- QuicUdpPacketInfoBit::PEER_ADDRESS),
- &result);
- ASSERT_TRUE(result.ok);
- ASSERT_TRUE(
- result.packet_info.HasValue(QuicUdpPacketInfoBit::PEER_ADDRESS));
- QuicSocketAddress read_peer_address = result.packet_info.peer_address();
- QuicIpAddress read_self_address = read_peer_address.host().IsIPv6()
- ? result.packet_info.self_v6_ip()
- : result.packet_info.self_v4_ip();
-
- EXPECT_EQ(read_self_address, peer_address_.host());
- EXPECT_EQ(read_peer_address, self_address_);
- for (int i = 0; i < this_packet_size; ++i) {
- EXPECT_EQ(this_packet_content, packet_buffer_[i]);
- }
- packets_received += this_packet_size;
- }
-
- QUIC_LOG(INFO) << "Received " << data_size_ << " bytes in "
- << packets_received << " packets.";
- }
-
- QuicSocketAddress self_address_;
- QuicSocketAddress peer_address_;
- ABSL_CACHELINE_ALIGNED char packet_buffer_[1500];
- ABSL_CACHELINE_ALIGNED char
- control_buffer_[kDefaultUdpPacketControlBufferSize];
- int address_family_;
- const size_t data_size_;
- const size_t packet_size_;
- int self_socket_;
- int peer_socket_;
-};
-
-TEST_P(QuicUdpBatchWriterIOTest, WriteAndRead) {
- if (ShouldSkip()) {
- return;
- }
-
- Initialize();
-
- ValidateWrite();
- ValidateRead();
-}
-
-} // namespace test
-} // namespace quic
-
-#endif // QUICHE_QUIC_PLATFORM_IMPL_BATCH_WRITER_QUIC_BATCH_WRITER_TEST_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/batch_writer/quic_gso_batch_writer.cc b/chromium/net/third_party/quiche/src/quic/core/batch_writer/quic_gso_batch_writer.cc
deleted file mode 100644
index fa26516872e..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/batch_writer/quic_gso_batch_writer.cc
+++ /dev/null
@@ -1,164 +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 "quic/core/batch_writer/quic_gso_batch_writer.h"
-
-#include <time.h>
-#include <ctime>
-
-#include "quic/core/quic_linux_socket_utils.h"
-#include "quic/platform/api/quic_server_stats.h"
-
-namespace quic {
-
-// static
-std::unique_ptr<QuicBatchWriterBuffer>
-QuicGsoBatchWriter::CreateBatchWriterBuffer() {
- return std::make_unique<QuicBatchWriterBuffer>();
-}
-
-QuicGsoBatchWriter::QuicGsoBatchWriter(int fd)
- : QuicGsoBatchWriter(fd, CLOCK_MONOTONIC) {}
-
-QuicGsoBatchWriter::QuicGsoBatchWriter(int fd,
- clockid_t clockid_for_release_time)
- : QuicUdpBatchWriter(CreateBatchWriterBuffer(), fd),
- clockid_for_release_time_(clockid_for_release_time),
- supports_release_time_(
- GetQuicRestartFlag(quic_support_release_time_for_gso) &&
- QuicLinuxSocketUtils::EnableReleaseTime(fd,
- clockid_for_release_time)) {
- if (supports_release_time_) {
- QUIC_RESTART_FLAG_COUNT(quic_support_release_time_for_gso);
- QUIC_LOG_FIRST_N(INFO, 5) << "Release time is enabled.";
- } else {
- QUIC_LOG_FIRST_N(INFO, 5) << "Release time is not enabled.";
- }
-}
-
-QuicGsoBatchWriter::QuicGsoBatchWriter(
- std::unique_ptr<QuicBatchWriterBuffer> batch_buffer,
- int fd,
- clockid_t clockid_for_release_time,
- ReleaseTimeForceEnabler /*enabler*/)
- : QuicUdpBatchWriter(std::move(batch_buffer), fd),
- clockid_for_release_time_(clockid_for_release_time),
- supports_release_time_(true) {
- QUIC_DLOG(INFO) << "Release time forcefully enabled.";
-}
-
-QuicGsoBatchWriter::CanBatchResult QuicGsoBatchWriter::CanBatch(
- const char* /*buffer*/,
- size_t buf_len,
- const QuicIpAddress& self_address,
- const QuicSocketAddress& peer_address,
- const PerPacketOptions* options,
- uint64_t release_time) const {
- // If there is nothing buffered already, this write will be included in this
- // batch.
- if (buffered_writes().empty()) {
- return CanBatchResult(/*can_batch=*/true, /*must_flush=*/false);
- }
-
- // The new write can be batched if all of the following are true:
- // [0] The total number of the GSO segments(one write=one segment, including
- // the new write) must not exceed |max_segments|.
- // [1] It has the same source and destination addresses as already buffered
- // writes.
- // [2] It won't cause this batch to exceed kMaxGsoPacketSize.
- // [3] Already buffered writes all have the same length.
- // [4] Length of already buffered writes must >= length of the new write.
- // [5] The new packet can be released without delay, or it has the same
- // release time as buffered writes.
- const BufferedWrite& first = buffered_writes().front();
- const BufferedWrite& last = buffered_writes().back();
- // Whether this packet can be sent without delay, regardless of release time.
- const bool can_burst = !SupportsReleaseTime() || !options ||
- options->release_time_delay.IsZero() ||
- options->allow_burst;
- size_t max_segments = MaxSegments(first.buf_len);
- bool can_batch =
- buffered_writes().size() < max_segments && // [0]
- last.self_address == self_address && // [1]
- last.peer_address == peer_address && // [1]
- batch_buffer().SizeInUse() + buf_len <= kMaxGsoPacketSize && // [2]
- first.buf_len == last.buf_len && // [3]
- first.buf_len >= buf_len && // [4]
- (can_burst || first.release_time == release_time); // [5]
-
- // A flush is required if any of the following is true:
- // [a] The new write can't be batched.
- // [b] Length of the new write is different from the length of already
- // buffered writes.
- // [c] The total number of the GSO segments, including the new write, reaches
- // |max_segments|.
- bool must_flush = (!can_batch) || // [a]
- (last.buf_len != buf_len) || // [b]
- (buffered_writes().size() + 1 == max_segments); // [c]
- return CanBatchResult(can_batch, must_flush);
-}
-
-QuicGsoBatchWriter::ReleaseTime QuicGsoBatchWriter::GetReleaseTime(
- const PerPacketOptions* options) const {
- QUICHE_DCHECK(SupportsReleaseTime());
-
- if (options == nullptr) {
- return {0, QuicTime::Delta::Zero()};
- }
-
- const uint64_t now = NowInNanosForReleaseTime();
- const uint64_t ideal_release_time =
- now + options->release_time_delay.ToMicroseconds() * 1000;
-
- if ((options->release_time_delay.IsZero() || options->allow_burst) &&
- !buffered_writes().empty() &&
- // If release time of buffered packets is in the past, flush buffered
- // packets and buffer this packet at the ideal release time.
- (buffered_writes().back().release_time >= now)) {
- // Send as soon as possible, but no sooner than the last buffered packet.
- const uint64_t actual_release_time = buffered_writes().back().release_time;
-
- const int64_t offset_ns = actual_release_time - ideal_release_time;
- ReleaseTime result{actual_release_time,
- QuicTime::Delta::FromMicroseconds(offset_ns / 1000)};
-
- QUIC_DVLOG(1) << "ideal_release_time:" << ideal_release_time
- << ", actual_release_time:" << actual_release_time
- << ", offset:" << result.release_time_offset;
- return result;
- }
-
- // Send according to the release time delay.
- return {ideal_release_time, QuicTime::Delta::Zero()};
-}
-
-uint64_t QuicGsoBatchWriter::NowInNanosForReleaseTime() const {
- struct timespec ts;
-
- if (clock_gettime(clockid_for_release_time_, &ts) != 0) {
- return 0;
- }
-
- return ts.tv_sec * (1000ULL * 1000 * 1000) + ts.tv_nsec;
-}
-
-// static
-void QuicGsoBatchWriter::BuildCmsg(QuicMsgHdr* hdr,
- const QuicIpAddress& self_address,
- uint16_t gso_size,
- uint64_t release_time) {
- hdr->SetIpInNextCmsg(self_address);
- if (gso_size > 0) {
- *hdr->GetNextCmsgData<uint16_t>(SOL_UDP, UDP_SEGMENT) = gso_size;
- }
- if (release_time != 0) {
- *hdr->GetNextCmsgData<uint64_t>(SOL_SOCKET, SO_TXTIME) = release_time;
- }
-}
-
-QuicGsoBatchWriter::FlushImplResult QuicGsoBatchWriter::FlushImpl() {
- return InternalFlushImpl<kCmsgSpace>(BuildCmsg);
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/batch_writer/quic_gso_batch_writer.h b/chromium/net/third_party/quiche/src/quic/core/batch_writer/quic_gso_batch_writer.h
deleted file mode 100644
index f87e9f8e78d..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/batch_writer/quic_gso_batch_writer.h
+++ /dev/null
@@ -1,117 +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_IMPL_BATCH_WRITER_QUIC_GSO_BATCH_WRITER_H_
-#define QUICHE_QUIC_PLATFORM_IMPL_BATCH_WRITER_QUIC_GSO_BATCH_WRITER_H_
-
-#include "quic/core/batch_writer/quic_batch_writer_base.h"
-
-namespace quic {
-
-// QuicGsoBatchWriter sends QUIC packets in batches, using UDP socket's generic
-// segmentation offload(GSO) capability.
-class QUIC_EXPORT_PRIVATE QuicGsoBatchWriter : public QuicUdpBatchWriter {
- public:
- explicit QuicGsoBatchWriter(int fd);
-
- // |clockid_for_release_time|: FQ qdisc requires CLOCK_MONOTONIC, EDF requires
- // CLOCK_TAI.
- QuicGsoBatchWriter(int fd, clockid_t clockid_for_release_time);
-
- bool SupportsReleaseTime() const final { return supports_release_time_; }
-
- CanBatchResult CanBatch(const char* buffer,
- size_t buf_len,
- const QuicIpAddress& self_address,
- const QuicSocketAddress& peer_address,
- const PerPacketOptions* options,
- uint64_t release_time) const override;
-
- FlushImplResult FlushImpl() override;
-
- protected:
- // Test only constructor to forcefully enable release time.
- struct QUIC_EXPORT_PRIVATE ReleaseTimeForceEnabler {};
- QuicGsoBatchWriter(std::unique_ptr<QuicBatchWriterBuffer> batch_buffer,
- int fd,
- clockid_t clockid_for_release_time,
- ReleaseTimeForceEnabler enabler);
-
- ReleaseTime GetReleaseTime(const PerPacketOptions* options) const override;
-
- // Get the current time in nanos from |clockid_for_release_time_|.
- virtual uint64_t NowInNanosForReleaseTime() const;
-
- static size_t MaxSegments(size_t gso_size) {
- // Max segments should be the min of UDP_MAX_SEGMENTS(64) and
- // (((64KB - sizeof(ip hdr) - sizeof(udp hdr)) / MSS) + 1), in the typical
- // case of IPv6 packets with 1500-byte MTU, the result is
- // ((64KB - 40 - 8) / (1500 - 48)) + 1 = 46
- // However, due a kernel bug, the limit is much lower for tiny gso_sizes.
- return gso_size <= 2 ? 16 : 45;
- }
-
- static const int kCmsgSpace =
- kCmsgSpaceForIp + kCmsgSpaceForSegmentSize + kCmsgSpaceForTxTime;
- static void BuildCmsg(QuicMsgHdr* hdr,
- const QuicIpAddress& self_address,
- uint16_t gso_size,
- uint64_t release_time);
-
- template <size_t CmsgSpace, typename CmsgBuilderT>
- FlushImplResult InternalFlushImpl(CmsgBuilderT cmsg_builder) {
- QUICHE_DCHECK(!IsWriteBlocked());
- QUICHE_DCHECK(!buffered_writes().empty());
-
- FlushImplResult result = {WriteResult(WRITE_STATUS_OK, 0),
- /*num_packets_sent=*/0, /*bytes_written=*/0};
- WriteResult& write_result = result.write_result;
-
- int total_bytes = batch_buffer().SizeInUse();
- const BufferedWrite& first = buffered_writes().front();
- char cbuf[CmsgSpace];
- QuicMsgHdr hdr(first.buffer, total_bytes, first.peer_address, cbuf,
- sizeof(cbuf));
-
- uint16_t gso_size = buffered_writes().size() > 1 ? first.buf_len : 0;
- cmsg_builder(&hdr, first.self_address, gso_size, first.release_time);
-
- write_result = QuicLinuxSocketUtils::WritePacket(fd(), hdr);
- QUIC_DVLOG(1) << "Write GSO packet result: " << write_result
- << ", fd: " << fd()
- << ", self_address: " << first.self_address.ToString()
- << ", peer_address: " << first.peer_address.ToString()
- << ", num_segments: " << buffered_writes().size()
- << ", total_bytes: " << total_bytes
- << ", gso_size: " << gso_size
- << ", release_time: " << first.release_time;
-
- // All segments in a GSO packet share the same fate - if the write failed,
- // none of them are sent, and it's not needed to call PopBufferedWrite().
- if (write_result.status != WRITE_STATUS_OK) {
- return result;
- }
-
- result.num_packets_sent = buffered_writes().size();
-
- write_result.bytes_written = total_bytes;
- result.bytes_written = total_bytes;
-
- batch_buffer().PopBufferedWrite(buffered_writes().size());
-
- QUIC_BUG_IF(quic_bug_12544_1, !buffered_writes().empty())
- << "All packets should have been written on a successful return";
- return result;
- }
-
- private:
- static std::unique_ptr<QuicBatchWriterBuffer> CreateBatchWriterBuffer();
-
- const clockid_t clockid_for_release_time_;
- const bool supports_release_time_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_PLATFORM_IMPL_BATCH_WRITER_QUIC_GSO_BATCH_WRITER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/batch_writer/quic_gso_batch_writer_test.cc b/chromium/net/third_party/quiche/src/quic/core/batch_writer/quic_gso_batch_writer_test.cc
deleted file mode 100644
index 4aab1982f55..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/batch_writer/quic_gso_batch_writer_test.cc
+++ /dev/null
@@ -1,472 +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 "quic/core/batch_writer/quic_gso_batch_writer.h"
-
-#include <cstdint>
-#include <limits>
-#include <memory>
-#include <utility>
-
-#include "quic/platform/api/quic_ip_address.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/quic_mock_syscall_wrapper.h"
-
-using testing::_;
-using testing::Invoke;
-using testing::StrictMock;
-
-namespace quic {
-namespace test {
-namespace {
-
-size_t PacketLength(const msghdr* msg) {
- size_t length = 0;
- for (size_t i = 0; i < msg->msg_iovlen; ++i) {
- length += msg->msg_iov[i].iov_len;
- }
- return length;
-}
-
-uint64_t MillisToNanos(uint64_t milliseconds) {
- return milliseconds * 1000000;
-}
-
-class QUIC_EXPORT_PRIVATE TestQuicGsoBatchWriter : public QuicGsoBatchWriter {
- public:
- using QuicGsoBatchWriter::batch_buffer;
- using QuicGsoBatchWriter::buffered_writes;
- using QuicGsoBatchWriter::CanBatch;
- using QuicGsoBatchWriter::CanBatchResult;
- using QuicGsoBatchWriter::GetReleaseTime;
- using QuicGsoBatchWriter::MaxSegments;
- using QuicGsoBatchWriter::QuicGsoBatchWriter;
- using QuicGsoBatchWriter::ReleaseTime;
-
- static std::unique_ptr<TestQuicGsoBatchWriter>
- NewInstanceWithReleaseTimeSupport() {
- return std::unique_ptr<TestQuicGsoBatchWriter>(new TestQuicGsoBatchWriter(
- std::make_unique<QuicBatchWriterBuffer>(),
- /*fd=*/-1, CLOCK_MONOTONIC, ReleaseTimeForceEnabler()));
- }
-
- uint64_t NowInNanosForReleaseTime() const override {
- return MillisToNanos(forced_release_time_ms_);
- }
-
- void ForceReleaseTimeMs(uint64_t forced_release_time_ms) {
- forced_release_time_ms_ = forced_release_time_ms;
- }
-
- private:
- uint64_t forced_release_time_ms_ = 1;
-};
-
-struct QUIC_EXPORT_PRIVATE TestPerPacketOptions : public PerPacketOptions {
- std::unique_ptr<quic::PerPacketOptions> Clone() const override {
- return std::make_unique<TestPerPacketOptions>(*this);
- }
-};
-
-// TestBufferedWrite is a copy-constructible BufferedWrite.
-struct QUIC_EXPORT_PRIVATE TestBufferedWrite : public BufferedWrite {
- using BufferedWrite::BufferedWrite;
- TestBufferedWrite(const TestBufferedWrite& other)
- : BufferedWrite(other.buffer,
- other.buf_len,
- other.self_address,
- other.peer_address,
- other.options ? other.options->Clone()
- : std::unique_ptr<PerPacketOptions>(),
- other.release_time) {}
-};
-
-// Pointed to by all instances of |BatchCriteriaTestData|. Content not used.
-static char unused_packet_buffer[kMaxOutgoingPacketSize];
-
-struct QUIC_EXPORT_PRIVATE BatchCriteriaTestData {
- BatchCriteriaTestData(size_t buf_len,
- const QuicIpAddress& self_address,
- const QuicSocketAddress& peer_address,
- uint64_t release_time,
- bool can_batch,
- bool must_flush)
- : buffered_write(unused_packet_buffer,
- buf_len,
- self_address,
- peer_address,
- std::unique_ptr<PerPacketOptions>(),
- release_time),
- can_batch(can_batch),
- must_flush(must_flush) {}
-
- TestBufferedWrite buffered_write;
- // Expected value of CanBatchResult.can_batch when batching |buffered_write|.
- bool can_batch;
- // Expected value of CanBatchResult.must_flush when batching |buffered_write|.
- bool must_flush;
-};
-
-std::vector<BatchCriteriaTestData> BatchCriteriaTestData_SizeDecrease() {
- const QuicIpAddress self_addr;
- const QuicSocketAddress peer_addr;
- std::vector<BatchCriteriaTestData> test_data_table = {
- // clang-format off
- // buf_len self_addr peer_addr t_rel can_batch must_flush
- {1350, self_addr, peer_addr, 0, true, false},
- {1350, self_addr, peer_addr, 0, true, false},
- {1350, self_addr, peer_addr, 0, true, false},
- {39, self_addr, peer_addr, 0, true, true},
- {39, self_addr, peer_addr, 0, false, true},
- {1350, self_addr, peer_addr, 0, false, true},
- // clang-format on
- };
- return test_data_table;
-}
-
-std::vector<BatchCriteriaTestData> BatchCriteriaTestData_SizeIncrease() {
- const QuicIpAddress self_addr;
- const QuicSocketAddress peer_addr;
- std::vector<BatchCriteriaTestData> test_data_table = {
- // clang-format off
- // buf_len self_addr peer_addr t_rel can_batch must_flush
- {1350, self_addr, peer_addr, 0, true, false},
- {1350, self_addr, peer_addr, 0, true, false},
- {1350, self_addr, peer_addr, 0, true, false},
- {1351, self_addr, peer_addr, 0, false, true},
- // clang-format on
- };
- return test_data_table;
-}
-
-std::vector<BatchCriteriaTestData> BatchCriteriaTestData_AddressChange() {
- const QuicIpAddress self_addr1 = QuicIpAddress::Loopback4();
- const QuicIpAddress self_addr2 = QuicIpAddress::Loopback6();
- const QuicSocketAddress peer_addr1(self_addr1, 666);
- const QuicSocketAddress peer_addr2(self_addr1, 777);
- const QuicSocketAddress peer_addr3(self_addr2, 666);
- const QuicSocketAddress peer_addr4(self_addr2, 777);
- std::vector<BatchCriteriaTestData> test_data_table = {
- // clang-format off
- // buf_len self_addr peer_addr t_rel can_batch must_flush
- {1350, self_addr1, peer_addr1, 0, true, false},
- {1350, self_addr1, peer_addr1, 0, true, false},
- {1350, self_addr1, peer_addr1, 0, true, false},
- {1350, self_addr2, peer_addr1, 0, false, true},
- {1350, self_addr1, peer_addr2, 0, false, true},
- {1350, self_addr1, peer_addr3, 0, false, true},
- {1350, self_addr1, peer_addr4, 0, false, true},
- {1350, self_addr1, peer_addr4, 0, false, true},
- // clang-format on
- };
- return test_data_table;
-}
-
-std::vector<BatchCriteriaTestData> BatchCriteriaTestData_ReleaseTime1() {
- const QuicIpAddress self_addr;
- const QuicSocketAddress peer_addr;
- std::vector<BatchCriteriaTestData> test_data_table = {
- // clang-format off
- // buf_len self_addr peer_addr t_rel can_batch must_flush
- {1350, self_addr, peer_addr, 5, true, false},
- {1350, self_addr, peer_addr, 5, true, false},
- {1350, self_addr, peer_addr, 5, true, false},
- {1350, self_addr, peer_addr, 9, false, true},
- // clang-format on
- };
- return test_data_table;
-}
-
-std::vector<BatchCriteriaTestData> BatchCriteriaTestData_ReleaseTime2() {
- const QuicIpAddress self_addr;
- const QuicSocketAddress peer_addr;
- std::vector<BatchCriteriaTestData> test_data_table = {
- // clang-format off
- // buf_len self_addr peer_addr t_rel can_batch must_flush
- {1350, self_addr, peer_addr, 0, true, false},
- {1350, self_addr, peer_addr, 0, true, false},
- {1350, self_addr, peer_addr, 0, true, false},
- {1350, self_addr, peer_addr, 9, false, true},
- // clang-format on
- };
- return test_data_table;
-}
-
-std::vector<BatchCriteriaTestData> BatchCriteriaTestData_MaxSegments(
- size_t gso_size) {
- const QuicIpAddress self_addr;
- const QuicSocketAddress peer_addr;
- std::vector<BatchCriteriaTestData> test_data_table;
- size_t max_segments = TestQuicGsoBatchWriter::MaxSegments(gso_size);
- for (size_t i = 0; i < max_segments; ++i) {
- bool is_last_in_batch = (i + 1 == max_segments);
- test_data_table.push_back({gso_size, self_addr, peer_addr,
- /*release_time=*/0, true, is_last_in_batch});
- }
- test_data_table.push_back(
- {gso_size, self_addr, peer_addr, /*release_time=*/0, false, true});
- return test_data_table;
-}
-
-class QuicGsoBatchWriterTest : public QuicTest {
- protected:
- WriteResult WritePacket(QuicGsoBatchWriter* writer, size_t packet_size) {
- return writer->WritePacket(&packet_buffer_[0], packet_size, self_address_,
- peer_address_, nullptr);
- }
-
- WriteResult WritePacketWithOptions(QuicGsoBatchWriter* writer,
- PerPacketOptions* options) {
- return writer->WritePacket(&packet_buffer_[0], 1350, self_address_,
- peer_address_, options);
- }
-
- QuicIpAddress self_address_ = QuicIpAddress::Any4();
- QuicSocketAddress peer_address_{QuicIpAddress::Any4(), 443};
- char packet_buffer_[1500];
- StrictMock<MockQuicSyscallWrapper> mock_syscalls_;
- ScopedGlobalSyscallWrapperOverride syscall_override_{&mock_syscalls_};
-};
-
-TEST_F(QuicGsoBatchWriterTest, BatchCriteria) {
- std::unique_ptr<TestQuicGsoBatchWriter> writer;
-
- std::vector<std::vector<BatchCriteriaTestData>> test_data_tables;
- test_data_tables.emplace_back(BatchCriteriaTestData_SizeDecrease());
- test_data_tables.emplace_back(BatchCriteriaTestData_SizeIncrease());
- test_data_tables.emplace_back(BatchCriteriaTestData_AddressChange());
- test_data_tables.emplace_back(BatchCriteriaTestData_ReleaseTime1());
- test_data_tables.emplace_back(BatchCriteriaTestData_ReleaseTime2());
- test_data_tables.emplace_back(BatchCriteriaTestData_MaxSegments(1));
- test_data_tables.emplace_back(BatchCriteriaTestData_MaxSegments(2));
- test_data_tables.emplace_back(BatchCriteriaTestData_MaxSegments(1350));
-
- for (size_t i = 0; i < test_data_tables.size(); ++i) {
- writer = TestQuicGsoBatchWriter::NewInstanceWithReleaseTimeSupport();
-
- const auto& test_data_table = test_data_tables[i];
- for (size_t j = 0; j < test_data_table.size(); ++j) {
- const BatchCriteriaTestData& test_data = test_data_table[j];
- SCOPED_TRACE(testing::Message() << "i=" << i << ", j=" << j);
- TestPerPacketOptions options;
- options.release_time_delay = QuicTime::Delta::FromMicroseconds(
- test_data.buffered_write.release_time);
- TestQuicGsoBatchWriter::CanBatchResult result = writer->CanBatch(
- test_data.buffered_write.buffer, test_data.buffered_write.buf_len,
- test_data.buffered_write.self_address,
- test_data.buffered_write.peer_address, &options,
- test_data.buffered_write.release_time);
-
- ASSERT_EQ(test_data.can_batch, result.can_batch);
- ASSERT_EQ(test_data.must_flush, result.must_flush);
-
- if (result.can_batch) {
- ASSERT_TRUE(writer->batch_buffer()
- .PushBufferedWrite(
- test_data.buffered_write.buffer,
- test_data.buffered_write.buf_len,
- test_data.buffered_write.self_address,
- test_data.buffered_write.peer_address, &options,
- test_data.buffered_write.release_time)
- .succeeded);
- }
- }
- }
-}
-
-TEST_F(QuicGsoBatchWriterTest, WriteSuccess) {
- TestQuicGsoBatchWriter writer(/*fd=*/-1);
-
- ASSERT_EQ(WriteResult(WRITE_STATUS_OK, 0), WritePacket(&writer, 1000));
-
- EXPECT_CALL(mock_syscalls_, Sendmsg(_, _, _))
- .WillOnce(Invoke([](int /*sockfd*/, const msghdr* msg, int /*flags*/) {
- EXPECT_EQ(1100u, PacketLength(msg));
- return 1100;
- }));
- ASSERT_EQ(WriteResult(WRITE_STATUS_OK, 1100), WritePacket(&writer, 100));
- ASSERT_EQ(0u, writer.batch_buffer().SizeInUse());
- ASSERT_EQ(0u, writer.buffered_writes().size());
-}
-
-TEST_F(QuicGsoBatchWriterTest, WriteBlockDataNotBuffered) {
- TestQuicGsoBatchWriter writer(/*fd=*/-1);
-
- ASSERT_EQ(WriteResult(WRITE_STATUS_OK, 0), WritePacket(&writer, 100));
- ASSERT_EQ(WriteResult(WRITE_STATUS_OK, 0), WritePacket(&writer, 100));
-
- EXPECT_CALL(mock_syscalls_, Sendmsg(_, _, _))
- .WillOnce(Invoke([](int /*sockfd*/, const msghdr* msg, int /*flags*/) {
- EXPECT_EQ(200u, PacketLength(msg));
- errno = EWOULDBLOCK;
- return -1;
- }));
- ASSERT_EQ(WriteResult(WRITE_STATUS_BLOCKED, EWOULDBLOCK),
- WritePacket(&writer, 150));
- ASSERT_EQ(200u, writer.batch_buffer().SizeInUse());
- ASSERT_EQ(2u, writer.buffered_writes().size());
-}
-
-TEST_F(QuicGsoBatchWriterTest, WriteBlockDataBuffered) {
- TestQuicGsoBatchWriter writer(/*fd=*/-1);
-
- ASSERT_EQ(WriteResult(WRITE_STATUS_OK, 0), WritePacket(&writer, 100));
- ASSERT_EQ(WriteResult(WRITE_STATUS_OK, 0), WritePacket(&writer, 100));
-
- EXPECT_CALL(mock_syscalls_, Sendmsg(_, _, _))
- .WillOnce(Invoke([](int /*sockfd*/, const msghdr* msg, int /*flags*/) {
- EXPECT_EQ(250u, PacketLength(msg));
- errno = EWOULDBLOCK;
- return -1;
- }));
- ASSERT_EQ(WriteResult(WRITE_STATUS_BLOCKED_DATA_BUFFERED, EWOULDBLOCK),
- WritePacket(&writer, 50));
-
- EXPECT_TRUE(writer.IsWriteBlocked());
-
- ASSERT_EQ(250u, writer.batch_buffer().SizeInUse());
- ASSERT_EQ(3u, writer.buffered_writes().size());
-}
-
-TEST_F(QuicGsoBatchWriterTest, WriteErrorWithoutDataBuffered) {
- TestQuicGsoBatchWriter writer(/*fd=*/-1);
-
- ASSERT_EQ(WriteResult(WRITE_STATUS_OK, 0), WritePacket(&writer, 100));
- ASSERT_EQ(WriteResult(WRITE_STATUS_OK, 0), WritePacket(&writer, 100));
-
- EXPECT_CALL(mock_syscalls_, Sendmsg(_, _, _))
- .WillOnce(Invoke([](int /*sockfd*/, const msghdr* msg, int /*flags*/) {
- EXPECT_EQ(200u, PacketLength(msg));
- errno = EPERM;
- return -1;
- }));
- WriteResult error_result = WritePacket(&writer, 150);
- ASSERT_EQ(WriteResult(WRITE_STATUS_ERROR, EPERM), error_result);
-
- ASSERT_EQ(3u, error_result.dropped_packets);
- ASSERT_EQ(0u, writer.batch_buffer().SizeInUse());
- ASSERT_EQ(0u, writer.buffered_writes().size());
-}
-
-TEST_F(QuicGsoBatchWriterTest, WriteErrorAfterDataBuffered) {
- TestQuicGsoBatchWriter writer(/*fd=*/-1);
-
- ASSERT_EQ(WriteResult(WRITE_STATUS_OK, 0), WritePacket(&writer, 100));
- ASSERT_EQ(WriteResult(WRITE_STATUS_OK, 0), WritePacket(&writer, 100));
-
- EXPECT_CALL(mock_syscalls_, Sendmsg(_, _, _))
- .WillOnce(Invoke([](int /*sockfd*/, const msghdr* msg, int /*flags*/) {
- EXPECT_EQ(250u, PacketLength(msg));
- errno = EPERM;
- return -1;
- }));
- WriteResult error_result = WritePacket(&writer, 50);
- ASSERT_EQ(WriteResult(WRITE_STATUS_ERROR, EPERM), error_result);
-
- ASSERT_EQ(3u, error_result.dropped_packets);
- ASSERT_EQ(0u, writer.batch_buffer().SizeInUse());
- ASSERT_EQ(0u, writer.buffered_writes().size());
-}
-
-TEST_F(QuicGsoBatchWriterTest, FlushError) {
- TestQuicGsoBatchWriter writer(/*fd=*/-1);
-
- ASSERT_EQ(WriteResult(WRITE_STATUS_OK, 0), WritePacket(&writer, 100));
- ASSERT_EQ(WriteResult(WRITE_STATUS_OK, 0), WritePacket(&writer, 100));
-
- EXPECT_CALL(mock_syscalls_, Sendmsg(_, _, _))
- .WillOnce(Invoke([](int /*sockfd*/, const msghdr* msg, int /*flags*/) {
- EXPECT_EQ(200u, PacketLength(msg));
- errno = EINVAL;
- return -1;
- }));
- WriteResult error_result = writer.Flush();
- ASSERT_EQ(WriteResult(WRITE_STATUS_ERROR, EINVAL), error_result);
-
- ASSERT_EQ(2u, error_result.dropped_packets);
- ASSERT_EQ(0u, writer.batch_buffer().SizeInUse());
- ASSERT_EQ(0u, writer.buffered_writes().size());
-}
-
-TEST_F(QuicGsoBatchWriterTest, ReleaseTimeNullOptions) {
- auto writer = TestQuicGsoBatchWriter::NewInstanceWithReleaseTimeSupport();
- EXPECT_EQ(0u, writer->GetReleaseTime(nullptr).actual_release_time);
-}
-
-TEST_F(QuicGsoBatchWriterTest, ReleaseTime) {
- const WriteResult write_buffered(WRITE_STATUS_OK, 0);
-
- auto writer = TestQuicGsoBatchWriter::NewInstanceWithReleaseTimeSupport();
-
- TestPerPacketOptions options;
- EXPECT_TRUE(options.release_time_delay.IsZero());
- EXPECT_FALSE(options.allow_burst);
- EXPECT_EQ(MillisToNanos(1),
- writer->GetReleaseTime(&options).actual_release_time);
-
- // The 1st packet has no delay.
- WriteResult result = WritePacketWithOptions(writer.get(), &options);
- ASSERT_EQ(write_buffered, result);
- EXPECT_EQ(MillisToNanos(1), writer->buffered_writes().back().release_time);
- EXPECT_EQ(result.send_time_offset, QuicTime::Delta::Zero());
-
- // The 2nd packet has some delay, but allows burst.
- options.release_time_delay = QuicTime::Delta::FromMilliseconds(3);
- options.allow_burst = true;
- result = WritePacketWithOptions(writer.get(), &options);
- ASSERT_EQ(write_buffered, result);
- EXPECT_EQ(MillisToNanos(1), writer->buffered_writes().back().release_time);
- EXPECT_EQ(result.send_time_offset, QuicTime::Delta::FromMilliseconds(-3));
-
- // The 3rd packet has more delay and does not allow burst.
- // The first 2 packets are flushed due to different release time.
- EXPECT_CALL(mock_syscalls_, Sendmsg(_, _, _))
- .WillOnce(Invoke([](int /*sockfd*/, const msghdr* msg, int /*flags*/) {
- EXPECT_EQ(2700u, PacketLength(msg));
- errno = 0;
- return 0;
- }));
- options.release_time_delay = QuicTime::Delta::FromMilliseconds(5);
- options.allow_burst = false;
- result = WritePacketWithOptions(writer.get(), &options);
- ASSERT_EQ(WriteResult(WRITE_STATUS_OK, 2700), result);
- EXPECT_EQ(MillisToNanos(6), writer->buffered_writes().back().release_time);
- EXPECT_EQ(result.send_time_offset, QuicTime::Delta::Zero());
-
- // The 4th packet has same delay, but allows burst.
- options.allow_burst = true;
- result = WritePacketWithOptions(writer.get(), &options);
- ASSERT_EQ(write_buffered, result);
- EXPECT_EQ(MillisToNanos(6), writer->buffered_writes().back().release_time);
- EXPECT_EQ(result.send_time_offset, QuicTime::Delta::Zero());
-
- // The 5th packet has same delay, allows burst, but is shorter.
- // Packets 3,4 and 5 are flushed.
- EXPECT_CALL(mock_syscalls_, Sendmsg(_, _, _))
- .WillOnce(Invoke([](int /*sockfd*/, const msghdr* msg, int /*flags*/) {
- EXPECT_EQ(3000u, PacketLength(msg));
- errno = 0;
- return 0;
- }));
- options.allow_burst = true;
- EXPECT_EQ(MillisToNanos(6),
- writer->GetReleaseTime(&options).actual_release_time);
- ASSERT_EQ(WriteResult(WRITE_STATUS_OK, 3000),
- writer->WritePacket(&packet_buffer_[0], 300, self_address_,
- peer_address_, &options));
- EXPECT_TRUE(writer->buffered_writes().empty());
-
- // Pretend 1ms has elapsed and the 6th packet has 1ms less delay. In other
- // words, the release time should still be the same as packets 3-5.
- writer->ForceReleaseTimeMs(2);
- options.release_time_delay = QuicTime::Delta::FromMilliseconds(4);
- result = WritePacketWithOptions(writer.get(), &options);
- ASSERT_EQ(write_buffered, result);
- EXPECT_EQ(MillisToNanos(6), writer->buffered_writes().back().release_time);
- EXPECT_EQ(result.send_time_offset, QuicTime::Delta::Zero());
-}
-
-} // namespace
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/batch_writer/quic_sendmmsg_batch_writer.cc b/chromium/net/third_party/quiche/src/quic/core/batch_writer/quic_sendmmsg_batch_writer.cc
deleted file mode 100644
index d5c03298607..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/batch_writer/quic_sendmmsg_batch_writer.cc
+++ /dev/null
@@ -1,84 +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 "quic/core/batch_writer/quic_sendmmsg_batch_writer.h"
-
-namespace quic {
-
-QuicSendmmsgBatchWriter::QuicSendmmsgBatchWriter(
- std::unique_ptr<QuicBatchWriterBuffer> batch_buffer,
- int fd)
- : QuicUdpBatchWriter(std::move(batch_buffer), fd) {}
-
-QuicSendmmsgBatchWriter::CanBatchResult QuicSendmmsgBatchWriter::CanBatch(
- const char* /*buffer*/,
- size_t /*buf_len*/,
- const QuicIpAddress& /*self_address*/,
- const QuicSocketAddress& /*peer_address*/,
- const PerPacketOptions* /*options*/,
- uint64_t /*release_time*/) const {
- return CanBatchResult(/*can_batch=*/true, /*must_flush=*/false);
-}
-
-QuicSendmmsgBatchWriter::FlushImplResult QuicSendmmsgBatchWriter::FlushImpl() {
- return InternalFlushImpl(
- kCmsgSpaceForIp,
- [](QuicMMsgHdr* mhdr, int i, const BufferedWrite& buffered_write) {
- mhdr->SetIpInNextCmsg(i, buffered_write.self_address);
- });
-}
-
-QuicSendmmsgBatchWriter::FlushImplResult
-QuicSendmmsgBatchWriter::InternalFlushImpl(size_t cmsg_space,
- const CmsgBuilder& cmsg_builder) {
- QUICHE_DCHECK(!IsWriteBlocked());
- QUICHE_DCHECK(!buffered_writes().empty());
-
- FlushImplResult result = {WriteResult(WRITE_STATUS_OK, 0),
- /*num_packets_sent=*/0, /*bytes_written=*/0};
- WriteResult& write_result = result.write_result;
-
- auto first = buffered_writes().cbegin();
- const auto last = buffered_writes().cend();
- while (first != last) {
- QuicMMsgHdr mhdr(first, last, cmsg_space, cmsg_builder);
-
- int num_packets_sent;
- write_result = QuicLinuxSocketUtils::WriteMultiplePackets(
- fd(), &mhdr, &num_packets_sent);
- QUIC_DVLOG(1) << "WriteMultiplePackets sent " << num_packets_sent
- << " out of " << mhdr.num_msgs()
- << " packets. WriteResult=" << write_result;
-
- if (write_result.status != WRITE_STATUS_OK) {
- QUICHE_DCHECK_EQ(0, num_packets_sent);
- break;
- } else if (num_packets_sent == 0) {
- QUIC_BUG(quic_bug_10825_1)
- << "WriteMultiplePackets returned OK, but no packets were sent.";
- write_result = WriteResult(WRITE_STATUS_ERROR, EIO);
- break;
- }
-
- first += num_packets_sent;
-
- result.num_packets_sent += num_packets_sent;
- result.bytes_written += write_result.bytes_written;
- }
-
- // Call PopBufferedWrite() even if write_result.status is not WRITE_STATUS_OK,
- // to deal with partial writes.
- batch_buffer().PopBufferedWrite(result.num_packets_sent);
-
- if (write_result.status != WRITE_STATUS_OK) {
- return result;
- }
-
- QUIC_BUG_IF(quic_bug_12537_1, !buffered_writes().empty())
- << "All packets should have been written on a successful return";
- write_result.bytes_written = result.bytes_written;
- return result;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/batch_writer/quic_sendmmsg_batch_writer.h b/chromium/net/third_party/quiche/src/quic/core/batch_writer/quic_sendmmsg_batch_writer.h
deleted file mode 100644
index 5efcb1de48b..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/batch_writer/quic_sendmmsg_batch_writer.h
+++ /dev/null
@@ -1,35 +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_IMPL_QUIC_SENDMMSG_BATCH_WRITER_H_
-#define QUICHE_QUIC_PLATFORM_IMPL_QUIC_SENDMMSG_BATCH_WRITER_H_
-
-#include "quic/core/batch_writer/quic_batch_writer_base.h"
-#include "quic/core/quic_linux_socket_utils.h"
-
-namespace quic {
-
-class QUIC_EXPORT_PRIVATE QuicSendmmsgBatchWriter : public QuicUdpBatchWriter {
- public:
- QuicSendmmsgBatchWriter(std::unique_ptr<QuicBatchWriterBuffer> batch_buffer,
- int fd);
-
- CanBatchResult CanBatch(const char* buffer,
- size_t buf_len,
- const QuicIpAddress& self_address,
- const QuicSocketAddress& peer_address,
- const PerPacketOptions* options,
- uint64_t release_time) const override;
-
- FlushImplResult FlushImpl() override;
-
- protected:
- using CmsgBuilder = QuicMMsgHdr::ControlBufferInitializer;
- FlushImplResult InternalFlushImpl(size_t cmsg_space,
- const CmsgBuilder& cmsg_builder);
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_PLATFORM_IMPL_QUIC_SENDMMSG_BATCH_WRITER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/batch_writer/quic_sendmmsg_batch_writer_test.cc b/chromium/net/third_party/quiche/src/quic/core/batch_writer/quic_sendmmsg_batch_writer_test.cc
deleted file mode 100644
index 1265fae7f78..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/batch_writer/quic_sendmmsg_batch_writer_test.cc
+++ /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.
-
-#include "quic/core/batch_writer/quic_sendmmsg_batch_writer.h"
-
-namespace quic {
-namespace test {
-namespace {
-
-// Add tests here.
-
-} // namespace
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/chlo_extractor.cc b/chromium/net/third_party/quiche/src/quic/core/chlo_extractor.cc
deleted file mode 100644
index 29a43a605e0..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/chlo_extractor.cc
+++ /dev/null
@@ -1,364 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/chlo_extractor.h"
-
-#include "absl/strings/match.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/crypto/crypto_framer.h"
-#include "quic/core/crypto/crypto_handshake.h"
-#include "quic/core/crypto/crypto_handshake_message.h"
-#include "quic/core/crypto/crypto_protocol.h"
-#include "quic/core/crypto/crypto_utils.h"
-#include "quic/core/crypto/quic_decrypter.h"
-#include "quic/core/crypto/quic_encrypter.h"
-#include "quic/core/frames/quic_ack_frequency_frame.h"
-#include "quic/core/quic_framer.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_utils.h"
-
-namespace quic {
-
-namespace {
-
-class ChloFramerVisitor : public QuicFramerVisitorInterface,
- public CryptoFramerVisitorInterface {
- public:
- ChloFramerVisitor(QuicFramer* framer,
- const QuicTagVector& create_session_tag_indicators,
- ChloExtractor::Delegate* delegate);
-
- ~ChloFramerVisitor() override = default;
-
- // QuicFramerVisitorInterface implementation
- void OnError(QuicFramer* /*framer*/) override {}
- bool OnProtocolVersionMismatch(ParsedQuicVersion version) override;
- void OnPacket() override {}
- void OnPublicResetPacket(const QuicPublicResetPacket& /*packet*/) override {}
- void OnVersionNegotiationPacket(
- const QuicVersionNegotiationPacket& /*packet*/) override {}
- void OnRetryPacket(QuicConnectionId /*original_connection_id*/,
- QuicConnectionId /*new_connection_id*/,
- absl::string_view /*retry_token*/,
- absl::string_view /*retry_integrity_tag*/,
- absl::string_view /*retry_without_tag*/) override {}
- bool OnUnauthenticatedPublicHeader(const QuicPacketHeader& header) override;
- bool OnUnauthenticatedHeader(const QuicPacketHeader& header) override;
- void OnDecryptedPacket(size_t /*length*/,
- EncryptionLevel /*level*/) override {}
- bool OnPacketHeader(const QuicPacketHeader& header) override;
- void OnCoalescedPacket(const QuicEncryptedPacket& packet) override;
- void OnUndecryptablePacket(const QuicEncryptedPacket& packet,
- EncryptionLevel decryption_level,
- bool has_decryption_key) override;
- bool OnStreamFrame(const QuicStreamFrame& frame) override;
- bool OnCryptoFrame(const QuicCryptoFrame& frame) override;
- bool OnAckFrameStart(QuicPacketNumber largest_acked,
- QuicTime::Delta ack_delay_time) override;
- bool OnAckRange(QuicPacketNumber start, QuicPacketNumber end) override;
- bool OnAckTimestamp(QuicPacketNumber packet_number,
- QuicTime timestamp) override;
- bool OnAckFrameEnd(QuicPacketNumber start) override;
- bool OnStopWaitingFrame(const QuicStopWaitingFrame& frame) override;
- bool OnPingFrame(const QuicPingFrame& frame) override;
- bool OnRstStreamFrame(const QuicRstStreamFrame& frame) override;
- bool OnConnectionCloseFrame(const QuicConnectionCloseFrame& frame) override;
- bool OnNewConnectionIdFrame(const QuicNewConnectionIdFrame& frame) override;
- bool OnRetireConnectionIdFrame(
- const QuicRetireConnectionIdFrame& frame) override;
- bool OnNewTokenFrame(const QuicNewTokenFrame& frame) override;
- bool OnStopSendingFrame(const QuicStopSendingFrame& frame) override;
- bool OnPathChallengeFrame(const QuicPathChallengeFrame& frame) override;
- bool OnPathResponseFrame(const QuicPathResponseFrame& frame) override;
- bool OnGoAwayFrame(const QuicGoAwayFrame& frame) override;
- bool OnMaxStreamsFrame(const QuicMaxStreamsFrame& frame) override;
- bool OnStreamsBlockedFrame(const QuicStreamsBlockedFrame& frame) override;
- bool OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame) override;
- bool OnBlockedFrame(const QuicBlockedFrame& frame) override;
- bool OnPaddingFrame(const QuicPaddingFrame& frame) override;
- bool OnMessageFrame(const QuicMessageFrame& frame) override;
- bool OnHandshakeDoneFrame(const QuicHandshakeDoneFrame& frame) override;
- bool OnAckFrequencyFrame(const QuicAckFrequencyFrame& farme) override;
- void OnPacketComplete() override {}
- bool IsValidStatelessResetToken(
- const StatelessResetToken& token) const override;
- void OnAuthenticatedIetfStatelessResetPacket(
- const QuicIetfStatelessResetPacket& /*packet*/) override {}
- void OnKeyUpdate(KeyUpdateReason /*reason*/) override;
- void OnDecryptedFirstPacketInKeyPhase() override;
- std::unique_ptr<QuicDecrypter> AdvanceKeysAndCreateCurrentOneRttDecrypter()
- override;
- std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() override;
-
- // CryptoFramerVisitorInterface implementation.
- void OnError(CryptoFramer* framer) override;
- void OnHandshakeMessage(const CryptoHandshakeMessage& message) override;
-
- // Shared implementation between OnStreamFrame and OnCryptoFrame.
- bool OnHandshakeData(absl::string_view data);
-
- bool found_chlo() { return found_chlo_; }
- bool chlo_contains_tags() { return chlo_contains_tags_; }
-
- private:
- QuicFramer* framer_;
- const QuicTagVector& create_session_tag_indicators_;
- ChloExtractor::Delegate* delegate_;
- bool found_chlo_;
- bool chlo_contains_tags_;
- QuicConnectionId connection_id_;
-};
-
-ChloFramerVisitor::ChloFramerVisitor(
- QuicFramer* framer,
- const QuicTagVector& create_session_tag_indicators,
- ChloExtractor::Delegate* delegate)
- : framer_(framer),
- create_session_tag_indicators_(create_session_tag_indicators),
- delegate_(delegate),
- found_chlo_(false),
- chlo_contains_tags_(false),
- connection_id_(EmptyQuicConnectionId()) {}
-
-bool ChloFramerVisitor::OnProtocolVersionMismatch(ParsedQuicVersion version) {
- if (!framer_->IsSupportedVersion(version)) {
- return false;
- }
- framer_->set_version(version);
- return true;
-}
-
-bool ChloFramerVisitor::OnUnauthenticatedPublicHeader(
- const QuicPacketHeader& header) {
- connection_id_ = header.destination_connection_id;
- // QuicFramer creates a NullEncrypter and NullDecrypter at level
- // ENCRYPTION_INITIAL. While those are the correct ones to use with some
- // versions of QUIC, others use the IETF-style initial crypters, so those need
- // to be created and installed.
- framer_->SetInitialObfuscators(header.destination_connection_id);
- return true;
-}
-bool ChloFramerVisitor::OnUnauthenticatedHeader(
- const QuicPacketHeader& /*header*/) {
- return true;
-}
-bool ChloFramerVisitor::OnPacketHeader(const QuicPacketHeader& /*header*/) {
- return true;
-}
-
-void ChloFramerVisitor::OnCoalescedPacket(
- const QuicEncryptedPacket& /*packet*/) {}
-
-void ChloFramerVisitor::OnUndecryptablePacket(
- const QuicEncryptedPacket& /*packet*/,
- EncryptionLevel /*decryption_level*/,
- bool /*has_decryption_key*/) {}
-
-bool ChloFramerVisitor::OnStreamFrame(const QuicStreamFrame& frame) {
- if (QuicVersionUsesCryptoFrames(framer_->transport_version())) {
- // CHLO will be sent in CRYPTO frames in v47 and above.
- return false;
- }
- absl::string_view data(frame.data_buffer, frame.data_length);
- if (QuicUtils::IsCryptoStreamId(framer_->transport_version(),
- frame.stream_id) &&
- frame.offset == 0 && absl::StartsWith(data, "CHLO")) {
- return OnHandshakeData(data);
- }
- return true;
-}
-
-bool ChloFramerVisitor::OnCryptoFrame(const QuicCryptoFrame& frame) {
- if (!QuicVersionUsesCryptoFrames(framer_->transport_version())) {
- // CHLO will be in stream frames before v47.
- return false;
- }
- absl::string_view data(frame.data_buffer, frame.data_length);
- if (frame.offset == 0 && absl::StartsWith(data, "CHLO")) {
- return OnHandshakeData(data);
- }
- return true;
-}
-
-bool ChloFramerVisitor::OnHandshakeData(absl::string_view data) {
- CryptoFramer crypto_framer;
- crypto_framer.set_visitor(this);
- if (!crypto_framer.ProcessInput(data)) {
- return false;
- }
- // Interrogate the crypto framer and see if there are any
- // intersecting tags between what we saw in the maybe-CHLO and the
- // indicator set.
- for (const QuicTag tag : create_session_tag_indicators_) {
- if (crypto_framer.HasTag(tag)) {
- chlo_contains_tags_ = true;
- }
- }
- if (chlo_contains_tags_ && delegate_) {
- // Unfortunately, because this is a partial CHLO,
- // OnHandshakeMessage was never called, so the ALPN was never
- // extracted. Fake it up a bit and send it to the delegate so that
- // the correct dispatch can happen.
- crypto_framer.ForceHandshake();
- }
-
- return true;
-}
-
-bool ChloFramerVisitor::OnAckFrameStart(QuicPacketNumber /*largest_acked*/,
- QuicTime::Delta /*ack_delay_time*/) {
- return true;
-}
-
-bool ChloFramerVisitor::OnAckRange(QuicPacketNumber /*start*/,
- QuicPacketNumber /*end*/) {
- return true;
-}
-
-bool ChloFramerVisitor::OnAckTimestamp(QuicPacketNumber /*packet_number*/,
- QuicTime /*timestamp*/) {
- return true;
-}
-
-bool ChloFramerVisitor::OnAckFrameEnd(QuicPacketNumber /*start*/) {
- return true;
-}
-
-bool ChloFramerVisitor::OnStopWaitingFrame(
- const QuicStopWaitingFrame& /*frame*/) {
- return true;
-}
-
-bool ChloFramerVisitor::OnPingFrame(const QuicPingFrame& /*frame*/) {
- return true;
-}
-
-bool ChloFramerVisitor::OnRstStreamFrame(const QuicRstStreamFrame& /*frame*/) {
- return true;
-}
-
-bool ChloFramerVisitor::OnConnectionCloseFrame(
- const QuicConnectionCloseFrame& /*frame*/) {
- return true;
-}
-
-bool ChloFramerVisitor::OnStopSendingFrame(
- const QuicStopSendingFrame& /*frame*/) {
- return true;
-}
-
-bool ChloFramerVisitor::OnPathChallengeFrame(
- const QuicPathChallengeFrame& /*frame*/) {
- return true;
-}
-
-bool ChloFramerVisitor::OnPathResponseFrame(
- const QuicPathResponseFrame& /*frame*/) {
- return true;
-}
-
-bool ChloFramerVisitor::OnGoAwayFrame(const QuicGoAwayFrame& /*frame*/) {
- return true;
-}
-
-bool ChloFramerVisitor::OnWindowUpdateFrame(
- const QuicWindowUpdateFrame& /*frame*/) {
- return true;
-}
-
-bool ChloFramerVisitor::OnBlockedFrame(const QuicBlockedFrame& /*frame*/) {
- return true;
-}
-
-bool ChloFramerVisitor::OnNewConnectionIdFrame(
- const QuicNewConnectionIdFrame& /*frame*/) {
- return true;
-}
-
-bool ChloFramerVisitor::OnRetireConnectionIdFrame(
- const QuicRetireConnectionIdFrame& /*frame*/) {
- return true;
-}
-
-bool ChloFramerVisitor::OnNewTokenFrame(const QuicNewTokenFrame& /*frame*/) {
- return true;
-}
-
-bool ChloFramerVisitor::OnPaddingFrame(const QuicPaddingFrame& /*frame*/) {
- return true;
-}
-
-bool ChloFramerVisitor::OnMessageFrame(const QuicMessageFrame& /*frame*/) {
- return true;
-}
-
-bool ChloFramerVisitor::OnHandshakeDoneFrame(
- const QuicHandshakeDoneFrame& /*frame*/) {
- return true;
-}
-
-bool ChloFramerVisitor::OnAckFrequencyFrame(
- const QuicAckFrequencyFrame& /*frame*/) {
- return true;
-}
-
-bool ChloFramerVisitor::IsValidStatelessResetToken(
- const StatelessResetToken& /*token*/) const {
- return false;
-}
-
-bool ChloFramerVisitor::OnMaxStreamsFrame(
- const QuicMaxStreamsFrame& /*frame*/) {
- return true;
-}
-
-bool ChloFramerVisitor::OnStreamsBlockedFrame(
- const QuicStreamsBlockedFrame& /*frame*/) {
- return true;
-}
-
-void ChloFramerVisitor::OnKeyUpdate(KeyUpdateReason /*reason*/) {}
-
-void ChloFramerVisitor::OnDecryptedFirstPacketInKeyPhase() {}
-
-std::unique_ptr<QuicDecrypter>
-ChloFramerVisitor::AdvanceKeysAndCreateCurrentOneRttDecrypter() {
- return nullptr;
-}
-
-std::unique_ptr<QuicEncrypter>
-ChloFramerVisitor::CreateCurrentOneRttEncrypter() {
- return nullptr;
-}
-
-void ChloFramerVisitor::OnError(CryptoFramer* /*framer*/) {}
-
-void ChloFramerVisitor::OnHandshakeMessage(
- const CryptoHandshakeMessage& message) {
- if (delegate_ != nullptr) {
- delegate_->OnChlo(framer_->transport_version(), connection_id_, message);
- }
- found_chlo_ = true;
-}
-
-} // namespace
-
-// static
-bool ChloExtractor::Extract(const QuicEncryptedPacket& packet,
- ParsedQuicVersion version,
- const QuicTagVector& create_session_tag_indicators,
- Delegate* delegate,
- uint8_t connection_id_length) {
- QUIC_DVLOG(1) << "Extracting CHLO using version " << version;
- QuicFramer framer({version}, QuicTime::Zero(), Perspective::IS_SERVER,
- connection_id_length);
- ChloFramerVisitor visitor(&framer, create_session_tag_indicators, delegate);
- framer.set_visitor(&visitor);
- if (!framer.ProcessPacket(packet)) {
- return false;
- }
- return visitor.found_chlo() || visitor.chlo_contains_tags();
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/chlo_extractor.h b/chromium/net/third_party/quiche/src/quic/core/chlo_extractor.h
deleted file mode 100644
index 4e5bbe1c871..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/chlo_extractor.h
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_CHLO_EXTRACTOR_H_
-#define QUICHE_QUIC_CORE_CHLO_EXTRACTOR_H_
-
-#include "quic/core/crypto/crypto_handshake_message.h"
-#include "quic/core/quic_packets.h"
-
-namespace quic {
-
-// A utility for extracting QUIC Client Hello messages from packets,
-// without needs to spin up a full QuicSession.
-class QUIC_NO_EXPORT ChloExtractor {
- public:
- class QUIC_NO_EXPORT Delegate {
- public:
- virtual ~Delegate() {}
-
- // Called when a CHLO message is found in the packets.
- virtual void OnChlo(QuicTransportVersion version,
- QuicConnectionId connection_id,
- const CryptoHandshakeMessage& chlo) = 0;
- };
-
- // Extracts a CHLO message from |packet| and invokes the OnChlo
- // method of |delegate|. Return true if a CHLO message was found,
- // and false otherwise. If non-empty,
- // |create_session_tag_indicators| contains a list of QUIC tags that
- // if found will result in the session being created early, to
- // enable support for multi-packet CHLOs.
- static bool Extract(const QuicEncryptedPacket& packet,
- ParsedQuicVersion version,
- const QuicTagVector& create_session_tag_indicators,
- Delegate* delegate,
- uint8_t connection_id_length);
-
- ChloExtractor(const ChloExtractor&) = delete;
- ChloExtractor operator=(const ChloExtractor&) = delete;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_CHLO_EXTRACTOR_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/chlo_extractor_test.cc b/chromium/net/third_party/quiche/src/quic/core/chlo_extractor_test.cc
deleted file mode 100644
index 69006203cd4..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/chlo_extractor_test.cc
+++ /dev/null
@@ -1,179 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/chlo_extractor.h"
-
-#include <memory>
-#include <string>
-#include <utility>
-
-#include "absl/base/macros.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_framer.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/crypto_test_utils.h"
-#include "quic/test_tools/first_flight.h"
-#include "quic/test_tools/quic_test_utils.h"
-
-namespace quic {
-namespace test {
-namespace {
-
-class TestDelegate : public ChloExtractor::Delegate {
- public:
- TestDelegate() = default;
- ~TestDelegate() override = default;
-
- // ChloExtractor::Delegate implementation
- void OnChlo(QuicTransportVersion version,
- QuicConnectionId connection_id,
- const CryptoHandshakeMessage& chlo) override {
- version_ = version;
- connection_id_ = connection_id;
- chlo_ = chlo.DebugString();
- absl::string_view alpn_value;
- if (chlo.GetStringPiece(kALPN, &alpn_value)) {
- alpn_ = std::string(alpn_value);
- }
- }
-
- QuicConnectionId connection_id() const { return connection_id_; }
- QuicTransportVersion transport_version() const { return version_; }
- const std::string& chlo() const { return chlo_; }
- const std::string& alpn() const { return alpn_; }
-
- private:
- QuicConnectionId connection_id_;
- QuicTransportVersion version_;
- std::string chlo_;
- std::string alpn_;
-};
-
-class ChloExtractorTest : public QuicTestWithParam<ParsedQuicVersion> {
- public:
- ChloExtractorTest() : version_(GetParam()) {}
-
- void MakePacket(absl::string_view data,
- bool munge_offset,
- bool munge_stream_id) {
- QuicPacketHeader header;
- header.destination_connection_id = TestConnectionId();
- header.destination_connection_id_included = CONNECTION_ID_PRESENT;
- header.version_flag = true;
- header.version = version_;
- header.reset_flag = false;
- header.packet_number_length = PACKET_4BYTE_PACKET_NUMBER;
- header.packet_number = QuicPacketNumber(1);
- if (version_.HasLongHeaderLengths()) {
- header.retry_token_length_length = VARIABLE_LENGTH_INTEGER_LENGTH_1;
- header.length_length = VARIABLE_LENGTH_INTEGER_LENGTH_2;
- }
- QuicFrames frames;
- size_t offset = 0;
- if (munge_offset) {
- offset++;
- }
- QuicFramer framer(SupportedVersions(version_), QuicTime::Zero(),
- Perspective::IS_CLIENT, kQuicDefaultConnectionIdLength);
- framer.SetInitialObfuscators(TestConnectionId());
- if (!version_.UsesCryptoFrames() || munge_stream_id) {
- QuicStreamId stream_id =
- QuicUtils::GetCryptoStreamId(version_.transport_version);
- if (munge_stream_id) {
- stream_id++;
- }
- frames.push_back(
- QuicFrame(QuicStreamFrame(stream_id, false, offset, data)));
- } else {
- frames.push_back(
- QuicFrame(new QuicCryptoFrame(ENCRYPTION_INITIAL, offset, data)));
- }
- std::unique_ptr<QuicPacket> packet(
- BuildUnsizedDataPacket(&framer, header, frames));
- EXPECT_TRUE(packet != nullptr);
- size_t encrypted_length =
- framer.EncryptPayload(ENCRYPTION_INITIAL, header.packet_number, *packet,
- buffer_, ABSL_ARRAYSIZE(buffer_));
- ASSERT_NE(0u, encrypted_length);
- packet_ = std::make_unique<QuicEncryptedPacket>(buffer_, encrypted_length);
- EXPECT_TRUE(packet_ != nullptr);
- DeleteFrames(&frames);
- }
-
- protected:
- ParsedQuicVersion version_;
- TestDelegate delegate_;
- std::unique_ptr<QuicEncryptedPacket> packet_;
- char buffer_[kMaxOutgoingPacketSize];
-};
-
-INSTANTIATE_TEST_SUITE_P(
- ChloExtractorTests,
- ChloExtractorTest,
- ::testing::ValuesIn(AllSupportedVersionsWithQuicCrypto()),
- ::testing::PrintToStringParamName());
-
-TEST_P(ChloExtractorTest, FindsValidChlo) {
- CryptoHandshakeMessage client_hello;
- client_hello.set_tag(kCHLO);
-
- std::string client_hello_str(client_hello.GetSerialized().AsStringPiece());
-
- MakePacket(client_hello_str, /*munge_offset=*/false,
- /*munge_stream_id=*/false);
- EXPECT_TRUE(ChloExtractor::Extract(*packet_, version_, {}, &delegate_,
- kQuicDefaultConnectionIdLength));
- EXPECT_EQ(version_.transport_version, delegate_.transport_version());
- EXPECT_EQ(TestConnectionId(), delegate_.connection_id());
- EXPECT_EQ(client_hello.DebugString(), delegate_.chlo());
-}
-
-TEST_P(ChloExtractorTest, DoesNotFindValidChloOnWrongStream) {
- if (version_.UsesCryptoFrames()) {
- // When crypto frames are in use we do not use stream frames.
- return;
- }
- CryptoHandshakeMessage client_hello;
- client_hello.set_tag(kCHLO);
-
- std::string client_hello_str(client_hello.GetSerialized().AsStringPiece());
- MakePacket(client_hello_str,
- /*munge_offset=*/false, /*munge_stream_id=*/true);
- EXPECT_FALSE(ChloExtractor::Extract(*packet_, version_, {}, &delegate_,
- kQuicDefaultConnectionIdLength));
-}
-
-TEST_P(ChloExtractorTest, DoesNotFindValidChloOnWrongOffset) {
- CryptoHandshakeMessage client_hello;
- client_hello.set_tag(kCHLO);
-
- std::string client_hello_str(client_hello.GetSerialized().AsStringPiece());
- MakePacket(client_hello_str, /*munge_offset=*/true,
- /*munge_stream_id=*/false);
- EXPECT_FALSE(ChloExtractor::Extract(*packet_, version_, {}, &delegate_,
- kQuicDefaultConnectionIdLength));
-}
-
-TEST_P(ChloExtractorTest, DoesNotFindInvalidChlo) {
- MakePacket("foo", /*munge_offset=*/false,
- /*munge_stream_id=*/false);
- EXPECT_FALSE(ChloExtractor::Extract(*packet_, version_, {}, &delegate_,
- kQuicDefaultConnectionIdLength));
-}
-
-TEST_P(ChloExtractorTest, FirstFlight) {
- std::vector<std::unique_ptr<QuicReceivedPacket>> packets =
- GetFirstFlightOfPackets(version_);
- ASSERT_EQ(packets.size(), 1u);
- EXPECT_TRUE(ChloExtractor::Extract(*packets[0], version_, {}, &delegate_,
- kQuicDefaultConnectionIdLength));
- EXPECT_EQ(version_.transport_version, delegate_.transport_version());
- EXPECT_EQ(TestConnectionId(), delegate_.connection_id());
- EXPECT_EQ(AlpnForVersion(version_), delegate_.alpn());
-}
-
-} // namespace
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/congestion_control/bandwidth_sampler.cc b/chromium/net/third_party/quiche/src/quic/core/congestion_control/bandwidth_sampler.cc
deleted file mode 100644
index fd2cc8f1bab..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/congestion_control/bandwidth_sampler.cc
+++ /dev/null
@@ -1,589 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/congestion_control/bandwidth_sampler.h"
-
-#include <algorithm>
-
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_flag_utils.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-std::ostream& operator<<(std::ostream& os, const SendTimeState& s) {
- os << "{valid:" << s.is_valid << ", app_limited:" << s.is_app_limited
- << ", total_sent:" << s.total_bytes_sent
- << ", total_acked:" << s.total_bytes_acked
- << ", total_lost:" << s.total_bytes_lost
- << ", inflight:" << s.bytes_in_flight << "}";
- return os;
-}
-
-QuicByteCount MaxAckHeightTracker::Update(
- QuicBandwidth bandwidth_estimate, bool is_new_max_bandwidth,
- QuicRoundTripCount round_trip_count,
- QuicPacketNumber last_sent_packet_number,
- QuicPacketNumber last_acked_packet_number, QuicTime ack_time,
- QuicByteCount bytes_acked) {
- bool force_new_epoch = false;
-
- if (reduce_extra_acked_on_bandwidth_increase_ && is_new_max_bandwidth) {
- // Save and clear existing entries.
- ExtraAckedEvent best = max_ack_height_filter_.GetBest();
- ExtraAckedEvent second_best = max_ack_height_filter_.GetSecondBest();
- ExtraAckedEvent third_best = max_ack_height_filter_.GetThirdBest();
- max_ack_height_filter_.Clear();
-
- // Reinsert the heights into the filter after recalculating.
- QuicByteCount expected_bytes_acked = bandwidth_estimate * best.time_delta;
- if (expected_bytes_acked < best.bytes_acked) {
- best.extra_acked = best.bytes_acked - expected_bytes_acked;
- max_ack_height_filter_.Update(best, best.round);
- }
- expected_bytes_acked = bandwidth_estimate * second_best.time_delta;
- if (expected_bytes_acked < second_best.bytes_acked) {
- QUICHE_DCHECK_LE(best.round, second_best.round);
- second_best.extra_acked = second_best.bytes_acked - expected_bytes_acked;
- max_ack_height_filter_.Update(second_best, second_best.round);
- }
- expected_bytes_acked = bandwidth_estimate * third_best.time_delta;
- if (expected_bytes_acked < third_best.bytes_acked) {
- QUICHE_DCHECK_LE(second_best.round, third_best.round);
- third_best.extra_acked = third_best.bytes_acked - expected_bytes_acked;
- max_ack_height_filter_.Update(third_best, third_best.round);
- }
- }
-
- // If any packet sent after the start of the epoch has been acked, start a new
- // epoch.
- if (start_new_aggregation_epoch_after_full_round_ &&
- last_sent_packet_number_before_epoch_.IsInitialized() &&
- last_acked_packet_number.IsInitialized() &&
- last_acked_packet_number > last_sent_packet_number_before_epoch_) {
- QUIC_DVLOG(3) << "Force starting a new aggregation epoch. "
- "last_sent_packet_number_before_epoch_:"
- << last_sent_packet_number_before_epoch_
- << ", last_acked_packet_number:" << last_acked_packet_number;
- if (reduce_extra_acked_on_bandwidth_increase_) {
- QUIC_BUG(quic_bwsampler_46)
- << "A full round of aggregation should never "
- << "pass with startup_include_extra_acked(B204) enabled.";
- }
- force_new_epoch = true;
- }
- if (aggregation_epoch_start_time_ == QuicTime::Zero() || force_new_epoch) {
- aggregation_epoch_bytes_ = bytes_acked;
- aggregation_epoch_start_time_ = ack_time;
- last_sent_packet_number_before_epoch_ = last_sent_packet_number;
- ++num_ack_aggregation_epochs_;
- return 0;
- }
-
- // Compute how many bytes are expected to be delivered, assuming max bandwidth
- // is correct.
- QuicTime::Delta aggregation_delta = ack_time - aggregation_epoch_start_time_;
- QuicByteCount expected_bytes_acked = bandwidth_estimate * aggregation_delta;
- // Reset the current aggregation epoch as soon as the ack arrival rate is less
- // than or equal to the max bandwidth.
- if (aggregation_epoch_bytes_ <=
- ack_aggregation_bandwidth_threshold_ * expected_bytes_acked) {
- QUIC_DVLOG(3) << "Starting a new aggregation epoch because "
- "aggregation_epoch_bytes_ "
- << aggregation_epoch_bytes_
- << " is smaller than expected. "
- "ack_aggregation_bandwidth_threshold_:"
- << ack_aggregation_bandwidth_threshold_
- << ", expected_bytes_acked:" << expected_bytes_acked
- << ", bandwidth_estimate:" << bandwidth_estimate
- << ", aggregation_duration:" << aggregation_delta
- << ", new_aggregation_epoch:" << ack_time
- << ", new_aggregation_bytes_acked:" << bytes_acked;
- // Reset to start measuring a new aggregation epoch.
- aggregation_epoch_bytes_ = bytes_acked;
- aggregation_epoch_start_time_ = ack_time;
- last_sent_packet_number_before_epoch_ = last_sent_packet_number;
- ++num_ack_aggregation_epochs_;
- return 0;
- }
-
- aggregation_epoch_bytes_ += bytes_acked;
-
- // Compute how many extra bytes were delivered vs max bandwidth.
- QuicByteCount extra_bytes_acked =
- aggregation_epoch_bytes_ - expected_bytes_acked;
- QUIC_DVLOG(3) << "Updating MaxAckHeight. ack_time:" << ack_time
- << ", last sent packet:" << last_sent_packet_number
- << ", bandwidth_estimate:" << bandwidth_estimate
- << ", bytes_acked:" << bytes_acked
- << ", expected_bytes_acked:" << expected_bytes_acked
- << ", aggregation_epoch_bytes_:" << aggregation_epoch_bytes_
- << ", extra_bytes_acked:" << extra_bytes_acked;
- ExtraAckedEvent new_event;
- new_event.extra_acked = extra_bytes_acked;
- new_event.bytes_acked = aggregation_epoch_bytes_;
- new_event.time_delta = aggregation_delta;
- max_ack_height_filter_.Update(new_event, round_trip_count);
- return extra_bytes_acked;
-}
-
-BandwidthSampler::BandwidthSampler(
- const QuicUnackedPacketMap* unacked_packet_map,
- QuicRoundTripCount max_height_tracker_window_length)
- : total_bytes_sent_(0),
- total_bytes_acked_(0),
- total_bytes_lost_(0),
- total_bytes_neutered_(0),
- total_bytes_sent_at_last_acked_packet_(0),
- last_acked_packet_sent_time_(QuicTime::Zero()),
- last_acked_packet_ack_time_(QuicTime::Zero()),
- is_app_limited_(true),
- connection_state_map_(),
- max_tracked_packets_(GetQuicFlag(FLAGS_quic_max_tracked_packet_count)),
- unacked_packet_map_(unacked_packet_map),
- max_ack_height_tracker_(max_height_tracker_window_length),
- total_bytes_acked_after_last_ack_event_(0),
- overestimate_avoidance_(false),
- limit_max_ack_height_tracker_by_send_rate_(false) {}
-
-BandwidthSampler::BandwidthSampler(const BandwidthSampler& other)
- : total_bytes_sent_(other.total_bytes_sent_),
- total_bytes_acked_(other.total_bytes_acked_),
- total_bytes_lost_(other.total_bytes_lost_),
- total_bytes_neutered_(other.total_bytes_neutered_),
- total_bytes_sent_at_last_acked_packet_(
- other.total_bytes_sent_at_last_acked_packet_),
- last_acked_packet_sent_time_(other.last_acked_packet_sent_time_),
- last_acked_packet_ack_time_(other.last_acked_packet_ack_time_),
- last_sent_packet_(other.last_sent_packet_),
- last_acked_packet_(other.last_acked_packet_),
- is_app_limited_(other.is_app_limited_),
- end_of_app_limited_phase_(other.end_of_app_limited_phase_),
- connection_state_map_(other.connection_state_map_),
- recent_ack_points_(other.recent_ack_points_),
- a0_candidates_(other.a0_candidates_),
- max_tracked_packets_(other.max_tracked_packets_),
- unacked_packet_map_(other.unacked_packet_map_),
- max_ack_height_tracker_(other.max_ack_height_tracker_),
- total_bytes_acked_after_last_ack_event_(
- other.total_bytes_acked_after_last_ack_event_),
- overestimate_avoidance_(other.overestimate_avoidance_),
- limit_max_ack_height_tracker_by_send_rate_(
- other.limit_max_ack_height_tracker_by_send_rate_) {}
-
-void BandwidthSampler::EnableOverestimateAvoidance() {
- if (overestimate_avoidance_) {
- return;
- }
-
- overestimate_avoidance_ = true;
- // TODO(wub): Change the default value of
- // --quic_ack_aggregation_bandwidth_threshold to 2.0.
- max_ack_height_tracker_.SetAckAggregationBandwidthThreshold(2.0);
-}
-
-BandwidthSampler::~BandwidthSampler() {}
-
-void BandwidthSampler::OnPacketSent(
- QuicTime sent_time,
- QuicPacketNumber packet_number,
- QuicByteCount bytes,
- QuicByteCount bytes_in_flight,
- HasRetransmittableData has_retransmittable_data) {
- last_sent_packet_ = packet_number;
-
- if (has_retransmittable_data != HAS_RETRANSMITTABLE_DATA) {
- return;
- }
-
- total_bytes_sent_ += bytes;
-
- // If there are no packets in flight, the time at which the new transmission
- // opens can be treated as the A_0 point for the purpose of bandwidth
- // sampling. This underestimates bandwidth to some extent, and produces some
- // artificially low samples for most packets in flight, but it provides with
- // samples at important points where we would not have them otherwise, most
- // importantly at the beginning of the connection.
- if (bytes_in_flight == 0) {
- last_acked_packet_ack_time_ = sent_time;
- if (overestimate_avoidance_) {
- recent_ack_points_.Clear();
- recent_ack_points_.Update(sent_time, total_bytes_acked_);
- a0_candidates_.clear();
- a0_candidates_.push_back(recent_ack_points_.MostRecentPoint());
- }
- total_bytes_sent_at_last_acked_packet_ = total_bytes_sent_;
-
- // In this situation ack compression is not a concern, set send rate to
- // effectively infinite.
- last_acked_packet_sent_time_ = sent_time;
- }
-
- if (!connection_state_map_.IsEmpty() &&
- packet_number >
- connection_state_map_.last_packet() + max_tracked_packets_) {
- if (unacked_packet_map_ != nullptr && !unacked_packet_map_->empty()) {
- QuicPacketNumber maybe_least_unacked =
- unacked_packet_map_->GetLeastUnacked();
- QUIC_BUG(quic_bug_10437_1)
- << "BandwidthSampler in-flight packet map has exceeded maximum "
- "number of tracked packets("
- << max_tracked_packets_
- << "). First tracked: " << connection_state_map_.first_packet()
- << "; last tracked: " << connection_state_map_.last_packet()
- << "; entry_slots_used: " << connection_state_map_.entry_slots_used()
- << "; number_of_present_entries: "
- << connection_state_map_.number_of_present_entries()
- << "; packet number: " << packet_number
- << "; unacked_map: " << unacked_packet_map_->DebugString()
- << "; total_bytes_sent: " << total_bytes_sent_
- << "; total_bytes_acked: " << total_bytes_acked_
- << "; total_bytes_lost: " << total_bytes_lost_
- << "; total_bytes_neutered: " << total_bytes_neutered_
- << "; last_acked_packet_sent_time: " << last_acked_packet_sent_time_
- << "; total_bytes_sent_at_last_acked_packet: "
- << total_bytes_sent_at_last_acked_packet_
- << "; least_unacked_packet_info: "
- << (unacked_packet_map_->IsUnacked(maybe_least_unacked)
- ? unacked_packet_map_
- ->GetTransmissionInfo(maybe_least_unacked)
- .DebugString()
- : "n/a");
- } else {
- QUIC_BUG(quic_bug_10437_2)
- << "BandwidthSampler in-flight packet map has exceeded maximum "
- "number of tracked packets.";
- }
- }
-
- bool success = connection_state_map_.Emplace(packet_number, sent_time, bytes,
- bytes_in_flight + bytes, *this);
- QUIC_BUG_IF(quic_bug_10437_3, !success)
- << "BandwidthSampler failed to insert the packet "
- "into the map, most likely because it's already "
- "in it.";
-}
-
-void BandwidthSampler::OnPacketNeutered(QuicPacketNumber packet_number) {
- connection_state_map_.Remove(
- packet_number, [&](const ConnectionStateOnSentPacket& sent_packet) {
- QUIC_CODE_COUNT(quic_bandwidth_sampler_packet_neutered);
- total_bytes_neutered_ += sent_packet.size;
- });
-}
-
-BandwidthSamplerInterface::CongestionEventSample
-BandwidthSampler::OnCongestionEvent(QuicTime ack_time,
- const AckedPacketVector& acked_packets,
- const LostPacketVector& lost_packets,
- QuicBandwidth max_bandwidth,
- QuicBandwidth est_bandwidth_upper_bound,
- QuicRoundTripCount round_trip_count) {
- CongestionEventSample event_sample;
-
- SendTimeState last_lost_packet_send_state;
-
- for (const LostPacket& packet : lost_packets) {
- SendTimeState send_state =
- OnPacketLost(packet.packet_number, packet.bytes_lost);
- if (send_state.is_valid) {
- last_lost_packet_send_state = send_state;
- }
- }
-
- if (acked_packets.empty()) {
- // Only populate send state for a loss-only event.
- event_sample.last_packet_send_state = last_lost_packet_send_state;
- return event_sample;
- }
-
- SendTimeState last_acked_packet_send_state;
- QuicBandwidth max_send_rate = QuicBandwidth::Zero();
- for (const auto& packet : acked_packets) {
- BandwidthSample sample =
- OnPacketAcknowledged(ack_time, packet.packet_number);
- if (!sample.state_at_send.is_valid) {
- continue;
- }
-
- last_acked_packet_send_state = sample.state_at_send;
-
- if (!sample.rtt.IsZero()) {
- event_sample.sample_rtt = std::min(event_sample.sample_rtt, sample.rtt);
- }
- if (sample.bandwidth > event_sample.sample_max_bandwidth) {
- event_sample.sample_max_bandwidth = sample.bandwidth;
- event_sample.sample_is_app_limited = sample.state_at_send.is_app_limited;
- }
- if (!sample.send_rate.IsInfinite()) {
- max_send_rate = std::max(max_send_rate, sample.send_rate);
- }
- const QuicByteCount inflight_sample =
- total_bytes_acked() - last_acked_packet_send_state.total_bytes_acked;
- if (inflight_sample > event_sample.sample_max_inflight) {
- event_sample.sample_max_inflight = inflight_sample;
- }
- }
-
- if (!last_lost_packet_send_state.is_valid) {
- event_sample.last_packet_send_state = last_acked_packet_send_state;
- } else if (!last_acked_packet_send_state.is_valid) {
- event_sample.last_packet_send_state = last_lost_packet_send_state;
- } else {
- // If two packets are inflight and an alarm is armed to lose a packet and it
- // wakes up late, then the first of two in flight packets could have been
- // acknowledged before the wakeup, which re-evaluates loss detection, and
- // could declare the later of the two lost.
- event_sample.last_packet_send_state =
- lost_packets.back().packet_number > acked_packets.back().packet_number
- ? last_lost_packet_send_state
- : last_acked_packet_send_state;
- }
-
- bool is_new_max_bandwidth = event_sample.sample_max_bandwidth > max_bandwidth;
- max_bandwidth = std::max(max_bandwidth, event_sample.sample_max_bandwidth);
- if (limit_max_ack_height_tracker_by_send_rate_) {
- max_bandwidth = std::max(max_bandwidth, max_send_rate);
- }
- // TODO(ianswett): Why is the min being passed in here?
- event_sample.extra_acked =
- OnAckEventEnd(std::min(est_bandwidth_upper_bound, max_bandwidth),
- is_new_max_bandwidth, round_trip_count);
-
- return event_sample;
-}
-
-QuicByteCount BandwidthSampler::OnAckEventEnd(
- QuicBandwidth bandwidth_estimate, bool is_new_max_bandwidth,
- QuicRoundTripCount round_trip_count) {
- const QuicByteCount newly_acked_bytes =
- total_bytes_acked_ - total_bytes_acked_after_last_ack_event_;
-
- if (newly_acked_bytes == 0) {
- return 0;
- }
- total_bytes_acked_after_last_ack_event_ = total_bytes_acked_;
- QuicByteCount extra_acked = max_ack_height_tracker_.Update(
- bandwidth_estimate, is_new_max_bandwidth, round_trip_count,
- last_sent_packet_, last_acked_packet_, last_acked_packet_ack_time_,
- newly_acked_bytes);
- // If |extra_acked| is zero, i.e. this ack event marks the start of a new ack
- // aggregation epoch, save LessRecentPoint, which is the last ack point of the
- // previous epoch, as a A0 candidate.
- if (overestimate_avoidance_ && extra_acked == 0) {
- a0_candidates_.push_back(recent_ack_points_.LessRecentPoint());
- QUIC_DVLOG(1) << "New a0_candidate:" << a0_candidates_.back();
- }
- return extra_acked;
-}
-
-BandwidthSample BandwidthSampler::OnPacketAcknowledged(
- QuicTime ack_time,
- QuicPacketNumber packet_number) {
- last_acked_packet_ = packet_number;
- ConnectionStateOnSentPacket* sent_packet_pointer =
- connection_state_map_.GetEntry(packet_number);
- if (sent_packet_pointer == nullptr) {
- // See the TODO below.
- return BandwidthSample();
- }
- BandwidthSample sample =
- OnPacketAcknowledgedInner(ack_time, packet_number, *sent_packet_pointer);
- return sample;
-}
-
-BandwidthSample BandwidthSampler::OnPacketAcknowledgedInner(
- QuicTime ack_time,
- QuicPacketNumber packet_number,
- const ConnectionStateOnSentPacket& sent_packet) {
- total_bytes_acked_ += sent_packet.size;
- total_bytes_sent_at_last_acked_packet_ =
- sent_packet.send_time_state.total_bytes_sent;
- last_acked_packet_sent_time_ = sent_packet.sent_time;
- last_acked_packet_ack_time_ = ack_time;
- if (overestimate_avoidance_) {
- recent_ack_points_.Update(ack_time, total_bytes_acked_);
- }
-
- if (is_app_limited_) {
- // Exit app-limited phase in two cases:
- // (1) end_of_app_limited_phase_ is not initialized, i.e., so far all
- // packets are sent while there are buffered packets or pending data.
- // (2) The current acked packet is after the sent packet marked as the end
- // of the app limit phase.
- if (!end_of_app_limited_phase_.IsInitialized() ||
- packet_number > end_of_app_limited_phase_) {
- is_app_limited_ = false;
- }
- }
-
- // There might have been no packets acknowledged at the moment when the
- // current packet was sent. In that case, there is no bandwidth sample to
- // make.
- if (sent_packet.last_acked_packet_sent_time == QuicTime::Zero()) {
- QUIC_BUG(quic_bug_10437_4)
- << "sent_packet.last_acked_packet_sent_time is zero";
- return BandwidthSample();
- }
-
- // Infinite rate indicates that the sampler is supposed to discard the
- // current send rate sample and use only the ack rate.
- QuicBandwidth send_rate = QuicBandwidth::Infinite();
- if (sent_packet.sent_time > sent_packet.last_acked_packet_sent_time) {
- send_rate = QuicBandwidth::FromBytesAndTimeDelta(
- sent_packet.send_time_state.total_bytes_sent -
- sent_packet.total_bytes_sent_at_last_acked_packet,
- sent_packet.sent_time - sent_packet.last_acked_packet_sent_time);
- }
-
- AckPoint a0;
- if (overestimate_avoidance_ &&
- ChooseA0Point(sent_packet.send_time_state.total_bytes_acked, &a0)) {
- QUIC_DVLOG(2) << "Using a0 point: " << a0;
- } else {
- a0.ack_time = sent_packet.last_acked_packet_ack_time,
- a0.total_bytes_acked = sent_packet.send_time_state.total_bytes_acked;
- }
-
- // During the slope calculation, ensure that ack time of the current packet is
- // always larger than the time of the previous packet, otherwise division by
- // zero or integer underflow can occur.
- if (ack_time <= a0.ack_time) {
- // TODO(wub): Compare this code count before and after fixing clock jitter
- // issue.
- if (a0.ack_time == sent_packet.sent_time) {
- // This is the 1st packet after quiescense.
- QUIC_CODE_COUNT_N(quic_prev_ack_time_larger_than_current_ack_time, 1, 2);
- } else {
- QUIC_CODE_COUNT_N(quic_prev_ack_time_larger_than_current_ack_time, 2, 2);
- }
- QUIC_LOG_EVERY_N_SEC(ERROR, 60)
- << "Time of the previously acked packet:"
- << a0.ack_time.ToDebuggingValue()
- << " is larger than the ack time of the current packet:"
- << ack_time.ToDebuggingValue()
- << ". acked packet number:" << packet_number
- << ", total_bytes_acked_:" << total_bytes_acked_
- << ", overestimate_avoidance_:" << overestimate_avoidance_
- << ", sent_packet:" << sent_packet;
- return BandwidthSample();
- }
- QuicBandwidth ack_rate = QuicBandwidth::FromBytesAndTimeDelta(
- total_bytes_acked_ - a0.total_bytes_acked, ack_time - a0.ack_time);
-
- BandwidthSample sample;
- sample.bandwidth = std::min(send_rate, ack_rate);
- // Note: this sample does not account for delayed acknowledgement time. This
- // means that the RTT measurements here can be artificially high, especially
- // on low bandwidth connections.
- sample.rtt = ack_time - sent_packet.sent_time;
- sample.send_rate = send_rate;
- SentPacketToSendTimeState(sent_packet, &sample.state_at_send);
-
- if (sample.bandwidth.IsZero()) {
- QUIC_LOG_EVERY_N_SEC(ERROR, 60)
- << "ack_rate: " << ack_rate << ", send_rate: " << send_rate
- << ". acked packet number:" << packet_number
- << ", overestimate_avoidance_:" << overestimate_avoidance_ << "a1:{"
- << total_bytes_acked_ << "@" << ack_time << "}, a0:{"
- << a0.total_bytes_acked << "@" << a0.ack_time
- << "}, sent_packet:" << sent_packet;
- }
- return sample;
-}
-
-bool BandwidthSampler::ChooseA0Point(QuicByteCount total_bytes_acked,
- AckPoint* a0) {
- if (a0_candidates_.empty()) {
- QUIC_BUG(quic_bug_10437_5)
- << "No A0 point candicates. total_bytes_acked:" << total_bytes_acked;
- return false;
- }
-
- if (a0_candidates_.size() == 1) {
- *a0 = a0_candidates_.front();
- return true;
- }
-
- for (size_t i = 1; i < a0_candidates_.size(); ++i) {
- if (a0_candidates_[i].total_bytes_acked > total_bytes_acked) {
- *a0 = a0_candidates_[i - 1];
- if (i > 1) {
- a0_candidates_.pop_front_n(i - 1);
- }
- return true;
- }
- }
-
- // All candidates' total_bytes_acked is <= |total_bytes_acked|.
- *a0 = a0_candidates_.back();
- a0_candidates_.pop_front_n(a0_candidates_.size() - 1);
- return true;
-}
-
-SendTimeState BandwidthSampler::OnPacketLost(QuicPacketNumber packet_number,
- QuicPacketLength bytes_lost) {
- // TODO(vasilvv): see the comment for the case of missing packets in
- // BandwidthSampler::OnPacketAcknowledged on why this does not raise a
- // QUIC_BUG when removal fails.
- SendTimeState send_time_state;
-
- total_bytes_lost_ += bytes_lost;
- ConnectionStateOnSentPacket* sent_packet_pointer =
- connection_state_map_.GetEntry(packet_number);
- if (sent_packet_pointer != nullptr) {
- SentPacketToSendTimeState(*sent_packet_pointer, &send_time_state);
- }
-
- return send_time_state;
-}
-
-void BandwidthSampler::SentPacketToSendTimeState(
- const ConnectionStateOnSentPacket& sent_packet,
- SendTimeState* send_time_state) const {
- *send_time_state = sent_packet.send_time_state;
- send_time_state->is_valid = true;
-}
-
-void BandwidthSampler::OnAppLimited() {
- is_app_limited_ = true;
- end_of_app_limited_phase_ = last_sent_packet_;
-}
-
-void BandwidthSampler::RemoveObsoletePackets(QuicPacketNumber least_unacked) {
- // A packet can become obsolete when it is removed from QuicUnackedPacketMap's
- // view of inflight before it is acked or marked as lost. For example, when
- // QuicSentPacketManager::RetransmitCryptoPackets retransmits a crypto packet,
- // the packet is removed from QuicUnackedPacketMap's inflight, but is not
- // marked as acked or lost in the BandwidthSampler.
- connection_state_map_.RemoveUpTo(least_unacked);
-}
-
-QuicByteCount BandwidthSampler::total_bytes_sent() const {
- return total_bytes_sent_;
-}
-
-QuicByteCount BandwidthSampler::total_bytes_acked() const {
- return total_bytes_acked_;
-}
-
-QuicByteCount BandwidthSampler::total_bytes_lost() const {
- return total_bytes_lost_;
-}
-
-QuicByteCount BandwidthSampler::total_bytes_neutered() const {
- return total_bytes_neutered_;
-}
-
-bool BandwidthSampler::is_app_limited() const {
- return is_app_limited_;
-}
-
-QuicPacketNumber BandwidthSampler::end_of_app_limited_phase() const {
- return end_of_app_limited_phase_;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/congestion_control/bandwidth_sampler.h b/chromium/net/third_party/quiche/src/quic/core/congestion_control/bandwidth_sampler.h
deleted file mode 100644
index 814571746c0..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/congestion_control/bandwidth_sampler.h
+++ /dev/null
@@ -1,627 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_CONGESTION_CONTROL_BANDWIDTH_SAMPLER_H_
-#define QUICHE_QUIC_CORE_CONGESTION_CONTROL_BANDWIDTH_SAMPLER_H_
-
-#include "quic/core/congestion_control/send_algorithm_interface.h"
-#include "quic/core/congestion_control/windowed_filter.h"
-#include "quic/core/packet_number_indexed_queue.h"
-#include "quic/core/quic_bandwidth.h"
-#include "quic/core/quic_packet_number.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_time.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_unacked_packet_map.h"
-#include "quic/platform/api/quic_export.h"
-#include "quic/platform/api/quic_flags.h"
-#include "common/quiche_circular_deque.h"
-
-namespace quic {
-
-namespace test {
-class BandwidthSamplerPeer;
-} // namespace test
-
-// A subset of BandwidthSampler::ConnectionStateOnSentPacket which is returned
-// to the caller when the packet is acked or lost.
-struct QUIC_EXPORT_PRIVATE SendTimeState {
- SendTimeState()
- : is_valid(false),
- is_app_limited(false),
- total_bytes_sent(0),
- total_bytes_acked(0),
- total_bytes_lost(0),
- bytes_in_flight(0) {}
-
- SendTimeState(bool is_app_limited,
- QuicByteCount total_bytes_sent,
- QuicByteCount total_bytes_acked,
- QuicByteCount total_bytes_lost,
- QuicByteCount bytes_in_flight)
- : is_valid(true),
- is_app_limited(is_app_limited),
- total_bytes_sent(total_bytes_sent),
- total_bytes_acked(total_bytes_acked),
- total_bytes_lost(total_bytes_lost),
- bytes_in_flight(bytes_in_flight) {}
-
- SendTimeState(const SendTimeState& other) = default;
- SendTimeState& operator=(const SendTimeState& other) = default;
-
- friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
- const SendTimeState& s);
-
- // Whether other states in this object is valid.
- bool is_valid;
-
- // Whether the sender is app limited at the time the packet was sent.
- // App limited bandwidth sample might be artificially low because the sender
- // did not have enough data to send in order to saturate the link.
- bool is_app_limited;
-
- // Total number of sent bytes at the time the packet was sent.
- // Includes the packet itself.
- QuicByteCount total_bytes_sent;
-
- // Total number of acked bytes at the time the packet was sent.
- QuicByteCount total_bytes_acked;
-
- // Total number of lost bytes at the time the packet was sent.
- QuicByteCount total_bytes_lost;
-
- // Total number of inflight bytes at the time the packet was sent.
- // Includes the packet itself.
- // It should be equal to |total_bytes_sent| minus the sum of
- // |total_bytes_acked|, |total_bytes_lost| and total neutered bytes.
- QuicByteCount bytes_in_flight;
-};
-
-struct QUIC_NO_EXPORT ExtraAckedEvent {
- // The excess bytes acknowlwedged in the time delta for this event.
- QuicByteCount extra_acked = 0;
-
- // The bytes acknowledged and time delta from the event.
- QuicByteCount bytes_acked = 0;
- QuicTime::Delta time_delta = QuicTime::Delta::Zero();
- // The round trip of the event.
- QuicRoundTripCount round = 0;
-
- inline bool operator>=(const ExtraAckedEvent& other) const {
- return extra_acked >= other.extra_acked;
- }
- inline bool operator==(const ExtraAckedEvent& other) const {
- return extra_acked == other.extra_acked;
- }
-};
-
-struct QUIC_EXPORT_PRIVATE BandwidthSample {
- // The bandwidth at that particular sample. Zero if no valid bandwidth sample
- // is available.
- QuicBandwidth bandwidth = QuicBandwidth::Zero();
-
- // The RTT measurement at this particular sample. Zero if no RTT sample is
- // available. Does not correct for delayed ack time.
- QuicTime::Delta rtt = QuicTime::Delta::Zero();
-
- // |send_rate| is computed from the current packet being acked('P') and an
- // earlier packet that is acked before P was sent.
- QuicBandwidth send_rate = QuicBandwidth::Infinite();
-
- // States captured when the packet was sent.
- SendTimeState state_at_send;
-};
-
-// MaxAckHeightTracker is part of the BandwidthSampler. It is called after every
-// ack event to keep track the degree of ack aggregation(a.k.a "ack height").
-class QUIC_EXPORT_PRIVATE MaxAckHeightTracker {
- public:
- explicit MaxAckHeightTracker(QuicRoundTripCount initial_filter_window)
- : max_ack_height_filter_(initial_filter_window, ExtraAckedEvent(), 0) {}
-
- QuicByteCount Get() const {
- return max_ack_height_filter_.GetBest().extra_acked;
- }
-
- QuicByteCount Update(QuicBandwidth bandwidth_estimate,
- bool is_new_max_bandwidth,
- QuicRoundTripCount round_trip_count,
- QuicPacketNumber last_sent_packet_number,
- QuicPacketNumber last_acked_packet_number,
- QuicTime ack_time, QuicByteCount bytes_acked);
-
- void SetFilterWindowLength(QuicRoundTripCount length) {
- max_ack_height_filter_.SetWindowLength(length);
- }
-
- void Reset(QuicByteCount new_height, QuicRoundTripCount new_time) {
- ExtraAckedEvent new_event;
- new_event.extra_acked = new_height;
- new_event.round = new_time;
- max_ack_height_filter_.Reset(new_event, new_time);
- }
-
- void SetAckAggregationBandwidthThreshold(double threshold) {
- ack_aggregation_bandwidth_threshold_ = threshold;
- }
-
- void SetStartNewAggregationEpochAfterFullRound(bool value) {
- start_new_aggregation_epoch_after_full_round_ = value;
- }
-
- void SetReduceExtraAckedOnBandwidthIncrease(bool value) {
- reduce_extra_acked_on_bandwidth_increase_ = value;
- }
-
- double ack_aggregation_bandwidth_threshold() const {
- return ack_aggregation_bandwidth_threshold_;
- }
-
- uint64_t num_ack_aggregation_epochs() const {
- return num_ack_aggregation_epochs_;
- }
-
- private:
- // Tracks the maximum number of bytes acked faster than the estimated
- // bandwidth.
- using MaxAckHeightFilter =
- WindowedFilter<ExtraAckedEvent, MaxFilter<ExtraAckedEvent>,
- QuicRoundTripCount, QuicRoundTripCount>;
- MaxAckHeightFilter max_ack_height_filter_;
-
- // The time this aggregation started and the number of bytes acked during it.
- QuicTime aggregation_epoch_start_time_ = QuicTime::Zero();
- QuicByteCount aggregation_epoch_bytes_ = 0;
- // The last sent packet number before the current aggregation epoch started.
- QuicPacketNumber last_sent_packet_number_before_epoch_;
- // The number of ack aggregation epochs ever started, including the ongoing
- // one. Stats only.
- uint64_t num_ack_aggregation_epochs_ = 0;
- double ack_aggregation_bandwidth_threshold_ =
- GetQuicFlag(FLAGS_quic_ack_aggregation_bandwidth_threshold);
- bool start_new_aggregation_epoch_after_full_round_ = false;
- bool reduce_extra_acked_on_bandwidth_increase_ = false;
-};
-
-// An interface common to any class that can provide bandwidth samples from the
-// information per individual acknowledged packet.
-class QUIC_EXPORT_PRIVATE BandwidthSamplerInterface {
- public:
- virtual ~BandwidthSamplerInterface() {}
-
- // Inputs the sent packet information into the sampler. Assumes that all
- // packets are sent in order. The information about the packet will not be
- // released from the sampler until it the packet is either acknowledged or
- // declared lost.
- virtual void OnPacketSent(
- QuicTime sent_time,
- QuicPacketNumber packet_number,
- QuicByteCount bytes,
- QuicByteCount bytes_in_flight,
- HasRetransmittableData has_retransmittable_data) = 0;
-
- virtual void OnPacketNeutered(QuicPacketNumber packet_number) = 0;
-
- struct QUIC_NO_EXPORT CongestionEventSample {
- // The maximum bandwidth sample from all acked packets.
- // QuicBandwidth::Zero() if no samples are available.
- QuicBandwidth sample_max_bandwidth = QuicBandwidth::Zero();
- // Whether |sample_max_bandwidth| is from a app-limited sample.
- bool sample_is_app_limited = false;
- // The minimum rtt sample from all acked packets.
- // QuicTime::Delta::Infinite() if no samples are available.
- QuicTime::Delta sample_rtt = QuicTime::Delta::Infinite();
- // For each packet p in acked packets, this is the max value of INFLIGHT(p),
- // where INFLIGHT(p) is the number of bytes acked while p is inflight.
- QuicByteCount sample_max_inflight = 0;
- // The send state of the largest packet in acked_packets, unless it is
- // empty. If acked_packets is empty, it's the send state of the largest
- // packet in lost_packets.
- SendTimeState last_packet_send_state;
- // The number of extra bytes acked from this ack event, compared to what is
- // expected from the flow's bandwidth. Larger value means more ack
- // aggregation.
- QuicByteCount extra_acked = 0;
- };
- // Notifies the sampler that at |ack_time|, all packets in |acked_packets|
- // have been acked, and all packets in |lost_packets| have been lost.
- // See the comments in CongestionEventSample for the return value.
- // |max_bandwidth| is the windowed maximum observed bandwidth.
- // |est_bandwidth_upper_bound| is an upper bound of estimated bandwidth used
- // to calculate extra_acked.
- virtual CongestionEventSample OnCongestionEvent(
- QuicTime ack_time,
- const AckedPacketVector& acked_packets,
- const LostPacketVector& lost_packets,
- QuicBandwidth max_bandwidth,
- QuicBandwidth est_bandwidth_upper_bound,
- QuicRoundTripCount round_trip_count) = 0;
-
- // Informs the sampler that the connection is currently app-limited, causing
- // the sampler to enter the app-limited phase. The phase will expire by
- // itself.
- virtual void OnAppLimited() = 0;
-
- // Remove all the packets lower than the specified packet number.
- virtual void RemoveObsoletePackets(QuicPacketNumber least_unacked) = 0;
-
- // Total number of bytes sent/acked/lost/neutered in the connection.
- virtual QuicByteCount total_bytes_sent() const = 0;
- virtual QuicByteCount total_bytes_acked() const = 0;
- virtual QuicByteCount total_bytes_lost() const = 0;
- virtual QuicByteCount total_bytes_neutered() const = 0;
-
- // Application-limited information exported for debugging.
- virtual bool is_app_limited() const = 0;
-
- virtual QuicPacketNumber end_of_app_limited_phase() const = 0;
-};
-
-// BandwidthSampler keeps track of sent and acknowledged packets and outputs a
-// bandwidth sample for every packet acknowledged. The samples are taken for
-// individual packets, and are not filtered; the consumer has to filter the
-// bandwidth samples itself. In certain cases, the sampler will locally severely
-// underestimate the bandwidth, hence a maximum filter with a size of at least
-// one RTT is recommended.
-//
-// This class bases its samples on the slope of two curves: the number of bytes
-// sent over time, and the number of bytes acknowledged as received over time.
-// It produces a sample of both slopes for every packet that gets acknowledged,
-// based on a slope between two points on each of the corresponding curves. Note
-// that due to the packet loss, the number of bytes on each curve might get
-// further and further away from each other, meaning that it is not feasible to
-// compare byte values coming from different curves with each other.
-//
-// The obvious points for measuring slope sample are the ones corresponding to
-// the packet that was just acknowledged. Let us denote them as S_1 (point at
-// which the current packet was sent) and A_1 (point at which the current packet
-// was acknowledged). However, taking a slope requires two points on each line,
-// so estimating bandwidth requires picking a packet in the past with respect to
-// which the slope is measured.
-//
-// For that purpose, BandwidthSampler always keeps track of the most recently
-// acknowledged packet, and records it together with every outgoing packet.
-// When a packet gets acknowledged (A_1), it has not only information about when
-// it itself was sent (S_1), but also the information about a previously
-// acknowledged packet before it was sent (S_0 and A_0).
-//
-// Based on that data, send and ack rate are estimated as:
-// send_rate = (bytes(S_1) - bytes(S_0)) / (time(S_1) - time(S_0))
-// ack_rate = (bytes(A_1) - bytes(A_0)) / (time(A_1) - time(A_0))
-//
-// Here, the ack rate is intuitively the rate we want to treat as bandwidth.
-// However, in certain cases (e.g. ack compression) the ack rate at a point may
-// end up higher than the rate at which the data was originally sent, which is
-// not indicative of the real bandwidth. Hence, we use the send rate as an upper
-// bound, and the sample value is
-// rate_sample = min(send_rate, ack_rate)
-//
-// An important edge case handled by the sampler is tracking the app-limited
-// samples. There are multiple meaning of "app-limited" used interchangeably,
-// hence it is important to understand and to be able to distinguish between
-// them.
-//
-// Meaning 1: connection state. The connection is said to be app-limited when
-// there is no outstanding data to send. This means that certain bandwidth
-// samples in the future would not be an accurate indication of the link
-// capacity, and it is important to inform consumer about that. Whenever
-// connection becomes app-limited, the sampler is notified via OnAppLimited()
-// method.
-//
-// Meaning 2: a phase in the bandwidth sampler. As soon as the bandwidth
-// sampler becomes notified about the connection being app-limited, it enters
-// app-limited phase. In that phase, all *sent* packets are marked as
-// app-limited. Note that the connection itself does not have to be
-// app-limited during the app-limited phase, and in fact it will not be
-// (otherwise how would it send packets?). The boolean flag below indicates
-// whether the sampler is in that phase.
-//
-// Meaning 3: a flag on the sent packet and on the sample. If a sent packet is
-// sent during the app-limited phase, the resulting sample related to the
-// packet will be marked as app-limited.
-//
-// With the terminology issue out of the way, let us consider the question of
-// what kind of situation it addresses.
-//
-// Consider a scenario where we first send packets 1 to 20 at a regular
-// bandwidth, and then immediately run out of data. After a few seconds, we send
-// packets 21 to 60, and only receive ack for 21 between sending packets 40 and
-// 41. In this case, when we sample bandwidth for packets 21 to 40, the S_0/A_0
-// we use to compute the slope is going to be packet 20, a few seconds apart
-// from the current packet, hence the resulting estimate would be extremely low
-// and not indicative of anything. Only at packet 41 the S_0/A_0 will become 21,
-// meaning that the bandwidth sample would exclude the quiescence.
-//
-// Based on the analysis of that scenario, we implement the following rule: once
-// OnAppLimited() is called, all sent packets will produce app-limited samples
-// up until an ack for a packet that was sent after OnAppLimited() was called.
-// Note that while the scenario above is not the only scenario when the
-// connection is app-limited, the approach works in other cases too.
-class QUIC_EXPORT_PRIVATE BandwidthSampler : public BandwidthSamplerInterface {
- public:
- BandwidthSampler(const QuicUnackedPacketMap* unacked_packet_map,
- QuicRoundTripCount max_height_tracker_window_length);
-
- // Copy states from |other|. This is useful when changing send algorithms in
- // the middle of a connection.
- BandwidthSampler(const BandwidthSampler& other);
- ~BandwidthSampler() override;
-
- void OnPacketSent(QuicTime sent_time,
- QuicPacketNumber packet_number,
- QuicByteCount bytes,
- QuicByteCount bytes_in_flight,
- HasRetransmittableData has_retransmittable_data) override;
- void OnPacketNeutered(QuicPacketNumber packet_number) override;
-
- CongestionEventSample OnCongestionEvent(
- QuicTime ack_time,
- const AckedPacketVector& acked_packets,
- const LostPacketVector& lost_packets,
- QuicBandwidth max_bandwidth,
- QuicBandwidth est_bandwidth_upper_bound,
- QuicRoundTripCount round_trip_count) override;
- QuicByteCount OnAckEventEnd(QuicBandwidth bandwidth_estimate,
- bool is_new_max_bandwidth,
- QuicRoundTripCount round_trip_count);
-
- void OnAppLimited() override;
-
- void RemoveObsoletePackets(QuicPacketNumber least_unacked) override;
-
- QuicByteCount total_bytes_sent() const override;
- QuicByteCount total_bytes_acked() const override;
- QuicByteCount total_bytes_lost() const override;
- QuicByteCount total_bytes_neutered() const override;
-
- bool is_app_limited() const override;
-
- QuicPacketNumber end_of_app_limited_phase() const override;
-
- QuicByteCount max_ack_height() const { return max_ack_height_tracker_.Get(); }
-
- uint64_t num_ack_aggregation_epochs() const {
- return max_ack_height_tracker_.num_ack_aggregation_epochs();
- }
-
- void SetMaxAckHeightTrackerWindowLength(QuicRoundTripCount length) {
- max_ack_height_tracker_.SetFilterWindowLength(length);
- }
-
- void ResetMaxAckHeightTracker(QuicByteCount new_height,
- QuicRoundTripCount new_time) {
- max_ack_height_tracker_.Reset(new_height, new_time);
- }
-
- void SetStartNewAggregationEpochAfterFullRound(bool value) {
- max_ack_height_tracker_.SetStartNewAggregationEpochAfterFullRound(value);
- }
-
- void SetLimitMaxAckHeightTrackerBySendRate(bool value) {
- limit_max_ack_height_tracker_by_send_rate_ = value;
- }
-
- void SetReduceExtraAckedOnBandwidthIncrease(bool value) {
- max_ack_height_tracker_.SetReduceExtraAckedOnBandwidthIncrease(value);
- }
-
- // AckPoint represents a point on the ack line.
- struct QUIC_NO_EXPORT AckPoint {
- QuicTime ack_time = QuicTime::Zero();
- QuicByteCount total_bytes_acked = 0;
-
- friend QUIC_NO_EXPORT std::ostream& operator<<(std::ostream& os,
- const AckPoint& ack_point) {
- return os << ack_point.ack_time << ":" << ack_point.total_bytes_acked;
- }
- };
-
- // RecentAckPoints maintains the most recent 2 ack points at distinct times.
- class QUIC_NO_EXPORT RecentAckPoints {
- public:
- void Update(QuicTime ack_time, QuicByteCount total_bytes_acked) {
- QUICHE_DCHECK_GE(total_bytes_acked, ack_points_[1].total_bytes_acked);
-
- if (ack_time < ack_points_[1].ack_time) {
- // This can only happen when time goes backwards, we use the smaller
- // timestamp for the most recent ack point in that case.
- // TODO(wub): Add a QUIC_BUG if ack time stops going backwards.
- ack_points_[1].ack_time = ack_time;
- } else if (ack_time > ack_points_[1].ack_time) {
- ack_points_[0] = ack_points_[1];
- ack_points_[1].ack_time = ack_time;
- }
-
- ack_points_[1].total_bytes_acked = total_bytes_acked;
- }
-
- void Clear() { ack_points_[0] = ack_points_[1] = AckPoint(); }
-
- const AckPoint& MostRecentPoint() const { return ack_points_[1]; }
-
- const AckPoint& LessRecentPoint() const {
- if (ack_points_[0].total_bytes_acked != 0) {
- return ack_points_[0];
- }
-
- return ack_points_[1];
- }
-
- private:
- AckPoint ack_points_[2];
- };
-
- void EnableOverestimateAvoidance();
- bool IsOverestimateAvoidanceEnabled() const {
- return overestimate_avoidance_;
- }
-
- private:
- friend class test::BandwidthSamplerPeer;
-
- // ConnectionStateOnSentPacket represents the information about a sent packet
- // and the state of the connection at the moment the packet was sent,
- // specifically the information about the most recently acknowledged packet at
- // that moment.
- struct QUIC_EXPORT_PRIVATE ConnectionStateOnSentPacket {
- // Time at which the packet is sent.
- QuicTime sent_time;
-
- // Size of the packet.
- QuicByteCount size;
-
- // The value of |total_bytes_sent_at_last_acked_packet_| at the time the
- // packet was sent.
- QuicByteCount total_bytes_sent_at_last_acked_packet;
-
- // The value of |last_acked_packet_sent_time_| at the time the packet was
- // sent.
- QuicTime last_acked_packet_sent_time;
-
- // The value of |last_acked_packet_ack_time_| at the time the packet was
- // sent.
- QuicTime last_acked_packet_ack_time;
-
- // Send time states that are returned to the congestion controller when the
- // packet is acked or lost.
- SendTimeState send_time_state;
-
- // Snapshot constructor. Records the current state of the bandwidth
- // sampler.
- // |bytes_in_flight| is the bytes in flight right after the packet is sent.
- ConnectionStateOnSentPacket(QuicTime sent_time,
- QuicByteCount size,
- QuicByteCount bytes_in_flight,
- const BandwidthSampler& sampler)
- : sent_time(sent_time),
- size(size),
- total_bytes_sent_at_last_acked_packet(
- sampler.total_bytes_sent_at_last_acked_packet_),
- last_acked_packet_sent_time(sampler.last_acked_packet_sent_time_),
- last_acked_packet_ack_time(sampler.last_acked_packet_ack_time_),
- send_time_state(sampler.is_app_limited_,
- sampler.total_bytes_sent_,
- sampler.total_bytes_acked_,
- sampler.total_bytes_lost_,
- bytes_in_flight) {}
-
- // Default constructor. Required to put this structure into
- // PacketNumberIndexedQueue.
- ConnectionStateOnSentPacket()
- : sent_time(QuicTime::Zero()),
- size(0),
- total_bytes_sent_at_last_acked_packet(0),
- last_acked_packet_sent_time(QuicTime::Zero()),
- last_acked_packet_ack_time(QuicTime::Zero()) {}
-
- friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
- std::ostream& os,
- const ConnectionStateOnSentPacket& p) {
- os << "{sent_time:" << p.sent_time << ", size:" << p.size
- << ", total_bytes_sent_at_last_acked_packet:"
- << p.total_bytes_sent_at_last_acked_packet
- << ", last_acked_packet_sent_time:" << p.last_acked_packet_sent_time
- << ", last_acked_packet_ack_time:" << p.last_acked_packet_ack_time
- << ", send_time_state:" << p.send_time_state << "}";
- return os;
- }
- };
-
- BandwidthSample OnPacketAcknowledged(QuicTime ack_time,
- QuicPacketNumber packet_number);
-
- SendTimeState OnPacketLost(QuicPacketNumber packet_number,
- QuicPacketLength bytes_lost);
-
- // Copy a subset of the (private) ConnectionStateOnSentPacket to the (public)
- // SendTimeState. Always set send_time_state->is_valid to true.
- void SentPacketToSendTimeState(const ConnectionStateOnSentPacket& sent_packet,
- SendTimeState* send_time_state) const;
-
- // Choose the best a0 from |a0_candidates_| to calculate the ack rate.
- // |total_bytes_acked| is the total bytes acked when the packet being acked is
- // sent. The best a0 is chosen as follows:
- // - If there's only one candidate, use it.
- // - If there are multiple candidates, let a[n] be the nth candidate, and
- // a[n-1].total_bytes_acked <= |total_bytes_acked| < a[n].total_bytes_acked,
- // use a[n-1].
- // - If all candidates's total_bytes_acked is > |total_bytes_acked|, use a[0].
- // This may happen when acks are received out of order, and ack[n] caused
- // some candidates of ack[n-x] to be removed.
- // - If all candidates's total_bytes_acked is <= |total_bytes_acked|, use
- // a[a.size()-1].
- bool ChooseA0Point(QuicByteCount total_bytes_acked, AckPoint* a0);
-
- // The total number of congestion controlled bytes sent during the connection.
- QuicByteCount total_bytes_sent_;
-
- // The total number of congestion controlled bytes which were acknowledged.
- QuicByteCount total_bytes_acked_;
-
- // The total number of congestion controlled bytes which were lost.
- QuicByteCount total_bytes_lost_;
-
- // The total number of congestion controlled bytes which have been neutered.
- QuicByteCount total_bytes_neutered_;
-
- // The value of |total_bytes_sent_| at the time the last acknowledged packet
- // was sent. Valid only when |last_acked_packet_sent_time_| is valid.
- QuicByteCount total_bytes_sent_at_last_acked_packet_;
-
- // The time at which the last acknowledged packet was sent. Set to
- // QuicTime::Zero() if no valid timestamp is available.
- QuicTime last_acked_packet_sent_time_;
-
- // The time at which the most recent packet was acknowledged.
- QuicTime last_acked_packet_ack_time_;
-
- // The most recently sent packet.
- QuicPacketNumber last_sent_packet_;
-
- // The most recently acked packet.
- QuicPacketNumber last_acked_packet_;
-
- // Indicates whether the bandwidth sampler is currently in an app-limited
- // phase.
- bool is_app_limited_;
-
- // The packet that will be acknowledged after this one will cause the sampler
- // to exit the app-limited phase.
- QuicPacketNumber end_of_app_limited_phase_;
-
- // Record of the connection state at the point where each packet in flight was
- // sent, indexed by the packet number.
- PacketNumberIndexedQueue<ConnectionStateOnSentPacket> connection_state_map_;
-
- RecentAckPoints recent_ack_points_;
- quiche::QuicheCircularDeque<AckPoint> a0_candidates_;
-
- // Maximum number of tracked packets.
- const QuicPacketCount max_tracked_packets_;
-
- // The main unacked packet map. Used for outputting extra debugging details.
- // May be null.
- // TODO(vasilvv): remove this once it's no longer useful for debugging.
- const QuicUnackedPacketMap* unacked_packet_map_;
-
- // Handles the actual bandwidth calculations, whereas the outer method handles
- // retrieving and removing |sent_packet|.
- BandwidthSample OnPacketAcknowledgedInner(
- QuicTime ack_time,
- QuicPacketNumber packet_number,
- const ConnectionStateOnSentPacket& sent_packet);
-
- MaxAckHeightTracker max_ack_height_tracker_;
- QuicByteCount total_bytes_acked_after_last_ack_event_;
-
- // True if connection option 'BSAO' is set.
- bool overestimate_avoidance_;
-
- // True if connection option 'BBRB' is set.
- bool limit_max_ack_height_tracker_by_send_rate_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_CONGESTION_CONTROL_BANDWIDTH_SAMPLER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/congestion_control/bandwidth_sampler_test.cc b/chromium/net/third_party/quiche/src/quic/core/congestion_control/bandwidth_sampler_test.cc
deleted file mode 100644
index 7babb1fece7..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/congestion_control/bandwidth_sampler_test.cc
+++ /dev/null
@@ -1,889 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/congestion_control/bandwidth_sampler.h"
-#include <cstdint>
-#include <set>
-
-#include "quic/core/quic_bandwidth.h"
-#include "quic/core/quic_time.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/mock_clock.h"
-
-namespace quic {
-namespace test {
-
-class BandwidthSamplerPeer {
- public:
- static size_t GetNumberOfTrackedPackets(const BandwidthSampler& sampler) {
- return sampler.connection_state_map_.number_of_present_entries();
- }
-
- static QuicByteCount GetPacketSize(const BandwidthSampler& sampler,
- QuicPacketNumber packet_number) {
- return sampler.connection_state_map_.GetEntry(packet_number)->size;
- }
-};
-
-const QuicByteCount kRegularPacketSize = 1280;
-// Enforce divisibility for some of the tests.
-static_assert((kRegularPacketSize & 31) == 0,
- "kRegularPacketSize has to be five times divisible by 2");
-
-struct TestParameters {
- bool overestimate_avoidance;
-};
-
-// Used by ::testing::PrintToStringParamName().
-std::string PrintToString(const TestParameters& p) {
- return p.overestimate_avoidance ? "enable_overestimate_avoidance"
- : "no_enable_overestimate_avoidance";
-}
-
-// A test fixture with utility methods for BandwidthSampler tests.
-class BandwidthSamplerTest : public QuicTestWithParam<TestParameters> {
- protected:
- BandwidthSamplerTest()
- : sampler_(nullptr, /*max_height_tracker_window_length=*/0),
- sampler_app_limited_at_start_(sampler_.is_app_limited()),
- bytes_in_flight_(0),
- max_bandwidth_(QuicBandwidth::Zero()),
- est_bandwidth_upper_bound_(QuicBandwidth::Infinite()),
- round_trip_count_(0) {
- // Ensure that the clock does not start at zero.
- clock_.AdvanceTime(QuicTime::Delta::FromSeconds(1));
- if (GetParam().overestimate_avoidance) {
- sampler_.EnableOverestimateAvoidance();
- }
- }
-
- MockClock clock_;
- BandwidthSampler sampler_;
- bool sampler_app_limited_at_start_;
- QuicByteCount bytes_in_flight_;
- QuicBandwidth max_bandwidth_; // Max observed bandwidth from acks.
- QuicBandwidth est_bandwidth_upper_bound_;
- QuicRoundTripCount round_trip_count_; // Needed to calculate extra_acked.
-
- QuicByteCount PacketsToBytes(QuicPacketCount packet_count) {
- return packet_count * kRegularPacketSize;
- }
-
- void SendPacketInner(uint64_t packet_number,
- QuicByteCount bytes,
- HasRetransmittableData has_retransmittable_data) {
- sampler_.OnPacketSent(clock_.Now(), QuicPacketNumber(packet_number), bytes,
- bytes_in_flight_, has_retransmittable_data);
- if (has_retransmittable_data == HAS_RETRANSMITTABLE_DATA) {
- bytes_in_flight_ += bytes;
- }
- }
-
- void SendPacket(uint64_t packet_number) {
- SendPacketInner(packet_number, kRegularPacketSize,
- HAS_RETRANSMITTABLE_DATA);
- }
-
- BandwidthSample AckPacketInner(uint64_t packet_number) {
- QuicByteCount size = BandwidthSamplerPeer::GetPacketSize(
- sampler_, QuicPacketNumber(packet_number));
- bytes_in_flight_ -= size;
- BandwidthSampler::CongestionEventSample sample = sampler_.OnCongestionEvent(
- clock_.Now(), {MakeAckedPacket(packet_number)}, {}, max_bandwidth_,
- est_bandwidth_upper_bound_, round_trip_count_);
- max_bandwidth_ = std::max(max_bandwidth_, sample.sample_max_bandwidth);
- BandwidthSample bandwidth_sample;
- bandwidth_sample.bandwidth = sample.sample_max_bandwidth;
- bandwidth_sample.rtt = sample.sample_rtt;
- bandwidth_sample.state_at_send = sample.last_packet_send_state;
- EXPECT_TRUE(bandwidth_sample.state_at_send.is_valid);
- return bandwidth_sample;
- }
-
- AckedPacket MakeAckedPacket(uint64_t packet_number) const {
- QuicByteCount size = BandwidthSamplerPeer::GetPacketSize(
- sampler_, QuicPacketNumber(packet_number));
- return AckedPacket(QuicPacketNumber(packet_number), size, clock_.Now());
- }
-
- LostPacket MakeLostPacket(uint64_t packet_number) const {
- return LostPacket(QuicPacketNumber(packet_number),
- BandwidthSamplerPeer::GetPacketSize(
- sampler_, QuicPacketNumber(packet_number)));
- }
-
- // Acknowledge receipt of a packet and expect it to be not app-limited.
- QuicBandwidth AckPacket(uint64_t packet_number) {
- BandwidthSample sample = AckPacketInner(packet_number);
- return sample.bandwidth;
- }
-
- BandwidthSampler::CongestionEventSample OnCongestionEvent(
- std::set<uint64_t> acked_packet_numbers,
- std::set<uint64_t> lost_packet_numbers) {
- AckedPacketVector acked_packets;
- for (auto it = acked_packet_numbers.begin();
- it != acked_packet_numbers.end(); ++it) {
- acked_packets.push_back(MakeAckedPacket(*it));
- bytes_in_flight_ -= acked_packets.back().bytes_acked;
- }
-
- LostPacketVector lost_packets;
- for (auto it = lost_packet_numbers.begin(); it != lost_packet_numbers.end();
- ++it) {
- lost_packets.push_back(MakeLostPacket(*it));
- bytes_in_flight_ -= lost_packets.back().bytes_lost;
- }
-
- BandwidthSampler::CongestionEventSample sample = sampler_.OnCongestionEvent(
- clock_.Now(), acked_packets, lost_packets, max_bandwidth_,
- est_bandwidth_upper_bound_, round_trip_count_);
- max_bandwidth_ = std::max(max_bandwidth_, sample.sample_max_bandwidth);
- return sample;
- }
-
- SendTimeState LosePacket(uint64_t packet_number) {
- QuicByteCount size = BandwidthSamplerPeer::GetPacketSize(
- sampler_, QuicPacketNumber(packet_number));
- bytes_in_flight_ -= size;
- LostPacket lost_packet(QuicPacketNumber(packet_number), size);
- BandwidthSampler::CongestionEventSample sample = sampler_.OnCongestionEvent(
- clock_.Now(), {}, {lost_packet}, max_bandwidth_,
- est_bandwidth_upper_bound_, round_trip_count_);
- EXPECT_TRUE(sample.last_packet_send_state.is_valid);
- EXPECT_EQ(sample.sample_max_bandwidth, QuicBandwidth::Zero());
- EXPECT_EQ(sample.sample_rtt, QuicTime::Delta::Infinite());
- return sample.last_packet_send_state;
- }
-
- // Sends one packet and acks it. Then, send 20 packets. Finally, send
- // another 20 packets while acknowledging previous 20.
- void Send40PacketsAndAckFirst20(QuicTime::Delta time_between_packets) {
- // Send 20 packets at a constant inter-packet time.
- for (int i = 1; i <= 20; i++) {
- SendPacket(i);
- clock_.AdvanceTime(time_between_packets);
- }
-
- // Ack packets 1 to 20, while sending new packets at the same rate as
- // before.
- for (int i = 1; i <= 20; i++) {
- AckPacket(i);
- SendPacket(i + 20);
- clock_.AdvanceTime(time_between_packets);
- }
- }
-};
-
-INSTANTIATE_TEST_SUITE_P(
- BandwidthSamplerTests,
- BandwidthSamplerTest,
- testing::Values(TestParameters{/*overestimate_avoidance=*/false},
- TestParameters{/*overestimate_avoidance=*/true}),
- testing::PrintToStringParamName());
-
-// Test the sampler in a simple stop-and-wait sender setting.
-TEST_P(BandwidthSamplerTest, SendAndWait) {
- QuicTime::Delta time_between_packets = QuicTime::Delta::FromMilliseconds(10);
- QuicBandwidth expected_bandwidth =
- QuicBandwidth::FromBytesPerSecond(kRegularPacketSize * 100);
-
- // Send packets at the constant bandwidth.
- for (int i = 1; i < 20; i++) {
- SendPacket(i);
- clock_.AdvanceTime(time_between_packets);
- QuicBandwidth current_sample = AckPacket(i);
- EXPECT_EQ(expected_bandwidth, current_sample);
- }
-
- // Send packets at the exponentially decreasing bandwidth.
- for (int i = 20; i < 25; i++) {
- time_between_packets = time_between_packets * 2;
- expected_bandwidth = expected_bandwidth * 0.5;
-
- SendPacket(i);
- clock_.AdvanceTime(time_between_packets);
- QuicBandwidth current_sample = AckPacket(i);
- EXPECT_EQ(expected_bandwidth, current_sample);
- }
- sampler_.RemoveObsoletePackets(QuicPacketNumber(25));
-
- EXPECT_EQ(0u, BandwidthSamplerPeer::GetNumberOfTrackedPackets(sampler_));
- EXPECT_EQ(0u, bytes_in_flight_);
-}
-
-TEST_P(BandwidthSamplerTest, SendTimeState) {
- QuicTime::Delta time_between_packets = QuicTime::Delta::FromMilliseconds(10);
-
- // Send packets 1-5.
- for (int i = 1; i <= 5; i++) {
- SendPacket(i);
- EXPECT_EQ(PacketsToBytes(i), sampler_.total_bytes_sent());
- clock_.AdvanceTime(time_between_packets);
- }
-
- // Ack packet 1.
- SendTimeState send_time_state = AckPacketInner(1).state_at_send;
- EXPECT_EQ(PacketsToBytes(1), send_time_state.total_bytes_sent);
- EXPECT_EQ(0u, send_time_state.total_bytes_acked);
- EXPECT_EQ(0u, send_time_state.total_bytes_lost);
- EXPECT_EQ(PacketsToBytes(1), sampler_.total_bytes_acked());
-
- // Lose packet 2.
- send_time_state = LosePacket(2);
- EXPECT_EQ(PacketsToBytes(2), send_time_state.total_bytes_sent);
- EXPECT_EQ(0u, send_time_state.total_bytes_acked);
- EXPECT_EQ(0u, send_time_state.total_bytes_lost);
- EXPECT_EQ(PacketsToBytes(1), sampler_.total_bytes_lost());
-
- // Lose packet 3.
- send_time_state = LosePacket(3);
- EXPECT_EQ(PacketsToBytes(3), send_time_state.total_bytes_sent);
- EXPECT_EQ(0u, send_time_state.total_bytes_acked);
- EXPECT_EQ(0u, send_time_state.total_bytes_lost);
- EXPECT_EQ(PacketsToBytes(2), sampler_.total_bytes_lost());
-
- // Send packets 6-10.
- for (int i = 6; i <= 10; i++) {
- SendPacket(i);
- EXPECT_EQ(PacketsToBytes(i), sampler_.total_bytes_sent());
- clock_.AdvanceTime(time_between_packets);
- }
-
- // Ack all inflight packets.
- QuicPacketCount acked_packet_count = 1;
- EXPECT_EQ(PacketsToBytes(acked_packet_count), sampler_.total_bytes_acked());
- for (int i = 4; i <= 10; i++) {
- send_time_state = AckPacketInner(i).state_at_send;
- ++acked_packet_count;
- EXPECT_EQ(PacketsToBytes(acked_packet_count), sampler_.total_bytes_acked());
- EXPECT_EQ(PacketsToBytes(i), send_time_state.total_bytes_sent);
- if (i <= 5) {
- EXPECT_EQ(0u, send_time_state.total_bytes_acked);
- EXPECT_EQ(0u, send_time_state.total_bytes_lost);
- } else {
- EXPECT_EQ(PacketsToBytes(1), send_time_state.total_bytes_acked);
- EXPECT_EQ(PacketsToBytes(2), send_time_state.total_bytes_lost);
- }
-
- // This equation works because there is no neutered bytes.
- EXPECT_EQ(send_time_state.total_bytes_sent -
- send_time_state.total_bytes_acked -
- send_time_state.total_bytes_lost,
- send_time_state.bytes_in_flight);
-
- clock_.AdvanceTime(time_between_packets);
- }
-}
-
-// Test the sampler during regular windowed sender scenario with fixed
-// CWND of 20.
-TEST_P(BandwidthSamplerTest, SendPaced) {
- const QuicTime::Delta time_between_packets =
- QuicTime::Delta::FromMilliseconds(1);
- QuicBandwidth expected_bandwidth =
- QuicBandwidth::FromKBytesPerSecond(kRegularPacketSize);
-
- Send40PacketsAndAckFirst20(time_between_packets);
-
- // Ack the packets 21 to 40, arriving at the correct bandwidth.
- QuicBandwidth last_bandwidth = QuicBandwidth::Zero();
- for (int i = 21; i <= 40; i++) {
- last_bandwidth = AckPacket(i);
- EXPECT_EQ(expected_bandwidth, last_bandwidth) << "i is " << i;
- clock_.AdvanceTime(time_between_packets);
- }
- sampler_.RemoveObsoletePackets(QuicPacketNumber(41));
-
- EXPECT_EQ(0u, BandwidthSamplerPeer::GetNumberOfTrackedPackets(sampler_));
- EXPECT_EQ(0u, bytes_in_flight_);
-}
-
-// Test the sampler in a scenario where 50% of packets is consistently lost.
-TEST_P(BandwidthSamplerTest, SendWithLosses) {
- const QuicTime::Delta time_between_packets =
- QuicTime::Delta::FromMilliseconds(1);
- QuicBandwidth expected_bandwidth =
- QuicBandwidth::FromKBytesPerSecond(kRegularPacketSize) * 0.5;
-
- // Send 20 packets, each 1 ms apart.
- for (int i = 1; i <= 20; i++) {
- SendPacket(i);
- clock_.AdvanceTime(time_between_packets);
- }
-
- // Ack packets 1 to 20, losing every even-numbered packet, while sending new
- // packets at the same rate as before.
- for (int i = 1; i <= 20; i++) {
- if (i % 2 == 0) {
- AckPacket(i);
- } else {
- LosePacket(i);
- }
- SendPacket(i + 20);
- clock_.AdvanceTime(time_between_packets);
- }
-
- // Ack the packets 21 to 40 with the same loss pattern.
- QuicBandwidth last_bandwidth = QuicBandwidth::Zero();
- for (int i = 21; i <= 40; i++) {
- if (i % 2 == 0) {
- last_bandwidth = AckPacket(i);
- EXPECT_EQ(expected_bandwidth, last_bandwidth);
- } else {
- LosePacket(i);
- }
- clock_.AdvanceTime(time_between_packets);
- }
- sampler_.RemoveObsoletePackets(QuicPacketNumber(41));
-
- EXPECT_EQ(0u, BandwidthSamplerPeer::GetNumberOfTrackedPackets(sampler_));
- EXPECT_EQ(0u, bytes_in_flight_);
-}
-
-// Test the sampler in a scenario where the 50% of packets are not
-// congestion controlled (specifically, non-retransmittable data is not
-// congestion controlled). Should be functionally consistent in behavior with
-// the SendWithLosses test.
-TEST_P(BandwidthSamplerTest, NotCongestionControlled) {
- const QuicTime::Delta time_between_packets =
- QuicTime::Delta::FromMilliseconds(1);
- QuicBandwidth expected_bandwidth =
- QuicBandwidth::FromKBytesPerSecond(kRegularPacketSize) * 0.5;
-
- // Send 20 packets, each 1 ms apart. Every even packet is not congestion
- // controlled.
- for (int i = 1; i <= 20; i++) {
- SendPacketInner(
- i, kRegularPacketSize,
- i % 2 == 0 ? HAS_RETRANSMITTABLE_DATA : NO_RETRANSMITTABLE_DATA);
- clock_.AdvanceTime(time_between_packets);
- }
-
- // Ensure only congestion controlled packets are tracked.
- EXPECT_EQ(10u, BandwidthSamplerPeer::GetNumberOfTrackedPackets(sampler_));
-
- // Ack packets 2 to 21, ignoring every even-numbered packet, while sending new
- // packets at the same rate as before.
- for (int i = 1; i <= 20; i++) {
- if (i % 2 == 0) {
- AckPacket(i);
- }
- SendPacketInner(
- i + 20, kRegularPacketSize,
- i % 2 == 0 ? HAS_RETRANSMITTABLE_DATA : NO_RETRANSMITTABLE_DATA);
- clock_.AdvanceTime(time_between_packets);
- }
-
- // Ack the packets 22 to 41 with the same congestion controlled pattern.
- QuicBandwidth last_bandwidth = QuicBandwidth::Zero();
- for (int i = 21; i <= 40; i++) {
- if (i % 2 == 0) {
- last_bandwidth = AckPacket(i);
- EXPECT_EQ(expected_bandwidth, last_bandwidth);
- }
- clock_.AdvanceTime(time_between_packets);
- }
- sampler_.RemoveObsoletePackets(QuicPacketNumber(41));
-
- // Since only congestion controlled packets are entered into the map, it has
- // to be empty at this point.
- EXPECT_EQ(0u, BandwidthSamplerPeer::GetNumberOfTrackedPackets(sampler_));
- EXPECT_EQ(0u, bytes_in_flight_);
-}
-
-// Simulate a situation where ACKs arrive in burst and earlier than usual, thus
-// producing an ACK rate which is higher than the original send rate.
-TEST_P(BandwidthSamplerTest, CompressedAck) {
- const QuicTime::Delta time_between_packets =
- QuicTime::Delta::FromMilliseconds(1);
- QuicBandwidth expected_bandwidth =
- QuicBandwidth::FromKBytesPerSecond(kRegularPacketSize);
-
- Send40PacketsAndAckFirst20(time_between_packets);
-
- // Simulate an RTT somewhat lower than the one for 1-to-21 transmission.
- clock_.AdvanceTime(time_between_packets * 15);
-
- // Ack the packets 21 to 40 almost immediately at once.
- QuicBandwidth last_bandwidth = QuicBandwidth::Zero();
- QuicTime::Delta ridiculously_small_time_delta =
- QuicTime::Delta::FromMicroseconds(20);
- for (int i = 21; i <= 40; i++) {
- last_bandwidth = AckPacket(i);
- clock_.AdvanceTime(ridiculously_small_time_delta);
- }
- EXPECT_EQ(expected_bandwidth, last_bandwidth);
-
- sampler_.RemoveObsoletePackets(QuicPacketNumber(41));
-
- EXPECT_EQ(0u, BandwidthSamplerPeer::GetNumberOfTrackedPackets(sampler_));
- EXPECT_EQ(0u, bytes_in_flight_);
-}
-
-// Tests receiving ACK packets in the reverse order.
-TEST_P(BandwidthSamplerTest, ReorderedAck) {
- const QuicTime::Delta time_between_packets =
- QuicTime::Delta::FromMilliseconds(1);
- QuicBandwidth expected_bandwidth =
- QuicBandwidth::FromKBytesPerSecond(kRegularPacketSize);
-
- Send40PacketsAndAckFirst20(time_between_packets);
-
- // Ack the packets 21 to 40 in the reverse order, while sending packets 41 to
- // 60.
- QuicBandwidth last_bandwidth = QuicBandwidth::Zero();
- for (int i = 0; i < 20; i++) {
- last_bandwidth = AckPacket(40 - i);
- EXPECT_EQ(expected_bandwidth, last_bandwidth);
- SendPacket(41 + i);
- clock_.AdvanceTime(time_between_packets);
- }
-
- // Ack the packets 41 to 60, now in the regular order.
- for (int i = 41; i <= 60; i++) {
- last_bandwidth = AckPacket(i);
- EXPECT_EQ(expected_bandwidth, last_bandwidth);
- clock_.AdvanceTime(time_between_packets);
- }
- sampler_.RemoveObsoletePackets(QuicPacketNumber(61));
-
- EXPECT_EQ(0u, BandwidthSamplerPeer::GetNumberOfTrackedPackets(sampler_));
- EXPECT_EQ(0u, bytes_in_flight_);
-}
-
-// Test the app-limited logic.
-TEST_P(BandwidthSamplerTest, AppLimited) {
- const QuicTime::Delta time_between_packets =
- QuicTime::Delta::FromMilliseconds(1);
- QuicBandwidth expected_bandwidth =
- QuicBandwidth::FromKBytesPerSecond(kRegularPacketSize);
-
- // Send 20 packets at a constant inter-packet time.
- for (int i = 1; i <= 20; i++) {
- SendPacket(i);
- clock_.AdvanceTime(time_between_packets);
- }
-
- // Ack packets 1 to 20, while sending new packets at the same rate as
- // before.
- for (int i = 1; i <= 20; i++) {
- BandwidthSample sample = AckPacketInner(i);
- EXPECT_EQ(sample.state_at_send.is_app_limited,
- sampler_app_limited_at_start_);
- SendPacket(i + 20);
- clock_.AdvanceTime(time_between_packets);
- }
-
- // We are now app-limited. Ack 21 to 40 as usual, but do not send anything for
- // now.
- sampler_.OnAppLimited();
- for (int i = 21; i <= 40; i++) {
- BandwidthSample sample = AckPacketInner(i);
- EXPECT_FALSE(sample.state_at_send.is_app_limited);
- EXPECT_EQ(expected_bandwidth, sample.bandwidth);
- clock_.AdvanceTime(time_between_packets);
- }
-
- // Enter quiescence.
- clock_.AdvanceTime(QuicTime::Delta::FromSeconds(1));
-
- // Send packets 41 to 60, all of which would be marked as app-limited.
- for (int i = 41; i <= 60; i++) {
- SendPacket(i);
- clock_.AdvanceTime(time_between_packets);
- }
-
- // Ack packets 41 to 60, while sending packets 61 to 80. 41 to 60 should be
- // app-limited and underestimate the bandwidth due to that.
- for (int i = 41; i <= 60; i++) {
- BandwidthSample sample = AckPacketInner(i);
- EXPECT_TRUE(sample.state_at_send.is_app_limited);
- EXPECT_LT(sample.bandwidth, 0.7f * expected_bandwidth);
-
- SendPacket(i + 20);
- clock_.AdvanceTime(time_between_packets);
- }
-
- // Run out of packets, and then ack packet 61 to 80, all of which should have
- // correct non-app-limited samples.
- for (int i = 61; i <= 80; i++) {
- BandwidthSample sample = AckPacketInner(i);
- EXPECT_FALSE(sample.state_at_send.is_app_limited);
- EXPECT_EQ(sample.bandwidth, expected_bandwidth);
- clock_.AdvanceTime(time_between_packets);
- }
- sampler_.RemoveObsoletePackets(QuicPacketNumber(81));
-
- EXPECT_EQ(0u, BandwidthSamplerPeer::GetNumberOfTrackedPackets(sampler_));
- EXPECT_EQ(0u, bytes_in_flight_);
-}
-
-// Test the samples taken at the first flight of packets sent.
-TEST_P(BandwidthSamplerTest, FirstRoundTrip) {
- const QuicTime::Delta time_between_packets =
- QuicTime::Delta::FromMilliseconds(1);
- const QuicTime::Delta rtt = QuicTime::Delta::FromMilliseconds(800);
- const int num_packets = 10;
- const QuicByteCount num_bytes = kRegularPacketSize * num_packets;
- const QuicBandwidth real_bandwidth =
- QuicBandwidth::FromBytesAndTimeDelta(num_bytes, rtt);
-
- for (int i = 1; i <= 10; i++) {
- SendPacket(i);
- clock_.AdvanceTime(time_between_packets);
- }
-
- clock_.AdvanceTime(rtt - num_packets * time_between_packets);
-
- QuicBandwidth last_sample = QuicBandwidth::Zero();
- for (int i = 1; i <= 10; i++) {
- QuicBandwidth sample = AckPacket(i);
- EXPECT_GT(sample, last_sample);
- last_sample = sample;
- clock_.AdvanceTime(time_between_packets);
- }
-
- // The final measured sample for the first flight of sample is expected to be
- // smaller than the real bandwidth, yet it should not lose more than 10%. The
- // specific value of the error depends on the difference between the RTT and
- // the time it takes to exhaust the congestion window (i.e. in the limit when
- // all packets are sent simultaneously, last sample would indicate the real
- // bandwidth).
- EXPECT_LT(last_sample, real_bandwidth);
- EXPECT_GT(last_sample, 0.9f * real_bandwidth);
-}
-
-// Test sampler's ability to remove obsolete packets.
-TEST_P(BandwidthSamplerTest, RemoveObsoletePackets) {
- SendPacket(1);
- SendPacket(2);
- SendPacket(3);
- SendPacket(4);
- SendPacket(5);
-
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(100));
-
- EXPECT_EQ(5u, BandwidthSamplerPeer::GetNumberOfTrackedPackets(sampler_));
- sampler_.RemoveObsoletePackets(QuicPacketNumber(4));
- EXPECT_EQ(2u, BandwidthSamplerPeer::GetNumberOfTrackedPackets(sampler_));
- LosePacket(4);
- sampler_.RemoveObsoletePackets(QuicPacketNumber(5));
-
- EXPECT_EQ(1u, BandwidthSamplerPeer::GetNumberOfTrackedPackets(sampler_));
- AckPacket(5);
-
- sampler_.RemoveObsoletePackets(QuicPacketNumber(6));
-
- EXPECT_EQ(0u, BandwidthSamplerPeer::GetNumberOfTrackedPackets(sampler_));
-}
-
-TEST_P(BandwidthSamplerTest, NeuterPacket) {
- SendPacket(1);
- EXPECT_EQ(0u, sampler_.total_bytes_neutered());
-
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
- sampler_.OnPacketNeutered(QuicPacketNumber(1));
- EXPECT_LT(0u, sampler_.total_bytes_neutered());
- EXPECT_EQ(0u, sampler_.total_bytes_acked());
-
- // If packet 1 is acked it should not produce a bandwidth sample.
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
- BandwidthSampler::CongestionEventSample sample = sampler_.OnCongestionEvent(
- clock_.Now(),
- {AckedPacket(QuicPacketNumber(1), kRegularPacketSize, clock_.Now())}, {},
- max_bandwidth_, est_bandwidth_upper_bound_, round_trip_count_);
- EXPECT_EQ(0u, sampler_.total_bytes_acked());
- EXPECT_EQ(QuicBandwidth::Zero(), sample.sample_max_bandwidth);
- EXPECT_FALSE(sample.sample_is_app_limited);
- EXPECT_EQ(QuicTime::Delta::Infinite(), sample.sample_rtt);
- EXPECT_EQ(0u, sample.sample_max_inflight);
- EXPECT_EQ(0u, sample.extra_acked);
-}
-
-TEST_P(BandwidthSamplerTest, CongestionEventSampleDefaultValues) {
- // Make sure a default constructed CongestionEventSample has the correct
- // initial values for BandwidthSampler::OnCongestionEvent() to work.
- BandwidthSampler::CongestionEventSample sample;
-
- EXPECT_EQ(QuicBandwidth::Zero(), sample.sample_max_bandwidth);
- EXPECT_FALSE(sample.sample_is_app_limited);
- EXPECT_EQ(QuicTime::Delta::Infinite(), sample.sample_rtt);
- EXPECT_EQ(0u, sample.sample_max_inflight);
- EXPECT_EQ(0u, sample.extra_acked);
-}
-
-// 1) Send 2 packets, 2) Ack both in 1 event, 3) Repeat.
-TEST_P(BandwidthSamplerTest, TwoAckedPacketsPerEvent) {
- QuicTime::Delta time_between_packets = QuicTime::Delta::FromMilliseconds(10);
- QuicBandwidth sending_rate = QuicBandwidth::FromBytesAndTimeDelta(
- kRegularPacketSize, time_between_packets);
-
- for (uint64_t i = 1; i < 21; i++) {
- SendPacket(i);
- clock_.AdvanceTime(time_between_packets);
- if (i % 2 != 0) {
- continue;
- }
-
- BandwidthSampler::CongestionEventSample sample =
- OnCongestionEvent({i - 1, i}, {});
- EXPECT_EQ(sending_rate, sample.sample_max_bandwidth);
- EXPECT_EQ(time_between_packets, sample.sample_rtt);
- EXPECT_EQ(2 * kRegularPacketSize, sample.sample_max_inflight);
- EXPECT_TRUE(sample.last_packet_send_state.is_valid);
- EXPECT_EQ(2 * kRegularPacketSize,
- sample.last_packet_send_state.bytes_in_flight);
- EXPECT_EQ(i * kRegularPacketSize,
- sample.last_packet_send_state.total_bytes_sent);
- EXPECT_EQ((i - 2) * kRegularPacketSize,
- sample.last_packet_send_state.total_bytes_acked);
- EXPECT_EQ(0u, sample.last_packet_send_state.total_bytes_lost);
- sampler_.RemoveObsoletePackets(QuicPacketNumber(i - 2));
- }
-}
-
-TEST_P(BandwidthSamplerTest, LoseEveryOtherPacket) {
- QuicTime::Delta time_between_packets = QuicTime::Delta::FromMilliseconds(10);
- QuicBandwidth sending_rate = QuicBandwidth::FromBytesAndTimeDelta(
- kRegularPacketSize, time_between_packets);
-
- for (uint64_t i = 1; i < 21; i++) {
- SendPacket(i);
- clock_.AdvanceTime(time_between_packets);
- if (i % 2 != 0) {
- continue;
- }
-
- // Ack packet i and lose i-1.
- BandwidthSampler::CongestionEventSample sample =
- OnCongestionEvent({i}, {i - 1});
- // Losing 50% packets means sending rate is twice the bandwidth.
- EXPECT_EQ(sending_rate, sample.sample_max_bandwidth * 2);
- EXPECT_EQ(time_between_packets, sample.sample_rtt);
- EXPECT_EQ(kRegularPacketSize, sample.sample_max_inflight);
- EXPECT_TRUE(sample.last_packet_send_state.is_valid);
- EXPECT_EQ(2 * kRegularPacketSize,
- sample.last_packet_send_state.bytes_in_flight);
- EXPECT_EQ(i * kRegularPacketSize,
- sample.last_packet_send_state.total_bytes_sent);
- EXPECT_EQ((i - 2) * kRegularPacketSize / 2,
- sample.last_packet_send_state.total_bytes_acked);
- EXPECT_EQ((i - 2) * kRegularPacketSize / 2,
- sample.last_packet_send_state.total_bytes_lost);
- sampler_.RemoveObsoletePackets(QuicPacketNumber(i - 2));
- }
-}
-
-TEST_P(BandwidthSamplerTest, AckHeightRespectBandwidthEstimateUpperBound) {
- QuicTime::Delta time_between_packets = QuicTime::Delta::FromMilliseconds(10);
- QuicBandwidth first_packet_sending_rate =
- QuicBandwidth::FromBytesAndTimeDelta(kRegularPacketSize,
- time_between_packets);
-
- // Send packets 1 to 4 and ack packet 1.
- SendPacket(1);
- clock_.AdvanceTime(time_between_packets);
- SendPacket(2);
- SendPacket(3);
- SendPacket(4);
- BandwidthSampler::CongestionEventSample sample = OnCongestionEvent({1}, {});
- EXPECT_EQ(first_packet_sending_rate, sample.sample_max_bandwidth);
- EXPECT_EQ(first_packet_sending_rate, max_bandwidth_);
-
- // Ack packet 2, 3 and 4, all of which uses S(1) to calculate ack rate since
- // there were no acks at the time they were sent.
- round_trip_count_++;
- est_bandwidth_upper_bound_ = first_packet_sending_rate * 0.3;
- clock_.AdvanceTime(time_between_packets);
- sample = OnCongestionEvent({2, 3, 4}, {});
- EXPECT_EQ(first_packet_sending_rate * 2, sample.sample_max_bandwidth);
- EXPECT_EQ(max_bandwidth_, sample.sample_max_bandwidth);
-
- EXPECT_LT(2 * kRegularPacketSize, sample.extra_acked);
-}
-
-class MaxAckHeightTrackerTest : public QuicTest {
- protected:
- MaxAckHeightTrackerTest() : tracker_(/*initial_filter_window=*/10) {
- tracker_.SetAckAggregationBandwidthThreshold(1.8);
- tracker_.SetStartNewAggregationEpochAfterFullRound(true);
- }
-
- // Run a full aggregation episode, which is one or more aggregated acks,
- // followed by a quiet period in which no ack happens.
- // After this function returns, the time is set to the earliest point at which
- // any ack event will cause tracker_.Update() to start a new aggregation.
- void AggregationEpisode(QuicBandwidth aggregation_bandwidth,
- QuicTime::Delta aggregation_duration,
- QuicByteCount bytes_per_ack,
- bool expect_new_aggregation_epoch) {
- ASSERT_GE(aggregation_bandwidth, bandwidth_);
- const QuicTime start_time = now_;
-
- const QuicByteCount aggregation_bytes =
- aggregation_bandwidth * aggregation_duration;
-
- const int num_acks = aggregation_bytes / bytes_per_ack;
- ASSERT_EQ(aggregation_bytes, num_acks * bytes_per_ack)
- << "aggregation_bytes: " << aggregation_bytes << " ["
- << aggregation_bandwidth << " in " << aggregation_duration
- << "], bytes_per_ack: " << bytes_per_ack;
-
- const QuicTime::Delta time_between_acks = QuicTime::Delta::FromMicroseconds(
- aggregation_duration.ToMicroseconds() / num_acks);
- ASSERT_EQ(aggregation_duration, num_acks * time_between_acks)
- << "aggregation_bytes: " << aggregation_bytes
- << ", num_acks: " << num_acks
- << ", time_between_acks: " << time_between_acks;
-
- // The total duration of aggregation time and quiet period.
- const QuicTime::Delta total_duration = QuicTime::Delta::FromMicroseconds(
- aggregation_bytes * 8 * 1000000 / bandwidth_.ToBitsPerSecond());
- ASSERT_EQ(aggregation_bytes, total_duration * bandwidth_)
- << "total_duration: " << total_duration
- << ", bandwidth_: " << bandwidth_;
-
- QuicByteCount last_extra_acked = 0;
- for (QuicByteCount bytes = 0; bytes < aggregation_bytes;
- bytes += bytes_per_ack) {
- QuicByteCount extra_acked = tracker_.Update(
- bandwidth_, true, RoundTripCount(), last_sent_packet_number_,
- last_acked_packet_number_, now_, bytes_per_ack);
- QUIC_VLOG(1) << "T" << now_ << ": Update after " << bytes_per_ack
- << " bytes acked, " << extra_acked << " extra bytes acked";
- // |extra_acked| should be 0 if either
- // [1] We are at the beginning of a aggregation epoch(bytes==0) and the
- // the current tracker implementation can identify it, or
- // [2] We are not really aggregating acks.
- if ((bytes == 0 && expect_new_aggregation_epoch) || // [1]
- (aggregation_bandwidth == bandwidth_)) { // [2]
- EXPECT_EQ(0u, extra_acked);
- } else {
- EXPECT_LT(last_extra_acked, extra_acked);
- }
- now_ = now_ + time_between_acks;
- last_extra_acked = extra_acked;
- }
-
- // Advance past the quiet period.
- const QuicTime time_after_aggregation = now_;
- now_ = start_time + total_duration;
- QUIC_VLOG(1) << "Advanced time from " << time_after_aggregation << " to "
- << now_ << ". Aggregation time["
- << (time_after_aggregation - start_time) << "], Quiet time["
- << (now_ - time_after_aggregation) << "].";
- }
-
- QuicRoundTripCount RoundTripCount() const {
- return (now_ - QuicTime::Zero()).ToMicroseconds() / rtt_.ToMicroseconds();
- }
-
- MaxAckHeightTracker tracker_;
- QuicBandwidth bandwidth_ = QuicBandwidth::FromBytesPerSecond(10 * 1000);
- QuicTime now_ = QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(1);
- QuicTime::Delta rtt_ = QuicTime::Delta::FromMilliseconds(60);
- QuicPacketNumber last_sent_packet_number_;
- QuicPacketNumber last_acked_packet_number_;
-};
-
-TEST_F(MaxAckHeightTrackerTest, VeryAggregatedLargeAck) {
- AggregationEpisode(bandwidth_ * 20, QuicTime::Delta::FromMilliseconds(6),
- 1200, true);
- AggregationEpisode(bandwidth_ * 20, QuicTime::Delta::FromMilliseconds(6),
- 1200, true);
- now_ = now_ - QuicTime::Delta::FromMilliseconds(1);
-
- if (tracker_.ack_aggregation_bandwidth_threshold() > 1.1) {
- AggregationEpisode(bandwidth_ * 20, QuicTime::Delta::FromMilliseconds(6),
- 1200, true);
- EXPECT_EQ(3u, tracker_.num_ack_aggregation_epochs());
- } else {
- AggregationEpisode(bandwidth_ * 20, QuicTime::Delta::FromMilliseconds(6),
- 1200, false);
- EXPECT_EQ(2u, tracker_.num_ack_aggregation_epochs());
- }
-}
-
-TEST_F(MaxAckHeightTrackerTest, VeryAggregatedSmallAcks) {
- AggregationEpisode(bandwidth_ * 20, QuicTime::Delta::FromMilliseconds(6), 300,
- true);
- AggregationEpisode(bandwidth_ * 20, QuicTime::Delta::FromMilliseconds(6), 300,
- true);
- now_ = now_ - QuicTime::Delta::FromMilliseconds(1);
-
- if (tracker_.ack_aggregation_bandwidth_threshold() > 1.1) {
- AggregationEpisode(bandwidth_ * 20, QuicTime::Delta::FromMilliseconds(6),
- 300, true);
- EXPECT_EQ(3u, tracker_.num_ack_aggregation_epochs());
- } else {
- AggregationEpisode(bandwidth_ * 20, QuicTime::Delta::FromMilliseconds(6),
- 300, false);
- EXPECT_EQ(2u, tracker_.num_ack_aggregation_epochs());
- }
-}
-
-TEST_F(MaxAckHeightTrackerTest, SomewhatAggregatedLargeAck) {
- AggregationEpisode(bandwidth_ * 2, QuicTime::Delta::FromMilliseconds(50),
- 1000, true);
- AggregationEpisode(bandwidth_ * 2, QuicTime::Delta::FromMilliseconds(50),
- 1000, true);
- now_ = now_ - QuicTime::Delta::FromMilliseconds(1);
-
- if (tracker_.ack_aggregation_bandwidth_threshold() > 1.1) {
- AggregationEpisode(bandwidth_ * 2, QuicTime::Delta::FromMilliseconds(50),
- 1000, true);
- EXPECT_EQ(3u, tracker_.num_ack_aggregation_epochs());
- } else {
- AggregationEpisode(bandwidth_ * 2, QuicTime::Delta::FromMilliseconds(50),
- 1000, false);
- EXPECT_EQ(2u, tracker_.num_ack_aggregation_epochs());
- }
-}
-
-TEST_F(MaxAckHeightTrackerTest, SomewhatAggregatedSmallAcks) {
- AggregationEpisode(bandwidth_ * 2, QuicTime::Delta::FromMilliseconds(50), 100,
- true);
- AggregationEpisode(bandwidth_ * 2, QuicTime::Delta::FromMilliseconds(50), 100,
- true);
- now_ = now_ - QuicTime::Delta::FromMilliseconds(1);
-
- if (tracker_.ack_aggregation_bandwidth_threshold() > 1.1) {
- AggregationEpisode(bandwidth_ * 2, QuicTime::Delta::FromMilliseconds(50),
- 100, true);
- EXPECT_EQ(3u, tracker_.num_ack_aggregation_epochs());
- } else {
- AggregationEpisode(bandwidth_ * 2, QuicTime::Delta::FromMilliseconds(50),
- 100, false);
- EXPECT_EQ(2u, tracker_.num_ack_aggregation_epochs());
- }
-}
-
-TEST_F(MaxAckHeightTrackerTest, NotAggregated) {
- AggregationEpisode(bandwidth_, QuicTime::Delta::FromMilliseconds(100), 100,
- true);
- EXPECT_LT(2u, tracker_.num_ack_aggregation_epochs());
-}
-
-TEST_F(MaxAckHeightTrackerTest, StartNewEpochAfterAFullRound) {
- last_sent_packet_number_ = QuicPacketNumber(10);
- AggregationEpisode(bandwidth_ * 2, QuicTime::Delta::FromMilliseconds(50), 100,
- true);
-
- last_acked_packet_number_ = QuicPacketNumber(11);
- // Update with a tiny bandwidth causes a very low expected bytes acked, which
- // in turn causes the current epoch to continue if the |tracker_| doesn't
- // check the packet numbers.
- tracker_.Update(bandwidth_ * 0.1, true, RoundTripCount(),
- last_sent_packet_number_, last_acked_packet_number_, now_,
- 100);
-
- EXPECT_EQ(2u, tracker_.num_ack_aggregation_epochs());
-}
-
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/congestion_control/bbr2_drain.cc b/chromium/net/third_party/quiche/src/quic/core/congestion_control/bbr2_drain.cc
deleted file mode 100644
index 69befb51531..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/congestion_control/bbr2_drain.cc
+++ /dev/null
@@ -1,62 +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 "quic/core/congestion_control/bbr2_drain.h"
-
-#include "quic/core/congestion_control/bbr2_sender.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-Bbr2Mode Bbr2DrainMode::OnCongestionEvent(
- QuicByteCount /*prior_in_flight*/,
- QuicTime /*event_time*/,
- const AckedPacketVector& /*acked_packets*/,
- const LostPacketVector& /*lost_packets*/,
- const Bbr2CongestionEvent& congestion_event) {
- model_->set_pacing_gain(Params().drain_pacing_gain);
-
- // Only STARTUP can transition to DRAIN, both of them use the same cwnd gain.
- QUICHE_DCHECK_EQ(model_->cwnd_gain(), Params().drain_cwnd_gain);
- model_->set_cwnd_gain(Params().drain_cwnd_gain);
-
- QuicByteCount drain_target = DrainTarget();
- if (congestion_event.bytes_in_flight <= drain_target) {
- QUIC_DVLOG(3) << sender_ << " Exiting DRAIN. bytes_in_flight:"
- << congestion_event.bytes_in_flight
- << ", bdp:" << model_->BDP()
- << ", drain_target:" << drain_target << " @ "
- << congestion_event.event_time;
- return Bbr2Mode::PROBE_BW;
- }
-
- QUIC_DVLOG(3) << sender_ << " Staying in DRAIN. bytes_in_flight:"
- << congestion_event.bytes_in_flight << ", bdp:" << model_->BDP()
- << ", drain_target:" << drain_target << " @ "
- << congestion_event.event_time;
- return Bbr2Mode::DRAIN;
-}
-
-QuicByteCount Bbr2DrainMode::DrainTarget() const {
- QuicByteCount bdp = model_->BDP();
- return std::max<QuicByteCount>(bdp, sender_->GetMinimumCongestionWindow());
-}
-
-Bbr2DrainMode::DebugState Bbr2DrainMode::ExportDebugState() const {
- DebugState s;
- s.drain_target = DrainTarget();
- return s;
-}
-
-std::ostream& operator<<(std::ostream& os,
- const Bbr2DrainMode::DebugState& state) {
- os << "[DRAIN] drain_target: " << state.drain_target << "\n";
- return os;
-}
-
-const Bbr2Params& Bbr2DrainMode::Params() const {
- return sender_->Params();
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/congestion_control/bbr2_drain.h b/chromium/net/third_party/quiche/src/quic/core/congestion_control/bbr2_drain.h
deleted file mode 100644
index 3026320f72d..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/congestion_control/bbr2_drain.h
+++ /dev/null
@@ -1,61 +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_CORE_CONGESTION_CONTROL_BBR2_DRAIN_H_
-#define QUICHE_QUIC_CORE_CONGESTION_CONTROL_BBR2_DRAIN_H_
-
-#include "quic/core/congestion_control/bbr2_misc.h"
-#include "quic/core/quic_time.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-class Bbr2Sender;
-class QUIC_EXPORT_PRIVATE Bbr2DrainMode final : public Bbr2ModeBase {
- public:
- using Bbr2ModeBase::Bbr2ModeBase;
-
- void Enter(QuicTime /*now*/,
- const Bbr2CongestionEvent* /*congestion_event*/) override {}
- void Leave(QuicTime /*now*/,
- const Bbr2CongestionEvent* /*congestion_event*/) override {}
-
- Bbr2Mode OnCongestionEvent(
- QuicByteCount prior_in_flight,
- QuicTime event_time,
- const AckedPacketVector& acked_packets,
- const LostPacketVector& lost_packets,
- const Bbr2CongestionEvent& congestion_event) override;
-
- Limits<QuicByteCount> GetCwndLimits() const override {
- return NoGreaterThan(model_->inflight_lo());
- }
-
- bool IsProbingForBandwidth() const override { return false; }
-
- Bbr2Mode OnExitQuiescence(QuicTime /*now*/,
- QuicTime /*quiescence_start_time*/) override {
- return Bbr2Mode::DRAIN;
- }
-
- struct QUIC_EXPORT_PRIVATE DebugState {
- QuicByteCount drain_target;
- };
-
- DebugState ExportDebugState() const;
-
- private:
- const Bbr2Params& Params() const;
-
- QuicByteCount DrainTarget() const;
-};
-
-QUIC_EXPORT_PRIVATE std::ostream& operator<<(
- std::ostream& os,
- const Bbr2DrainMode::DebugState& state);
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_CONGESTION_CONTROL_BBR2_DRAIN_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/congestion_control/bbr2_misc.cc b/chromium/net/third_party/quiche/src/quic/core/congestion_control/bbr2_misc.cc
deleted file mode 100644
index 84728906d31..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/congestion_control/bbr2_misc.cc
+++ /dev/null
@@ -1,454 +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 "quic/core/congestion_control/bbr2_misc.h"
-
-#include "quic/core/congestion_control/bandwidth_sampler.h"
-#include "quic/core/quic_bandwidth.h"
-#include "quic/core/quic_time.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_flag_utils.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-RoundTripCounter::RoundTripCounter() : round_trip_count_(0) {}
-
-void RoundTripCounter::OnPacketSent(QuicPacketNumber packet_number) {
- QUICHE_DCHECK(!last_sent_packet_.IsInitialized() ||
- last_sent_packet_ < packet_number);
- last_sent_packet_ = packet_number;
-}
-
-bool RoundTripCounter::OnPacketsAcked(QuicPacketNumber last_acked_packet) {
- if (!end_of_round_trip_.IsInitialized() ||
- last_acked_packet > end_of_round_trip_) {
- round_trip_count_++;
- end_of_round_trip_ = last_sent_packet_;
- return true;
- }
- return false;
-}
-
-void RoundTripCounter::RestartRound() {
- end_of_round_trip_ = last_sent_packet_;
-}
-
-MinRttFilter::MinRttFilter(QuicTime::Delta initial_min_rtt,
- QuicTime initial_min_rtt_timestamp)
- : min_rtt_(initial_min_rtt),
- min_rtt_timestamp_(initial_min_rtt_timestamp) {}
-
-void MinRttFilter::Update(QuicTime::Delta sample_rtt, QuicTime now) {
- if (sample_rtt < min_rtt_ || min_rtt_timestamp_ == QuicTime::Zero()) {
- min_rtt_ = sample_rtt;
- min_rtt_timestamp_ = now;
- }
-}
-
-void MinRttFilter::ForceUpdate(QuicTime::Delta sample_rtt, QuicTime now) {
- min_rtt_ = sample_rtt;
- min_rtt_timestamp_ = now;
-}
-
-Bbr2NetworkModel::Bbr2NetworkModel(const Bbr2Params* params,
- QuicTime::Delta initial_rtt,
- QuicTime initial_rtt_timestamp,
- float cwnd_gain,
- float pacing_gain,
- const BandwidthSampler* old_sampler)
- : params_(params),
- bandwidth_sampler_([](QuicRoundTripCount max_height_tracker_window_length,
- const BandwidthSampler* old_sampler) {
- if (old_sampler != nullptr) {
- return BandwidthSampler(*old_sampler);
- }
- return BandwidthSampler(/*unacked_packet_map=*/nullptr,
- max_height_tracker_window_length);
- }(params->initial_max_ack_height_filter_window, old_sampler)),
- min_rtt_filter_(initial_rtt, initial_rtt_timestamp),
- cwnd_gain_(cwnd_gain),
- pacing_gain_(pacing_gain) {}
-
-void Bbr2NetworkModel::OnPacketSent(QuicTime sent_time,
- QuicByteCount bytes_in_flight,
- QuicPacketNumber packet_number,
- QuicByteCount bytes,
- HasRetransmittableData is_retransmittable) {
- round_trip_counter_.OnPacketSent(packet_number);
-
- bandwidth_sampler_.OnPacketSent(sent_time, packet_number, bytes,
- bytes_in_flight, is_retransmittable);
-}
-
-void Bbr2NetworkModel::OnCongestionEventStart(
- QuicTime event_time,
- const AckedPacketVector& acked_packets,
- const LostPacketVector& lost_packets,
- Bbr2CongestionEvent* congestion_event) {
- const QuicByteCount prior_bytes_acked = total_bytes_acked();
- const QuicByteCount prior_bytes_lost = total_bytes_lost();
-
- congestion_event->event_time = event_time;
- congestion_event->end_of_round_trip =
- acked_packets.empty() ? false
- : round_trip_counter_.OnPacketsAcked(
- acked_packets.rbegin()->packet_number);
-
- BandwidthSamplerInterface::CongestionEventSample sample =
- bandwidth_sampler_.OnCongestionEvent(event_time, acked_packets,
- lost_packets, MaxBandwidth(),
- bandwidth_lo(), RoundTripCount());
-
- if (sample.extra_acked == 0) {
- cwnd_limited_before_aggregation_epoch_ =
- congestion_event->prior_bytes_in_flight >= congestion_event->prior_cwnd;
- }
-
- if (sample.last_packet_send_state.is_valid) {
- congestion_event->last_packet_send_state = sample.last_packet_send_state;
- }
-
- // Avoid updating |max_bandwidth_filter_| if a) this is a loss-only event, or
- // b) all packets in |acked_packets| did not generate valid samples. (e.g. ack
- // of ack-only packets). In both cases, total_bytes_acked() will not change.
- if (prior_bytes_acked != total_bytes_acked()) {
- QUIC_LOG_IF(WARNING, sample.sample_max_bandwidth.IsZero())
- << total_bytes_acked() - prior_bytes_acked << " bytes from "
- << acked_packets.size()
- << " packets have been acked, but sample_max_bandwidth is zero.";
- congestion_event->sample_max_bandwidth = sample.sample_max_bandwidth;
- if (!sample.sample_is_app_limited ||
- sample.sample_max_bandwidth > MaxBandwidth()) {
- max_bandwidth_filter_.Update(congestion_event->sample_max_bandwidth);
- }
- }
-
- if (!sample.sample_rtt.IsInfinite()) {
- congestion_event->sample_min_rtt = sample.sample_rtt;
- min_rtt_filter_.Update(congestion_event->sample_min_rtt, event_time);
- }
-
- congestion_event->bytes_acked = total_bytes_acked() - prior_bytes_acked;
- congestion_event->bytes_lost = total_bytes_lost() - prior_bytes_lost;
-
- if (congestion_event->prior_bytes_in_flight >=
- congestion_event->bytes_acked + congestion_event->bytes_lost) {
- congestion_event->bytes_in_flight =
- congestion_event->prior_bytes_in_flight -
- congestion_event->bytes_acked - congestion_event->bytes_lost;
- } else {
- QUIC_LOG_FIRST_N(ERROR, 1)
- << "prior_bytes_in_flight:" << congestion_event->prior_bytes_in_flight
- << " is smaller than the sum of bytes_acked:"
- << congestion_event->bytes_acked
- << " and bytes_lost:" << congestion_event->bytes_lost;
- congestion_event->bytes_in_flight = 0;
- }
-
- if (congestion_event->bytes_lost > 0) {
- bytes_lost_in_round_ += congestion_event->bytes_lost;
- loss_events_in_round_++;
- }
-
- if (congestion_event->bytes_acked > 0 &&
- congestion_event->last_packet_send_state.is_valid &&
- total_bytes_acked() >
- congestion_event->last_packet_send_state.total_bytes_acked) {
- QuicByteCount bytes_delivered =
- total_bytes_acked() -
- congestion_event->last_packet_send_state.total_bytes_acked;
- max_bytes_delivered_in_round_ =
- std::max(max_bytes_delivered_in_round_, bytes_delivered);
- // TODO(ianswett) Consider treating any bytes lost as decreasing inflight,
- // because it's a sign of overutilization, not underutilization.
- if (min_bytes_in_flight_in_round_ == 0 ||
- congestion_event->bytes_in_flight < min_bytes_in_flight_in_round_) {
- min_bytes_in_flight_in_round_ = congestion_event->bytes_in_flight;
- }
- }
-
- // |bandwidth_latest_| and |inflight_latest_| only increased within a round.
- if (sample.sample_max_bandwidth > bandwidth_latest_) {
- bandwidth_latest_ = sample.sample_max_bandwidth;
- }
-
- if (sample.sample_max_inflight > inflight_latest_) {
- inflight_latest_ = sample.sample_max_inflight;
- }
-
- // Adapt lower bounds(bandwidth_lo and inflight_lo).
- AdaptLowerBounds(*congestion_event);
-
- if (!congestion_event->end_of_round_trip) {
- return;
- }
-
- if (!sample.sample_max_bandwidth.IsZero()) {
- bandwidth_latest_ = sample.sample_max_bandwidth;
- }
-
- if (sample.sample_max_inflight > 0) {
- inflight_latest_ = sample.sample_max_inflight;
- }
-}
-
-void Bbr2NetworkModel::AdaptLowerBounds(
- const Bbr2CongestionEvent& congestion_event) {
- if (Params().bw_lo_mode_ == Bbr2Params::DEFAULT) {
- if (!congestion_event.end_of_round_trip ||
- congestion_event.is_probing_for_bandwidth) {
- return;
- }
-
- if (bytes_lost_in_round_ > 0) {
- if (bandwidth_lo_.IsInfinite()) {
- bandwidth_lo_ = MaxBandwidth();
- }
- bandwidth_lo_ =
- std::max(bandwidth_latest_, bandwidth_lo_ * (1.0 - Params().beta));
- QUIC_DVLOG(3) << "bandwidth_lo_ updated to " << bandwidth_lo_
- << ", bandwidth_latest_ is " << bandwidth_latest_;
-
- if (Params().ignore_inflight_lo) {
- return;
- }
- if (inflight_lo_ == inflight_lo_default()) {
- inflight_lo_ = congestion_event.prior_cwnd;
- }
- inflight_lo_ = std::max<QuicByteCount>(
- inflight_latest_, inflight_lo_ * (1.0 - Params().beta));
- }
- return;
- }
-
- // Params().bw_lo_mode_ != Bbr2Params::DEFAULT
- if (congestion_event.bytes_lost == 0) {
- return;
- }
- // Ignore losses from packets sent when probing for more bandwidth in
- // STARTUP or PROBE_UP when they're lost in DRAIN or PROBE_DOWN.
- if (pacing_gain_ < 1) {
- return;
- }
- // Decrease bandwidth_lo whenever there is loss.
- // Set bandwidth_lo_ if it is not yet set.
- if (bandwidth_lo_.IsInfinite()) {
- bandwidth_lo_ = MaxBandwidth();
- }
- // Save bandwidth_lo_ if it hasn't already been saved.
- if (prior_bandwidth_lo_.IsZero()) {
- prior_bandwidth_lo_ = bandwidth_lo_;
- }
- switch (Params().bw_lo_mode_) {
- case Bbr2Params::MIN_RTT_REDUCTION:
- bandwidth_lo_ =
- bandwidth_lo_ - QuicBandwidth::FromBytesAndTimeDelta(
- congestion_event.bytes_lost, MinRtt());
- break;
- case Bbr2Params::INFLIGHT_REDUCTION: {
- // Use a max of BDP and inflight to avoid starving app-limited flows.
- const QuicByteCount effective_inflight =
- std::max(BDP(), congestion_event.prior_bytes_in_flight);
- // This could use bytes_lost_in_round if the bandwidth_lo_ was saved
- // when entering 'recovery', but this BBRv2 implementation doesn't have
- // recovery defined.
- bandwidth_lo_ =
- bandwidth_lo_ * ((effective_inflight - congestion_event.bytes_lost) /
- static_cast<double>(effective_inflight));
- break;
- }
- case Bbr2Params::CWND_REDUCTION:
- bandwidth_lo_ =
- bandwidth_lo_ *
- ((congestion_event.prior_cwnd - congestion_event.bytes_lost) /
- static_cast<double>(congestion_event.prior_cwnd));
- break;
- case Bbr2Params::DEFAULT:
- QUIC_BUG(quic_bug_10466_1) << "Unreachable case DEFAULT.";
- }
- QuicBandwidth last_bandwidth = bandwidth_latest_;
- // sample_max_bandwidth will be Zero() if the loss is triggered by a timer
- // expiring. Ideally we'd use the most recent bandwidth sample,
- // but bandwidth_latest is safer than Zero().
- if (!congestion_event.sample_max_bandwidth.IsZero()) {
- // bandwidth_latest_ is the max bandwidth for the round, but to allow
- // fast, conservation style response to loss, use the last sample.
- last_bandwidth = congestion_event.sample_max_bandwidth;
- }
- if (pacing_gain_ > Params().startup_full_bw_threshold) {
- // In STARTUP, pacing_gain_ is applied to bandwidth_lo_ in
- // UpdatePacingRate, so this backs that multiplication out to allow the
- // pacing rate to decrease, but not below
- // last_bandwidth * startup_full_bw_threshold.
- // TODO(ianswett): Consider altering pacing_gain_ when in STARTUP instead.
- bandwidth_lo_ = std::max(
- bandwidth_lo_,
- last_bandwidth * (Params().startup_full_bw_threshold / pacing_gain_));
- } else {
- // Ensure bandwidth_lo isn't lower than last_bandwidth.
- bandwidth_lo_ = std::max(bandwidth_lo_, last_bandwidth);
- }
- // If it's the end of the round, ensure bandwidth_lo doesn't decrease more
- // than beta.
- if (congestion_event.end_of_round_trip) {
- bandwidth_lo_ =
- std::max(bandwidth_lo_, prior_bandwidth_lo_ * (1.0 - Params().beta));
- prior_bandwidth_lo_ = QuicBandwidth::Zero();
- }
- // These modes ignore inflight_lo as well.
-}
-
-void Bbr2NetworkModel::OnCongestionEventFinish(
- QuicPacketNumber least_unacked_packet,
- const Bbr2CongestionEvent& congestion_event) {
- if (congestion_event.end_of_round_trip) {
- OnNewRound();
- }
-
- bandwidth_sampler_.RemoveObsoletePackets(least_unacked_packet);
-}
-
-void Bbr2NetworkModel::UpdateNetworkParameters(QuicTime::Delta rtt) {
- if (!rtt.IsZero()) {
- min_rtt_filter_.Update(rtt, MinRttTimestamp());
- }
-}
-
-bool Bbr2NetworkModel::MaybeExpireMinRtt(
- const Bbr2CongestionEvent& congestion_event) {
- if (congestion_event.event_time <
- (MinRttTimestamp() + Params().probe_rtt_period)) {
- return false;
- }
- if (congestion_event.sample_min_rtt.IsInfinite()) {
- return false;
- }
- QUIC_DVLOG(3) << "Replacing expired min rtt of " << min_rtt_filter_.Get()
- << " by " << congestion_event.sample_min_rtt << " @ "
- << congestion_event.event_time;
- min_rtt_filter_.ForceUpdate(congestion_event.sample_min_rtt,
- congestion_event.event_time);
- return true;
-}
-
-bool Bbr2NetworkModel::IsInflightTooHigh(
- const Bbr2CongestionEvent& congestion_event,
- int64_t max_loss_events) const {
- const SendTimeState& send_state = congestion_event.last_packet_send_state;
- if (!send_state.is_valid) {
- // Not enough information.
- return false;
- }
-
- if (loss_events_in_round() < max_loss_events) {
- return false;
- }
-
- const QuicByteCount inflight_at_send = BytesInFlight(send_state);
- // TODO(wub): Consider total_bytes_lost() - send_state.total_bytes_lost, which
- // is the total bytes lost when the largest numbered packet was inflight.
- // bytes_lost_in_round_, OTOH, is the total bytes lost in the "current" round.
- const QuicByteCount bytes_lost_in_round = bytes_lost_in_round_;
-
- QUIC_DVLOG(3) << "IsInflightTooHigh: loss_events_in_round:"
- << loss_events_in_round()
-
- << " bytes_lost_in_round:" << bytes_lost_in_round
- << ", lost_in_round_threshold:"
- << inflight_at_send * Params().loss_threshold;
-
- if (inflight_at_send > 0 && bytes_lost_in_round > 0) {
- QuicByteCount lost_in_round_threshold =
- inflight_at_send * Params().loss_threshold;
- if (bytes_lost_in_round > lost_in_round_threshold) {
- return true;
- }
- }
-
- return false;
-}
-
-void Bbr2NetworkModel::RestartRoundEarly() {
- OnNewRound();
- round_trip_counter_.RestartRound();
-}
-
-void Bbr2NetworkModel::OnNewRound() {
- bytes_lost_in_round_ = 0;
- loss_events_in_round_ = 0;
- max_bytes_delivered_in_round_ = 0;
- min_bytes_in_flight_in_round_ = 0;
-}
-
-void Bbr2NetworkModel::cap_inflight_lo(QuicByteCount cap) {
- if (Params().ignore_inflight_lo) {
- return;
- }
- if (inflight_lo_ != inflight_lo_default() && inflight_lo_ > cap) {
- inflight_lo_ = cap;
- }
-}
-
-QuicByteCount Bbr2NetworkModel::inflight_hi_with_headroom() const {
- QuicByteCount headroom = inflight_hi_ * Params().inflight_hi_headroom;
-
- return inflight_hi_ > headroom ? inflight_hi_ - headroom : 0;
-}
-
-bool Bbr2NetworkModel::HasBandwidthGrowth(
- const Bbr2CongestionEvent& congestion_event) {
- QUICHE_DCHECK(!full_bandwidth_reached_);
- QUICHE_DCHECK(congestion_event.end_of_round_trip);
-
- QuicBandwidth threshold =
- full_bandwidth_baseline_ * Params().startup_full_bw_threshold;
-
- if (MaxBandwidth() >= threshold) {
- QUIC_DVLOG(3) << " CheckBandwidthGrowth at end of round. max_bandwidth:"
- << MaxBandwidth() << ", threshold:" << threshold
- << " (Still growing) @ " << congestion_event.event_time;
- full_bandwidth_baseline_ = MaxBandwidth();
- rounds_without_bandwidth_growth_ = 0;
- return true;
- }
- ++rounds_without_bandwidth_growth_;
-
- // full_bandwidth_reached is only set to true when not app-limited, except
- // when exit_startup_on_persistent_queue is true.
- if (rounds_without_bandwidth_growth_ >= Params().startup_full_bw_rounds &&
- !congestion_event.last_packet_send_state.is_app_limited) {
- full_bandwidth_reached_ = true;
- }
- QUIC_DVLOG(3) << " CheckBandwidthGrowth at end of round. max_bandwidth:"
- << MaxBandwidth() << ", threshold:" << threshold
- << " rounds_without_growth:" << rounds_without_bandwidth_growth_
- << " full_bw_reached:" << full_bandwidth_reached_ << " @ "
- << congestion_event.event_time;
-
- return false;
-}
-
-bool Bbr2NetworkModel::CheckPersistentQueue(
- const Bbr2CongestionEvent& congestion_event, float bdp_gain) {
- QUICHE_DCHECK(congestion_event.end_of_round_trip);
- QuicByteCount target = bdp_gain * BDP();
- if (bdp_gain >= 2) {
- // Use a more conservative threshold for STARTUP because CWND gain is 2.
- if (target <= QueueingThresholdExtraBytes()) {
- return false;
- }
- target -= QueueingThresholdExtraBytes();
- } else {
- target += QueueingThresholdExtraBytes();
- }
- if (min_bytes_in_flight_in_round_ > target) {
- full_bandwidth_reached_ = true;
- return true;
- }
- return false;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/congestion_control/bbr2_misc.h b/chromium/net/third_party/quiche/src/quic/core/congestion_control/bbr2_misc.h
deleted file mode 100644
index 5716ce9ff17..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/congestion_control/bbr2_misc.h
+++ /dev/null
@@ -1,674 +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_CORE_CONGESTION_CONTROL_BBR2_MISC_H_
-#define QUICHE_QUIC_CORE_CONGESTION_CONTROL_BBR2_MISC_H_
-
-#include <algorithm>
-#include <limits>
-
-#include "quic/core/congestion_control/bandwidth_sampler.h"
-#include "quic/core/congestion_control/send_algorithm_interface.h"
-#include "quic/core/congestion_control/windowed_filter.h"
-#include "quic/core/quic_bandwidth.h"
-#include "quic/core/quic_packet_number.h"
-#include "quic/core/quic_time.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_export.h"
-#include "quic/platform/api/quic_flags.h"
-
-namespace quic {
-
-template <typename T>
-class QUIC_EXPORT_PRIVATE Limits {
- public:
- Limits(T min, T max) : min_(min), max_(max) {}
-
- // If [min, max] is an empty range, i.e. min > max, this function returns max,
- // because typically a value larger than max means "risky".
- T ApplyLimits(T raw_value) const {
- return std::min(max_, std::max(min_, raw_value));
- }
-
- T Min() const { return min_; }
- T Max() const { return max_; }
-
- private:
- T min_;
- T max_;
-};
-
-template <typename T>
-QUIC_EXPORT_PRIVATE inline Limits<T> MinMax(T min, T max) {
- return Limits<T>(min, max);
-}
-
-template <typename T>
-QUIC_EXPORT_PRIVATE inline Limits<T> NoLessThan(T min) {
- return Limits<T>(min, std::numeric_limits<T>::max());
-}
-
-template <typename T>
-QUIC_EXPORT_PRIVATE inline Limits<T> NoGreaterThan(T max) {
- return Limits<T>(std::numeric_limits<T>::min(), max);
-}
-
-template <typename T>
-QUIC_EXPORT_PRIVATE inline Limits<T> Unlimited() {
- return Limits<T>(std::numeric_limits<T>::min(),
- std::numeric_limits<T>::max());
-}
-
-template <typename T>
-QUIC_EXPORT_PRIVATE inline std::ostream& operator<<(std::ostream& os,
- const Limits<T>& limits) {
- return os << "[" << limits.Min() << ", " << limits.Max() << "]";
-}
-
-// Bbr2Params contains all parameters of a Bbr2Sender.
-struct QUIC_EXPORT_PRIVATE Bbr2Params {
- Bbr2Params(QuicByteCount cwnd_min, QuicByteCount cwnd_max)
- : cwnd_limits(cwnd_min, cwnd_max) {}
-
- /*
- * STARTUP parameters.
- */
-
- // The gain for both CWND and PacingRate at startup.
- float startup_cwnd_gain = 2.0;
- // TODO(wub): Maybe change to the newly derived value of 2.773 (4 * ln(2)).
- float startup_pacing_gain = 2.885;
-
- // Full bandwidth is declared if the total bandwidth growth is less than
- // |startup_full_bw_threshold| times in the last |startup_full_bw_rounds|
- // round trips.
- float startup_full_bw_threshold = 1.25;
-
- QuicRoundTripCount startup_full_bw_rounds = 3;
-
- // The minimum number of loss marking events to exit STARTUP.
- int64_t startup_full_loss_count =
- GetQuicFlag(FLAGS_quic_bbr2_default_startup_full_loss_count);
-
- // If true, always exit STARTUP on loss, even if bandwidth exceeds threshold.
- // If false, exit STARTUP on loss only if bandwidth is below threshold.
- bool always_exit_startup_on_excess_loss = false;
-
- // If true, include extra acked during STARTUP and proactively reduce extra
- // acked when bandwidth increases.
- bool startup_include_extra_acked = false;
-
- // If true, exit STARTUP if bytes in flight has not gone below 2 * BDP at
- // any point in the last round.
- bool exit_startup_on_persistent_queue = false;
-
- /*
- * DRAIN parameters.
- */
- float drain_cwnd_gain = 2.0;
- float drain_pacing_gain = 1.0 / 2.885;
-
- /*
- * PROBE_BW parameters.
- */
- // Max amount of randomness to inject in round counting for Reno-coexistence.
- QuicRoundTripCount probe_bw_max_probe_rand_rounds = 2;
-
- // Max number of rounds before probing for Reno-coexistence.
- uint32_t probe_bw_probe_max_rounds = 63;
-
- // Multiplier to get Reno-style probe epoch duration as: k * BDP round trips.
- // If zero, disables Reno-style BDP-scaled coexistence mechanism.
- float probe_bw_probe_reno_gain = 1.0;
-
- // Minimum duration for BBR-native probes.
- QuicTime::Delta probe_bw_probe_base_duration =
- QuicTime::Delta::FromMilliseconds(
- GetQuicFlag(FLAGS_quic_bbr2_default_probe_bw_base_duration_ms));
-
- // The upper bound of the random amount of BBR-native probes.
- QuicTime::Delta probe_bw_probe_max_rand_duration =
- QuicTime::Delta::FromMilliseconds(
- GetQuicFlag(FLAGS_quic_bbr2_default_probe_bw_max_rand_duration_ms));
-
- // The minimum number of loss marking events to exit the PROBE_UP phase.
- int64_t probe_bw_full_loss_count =
- GetQuicFlag(FLAGS_quic_bbr2_default_probe_bw_full_loss_count);
-
- // Multiplier to get target inflight (as multiple of BDP) for PROBE_UP phase.
- float probe_bw_probe_inflight_gain = 1.25;
-
- // When attempting to grow inflight_hi in PROBE_UP, check whether we are cwnd
- // limited before the current aggregation epoch, instead of before the current
- // ack event.
- bool probe_bw_check_cwnd_limited_before_aggregation_epoch = false;
-
- // Pacing gains.
- float probe_bw_probe_up_pacing_gain = 1.25;
- float probe_bw_probe_down_pacing_gain = 0.75;
- float probe_bw_default_pacing_gain = 1.0;
-
- float probe_bw_cwnd_gain = 2.0;
-
- /*
- * PROBE_UP parameters.
- */
- bool probe_up_includes_acks_after_cwnd_limited = false;
- bool probe_up_dont_exit_if_no_queue_ = false;
- bool probe_up_ignore_inflight_hi = false;
-
- /*
- * PROBE_RTT parameters.
- */
- float probe_rtt_inflight_target_bdp_fraction = 0.5;
- QuicTime::Delta probe_rtt_period = QuicTime::Delta::FromMilliseconds(
- GetQuicFlag(FLAGS_quic_bbr2_default_probe_rtt_period_ms));
- QuicTime::Delta probe_rtt_duration = QuicTime::Delta::FromMilliseconds(200);
-
- /*
- * Parameters used by multiple modes.
- */
-
- // The initial value of the max ack height filter's window length.
- QuicRoundTripCount initial_max_ack_height_filter_window =
- GetQuicFlag(FLAGS_quic_bbr2_default_initial_ack_height_filter_window);
-
- // Fraction of unutilized headroom to try to leave in path upon high loss.
- float inflight_hi_headroom =
- GetQuicFlag(FLAGS_quic_bbr2_default_inflight_hi_headroom);
-
- // Estimate startup/bw probing has gone too far if loss rate exceeds this.
- float loss_threshold = GetQuicFlag(FLAGS_quic_bbr2_default_loss_threshold);
-
- // A common factor for multiplicative decreases. Used for adjusting
- // bandwidth_lo, inflight_lo and inflight_hi upon losses.
- float beta = 0.3;
-
- Limits<QuicByteCount> cwnd_limits;
-
- /*
- * Experimental flags from QuicConfig.
- */
-
- // Can be disabled by connection option 'B2NA'.
- bool add_ack_height_to_queueing_threshold = true;
-
- // Can be disabled by connection option 'B2RP'.
- bool avoid_unnecessary_probe_rtt = true;
-
- // Can be enabled by connection option 'B2LO'.
- bool ignore_inflight_lo = false;
-
- // Can be enabled by connection option 'B2H2'.
- bool limit_inflight_hi_by_max_delivered = false;
-
- // Can be disabled by connection option 'B2SL'.
- bool startup_loss_exit_use_max_delivered_for_inflight_hi = true;
-
- // Can be enabled by connection option 'B2DL'.
- bool use_bytes_delivered_for_inflight_hi = false;
-
- // Can be disabled by connection option 'B2RC'.
- bool enable_reno_coexistence = true;
-
- // For experimentation to improve fast convergence upon loss.
- enum QuicBandwidthLoMode : uint8_t {
- DEFAULT = 0,
- MIN_RTT_REDUCTION = 1, // 'BBQ7'
- INFLIGHT_REDUCTION = 2, // 'BBQ8'
- CWND_REDUCTION = 3, // 'BBQ9'
- };
-
- // Different modes change bandwidth_lo_ differently upon loss.
- QuicBandwidthLoMode bw_lo_mode_ = QuicBandwidthLoMode::DEFAULT;
-
- // Set the pacing gain to 25% larger than the recent BW increase in STARTUP.
- bool decrease_startup_pacing_at_end_of_round = false;
-};
-
-class QUIC_EXPORT_PRIVATE RoundTripCounter {
- public:
- RoundTripCounter();
-
- QuicRoundTripCount Count() const { return round_trip_count_; }
-
- QuicPacketNumber last_sent_packet() const { return last_sent_packet_; }
-
- // Must be called in ascending packet number order.
- void OnPacketSent(QuicPacketNumber packet_number);
-
- // Return whether a round trip has just completed.
- bool OnPacketsAcked(QuicPacketNumber last_acked_packet);
-
- void RestartRound();
-
- private:
- QuicRoundTripCount round_trip_count_;
- QuicPacketNumber last_sent_packet_;
- // The last sent packet number of the current round trip.
- QuicPacketNumber end_of_round_trip_;
-};
-
-class QUIC_EXPORT_PRIVATE MinRttFilter {
- public:
- MinRttFilter(QuicTime::Delta initial_min_rtt,
- QuicTime initial_min_rtt_timestamp);
-
- void Update(QuicTime::Delta sample_rtt, QuicTime now);
-
- void ForceUpdate(QuicTime::Delta sample_rtt, QuicTime now);
-
- QuicTime::Delta Get() const { return min_rtt_; }
-
- QuicTime GetTimestamp() const { return min_rtt_timestamp_; }
-
- private:
- QuicTime::Delta min_rtt_;
- // Time when the current value of |min_rtt_| was assigned.
- QuicTime min_rtt_timestamp_;
-};
-
-class QUIC_EXPORT_PRIVATE Bbr2MaxBandwidthFilter {
- public:
- void Update(QuicBandwidth sample) {
- max_bandwidth_[1] = std::max(sample, max_bandwidth_[1]);
- }
-
- void Advance() {
- if (max_bandwidth_[1].IsZero()) {
- return;
- }
-
- max_bandwidth_[0] = max_bandwidth_[1];
- max_bandwidth_[1] = QuicBandwidth::Zero();
- }
-
- QuicBandwidth Get() const {
- return std::max(max_bandwidth_[0], max_bandwidth_[1]);
- }
-
- private:
- QuicBandwidth max_bandwidth_[2] = {QuicBandwidth::Zero(),
- QuicBandwidth::Zero()};
-};
-
-// Information that are meaningful only when Bbr2Sender::OnCongestionEvent is
-// running.
-struct QUIC_EXPORT_PRIVATE Bbr2CongestionEvent {
- QuicTime event_time = QuicTime::Zero();
-
- // The congestion window prior to the processing of the ack/loss events.
- QuicByteCount prior_cwnd;
-
- // Total bytes inflight before the processing of the ack/loss events.
- QuicByteCount prior_bytes_in_flight = 0;
-
- // Total bytes inflight after the processing of the ack/loss events.
- QuicByteCount bytes_in_flight = 0;
-
- // Total bytes acked from acks in this event.
- QuicByteCount bytes_acked = 0;
-
- // Total bytes lost from losses in this event.
- QuicByteCount bytes_lost = 0;
-
- // Whether acked_packets indicates the end of a round trip.
- bool end_of_round_trip = false;
-
- // When the event happened, whether the sender is probing for bandwidth.
- bool is_probing_for_bandwidth = false;
-
- // Minimum rtt of all bandwidth samples from acked_packets.
- // QuicTime::Delta::Infinite() if acked_packets is empty.
- QuicTime::Delta sample_min_rtt = QuicTime::Delta::Infinite();
-
- // Maximum bandwidth of all bandwidth samples from acked_packets.
- // This sample may be app-limited, and will be Zero() if there are no newly
- // acknowledged inflight packets.
- QuicBandwidth sample_max_bandwidth = QuicBandwidth::Zero();
-
- // The send state of the largest packet in acked_packets, unless it is empty.
- // If acked_packets is empty, it's the send state of the largest packet in
- // lost_packets.
- SendTimeState last_packet_send_state;
-};
-
-// Bbr2NetworkModel takes low level congestion signals(packets sent/acked/lost)
-// as input and produces BBRv2 model parameters like inflight_(hi|lo),
-// bandwidth_(hi|lo), bandwidth and rtt estimates, etc.
-class QUIC_EXPORT_PRIVATE Bbr2NetworkModel {
- public:
- Bbr2NetworkModel(const Bbr2Params* params,
- QuicTime::Delta initial_rtt,
- QuicTime initial_rtt_timestamp,
- float cwnd_gain,
- float pacing_gain,
- const BandwidthSampler* old_sampler);
-
- void OnPacketSent(QuicTime sent_time,
- QuicByteCount bytes_in_flight,
- QuicPacketNumber packet_number,
- QuicByteCount bytes,
- HasRetransmittableData is_retransmittable);
-
- void OnCongestionEventStart(QuicTime event_time,
- const AckedPacketVector& acked_packets,
- const LostPacketVector& lost_packets,
- Bbr2CongestionEvent* congestion_event);
-
- void OnCongestionEventFinish(QuicPacketNumber least_unacked_packet,
- const Bbr2CongestionEvent& congestion_event);
-
- // Update the model without a congestion event.
- // Min rtt is updated if |rtt| is non-zero and smaller than existing min rtt.
- void UpdateNetworkParameters(QuicTime::Delta rtt);
-
- // Update inflight/bandwidth short-term lower bounds.
- void AdaptLowerBounds(const Bbr2CongestionEvent& congestion_event);
-
- // Restart the current round trip as if it is starting now.
- void RestartRoundEarly();
-
- void AdvanceMaxBandwidthFilter() { max_bandwidth_filter_.Advance(); }
-
- void OnApplicationLimited() { bandwidth_sampler_.OnAppLimited(); }
-
- // Calculates BDP using the current MaxBandwidth.
- QuicByteCount BDP() const { return BDP(MaxBandwidth()); }
-
- QuicByteCount BDP(QuicBandwidth bandwidth) const {
- return bandwidth * MinRtt();
- }
-
- QuicByteCount BDP(QuicBandwidth bandwidth, float gain) const {
- return bandwidth * MinRtt() * gain;
- }
-
- QuicTime::Delta MinRtt() const { return min_rtt_filter_.Get(); }
-
- QuicTime MinRttTimestamp() const { return min_rtt_filter_.GetTimestamp(); }
-
- // TODO(wub): If we do this too frequently, we can potentailly postpone
- // PROBE_RTT indefinitely. Observe how it works in production and improve it.
- void PostponeMinRttTimestamp(QuicTime::Delta duration) {
- min_rtt_filter_.ForceUpdate(MinRtt(), MinRttTimestamp() + duration);
- }
-
- QuicBandwidth MaxBandwidth() const { return max_bandwidth_filter_.Get(); }
-
- QuicByteCount MaxAckHeight() const {
- return bandwidth_sampler_.max_ack_height();
- }
-
- // 2 packets. Used to indicate the typical number of bytes ACKed at once.
- QuicByteCount QueueingThresholdExtraBytes() const {
- return 2 * kDefaultTCPMSS;
- }
-
- bool cwnd_limited_before_aggregation_epoch() const {
- return cwnd_limited_before_aggregation_epoch_;
- }
-
- void EnableOverestimateAvoidance() {
- bandwidth_sampler_.EnableOverestimateAvoidance();
- }
-
- bool IsBandwidthOverestimateAvoidanceEnabled() const {
- return bandwidth_sampler_.IsOverestimateAvoidanceEnabled();
- }
-
- void OnPacketNeutered(QuicPacketNumber packet_number) {
- bandwidth_sampler_.OnPacketNeutered(packet_number);
- }
-
- uint64_t num_ack_aggregation_epochs() const {
- return bandwidth_sampler_.num_ack_aggregation_epochs();
- }
-
- void SetStartNewAggregationEpochAfterFullRound(bool value) {
- bandwidth_sampler_.SetStartNewAggregationEpochAfterFullRound(value);
- }
-
- void SetLimitMaxAckHeightTrackerBySendRate(bool value) {
- bandwidth_sampler_.SetLimitMaxAckHeightTrackerBySendRate(value);
- }
-
- void SetMaxAckHeightTrackerWindowLength(QuicRoundTripCount value) {
- bandwidth_sampler_.SetMaxAckHeightTrackerWindowLength(value);
- }
-
- void SetReduceExtraAckedOnBandwidthIncrease(bool value) {
- bandwidth_sampler_.SetReduceExtraAckedOnBandwidthIncrease(value);
- }
-
- bool MaybeExpireMinRtt(const Bbr2CongestionEvent& congestion_event);
-
- QuicBandwidth BandwidthEstimate() const {
- return std::min(MaxBandwidth(), bandwidth_lo_);
- }
-
- QuicRoundTripCount RoundTripCount() const {
- return round_trip_counter_.Count();
- }
-
- // Return true if the number of loss events exceeds max_loss_events and
- // fraction of bytes lost exceed the loss threshold.
- bool IsInflightTooHigh(const Bbr2CongestionEvent& congestion_event,
- int64_t max_loss_events) const;
-
- // Check bandwidth growth in the past round. Must be called at the end of a
- // round. Returns true if there was sufficient bandwidth growth and false
- // otherwise. If it's been too many rounds without growth, also sets
- // |full_bandwidth_reached_| to true.
- bool HasBandwidthGrowth(const Bbr2CongestionEvent& congestion_event);
-
- // Returns true if the minimum bytes in flight during the round is greater
- // than the BDP * |bdp_gain|.
- bool CheckPersistentQueue(const Bbr2CongestionEvent& congestion_event,
- float bdp_gain);
-
- QuicPacketNumber last_sent_packet() const {
- return round_trip_counter_.last_sent_packet();
- }
-
- QuicByteCount total_bytes_acked() const {
- return bandwidth_sampler_.total_bytes_acked();
- }
-
- QuicByteCount total_bytes_lost() const {
- return bandwidth_sampler_.total_bytes_lost();
- }
-
- QuicByteCount total_bytes_sent() const {
- return bandwidth_sampler_.total_bytes_sent();
- }
-
- int64_t loss_events_in_round() const { return loss_events_in_round_; }
-
- QuicByteCount max_bytes_delivered_in_round() const {
- return max_bytes_delivered_in_round_;
- }
-
- QuicByteCount min_bytes_in_flight_in_round() const {
- return min_bytes_in_flight_in_round_;
- }
-
- QuicPacketNumber end_of_app_limited_phase() const {
- return bandwidth_sampler_.end_of_app_limited_phase();
- }
-
- QuicBandwidth bandwidth_latest() const { return bandwidth_latest_; }
- QuicBandwidth bandwidth_lo() const { return bandwidth_lo_; }
- static QuicBandwidth bandwidth_lo_default() {
- return QuicBandwidth::Infinite();
- }
- void clear_bandwidth_lo() { bandwidth_lo_ = bandwidth_lo_default(); }
-
- QuicByteCount inflight_latest() const { return inflight_latest_; }
- QuicByteCount inflight_lo() const { return inflight_lo_; }
- static QuicByteCount inflight_lo_default() {
- return std::numeric_limits<QuicByteCount>::max();
- }
- void clear_inflight_lo() { inflight_lo_ = inflight_lo_default(); }
- void cap_inflight_lo(QuicByteCount cap);
-
- QuicByteCount inflight_hi_with_headroom() const;
- QuicByteCount inflight_hi() const { return inflight_hi_; }
- static QuicByteCount inflight_hi_default() {
- return std::numeric_limits<QuicByteCount>::max();
- }
- void set_inflight_hi(QuicByteCount inflight_hi) {
- inflight_hi_ = inflight_hi;
- }
-
- float cwnd_gain() const { return cwnd_gain_; }
- void set_cwnd_gain(float cwnd_gain) { cwnd_gain_ = cwnd_gain; }
-
- float pacing_gain() const { return pacing_gain_; }
- void set_pacing_gain(float pacing_gain) { pacing_gain_ = pacing_gain; }
-
- bool full_bandwidth_reached() const { return full_bandwidth_reached_; }
- void set_full_bandwidth_reached() { full_bandwidth_reached_ = true; }
- QuicBandwidth full_bandwidth_baseline() const {
- return full_bandwidth_baseline_;
- }
- QuicRoundTripCount rounds_without_bandwidth_growth() const {
- return rounds_without_bandwidth_growth_;
- }
-
- private:
- // Called when a new round trip starts.
- void OnNewRound();
-
- const Bbr2Params& Params() const { return *params_; }
- const Bbr2Params* const params_;
- RoundTripCounter round_trip_counter_;
-
- // Bandwidth sampler provides BBR with the bandwidth measurements at
- // individual points.
- BandwidthSampler bandwidth_sampler_;
- // The filter that tracks the maximum bandwidth over multiple recent round
- // trips.
- Bbr2MaxBandwidthFilter max_bandwidth_filter_;
- MinRttFilter min_rtt_filter_;
-
- // Bytes lost in the current round. Updated once per congestion event.
- QuicByteCount bytes_lost_in_round_ = 0;
- // Number of loss marking events in the current round.
- int64_t loss_events_in_round_ = 0;
-
- // A max of bytes delivered among all congestion events in the current round.
- // A congestions event's bytes delivered is the total bytes acked between time
- // Ts and Ta, which is the time when the largest acked packet(within the
- // congestion event) was sent and acked, respectively.
- QuicByteCount max_bytes_delivered_in_round_ = 0;
-
- // The minimum bytes in flight during this round.
- QuicByteCount min_bytes_in_flight_in_round_ = 0;
-
- // Max bandwidth in the current round. Updated once per congestion event.
- QuicBandwidth bandwidth_latest_ = QuicBandwidth::Zero();
- // Max bandwidth of recent rounds. Updated once per round.
- QuicBandwidth bandwidth_lo_ = bandwidth_lo_default();
- // bandwidth_lo_ at the beginning of a round with loss. Only used when the
- // bw_lo_mode is non-default.
- QuicBandwidth prior_bandwidth_lo_ = QuicBandwidth::Zero();
-
- // Max inflight in the current round. Updated once per congestion event.
- QuicByteCount inflight_latest_ = 0;
- // Max inflight of recent rounds. Updated once per round.
- QuicByteCount inflight_lo_ = inflight_lo_default();
- QuicByteCount inflight_hi_ = inflight_hi_default();
-
- float cwnd_gain_;
- float pacing_gain_;
-
- // Whether we are cwnd limited prior to the start of the current aggregation
- // epoch.
- bool cwnd_limited_before_aggregation_epoch_ = false;
-
- // STARTUP-centric fields which experimentally used by PROBE_UP.
- bool full_bandwidth_reached_ = false;
- QuicBandwidth full_bandwidth_baseline_ = QuicBandwidth::Zero();
- QuicRoundTripCount rounds_without_bandwidth_growth_ = 0;
-};
-
-enum class Bbr2Mode : uint8_t {
- // Startup phase of the connection.
- STARTUP,
- // After achieving the highest possible bandwidth during the startup, lower
- // the pacing rate in order to drain the queue.
- DRAIN,
- // Cruising mode.
- PROBE_BW,
- // Temporarily slow down sending in order to empty the buffer and measure
- // the real minimum RTT.
- PROBE_RTT,
-};
-
-QUIC_EXPORT_PRIVATE inline std::ostream& operator<<(std::ostream& os,
- const Bbr2Mode& mode) {
- switch (mode) {
- case Bbr2Mode::STARTUP:
- return os << "STARTUP";
- case Bbr2Mode::DRAIN:
- return os << "DRAIN";
- case Bbr2Mode::PROBE_BW:
- return os << "PROBE_BW";
- case Bbr2Mode::PROBE_RTT:
- return os << "PROBE_RTT";
- }
- return os << "<Invalid Mode>";
-}
-
-// The base class for all BBRv2 modes. A Bbr2Sender is in one mode at a time,
-// this interface is used to implement mode-specific behaviors.
-class Bbr2Sender;
-class QUIC_EXPORT_PRIVATE Bbr2ModeBase {
- public:
- Bbr2ModeBase(const Bbr2Sender* sender, Bbr2NetworkModel* model)
- : sender_(sender), model_(model) {}
-
- virtual ~Bbr2ModeBase() = default;
-
- // Called when entering/leaving this mode.
- // congestion_event != nullptr means BBRv2 is switching modes in the context
- // of a ack and/or loss.
- virtual void Enter(QuicTime now,
- const Bbr2CongestionEvent* congestion_event) = 0;
- virtual void Leave(QuicTime now,
- const Bbr2CongestionEvent* congestion_event) = 0;
-
- virtual Bbr2Mode OnCongestionEvent(
- QuicByteCount prior_in_flight,
- QuicTime event_time,
- const AckedPacketVector& acked_packets,
- const LostPacketVector& lost_packets,
- const Bbr2CongestionEvent& congestion_event) = 0;
-
- virtual Limits<QuicByteCount> GetCwndLimits() const = 0;
-
- virtual bool IsProbingForBandwidth() const = 0;
-
- virtual Bbr2Mode OnExitQuiescence(QuicTime now,
- QuicTime quiescence_start_time) = 0;
-
- protected:
- const Bbr2Sender* const sender_;
- Bbr2NetworkModel* model_;
-};
-
-QUIC_EXPORT_PRIVATE inline QuicByteCount BytesInFlight(
- const SendTimeState& send_state) {
- QUICHE_DCHECK(send_state.is_valid);
- if (send_state.bytes_in_flight != 0) {
- return send_state.bytes_in_flight;
- }
- return send_state.total_bytes_sent - send_state.total_bytes_acked -
- send_state.total_bytes_lost;
-}
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_CONGESTION_CONTROL_BBR2_MISC_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/congestion_control/bbr2_probe_bw.cc b/chromium/net/third_party/quiche/src/quic/core/congestion_control/bbr2_probe_bw.cc
deleted file mode 100644
index 0f65eca7165..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/congestion_control/bbr2_probe_bw.cc
+++ /dev/null
@@ -1,677 +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 "quic/core/congestion_control/bbr2_probe_bw.h"
-
-#include "quic/core/congestion_control/bbr2_misc.h"
-#include "quic/core/congestion_control/bbr2_sender.h"
-#include "quic/core/quic_bandwidth.h"
-#include "quic/core/quic_time.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_flag_utils.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-void Bbr2ProbeBwMode::Enter(QuicTime now,
- const Bbr2CongestionEvent* /*congestion_event*/) {
- if (cycle_.phase == CyclePhase::PROBE_NOT_STARTED) {
- // First time entering PROBE_BW. Start a new probing cycle.
- EnterProbeDown(/*probed_too_high=*/false, /*stopped_risky_probe=*/false,
- now);
- } else {
- // Transitioning from PROBE_RTT to PROBE_BW. Re-enter the last phase before
- // PROBE_RTT.
- QUICHE_DCHECK(cycle_.phase == CyclePhase::PROBE_CRUISE ||
- cycle_.phase == CyclePhase::PROBE_REFILL);
- cycle_.cycle_start_time = now;
- if (cycle_.phase == CyclePhase::PROBE_CRUISE) {
- EnterProbeCruise(now);
- } else if (cycle_.phase == CyclePhase::PROBE_REFILL) {
- EnterProbeRefill(cycle_.probe_up_rounds, now);
- }
- }
-}
-
-Bbr2Mode Bbr2ProbeBwMode::OnCongestionEvent(
- QuicByteCount prior_in_flight, QuicTime event_time,
- const AckedPacketVector& /*acked_packets*/,
- const LostPacketVector& /*lost_packets*/,
- const Bbr2CongestionEvent& congestion_event) {
- QUICHE_DCHECK_NE(cycle_.phase, CyclePhase::PROBE_NOT_STARTED);
-
- if (congestion_event.end_of_round_trip) {
- if (cycle_.cycle_start_time != event_time) {
- ++cycle_.rounds_since_probe;
- }
- if (cycle_.phase_start_time != event_time) {
- ++cycle_.rounds_in_phase;
- }
- }
-
- bool switch_to_probe_rtt = false;
-
- if (cycle_.phase == CyclePhase::PROBE_UP) {
- UpdateProbeUp(prior_in_flight, congestion_event);
- } else if (cycle_.phase == CyclePhase::PROBE_DOWN) {
- UpdateProbeDown(prior_in_flight, congestion_event);
- // Maybe transition to PROBE_RTT at the end of this cycle.
- if (cycle_.phase != CyclePhase::PROBE_DOWN &&
- model_->MaybeExpireMinRtt(congestion_event)) {
- switch_to_probe_rtt = true;
- }
- } else if (cycle_.phase == CyclePhase::PROBE_CRUISE) {
- UpdateProbeCruise(congestion_event);
- } else if (cycle_.phase == CyclePhase::PROBE_REFILL) {
- UpdateProbeRefill(congestion_event);
- }
-
- // Do not need to set the gains if switching to PROBE_RTT, they will be set
- // when Bbr2ProbeRttMode::Enter is called.
- if (!switch_to_probe_rtt) {
- model_->set_pacing_gain(PacingGainForPhase(cycle_.phase));
- model_->set_cwnd_gain(Params().probe_bw_cwnd_gain);
- }
-
- return switch_to_probe_rtt ? Bbr2Mode::PROBE_RTT : Bbr2Mode::PROBE_BW;
-}
-
-Limits<QuicByteCount> Bbr2ProbeBwMode::GetCwndLimits() const {
- if (cycle_.phase == CyclePhase::PROBE_CRUISE) {
- return NoGreaterThan(
- std::min(model_->inflight_lo(), model_->inflight_hi_with_headroom()));
- }
- if (Params().probe_up_ignore_inflight_hi &&
- cycle_.phase == CyclePhase::PROBE_UP) {
- // Similar to STARTUP.
- return NoGreaterThan(model_->inflight_lo());
- }
-
- return NoGreaterThan(std::min(model_->inflight_lo(), model_->inflight_hi()));
-}
-
-bool Bbr2ProbeBwMode::IsProbingForBandwidth() const {
- return cycle_.phase == CyclePhase::PROBE_REFILL ||
- cycle_.phase == CyclePhase::PROBE_UP;
-}
-
-Bbr2Mode Bbr2ProbeBwMode::OnExitQuiescence(QuicTime now,
- QuicTime quiescence_start_time) {
- QUIC_DVLOG(3) << sender_ << " Postponing min_rtt_timestamp("
- << model_->MinRttTimestamp() << ") by "
- << now - quiescence_start_time;
- model_->PostponeMinRttTimestamp(now - quiescence_start_time);
- return Bbr2Mode::PROBE_BW;
-}
-
-// TODO(ianswett): Remove prior_in_flight from UpdateProbeDown.
-void Bbr2ProbeBwMode::UpdateProbeDown(
- QuicByteCount prior_in_flight,
- const Bbr2CongestionEvent& congestion_event) {
- QUICHE_DCHECK_EQ(cycle_.phase, CyclePhase::PROBE_DOWN);
-
- if (cycle_.rounds_in_phase == 1 && congestion_event.end_of_round_trip) {
- cycle_.is_sample_from_probing = false;
-
- if (!congestion_event.last_packet_send_state.is_app_limited) {
- QUIC_DVLOG(2)
- << sender_
- << " Advancing max bw filter after one round in PROBE_DOWN.";
- model_->AdvanceMaxBandwidthFilter();
- cycle_.has_advanced_max_bw = true;
- }
-
- if (last_cycle_stopped_risky_probe_ && !last_cycle_probed_too_high_) {
- EnterProbeRefill(/*probe_up_rounds=*/0, congestion_event.event_time);
- return;
- }
- }
-
- MaybeAdaptUpperBounds(congestion_event);
-
- if (IsTimeToProbeBandwidth(congestion_event)) {
- EnterProbeRefill(/*probe_up_rounds=*/0, congestion_event.event_time);
- return;
- }
-
- if (HasStayedLongEnoughInProbeDown(congestion_event)) {
- QUIC_DVLOG(3) << sender_ << " Proportional time based PROBE_DOWN exit";
- EnterProbeCruise(congestion_event.event_time);
- return;
- }
-
- const QuicByteCount inflight_with_headroom =
- model_->inflight_hi_with_headroom();
- QUIC_DVLOG(3)
- << sender_
- << " Checking if have enough inflight headroom. prior_in_flight:"
- << prior_in_flight << " congestion_event.bytes_in_flight:"
- << congestion_event.bytes_in_flight
- << ", inflight_with_headroom:" << inflight_with_headroom;
- QuicByteCount bytes_in_flight = congestion_event.bytes_in_flight;
-
- if (bytes_in_flight > inflight_with_headroom) {
- // Stay in PROBE_DOWN.
- return;
- }
-
- // Transition to PROBE_CRUISE iff we've drained to target.
- QuicByteCount bdp = model_->BDP();
- QUIC_DVLOG(3) << sender_ << " Checking if drained to target. bytes_in_flight:"
- << bytes_in_flight << ", bdp:" << bdp;
- if (bytes_in_flight < bdp) {
- EnterProbeCruise(congestion_event.event_time);
- }
-}
-
-Bbr2ProbeBwMode::AdaptUpperBoundsResult Bbr2ProbeBwMode::MaybeAdaptUpperBounds(
- const Bbr2CongestionEvent& congestion_event) {
- const SendTimeState& send_state = congestion_event.last_packet_send_state;
- if (!send_state.is_valid) {
- QUIC_DVLOG(3) << sender_ << " " << cycle_.phase
- << ": NOT_ADAPTED_INVALID_SAMPLE";
- return NOT_ADAPTED_INVALID_SAMPLE;
- }
-
- // TODO(ianswett): Rename to bytes_delivered if
- // use_bytes_delivered_for_inflight_hi is default enabled.
- QuicByteCount inflight_at_send = BytesInFlight(send_state);
- if (Params().use_bytes_delivered_for_inflight_hi) {
- if (congestion_event.last_packet_send_state.total_bytes_acked <=
- model_->total_bytes_acked()) {
- inflight_at_send =
- model_->total_bytes_acked() -
- congestion_event.last_packet_send_state.total_bytes_acked;
- } else {
- QUIC_BUG(quic_bug_10436_1)
- << "Total_bytes_acked(" << model_->total_bytes_acked()
- << ") < send_state.total_bytes_acked("
- << congestion_event.last_packet_send_state.total_bytes_acked << ")";
- }
- }
- // TODO(ianswett): Inflight too high is really checking for loss, not
- // inflight.
- if (model_->IsInflightTooHigh(congestion_event,
- Params().probe_bw_full_loss_count)) {
- if (cycle_.is_sample_from_probing) {
- cycle_.is_sample_from_probing = false;
- if (!send_state.is_app_limited ||
- Params().probe_up_dont_exit_if_no_queue_) {
- if (send_state.is_app_limited) {
- // If there's excess loss or a queue is building, exit even if the
- // last sample was app limited.
- QUIC_RELOADABLE_FLAG_COUNT_N(quic_bbr2_no_probe_up_exit_if_no_queue,
- 2, 2);
- }
- const QuicByteCount inflight_target =
- sender_->GetTargetBytesInflight() * (1.0 - Params().beta);
- if (inflight_at_send >= inflight_target) {
- // The new code does not change behavior.
- QUIC_CODE_COUNT(quic_bbr2_cut_inflight_hi_gradually_noop);
- } else {
- // The new code actually cuts inflight_hi slower than before.
- QUIC_CODE_COUNT(quic_bbr2_cut_inflight_hi_gradually_in_effect);
- }
- if (Params().limit_inflight_hi_by_max_delivered) {
- QuicByteCount new_inflight_hi =
- std::max(inflight_at_send, inflight_target);
- if (new_inflight_hi >= model_->max_bytes_delivered_in_round()) {
- QUIC_CODE_COUNT(quic_bbr2_cut_inflight_hi_max_delivered_noop);
- } else {
- QUIC_CODE_COUNT(quic_bbr2_cut_inflight_hi_max_delivered_in_effect);
- new_inflight_hi = model_->max_bytes_delivered_in_round();
- }
- QUIC_DVLOG(3) << sender_
- << " Setting inflight_hi due to loss. new_inflight_hi:"
- << new_inflight_hi
- << ", inflight_at_send:" << inflight_at_send
- << ", inflight_target:" << inflight_target
- << ", max_bytes_delivered_in_round:"
- << model_->max_bytes_delivered_in_round() << " @ "
- << congestion_event.event_time;
- model_->set_inflight_hi(new_inflight_hi);
- } else {
- model_->set_inflight_hi(std::max(inflight_at_send, inflight_target));
- }
- }
-
- QUIC_DVLOG(3) << sender_ << " " << cycle_.phase
- << ": ADAPTED_PROBED_TOO_HIGH";
- return ADAPTED_PROBED_TOO_HIGH;
- }
- return ADAPTED_OK;
- }
-
- if (model_->inflight_hi() == model_->inflight_hi_default()) {
- QUIC_DVLOG(3) << sender_ << " " << cycle_.phase
- << ": NOT_ADAPTED_INFLIGHT_HIGH_NOT_SET";
- return NOT_ADAPTED_INFLIGHT_HIGH_NOT_SET;
- }
-
- // Raise the upper bound for inflight.
- if (inflight_at_send > model_->inflight_hi()) {
- QUIC_DVLOG(3)
- << sender_ << " " << cycle_.phase
- << ": Adapting inflight_hi from inflight_at_send. inflight_at_send:"
- << inflight_at_send << ", old inflight_hi:" << model_->inflight_hi();
- model_->set_inflight_hi(inflight_at_send);
- }
-
- return ADAPTED_OK;
-}
-
-bool Bbr2ProbeBwMode::IsTimeToProbeBandwidth(
- const Bbr2CongestionEvent& congestion_event) const {
- if (HasCycleLasted(cycle_.probe_wait_time, congestion_event)) {
- return true;
- }
-
- if (IsTimeToProbeForRenoCoexistence(1.0, congestion_event)) {
- ++sender_->connection_stats_->bbr_num_short_cycles_for_reno_coexistence;
- return true;
- }
- return false;
-}
-
-// QUIC only. Used to prevent a Bbr2 flow from staying in PROBE_DOWN for too
-// long, as seen in some multi-sender simulator tests.
-bool Bbr2ProbeBwMode::HasStayedLongEnoughInProbeDown(
- const Bbr2CongestionEvent& congestion_event) const {
- // Stay in PROBE_DOWN for at most the time of a min rtt, as it is done in
- // BBRv1.
- // TODO(wub): Consider exit after a full round instead, which typically
- // indicates most(if not all) packets sent during PROBE_UP have been acked.
- return HasPhaseLasted(model_->MinRtt(), congestion_event);
-}
-
-bool Bbr2ProbeBwMode::HasCycleLasted(
- QuicTime::Delta duration,
- const Bbr2CongestionEvent& congestion_event) const {
- bool result =
- (congestion_event.event_time - cycle_.cycle_start_time) > duration;
- QUIC_DVLOG(3) << sender_ << " " << cycle_.phase
- << ": HasCycleLasted=" << result << ". elapsed:"
- << (congestion_event.event_time - cycle_.cycle_start_time)
- << ", duration:" << duration;
- return result;
-}
-
-bool Bbr2ProbeBwMode::HasPhaseLasted(
- QuicTime::Delta duration,
- const Bbr2CongestionEvent& congestion_event) const {
- bool result =
- (congestion_event.event_time - cycle_.phase_start_time) > duration;
- QUIC_DVLOG(3) << sender_ << " " << cycle_.phase
- << ": HasPhaseLasted=" << result << ". elapsed:"
- << (congestion_event.event_time - cycle_.phase_start_time)
- << ", duration:" << duration;
- return result;
-}
-
-bool Bbr2ProbeBwMode::IsTimeToProbeForRenoCoexistence(
- double probe_wait_fraction,
- const Bbr2CongestionEvent& /*congestion_event*/) const {
- if (!Params().enable_reno_coexistence) {
- return false;
- }
-
- uint64_t rounds = Params().probe_bw_probe_max_rounds;
- if (Params().probe_bw_probe_reno_gain > 0.0) {
- QuicByteCount target_bytes_inflight = sender_->GetTargetBytesInflight();
- uint64_t reno_rounds = Params().probe_bw_probe_reno_gain *
- target_bytes_inflight / kDefaultTCPMSS;
- rounds = std::min(rounds, reno_rounds);
- }
- bool result = cycle_.rounds_since_probe >= (rounds * probe_wait_fraction);
- QUIC_DVLOG(3) << sender_ << " " << cycle_.phase
- << ": IsTimeToProbeForRenoCoexistence=" << result
- << ". rounds_since_probe:" << cycle_.rounds_since_probe
- << ", rounds:" << rounds
- << ", probe_wait_fraction:" << probe_wait_fraction;
- return result;
-}
-
-void Bbr2ProbeBwMode::RaiseInflightHighSlope() {
- QUICHE_DCHECK_EQ(cycle_.phase, CyclePhase::PROBE_UP);
- uint64_t growth_this_round = 1 << cycle_.probe_up_rounds;
- // The number 30 below means |growth_this_round| is capped at 1G and the lower
- // bound of |probe_up_bytes| is (practically) 1 mss, at this speed inflight_hi
- // grows by approximately 1 packet per packet acked.
- cycle_.probe_up_rounds = std::min<uint64_t>(cycle_.probe_up_rounds + 1, 30);
- uint64_t probe_up_bytes = sender_->GetCongestionWindow() / growth_this_round;
- cycle_.probe_up_bytes =
- std::max<QuicByteCount>(probe_up_bytes, kDefaultTCPMSS);
- QUIC_DVLOG(3) << sender_ << " Rasing inflight_hi slope. probe_up_rounds:"
- << cycle_.probe_up_rounds
- << ", probe_up_bytes:" << cycle_.probe_up_bytes;
-}
-
-void Bbr2ProbeBwMode::ProbeInflightHighUpward(
- const Bbr2CongestionEvent& congestion_event) {
- QUICHE_DCHECK_EQ(cycle_.phase, CyclePhase::PROBE_UP);
- if (Params().probe_up_ignore_inflight_hi) {
- // When inflight_hi is disabled in PROBE_UP, it increases when
- // the number of bytes delivered in a round is larger inflight_hi.
- return;
- }
- if (Params().probe_bw_check_cwnd_limited_before_aggregation_epoch) {
- if (!model_->cwnd_limited_before_aggregation_epoch()) {
- QUIC_DVLOG(3) << sender_
- << " Raising inflight_hi early return: Not cwnd limited "
- "before aggregation epoch.";
- // Not fully utilizing cwnd, so can't safely grow.
- return;
- }
- } else if (Params().probe_up_includes_acks_after_cwnd_limited) {
- QUIC_RELOADABLE_FLAG_COUNT(
- quic_bbr2_add_bytes_acked_after_inflight_hi_limited);
- // Don't continue adding bytes to probe_up_acked if the sender was not
- // app-limited after being inflight_hi limited at least once.
- if (!cycle_.probe_up_app_limited_since_inflight_hi_limited_ ||
- congestion_event.last_packet_send_state.is_app_limited) {
- cycle_.probe_up_app_limited_since_inflight_hi_limited_ = false;
- if (congestion_event.prior_bytes_in_flight <
- congestion_event.prior_cwnd) {
- QUIC_DVLOG(3) << sender_
- << " Raising inflight_hi early return: Not cwnd limited.";
- // Not fully utilizing cwnd, so can't safely grow.
- return;
- }
-
- if (congestion_event.prior_cwnd < model_->inflight_hi()) {
- QUIC_DVLOG(3)
- << sender_
- << " Raising inflight_hi early return: inflight_hi not fully used.";
- // Not fully using inflight_hi, so don't grow it.
- return;
- }
- }
- // Start a new period of adding bytes_acked, because inflight_hi limited.
- cycle_.probe_up_app_limited_since_inflight_hi_limited_ = true;
- } else {
- if (congestion_event.prior_bytes_in_flight < congestion_event.prior_cwnd) {
- QUIC_DVLOG(3) << sender_
- << " Raising inflight_hi early return: Not cwnd limited.";
- // Not fully utilizing cwnd, so can't safely grow.
- return;
- }
- }
-
- if (congestion_event.prior_cwnd < model_->inflight_hi()) {
- QUIC_DVLOG(3)
- << sender_
- << " Raising inflight_hi early return: inflight_hi not fully used.";
- // Not fully using inflight_hi, so don't grow it.
- return;
- }
-
- // Increase inflight_hi by the number of probe_up_bytes within probe_up_acked.
- cycle_.probe_up_acked += congestion_event.bytes_acked;
- if (cycle_.probe_up_acked >= cycle_.probe_up_bytes) {
- uint64_t delta = cycle_.probe_up_acked / cycle_.probe_up_bytes;
- cycle_.probe_up_acked -= delta * cycle_.probe_up_bytes;
- QuicByteCount new_inflight_hi =
- model_->inflight_hi() + delta * kDefaultTCPMSS;
- if (new_inflight_hi > model_->inflight_hi()) {
- QUIC_DVLOG(3) << sender_ << " Raising inflight_hi from "
- << model_->inflight_hi() << " to " << new_inflight_hi
- << ". probe_up_bytes:" << cycle_.probe_up_bytes
- << ", delta:" << delta
- << ", (new)probe_up_acked:" << cycle_.probe_up_acked;
-
- model_->set_inflight_hi(new_inflight_hi);
- } else {
- QUIC_BUG(quic_bug_10436_2)
- << "Not growing inflight_hi due to wrap around. Old value:"
- << model_->inflight_hi() << ", new value:" << new_inflight_hi;
- }
- }
-
- if (congestion_event.end_of_round_trip) {
- RaiseInflightHighSlope();
- }
-}
-
-void Bbr2ProbeBwMode::UpdateProbeCruise(
- const Bbr2CongestionEvent& congestion_event) {
- QUICHE_DCHECK_EQ(cycle_.phase, CyclePhase::PROBE_CRUISE);
- MaybeAdaptUpperBounds(congestion_event);
- QUICHE_DCHECK(!cycle_.is_sample_from_probing);
-
- if (IsTimeToProbeBandwidth(congestion_event)) {
- EnterProbeRefill(/*probe_up_rounds=*/0, congestion_event.event_time);
- return;
- }
-}
-
-void Bbr2ProbeBwMode::UpdateProbeRefill(
- const Bbr2CongestionEvent& congestion_event) {
- QUICHE_DCHECK_EQ(cycle_.phase, CyclePhase::PROBE_REFILL);
- MaybeAdaptUpperBounds(congestion_event);
- QUICHE_DCHECK(!cycle_.is_sample_from_probing);
-
- if (cycle_.rounds_in_phase > 0 && congestion_event.end_of_round_trip) {
- EnterProbeUp(congestion_event.event_time);
- return;
- }
-}
-
-void Bbr2ProbeBwMode::UpdateProbeUp(
- QuicByteCount prior_in_flight,
- const Bbr2CongestionEvent& congestion_event) {
- QUICHE_DCHECK_EQ(cycle_.phase, CyclePhase::PROBE_UP);
- if (MaybeAdaptUpperBounds(congestion_event) == ADAPTED_PROBED_TOO_HIGH) {
- EnterProbeDown(/*probed_too_high=*/true, /*stopped_risky_probe=*/false,
- congestion_event.event_time);
- return;
- }
-
- // TODO(wub): Consider exit PROBE_UP after a certain number(e.g. 64) of RTTs.
-
- ProbeInflightHighUpward(congestion_event);
-
- bool is_risky = false;
- bool is_queuing = false;
- if (last_cycle_probed_too_high_ && prior_in_flight >= model_->inflight_hi()) {
- is_risky = true;
- QUIC_DVLOG(3) << sender_
- << " Probe is too risky. last_cycle_probed_too_high_:"
- << last_cycle_probed_too_high_
- << ", prior_in_flight:" << prior_in_flight
- << ", inflight_hi:" << model_->inflight_hi();
- // TCP uses min_rtt instead of a full round:
- // HasPhaseLasted(model_->MinRtt(), congestion_event)
- } else if (cycle_.rounds_in_phase > 0) {
- if (Params().probe_up_dont_exit_if_no_queue_) {
- QUIC_RELOADABLE_FLAG_COUNT_N(quic_bbr2_no_probe_up_exit_if_no_queue, 1,
- 2);
- is_queuing = congestion_event.end_of_round_trip &&
- model_->CheckPersistentQueue(
- congestion_event, Params().probe_bw_probe_inflight_gain);
- } else {
- QuicByteCount queuing_threshold_extra_bytes =
- model_->QueueingThresholdExtraBytes();
- if (Params().add_ack_height_to_queueing_threshold) {
- queuing_threshold_extra_bytes += model_->MaxAckHeight();
- }
- QuicByteCount queuing_threshold =
- (Params().probe_bw_probe_inflight_gain * model_->BDP()) +
- queuing_threshold_extra_bytes;
-
- is_queuing = congestion_event.bytes_in_flight >= queuing_threshold;
-
- QUIC_DVLOG(3) << sender_
- << " Checking if building up a queue. prior_in_flight:"
- << prior_in_flight
- << ", post_in_flight:" << congestion_event.bytes_in_flight
- << ", threshold:" << queuing_threshold
- << ", is_queuing:" << is_queuing
- << ", max_bw:" << model_->MaxBandwidth()
- << ", min_rtt:" << model_->MinRtt();
- }
- }
-
- if (is_risky || is_queuing) {
- EnterProbeDown(/*probed_too_high=*/false, /*stopped_risky_probe=*/is_risky,
- congestion_event.event_time);
- }
-}
-
-void Bbr2ProbeBwMode::EnterProbeDown(bool probed_too_high,
- bool stopped_risky_probe, QuicTime now) {
- QUIC_DVLOG(2) << sender_ << " Phase change: " << cycle_.phase << " ==> "
- << CyclePhase::PROBE_DOWN << " after "
- << now - cycle_.phase_start_time << ", or "
- << cycle_.rounds_in_phase
- << " rounds. probed_too_high:" << probed_too_high
- << ", stopped_risky_probe:" << stopped_risky_probe << " @ "
- << now;
- last_cycle_probed_too_high_ = probed_too_high;
- last_cycle_stopped_risky_probe_ = stopped_risky_probe;
-
- cycle_.cycle_start_time = now;
- cycle_.phase = CyclePhase::PROBE_DOWN;
- cycle_.rounds_in_phase = 0;
- cycle_.phase_start_time = now;
- ++sender_->connection_stats_->bbr_num_cycles;
- if (Params().bw_lo_mode_ != Bbr2Params::QuicBandwidthLoMode::DEFAULT) {
- // Clear bandwidth lo if it was set in PROBE_UP, because losses in PROBE_UP
- // should not permanently change bandwidth_lo.
- // It's possible for bandwidth_lo to be set during REFILL, but if that was
- // a valid value, it'll quickly be rediscovered.
- model_->clear_bandwidth_lo();
- }
-
- // Pick probe wait time.
- cycle_.rounds_since_probe =
- sender_->RandomUint64(Params().probe_bw_max_probe_rand_rounds);
- cycle_.probe_wait_time =
- Params().probe_bw_probe_base_duration +
- QuicTime::Delta::FromMicroseconds(sender_->RandomUint64(
- Params().probe_bw_probe_max_rand_duration.ToMicroseconds()));
-
- cycle_.probe_up_bytes = std::numeric_limits<QuicByteCount>::max();
- cycle_.probe_up_app_limited_since_inflight_hi_limited_ = false;
- cycle_.has_advanced_max_bw = false;
- model_->RestartRoundEarly();
-}
-
-void Bbr2ProbeBwMode::EnterProbeCruise(QuicTime now) {
- if (cycle_.phase == CyclePhase::PROBE_DOWN) {
- ExitProbeDown();
- }
- QUIC_DVLOG(2) << sender_ << " Phase change: " << cycle_.phase << " ==> "
- << CyclePhase::PROBE_CRUISE << " after "
- << now - cycle_.phase_start_time << ", or "
- << cycle_.rounds_in_phase << " rounds. @ " << now;
-
- model_->cap_inflight_lo(model_->inflight_hi());
- cycle_.phase = CyclePhase::PROBE_CRUISE;
- cycle_.rounds_in_phase = 0;
- cycle_.phase_start_time = now;
- cycle_.is_sample_from_probing = false;
-}
-
-void Bbr2ProbeBwMode::EnterProbeRefill(uint64_t probe_up_rounds, QuicTime now) {
- if (cycle_.phase == CyclePhase::PROBE_DOWN) {
- ExitProbeDown();
- }
- QUIC_DVLOG(2) << sender_ << " Phase change: " << cycle_.phase << " ==> "
- << CyclePhase::PROBE_REFILL << " after "
- << now - cycle_.phase_start_time << ", or "
- << cycle_.rounds_in_phase
- << " rounds. probe_up_rounds:" << probe_up_rounds << " @ "
- << now;
- cycle_.phase = CyclePhase::PROBE_REFILL;
- cycle_.rounds_in_phase = 0;
- cycle_.phase_start_time = now;
- cycle_.is_sample_from_probing = false;
- last_cycle_stopped_risky_probe_ = false;
-
- model_->clear_bandwidth_lo();
- model_->clear_inflight_lo();
- cycle_.probe_up_rounds = probe_up_rounds;
- cycle_.probe_up_acked = 0;
- model_->RestartRoundEarly();
-}
-
-void Bbr2ProbeBwMode::EnterProbeUp(QuicTime now) {
- QUICHE_DCHECK_EQ(cycle_.phase, CyclePhase::PROBE_REFILL);
- QUIC_DVLOG(2) << sender_ << " Phase change: " << cycle_.phase << " ==> "
- << CyclePhase::PROBE_UP << " after "
- << now - cycle_.phase_start_time << ", or "
- << cycle_.rounds_in_phase << " rounds. @ " << now;
- cycle_.phase = CyclePhase::PROBE_UP;
- cycle_.rounds_in_phase = 0;
- cycle_.phase_start_time = now;
- cycle_.is_sample_from_probing = true;
- RaiseInflightHighSlope();
-
- model_->RestartRoundEarly();
-}
-
-void Bbr2ProbeBwMode::ExitProbeDown() {
- QUICHE_DCHECK_EQ(cycle_.phase, CyclePhase::PROBE_DOWN);
- if (!cycle_.has_advanced_max_bw) {
- QUIC_DVLOG(2) << sender_ << " Advancing max bw filter at end of cycle.";
- model_->AdvanceMaxBandwidthFilter();
- cycle_.has_advanced_max_bw = true;
- }
-}
-
-// static
-const char* Bbr2ProbeBwMode::CyclePhaseToString(CyclePhase phase) {
- switch (phase) {
- case CyclePhase::PROBE_NOT_STARTED:
- return "PROBE_NOT_STARTED";
- case CyclePhase::PROBE_UP:
- return "PROBE_UP";
- case CyclePhase::PROBE_DOWN:
- return "PROBE_DOWN";
- case CyclePhase::PROBE_CRUISE:
- return "PROBE_CRUISE";
- case CyclePhase::PROBE_REFILL:
- return "PROBE_REFILL";
- default:
- break;
- }
- return "<Invalid CyclePhase>";
-}
-
-std::ostream& operator<<(std::ostream& os,
- const Bbr2ProbeBwMode::CyclePhase phase) {
- return os << Bbr2ProbeBwMode::CyclePhaseToString(phase);
-}
-
-Bbr2ProbeBwMode::DebugState Bbr2ProbeBwMode::ExportDebugState() const {
- DebugState s;
- s.phase = cycle_.phase;
- s.cycle_start_time = cycle_.cycle_start_time;
- s.phase_start_time = cycle_.phase_start_time;
- return s;
-}
-
-std::ostream& operator<<(std::ostream& os,
- const Bbr2ProbeBwMode::DebugState& state) {
- os << "[PROBE_BW] phase: " << state.phase << "\n";
- os << "[PROBE_BW] cycle_start_time: " << state.cycle_start_time << "\n";
- os << "[PROBE_BW] phase_start_time: " << state.phase_start_time << "\n";
- return os;
-}
-
-const Bbr2Params& Bbr2ProbeBwMode::Params() const { return sender_->Params(); }
-
-float Bbr2ProbeBwMode::PacingGainForPhase(
- Bbr2ProbeBwMode::CyclePhase phase) const {
- if (phase == Bbr2ProbeBwMode::CyclePhase::PROBE_UP) {
- return Params().probe_bw_probe_up_pacing_gain;
- }
- if (phase == Bbr2ProbeBwMode::CyclePhase::PROBE_DOWN) {
- return Params().probe_bw_probe_down_pacing_gain;
- }
- return Params().probe_bw_default_pacing_gain;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/congestion_control/bbr2_probe_bw.h b/chromium/net/third_party/quiche/src/quic/core/congestion_control/bbr2_probe_bw.h
deleted file mode 100644
index 832dfa14154..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/congestion_control/bbr2_probe_bw.h
+++ /dev/null
@@ -1,142 +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_CORE_CONGESTION_CONTROL_BBR2_PROBE_BW_H_
-#define QUICHE_QUIC_CORE_CONGESTION_CONTROL_BBR2_PROBE_BW_H_
-
-#include <cstdint>
-
-#include "quic/core/congestion_control/bbr2_misc.h"
-#include "quic/core/quic_time.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_export.h"
-#include "quic/platform/api/quic_flags.h"
-
-namespace quic {
-
-class Bbr2Sender;
-class QUIC_EXPORT_PRIVATE Bbr2ProbeBwMode final : public Bbr2ModeBase {
- public:
- using Bbr2ModeBase::Bbr2ModeBase;
-
- void Enter(QuicTime now,
- const Bbr2CongestionEvent* congestion_event) override;
- void Leave(QuicTime /*now*/,
- const Bbr2CongestionEvent* /*congestion_event*/) override {}
-
- Bbr2Mode OnCongestionEvent(
- QuicByteCount prior_in_flight,
- QuicTime event_time,
- const AckedPacketVector& acked_packets,
- const LostPacketVector& lost_packets,
- const Bbr2CongestionEvent& congestion_event) override;
-
- Limits<QuicByteCount> GetCwndLimits() const override;
-
- bool IsProbingForBandwidth() const override;
-
- Bbr2Mode OnExitQuiescence(QuicTime now,
- QuicTime quiescence_start_time) override;
-
- enum class CyclePhase : uint8_t {
- PROBE_NOT_STARTED,
- PROBE_UP,
- PROBE_DOWN,
- PROBE_CRUISE,
- PROBE_REFILL,
- };
-
- static const char* CyclePhaseToString(CyclePhase phase);
-
- struct QUIC_EXPORT_PRIVATE DebugState {
- CyclePhase phase;
- QuicTime cycle_start_time = QuicTime::Zero();
- QuicTime phase_start_time = QuicTime::Zero();
- };
-
- DebugState ExportDebugState() const;
-
- private:
- const Bbr2Params& Params() const;
- float PacingGainForPhase(CyclePhase phase) const;
-
- void UpdateProbeUp(QuicByteCount prior_in_flight,
- const Bbr2CongestionEvent& congestion_event);
- void UpdateProbeDown(QuicByteCount prior_in_flight,
- const Bbr2CongestionEvent& congestion_event);
- void UpdateProbeCruise(const Bbr2CongestionEvent& congestion_event);
- void UpdateProbeRefill(const Bbr2CongestionEvent& congestion_event);
-
- enum AdaptUpperBoundsResult : uint8_t {
- ADAPTED_OK,
- ADAPTED_PROBED_TOO_HIGH,
- NOT_ADAPTED_INFLIGHT_HIGH_NOT_SET,
- NOT_ADAPTED_INVALID_SAMPLE,
- };
-
- // Return whether adapted inflight_hi. If inflight is too high, this function
- // will not adapt inflight_hi and will return false.
- AdaptUpperBoundsResult MaybeAdaptUpperBounds(
- const Bbr2CongestionEvent& congestion_event);
-
- void EnterProbeDown(bool probed_too_high,
- bool stopped_risky_probe,
- QuicTime now);
- void EnterProbeCruise(QuicTime now);
- void EnterProbeRefill(uint64_t probe_up_rounds, QuicTime now);
- void EnterProbeUp(QuicTime now);
-
- // Call right before the exit of PROBE_DOWN.
- void ExitProbeDown();
-
- float PercentTimeElapsedToProbeBandwidth(
- const Bbr2CongestionEvent& congestion_event) const;
-
- bool IsTimeToProbeBandwidth(
- const Bbr2CongestionEvent& congestion_event) const;
- bool HasStayedLongEnoughInProbeDown(
- const Bbr2CongestionEvent& congestion_event) const;
- bool HasCycleLasted(QuicTime::Delta duration,
- const Bbr2CongestionEvent& congestion_event) const;
- bool HasPhaseLasted(QuicTime::Delta duration,
- const Bbr2CongestionEvent& congestion_event) const;
- bool IsTimeToProbeForRenoCoexistence(
- double probe_wait_fraction,
- const Bbr2CongestionEvent& congestion_event) const;
-
- void RaiseInflightHighSlope();
- void ProbeInflightHighUpward(const Bbr2CongestionEvent& congestion_event);
-
- struct QUIC_EXPORT_PRIVATE Cycle {
- QuicTime cycle_start_time = QuicTime::Zero();
- CyclePhase phase = CyclePhase::PROBE_NOT_STARTED;
- uint64_t rounds_in_phase = 0;
- QuicTime phase_start_time = QuicTime::Zero();
- QuicRoundTripCount rounds_since_probe = 0;
- QuicTime::Delta probe_wait_time = QuicTime::Delta::Zero();
- uint64_t probe_up_rounds = 0;
- QuicByteCount probe_up_bytes = std::numeric_limits<QuicByteCount>::max();
- QuicByteCount probe_up_acked = 0;
- bool probe_up_app_limited_since_inflight_hi_limited_ = false;
- // Whether max bandwidth filter window has advanced in this cycle. It is
- // advanced once per cycle.
- bool has_advanced_max_bw = false;
- bool is_sample_from_probing = false;
- } cycle_;
-
- bool last_cycle_probed_too_high_;
- bool last_cycle_stopped_risky_probe_;
-};
-
-QUIC_EXPORT_PRIVATE std::ostream& operator<<(
- std::ostream& os,
- const Bbr2ProbeBwMode::DebugState& state);
-
-QUIC_EXPORT_PRIVATE std::ostream& operator<<(
- std::ostream& os,
- const Bbr2ProbeBwMode::CyclePhase phase);
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_CONGESTION_CONTROL_BBR2_PROBE_BW_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/congestion_control/bbr2_probe_rtt.cc b/chromium/net/third_party/quiche/src/quic/core/congestion_control/bbr2_probe_rtt.cc
deleted file mode 100644
index d83e5e67739..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/congestion_control/bbr2_probe_rtt.cc
+++ /dev/null
@@ -1,83 +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 "quic/core/congestion_control/bbr2_probe_rtt.h"
-
-#include "quic/core/congestion_control/bbr2_sender.h"
-#include "quic/core/quic_time.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-void Bbr2ProbeRttMode::Enter(QuicTime /*now*/,
- const Bbr2CongestionEvent* /*congestion_event*/) {
- model_->set_pacing_gain(1.0);
- model_->set_cwnd_gain(1.0);
- exit_time_ = QuicTime::Zero();
-}
-
-Bbr2Mode Bbr2ProbeRttMode::OnCongestionEvent(
- QuicByteCount /*prior_in_flight*/,
- QuicTime /*event_time*/,
- const AckedPacketVector& /*acked_packets*/,
- const LostPacketVector& /*lost_packets*/,
- const Bbr2CongestionEvent& congestion_event) {
- if (exit_time_ == QuicTime::Zero()) {
- if (congestion_event.bytes_in_flight <= InflightTarget() ||
- congestion_event.bytes_in_flight <=
- sender_->GetMinimumCongestionWindow()) {
- exit_time_ = congestion_event.event_time + Params().probe_rtt_duration;
- QUIC_DVLOG(2) << sender_ << " PROBE_RTT exit time set to " << exit_time_
- << ". bytes_inflight:" << congestion_event.bytes_in_flight
- << ", inflight_target:" << InflightTarget()
- << ", min_congestion_window:"
- << sender_->GetMinimumCongestionWindow() << " @ "
- << congestion_event.event_time;
- }
- return Bbr2Mode::PROBE_RTT;
- }
-
- return congestion_event.event_time > exit_time_ ? Bbr2Mode::PROBE_BW
- : Bbr2Mode::PROBE_RTT;
-}
-
-QuicByteCount Bbr2ProbeRttMode::InflightTarget() const {
- return model_->BDP(model_->MaxBandwidth(),
- Params().probe_rtt_inflight_target_bdp_fraction);
-}
-
-Limits<QuicByteCount> Bbr2ProbeRttMode::GetCwndLimits() const {
- QuicByteCount inflight_upper_bound =
- std::min(model_->inflight_lo(), model_->inflight_hi_with_headroom());
- return NoGreaterThan(std::min(inflight_upper_bound, InflightTarget()));
-}
-
-Bbr2Mode Bbr2ProbeRttMode::OnExitQuiescence(
- QuicTime now,
- QuicTime /*quiescence_start_time*/) {
- if (now > exit_time_) {
- return Bbr2Mode::PROBE_BW;
- }
- return Bbr2Mode::PROBE_RTT;
-}
-
-Bbr2ProbeRttMode::DebugState Bbr2ProbeRttMode::ExportDebugState() const {
- DebugState s;
- s.inflight_target = InflightTarget();
- s.exit_time = exit_time_;
- return s;
-}
-
-std::ostream& operator<<(std::ostream& os,
- const Bbr2ProbeRttMode::DebugState& state) {
- os << "[PROBE_RTT] inflight_target: " << state.inflight_target << "\n";
- os << "[PROBE_RTT] exit_time: " << state.exit_time << "\n";
- return os;
-}
-
-const Bbr2Params& Bbr2ProbeRttMode::Params() const {
- return sender_->Params();
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/congestion_control/bbr2_probe_rtt.h b/chromium/net/third_party/quiche/src/quic/core/congestion_control/bbr2_probe_rtt.h
deleted file mode 100644
index 7d3873d47b4..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/congestion_control/bbr2_probe_rtt.h
+++ /dev/null
@@ -1,60 +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_CORE_CONGESTION_CONTROL_BBR2_PROBE_RTT_H_
-#define QUICHE_QUIC_CORE_CONGESTION_CONTROL_BBR2_PROBE_RTT_H_
-
-#include "quic/core/congestion_control/bbr2_misc.h"
-#include "quic/core/quic_time.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-class Bbr2Sender;
-class QUIC_EXPORT_PRIVATE Bbr2ProbeRttMode final : public Bbr2ModeBase {
- public:
- using Bbr2ModeBase::Bbr2ModeBase;
-
- void Enter(QuicTime now,
- const Bbr2CongestionEvent* congestion_event) override;
- void Leave(QuicTime /*now*/,
- const Bbr2CongestionEvent* /*congestion_event*/) override {}
-
- Bbr2Mode OnCongestionEvent(
- QuicByteCount prior_in_flight,
- QuicTime event_time,
- const AckedPacketVector& acked_packets,
- const LostPacketVector& lost_packets,
- const Bbr2CongestionEvent& congestion_event) override;
-
- Limits<QuicByteCount> GetCwndLimits() const override;
-
- bool IsProbingForBandwidth() const override { return false; }
-
- Bbr2Mode OnExitQuiescence(QuicTime now,
- QuicTime quiescence_start_time) override;
-
- struct QUIC_EXPORT_PRIVATE DebugState {
- QuicByteCount inflight_target;
- QuicTime exit_time = QuicTime::Zero();
- };
-
- DebugState ExportDebugState() const;
-
- private:
- const Bbr2Params& Params() const;
-
- QuicByteCount InflightTarget() const;
-
- QuicTime exit_time_ = QuicTime::Zero();
-};
-
-QUIC_EXPORT_PRIVATE std::ostream& operator<<(
- std::ostream& os,
- const Bbr2ProbeRttMode::DebugState& state);
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_CONGESTION_CONTROL_BBR2_PROBE_RTT_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/congestion_control/bbr2_sender.cc b/chromium/net/third_party/quiche/src/quic/core/congestion_control/bbr2_sender.cc
deleted file mode 100644
index 266c8250b01..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/congestion_control/bbr2_sender.cc
+++ /dev/null
@@ -1,578 +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 "quic/core/congestion_control/bbr2_sender.h"
-
-#include <cstddef>
-
-#include "quic/core/congestion_control/bandwidth_sampler.h"
-#include "quic/core/congestion_control/bbr2_drain.h"
-#include "quic/core/congestion_control/bbr2_misc.h"
-#include "quic/core/crypto/crypto_protocol.h"
-#include "quic/core/quic_bandwidth.h"
-#include "quic/core/quic_tag.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_flag_utils.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-#include "common/print_elements.h"
-
-namespace quic {
-
-namespace {
-// Constants based on TCP defaults.
-// The minimum CWND to ensure delayed acks don't reduce bandwidth measurements.
-// Does not inflate the pacing rate.
-const QuicByteCount kDefaultMinimumCongestionWindow = 4 * kMaxSegmentSize;
-
-const float kInitialPacingGain = 2.885f;
-
-const int kMaxModeChangesPerCongestionEvent = 4;
-} // namespace
-
-// Call |member_function_call| based on the current Bbr2Mode we are in. e.g.
-//
-// auto result = BBR2_MODE_DISPATCH(Foo());
-//
-// is equivalent to:
-//
-// Bbr2ModeBase& Bbr2Sender::GetCurrentMode() {
-// if (mode_ == Bbr2Mode::STARTUP) { return startup_; }
-// if (mode_ == Bbr2Mode::DRAIN) { return drain_; }
-// ...
-// }
-// auto result = GetCurrentMode().Foo();
-//
-// Except that BBR2_MODE_DISPATCH guarantees the call to Foo() is non-virtual.
-//
-#define BBR2_MODE_DISPATCH(member_function_call) \
- (mode_ == Bbr2Mode::STARTUP \
- ? (startup_.member_function_call) \
- : (mode_ == Bbr2Mode::PROBE_BW \
- ? (probe_bw_.member_function_call) \
- : (mode_ == Bbr2Mode::DRAIN \
- ? (drain_.member_function_call) \
- : (probe_rtt_or_die().member_function_call))))
-
-Bbr2Sender::Bbr2Sender(QuicTime now,
- const RttStats* rtt_stats,
- const QuicUnackedPacketMap* unacked_packets,
- QuicPacketCount initial_cwnd_in_packets,
- QuicPacketCount max_cwnd_in_packets,
- QuicRandom* random,
- QuicConnectionStats* stats,
- BbrSender* old_sender)
- : mode_(Bbr2Mode::STARTUP),
- rtt_stats_(rtt_stats),
- unacked_packets_(unacked_packets),
- random_(random),
- connection_stats_(stats),
- params_(kDefaultMinimumCongestionWindow,
- max_cwnd_in_packets * kDefaultTCPMSS),
- model_(&params_,
- rtt_stats->SmoothedOrInitialRtt(),
- rtt_stats->last_update_time(),
- /*cwnd_gain=*/1.0,
- /*pacing_gain=*/kInitialPacingGain,
- old_sender ? &old_sender->sampler_ : nullptr),
- initial_cwnd_(cwnd_limits().ApplyLimits(
- (old_sender) ? old_sender->GetCongestionWindow()
- : (initial_cwnd_in_packets * kDefaultTCPMSS))),
- cwnd_(initial_cwnd_),
- pacing_rate_(kInitialPacingGain * QuicBandwidth::FromBytesAndTimeDelta(
- cwnd_,
- rtt_stats->SmoothedOrInitialRtt())),
- startup_(this, &model_, now),
- drain_(this, &model_),
- probe_bw_(this, &model_),
- probe_rtt_(this, &model_),
- last_sample_is_app_limited_(false) {
- QUIC_DVLOG(2) << this << " Initializing Bbr2Sender. mode:" << mode_
- << ", PacingRate:" << pacing_rate_ << ", Cwnd:" << cwnd_
- << ", CwndLimits:" << cwnd_limits() << " @ " << now;
- QUICHE_DCHECK_EQ(mode_, Bbr2Mode::STARTUP);
-}
-
-void Bbr2Sender::SetFromConfig(const QuicConfig& config,
- Perspective perspective) {
- if (config.HasClientRequestedIndependentOption(kB2NA, perspective)) {
- params_.add_ack_height_to_queueing_threshold = false;
- }
- if (config.HasClientRequestedIndependentOption(kB2RP, perspective)) {
- params_.avoid_unnecessary_probe_rtt = false;
- }
- if (config.HasClientRequestedIndependentOption(k1RTT, perspective)) {
- params_.startup_full_bw_rounds = 1;
- }
- if (config.HasClientRequestedIndependentOption(k2RTT, perspective)) {
- params_.startup_full_bw_rounds = 2;
- }
- if (config.HasClientRequestedIndependentOption(kB2HR, perspective)) {
- params_.inflight_hi_headroom = 0.15;
- }
- if (config.HasClientRequestedIndependentOption(kICW1, perspective)) {
- max_cwnd_when_network_parameters_adjusted_ = 100 * kDefaultTCPMSS;
- }
-
- ApplyConnectionOptions(config.ClientRequestedIndependentOptions(perspective));
-}
-
-void Bbr2Sender::ApplyConnectionOptions(
- const QuicTagVector& connection_options) {
- if (GetQuicReloadableFlag(quic_bbr2_extra_acked_window) &&
- ContainsQuicTag(connection_options, kBBR4)) {
- QUIC_RELOADABLE_FLAG_COUNT_N(quic_bbr2_extra_acked_window, 1, 2);
- model_.SetMaxAckHeightTrackerWindowLength(20);
- }
- if (GetQuicReloadableFlag(quic_bbr2_extra_acked_window) &&
- ContainsQuicTag(connection_options, kBBR5)) {
- QUIC_RELOADABLE_FLAG_COUNT_N(quic_bbr2_extra_acked_window, 2, 2);
- model_.SetMaxAckHeightTrackerWindowLength(40);
- }
- if (ContainsQuicTag(connection_options, kBBQ2)) {
- params_.startup_cwnd_gain = 2.885;
- params_.drain_cwnd_gain = 2.885;
- model_.set_cwnd_gain(params_.startup_cwnd_gain);
- }
- if (ContainsQuicTag(connection_options, kB2LO)) {
- params_.ignore_inflight_lo = true;
- }
- if (ContainsQuicTag(connection_options, kB2NE)) {
- params_.always_exit_startup_on_excess_loss = true;
- }
- if (ContainsQuicTag(connection_options, kB2SL)) {
- params_.startup_loss_exit_use_max_delivered_for_inflight_hi = false;
- }
- if (ContainsQuicTag(connection_options, kB2H2)) {
- params_.limit_inflight_hi_by_max_delivered = true;
- }
- if (ContainsQuicTag(connection_options, kB2DL)) {
- params_.use_bytes_delivered_for_inflight_hi = true;
- }
- if (ContainsQuicTag(connection_options, kB2RC)) {
- params_.enable_reno_coexistence = false;
- }
- if (ContainsQuicTag(connection_options, kBSAO)) {
- model_.EnableOverestimateAvoidance();
- }
- if (ContainsQuicTag(connection_options, kBBQ6)) {
- params_.decrease_startup_pacing_at_end_of_round = true;
- }
- if (ContainsQuicTag(connection_options, kBBQ7)) {
- params_.bw_lo_mode_ = Bbr2Params::QuicBandwidthLoMode::MIN_RTT_REDUCTION;
- }
- if (ContainsQuicTag(connection_options, kBBQ8)) {
- params_.bw_lo_mode_ = Bbr2Params::QuicBandwidthLoMode::INFLIGHT_REDUCTION;
- }
- if (ContainsQuicTag(connection_options, kBBQ9)) {
- params_.bw_lo_mode_ = Bbr2Params::QuicBandwidthLoMode::CWND_REDUCTION;
- }
- if (ContainsQuicTag(connection_options, kB201)) {
- params_.probe_bw_check_cwnd_limited_before_aggregation_epoch = true;
- }
- if (GetQuicReloadableFlag(quic_bbr2_no_probe_up_exit_if_no_queue) &&
- ContainsQuicTag(connection_options, kB202)) {
- params_.probe_up_dont_exit_if_no_queue_ = true;
- }
- if (GetQuicReloadableFlag(quic_bbr2_ignore_inflight_hi_in_probe_up) &&
- ContainsQuicTag(connection_options, kB203)) {
- QUIC_RELOADABLE_FLAG_COUNT(quic_bbr2_ignore_inflight_hi_in_probe_up);
- params_.probe_up_ignore_inflight_hi = true;
- }
- if (GetQuicReloadableFlag(quic_bbr2_startup_extra_acked) &&
- ContainsQuicTag(connection_options, kB204)) {
- QUIC_RELOADABLE_FLAG_COUNT_N(quic_bbr2_startup_extra_acked, 1, 2);
- model_.SetReduceExtraAckedOnBandwidthIncrease(true);
- }
- if (GetQuicReloadableFlag(quic_bbr2_startup_extra_acked) &&
- ContainsQuicTag(connection_options, kB205)) {
- QUIC_RELOADABLE_FLAG_COUNT_N(quic_bbr2_startup_extra_acked, 2, 2);
- params_.startup_include_extra_acked = true;
- }
- if (GetQuicReloadableFlag(quic_bbr2_exit_startup_on_persistent_queue2) &&
- ContainsQuicTag(connection_options, kB207)) {
- params_.exit_startup_on_persistent_queue = true;
- }
-
- if (ContainsQuicTag(connection_options, kBBRA)) {
- model_.SetStartNewAggregationEpochAfterFullRound(true);
- }
- if (GetQuicReloadableFlag(quic_bbr_use_send_rate_in_max_ack_height_tracker) &&
- ContainsQuicTag(connection_options, kBBRB)) {
- QUIC_RELOADABLE_FLAG_COUNT_N(
- quic_bbr_use_send_rate_in_max_ack_height_tracker, 2, 2);
- model_.SetLimitMaxAckHeightTrackerBySendRate(true);
- }
- if (GetQuicReloadableFlag(
- quic_bbr2_add_bytes_acked_after_inflight_hi_limited) &&
- ContainsQuicTag(connection_options, kBBQ0)) {
- params_.probe_up_includes_acks_after_cwnd_limited = true;
- }
-
- if (GetQuicReloadableFlag(quic_bbr2_startup_probe_up_loss_events) &&
- ContainsQuicTag(connection_options, kB206)) {
- QUIC_RELOADABLE_FLAG_COUNT(quic_bbr2_startup_probe_up_loss_events);
- params_.startup_full_loss_count = params_.probe_bw_full_loss_count;
- }
-}
-
-Limits<QuicByteCount> Bbr2Sender::GetCwndLimitsByMode() const {
- switch (mode_) {
- case Bbr2Mode::STARTUP:
- return startup_.GetCwndLimits();
- case Bbr2Mode::PROBE_BW:
- return probe_bw_.GetCwndLimits();
- case Bbr2Mode::DRAIN:
- return drain_.GetCwndLimits();
- case Bbr2Mode::PROBE_RTT:
- return probe_rtt_.GetCwndLimits();
- default:
- QUIC_NOTREACHED();
- return Unlimited<QuicByteCount>();
- }
-}
-
-const Limits<QuicByteCount>& Bbr2Sender::cwnd_limits() const {
- return params().cwnd_limits;
-}
-
-void Bbr2Sender::AdjustNetworkParameters(const NetworkParams& params) {
- model_.UpdateNetworkParameters(params.rtt);
-
- if (mode_ == Bbr2Mode::STARTUP) {
- const QuicByteCount prior_cwnd = cwnd_;
-
- QuicBandwidth effective_bandwidth =
- std::max(params.bandwidth, model_.BandwidthEstimate());
- connection_stats_->cwnd_bootstrapping_rtt_us =
- model_.MinRtt().ToMicroseconds();
-
- if (params.max_initial_congestion_window > 0) {
- max_cwnd_when_network_parameters_adjusted_ =
- params.max_initial_congestion_window * kDefaultTCPMSS;
- }
- cwnd_ = cwnd_limits().ApplyLimits(
- std::min(max_cwnd_when_network_parameters_adjusted_,
- model_.BDP(effective_bandwidth)));
-
- if (!params.allow_cwnd_to_decrease) {
- cwnd_ = std::max(cwnd_, prior_cwnd);
- }
-
- pacing_rate_ = std::max(pacing_rate_, QuicBandwidth::FromBytesAndTimeDelta(
- cwnd_, model_.MinRtt()));
- }
-}
-
-void Bbr2Sender::SetInitialCongestionWindowInPackets(
- QuicPacketCount congestion_window) {
- if (mode_ == Bbr2Mode::STARTUP) {
- // The cwnd limits is unchanged and still applies to the new cwnd.
- cwnd_ = cwnd_limits().ApplyLimits(congestion_window * kDefaultTCPMSS);
- }
-}
-
-void Bbr2Sender::OnCongestionEvent(bool /*rtt_updated*/,
- QuicByteCount prior_in_flight,
- QuicTime event_time,
- const AckedPacketVector& acked_packets,
- const LostPacketVector& lost_packets) {
- QUIC_DVLOG(3) << this
- << " OnCongestionEvent. prior_in_flight:" << prior_in_flight
- << " prior_cwnd:" << cwnd_ << " @ " << event_time;
- Bbr2CongestionEvent congestion_event;
- congestion_event.prior_cwnd = cwnd_;
- congestion_event.prior_bytes_in_flight = prior_in_flight;
- congestion_event.is_probing_for_bandwidth =
- BBR2_MODE_DISPATCH(IsProbingForBandwidth());
-
- model_.OnCongestionEventStart(event_time, acked_packets, lost_packets,
- &congestion_event);
-
- if (InSlowStart()) {
- if (!lost_packets.empty()) {
- connection_stats_->slowstart_packets_lost += lost_packets.size();
- connection_stats_->slowstart_bytes_lost += congestion_event.bytes_lost;
- }
- if (congestion_event.end_of_round_trip) {
- ++connection_stats_->slowstart_num_rtts;
- }
- }
-
- // Number of mode changes allowed for this congestion event.
- int mode_changes_allowed = kMaxModeChangesPerCongestionEvent;
- while (true) {
- Bbr2Mode next_mode = BBR2_MODE_DISPATCH(
- OnCongestionEvent(prior_in_flight, event_time, acked_packets,
- lost_packets, congestion_event));
-
- if (next_mode == mode_) {
- break;
- }
-
- QUIC_DVLOG(2) << this << " Mode change: " << mode_ << " ==> " << next_mode
- << " @ " << event_time;
- BBR2_MODE_DISPATCH(Leave(event_time, &congestion_event));
- mode_ = next_mode;
- BBR2_MODE_DISPATCH(Enter(event_time, &congestion_event));
- --mode_changes_allowed;
- if (mode_changes_allowed < 0) {
- QUIC_BUG(quic_bug_10443_1)
- << "Exceeded max number of mode changes per congestion event.";
- break;
- }
- }
-
- UpdatePacingRate(congestion_event.bytes_acked);
- QUIC_BUG_IF(quic_bug_10443_2, pacing_rate_.IsZero())
- << "Pacing rate must not be zero!";
-
- UpdateCongestionWindow(congestion_event.bytes_acked);
- QUIC_BUG_IF(quic_bug_10443_3, cwnd_ == 0u)
- << "Congestion window must not be zero!";
-
- model_.OnCongestionEventFinish(unacked_packets_->GetLeastUnacked(),
- congestion_event);
- last_sample_is_app_limited_ =
- congestion_event.last_packet_send_state.is_app_limited;
- if (congestion_event.bytes_in_flight == 0 &&
- params().avoid_unnecessary_probe_rtt) {
- OnEnterQuiescence(event_time);
- }
-
- QUIC_DVLOG(3)
- << this
- << " END CongestionEvent(acked:" << quiche::PrintElements(acked_packets)
- << ", lost:" << lost_packets.size() << ") "
- << ", Mode:" << mode_ << ", RttCount:" << model_.RoundTripCount()
- << ", BytesInFlight:" << congestion_event.bytes_in_flight
- << ", PacingRate:" << PacingRate(0) << ", CWND:" << GetCongestionWindow()
- << ", PacingGain:" << model_.pacing_gain()
- << ", CwndGain:" << model_.cwnd_gain()
- << ", BandwidthEstimate(kbps):" << BandwidthEstimate().ToKBitsPerSecond()
- << ", MinRTT(us):" << model_.MinRtt().ToMicroseconds()
- << ", BDP:" << model_.BDP(BandwidthEstimate())
- << ", BandwidthLatest(kbps):"
- << model_.bandwidth_latest().ToKBitsPerSecond()
- << ", BandwidthLow(kbps):" << model_.bandwidth_lo().ToKBitsPerSecond()
- << ", BandwidthHigh(kbps):" << model_.MaxBandwidth().ToKBitsPerSecond()
- << ", InflightLatest:" << model_.inflight_latest()
- << ", InflightLow:" << model_.inflight_lo()
- << ", InflightHigh:" << model_.inflight_hi()
- << ", TotalAcked:" << model_.total_bytes_acked()
- << ", TotalLost:" << model_.total_bytes_lost()
- << ", TotalSent:" << model_.total_bytes_sent() << " @ " << event_time;
-}
-
-void Bbr2Sender::UpdatePacingRate(QuicByteCount bytes_acked) {
- if (BandwidthEstimate().IsZero()) {
- return;
- }
-
- if (model_.total_bytes_acked() == bytes_acked) {
- // After the first ACK, cwnd_ is still the initial congestion window.
- pacing_rate_ = QuicBandwidth::FromBytesAndTimeDelta(cwnd_, model_.MinRtt());
- return;
- }
-
- QuicBandwidth target_rate = model_.pacing_gain() * model_.BandwidthEstimate();
- if (model_.full_bandwidth_reached()) {
- pacing_rate_ = target_rate;
- return;
- }
- if (params_.decrease_startup_pacing_at_end_of_round &&
- model_.pacing_gain() < Params().startup_pacing_gain) {
- pacing_rate_ = target_rate;
- return;
- }
- if (params_.bw_lo_mode_ != Bbr2Params::DEFAULT &&
- model_.loss_events_in_round() > 0) {
- pacing_rate_ = target_rate;
- return;
- }
-
- // By default, the pacing rate never decreases in STARTUP.
- if (target_rate > pacing_rate_) {
- pacing_rate_ = target_rate;
- }
-}
-
-void Bbr2Sender::UpdateCongestionWindow(QuicByteCount bytes_acked) {
- QuicByteCount target_cwnd = GetTargetCongestionWindow(model_.cwnd_gain());
-
- const QuicByteCount prior_cwnd = cwnd_;
- if (model_.full_bandwidth_reached() || Params().startup_include_extra_acked) {
- target_cwnd += model_.MaxAckHeight();
- cwnd_ = std::min(prior_cwnd + bytes_acked, target_cwnd);
- } else if (prior_cwnd < target_cwnd || prior_cwnd < 2 * initial_cwnd_) {
- cwnd_ = prior_cwnd + bytes_acked;
- }
- const QuicByteCount desired_cwnd = cwnd_;
-
- cwnd_ = GetCwndLimitsByMode().ApplyLimits(cwnd_);
- const QuicByteCount model_limited_cwnd = cwnd_;
-
- cwnd_ = cwnd_limits().ApplyLimits(cwnd_);
-
- QUIC_DVLOG(3) << this << " Updating CWND. target_cwnd:" << target_cwnd
- << ", max_ack_height:" << model_.MaxAckHeight()
- << ", full_bw:" << model_.full_bandwidth_reached()
- << ", bytes_acked:" << bytes_acked
- << ", inflight_lo:" << model_.inflight_lo()
- << ", inflight_hi:" << model_.inflight_hi() << ". (prior_cwnd) "
- << prior_cwnd << " => (desired_cwnd) " << desired_cwnd
- << " => (model_limited_cwnd) " << model_limited_cwnd
- << " => (final_cwnd) " << cwnd_;
-}
-
-QuicByteCount Bbr2Sender::GetTargetCongestionWindow(float gain) const {
- return std::max(model_.BDP(model_.BandwidthEstimate(), gain),
- cwnd_limits().Min());
-}
-
-void Bbr2Sender::OnPacketSent(QuicTime sent_time,
- QuicByteCount bytes_in_flight,
- QuicPacketNumber packet_number,
- QuicByteCount bytes,
- HasRetransmittableData is_retransmittable) {
- QUIC_DVLOG(3) << this << " OnPacketSent: pkn:" << packet_number
- << ", bytes:" << bytes << ", cwnd:" << cwnd_
- << ", inflight:" << bytes_in_flight + bytes
- << ", total_sent:" << model_.total_bytes_sent() + bytes
- << ", total_acked:" << model_.total_bytes_acked()
- << ", total_lost:" << model_.total_bytes_lost() << " @ "
- << sent_time;
- if (InSlowStart()) {
- ++connection_stats_->slowstart_packets_sent;
- connection_stats_->slowstart_bytes_sent += bytes;
- }
- if (bytes_in_flight == 0 && params().avoid_unnecessary_probe_rtt) {
- OnExitQuiescence(sent_time);
- }
- model_.OnPacketSent(sent_time, bytes_in_flight, packet_number, bytes,
- is_retransmittable);
-}
-
-void Bbr2Sender::OnPacketNeutered(QuicPacketNumber packet_number) {
- model_.OnPacketNeutered(packet_number);
-}
-
-bool Bbr2Sender::CanSend(QuicByteCount bytes_in_flight) {
- const bool result = bytes_in_flight < GetCongestionWindow();
- return result;
-}
-
-QuicByteCount Bbr2Sender::GetCongestionWindow() const {
- // TODO(wub): Implement Recovery?
- return cwnd_;
-}
-
-QuicBandwidth Bbr2Sender::PacingRate(QuicByteCount /*bytes_in_flight*/) const {
- return pacing_rate_;
-}
-
-void Bbr2Sender::OnApplicationLimited(QuicByteCount bytes_in_flight) {
- if (bytes_in_flight >= GetCongestionWindow()) {
- return;
- }
-
- model_.OnApplicationLimited();
- QUIC_DVLOG(2) << this << " Becoming application limited. Last sent packet: "
- << model_.last_sent_packet()
- << ", CWND: " << GetCongestionWindow();
-}
-
-QuicByteCount Bbr2Sender::GetTargetBytesInflight() const {
- QuicByteCount bdp = model_.BDP(model_.BandwidthEstimate());
- return std::min(bdp, GetCongestionWindow());
-}
-
-void Bbr2Sender::PopulateConnectionStats(QuicConnectionStats* stats) const {
- stats->num_ack_aggregation_epochs = model_.num_ack_aggregation_epochs();
-}
-
-void Bbr2Sender::OnEnterQuiescence(QuicTime now) {
- last_quiescence_start_ = now;
-}
-
-void Bbr2Sender::OnExitQuiescence(QuicTime now) {
- if (last_quiescence_start_ != QuicTime::Zero()) {
- Bbr2Mode next_mode = BBR2_MODE_DISPATCH(
- OnExitQuiescence(now, std::min(now, last_quiescence_start_)));
- if (next_mode != mode_) {
- BBR2_MODE_DISPATCH(Leave(now, nullptr));
- mode_ = next_mode;
- BBR2_MODE_DISPATCH(Enter(now, nullptr));
- }
- last_quiescence_start_ = QuicTime::Zero();
- }
-}
-
-bool Bbr2Sender::ShouldSendProbingPacket() const {
- // TODO(wub): Implement ShouldSendProbingPacket properly.
- return BBR2_MODE_DISPATCH(IsProbingForBandwidth());
-}
-
-std::string Bbr2Sender::GetDebugState() const {
- std::ostringstream stream;
- stream << ExportDebugState();
- return stream.str();
-}
-
-Bbr2Sender::DebugState Bbr2Sender::ExportDebugState() const {
- DebugState s;
- s.mode = mode_;
- s.round_trip_count = model_.RoundTripCount();
- s.bandwidth_hi = model_.MaxBandwidth();
- s.bandwidth_lo = model_.bandwidth_lo();
- s.bandwidth_est = BandwidthEstimate();
- s.inflight_hi = model_.inflight_hi();
- s.inflight_lo = model_.inflight_lo();
- s.max_ack_height = model_.MaxAckHeight();
- s.min_rtt = model_.MinRtt();
- s.min_rtt_timestamp = model_.MinRttTimestamp();
- s.congestion_window = cwnd_;
- s.pacing_rate = pacing_rate_;
- s.last_sample_is_app_limited = last_sample_is_app_limited_;
- s.end_of_app_limited_phase = model_.end_of_app_limited_phase();
-
- s.startup = startup_.ExportDebugState();
- s.drain = drain_.ExportDebugState();
- s.probe_bw = probe_bw_.ExportDebugState();
- s.probe_rtt = probe_rtt_.ExportDebugState();
-
- return s;
-}
-
-std::ostream& operator<<(std::ostream& os, const Bbr2Sender::DebugState& s) {
- os << "mode: " << s.mode << "\n";
- os << "round_trip_count: " << s.round_trip_count << "\n";
- os << "bandwidth_hi ~ lo ~ est: " << s.bandwidth_hi << " ~ " << s.bandwidth_lo
- << " ~ " << s.bandwidth_est << "\n";
- os << "min_rtt: " << s.min_rtt << "\n";
- os << "min_rtt_timestamp: " << s.min_rtt_timestamp << "\n";
- os << "congestion_window: " << s.congestion_window << "\n";
- os << "pacing_rate: " << s.pacing_rate << "\n";
- os << "last_sample_is_app_limited: " << s.last_sample_is_app_limited << "\n";
-
- if (s.mode == Bbr2Mode::STARTUP) {
- os << s.startup;
- }
-
- if (s.mode == Bbr2Mode::DRAIN) {
- os << s.drain;
- }
-
- if (s.mode == Bbr2Mode::PROBE_BW) {
- os << s.probe_bw;
- }
-
- if (s.mode == Bbr2Mode::PROBE_RTT) {
- os << s.probe_rtt;
- }
-
- return os;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/congestion_control/bbr2_sender.h b/chromium/net/third_party/quiche/src/quic/core/congestion_control/bbr2_sender.h
deleted file mode 100644
index a0b5199b254..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/congestion_control/bbr2_sender.h
+++ /dev/null
@@ -1,216 +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_CORE_CONGESTION_CONTROL_BBR2_SENDER_H_
-#define QUICHE_QUIC_CORE_CONGESTION_CONTROL_BBR2_SENDER_H_
-
-#include <cstdint>
-
-#include "quic/core/congestion_control/bandwidth_sampler.h"
-#include "quic/core/congestion_control/bbr2_drain.h"
-#include "quic/core/congestion_control/bbr2_misc.h"
-#include "quic/core/congestion_control/bbr2_probe_bw.h"
-#include "quic/core/congestion_control/bbr2_probe_rtt.h"
-#include "quic/core/congestion_control/bbr2_startup.h"
-#include "quic/core/congestion_control/bbr_sender.h"
-#include "quic/core/congestion_control/rtt_stats.h"
-#include "quic/core/congestion_control/send_algorithm_interface.h"
-#include "quic/core/congestion_control/windowed_filter.h"
-#include "quic/core/quic_bandwidth.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_export.h"
-#include "quic/platform/api/quic_flags.h"
-
-namespace quic {
-
-class QUIC_EXPORT_PRIVATE Bbr2Sender final : public SendAlgorithmInterface {
- public:
- Bbr2Sender(QuicTime now,
- const RttStats* rtt_stats,
- const QuicUnackedPacketMap* unacked_packets,
- QuicPacketCount initial_cwnd_in_packets,
- QuicPacketCount max_cwnd_in_packets,
- QuicRandom* random,
- QuicConnectionStats* stats,
- BbrSender* old_sender);
-
- ~Bbr2Sender() override = default;
-
- // Start implementation of SendAlgorithmInterface.
- bool InSlowStart() const override { return mode_ == Bbr2Mode::STARTUP; }
-
- bool InRecovery() const override {
- // TODO(wub): Implement Recovery.
- return false;
- }
-
- bool ShouldSendProbingPacket() const override;
-
- void SetFromConfig(const QuicConfig& config,
- Perspective perspective) override;
-
- void ApplyConnectionOptions(const QuicTagVector& connection_options) override;
-
- void AdjustNetworkParameters(const NetworkParams& params) override;
-
- void SetInitialCongestionWindowInPackets(
- QuicPacketCount congestion_window) override;
-
- void OnCongestionEvent(bool rtt_updated,
- QuicByteCount prior_in_flight,
- QuicTime event_time,
- const AckedPacketVector& acked_packets,
- const LostPacketVector& lost_packets) override;
-
- void OnPacketSent(QuicTime sent_time,
- QuicByteCount bytes_in_flight,
- QuicPacketNumber packet_number,
- QuicByteCount bytes,
- HasRetransmittableData is_retransmittable) override;
-
- void OnPacketNeutered(QuicPacketNumber packet_number) override;
-
- void OnRetransmissionTimeout(bool /*packets_retransmitted*/) override {}
-
- void OnConnectionMigration() override {}
-
- bool CanSend(QuicByteCount bytes_in_flight) override;
-
- QuicBandwidth PacingRate(QuicByteCount bytes_in_flight) const override;
-
- QuicBandwidth BandwidthEstimate() const override {
- return model_.BandwidthEstimate();
- }
-
- QuicByteCount GetCongestionWindow() const override;
-
- QuicByteCount GetSlowStartThreshold() const override { return 0; }
-
- CongestionControlType GetCongestionControlType() const override {
- return kBBRv2;
- }
-
- std::string GetDebugState() const override;
-
- void OnApplicationLimited(QuicByteCount bytes_in_flight) override;
-
- void PopulateConnectionStats(QuicConnectionStats* stats) const override;
- // End implementation of SendAlgorithmInterface.
-
- const Bbr2Params& Params() const { return params_; }
-
- QuicByteCount GetMinimumCongestionWindow() const {
- return cwnd_limits().Min();
- }
-
- // Returns the min of BDP and congestion window.
- QuicByteCount GetTargetBytesInflight() const;
-
- bool IsBandwidthOverestimateAvoidanceEnabled() const {
- return model_.IsBandwidthOverestimateAvoidanceEnabled();
- }
-
- struct QUIC_EXPORT_PRIVATE DebugState {
- Bbr2Mode mode;
-
- // Shared states.
- QuicRoundTripCount round_trip_count;
- QuicBandwidth bandwidth_hi = QuicBandwidth::Zero();
- QuicBandwidth bandwidth_lo = QuicBandwidth::Zero();
- QuicBandwidth bandwidth_est = QuicBandwidth::Zero();
- QuicByteCount inflight_hi;
- QuicByteCount inflight_lo;
- QuicByteCount max_ack_height;
- QuicTime::Delta min_rtt = QuicTime::Delta::Zero();
- QuicTime min_rtt_timestamp = QuicTime::Zero();
- QuicByteCount congestion_window;
- QuicBandwidth pacing_rate = QuicBandwidth::Zero();
- bool last_sample_is_app_limited;
- QuicPacketNumber end_of_app_limited_phase;
-
- // Mode-specific debug states.
- Bbr2StartupMode::DebugState startup;
- Bbr2DrainMode::DebugState drain;
- Bbr2ProbeBwMode::DebugState probe_bw;
- Bbr2ProbeRttMode::DebugState probe_rtt;
- };
-
- DebugState ExportDebugState() const;
-
- private:
- void UpdatePacingRate(QuicByteCount bytes_acked);
- void UpdateCongestionWindow(QuicByteCount bytes_acked);
- QuicByteCount GetTargetCongestionWindow(float gain) const;
- void OnEnterQuiescence(QuicTime now);
- void OnExitQuiescence(QuicTime now);
-
- // Helper function for BBR2_MODE_DISPATCH.
- Bbr2ProbeRttMode& probe_rtt_or_die() {
- QUICHE_DCHECK_EQ(mode_, Bbr2Mode::PROBE_RTT);
- return probe_rtt_;
- }
-
- const Bbr2ProbeRttMode& probe_rtt_or_die() const {
- QUICHE_DCHECK_EQ(mode_, Bbr2Mode::PROBE_RTT);
- return probe_rtt_;
- }
-
- uint64_t RandomUint64(uint64_t max) const {
- return random_->RandUint64() % max;
- }
-
- // Cwnd limits imposed by the current Bbr2 mode.
- Limits<QuicByteCount> GetCwndLimitsByMode() const;
-
- // Cwnd limits imposed by caller.
- const Limits<QuicByteCount>& cwnd_limits() const;
-
- const Bbr2Params& params() const { return params_; }
-
- Bbr2Mode mode_;
-
- const RttStats* const rtt_stats_;
- const QuicUnackedPacketMap* const unacked_packets_;
- QuicRandom* random_;
- QuicConnectionStats* connection_stats_;
-
- // Don't use it directly outside of SetFromConfig and ApplyConnectionOptions.
- // Instead, use params() to get read-only access.
- Bbr2Params params_;
-
- // Max congestion window when adjusting network parameters.
- QuicByteCount max_cwnd_when_network_parameters_adjusted_ =
- kMaxInitialCongestionWindow * kDefaultTCPMSS;
-
- Bbr2NetworkModel model_;
-
- const QuicByteCount initial_cwnd_;
-
- // Current cwnd and pacing rate.
- QuicByteCount cwnd_;
- QuicBandwidth pacing_rate_;
-
- QuicTime last_quiescence_start_ = QuicTime::Zero();
-
- Bbr2StartupMode startup_;
- Bbr2DrainMode drain_;
- Bbr2ProbeBwMode probe_bw_;
- Bbr2ProbeRttMode probe_rtt_;
-
- // Debug only.
- bool last_sample_is_app_limited_;
-
- friend class Bbr2StartupMode;
- friend class Bbr2DrainMode;
- friend class Bbr2ProbeBwMode;
- friend class Bbr2ProbeRttMode;
-};
-
-QUIC_EXPORT_PRIVATE std::ostream& operator<<(
- std::ostream& os,
- const Bbr2Sender::DebugState& state);
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_CONGESTION_CONTROL_BBR2_SENDER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/congestion_control/bbr2_simulator_test.cc b/chromium/net/third_party/quiche/src/quic/core/congestion_control/bbr2_simulator_test.cc
deleted file mode 100644
index c634db5d4a3..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/congestion_control/bbr2_simulator_test.cc
+++ /dev/null
@@ -1,2296 +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 <memory>
-#include <sstream>
-#include <utility>
-
-#include "absl/strings/str_cat.h"
-#include "absl/types/optional.h"
-#include "quic/core/congestion_control/bbr2_misc.h"
-#include "quic/core/congestion_control/bbr2_sender.h"
-#include "quic/core/congestion_control/bbr_sender.h"
-#include "quic/core/congestion_control/tcp_cubic_sender_bytes.h"
-#include "quic/core/quic_bandwidth.h"
-#include "quic/core/quic_packet_number.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/quic_config_peer.h"
-#include "quic/test_tools/quic_connection_peer.h"
-#include "quic/test_tools/quic_sent_packet_manager_peer.h"
-#include "quic/test_tools/quic_test_utils.h"
-#include "quic/test_tools/send_algorithm_test_result.pb.h"
-#include "quic/test_tools/send_algorithm_test_utils.h"
-#include "quic/test_tools/simulator/link.h"
-#include "quic/test_tools/simulator/quic_endpoint.h"
-#include "quic/test_tools/simulator/simulator.h"
-#include "quic/test_tools/simulator/switch.h"
-#include "quic/test_tools/simulator/traffic_policer.h"
-#include "common/platform/api/quiche_command_line_flags.h"
-
-using testing::AllOf;
-using testing::Ge;
-using testing::Le;
-
-DEFINE_QUICHE_COMMAND_LINE_FLAG(
- std::string, quic_bbr2_test_regression_mode, "",
- "One of a) 'record' to record test result (one file per test), or "
- "b) 'regress' to regress against recorded results, or "
- "c) <anything else> for non-regression mode.");
-
-namespace quic {
-
-using CyclePhase = Bbr2ProbeBwMode::CyclePhase;
-
-namespace test {
-
-// Use the initial CWND of 10, as 32 is too much for the test network.
-const uint32_t kDefaultInitialCwndPackets = 10;
-const uint32_t kDefaultInitialCwndBytes =
- kDefaultInitialCwndPackets * kDefaultTCPMSS;
-
-struct LinkParams {
- LinkParams(int64_t kilo_bits_per_sec, int64_t delay_us)
- : bandwidth(QuicBandwidth::FromKBitsPerSecond(kilo_bits_per_sec)),
- delay(QuicTime::Delta::FromMicroseconds(delay_us)) {}
- QuicBandwidth bandwidth;
- QuicTime::Delta delay;
-};
-
-struct TrafficPolicerParams {
- std::string name = "policer";
- QuicByteCount initial_burst_size;
- QuicByteCount max_bucket_size;
- QuicBandwidth target_bandwidth = QuicBandwidth::Zero();
-};
-
-// All Bbr2DefaultTopologyTests uses the default network topology:
-//
-// Sender
-// |
-// | <-- local_link
-// |
-// Network switch
-// * <-- the bottleneck queue in the direction
-// | of the receiver
-// |
-// | <-- test_link
-// |
-// |
-// Receiver
-class DefaultTopologyParams {
- public:
- LinkParams local_link = {10000, 2000};
- LinkParams test_link = {4000, 30000};
-
- const simulator::SwitchPortNumber switch_port_count = 2;
- // Network switch queue capacity, in number of BDPs.
- float switch_queue_capacity_in_bdp = 2;
-
- absl::optional<TrafficPolicerParams> sender_policer_params;
-
- QuicBandwidth BottleneckBandwidth() const {
- return std::min(local_link.bandwidth, test_link.bandwidth);
- }
-
- // Round trip time of a single full size packet.
- QuicTime::Delta RTT() const {
- return 2 * (local_link.delay + test_link.delay +
- local_link.bandwidth.TransferTime(kMaxOutgoingPacketSize) +
- test_link.bandwidth.TransferTime(kMaxOutgoingPacketSize));
- }
-
- QuicByteCount BDP() const { return BottleneckBandwidth() * RTT(); }
-
- QuicByteCount SwitchQueueCapacity() const {
- return switch_queue_capacity_in_bdp * BDP();
- }
-
- std::string ToString() const {
- std::ostringstream os;
- os << "{ BottleneckBandwidth: " << BottleneckBandwidth()
- << " RTT: " << RTT() << " BDP: " << BDP()
- << " BottleneckQueueSize: " << SwitchQueueCapacity() << "}";
- return os.str();
- }
-};
-
-class Bbr2SimulatorTest : public QuicTest {
- protected:
- Bbr2SimulatorTest() : simulator_(&random_) {
- // Prevent the server(receiver), which only sends acks, from closing
- // connection due to too many outstanding packets.
- SetQuicFlag(FLAGS_quic_max_tracked_packet_count, 1000000);
- }
-
- void SetUp() override {
- if (GetQuicFlag(FLAGS_quic_bbr2_test_regression_mode) == "regress") {
- SendAlgorithmTestResult expected;
- ASSERT_TRUE(LoadSendAlgorithmTestResult(&expected));
- random_seed_ = expected.random_seed();
- } else {
- random_seed_ = QuicRandom::GetInstance()->RandUint64();
- }
- random_.set_seed(random_seed_);
- QUIC_LOG(INFO) << "Using random seed: " << random_seed_;
- }
-
- ~Bbr2SimulatorTest() override {
- const std::string regression_mode =
- GetQuicFlag(FLAGS_quic_bbr2_test_regression_mode);
- const QuicTime::Delta simulated_duration =
- SimulatedNow() - QuicTime::Zero();
- if (regression_mode == "record") {
- RecordSendAlgorithmTestResult(random_seed_,
- simulated_duration.ToMicroseconds());
- } else if (regression_mode == "regress") {
- CompareSendAlgorithmTestResult(simulated_duration.ToMicroseconds());
- }
- }
-
- QuicTime SimulatedNow() const { return simulator_.GetClock()->Now(); }
-
- uint64_t random_seed_;
- SimpleRandom random_;
- simulator::Simulator simulator_;
-};
-
-class Bbr2DefaultTopologyTest : public Bbr2SimulatorTest {
- protected:
- Bbr2DefaultTopologyTest()
- : sender_endpoint_(&simulator_,
- "Sender",
- "Receiver",
- Perspective::IS_CLIENT,
- TestConnectionId(42)),
- receiver_endpoint_(&simulator_,
- "Receiver",
- "Sender",
- Perspective::IS_SERVER,
- TestConnectionId(42)) {
- sender_ = SetupBbr2Sender(&sender_endpoint_, /*old_sender=*/nullptr);
- }
-
- ~Bbr2DefaultTopologyTest() {
- const auto* test_info =
- ::testing::UnitTest::GetInstance()->current_test_info();
- const Bbr2Sender::DebugState& debug_state = sender_->ExportDebugState();
- QUIC_LOG(INFO) << "Bbr2DefaultTopologyTest." << test_info->name()
- << " completed at simulated time: "
- << SimulatedNow().ToDebuggingValue() / 1e6
- << " sec. packet loss:"
- << sender_loss_rate_in_packets() * 100
- << "%, bw_hi:" << debug_state.bandwidth_hi;
- }
-
- QuicUnackedPacketMap* GetUnackedMap(QuicConnection* connection) {
- return QuicSentPacketManagerPeer::GetUnackedPacketMap(
- QuicConnectionPeer::GetSentPacketManager(connection));
- }
-
- Bbr2Sender* SetupBbr2Sender(simulator::QuicEndpoint* endpoint,
- BbrSender* old_sender) {
- // Ownership of the sender will be overtaken by the endpoint.
- Bbr2Sender* sender = new Bbr2Sender(
- endpoint->connection()->clock()->Now(),
- endpoint->connection()->sent_packet_manager().GetRttStats(),
- GetUnackedMap(endpoint->connection()), kDefaultInitialCwndPackets,
- GetQuicFlag(FLAGS_quic_max_congestion_window), &random_,
- QuicConnectionPeer::GetStats(endpoint->connection()), old_sender);
- QuicConnectionPeer::SetSendAlgorithm(endpoint->connection(), sender);
- const int kTestMaxPacketSize = 1350;
- endpoint->connection()->SetMaxPacketLength(kTestMaxPacketSize);
- endpoint->RecordTrace();
- return sender;
- }
-
- void CreateNetwork(const DefaultTopologyParams& params) {
- QUIC_LOG(INFO) << "CreateNetwork with parameters: " << params.ToString();
- switch_ = std::make_unique<simulator::Switch>(&simulator_, "Switch",
- params.switch_port_count,
- params.SwitchQueueCapacity());
-
- // WARNING: The order to add links to network_links_ matters, because some
- // tests adjusts the link bandwidth on the fly.
-
- // Local link connects sender and port 1.
- network_links_.push_back(std::make_unique<simulator::SymmetricLink>(
- &sender_endpoint_, switch_->port(1), params.local_link.bandwidth,
- params.local_link.delay));
-
- // Test link connects receiver and port 2.
- if (params.sender_policer_params.has_value()) {
- const TrafficPolicerParams& policer_params =
- params.sender_policer_params.value();
- sender_policer_ = std::make_unique<simulator::TrafficPolicer>(
- &simulator_, policer_params.name, policer_params.initial_burst_size,
- policer_params.max_bucket_size, policer_params.target_bandwidth,
- switch_->port(2));
- network_links_.push_back(std::make_unique<simulator::SymmetricLink>(
- &receiver_endpoint_, sender_policer_.get(),
- params.test_link.bandwidth, params.test_link.delay));
- } else {
- network_links_.push_back(std::make_unique<simulator::SymmetricLink>(
- &receiver_endpoint_, switch_->port(2), params.test_link.bandwidth,
- params.test_link.delay));
- }
- }
-
- simulator::SymmetricLink* TestLink() { return network_links_[1].get(); }
-
- void DoSimpleTransfer(QuicByteCount transfer_size, QuicTime::Delta timeout) {
- sender_endpoint_.AddBytesToTransfer(transfer_size);
- // TODO(wub): consider rewriting this to run until the receiver actually
- // receives the intended amount of bytes.
- bool simulator_result = simulator_.RunUntilOrTimeout(
- [this]() { return sender_endpoint_.bytes_to_transfer() == 0; },
- timeout);
- EXPECT_TRUE(simulator_result)
- << "Simple transfer failed. Bytes remaining: "
- << sender_endpoint_.bytes_to_transfer();
- QUIC_LOG(INFO) << "Simple transfer state: " << sender_->ExportDebugState();
- }
-
- // Drive the simulator by sending enough data to enter PROBE_BW.
- void DriveOutOfStartup(const DefaultTopologyParams& params) {
- ASSERT_FALSE(sender_->ExportDebugState().startup.full_bandwidth_reached);
- DoSimpleTransfer(1024 * 1024, QuicTime::Delta::FromSeconds(15));
- EXPECT_EQ(Bbr2Mode::PROBE_BW, sender_->ExportDebugState().mode);
- EXPECT_APPROX_EQ(params.BottleneckBandwidth(),
- sender_->ExportDebugState().bandwidth_hi, 0.02f);
- }
-
- // Send |bytes|-sized bursts of data |number_of_bursts| times, waiting for
- // |wait_time| between each burst.
- void SendBursts(const DefaultTopologyParams& params,
- size_t number_of_bursts,
- QuicByteCount bytes,
- QuicTime::Delta wait_time) {
- ASSERT_EQ(0u, sender_endpoint_.bytes_to_transfer());
- for (size_t i = 0; i < number_of_bursts; i++) {
- sender_endpoint_.AddBytesToTransfer(bytes);
-
- // Transfer data and wait for three seconds between each transfer.
- simulator_.RunFor(wait_time);
-
- // Ensure the connection did not time out.
- ASSERT_TRUE(sender_endpoint_.connection()->connected());
- ASSERT_TRUE(receiver_endpoint_.connection()->connected());
- }
-
- simulator_.RunFor(wait_time + params.RTT());
- ASSERT_EQ(0u, sender_endpoint_.bytes_to_transfer());
- }
-
- template <class TerminationPredicate>
- bool SendUntilOrTimeout(TerminationPredicate termination_predicate,
- QuicTime::Delta timeout) {
- EXPECT_EQ(0u, sender_endpoint_.bytes_to_transfer());
- const QuicTime deadline = SimulatedNow() + timeout;
- do {
- sender_endpoint_.AddBytesToTransfer(4 * kDefaultTCPMSS);
- if (simulator_.RunUntilOrTimeout(
- [this]() { return sender_endpoint_.bytes_to_transfer() == 0; },
- deadline - SimulatedNow()) &&
- termination_predicate()) {
- return true;
- }
- } while (SimulatedNow() < deadline);
- return false;
- }
-
- void EnableAggregation(QuicByteCount aggregation_bytes,
- QuicTime::Delta aggregation_timeout) {
- switch_->port_queue(1)->EnableAggregation(aggregation_bytes,
- aggregation_timeout);
- }
-
- void SetConnectionOption(QuicTag option) {
- SetConnectionOption(std::move(option), sender_);
- }
-
- void SetConnectionOption(QuicTag option, Bbr2Sender* sender) {
- QuicConfig config;
- QuicTagVector options;
- options.push_back(option);
- QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
- sender->SetFromConfig(config, Perspective::IS_SERVER);
- }
-
- bool Bbr2ModeIsOneOf(const std::vector<Bbr2Mode>& expected_modes) const {
- const Bbr2Mode mode = sender_->ExportDebugState().mode;
- for (Bbr2Mode expected_mode : expected_modes) {
- if (mode == expected_mode) {
- return true;
- }
- }
- return false;
- }
-
- const RttStats* rtt_stats() {
- return sender_endpoint_.connection()->sent_packet_manager().GetRttStats();
- }
-
- QuicConnection* sender_connection() { return sender_endpoint_.connection(); }
-
- Bbr2Sender::DebugState sender_debug_state() const {
- return sender_->ExportDebugState();
- }
-
- const QuicConnectionStats& sender_connection_stats() {
- return sender_connection()->GetStats();
- }
-
- QuicUnackedPacketMap* sender_unacked_map() {
- return GetUnackedMap(sender_connection());
- }
-
- float sender_loss_rate_in_packets() {
- return static_cast<float>(sender_connection_stats().packets_lost) /
- sender_connection_stats().packets_sent;
- }
-
- simulator::QuicEndpoint sender_endpoint_;
- simulator::QuicEndpoint receiver_endpoint_;
- Bbr2Sender* sender_;
-
- std::unique_ptr<simulator::Switch> switch_;
- std::unique_ptr<simulator::TrafficPolicer> sender_policer_;
- std::vector<std::unique_ptr<simulator::SymmetricLink>> network_links_;
-};
-
-TEST_F(Bbr2DefaultTopologyTest, NormalStartup) {
- DefaultTopologyParams params;
- CreateNetwork(params);
-
- // Run until the full bandwidth is reached and check how many rounds it was.
- sender_endpoint_.AddBytesToTransfer(12 * 1024 * 1024);
- QuicRoundTripCount max_bw_round = 0;
- QuicBandwidth max_bw(QuicBandwidth::Zero());
- bool simulator_result = simulator_.RunUntilOrTimeout(
- [this, &max_bw, &max_bw_round]() {
- if (max_bw < sender_->ExportDebugState().bandwidth_hi) {
- max_bw = sender_->ExportDebugState().bandwidth_hi;
- max_bw_round = sender_->ExportDebugState().round_trip_count;
- }
- return sender_->ExportDebugState().startup.full_bandwidth_reached;
- },
- QuicTime::Delta::FromSeconds(5));
- ASSERT_TRUE(simulator_result);
- EXPECT_EQ(Bbr2Mode::DRAIN, sender_->ExportDebugState().mode);
- EXPECT_EQ(3u, sender_->ExportDebugState().round_trip_count - max_bw_round);
- EXPECT_EQ(
- 3u,
- sender_->ExportDebugState().startup.round_trips_without_bandwidth_growth);
- EXPECT_EQ(0u, sender_connection_stats().packets_lost);
- EXPECT_APPROX_EQ(params.BottleneckBandwidth(),
- sender_->ExportDebugState().bandwidth_hi, 0.01f);
- EXPECT_FALSE(sender_->ExportDebugState().last_sample_is_app_limited);
-}
-
-TEST_F(Bbr2DefaultTopologyTest, NormalStartupB207) {
- SetQuicReloadableFlag(quic_bbr2_exit_startup_on_persistent_queue2, true);
- SetConnectionOption(kB207);
- DefaultTopologyParams params;
- CreateNetwork(params);
-
- // Run until the full bandwidth is reached and check how many rounds it was.
- sender_endpoint_.AddBytesToTransfer(12 * 1024 * 1024);
- QuicRoundTripCount max_bw_round = 0;
- QuicBandwidth max_bw(QuicBandwidth::Zero());
- bool simulator_result = simulator_.RunUntilOrTimeout(
- [this, &max_bw, &max_bw_round]() {
- if (max_bw < sender_->ExportDebugState().bandwidth_hi) {
- max_bw = sender_->ExportDebugState().bandwidth_hi;
- max_bw_round = sender_->ExportDebugState().round_trip_count;
- }
- return sender_->ExportDebugState().startup.full_bandwidth_reached;
- },
- QuicTime::Delta::FromSeconds(5));
- ASSERT_TRUE(simulator_result);
- EXPECT_EQ(Bbr2Mode::DRAIN, sender_->ExportDebugState().mode);
- EXPECT_EQ(1u, sender_->ExportDebugState().round_trip_count - max_bw_round);
- EXPECT_EQ(
- 1u,
- sender_->ExportDebugState().startup.round_trips_without_bandwidth_growth);
- EXPECT_APPROX_EQ(params.BottleneckBandwidth(),
- sender_->ExportDebugState().bandwidth_hi, 0.01f);
- EXPECT_EQ(0u, sender_connection_stats().packets_lost);
-}
-
-// Add extra_acked to CWND in STARTUP and exit STARTUP on a persistent queue.
-TEST_F(Bbr2DefaultTopologyTest, NormalStartupB207andB205) {
- SetQuicReloadableFlag(quic_bbr2_startup_extra_acked, true);
- SetQuicReloadableFlag(quic_bbr2_exit_startup_on_persistent_queue2, true);
- SetConnectionOption(kB205);
- SetConnectionOption(kB207);
- DefaultTopologyParams params;
- CreateNetwork(params);
-
- // Run until the full bandwidth is reached and check how many rounds it was.
- sender_endpoint_.AddBytesToTransfer(12 * 1024 * 1024);
- QuicRoundTripCount max_bw_round = 0;
- QuicBandwidth max_bw(QuicBandwidth::Zero());
- bool simulator_result = simulator_.RunUntilOrTimeout(
- [this, &max_bw, &max_bw_round]() {
- if (max_bw < sender_->ExportDebugState().bandwidth_hi) {
- max_bw = sender_->ExportDebugState().bandwidth_hi;
- max_bw_round = sender_->ExportDebugState().round_trip_count;
- }
- return sender_->ExportDebugState().startup.full_bandwidth_reached;
- },
- QuicTime::Delta::FromSeconds(5));
- ASSERT_TRUE(simulator_result);
- EXPECT_EQ(Bbr2Mode::DRAIN, sender_->ExportDebugState().mode);
- EXPECT_EQ(1u, sender_->ExportDebugState().round_trip_count - max_bw_round);
- EXPECT_EQ(
- 2u,
- sender_->ExportDebugState().startup.round_trips_without_bandwidth_growth);
- EXPECT_APPROX_EQ(params.BottleneckBandwidth(),
- sender_->ExportDebugState().bandwidth_hi, 0.01f);
- EXPECT_EQ(0u, sender_connection_stats().packets_lost);
-}
-
-// Test a simple long data transfer in the default setup.
-TEST_F(Bbr2DefaultTopologyTest, SimpleTransfer) {
- DefaultTopologyParams params;
- CreateNetwork(params);
-
- // At startup make sure we are at the default.
- EXPECT_EQ(kDefaultInitialCwndBytes, sender_->GetCongestionWindow());
- // At startup make sure we can send.
- EXPECT_TRUE(sender_->CanSend(0));
- // And that window is un-affected.
- EXPECT_EQ(kDefaultInitialCwndBytes, sender_->GetCongestionWindow());
-
- // Verify that Sender is in slow start.
- EXPECT_TRUE(sender_->InSlowStart());
-
- // Verify that pacing rate is based on the initial RTT.
- QuicBandwidth expected_pacing_rate = QuicBandwidth::FromBytesAndTimeDelta(
- 2.885 * kDefaultInitialCwndBytes, rtt_stats()->initial_rtt());
- EXPECT_APPROX_EQ(expected_pacing_rate.ToBitsPerSecond(),
- sender_->PacingRate(0).ToBitsPerSecond(), 0.01f);
-
- ASSERT_GE(params.BDP(), kDefaultInitialCwndBytes + kDefaultTCPMSS);
-
- DoSimpleTransfer(12 * 1024 * 1024, QuicTime::Delta::FromSeconds(30));
- EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
- EXPECT_EQ(0u, sender_connection_stats().packets_lost);
- EXPECT_FALSE(sender_->ExportDebugState().last_sample_is_app_limited);
-
- // The margin here is quite high, since there exists a possibility that the
- // connection just exited high gain cycle.
- EXPECT_APPROX_EQ(params.RTT(), rtt_stats()->smoothed_rtt(), 1.0f);
-}
-
-TEST_F(Bbr2DefaultTopologyTest, SimpleTransferB2RC) {
- SetConnectionOption(kB2RC);
- DefaultTopologyParams params;
- CreateNetwork(params);
-
- // Transfer 12MB.
- DoSimpleTransfer(12 * 1024 * 1024, QuicTime::Delta::FromSeconds(35));
- EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
-
- EXPECT_APPROX_EQ(params.BottleneckBandwidth(),
- sender_->ExportDebugState().bandwidth_hi, 0.01f);
-
- EXPECT_LE(sender_loss_rate_in_packets(), 0.05);
- // The margin here is high, because the aggregation greatly increases
- // smoothed rtt.
- EXPECT_GE(params.RTT() * 4, rtt_stats()->smoothed_rtt());
- EXPECT_APPROX_EQ(params.RTT(), rtt_stats()->min_rtt(), 0.2f);
-}
-
-TEST_F(Bbr2DefaultTopologyTest, SimpleTransferB201) {
- SetConnectionOption(kB201);
- DefaultTopologyParams params;
- CreateNetwork(params);
-
- // Transfer 12MB.
- DoSimpleTransfer(12 * 1024 * 1024, QuicTime::Delta::FromSeconds(35));
- EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
-
- EXPECT_APPROX_EQ(params.BottleneckBandwidth(),
- sender_->ExportDebugState().bandwidth_hi, 0.01f);
-
- EXPECT_LE(sender_loss_rate_in_packets(), 0.05);
- // The margin here is high, because the aggregation greatly increases
- // smoothed rtt.
- EXPECT_GE(params.RTT() * 4, rtt_stats()->smoothed_rtt());
- EXPECT_APPROX_EQ(params.RTT(), rtt_stats()->min_rtt(), 0.2f);
-}
-
-TEST_F(Bbr2DefaultTopologyTest, SimpleTransferB206) {
- SetQuicReloadableFlag(quic_bbr2_startup_probe_up_loss_events, true);
- SetConnectionOption(kB206);
- DefaultTopologyParams params;
- CreateNetwork(params);
-
- // Transfer 12MB.
- DoSimpleTransfer(12 * 1024 * 1024, QuicTime::Delta::FromSeconds(35));
- EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
-
- EXPECT_APPROX_EQ(params.BottleneckBandwidth(),
- sender_->ExportDebugState().bandwidth_hi, 0.01f);
-
- EXPECT_LE(sender_loss_rate_in_packets(), 0.05);
- // The margin here is high, because the aggregation greatly increases
- // smoothed rtt.
- EXPECT_GE(params.RTT() * 4, rtt_stats()->smoothed_rtt());
- EXPECT_APPROX_EQ(params.RTT(), rtt_stats()->min_rtt(), 0.2f);
-}
-
-TEST_F(Bbr2DefaultTopologyTest, SimpleTransferB207) {
- SetQuicReloadableFlag(quic_bbr2_exit_startup_on_persistent_queue2, true);
- SetConnectionOption(kB207);
- DefaultTopologyParams params;
- CreateNetwork(params);
-
- // Transfer 12MB.
- DoSimpleTransfer(12 * 1024 * 1024, QuicTime::Delta::FromSeconds(35));
- EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
-
- EXPECT_APPROX_EQ(params.BottleneckBandwidth(),
- sender_->ExportDebugState().bandwidth_hi, 0.01f);
-
- EXPECT_LE(sender_loss_rate_in_packets(), 0.05);
- // The margin here is high, because the aggregation greatly increases
- // smoothed rtt.
- EXPECT_GE(params.RTT() * 4, rtt_stats()->smoothed_rtt());
- EXPECT_APPROX_EQ(params.RTT(), rtt_stats()->min_rtt(), 0.2f);
-}
-
-TEST_F(Bbr2DefaultTopologyTest, SimpleTransferBBRB) {
- SetQuicReloadableFlag(quic_bbr_use_send_rate_in_max_ack_height_tracker, true);
- SetConnectionOption(kBBRB);
- DefaultTopologyParams params;
- CreateNetwork(params);
-
- // Transfer 12MB.
- DoSimpleTransfer(12 * 1024 * 1024, QuicTime::Delta::FromSeconds(35));
- EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
-
- EXPECT_APPROX_EQ(params.BottleneckBandwidth(),
- sender_->ExportDebugState().bandwidth_hi, 0.01f);
-
- EXPECT_LE(sender_loss_rate_in_packets(), 0.05);
- // The margin here is high, because the aggregation greatly increases
- // smoothed rtt.
- EXPECT_GE(params.RTT() * 4, rtt_stats()->smoothed_rtt());
- EXPECT_APPROX_EQ(params.RTT(), rtt_stats()->min_rtt(), 0.2f);
-}
-
-TEST_F(Bbr2DefaultTopologyTest, SimpleTransferBBR4) {
- SetQuicReloadableFlag(quic_bbr2_extra_acked_window, true);
- SetConnectionOption(kBBR4);
- DefaultTopologyParams params;
- CreateNetwork(params);
-
- // Transfer 12MB.
- DoSimpleTransfer(12 * 1024 * 1024, QuicTime::Delta::FromSeconds(35));
- EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
-
- EXPECT_APPROX_EQ(params.BottleneckBandwidth(),
- sender_->ExportDebugState().bandwidth_hi, 0.01f);
-
- EXPECT_LE(sender_loss_rate_in_packets(), 0.05);
- // The margin here is high, because the aggregation greatly increases
- // smoothed rtt.
- EXPECT_GE(params.RTT() * 4, rtt_stats()->smoothed_rtt());
- EXPECT_APPROX_EQ(params.RTT(), rtt_stats()->min_rtt(), 0.2f);
-}
-
-TEST_F(Bbr2DefaultTopologyTest, SimpleTransferBBR5) {
- SetQuicReloadableFlag(quic_bbr2_extra_acked_window, true);
- SetConnectionOption(kBBR5);
- DefaultTopologyParams params;
- CreateNetwork(params);
-
- // Transfer 12MB.
- DoSimpleTransfer(12 * 1024 * 1024, QuicTime::Delta::FromSeconds(35));
- EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
-
- EXPECT_APPROX_EQ(params.BottleneckBandwidth(),
- sender_->ExportDebugState().bandwidth_hi, 0.01f);
-
- EXPECT_LE(sender_loss_rate_in_packets(), 0.05);
- // The margin here is high, because the aggregation greatly increases
- // smoothed rtt.
- EXPECT_GE(params.RTT() * 4, rtt_stats()->smoothed_rtt());
- EXPECT_APPROX_EQ(params.RTT(), rtt_stats()->min_rtt(), 0.2f);
-}
-
-TEST_F(Bbr2DefaultTopologyTest, SimpleTransferSmallBuffer) {
- DefaultTopologyParams params;
- params.switch_queue_capacity_in_bdp = 0.5;
- CreateNetwork(params);
-
- DoSimpleTransfer(12 * 1024 * 1024, QuicTime::Delta::FromSeconds(30));
- EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
- EXPECT_APPROX_EQ(params.BottleneckBandwidth(),
- sender_->ExportDebugState().bandwidth_hi, 0.02f);
- EXPECT_GE(sender_connection_stats().packets_lost, 0u);
- EXPECT_FALSE(sender_->ExportDebugState().last_sample_is_app_limited);
-}
-
-TEST_F(Bbr2DefaultTopologyTest, SimpleTransferSmallBufferB2H2) {
- SetConnectionOption(kB2H2);
- DefaultTopologyParams params;
- params.switch_queue_capacity_in_bdp = 0.5;
- CreateNetwork(params);
-
- DoSimpleTransfer(12 * 1024 * 1024, QuicTime::Delta::FromSeconds(30));
- EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
- EXPECT_APPROX_EQ(params.BottleneckBandwidth(),
- sender_->ExportDebugState().bandwidth_hi, 0.02f);
- EXPECT_GE(sender_connection_stats().packets_lost, 0u);
- EXPECT_FALSE(sender_->ExportDebugState().last_sample_is_app_limited);
-}
-
-TEST_F(Bbr2DefaultTopologyTest, SimpleTransfer2RTTAggregationBytes) {
- SetConnectionOption(kBSAO);
- DefaultTopologyParams params;
- CreateNetwork(params);
- // 2 RTTs of aggregation, with a max of 10kb.
- EnableAggregation(10 * 1024, 2 * params.RTT());
-
- // Transfer 12MB.
- DoSimpleTransfer(12 * 1024 * 1024, QuicTime::Delta::FromSeconds(35));
- EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
-
- EXPECT_APPROX_EQ(params.BottleneckBandwidth(),
- sender_->ExportDebugState().bandwidth_hi, 0.01f);
-
- if (GetQuicReloadableFlag(quic_fix_pacing_sender_bursts)) {
- EXPECT_EQ(sender_loss_rate_in_packets(), 0);
- } else {
- EXPECT_LE(sender_loss_rate_in_packets(), 0.05);
- }
- // The margin here is high, because both link level aggregation and ack
- // decimation can greatly increase smoothed rtt.
- EXPECT_GE(params.RTT() * 5, rtt_stats()->smoothed_rtt());
- EXPECT_APPROX_EQ(params.RTT(), rtt_stats()->min_rtt(), 0.2f);
-}
-
-TEST_F(Bbr2DefaultTopologyTest, SimpleTransfer2RTTAggregationBytesB201) {
- SetConnectionOption(kB201);
- DefaultTopologyParams params;
- CreateNetwork(params);
- // 2 RTTs of aggregation, with a max of 10kb.
- EnableAggregation(10 * 1024, 2 * params.RTT());
-
- // Transfer 12MB.
- DoSimpleTransfer(12 * 1024 * 1024, QuicTime::Delta::FromSeconds(35));
- EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
-
- // TODO(wub): Tighten the error bound once BSAO is default enabled.
- EXPECT_APPROX_EQ(params.BottleneckBandwidth(),
- sender_->ExportDebugState().bandwidth_hi, 0.5f);
-
- if (GetQuicReloadableFlag(quic_fix_pacing_sender_bursts)) {
- EXPECT_LE(sender_loss_rate_in_packets(), 0.01);
- } else {
- EXPECT_LE(sender_loss_rate_in_packets(), 0.05);
- }
- // The margin here is high, because both link level aggregation and ack
- // decimation can greatly increase smoothed rtt.
- EXPECT_GE(params.RTT() * 5, rtt_stats()->smoothed_rtt());
- EXPECT_APPROX_EQ(params.RTT(), rtt_stats()->min_rtt(), 0.2f);
-}
-
-TEST_F(Bbr2DefaultTopologyTest, SimpleTransferAckDecimation) {
- SetConnectionOption(kBSAO);
- DefaultTopologyParams params;
- CreateNetwork(params);
-
- // Transfer 12MB.
- DoSimpleTransfer(12 * 1024 * 1024, QuicTime::Delta::FromSeconds(35));
- EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
-
- EXPECT_APPROX_EQ(params.BottleneckBandwidth(),
- sender_->ExportDebugState().bandwidth_hi, 0.01f);
-
- EXPECT_LE(sender_loss_rate_in_packets(), 0.001);
- EXPECT_FALSE(sender_->ExportDebugState().last_sample_is_app_limited);
- // The margin here is high, because the aggregation greatly increases
- // smoothed rtt.
- EXPECT_GE(params.RTT() * 3, rtt_stats()->smoothed_rtt());
- EXPECT_APPROX_EQ(params.RTT(), rtt_stats()->min_rtt(), 0.1f);
-}
-
-// Test Bbr2's reaction to a 100x bandwidth decrease during a transfer.
-TEST_F(Bbr2DefaultTopologyTest, QUIC_SLOW_TEST(BandwidthDecrease)) {
- DefaultTopologyParams params;
- params.local_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(15000);
- params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(10000);
- CreateNetwork(params);
-
- sender_endpoint_.AddBytesToTransfer(20 * 1024 * 1024);
-
- // We can transfer ~12MB in the first 10 seconds. The rest ~8MB needs about
- // 640 seconds.
- simulator_.RunFor(QuicTime::Delta::FromSeconds(10));
- EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
- QUIC_LOG(INFO) << "Bandwidth decreasing at time " << SimulatedNow();
-
- EXPECT_APPROX_EQ(params.test_link.bandwidth,
- sender_->ExportDebugState().bandwidth_est, 0.1f);
- EXPECT_EQ(0u, sender_connection_stats().packets_lost);
-
- // Now decrease the bottleneck bandwidth from 10Mbps to 100Kbps.
- params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(100);
- TestLink()->set_bandwidth(params.test_link.bandwidth);
-
- bool simulator_result = simulator_.RunUntilOrTimeout(
- [this]() { return sender_endpoint_.bytes_to_transfer() == 0; },
- QuicTime::Delta::FromSeconds(800));
- EXPECT_TRUE(simulator_result);
-}
-
-// Test Bbr2's reaction to a 100x bandwidth increase during a transfer.
-TEST_F(Bbr2DefaultTopologyTest, QUIC_SLOW_TEST(BandwidthIncrease)) {
- DefaultTopologyParams params;
- params.local_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(15000);
- params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(100);
- CreateNetwork(params);
-
- sender_endpoint_.AddBytesToTransfer(20 * 1024 * 1024);
-
- simulator_.RunFor(QuicTime::Delta::FromSeconds(15));
- EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
- QUIC_LOG(INFO) << "Bandwidth increasing at time " << SimulatedNow();
-
- EXPECT_APPROX_EQ(params.test_link.bandwidth,
- sender_->ExportDebugState().bandwidth_est, 0.1f);
- EXPECT_LE(sender_loss_rate_in_packets(), 0.30);
-
- // Now increase the bottleneck bandwidth from 100Kbps to 10Mbps.
- params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(10000);
- TestLink()->set_bandwidth(params.test_link.bandwidth);
-
- bool simulator_result = simulator_.RunUntilOrTimeout(
- [this]() { return sender_endpoint_.bytes_to_transfer() == 0; },
- QuicTime::Delta::FromSeconds(50));
- EXPECT_TRUE(simulator_result);
- // Ensure the full bandwidth is discovered.
- EXPECT_APPROX_EQ(params.test_link.bandwidth,
- sender_->ExportDebugState().bandwidth_hi, 0.02f);
-}
-
-// Test Bbr2's reaction to a 100x bandwidth increase during a transfer with BBQ0
-TEST_F(Bbr2DefaultTopologyTest, QUIC_SLOW_TEST(BandwidthIncreaseBBQ0)) {
- SetQuicReloadableFlag(quic_bbr2_add_bytes_acked_after_inflight_hi_limited,
- true);
- SetConnectionOption(kBBQ0);
- DefaultTopologyParams params;
- params.local_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(15000);
- params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(100);
- CreateNetwork(params);
-
- sender_endpoint_.AddBytesToTransfer(10 * 1024 * 1024);
-
- simulator_.RunFor(QuicTime::Delta::FromSeconds(15));
- EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
- QUIC_LOG(INFO) << "Bandwidth increasing at time " << SimulatedNow();
-
- EXPECT_APPROX_EQ(params.test_link.bandwidth,
- sender_->ExportDebugState().bandwidth_est, 0.1f);
- EXPECT_LE(sender_loss_rate_in_packets(), 0.30);
-
- // Now increase the bottleneck bandwidth from 100Kbps to 10Mbps.
- params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(10000);
- TestLink()->set_bandwidth(params.test_link.bandwidth);
-
- bool simulator_result = simulator_.RunUntilOrTimeout(
- [this]() { return sender_endpoint_.bytes_to_transfer() == 0; },
- QuicTime::Delta::FromSeconds(50));
- EXPECT_TRUE(simulator_result);
- // Ensure the full bandwidth is discovered.
- EXPECT_APPROX_EQ(params.test_link.bandwidth,
- sender_->ExportDebugState().bandwidth_hi, 0.02f);
-}
-
-// Test Bbr2's reaction to a 100x bandwidth increase during a transfer with BBQ0
-// in the presence of ACK aggregation.
-TEST_F(Bbr2DefaultTopologyTest,
- QUIC_SLOW_TEST(BandwidthIncreaseBBQ0Aggregation)) {
- SetQuicReloadableFlag(quic_bbr2_add_bytes_acked_after_inflight_hi_limited,
- true);
- SetConnectionOption(kBBQ0);
- DefaultTopologyParams params;
- params.local_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(15000);
- params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(100);
- CreateNetwork(params);
-
- // 2 RTTs of aggregation, with a max of 10kb.
- EnableAggregation(10 * 1024, 2 * params.RTT());
-
- // Reduce the payload to 2MB because 10MB takes too long.
- sender_endpoint_.AddBytesToTransfer(2 * 1024 * 1024);
-
- simulator_.RunFor(QuicTime::Delta::FromSeconds(15));
- EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
- QUIC_LOG(INFO) << "Bandwidth increasing at time " << SimulatedNow();
-
- // This is much farther off when aggregation is present,
- // Ideally BSAO or another option would fix this.
- // TODO(ianswett) Make these bound tighter once overestimation is reduced.
- EXPECT_APPROX_EQ(params.test_link.bandwidth,
- sender_->ExportDebugState().bandwidth_est, 0.6f);
- EXPECT_LE(sender_loss_rate_in_packets(), 0.35);
-
- // Now increase the bottleneck bandwidth from 100Kbps to 10Mbps.
- params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(10000);
- TestLink()->set_bandwidth(params.test_link.bandwidth);
-
- bool simulator_result = simulator_.RunUntilOrTimeout(
- [this]() { return sender_endpoint_.bytes_to_transfer() == 0; },
- QuicTime::Delta::FromSeconds(50));
- EXPECT_TRUE(simulator_result);
- // Ensure at least 10% of full bandwidth is discovered.
- EXPECT_APPROX_EQ(params.test_link.bandwidth,
- sender_->ExportDebugState().bandwidth_hi, 0.90f);
-}
-
-// Test Bbr2's reaction to a 100x bandwidth increase during a transfer with B202
-TEST_F(Bbr2DefaultTopologyTest, QUIC_SLOW_TEST(BandwidthIncreaseB202)) {
- SetQuicReloadableFlag(quic_bbr2_no_probe_up_exit_if_no_queue, true);
- SetConnectionOption(kB202);
- DefaultTopologyParams params;
- params.local_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(15000);
- params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(100);
- CreateNetwork(params);
-
- sender_endpoint_.AddBytesToTransfer(10 * 1024 * 1024);
-
- simulator_.RunFor(QuicTime::Delta::FromSeconds(15));
- EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
- QUIC_LOG(INFO) << "Bandwidth increasing at time " << SimulatedNow();
-
- EXPECT_APPROX_EQ(params.test_link.bandwidth,
- sender_->ExportDebugState().bandwidth_est, 0.1f);
- EXPECT_LE(sender_loss_rate_in_packets(), 0.30);
-
- // Now increase the bottleneck bandwidth from 100Kbps to 10Mbps.
- params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(10000);
- TestLink()->set_bandwidth(params.test_link.bandwidth);
-
- bool simulator_result = simulator_.RunUntilOrTimeout(
- [this]() { return sender_endpoint_.bytes_to_transfer() == 0; },
- QuicTime::Delta::FromSeconds(50));
- EXPECT_TRUE(simulator_result);
- // Ensure the full bandwidth is discovered.
- EXPECT_APPROX_EQ(params.test_link.bandwidth,
- sender_->ExportDebugState().bandwidth_hi, 0.1f);
-}
-
-// Test Bbr2's reaction to a 100x bandwidth increase during a transfer with B202
-// in the presence of ACK aggregation.
-TEST_F(Bbr2DefaultTopologyTest,
- QUIC_SLOW_TEST(BandwidthIncreaseB202Aggregation)) {
- SetQuicReloadableFlag(quic_bbr2_no_probe_up_exit_if_no_queue, true);
- SetConnectionOption(kB202);
- DefaultTopologyParams params;
- params.local_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(15000);
- params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(100);
- CreateNetwork(params);
-
- // 2 RTTs of aggregation, with a max of 10kb.
- EnableAggregation(10 * 1024, 2 * params.RTT());
-
- // Reduce the payload to 2MB because 10MB takes too long.
- sender_endpoint_.AddBytesToTransfer(2 * 1024 * 1024);
-
- simulator_.RunFor(QuicTime::Delta::FromSeconds(15));
- EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
- QUIC_LOG(INFO) << "Bandwidth increasing at time " << SimulatedNow();
-
- // This is much farther off when aggregation is present,
- // Ideally BSAO or another option would fix this.
- EXPECT_APPROX_EQ(params.test_link.bandwidth,
- sender_->ExportDebugState().bandwidth_est, 0.6f);
- EXPECT_LE(sender_loss_rate_in_packets(), 0.35);
-
- // Now increase the bottleneck bandwidth from 100Kbps to 10Mbps.
- params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(10000);
- TestLink()->set_bandwidth(params.test_link.bandwidth);
-
- bool simulator_result = simulator_.RunUntilOrTimeout(
- [this]() { return sender_endpoint_.bytes_to_transfer() == 0; },
- QuicTime::Delta::FromSeconds(50));
- EXPECT_TRUE(simulator_result);
- // Ensure at least 10% of full bandwidth is discovered.
- EXPECT_APPROX_EQ(params.test_link.bandwidth,
- sender_->ExportDebugState().bandwidth_hi, 0.92f);
-}
-
-// Test Bbr2's reaction to a 100x bandwidth increase during a transfer with B203
-TEST_F(Bbr2DefaultTopologyTest, QUIC_SLOW_TEST(BandwidthIncreaseB203)) {
- SetQuicReloadableFlag(quic_bbr2_ignore_inflight_hi_in_probe_up, true);
- SetConnectionOption(kB203);
- DefaultTopologyParams params;
- params.local_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(15000);
- params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(100);
- CreateNetwork(params);
-
- sender_endpoint_.AddBytesToTransfer(10 * 1024 * 1024);
-
- simulator_.RunFor(QuicTime::Delta::FromSeconds(15));
- EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
- QUIC_LOG(INFO) << "Bandwidth increasing at time " << SimulatedNow();
-
- EXPECT_APPROX_EQ(params.test_link.bandwidth,
- sender_->ExportDebugState().bandwidth_est, 0.1f);
- EXPECT_LE(sender_loss_rate_in_packets(), 0.30);
-
- // Now increase the bottleneck bandwidth from 100Kbps to 10Mbps.
- params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(10000);
- TestLink()->set_bandwidth(params.test_link.bandwidth);
-
- bool simulator_result = simulator_.RunUntilOrTimeout(
- [this]() { return sender_endpoint_.bytes_to_transfer() == 0; },
- QuicTime::Delta::FromSeconds(50));
- EXPECT_TRUE(simulator_result);
- // Ensure the full bandwidth is discovered.
- EXPECT_APPROX_EQ(params.test_link.bandwidth,
- sender_->ExportDebugState().bandwidth_hi, 0.02f);
-}
-
-// Test Bbr2's reaction to a 100x bandwidth increase during a transfer with B203
-// in the presence of ACK aggregation.
-TEST_F(Bbr2DefaultTopologyTest,
- QUIC_SLOW_TEST(BandwidthIncreaseB203Aggregation)) {
- SetQuicReloadableFlag(quic_bbr2_ignore_inflight_hi_in_probe_up, true);
- SetConnectionOption(kB203);
- DefaultTopologyParams params;
- params.local_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(15000);
- params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(100);
- CreateNetwork(params);
-
- // 2 RTTs of aggregation, with a max of 10kb.
- EnableAggregation(10 * 1024, 2 * params.RTT());
-
- // Reduce the payload to 2MB because 10MB takes too long.
- sender_endpoint_.AddBytesToTransfer(2 * 1024 * 1024);
-
- simulator_.RunFor(QuicTime::Delta::FromSeconds(15));
- EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
- QUIC_LOG(INFO) << "Bandwidth increasing at time " << SimulatedNow();
-
- // This is much farther off when aggregation is present,
- // Ideally BSAO or another option would fix this.
- EXPECT_APPROX_EQ(params.test_link.bandwidth,
- sender_->ExportDebugState().bandwidth_est, 0.60f);
- EXPECT_LE(sender_loss_rate_in_packets(), 0.35);
-
- // Now increase the bottleneck bandwidth from 100Kbps to 10Mbps.
- params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(10000);
- TestLink()->set_bandwidth(params.test_link.bandwidth);
-
- bool simulator_result = simulator_.RunUntilOrTimeout(
- [this]() { return sender_endpoint_.bytes_to_transfer() == 0; },
- QuicTime::Delta::FromSeconds(50));
- EXPECT_TRUE(simulator_result);
- // Ensure at least 10% of full bandwidth is discovered.
- EXPECT_APPROX_EQ(params.test_link.bandwidth,
- sender_->ExportDebugState().bandwidth_hi, 0.91f);
-}
-
-// Test Bbr2's reaction to a 100x bandwidth increase during a transfer with B204
-TEST_F(Bbr2DefaultTopologyTest, QUIC_SLOW_TEST(BandwidthIncreaseB204)) {
- SetQuicReloadableFlag(quic_bbr2_startup_extra_acked, true);
- SetConnectionOption(kB204);
- DefaultTopologyParams params;
- params.local_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(15000);
- params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(100);
- CreateNetwork(params);
-
- sender_endpoint_.AddBytesToTransfer(10 * 1024 * 1024);
-
- simulator_.RunFor(QuicTime::Delta::FromSeconds(15));
- EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
- QUIC_LOG(INFO) << "Bandwidth increasing at time " << SimulatedNow();
-
- EXPECT_APPROX_EQ(params.test_link.bandwidth,
- sender_->ExportDebugState().bandwidth_est, 0.1f);
- EXPECT_LE(sender_loss_rate_in_packets(), 0.25);
- EXPECT_LE(sender_->ExportDebugState().max_ack_height, 2000u);
-
- // Now increase the bottleneck bandwidth from 100Kbps to 10Mbps.
- params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(10000);
- TestLink()->set_bandwidth(params.test_link.bandwidth);
-
- bool simulator_result = simulator_.RunUntilOrTimeout(
- [this]() { return sender_endpoint_.bytes_to_transfer() == 0; },
- QuicTime::Delta::FromSeconds(50));
- EXPECT_TRUE(simulator_result);
- // Ensure the full bandwidth is discovered.
- EXPECT_APPROX_EQ(params.test_link.bandwidth,
- sender_->ExportDebugState().bandwidth_hi, 0.02f);
-}
-
-// Test Bbr2's reaction to a 100x bandwidth increase during a transfer with B204
-// in the presence of ACK aggregation.
-TEST_F(Bbr2DefaultTopologyTest,
- QUIC_SLOW_TEST(BandwidthIncreaseB204Aggregation)) {
- SetQuicReloadableFlag(quic_bbr2_startup_extra_acked, true);
- SetConnectionOption(kB204);
- DefaultTopologyParams params;
- params.local_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(15000);
- params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(100);
- CreateNetwork(params);
-
- // 2 RTTs of aggregation, with a max of 10kb.
- EnableAggregation(10 * 1024, 2 * params.RTT());
-
- // Reduce the payload to 2MB because 10MB takes too long.
- sender_endpoint_.AddBytesToTransfer(2 * 1024 * 1024);
-
- simulator_.RunFor(QuicTime::Delta::FromSeconds(15));
- EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
- QUIC_LOG(INFO) << "Bandwidth increasing at time " << SimulatedNow();
-
- // This is much farther off when aggregation is present, and B204 actually
- // is increasing overestimation, which is surprising.
- // Ideally BSAO or another option would fix this.
- EXPECT_APPROX_EQ(params.test_link.bandwidth,
- sender_->ExportDebugState().bandwidth_est, 0.60f);
- EXPECT_LE(sender_loss_rate_in_packets(), 0.35);
- EXPECT_LE(sender_->ExportDebugState().max_ack_height, 10000u);
-
- // Now increase the bottleneck bandwidth from 100Kbps to 10Mbps.
- params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(10000);
- TestLink()->set_bandwidth(params.test_link.bandwidth);
-
- bool simulator_result = simulator_.RunUntilOrTimeout(
- [this]() { return sender_endpoint_.bytes_to_transfer() == 0; },
- QuicTime::Delta::FromSeconds(50));
- EXPECT_TRUE(simulator_result);
- // Ensure at least 10% of full bandwidth is discovered.
- EXPECT_APPROX_EQ(params.test_link.bandwidth,
- sender_->ExportDebugState().bandwidth_hi, 0.95f);
-}
-
-// Test Bbr2's reaction to a 100x bandwidth increase during a transfer with B205
-TEST_F(Bbr2DefaultTopologyTest, QUIC_SLOW_TEST(BandwidthIncreaseB205)) {
- SetQuicReloadableFlag(quic_bbr2_startup_extra_acked, true);
- SetConnectionOption(kB205);
- DefaultTopologyParams params;
- params.local_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(15000);
- params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(100);
- CreateNetwork(params);
-
- sender_endpoint_.AddBytesToTransfer(10 * 1024 * 1024);
-
- simulator_.RunFor(QuicTime::Delta::FromSeconds(15));
- EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
- QUIC_LOG(INFO) << "Bandwidth increasing at time " << SimulatedNow();
-
- EXPECT_APPROX_EQ(params.test_link.bandwidth,
- sender_->ExportDebugState().bandwidth_est, 0.1f);
- EXPECT_LE(sender_loss_rate_in_packets(), 0.10);
-
- // Now increase the bottleneck bandwidth from 100Kbps to 10Mbps.
- params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(10000);
- TestLink()->set_bandwidth(params.test_link.bandwidth);
-
- bool simulator_result = simulator_.RunUntilOrTimeout(
- [this]() { return sender_endpoint_.bytes_to_transfer() == 0; },
- QuicTime::Delta::FromSeconds(50));
- EXPECT_TRUE(simulator_result);
- // Ensure the full bandwidth is discovered.
- EXPECT_APPROX_EQ(params.test_link.bandwidth,
- sender_->ExportDebugState().bandwidth_hi, 0.1f);
-}
-
-// Test Bbr2's reaction to a 100x bandwidth increase during a transfer with B205
-// in the presence of ACK aggregation.
-TEST_F(Bbr2DefaultTopologyTest,
- QUIC_SLOW_TEST(BandwidthIncreaseB205Aggregation)) {
- SetQuicReloadableFlag(quic_bbr2_startup_extra_acked, true);
- SetConnectionOption(kB205);
- DefaultTopologyParams params;
- params.local_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(15000);
- params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(100);
- CreateNetwork(params);
-
- // 2 RTTs of aggregation, with a max of 10kb.
- EnableAggregation(10 * 1024, 2 * params.RTT());
-
- // Reduce the payload to 2MB because 10MB takes too long.
- sender_endpoint_.AddBytesToTransfer(2 * 1024 * 1024);
-
- simulator_.RunFor(QuicTime::Delta::FromSeconds(15));
- EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
- QUIC_LOG(INFO) << "Bandwidth increasing at time " << SimulatedNow();
-
- // This is much farther off when aggregation is present,
- // Ideally BSAO or another option would fix this.
- EXPECT_APPROX_EQ(params.test_link.bandwidth,
- sender_->ExportDebugState().bandwidth_est, 0.45f);
- EXPECT_LE(sender_loss_rate_in_packets(), 0.15);
-
- // Now increase the bottleneck bandwidth from 100Kbps to 10Mbps.
- params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(10000);
- TestLink()->set_bandwidth(params.test_link.bandwidth);
-
- bool simulator_result = simulator_.RunUntilOrTimeout(
- [this]() { return sender_endpoint_.bytes_to_transfer() == 0; },
- QuicTime::Delta::FromSeconds(50));
- EXPECT_TRUE(simulator_result);
- // Ensure at least 5% of full bandwidth is discovered.
- EXPECT_APPROX_EQ(params.test_link.bandwidth,
- sender_->ExportDebugState().bandwidth_hi, 0.9f);
-}
-
-// Test the number of losses incurred by the startup phase in a situation when
-// the buffer is less than BDP.
-TEST_F(Bbr2DefaultTopologyTest, PacketLossOnSmallBufferStartup) {
- DefaultTopologyParams params;
- params.switch_queue_capacity_in_bdp = 0.5;
- CreateNetwork(params);
-
- DriveOutOfStartup(params);
- // Packet loss is smaller with a CWND gain of 2 than 2.889.
- EXPECT_LE(sender_loss_rate_in_packets(), 0.05);
-}
-
-// Test the number of losses decreases with packet-conservation pacing.
-TEST_F(Bbr2DefaultTopologyTest, PacketLossBBQ6SmallBufferStartup) {
- SetConnectionOption(kBBQ2); // Increase CWND gain.
- SetConnectionOption(kBBQ6);
- DefaultTopologyParams params;
- params.switch_queue_capacity_in_bdp = 0.5;
- CreateNetwork(params);
-
- DriveOutOfStartup(params);
- EXPECT_LE(sender_loss_rate_in_packets(), 0.0575);
- // bandwidth_lo is cleared exiting STARTUP.
- EXPECT_EQ(sender_->ExportDebugState().bandwidth_lo,
- QuicBandwidth::Infinite());
-}
-
-// Test the number of losses decreases with min_rtt packet-conservation pacing.
-TEST_F(Bbr2DefaultTopologyTest, PacketLossBBQ7SmallBufferStartup) {
- SetConnectionOption(kBBQ2); // Increase CWND gain.
- SetConnectionOption(kBBQ7);
- DefaultTopologyParams params;
- params.switch_queue_capacity_in_bdp = 0.5;
- CreateNetwork(params);
-
- DriveOutOfStartup(params);
- EXPECT_LE(sender_loss_rate_in_packets(), 0.06);
- // bandwidth_lo is cleared exiting STARTUP.
- EXPECT_EQ(sender_->ExportDebugState().bandwidth_lo,
- QuicBandwidth::Infinite());
-}
-
-// Test the number of losses decreases with Inflight packet-conservation pacing.
-TEST_F(Bbr2DefaultTopologyTest, PacketLossBBQ8SmallBufferStartup) {
- SetConnectionOption(kBBQ2); // Increase CWND gain.
- SetConnectionOption(kBBQ8);
- DefaultTopologyParams params;
- params.switch_queue_capacity_in_bdp = 0.5;
- CreateNetwork(params);
-
- DriveOutOfStartup(params);
- EXPECT_LE(sender_loss_rate_in_packets(), 0.065);
- // bandwidth_lo is cleared exiting STARTUP.
- EXPECT_EQ(sender_->ExportDebugState().bandwidth_lo,
- QuicBandwidth::Infinite());
-}
-
-// Test the number of losses decreases with CWND packet-conservation pacing.
-TEST_F(Bbr2DefaultTopologyTest, PacketLossBBQ9SmallBufferStartup) {
- SetConnectionOption(kBBQ2); // Increase CWND gain.
- SetConnectionOption(kBBQ9);
- DefaultTopologyParams params;
- params.switch_queue_capacity_in_bdp = 0.5;
- CreateNetwork(params);
-
- DriveOutOfStartup(params);
- EXPECT_LE(sender_loss_rate_in_packets(), 0.065);
- // bandwidth_lo is cleared exiting STARTUP.
- EXPECT_EQ(sender_->ExportDebugState().bandwidth_lo,
- QuicBandwidth::Infinite());
-}
-
-// Verify the behavior of the algorithm in the case when the connection sends
-// small bursts of data after sending continuously for a while.
-TEST_F(Bbr2DefaultTopologyTest, ApplicationLimitedBursts) {
- DefaultTopologyParams params;
- CreateNetwork(params);
-
- DriveOutOfStartup(params);
- EXPECT_FALSE(sender_->ExportDebugState().last_sample_is_app_limited);
-
- SendBursts(params, 20, 512, QuicTime::Delta::FromSeconds(3));
- EXPECT_TRUE(sender_->ExportDebugState().last_sample_is_app_limited);
- EXPECT_APPROX_EQ(params.BottleneckBandwidth(),
- sender_->ExportDebugState().bandwidth_hi, 0.01f);
-}
-
-// Verify the behavior of the algorithm in the case when the connection sends
-// small bursts of data and then starts sending continuously.
-TEST_F(Bbr2DefaultTopologyTest, ApplicationLimitedBurstsWithoutPrior) {
- DefaultTopologyParams params;
- CreateNetwork(params);
-
- SendBursts(params, 40, 512, QuicTime::Delta::FromSeconds(3));
- EXPECT_TRUE(sender_->ExportDebugState().last_sample_is_app_limited);
-
- DriveOutOfStartup(params);
- EXPECT_APPROX_EQ(params.BottleneckBandwidth(),
- sender_->ExportDebugState().bandwidth_hi, 0.01f);
- EXPECT_FALSE(sender_->ExportDebugState().last_sample_is_app_limited);
-}
-
-// Verify that the DRAIN phase works correctly.
-TEST_F(Bbr2DefaultTopologyTest, Drain) {
- DefaultTopologyParams params;
- CreateNetwork(params);
-
- const QuicTime::Delta timeout = QuicTime::Delta::FromSeconds(10);
- // Get the queue at the bottleneck, which is the outgoing queue at the port to
- // which the receiver is connected.
- const simulator::Queue* queue = switch_->port_queue(2);
- bool simulator_result;
-
- // We have no intention of ever finishing this transfer.
- sender_endpoint_.AddBytesToTransfer(100 * 1024 * 1024);
-
- // Run the startup, and verify that it fills up the queue.
- ASSERT_EQ(Bbr2Mode::STARTUP, sender_->ExportDebugState().mode);
- simulator_result = simulator_.RunUntilOrTimeout(
- [this]() {
- return sender_->ExportDebugState().mode != Bbr2Mode::STARTUP;
- },
- timeout);
- ASSERT_TRUE(simulator_result);
- ASSERT_EQ(Bbr2Mode::DRAIN, sender_->ExportDebugState().mode);
- EXPECT_APPROX_EQ(sender_->BandwidthEstimate() * (1 / 2.885f),
- sender_->PacingRate(0), 0.01f);
-
- // BBR uses CWND gain of 2 during STARTUP, hence it will fill the buffer with
- // approximately 1 BDP. Here, we use 0.95 to give some margin for error.
- EXPECT_GE(queue->bytes_queued(), 0.95 * params.BDP());
-
- // Observe increased RTT due to bufferbloat.
- const QuicTime::Delta queueing_delay =
- params.test_link.bandwidth.TransferTime(queue->bytes_queued());
- EXPECT_APPROX_EQ(params.RTT() + queueing_delay, rtt_stats()->latest_rtt(),
- 0.1f);
-
- // Transition to the drain phase and verify that it makes the queue
- // have at most a BDP worth of packets.
- simulator_result = simulator_.RunUntilOrTimeout(
- [this]() { return sender_->ExportDebugState().mode != Bbr2Mode::DRAIN; },
- timeout);
- ASSERT_TRUE(simulator_result);
- ASSERT_EQ(Bbr2Mode::PROBE_BW, sender_->ExportDebugState().mode);
- EXPECT_LE(queue->bytes_queued(), params.BDP());
-
- // Wait for a few round trips and ensure we're in appropriate phase of gain
- // cycling before taking an RTT measurement.
- const QuicRoundTripCount start_round_trip =
- sender_->ExportDebugState().round_trip_count;
- simulator_result = simulator_.RunUntilOrTimeout(
- [this, start_round_trip]() {
- const auto& debug_state = sender_->ExportDebugState();
- QuicRoundTripCount rounds_passed =
- debug_state.round_trip_count - start_round_trip;
- return rounds_passed >= 4 && debug_state.mode == Bbr2Mode::PROBE_BW &&
- debug_state.probe_bw.phase == CyclePhase::PROBE_REFILL;
- },
- timeout);
- ASSERT_TRUE(simulator_result);
-
- // Observe the bufferbloat go away.
- EXPECT_APPROX_EQ(params.RTT(), rtt_stats()->smoothed_rtt(), 0.1f);
-}
-
-// Ensure that a connection that is app-limited and is at sufficiently low
-// bandwidth will not exit high gain phase, and similarly ensure that the
-// connection will exit low gain early if the number of bytes in flight is low.
-TEST_F(Bbr2DefaultTopologyTest, InFlightAwareGainCycling) {
- DefaultTopologyParams params;
- CreateNetwork(params);
- DriveOutOfStartup(params);
-
- const QuicTime::Delta timeout = QuicTime::Delta::FromSeconds(5);
- bool simulator_result;
-
- // Start a few cycles prior to the high gain one.
- simulator_result = SendUntilOrTimeout(
- [this]() {
- return sender_->ExportDebugState().probe_bw.phase ==
- CyclePhase::PROBE_REFILL;
- },
- timeout);
- ASSERT_TRUE(simulator_result);
-
- // Send at 10% of available rate. Run for 3 seconds, checking in the middle
- // and at the end. The pacing gain should be high throughout.
- QuicBandwidth target_bandwidth = 0.1f * params.BottleneckBandwidth();
- QuicTime::Delta burst_interval = QuicTime::Delta::FromMilliseconds(300);
- for (int i = 0; i < 2; i++) {
- SendBursts(params, 5, target_bandwidth * burst_interval, burst_interval);
- EXPECT_EQ(Bbr2Mode::PROBE_BW, sender_->ExportDebugState().mode);
- EXPECT_EQ(CyclePhase::PROBE_UP, sender_->ExportDebugState().probe_bw.phase);
- EXPECT_APPROX_EQ(params.BottleneckBandwidth(),
- sender_->ExportDebugState().bandwidth_hi, 0.02f);
- }
-
- // Now that in-flight is almost zero and the pacing gain is still above 1,
- // send approximately 1.4 BDPs worth of data. This should cause the PROBE_BW
- // mode to enter low gain cycle(PROBE_DOWN), and exit it earlier than one
- // min_rtt due to running out of data to send.
- sender_endpoint_.AddBytesToTransfer(1.4 * params.BDP());
- simulator_result = simulator_.RunUntilOrTimeout(
- [this]() {
- return sender_->ExportDebugState().probe_bw.phase ==
- CyclePhase::PROBE_DOWN;
- },
- timeout);
- ASSERT_TRUE(simulator_result);
- simulator_.RunFor(0.75 * sender_->ExportDebugState().min_rtt);
- EXPECT_EQ(Bbr2Mode::PROBE_BW, sender_->ExportDebugState().mode);
- EXPECT_EQ(CyclePhase::PROBE_CRUISE,
- sender_->ExportDebugState().probe_bw.phase);
-}
-
-// Test exiting STARTUP earlier upon loss due to loss.
-TEST_F(Bbr2DefaultTopologyTest, ExitStartupDueToLoss) {
- DefaultTopologyParams params;
- params.switch_queue_capacity_in_bdp = 0.5;
- CreateNetwork(params);
-
- // Run until the full bandwidth is reached and check how many rounds it was.
- sender_endpoint_.AddBytesToTransfer(12 * 1024 * 1024);
- QuicRoundTripCount max_bw_round = 0;
- QuicBandwidth max_bw(QuicBandwidth::Zero());
- bool simulator_result = simulator_.RunUntilOrTimeout(
- [this, &max_bw, &max_bw_round]() {
- if (max_bw < sender_->ExportDebugState().bandwidth_hi) {
- max_bw = sender_->ExportDebugState().bandwidth_hi;
- max_bw_round = sender_->ExportDebugState().round_trip_count;
- }
- return sender_->ExportDebugState().startup.full_bandwidth_reached;
- },
- QuicTime::Delta::FromSeconds(5));
- ASSERT_TRUE(simulator_result);
- EXPECT_EQ(Bbr2Mode::DRAIN, sender_->ExportDebugState().mode);
- EXPECT_GE(2u, sender_->ExportDebugState().round_trip_count - max_bw_round);
- EXPECT_EQ(
- 1u,
- sender_->ExportDebugState().startup.round_trips_without_bandwidth_growth);
- EXPECT_NE(0u, sender_connection_stats().packets_lost);
- EXPECT_FALSE(sender_->ExportDebugState().last_sample_is_app_limited);
-
- EXPECT_GT(sender_->ExportDebugState().inflight_hi, 1.2f * params.BDP());
-}
-
-// Test exiting STARTUP earlier upon loss due to loss when connection option
-// B2SL is used.
-TEST_F(Bbr2DefaultTopologyTest, ExitStartupDueToLossB2SL) {
- SetConnectionOption(kB2SL);
- DefaultTopologyParams params;
- params.switch_queue_capacity_in_bdp = 0.5;
- CreateNetwork(params);
-
- // Run until the full bandwidth is reached and check how many rounds it was.
- sender_endpoint_.AddBytesToTransfer(12 * 1024 * 1024);
- QuicRoundTripCount max_bw_round = 0;
- QuicBandwidth max_bw(QuicBandwidth::Zero());
- bool simulator_result = simulator_.RunUntilOrTimeout(
- [this, &max_bw, &max_bw_round]() {
- if (max_bw < sender_->ExportDebugState().bandwidth_hi) {
- max_bw = sender_->ExportDebugState().bandwidth_hi;
- max_bw_round = sender_->ExportDebugState().round_trip_count;
- }
- return sender_->ExportDebugState().startup.full_bandwidth_reached;
- },
- QuicTime::Delta::FromSeconds(5));
- ASSERT_TRUE(simulator_result);
- EXPECT_EQ(Bbr2Mode::DRAIN, sender_->ExportDebugState().mode);
- EXPECT_GE(2u, sender_->ExportDebugState().round_trip_count - max_bw_round);
- EXPECT_EQ(
- 1u,
- sender_->ExportDebugState().startup.round_trips_without_bandwidth_growth);
- EXPECT_NE(0u, sender_connection_stats().packets_lost);
- EXPECT_FALSE(sender_->ExportDebugState().last_sample_is_app_limited);
-
- EXPECT_APPROX_EQ(sender_->ExportDebugState().inflight_hi, params.BDP(), 0.1f);
-}
-
-// Verifies that in STARTUP, if we exceed loss threshold in a round, we exit
-// STARTUP at the end of the round even if there's enough bandwidth growth.
-TEST_F(Bbr2DefaultTopologyTest, ExitStartupDueToLossB2NE) {
- // Set up flags such that any loss will be considered "too high".
- SetQuicFlag(FLAGS_quic_bbr2_default_startup_full_loss_count, 0);
- SetQuicFlag(FLAGS_quic_bbr2_default_loss_threshold, 0.0);
-
- sender_ = SetupBbr2Sender(&sender_endpoint_, /*old_sender=*/nullptr);
-
- SetConnectionOption(kB2NE);
- DefaultTopologyParams params;
- params.switch_queue_capacity_in_bdp = 0.5;
- CreateNetwork(params);
-
- // Run until the full bandwidth is reached and check how many rounds it was.
- sender_endpoint_.AddBytesToTransfer(12 * 1024 * 1024);
- QuicRoundTripCount max_bw_round = 0;
- QuicBandwidth max_bw(QuicBandwidth::Zero());
- bool simulator_result = simulator_.RunUntilOrTimeout(
- [this, &max_bw, &max_bw_round]() {
- if (max_bw < sender_->ExportDebugState().bandwidth_hi) {
- max_bw = sender_->ExportDebugState().bandwidth_hi;
- max_bw_round = sender_->ExportDebugState().round_trip_count;
- }
- return sender_->ExportDebugState().startup.full_bandwidth_reached;
- },
- QuicTime::Delta::FromSeconds(5));
- ASSERT_TRUE(simulator_result);
- EXPECT_EQ(Bbr2Mode::DRAIN, sender_->ExportDebugState().mode);
- EXPECT_EQ(sender_->ExportDebugState().round_trip_count, max_bw_round);
- EXPECT_EQ(
- 0u,
- sender_->ExportDebugState().startup.round_trips_without_bandwidth_growth);
- EXPECT_NE(0u, sender_connection_stats().packets_lost);
-}
-
-TEST_F(Bbr2DefaultTopologyTest, SenderPoliced) {
- DefaultTopologyParams params;
- params.sender_policer_params = TrafficPolicerParams();
- params.sender_policer_params->initial_burst_size = 1000 * 10;
- params.sender_policer_params->max_bucket_size = 1000 * 100;
- params.sender_policer_params->target_bandwidth =
- params.BottleneckBandwidth() * 0.25;
-
- CreateNetwork(params);
-
- ASSERT_GE(params.BDP(), kDefaultInitialCwndBytes + kDefaultTCPMSS);
-
- DoSimpleTransfer(3 * 1024 * 1024, QuicTime::Delta::FromSeconds(30));
- EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
- // TODO(wub): Fix (long-term) bandwidth overestimation in policer mode, then
- // reduce the loss rate upper bound.
- EXPECT_LE(sender_loss_rate_in_packets(), 0.30);
-}
-
-// TODO(wub): Add other slowstart stats to BBRv2.
-TEST_F(Bbr2DefaultTopologyTest, StartupStats) {
- DefaultTopologyParams params;
- CreateNetwork(params);
-
- DriveOutOfStartup(params);
- ASSERT_FALSE(sender_->InSlowStart());
-
- const QuicConnectionStats& stats = sender_connection_stats();
- // The test explicitly replaces the default-created send algorithm with the
- // one created by the test. slowstart_count increaments every time a BBR
- // sender is created.
- EXPECT_GE(stats.slowstart_count, 1u);
- EXPECT_FALSE(stats.slowstart_duration.IsRunning());
- EXPECT_THAT(stats.slowstart_duration.GetTotalElapsedTime(),
- AllOf(Ge(QuicTime::Delta::FromMilliseconds(500)),
- Le(QuicTime::Delta::FromMilliseconds(1500))));
- EXPECT_EQ(stats.slowstart_duration.GetTotalElapsedTime(),
- QuicConnectionPeer::GetSentPacketManager(sender_connection())
- ->GetSlowStartDuration());
-}
-
-TEST_F(Bbr2DefaultTopologyTest, ProbeUpAdaptInflightHiGradually) {
- DefaultTopologyParams params;
- CreateNetwork(params);
-
- DriveOutOfStartup(params);
-
- AckedPacketVector acked_packets;
- QuicPacketNumber acked_packet_number =
- sender_unacked_map()->GetLeastUnacked();
- for (auto& info : *sender_unacked_map()) {
- acked_packets.emplace_back(acked_packet_number++, info.bytes_sent,
- SimulatedNow());
- }
-
- // Advance time significantly so the OnCongestionEvent enters PROBE_REFILL.
- QuicTime now = SimulatedNow() + QuicTime::Delta::FromSeconds(5);
- auto next_packet_number = sender_unacked_map()->largest_sent_packet() + 1;
- sender_->OnCongestionEvent(
- /*rtt_updated=*/true, sender_unacked_map()->bytes_in_flight(), now,
- acked_packets, {});
- ASSERT_EQ(CyclePhase::PROBE_REFILL,
- sender_->ExportDebugState().probe_bw.phase);
-
- // Send and Ack one packet to exit app limited and enter PROBE_UP.
- sender_->OnPacketSent(now, /*bytes_in_flight=*/0, next_packet_number++,
- kDefaultMaxPacketSize, HAS_RETRANSMITTABLE_DATA);
- now = now + params.RTT();
- sender_->OnCongestionEvent(
- /*rtt_updated=*/true, kDefaultMaxPacketSize, now,
- {AckedPacket(next_packet_number - 1, kDefaultMaxPacketSize, now)}, {});
- ASSERT_EQ(CyclePhase::PROBE_UP, sender_->ExportDebugState().probe_bw.phase);
-
- // Send 2 packets and lose the first one(50% loss) to exit PROBE_UP.
- for (uint64_t i = 0; i < 2; ++i) {
- sender_->OnPacketSent(now, /*bytes_in_flight=*/i * kDefaultMaxPacketSize,
- next_packet_number++, kDefaultMaxPacketSize,
- HAS_RETRANSMITTABLE_DATA);
- }
- now = now + params.RTT();
- sender_->OnCongestionEvent(
- /*rtt_updated=*/true, kDefaultMaxPacketSize, now,
- {AckedPacket(next_packet_number - 1, kDefaultMaxPacketSize, now)},
- {LostPacket(next_packet_number - 2, kDefaultMaxPacketSize)});
-
- QuicByteCount inflight_hi = sender_->ExportDebugState().inflight_hi;
- EXPECT_LT(2 * kDefaultMaxPacketSize, inflight_hi);
-}
-
-// Ensures bandwidth estimate does not change after a loss only event.
-TEST_F(Bbr2DefaultTopologyTest, LossOnlyCongestionEvent) {
- DefaultTopologyParams params;
- CreateNetwork(params);
-
- DriveOutOfStartup(params);
- EXPECT_FALSE(sender_->ExportDebugState().last_sample_is_app_limited);
-
- // Send some bursts, each burst increments round count by 1, since it only
- // generates small, app-limited samples, the max_bandwidth_filter_ will not be
- // updated.
- SendBursts(params, 20, 512, QuicTime::Delta::FromSeconds(3));
-
- // Run until we have something in flight.
- sender_endpoint_.AddBytesToTransfer(50 * 1024 * 1024);
- bool simulator_result = simulator_.RunUntilOrTimeout(
- [&]() { return sender_unacked_map()->bytes_in_flight() > 0; },
- QuicTime::Delta::FromSeconds(5));
- ASSERT_TRUE(simulator_result);
-
- const QuicBandwidth prior_bandwidth_estimate = sender_->BandwidthEstimate();
- EXPECT_APPROX_EQ(params.BottleneckBandwidth(), prior_bandwidth_estimate,
- 0.01f);
-
- // Lose the least unacked packet.
- LostPacketVector lost_packets;
- lost_packets.emplace_back(
- sender_connection()->sent_packet_manager().GetLeastUnacked(),
- kDefaultMaxPacketSize);
-
- QuicTime now = simulator_.GetClock()->Now() + params.RTT() * 0.25;
- sender_->OnCongestionEvent(false, sender_unacked_map()->bytes_in_flight(),
- now, {}, lost_packets);
-
- // Bandwidth estimate should not change for the loss only event.
- EXPECT_EQ(prior_bandwidth_estimate, sender_->BandwidthEstimate());
-}
-
-// After quiescence, if the sender is in PROBE_RTT, it should transition to
-// PROBE_BW immediately on the first sent packet after quiescence.
-TEST_F(Bbr2DefaultTopologyTest, ProbeRttAfterQuiescenceImmediatelyExits) {
- DefaultTopologyParams params;
- CreateNetwork(params);
-
- DriveOutOfStartup(params);
-
- const QuicTime::Delta timeout = QuicTime::Delta::FromSeconds(15);
- bool simulator_result;
-
- // Keep sending until reach PROBE_RTT.
- simulator_result = SendUntilOrTimeout(
- [this]() {
- return sender_->ExportDebugState().mode == Bbr2Mode::PROBE_RTT;
- },
- timeout);
- ASSERT_TRUE(simulator_result);
-
- // Wait for entering a quiescence of 5 seconds.
- ASSERT_TRUE(simulator_.RunUntilOrTimeout(
- [this]() {
- return sender_unacked_map()->bytes_in_flight() == 0 &&
- sender_->ExportDebugState().mode == Bbr2Mode::PROBE_RTT;
- },
- timeout));
-
- simulator_.RunFor(QuicTime::Delta::FromSeconds(5));
-
- // Send one packet to exit quiescence.
- EXPECT_EQ(sender_->ExportDebugState().mode, Bbr2Mode::PROBE_RTT);
- sender_->OnPacketSent(SimulatedNow(), /*bytes_in_flight=*/0,
- sender_unacked_map()->largest_sent_packet() + 1,
- kDefaultMaxPacketSize, HAS_RETRANSMITTABLE_DATA);
-
- EXPECT_EQ(sender_->ExportDebugState().mode, Bbr2Mode::PROBE_BW);
-}
-
-TEST_F(Bbr2DefaultTopologyTest, ProbeBwAfterQuiescencePostponeMinRttTimestamp) {
- DefaultTopologyParams params;
- CreateNetwork(params);
-
- DriveOutOfStartup(params);
-
- const QuicTime::Delta timeout = QuicTime::Delta::FromSeconds(5);
- bool simulator_result;
-
- // Keep sending until reach PROBE_REFILL.
- simulator_result = SendUntilOrTimeout(
- [this]() {
- return sender_->ExportDebugState().probe_bw.phase ==
- CyclePhase::PROBE_REFILL;
- },
- timeout);
- ASSERT_TRUE(simulator_result);
-
- const QuicTime min_rtt_timestamp_before_idle =
- sender_->ExportDebugState().min_rtt_timestamp;
-
- // Wait for entering a quiescence of 15 seconds.
- ASSERT_TRUE(simulator_.RunUntilOrTimeout(
- [this]() { return sender_unacked_map()->bytes_in_flight() == 0; },
- params.RTT() + timeout));
-
- simulator_.RunFor(QuicTime::Delta::FromSeconds(15));
-
- // Send some data to exit quiescence.
- SendBursts(params, 1, kDefaultTCPMSS, QuicTime::Delta::Zero());
- const QuicTime min_rtt_timestamp_after_idle =
- sender_->ExportDebugState().min_rtt_timestamp;
-
- EXPECT_LT(min_rtt_timestamp_before_idle + QuicTime::Delta::FromSeconds(14),
- min_rtt_timestamp_after_idle);
-}
-
-TEST_F(Bbr2DefaultTopologyTest, SwitchToBbr2MidConnection) {
- QuicTime now = QuicTime::Zero();
- BbrSender old_sender(sender_connection()->clock()->Now(),
- sender_connection()->sent_packet_manager().GetRttStats(),
- GetUnackedMap(sender_connection()),
- kDefaultInitialCwndPackets + 1,
- GetQuicFlag(FLAGS_quic_max_congestion_window), &random_,
- QuicConnectionPeer::GetStats(sender_connection()));
-
- QuicPacketNumber next_packet_number(1);
-
- // Send packets 1-4.
- while (next_packet_number < QuicPacketNumber(5)) {
- now = now + QuicTime::Delta::FromMilliseconds(10);
-
- old_sender.OnPacketSent(now, /*bytes_in_flight=*/0, next_packet_number++,
- /*bytes=*/1350, HAS_RETRANSMITTABLE_DATA);
- }
-
- // Switch from |old_sender| to |sender_|.
- const QuicByteCount old_sender_cwnd = old_sender.GetCongestionWindow();
- sender_ = SetupBbr2Sender(&sender_endpoint_, &old_sender);
- EXPECT_EQ(old_sender_cwnd, sender_->GetCongestionWindow());
-
- // Send packets 5-7.
- now = now + QuicTime::Delta::FromMilliseconds(10);
- sender_->OnPacketSent(now, /*bytes_in_flight=*/1350, next_packet_number++,
- /*bytes=*/23, NO_RETRANSMITTABLE_DATA);
-
- now = now + QuicTime::Delta::FromMilliseconds(10);
- sender_->OnPacketSent(now, /*bytes_in_flight=*/1350, next_packet_number++,
- /*bytes=*/767, HAS_RETRANSMITTABLE_DATA);
-
- QuicByteCount bytes_in_flight = 767;
- while (next_packet_number < QuicPacketNumber(30)) {
- now = now + QuicTime::Delta::FromMilliseconds(10);
- bytes_in_flight += 1350;
- sender_->OnPacketSent(now, bytes_in_flight, next_packet_number++,
- /*bytes=*/1350, HAS_RETRANSMITTABLE_DATA);
- }
-
- // Ack 1 & 2.
- AckedPacketVector acked = {
- AckedPacket(QuicPacketNumber(1), /*bytes_acked=*/0, QuicTime::Zero()),
- AckedPacket(QuicPacketNumber(2), /*bytes_acked=*/0, QuicTime::Zero()),
- };
- now = now + QuicTime::Delta::FromMilliseconds(2000);
- sender_->OnCongestionEvent(true, bytes_in_flight, now, acked, {});
-
- // Send 30-41.
- while (next_packet_number < QuicPacketNumber(42)) {
- now = now + QuicTime::Delta::FromMilliseconds(10);
- bytes_in_flight += 1350;
- sender_->OnPacketSent(now, bytes_in_flight, next_packet_number++,
- /*bytes=*/1350, HAS_RETRANSMITTABLE_DATA);
- }
-
- // Ack 3.
- acked = {
- AckedPacket(QuicPacketNumber(3), /*bytes_acked=*/0, QuicTime::Zero()),
- };
- now = now + QuicTime::Delta::FromMilliseconds(2000);
- sender_->OnCongestionEvent(true, bytes_in_flight, now, acked, {});
-
- // Send 42.
- now = now + QuicTime::Delta::FromMilliseconds(10);
- bytes_in_flight += 1350;
- sender_->OnPacketSent(now, bytes_in_flight, next_packet_number++,
- /*bytes=*/1350, HAS_RETRANSMITTABLE_DATA);
-
- // Ack 4-7.
- acked = {
- AckedPacket(QuicPacketNumber(4), /*bytes_acked=*/0, QuicTime::Zero()),
- AckedPacket(QuicPacketNumber(5), /*bytes_acked=*/0, QuicTime::Zero()),
- AckedPacket(QuicPacketNumber(6), /*bytes_acked=*/767, QuicTime::Zero()),
- AckedPacket(QuicPacketNumber(7), /*bytes_acked=*/1350, QuicTime::Zero()),
- };
- now = now + QuicTime::Delta::FromMilliseconds(2000);
- sender_->OnCongestionEvent(true, bytes_in_flight, now, acked, {});
- EXPECT_FALSE(sender_->BandwidthEstimate().IsZero());
-}
-
-TEST_F(Bbr2DefaultTopologyTest, AdjustNetworkParameters) {
- DefaultTopologyParams params;
- CreateNetwork(params);
-
- QUIC_LOG(INFO) << "Initial cwnd: " << sender_debug_state().congestion_window
- << "\nInitial pacing rate: " << sender_->PacingRate(0)
- << "\nInitial bandwidth estimate: "
- << sender_->BandwidthEstimate()
- << "\nInitial rtt: " << sender_debug_state().min_rtt;
-
- sender_connection()->AdjustNetworkParameters(
- SendAlgorithmInterface::NetworkParams(params.BottleneckBandwidth(),
- params.RTT(),
- /*allow_cwnd_to_decrease=*/false));
-
- EXPECT_EQ(params.BDP(), sender_->ExportDebugState().congestion_window);
-
- EXPECT_EQ(params.BottleneckBandwidth(),
- sender_->PacingRate(/*bytes_in_flight=*/0));
- EXPECT_NE(params.BottleneckBandwidth(), sender_->BandwidthEstimate());
-
- EXPECT_APPROX_EQ(params.RTT(), sender_->ExportDebugState().min_rtt, 0.01f);
-
- DriveOutOfStartup(params);
-}
-
-TEST_F(Bbr2DefaultTopologyTest,
- 200InitialCongestionWindowWithNetworkParameterAdjusted) {
- DefaultTopologyParams params;
- CreateNetwork(params);
-
- sender_endpoint_.AddBytesToTransfer(1 * 1024 * 1024);
-
- // Wait until an ACK comes back.
- const QuicTime::Delta timeout = QuicTime::Delta::FromSeconds(5);
- bool simulator_result = simulator_.RunUntilOrTimeout(
- [this]() { return !sender_->ExportDebugState().min_rtt.IsZero(); },
- timeout);
- ASSERT_TRUE(simulator_result);
-
- // Bootstrap cwnd by a overly large bandwidth sample.
- sender_connection()->AdjustNetworkParameters(
- SendAlgorithmInterface::NetworkParams(1024 * params.BottleneckBandwidth(),
- QuicTime::Delta::Zero(), false));
-
- // Verify cwnd is capped at 200.
- EXPECT_EQ(200 * kDefaultTCPMSS,
- sender_->ExportDebugState().congestion_window);
- EXPECT_GT(1024 * params.BottleneckBandwidth(), sender_->PacingRate(0));
-}
-
-TEST_F(Bbr2DefaultTopologyTest,
- 100InitialCongestionWindowFromNetworkParameter) {
- DefaultTopologyParams params;
- CreateNetwork(params);
-
- sender_endpoint_.AddBytesToTransfer(1 * 1024 * 1024);
- // Wait until an ACK comes back.
- const QuicTime::Delta timeout = QuicTime::Delta::FromSeconds(5);
- bool simulator_result = simulator_.RunUntilOrTimeout(
- [this]() { return !sender_->ExportDebugState().min_rtt.IsZero(); },
- timeout);
- ASSERT_TRUE(simulator_result);
-
- // Bootstrap cwnd by a overly large bandwidth sample.
- SendAlgorithmInterface::NetworkParams network_params(
- 1024 * params.BottleneckBandwidth(), QuicTime::Delta::Zero(), false);
- network_params.max_initial_congestion_window = 100;
- sender_connection()->AdjustNetworkParameters(network_params);
-
- // Verify cwnd is capped at 100.
- EXPECT_EQ(100 * kDefaultTCPMSS,
- sender_->ExportDebugState().congestion_window);
- EXPECT_GT(1024 * params.BottleneckBandwidth(), sender_->PacingRate(0));
-}
-
-TEST_F(Bbr2DefaultTopologyTest,
- 100InitialCongestionWindowWithNetworkParameterAdjusted) {
- SetConnectionOption(kICW1);
- DefaultTopologyParams params;
- CreateNetwork(params);
-
- sender_endpoint_.AddBytesToTransfer(1 * 1024 * 1024);
- // Wait until an ACK comes back.
- const QuicTime::Delta timeout = QuicTime::Delta::FromSeconds(5);
- bool simulator_result = simulator_.RunUntilOrTimeout(
- [this]() { return !sender_->ExportDebugState().min_rtt.IsZero(); },
- timeout);
- ASSERT_TRUE(simulator_result);
-
- // Bootstrap cwnd by a overly large bandwidth sample.
- sender_connection()->AdjustNetworkParameters(
- SendAlgorithmInterface::NetworkParams(1024 * params.BottleneckBandwidth(),
- QuicTime::Delta::Zero(), false));
-
- // Verify cwnd is capped at 100.
- EXPECT_EQ(100 * kDefaultTCPMSS,
- sender_->ExportDebugState().congestion_window);
- EXPECT_GT(1024 * params.BottleneckBandwidth(), sender_->PacingRate(0));
-}
-
-// All Bbr2MultiSenderTests uses the following network topology:
-//
-// Sender 0 (A Bbr2Sender)
-// |
-// | <-- local_links[0]
-// |
-// | Sender N (1 <= N < kNumLocalLinks) (May or may not be a Bbr2Sender)
-// | |
-// | | <-- local_links[N]
-// | |
-// Network switch
-// * <-- the bottleneck queue in the direction
-// | of the receiver
-// |
-// | <-- test_link
-// |
-// |
-// Receiver
-class MultiSenderTopologyParams {
- public:
- static constexpr size_t kNumLocalLinks = 8;
- std::array<LinkParams, kNumLocalLinks> local_links = {
- LinkParams(10000, 1987), LinkParams(10000, 1993), LinkParams(10000, 1997),
- LinkParams(10000, 1999), LinkParams(10000, 2003), LinkParams(10000, 2011),
- LinkParams(10000, 2017), LinkParams(10000, 2027),
- };
-
- LinkParams test_link = LinkParams(4000, 30000);
-
- const simulator::SwitchPortNumber switch_port_count = kNumLocalLinks + 1;
-
- // Network switch queue capacity, in number of BDPs.
- float switch_queue_capacity_in_bdp = 2;
-
- QuicBandwidth BottleneckBandwidth() const {
- // Make sure all local links have a higher bandwidth than the test link.
- for (size_t i = 0; i < local_links.size(); ++i) {
- QUICHE_CHECK_GT(local_links[i].bandwidth, test_link.bandwidth);
- }
- return test_link.bandwidth;
- }
-
- // Sender n's round trip time of a single full size packet.
- QuicTime::Delta Rtt(size_t n) const {
- return 2 * (local_links[n].delay + test_link.delay +
- local_links[n].bandwidth.TransferTime(kMaxOutgoingPacketSize) +
- test_link.bandwidth.TransferTime(kMaxOutgoingPacketSize));
- }
-
- QuicByteCount Bdp(size_t n) const { return BottleneckBandwidth() * Rtt(n); }
-
- QuicByteCount SwitchQueueCapacity() const {
- return switch_queue_capacity_in_bdp * Bdp(1);
- }
-
- std::string ToString() const {
- std::ostringstream os;
- os << "{ BottleneckBandwidth: " << BottleneckBandwidth();
- for (size_t i = 0; i < local_links.size(); ++i) {
- os << " RTT_" << i << ": " << Rtt(i) << " BDP_" << i << ": " << Bdp(i);
- }
- os << " BottleneckQueueSize: " << SwitchQueueCapacity() << "}";
- return os.str();
- }
-};
-
-class Bbr2MultiSenderTest : public Bbr2SimulatorTest {
- protected:
- Bbr2MultiSenderTest() {
- uint64_t first_connection_id = 42;
- std::vector<simulator::QuicEndpointBase*> receiver_endpoint_pointers;
- for (size_t i = 0; i < MultiSenderTopologyParams::kNumLocalLinks; ++i) {
- std::string sender_name = absl::StrCat("Sender", i + 1);
- std::string receiver_name = absl::StrCat("Receiver", i + 1);
- sender_endpoints_.push_back(std::make_unique<simulator::QuicEndpoint>(
- &simulator_, sender_name, receiver_name, Perspective::IS_CLIENT,
- TestConnectionId(first_connection_id + i)));
- receiver_endpoints_.push_back(std::make_unique<simulator::QuicEndpoint>(
- &simulator_, receiver_name, sender_name, Perspective::IS_SERVER,
- TestConnectionId(first_connection_id + i)));
- receiver_endpoint_pointers.push_back(receiver_endpoints_.back().get());
- }
- receiver_multiplexer_ =
- std::make_unique<simulator::QuicEndpointMultiplexer>(
- "Receiver multiplexer", receiver_endpoint_pointers);
- sender_0_ = SetupBbr2Sender(sender_endpoints_[0].get());
- }
-
- ~Bbr2MultiSenderTest() {
- const auto* test_info =
- ::testing::UnitTest::GetInstance()->current_test_info();
- QUIC_LOG(INFO) << "Bbr2MultiSenderTest." << test_info->name()
- << " completed at simulated time: "
- << SimulatedNow().ToDebuggingValue() / 1e6
- << " sec. Per sender stats:";
- for (size_t i = 0; i < sender_endpoints_.size(); ++i) {
- QUIC_LOG(INFO) << "sender[" << i << "]: "
- << sender_connection(i)
- ->sent_packet_manager()
- .GetSendAlgorithm()
- ->GetCongestionControlType()
- << ", packet_loss:"
- << 100.0 * sender_loss_rate_in_packets(i) << "%";
- }
- }
-
- Bbr2Sender* SetupBbr2Sender(simulator::QuicEndpoint* endpoint) {
- // Ownership of the sender will be overtaken by the endpoint.
- Bbr2Sender* sender = new Bbr2Sender(
- endpoint->connection()->clock()->Now(),
- endpoint->connection()->sent_packet_manager().GetRttStats(),
- QuicSentPacketManagerPeer::GetUnackedPacketMap(
- QuicConnectionPeer::GetSentPacketManager(endpoint->connection())),
- kDefaultInitialCwndPackets,
- GetQuicFlag(FLAGS_quic_max_congestion_window), &random_,
- QuicConnectionPeer::GetStats(endpoint->connection()), nullptr);
- // TODO(ianswett): Add dedicated tests for this option until it becomes
- // the default behavior.
- SetConnectionOption(sender, kBBRA);
-
- QuicConnectionPeer::SetSendAlgorithm(endpoint->connection(), sender);
- endpoint->RecordTrace();
- return sender;
- }
-
- BbrSender* SetupBbrSender(simulator::QuicEndpoint* endpoint) {
- // Ownership of the sender will be overtaken by the endpoint.
- BbrSender* sender = new BbrSender(
- endpoint->connection()->clock()->Now(),
- endpoint->connection()->sent_packet_manager().GetRttStats(),
- QuicSentPacketManagerPeer::GetUnackedPacketMap(
- QuicConnectionPeer::GetSentPacketManager(endpoint->connection())),
- kDefaultInitialCwndPackets,
- GetQuicFlag(FLAGS_quic_max_congestion_window), &random_,
- QuicConnectionPeer::GetStats(endpoint->connection()));
- QuicConnectionPeer::SetSendAlgorithm(endpoint->connection(), sender);
- endpoint->RecordTrace();
- return sender;
- }
-
- // reno => Reno. !reno => Cubic.
- TcpCubicSenderBytes* SetupTcpSender(simulator::QuicEndpoint* endpoint,
- bool reno) {
- // Ownership of the sender will be overtaken by the endpoint.
- TcpCubicSenderBytes* sender = new TcpCubicSenderBytes(
- endpoint->connection()->clock(),
- endpoint->connection()->sent_packet_manager().GetRttStats(), reno,
- kDefaultInitialCwndPackets,
- GetQuicFlag(FLAGS_quic_max_congestion_window),
- QuicConnectionPeer::GetStats(endpoint->connection()));
- QuicConnectionPeer::SetSendAlgorithm(endpoint->connection(), sender);
- endpoint->RecordTrace();
- return sender;
- }
-
- void SetConnectionOption(SendAlgorithmInterface* sender, QuicTag option) {
- QuicConfig config;
- QuicTagVector options;
- options.push_back(option);
- QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
- sender->SetFromConfig(config, Perspective::IS_SERVER);
- }
-
- void CreateNetwork(const MultiSenderTopologyParams& params) {
- QUIC_LOG(INFO) << "CreateNetwork with parameters: " << params.ToString();
- switch_ = std::make_unique<simulator::Switch>(&simulator_, "Switch",
- params.switch_port_count,
- params.SwitchQueueCapacity());
-
- network_links_.push_back(std::make_unique<simulator::SymmetricLink>(
- receiver_multiplexer_.get(), switch_->port(1),
- params.test_link.bandwidth, params.test_link.delay));
- for (size_t i = 0; i < MultiSenderTopologyParams::kNumLocalLinks; ++i) {
- simulator::SwitchPortNumber port_number = i + 2;
- network_links_.push_back(std::make_unique<simulator::SymmetricLink>(
- sender_endpoints_[i].get(), switch_->port(port_number),
- params.local_links[i].bandwidth, params.local_links[i].delay));
- }
- }
-
- QuicConnection* sender_connection(size_t which) {
- return sender_endpoints_[which]->connection();
- }
-
- const QuicConnectionStats& sender_connection_stats(size_t which) {
- return sender_connection(which)->GetStats();
- }
-
- float sender_loss_rate_in_packets(size_t which) {
- return static_cast<float>(sender_connection_stats(which).packets_lost) /
- sender_connection_stats(which).packets_sent;
- }
-
- std::vector<std::unique_ptr<simulator::QuicEndpoint>> sender_endpoints_;
- std::vector<std::unique_ptr<simulator::QuicEndpoint>> receiver_endpoints_;
- std::unique_ptr<simulator::QuicEndpointMultiplexer> receiver_multiplexer_;
- Bbr2Sender* sender_0_;
-
- std::unique_ptr<simulator::Switch> switch_;
- std::vector<std::unique_ptr<simulator::SymmetricLink>> network_links_;
-};
-
-TEST_F(Bbr2MultiSenderTest, Bbr2VsBbr2) {
- SetupBbr2Sender(sender_endpoints_[1].get());
-
- MultiSenderTopologyParams params;
- CreateNetwork(params);
-
- const QuicByteCount transfer_size = 10 * 1024 * 1024;
- const QuicTime::Delta transfer_time =
- params.BottleneckBandwidth().TransferTime(transfer_size);
- QUIC_LOG(INFO) << "Single flow transfer time: " << transfer_time;
-
- // Transfer 10% of data in first transfer.
- sender_endpoints_[0]->AddBytesToTransfer(transfer_size);
- bool simulator_result = simulator_.RunUntilOrTimeout(
- [this]() {
- return receiver_endpoints_[0]->bytes_received() >= 0.1 * transfer_size;
- },
- transfer_time);
- ASSERT_TRUE(simulator_result);
-
- // Start the second transfer and wait until both finish.
- sender_endpoints_[1]->AddBytesToTransfer(transfer_size);
- simulator_result = simulator_.RunUntilOrTimeout(
- [this]() {
- return receiver_endpoints_[0]->bytes_received() == transfer_size &&
- receiver_endpoints_[1]->bytes_received() == transfer_size;
- },
- 3 * transfer_time);
- ASSERT_TRUE(simulator_result);
-}
-
-TEST_F(Bbr2MultiSenderTest, QUIC_SLOW_TEST(MultipleBbr2s)) {
- const int kTotalNumSenders = 6;
- for (int i = 1; i < kTotalNumSenders; ++i) {
- SetupBbr2Sender(sender_endpoints_[i].get());
- }
-
- MultiSenderTopologyParams params;
- CreateNetwork(params);
-
- const QuicByteCount transfer_size = 10 * 1024 * 1024;
- const QuicTime::Delta transfer_time =
- params.BottleneckBandwidth().TransferTime(transfer_size);
- QUIC_LOG(INFO) << "Single flow transfer time: " << transfer_time
- << ". Now: " << SimulatedNow();
-
- // Start all transfers.
- for (int i = 0; i < kTotalNumSenders; ++i) {
- if (i != 0) {
- const QuicTime sender_start_time =
- SimulatedNow() + QuicTime::Delta::FromSeconds(2);
- bool simulator_result = simulator_.RunUntilOrTimeout(
- [&]() { return SimulatedNow() >= sender_start_time; }, transfer_time);
- ASSERT_TRUE(simulator_result);
- }
-
- sender_endpoints_[i]->AddBytesToTransfer(transfer_size);
- }
-
- // Wait for all transfers to finish.
- QuicTime::Delta expected_total_transfer_time_upper_bound =
- QuicTime::Delta::FromMicroseconds(kTotalNumSenders *
- transfer_time.ToMicroseconds() * 1.1);
- bool simulator_result = simulator_.RunUntilOrTimeout(
- [this]() {
- for (int i = 0; i < kTotalNumSenders; ++i) {
- if (receiver_endpoints_[i]->bytes_received() < transfer_size) {
- return false;
- }
- }
- return true;
- },
- expected_total_transfer_time_upper_bound);
- ASSERT_TRUE(simulator_result)
- << "Expected upper bound: " << expected_total_transfer_time_upper_bound;
-}
-
-/* The first 11 packets are sent at the same time, but the duration between the
- * acks of the 1st and the 11th packet is 49 milliseconds, causing very low bw
- * samples. This happens for both large and small buffers.
- */
-/*
-TEST_F(Bbr2MultiSenderTest, Bbr2VsBbr2LargeRttTinyBuffer) {
- SetupBbr2Sender(sender_endpoints_[1].get());
-
- MultiSenderTopologyParams params;
- params.switch_queue_capacity_in_bdp = 0.05;
- params.test_link.delay = QuicTime::Delta::FromSeconds(1);
- CreateNetwork(params);
-
- const QuicByteCount transfer_size = 10 * 1024 * 1024;
- const QuicTime::Delta transfer_time =
- params.BottleneckBandwidth().TransferTime(transfer_size);
- QUIC_LOG(INFO) << "Single flow transfer time: " << transfer_time;
-
- // Transfer 10% of data in first transfer.
- sender_endpoints_[0]->AddBytesToTransfer(transfer_size);
- bool simulator_result = simulator_.RunUntilOrTimeout(
- [this]() {
- return receiver_endpoints_[0]->bytes_received() >= 0.1 * transfer_size;
- },
- transfer_time);
- ASSERT_TRUE(simulator_result);
-
- // Start the second transfer and wait until both finish.
- sender_endpoints_[1]->AddBytesToTransfer(transfer_size);
- simulator_result = simulator_.RunUntilOrTimeout(
- [this]() {
- return receiver_endpoints_[0]->bytes_received() == transfer_size &&
- receiver_endpoints_[1]->bytes_received() == transfer_size;
- },
- 3 * transfer_time);
- ASSERT_TRUE(simulator_result);
-}
-*/
-
-TEST_F(Bbr2MultiSenderTest, Bbr2VsBbr1) {
- SetupBbrSender(sender_endpoints_[1].get());
-
- MultiSenderTopologyParams params;
- CreateNetwork(params);
-
- const QuicByteCount transfer_size = 10 * 1024 * 1024;
- const QuicTime::Delta transfer_time =
- params.BottleneckBandwidth().TransferTime(transfer_size);
- QUIC_LOG(INFO) << "Single flow transfer time: " << transfer_time;
-
- // Transfer 10% of data in first transfer.
- sender_endpoints_[0]->AddBytesToTransfer(transfer_size);
- bool simulator_result = simulator_.RunUntilOrTimeout(
- [this]() {
- return receiver_endpoints_[0]->bytes_received() >= 0.1 * transfer_size;
- },
- transfer_time);
- ASSERT_TRUE(simulator_result);
-
- // Start the second transfer and wait until both finish.
- sender_endpoints_[1]->AddBytesToTransfer(transfer_size);
- simulator_result = simulator_.RunUntilOrTimeout(
- [this]() {
- return receiver_endpoints_[0]->bytes_received() == transfer_size &&
- receiver_endpoints_[1]->bytes_received() == transfer_size;
- },
- 3 * transfer_time);
- ASSERT_TRUE(simulator_result);
-}
-
-TEST_F(Bbr2MultiSenderTest, QUIC_SLOW_TEST(Bbr2VsReno)) {
- SetupTcpSender(sender_endpoints_[1].get(), /*reno=*/true);
-
- MultiSenderTopologyParams params;
- CreateNetwork(params);
-
- const QuicByteCount transfer_size = 10 * 1024 * 1024;
- const QuicTime::Delta transfer_time =
- params.BottleneckBandwidth().TransferTime(transfer_size);
- QUIC_LOG(INFO) << "Single flow transfer time: " << transfer_time;
-
- // Transfer 10% of data in first transfer.
- sender_endpoints_[0]->AddBytesToTransfer(transfer_size);
- bool simulator_result = simulator_.RunUntilOrTimeout(
- [this]() {
- return receiver_endpoints_[0]->bytes_received() >= 0.1 * transfer_size;
- },
- transfer_time);
- ASSERT_TRUE(simulator_result);
-
- // Start the second transfer and wait until both finish.
- sender_endpoints_[1]->AddBytesToTransfer(transfer_size);
- simulator_result = simulator_.RunUntilOrTimeout(
- [this]() {
- return receiver_endpoints_[0]->bytes_received() == transfer_size &&
- receiver_endpoints_[1]->bytes_received() == transfer_size;
- },
- 3 * transfer_time);
- ASSERT_TRUE(simulator_result);
-}
-
-TEST_F(Bbr2MultiSenderTest, QUIC_SLOW_TEST(Bbr2VsRenoB2RC)) {
- SetConnectionOption(sender_0_, kB2RC);
- SetupTcpSender(sender_endpoints_[1].get(), /*reno=*/true);
-
- MultiSenderTopologyParams params;
- CreateNetwork(params);
-
- const QuicByteCount transfer_size = 10 * 1024 * 1024;
- const QuicTime::Delta transfer_time =
- params.BottleneckBandwidth().TransferTime(transfer_size);
- QUIC_LOG(INFO) << "Single flow transfer time: " << transfer_time;
-
- // Transfer 10% of data in first transfer.
- sender_endpoints_[0]->AddBytesToTransfer(transfer_size);
- bool simulator_result = simulator_.RunUntilOrTimeout(
- [this]() {
- return receiver_endpoints_[0]->bytes_received() >= 0.1 * transfer_size;
- },
- transfer_time);
- ASSERT_TRUE(simulator_result);
-
- // Start the second transfer and wait until both finish.
- sender_endpoints_[1]->AddBytesToTransfer(transfer_size);
- simulator_result = simulator_.RunUntilOrTimeout(
- [this]() {
- return receiver_endpoints_[0]->bytes_received() == transfer_size &&
- receiver_endpoints_[1]->bytes_received() == transfer_size;
- },
- 3 * transfer_time);
- ASSERT_TRUE(simulator_result);
-}
-
-TEST_F(Bbr2MultiSenderTest, QUIC_SLOW_TEST(Bbr2VsCubic)) {
- SetupTcpSender(sender_endpoints_[1].get(), /*reno=*/false);
-
- MultiSenderTopologyParams params;
- CreateNetwork(params);
-
- const QuicByteCount transfer_size = 50 * 1024 * 1024;
- const QuicTime::Delta transfer_time =
- params.BottleneckBandwidth().TransferTime(transfer_size);
- QUIC_LOG(INFO) << "Single flow transfer time: " << transfer_time;
-
- // Transfer 10% of data in first transfer.
- sender_endpoints_[0]->AddBytesToTransfer(transfer_size);
- bool simulator_result = simulator_.RunUntilOrTimeout(
- [this]() {
- return receiver_endpoints_[0]->bytes_received() >= 0.1 * transfer_size;
- },
- transfer_time);
- ASSERT_TRUE(simulator_result);
-
- // Start the second transfer and wait until both finish.
- sender_endpoints_[1]->AddBytesToTransfer(transfer_size);
- simulator_result = simulator_.RunUntilOrTimeout(
- [this]() {
- return receiver_endpoints_[0]->bytes_received() == transfer_size &&
- receiver_endpoints_[1]->bytes_received() == transfer_size;
- },
- 3 * transfer_time);
- ASSERT_TRUE(simulator_result);
-}
-
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/congestion_control/bbr2_startup.cc b/chromium/net/third_party/quiche/src/quic/core/congestion_control/bbr2_startup.cc
deleted file mode 100644
index 690bdb2c060..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/congestion_control/bbr2_startup.cc
+++ /dev/null
@@ -1,157 +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 "quic/core/congestion_control/bbr2_startup.h"
-
-#include "quic/core/congestion_control/bbr2_misc.h"
-#include "quic/core/congestion_control/bbr2_sender.h"
-#include "quic/core/quic_bandwidth.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_flag_utils.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-Bbr2StartupMode::Bbr2StartupMode(const Bbr2Sender* sender,
- Bbr2NetworkModel* model,
- QuicTime now)
- : Bbr2ModeBase(sender, model) {
- // Increment, instead of reset startup stats, so we don't lose data recorded
- // before QuicConnection switched send algorithm to BBRv2.
- ++sender_->connection_stats_->slowstart_count;
- if (!sender_->connection_stats_->slowstart_duration.IsRunning()) {
- sender_->connection_stats_->slowstart_duration.Start(now);
- }
- // Enter() is never called for Startup, so the gains needs to be set here.
- model_->set_pacing_gain(Params().startup_pacing_gain);
- model_->set_cwnd_gain(Params().startup_cwnd_gain);
-}
-
-void Bbr2StartupMode::Enter(QuicTime /*now*/,
- const Bbr2CongestionEvent* /*congestion_event*/) {
- QUIC_BUG(quic_bug_10463_1) << "Bbr2StartupMode::Enter should not be called";
-}
-
-void Bbr2StartupMode::Leave(QuicTime now,
- const Bbr2CongestionEvent* /*congestion_event*/) {
- sender_->connection_stats_->slowstart_duration.Stop(now);
- // Clear bandwidth_lo if it's set during STARTUP.
- model_->clear_bandwidth_lo();
-}
-
-Bbr2Mode Bbr2StartupMode::OnCongestionEvent(
- QuicByteCount /*prior_in_flight*/,
- QuicTime /*event_time*/,
- const AckedPacketVector& /*acked_packets*/,
- const LostPacketVector& /*lost_packets*/,
- const Bbr2CongestionEvent& congestion_event) {
- if (model_->full_bandwidth_reached()) {
- QUIC_BUG() << "In STARTUP, but full_bandwidth_reached is true.";
- return Bbr2Mode::DRAIN;
- }
- if (!congestion_event.end_of_round_trip) {
- return Bbr2Mode::STARTUP;
- }
- bool has_bandwidth_growth = model_->HasBandwidthGrowth(congestion_event);
- if (Params().exit_startup_on_persistent_queue && !has_bandwidth_growth) {
- QUIC_RELOADABLE_FLAG_COUNT(quic_bbr2_exit_startup_on_persistent_queue2);
- model_->CheckPersistentQueue(congestion_event, Params().startup_cwnd_gain);
- }
- // TCP BBR always exits upon excessive losses. QUIC BBRv1 does not exit
- // upon excessive losses, if enough bandwidth growth is observed or if the
- // sample was app limited.
- if (Params().always_exit_startup_on_excess_loss ||
- (!congestion_event.last_packet_send_state.is_app_limited &&
- !has_bandwidth_growth)) {
- CheckExcessiveLosses(congestion_event);
- }
-
- if (Params().decrease_startup_pacing_at_end_of_round) {
- QUICHE_DCHECK_GT(model_->pacing_gain(), 0);
- if (!congestion_event.last_packet_send_state.is_app_limited) {
- // Multiply by startup_pacing_gain, so if the bandwidth doubles,
- // the pacing gain will be the full startup_pacing_gain.
- if (max_bw_at_round_beginning_ > QuicBandwidth::Zero()) {
- const float bandwidth_ratio =
- std::max(1., model_->MaxBandwidth().ToBitsPerSecond() /
- static_cast<double>(
- max_bw_at_round_beginning_.ToBitsPerSecond()));
- // Even when bandwidth isn't increasing, use a gain large enough to
- // cause a startup_full_bw_threshold increase.
- const float new_gain =
- ((bandwidth_ratio - 1) * (Params().startup_pacing_gain -
- Params().startup_full_bw_threshold)) +
- Params().startup_full_bw_threshold;
- // Allow the pacing gain to decrease.
- model_->set_pacing_gain(
- std::min(Params().startup_pacing_gain, new_gain));
- // Clear bandwidth_lo if it's less than the pacing rate.
- // This avoids a constantly app-limited flow from having it's pacing
- // gain effectively decreased below 1.25.
- if (model_->bandwidth_lo() <
- model_->MaxBandwidth() * model_->pacing_gain()) {
- model_->clear_bandwidth_lo();
- }
- }
- max_bw_at_round_beginning_ = model_->MaxBandwidth();
- }
- }
-
- // TODO(wub): Maybe implement STARTUP => PROBE_RTT.
- return model_->full_bandwidth_reached() ? Bbr2Mode::DRAIN : Bbr2Mode::STARTUP;
-}
-
-void Bbr2StartupMode::CheckExcessiveLosses(
- const Bbr2CongestionEvent& congestion_event) {
- QUICHE_DCHECK(congestion_event.end_of_round_trip);
-
- if (model_->full_bandwidth_reached()) {
- return;
- }
-
- // At the end of a round trip. Check if loss is too high in this round.
- if (model_->IsInflightTooHigh(congestion_event,
- Params().startup_full_loss_count)) {
- QuicByteCount new_inflight_hi = model_->BDP();
- if (Params().startup_loss_exit_use_max_delivered_for_inflight_hi) {
- if (new_inflight_hi < model_->max_bytes_delivered_in_round()) {
- new_inflight_hi = model_->max_bytes_delivered_in_round();
- }
- }
- QUIC_DVLOG(3) << sender_ << " Exiting STARTUP due to loss at round "
- << model_->RoundTripCount()
- << ". inflight_hi:" << new_inflight_hi;
- // TODO(ianswett): Add a shared method to set inflight_hi in the model.
- model_->set_inflight_hi(new_inflight_hi);
- model_->set_full_bandwidth_reached();
- sender_->connection_stats_->bbr_exit_startup_due_to_loss = true;
- }
-}
-
-Bbr2StartupMode::DebugState Bbr2StartupMode::ExportDebugState() const {
- DebugState s;
- s.full_bandwidth_reached = model_->full_bandwidth_reached();
- s.full_bandwidth_baseline = model_->full_bandwidth_baseline();
- s.round_trips_without_bandwidth_growth =
- model_->rounds_without_bandwidth_growth();
- return s;
-}
-
-std::ostream& operator<<(std::ostream& os,
- const Bbr2StartupMode::DebugState& state) {
- os << "[STARTUP] full_bandwidth_reached: " << state.full_bandwidth_reached
- << "\n";
- os << "[STARTUP] full_bandwidth_baseline: " << state.full_bandwidth_baseline
- << "\n";
- os << "[STARTUP] round_trips_without_bandwidth_growth: "
- << state.round_trips_without_bandwidth_growth << "\n";
- return os;
-}
-
-const Bbr2Params& Bbr2StartupMode::Params() const {
- return sender_->Params();
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/congestion_control/bbr2_startup.h b/chromium/net/third_party/quiche/src/quic/core/congestion_control/bbr2_startup.h
deleted file mode 100644
index a05bac28216..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/congestion_control/bbr2_startup.h
+++ /dev/null
@@ -1,71 +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_CORE_CONGESTION_CONTROL_BBR2_STARTUP_H_
-#define QUICHE_QUIC_CORE_CONGESTION_CONTROL_BBR2_STARTUP_H_
-
-#include "quic/core/congestion_control/bbr2_misc.h"
-#include "quic/core/quic_bandwidth.h"
-#include "quic/core/quic_time.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-class Bbr2Sender;
-class QUIC_EXPORT_PRIVATE Bbr2StartupMode final : public Bbr2ModeBase {
- public:
- Bbr2StartupMode(const Bbr2Sender* sender,
- Bbr2NetworkModel* model,
- QuicTime now);
-
- void Enter(QuicTime now,
- const Bbr2CongestionEvent* congestion_event) override;
- void Leave(QuicTime now,
- const Bbr2CongestionEvent* congestion_event) override;
-
- Bbr2Mode OnCongestionEvent(
- QuicByteCount prior_in_flight,
- QuicTime event_time,
- const AckedPacketVector& acked_packets,
- const LostPacketVector& lost_packets,
- const Bbr2CongestionEvent& congestion_event) override;
-
- Limits<QuicByteCount> GetCwndLimits() const override {
- // Inflight_lo is never set in STARTUP.
- QUICHE_DCHECK_EQ(Bbr2NetworkModel::inflight_lo_default(),
- model_->inflight_lo());
- return NoGreaterThan(model_->inflight_lo());
- }
-
- bool IsProbingForBandwidth() const override { return true; }
-
- Bbr2Mode OnExitQuiescence(QuicTime /*now*/,
- QuicTime /*quiescence_start_time*/) override {
- return Bbr2Mode::STARTUP;
- }
-
- struct QUIC_EXPORT_PRIVATE DebugState {
- bool full_bandwidth_reached;
- QuicBandwidth full_bandwidth_baseline = QuicBandwidth::Zero();
- QuicRoundTripCount round_trips_without_bandwidth_growth;
- };
-
- DebugState ExportDebugState() const;
-
- private:
- const Bbr2Params& Params() const;
-
- void CheckExcessiveLosses(const Bbr2CongestionEvent& congestion_event);
- // Used when the pacing gain can decrease in STARTUP.
- QuicBandwidth max_bw_at_round_beginning_ = QuicBandwidth::Zero();
-};
-
-QUIC_EXPORT_PRIVATE std::ostream& operator<<(
- std::ostream& os,
- const Bbr2StartupMode::DebugState& state);
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_CONGESTION_CONTROL_BBR2_STARTUP_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/congestion_control/bbr_sender.cc b/chromium/net/third_party/quiche/src/quic/core/congestion_control/bbr_sender.cc
deleted file mode 100644
index 59b089d317d..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/congestion_control/bbr_sender.cc
+++ /dev/null
@@ -1,917 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/congestion_control/bbr_sender.h"
-
-#include <algorithm>
-#include <sstream>
-#include <string>
-
-#include "absl/base/attributes.h"
-#include "quic/core/congestion_control/rtt_stats.h"
-#include "quic/core/crypto/crypto_protocol.h"
-#include "quic/core/quic_time.h"
-#include "quic/core/quic_time_accumulator.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_flag_utils.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-namespace {
-// Constants based on TCP defaults.
-// The minimum CWND to ensure delayed acks don't reduce bandwidth measurements.
-// Does not inflate the pacing rate.
-const QuicByteCount kDefaultMinimumCongestionWindow = 4 * kMaxSegmentSize;
-
-// The gain used for the STARTUP, equal to 2/ln(2).
-const float kDefaultHighGain = 2.885f;
-// The newly derived gain for STARTUP, equal to 4 * ln(2)
-const float kDerivedHighGain = 2.773f;
-// The newly derived CWND gain for STARTUP, 2.
-const float kDerivedHighCWNDGain = 2.0f;
-// The cycle of gains used during the PROBE_BW stage.
-const float kPacingGain[] = {1.25, 0.75, 1, 1, 1, 1, 1, 1};
-
-// The length of the gain cycle.
-const size_t kGainCycleLength = sizeof(kPacingGain) / sizeof(kPacingGain[0]);
-// The size of the bandwidth filter window, in round-trips.
-const QuicRoundTripCount kBandwidthWindowSize = kGainCycleLength + 2;
-
-// The time after which the current min_rtt value expires.
-const QuicTime::Delta kMinRttExpiry = QuicTime::Delta::FromSeconds(10);
-// The minimum time the connection can spend in PROBE_RTT mode.
-const QuicTime::Delta kProbeRttTime = QuicTime::Delta::FromMilliseconds(200);
-// If the bandwidth does not increase by the factor of |kStartupGrowthTarget|
-// within |kRoundTripsWithoutGrowthBeforeExitingStartup| rounds, the connection
-// will exit the STARTUP mode.
-const float kStartupGrowthTarget = 1.25;
-const QuicRoundTripCount kRoundTripsWithoutGrowthBeforeExitingStartup = 3;
-} // namespace
-
-BbrSender::DebugState::DebugState(const BbrSender& sender)
- : mode(sender.mode_),
- max_bandwidth(sender.max_bandwidth_.GetBest()),
- round_trip_count(sender.round_trip_count_),
- gain_cycle_index(sender.cycle_current_offset_),
- congestion_window(sender.congestion_window_),
- is_at_full_bandwidth(sender.is_at_full_bandwidth_),
- bandwidth_at_last_round(sender.bandwidth_at_last_round_),
- rounds_without_bandwidth_gain(sender.rounds_without_bandwidth_gain_),
- min_rtt(sender.min_rtt_),
- min_rtt_timestamp(sender.min_rtt_timestamp_),
- recovery_state(sender.recovery_state_),
- recovery_window(sender.recovery_window_),
- last_sample_is_app_limited(sender.last_sample_is_app_limited_),
- end_of_app_limited_phase(sender.sampler_.end_of_app_limited_phase()) {}
-
-BbrSender::DebugState::DebugState(const DebugState& state) = default;
-
-BbrSender::BbrSender(QuicTime now,
- const RttStats* rtt_stats,
- const QuicUnackedPacketMap* unacked_packets,
- QuicPacketCount initial_tcp_congestion_window,
- QuicPacketCount max_tcp_congestion_window,
- QuicRandom* random,
- QuicConnectionStats* stats)
- : rtt_stats_(rtt_stats),
- unacked_packets_(unacked_packets),
- random_(random),
- stats_(stats),
- mode_(STARTUP),
- sampler_(unacked_packets, kBandwidthWindowSize),
- round_trip_count_(0),
- num_loss_events_in_round_(0),
- bytes_lost_in_round_(0),
- max_bandwidth_(kBandwidthWindowSize, QuicBandwidth::Zero(), 0),
- min_rtt_(QuicTime::Delta::Zero()),
- min_rtt_timestamp_(QuicTime::Zero()),
- congestion_window_(initial_tcp_congestion_window * kDefaultTCPMSS),
- initial_congestion_window_(initial_tcp_congestion_window *
- kDefaultTCPMSS),
- max_congestion_window_(max_tcp_congestion_window * kDefaultTCPMSS),
- min_congestion_window_(kDefaultMinimumCongestionWindow),
- high_gain_(kDefaultHighGain),
- high_cwnd_gain_(kDefaultHighGain),
- drain_gain_(1.f / kDefaultHighGain),
- pacing_rate_(QuicBandwidth::Zero()),
- pacing_gain_(1),
- congestion_window_gain_(1),
- congestion_window_gain_constant_(
- static_cast<float>(GetQuicFlag(FLAGS_quic_bbr_cwnd_gain))),
- num_startup_rtts_(kRoundTripsWithoutGrowthBeforeExitingStartup),
- cycle_current_offset_(0),
- last_cycle_start_(QuicTime::Zero()),
- is_at_full_bandwidth_(false),
- rounds_without_bandwidth_gain_(0),
- bandwidth_at_last_round_(QuicBandwidth::Zero()),
- exiting_quiescence_(false),
- exit_probe_rtt_at_(QuicTime::Zero()),
- probe_rtt_round_passed_(false),
- last_sample_is_app_limited_(false),
- has_non_app_limited_sample_(false),
- recovery_state_(NOT_IN_RECOVERY),
- recovery_window_(max_congestion_window_),
- slower_startup_(false),
- rate_based_startup_(false),
- enable_ack_aggregation_during_startup_(false),
- expire_ack_aggregation_in_startup_(false),
- drain_to_target_(false),
- detect_overshooting_(false),
- bytes_lost_while_detecting_overshooting_(0),
- bytes_lost_multiplier_while_detecting_overshooting_(2),
- cwnd_to_calculate_min_pacing_rate_(initial_congestion_window_),
- max_congestion_window_with_network_parameters_adjusted_(
- kMaxInitialCongestionWindow * kDefaultTCPMSS) {
- if (stats_) {
- // Clear some startup stats if |stats_| has been used by another sender,
- // which happens e.g. when QuicConnection switch send algorithms.
- stats_->slowstart_count = 0;
- stats_->slowstart_duration = QuicTimeAccumulator();
- }
- EnterStartupMode(now);
- set_high_cwnd_gain(kDerivedHighCWNDGain);
-}
-
-BbrSender::~BbrSender() {}
-
-void BbrSender::SetInitialCongestionWindowInPackets(
- QuicPacketCount congestion_window) {
- if (mode_ == STARTUP) {
- initial_congestion_window_ = congestion_window * kDefaultTCPMSS;
- congestion_window_ = congestion_window * kDefaultTCPMSS;
- cwnd_to_calculate_min_pacing_rate_ = std::min(
- initial_congestion_window_, cwnd_to_calculate_min_pacing_rate_);
- }
-}
-
-bool BbrSender::InSlowStart() const {
- return mode_ == STARTUP;
-}
-
-void BbrSender::OnPacketSent(QuicTime sent_time,
- QuicByteCount bytes_in_flight,
- QuicPacketNumber packet_number,
- QuicByteCount bytes,
- HasRetransmittableData is_retransmittable) {
- if (stats_ && InSlowStart()) {
- ++stats_->slowstart_packets_sent;
- stats_->slowstart_bytes_sent += bytes;
- }
-
- last_sent_packet_ = packet_number;
-
- if (bytes_in_flight == 0 && sampler_.is_app_limited()) {
- exiting_quiescence_ = true;
- }
-
- sampler_.OnPacketSent(sent_time, packet_number, bytes, bytes_in_flight,
- is_retransmittable);
-}
-
-void BbrSender::OnPacketNeutered(QuicPacketNumber packet_number) {
- sampler_.OnPacketNeutered(packet_number);
-}
-
-bool BbrSender::CanSend(QuicByteCount bytes_in_flight) {
- return bytes_in_flight < GetCongestionWindow();
-}
-
-QuicBandwidth BbrSender::PacingRate(QuicByteCount /*bytes_in_flight*/) const {
- if (pacing_rate_.IsZero()) {
- return high_gain_ * QuicBandwidth::FromBytesAndTimeDelta(
- initial_congestion_window_, GetMinRtt());
- }
- return pacing_rate_;
-}
-
-QuicBandwidth BbrSender::BandwidthEstimate() const {
- return max_bandwidth_.GetBest();
-}
-
-QuicByteCount BbrSender::GetCongestionWindow() const {
- if (mode_ == PROBE_RTT) {
- return ProbeRttCongestionWindow();
- }
-
- if (InRecovery()) {
- return std::min(congestion_window_, recovery_window_);
- }
-
- return congestion_window_;
-}
-
-QuicByteCount BbrSender::GetSlowStartThreshold() const {
- return 0;
-}
-
-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)) {
- num_startup_rtts_ = 1;
- }
- if (config.HasClientRequestedIndependentOption(k2RTT, perspective)) {
- num_startup_rtts_ = 2;
- }
- if (config.HasClientRequestedIndependentOption(kBBR3, perspective)) {
- drain_to_target_ = true;
- }
- if (config.HasClientRequestedIndependentOption(kBWM3, perspective)) {
- bytes_lost_multiplier_while_detecting_overshooting_ = 3;
- }
- if (config.HasClientRequestedIndependentOption(kBWM4, perspective)) {
- bytes_lost_multiplier_while_detecting_overshooting_ = 4;
- }
- if (config.HasClientRequestedIndependentOption(kBBR4, perspective)) {
- sampler_.SetMaxAckHeightTrackerWindowLength(2 * kBandwidthWindowSize);
- }
- if (config.HasClientRequestedIndependentOption(kBBR5, perspective)) {
- sampler_.SetMaxAckHeightTrackerWindowLength(4 * kBandwidthWindowSize);
- }
- if (config.HasClientRequestedIndependentOption(kBBQ1, perspective)) {
- set_high_gain(kDerivedHighGain);
- set_high_cwnd_gain(kDerivedHighGain);
- set_drain_gain(1.f / kDerivedHighGain);
- }
- if (config.HasClientRequestedIndependentOption(kBBQ3, perspective)) {
- enable_ack_aggregation_during_startup_ = true;
- }
- if (config.HasClientRequestedIndependentOption(kBBQ5, perspective)) {
- expire_ack_aggregation_in_startup_ = true;
- }
- if (config.HasClientRequestedIndependentOption(kMIN1, perspective)) {
- min_congestion_window_ = kMaxSegmentSize;
- }
- if (config.HasClientRequestedIndependentOption(kICW1, perspective)) {
- max_congestion_window_with_network_parameters_adjusted_ =
- 100 * kDefaultTCPMSS;
- }
- if (config.HasClientRequestedIndependentOption(kDTOS, perspective)) {
- detect_overshooting_ = true;
- // DTOS would allow pacing rate drop to IW 10 / min_rtt if overshooting is
- // detected.
- cwnd_to_calculate_min_pacing_rate_ =
- std::min(initial_congestion_window_, 10 * kDefaultTCPMSS);
- }
-
- ApplyConnectionOptions(config.ClientRequestedIndependentOptions(perspective));
-}
-
-void BbrSender::ApplyConnectionOptions(
- const QuicTagVector& connection_options) {
- if (ContainsQuicTag(connection_options, kBSAO)) {
- sampler_.EnableOverestimateAvoidance();
- }
- if (ContainsQuicTag(connection_options, kBBRA)) {
- sampler_.SetStartNewAggregationEpochAfterFullRound(true);
- }
- if (GetQuicReloadableFlag(quic_bbr_use_send_rate_in_max_ack_height_tracker) &&
- ContainsQuicTag(connection_options, kBBRB)) {
- QUIC_RELOADABLE_FLAG_COUNT_N(
- quic_bbr_use_send_rate_in_max_ack_height_tracker, 1, 2);
- sampler_.SetLimitMaxAckHeightTrackerBySendRate(true);
- }
-}
-
-void BbrSender::AdjustNetworkParameters(const NetworkParams& params) {
- const QuicBandwidth& bandwidth = params.bandwidth;
- const QuicTime::Delta& rtt = params.rtt;
-
- if (!rtt.IsZero() && (min_rtt_ > rtt || min_rtt_.IsZero())) {
- min_rtt_ = rtt;
- }
-
- if (mode_ == STARTUP) {
- if (bandwidth.IsZero()) {
- // Ignore bad bandwidth samples.
- return;
- }
-
- auto cwnd_bootstrapping_rtt = GetMinRtt();
- if (params.max_initial_congestion_window > 0) {
- max_congestion_window_with_network_parameters_adjusted_ =
- params.max_initial_congestion_window * kDefaultTCPMSS;
- }
- const QuicByteCount new_cwnd = std::max(
- kMinInitialCongestionWindow * kDefaultTCPMSS,
- std::min(max_congestion_window_with_network_parameters_adjusted_,
- bandwidth * cwnd_bootstrapping_rtt));
-
- stats_->cwnd_bootstrapping_rtt_us = cwnd_bootstrapping_rtt.ToMicroseconds();
- if (!rtt_stats_->smoothed_rtt().IsZero()) {
- QUIC_CODE_COUNT(quic_smoothed_rtt_available);
- } else if (rtt_stats_->initial_rtt() !=
- QuicTime::Delta::FromMilliseconds(kInitialRttMs)) {
- QUIC_CODE_COUNT(quic_client_initial_rtt_available);
- } else {
- QUIC_CODE_COUNT(quic_default_initial_rtt);
- }
- if (new_cwnd < congestion_window_ && !params.allow_cwnd_to_decrease) {
- // Only decrease cwnd if allow_cwnd_to_decrease is true.
- return;
- }
- if (GetQuicReloadableFlag(quic_conservative_cwnd_and_pacing_gains)) {
- // Decreases cwnd gain and pacing gain. Please note, if pacing_rate_ has
- // been calculated, it cannot decrease in STARTUP phase.
- QUIC_RELOADABLE_FLAG_COUNT(quic_conservative_cwnd_and_pacing_gains);
- set_high_gain(kDerivedHighCWNDGain);
- set_high_cwnd_gain(kDerivedHighCWNDGain);
- }
- congestion_window_ = new_cwnd;
-
- // Pace at the rate of new_cwnd / RTT.
- QuicBandwidth new_pacing_rate =
- QuicBandwidth::FromBytesAndTimeDelta(congestion_window_, GetMinRtt());
- pacing_rate_ = std::max(pacing_rate_, new_pacing_rate);
- detect_overshooting_ = true;
- }
-}
-
-void BbrSender::OnCongestionEvent(bool /*rtt_updated*/,
- QuicByteCount prior_in_flight,
- QuicTime event_time,
- const AckedPacketVector& acked_packets,
- const LostPacketVector& lost_packets) {
- const QuicByteCount total_bytes_acked_before = sampler_.total_bytes_acked();
- const QuicByteCount total_bytes_lost_before = sampler_.total_bytes_lost();
-
- bool is_round_start = false;
- bool min_rtt_expired = false;
- QuicByteCount excess_acked = 0;
- QuicByteCount bytes_lost = 0;
-
- // The send state of the largest packet in acked_packets, unless it is
- // empty. If acked_packets is empty, it's the send state of the largest
- // packet in lost_packets.
- SendTimeState last_packet_send_state;
-
- if (!acked_packets.empty()) {
- QuicPacketNumber last_acked_packet = acked_packets.rbegin()->packet_number;
- is_round_start = UpdateRoundTripCounter(last_acked_packet);
- UpdateRecoveryState(last_acked_packet, !lost_packets.empty(),
- is_round_start);
- }
-
- BandwidthSamplerInterface::CongestionEventSample sample =
- sampler_.OnCongestionEvent(event_time, acked_packets, lost_packets,
- max_bandwidth_.GetBest(),
- QuicBandwidth::Infinite(), round_trip_count_);
- if (sample.last_packet_send_state.is_valid) {
- last_sample_is_app_limited_ = sample.last_packet_send_state.is_app_limited;
- has_non_app_limited_sample_ |= !last_sample_is_app_limited_;
- if (stats_) {
- stats_->has_non_app_limited_sample = has_non_app_limited_sample_;
- }
- }
- // Avoid updating |max_bandwidth_| if a) this is a loss-only event, or b) all
- // packets in |acked_packets| did not generate valid samples. (e.g. ack of
- // ack-only packets). In both cases, sampler_.total_bytes_acked() will not
- // change.
- if (total_bytes_acked_before != sampler_.total_bytes_acked()) {
- QUIC_LOG_IF(WARNING, sample.sample_max_bandwidth.IsZero())
- << sampler_.total_bytes_acked() - total_bytes_acked_before
- << " bytes from " << acked_packets.size()
- << " packets have been acked, but sample_max_bandwidth is zero.";
- if (!sample.sample_is_app_limited ||
- sample.sample_max_bandwidth > max_bandwidth_.GetBest()) {
- max_bandwidth_.Update(sample.sample_max_bandwidth, round_trip_count_);
- }
- }
-
- if (!sample.sample_rtt.IsInfinite()) {
- min_rtt_expired = MaybeUpdateMinRtt(event_time, sample.sample_rtt);
- }
- bytes_lost = sampler_.total_bytes_lost() - total_bytes_lost_before;
- if (mode_ == STARTUP) {
- if (stats_) {
- stats_->slowstart_packets_lost += lost_packets.size();
- stats_->slowstart_bytes_lost += bytes_lost;
- }
- }
- excess_acked = sample.extra_acked;
- last_packet_send_state = sample.last_packet_send_state;
-
- if (!lost_packets.empty()) {
- ++num_loss_events_in_round_;
- bytes_lost_in_round_ += bytes_lost;
- }
-
- // Handle logic specific to PROBE_BW mode.
- if (mode_ == PROBE_BW) {
- UpdateGainCyclePhase(event_time, prior_in_flight, !lost_packets.empty());
- }
-
- // Handle logic specific to STARTUP and DRAIN modes.
- if (is_round_start && !is_at_full_bandwidth_) {
- CheckIfFullBandwidthReached(last_packet_send_state);
- }
- MaybeExitStartupOrDrain(event_time);
-
- // Handle logic specific to PROBE_RTT.
- MaybeEnterOrExitProbeRtt(event_time, is_round_start, min_rtt_expired);
-
- // Calculate number of packets acked and lost.
- QuicByteCount bytes_acked =
- sampler_.total_bytes_acked() - total_bytes_acked_before;
-
- // After the model is updated, recalculate the pacing rate and congestion
- // window.
- CalculatePacingRate(bytes_lost);
- CalculateCongestionWindow(bytes_acked, excess_acked);
- CalculateRecoveryWindow(bytes_acked, bytes_lost);
-
- // Cleanup internal state.
- sampler_.RemoveObsoletePackets(unacked_packets_->GetLeastUnacked());
- if (is_round_start) {
- num_loss_events_in_round_ = 0;
- bytes_lost_in_round_ = 0;
- }
-}
-
-CongestionControlType BbrSender::GetCongestionControlType() const {
- return kBBR;
-}
-
-QuicTime::Delta BbrSender::GetMinRtt() const {
- if (!min_rtt_.IsZero()) {
- return min_rtt_;
- }
- // min_rtt could be available if the handshake packet gets neutered then
- // gets acknowledged. This could only happen for QUIC crypto where we do not
- // drop keys.
- return rtt_stats_->MinOrInitialRtt();
-}
-
-QuicByteCount BbrSender::GetTargetCongestionWindow(float gain) const {
- QuicByteCount bdp = GetMinRtt() * BandwidthEstimate();
- QuicByteCount congestion_window = gain * bdp;
-
- // BDP estimate will be zero if no bandwidth samples are available yet.
- if (congestion_window == 0) {
- congestion_window = gain * initial_congestion_window_;
- }
-
- return std::max(congestion_window, min_congestion_window_);
-}
-
-QuicByteCount BbrSender::ProbeRttCongestionWindow() const {
- return min_congestion_window_;
-}
-
-void BbrSender::EnterStartupMode(QuicTime now) {
- if (stats_) {
- ++stats_->slowstart_count;
- stats_->slowstart_duration.Start(now);
- }
- mode_ = STARTUP;
- pacing_gain_ = high_gain_;
- congestion_window_gain_ = high_cwnd_gain_;
-}
-
-void BbrSender::EnterProbeBandwidthMode(QuicTime now) {
- mode_ = PROBE_BW;
- congestion_window_gain_ = congestion_window_gain_constant_;
-
- // Pick a random offset for the gain cycle out of {0, 2..7} range. 1 is
- // excluded because in that case increased gain and decreased gain would not
- // follow each other.
- cycle_current_offset_ = random_->RandUint64() % (kGainCycleLength - 1);
- if (cycle_current_offset_ >= 1) {
- cycle_current_offset_ += 1;
- }
-
- last_cycle_start_ = now;
- pacing_gain_ = kPacingGain[cycle_current_offset_];
-}
-
-bool BbrSender::UpdateRoundTripCounter(QuicPacketNumber last_acked_packet) {
- if (!current_round_trip_end_.IsInitialized() ||
- last_acked_packet > current_round_trip_end_) {
- round_trip_count_++;
- current_round_trip_end_ = last_sent_packet_;
- if (stats_ && InSlowStart()) {
- ++stats_->slowstart_num_rtts;
- }
- return true;
- }
-
- return false;
-}
-
-bool BbrSender::MaybeUpdateMinRtt(QuicTime now,
- QuicTime::Delta sample_min_rtt) {
- // Do not expire min_rtt if none was ever available.
- bool min_rtt_expired =
- !min_rtt_.IsZero() && (now > (min_rtt_timestamp_ + kMinRttExpiry));
-
- if (min_rtt_expired || sample_min_rtt < min_rtt_ || min_rtt_.IsZero()) {
- QUIC_DVLOG(2) << "Min RTT updated, old value: " << min_rtt_
- << ", new value: " << sample_min_rtt
- << ", current time: " << now.ToDebuggingValue();
-
- min_rtt_ = sample_min_rtt;
- min_rtt_timestamp_ = now;
- }
- QUICHE_DCHECK(!min_rtt_.IsZero());
-
- return min_rtt_expired;
-}
-
-void BbrSender::UpdateGainCyclePhase(QuicTime now,
- QuicByteCount prior_in_flight,
- bool has_losses) {
- const QuicByteCount bytes_in_flight = unacked_packets_->bytes_in_flight();
- // In most cases, the cycle is advanced after an RTT passes.
- bool should_advance_gain_cycling = now - last_cycle_start_ > GetMinRtt();
-
- // If the pacing gain is above 1.0, the connection is trying to probe the
- // bandwidth by increasing the number of bytes in flight to at least
- // pacing_gain * BDP. Make sure that it actually reaches the target, as long
- // as there are no losses suggesting that the buffers are not able to hold
- // that much.
- if (pacing_gain_ > 1.0 && !has_losses &&
- prior_in_flight < GetTargetCongestionWindow(pacing_gain_)) {
- should_advance_gain_cycling = false;
- }
-
- // If pacing gain is below 1.0, the connection is trying to drain the extra
- // queue which could have been incurred by probing prior to it. If the number
- // of bytes in flight falls down to the estimated BDP value earlier, conclude
- // that the queue has been successfully drained and exit this cycle early.
- if (pacing_gain_ < 1.0 && bytes_in_flight <= GetTargetCongestionWindow(1)) {
- should_advance_gain_cycling = true;
- }
-
- if (should_advance_gain_cycling) {
- cycle_current_offset_ = (cycle_current_offset_ + 1) % kGainCycleLength;
- if (cycle_current_offset_ == 0) {
- ++stats_->bbr_num_cycles;
- }
- last_cycle_start_ = now;
- // Stay in low gain mode until the target BDP is hit.
- // Low gain mode will be exited immediately when the target BDP is achieved.
- if (drain_to_target_ && pacing_gain_ < 1 &&
- kPacingGain[cycle_current_offset_] == 1 &&
- bytes_in_flight > GetTargetCongestionWindow(1)) {
- return;
- }
- pacing_gain_ = kPacingGain[cycle_current_offset_];
- }
-}
-
-void BbrSender::CheckIfFullBandwidthReached(
- const SendTimeState& last_packet_send_state) {
- if (last_sample_is_app_limited_) {
- return;
- }
-
- QuicBandwidth target = bandwidth_at_last_round_ * kStartupGrowthTarget;
- if (BandwidthEstimate() >= target) {
- bandwidth_at_last_round_ = BandwidthEstimate();
- rounds_without_bandwidth_gain_ = 0;
- if (expire_ack_aggregation_in_startup_) {
- // Expire old excess delivery measurements now that bandwidth increased.
- sampler_.ResetMaxAckHeightTracker(0, round_trip_count_);
- }
- return;
- }
-
- rounds_without_bandwidth_gain_++;
- if ((rounds_without_bandwidth_gain_ >= num_startup_rtts_) ||
- ShouldExitStartupDueToLoss(last_packet_send_state)) {
- QUICHE_DCHECK(has_non_app_limited_sample_);
- is_at_full_bandwidth_ = true;
- }
-}
-
-void BbrSender::MaybeExitStartupOrDrain(QuicTime now) {
- if (mode_ == STARTUP && is_at_full_bandwidth_) {
- OnExitStartup(now);
- mode_ = DRAIN;
- pacing_gain_ = drain_gain_;
- congestion_window_gain_ = high_cwnd_gain_;
- }
- if (mode_ == DRAIN &&
- unacked_packets_->bytes_in_flight() <= GetTargetCongestionWindow(1)) {
- EnterProbeBandwidthMode(now);
- }
-}
-
-void BbrSender::OnExitStartup(QuicTime now) {
- QUICHE_DCHECK_EQ(mode_, STARTUP);
- if (stats_) {
- stats_->slowstart_duration.Stop(now);
- }
-}
-
-bool BbrSender::ShouldExitStartupDueToLoss(
- const SendTimeState& last_packet_send_state) const {
- if (num_loss_events_in_round_ <
- GetQuicFlag(FLAGS_quic_bbr2_default_startup_full_loss_count) ||
- !last_packet_send_state.is_valid) {
- return false;
- }
-
- const QuicByteCount inflight_at_send = last_packet_send_state.bytes_in_flight;
-
- if (inflight_at_send > 0 && bytes_lost_in_round_ > 0) {
- if (bytes_lost_in_round_ >
- inflight_at_send *
- GetQuicFlag(FLAGS_quic_bbr2_default_loss_threshold)) {
- stats_->bbr_exit_startup_due_to_loss = true;
- return true;
- }
- return false;
- }
-
- return false;
-}
-
-void BbrSender::MaybeEnterOrExitProbeRtt(QuicTime now,
- bool is_round_start,
- bool min_rtt_expired) {
- if (min_rtt_expired && !exiting_quiescence_ && mode_ != PROBE_RTT) {
- if (InSlowStart()) {
- OnExitStartup(now);
- }
- mode_ = PROBE_RTT;
- pacing_gain_ = 1;
- // Do not decide on the time to exit PROBE_RTT until the |bytes_in_flight|
- // is at the target small value.
- exit_probe_rtt_at_ = QuicTime::Zero();
- }
-
- if (mode_ == PROBE_RTT) {
- sampler_.OnAppLimited();
-
- if (exit_probe_rtt_at_ == QuicTime::Zero()) {
- // If the window has reached the appropriate size, schedule exiting
- // PROBE_RTT. The CWND during PROBE_RTT is kMinimumCongestionWindow, but
- // we allow an extra packet since QUIC checks CWND before sending a
- // packet.
- if (unacked_packets_->bytes_in_flight() <
- ProbeRttCongestionWindow() + kMaxOutgoingPacketSize) {
- exit_probe_rtt_at_ = now + kProbeRttTime;
- probe_rtt_round_passed_ = false;
- }
- } else {
- if (is_round_start) {
- probe_rtt_round_passed_ = true;
- }
- if (now >= exit_probe_rtt_at_ && probe_rtt_round_passed_) {
- min_rtt_timestamp_ = now;
- if (!is_at_full_bandwidth_) {
- EnterStartupMode(now);
- } else {
- EnterProbeBandwidthMode(now);
- }
- }
- }
- }
-
- exiting_quiescence_ = false;
-}
-
-void BbrSender::UpdateRecoveryState(QuicPacketNumber last_acked_packet,
- bool has_losses,
- bool is_round_start) {
- // Disable recovery in startup, if loss-based exit is enabled.
- if (!is_at_full_bandwidth_) {
- return;
- }
-
- // Exit recovery when there are no losses for a round.
- if (has_losses) {
- end_recovery_at_ = last_sent_packet_;
- }
-
- switch (recovery_state_) {
- case NOT_IN_RECOVERY:
- // Enter conservation on the first loss.
- if (has_losses) {
- recovery_state_ = CONSERVATION;
- // This will cause the |recovery_window_| to be set to the correct
- // value in CalculateRecoveryWindow().
- recovery_window_ = 0;
- // Since the conservation phase is meant to be lasting for a whole
- // round, extend the current round as if it were started right now.
- current_round_trip_end_ = last_sent_packet_;
- }
- break;
-
- case CONSERVATION:
- if (is_round_start) {
- recovery_state_ = GROWTH;
- }
- ABSL_FALLTHROUGH_INTENDED;
-
- case GROWTH:
- // Exit recovery if appropriate.
- if (!has_losses && last_acked_packet > end_recovery_at_) {
- recovery_state_ = NOT_IN_RECOVERY;
- }
-
- break;
- }
-}
-
-void BbrSender::CalculatePacingRate(QuicByteCount bytes_lost) {
- if (BandwidthEstimate().IsZero()) {
- return;
- }
-
- QuicBandwidth target_rate = pacing_gain_ * BandwidthEstimate();
- if (is_at_full_bandwidth_) {
- pacing_rate_ = target_rate;
- return;
- }
-
- // Pace at the rate of initial_window / RTT as soon as RTT measurements are
- // available.
- if (pacing_rate_.IsZero() && !rtt_stats_->min_rtt().IsZero()) {
- pacing_rate_ = QuicBandwidth::FromBytesAndTimeDelta(
- initial_congestion_window_, rtt_stats_->min_rtt());
- return;
- }
-
- if (detect_overshooting_) {
- bytes_lost_while_detecting_overshooting_ += bytes_lost;
- // Check for overshooting with network parameters adjusted when pacing rate
- // > target_rate and loss has been detected.
- if (pacing_rate_ > target_rate &&
- bytes_lost_while_detecting_overshooting_ > 0) {
- if (has_non_app_limited_sample_ ||
- bytes_lost_while_detecting_overshooting_ *
- bytes_lost_multiplier_while_detecting_overshooting_ >
- initial_congestion_window_) {
- // We are fairly sure overshoot happens if 1) there is at least one
- // non app-limited bw sample or 2) half of IW gets lost. Slow pacing
- // rate.
- pacing_rate_ = std::max(
- target_rate, QuicBandwidth::FromBytesAndTimeDelta(
- cwnd_to_calculate_min_pacing_rate_, GetMinRtt()));
- if (stats_) {
- stats_->overshooting_detected_with_network_parameters_adjusted = true;
- }
- bytes_lost_while_detecting_overshooting_ = 0;
- detect_overshooting_ = false;
- }
- }
- }
-
- // Do not decrease the pacing rate during startup.
- pacing_rate_ = std::max(pacing_rate_, target_rate);
-}
-
-void BbrSender::CalculateCongestionWindow(QuicByteCount bytes_acked,
- QuicByteCount excess_acked) {
- if (mode_ == PROBE_RTT) {
- return;
- }
-
- QuicByteCount target_window =
- GetTargetCongestionWindow(congestion_window_gain_);
- if (is_at_full_bandwidth_) {
- // Add the max recently measured ack aggregation to CWND.
- target_window += sampler_.max_ack_height();
- } else if (enable_ack_aggregation_during_startup_) {
- // Add the most recent excess acked. Because CWND never decreases in
- // STARTUP, this will automatically create a very localized max filter.
- target_window += excess_acked;
- }
-
- // Instead of immediately setting the target CWND as the new one, BBR grows
- // the CWND towards |target_window| by only increasing it |bytes_acked| at a
- // time.
- if (is_at_full_bandwidth_) {
- congestion_window_ =
- std::min(target_window, congestion_window_ + bytes_acked);
- } else if (congestion_window_ < target_window ||
- sampler_.total_bytes_acked() < initial_congestion_window_) {
- // If the connection is not yet out of startup phase, do not decrease the
- // window.
- congestion_window_ = congestion_window_ + bytes_acked;
- }
-
- // Enforce the limits on the congestion window.
- congestion_window_ = std::max(congestion_window_, min_congestion_window_);
- congestion_window_ = std::min(congestion_window_, max_congestion_window_);
-}
-
-void BbrSender::CalculateRecoveryWindow(QuicByteCount bytes_acked,
- QuicByteCount bytes_lost) {
- if (recovery_state_ == NOT_IN_RECOVERY) {
- return;
- }
-
- // Set up the initial recovery window.
- if (recovery_window_ == 0) {
- recovery_window_ = unacked_packets_->bytes_in_flight() + bytes_acked;
- recovery_window_ = std::max(min_congestion_window_, recovery_window_);
- return;
- }
-
- // Remove losses from the recovery window, while accounting for a potential
- // integer underflow.
- recovery_window_ = recovery_window_ >= bytes_lost
- ? recovery_window_ - bytes_lost
- : kMaxSegmentSize;
-
- // In CONSERVATION mode, just subtracting losses is sufficient. In GROWTH,
- // release additional |bytes_acked| to achieve a slow-start-like behavior.
- if (recovery_state_ == GROWTH) {
- recovery_window_ += bytes_acked;
- }
-
- // Always allow sending at least |bytes_acked| in response.
- recovery_window_ = std::max(
- recovery_window_, unacked_packets_->bytes_in_flight() + bytes_acked);
- recovery_window_ = std::max(min_congestion_window_, recovery_window_);
-}
-
-std::string BbrSender::GetDebugState() const {
- std::ostringstream stream;
- stream << ExportDebugState();
- return stream.str();
-}
-
-void BbrSender::OnApplicationLimited(QuicByteCount bytes_in_flight) {
- if (bytes_in_flight >= GetCongestionWindow()) {
- return;
- }
-
- sampler_.OnAppLimited();
- QUIC_DVLOG(2) << "Becoming application limited. Last sent packet: "
- << last_sent_packet_ << ", CWND: " << GetCongestionWindow();
-}
-
-void BbrSender::PopulateConnectionStats(QuicConnectionStats* stats) const {
- stats->num_ack_aggregation_epochs = sampler_.num_ack_aggregation_epochs();
-}
-
-BbrSender::DebugState BbrSender::ExportDebugState() const {
- return DebugState(*this);
-}
-
-static std::string ModeToString(BbrSender::Mode mode) {
- switch (mode) {
- case BbrSender::STARTUP:
- return "STARTUP";
- case BbrSender::DRAIN:
- return "DRAIN";
- case BbrSender::PROBE_BW:
- return "PROBE_BW";
- case BbrSender::PROBE_RTT:
- return "PROBE_RTT";
- }
- return "???";
-}
-
-std::ostream& operator<<(std::ostream& os, const BbrSender::Mode& mode) {
- os << ModeToString(mode);
- return os;
-}
-
-std::ostream& operator<<(std::ostream& os, const BbrSender::DebugState& state) {
- os << "Mode: " << ModeToString(state.mode) << std::endl;
- os << "Maximum bandwidth: " << state.max_bandwidth << std::endl;
- os << "Round trip counter: " << state.round_trip_count << std::endl;
- os << "Gain cycle index: " << static_cast<int>(state.gain_cycle_index)
- << std::endl;
- os << "Congestion window: " << state.congestion_window << " bytes"
- << std::endl;
-
- if (state.mode == BbrSender::STARTUP) {
- os << "(startup) Bandwidth at last round: " << state.bandwidth_at_last_round
- << std::endl;
- os << "(startup) Rounds without gain: "
- << state.rounds_without_bandwidth_gain << std::endl;
- }
-
- os << "Minimum RTT: " << state.min_rtt << std::endl;
- os << "Minimum RTT timestamp: " << state.min_rtt_timestamp.ToDebuggingValue()
- << std::endl;
-
- os << "Last sample is app-limited: "
- << (state.last_sample_is_app_limited ? "yes" : "no");
-
- return os;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/congestion_control/bbr_sender.h b/chromium/net/third_party/quiche/src/quic/core/congestion_control/bbr_sender.h
deleted file mode 100644
index ea6410ff753..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/congestion_control/bbr_sender.h
+++ /dev/null
@@ -1,396 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// BBR (Bottleneck Bandwidth and RTT) congestion control algorithm.
-
-#ifndef QUICHE_QUIC_CORE_CONGESTION_CONTROL_BBR_SENDER_H_
-#define QUICHE_QUIC_CORE_CONGESTION_CONTROL_BBR_SENDER_H_
-
-#include <cstdint>
-#include <ostream>
-#include <string>
-
-#include "quic/core/congestion_control/bandwidth_sampler.h"
-#include "quic/core/congestion_control/send_algorithm_interface.h"
-#include "quic/core/congestion_control/windowed_filter.h"
-#include "quic/core/crypto/quic_random.h"
-#include "quic/core/quic_bandwidth.h"
-#include "quic/core/quic_packet_number.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_time.h"
-#include "quic/core/quic_unacked_packet_map.h"
-#include "quic/platform/api/quic_export.h"
-#include "quic/platform/api/quic_flags.h"
-
-namespace quic {
-
-class RttStats;
-
-// BbrSender implements BBR congestion control algorithm. BBR aims to estimate
-// the current available Bottleneck Bandwidth and RTT (hence the name), and
-// regulates the pacing rate and the size of the congestion window based on
-// those signals.
-//
-// BBR relies on pacing in order to function properly. Do not use BBR when
-// pacing is disabled.
-//
-// TODO(vasilvv): implement traffic policer (long-term sampling) mode.
-class QUIC_EXPORT_PRIVATE BbrSender : public SendAlgorithmInterface {
- public:
- enum Mode {
- // Startup phase of the connection.
- STARTUP,
- // After achieving the highest possible bandwidth during the startup, lower
- // the pacing rate in order to drain the queue.
- DRAIN,
- // Cruising mode.
- PROBE_BW,
- // Temporarily slow down sending in order to empty the buffer and measure
- // the real minimum RTT.
- PROBE_RTT,
- };
-
- // Indicates how the congestion control limits the amount of bytes in flight.
- enum RecoveryState {
- // Do not limit.
- NOT_IN_RECOVERY,
- // Allow an extra outstanding byte for each byte acknowledged.
- CONSERVATION,
- // Allow two extra outstanding bytes for each byte acknowledged (slow
- // start).
- GROWTH
- };
-
- // Debug state can be exported in order to troubleshoot potential congestion
- // control issues.
- struct QUIC_EXPORT_PRIVATE DebugState {
- explicit DebugState(const BbrSender& sender);
- DebugState(const DebugState& state);
-
- Mode mode;
- QuicBandwidth max_bandwidth;
- QuicRoundTripCount round_trip_count;
- int gain_cycle_index;
- QuicByteCount congestion_window;
-
- bool is_at_full_bandwidth;
- QuicBandwidth bandwidth_at_last_round;
- QuicRoundTripCount rounds_without_bandwidth_gain;
-
- QuicTime::Delta min_rtt;
- QuicTime min_rtt_timestamp;
-
- RecoveryState recovery_state;
- QuicByteCount recovery_window;
-
- bool last_sample_is_app_limited;
- QuicPacketNumber end_of_app_limited_phase;
- };
-
- BbrSender(QuicTime now,
- const RttStats* rtt_stats,
- const QuicUnackedPacketMap* unacked_packets,
- QuicPacketCount initial_tcp_congestion_window,
- QuicPacketCount max_tcp_congestion_window,
- QuicRandom* random,
- QuicConnectionStats* stats);
- BbrSender(const BbrSender&) = delete;
- BbrSender& operator=(const BbrSender&) = delete;
- ~BbrSender() override;
-
- // Start implementation of SendAlgorithmInterface.
- bool InSlowStart() const override;
- bool InRecovery() const override;
- bool ShouldSendProbingPacket() const override;
-
- void SetFromConfig(const QuicConfig& config,
- Perspective perspective) override;
- void ApplyConnectionOptions(const QuicTagVector& connection_options) override;
-
- void AdjustNetworkParameters(const NetworkParams& params) override;
- void SetInitialCongestionWindowInPackets(
- QuicPacketCount congestion_window) override;
- void OnCongestionEvent(bool rtt_updated,
- QuicByteCount prior_in_flight,
- QuicTime event_time,
- const AckedPacketVector& acked_packets,
- const LostPacketVector& lost_packets) override;
- void OnPacketSent(QuicTime sent_time,
- QuicByteCount bytes_in_flight,
- QuicPacketNumber packet_number,
- QuicByteCount bytes,
- HasRetransmittableData is_retransmittable) override;
- void OnPacketNeutered(QuicPacketNumber packet_number) override;
- void OnRetransmissionTimeout(bool /*packets_retransmitted*/) override {}
- void OnConnectionMigration() override {}
- bool CanSend(QuicByteCount bytes_in_flight) override;
- QuicBandwidth PacingRate(QuicByteCount bytes_in_flight) const override;
- QuicBandwidth BandwidthEstimate() const override;
- QuicByteCount GetCongestionWindow() const override;
- QuicByteCount GetSlowStartThreshold() const override;
- CongestionControlType GetCongestionControlType() const override;
- std::string GetDebugState() const override;
- void OnApplicationLimited(QuicByteCount bytes_in_flight) override;
- void PopulateConnectionStats(QuicConnectionStats* stats) const override;
- // End implementation of SendAlgorithmInterface.
-
- // Gets the number of RTTs BBR remains in STARTUP phase.
- QuicRoundTripCount num_startup_rtts() const { return num_startup_rtts_; }
- bool has_non_app_limited_sample() const {
- return has_non_app_limited_sample_;
- }
-
- // Sets the pacing gain used in STARTUP. Must be greater than 1.
- void set_high_gain(float high_gain) {
- QUICHE_DCHECK_LT(1.0f, high_gain);
- high_gain_ = high_gain;
- if (mode_ == STARTUP) {
- pacing_gain_ = high_gain;
- }
- }
-
- // Sets the CWND gain used in STARTUP. Must be greater than 1.
- void set_high_cwnd_gain(float high_cwnd_gain) {
- QUICHE_DCHECK_LT(1.0f, high_cwnd_gain);
- high_cwnd_gain_ = high_cwnd_gain;
- if (mode_ == STARTUP) {
- congestion_window_gain_ = high_cwnd_gain;
- }
- }
-
- // Sets the gain used in DRAIN. Must be less than 1.
- void set_drain_gain(float drain_gain) {
- QUICHE_DCHECK_GT(1.0f, drain_gain);
- drain_gain_ = drain_gain;
- }
-
- // Returns the current estimate of the RTT of the connection. Outside of the
- // edge cases, this is minimum RTT.
- QuicTime::Delta GetMinRtt() const;
-
- DebugState ExportDebugState() const;
-
- private:
- // For switching send algorithm mid connection.
- friend class Bbr2Sender;
-
- using MaxBandwidthFilter = WindowedFilter<QuicBandwidth,
- MaxFilter<QuicBandwidth>,
- QuicRoundTripCount,
- QuicRoundTripCount>;
-
- using MaxAckHeightFilter = WindowedFilter<QuicByteCount,
- MaxFilter<QuicByteCount>,
- QuicRoundTripCount,
- QuicRoundTripCount>;
-
- // Computes the target congestion window using the specified gain.
- QuicByteCount GetTargetCongestionWindow(float gain) const;
- // The target congestion window during PROBE_RTT.
- QuicByteCount ProbeRttCongestionWindow() const;
- bool MaybeUpdateMinRtt(QuicTime now, QuicTime::Delta sample_min_rtt);
-
- // Enters the STARTUP mode.
- void EnterStartupMode(QuicTime now);
- // Enters the PROBE_BW mode.
- void EnterProbeBandwidthMode(QuicTime now);
-
- // Updates the round-trip counter if a round-trip has passed. Returns true if
- // the counter has been advanced.
- bool UpdateRoundTripCounter(QuicPacketNumber last_acked_packet);
-
- // Updates the current gain used in PROBE_BW mode.
- void UpdateGainCyclePhase(QuicTime now,
- QuicByteCount prior_in_flight,
- bool has_losses);
- // Tracks for how many round-trips the bandwidth has not increased
- // significantly.
- void CheckIfFullBandwidthReached(const SendTimeState& last_packet_send_state);
- // Transitions from STARTUP to DRAIN and from DRAIN to PROBE_BW if
- // appropriate.
- void MaybeExitStartupOrDrain(QuicTime now);
- // Decides whether to enter or exit PROBE_RTT.
- void MaybeEnterOrExitProbeRtt(QuicTime now,
- bool is_round_start,
- bool min_rtt_expired);
- // Determines whether BBR needs to enter, exit or advance state of the
- // recovery.
- void UpdateRecoveryState(QuicPacketNumber last_acked_packet,
- bool has_losses,
- bool is_round_start);
-
- // Updates the ack aggregation max filter in bytes.
- // Returns the most recent addition to the filter, or |newly_acked_bytes| if
- // nothing was fed in to the filter.
- QuicByteCount UpdateAckAggregationBytes(QuicTime ack_time,
- QuicByteCount newly_acked_bytes);
-
- // Determines the appropriate pacing rate for the connection.
- void CalculatePacingRate(QuicByteCount bytes_lost);
- // Determines the appropriate congestion window for the connection.
- void CalculateCongestionWindow(QuicByteCount bytes_acked,
- QuicByteCount excess_acked);
- // Determines the appropriate window that constrains the in-flight during
- // recovery.
- void CalculateRecoveryWindow(QuicByteCount bytes_acked,
- QuicByteCount bytes_lost);
-
- // Called right before exiting STARTUP.
- void OnExitStartup(QuicTime now);
-
- // Return whether we should exit STARTUP due to excessive loss.
- bool ShouldExitStartupDueToLoss(
- const SendTimeState& last_packet_send_state) const;
-
- const RttStats* rtt_stats_;
- const QuicUnackedPacketMap* unacked_packets_;
- QuicRandom* random_;
- QuicConnectionStats* stats_;
-
- Mode mode_;
-
- // Bandwidth sampler provides BBR with the bandwidth measurements at
- // individual points.
- BandwidthSampler sampler_;
-
- // The number of the round trips that have occurred during the connection.
- QuicRoundTripCount round_trip_count_;
-
- // The packet number of the most recently sent packet.
- QuicPacketNumber last_sent_packet_;
- // Acknowledgement of any packet after |current_round_trip_end_| will cause
- // the round trip counter to advance.
- QuicPacketNumber current_round_trip_end_;
-
- // Number of congestion events with some losses, in the current round.
- int64_t num_loss_events_in_round_;
-
- // Number of total bytes lost in the current round.
- QuicByteCount bytes_lost_in_round_;
-
- // The filter that tracks the maximum bandwidth over the multiple recent
- // round-trips.
- MaxBandwidthFilter max_bandwidth_;
-
- // Minimum RTT estimate. Automatically expires within 10 seconds (and
- // triggers PROBE_RTT mode) if no new value is sampled during that period.
- QuicTime::Delta min_rtt_;
- // The time at which the current value of |min_rtt_| was assigned.
- QuicTime min_rtt_timestamp_;
-
- // The maximum allowed number of bytes in flight.
- QuicByteCount congestion_window_;
-
- // The initial value of the |congestion_window_|.
- QuicByteCount initial_congestion_window_;
-
- // The largest value the |congestion_window_| can achieve.
- QuicByteCount max_congestion_window_;
-
- // The smallest value the |congestion_window_| can achieve.
- QuicByteCount min_congestion_window_;
-
- // The pacing gain applied during the STARTUP phase.
- float high_gain_;
-
- // The CWND gain applied during the STARTUP phase.
- float high_cwnd_gain_;
-
- // The pacing gain applied during the DRAIN phase.
- float drain_gain_;
-
- // The current pacing rate of the connection.
- QuicBandwidth pacing_rate_;
-
- // The gain currently applied to the pacing rate.
- float pacing_gain_;
- // The gain currently applied to the congestion window.
- float congestion_window_gain_;
-
- // The gain used for the congestion window during PROBE_BW. Latched from
- // quic_bbr_cwnd_gain flag.
- const float congestion_window_gain_constant_;
- // The number of RTTs to stay in STARTUP mode. Defaults to 3.
- QuicRoundTripCount num_startup_rtts_;
-
- // Number of round-trips in PROBE_BW mode, used for determining the current
- // pacing gain cycle.
- int cycle_current_offset_;
- // The time at which the last pacing gain cycle was started.
- QuicTime last_cycle_start_;
-
- // Indicates whether the connection has reached the full bandwidth mode.
- bool is_at_full_bandwidth_;
- // Number of rounds during which there was no significant bandwidth increase.
- QuicRoundTripCount rounds_without_bandwidth_gain_;
- // The bandwidth compared to which the increase is measured.
- QuicBandwidth bandwidth_at_last_round_;
-
- // Set to true upon exiting quiescence.
- bool exiting_quiescence_;
-
- // Time at which PROBE_RTT has to be exited. Setting it to zero indicates
- // that the time is yet unknown as the number of packets in flight has not
- // reached the required value.
- QuicTime exit_probe_rtt_at_;
- // Indicates whether a round-trip has passed since PROBE_RTT became active.
- bool probe_rtt_round_passed_;
-
- // Indicates whether the most recent bandwidth sample was marked as
- // app-limited.
- bool last_sample_is_app_limited_;
- // Indicates whether any non app-limited samples have been recorded.
- bool has_non_app_limited_sample_;
-
- // Current state of recovery.
- RecoveryState recovery_state_;
- // Receiving acknowledgement of a packet after |end_recovery_at_| will cause
- // BBR to exit the recovery mode. A value above zero indicates at least one
- // loss has been detected, so it must not be set back to zero.
- QuicPacketNumber end_recovery_at_;
- // A window used to limit the number of bytes in flight during loss recovery.
- QuicByteCount recovery_window_;
- // If true, consider all samples in recovery app-limited.
- bool is_app_limited_recovery_;
-
- // When true, pace at 1.5x and disable packet conservation in STARTUP.
- bool slower_startup_;
- // When true, disables packet conservation in STARTUP.
- bool rate_based_startup_;
-
- // When true, add the most recent ack aggregation measurement during STARTUP.
- bool enable_ack_aggregation_during_startup_;
- // When true, expire the windowed ack aggregation values in STARTUP when
- // bandwidth increases more than 25%.
- bool expire_ack_aggregation_in_startup_;
-
- // If true, will not exit low gain mode until bytes_in_flight drops below BDP
- // or it's time for high gain mode.
- bool drain_to_target_;
-
- // If true, slow down pacing rate in STARTUP when overshooting is detected.
- bool detect_overshooting_;
- // Bytes lost while detect_overshooting_ is true.
- QuicByteCount bytes_lost_while_detecting_overshooting_;
- // Slow down pacing rate if
- // bytes_lost_while_detecting_overshooting_ *
- // bytes_lost_multiplier_while_detecting_overshooting_ > IW.
- uint8_t bytes_lost_multiplier_while_detecting_overshooting_;
- // When overshooting is detected, do not drop pacing_rate_ below this value /
- // min_rtt.
- QuicByteCount cwnd_to_calculate_min_pacing_rate_;
-
- // Max congestion window when adjusting network parameters.
- QuicByteCount max_congestion_window_with_network_parameters_adjusted_;
-};
-
-QUIC_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
- const BbrSender::Mode& mode);
-QUIC_EXPORT_PRIVATE std::ostream& operator<<(
- std::ostream& os,
- const BbrSender::DebugState& state);
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_CONGESTION_CONTROL_BBR_SENDER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/congestion_control/bbr_sender_test.cc b/chromium/net/third_party/quiche/src/quic/core/congestion_control/bbr_sender_test.cc
deleted file mode 100644
index caba9b1c7f4..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/congestion_control/bbr_sender_test.cc
+++ /dev/null
@@ -1,1332 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/congestion_control/bbr_sender.h"
-
-#include <algorithm>
-#include <map>
-#include <memory>
-#include <utility>
-
-#include "quic/core/congestion_control/rtt_stats.h"
-#include "quic/core/crypto/crypto_protocol.h"
-#include "quic/core/quic_bandwidth.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/mock_clock.h"
-#include "quic/test_tools/quic_config_peer.h"
-#include "quic/test_tools/quic_connection_peer.h"
-#include "quic/test_tools/quic_sent_packet_manager_peer.h"
-#include "quic/test_tools/quic_test_utils.h"
-#include "quic/test_tools/send_algorithm_test_result.pb.h"
-#include "quic/test_tools/send_algorithm_test_utils.h"
-#include "quic/test_tools/simulator/quic_endpoint.h"
-#include "quic/test_tools/simulator/simulator.h"
-#include "quic/test_tools/simulator/switch.h"
-#include "common/platform/api/quiche_command_line_flags.h"
-
-using testing::AllOf;
-using testing::Ge;
-using testing::Le;
-
-DEFINE_QUICHE_COMMAND_LINE_FLAG(
- std::string, quic_bbr_test_regression_mode, "",
- "One of a) 'record' to record test result (one file per test), or "
- "b) 'regress' to regress against recorded results, or "
- "c) <anything else> for non-regression mode.");
-
-namespace quic {
-namespace test {
-
-// Use the initial CWND of 10, as 32 is too much for the test network.
-const uint32_t kInitialCongestionWindowPackets = 10;
-const uint32_t kDefaultWindowTCP =
- kInitialCongestionWindowPackets * kDefaultTCPMSS;
-
-// Test network parameters. Here, the topology of the network is:
-//
-// BBR sender
-// |
-// | <-- local link (10 Mbps, 2 ms delay)
-// |
-// Network switch
-// * <-- the bottleneck queue in the direction
-// | of the receiver
-// |
-// | <-- test link (4 Mbps, 30 ms delay)
-// |
-// |
-// Receiver
-//
-// The reason the bandwidths chosen are relatively low is the fact that the
-// connection simulator uses QuicTime for its internal clock, and as such has
-// the granularity of 1us, meaning that at bandwidth higher than 20 Mbps the
-// packets can start to land on the same timestamp.
-const QuicBandwidth kTestLinkBandwidth =
- QuicBandwidth::FromKBitsPerSecond(4000);
-const QuicBandwidth kLocalLinkBandwidth =
- QuicBandwidth::FromKBitsPerSecond(10000);
-const QuicTime::Delta kTestPropagationDelay =
- QuicTime::Delta::FromMilliseconds(30);
-const QuicTime::Delta kLocalPropagationDelay =
- QuicTime::Delta::FromMilliseconds(2);
-const QuicTime::Delta kTestTransferTime =
- kTestLinkBandwidth.TransferTime(kMaxOutgoingPacketSize) +
- kLocalLinkBandwidth.TransferTime(kMaxOutgoingPacketSize);
-const QuicTime::Delta kTestRtt =
- (kTestPropagationDelay + kLocalPropagationDelay + kTestTransferTime) * 2;
-const QuicByteCount kTestBdp = kTestRtt * kTestLinkBandwidth;
-
-class BbrSenderTest : public QuicTest {
- protected:
- BbrSenderTest()
- : simulator_(&random_),
- bbr_sender_(&simulator_,
- "BBR sender",
- "Receiver",
- Perspective::IS_CLIENT,
- /*connection_id=*/TestConnectionId(42)),
- competing_sender_(&simulator_,
- "Competing sender",
- "Competing receiver",
- Perspective::IS_CLIENT,
- /*connection_id=*/TestConnectionId(43)),
- receiver_(&simulator_,
- "Receiver",
- "BBR sender",
- Perspective::IS_SERVER,
- /*connection_id=*/TestConnectionId(42)),
- competing_receiver_(&simulator_,
- "Competing receiver",
- "Competing sender",
- Perspective::IS_SERVER,
- /*connection_id=*/TestConnectionId(43)),
- receiver_multiplexer_("Receiver multiplexer",
- {&receiver_, &competing_receiver_}) {
- rtt_stats_ = bbr_sender_.connection()->sent_packet_manager().GetRttStats();
- const int kTestMaxPacketSize = 1350;
- bbr_sender_.connection()->SetMaxPacketLength(kTestMaxPacketSize);
- sender_ = SetupBbrSender(&bbr_sender_);
- SetConnectionOption(kBBRA);
- clock_ = simulator_.GetClock();
- }
-
- void SetUp() override {
- if (GetQuicFlag(FLAGS_quic_bbr_test_regression_mode) == "regress") {
- SendAlgorithmTestResult expected;
- ASSERT_TRUE(LoadSendAlgorithmTestResult(&expected));
- random_seed_ = expected.random_seed();
- } else {
- random_seed_ = QuicRandom::GetInstance()->RandUint64();
- }
- random_.set_seed(random_seed_);
- QUIC_LOG(INFO) << "BbrSenderTest simulator set up. Seed: " << random_seed_;
- }
-
- ~BbrSenderTest() {
- const std::string regression_mode =
- GetQuicFlag(FLAGS_quic_bbr_test_regression_mode);
- const QuicTime::Delta simulated_duration = clock_->Now() - QuicTime::Zero();
- if (regression_mode == "record") {
- RecordSendAlgorithmTestResult(random_seed_,
- simulated_duration.ToMicroseconds());
- } else if (regression_mode == "regress") {
- CompareSendAlgorithmTestResult(simulated_duration.ToMicroseconds());
- }
- }
-
- uint64_t random_seed_;
- SimpleRandom random_;
- simulator::Simulator simulator_;
- simulator::QuicEndpoint bbr_sender_;
- simulator::QuicEndpoint competing_sender_;
- simulator::QuicEndpoint receiver_;
- simulator::QuicEndpoint competing_receiver_;
- simulator::QuicEndpointMultiplexer receiver_multiplexer_;
- std::unique_ptr<simulator::Switch> switch_;
- std::unique_ptr<simulator::SymmetricLink> bbr_sender_link_;
- std::unique_ptr<simulator::SymmetricLink> competing_sender_link_;
- std::unique_ptr<simulator::SymmetricLink> receiver_link_;
-
- // Owned by different components of the connection.
- const QuicClock* clock_;
- const RttStats* rtt_stats_;
- BbrSender* sender_;
-
- // Enables BBR on |endpoint| and returns the associated BBR congestion
- // controller.
- BbrSender* SetupBbrSender(simulator::QuicEndpoint* endpoint) {
- const RttStats* rtt_stats =
- endpoint->connection()->sent_packet_manager().GetRttStats();
- // Ownership of the sender will be overtaken by the endpoint.
- BbrSender* sender = new BbrSender(
- endpoint->connection()->clock()->Now(), rtt_stats,
- QuicSentPacketManagerPeer::GetUnackedPacketMap(
- QuicConnectionPeer::GetSentPacketManager(endpoint->connection())),
- kInitialCongestionWindowPackets,
- GetQuicFlag(FLAGS_quic_max_congestion_window), &random_,
- QuicConnectionPeer::GetStats(endpoint->connection()));
- QuicConnectionPeer::SetSendAlgorithm(endpoint->connection(), sender);
- endpoint->RecordTrace();
- return sender;
- }
-
- // Creates a default setup, which is a network with a bottleneck between the
- // receiver and the switch. The switch has the buffers four times larger than
- // the bottleneck BDP, which should guarantee a lack of losses.
- void CreateDefaultSetup() {
- switch_ = std::make_unique<simulator::Switch>(&simulator_, "Switch", 8,
- 2 * kTestBdp);
- bbr_sender_link_ = std::make_unique<simulator::SymmetricLink>(
- &bbr_sender_, switch_->port(1), kLocalLinkBandwidth,
- kLocalPropagationDelay);
- receiver_link_ = std::make_unique<simulator::SymmetricLink>(
- &receiver_, switch_->port(2), kTestLinkBandwidth,
- kTestPropagationDelay);
- }
-
- // Same as the default setup, except the buffer now is half of the BDP.
- void CreateSmallBufferSetup() {
- switch_ = std::make_unique<simulator::Switch>(&simulator_, "Switch", 8,
- 0.5 * kTestBdp);
- bbr_sender_link_ = std::make_unique<simulator::SymmetricLink>(
- &bbr_sender_, switch_->port(1), kLocalLinkBandwidth,
- kLocalPropagationDelay);
- receiver_link_ = std::make_unique<simulator::SymmetricLink>(
- &receiver_, switch_->port(2), kTestLinkBandwidth,
- kTestPropagationDelay);
- }
-
- // Creates the variation of the default setup in which there is another sender
- // that competes for the same bottleneck link.
- void CreateCompetitionSetup() {
- switch_ = std::make_unique<simulator::Switch>(&simulator_, "Switch", 8,
- 2 * kTestBdp);
-
- // Add a small offset to the competing link in order to avoid
- // synchronization effects.
- const QuicTime::Delta small_offset = QuicTime::Delta::FromMicroseconds(3);
- bbr_sender_link_ = std::make_unique<simulator::SymmetricLink>(
- &bbr_sender_, switch_->port(1), kLocalLinkBandwidth,
- kLocalPropagationDelay);
- competing_sender_link_ = std::make_unique<simulator::SymmetricLink>(
- &competing_sender_, switch_->port(3), kLocalLinkBandwidth,
- kLocalPropagationDelay + small_offset);
- receiver_link_ = std::make_unique<simulator::SymmetricLink>(
- &receiver_multiplexer_, switch_->port(2), kTestLinkBandwidth,
- kTestPropagationDelay);
- }
-
- // Creates a BBR vs BBR competition setup.
- void CreateBbrVsBbrSetup() {
- SetupBbrSender(&competing_sender_);
- CreateCompetitionSetup();
- }
-
- void EnableAggregation(QuicByteCount aggregation_bytes,
- QuicTime::Delta aggregation_timeout) {
- // Enable aggregation on the path from the receiver to the sender.
- switch_->port_queue(1)->EnableAggregation(aggregation_bytes,
- aggregation_timeout);
- }
-
- void DoSimpleTransfer(QuicByteCount transfer_size, QuicTime::Delta deadline) {
- bbr_sender_.AddBytesToTransfer(transfer_size);
- // TODO(vasilvv): consider rewriting this to run until the receiver actually
- // receives the intended amount of bytes.
- bool simulator_result = simulator_.RunUntilOrTimeout(
- [this]() { return bbr_sender_.bytes_to_transfer() == 0; }, deadline);
- EXPECT_TRUE(simulator_result)
- << "Simple transfer failed. Bytes remaining: "
- << bbr_sender_.bytes_to_transfer();
- QUIC_LOG(INFO) << "Simple transfer state: " << sender_->ExportDebugState();
- }
-
- // Drive the simulator by sending enough data to enter PROBE_BW.
- void DriveOutOfStartup() {
- ASSERT_FALSE(sender_->ExportDebugState().is_at_full_bandwidth);
- DoSimpleTransfer(1024 * 1024, QuicTime::Delta::FromSeconds(15));
- EXPECT_EQ(BbrSender::PROBE_BW, sender_->ExportDebugState().mode);
- EXPECT_APPROX_EQ(kTestLinkBandwidth,
- sender_->ExportDebugState().max_bandwidth, 0.02f);
- }
-
- // Send |bytes|-sized bursts of data |number_of_bursts| times, waiting for
- // |wait_time| between each burst.
- void SendBursts(size_t number_of_bursts,
- QuicByteCount bytes,
- QuicTime::Delta wait_time) {
- ASSERT_EQ(0u, bbr_sender_.bytes_to_transfer());
- for (size_t i = 0; i < number_of_bursts; i++) {
- bbr_sender_.AddBytesToTransfer(bytes);
-
- // Transfer data and wait for three seconds between each transfer.
- simulator_.RunFor(wait_time);
-
- // Ensure the connection did not time out.
- ASSERT_TRUE(bbr_sender_.connection()->connected());
- ASSERT_TRUE(receiver_.connection()->connected());
- }
-
- simulator_.RunFor(wait_time + kTestRtt);
- ASSERT_EQ(0u, bbr_sender_.bytes_to_transfer());
- }
-
- void SetConnectionOption(QuicTag option) {
- QuicConfig config;
- QuicTagVector options;
- options.push_back(option);
- QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
- sender_->SetFromConfig(config, Perspective::IS_SERVER);
- }
-};
-
-TEST_F(BbrSenderTest, SetInitialCongestionWindow) {
- EXPECT_NE(3u * kDefaultTCPMSS, sender_->GetCongestionWindow());
- sender_->SetInitialCongestionWindowInPackets(3);
- EXPECT_EQ(3u * kDefaultTCPMSS, sender_->GetCongestionWindow());
-}
-
-// Test a simple long data transfer in the default setup.
-TEST_F(BbrSenderTest, SimpleTransfer) {
- CreateDefaultSetup();
-
- // At startup make sure we are at the default.
- EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow());
- // At startup make sure we can send.
- EXPECT_TRUE(sender_->CanSend(0));
- // And that window is un-affected.
- EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow());
-
- // Verify that Sender is in slow start.
- EXPECT_TRUE(sender_->InSlowStart());
-
- // Verify that pacing rate is based on the initial RTT.
- QuicBandwidth expected_pacing_rate = QuicBandwidth::FromBytesAndTimeDelta(
- 2.885 * kDefaultWindowTCP, rtt_stats_->initial_rtt());
- EXPECT_APPROX_EQ(expected_pacing_rate.ToBitsPerSecond(),
- sender_->PacingRate(0).ToBitsPerSecond(), 0.01f);
-
- ASSERT_GE(kTestBdp, kDefaultWindowTCP + kDefaultTCPMSS);
-
- DoSimpleTransfer(12 * 1024 * 1024, QuicTime::Delta::FromSeconds(30));
- EXPECT_EQ(BbrSender::PROBE_BW, sender_->ExportDebugState().mode);
- EXPECT_EQ(0u, bbr_sender_.connection()->GetStats().packets_lost);
- EXPECT_FALSE(sender_->ExportDebugState().last_sample_is_app_limited);
-
- // The margin here is quite high, since there exists a possibility that the
- // connection just exited high gain cycle.
- EXPECT_APPROX_EQ(kTestRtt, rtt_stats_->smoothed_rtt(), 0.2f);
-}
-
-TEST_F(BbrSenderTest, SimpleTransferBBRB) {
- SetQuicReloadableFlag(quic_bbr_use_send_rate_in_max_ack_height_tracker, true);
- SetConnectionOption(kBBRB);
- CreateDefaultSetup();
-
- // At startup make sure we are at the default.
- EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow());
- // At startup make sure we can send.
- EXPECT_TRUE(sender_->CanSend(0));
- // And that window is un-affected.
- EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow());
-
- // Verify that Sender is in slow start.
- EXPECT_TRUE(sender_->InSlowStart());
-
- // Verify that pacing rate is based on the initial RTT.
- QuicBandwidth expected_pacing_rate = QuicBandwidth::FromBytesAndTimeDelta(
- 2.885 * kDefaultWindowTCP, rtt_stats_->initial_rtt());
- EXPECT_APPROX_EQ(expected_pacing_rate.ToBitsPerSecond(),
- sender_->PacingRate(0).ToBitsPerSecond(), 0.01f);
-
- ASSERT_GE(kTestBdp, kDefaultWindowTCP + kDefaultTCPMSS);
-
- DoSimpleTransfer(12 * 1024 * 1024, QuicTime::Delta::FromSeconds(30));
- EXPECT_EQ(BbrSender::PROBE_BW, sender_->ExportDebugState().mode);
- EXPECT_EQ(0u, bbr_sender_.connection()->GetStats().packets_lost);
- EXPECT_FALSE(sender_->ExportDebugState().last_sample_is_app_limited);
-
- // The margin here is quite high, since there exists a possibility that the
- // connection just exited high gain cycle.
- EXPECT_APPROX_EQ(kTestRtt, rtt_stats_->smoothed_rtt(), 0.2f);
-}
-
-// Test a simple transfer in a situation when the buffer is less than BDP.
-TEST_F(BbrSenderTest, SimpleTransferSmallBuffer) {
- CreateSmallBufferSetup();
-
- DoSimpleTransfer(12 * 1024 * 1024, QuicTime::Delta::FromSeconds(30));
- EXPECT_EQ(BbrSender::PROBE_BW, sender_->ExportDebugState().mode);
- EXPECT_APPROX_EQ(kTestLinkBandwidth,
- sender_->ExportDebugState().max_bandwidth, 0.01f);
- EXPECT_GE(bbr_sender_.connection()->GetStats().packets_lost, 0u);
- EXPECT_FALSE(sender_->ExportDebugState().last_sample_is_app_limited);
-
- // The margin here is quite high, since there exists a possibility that the
- // connection just exited high gain cycle.
- EXPECT_APPROX_EQ(kTestRtt, sender_->GetMinRtt(), 0.2f);
-}
-
-TEST_F(BbrSenderTest, RemoveBytesLostInRecovery) {
- CreateDefaultSetup();
-
- DriveOutOfStartup();
-
- // Drop a packet to enter recovery.
- receiver_.DropNextIncomingPacket();
- ASSERT_TRUE(
- simulator_.RunUntilOrTimeout([this]() { return sender_->InRecovery(); },
- QuicTime::Delta::FromSeconds(30)));
-
- QuicUnackedPacketMap* unacked_packets =
- QuicSentPacketManagerPeer::GetUnackedPacketMap(
- QuicConnectionPeer::GetSentPacketManager(bbr_sender_.connection()));
- QuicPacketNumber largest_sent =
- bbr_sender_.connection()->sent_packet_manager().GetLargestSentPacket();
- // least_inflight is the smallest inflight packet.
- QuicPacketNumber least_inflight =
- bbr_sender_.connection()->sent_packet_manager().GetLeastUnacked();
- while (!unacked_packets->GetTransmissionInfo(least_inflight).in_flight) {
- ASSERT_LE(least_inflight, largest_sent);
- least_inflight++;
- }
- QuicPacketLength least_inflight_packet_size =
- unacked_packets->GetTransmissionInfo(least_inflight).bytes_sent;
- QuicByteCount prior_recovery_window =
- sender_->ExportDebugState().recovery_window;
- QuicByteCount prior_inflight = unacked_packets->bytes_in_flight();
- QUIC_LOG(INFO) << "Recovery window:" << prior_recovery_window
- << ", least_inflight_packet_size:"
- << least_inflight_packet_size
- << ", bytes_in_flight:" << prior_inflight;
- ASSERT_GT(prior_recovery_window, least_inflight_packet_size);
-
- // Lose the least inflight packet and expect the recovery window to drop.
- unacked_packets->RemoveFromInFlight(least_inflight);
- LostPacketVector lost_packets;
- lost_packets.emplace_back(least_inflight, least_inflight_packet_size);
- sender_->OnCongestionEvent(false, prior_inflight, clock_->Now(), {},
- lost_packets);
- EXPECT_EQ(sender_->ExportDebugState().recovery_window,
- prior_inflight - least_inflight_packet_size);
- EXPECT_LT(sender_->ExportDebugState().recovery_window, prior_recovery_window);
-}
-
-// Test a simple long data transfer with 2 rtts of aggregation.
-TEST_F(BbrSenderTest, SimpleTransfer2RTTAggregationBytes) {
- SetConnectionOption(kBSAO);
- CreateDefaultSetup();
- // 2 RTTs of aggregation, with a max of 10kb.
- EnableAggregation(10 * 1024, 2 * kTestRtt);
-
- // Transfer 12MB.
- DoSimpleTransfer(12 * 1024 * 1024, QuicTime::Delta::FromSeconds(35));
- EXPECT_TRUE(sender_->ExportDebugState().mode == BbrSender::PROBE_BW ||
- sender_->ExportDebugState().mode == BbrSender::PROBE_RTT);
-
- EXPECT_APPROX_EQ(kTestLinkBandwidth,
- sender_->ExportDebugState().max_bandwidth, 0.01f);
-
- // The margin here is high, because the aggregation greatly increases
- // smoothed rtt.
- EXPECT_GE(kTestRtt * 4, rtt_stats_->smoothed_rtt());
- EXPECT_APPROX_EQ(kTestRtt, rtt_stats_->min_rtt(), 0.5f);
-}
-
-// Test a simple long data transfer with 2 rtts of aggregation.
-TEST_F(BbrSenderTest, SimpleTransferAckDecimation) {
- SetConnectionOption(kBSAO);
- // Decrease the CWND gain so extra CWND is required with stretch acks.
- SetQuicFlag(FLAGS_quic_bbr_cwnd_gain, 1.0);
- sender_ = new BbrSender(
- bbr_sender_.connection()->clock()->Now(), rtt_stats_,
- QuicSentPacketManagerPeer::GetUnackedPacketMap(
- QuicConnectionPeer::GetSentPacketManager(bbr_sender_.connection())),
- kInitialCongestionWindowPackets,
- GetQuicFlag(FLAGS_quic_max_congestion_window), &random_,
- QuicConnectionPeer::GetStats(bbr_sender_.connection()));
- QuicConnectionPeer::SetSendAlgorithm(bbr_sender_.connection(), sender_);
- CreateDefaultSetup();
-
- // Transfer 12MB.
- DoSimpleTransfer(12 * 1024 * 1024, QuicTime::Delta::FromSeconds(35));
- EXPECT_EQ(BbrSender::PROBE_BW, sender_->ExportDebugState().mode);
-
- EXPECT_APPROX_EQ(kTestLinkBandwidth,
- sender_->ExportDebugState().max_bandwidth, 0.01f);
-
- // TODO(ianswett): Expect 0 packets are lost once BBR no longer measures
- // bandwidth higher than the link rate.
- EXPECT_FALSE(sender_->ExportDebugState().last_sample_is_app_limited);
- // The margin here is high, because the aggregation greatly increases
- // smoothed rtt.
- EXPECT_GE(kTestRtt * 2, rtt_stats_->smoothed_rtt());
- EXPECT_APPROX_EQ(kTestRtt, rtt_stats_->min_rtt(), 0.1f);
-}
-
-// Test a simple long data transfer with 2 rtts of aggregation.
-// TODO(b/172302465) Re-enable this test.
-TEST_F(BbrSenderTest,
- QUIC_TEST_DISABLED_IN_CHROME(
- SimpleTransfer2RTTAggregationBytes20RTTWindow)) {
- SetConnectionOption(kBSAO);
- CreateDefaultSetup();
- SetConnectionOption(kBBR4);
- // 2 RTTs of aggregation, with a max of 10kb.
- EnableAggregation(10 * 1024, 2 * kTestRtt);
-
- // Transfer 12MB.
- DoSimpleTransfer(12 * 1024 * 1024, QuicTime::Delta::FromSeconds(35));
- EXPECT_TRUE(sender_->ExportDebugState().mode == BbrSender::PROBE_BW ||
- sender_->ExportDebugState().mode == BbrSender::PROBE_RTT);
-
- EXPECT_APPROX_EQ(kTestLinkBandwidth,
- sender_->ExportDebugState().max_bandwidth, 0.01f);
-
- // TODO(ianswett): Expect 0 packets are lost once BBR no longer measures
- // bandwidth higher than the link rate.
- // The margin here is high, because the aggregation greatly increases
- // smoothed rtt.
- EXPECT_GE(kTestRtt * 4, rtt_stats_->smoothed_rtt());
- EXPECT_APPROX_EQ(kTestRtt, rtt_stats_->min_rtt(), 0.25f);
-}
-
-// Test a simple long data transfer with 2 rtts of aggregation.
-TEST_F(BbrSenderTest, SimpleTransfer2RTTAggregationBytes40RTTWindow) {
- SetConnectionOption(kBSAO);
- CreateDefaultSetup();
- SetConnectionOption(kBBR5);
- // 2 RTTs of aggregation, with a max of 10kb.
- EnableAggregation(10 * 1024, 2 * kTestRtt);
-
- // Transfer 12MB.
- DoSimpleTransfer(12 * 1024 * 1024, QuicTime::Delta::FromSeconds(35));
- EXPECT_TRUE(sender_->ExportDebugState().mode == BbrSender::PROBE_BW ||
- sender_->ExportDebugState().mode == BbrSender::PROBE_RTT);
-
- EXPECT_APPROX_EQ(kTestLinkBandwidth,
- sender_->ExportDebugState().max_bandwidth, 0.01f);
-
- // TODO(ianswett): Expect 0 packets are lost once BBR no longer measures
- // bandwidth higher than the link rate.
- // The margin here is high, because the aggregation greatly increases
- // smoothed rtt.
- EXPECT_GE(kTestRtt * 4, rtt_stats_->smoothed_rtt());
- EXPECT_APPROX_EQ(kTestRtt, rtt_stats_->min_rtt(), 0.25f);
-}
-
-// Test the number of losses incurred by the startup phase in a situation when
-// the buffer is less than BDP.
-TEST_F(BbrSenderTest, PacketLossOnSmallBufferStartup) {
- CreateSmallBufferSetup();
-
- DriveOutOfStartup();
- float loss_rate =
- static_cast<float>(bbr_sender_.connection()->GetStats().packets_lost) /
- bbr_sender_.connection()->GetStats().packets_sent;
- EXPECT_LE(loss_rate, 0.31);
-}
-
-// Test the number of losses incurred by the startup phase in a situation when
-// the buffer is less than BDP, with a STARTUP CWND gain of 2.
-TEST_F(BbrSenderTest, PacketLossOnSmallBufferStartupDerivedCWNDGain) {
- CreateSmallBufferSetup();
-
- SetConnectionOption(kBBQ2);
- DriveOutOfStartup();
- float loss_rate =
- static_cast<float>(bbr_sender_.connection()->GetStats().packets_lost) /
- bbr_sender_.connection()->GetStats().packets_sent;
- EXPECT_LE(loss_rate, 0.1);
-}
-
-// Ensures the code transitions loss recovery states correctly (NOT_IN_RECOVERY
-// -> CONSERVATION -> GROWTH -> NOT_IN_RECOVERY).
-TEST_F(BbrSenderTest, RecoveryStates) {
- const QuicTime::Delta timeout = QuicTime::Delta::FromSeconds(10);
- bool simulator_result;
- CreateSmallBufferSetup();
-
- bbr_sender_.AddBytesToTransfer(100 * 1024 * 1024);
- ASSERT_EQ(BbrSender::NOT_IN_RECOVERY,
- sender_->ExportDebugState().recovery_state);
-
- simulator_result = simulator_.RunUntilOrTimeout(
- [this]() {
- return sender_->ExportDebugState().recovery_state !=
- BbrSender::NOT_IN_RECOVERY;
- },
- timeout);
- ASSERT_TRUE(simulator_result);
- ASSERT_EQ(BbrSender::CONSERVATION,
- sender_->ExportDebugState().recovery_state);
-
- simulator_result = simulator_.RunUntilOrTimeout(
- [this]() {
- return sender_->ExportDebugState().recovery_state !=
- BbrSender::CONSERVATION;
- },
- timeout);
- ASSERT_TRUE(simulator_result);
- ASSERT_EQ(BbrSender::GROWTH, sender_->ExportDebugState().recovery_state);
-
- simulator_result = simulator_.RunUntilOrTimeout(
- [this]() {
- return sender_->ExportDebugState().recovery_state != BbrSender::GROWTH;
- },
- timeout);
-
- ASSERT_EQ(BbrSender::NOT_IN_RECOVERY,
- sender_->ExportDebugState().recovery_state);
- ASSERT_TRUE(simulator_result);
-}
-
-// Verify the behavior of the algorithm in the case when the connection sends
-// small bursts of data after sending continuously for a while.
-TEST_F(BbrSenderTest, ApplicationLimitedBursts) {
- CreateDefaultSetup();
-
- DriveOutOfStartup();
- EXPECT_FALSE(sender_->ExportDebugState().last_sample_is_app_limited);
-
- SendBursts(20, 512, QuicTime::Delta::FromSeconds(3));
- EXPECT_TRUE(sender_->ExportDebugState().last_sample_is_app_limited);
- EXPECT_APPROX_EQ(kTestLinkBandwidth,
- sender_->ExportDebugState().max_bandwidth, 0.01f);
-}
-
-// Verify the behavior of the algorithm in the case when the connection sends
-// small bursts of data and then starts sending continuously.
-TEST_F(BbrSenderTest, ApplicationLimitedBurstsWithoutPrior) {
- CreateDefaultSetup();
-
- SendBursts(40, 512, QuicTime::Delta::FromSeconds(3));
- EXPECT_TRUE(sender_->ExportDebugState().last_sample_is_app_limited);
-
- DriveOutOfStartup();
- EXPECT_APPROX_EQ(kTestLinkBandwidth,
- sender_->ExportDebugState().max_bandwidth, 0.01f);
- EXPECT_FALSE(sender_->ExportDebugState().last_sample_is_app_limited);
-}
-
-// Verify that the DRAIN phase works correctly.
-TEST_F(BbrSenderTest, Drain) {
- CreateDefaultSetup();
- const QuicTime::Delta timeout = QuicTime::Delta::FromSeconds(10);
- // Get the queue at the bottleneck, which is the outgoing queue at the port to
- // which the receiver is connected.
- const simulator::Queue* queue = switch_->port_queue(2);
- bool simulator_result;
-
- // We have no intention of ever finishing this transfer.
- bbr_sender_.AddBytesToTransfer(100 * 1024 * 1024);
-
- // Run the startup, and verify that it fills up the queue.
- ASSERT_EQ(BbrSender::STARTUP, sender_->ExportDebugState().mode);
- simulator_result = simulator_.RunUntilOrTimeout(
- [this]() {
- return sender_->ExportDebugState().mode != BbrSender::STARTUP;
- },
- timeout);
- ASSERT_TRUE(simulator_result);
- ASSERT_EQ(BbrSender::DRAIN, sender_->ExportDebugState().mode);
- EXPECT_APPROX_EQ(sender_->BandwidthEstimate() * (1 / 2.885f),
- sender_->PacingRate(0), 0.01f);
-
- // BBR uses CWND gain of 2 during STARTUP, hence it will fill the buffer
- // with approximately 1 BDP. Here, we use 0.8 to give some margin for
- // error.
- EXPECT_GE(queue->bytes_queued(), 0.8 * kTestBdp);
-
- // Observe increased RTT due to bufferbloat.
- const QuicTime::Delta queueing_delay =
- kTestLinkBandwidth.TransferTime(queue->bytes_queued());
- EXPECT_APPROX_EQ(kTestRtt + queueing_delay, rtt_stats_->latest_rtt(), 0.1f);
-
- // Transition to the drain phase and verify that it makes the queue
- // have at most a BDP worth of packets.
- simulator_result = simulator_.RunUntilOrTimeout(
- [this]() { return sender_->ExportDebugState().mode != BbrSender::DRAIN; },
- timeout);
- ASSERT_TRUE(simulator_result);
- ASSERT_EQ(BbrSender::PROBE_BW, sender_->ExportDebugState().mode);
- EXPECT_LE(queue->bytes_queued(), kTestBdp);
-
- // Wait for a few round trips and ensure we're in appropriate phase of gain
- // cycling before taking an RTT measurement.
- const QuicRoundTripCount start_round_trip =
- sender_->ExportDebugState().round_trip_count;
- simulator_result = simulator_.RunUntilOrTimeout(
- [this, start_round_trip]() {
- QuicRoundTripCount rounds_passed =
- sender_->ExportDebugState().round_trip_count - start_round_trip;
- return rounds_passed >= 4 &&
- sender_->ExportDebugState().gain_cycle_index == 7;
- },
- timeout);
- ASSERT_TRUE(simulator_result);
-
- // Observe the bufferbloat go away.
- EXPECT_APPROX_EQ(kTestRtt, rtt_stats_->smoothed_rtt(), 0.1f);
-}
-
-// TODO(wub): Re-enable this test once default drain_gain changed to 0.75.
-// Verify that the DRAIN phase works correctly.
-TEST_F(BbrSenderTest, DISABLED_ShallowDrain) {
- CreateDefaultSetup();
- const QuicTime::Delta timeout = QuicTime::Delta::FromSeconds(10);
- // Get the queue at the bottleneck, which is the outgoing queue at the port to
- // which the receiver is connected.
- const simulator::Queue* queue = switch_->port_queue(2);
- bool simulator_result;
-
- // We have no intention of ever finishing this transfer.
- bbr_sender_.AddBytesToTransfer(100 * 1024 * 1024);
-
- // Run the startup, and verify that it fills up the queue.
- ASSERT_EQ(BbrSender::STARTUP, sender_->ExportDebugState().mode);
- simulator_result = simulator_.RunUntilOrTimeout(
- [this]() {
- return sender_->ExportDebugState().mode != BbrSender::STARTUP;
- },
- timeout);
- ASSERT_TRUE(simulator_result);
- ASSERT_EQ(BbrSender::DRAIN, sender_->ExportDebugState().mode);
- EXPECT_EQ(0.75 * sender_->BandwidthEstimate(), sender_->PacingRate(0));
- // BBR uses CWND gain of 2.88 during STARTUP, hence it will fill the buffer
- // with approximately 1.88 BDPs. Here, we use 1.5 to give some margin for
- // error.
- EXPECT_GE(queue->bytes_queued(), 1.5 * kTestBdp);
-
- // Observe increased RTT due to bufferbloat.
- const QuicTime::Delta queueing_delay =
- kTestLinkBandwidth.TransferTime(queue->bytes_queued());
- EXPECT_APPROX_EQ(kTestRtt + queueing_delay, rtt_stats_->latest_rtt(), 0.1f);
-
- // Transition to the drain phase and verify that it makes the queue
- // have at most a BDP worth of packets.
- simulator_result = simulator_.RunUntilOrTimeout(
- [this]() { return sender_->ExportDebugState().mode != BbrSender::DRAIN; },
- timeout);
- ASSERT_TRUE(simulator_result);
- ASSERT_EQ(BbrSender::PROBE_BW, sender_->ExportDebugState().mode);
- EXPECT_LE(queue->bytes_queued(), kTestBdp);
-
- // Wait for a few round trips and ensure we're in appropriate phase of gain
- // cycling before taking an RTT measurement.
- const QuicRoundTripCount start_round_trip =
- sender_->ExportDebugState().round_trip_count;
- simulator_result = simulator_.RunUntilOrTimeout(
- [this, start_round_trip]() {
- QuicRoundTripCount rounds_passed =
- sender_->ExportDebugState().round_trip_count - start_round_trip;
- return rounds_passed >= 4 &&
- sender_->ExportDebugState().gain_cycle_index == 7;
- },
- timeout);
- ASSERT_TRUE(simulator_result);
-
- // Observe the bufferbloat go away.
- EXPECT_APPROX_EQ(kTestRtt, rtt_stats_->smoothed_rtt(), 0.1f);
-}
-
-// Verify that the connection enters and exits PROBE_RTT correctly.
-TEST_F(BbrSenderTest, ProbeRtt) {
- CreateDefaultSetup();
- DriveOutOfStartup();
-
- // We have no intention of ever finishing this transfer.
- bbr_sender_.AddBytesToTransfer(100 * 1024 * 1024);
-
- // Wait until the connection enters PROBE_RTT.
- const QuicTime::Delta timeout = QuicTime::Delta::FromSeconds(12);
- bool simulator_result = simulator_.RunUntilOrTimeout(
- [this]() {
- return sender_->ExportDebugState().mode == BbrSender::PROBE_RTT;
- },
- timeout);
- ASSERT_TRUE(simulator_result);
- ASSERT_EQ(BbrSender::PROBE_RTT, sender_->ExportDebugState().mode);
-
- // Exit PROBE_RTT.
- const QuicTime probe_rtt_start = clock_->Now();
- const QuicTime::Delta time_to_exit_probe_rtt =
- kTestRtt + QuicTime::Delta::FromMilliseconds(200);
- simulator_.RunFor(1.5 * time_to_exit_probe_rtt);
- EXPECT_EQ(BbrSender::PROBE_BW, sender_->ExportDebugState().mode);
- EXPECT_GE(sender_->ExportDebugState().min_rtt_timestamp, probe_rtt_start);
-}
-
-// Ensure that a connection that is app-limited and is at sufficiently low
-// bandwidth will not exit high gain phase, and similarly ensure that the
-// connection will exit low gain early if the number of bytes in flight is low.
-// TODO(crbug.com/1145095): Re-enable this test.
-TEST_F(BbrSenderTest, QUIC_TEST_DISABLED_IN_CHROME(InFlightAwareGainCycling)) {
- CreateDefaultSetup();
- DriveOutOfStartup();
-
- const QuicTime::Delta timeout = QuicTime::Delta::FromSeconds(5);
- while (!(sender_->ExportDebugState().gain_cycle_index >= 4 &&
- bbr_sender_.bytes_to_transfer() == 0)) {
- bbr_sender_.AddBytesToTransfer(kTestLinkBandwidth.ToBytesPerSecond());
- ASSERT_TRUE(simulator_.RunUntilOrTimeout(
- [this]() { return bbr_sender_.bytes_to_transfer() == 0; }, timeout));
- }
-
- // Send at 10% of available rate. Run for 3 seconds, checking in the middle
- // and at the end. The pacing gain should be high throughout.
- QuicBandwidth target_bandwidth = 0.1f * kTestLinkBandwidth;
- QuicTime::Delta burst_interval = QuicTime::Delta::FromMilliseconds(300);
- for (int i = 0; i < 2; i++) {
- SendBursts(5, target_bandwidth * burst_interval, burst_interval);
- EXPECT_EQ(BbrSender::PROBE_BW, sender_->ExportDebugState().mode);
- EXPECT_EQ(0, sender_->ExportDebugState().gain_cycle_index);
- EXPECT_APPROX_EQ(kTestLinkBandwidth,
- sender_->ExportDebugState().max_bandwidth, 0.02f);
- }
-
- // Now that in-flight is almost zero and the pacing gain is still above 1,
- // send approximately 1.25 BDPs worth of data. This should cause the
- // PROBE_BW mode to enter low gain cycle, and exit it earlier than one min_rtt
- // due to running out of data to send.
- bbr_sender_.AddBytesToTransfer(1.3 * kTestBdp);
- ASSERT_TRUE(simulator_.RunUntilOrTimeout(
- [this]() { return sender_->ExportDebugState().gain_cycle_index == 1; },
- timeout));
-
- simulator_.RunFor(0.75 * sender_->ExportDebugState().min_rtt);
- EXPECT_EQ(BbrSender::PROBE_BW, sender_->ExportDebugState().mode);
- EXPECT_EQ(2, sender_->ExportDebugState().gain_cycle_index);
-}
-
-// Ensure that the pacing rate does not drop at startup.
-TEST_F(BbrSenderTest, NoBandwidthDropOnStartup) {
- CreateDefaultSetup();
-
- const QuicTime::Delta timeout = QuicTime::Delta::FromSeconds(5);
- bool simulator_result;
-
- QuicBandwidth initial_rate = QuicBandwidth::FromBytesAndTimeDelta(
- kInitialCongestionWindowPackets * kDefaultTCPMSS,
- rtt_stats_->initial_rtt());
- EXPECT_GE(sender_->PacingRate(0), initial_rate);
-
- // Send a packet.
- bbr_sender_.AddBytesToTransfer(1000);
- simulator_result = simulator_.RunUntilOrTimeout(
- [this]() { return receiver_.bytes_received() == 1000; }, timeout);
- ASSERT_TRUE(simulator_result);
- EXPECT_GE(sender_->PacingRate(0), initial_rate);
-
- // Wait for a while.
- simulator_.RunFor(QuicTime::Delta::FromSeconds(2));
- EXPECT_GE(sender_->PacingRate(0), initial_rate);
-
- // Send another packet.
- bbr_sender_.AddBytesToTransfer(1000);
- simulator_result = simulator_.RunUntilOrTimeout(
- [this]() { return receiver_.bytes_received() == 2000; }, timeout);
- ASSERT_TRUE(simulator_result);
- EXPECT_GE(sender_->PacingRate(0), initial_rate);
-}
-
-// Test exiting STARTUP earlier due to the 1RTT connection option.
-TEST_F(BbrSenderTest, SimpleTransfer1RTTStartup) {
- CreateDefaultSetup();
-
- SetConnectionOption(k1RTT);
- EXPECT_EQ(1u, sender_->num_startup_rtts());
-
- // Run until the full bandwidth is reached and check how many rounds it was.
- bbr_sender_.AddBytesToTransfer(12 * 1024 * 1024);
- QuicRoundTripCount max_bw_round = 0;
- QuicBandwidth max_bw(QuicBandwidth::Zero());
- bool simulator_result = simulator_.RunUntilOrTimeout(
- [this, &max_bw, &max_bw_round]() {
- if (max_bw < sender_->ExportDebugState().max_bandwidth) {
- max_bw = sender_->ExportDebugState().max_bandwidth;
- max_bw_round = sender_->ExportDebugState().round_trip_count;
- }
- return sender_->ExportDebugState().is_at_full_bandwidth;
- },
- QuicTime::Delta::FromSeconds(5));
- ASSERT_TRUE(simulator_result);
- EXPECT_EQ(BbrSender::DRAIN, sender_->ExportDebugState().mode);
- EXPECT_EQ(1u, sender_->ExportDebugState().round_trip_count - max_bw_round);
- EXPECT_EQ(1u, sender_->ExportDebugState().rounds_without_bandwidth_gain);
- EXPECT_EQ(0u, bbr_sender_.connection()->GetStats().packets_lost);
- EXPECT_FALSE(sender_->ExportDebugState().last_sample_is_app_limited);
-}
-
-// Test exiting STARTUP earlier due to the 2RTT connection option.
-TEST_F(BbrSenderTest, SimpleTransfer2RTTStartup) {
- CreateDefaultSetup();
-
- SetConnectionOption(k2RTT);
- EXPECT_EQ(2u, sender_->num_startup_rtts());
-
- // Run until the full bandwidth is reached and check how many rounds it was.
- bbr_sender_.AddBytesToTransfer(12 * 1024 * 1024);
- QuicRoundTripCount max_bw_round = 0;
- QuicBandwidth max_bw(QuicBandwidth::Zero());
- bool simulator_result = simulator_.RunUntilOrTimeout(
- [this, &max_bw, &max_bw_round]() {
- if (max_bw < sender_->ExportDebugState().max_bandwidth) {
- max_bw = sender_->ExportDebugState().max_bandwidth;
- max_bw_round = sender_->ExportDebugState().round_trip_count;
- }
- return sender_->ExportDebugState().is_at_full_bandwidth;
- },
- QuicTime::Delta::FromSeconds(5));
- ASSERT_TRUE(simulator_result);
- EXPECT_EQ(BbrSender::DRAIN, sender_->ExportDebugState().mode);
- EXPECT_EQ(2u, sender_->ExportDebugState().round_trip_count - max_bw_round);
- EXPECT_EQ(2u, sender_->ExportDebugState().rounds_without_bandwidth_gain);
- EXPECT_EQ(0u, bbr_sender_.connection()->GetStats().packets_lost);
- EXPECT_FALSE(sender_->ExportDebugState().last_sample_is_app_limited);
-}
-
-// Test exiting STARTUP earlier upon loss.
-TEST_F(BbrSenderTest, SimpleTransferExitStartupOnLoss) {
- CreateDefaultSetup();
-
- EXPECT_EQ(3u, sender_->num_startup_rtts());
-
- // Run until the full bandwidth is reached and check how many rounds it was.
- bbr_sender_.AddBytesToTransfer(12 * 1024 * 1024);
- QuicRoundTripCount max_bw_round = 0;
- QuicBandwidth max_bw(QuicBandwidth::Zero());
- bool simulator_result = simulator_.RunUntilOrTimeout(
- [this, &max_bw, &max_bw_round]() {
- if (max_bw < sender_->ExportDebugState().max_bandwidth) {
- max_bw = sender_->ExportDebugState().max_bandwidth;
- max_bw_round = sender_->ExportDebugState().round_trip_count;
- }
- return sender_->ExportDebugState().is_at_full_bandwidth;
- },
- QuicTime::Delta::FromSeconds(5));
- ASSERT_TRUE(simulator_result);
- EXPECT_EQ(BbrSender::DRAIN, sender_->ExportDebugState().mode);
- EXPECT_EQ(3u, sender_->ExportDebugState().round_trip_count - max_bw_round);
- EXPECT_EQ(3u, sender_->ExportDebugState().rounds_without_bandwidth_gain);
- EXPECT_EQ(0u, bbr_sender_.connection()->GetStats().packets_lost);
- EXPECT_FALSE(sender_->ExportDebugState().last_sample_is_app_limited);
-}
-
-// Test exiting STARTUP earlier upon loss with a small buffer.
-TEST_F(BbrSenderTest, SimpleTransferExitStartupOnLossSmallBuffer) {
- CreateSmallBufferSetup();
-
- EXPECT_EQ(3u, sender_->num_startup_rtts());
-
- // Run until the full bandwidth is reached and check how many rounds it was.
- bbr_sender_.AddBytesToTransfer(12 * 1024 * 1024);
- QuicRoundTripCount max_bw_round = 0;
- QuicBandwidth max_bw(QuicBandwidth::Zero());
- bool simulator_result = simulator_.RunUntilOrTimeout(
- [this, &max_bw, &max_bw_round]() {
- if (max_bw < sender_->ExportDebugState().max_bandwidth) {
- max_bw = sender_->ExportDebugState().max_bandwidth;
- max_bw_round = sender_->ExportDebugState().round_trip_count;
- }
- return sender_->ExportDebugState().is_at_full_bandwidth;
- },
- QuicTime::Delta::FromSeconds(5));
- ASSERT_TRUE(simulator_result);
- EXPECT_EQ(BbrSender::DRAIN, sender_->ExportDebugState().mode);
- EXPECT_GE(2u, sender_->ExportDebugState().round_trip_count - max_bw_round);
- EXPECT_EQ(1u, sender_->ExportDebugState().rounds_without_bandwidth_gain);
- EXPECT_NE(0u, bbr_sender_.connection()->GetStats().packets_lost);
- EXPECT_FALSE(sender_->ExportDebugState().last_sample_is_app_limited);
-}
-
-TEST_F(BbrSenderTest, DerivedPacingGainStartup) {
- CreateDefaultSetup();
-
- SetConnectionOption(kBBQ1);
- EXPECT_EQ(3u, sender_->num_startup_rtts());
- // Verify that Sender is in slow start.
- EXPECT_TRUE(sender_->InSlowStart());
- // Verify that pacing rate is based on the initial RTT.
- QuicBandwidth expected_pacing_rate = QuicBandwidth::FromBytesAndTimeDelta(
- 2.773 * kDefaultWindowTCP, rtt_stats_->initial_rtt());
- EXPECT_APPROX_EQ(expected_pacing_rate.ToBitsPerSecond(),
- sender_->PacingRate(0).ToBitsPerSecond(), 0.01f);
-
- // Run until the full bandwidth is reached and check how many rounds it was.
- bbr_sender_.AddBytesToTransfer(12 * 1024 * 1024);
- bool simulator_result = simulator_.RunUntilOrTimeout(
- [this]() { return sender_->ExportDebugState().is_at_full_bandwidth; },
- QuicTime::Delta::FromSeconds(5));
- ASSERT_TRUE(simulator_result);
- EXPECT_EQ(BbrSender::DRAIN, sender_->ExportDebugState().mode);
- EXPECT_EQ(3u, sender_->ExportDebugState().rounds_without_bandwidth_gain);
- EXPECT_APPROX_EQ(kTestLinkBandwidth,
- sender_->ExportDebugState().max_bandwidth, 0.01f);
- EXPECT_EQ(0u, bbr_sender_.connection()->GetStats().packets_lost);
- EXPECT_FALSE(sender_->ExportDebugState().last_sample_is_app_limited);
-}
-
-TEST_F(BbrSenderTest, DerivedCWNDGainStartup) {
- CreateSmallBufferSetup();
-
- EXPECT_EQ(3u, sender_->num_startup_rtts());
- // Verify that Sender is in slow start.
- EXPECT_TRUE(sender_->InSlowStart());
- // Verify that pacing rate is based on the initial RTT.
- QuicBandwidth expected_pacing_rate = QuicBandwidth::FromBytesAndTimeDelta(
- 2.885 * kDefaultWindowTCP, rtt_stats_->initial_rtt());
- EXPECT_APPROX_EQ(expected_pacing_rate.ToBitsPerSecond(),
- sender_->PacingRate(0).ToBitsPerSecond(), 0.01f);
-
- // Run until the full bandwidth is reached and check how many rounds it was.
- bbr_sender_.AddBytesToTransfer(12 * 1024 * 1024);
- bool simulator_result = simulator_.RunUntilOrTimeout(
- [this]() { return sender_->ExportDebugState().is_at_full_bandwidth; },
- QuicTime::Delta::FromSeconds(5));
- ASSERT_TRUE(simulator_result);
- EXPECT_EQ(BbrSender::DRAIN, sender_->ExportDebugState().mode);
- if (!bbr_sender_.connection()->GetStats().bbr_exit_startup_due_to_loss) {
- EXPECT_EQ(3u, sender_->ExportDebugState().rounds_without_bandwidth_gain);
- }
- EXPECT_APPROX_EQ(kTestLinkBandwidth,
- sender_->ExportDebugState().max_bandwidth, 0.01f);
- float loss_rate =
- static_cast<float>(bbr_sender_.connection()->GetStats().packets_lost) /
- bbr_sender_.connection()->GetStats().packets_sent;
- EXPECT_LT(loss_rate, 0.15f);
- EXPECT_FALSE(sender_->ExportDebugState().last_sample_is_app_limited);
- // Expect an SRTT less than 2.7 * Min RTT on exit from STARTUP.
- EXPECT_GT(kTestRtt * 2.7, rtt_stats_->smoothed_rtt());
-}
-
-TEST_F(BbrSenderTest, AckAggregationInStartup) {
- CreateDefaultSetup();
-
- SetConnectionOption(kBBQ3);
- EXPECT_EQ(3u, sender_->num_startup_rtts());
- // Verify that Sender is in slow start.
- EXPECT_TRUE(sender_->InSlowStart());
- // Verify that pacing rate is based on the initial RTT.
- QuicBandwidth expected_pacing_rate = QuicBandwidth::FromBytesAndTimeDelta(
- 2.885 * kDefaultWindowTCP, rtt_stats_->initial_rtt());
- EXPECT_APPROX_EQ(expected_pacing_rate.ToBitsPerSecond(),
- sender_->PacingRate(0).ToBitsPerSecond(), 0.01f);
-
- // Run until the full bandwidth is reached and check how many rounds it was.
- bbr_sender_.AddBytesToTransfer(12 * 1024 * 1024);
- bool simulator_result = simulator_.RunUntilOrTimeout(
- [this]() { return sender_->ExportDebugState().is_at_full_bandwidth; },
- QuicTime::Delta::FromSeconds(5));
- ASSERT_TRUE(simulator_result);
- EXPECT_EQ(BbrSender::DRAIN, sender_->ExportDebugState().mode);
- EXPECT_EQ(3u, sender_->ExportDebugState().rounds_without_bandwidth_gain);
- EXPECT_APPROX_EQ(kTestLinkBandwidth,
- sender_->ExportDebugState().max_bandwidth, 0.01f);
- EXPECT_EQ(0u, bbr_sender_.connection()->GetStats().packets_lost);
- EXPECT_FALSE(sender_->ExportDebugState().last_sample_is_app_limited);
-}
-
-// Test that two BBR flows started slightly apart from each other terminate.
-TEST_F(BbrSenderTest, SimpleCompetition) {
- const QuicByteCount transfer_size = 10 * 1024 * 1024;
- const QuicTime::Delta transfer_time =
- kTestLinkBandwidth.TransferTime(transfer_size);
- CreateBbrVsBbrSetup();
-
- // Transfer 10% of data in first transfer.
- bbr_sender_.AddBytesToTransfer(transfer_size);
- bool simulator_result = simulator_.RunUntilOrTimeout(
- [this]() { return receiver_.bytes_received() >= 0.1 * transfer_size; },
- transfer_time);
- ASSERT_TRUE(simulator_result);
-
- // Start the second transfer and wait until both finish.
- competing_sender_.AddBytesToTransfer(transfer_size);
- simulator_result = simulator_.RunUntilOrTimeout(
- [this]() {
- return receiver_.bytes_received() == transfer_size &&
- competing_receiver_.bytes_received() == transfer_size;
- },
- 3 * transfer_time);
- ASSERT_TRUE(simulator_result);
-}
-
-// Test that BBR can resume bandwidth from cached network parameters.
-TEST_F(BbrSenderTest, ResumeConnectionState) {
- CreateDefaultSetup();
-
- bbr_sender_.connection()->AdjustNetworkParameters(
- SendAlgorithmInterface::NetworkParams(kTestLinkBandwidth, kTestRtt,
- false));
- EXPECT_EQ(kTestLinkBandwidth * kTestRtt,
- sender_->ExportDebugState().congestion_window);
-
- EXPECT_EQ(kTestLinkBandwidth, sender_->PacingRate(/*bytes_in_flight=*/0));
-
- EXPECT_APPROX_EQ(kTestRtt, sender_->ExportDebugState().min_rtt, 0.01f);
-
- DriveOutOfStartup();
-}
-
-// Test with a min CWND of 1 instead of 4 packets.
-TEST_F(BbrSenderTest, ProbeRTTMinCWND1) {
- CreateDefaultSetup();
- SetConnectionOption(kMIN1);
- DriveOutOfStartup();
-
- // We have no intention of ever finishing this transfer.
- bbr_sender_.AddBytesToTransfer(100 * 1024 * 1024);
-
- // Wait until the connection enters PROBE_RTT.
- const QuicTime::Delta timeout = QuicTime::Delta::FromSeconds(12);
- bool simulator_result = simulator_.RunUntilOrTimeout(
- [this]() {
- return sender_->ExportDebugState().mode == BbrSender::PROBE_RTT;
- },
- timeout);
- ASSERT_TRUE(simulator_result);
- ASSERT_EQ(BbrSender::PROBE_RTT, sender_->ExportDebugState().mode);
- // The PROBE_RTT CWND should be 1 if the min CWND is 1.
- EXPECT_EQ(kDefaultTCPMSS, sender_->GetCongestionWindow());
-
- // Exit PROBE_RTT.
- const QuicTime probe_rtt_start = clock_->Now();
- const QuicTime::Delta time_to_exit_probe_rtt =
- kTestRtt + QuicTime::Delta::FromMilliseconds(200);
- simulator_.RunFor(1.5 * time_to_exit_probe_rtt);
- EXPECT_EQ(BbrSender::PROBE_BW, sender_->ExportDebugState().mode);
- EXPECT_GE(sender_->ExportDebugState().min_rtt_timestamp, probe_rtt_start);
-}
-
-TEST_F(BbrSenderTest, StartupStats) {
- CreateDefaultSetup();
-
- DriveOutOfStartup();
- ASSERT_FALSE(sender_->InSlowStart());
-
- const QuicConnectionStats& stats = bbr_sender_.connection()->GetStats();
- EXPECT_EQ(1u, stats.slowstart_count);
- EXPECT_THAT(stats.slowstart_num_rtts, AllOf(Ge(5u), Le(15u)));
- EXPECT_THAT(stats.slowstart_packets_sent, AllOf(Ge(100u), Le(1000u)));
- EXPECT_THAT(stats.slowstart_bytes_sent, AllOf(Ge(100000u), Le(1000000u)));
- EXPECT_LE(stats.slowstart_packets_lost, 10u);
- EXPECT_LE(stats.slowstart_bytes_lost, 10000u);
- EXPECT_FALSE(stats.slowstart_duration.IsRunning());
- EXPECT_THAT(stats.slowstart_duration.GetTotalElapsedTime(),
- AllOf(Ge(QuicTime::Delta::FromMilliseconds(500)),
- Le(QuicTime::Delta::FromMilliseconds(1500))));
- EXPECT_EQ(stats.slowstart_duration.GetTotalElapsedTime(),
- QuicConnectionPeer::GetSentPacketManager(bbr_sender_.connection())
- ->GetSlowStartDuration());
-}
-
-// Regression test for b/143540157.
-TEST_F(BbrSenderTest, RecalculatePacingRateOnCwndChange1RTT) {
- CreateDefaultSetup();
-
- bbr_sender_.AddBytesToTransfer(1 * 1024 * 1024);
- // Wait until an ACK comes back.
- const QuicTime::Delta timeout = QuicTime::Delta::FromSeconds(5);
- bool simulator_result = simulator_.RunUntilOrTimeout(
- [this]() { return !sender_->ExportDebugState().min_rtt.IsZero(); },
- timeout);
- ASSERT_TRUE(simulator_result);
- const QuicByteCount previous_cwnd =
- sender_->ExportDebugState().congestion_window;
-
- // Bootstrap cwnd.
- bbr_sender_.connection()->AdjustNetworkParameters(
- SendAlgorithmInterface::NetworkParams(kTestLinkBandwidth,
- QuicTime::Delta::Zero(), false));
- EXPECT_LT(previous_cwnd, sender_->ExportDebugState().congestion_window);
-
- // Verify pacing rate is re-calculated based on the new cwnd and min_rtt.
- EXPECT_APPROX_EQ(QuicBandwidth::FromBytesAndTimeDelta(
- sender_->ExportDebugState().congestion_window,
- sender_->ExportDebugState().min_rtt),
- sender_->PacingRate(/*bytes_in_flight=*/0), 0.01f);
-}
-
-TEST_F(BbrSenderTest, RecalculatePacingRateOnCwndChange0RTT) {
- CreateDefaultSetup();
- // Initial RTT is available.
- const_cast<RttStats*>(rtt_stats_)->set_initial_rtt(kTestRtt);
-
- // Bootstrap cwnd.
- bbr_sender_.connection()->AdjustNetworkParameters(
- SendAlgorithmInterface::NetworkParams(kTestLinkBandwidth,
- QuicTime::Delta::Zero(), false));
- EXPECT_LT(kInitialCongestionWindowPackets * kDefaultTCPMSS,
- sender_->ExportDebugState().congestion_window);
- // No Rtt sample is available.
- EXPECT_TRUE(sender_->ExportDebugState().min_rtt.IsZero());
-
- // Verify pacing rate is re-calculated based on the new cwnd and initial
- // RTT.
- EXPECT_APPROX_EQ(QuicBandwidth::FromBytesAndTimeDelta(
- sender_->ExportDebugState().congestion_window,
- rtt_stats_->initial_rtt()),
- sender_->PacingRate(/*bytes_in_flight=*/0), 0.01f);
-}
-
-TEST_F(BbrSenderTest, MitigateCwndBootstrappingOvershoot) {
- CreateDefaultSetup();
- bbr_sender_.AddBytesToTransfer(1 * 1024 * 1024);
-
- // Wait until an ACK comes back.
- const QuicTime::Delta timeout = QuicTime::Delta::FromSeconds(5);
- bool simulator_result = simulator_.RunUntilOrTimeout(
- [this]() { return !sender_->ExportDebugState().min_rtt.IsZero(); },
- timeout);
- ASSERT_TRUE(simulator_result);
-
- // Bootstrap cwnd by a overly large bandwidth sample.
- bbr_sender_.connection()->AdjustNetworkParameters(
- SendAlgorithmInterface::NetworkParams(8 * kTestLinkBandwidth,
- QuicTime::Delta::Zero(), false));
- QuicBandwidth pacing_rate = sender_->PacingRate(0);
- EXPECT_EQ(8 * kTestLinkBandwidth, pacing_rate);
-
- // Wait until pacing_rate decreases.
- simulator_result = simulator_.RunUntilOrTimeout(
- [this, pacing_rate]() { return sender_->PacingRate(0) < pacing_rate; },
- timeout);
- ASSERT_TRUE(simulator_result);
- EXPECT_EQ(BbrSender::STARTUP, sender_->ExportDebugState().mode);
- if (GetQuicReloadableFlag(quic_conservative_cwnd_and_pacing_gains)) {
- EXPECT_APPROX_EQ(2.0f * sender_->BandwidthEstimate(),
- sender_->PacingRate(0), 0.01f);
- } else {
- EXPECT_APPROX_EQ(2.885f * sender_->BandwidthEstimate(),
- sender_->PacingRate(0), 0.01f);
- }
-}
-
-TEST_F(BbrSenderTest, 200InitialCongestionWindowWithNetworkParameterAdjusted) {
- CreateDefaultSetup();
-
- bbr_sender_.AddBytesToTransfer(1 * 1024 * 1024);
- // Wait until an ACK comes back.
- const QuicTime::Delta timeout = QuicTime::Delta::FromSeconds(5);
- bool simulator_result = simulator_.RunUntilOrTimeout(
- [this]() { return !sender_->ExportDebugState().min_rtt.IsZero(); },
- timeout);
- ASSERT_TRUE(simulator_result);
-
- // Bootstrap cwnd by a overly large bandwidth sample.
- bbr_sender_.connection()->AdjustNetworkParameters(
- SendAlgorithmInterface::NetworkParams(1024 * kTestLinkBandwidth,
- QuicTime::Delta::Zero(), false));
- // Verify cwnd is capped at 200.
- EXPECT_EQ(200 * kDefaultTCPMSS,
- sender_->ExportDebugState().congestion_window);
- EXPECT_GT(1024 * kTestLinkBandwidth, sender_->PacingRate(0));
-}
-
-TEST_F(BbrSenderTest, 100InitialCongestionWindowFromNetworkParameter) {
- CreateDefaultSetup();
-
- bbr_sender_.AddBytesToTransfer(1 * 1024 * 1024);
- // Wait until an ACK comes back.
- const QuicTime::Delta timeout = QuicTime::Delta::FromSeconds(5);
- bool simulator_result = simulator_.RunUntilOrTimeout(
- [this]() { return !sender_->ExportDebugState().min_rtt.IsZero(); },
- timeout);
- ASSERT_TRUE(simulator_result);
-
- // Bootstrap cwnd by a overly large bandwidth sample.
- SendAlgorithmInterface::NetworkParams network_params(
- 1024 * kTestLinkBandwidth, QuicTime::Delta::Zero(), false);
- network_params.max_initial_congestion_window = 100;
- bbr_sender_.connection()->AdjustNetworkParameters(network_params);
- // Verify cwnd is capped at 100.
- EXPECT_EQ(100 * kDefaultTCPMSS,
- sender_->ExportDebugState().congestion_window);
- EXPECT_GT(1024 * kTestLinkBandwidth, sender_->PacingRate(0));
-}
-
-TEST_F(BbrSenderTest, 100InitialCongestionWindowWithNetworkParameterAdjusted) {
- SetConnectionOption(kICW1);
- CreateDefaultSetup();
-
- bbr_sender_.AddBytesToTransfer(1 * 1024 * 1024);
- // Wait until an ACK comes back.
- const QuicTime::Delta timeout = QuicTime::Delta::FromSeconds(5);
- bool simulator_result = simulator_.RunUntilOrTimeout(
- [this]() { return !sender_->ExportDebugState().min_rtt.IsZero(); },
- timeout);
- ASSERT_TRUE(simulator_result);
-
- // Bootstrap cwnd by a overly large bandwidth sample.
- bbr_sender_.connection()->AdjustNetworkParameters(
- SendAlgorithmInterface::NetworkParams(1024 * kTestLinkBandwidth,
- QuicTime::Delta::Zero(), false));
- // Verify cwnd is capped at 100.
- EXPECT_EQ(100 * kDefaultTCPMSS,
- sender_->ExportDebugState().congestion_window);
- EXPECT_GT(1024 * kTestLinkBandwidth, sender_->PacingRate(0));
-}
-
-// Ensures bandwidth estimate does not change after a loss only event.
-// Regression test for b/151239871.
-TEST_F(BbrSenderTest, LossOnlyCongestionEvent) {
- CreateDefaultSetup();
-
- DriveOutOfStartup();
- EXPECT_FALSE(sender_->ExportDebugState().last_sample_is_app_limited);
-
- // Send some bursts, each burst increments round count by 1, since it only
- // generates small, app-limited samples, the max_bandwidth_ will not be
- // updated. At the end of all bursts, all estimates in max_bandwidth_ will
- // look very old such that any Update() will reset all estimates.
- SendBursts(20, 512, QuicTime::Delta::FromSeconds(3));
-
- QuicUnackedPacketMap* unacked_packets =
- QuicSentPacketManagerPeer::GetUnackedPacketMap(
- QuicConnectionPeer::GetSentPacketManager(bbr_sender_.connection()));
- // Run until we have something in flight.
- bbr_sender_.AddBytesToTransfer(50 * 1024 * 1024);
- bool simulator_result = simulator_.RunUntilOrTimeout(
- [&]() { return unacked_packets->bytes_in_flight() > 0; },
- QuicTime::Delta::FromSeconds(5));
- ASSERT_TRUE(simulator_result);
-
- const QuicBandwidth prior_bandwidth_estimate = sender_->BandwidthEstimate();
- EXPECT_APPROX_EQ(kTestLinkBandwidth, prior_bandwidth_estimate, 0.01f);
-
- // Lose the least unacked packet.
- LostPacketVector lost_packets;
- lost_packets.emplace_back(
- bbr_sender_.connection()->sent_packet_manager().GetLeastUnacked(),
- kDefaultMaxPacketSize);
-
- QuicTime now = simulator_.GetClock()->Now() + kTestRtt * 0.25;
- sender_->OnCongestionEvent(false, unacked_packets->bytes_in_flight(), now, {},
- lost_packets);
-
- // Bandwidth estimate should not change for the loss only event.
- EXPECT_EQ(prior_bandwidth_estimate, sender_->BandwidthEstimate());
-}
-
-TEST_F(BbrSenderTest, EnableOvershootingDetection) {
- SetConnectionOption(kDTOS);
- CreateSmallBufferSetup();
- // Set a overly large initial cwnd.
- sender_->SetInitialCongestionWindowInPackets(200);
- const QuicConnectionStats& stats = bbr_sender_.connection()->GetStats();
- EXPECT_FALSE(stats.overshooting_detected_with_network_parameters_adjusted);
- DoSimpleTransfer(12 * 1024 * 1024, QuicTime::Delta::FromSeconds(30));
-
- // Verify overshooting is detected.
- EXPECT_TRUE(stats.overshooting_detected_with_network_parameters_adjusted);
-}
-
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/congestion_control/cubic_bytes.cc b/chromium/net/third_party/quiche/src/quic/core/congestion_control/cubic_bytes.cc
deleted file mode 100644
index 854d6a75433..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/congestion_control/cubic_bytes.cc
+++ /dev/null
@@ -1,191 +0,0 @@
-// Copyright (c) 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/congestion_control/cubic_bytes.h"
-
-#include <algorithm>
-#include <cmath>
-#include <cstdint>
-
-#include "quic/core/quic_constants.h"
-#include "quic/core/quic_packets.h"
-#include "quic/platform/api/quic_flag_utils.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-namespace {
-
-// Constants based on TCP defaults.
-// The following constants are in 2^10 fractions of a second instead of ms to
-// allow a 10 shift right to divide.
-const int kCubeScale = 40; // 1024*1024^3 (first 1024 is from 0.100^3)
- // where 0.100 is 100 ms which is the scaling
- // round trip time.
-const int kCubeCongestionWindowScale = 410;
-// The cube factor for packets in bytes.
-const uint64_t kCubeFactor =
- (UINT64_C(1) << kCubeScale) / kCubeCongestionWindowScale / kDefaultTCPMSS;
-
-const float kDefaultCubicBackoffFactor = 0.7f; // Default Cubic backoff factor.
-// Additional backoff factor when loss occurs in the concave part of the Cubic
-// curve. This additional backoff factor is expected to give up bandwidth to
-// new concurrent flows and speed up convergence.
-const float kBetaLastMax = 0.85f;
-
-} // namespace
-
-CubicBytes::CubicBytes(const QuicClock* clock)
- : clock_(clock),
- num_connections_(kDefaultNumConnections),
- epoch_(QuicTime::Zero()) {
- ResetCubicState();
-}
-
-void CubicBytes::SetNumConnections(int num_connections) {
- num_connections_ = num_connections;
-}
-
-float CubicBytes::Alpha() const {
- // TCPFriendly alpha is described in Section 3.3 of the CUBIC paper. Note that
- // beta here is a cwnd multiplier, and is equal to 1-beta from the paper.
- // We derive the equivalent alpha for an N-connection emulation as:
- const float beta = Beta();
- return 3 * num_connections_ * num_connections_ * (1 - beta) / (1 + beta);
-}
-
-float CubicBytes::Beta() const {
- // kNConnectionBeta is the backoff factor after loss for our N-connection
- // emulation, which emulates the effective backoff of an ensemble of N
- // TCP-Reno connections on a single loss event. The effective multiplier is
- // computed as:
- return (num_connections_ - 1 + kDefaultCubicBackoffFactor) / num_connections_;
-}
-
-float CubicBytes::BetaLastMax() const {
- // BetaLastMax is the additional backoff factor after loss for our
- // N-connection emulation, which emulates the additional backoff of
- // an ensemble of N TCP-Reno connections on a single loss event. The
- // effective multiplier is computed as:
- return (num_connections_ - 1 + kBetaLastMax) / num_connections_;
-}
-
-void CubicBytes::ResetCubicState() {
- epoch_ = QuicTime::Zero(); // Reset time.
- last_max_congestion_window_ = 0;
- acked_bytes_count_ = 0;
- estimated_tcp_congestion_window_ = 0;
- origin_point_congestion_window_ = 0;
- time_to_origin_point_ = 0;
- last_target_congestion_window_ = 0;
-}
-
-void CubicBytes::OnApplicationLimited() {
- // When sender is not using the available congestion window, the window does
- // not grow. But to be RTT-independent, Cubic assumes that the sender has been
- // using the entire window during the time since the beginning of the current
- // "epoch" (the end of the last loss recovery period). Since
- // application-limited periods break this assumption, we reset the epoch when
- // in such a period. This reset effectively freezes congestion window growth
- // through application-limited periods and allows Cubic growth to continue
- // when the entire window is being used.
- epoch_ = QuicTime::Zero();
-}
-
-QuicByteCount CubicBytes::CongestionWindowAfterPacketLoss(
- QuicByteCount current_congestion_window) {
- // Since bytes-mode Reno mode slightly under-estimates the cwnd, we
- // may never reach precisely the last cwnd over the course of an
- // RTT. Do not interpret a slight under-estimation as competing traffic.
- if (current_congestion_window + kDefaultTCPMSS <
- last_max_congestion_window_) {
- // We never reached the old max, so assume we are competing with
- // another flow. Use our extra back off factor to allow the other
- // flow to go up.
- last_max_congestion_window_ =
- static_cast<int>(BetaLastMax() * current_congestion_window);
- } else {
- last_max_congestion_window_ = current_congestion_window;
- }
- epoch_ = QuicTime::Zero(); // Reset time.
- return static_cast<int>(current_congestion_window * Beta());
-}
-
-QuicByteCount CubicBytes::CongestionWindowAfterAck(
- QuicByteCount acked_bytes,
- QuicByteCount current_congestion_window,
- QuicTime::Delta delay_min,
- QuicTime event_time) {
- acked_bytes_count_ += acked_bytes;
-
- if (!epoch_.IsInitialized()) {
- // First ACK after a loss event.
- QUIC_DVLOG(1) << "Start of epoch";
- epoch_ = event_time; // Start of epoch.
- acked_bytes_count_ = acked_bytes; // Reset count.
- // Reset estimated_tcp_congestion_window_ to be in sync with cubic.
- estimated_tcp_congestion_window_ = current_congestion_window;
- if (last_max_congestion_window_ <= current_congestion_window) {
- time_to_origin_point_ = 0;
- origin_point_congestion_window_ = current_congestion_window;
- } else {
- time_to_origin_point_ = static_cast<uint32_t>(
- cbrt(kCubeFactor *
- (last_max_congestion_window_ - current_congestion_window)));
- origin_point_congestion_window_ = last_max_congestion_window_;
- }
- }
- // Change the time unit from microseconds to 2^10 fractions per second. Take
- // the round trip time in account. This is done to allow us to use shift as a
- // divide operator.
- int64_t elapsed_time =
- ((event_time + delay_min - epoch_).ToMicroseconds() << 10) /
- kNumMicrosPerSecond;
-
- // Right-shifts of negative, signed numbers have implementation-dependent
- // behavior, so force the offset to be positive, as is done in the kernel.
- uint64_t offset = std::abs(time_to_origin_point_ - elapsed_time);
-
- QuicByteCount delta_congestion_window = (kCubeCongestionWindowScale * offset *
- offset * offset * kDefaultTCPMSS) >>
- kCubeScale;
-
- const bool add_delta = elapsed_time > time_to_origin_point_;
- QUICHE_DCHECK(add_delta ||
- (origin_point_congestion_window_ > delta_congestion_window));
- QuicByteCount target_congestion_window =
- add_delta ? origin_point_congestion_window_ + delta_congestion_window
- : origin_point_congestion_window_ - delta_congestion_window;
- // Limit the CWND increase to half the acked bytes.
- target_congestion_window =
- std::min(target_congestion_window,
- current_congestion_window + acked_bytes_count_ / 2);
-
- QUICHE_DCHECK_LT(0u, estimated_tcp_congestion_window_);
- // Increase the window by approximately Alpha * 1 MSS of bytes every
- // time we ack an estimated tcp window of bytes. For small
- // congestion windows (less than 25), the formula below will
- // increase slightly slower than linearly per estimated tcp window
- // of bytes.
- estimated_tcp_congestion_window_ += acked_bytes_count_ *
- (Alpha() * kDefaultTCPMSS) /
- estimated_tcp_congestion_window_;
- acked_bytes_count_ = 0;
-
- // We have a new cubic congestion window.
- last_target_congestion_window_ = target_congestion_window;
-
- // Compute target congestion_window based on cubic target and estimated TCP
- // congestion_window, use highest (fastest).
- if (target_congestion_window < estimated_tcp_congestion_window_) {
- target_congestion_window = estimated_tcp_congestion_window_;
- }
-
- QUIC_DVLOG(1) << "Final target congestion_window: "
- << target_congestion_window;
- return target_congestion_window;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/congestion_control/cubic_bytes.h b/chromium/net/third_party/quiche/src/quic/core/congestion_control/cubic_bytes.h
deleted file mode 100644
index 75a3bcdc3e0..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/congestion_control/cubic_bytes.h
+++ /dev/null
@@ -1,102 +0,0 @@
-// Copyright (c) 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Cubic algorithm, helper class to TCP cubic.
-// For details see http://netsrv.csc.ncsu.edu/export/cubic_a_new_tcp_2008.pdf.
-
-#ifndef QUICHE_QUIC_CORE_CONGESTION_CONTROL_CUBIC_BYTES_H_
-#define QUICHE_QUIC_CORE_CONGESTION_CONTROL_CUBIC_BYTES_H_
-
-#include <cstdint>
-
-#include "quic/core/quic_bandwidth.h"
-#include "quic/core/quic_clock.h"
-#include "quic/core/quic_connection_stats.h"
-#include "quic/core/quic_time.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-namespace test {
-class CubicBytesTest;
-} // namespace test
-
-class QUIC_EXPORT_PRIVATE CubicBytes {
- public:
- explicit CubicBytes(const QuicClock* clock);
- CubicBytes(const CubicBytes&) = delete;
- CubicBytes& operator=(const CubicBytes&) = delete;
-
- void SetNumConnections(int num_connections);
-
- // Call after a timeout to reset the cubic state.
- void ResetCubicState();
-
- // Compute a new congestion window to use after a loss event.
- // Returns the new congestion window in packets. The new congestion window is
- // a multiplicative decrease of our current window.
- QuicByteCount CongestionWindowAfterPacketLoss(QuicPacketCount current);
-
- // Compute a new congestion window to use after a received ACK.
- // Returns the new congestion window in bytes. The new congestion window
- // follows a cubic function that depends on the time passed since last packet
- // loss.
- QuicByteCount CongestionWindowAfterAck(QuicByteCount acked_bytes,
- QuicByteCount current,
- QuicTime::Delta delay_min,
- QuicTime event_time);
-
- // Call on ack arrival when sender is unable to use the available congestion
- // window. Resets Cubic state during quiescence.
- void OnApplicationLimited();
-
- private:
- friend class test::CubicBytesTest;
-
- static const QuicTime::Delta MaxCubicTimeInterval() {
- return QuicTime::Delta::FromMilliseconds(30);
- }
-
- // Compute the TCP Cubic alpha, beta, and beta-last-max based on the
- // current number of connections.
- float Alpha() const;
- float Beta() const;
- float BetaLastMax() const;
-
- QuicByteCount last_max_congestion_window() const {
- return last_max_congestion_window_;
- }
-
- const QuicClock* clock_;
-
- // Number of connections to simulate.
- int num_connections_;
-
- // Time when this cycle started, after last loss event.
- QuicTime epoch_;
-
- // Max congestion window used just before last loss event.
- // Note: to improve fairness to other streams an additional back off is
- // applied to this value if the new value is below our latest value.
- QuicByteCount last_max_congestion_window_;
-
- // Number of acked bytes since the cycle started (epoch).
- QuicByteCount acked_bytes_count_;
-
- // TCP Reno equivalent congestion window in packets.
- QuicByteCount estimated_tcp_congestion_window_;
-
- // Origin point of cubic function.
- QuicByteCount origin_point_congestion_window_;
-
- // Time to origin point of cubic function in 2^10 fractions of a second.
- uint32_t time_to_origin_point_;
-
- // Last congestion window in packets computed by cubic function.
- QuicByteCount last_target_congestion_window_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_CONGESTION_CONTROL_CUBIC_BYTES_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/congestion_control/cubic_bytes_test.cc b/chromium/net/third_party/quiche/src/quic/core/congestion_control/cubic_bytes_test.cc
deleted file mode 100644
index edbe18dbea5..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/congestion_control/cubic_bytes_test.cc
+++ /dev/null
@@ -1,387 +0,0 @@
-// Copyright (c) 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/congestion_control/cubic_bytes.h"
-
-#include <cstdint>
-
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/mock_clock.h"
-
-namespace quic {
-namespace test {
-namespace {
-
-const float kBeta = 0.7f; // Default Cubic backoff factor.
-const float kBetaLastMax = 0.85f; // Default Cubic backoff factor.
-const uint32_t kNumConnections = 2;
-const float kNConnectionBeta = (kNumConnections - 1 + kBeta) / kNumConnections;
-const float kNConnectionBetaLastMax =
- (kNumConnections - 1 + kBetaLastMax) / kNumConnections;
-const float kNConnectionAlpha = 3 * kNumConnections * kNumConnections *
- (1 - kNConnectionBeta) / (1 + kNConnectionBeta);
-
-} // namespace
-
-class CubicBytesTest : public QuicTest {
- protected:
- CubicBytesTest()
- : one_ms_(QuicTime::Delta::FromMilliseconds(1)),
- hundred_ms_(QuicTime::Delta::FromMilliseconds(100)),
- cubic_(&clock_) {}
-
- QuicByteCount RenoCwndInBytes(QuicByteCount current_cwnd) {
- QuicByteCount reno_estimated_cwnd =
- current_cwnd +
- kDefaultTCPMSS * (kNConnectionAlpha * kDefaultTCPMSS) / current_cwnd;
- return reno_estimated_cwnd;
- }
-
- QuicByteCount ConservativeCwndInBytes(QuicByteCount current_cwnd) {
- QuicByteCount conservative_cwnd = current_cwnd + kDefaultTCPMSS / 2;
- return conservative_cwnd;
- }
-
- QuicByteCount CubicConvexCwndInBytes(QuicByteCount initial_cwnd,
- QuicTime::Delta rtt,
- QuicTime::Delta elapsed_time) {
- const int64_t offset =
- ((elapsed_time + rtt).ToMicroseconds() << 10) / 1000000;
- const QuicByteCount delta_congestion_window =
- ((410 * offset * offset * offset) * kDefaultTCPMSS >> 40);
- const QuicByteCount cubic_cwnd = initial_cwnd + delta_congestion_window;
- return cubic_cwnd;
- }
-
- QuicByteCount LastMaxCongestionWindow() {
- return cubic_.last_max_congestion_window();
- }
-
- QuicTime::Delta MaxCubicTimeInterval() {
- return cubic_.MaxCubicTimeInterval();
- }
-
- const QuicTime::Delta one_ms_;
- const QuicTime::Delta hundred_ms_;
- MockClock clock_;
- CubicBytes cubic_;
-};
-
-// TODO(jokulik): The original "AboveOrigin" test, below, is very
-// loose. It's nearly impossible to make the test tighter without
-// deploying the fix for convex mode. Once cubic convex is deployed,
-// replace "AboveOrigin" with this test.
-TEST_F(CubicBytesTest, AboveOriginWithTighterBounds) {
- // Convex growth.
- const QuicTime::Delta rtt_min = hundred_ms_;
- int64_t rtt_min_ms = rtt_min.ToMilliseconds();
- float rtt_min_s = rtt_min_ms / 1000.0;
- QuicByteCount current_cwnd = 10 * kDefaultTCPMSS;
- const QuicByteCount initial_cwnd = current_cwnd;
-
- clock_.AdvanceTime(one_ms_);
- const QuicTime initial_time = clock_.ApproximateNow();
- const QuicByteCount expected_first_cwnd = RenoCwndInBytes(current_cwnd);
- current_cwnd = cubic_.CongestionWindowAfterAck(kDefaultTCPMSS, current_cwnd,
- rtt_min, initial_time);
- ASSERT_EQ(expected_first_cwnd, current_cwnd);
-
- // Normal TCP phase.
- // The maximum number of expected Reno RTTs is calculated by
- // finding the point where the cubic curve and the reno curve meet.
- const int max_reno_rtts =
- std::sqrt(kNConnectionAlpha / (.4 * rtt_min_s * rtt_min_s * rtt_min_s)) -
- 2;
- for (int i = 0; i < max_reno_rtts; ++i) {
- // Alternatively, we expect it to increase by one, every time we
- // receive current_cwnd/Alpha acks back. (This is another way of
- // saying we expect cwnd to increase by approximately Alpha once
- // we receive current_cwnd number ofacks back).
- const uint64_t num_acks_this_epoch =
- current_cwnd / kDefaultTCPMSS / kNConnectionAlpha;
- const QuicByteCount initial_cwnd_this_epoch = current_cwnd;
- for (QuicPacketCount n = 0; n < num_acks_this_epoch; ++n) {
- // Call once per ACK.
- const QuicByteCount expected_next_cwnd = RenoCwndInBytes(current_cwnd);
- current_cwnd = cubic_.CongestionWindowAfterAck(
- kDefaultTCPMSS, current_cwnd, rtt_min, clock_.ApproximateNow());
- ASSERT_EQ(expected_next_cwnd, current_cwnd);
- }
- // Our byte-wise Reno implementation is an estimate. We expect
- // the cwnd to increase by approximately one MSS every
- // cwnd/kDefaultTCPMSS/Alpha acks, but it may be off by as much as
- // half a packet for smaller values of current_cwnd.
- const QuicByteCount cwnd_change_this_epoch =
- current_cwnd - initial_cwnd_this_epoch;
- ASSERT_NEAR(kDefaultTCPMSS, cwnd_change_this_epoch, kDefaultTCPMSS / 2);
- clock_.AdvanceTime(hundred_ms_);
- }
-
- for (int i = 0; i < 54; ++i) {
- const uint64_t max_acks_this_epoch = current_cwnd / kDefaultTCPMSS;
- const QuicTime::Delta interval = QuicTime::Delta::FromMicroseconds(
- hundred_ms_.ToMicroseconds() / max_acks_this_epoch);
- for (QuicPacketCount n = 0; n < max_acks_this_epoch; ++n) {
- clock_.AdvanceTime(interval);
- current_cwnd = cubic_.CongestionWindowAfterAck(
- kDefaultTCPMSS, current_cwnd, rtt_min, clock_.ApproximateNow());
- const QuicByteCount expected_cwnd = CubicConvexCwndInBytes(
- initial_cwnd, rtt_min, (clock_.ApproximateNow() - initial_time));
- // If we allow per-ack updates, every update is a small cubic update.
- ASSERT_EQ(expected_cwnd, current_cwnd);
- }
- }
- const QuicByteCount expected_cwnd = CubicConvexCwndInBytes(
- initial_cwnd, rtt_min, (clock_.ApproximateNow() - initial_time));
- current_cwnd = cubic_.CongestionWindowAfterAck(
- kDefaultTCPMSS, current_cwnd, rtt_min, clock_.ApproximateNow());
- ASSERT_EQ(expected_cwnd, current_cwnd);
-}
-
-// TODO(ianswett): This test was disabled when all fixes were enabled, but it
-// may be worth fixing.
-TEST_F(CubicBytesTest, DISABLED_AboveOrigin) {
- // Convex growth.
- const QuicTime::Delta rtt_min = hundred_ms_;
- QuicByteCount current_cwnd = 10 * kDefaultTCPMSS;
- // Without the signed-integer, cubic-convex fix, we start out in the
- // wrong mode.
- QuicPacketCount expected_cwnd = RenoCwndInBytes(current_cwnd);
- // Initialize the state.
- clock_.AdvanceTime(one_ms_);
- ASSERT_EQ(expected_cwnd,
- cubic_.CongestionWindowAfterAck(kDefaultTCPMSS, current_cwnd,
- rtt_min, clock_.ApproximateNow()));
- current_cwnd = expected_cwnd;
- const QuicPacketCount initial_cwnd = expected_cwnd;
- // Normal TCP phase.
- for (int i = 0; i < 48; ++i) {
- for (QuicPacketCount n = 1;
- n < current_cwnd / kDefaultTCPMSS / kNConnectionAlpha; ++n) {
- // Call once per ACK.
- ASSERT_NEAR(
- current_cwnd,
- cubic_.CongestionWindowAfterAck(kDefaultTCPMSS, current_cwnd, rtt_min,
- clock_.ApproximateNow()),
- kDefaultTCPMSS);
- }
- clock_.AdvanceTime(hundred_ms_);
- current_cwnd = cubic_.CongestionWindowAfterAck(
- kDefaultTCPMSS, current_cwnd, rtt_min, clock_.ApproximateNow());
- // When we fix convex mode and the uint64 arithmetic, we
- // increase the expected_cwnd only after after the first 100ms,
- // rather than after the initial 1ms.
- expected_cwnd += kDefaultTCPMSS;
- ASSERT_NEAR(expected_cwnd, current_cwnd, kDefaultTCPMSS);
- }
- // Cubic phase.
- for (int i = 0; i < 52; ++i) {
- for (QuicPacketCount n = 1; n < current_cwnd / kDefaultTCPMSS; ++n) {
- // Call once per ACK.
- ASSERT_NEAR(
- current_cwnd,
- cubic_.CongestionWindowAfterAck(kDefaultTCPMSS, current_cwnd, rtt_min,
- clock_.ApproximateNow()),
- kDefaultTCPMSS);
- }
- clock_.AdvanceTime(hundred_ms_);
- current_cwnd = cubic_.CongestionWindowAfterAck(
- kDefaultTCPMSS, current_cwnd, rtt_min, clock_.ApproximateNow());
- }
- // Total time elapsed so far; add min_rtt (0.1s) here as well.
- float elapsed_time_s = 10.0f + 0.1f;
- // |expected_cwnd| is initial value of cwnd + K * t^3, where K = 0.4.
- expected_cwnd =
- initial_cwnd / kDefaultTCPMSS +
- (elapsed_time_s * elapsed_time_s * elapsed_time_s * 410) / 1024;
- EXPECT_EQ(expected_cwnd, current_cwnd / kDefaultTCPMSS);
-}
-
-// Constructs an artificial scenario to ensure that cubic-convex
-// increases are truly fine-grained:
-//
-// - After starting the epoch, this test advances the elapsed time
-// sufficiently far that cubic will do small increases at less than
-// MaxCubicTimeInterval() intervals.
-//
-// - Sets an artificially large initial cwnd to prevent Reno from the
-// convex increases on every ack.
-TEST_F(CubicBytesTest, AboveOriginFineGrainedCubing) {
- // Start the test with an artificially large cwnd to prevent Reno
- // from over-taking cubic.
- QuicByteCount current_cwnd = 1000 * kDefaultTCPMSS;
- const QuicByteCount initial_cwnd = current_cwnd;
- const QuicTime::Delta rtt_min = hundred_ms_;
- clock_.AdvanceTime(one_ms_);
- QuicTime initial_time = clock_.ApproximateNow();
-
- // Start the epoch and then artificially advance the time.
- current_cwnd = cubic_.CongestionWindowAfterAck(
- kDefaultTCPMSS, current_cwnd, rtt_min, clock_.ApproximateNow());
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(600));
- current_cwnd = cubic_.CongestionWindowAfterAck(
- kDefaultTCPMSS, current_cwnd, rtt_min, clock_.ApproximateNow());
-
- // We expect the algorithm to perform only non-zero, fine-grained cubic
- // increases on every ack in this case.
- for (int i = 0; i < 100; ++i) {
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
- const QuicByteCount expected_cwnd = CubicConvexCwndInBytes(
- initial_cwnd, rtt_min, (clock_.ApproximateNow() - initial_time));
- const QuicByteCount next_cwnd = cubic_.CongestionWindowAfterAck(
- kDefaultTCPMSS, current_cwnd, rtt_min, clock_.ApproximateNow());
- // Make sure we are performing cubic increases.
- ASSERT_EQ(expected_cwnd, next_cwnd);
- // Make sure that these are non-zero, less-than-packet sized
- // increases.
- ASSERT_GT(next_cwnd, current_cwnd);
- const QuicByteCount cwnd_delta = next_cwnd - current_cwnd;
- ASSERT_GT(kDefaultTCPMSS * .1, cwnd_delta);
-
- current_cwnd = next_cwnd;
- }
-}
-
-// Constructs an artificial scenario to show what happens when we
-// allow per-ack updates, rather than limititing update freqency. In
-// this scenario, the first two acks of the epoch produce the same
-// cwnd. When we limit per-ack updates, this would cause the
-// cessation of cubic updates for 30ms. When we allow per-ack
-// updates, the window continues to grow on every ack.
-TEST_F(CubicBytesTest, PerAckUpdates) {
- // Start the test with a large cwnd and RTT, to force the first
- // increase to be a cubic increase.
- QuicPacketCount initial_cwnd_packets = 150;
- QuicByteCount current_cwnd = initial_cwnd_packets * kDefaultTCPMSS;
- const QuicTime::Delta rtt_min = 350 * one_ms_;
-
- // Initialize the epoch
- clock_.AdvanceTime(one_ms_);
- // Keep track of the growth of the reno-equivalent cwnd.
- QuicByteCount reno_cwnd = RenoCwndInBytes(current_cwnd);
- current_cwnd = cubic_.CongestionWindowAfterAck(
- kDefaultTCPMSS, current_cwnd, rtt_min, clock_.ApproximateNow());
- const QuicByteCount initial_cwnd = current_cwnd;
-
- // Simulate the return of cwnd packets in less than
- // MaxCubicInterval() time.
- const QuicPacketCount max_acks = initial_cwnd_packets / kNConnectionAlpha;
- const QuicTime::Delta interval = QuicTime::Delta::FromMicroseconds(
- MaxCubicTimeInterval().ToMicroseconds() / (max_acks + 1));
-
- // In this scenario, the first increase is dictated by the cubic
- // equation, but it is less than one byte, so the cwnd doesn't
- // change. Normally, without per-ack increases, any cwnd plateau
- // will cause the cwnd to be pinned for MaxCubicTimeInterval(). If
- // we enable per-ack updates, the cwnd will continue to grow,
- // regardless of the temporary plateau.
- clock_.AdvanceTime(interval);
- reno_cwnd = RenoCwndInBytes(reno_cwnd);
- ASSERT_EQ(current_cwnd,
- cubic_.CongestionWindowAfterAck(kDefaultTCPMSS, current_cwnd,
- rtt_min, clock_.ApproximateNow()));
- for (QuicPacketCount i = 1; i < max_acks; ++i) {
- clock_.AdvanceTime(interval);
- const QuicByteCount next_cwnd = cubic_.CongestionWindowAfterAck(
- kDefaultTCPMSS, current_cwnd, rtt_min, clock_.ApproximateNow());
- reno_cwnd = RenoCwndInBytes(reno_cwnd);
- // The window shoud increase on every ack.
- ASSERT_LT(current_cwnd, next_cwnd);
- ASSERT_EQ(reno_cwnd, next_cwnd);
- current_cwnd = next_cwnd;
- }
-
- // After all the acks are returned from the epoch, we expect the
- // cwnd to have increased by nearly one packet. (Not exactly one
- // packet, because our byte-wise Reno algorithm is always a slight
- // under-estimation). Without per-ack updates, the current_cwnd
- // would otherwise be unchanged.
- const QuicByteCount minimum_expected_increase = kDefaultTCPMSS * .9;
- EXPECT_LT(minimum_expected_increase + initial_cwnd, current_cwnd);
-}
-
-TEST_F(CubicBytesTest, LossEvents) {
- const QuicTime::Delta rtt_min = hundred_ms_;
- QuicByteCount current_cwnd = 422 * kDefaultTCPMSS;
- // Without the signed-integer, cubic-convex fix, we mistakenly
- // increment cwnd after only one_ms_ and a single ack.
- QuicPacketCount expected_cwnd = RenoCwndInBytes(current_cwnd);
- // Initialize the state.
- clock_.AdvanceTime(one_ms_);
- EXPECT_EQ(expected_cwnd,
- cubic_.CongestionWindowAfterAck(kDefaultTCPMSS, current_cwnd,
- rtt_min, clock_.ApproximateNow()));
-
- // On the first loss, the last max congestion window is set to the
- // congestion window before the loss.
- QuicByteCount pre_loss_cwnd = current_cwnd;
- ASSERT_EQ(0u, LastMaxCongestionWindow());
- expected_cwnd = static_cast<QuicByteCount>(current_cwnd * kNConnectionBeta);
- EXPECT_EQ(expected_cwnd,
- cubic_.CongestionWindowAfterPacketLoss(current_cwnd));
- ASSERT_EQ(pre_loss_cwnd, LastMaxCongestionWindow());
- current_cwnd = expected_cwnd;
-
- // On the second loss, the current congestion window has not yet
- // reached the last max congestion window. The last max congestion
- // window will be reduced by an additional backoff factor to allow
- // for competition.
- pre_loss_cwnd = current_cwnd;
- expected_cwnd = static_cast<QuicByteCount>(current_cwnd * kNConnectionBeta);
- ASSERT_EQ(expected_cwnd,
- cubic_.CongestionWindowAfterPacketLoss(current_cwnd));
- current_cwnd = expected_cwnd;
- EXPECT_GT(pre_loss_cwnd, LastMaxCongestionWindow());
- QuicByteCount expected_last_max =
- static_cast<QuicByteCount>(pre_loss_cwnd * kNConnectionBetaLastMax);
- EXPECT_EQ(expected_last_max, LastMaxCongestionWindow());
- EXPECT_LT(expected_cwnd, LastMaxCongestionWindow());
- // Simulate an increase, and check that we are below the origin.
- current_cwnd = cubic_.CongestionWindowAfterAck(
- kDefaultTCPMSS, current_cwnd, rtt_min, clock_.ApproximateNow());
- EXPECT_GT(LastMaxCongestionWindow(), current_cwnd);
-
- // On the final loss, simulate the condition where the congestion
- // window had a chance to grow nearly to the last congestion window.
- current_cwnd = LastMaxCongestionWindow() - 1;
- pre_loss_cwnd = current_cwnd;
- expected_cwnd = static_cast<QuicByteCount>(current_cwnd * kNConnectionBeta);
- EXPECT_EQ(expected_cwnd,
- cubic_.CongestionWindowAfterPacketLoss(current_cwnd));
- expected_last_max = pre_loss_cwnd;
- ASSERT_EQ(expected_last_max, LastMaxCongestionWindow());
-}
-
-TEST_F(CubicBytesTest, BelowOrigin) {
- // Concave growth.
- const QuicTime::Delta rtt_min = hundred_ms_;
- QuicByteCount current_cwnd = 422 * kDefaultTCPMSS;
- // Without the signed-integer, cubic-convex fix, we mistakenly
- // increment cwnd after only one_ms_ and a single ack.
- QuicPacketCount expected_cwnd = RenoCwndInBytes(current_cwnd);
- // Initialize the state.
- clock_.AdvanceTime(one_ms_);
- EXPECT_EQ(expected_cwnd,
- cubic_.CongestionWindowAfterAck(kDefaultTCPMSS, current_cwnd,
- rtt_min, clock_.ApproximateNow()));
- expected_cwnd = static_cast<QuicPacketCount>(current_cwnd * kNConnectionBeta);
- EXPECT_EQ(expected_cwnd,
- cubic_.CongestionWindowAfterPacketLoss(current_cwnd));
- current_cwnd = expected_cwnd;
- // First update after loss to initialize the epoch.
- current_cwnd = cubic_.CongestionWindowAfterAck(
- kDefaultTCPMSS, current_cwnd, rtt_min, clock_.ApproximateNow());
- // Cubic phase.
- for (int i = 0; i < 40; ++i) {
- clock_.AdvanceTime(hundred_ms_);
- current_cwnd = cubic_.CongestionWindowAfterAck(
- kDefaultTCPMSS, current_cwnd, rtt_min, clock_.ApproximateNow());
- }
- expected_cwnd = 553632;
- EXPECT_EQ(expected_cwnd, current_cwnd);
-}
-
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/congestion_control/general_loss_algorithm.cc b/chromium/net/third_party/quiche/src/quic/core/congestion_control/general_loss_algorithm.cc
deleted file mode 100644
index f9b7ac42c09..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/congestion_control/general_loss_algorithm.cc
+++ /dev/null
@@ -1,196 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/congestion_control/general_loss_algorithm.h"
-
-#include "quic/core/congestion_control/rtt_stats.h"
-#include "quic/core/quic_packets.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_flag_utils.h"
-#include "quic/platform/api/quic_flags.h"
-
-namespace quic {
-
-namespace {
-float DetectionResponseTime(QuicTime::Delta rtt,
- QuicTime send_time,
- QuicTime detection_time) {
- if (detection_time <= send_time || rtt.IsZero()) {
- // Time skewed, assume a very fast detection where |detection_time| is
- // |send_time| + |rtt|.
- return 1.0;
- }
- float send_to_detection_us = (detection_time - send_time).ToMicroseconds();
- return send_to_detection_us / rtt.ToMicroseconds();
-}
-
-QuicTime::Delta GetMaxRtt(const RttStats& rtt_stats) {
- return std::max(kAlarmGranularity,
- std::max(rtt_stats.previous_srtt(), rtt_stats.latest_rtt()));
-}
-
-} // namespace
-
-// Uses nack counts to decide when packets are lost.
-LossDetectionInterface::DetectionStats GeneralLossAlgorithm::DetectLosses(
- const QuicUnackedPacketMap& unacked_packets,
- QuicTime time,
- const RttStats& rtt_stats,
- QuicPacketNumber largest_newly_acked,
- const AckedPacketVector& packets_acked,
- LostPacketVector* packets_lost) {
- DetectionStats detection_stats;
-
- loss_detection_timeout_ = QuicTime::Zero();
- if (!packets_acked.empty() && least_in_flight_.IsInitialized() &&
- packets_acked.front().packet_number == least_in_flight_) {
- if (packets_acked.back().packet_number == largest_newly_acked &&
- least_in_flight_ + packets_acked.size() - 1 == largest_newly_acked) {
- // Optimization for the case when no packet is missing. Please note,
- // packets_acked can include packets of different packet number space, so
- // do not use this optimization if largest_newly_acked is not the largest
- // packet in packets_acked.
- least_in_flight_ = largest_newly_acked + 1;
- return detection_stats;
- }
- // There is hole in acked_packets, increment least_in_flight_ if possible.
- for (const auto& acked : packets_acked) {
- if (acked.packet_number != least_in_flight_) {
- break;
- }
- ++least_in_flight_;
- }
- }
-
- const QuicTime::Delta max_rtt = GetMaxRtt(rtt_stats);
-
- QuicPacketNumber packet_number = unacked_packets.GetLeastUnacked();
- auto it = unacked_packets.begin();
- if (least_in_flight_.IsInitialized() && least_in_flight_ >= packet_number) {
- if (least_in_flight_ > unacked_packets.largest_sent_packet() + 1) {
- QUIC_BUG(quic_bug_10430_1) << "least_in_flight: " << least_in_flight_
- << " is greater than largest_sent_packet + 1: "
- << unacked_packets.largest_sent_packet() + 1;
- } else {
- it += (least_in_flight_ - packet_number);
- packet_number = least_in_flight_;
- }
- }
- // Clear least_in_flight_.
- least_in_flight_.Clear();
- QUICHE_DCHECK_EQ(packet_number_space_,
- unacked_packets.GetPacketNumberSpace(largest_newly_acked));
- for (; it != unacked_packets.end() && packet_number <= largest_newly_acked;
- ++it, ++packet_number) {
- if (unacked_packets.GetPacketNumberSpace(it->encryption_level) !=
- packet_number_space_) {
- // Skip packets of different packet number space.
- continue;
- }
-
- if (!it->in_flight) {
- continue;
- }
-
- if (parent_ != nullptr && largest_newly_acked != packet_number) {
- parent_->OnReorderingDetected();
- }
-
- if (largest_newly_acked - packet_number >
- detection_stats.sent_packets_max_sequence_reordering) {
- detection_stats.sent_packets_max_sequence_reordering =
- largest_newly_acked - packet_number;
- }
-
- // Packet threshold loss detection.
- // Skip packet threshold loss detection if largest_newly_acked is a runt.
- const bool skip_packet_threshold_detection =
- !use_packet_threshold_for_runt_packets_ &&
- it->bytes_sent >
- unacked_packets.GetTransmissionInfo(largest_newly_acked).bytes_sent;
- if (!skip_packet_threshold_detection &&
- largest_newly_acked - packet_number >= reordering_threshold_) {
- packets_lost->push_back(LostPacket(packet_number, it->bytes_sent));
- detection_stats.total_loss_detection_response_time +=
- DetectionResponseTime(max_rtt, it->sent_time, time);
- continue;
- }
-
- // Time threshold loss detection.
- const QuicTime::Delta loss_delay = max_rtt + (max_rtt >> reordering_shift_);
- QuicTime when_lost = it->sent_time + loss_delay;
- if (time < when_lost) {
- if (time >=
- it->sent_time + max_rtt + (max_rtt >> (reordering_shift_ + 1))) {
- ++detection_stats.sent_packets_num_borderline_time_reorderings;
- }
- loss_detection_timeout_ = when_lost;
- if (!least_in_flight_.IsInitialized()) {
- // At this point, packet_number is in flight and not detected as lost.
- least_in_flight_ = packet_number;
- }
- break;
- }
- packets_lost->push_back(LostPacket(packet_number, it->bytes_sent));
- detection_stats.total_loss_detection_response_time +=
- DetectionResponseTime(max_rtt, it->sent_time, time);
- }
- if (!least_in_flight_.IsInitialized()) {
- // There is no in flight packet.
- least_in_flight_ = largest_newly_acked + 1;
- }
-
- return detection_stats;
-}
-
-QuicTime GeneralLossAlgorithm::GetLossTimeout() const {
- return loss_detection_timeout_;
-}
-
-void GeneralLossAlgorithm::SpuriousLossDetected(
- const QuicUnackedPacketMap& unacked_packets,
- const RttStats& rtt_stats,
- QuicTime ack_receive_time,
- QuicPacketNumber packet_number,
- QuicPacketNumber previous_largest_acked) {
- if (use_adaptive_time_threshold_ && reordering_shift_ > 0) {
- // Increase reordering fraction such that the packet would not have been
- // declared lost.
- QuicTime::Delta time_needed =
- ack_receive_time -
- unacked_packets.GetTransmissionInfo(packet_number).sent_time;
- QuicTime::Delta max_rtt =
- std::max(rtt_stats.previous_srtt(), rtt_stats.latest_rtt());
- while (max_rtt + (max_rtt >> reordering_shift_) < time_needed &&
- reordering_shift_ > 0) {
- --reordering_shift_;
- }
- }
-
- if (use_adaptive_reordering_threshold_) {
- QUICHE_DCHECK_LT(packet_number, previous_largest_acked);
- // Increase reordering_threshold_ such that packet_number would not have
- // been declared lost.
- reordering_threshold_ = std::max(
- reordering_threshold_, previous_largest_acked - packet_number + 1);
- }
-}
-
-void GeneralLossAlgorithm::Initialize(PacketNumberSpace packet_number_space,
- LossDetectionInterface* parent) {
- parent_ = parent;
- if (packet_number_space_ < NUM_PACKET_NUMBER_SPACES) {
- QUIC_BUG(quic_bug_10430_2) << "Cannot switch packet_number_space";
- return;
- }
-
- packet_number_space_ = packet_number_space;
-}
-
-void GeneralLossAlgorithm::Reset() {
- loss_detection_timeout_ = QuicTime::Zero();
- least_in_flight_.Clear();
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/congestion_control/general_loss_algorithm.h b/chromium/net/third_party/quiche/src/quic/core/congestion_control/general_loss_algorithm.h
deleted file mode 100644
index 6a3c5dd3515..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/congestion_control/general_loss_algorithm.h
+++ /dev/null
@@ -1,138 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_CONGESTION_CONTROL_GENERAL_LOSS_ALGORITHM_H_
-#define QUICHE_QUIC_CORE_CONGESTION_CONTROL_GENERAL_LOSS_ALGORITHM_H_
-
-#include <algorithm>
-#include <map>
-
-#include "quic/core/congestion_control/loss_detection_interface.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_time.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_unacked_packet_map.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// Class which can be configured to implement's TCP's approach of detecting loss
-// when 3 nacks have been received for a packet or with a time threshold.
-// Also implements TCP's early retransmit(RFC5827).
-class QUIC_EXPORT_PRIVATE GeneralLossAlgorithm : public LossDetectionInterface {
- public:
- GeneralLossAlgorithm() = default;
- GeneralLossAlgorithm(const GeneralLossAlgorithm&) = delete;
- GeneralLossAlgorithm& operator=(const GeneralLossAlgorithm&) = delete;
- ~GeneralLossAlgorithm() override {}
-
- void SetFromConfig(const QuicConfig& /*config*/,
- Perspective /*perspective*/) override {}
-
- // Uses |largest_acked| and time to decide when packets are lost.
- DetectionStats DetectLosses(const QuicUnackedPacketMap& unacked_packets,
- QuicTime time,
- const RttStats& rtt_stats,
- QuicPacketNumber largest_newly_acked,
- const AckedPacketVector& packets_acked,
- LostPacketVector* packets_lost) override;
-
- // Returns a non-zero value when the early retransmit timer is active.
- QuicTime GetLossTimeout() const override;
-
- // Called to increases time and/or packet threshold.
- void SpuriousLossDetected(const QuicUnackedPacketMap& unacked_packets,
- const RttStats& rtt_stats,
- QuicTime ack_receive_time,
- QuicPacketNumber packet_number,
- QuicPacketNumber previous_largest_acked) override;
-
- void OnConfigNegotiated() override {
- QUICHE_DCHECK(false)
- << "Unexpected call to GeneralLossAlgorithm::OnConfigNegotiated";
- }
-
- void OnMinRttAvailable() override {
- QUICHE_DCHECK(false)
- << "Unexpected call to GeneralLossAlgorithm::OnMinRttAvailable";
- }
-
- void OnUserAgentIdKnown() override {
- QUICHE_DCHECK(false)
- << "Unexpected call to GeneralLossAlgorithm::OnUserAgentIdKnown";
- }
-
- void OnConnectionClosed() override {
- QUICHE_DCHECK(false)
- << "Unexpected call to GeneralLossAlgorithm::OnConnectionClosed";
- }
-
- void OnReorderingDetected() override {
- QUICHE_DCHECK(false)
- << "Unexpected call to GeneralLossAlgorithm::OnReorderingDetected";
- }
-
- void Initialize(PacketNumberSpace packet_number_space,
- LossDetectionInterface* parent);
-
- void Reset();
-
- QuicPacketCount reordering_threshold() const { return reordering_threshold_; }
-
- int reordering_shift() const { return reordering_shift_; }
-
- void set_reordering_shift(int reordering_shift) {
- reordering_shift_ = reordering_shift;
- }
-
- void set_reordering_threshold(QuicPacketCount reordering_threshold) {
- reordering_threshold_ = reordering_threshold;
- }
-
- bool use_adaptive_reordering_threshold() const {
- return use_adaptive_reordering_threshold_;
- }
-
- void set_use_adaptive_reordering_threshold(bool value) {
- use_adaptive_reordering_threshold_ = value;
- }
-
- bool use_adaptive_time_threshold() const {
- return use_adaptive_time_threshold_;
- }
-
- void enable_adaptive_time_threshold() { use_adaptive_time_threshold_ = true; }
-
- bool use_packet_threshold_for_runt_packets() const {
- return use_packet_threshold_for_runt_packets_;
- }
-
- void disable_packet_threshold_for_runt_packets() {
- use_packet_threshold_for_runt_packets_ = false;
- }
-
- private:
- LossDetectionInterface* parent_ = nullptr;
- QuicTime loss_detection_timeout_ = QuicTime::Zero();
- // Fraction of a max(SRTT, latest_rtt) to permit reordering before declaring
- // loss. Fraction calculated by shifting max(SRTT, latest_rtt) to the right
- // by reordering_shift.
- int reordering_shift_ = kDefaultLossDelayShift;
- // Reordering threshold for loss detection.
- QuicPacketCount reordering_threshold_ = kDefaultPacketReorderingThreshold;
- // If true, uses adaptive reordering threshold for loss detection.
- bool use_adaptive_reordering_threshold_ = true;
- // If true, uses adaptive time threshold for time based loss detection.
- bool use_adaptive_time_threshold_ = false;
- // If true, uses packet threshold when largest acked is a runt packet.
- bool use_packet_threshold_for_runt_packets_ = true;
- // The least in flight packet. Loss detection should start from this. Please
- // note, least_in_flight_ could be largest packet ever sent + 1.
- QuicPacketNumber least_in_flight_{1};
- PacketNumberSpace packet_number_space_ = NUM_PACKET_NUMBER_SPACES;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_CONGESTION_CONTROL_GENERAL_LOSS_ALGORITHM_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/congestion_control/general_loss_algorithm_test.cc b/chromium/net/third_party/quiche/src/quic/core/congestion_control/general_loss_algorithm_test.cc
deleted file mode 100644
index b8cffab6529..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/congestion_control/general_loss_algorithm_test.cc
+++ /dev/null
@@ -1,489 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/congestion_control/general_loss_algorithm.h"
-
-#include <algorithm>
-#include <cstdint>
-
-#include "quic/core/congestion_control/rtt_stats.h"
-#include "quic/core/quic_unacked_packet_map.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/mock_clock.h"
-
-namespace quic {
-namespace test {
-namespace {
-
-// Default packet length.
-const uint32_t kDefaultLength = 1000;
-
-class GeneralLossAlgorithmTest : public QuicTest {
- protected:
- GeneralLossAlgorithmTest() : unacked_packets_(Perspective::IS_CLIENT) {
- rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(100),
- QuicTime::Delta::Zero(), clock_.Now());
- EXPECT_LT(0, rtt_stats_.smoothed_rtt().ToMicroseconds());
- loss_algorithm_.Initialize(HANDSHAKE_DATA, nullptr);
- }
-
- ~GeneralLossAlgorithmTest() override {}
-
- void SendDataPacket(uint64_t packet_number,
- QuicPacketLength encrypted_length) {
- QuicStreamFrame frame;
- frame.stream_id = QuicUtils::GetFirstBidirectionalStreamId(
- CurrentSupportedVersions()[0].transport_version,
- Perspective::IS_CLIENT);
- SerializedPacket packet(QuicPacketNumber(packet_number),
- PACKET_1BYTE_PACKET_NUMBER, nullptr,
- encrypted_length, false, false);
- packet.retransmittable_frames.push_back(QuicFrame(frame));
- unacked_packets_.AddSentPacket(&packet, NOT_RETRANSMISSION, clock_.Now(),
- true, true);
- }
-
- void SendDataPacket(uint64_t packet_number) {
- SendDataPacket(packet_number, kDefaultLength);
- }
-
- void SendAckPacket(uint64_t packet_number) {
- SerializedPacket packet(QuicPacketNumber(packet_number),
- PACKET_1BYTE_PACKET_NUMBER, nullptr, kDefaultLength,
- true, false);
- unacked_packets_.AddSentPacket(&packet, NOT_RETRANSMISSION, clock_.Now(),
- false, true);
- }
-
- void VerifyLosses(uint64_t largest_newly_acked,
- const AckedPacketVector& packets_acked,
- const std::vector<uint64_t>& losses_expected) {
- return VerifyLosses(largest_newly_acked, packets_acked, losses_expected,
- absl::nullopt, absl::nullopt);
- }
-
- void VerifyLosses(
- uint64_t largest_newly_acked,
- const AckedPacketVector& packets_acked,
- const std::vector<uint64_t>& losses_expected,
- absl::optional<QuicPacketCount> max_sequence_reordering_expected,
- absl::optional<QuicPacketCount>
- num_borderline_time_reorderings_expected) {
- unacked_packets_.MaybeUpdateLargestAckedOfPacketNumberSpace(
- APPLICATION_DATA, QuicPacketNumber(largest_newly_acked));
- LostPacketVector lost_packets;
- LossDetectionInterface::DetectionStats stats = loss_algorithm_.DetectLosses(
- unacked_packets_, clock_.Now(), rtt_stats_,
- QuicPacketNumber(largest_newly_acked), packets_acked, &lost_packets);
- if (max_sequence_reordering_expected.has_value()) {
- EXPECT_EQ(stats.sent_packets_max_sequence_reordering,
- max_sequence_reordering_expected.value());
- }
- if (num_borderline_time_reorderings_expected.has_value()) {
- EXPECT_EQ(stats.sent_packets_num_borderline_time_reorderings,
- num_borderline_time_reorderings_expected.value());
- }
- ASSERT_EQ(losses_expected.size(), lost_packets.size());
- for (size_t i = 0; i < losses_expected.size(); ++i) {
- EXPECT_EQ(lost_packets[i].packet_number,
- QuicPacketNumber(losses_expected[i]));
- }
- }
-
- QuicUnackedPacketMap unacked_packets_;
- GeneralLossAlgorithm loss_algorithm_;
- RttStats rtt_stats_;
- MockClock clock_;
-};
-
-TEST_F(GeneralLossAlgorithmTest, NackRetransmit1Packet) {
- const size_t kNumSentPackets = 5;
- // Transmit 5 packets.
- for (size_t i = 1; i <= kNumSentPackets; ++i) {
- SendDataPacket(i);
- }
- AckedPacketVector packets_acked;
- // No loss on one ack.
- unacked_packets_.RemoveFromInFlight(QuicPacketNumber(2));
- packets_acked.push_back(AckedPacket(
- QuicPacketNumber(2), kMaxOutgoingPacketSize, QuicTime::Zero()));
- VerifyLosses(2, packets_acked, std::vector<uint64_t>{}, 1, 0);
- packets_acked.clear();
- // No loss on two acks.
- unacked_packets_.RemoveFromInFlight(QuicPacketNumber(3));
- packets_acked.push_back(AckedPacket(
- QuicPacketNumber(3), kMaxOutgoingPacketSize, QuicTime::Zero()));
- VerifyLosses(3, packets_acked, std::vector<uint64_t>{}, 2, 0);
- packets_acked.clear();
- // Loss on three acks.
- unacked_packets_.RemoveFromInFlight(QuicPacketNumber(4));
- packets_acked.push_back(AckedPacket(
- QuicPacketNumber(4), kMaxOutgoingPacketSize, QuicTime::Zero()));
- VerifyLosses(4, packets_acked, {1}, 3, 0);
- EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout());
-}
-
-// A stretch ack is an ack that covers more than 1 packet of previously
-// unacknowledged data.
-TEST_F(GeneralLossAlgorithmTest, NackRetransmit1PacketWith1StretchAck) {
- const size_t kNumSentPackets = 10;
- // Transmit 10 packets.
- for (size_t i = 1; i <= kNumSentPackets; ++i) {
- SendDataPacket(i);
- }
- AckedPacketVector packets_acked;
- // Nack the first packet 3 times in a single StretchAck.
- unacked_packets_.RemoveFromInFlight(QuicPacketNumber(2));
- packets_acked.push_back(AckedPacket(
- QuicPacketNumber(2), kMaxOutgoingPacketSize, QuicTime::Zero()));
- unacked_packets_.RemoveFromInFlight(QuicPacketNumber(3));
- packets_acked.push_back(AckedPacket(
- QuicPacketNumber(3), kMaxOutgoingPacketSize, QuicTime::Zero()));
- unacked_packets_.RemoveFromInFlight(QuicPacketNumber(4));
- packets_acked.push_back(AckedPacket(
- QuicPacketNumber(4), kMaxOutgoingPacketSize, QuicTime::Zero()));
- VerifyLosses(4, packets_acked, {1});
- EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout());
-}
-
-// Ack a packet 3 packets ahead, causing a retransmit.
-TEST_F(GeneralLossAlgorithmTest, NackRetransmit1PacketSingleAck) {
- const size_t kNumSentPackets = 10;
- // Transmit 10 packets.
- for (size_t i = 1; i <= kNumSentPackets; ++i) {
- SendDataPacket(i);
- }
- AckedPacketVector packets_acked;
- // Nack the first packet 3 times in an AckFrame with three missing packets.
- unacked_packets_.RemoveFromInFlight(QuicPacketNumber(4));
- packets_acked.push_back(AckedPacket(
- QuicPacketNumber(4), kMaxOutgoingPacketSize, QuicTime::Zero()));
- VerifyLosses(4, packets_acked, {1});
- EXPECT_EQ(clock_.Now() + 1.25 * rtt_stats_.smoothed_rtt(),
- loss_algorithm_.GetLossTimeout());
-}
-
-TEST_F(GeneralLossAlgorithmTest, EarlyRetransmit1Packet) {
- const size_t kNumSentPackets = 2;
- // Transmit 2 packets.
- for (size_t i = 1; i <= kNumSentPackets; ++i) {
- SendDataPacket(i);
- }
- AckedPacketVector packets_acked;
- // Early retransmit when the final packet gets acked and the first is nacked.
- unacked_packets_.RemoveFromInFlight(QuicPacketNumber(2));
- packets_acked.push_back(AckedPacket(
- QuicPacketNumber(2), kMaxOutgoingPacketSize, QuicTime::Zero()));
- VerifyLosses(2, packets_acked, std::vector<uint64_t>{});
- packets_acked.clear();
- EXPECT_EQ(clock_.Now() + 1.25 * rtt_stats_.smoothed_rtt(),
- loss_algorithm_.GetLossTimeout());
-
- clock_.AdvanceTime(1.13 * rtt_stats_.latest_rtt());
- // If reordering_shift increases by one we should have detected a loss.
- VerifyLosses(2, packets_acked, {}, /*max_sequence_reordering_expected=*/1,
- /*num_borderline_time_reorderings_expected=*/1);
-
- clock_.AdvanceTime(0.13 * rtt_stats_.latest_rtt());
- VerifyLosses(2, packets_acked, {1});
- EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout());
-}
-
-TEST_F(GeneralLossAlgorithmTest, EarlyRetransmitAllPackets) {
- const size_t kNumSentPackets = 5;
- for (size_t i = 1; i <= kNumSentPackets; ++i) {
- SendDataPacket(i);
- // Advance the time 1/4 RTT between 3 and 4.
- if (i == 3) {
- clock_.AdvanceTime(0.25 * rtt_stats_.smoothed_rtt());
- }
- }
- AckedPacketVector packets_acked;
- // Early retransmit when the final packet gets acked and 1.25 RTTs have
- // elapsed since the packets were sent.
- unacked_packets_.RemoveFromInFlight(QuicPacketNumber(kNumSentPackets));
- packets_acked.push_back(AckedPacket(QuicPacketNumber(kNumSentPackets),
- kMaxOutgoingPacketSize,
- QuicTime::Zero()));
- // This simulates a single ack following multiple missing packets with FACK.
- VerifyLosses(kNumSentPackets, packets_acked, {1, 2});
- packets_acked.clear();
- // The time has already advanced 1/4 an RTT, so ensure the timeout is set
- // 1.25 RTTs after the earliest pending packet(3), not the last(4).
- EXPECT_EQ(clock_.Now() + rtt_stats_.smoothed_rtt(),
- loss_algorithm_.GetLossTimeout());
-
- clock_.AdvanceTime(rtt_stats_.smoothed_rtt());
- VerifyLosses(kNumSentPackets, packets_acked, {3});
- EXPECT_EQ(clock_.Now() + 0.25 * rtt_stats_.smoothed_rtt(),
- loss_algorithm_.GetLossTimeout());
- clock_.AdvanceTime(0.25 * rtt_stats_.smoothed_rtt());
- VerifyLosses(kNumSentPackets, packets_acked, {4});
- EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout());
-}
-
-TEST_F(GeneralLossAlgorithmTest, DontEarlyRetransmitNeuteredPacket) {
- const size_t kNumSentPackets = 2;
- // Transmit 2 packets.
- for (size_t i = 1; i <= kNumSentPackets; ++i) {
- SendDataPacket(i);
- }
- AckedPacketVector packets_acked;
- // Neuter packet 1.
- unacked_packets_.RemoveRetransmittability(QuicPacketNumber(1));
- clock_.AdvanceTime(rtt_stats_.smoothed_rtt());
-
- // Early retransmit when the final packet gets acked and the first is nacked.
- unacked_packets_.MaybeUpdateLargestAckedOfPacketNumberSpace(
- APPLICATION_DATA, QuicPacketNumber(2));
- unacked_packets_.RemoveFromInFlight(QuicPacketNumber(2));
- packets_acked.push_back(AckedPacket(
- QuicPacketNumber(2), kMaxOutgoingPacketSize, QuicTime::Zero()));
- VerifyLosses(2, packets_acked, std::vector<uint64_t>{});
- EXPECT_EQ(clock_.Now() + 0.25 * rtt_stats_.smoothed_rtt(),
- loss_algorithm_.GetLossTimeout());
-}
-
-TEST_F(GeneralLossAlgorithmTest, EarlyRetransmitWithLargerUnackablePackets) {
- // Transmit 2 data packets and one ack.
- SendDataPacket(1);
- SendDataPacket(2);
- SendAckPacket(3);
- AckedPacketVector packets_acked;
- clock_.AdvanceTime(rtt_stats_.smoothed_rtt());
-
- // Early retransmit when the final packet gets acked and the first is nacked.
- unacked_packets_.MaybeUpdateLargestAckedOfPacketNumberSpace(
- APPLICATION_DATA, QuicPacketNumber(2));
- unacked_packets_.RemoveFromInFlight(QuicPacketNumber(2));
- packets_acked.push_back(AckedPacket(
- QuicPacketNumber(2), kMaxOutgoingPacketSize, QuicTime::Zero()));
- VerifyLosses(2, packets_acked, std::vector<uint64_t>{});
- packets_acked.clear();
- EXPECT_EQ(clock_.Now() + 0.25 * rtt_stats_.smoothed_rtt(),
- loss_algorithm_.GetLossTimeout());
-
- // The packet should be lost once the loss timeout is reached.
- clock_.AdvanceTime(0.25 * rtt_stats_.latest_rtt());
- VerifyLosses(2, packets_acked, {1});
- EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout());
-}
-
-TEST_F(GeneralLossAlgorithmTest, AlwaysLosePacketSent1RTTEarlier) {
- // Transmit 1 packet and then wait an rtt plus 1ms.
- SendDataPacket(1);
- clock_.AdvanceTime(rtt_stats_.smoothed_rtt() +
- QuicTime::Delta::FromMilliseconds(1));
-
- // Transmit 2 packets.
- SendDataPacket(2);
- SendDataPacket(3);
- AckedPacketVector packets_acked;
- // Wait another RTT and ack 2.
- clock_.AdvanceTime(rtt_stats_.smoothed_rtt());
- unacked_packets_.MaybeUpdateLargestAckedOfPacketNumberSpace(
- APPLICATION_DATA, QuicPacketNumber(2));
- unacked_packets_.RemoveFromInFlight(QuicPacketNumber(2));
- packets_acked.push_back(AckedPacket(
- QuicPacketNumber(2), kMaxOutgoingPacketSize, QuicTime::Zero()));
- VerifyLosses(2, packets_acked, {1});
-}
-
-TEST_F(GeneralLossAlgorithmTest, IncreaseTimeThresholdUponSpuriousLoss) {
- loss_algorithm_.enable_adaptive_time_threshold();
- loss_algorithm_.set_reordering_shift(kDefaultLossDelayShift);
- EXPECT_EQ(kDefaultLossDelayShift, loss_algorithm_.reordering_shift());
- EXPECT_TRUE(loss_algorithm_.use_adaptive_time_threshold());
- const size_t kNumSentPackets = 10;
- // Transmit 2 packets at 1/10th an RTT interval.
- for (size_t i = 1; i <= kNumSentPackets; ++i) {
- SendDataPacket(i);
- clock_.AdvanceTime(0.1 * rtt_stats_.smoothed_rtt());
- }
- EXPECT_EQ(QuicTime::Zero() + rtt_stats_.smoothed_rtt(), clock_.Now());
- AckedPacketVector packets_acked;
- // Expect the timer to not be set.
- EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout());
- // Packet 1 should not be lost until 1/4 RTTs pass.
- unacked_packets_.RemoveFromInFlight(QuicPacketNumber(2));
- packets_acked.push_back(AckedPacket(
- QuicPacketNumber(2), kMaxOutgoingPacketSize, QuicTime::Zero()));
- VerifyLosses(2, packets_acked, std::vector<uint64_t>{});
- packets_acked.clear();
- // Expect the timer to be set to 1/4 RTT's in the future.
- EXPECT_EQ(rtt_stats_.smoothed_rtt() * (1.0f / 4),
- loss_algorithm_.GetLossTimeout() - clock_.Now());
- VerifyLosses(2, packets_acked, std::vector<uint64_t>{});
- clock_.AdvanceTime(rtt_stats_.smoothed_rtt() * (1.0f / 4));
- VerifyLosses(2, packets_acked, {1});
- EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout());
- // Retransmit packet 1 as 11 and 2 as 12.
- SendDataPacket(11);
- SendDataPacket(12);
-
- // Advance the time 1/4 RTT and indicate the loss was spurious.
- // The new threshold should be 1/2 RTT.
- clock_.AdvanceTime(rtt_stats_.smoothed_rtt() * (1.0f / 4));
- loss_algorithm_.SpuriousLossDetected(unacked_packets_, rtt_stats_,
- clock_.Now(), QuicPacketNumber(1),
- QuicPacketNumber(2));
- EXPECT_EQ(1, loss_algorithm_.reordering_shift());
-}
-
-TEST_F(GeneralLossAlgorithmTest, IncreaseReorderingThresholdUponSpuriousLoss) {
- loss_algorithm_.set_use_adaptive_reordering_threshold(true);
- for (size_t i = 1; i <= 4; ++i) {
- SendDataPacket(i);
- }
- // Acking 4 causes 1 detected lost.
- AckedPacketVector packets_acked;
- unacked_packets_.RemoveFromInFlight(QuicPacketNumber(4));
- packets_acked.push_back(AckedPacket(
- QuicPacketNumber(4), kMaxOutgoingPacketSize, QuicTime::Zero()));
- VerifyLosses(4, packets_acked, std::vector<uint64_t>{1});
- packets_acked.clear();
-
- // Retransmit 1 as 5.
- SendDataPacket(5);
-
- // Acking 1 such that it was detected lost spuriously.
- unacked_packets_.RemoveFromInFlight(QuicPacketNumber(1));
- packets_acked.push_back(AckedPacket(
- QuicPacketNumber(1), kMaxOutgoingPacketSize, QuicTime::Zero()));
- loss_algorithm_.SpuriousLossDetected(unacked_packets_, rtt_stats_,
- clock_.Now(), QuicPacketNumber(1),
- QuicPacketNumber(4));
- VerifyLosses(4, packets_acked, std::vector<uint64_t>{});
- packets_acked.clear();
-
- // Verify acking 5 does not cause 2 detected lost.
- unacked_packets_.RemoveFromInFlight(QuicPacketNumber(5));
- packets_acked.push_back(AckedPacket(
- QuicPacketNumber(5), kMaxOutgoingPacketSize, QuicTime::Zero()));
- VerifyLosses(5, packets_acked, std::vector<uint64_t>{});
- packets_acked.clear();
-
- SendDataPacket(6);
-
- // Acking 6 will causes 2 detected lost.
- unacked_packets_.RemoveFromInFlight(QuicPacketNumber(6));
- packets_acked.push_back(AckedPacket(
- QuicPacketNumber(6), kMaxOutgoingPacketSize, QuicTime::Zero()));
- VerifyLosses(6, packets_acked, std::vector<uint64_t>{2});
- packets_acked.clear();
-
- // Retransmit 2 as 7.
- SendDataPacket(7);
-
- // Acking 2 such that it was detected lost spuriously.
- unacked_packets_.RemoveFromInFlight(QuicPacketNumber(2));
- packets_acked.push_back(AckedPacket(
- QuicPacketNumber(2), kMaxOutgoingPacketSize, QuicTime::Zero()));
- loss_algorithm_.SpuriousLossDetected(unacked_packets_, rtt_stats_,
- clock_.Now(), QuicPacketNumber(2),
- QuicPacketNumber(6));
- VerifyLosses(6, packets_acked, std::vector<uint64_t>{});
- packets_acked.clear();
-
- // Acking 7 will not cause 3 as detected lost.
- unacked_packets_.RemoveFromInFlight(QuicPacketNumber(7));
- packets_acked.push_back(AckedPacket(
- QuicPacketNumber(7), kMaxOutgoingPacketSize, QuicTime::Zero()));
- VerifyLosses(7, packets_acked, std::vector<uint64_t>{});
- packets_acked.clear();
-}
-
-TEST_F(GeneralLossAlgorithmTest, DefaultIetfLossDetection) {
- loss_algorithm_.set_reordering_shift(kDefaultIetfLossDelayShift);
- for (size_t i = 1; i <= 6; ++i) {
- SendDataPacket(i);
- }
- // Packet threshold loss detection.
- AckedPacketVector packets_acked;
- // No loss on one ack.
- unacked_packets_.RemoveFromInFlight(QuicPacketNumber(2));
- packets_acked.push_back(AckedPacket(
- QuicPacketNumber(2), kMaxOutgoingPacketSize, QuicTime::Zero()));
- VerifyLosses(2, packets_acked, std::vector<uint64_t>{});
- packets_acked.clear();
- // No loss on two acks.
- unacked_packets_.RemoveFromInFlight(QuicPacketNumber(3));
- packets_acked.push_back(AckedPacket(
- QuicPacketNumber(3), kMaxOutgoingPacketSize, QuicTime::Zero()));
- VerifyLosses(3, packets_acked, std::vector<uint64_t>{});
- packets_acked.clear();
- // Loss on three acks.
- unacked_packets_.RemoveFromInFlight(QuicPacketNumber(4));
- packets_acked.push_back(AckedPacket(
- QuicPacketNumber(4), kMaxOutgoingPacketSize, QuicTime::Zero()));
- VerifyLosses(4, packets_acked, {1});
- EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout());
- packets_acked.clear();
-
- SendDataPacket(7);
-
- // Time threshold loss detection.
- unacked_packets_.RemoveFromInFlight(QuicPacketNumber(6));
- packets_acked.push_back(AckedPacket(
- QuicPacketNumber(6), kMaxOutgoingPacketSize, QuicTime::Zero()));
- VerifyLosses(6, packets_acked, std::vector<uint64_t>{});
- packets_acked.clear();
- EXPECT_EQ(clock_.Now() + rtt_stats_.smoothed_rtt() +
- (rtt_stats_.smoothed_rtt() >> 3),
- loss_algorithm_.GetLossTimeout());
- clock_.AdvanceTime(rtt_stats_.smoothed_rtt() +
- (rtt_stats_.smoothed_rtt() >> 3));
- VerifyLosses(6, packets_acked, {5});
- EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout());
-}
-
-TEST_F(GeneralLossAlgorithmTest, IetfLossDetectionWithOneFourthRttDelay) {
- loss_algorithm_.set_reordering_shift(2);
- SendDataPacket(1);
- SendDataPacket(2);
-
- AckedPacketVector packets_acked;
- unacked_packets_.RemoveFromInFlight(QuicPacketNumber(2));
- packets_acked.push_back(AckedPacket(
- QuicPacketNumber(2), kMaxOutgoingPacketSize, QuicTime::Zero()));
- VerifyLosses(2, packets_acked, std::vector<uint64_t>{});
- packets_acked.clear();
- EXPECT_EQ(clock_.Now() + rtt_stats_.smoothed_rtt() +
- (rtt_stats_.smoothed_rtt() >> 2),
- loss_algorithm_.GetLossTimeout());
- clock_.AdvanceTime(rtt_stats_.smoothed_rtt() +
- (rtt_stats_.smoothed_rtt() >> 2));
- VerifyLosses(2, packets_acked, {1});
- EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout());
-}
-
-TEST_F(GeneralLossAlgorithmTest, NoPacketThresholdForRuntPackets) {
- loss_algorithm_.disable_packet_threshold_for_runt_packets();
- for (size_t i = 1; i <= 6; ++i) {
- SendDataPacket(i);
- }
- // Send a small packet.
- SendDataPacket(7, /*encrypted_length=*/kDefaultLength / 2);
- // No packet threshold for runt packet.
- AckedPacketVector packets_acked;
- unacked_packets_.RemoveFromInFlight(QuicPacketNumber(7));
- packets_acked.push_back(AckedPacket(
- QuicPacketNumber(7), kMaxOutgoingPacketSize, QuicTime::Zero()));
- // Verify no packet is detected lost because packet 7 is a runt.
- VerifyLosses(7, packets_acked, std::vector<uint64_t>{});
- EXPECT_EQ(clock_.Now() + rtt_stats_.smoothed_rtt() +
- (rtt_stats_.smoothed_rtt() >> 2),
- loss_algorithm_.GetLossTimeout());
- clock_.AdvanceTime(rtt_stats_.smoothed_rtt() +
- (rtt_stats_.smoothed_rtt() >> 2));
- // Verify packets are declared lost because time threshold has passed.
- VerifyLosses(7, packets_acked, {1, 2, 3, 4, 5, 6});
- EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout());
-}
-
-} // namespace
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/congestion_control/hybrid_slow_start.cc b/chromium/net/third_party/quiche/src/quic/core/congestion_control/hybrid_slow_start.cc
deleted file mode 100644
index 1e567faa8be..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/congestion_control/hybrid_slow_start.cc
+++ /dev/null
@@ -1,104 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/congestion_control/hybrid_slow_start.h"
-
-#include <algorithm>
-
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-// Note(pwestin): the magic clamping numbers come from the original code in
-// tcp_cubic.c.
-const int64_t kHybridStartLowWindow = 16;
-// Number of delay samples for detecting the increase of delay.
-const uint32_t kHybridStartMinSamples = 8;
-// Exit slow start if the min rtt has increased by more than 1/8th.
-const int kHybridStartDelayFactorExp = 3; // 2^3 = 8
-// The original paper specifies 2 and 8ms, but those have changed over time.
-const int64_t kHybridStartDelayMinThresholdUs = 4000;
-const int64_t kHybridStartDelayMaxThresholdUs = 16000;
-
-HybridSlowStart::HybridSlowStart()
- : started_(false),
- hystart_found_(NOT_FOUND),
- rtt_sample_count_(0),
- current_min_rtt_(QuicTime::Delta::Zero()) {}
-
-void HybridSlowStart::OnPacketAcked(QuicPacketNumber acked_packet_number) {
- // OnPacketAcked gets invoked after ShouldExitSlowStart, so it's best to end
- // the round when the final packet of the burst is received and start it on
- // the next incoming ack.
- if (IsEndOfRound(acked_packet_number)) {
- started_ = false;
- }
-}
-
-void HybridSlowStart::OnPacketSent(QuicPacketNumber packet_number) {
- last_sent_packet_number_ = packet_number;
-}
-
-void HybridSlowStart::Restart() {
- started_ = false;
- hystart_found_ = NOT_FOUND;
-}
-
-void HybridSlowStart::StartReceiveRound(QuicPacketNumber last_sent) {
- QUIC_DVLOG(1) << "Reset hybrid slow start @" << last_sent;
- end_packet_number_ = last_sent;
- current_min_rtt_ = QuicTime::Delta::Zero();
- rtt_sample_count_ = 0;
- started_ = true;
-}
-
-bool HybridSlowStart::IsEndOfRound(QuicPacketNumber ack) const {
- return !end_packet_number_.IsInitialized() || end_packet_number_ <= ack;
-}
-
-bool HybridSlowStart::ShouldExitSlowStart(QuicTime::Delta latest_rtt,
- QuicTime::Delta min_rtt,
- QuicPacketCount congestion_window) {
- if (!started_) {
- // Time to start the hybrid slow start.
- StartReceiveRound(last_sent_packet_number_);
- }
- if (hystart_found_ != NOT_FOUND) {
- return true;
- }
- // Second detection parameter - delay increase detection.
- // Compare the minimum delay (current_min_rtt_) of the current
- // burst of packets relative to the minimum delay during the session.
- // Note: we only look at the first few(8) packets in each burst, since we
- // only want to compare the lowest RTT of the burst relative to previous
- // bursts.
- rtt_sample_count_++;
- if (rtt_sample_count_ <= kHybridStartMinSamples) {
- if (current_min_rtt_.IsZero() || current_min_rtt_ > latest_rtt) {
- current_min_rtt_ = latest_rtt;
- }
- }
- // We only need to check this once per round.
- if (rtt_sample_count_ == kHybridStartMinSamples) {
- // Divide min_rtt by 8 to get a rtt increase threshold for exiting.
- int64_t min_rtt_increase_threshold_us =
- min_rtt.ToMicroseconds() >> kHybridStartDelayFactorExp;
- // Ensure the rtt threshold is never less than 2ms or more than 16ms.
- min_rtt_increase_threshold_us = std::min(min_rtt_increase_threshold_us,
- kHybridStartDelayMaxThresholdUs);
- QuicTime::Delta min_rtt_increase_threshold =
- QuicTime::Delta::FromMicroseconds(std::max(
- min_rtt_increase_threshold_us, kHybridStartDelayMinThresholdUs));
-
- if (current_min_rtt_ > min_rtt + min_rtt_increase_threshold) {
- hystart_found_ = DELAY;
- }
- }
- // Exit from slow start if the cwnd is greater than 16 and
- // increasing delay is found.
- return congestion_window >= kHybridStartLowWindow &&
- hystart_found_ != NOT_FOUND;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/congestion_control/hybrid_slow_start.h b/chromium/net/third_party/quiche/src/quic/core/congestion_control/hybrid_slow_start.h
deleted file mode 100644
index bd1292ae9c2..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/congestion_control/hybrid_slow_start.h
+++ /dev/null
@@ -1,83 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// This class is a helper class to TcpCubicSender.
-// Slow start is the initial startup phase of TCP, it lasts until first packet
-// loss. This class implements hybrid slow start of the TCP cubic send side
-// congestion algorithm. The key feaure of hybrid slow start is that it tries to
-// avoid running into the wall too hard during the slow start phase, which
-// the traditional TCP implementation does.
-// This does not implement ack train detection because it interacts poorly with
-// pacing.
-// http://netsrv.csc.ncsu.edu/export/hybridstart_pfldnet08.pdf
-// http://research.csc.ncsu.edu/netsrv/sites/default/files/hystart_techreport_2008.pdf
-
-#ifndef QUICHE_QUIC_CORE_CONGESTION_CONTROL_HYBRID_SLOW_START_H_
-#define QUICHE_QUIC_CORE_CONGESTION_CONTROL_HYBRID_SLOW_START_H_
-
-#include <cstdint>
-
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_time.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-class QUIC_EXPORT_PRIVATE HybridSlowStart {
- public:
- HybridSlowStart();
- HybridSlowStart(const HybridSlowStart&) = delete;
- HybridSlowStart& operator=(const HybridSlowStart&) = delete;
-
- void OnPacketAcked(QuicPacketNumber acked_packet_number);
-
- void OnPacketSent(QuicPacketNumber packet_number);
-
- // ShouldExitSlowStart should be called on every new ack frame, since a new
- // RTT measurement can be made then.
- // rtt: the RTT for this ack packet.
- // min_rtt: is the lowest delay (RTT) we have seen during the session.
- // congestion_window: the congestion window in packets.
- bool ShouldExitSlowStart(QuicTime::Delta rtt,
- QuicTime::Delta min_rtt,
- QuicPacketCount congestion_window);
-
- // Start a new slow start phase.
- void Restart();
-
- // TODO(ianswett): The following methods should be private, but that requires
- // a follow up CL to update the unit test.
- // Returns true if this ack the last packet number of our current slow start
- // round.
- // Call Reset if this returns true.
- bool IsEndOfRound(QuicPacketNumber ack) const;
-
- // Call for the start of each receive round (burst) in the slow start phase.
- void StartReceiveRound(QuicPacketNumber last_sent);
-
- // Whether slow start has started.
- bool started() const { return started_; }
-
- private:
- // Whether a condition for exiting slow start has been found.
- enum HystartState {
- NOT_FOUND,
- DELAY, // Too much increase in the round's min_rtt was observed.
- };
-
- // Whether the hybrid slow start has been started.
- bool started_;
- HystartState hystart_found_;
- // Last packet number sent which was CWND limited.
- QuicPacketNumber last_sent_packet_number_;
-
- // Variables for tracking acks received during a slow start round.
- QuicPacketNumber end_packet_number_; // End of the receive round.
- uint32_t rtt_sample_count_; // Number of rtt samples in the current round.
- QuicTime::Delta current_min_rtt_; // The minimum rtt of current round.
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_CONGESTION_CONTROL_HYBRID_SLOW_START_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/congestion_control/hybrid_slow_start_test.cc b/chromium/net/third_party/quiche/src/quic/core/congestion_control/hybrid_slow_start_test.cc
deleted file mode 100644
index caa07812e48..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/congestion_control/hybrid_slow_start_test.cc
+++ /dev/null
@@ -1,76 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/congestion_control/hybrid_slow_start.h"
-
-#include <memory>
-#include <utility>
-
-#include "quic/platform/api/quic_test.h"
-
-namespace quic {
-namespace test {
-
-class HybridSlowStartTest : public QuicTest {
- protected:
- HybridSlowStartTest()
- : one_ms_(QuicTime::Delta::FromMilliseconds(1)),
- rtt_(QuicTime::Delta::FromMilliseconds(60)) {}
- void SetUp() override { slow_start_ = std::make_unique<HybridSlowStart>(); }
- const QuicTime::Delta one_ms_;
- const QuicTime::Delta rtt_;
- std::unique_ptr<HybridSlowStart> slow_start_;
-};
-
-TEST_F(HybridSlowStartTest, Simple) {
- QuicPacketNumber packet_number(1);
- QuicPacketNumber end_packet_number(3);
- slow_start_->StartReceiveRound(end_packet_number);
-
- EXPECT_FALSE(slow_start_->IsEndOfRound(packet_number++));
-
- // Test duplicates.
- EXPECT_FALSE(slow_start_->IsEndOfRound(packet_number));
-
- EXPECT_FALSE(slow_start_->IsEndOfRound(packet_number++));
- EXPECT_TRUE(slow_start_->IsEndOfRound(packet_number++));
-
- // Test without a new registered end_packet_number;
- EXPECT_TRUE(slow_start_->IsEndOfRound(packet_number++));
-
- end_packet_number = QuicPacketNumber(20);
- slow_start_->StartReceiveRound(end_packet_number);
- while (packet_number < end_packet_number) {
- EXPECT_FALSE(slow_start_->IsEndOfRound(packet_number++));
- }
- EXPECT_TRUE(slow_start_->IsEndOfRound(packet_number++));
-}
-
-TEST_F(HybridSlowStartTest, Delay) {
- // We expect to detect the increase at +1/8 of the RTT; hence at a typical
- // RTT of 60ms the detection will happen at 67.5 ms.
- const int kHybridStartMinSamples = 8; // Number of acks required to trigger.
-
- QuicPacketNumber end_packet_number(1);
- slow_start_->StartReceiveRound(end_packet_number++);
-
- // Will not trigger since our lowest RTT in our burst is the same as the long
- // term RTT provided.
- for (int n = 0; n < kHybridStartMinSamples; ++n) {
- EXPECT_FALSE(slow_start_->ShouldExitSlowStart(
- rtt_ + QuicTime::Delta::FromMilliseconds(n), rtt_, 100));
- }
- slow_start_->StartReceiveRound(end_packet_number++);
- for (int n = 1; n < kHybridStartMinSamples; ++n) {
- EXPECT_FALSE(slow_start_->ShouldExitSlowStart(
- rtt_ + QuicTime::Delta::FromMilliseconds(n + 10), rtt_, 100));
- }
- // Expect to trigger since all packets in this burst was above the long term
- // RTT provided.
- EXPECT_TRUE(slow_start_->ShouldExitSlowStart(
- rtt_ + QuicTime::Delta::FromMilliseconds(10), rtt_, 100));
-}
-
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/congestion_control/loss_detection_interface.h b/chromium/net/third_party/quiche/src/quic/core/congestion_control/loss_detection_interface.h
deleted file mode 100644
index 77c8913e6aa..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/congestion_control/loss_detection_interface.h
+++ /dev/null
@@ -1,75 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// The pure virtual class for send side loss detection algorithm.
-
-#ifndef QUICHE_QUIC_CORE_CONGESTION_CONTROL_LOSS_DETECTION_INTERFACE_H_
-#define QUICHE_QUIC_CORE_CONGESTION_CONTROL_LOSS_DETECTION_INTERFACE_H_
-
-#include "quic/core/congestion_control/send_algorithm_interface.h"
-#include "quic/core/quic_config.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_time.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-class QuicUnackedPacketMap;
-class RttStats;
-
-class QUIC_EXPORT_PRIVATE LossDetectionInterface {
- public:
- virtual ~LossDetectionInterface() {}
-
- virtual void SetFromConfig(const QuicConfig& config,
- Perspective perspective) = 0;
-
- struct QUIC_NO_EXPORT DetectionStats {
- // Maximum sequence reordering observed in newly acked packets.
- QuicPacketCount sent_packets_max_sequence_reordering = 0;
- QuicPacketCount sent_packets_num_borderline_time_reorderings = 0;
- // Total detection response time for lost packets from this detection.
- // See QuicConnectionStats for the definition of detection response time.
- float total_loss_detection_response_time = 0.0;
- };
-
- // Called when a new ack arrives or the loss alarm fires.
- virtual DetectionStats DetectLosses(
- const QuicUnackedPacketMap& unacked_packets,
- QuicTime time,
- const RttStats& rtt_stats,
- QuicPacketNumber largest_newly_acked,
- const AckedPacketVector& packets_acked,
- LostPacketVector* packets_lost) = 0;
-
- // Get the time the LossDetectionAlgorithm wants to re-evaluate losses.
- // Returns QuicTime::Zero if no alarm needs to be set.
- virtual QuicTime GetLossTimeout() const = 0;
-
- // Called when |packet_number| was detected lost but gets acked later.
- virtual void SpuriousLossDetected(
- const QuicUnackedPacketMap& unacked_packets,
- const RttStats& rtt_stats,
- QuicTime ack_receive_time,
- QuicPacketNumber packet_number,
- QuicPacketNumber previous_largest_acked) = 0;
-
- virtual void OnConfigNegotiated() = 0;
-
- virtual void OnMinRttAvailable() = 0;
-
- virtual void OnUserAgentIdKnown() = 0;
-
- virtual void OnConnectionClosed() = 0;
-
- // Called when a reordering is detected by the loss algorithm, but _before_
- // the reordering_shift and reordering_threshold are consulted to see whether
- // it is a loss.
- virtual void OnReorderingDetected() = 0;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_CONGESTION_CONTROL_LOSS_DETECTION_INTERFACE_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/congestion_control/pacing_sender.cc b/chromium/net/third_party/quiche/src/quic/core/congestion_control/pacing_sender.cc
deleted file mode 100644
index e4b6534e6fc..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/congestion_control/pacing_sender.cc
+++ /dev/null
@@ -1,177 +0,0 @@
-// Copyright (c) 2013 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 "quic/core/congestion_control/pacing_sender.h"
-
-#include "quic/core/quic_bandwidth.h"
-#include "quic/platform/api/quic_flag_utils.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-namespace {
-
-// Configured maximum size of the burst coming out of quiescence. The burst
-// is never larger than the current CWND in packets.
-static const uint32_t kInitialUnpacedBurst = 10;
-
-} // namespace
-
-PacingSender::PacingSender()
- : sender_(nullptr),
- max_pacing_rate_(QuicBandwidth::Zero()),
- burst_tokens_(kInitialUnpacedBurst),
- ideal_next_packet_send_time_(QuicTime::Zero()),
- initial_burst_size_(kInitialUnpacedBurst),
- lumpy_tokens_(0),
- alarm_granularity_(kAlarmGranularity),
- pacing_limited_(false) {
- if (GetQuicReloadableFlag(quic_donot_reset_ideal_next_packet_send_time)) {
- QUIC_RELOADABLE_FLAG_COUNT(quic_donot_reset_ideal_next_packet_send_time);
- }
-}
-
-PacingSender::~PacingSender() {}
-
-void PacingSender::set_sender(SendAlgorithmInterface* sender) {
- QUICHE_DCHECK(sender != nullptr);
- sender_ = sender;
-}
-
-void PacingSender::OnCongestionEvent(bool rtt_updated,
- QuicByteCount bytes_in_flight,
- QuicTime event_time,
- const AckedPacketVector& acked_packets,
- const LostPacketVector& lost_packets) {
- QUICHE_DCHECK(sender_ != nullptr);
- if (!lost_packets.empty()) {
- // Clear any burst tokens when entering recovery.
- burst_tokens_ = 0;
- }
- sender_->OnCongestionEvent(rtt_updated, bytes_in_flight, event_time,
- acked_packets, lost_packets);
-}
-
-void PacingSender::OnPacketSent(
- QuicTime sent_time,
- QuicByteCount bytes_in_flight,
- QuicPacketNumber packet_number,
- QuicByteCount bytes,
- HasRetransmittableData has_retransmittable_data) {
- QUICHE_DCHECK(sender_ != nullptr);
- sender_->OnPacketSent(sent_time, bytes_in_flight, packet_number, bytes,
- has_retransmittable_data);
- if (has_retransmittable_data != HAS_RETRANSMITTABLE_DATA) {
- return;
- }
- // If in recovery, the connection is not coming out of quiescence.
- if (bytes_in_flight == 0 && !sender_->InRecovery()) {
- // Add more burst tokens anytime the connection is leaving quiescence, but
- // limit it to the equivalent of a single bulk write, not exceeding the
- // current CWND in packets.
- burst_tokens_ = std::min(
- initial_burst_size_,
- static_cast<uint32_t>(sender_->GetCongestionWindow() / kDefaultTCPMSS));
- }
- if (burst_tokens_ > 0) {
- --burst_tokens_;
- if (!GetQuicReloadableFlag(quic_donot_reset_ideal_next_packet_send_time)) {
- ideal_next_packet_send_time_ = QuicTime::Zero();
- }
- pacing_limited_ = false;
- return;
- }
- // The next packet should be sent as soon as the current packet has been
- // transferred. PacingRate is based on bytes in flight including this packet.
- QuicTime::Delta delay =
- PacingRate(bytes_in_flight + bytes).TransferTime(bytes);
- if (!pacing_limited_ || lumpy_tokens_ == 0) {
- // Reset lumpy_tokens_ if either application or cwnd throttles sending or
- // token runs out.
- lumpy_tokens_ = std::max(
- 1u, std::min(static_cast<uint32_t>(
- GetQuicFlag(FLAGS_quic_lumpy_pacing_size)),
- static_cast<uint32_t>(
- (sender_->GetCongestionWindow() *
- GetQuicFlag(FLAGS_quic_lumpy_pacing_cwnd_fraction)) /
- kDefaultTCPMSS)));
- if (sender_->BandwidthEstimate() <
- QuicBandwidth::FromKBitsPerSecond(
- GetQuicFlag(FLAGS_quic_lumpy_pacing_min_bandwidth_kbps))) {
- // Below 1.2Mbps, send 1 packet at once, because one full-sized packet
- // is about 10ms of queueing.
- lumpy_tokens_ = 1u;
- }
- if (GetQuicReloadableFlag(quic_fix_pacing_sender_bursts) &&
- (bytes_in_flight + bytes) >= sender_->GetCongestionWindow()) {
- QUIC_RELOADABLE_FLAG_COUNT(quic_fix_pacing_sender_bursts);
- // Don't add lumpy_tokens if the congestion controller is CWND limited.
- lumpy_tokens_ = 1u;
- }
- }
- --lumpy_tokens_;
- if (pacing_limited_) {
- // Make up for lost time since pacing throttles the sending.
- ideal_next_packet_send_time_ = ideal_next_packet_send_time_ + delay;
- } else {
- ideal_next_packet_send_time_ =
- std::max(ideal_next_packet_send_time_ + delay, sent_time + delay);
- }
- // Stop making up for lost time if underlying sender prevents sending.
- pacing_limited_ = sender_->CanSend(bytes_in_flight + bytes);
-}
-
-void PacingSender::OnApplicationLimited() {
- // The send is application limited, stop making up for lost time.
- pacing_limited_ = false;
-}
-
-void PacingSender::SetBurstTokens(uint32_t burst_tokens) {
- initial_burst_size_ = burst_tokens;
- burst_tokens_ = std::min(
- initial_burst_size_,
- static_cast<uint32_t>(sender_->GetCongestionWindow() / kDefaultTCPMSS));
-}
-
-QuicTime::Delta PacingSender::TimeUntilSend(
- QuicTime now,
- QuicByteCount bytes_in_flight) const {
- QUICHE_DCHECK(sender_ != nullptr);
-
- if (!sender_->CanSend(bytes_in_flight)) {
- // The underlying sender prevents sending.
- return QuicTime::Delta::Infinite();
- }
-
- if (burst_tokens_ > 0 || bytes_in_flight == 0 || lumpy_tokens_ > 0) {
- // Don't pace if we have burst tokens available or leaving quiescence.
- QUIC_DVLOG(1) << "Sending packet now. burst_tokens:" << burst_tokens_
- << ", bytes_in_flight:" << bytes_in_flight
- << ", lumpy_tokens:" << lumpy_tokens_;
- return QuicTime::Delta::Zero();
- }
-
- // If the next send time is within the alarm granularity, send immediately.
- if (ideal_next_packet_send_time_ > now + alarm_granularity_) {
- QUIC_DVLOG(1) << "Delaying packet: "
- << (ideal_next_packet_send_time_ - now).ToMicroseconds();
- return ideal_next_packet_send_time_ - now;
- }
-
- QUIC_DVLOG(1) << "Sending packet now. ideal_next_packet_send_time: "
- << ideal_next_packet_send_time_ << ", now: " << now;
- return QuicTime::Delta::Zero();
-}
-
-QuicBandwidth PacingSender::PacingRate(QuicByteCount bytes_in_flight) const {
- QUICHE_DCHECK(sender_ != nullptr);
- if (!max_pacing_rate_.IsZero()) {
- return QuicBandwidth::FromBitsPerSecond(
- std::min(max_pacing_rate_.ToBitsPerSecond(),
- sender_->PacingRate(bytes_in_flight).ToBitsPerSecond()));
- }
- return sender_->PacingRate(bytes_in_flight);
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/congestion_control/pacing_sender.h b/chromium/net/third_party/quiche/src/quic/core/congestion_control/pacing_sender.h
deleted file mode 100644
index b2401a2b6c7..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/congestion_control/pacing_sender.h
+++ /dev/null
@@ -1,116 +0,0 @@
-// Copyright (c) 2013 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.
-
-// A send algorithm that adds pacing on top of an another send algorithm.
-// It uses the underlying sender's pacing rate to schedule packets.
-// It also takes into consideration the expected granularity of the underlying
-// alarm to ensure that alarms are not set too aggressively, and err towards
-// sending packets too early instead of too late.
-
-#ifndef QUICHE_QUIC_CORE_CONGESTION_CONTROL_PACING_SENDER_H_
-#define QUICHE_QUIC_CORE_CONGESTION_CONTROL_PACING_SENDER_H_
-
-#include <cstdint>
-#include <map>
-#include <memory>
-
-#include "quic/core/congestion_control/send_algorithm_interface.h"
-#include "quic/core/quic_bandwidth.h"
-#include "quic/core/quic_config.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_time.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-namespace test {
-class QuicSentPacketManagerPeer;
-} // namespace test
-
-class QUIC_EXPORT_PRIVATE PacingSender {
- public:
- PacingSender();
- PacingSender(const PacingSender&) = delete;
- PacingSender& operator=(const PacingSender&) = delete;
- ~PacingSender();
-
- // Sets the underlying sender. Does not take ownership of |sender|. |sender|
- // must not be null. This must be called before any of the
- // SendAlgorithmInterface wrapper methods are called.
- void set_sender(SendAlgorithmInterface* sender);
-
- void set_max_pacing_rate(QuicBandwidth max_pacing_rate) {
- max_pacing_rate_ = max_pacing_rate;
- }
-
- void set_alarm_granularity(QuicTime::Delta alarm_granularity) {
- alarm_granularity_ = alarm_granularity;
- }
-
- QuicBandwidth max_pacing_rate() const { return max_pacing_rate_; }
-
- void OnCongestionEvent(bool rtt_updated,
- QuicByteCount bytes_in_flight,
- QuicTime event_time,
- const AckedPacketVector& acked_packets,
- const LostPacketVector& lost_packets);
-
- void OnPacketSent(QuicTime sent_time,
- QuicByteCount bytes_in_flight,
- QuicPacketNumber packet_number,
- QuicByteCount bytes,
- HasRetransmittableData has_retransmittable_data);
-
- // Called when application throttles the sending, so that pacing sender stops
- // making up for lost time.
- void OnApplicationLimited();
-
- // Set burst_tokens_ and initial_burst_size_.
- void SetBurstTokens(uint32_t burst_tokens);
-
- QuicTime::Delta TimeUntilSend(QuicTime now,
- QuicByteCount bytes_in_flight) const;
-
- QuicBandwidth PacingRate(QuicByteCount bytes_in_flight) const;
-
- NextReleaseTimeResult GetNextReleaseTime() const {
- bool allow_burst = (burst_tokens_ > 0 || lumpy_tokens_ > 0);
- return {ideal_next_packet_send_time_, allow_burst};
- }
-
- uint32_t initial_burst_size() const { return initial_burst_size_; }
-
- protected:
- uint32_t lumpy_tokens() const { return lumpy_tokens_; }
-
- private:
- friend class test::QuicSentPacketManagerPeer;
-
- // Underlying sender. Not owned.
- SendAlgorithmInterface* sender_;
- // If not QuicBandidth::Zero, the maximum rate the PacingSender will use.
- QuicBandwidth max_pacing_rate_;
-
- // Number of unpaced packets to be sent before packets are delayed.
- uint32_t burst_tokens_;
- QuicTime ideal_next_packet_send_time_; // When can the next packet be sent.
- uint32_t initial_burst_size_;
-
- // Number of unpaced packets to be sent before packets are delayed. This token
- // is consumed after burst_tokens_ ran out.
- uint32_t lumpy_tokens_;
-
- // If the next send time is within alarm_granularity_, send immediately.
- // TODO(fayang): Remove alarm_granularity_ when deprecating
- // quic_offload_pacing_to_usps2 flag.
- QuicTime::Delta alarm_granularity_;
-
- // Indicates whether pacing throttles the sending. If true, make up for lost
- // time.
- bool pacing_limited_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_CONGESTION_CONTROL_PACING_SENDER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/congestion_control/pacing_sender_test.cc b/chromium/net/third_party/quiche/src/quic/core/congestion_control/pacing_sender_test.cc
deleted file mode 100644
index ec3119d2407..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/congestion_control/pacing_sender_test.cc
+++ /dev/null
@@ -1,597 +0,0 @@
-// Copyright (c) 2013 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 "quic/core/congestion_control/pacing_sender.h"
-
-#include <memory>
-#include <utility>
-
-#include "quic/core/quic_constants.h"
-#include "quic/core/quic_packets.h"
-#include "quic/platform/api/quic_flag_utils.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/mock_clock.h"
-#include "quic/test_tools/quic_test_utils.h"
-
-using testing::_;
-using testing::AtMost;
-using testing::IsEmpty;
-using testing::Return;
-using testing::StrictMock;
-
-namespace quic {
-namespace test {
-
-const QuicByteCount kBytesInFlight = 1024;
-const int kInitialBurstPackets = 10;
-
-class TestPacingSender : public PacingSender {
- public:
- using PacingSender::lumpy_tokens;
- using PacingSender::PacingSender;
-
- QuicTime ideal_next_packet_send_time() const {
- return GetNextReleaseTime().release_time;
- }
-};
-
-class PacingSenderTest : public QuicTest {
- protected:
- PacingSenderTest()
- : zero_time_(QuicTime::Delta::Zero()),
- infinite_time_(QuicTime::Delta::Infinite()),
- packet_number_(1),
- mock_sender_(new StrictMock<MockSendAlgorithm>()),
- pacing_sender_(new TestPacingSender) {
- pacing_sender_->set_sender(mock_sender_.get());
- // Pick arbitrary time.
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(9));
- }
-
- ~PacingSenderTest() override {}
-
- void InitPacingRate(QuicPacketCount burst_size, QuicBandwidth bandwidth) {
- mock_sender_ = std::make_unique<StrictMock<MockSendAlgorithm>>();
- pacing_sender_ = std::make_unique<TestPacingSender>();
- pacing_sender_->set_sender(mock_sender_.get());
- EXPECT_CALL(*mock_sender_, PacingRate(_)).WillRepeatedly(Return(bandwidth));
- EXPECT_CALL(*mock_sender_, BandwidthEstimate())
- .WillRepeatedly(Return(bandwidth));
- if (burst_size == 0) {
- EXPECT_CALL(*mock_sender_, OnCongestionEvent(_, _, _, _, _));
- LostPacketVector lost_packets;
- lost_packets.push_back(
- LostPacket(QuicPacketNumber(1), kMaxOutgoingPacketSize));
- AckedPacketVector empty;
- pacing_sender_->OnCongestionEvent(true, 1234, clock_.Now(), empty,
- lost_packets);
- } else if (burst_size != kInitialBurstPackets) {
- QUIC_LOG(FATAL) << "Unsupported burst_size " << burst_size
- << " specificied, only 0 and " << kInitialBurstPackets
- << " are supported.";
- }
- }
-
- void CheckPacketIsSentImmediately(HasRetransmittableData retransmittable_data,
- QuicByteCount prior_in_flight,
- bool in_recovery,
- QuicPacketCount cwnd) {
- // In order for the packet to be sendable, the underlying sender must
- // permit it to be sent immediately.
- for (int i = 0; i < 2; ++i) {
- EXPECT_CALL(*mock_sender_, CanSend(prior_in_flight))
- .WillOnce(Return(true));
- // Verify that the packet can be sent immediately.
- EXPECT_EQ(zero_time_,
- pacing_sender_->TimeUntilSend(clock_.Now(), prior_in_flight));
- }
-
- // Actually send the packet.
- if (prior_in_flight == 0) {
- EXPECT_CALL(*mock_sender_, InRecovery()).WillOnce(Return(in_recovery));
- }
- EXPECT_CALL(*mock_sender_,
- OnPacketSent(clock_.Now(), prior_in_flight, packet_number_,
- kMaxOutgoingPacketSize, retransmittable_data));
- EXPECT_CALL(*mock_sender_, GetCongestionWindow())
- .WillRepeatedly(Return(cwnd * kDefaultTCPMSS));
- EXPECT_CALL(*mock_sender_,
- CanSend(prior_in_flight + kMaxOutgoingPacketSize))
- .Times(AtMost(1))
- .WillRepeatedly(Return((prior_in_flight + kMaxOutgoingPacketSize) <
- (cwnd * kDefaultTCPMSS)));
- pacing_sender_->OnPacketSent(clock_.Now(), prior_in_flight,
- packet_number_++, kMaxOutgoingPacketSize,
- retransmittable_data);
- }
-
- void CheckPacketIsSentImmediately() {
- CheckPacketIsSentImmediately(HAS_RETRANSMITTABLE_DATA, kBytesInFlight,
- false, 10);
- }
-
- void CheckPacketIsDelayed(QuicTime::Delta delay) {
- // In order for the packet to be sendable, the underlying sender must
- // permit it to be sent immediately.
- for (int i = 0; i < 2; ++i) {
- EXPECT_CALL(*mock_sender_, CanSend(kBytesInFlight))
- .WillOnce(Return(true));
- // Verify that the packet is delayed.
- EXPECT_EQ(delay.ToMicroseconds(),
- pacing_sender_->TimeUntilSend(clock_.Now(), kBytesInFlight)
- .ToMicroseconds());
- }
- }
-
- void UpdateRtt() {
- EXPECT_CALL(*mock_sender_,
- OnCongestionEvent(true, kBytesInFlight, _, _, _));
- AckedPacketVector empty_acked;
- LostPacketVector empty_lost;
- pacing_sender_->OnCongestionEvent(true, kBytesInFlight, clock_.Now(),
- empty_acked, empty_lost);
- }
-
- void OnApplicationLimited() { pacing_sender_->OnApplicationLimited(); }
-
- const QuicTime::Delta zero_time_;
- const QuicTime::Delta infinite_time_;
- MockClock clock_;
- QuicPacketNumber packet_number_;
- std::unique_ptr<StrictMock<MockSendAlgorithm>> mock_sender_;
- std::unique_ptr<TestPacingSender> pacing_sender_;
-};
-
-TEST_F(PacingSenderTest, NoSend) {
- for (int i = 0; i < 2; ++i) {
- EXPECT_CALL(*mock_sender_, CanSend(kBytesInFlight)).WillOnce(Return(false));
- EXPECT_EQ(infinite_time_,
- pacing_sender_->TimeUntilSend(clock_.Now(), kBytesInFlight));
- }
-}
-
-TEST_F(PacingSenderTest, SendNow) {
- for (int i = 0; i < 2; ++i) {
- EXPECT_CALL(*mock_sender_, CanSend(kBytesInFlight)).WillOnce(Return(true));
- EXPECT_EQ(zero_time_,
- pacing_sender_->TimeUntilSend(clock_.Now(), kBytesInFlight));
- }
-}
-
-TEST_F(PacingSenderTest, VariousSending) {
- // Configure pacing rate of 1 packet per 1 ms, no initial burst.
- InitPacingRate(
- 0, QuicBandwidth::FromBytesAndTimeDelta(
- kMaxOutgoingPacketSize, QuicTime::Delta::FromMilliseconds(1)));
-
- // Now update the RTT and verify that packets are actually paced.
- UpdateRtt();
-
- CheckPacketIsSentImmediately();
- CheckPacketIsSentImmediately();
-
- // The first packet was a "make up", then we sent two packets "into the
- // future", so the delay should be 2.
- CheckPacketIsDelayed(QuicTime::Delta::FromMilliseconds(2));
-
- // Wake up on time.
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(2));
- CheckPacketIsSentImmediately();
- CheckPacketIsSentImmediately();
- CheckPacketIsDelayed(QuicTime::Delta::FromMilliseconds(2));
-
- // Wake up late.
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(4));
- CheckPacketIsSentImmediately();
- CheckPacketIsSentImmediately();
- CheckPacketIsSentImmediately();
- CheckPacketIsSentImmediately();
- CheckPacketIsDelayed(QuicTime::Delta::FromMilliseconds(2));
-
- // Wake up really late.
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(8));
- CheckPacketIsSentImmediately();
- CheckPacketIsSentImmediately();
- CheckPacketIsSentImmediately();
- CheckPacketIsSentImmediately();
- CheckPacketIsSentImmediately();
- CheckPacketIsSentImmediately();
- CheckPacketIsSentImmediately();
- CheckPacketIsSentImmediately();
- CheckPacketIsDelayed(QuicTime::Delta::FromMilliseconds(2));
-
- // Wake up really late again, but application pause partway through.
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(8));
- CheckPacketIsSentImmediately();
- CheckPacketIsSentImmediately();
- OnApplicationLimited();
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(100));
- CheckPacketIsSentImmediately();
- CheckPacketIsSentImmediately();
- CheckPacketIsDelayed(QuicTime::Delta::FromMilliseconds(2));
- // Wake up early, but after enough time has passed to permit a send.
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(1));
- CheckPacketIsSentImmediately();
-}
-
-TEST_F(PacingSenderTest, InitialBurst) {
- // Configure pacing rate of 1 packet per 1 ms.
- InitPacingRate(
- 10, QuicBandwidth::FromBytesAndTimeDelta(
- kMaxOutgoingPacketSize, QuicTime::Delta::FromMilliseconds(1)));
-
- // Update the RTT and verify that the first 10 packets aren't paced.
- UpdateRtt();
-
- // Send 10 packets, and verify that they are not paced.
- for (int i = 0; i < kInitialBurstPackets; ++i) {
- CheckPacketIsSentImmediately();
- }
-
- // The first packet was a "make up", then we sent two packets "into the
- // future", so the delay should be 2ms.
- CheckPacketIsSentImmediately();
- CheckPacketIsSentImmediately();
- CheckPacketIsDelayed(QuicTime::Delta::FromMilliseconds(2));
-
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
- CheckPacketIsSentImmediately();
-
- // Next time TimeUntilSend is called with no bytes in flight, pacing should
- // allow a packet to be sent, and when it's sent, the tokens are refilled.
- CheckPacketIsSentImmediately(HAS_RETRANSMITTABLE_DATA, 0, false, 10);
- for (int i = 0; i < kInitialBurstPackets - 1; ++i) {
- CheckPacketIsSentImmediately();
- }
-
- // The first packet was a "make up", then we sent two packets "into the
- // future", so the delay should be 2ms.
- CheckPacketIsSentImmediately();
- CheckPacketIsSentImmediately();
- CheckPacketIsDelayed(QuicTime::Delta::FromMilliseconds(2));
-}
-
-TEST_F(PacingSenderTest, InitialBurstNoRttMeasurement) {
- // Configure pacing rate of 1 packet per 1 ms.
- InitPacingRate(
- 10, QuicBandwidth::FromBytesAndTimeDelta(
- kMaxOutgoingPacketSize, QuicTime::Delta::FromMilliseconds(1)));
-
- // Send 10 packets, and verify that they are not paced.
- for (int i = 0; i < kInitialBurstPackets; ++i) {
- CheckPacketIsSentImmediately();
- }
-
- // The first packet was a "make up", then we sent two packets "into the
- // future", so the delay should be 2ms.
- CheckPacketIsSentImmediately();
- CheckPacketIsSentImmediately();
- CheckPacketIsDelayed(QuicTime::Delta::FromMilliseconds(2));
-
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
- CheckPacketIsSentImmediately();
-
- // Next time TimeUntilSend is called with no bytes in flight, the tokens
- // should be refilled and there should be no delay.
- CheckPacketIsSentImmediately(HAS_RETRANSMITTABLE_DATA, 0, false, 10);
- // Send 10 packets, and verify that they are not paced.
- for (int i = 0; i < kInitialBurstPackets - 1; ++i) {
- CheckPacketIsSentImmediately();
- }
-
- // The first packet was a "make up", then we sent two packets "into the
- // future", so the delay should be 2ms.
- CheckPacketIsSentImmediately();
- CheckPacketIsSentImmediately();
- CheckPacketIsDelayed(QuicTime::Delta::FromMilliseconds(2));
-}
-
-TEST_F(PacingSenderTest, FastSending) {
- // Ensure the pacing sender paces, even when the inter-packet spacing(0.5ms)
- // is less than the pacing granularity(1ms).
- InitPacingRate(10, QuicBandwidth::FromBytesAndTimeDelta(
- 2 * kMaxOutgoingPacketSize,
- QuicTime::Delta::FromMilliseconds(1)));
- // Update the RTT and verify that the first 10 packets aren't paced.
- UpdateRtt();
-
- // Send 10 packets, and verify that they are not paced.
- for (int i = 0; i < kInitialBurstPackets; ++i) {
- CheckPacketIsSentImmediately();
- }
-
- CheckPacketIsSentImmediately(); // Make up
- CheckPacketIsSentImmediately(); // Lumpy token
- CheckPacketIsSentImmediately(); // "In the future" but within granularity.
- CheckPacketIsSentImmediately(); // Lumpy token
- CheckPacketIsDelayed(QuicTime::Delta::FromMicroseconds(2000));
-
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
- CheckPacketIsSentImmediately();
-
- // Next time TimeUntilSend is called with no bytes in flight, the tokens
- // should be refilled and there should be no delay.
- CheckPacketIsSentImmediately(HAS_RETRANSMITTABLE_DATA, 0, false, 10);
- for (int i = 0; i < kInitialBurstPackets - 1; ++i) {
- CheckPacketIsSentImmediately();
- }
-
- // The first packet was a "make up", then we sent two packets "into the
- // future", so the delay should be 1.5ms.
- CheckPacketIsSentImmediately(); // Make up
- CheckPacketIsSentImmediately(); // Lumpy token
- CheckPacketIsSentImmediately(); // "In the future" but within granularity.
- CheckPacketIsSentImmediately(); // Lumpy token
- CheckPacketIsDelayed(QuicTime::Delta::FromMicroseconds(2000));
-}
-
-TEST_F(PacingSenderTest, NoBurstEnteringRecovery) {
- // Configure pacing rate of 1 packet per 1 ms with no burst tokens.
- InitPacingRate(
- 0, QuicBandwidth::FromBytesAndTimeDelta(
- kMaxOutgoingPacketSize, QuicTime::Delta::FromMilliseconds(1)));
- // Sending a packet will set burst tokens.
- CheckPacketIsSentImmediately();
-
- // Losing a packet will set clear burst tokens.
- LostPacketVector lost_packets;
- lost_packets.push_back(
- LostPacket(QuicPacketNumber(1), kMaxOutgoingPacketSize));
- AckedPacketVector empty_acked;
- EXPECT_CALL(*mock_sender_,
- OnCongestionEvent(true, kMaxOutgoingPacketSize, _, IsEmpty(), _));
- pacing_sender_->OnCongestionEvent(true, kMaxOutgoingPacketSize, clock_.Now(),
- empty_acked, lost_packets);
- // One packet is sent immediately, because of 1ms pacing granularity.
- CheckPacketIsSentImmediately();
- // Ensure packets are immediately paced.
- EXPECT_CALL(*mock_sender_, CanSend(kMaxOutgoingPacketSize))
- .WillOnce(Return(true));
- // Verify the next packet is paced and delayed 2ms due to granularity.
- EXPECT_EQ(
- QuicTime::Delta::FromMilliseconds(2),
- pacing_sender_->TimeUntilSend(clock_.Now(), kMaxOutgoingPacketSize));
- CheckPacketIsDelayed(QuicTime::Delta::FromMilliseconds(2));
-}
-
-TEST_F(PacingSenderTest, NoBurstInRecovery) {
- // Configure pacing rate of 1 packet per 1 ms with no burst tokens.
- InitPacingRate(
- 0, QuicBandwidth::FromBytesAndTimeDelta(
- kMaxOutgoingPacketSize, QuicTime::Delta::FromMilliseconds(1)));
-
- UpdateRtt();
-
- // Ensure only one packet is sent immediately and the rest are paced.
- CheckPacketIsSentImmediately(HAS_RETRANSMITTABLE_DATA, 0, true, 10);
- CheckPacketIsSentImmediately();
- CheckPacketIsDelayed(QuicTime::Delta::FromMilliseconds(2));
-}
-
-TEST_F(PacingSenderTest, CwndLimited) {
- // Configure pacing rate of 1 packet per 1 ms, no initial burst.
- InitPacingRate(
- 0, QuicBandwidth::FromBytesAndTimeDelta(
- kMaxOutgoingPacketSize, QuicTime::Delta::FromMilliseconds(1)));
-
- UpdateRtt();
-
- CheckPacketIsSentImmediately();
- CheckPacketIsSentImmediately();
- // Packet 3 will be delayed 2ms.
- CheckPacketIsDelayed(QuicTime::Delta::FromMilliseconds(2));
-
- // Wake up on time.
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(2));
- // After sending packet 3, cwnd is limited.
- // This test is slightly odd because bytes_in_flight is calculated using
- // kMaxOutgoingPacketSize and CWND is calculated using kDefaultTCPMSS,
- // which is 8 bytes larger, so 3 packets can be sent for a CWND of 2.
- CheckPacketIsSentImmediately(HAS_RETRANSMITTABLE_DATA,
- 2 * kMaxOutgoingPacketSize, false, 2);
-
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(100));
- // Verify pacing sender stops making up for lost time after sending packet 3.
- // Packet 6 will be delayed 2ms.
- CheckPacketIsSentImmediately();
- CheckPacketIsSentImmediately();
- CheckPacketIsDelayed(QuicTime::Delta::FromMilliseconds(2));
-}
-
-TEST_F(PacingSenderTest, LumpyPacingWithInitialBurstToken) {
- // Set lumpy size to be 3, and cwnd faction to 0.5
- SetQuicFlag(FLAGS_quic_lumpy_pacing_size, 3);
- SetQuicFlag(FLAGS_quic_lumpy_pacing_cwnd_fraction, 0.5f);
- // Configure pacing rate of 1 packet per 1 ms.
- InitPacingRate(
- 10, QuicBandwidth::FromBytesAndTimeDelta(
- kMaxOutgoingPacketSize, QuicTime::Delta::FromMilliseconds(1)));
- UpdateRtt();
-
- // Send 10 packets, and verify that they are not paced.
- for (int i = 0; i < kInitialBurstPackets; ++i) {
- CheckPacketIsSentImmediately();
- }
-
- CheckPacketIsSentImmediately();
- CheckPacketIsSentImmediately();
- CheckPacketIsSentImmediately();
- // Packet 14 will be delayed 3ms.
- CheckPacketIsDelayed(QuicTime::Delta::FromMilliseconds(3));
-
- // Wake up on time.
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(3));
- CheckPacketIsSentImmediately();
- CheckPacketIsSentImmediately();
- CheckPacketIsSentImmediately();
- // Packet 17 will be delayed 3ms.
- CheckPacketIsDelayed(QuicTime::Delta::FromMilliseconds(3));
-
- // Application throttles sending.
- OnApplicationLimited();
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(100));
- CheckPacketIsSentImmediately();
- CheckPacketIsSentImmediately();
- CheckPacketIsSentImmediately();
- // Packet 20 will be delayed 3ms.
- CheckPacketIsDelayed(QuicTime::Delta::FromMilliseconds(3));
-
- // Wake up on time.
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(3));
- CheckPacketIsSentImmediately();
- // After sending packet 21, cwnd is limited.
- // This test is slightly odd because bytes_in_flight is calculated using
- // kMaxOutgoingPacketSize and CWND is calculated using kDefaultTCPMSS,
- // which is 8 bytes larger, so 21 packets can be sent for a CWND of 20.
- CheckPacketIsSentImmediately(HAS_RETRANSMITTABLE_DATA,
- 20 * kMaxOutgoingPacketSize, false, 20);
-
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(100));
- // Suppose cwnd size is 5, so that lumpy size becomes 2.
- CheckPacketIsSentImmediately(HAS_RETRANSMITTABLE_DATA, kBytesInFlight, false,
- 5);
- CheckPacketIsSentImmediately();
- // Packet 24 will be delayed 2ms.
- CheckPacketIsDelayed(QuicTime::Delta::FromMilliseconds(2));
-}
-
-TEST_F(PacingSenderTest, NoLumpyPacingForLowBandwidthFlows) {
- // Set lumpy size to be 3, and cwnd fraction to 0.5
- SetQuicFlag(FLAGS_quic_lumpy_pacing_size, 3);
- SetQuicFlag(FLAGS_quic_lumpy_pacing_cwnd_fraction, 0.5f);
-
- // Configure pacing rate of 1 packet per 100 ms.
- QuicTime::Delta inter_packet_delay = QuicTime::Delta::FromMilliseconds(100);
- InitPacingRate(kInitialBurstPackets,
- QuicBandwidth::FromBytesAndTimeDelta(kMaxOutgoingPacketSize,
- inter_packet_delay));
- UpdateRtt();
-
- // Send kInitialBurstPackets packets, and verify that they are not paced.
- for (int i = 0; i < kInitialBurstPackets; ++i) {
- CheckPacketIsSentImmediately();
- }
-
- // The first packet after burst token exhausted is also sent immediately,
- // because ideal_next_packet_send_time has not been set yet.
- CheckPacketIsSentImmediately();
-
- for (int i = 0; i < 200; ++i) {
- CheckPacketIsDelayed(inter_packet_delay);
- }
-}
-
-// Regression test for b/184471302 to ensure that ACKs received back-to-back
-// don't cause bursts in sending.
-TEST_F(PacingSenderTest, NoBurstsForLumpyPacingWithAckAggregation) {
- // Configure pacing rate of 1 packet per millisecond.
- QuicTime::Delta inter_packet_delay = QuicTime::Delta::FromMilliseconds(1);
- InitPacingRate(kInitialBurstPackets,
- QuicBandwidth::FromBytesAndTimeDelta(kMaxOutgoingPacketSize,
- inter_packet_delay));
- UpdateRtt();
-
- // Send kInitialBurstPackets packets, and verify that they are not paced.
- for (int i = 0; i < kInitialBurstPackets; ++i) {
- CheckPacketIsSentImmediately();
- }
- // The last packet of the burst causes the sender to be CWND limited.
- CheckPacketIsSentImmediately(HAS_RETRANSMITTABLE_DATA,
- 10 * kMaxOutgoingPacketSize, false, 10);
-
- if (GetQuicReloadableFlag(quic_fix_pacing_sender_bursts)) {
- // The last sent packet made the connection CWND limited, so no lumpy tokens
- // should be available.
- EXPECT_EQ(0u, pacing_sender_->lumpy_tokens());
- CheckPacketIsSentImmediately(HAS_RETRANSMITTABLE_DATA,
- 10 * kMaxOutgoingPacketSize, false, 10);
- EXPECT_EQ(0u, pacing_sender_->lumpy_tokens());
- CheckPacketIsDelayed(2 * inter_packet_delay);
- } else {
- EXPECT_EQ(1u, pacing_sender_->lumpy_tokens());
- // Repeatedly send single packets to make the sender CWND limited and
- // observe that there's no pacing without the fix.
- for (int i = 0; i < 10; ++i) {
- CheckPacketIsSentImmediately(HAS_RETRANSMITTABLE_DATA,
- 10 * kMaxOutgoingPacketSize, false, 10);
- }
- }
-}
-
-TEST_F(PacingSenderTest, IdealNextPacketSendTimeWithLumpyPacing) {
- // Set lumpy size to be 3, and cwnd faction to 0.5
- SetQuicFlag(FLAGS_quic_lumpy_pacing_size, 3);
- SetQuicFlag(FLAGS_quic_lumpy_pacing_cwnd_fraction, 0.5f);
-
- // Configure pacing rate of 1 packet per millisecond.
- QuicTime::Delta inter_packet_delay = QuicTime::Delta::FromMilliseconds(1);
- InitPacingRate(kInitialBurstPackets,
- QuicBandwidth::FromBytesAndTimeDelta(kMaxOutgoingPacketSize,
- inter_packet_delay));
-
- // Send kInitialBurstPackets packets, and verify that they are not paced.
- for (int i = 0; i < kInitialBurstPackets; ++i) {
- CheckPacketIsSentImmediately();
- }
-
- CheckPacketIsSentImmediately();
- EXPECT_EQ(pacing_sender_->ideal_next_packet_send_time(),
- clock_.Now() + inter_packet_delay);
- EXPECT_EQ(pacing_sender_->lumpy_tokens(), 2u);
-
- CheckPacketIsSentImmediately();
- EXPECT_EQ(pacing_sender_->ideal_next_packet_send_time(),
- clock_.Now() + 2 * inter_packet_delay);
- EXPECT_EQ(pacing_sender_->lumpy_tokens(), 1u);
-
- CheckPacketIsSentImmediately();
- EXPECT_EQ(pacing_sender_->ideal_next_packet_send_time(),
- clock_.Now() + 3 * inter_packet_delay);
- EXPECT_EQ(pacing_sender_->lumpy_tokens(), 0u);
-
- CheckPacketIsDelayed(3 * inter_packet_delay);
-
- // Wake up on time.
- clock_.AdvanceTime(3 * inter_packet_delay);
- CheckPacketIsSentImmediately();
- EXPECT_EQ(pacing_sender_->ideal_next_packet_send_time(),
- clock_.Now() + inter_packet_delay);
- EXPECT_EQ(pacing_sender_->lumpy_tokens(), 2u);
-
- CheckPacketIsSentImmediately();
- EXPECT_EQ(pacing_sender_->ideal_next_packet_send_time(),
- clock_.Now() + 2 * inter_packet_delay);
- EXPECT_EQ(pacing_sender_->lumpy_tokens(), 1u);
-
- CheckPacketIsSentImmediately();
- EXPECT_EQ(pacing_sender_->ideal_next_packet_send_time(),
- clock_.Now() + 3 * inter_packet_delay);
- EXPECT_EQ(pacing_sender_->lumpy_tokens(), 0u);
-
- CheckPacketIsDelayed(3 * inter_packet_delay);
-
- // Wake up late.
- clock_.AdvanceTime(4.5 * inter_packet_delay);
- CheckPacketIsSentImmediately();
- EXPECT_EQ(pacing_sender_->ideal_next_packet_send_time(),
- clock_.Now() - 0.5 * inter_packet_delay);
- EXPECT_EQ(pacing_sender_->lumpy_tokens(), 2u);
-
- CheckPacketIsSentImmediately();
- EXPECT_EQ(pacing_sender_->ideal_next_packet_send_time(),
- clock_.Now() + 0.5 * inter_packet_delay);
- EXPECT_EQ(pacing_sender_->lumpy_tokens(), 1u);
-
- CheckPacketIsSentImmediately();
- EXPECT_EQ(pacing_sender_->ideal_next_packet_send_time(),
- clock_.Now() + 1.5 * inter_packet_delay);
- EXPECT_EQ(pacing_sender_->lumpy_tokens(), 0u);
-
- CheckPacketIsDelayed(1.5 * inter_packet_delay);
-}
-
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/congestion_control/prr_sender.cc b/chromium/net/third_party/quiche/src/quic/core/congestion_control/prr_sender.cc
deleted file mode 100644
index ed969534bc6..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/congestion_control/prr_sender.cc
+++ /dev/null
@@ -1,62 +0,0 @@
-// Copyright (c) 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/congestion_control/prr_sender.h"
-
-#include "quic/core/quic_packets.h"
-
-namespace quic {
-
-PrrSender::PrrSender()
- : bytes_sent_since_loss_(0),
- bytes_delivered_since_loss_(0),
- ack_count_since_loss_(0),
- bytes_in_flight_before_loss_(0) {}
-
-void PrrSender::OnPacketSent(QuicByteCount sent_bytes) {
- bytes_sent_since_loss_ += sent_bytes;
-}
-
-void PrrSender::OnPacketLost(QuicByteCount prior_in_flight) {
- bytes_sent_since_loss_ = 0;
- bytes_in_flight_before_loss_ = prior_in_flight;
- bytes_delivered_since_loss_ = 0;
- ack_count_since_loss_ = 0;
-}
-
-void PrrSender::OnPacketAcked(QuicByteCount acked_bytes) {
- bytes_delivered_since_loss_ += acked_bytes;
- ++ack_count_since_loss_;
-}
-
-bool PrrSender::CanSend(QuicByteCount congestion_window,
- QuicByteCount bytes_in_flight,
- QuicByteCount slowstart_threshold) const {
- // Return QuicTime::Zero in order to ensure limited transmit always works.
- if (bytes_sent_since_loss_ == 0 || bytes_in_flight < kMaxSegmentSize) {
- return true;
- }
- if (congestion_window > bytes_in_flight) {
- // During PRR-SSRB, limit outgoing packets to 1 extra MSS per ack, instead
- // of sending the entire available window. This prevents burst retransmits
- // when more packets are lost than the CWND reduction.
- // limit = MAX(prr_delivered - prr_out, DeliveredData) + MSS
- if (bytes_delivered_since_loss_ + ack_count_since_loss_ * kMaxSegmentSize <=
- bytes_sent_since_loss_) {
- return false;
- }
- return true;
- }
- // Implement Proportional Rate Reduction (RFC6937).
- // Checks a simplified version of the PRR formula that doesn't use division:
- // AvailableSendWindow =
- // CEIL(prr_delivered * ssthresh / BytesInFlightAtLoss) - prr_sent
- if (bytes_delivered_since_loss_ * slowstart_threshold >
- bytes_sent_since_loss_ * bytes_in_flight_before_loss_) {
- return true;
- }
- return false;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/congestion_control/prr_sender.h b/chromium/net/third_party/quiche/src/quic/core/congestion_control/prr_sender.h
deleted file mode 100644
index a403dcf7295..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/congestion_control/prr_sender.h
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright (c) 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Implements Proportional Rate Reduction (PRR) per RFC 6937.
-
-#ifndef QUICHE_QUIC_CORE_CONGESTION_CONTROL_PRR_SENDER_H_
-#define QUICHE_QUIC_CORE_CONGESTION_CONTROL_PRR_SENDER_H_
-
-#include "quic/core/quic_bandwidth.h"
-#include "quic/core/quic_time.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-class QUIC_EXPORT_PRIVATE PrrSender {
- public:
- PrrSender();
- // OnPacketLost should be called on the first loss that triggers a recovery
- // period and all other methods in this class should only be called when in
- // recovery.
- void OnPacketLost(QuicByteCount prior_in_flight);
- void OnPacketSent(QuicByteCount sent_bytes);
- void OnPacketAcked(QuicByteCount acked_bytes);
- bool CanSend(QuicByteCount congestion_window,
- QuicByteCount bytes_in_flight,
- QuicByteCount slowstart_threshold) const;
-
- private:
- // Bytes sent and acked since the last loss event.
- // |bytes_sent_since_loss_| is the same as "prr_out_" in RFC 6937,
- // and |bytes_delivered_since_loss_| is the same as "prr_delivered_".
- QuicByteCount bytes_sent_since_loss_;
- QuicByteCount bytes_delivered_since_loss_;
- size_t ack_count_since_loss_;
-
- // The congestion window before the last loss event.
- QuicByteCount bytes_in_flight_before_loss_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_CONGESTION_CONTROL_PRR_SENDER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/congestion_control/prr_sender_test.cc b/chromium/net/third_party/quiche/src/quic/core/congestion_control/prr_sender_test.cc
deleted file mode 100644
index 80e9b4132c8..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/congestion_control/prr_sender_test.cc
+++ /dev/null
@@ -1,123 +0,0 @@
-// Copyright (c) 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/congestion_control/prr_sender.h"
-
-#include <algorithm>
-
-#include "quic/core/crypto/crypto_protocol.h"
-#include "quic/core/quic_constants.h"
-#include "quic/platform/api/quic_test.h"
-
-namespace quic {
-namespace test {
-
-namespace {
-// Constant based on TCP defaults.
-const QuicByteCount kMaxSegmentSize = kDefaultTCPMSS;
-} // namespace
-
-class PrrSenderTest : public QuicTest {};
-
-TEST_F(PrrSenderTest, SingleLossResultsInSendOnEveryOtherAck) {
- PrrSender prr;
- QuicPacketCount num_packets_in_flight = 50;
- QuicByteCount bytes_in_flight = num_packets_in_flight * kMaxSegmentSize;
- const QuicPacketCount ssthresh_after_loss = num_packets_in_flight / 2;
- const QuicByteCount congestion_window = ssthresh_after_loss * kMaxSegmentSize;
-
- prr.OnPacketLost(bytes_in_flight);
- // Ack a packet. PRR allows one packet to leave immediately.
- prr.OnPacketAcked(kMaxSegmentSize);
- bytes_in_flight -= kMaxSegmentSize;
- EXPECT_TRUE(prr.CanSend(congestion_window, bytes_in_flight,
- ssthresh_after_loss * kMaxSegmentSize));
- // Send retransmission.
- prr.OnPacketSent(kMaxSegmentSize);
- // PRR shouldn't allow sending any more packets.
- EXPECT_FALSE(prr.CanSend(congestion_window, bytes_in_flight,
- ssthresh_after_loss * kMaxSegmentSize));
-
- // One packet is lost, and one ack was consumed above. PRR now paces
- // transmissions through the remaining 48 acks. PRR will alternatively
- // disallow and allow a packet to be sent in response to an ack.
- for (uint64_t i = 0; i < ssthresh_after_loss - 1; ++i) {
- // Ack a packet. PRR shouldn't allow sending a packet in response.
- prr.OnPacketAcked(kMaxSegmentSize);
- bytes_in_flight -= kMaxSegmentSize;
- EXPECT_FALSE(prr.CanSend(congestion_window, bytes_in_flight,
- ssthresh_after_loss * kMaxSegmentSize));
- // Ack another packet. PRR should now allow sending a packet in response.
- prr.OnPacketAcked(kMaxSegmentSize);
- bytes_in_flight -= kMaxSegmentSize;
- EXPECT_TRUE(prr.CanSend(congestion_window, bytes_in_flight,
- ssthresh_after_loss * kMaxSegmentSize));
- // Send a packet in response.
- prr.OnPacketSent(kMaxSegmentSize);
- bytes_in_flight += kMaxSegmentSize;
- }
-
- // Since bytes_in_flight is now equal to congestion_window, PRR now maintains
- // packet conservation, allowing one packet to be sent in response to an ack.
- EXPECT_EQ(congestion_window, bytes_in_flight);
- for (int i = 0; i < 10; ++i) {
- // Ack a packet.
- prr.OnPacketAcked(kMaxSegmentSize);
- bytes_in_flight -= kMaxSegmentSize;
- EXPECT_TRUE(prr.CanSend(congestion_window, bytes_in_flight,
- ssthresh_after_loss * kMaxSegmentSize));
- // Send a packet in response, since PRR allows it.
- prr.OnPacketSent(kMaxSegmentSize);
- bytes_in_flight += kMaxSegmentSize;
-
- // Since bytes_in_flight is equal to the congestion_window,
- // PRR disallows sending.
- EXPECT_EQ(congestion_window, bytes_in_flight);
- EXPECT_FALSE(prr.CanSend(congestion_window, bytes_in_flight,
- ssthresh_after_loss * kMaxSegmentSize));
- }
-}
-
-TEST_F(PrrSenderTest, BurstLossResultsInSlowStart) {
- PrrSender prr;
- QuicByteCount bytes_in_flight = 20 * kMaxSegmentSize;
- const QuicPacketCount num_packets_lost = 13;
- const QuicPacketCount ssthresh_after_loss = 10;
- const QuicByteCount congestion_window = ssthresh_after_loss * kMaxSegmentSize;
-
- // Lose 13 packets.
- bytes_in_flight -= num_packets_lost * kMaxSegmentSize;
- prr.OnPacketLost(bytes_in_flight);
-
- // PRR-SSRB will allow the following 3 acks to send up to 2 packets.
- for (int i = 0; i < 3; ++i) {
- prr.OnPacketAcked(kMaxSegmentSize);
- bytes_in_flight -= kMaxSegmentSize;
- // PRR-SSRB should allow two packets to be sent.
- for (int j = 0; j < 2; ++j) {
- EXPECT_TRUE(prr.CanSend(congestion_window, bytes_in_flight,
- ssthresh_after_loss * kMaxSegmentSize));
- // Send a packet in response.
- prr.OnPacketSent(kMaxSegmentSize);
- bytes_in_flight += kMaxSegmentSize;
- }
- // PRR should allow no more than 2 packets in response to an ack.
- EXPECT_FALSE(prr.CanSend(congestion_window, bytes_in_flight,
- ssthresh_after_loss * kMaxSegmentSize));
- }
-
- // Out of SSRB mode, PRR allows one send in response to each ack.
- for (int i = 0; i < 10; ++i) {
- prr.OnPacketAcked(kMaxSegmentSize);
- bytes_in_flight -= kMaxSegmentSize;
- EXPECT_TRUE(prr.CanSend(congestion_window, bytes_in_flight,
- ssthresh_after_loss * kMaxSegmentSize));
- // Send a packet in response.
- prr.OnPacketSent(kMaxSegmentSize);
- bytes_in_flight += kMaxSegmentSize;
- }
-}
-
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/congestion_control/rtt_stats.cc b/chromium/net/third_party/quiche/src/quic/core/congestion_control/rtt_stats.cc
deleted file mode 100644
index e167dec9cf1..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/congestion_control/rtt_stats.cc
+++ /dev/null
@@ -1,144 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/congestion_control/rtt_stats.h"
-
-#include <cstdlib> // std::abs
-
-#include "quic/platform/api/quic_flag_utils.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-namespace {
-
-const float kAlpha = 0.125f;
-const float kOneMinusAlpha = (1 - kAlpha);
-const float kBeta = 0.25f;
-const float kOneMinusBeta = (1 - kBeta);
-
-} // namespace
-
-RttStats::RttStats()
- : latest_rtt_(QuicTime::Delta::Zero()),
- min_rtt_(QuicTime::Delta::Zero()),
- smoothed_rtt_(QuicTime::Delta::Zero()),
- previous_srtt_(QuicTime::Delta::Zero()),
- mean_deviation_(QuicTime::Delta::Zero()),
- calculate_standard_deviation_(false),
- initial_rtt_(QuicTime::Delta::FromMilliseconds(kInitialRttMs)),
- last_update_time_(QuicTime::Zero()) {}
-
-void RttStats::ExpireSmoothedMetrics() {
- mean_deviation_ = std::max(
- mean_deviation_, QuicTime::Delta::FromMicroseconds(std::abs(
- (smoothed_rtt_ - latest_rtt_).ToMicroseconds())));
- smoothed_rtt_ = std::max(smoothed_rtt_, latest_rtt_);
-}
-
-// Updates the RTT based on a new sample.
-void 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;
- }
-
- last_update_time_ = now;
-
- // Update min_rtt_ first. min_rtt_ does not use an rtt_sample corrected for
- // ack_delay but the raw observed send_delta, since poor clock granularity at
- // the client may cause a high ack_delay to result in underestimation of the
- // min_rtt_.
- if (min_rtt_.IsZero() || min_rtt_ > send_delta) {
- min_rtt_ = send_delta;
- }
-
- QuicTime::Delta rtt_sample(send_delta);
- previous_srtt_ = smoothed_rtt_;
- // Correct for ack_delay if information received from the peer results in a
- // an RTT sample at least as large as min_rtt. Otherwise, only use the
- // send_delta.
- // TODO(fayang): consider to ignore rtt_sample if rtt_sample < ack_delay and
- // ack_delay is relatively large.
- if (rtt_sample > ack_delay) {
- if (rtt_sample - min_rtt_ >= ack_delay) {
- rtt_sample = rtt_sample - ack_delay;
- } else {
- QUIC_CODE_COUNT(quic_ack_delay_makes_rtt_sample_smaller_than_min_rtt);
- }
- } else {
- QUIC_CODE_COUNT(quic_ack_delay_greater_than_rtt_sample);
- }
- latest_rtt_ = rtt_sample;
- if (calculate_standard_deviation_) {
- standard_deviation_calculator_.OnNewRttSample(rtt_sample, smoothed_rtt_);
- }
- // First time call.
- if (smoothed_rtt_.IsZero()) {
- smoothed_rtt_ = rtt_sample;
- mean_deviation_ =
- QuicTime::Delta::FromMicroseconds(rtt_sample.ToMicroseconds() / 2);
- } else {
- mean_deviation_ = QuicTime::Delta::FromMicroseconds(static_cast<int64_t>(
- kOneMinusBeta * mean_deviation_.ToMicroseconds() +
- kBeta * std::abs((smoothed_rtt_ - rtt_sample).ToMicroseconds())));
- smoothed_rtt_ = kOneMinusAlpha * smoothed_rtt_ + kAlpha * rtt_sample;
- QUIC_DVLOG(1) << " smoothed_rtt(us):" << smoothed_rtt_.ToMicroseconds()
- << " mean_deviation(us):" << mean_deviation_.ToMicroseconds();
- }
-}
-
-void RttStats::OnConnectionMigration() {
- latest_rtt_ = QuicTime::Delta::Zero();
- min_rtt_ = QuicTime::Delta::Zero();
- smoothed_rtt_ = QuicTime::Delta::Zero();
- mean_deviation_ = QuicTime::Delta::Zero();
- initial_rtt_ = QuicTime::Delta::FromMilliseconds(kInitialRttMs);
-}
-
-QuicTime::Delta RttStats::GetStandardOrMeanDeviation() const {
- QUICHE_DCHECK(calculate_standard_deviation_);
- if (!standard_deviation_calculator_.has_valid_standard_deviation) {
- return mean_deviation_;
- }
- return standard_deviation_calculator_.CalculateStandardDeviation();
-}
-
-void RttStats::StandardDeviationCaculator::OnNewRttSample(
- QuicTime::Delta rtt_sample,
- QuicTime::Delta smoothed_rtt) {
- double new_value = rtt_sample.ToMicroseconds();
- if (smoothed_rtt.IsZero()) {
- return;
- }
- has_valid_standard_deviation = true;
- const double delta = new_value - smoothed_rtt.ToMicroseconds();
- m2 = kOneMinusBeta * m2 + kBeta * pow(delta, 2);
-}
-
-QuicTime::Delta
-RttStats::StandardDeviationCaculator::CalculateStandardDeviation() const {
- QUICHE_DCHECK(has_valid_standard_deviation);
- return QuicTime::Delta::FromMicroseconds(sqrt(m2));
-}
-
-void RttStats::CloneFrom(const RttStats& stats) {
- latest_rtt_ = stats.latest_rtt_;
- min_rtt_ = stats.min_rtt_;
- smoothed_rtt_ = stats.smoothed_rtt_;
- previous_srtt_ = stats.previous_srtt_;
- mean_deviation_ = stats.mean_deviation_;
- standard_deviation_calculator_ = stats.standard_deviation_calculator_;
- calculate_standard_deviation_ = stats.calculate_standard_deviation_;
- initial_rtt_ = stats.initial_rtt_;
- last_update_time_ = stats.last_update_time_;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/congestion_control/rtt_stats.h b/chromium/net/third_party/quiche/src/quic/core/congestion_control/rtt_stats.h
deleted file mode 100644
index cb591dbf2e1..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/congestion_control/rtt_stats.h
+++ /dev/null
@@ -1,131 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// A convenience class to store rtt samples and calculate smoothed rtt.
-
-#ifndef QUICHE_QUIC_CORE_CONGESTION_CONTROL_RTT_STATS_H_
-#define QUICHE_QUIC_CORE_CONGESTION_CONTROL_RTT_STATS_H_
-
-#include <algorithm>
-#include <cstdint>
-
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_time.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-namespace test {
-class RttStatsPeer;
-} // namespace test
-
-class QUIC_EXPORT_PRIVATE RttStats {
- public:
- // Calculates running standard-deviation using Welford's algorithm:
- // https://en.wikipedia.org/wiki/Algorithms_for_calculating_variance#
- // Welford's_Online_algorithm.
- struct QUIC_EXPORT_PRIVATE StandardDeviationCaculator {
- StandardDeviationCaculator() {}
-
- // Called when a new RTT sample is available.
- void OnNewRttSample(QuicTime::Delta rtt_sample,
- QuicTime::Delta smoothed_rtt);
- // Calculates the standard deviation.
- QuicTime::Delta CalculateStandardDeviation() const;
-
- bool has_valid_standard_deviation = false;
-
- private:
- double m2 = 0;
- };
-
- RttStats();
- RttStats(const RttStats&) = delete;
- RttStats& operator=(const RttStats&) = delete;
-
- // 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,
- QuicTime now);
-
- // Causes the smoothed_rtt to be increased to the latest_rtt if the latest_rtt
- // is larger. The mean deviation is increased to the most recent deviation if
- // it's larger.
- void ExpireSmoothedMetrics();
-
- // Called when connection migrates and rtt measurement needs to be reset.
- void OnConnectionMigration();
-
- // Returns the EWMA smoothed RTT for the connection.
- // May return Zero if no valid updates have occurred.
- QuicTime::Delta smoothed_rtt() const { return smoothed_rtt_; }
-
- // Returns the EWMA smoothed RTT prior to the most recent RTT sample.
- QuicTime::Delta previous_srtt() const { return previous_srtt_; }
-
- QuicTime::Delta initial_rtt() const { return initial_rtt_; }
-
- QuicTime::Delta SmoothedOrInitialRtt() const {
- return smoothed_rtt_.IsZero() ? initial_rtt_ : smoothed_rtt_;
- }
-
- QuicTime::Delta MinOrInitialRtt() const {
- return min_rtt_.IsZero() ? initial_rtt_ : min_rtt_;
- }
-
- // Sets an initial RTT to be used for SmoothedRtt before any RTT updates.
- void set_initial_rtt(QuicTime::Delta initial_rtt) {
- if (initial_rtt.ToMicroseconds() <= 0) {
- QUIC_BUG(quic_bug_10453_1) << "Attempt to set initial rtt to <= 0.";
- return;
- }
- initial_rtt_ = initial_rtt;
- }
-
- // The most recent rtt measurement.
- // May return Zero if no valid updates have occurred.
- QuicTime::Delta latest_rtt() const { return latest_rtt_; }
-
- // Returns the min_rtt for the entire connection.
- // May return Zero if no valid updates have occurred.
- QuicTime::Delta min_rtt() const { return min_rtt_; }
-
- QuicTime::Delta mean_deviation() const { return mean_deviation_; }
-
- // Returns standard deviation if there is a valid one. Otherwise, returns
- // mean_deviation_.
- QuicTime::Delta GetStandardOrMeanDeviation() const;
-
- QuicTime last_update_time() const { return last_update_time_; }
-
- void EnableStandardDeviationCalculation() {
- calculate_standard_deviation_ = true;
- }
-
- void CloneFrom(const RttStats& stats);
-
- private:
- friend class test::RttStatsPeer;
-
- QuicTime::Delta latest_rtt_;
- QuicTime::Delta min_rtt_;
- QuicTime::Delta smoothed_rtt_;
- QuicTime::Delta previous_srtt_;
- // Mean RTT deviation during this session.
- // Approximation of standard deviation, the error is roughly 1.25 times
- // larger than the standard deviation, for a normally distributed signal.
- QuicTime::Delta mean_deviation_;
- // Standard deviation calculator. Only used calculate_standard_deviation_ is
- // true.
- StandardDeviationCaculator standard_deviation_calculator_;
- bool calculate_standard_deviation_;
- QuicTime::Delta initial_rtt_;
- QuicTime last_update_time_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_CONGESTION_CONTROL_RTT_STATS_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/congestion_control/rtt_stats_test.cc b/chromium/net/third_party/quiche/src/quic/core/congestion_control/rtt_stats_test.cc
deleted file mode 100644
index 1df509f0f7c..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/congestion_control/rtt_stats_test.cc
+++ /dev/null
@@ -1,242 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/congestion_control/rtt_stats.h"
-
-#include <cmath>
-
-#include "quic/platform/api/quic_logging.h"
-#include "quic/platform/api/quic_mock_log.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/quic_test_utils.h"
-#include "quic/test_tools/rtt_stats_peer.h"
-
-using testing::_;
-using testing::Message;
-
-namespace quic {
-namespace test {
-
-class RttStatsTest : public QuicTest {
- protected:
- RttStats rtt_stats_;
-};
-
-TEST_F(RttStatsTest, DefaultsBeforeUpdate) {
- EXPECT_LT(QuicTime::Delta::Zero(), rtt_stats_.initial_rtt());
- EXPECT_EQ(QuicTime::Delta::Zero(), rtt_stats_.min_rtt());
- EXPECT_EQ(QuicTime::Delta::Zero(), rtt_stats_.smoothed_rtt());
-}
-
-TEST_F(RttStatsTest, SmoothedRtt) {
- // Verify that ack_delay is ignored in the first measurement.
- rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(300),
- QuicTime::Delta::FromMilliseconds(100),
- QuicTime::Zero());
- EXPECT_EQ(QuicTime::Delta::FromMilliseconds(300), rtt_stats_.latest_rtt());
- EXPECT_EQ(QuicTime::Delta::FromMilliseconds(300), rtt_stats_.smoothed_rtt());
- // Verify that a plausible ack delay increases the max ack delay.
- rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(400),
- QuicTime::Delta::FromMilliseconds(100),
- QuicTime::Zero());
- EXPECT_EQ(QuicTime::Delta::FromMilliseconds(300), rtt_stats_.latest_rtt());
- EXPECT_EQ(QuicTime::Delta::FromMilliseconds(300), rtt_stats_.smoothed_rtt());
- // Verify that Smoothed RTT includes max ack delay if it's reasonable.
- rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(350),
- QuicTime::Delta::FromMilliseconds(50), QuicTime::Zero());
- EXPECT_EQ(QuicTime::Delta::FromMilliseconds(300), rtt_stats_.latest_rtt());
- EXPECT_EQ(QuicTime::Delta::FromMilliseconds(300), rtt_stats_.smoothed_rtt());
- // Verify that large erroneous ack_delay does not change Smoothed RTT.
- rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(200),
- QuicTime::Delta::FromMilliseconds(300),
- QuicTime::Zero());
- EXPECT_EQ(QuicTime::Delta::FromMilliseconds(200), rtt_stats_.latest_rtt());
- EXPECT_EQ(QuicTime::Delta::FromMicroseconds(287500),
- rtt_stats_.smoothed_rtt());
-}
-
-// Ensure that the potential rounding artifacts in EWMA calculation do not cause
-// the SRTT to drift too far from the exact value.
-TEST_F(RttStatsTest, SmoothedRttStability) {
- for (size_t time = 3; time < 20000; time++) {
- RttStats stats;
- for (size_t i = 0; i < 100; i++) {
- stats.UpdateRtt(QuicTime::Delta::FromMicroseconds(time),
- QuicTime::Delta::FromMilliseconds(0), QuicTime::Zero());
- int64_t time_delta_us = stats.smoothed_rtt().ToMicroseconds() - time;
- ASSERT_LE(std::abs(time_delta_us), 1);
- }
- }
-}
-
-TEST_F(RttStatsTest, PreviousSmoothedRtt) {
- // Verify that ack_delay is corrected for in Smoothed RTT.
- rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(200),
- QuicTime::Delta::FromMilliseconds(0), QuicTime::Zero());
- EXPECT_EQ(QuicTime::Delta::FromMilliseconds(200), rtt_stats_.latest_rtt());
- EXPECT_EQ(QuicTime::Delta::FromMilliseconds(200), rtt_stats_.smoothed_rtt());
- EXPECT_EQ(QuicTime::Delta::Zero(), rtt_stats_.previous_srtt());
- // Ensure the previous SRTT is 200ms after a 100ms sample.
- rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(100),
- QuicTime::Delta::Zero(), QuicTime::Zero());
- EXPECT_EQ(QuicTime::Delta::FromMilliseconds(100), rtt_stats_.latest_rtt());
- EXPECT_EQ(QuicTime::Delta::FromMicroseconds(187500).ToMicroseconds(),
- rtt_stats_.smoothed_rtt().ToMicroseconds());
- EXPECT_EQ(QuicTime::Delta::FromMilliseconds(200), rtt_stats_.previous_srtt());
-}
-
-TEST_F(RttStatsTest, MinRtt) {
- rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(200),
- QuicTime::Delta::Zero(), QuicTime::Zero());
- EXPECT_EQ(QuicTime::Delta::FromMilliseconds(200), rtt_stats_.min_rtt());
- rtt_stats_.UpdateRtt(
- QuicTime::Delta::FromMilliseconds(10), QuicTime::Delta::Zero(),
- QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(10));
- EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10), rtt_stats_.min_rtt());
- rtt_stats_.UpdateRtt(
- QuicTime::Delta::FromMilliseconds(50), QuicTime::Delta::Zero(),
- QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(20));
- EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10), rtt_stats_.min_rtt());
- rtt_stats_.UpdateRtt(
- QuicTime::Delta::FromMilliseconds(50), QuicTime::Delta::Zero(),
- QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(30));
- EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10), rtt_stats_.min_rtt());
- rtt_stats_.UpdateRtt(
- QuicTime::Delta::FromMilliseconds(50), QuicTime::Delta::Zero(),
- QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(40));
- EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10), rtt_stats_.min_rtt());
- // Verify that ack_delay does not go into recording of min_rtt_.
- rtt_stats_.UpdateRtt(
- QuicTime::Delta::FromMilliseconds(7),
- QuicTime::Delta::FromMilliseconds(2),
- QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(50));
- EXPECT_EQ(QuicTime::Delta::FromMilliseconds(7), rtt_stats_.min_rtt());
-}
-
-TEST_F(RttStatsTest, ExpireSmoothedMetrics) {
- 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());
- EXPECT_EQ(initial_rtt, rtt_stats_.smoothed_rtt());
-
- EXPECT_EQ(0.5 * initial_rtt, rtt_stats_.mean_deviation());
-
- // Update once with a 20ms RTT.
- QuicTime::Delta doubled_rtt = 2 * initial_rtt;
- rtt_stats_.UpdateRtt(doubled_rtt, QuicTime::Delta::Zero(), QuicTime::Zero());
- EXPECT_EQ(1.125 * initial_rtt, rtt_stats_.smoothed_rtt());
-
- // Expire the smoothed metrics, increasing smoothed rtt and mean deviation.
- rtt_stats_.ExpireSmoothedMetrics();
- EXPECT_EQ(doubled_rtt, rtt_stats_.smoothed_rtt());
- EXPECT_EQ(0.875 * initial_rtt, rtt_stats_.mean_deviation());
-
- // Now go back down to 5ms and expire the smoothed metrics, and ensure the
- // mean deviation increases to 15ms.
- QuicTime::Delta half_rtt = 0.5 * initial_rtt;
- rtt_stats_.UpdateRtt(half_rtt, QuicTime::Delta::Zero(), QuicTime::Zero());
- EXPECT_GT(doubled_rtt, rtt_stats_.smoothed_rtt());
- EXPECT_LT(initial_rtt, rtt_stats_.mean_deviation());
-}
-
-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());
- EXPECT_EQ(initial_rtt, rtt_stats_.smoothed_rtt());
-
- std::vector<QuicTime::Delta> bad_send_deltas;
- 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_EQ(initial_rtt, rtt_stats_.min_rtt());
- EXPECT_EQ(initial_rtt, rtt_stats_.smoothed_rtt());
- }
-}
-
-TEST_F(RttStatsTest, ResetAfterConnectionMigrations) {
- rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(200),
- QuicTime::Delta::FromMilliseconds(0), QuicTime::Zero());
- EXPECT_EQ(QuicTime::Delta::FromMilliseconds(200), rtt_stats_.latest_rtt());
- EXPECT_EQ(QuicTime::Delta::FromMilliseconds(200), rtt_stats_.smoothed_rtt());
- EXPECT_EQ(QuicTime::Delta::FromMilliseconds(200), rtt_stats_.min_rtt());
-
- rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(300),
- QuicTime::Delta::FromMilliseconds(100),
- QuicTime::Zero());
- EXPECT_EQ(QuicTime::Delta::FromMilliseconds(200), rtt_stats_.latest_rtt());
- EXPECT_EQ(QuicTime::Delta::FromMilliseconds(200), rtt_stats_.smoothed_rtt());
- EXPECT_EQ(QuicTime::Delta::FromMilliseconds(200), rtt_stats_.min_rtt());
-
- // Reset rtt stats on connection migrations.
- rtt_stats_.OnConnectionMigration();
- EXPECT_EQ(QuicTime::Delta::Zero(), rtt_stats_.latest_rtt());
- EXPECT_EQ(QuicTime::Delta::Zero(), rtt_stats_.smoothed_rtt());
- EXPECT_EQ(QuicTime::Delta::Zero(), rtt_stats_.min_rtt());
-}
-
-TEST_F(RttStatsTest, StandardDeviationCaculatorTest1) {
- // All samples are the same.
- rtt_stats_.EnableStandardDeviationCalculation();
- rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(10),
- QuicTime::Delta::Zero(), QuicTime::Zero());
- EXPECT_EQ(rtt_stats_.mean_deviation(),
- rtt_stats_.GetStandardOrMeanDeviation());
-
- rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(10),
- QuicTime::Delta::Zero(), QuicTime::Zero());
- rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(10),
- QuicTime::Delta::Zero(), QuicTime::Zero());
- EXPECT_EQ(QuicTime::Delta::Zero(), rtt_stats_.GetStandardOrMeanDeviation());
-}
-
-TEST_F(RttStatsTest, StandardDeviationCaculatorTest2) {
- // Small variance.
- rtt_stats_.EnableStandardDeviationCalculation();
- rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(10),
- QuicTime::Delta::Zero(), QuicTime::Zero());
- rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(10),
- QuicTime::Delta::Zero(), QuicTime::Zero());
- rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(10),
- QuicTime::Delta::Zero(), QuicTime::Zero());
- rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(9),
- QuicTime::Delta::Zero(), QuicTime::Zero());
- rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(11),
- QuicTime::Delta::Zero(), QuicTime::Zero());
- EXPECT_LT(QuicTime::Delta::FromMicroseconds(500),
- rtt_stats_.GetStandardOrMeanDeviation());
- EXPECT_GT(QuicTime::Delta::FromMilliseconds(1),
- rtt_stats_.GetStandardOrMeanDeviation());
-}
-
-TEST_F(RttStatsTest, StandardDeviationCaculatorTest3) {
- // Some variance.
- rtt_stats_.EnableStandardDeviationCalculation();
- rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(50),
- QuicTime::Delta::Zero(), QuicTime::Zero());
- rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(100),
- QuicTime::Delta::Zero(), QuicTime::Zero());
- rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(100),
- QuicTime::Delta::Zero(), QuicTime::Zero());
- rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(50),
- QuicTime::Delta::Zero(), QuicTime::Zero());
- EXPECT_APPROX_EQ(rtt_stats_.mean_deviation(),
- rtt_stats_.GetStandardOrMeanDeviation(), 0.25f);
-}
-
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/congestion_control/send_algorithm_interface.cc b/chromium/net/third_party/quiche/src/quic/core/congestion_control/send_algorithm_interface.cc
deleted file mode 100644
index 22f164cd3b7..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/congestion_control/send_algorithm_interface.cc
+++ /dev/null
@@ -1,61 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/congestion_control/send_algorithm_interface.h"
-
-#include "absl/base/attributes.h"
-#include "quic/core/congestion_control/bbr2_sender.h"
-#include "quic/core/congestion_control/bbr_sender.h"
-#include "quic/core/congestion_control/tcp_cubic_sender_bytes.h"
-#include "quic/core/quic_packets.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_flag_utils.h"
-#include "quic/platform/api/quic_flags.h"
-
-namespace quic {
-
-class RttStats;
-
-// Factory for send side congestion control algorithm.
-SendAlgorithmInterface* SendAlgorithmInterface::Create(
- const QuicClock* clock,
- const RttStats* rtt_stats,
- const QuicUnackedPacketMap* unacked_packets,
- CongestionControlType congestion_control_type,
- QuicRandom* random,
- QuicConnectionStats* stats,
- QuicPacketCount initial_congestion_window,
- SendAlgorithmInterface* old_send_algorithm) {
- QuicPacketCount max_congestion_window =
- GetQuicFlag(FLAGS_quic_max_congestion_window);
- switch (congestion_control_type) {
- case kGoogCC: // GoogCC is not supported by quic/core, fall back to BBR.
- case kBBR:
- return new BbrSender(clock->ApproximateNow(), rtt_stats, unacked_packets,
- initial_congestion_window, max_congestion_window,
- random, stats);
- case kBBRv2:
- return new Bbr2Sender(
- clock->ApproximateNow(), rtt_stats, unacked_packets,
- initial_congestion_window, max_congestion_window, random, stats,
- old_send_algorithm &&
- old_send_algorithm->GetCongestionControlType() == kBBR
- ? static_cast<BbrSender*>(old_send_algorithm)
- : nullptr);
- case kPCC:
- // PCC is currently not supported, fall back to CUBIC instead.
- ABSL_FALLTHROUGH_INTENDED;
- case kCubicBytes:
- return new TcpCubicSenderBytes(
- clock, rtt_stats, false /* don't use Reno */,
- initial_congestion_window, max_congestion_window, stats);
- case kRenoBytes:
- return new TcpCubicSenderBytes(clock, rtt_stats, true /* use Reno */,
- initial_congestion_window,
- max_congestion_window, stats);
- }
- return nullptr;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/congestion_control/send_algorithm_interface.h b/chromium/net/third_party/quiche/src/quic/core/congestion_control/send_algorithm_interface.h
deleted file mode 100644
index 42716033c6d..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/congestion_control/send_algorithm_interface.h
+++ /dev/null
@@ -1,177 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// The pure virtual class for send side congestion control algorithm.
-
-#ifndef QUICHE_QUIC_CORE_CONGESTION_CONTROL_SEND_ALGORITHM_INTERFACE_H_
-#define QUICHE_QUIC_CORE_CONGESTION_CONTROL_SEND_ALGORITHM_INTERFACE_H_
-
-#include <algorithm>
-#include <map>
-#include <string>
-
-#include "quic/core/crypto/quic_random.h"
-#include "quic/core/quic_bandwidth.h"
-#include "quic/core/quic_clock.h"
-#include "quic/core/quic_config.h"
-#include "quic/core/quic_connection_stats.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_time.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_unacked_packet_map.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-using QuicRoundTripCount = uint64_t;
-
-class CachedNetworkParameters;
-class RttStats;
-
-class QUIC_EXPORT_PRIVATE SendAlgorithmInterface {
- public:
- // Network Params for AdjustNetworkParameters.
- struct QUIC_NO_EXPORT NetworkParams {
- NetworkParams() = default;
- NetworkParams(const QuicBandwidth& bandwidth,
- const QuicTime::Delta& rtt,
- bool allow_cwnd_to_decrease)
- : 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;
- }
-
- 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;
- };
-
- static SendAlgorithmInterface* Create(
- const QuicClock* clock,
- const RttStats* rtt_stats,
- const QuicUnackedPacketMap* unacked_packets,
- CongestionControlType type,
- QuicRandom* random,
- QuicConnectionStats* stats,
- QuicPacketCount initial_congestion_window,
- SendAlgorithmInterface* old_send_algorithm);
-
- virtual ~SendAlgorithmInterface() {}
-
- virtual void SetFromConfig(const QuicConfig& config,
- Perspective perspective) = 0;
-
- virtual void ApplyConnectionOptions(
- const QuicTagVector& connection_options) = 0;
-
- // Sets the initial congestion window in number of packets. May be ignored
- // if called after the initial congestion window is no longer relevant.
- virtual void SetInitialCongestionWindowInPackets(QuicPacketCount packets) = 0;
-
- // Indicates an update to the congestion state, caused either by an incoming
- // ack or loss event timeout. |rtt_updated| indicates whether a new
- // latest_rtt sample has been taken, |prior_in_flight| the bytes in flight
- // prior to the congestion event. |acked_packets| and |lost_packets| are any
- // packets considered acked or lost as a result of the congestion event.
- virtual void OnCongestionEvent(bool rtt_updated,
- QuicByteCount prior_in_flight,
- QuicTime event_time,
- const AckedPacketVector& acked_packets,
- const LostPacketVector& lost_packets) = 0;
-
- // Inform that we sent |bytes| to the wire, and if the packet is
- // retransmittable. |bytes_in_flight| is the number of bytes in flight before
- // the packet was sent.
- // Note: this function must be called for every packet sent to the wire.
- virtual void OnPacketSent(QuicTime sent_time,
- QuicByteCount bytes_in_flight,
- QuicPacketNumber packet_number,
- QuicByteCount bytes,
- HasRetransmittableData is_retransmittable) = 0;
-
- // Inform that |packet_number| has been neutered.
- virtual void OnPacketNeutered(QuicPacketNumber packet_number) = 0;
-
- // Called when the retransmission timeout fires. Neither OnPacketAbandoned
- // nor OnPacketLost will be called for these packets.
- virtual void OnRetransmissionTimeout(bool packets_retransmitted) = 0;
-
- // Called when connection migrates and cwnd needs to be reset.
- virtual void OnConnectionMigration() = 0;
-
- // Make decision on whether the sender can send right now. Note that even
- // when this method returns true, the sending can be delayed due to pacing.
- virtual bool CanSend(QuicByteCount bytes_in_flight) = 0;
-
- // The pacing rate of the send algorithm. May be zero if the rate is unknown.
- virtual QuicBandwidth PacingRate(QuicByteCount bytes_in_flight) const = 0;
-
- // What's the current estimated bandwidth in bytes per second.
- // Returns 0 when it does not have an estimate.
- virtual QuicBandwidth BandwidthEstimate() const = 0;
-
- // Returns the size of the current congestion window in bytes. Note, this is
- // not the *available* window. Some send algorithms may not use a congestion
- // window and will return 0.
- virtual QuicByteCount GetCongestionWindow() const = 0;
-
- // Whether the send algorithm is currently in slow start. When true, the
- // BandwidthEstimate is expected to be too low.
- virtual bool InSlowStart() const = 0;
-
- // 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;
-
- virtual CongestionControlType GetCongestionControlType() const = 0;
-
- // Notifies the congestion control algorithm of an external network
- // measurement or prediction. Either |bandwidth| or |rtt| may be zero if no
- // sample is available.
- virtual void AdjustNetworkParameters(const NetworkParams& params) = 0;
-
- // Retrieves debugging information about the current state of the
- // send algorithm.
- virtual std::string GetDebugState() const = 0;
-
- // Called when the connection has no outstanding data to send. Specifically,
- // this means that none of the data streams are write-blocked, there are no
- // packets in the connection queue, and there are no pending retransmissins,
- // i.e. the sender cannot send anything for reasons other than being blocked
- // by congestion controller. This includes cases when the connection is
- // blocked by the flow controller.
- //
- // The fact that this method is called does not necessarily imply that the
- // connection would not be blocked by the congestion control if it actually
- // tried to send data. If the congestion control algorithm needs to exclude
- // such cases, it should use the internal state it uses for congestion control
- // for that.
- virtual void OnApplicationLimited(QuicByteCount bytes_in_flight) = 0;
-
- // Called before connection close to collect stats.
- virtual void PopulateConnectionStats(QuicConnectionStats* stats) const = 0;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_CONGESTION_CONTROL_SEND_ALGORITHM_INTERFACE_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/congestion_control/send_algorithm_test.cc b/chromium/net/third_party/quiche/src/quic/core/congestion_control/send_algorithm_test.cc
deleted file mode 100644
index d4c607063ac..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/congestion_control/send_algorithm_test.cc
+++ /dev/null
@@ -1,373 +0,0 @@
-// Copyright 2013 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 <algorithm>
-#include <map>
-#include <memory>
-#include <string>
-#include <utility>
-
-#include "absl/strings/str_cat.h"
-#include "quic/core/congestion_control/rtt_stats.h"
-#include "quic/core/congestion_control/send_algorithm_interface.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/mock_clock.h"
-#include "quic/test_tools/quic_config_peer.h"
-#include "quic/test_tools/quic_connection_peer.h"
-#include "quic/test_tools/quic_sent_packet_manager_peer.h"
-#include "quic/test_tools/quic_test_utils.h"
-#include "quic/test_tools/simulator/quic_endpoint.h"
-#include "quic/test_tools/simulator/simulator.h"
-#include "quic/test_tools/simulator/switch.h"
-
-namespace quic {
-namespace test {
-namespace {
-
-// Use the initial CWND of 10, as 32 is too much for the test network.
-const uint32_t kInitialCongestionWindowPackets = 10;
-
-// Test network parameters. Here, the topology of the network is:
-//
-// QUIC Sender
-// |
-// | <-- local link
-// |
-// Network switch
-// * <-- the bottleneck queue in the direction
-// | of the receiver
-// |
-// | <-- test link
-// |
-// |
-// Receiver
-//
-// When setting the bandwidth of the local link and test link, choose
-// a bandwidth lower than 20Mbps, as the clock-granularity of the
-// simulator can only handle a granularity of 1us.
-
-// Default settings between the switch and the sender.
-const QuicBandwidth kLocalLinkBandwidth =
- QuicBandwidth::FromKBitsPerSecond(10000);
-const QuicTime::Delta kLocalPropagationDelay =
- QuicTime::Delta::FromMilliseconds(2);
-
-// Wired network settings. A typical desktop network setup, a
-// high-bandwidth, 30ms test link to the receiver.
-const QuicBandwidth kTestLinkWiredBandwidth =
- QuicBandwidth::FromKBitsPerSecond(4000);
-const QuicTime::Delta kTestLinkWiredPropagationDelay =
- QuicTime::Delta::FromMilliseconds(50);
-const QuicTime::Delta kTestWiredTransferTime =
- kTestLinkWiredBandwidth.TransferTime(kMaxOutgoingPacketSize) +
- kLocalLinkBandwidth.TransferTime(kMaxOutgoingPacketSize);
-const QuicTime::Delta kTestWiredRtt =
- (kTestLinkWiredPropagationDelay + kLocalPropagationDelay +
- kTestWiredTransferTime) *
- 2;
-const QuicByteCount kTestWiredBdp = kTestWiredRtt * kTestLinkWiredBandwidth;
-
-// Small BDP, Bandwidth-policed network settings. In this scenario,
-// the receiver has a low-bandwidth, short propagation-delay link,
-// resulting in a small BDP. We model the policer by setting the
-// queue size to only one packet.
-const QuicBandwidth kTestLinkLowBdpBandwidth =
- QuicBandwidth::FromKBitsPerSecond(200);
-const QuicTime::Delta kTestLinkLowBdpPropagationDelay =
- QuicTime::Delta::FromMilliseconds(50);
-const QuicByteCount kTestPolicerQueue = kMaxOutgoingPacketSize;
-
-// Satellite network settings. In a satellite network, the bottleneck
-// buffer is typically sized for non-satellite links , but the
-// propagation delay of the test link to the receiver is as much as a
-// quarter second.
-const QuicTime::Delta kTestSatellitePropagationDelay =
- QuicTime::Delta::FromMilliseconds(250);
-
-// Cellular scenarios. In a cellular network, the bottleneck queue at
-// the edge of the network can be as great as 3MB.
-const QuicBandwidth kTestLink2GBandwidth =
- QuicBandwidth::FromKBitsPerSecond(100);
-const QuicBandwidth kTestLink3GBandwidth =
- QuicBandwidth::FromKBitsPerSecond(1500);
-const QuicByteCount kCellularQueue = 3 * 1024 * 1024;
-const QuicTime::Delta kTestCellularPropagationDelay =
- QuicTime::Delta::FromMilliseconds(40);
-
-// Small RTT scenario, below the per-ack-update threshold of 30ms.
-const QuicTime::Delta kTestLinkSmallRTTDelay =
- QuicTime::Delta::FromMilliseconds(10);
-
-const char* CongestionControlTypeToString(CongestionControlType cc_type) {
- switch (cc_type) {
- case kCubicBytes:
- return "CUBIC_BYTES";
- case kRenoBytes:
- return "RENO_BYTES";
- case kBBR:
- return "BBR";
- case kPCC:
- return "PCC";
- default:
- QUIC_DLOG(FATAL) << "Unexpected CongestionControlType";
- return nullptr;
- }
-}
-
-struct TestParams {
- explicit TestParams(CongestionControlType congestion_control_type)
- : congestion_control_type(congestion_control_type) {}
-
- friend std::ostream& operator<<(std::ostream& os, const TestParams& p) {
- os << "{ congestion_control_type: "
- << CongestionControlTypeToString(p.congestion_control_type);
- os << " }";
- return os;
- }
-
- const CongestionControlType congestion_control_type;
-};
-
-std::string TestParamToString(
- const testing::TestParamInfo<TestParams>& params) {
- return absl::StrCat(
- CongestionControlTypeToString(params.param.congestion_control_type), "_");
-}
-
-// Constructs various test permutations.
-std::vector<TestParams> GetTestParams() {
- std::vector<TestParams> params;
- for (const CongestionControlType congestion_control_type :
- {kBBR, kCubicBytes, kRenoBytes, kPCC}) {
- params.push_back(TestParams(congestion_control_type));
- }
- return params;
-}
-
-} // namespace
-
-class SendAlgorithmTest : public QuicTestWithParam<TestParams> {
- protected:
- SendAlgorithmTest()
- : simulator_(),
- quic_sender_(&simulator_,
- "QUIC sender",
- "Receiver",
- Perspective::IS_CLIENT,
- TestConnectionId()),
- receiver_(&simulator_,
- "Receiver",
- "QUIC sender",
- Perspective::IS_SERVER,
- TestConnectionId()) {
- rtt_stats_ = quic_sender_.connection()->sent_packet_manager().GetRttStats();
- sender_ = SendAlgorithmInterface::Create(
- simulator_.GetClock(), rtt_stats_,
- QuicSentPacketManagerPeer::GetUnackedPacketMap(
- QuicConnectionPeer::GetSentPacketManager(
- quic_sender_.connection())),
- GetParam().congestion_control_type, &random_, &stats_,
- kInitialCongestionWindowPackets, nullptr);
- quic_sender_.RecordTrace();
-
- QuicConnectionPeer::SetSendAlgorithm(quic_sender_.connection(), sender_);
- const int kTestMaxPacketSize = 1350;
- quic_sender_.connection()->SetMaxPacketLength(kTestMaxPacketSize);
- clock_ = simulator_.GetClock();
- simulator_.set_random_generator(&random_);
-
- uint64_t seed = QuicRandom::GetInstance()->RandUint64();
- random_.set_seed(seed);
- QUIC_LOG(INFO) << "SendAlgorithmTest simulator set up. Seed: " << seed;
- }
-
- // Creates a simulated network, with default settings between the
- // sender and the switch and the given settings from the switch to
- // the receiver.
- void CreateSetup(const QuicBandwidth& test_bandwidth,
- const QuicTime::Delta& test_link_delay,
- QuicByteCount bottleneck_queue_length) {
- switch_ = std::make_unique<simulator::Switch>(&simulator_, "Switch", 8,
- bottleneck_queue_length);
- quic_sender_link_ = std::make_unique<simulator::SymmetricLink>(
- &quic_sender_, switch_->port(1), kLocalLinkBandwidth,
- kLocalPropagationDelay);
- receiver_link_ = std::make_unique<simulator::SymmetricLink>(
- &receiver_, switch_->port(2), test_bandwidth, test_link_delay);
- }
-
- void DoSimpleTransfer(QuicByteCount transfer_size, QuicTime::Delta deadline) {
- quic_sender_.AddBytesToTransfer(transfer_size);
- bool simulator_result = simulator_.RunUntilOrTimeout(
- [this]() { return quic_sender_.bytes_to_transfer() == 0; }, deadline);
- EXPECT_TRUE(simulator_result)
- << "Simple transfer failed. Bytes remaining: "
- << quic_sender_.bytes_to_transfer();
- }
-
- void SendBursts(size_t number_of_bursts,
- QuicByteCount bytes,
- QuicTime::Delta rtt,
- QuicTime::Delta wait_time) {
- ASSERT_EQ(0u, quic_sender_.bytes_to_transfer());
- for (size_t i = 0; i < number_of_bursts; i++) {
- quic_sender_.AddBytesToTransfer(bytes);
-
- // Transfer data and wait for three seconds between each transfer.
- simulator_.RunFor(wait_time);
-
- // Ensure the connection did not time out.
- ASSERT_TRUE(quic_sender_.connection()->connected());
- ASSERT_TRUE(receiver_.connection()->connected());
- }
-
- simulator_.RunFor(wait_time + rtt);
- EXPECT_EQ(0u, quic_sender_.bytes_to_transfer());
- }
-
- // Estimates the elapsed time for a given transfer size, given the
- // bottleneck bandwidth and link propagation delay.
- QuicTime::Delta EstimatedElapsedTime(
- QuicByteCount transfer_size_bytes,
- QuicBandwidth test_link_bandwidth,
- const QuicTime::Delta& test_link_delay) const {
- return test_link_bandwidth.TransferTime(transfer_size_bytes) +
- 2 * test_link_delay;
- }
-
- QuicTime QuicSenderStartTime() {
- return quic_sender_.connection()->GetStats().connection_creation_time;
- }
-
- void PrintTransferStats() {
- const QuicConnectionStats& stats = quic_sender_.connection()->GetStats();
- QUIC_LOG(INFO) << "Summary for scenario " << GetParam();
- QUIC_LOG(INFO) << "Sender stats is " << stats;
- const double rtx_rate =
- static_cast<double>(stats.bytes_retransmitted) / stats.bytes_sent;
- QUIC_LOG(INFO) << "Retransmit rate (num_rtx/num_total_sent): " << rtx_rate;
- QUIC_LOG(INFO) << "Connection elapsed time: "
- << (clock_->Now() - QuicSenderStartTime()).ToMilliseconds()
- << " (ms)";
- }
-
- simulator::Simulator simulator_;
- simulator::QuicEndpoint quic_sender_;
- simulator::QuicEndpoint receiver_;
- std::unique_ptr<simulator::Switch> switch_;
- std::unique_ptr<simulator::SymmetricLink> quic_sender_link_;
- std::unique_ptr<simulator::SymmetricLink> receiver_link_;
- QuicConnectionStats stats_;
-
- SimpleRandom random_;
-
- // Owned by different components of the connection.
- const QuicClock* clock_;
- const RttStats* rtt_stats_;
- SendAlgorithmInterface* sender_;
-};
-
-INSTANTIATE_TEST_SUITE_P(SendAlgorithmTests,
- SendAlgorithmTest,
- ::testing::ValuesIn(GetTestParams()),
- TestParamToString);
-
-// Test a simple long data transfer in the default setup.
-TEST_P(SendAlgorithmTest, SimpleWiredNetworkTransfer) {
- CreateSetup(kTestLinkWiredBandwidth, kTestLinkWiredPropagationDelay,
- kTestWiredBdp);
- const QuicByteCount kTransferSizeBytes = 12 * 1024 * 1024;
- const QuicTime::Delta maximum_elapsed_time =
- EstimatedElapsedTime(kTransferSizeBytes, kTestLinkWiredBandwidth,
- kTestLinkWiredPropagationDelay) *
- 1.2;
- DoSimpleTransfer(kTransferSizeBytes, maximum_elapsed_time);
- PrintTransferStats();
-}
-
-TEST_P(SendAlgorithmTest, LowBdpPolicedNetworkTransfer) {
- CreateSetup(kTestLinkLowBdpBandwidth, kTestLinkLowBdpPropagationDelay,
- kTestPolicerQueue);
- const QuicByteCount kTransferSizeBytes = 5 * 1024 * 1024;
- const QuicTime::Delta maximum_elapsed_time =
- EstimatedElapsedTime(kTransferSizeBytes, kTestLinkLowBdpBandwidth,
- kTestLinkLowBdpPropagationDelay) *
- 1.2;
- DoSimpleTransfer(kTransferSizeBytes, maximum_elapsed_time);
- PrintTransferStats();
-}
-
-TEST_P(SendAlgorithmTest, AppLimitedBurstsOverWiredNetwork) {
- CreateSetup(kTestLinkWiredBandwidth, kTestLinkWiredPropagationDelay,
- kTestWiredBdp);
- const QuicByteCount kBurstSizeBytes = 512;
- const int kNumBursts = 20;
- const QuicTime::Delta kWaitTime = QuicTime::Delta::FromSeconds(3);
- SendBursts(kNumBursts, kBurstSizeBytes, kTestWiredRtt, kWaitTime);
- PrintTransferStats();
-
- const QuicTime::Delta estimated_burst_time =
- EstimatedElapsedTime(kBurstSizeBytes, kTestLinkWiredBandwidth,
- kTestLinkWiredPropagationDelay) +
- kWaitTime;
- const QuicTime::Delta max_elapsed_time =
- kNumBursts * estimated_burst_time + kWaitTime;
- const QuicTime::Delta actual_elapsed_time =
- clock_->Now() - QuicSenderStartTime();
- EXPECT_GE(max_elapsed_time, actual_elapsed_time);
-}
-
-TEST_P(SendAlgorithmTest, SatelliteNetworkTransfer) {
- CreateSetup(kTestLinkWiredBandwidth, kTestSatellitePropagationDelay,
- kTestWiredBdp);
- const QuicByteCount kTransferSizeBytes = 12 * 1024 * 1024;
- const QuicTime::Delta maximum_elapsed_time =
- EstimatedElapsedTime(kTransferSizeBytes, kTestLinkWiredBandwidth,
- kTestSatellitePropagationDelay) *
- 1.25;
- DoSimpleTransfer(kTransferSizeBytes, maximum_elapsed_time);
- PrintTransferStats();
-}
-
-TEST_P(SendAlgorithmTest, 2GNetworkTransfer) {
- CreateSetup(kTestLink2GBandwidth, kTestCellularPropagationDelay,
- kCellularQueue);
- const QuicByteCount kTransferSizeBytes = 1024 * 1024;
- const QuicTime::Delta maximum_elapsed_time =
- EstimatedElapsedTime(kTransferSizeBytes, kTestLink2GBandwidth,
- kTestCellularPropagationDelay) *
- 1.2;
- DoSimpleTransfer(kTransferSizeBytes, maximum_elapsed_time);
- PrintTransferStats();
-}
-
-TEST_P(SendAlgorithmTest, 3GNetworkTransfer) {
- CreateSetup(kTestLink3GBandwidth, kTestCellularPropagationDelay,
- kCellularQueue);
- const QuicByteCount kTransferSizeBytes = 5 * 1024 * 1024;
- const QuicTime::Delta maximum_elapsed_time =
- EstimatedElapsedTime(kTransferSizeBytes, kTestLink3GBandwidth,
- kTestCellularPropagationDelay) *
- 1.2;
- DoSimpleTransfer(kTransferSizeBytes, maximum_elapsed_time);
- PrintTransferStats();
-}
-
-TEST_P(SendAlgorithmTest, LowRTTTransfer) {
- CreateSetup(kTestLinkWiredBandwidth, kTestLinkSmallRTTDelay, kCellularQueue);
-
- const QuicByteCount kTransferSizeBytes = 12 * 1024 * 1024;
- const QuicTime::Delta maximum_elapsed_time =
- EstimatedElapsedTime(kTransferSizeBytes, kTestLinkWiredBandwidth,
- kTestLinkSmallRTTDelay) *
- 1.2;
- DoSimpleTransfer(kTransferSizeBytes, maximum_elapsed_time);
- PrintTransferStats();
-}
-
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/congestion_control/tcp_cubic_sender_bytes.cc b/chromium/net/third_party/quiche/src/quic/core/congestion_control/tcp_cubic_sender_bytes.cc
deleted file mode 100644
index 562da98c414..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/congestion_control/tcp_cubic_sender_bytes.cc
+++ /dev/null
@@ -1,431 +0,0 @@
-// Copyright (c) 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/congestion_control/tcp_cubic_sender_bytes.h"
-
-#include <algorithm>
-#include <cstdint>
-#include <string>
-
-#include "quic/core/congestion_control/prr_sender.h"
-#include "quic/core/congestion_control/rtt_stats.h"
-#include "quic/core/crypto/crypto_protocol.h"
-#include "quic/core/quic_constants.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-namespace {
-// Constants based on TCP defaults.
-const QuicByteCount kMaxBurstBytes = 3 * kDefaultTCPMSS;
-const float kRenoBeta = 0.7f; // Reno backoff factor.
-// The minimum cwnd based on RFC 3782 (TCP NewReno) for cwnd reductions on a
-// fast retransmission.
-const QuicByteCount kDefaultMinimumCongestionWindow = 2 * kDefaultTCPMSS;
-} // namespace
-
-TcpCubicSenderBytes::TcpCubicSenderBytes(
- const QuicClock* clock,
- const RttStats* rtt_stats,
- bool reno,
- QuicPacketCount initial_tcp_congestion_window,
- QuicPacketCount max_congestion_window,
- QuicConnectionStats* stats)
- : rtt_stats_(rtt_stats),
- stats_(stats),
- reno_(reno),
- num_connections_(kDefaultNumConnections),
- min4_mode_(false),
- last_cutback_exited_slowstart_(false),
- slow_start_large_reduction_(false),
- no_prr_(false),
- cubic_(clock),
- num_acked_packets_(0),
- congestion_window_(initial_tcp_congestion_window * kDefaultTCPMSS),
- min_congestion_window_(kDefaultMinimumCongestionWindow),
- max_congestion_window_(max_congestion_window * kDefaultTCPMSS),
- slowstart_threshold_(max_congestion_window * kDefaultTCPMSS),
- initial_tcp_congestion_window_(initial_tcp_congestion_window *
- kDefaultTCPMSS),
- initial_max_tcp_congestion_window_(max_congestion_window *
- kDefaultTCPMSS),
- min_slow_start_exit_window_(min_congestion_window_) {}
-
-TcpCubicSenderBytes::~TcpCubicSenderBytes() {}
-
-void TcpCubicSenderBytes::SetFromConfig(const QuicConfig& config,
- Perspective perspective) {
- if (perspective == Perspective::IS_SERVER) {
- if (!GetQuicReloadableFlag(quic_unified_iw_options)) {
- if (config.HasReceivedConnectionOptions() &&
- ContainsQuicTag(config.ReceivedConnectionOptions(), kIW03)) {
- // Initial window experiment.
- SetInitialCongestionWindowInPackets(3);
- }
- if (config.HasReceivedConnectionOptions() &&
- ContainsQuicTag(config.ReceivedConnectionOptions(), kIW10)) {
- // Initial window experiment.
- SetInitialCongestionWindowInPackets(10);
- }
- if (config.HasReceivedConnectionOptions() &&
- ContainsQuicTag(config.ReceivedConnectionOptions(), kIW20)) {
- // Initial window experiment.
- SetInitialCongestionWindowInPackets(20);
- }
- if (config.HasReceivedConnectionOptions() &&
- ContainsQuicTag(config.ReceivedConnectionOptions(), kIW50)) {
- // Initial window experiment.
- SetInitialCongestionWindowInPackets(50);
- }
- if (config.HasReceivedConnectionOptions() &&
- ContainsQuicTag(config.ReceivedConnectionOptions(), kMIN1)) {
- // Min CWND experiment.
- SetMinCongestionWindowInPackets(1);
- }
- }
- if (config.HasReceivedConnectionOptions() &&
- ContainsQuicTag(config.ReceivedConnectionOptions(), kMIN4)) {
- // Min CWND of 4 experiment.
- min4_mode_ = true;
- SetMinCongestionWindowInPackets(1);
- }
- if (config.HasReceivedConnectionOptions() &&
- ContainsQuicTag(config.ReceivedConnectionOptions(), kSSLR)) {
- // Slow Start Fast Exit experiment.
- slow_start_large_reduction_ = true;
- }
- if (config.HasReceivedConnectionOptions() &&
- ContainsQuicTag(config.ReceivedConnectionOptions(), kNPRR)) {
- // Use unity pacing instead of PRR.
- no_prr_ = true;
- }
- }
-}
-
-void TcpCubicSenderBytes::AdjustNetworkParameters(const NetworkParams& params) {
- if (params.bandwidth.IsZero() || params.rtt.IsZero()) {
- return;
- }
- SetCongestionWindowFromBandwidthAndRtt(params.bandwidth, params.rtt);
-}
-
-float TcpCubicSenderBytes::RenoBeta() const {
- // kNConnectionBeta is the backoff factor after loss for our N-connection
- // emulation, which emulates the effective backoff of an ensemble of N
- // TCP-Reno connections on a single loss event. The effective multiplier is
- // computed as:
- return (num_connections_ - 1 + kRenoBeta) / num_connections_;
-}
-
-void TcpCubicSenderBytes::OnCongestionEvent(
- bool rtt_updated,
- QuicByteCount prior_in_flight,
- QuicTime event_time,
- const AckedPacketVector& acked_packets,
- const LostPacketVector& lost_packets) {
- if (rtt_updated && InSlowStart() &&
- hybrid_slow_start_.ShouldExitSlowStart(
- rtt_stats_->latest_rtt(), rtt_stats_->min_rtt(),
- GetCongestionWindow() / kDefaultTCPMSS)) {
- ExitSlowstart();
- }
- for (const LostPacket& lost_packet : lost_packets) {
- OnPacketLost(lost_packet.packet_number, lost_packet.bytes_lost,
- prior_in_flight);
- }
- for (const AckedPacket& acked_packet : acked_packets) {
- OnPacketAcked(acked_packet.packet_number, acked_packet.bytes_acked,
- prior_in_flight, event_time);
- }
-}
-
-void TcpCubicSenderBytes::OnPacketAcked(QuicPacketNumber acked_packet_number,
- QuicByteCount acked_bytes,
- QuicByteCount prior_in_flight,
- QuicTime event_time) {
- largest_acked_packet_number_.UpdateMax(acked_packet_number);
- if (InRecovery()) {
- if (!no_prr_) {
- // PRR is used when in recovery.
- prr_.OnPacketAcked(acked_bytes);
- }
- return;
- }
- MaybeIncreaseCwnd(acked_packet_number, acked_bytes, prior_in_flight,
- event_time);
- if (InSlowStart()) {
- hybrid_slow_start_.OnPacketAcked(acked_packet_number);
- }
-}
-
-void TcpCubicSenderBytes::OnPacketSent(
- QuicTime /*sent_time*/,
- QuicByteCount /*bytes_in_flight*/,
- QuicPacketNumber packet_number,
- QuicByteCount bytes,
- HasRetransmittableData is_retransmittable) {
- if (InSlowStart()) {
- ++(stats_->slowstart_packets_sent);
- }
-
- if (is_retransmittable != HAS_RETRANSMITTABLE_DATA) {
- return;
- }
- if (InRecovery()) {
- // PRR is used when in recovery.
- prr_.OnPacketSent(bytes);
- }
- QUICHE_DCHECK(!largest_sent_packet_number_.IsInitialized() ||
- largest_sent_packet_number_ < packet_number);
- largest_sent_packet_number_ = packet_number;
- hybrid_slow_start_.OnPacketSent(packet_number);
-}
-
-bool TcpCubicSenderBytes::CanSend(QuicByteCount bytes_in_flight) {
- if (!no_prr_ && InRecovery()) {
- // PRR is used when in recovery.
- return prr_.CanSend(GetCongestionWindow(), bytes_in_flight,
- GetSlowStartThreshold());
- }
- if (GetCongestionWindow() > bytes_in_flight) {
- return true;
- }
- if (min4_mode_ && bytes_in_flight < 4 * kDefaultTCPMSS) {
- return true;
- }
- return false;
-}
-
-QuicBandwidth TcpCubicSenderBytes::PacingRate(
- QuicByteCount /* bytes_in_flight */) const {
- // We pace at twice the rate of the underlying sender's bandwidth estimate
- // during slow start and 1.25x during congestion avoidance to ensure pacing
- // doesn't prevent us from filling the window.
- QuicTime::Delta srtt = rtt_stats_->SmoothedOrInitialRtt();
- const QuicBandwidth bandwidth =
- QuicBandwidth::FromBytesAndTimeDelta(GetCongestionWindow(), srtt);
- return bandwidth * (InSlowStart() ? 2 : (no_prr_ && InRecovery() ? 1 : 1.25));
-}
-
-QuicBandwidth TcpCubicSenderBytes::BandwidthEstimate() const {
- QuicTime::Delta srtt = rtt_stats_->smoothed_rtt();
- if (srtt.IsZero()) {
- // If we haven't measured an rtt, the bandwidth estimate is unknown.
- return QuicBandwidth::Zero();
- }
- return QuicBandwidth::FromBytesAndTimeDelta(GetCongestionWindow(), srtt);
-}
-
-bool TcpCubicSenderBytes::InSlowStart() const {
- return GetCongestionWindow() < GetSlowStartThreshold();
-}
-
-bool TcpCubicSenderBytes::IsCwndLimited(QuicByteCount bytes_in_flight) const {
- const QuicByteCount congestion_window = GetCongestionWindow();
- if (bytes_in_flight >= congestion_window) {
- return true;
- }
- const QuicByteCount available_bytes = congestion_window - bytes_in_flight;
- const bool slow_start_limited =
- InSlowStart() && bytes_in_flight > congestion_window / 2;
- return slow_start_limited || available_bytes <= kMaxBurstBytes;
-}
-
-bool TcpCubicSenderBytes::InRecovery() const {
- return largest_acked_packet_number_.IsInitialized() &&
- largest_sent_at_last_cutback_.IsInitialized() &&
- 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) {
- return;
- }
- hybrid_slow_start_.Restart();
- HandleRetransmissionTimeout();
-}
-
-std::string TcpCubicSenderBytes::GetDebugState() const {
- return "";
-}
-
-void TcpCubicSenderBytes::OnApplicationLimited(
- QuicByteCount /*bytes_in_flight*/) {}
-
-void TcpCubicSenderBytes::SetCongestionWindowFromBandwidthAndRtt(
- QuicBandwidth bandwidth,
- QuicTime::Delta rtt) {
- QuicByteCount new_congestion_window = bandwidth.ToBytesPerPeriod(rtt);
- // Limit new CWND if needed.
- congestion_window_ =
- std::max(min_congestion_window_,
- std::min(new_congestion_window,
- kMaxResumptionCongestionWindow * kDefaultTCPMSS));
-}
-
-void TcpCubicSenderBytes::SetInitialCongestionWindowInPackets(
- QuicPacketCount congestion_window) {
- congestion_window_ = congestion_window * kDefaultTCPMSS;
-}
-
-void TcpCubicSenderBytes::SetMinCongestionWindowInPackets(
- QuicPacketCount congestion_window) {
- min_congestion_window_ = congestion_window * kDefaultTCPMSS;
-}
-
-void TcpCubicSenderBytes::SetNumEmulatedConnections(int num_connections) {
- num_connections_ = std::max(1, num_connections);
- cubic_.SetNumConnections(num_connections_);
-}
-
-void TcpCubicSenderBytes::ExitSlowstart() {
- slowstart_threshold_ = congestion_window_;
-}
-
-void TcpCubicSenderBytes::OnPacketLost(QuicPacketNumber packet_number,
- QuicByteCount lost_bytes,
- QuicByteCount prior_in_flight) {
- // TCP NewReno (RFC6582) says that once a loss occurs, any losses in packets
- // already sent should be treated as a single loss event, since it's expected.
- if (largest_sent_at_last_cutback_.IsInitialized() &&
- packet_number <= largest_sent_at_last_cutback_) {
- if (last_cutback_exited_slowstart_) {
- ++stats_->slowstart_packets_lost;
- stats_->slowstart_bytes_lost += lost_bytes;
- if (slow_start_large_reduction_) {
- // Reduce congestion window by lost_bytes for every loss.
- congestion_window_ = std::max(congestion_window_ - lost_bytes,
- min_slow_start_exit_window_);
- slowstart_threshold_ = congestion_window_;
- }
- }
- QUIC_DVLOG(1) << "Ignoring loss for largest_missing:" << packet_number
- << " because it was sent prior to the last CWND cutback.";
- return;
- }
- ++stats_->tcp_loss_events;
- last_cutback_exited_slowstart_ = InSlowStart();
- if (InSlowStart()) {
- ++stats_->slowstart_packets_lost;
- }
-
- if (!no_prr_) {
- prr_.OnPacketLost(prior_in_flight);
- }
-
- // TODO(b/77268641): Separate out all of slow start into a separate class.
- if (slow_start_large_reduction_ && InSlowStart()) {
- QUICHE_DCHECK_LT(kDefaultTCPMSS, congestion_window_);
- if (congestion_window_ >= 2 * initial_tcp_congestion_window_) {
- min_slow_start_exit_window_ = congestion_window_ / 2;
- }
- congestion_window_ = congestion_window_ - kDefaultTCPMSS;
- } else if (reno_) {
- congestion_window_ = congestion_window_ * RenoBeta();
- } else {
- congestion_window_ =
- cubic_.CongestionWindowAfterPacketLoss(congestion_window_);
- }
- if (congestion_window_ < min_congestion_window_) {
- congestion_window_ = min_congestion_window_;
- }
- slowstart_threshold_ = congestion_window_;
- largest_sent_at_last_cutback_ = largest_sent_packet_number_;
- // Reset packet count from congestion avoidance mode. We start counting again
- // when we're out of recovery.
- num_acked_packets_ = 0;
- QUIC_DVLOG(1) << "Incoming loss; congestion window: " << congestion_window_
- << " slowstart threshold: " << slowstart_threshold_;
-}
-
-QuicByteCount TcpCubicSenderBytes::GetCongestionWindow() const {
- return congestion_window_;
-}
-
-QuicByteCount TcpCubicSenderBytes::GetSlowStartThreshold() const {
- return slowstart_threshold_;
-}
-
-// Called when we receive an ack. Normal TCP tracks how many packets one ack
-// represents, but quic has a separate ack for each packet.
-void TcpCubicSenderBytes::MaybeIncreaseCwnd(
- QuicPacketNumber /*acked_packet_number*/,
- QuicByteCount acked_bytes,
- QuicByteCount prior_in_flight,
- QuicTime event_time) {
- QUIC_BUG_IF(quic_bug_10439_1, InRecovery())
- << "Never increase the CWND during recovery.";
- // Do not increase the congestion window unless the sender is close to using
- // the current window.
- if (!IsCwndLimited(prior_in_flight)) {
- cubic_.OnApplicationLimited();
- return;
- }
- if (congestion_window_ >= max_congestion_window_) {
- return;
- }
- if (InSlowStart()) {
- // TCP slow start, exponential growth, increase by one for each ACK.
- congestion_window_ += kDefaultTCPMSS;
- QUIC_DVLOG(1) << "Slow start; congestion window: " << congestion_window_
- << " slowstart threshold: " << slowstart_threshold_;
- return;
- }
- // Congestion avoidance.
- if (reno_) {
- // Classic Reno congestion avoidance.
- ++num_acked_packets_;
- // Divide by num_connections to smoothly increase the CWND at a faster rate
- // than conventional Reno.
- if (num_acked_packets_ * num_connections_ >=
- congestion_window_ / kDefaultTCPMSS) {
- congestion_window_ += kDefaultTCPMSS;
- num_acked_packets_ = 0;
- }
-
- QUIC_DVLOG(1) << "Reno; congestion window: " << congestion_window_
- << " slowstart threshold: " << slowstart_threshold_
- << " congestion window count: " << num_acked_packets_;
- } else {
- congestion_window_ = std::min(
- max_congestion_window_,
- cubic_.CongestionWindowAfterAck(acked_bytes, congestion_window_,
- rtt_stats_->min_rtt(), event_time));
- QUIC_DVLOG(1) << "Cubic; congestion window: " << congestion_window_
- << " slowstart threshold: " << slowstart_threshold_;
- }
-}
-
-void TcpCubicSenderBytes::HandleRetransmissionTimeout() {
- cubic_.ResetCubicState();
- slowstart_threshold_ = congestion_window_ / 2;
- congestion_window_ = min_congestion_window_;
-}
-
-void TcpCubicSenderBytes::OnConnectionMigration() {
- hybrid_slow_start_.Restart();
- prr_ = PrrSender();
- largest_sent_packet_number_.Clear();
- largest_acked_packet_number_.Clear();
- largest_sent_at_last_cutback_.Clear();
- last_cutback_exited_slowstart_ = false;
- cubic_.ResetCubicState();
- num_acked_packets_ = 0;
- congestion_window_ = initial_tcp_congestion_window_;
- max_congestion_window_ = initial_max_tcp_congestion_window_;
- slowstart_threshold_ = initial_max_tcp_congestion_window_;
-}
-
-CongestionControlType TcpCubicSenderBytes::GetCongestionControlType() const {
- return reno_ ? kRenoBytes : kCubicBytes;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/congestion_control/tcp_cubic_sender_bytes.h b/chromium/net/third_party/quiche/src/quic/core/congestion_control/tcp_cubic_sender_bytes.h
deleted file mode 100644
index be4d2b2ad8d..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/congestion_control/tcp_cubic_sender_bytes.h
+++ /dev/null
@@ -1,174 +0,0 @@
-// Copyright (c) 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// TCP cubic send side congestion algorithm, emulates the behavior of TCP cubic.
-
-#ifndef QUICHE_QUIC_CORE_CONGESTION_CONTROL_TCP_CUBIC_SENDER_BYTES_H_
-#define QUICHE_QUIC_CORE_CONGESTION_CONTROL_TCP_CUBIC_SENDER_BYTES_H_
-
-#include <cstdint>
-#include <string>
-
-#include "quic/core/congestion_control/cubic_bytes.h"
-#include "quic/core/congestion_control/hybrid_slow_start.h"
-#include "quic/core/congestion_control/prr_sender.h"
-#include "quic/core/congestion_control/send_algorithm_interface.h"
-#include "quic/core/quic_bandwidth.h"
-#include "quic/core/quic_connection_stats.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_time.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-class RttStats;
-
-// Maximum window to allow when doing bandwidth resumption.
-const QuicPacketCount kMaxResumptionCongestionWindow = 200;
-
-namespace test {
-class TcpCubicSenderBytesPeer;
-} // namespace test
-
-class QUIC_EXPORT_PRIVATE TcpCubicSenderBytes : public SendAlgorithmInterface {
- public:
- TcpCubicSenderBytes(const QuicClock* clock,
- const RttStats* rtt_stats,
- bool reno,
- QuicPacketCount initial_tcp_congestion_window,
- QuicPacketCount max_congestion_window,
- QuicConnectionStats* stats);
- TcpCubicSenderBytes(const TcpCubicSenderBytes&) = delete;
- TcpCubicSenderBytes& operator=(const TcpCubicSenderBytes&) = delete;
- ~TcpCubicSenderBytes() override;
-
- // Start implementation of SendAlgorithmInterface.
- void SetFromConfig(const QuicConfig& config,
- Perspective perspective) override;
- void ApplyConnectionOptions(
- const QuicTagVector& /*connection_options*/) override {}
- void AdjustNetworkParameters(const NetworkParams& params) override;
- void SetNumEmulatedConnections(int num_connections);
- void SetInitialCongestionWindowInPackets(
- QuicPacketCount congestion_window) override;
- void OnConnectionMigration() override;
- void OnCongestionEvent(bool rtt_updated,
- QuicByteCount prior_in_flight,
- QuicTime event_time,
- const AckedPacketVector& acked_packets,
- const LostPacketVector& lost_packets) override;
- void OnPacketSent(QuicTime sent_time,
- QuicByteCount bytes_in_flight,
- QuicPacketNumber packet_number,
- QuicByteCount bytes,
- HasRetransmittableData is_retransmittable) override;
- void OnPacketNeutered(QuicPacketNumber /*packet_number*/) override {}
- void OnRetransmissionTimeout(bool packets_retransmitted) override;
- bool CanSend(QuicByteCount bytes_in_flight) override;
- QuicBandwidth PacingRate(QuicByteCount bytes_in_flight) const override;
- QuicBandwidth BandwidthEstimate() const override;
- QuicByteCount GetCongestionWindow() const override;
- QuicByteCount GetSlowStartThreshold() const override;
- CongestionControlType GetCongestionControlType() const override;
- bool InSlowStart() const override;
- bool InRecovery() const override;
- bool ShouldSendProbingPacket() const override;
- std::string GetDebugState() const override;
- void OnApplicationLimited(QuicByteCount bytes_in_flight) override;
- void PopulateConnectionStats(QuicConnectionStats* /*stats*/) const override {}
- // End implementation of SendAlgorithmInterface.
-
- QuicByteCount min_congestion_window() const { return min_congestion_window_; }
-
- protected:
- // Compute the TCP Reno beta based on the current number of connections.
- float RenoBeta() const;
-
- bool IsCwndLimited(QuicByteCount bytes_in_flight) const;
-
- // TODO(ianswett): Remove these and migrate to OnCongestionEvent.
- void OnPacketAcked(QuicPacketNumber acked_packet_number,
- QuicByteCount acked_bytes,
- QuicByteCount prior_in_flight,
- QuicTime event_time);
- void SetCongestionWindowFromBandwidthAndRtt(QuicBandwidth bandwidth,
- QuicTime::Delta rtt);
- void SetMinCongestionWindowInPackets(QuicPacketCount congestion_window);
- void ExitSlowstart();
- void OnPacketLost(QuicPacketNumber packet_number, QuicByteCount lost_bytes,
- QuicByteCount prior_in_flight);
- void MaybeIncreaseCwnd(QuicPacketNumber acked_packet_number,
- QuicByteCount acked_bytes,
- QuicByteCount prior_in_flight,
- QuicTime event_time);
- void HandleRetransmissionTimeout();
-
- private:
- friend class test::TcpCubicSenderBytesPeer;
-
- HybridSlowStart hybrid_slow_start_;
- PrrSender prr_;
- const RttStats* rtt_stats_;
- QuicConnectionStats* stats_;
-
- // If true, Reno congestion control is used instead of Cubic.
- const bool reno_;
-
- // Number of connections to simulate.
- uint32_t num_connections_;
-
- // Track the largest packet that has been sent.
- QuicPacketNumber largest_sent_packet_number_;
-
- // Track the largest packet that has been acked.
- QuicPacketNumber largest_acked_packet_number_;
-
- // Track the largest packet number outstanding when a CWND cutback occurs.
- QuicPacketNumber largest_sent_at_last_cutback_;
-
- // Whether to use 4 packets as the actual min, but pace lower.
- bool min4_mode_;
-
- // Whether the last loss event caused us to exit slowstart.
- // Used for stats collection of slowstart_packets_lost
- bool last_cutback_exited_slowstart_;
-
- // When true, exit slow start with large cutback of congestion window.
- bool slow_start_large_reduction_;
-
- // When true, use unity pacing instead of PRR.
- bool no_prr_;
-
- CubicBytes cubic_;
-
- // ACK counter for the Reno implementation.
- uint64_t num_acked_packets_;
-
- // Congestion window in bytes.
- QuicByteCount congestion_window_;
-
- // Minimum congestion window in bytes.
- QuicByteCount min_congestion_window_;
-
- // Maximum congestion window in bytes.
- QuicByteCount max_congestion_window_;
-
- // Slow start congestion window in bytes, aka ssthresh.
- QuicByteCount slowstart_threshold_;
-
- // Initial TCP congestion window in bytes. This variable can only be set when
- // this algorithm is created.
- const QuicByteCount initial_tcp_congestion_window_;
-
- // Initial maximum TCP congestion window in bytes. This variable can only be
- // set when this algorithm is created.
- const QuicByteCount initial_max_tcp_congestion_window_;
-
- // The minimum window when exiting slow start with large reduction.
- QuicByteCount min_slow_start_exit_window_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_CONGESTION_CONTROL_TCP_CUBIC_SENDER_BYTES_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/congestion_control/tcp_cubic_sender_bytes_test.cc b/chromium/net/third_party/quiche/src/quic/core/congestion_control/tcp_cubic_sender_bytes_test.cc
deleted file mode 100644
index 6ef746d0a33..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/congestion_control/tcp_cubic_sender_bytes_test.cc
+++ /dev/null
@@ -1,845 +0,0 @@
-// Copyright (c) 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/congestion_control/tcp_cubic_sender_bytes.h"
-
-#include <algorithm>
-#include <cstdint>
-#include <memory>
-#include <utility>
-
-#include "quic/core/congestion_control/rtt_stats.h"
-#include "quic/core/congestion_control/send_algorithm_interface.h"
-#include "quic/core/crypto/crypto_protocol.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/mock_clock.h"
-#include "quic/test_tools/quic_config_peer.h"
-
-namespace quic {
-namespace test {
-
-// TODO(ianswett): A number of theses tests were written with the assumption of
-// an initial CWND of 10. They have carefully calculated values which should be
-// updated to be based on kInitialCongestionWindow.
-const uint32_t kInitialCongestionWindowPackets = 10;
-const uint32_t kMaxCongestionWindowPackets = 200;
-const uint32_t kDefaultWindowTCP =
- kInitialCongestionWindowPackets * kDefaultTCPMSS;
-const float kRenoBeta = 0.7f; // Reno backoff factor.
-
-class TcpCubicSenderBytesPeer : public TcpCubicSenderBytes {
- public:
- TcpCubicSenderBytesPeer(const QuicClock* clock, bool reno)
- : TcpCubicSenderBytes(clock,
- &rtt_stats_,
- reno,
- kInitialCongestionWindowPackets,
- kMaxCongestionWindowPackets,
- &stats_) {}
-
- const HybridSlowStart& hybrid_slow_start() const {
- return hybrid_slow_start_;
- }
-
- float GetRenoBeta() const { return RenoBeta(); }
-
- RttStats rtt_stats_;
- QuicConnectionStats stats_;
-};
-
-class TcpCubicSenderBytesTest : public QuicTest {
- protected:
- TcpCubicSenderBytesTest()
- : one_ms_(QuicTime::Delta::FromMilliseconds(1)),
- sender_(new TcpCubicSenderBytesPeer(&clock_, true)),
- packet_number_(1),
- acked_packet_number_(0),
- bytes_in_flight_(0) {}
-
- int SendAvailableSendWindow() {
- return SendAvailableSendWindow(kDefaultTCPMSS);
- }
-
- int SendAvailableSendWindow(QuicPacketLength /*packet_length*/) {
- // Send as long as TimeUntilSend returns Zero.
- int packets_sent = 0;
- bool can_send = sender_->CanSend(bytes_in_flight_);
- while (can_send) {
- sender_->OnPacketSent(clock_.Now(), bytes_in_flight_,
- QuicPacketNumber(packet_number_++), kDefaultTCPMSS,
- HAS_RETRANSMITTABLE_DATA);
- ++packets_sent;
- bytes_in_flight_ += kDefaultTCPMSS;
- can_send = sender_->CanSend(bytes_in_flight_);
- }
- return packets_sent;
- }
-
- // Normal is that TCP acks every other segment.
- void AckNPackets(int n) {
- sender_->rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(60),
- QuicTime::Delta::Zero(), clock_.Now());
- AckedPacketVector acked_packets;
- LostPacketVector lost_packets;
- for (int i = 0; i < n; ++i) {
- ++acked_packet_number_;
- acked_packets.push_back(
- AckedPacket(QuicPacketNumber(acked_packet_number_), kDefaultTCPMSS,
- QuicTime::Zero()));
- }
- sender_->OnCongestionEvent(true, bytes_in_flight_, clock_.Now(),
- acked_packets, lost_packets);
- bytes_in_flight_ -= n * kDefaultTCPMSS;
- clock_.AdvanceTime(one_ms_);
- }
-
- void LoseNPackets(int n) { LoseNPackets(n, kDefaultTCPMSS); }
-
- void LoseNPackets(int n, QuicPacketLength packet_length) {
- AckedPacketVector acked_packets;
- LostPacketVector lost_packets;
- for (int i = 0; i < n; ++i) {
- ++acked_packet_number_;
- lost_packets.push_back(
- LostPacket(QuicPacketNumber(acked_packet_number_), packet_length));
- }
- sender_->OnCongestionEvent(false, bytes_in_flight_, clock_.Now(),
- acked_packets, lost_packets);
- bytes_in_flight_ -= n * packet_length;
- }
-
- // Does not increment acked_packet_number_.
- void LosePacket(uint64_t packet_number) {
- AckedPacketVector acked_packets;
- LostPacketVector lost_packets;
- lost_packets.push_back(
- LostPacket(QuicPacketNumber(packet_number), kDefaultTCPMSS));
- sender_->OnCongestionEvent(false, bytes_in_flight_, clock_.Now(),
- acked_packets, lost_packets);
- bytes_in_flight_ -= kDefaultTCPMSS;
- }
-
- const QuicTime::Delta one_ms_;
- MockClock clock_;
- std::unique_ptr<TcpCubicSenderBytesPeer> sender_;
- uint64_t packet_number_;
- uint64_t acked_packet_number_;
- QuicByteCount bytes_in_flight_;
-};
-
-TEST_F(TcpCubicSenderBytesTest, SimpleSender) {
- // At startup make sure we are at the default.
- EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow());
- // At startup make sure we can send.
- EXPECT_TRUE(sender_->CanSend(0));
- // Make sure we can send.
- EXPECT_TRUE(sender_->CanSend(0));
- // And that window is un-affected.
- EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow());
-
- // Fill the send window with data, then verify that we can't send.
- SendAvailableSendWindow();
- EXPECT_FALSE(sender_->CanSend(sender_->GetCongestionWindow()));
-}
-
-TEST_F(TcpCubicSenderBytesTest, ApplicationLimitedSlowStart) {
- // Send exactly 10 packets and ensure the CWND ends at 14 packets.
- const int kNumberOfAcks = 5;
- // At startup make sure we can send.
- EXPECT_TRUE(sender_->CanSend(0));
- // Make sure we can send.
- EXPECT_TRUE(sender_->CanSend(0));
-
- SendAvailableSendWindow();
- for (int i = 0; i < kNumberOfAcks; ++i) {
- AckNPackets(2);
- }
- QuicByteCount bytes_to_send = sender_->GetCongestionWindow();
- // It's expected 2 acks will arrive when the bytes_in_flight are greater than
- // half the CWND.
- EXPECT_EQ(kDefaultWindowTCP + kDefaultTCPMSS * 2 * 2, bytes_to_send);
-}
-
-TEST_F(TcpCubicSenderBytesTest, ExponentialSlowStart) {
- const int kNumberOfAcks = 20;
- // At startup make sure we can send.
- EXPECT_TRUE(sender_->CanSend(0));
- EXPECT_EQ(QuicBandwidth::Zero(), sender_->BandwidthEstimate());
- // Make sure we can send.
- EXPECT_TRUE(sender_->CanSend(0));
-
- for (int i = 0; i < kNumberOfAcks; ++i) {
- // Send our full send window.
- SendAvailableSendWindow();
- AckNPackets(2);
- }
- const QuicByteCount cwnd = sender_->GetCongestionWindow();
- EXPECT_EQ(kDefaultWindowTCP + kDefaultTCPMSS * 2 * kNumberOfAcks, cwnd);
- EXPECT_EQ(QuicBandwidth::FromBytesAndTimeDelta(
- cwnd, sender_->rtt_stats_.smoothed_rtt()),
- sender_->BandwidthEstimate());
-}
-
-TEST_F(TcpCubicSenderBytesTest, SlowStartPacketLoss) {
- sender_->SetNumEmulatedConnections(1);
- const int kNumberOfAcks = 10;
- for (int i = 0; i < kNumberOfAcks; ++i) {
- // Send our full send window.
- SendAvailableSendWindow();
- AckNPackets(2);
- }
- SendAvailableSendWindow();
- QuicByteCount expected_send_window =
- kDefaultWindowTCP + (kDefaultTCPMSS * 2 * kNumberOfAcks);
- EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-
- // Lose a packet to exit slow start.
- LoseNPackets(1);
- size_t packets_in_recovery_window = expected_send_window / kDefaultTCPMSS;
-
- // We should now have fallen out of slow start with a reduced window.
- expected_send_window *= kRenoBeta;
- EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-
- // Recovery phase. We need to ack every packet in the recovery window before
- // we exit recovery.
- size_t number_of_packets_in_window = expected_send_window / kDefaultTCPMSS;
- QUIC_DLOG(INFO) << "number_packets: " << number_of_packets_in_window;
- AckNPackets(packets_in_recovery_window);
- SendAvailableSendWindow();
- EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-
- // We need to ack an entire window before we increase CWND by 1.
- AckNPackets(number_of_packets_in_window - 2);
- SendAvailableSendWindow();
- EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-
- // Next ack should increase cwnd by 1.
- AckNPackets(1);
- expected_send_window += kDefaultTCPMSS;
- EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-
- // Now RTO and ensure slow start gets reset.
- EXPECT_TRUE(sender_->hybrid_slow_start().started());
- sender_->OnRetransmissionTimeout(true);
- EXPECT_FALSE(sender_->hybrid_slow_start().started());
-}
-
-TEST_F(TcpCubicSenderBytesTest, SlowStartPacketLossWithLargeReduction) {
- QuicConfig config;
- QuicTagVector options;
- options.push_back(kSSLR);
- QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
- sender_->SetFromConfig(config, Perspective::IS_SERVER);
-
- sender_->SetNumEmulatedConnections(1);
- const int kNumberOfAcks = (kDefaultWindowTCP / (2 * kDefaultTCPMSS)) - 1;
- for (int i = 0; i < kNumberOfAcks; ++i) {
- // Send our full send window.
- SendAvailableSendWindow();
- AckNPackets(2);
- }
- SendAvailableSendWindow();
- QuicByteCount expected_send_window =
- kDefaultWindowTCP + (kDefaultTCPMSS * 2 * kNumberOfAcks);
- EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-
- // Lose a packet to exit slow start. We should now have fallen out of
- // slow start with a window reduced by 1.
- LoseNPackets(1);
- expected_send_window -= kDefaultTCPMSS;
- EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-
- // Lose 5 packets in recovery and verify that congestion window is reduced
- // further.
- LoseNPackets(5);
- expected_send_window -= 5 * kDefaultTCPMSS;
- EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
- // Lose another 10 packets and ensure it reduces below half the peak CWND,
- // because we never acked the full IW.
- LoseNPackets(10);
- expected_send_window -= 10 * kDefaultTCPMSS;
- EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-
- size_t packets_in_recovery_window = expected_send_window / kDefaultTCPMSS;
-
- // Recovery phase. We need to ack every packet in the recovery window before
- // we exit recovery.
- size_t number_of_packets_in_window = expected_send_window / kDefaultTCPMSS;
- QUIC_DLOG(INFO) << "number_packets: " << number_of_packets_in_window;
- AckNPackets(packets_in_recovery_window);
- SendAvailableSendWindow();
- EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-
- // We need to ack an entire window before we increase CWND by 1.
- AckNPackets(number_of_packets_in_window - 1);
- SendAvailableSendWindow();
- EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-
- // Next ack should increase cwnd by 1.
- AckNPackets(1);
- expected_send_window += kDefaultTCPMSS;
- EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-
- // Now RTO and ensure slow start gets reset.
- EXPECT_TRUE(sender_->hybrid_slow_start().started());
- sender_->OnRetransmissionTimeout(true);
- EXPECT_FALSE(sender_->hybrid_slow_start().started());
-}
-
-TEST_F(TcpCubicSenderBytesTest, SlowStartHalfPacketLossWithLargeReduction) {
- QuicConfig config;
- QuicTagVector options;
- options.push_back(kSSLR);
- QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
- sender_->SetFromConfig(config, Perspective::IS_SERVER);
-
- sender_->SetNumEmulatedConnections(1);
- const int kNumberOfAcks = 10;
- for (int i = 0; i < kNumberOfAcks; ++i) {
- // Send our full send window in half sized packets.
- SendAvailableSendWindow(kDefaultTCPMSS / 2);
- AckNPackets(2);
- }
- SendAvailableSendWindow(kDefaultTCPMSS / 2);
- QuicByteCount expected_send_window =
- kDefaultWindowTCP + (kDefaultTCPMSS * 2 * kNumberOfAcks);
- EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-
- // Lose a packet to exit slow start. We should now have fallen out of
- // slow start with a window reduced by 1.
- LoseNPackets(1);
- expected_send_window -= kDefaultTCPMSS;
- EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-
- // Lose 10 packets in recovery and verify that congestion window is reduced
- // by 5 packets.
- LoseNPackets(10, kDefaultTCPMSS / 2);
- expected_send_window -= 5 * kDefaultTCPMSS;
- EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-}
-
-TEST_F(TcpCubicSenderBytesTest, SlowStartPacketLossWithMaxHalfReduction) {
- QuicConfig config;
- QuicTagVector options;
- options.push_back(kSSLR);
- QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
- sender_->SetFromConfig(config, Perspective::IS_SERVER);
-
- sender_->SetNumEmulatedConnections(1);
- const int kNumberOfAcks = kInitialCongestionWindowPackets / 2;
- for (int i = 0; i < kNumberOfAcks; ++i) {
- // Send our full send window.
- SendAvailableSendWindow();
- AckNPackets(2);
- }
- SendAvailableSendWindow();
- QuicByteCount expected_send_window =
- kDefaultWindowTCP + (kDefaultTCPMSS * 2 * kNumberOfAcks);
- EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-
- // Lose a packet to exit slow start. We should now have fallen out of
- // slow start with a window reduced by 1.
- LoseNPackets(1);
- expected_send_window -= kDefaultTCPMSS;
- EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-
- // Lose half the outstanding packets in recovery and verify the congestion
- // window is only reduced by a max of half.
- LoseNPackets(kNumberOfAcks * 2);
- expected_send_window -= (kNumberOfAcks * 2 - 1) * kDefaultTCPMSS;
- EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
- LoseNPackets(5);
- EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-}
-
-TEST_F(TcpCubicSenderBytesTest, NoPRRWhenLessThanOnePacketInFlight) {
- SendAvailableSendWindow();
- LoseNPackets(kInitialCongestionWindowPackets - 1);
- AckNPackets(1);
- // PRR will allow 2 packets for every ack during recovery.
- EXPECT_EQ(2, SendAvailableSendWindow());
- // Simulate abandoning all packets by supplying a bytes_in_flight of 0.
- // PRR should now allow a packet to be sent, even though prr's state variables
- // believe it has sent enough packets.
- EXPECT_TRUE(sender_->CanSend(0));
-}
-
-TEST_F(TcpCubicSenderBytesTest, SlowStartPacketLossPRR) {
- sender_->SetNumEmulatedConnections(1);
- // Test based on the first example in RFC6937.
- // Ack 10 packets in 5 acks to raise the CWND to 20, as in the example.
- const int kNumberOfAcks = 5;
- for (int i = 0; i < kNumberOfAcks; ++i) {
- // Send our full send window.
- SendAvailableSendWindow();
- AckNPackets(2);
- }
- SendAvailableSendWindow();
- QuicByteCount expected_send_window =
- kDefaultWindowTCP + (kDefaultTCPMSS * 2 * kNumberOfAcks);
- EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-
- LoseNPackets(1);
-
- // We should now have fallen out of slow start with a reduced window.
- size_t send_window_before_loss = expected_send_window;
- expected_send_window *= kRenoBeta;
- EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-
- // Testing TCP proportional rate reduction.
- // We should send packets paced over the received acks for the remaining
- // outstanding packets. The number of packets before we exit recovery is the
- // original CWND minus the packet that has been lost and the one which
- // triggered the loss.
- size_t remaining_packets_in_recovery =
- send_window_before_loss / kDefaultTCPMSS - 2;
-
- for (size_t i = 0; i < remaining_packets_in_recovery; ++i) {
- AckNPackets(1);
- SendAvailableSendWindow();
- EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
- }
-
- // We need to ack another window before we increase CWND by 1.
- size_t number_of_packets_in_window = expected_send_window / kDefaultTCPMSS;
- for (size_t i = 0; i < number_of_packets_in_window; ++i) {
- AckNPackets(1);
- EXPECT_EQ(1, SendAvailableSendWindow());
- EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
- }
-
- AckNPackets(1);
- expected_send_window += kDefaultTCPMSS;
- EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-}
-
-TEST_F(TcpCubicSenderBytesTest, SlowStartBurstPacketLossPRR) {
- sender_->SetNumEmulatedConnections(1);
- // Test based on the second example in RFC6937, though we also implement
- // forward acknowledgements, so the first two incoming acks will trigger
- // PRR immediately.
- // Ack 20 packets in 10 acks to raise the CWND to 30.
- const int kNumberOfAcks = 10;
- for (int i = 0; i < kNumberOfAcks; ++i) {
- // Send our full send window.
- SendAvailableSendWindow();
- AckNPackets(2);
- }
- SendAvailableSendWindow();
- QuicByteCount expected_send_window =
- kDefaultWindowTCP + (kDefaultTCPMSS * 2 * kNumberOfAcks);
- EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-
- // Lose one more than the congestion window reduction, so that after loss,
- // bytes_in_flight is lesser than the congestion window.
- size_t send_window_after_loss = kRenoBeta * expected_send_window;
- size_t num_packets_to_lose =
- (expected_send_window - send_window_after_loss) / kDefaultTCPMSS + 1;
- LoseNPackets(num_packets_to_lose);
- // Immediately after the loss, ensure at least one packet can be sent.
- // Losses without subsequent acks can occur with timer based loss detection.
- EXPECT_TRUE(sender_->CanSend(bytes_in_flight_));
- AckNPackets(1);
-
- // We should now have fallen out of slow start with a reduced window.
- expected_send_window *= kRenoBeta;
- EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-
- // Only 2 packets should be allowed to be sent, per PRR-SSRB.
- EXPECT_EQ(2, SendAvailableSendWindow());
-
- // Ack the next packet, which triggers another loss.
- LoseNPackets(1);
- AckNPackets(1);
-
- // Send 2 packets to simulate PRR-SSRB.
- EXPECT_EQ(2, SendAvailableSendWindow());
-
- // Ack the next packet, which triggers another loss.
- LoseNPackets(1);
- AckNPackets(1);
-
- // Send 2 packets to simulate PRR-SSRB.
- EXPECT_EQ(2, SendAvailableSendWindow());
-
- // Exit recovery and return to sending at the new rate.
- for (int i = 0; i < kNumberOfAcks; ++i) {
- AckNPackets(1);
- EXPECT_EQ(1, SendAvailableSendWindow());
- }
-}
-
-TEST_F(TcpCubicSenderBytesTest, RTOCongestionWindow) {
- EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow());
- // Expect the window to decrease to the minimum once the RTO fires and slow
- // start threshold to be set to 1/2 of the CWND.
- sender_->OnRetransmissionTimeout(true);
- EXPECT_EQ(2 * kDefaultTCPMSS, sender_->GetCongestionWindow());
- EXPECT_EQ(5u * kDefaultTCPMSS, sender_->GetSlowStartThreshold());
-}
-
-TEST_F(TcpCubicSenderBytesTest, RTOCongestionWindowNoRetransmission) {
- EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow());
-
- // Expect the window to remain unchanged if the RTO fires but no packets are
- // retransmitted.
- sender_->OnRetransmissionTimeout(false);
- EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow());
-}
-
-TEST_F(TcpCubicSenderBytesTest, TcpCubicResetEpochOnQuiescence) {
- const int kMaxCongestionWindow = 50;
- const QuicByteCount kMaxCongestionWindowBytes =
- kMaxCongestionWindow * kDefaultTCPMSS;
- int num_sent = SendAvailableSendWindow();
-
- // Make sure we fall out of slow start.
- QuicByteCount saved_cwnd = sender_->GetCongestionWindow();
- LoseNPackets(1);
- EXPECT_GT(saved_cwnd, sender_->GetCongestionWindow());
-
- // Ack the rest of the outstanding packets to get out of recovery.
- for (int i = 1; i < num_sent; ++i) {
- AckNPackets(1);
- }
- EXPECT_EQ(0u, bytes_in_flight_);
-
- // Send a new window of data and ack all; cubic growth should occur.
- saved_cwnd = sender_->GetCongestionWindow();
- num_sent = SendAvailableSendWindow();
- for (int i = 0; i < num_sent; ++i) {
- AckNPackets(1);
- }
- EXPECT_LT(saved_cwnd, sender_->GetCongestionWindow());
- EXPECT_GT(kMaxCongestionWindowBytes, sender_->GetCongestionWindow());
- EXPECT_EQ(0u, bytes_in_flight_);
-
- // Quiescent time of 100 seconds
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(100000));
-
- // Send new window of data and ack one packet. Cubic epoch should have
- // been reset; ensure cwnd increase is not dramatic.
- saved_cwnd = sender_->GetCongestionWindow();
- SendAvailableSendWindow();
- AckNPackets(1);
- EXPECT_NEAR(saved_cwnd, sender_->GetCongestionWindow(), kDefaultTCPMSS);
- EXPECT_GT(kMaxCongestionWindowBytes, sender_->GetCongestionWindow());
-}
-
-TEST_F(TcpCubicSenderBytesTest, MultipleLossesInOneWindow) {
- SendAvailableSendWindow();
- const QuicByteCount initial_window = sender_->GetCongestionWindow();
- LosePacket(acked_packet_number_ + 1);
- const QuicByteCount post_loss_window = sender_->GetCongestionWindow();
- EXPECT_GT(initial_window, post_loss_window);
- LosePacket(acked_packet_number_ + 3);
- EXPECT_EQ(post_loss_window, sender_->GetCongestionWindow());
- LosePacket(packet_number_ - 1);
- EXPECT_EQ(post_loss_window, sender_->GetCongestionWindow());
-
- // Lose a later packet and ensure the window decreases.
- LosePacket(packet_number_);
- EXPECT_GT(post_loss_window, sender_->GetCongestionWindow());
-}
-
-TEST_F(TcpCubicSenderBytesTest, ConfigureMaxInitialWindow) {
- SetQuicReloadableFlag(quic_unified_iw_options, false);
- QuicConfig config;
-
- // Verify that kCOPT: kIW10 forces the congestion window to the default of 10.
- QuicTagVector options;
- options.push_back(kIW10);
- QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
- sender_->SetFromConfig(config, Perspective::IS_SERVER);
- EXPECT_EQ(10u * kDefaultTCPMSS, sender_->GetCongestionWindow());
-}
-
-TEST_F(TcpCubicSenderBytesTest, SetInitialCongestionWindow) {
- EXPECT_NE(3u * kDefaultTCPMSS, sender_->GetCongestionWindow());
- sender_->SetInitialCongestionWindowInPackets(3);
- EXPECT_EQ(3u * kDefaultTCPMSS, sender_->GetCongestionWindow());
-}
-
-TEST_F(TcpCubicSenderBytesTest, 2ConnectionCongestionAvoidanceAtEndOfRecovery) {
- sender_->SetNumEmulatedConnections(2);
- // Ack 10 packets in 5 acks to raise the CWND to 20.
- const int kNumberOfAcks = 5;
- for (int i = 0; i < kNumberOfAcks; ++i) {
- // Send our full send window.
- SendAvailableSendWindow();
- AckNPackets(2);
- }
- SendAvailableSendWindow();
- QuicByteCount expected_send_window =
- kDefaultWindowTCP + (kDefaultTCPMSS * 2 * kNumberOfAcks);
- EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-
- LoseNPackets(1);
-
- // We should now have fallen out of slow start with a reduced window.
- expected_send_window = expected_send_window * sender_->GetRenoBeta();
- EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-
- // No congestion window growth should occur in recovery phase, i.e., until the
- // currently outstanding 20 packets are acked.
- for (int i = 0; i < 10; ++i) {
- // Send our full send window.
- SendAvailableSendWindow();
- EXPECT_TRUE(sender_->InRecovery());
- AckNPackets(2);
- EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
- }
- EXPECT_FALSE(sender_->InRecovery());
-
- // Out of recovery now. Congestion window should not grow for half an RTT.
- size_t packets_in_send_window = expected_send_window / kDefaultTCPMSS;
- SendAvailableSendWindow();
- AckNPackets(packets_in_send_window / 2 - 2);
- EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-
- // Next ack should increase congestion window by 1MSS.
- SendAvailableSendWindow();
- AckNPackets(2);
- expected_send_window += kDefaultTCPMSS;
- packets_in_send_window += 1;
- EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-
- // Congestion window should remain steady again for half an RTT.
- SendAvailableSendWindow();
- AckNPackets(packets_in_send_window / 2 - 1);
- EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-
- // Next ack should cause congestion window to grow by 1MSS.
- SendAvailableSendWindow();
- AckNPackets(2);
- expected_send_window += kDefaultTCPMSS;
- EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-}
-
-TEST_F(TcpCubicSenderBytesTest, 1ConnectionCongestionAvoidanceAtEndOfRecovery) {
- sender_->SetNumEmulatedConnections(1);
- // Ack 10 packets in 5 acks to raise the CWND to 20.
- const int kNumberOfAcks = 5;
- for (int i = 0; i < kNumberOfAcks; ++i) {
- // Send our full send window.
- SendAvailableSendWindow();
- AckNPackets(2);
- }
- SendAvailableSendWindow();
- QuicByteCount expected_send_window =
- kDefaultWindowTCP + (kDefaultTCPMSS * 2 * kNumberOfAcks);
- EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-
- LoseNPackets(1);
-
- // We should now have fallen out of slow start with a reduced window.
- expected_send_window *= kRenoBeta;
- EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-
- // No congestion window growth should occur in recovery phase, i.e., until the
- // currently outstanding 20 packets are acked.
- for (int i = 0; i < 10; ++i) {
- // Send our full send window.
- SendAvailableSendWindow();
- EXPECT_TRUE(sender_->InRecovery());
- AckNPackets(2);
- EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
- }
- EXPECT_FALSE(sender_->InRecovery());
-
- // Out of recovery now. Congestion window should not grow during RTT.
- for (uint64_t i = 0; i < expected_send_window / kDefaultTCPMSS - 2; i += 2) {
- // Send our full send window.
- SendAvailableSendWindow();
- AckNPackets(2);
- EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
- }
-
- // Next ack should cause congestion window to grow by 1MSS.
- SendAvailableSendWindow();
- AckNPackets(2);
- expected_send_window += kDefaultTCPMSS;
- EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-}
-
-TEST_F(TcpCubicSenderBytesTest, BandwidthResumption) {
- // Test that when provided with CachedNetworkParameters and opted in to the
- // bandwidth resumption experiment, that the TcpCubicSenderPackets sets
- // initial CWND appropriately.
-
- // Set some common values.
- const QuicPacketCount kNumberOfPackets = 123;
- const QuicBandwidth kBandwidthEstimate =
- QuicBandwidth::FromBytesPerSecond(kNumberOfPackets * kDefaultTCPMSS);
- const QuicTime::Delta kRttEstimate = QuicTime::Delta::FromSeconds(1);
-
- SendAlgorithmInterface::NetworkParams network_param;
- network_param.bandwidth = kBandwidthEstimate;
- network_param.rtt = kRttEstimate;
- sender_->AdjustNetworkParameters(network_param);
- EXPECT_EQ(kNumberOfPackets * kDefaultTCPMSS, sender_->GetCongestionWindow());
-
- // Resume with an illegal value of 0 and verify the server ignores it.
- SendAlgorithmInterface::NetworkParams network_param_no_bandwidth;
- network_param_no_bandwidth.bandwidth = QuicBandwidth::Zero();
- network_param_no_bandwidth.rtt = kRttEstimate;
- sender_->AdjustNetworkParameters(network_param_no_bandwidth);
- EXPECT_EQ(kNumberOfPackets * kDefaultTCPMSS, sender_->GetCongestionWindow());
-
- // Resumed CWND is limited to be in a sensible range.
- const QuicBandwidth kUnreasonableBandwidth =
- QuicBandwidth::FromBytesPerSecond((kMaxResumptionCongestionWindow + 1) *
- kDefaultTCPMSS);
- SendAlgorithmInterface::NetworkParams network_param_large_bandwidth;
- network_param_large_bandwidth.bandwidth = kUnreasonableBandwidth;
- network_param_large_bandwidth.rtt = QuicTime::Delta::FromSeconds(1);
- sender_->AdjustNetworkParameters(network_param_large_bandwidth);
- EXPECT_EQ(kMaxResumptionCongestionWindow * kDefaultTCPMSS,
- sender_->GetCongestionWindow());
-}
-
-TEST_F(TcpCubicSenderBytesTest, PaceBelowCWND) {
- QuicConfig config;
-
- // Verify that kCOPT: kMIN4 forces the min CWND to 1 packet, but allows up
- // to 4 to be sent.
- QuicTagVector options;
- options.push_back(kMIN4);
- QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
- sender_->SetFromConfig(config, Perspective::IS_SERVER);
- sender_->OnRetransmissionTimeout(true);
- EXPECT_EQ(kDefaultTCPMSS, sender_->GetCongestionWindow());
- EXPECT_TRUE(sender_->CanSend(kDefaultTCPMSS));
- EXPECT_TRUE(sender_->CanSend(2 * kDefaultTCPMSS));
- EXPECT_TRUE(sender_->CanSend(3 * kDefaultTCPMSS));
- EXPECT_FALSE(sender_->CanSend(4 * kDefaultTCPMSS));
-}
-
-TEST_F(TcpCubicSenderBytesTest, NoPRR) {
- QuicTime::Delta rtt = QuicTime::Delta::FromMilliseconds(100);
- sender_->rtt_stats_.UpdateRtt(rtt, QuicTime::Delta::Zero(), QuicTime::Zero());
-
- sender_->SetNumEmulatedConnections(1);
- // Verify that kCOPT: kNPRR allows all packets to be sent, even if only one
- // ack has been received.
- QuicTagVector options;
- options.push_back(kNPRR);
- QuicConfig config;
- QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
- sender_->SetFromConfig(config, Perspective::IS_SERVER);
- SendAvailableSendWindow();
- LoseNPackets(9);
- AckNPackets(1);
-
- // We should now have fallen out of slow start with a reduced window.
- EXPECT_EQ(kRenoBeta * kDefaultWindowTCP, sender_->GetCongestionWindow());
- const QuicPacketCount window_in_packets =
- kRenoBeta * kDefaultWindowTCP / kDefaultTCPMSS;
- const QuicBandwidth expected_pacing_rate =
- QuicBandwidth::FromBytesAndTimeDelta(kRenoBeta * kDefaultWindowTCP,
- sender_->rtt_stats_.smoothed_rtt());
- EXPECT_EQ(expected_pacing_rate, sender_->PacingRate(0));
- EXPECT_EQ(window_in_packets,
- static_cast<uint64_t>(SendAvailableSendWindow()));
- EXPECT_EQ(expected_pacing_rate,
- sender_->PacingRate(kRenoBeta * kDefaultWindowTCP));
-}
-
-TEST_F(TcpCubicSenderBytesTest, ResetAfterConnectionMigration) {
- // Starts from slow start.
- sender_->SetNumEmulatedConnections(1);
- const int kNumberOfAcks = 10;
- for (int i = 0; i < kNumberOfAcks; ++i) {
- // Send our full send window.
- SendAvailableSendWindow();
- AckNPackets(2);
- }
- SendAvailableSendWindow();
- QuicByteCount expected_send_window =
- kDefaultWindowTCP + (kDefaultTCPMSS * 2 * kNumberOfAcks);
- EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-
- // Loses a packet to exit slow start.
- LoseNPackets(1);
-
- // We should now have fallen out of slow start with a reduced window. Slow
- // start threshold is also updated.
- expected_send_window *= kRenoBeta;
- EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
- EXPECT_EQ(expected_send_window, sender_->GetSlowStartThreshold());
-
- // Resets cwnd and slow start threshold on connection migrations.
- sender_->OnConnectionMigration();
- EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow());
- EXPECT_EQ(kMaxCongestionWindowPackets * kDefaultTCPMSS,
- sender_->GetSlowStartThreshold());
- EXPECT_FALSE(sender_->hybrid_slow_start().started());
-}
-
-TEST_F(TcpCubicSenderBytesTest, DefaultMaxCwnd) {
- RttStats rtt_stats;
- QuicConnectionStats stats;
- std::unique_ptr<SendAlgorithmInterface> sender(SendAlgorithmInterface::Create(
- &clock_, &rtt_stats, /*unacked_packets=*/nullptr, kCubicBytes,
- QuicRandom::GetInstance(), &stats, kInitialCongestionWindow, nullptr));
-
- AckedPacketVector acked_packets;
- LostPacketVector missing_packets;
- QuicPacketCount max_congestion_window =
- GetQuicFlag(FLAGS_quic_max_congestion_window);
- for (uint64_t i = 1; i < max_congestion_window; ++i) {
- acked_packets.clear();
- acked_packets.push_back(
- AckedPacket(QuicPacketNumber(i), 1350, QuicTime::Zero()));
- sender->OnCongestionEvent(true, sender->GetCongestionWindow(), clock_.Now(),
- acked_packets, missing_packets);
- }
- EXPECT_EQ(max_congestion_window,
- sender->GetCongestionWindow() / kDefaultTCPMSS);
-}
-
-TEST_F(TcpCubicSenderBytesTest, LimitCwndIncreaseInCongestionAvoidance) {
- // Enable Cubic.
- sender_ = std::make_unique<TcpCubicSenderBytesPeer>(&clock_, false);
-
- int num_sent = SendAvailableSendWindow();
-
- // Make sure we fall out of slow start.
- QuicByteCount saved_cwnd = sender_->GetCongestionWindow();
- LoseNPackets(1);
- EXPECT_GT(saved_cwnd, sender_->GetCongestionWindow());
-
- // Ack the rest of the outstanding packets to get out of recovery.
- for (int i = 1; i < num_sent; ++i) {
- AckNPackets(1);
- }
- EXPECT_EQ(0u, bytes_in_flight_);
- // Send a new window of data and ack all; cubic growth should occur.
- saved_cwnd = sender_->GetCongestionWindow();
- num_sent = SendAvailableSendWindow();
-
- // Ack packets until the CWND increases.
- while (sender_->GetCongestionWindow() == saved_cwnd) {
- AckNPackets(1);
- SendAvailableSendWindow();
- }
- // Bytes in flight may be larger than the CWND if the CWND isn't an exact
- // multiple of the packet sizes being sent.
- EXPECT_GE(bytes_in_flight_, sender_->GetCongestionWindow());
- saved_cwnd = sender_->GetCongestionWindow();
-
- // Advance time 2 seconds waiting for an ack.
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(2000));
-
- // Ack two packets. The CWND should increase by only one packet.
- AckNPackets(2);
- EXPECT_EQ(saved_cwnd + kDefaultTCPMSS, sender_->GetCongestionWindow());
-}
-
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/congestion_control/uber_loss_algorithm.cc b/chromium/net/third_party/quiche/src/quic/core/congestion_control/uber_loss_algorithm.cc
deleted file mode 100644
index 2bf8d864b00..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/congestion_control/uber_loss_algorithm.cc
+++ /dev/null
@@ -1,215 +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 "quic/core/congestion_control/uber_loss_algorithm.h"
-
-#include <algorithm>
-
-#include "quic/core/crypto/crypto_protocol.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-
-namespace quic {
-
-UberLossAlgorithm::UberLossAlgorithm() {
- for (int8_t i = INITIAL_DATA; i < NUM_PACKET_NUMBER_SPACES; ++i) {
- general_loss_algorithms_[i].Initialize(static_cast<PacketNumberSpace>(i),
- this);
- }
-}
-
-void UberLossAlgorithm::SetFromConfig(const QuicConfig& config,
- Perspective perspective) {
- if (config.HasClientRequestedIndependentOption(kELDT, perspective) &&
- tuner_ != nullptr) {
- tuning_configured_ = true;
- MaybeStartTuning();
- }
-}
-
-LossDetectionInterface::DetectionStats UberLossAlgorithm::DetectLosses(
- const QuicUnackedPacketMap& unacked_packets,
- QuicTime time,
- const RttStats& rtt_stats,
- QuicPacketNumber /*largest_newly_acked*/,
- const AckedPacketVector& packets_acked,
- LostPacketVector* packets_lost) {
- DetectionStats overall_stats;
-
- for (int8_t i = INITIAL_DATA; i < NUM_PACKET_NUMBER_SPACES; ++i) {
- const QuicPacketNumber largest_acked =
- unacked_packets.GetLargestAckedOfPacketNumberSpace(
- static_cast<PacketNumberSpace>(i));
- if (!largest_acked.IsInitialized() ||
- unacked_packets.GetLeastUnacked() > largest_acked) {
- // Skip detecting losses if no packet has been received for this packet
- // number space or the least_unacked is greater than largest_acked.
- continue;
- }
-
- DetectionStats stats = general_loss_algorithms_[i].DetectLosses(
- unacked_packets, time, rtt_stats, largest_acked, packets_acked,
- packets_lost);
-
- overall_stats.sent_packets_max_sequence_reordering =
- std::max(overall_stats.sent_packets_max_sequence_reordering,
- stats.sent_packets_max_sequence_reordering);
- overall_stats.sent_packets_num_borderline_time_reorderings +=
- stats.sent_packets_num_borderline_time_reorderings;
- overall_stats.total_loss_detection_response_time +=
- stats.total_loss_detection_response_time;
- }
-
- return overall_stats;
-}
-
-QuicTime UberLossAlgorithm::GetLossTimeout() const {
- QuicTime loss_timeout = QuicTime::Zero();
- // Returns the earliest non-zero loss timeout.
- for (int8_t i = INITIAL_DATA; i < NUM_PACKET_NUMBER_SPACES; ++i) {
- const QuicTime timeout = general_loss_algorithms_[i].GetLossTimeout();
- if (!loss_timeout.IsInitialized()) {
- loss_timeout = timeout;
- continue;
- }
- if (timeout.IsInitialized()) {
- loss_timeout = std::min(loss_timeout, timeout);
- }
- }
- return loss_timeout;
-}
-
-void UberLossAlgorithm::SpuriousLossDetected(
- const QuicUnackedPacketMap& unacked_packets,
- const RttStats& rtt_stats,
- QuicTime ack_receive_time,
- QuicPacketNumber packet_number,
- QuicPacketNumber previous_largest_acked) {
- general_loss_algorithms_[unacked_packets.GetPacketNumberSpace(packet_number)]
- .SpuriousLossDetected(unacked_packets, rtt_stats, ack_receive_time,
- packet_number, previous_largest_acked);
-}
-
-void UberLossAlgorithm::SetLossDetectionTuner(
- std::unique_ptr<LossDetectionTunerInterface> tuner) {
- if (tuner_ != nullptr) {
- QUIC_BUG(quic_bug_10469_1)
- << "LossDetectionTuner can only be set once when session begins.";
- return;
- }
- tuner_ = std::move(tuner);
-}
-
-void UberLossAlgorithm::MaybeStartTuning() {
- if (tuner_started_ || !tuning_configured_ || !min_rtt_available_ ||
- !user_agent_known_ || !reorder_happened_) {
- return;
- }
-
- tuner_started_ = tuner_->Start(&tuned_parameters_);
- if (!tuner_started_) {
- return;
- }
-
- if (tuned_parameters_.reordering_shift.has_value() &&
- tuned_parameters_.reordering_threshold.has_value()) {
- QUIC_DLOG(INFO) << "Setting reordering shift to "
- << *tuned_parameters_.reordering_shift
- << ", and reordering threshold to "
- << *tuned_parameters_.reordering_threshold;
- SetReorderingShift(*tuned_parameters_.reordering_shift);
- SetReorderingThreshold(*tuned_parameters_.reordering_threshold);
- } else {
- QUIC_BUG(quic_bug_10469_2)
- << "Tuner started but some parameters are missing";
- }
-}
-
-void UberLossAlgorithm::OnConfigNegotiated() {}
-
-void UberLossAlgorithm::OnMinRttAvailable() {
- min_rtt_available_ = true;
- MaybeStartTuning();
-}
-
-void UberLossAlgorithm::OnUserAgentIdKnown() {
- user_agent_known_ = true;
- MaybeStartTuning();
-}
-
-void UberLossAlgorithm::OnConnectionClosed() {
- if (tuner_ != nullptr && tuner_started_) {
- tuner_->Finish(tuned_parameters_);
- }
-}
-
-void UberLossAlgorithm::OnReorderingDetected() {
- const bool tuner_started_before = tuner_started_;
- const bool reorder_happened_before = reorder_happened_;
-
- reorder_happened_ = true;
- MaybeStartTuning();
-
- if (!tuner_started_before && tuner_started_) {
- if (reorder_happened_before) {
- QUIC_CODE_COUNT(quic_loss_tuner_started_after_first_reorder);
- } else {
- QUIC_CODE_COUNT(quic_loss_tuner_started_on_first_reorder);
- }
- }
-}
-
-void UberLossAlgorithm::SetReorderingShift(int reordering_shift) {
- for (int8_t i = INITIAL_DATA; i < NUM_PACKET_NUMBER_SPACES; ++i) {
- general_loss_algorithms_[i].set_reordering_shift(reordering_shift);
- }
-}
-
-void UberLossAlgorithm::SetReorderingThreshold(
- QuicPacketCount reordering_threshold) {
- for (int8_t i = INITIAL_DATA; i < NUM_PACKET_NUMBER_SPACES; ++i) {
- general_loss_algorithms_[i].set_reordering_threshold(reordering_threshold);
- }
-}
-
-void UberLossAlgorithm::EnableAdaptiveReorderingThreshold() {
- for (int8_t i = INITIAL_DATA; i < NUM_PACKET_NUMBER_SPACES; ++i) {
- general_loss_algorithms_[i].set_use_adaptive_reordering_threshold(true);
- }
-}
-
-void UberLossAlgorithm::DisableAdaptiveReorderingThreshold() {
- for (int8_t i = INITIAL_DATA; i < NUM_PACKET_NUMBER_SPACES; ++i) {
- general_loss_algorithms_[i].set_use_adaptive_reordering_threshold(false);
- }
-}
-
-void UberLossAlgorithm::EnableAdaptiveTimeThreshold() {
- for (int8_t i = INITIAL_DATA; i < NUM_PACKET_NUMBER_SPACES; ++i) {
- general_loss_algorithms_[i].enable_adaptive_time_threshold();
- }
-}
-
-QuicPacketCount UberLossAlgorithm::GetPacketReorderingThreshold() const {
- return general_loss_algorithms_[APPLICATION_DATA].reordering_threshold();
-}
-
-int UberLossAlgorithm::GetPacketReorderingShift() const {
- return general_loss_algorithms_[APPLICATION_DATA].reordering_shift();
-}
-
-void UberLossAlgorithm::DisablePacketThresholdForRuntPackets() {
- for (int8_t i = INITIAL_DATA; i < NUM_PACKET_NUMBER_SPACES; ++i) {
- general_loss_algorithms_[i].disable_packet_threshold_for_runt_packets();
- }
-}
-
-void UberLossAlgorithm::ResetLossDetection(PacketNumberSpace space) {
- if (space >= NUM_PACKET_NUMBER_SPACES) {
- QUIC_BUG(quic_bug_10469_3) << "Invalid packet number space: " << space;
- return;
- }
- general_loss_algorithms_[space].Reset();
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/congestion_control/uber_loss_algorithm.h b/chromium/net/third_party/quiche/src/quic/core/congestion_control/uber_loss_algorithm.h
deleted file mode 100644
index 58cb53e3843..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/congestion_control/uber_loss_algorithm.h
+++ /dev/null
@@ -1,140 +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_CORE_CONGESTION_CONTROL_UBER_LOSS_ALGORITHM_H_
-#define QUICHE_QUIC_CORE_CONGESTION_CONTROL_UBER_LOSS_ALGORITHM_H_
-
-#include "absl/types/optional.h"
-#include "quic/core/congestion_control/general_loss_algorithm.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_flags.h"
-
-namespace quic {
-
-namespace test {
-
-class QuicSentPacketManagerPeer;
-
-} // namespace test
-
-struct QUIC_EXPORT_PRIVATE LossDetectionParameters {
- // See GeneralLossAlgorithm for the meaning of reordering_(shift|threshold).
- absl::optional<int> reordering_shift;
- absl::optional<QuicPacketCount> reordering_threshold;
-};
-
-class QUIC_EXPORT_PRIVATE LossDetectionTunerInterface {
- public:
- virtual ~LossDetectionTunerInterface() {}
-
- // Start the tuning by choosing parameters and saving them into |*params|.
- // Called near the start of a QUIC session, see the .cc file for exactly
- // where.
- virtual bool Start(LossDetectionParameters* params) = 0;
-
- // Finish tuning. The tuner is expected to use the actual loss detection
- // performance(for its definition of performance) to improve the parameter
- // selection for future QUIC sessions.
- // Called when a QUIC session closes.
- virtual void Finish(const LossDetectionParameters& params) = 0;
-};
-
-// This class comprises multiple loss algorithms, each per packet number space.
-class QUIC_EXPORT_PRIVATE UberLossAlgorithm : public LossDetectionInterface {
- public:
- UberLossAlgorithm();
- UberLossAlgorithm(const UberLossAlgorithm&) = delete;
- UberLossAlgorithm& operator=(const UberLossAlgorithm&) = delete;
- ~UberLossAlgorithm() override {}
-
- void SetFromConfig(const QuicConfig& config,
- Perspective perspective) override;
-
- // Detects lost packets.
- DetectionStats DetectLosses(const QuicUnackedPacketMap& unacked_packets,
- QuicTime time,
- const RttStats& rtt_stats,
- QuicPacketNumber largest_newly_acked,
- const AckedPacketVector& packets_acked,
- LostPacketVector* packets_lost) override;
-
- // Returns the earliest time the early retransmit timer should be active.
- QuicTime GetLossTimeout() const override;
-
- // Called to increases time or packet threshold.
- void SpuriousLossDetected(const QuicUnackedPacketMap& unacked_packets,
- const RttStats& rtt_stats,
- QuicTime ack_receive_time,
- QuicPacketNumber packet_number,
- QuicPacketNumber previous_largest_acked) override;
-
- void SetLossDetectionTuner(
- std::unique_ptr<LossDetectionTunerInterface> tuner);
- void OnConfigNegotiated() override;
- void OnMinRttAvailable() override;
- void OnUserAgentIdKnown() override;
- void OnConnectionClosed() override;
- void OnReorderingDetected() override;
-
- // Sets reordering_shift for all packet number spaces.
- void SetReorderingShift(int reordering_shift);
-
- // Sets reordering_threshold for all packet number spaces.
- void SetReorderingThreshold(QuicPacketCount reordering_threshold);
-
- // Enable adaptive reordering threshold of all packet number spaces.
- void EnableAdaptiveReorderingThreshold();
-
- // Disable adaptive reordering threshold of all packet number spaces.
- void DisableAdaptiveReorderingThreshold();
-
- // Enable adaptive time threshold of all packet number spaces.
- void EnableAdaptiveTimeThreshold();
-
- // Get the packet reordering threshold from the APPLICATION_DATA PN space.
- // Always 3 when adaptive reordering is not enabled.
- QuicPacketCount GetPacketReorderingThreshold() const;
-
- // Get the packet reordering shift from the APPLICATION_DATA PN space.
- int GetPacketReorderingShift() const;
-
- // Disable packet threshold loss detection for *runt* packets.
- void DisablePacketThresholdForRuntPackets();
-
- // Called to reset loss detection of |space|.
- void ResetLossDetection(PacketNumberSpace space);
-
- bool use_adaptive_reordering_threshold() const {
- return general_loss_algorithms_[APPLICATION_DATA]
- .use_adaptive_reordering_threshold();
- }
-
- bool use_adaptive_time_threshold() const {
- return general_loss_algorithms_[APPLICATION_DATA]
- .use_adaptive_time_threshold();
- }
-
- private:
- friend class test::QuicSentPacketManagerPeer;
-
- void MaybeStartTuning();
-
- // One loss algorithm per packet number space.
- GeneralLossAlgorithm general_loss_algorithms_[NUM_PACKET_NUMBER_SPACES];
-
- // Used to tune reordering_shift and reordering_threshold.
- std::unique_ptr<LossDetectionTunerInterface> tuner_;
- LossDetectionParameters tuned_parameters_;
- bool tuner_started_ = false;
- bool min_rtt_available_ = false;
- // Whether user agent is known to the session.
- bool user_agent_known_ = false;
- // Whether tuning is configured in QuicConfig.
- bool tuning_configured_ = false;
- bool reorder_happened_ = false; // Whether any reordered packet is observed.
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_CONGESTION_CONTROL_UBER_LOSS_ALGORITHM_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/congestion_control/uber_loss_algorithm_test.cc b/chromium/net/third_party/quiche/src/quic/core/congestion_control/uber_loss_algorithm_test.cc
deleted file mode 100644
index a24b444026a..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/congestion_control/uber_loss_algorithm_test.cc
+++ /dev/null
@@ -1,361 +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 "quic/core/congestion_control/uber_loss_algorithm.h"
-
-#include <memory>
-#include <utility>
-
-#include "absl/types/optional.h"
-#include "quic/core/congestion_control/rtt_stats.h"
-#include "quic/core/crypto/crypto_protocol.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/mock_clock.h"
-#include "quic/test_tools/quic_unacked_packet_map_peer.h"
-
-namespace quic {
-namespace test {
-namespace {
-
-// Default packet length.
-const uint32_t kDefaultLength = 1000;
-
-class UberLossAlgorithmTest : public QuicTest {
- protected:
- UberLossAlgorithmTest() {
- unacked_packets_ =
- std::make_unique<QuicUnackedPacketMap>(Perspective::IS_CLIENT);
- rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(100),
- QuicTime::Delta::Zero(), clock_.Now());
- EXPECT_LT(0, rtt_stats_.smoothed_rtt().ToMicroseconds());
- }
-
- void SendPacket(uint64_t packet_number, EncryptionLevel encryption_level) {
- QuicStreamFrame frame;
- QuicTransportVersion version =
- CurrentSupportedVersions()[0].transport_version;
- frame.stream_id = QuicUtils::GetFirstBidirectionalStreamId(
- version, Perspective::IS_CLIENT);
- if (encryption_level == ENCRYPTION_INITIAL) {
- if (QuicVersionUsesCryptoFrames(version)) {
- frame.stream_id = QuicUtils::GetFirstBidirectionalStreamId(
- version, Perspective::IS_CLIENT);
- } else {
- frame.stream_id = QuicUtils::GetCryptoStreamId(version);
- }
- }
- SerializedPacket packet(QuicPacketNumber(packet_number),
- PACKET_1BYTE_PACKET_NUMBER, nullptr, kDefaultLength,
- false, false);
- packet.encryption_level = encryption_level;
- packet.retransmittable_frames.push_back(QuicFrame(frame));
- unacked_packets_->AddSentPacket(&packet, NOT_RETRANSMISSION, clock_.Now(),
- true, true);
- }
-
- void AckPackets(const std::vector<uint64_t>& packets_acked) {
- packets_acked_.clear();
- for (uint64_t acked : packets_acked) {
- unacked_packets_->RemoveFromInFlight(QuicPacketNumber(acked));
- packets_acked_.push_back(AckedPacket(
- QuicPacketNumber(acked), kMaxOutgoingPacketSize, QuicTime::Zero()));
- }
- }
-
- void VerifyLosses(uint64_t largest_newly_acked,
- const AckedPacketVector& packets_acked,
- const std::vector<uint64_t>& losses_expected) {
- return VerifyLosses(largest_newly_acked, packets_acked, losses_expected,
- absl::nullopt);
- }
-
- void VerifyLosses(
- uint64_t largest_newly_acked,
- const AckedPacketVector& packets_acked,
- const std::vector<uint64_t>& losses_expected,
- absl::optional<QuicPacketCount> max_sequence_reordering_expected) {
- LostPacketVector lost_packets;
- LossDetectionInterface::DetectionStats stats = loss_algorithm_.DetectLosses(
- *unacked_packets_, clock_.Now(), rtt_stats_,
- QuicPacketNumber(largest_newly_acked), packets_acked, &lost_packets);
- if (max_sequence_reordering_expected.has_value()) {
- EXPECT_EQ(stats.sent_packets_max_sequence_reordering,
- max_sequence_reordering_expected.value());
- }
- ASSERT_EQ(losses_expected.size(), lost_packets.size());
- for (size_t i = 0; i < losses_expected.size(); ++i) {
- EXPECT_EQ(lost_packets[i].packet_number,
- QuicPacketNumber(losses_expected[i]));
- }
- }
-
- MockClock clock_;
- std::unique_ptr<QuicUnackedPacketMap> unacked_packets_;
- RttStats rtt_stats_;
- UberLossAlgorithm loss_algorithm_;
- AckedPacketVector packets_acked_;
-};
-
-TEST_F(UberLossAlgorithmTest, ScenarioA) {
- // This test mimics a scenario: client sends 1-CHLO, 2-0RTT, 3-0RTT,
- // timeout and retransmits 4-CHLO. Server acks packet 1 (ack gets lost).
- // Server receives and buffers packets 2 and 3. Server receives packet 4 and
- // processes handshake asynchronously, so server acks 4 and cannot process
- // packets 2 and 3.
- SendPacket(1, ENCRYPTION_INITIAL);
- SendPacket(2, ENCRYPTION_ZERO_RTT);
- SendPacket(3, ENCRYPTION_ZERO_RTT);
- unacked_packets_->RemoveFromInFlight(QuicPacketNumber(1));
- SendPacket(4, ENCRYPTION_INITIAL);
-
- AckPackets({1, 4});
- unacked_packets_->MaybeUpdateLargestAckedOfPacketNumberSpace(
- HANDSHAKE_DATA, QuicPacketNumber(4));
- // Verify no packet is detected lost.
- VerifyLosses(4, packets_acked_, std::vector<uint64_t>{}, 0);
- EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout());
-}
-
-TEST_F(UberLossAlgorithmTest, ScenarioB) {
- // This test mimics a scenario: client sends 3-0RTT, 4-0RTT, receives SHLO,
- // sends 5-1RTT, 6-1RTT.
- SendPacket(3, ENCRYPTION_ZERO_RTT);
- SendPacket(4, ENCRYPTION_ZERO_RTT);
- SendPacket(5, ENCRYPTION_FORWARD_SECURE);
- SendPacket(6, ENCRYPTION_FORWARD_SECURE);
-
- AckPackets({4});
- unacked_packets_->MaybeUpdateLargestAckedOfPacketNumberSpace(
- APPLICATION_DATA, QuicPacketNumber(4));
- // No packet loss by acking 4.
- VerifyLosses(4, packets_acked_, std::vector<uint64_t>{}, 1);
- EXPECT_EQ(clock_.Now() + 1.25 * rtt_stats_.smoothed_rtt(),
- loss_algorithm_.GetLossTimeout());
-
- // Acking 6 causes 3 to be detected loss.
- AckPackets({6});
- unacked_packets_->MaybeUpdateLargestAckedOfPacketNumberSpace(
- APPLICATION_DATA, QuicPacketNumber(6));
- VerifyLosses(6, packets_acked_, std::vector<uint64_t>{3}, 3);
- EXPECT_EQ(clock_.Now() + 1.25 * rtt_stats_.smoothed_rtt(),
- loss_algorithm_.GetLossTimeout());
- packets_acked_.clear();
-
- clock_.AdvanceTime(1.25 * rtt_stats_.latest_rtt());
- // Verify 5 will be early retransmitted.
- VerifyLosses(6, packets_acked_, {5}, 1);
-}
-
-TEST_F(UberLossAlgorithmTest, ScenarioC) {
- // This test mimics a scenario: server sends 1-SHLO, 2-1RTT, 3-1RTT, 4-1RTT
- // and retransmit 4-SHLO. Client receives and buffers packet 4. Client
- // receives packet 5 and processes 4.
- QuicUnackedPacketMapPeer::SetPerspective(unacked_packets_.get(),
- Perspective::IS_SERVER);
- SendPacket(1, ENCRYPTION_ZERO_RTT);
- SendPacket(2, ENCRYPTION_FORWARD_SECURE);
- SendPacket(3, ENCRYPTION_FORWARD_SECURE);
- SendPacket(4, ENCRYPTION_FORWARD_SECURE);
- unacked_packets_->RemoveFromInFlight(QuicPacketNumber(1));
- SendPacket(5, ENCRYPTION_ZERO_RTT);
-
- AckPackets({4, 5});
- unacked_packets_->MaybeUpdateLargestAckedOfPacketNumberSpace(
- APPLICATION_DATA, QuicPacketNumber(4));
- unacked_packets_->MaybeUpdateLargestAckedOfPacketNumberSpace(
- HANDSHAKE_DATA, QuicPacketNumber(5));
- // No packet loss by acking 5.
- VerifyLosses(5, packets_acked_, std::vector<uint64_t>{}, 2);
- EXPECT_EQ(clock_.Now() + 1.25 * rtt_stats_.smoothed_rtt(),
- loss_algorithm_.GetLossTimeout());
- packets_acked_.clear();
-
- clock_.AdvanceTime(1.25 * rtt_stats_.latest_rtt());
- // Verify 2 and 3 will be early retransmitted.
- VerifyLosses(5, packets_acked_, std::vector<uint64_t>{2, 3}, 2);
-}
-
-// Regression test for b/133771183.
-TEST_F(UberLossAlgorithmTest, PacketInLimbo) {
- // This test mimics a scenario: server sends 1-SHLO, 2-1RTT, 3-1RTT,
- // 4-retransmit SHLO. Client receives and ACKs packets 1, 3 and 4.
- QuicUnackedPacketMapPeer::SetPerspective(unacked_packets_.get(),
- Perspective::IS_SERVER);
-
- SendPacket(1, ENCRYPTION_ZERO_RTT);
- SendPacket(2, ENCRYPTION_FORWARD_SECURE);
- SendPacket(3, ENCRYPTION_FORWARD_SECURE);
- SendPacket(4, ENCRYPTION_ZERO_RTT);
-
- SendPacket(5, ENCRYPTION_FORWARD_SECURE);
- AckPackets({1, 3, 4});
- unacked_packets_->MaybeUpdateLargestAckedOfPacketNumberSpace(
- APPLICATION_DATA, QuicPacketNumber(3));
- unacked_packets_->MaybeUpdateLargestAckedOfPacketNumberSpace(
- HANDSHAKE_DATA, QuicPacketNumber(4));
- // No packet loss detected.
- VerifyLosses(4, packets_acked_, std::vector<uint64_t>{});
-
- SendPacket(6, ENCRYPTION_FORWARD_SECURE);
- AckPackets({5, 6});
- unacked_packets_->MaybeUpdateLargestAckedOfPacketNumberSpace(
- APPLICATION_DATA, QuicPacketNumber(6));
- // Verify packet 2 is detected lost.
- VerifyLosses(6, packets_acked_, std::vector<uint64_t>{2});
-}
-
-class TestLossTuner : public LossDetectionTunerInterface {
- public:
- TestLossTuner(bool forced_start_result,
- LossDetectionParameters forced_parameters)
- : forced_start_result_(forced_start_result),
- forced_parameters_(std::move(forced_parameters)) {}
-
- ~TestLossTuner() override = default;
-
- bool Start(LossDetectionParameters* params) override {
- start_called_ = true;
- *params = forced_parameters_;
- return forced_start_result_;
- }
-
- void Finish(const LossDetectionParameters& /*params*/) override {}
-
- bool start_called() const { return start_called_; }
-
- private:
- bool forced_start_result_;
- LossDetectionParameters forced_parameters_;
- bool start_called_ = false;
-};
-
-// Verify the parameters are changed if first call SetFromConfig(), then call
-// OnMinRttAvailable().
-TEST_F(UberLossAlgorithmTest, LossDetectionTuning_SetFromConfigFirst) {
- const int old_reordering_shift = loss_algorithm_.GetPacketReorderingShift();
- const QuicPacketCount old_reordering_threshold =
- loss_algorithm_.GetPacketReorderingThreshold();
-
- loss_algorithm_.OnUserAgentIdKnown();
-
- // Not owned.
- TestLossTuner* test_tuner = new TestLossTuner(
- /*forced_start_result=*/true,
- LossDetectionParameters{
- /*reordering_shift=*/old_reordering_shift + 1,
- /*reordering_threshold=*/old_reordering_threshold * 2});
- loss_algorithm_.SetLossDetectionTuner(
- std::unique_ptr<LossDetectionTunerInterface>(test_tuner));
-
- QuicConfig config;
- QuicTagVector connection_options;
- connection_options.push_back(kELDT);
- config.SetInitialReceivedConnectionOptions(connection_options);
- loss_algorithm_.SetFromConfig(config, Perspective::IS_SERVER);
-
- // MinRtt was not available when SetFromConfig was called.
- EXPECT_FALSE(test_tuner->start_called());
- EXPECT_EQ(old_reordering_shift, loss_algorithm_.GetPacketReorderingShift());
- EXPECT_EQ(old_reordering_threshold,
- loss_algorithm_.GetPacketReorderingThreshold());
-
- // MinRtt available. Tuner should not start yet because no reordering yet.
- loss_algorithm_.OnMinRttAvailable();
- EXPECT_FALSE(test_tuner->start_called());
-
- // Reordering happened. Tuner should start now.
- loss_algorithm_.OnReorderingDetected();
- EXPECT_TRUE(test_tuner->start_called());
- EXPECT_NE(old_reordering_shift, loss_algorithm_.GetPacketReorderingShift());
- EXPECT_NE(old_reordering_threshold,
- loss_algorithm_.GetPacketReorderingThreshold());
-}
-
-// Verify the parameters are changed if first call OnMinRttAvailable(), then
-// call SetFromConfig().
-TEST_F(UberLossAlgorithmTest, LossDetectionTuning_OnMinRttAvailableFirst) {
- const int old_reordering_shift = loss_algorithm_.GetPacketReorderingShift();
- const QuicPacketCount old_reordering_threshold =
- loss_algorithm_.GetPacketReorderingThreshold();
-
- loss_algorithm_.OnUserAgentIdKnown();
-
- // Not owned.
- TestLossTuner* test_tuner = new TestLossTuner(
- /*forced_start_result=*/true,
- LossDetectionParameters{
- /*reordering_shift=*/old_reordering_shift + 1,
- /*reordering_threshold=*/old_reordering_threshold * 2});
- loss_algorithm_.SetLossDetectionTuner(
- std::unique_ptr<LossDetectionTunerInterface>(test_tuner));
-
- loss_algorithm_.OnMinRttAvailable();
- EXPECT_FALSE(test_tuner->start_called());
- EXPECT_EQ(old_reordering_shift, loss_algorithm_.GetPacketReorderingShift());
- EXPECT_EQ(old_reordering_threshold,
- loss_algorithm_.GetPacketReorderingThreshold());
-
- // Pretend a reodering has happened.
- loss_algorithm_.OnReorderingDetected();
- EXPECT_FALSE(test_tuner->start_called());
-
- QuicConfig config;
- QuicTagVector connection_options;
- connection_options.push_back(kELDT);
- config.SetInitialReceivedConnectionOptions(connection_options);
- // Should start tuning since MinRtt is available.
- loss_algorithm_.SetFromConfig(config, Perspective::IS_SERVER);
-
- EXPECT_TRUE(test_tuner->start_called());
- EXPECT_NE(old_reordering_shift, loss_algorithm_.GetPacketReorderingShift());
- EXPECT_NE(old_reordering_threshold,
- loss_algorithm_.GetPacketReorderingThreshold());
-}
-
-// Verify the parameters are not changed if Tuner.Start() returns false.
-TEST_F(UberLossAlgorithmTest, LossDetectionTuning_StartFailed) {
- const int old_reordering_shift = loss_algorithm_.GetPacketReorderingShift();
- const QuicPacketCount old_reordering_threshold =
- loss_algorithm_.GetPacketReorderingThreshold();
-
- loss_algorithm_.OnUserAgentIdKnown();
-
- // Not owned.
- TestLossTuner* test_tuner = new TestLossTuner(
- /*forced_start_result=*/false,
- LossDetectionParameters{
- /*reordering_shift=*/old_reordering_shift + 1,
- /*reordering_threshold=*/old_reordering_threshold * 2});
- loss_algorithm_.SetLossDetectionTuner(
- std::unique_ptr<LossDetectionTunerInterface>(test_tuner));
-
- QuicConfig config;
- QuicTagVector connection_options;
- connection_options.push_back(kELDT);
- config.SetInitialReceivedConnectionOptions(connection_options);
- loss_algorithm_.SetFromConfig(config, Perspective::IS_SERVER);
-
- // MinRtt was not available when SetFromConfig was called.
- EXPECT_FALSE(test_tuner->start_called());
- EXPECT_EQ(old_reordering_shift, loss_algorithm_.GetPacketReorderingShift());
- EXPECT_EQ(old_reordering_threshold,
- loss_algorithm_.GetPacketReorderingThreshold());
-
- // Pretend a reodering has happened.
- loss_algorithm_.OnReorderingDetected();
- EXPECT_FALSE(test_tuner->start_called());
-
- // Parameters should not change since test_tuner->Start() returns false.
- loss_algorithm_.OnMinRttAvailable();
- EXPECT_TRUE(test_tuner->start_called());
- EXPECT_EQ(old_reordering_shift, loss_algorithm_.GetPacketReorderingShift());
- EXPECT_EQ(old_reordering_threshold,
- loss_algorithm_.GetPacketReorderingThreshold());
-}
-
-} // namespace
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/congestion_control/windowed_filter.h b/chromium/net/third_party/quiche/src/quic/core/congestion_control/windowed_filter.h
deleted file mode 100644
index a777ac5fc74..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/congestion_control/windowed_filter.h
+++ /dev/null
@@ -1,164 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_CONGESTION_CONTROL_WINDOWED_FILTER_H_
-#define QUICHE_QUIC_CORE_CONGESTION_CONTROL_WINDOWED_FILTER_H_
-
-// Implements Kathleen Nichols' algorithm for tracking the minimum (or maximum)
-// estimate of a stream of samples over some fixed time interval. (E.g.,
-// the minimum RTT over the past five minutes.) The algorithm keeps track of
-// the best, second best, and third best min (or max) estimates, maintaining an
-// invariant that the measurement time of the n'th best >= n-1'th best.
-
-// The algorithm works as follows. On a reset, all three estimates are set to
-// the same sample. The second best estimate is then recorded in the second
-// quarter of the window, and a third best estimate is recorded in the second
-// half of the window, bounding the worst case error when the true min is
-// monotonically increasing (or true max is monotonically decreasing) over the
-// window.
-//
-// A new best sample replaces all three estimates, since the new best is lower
-// (or higher) than everything else in the window and it is the most recent.
-// The window thus effectively gets reset on every new min. The same property
-// holds true for second best and third best estimates. Specifically, when a
-// sample arrives that is better than the second best but not better than the
-// best, it replaces the second and third best estimates but not the best
-// estimate. Similarly, a sample that is better than the third best estimate
-// but not the other estimates replaces only the third best estimate.
-//
-// Finally, when the best expires, it is replaced by the second best, which in
-// turn is replaced by the third best. The newest sample replaces the third
-// best.
-
-#include "quic/core/quic_time.h"
-
-namespace quic {
-
-// Compares two values and returns true if the first is less than or equal
-// to the second.
-template <class T>
-struct QUIC_EXPORT_PRIVATE MinFilter {
- bool operator()(const T& lhs, const T& rhs) const { return lhs <= rhs; }
-};
-
-// Compares two values and returns true if the first is greater than or equal
-// to the second.
-template <class T>
-struct QUIC_EXPORT_PRIVATE MaxFilter {
- bool operator()(const T& lhs, const T& rhs) const { return lhs >= rhs; }
-};
-
-// Use the following to construct a windowed filter object of type T.
-// For example, a min filter using QuicTime as the time type:
-// WindowedFilter<T, MinFilter<T>, QuicTime, QuicTime::Delta> ObjectName;
-// A max filter using 64-bit integers as the time type:
-// WindowedFilter<T, MaxFilter<T>, uint64_t, int64_t> ObjectName;
-// Specifically, this template takes four arguments:
-// 1. T -- type of the measurement that is being filtered.
-// 2. Compare -- MinFilter<T> or MaxFilter<T>, depending on the type of filter
-// desired.
-// 3. TimeT -- the type used to represent timestamps.
-// 4. TimeDeltaT -- the type used to represent continuous time intervals between
-// two timestamps. Has to be the type of (a - b) if both |a| and |b| are
-// of type TimeT.
-template <class T, class Compare, typename TimeT, typename TimeDeltaT>
-class QUIC_EXPORT_PRIVATE WindowedFilter {
- public:
- // |window_length| is the period after which a best estimate expires.
- // |zero_value| is used as the uninitialized value for objects of T.
- // Importantly, |zero_value| should be an invalid value for a true sample.
- WindowedFilter(TimeDeltaT window_length, T zero_value, TimeT zero_time)
- : window_length_(window_length),
- zero_value_(zero_value),
- zero_time_(zero_time),
- estimates_{Sample(zero_value_, zero_time),
- Sample(zero_value_, zero_time),
- Sample(zero_value_, zero_time)} {}
-
- // Changes the window length. Does not update any current samples.
- void SetWindowLength(TimeDeltaT window_length) {
- window_length_ = window_length;
- }
-
- // Updates best estimates with |sample|, and expires and updates best
- // estimates as necessary.
- void Update(T new_sample, TimeT new_time) {
- // Reset all estimates if they have not yet been initialized, if new sample
- // is a new best, or if the newest recorded estimate is too old.
- if (estimates_[0].sample == zero_value_ ||
- Compare()(new_sample, estimates_[0].sample) ||
- new_time - estimates_[2].time > window_length_) {
- Reset(new_sample, new_time);
- return;
- }
-
- if (Compare()(new_sample, estimates_[1].sample)) {
- estimates_[1] = Sample(new_sample, new_time);
- estimates_[2] = estimates_[1];
- } else if (Compare()(new_sample, estimates_[2].sample)) {
- estimates_[2] = Sample(new_sample, new_time);
- }
-
- // Expire and update estimates as necessary.
- if (new_time - estimates_[0].time > window_length_) {
- // The best estimate hasn't been updated for an entire window, so promote
- // second and third best estimates.
- estimates_[0] = estimates_[1];
- estimates_[1] = estimates_[2];
- estimates_[2] = Sample(new_sample, new_time);
- // Need to iterate one more time. Check if the new best estimate is
- // outside the window as well, since it may also have been recorded a
- // long time ago. Don't need to iterate once more since we cover that
- // case at the beginning of the method.
- if (new_time - estimates_[0].time > window_length_) {
- estimates_[0] = estimates_[1];
- estimates_[1] = estimates_[2];
- }
- return;
- }
- if (estimates_[1].sample == estimates_[0].sample &&
- new_time - estimates_[1].time > window_length_ >> 2) {
- // A quarter of the window has passed without a better sample, so the
- // second-best estimate is taken from the second quarter of the window.
- estimates_[2] = estimates_[1] = Sample(new_sample, new_time);
- return;
- }
-
- if (estimates_[2].sample == estimates_[1].sample &&
- new_time - estimates_[2].time > window_length_ >> 1) {
- // We've passed a half of the window without a better estimate, so take
- // a third-best estimate from the second half of the window.
- estimates_[2] = Sample(new_sample, new_time);
- }
- }
-
- // Resets all estimates to new sample.
- void Reset(T new_sample, TimeT new_time) {
- estimates_[0] = estimates_[1] = estimates_[2] =
- Sample(new_sample, new_time);
- }
-
- void Clear() { Reset(zero_value_, zero_time_); }
-
- T GetBest() const { return estimates_[0].sample; }
- T GetSecondBest() const { return estimates_[1].sample; }
- T GetThirdBest() const { return estimates_[2].sample; }
-
- private:
- struct QUIC_EXPORT_PRIVATE Sample {
- T sample;
- TimeT time;
- Sample(T init_sample, TimeT init_time)
- : sample(init_sample), time(init_time) {}
- };
-
- TimeDeltaT window_length_; // Time length of window.
- T zero_value_; // Uninitialized value of T.
- TimeT zero_time_; // Uninitialized value of TimeT.
- Sample estimates_[3]; // Best estimate is element 0.
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_CONGESTION_CONTROL_WINDOWED_FILTER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/congestion_control/windowed_filter_test.cc b/chromium/net/third_party/quiche/src/quic/core/congestion_control/windowed_filter_test.cc
deleted file mode 100644
index bb0e8fb793c..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/congestion_control/windowed_filter_test.cc
+++ /dev/null
@@ -1,388 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/congestion_control/windowed_filter.h"
-
-#include "quic/core/congestion_control/rtt_stats.h"
-#include "quic/core/quic_bandwidth.h"
-#include "quic/core/quic_packets.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/platform/api/quic_test.h"
-
-namespace quic {
-namespace test {
-
-class WindowedFilterTest : public QuicTest {
- public:
- // Set the window to 99ms, so 25ms is more than a quarter rtt.
- WindowedFilterTest()
- : windowed_min_rtt_(QuicTime::Delta::FromMilliseconds(99),
- QuicTime::Delta::Zero(),
- QuicTime::Zero()),
- windowed_max_bw_(QuicTime::Delta::FromMilliseconds(99),
- QuicBandwidth::Zero(),
- QuicTime::Zero()) {}
-
- // Sets up windowed_min_rtt_ to have the following values:
- // Best = 20ms, recorded at 25ms
- // Second best = 40ms, recorded at 75ms
- // Third best = 50ms, recorded at 100ms
- void InitializeMinFilter() {
- QuicTime now = QuicTime::Zero();
- QuicTime::Delta rtt_sample = QuicTime::Delta::FromMilliseconds(10);
- for (int i = 0; i < 5; ++i) {
- windowed_min_rtt_.Update(rtt_sample, now);
- QUIC_VLOG(1) << "i: " << i << " sample: " << rtt_sample.ToMilliseconds()
- << " mins: "
- << " " << windowed_min_rtt_.GetBest().ToMilliseconds() << " "
- << windowed_min_rtt_.GetSecondBest().ToMilliseconds() << " "
- << windowed_min_rtt_.GetThirdBest().ToMilliseconds();
- now = now + QuicTime::Delta::FromMilliseconds(25);
- rtt_sample = rtt_sample + QuicTime::Delta::FromMilliseconds(10);
- }
- EXPECT_EQ(QuicTime::Delta::FromMilliseconds(20),
- windowed_min_rtt_.GetBest());
- EXPECT_EQ(QuicTime::Delta::FromMilliseconds(40),
- windowed_min_rtt_.GetSecondBest());
- EXPECT_EQ(QuicTime::Delta::FromMilliseconds(50),
- windowed_min_rtt_.GetThirdBest());
- }
-
- // Sets up windowed_max_bw_ to have the following values:
- // Best = 900 bps, recorded at 25ms
- // Second best = 700 bps, recorded at 75ms
- // Third best = 600 bps, recorded at 100ms
- void InitializeMaxFilter() {
- QuicTime now = QuicTime::Zero();
- QuicBandwidth bw_sample = QuicBandwidth::FromBitsPerSecond(1000);
- for (int i = 0; i < 5; ++i) {
- windowed_max_bw_.Update(bw_sample, now);
- QUIC_VLOG(1) << "i: " << i << " sample: " << bw_sample.ToBitsPerSecond()
- << " maxs: "
- << " " << windowed_max_bw_.GetBest().ToBitsPerSecond() << " "
- << windowed_max_bw_.GetSecondBest().ToBitsPerSecond() << " "
- << windowed_max_bw_.GetThirdBest().ToBitsPerSecond();
- now = now + QuicTime::Delta::FromMilliseconds(25);
- bw_sample = bw_sample - QuicBandwidth::FromBitsPerSecond(100);
- }
- EXPECT_EQ(QuicBandwidth::FromBitsPerSecond(900),
- windowed_max_bw_.GetBest());
- EXPECT_EQ(QuicBandwidth::FromBitsPerSecond(700),
- windowed_max_bw_.GetSecondBest());
- EXPECT_EQ(QuicBandwidth::FromBitsPerSecond(600),
- windowed_max_bw_.GetThirdBest());
- }
-
- protected:
- WindowedFilter<QuicTime::Delta,
- MinFilter<QuicTime::Delta>,
- QuicTime,
- QuicTime::Delta>
- windowed_min_rtt_;
- WindowedFilter<QuicBandwidth,
- MaxFilter<QuicBandwidth>,
- QuicTime,
- QuicTime::Delta>
- windowed_max_bw_;
-};
-
-namespace {
-// Test helper function: updates the filter with a lot of small values in order
-// to ensure that it is not susceptible to noise.
-void UpdateWithIrrelevantSamples(
- WindowedFilter<uint64_t, MaxFilter<uint64_t>, uint64_t, uint64_t>* filter,
- uint64_t max_value,
- uint64_t time) {
- for (uint64_t i = 0; i < 1000; i++) {
- filter->Update(i % max_value, time);
- }
-}
-} // namespace
-
-TEST_F(WindowedFilterTest, UninitializedEstimates) {
- EXPECT_EQ(QuicTime::Delta::Zero(), windowed_min_rtt_.GetBest());
- EXPECT_EQ(QuicTime::Delta::Zero(), windowed_min_rtt_.GetSecondBest());
- EXPECT_EQ(QuicTime::Delta::Zero(), windowed_min_rtt_.GetThirdBest());
- EXPECT_EQ(QuicBandwidth::Zero(), windowed_max_bw_.GetBest());
- EXPECT_EQ(QuicBandwidth::Zero(), windowed_max_bw_.GetSecondBest());
- EXPECT_EQ(QuicBandwidth::Zero(), windowed_max_bw_.GetThirdBest());
-}
-
-TEST_F(WindowedFilterTest, MonotonicallyIncreasingMin) {
- QuicTime now = QuicTime::Zero();
- QuicTime::Delta rtt_sample = QuicTime::Delta::FromMilliseconds(10);
- windowed_min_rtt_.Update(rtt_sample, now);
- EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10), windowed_min_rtt_.GetBest());
-
- // Gradually increase the rtt samples and ensure the windowed min rtt starts
- // rising.
- for (int i = 0; i < 6; ++i) {
- now = now + QuicTime::Delta::FromMilliseconds(25);
- rtt_sample = rtt_sample + QuicTime::Delta::FromMilliseconds(10);
- windowed_min_rtt_.Update(rtt_sample, now);
- QUIC_VLOG(1) << "i: " << i << " sample: " << rtt_sample.ToMilliseconds()
- << " mins: "
- << " " << windowed_min_rtt_.GetBest().ToMilliseconds() << " "
- << windowed_min_rtt_.GetSecondBest().ToMilliseconds() << " "
- << windowed_min_rtt_.GetThirdBest().ToMilliseconds();
- if (i < 3) {
- EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10),
- windowed_min_rtt_.GetBest());
- } else if (i == 3) {
- EXPECT_EQ(QuicTime::Delta::FromMilliseconds(20),
- windowed_min_rtt_.GetBest());
- } else if (i < 6) {
- EXPECT_EQ(QuicTime::Delta::FromMilliseconds(40),
- windowed_min_rtt_.GetBest());
- }
- }
-}
-
-TEST_F(WindowedFilterTest, MonotonicallyDecreasingMax) {
- QuicTime now = QuicTime::Zero();
- QuicBandwidth bw_sample = QuicBandwidth::FromBitsPerSecond(1000);
- windowed_max_bw_.Update(bw_sample, now);
- EXPECT_EQ(QuicBandwidth::FromBitsPerSecond(1000), windowed_max_bw_.GetBest());
-
- // Gradually decrease the bw samples and ensure the windowed max bw starts
- // decreasing.
- for (int i = 0; i < 6; ++i) {
- now = now + QuicTime::Delta::FromMilliseconds(25);
- bw_sample = bw_sample - QuicBandwidth::FromBitsPerSecond(100);
- windowed_max_bw_.Update(bw_sample, now);
- QUIC_VLOG(1) << "i: " << i << " sample: " << bw_sample.ToBitsPerSecond()
- << " maxs: "
- << " " << windowed_max_bw_.GetBest().ToBitsPerSecond() << " "
- << windowed_max_bw_.GetSecondBest().ToBitsPerSecond() << " "
- << windowed_max_bw_.GetThirdBest().ToBitsPerSecond();
- if (i < 3) {
- EXPECT_EQ(QuicBandwidth::FromBitsPerSecond(1000),
- windowed_max_bw_.GetBest());
- } else if (i == 3) {
- EXPECT_EQ(QuicBandwidth::FromBitsPerSecond(900),
- windowed_max_bw_.GetBest());
- } else if (i < 6) {
- EXPECT_EQ(QuicBandwidth::FromBitsPerSecond(700),
- windowed_max_bw_.GetBest());
- }
- }
-}
-
-TEST_F(WindowedFilterTest, SampleChangesThirdBestMin) {
- InitializeMinFilter();
- // RTT sample lower than the third-choice min-rtt sets that, but nothing else.
- QuicTime::Delta rtt_sample =
- windowed_min_rtt_.GetThirdBest() - QuicTime::Delta::FromMilliseconds(5);
- // This assert is necessary to avoid triggering -Wstrict-overflow
- // See crbug/616957
- ASSERT_GT(windowed_min_rtt_.GetThirdBest(),
- QuicTime::Delta::FromMilliseconds(5));
- // Latest sample was recorded at 100ms.
- QuicTime now = QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(101);
- windowed_min_rtt_.Update(rtt_sample, now);
- EXPECT_EQ(rtt_sample, windowed_min_rtt_.GetThirdBest());
- EXPECT_EQ(QuicTime::Delta::FromMilliseconds(40),
- windowed_min_rtt_.GetSecondBest());
- EXPECT_EQ(QuicTime::Delta::FromMilliseconds(20), windowed_min_rtt_.GetBest());
-}
-
-TEST_F(WindowedFilterTest, SampleChangesThirdBestMax) {
- InitializeMaxFilter();
- // BW sample higher than the third-choice max sets that, but nothing else.
- QuicBandwidth bw_sample =
- windowed_max_bw_.GetThirdBest() + QuicBandwidth::FromBitsPerSecond(50);
- // Latest sample was recorded at 100ms.
- QuicTime now = QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(101);
- windowed_max_bw_.Update(bw_sample, now);
- EXPECT_EQ(bw_sample, windowed_max_bw_.GetThirdBest());
- EXPECT_EQ(QuicBandwidth::FromBitsPerSecond(700),
- windowed_max_bw_.GetSecondBest());
- EXPECT_EQ(QuicBandwidth::FromBitsPerSecond(900), windowed_max_bw_.GetBest());
-}
-
-TEST_F(WindowedFilterTest, SampleChangesSecondBestMin) {
- InitializeMinFilter();
- // RTT sample lower than the second-choice min sets that and also
- // the third-choice min.
- QuicTime::Delta rtt_sample =
- windowed_min_rtt_.GetSecondBest() - QuicTime::Delta::FromMilliseconds(5);
- // This assert is necessary to avoid triggering -Wstrict-overflow
- // See crbug/616957
- ASSERT_GT(windowed_min_rtt_.GetSecondBest(),
- QuicTime::Delta::FromMilliseconds(5));
- // Latest sample was recorded at 100ms.
- QuicTime now = QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(101);
- windowed_min_rtt_.Update(rtt_sample, now);
- EXPECT_EQ(rtt_sample, windowed_min_rtt_.GetThirdBest());
- EXPECT_EQ(rtt_sample, windowed_min_rtt_.GetSecondBest());
- EXPECT_EQ(QuicTime::Delta::FromMilliseconds(20), windowed_min_rtt_.GetBest());
-}
-
-TEST_F(WindowedFilterTest, SampleChangesSecondBestMax) {
- InitializeMaxFilter();
- // BW sample higher than the second-choice max sets that and also
- // the third-choice max.
- QuicBandwidth bw_sample =
- windowed_max_bw_.GetSecondBest() + QuicBandwidth::FromBitsPerSecond(50);
- // Latest sample was recorded at 100ms.
- QuicTime now = QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(101);
- windowed_max_bw_.Update(bw_sample, now);
- EXPECT_EQ(bw_sample, windowed_max_bw_.GetThirdBest());
- EXPECT_EQ(bw_sample, windowed_max_bw_.GetSecondBest());
- EXPECT_EQ(QuicBandwidth::FromBitsPerSecond(900), windowed_max_bw_.GetBest());
-}
-
-TEST_F(WindowedFilterTest, SampleChangesAllMins) {
- InitializeMinFilter();
- // RTT sample lower than the first-choice min-rtt sets that and also
- // the second and third-choice mins.
- QuicTime::Delta rtt_sample =
- windowed_min_rtt_.GetBest() - QuicTime::Delta::FromMilliseconds(5);
- // This assert is necessary to avoid triggering -Wstrict-overflow
- // See crbug/616957
- ASSERT_GT(windowed_min_rtt_.GetBest(), QuicTime::Delta::FromMilliseconds(5));
- // Latest sample was recorded at 100ms.
- QuicTime now = QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(101);
- windowed_min_rtt_.Update(rtt_sample, now);
- EXPECT_EQ(rtt_sample, windowed_min_rtt_.GetThirdBest());
- EXPECT_EQ(rtt_sample, windowed_min_rtt_.GetSecondBest());
- EXPECT_EQ(rtt_sample, windowed_min_rtt_.GetBest());
-}
-
-TEST_F(WindowedFilterTest, SampleChangesAllMaxs) {
- InitializeMaxFilter();
- // BW sample higher than the first-choice max sets that and also
- // the second and third-choice maxs.
- QuicBandwidth bw_sample =
- windowed_max_bw_.GetBest() + QuicBandwidth::FromBitsPerSecond(50);
- // Latest sample was recorded at 100ms.
- QuicTime now = QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(101);
- windowed_max_bw_.Update(bw_sample, now);
- EXPECT_EQ(bw_sample, windowed_max_bw_.GetThirdBest());
- EXPECT_EQ(bw_sample, windowed_max_bw_.GetSecondBest());
- EXPECT_EQ(bw_sample, windowed_max_bw_.GetBest());
-}
-
-TEST_F(WindowedFilterTest, ExpireBestMin) {
- InitializeMinFilter();
- QuicTime::Delta old_third_best = windowed_min_rtt_.GetThirdBest();
- QuicTime::Delta old_second_best = windowed_min_rtt_.GetSecondBest();
- QuicTime::Delta rtt_sample =
- old_third_best + QuicTime::Delta::FromMilliseconds(5);
- // Best min sample was recorded at 25ms, so expiry time is 124ms.
- QuicTime now = QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(125);
- windowed_min_rtt_.Update(rtt_sample, now);
- EXPECT_EQ(rtt_sample, windowed_min_rtt_.GetThirdBest());
- EXPECT_EQ(old_third_best, windowed_min_rtt_.GetSecondBest());
- EXPECT_EQ(old_second_best, windowed_min_rtt_.GetBest());
-}
-
-TEST_F(WindowedFilterTest, ExpireBestMax) {
- InitializeMaxFilter();
- QuicBandwidth old_third_best = windowed_max_bw_.GetThirdBest();
- QuicBandwidth old_second_best = windowed_max_bw_.GetSecondBest();
- QuicBandwidth bw_sample =
- old_third_best - QuicBandwidth::FromBitsPerSecond(50);
- // Best max sample was recorded at 25ms, so expiry time is 124ms.
- QuicTime now = QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(125);
- windowed_max_bw_.Update(bw_sample, now);
- EXPECT_EQ(bw_sample, windowed_max_bw_.GetThirdBest());
- EXPECT_EQ(old_third_best, windowed_max_bw_.GetSecondBest());
- EXPECT_EQ(old_second_best, windowed_max_bw_.GetBest());
-}
-
-TEST_F(WindowedFilterTest, ExpireSecondBestMin) {
- InitializeMinFilter();
- QuicTime::Delta old_third_best = windowed_min_rtt_.GetThirdBest();
- QuicTime::Delta rtt_sample =
- old_third_best + QuicTime::Delta::FromMilliseconds(5);
- // Second best min sample was recorded at 75ms, so expiry time is 174ms.
- QuicTime now = QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(175);
- windowed_min_rtt_.Update(rtt_sample, now);
- EXPECT_EQ(rtt_sample, windowed_min_rtt_.GetThirdBest());
- EXPECT_EQ(rtt_sample, windowed_min_rtt_.GetSecondBest());
- EXPECT_EQ(old_third_best, windowed_min_rtt_.GetBest());
-}
-
-TEST_F(WindowedFilterTest, ExpireSecondBestMax) {
- InitializeMaxFilter();
- QuicBandwidth old_third_best = windowed_max_bw_.GetThirdBest();
- QuicBandwidth bw_sample =
- old_third_best - QuicBandwidth::FromBitsPerSecond(50);
- // Second best max sample was recorded at 75ms, so expiry time is 174ms.
- QuicTime now = QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(175);
- windowed_max_bw_.Update(bw_sample, now);
- EXPECT_EQ(bw_sample, windowed_max_bw_.GetThirdBest());
- EXPECT_EQ(bw_sample, windowed_max_bw_.GetSecondBest());
- EXPECT_EQ(old_third_best, windowed_max_bw_.GetBest());
-}
-
-TEST_F(WindowedFilterTest, ExpireAllMins) {
- InitializeMinFilter();
- QuicTime::Delta rtt_sample =
- windowed_min_rtt_.GetThirdBest() + QuicTime::Delta::FromMilliseconds(5);
- // This assert is necessary to avoid triggering -Wstrict-overflow
- // See crbug/616957
- ASSERT_LT(windowed_min_rtt_.GetThirdBest(),
- QuicTime::Delta::Infinite() - QuicTime::Delta::FromMilliseconds(5));
- // Third best min sample was recorded at 100ms, so expiry time is 199ms.
- QuicTime now = QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(200);
- windowed_min_rtt_.Update(rtt_sample, now);
- EXPECT_EQ(rtt_sample, windowed_min_rtt_.GetThirdBest());
- EXPECT_EQ(rtt_sample, windowed_min_rtt_.GetSecondBest());
- EXPECT_EQ(rtt_sample, windowed_min_rtt_.GetBest());
-}
-
-TEST_F(WindowedFilterTest, ExpireAllMaxs) {
- InitializeMaxFilter();
- QuicBandwidth bw_sample =
- windowed_max_bw_.GetThirdBest() - QuicBandwidth::FromBitsPerSecond(50);
- // Third best max sample was recorded at 100ms, so expiry time is 199ms.
- QuicTime now = QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(200);
- windowed_max_bw_.Update(bw_sample, now);
- EXPECT_EQ(bw_sample, windowed_max_bw_.GetThirdBest());
- EXPECT_EQ(bw_sample, windowed_max_bw_.GetSecondBest());
- EXPECT_EQ(bw_sample, windowed_max_bw_.GetBest());
-}
-
-// Test the windowed filter where the time used is an exact counter instead of a
-// timestamp. This is useful if, for example, the time is measured in round
-// trips.
-TEST_F(WindowedFilterTest, ExpireCounterBasedMax) {
- // Create a window which starts at t = 0 and expires after two cycles.
- WindowedFilter<uint64_t, MaxFilter<uint64_t>, uint64_t, uint64_t> max_filter(
- 2, 0, 0);
-
- const uint64_t kBest = 50000;
- // Insert 50000 at t = 1.
- max_filter.Update(50000, 1);
- EXPECT_EQ(kBest, max_filter.GetBest());
- UpdateWithIrrelevantSamples(&max_filter, 20, 1);
- EXPECT_EQ(kBest, max_filter.GetBest());
-
- // Insert 40000 at t = 2. Nothing is expected to expire.
- max_filter.Update(40000, 2);
- EXPECT_EQ(kBest, max_filter.GetBest());
- UpdateWithIrrelevantSamples(&max_filter, 20, 2);
- EXPECT_EQ(kBest, max_filter.GetBest());
-
- // Insert 30000 at t = 3. Nothing is expected to expire yet.
- max_filter.Update(30000, 3);
- EXPECT_EQ(kBest, max_filter.GetBest());
- UpdateWithIrrelevantSamples(&max_filter, 20, 3);
- EXPECT_EQ(kBest, max_filter.GetBest());
- QUIC_VLOG(0) << max_filter.GetSecondBest();
- QUIC_VLOG(0) << max_filter.GetThirdBest();
-
- // Insert 20000 at t = 4. 50000 at t = 1 expires, so 40000 becomes the new
- // maximum.
- const uint64_t kNewBest = 40000;
- max_filter.Update(20000, 4);
- EXPECT_EQ(kNewBest, max_filter.GetBest());
- UpdateWithIrrelevantSamples(&max_filter, 20, 4);
- EXPECT_EQ(kNewBest, max_filter.GetBest());
-}
-
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/aead_base_decrypter.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/aead_base_decrypter.cc
deleted file mode 100644
index 69724ba88fc..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/aead_base_decrypter.cc
+++ /dev/null
@@ -1,214 +0,0 @@
-// Copyright (c) 2013 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 "quic/core/crypto/aead_base_decrypter.h"
-
-#include <cstdint>
-#include <string>
-
-#include "absl/base/macros.h"
-#include "absl/strings/string_view.h"
-#include "third_party/boringssl/src/include/openssl/crypto.h"
-#include "third_party/boringssl/src/include/openssl/err.h"
-#include "third_party/boringssl/src/include/openssl/evp.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-namespace {
-
-// Clear OpenSSL error stack.
-void ClearOpenSslErrors() {
- while (ERR_get_error()) {
- }
-}
-
-// In debug builds only, log OpenSSL error stack. Then clear OpenSSL error
-// stack.
-void DLogOpenSslErrors() {
-#ifdef NDEBUG
- ClearOpenSslErrors();
-#else
- while (uint32_t error = ERR_get_error()) {
- char buf[120];
- ERR_error_string_n(error, buf, ABSL_ARRAYSIZE(buf));
- QUIC_DLOG(ERROR) << "OpenSSL error: " << buf;
- }
-#endif
-}
-
-const EVP_AEAD* InitAndCall(const EVP_AEAD* (*aead_getter)()) {
- // Ensure BoringSSL is initialized before calling |aead_getter|. In Chromium,
- // the static initializer is disabled.
- CRYPTO_library_init();
- return aead_getter();
-}
-
-} // namespace
-
-AeadBaseDecrypter::AeadBaseDecrypter(const EVP_AEAD* (*aead_getter)(),
- size_t key_size,
- size_t auth_tag_size,
- size_t nonce_size,
- bool use_ietf_nonce_construction)
- : aead_alg_(InitAndCall(aead_getter)),
- key_size_(key_size),
- auth_tag_size_(auth_tag_size),
- nonce_size_(nonce_size),
- use_ietf_nonce_construction_(use_ietf_nonce_construction),
- have_preliminary_key_(false) {
- QUICHE_DCHECK_GT(256u, key_size);
- QUICHE_DCHECK_GT(256u, auth_tag_size);
- QUICHE_DCHECK_GT(256u, nonce_size);
- QUICHE_DCHECK_LE(key_size_, sizeof(key_));
- QUICHE_DCHECK_LE(nonce_size_, sizeof(iv_));
-}
-
-AeadBaseDecrypter::~AeadBaseDecrypter() {}
-
-bool AeadBaseDecrypter::SetKey(absl::string_view key) {
- QUICHE_DCHECK_EQ(key.size(), key_size_);
- if (key.size() != key_size_) {
- return false;
- }
- memcpy(key_, key.data(), key.size());
-
- EVP_AEAD_CTX_cleanup(ctx_.get());
- if (!EVP_AEAD_CTX_init(ctx_.get(), aead_alg_, key_, key_size_, auth_tag_size_,
- nullptr)) {
- DLogOpenSslErrors();
- return false;
- }
-
- return true;
-}
-
-bool AeadBaseDecrypter::SetNoncePrefix(absl::string_view nonce_prefix) {
- if (use_ietf_nonce_construction_) {
- QUIC_BUG(quic_bug_10709_1)
- << "Attempted to set nonce prefix on IETF QUIC crypter";
- return false;
- }
- QUICHE_DCHECK_EQ(nonce_prefix.size(), nonce_size_ - sizeof(QuicPacketNumber));
- if (nonce_prefix.size() != nonce_size_ - sizeof(QuicPacketNumber)) {
- return false;
- }
- memcpy(iv_, nonce_prefix.data(), nonce_prefix.size());
- return true;
-}
-
-bool AeadBaseDecrypter::SetIV(absl::string_view iv) {
- if (!use_ietf_nonce_construction_) {
- QUIC_BUG(quic_bug_10709_2) << "Attempted to set IV on Google QUIC crypter";
- return false;
- }
- QUICHE_DCHECK_EQ(iv.size(), nonce_size_);
- if (iv.size() != nonce_size_) {
- return false;
- }
- memcpy(iv_, iv.data(), iv.size());
- return true;
-}
-
-bool AeadBaseDecrypter::SetPreliminaryKey(absl::string_view key) {
- QUICHE_DCHECK(!have_preliminary_key_);
- SetKey(key);
- have_preliminary_key_ = true;
-
- return true;
-}
-
-bool AeadBaseDecrypter::SetDiversificationNonce(
- const DiversificationNonce& nonce) {
- if (!have_preliminary_key_) {
- return true;
- }
-
- std::string key, nonce_prefix;
- size_t prefix_size = nonce_size_;
- if (!use_ietf_nonce_construction_) {
- prefix_size -= sizeof(QuicPacketNumber);
- }
- DiversifyPreliminaryKey(
- absl::string_view(reinterpret_cast<const char*>(key_), key_size_),
- absl::string_view(reinterpret_cast<const char*>(iv_), prefix_size), nonce,
- key_size_, prefix_size, &key, &nonce_prefix);
-
- if (!SetKey(key) ||
- (!use_ietf_nonce_construction_ && !SetNoncePrefix(nonce_prefix)) ||
- (use_ietf_nonce_construction_ && !SetIV(nonce_prefix))) {
- QUICHE_DCHECK(false);
- return false;
- }
-
- have_preliminary_key_ = false;
- return true;
-}
-
-bool AeadBaseDecrypter::DecryptPacket(uint64_t packet_number,
- absl::string_view associated_data,
- absl::string_view ciphertext,
- char* output,
- size_t* output_length,
- size_t max_output_length) {
- if (ciphertext.length() < auth_tag_size_) {
- return false;
- }
-
- if (have_preliminary_key_) {
- QUIC_BUG(quic_bug_10709_3)
- << "Unable to decrypt while key diversification is pending";
- return false;
- }
-
- uint8_t nonce[kMaxNonceSize];
- memcpy(nonce, iv_, nonce_size_);
- size_t prefix_len = nonce_size_ - sizeof(packet_number);
- if (use_ietf_nonce_construction_) {
- for (size_t i = 0; i < sizeof(packet_number); ++i) {
- nonce[prefix_len + i] ^=
- (packet_number >> ((sizeof(packet_number) - i - 1) * 8)) & 0xff;
- }
- } else {
- memcpy(nonce + prefix_len, &packet_number, sizeof(packet_number));
- }
- if (!EVP_AEAD_CTX_open(
- ctx_.get(), reinterpret_cast<uint8_t*>(output), output_length,
- max_output_length, reinterpret_cast<const uint8_t*>(nonce),
- nonce_size_, reinterpret_cast<const uint8_t*>(ciphertext.data()),
- ciphertext.size(),
- reinterpret_cast<const uint8_t*>(associated_data.data()),
- associated_data.size())) {
- // Because QuicFramer does trial decryption, decryption errors are expected
- // when encryption level changes. So we don't log decryption errors.
- ClearOpenSslErrors();
- return false;
- }
- return true;
-}
-
-size_t AeadBaseDecrypter::GetKeySize() const {
- return key_size_;
-}
-
-size_t AeadBaseDecrypter::GetNoncePrefixSize() const {
- return nonce_size_ - sizeof(QuicPacketNumber);
-}
-
-size_t AeadBaseDecrypter::GetIVSize() const {
- return nonce_size_;
-}
-
-absl::string_view AeadBaseDecrypter::GetKey() const {
- return absl::string_view(reinterpret_cast<const char*>(key_), key_size_);
-}
-
-absl::string_view AeadBaseDecrypter::GetNoncePrefix() const {
- return absl::string_view(reinterpret_cast<const char*>(iv_),
- nonce_size_ - sizeof(QuicPacketNumber));
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/aead_base_decrypter.h b/chromium/net/third_party/quiche/src/quic/core/crypto/aead_base_decrypter.h
deleted file mode 100644
index 1d4598b38ca..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/aead_base_decrypter.h
+++ /dev/null
@@ -1,74 +0,0 @@
-// Copyright (c) 2013 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_CRYPTO_AEAD_BASE_DECRYPTER_H_
-#define QUICHE_QUIC_CORE_CRYPTO_AEAD_BASE_DECRYPTER_H_
-
-#include <cstddef>
-
-#include "absl/strings/string_view.h"
-#include "third_party/boringssl/src/include/openssl/aead.h"
-#include "quic/core/crypto/quic_decrypter.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// AeadBaseDecrypter is the base class of AEAD QuicDecrypter subclasses.
-class QUIC_EXPORT_PRIVATE AeadBaseDecrypter : public QuicDecrypter {
- public:
- // This takes the function pointer rather than the EVP_AEAD itself so
- // subclasses do not need to call CRYPTO_library_init.
- AeadBaseDecrypter(const EVP_AEAD* (*aead_getter)(),
- size_t key_size,
- size_t auth_tag_size,
- size_t nonce_size,
- bool use_ietf_nonce_construction);
- AeadBaseDecrypter(const AeadBaseDecrypter&) = delete;
- AeadBaseDecrypter& operator=(const AeadBaseDecrypter&) = delete;
- ~AeadBaseDecrypter() override;
-
- // QuicDecrypter implementation
- bool SetKey(absl::string_view key) override;
- bool SetNoncePrefix(absl::string_view nonce_prefix) override;
- bool SetIV(absl::string_view iv) override;
- bool SetPreliminaryKey(absl::string_view key) override;
- bool SetDiversificationNonce(const DiversificationNonce& nonce) override;
- bool DecryptPacket(uint64_t packet_number,
- absl::string_view associated_data,
- absl::string_view ciphertext,
- char* output,
- size_t* output_length,
- size_t max_output_length) override;
- size_t GetKeySize() const override;
- size_t GetNoncePrefixSize() const override;
- size_t GetIVSize() const override;
- absl::string_view GetKey() const override;
- absl::string_view GetNoncePrefix() const override;
-
- protected:
- // Make these constants available to the subclasses so that the subclasses
- // can assert at compile time their key_size_ and nonce_size_ do not
- // exceed the maximum.
- static const size_t kMaxKeySize = 32;
- static const size_t kMaxNonceSize = 12;
-
- private:
- const EVP_AEAD* const aead_alg_;
- const size_t key_size_;
- const size_t auth_tag_size_;
- const size_t nonce_size_;
- const bool use_ietf_nonce_construction_;
- bool have_preliminary_key_;
-
- // The key.
- unsigned char key_[kMaxKeySize];
- // The IV used to construct the nonce.
- unsigned char iv_[kMaxNonceSize];
-
- bssl::ScopedEVP_AEAD_CTX ctx_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_CRYPTO_AEAD_BASE_DECRYPTER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/aead_base_encrypter.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/aead_base_encrypter.cc
deleted file mode 100644
index f4878e5a6d0..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/aead_base_encrypter.cc
+++ /dev/null
@@ -1,188 +0,0 @@
-// Copyright (c) 2013 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 "quic/core/crypto/aead_base_encrypter.h"
-
-#include "absl/base/macros.h"
-#include "absl/strings/string_view.h"
-#include "third_party/boringssl/src/include/openssl/crypto.h"
-#include "third_party/boringssl/src/include/openssl/err.h"
-#include "third_party/boringssl/src/include/openssl/evp.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-namespace {
-
-// In debug builds only, log OpenSSL error stack. Then clear OpenSSL error
-// stack.
-void DLogOpenSslErrors() {
-#ifdef NDEBUG
- while (ERR_get_error()) {
- }
-#else
- while (unsigned long error = ERR_get_error()) {
- char buf[120];
- ERR_error_string_n(error, buf, ABSL_ARRAYSIZE(buf));
- QUIC_DLOG(ERROR) << "OpenSSL error: " << buf;
- }
-#endif
-}
-
-const EVP_AEAD* InitAndCall(const EVP_AEAD* (*aead_getter)()) {
- // Ensure BoringSSL is initialized before calling |aead_getter|. In Chromium,
- // the static initializer is disabled.
- CRYPTO_library_init();
- return aead_getter();
-}
-
-} // namespace
-
-AeadBaseEncrypter::AeadBaseEncrypter(const EVP_AEAD* (*aead_getter)(),
- size_t key_size,
- size_t auth_tag_size,
- size_t nonce_size,
- bool use_ietf_nonce_construction)
- : aead_alg_(InitAndCall(aead_getter)),
- key_size_(key_size),
- auth_tag_size_(auth_tag_size),
- nonce_size_(nonce_size),
- use_ietf_nonce_construction_(use_ietf_nonce_construction) {
- QUICHE_DCHECK_LE(key_size_, sizeof(key_));
- QUICHE_DCHECK_LE(nonce_size_, sizeof(iv_));
- QUICHE_DCHECK_GE(kMaxNonceSize, nonce_size_);
-}
-
-AeadBaseEncrypter::~AeadBaseEncrypter() {}
-
-bool AeadBaseEncrypter::SetKey(absl::string_view key) {
- QUICHE_DCHECK_EQ(key.size(), key_size_);
- if (key.size() != key_size_) {
- return false;
- }
- memcpy(key_, key.data(), key.size());
-
- EVP_AEAD_CTX_cleanup(ctx_.get());
-
- if (!EVP_AEAD_CTX_init(ctx_.get(), aead_alg_, key_, key_size_, auth_tag_size_,
- nullptr)) {
- DLogOpenSslErrors();
- return false;
- }
-
- return true;
-}
-
-bool AeadBaseEncrypter::SetNoncePrefix(absl::string_view nonce_prefix) {
- if (use_ietf_nonce_construction_) {
- QUIC_BUG(quic_bug_10634_1)
- << "Attempted to set nonce prefix on IETF QUIC crypter";
- return false;
- }
- QUICHE_DCHECK_EQ(nonce_prefix.size(), nonce_size_ - sizeof(QuicPacketNumber));
- if (nonce_prefix.size() != nonce_size_ - sizeof(QuicPacketNumber)) {
- return false;
- }
- memcpy(iv_, nonce_prefix.data(), nonce_prefix.size());
- return true;
-}
-
-bool AeadBaseEncrypter::SetIV(absl::string_view iv) {
- if (!use_ietf_nonce_construction_) {
- QUIC_BUG(quic_bug_10634_2) << "Attempted to set IV on Google QUIC crypter";
- return false;
- }
- QUICHE_DCHECK_EQ(iv.size(), nonce_size_);
- if (iv.size() != nonce_size_) {
- return false;
- }
- memcpy(iv_, iv.data(), iv.size());
- return true;
-}
-
-bool AeadBaseEncrypter::Encrypt(absl::string_view nonce,
- absl::string_view associated_data,
- absl::string_view plaintext,
- unsigned char* output) {
- QUICHE_DCHECK_EQ(nonce.size(), nonce_size_);
-
- size_t ciphertext_len;
- if (!EVP_AEAD_CTX_seal(
- ctx_.get(), output, &ciphertext_len,
- plaintext.size() + auth_tag_size_,
- reinterpret_cast<const uint8_t*>(nonce.data()), nonce.size(),
- reinterpret_cast<const uint8_t*>(plaintext.data()), plaintext.size(),
- reinterpret_cast<const uint8_t*>(associated_data.data()),
- associated_data.size())) {
- DLogOpenSslErrors();
- return false;
- }
-
- return true;
-}
-
-bool AeadBaseEncrypter::EncryptPacket(uint64_t packet_number,
- absl::string_view associated_data,
- absl::string_view plaintext,
- char* output,
- size_t* output_length,
- size_t max_output_length) {
- size_t ciphertext_size = GetCiphertextSize(plaintext.length());
- if (max_output_length < ciphertext_size) {
- return false;
- }
- // TODO(ianswett): Introduce a check to ensure that we don't encrypt with the
- // same packet number twice.
- alignas(4) char nonce_buffer[kMaxNonceSize];
- memcpy(nonce_buffer, iv_, nonce_size_);
- size_t prefix_len = nonce_size_ - sizeof(packet_number);
- if (use_ietf_nonce_construction_) {
- for (size_t i = 0; i < sizeof(packet_number); ++i) {
- nonce_buffer[prefix_len + i] ^=
- (packet_number >> ((sizeof(packet_number) - i - 1) * 8)) & 0xff;
- }
- } else {
- memcpy(nonce_buffer + prefix_len, &packet_number, sizeof(packet_number));
- }
-
- if (!Encrypt(absl::string_view(nonce_buffer, nonce_size_), associated_data,
- plaintext, reinterpret_cast<unsigned char*>(output))) {
- return false;
- }
- *output_length = ciphertext_size;
- return true;
-}
-
-size_t AeadBaseEncrypter::GetKeySize() const {
- return key_size_;
-}
-
-size_t AeadBaseEncrypter::GetNoncePrefixSize() const {
- return nonce_size_ - sizeof(QuicPacketNumber);
-}
-
-size_t AeadBaseEncrypter::GetIVSize() const {
- return nonce_size_;
-}
-
-size_t AeadBaseEncrypter::GetMaxPlaintextSize(size_t ciphertext_size) const {
- return ciphertext_size - std::min(ciphertext_size, auth_tag_size_);
-}
-
-size_t AeadBaseEncrypter::GetCiphertextSize(size_t plaintext_size) const {
- return plaintext_size + auth_tag_size_;
-}
-
-absl::string_view AeadBaseEncrypter::GetKey() const {
- return absl::string_view(reinterpret_cast<const char*>(key_), key_size_);
-}
-
-absl::string_view AeadBaseEncrypter::GetNoncePrefix() const {
- return absl::string_view(reinterpret_cast<const char*>(iv_),
- GetNoncePrefixSize());
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/aead_base_encrypter.h b/chromium/net/third_party/quiche/src/quic/core/crypto/aead_base_encrypter.h
deleted file mode 100644
index 7571a651d7c..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/aead_base_encrypter.h
+++ /dev/null
@@ -1,80 +0,0 @@
-// Copyright (c) 2013 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_CRYPTO_AEAD_BASE_ENCRYPTER_H_
-#define QUICHE_QUIC_CORE_CRYPTO_AEAD_BASE_ENCRYPTER_H_
-
-#include <cstddef>
-
-#include "absl/strings/string_view.h"
-#include "third_party/boringssl/src/include/openssl/aead.h"
-#include "quic/core/crypto/quic_encrypter.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// AeadBaseEncrypter is the base class of AEAD QuicEncrypter subclasses.
-class QUIC_EXPORT_PRIVATE AeadBaseEncrypter : public QuicEncrypter {
- public:
- // This takes the function pointer rather than the EVP_AEAD itself so
- // subclasses do not need to call CRYPTO_library_init.
- AeadBaseEncrypter(const EVP_AEAD* (*aead_getter)(),
- size_t key_size,
- size_t auth_tag_size,
- size_t nonce_size,
- bool use_ietf_nonce_construction);
- AeadBaseEncrypter(const AeadBaseEncrypter&) = delete;
- AeadBaseEncrypter& operator=(const AeadBaseEncrypter&) = delete;
- ~AeadBaseEncrypter() override;
-
- // QuicEncrypter implementation
- bool SetKey(absl::string_view key) override;
- bool SetNoncePrefix(absl::string_view nonce_prefix) override;
- bool SetIV(absl::string_view iv) override;
- bool EncryptPacket(uint64_t packet_number,
- absl::string_view associated_data,
- absl::string_view plaintext,
- char* output,
- size_t* output_length,
- size_t max_output_length) override;
- size_t GetKeySize() const override;
- size_t GetNoncePrefixSize() const override;
- size_t GetIVSize() const override;
- size_t GetMaxPlaintextSize(size_t ciphertext_size) const override;
- size_t GetCiphertextSize(size_t plaintext_size) const override;
- absl::string_view GetKey() const override;
- absl::string_view GetNoncePrefix() const override;
-
- // Necessary so unit tests can explicitly specify a nonce, instead of an IV
- // (or nonce prefix) and packet number.
- bool Encrypt(absl::string_view nonce,
- absl::string_view associated_data,
- absl::string_view plaintext,
- unsigned char* output);
-
- protected:
- // Make these constants available to the subclasses so that the subclasses
- // can assert at compile time their key_size_ and nonce_size_ do not
- // exceed the maximum.
- static const size_t kMaxKeySize = 32;
- enum : size_t { kMaxNonceSize = 12 };
-
- private:
- const EVP_AEAD* const aead_alg_;
- const size_t key_size_;
- const size_t auth_tag_size_;
- const size_t nonce_size_;
- const bool use_ietf_nonce_construction_;
-
- // The key.
- unsigned char key_[kMaxKeySize];
- // The IV used to construct the nonce.
- unsigned char iv_[kMaxNonceSize];
-
- bssl::ScopedEVP_AEAD_CTX ctx_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_CRYPTO_AEAD_BASE_ENCRYPTER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/aes_128_gcm_12_decrypter.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/aes_128_gcm_12_decrypter.cc
deleted file mode 100644
index 579ff923d56..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/aes_128_gcm_12_decrypter.cc
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright (c) 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/crypto/aes_128_gcm_12_decrypter.h"
-
-#include "third_party/boringssl/src/include/openssl/aead.h"
-#include "third_party/boringssl/src/include/openssl/tls1.h"
-
-namespace quic {
-
-namespace {
-
-const size_t kKeySize = 16;
-const size_t kNonceSize = 12;
-
-} // namespace
-
-Aes128Gcm12Decrypter::Aes128Gcm12Decrypter()
- : AesBaseDecrypter(EVP_aead_aes_128_gcm,
- kKeySize,
- kAuthTagSize,
- kNonceSize,
- /* use_ietf_nonce_construction */ false) {
- static_assert(kKeySize <= kMaxKeySize, "key size too big");
- static_assert(kNonceSize <= kMaxNonceSize, "nonce size too big");
-}
-
-Aes128Gcm12Decrypter::~Aes128Gcm12Decrypter() {}
-
-uint32_t Aes128Gcm12Decrypter::cipher_id() const {
- return TLS1_CK_AES_128_GCM_SHA256;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/aes_128_gcm_12_decrypter.h b/chromium/net/third_party/quiche/src/quic/core/crypto/aes_128_gcm_12_decrypter.h
deleted file mode 100644
index fbd8d51fb04..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/aes_128_gcm_12_decrypter.h
+++ /dev/null
@@ -1,38 +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_CORE_CRYPTO_AES_128_GCM_12_DECRYPTER_H_
-#define QUICHE_QUIC_CORE_CRYPTO_AES_128_GCM_12_DECRYPTER_H_
-
-#include <cstdint>
-
-#include "quic/core/crypto/aes_base_decrypter.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// An Aes128Gcm12Decrypter is a QuicDecrypter that implements the
-// AEAD_AES_128_GCM_12 algorithm specified in RFC 5282. Create an instance by
-// calling QuicDecrypter::Create(kAESG).
-//
-// It uses an authentication tag of 12 bytes (96 bits). The fixed prefix
-// of the nonce is four bytes.
-class QUIC_EXPORT_PRIVATE Aes128Gcm12Decrypter : public AesBaseDecrypter {
- public:
- enum {
- // Authentication tags are truncated to 96 bits.
- kAuthTagSize = 12,
- };
-
- Aes128Gcm12Decrypter();
- Aes128Gcm12Decrypter(const Aes128Gcm12Decrypter&) = delete;
- Aes128Gcm12Decrypter& operator=(const Aes128Gcm12Decrypter&) = delete;
- ~Aes128Gcm12Decrypter() override;
-
- uint32_t cipher_id() const override;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_CRYPTO_AES_128_GCM_12_DECRYPTER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/aes_128_gcm_12_decrypter_test.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/aes_128_gcm_12_decrypter_test.cc
deleted file mode 100644
index dccd7dfa48d..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/aes_128_gcm_12_decrypter_test.cc
+++ /dev/null
@@ -1,288 +0,0 @@
-// Copyright (c) 2013 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 "quic/core/crypto/aes_128_gcm_12_decrypter.h"
-
-#include <memory>
-#include <string>
-
-#include "absl/base/macros.h"
-#include "absl/strings/escaping.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/quic_test_utils.h"
-#include "common/test_tools/quiche_test_utils.h"
-
-namespace {
-
-// The AES GCM test vectors come from the file gcmDecrypt128.rsp
-// downloaded from http://csrc.nist.gov/groups/STM/cavp/index.html on
-// 2013-02-01. The test vectors in that file look like this:
-//
-// [Keylen = 128]
-// [IVlen = 96]
-// [PTlen = 0]
-// [AADlen = 0]
-// [Taglen = 128]
-//
-// Count = 0
-// Key = cf063a34d4a9a76c2c86787d3f96db71
-// IV = 113b9785971864c83b01c787
-// CT =
-// AAD =
-// Tag = 72ac8493e3a5228b5d130a69d2510e42
-// PT =
-//
-// Count = 1
-// Key = a49a5e26a2f8cb63d05546c2a62f5343
-// IV = 907763b19b9b4ab6bd4f0281
-// CT =
-// AAD =
-// Tag = a2be08210d8c470a8df6e8fbd79ec5cf
-// FAIL
-//
-// ...
-//
-// The gcmDecrypt128.rsp file is huge (2.6 MB), so I selected just a
-// few test vectors for this unit test.
-
-// Describes a group of test vectors that all have a given key length, IV
-// length, plaintext length, AAD length, and tag length.
-struct TestGroupInfo {
- size_t key_len;
- size_t iv_len;
- size_t pt_len;
- size_t aad_len;
- size_t tag_len;
-};
-
-// Each test vector consists of six strings of lowercase hexadecimal digits.
-// The strings may be empty (zero length). A test vector with a nullptr |key|
-// marks the end of an array of test vectors.
-struct TestVector {
- // Input:
- const char* key;
- const char* iv;
- const char* ct;
- const char* aad;
- const char* tag;
-
- // Expected output:
- const char* pt; // An empty string "" means decryption succeeded and
- // the plaintext is zero-length. nullptr means decryption
- // failed.
-};
-
-const TestGroupInfo test_group_info[] = {
- {128, 96, 0, 0, 128}, {128, 96, 0, 128, 128}, {128, 96, 128, 0, 128},
- {128, 96, 408, 160, 128}, {128, 96, 408, 720, 128}, {128, 96, 104, 0, 128},
-};
-
-const TestVector test_group_0[] = {
- {"cf063a34d4a9a76c2c86787d3f96db71", "113b9785971864c83b01c787", "", "",
- "72ac8493e3a5228b5d130a69d2510e42", ""},
- {
- "a49a5e26a2f8cb63d05546c2a62f5343", "907763b19b9b4ab6bd4f0281", "", "",
- "a2be08210d8c470a8df6e8fbd79ec5cf",
- nullptr // FAIL
- },
- {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
-
-const TestVector test_group_1[] = {
- {
- "d1f6af919cde85661208bdce0c27cb22", "898c6929b435017bf031c3c5", "",
- "7c5faa40e636bbc91107e68010c92b9f", "ae45f11777540a2caeb128be8092468a",
- nullptr // FAIL
- },
- {"2370e320d4344208e0ff5683f243b213", "04dbb82f044d30831c441228", "",
- "d43a8e5089eea0d026c03a85178b27da", "2a049c049d25aa95969b451d93c31c6e",
- ""},
- {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
-
-const TestVector test_group_2[] = {
- {"e98b72a9881a84ca6b76e0f43e68647a", "8b23299fde174053f3d652ba",
- "5a3c1cf1985dbb8bed818036fdd5ab42", "", "23c7ab0f952b7091cd324835043b5eb5",
- "28286a321293253c3e0aa2704a278032"},
- {"33240636cd3236165f1a553b773e728e", "17c4d61493ecdc8f31700b12",
- "47bb7e23f7bdfe05a8091ac90e4f8b2e", "", "b723c70e931d9785f40fd4ab1d612dc9",
- "95695a5b12f2870b9cc5fdc8f218a97d"},
- {
- "5164df856f1e9cac04a79b808dc5be39", "e76925d5355e0584ce871b2b",
- "0216c899c88d6e32c958c7e553daa5bc", "",
- "a145319896329c96df291f64efbe0e3a",
- nullptr // FAIL
- },
- {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
-
-const TestVector test_group_3[] = {
- {"af57f42c60c0fc5a09adb81ab86ca1c3", "a2dc01871f37025dc0fc9a79",
- "b9a535864f48ea7b6b1367914978f9bfa087d854bb0e269bed8d279d2eea1210e48947"
- "338b22f9bad09093276a331e9c79c7f4",
- "41dc38988945fcb44faf2ef72d0061289ef8efd8",
- "4f71e72bde0018f555c5adcce062e005",
- "3803a0727eeb0ade441e0ec107161ded2d425ec0d102f21f51bf2cf9947c7ec4aa7279"
- "5b2f69b041596e8817d0a3c16f8fadeb"},
- {"ebc753e5422b377d3cb64b58ffa41b61", "2e1821efaced9acf1f241c9b",
- "069567190554e9ab2b50a4e1fbf9c147340a5025fdbd201929834eaf6532325899ccb9"
- "f401823e04b05817243d2142a3589878",
- "b9673412fd4f88ba0e920f46dd6438ff791d8eef",
- "534d9234d2351cf30e565de47baece0b",
- "39077edb35e9c5a4b1e4c2a6b9bb1fce77f00f5023af40333d6d699014c2bcf4209c18"
- "353a18017f5b36bfc00b1f6dcb7ed485"},
- {
- "52bdbbf9cf477f187ec010589cb39d58", "d3be36d3393134951d324b31",
- "700188da144fa692cf46e4a8499510a53d90903c967f7f13e8a1bd8151a74adc4fe63e"
- "32b992760b3a5f99e9a47838867000a9",
- "93c4fc6a4135f54d640b0c976bf755a06a292c33",
- "8ca4e38aa3dfa6b1d0297021ccf3ea5f",
- nullptr // FAIL
- },
- {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
-
-const TestVector test_group_4[] = {
- {"da2bb7d581493d692380c77105590201", "44aa3e7856ca279d2eb020c6",
- "9290d430c9e89c37f0446dbd620c9a6b34b1274aeb6f911f75867efcf95b6feda69f1a"
- "f4ee16c761b3c9aeac3da03aa9889c88",
- "4cd171b23bddb3a53cdf959d5c1710b481eb3785a90eb20a2345ee00d0bb7868c367ab"
- "12e6f4dd1dee72af4eee1d197777d1d6499cc541f34edbf45cda6ef90b3c024f9272d7"
- "2ec1909fb8fba7db88a4d6f7d3d925980f9f9f72",
- "9e3ac938d3eb0cadd6f5c9e35d22ba38",
- "9bbf4c1a2742f6ac80cb4e8a052e4a8f4f07c43602361355b717381edf9fabd4cb7e3a"
- "d65dbd1378b196ac270588dd0621f642"},
- {"d74e4958717a9d5c0e235b76a926cae8", "0b7471141e0c70b1995fd7b1",
- "e701c57d2330bf066f9ff8cf3ca4343cafe4894651cd199bdaaa681ba486b4a65c5a22"
- "b0f1420be29ea547d42c713bc6af66aa",
- "4a42b7aae8c245c6f1598a395316e4b8484dbd6e64648d5e302021b1d3fa0a38f46e22"
- "bd9c8080b863dc0016482538a8562a4bd0ba84edbe2697c76fd039527ac179ec5506cf"
- "34a6039312774cedebf4961f3978b14a26509f96",
- "e192c23cb036f0b31592989119eed55d",
- "840d9fb95e32559fb3602e48590280a172ca36d9b49ab69510f5bd552bfab7a306f85f"
- "f0a34bc305b88b804c60b90add594a17"},
- {
- "1986310c725ac94ecfe6422e75fc3ee7", "93ec4214fa8e6dc4e3afc775",
- "b178ec72f85a311ac4168f42a4b2c23113fbea4b85f4b9dabb74e143eb1b8b0a361e02"
- "43edfd365b90d5b325950df0ada058f9",
- "e80b88e62c49c958b5e0b8b54f532d9ff6aa84c8a40132e93e55b59fc24e8decf28463"
- "139f155d1e8ce4ee76aaeefcd245baa0fc519f83a5fb9ad9aa40c4b21126013f576c42"
- "72c2cb136c8fd091cc4539877a5d1e72d607f960",
- "8b347853f11d75e81e8a95010be81f17",
- nullptr // FAIL
- },
- {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
-
-const TestVector test_group_5[] = {
- {"387218b246c1a8257748b56980e50c94", "dd7e014198672be39f95b69d",
- "cdba9e73eaf3d38eceb2b04a8d", "", "ecf90f4a47c9c626d6fb2c765d201556",
- "48f5b426baca03064554cc2b30"},
- {"294de463721e359863887c820524b3d4", "3338b35c9d57a5d28190e8c9",
- "2f46634e74b8e4c89812ac83b9", "", "dabd506764e68b82a7e720aa18da0abe",
- "46a2e55c8e264df211bd112685"},
- {"28ead7fd2179e0d12aa6d5d88c58c2dc", "5055347f18b4d5add0ae5c41",
- "142d8210c3fb84774cdbd0447a", "", "5fd321d9cdb01952dc85f034736c2a7d",
- "3b95b981086ee73cc4d0cc1422"},
- {
- "7d7b6c988137b8d470c57bf674a09c87", "9edf2aa970d016ac962e1fd8",
- "a85b66c3cb5eab91d5bdc8bc0e", "", "dc054efc01f3afd21d9c2484819f569a",
- nullptr // FAIL
- },
- {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
-
-const TestVector* const test_group_array[] = {
- test_group_0, test_group_1, test_group_2,
- test_group_3, test_group_4, test_group_5,
-};
-
-} // namespace
-
-namespace quic {
-namespace test {
-
-// DecryptWithNonce wraps the |Decrypt| method of |decrypter| to allow passing
-// in an nonce and also to allocate the buffer needed for the plaintext.
-QuicData* DecryptWithNonce(Aes128Gcm12Decrypter* decrypter,
- absl::string_view nonce,
- absl::string_view associated_data,
- absl::string_view ciphertext) {
- uint64_t packet_number;
- absl::string_view nonce_prefix(nonce.data(),
- nonce.size() - sizeof(packet_number));
- decrypter->SetNoncePrefix(nonce_prefix);
- memcpy(&packet_number, nonce.data() + nonce_prefix.size(),
- sizeof(packet_number));
- std::unique_ptr<char[]> output(new char[ciphertext.length()]);
- size_t output_length = 0;
- const bool success = decrypter->DecryptPacket(
- packet_number, associated_data, ciphertext, output.get(), &output_length,
- ciphertext.length());
- if (!success) {
- return nullptr;
- }
- return new QuicData(output.release(), output_length, true);
-}
-
-class Aes128Gcm12DecrypterTest : public QuicTest {};
-
-TEST_F(Aes128Gcm12DecrypterTest, Decrypt) {
- for (size_t i = 0; i < ABSL_ARRAYSIZE(test_group_array); i++) {
- SCOPED_TRACE(i);
- const TestVector* test_vectors = test_group_array[i];
- const TestGroupInfo& test_info = test_group_info[i];
- for (size_t j = 0; test_vectors[j].key != nullptr; j++) {
- // If not present then decryption is expected to fail.
- bool has_pt = test_vectors[j].pt;
-
- // Decode the test vector.
- std::string key = absl::HexStringToBytes(test_vectors[j].key);
- std::string iv = absl::HexStringToBytes(test_vectors[j].iv);
- std::string ct = absl::HexStringToBytes(test_vectors[j].ct);
- std::string aad = absl::HexStringToBytes(test_vectors[j].aad);
- std::string tag = absl::HexStringToBytes(test_vectors[j].tag);
- std::string pt;
- if (has_pt) {
- pt = absl::HexStringToBytes(test_vectors[j].pt);
- }
-
- // The test vector's lengths should look sane. Note that the lengths
- // in |test_info| are in bits.
- EXPECT_EQ(test_info.key_len, key.length() * 8);
- EXPECT_EQ(test_info.iv_len, iv.length() * 8);
- EXPECT_EQ(test_info.pt_len, ct.length() * 8);
- EXPECT_EQ(test_info.aad_len, aad.length() * 8);
- EXPECT_EQ(test_info.tag_len, tag.length() * 8);
- if (has_pt) {
- EXPECT_EQ(test_info.pt_len, pt.length() * 8);
- }
-
- // The test vectors have 16 byte authenticators but this code only uses
- // the first 12.
- ASSERT_LE(static_cast<size_t>(Aes128Gcm12Decrypter::kAuthTagSize),
- tag.length());
- tag.resize(Aes128Gcm12Decrypter::kAuthTagSize);
- std::string ciphertext = ct + tag;
-
- Aes128Gcm12Decrypter decrypter;
- ASSERT_TRUE(decrypter.SetKey(key));
-
- std::unique_ptr<QuicData> decrypted(DecryptWithNonce(
- &decrypter, iv,
- // This deliberately tests that the decrypter can
- // handle an AAD that is set to nullptr, as opposed
- // to a zero-length, non-nullptr pointer.
- aad.length() ? aad : absl::string_view(), ciphertext));
- if (!decrypted) {
- EXPECT_FALSE(has_pt);
- continue;
- }
- EXPECT_TRUE(has_pt);
-
- ASSERT_EQ(pt.length(), decrypted->length());
- quiche::test::CompareCharArraysWithHexError(
- "plaintext", decrypted->data(), pt.length(), pt.data(), pt.length());
- }
- }
-}
-
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/aes_128_gcm_12_encrypter.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/aes_128_gcm_12_encrypter.cc
deleted file mode 100644
index 075a21b9ef5..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/aes_128_gcm_12_encrypter.cc
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright (c) 2013 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 "quic/core/crypto/aes_128_gcm_12_encrypter.h"
-
-#include "third_party/boringssl/src/include/openssl/evp.h"
-
-namespace quic {
-
-namespace {
-
-const size_t kKeySize = 16;
-const size_t kNonceSize = 12;
-
-} // namespace
-
-Aes128Gcm12Encrypter::Aes128Gcm12Encrypter()
- : AesBaseEncrypter(EVP_aead_aes_128_gcm,
- kKeySize,
- kAuthTagSize,
- kNonceSize,
- /* use_ietf_nonce_construction */ false) {
- static_assert(kKeySize <= kMaxKeySize, "key size too big");
- static_assert(kNonceSize <= kMaxNonceSize, "nonce size too big");
-}
-
-Aes128Gcm12Encrypter::~Aes128Gcm12Encrypter() {}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/aes_128_gcm_12_encrypter.h b/chromium/net/third_party/quiche/src/quic/core/crypto/aes_128_gcm_12_encrypter.h
deleted file mode 100644
index f457336c00e..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/aes_128_gcm_12_encrypter.h
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright (c) 2013 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_CRYPTO_AES_128_GCM_12_ENCRYPTER_H_
-#define QUICHE_QUIC_CORE_CRYPTO_AES_128_GCM_12_ENCRYPTER_H_
-
-#include "quic/core/crypto/aes_base_encrypter.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// An Aes128Gcm12Encrypter is a QuicEncrypter that implements the
-// AEAD_AES_128_GCM_12 algorithm specified in RFC 5282. Create an instance by
-// calling QuicEncrypter::Create(kAESG).
-//
-// It uses an authentication tag of 12 bytes (96 bits). The fixed prefix
-// of the nonce is four bytes.
-class QUIC_EXPORT_PRIVATE Aes128Gcm12Encrypter : public AesBaseEncrypter {
- public:
- enum {
- // Authentication tags are truncated to 96 bits.
- kAuthTagSize = 12,
- };
-
- Aes128Gcm12Encrypter();
- Aes128Gcm12Encrypter(const Aes128Gcm12Encrypter&) = delete;
- Aes128Gcm12Encrypter& operator=(const Aes128Gcm12Encrypter&) = delete;
- ~Aes128Gcm12Encrypter() override;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_CRYPTO_AES_128_GCM_12_ENCRYPTER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/aes_128_gcm_12_encrypter_test.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/aes_128_gcm_12_encrypter_test.cc
deleted file mode 100644
index 67e35ed8934..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/aes_128_gcm_12_encrypter_test.cc
+++ /dev/null
@@ -1,244 +0,0 @@
-// Copyright (c) 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/crypto/aes_128_gcm_12_encrypter.h"
-
-#include <memory>
-#include <string>
-
-#include "absl/base/macros.h"
-#include "absl/strings/escaping.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/quic_test_utils.h"
-#include "common/test_tools/quiche_test_utils.h"
-
-namespace {
-
-// The AES GCM test vectors come from the file gcmEncryptExtIV128.rsp
-// downloaded from http://csrc.nist.gov/groups/STM/cavp/index.html on
-// 2013-02-01. The test vectors in that file look like this:
-//
-// [Keylen = 128]
-// [IVlen = 96]
-// [PTlen = 0]
-// [AADlen = 0]
-// [Taglen = 128]
-//
-// Count = 0
-// Key = 11754cd72aec309bf52f7687212e8957
-// IV = 3c819d9a9bed087615030b65
-// PT =
-// AAD =
-// CT =
-// Tag = 250327c674aaf477aef2675748cf6971
-//
-// Count = 1
-// Key = ca47248ac0b6f8372a97ac43508308ed
-// IV = ffd2b598feabc9019262d2be
-// PT =
-// AAD =
-// CT =
-// Tag = 60d20404af527d248d893ae495707d1a
-//
-// ...
-//
-// The gcmEncryptExtIV128.rsp file is huge (2.8 MB), so I selected just a
-// few test vectors for this unit test.
-
-// Describes a group of test vectors that all have a given key length, IV
-// length, plaintext length, AAD length, and tag length.
-struct TestGroupInfo {
- size_t key_len;
- size_t iv_len;
- size_t pt_len;
- size_t aad_len;
- size_t tag_len;
-};
-
-// Each test vector consists of six strings of lowercase hexadecimal digits.
-// The strings may be empty (zero length). A test vector with a nullptr |key|
-// marks the end of an array of test vectors.
-struct TestVector {
- const char* key;
- const char* iv;
- const char* pt;
- const char* aad;
- const char* ct;
- const char* tag;
-};
-
-const TestGroupInfo test_group_info[] = {
- {128, 96, 0, 0, 128}, {128, 96, 0, 128, 128}, {128, 96, 128, 0, 128},
- {128, 96, 408, 160, 128}, {128, 96, 408, 720, 128}, {128, 96, 104, 0, 128},
-};
-
-const TestVector test_group_0[] = {
- {"11754cd72aec309bf52f7687212e8957", "3c819d9a9bed087615030b65", "", "", "",
- "250327c674aaf477aef2675748cf6971"},
- {"ca47248ac0b6f8372a97ac43508308ed", "ffd2b598feabc9019262d2be", "", "", "",
- "60d20404af527d248d893ae495707d1a"},
- {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
-
-const TestVector test_group_1[] = {
- {"77be63708971c4e240d1cb79e8d77feb", "e0e00f19fed7ba0136a797f3", "",
- "7a43ec1d9c0a5a78a0b16533a6213cab", "",
- "209fcc8d3675ed938e9c7166709dd946"},
- {"7680c5d3ca6154758e510f4d25b98820", "f8f105f9c3df4965780321f8", "",
- "c94c410194c765e3dcc7964379758ed3", "",
- "94dca8edfcf90bb74b153c8d48a17930"},
- {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
-
-const TestVector test_group_2[] = {
- {"7fddb57453c241d03efbed3ac44e371c", "ee283a3fc75575e33efd4887",
- "d5de42b461646c255c87bd2962d3b9a2", "", "2ccda4a5415cb91e135c2a0f78c9b2fd",
- "b36d1df9b9d5e596f83e8b7f52971cb3"},
- {"ab72c77b97cb5fe9a382d9fe81ffdbed", "54cc7dc2c37ec006bcc6d1da",
- "007c5e5b3e59df24a7c355584fc1518d", "", "0e1bde206a07a9c2c1b65300f8c64997",
- "2b4401346697138c7a4891ee59867d0c"},
- {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
-
-const TestVector test_group_3[] = {
- {"fe47fcce5fc32665d2ae399e4eec72ba", "5adb9609dbaeb58cbd6e7275",
- "7c0e88c88899a779228465074797cd4c2e1498d259b54390b85e3eef1c02df60e743f1"
- "b840382c4bccaf3bafb4ca8429bea063",
- "88319d6e1d3ffa5f987199166c8a9b56c2aeba5a",
- "98f4826f05a265e6dd2be82db241c0fbbbf9ffb1c173aa83964b7cf539304373636525"
- "3ddbc5db8778371495da76d269e5db3e",
- "291ef1982e4defedaa2249f898556b47"},
- {"ec0c2ba17aa95cd6afffe949da9cc3a8", "296bce5b50b7d66096d627ef",
- "b85b3753535b825cbe5f632c0b843c741351f18aa484281aebec2f45bb9eea2d79d987"
- "b764b9611f6c0f8641843d5d58f3a242",
- "f8d00f05d22bf68599bcdeb131292ad6e2df5d14",
- "a7443d31c26bdf2a1c945e29ee4bd344a99cfaf3aa71f8b3f191f83c2adfc7a0716299"
- "5506fde6309ffc19e716eddf1a828c5a",
- "890147971946b627c40016da1ecf3e77"},
- {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
-
-const TestVector test_group_4[] = {
- {"2c1f21cf0f6fb3661943155c3e3d8492", "23cb5ff362e22426984d1907",
- "42f758836986954db44bf37c6ef5e4ac0adaf38f27252a1b82d02ea949c8a1a2dbc0d6"
- "8b5615ba7c1220ff6510e259f06655d8",
- "5d3624879d35e46849953e45a32a624d6a6c536ed9857c613b572b0333e701557a713e"
- "3f010ecdf9a6bd6c9e3e44b065208645aff4aabee611b391528514170084ccf587177f"
- "4488f33cfb5e979e42b6e1cfc0a60238982a7aec",
- "81824f0e0d523db30d3da369fdc0d60894c7a0a20646dd015073ad2732bd989b14a222"
- "b6ad57af43e1895df9dca2a5344a62cc",
- "57a3ee28136e94c74838997ae9823f3a"},
- {"d9f7d2411091f947b4d6f1e2d1f0fb2e", "e1934f5db57cc983e6b180e7",
- "73ed042327f70fe9c572a61545eda8b2a0c6e1d6c291ef19248e973aee6c312012f490"
- "c2c6f6166f4a59431e182663fcaea05a",
- "0a8a18a7150e940c3d87b38e73baee9a5c049ee21795663e264b694a949822b639092d"
- "0e67015e86363583fcf0ca645af9f43375f05fdb4ce84f411dcbca73c2220dea03a201"
- "15d2e51398344b16bee1ed7c499b353d6c597af8",
- "aaadbd5c92e9151ce3db7210b8714126b73e43436d242677afa50384f2149b831f1d57"
- "3c7891c2a91fbc48db29967ec9542b23",
- "21b51ca862cb637cdd03b99a0f93b134"},
- {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
-
-const TestVector test_group_5[] = {
- {"fe9bb47deb3a61e423c2231841cfd1fb", "4d328eb776f500a2f7fb47aa",
- "f1cc3818e421876bb6b8bbd6c9", "", "b88c5c1977b35b517b0aeae967",
- "43fd4727fe5cdb4b5b42818dea7ef8c9"},
- {"6703df3701a7f54911ca72e24dca046a", "12823ab601c350ea4bc2488c",
- "793cd125b0b84a043e3ac67717", "", "b2051c80014f42f08735a7b0cd",
- "38e6bcd29962e5f2c13626b85a877101"},
- {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
-
-const TestVector* const test_group_array[] = {
- test_group_0, test_group_1, test_group_2,
- test_group_3, test_group_4, test_group_5,
-};
-
-} // namespace
-
-namespace quic {
-namespace test {
-
-// EncryptWithNonce wraps the |Encrypt| method of |encrypter| to allow passing
-// in an nonce and also to allocate the buffer needed for the ciphertext.
-QuicData* EncryptWithNonce(Aes128Gcm12Encrypter* encrypter,
- absl::string_view nonce,
- absl::string_view associated_data,
- absl::string_view plaintext) {
- size_t ciphertext_size = encrypter->GetCiphertextSize(plaintext.length());
- std::unique_ptr<char[]> ciphertext(new char[ciphertext_size]);
-
- if (!encrypter->Encrypt(nonce, associated_data, plaintext,
- reinterpret_cast<unsigned char*>(ciphertext.get()))) {
- return nullptr;
- }
-
- return new QuicData(ciphertext.release(), ciphertext_size, true);
-}
-
-class Aes128Gcm12EncrypterTest : public QuicTest {};
-
-TEST_F(Aes128Gcm12EncrypterTest, Encrypt) {
- for (size_t i = 0; i < ABSL_ARRAYSIZE(test_group_array); i++) {
- SCOPED_TRACE(i);
- const TestVector* test_vectors = test_group_array[i];
- const TestGroupInfo& test_info = test_group_info[i];
- for (size_t j = 0; test_vectors[j].key != nullptr; j++) {
- // Decode the test vector.
- std::string key = absl::HexStringToBytes(test_vectors[j].key);
- std::string iv = absl::HexStringToBytes(test_vectors[j].iv);
- std::string pt = absl::HexStringToBytes(test_vectors[j].pt);
- std::string aad = absl::HexStringToBytes(test_vectors[j].aad);
- std::string ct = absl::HexStringToBytes(test_vectors[j].ct);
- std::string tag = absl::HexStringToBytes(test_vectors[j].tag);
-
- // The test vector's lengths should look sane. Note that the lengths
- // in |test_info| are in bits.
- EXPECT_EQ(test_info.key_len, key.length() * 8);
- EXPECT_EQ(test_info.iv_len, iv.length() * 8);
- EXPECT_EQ(test_info.pt_len, pt.length() * 8);
- EXPECT_EQ(test_info.aad_len, aad.length() * 8);
- EXPECT_EQ(test_info.pt_len, ct.length() * 8);
- EXPECT_EQ(test_info.tag_len, tag.length() * 8);
-
- Aes128Gcm12Encrypter encrypter;
- ASSERT_TRUE(encrypter.SetKey(key));
- std::unique_ptr<QuicData> encrypted(
- EncryptWithNonce(&encrypter, iv,
- // This deliberately tests that the encrypter can
- // handle an AAD that is set to nullptr, as opposed
- // to a zero-length, non-nullptr pointer.
- aad.length() ? aad : absl::string_view(), pt));
- ASSERT_TRUE(encrypted.get());
-
- // The test vectors have 16 byte authenticators but this code only uses
- // the first 12.
- ASSERT_LE(static_cast<size_t>(Aes128Gcm12Encrypter::kAuthTagSize),
- tag.length());
- tag.resize(Aes128Gcm12Encrypter::kAuthTagSize);
-
- ASSERT_EQ(ct.length() + tag.length(), encrypted->length());
- quiche::test::CompareCharArraysWithHexError(
- "ciphertext", encrypted->data(), ct.length(), ct.data(), ct.length());
- quiche::test::CompareCharArraysWithHexError(
- "authentication tag", encrypted->data() + ct.length(), tag.length(),
- tag.data(), tag.length());
- }
- }
-}
-
-TEST_F(Aes128Gcm12EncrypterTest, GetMaxPlaintextSize) {
- Aes128Gcm12Encrypter encrypter;
- EXPECT_EQ(1000u, encrypter.GetMaxPlaintextSize(1012));
- EXPECT_EQ(100u, encrypter.GetMaxPlaintextSize(112));
- EXPECT_EQ(10u, encrypter.GetMaxPlaintextSize(22));
- EXPECT_EQ(0u, encrypter.GetMaxPlaintextSize(11));
-}
-
-TEST_F(Aes128Gcm12EncrypterTest, GetCiphertextSize) {
- Aes128Gcm12Encrypter encrypter;
- EXPECT_EQ(1012u, encrypter.GetCiphertextSize(1000));
- EXPECT_EQ(112u, encrypter.GetCiphertextSize(100));
- EXPECT_EQ(22u, encrypter.GetCiphertextSize(10));
-}
-
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/aes_128_gcm_decrypter.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/aes_128_gcm_decrypter.cc
deleted file mode 100644
index d1def92811d..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/aes_128_gcm_decrypter.cc
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright (c) 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/crypto/aes_128_gcm_decrypter.h"
-
-#include "third_party/boringssl/src/include/openssl/aead.h"
-#include "third_party/boringssl/src/include/openssl/tls1.h"
-#include "quic/platform/api/quic_flag_utils.h"
-#include "quic/platform/api/quic_flags.h"
-
-namespace quic {
-
-namespace {
-
-const size_t kKeySize = 16;
-const size_t kNonceSize = 12;
-
-} // namespace
-
-Aes128GcmDecrypter::Aes128GcmDecrypter()
- : AesBaseDecrypter(EVP_aead_aes_128_gcm,
- kKeySize,
- kAuthTagSize,
- kNonceSize,
- /* use_ietf_nonce_construction */ true) {
- static_assert(kKeySize <= kMaxKeySize, "key size too big");
- static_assert(kNonceSize <= kMaxNonceSize, "nonce size too big");
-}
-
-Aes128GcmDecrypter::~Aes128GcmDecrypter() {}
-
-uint32_t Aes128GcmDecrypter::cipher_id() const {
- return TLS1_CK_AES_128_GCM_SHA256;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/aes_128_gcm_decrypter.h b/chromium/net/third_party/quiche/src/quic/core/crypto/aes_128_gcm_decrypter.h
deleted file mode 100644
index b9b3c68d8a7..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/aes_128_gcm_decrypter.h
+++ /dev/null
@@ -1,36 +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_CORE_CRYPTO_AES_128_GCM_DECRYPTER_H_
-#define QUICHE_QUIC_CORE_CRYPTO_AES_128_GCM_DECRYPTER_H_
-
-#include <cstdint>
-
-#include "quic/core/crypto/aes_base_decrypter.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// An Aes128GcmDecrypter is a QuicDecrypter that implements the
-// AEAD_AES_128_GCM algorithm specified in RFC 5116 for use in IETF QUIC.
-//
-// It uses an authentication tag of 16 bytes (128 bits). It uses a 12 byte IV
-// that is XOR'd with the packet number to compute the nonce.
-class QUIC_EXPORT_PRIVATE Aes128GcmDecrypter : public AesBaseDecrypter {
- public:
- enum {
- kAuthTagSize = 16,
- };
-
- Aes128GcmDecrypter();
- Aes128GcmDecrypter(const Aes128GcmDecrypter&) = delete;
- Aes128GcmDecrypter& operator=(const Aes128GcmDecrypter&) = delete;
- ~Aes128GcmDecrypter() override;
-
- uint32_t cipher_id() const override;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_CRYPTO_AES_128_GCM_DECRYPTER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/aes_128_gcm_decrypter_test.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/aes_128_gcm_decrypter_test.cc
deleted file mode 100644
index 25abd716576..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/aes_128_gcm_decrypter_test.cc
+++ /dev/null
@@ -1,291 +0,0 @@
-// Copyright (c) 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/crypto/aes_128_gcm_decrypter.h"
-
-#include <memory>
-#include <string>
-
-#include "absl/base/macros.h"
-#include "absl/strings/escaping.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/quic_test_utils.h"
-#include "common/test_tools/quiche_test_utils.h"
-
-namespace {
-
-// The AES GCM test vectors come from the file gcmDecrypt128.rsp
-// downloaded from http://csrc.nist.gov/groups/STM/cavp/index.html on
-// 2013-02-01. The test vectors in that file look like this:
-//
-// [Keylen = 128]
-// [IVlen = 96]
-// [PTlen = 0]
-// [AADlen = 0]
-// [Taglen = 128]
-//
-// Count = 0
-// Key = cf063a34d4a9a76c2c86787d3f96db71
-// IV = 113b9785971864c83b01c787
-// CT =
-// AAD =
-// Tag = 72ac8493e3a5228b5d130a69d2510e42
-// PT =
-//
-// Count = 1
-// Key = a49a5e26a2f8cb63d05546c2a62f5343
-// IV = 907763b19b9b4ab6bd4f0281
-// CT =
-// AAD =
-// Tag = a2be08210d8c470a8df6e8fbd79ec5cf
-// FAIL
-//
-// ...
-//
-// The gcmDecrypt128.rsp file is huge (2.6 MB), so I selected just a
-// few test vectors for this unit test.
-
-// Describes a group of test vectors that all have a given key length, IV
-// length, plaintext length, AAD length, and tag length.
-struct TestGroupInfo {
- size_t key_len;
- size_t iv_len;
- size_t pt_len;
- size_t aad_len;
- size_t tag_len;
-};
-
-// Each test vector consists of six strings of lowercase hexadecimal digits.
-// The strings may be empty (zero length). A test vector with a nullptr |key|
-// marks the end of an array of test vectors.
-struct TestVector {
- // Input:
- const char* key;
- const char* iv;
- const char* ct;
- const char* aad;
- const char* tag;
-
- // Expected output:
- const char* pt; // An empty string "" means decryption succeeded and
- // the plaintext is zero-length. nullptr means decryption
- // failed.
-};
-
-const TestGroupInfo test_group_info[] = {
- {128, 96, 0, 0, 128}, {128, 96, 0, 128, 128}, {128, 96, 128, 0, 128},
- {128, 96, 408, 160, 128}, {128, 96, 408, 720, 128}, {128, 96, 104, 0, 128},
-};
-
-const TestVector test_group_0[] = {
- {"cf063a34d4a9a76c2c86787d3f96db71", "113b9785971864c83b01c787", "", "",
- "72ac8493e3a5228b5d130a69d2510e42", ""},
- {
- "a49a5e26a2f8cb63d05546c2a62f5343", "907763b19b9b4ab6bd4f0281", "", "",
- "a2be08210d8c470a8df6e8fbd79ec5cf",
- nullptr // FAIL
- },
- {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
-
-const TestVector test_group_1[] = {
- {
- "d1f6af919cde85661208bdce0c27cb22", "898c6929b435017bf031c3c5", "",
- "7c5faa40e636bbc91107e68010c92b9f", "ae45f11777540a2caeb128be8092468a",
- nullptr // FAIL
- },
- {"2370e320d4344208e0ff5683f243b213", "04dbb82f044d30831c441228", "",
- "d43a8e5089eea0d026c03a85178b27da", "2a049c049d25aa95969b451d93c31c6e",
- ""},
- {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
-
-const TestVector test_group_2[] = {
- {"e98b72a9881a84ca6b76e0f43e68647a", "8b23299fde174053f3d652ba",
- "5a3c1cf1985dbb8bed818036fdd5ab42", "", "23c7ab0f952b7091cd324835043b5eb5",
- "28286a321293253c3e0aa2704a278032"},
- {"33240636cd3236165f1a553b773e728e", "17c4d61493ecdc8f31700b12",
- "47bb7e23f7bdfe05a8091ac90e4f8b2e", "", "b723c70e931d9785f40fd4ab1d612dc9",
- "95695a5b12f2870b9cc5fdc8f218a97d"},
- {
- "5164df856f1e9cac04a79b808dc5be39", "e76925d5355e0584ce871b2b",
- "0216c899c88d6e32c958c7e553daa5bc", "",
- "a145319896329c96df291f64efbe0e3a",
- nullptr // FAIL
- },
- {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
-
-const TestVector test_group_3[] = {
- {"af57f42c60c0fc5a09adb81ab86ca1c3", "a2dc01871f37025dc0fc9a79",
- "b9a535864f48ea7b6b1367914978f9bfa087d854bb0e269bed8d279d2eea1210e48947"
- "338b22f9bad09093276a331e9c79c7f4",
- "41dc38988945fcb44faf2ef72d0061289ef8efd8",
- "4f71e72bde0018f555c5adcce062e005",
- "3803a0727eeb0ade441e0ec107161ded2d425ec0d102f21f51bf2cf9947c7ec4aa7279"
- "5b2f69b041596e8817d0a3c16f8fadeb"},
- {"ebc753e5422b377d3cb64b58ffa41b61", "2e1821efaced9acf1f241c9b",
- "069567190554e9ab2b50a4e1fbf9c147340a5025fdbd201929834eaf6532325899ccb9"
- "f401823e04b05817243d2142a3589878",
- "b9673412fd4f88ba0e920f46dd6438ff791d8eef",
- "534d9234d2351cf30e565de47baece0b",
- "39077edb35e9c5a4b1e4c2a6b9bb1fce77f00f5023af40333d6d699014c2bcf4209c18"
- "353a18017f5b36bfc00b1f6dcb7ed485"},
- {
- "52bdbbf9cf477f187ec010589cb39d58", "d3be36d3393134951d324b31",
- "700188da144fa692cf46e4a8499510a53d90903c967f7f13e8a1bd8151a74adc4fe63e"
- "32b992760b3a5f99e9a47838867000a9",
- "93c4fc6a4135f54d640b0c976bf755a06a292c33",
- "8ca4e38aa3dfa6b1d0297021ccf3ea5f",
- nullptr // FAIL
- },
- {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
-
-const TestVector test_group_4[] = {
- {"da2bb7d581493d692380c77105590201", "44aa3e7856ca279d2eb020c6",
- "9290d430c9e89c37f0446dbd620c9a6b34b1274aeb6f911f75867efcf95b6feda69f1a"
- "f4ee16c761b3c9aeac3da03aa9889c88",
- "4cd171b23bddb3a53cdf959d5c1710b481eb3785a90eb20a2345ee00d0bb7868c367ab"
- "12e6f4dd1dee72af4eee1d197777d1d6499cc541f34edbf45cda6ef90b3c024f9272d7"
- "2ec1909fb8fba7db88a4d6f7d3d925980f9f9f72",
- "9e3ac938d3eb0cadd6f5c9e35d22ba38",
- "9bbf4c1a2742f6ac80cb4e8a052e4a8f4f07c43602361355b717381edf9fabd4cb7e3a"
- "d65dbd1378b196ac270588dd0621f642"},
- {"d74e4958717a9d5c0e235b76a926cae8", "0b7471141e0c70b1995fd7b1",
- "e701c57d2330bf066f9ff8cf3ca4343cafe4894651cd199bdaaa681ba486b4a65c5a22"
- "b0f1420be29ea547d42c713bc6af66aa",
- "4a42b7aae8c245c6f1598a395316e4b8484dbd6e64648d5e302021b1d3fa0a38f46e22"
- "bd9c8080b863dc0016482538a8562a4bd0ba84edbe2697c76fd039527ac179ec5506cf"
- "34a6039312774cedebf4961f3978b14a26509f96",
- "e192c23cb036f0b31592989119eed55d",
- "840d9fb95e32559fb3602e48590280a172ca36d9b49ab69510f5bd552bfab7a306f85f"
- "f0a34bc305b88b804c60b90add594a17"},
- {
- "1986310c725ac94ecfe6422e75fc3ee7", "93ec4214fa8e6dc4e3afc775",
- "b178ec72f85a311ac4168f42a4b2c23113fbea4b85f4b9dabb74e143eb1b8b0a361e02"
- "43edfd365b90d5b325950df0ada058f9",
- "e80b88e62c49c958b5e0b8b54f532d9ff6aa84c8a40132e93e55b59fc24e8decf28463"
- "139f155d1e8ce4ee76aaeefcd245baa0fc519f83a5fb9ad9aa40c4b21126013f576c42"
- "72c2cb136c8fd091cc4539877a5d1e72d607f960",
- "8b347853f11d75e81e8a95010be81f17",
- nullptr // FAIL
- },
- {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
-
-const TestVector test_group_5[] = {
- {"387218b246c1a8257748b56980e50c94", "dd7e014198672be39f95b69d",
- "cdba9e73eaf3d38eceb2b04a8d", "", "ecf90f4a47c9c626d6fb2c765d201556",
- "48f5b426baca03064554cc2b30"},
- {"294de463721e359863887c820524b3d4", "3338b35c9d57a5d28190e8c9",
- "2f46634e74b8e4c89812ac83b9", "", "dabd506764e68b82a7e720aa18da0abe",
- "46a2e55c8e264df211bd112685"},
- {"28ead7fd2179e0d12aa6d5d88c58c2dc", "5055347f18b4d5add0ae5c41",
- "142d8210c3fb84774cdbd0447a", "", "5fd321d9cdb01952dc85f034736c2a7d",
- "3b95b981086ee73cc4d0cc1422"},
- {
- "7d7b6c988137b8d470c57bf674a09c87", "9edf2aa970d016ac962e1fd8",
- "a85b66c3cb5eab91d5bdc8bc0e", "", "dc054efc01f3afd21d9c2484819f569a",
- nullptr // FAIL
- },
- {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
-
-const TestVector* const test_group_array[] = {
- test_group_0, test_group_1, test_group_2,
- test_group_3, test_group_4, test_group_5,
-};
-
-} // namespace
-
-namespace quic {
-namespace test {
-
-// DecryptWithNonce wraps the |Decrypt| method of |decrypter| to allow passing
-// in an nonce and also to allocate the buffer needed for the plaintext.
-QuicData* DecryptWithNonce(Aes128GcmDecrypter* decrypter,
- absl::string_view nonce,
- absl::string_view associated_data,
- absl::string_view ciphertext) {
- decrypter->SetIV(nonce);
- std::unique_ptr<char[]> output(new char[ciphertext.length()]);
- size_t output_length = 0;
- const bool success =
- decrypter->DecryptPacket(0, associated_data, ciphertext, output.get(),
- &output_length, ciphertext.length());
- if (!success) {
- return nullptr;
- }
- return new QuicData(output.release(), output_length, true);
-}
-
-class Aes128GcmDecrypterTest : public QuicTest {};
-
-TEST_F(Aes128GcmDecrypterTest, Decrypt) {
- for (size_t i = 0; i < ABSL_ARRAYSIZE(test_group_array); i++) {
- SCOPED_TRACE(i);
- const TestVector* test_vectors = test_group_array[i];
- const TestGroupInfo& test_info = test_group_info[i];
- for (size_t j = 0; test_vectors[j].key != nullptr; j++) {
- // If not present then decryption is expected to fail.
- bool has_pt = test_vectors[j].pt;
-
- // Decode the test vector.
- std::string key = absl::HexStringToBytes(test_vectors[j].key);
- std::string iv = absl::HexStringToBytes(test_vectors[j].iv);
- std::string ct = absl::HexStringToBytes(test_vectors[j].ct);
- std::string aad = absl::HexStringToBytes(test_vectors[j].aad);
- std::string tag = absl::HexStringToBytes(test_vectors[j].tag);
- std::string pt;
- if (has_pt) {
- pt = absl::HexStringToBytes(test_vectors[j].pt);
- }
-
- // The test vector's lengths should look sane. Note that the lengths
- // in |test_info| are in bits.
- EXPECT_EQ(test_info.key_len, key.length() * 8);
- EXPECT_EQ(test_info.iv_len, iv.length() * 8);
- EXPECT_EQ(test_info.pt_len, ct.length() * 8);
- EXPECT_EQ(test_info.aad_len, aad.length() * 8);
- EXPECT_EQ(test_info.tag_len, tag.length() * 8);
- if (has_pt) {
- EXPECT_EQ(test_info.pt_len, pt.length() * 8);
- }
- std::string ciphertext = ct + tag;
-
- Aes128GcmDecrypter decrypter;
- ASSERT_TRUE(decrypter.SetKey(key));
-
- std::unique_ptr<QuicData> decrypted(DecryptWithNonce(
- &decrypter, iv,
- // This deliberately tests that the decrypter can
- // handle an AAD that is set to nullptr, as opposed
- // to a zero-length, non-nullptr pointer.
- aad.length() ? aad : absl::string_view(), ciphertext));
- if (!decrypted) {
- EXPECT_FALSE(has_pt);
- continue;
- }
- EXPECT_TRUE(has_pt);
-
- ASSERT_EQ(pt.length(), decrypted->length());
- quiche::test::CompareCharArraysWithHexError(
- "plaintext", decrypted->data(), pt.length(), pt.data(), pt.length());
- }
- }
-}
-
-TEST_F(Aes128GcmDecrypterTest, GenerateHeaderProtectionMask) {
- Aes128GcmDecrypter decrypter;
- std::string key = absl::HexStringToBytes("d9132370cb18476ab833649cf080d970");
- std::string sample =
- absl::HexStringToBytes("d1d7998068517adb769b48b924a32c47");
- QuicDataReader sample_reader(sample.data(), sample.size());
- ASSERT_TRUE(decrypter.SetHeaderProtectionKey(key));
- std::string mask = decrypter.GenerateHeaderProtectionMask(&sample_reader);
- std::string expected_mask =
- absl::HexStringToBytes("b132c37d6164da4ea4dc9b763aceec27");
- quiche::test::CompareCharArraysWithHexError(
- "header protection mask", mask.data(), mask.size(), expected_mask.data(),
- expected_mask.size());
-}
-
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/aes_128_gcm_encrypter.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/aes_128_gcm_encrypter.cc
deleted file mode 100644
index 1cf28178581..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/aes_128_gcm_encrypter.cc
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright (c) 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/crypto/aes_128_gcm_encrypter.h"
-
-#include "third_party/boringssl/src/include/openssl/evp.h"
-
-namespace quic {
-
-namespace {
-
-const size_t kKeySize = 16;
-const size_t kNonceSize = 12;
-
-} // namespace
-
-Aes128GcmEncrypter::Aes128GcmEncrypter()
- : AesBaseEncrypter(EVP_aead_aes_128_gcm,
- kKeySize,
- kAuthTagSize,
- kNonceSize,
- /* use_ietf_nonce_construction */ true) {
- static_assert(kKeySize <= kMaxKeySize, "key size too big");
- static_assert(kNonceSize <= kMaxNonceSize, "nonce size too big");
-}
-
-Aes128GcmEncrypter::~Aes128GcmEncrypter() {}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/aes_128_gcm_encrypter.h b/chromium/net/third_party/quiche/src/quic/core/crypto/aes_128_gcm_encrypter.h
deleted file mode 100644
index c385de3b1b8..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/aes_128_gcm_encrypter.h
+++ /dev/null
@@ -1,32 +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_CORE_CRYPTO_AES_128_GCM_ENCRYPTER_H_
-#define QUICHE_QUIC_CORE_CRYPTO_AES_128_GCM_ENCRYPTER_H_
-
-#include "quic/core/crypto/aes_base_encrypter.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// An Aes128GcmEncrypter is a QuicEncrypter that implements the
-// AEAD_AES_128_GCM algorithm specified in RFC 5116 for use in IETF QUIC.
-//
-// It uses an authentication tag of 16 bytes (128 bits). It uses a 12 byte IV
-// that is XOR'd with the packet number to compute the nonce.
-class QUIC_EXPORT_PRIVATE Aes128GcmEncrypter : public AesBaseEncrypter {
- public:
- enum {
- kAuthTagSize = 16,
- };
-
- Aes128GcmEncrypter();
- Aes128GcmEncrypter(const Aes128GcmEncrypter&) = delete;
- Aes128GcmEncrypter& operator=(const Aes128GcmEncrypter&) = delete;
- ~Aes128GcmEncrypter() override;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_CRYPTO_AES_128_GCM_ENCRYPTER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/aes_128_gcm_encrypter_test.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/aes_128_gcm_encrypter_test.cc
deleted file mode 100644
index 7e5fb25a937..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/aes_128_gcm_encrypter_test.cc
+++ /dev/null
@@ -1,273 +0,0 @@
-// Copyright (c) 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/crypto/aes_128_gcm_encrypter.h"
-
-#include <memory>
-#include <string>
-
-#include "absl/base/macros.h"
-#include "absl/strings/escaping.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/quic_test_utils.h"
-#include "common/test_tools/quiche_test_utils.h"
-
-namespace {
-
-// The AES GCM test vectors come from the file gcmEncryptExtIV128.rsp
-// downloaded from http://csrc.nist.gov/groups/STM/cavp/index.html on
-// 2013-02-01. The test vectors in that file look like this:
-//
-// [Keylen = 128]
-// [IVlen = 96]
-// [PTlen = 0]
-// [AADlen = 0]
-// [Taglen = 128]
-//
-// Count = 0
-// Key = 11754cd72aec309bf52f7687212e8957
-// IV = 3c819d9a9bed087615030b65
-// PT =
-// AAD =
-// CT =
-// Tag = 250327c674aaf477aef2675748cf6971
-//
-// Count = 1
-// Key = ca47248ac0b6f8372a97ac43508308ed
-// IV = ffd2b598feabc9019262d2be
-// PT =
-// AAD =
-// CT =
-// Tag = 60d20404af527d248d893ae495707d1a
-//
-// ...
-//
-// The gcmEncryptExtIV128.rsp file is huge (2.8 MB), so I selected just a
-// few test vectors for this unit test.
-
-// Describes a group of test vectors that all have a given key length, IV
-// length, plaintext length, AAD length, and tag length.
-struct TestGroupInfo {
- size_t key_len;
- size_t iv_len;
- size_t pt_len;
- size_t aad_len;
- size_t tag_len;
-};
-
-// Each test vector consists of six strings of lowercase hexadecimal digits.
-// The strings may be empty (zero length). A test vector with a nullptr |key|
-// marks the end of an array of test vectors.
-struct TestVector {
- const char* key;
- const char* iv;
- const char* pt;
- const char* aad;
- const char* ct;
- const char* tag;
-};
-
-const TestGroupInfo test_group_info[] = {
- {128, 96, 0, 0, 128}, {128, 96, 0, 128, 128}, {128, 96, 128, 0, 128},
- {128, 96, 408, 160, 128}, {128, 96, 408, 720, 128}, {128, 96, 104, 0, 128},
-};
-
-const TestVector test_group_0[] = {
- {"11754cd72aec309bf52f7687212e8957", "3c819d9a9bed087615030b65", "", "", "",
- "250327c674aaf477aef2675748cf6971"},
- {"ca47248ac0b6f8372a97ac43508308ed", "ffd2b598feabc9019262d2be", "", "", "",
- "60d20404af527d248d893ae495707d1a"},
- {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
-
-const TestVector test_group_1[] = {
- {"77be63708971c4e240d1cb79e8d77feb", "e0e00f19fed7ba0136a797f3", "",
- "7a43ec1d9c0a5a78a0b16533a6213cab", "",
- "209fcc8d3675ed938e9c7166709dd946"},
- {"7680c5d3ca6154758e510f4d25b98820", "f8f105f9c3df4965780321f8", "",
- "c94c410194c765e3dcc7964379758ed3", "",
- "94dca8edfcf90bb74b153c8d48a17930"},
- {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
-
-const TestVector test_group_2[] = {
- {"7fddb57453c241d03efbed3ac44e371c", "ee283a3fc75575e33efd4887",
- "d5de42b461646c255c87bd2962d3b9a2", "", "2ccda4a5415cb91e135c2a0f78c9b2fd",
- "b36d1df9b9d5e596f83e8b7f52971cb3"},
- {"ab72c77b97cb5fe9a382d9fe81ffdbed", "54cc7dc2c37ec006bcc6d1da",
- "007c5e5b3e59df24a7c355584fc1518d", "", "0e1bde206a07a9c2c1b65300f8c64997",
- "2b4401346697138c7a4891ee59867d0c"},
- {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
-
-const TestVector test_group_3[] = {
- {"fe47fcce5fc32665d2ae399e4eec72ba", "5adb9609dbaeb58cbd6e7275",
- "7c0e88c88899a779228465074797cd4c2e1498d259b54390b85e3eef1c02df60e743f1"
- "b840382c4bccaf3bafb4ca8429bea063",
- "88319d6e1d3ffa5f987199166c8a9b56c2aeba5a",
- "98f4826f05a265e6dd2be82db241c0fbbbf9ffb1c173aa83964b7cf539304373636525"
- "3ddbc5db8778371495da76d269e5db3e",
- "291ef1982e4defedaa2249f898556b47"},
- {"ec0c2ba17aa95cd6afffe949da9cc3a8", "296bce5b50b7d66096d627ef",
- "b85b3753535b825cbe5f632c0b843c741351f18aa484281aebec2f45bb9eea2d79d987"
- "b764b9611f6c0f8641843d5d58f3a242",
- "f8d00f05d22bf68599bcdeb131292ad6e2df5d14",
- "a7443d31c26bdf2a1c945e29ee4bd344a99cfaf3aa71f8b3f191f83c2adfc7a0716299"
- "5506fde6309ffc19e716eddf1a828c5a",
- "890147971946b627c40016da1ecf3e77"},
- {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
-
-const TestVector test_group_4[] = {
- {"2c1f21cf0f6fb3661943155c3e3d8492", "23cb5ff362e22426984d1907",
- "42f758836986954db44bf37c6ef5e4ac0adaf38f27252a1b82d02ea949c8a1a2dbc0d6"
- "8b5615ba7c1220ff6510e259f06655d8",
- "5d3624879d35e46849953e45a32a624d6a6c536ed9857c613b572b0333e701557a713e"
- "3f010ecdf9a6bd6c9e3e44b065208645aff4aabee611b391528514170084ccf587177f"
- "4488f33cfb5e979e42b6e1cfc0a60238982a7aec",
- "81824f0e0d523db30d3da369fdc0d60894c7a0a20646dd015073ad2732bd989b14a222"
- "b6ad57af43e1895df9dca2a5344a62cc",
- "57a3ee28136e94c74838997ae9823f3a"},
- {"d9f7d2411091f947b4d6f1e2d1f0fb2e", "e1934f5db57cc983e6b180e7",
- "73ed042327f70fe9c572a61545eda8b2a0c6e1d6c291ef19248e973aee6c312012f490"
- "c2c6f6166f4a59431e182663fcaea05a",
- "0a8a18a7150e940c3d87b38e73baee9a5c049ee21795663e264b694a949822b639092d"
- "0e67015e86363583fcf0ca645af9f43375f05fdb4ce84f411dcbca73c2220dea03a201"
- "15d2e51398344b16bee1ed7c499b353d6c597af8",
- "aaadbd5c92e9151ce3db7210b8714126b73e43436d242677afa50384f2149b831f1d57"
- "3c7891c2a91fbc48db29967ec9542b23",
- "21b51ca862cb637cdd03b99a0f93b134"},
- {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
-
-const TestVector test_group_5[] = {
- {"fe9bb47deb3a61e423c2231841cfd1fb", "4d328eb776f500a2f7fb47aa",
- "f1cc3818e421876bb6b8bbd6c9", "", "b88c5c1977b35b517b0aeae967",
- "43fd4727fe5cdb4b5b42818dea7ef8c9"},
- {"6703df3701a7f54911ca72e24dca046a", "12823ab601c350ea4bc2488c",
- "793cd125b0b84a043e3ac67717", "", "b2051c80014f42f08735a7b0cd",
- "38e6bcd29962e5f2c13626b85a877101"},
- {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
-
-const TestVector* const test_group_array[] = {
- test_group_0, test_group_1, test_group_2,
- test_group_3, test_group_4, test_group_5,
-};
-
-} // namespace
-
-namespace quic {
-namespace test {
-
-// EncryptWithNonce wraps the |Encrypt| method of |encrypter| to allow passing
-// in an nonce and also to allocate the buffer needed for the ciphertext.
-QuicData* EncryptWithNonce(Aes128GcmEncrypter* encrypter,
- absl::string_view nonce,
- absl::string_view associated_data,
- absl::string_view plaintext) {
- size_t ciphertext_size = encrypter->GetCiphertextSize(plaintext.length());
- std::unique_ptr<char[]> ciphertext(new char[ciphertext_size]);
-
- if (!encrypter->Encrypt(nonce, associated_data, plaintext,
- reinterpret_cast<unsigned char*>(ciphertext.get()))) {
- return nullptr;
- }
-
- return new QuicData(ciphertext.release(), ciphertext_size, true);
-}
-
-class Aes128GcmEncrypterTest : public QuicTest {};
-
-TEST_F(Aes128GcmEncrypterTest, Encrypt) {
- for (size_t i = 0; i < ABSL_ARRAYSIZE(test_group_array); i++) {
- SCOPED_TRACE(i);
- const TestVector* test_vectors = test_group_array[i];
- const TestGroupInfo& test_info = test_group_info[i];
- for (size_t j = 0; test_vectors[j].key != nullptr; j++) {
- // Decode the test vector.
- std::string key = absl::HexStringToBytes(test_vectors[j].key);
- std::string iv = absl::HexStringToBytes(test_vectors[j].iv);
- std::string pt = absl::HexStringToBytes(test_vectors[j].pt);
- std::string aad = absl::HexStringToBytes(test_vectors[j].aad);
- std::string ct = absl::HexStringToBytes(test_vectors[j].ct);
- std::string tag = absl::HexStringToBytes(test_vectors[j].tag);
-
- // The test vector's lengths should look sane. Note that the lengths
- // in |test_info| are in bits.
- EXPECT_EQ(test_info.key_len, key.length() * 8);
- EXPECT_EQ(test_info.iv_len, iv.length() * 8);
- EXPECT_EQ(test_info.pt_len, pt.length() * 8);
- EXPECT_EQ(test_info.aad_len, aad.length() * 8);
- EXPECT_EQ(test_info.pt_len, ct.length() * 8);
- EXPECT_EQ(test_info.tag_len, tag.length() * 8);
-
- Aes128GcmEncrypter encrypter;
- ASSERT_TRUE(encrypter.SetKey(key));
- std::unique_ptr<QuicData> encrypted(
- EncryptWithNonce(&encrypter, iv,
- // This deliberately tests that the encrypter can
- // handle an AAD that is set to nullptr, as opposed
- // to a zero-length, non-nullptr pointer.
- aad.length() ? aad : absl::string_view(), pt));
- ASSERT_TRUE(encrypted.get());
-
- ASSERT_EQ(ct.length() + tag.length(), encrypted->length());
- quiche::test::CompareCharArraysWithHexError(
- "ciphertext", encrypted->data(), ct.length(), ct.data(), ct.length());
- quiche::test::CompareCharArraysWithHexError(
- "authentication tag", encrypted->data() + ct.length(), tag.length(),
- tag.data(), tag.length());
- }
- }
-}
-
-TEST_F(Aes128GcmEncrypterTest, EncryptPacket) {
- std::string key = absl::HexStringToBytes("d95a145250826c25a77b6a84fd4d34fc");
- std::string iv = absl::HexStringToBytes("50c4431ebb18283448e276e2");
- uint64_t packet_num = 0x13278f44;
- std::string aad =
- absl::HexStringToBytes("875d49f64a70c9cbe713278f44ff000005");
- std::string pt = absl::HexStringToBytes("aa0003a250bd000000000001");
- std::string ct = absl::HexStringToBytes(
- "7dd4708b989ee7d38a013e3656e9b37beefd05808fe1ab41e3b4f2c0");
-
- std::vector<char> out(ct.size());
- size_t out_size;
-
- Aes128GcmEncrypter encrypter;
- ASSERT_TRUE(encrypter.SetKey(key));
- ASSERT_TRUE(encrypter.SetIV(iv));
- ASSERT_TRUE(encrypter.EncryptPacket(packet_num, aad, pt, out.data(),
- &out_size, out.size()));
- EXPECT_EQ(out_size, out.size());
- quiche::test::CompareCharArraysWithHexError("ciphertext", out.data(),
- out.size(), ct.data(), ct.size());
-}
-
-TEST_F(Aes128GcmEncrypterTest, GetMaxPlaintextSize) {
- Aes128GcmEncrypter encrypter;
- EXPECT_EQ(1000u, encrypter.GetMaxPlaintextSize(1016));
- EXPECT_EQ(100u, encrypter.GetMaxPlaintextSize(116));
- EXPECT_EQ(10u, encrypter.GetMaxPlaintextSize(26));
-}
-
-TEST_F(Aes128GcmEncrypterTest, GetCiphertextSize) {
- Aes128GcmEncrypter encrypter;
- EXPECT_EQ(1016u, encrypter.GetCiphertextSize(1000));
- EXPECT_EQ(116u, encrypter.GetCiphertextSize(100));
- EXPECT_EQ(26u, encrypter.GetCiphertextSize(10));
-}
-
-TEST_F(Aes128GcmEncrypterTest, GenerateHeaderProtectionMask) {
- Aes128GcmEncrypter encrypter;
- std::string key = absl::HexStringToBytes("d9132370cb18476ab833649cf080d970");
- std::string sample =
- absl::HexStringToBytes("d1d7998068517adb769b48b924a32c47");
- ASSERT_TRUE(encrypter.SetHeaderProtectionKey(key));
- std::string mask = encrypter.GenerateHeaderProtectionMask(sample);
- std::string expected_mask =
- absl::HexStringToBytes("b132c37d6164da4ea4dc9b763aceec27");
- quiche::test::CompareCharArraysWithHexError(
- "header protection mask", mask.data(), mask.size(), expected_mask.data(),
- expected_mask.size());
-}
-
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/aes_256_gcm_decrypter.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/aes_256_gcm_decrypter.cc
deleted file mode 100644
index 50980b731d2..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/aes_256_gcm_decrypter.cc
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright (c) 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/crypto/aes_256_gcm_decrypter.h"
-
-#include "third_party/boringssl/src/include/openssl/aead.h"
-#include "third_party/boringssl/src/include/openssl/tls1.h"
-#include "quic/platform/api/quic_flag_utils.h"
-#include "quic/platform/api/quic_flags.h"
-
-namespace quic {
-
-namespace {
-
-const size_t kKeySize = 32;
-const size_t kNonceSize = 12;
-
-} // namespace
-
-Aes256GcmDecrypter::Aes256GcmDecrypter()
- : AesBaseDecrypter(EVP_aead_aes_256_gcm,
- kKeySize,
- kAuthTagSize,
- kNonceSize,
- /* use_ietf_nonce_construction */ true) {
- static_assert(kKeySize <= kMaxKeySize, "key size too big");
- static_assert(kNonceSize <= kMaxNonceSize, "nonce size too big");
-}
-
-Aes256GcmDecrypter::~Aes256GcmDecrypter() {}
-
-uint32_t Aes256GcmDecrypter::cipher_id() const {
- return TLS1_CK_AES_256_GCM_SHA384;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/aes_256_gcm_decrypter.h b/chromium/net/third_party/quiche/src/quic/core/crypto/aes_256_gcm_decrypter.h
deleted file mode 100644
index 6cc451ba186..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/aes_256_gcm_decrypter.h
+++ /dev/null
@@ -1,36 +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_CORE_CRYPTO_AES_256_GCM_DECRYPTER_H_
-#define QUICHE_QUIC_CORE_CRYPTO_AES_256_GCM_DECRYPTER_H_
-
-#include <cstdint>
-
-#include "quic/core/crypto/aes_base_decrypter.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// An Aes256GcmDecrypter is a QuicDecrypter that implements the
-// AEAD_AES_256_GCM algorithm specified in RFC 5116 for use in IETF QUIC.
-//
-// It uses an authentication tag of 16 bytes (128 bits). It uses a 12 byte IV
-// that is XOR'd with the packet number to compute the nonce.
-class QUIC_EXPORT_PRIVATE Aes256GcmDecrypter : public AesBaseDecrypter {
- public:
- enum {
- kAuthTagSize = 16,
- };
-
- Aes256GcmDecrypter();
- Aes256GcmDecrypter(const Aes256GcmDecrypter&) = delete;
- Aes256GcmDecrypter& operator=(const Aes256GcmDecrypter&) = delete;
- ~Aes256GcmDecrypter() override;
-
- uint32_t cipher_id() const override;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_CRYPTO_AES_256_GCM_DECRYPTER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/aes_256_gcm_decrypter_test.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/aes_256_gcm_decrypter_test.cc
deleted file mode 100644
index c63a589a3d8..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/aes_256_gcm_decrypter_test.cc
+++ /dev/null
@@ -1,297 +0,0 @@
-// Copyright (c) 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/crypto/aes_256_gcm_decrypter.h"
-
-#include <memory>
-#include <string>
-
-#include "absl/base/macros.h"
-#include "absl/strings/escaping.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/quic_test_utils.h"
-#include "common/test_tools/quiche_test_utils.h"
-
-namespace {
-
-// The AES GCM test vectors come from the file gcmDecrypt256.rsp
-// downloaded from
-// https://csrc.nist.gov/Projects/Cryptographic-Algorithm-Validation-Program/CAVP-TESTING-BLOCK-CIPHER-MODES#GCMVS
-// on 2017-09-27. The test vectors in that file look like this:
-//
-// [Keylen = 256]
-// [IVlen = 96]
-// [PTlen = 0]
-// [AADlen = 0]
-// [Taglen = 128]
-//
-// Count = 0
-// Key = f5a2b27c74355872eb3ef6c5feafaa740e6ae990d9d48c3bd9bb8235e589f010
-// IV = 58d2240f580a31c1d24948e9
-// CT =
-// AAD =
-// Tag = 15e051a5e4a5f5da6cea92e2ebee5bac
-// PT =
-//
-// Count = 1
-// Key = e5a8123f2e2e007d4e379ba114a2fb66e6613f57c72d4e4f024964053028a831
-// IV = 51e43385bf533e168427e1ad
-// CT =
-// AAD =
-// Tag = 38fe845c66e66bdd884c2aecafd280e6
-// FAIL
-//
-// ...
-//
-// The gcmDecrypt256.rsp file is huge (3.0 MB), so a few test vectors were
-// selected for this unit test.
-
-// Describes a group of test vectors that all have a given key length, IV
-// length, plaintext length, AAD length, and tag length.
-struct TestGroupInfo {
- size_t key_len;
- size_t iv_len;
- size_t pt_len;
- size_t aad_len;
- size_t tag_len;
-};
-
-// Each test vector consists of six strings of lowercase hexadecimal digits.
-// The strings may be empty (zero length). A test vector with a nullptr |key|
-// marks the end of an array of test vectors.
-struct TestVector {
- // Input:
- const char* key;
- const char* iv;
- const char* ct;
- const char* aad;
- const char* tag;
-
- // Expected output:
- const char* pt; // An empty string "" means decryption succeeded and
- // the plaintext is zero-length. nullptr means decryption
- // failed.
-};
-
-const TestGroupInfo test_group_info[] = {
- {256, 96, 0, 0, 128}, {256, 96, 0, 128, 128}, {256, 96, 128, 0, 128},
- {256, 96, 408, 160, 128}, {256, 96, 408, 720, 128}, {256, 96, 104, 0, 128},
-};
-
-const TestVector test_group_0[] = {
- {"f5a2b27c74355872eb3ef6c5feafaa740e6ae990d9d48c3bd9bb8235e589f010",
- "58d2240f580a31c1d24948e9", "", "", "15e051a5e4a5f5da6cea92e2ebee5bac",
- ""},
- {
- "e5a8123f2e2e007d4e379ba114a2fb66e6613f57c72d4e4f024964053028a831",
- "51e43385bf533e168427e1ad", "", "", "38fe845c66e66bdd884c2aecafd280e6",
- nullptr // FAIL
- },
- {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
-
-const TestVector test_group_1[] = {
- {"6dfdafd6703c285c01f14fd10a6012862b2af950d4733abb403b2e745b26945d",
- "3749d0b3d5bacb71be06ade6", "", "c0d249871992e70302ae008193d1e89f",
- "4aa4cc69f84ee6ac16d9bfb4e05de500", ""},
- {
- "2c392a5eb1a9c705371beda3a901c7c61dca4d93b4291de1dd0dd15ec11ffc45",
- "0723fb84a08f4ea09841f32a", "", "140be561b6171eab942c486a94d33d43",
- "aa0e1c9b57975bfc91aa137231977d2c", nullptr // FAIL
- },
- {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
-
-const TestVector test_group_2[] = {
- {"4c8ebfe1444ec1b2d503c6986659af2c94fafe945f72c1e8486a5acfedb8a0f8",
- "473360e0ad24889959858995", "d2c78110ac7e8f107c0df0570bd7c90c", "",
- "c26a379b6d98ef2852ead8ce83a833a7", "7789b41cb3ee548814ca0b388c10b343"},
- {"3934f363fd9f771352c4c7a060682ed03c2864223a1573b3af997e2ababd60ab",
- "efe2656d878c586e41c539c4", "e0de64302ac2d04048d65a87d2ad09fe", "",
- "33cbd8d2fb8a3a03e30c1eb1b53c1d99", "697aff2d6b77e5ed6232770e400c1ead"},
- {
- "c997768e2d14e3d38259667a6649079de77beb4543589771e5068e6cd7cd0b14",
- "835090aed9552dbdd45277e2", "9f6607d68e22ccf21928db0986be126e", "",
- "f32617f67c574fd9f44ef76ff880ab9f", nullptr // FAIL
- },
- {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
-
-const TestVector test_group_3[] = {
- {
- "e9d381a9c413bee66175d5586a189836e5c20f5583535ab4d3f3e612dc21700e",
- "23e81571da1c7821c681c7ca",
- "a25f3f580306cd5065d22a6b7e9660110af7204bb77d370f7f34bee547feeff7b32a59"
- "6fce29c9040e68b1589aad48da881990",
- "6f39c9ae7b8e8a58a95f0dd8ea6a9087cbccdfd6",
- "5b6dcd70eefb0892fab1539298b92a4b",
- nullptr // FAIL
- },
- {"6450d4501b1e6cfbe172c4c8570363e96b496591b842661c28c2f6c908379cad",
- "7e4262035e0bf3d60e91668a",
- "5a99b336fd3cfd82f10fb08f7045012415f0d9a06bb92dcf59c6f0dbe62d433671aacb8a1"
- "c52ce7bbf6aea372bf51e2ba79406",
- "f1c522f026e4c5d43851da516a1b78768ab18171",
- "fe93b01636f7bb0458041f213e98de65",
- "17449e236ef5858f6d891412495ead4607bfae2a2d735182a2a0242f9d52fc5345ef912db"
- "e16f3bb4576fe3bcafe336dee6085"},
- {"90f2e71ccb1148979cb742efc8f921de95457d898c84ce28edeed701650d3a26",
- "aba58ad60047ba553f6e4c98",
- "3fc77a5fe9203d091c7916587c9763cf2e4d0d53ca20b078b851716f1dab4873fe342b7b3"
- "01402f015d00263bf3f77c58a99d6",
- "2abe465df6e5be47f05b92c9a93d76ae3611fac5",
- "9cb3d04637048bc0bddef803ffbb56cf",
- "1d21639640e11638a2769e3fab78778f84be3f4a8ce28dfd99cb2e75171e05ea8e94e30aa"
- "78b54bb402b39d613616a8ed951dc"},
- {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
-
-const TestVector test_group_4[] = {
- {
- "e36aca93414b13f5313e76a7244588ee116551d1f34c32859166f2eb0ac1a9b7",
- "e9e701b1ccef6bddd03391d8",
- "5b059ac6733b6de0e8cf5b88b7301c02c993426f71bb12abf692e9deeacfac1ff1644c"
- "87d4df130028f515f0feda636309a24d",
- "6a08fe6e55a08f283cec4c4b37676e770f402af6102f548ad473ec6236da764f7076ff"
- "d41bbd9611b439362d899682b7b0f839fc5a68d9df54afd1e2b3c4e7d072454ee27111"
- "d52193d28b9c4f925d2a8b451675af39191a2cba",
- "43c7c9c93cc265fc8e192000e0417b5b",
- nullptr // FAIL
- },
- {"5f72046245d3f4a0877e50a86554bfd57d1c5e073d1ed3b5451f6d0fc2a8507a",
- "ea6f5b391e44b751b26bce6f",
- "0e6e0b2114c40769c15958d965a14dcf50b680e0185a4409d77d894ca15b1e698dd83b353"
- "6b18c05d8cd0873d1edce8150ecb5",
- "9b3a68c941d42744673fb60fea49075eae77322e7e70e34502c115b6495ebfc796d629080"
- "7653c6b53cd84281bd0311656d0013f44619d2748177e99e8f8347c989a7b59f9d8dcf00f"
- "31db0684a4a83e037e8777bae55f799b0d",
- "fdaaff86ceb937502cd9012d03585800",
- "b0a881b751cc1eb0c912a4cf9bd971983707dbd2411725664503455c55db25cdb19bc669c"
- "2654a3a8011de6bf7eff3f9f07834"},
- {"ab639bae205547607506522bd3cdca7861369e2b42ef175ff135f6ba435d5a8e",
- "5fbb63eb44bd59fee458d8f6",
- "9a34c62bed0972285503a32812877187a54dedbd55d2317fed89282bf1af4ba0b6bb9f9e1"
- "6dd86da3b441deb7841262bc6bd63",
- "1ef2b1768b805587935ffaf754a11bd2a305076d6374f1f5098b1284444b78f55408a786d"
- "a37e1b7f1401c330d3585ef56f3e4d35eaaac92e1381d636477dc4f4beaf559735e902d6b"
- "e58723257d4ac1ed9bd213de387f35f3c4",
- "e0299e079bff46fd12e36d1c60e41434",
- "e5a3ce804a8516cdd12122c091256b789076576040dbf3c55e8be3c016025896b8a72532b"
- "fd51196cc82efca47aa0fd8e2e0dc"},
- {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
-
-const TestVector test_group_5[] = {
- {
- "8b37c4b8cf634704920059866ad96c49e9da502c63fca4a3a7a4dcec74cb0610",
- "cb59344d2b06c4ae57cd0ea4", "66ab935c93555e786b775637a3", "",
- "d8733acbb564d8afaa99d7ca2e2f92a9", nullptr // FAIL
- },
- {"a71dac1377a3bf5d7fb1b5e36bee70d2e01de2a84a1c1009ba7448f7f26131dc",
- "c5b60dda3f333b1146e9da7c", "43af49ec1ae3738a20755034d6", "",
- "6f80b6ef2d8830a55eb63680a8dff9e0", "5b87141335f2becac1a559e05f"},
- {"dc1f64681014be221b00793bbcf5a5bc675b968eb7a3a3d5aa5978ef4fa45ecc",
- "056ae9a1a69e38af603924fe", "33013a48d9ea0df2911d583271", "",
- "5b8f9cc22303e979cd1524187e9f70fe", "2a7e05612191c8bce2f529dca9"},
- {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
-
-const TestVector* const test_group_array[] = {
- test_group_0, test_group_1, test_group_2,
- test_group_3, test_group_4, test_group_5,
-};
-
-} // namespace
-
-namespace quic {
-namespace test {
-
-// DecryptWithNonce wraps the |Decrypt| method of |decrypter| to allow passing
-// in an nonce and also to allocate the buffer needed for the plaintext.
-QuicData* DecryptWithNonce(Aes256GcmDecrypter* decrypter,
- absl::string_view nonce,
- absl::string_view associated_data,
- absl::string_view ciphertext) {
- decrypter->SetIV(nonce);
- std::unique_ptr<char[]> output(new char[ciphertext.length()]);
- size_t output_length = 0;
- const bool success =
- decrypter->DecryptPacket(0, associated_data, ciphertext, output.get(),
- &output_length, ciphertext.length());
- if (!success) {
- return nullptr;
- }
- return new QuicData(output.release(), output_length, true);
-}
-
-class Aes256GcmDecrypterTest : public QuicTest {};
-
-TEST_F(Aes256GcmDecrypterTest, Decrypt) {
- for (size_t i = 0; i < ABSL_ARRAYSIZE(test_group_array); i++) {
- SCOPED_TRACE(i);
- const TestVector* test_vectors = test_group_array[i];
- const TestGroupInfo& test_info = test_group_info[i];
- for (size_t j = 0; test_vectors[j].key != nullptr; j++) {
- // If not present then decryption is expected to fail.
- bool has_pt = test_vectors[j].pt;
-
- // Decode the test vector.
- std::string key = absl::HexStringToBytes(test_vectors[j].key);
- std::string iv = absl::HexStringToBytes(test_vectors[j].iv);
- std::string ct = absl::HexStringToBytes(test_vectors[j].ct);
- std::string aad = absl::HexStringToBytes(test_vectors[j].aad);
- std::string tag = absl::HexStringToBytes(test_vectors[j].tag);
- std::string pt;
- if (has_pt) {
- pt = absl::HexStringToBytes(test_vectors[j].pt);
- }
-
- // The test vector's lengths should look sane. Note that the lengths
- // in |test_info| are in bits.
- EXPECT_EQ(test_info.key_len, key.length() * 8);
- EXPECT_EQ(test_info.iv_len, iv.length() * 8);
- EXPECT_EQ(test_info.pt_len, ct.length() * 8);
- EXPECT_EQ(test_info.aad_len, aad.length() * 8);
- EXPECT_EQ(test_info.tag_len, tag.length() * 8);
- if (has_pt) {
- EXPECT_EQ(test_info.pt_len, pt.length() * 8);
- }
- std::string ciphertext = ct + tag;
-
- Aes256GcmDecrypter decrypter;
- ASSERT_TRUE(decrypter.SetKey(key));
-
- std::unique_ptr<QuicData> decrypted(DecryptWithNonce(
- &decrypter, iv,
- // This deliberately tests that the decrypter can
- // handle an AAD that is set to nullptr, as opposed
- // to a zero-length, non-nullptr pointer.
- aad.length() ? aad : absl::string_view(), ciphertext));
- if (!decrypted) {
- EXPECT_FALSE(has_pt);
- continue;
- }
- EXPECT_TRUE(has_pt);
-
- ASSERT_EQ(pt.length(), decrypted->length());
- quiche::test::CompareCharArraysWithHexError(
- "plaintext", decrypted->data(), pt.length(), pt.data(), pt.length());
- }
- }
-}
-
-TEST_F(Aes256GcmDecrypterTest, GenerateHeaderProtectionMask) {
- Aes256GcmDecrypter decrypter;
- std::string key = absl::HexStringToBytes(
- "ed23ecbf54d426def5c52c3dcfc84434e62e57781d3125bb21ed91b7d3e07788");
- std::string sample =
- absl::HexStringToBytes("4d190c474be2b8babafb49ec4e38e810");
- QuicDataReader sample_reader(sample.data(), sample.size());
- ASSERT_TRUE(decrypter.SetHeaderProtectionKey(key));
- std::string mask = decrypter.GenerateHeaderProtectionMask(&sample_reader);
- std::string expected_mask =
- absl::HexStringToBytes("db9ed4e6ccd033af2eae01407199c56e");
- quiche::test::CompareCharArraysWithHexError(
- "header protection mask", mask.data(), mask.size(), expected_mask.data(),
- expected_mask.size());
-}
-
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/aes_256_gcm_encrypter.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/aes_256_gcm_encrypter.cc
deleted file mode 100644
index 06324967984..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/aes_256_gcm_encrypter.cc
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright (c) 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/crypto/aes_256_gcm_encrypter.h"
-
-#include "third_party/boringssl/src/include/openssl/evp.h"
-
-namespace quic {
-
-namespace {
-
-const size_t kKeySize = 32;
-const size_t kNonceSize = 12;
-
-} // namespace
-
-Aes256GcmEncrypter::Aes256GcmEncrypter()
- : AesBaseEncrypter(EVP_aead_aes_256_gcm,
- kKeySize,
- kAuthTagSize,
- kNonceSize,
- /* use_ietf_nonce_construction */ true) {
- static_assert(kKeySize <= kMaxKeySize, "key size too big");
- static_assert(kNonceSize <= kMaxNonceSize, "nonce size too big");
-}
-
-Aes256GcmEncrypter::~Aes256GcmEncrypter() {}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/aes_256_gcm_encrypter.h b/chromium/net/third_party/quiche/src/quic/core/crypto/aes_256_gcm_encrypter.h
deleted file mode 100644
index 7183fb764fa..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/aes_256_gcm_encrypter.h
+++ /dev/null
@@ -1,32 +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_CORE_CRYPTO_AES_256_GCM_ENCRYPTER_H_
-#define QUICHE_QUIC_CORE_CRYPTO_AES_256_GCM_ENCRYPTER_H_
-
-#include "quic/core/crypto/aes_base_encrypter.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// An Aes256GcmEncrypter is a QuicEncrypter that implements the
-// AEAD_AES_256_GCM algorithm specified in RFC 5116 for use in IETF QUIC.
-//
-// It uses an authentication tag of 16 bytes (128 bits). It uses a 12 byte IV
-// that is XOR'd with the packet number to compute the nonce.
-class QUIC_EXPORT_PRIVATE Aes256GcmEncrypter : public AesBaseEncrypter {
- public:
- enum {
- kAuthTagSize = 16,
- };
-
- Aes256GcmEncrypter();
- Aes256GcmEncrypter(const Aes256GcmEncrypter&) = delete;
- Aes256GcmEncrypter& operator=(const Aes256GcmEncrypter&) = delete;
- ~Aes256GcmEncrypter() override;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_CRYPTO_AES_256_GCM_ENCRYPTER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/aes_256_gcm_encrypter_test.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/aes_256_gcm_encrypter_test.cc
deleted file mode 100644
index a2f8066717c..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/aes_256_gcm_encrypter_test.cc
+++ /dev/null
@@ -1,259 +0,0 @@
-// Copyright (c) 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/crypto/aes_256_gcm_encrypter.h"
-
-#include <memory>
-#include <string>
-
-#include "absl/base/macros.h"
-#include "absl/strings/escaping.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/quic_test_utils.h"
-#include "common/test_tools/quiche_test_utils.h"
-
-namespace {
-
-// The AES GCM test vectors come from the file gcmEncryptExtIV256.rsp
-// downloaded from
-// https://csrc.nist.gov/Projects/Cryptographic-Algorithm-Validation-Program/CAVP-TESTING-BLOCK-CIPHER-MODES#GCMVS
-// on 2017-09-27. The test vectors in that file look like this:
-//
-// [Keylen = 256]
-// [IVlen = 96]
-// [PTlen = 0]
-// [AADlen = 0]
-// [Taglen = 128]
-//
-// Count = 0
-// Key = b52c505a37d78eda5dd34f20c22540ea1b58963cf8e5bf8ffa85f9f2492505b4
-// IV = 516c33929df5a3284ff463d7
-// PT =
-// AAD =
-// CT =
-// Tag = bdc1ac884d332457a1d2664f168c76f0
-//
-// Count = 1
-// Key = 5fe0861cdc2690ce69b3658c7f26f8458eec1c9243c5ba0845305d897e96ca0f
-// IV = 770ac1a5a3d476d5d96944a1
-// PT =
-// AAD =
-// CT =
-// Tag = 196d691e1047093ca4b3d2ef4baba216
-//
-// ...
-//
-// The gcmEncryptExtIV256.rsp file is huge (3.2 MB), so a few test vectors were
-// selected for this unit test.
-
-// Describes a group of test vectors that all have a given key length, IV
-// length, plaintext length, AAD length, and tag length.
-struct TestGroupInfo {
- size_t key_len;
- size_t iv_len;
- size_t pt_len;
- size_t aad_len;
- size_t tag_len;
-};
-
-// Each test vector consists of six strings of lowercase hexadecimal digits.
-// The strings may be empty (zero length). A test vector with a nullptr |key|
-// marks the end of an array of test vectors.
-struct TestVector {
- const char* key;
- const char* iv;
- const char* pt;
- const char* aad;
- const char* ct;
- const char* tag;
-};
-
-const TestGroupInfo test_group_info[] = {
- {256, 96, 0, 0, 128}, {256, 96, 0, 128, 128}, {256, 96, 128, 0, 128},
- {256, 96, 408, 160, 128}, {256, 96, 408, 720, 128}, {256, 96, 104, 0, 128},
-};
-
-const TestVector test_group_0[] = {
- {"b52c505a37d78eda5dd34f20c22540ea1b58963cf8e5bf8ffa85f9f2492505b4",
- "516c33929df5a3284ff463d7", "", "", "",
- "bdc1ac884d332457a1d2664f168c76f0"},
- {"5fe0861cdc2690ce69b3658c7f26f8458eec1c9243c5ba0845305d897e96ca0f",
- "770ac1a5a3d476d5d96944a1", "", "", "",
- "196d691e1047093ca4b3d2ef4baba216"},
- {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
-
-const TestVector test_group_1[] = {
- {"78dc4e0aaf52d935c3c01eea57428f00ca1fd475f5da86a49c8dd73d68c8e223",
- "d79cf22d504cc793c3fb6c8a", "", "b96baa8c1c75a671bfb2d08d06be5f36", "",
- "3e5d486aa2e30b22e040b85723a06e76"},
- {"4457ff33683cca6ca493878bdc00373893a9763412eef8cddb54f91318e0da88",
- "699d1f29d7b8c55300bb1fd2", "", "6749daeea367d0e9809e2dc2f309e6e3", "",
- "d60c74d2517fde4a74e0cd4709ed43a9"},
- {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
-
-const TestVector test_group_2[] = {
- {"31bdadd96698c204aa9ce1448ea94ae1fb4a9a0b3c9d773b51bb1822666b8f22",
- "0d18e06c7c725ac9e362e1ce", "2db5168e932556f8089a0622981d017d", "",
- "fa4362189661d163fcd6a56d8bf0405a", "d636ac1bbedd5cc3ee727dc2ab4a9489"},
- {"460fc864972261c2560e1eb88761ff1c992b982497bd2ac36c04071cbb8e5d99",
- "8a4a16b9e210eb68bcb6f58d", "99e4e926ffe927f691893fb79a96b067", "",
- "133fc15751621b5f325c7ff71ce08324", "ec4e87e0cf74a13618d0b68636ba9fa7"},
- {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
-
-const TestVector test_group_3[] = {
- {"24501ad384e473963d476edcfe08205237acfd49b5b8f33857f8114e863fec7f",
- "9ff18563b978ec281b3f2794",
- "27f348f9cdc0c5bd5e66b1ccb63ad920ff2219d14e8d631b3872265cf117ee86757accb15"
- "8bd9abb3868fdc0d0b074b5f01b2c",
- "adb5ec720ccf9898500028bf34afccbcaca126ef",
- "eb7cb754c824e8d96f7c6d9b76c7d26fb874ffbf1d65c6f64a698d839b0b06145dae82057"
- "ad55994cf59ad7f67c0fa5e85fab8",
- "bc95c532fecc594c36d1550286a7a3f0"},
- {"fb43f5ab4a1738a30c1e053d484a94254125d55dccee1ad67c368bc1a985d235",
- "9fbb5f8252db0bca21f1c230",
- "34b797bb82250e23c5e796db2c37e488b3b99d1b981cea5e5b0c61a0b39adb6bd6ef1f507"
- "22e2e4f81115cfcf53f842e2a6c08",
- "98f8ae1735c39f732e2cbee1156dabeb854ec7a2",
- "871cd53d95a8b806bd4821e6c4456204d27fd704ba3d07ce25872dc604ea5c5ea13322186"
- "b7489db4fa060c1fd4159692612c8",
- "07b48e4a32fac47e115d7ac7445d8330"},
- {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
-
-const TestVector test_group_4[] = {
- {"148579a3cbca86d5520d66c0ec71ca5f7e41ba78e56dc6eebd566fed547fe691",
- "b08a5ea1927499c6ecbfd4e0",
- "9d0b15fdf1bd595f91f8b3abc0f7dec927dfd4799935a1795d9ce00c9b879434420fe42c2"
- "75a7cd7b39d638fb81ca52b49dc41",
- "e4f963f015ffbb99ee3349bbaf7e8e8e6c2a71c230a48f9d59860a29091d2747e01a5ca57"
- "2347e247d25f56ba7ae8e05cde2be3c97931292c02370208ecd097ef692687fecf2f419d3"
- "200162a6480a57dad408a0dfeb492e2c5d",
- "2097e372950a5e9383c675e89eea1c314f999159f5611344b298cda45e62843716f215f82"
- "ee663919c64002a5c198d7878fd3f",
- "adbecdb0d5c2224d804d2886ff9a5760"},
- {"e49af19182faef0ebeeba9f2d3be044e77b1212358366e4ef59e008aebcd9788",
- "e7f37d79a6a487a5a703edbb",
- "461cd0caf7427a3d44408d825ed719237272ecd503b9094d1f62c97d63ed83a0b50bdc804"
- "ffdd7991da7a5b6dcf48d4bcd2cbc",
- "19a9a1cfc647346781bef51ed9070d05f99a0e0192a223c5cd2522dbdf97d9739dd39fb17"
- "8ade3339e68774b058aa03e9a20a9a205bc05f32381df4d63396ef691fefd5a71b49a2ad8"
- "2d5ea428778ca47ee1398792762413cff4",
- "32ca3588e3e56eb4c8301b009d8b84b8a900b2b88ca3c21944205e9dd7311757b51394ae9"
- "0d8bb3807b471677614f4198af909",
- "3e403d035c71d88f1be1a256c89ba6ad"},
- {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
-
-const TestVector test_group_5[] = {
- {"82c4f12eeec3b2d3d157b0f992d292b237478d2cecc1d5f161389b97f999057a",
- "7b40b20f5f397177990ef2d1", "982a296ee1cd7086afad976945", "",
- "ec8e05a0471d6b43a59ca5335f", "113ddeafc62373cac2f5951bb9165249"},
- {"db4340af2f835a6c6d7ea0ca9d83ca81ba02c29b7410f221cb6071114e393240",
- "40e438357dd80a85cac3349e", "8ddb3397bd42853193cb0f80c9", "",
- "b694118c85c41abf69e229cb0f", "c07f1b8aafbd152f697eb67f2a85fe45"},
- {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
-
-const TestVector* const test_group_array[] = {
- test_group_0, test_group_1, test_group_2,
- test_group_3, test_group_4, test_group_5,
-};
-
-} // namespace
-
-namespace quic {
-namespace test {
-
-// EncryptWithNonce wraps the |Encrypt| method of |encrypter| to allow passing
-// in an nonce and also to allocate the buffer needed for the ciphertext.
-QuicData* EncryptWithNonce(Aes256GcmEncrypter* encrypter,
- absl::string_view nonce,
- absl::string_view associated_data,
- absl::string_view plaintext) {
- size_t ciphertext_size = encrypter->GetCiphertextSize(plaintext.length());
- std::unique_ptr<char[]> ciphertext(new char[ciphertext_size]);
-
- if (!encrypter->Encrypt(nonce, associated_data, plaintext,
- reinterpret_cast<unsigned char*>(ciphertext.get()))) {
- return nullptr;
- }
-
- return new QuicData(ciphertext.release(), ciphertext_size, true);
-}
-
-class Aes256GcmEncrypterTest : public QuicTest {};
-
-TEST_F(Aes256GcmEncrypterTest, Encrypt) {
- for (size_t i = 0; i < ABSL_ARRAYSIZE(test_group_array); i++) {
- SCOPED_TRACE(i);
- const TestVector* test_vectors = test_group_array[i];
- const TestGroupInfo& test_info = test_group_info[i];
- for (size_t j = 0; test_vectors[j].key != nullptr; j++) {
- // Decode the test vector.
- std::string key = absl::HexStringToBytes(test_vectors[j].key);
- std::string iv = absl::HexStringToBytes(test_vectors[j].iv);
- std::string pt = absl::HexStringToBytes(test_vectors[j].pt);
- std::string aad = absl::HexStringToBytes(test_vectors[j].aad);
- std::string ct = absl::HexStringToBytes(test_vectors[j].ct);
- std::string tag = absl::HexStringToBytes(test_vectors[j].tag);
-
- // The test vector's lengths should look sane. Note that the lengths
- // in |test_info| are in bits.
- EXPECT_EQ(test_info.key_len, key.length() * 8);
- EXPECT_EQ(test_info.iv_len, iv.length() * 8);
- EXPECT_EQ(test_info.pt_len, pt.length() * 8);
- EXPECT_EQ(test_info.aad_len, aad.length() * 8);
- EXPECT_EQ(test_info.pt_len, ct.length() * 8);
- EXPECT_EQ(test_info.tag_len, tag.length() * 8);
-
- Aes256GcmEncrypter encrypter;
- ASSERT_TRUE(encrypter.SetKey(key));
- std::unique_ptr<QuicData> encrypted(
- EncryptWithNonce(&encrypter, iv,
- // This deliberately tests that the encrypter can
- // handle an AAD that is set to nullptr, as opposed
- // to a zero-length, non-nullptr pointer.
- aad.length() ? aad : absl::string_view(), pt));
- ASSERT_TRUE(encrypted.get());
-
- ASSERT_EQ(ct.length() + tag.length(), encrypted->length());
- quiche::test::CompareCharArraysWithHexError(
- "ciphertext", encrypted->data(), ct.length(), ct.data(), ct.length());
- quiche::test::CompareCharArraysWithHexError(
- "authentication tag", encrypted->data() + ct.length(), tag.length(),
- tag.data(), tag.length());
- }
- }
-}
-
-TEST_F(Aes256GcmEncrypterTest, GetMaxPlaintextSize) {
- Aes256GcmEncrypter encrypter;
- EXPECT_EQ(1000u, encrypter.GetMaxPlaintextSize(1016));
- EXPECT_EQ(100u, encrypter.GetMaxPlaintextSize(116));
- EXPECT_EQ(10u, encrypter.GetMaxPlaintextSize(26));
-}
-
-TEST_F(Aes256GcmEncrypterTest, GetCiphertextSize) {
- Aes256GcmEncrypter encrypter;
- EXPECT_EQ(1016u, encrypter.GetCiphertextSize(1000));
- EXPECT_EQ(116u, encrypter.GetCiphertextSize(100));
- EXPECT_EQ(26u, encrypter.GetCiphertextSize(10));
-}
-
-TEST_F(Aes256GcmEncrypterTest, GenerateHeaderProtectionMask) {
- Aes256GcmEncrypter encrypter;
- std::string key = absl::HexStringToBytes(
- "ed23ecbf54d426def5c52c3dcfc84434e62e57781d3125bb21ed91b7d3e07788");
- std::string sample =
- absl::HexStringToBytes("4d190c474be2b8babafb49ec4e38e810");
- ASSERT_TRUE(encrypter.SetHeaderProtectionKey(key));
- std::string mask = encrypter.GenerateHeaderProtectionMask(sample);
- std::string expected_mask =
- absl::HexStringToBytes("db9ed4e6ccd033af2eae01407199c56e");
- quiche::test::CompareCharArraysWithHexError(
- "header protection mask", mask.data(), mask.size(), expected_mask.data(),
- expected_mask.size());
-}
-
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/aes_base_decrypter.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/aes_base_decrypter.cc
deleted file mode 100644
index fd21c7342bf..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/aes_base_decrypter.cc
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright (c) 2013 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 "quic/core/crypto/aes_base_decrypter.h"
-
-#include "absl/strings/string_view.h"
-#include "third_party/boringssl/src/include/openssl/aes.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-
-namespace quic {
-
-bool AesBaseDecrypter::SetHeaderProtectionKey(absl::string_view key) {
- if (key.size() != GetKeySize()) {
- QUIC_BUG(quic_bug_10649_1) << "Invalid key size for header protection";
- return false;
- }
- if (AES_set_encrypt_key(reinterpret_cast<const uint8_t*>(key.data()),
- key.size() * 8, &pne_key_) != 0) {
- QUIC_BUG(quic_bug_10649_2) << "Unexpected failure of AES_set_encrypt_key";
- return false;
- }
- return true;
-}
-
-std::string AesBaseDecrypter::GenerateHeaderProtectionMask(
- QuicDataReader* sample_reader) {
- absl::string_view sample;
- if (!sample_reader->ReadStringPiece(&sample, AES_BLOCK_SIZE)) {
- return std::string();
- }
- std::string out(AES_BLOCK_SIZE, 0);
- AES_encrypt(reinterpret_cast<const uint8_t*>(sample.data()),
- reinterpret_cast<uint8_t*>(const_cast<char*>(out.data())),
- &pne_key_);
- return out;
-}
-
-QuicPacketCount AesBaseDecrypter::GetIntegrityLimit() const {
- // For AEAD_AES_128_GCM ... endpoints that do not attempt to remove
- // protection from packets larger than 2^11 bytes can attempt to remove
- // protection from at most 2^57 packets.
- // For AEAD_AES_256_GCM [the limit] is substantially larger than the limit for
- // AEAD_AES_128_GCM. However, this document recommends that the same limit be
- // applied to both functions as either limit is acceptably large.
- // https://quicwg.org/base-drafts/draft-ietf-quic-tls.html#name-integrity-limit
- static_assert(kMaxIncomingPacketSize <= 2048,
- "This key limit requires limits on decryption payload sizes");
- return 144115188075855872U;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/aes_base_decrypter.h b/chromium/net/third_party/quiche/src/quic/core/crypto/aes_base_decrypter.h
deleted file mode 100644
index a826f41b406..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/aes_base_decrypter.h
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright (c) 2013 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_CRYPTO_AES_BASE_DECRYPTER_H_
-#define QUICHE_QUIC_CORE_CRYPTO_AES_BASE_DECRYPTER_H_
-
-#include <cstddef>
-
-#include "absl/strings/string_view.h"
-#include "third_party/boringssl/src/include/openssl/aes.h"
-#include "quic/core/crypto/aead_base_decrypter.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-class QUIC_EXPORT_PRIVATE AesBaseDecrypter : public AeadBaseDecrypter {
- public:
- using AeadBaseDecrypter::AeadBaseDecrypter;
-
- bool SetHeaderProtectionKey(absl::string_view key) override;
- std::string GenerateHeaderProtectionMask(
- QuicDataReader* sample_reader) override;
- QuicPacketCount GetIntegrityLimit() const override;
-
- private:
- // The key used for packet number encryption.
- AES_KEY pne_key_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_CRYPTO_AES_BASE_DECRYPTER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/aes_base_encrypter.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/aes_base_encrypter.cc
deleted file mode 100644
index fb25a334e47..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/aes_base_encrypter.cc
+++ /dev/null
@@ -1,48 +0,0 @@
-// Copyright (c) 2013 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 "quic/core/crypto/aes_base_encrypter.h"
-
-#include "absl/strings/string_view.h"
-#include "third_party/boringssl/src/include/openssl/aes.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-
-namespace quic {
-
-bool AesBaseEncrypter::SetHeaderProtectionKey(absl::string_view key) {
- if (key.size() != GetKeySize()) {
- QUIC_BUG(quic_bug_10726_1)
- << "Invalid key size for header protection: " << key.size();
- return false;
- }
- if (AES_set_encrypt_key(reinterpret_cast<const uint8_t*>(key.data()),
- key.size() * 8, &pne_key_) != 0) {
- QUIC_BUG(quic_bug_10726_2) << "Unexpected failure of AES_set_encrypt_key";
- return false;
- }
- return true;
-}
-
-std::string AesBaseEncrypter::GenerateHeaderProtectionMask(
- absl::string_view sample) {
- if (sample.size() != AES_BLOCK_SIZE) {
- return std::string();
- }
- std::string out(AES_BLOCK_SIZE, 0);
- AES_encrypt(reinterpret_cast<const uint8_t*>(sample.data()),
- reinterpret_cast<uint8_t*>(const_cast<char*>(out.data())),
- &pne_key_);
- return out;
-}
-
-QuicPacketCount AesBaseEncrypter::GetConfidentialityLimit() const {
- // For AEAD_AES_128_GCM and AEAD_AES_256_GCM ... endpoints that do not send
- // packets larger than 2^11 bytes cannot protect more than 2^28 packets.
- // https://quicwg.org/base-drafts/draft-ietf-quic-tls.html#name-confidentiality-limit
- static_assert(kMaxOutgoingPacketSize <= 2048,
- "This key limit requires limits on encryption payload sizes");
- return 268435456U;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/aes_base_encrypter.h b/chromium/net/third_party/quiche/src/quic/core/crypto/aes_base_encrypter.h
deleted file mode 100644
index 8ea3787a911..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/aes_base_encrypter.h
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright (c) 2013 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_CRYPTO_AES_BASE_ENCRYPTER_H_
-#define QUICHE_QUIC_CORE_CRYPTO_AES_BASE_ENCRYPTER_H_
-
-#include <cstddef>
-
-#include "absl/strings/string_view.h"
-#include "third_party/boringssl/src/include/openssl/aes.h"
-#include "quic/core/crypto/aead_base_encrypter.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-class QUIC_EXPORT_PRIVATE AesBaseEncrypter : public AeadBaseEncrypter {
- public:
- using AeadBaseEncrypter::AeadBaseEncrypter;
-
- bool SetHeaderProtectionKey(absl::string_view key) override;
- std::string GenerateHeaderProtectionMask(absl::string_view sample) override;
- QuicPacketCount GetConfidentialityLimit() const override;
-
- private:
- // The key used for packet number encryption.
- AES_KEY pne_key_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_CRYPTO_AES_BASE_ENCRYPTER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/boring_utils.h b/chromium/net/third_party/quiche/src/quic/core/crypto/boring_utils.h
deleted file mode 100644
index d623fa25af5..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/boring_utils.h
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_CRYPTO_BORING_UTILS_H_
-#define QUICHE_QUIC_CORE_CRYPTO_BORING_UTILS_H_
-
-#include "absl/strings/string_view.h"
-#include "third_party/boringssl/src/include/openssl/bytestring.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-inline QUIC_EXPORT_PRIVATE absl::string_view CbsToStringPiece(CBS cbs) {
- return absl::string_view(reinterpret_cast<const char*>(CBS_data(&cbs)),
- CBS_len(&cbs));
-}
-
-inline QUIC_EXPORT_PRIVATE CBS StringPieceToCbs(absl::string_view piece) {
- CBS result;
- CBS_init(&result, reinterpret_cast<const uint8_t*>(piece.data()),
- piece.size());
- return result;
-}
-
-inline QUIC_EXPORT_PRIVATE bool AddStringToCbb(CBB* cbb,
- absl::string_view piece) {
- return 1 == CBB_add_bytes(cbb, reinterpret_cast<const uint8_t*>(piece.data()),
- piece.size());
-}
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_CRYPTO_BORING_UTILS_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/cert_compressor.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/cert_compressor.cc
deleted file mode 100644
index e032ef6fc2b..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/cert_compressor.cc
+++ /dev/null
@@ -1,660 +0,0 @@
-// Copyright (c) 2013 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 "quic/core/crypto/cert_compressor.h"
-
-#include <cstdint>
-#include <memory>
-#include <string>
-#include <utility>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_flag_utils.h"
-#include "quic/platform/api/quic_flags.h"
-#include "third_party/zlib/zlib.h"
-
-namespace quic {
-
-namespace {
-
-// kCommonCertSubstrings contains ~1500 bytes of common certificate substrings
-// in order to help zlib. This was generated via a fairly dumb algorithm from
-// the Alexa Top 5000 set - we could probably do better.
-static const unsigned char kCommonCertSubstrings[] = {
- 0x04, 0x02, 0x30, 0x00, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04,
- 0x16, 0x30, 0x14, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03,
- 0x01, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x02, 0x30,
- 0x5f, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42, 0x04, 0x01,
- 0x06, 0x06, 0x0b, 0x60, 0x86, 0x48, 0x01, 0x86, 0xfd, 0x6d, 0x01, 0x07,
- 0x17, 0x01, 0x30, 0x33, 0x20, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x64, 0x65,
- 0x64, 0x20, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e,
- 0x20, 0x53, 0x20, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x65, 0x64, 0x31, 0x34,
- 0x20, 0x53, 0x53, 0x4c, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31,
- 0x32, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x53, 0x65, 0x72,
- 0x76, 0x65, 0x72, 0x20, 0x43, 0x41, 0x30, 0x2d, 0x61, 0x69, 0x61, 0x2e,
- 0x76, 0x65, 0x72, 0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d,
- 0x2f, 0x45, 0x2d, 0x63, 0x72, 0x6c, 0x2e, 0x76, 0x65, 0x72, 0x69, 0x73,
- 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x45, 0x2e, 0x63, 0x65,
- 0x72, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
- 0x01, 0x05, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x4a, 0x2e, 0x63,
- 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73,
- 0x2f, 0x63, 0x70, 0x73, 0x20, 0x28, 0x63, 0x29, 0x30, 0x30, 0x09, 0x06,
- 0x03, 0x55, 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x1d, 0x30, 0x0d,
- 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05,
- 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x7b, 0x30, 0x1d, 0x06, 0x03, 0x55,
- 0x1d, 0x0e, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
- 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01,
- 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xd2,
- 0x6f, 0x64, 0x6f, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x43, 0x2e,
- 0x63, 0x72, 0x6c, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16,
- 0x04, 0x14, 0xb4, 0x2e, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x73, 0x69,
- 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x30, 0x0b, 0x06, 0x03,
- 0x55, 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x01, 0x30, 0x0d, 0x06, 0x09,
- 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30,
- 0x81, 0xca, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
- 0x02, 0x55, 0x53, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x08,
- 0x13, 0x07, 0x41, 0x72, 0x69, 0x7a, 0x6f, 0x6e, 0x61, 0x31, 0x13, 0x30,
- 0x11, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x0a, 0x53, 0x63, 0x6f, 0x74,
- 0x74, 0x73, 0x64, 0x61, 0x6c, 0x65, 0x31, 0x1a, 0x30, 0x18, 0x06, 0x03,
- 0x55, 0x04, 0x0a, 0x13, 0x11, 0x47, 0x6f, 0x44, 0x61, 0x64, 0x64, 0x79,
- 0x2e, 0x63, 0x6f, 0x6d, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x33,
- 0x30, 0x31, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x2a, 0x68, 0x74, 0x74,
- 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63,
- 0x61, 0x74, 0x65, 0x73, 0x2e, 0x67, 0x6f, 0x64, 0x61, 0x64, 0x64, 0x79,
- 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74,
- 0x6f, 0x72, 0x79, 0x31, 0x30, 0x30, 0x2e, 0x06, 0x03, 0x55, 0x04, 0x03,
- 0x13, 0x27, 0x47, 0x6f, 0x20, 0x44, 0x61, 0x64, 0x64, 0x79, 0x20, 0x53,
- 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66,
- 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68,
- 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55,
- 0x04, 0x05, 0x13, 0x08, 0x30, 0x37, 0x39, 0x36, 0x39, 0x32, 0x38, 0x37,
- 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x31, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d,
- 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x05, 0xa0, 0x30, 0x0c,
- 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x02, 0x30, 0x00,
- 0x30, 0x1d, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff,
- 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0x00, 0x30, 0x1d, 0x06, 0x03, 0x55,
- 0x1d, 0x25, 0x04, 0x16, 0x30, 0x14, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05,
- 0x05, 0x07, 0x03, 0x01, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
- 0x03, 0x02, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff,
- 0x04, 0x04, 0x03, 0x02, 0x05, 0xa0, 0x30, 0x33, 0x06, 0x03, 0x55, 0x1d,
- 0x1f, 0x04, 0x2c, 0x30, 0x2a, 0x30, 0x28, 0xa0, 0x26, 0xa0, 0x24, 0x86,
- 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e,
- 0x67, 0x6f, 0x64, 0x61, 0x64, 0x64, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x2f,
- 0x67, 0x64, 0x73, 0x31, 0x2d, 0x32, 0x30, 0x2a, 0x30, 0x28, 0x06, 0x08,
- 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x1c, 0x68, 0x74,
- 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x76, 0x65,
- 0x72, 0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63,
- 0x70, 0x73, 0x30, 0x34, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17,
- 0x0d, 0x31, 0x33, 0x30, 0x35, 0x30, 0x39, 0x06, 0x08, 0x2b, 0x06, 0x01,
- 0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x2d, 0x68, 0x74, 0x74, 0x70, 0x3a,
- 0x2f, 0x2f, 0x73, 0x30, 0x39, 0x30, 0x37, 0x06, 0x08, 0x2b, 0x06, 0x01,
- 0x05, 0x05, 0x07, 0x02, 0x30, 0x44, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04,
- 0x3d, 0x30, 0x3b, 0x30, 0x39, 0x06, 0x0b, 0x60, 0x86, 0x48, 0x01, 0x86,
- 0xf8, 0x45, 0x01, 0x07, 0x17, 0x06, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03,
- 0x55, 0x04, 0x06, 0x13, 0x02, 0x47, 0x42, 0x31, 0x1b, 0x53, 0x31, 0x17,
- 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0e, 0x56, 0x65, 0x72,
- 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31,
- 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x16, 0x56, 0x65,
- 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74,
- 0x20, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x31, 0x3b, 0x30, 0x39,
- 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x32, 0x54, 0x65, 0x72, 0x6d, 0x73,
- 0x20, 0x6f, 0x66, 0x20, 0x75, 0x73, 0x65, 0x20, 0x61, 0x74, 0x20, 0x68,
- 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x76,
- 0x65, 0x72, 0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f,
- 0x72, 0x70, 0x61, 0x20, 0x28, 0x63, 0x29, 0x30, 0x31, 0x10, 0x30, 0x0e,
- 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x07, 0x53, 0x31, 0x13, 0x30, 0x11,
- 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x0a, 0x47, 0x31, 0x13, 0x30, 0x11,
- 0x06, 0x0b, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x3c, 0x02, 0x01,
- 0x03, 0x13, 0x02, 0x55, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04,
- 0x03, 0x14, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
- 0x31, 0x1d, 0x30, 0x1b, 0x06, 0x03, 0x55, 0x04, 0x0f, 0x13, 0x14, 0x50,
- 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x20, 0x4f, 0x72, 0x67, 0x61, 0x6e,
- 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x31, 0x12, 0x31, 0x21, 0x30,
- 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x18, 0x44, 0x6f, 0x6d, 0x61,
- 0x69, 0x6e, 0x20, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x20, 0x56,
- 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x64, 0x31, 0x14, 0x31, 0x31,
- 0x30, 0x2f, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x28, 0x53, 0x65, 0x65,
- 0x20, 0x77, 0x77, 0x77, 0x2e, 0x72, 0x3a, 0x2f, 0x2f, 0x73, 0x65, 0x63,
- 0x75, 0x72, 0x65, 0x2e, 0x67, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x53,
- 0x69, 0x67, 0x6e, 0x31, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x43, 0x41,
- 0x2e, 0x63, 0x72, 0x6c, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e,
- 0x20, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x33, 0x20, 0x45, 0x63, 0x72,
- 0x6c, 0x2e, 0x67, 0x65, 0x6f, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63,
- 0x6f, 0x6d, 0x2f, 0x63, 0x72, 0x6c, 0x73, 0x2f, 0x73, 0x64, 0x31, 0x1a,
- 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x68, 0x74, 0x74, 0x70, 0x3a,
- 0x2f, 0x2f, 0x45, 0x56, 0x49, 0x6e, 0x74, 0x6c, 0x2d, 0x63, 0x63, 0x72,
- 0x74, 0x2e, 0x67, 0x77, 0x77, 0x77, 0x2e, 0x67, 0x69, 0x63, 0x65, 0x72,
- 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x31, 0x6f, 0x63, 0x73, 0x70, 0x2e,
- 0x76, 0x65, 0x72, 0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d,
- 0x30, 0x39, 0x72, 0x61, 0x70, 0x69, 0x64, 0x73, 0x73, 0x6c, 0x2e, 0x63,
- 0x6f, 0x73, 0x2e, 0x67, 0x6f, 0x64, 0x61, 0x64, 0x64, 0x79, 0x2e, 0x63,
- 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72,
- 0x79, 0x2f, 0x30, 0x81, 0x80, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05,
- 0x07, 0x01, 0x01, 0x04, 0x74, 0x30, 0x72, 0x30, 0x24, 0x06, 0x08, 0x2b,
- 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x18, 0x68, 0x74, 0x74,
- 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x67, 0x6f, 0x64,
- 0x61, 0x64, 0x64, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x30, 0x4a, 0x06,
- 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x3e, 0x68,
- 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66,
- 0x69, 0x63, 0x61, 0x74, 0x65, 0x73, 0x2e, 0x67, 0x6f, 0x64, 0x61, 0x64,
- 0x64, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73,
- 0x69, 0x74, 0x6f, 0x72, 0x79, 0x2f, 0x67, 0x64, 0x5f, 0x69, 0x6e, 0x74,
- 0x65, 0x72, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x2e, 0x63, 0x72,
- 0x74, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16,
- 0x80, 0x14, 0xfd, 0xac, 0x61, 0x32, 0x93, 0x6c, 0x45, 0xd6, 0xe2, 0xee,
- 0x85, 0x5f, 0x9a, 0xba, 0xe7, 0x76, 0x99, 0x68, 0xcc, 0xe7, 0x30, 0x27,
- 0x86, 0x29, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x86, 0x30,
- 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x73,
-};
-
-// CertEntry represents a certificate in compressed form. Each entry is one of
-// the three types enumerated in |Type|.
-struct CertEntry {
- public:
- enum Type {
- // Type 0 is reserved to mean "end of list" in the wire format.
-
- // COMPRESSED means that the certificate is included in the trailing zlib
- // data.
- COMPRESSED = 1,
- // CACHED means that the certificate is already known to the peer and will
- // be replaced by its 64-bit hash (in |hash|).
- CACHED = 2,
- // COMMON means that the certificate is in a common certificate set known
- // to the peer with hash |set_hash| and certificate index |index|.
- COMMON = 3,
- };
-
- Type type;
- uint64_t hash;
- uint64_t set_hash;
- uint32_t index;
-};
-
-// MatchCerts returns a vector of CertEntries describing how to most
-// efficiently represent |certs| to a peer who has the common sets identified
-// by |client_common_set_hashes| and who has cached the certificates with the
-// 64-bit, FNV-1a hashes in |client_cached_cert_hashes|.
-std::vector<CertEntry> MatchCerts(const std::vector<std::string>& certs,
- absl::string_view client_common_set_hashes,
- absl::string_view client_cached_cert_hashes,
- const CommonCertSets* common_sets) {
- std::vector<CertEntry> entries;
- entries.reserve(certs.size());
-
- const bool cached_valid =
- client_cached_cert_hashes.size() % sizeof(uint64_t) == 0 &&
- !client_cached_cert_hashes.empty();
-
- for (auto i = certs.begin(); i != certs.end(); ++i) {
- CertEntry entry;
-
- if (cached_valid) {
- bool cached = false;
-
- uint64_t hash = QuicUtils::FNV1a_64_Hash(*i);
- // This assumes that the machine is little-endian.
- for (size_t j = 0; j < client_cached_cert_hashes.size();
- j += sizeof(uint64_t)) {
- uint64_t cached_hash;
- memcpy(&cached_hash, client_cached_cert_hashes.data() + j,
- sizeof(uint64_t));
- if (hash != cached_hash) {
- continue;
- }
-
- entry.type = CertEntry::CACHED;
- entry.hash = hash;
- entries.push_back(entry);
- cached = true;
- break;
- }
-
- if (cached) {
- continue;
- }
- }
-
- if (GetQuicRestartFlag(quic_no_common_cert_set)) {
- QUIC_RESTART_FLAG_COUNT(quic_no_common_cert_set);
- } else if (common_sets &&
- common_sets->MatchCert(*i, client_common_set_hashes,
- &entry.set_hash, &entry.index)) {
- entry.type = CertEntry::COMMON;
- entries.push_back(entry);
- continue;
- }
-
- entry.type = CertEntry::COMPRESSED;
- entries.push_back(entry);
- }
-
- return entries;
-}
-
-// CertEntriesSize returns the size, in bytes, of the serialised form of
-// |entries|.
-size_t CertEntriesSize(const std::vector<CertEntry>& entries) {
- size_t entries_size = 0;
-
- for (auto i = entries.begin(); i != entries.end(); ++i) {
- entries_size++;
- switch (i->type) {
- case CertEntry::COMPRESSED:
- break;
- case CertEntry::CACHED:
- entries_size += sizeof(uint64_t);
- break;
- case CertEntry::COMMON:
- QUIC_BUG_IF(unexpected_common_cert_entry_1,
- GetQuicRestartFlag(quic_no_common_cert_set));
- entries_size += sizeof(uint64_t) + sizeof(uint32_t);
- break;
- }
- }
-
- entries_size++; // for end marker
-
- return entries_size;
-}
-
-// SerializeCertEntries serialises |entries| to |out|, which must have enough
-// space to contain them.
-void SerializeCertEntries(uint8_t* out, const std::vector<CertEntry>& entries) {
- for (auto i = entries.begin(); i != entries.end(); ++i) {
- *out++ = static_cast<uint8_t>(i->type);
- switch (i->type) {
- case CertEntry::COMPRESSED:
- break;
- case CertEntry::CACHED:
- memcpy(out, &i->hash, sizeof(i->hash));
- out += sizeof(uint64_t);
- break;
- case CertEntry::COMMON:
- QUIC_BUG_IF(unexpected_common_cert_entry_2,
- GetQuicRestartFlag(quic_no_common_cert_set));
- // Assumes a little-endian machine.
- memcpy(out, &i->set_hash, sizeof(i->set_hash));
- out += sizeof(i->set_hash);
- memcpy(out, &i->index, sizeof(uint32_t));
- out += sizeof(uint32_t);
- break;
- }
- }
-
- *out++ = 0; // end marker
-}
-
-// ZlibDictForEntries returns a string that contains the zlib pre-shared
-// dictionary to use in order to decompress a zlib block following |entries|.
-// |certs| is one-to-one with |entries| and contains the certificates for those
-// entries that are CACHED or COMMON.
-std::string ZlibDictForEntries(const std::vector<CertEntry>& entries,
- const std::vector<std::string>& certs) {
- std::string zlib_dict;
-
- // The dictionary starts with the common and cached certs in reverse order.
- size_t zlib_dict_size = 0;
- for (size_t i = certs.size() - 1; i < certs.size(); i--) {
- if (entries[i].type != CertEntry::COMPRESSED) {
- zlib_dict_size += certs[i].size();
- }
- }
-
- // At the end of the dictionary is a block of common certificate substrings.
- zlib_dict_size += sizeof(kCommonCertSubstrings);
-
- zlib_dict.reserve(zlib_dict_size);
-
- for (size_t i = certs.size() - 1; i < certs.size(); i--) {
- if (entries[i].type != CertEntry::COMPRESSED) {
- zlib_dict += certs[i];
- }
- }
-
- zlib_dict += std::string(reinterpret_cast<const char*>(kCommonCertSubstrings),
- sizeof(kCommonCertSubstrings));
-
- QUICHE_DCHECK_EQ(zlib_dict.size(), zlib_dict_size);
-
- return zlib_dict;
-}
-
-// HashCerts returns the FNV-1a hashes of |certs|.
-std::vector<uint64_t> HashCerts(const std::vector<std::string>& certs) {
- std::vector<uint64_t> ret;
- ret.reserve(certs.size());
-
- for (auto i = certs.begin(); i != certs.end(); ++i) {
- ret.push_back(QuicUtils::FNV1a_64_Hash(*i));
- }
-
- return ret;
-}
-
-// ParseEntries parses the serialised form of a vector of CertEntries from
-// |in_out| and writes them to |out_entries|. CACHED and COMMON entries are
-// resolved using |cached_certs| and |common_sets| and written to |out_certs|.
-// |in_out| is updated to contain the trailing data.
-bool ParseEntries(absl::string_view* in_out,
- const std::vector<std::string>& cached_certs,
- const CommonCertSets* common_sets,
- std::vector<CertEntry>* out_entries,
- std::vector<std::string>* out_certs) {
- absl::string_view in = *in_out;
- std::vector<uint64_t> cached_hashes;
-
- out_entries->clear();
- out_certs->clear();
-
- for (;;) {
- if (in.empty()) {
- return false;
- }
- CertEntry entry;
- const uint8_t type_byte = in[0];
- in.remove_prefix(1);
-
- if (type_byte == 0) {
- break;
- }
-
- entry.type = static_cast<CertEntry::Type>(type_byte);
-
- switch (entry.type) {
- case CertEntry::COMPRESSED:
- out_certs->push_back(std::string());
- break;
- case CertEntry::CACHED: {
- if (in.size() < sizeof(uint64_t)) {
- return false;
- }
- memcpy(&entry.hash, in.data(), sizeof(uint64_t));
- in.remove_prefix(sizeof(uint64_t));
-
- if (cached_hashes.size() != cached_certs.size()) {
- cached_hashes = HashCerts(cached_certs);
- }
- bool found = false;
- for (size_t i = 0; i < cached_hashes.size(); i++) {
- if (cached_hashes[i] == entry.hash) {
- out_certs->push_back(cached_certs[i]);
- found = true;
- break;
- }
- }
- if (!found) {
- return false;
- }
- break;
- }
- case CertEntry::COMMON: {
- if (GetQuicRestartFlag(quic_no_common_cert_set)) {
- // Client only. No flag count.
- return false;
- }
- if (!common_sets) {
- return false;
- }
- if (in.size() < sizeof(uint64_t) + sizeof(uint32_t)) {
- return false;
- }
- memcpy(&entry.set_hash, in.data(), sizeof(uint64_t));
- in.remove_prefix(sizeof(uint64_t));
- memcpy(&entry.index, in.data(), sizeof(uint32_t));
- in.remove_prefix(sizeof(uint32_t));
-
- absl::string_view cert =
- common_sets->GetCert(entry.set_hash, entry.index);
- if (cert.empty()) {
- return false;
- }
- out_certs->push_back(std::string(cert));
- break;
- }
- default:
- return false;
- }
- out_entries->push_back(entry);
- }
-
- *in_out = in;
- return true;
-}
-
-// ScopedZLib deals with the automatic destruction of a zlib context.
-class ScopedZLib {
- public:
- enum Type {
- INFLATE,
- DEFLATE,
- };
-
- explicit ScopedZLib(Type type) : z_(nullptr), type_(type) {}
-
- void reset(z_stream* z) {
- Clear();
- z_ = z;
- }
-
- ~ScopedZLib() { Clear(); }
-
- private:
- void Clear() {
- if (!z_) {
- return;
- }
-
- if (type_ == DEFLATE) {
- deflateEnd(z_);
- } else {
- inflateEnd(z_);
- }
- z_ = nullptr;
- }
-
- z_stream* z_;
- const Type type_;
-};
-
-} // anonymous namespace
-
-// static
-std::string CertCompressor::CompressChain(
- const std::vector<std::string>& certs,
- absl::string_view client_common_set_hashes,
- absl::string_view client_cached_cert_hashes,
- const CommonCertSets* common_sets) {
- const std::vector<CertEntry> entries = MatchCerts(
- certs, client_common_set_hashes, client_cached_cert_hashes, common_sets);
- QUICHE_DCHECK_EQ(entries.size(), certs.size());
-
- size_t uncompressed_size = 0;
- for (size_t i = 0; i < entries.size(); i++) {
- if (entries[i].type == CertEntry::COMPRESSED) {
- uncompressed_size += 4 /* uint32_t length */ + certs[i].size();
- }
- }
-
- size_t compressed_size = 0;
- z_stream z;
- ScopedZLib scoped_z(ScopedZLib::DEFLATE);
-
- if (uncompressed_size > 0) {
- memset(&z, 0, sizeof(z));
- int rv = deflateInit(&z, Z_DEFAULT_COMPRESSION);
- QUICHE_DCHECK_EQ(Z_OK, rv);
- if (rv != Z_OK) {
- return "";
- }
- scoped_z.reset(&z);
-
- std::string zlib_dict = ZlibDictForEntries(entries, certs);
-
- rv = deflateSetDictionary(
- &z, reinterpret_cast<const uint8_t*>(&zlib_dict[0]), zlib_dict.size());
- QUICHE_DCHECK_EQ(Z_OK, rv);
- if (rv != Z_OK) {
- return "";
- }
-
- compressed_size = deflateBound(&z, uncompressed_size);
- }
-
- const size_t entries_size = CertEntriesSize(entries);
-
- std::string result;
- result.resize(entries_size + (uncompressed_size > 0 ? 4 : 0) +
- compressed_size);
-
- uint8_t* j = reinterpret_cast<uint8_t*>(&result[0]);
- SerializeCertEntries(j, entries);
- j += entries_size;
-
- if (uncompressed_size == 0) {
- return result;
- }
-
- uint32_t uncompressed_size_32 = uncompressed_size;
- memcpy(j, &uncompressed_size_32, sizeof(uint32_t));
- j += sizeof(uint32_t);
-
- int rv;
-
- z.next_out = j;
- z.avail_out = compressed_size;
-
- for (size_t i = 0; i < certs.size(); i++) {
- if (entries[i].type != CertEntry::COMPRESSED) {
- continue;
- }
-
- uint32_t length32 = certs[i].size();
- z.next_in = reinterpret_cast<uint8_t*>(&length32);
- z.avail_in = sizeof(length32);
- rv = deflate(&z, Z_NO_FLUSH);
- QUICHE_DCHECK_EQ(Z_OK, rv);
- QUICHE_DCHECK_EQ(0u, z.avail_in);
- if (rv != Z_OK || z.avail_in) {
- return "";
- }
-
- z.next_in =
- const_cast<uint8_t*>(reinterpret_cast<const uint8_t*>(certs[i].data()));
- z.avail_in = certs[i].size();
- rv = deflate(&z, Z_NO_FLUSH);
- QUICHE_DCHECK_EQ(Z_OK, rv);
- QUICHE_DCHECK_EQ(0u, z.avail_in);
- if (rv != Z_OK || z.avail_in) {
- return "";
- }
- }
-
- z.avail_in = 0;
- rv = deflate(&z, Z_FINISH);
- QUICHE_DCHECK_EQ(Z_STREAM_END, rv);
- if (rv != Z_STREAM_END) {
- return "";
- }
-
- result.resize(result.size() - z.avail_out);
- return result;
-}
-
-// static
-bool CertCompressor::DecompressChain(
- absl::string_view in,
- const std::vector<std::string>& cached_certs,
- const CommonCertSets* common_sets,
- std::vector<std::string>* out_certs) {
- std::vector<CertEntry> entries;
- if (!ParseEntries(&in, cached_certs, common_sets, &entries, out_certs)) {
- return false;
- }
- QUICHE_DCHECK_EQ(entries.size(), out_certs->size());
-
- std::unique_ptr<uint8_t[]> uncompressed_data;
- absl::string_view uncompressed;
-
- if (!in.empty()) {
- if (in.size() < sizeof(uint32_t)) {
- return false;
- }
-
- uint32_t uncompressed_size;
- memcpy(&uncompressed_size, in.data(), sizeof(uncompressed_size));
- in.remove_prefix(sizeof(uint32_t));
-
- if (uncompressed_size > 128 * 1024) {
- return false;
- }
-
- uncompressed_data = std::make_unique<uint8_t[]>(uncompressed_size);
- z_stream z;
- ScopedZLib scoped_z(ScopedZLib::INFLATE);
-
- memset(&z, 0, sizeof(z));
- z.next_out = uncompressed_data.get();
- z.avail_out = uncompressed_size;
- z.next_in =
- const_cast<uint8_t*>(reinterpret_cast<const uint8_t*>(in.data()));
- z.avail_in = in.size();
-
- if (Z_OK != inflateInit(&z)) {
- return false;
- }
- scoped_z.reset(&z);
-
- int rv = inflate(&z, Z_FINISH);
- if (rv == Z_NEED_DICT) {
- std::string zlib_dict = ZlibDictForEntries(entries, *out_certs);
- const uint8_t* dict = reinterpret_cast<const uint8_t*>(zlib_dict.data());
- if (Z_OK != inflateSetDictionary(&z, dict, zlib_dict.size())) {
- return false;
- }
- rv = inflate(&z, Z_FINISH);
- }
-
- if (Z_STREAM_END != rv || z.avail_out > 0 || z.avail_in > 0) {
- return false;
- }
-
- uncompressed = absl::string_view(
- reinterpret_cast<char*>(uncompressed_data.get()), uncompressed_size);
- }
-
- for (size_t i = 0; i < entries.size(); i++) {
- switch (entries[i].type) {
- case CertEntry::COMPRESSED:
- if (uncompressed.size() < sizeof(uint32_t)) {
- return false;
- }
- uint32_t cert_len;
- memcpy(&cert_len, uncompressed.data(), sizeof(cert_len));
- uncompressed.remove_prefix(sizeof(uint32_t));
- if (uncompressed.size() < cert_len) {
- return false;
- }
- (*out_certs)[i] = std::string(uncompressed.substr(0, cert_len));
- uncompressed.remove_prefix(cert_len);
- break;
- case CertEntry::CACHED:
- break;
- case CertEntry::COMMON:
- QUIC_BUG_IF(unexpected_common_cert_entry_3,
- GetQuicRestartFlag(quic_no_common_cert_set));
- break;
- }
- }
-
- if (!uncompressed.empty()) {
- return false;
- }
-
- return true;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/cert_compressor.h b/chromium/net/third_party/quiche/src/quic/core/crypto/cert_compressor.h
deleted file mode 100644
index 85542228fbb..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/cert_compressor.h
+++ /dev/null
@@ -1,56 +0,0 @@
-// Copyright (c) 2013 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_CRYPTO_CERT_COMPRESSOR_H_
-#define QUICHE_QUIC_CORE_CRYPTO_CERT_COMPRESSOR_H_
-
-#include <string>
-#include <vector>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/crypto/common_cert_set.h"
-#include "quic/core/crypto/crypto_protocol.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// CertCompressor provides functions for compressing and decompressing
-// certificate chains using three techniquies:
-// 1) The peer may provide a list of a 64-bit, FNV-1a hashes of certificates
-// that they already have. In the event that one of them is to be
-// compressed, it can be replaced with just the hash.
-// 2) The peer may provide a number of hashes that represent sets of
-// pre-shared certificates (CommonCertSets). If one of those certificates
-// is to be compressed, and it's known to the given CommonCertSets, then it
-// can be replaced with a set hash and certificate index.
-// 3) Otherwise the certificates are compressed with zlib using a pre-shared
-// dictionary that consists of the certificates handled with the above
-// methods and a small chunk of common substrings.
-class QUIC_EXPORT_PRIVATE CertCompressor {
- public:
- CertCompressor() = delete;
-
- // CompressChain compresses the certificates in |certs| and returns a
- // compressed representation. |common_sets| contains the common certificate
- // sets known locally and |client_common_set_hashes| contains the hashes of
- // the common sets known to the peer. |client_cached_cert_hashes| contains
- // 64-bit, FNV-1a hashes of certificates that the peer already possesses.
- static std::string CompressChain(const std::vector<std::string>& certs,
- absl::string_view client_common_set_hashes,
- absl::string_view client_cached_cert_hashes,
- const CommonCertSets* common_sets);
-
- // DecompressChain decompresses the result of |CompressChain|, given in |in|,
- // into a series of certificates that are written to |out_certs|.
- // |cached_certs| contains certificates that the peer may have omitted and
- // |common_sets| contains the common certificate sets known locally.
- static bool DecompressChain(absl::string_view in,
- const std::vector<std::string>& cached_certs,
- const CommonCertSets* common_sets,
- std::vector<std::string>* out_certs);
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_CRYPTO_CERT_COMPRESSOR_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/cert_compressor_test.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/cert_compressor_test.cc
deleted file mode 100644
index f4ac507d141..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/cert_compressor_test.cc
+++ /dev/null
@@ -1,137 +0,0 @@
-// Copyright (c) 2013 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 "quic/core/crypto/cert_compressor.h"
-
-#include <memory>
-#include <string>
-
-#include "absl/strings/escaping.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/crypto_test_utils.h"
-
-namespace quic {
-namespace test {
-
-class CertCompressorTest : public QuicTest {};
-
-TEST_F(CertCompressorTest, EmptyChain) {
- std::vector<std::string> chain;
- const std::string compressed = CertCompressor::CompressChain(
- chain, absl::string_view(), absl::string_view(), nullptr);
- EXPECT_EQ("00", absl::BytesToHexString(compressed));
-
- std::vector<std::string> chain2, cached_certs;
- ASSERT_TRUE(CertCompressor::DecompressChain(compressed, cached_certs, nullptr,
- &chain2));
- EXPECT_EQ(chain.size(), chain2.size());
-}
-
-TEST_F(CertCompressorTest, Compressed) {
- std::vector<std::string> chain;
- chain.push_back("testcert");
- const std::string compressed = CertCompressor::CompressChain(
- chain, absl::string_view(), absl::string_view(), nullptr);
- ASSERT_GE(compressed.size(), 2u);
- EXPECT_EQ("0100", absl::BytesToHexString(compressed.substr(0, 2)));
-
- std::vector<std::string> chain2, cached_certs;
- ASSERT_TRUE(CertCompressor::DecompressChain(compressed, cached_certs, nullptr,
- &chain2));
- EXPECT_EQ(chain.size(), chain2.size());
- EXPECT_EQ(chain[0], chain2[0]);
-}
-
-TEST_F(CertCompressorTest, Common) {
- std::vector<std::string> chain;
- chain.push_back("testcert");
- static const uint64_t set_hash = 42;
- std::unique_ptr<CommonCertSets> common_sets(
- crypto_test_utils::MockCommonCertSets(chain[0], set_hash, 1));
- const std::string compressed = CertCompressor::CompressChain(
- chain,
- absl::string_view(reinterpret_cast<const char*>(&set_hash),
- sizeof(set_hash)),
- absl::string_view(), common_sets.get());
- if (!GetQuicRestartFlag(quic_no_common_cert_set)) {
- EXPECT_EQ(
- "03" /* common */
- "2a00000000000000" /* set hash 42 */
- "01000000" /* index 1 */
- "00" /* end of list */,
- absl::BytesToHexString(compressed));
- } else {
- ASSERT_GE(compressed.size(), 2u);
- // 01 is the prefix for a zlib "compressed" cert not common or cached.
- EXPECT_EQ("0100", absl::BytesToHexString(compressed.substr(0, 2)));
- }
-
- std::vector<std::string> chain2, cached_certs;
- ASSERT_TRUE(CertCompressor::DecompressChain(compressed, cached_certs,
- common_sets.get(), &chain2));
- EXPECT_EQ(chain.size(), chain2.size());
- EXPECT_EQ(chain[0], chain2[0]);
-}
-
-TEST_F(CertCompressorTest, Cached) {
- std::vector<std::string> chain;
- chain.push_back("testcert");
- uint64_t hash = QuicUtils::FNV1a_64_Hash(chain[0]);
- absl::string_view hash_bytes(reinterpret_cast<char*>(&hash), sizeof(hash));
- const std::string compressed = CertCompressor::CompressChain(
- chain, absl::string_view(), hash_bytes, nullptr);
-
- EXPECT_EQ("02" /* cached */ + absl::BytesToHexString(hash_bytes) +
- "00" /* end of list */,
- absl::BytesToHexString(compressed));
-
- std::vector<std::string> cached_certs, chain2;
- cached_certs.push_back(chain[0]);
- ASSERT_TRUE(CertCompressor::DecompressChain(compressed, cached_certs, nullptr,
- &chain2));
- EXPECT_EQ(chain.size(), chain2.size());
- EXPECT_EQ(chain[0], chain2[0]);
-}
-
-TEST_F(CertCompressorTest, BadInputs) {
- std::vector<std::string> cached_certs, chain;
-
- EXPECT_FALSE(CertCompressor::DecompressChain(
- absl::BytesToHexString("04") /* bad entry type */, cached_certs, nullptr,
- &chain));
-
- EXPECT_FALSE(CertCompressor::DecompressChain(
- absl::BytesToHexString("01") /* no terminator */, cached_certs, nullptr,
- &chain));
-
- EXPECT_FALSE(CertCompressor::DecompressChain(
- absl::BytesToHexString("0200") /* hash truncated */, cached_certs,
- nullptr, &chain));
-
- EXPECT_FALSE(CertCompressor::DecompressChain(
- absl::BytesToHexString("0300") /* hash and index truncated */,
- cached_certs, nullptr, &chain));
-
- /* without a CommonCertSets */
- EXPECT_FALSE(
- CertCompressor::DecompressChain(absl::BytesToHexString("03"
- "0000000000000000"
- "00000000"),
- cached_certs, nullptr, &chain));
-
- std::unique_ptr<CommonCertSets> common_sets(
- crypto_test_utils::MockCommonCertSets("foo", 42, 1));
-
- /* incorrect hash and index */
- EXPECT_FALSE(
- CertCompressor::DecompressChain(absl::BytesToHexString("03"
- "a200000000000000"
- "00000000"),
- cached_certs, nullptr, &chain));
-}
-
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/certificate_util.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/certificate_util.cc
deleted file mode 100644
index 550adffa582..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/certificate_util.cc
+++ /dev/null
@@ -1,280 +0,0 @@
-// Copyright 2021 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 "quic/core/crypto/certificate_util.h"
-
-#include "absl/strings/str_format.h"
-#include "absl/strings/str_split.h"
-#include "absl/strings/string_view.h"
-#include "third_party/boringssl/src/include/openssl/bn.h"
-#include "third_party/boringssl/src/include/openssl/bytestring.h"
-#include "third_party/boringssl/src/include/openssl/digest.h"
-#include "third_party/boringssl/src/include/openssl/ec_key.h"
-#include "third_party/boringssl/src/include/openssl/mem.h"
-#include "third_party/boringssl/src/include/openssl/pkcs7.h"
-#include "third_party/boringssl/src/include/openssl/pool.h"
-#include "third_party/boringssl/src/include/openssl/rsa.h"
-#include "third_party/boringssl/src/include/openssl/stack.h"
-#include "quic/core/crypto/boring_utils.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-namespace {
-bool AddEcdsa256SignatureAlgorithm(CBB* cbb) {
- // See RFC 5758. This is the encoding of OID 1.2.840.10045.4.3.2.
- static const uint8_t kEcdsaWithSha256[] = {0x2a, 0x86, 0x48, 0xce,
- 0x3d, 0x04, 0x03, 0x02};
-
- // An AlgorithmIdentifier is described in RFC 5280, 4.1.1.2.
- CBB sequence, oid;
- if (!CBB_add_asn1(cbb, &sequence, CBS_ASN1_SEQUENCE) ||
- !CBB_add_asn1(&sequence, &oid, CBS_ASN1_OBJECT)) {
- return false;
- }
-
- if (!CBB_add_bytes(&oid, kEcdsaWithSha256, sizeof(kEcdsaWithSha256))) {
- return false;
- }
-
- // RFC 5758, section 3.2: ecdsa-with-sha256 MUST omit the parameters field.
- return CBB_flush(cbb);
-}
-
-// Adds an X.509 Name with the specified distinguished name to |cbb|.
-bool AddName(CBB* cbb, absl::string_view name) {
- // See RFC 4519.
- static const uint8_t kCommonName[] = {0x55, 0x04, 0x03};
- static const uint8_t kCountryName[] = {0x55, 0x04, 0x06};
- static const uint8_t kOrganizationName[] = {0x55, 0x04, 0x0a};
- static const uint8_t kOrganizationalUnitName[] = {0x55, 0x04, 0x0b};
-
- std::vector<std::string> attributes =
- absl::StrSplit(name, ',', absl::SkipEmpty());
-
- if (attributes.empty()) {
- QUIC_LOG(ERROR) << "Missing DN or wrong format";
- return false;
- }
-
- // See RFC 5280, section 4.1.2.4.
- CBB rdns;
- if (!CBB_add_asn1(cbb, &rdns, CBS_ASN1_SEQUENCE)) {
- return false;
- }
-
- for (const std::string& attribute : attributes) {
- std::vector<std::string> parts =
- absl::StrSplit(absl::StripAsciiWhitespace(attribute), '=');
- if (parts.size() != 2) {
- QUIC_LOG(ERROR) << "Wrong DN format at " + attribute;
- return false;
- }
-
- const std::string& type_string = parts[0];
- const std::string& value_string = parts[1];
- absl::Span<const uint8_t> type_bytes;
- if (type_string == "CN") {
- type_bytes = kCommonName;
- } else if (type_string == "C") {
- type_bytes = kCountryName;
- } else if (type_string == "O") {
- type_bytes = kOrganizationName;
- } else if (type_string == "OU") {
- type_bytes = kOrganizationalUnitName;
- } else {
- QUIC_LOG(ERROR) << "Unrecognized type " + type_string;
- return false;
- }
-
- CBB rdn, attr, type, value;
- if (!CBB_add_asn1(&rdns, &rdn, CBS_ASN1_SET) ||
- !CBB_add_asn1(&rdn, &attr, CBS_ASN1_SEQUENCE) ||
- !CBB_add_asn1(&attr, &type, CBS_ASN1_OBJECT) ||
- !CBB_add_bytes(&type, type_bytes.data(), type_bytes.size()) ||
- !CBB_add_asn1(&attr, &value,
- type_string == "C" ? CBS_ASN1_PRINTABLESTRING
- : CBS_ASN1_UTF8STRING) ||
- !AddStringToCbb(&value, value_string) || !CBB_flush(&rdns)) {
- return false;
- }
- }
- if (!CBB_flush(cbb)) {
- return false;
- }
- return true;
-}
-
-bool CBBAddTime(CBB* cbb, const CertificateTimestamp& timestamp) {
- CBB child;
- std::string formatted_time;
-
- // Per RFC 5280, 4.1.2.5, times which fit in UTCTime must be encoded as
- // UTCTime rather than GeneralizedTime.
- const bool is_utc_time = (1950 <= timestamp.year && timestamp.year < 2050);
- if (is_utc_time) {
- uint16_t year = timestamp.year - 1900;
- if (year >= 100) {
- year -= 100;
- }
- formatted_time = absl::StrFormat("%02d", year);
- if (!CBB_add_asn1(cbb, &child, CBS_ASN1_UTCTIME)) {
- return false;
- }
- } else {
- formatted_time = absl::StrFormat("%04d", timestamp.year);
- if (!CBB_add_asn1(cbb, &child, CBS_ASN1_GENERALIZEDTIME)) {
- return false;
- }
- }
-
- absl::StrAppendFormat(&formatted_time, "%02d%02d%02d%02d%02dZ",
- timestamp.month, timestamp.day, timestamp.hour,
- timestamp.minute, timestamp.second);
-
- static const size_t kGeneralizedTimeLength = 15;
- static const size_t kUTCTimeLength = 13;
- QUICHE_DCHECK_EQ(formatted_time.size(),
- is_utc_time ? kUTCTimeLength : kGeneralizedTimeLength);
-
- return AddStringToCbb(&child, formatted_time) && CBB_flush(cbb);
-}
-
-bool CBBAddExtension(CBB* extensions, absl::Span<const uint8_t> oid,
- bool critical, absl::Span<const uint8_t> contents) {
- CBB extension, cbb_oid, cbb_contents;
- if (!CBB_add_asn1(extensions, &extension, CBS_ASN1_SEQUENCE) ||
- !CBB_add_asn1(&extension, &cbb_oid, CBS_ASN1_OBJECT) ||
- !CBB_add_bytes(&cbb_oid, oid.data(), oid.size()) ||
- (critical && !CBB_add_asn1_bool(&extension, 1)) ||
- !CBB_add_asn1(&extension, &cbb_contents, CBS_ASN1_OCTETSTRING) ||
- !CBB_add_bytes(&cbb_contents, contents.data(), contents.size()) ||
- !CBB_flush(extensions)) {
- return false;
- }
-
- return true;
-}
-
-bool IsEcdsa256Key(const EVP_PKEY& evp_key) {
- if (EVP_PKEY_id(&evp_key) != EVP_PKEY_EC) {
- return false;
- }
- const EC_KEY* key = EVP_PKEY_get0_EC_KEY(&evp_key);
- if (key == nullptr) {
- return false;
- }
- const EC_GROUP* group = EC_KEY_get0_group(key);
- if (group == nullptr) {
- return false;
- }
- return EC_GROUP_get_curve_name(group) == NID_X9_62_prime256v1;
-}
-
-} // namespace
-
-bssl::UniquePtr<EVP_PKEY> MakeKeyPairForSelfSignedCertificate() {
- bssl::UniquePtr<EVP_PKEY_CTX> context(
- EVP_PKEY_CTX_new_id(EVP_PKEY_EC, nullptr));
- if (!context) {
- return nullptr;
- }
- if (EVP_PKEY_keygen_init(context.get()) != 1) {
- return nullptr;
- }
- if (EVP_PKEY_CTX_set_ec_paramgen_curve_nid(context.get(),
- NID_X9_62_prime256v1) != 1) {
- return nullptr;
- }
- EVP_PKEY* raw_key = nullptr;
- if (EVP_PKEY_keygen(context.get(), &raw_key) != 1) {
- return nullptr;
- }
- return bssl::UniquePtr<EVP_PKEY>(raw_key);
-}
-
-std::string CreateSelfSignedCertificate(EVP_PKEY& key,
- const CertificateOptions& options) {
- std::string error;
- if (!IsEcdsa256Key(key)) {
- QUIC_LOG(ERROR) << "CreateSelfSignedCert only accepts ECDSA P-256 keys";
- return error;
- }
-
- // See RFC 5280, section 4.1. First, construct the TBSCertificate.
- bssl::ScopedCBB cbb;
- CBB tbs_cert, version, validity;
- uint8_t* tbs_cert_bytes;
- size_t tbs_cert_len;
-
- if (!CBB_init(cbb.get(), 64) ||
- !CBB_add_asn1(cbb.get(), &tbs_cert, CBS_ASN1_SEQUENCE) ||
- !CBB_add_asn1(&tbs_cert, &version,
- CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0) ||
- !CBB_add_asn1_uint64(&version, 2) || // X.509 version 3
- !CBB_add_asn1_uint64(&tbs_cert, options.serial_number) ||
- !AddEcdsa256SignatureAlgorithm(&tbs_cert) || // signature algorithm
- !AddName(&tbs_cert, options.subject) || // issuer
- !CBB_add_asn1(&tbs_cert, &validity, CBS_ASN1_SEQUENCE) ||
- !CBBAddTime(&validity, options.validity_start) ||
- !CBBAddTime(&validity, options.validity_end) ||
- !AddName(&tbs_cert, options.subject) || // subject
- !EVP_marshal_public_key(&tbs_cert, &key)) { // subjectPublicKeyInfo
- return error;
- }
-
- CBB outer_extensions, extensions;
- if (!CBB_add_asn1(&tbs_cert, &outer_extensions,
- 3 | CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED) ||
- !CBB_add_asn1(&outer_extensions, &extensions, CBS_ASN1_SEQUENCE)) {
- return error;
- }
-
- // Key Usage
- constexpr uint8_t kKeyUsageOid[] = {0x55, 0x1d, 0x0f};
- constexpr uint8_t kKeyUsageContent[] = {
- 0x3, // BIT STRING
- 0x2, // Length
- 0x0, // Unused bits
- 0x80, // bit(0): digitalSignature
- };
- CBBAddExtension(&extensions, kKeyUsageOid, true, kKeyUsageContent);
-
- // TODO(wub): Add more extensions here if needed.
-
- if (!CBB_finish(cbb.get(), &tbs_cert_bytes, &tbs_cert_len)) {
- return error;
- }
-
- bssl::UniquePtr<uint8_t> delete_tbs_cert_bytes(tbs_cert_bytes);
-
- // Sign the TBSCertificate and write the entire certificate.
- CBB cert, signature;
- bssl::ScopedEVP_MD_CTX ctx;
- uint8_t* sig_out;
- size_t sig_len;
- uint8_t* cert_bytes;
- size_t cert_len;
- if (!CBB_init(cbb.get(), tbs_cert_len) ||
- !CBB_add_asn1(cbb.get(), &cert, CBS_ASN1_SEQUENCE) ||
- !CBB_add_bytes(&cert, tbs_cert_bytes, tbs_cert_len) ||
- !AddEcdsa256SignatureAlgorithm(&cert) ||
- !CBB_add_asn1(&cert, &signature, CBS_ASN1_BITSTRING) ||
- !CBB_add_u8(&signature, 0 /* no unused bits */) ||
- !EVP_DigestSignInit(ctx.get(), nullptr, EVP_sha256(), nullptr, &key) ||
- // Compute the maximum signature length.
- !EVP_DigestSign(ctx.get(), nullptr, &sig_len, tbs_cert_bytes,
- tbs_cert_len) ||
- !CBB_reserve(&signature, &sig_out, sig_len) ||
- // Actually sign the TBSCertificate.
- !EVP_DigestSign(ctx.get(), sig_out, &sig_len, tbs_cert_bytes,
- tbs_cert_len) ||
- !CBB_did_write(&signature, sig_len) ||
- !CBB_finish(cbb.get(), &cert_bytes, &cert_len)) {
- return error;
- }
- bssl::UniquePtr<uint8_t> delete_cert_bytes(cert_bytes);
- return std::string(reinterpret_cast<char*>(cert_bytes), cert_len);
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/certificate_util.h b/chromium/net/third_party/quiche/src/quic/core/crypto/certificate_util.h
deleted file mode 100644
index ebc1cf48d6e..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/certificate_util.h
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright 2021 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_CRYPTO_CERTIFICATE_UTIL_H_
-#define QUICHE_QUIC_CORE_CRYPTO_CERTIFICATE_UTIL_H_
-
-#include <string>
-
-#include "absl/strings/string_view.h"
-#include "third_party/boringssl/src/include/openssl/evp.h"
-#include "quic/core/quic_time.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-struct QUIC_NO_EXPORT CertificateTimestamp {
- uint16_t year;
- uint8_t month;
- uint8_t day;
- uint8_t hour;
- uint8_t minute;
- uint8_t second;
-};
-
-struct QUIC_NO_EXPORT CertificateOptions {
- absl::string_view subject;
- uint64_t serial_number;
- CertificateTimestamp validity_start; // a.k.a not_valid_before
- CertificateTimestamp validity_end; // a.k.a not_valid_after
-};
-
-// Creates a ECDSA P-256 key pair.
-QUIC_EXPORT_PRIVATE bssl::UniquePtr<EVP_PKEY>
-MakeKeyPairForSelfSignedCertificate();
-
-// Creates a self-signed, DER-encoded X.509 certificate.
-// |key| must be a ECDSA P-256 key.
-// This is mostly stolen from Chromium's net/cert/x509_util.h, with
-// modifications to make it work in QUICHE.
-QUIC_EXPORT_PRIVATE std::string CreateSelfSignedCertificate(
- EVP_PKEY& key, const CertificateOptions& options);
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_CRYPTO_CERTIFICATE_UTIL_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/certificate_util_test.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/certificate_util_test.cc
deleted file mode 100644
index 1ffe6f551ee..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/certificate_util_test.cc
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright 2021 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 "quic/core/crypto/certificate_util.h"
-
-#include "third_party/boringssl/src/include/openssl/ssl.h"
-#include "quic/core/crypto/certificate_view.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/platform/api/quic_test_output.h"
-
-namespace quic {
-namespace test {
-namespace {
-
-TEST(CertificateUtilTest, CreateSelfSignedCertificate) {
- bssl::UniquePtr<EVP_PKEY> key = MakeKeyPairForSelfSignedCertificate();
- ASSERT_NE(key, nullptr);
-
- CertificatePrivateKey cert_key(std::move(key));
-
- CertificateOptions options;
- options.subject = "CN=subject";
- options.serial_number = 0x12345678;
- options.validity_start = {2020, 1, 1, 0, 0, 0};
- options.validity_end = {2049, 12, 31, 0, 0, 0};
- std::string der_cert =
- CreateSelfSignedCertificate(*cert_key.private_key(), options);
- ASSERT_FALSE(der_cert.empty());
-
- QuicSaveTestOutput("CertificateUtilTest_CreateSelfSignedCert.crt", der_cert);
-
- std::unique_ptr<CertificateView> cert_view =
- CertificateView::ParseSingleCertificate(der_cert);
- ASSERT_NE(cert_view, nullptr);
- EXPECT_EQ(cert_view->public_key_type(), PublicKeyType::kP256);
-
- absl::optional<std::string> subject = cert_view->GetHumanReadableSubject();
- ASSERT_TRUE(subject.has_value());
- EXPECT_EQ(*subject, options.subject);
-
- EXPECT_TRUE(
- cert_key.ValidForSignatureAlgorithm(SSL_SIGN_ECDSA_SECP256R1_SHA256));
- EXPECT_TRUE(cert_key.MatchesPublicKey(*cert_view));
-}
-
-} // namespace
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/certificate_view.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/certificate_view.cc
deleted file mode 100644
index 12866670783..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/certificate_view.cc
+++ /dev/null
@@ -1,650 +0,0 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/crypto/certificate_view.h"
-
-#include <algorithm>
-#include <cstdint>
-#include <memory>
-#include <string>
-
-#include "absl/strings/escaping.h"
-#include "absl/strings/match.h"
-#include "absl/strings/str_cat.h"
-#include "absl/strings/str_join.h"
-#include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
-#include "third_party/boringssl/src/include/openssl/base.h"
-#include "third_party/boringssl/src/include/openssl/bytestring.h"
-#include "third_party/boringssl/src/include/openssl/digest.h"
-#include "third_party/boringssl/src/include/openssl/ec.h"
-#include "third_party/boringssl/src/include/openssl/ec_key.h"
-#include "third_party/boringssl/src/include/openssl/evp.h"
-#include "third_party/boringssl/src/include/openssl/nid.h"
-#include "third_party/boringssl/src/include/openssl/rsa.h"
-#include "third_party/boringssl/src/include/openssl/ssl.h"
-#include "quic/core/crypto/boring_utils.h"
-#include "quic/core/quic_time.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_ip_address.h"
-#include "quic/platform/api/quic_logging.h"
-#include "common/platform/api/quiche_time_utils.h"
-#include "common/quiche_data_reader.h"
-#include "common/quiche_text_utils.h"
-
-namespace quic {
-namespace {
-
-using ::quiche::QuicheTextUtils;
-
-// The literals below were encoded using `ascii2der | xxd -i`. The comments
-// above the literals are the contents in the der2ascii syntax.
-
-// X.509 version 3 (version numbering starts with zero).
-// INTEGER { 2 }
-constexpr uint8_t kX509Version[] = {0x02, 0x01, 0x02};
-
-// 2.5.29.17
-constexpr uint8_t kSubjectAltNameOid[] = {0x55, 0x1d, 0x11};
-
-PublicKeyType PublicKeyTypeFromKey(EVP_PKEY* public_key) {
- switch (EVP_PKEY_id(public_key)) {
- case EVP_PKEY_RSA:
- return PublicKeyType::kRsa;
- case EVP_PKEY_EC: {
- const EC_KEY* key = EVP_PKEY_get0_EC_KEY(public_key);
- if (key == nullptr) {
- return PublicKeyType::kUnknown;
- }
- const EC_GROUP* group = EC_KEY_get0_group(key);
- if (group == nullptr) {
- return PublicKeyType::kUnknown;
- }
- const int curve_nid = EC_GROUP_get_curve_name(group);
- switch (curve_nid) {
- case NID_X9_62_prime256v1:
- return PublicKeyType::kP256;
- case NID_secp384r1:
- return PublicKeyType::kP384;
- default:
- return PublicKeyType::kUnknown;
- }
- }
- case EVP_PKEY_ED25519:
- return PublicKeyType::kEd25519;
- default:
- return PublicKeyType::kUnknown;
- }
-}
-
-PublicKeyType PublicKeyTypeFromSignatureAlgorithm(
- uint16_t signature_algorithm) {
- switch (signature_algorithm) {
- case SSL_SIGN_RSA_PSS_RSAE_SHA256:
- return PublicKeyType::kRsa;
- case SSL_SIGN_ECDSA_SECP256R1_SHA256:
- return PublicKeyType::kP256;
- case SSL_SIGN_ECDSA_SECP384R1_SHA384:
- return PublicKeyType::kP384;
- case SSL_SIGN_ED25519:
- return PublicKeyType::kEd25519;
- default:
- return PublicKeyType::kUnknown;
- }
-}
-
-std::string AttributeNameToString(const CBS& oid_cbs) {
- absl::string_view oid = CbsToStringPiece(oid_cbs);
-
- // We only handle OIDs of form 2.5.4.N, which have binary encoding of
- // "55 04 0N".
- if (oid.length() == 3 && absl::StartsWith(oid, "\x55\x04")) {
- // clang-format off
- switch (oid[2]) {
- case '\x3': return "CN";
- case '\x7': return "L";
- case '\x8': return "ST";
- case '\xa': return "O";
- case '\xb': return "OU";
- case '\x6': return "C";
- }
- // clang-format on
- }
-
- bssl::UniquePtr<char> oid_representation(CBS_asn1_oid_to_text(&oid_cbs));
- if (oid_representation == nullptr) {
- return absl::StrCat("(", absl::BytesToHexString(oid), ")");
- }
- return std::string(oid_representation.get());
-}
-
-} // namespace
-
-absl::optional<std::string> X509NameAttributeToString(CBS input) {
- CBS name, value;
- unsigned value_tag;
- if (!CBS_get_asn1(&input, &name, CBS_ASN1_OBJECT) ||
- !CBS_get_any_asn1(&input, &value, &value_tag) || CBS_len(&input) != 0) {
- return absl::nullopt;
- }
- // Note that this does not process encoding of |input| in any way. This works
- // fine for the most cases.
- return absl::StrCat(AttributeNameToString(name), "=",
- absl::CHexEscape(CbsToStringPiece(value)));
-}
-
-namespace {
-
-template <unsigned inner_tag,
- char separator,
- absl::optional<std::string> (*parser)(CBS)>
-absl::optional<std::string> ParseAndJoin(CBS input) {
- std::vector<std::string> pieces;
- while (CBS_len(&input) != 0) {
- CBS attribute;
- if (!CBS_get_asn1(&input, &attribute, inner_tag)) {
- return absl::nullopt;
- }
- absl::optional<std::string> formatted = parser(attribute);
- if (!formatted.has_value()) {
- return absl::nullopt;
- }
- pieces.push_back(*formatted);
- }
-
- return absl::StrJoin(pieces, std::string({separator}));
-}
-
-absl::optional<std::string> RelativeDistinguishedNameToString(CBS input) {
- return ParseAndJoin<CBS_ASN1_SEQUENCE, '+', X509NameAttributeToString>(input);
-}
-
-absl::optional<std::string> DistinguishedNameToString(CBS input) {
- return ParseAndJoin<CBS_ASN1_SET, ',', RelativeDistinguishedNameToString>(
- input);
-}
-
-} // namespace
-
-std::string PublicKeyTypeToString(PublicKeyType type) {
- switch (type) {
- case PublicKeyType::kRsa:
- return "RSA";
- case PublicKeyType::kP256:
- return "ECDSA P-256";
- case PublicKeyType::kP384:
- return "ECDSA P-384";
- case PublicKeyType::kEd25519:
- return "Ed25519";
- case PublicKeyType::kUnknown:
- return "unknown";
- }
- return "";
-}
-
-absl::optional<quic::QuicWallTime> ParseDerTime(unsigned tag,
- absl::string_view payload) {
- if (tag != CBS_ASN1_GENERALIZEDTIME && tag != CBS_ASN1_UTCTIME) {
- QUIC_DLOG(WARNING) << "Invalid tag supplied for a DER timestamp";
- return absl::nullopt;
- }
-
- const size_t year_length = tag == CBS_ASN1_GENERALIZEDTIME ? 4 : 2;
- uint64_t year, month, day, hour, minute, second;
- quiche::QuicheDataReader reader(payload);
- if (!reader.ReadDecimal64(year_length, &year) ||
- !reader.ReadDecimal64(2, &month) || !reader.ReadDecimal64(2, &day) ||
- !reader.ReadDecimal64(2, &hour) || !reader.ReadDecimal64(2, &minute) ||
- !reader.ReadDecimal64(2, &second) ||
- reader.ReadRemainingPayload() != "Z") {
- QUIC_DLOG(WARNING) << "Failed to parse the DER timestamp";
- return absl::nullopt;
- }
-
- if (tag == CBS_ASN1_UTCTIME) {
- QUICHE_DCHECK_LE(year, 100u);
- year += (year >= 50) ? 1900 : 2000;
- }
-
- const absl::optional<int64_t> unix_time =
- quiche::QuicheUtcDateTimeToUnixSeconds(year, month, day, hour, minute,
- second);
- if (!unix_time.has_value() || *unix_time < 0) {
- return absl::nullopt;
- }
- return QuicWallTime::FromUNIXSeconds(*unix_time);
-}
-
-PemReadResult ReadNextPemMessage(std::istream* input) {
- constexpr absl::string_view kPemBegin = "-----BEGIN ";
- constexpr absl::string_view kPemEnd = "-----END ";
- constexpr absl::string_view kPemDashes = "-----";
-
- std::string line_buffer, encoded_message_contents, expected_end;
- bool pending_message = false;
- PemReadResult result;
- while (std::getline(*input, line_buffer)) {
- absl::string_view line(line_buffer);
- QuicheTextUtils::RemoveLeadingAndTrailingWhitespace(&line);
-
- // Handle BEGIN lines.
- if (!pending_message && absl::StartsWith(line, kPemBegin) &&
- absl::EndsWith(line, kPemDashes)) {
- result.type = std::string(
- line.substr(kPemBegin.size(),
- line.size() - kPemDashes.size() - kPemBegin.size()));
- expected_end = absl::StrCat(kPemEnd, result.type, kPemDashes);
- pending_message = true;
- continue;
- }
-
- // Handle END lines.
- if (pending_message && line == expected_end) {
- absl::optional<std::string> data =
- QuicheTextUtils::Base64Decode(encoded_message_contents);
- if (data.has_value()) {
- result.status = PemReadResult::kOk;
- result.contents = data.value();
- } else {
- result.status = PemReadResult::kError;
- }
- return result;
- }
-
- if (pending_message) {
- encoded_message_contents.append(std::string(line));
- }
- }
- bool eof_reached = input->eof() && !pending_message;
- return PemReadResult{
- (eof_reached ? PemReadResult::kEof : PemReadResult::kError), "", ""};
-}
-
-std::unique_ptr<CertificateView> CertificateView::ParseSingleCertificate(
- absl::string_view certificate) {
- std::unique_ptr<CertificateView> result(new CertificateView());
- CBS top = StringPieceToCbs(certificate);
-
- CBS top_certificate, tbs_certificate, signature_algorithm, signature;
- if (!CBS_get_asn1(&top, &top_certificate, CBS_ASN1_SEQUENCE) ||
- CBS_len(&top) != 0) {
- return nullptr;
- }
-
- // Certificate ::= SEQUENCE {
- if (
- // tbsCertificate TBSCertificate,
- !CBS_get_asn1(&top_certificate, &tbs_certificate, CBS_ASN1_SEQUENCE) ||
-
- // signatureAlgorithm AlgorithmIdentifier,
- !CBS_get_asn1(&top_certificate, &signature_algorithm,
- CBS_ASN1_SEQUENCE) ||
-
- // signature BIT STRING }
- !CBS_get_asn1(&top_certificate, &signature, CBS_ASN1_BITSTRING) ||
- CBS_len(&top_certificate) != 0) {
- return nullptr;
- }
-
- int has_version, has_extensions;
- CBS version, serial, signature_algorithm_inner, issuer, validity, subject,
- spki, issuer_id, subject_id, extensions_outer;
- // TBSCertificate ::= SEQUENCE {
- if (
- // version [0] Version DEFAULT v1,
- !CBS_get_optional_asn1(
- &tbs_certificate, &version, &has_version,
- CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 0) ||
-
- // serialNumber CertificateSerialNumber,
- !CBS_get_asn1(&tbs_certificate, &serial, CBS_ASN1_INTEGER) ||
-
- // signature AlgorithmIdentifier,
- !CBS_get_asn1(&tbs_certificate, &signature_algorithm_inner,
- CBS_ASN1_SEQUENCE) ||
-
- // issuer Name,
- !CBS_get_asn1(&tbs_certificate, &issuer, CBS_ASN1_SEQUENCE) ||
-
- // validity Validity,
- !CBS_get_asn1(&tbs_certificate, &validity, CBS_ASN1_SEQUENCE) ||
-
- // subject Name,
- !CBS_get_asn1(&tbs_certificate, &subject, CBS_ASN1_SEQUENCE) ||
-
- // subjectPublicKeyInfo SubjectPublicKeyInfo,
- !CBS_get_asn1_element(&tbs_certificate, &spki, CBS_ASN1_SEQUENCE) ||
-
- // issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL,
- // -- If present, version MUST be v2 or v3
- !CBS_get_optional_asn1(&tbs_certificate, &issuer_id, nullptr,
- CBS_ASN1_CONTEXT_SPECIFIC | 1) ||
-
- // subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL,
- // -- If present, version MUST be v2 or v3
- !CBS_get_optional_asn1(&tbs_certificate, &subject_id, nullptr,
- CBS_ASN1_CONTEXT_SPECIFIC | 2) ||
-
- // extensions [3] Extensions OPTIONAL
- // -- If present, version MUST be v3 -- }
- !CBS_get_optional_asn1(
- &tbs_certificate, &extensions_outer, &has_extensions,
- CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 3) ||
-
- CBS_len(&tbs_certificate) != 0) {
- return nullptr;
- }
-
- result->subject_der_ = CbsToStringPiece(subject);
-
- unsigned not_before_tag, not_after_tag;
- CBS not_before, not_after;
- if (!CBS_get_any_asn1(&validity, &not_before, &not_before_tag) ||
- !CBS_get_any_asn1(&validity, &not_after, &not_after_tag) ||
- CBS_len(&validity) != 0) {
- QUIC_DLOG(WARNING) << "Failed to extract the validity dates";
- return nullptr;
- }
- absl::optional<QuicWallTime> not_before_parsed =
- ParseDerTime(not_before_tag, CbsToStringPiece(not_before));
- absl::optional<QuicWallTime> not_after_parsed =
- ParseDerTime(not_after_tag, CbsToStringPiece(not_after));
- if (!not_before_parsed.has_value() || !not_after_parsed.has_value()) {
- QUIC_DLOG(WARNING) << "Failed to parse validity dates";
- return nullptr;
- }
- result->validity_start_ = *not_before_parsed;
- result->validity_end_ = *not_after_parsed;
-
- result->public_key_.reset(EVP_parse_public_key(&spki));
- if (result->public_key_ == nullptr) {
- QUIC_DLOG(WARNING) << "Failed to parse the public key";
- return nullptr;
- }
- if (!result->ValidatePublicKeyParameters()) {
- QUIC_DLOG(WARNING) << "Public key has invalid parameters";
- return nullptr;
- }
-
- // Only support X.509v3.
- if (!has_version ||
- !CBS_mem_equal(&version, kX509Version, sizeof(kX509Version))) {
- QUIC_DLOG(WARNING) << "Bad X.509 version";
- return nullptr;
- }
-
- if (!has_extensions) {
- return nullptr;
- }
-
- CBS extensions;
- if (!CBS_get_asn1(&extensions_outer, &extensions, CBS_ASN1_SEQUENCE) ||
- CBS_len(&extensions_outer) != 0) {
- QUIC_DLOG(WARNING) << "Failed to extract the extension sequence";
- return nullptr;
- }
- if (!result->ParseExtensions(extensions)) {
- QUIC_DLOG(WARNING) << "Failed to parse extensions";
- return nullptr;
- }
-
- return result;
-}
-
-bool CertificateView::ParseExtensions(CBS extensions) {
- while (CBS_len(&extensions) != 0) {
- CBS extension, oid, critical, payload;
- if (
- // Extension ::= SEQUENCE {
- !CBS_get_asn1(&extensions, &extension, CBS_ASN1_SEQUENCE) ||
- // extnID OBJECT IDENTIFIER,
- !CBS_get_asn1(&extension, &oid, CBS_ASN1_OBJECT) ||
- // critical BOOLEAN DEFAULT FALSE,
- !CBS_get_optional_asn1(&extension, &critical, nullptr,
- CBS_ASN1_BOOLEAN) ||
- // extnValue OCTET STRING
- // -- contains the DER encoding of an ASN.1 value
- // -- corresponding to the extension type identified
- // -- by extnID
- !CBS_get_asn1(&extension, &payload, CBS_ASN1_OCTETSTRING) ||
- CBS_len(&extension) != 0) {
- QUIC_DLOG(WARNING) << "Bad extension entry";
- return false;
- }
-
- if (CBS_mem_equal(&oid, kSubjectAltNameOid, sizeof(kSubjectAltNameOid))) {
- CBS alt_names;
- if (!CBS_get_asn1(&payload, &alt_names, CBS_ASN1_SEQUENCE) ||
- CBS_len(&payload) != 0) {
- QUIC_DLOG(WARNING) << "Failed to parse subjectAltName";
- return false;
- }
- while (CBS_len(&alt_names) != 0) {
- CBS alt_name_cbs;
- unsigned int alt_name_tag;
- if (!CBS_get_any_asn1(&alt_names, &alt_name_cbs, &alt_name_tag)) {
- QUIC_DLOG(WARNING) << "Failed to parse subjectAltName";
- return false;
- }
-
- absl::string_view alt_name = CbsToStringPiece(alt_name_cbs);
- QuicIpAddress ip_address;
- // GeneralName ::= CHOICE {
- switch (alt_name_tag) {
- // dNSName [2] IA5String,
- case CBS_ASN1_CONTEXT_SPECIFIC | 2:
- subject_alt_name_domains_.push_back(alt_name);
- break;
-
- // iPAddress [7] OCTET STRING,
- case CBS_ASN1_CONTEXT_SPECIFIC | 7:
- if (!ip_address.FromPackedString(alt_name.data(),
- alt_name.size())) {
- QUIC_DLOG(WARNING) << "Failed to parse subjectAltName IP address";
- return false;
- }
- subject_alt_name_ips_.push_back(ip_address);
- break;
-
- default:
- QUIC_DLOG(INFO) << "Unknown subjectAltName tag " << alt_name_tag;
- continue;
- }
- }
- }
- }
-
- return true;
-}
-
-std::vector<std::string> CertificateView::LoadPemFromStream(
- std::istream* input) {
- std::vector<std::string> result;
- for (;;) {
- PemReadResult read_result = ReadNextPemMessage(input);
- if (read_result.status == PemReadResult::kEof) {
- return result;
- }
- if (read_result.status != PemReadResult::kOk) {
- return std::vector<std::string>();
- }
- if (read_result.type != "CERTIFICATE") {
- continue;
- }
- result.emplace_back(std::move(read_result.contents));
- }
-}
-
-PublicKeyType CertificateView::public_key_type() const {
- return PublicKeyTypeFromKey(public_key_.get());
-}
-
-bool CertificateView::ValidatePublicKeyParameters() {
- // The profile here affects what certificates can be used when QUIC is used as
- // a server library without any custom certificate provider logic.
- // The goal is to allow at minimum any certificate that would be allowed on a
- // regular Web session over TLS 1.3 while ensuring we do not expose any
- // algorithms we don't want to support long-term.
- PublicKeyType key_type = PublicKeyTypeFromKey(public_key_.get());
- switch (key_type) {
- case PublicKeyType::kRsa:
- return EVP_PKEY_bits(public_key_.get()) >= 2048;
- case PublicKeyType::kP256:
- case PublicKeyType::kP384:
- case PublicKeyType::kEd25519:
- return true;
- default:
- return false;
- }
-}
-
-bool CertificateView::VerifySignature(absl::string_view data,
- absl::string_view signature,
- uint16_t signature_algorithm) const {
- if (PublicKeyTypeFromSignatureAlgorithm(signature_algorithm) !=
- PublicKeyTypeFromKey(public_key_.get())) {
- QUIC_BUG(quic_bug_10640_1)
- << "Mismatch between the requested signature algorithm and the "
- "type of the public key.";
- return false;
- }
-
- bssl::ScopedEVP_MD_CTX md_ctx;
- EVP_PKEY_CTX* pctx;
- if (!EVP_DigestVerifyInit(
- md_ctx.get(), &pctx,
- SSL_get_signature_algorithm_digest(signature_algorithm), nullptr,
- public_key_.get())) {
- return false;
- }
- if (SSL_is_signature_algorithm_rsa_pss(signature_algorithm)) {
- if (!EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_PKCS1_PSS_PADDING) ||
- !EVP_PKEY_CTX_set_rsa_pss_saltlen(pctx, -1)) {
- return false;
- }
- }
- return EVP_DigestVerify(
- md_ctx.get(), reinterpret_cast<const uint8_t*>(signature.data()),
- signature.size(), reinterpret_cast<const uint8_t*>(data.data()),
- data.size());
-}
-
-absl::optional<std::string> CertificateView::GetHumanReadableSubject() const {
- CBS input = StringPieceToCbs(subject_der_);
- return DistinguishedNameToString(input);
-}
-
-std::unique_ptr<CertificatePrivateKey> CertificatePrivateKey::LoadFromDer(
- absl::string_view private_key) {
- std::unique_ptr<CertificatePrivateKey> result(new CertificatePrivateKey());
- CBS private_key_cbs = StringPieceToCbs(private_key);
- result->private_key_.reset(EVP_parse_private_key(&private_key_cbs));
- if (result->private_key_ == nullptr || CBS_len(&private_key_cbs) != 0) {
- return nullptr;
- }
- return result;
-}
-
-std::unique_ptr<CertificatePrivateKey> CertificatePrivateKey::LoadPemFromStream(
- std::istream* input) {
-skip:
- PemReadResult result = ReadNextPemMessage(input);
- if (result.status != PemReadResult::kOk) {
- return nullptr;
- }
- // RFC 5958 OneAsymmetricKey message.
- if (result.type == "PRIVATE KEY") {
- return LoadFromDer(result.contents);
- }
- // Legacy OpenSSL format: PKCS#1 (RFC 8017) RSAPrivateKey message.
- if (result.type == "RSA PRIVATE KEY") {
- CBS private_key_cbs = StringPieceToCbs(result.contents);
- bssl::UniquePtr<RSA> rsa(RSA_parse_private_key(&private_key_cbs));
- if (rsa == nullptr || CBS_len(&private_key_cbs) != 0) {
- return nullptr;
- }
-
- std::unique_ptr<CertificatePrivateKey> key(new CertificatePrivateKey());
- key->private_key_.reset(EVP_PKEY_new());
- EVP_PKEY_assign_RSA(key->private_key_.get(), rsa.release());
- return key;
- }
- // EC keys are sometimes generated with "openssl ecparam -genkey". If the user
- // forgets -noout, OpenSSL will output a redundant copy of the EC parameters.
- // Skip those.
- if (result.type == "EC PARAMETERS") {
- goto skip;
- }
- // Legacy OpenSSL format: RFC 5915 ECPrivateKey message.
- if (result.type == "EC PRIVATE KEY") {
- CBS private_key_cbs = StringPieceToCbs(result.contents);
- bssl::UniquePtr<EC_KEY> ec_key(
- EC_KEY_parse_private_key(&private_key_cbs, /*group=*/nullptr));
- if (ec_key == nullptr || CBS_len(&private_key_cbs) != 0) {
- return nullptr;
- }
-
- std::unique_ptr<CertificatePrivateKey> key(new CertificatePrivateKey());
- key->private_key_.reset(EVP_PKEY_new());
- EVP_PKEY_assign_EC_KEY(key->private_key_.get(), ec_key.release());
- return key;
- }
- // Unknown format.
- return nullptr;
-}
-
-std::string CertificatePrivateKey::Sign(absl::string_view input,
- uint16_t signature_algorithm) const {
- if (!ValidForSignatureAlgorithm(signature_algorithm)) {
- QUIC_BUG(quic_bug_10640_2)
- << "Mismatch between the requested signature algorithm and the "
- "type of the private key.";
- return "";
- }
-
- bssl::ScopedEVP_MD_CTX md_ctx;
- EVP_PKEY_CTX* pctx;
- if (!EVP_DigestSignInit(
- md_ctx.get(), &pctx,
- SSL_get_signature_algorithm_digest(signature_algorithm),
- /*e=*/nullptr, private_key_.get())) {
- return "";
- }
- if (SSL_is_signature_algorithm_rsa_pss(signature_algorithm)) {
- if (!EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_PKCS1_PSS_PADDING) ||
- !EVP_PKEY_CTX_set_rsa_pss_saltlen(pctx, -1)) {
- return "";
- }
- }
-
- std::string output;
- size_t output_size;
- if (!EVP_DigestSign(md_ctx.get(), /*out_sig=*/nullptr, &output_size,
- reinterpret_cast<const uint8_t*>(input.data()),
- input.size())) {
- return "";
- }
- output.resize(output_size);
- if (!EVP_DigestSign(
- md_ctx.get(), reinterpret_cast<uint8_t*>(&output[0]), &output_size,
- reinterpret_cast<const uint8_t*>(input.data()), input.size())) {
- return "";
- }
- output.resize(output_size);
- return output;
-}
-
-bool CertificatePrivateKey::MatchesPublicKey(
- const CertificateView& view) const {
- return EVP_PKEY_cmp(view.public_key(), private_key_.get()) == 1;
-}
-
-bool CertificatePrivateKey::ValidForSignatureAlgorithm(
- uint16_t signature_algorithm) const {
- return PublicKeyTypeFromSignatureAlgorithm(signature_algorithm) ==
- PublicKeyTypeFromKey(private_key_.get());
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/certificate_view.h b/chromium/net/third_party/quiche/src/quic/core/crypto/certificate_view.h
deleted file mode 100644
index 5b3c8c762c6..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/certificate_view.h
+++ /dev/null
@@ -1,151 +0,0 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_CRYPTO_CERTIFICATE_VIEW_H_
-#define QUICHE_QUIC_CORE_CRYPTO_CERTIFICATE_VIEW_H_
-
-#include <istream>
-#include <memory>
-#include <vector>
-
-#include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
-#include "third_party/boringssl/src/include/openssl/base.h"
-#include "third_party/boringssl/src/include/openssl/bytestring.h"
-#include "third_party/boringssl/src/include/openssl/evp.h"
-#include "quic/core/crypto/boring_utils.h"
-#include "quic/core/quic_time.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_export.h"
-#include "quic/platform/api/quic_ip_address.h"
-
-namespace quic {
-
-struct QUIC_EXPORT_PRIVATE PemReadResult {
- enum Status { kOk, kEof, kError };
- Status status;
- std::string contents;
- // The type of the PEM message (e.g., if the message starts with
- // "-----BEGIN CERTIFICATE-----", the |type| would be "CERTIFICATE").
- std::string type;
-};
-
-// Reads |input| line-by-line and returns the next available PEM message.
-QUIC_EXPORT_PRIVATE PemReadResult ReadNextPemMessage(std::istream* input);
-
-// Cryptograhpic algorithms recognized in X.509.
-enum class PublicKeyType {
- kRsa,
- kP256,
- kP384,
- kEd25519,
- kUnknown,
-};
-QUIC_EXPORT_PRIVATE std::string PublicKeyTypeToString(PublicKeyType type);
-
-// 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
-// and consists primarily of pointers into the certificate that is passed into
-// the parser.
-class QUIC_EXPORT_PRIVATE CertificateView {
- public:
- // Parses a single DER-encoded X.509 certificate. Returns nullptr on parse
- // error.
- static std::unique_ptr<CertificateView> ParseSingleCertificate(
- absl::string_view certificate);
-
- // Loads all PEM-encoded X.509 certificates found in the |input| stream
- // without parsing them. Returns an empty vector if any parsing error occurs.
- static std::vector<std::string> LoadPemFromStream(std::istream* input);
-
- QuicWallTime validity_start() const { return validity_start_; }
- QuicWallTime validity_end() const { return validity_end_; }
- const EVP_PKEY* public_key() const { return public_key_.get(); }
-
- const std::vector<absl::string_view>& subject_alt_name_domains() const {
- return subject_alt_name_domains_;
- }
- const std::vector<QuicIpAddress>& subject_alt_name_ips() const {
- return subject_alt_name_ips_;
- }
-
- // Returns a human-readable representation of the Subject field. The format
- // is similar to RFC 2253, but does not match it exactly.
- absl::optional<std::string> GetHumanReadableSubject() const;
-
- // |signature_algorithm| is a TLS signature algorithm ID.
- bool VerifySignature(absl::string_view data,
- absl::string_view signature,
- uint16_t signature_algorithm) const;
-
- // Returns the type of the key used in the certificate's SPKI.
- PublicKeyType public_key_type() const;
-
- private:
- CertificateView() = default;
-
- QuicWallTime validity_start_ = QuicWallTime::Zero();
- QuicWallTime validity_end_ = QuicWallTime::Zero();
- absl::string_view subject_der_;
-
- // Public key parsed from SPKI.
- bssl::UniquePtr<EVP_PKEY> public_key_;
-
- // SubjectAltName, https://tools.ietf.org/html/rfc5280#section-4.2.1.6
- std::vector<absl::string_view> subject_alt_name_domains_;
- std::vector<QuicIpAddress> subject_alt_name_ips_;
-
- // Called from ParseSingleCertificate().
- bool ParseExtensions(CBS extensions);
- bool ValidatePublicKeyParameters();
-};
-
-// CertificatePrivateKey represents a private key that can be used with an X.509
-// certificate.
-class QUIC_EXPORT_PRIVATE CertificatePrivateKey {
- public:
- explicit CertificatePrivateKey(bssl::UniquePtr<EVP_PKEY> private_key)
- : private_key_(std::move(private_key)) {}
-
- // Loads a DER-encoded PrivateKeyInfo structure (RFC 5958) as a private key.
- static std::unique_ptr<CertificatePrivateKey> LoadFromDer(
- absl::string_view private_key);
-
- // Loads a private key from a PEM file formatted according to RFC 7468. Also
- // supports legacy OpenSSL RSA key format ("BEGIN RSA PRIVATE KEY").
- static std::unique_ptr<CertificatePrivateKey> LoadPemFromStream(
- std::istream* input);
-
- // |signature_algorithm| is a TLS signature algorithm ID.
- std::string Sign(absl::string_view input, uint16_t signature_algorithm) const;
-
- // Verifies that the private key in question matches the public key of the
- // certificate |view|.
- bool MatchesPublicKey(const CertificateView& view) const;
-
- // Verifies that the private key can be used with the specified TLS signature
- // algorithm.
- bool ValidForSignatureAlgorithm(uint16_t signature_algorithm) const;
-
- EVP_PKEY* private_key() const { return private_key_.get(); }
-
- private:
- CertificatePrivateKey() = default;
-
- bssl::UniquePtr<EVP_PKEY> private_key_;
-};
-
-// Parses a DER-encoded X.509 NameAttribute. Exposed primarily for testing.
-QUIC_EXPORT_PRIVATE absl::optional<std::string> X509NameAttributeToString(
- CBS input);
-
-// Parses a DER time based on the specified ASN.1 tag. Exposed primarily for
-// testing.
-QUIC_EXPORT_PRIVATE absl::optional<quic::QuicWallTime> ParseDerTime(
- unsigned tag,
- absl::string_view payload);
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_CRYPTO_CERTIFICATE_VIEW_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/certificate_view_der_fuzzer.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/certificate_view_der_fuzzer.cc
deleted file mode 100644
index da931a26ecf..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/certificate_view_der_fuzzer.cc
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <string>
-
-#include "quic/core/crypto/certificate_view.h"
-
-extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
- std::string input(reinterpret_cast<const char*>(data), size);
-
- std::unique_ptr<quic::CertificateView> view =
- quic::CertificateView::ParseSingleCertificate(input);
- if (view != nullptr) {
- view->GetHumanReadableSubject();
- }
- quic::CertificatePrivateKey::LoadFromDer(input);
- return 0;
-}
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/certificate_view_pem_fuzzer.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/certificate_view_pem_fuzzer.cc
deleted file mode 100644
index b317bef0041..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/certificate_view_pem_fuzzer.cc
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <sstream>
-#include <string>
-
-#include "quic/core/crypto/certificate_view.h"
-
-extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
- std::string input(reinterpret_cast<const char*>(data), size);
- std::stringstream stream(input);
-
- quic::CertificateView::LoadPemFromStream(&stream);
- stream.seekg(0);
- quic::CertificatePrivateKey::LoadPemFromStream(&stream);
- return 0;
-}
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/certificate_view_test.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/certificate_view_test.cc
deleted file mode 100644
index fbca9159c82..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/certificate_view_test.cc
+++ /dev/null
@@ -1,214 +0,0 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/crypto/certificate_view.h"
-
-#include <memory>
-#include <sstream>
-
-#include "absl/strings/escaping.h"
-#include "absl/strings/string_view.h"
-#include "third_party/boringssl/src/include/openssl/base.h"
-#include "third_party/boringssl/src/include/openssl/bytestring.h"
-#include "third_party/boringssl/src/include/openssl/evp.h"
-#include "third_party/boringssl/src/include/openssl/ssl.h"
-#include "quic/core/crypto/boring_utils.h"
-#include "quic/core/quic_time.h"
-#include "quic/platform/api/quic_ip_address.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/test_certificates.h"
-#include "common/platform/api/quiche_time_utils.h"
-
-namespace quic {
-namespace test {
-namespace {
-
-using ::testing::ElementsAre;
-using ::testing::HasSubstr;
-using ::testing::Optional;
-
-TEST(CertificateViewTest, PemParser) {
- std::stringstream stream(kTestCertificatePem);
- PemReadResult result = ReadNextPemMessage(&stream);
- EXPECT_EQ(result.status, PemReadResult::kOk);
- EXPECT_EQ(result.type, "CERTIFICATE");
- EXPECT_EQ(result.contents, kTestCertificate);
-
- result = ReadNextPemMessage(&stream);
- EXPECT_EQ(result.status, PemReadResult::kEof);
-}
-
-TEST(CertificateViewTest, Parse) {
- std::unique_ptr<CertificateView> view =
- CertificateView::ParseSingleCertificate(kTestCertificate);
- ASSERT_TRUE(view != nullptr);
-
- EXPECT_THAT(view->subject_alt_name_domains(),
- ElementsAre(absl::string_view("www.example.org"),
- absl::string_view("mail.example.org"),
- absl::string_view("mail.example.com")));
- EXPECT_THAT(view->subject_alt_name_ips(),
- ElementsAre(QuicIpAddress::Loopback4()));
- EXPECT_EQ(EVP_PKEY_id(view->public_key()), EVP_PKEY_RSA);
-
- const QuicWallTime validity_start = QuicWallTime::FromUNIXSeconds(
- *quiche::QuicheUtcDateTimeToUnixSeconds(2020, 1, 30, 18, 13, 59));
- EXPECT_EQ(view->validity_start(), validity_start);
- const QuicWallTime validity_end = QuicWallTime::FromUNIXSeconds(
- *quiche::QuicheUtcDateTimeToUnixSeconds(2020, 2, 2, 18, 13, 59));
- EXPECT_EQ(view->validity_end(), validity_end);
- EXPECT_EQ(view->public_key_type(), PublicKeyType::kRsa);
- EXPECT_EQ(PublicKeyTypeToString(view->public_key_type()), "RSA");
-
- EXPECT_EQ("C=US,ST=California,L=Mountain View,O=QUIC Server,CN=127.0.0.1",
- view->GetHumanReadableSubject());
-}
-
-TEST(CertificateViewTest, ParseCertWithUnknownSanType) {
- std::stringstream stream(kTestCertWithUnknownSanTypePem);
- PemReadResult result = ReadNextPemMessage(&stream);
- EXPECT_EQ(result.status, PemReadResult::kOk);
- EXPECT_EQ(result.type, "CERTIFICATE");
-
- std::unique_ptr<CertificateView> view =
- CertificateView::ParseSingleCertificate(result.contents);
- EXPECT_TRUE(view != nullptr);
-}
-
-TEST(CertificateViewTest, PemSingleCertificate) {
- std::stringstream pem_stream(kTestCertificatePem);
- std::vector<std::string> chain =
- CertificateView::LoadPemFromStream(&pem_stream);
- EXPECT_THAT(chain, ElementsAre(kTestCertificate));
-}
-
-TEST(CertificateViewTest, PemMultipleCertificates) {
- std::stringstream pem_stream(kTestCertificateChainPem);
- std::vector<std::string> chain =
- CertificateView::LoadPemFromStream(&pem_stream);
- EXPECT_THAT(chain,
- ElementsAre(kTestCertificate, HasSubstr("QUIC Server Root CA")));
-}
-
-TEST(CertificateViewTest, PemNoCertificates) {
- std::stringstream pem_stream("one\ntwo\nthree\n");
- std::vector<std::string> chain =
- CertificateView::LoadPemFromStream(&pem_stream);
- EXPECT_TRUE(chain.empty());
-}
-
-TEST(CertificateViewTest, SignAndVerify) {
- std::unique_ptr<CertificatePrivateKey> key =
- CertificatePrivateKey::LoadFromDer(kTestCertificatePrivateKey);
- ASSERT_TRUE(key != nullptr);
-
- std::string data = "A really important message";
- std::string signature = key->Sign(data, SSL_SIGN_RSA_PSS_RSAE_SHA256);
- ASSERT_FALSE(signature.empty());
-
- std::unique_ptr<CertificateView> view =
- CertificateView::ParseSingleCertificate(kTestCertificate);
- ASSERT_TRUE(view != nullptr);
- EXPECT_TRUE(key->MatchesPublicKey(*view));
-
- EXPECT_TRUE(
- view->VerifySignature(data, signature, SSL_SIGN_RSA_PSS_RSAE_SHA256));
- EXPECT_FALSE(view->VerifySignature("An unimportant message", signature,
- SSL_SIGN_RSA_PSS_RSAE_SHA256));
- EXPECT_FALSE(view->VerifySignature(data, "Not a signature",
- SSL_SIGN_RSA_PSS_RSAE_SHA256));
-}
-
-TEST(CertificateViewTest, PrivateKeyPem) {
- std::unique_ptr<CertificateView> view =
- CertificateView::ParseSingleCertificate(kTestCertificate);
- ASSERT_TRUE(view != nullptr);
-
- std::stringstream pem_stream(kTestCertificatePrivateKeyPem);
- std::unique_ptr<CertificatePrivateKey> pem_key =
- CertificatePrivateKey::LoadPemFromStream(&pem_stream);
- ASSERT_TRUE(pem_key != nullptr);
- EXPECT_TRUE(pem_key->MatchesPublicKey(*view));
-
- std::stringstream legacy_stream(kTestCertificatePrivateKeyLegacyPem);
- std::unique_ptr<CertificatePrivateKey> legacy_key =
- CertificatePrivateKey::LoadPemFromStream(&legacy_stream);
- ASSERT_TRUE(legacy_key != nullptr);
- EXPECT_TRUE(legacy_key->MatchesPublicKey(*view));
-}
-
-TEST(CertificateViewTest, PrivateKeyEcdsaPem) {
- std::stringstream pem_stream(kTestEcPrivateKeyLegacyPem);
- std::unique_ptr<CertificatePrivateKey> key =
- CertificatePrivateKey::LoadPemFromStream(&pem_stream);
- ASSERT_TRUE(key != nullptr);
- EXPECT_TRUE(key->ValidForSignatureAlgorithm(SSL_SIGN_ECDSA_SECP256R1_SHA256));
-}
-
-TEST(CertificateViewTest, DerTime) {
- EXPECT_THAT(ParseDerTime(CBS_ASN1_GENERALIZEDTIME, "19700101000024Z"),
- Optional(QuicWallTime::FromUNIXSeconds(24)));
- EXPECT_THAT(ParseDerTime(CBS_ASN1_GENERALIZEDTIME, "19710101000024Z"),
- Optional(QuicWallTime::FromUNIXSeconds(365 * 86400 + 24)));
- EXPECT_THAT(ParseDerTime(CBS_ASN1_UTCTIME, "700101000024Z"),
- Optional(QuicWallTime::FromUNIXSeconds(24)));
- EXPECT_TRUE(ParseDerTime(CBS_ASN1_UTCTIME, "200101000024Z").has_value());
-
- EXPECT_EQ(ParseDerTime(CBS_ASN1_GENERALIZEDTIME, ""), absl::nullopt);
- EXPECT_EQ(ParseDerTime(CBS_ASN1_GENERALIZEDTIME, "19700101000024.001Z"),
- absl::nullopt);
- EXPECT_EQ(ParseDerTime(CBS_ASN1_GENERALIZEDTIME, "19700101000024Q"),
- absl::nullopt);
- EXPECT_EQ(ParseDerTime(CBS_ASN1_GENERALIZEDTIME, "19700101000024-0500"),
- absl::nullopt);
- EXPECT_EQ(ParseDerTime(CBS_ASN1_GENERALIZEDTIME, "700101000024ZZ"),
- absl::nullopt);
- EXPECT_EQ(ParseDerTime(CBS_ASN1_GENERALIZEDTIME, "19700101000024.00Z"),
- absl::nullopt);
- EXPECT_EQ(ParseDerTime(CBS_ASN1_GENERALIZEDTIME, "19700101000024.Z"),
- absl::nullopt);
- EXPECT_EQ(ParseDerTime(CBS_ASN1_GENERALIZEDTIME, "197O0101000024Z"),
- absl::nullopt);
- EXPECT_EQ(ParseDerTime(CBS_ASN1_GENERALIZEDTIME, "19700101000024.0O1Z"),
- absl::nullopt);
- EXPECT_EQ(ParseDerTime(CBS_ASN1_GENERALIZEDTIME, "-9700101000024Z"),
- absl::nullopt);
- EXPECT_EQ(ParseDerTime(CBS_ASN1_GENERALIZEDTIME, "1970-101000024Z"),
- absl::nullopt);
-
- EXPECT_TRUE(ParseDerTime(CBS_ASN1_UTCTIME, "490101000024Z").has_value());
- // This should parse as 1950, which predates UNIX epoch.
- EXPECT_FALSE(ParseDerTime(CBS_ASN1_UTCTIME, "500101000024Z").has_value());
-
- EXPECT_THAT(ParseDerTime(CBS_ASN1_GENERALIZEDTIME, "19700101230000Z"),
- Optional(QuicWallTime::FromUNIXSeconds(23 * 3600)));
- EXPECT_EQ(ParseDerTime(CBS_ASN1_GENERALIZEDTIME, "19700101240000Z"),
- absl::nullopt);
-}
-
-TEST(CertificateViewTest, NameAttribute) {
- // OBJECT_IDENTIFIER { 1.2.840.113554.4.1.112411 }
- // UTF8String { "Test" }
- std::string unknown_oid =
- absl::HexStringToBytes("060b2a864886f712040186ee1b0c0454657374");
- EXPECT_EQ("1.2.840.113554.4.1.112411=Test",
- X509NameAttributeToString(StringPieceToCbs(unknown_oid)));
-
- // OBJECT_IDENTIFIER { 2.5.4.3 }
- // UTF8String { "Bell: \x07" }
- std::string non_printable =
- absl::HexStringToBytes("06035504030c0742656c6c3a2007");
- EXPECT_EQ(R"(CN=Bell: \x07)",
- X509NameAttributeToString(StringPieceToCbs(non_printable)));
-
- // OBJECT_IDENTIFIER { "\x55\x80" }
- // UTF8String { "Test" }
- std::string invalid_oid = absl::HexStringToBytes("060255800c0454657374");
- EXPECT_EQ("(5580)=Test",
- X509NameAttributeToString(StringPieceToCbs(invalid_oid)));
-}
-
-} // namespace
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/chacha20_poly1305_decrypter.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/chacha20_poly1305_decrypter.cc
deleted file mode 100644
index 8a4571b7da4..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/chacha20_poly1305_decrypter.cc
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/crypto/chacha20_poly1305_decrypter.h"
-
-#include "third_party/boringssl/src/include/openssl/aead.h"
-#include "third_party/boringssl/src/include/openssl/tls1.h"
-
-namespace quic {
-
-namespace {
-
-const size_t kKeySize = 32;
-const size_t kNonceSize = 12;
-
-} // namespace
-
-ChaCha20Poly1305Decrypter::ChaCha20Poly1305Decrypter()
- : ChaChaBaseDecrypter(EVP_aead_chacha20_poly1305,
- kKeySize,
- kAuthTagSize,
- kNonceSize,
- /* use_ietf_nonce_construction */ false) {
- static_assert(kKeySize <= kMaxKeySize, "key size too big");
- static_assert(kNonceSize <= kMaxNonceSize, "nonce size too big");
-}
-
-ChaCha20Poly1305Decrypter::~ChaCha20Poly1305Decrypter() {}
-
-uint32_t ChaCha20Poly1305Decrypter::cipher_id() const {
- return TLS1_CK_CHACHA20_POLY1305_SHA256;
-}
-
-QuicPacketCount ChaCha20Poly1305Decrypter::GetIntegrityLimit() const {
- // For AEAD_CHACHA20_POLY1305, the integrity limit is 2^36 invalid packets.
- // https://quicwg.org/base-drafts/draft-ietf-quic-tls.html#name-limits-on-aead-usage
- static_assert(kMaxIncomingPacketSize < 16384,
- "This key limit requires limits on decryption payload sizes");
- return 68719476736U;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/chacha20_poly1305_decrypter.h b/chromium/net/third_party/quiche/src/quic/core/crypto/chacha20_poly1305_decrypter.h
deleted file mode 100644
index f6af33d7902..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/chacha20_poly1305_decrypter.h
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_CRYPTO_CHACHA20_POLY1305_DECRYPTER_H_
-#define QUICHE_QUIC_CORE_CRYPTO_CHACHA20_POLY1305_DECRYPTER_H_
-
-#include <cstdint>
-
-#include "quic/core/crypto/chacha_base_decrypter.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// A ChaCha20Poly1305Decrypter is a QuicDecrypter that implements the
-// AEAD_CHACHA20_POLY1305 algorithm specified in RFC 7539, except that
-// it truncates the Poly1305 authenticator to 12 bytes. Create an instance
-// by calling QuicDecrypter::Create(kCC20).
-//
-// It uses an authentication tag of 12 bytes (96 bits). The fixed prefix of the
-// nonce is four bytes.
-class QUIC_EXPORT_PRIVATE ChaCha20Poly1305Decrypter
- : public ChaChaBaseDecrypter {
- public:
- enum {
- kAuthTagSize = 12,
- };
-
- ChaCha20Poly1305Decrypter();
- ChaCha20Poly1305Decrypter(const ChaCha20Poly1305Decrypter&) = delete;
- ChaCha20Poly1305Decrypter& operator=(const ChaCha20Poly1305Decrypter&) =
- delete;
- ~ChaCha20Poly1305Decrypter() override;
-
- uint32_t cipher_id() const override;
- QuicPacketCount GetIntegrityLimit() const override;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_CRYPTO_CHACHA20_POLY1305_DECRYPTER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/chacha20_poly1305_decrypter_test.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/chacha20_poly1305_decrypter_test.cc
deleted file mode 100644
index 93e48d257d0..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/chacha20_poly1305_decrypter_test.cc
+++ /dev/null
@@ -1,178 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/crypto/chacha20_poly1305_decrypter.h"
-
-#include <memory>
-#include <string>
-
-#include "absl/strings/escaping.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/quic_test_utils.h"
-#include "common/test_tools/quiche_test_utils.h"
-
-namespace {
-
-// The test vectors come from RFC 7539 Section 2.8.2.
-
-// Each test vector consists of six strings of lowercase hexadecimal digits.
-// The strings may be empty (zero length). A test vector with a nullptr |key|
-// marks the end of an array of test vectors.
-struct TestVector {
- // Input:
- const char* key;
- const char* iv;
- const char* fixed;
- const char* aad;
- const char* ct;
-
- // Expected output:
- const char* pt; // An empty string "" means decryption succeeded and
- // the plaintext is zero-length. nullptr means decryption
- // failed.
-};
-
-const TestVector test_vectors[] = {
- {"808182838485868788898a8b8c8d8e8f"
- "909192939495969798999a9b9c9d9e9f",
-
- "4041424344454647",
-
- "07000000",
-
- "50515253c0c1c2c3c4c5c6c7",
-
- "d31a8d34648e60db7b86afbc53ef7ec2"
- "a4aded51296e08fea9e2b5a736ee62d6"
- "3dbea45e8ca9671282fafb69da92728b"
- "1a71de0a9e060b2905d6a5b67ecd3b36"
- "92ddbd7f2d778b8c9803aee328091b58"
- "fab324e4fad675945585808b4831d7bc"
- "3ff4def08e4b7a9de576d26586cec64b"
- "6116"
- "1ae10b594f09e26a7e902ecb", // "d0600691" truncated
-
- "4c616469657320616e642047656e746c"
- "656d656e206f662074686520636c6173"
- "73206f66202739393a20496620492063"
- "6f756c64206f6666657220796f75206f"
- "6e6c79206f6e652074697020666f7220"
- "746865206675747572652c2073756e73"
- "637265656e20776f756c642062652069"
- "742e"},
- // Modify the ciphertext (Poly1305 authenticator).
- {"808182838485868788898a8b8c8d8e8f"
- "909192939495969798999a9b9c9d9e9f",
-
- "4041424344454647",
-
- "07000000",
-
- "50515253c0c1c2c3c4c5c6c7",
-
- "d31a8d34648e60db7b86afbc53ef7ec2"
- "a4aded51296e08fea9e2b5a736ee62d6"
- "3dbea45e8ca9671282fafb69da92728b"
- "1a71de0a9e060b2905d6a5b67ecd3b36"
- "92ddbd7f2d778b8c9803aee328091b58"
- "fab324e4fad675945585808b4831d7bc"
- "3ff4def08e4b7a9de576d26586cec64b"
- "6116"
- "1ae10b594f09e26a7e902ecc", // "d0600691" truncated
-
- nullptr},
- // Modify the associated data.
- {"808182838485868788898a8b8c8d8e8f"
- "909192939495969798999a9b9c9d9e9f",
-
- "4041424344454647",
-
- "07000000",
-
- "60515253c0c1c2c3c4c5c6c7",
-
- "d31a8d34648e60db7b86afbc53ef7ec2"
- "a4aded51296e08fea9e2b5a736ee62d6"
- "3dbea45e8ca9671282fafb69da92728b"
- "1a71de0a9e060b2905d6a5b67ecd3b36"
- "92ddbd7f2d778b8c9803aee328091b58"
- "fab324e4fad675945585808b4831d7bc"
- "3ff4def08e4b7a9de576d26586cec64b"
- "6116"
- "1ae10b594f09e26a7e902ecb", // "d0600691" truncated
-
- nullptr},
- {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
-
-} // namespace
-
-namespace quic {
-namespace test {
-
-// DecryptWithNonce wraps the |Decrypt| method of |decrypter| to allow passing
-// in an nonce and also to allocate the buffer needed for the plaintext.
-QuicData* DecryptWithNonce(ChaCha20Poly1305Decrypter* decrypter,
- absl::string_view nonce,
- absl::string_view associated_data,
- absl::string_view ciphertext) {
- uint64_t packet_number;
- absl::string_view nonce_prefix(nonce.data(),
- nonce.size() - sizeof(packet_number));
- decrypter->SetNoncePrefix(nonce_prefix);
- memcpy(&packet_number, nonce.data() + nonce_prefix.size(),
- sizeof(packet_number));
- std::unique_ptr<char[]> output(new char[ciphertext.length()]);
- size_t output_length = 0;
- const bool success = decrypter->DecryptPacket(
- packet_number, associated_data, ciphertext, output.get(), &output_length,
- ciphertext.length());
- if (!success) {
- return nullptr;
- }
- return new QuicData(output.release(), output_length, true);
-}
-
-class ChaCha20Poly1305DecrypterTest : public QuicTest {};
-
-TEST_F(ChaCha20Poly1305DecrypterTest, Decrypt) {
- for (size_t i = 0; test_vectors[i].key != nullptr; i++) {
- // If not present then decryption is expected to fail.
- bool has_pt = test_vectors[i].pt;
-
- // Decode the test vector.
- std::string key = absl::HexStringToBytes(test_vectors[i].key);
- std::string iv = absl::HexStringToBytes(test_vectors[i].iv);
- std::string fixed = absl::HexStringToBytes(test_vectors[i].fixed);
- std::string aad = absl::HexStringToBytes(test_vectors[i].aad);
- std::string ct = absl::HexStringToBytes(test_vectors[i].ct);
- std::string pt;
- if (has_pt) {
- pt = absl::HexStringToBytes(test_vectors[i].pt);
- }
-
- ChaCha20Poly1305Decrypter decrypter;
- ASSERT_TRUE(decrypter.SetKey(key));
- std::unique_ptr<QuicData> decrypted(DecryptWithNonce(
- &decrypter, fixed + iv,
- // This deliberately tests that the decrypter can handle an AAD that
- // is set to nullptr, as opposed to a zero-length, non-nullptr pointer.
- absl::string_view(aad.length() ? aad.data() : nullptr, aad.length()),
- ct));
- if (!decrypted) {
- EXPECT_FALSE(has_pt);
- continue;
- }
- EXPECT_TRUE(has_pt);
-
- EXPECT_EQ(12u, ct.size() - decrypted->length());
- ASSERT_EQ(pt.length(), decrypted->length());
- quiche::test::CompareCharArraysWithHexError(
- "plaintext", decrypted->data(), pt.length(), pt.data(), pt.length());
- }
-}
-
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/chacha20_poly1305_encrypter.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/chacha20_poly1305_encrypter.cc
deleted file mode 100644
index 09be04ff79f..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/chacha20_poly1305_encrypter.cc
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/crypto/chacha20_poly1305_encrypter.h"
-
-#include "third_party/boringssl/src/include/openssl/evp.h"
-
-namespace quic {
-
-namespace {
-
-const size_t kKeySize = 32;
-const size_t kNonceSize = 12;
-
-} // namespace
-
-ChaCha20Poly1305Encrypter::ChaCha20Poly1305Encrypter()
- : ChaChaBaseEncrypter(EVP_aead_chacha20_poly1305,
- kKeySize,
- kAuthTagSize,
- kNonceSize,
- /* use_ietf_nonce_construction */ false) {
- static_assert(kKeySize <= kMaxKeySize, "key size too big");
- static_assert(kNonceSize <= kMaxNonceSize, "nonce size too big");
-}
-
-ChaCha20Poly1305Encrypter::~ChaCha20Poly1305Encrypter() {}
-
-QuicPacketCount ChaCha20Poly1305Encrypter::GetConfidentialityLimit() const {
- // For AEAD_CHACHA20_POLY1305, the confidentiality limit is greater than the
- // number of possible packets (2^62) and so can be disregarded.
- // https://quicwg.org/base-drafts/draft-ietf-quic-tls.html#name-limits-on-aead-usage
- return std::numeric_limits<QuicPacketCount>::max();
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/chacha20_poly1305_encrypter.h b/chromium/net/third_party/quiche/src/quic/core/crypto/chacha20_poly1305_encrypter.h
deleted file mode 100644
index 3f58b592433..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/chacha20_poly1305_encrypter.h
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_CRYPTO_CHACHA20_POLY1305_ENCRYPTER_H_
-#define QUICHE_QUIC_CORE_CRYPTO_CHACHA20_POLY1305_ENCRYPTER_H_
-
-#include "quic/core/crypto/chacha_base_encrypter.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// A ChaCha20Poly1305Encrypter is a QuicEncrypter that implements the
-// AEAD_CHACHA20_POLY1305 algorithm specified in RFC 7539, except that
-// it truncates the Poly1305 authenticator to 12 bytes. Create an instance
-// by calling QuicEncrypter::Create(kCC20).
-//
-// It uses an authentication tag of 12 bytes (96 bits). The fixed prefix of the
-// nonce is four bytes.
-class QUIC_EXPORT_PRIVATE ChaCha20Poly1305Encrypter
- : public ChaChaBaseEncrypter {
- public:
- enum {
- kAuthTagSize = 12,
- };
-
- ChaCha20Poly1305Encrypter();
- ChaCha20Poly1305Encrypter(const ChaCha20Poly1305Encrypter&) = delete;
- ChaCha20Poly1305Encrypter& operator=(const ChaCha20Poly1305Encrypter&) =
- delete;
- ~ChaCha20Poly1305Encrypter() override;
-
- QuicPacketCount GetConfidentialityLimit() const override;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_CRYPTO_CHACHA20_POLY1305_ENCRYPTER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/chacha20_poly1305_encrypter_test.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/chacha20_poly1305_encrypter_test.cc
deleted file mode 100644
index 7fc32822f7e..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/chacha20_poly1305_encrypter_test.cc
+++ /dev/null
@@ -1,159 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/crypto/chacha20_poly1305_encrypter.h"
-
-#include <memory>
-#include <string>
-
-#include "absl/base/macros.h"
-#include "absl/strings/escaping.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/crypto/chacha20_poly1305_decrypter.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/quic_test_utils.h"
-#include "common/test_tools/quiche_test_utils.h"
-
-namespace {
-
-// The test vectors come from RFC 7539 Section 2.8.2.
-
-// Each test vector consists of five strings of lowercase hexadecimal digits.
-// The strings may be empty (zero length). A test vector with a nullptr |key|
-// marks the end of an array of test vectors.
-struct TestVector {
- const char* key;
- const char* pt;
- const char* iv;
- const char* fixed;
- const char* aad;
- const char* ct;
-};
-
-const TestVector test_vectors[] = {
- {
- "808182838485868788898a8b8c8d8e8f"
- "909192939495969798999a9b9c9d9e9f",
-
- "4c616469657320616e642047656e746c"
- "656d656e206f662074686520636c6173"
- "73206f66202739393a20496620492063"
- "6f756c64206f6666657220796f75206f"
- "6e6c79206f6e652074697020666f7220"
- "746865206675747572652c2073756e73"
- "637265656e20776f756c642062652069"
- "742e",
-
- "4041424344454647",
-
- "07000000",
-
- "50515253c0c1c2c3c4c5c6c7",
-
- "d31a8d34648e60db7b86afbc53ef7ec2"
- "a4aded51296e08fea9e2b5a736ee62d6"
- "3dbea45e8ca9671282fafb69da92728b"
- "1a71de0a9e060b2905d6a5b67ecd3b36"
- "92ddbd7f2d778b8c9803aee328091b58"
- "fab324e4fad675945585808b4831d7bc"
- "3ff4def08e4b7a9de576d26586cec64b"
- "6116"
- "1ae10b594f09e26a7e902ecb", // "d0600691" truncated
- },
- {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
-
-} // namespace
-
-namespace quic {
-namespace test {
-
-// EncryptWithNonce wraps the |Encrypt| method of |encrypter| to allow passing
-// in an nonce and also to allocate the buffer needed for the ciphertext.
-QuicData* EncryptWithNonce(ChaCha20Poly1305Encrypter* encrypter,
- absl::string_view nonce,
- absl::string_view associated_data,
- absl::string_view plaintext) {
- size_t ciphertext_size = encrypter->GetCiphertextSize(plaintext.length());
- std::unique_ptr<char[]> ciphertext(new char[ciphertext_size]);
-
- if (!encrypter->Encrypt(nonce, associated_data, plaintext,
- reinterpret_cast<unsigned char*>(ciphertext.get()))) {
- return nullptr;
- }
-
- return new QuicData(ciphertext.release(), ciphertext_size, true);
-}
-
-class ChaCha20Poly1305EncrypterTest : public QuicTest {};
-
-TEST_F(ChaCha20Poly1305EncrypterTest, EncryptThenDecrypt) {
- ChaCha20Poly1305Encrypter encrypter;
- ChaCha20Poly1305Decrypter decrypter;
-
- std::string key = absl::HexStringToBytes(test_vectors[0].key);
- ASSERT_TRUE(encrypter.SetKey(key));
- ASSERT_TRUE(decrypter.SetKey(key));
- ASSERT_TRUE(encrypter.SetNoncePrefix("abcd"));
- ASSERT_TRUE(decrypter.SetNoncePrefix("abcd"));
-
- uint64_t packet_number = UINT64_C(0x123456789ABC);
- std::string associated_data = "associated_data";
- std::string plaintext = "plaintext";
- char encrypted[1024];
- size_t len;
- ASSERT_TRUE(encrypter.EncryptPacket(packet_number, associated_data, plaintext,
- encrypted, &len,
- ABSL_ARRAYSIZE(encrypted)));
- absl::string_view ciphertext(encrypted, len);
- char decrypted[1024];
- ASSERT_TRUE(decrypter.DecryptPacket(packet_number, associated_data,
- ciphertext, decrypted, &len,
- ABSL_ARRAYSIZE(decrypted)));
-}
-
-TEST_F(ChaCha20Poly1305EncrypterTest, Encrypt) {
- for (size_t i = 0; test_vectors[i].key != nullptr; i++) {
- // Decode the test vector.
- std::string key = absl::HexStringToBytes(test_vectors[i].key);
- std::string pt = absl::HexStringToBytes(test_vectors[i].pt);
- std::string iv = absl::HexStringToBytes(test_vectors[i].iv);
- std::string fixed = absl::HexStringToBytes(test_vectors[i].fixed);
- std::string aad = absl::HexStringToBytes(test_vectors[i].aad);
- std::string ct = absl::HexStringToBytes(test_vectors[i].ct);
-
- ChaCha20Poly1305Encrypter encrypter;
- ASSERT_TRUE(encrypter.SetKey(key));
- std::unique_ptr<QuicData> encrypted(EncryptWithNonce(
- &encrypter, fixed + iv,
- // This deliberately tests that the encrypter can handle an AAD that
- // is set to nullptr, as opposed to a zero-length, non-nullptr pointer.
- absl::string_view(aad.length() ? aad.data() : nullptr, aad.length()),
- pt));
- ASSERT_TRUE(encrypted.get());
- EXPECT_EQ(12u, ct.size() - pt.size());
- EXPECT_EQ(12u, encrypted->length() - pt.size());
-
- quiche::test::CompareCharArraysWithHexError("ciphertext", encrypted->data(),
- encrypted->length(), ct.data(),
- ct.length());
- }
-}
-
-TEST_F(ChaCha20Poly1305EncrypterTest, GetMaxPlaintextSize) {
- ChaCha20Poly1305Encrypter encrypter;
- EXPECT_EQ(1000u, encrypter.GetMaxPlaintextSize(1012));
- EXPECT_EQ(100u, encrypter.GetMaxPlaintextSize(112));
- EXPECT_EQ(10u, encrypter.GetMaxPlaintextSize(22));
-}
-
-TEST_F(ChaCha20Poly1305EncrypterTest, GetCiphertextSize) {
- ChaCha20Poly1305Encrypter encrypter;
- EXPECT_EQ(1012u, encrypter.GetCiphertextSize(1000));
- EXPECT_EQ(112u, encrypter.GetCiphertextSize(100));
- EXPECT_EQ(22u, encrypter.GetCiphertextSize(10));
-}
-
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/chacha20_poly1305_tls_decrypter.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/chacha20_poly1305_tls_decrypter.cc
deleted file mode 100644
index 92cb1320f69..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/chacha20_poly1305_tls_decrypter.cc
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/crypto/chacha20_poly1305_tls_decrypter.h"
-
-#include "third_party/boringssl/src/include/openssl/aead.h"
-#include "third_party/boringssl/src/include/openssl/tls1.h"
-#include "quic/platform/api/quic_flag_utils.h"
-#include "quic/platform/api/quic_flags.h"
-
-namespace quic {
-
-namespace {
-
-const size_t kKeySize = 32;
-const size_t kNonceSize = 12;
-
-} // namespace
-
-ChaCha20Poly1305TlsDecrypter::ChaCha20Poly1305TlsDecrypter()
- : ChaChaBaseDecrypter(EVP_aead_chacha20_poly1305,
- kKeySize,
- kAuthTagSize,
- kNonceSize,
- /* use_ietf_nonce_construction */ true) {
- static_assert(kKeySize <= kMaxKeySize, "key size too big");
- static_assert(kNonceSize <= kMaxNonceSize, "nonce size too big");
-}
-
-ChaCha20Poly1305TlsDecrypter::~ChaCha20Poly1305TlsDecrypter() {}
-
-uint32_t ChaCha20Poly1305TlsDecrypter::cipher_id() const {
- return TLS1_CK_CHACHA20_POLY1305_SHA256;
-}
-
-QuicPacketCount ChaCha20Poly1305TlsDecrypter::GetIntegrityLimit() const {
- // For AEAD_CHACHA20_POLY1305, the integrity limit is 2^36 invalid packets.
- // https://quicwg.org/base-drafts/draft-ietf-quic-tls.html#name-limits-on-aead-usage
- static_assert(kMaxIncomingPacketSize < 16384,
- "This key limit requires limits on decryption payload sizes");
- return 68719476736U;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/chacha20_poly1305_tls_decrypter.h b/chromium/net/third_party/quiche/src/quic/core/crypto/chacha20_poly1305_tls_decrypter.h
deleted file mode 100644
index 69abd89f873..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/chacha20_poly1305_tls_decrypter.h
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_CRYPTO_CHACHA20_POLY1305_TLS_DECRYPTER_H_
-#define QUICHE_QUIC_CORE_CRYPTO_CHACHA20_POLY1305_TLS_DECRYPTER_H_
-
-#include <cstdint>
-
-#include "quic/core/crypto/chacha_base_decrypter.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// A ChaCha20Poly1305TlsDecrypter is a QuicDecrypter that implements the
-// AEAD_CHACHA20_POLY1305 algorithm specified in RFC 7539 for use in IETF QUIC.
-//
-// It uses an authentication tag of 16 bytes (128 bits). It uses a 12 bytes IV
-// that is XOR'd with the packet number to compute the nonce.
-class QUIC_EXPORT_PRIVATE ChaCha20Poly1305TlsDecrypter
- : public ChaChaBaseDecrypter {
- public:
- enum {
- kAuthTagSize = 16,
- };
-
- ChaCha20Poly1305TlsDecrypter();
- ChaCha20Poly1305TlsDecrypter(const ChaCha20Poly1305TlsDecrypter&) = delete;
- ChaCha20Poly1305TlsDecrypter& operator=(const ChaCha20Poly1305TlsDecrypter&) =
- delete;
- ~ChaCha20Poly1305TlsDecrypter() override;
-
- uint32_t cipher_id() const override;
- QuicPacketCount GetIntegrityLimit() const override;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_CRYPTO_CHACHA20_POLY1305_TLS_DECRYPTER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/chacha20_poly1305_tls_decrypter_test.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/chacha20_poly1305_tls_decrypter_test.cc
deleted file mode 100644
index b71bcf127f8..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/chacha20_poly1305_tls_decrypter_test.cc
+++ /dev/null
@@ -1,188 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/crypto/chacha20_poly1305_tls_decrypter.h"
-
-#include <memory>
-#include <string>
-
-#include "absl/strings/escaping.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/quic_test_utils.h"
-#include "common/test_tools/quiche_test_utils.h"
-
-namespace {
-
-// The test vectors come from RFC 7539 Section 2.8.2.
-
-// Each test vector consists of six strings of lowercase hexadecimal digits.
-// The strings may be empty (zero length). A test vector with a nullptr |key|
-// marks the end of an array of test vectors.
-struct TestVector {
- // Input:
- const char* key;
- const char* iv;
- const char* fixed;
- const char* aad;
- const char* ct;
-
- // Expected output:
- const char* pt; // An empty string "" means decryption succeeded and
- // the plaintext is zero-length. nullptr means decryption
- // failed.
-};
-
-const TestVector test_vectors[] = {
- {"808182838485868788898a8b8c8d8e8f"
- "909192939495969798999a9b9c9d9e9f",
-
- "4041424344454647",
-
- "07000000",
-
- "50515253c0c1c2c3c4c5c6c7",
-
- "d31a8d34648e60db7b86afbc53ef7ec2"
- "a4aded51296e08fea9e2b5a736ee62d6"
- "3dbea45e8ca9671282fafb69da92728b"
- "1a71de0a9e060b2905d6a5b67ecd3b36"
- "92ddbd7f2d778b8c9803aee328091b58"
- "fab324e4fad675945585808b4831d7bc"
- "3ff4def08e4b7a9de576d26586cec64b"
- "6116"
- "1ae10b594f09e26a7e902ecbd0600691",
-
- "4c616469657320616e642047656e746c"
- "656d656e206f662074686520636c6173"
- "73206f66202739393a20496620492063"
- "6f756c64206f6666657220796f75206f"
- "6e6c79206f6e652074697020666f7220"
- "746865206675747572652c2073756e73"
- "637265656e20776f756c642062652069"
- "742e"},
- // Modify the ciphertext (Poly1305 authenticator).
- {"808182838485868788898a8b8c8d8e8f"
- "909192939495969798999a9b9c9d9e9f",
-
- "4041424344454647",
-
- "07000000",
-
- "50515253c0c1c2c3c4c5c6c7",
-
- "d31a8d34648e60db7b86afbc53ef7ec2"
- "a4aded51296e08fea9e2b5a736ee62d6"
- "3dbea45e8ca9671282fafb69da92728b"
- "1a71de0a9e060b2905d6a5b67ecd3b36"
- "92ddbd7f2d778b8c9803aee328091b58"
- "fab324e4fad675945585808b4831d7bc"
- "3ff4def08e4b7a9de576d26586cec64b"
- "6116"
- "1ae10b594f09e26a7e902eccd0600691",
-
- nullptr},
- // Modify the associated data.
- {"808182838485868788898a8b8c8d8e8f"
- "909192939495969798999a9b9c9d9e9f",
-
- "4041424344454647",
-
- "07000000",
-
- "60515253c0c1c2c3c4c5c6c7",
-
- "d31a8d34648e60db7b86afbc53ef7ec2"
- "a4aded51296e08fea9e2b5a736ee62d6"
- "3dbea45e8ca9671282fafb69da92728b"
- "1a71de0a9e060b2905d6a5b67ecd3b36"
- "92ddbd7f2d778b8c9803aee328091b58"
- "fab324e4fad675945585808b4831d7bc"
- "3ff4def08e4b7a9de576d26586cec64b"
- "6116"
- "1ae10b594f09e26a7e902ecbd0600691",
-
- nullptr},
- {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
-
-} // namespace
-
-namespace quic {
-namespace test {
-
-// DecryptWithNonce wraps the |Decrypt| method of |decrypter| to allow passing
-// in an nonce and also to allocate the buffer needed for the plaintext.
-QuicData* DecryptWithNonce(ChaCha20Poly1305TlsDecrypter* decrypter,
- absl::string_view nonce,
- absl::string_view associated_data,
- absl::string_view ciphertext) {
- decrypter->SetIV(nonce);
- std::unique_ptr<char[]> output(new char[ciphertext.length()]);
- size_t output_length = 0;
- const bool success =
- decrypter->DecryptPacket(0, associated_data, ciphertext, output.get(),
- &output_length, ciphertext.length());
- if (!success) {
- return nullptr;
- }
- return new QuicData(output.release(), output_length, true);
-}
-
-class ChaCha20Poly1305TlsDecrypterTest : public QuicTest {};
-
-TEST_F(ChaCha20Poly1305TlsDecrypterTest, Decrypt) {
- for (size_t i = 0; test_vectors[i].key != nullptr; i++) {
- // If not present then decryption is expected to fail.
- bool has_pt = test_vectors[i].pt;
-
- // Decode the test vector.
- std::string key = absl::HexStringToBytes(test_vectors[i].key);
- std::string iv = absl::HexStringToBytes(test_vectors[i].iv);
- std::string fixed = absl::HexStringToBytes(test_vectors[i].fixed);
- std::string aad = absl::HexStringToBytes(test_vectors[i].aad);
- std::string ct = absl::HexStringToBytes(test_vectors[i].ct);
- std::string pt;
- if (has_pt) {
- pt = absl::HexStringToBytes(test_vectors[i].pt);
- }
-
- ChaCha20Poly1305TlsDecrypter decrypter;
- ASSERT_TRUE(decrypter.SetKey(key));
- std::unique_ptr<QuicData> decrypted(DecryptWithNonce(
- &decrypter, fixed + iv,
- // This deliberately tests that the decrypter can handle an AAD that
- // is set to nullptr, as opposed to a zero-length, non-nullptr pointer.
- absl::string_view(aad.length() ? aad.data() : nullptr, aad.length()),
- ct));
- if (!decrypted) {
- EXPECT_FALSE(has_pt);
- continue;
- }
- EXPECT_TRUE(has_pt);
-
- EXPECT_EQ(16u, ct.size() - decrypted->length());
- ASSERT_EQ(pt.length(), decrypted->length());
- quiche::test::CompareCharArraysWithHexError(
- "plaintext", decrypted->data(), pt.length(), pt.data(), pt.length());
- }
-}
-
-TEST_F(ChaCha20Poly1305TlsDecrypterTest, GenerateHeaderProtectionMask) {
- ChaCha20Poly1305TlsDecrypter decrypter;
- std::string key = absl::HexStringToBytes(
- "6a067f432787bd6034dd3f08f07fc9703a27e58c70e2d88d948b7f6489923cc7");
- std::string sample =
- absl::HexStringToBytes("1210d91cceb45c716b023f492c29e612");
- QuicDataReader sample_reader(sample.data(), sample.size());
- ASSERT_TRUE(decrypter.SetHeaderProtectionKey(key));
- std::string mask = decrypter.GenerateHeaderProtectionMask(&sample_reader);
- std::string expected_mask = absl::HexStringToBytes("1cc2cd98dc");
- quiche::test::CompareCharArraysWithHexError(
- "header protection mask", mask.data(), mask.size(), expected_mask.data(),
- expected_mask.size());
-}
-
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/chacha20_poly1305_tls_encrypter.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/chacha20_poly1305_tls_encrypter.cc
deleted file mode 100644
index bbcb332799c..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/chacha20_poly1305_tls_encrypter.cc
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/crypto/chacha20_poly1305_tls_encrypter.h"
-
-#include "third_party/boringssl/src/include/openssl/evp.h"
-
-namespace quic {
-
-namespace {
-
-const size_t kKeySize = 32;
-const size_t kNonceSize = 12;
-
-} // namespace
-
-ChaCha20Poly1305TlsEncrypter::ChaCha20Poly1305TlsEncrypter()
- : ChaChaBaseEncrypter(EVP_aead_chacha20_poly1305,
- kKeySize,
- kAuthTagSize,
- kNonceSize,
- /* use_ietf_nonce_construction */ true) {
- static_assert(kKeySize <= kMaxKeySize, "key size too big");
- static_assert(kNonceSize <= kMaxNonceSize, "nonce size too big");
-}
-
-ChaCha20Poly1305TlsEncrypter::~ChaCha20Poly1305TlsEncrypter() {}
-
-QuicPacketCount ChaCha20Poly1305TlsEncrypter::GetConfidentialityLimit() const {
- // For AEAD_CHACHA20_POLY1305, the confidentiality limit is greater than the
- // number of possible packets (2^62) and so can be disregarded.
- // https://quicwg.org/base-drafts/draft-ietf-quic-tls.html#name-limits-on-aead-usage
- return std::numeric_limits<QuicPacketCount>::max();
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/chacha20_poly1305_tls_encrypter.h b/chromium/net/third_party/quiche/src/quic/core/crypto/chacha20_poly1305_tls_encrypter.h
deleted file mode 100644
index 81a750fddb0..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/chacha20_poly1305_tls_encrypter.h
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_CRYPTO_CHACHA20_POLY1305_TLS_ENCRYPTER_H_
-#define QUICHE_QUIC_CORE_CRYPTO_CHACHA20_POLY1305_TLS_ENCRYPTER_H_
-
-#include "quic/core/crypto/chacha_base_encrypter.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// A ChaCha20Poly1305Encrypter is a QuicEncrypter that implements the
-// AEAD_CHACHA20_POLY1305 algorithm specified in RFC 7539 for use in IETF QUIC.
-//
-// It uses an authentication tag of 16 bytes (128 bits). It uses a 12 byte IV
-// that is XOR'd with the packet number to compute the nonce.
-class QUIC_EXPORT_PRIVATE ChaCha20Poly1305TlsEncrypter
- : public ChaChaBaseEncrypter {
- public:
- enum {
- kAuthTagSize = 16,
- };
-
- ChaCha20Poly1305TlsEncrypter();
- ChaCha20Poly1305TlsEncrypter(const ChaCha20Poly1305TlsEncrypter&) = delete;
- ChaCha20Poly1305TlsEncrypter& operator=(const ChaCha20Poly1305TlsEncrypter&) =
- delete;
- ~ChaCha20Poly1305TlsEncrypter() override;
-
- QuicPacketCount GetConfidentialityLimit() const override;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_CRYPTO_CHACHA20_POLY1305_TLS_ENCRYPTER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/chacha20_poly1305_tls_encrypter_test.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/chacha20_poly1305_tls_encrypter_test.cc
deleted file mode 100644
index 61aaac73d17..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/chacha20_poly1305_tls_encrypter_test.cc
+++ /dev/null
@@ -1,173 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/crypto/chacha20_poly1305_tls_encrypter.h"
-
-#include <memory>
-#include <string>
-
-#include "absl/base/macros.h"
-#include "absl/strings/escaping.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/crypto/chacha20_poly1305_tls_decrypter.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/quic_test_utils.h"
-#include "common/test_tools/quiche_test_utils.h"
-
-namespace {
-
-// The test vectors come from RFC 7539 Section 2.8.2.
-
-// Each test vector consists of five strings of lowercase hexadecimal digits.
-// The strings may be empty (zero length). A test vector with a nullptr |key|
-// marks the end of an array of test vectors.
-struct TestVector {
- const char* key;
- const char* pt;
- const char* iv;
- const char* fixed;
- const char* aad;
- const char* ct;
-};
-
-const TestVector test_vectors[] = {
- {
- "808182838485868788898a8b8c8d8e8f"
- "909192939495969798999a9b9c9d9e9f",
-
- "4c616469657320616e642047656e746c"
- "656d656e206f662074686520636c6173"
- "73206f66202739393a20496620492063"
- "6f756c64206f6666657220796f75206f"
- "6e6c79206f6e652074697020666f7220"
- "746865206675747572652c2073756e73"
- "637265656e20776f756c642062652069"
- "742e",
-
- "4041424344454647",
-
- "07000000",
-
- "50515253c0c1c2c3c4c5c6c7",
-
- "d31a8d34648e60db7b86afbc53ef7ec2"
- "a4aded51296e08fea9e2b5a736ee62d6"
- "3dbea45e8ca9671282fafb69da92728b"
- "1a71de0a9e060b2905d6a5b67ecd3b36"
- "92ddbd7f2d778b8c9803aee328091b58"
- "fab324e4fad675945585808b4831d7bc"
- "3ff4def08e4b7a9de576d26586cec64b"
- "6116"
- "1ae10b594f09e26a7e902ecbd0600691",
- },
- {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
-
-} // namespace
-
-namespace quic {
-namespace test {
-
-// EncryptWithNonce wraps the |Encrypt| method of |encrypter| to allow passing
-// in an nonce and also to allocate the buffer needed for the ciphertext.
-QuicData* EncryptWithNonce(ChaCha20Poly1305TlsEncrypter* encrypter,
- absl::string_view nonce,
- absl::string_view associated_data,
- absl::string_view plaintext) {
- size_t ciphertext_size = encrypter->GetCiphertextSize(plaintext.length());
- std::unique_ptr<char[]> ciphertext(new char[ciphertext_size]);
-
- if (!encrypter->Encrypt(nonce, associated_data, plaintext,
- reinterpret_cast<unsigned char*>(ciphertext.get()))) {
- return nullptr;
- }
-
- return new QuicData(ciphertext.release(), ciphertext_size, true);
-}
-
-class ChaCha20Poly1305TlsEncrypterTest : public QuicTest {};
-
-TEST_F(ChaCha20Poly1305TlsEncrypterTest, EncryptThenDecrypt) {
- ChaCha20Poly1305TlsEncrypter encrypter;
- ChaCha20Poly1305TlsDecrypter decrypter;
-
- std::string key = absl::HexStringToBytes(test_vectors[0].key);
- ASSERT_TRUE(encrypter.SetKey(key));
- ASSERT_TRUE(decrypter.SetKey(key));
- ASSERT_TRUE(encrypter.SetIV("abcdefghijkl"));
- ASSERT_TRUE(decrypter.SetIV("abcdefghijkl"));
-
- uint64_t packet_number = UINT64_C(0x123456789ABC);
- std::string associated_data = "associated_data";
- std::string plaintext = "plaintext";
- char encrypted[1024];
- size_t len;
- ASSERT_TRUE(encrypter.EncryptPacket(packet_number, associated_data, plaintext,
- encrypted, &len,
- ABSL_ARRAYSIZE(encrypted)));
- absl::string_view ciphertext(encrypted, len);
- char decrypted[1024];
- ASSERT_TRUE(decrypter.DecryptPacket(packet_number, associated_data,
- ciphertext, decrypted, &len,
- ABSL_ARRAYSIZE(decrypted)));
-}
-
-TEST_F(ChaCha20Poly1305TlsEncrypterTest, Encrypt) {
- for (size_t i = 0; test_vectors[i].key != nullptr; i++) {
- // Decode the test vector.
- std::string key = absl::HexStringToBytes(test_vectors[i].key);
- std::string pt = absl::HexStringToBytes(test_vectors[i].pt);
- std::string iv = absl::HexStringToBytes(test_vectors[i].iv);
- std::string fixed = absl::HexStringToBytes(test_vectors[i].fixed);
- std::string aad = absl::HexStringToBytes(test_vectors[i].aad);
- std::string ct = absl::HexStringToBytes(test_vectors[i].ct);
-
- ChaCha20Poly1305TlsEncrypter encrypter;
- ASSERT_TRUE(encrypter.SetKey(key));
- std::unique_ptr<QuicData> encrypted(EncryptWithNonce(
- &encrypter, fixed + iv,
- // This deliberately tests that the encrypter can handle an AAD that
- // is set to nullptr, as opposed to a zero-length, non-nullptr pointer.
- absl::string_view(aad.length() ? aad.data() : nullptr, aad.length()),
- pt));
- ASSERT_TRUE(encrypted.get());
- EXPECT_EQ(16u, ct.size() - pt.size());
- EXPECT_EQ(16u, encrypted->length() - pt.size());
-
- quiche::test::CompareCharArraysWithHexError("ciphertext", encrypted->data(),
- encrypted->length(), ct.data(),
- ct.length());
- }
-}
-
-TEST_F(ChaCha20Poly1305TlsEncrypterTest, GetMaxPlaintextSize) {
- ChaCha20Poly1305TlsEncrypter encrypter;
- EXPECT_EQ(1000u, encrypter.GetMaxPlaintextSize(1016));
- EXPECT_EQ(100u, encrypter.GetMaxPlaintextSize(116));
- EXPECT_EQ(10u, encrypter.GetMaxPlaintextSize(26));
-}
-
-TEST_F(ChaCha20Poly1305TlsEncrypterTest, GetCiphertextSize) {
- ChaCha20Poly1305TlsEncrypter encrypter;
- EXPECT_EQ(1016u, encrypter.GetCiphertextSize(1000));
- EXPECT_EQ(116u, encrypter.GetCiphertextSize(100));
- EXPECT_EQ(26u, encrypter.GetCiphertextSize(10));
-}
-
-TEST_F(ChaCha20Poly1305TlsEncrypterTest, GenerateHeaderProtectionMask) {
- ChaCha20Poly1305TlsEncrypter encrypter;
- std::string key = absl::HexStringToBytes(
- "6a067f432787bd6034dd3f08f07fc9703a27e58c70e2d88d948b7f6489923cc7");
- std::string sample =
- absl::HexStringToBytes("1210d91cceb45c716b023f492c29e612");
- ASSERT_TRUE(encrypter.SetHeaderProtectionKey(key));
- std::string mask = encrypter.GenerateHeaderProtectionMask(sample);
- std::string expected_mask = absl::HexStringToBytes("1cc2cd98dc");
- quiche::test::CompareCharArraysWithHexError(
- "header protection mask", mask.data(), mask.size(), expected_mask.data(),
- expected_mask.size());
-}
-
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/chacha_base_decrypter.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/chacha_base_decrypter.cc
deleted file mode 100644
index b1be3d6155f..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/chacha_base_decrypter.cc
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright (c) 2013 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 "quic/core/crypto/chacha_base_decrypter.h"
-
-#include <cstdint>
-
-#include "absl/base/macros.h"
-#include "absl/strings/string_view.h"
-#include "third_party/boringssl/src/include/openssl/chacha.h"
-#include "quic/core/quic_data_reader.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "common/quiche_endian.h"
-
-namespace quic {
-
-bool ChaChaBaseDecrypter::SetHeaderProtectionKey(absl::string_view key) {
- if (key.size() != GetKeySize()) {
- QUIC_BUG(quic_bug_10620_1) << "Invalid key size for header protection";
- return false;
- }
- memcpy(pne_key_, key.data(), key.size());
- return true;
-}
-
-std::string ChaChaBaseDecrypter::GenerateHeaderProtectionMask(
- QuicDataReader* sample_reader) {
- absl::string_view sample;
- if (!sample_reader->ReadStringPiece(&sample, 16)) {
- return std::string();
- }
- const uint8_t* nonce = reinterpret_cast<const uint8_t*>(sample.data()) + 4;
- uint32_t counter;
- QuicDataReader(sample.data(), 4, quiche::HOST_BYTE_ORDER)
- .ReadUInt32(&counter);
- const uint8_t zeroes[] = {0, 0, 0, 0, 0};
- std::string out(ABSL_ARRAYSIZE(zeroes), 0);
- CRYPTO_chacha_20(reinterpret_cast<uint8_t*>(const_cast<char*>(out.data())),
- zeroes, ABSL_ARRAYSIZE(zeroes), pne_key_, nonce, counter);
- return out;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/chacha_base_decrypter.h b/chromium/net/third_party/quiche/src/quic/core/crypto/chacha_base_decrypter.h
deleted file mode 100644
index 4348cacee7d..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/chacha_base_decrypter.h
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright (c) 2013 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_CRYPTO_CHACHA_BASE_DECRYPTER_H_
-#define QUICHE_QUIC_CORE_CRYPTO_CHACHA_BASE_DECRYPTER_H_
-
-#include <cstddef>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/crypto/aead_base_decrypter.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-class QUIC_EXPORT_PRIVATE ChaChaBaseDecrypter : public AeadBaseDecrypter {
- public:
- using AeadBaseDecrypter::AeadBaseDecrypter;
-
- bool SetHeaderProtectionKey(absl::string_view key) override;
- std::string GenerateHeaderProtectionMask(
- QuicDataReader* sample_reader) override;
-
- private:
- // The key used for packet number encryption.
- unsigned char pne_key_[kMaxKeySize];
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_CRYPTO_CHACHA_BASE_DECRYPTER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/chacha_base_encrypter.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/chacha_base_encrypter.cc
deleted file mode 100644
index 1dfe8e6193f..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/chacha_base_encrypter.cc
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright (c) 2013 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 "quic/core/crypto/chacha_base_encrypter.h"
-
-#include "absl/base/macros.h"
-#include "absl/strings/string_view.h"
-#include "third_party/boringssl/src/include/openssl/chacha.h"
-#include "quic/core/quic_data_reader.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "common/quiche_endian.h"
-
-namespace quic {
-
-bool ChaChaBaseEncrypter::SetHeaderProtectionKey(absl::string_view key) {
- if (key.size() != GetKeySize()) {
- QUIC_BUG(quic_bug_10656_1) << "Invalid key size for header protection";
- return false;
- }
- memcpy(pne_key_, key.data(), key.size());
- return true;
-}
-
-std::string ChaChaBaseEncrypter::GenerateHeaderProtectionMask(
- absl::string_view sample) {
- if (sample.size() != 16) {
- return std::string();
- }
- const uint8_t* nonce = reinterpret_cast<const uint8_t*>(sample.data()) + 4;
- uint32_t counter;
- QuicDataReader(sample.data(), 4, quiche::HOST_BYTE_ORDER)
- .ReadUInt32(&counter);
- const uint8_t zeroes[] = {0, 0, 0, 0, 0};
- std::string out(ABSL_ARRAYSIZE(zeroes), 0);
- CRYPTO_chacha_20(reinterpret_cast<uint8_t*>(const_cast<char*>(out.data())),
- zeroes, ABSL_ARRAYSIZE(zeroes), pne_key_, nonce, counter);
- return out;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/chacha_base_encrypter.h b/chromium/net/third_party/quiche/src/quic/core/crypto/chacha_base_encrypter.h
deleted file mode 100644
index 4b48963d0ac..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/chacha_base_encrypter.h
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright (c) 2013 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_CRYPTO_CHACHA_BASE_ENCRYPTER_H_
-#define QUICHE_QUIC_CORE_CRYPTO_CHACHA_BASE_ENCRYPTER_H_
-
-#include <cstddef>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/crypto/aead_base_encrypter.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-class QUIC_EXPORT_PRIVATE ChaChaBaseEncrypter : public AeadBaseEncrypter {
- public:
- using AeadBaseEncrypter::AeadBaseEncrypter;
-
- bool SetHeaderProtectionKey(absl::string_view key) override;
- std::string GenerateHeaderProtectionMask(absl::string_view sample) override;
-
- private:
- // The key used for packet number encryption.
- unsigned char pne_key_[kMaxKeySize];
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_CRYPTO_CHACHA_BASE_ENCRYPTER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/channel_id.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/channel_id.cc
deleted file mode 100644
index 2d6f825a481..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/channel_id.cc
+++ /dev/null
@@ -1,90 +0,0 @@
-// Copyright 2013 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 "quic/core/crypto/channel_id.h"
-
-#include <cstdint>
-
-#include "absl/strings/string_view.h"
-#include "third_party/boringssl/src/include/openssl/bn.h"
-#include "third_party/boringssl/src/include/openssl/ec.h"
-#include "third_party/boringssl/src/include/openssl/ecdsa.h"
-#include "third_party/boringssl/src/include/openssl/nid.h"
-#include "third_party/boringssl/src/include/openssl/sha.h"
-
-namespace quic {
-
-// static
-const char ChannelIDVerifier::kContextStr[] = "QUIC ChannelID";
-// static
-const char ChannelIDVerifier::kClientToServerStr[] = "client -> server";
-
-// static
-bool ChannelIDVerifier::Verify(absl::string_view key,
- absl::string_view signed_data,
- absl::string_view signature) {
- return VerifyRaw(key, signed_data, signature, true);
-}
-
-// static
-bool ChannelIDVerifier::VerifyRaw(absl::string_view key,
- absl::string_view signed_data,
- absl::string_view signature,
- bool is_channel_id_signature) {
- if (key.size() != 32 * 2 || signature.size() != 32 * 2) {
- return false;
- }
-
- bssl::UniquePtr<EC_GROUP> p256(
- EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1));
- if (p256.get() == nullptr) {
- return false;
- }
-
- bssl::UniquePtr<BIGNUM> x(BN_new()), y(BN_new()), r(BN_new()), s(BN_new());
-
- ECDSA_SIG sig;
- sig.r = r.get();
- sig.s = s.get();
-
- const uint8_t* key_bytes = reinterpret_cast<const uint8_t*>(key.data());
- const uint8_t* signature_bytes =
- reinterpret_cast<const uint8_t*>(signature.data());
-
- if (BN_bin2bn(key_bytes + 0, 32, x.get()) == nullptr ||
- BN_bin2bn(key_bytes + 32, 32, y.get()) == nullptr ||
- BN_bin2bn(signature_bytes + 0, 32, sig.r) == nullptr ||
- BN_bin2bn(signature_bytes + 32, 32, sig.s) == nullptr) {
- return false;
- }
-
- bssl::UniquePtr<EC_POINT> point(EC_POINT_new(p256.get()));
- if (point.get() == nullptr ||
- !EC_POINT_set_affine_coordinates_GFp(p256.get(), point.get(), x.get(),
- y.get(), nullptr)) {
- return false;
- }
-
- bssl::UniquePtr<EC_KEY> ecdsa_key(EC_KEY_new());
- if (ecdsa_key.get() == nullptr ||
- !EC_KEY_set_group(ecdsa_key.get(), p256.get()) ||
- !EC_KEY_set_public_key(ecdsa_key.get(), point.get())) {
- return false;
- }
-
- SHA256_CTX sha256;
- SHA256_Init(&sha256);
- if (is_channel_id_signature) {
- SHA256_Update(&sha256, kContextStr, strlen(kContextStr) + 1);
- SHA256_Update(&sha256, kClientToServerStr, strlen(kClientToServerStr) + 1);
- }
- SHA256_Update(&sha256, signed_data.data(), signed_data.size());
-
- unsigned char digest[SHA256_DIGEST_LENGTH];
- SHA256_Final(digest, &sha256);
-
- return ECDSA_do_verify(digest, sizeof(digest), &sig, ecdsa_key.get()) == 1;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/channel_id.h b/chromium/net/third_party/quiche/src/quic/core/crypto/channel_id.h
deleted file mode 100644
index 11759d23601..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/channel_id.h
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright 2013 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_CRYPTO_CHANNEL_ID_H_
-#define QUICHE_QUIC_CORE_CRYPTO_CHANNEL_ID_H_
-
-#include <memory>
-#include <string>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// ChannelIDVerifier verifies ChannelID signatures.
-class QUIC_EXPORT_PRIVATE ChannelIDVerifier {
- public:
- ChannelIDVerifier() = delete;
-
- // kContextStr is prepended to the data to be signed in order to ensure that
- // a ChannelID signature cannot be used in a different context. (The
- // terminating NUL byte is inclued.)
- static const char kContextStr[];
- // kClientToServerStr follows kContextStr to specify that the ChannelID is
- // being used in the client to server direction. (The terminating NUL byte is
- // included.)
- static const char kClientToServerStr[];
-
- // Verify returns true iff |signature| is a valid signature of |signed_data|
- // by |key|.
- static bool Verify(absl::string_view key,
- absl::string_view signed_data,
- absl::string_view signature);
-
- // FOR TESTING ONLY: VerifyRaw returns true iff |signature| is a valid
- // signature of |signed_data| by |key|. |is_channel_id_signature| indicates
- // whether |signature| is a ChannelID signature (with kContextStr prepended
- // to the data to be signed).
- static bool VerifyRaw(absl::string_view key,
- absl::string_view signed_data,
- absl::string_view signature,
- bool is_channel_id_signature);
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_CRYPTO_CHANNEL_ID_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/channel_id_test.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/channel_id_test.cc
deleted file mode 100644
index cf89fe5d891..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/channel_id_test.cc
+++ /dev/null
@@ -1,287 +0,0 @@
-// Copyright 2013 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 "quic/core/crypto/channel_id.h"
-
-#include <memory>
-#include <string>
-
-#include "absl/strings/string_view.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/crypto_test_utils.h"
-
-namespace quic {
-namespace test {
-
-namespace {
-
-// The following ECDSA signature verification test vectors for P-256,SHA-256
-// come from the SigVer.rsp file in
-// http://csrc.nist.gov/groups/STM/cavp/documents/dss/186-3ecdsatestvectors.zip
-// downloaded on 2013-06-11.
-struct TestVector {
- // Input:
- const char* msg;
- const char* qx;
- const char* qy;
- const char* r;
- const char* s;
-
- // Expected output:
- bool result; // true means "P", false means "F"
-};
-
-const TestVector test_vector[] = {
- {
- "e4796db5f785f207aa30d311693b3702821dff1168fd2e04c0836825aefd850d"
- "9aa60326d88cde1a23c7745351392ca2288d632c264f197d05cd424a30336c19"
- "fd09bb229654f0222fcb881a4b35c290a093ac159ce13409111ff0358411133c"
- "24f5b8e2090d6db6558afc36f06ca1f6ef779785adba68db27a409859fc4c4a0",
- "87f8f2b218f49845f6f10eec3877136269f5c1a54736dbdf69f89940cad41555",
- "e15f369036f49842fac7a86c8a2b0557609776814448b8f5e84aa9f4395205e9",
- "d19ff48b324915576416097d2544f7cbdf8768b1454ad20e0baac50e211f23b0",
- "a3e81e59311cdfff2d4784949f7a2cb50ba6c3a91fa54710568e61aca3e847c6",
- false // F (3 - S changed)
- },
- {
- "069a6e6b93dfee6df6ef6997cd80dd2182c36653cef10c655d524585655462d6"
- "83877f95ecc6d6c81623d8fac4e900ed0019964094e7de91f1481989ae187300"
- "4565789cbf5dc56c62aedc63f62f3b894c9c6f7788c8ecaadc9bd0e81ad91b2b"
- "3569ea12260e93924fdddd3972af5273198f5efda0746219475017557616170e",
- "5cf02a00d205bdfee2016f7421807fc38ae69e6b7ccd064ee689fc1a94a9f7d2",
- "ec530ce3cc5c9d1af463f264d685afe2b4db4b5828d7e61b748930f3ce622a85",
- "dc23d130c6117fb5751201455e99f36f59aba1a6a21cf2d0e7481a97451d6693",
- "d6ce7708c18dbf35d4f8aa7240922dc6823f2e7058cbc1484fcad1599db5018c",
- false // F (2 - R changed)
- },
- {
- "df04a346cf4d0e331a6db78cca2d456d31b0a000aa51441defdb97bbeb20b94d"
- "8d746429a393ba88840d661615e07def615a342abedfa4ce912e562af7149598"
- "96858af817317a840dcff85a057bb91a3c2bf90105500362754a6dd321cdd861"
- "28cfc5f04667b57aa78c112411e42da304f1012d48cd6a7052d7de44ebcc01de",
- "2ddfd145767883ffbb0ac003ab4a44346d08fa2570b3120dcce94562422244cb",
- "5f70c7d11ac2b7a435ccfbbae02c3df1ea6b532cc0e9db74f93fffca7c6f9a64",
- "9913111cff6f20c5bf453a99cd2c2019a4e749a49724a08774d14e4c113edda8",
- "9467cd4cd21ecb56b0cab0a9a453b43386845459127a952421f5c6382866c5cc",
- false // F (4 - Q changed)
- },
- {
- "e1130af6a38ccb412a9c8d13e15dbfc9e69a16385af3c3f1e5da954fd5e7c45f"
- "d75e2b8c36699228e92840c0562fbf3772f07e17f1add56588dd45f7450e1217"
- "ad239922dd9c32695dc71ff2424ca0dec1321aa47064a044b7fe3c2b97d03ce4"
- "70a592304c5ef21eed9f93da56bb232d1eeb0035f9bf0dfafdcc4606272b20a3",
- "e424dc61d4bb3cb7ef4344a7f8957a0c5134e16f7a67c074f82e6e12f49abf3c",
- "970eed7aa2bc48651545949de1dddaf0127e5965ac85d1243d6f60e7dfaee927",
- "bf96b99aa49c705c910be33142017c642ff540c76349b9dab72f981fd9347f4f",
- "17c55095819089c2e03b9cd415abdf12444e323075d98f31920b9e0f57ec871c",
- true // P (0 )
- },
- {
- "73c5f6a67456ae48209b5f85d1e7de7758bf235300c6ae2bdceb1dcb27a7730f"
- "b68c950b7fcada0ecc4661d3578230f225a875e69aaa17f1e71c6be5c831f226"
- "63bac63d0c7a9635edb0043ff8c6f26470f02a7bc56556f1437f06dfa27b487a"
- "6c4290d8bad38d4879b334e341ba092dde4e4ae694a9c09302e2dbf443581c08",
- "e0fc6a6f50e1c57475673ee54e3a57f9a49f3328e743bf52f335e3eeaa3d2864",
- "7f59d689c91e463607d9194d99faf316e25432870816dde63f5d4b373f12f22a",
- "1d75830cd36f4c9aa181b2c4221e87f176b7f05b7c87824e82e396c88315c407",
- "cb2acb01dac96efc53a32d4a0d85d0c2e48955214783ecf50a4f0414a319c05a",
- true // P (0 )
- },
- {
- "666036d9b4a2426ed6585a4e0fd931a8761451d29ab04bd7dc6d0c5b9e38e6c2"
- "b263ff6cb837bd04399de3d757c6c7005f6d7a987063cf6d7e8cb38a4bf0d74a"
- "282572bd01d0f41e3fd066e3021575f0fa04f27b700d5b7ddddf50965993c3f9"
- "c7118ed78888da7cb221849b3260592b8e632d7c51e935a0ceae15207bedd548",
- "a849bef575cac3c6920fbce675c3b787136209f855de19ffe2e8d29b31a5ad86",
- "bf5fe4f7858f9b805bd8dcc05ad5e7fb889de2f822f3d8b41694e6c55c16b471",
- "25acc3aa9d9e84c7abf08f73fa4195acc506491d6fc37cb9074528a7db87b9d6",
- "9b21d5b5259ed3f2ef07dfec6cc90d3a37855d1ce122a85ba6a333f307d31537",
- false // F (2 - R changed)
- },
- {
- "7e80436bce57339ce8da1b5660149a20240b146d108deef3ec5da4ae256f8f89"
- "4edcbbc57b34ce37089c0daa17f0c46cd82b5a1599314fd79d2fd2f446bd5a25"
- "b8e32fcf05b76d644573a6df4ad1dfea707b479d97237a346f1ec632ea5660ef"
- "b57e8717a8628d7f82af50a4e84b11f21bdff6839196a880ae20b2a0918d58cd",
- "3dfb6f40f2471b29b77fdccba72d37c21bba019efa40c1c8f91ec405d7dcc5df",
- "f22f953f1e395a52ead7f3ae3fc47451b438117b1e04d613bc8555b7d6e6d1bb",
- "548886278e5ec26bed811dbb72db1e154b6f17be70deb1b210107decb1ec2a5a",
- "e93bfebd2f14f3d827ca32b464be6e69187f5edbd52def4f96599c37d58eee75",
- false // F (4 - Q changed)
- },
- {
- "1669bfb657fdc62c3ddd63269787fc1c969f1850fb04c933dda063ef74a56ce1"
- "3e3a649700820f0061efabf849a85d474326c8a541d99830eea8131eaea584f2"
- "2d88c353965dabcdc4bf6b55949fd529507dfb803ab6b480cd73ca0ba00ca19c"
- "438849e2cea262a1c57d8f81cd257fb58e19dec7904da97d8386e87b84948169",
- "69b7667056e1e11d6caf6e45643f8b21e7a4bebda463c7fdbc13bc98efbd0214",
- "d3f9b12eb46c7c6fda0da3fc85bc1fd831557f9abc902a3be3cb3e8be7d1aa2f",
- "288f7a1cd391842cce21f00e6f15471c04dc182fe4b14d92dc18910879799790",
- "247b3c4e89a3bcadfea73c7bfd361def43715fa382b8c3edf4ae15d6e55e9979",
- false // F (1 - Message changed)
- },
- {
- "3fe60dd9ad6caccf5a6f583b3ae65953563446c4510b70da115ffaa0ba04c076"
- "115c7043ab8733403cd69c7d14c212c655c07b43a7c71b9a4cffe22c2684788e"
- "c6870dc2013f269172c822256f9e7cc674791bf2d8486c0f5684283e1649576e"
- "fc982ede17c7b74b214754d70402fb4bb45ad086cf2cf76b3d63f7fce39ac970",
- "bf02cbcf6d8cc26e91766d8af0b164fc5968535e84c158eb3bc4e2d79c3cc682",
- "069ba6cb06b49d60812066afa16ecf7b51352f2c03bd93ec220822b1f3dfba03",
- "f5acb06c59c2b4927fb852faa07faf4b1852bbb5d06840935e849c4d293d1bad",
- "049dab79c89cc02f1484c437f523e080a75f134917fda752f2d5ca397addfe5d",
- false // F (3 - S changed)
- },
- {
- "983a71b9994d95e876d84d28946a041f8f0a3f544cfcc055496580f1dfd4e312"
- "a2ad418fe69dbc61db230cc0c0ed97e360abab7d6ff4b81ee970a7e97466acfd"
- "9644f828ffec538abc383d0e92326d1c88c55e1f46a668a039beaa1be631a891"
- "29938c00a81a3ae46d4aecbf9707f764dbaccea3ef7665e4c4307fa0b0a3075c",
- "224a4d65b958f6d6afb2904863efd2a734b31798884801fcab5a590f4d6da9de",
- "178d51fddada62806f097aa615d33b8f2404e6b1479f5fd4859d595734d6d2b9",
- "87b93ee2fecfda54deb8dff8e426f3c72c8864991f8ec2b3205bb3b416de93d2",
- "4044a24df85be0cc76f21a4430b75b8e77b932a87f51e4eccbc45c263ebf8f66",
- false // F (2 - R changed)
- },
- {
- "4a8c071ac4fd0d52faa407b0fe5dab759f7394a5832127f2a3498f34aac28733"
- "9e043b4ffa79528faf199dc917f7b066ad65505dab0e11e6948515052ce20cfd"
- "b892ffb8aa9bf3f1aa5be30a5bbe85823bddf70b39fd7ebd4a93a2f75472c1d4"
- "f606247a9821f1a8c45a6cb80545de2e0c6c0174e2392088c754e9c8443eb5af",
- "43691c7795a57ead8c5c68536fe934538d46f12889680a9cb6d055a066228369",
- "f8790110b3c3b281aa1eae037d4f1234aff587d903d93ba3af225c27ddc9ccac",
- "8acd62e8c262fa50dd9840480969f4ef70f218ebf8ef9584f199031132c6b1ce",
- "cfca7ed3d4347fb2a29e526b43c348ae1ce6c60d44f3191b6d8ea3a2d9c92154",
- false // F (3 - S changed)
- },
- {
- "0a3a12c3084c865daf1d302c78215d39bfe0b8bf28272b3c0b74beb4b7409db0"
- "718239de700785581514321c6440a4bbaea4c76fa47401e151e68cb6c29017f0"
- "bce4631290af5ea5e2bf3ed742ae110b04ade83a5dbd7358f29a85938e23d87a"
- "c8233072b79c94670ff0959f9c7f4517862ff829452096c78f5f2e9a7e4e9216",
- "9157dbfcf8cf385f5bb1568ad5c6e2a8652ba6dfc63bc1753edf5268cb7eb596",
- "972570f4313d47fc96f7c02d5594d77d46f91e949808825b3d31f029e8296405",
- "dfaea6f297fa320b707866125c2a7d5d515b51a503bee817de9faa343cc48eeb",
- "8f780ad713f9c3e5a4f7fa4c519833dfefc6a7432389b1e4af463961f09764f2",
- false // F (1 - Message changed)
- },
- {
- "785d07a3c54f63dca11f5d1a5f496ee2c2f9288e55007e666c78b007d95cc285"
- "81dce51f490b30fa73dc9e2d45d075d7e3a95fb8a9e1465ad191904124160b7c"
- "60fa720ef4ef1c5d2998f40570ae2a870ef3e894c2bc617d8a1dc85c3c557749"
- "28c38789b4e661349d3f84d2441a3b856a76949b9f1f80bc161648a1cad5588e",
- "072b10c081a4c1713a294f248aef850e297991aca47fa96a7470abe3b8acfdda",
- "9581145cca04a0fb94cedce752c8f0370861916d2a94e7c647c5373ce6a4c8f5",
- "09f5483eccec80f9d104815a1be9cc1a8e5b12b6eb482a65c6907b7480cf4f19",
- "a4f90e560c5e4eb8696cb276e5165b6a9d486345dedfb094a76e8442d026378d",
- false // F (4 - Q changed)
- },
- {
- "76f987ec5448dd72219bd30bf6b66b0775c80b394851a43ff1f537f140a6e722"
- "9ef8cd72ad58b1d2d20298539d6347dd5598812bc65323aceaf05228f738b5ad"
- "3e8d9fe4100fd767c2f098c77cb99c2992843ba3eed91d32444f3b6db6cd212d"
- "d4e5609548f4bb62812a920f6e2bf1581be1ebeebdd06ec4e971862cc42055ca",
- "09308ea5bfad6e5adf408634b3d5ce9240d35442f7fe116452aaec0d25be8c24",
- "f40c93e023ef494b1c3079b2d10ef67f3170740495ce2cc57f8ee4b0618b8ee5",
- "5cc8aa7c35743ec0c23dde88dabd5e4fcd0192d2116f6926fef788cddb754e73",
- "9c9c045ebaa1b828c32f82ace0d18daebf5e156eb7cbfdc1eff4399a8a900ae7",
- false // F (1 - Message changed)
- },
- {
- "60cd64b2cd2be6c33859b94875120361a24085f3765cb8b2bf11e026fa9d8855"
- "dbe435acf7882e84f3c7857f96e2baab4d9afe4588e4a82e17a78827bfdb5ddb"
- "d1c211fbc2e6d884cddd7cb9d90d5bf4a7311b83f352508033812c776a0e00c0"
- "03c7e0d628e50736c7512df0acfa9f2320bd102229f46495ae6d0857cc452a84",
- "2d98ea01f754d34bbc3003df5050200abf445ec728556d7ed7d5c54c55552b6d",
- "9b52672742d637a32add056dfd6d8792f2a33c2e69dafabea09b960bc61e230a",
- "06108e525f845d0155bf60193222b3219c98e3d49424c2fb2a0987f825c17959",
- "62b5cdd591e5b507e560167ba8f6f7cda74673eb315680cb89ccbc4eec477dce",
- true // P (0 )
- },
- {nullptr, nullptr, nullptr, nullptr, nullptr, false}};
-
-// Returns true if |ch| is a lowercase hexadecimal digit.
-bool IsHexDigit(char ch) {
- return ('0' <= ch && ch <= '9') || ('a' <= ch && ch <= 'f');
-}
-
-// Converts a lowercase hexadecimal digit to its integer value.
-int HexDigitToInt(char ch) {
- if ('0' <= ch && ch <= '9') {
- return ch - '0';
- }
- return ch - 'a' + 10;
-}
-
-// |in| is a string consisting of lowercase hexadecimal digits, where
-// every two digits represent one byte. |out| is a buffer of size |max_len|.
-// Converts |in| to bytes and stores the bytes in the |out| buffer. The
-// number of bytes converted is returned in |*out_len|. Returns true on
-// success, false on failure.
-bool DecodeHexString(const char* in,
- char* out,
- size_t* out_len,
- size_t max_len) {
- if (!in) {
- *out_len = static_cast<size_t>(-1);
- return true;
- }
- *out_len = 0;
- while (*in != '\0') {
- if (!IsHexDigit(*in) || !IsHexDigit(*(in + 1))) {
- return false;
- }
- if (*out_len >= max_len) {
- return false;
- }
- out[*out_len] = HexDigitToInt(*in) * 16 + HexDigitToInt(*(in + 1));
- (*out_len)++;
- in += 2;
- }
- return true;
-}
-
-} // namespace
-
-class ChannelIDTest : public QuicTest {};
-
-// A known answer test for ChannelIDVerifier.
-TEST_F(ChannelIDTest, VerifyKnownAnswerTest) {
- char msg[1024];
- size_t msg_len;
- char key[64];
- size_t qx_len;
- size_t qy_len;
- char signature[64];
- size_t r_len;
- size_t s_len;
-
- for (size_t i = 0; test_vector[i].msg != nullptr; i++) {
- SCOPED_TRACE(i);
- // Decode the test vector.
- ASSERT_TRUE(
- DecodeHexString(test_vector[i].msg, msg, &msg_len, sizeof(msg)));
- ASSERT_TRUE(DecodeHexString(test_vector[i].qx, key, &qx_len, sizeof(key)));
- ASSERT_TRUE(DecodeHexString(test_vector[i].qy, key + qx_len, &qy_len,
- sizeof(key) - qx_len));
- ASSERT_TRUE(DecodeHexString(test_vector[i].r, signature, &r_len,
- sizeof(signature)));
- ASSERT_TRUE(DecodeHexString(test_vector[i].s, signature + r_len, &s_len,
- sizeof(signature) - r_len));
-
- // The test vector's lengths should look sane.
- EXPECT_EQ(sizeof(key) / 2, qx_len);
- EXPECT_EQ(sizeof(key) / 2, qy_len);
- EXPECT_EQ(sizeof(signature) / 2, r_len);
- EXPECT_EQ(sizeof(signature) / 2, s_len);
-
- EXPECT_EQ(test_vector[i].result,
- ChannelIDVerifier::VerifyRaw(
- absl::string_view(key, sizeof(key)),
- absl::string_view(msg, msg_len),
- absl::string_view(signature, sizeof(signature)), false));
- }
-}
-
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/client_proof_source.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/client_proof_source.cc
deleted file mode 100644
index 4e4d44238b3..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/client_proof_source.cc
+++ /dev/null
@@ -1,62 +0,0 @@
-// Copyright (c) 2021 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 "quic/core/crypto/client_proof_source.h"
-
-#include "absl/strings/match.h"
-
-namespace quic {
-
-bool DefaultClientProofSource::AddCertAndKey(
- std::vector<std::string> server_hostnames,
- QuicReferenceCountedPointer<Chain> chain,
- CertificatePrivateKey private_key) {
- if (!ValidateCertAndKey(chain, private_key)) {
- return false;
- }
-
- auto cert_and_key =
- std::make_shared<CertAndKey>(std::move(chain), std::move(private_key));
- for (const std::string& domain : server_hostnames) {
- cert_and_keys_[domain] = cert_and_key;
- }
- return true;
-}
-
-const ClientProofSource::CertAndKey* DefaultClientProofSource::GetCertAndKey(
- absl::string_view hostname) const {
- const CertAndKey* result = LookupExact(hostname);
- if (result != nullptr || hostname == "*") {
- return result;
- }
-
- // Either a full or a wildcard domain lookup failed. In the former case,
- // derive the wildcard domain and look it up.
- if (hostname.size() > 1 && !absl::StartsWith(hostname, "*.")) {
- auto dot_pos = hostname.find('.');
- if (dot_pos != std::string::npos) {
- std::string wildcard = absl::StrCat("*", hostname.substr(dot_pos));
- const CertAndKey* result = LookupExact(wildcard);
- if (result != nullptr) {
- return result;
- }
- }
- }
-
- // Return default cert, if any.
- return LookupExact("*");
-}
-
-const ClientProofSource::CertAndKey* DefaultClientProofSource::LookupExact(
- absl::string_view map_key) const {
- const auto it = cert_and_keys_.find(map_key);
- QUIC_DVLOG(1) << "LookupExact(" << map_key
- << ") found:" << (it != cert_and_keys_.end());
- if (it != cert_and_keys_.end()) {
- return it->second.get();
- }
- return nullptr;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/client_proof_source.h b/chromium/net/third_party/quiche/src/quic/core/crypto/client_proof_source.h
deleted file mode 100644
index d1ab26c2ef3..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/client_proof_source.h
+++ /dev/null
@@ -1,70 +0,0 @@
-// Copyright (c) 2021 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_CRYPTO_CLIENT_PROOF_SOURCE_H_
-#define QUICHE_QUIC_CORE_CRYPTO_CLIENT_PROOF_SOURCE_H_
-
-#include <memory>
-
-#include "absl/container/flat_hash_map.h"
-#include "quic/core/crypto/certificate_view.h"
-#include "quic/core/crypto/proof_source.h"
-
-namespace quic {
-
-// ClientProofSource is the interface for a QUIC client to provide client certs
-// and keys based on server hostname. It is only used by TLS handshakes.
-class QUIC_EXPORT_PRIVATE ClientProofSource {
- public:
- using Chain = ProofSource::Chain;
-
- virtual ~ClientProofSource() {}
-
- struct QUIC_EXPORT_PRIVATE CertAndKey {
- CertAndKey(QuicReferenceCountedPointer<Chain> chain,
- CertificatePrivateKey private_key)
- : chain(std::move(chain)), private_key(std::move(private_key)) {}
-
- QuicReferenceCountedPointer<Chain> chain;
- CertificatePrivateKey private_key;
- };
-
- // Get the client certificate to be sent to the server with |server_hostname|
- // and its corresponding private key. It returns nullptr if the cert and key
- // can not be found.
- //
- // |server_hostname| is typically a full domain name(www.foo.com), but it
- // could also be a wildcard domain(*.foo.com), or a "*" which will return the
- // default cert.
- virtual const CertAndKey* GetCertAndKey(
- absl::string_view server_hostname) const = 0;
-};
-
-// DefaultClientProofSource is an implementation that simply keeps an in memory
-// map of server hostnames to certs.
-class QUIC_EXPORT_PRIVATE DefaultClientProofSource : public ClientProofSource {
- public:
- ~DefaultClientProofSource() override {}
-
- // Associate all hostnames in |server_hostnames| with {|chain|,|private_key|}.
- // Elements of |server_hostnames| can be full domain names(www.foo.com),
- // wildcard domains(*.foo.com), or "*" which means the given cert chain is the
- // default one.
- // If any element of |server_hostnames| is already associated with a cert
- // chain, it will be updated to be associated with the new cert chain.
- bool AddCertAndKey(std::vector<std::string> server_hostnames,
- QuicReferenceCountedPointer<Chain> chain,
- CertificatePrivateKey private_key);
-
- // ClientProofSource implementation
- const CertAndKey* GetCertAndKey(absl::string_view hostname) const override;
-
- private:
- const CertAndKey* LookupExact(absl::string_view map_key) const;
- absl::flat_hash_map<std::string, std::shared_ptr<CertAndKey>> cert_and_keys_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_CRYPTO_CLIENT_PROOF_SOURCE_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/client_proof_source_test.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/client_proof_source_test.cc
deleted file mode 100644
index 08f5b76e7b6..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/client_proof_source_test.cc
+++ /dev/null
@@ -1,212 +0,0 @@
-// Copyright (c) 2021 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 "quic/core/crypto/client_proof_source.h"
-
-#include "quic/platform/api/quic_expect_bug.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/test_certificates.h"
-
-namespace quic {
-namespace test {
-
-QuicReferenceCountedPointer<ClientProofSource::Chain> TestCertChain() {
- return QuicReferenceCountedPointer<ClientProofSource::Chain>(
- new ClientProofSource::Chain({std::string(kTestCertificate)}));
-}
-
-CertificatePrivateKey TestPrivateKey() {
- CBS private_key_cbs;
- CBS_init(&private_key_cbs,
- reinterpret_cast<const uint8_t*>(kTestCertificatePrivateKey.data()),
- kTestCertificatePrivateKey.size());
-
- return CertificatePrivateKey(
- bssl::UniquePtr<EVP_PKEY>(EVP_parse_private_key(&private_key_cbs)));
-}
-
-const ClientProofSource::CertAndKey* TestCertAndKey() {
- static const ClientProofSource::CertAndKey cert_and_key(TestCertChain(),
- TestPrivateKey());
- return &cert_and_key;
-}
-
-QuicReferenceCountedPointer<ClientProofSource::Chain> NullCertChain() {
- return QuicReferenceCountedPointer<ClientProofSource::Chain>();
-}
-
-QuicReferenceCountedPointer<ClientProofSource::Chain> EmptyCertChain() {
- return QuicReferenceCountedPointer<ClientProofSource::Chain>(
- new ClientProofSource::Chain(std::vector<std::string>()));
-}
-
-QuicReferenceCountedPointer<ClientProofSource::Chain> BadCertChain() {
- return QuicReferenceCountedPointer<ClientProofSource::Chain>(
- new ClientProofSource::Chain({"This is the content of a bad cert."}));
-}
-
-CertificatePrivateKey EmptyPrivateKey() {
- return CertificatePrivateKey(bssl::UniquePtr<EVP_PKEY>(EVP_PKEY_new()));
-}
-
-#define VERIFY_CERT_AND_KEY_MATCHES(lhs, rhs) \
- do { \
- SCOPED_TRACE(testing::Message()); \
- VerifyCertAndKeyMatches(lhs, rhs); \
- } while (0)
-
-void VerifyCertAndKeyMatches(const ClientProofSource::CertAndKey* lhs,
- const ClientProofSource::CertAndKey* rhs) {
- if (lhs == rhs) {
- return;
- }
-
- if (lhs == nullptr) {
- ADD_FAILURE() << "lhs is nullptr, but rhs is not";
- return;
- }
-
- if (rhs == nullptr) {
- ADD_FAILURE() << "rhs is nullptr, but lhs is not";
- return;
- }
-
- if (1 != EVP_PKEY_cmp(lhs->private_key.private_key(),
- rhs->private_key.private_key())) {
- ADD_FAILURE() << "Private keys mismatch";
- return;
- }
-
- const ClientProofSource::Chain* lhs_chain = lhs->chain.get();
- const ClientProofSource::Chain* rhs_chain = rhs->chain.get();
-
- if (lhs_chain == rhs_chain) {
- return;
- }
-
- if (lhs_chain == nullptr) {
- ADD_FAILURE() << "lhs->chain is nullptr, but rhs->chain is not";
- return;
- }
-
- if (rhs_chain == nullptr) {
- ADD_FAILURE() << "rhs->chain is nullptr, but lhs->chain is not";
- return;
- }
-
- if (lhs_chain->certs.size() != rhs_chain->certs.size()) {
- ADD_FAILURE() << "Cert chain length differ. lhs:" << lhs_chain->certs.size()
- << ", rhs:" << rhs_chain->certs.size();
- return;
- }
-
- for (size_t i = 0; i < lhs_chain->certs.size(); ++i) {
- if (lhs_chain->certs[i] != rhs_chain->certs[i]) {
- ADD_FAILURE() << "The " << i << "-th certs differ.";
- return;
- }
- }
-
- // All good.
-}
-
-TEST(DefaultClientProofSource, FullDomain) {
- DefaultClientProofSource proof_source;
- ASSERT_TRUE(proof_source.AddCertAndKey({"www.google.com"}, TestCertChain(),
- TestPrivateKey()));
- VERIFY_CERT_AND_KEY_MATCHES(proof_source.GetCertAndKey("www.google.com"),
- TestCertAndKey());
- EXPECT_EQ(proof_source.GetCertAndKey("*.google.com"), nullptr);
- EXPECT_EQ(proof_source.GetCertAndKey("*"), nullptr);
-}
-
-TEST(DefaultClientProofSource, WildcardDomain) {
- DefaultClientProofSource proof_source;
- ASSERT_TRUE(proof_source.AddCertAndKey({"*.google.com"}, TestCertChain(),
- TestPrivateKey()));
- VERIFY_CERT_AND_KEY_MATCHES(proof_source.GetCertAndKey("www.google.com"),
- TestCertAndKey());
- VERIFY_CERT_AND_KEY_MATCHES(proof_source.GetCertAndKey("*.google.com"),
- TestCertAndKey());
- EXPECT_EQ(proof_source.GetCertAndKey("*"), nullptr);
-}
-
-TEST(DefaultClientProofSource, DefaultDomain) {
- DefaultClientProofSource proof_source;
- ASSERT_TRUE(
- proof_source.AddCertAndKey({"*"}, TestCertChain(), TestPrivateKey()));
- VERIFY_CERT_AND_KEY_MATCHES(proof_source.GetCertAndKey("www.google.com"),
- TestCertAndKey());
- VERIFY_CERT_AND_KEY_MATCHES(proof_source.GetCertAndKey("*.google.com"),
- TestCertAndKey());
- VERIFY_CERT_AND_KEY_MATCHES(proof_source.GetCertAndKey("*"),
- TestCertAndKey());
-}
-
-TEST(DefaultClientProofSource, FullAndWildcard) {
- DefaultClientProofSource proof_source;
- ASSERT_TRUE(proof_source.AddCertAndKey({"www.google.com", "*.google.com"},
- TestCertChain(), TestPrivateKey()));
- VERIFY_CERT_AND_KEY_MATCHES(proof_source.GetCertAndKey("www.google.com"),
- TestCertAndKey());
- VERIFY_CERT_AND_KEY_MATCHES(proof_source.GetCertAndKey("foo.google.com"),
- TestCertAndKey());
- EXPECT_EQ(proof_source.GetCertAndKey("www.example.com"), nullptr);
- EXPECT_EQ(proof_source.GetCertAndKey("*"), nullptr);
-}
-
-TEST(DefaultClientProofSource, FullWildcardAndDefault) {
- DefaultClientProofSource proof_source;
- ASSERT_TRUE(
- proof_source.AddCertAndKey({"www.google.com", "*.google.com", "*"},
- TestCertChain(), TestPrivateKey()));
- VERIFY_CERT_AND_KEY_MATCHES(proof_source.GetCertAndKey("www.google.com"),
- TestCertAndKey());
- VERIFY_CERT_AND_KEY_MATCHES(proof_source.GetCertAndKey("foo.google.com"),
- TestCertAndKey());
- VERIFY_CERT_AND_KEY_MATCHES(proof_source.GetCertAndKey("www.example.com"),
- TestCertAndKey());
- VERIFY_CERT_AND_KEY_MATCHES(proof_source.GetCertAndKey("*.google.com"),
- TestCertAndKey());
- VERIFY_CERT_AND_KEY_MATCHES(proof_source.GetCertAndKey("*"),
- TestCertAndKey());
-}
-
-TEST(DefaultClientProofSource, EmptyCerts) {
- DefaultClientProofSource proof_source;
- bool ok;
- EXPECT_QUIC_BUG(
- ok = proof_source.AddCertAndKey({"*"}, NullCertChain(), TestPrivateKey()),
- "Certificate chain is empty");
- ASSERT_FALSE(ok);
-
- EXPECT_QUIC_BUG(ok = proof_source.AddCertAndKey({"*"}, EmptyCertChain(),
- TestPrivateKey()),
- "Certificate chain is empty");
- ASSERT_FALSE(ok);
- EXPECT_EQ(proof_source.GetCertAndKey("*"), nullptr);
-}
-
-TEST(DefaultClientProofSource, BadCerts) {
- DefaultClientProofSource proof_source;
- bool ok;
- EXPECT_QUIC_BUG(
- ok = proof_source.AddCertAndKey({"*"}, BadCertChain(), TestPrivateKey()),
- "Unabled to parse leaf certificate");
- ASSERT_FALSE(ok);
- EXPECT_EQ(proof_source.GetCertAndKey("*"), nullptr);
-}
-
-TEST(DefaultClientProofSource, KeyMismatch) {
- DefaultClientProofSource proof_source;
- bool ok;
- EXPECT_QUIC_BUG(ok = proof_source.AddCertAndKey(
- {"www.google.com"}, TestCertChain(), EmptyPrivateKey()),
- "Private key does not match the leaf certificate");
- ASSERT_FALSE(ok);
- EXPECT_EQ(proof_source.GetCertAndKey("*"), nullptr);
-}
-
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/common_cert_set.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/common_cert_set.cc
deleted file mode 100644
index aa057538948..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/common_cert_set.cc
+++ /dev/null
@@ -1,165 +0,0 @@
-// Copyright (c) 2013 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 "quic/core/crypto/common_cert_set.h"
-
-#include <cstddef>
-
-#include "absl/base/macros.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_utils.h"
-
-namespace quic {
-
-namespace common_cert_set_2 {
-#include "quic/core/crypto/common_cert_set_2.c"
-}
-
-namespace common_cert_set_3 {
-#include "quic/core/crypto/common_cert_set_3.c"
-}
-
-namespace {
-
-struct CertSet {
- // num_certs contains the number of certificates in this set.
- size_t num_certs;
- // certs is an array of |num_certs| pointers to the DER encoded certificates.
- const unsigned char* const* certs;
- // lens is an array of |num_certs| integers describing the length, in bytes,
- // of each certificate.
- const size_t* lens;
- // hash contains the 64-bit, FNV-1a hash of this set.
- uint64_t hash;
-};
-
-const CertSet kSets[] = {
- {
- common_cert_set_2::kNumCerts,
- common_cert_set_2::kCerts,
- common_cert_set_2::kLens,
- common_cert_set_2::kHash,
- },
- {
- common_cert_set_3::kNumCerts,
- common_cert_set_3::kCerts,
- common_cert_set_3::kLens,
- common_cert_set_3::kHash,
- },
-};
-
-const uint64_t kSetHashes[] = {
- common_cert_set_2::kHash,
- common_cert_set_3::kHash,
-};
-
-// Compare returns a value less than, equal to or greater than zero if |a| is
-// lexicographically less than, equal to or greater than |b|, respectively.
-int Compare(absl::string_view a, const unsigned char* b, size_t b_len) {
- size_t len = a.size();
- if (len > b_len) {
- len = b_len;
- }
- int n = memcmp(a.data(), b, len);
- if (n != 0) {
- return n;
- }
-
- if (a.size() < b_len) {
- return -1;
- } else if (a.size() > b_len) {
- return 1;
- }
- return 0;
-}
-
-// CommonCertSetsQUIC implements the CommonCertSets interface using the default
-// certificate sets.
-class CommonCertSetsQUIC : public CommonCertSets {
- public:
- // CommonCertSets interface.
- absl::string_view GetCommonHashes() const override {
- return absl::string_view(reinterpret_cast<const char*>(kSetHashes),
- sizeof(uint64_t) * ABSL_ARRAYSIZE(kSetHashes));
- }
-
- absl::string_view GetCert(uint64_t hash, uint32_t index) const override {
- for (size_t i = 0; i < ABSL_ARRAYSIZE(kSets); i++) {
- if (kSets[i].hash == hash) {
- if (index < kSets[i].num_certs) {
- return absl::string_view(
- reinterpret_cast<const char*>(kSets[i].certs[index]),
- kSets[i].lens[index]);
- }
- break;
- }
- }
-
- return absl::string_view();
- }
-
- bool MatchCert(absl::string_view cert,
- absl::string_view common_set_hashes,
- uint64_t* out_hash,
- uint32_t* out_index) const override {
- if (common_set_hashes.size() % sizeof(uint64_t) != 0) {
- return false;
- }
-
- for (size_t i = 0; i < common_set_hashes.size() / sizeof(uint64_t); i++) {
- uint64_t hash;
- memcpy(&hash, common_set_hashes.data() + i * sizeof(uint64_t),
- sizeof(uint64_t));
-
- for (size_t j = 0; j < ABSL_ARRAYSIZE(kSets); j++) {
- if (kSets[j].hash != hash) {
- continue;
- }
-
- if (kSets[j].num_certs == 0) {
- continue;
- }
-
- // Binary search for a matching certificate.
- size_t min = 0;
- size_t max = kSets[j].num_certs - 1;
- while (max >= min) {
- size_t mid = min + ((max - min) / 2);
- int n = Compare(cert, kSets[j].certs[mid], kSets[j].lens[mid]);
- if (n < 0) {
- if (mid == 0) {
- break;
- }
- max = mid - 1;
- } else if (n > 0) {
- min = mid + 1;
- } else {
- *out_hash = hash;
- *out_index = mid;
- return true;
- }
- }
- }
- }
-
- return false;
- }
-
- CommonCertSetsQUIC() {}
- CommonCertSetsQUIC(const CommonCertSetsQUIC&) = delete;
- CommonCertSetsQUIC& operator=(const CommonCertSetsQUIC&) = delete;
- ~CommonCertSetsQUIC() override {}
-};
-
-} // anonymous namespace
-
-CommonCertSets::~CommonCertSets() {}
-
-// static
-const CommonCertSets* CommonCertSets::GetInstanceQUIC() {
- static CommonCertSetsQUIC* certs = new CommonCertSetsQUIC();
- return certs;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/common_cert_set.h b/chromium/net/third_party/quiche/src/quic/core/crypto/common_cert_set.h
deleted file mode 100644
index 6bcd87d7844..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/common_cert_set.h
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright (c) 2013 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_CRYPTO_COMMON_CERT_SET_H_
-#define QUICHE_QUIC_CORE_CRYPTO_COMMON_CERT_SET_H_
-
-#include <cstdint>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/crypto/crypto_protocol.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// CommonCertSets is an interface to an object that contains a number of common
-// certificate sets and can match against them.
-class QUIC_EXPORT_PRIVATE CommonCertSets {
- public:
- virtual ~CommonCertSets();
-
- // GetInstanceQUIC returns the standard QUIC common certificate sets.
- static const CommonCertSets* GetInstanceQUIC();
-
- // GetCommonHashes returns a absl::string_view containing the hashes
- // of common sets supported by this object. The 64-bit hashes are concatenated
- // in the absl::string_view.
- virtual absl::string_view GetCommonHashes() const = 0;
-
- // GetCert returns a specific certificate (at index |index|) in the common
- // set identified by |hash|. If no such certificate is known, an empty
- // absl::string_view is returned.
- virtual absl::string_view GetCert(uint64_t hash, uint32_t index) const = 0;
-
- // MatchCert tries to find |cert| in one of the common certificate sets
- // identified by |common_set_hashes|. On success it puts the hash of the
- // set in |out_hash|, the index of |cert| in the set in |out_index| and
- // returns true. Otherwise it returns false.
- virtual bool MatchCert(absl::string_view cert,
- absl::string_view common_set_hashes,
- uint64_t* out_hash,
- uint32_t* out_index) const = 0;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_CRYPTO_COMMON_CERT_SET_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/common_cert_set_2.c b/chromium/net/third_party/quiche/src/quic/core/crypto/common_cert_set_2.c
deleted file mode 100644
index 6392e67d387..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/common_cert_set_2.c
+++ /dev/null
@@ -1,122 +0,0 @@
-/* This file contains common certificates. It's designed to be #included in
- * another file, in a namespace. */
-
-#include "quic/core/crypto/common_cert_set_2a.inc"
-#include "quic/core/crypto/common_cert_set_2b.inc"
-
-static const size_t kNumCerts = 54;
-static const unsigned char* const kCerts[] = {
- kDERCert0,
- kDERCert1,
- kDERCert2,
- kDERCert3,
- kDERCert4,
- kDERCert5,
- kDERCert6,
- kDERCert7,
- kDERCert8,
- kDERCert9,
- kDERCert10,
- kDERCert11,
- kDERCert12,
- kDERCert13,
- kDERCert14,
- kDERCert15,
- kDERCert16,
- kDERCert17,
- kDERCert18,
- kDERCert19,
- kDERCert20,
- kDERCert21,
- kDERCert22,
- kDERCert23,
- kDERCert24,
- kDERCert25,
- kDERCert26,
- kDERCert27,
- kDERCert28,
- kDERCert29,
- kDERCert30,
- kDERCert31,
- kDERCert32,
- kDERCert33,
- kDERCert34,
- kDERCert35,
- kDERCert36,
- kDERCert37,
- kDERCert38,
- kDERCert39,
- kDERCert40,
- kDERCert41,
- kDERCert42,
- kDERCert43,
- kDERCert44,
- kDERCert45,
- kDERCert46,
- kDERCert47,
- kDERCert48,
- kDERCert49,
- kDERCert50,
- kDERCert51,
- kDERCert52,
- kDERCert53,
-};
-
-static const size_t kLens[] = {
- 897,
- 911,
- 985,
- 1012,
- 1049,
- 1062,
- 1065,
- 1071,
- 1084,
- 1096,
- 1097,
- 1105,
- 1107,
- 1117,
- 1127,
- 1133,
- 1136,
- 1138,
- 1153,
- 1171,
- 1172,
- 1176,
- 1182,
- 1188,
- 1194,
- 1203,
- 1205,
- 1206,
- 1210,
- 1222,
- 1226,
- 1236,
- 1236,
- 1236,
- 1238,
- 1256,
- 1270,
- 1280,
- 1283,
- 1284,
- 1287,
- 1315,
- 1327,
- 1340,
- 1418,
- 1447,
- 1509,
- 1520,
- 1570,
- 1581,
- 1592,
- 1628,
- 1632,
- 1770,
-};
-
-static const uint64_t kHash = UINT64_C(0xe81a92926081e801);
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/common_cert_set_2a.inc b/chromium/net/third_party/quiche/src/quic/core/crypto/common_cert_set_2a.inc
deleted file mode 100644
index 75e648c9228..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/common_cert_set_2a.inc
+++ /dev/null
@@ -1,5622 +0,0 @@
-#if 0
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number: 1227750 (0x12bbe6)
- Signature Algorithm: sha1WithRSAEncryption
- Issuer: C=US, O=Equifax, OU=Equifax Secure Certificate Authority
- Validity
- Not Before: May 21 04:00:00 2002 GMT
- Not After : Aug 21 04:00:00 2018 GMT
- Subject: C=US, O=GeoTrust Inc., CN=GeoTrust Global CA
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:da:cc:18:63:30:fd:f4:17:23:1a:56:7e:5b:df:
- 3c:6c:38:e4:71:b7:78:91:d4:bc:a1:d8:4c:f8:a8:
- 43:b6:03:e9:4d:21:07:08:88:da:58:2f:66:39:29:
- bd:05:78:8b:9d:38:e8:05:b7:6a:7e:71:a4:e6:c4:
- 60:a6:b0:ef:80:e4:89:28:0f:9e:25:d6:ed:83:f3:
- ad:a6:91:c7:98:c9:42:18:35:14:9d:ad:98:46:92:
- 2e:4f:ca:f1:87:43:c1:16:95:57:2d:50:ef:89:2d:
- 80:7a:57:ad:f2:ee:5f:6b:d2:00:8d:b9:14:f8:14:
- 15:35:d9:c0:46:a3:7b:72:c8:91:bf:c9:55:2b:cd:
- d0:97:3e:9c:26:64:cc:df:ce:83:19:71:ca:4e:e6:
- d4:d5:7b:a9:19:cd:55:de:c8:ec:d2:5e:38:53:e5:
- 5c:4f:8c:2d:fe:50:23:36:fc:66:e6:cb:8e:a4:39:
- 19:00:b7:95:02:39:91:0b:0e:fe:38:2e:d1:1d:05:
- 9a:f6:4d:3e:6f:0f:07:1d:af:2c:1e:8f:60:39:e2:
- fa:36:53:13:39:d4:5e:26:2b:db:3d:a8:14:bd:32:
- eb:18:03:28:52:04:71:e5:ab:33:3d:e1:38:bb:07:
- 36:84:62:9c:79:ea:16:30:f4:5f:c0:2b:e8:71:6b:
- e4:f9
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Authority Key Identifier:
- keyid:48:E6:68:F9:2B:D2:B2:95:D7:47:D8:23:20:10:4F:33:98:90:9F:D4
-
- X509v3 Subject Key Identifier:
- C0:7A:98:68:8D:89:FB:AB:05:64:0C:11:7D:AA:7D:65:B8:CA:CC:4E
- X509v3 Basic Constraints: critical
- CA:TRUE
- X509v3 Key Usage: critical
- Certificate Sign, CRL Sign
- X509v3 CRL Distribution Points:
-
- Full Name:
- URI:http://crl.geotrust.com/crls/secureca.crl
-
- X509v3 Certificate Policies:
- Policy: X509v3 Any Policy
- CPS: https://www.geotrust.com/resources/repository
-
- Signature Algorithm: sha1WithRSAEncryption
- 76:e1:12:6e:4e:4b:16:12:86:30:06:b2:81:08:cf:f0:08:c7:
- c7:71:7e:66:ee:c2:ed:d4:3b:1f:ff:f0:f0:c8:4e:d6:43:38:
- b0:b9:30:7d:18:d0:55:83:a2:6a:cb:36:11:9c:e8:48:66:a3:
- 6d:7f:b8:13:d4:47:fe:8b:5a:5c:73:fc:ae:d9:1b:32:19:38:
- ab:97:34:14:aa:96:d2:eb:a3:1c:14:08:49:b6:bb:e5:91:ef:
- 83:36:eb:1d:56:6f:ca:da:bc:73:63:90:e4:7f:7b:3e:22:cb:
- 3d:07:ed:5f:38:74:9c:e3:03:50:4e:a1:af:98:ee:61:f2:84:
- 3f:12
------BEGIN CERTIFICATE-----
-MIIDfTCCAuagAwIBAgIDErvmMA0GCSqGSIb3DQEBBQUAME4xCzAJBgNVBAYTAlVT
-MRAwDgYDVQQKEwdFcXVpZmF4MS0wKwYDVQQLEyRFcXVpZmF4IFNlY3VyZSBDZXJ0
-aWZpY2F0ZSBBdXRob3JpdHkwHhcNMDIwNTIxMDQwMDAwWhcNMTgwODIxMDQwMDAw
-WjBCMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEbMBkGA1UE
-AxMSR2VvVHJ1c3QgR2xvYmFsIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
-CgKCAQEA2swYYzD99BcjGlZ+W988bDjkcbd4kdS8odhM+KhDtgPpTSEHCIjaWC9m
-OSm9BXiLnTjoBbdqfnGk5sRgprDvgOSJKA+eJdbtg/OtppHHmMlCGDUUna2YRpIu
-T8rxh0PBFpVXLVDviS2Aelet8u5fa9IAjbkU+BQVNdnARqN7csiRv8lVK83Qlz6c
-JmTM386DGXHKTubU1XupGc1V3sjs0l44U+VcT4wt/lAjNvxm5suOpDkZALeVAjmR
-Cw7+OC7RHQWa9k0+bw8HHa8sHo9gOeL6NlMTOdReJivbPagUvTLrGAMoUgRx5asz
-PeE4uwc2hGKceeoWMPRfwCvocWvk+QIDAQABo4HwMIHtMB8GA1UdIwQYMBaAFEjm
-aPkr0rKV10fYIyAQTzOYkJ/UMB0GA1UdDgQWBBTAephojYn7qwVkDBF9qn1luMrM
-TjAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjA6BgNVHR8EMzAxMC+g
-LaArhilodHRwOi8vY3JsLmdlb3RydXN0LmNvbS9jcmxzL3NlY3VyZWNhLmNybDBO
-BgNVHSAERzBFMEMGBFUdIAAwOzA5BggrBgEFBQcCARYtaHR0cHM6Ly93d3cuZ2Vv
-dHJ1c3QuY29tL3Jlc291cmNlcy9yZXBvc2l0b3J5MA0GCSqGSIb3DQEBBQUAA4GB
-AHbhEm5OSxYShjAGsoEIz/AIx8dxfmbuwu3UOx//8PDITtZDOLC5MH0Y0FWDomrL
-NhGc6Ehmo21/uBPUR/6LWlxz/K7ZGzIZOKuXNBSqltLroxwUCEm2u+WR74M26x1W
-b8ravHNjkOR/ez4iyz0H7V84dJzjA1BOoa+Y7mHyhD8S
------END CERTIFICATE-----
-#endif
-static const unsigned char kDERCert0[] = {
- 0x30, 0x82, 0x03, 0x7d, 0x30, 0x82, 0x02, 0xe6, 0xa0, 0x03, 0x02, 0x01,
- 0x02, 0x02, 0x03, 0x12, 0xbb, 0xe6, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
- 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x4e, 0x31,
- 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53,
- 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x07, 0x45,
- 0x71, 0x75, 0x69, 0x66, 0x61, 0x78, 0x31, 0x2d, 0x30, 0x2b, 0x06, 0x03,
- 0x55, 0x04, 0x0b, 0x13, 0x24, 0x45, 0x71, 0x75, 0x69, 0x66, 0x61, 0x78,
- 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74,
- 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68,
- 0x6f, 0x72, 0x69, 0x74, 0x79, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x32, 0x30,
- 0x35, 0x32, 0x31, 0x30, 0x34, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d,
- 0x31, 0x38, 0x30, 0x38, 0x32, 0x31, 0x30, 0x34, 0x30, 0x30, 0x30, 0x30,
- 0x5a, 0x30, 0x42, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06,
- 0x13, 0x02, 0x55, 0x53, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04,
- 0x0a, 0x13, 0x0d, 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20,
- 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04,
- 0x03, 0x13, 0x12, 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20,
- 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x20, 0x43, 0x41, 0x30, 0x82, 0x01,
- 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
- 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01,
- 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xda, 0xcc, 0x18, 0x63, 0x30, 0xfd,
- 0xf4, 0x17, 0x23, 0x1a, 0x56, 0x7e, 0x5b, 0xdf, 0x3c, 0x6c, 0x38, 0xe4,
- 0x71, 0xb7, 0x78, 0x91, 0xd4, 0xbc, 0xa1, 0xd8, 0x4c, 0xf8, 0xa8, 0x43,
- 0xb6, 0x03, 0xe9, 0x4d, 0x21, 0x07, 0x08, 0x88, 0xda, 0x58, 0x2f, 0x66,
- 0x39, 0x29, 0xbd, 0x05, 0x78, 0x8b, 0x9d, 0x38, 0xe8, 0x05, 0xb7, 0x6a,
- 0x7e, 0x71, 0xa4, 0xe6, 0xc4, 0x60, 0xa6, 0xb0, 0xef, 0x80, 0xe4, 0x89,
- 0x28, 0x0f, 0x9e, 0x25, 0xd6, 0xed, 0x83, 0xf3, 0xad, 0xa6, 0x91, 0xc7,
- 0x98, 0xc9, 0x42, 0x18, 0x35, 0x14, 0x9d, 0xad, 0x98, 0x46, 0x92, 0x2e,
- 0x4f, 0xca, 0xf1, 0x87, 0x43, 0xc1, 0x16, 0x95, 0x57, 0x2d, 0x50, 0xef,
- 0x89, 0x2d, 0x80, 0x7a, 0x57, 0xad, 0xf2, 0xee, 0x5f, 0x6b, 0xd2, 0x00,
- 0x8d, 0xb9, 0x14, 0xf8, 0x14, 0x15, 0x35, 0xd9, 0xc0, 0x46, 0xa3, 0x7b,
- 0x72, 0xc8, 0x91, 0xbf, 0xc9, 0x55, 0x2b, 0xcd, 0xd0, 0x97, 0x3e, 0x9c,
- 0x26, 0x64, 0xcc, 0xdf, 0xce, 0x83, 0x19, 0x71, 0xca, 0x4e, 0xe6, 0xd4,
- 0xd5, 0x7b, 0xa9, 0x19, 0xcd, 0x55, 0xde, 0xc8, 0xec, 0xd2, 0x5e, 0x38,
- 0x53, 0xe5, 0x5c, 0x4f, 0x8c, 0x2d, 0xfe, 0x50, 0x23, 0x36, 0xfc, 0x66,
- 0xe6, 0xcb, 0x8e, 0xa4, 0x39, 0x19, 0x00, 0xb7, 0x95, 0x02, 0x39, 0x91,
- 0x0b, 0x0e, 0xfe, 0x38, 0x2e, 0xd1, 0x1d, 0x05, 0x9a, 0xf6, 0x4d, 0x3e,
- 0x6f, 0x0f, 0x07, 0x1d, 0xaf, 0x2c, 0x1e, 0x8f, 0x60, 0x39, 0xe2, 0xfa,
- 0x36, 0x53, 0x13, 0x39, 0xd4, 0x5e, 0x26, 0x2b, 0xdb, 0x3d, 0xa8, 0x14,
- 0xbd, 0x32, 0xeb, 0x18, 0x03, 0x28, 0x52, 0x04, 0x71, 0xe5, 0xab, 0x33,
- 0x3d, 0xe1, 0x38, 0xbb, 0x07, 0x36, 0x84, 0x62, 0x9c, 0x79, 0xea, 0x16,
- 0x30, 0xf4, 0x5f, 0xc0, 0x2b, 0xe8, 0x71, 0x6b, 0xe4, 0xf9, 0x02, 0x03,
- 0x01, 0x00, 0x01, 0xa3, 0x81, 0xf0, 0x30, 0x81, 0xed, 0x30, 0x1f, 0x06,
- 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x48, 0xe6,
- 0x68, 0xf9, 0x2b, 0xd2, 0xb2, 0x95, 0xd7, 0x47, 0xd8, 0x23, 0x20, 0x10,
- 0x4f, 0x33, 0x98, 0x90, 0x9f, 0xd4, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d,
- 0x0e, 0x04, 0x16, 0x04, 0x14, 0xc0, 0x7a, 0x98, 0x68, 0x8d, 0x89, 0xfb,
- 0xab, 0x05, 0x64, 0x0c, 0x11, 0x7d, 0xaa, 0x7d, 0x65, 0xb8, 0xca, 0xcc,
- 0x4e, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04,
- 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d,
- 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x3a,
- 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x33, 0x30, 0x31, 0x30, 0x2f, 0xa0,
- 0x2d, 0xa0, 0x2b, 0x86, 0x29, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f,
- 0x63, 0x72, 0x6c, 0x2e, 0x67, 0x65, 0x6f, 0x74, 0x72, 0x75, 0x73, 0x74,
- 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x72, 0x6c, 0x73, 0x2f, 0x73, 0x65,
- 0x63, 0x75, 0x72, 0x65, 0x63, 0x61, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x4e,
- 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x47, 0x30, 0x45, 0x30, 0x43, 0x06,
- 0x04, 0x55, 0x1d, 0x20, 0x00, 0x30, 0x3b, 0x30, 0x39, 0x06, 0x08, 0x2b,
- 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x2d, 0x68, 0x74, 0x74,
- 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x67, 0x65, 0x6f,
- 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65,
- 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x2f, 0x72, 0x65, 0x70, 0x6f,
- 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
- 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x81, 0x81,
- 0x00, 0x76, 0xe1, 0x12, 0x6e, 0x4e, 0x4b, 0x16, 0x12, 0x86, 0x30, 0x06,
- 0xb2, 0x81, 0x08, 0xcf, 0xf0, 0x08, 0xc7, 0xc7, 0x71, 0x7e, 0x66, 0xee,
- 0xc2, 0xed, 0xd4, 0x3b, 0x1f, 0xff, 0xf0, 0xf0, 0xc8, 0x4e, 0xd6, 0x43,
- 0x38, 0xb0, 0xb9, 0x30, 0x7d, 0x18, 0xd0, 0x55, 0x83, 0xa2, 0x6a, 0xcb,
- 0x36, 0x11, 0x9c, 0xe8, 0x48, 0x66, 0xa3, 0x6d, 0x7f, 0xb8, 0x13, 0xd4,
- 0x47, 0xfe, 0x8b, 0x5a, 0x5c, 0x73, 0xfc, 0xae, 0xd9, 0x1b, 0x32, 0x19,
- 0x38, 0xab, 0x97, 0x34, 0x14, 0xaa, 0x96, 0xd2, 0xeb, 0xa3, 0x1c, 0x14,
- 0x08, 0x49, 0xb6, 0xbb, 0xe5, 0x91, 0xef, 0x83, 0x36, 0xeb, 0x1d, 0x56,
- 0x6f, 0xca, 0xda, 0xbc, 0x73, 0x63, 0x90, 0xe4, 0x7f, 0x7b, 0x3e, 0x22,
- 0xcb, 0x3d, 0x07, 0xed, 0x5f, 0x38, 0x74, 0x9c, 0xe3, 0x03, 0x50, 0x4e,
- 0xa1, 0xaf, 0x98, 0xee, 0x61, 0xf2, 0x84, 0x3f, 0x12,
-};
-
-#if 0
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number: 880226 (0xd6e62)
- Signature Algorithm: sha1WithRSAEncryption
- Issuer: C=US, O=Equifax, OU=Equifax Secure Certificate Authority
- Validity
- Not Before: Nov 27 00:00:00 2006 GMT
- Not After : Aug 21 16:15:00 2018 GMT
- Subject: C=US, O=GeoTrust Inc., CN=GeoTrust Primary Certification Authority
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:be:b8:15:7b:ff:d4:7c:7d:67:ad:83:64:7b:c8:
- 42:53:2d:df:f6:84:08:20:61:d6:01:59:6a:9c:44:
- 11:af:ef:76:fd:95:7e:ce:61:30:bb:7a:83:5f:02:
- bd:01:66:ca:ee:15:8d:6f:a1:30:9c:bd:a1:85:9e:
- 94:3a:f3:56:88:00:31:cf:d8:ee:6a:96:02:d9:ed:
- 03:8c:fb:75:6d:e7:ea:b8:55:16:05:16:9a:f4:e0:
- 5e:b1:88:c0:64:85:5c:15:4d:88:c7:b7:ba:e0:75:
- e9:ad:05:3d:9d:c7:89:48:e0:bb:28:c8:03:e1:30:
- 93:64:5e:52:c0:59:70:22:35:57:88:8a:f1:95:0a:
- 83:d7:bc:31:73:01:34:ed:ef:46:71:e0:6b:02:a8:
- 35:72:6b:97:9b:66:e0:cb:1c:79:5f:d8:1a:04:68:
- 1e:47:02:e6:9d:60:e2:36:97:01:df:ce:35:92:df:
- be:67:c7:6d:77:59:3b:8f:9d:d6:90:15:94:bc:42:
- 34:10:c1:39:f9:b1:27:3e:7e:d6:8a:75:c5:b2:af:
- 96:d3:a2:de:9b:e4:98:be:7d:e1:e9:81:ad:b6:6f:
- fc:d7:0e:da:e0:34:b0:0d:1a:77:e7:e3:08:98:ef:
- 58:fa:9c:84:b7:36:af:c2:df:ac:d2:f4:10:06:70:
- 71:35
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Key Usage: critical
- Certificate Sign, CRL Sign
- X509v3 Subject Key Identifier:
- 2C:D5:50:41:97:15:8B:F0:8F:36:61:5B:4A:FB:6B:D9:99:C9:33:92
- X509v3 Authority Key Identifier:
- keyid:48:E6:68:F9:2B:D2:B2:95:D7:47:D8:23:20:10:4F:33:98:90:9F:D4
-
- X509v3 Basic Constraints: critical
- CA:TRUE
- X509v3 CRL Distribution Points:
-
- Full Name:
- URI:http://crl.geotrust.com/crls/secureca.crl
-
- X509v3 Certificate Policies:
- Policy: X509v3 Any Policy
- CPS: http://www.geotrust.com/resources/cps
-
- Signature Algorithm: sha1WithRSAEncryption
- af:f3:0e:d6:72:ab:c7:a9:97:ca:2a:6b:84:39:de:79:a9:f0:
- 81:e5:08:67:ab:d7:2f:20:02:01:71:0c:04:22:c9:1e:88:95:
- 03:c9:49:3a:af:67:08:49:b0:d5:08:f5:20:3d:80:91:a0:c5:
- 87:a3:fb:c9:a3:17:91:f9:a8:2f:ae:e9:0f:df:96:72:0f:75:
- 17:80:5d:78:01:4d:9f:1f:6d:7b:d8:f5:42:38:23:1a:99:93:
- f4:83:be:3b:35:74:e7:37:13:35:7a:ac:b4:b6:90:82:6c:27:
- a4:e0:ec:9e:35:bd:bf:e5:29:a1:47:9f:5b:32:fc:e9:99:7d:
- 2b:39
------BEGIN CERTIFICATE-----
-MIIDizCCAvSgAwIBAgIDDW5iMA0GCSqGSIb3DQEBBQUAME4xCzAJBgNVBAYTAlVT
-MRAwDgYDVQQKEwdFcXVpZmF4MS0wKwYDVQQLEyRFcXVpZmF4IFNlY3VyZSBDZXJ0
-aWZpY2F0ZSBBdXRob3JpdHkwHhcNMDYxMTI3MDAwMDAwWhcNMTgwODIxMTYxNTAw
-WjBYMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjExMC8GA1UE
-AxMoR2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASIw
-DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL64FXv/1Hx9Z62DZHvIQlMt3/aE
-CCBh1gFZapxEEa/vdv2Vfs5hMLt6g18CvQFmyu4VjW+hMJy9oYWelDrzVogAMc/Y
-7mqWAtntA4z7dW3n6rhVFgUWmvTgXrGIwGSFXBVNiMe3uuB16a0FPZ3HiUjguyjI
-A+Ewk2ReUsBZcCI1V4iK8ZUKg9e8MXMBNO3vRnHgawKoNXJrl5tm4MsceV/YGgRo
-HkcC5p1g4jaXAd/ONZLfvmfHbXdZO4+d1pAVlLxCNBDBOfmxJz5+1op1xbKvltOi
-3pvkmL594emBrbZv/NcO2uA0sA0ad+fjCJjvWPqchLc2r8LfrNL0EAZwcTUCAwEA
-AaOB6DCB5TAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFCzVUEGXFYvwjzZhW0r7
-a9mZyTOSMB8GA1UdIwQYMBaAFEjmaPkr0rKV10fYIyAQTzOYkJ/UMA8GA1UdEwEB
-/wQFMAMBAf8wOgYDVR0fBDMwMTAvoC2gK4YpaHR0cDovL2NybC5nZW90cnVzdC5j
-b20vY3Jscy9zZWN1cmVjYS5jcmwwRgYDVR0gBD8wPTA7BgRVHSAAMDMwMQYIKwYB
-BQUHAgEWJWh0dHA6Ly93d3cuZ2VvdHJ1c3QuY29tL3Jlc291cmNlcy9jcHMwDQYJ
-KoZIhvcNAQEFBQADgYEAr/MO1nKrx6mXyiprhDneeanwgeUIZ6vXLyACAXEMBCLJ
-HoiVA8lJOq9nCEmw1Qj1ID2AkaDFh6P7yaMXkfmoL67pD9+Wcg91F4BdeAFNnx9t
-e9j1QjgjGpmT9IO+OzV05zcTNXqstLaQgmwnpODsnjW9v+UpoUefWzL86Zl9Kzk=
------END CERTIFICATE-----
-#endif
-static const unsigned char kDERCert1[] = {
- 0x30, 0x82, 0x03, 0x8b, 0x30, 0x82, 0x02, 0xf4, 0xa0, 0x03, 0x02, 0x01,
- 0x02, 0x02, 0x03, 0x0d, 0x6e, 0x62, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
- 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x4e, 0x31,
- 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53,
- 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x07, 0x45,
- 0x71, 0x75, 0x69, 0x66, 0x61, 0x78, 0x31, 0x2d, 0x30, 0x2b, 0x06, 0x03,
- 0x55, 0x04, 0x0b, 0x13, 0x24, 0x45, 0x71, 0x75, 0x69, 0x66, 0x61, 0x78,
- 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74,
- 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68,
- 0x6f, 0x72, 0x69, 0x74, 0x79, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x36, 0x31,
- 0x31, 0x32, 0x37, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d,
- 0x31, 0x38, 0x30, 0x38, 0x32, 0x31, 0x31, 0x36, 0x31, 0x35, 0x30, 0x30,
- 0x5a, 0x30, 0x58, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06,
- 0x13, 0x02, 0x55, 0x53, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04,
- 0x0a, 0x13, 0x0d, 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20,
- 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x31, 0x30, 0x2f, 0x06, 0x03, 0x55, 0x04,
- 0x03, 0x13, 0x28, 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20,
- 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x20, 0x43, 0x65, 0x72, 0x74,
- 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75,
- 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x30, 0x82, 0x01, 0x22, 0x30,
- 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01,
- 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02,
- 0x82, 0x01, 0x01, 0x00, 0xbe, 0xb8, 0x15, 0x7b, 0xff, 0xd4, 0x7c, 0x7d,
- 0x67, 0xad, 0x83, 0x64, 0x7b, 0xc8, 0x42, 0x53, 0x2d, 0xdf, 0xf6, 0x84,
- 0x08, 0x20, 0x61, 0xd6, 0x01, 0x59, 0x6a, 0x9c, 0x44, 0x11, 0xaf, 0xef,
- 0x76, 0xfd, 0x95, 0x7e, 0xce, 0x61, 0x30, 0xbb, 0x7a, 0x83, 0x5f, 0x02,
- 0xbd, 0x01, 0x66, 0xca, 0xee, 0x15, 0x8d, 0x6f, 0xa1, 0x30, 0x9c, 0xbd,
- 0xa1, 0x85, 0x9e, 0x94, 0x3a, 0xf3, 0x56, 0x88, 0x00, 0x31, 0xcf, 0xd8,
- 0xee, 0x6a, 0x96, 0x02, 0xd9, 0xed, 0x03, 0x8c, 0xfb, 0x75, 0x6d, 0xe7,
- 0xea, 0xb8, 0x55, 0x16, 0x05, 0x16, 0x9a, 0xf4, 0xe0, 0x5e, 0xb1, 0x88,
- 0xc0, 0x64, 0x85, 0x5c, 0x15, 0x4d, 0x88, 0xc7, 0xb7, 0xba, 0xe0, 0x75,
- 0xe9, 0xad, 0x05, 0x3d, 0x9d, 0xc7, 0x89, 0x48, 0xe0, 0xbb, 0x28, 0xc8,
- 0x03, 0xe1, 0x30, 0x93, 0x64, 0x5e, 0x52, 0xc0, 0x59, 0x70, 0x22, 0x35,
- 0x57, 0x88, 0x8a, 0xf1, 0x95, 0x0a, 0x83, 0xd7, 0xbc, 0x31, 0x73, 0x01,
- 0x34, 0xed, 0xef, 0x46, 0x71, 0xe0, 0x6b, 0x02, 0xa8, 0x35, 0x72, 0x6b,
- 0x97, 0x9b, 0x66, 0xe0, 0xcb, 0x1c, 0x79, 0x5f, 0xd8, 0x1a, 0x04, 0x68,
- 0x1e, 0x47, 0x02, 0xe6, 0x9d, 0x60, 0xe2, 0x36, 0x97, 0x01, 0xdf, 0xce,
- 0x35, 0x92, 0xdf, 0xbe, 0x67, 0xc7, 0x6d, 0x77, 0x59, 0x3b, 0x8f, 0x9d,
- 0xd6, 0x90, 0x15, 0x94, 0xbc, 0x42, 0x34, 0x10, 0xc1, 0x39, 0xf9, 0xb1,
- 0x27, 0x3e, 0x7e, 0xd6, 0x8a, 0x75, 0xc5, 0xb2, 0xaf, 0x96, 0xd3, 0xa2,
- 0xde, 0x9b, 0xe4, 0x98, 0xbe, 0x7d, 0xe1, 0xe9, 0x81, 0xad, 0xb6, 0x6f,
- 0xfc, 0xd7, 0x0e, 0xda, 0xe0, 0x34, 0xb0, 0x0d, 0x1a, 0x77, 0xe7, 0xe3,
- 0x08, 0x98, 0xef, 0x58, 0xfa, 0x9c, 0x84, 0xb7, 0x36, 0xaf, 0xc2, 0xdf,
- 0xac, 0xd2, 0xf4, 0x10, 0x06, 0x70, 0x71, 0x35, 0x02, 0x03, 0x01, 0x00,
- 0x01, 0xa3, 0x81, 0xe8, 0x30, 0x81, 0xe5, 0x30, 0x0e, 0x06, 0x03, 0x55,
- 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30,
- 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x2c, 0xd5,
- 0x50, 0x41, 0x97, 0x15, 0x8b, 0xf0, 0x8f, 0x36, 0x61, 0x5b, 0x4a, 0xfb,
- 0x6b, 0xd9, 0x99, 0xc9, 0x33, 0x92, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d,
- 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x48, 0xe6, 0x68, 0xf9, 0x2b,
- 0xd2, 0xb2, 0x95, 0xd7, 0x47, 0xd8, 0x23, 0x20, 0x10, 0x4f, 0x33, 0x98,
- 0x90, 0x9f, 0xd4, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01,
- 0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x3a, 0x06, 0x03,
- 0x55, 0x1d, 0x1f, 0x04, 0x33, 0x30, 0x31, 0x30, 0x2f, 0xa0, 0x2d, 0xa0,
- 0x2b, 0x86, 0x29, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72,
- 0x6c, 0x2e, 0x67, 0x65, 0x6f, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63,
- 0x6f, 0x6d, 0x2f, 0x63, 0x72, 0x6c, 0x73, 0x2f, 0x73, 0x65, 0x63, 0x75,
- 0x72, 0x65, 0x63, 0x61, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x46, 0x06, 0x03,
- 0x55, 0x1d, 0x20, 0x04, 0x3f, 0x30, 0x3d, 0x30, 0x3b, 0x06, 0x04, 0x55,
- 0x1d, 0x20, 0x00, 0x30, 0x33, 0x30, 0x31, 0x06, 0x08, 0x2b, 0x06, 0x01,
- 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x25, 0x68, 0x74, 0x74, 0x70, 0x3a,
- 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x67, 0x65, 0x6f, 0x74, 0x72, 0x75,
- 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75,
- 0x72, 0x63, 0x65, 0x73, 0x2f, 0x63, 0x70, 0x73, 0x30, 0x0d, 0x06, 0x09,
- 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03,
- 0x81, 0x81, 0x00, 0xaf, 0xf3, 0x0e, 0xd6, 0x72, 0xab, 0xc7, 0xa9, 0x97,
- 0xca, 0x2a, 0x6b, 0x84, 0x39, 0xde, 0x79, 0xa9, 0xf0, 0x81, 0xe5, 0x08,
- 0x67, 0xab, 0xd7, 0x2f, 0x20, 0x02, 0x01, 0x71, 0x0c, 0x04, 0x22, 0xc9,
- 0x1e, 0x88, 0x95, 0x03, 0xc9, 0x49, 0x3a, 0xaf, 0x67, 0x08, 0x49, 0xb0,
- 0xd5, 0x08, 0xf5, 0x20, 0x3d, 0x80, 0x91, 0xa0, 0xc5, 0x87, 0xa3, 0xfb,
- 0xc9, 0xa3, 0x17, 0x91, 0xf9, 0xa8, 0x2f, 0xae, 0xe9, 0x0f, 0xdf, 0x96,
- 0x72, 0x0f, 0x75, 0x17, 0x80, 0x5d, 0x78, 0x01, 0x4d, 0x9f, 0x1f, 0x6d,
- 0x7b, 0xd8, 0xf5, 0x42, 0x38, 0x23, 0x1a, 0x99, 0x93, 0xf4, 0x83, 0xbe,
- 0x3b, 0x35, 0x74, 0xe7, 0x37, 0x13, 0x35, 0x7a, 0xac, 0xb4, 0xb6, 0x90,
- 0x82, 0x6c, 0x27, 0xa4, 0xe0, 0xec, 0x9e, 0x35, 0xbd, 0xbf, 0xe5, 0x29,
- 0xa1, 0x47, 0x9f, 0x5b, 0x32, 0xfc, 0xe9, 0x99, 0x7d, 0x2b, 0x39,
-};
-
-#if 0
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number: 145105 (0x236d1)
- Signature Algorithm: sha1WithRSAEncryption
- Issuer: C=US, O=GeoTrust Inc., CN=GeoTrust Global CA
- Validity
- Not Before: Feb 19 22:45:05 2010 GMT
- Not After : Feb 18 22:45:05 2020 GMT
- Subject: C=US, O=GeoTrust, Inc., CN=RapidSSL CA
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:c7:71:f8:56:c7:1e:d9:cc:b5:ad:f6:b4:97:a3:
- fb:a1:e6:0b:50:5f:50:aa:3a:da:0f:fc:3d:29:24:
- 43:c6:10:29:c1:fc:55:40:72:ee:bd:ea:df:9f:b6:
- 41:f4:48:4b:c8:6e:fe:4f:57:12:8b:5b:fa:92:dd:
- 5e:e8:ad:f3:f0:1b:b1:7b:4d:fb:cf:fd:d1:e5:f8:
- e3:dc:e7:f5:73:7f:df:01:49:cf:8c:56:c1:bd:37:
- e3:5b:be:b5:4f:8b:8b:f0:da:4f:c7:e3:dd:55:47:
- 69:df:f2:5b:7b:07:4f:3d:e5:ac:21:c1:c8:1d:7a:
- e8:e7:f6:0f:a1:aa:f5:6f:de:a8:65:4f:10:89:9c:
- 03:f3:89:7a:a5:5e:01:72:33:ed:a9:e9:5a:1e:79:
- f3:87:c8:df:c8:c5:fc:37:c8:9a:9a:d7:b8:76:cc:
- b0:3e:e7:fd:e6:54:ea:df:5f:52:41:78:59:57:ad:
- f1:12:d6:7f:bc:d5:9f:70:d3:05:6c:fa:a3:7d:67:
- 58:dd:26:62:1d:31:92:0c:79:79:1c:8e:cf:ca:7b:
- c1:66:af:a8:74:48:fb:8e:82:c2:9e:2c:99:5c:7b:
- 2d:5d:9b:bc:5b:57:9e:7c:3a:7a:13:ad:f2:a3:18:
- 5b:2b:59:0f:cd:5c:3a:eb:68:33:c6:28:1d:82:d1:
- 50:8b
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Key Usage: critical
- Certificate Sign, CRL Sign
- X509v3 Subject Key Identifier:
- 6B:69:3D:6A:18:42:4A:DD:8F:02:65:39:FD:35:24:86:78:91:16:30
- X509v3 Authority Key Identifier:
- keyid:C0:7A:98:68:8D:89:FB:AB:05:64:0C:11:7D:AA:7D:65:B8:CA:CC:4E
-
- X509v3 Basic Constraints: critical
- CA:TRUE, pathlen:0
- X509v3 CRL Distribution Points:
-
- Full Name:
- URI:http://crl.geotrust.com/crls/gtglobal.crl
-
- Authority Information Access:
- OCSP - URI:http://ocsp.geotrust.com
-
- Signature Algorithm: sha1WithRSAEncryption
- ab:bc:bc:0a:5d:18:94:e3:c1:b1:c3:a8:4c:55:d6:be:b4:98:
- f1:ee:3c:1c:cd:cf:f3:24:24:5c:96:03:27:58:fc:36:ae:a2:
- 2f:8f:f1:fe:da:2b:02:c3:33:bd:c8:dd:48:22:2b:60:0f:a5:
- 03:10:fd:77:f8:d0:ed:96:67:4f:fd:ea:47:20:70:54:dc:a9:
- 0c:55:7e:e1:96:25:8a:d9:b5:da:57:4a:be:8d:8e:49:43:63:
- a5:6c:4e:27:87:25:eb:5b:6d:fe:a2:7f:38:28:e0:36:ab:ad:
- 39:a5:a5:62:c4:b7:5c:58:2c:aa:5d:01:60:a6:62:67:a3:c0:
- c7:62:23:f4:e7:6c:46:ee:b5:d3:80:6a:22:13:d2:2d:3f:74:
- 4f:ea:af:8c:5f:b4:38:9c:db:ae:ce:af:84:1e:a6:f6:34:51:
- 59:79:d3:e3:75:dc:bc:d7:f3:73:df:92:ec:d2:20:59:6f:9c:
- fb:95:f8:92:76:18:0a:7c:0f:2c:a6:ca:de:8a:62:7b:d8:f3:
- ce:5f:68:bd:8f:3e:c1:74:bb:15:72:3a:16:83:a9:0b:e6:4d:
- 99:9c:d8:57:ec:a8:01:51:c7:6f:57:34:5e:ab:4a:2c:42:f6:
- 4f:1c:89:78:de:26:4e:f5:6f:93:4c:15:6b:27:56:4d:00:54:
- 6c:7a:b7:b7
------BEGIN CERTIFICATE-----
-MIID1TCCAr2gAwIBAgIDAjbRMA0GCSqGSIb3DQEBBQUAMEIxCzAJBgNVBAYTAlVT
-MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i
-YWwgQ0EwHhcNMTAwMjE5MjI0NTA1WhcNMjAwMjE4MjI0NTA1WjA8MQswCQYDVQQG
-EwJVUzEXMBUGA1UEChMOR2VvVHJ1c3QsIEluYy4xFDASBgNVBAMTC1JhcGlkU1NM
-IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAx3H4Vsce2cy1rfa0
-l6P7oeYLUF9QqjraD/w9KSRDxhApwfxVQHLuverfn7ZB9EhLyG7+T1cSi1v6kt1e
-6K3z8Buxe037z/3R5fjj3Of1c3/fAUnPjFbBvTfjW761T4uL8NpPx+PdVUdp3/Jb
-ewdPPeWsIcHIHXro5/YPoar1b96oZU8QiZwD84l6pV4BcjPtqelaHnnzh8jfyMX8
-N8iamte4dsywPuf95lTq319SQXhZV63xEtZ/vNWfcNMFbPqjfWdY3SZiHTGSDHl5
-HI7PynvBZq+odEj7joLCniyZXHstXZu8W1eefDp6E63yoxhbK1kPzVw662gzxigd
-gtFQiwIDAQABo4HZMIHWMA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUa2k9ahhC
-St2PAmU5/TUkhniRFjAwHwYDVR0jBBgwFoAUwHqYaI2J+6sFZAwRfap9ZbjKzE4w
-EgYDVR0TAQH/BAgwBgEB/wIBADA6BgNVHR8EMzAxMC+gLaArhilodHRwOi8vY3Js
-Lmdlb3RydXN0LmNvbS9jcmxzL2d0Z2xvYmFsLmNybDA0BggrBgEFBQcBAQQoMCYw
-JAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmdlb3RydXN0LmNvbTANBgkqhkiG9w0B
-AQUFAAOCAQEAq7y8Cl0YlOPBscOoTFXWvrSY8e48HM3P8yQkXJYDJ1j8Nq6iL4/x
-/torAsMzvcjdSCIrYA+lAxD9d/jQ7ZZnT/3qRyBwVNypDFV+4ZYlitm12ldKvo2O
-SUNjpWxOJ4cl61tt/qJ/OCjgNqutOaWlYsS3XFgsql0BYKZiZ6PAx2Ij9OdsRu61
-04BqIhPSLT90T+qvjF+0OJzbrs6vhB6m9jRRWXnT43XcvNfzc9+S7NIgWW+c+5X4
-knYYCnwPLKbK3opie9jzzl9ovY8+wXS7FXI6FoOpC+ZNmZzYV+yoAVHHb1c0XqtK
-LEL2TxyJeN4mTvVvk0wVaydWTQBUbHq3tw==
------END CERTIFICATE-----
-#endif
-static const unsigned char kDERCert2[] = {
- 0x30, 0x82, 0x03, 0xd5, 0x30, 0x82, 0x02, 0xbd, 0xa0, 0x03, 0x02, 0x01,
- 0x02, 0x02, 0x03, 0x02, 0x36, 0xd1, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
- 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x42, 0x31,
- 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53,
- 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0d, 0x47,
- 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x49, 0x6e, 0x63, 0x2e,
- 0x31, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x12, 0x47,
- 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x47, 0x6c, 0x6f, 0x62,
- 0x61, 0x6c, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x30, 0x30,
- 0x32, 0x31, 0x39, 0x32, 0x32, 0x34, 0x35, 0x30, 0x35, 0x5a, 0x17, 0x0d,
- 0x32, 0x30, 0x30, 0x32, 0x31, 0x38, 0x32, 0x32, 0x34, 0x35, 0x30, 0x35,
- 0x5a, 0x30, 0x3c, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06,
- 0x13, 0x02, 0x55, 0x53, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04,
- 0x0a, 0x13, 0x0e, 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x2c,
- 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55,
- 0x04, 0x03, 0x13, 0x0b, 0x52, 0x61, 0x70, 0x69, 0x64, 0x53, 0x53, 0x4c,
- 0x20, 0x43, 0x41, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a,
- 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82,
- 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00,
- 0xc7, 0x71, 0xf8, 0x56, 0xc7, 0x1e, 0xd9, 0xcc, 0xb5, 0xad, 0xf6, 0xb4,
- 0x97, 0xa3, 0xfb, 0xa1, 0xe6, 0x0b, 0x50, 0x5f, 0x50, 0xaa, 0x3a, 0xda,
- 0x0f, 0xfc, 0x3d, 0x29, 0x24, 0x43, 0xc6, 0x10, 0x29, 0xc1, 0xfc, 0x55,
- 0x40, 0x72, 0xee, 0xbd, 0xea, 0xdf, 0x9f, 0xb6, 0x41, 0xf4, 0x48, 0x4b,
- 0xc8, 0x6e, 0xfe, 0x4f, 0x57, 0x12, 0x8b, 0x5b, 0xfa, 0x92, 0xdd, 0x5e,
- 0xe8, 0xad, 0xf3, 0xf0, 0x1b, 0xb1, 0x7b, 0x4d, 0xfb, 0xcf, 0xfd, 0xd1,
- 0xe5, 0xf8, 0xe3, 0xdc, 0xe7, 0xf5, 0x73, 0x7f, 0xdf, 0x01, 0x49, 0xcf,
- 0x8c, 0x56, 0xc1, 0xbd, 0x37, 0xe3, 0x5b, 0xbe, 0xb5, 0x4f, 0x8b, 0x8b,
- 0xf0, 0xda, 0x4f, 0xc7, 0xe3, 0xdd, 0x55, 0x47, 0x69, 0xdf, 0xf2, 0x5b,
- 0x7b, 0x07, 0x4f, 0x3d, 0xe5, 0xac, 0x21, 0xc1, 0xc8, 0x1d, 0x7a, 0xe8,
- 0xe7, 0xf6, 0x0f, 0xa1, 0xaa, 0xf5, 0x6f, 0xde, 0xa8, 0x65, 0x4f, 0x10,
- 0x89, 0x9c, 0x03, 0xf3, 0x89, 0x7a, 0xa5, 0x5e, 0x01, 0x72, 0x33, 0xed,
- 0xa9, 0xe9, 0x5a, 0x1e, 0x79, 0xf3, 0x87, 0xc8, 0xdf, 0xc8, 0xc5, 0xfc,
- 0x37, 0xc8, 0x9a, 0x9a, 0xd7, 0xb8, 0x76, 0xcc, 0xb0, 0x3e, 0xe7, 0xfd,
- 0xe6, 0x54, 0xea, 0xdf, 0x5f, 0x52, 0x41, 0x78, 0x59, 0x57, 0xad, 0xf1,
- 0x12, 0xd6, 0x7f, 0xbc, 0xd5, 0x9f, 0x70, 0xd3, 0x05, 0x6c, 0xfa, 0xa3,
- 0x7d, 0x67, 0x58, 0xdd, 0x26, 0x62, 0x1d, 0x31, 0x92, 0x0c, 0x79, 0x79,
- 0x1c, 0x8e, 0xcf, 0xca, 0x7b, 0xc1, 0x66, 0xaf, 0xa8, 0x74, 0x48, 0xfb,
- 0x8e, 0x82, 0xc2, 0x9e, 0x2c, 0x99, 0x5c, 0x7b, 0x2d, 0x5d, 0x9b, 0xbc,
- 0x5b, 0x57, 0x9e, 0x7c, 0x3a, 0x7a, 0x13, 0xad, 0xf2, 0xa3, 0x18, 0x5b,
- 0x2b, 0x59, 0x0f, 0xcd, 0x5c, 0x3a, 0xeb, 0x68, 0x33, 0xc6, 0x28, 0x1d,
- 0x82, 0xd1, 0x50, 0x8b, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x81, 0xd9,
- 0x30, 0x81, 0xd6, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01,
- 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x1d, 0x06, 0x03, 0x55,
- 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x6b, 0x69, 0x3d, 0x6a, 0x18, 0x42,
- 0x4a, 0xdd, 0x8f, 0x02, 0x65, 0x39, 0xfd, 0x35, 0x24, 0x86, 0x78, 0x91,
- 0x16, 0x30, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30,
- 0x16, 0x80, 0x14, 0xc0, 0x7a, 0x98, 0x68, 0x8d, 0x89, 0xfb, 0xab, 0x05,
- 0x64, 0x0c, 0x11, 0x7d, 0xaa, 0x7d, 0x65, 0xb8, 0xca, 0xcc, 0x4e, 0x30,
- 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30,
- 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x00, 0x30, 0x3a, 0x06, 0x03, 0x55,
- 0x1d, 0x1f, 0x04, 0x33, 0x30, 0x31, 0x30, 0x2f, 0xa0, 0x2d, 0xa0, 0x2b,
- 0x86, 0x29, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c,
- 0x2e, 0x67, 0x65, 0x6f, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63, 0x6f,
- 0x6d, 0x2f, 0x63, 0x72, 0x6c, 0x73, 0x2f, 0x67, 0x74, 0x67, 0x6c, 0x6f,
- 0x62, 0x61, 0x6c, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x34, 0x06, 0x08, 0x2b,
- 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x28, 0x30, 0x26, 0x30,
- 0x24, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86,
- 0x18, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70,
- 0x2e, 0x67, 0x65, 0x6f, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63, 0x6f,
- 0x6d, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
- 0x01, 0x05, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0xab, 0xbc, 0xbc,
- 0x0a, 0x5d, 0x18, 0x94, 0xe3, 0xc1, 0xb1, 0xc3, 0xa8, 0x4c, 0x55, 0xd6,
- 0xbe, 0xb4, 0x98, 0xf1, 0xee, 0x3c, 0x1c, 0xcd, 0xcf, 0xf3, 0x24, 0x24,
- 0x5c, 0x96, 0x03, 0x27, 0x58, 0xfc, 0x36, 0xae, 0xa2, 0x2f, 0x8f, 0xf1,
- 0xfe, 0xda, 0x2b, 0x02, 0xc3, 0x33, 0xbd, 0xc8, 0xdd, 0x48, 0x22, 0x2b,
- 0x60, 0x0f, 0xa5, 0x03, 0x10, 0xfd, 0x77, 0xf8, 0xd0, 0xed, 0x96, 0x67,
- 0x4f, 0xfd, 0xea, 0x47, 0x20, 0x70, 0x54, 0xdc, 0xa9, 0x0c, 0x55, 0x7e,
- 0xe1, 0x96, 0x25, 0x8a, 0xd9, 0xb5, 0xda, 0x57, 0x4a, 0xbe, 0x8d, 0x8e,
- 0x49, 0x43, 0x63, 0xa5, 0x6c, 0x4e, 0x27, 0x87, 0x25, 0xeb, 0x5b, 0x6d,
- 0xfe, 0xa2, 0x7f, 0x38, 0x28, 0xe0, 0x36, 0xab, 0xad, 0x39, 0xa5, 0xa5,
- 0x62, 0xc4, 0xb7, 0x5c, 0x58, 0x2c, 0xaa, 0x5d, 0x01, 0x60, 0xa6, 0x62,
- 0x67, 0xa3, 0xc0, 0xc7, 0x62, 0x23, 0xf4, 0xe7, 0x6c, 0x46, 0xee, 0xb5,
- 0xd3, 0x80, 0x6a, 0x22, 0x13, 0xd2, 0x2d, 0x3f, 0x74, 0x4f, 0xea, 0xaf,
- 0x8c, 0x5f, 0xb4, 0x38, 0x9c, 0xdb, 0xae, 0xce, 0xaf, 0x84, 0x1e, 0xa6,
- 0xf6, 0x34, 0x51, 0x59, 0x79, 0xd3, 0xe3, 0x75, 0xdc, 0xbc, 0xd7, 0xf3,
- 0x73, 0xdf, 0x92, 0xec, 0xd2, 0x20, 0x59, 0x6f, 0x9c, 0xfb, 0x95, 0xf8,
- 0x92, 0x76, 0x18, 0x0a, 0x7c, 0x0f, 0x2c, 0xa6, 0xca, 0xde, 0x8a, 0x62,
- 0x7b, 0xd8, 0xf3, 0xce, 0x5f, 0x68, 0xbd, 0x8f, 0x3e, 0xc1, 0x74, 0xbb,
- 0x15, 0x72, 0x3a, 0x16, 0x83, 0xa9, 0x0b, 0xe6, 0x4d, 0x99, 0x9c, 0xd8,
- 0x57, 0xec, 0xa8, 0x01, 0x51, 0xc7, 0x6f, 0x57, 0x34, 0x5e, 0xab, 0x4a,
- 0x2c, 0x42, 0xf6, 0x4f, 0x1c, 0x89, 0x78, 0xde, 0x26, 0x4e, 0xf5, 0x6f,
- 0x93, 0x4c, 0x15, 0x6b, 0x27, 0x56, 0x4d, 0x00, 0x54, 0x6c, 0x7a, 0xb7,
- 0xb7,
-};
-
-#if 0
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number: 146051 (0x23a83)
- Signature Algorithm: sha256WithRSAEncryption
- Issuer: C=US, O=GeoTrust Inc., CN=GeoTrust Global CA
- Validity
- Not Before: Apr 5 15:15:56 2013 GMT
- Not After : Dec 31 23:59:59 2016 GMT
- Subject: C=US, O=Google Inc, CN=Google Internet Authority G2
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:9c:2a:04:77:5c:d8:50:91:3a:06:a3:82:e0:d8:
- 50:48:bc:89:3f:f1:19:70:1a:88:46:7e:e0:8f:c5:
- f1:89:ce:21:ee:5a:fe:61:0d:b7:32:44:89:a0:74:
- 0b:53:4f:55:a4:ce:82:62:95:ee:eb:59:5f:c6:e1:
- 05:80:12:c4:5e:94:3f:bc:5b:48:38:f4:53:f7:24:
- e6:fb:91:e9:15:c4:cf:f4:53:0d:f4:4a:fc:9f:54:
- de:7d:be:a0:6b:6f:87:c0:d0:50:1f:28:30:03:40:
- da:08:73:51:6c:7f:ff:3a:3c:a7:37:06:8e:bd:4b:
- 11:04:eb:7d:24:de:e6:f9:fc:31:71:fb:94:d5:60:
- f3:2e:4a:af:42:d2:cb:ea:c4:6a:1a:b2:cc:53:dd:
- 15:4b:8b:1f:c8:19:61:1f:cd:9d:a8:3e:63:2b:84:
- 35:69:65:84:c8:19:c5:46:22:f8:53:95:be:e3:80:
- 4a:10:c6:2a:ec:ba:97:20:11:c7:39:99:10:04:a0:
- f0:61:7a:95:25:8c:4e:52:75:e2:b6:ed:08:ca:14:
- fc:ce:22:6a:b3:4e:cf:46:03:97:97:03:7e:c0:b1:
- de:7b:af:45:33:cf:ba:3e:71:b7:de:f4:25:25:c2:
- 0d:35:89:9d:9d:fb:0e:11:79:89:1e:37:c5:af:8e:
- 72:69
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Authority Key Identifier:
- keyid:C0:7A:98:68:8D:89:FB:AB:05:64:0C:11:7D:AA:7D:65:B8:CA:CC:4E
-
- X509v3 Subject Key Identifier:
- 4A:DD:06:16:1B:BC:F6:68:B5:76:F5:81:B6:BB:62:1A:BA:5A:81:2F
- X509v3 Key Usage: critical
- Certificate Sign, CRL Sign
- Authority Information Access:
- OCSP - URI:http://g.symcd.com
-
- X509v3 Basic Constraints: critical
- CA:TRUE, pathlen:0
- X509v3 CRL Distribution Points:
-
- Full Name:
- URI:http://g.symcb.com/crls/gtglobal.crl
-
- X509v3 Certificate Policies:
- Policy: 1.3.6.1.4.1.11129.2.5.1
-
- Signature Algorithm: sha256WithRSAEncryption
- aa:fa:a9:20:cd:6a:67:83:ed:5e:d4:7e:de:1d:c4:7f:e0:25:
- 06:00:c5:24:fb:a9:c8:2d:6d:7e:de:9d:82:65:2c:81:63:34:
- 66:3e:e9:52:c2:08:b4:cb:2f:f7:5f:99:3a:6a:9c:50:7a:85:
- 05:8c:7d:d1:2a:48:84:d3:09:6c:7c:c2:cd:35:9f:f3:82:ee:
- 52:de:68:5f:e4:00:8a:17:20:96:f7:29:8d:9a:4d:cb:a8:de:
- 86:c8:0d:6f:56:87:03:7d:03:3f:dc:fa:79:7d:21:19:f9:c8:
- 3a:2f:51:76:8c:c7:41:92:71:8f:25:ce:37:f8:4a:4c:00:23:
- ef:c4:35:10:ae:e0:23:80:73:7c:4d:34:2e:c8:6e:90:d6:10:
- 1e:99:84:73:1a:70:f2:ed:55:0e:ee:17:06:ea:67:ee:32:eb:
- 2c:dd:67:07:3f:f6:8b:c2:70:de:5b:00:e6:bb:1b:d3:36:1a:
- 22:6c:6c:b0:35:42:6c:90:09:3d:93:e9:64:09:22:0e:85:06:
- 9f:c2:73:21:d3:e6:5f:80:e4:8d:85:22:3a:73:03:b1:60:8e:
- ae:68:e2:f4:3e:97:e7:60:12:09:68:36:de:3a:d6:e2:43:95:
- 5b:37:81:92:81:1f:bb:8d:d7:ad:52:64:16:57:96:d9:5e:34:
- 7e:c8:35:d8
------BEGIN CERTIFICATE-----
-MIID8DCCAtigAwIBAgIDAjqDMA0GCSqGSIb3DQEBCwUAMEIxCzAJBgNVBAYTAlVT
-MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i
-YWwgQ0EwHhcNMTMwNDA1MTUxNTU2WhcNMTYxMjMxMjM1OTU5WjBJMQswCQYDVQQG
-EwJVUzETMBEGA1UEChMKR29vZ2xlIEluYzElMCMGA1UEAxMcR29vZ2xlIEludGVy
-bmV0IEF1dGhvcml0eSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
-AJwqBHdc2FCROgajguDYUEi8iT/xGXAaiEZ+4I/F8YnOIe5a/mENtzJEiaB0C1NP
-VaTOgmKV7utZX8bhBYASxF6UP7xbSDj0U/ck5vuR6RXEz/RTDfRK/J9U3n2+oGtv
-h8DQUB8oMANA2ghzUWx//zo8pzcGjr1LEQTrfSTe5vn8MXH7lNVg8y5Kr0LSy+rE
-ahqyzFPdFUuLH8gZYR/Nnag+YyuENWllhMgZxUYi+FOVvuOAShDGKuy6lyARxzmZ
-EASg8GF6lSWMTlJ14rbtCMoU/M4iarNOz0YDl5cDfsCx3nuvRTPPuj5xt970JSXC
-DTWJnZ37DhF5iR43xa+OcmkCAwEAAaOB5zCB5DAfBgNVHSMEGDAWgBTAephojYn7
-qwVkDBF9qn1luMrMTjAdBgNVHQ4EFgQUSt0GFhu89mi1dvWBtrtiGrpagS8wDgYD
-VR0PAQH/BAQDAgEGMC4GCCsGAQUFBwEBBCIwIDAeBggrBgEFBQcwAYYSaHR0cDov
-L2cuc3ltY2QuY29tMBIGA1UdEwEB/wQIMAYBAf8CAQAwNQYDVR0fBC4wLDAqoCig
-JoYkaHR0cDovL2cuc3ltY2IuY29tL2NybHMvZ3RnbG9iYWwuY3JsMBcGA1UdIAQQ
-MA4wDAYKKwYBBAHWeQIFATANBgkqhkiG9w0BAQsFAAOCAQEAqvqpIM1qZ4PtXtR+
-3h3Ef+AlBgDFJPupyC1tft6dgmUsgWM0Zj7pUsIItMsv91+ZOmqcUHqFBYx90SpI
-hNMJbHzCzTWf84LuUt5oX+QAihcglvcpjZpNy6jehsgNb1aHA30DP9z6eX0hGfnI
-Oi9RdozHQZJxjyXON/hKTAAj78Q1EK7gI4BzfE00LshukNYQHpmEcxpw8u1VDu4X
-Bupn7jLrLN1nBz/2i8Jw3lsA5rsb0zYaImxssDVCbJAJPZPpZAkiDoUGn8JzIdPm
-X4DkjYUiOnMDsWCOrmji9D6X52ASCWg23jrW4kOVWzeBkoEfu43XrVJkFleW2V40
-fsg12A==
------END CERTIFICATE-----
-#endif
-static const unsigned char kDERCert3[] = {
- 0x30, 0x82, 0x03, 0xf0, 0x30, 0x82, 0x02, 0xd8, 0xa0, 0x03, 0x02, 0x01,
- 0x02, 0x02, 0x03, 0x02, 0x3a, 0x83, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
- 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x42, 0x31,
- 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53,
- 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0d, 0x47,
- 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x49, 0x6e, 0x63, 0x2e,
- 0x31, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x12, 0x47,
- 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x47, 0x6c, 0x6f, 0x62,
- 0x61, 0x6c, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x33, 0x30,
- 0x34, 0x30, 0x35, 0x31, 0x35, 0x31, 0x35, 0x35, 0x36, 0x5a, 0x17, 0x0d,
- 0x31, 0x36, 0x31, 0x32, 0x33, 0x31, 0x32, 0x33, 0x35, 0x39, 0x35, 0x39,
- 0x5a, 0x30, 0x49, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06,
- 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04,
- 0x0a, 0x13, 0x0a, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x20, 0x49, 0x6e,
- 0x63, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x1c,
- 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x74, 0x65, 0x72,
- 0x6e, 0x65, 0x74, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74,
- 0x79, 0x20, 0x47, 0x32, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09,
- 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03,
- 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01,
- 0x00, 0x9c, 0x2a, 0x04, 0x77, 0x5c, 0xd8, 0x50, 0x91, 0x3a, 0x06, 0xa3,
- 0x82, 0xe0, 0xd8, 0x50, 0x48, 0xbc, 0x89, 0x3f, 0xf1, 0x19, 0x70, 0x1a,
- 0x88, 0x46, 0x7e, 0xe0, 0x8f, 0xc5, 0xf1, 0x89, 0xce, 0x21, 0xee, 0x5a,
- 0xfe, 0x61, 0x0d, 0xb7, 0x32, 0x44, 0x89, 0xa0, 0x74, 0x0b, 0x53, 0x4f,
- 0x55, 0xa4, 0xce, 0x82, 0x62, 0x95, 0xee, 0xeb, 0x59, 0x5f, 0xc6, 0xe1,
- 0x05, 0x80, 0x12, 0xc4, 0x5e, 0x94, 0x3f, 0xbc, 0x5b, 0x48, 0x38, 0xf4,
- 0x53, 0xf7, 0x24, 0xe6, 0xfb, 0x91, 0xe9, 0x15, 0xc4, 0xcf, 0xf4, 0x53,
- 0x0d, 0xf4, 0x4a, 0xfc, 0x9f, 0x54, 0xde, 0x7d, 0xbe, 0xa0, 0x6b, 0x6f,
- 0x87, 0xc0, 0xd0, 0x50, 0x1f, 0x28, 0x30, 0x03, 0x40, 0xda, 0x08, 0x73,
- 0x51, 0x6c, 0x7f, 0xff, 0x3a, 0x3c, 0xa7, 0x37, 0x06, 0x8e, 0xbd, 0x4b,
- 0x11, 0x04, 0xeb, 0x7d, 0x24, 0xde, 0xe6, 0xf9, 0xfc, 0x31, 0x71, 0xfb,
- 0x94, 0xd5, 0x60, 0xf3, 0x2e, 0x4a, 0xaf, 0x42, 0xd2, 0xcb, 0xea, 0xc4,
- 0x6a, 0x1a, 0xb2, 0xcc, 0x53, 0xdd, 0x15, 0x4b, 0x8b, 0x1f, 0xc8, 0x19,
- 0x61, 0x1f, 0xcd, 0x9d, 0xa8, 0x3e, 0x63, 0x2b, 0x84, 0x35, 0x69, 0x65,
- 0x84, 0xc8, 0x19, 0xc5, 0x46, 0x22, 0xf8, 0x53, 0x95, 0xbe, 0xe3, 0x80,
- 0x4a, 0x10, 0xc6, 0x2a, 0xec, 0xba, 0x97, 0x20, 0x11, 0xc7, 0x39, 0x99,
- 0x10, 0x04, 0xa0, 0xf0, 0x61, 0x7a, 0x95, 0x25, 0x8c, 0x4e, 0x52, 0x75,
- 0xe2, 0xb6, 0xed, 0x08, 0xca, 0x14, 0xfc, 0xce, 0x22, 0x6a, 0xb3, 0x4e,
- 0xcf, 0x46, 0x03, 0x97, 0x97, 0x03, 0x7e, 0xc0, 0xb1, 0xde, 0x7b, 0xaf,
- 0x45, 0x33, 0xcf, 0xba, 0x3e, 0x71, 0xb7, 0xde, 0xf4, 0x25, 0x25, 0xc2,
- 0x0d, 0x35, 0x89, 0x9d, 0x9d, 0xfb, 0x0e, 0x11, 0x79, 0x89, 0x1e, 0x37,
- 0xc5, 0xaf, 0x8e, 0x72, 0x69, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x81,
- 0xe7, 0x30, 0x81, 0xe4, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04,
- 0x18, 0x30, 0x16, 0x80, 0x14, 0xc0, 0x7a, 0x98, 0x68, 0x8d, 0x89, 0xfb,
- 0xab, 0x05, 0x64, 0x0c, 0x11, 0x7d, 0xaa, 0x7d, 0x65, 0xb8, 0xca, 0xcc,
- 0x4e, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14,
- 0x4a, 0xdd, 0x06, 0x16, 0x1b, 0xbc, 0xf6, 0x68, 0xb5, 0x76, 0xf5, 0x81,
- 0xb6, 0xbb, 0x62, 0x1a, 0xba, 0x5a, 0x81, 0x2f, 0x30, 0x0e, 0x06, 0x03,
- 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06,
- 0x30, 0x2e, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01,
- 0x04, 0x22, 0x30, 0x20, 0x30, 0x1e, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05,
- 0x05, 0x07, 0x30, 0x01, 0x86, 0x12, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f,
- 0x2f, 0x67, 0x2e, 0x73, 0x79, 0x6d, 0x63, 0x64, 0x2e, 0x63, 0x6f, 0x6d,
- 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08,
- 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x00, 0x30, 0x35, 0x06, 0x03,
- 0x55, 0x1d, 0x1f, 0x04, 0x2e, 0x30, 0x2c, 0x30, 0x2a, 0xa0, 0x28, 0xa0,
- 0x26, 0x86, 0x24, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x67, 0x2e,
- 0x73, 0x79, 0x6d, 0x63, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x72,
- 0x6c, 0x73, 0x2f, 0x67, 0x74, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x2e,
- 0x63, 0x72, 0x6c, 0x30, 0x17, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x10,
- 0x30, 0x0e, 0x30, 0x0c, 0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01, 0xd6,
- 0x79, 0x02, 0x05, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
- 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00,
- 0xaa, 0xfa, 0xa9, 0x20, 0xcd, 0x6a, 0x67, 0x83, 0xed, 0x5e, 0xd4, 0x7e,
- 0xde, 0x1d, 0xc4, 0x7f, 0xe0, 0x25, 0x06, 0x00, 0xc5, 0x24, 0xfb, 0xa9,
- 0xc8, 0x2d, 0x6d, 0x7e, 0xde, 0x9d, 0x82, 0x65, 0x2c, 0x81, 0x63, 0x34,
- 0x66, 0x3e, 0xe9, 0x52, 0xc2, 0x08, 0xb4, 0xcb, 0x2f, 0xf7, 0x5f, 0x99,
- 0x3a, 0x6a, 0x9c, 0x50, 0x7a, 0x85, 0x05, 0x8c, 0x7d, 0xd1, 0x2a, 0x48,
- 0x84, 0xd3, 0x09, 0x6c, 0x7c, 0xc2, 0xcd, 0x35, 0x9f, 0xf3, 0x82, 0xee,
- 0x52, 0xde, 0x68, 0x5f, 0xe4, 0x00, 0x8a, 0x17, 0x20, 0x96, 0xf7, 0x29,
- 0x8d, 0x9a, 0x4d, 0xcb, 0xa8, 0xde, 0x86, 0xc8, 0x0d, 0x6f, 0x56, 0x87,
- 0x03, 0x7d, 0x03, 0x3f, 0xdc, 0xfa, 0x79, 0x7d, 0x21, 0x19, 0xf9, 0xc8,
- 0x3a, 0x2f, 0x51, 0x76, 0x8c, 0xc7, 0x41, 0x92, 0x71, 0x8f, 0x25, 0xce,
- 0x37, 0xf8, 0x4a, 0x4c, 0x00, 0x23, 0xef, 0xc4, 0x35, 0x10, 0xae, 0xe0,
- 0x23, 0x80, 0x73, 0x7c, 0x4d, 0x34, 0x2e, 0xc8, 0x6e, 0x90, 0xd6, 0x10,
- 0x1e, 0x99, 0x84, 0x73, 0x1a, 0x70, 0xf2, 0xed, 0x55, 0x0e, 0xee, 0x17,
- 0x06, 0xea, 0x67, 0xee, 0x32, 0xeb, 0x2c, 0xdd, 0x67, 0x07, 0x3f, 0xf6,
- 0x8b, 0xc2, 0x70, 0xde, 0x5b, 0x00, 0xe6, 0xbb, 0x1b, 0xd3, 0x36, 0x1a,
- 0x22, 0x6c, 0x6c, 0xb0, 0x35, 0x42, 0x6c, 0x90, 0x09, 0x3d, 0x93, 0xe9,
- 0x64, 0x09, 0x22, 0x0e, 0x85, 0x06, 0x9f, 0xc2, 0x73, 0x21, 0xd3, 0xe6,
- 0x5f, 0x80, 0xe4, 0x8d, 0x85, 0x22, 0x3a, 0x73, 0x03, 0xb1, 0x60, 0x8e,
- 0xae, 0x68, 0xe2, 0xf4, 0x3e, 0x97, 0xe7, 0x60, 0x12, 0x09, 0x68, 0x36,
- 0xde, 0x3a, 0xd6, 0xe2, 0x43, 0x95, 0x5b, 0x37, 0x81, 0x92, 0x81, 0x1f,
- 0xbb, 0x8d, 0xd7, 0xad, 0x52, 0x64, 0x16, 0x57, 0x96, 0xd9, 0x5e, 0x34,
- 0x7e, 0xc8, 0x35, 0xd8,
-};
-
-#if 0
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number: 120033005 (0x7278eed)
- Signature Algorithm: sha1WithRSAEncryption
- Issuer: C=US, O=GTE Corporation, OU=GTE CyberTrust Solutions, Inc., CN=GTE CyberTrust Global Root
- Validity
- Not Before: Apr 18 16:36:18 2012 GMT
- Not After : Aug 13 16:35:17 2018 GMT
- Subject: C=IE, O=Baltimore, OU=CyberTrust, CN=Baltimore CyberTrust Root
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:a3:04:bb:22:ab:98:3d:57:e8:26:72:9a:b5:79:
- d4:29:e2:e1:e8:95:80:b1:b0:e3:5b:8e:2b:29:9a:
- 64:df:a1:5d:ed:b0:09:05:6d:db:28:2e:ce:62:a2:
- 62:fe:b4:88:da:12:eb:38:eb:21:9d:c0:41:2b:01:
- 52:7b:88:77:d3:1c:8f:c7:ba:b9:88:b5:6a:09:e7:
- 73:e8:11:40:a7:d1:cc:ca:62:8d:2d:e5:8f:0b:a6:
- 50:d2:a8:50:c3:28:ea:f5:ab:25:87:8a:9a:96:1c:
- a9:67:b8:3f:0c:d5:f7:f9:52:13:2f:c2:1b:d5:70:
- 70:f0:8f:c0:12:ca:06:cb:9a:e1:d9:ca:33:7a:77:
- d6:f8:ec:b9:f1:68:44:42:48:13:d2:c0:c2:a4:ae:
- 5e:60:fe:b6:a6:05:fc:b4:dd:07:59:02:d4:59:18:
- 98:63:f5:a5:63:e0:90:0c:7d:5d:b2:06:7a:f3:85:
- ea:eb:d4:03:ae:5e:84:3e:5f:ff:15:ed:69:bc:f9:
- 39:36:72:75:cf:77:52:4d:f3:c9:90:2c:b9:3d:e5:
- c9:23:53:3f:1f:24:98:21:5c:07:99:29:bd:c6:3a:
- ec:e7:6e:86:3a:6b:97:74:63:33:bd:68:18:31:f0:
- 78:8d:76:bf:fc:9e:8e:5d:2a:86:a7:4d:90:dc:27:
- 1a:39
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Basic Constraints: critical
- CA:TRUE, pathlen:3
- X509v3 Certificate Policies:
- Policy: X509v3 Any Policy
- CPS: http://cybertrust.omniroot.com/repository
-
- X509v3 Key Usage: critical
- Certificate Sign, CRL Sign
- X509v3 Authority Key Identifier:
- DirName:/C=US/O=GTE Corporation/OU=GTE CyberTrust Solutions, Inc./CN=GTE CyberTrust Global Root
- serial:01:A5
-
- X509v3 CRL Distribution Points:
-
- Full Name:
- URI:http://www.public-trust.com/cgi-bin/CRL/2018/cdp.crl
-
- Signature Algorithm: sha1WithRSAEncryption
- 93:1d:fe:8b:ae:46:ec:cb:a9:0f:ab:e5:ef:ca:b2:68:16:68:
- d8:8f:fa:13:a9:af:b3:cb:2d:e7:4b:6e:8e:69:2a:c2:2b:10:
- 0a:8d:f6:ae:73:b6:b9:fb:14:fd:5f:6d:b8:50:b6:c4:8a:d6:
- 40:7e:d7:c3:cb:73:dc:c9:5d:5b:af:b0:41:b5:37:eb:ea:dc:
- 20:91:c4:34:6a:f4:a1:f3:96:9d:37:86:97:e1:71:a4:dd:7d:
- fa:44:84:94:ae:d7:09:04:22:76:0f:64:51:35:a9:24:0f:f9:
- 0b:db:32:da:c2:fe:c1:b9:2a:5c:7a:27:13:ca:b1:48:3a:71:
- d0:43
------BEGIN CERTIFICATE-----
-MIIEFTCCA36gAwIBAgIEByeO7TANBgkqhkiG9w0BAQUFADB1MQswCQYDVQQGEwJV
-UzEYMBYGA1UEChMPR1RFIENvcnBvcmF0aW9uMScwJQYDVQQLEx5HVEUgQ3liZXJU
-cnVzdCBTb2x1dGlvbnMsIEluYy4xIzAhBgNVBAMTGkdURSBDeWJlclRydXN0IEds
-b2JhbCBSb290MB4XDTEyMDQxODE2MzYxOFoXDTE4MDgxMzE2MzUxN1owWjELMAkG
-A1UEBhMCSUUxEjAQBgNVBAoTCUJhbHRpbW9yZTETMBEGA1UECxMKQ3liZXJUcnVz
-dDEiMCAGA1UEAxMZQmFsdGltb3JlIEN5YmVyVHJ1c3QgUm9vdDCCASIwDQYJKoZI
-hvcNAQEBBQADggEPADCCAQoCggEBAKMEuyKrmD1X6CZymrV51Cni4eiVgLGw41uO
-KymaZN+hXe2wCQVt2yguzmKiYv60iNoS6zjrIZ3AQSsBUnuId9Mcj8e6uYi1agnn
-c+gRQKfRzMpijS3ljwumUNKoUMMo6vWrJYeKmpYcqWe4PwzV9/lSEy/CG9VwcPCP
-wBLKBsua4dnKM3p31vjsufFoREJIE9LAwqSuXmD+tqYF/LTdB1kC1FkYmGP1pWPg
-kAx9XbIGevOF6uvUA65ehD5f/xXtabz5OTZydc93Uk3zyZAsuT3lySNTPx8kmCFc
-B5kpvcY67Oduhjprl3RjM71oGDHweI12v/yejl0qhqdNkNwnGjkCAwEAAaOCAUcw
-ggFDMBIGA1UdEwEB/wQIMAYBAf8CAQMwSgYDVR0gBEMwQTA/BgRVHSAAMDcwNQYI
-KwYBBQUHAgEWKWh0dHA6Ly9jeWJlcnRydXN0Lm9tbmlyb290LmNvbS9yZXBvc2l0
-b3J5MA4GA1UdDwEB/wQEAwIBBjCBiQYDVR0jBIGBMH+heaR3MHUxCzAJBgNVBAYT
-AlVTMRgwFgYDVQQKEw9HVEUgQ29ycG9yYXRpb24xJzAlBgNVBAsTHkdURSBDeWJl
-clRydXN0IFNvbHV0aW9ucywgSW5jLjEjMCEGA1UEAxMaR1RFIEN5YmVyVHJ1c3Qg
-R2xvYmFsIFJvb3SCAgGlMEUGA1UdHwQ+MDwwOqA4oDaGNGh0dHA6Ly93d3cucHVi
-bGljLXRydXN0LmNvbS9jZ2ktYmluL0NSTC8yMDE4L2NkcC5jcmwwDQYJKoZIhvcN
-AQEFBQADgYEAkx3+i65G7MupD6vl78qyaBZo2I/6E6mvs8st50tujmkqwisQCo32
-rnO2ufsU/V9tuFC2xIrWQH7Xw8tz3MldW6+wQbU36+rcIJHENGr0ofOWnTeGl+Fx
-pN19+kSElK7XCQQidg9kUTWpJA/5C9sy2sL+wbkqXHonE8qxSDpx0EM=
------END CERTIFICATE-----
-#endif
-static const unsigned char kDERCert4[] = {
- 0x30, 0x82, 0x04, 0x15, 0x30, 0x82, 0x03, 0x7e, 0xa0, 0x03, 0x02, 0x01,
- 0x02, 0x02, 0x04, 0x07, 0x27, 0x8e, 0xed, 0x30, 0x0d, 0x06, 0x09, 0x2a,
- 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x75,
- 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55,
- 0x53, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0f,
- 0x47, 0x54, 0x45, 0x20, 0x43, 0x6f, 0x72, 0x70, 0x6f, 0x72, 0x61, 0x74,
- 0x69, 0x6f, 0x6e, 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x0b,
- 0x13, 0x1e, 0x47, 0x54, 0x45, 0x20, 0x43, 0x79, 0x62, 0x65, 0x72, 0x54,
- 0x72, 0x75, 0x73, 0x74, 0x20, 0x53, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f,
- 0x6e, 0x73, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x23, 0x30, 0x21,
- 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x1a, 0x47, 0x54, 0x45, 0x20, 0x43,
- 0x79, 0x62, 0x65, 0x72, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x47, 0x6c,
- 0x6f, 0x62, 0x61, 0x6c, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x30, 0x1e, 0x17,
- 0x0d, 0x31, 0x32, 0x30, 0x34, 0x31, 0x38, 0x31, 0x36, 0x33, 0x36, 0x31,
- 0x38, 0x5a, 0x17, 0x0d, 0x31, 0x38, 0x30, 0x38, 0x31, 0x33, 0x31, 0x36,
- 0x33, 0x35, 0x31, 0x37, 0x5a, 0x30, 0x5a, 0x31, 0x0b, 0x30, 0x09, 0x06,
- 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x49, 0x45, 0x31, 0x12, 0x30, 0x10,
- 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x09, 0x42, 0x61, 0x6c, 0x74, 0x69,
- 0x6d, 0x6f, 0x72, 0x65, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04,
- 0x0b, 0x13, 0x0a, 0x43, 0x79, 0x62, 0x65, 0x72, 0x54, 0x72, 0x75, 0x73,
- 0x74, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x19,
- 0x42, 0x61, 0x6c, 0x74, 0x69, 0x6d, 0x6f, 0x72, 0x65, 0x20, 0x43, 0x79,
- 0x62, 0x65, 0x72, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x52, 0x6f, 0x6f,
- 0x74, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48,
- 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f,
- 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xa3, 0x04,
- 0xbb, 0x22, 0xab, 0x98, 0x3d, 0x57, 0xe8, 0x26, 0x72, 0x9a, 0xb5, 0x79,
- 0xd4, 0x29, 0xe2, 0xe1, 0xe8, 0x95, 0x80, 0xb1, 0xb0, 0xe3, 0x5b, 0x8e,
- 0x2b, 0x29, 0x9a, 0x64, 0xdf, 0xa1, 0x5d, 0xed, 0xb0, 0x09, 0x05, 0x6d,
- 0xdb, 0x28, 0x2e, 0xce, 0x62, 0xa2, 0x62, 0xfe, 0xb4, 0x88, 0xda, 0x12,
- 0xeb, 0x38, 0xeb, 0x21, 0x9d, 0xc0, 0x41, 0x2b, 0x01, 0x52, 0x7b, 0x88,
- 0x77, 0xd3, 0x1c, 0x8f, 0xc7, 0xba, 0xb9, 0x88, 0xb5, 0x6a, 0x09, 0xe7,
- 0x73, 0xe8, 0x11, 0x40, 0xa7, 0xd1, 0xcc, 0xca, 0x62, 0x8d, 0x2d, 0xe5,
- 0x8f, 0x0b, 0xa6, 0x50, 0xd2, 0xa8, 0x50, 0xc3, 0x28, 0xea, 0xf5, 0xab,
- 0x25, 0x87, 0x8a, 0x9a, 0x96, 0x1c, 0xa9, 0x67, 0xb8, 0x3f, 0x0c, 0xd5,
- 0xf7, 0xf9, 0x52, 0x13, 0x2f, 0xc2, 0x1b, 0xd5, 0x70, 0x70, 0xf0, 0x8f,
- 0xc0, 0x12, 0xca, 0x06, 0xcb, 0x9a, 0xe1, 0xd9, 0xca, 0x33, 0x7a, 0x77,
- 0xd6, 0xf8, 0xec, 0xb9, 0xf1, 0x68, 0x44, 0x42, 0x48, 0x13, 0xd2, 0xc0,
- 0xc2, 0xa4, 0xae, 0x5e, 0x60, 0xfe, 0xb6, 0xa6, 0x05, 0xfc, 0xb4, 0xdd,
- 0x07, 0x59, 0x02, 0xd4, 0x59, 0x18, 0x98, 0x63, 0xf5, 0xa5, 0x63, 0xe0,
- 0x90, 0x0c, 0x7d, 0x5d, 0xb2, 0x06, 0x7a, 0xf3, 0x85, 0xea, 0xeb, 0xd4,
- 0x03, 0xae, 0x5e, 0x84, 0x3e, 0x5f, 0xff, 0x15, 0xed, 0x69, 0xbc, 0xf9,
- 0x39, 0x36, 0x72, 0x75, 0xcf, 0x77, 0x52, 0x4d, 0xf3, 0xc9, 0x90, 0x2c,
- 0xb9, 0x3d, 0xe5, 0xc9, 0x23, 0x53, 0x3f, 0x1f, 0x24, 0x98, 0x21, 0x5c,
- 0x07, 0x99, 0x29, 0xbd, 0xc6, 0x3a, 0xec, 0xe7, 0x6e, 0x86, 0x3a, 0x6b,
- 0x97, 0x74, 0x63, 0x33, 0xbd, 0x68, 0x18, 0x31, 0xf0, 0x78, 0x8d, 0x76,
- 0xbf, 0xfc, 0x9e, 0x8e, 0x5d, 0x2a, 0x86, 0xa7, 0x4d, 0x90, 0xdc, 0x27,
- 0x1a, 0x39, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x47, 0x30,
- 0x82, 0x01, 0x43, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01,
- 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x03, 0x30,
- 0x4a, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x43, 0x30, 0x41, 0x30, 0x3f,
- 0x06, 0x04, 0x55, 0x1d, 0x20, 0x00, 0x30, 0x37, 0x30, 0x35, 0x06, 0x08,
- 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x29, 0x68, 0x74,
- 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x79, 0x62, 0x65, 0x72, 0x74, 0x72,
- 0x75, 0x73, 0x74, 0x2e, 0x6f, 0x6d, 0x6e, 0x69, 0x72, 0x6f, 0x6f, 0x74,
- 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74,
- 0x6f, 0x72, 0x79, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01,
- 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x81, 0x89, 0x06, 0x03,
- 0x55, 0x1d, 0x23, 0x04, 0x81, 0x81, 0x30, 0x7f, 0xa1, 0x79, 0xa4, 0x77,
- 0x30, 0x75, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
- 0x02, 0x55, 0x53, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x0a,
- 0x13, 0x0f, 0x47, 0x54, 0x45, 0x20, 0x43, 0x6f, 0x72, 0x70, 0x6f, 0x72,
- 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, 0x55,
- 0x04, 0x0b, 0x13, 0x1e, 0x47, 0x54, 0x45, 0x20, 0x43, 0x79, 0x62, 0x65,
- 0x72, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x53, 0x6f, 0x6c, 0x75, 0x74,
- 0x69, 0x6f, 0x6e, 0x73, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x23,
- 0x30, 0x21, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x1a, 0x47, 0x54, 0x45,
- 0x20, 0x43, 0x79, 0x62, 0x65, 0x72, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20,
- 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x82,
- 0x02, 0x01, 0xa5, 0x30, 0x45, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x3e,
- 0x30, 0x3c, 0x30, 0x3a, 0xa0, 0x38, 0xa0, 0x36, 0x86, 0x34, 0x68, 0x74,
- 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x70, 0x75, 0x62,
- 0x6c, 0x69, 0x63, 0x2d, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63, 0x6f,
- 0x6d, 0x2f, 0x63, 0x67, 0x69, 0x2d, 0x62, 0x69, 0x6e, 0x2f, 0x43, 0x52,
- 0x4c, 0x2f, 0x32, 0x30, 0x31, 0x38, 0x2f, 0x63, 0x64, 0x70, 0x2e, 0x63,
- 0x72, 0x6c, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
- 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x81, 0x81, 0x00, 0x93, 0x1d, 0xfe,
- 0x8b, 0xae, 0x46, 0xec, 0xcb, 0xa9, 0x0f, 0xab, 0xe5, 0xef, 0xca, 0xb2,
- 0x68, 0x16, 0x68, 0xd8, 0x8f, 0xfa, 0x13, 0xa9, 0xaf, 0xb3, 0xcb, 0x2d,
- 0xe7, 0x4b, 0x6e, 0x8e, 0x69, 0x2a, 0xc2, 0x2b, 0x10, 0x0a, 0x8d, 0xf6,
- 0xae, 0x73, 0xb6, 0xb9, 0xfb, 0x14, 0xfd, 0x5f, 0x6d, 0xb8, 0x50, 0xb6,
- 0xc4, 0x8a, 0xd6, 0x40, 0x7e, 0xd7, 0xc3, 0xcb, 0x73, 0xdc, 0xc9, 0x5d,
- 0x5b, 0xaf, 0xb0, 0x41, 0xb5, 0x37, 0xeb, 0xea, 0xdc, 0x20, 0x91, 0xc4,
- 0x34, 0x6a, 0xf4, 0xa1, 0xf3, 0x96, 0x9d, 0x37, 0x86, 0x97, 0xe1, 0x71,
- 0xa4, 0xdd, 0x7d, 0xfa, 0x44, 0x84, 0x94, 0xae, 0xd7, 0x09, 0x04, 0x22,
- 0x76, 0x0f, 0x64, 0x51, 0x35, 0xa9, 0x24, 0x0f, 0xf9, 0x0b, 0xdb, 0x32,
- 0xda, 0xc2, 0xfe, 0xc1, 0xb9, 0x2a, 0x5c, 0x7a, 0x27, 0x13, 0xca, 0xb1,
- 0x48, 0x3a, 0x71, 0xd0, 0x43,
-};
-
-#if 0
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number: 146041 (0x23a79)
- Signature Algorithm: sha256WithRSAEncryption
- Issuer: C=US, O=GeoTrust Inc., CN=GeoTrust Global CA
- Validity
- Not Before: Sep 8 20:41:10 2014 GMT
- Not After : May 20 20:41:10 2022 GMT
- Subject: C=US, O=GeoTrust Inc., CN=GeoTrust SSL CA - G4
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:9a:7d:98:68:11:40:c1:5f:72:ec:55:b3:b1:63:
- f3:32:22:72:91:c6:16:05:bb:08:82:31:b4:f6:ee:
- d4:18:39:11:2f:2e:da:47:fe:51:31:6e:5b:f2:a9:
- 0a:eb:2f:bb:f5:61:59:65:57:02:cd:80:ff:c7:70:
- 32:54:89:fd:db:ae:99:72:d4:4f:0c:26:b9:2e:63:
- 30:7d:de:14:5b:6a:d7:52:78:21:f9:bf:bc:50:d5:
- 54:12:59:d8:b5:36:d9:21:47:b8:3f:6a:58:1d:8c:
- 72:e1:97:95:d3:e1:45:a8:f1:5a:e5:be:fe:e3:53:
- 7c:a5:f0:52:e0:cf:39:94:0c:19:71:f2:c0:25:07:
- 48:7d:1c:e6:f1:39:25:2f:98:79:43:e8:18:72:f4:
- 65:86:98:5a:00:04:47:da:4b:58:1e:7c:86:b1:4b:
- 35:a6:20:00:1c:cd:1b:3b:22:5d:d1:93:28:33:12:
- 23:94:08:aa:c3:3a:f5:d1:c6:8c:7e:99:d3:18:a0:
- ad:9d:18:cf:49:ad:10:03:f7:99:33:26:86:46:9a:
- 2f:a0:ba:6c:6e:c8:88:02:b7:6e:fa:7a:9e:98:4a:
- ee:9a:31:7d:19:14:60:0c:ec:8f:20:23:3c:da:97:
- 26:b6:ea:80:6c:8a:57:9e:20:ee:6f:17:25:4a:32:
- ad:35
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Authority Key Identifier:
- keyid:C0:7A:98:68:8D:89:FB:AB:05:64:0C:11:7D:AA:7D:65:B8:CA:CC:4E
-
- X509v3 Subject Key Identifier:
- AC:32:ED:5A:C9:E0:DE:30:9C:90:58:55:26:63:F6:72:A6:54:5F:E3
- X509v3 Basic Constraints: critical
- CA:TRUE, pathlen:0
- X509v3 Key Usage: critical
- Certificate Sign, CRL Sign
- X509v3 CRL Distribution Points:
-
- Full Name:
- URI:http://g.symcb.com/crls/gtglobal.crl
-
- Authority Information Access:
- OCSP - URI:http://g.symcd.com
-
- X509v3 Certificate Policies:
- Policy: 2.16.840.1.113733.1.7.54
- CPS: http://www.geotrust.com/resources/cps
-
- Signature Algorithm: sha256WithRSAEncryption
- 61:40:ad:21:0f:03:bb:95:dc:89:fc:a3:cb:05:71:e9:1c:59:
- 97:35:c2:fa:6b:05:a4:16:c6:56:46:37:74:1b:1b:f1:3e:2c:
- e8:37:19:b7:94:d2:0f:0e:c5:bf:14:07:2b:34:cd:5b:b4:8d:
- c7:56:9d:19:fc:02:b4:9e:90:31:fa:a4:44:c6:75:dd:dd:1f:
- 25:54:a3:30:4c:ac:db:fe:c4:88:f7:31:26:18:47:ae:4c:20:
- 19:1a:c7:ae:3e:98:0a:16:3d:d2:c2:a6:5d:0d:2e:29:7d:b2:
- 9d:c7:41:32:17:ca:9d:ae:39:bf:91:98:de:e7:44:e2:95:9c:
- 94:5c:6c:42:1b:59:c9:7b:68:13:a8:96:09:74:ee:40:14:a4:
- d5:d7:c9:7b:33:a3:0f:5a:69:9c:1a:fa:6f:12:47:1c:df:1e:
- 4c:70:4e:6d:dd:fe:1c:87:b5:9d:e1:54:07:09:8a:cd:be:aa:
- a8:46:78:6e:16:f2:e7:91:0e:c3:af:da:76:00:d1:d8:a2:46:
- 24:03:a5:1a:85:81:56:83:63:27:ba:90:8e:f9:62:11:ba:a7:
- 7c:90:a9:1a:66:b4:c5:bc:8f:29:41:ab:eb:8d:99:a6:cc:91:
- 64:ba:dc:c6:a6:4c:b3:b4:23:26:51:72:56:f9:f3:74:55:9f:
- 25:75:4f:2b
------BEGIN CERTIFICATE-----
-MIIEIjCCAwqgAwIBAgIDAjp5MA0GCSqGSIb3DQEBCwUAMEIxCzAJBgNVBAYTAlVT
-MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i
-YWwgQ0EwHhcNMTQwOTA4MjA0MTEwWhcNMjIwNTIwMjA0MTEwWjBEMQswCQYDVQQG
-EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEdMBsGA1UEAxMUR2VvVHJ1c3Qg
-U1NMIENBIC0gRzQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCafZho
-EUDBX3LsVbOxY/MyInKRxhYFuwiCMbT27tQYOREvLtpH/lExblvyqQrrL7v1YVll
-VwLNgP/HcDJUif3brply1E8MJrkuYzB93hRbatdSeCH5v7xQ1VQSWdi1NtkhR7g/
-algdjHLhl5XT4UWo8Vrlvv7jU3yl8FLgzzmUDBlx8sAlB0h9HObxOSUvmHlD6Bhy
-9GWGmFoABEfaS1gefIaxSzWmIAAczRs7Il3RkygzEiOUCKrDOvXRxox+mdMYoK2d
-GM9JrRAD95kzJoZGmi+gumxuyIgCt276ep6YSu6aMX0ZFGAM7I8gIzzalya26oBs
-ileeIO5vFyVKMq01AgMBAAGjggEdMIIBGTAfBgNVHSMEGDAWgBTAephojYn7qwVk
-DBF9qn1luMrMTjAdBgNVHQ4EFgQUrDLtWsng3jCckFhVJmP2cqZUX+MwEgYDVR0T
-AQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAQYwNQYDVR0fBC4wLDAqoCigJoYk
-aHR0cDovL2cuc3ltY2IuY29tL2NybHMvZ3RnbG9iYWwuY3JsMC4GCCsGAQUFBwEB
-BCIwIDAeBggrBgEFBQcwAYYSaHR0cDovL2cuc3ltY2QuY29tMEwGA1UdIARFMEMw
-QQYKYIZIAYb4RQEHNjAzMDEGCCsGAQUFBwIBFiVodHRwOi8vd3d3Lmdlb3RydXN0
-LmNvbS9yZXNvdXJjZXMvY3BzMA0GCSqGSIb3DQEBCwUAA4IBAQBhQK0hDwO7ldyJ
-/KPLBXHpHFmXNcL6awWkFsZWRjd0GxvxPizoNxm3lNIPDsW/FAcrNM1btI3HVp0Z
-/AK0npAx+qRExnXd3R8lVKMwTKzb/sSI9zEmGEeuTCAZGseuPpgKFj3SwqZdDS4p
-fbKdx0EyF8qdrjm/kZje50TilZyUXGxCG1nJe2gTqJYJdO5AFKTV18l7M6MPWmmc
-GvpvEkcc3x5McE5t3f4ch7Wd4VQHCYrNvqqoRnhuFvLnkQ7Dr9p2ANHYokYkA6Ua
-hYFWg2MnupCO+WIRuqd8kKkaZrTFvI8pQavrjZmmzJFkutzGpkyztCMmUXJW+fN0
-VZ8ldU8r
------END CERTIFICATE-----
-#endif
-static const unsigned char kDERCert5[] = {
- 0x30, 0x82, 0x04, 0x22, 0x30, 0x82, 0x03, 0x0a, 0xa0, 0x03, 0x02, 0x01,
- 0x02, 0x02, 0x03, 0x02, 0x3a, 0x79, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
- 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x42, 0x31,
- 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53,
- 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0d, 0x47,
- 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x49, 0x6e, 0x63, 0x2e,
- 0x31, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x12, 0x47,
- 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x47, 0x6c, 0x6f, 0x62,
- 0x61, 0x6c, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x34, 0x30,
- 0x39, 0x30, 0x38, 0x32, 0x30, 0x34, 0x31, 0x31, 0x30, 0x5a, 0x17, 0x0d,
- 0x32, 0x32, 0x30, 0x35, 0x32, 0x30, 0x32, 0x30, 0x34, 0x31, 0x31, 0x30,
- 0x5a, 0x30, 0x44, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06,
- 0x13, 0x02, 0x55, 0x53, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04,
- 0x0a, 0x13, 0x0d, 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20,
- 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x1d, 0x30, 0x1b, 0x06, 0x03, 0x55, 0x04,
- 0x03, 0x13, 0x14, 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20,
- 0x53, 0x53, 0x4c, 0x20, 0x43, 0x41, 0x20, 0x2d, 0x20, 0x47, 0x34, 0x30,
- 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
- 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30,
- 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0x9a, 0x7d, 0x98, 0x68,
- 0x11, 0x40, 0xc1, 0x5f, 0x72, 0xec, 0x55, 0xb3, 0xb1, 0x63, 0xf3, 0x32,
- 0x22, 0x72, 0x91, 0xc6, 0x16, 0x05, 0xbb, 0x08, 0x82, 0x31, 0xb4, 0xf6,
- 0xee, 0xd4, 0x18, 0x39, 0x11, 0x2f, 0x2e, 0xda, 0x47, 0xfe, 0x51, 0x31,
- 0x6e, 0x5b, 0xf2, 0xa9, 0x0a, 0xeb, 0x2f, 0xbb, 0xf5, 0x61, 0x59, 0x65,
- 0x57, 0x02, 0xcd, 0x80, 0xff, 0xc7, 0x70, 0x32, 0x54, 0x89, 0xfd, 0xdb,
- 0xae, 0x99, 0x72, 0xd4, 0x4f, 0x0c, 0x26, 0xb9, 0x2e, 0x63, 0x30, 0x7d,
- 0xde, 0x14, 0x5b, 0x6a, 0xd7, 0x52, 0x78, 0x21, 0xf9, 0xbf, 0xbc, 0x50,
- 0xd5, 0x54, 0x12, 0x59, 0xd8, 0xb5, 0x36, 0xd9, 0x21, 0x47, 0xb8, 0x3f,
- 0x6a, 0x58, 0x1d, 0x8c, 0x72, 0xe1, 0x97, 0x95, 0xd3, 0xe1, 0x45, 0xa8,
- 0xf1, 0x5a, 0xe5, 0xbe, 0xfe, 0xe3, 0x53, 0x7c, 0xa5, 0xf0, 0x52, 0xe0,
- 0xcf, 0x39, 0x94, 0x0c, 0x19, 0x71, 0xf2, 0xc0, 0x25, 0x07, 0x48, 0x7d,
- 0x1c, 0xe6, 0xf1, 0x39, 0x25, 0x2f, 0x98, 0x79, 0x43, 0xe8, 0x18, 0x72,
- 0xf4, 0x65, 0x86, 0x98, 0x5a, 0x00, 0x04, 0x47, 0xda, 0x4b, 0x58, 0x1e,
- 0x7c, 0x86, 0xb1, 0x4b, 0x35, 0xa6, 0x20, 0x00, 0x1c, 0xcd, 0x1b, 0x3b,
- 0x22, 0x5d, 0xd1, 0x93, 0x28, 0x33, 0x12, 0x23, 0x94, 0x08, 0xaa, 0xc3,
- 0x3a, 0xf5, 0xd1, 0xc6, 0x8c, 0x7e, 0x99, 0xd3, 0x18, 0xa0, 0xad, 0x9d,
- 0x18, 0xcf, 0x49, 0xad, 0x10, 0x03, 0xf7, 0x99, 0x33, 0x26, 0x86, 0x46,
- 0x9a, 0x2f, 0xa0, 0xba, 0x6c, 0x6e, 0xc8, 0x88, 0x02, 0xb7, 0x6e, 0xfa,
- 0x7a, 0x9e, 0x98, 0x4a, 0xee, 0x9a, 0x31, 0x7d, 0x19, 0x14, 0x60, 0x0c,
- 0xec, 0x8f, 0x20, 0x23, 0x3c, 0xda, 0x97, 0x26, 0xb6, 0xea, 0x80, 0x6c,
- 0x8a, 0x57, 0x9e, 0x20, 0xee, 0x6f, 0x17, 0x25, 0x4a, 0x32, 0xad, 0x35,
- 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x1d, 0x30, 0x82, 0x01,
- 0x19, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16,
- 0x80, 0x14, 0xc0, 0x7a, 0x98, 0x68, 0x8d, 0x89, 0xfb, 0xab, 0x05, 0x64,
- 0x0c, 0x11, 0x7d, 0xaa, 0x7d, 0x65, 0xb8, 0xca, 0xcc, 0x4e, 0x30, 0x1d,
- 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xac, 0x32, 0xed,
- 0x5a, 0xc9, 0xe0, 0xde, 0x30, 0x9c, 0x90, 0x58, 0x55, 0x26, 0x63, 0xf6,
- 0x72, 0xa6, 0x54, 0x5f, 0xe3, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13,
- 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01,
- 0x00, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04,
- 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x35, 0x06, 0x03, 0x55, 0x1d, 0x1f,
- 0x04, 0x2e, 0x30, 0x2c, 0x30, 0x2a, 0xa0, 0x28, 0xa0, 0x26, 0x86, 0x24,
- 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x67, 0x2e, 0x73, 0x79, 0x6d,
- 0x63, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x72, 0x6c, 0x73, 0x2f,
- 0x67, 0x74, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x2e, 0x63, 0x72, 0x6c,
- 0x30, 0x2e, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01,
- 0x04, 0x22, 0x30, 0x20, 0x30, 0x1e, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05,
- 0x05, 0x07, 0x30, 0x01, 0x86, 0x12, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f,
- 0x2f, 0x67, 0x2e, 0x73, 0x79, 0x6d, 0x63, 0x64, 0x2e, 0x63, 0x6f, 0x6d,
- 0x30, 0x4c, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x45, 0x30, 0x43, 0x30,
- 0x41, 0x06, 0x0a, 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x45, 0x01, 0x07,
- 0x36, 0x30, 0x33, 0x30, 0x31, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05,
- 0x07, 0x02, 0x01, 0x16, 0x25, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f,
- 0x77, 0x77, 0x77, 0x2e, 0x67, 0x65, 0x6f, 0x74, 0x72, 0x75, 0x73, 0x74,
- 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63,
- 0x65, 0x73, 0x2f, 0x63, 0x70, 0x73, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
- 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01,
- 0x01, 0x00, 0x61, 0x40, 0xad, 0x21, 0x0f, 0x03, 0xbb, 0x95, 0xdc, 0x89,
- 0xfc, 0xa3, 0xcb, 0x05, 0x71, 0xe9, 0x1c, 0x59, 0x97, 0x35, 0xc2, 0xfa,
- 0x6b, 0x05, 0xa4, 0x16, 0xc6, 0x56, 0x46, 0x37, 0x74, 0x1b, 0x1b, 0xf1,
- 0x3e, 0x2c, 0xe8, 0x37, 0x19, 0xb7, 0x94, 0xd2, 0x0f, 0x0e, 0xc5, 0xbf,
- 0x14, 0x07, 0x2b, 0x34, 0xcd, 0x5b, 0xb4, 0x8d, 0xc7, 0x56, 0x9d, 0x19,
- 0xfc, 0x02, 0xb4, 0x9e, 0x90, 0x31, 0xfa, 0xa4, 0x44, 0xc6, 0x75, 0xdd,
- 0xdd, 0x1f, 0x25, 0x54, 0xa3, 0x30, 0x4c, 0xac, 0xdb, 0xfe, 0xc4, 0x88,
- 0xf7, 0x31, 0x26, 0x18, 0x47, 0xae, 0x4c, 0x20, 0x19, 0x1a, 0xc7, 0xae,
- 0x3e, 0x98, 0x0a, 0x16, 0x3d, 0xd2, 0xc2, 0xa6, 0x5d, 0x0d, 0x2e, 0x29,
- 0x7d, 0xb2, 0x9d, 0xc7, 0x41, 0x32, 0x17, 0xca, 0x9d, 0xae, 0x39, 0xbf,
- 0x91, 0x98, 0xde, 0xe7, 0x44, 0xe2, 0x95, 0x9c, 0x94, 0x5c, 0x6c, 0x42,
- 0x1b, 0x59, 0xc9, 0x7b, 0x68, 0x13, 0xa8, 0x96, 0x09, 0x74, 0xee, 0x40,
- 0x14, 0xa4, 0xd5, 0xd7, 0xc9, 0x7b, 0x33, 0xa3, 0x0f, 0x5a, 0x69, 0x9c,
- 0x1a, 0xfa, 0x6f, 0x12, 0x47, 0x1c, 0xdf, 0x1e, 0x4c, 0x70, 0x4e, 0x6d,
- 0xdd, 0xfe, 0x1c, 0x87, 0xb5, 0x9d, 0xe1, 0x54, 0x07, 0x09, 0x8a, 0xcd,
- 0xbe, 0xaa, 0xa8, 0x46, 0x78, 0x6e, 0x16, 0xf2, 0xe7, 0x91, 0x0e, 0xc3,
- 0xaf, 0xda, 0x76, 0x00, 0xd1, 0xd8, 0xa2, 0x46, 0x24, 0x03, 0xa5, 0x1a,
- 0x85, 0x81, 0x56, 0x83, 0x63, 0x27, 0xba, 0x90, 0x8e, 0xf9, 0x62, 0x11,
- 0xba, 0xa7, 0x7c, 0x90, 0xa9, 0x1a, 0x66, 0xb4, 0xc5, 0xbc, 0x8f, 0x29,
- 0x41, 0xab, 0xeb, 0x8d, 0x99, 0xa6, 0xcc, 0x91, 0x64, 0xba, 0xdc, 0xc6,
- 0xa6, 0x4c, 0xb3, 0xb4, 0x23, 0x26, 0x51, 0x72, 0x56, 0xf9, 0xf3, 0x74,
- 0x55, 0x9f, 0x25, 0x75, 0x4f, 0x2b,
-};
-
-#if 0
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number: 146039 (0x23a77)
- Signature Algorithm: sha256WithRSAEncryption
- Issuer: C=US, O=GeoTrust Inc., CN=GeoTrust Global CA
- Validity
- Not Before: Aug 29 21:39:32 2014 GMT
- Not After : May 20 21:39:32 2022 GMT
- Subject: C=US, O=GeoTrust Inc., CN=RapidSSL SHA256 CA - G3
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:af:54:9b:d9:58:5d:1e:2c:56:c6:d5:e8:7f:f4:
- 7d:16:03:ff:d0:8b:5a:e4:8e:a7:dd:54:2e:d4:04:
- c0:5d:98:9c:8d:90:0f:bc:10:65:5f:da:9a:d6:44:
- 7c:c0:9f:b5:e9:4a:8c:0b:06:43:04:bb:f4:96:e2:
- 26:f6:61:01:91:66:31:22:c3:34:34:5f:3f:3f:91:
- 2f:44:5f:dc:c7:14:b6:03:9f:86:4b:0e:a3:ff:a0:
- 80:02:83:c3:d3:1f:69:52:d6:9d:64:0f:c9:83:e7:
- 1b:c4:70:ac:94:e7:c3:a4:6a:2c:bd:b8:9e:69:d8:
- be:0a:8f:16:63:5a:68:71:80:7b:30:de:15:04:bf:
- cc:d3:bf:3e:48:05:55:7a:b3:d7:10:0c:03:fc:9b:
- fd:08:a7:8c:8c:db:a7:8e:f1:1e:63:dc:b3:01:2f:
- 7f:af:57:c3:3c:48:a7:83:68:21:a7:2f:e7:a7:3f:
- f0:b5:0c:fc:f5:84:d1:53:bc:0e:72:4f:60:0c:42:
- b8:98:ad:19:88:57:d7:04:ec:87:bf:7e:87:4e:a3:
- 21:f9:53:fd:36:98:48:8d:d6:f8:bb:48:f2:29:c8:
- 64:d1:cc:54:48:53:8b:af:b7:65:1e:bf:29:33:29:
- d9:29:60:48:f8:ff:91:bc:57:58:e5:35:2e:bb:69:
- b6:59
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Authority Key Identifier:
- keyid:C0:7A:98:68:8D:89:FB:AB:05:64:0C:11:7D:AA:7D:65:B8:CA:CC:4E
-
- X509v3 Subject Key Identifier:
- C3:9C:F3:FC:D3:46:08:34:BB:CE:46:7F:A0:7C:5B:F3:E2:08:CB:59
- X509v3 Basic Constraints: critical
- CA:TRUE, pathlen:0
- X509v3 Key Usage: critical
- Certificate Sign, CRL Sign
- X509v3 CRL Distribution Points:
-
- Full Name:
- URI:http://g.symcb.com/crls/gtglobal.crl
-
- Authority Information Access:
- OCSP - URI:http://g.symcd.com
-
- X509v3 Certificate Policies:
- Policy: 2.16.840.1.113733.1.7.54
- CPS: http://www.geotrust.com/resources/cps
-
- Signature Algorithm: sha256WithRSAEncryption
- a3:58:1e:c6:43:32:ac:ac:2f:93:78:b7:ea:ae:54:40:47:2d:
- 7e:78:8d:50:f6:f8:66:ac:d6:4f:73:d6:44:ef:af:0b:cc:5b:
- c1:f4:4f:9a:8f:49:7e:60:af:c2:27:c7:16:f1:fb:93:81:90:
- a9:7c:ef:6f:7e:6e:45:94:16:84:bd:ec:49:f1:c4:0e:f4:af:
- 04:59:83:87:0f:2c:3b:97:c3:5a:12:9b:7b:04:35:7b:a3:95:
- 33:08:7b:93:71:22:42:b3:a9:d9:6f:4f:81:92:fc:07:b6:79:
- bc:84:4a:9d:77:09:f1:c5:89:f2:f0:b4:9c:54:aa:12:7b:0d:
- ba:4f:ef:93:19:ec:ef:7d:4e:61:a3:8e:76:9c:59:cf:8c:94:
- b1:84:97:f7:1a:b9:07:b8:b2:c6:4f:13:79:db:bf:4f:51:1b:
- 7f:69:0d:51:2a:c1:d6:15:ff:37:51:34:65:51:f4:1e:be:38:
- 6a:ec:0e:ab:bf:3d:7b:39:05:7b:f4:f3:fb:1a:a1:d0:c8:7e:
- 4e:64:8d:cd:8c:61:55:90:fe:3a:ca:5d:25:0f:f8:1d:a3:4a:
- 74:56:4f:1a:55:40:70:75:25:a6:33:2e:ba:4b:a5:5d:53:9a:
- 0d:30:e1:8d:5f:61:2c:af:cc:ef:b0:99:a1:80:ff:0b:f2:62:
- 4c:70:26:98
------BEGIN CERTIFICATE-----
-MIIEJTCCAw2gAwIBAgIDAjp3MA0GCSqGSIb3DQEBCwUAMEIxCzAJBgNVBAYTAlVT
-MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i
-YWwgQ0EwHhcNMTQwODI5MjEzOTMyWhcNMjIwNTIwMjEzOTMyWjBHMQswCQYDVQQG
-EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEgMB4GA1UEAxMXUmFwaWRTU0wg
-U0hBMjU2IENBIC0gRzMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCv
-VJvZWF0eLFbG1eh/9H0WA//Qi1rkjqfdVC7UBMBdmJyNkA+8EGVf2prWRHzAn7Xp
-SowLBkMEu/SW4ib2YQGRZjEiwzQ0Xz8/kS9EX9zHFLYDn4ZLDqP/oIACg8PTH2lS
-1p1kD8mD5xvEcKyU58Okaiy9uJ5p2L4KjxZjWmhxgHsw3hUEv8zTvz5IBVV6s9cQ
-DAP8m/0Ip4yM26eO8R5j3LMBL3+vV8M8SKeDaCGnL+enP/C1DPz1hNFTvA5yT2AM
-QriYrRmIV9cE7Ie/fodOoyH5U/02mEiN1vi7SPIpyGTRzFRIU4uvt2UevykzKdkp
-YEj4/5G8V1jlNS67abZZAgMBAAGjggEdMIIBGTAfBgNVHSMEGDAWgBTAephojYn7
-qwVkDBF9qn1luMrMTjAdBgNVHQ4EFgQUw5zz/NNGCDS7zkZ/oHxb8+IIy1kwEgYD
-VR0TAQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAQYwNQYDVR0fBC4wLDAqoCig
-JoYkaHR0cDovL2cuc3ltY2IuY29tL2NybHMvZ3RnbG9iYWwuY3JsMC4GCCsGAQUF
-BwEBBCIwIDAeBggrBgEFBQcwAYYSaHR0cDovL2cuc3ltY2QuY29tMEwGA1UdIARF
-MEMwQQYKYIZIAYb4RQEHNjAzMDEGCCsGAQUFBwIBFiVodHRwOi8vd3d3Lmdlb3Ry
-dXN0LmNvbS9yZXNvdXJjZXMvY3BzMA0GCSqGSIb3DQEBCwUAA4IBAQCjWB7GQzKs
-rC+TeLfqrlRARy1+eI1Q9vhmrNZPc9ZE768LzFvB9E+aj0l+YK/CJ8cW8fuTgZCp
-fO9vfm5FlBaEvexJ8cQO9K8EWYOHDyw7l8NaEpt7BDV7o5UzCHuTcSJCs6nZb0+B
-kvwHtnm8hEqddwnxxYny8LScVKoSew26T++TGezvfU5ho452nFnPjJSxhJf3GrkH
-uLLGTxN5279PURt/aQ1RKsHWFf83UTRlUfQevjhq7A6rvz17OQV79PP7GqHQyH5O
-ZI3NjGFVkP46yl0lD/gdo0p0Vk8aVUBwdSWmMy66S6VdU5oNMOGNX2Esr8zvsJmh
-gP8L8mJMcCaY
------END CERTIFICATE-----
-#endif
-static const unsigned char kDERCert6[] = {
- 0x30, 0x82, 0x04, 0x25, 0x30, 0x82, 0x03, 0x0d, 0xa0, 0x03, 0x02, 0x01,
- 0x02, 0x02, 0x03, 0x02, 0x3a, 0x77, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
- 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x42, 0x31,
- 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53,
- 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0d, 0x47,
- 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x49, 0x6e, 0x63, 0x2e,
- 0x31, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x12, 0x47,
- 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x47, 0x6c, 0x6f, 0x62,
- 0x61, 0x6c, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x34, 0x30,
- 0x38, 0x32, 0x39, 0x32, 0x31, 0x33, 0x39, 0x33, 0x32, 0x5a, 0x17, 0x0d,
- 0x32, 0x32, 0x30, 0x35, 0x32, 0x30, 0x32, 0x31, 0x33, 0x39, 0x33, 0x32,
- 0x5a, 0x30, 0x47, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06,
- 0x13, 0x02, 0x55, 0x53, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04,
- 0x0a, 0x13, 0x0d, 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20,
- 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x20, 0x30, 0x1e, 0x06, 0x03, 0x55, 0x04,
- 0x03, 0x13, 0x17, 0x52, 0x61, 0x70, 0x69, 0x64, 0x53, 0x53, 0x4c, 0x20,
- 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, 0x20, 0x43, 0x41, 0x20, 0x2d, 0x20,
- 0x47, 0x33, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
- 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01,
- 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xaf,
- 0x54, 0x9b, 0xd9, 0x58, 0x5d, 0x1e, 0x2c, 0x56, 0xc6, 0xd5, 0xe8, 0x7f,
- 0xf4, 0x7d, 0x16, 0x03, 0xff, 0xd0, 0x8b, 0x5a, 0xe4, 0x8e, 0xa7, 0xdd,
- 0x54, 0x2e, 0xd4, 0x04, 0xc0, 0x5d, 0x98, 0x9c, 0x8d, 0x90, 0x0f, 0xbc,
- 0x10, 0x65, 0x5f, 0xda, 0x9a, 0xd6, 0x44, 0x7c, 0xc0, 0x9f, 0xb5, 0xe9,
- 0x4a, 0x8c, 0x0b, 0x06, 0x43, 0x04, 0xbb, 0xf4, 0x96, 0xe2, 0x26, 0xf6,
- 0x61, 0x01, 0x91, 0x66, 0x31, 0x22, 0xc3, 0x34, 0x34, 0x5f, 0x3f, 0x3f,
- 0x91, 0x2f, 0x44, 0x5f, 0xdc, 0xc7, 0x14, 0xb6, 0x03, 0x9f, 0x86, 0x4b,
- 0x0e, 0xa3, 0xff, 0xa0, 0x80, 0x02, 0x83, 0xc3, 0xd3, 0x1f, 0x69, 0x52,
- 0xd6, 0x9d, 0x64, 0x0f, 0xc9, 0x83, 0xe7, 0x1b, 0xc4, 0x70, 0xac, 0x94,
- 0xe7, 0xc3, 0xa4, 0x6a, 0x2c, 0xbd, 0xb8, 0x9e, 0x69, 0xd8, 0xbe, 0x0a,
- 0x8f, 0x16, 0x63, 0x5a, 0x68, 0x71, 0x80, 0x7b, 0x30, 0xde, 0x15, 0x04,
- 0xbf, 0xcc, 0xd3, 0xbf, 0x3e, 0x48, 0x05, 0x55, 0x7a, 0xb3, 0xd7, 0x10,
- 0x0c, 0x03, 0xfc, 0x9b, 0xfd, 0x08, 0xa7, 0x8c, 0x8c, 0xdb, 0xa7, 0x8e,
- 0xf1, 0x1e, 0x63, 0xdc, 0xb3, 0x01, 0x2f, 0x7f, 0xaf, 0x57, 0xc3, 0x3c,
- 0x48, 0xa7, 0x83, 0x68, 0x21, 0xa7, 0x2f, 0xe7, 0xa7, 0x3f, 0xf0, 0xb5,
- 0x0c, 0xfc, 0xf5, 0x84, 0xd1, 0x53, 0xbc, 0x0e, 0x72, 0x4f, 0x60, 0x0c,
- 0x42, 0xb8, 0x98, 0xad, 0x19, 0x88, 0x57, 0xd7, 0x04, 0xec, 0x87, 0xbf,
- 0x7e, 0x87, 0x4e, 0xa3, 0x21, 0xf9, 0x53, 0xfd, 0x36, 0x98, 0x48, 0x8d,
- 0xd6, 0xf8, 0xbb, 0x48, 0xf2, 0x29, 0xc8, 0x64, 0xd1, 0xcc, 0x54, 0x48,
- 0x53, 0x8b, 0xaf, 0xb7, 0x65, 0x1e, 0xbf, 0x29, 0x33, 0x29, 0xd9, 0x29,
- 0x60, 0x48, 0xf8, 0xff, 0x91, 0xbc, 0x57, 0x58, 0xe5, 0x35, 0x2e, 0xbb,
- 0x69, 0xb6, 0x59, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x1d,
- 0x30, 0x82, 0x01, 0x19, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04,
- 0x18, 0x30, 0x16, 0x80, 0x14, 0xc0, 0x7a, 0x98, 0x68, 0x8d, 0x89, 0xfb,
- 0xab, 0x05, 0x64, 0x0c, 0x11, 0x7d, 0xaa, 0x7d, 0x65, 0xb8, 0xca, 0xcc,
- 0x4e, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14,
- 0xc3, 0x9c, 0xf3, 0xfc, 0xd3, 0x46, 0x08, 0x34, 0xbb, 0xce, 0x46, 0x7f,
- 0xa0, 0x7c, 0x5b, 0xf3, 0xe2, 0x08, 0xcb, 0x59, 0x30, 0x12, 0x06, 0x03,
- 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01,
- 0xff, 0x02, 0x01, 0x00, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01,
- 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x35, 0x06, 0x03,
- 0x55, 0x1d, 0x1f, 0x04, 0x2e, 0x30, 0x2c, 0x30, 0x2a, 0xa0, 0x28, 0xa0,
- 0x26, 0x86, 0x24, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x67, 0x2e,
- 0x73, 0x79, 0x6d, 0x63, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x72,
- 0x6c, 0x73, 0x2f, 0x67, 0x74, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x2e,
- 0x63, 0x72, 0x6c, 0x30, 0x2e, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05,
- 0x07, 0x01, 0x01, 0x04, 0x22, 0x30, 0x20, 0x30, 0x1e, 0x06, 0x08, 0x2b,
- 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x12, 0x68, 0x74, 0x74,
- 0x70, 0x3a, 0x2f, 0x2f, 0x67, 0x2e, 0x73, 0x79, 0x6d, 0x63, 0x64, 0x2e,
- 0x63, 0x6f, 0x6d, 0x30, 0x4c, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x45,
- 0x30, 0x43, 0x30, 0x41, 0x06, 0x0a, 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8,
- 0x45, 0x01, 0x07, 0x36, 0x30, 0x33, 0x30, 0x31, 0x06, 0x08, 0x2b, 0x06,
- 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x25, 0x68, 0x74, 0x74, 0x70,
- 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x67, 0x65, 0x6f, 0x74, 0x72,
- 0x75, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x73, 0x6f,
- 0x75, 0x72, 0x63, 0x65, 0x73, 0x2f, 0x63, 0x70, 0x73, 0x30, 0x0d, 0x06,
- 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00,
- 0x03, 0x82, 0x01, 0x01, 0x00, 0xa3, 0x58, 0x1e, 0xc6, 0x43, 0x32, 0xac,
- 0xac, 0x2f, 0x93, 0x78, 0xb7, 0xea, 0xae, 0x54, 0x40, 0x47, 0x2d, 0x7e,
- 0x78, 0x8d, 0x50, 0xf6, 0xf8, 0x66, 0xac, 0xd6, 0x4f, 0x73, 0xd6, 0x44,
- 0xef, 0xaf, 0x0b, 0xcc, 0x5b, 0xc1, 0xf4, 0x4f, 0x9a, 0x8f, 0x49, 0x7e,
- 0x60, 0xaf, 0xc2, 0x27, 0xc7, 0x16, 0xf1, 0xfb, 0x93, 0x81, 0x90, 0xa9,
- 0x7c, 0xef, 0x6f, 0x7e, 0x6e, 0x45, 0x94, 0x16, 0x84, 0xbd, 0xec, 0x49,
- 0xf1, 0xc4, 0x0e, 0xf4, 0xaf, 0x04, 0x59, 0x83, 0x87, 0x0f, 0x2c, 0x3b,
- 0x97, 0xc3, 0x5a, 0x12, 0x9b, 0x7b, 0x04, 0x35, 0x7b, 0xa3, 0x95, 0x33,
- 0x08, 0x7b, 0x93, 0x71, 0x22, 0x42, 0xb3, 0xa9, 0xd9, 0x6f, 0x4f, 0x81,
- 0x92, 0xfc, 0x07, 0xb6, 0x79, 0xbc, 0x84, 0x4a, 0x9d, 0x77, 0x09, 0xf1,
- 0xc5, 0x89, 0xf2, 0xf0, 0xb4, 0x9c, 0x54, 0xaa, 0x12, 0x7b, 0x0d, 0xba,
- 0x4f, 0xef, 0x93, 0x19, 0xec, 0xef, 0x7d, 0x4e, 0x61, 0xa3, 0x8e, 0x76,
- 0x9c, 0x59, 0xcf, 0x8c, 0x94, 0xb1, 0x84, 0x97, 0xf7, 0x1a, 0xb9, 0x07,
- 0xb8, 0xb2, 0xc6, 0x4f, 0x13, 0x79, 0xdb, 0xbf, 0x4f, 0x51, 0x1b, 0x7f,
- 0x69, 0x0d, 0x51, 0x2a, 0xc1, 0xd6, 0x15, 0xff, 0x37, 0x51, 0x34, 0x65,
- 0x51, 0xf4, 0x1e, 0xbe, 0x38, 0x6a, 0xec, 0x0e, 0xab, 0xbf, 0x3d, 0x7b,
- 0x39, 0x05, 0x7b, 0xf4, 0xf3, 0xfb, 0x1a, 0xa1, 0xd0, 0xc8, 0x7e, 0x4e,
- 0x64, 0x8d, 0xcd, 0x8c, 0x61, 0x55, 0x90, 0xfe, 0x3a, 0xca, 0x5d, 0x25,
- 0x0f, 0xf8, 0x1d, 0xa3, 0x4a, 0x74, 0x56, 0x4f, 0x1a, 0x55, 0x40, 0x70,
- 0x75, 0x25, 0xa6, 0x33, 0x2e, 0xba, 0x4b, 0xa5, 0x5d, 0x53, 0x9a, 0x0d,
- 0x30, 0xe1, 0x8d, 0x5f, 0x61, 0x2c, 0xaf, 0xcc, 0xef, 0xb0, 0x99, 0xa1,
- 0x80, 0xff, 0x0b, 0xf2, 0x62, 0x4c, 0x70, 0x26, 0x98,
-};
-
-#if 0
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number:
- 11:20:96:f6:c8:03:7c:9e:07:b1:38:bf:2e:72:10:8a:d7:ed
- Signature Algorithm: sha1WithRSAEncryption
- Issuer: C=FR, O=Certplus, CN=Class 2 Primary CA
- Validity
- Not Before: Jun 5 00:00:00 2007 GMT
- Not After : Jun 20 00:00:00 2019 GMT
- Subject: C=FR, O=KEYNECTIS, CN=CLASS 2 KEYNECTIS CA
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:c6:be:fe:44:23:04:d4:ef:2f:3b:86:aa:35:58:
- 81:d1:e1:9a:d6:b1:d4:27:45:28:fc:d1:1e:46:85:
- ba:54:23:11:7d:e0:66:3f:d4:a3:57:66:78:f9:6b:
- eb:74:7c:2a:b8:37:a5:e8:70:ae:82:b5:4e:d4:81:
- fe:5b:e2:ea:e7:22:16:f8:f9:d7:ba:3a:f6:88:56:
- dc:c4:f2:a0:a4:e5:75:06:60:72:2b:fb:f5:94:ee:
- 2c:83:28:de:91:9a:b3:83:3a:b0:9f:08:fa:dd:d8:
- 9e:8c:24:e6:df:66:5b:c8:7e:a3:62:4d:3f:3a:85:
- 23:ec:e8:71:8f:0a:00:ac:89:6d:7e:d8:72:e5:dd:
- c1:94:8e:5f:e4:73:e6:c1:c6:0c:87:58:4f:37:da:
- d1:a9:88:26:76:b4:ee:11:8d:f6:ad:b2:a7:bc:73:
- c4:cd:1c:6e:1a:e6:8d:72:56:44:a0:98:f7:92:f9:
- d7:79:9b:03:e6:68:5f:a4:5c:7c:3d:50:b4:83:cc:
- e5:ac:0d:e1:3e:4f:14:f2:b4:e4:7d:bf:71:a4:c3:
- 97:73:38:d6:52:7c:c8:a4:b5:ea:e9:b2:54:56:d4:
- eb:b8:57:3a:40:52:5a:5e:46:27:a3:7b:30:2d:08:
- 3d:85:1e:9a:f0:32:a8:f2:10:a2:83:9b:e2:28:f6:
- 9d:cb
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Basic Constraints: critical
- CA:TRUE, pathlen:0
- X509v3 Certificate Policies:
- Policy: 1.3.6.4.1.22234.2.5.3.3
- CPS: http://www.keynectis.com/PC
- Policy: 1.3.6.4.1.22234.2.5.1.3
- CPS: http://www.keynectis.com/PC
-
- X509v3 CRL Distribution Points:
-
- Full Name:
- URI:http://www.certplus.com/CRL/class2.crl
-
- X509v3 Key Usage: critical
- Certificate Sign, CRL Sign
- X509v3 Subject Key Identifier:
- 00:11:41:DF:3B:9D:3B:CB:B8:A2:C1:33:92:A8:81:CC:E5:7D:E7:99
- X509v3 Authority Key Identifier:
- keyid:E3:73:2D:DF:CB:0E:28:0C:DE:DD:B3:A4:CA:79:B8:8E:BB:E8:30:89
-
- Signature Algorithm: sha1WithRSAEncryption
- 08:88:fe:1f:a2:ca:cd:e2:a0:f1:2e:7c:67:49:fb:dc:94:ac:
- 7f:41:0d:78:01:ba:31:f7:9b:fb:31:18:77:2f:66:25:94:b8:
- 6d:16:74:81:f1:c0:ae:67:c6:14:45:7a:01:d1:13:88:fc:e2:
- 8d:22:1d:bd:1e:0c:c7:a9:7e:d0:c3:97:f6:37:5b:41:5e:67:
- 94:8e:ab:69:02:17:18:f5:4d:38:c2:49:28:09:6e:5a:9b:a6:
- 27:db:c0:5f:8f:44:9c:90:65:99:d8:b3:2e:c1:92:ee:1a:9d:
- 0f:72:45:20:fa:2c:0c:9c:5d:cd:5b:54:41:54:4f:d3:e2:c7:
- 59:84:3f:17:7b:7d:0e:c2:ef:62:c7:ba:b1:26:6c:83:4e:d3:
- 19:c5:ff:56:a7:b4:45:3f:7a:9e:fa:d0:39:3e:80:46:75:5d:
- 5a:79:7a:33:c5:01:bc:02:44:ce:1b:c0:31:4e:47:96:15:6e:
- e7:e4:76:f0:c2:90:0d:a1:78:f4:38:00:91:2b:65:7c:79:13:
- a8:3e:91:14:dc:88:05:08:d7:6f:53:f6:15:43:ee:c5:53:56:
- 1a:02:b5:a6:a2:46:8d:1e:13:e4:67:c2:45:5f:40:5e:10:42:
- 58:b5:cd:44:a3:94:4c:1c:54:90:4d:91:9a:26:8b:ad:a2:80:
- 50:8d:14:14
------BEGIN CERTIFICATE-----
-MIIEKzCCAxOgAwIBAgISESCW9sgDfJ4HsTi/LnIQitftMA0GCSqGSIb3DQEBBQUA
-MD0xCzAJBgNVBAYTAkZSMREwDwYDVQQKEwhDZXJ0cGx1czEbMBkGA1UEAxMSQ2xh
-c3MgMiBQcmltYXJ5IENBMB4XDTA3MDYwNTAwMDAwMFoXDTE5MDYyMDAwMDAwMFow
-QDELMAkGA1UEBhMCRlIxEjAQBgNVBAoTCUtFWU5FQ1RJUzEdMBsGA1UEAxMUQ0xB
-U1MgMiBLRVlORUNUSVMgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
-AQDGvv5EIwTU7y87hqo1WIHR4ZrWsdQnRSj80R5GhbpUIxF94GY/1KNXZnj5a+t0
-fCq4N6XocK6CtU7Ugf5b4urnIhb4+de6OvaIVtzE8qCk5XUGYHIr+/WU7iyDKN6R
-mrODOrCfCPrd2J6MJObfZlvIfqNiTT86hSPs6HGPCgCsiW1+2HLl3cGUjl/kc+bB
-xgyHWE832tGpiCZ2tO4Rjfatsqe8c8TNHG4a5o1yVkSgmPeS+dd5mwPmaF+kXHw9
-ULSDzOWsDeE+TxTytOR9v3Gkw5dzONZSfMikterpslRW1Ou4VzpAUlpeRiejezAt
-CD2FHprwMqjyEKKDm+Io9p3LAgMBAAGjggEgMIIBHDASBgNVHRMBAf8ECDAGAQH/
-AgEAMH0GA1UdIAR2MHQwOAYLKwYEAYGtWgIFAwMwKTAnBggrBgEFBQcCARYbaHR0
-cDovL3d3dy5rZXluZWN0aXMuY29tL1BDMDgGCysGBAGBrVoCBQEDMCkwJwYIKwYB
-BQUHAgEWG2h0dHA6Ly93d3cua2V5bmVjdGlzLmNvbS9QQzA3BgNVHR8EMDAuMCyg
-KqAohiZodHRwOi8vd3d3LmNlcnRwbHVzLmNvbS9DUkwvY2xhc3MyLmNybDAOBgNV
-HQ8BAf8EBAMCAQYwHQYDVR0OBBYEFAARQd87nTvLuKLBM5KogczlfeeZMB8GA1Ud
-IwQYMBaAFONzLd/LDigM3t2zpMp5uI676DCJMA0GCSqGSIb3DQEBBQUAA4IBAQAI
-iP4fosrN4qDxLnxnSfvclKx/QQ14Abox95v7MRh3L2YllLhtFnSB8cCuZ8YURXoB
-0ROI/OKNIh29HgzHqX7Qw5f2N1tBXmeUjqtpAhcY9U04wkkoCW5am6Yn28Bfj0Sc
-kGWZ2LMuwZLuGp0PckUg+iwMnF3NW1RBVE/T4sdZhD8Xe30Owu9ix7qxJmyDTtMZ
-xf9Wp7RFP3qe+tA5PoBGdV1aeXozxQG8AkTOG8AxTkeWFW7n5HbwwpANoXj0OACR
-K2V8eROoPpEU3IgFCNdvU/YVQ+7FU1YaArWmokaNHhPkZ8JFX0BeEEJYtc1Eo5RM
-HFSQTZGaJoutooBQjRQU
------END CERTIFICATE-----
-#endif
-static const unsigned char kDERCert7[] = {
- 0x30, 0x82, 0x04, 0x2b, 0x30, 0x82, 0x03, 0x13, 0xa0, 0x03, 0x02, 0x01,
- 0x02, 0x02, 0x12, 0x11, 0x20, 0x96, 0xf6, 0xc8, 0x03, 0x7c, 0x9e, 0x07,
- 0xb1, 0x38, 0xbf, 0x2e, 0x72, 0x10, 0x8a, 0xd7, 0xed, 0x30, 0x0d, 0x06,
- 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00,
- 0x30, 0x3d, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
- 0x02, 0x46, 0x52, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x0a,
- 0x13, 0x08, 0x43, 0x65, 0x72, 0x74, 0x70, 0x6c, 0x75, 0x73, 0x31, 0x1b,
- 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x12, 0x43, 0x6c, 0x61,
- 0x73, 0x73, 0x20, 0x32, 0x20, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79,
- 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x37, 0x30, 0x36, 0x30,
- 0x35, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x31, 0x39,
- 0x30, 0x36, 0x32, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30,
- 0x40, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
- 0x46, 0x52, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13,
- 0x09, 0x4b, 0x45, 0x59, 0x4e, 0x45, 0x43, 0x54, 0x49, 0x53, 0x31, 0x1d,
- 0x30, 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x14, 0x43, 0x4c, 0x41,
- 0x53, 0x53, 0x20, 0x32, 0x20, 0x4b, 0x45, 0x59, 0x4e, 0x45, 0x43, 0x54,
- 0x49, 0x53, 0x20, 0x43, 0x41, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06,
- 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00,
- 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01,
- 0x01, 0x00, 0xc6, 0xbe, 0xfe, 0x44, 0x23, 0x04, 0xd4, 0xef, 0x2f, 0x3b,
- 0x86, 0xaa, 0x35, 0x58, 0x81, 0xd1, 0xe1, 0x9a, 0xd6, 0xb1, 0xd4, 0x27,
- 0x45, 0x28, 0xfc, 0xd1, 0x1e, 0x46, 0x85, 0xba, 0x54, 0x23, 0x11, 0x7d,
- 0xe0, 0x66, 0x3f, 0xd4, 0xa3, 0x57, 0x66, 0x78, 0xf9, 0x6b, 0xeb, 0x74,
- 0x7c, 0x2a, 0xb8, 0x37, 0xa5, 0xe8, 0x70, 0xae, 0x82, 0xb5, 0x4e, 0xd4,
- 0x81, 0xfe, 0x5b, 0xe2, 0xea, 0xe7, 0x22, 0x16, 0xf8, 0xf9, 0xd7, 0xba,
- 0x3a, 0xf6, 0x88, 0x56, 0xdc, 0xc4, 0xf2, 0xa0, 0xa4, 0xe5, 0x75, 0x06,
- 0x60, 0x72, 0x2b, 0xfb, 0xf5, 0x94, 0xee, 0x2c, 0x83, 0x28, 0xde, 0x91,
- 0x9a, 0xb3, 0x83, 0x3a, 0xb0, 0x9f, 0x08, 0xfa, 0xdd, 0xd8, 0x9e, 0x8c,
- 0x24, 0xe6, 0xdf, 0x66, 0x5b, 0xc8, 0x7e, 0xa3, 0x62, 0x4d, 0x3f, 0x3a,
- 0x85, 0x23, 0xec, 0xe8, 0x71, 0x8f, 0x0a, 0x00, 0xac, 0x89, 0x6d, 0x7e,
- 0xd8, 0x72, 0xe5, 0xdd, 0xc1, 0x94, 0x8e, 0x5f, 0xe4, 0x73, 0xe6, 0xc1,
- 0xc6, 0x0c, 0x87, 0x58, 0x4f, 0x37, 0xda, 0xd1, 0xa9, 0x88, 0x26, 0x76,
- 0xb4, 0xee, 0x11, 0x8d, 0xf6, 0xad, 0xb2, 0xa7, 0xbc, 0x73, 0xc4, 0xcd,
- 0x1c, 0x6e, 0x1a, 0xe6, 0x8d, 0x72, 0x56, 0x44, 0xa0, 0x98, 0xf7, 0x92,
- 0xf9, 0xd7, 0x79, 0x9b, 0x03, 0xe6, 0x68, 0x5f, 0xa4, 0x5c, 0x7c, 0x3d,
- 0x50, 0xb4, 0x83, 0xcc, 0xe5, 0xac, 0x0d, 0xe1, 0x3e, 0x4f, 0x14, 0xf2,
- 0xb4, 0xe4, 0x7d, 0xbf, 0x71, 0xa4, 0xc3, 0x97, 0x73, 0x38, 0xd6, 0x52,
- 0x7c, 0xc8, 0xa4, 0xb5, 0xea, 0xe9, 0xb2, 0x54, 0x56, 0xd4, 0xeb, 0xb8,
- 0x57, 0x3a, 0x40, 0x52, 0x5a, 0x5e, 0x46, 0x27, 0xa3, 0x7b, 0x30, 0x2d,
- 0x08, 0x3d, 0x85, 0x1e, 0x9a, 0xf0, 0x32, 0xa8, 0xf2, 0x10, 0xa2, 0x83,
- 0x9b, 0xe2, 0x28, 0xf6, 0x9d, 0xcb, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3,
- 0x82, 0x01, 0x20, 0x30, 0x82, 0x01, 0x1c, 0x30, 0x12, 0x06, 0x03, 0x55,
- 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff,
- 0x02, 0x01, 0x00, 0x30, 0x7d, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x76,
- 0x30, 0x74, 0x30, 0x38, 0x06, 0x0b, 0x2b, 0x06, 0x04, 0x01, 0x81, 0xad,
- 0x5a, 0x02, 0x05, 0x03, 0x03, 0x30, 0x29, 0x30, 0x27, 0x06, 0x08, 0x2b,
- 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x1b, 0x68, 0x74, 0x74,
- 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x6b, 0x65, 0x79, 0x6e,
- 0x65, 0x63, 0x74, 0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x50, 0x43,
- 0x30, 0x38, 0x06, 0x0b, 0x2b, 0x06, 0x04, 0x01, 0x81, 0xad, 0x5a, 0x02,
- 0x05, 0x01, 0x03, 0x30, 0x29, 0x30, 0x27, 0x06, 0x08, 0x2b, 0x06, 0x01,
- 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x1b, 0x68, 0x74, 0x74, 0x70, 0x3a,
- 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x6b, 0x65, 0x79, 0x6e, 0x65, 0x63,
- 0x74, 0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x50, 0x43, 0x30, 0x37,
- 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x30, 0x30, 0x2e, 0x30, 0x2c, 0xa0,
- 0x2a, 0xa0, 0x28, 0x86, 0x26, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f,
- 0x77, 0x77, 0x77, 0x2e, 0x63, 0x65, 0x72, 0x74, 0x70, 0x6c, 0x75, 0x73,
- 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x43, 0x52, 0x4c, 0x2f, 0x63, 0x6c, 0x61,
- 0x73, 0x73, 0x32, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x0e, 0x06, 0x03, 0x55,
- 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30,
- 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x00, 0x11,
- 0x41, 0xdf, 0x3b, 0x9d, 0x3b, 0xcb, 0xb8, 0xa2, 0xc1, 0x33, 0x92, 0xa8,
- 0x81, 0xcc, 0xe5, 0x7d, 0xe7, 0x99, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d,
- 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0xe3, 0x73, 0x2d, 0xdf, 0xcb,
- 0x0e, 0x28, 0x0c, 0xde, 0xdd, 0xb3, 0xa4, 0xca, 0x79, 0xb8, 0x8e, 0xbb,
- 0xe8, 0x30, 0x89, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
- 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x08,
- 0x88, 0xfe, 0x1f, 0xa2, 0xca, 0xcd, 0xe2, 0xa0, 0xf1, 0x2e, 0x7c, 0x67,
- 0x49, 0xfb, 0xdc, 0x94, 0xac, 0x7f, 0x41, 0x0d, 0x78, 0x01, 0xba, 0x31,
- 0xf7, 0x9b, 0xfb, 0x31, 0x18, 0x77, 0x2f, 0x66, 0x25, 0x94, 0xb8, 0x6d,
- 0x16, 0x74, 0x81, 0xf1, 0xc0, 0xae, 0x67, 0xc6, 0x14, 0x45, 0x7a, 0x01,
- 0xd1, 0x13, 0x88, 0xfc, 0xe2, 0x8d, 0x22, 0x1d, 0xbd, 0x1e, 0x0c, 0xc7,
- 0xa9, 0x7e, 0xd0, 0xc3, 0x97, 0xf6, 0x37, 0x5b, 0x41, 0x5e, 0x67, 0x94,
- 0x8e, 0xab, 0x69, 0x02, 0x17, 0x18, 0xf5, 0x4d, 0x38, 0xc2, 0x49, 0x28,
- 0x09, 0x6e, 0x5a, 0x9b, 0xa6, 0x27, 0xdb, 0xc0, 0x5f, 0x8f, 0x44, 0x9c,
- 0x90, 0x65, 0x99, 0xd8, 0xb3, 0x2e, 0xc1, 0x92, 0xee, 0x1a, 0x9d, 0x0f,
- 0x72, 0x45, 0x20, 0xfa, 0x2c, 0x0c, 0x9c, 0x5d, 0xcd, 0x5b, 0x54, 0x41,
- 0x54, 0x4f, 0xd3, 0xe2, 0xc7, 0x59, 0x84, 0x3f, 0x17, 0x7b, 0x7d, 0x0e,
- 0xc2, 0xef, 0x62, 0xc7, 0xba, 0xb1, 0x26, 0x6c, 0x83, 0x4e, 0xd3, 0x19,
- 0xc5, 0xff, 0x56, 0xa7, 0xb4, 0x45, 0x3f, 0x7a, 0x9e, 0xfa, 0xd0, 0x39,
- 0x3e, 0x80, 0x46, 0x75, 0x5d, 0x5a, 0x79, 0x7a, 0x33, 0xc5, 0x01, 0xbc,
- 0x02, 0x44, 0xce, 0x1b, 0xc0, 0x31, 0x4e, 0x47, 0x96, 0x15, 0x6e, 0xe7,
- 0xe4, 0x76, 0xf0, 0xc2, 0x90, 0x0d, 0xa1, 0x78, 0xf4, 0x38, 0x00, 0x91,
- 0x2b, 0x65, 0x7c, 0x79, 0x13, 0xa8, 0x3e, 0x91, 0x14, 0xdc, 0x88, 0x05,
- 0x08, 0xd7, 0x6f, 0x53, 0xf6, 0x15, 0x43, 0xee, 0xc5, 0x53, 0x56, 0x1a,
- 0x02, 0xb5, 0xa6, 0xa2, 0x46, 0x8d, 0x1e, 0x13, 0xe4, 0x67, 0xc2, 0x45,
- 0x5f, 0x40, 0x5e, 0x10, 0x42, 0x58, 0xb5, 0xcd, 0x44, 0xa3, 0x94, 0x4c,
- 0x1c, 0x54, 0x90, 0x4d, 0x91, 0x9a, 0x26, 0x8b, 0xad, 0xa2, 0x80, 0x50,
- 0x8d, 0x14, 0x14,
-};
-
-#if 0
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number: 120024505 (0x7276db9)
- Signature Algorithm: sha1WithRSAEncryption
- Issuer: C=US, O=GTE Corporation, OU=GTE CyberTrust Solutions, Inc., CN=GTE CyberTrust Global Root
- Validity
- Not Before: Nov 30 16:35:21 2010 GMT
- Not After : Aug 10 15:34:26 2018 GMT
- Subject: C=IE, O=Baltimore, OU=CyberTrust, CN=Baltimore CyberTrust Root
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:a3:04:bb:22:ab:98:3d:57:e8:26:72:9a:b5:79:
- d4:29:e2:e1:e8:95:80:b1:b0:e3:5b:8e:2b:29:9a:
- 64:df:a1:5d:ed:b0:09:05:6d:db:28:2e:ce:62:a2:
- 62:fe:b4:88:da:12:eb:38:eb:21:9d:c0:41:2b:01:
- 52:7b:88:77:d3:1c:8f:c7:ba:b9:88:b5:6a:09:e7:
- 73:e8:11:40:a7:d1:cc:ca:62:8d:2d:e5:8f:0b:a6:
- 50:d2:a8:50:c3:28:ea:f5:ab:25:87:8a:9a:96:1c:
- a9:67:b8:3f:0c:d5:f7:f9:52:13:2f:c2:1b:d5:70:
- 70:f0:8f:c0:12:ca:06:cb:9a:e1:d9:ca:33:7a:77:
- d6:f8:ec:b9:f1:68:44:42:48:13:d2:c0:c2:a4:ae:
- 5e:60:fe:b6:a6:05:fc:b4:dd:07:59:02:d4:59:18:
- 98:63:f5:a5:63:e0:90:0c:7d:5d:b2:06:7a:f3:85:
- ea:eb:d4:03:ae:5e:84:3e:5f:ff:15:ed:69:bc:f9:
- 39:36:72:75:cf:77:52:4d:f3:c9:90:2c:b9:3d:e5:
- c9:23:53:3f:1f:24:98:21:5c:07:99:29:bd:c6:3a:
- ec:e7:6e:86:3a:6b:97:74:63:33:bd:68:18:31:f0:
- 78:8d:76:bf:fc:9e:8e:5d:2a:86:a7:4d:90:dc:27:
- 1a:39
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Basic Constraints: critical
- CA:TRUE, pathlen:3
- X509v3 Certificate Policies:
- Policy: X509v3 Any Policy
- CPS: http://cybertrust.omniroot.com/repository.cfm
-
- X509v3 Key Usage: critical
- Certificate Sign, CRL Sign
- X509v3 Authority Key Identifier:
- DirName:/C=US/O=GTE Corporation/OU=GTE CyberTrust Solutions, Inc./CN=GTE CyberTrust Global Root
- serial:01:A5
-
- X509v3 CRL Distribution Points:
-
- Full Name:
- URI:http://www.public-trust.com/cgi-bin/CRL/2018/cdp.crl
-
- X509v3 Subject Key Identifier:
- E5:9D:59:30:82:47:58:CC:AC:FA:08:54:36:86:7B:3A:B5:04:4D:F0
- Signature Algorithm: sha1WithRSAEncryption
- 16:b4:2c:c9:f1:5e:e1:a2:7b:9b:78:20:7a:4a:70:70:86:19:
- 00:b7:05:2a:e8:c9:25:39:0f:c3:64:3c:75:09:d9:89:15:80:
- 07:c2:8d:bc:29:a5:64:50:cf:71:75:47:23:bd:4d:d8:7f:77:
- 9a:51:10:6e:4e:1f:20:3c:47:9c:43:74:7f:96:84:10:4c:13:
- 43:be:f8:e0:72:2e:ff:bf:ae:3c:0a:03:60:82:4b:6f:f9:9a:
- c5:1e:f6:af:90:3b:9f:61:3b:3e:de:9b:05:1a:c6:2c:3c:57:
- 21:08:0f:54:fa:28:63:6c:e8:1b:9c:0f:cf:dd:30:44:13:b9:
- 57:fe
------BEGIN CERTIFICATE-----
-MIIEODCCA6GgAwIBAgIEBydtuTANBgkqhkiG9w0BAQUFADB1MQswCQYDVQQGEwJV
-UzEYMBYGA1UEChMPR1RFIENvcnBvcmF0aW9uMScwJQYDVQQLEx5HVEUgQ3liZXJU
-cnVzdCBTb2x1dGlvbnMsIEluYy4xIzAhBgNVBAMTGkdURSBDeWJlclRydXN0IEds
-b2JhbCBSb290MB4XDTEwMTEzMDE2MzUyMVoXDTE4MDgxMDE1MzQyNlowWjELMAkG
-A1UEBhMCSUUxEjAQBgNVBAoTCUJhbHRpbW9yZTETMBEGA1UECxMKQ3liZXJUcnVz
-dDEiMCAGA1UEAxMZQmFsdGltb3JlIEN5YmVyVHJ1c3QgUm9vdDCCASIwDQYJKoZI
-hvcNAQEBBQADggEPADCCAQoCggEBAKMEuyKrmD1X6CZymrV51Cni4eiVgLGw41uO
-KymaZN+hXe2wCQVt2yguzmKiYv60iNoS6zjrIZ3AQSsBUnuId9Mcj8e6uYi1agnn
-c+gRQKfRzMpijS3ljwumUNKoUMMo6vWrJYeKmpYcqWe4PwzV9/lSEy/CG9VwcPCP
-wBLKBsua4dnKM3p31vjsufFoREJIE9LAwqSuXmD+tqYF/LTdB1kC1FkYmGP1pWPg
-kAx9XbIGevOF6uvUA65ehD5f/xXtabz5OTZydc93Uk3zyZAsuT3lySNTPx8kmCFc
-B5kpvcY67Oduhjprl3RjM71oGDHweI12v/yejl0qhqdNkNwnGjkCAwEAAaOCAWow
-ggFmMBIGA1UdEwEB/wQIMAYBAf8CAQMwTgYDVR0gBEcwRTBDBgRVHSAAMDswOQYI
-KwYBBQUHAgEWLWh0dHA6Ly9jeWJlcnRydXN0Lm9tbmlyb290LmNvbS9yZXBvc2l0
-b3J5LmNmbTAOBgNVHQ8BAf8EBAMCAQYwgYkGA1UdIwSBgTB/oXmkdzB1MQswCQYD
-VQQGEwJVUzEYMBYGA1UEChMPR1RFIENvcnBvcmF0aW9uMScwJQYDVQQLEx5HVEUg
-Q3liZXJUcnVzdCBTb2x1dGlvbnMsIEluYy4xIzAhBgNVBAMTGkdURSBDeWJlclRy
-dXN0IEdsb2JhbCBSb290ggIBpTBFBgNVHR8EPjA8MDqgOKA2hjRodHRwOi8vd3d3
-LnB1YmxpYy10cnVzdC5jb20vY2dpLWJpbi9DUkwvMjAxOC9jZHAuY3JsMB0GA1Ud
-DgQWBBTlnVkwgkdYzKz6CFQ2hns6tQRN8DANBgkqhkiG9w0BAQUFAAOBgQAWtCzJ
-8V7honubeCB6SnBwhhkAtwUq6MklOQ/DZDx1CdmJFYAHwo28KaVkUM9xdUcjvU3Y
-f3eaURBuTh8gPEecQ3R/loQQTBNDvvjgci7/v648CgNggktv+ZrFHvavkDufYTs+
-3psFGsYsPFchCA9U+ihjbOgbnA/P3TBEE7lX/g==
------END CERTIFICATE-----
-#endif
-static const unsigned char kDERCert8[] = {
- 0x30, 0x82, 0x04, 0x38, 0x30, 0x82, 0x03, 0xa1, 0xa0, 0x03, 0x02, 0x01,
- 0x02, 0x02, 0x04, 0x07, 0x27, 0x6d, 0xb9, 0x30, 0x0d, 0x06, 0x09, 0x2a,
- 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x75,
- 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55,
- 0x53, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0f,
- 0x47, 0x54, 0x45, 0x20, 0x43, 0x6f, 0x72, 0x70, 0x6f, 0x72, 0x61, 0x74,
- 0x69, 0x6f, 0x6e, 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x0b,
- 0x13, 0x1e, 0x47, 0x54, 0x45, 0x20, 0x43, 0x79, 0x62, 0x65, 0x72, 0x54,
- 0x72, 0x75, 0x73, 0x74, 0x20, 0x53, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f,
- 0x6e, 0x73, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x23, 0x30, 0x21,
- 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x1a, 0x47, 0x54, 0x45, 0x20, 0x43,
- 0x79, 0x62, 0x65, 0x72, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x47, 0x6c,
- 0x6f, 0x62, 0x61, 0x6c, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x30, 0x1e, 0x17,
- 0x0d, 0x31, 0x30, 0x31, 0x31, 0x33, 0x30, 0x31, 0x36, 0x33, 0x35, 0x32,
- 0x31, 0x5a, 0x17, 0x0d, 0x31, 0x38, 0x30, 0x38, 0x31, 0x30, 0x31, 0x35,
- 0x33, 0x34, 0x32, 0x36, 0x5a, 0x30, 0x5a, 0x31, 0x0b, 0x30, 0x09, 0x06,
- 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x49, 0x45, 0x31, 0x12, 0x30, 0x10,
- 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x09, 0x42, 0x61, 0x6c, 0x74, 0x69,
- 0x6d, 0x6f, 0x72, 0x65, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04,
- 0x0b, 0x13, 0x0a, 0x43, 0x79, 0x62, 0x65, 0x72, 0x54, 0x72, 0x75, 0x73,
- 0x74, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x19,
- 0x42, 0x61, 0x6c, 0x74, 0x69, 0x6d, 0x6f, 0x72, 0x65, 0x20, 0x43, 0x79,
- 0x62, 0x65, 0x72, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x52, 0x6f, 0x6f,
- 0x74, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48,
- 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f,
- 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xa3, 0x04,
- 0xbb, 0x22, 0xab, 0x98, 0x3d, 0x57, 0xe8, 0x26, 0x72, 0x9a, 0xb5, 0x79,
- 0xd4, 0x29, 0xe2, 0xe1, 0xe8, 0x95, 0x80, 0xb1, 0xb0, 0xe3, 0x5b, 0x8e,
- 0x2b, 0x29, 0x9a, 0x64, 0xdf, 0xa1, 0x5d, 0xed, 0xb0, 0x09, 0x05, 0x6d,
- 0xdb, 0x28, 0x2e, 0xce, 0x62, 0xa2, 0x62, 0xfe, 0xb4, 0x88, 0xda, 0x12,
- 0xeb, 0x38, 0xeb, 0x21, 0x9d, 0xc0, 0x41, 0x2b, 0x01, 0x52, 0x7b, 0x88,
- 0x77, 0xd3, 0x1c, 0x8f, 0xc7, 0xba, 0xb9, 0x88, 0xb5, 0x6a, 0x09, 0xe7,
- 0x73, 0xe8, 0x11, 0x40, 0xa7, 0xd1, 0xcc, 0xca, 0x62, 0x8d, 0x2d, 0xe5,
- 0x8f, 0x0b, 0xa6, 0x50, 0xd2, 0xa8, 0x50, 0xc3, 0x28, 0xea, 0xf5, 0xab,
- 0x25, 0x87, 0x8a, 0x9a, 0x96, 0x1c, 0xa9, 0x67, 0xb8, 0x3f, 0x0c, 0xd5,
- 0xf7, 0xf9, 0x52, 0x13, 0x2f, 0xc2, 0x1b, 0xd5, 0x70, 0x70, 0xf0, 0x8f,
- 0xc0, 0x12, 0xca, 0x06, 0xcb, 0x9a, 0xe1, 0xd9, 0xca, 0x33, 0x7a, 0x77,
- 0xd6, 0xf8, 0xec, 0xb9, 0xf1, 0x68, 0x44, 0x42, 0x48, 0x13, 0xd2, 0xc0,
- 0xc2, 0xa4, 0xae, 0x5e, 0x60, 0xfe, 0xb6, 0xa6, 0x05, 0xfc, 0xb4, 0xdd,
- 0x07, 0x59, 0x02, 0xd4, 0x59, 0x18, 0x98, 0x63, 0xf5, 0xa5, 0x63, 0xe0,
- 0x90, 0x0c, 0x7d, 0x5d, 0xb2, 0x06, 0x7a, 0xf3, 0x85, 0xea, 0xeb, 0xd4,
- 0x03, 0xae, 0x5e, 0x84, 0x3e, 0x5f, 0xff, 0x15, 0xed, 0x69, 0xbc, 0xf9,
- 0x39, 0x36, 0x72, 0x75, 0xcf, 0x77, 0x52, 0x4d, 0xf3, 0xc9, 0x90, 0x2c,
- 0xb9, 0x3d, 0xe5, 0xc9, 0x23, 0x53, 0x3f, 0x1f, 0x24, 0x98, 0x21, 0x5c,
- 0x07, 0x99, 0x29, 0xbd, 0xc6, 0x3a, 0xec, 0xe7, 0x6e, 0x86, 0x3a, 0x6b,
- 0x97, 0x74, 0x63, 0x33, 0xbd, 0x68, 0x18, 0x31, 0xf0, 0x78, 0x8d, 0x76,
- 0xbf, 0xfc, 0x9e, 0x8e, 0x5d, 0x2a, 0x86, 0xa7, 0x4d, 0x90, 0xdc, 0x27,
- 0x1a, 0x39, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x6a, 0x30,
- 0x82, 0x01, 0x66, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01,
- 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x03, 0x30,
- 0x4e, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x47, 0x30, 0x45, 0x30, 0x43,
- 0x06, 0x04, 0x55, 0x1d, 0x20, 0x00, 0x30, 0x3b, 0x30, 0x39, 0x06, 0x08,
- 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x2d, 0x68, 0x74,
- 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x79, 0x62, 0x65, 0x72, 0x74, 0x72,
- 0x75, 0x73, 0x74, 0x2e, 0x6f, 0x6d, 0x6e, 0x69, 0x72, 0x6f, 0x6f, 0x74,
- 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74,
- 0x6f, 0x72, 0x79, 0x2e, 0x63, 0x66, 0x6d, 0x30, 0x0e, 0x06, 0x03, 0x55,
- 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30,
- 0x81, 0x89, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x81, 0x81, 0x30, 0x7f,
- 0xa1, 0x79, 0xa4, 0x77, 0x30, 0x75, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03,
- 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x18, 0x30, 0x16, 0x06,
- 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0f, 0x47, 0x54, 0x45, 0x20, 0x43, 0x6f,
- 0x72, 0x70, 0x6f, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x31, 0x27, 0x30,
- 0x25, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1e, 0x47, 0x54, 0x45, 0x20,
- 0x43, 0x79, 0x62, 0x65, 0x72, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x53,
- 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2c, 0x20, 0x49, 0x6e,
- 0x63, 0x2e, 0x31, 0x23, 0x30, 0x21, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
- 0x1a, 0x47, 0x54, 0x45, 0x20, 0x43, 0x79, 0x62, 0x65, 0x72, 0x54, 0x72,
- 0x75, 0x73, 0x74, 0x20, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x20, 0x52,
- 0x6f, 0x6f, 0x74, 0x82, 0x02, 0x01, 0xa5, 0x30, 0x45, 0x06, 0x03, 0x55,
- 0x1d, 0x1f, 0x04, 0x3e, 0x30, 0x3c, 0x30, 0x3a, 0xa0, 0x38, 0xa0, 0x36,
- 0x86, 0x34, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77,
- 0x2e, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x2d, 0x74, 0x72, 0x75, 0x73,
- 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x67, 0x69, 0x2d, 0x62, 0x69,
- 0x6e, 0x2f, 0x43, 0x52, 0x4c, 0x2f, 0x32, 0x30, 0x31, 0x38, 0x2f, 0x63,
- 0x64, 0x70, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d,
- 0x0e, 0x04, 0x16, 0x04, 0x14, 0xe5, 0x9d, 0x59, 0x30, 0x82, 0x47, 0x58,
- 0xcc, 0xac, 0xfa, 0x08, 0x54, 0x36, 0x86, 0x7b, 0x3a, 0xb5, 0x04, 0x4d,
- 0xf0, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
- 0x01, 0x05, 0x05, 0x00, 0x03, 0x81, 0x81, 0x00, 0x16, 0xb4, 0x2c, 0xc9,
- 0xf1, 0x5e, 0xe1, 0xa2, 0x7b, 0x9b, 0x78, 0x20, 0x7a, 0x4a, 0x70, 0x70,
- 0x86, 0x19, 0x00, 0xb7, 0x05, 0x2a, 0xe8, 0xc9, 0x25, 0x39, 0x0f, 0xc3,
- 0x64, 0x3c, 0x75, 0x09, 0xd9, 0x89, 0x15, 0x80, 0x07, 0xc2, 0x8d, 0xbc,
- 0x29, 0xa5, 0x64, 0x50, 0xcf, 0x71, 0x75, 0x47, 0x23, 0xbd, 0x4d, 0xd8,
- 0x7f, 0x77, 0x9a, 0x51, 0x10, 0x6e, 0x4e, 0x1f, 0x20, 0x3c, 0x47, 0x9c,
- 0x43, 0x74, 0x7f, 0x96, 0x84, 0x10, 0x4c, 0x13, 0x43, 0xbe, 0xf8, 0xe0,
- 0x72, 0x2e, 0xff, 0xbf, 0xae, 0x3c, 0x0a, 0x03, 0x60, 0x82, 0x4b, 0x6f,
- 0xf9, 0x9a, 0xc5, 0x1e, 0xf6, 0xaf, 0x90, 0x3b, 0x9f, 0x61, 0x3b, 0x3e,
- 0xde, 0x9b, 0x05, 0x1a, 0xc6, 0x2c, 0x3c, 0x57, 0x21, 0x08, 0x0f, 0x54,
- 0xfa, 0x28, 0x63, 0x6c, 0xe8, 0x1b, 0x9c, 0x0f, 0xcf, 0xdd, 0x30, 0x44,
- 0x13, 0xb9, 0x57, 0xfe,
-};
-
-#if 0
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number: 146040 (0x23a78)
- Signature Algorithm: sha256WithRSAEncryption
- Issuer: C=US, O=GeoTrust Inc., CN=GeoTrust Global CA
- Validity
- Not Before: Aug 29 22:24:58 2014 GMT
- Not After : May 20 22:24:58 2022 GMT
- Subject: C=US, O=GeoTrust Inc., OU=Domain Validated SSL, CN=GeoTrust DV SSL CA - G4
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:df:41:94:7a:da:f7:e4:31:43:b6:ea:01:1b:5c:
- ce:63:ea:fa:6d:a3:d9:6a:ee:2d:9a:75:f9:d5:9c:
- 5b:bd:34:df:d8:1c:c9:6d:d8:04:88:da:6e:b5:b7:
- b5:f0:30:ae:40:d6:5d:fa:c4:53:c1:d4:22:9d:04:
- 4e:11:a6:95:d5:45:7c:41:05:58:e0:4c:dd:f9:ee:
- 55:bd:5f:46:dc:ad:13:08:9d:2c:e4:f7:82:e6:07:
- 2b:9e:0e:8c:34:a1:ce:c4:a1:e0:81:70:86:00:06:
- 3f:2d:ea:7c:9b:28:ae:1b:28:8b:39:09:d3:e7:f0:
- 45:a4:b1:ba:11:67:90:55:7b:8f:de:ed:38:5c:a1:
- e1:e3:83:c4:c3:72:91:4f:98:ee:1c:c2:80:aa:64:
- a5:3e:83:62:1c:cc:e0:9e:f8:5a:c0:13:12:7d:a2:
- a7:8b:a3:e7:9f:2a:d7:9b:ca:cb:ed:97:01:9c:28:
- 84:51:04:50:41:bc:b4:fc:78:e9:1b:cf:14:ea:1f:
- 0f:fc:2e:01:32:8d:b6:35:cb:0a:18:3b:ec:5a:3e:
- 3c:1b:d3:99:43:1e:2f:f7:bd:f3:5b:12:b9:07:5e:
- ed:3e:d1:a9:87:cc:77:72:27:d4:d9:75:a2:63:4b:
- 93:36:bd:e5:5c:d7:bf:5f:79:0d:b3:32:a7:0b:b2:
- 63:23
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Authority Key Identifier:
- keyid:C0:7A:98:68:8D:89:FB:AB:05:64:0C:11:7D:AA:7D:65:B8:CA:CC:4E
-
- X509v3 Subject Key Identifier:
- 0B:50:EC:77:EF:2A:9B:FF:EC:03:A1:0A:FF:AD:C6:E4:2A:18:C7:3E
- X509v3 Basic Constraints: critical
- CA:TRUE, pathlen:0
- X509v3 Key Usage: critical
- Certificate Sign, CRL Sign
- X509v3 CRL Distribution Points:
-
- Full Name:
- URI:http://g.symcb.com/crls/gtglobal.crl
-
- Authority Information Access:
- OCSP - URI:http://g.symcd.com
-
- X509v3 Certificate Policies:
- Policy: 2.16.840.1.113733.1.7.54
- CPS: http://www.geotrust.com/resources/cps
-
- Signature Algorithm: sha256WithRSAEncryption
- 33:24:d5:90:aa:29:0c:35:b9:2f:c3:c7:42:93:c0:c6:10:4b:
- 03:08:76:84:10:a2:e0:e7:53:12:27:f2:0a:da:7f:3a:dc:fd:
- 5c:79:5a:8f:17:74:43:53:b1:d5:d1:5d:59:b9:a6:84:64:ca:
- f1:3a:0a:59:96:10:bf:a9:81:57:8b:5c:87:dc:7f:e3:e4:bb:
- 05:7a:a0:32:09:13:4e:10:81:28:1f:9c:03:62:bc:f4:01:b5:
- 29:83:46:07:b9:e7:b8:5d:c8:e9:d1:dd:ad:3b:f8:34:db:c1:
- d1:95:a9:91:18:ed:3c:2c:37:11:4d:cc:fe:53:3e:50:43:f9:
- c3:56:41:ac:53:9b:6c:05:b2:9a:e2:e0:59:57:30:32:b6:26:
- 4e:13:25:cd:fa:48:70:0f:75:55:60:11:f5:3b:d5:5e:5a:3c:
- 8b:5b:0f:0f:62:42:48:61:85:8b:10:f4:c1:88:bf:7f:5f:8a:
- c2:d7:cd:2b:94:5c:1f:34:4a:08:af:eb:ae:89:a8:48:75:55:
- 95:1d:bb:c0:9a:01:b9:f4:03:22:3e:d4:e6:52:30:0d:67:b9:
- c0:91:fd:2d:4c:30:8e:bd:8c:a5:04:91:bb:a4:ab:7f:0f:d8:
- 6f:f0:66:00:c9:a3:5c:f5:b0:8f:83:e6:9c:5a:e6:b6:b9:c5:
- bc:be:e4:02
------BEGIN CERTIFICATE-----
-MIIERDCCAyygAwIBAgIDAjp4MA0GCSqGSIb3DQEBCwUAMEIxCzAJBgNVBAYTAlVT
-MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i
-YWwgQ0EwHhcNMTQwODI5MjIyNDU4WhcNMjIwNTIwMjIyNDU4WjBmMQswCQYDVQQG
-EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEdMBsGA1UECxMURG9tYWluIFZh
-bGlkYXRlZCBTU0wxIDAeBgNVBAMTF0dlb1RydXN0IERWIFNTTCBDQSAtIEc0MIIB
-IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA30GUetr35DFDtuoBG1zOY+r6
-baPZau4tmnX51ZxbvTTf2BzJbdgEiNputbe18DCuQNZd+sRTwdQinQROEaaV1UV8
-QQVY4Ezd+e5VvV9G3K0TCJ0s5PeC5gcrng6MNKHOxKHggXCGAAY/Lep8myiuGyiL
-OQnT5/BFpLG6EWeQVXuP3u04XKHh44PEw3KRT5juHMKAqmSlPoNiHMzgnvhawBMS
-faKni6PnnyrXm8rL7ZcBnCiEUQRQQby0/HjpG88U6h8P/C4BMo22NcsKGDvsWj48
-G9OZQx4v973zWxK5B17tPtGph8x3cifU2XWiY0uTNr3lXNe/X3kNszKnC7JjIwID
-AQABo4IBHTCCARkwHwYDVR0jBBgwFoAUwHqYaI2J+6sFZAwRfap9ZbjKzE4wHQYD
-VR0OBBYEFAtQ7HfvKpv/7AOhCv+txuQqGMc+MBIGA1UdEwEB/wQIMAYBAf8CAQAw
-DgYDVR0PAQH/BAQDAgEGMDUGA1UdHwQuMCwwKqAooCaGJGh0dHA6Ly9nLnN5bWNi
-LmNvbS9jcmxzL2d0Z2xvYmFsLmNybDAuBggrBgEFBQcBAQQiMCAwHgYIKwYBBQUH
-MAGGEmh0dHA6Ly9nLnN5bWNkLmNvbTBMBgNVHSAERTBDMEEGCmCGSAGG+EUBBzYw
-MzAxBggrBgEFBQcCARYlaHR0cDovL3d3dy5nZW90cnVzdC5jb20vcmVzb3VyY2Vz
-L2NwczANBgkqhkiG9w0BAQsFAAOCAQEAMyTVkKopDDW5L8PHQpPAxhBLAwh2hBCi
-4OdTEifyCtp/Otz9XHlajxd0Q1Ox1dFdWbmmhGTK8ToKWZYQv6mBV4tch9x/4+S7
-BXqgMgkTThCBKB+cA2K89AG1KYNGB7nnuF3I6dHdrTv4NNvB0ZWpkRjtPCw3EU3M
-/lM+UEP5w1ZBrFObbAWymuLgWVcwMrYmThMlzfpIcA91VWAR9TvVXlo8i1sPD2JC
-SGGFixD0wYi/f1+KwtfNK5RcHzRKCK/rromoSHVVlR27wJoBufQDIj7U5lIwDWe5
-wJH9LUwwjr2MpQSRu6Srfw/Yb/BmAMmjXPWwj4PmnFrmtrnFvL7kAg==
------END CERTIFICATE-----
-#endif
-static const unsigned char kDERCert9[] = {
- 0x30, 0x82, 0x04, 0x44, 0x30, 0x82, 0x03, 0x2c, 0xa0, 0x03, 0x02, 0x01,
- 0x02, 0x02, 0x03, 0x02, 0x3a, 0x78, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
- 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x42, 0x31,
- 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53,
- 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0d, 0x47,
- 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x49, 0x6e, 0x63, 0x2e,
- 0x31, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x12, 0x47,
- 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x47, 0x6c, 0x6f, 0x62,
- 0x61, 0x6c, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x34, 0x30,
- 0x38, 0x32, 0x39, 0x32, 0x32, 0x32, 0x34, 0x35, 0x38, 0x5a, 0x17, 0x0d,
- 0x32, 0x32, 0x30, 0x35, 0x32, 0x30, 0x32, 0x32, 0x32, 0x34, 0x35, 0x38,
- 0x5a, 0x30, 0x66, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06,
- 0x13, 0x02, 0x55, 0x53, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04,
- 0x0a, 0x13, 0x0d, 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20,
- 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x1d, 0x30, 0x1b, 0x06, 0x03, 0x55, 0x04,
- 0x0b, 0x13, 0x14, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x20, 0x56, 0x61,
- 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x64, 0x20, 0x53, 0x53, 0x4c, 0x31,
- 0x20, 0x30, 0x1e, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x17, 0x47, 0x65,
- 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x44, 0x56, 0x20, 0x53, 0x53,
- 0x4c, 0x20, 0x43, 0x41, 0x20, 0x2d, 0x20, 0x47, 0x34, 0x30, 0x82, 0x01,
- 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
- 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01,
- 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xdf, 0x41, 0x94, 0x7a, 0xda, 0xf7,
- 0xe4, 0x31, 0x43, 0xb6, 0xea, 0x01, 0x1b, 0x5c, 0xce, 0x63, 0xea, 0xfa,
- 0x6d, 0xa3, 0xd9, 0x6a, 0xee, 0x2d, 0x9a, 0x75, 0xf9, 0xd5, 0x9c, 0x5b,
- 0xbd, 0x34, 0xdf, 0xd8, 0x1c, 0xc9, 0x6d, 0xd8, 0x04, 0x88, 0xda, 0x6e,
- 0xb5, 0xb7, 0xb5, 0xf0, 0x30, 0xae, 0x40, 0xd6, 0x5d, 0xfa, 0xc4, 0x53,
- 0xc1, 0xd4, 0x22, 0x9d, 0x04, 0x4e, 0x11, 0xa6, 0x95, 0xd5, 0x45, 0x7c,
- 0x41, 0x05, 0x58, 0xe0, 0x4c, 0xdd, 0xf9, 0xee, 0x55, 0xbd, 0x5f, 0x46,
- 0xdc, 0xad, 0x13, 0x08, 0x9d, 0x2c, 0xe4, 0xf7, 0x82, 0xe6, 0x07, 0x2b,
- 0x9e, 0x0e, 0x8c, 0x34, 0xa1, 0xce, 0xc4, 0xa1, 0xe0, 0x81, 0x70, 0x86,
- 0x00, 0x06, 0x3f, 0x2d, 0xea, 0x7c, 0x9b, 0x28, 0xae, 0x1b, 0x28, 0x8b,
- 0x39, 0x09, 0xd3, 0xe7, 0xf0, 0x45, 0xa4, 0xb1, 0xba, 0x11, 0x67, 0x90,
- 0x55, 0x7b, 0x8f, 0xde, 0xed, 0x38, 0x5c, 0xa1, 0xe1, 0xe3, 0x83, 0xc4,
- 0xc3, 0x72, 0x91, 0x4f, 0x98, 0xee, 0x1c, 0xc2, 0x80, 0xaa, 0x64, 0xa5,
- 0x3e, 0x83, 0x62, 0x1c, 0xcc, 0xe0, 0x9e, 0xf8, 0x5a, 0xc0, 0x13, 0x12,
- 0x7d, 0xa2, 0xa7, 0x8b, 0xa3, 0xe7, 0x9f, 0x2a, 0xd7, 0x9b, 0xca, 0xcb,
- 0xed, 0x97, 0x01, 0x9c, 0x28, 0x84, 0x51, 0x04, 0x50, 0x41, 0xbc, 0xb4,
- 0xfc, 0x78, 0xe9, 0x1b, 0xcf, 0x14, 0xea, 0x1f, 0x0f, 0xfc, 0x2e, 0x01,
- 0x32, 0x8d, 0xb6, 0x35, 0xcb, 0x0a, 0x18, 0x3b, 0xec, 0x5a, 0x3e, 0x3c,
- 0x1b, 0xd3, 0x99, 0x43, 0x1e, 0x2f, 0xf7, 0xbd, 0xf3, 0x5b, 0x12, 0xb9,
- 0x07, 0x5e, 0xed, 0x3e, 0xd1, 0xa9, 0x87, 0xcc, 0x77, 0x72, 0x27, 0xd4,
- 0xd9, 0x75, 0xa2, 0x63, 0x4b, 0x93, 0x36, 0xbd, 0xe5, 0x5c, 0xd7, 0xbf,
- 0x5f, 0x79, 0x0d, 0xb3, 0x32, 0xa7, 0x0b, 0xb2, 0x63, 0x23, 0x02, 0x03,
- 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x1d, 0x30, 0x82, 0x01, 0x19, 0x30,
- 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14,
- 0xc0, 0x7a, 0x98, 0x68, 0x8d, 0x89, 0xfb, 0xab, 0x05, 0x64, 0x0c, 0x11,
- 0x7d, 0xaa, 0x7d, 0x65, 0xb8, 0xca, 0xcc, 0x4e, 0x30, 0x1d, 0x06, 0x03,
- 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x0b, 0x50, 0xec, 0x77, 0xef,
- 0x2a, 0x9b, 0xff, 0xec, 0x03, 0xa1, 0x0a, 0xff, 0xad, 0xc6, 0xe4, 0x2a,
- 0x18, 0xc7, 0x3e, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01,
- 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x00, 0x30,
- 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03,
- 0x02, 0x01, 0x06, 0x30, 0x35, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x2e,
- 0x30, 0x2c, 0x30, 0x2a, 0xa0, 0x28, 0xa0, 0x26, 0x86, 0x24, 0x68, 0x74,
- 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x67, 0x2e, 0x73, 0x79, 0x6d, 0x63, 0x62,
- 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x72, 0x6c, 0x73, 0x2f, 0x67, 0x74,
- 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x2e,
- 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x22,
- 0x30, 0x20, 0x30, 0x1e, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
- 0x30, 0x01, 0x86, 0x12, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x67,
- 0x2e, 0x73, 0x79, 0x6d, 0x63, 0x64, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x4c,
- 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x45, 0x30, 0x43, 0x30, 0x41, 0x06,
- 0x0a, 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x45, 0x01, 0x07, 0x36, 0x30,
- 0x33, 0x30, 0x31, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02,
- 0x01, 0x16, 0x25, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77,
- 0x77, 0x2e, 0x67, 0x65, 0x6f, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63,
- 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73,
- 0x2f, 0x63, 0x70, 0x73, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
- 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00,
- 0x33, 0x24, 0xd5, 0x90, 0xaa, 0x29, 0x0c, 0x35, 0xb9, 0x2f, 0xc3, 0xc7,
- 0x42, 0x93, 0xc0, 0xc6, 0x10, 0x4b, 0x03, 0x08, 0x76, 0x84, 0x10, 0xa2,
- 0xe0, 0xe7, 0x53, 0x12, 0x27, 0xf2, 0x0a, 0xda, 0x7f, 0x3a, 0xdc, 0xfd,
- 0x5c, 0x79, 0x5a, 0x8f, 0x17, 0x74, 0x43, 0x53, 0xb1, 0xd5, 0xd1, 0x5d,
- 0x59, 0xb9, 0xa6, 0x84, 0x64, 0xca, 0xf1, 0x3a, 0x0a, 0x59, 0x96, 0x10,
- 0xbf, 0xa9, 0x81, 0x57, 0x8b, 0x5c, 0x87, 0xdc, 0x7f, 0xe3, 0xe4, 0xbb,
- 0x05, 0x7a, 0xa0, 0x32, 0x09, 0x13, 0x4e, 0x10, 0x81, 0x28, 0x1f, 0x9c,
- 0x03, 0x62, 0xbc, 0xf4, 0x01, 0xb5, 0x29, 0x83, 0x46, 0x07, 0xb9, 0xe7,
- 0xb8, 0x5d, 0xc8, 0xe9, 0xd1, 0xdd, 0xad, 0x3b, 0xf8, 0x34, 0xdb, 0xc1,
- 0xd1, 0x95, 0xa9, 0x91, 0x18, 0xed, 0x3c, 0x2c, 0x37, 0x11, 0x4d, 0xcc,
- 0xfe, 0x53, 0x3e, 0x50, 0x43, 0xf9, 0xc3, 0x56, 0x41, 0xac, 0x53, 0x9b,
- 0x6c, 0x05, 0xb2, 0x9a, 0xe2, 0xe0, 0x59, 0x57, 0x30, 0x32, 0xb6, 0x26,
- 0x4e, 0x13, 0x25, 0xcd, 0xfa, 0x48, 0x70, 0x0f, 0x75, 0x55, 0x60, 0x11,
- 0xf5, 0x3b, 0xd5, 0x5e, 0x5a, 0x3c, 0x8b, 0x5b, 0x0f, 0x0f, 0x62, 0x42,
- 0x48, 0x61, 0x85, 0x8b, 0x10, 0xf4, 0xc1, 0x88, 0xbf, 0x7f, 0x5f, 0x8a,
- 0xc2, 0xd7, 0xcd, 0x2b, 0x94, 0x5c, 0x1f, 0x34, 0x4a, 0x08, 0xaf, 0xeb,
- 0xae, 0x89, 0xa8, 0x48, 0x75, 0x55, 0x95, 0x1d, 0xbb, 0xc0, 0x9a, 0x01,
- 0xb9, 0xf4, 0x03, 0x22, 0x3e, 0xd4, 0xe6, 0x52, 0x30, 0x0d, 0x67, 0xb9,
- 0xc0, 0x91, 0xfd, 0x2d, 0x4c, 0x30, 0x8e, 0xbd, 0x8c, 0xa5, 0x04, 0x91,
- 0xbb, 0xa4, 0xab, 0x7f, 0x0f, 0xd8, 0x6f, 0xf0, 0x66, 0x00, 0xc9, 0xa3,
- 0x5c, 0xf5, 0xb0, 0x8f, 0x83, 0xe6, 0x9c, 0x5a, 0xe6, 0xb6, 0xb9, 0xc5,
- 0xbc, 0xbe, 0xe4, 0x02,
-};
-
-#if 0
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number:
- 33:65:50:08:79:ad:73:e2:30:b9:e0:1d:0d:7f:ac:91
- Signature Algorithm: sha1WithRSAEncryption
- Issuer: C=ZA, ST=Western Cape, L=Cape Town, O=Thawte Consulting cc, OU=Certification Services Division, CN=Thawte Premium Server CA/emailAddress=premium-server@thawte.com
- Validity
- Not Before: Nov 17 00:00:00 2006 GMT
- Not After : Dec 30 23:59:59 2020 GMT
- Subject: C=US, O=thawte, Inc., OU=Certification Services Division, OU=(c) 2006 thawte, Inc. - For authorized use only, CN=thawte Primary Root CA
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:ac:a0:f0:fb:80:59:d4:9c:c7:a4:cf:9d:a1:59:
- 73:09:10:45:0c:0d:2c:6e:68:f1:6c:5b:48:68:49:
- 59:37:fc:0b:33:19:c2:77:7f:cc:10:2d:95:34:1c:
- e6:eb:4d:09:a7:1c:d2:b8:c9:97:36:02:b7:89:d4:
- 24:5f:06:c0:cc:44:94:94:8d:02:62:6f:eb:5a:dd:
- 11:8d:28:9a:5c:84:90:10:7a:0d:bd:74:66:2f:6a:
- 38:a0:e2:d5:54:44:eb:1d:07:9f:07:ba:6f:ee:e9:
- fd:4e:0b:29:f5:3e:84:a0:01:f1:9c:ab:f8:1c:7e:
- 89:a4:e8:a1:d8:71:65:0d:a3:51:7b:ee:bc:d2:22:
- 60:0d:b9:5b:9d:df:ba:fc:51:5b:0b:af:98:b2:e9:
- 2e:e9:04:e8:62:87:de:2b:c8:d7:4e:c1:4c:64:1e:
- dd:cf:87:58:ba:4a:4f:ca:68:07:1d:1c:9d:4a:c6:
- d5:2f:91:cc:7c:71:72:1c:c5:c0:67:eb:32:fd:c9:
- 92:5c:94:da:85:c0:9b:bf:53:7d:2b:09:f4:8c:9d:
- 91:1f:97:6a:52:cb:de:09:36:a4:77:d8:7b:87:50:
- 44:d5:3e:6e:29:69:fb:39:49:26:1e:09:a5:80:7b:
- 40:2d:eb:e8:27:85:c9:fe:61:fd:7e:e6:7c:97:1d:
- d5:9d
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Basic Constraints: critical
- CA:TRUE
- X509v3 Certificate Policies:
- Policy: X509v3 Any Policy
- CPS: https://www.thawte.com/cps
-
- X509v3 Key Usage: critical
- Certificate Sign, CRL Sign
- X509v3 Subject Key Identifier:
- 7B:5B:45:CF:AF:CE:CB:7A:FD:31:92:1A:6A:B6:F3:46:EB:57:48:50
- X509v3 CRL Distribution Points:
-
- Full Name:
- URI:http://crl.thawte.com/ThawtePremiumServerCA.crl
-
- Signature Algorithm: sha1WithRSAEncryption
- 84:a8:4c:c9:3e:2a:bc:9a:e2:cc:8f:0b:b2:25:77:c4:61:89:
- 89:63:5a:d4:a3:15:40:d4:fb:5e:3f:b4:43:ea:63:17:2b:6b:
- 99:74:9e:09:a8:dd:d4:56:15:2e:7a:79:31:5f:63:96:53:1b:
- 34:d9:15:ea:4f:6d:70:ca:be:f6:82:a9:ed:da:85:77:cc:76:
- 1c:6a:81:0a:21:d8:41:99:7f:5e:2e:82:c1:e8:aa:f7:93:81:
- 05:aa:92:b4:1f:b7:9a:c0:07:17:f5:cb:c6:b4:4c:0e:d7:56:
- dc:71:20:74:38:d6:74:c6:d6:8f:6b:af:8b:8d:a0:6c:29:0b:
- 61:e0
------BEGIN CERTIFICATE-----
-MIIERTCCA66gAwIBAgIQM2VQCHmtc+IwueAdDX+skTANBgkqhkiG9w0BAQUFADCB
-zjELMAkGA1UEBhMCWkExFTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJ
-Q2FwZSBUb3duMR0wGwYDVQQKExRUaGF3dGUgQ29uc3VsdGluZyBjYzEoMCYGA1UE
-CxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjEhMB8GA1UEAxMYVGhh
-d3RlIFByZW1pdW0gU2VydmVyIENBMSgwJgYJKoZIhvcNAQkBFhlwcmVtaXVtLXNl
-cnZlckB0aGF3dGUuY29tMB4XDTA2MTExNzAwMDAwMFoXDTIwMTIzMDIzNTk1OVow
-gakxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwx0aGF3dGUsIEluYy4xKDAmBgNVBAsT
-H0NlcnRpZmljYXRpb24gU2VydmljZXMgRGl2aXNpb24xODA2BgNVBAsTLyhjKSAy
-MDA2IHRoYXd0ZSwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MR8wHQYD
-VQQDExZ0aGF3dGUgUHJpbWFyeSBSb290IENBMIIBIjANBgkqhkiG9w0BAQEFAAOC
-AQ8AMIIBCgKCAQEArKDw+4BZ1JzHpM+doVlzCRBFDA0sbmjxbFtIaElZN/wLMxnC
-d3/MEC2VNBzm600JpxzSuMmXNgK3idQkXwbAzESUlI0CYm/rWt0RjSiaXISQEHoN
-vXRmL2o4oOLVVETrHQefB7pv7un9Tgsp9T6EoAHxnKv4HH6JpOih2HFlDaNRe+68
-0iJgDblbnd+6/FFbC6+Ysuku6QToYofeK8jXTsFMZB7dz4dYukpPymgHHRydSsbV
-L5HMfHFyHMXAZ+sy/cmSXJTahcCbv1N9Kwn0jJ2RH5dqUsveCTakd9h7h1BE1T5u
-KWn7OUkmHgmlgHtALevoJ4XJ/mH9fuZ8lx3VnQIDAQABo4HCMIG/MA8GA1UdEwEB
-/wQFMAMBAf8wOwYDVR0gBDQwMjAwBgRVHSAAMCgwJgYIKwYBBQUHAgEWGmh0dHBz
-Oi8vd3d3LnRoYXd0ZS5jb20vY3BzMA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQU
-e1tFz6/Oy3r9MZIaarbzRutXSFAwQAYDVR0fBDkwNzA1oDOgMYYvaHR0cDovL2Ny
-bC50aGF3dGUuY29tL1RoYXd0ZVByZW1pdW1TZXJ2ZXJDQS5jcmwwDQYJKoZIhvcN
-AQEFBQADgYEAhKhMyT4qvJrizI8LsiV3xGGJiWNa1KMVQNT7Xj+0Q+pjFytrmXSe
-Cajd1FYVLnp5MV9jllMbNNkV6k9tcMq+9oKp7dqFd8x2HGqBCiHYQZl/Xi6Cweiq
-95OBBaqStB+3msAHF/XLxrRMDtdW3HEgdDjWdMbWj2uvi42gbCkLYeA=
------END CERTIFICATE-----
-#endif
-static const unsigned char kDERCert10[] = {
- 0x30, 0x82, 0x04, 0x45, 0x30, 0x82, 0x03, 0xae, 0xa0, 0x03, 0x02, 0x01,
- 0x02, 0x02, 0x10, 0x33, 0x65, 0x50, 0x08, 0x79, 0xad, 0x73, 0xe2, 0x30,
- 0xb9, 0xe0, 0x1d, 0x0d, 0x7f, 0xac, 0x91, 0x30, 0x0d, 0x06, 0x09, 0x2a,
- 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x81,
- 0xce, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
- 0x5a, 0x41, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13,
- 0x0c, 0x57, 0x65, 0x73, 0x74, 0x65, 0x72, 0x6e, 0x20, 0x43, 0x61, 0x70,
- 0x65, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x09,
- 0x43, 0x61, 0x70, 0x65, 0x20, 0x54, 0x6f, 0x77, 0x6e, 0x31, 0x1d, 0x30,
- 0x1b, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x14, 0x54, 0x68, 0x61, 0x77,
- 0x74, 0x65, 0x20, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x74, 0x69, 0x6e,
- 0x67, 0x20, 0x63, 0x63, 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, 0x04,
- 0x0b, 0x13, 0x1f, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61,
- 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
- 0x73, 0x20, 0x44, 0x69, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x31, 0x21,
- 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x18, 0x54, 0x68, 0x61,
- 0x77, 0x74, 0x65, 0x20, 0x50, 0x72, 0x65, 0x6d, 0x69, 0x75, 0x6d, 0x20,
- 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x43, 0x41, 0x31, 0x28, 0x30,
- 0x26, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01,
- 0x16, 0x19, 0x70, 0x72, 0x65, 0x6d, 0x69, 0x75, 0x6d, 0x2d, 0x73, 0x65,
- 0x72, 0x76, 0x65, 0x72, 0x40, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2e,
- 0x63, 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x36, 0x31, 0x31, 0x31,
- 0x37, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x30,
- 0x31, 0x32, 0x33, 0x30, 0x32, 0x33, 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30,
- 0x81, 0xa9, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
- 0x02, 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0a,
- 0x13, 0x0c, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2c, 0x20, 0x49, 0x6e,
- 0x63, 0x2e, 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13,
- 0x1f, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69,
- 0x6f, 0x6e, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20,
- 0x44, 0x69, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x31, 0x38, 0x30, 0x36,
- 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x2f, 0x28, 0x63, 0x29, 0x20, 0x32,
- 0x30, 0x30, 0x36, 0x20, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2c, 0x20,
- 0x49, 0x6e, 0x63, 0x2e, 0x20, 0x2d, 0x20, 0x46, 0x6f, 0x72, 0x20, 0x61,
- 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x20, 0x75, 0x73,
- 0x65, 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03,
- 0x55, 0x04, 0x03, 0x13, 0x16, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x20,
- 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x20, 0x52, 0x6f, 0x6f, 0x74,
- 0x20, 0x43, 0x41, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a,
- 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82,
- 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00,
- 0xac, 0xa0, 0xf0, 0xfb, 0x80, 0x59, 0xd4, 0x9c, 0xc7, 0xa4, 0xcf, 0x9d,
- 0xa1, 0x59, 0x73, 0x09, 0x10, 0x45, 0x0c, 0x0d, 0x2c, 0x6e, 0x68, 0xf1,
- 0x6c, 0x5b, 0x48, 0x68, 0x49, 0x59, 0x37, 0xfc, 0x0b, 0x33, 0x19, 0xc2,
- 0x77, 0x7f, 0xcc, 0x10, 0x2d, 0x95, 0x34, 0x1c, 0xe6, 0xeb, 0x4d, 0x09,
- 0xa7, 0x1c, 0xd2, 0xb8, 0xc9, 0x97, 0x36, 0x02, 0xb7, 0x89, 0xd4, 0x24,
- 0x5f, 0x06, 0xc0, 0xcc, 0x44, 0x94, 0x94, 0x8d, 0x02, 0x62, 0x6f, 0xeb,
- 0x5a, 0xdd, 0x11, 0x8d, 0x28, 0x9a, 0x5c, 0x84, 0x90, 0x10, 0x7a, 0x0d,
- 0xbd, 0x74, 0x66, 0x2f, 0x6a, 0x38, 0xa0, 0xe2, 0xd5, 0x54, 0x44, 0xeb,
- 0x1d, 0x07, 0x9f, 0x07, 0xba, 0x6f, 0xee, 0xe9, 0xfd, 0x4e, 0x0b, 0x29,
- 0xf5, 0x3e, 0x84, 0xa0, 0x01, 0xf1, 0x9c, 0xab, 0xf8, 0x1c, 0x7e, 0x89,
- 0xa4, 0xe8, 0xa1, 0xd8, 0x71, 0x65, 0x0d, 0xa3, 0x51, 0x7b, 0xee, 0xbc,
- 0xd2, 0x22, 0x60, 0x0d, 0xb9, 0x5b, 0x9d, 0xdf, 0xba, 0xfc, 0x51, 0x5b,
- 0x0b, 0xaf, 0x98, 0xb2, 0xe9, 0x2e, 0xe9, 0x04, 0xe8, 0x62, 0x87, 0xde,
- 0x2b, 0xc8, 0xd7, 0x4e, 0xc1, 0x4c, 0x64, 0x1e, 0xdd, 0xcf, 0x87, 0x58,
- 0xba, 0x4a, 0x4f, 0xca, 0x68, 0x07, 0x1d, 0x1c, 0x9d, 0x4a, 0xc6, 0xd5,
- 0x2f, 0x91, 0xcc, 0x7c, 0x71, 0x72, 0x1c, 0xc5, 0xc0, 0x67, 0xeb, 0x32,
- 0xfd, 0xc9, 0x92, 0x5c, 0x94, 0xda, 0x85, 0xc0, 0x9b, 0xbf, 0x53, 0x7d,
- 0x2b, 0x09, 0xf4, 0x8c, 0x9d, 0x91, 0x1f, 0x97, 0x6a, 0x52, 0xcb, 0xde,
- 0x09, 0x36, 0xa4, 0x77, 0xd8, 0x7b, 0x87, 0x50, 0x44, 0xd5, 0x3e, 0x6e,
- 0x29, 0x69, 0xfb, 0x39, 0x49, 0x26, 0x1e, 0x09, 0xa5, 0x80, 0x7b, 0x40,
- 0x2d, 0xeb, 0xe8, 0x27, 0x85, 0xc9, 0xfe, 0x61, 0xfd, 0x7e, 0xe6, 0x7c,
- 0x97, 0x1d, 0xd5, 0x9d, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x81, 0xc2,
- 0x30, 0x81, 0xbf, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01,
- 0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x3b, 0x06, 0x03,
- 0x55, 0x1d, 0x20, 0x04, 0x34, 0x30, 0x32, 0x30, 0x30, 0x06, 0x04, 0x55,
- 0x1d, 0x20, 0x00, 0x30, 0x28, 0x30, 0x26, 0x06, 0x08, 0x2b, 0x06, 0x01,
- 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x1a, 0x68, 0x74, 0x74, 0x70, 0x73,
- 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x74, 0x68, 0x61, 0x77, 0x74,
- 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x70, 0x73, 0x30, 0x0e, 0x06,
- 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01,
- 0x06, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14,
- 0x7b, 0x5b, 0x45, 0xcf, 0xaf, 0xce, 0xcb, 0x7a, 0xfd, 0x31, 0x92, 0x1a,
- 0x6a, 0xb6, 0xf3, 0x46, 0xeb, 0x57, 0x48, 0x50, 0x30, 0x40, 0x06, 0x03,
- 0x55, 0x1d, 0x1f, 0x04, 0x39, 0x30, 0x37, 0x30, 0x35, 0xa0, 0x33, 0xa0,
- 0x31, 0x86, 0x2f, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72,
- 0x6c, 0x2e, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2e, 0x63, 0x6f, 0x6d,
- 0x2f, 0x54, 0x68, 0x61, 0x77, 0x74, 0x65, 0x50, 0x72, 0x65, 0x6d, 0x69,
- 0x75, 0x6d, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x43, 0x41, 0x2e, 0x63,
- 0x72, 0x6c, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
- 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x81, 0x81, 0x00, 0x84, 0xa8, 0x4c,
- 0xc9, 0x3e, 0x2a, 0xbc, 0x9a, 0xe2, 0xcc, 0x8f, 0x0b, 0xb2, 0x25, 0x77,
- 0xc4, 0x61, 0x89, 0x89, 0x63, 0x5a, 0xd4, 0xa3, 0x15, 0x40, 0xd4, 0xfb,
- 0x5e, 0x3f, 0xb4, 0x43, 0xea, 0x63, 0x17, 0x2b, 0x6b, 0x99, 0x74, 0x9e,
- 0x09, 0xa8, 0xdd, 0xd4, 0x56, 0x15, 0x2e, 0x7a, 0x79, 0x31, 0x5f, 0x63,
- 0x96, 0x53, 0x1b, 0x34, 0xd9, 0x15, 0xea, 0x4f, 0x6d, 0x70, 0xca, 0xbe,
- 0xf6, 0x82, 0xa9, 0xed, 0xda, 0x85, 0x77, 0xcc, 0x76, 0x1c, 0x6a, 0x81,
- 0x0a, 0x21, 0xd8, 0x41, 0x99, 0x7f, 0x5e, 0x2e, 0x82, 0xc1, 0xe8, 0xaa,
- 0xf7, 0x93, 0x81, 0x05, 0xaa, 0x92, 0xb4, 0x1f, 0xb7, 0x9a, 0xc0, 0x07,
- 0x17, 0xf5, 0xcb, 0xc6, 0xb4, 0x4c, 0x0e, 0xd7, 0x56, 0xdc, 0x71, 0x20,
- 0x74, 0x38, 0xd6, 0x74, 0xc6, 0xd6, 0x8f, 0x6b, 0xaf, 0x8b, 0x8d, 0xa0,
- 0x6c, 0x29, 0x0b, 0x61, 0xe0,
-};
-
-#if 0
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number:
- 04:00:00:00:00:01:44:4e:f0:36:31
- Signature Algorithm: sha256WithRSAEncryption
- Issuer: C=BE, O=GlobalSign nv-sa, OU=Root CA, CN=GlobalSign Root CA
- Validity
- Not Before: Feb 20 10:00:00 2014 GMT
- Not After : Feb 20 10:00:00 2024 GMT
- Subject: C=BE, O=GlobalSign nv-sa, CN=AlphaSSL CA - SHA256 - G2
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:da:01:ec:e4:ec:73:60:fb:7e:8f:6a:b7:c6:17:
- e3:92:64:32:d4:ac:00:d9:a2:0f:b9:ed:ee:6b:8a:
- 86:ca:92:67:d9:74:d7:5d:47:02:3c:8f:40:d6:9e:
- 6d:14:cd:c3:da:29:39:a7:0f:05:0a:68:a2:66:1a:
- 1e:c4:b2:8b:76:58:e5:ab:5d:1d:8f:40:b3:39:8b:
- ef:1e:83:7d:22:d0:e3:a9:00:2e:ec:53:cf:62:19:
- 85:44:28:4c:c0:27:cb:7b:0e:ec:10:64:00:10:a4:
- 05:cc:a0:72:be:41:6c:31:5b:48:e4:b1:ec:b9:23:
- eb:55:4d:d0:7d:62:4a:a5:b4:a5:a4:59:85:c5:25:
- 91:a6:fe:a6:09:9f:06:10:6d:8f:81:0c:64:40:5e:
- 73:00:9a:e0:2e:65:98:54:10:00:70:98:c8:e1:ed:
- 34:5f:d8:9c:c7:0d:c0:d6:23:59:45:fc:fe:55:7a:
- 86:ee:94:60:22:f1:ae:d1:e6:55:46:f6:99:c5:1b:
- 08:74:5f:ac:b0:64:84:8f:89:38:1c:a1:a7:90:21:
- 4f:02:6e:bd:e0:61:67:d4:f8:42:87:0f:0a:f7:c9:
- 04:6d:2a:a9:2f:ef:42:a5:df:dd:a3:53:db:98:1e:
- 81:f9:9a:72:7b:5a:de:4f:3e:7f:a2:58:a0:e2:17:
- ad:67
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Key Usage: critical
- Certificate Sign, CRL Sign
- X509v3 Basic Constraints: critical
- CA:TRUE, pathlen:0
- X509v3 Subject Key Identifier:
- F5:CD:D5:3C:08:50:F9:6A:4F:3A:B7:97:DA:56:83:E6:69:D2:68:F7
- X509v3 Certificate Policies:
- Policy: X509v3 Any Policy
- CPS: https://www.alphassl.com/repository/
-
- X509v3 CRL Distribution Points:
-
- Full Name:
- URI:http://crl.globalsign.net/root.crl
-
- Authority Information Access:
- OCSP - URI:http://ocsp.globalsign.com/rootr1
-
- X509v3 Authority Key Identifier:
- keyid:60:7B:66:1A:45:0D:97:CA:89:50:2F:7D:04:CD:34:A8:FF:FC:FD:4B
-
- Signature Algorithm: sha256WithRSAEncryption
- 60:40:68:16:47:e7:16:8d:db:5c:a1:56:2a:cb:f4:5c:9b:b0:
- 1e:a2:4b:f5:cb:02:3f:f8:0b:a1:f2:a7:42:d4:b7:4c:eb:e3:
- 66:80:f3:25:43:78:2e:1b:17:56:07:52:18:cb:d1:a8:ec:e6:
- fb:73:3e:a4:62:8c:80:b4:d2:c5:12:73:a3:d3:fa:02:38:be:
- 63:3d:84:b8:99:c1:f1:ba:f7:9f:c3:40:d1:58:18:53:c1:62:
- dd:af:18:42:7f:34:4e:c5:43:d5:71:b0:30:00:c7:e3:90:ae:
- 3f:57:86:97:ce:ea:0c:12:8e:22:70:e3:66:a7:54:7f:2e:28:
- cb:d4:54:d0:b3:1e:62:67:08:f9:27:e1:cb:e3:66:b8:24:1b:
- 89:6a:89:44:65:f2:d9:4c:d2:58:1c:8c:4e:c0:95:a1:d4:ef:
- 67:2f:38:20:e8:2e:ff:96:51:f0:ba:d8:3d:92:70:47:65:1c:
- 9e:73:72:b4:60:0c:5c:e2:d1:73:76:e0:af:4e:e2:e5:37:a5:
- 45:2f:8a:23:3e:87:c7:30:e6:31:38:7c:f4:dd:52:ca:f3:53:
- 04:25:57:56:66:94:e8:0b:ee:e6:03:14:4e:ee:fd:6d:94:64:
- 9e:5e:ce:79:d4:b2:a6:cf:40:b1:44:a8:3e:87:19:5e:e9:f8:
- 21:16:59:53
------BEGIN CERTIFICATE-----
-MIIETTCCAzWgAwIBAgILBAAAAAABRE7wNjEwDQYJKoZIhvcNAQELBQAwVzELMAkG
-A1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jv
-b3QgQ0ExGzAZBgNVBAMTEkdsb2JhbFNpZ24gUm9vdCBDQTAeFw0xNDAyMjAxMDAw
-MDBaFw0yNDAyMjAxMDAwMDBaMEwxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9i
-YWxTaWduIG52LXNhMSIwIAYDVQQDExlBbHBoYVNTTCBDQSAtIFNIQTI1NiAtIEcy
-MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2gHs5OxzYPt+j2q3xhfj
-kmQy1KwA2aIPue3ua4qGypJn2XTXXUcCPI9A1p5tFM3D2ik5pw8FCmiiZhoexLKL
-dljlq10dj0CzOYvvHoN9ItDjqQAu7FPPYhmFRChMwCfLew7sEGQAEKQFzKByvkFs
-MVtI5LHsuSPrVU3QfWJKpbSlpFmFxSWRpv6mCZ8GEG2PgQxkQF5zAJrgLmWYVBAA
-cJjI4e00X9icxw3A1iNZRfz+VXqG7pRgIvGu0eZVRvaZxRsIdF+ssGSEj4k4HKGn
-kCFPAm694GFn1PhChw8K98kEbSqpL+9Cpd/do1PbmB6B+Zpye1reTz5/olig4het
-ZwIDAQABo4IBIzCCAR8wDgYDVR0PAQH/BAQDAgEGMBIGA1UdEwEB/wQIMAYBAf8C
-AQAwHQYDVR0OBBYEFPXN1TwIUPlqTzq3l9pWg+Zp0mj3MEUGA1UdIAQ+MDwwOgYE
-VR0gADAyMDAGCCsGAQUFBwIBFiRodHRwczovL3d3dy5hbHBoYXNzbC5jb20vcmVw
-b3NpdG9yeS8wMwYDVR0fBCwwKjAooCagJIYiaHR0cDovL2NybC5nbG9iYWxzaWdu
-Lm5ldC9yb290LmNybDA9BggrBgEFBQcBAQQxMC8wLQYIKwYBBQUHMAGGIWh0dHA6
-Ly9vY3NwLmdsb2JhbHNpZ24uY29tL3Jvb3RyMTAfBgNVHSMEGDAWgBRge2YaRQ2X
-yolQL30EzTSo//z9SzANBgkqhkiG9w0BAQsFAAOCAQEAYEBoFkfnFo3bXKFWKsv0
-XJuwHqJL9csCP/gLofKnQtS3TOvjZoDzJUN4LhsXVgdSGMvRqOzm+3M+pGKMgLTS
-xRJzo9P6Aji+Yz2EuJnB8br3n8NA0VgYU8Fi3a8YQn80TsVD1XGwMADH45CuP1eG
-l87qDBKOInDjZqdUfy4oy9RU0LMeYmcI+Sfhy+NmuCQbiWqJRGXy2UzSWByMTsCV
-odTvZy84IOgu/5ZR8LrYPZJwR2UcnnNytGAMXOLRc3bgr07i5TelRS+KIz6HxzDm
-MTh89N1SyvNTBCVXVmaU6Avu5gMUTu79bZRknl7OedSyps9AsUSoPocZXun4IRZZ
-Uw==
------END CERTIFICATE-----
-#endif
-static const unsigned char kDERCert11[] = {
- 0x30, 0x82, 0x04, 0x4d, 0x30, 0x82, 0x03, 0x35, 0xa0, 0x03, 0x02, 0x01,
- 0x02, 0x02, 0x0b, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01, 0x44, 0x4e, 0xf0,
- 0x36, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
- 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x57, 0x31, 0x0b, 0x30, 0x09, 0x06,
- 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x42, 0x45, 0x31, 0x19, 0x30, 0x17,
- 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x10, 0x47, 0x6c, 0x6f, 0x62, 0x61,
- 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x6e, 0x76, 0x2d, 0x73, 0x61, 0x31,
- 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x07, 0x52, 0x6f,
- 0x6f, 0x74, 0x20, 0x43, 0x41, 0x31, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55,
- 0x04, 0x03, 0x13, 0x12, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x53, 0x69,
- 0x67, 0x6e, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41, 0x30, 0x1e,
- 0x17, 0x0d, 0x31, 0x34, 0x30, 0x32, 0x32, 0x30, 0x31, 0x30, 0x30, 0x30,
- 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x34, 0x30, 0x32, 0x32, 0x30, 0x31,
- 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x4c, 0x31, 0x0b, 0x30, 0x09,
- 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x42, 0x45, 0x31, 0x19, 0x30,
- 0x17, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x10, 0x47, 0x6c, 0x6f, 0x62,
- 0x61, 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x6e, 0x76, 0x2d, 0x73, 0x61,
- 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x19, 0x41,
- 0x6c, 0x70, 0x68, 0x61, 0x53, 0x53, 0x4c, 0x20, 0x43, 0x41, 0x20, 0x2d,
- 0x20, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, 0x20, 0x2d, 0x20, 0x47, 0x32,
- 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
- 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00,
- 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xda, 0x01, 0xec,
- 0xe4, 0xec, 0x73, 0x60, 0xfb, 0x7e, 0x8f, 0x6a, 0xb7, 0xc6, 0x17, 0xe3,
- 0x92, 0x64, 0x32, 0xd4, 0xac, 0x00, 0xd9, 0xa2, 0x0f, 0xb9, 0xed, 0xee,
- 0x6b, 0x8a, 0x86, 0xca, 0x92, 0x67, 0xd9, 0x74, 0xd7, 0x5d, 0x47, 0x02,
- 0x3c, 0x8f, 0x40, 0xd6, 0x9e, 0x6d, 0x14, 0xcd, 0xc3, 0xda, 0x29, 0x39,
- 0xa7, 0x0f, 0x05, 0x0a, 0x68, 0xa2, 0x66, 0x1a, 0x1e, 0xc4, 0xb2, 0x8b,
- 0x76, 0x58, 0xe5, 0xab, 0x5d, 0x1d, 0x8f, 0x40, 0xb3, 0x39, 0x8b, 0xef,
- 0x1e, 0x83, 0x7d, 0x22, 0xd0, 0xe3, 0xa9, 0x00, 0x2e, 0xec, 0x53, 0xcf,
- 0x62, 0x19, 0x85, 0x44, 0x28, 0x4c, 0xc0, 0x27, 0xcb, 0x7b, 0x0e, 0xec,
- 0x10, 0x64, 0x00, 0x10, 0xa4, 0x05, 0xcc, 0xa0, 0x72, 0xbe, 0x41, 0x6c,
- 0x31, 0x5b, 0x48, 0xe4, 0xb1, 0xec, 0xb9, 0x23, 0xeb, 0x55, 0x4d, 0xd0,
- 0x7d, 0x62, 0x4a, 0xa5, 0xb4, 0xa5, 0xa4, 0x59, 0x85, 0xc5, 0x25, 0x91,
- 0xa6, 0xfe, 0xa6, 0x09, 0x9f, 0x06, 0x10, 0x6d, 0x8f, 0x81, 0x0c, 0x64,
- 0x40, 0x5e, 0x73, 0x00, 0x9a, 0xe0, 0x2e, 0x65, 0x98, 0x54, 0x10, 0x00,
- 0x70, 0x98, 0xc8, 0xe1, 0xed, 0x34, 0x5f, 0xd8, 0x9c, 0xc7, 0x0d, 0xc0,
- 0xd6, 0x23, 0x59, 0x45, 0xfc, 0xfe, 0x55, 0x7a, 0x86, 0xee, 0x94, 0x60,
- 0x22, 0xf1, 0xae, 0xd1, 0xe6, 0x55, 0x46, 0xf6, 0x99, 0xc5, 0x1b, 0x08,
- 0x74, 0x5f, 0xac, 0xb0, 0x64, 0x84, 0x8f, 0x89, 0x38, 0x1c, 0xa1, 0xa7,
- 0x90, 0x21, 0x4f, 0x02, 0x6e, 0xbd, 0xe0, 0x61, 0x67, 0xd4, 0xf8, 0x42,
- 0x87, 0x0f, 0x0a, 0xf7, 0xc9, 0x04, 0x6d, 0x2a, 0xa9, 0x2f, 0xef, 0x42,
- 0xa5, 0xdf, 0xdd, 0xa3, 0x53, 0xdb, 0x98, 0x1e, 0x81, 0xf9, 0x9a, 0x72,
- 0x7b, 0x5a, 0xde, 0x4f, 0x3e, 0x7f, 0xa2, 0x58, 0xa0, 0xe2, 0x17, 0xad,
- 0x67, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x23, 0x30, 0x82,
- 0x01, 0x1f, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff,
- 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d,
- 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02,
- 0x01, 0x00, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04,
- 0x14, 0xf5, 0xcd, 0xd5, 0x3c, 0x08, 0x50, 0xf9, 0x6a, 0x4f, 0x3a, 0xb7,
- 0x97, 0xda, 0x56, 0x83, 0xe6, 0x69, 0xd2, 0x68, 0xf7, 0x30, 0x45, 0x06,
- 0x03, 0x55, 0x1d, 0x20, 0x04, 0x3e, 0x30, 0x3c, 0x30, 0x3a, 0x06, 0x04,
- 0x55, 0x1d, 0x20, 0x00, 0x30, 0x32, 0x30, 0x30, 0x06, 0x08, 0x2b, 0x06,
- 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x24, 0x68, 0x74, 0x74, 0x70,
- 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x61, 0x6c, 0x70, 0x68,
- 0x61, 0x73, 0x73, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x70,
- 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x2f, 0x30, 0x33, 0x06, 0x03,
- 0x55, 0x1d, 0x1f, 0x04, 0x2c, 0x30, 0x2a, 0x30, 0x28, 0xa0, 0x26, 0xa0,
- 0x24, 0x86, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72,
- 0x6c, 0x2e, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x73, 0x69, 0x67, 0x6e,
- 0x2e, 0x6e, 0x65, 0x74, 0x2f, 0x72, 0x6f, 0x6f, 0x74, 0x2e, 0x63, 0x72,
- 0x6c, 0x30, 0x3d, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01,
- 0x01, 0x04, 0x31, 0x30, 0x2f, 0x30, 0x2d, 0x06, 0x08, 0x2b, 0x06, 0x01,
- 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x21, 0x68, 0x74, 0x74, 0x70, 0x3a,
- 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x67, 0x6c, 0x6f, 0x62, 0x61,
- 0x6c, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x6f,
- 0x6f, 0x74, 0x72, 0x31, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04,
- 0x18, 0x30, 0x16, 0x80, 0x14, 0x60, 0x7b, 0x66, 0x1a, 0x45, 0x0d, 0x97,
- 0xca, 0x89, 0x50, 0x2f, 0x7d, 0x04, 0xcd, 0x34, 0xa8, 0xff, 0xfc, 0xfd,
- 0x4b, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
- 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x60, 0x40, 0x68,
- 0x16, 0x47, 0xe7, 0x16, 0x8d, 0xdb, 0x5c, 0xa1, 0x56, 0x2a, 0xcb, 0xf4,
- 0x5c, 0x9b, 0xb0, 0x1e, 0xa2, 0x4b, 0xf5, 0xcb, 0x02, 0x3f, 0xf8, 0x0b,
- 0xa1, 0xf2, 0xa7, 0x42, 0xd4, 0xb7, 0x4c, 0xeb, 0xe3, 0x66, 0x80, 0xf3,
- 0x25, 0x43, 0x78, 0x2e, 0x1b, 0x17, 0x56, 0x07, 0x52, 0x18, 0xcb, 0xd1,
- 0xa8, 0xec, 0xe6, 0xfb, 0x73, 0x3e, 0xa4, 0x62, 0x8c, 0x80, 0xb4, 0xd2,
- 0xc5, 0x12, 0x73, 0xa3, 0xd3, 0xfa, 0x02, 0x38, 0xbe, 0x63, 0x3d, 0x84,
- 0xb8, 0x99, 0xc1, 0xf1, 0xba, 0xf7, 0x9f, 0xc3, 0x40, 0xd1, 0x58, 0x18,
- 0x53, 0xc1, 0x62, 0xdd, 0xaf, 0x18, 0x42, 0x7f, 0x34, 0x4e, 0xc5, 0x43,
- 0xd5, 0x71, 0xb0, 0x30, 0x00, 0xc7, 0xe3, 0x90, 0xae, 0x3f, 0x57, 0x86,
- 0x97, 0xce, 0xea, 0x0c, 0x12, 0x8e, 0x22, 0x70, 0xe3, 0x66, 0xa7, 0x54,
- 0x7f, 0x2e, 0x28, 0xcb, 0xd4, 0x54, 0xd0, 0xb3, 0x1e, 0x62, 0x67, 0x08,
- 0xf9, 0x27, 0xe1, 0xcb, 0xe3, 0x66, 0xb8, 0x24, 0x1b, 0x89, 0x6a, 0x89,
- 0x44, 0x65, 0xf2, 0xd9, 0x4c, 0xd2, 0x58, 0x1c, 0x8c, 0x4e, 0xc0, 0x95,
- 0xa1, 0xd4, 0xef, 0x67, 0x2f, 0x38, 0x20, 0xe8, 0x2e, 0xff, 0x96, 0x51,
- 0xf0, 0xba, 0xd8, 0x3d, 0x92, 0x70, 0x47, 0x65, 0x1c, 0x9e, 0x73, 0x72,
- 0xb4, 0x60, 0x0c, 0x5c, 0xe2, 0xd1, 0x73, 0x76, 0xe0, 0xaf, 0x4e, 0xe2,
- 0xe5, 0x37, 0xa5, 0x45, 0x2f, 0x8a, 0x23, 0x3e, 0x87, 0xc7, 0x30, 0xe6,
- 0x31, 0x38, 0x7c, 0xf4, 0xdd, 0x52, 0xca, 0xf3, 0x53, 0x04, 0x25, 0x57,
- 0x56, 0x66, 0x94, 0xe8, 0x0b, 0xee, 0xe6, 0x03, 0x14, 0x4e, 0xee, 0xfd,
- 0x6d, 0x94, 0x64, 0x9e, 0x5e, 0xce, 0x79, 0xd4, 0xb2, 0xa6, 0xcf, 0x40,
- 0xb1, 0x44, 0xa8, 0x3e, 0x87, 0x19, 0x5e, 0xe9, 0xf8, 0x21, 0x16, 0x59,
- 0x53,
-};
-
-#if 0
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number: 146031 (0x23a6f)
- Signature Algorithm: sha256WithRSAEncryption
- Issuer: C=US, O=GeoTrust Inc., CN=GeoTrust Global CA
- Validity
- Not Before: Nov 5 21:36:50 2013 GMT
- Not After : May 20 21:36:50 2022 GMT
- Subject: C=US, O=GeoTrust Inc., CN=GeoTrust SSL CA - G3
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:e3:be:7e:0a:86:a3:cf:6b:6d:3d:2b:a1:97:ad:
- 49:24:4d:d7:77:b9:34:79:08:a5:9e:a2:9e:de:47:
- 12:92:3d:7e:ea:19:86:b1:e8:4f:3d:5f:f7:d0:a7:
- 77:9a:5b:1f:0a:03:b5:19:53:db:a5:21:94:69:63:
- 9d:6a:4c:91:0c:10:47:be:11:fa:6c:86:25:b7:ab:
- 04:68:42:38:09:65:f0:14:da:19:9e:fa:6b:0b:ab:
- 62:ef:8d:a7:ef:63:70:23:a8:af:81:f3:d1:6e:88:
- 67:53:ec:12:a4:29:75:8a:a7:f2:57:3d:a2:83:98:
- 97:f2:0a:7d:d4:e7:43:6e:30:78:62:22:59:59:b8:
- 71:27:45:aa:0f:66:c6:55:3f:fa:32:17:2b:31:8f:
- 46:a0:fa:69:14:7c:9d:9f:5a:e2:eb:33:4e:10:a6:
- b3:ed:77:63:d8:c3:9e:f4:dd:df:79:9a:7a:d4:ee:
- de:dd:9a:cc:c3:b7:a9:5d:cc:11:3a:07:bb:6f:97:
- a4:01:23:47:95:1f:a3:77:fa:58:92:c6:c7:d0:bd:
- cf:93:18:42:b7:7e:f7:9e:65:ea:d5:3b:ca:ed:ac:
- c5:70:a1:fe:d4:10:9a:f0:12:04:44:ac:1a:5b:78:
- 50:45:57:4c:6f:bd:80:cb:81:5c:2d:b3:bc:76:a1:
- 1e:65
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Authority Key Identifier:
- keyid:C0:7A:98:68:8D:89:FB:AB:05:64:0C:11:7D:AA:7D:65:B8:CA:CC:4E
-
- X509v3 Subject Key Identifier:
- D2:6F:F7:96:F4:85:3F:72:3C:30:7D:23:DA:85:78:9B:A3:7C:5A:7C
- X509v3 Basic Constraints: critical
- CA:TRUE, pathlen:0
- X509v3 Key Usage: critical
- Certificate Sign, CRL Sign
- X509v3 CRL Distribution Points:
-
- Full Name:
- URI:http://g1.symcb.com/crls/gtglobal.crl
-
- Authority Information Access:
- OCSP - URI:http://g2.symcb.com
-
- X509v3 Certificate Policies:
- Policy: 2.16.840.1.113733.1.7.54
- CPS: http://www.geotrust.com/resources/cps
-
- X509v3 Subject Alternative Name:
- DirName:/CN=SymantecPKI-1-539
- Signature Algorithm: sha256WithRSAEncryption
- a0:d4:f7:2c:fb:74:0b:7f:64:f1:cd:43:6a:9f:62:53:1c:02:
- 7c:98:90:a2:ee:4f:68:d4:20:1a:73:12:3e:77:b3:50:eb:72:
- bc:ee:88:be:7f:17:ea:77:8f:83:61:95:4f:84:a1:cb:32:4f:
- 6c:21:be:d2:69:96:7d:63:bd:dc:2b:a8:1f:d0:13:84:70:fe:
- f6:35:95:89:f9:a6:77:b0:46:c8:bb:b7:13:f5:c9:60:69:d6:
- 4c:fe:d2:8e:ef:d3:60:c1:80:80:e1:e7:fb:8b:6f:21:79:4a:
- e0:dc:a9:1b:c1:b7:fb:c3:49:59:5c:b5:77:07:44:d4:97:fc:
- 49:00:89:6f:06:4e:01:70:19:ac:2f:11:c0:e2:e6:0f:2f:86:
- 4b:8d:7b:c3:b9:a7:2e:f4:f1:ac:16:3e:39:49:51:9e:17:4b:
- 4f:10:3a:5b:a5:a8:92:6f:fd:fa:d6:0b:03:4d:47:56:57:19:
- f3:cb:6b:f5:f3:d6:cf:b0:f5:f5:a3:11:d2:20:53:13:34:37:
- 05:2c:43:5a:63:df:8d:40:d6:85:1e:51:e9:51:17:1e:03:56:
- c9:f1:30:ad:e7:9b:11:a2:b9:d0:31:81:9b:68:b1:d9:e8:f3:
- e6:94:7e:c7:ae:13:2f:87:ed:d0:25:b0:68:f9:de:08:5a:f3:
- 29:cc:d4:92
------BEGIN CERTIFICATE-----
-MIIETzCCAzegAwIBAgIDAjpvMA0GCSqGSIb3DQEBCwUAMEIxCzAJBgNVBAYTAlVT
-MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i
-YWwgQ0EwHhcNMTMxMTA1MjEzNjUwWhcNMjIwNTIwMjEzNjUwWjBEMQswCQYDVQQG
-EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEdMBsGA1UEAxMUR2VvVHJ1c3Qg
-U1NMIENBIC0gRzMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDjvn4K
-hqPPa209K6GXrUkkTdd3uTR5CKWeop7eRxKSPX7qGYax6E89X/fQp3eaWx8KA7UZ
-U9ulIZRpY51qTJEMEEe+EfpshiW3qwRoQjgJZfAU2hme+msLq2LvjafvY3AjqK+B
-89FuiGdT7BKkKXWKp/JXPaKDmJfyCn3U50NuMHhiIllZuHEnRaoPZsZVP/oyFysx
-j0ag+mkUfJ2fWuLrM04QprPtd2PYw5703d95mnrU7t7dmszDt6ldzBE6B7tvl6QB
-I0eVH6N3+liSxsfQvc+TGEK3fveeZerVO8rtrMVwof7UEJrwEgRErBpbeFBFV0xv
-vYDLgVwts7x2oR5lAgMBAAGjggFKMIIBRjAfBgNVHSMEGDAWgBTAephojYn7qwVk
-DBF9qn1luMrMTjAdBgNVHQ4EFgQU0m/3lvSFP3I8MH0j2oV4m6N8WnwwEgYDVR0T
-AQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAQYwNgYDVR0fBC8wLTAroCmgJ4Yl
-aHR0cDovL2cxLnN5bWNiLmNvbS9jcmxzL2d0Z2xvYmFsLmNybDAvBggrBgEFBQcB
-AQQjMCEwHwYIKwYBBQUHMAGGE2h0dHA6Ly9nMi5zeW1jYi5jb20wTAYDVR0gBEUw
-QzBBBgpghkgBhvhFAQc2MDMwMQYIKwYBBQUHAgEWJWh0dHA6Ly93d3cuZ2VvdHJ1
-c3QuY29tL3Jlc291cmNlcy9jcHMwKQYDVR0RBCIwIKQeMBwxGjAYBgNVBAMTEVN5
-bWFudGVjUEtJLTEtNTM5MA0GCSqGSIb3DQEBCwUAA4IBAQCg1Pcs+3QLf2TxzUNq
-n2JTHAJ8mJCi7k9o1CAacxI+d7NQ63K87oi+fxfqd4+DYZVPhKHLMk9sIb7SaZZ9
-Y73cK6gf0BOEcP72NZWJ+aZ3sEbIu7cT9clgadZM/tKO79NgwYCA4ef7i28heUrg
-3Kkbwbf7w0lZXLV3B0TUl/xJAIlvBk4BcBmsLxHA4uYPL4ZLjXvDuacu9PGsFj45
-SVGeF0tPEDpbpaiSb/361gsDTUdWVxnzy2v189bPsPX1oxHSIFMTNDcFLENaY9+N
-QNaFHlHpURceA1bJ8TCt55sRornQMYGbaLHZ6PPmlH7HrhMvh+3QJbBo+d4IWvMp
-zNSS
------END CERTIFICATE-----
-#endif
-static const unsigned char kDERCert12[] = {
- 0x30, 0x82, 0x04, 0x4f, 0x30, 0x82, 0x03, 0x37, 0xa0, 0x03, 0x02, 0x01,
- 0x02, 0x02, 0x03, 0x02, 0x3a, 0x6f, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
- 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x42, 0x31,
- 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53,
- 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0d, 0x47,
- 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x49, 0x6e, 0x63, 0x2e,
- 0x31, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x12, 0x47,
- 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x47, 0x6c, 0x6f, 0x62,
- 0x61, 0x6c, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x33, 0x31,
- 0x31, 0x30, 0x35, 0x32, 0x31, 0x33, 0x36, 0x35, 0x30, 0x5a, 0x17, 0x0d,
- 0x32, 0x32, 0x30, 0x35, 0x32, 0x30, 0x32, 0x31, 0x33, 0x36, 0x35, 0x30,
- 0x5a, 0x30, 0x44, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06,
- 0x13, 0x02, 0x55, 0x53, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04,
- 0x0a, 0x13, 0x0d, 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20,
- 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x1d, 0x30, 0x1b, 0x06, 0x03, 0x55, 0x04,
- 0x03, 0x13, 0x14, 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20,
- 0x53, 0x53, 0x4c, 0x20, 0x43, 0x41, 0x20, 0x2d, 0x20, 0x47, 0x33, 0x30,
- 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
- 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30,
- 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xe3, 0xbe, 0x7e, 0x0a,
- 0x86, 0xa3, 0xcf, 0x6b, 0x6d, 0x3d, 0x2b, 0xa1, 0x97, 0xad, 0x49, 0x24,
- 0x4d, 0xd7, 0x77, 0xb9, 0x34, 0x79, 0x08, 0xa5, 0x9e, 0xa2, 0x9e, 0xde,
- 0x47, 0x12, 0x92, 0x3d, 0x7e, 0xea, 0x19, 0x86, 0xb1, 0xe8, 0x4f, 0x3d,
- 0x5f, 0xf7, 0xd0, 0xa7, 0x77, 0x9a, 0x5b, 0x1f, 0x0a, 0x03, 0xb5, 0x19,
- 0x53, 0xdb, 0xa5, 0x21, 0x94, 0x69, 0x63, 0x9d, 0x6a, 0x4c, 0x91, 0x0c,
- 0x10, 0x47, 0xbe, 0x11, 0xfa, 0x6c, 0x86, 0x25, 0xb7, 0xab, 0x04, 0x68,
- 0x42, 0x38, 0x09, 0x65, 0xf0, 0x14, 0xda, 0x19, 0x9e, 0xfa, 0x6b, 0x0b,
- 0xab, 0x62, 0xef, 0x8d, 0xa7, 0xef, 0x63, 0x70, 0x23, 0xa8, 0xaf, 0x81,
- 0xf3, 0xd1, 0x6e, 0x88, 0x67, 0x53, 0xec, 0x12, 0xa4, 0x29, 0x75, 0x8a,
- 0xa7, 0xf2, 0x57, 0x3d, 0xa2, 0x83, 0x98, 0x97, 0xf2, 0x0a, 0x7d, 0xd4,
- 0xe7, 0x43, 0x6e, 0x30, 0x78, 0x62, 0x22, 0x59, 0x59, 0xb8, 0x71, 0x27,
- 0x45, 0xaa, 0x0f, 0x66, 0xc6, 0x55, 0x3f, 0xfa, 0x32, 0x17, 0x2b, 0x31,
- 0x8f, 0x46, 0xa0, 0xfa, 0x69, 0x14, 0x7c, 0x9d, 0x9f, 0x5a, 0xe2, 0xeb,
- 0x33, 0x4e, 0x10, 0xa6, 0xb3, 0xed, 0x77, 0x63, 0xd8, 0xc3, 0x9e, 0xf4,
- 0xdd, 0xdf, 0x79, 0x9a, 0x7a, 0xd4, 0xee, 0xde, 0xdd, 0x9a, 0xcc, 0xc3,
- 0xb7, 0xa9, 0x5d, 0xcc, 0x11, 0x3a, 0x07, 0xbb, 0x6f, 0x97, 0xa4, 0x01,
- 0x23, 0x47, 0x95, 0x1f, 0xa3, 0x77, 0xfa, 0x58, 0x92, 0xc6, 0xc7, 0xd0,
- 0xbd, 0xcf, 0x93, 0x18, 0x42, 0xb7, 0x7e, 0xf7, 0x9e, 0x65, 0xea, 0xd5,
- 0x3b, 0xca, 0xed, 0xac, 0xc5, 0x70, 0xa1, 0xfe, 0xd4, 0x10, 0x9a, 0xf0,
- 0x12, 0x04, 0x44, 0xac, 0x1a, 0x5b, 0x78, 0x50, 0x45, 0x57, 0x4c, 0x6f,
- 0xbd, 0x80, 0xcb, 0x81, 0x5c, 0x2d, 0xb3, 0xbc, 0x76, 0xa1, 0x1e, 0x65,
- 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x4a, 0x30, 0x82, 0x01,
- 0x46, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16,
- 0x80, 0x14, 0xc0, 0x7a, 0x98, 0x68, 0x8d, 0x89, 0xfb, 0xab, 0x05, 0x64,
- 0x0c, 0x11, 0x7d, 0xaa, 0x7d, 0x65, 0xb8, 0xca, 0xcc, 0x4e, 0x30, 0x1d,
- 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xd2, 0x6f, 0xf7,
- 0x96, 0xf4, 0x85, 0x3f, 0x72, 0x3c, 0x30, 0x7d, 0x23, 0xda, 0x85, 0x78,
- 0x9b, 0xa3, 0x7c, 0x5a, 0x7c, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13,
- 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01,
- 0x00, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04,
- 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x36, 0x06, 0x03, 0x55, 0x1d, 0x1f,
- 0x04, 0x2f, 0x30, 0x2d, 0x30, 0x2b, 0xa0, 0x29, 0xa0, 0x27, 0x86, 0x25,
- 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x67, 0x31, 0x2e, 0x73, 0x79,
- 0x6d, 0x63, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x72, 0x6c, 0x73,
- 0x2f, 0x67, 0x74, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x2e, 0x63, 0x72,
- 0x6c, 0x30, 0x2f, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01,
- 0x01, 0x04, 0x23, 0x30, 0x21, 0x30, 0x1f, 0x06, 0x08, 0x2b, 0x06, 0x01,
- 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x13, 0x68, 0x74, 0x74, 0x70, 0x3a,
- 0x2f, 0x2f, 0x67, 0x32, 0x2e, 0x73, 0x79, 0x6d, 0x63, 0x62, 0x2e, 0x63,
- 0x6f, 0x6d, 0x30, 0x4c, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x45, 0x30,
- 0x43, 0x30, 0x41, 0x06, 0x0a, 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x45,
- 0x01, 0x07, 0x36, 0x30, 0x33, 0x30, 0x31, 0x06, 0x08, 0x2b, 0x06, 0x01,
- 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x25, 0x68, 0x74, 0x74, 0x70, 0x3a,
- 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x67, 0x65, 0x6f, 0x74, 0x72, 0x75,
- 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75,
- 0x72, 0x63, 0x65, 0x73, 0x2f, 0x63, 0x70, 0x73, 0x30, 0x29, 0x06, 0x03,
- 0x55, 0x1d, 0x11, 0x04, 0x22, 0x30, 0x20, 0xa4, 0x1e, 0x30, 0x1c, 0x31,
- 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x11, 0x53, 0x79,
- 0x6d, 0x61, 0x6e, 0x74, 0x65, 0x63, 0x50, 0x4b, 0x49, 0x2d, 0x31, 0x2d,
- 0x35, 0x33, 0x39, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
- 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0xa0,
- 0xd4, 0xf7, 0x2c, 0xfb, 0x74, 0x0b, 0x7f, 0x64, 0xf1, 0xcd, 0x43, 0x6a,
- 0x9f, 0x62, 0x53, 0x1c, 0x02, 0x7c, 0x98, 0x90, 0xa2, 0xee, 0x4f, 0x68,
- 0xd4, 0x20, 0x1a, 0x73, 0x12, 0x3e, 0x77, 0xb3, 0x50, 0xeb, 0x72, 0xbc,
- 0xee, 0x88, 0xbe, 0x7f, 0x17, 0xea, 0x77, 0x8f, 0x83, 0x61, 0x95, 0x4f,
- 0x84, 0xa1, 0xcb, 0x32, 0x4f, 0x6c, 0x21, 0xbe, 0xd2, 0x69, 0x96, 0x7d,
- 0x63, 0xbd, 0xdc, 0x2b, 0xa8, 0x1f, 0xd0, 0x13, 0x84, 0x70, 0xfe, 0xf6,
- 0x35, 0x95, 0x89, 0xf9, 0xa6, 0x77, 0xb0, 0x46, 0xc8, 0xbb, 0xb7, 0x13,
- 0xf5, 0xc9, 0x60, 0x69, 0xd6, 0x4c, 0xfe, 0xd2, 0x8e, 0xef, 0xd3, 0x60,
- 0xc1, 0x80, 0x80, 0xe1, 0xe7, 0xfb, 0x8b, 0x6f, 0x21, 0x79, 0x4a, 0xe0,
- 0xdc, 0xa9, 0x1b, 0xc1, 0xb7, 0xfb, 0xc3, 0x49, 0x59, 0x5c, 0xb5, 0x77,
- 0x07, 0x44, 0xd4, 0x97, 0xfc, 0x49, 0x00, 0x89, 0x6f, 0x06, 0x4e, 0x01,
- 0x70, 0x19, 0xac, 0x2f, 0x11, 0xc0, 0xe2, 0xe6, 0x0f, 0x2f, 0x86, 0x4b,
- 0x8d, 0x7b, 0xc3, 0xb9, 0xa7, 0x2e, 0xf4, 0xf1, 0xac, 0x16, 0x3e, 0x39,
- 0x49, 0x51, 0x9e, 0x17, 0x4b, 0x4f, 0x10, 0x3a, 0x5b, 0xa5, 0xa8, 0x92,
- 0x6f, 0xfd, 0xfa, 0xd6, 0x0b, 0x03, 0x4d, 0x47, 0x56, 0x57, 0x19, 0xf3,
- 0xcb, 0x6b, 0xf5, 0xf3, 0xd6, 0xcf, 0xb0, 0xf5, 0xf5, 0xa3, 0x11, 0xd2,
- 0x20, 0x53, 0x13, 0x34, 0x37, 0x05, 0x2c, 0x43, 0x5a, 0x63, 0xdf, 0x8d,
- 0x40, 0xd6, 0x85, 0x1e, 0x51, 0xe9, 0x51, 0x17, 0x1e, 0x03, 0x56, 0xc9,
- 0xf1, 0x30, 0xad, 0xe7, 0x9b, 0x11, 0xa2, 0xb9, 0xd0, 0x31, 0x81, 0x9b,
- 0x68, 0xb1, 0xd9, 0xe8, 0xf3, 0xe6, 0x94, 0x7e, 0xc7, 0xae, 0x13, 0x2f,
- 0x87, 0xed, 0xd0, 0x25, 0xb0, 0x68, 0xf9, 0xde, 0x08, 0x5a, 0xf3, 0x29,
- 0xcc, 0xd4, 0x92,
-};
-
-#if 0
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number: 146019 (0x23a63)
- Signature Algorithm: sha1WithRSAEncryption
- Issuer: C=US, O=GeoTrust Inc., CN=GeoTrust Global CA
- Validity
- Not Before: Aug 27 20:40:40 2012 GMT
- Not After : May 20 20:40:40 2022 GMT
- Subject: C=US, O=GeoTrust Inc., CN=GeoTrust SSL CA - G2
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:b9:27:f9:4f:d8:f6:b7:15:3f:8f:cd:ce:d6:8d:
- 1c:6b:fd:7f:da:54:21:4e:03:d8:ca:d0:72:52:15:
- b8:c9:82:5b:58:79:84:ff:24:72:6f:f2:69:7f:bc:
- 96:d9:9a:7a:c3:3e:a9:cf:50:22:13:0e:86:19:db:
- e8:49:ef:8b:e6:d6:47:f2:fd:73:45:08:ae:8f:ac:
- 5e:b6:f8:9e:7c:f7:10:ff:92:43:66:ef:1c:d4:ee:
- a1:46:88:11:89:49:79:7a:25:ce:4b:6a:f0:d7:1c:
- 76:1a:29:3c:c9:e4:fd:1e:85:dc:e0:31:65:05:47:
- 16:ac:0a:07:4b:2e:70:5e:6b:06:a7:6b:3a:6c:af:
- 05:12:c4:b2:11:25:d6:3e:97:29:f0:83:6c:57:1c:
- d8:a5:ef:cc:ec:fd:d6:12:f1:3f:db:40:b4:ae:0f:
- 18:d3:c5:af:40:92:5d:07:5e:4e:fe:62:17:37:89:
- e9:8b:74:26:a2:ed:b8:0a:e7:6c:15:5b:35:90:72:
- dd:d8:4d:21:d4:40:23:5c:8f:ee:80:31:16:ab:68:
- 55:f4:0e:3b:54:e9:04:4d:f0:cc:4e:81:5e:e9:6f:
- 52:69:4e:be:a6:16:6d:42:f5:51:ff:e0:0b:56:3c:
- 98:4f:73:8f:0e:6f:1a:23:f1:c9:c8:d9:df:bc:ec:
- 52:d7
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Authority Key Identifier:
- keyid:C0:7A:98:68:8D:89:FB:AB:05:64:0C:11:7D:AA:7D:65:B8:CA:CC:4E
-
- X509v3 Subject Key Identifier:
- 11:4A:D0:73:39:D5:5B:69:08:5C:BA:3D:BF:64:9A:A8:8B:1C:55:BC
- X509v3 Basic Constraints: critical
- CA:TRUE, pathlen:0
- X509v3 Key Usage: critical
- Certificate Sign, CRL Sign
- X509v3 CRL Distribution Points:
-
- Full Name:
- URI:http://crl.geotrust.com/crls/gtglobal.crl
-
- Authority Information Access:
- OCSP - URI:http://ocsp.geotrust.com
-
- X509v3 Certificate Policies:
- Policy: 2.16.840.1.113733.1.7.54
- CPS: http://www.geotrust.com/resources/cps
-
- X509v3 Subject Alternative Name:
- DirName:/CN=VeriSignMPKI-2-254
- Signature Algorithm: sha1WithRSAEncryption
- 3c:e5:3d:5a:1b:a2:37:2a:e3:46:cf:36:96:18:3c:7b:f1:84:
- c5:57:86:77:40:9d:35:f0:12:f0:78:18:fb:22:a4:de:98:4b:
- 78:81:e6:4d:86:e3:91:0f:42:e3:b9:dc:a0:d6:ff:a9:f8:b1:
- 79:97:99:d1:c3:6c:42:a5:92:94:e0:5d:0c:33:18:25:c9:2b:
- 95:53:e0:e5:a9:0c:7d:47:fe:7f:51:31:44:5e:f7:2a:1e:35:
- a2:94:32:f7:c9:ee:c0:b6:c6:9a:ac:de:99:21:6a:23:a0:38:
- 64:ee:a3:c4:88:73:32:3b:50:ce:bf:ad:d3:75:1e:a6:f4:e9:
- f9:42:6b:60:b2:dd:45:fd:5d:57:08:ce:2d:50:e6:12:32:16:
- 13:8a:f2:94:a2:9b:47:a8:86:7f:d9:98:e5:f7:e5:76:74:64:
- d8:91:bc:84:16:28:d8:25:44:30:7e:82:d8:ac:b1:e4:c0:e4:
- 15:6c:db:b6:24:27:02:2a:01:12:85:ba:31:88:58:47:74:e3:
- b8:d2:64:a6:c3:32:59:2e:29:4b:45:f1:5b:89:49:2e:82:9a:
- c6:18:15:44:d0:2e:64:01:15:68:38:f9:f6:f9:66:03:0c:55:
- 1b:9d:bf:00:40:ae:f0:48:27:4c:e0:80:5e:2d:b9:2a:15:7a:
- bc:66:f8:35
------BEGIN CERTIFICATE-----
-MIIEWTCCA0GgAwIBAgIDAjpjMA0GCSqGSIb3DQEBBQUAMEIxCzAJBgNVBAYTAlVT
-MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i
-YWwgQ0EwHhcNMTIwODI3MjA0MDQwWhcNMjIwNTIwMjA0MDQwWjBEMQswCQYDVQQG
-EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEdMBsGA1UEAxMUR2VvVHJ1c3Qg
-U1NMIENBIC0gRzIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC5J/lP
-2Pa3FT+Pzc7WjRxr/X/aVCFOA9jK0HJSFbjJgltYeYT/JHJv8ml/vJbZmnrDPqnP
-UCITDoYZ2+hJ74vm1kfy/XNFCK6PrF62+J589xD/kkNm7xzU7qFGiBGJSXl6Jc5L
-avDXHHYaKTzJ5P0ehdzgMWUFRxasCgdLLnBeawanazpsrwUSxLIRJdY+lynwg2xX
-HNil78zs/dYS8T/bQLSuDxjTxa9Akl0HXk7+Yhc3iemLdCai7bgK52wVWzWQct3Y
-TSHUQCNcj+6AMRaraFX0DjtU6QRN8MxOgV7pb1JpTr6mFm1C9VH/4AtWPJhPc48O
-bxoj8cnI2d+87FLXAgMBAAGjggFUMIIBUDAfBgNVHSMEGDAWgBTAephojYn7qwVk
-DBF9qn1luMrMTjAdBgNVHQ4EFgQUEUrQcznVW2kIXLo9v2SaqIscVbwwEgYDVR0T
-AQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAQYwOgYDVR0fBDMwMTAvoC2gK4Yp
-aHR0cDovL2NybC5nZW90cnVzdC5jb20vY3Jscy9ndGdsb2JhbC5jcmwwNAYIKwYB
-BQUHAQEEKDAmMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5nZW90cnVzdC5jb20w
-TAYDVR0gBEUwQzBBBgpghkgBhvhFAQc2MDMwMQYIKwYBBQUHAgEWJWh0dHA6Ly93
-d3cuZ2VvdHJ1c3QuY29tL3Jlc291cmNlcy9jcHMwKgYDVR0RBCMwIaQfMB0xGzAZ
-BgNVBAMTElZlcmlTaWduTVBLSS0yLTI1NDANBgkqhkiG9w0BAQUFAAOCAQEAPOU9
-WhuiNyrjRs82lhg8e/GExVeGd0CdNfAS8HgY+yKk3phLeIHmTYbjkQ9C47ncoNb/
-qfixeZeZ0cNsQqWSlOBdDDMYJckrlVPg5akMfUf+f1ExRF73Kh41opQy98nuwLbG
-mqzemSFqI6A4ZO6jxIhzMjtQzr+t03UepvTp+UJrYLLdRf1dVwjOLVDmEjIWE4ry
-lKKbR6iGf9mY5ffldnRk2JG8hBYo2CVEMH6C2Kyx5MDkFWzbtiQnAioBEoW6MYhY
-R3TjuNJkpsMyWS4pS0XxW4lJLoKaxhgVRNAuZAEVaDj59vlmAwxVG52/AECu8Egn
-TOCAXi25KhV6vGb4NQ==
------END CERTIFICATE-----
-#endif
-static const unsigned char kDERCert13[] = {
- 0x30, 0x82, 0x04, 0x59, 0x30, 0x82, 0x03, 0x41, 0xa0, 0x03, 0x02, 0x01,
- 0x02, 0x02, 0x03, 0x02, 0x3a, 0x63, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
- 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x42, 0x31,
- 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53,
- 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0d, 0x47,
- 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x49, 0x6e, 0x63, 0x2e,
- 0x31, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x12, 0x47,
- 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x47, 0x6c, 0x6f, 0x62,
- 0x61, 0x6c, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x32, 0x30,
- 0x38, 0x32, 0x37, 0x32, 0x30, 0x34, 0x30, 0x34, 0x30, 0x5a, 0x17, 0x0d,
- 0x32, 0x32, 0x30, 0x35, 0x32, 0x30, 0x32, 0x30, 0x34, 0x30, 0x34, 0x30,
- 0x5a, 0x30, 0x44, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06,
- 0x13, 0x02, 0x55, 0x53, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04,
- 0x0a, 0x13, 0x0d, 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20,
- 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x1d, 0x30, 0x1b, 0x06, 0x03, 0x55, 0x04,
- 0x03, 0x13, 0x14, 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20,
- 0x53, 0x53, 0x4c, 0x20, 0x43, 0x41, 0x20, 0x2d, 0x20, 0x47, 0x32, 0x30,
- 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
- 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30,
- 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xb9, 0x27, 0xf9, 0x4f,
- 0xd8, 0xf6, 0xb7, 0x15, 0x3f, 0x8f, 0xcd, 0xce, 0xd6, 0x8d, 0x1c, 0x6b,
- 0xfd, 0x7f, 0xda, 0x54, 0x21, 0x4e, 0x03, 0xd8, 0xca, 0xd0, 0x72, 0x52,
- 0x15, 0xb8, 0xc9, 0x82, 0x5b, 0x58, 0x79, 0x84, 0xff, 0x24, 0x72, 0x6f,
- 0xf2, 0x69, 0x7f, 0xbc, 0x96, 0xd9, 0x9a, 0x7a, 0xc3, 0x3e, 0xa9, 0xcf,
- 0x50, 0x22, 0x13, 0x0e, 0x86, 0x19, 0xdb, 0xe8, 0x49, 0xef, 0x8b, 0xe6,
- 0xd6, 0x47, 0xf2, 0xfd, 0x73, 0x45, 0x08, 0xae, 0x8f, 0xac, 0x5e, 0xb6,
- 0xf8, 0x9e, 0x7c, 0xf7, 0x10, 0xff, 0x92, 0x43, 0x66, 0xef, 0x1c, 0xd4,
- 0xee, 0xa1, 0x46, 0x88, 0x11, 0x89, 0x49, 0x79, 0x7a, 0x25, 0xce, 0x4b,
- 0x6a, 0xf0, 0xd7, 0x1c, 0x76, 0x1a, 0x29, 0x3c, 0xc9, 0xe4, 0xfd, 0x1e,
- 0x85, 0xdc, 0xe0, 0x31, 0x65, 0x05, 0x47, 0x16, 0xac, 0x0a, 0x07, 0x4b,
- 0x2e, 0x70, 0x5e, 0x6b, 0x06, 0xa7, 0x6b, 0x3a, 0x6c, 0xaf, 0x05, 0x12,
- 0xc4, 0xb2, 0x11, 0x25, 0xd6, 0x3e, 0x97, 0x29, 0xf0, 0x83, 0x6c, 0x57,
- 0x1c, 0xd8, 0xa5, 0xef, 0xcc, 0xec, 0xfd, 0xd6, 0x12, 0xf1, 0x3f, 0xdb,
- 0x40, 0xb4, 0xae, 0x0f, 0x18, 0xd3, 0xc5, 0xaf, 0x40, 0x92, 0x5d, 0x07,
- 0x5e, 0x4e, 0xfe, 0x62, 0x17, 0x37, 0x89, 0xe9, 0x8b, 0x74, 0x26, 0xa2,
- 0xed, 0xb8, 0x0a, 0xe7, 0x6c, 0x15, 0x5b, 0x35, 0x90, 0x72, 0xdd, 0xd8,
- 0x4d, 0x21, 0xd4, 0x40, 0x23, 0x5c, 0x8f, 0xee, 0x80, 0x31, 0x16, 0xab,
- 0x68, 0x55, 0xf4, 0x0e, 0x3b, 0x54, 0xe9, 0x04, 0x4d, 0xf0, 0xcc, 0x4e,
- 0x81, 0x5e, 0xe9, 0x6f, 0x52, 0x69, 0x4e, 0xbe, 0xa6, 0x16, 0x6d, 0x42,
- 0xf5, 0x51, 0xff, 0xe0, 0x0b, 0x56, 0x3c, 0x98, 0x4f, 0x73, 0x8f, 0x0e,
- 0x6f, 0x1a, 0x23, 0xf1, 0xc9, 0xc8, 0xd9, 0xdf, 0xbc, 0xec, 0x52, 0xd7,
- 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x54, 0x30, 0x82, 0x01,
- 0x50, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16,
- 0x80, 0x14, 0xc0, 0x7a, 0x98, 0x68, 0x8d, 0x89, 0xfb, 0xab, 0x05, 0x64,
- 0x0c, 0x11, 0x7d, 0xaa, 0x7d, 0x65, 0xb8, 0xca, 0xcc, 0x4e, 0x30, 0x1d,
- 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x11, 0x4a, 0xd0,
- 0x73, 0x39, 0xd5, 0x5b, 0x69, 0x08, 0x5c, 0xba, 0x3d, 0xbf, 0x64, 0x9a,
- 0xa8, 0x8b, 0x1c, 0x55, 0xbc, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13,
- 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01,
- 0x00, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04,
- 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x3a, 0x06, 0x03, 0x55, 0x1d, 0x1f,
- 0x04, 0x33, 0x30, 0x31, 0x30, 0x2f, 0xa0, 0x2d, 0xa0, 0x2b, 0x86, 0x29,
- 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x67,
- 0x65, 0x6f, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f,
- 0x63, 0x72, 0x6c, 0x73, 0x2f, 0x67, 0x74, 0x67, 0x6c, 0x6f, 0x62, 0x61,
- 0x6c, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x34, 0x06, 0x08, 0x2b, 0x06, 0x01,
- 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x28, 0x30, 0x26, 0x30, 0x24, 0x06,
- 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x18, 0x68,
- 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x67,
- 0x65, 0x6f, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x30,
- 0x4c, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x45, 0x30, 0x43, 0x30, 0x41,
- 0x06, 0x0a, 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x45, 0x01, 0x07, 0x36,
- 0x30, 0x33, 0x30, 0x31, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
- 0x02, 0x01, 0x16, 0x25, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77,
- 0x77, 0x77, 0x2e, 0x67, 0x65, 0x6f, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e,
- 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65,
- 0x73, 0x2f, 0x63, 0x70, 0x73, 0x30, 0x2a, 0x06, 0x03, 0x55, 0x1d, 0x11,
- 0x04, 0x23, 0x30, 0x21, 0xa4, 0x1f, 0x30, 0x1d, 0x31, 0x1b, 0x30, 0x19,
- 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x12, 0x56, 0x65, 0x72, 0x69, 0x53,
- 0x69, 0x67, 0x6e, 0x4d, 0x50, 0x4b, 0x49, 0x2d, 0x32, 0x2d, 0x32, 0x35,
- 0x34, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
- 0x01, 0x05, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x3c, 0xe5, 0x3d,
- 0x5a, 0x1b, 0xa2, 0x37, 0x2a, 0xe3, 0x46, 0xcf, 0x36, 0x96, 0x18, 0x3c,
- 0x7b, 0xf1, 0x84, 0xc5, 0x57, 0x86, 0x77, 0x40, 0x9d, 0x35, 0xf0, 0x12,
- 0xf0, 0x78, 0x18, 0xfb, 0x22, 0xa4, 0xde, 0x98, 0x4b, 0x78, 0x81, 0xe6,
- 0x4d, 0x86, 0xe3, 0x91, 0x0f, 0x42, 0xe3, 0xb9, 0xdc, 0xa0, 0xd6, 0xff,
- 0xa9, 0xf8, 0xb1, 0x79, 0x97, 0x99, 0xd1, 0xc3, 0x6c, 0x42, 0xa5, 0x92,
- 0x94, 0xe0, 0x5d, 0x0c, 0x33, 0x18, 0x25, 0xc9, 0x2b, 0x95, 0x53, 0xe0,
- 0xe5, 0xa9, 0x0c, 0x7d, 0x47, 0xfe, 0x7f, 0x51, 0x31, 0x44, 0x5e, 0xf7,
- 0x2a, 0x1e, 0x35, 0xa2, 0x94, 0x32, 0xf7, 0xc9, 0xee, 0xc0, 0xb6, 0xc6,
- 0x9a, 0xac, 0xde, 0x99, 0x21, 0x6a, 0x23, 0xa0, 0x38, 0x64, 0xee, 0xa3,
- 0xc4, 0x88, 0x73, 0x32, 0x3b, 0x50, 0xce, 0xbf, 0xad, 0xd3, 0x75, 0x1e,
- 0xa6, 0xf4, 0xe9, 0xf9, 0x42, 0x6b, 0x60, 0xb2, 0xdd, 0x45, 0xfd, 0x5d,
- 0x57, 0x08, 0xce, 0x2d, 0x50, 0xe6, 0x12, 0x32, 0x16, 0x13, 0x8a, 0xf2,
- 0x94, 0xa2, 0x9b, 0x47, 0xa8, 0x86, 0x7f, 0xd9, 0x98, 0xe5, 0xf7, 0xe5,
- 0x76, 0x74, 0x64, 0xd8, 0x91, 0xbc, 0x84, 0x16, 0x28, 0xd8, 0x25, 0x44,
- 0x30, 0x7e, 0x82, 0xd8, 0xac, 0xb1, 0xe4, 0xc0, 0xe4, 0x15, 0x6c, 0xdb,
- 0xb6, 0x24, 0x27, 0x02, 0x2a, 0x01, 0x12, 0x85, 0xba, 0x31, 0x88, 0x58,
- 0x47, 0x74, 0xe3, 0xb8, 0xd2, 0x64, 0xa6, 0xc3, 0x32, 0x59, 0x2e, 0x29,
- 0x4b, 0x45, 0xf1, 0x5b, 0x89, 0x49, 0x2e, 0x82, 0x9a, 0xc6, 0x18, 0x15,
- 0x44, 0xd0, 0x2e, 0x64, 0x01, 0x15, 0x68, 0x38, 0xf9, 0xf6, 0xf9, 0x66,
- 0x03, 0x0c, 0x55, 0x1b, 0x9d, 0xbf, 0x00, 0x40, 0xae, 0xf0, 0x48, 0x27,
- 0x4c, 0xe0, 0x80, 0x5e, 0x2d, 0xb9, 0x2a, 0x15, 0x7a, 0xbc, 0x66, 0xf8,
- 0x35,
-};
-
-#if 0
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number:
- 04:00:00:00:00:01:44:4e:f0:3e:20
- Signature Algorithm: sha256WithRSAEncryption
- Issuer: C=BE, O=GlobalSign nv-sa, OU=Root CA, CN=GlobalSign Root CA
- Validity
- Not Before: Feb 20 10:00:00 2014 GMT
- Not After : Feb 20 10:00:00 2024 GMT
- Subject: C=BE, O=GlobalSign nv-sa, CN=GlobalSign Domain Validation CA - SHA256 - G2
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:a9:dd:cc:0e:b3:e2:32:39:dd:49:22:a8:13:69:
- 93:87:88:e1:0c:ee:71:7d:bd:90:87:96:5d:59:f2:
- cc:b3:d2:58:57:57:f9:46:ef:6c:26:d8:36:42:8e:
- 7e:30:b3:2f:9a:3e:53:7b:1f:6e:b6:a2:4c:45:1f:
- 3c:d3:15:93:1c:89:ed:3c:f4:57:de:ca:bd:ec:06:
- 9a:6a:2a:a0:19:52:7f:51:d1:74:39:08:9f:ab:eb:
- d7:86:13:15:97:ae:36:c3:54:66:0e:5a:f2:a0:73:
- 85:31:e3:b2:64:14:6a:ff:a5:a2:8e:24:bb:bd:85:
- 52:15:a2:79:ee:f0:b5:ee:3d:b8:f4:7d:80:bc:d9:
- 90:35:65:b8:17:a9:ad:b3:98:9f:a0:7e:7d:6e:fb:
- 3f:ad:7c:c2:1b:59:36:96:da:37:32:4b:4b:5d:35:
- 02:63:8e:db:a7:cf:62:ee:cc:2e:d4:8d:c9:bd:3c:
- 6a:91:72:a2:22:a7:72:2d:20:d1:fa:ca:37:da:18:
- 98:e6:16:24:71:25:4b:c4:e5:7b:89:52:09:02:fd:
- 59:2b:04:6e:ca:07:81:d4:b3:da:da:db:e3:cc:80:
- a8:56:07:06:7c:96:08:37:9d:db:38:b6:62:34:91:
- 62:07:74:01:38:d8:72:30:e2:eb:90:71:26:62:c0:
- 57:f3
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Key Usage: critical
- Certificate Sign, CRL Sign
- X509v3 Basic Constraints: critical
- CA:TRUE, pathlen:0
- X509v3 Subject Key Identifier:
- EA:4E:7C:D4:80:2D:E5:15:81:86:26:8C:82:6D:C0:98:A4:CF:97:0F
- X509v3 Certificate Policies:
- Policy: X509v3 Any Policy
- CPS: https://www.globalsign.com/repository/
-
- X509v3 CRL Distribution Points:
-
- Full Name:
- URI:http://crl.globalsign.net/root.crl
-
- Authority Information Access:
- OCSP - URI:http://ocsp.globalsign.com/rootr1
-
- X509v3 Authority Key Identifier:
- keyid:60:7B:66:1A:45:0D:97:CA:89:50:2F:7D:04:CD:34:A8:FF:FC:FD:4B
-
- Signature Algorithm: sha256WithRSAEncryption
- d7:45:9e:a0:dc:e0:e3:61:5a:0b:7d:77:84:17:2d:65:5a:82:
- 9a:8d:a3:27:2a:85:f7:c9:ef:e9:86:fd:d4:47:cd:01:52:96:
- c5:43:bd:37:b1:e1:b8:f2:a9:d2:8a:11:84:71:91:15:89:dc:
- 02:9d:0b:cb:6c:33:85:34:28:9e:20:b2:b1:97:dc:6d:0b:10:
- c1:3c:cd:5f:ea:5d:d7:98:31:c5:34:99:5c:00:61:55:c4:1b:
- 02:5b:c5:e3:89:c8:b4:b8:6f:1e:38:f2:56:26:e9:41:ef:3d:
- cd:ac:99:4f:59:4a:57:2d:4b:7d:ae:c7:88:fb:d6:98:3b:f5:
- e5:f0:e8:89:89:b9:8b:03:cb:5a:23:1f:a4:fd:b8:ea:fb:2e:
- 9d:ae:6a:73:09:bc:fc:d5:a0:b5:44:82:ab:44:91:2e:50:2e:
- 57:c1:43:d8:91:04:8b:e9:11:2e:5f:b4:3f:79:df:1e:fb:3f:
- 30:00:8b:53:e3:b7:2c:1d:3b:4d:8b:dc:e4:64:1d:04:58:33:
- af:1b:55:e7:ab:0c:bf:30:04:74:e4:f3:0e:2f:30:39:8d:4b:
- 04:8c:1e:75:66:66:49:e0:be:40:34:c7:5c:5a:51:92:ba:12:
- 3c:52:d5:04:82:55:2d:67:a5:df:b7:95:7c:ee:3f:c3:08:ba:
- 04:be:c0:46
------BEGIN CERTIFICATE-----
-MIIEYzCCA0ugAwIBAgILBAAAAAABRE7wPiAwDQYJKoZIhvcNAQELBQAwVzELMAkG
-A1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jv
-b3QgQ0ExGzAZBgNVBAMTEkdsb2JhbFNpZ24gUm9vdCBDQTAeFw0xNDAyMjAxMDAw
-MDBaFw0yNDAyMjAxMDAwMDBaMGAxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9i
-YWxTaWduIG52LXNhMTYwNAYDVQQDEy1HbG9iYWxTaWduIERvbWFpbiBWYWxpZGF0
-aW9uIENBIC0gU0hBMjU2IC0gRzIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
-AoIBAQCp3cwOs+IyOd1JIqgTaZOHiOEM7nF9vZCHll1Z8syz0lhXV/lG72wm2DZC
-jn4wsy+aPlN7H262okxFHzzTFZMcie089Ffeyr3sBppqKqAZUn9R0XQ5CJ+r69eG
-ExWXrjbDVGYOWvKgc4Ux47JkFGr/paKOJLu9hVIVonnu8LXuPbj0fYC82ZA1ZbgX
-qa2zmJ+gfn1u+z+tfMIbWTaW2jcyS0tdNQJjjtunz2LuzC7Ujcm9PGqRcqIip3It
-INH6yjfaGJjmFiRxJUvE5XuJUgkC/VkrBG7KB4HUs9ra2+PMgKhWBwZ8lgg3nds4
-tmI0kWIHdAE42HIw4uuQcSZiwFfzAgMBAAGjggElMIIBITAOBgNVHQ8BAf8EBAMC
-AQYwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQU6k581IAt5RWBhiaMgm3A
-mKTPlw8wRwYDVR0gBEAwPjA8BgRVHSAAMDQwMgYIKwYBBQUHAgEWJmh0dHBzOi8v
-d3d3Lmdsb2JhbHNpZ24uY29tL3JlcG9zaXRvcnkvMDMGA1UdHwQsMCowKKAmoCSG
-Imh0dHA6Ly9jcmwuZ2xvYmFsc2lnbi5uZXQvcm9vdC5jcmwwPQYIKwYBBQUHAQEE
-MTAvMC0GCCsGAQUFBzABhiFodHRwOi8vb2NzcC5nbG9iYWxzaWduLmNvbS9yb290
-cjEwHwYDVR0jBBgwFoAUYHtmGkUNl8qJUC99BM00qP/8/UswDQYJKoZIhvcNAQEL
-BQADggEBANdFnqDc4ONhWgt9d4QXLWVagpqNoycqhffJ7+mG/dRHzQFSlsVDvTex
-4bjyqdKKEYRxkRWJ3AKdC8tsM4U0KJ4gsrGX3G0LEME8zV/qXdeYMcU0mVwAYVXE
-GwJbxeOJyLS4bx448lYm6UHvPc2smU9ZSlctS32ux4j71pg79eXw6ImJuYsDy1oj
-H6T9uOr7Lp2uanMJvPzVoLVEgqtEkS5QLlfBQ9iRBIvpES5ftD953x77PzAAi1Pj
-tywdO02L3ORkHQRYM68bVeerDL8wBHTk8w4vMDmNSwSMHnVmZkngvkA0x1xaUZK6
-EjxS1QSCVS1npd+3lXzuP8MIugS+wEY=
------END CERTIFICATE-----
-#endif
-static const unsigned char kDERCert14[] = {
- 0x30, 0x82, 0x04, 0x63, 0x30, 0x82, 0x03, 0x4b, 0xa0, 0x03, 0x02, 0x01,
- 0x02, 0x02, 0x0b, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01, 0x44, 0x4e, 0xf0,
- 0x3e, 0x20, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
- 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x57, 0x31, 0x0b, 0x30, 0x09, 0x06,
- 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x42, 0x45, 0x31, 0x19, 0x30, 0x17,
- 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x10, 0x47, 0x6c, 0x6f, 0x62, 0x61,
- 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x6e, 0x76, 0x2d, 0x73, 0x61, 0x31,
- 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x07, 0x52, 0x6f,
- 0x6f, 0x74, 0x20, 0x43, 0x41, 0x31, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55,
- 0x04, 0x03, 0x13, 0x12, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x53, 0x69,
- 0x67, 0x6e, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41, 0x30, 0x1e,
- 0x17, 0x0d, 0x31, 0x34, 0x30, 0x32, 0x32, 0x30, 0x31, 0x30, 0x30, 0x30,
- 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x34, 0x30, 0x32, 0x32, 0x30, 0x31,
- 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x60, 0x31, 0x0b, 0x30, 0x09,
- 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x42, 0x45, 0x31, 0x19, 0x30,
- 0x17, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x10, 0x47, 0x6c, 0x6f, 0x62,
- 0x61, 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x6e, 0x76, 0x2d, 0x73, 0x61,
- 0x31, 0x36, 0x30, 0x34, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x2d, 0x47,
- 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x44, 0x6f,
- 0x6d, 0x61, 0x69, 0x6e, 0x20, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74,
- 0x69, 0x6f, 0x6e, 0x20, 0x43, 0x41, 0x20, 0x2d, 0x20, 0x53, 0x48, 0x41,
- 0x32, 0x35, 0x36, 0x20, 0x2d, 0x20, 0x47, 0x32, 0x30, 0x82, 0x01, 0x22,
- 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
- 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a,
- 0x02, 0x82, 0x01, 0x01, 0x00, 0xa9, 0xdd, 0xcc, 0x0e, 0xb3, 0xe2, 0x32,
- 0x39, 0xdd, 0x49, 0x22, 0xa8, 0x13, 0x69, 0x93, 0x87, 0x88, 0xe1, 0x0c,
- 0xee, 0x71, 0x7d, 0xbd, 0x90, 0x87, 0x96, 0x5d, 0x59, 0xf2, 0xcc, 0xb3,
- 0xd2, 0x58, 0x57, 0x57, 0xf9, 0x46, 0xef, 0x6c, 0x26, 0xd8, 0x36, 0x42,
- 0x8e, 0x7e, 0x30, 0xb3, 0x2f, 0x9a, 0x3e, 0x53, 0x7b, 0x1f, 0x6e, 0xb6,
- 0xa2, 0x4c, 0x45, 0x1f, 0x3c, 0xd3, 0x15, 0x93, 0x1c, 0x89, 0xed, 0x3c,
- 0xf4, 0x57, 0xde, 0xca, 0xbd, 0xec, 0x06, 0x9a, 0x6a, 0x2a, 0xa0, 0x19,
- 0x52, 0x7f, 0x51, 0xd1, 0x74, 0x39, 0x08, 0x9f, 0xab, 0xeb, 0xd7, 0x86,
- 0x13, 0x15, 0x97, 0xae, 0x36, 0xc3, 0x54, 0x66, 0x0e, 0x5a, 0xf2, 0xa0,
- 0x73, 0x85, 0x31, 0xe3, 0xb2, 0x64, 0x14, 0x6a, 0xff, 0xa5, 0xa2, 0x8e,
- 0x24, 0xbb, 0xbd, 0x85, 0x52, 0x15, 0xa2, 0x79, 0xee, 0xf0, 0xb5, 0xee,
- 0x3d, 0xb8, 0xf4, 0x7d, 0x80, 0xbc, 0xd9, 0x90, 0x35, 0x65, 0xb8, 0x17,
- 0xa9, 0xad, 0xb3, 0x98, 0x9f, 0xa0, 0x7e, 0x7d, 0x6e, 0xfb, 0x3f, 0xad,
- 0x7c, 0xc2, 0x1b, 0x59, 0x36, 0x96, 0xda, 0x37, 0x32, 0x4b, 0x4b, 0x5d,
- 0x35, 0x02, 0x63, 0x8e, 0xdb, 0xa7, 0xcf, 0x62, 0xee, 0xcc, 0x2e, 0xd4,
- 0x8d, 0xc9, 0xbd, 0x3c, 0x6a, 0x91, 0x72, 0xa2, 0x22, 0xa7, 0x72, 0x2d,
- 0x20, 0xd1, 0xfa, 0xca, 0x37, 0xda, 0x18, 0x98, 0xe6, 0x16, 0x24, 0x71,
- 0x25, 0x4b, 0xc4, 0xe5, 0x7b, 0x89, 0x52, 0x09, 0x02, 0xfd, 0x59, 0x2b,
- 0x04, 0x6e, 0xca, 0x07, 0x81, 0xd4, 0xb3, 0xda, 0xda, 0xdb, 0xe3, 0xcc,
- 0x80, 0xa8, 0x56, 0x07, 0x06, 0x7c, 0x96, 0x08, 0x37, 0x9d, 0xdb, 0x38,
- 0xb6, 0x62, 0x34, 0x91, 0x62, 0x07, 0x74, 0x01, 0x38, 0xd8, 0x72, 0x30,
- 0xe2, 0xeb, 0x90, 0x71, 0x26, 0x62, 0xc0, 0x57, 0xf3, 0x02, 0x03, 0x01,
- 0x00, 0x01, 0xa3, 0x82, 0x01, 0x25, 0x30, 0x82, 0x01, 0x21, 0x30, 0x0e,
- 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02,
- 0x01, 0x06, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff,
- 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x00, 0x30, 0x1d,
- 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xea, 0x4e, 0x7c,
- 0xd4, 0x80, 0x2d, 0xe5, 0x15, 0x81, 0x86, 0x26, 0x8c, 0x82, 0x6d, 0xc0,
- 0x98, 0xa4, 0xcf, 0x97, 0x0f, 0x30, 0x47, 0x06, 0x03, 0x55, 0x1d, 0x20,
- 0x04, 0x40, 0x30, 0x3e, 0x30, 0x3c, 0x06, 0x04, 0x55, 0x1d, 0x20, 0x00,
- 0x30, 0x34, 0x30, 0x32, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
- 0x02, 0x01, 0x16, 0x26, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f,
- 0x77, 0x77, 0x77, 0x2e, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x73, 0x69,
- 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73,
- 0x69, 0x74, 0x6f, 0x72, 0x79, 0x2f, 0x30, 0x33, 0x06, 0x03, 0x55, 0x1d,
- 0x1f, 0x04, 0x2c, 0x30, 0x2a, 0x30, 0x28, 0xa0, 0x26, 0xa0, 0x24, 0x86,
- 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e,
- 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x6e,
- 0x65, 0x74, 0x2f, 0x72, 0x6f, 0x6f, 0x74, 0x2e, 0x63, 0x72, 0x6c, 0x30,
- 0x3d, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04,
- 0x31, 0x30, 0x2f, 0x30, 0x2d, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05,
- 0x07, 0x30, 0x01, 0x86, 0x21, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f,
- 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x73,
- 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x6f, 0x6f, 0x74,
- 0x72, 0x31, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30,
- 0x16, 0x80, 0x14, 0x60, 0x7b, 0x66, 0x1a, 0x45, 0x0d, 0x97, 0xca, 0x89,
- 0x50, 0x2f, 0x7d, 0x04, 0xcd, 0x34, 0xa8, 0xff, 0xfc, 0xfd, 0x4b, 0x30,
- 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b,
- 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0xd7, 0x45, 0x9e, 0xa0, 0xdc,
- 0xe0, 0xe3, 0x61, 0x5a, 0x0b, 0x7d, 0x77, 0x84, 0x17, 0x2d, 0x65, 0x5a,
- 0x82, 0x9a, 0x8d, 0xa3, 0x27, 0x2a, 0x85, 0xf7, 0xc9, 0xef, 0xe9, 0x86,
- 0xfd, 0xd4, 0x47, 0xcd, 0x01, 0x52, 0x96, 0xc5, 0x43, 0xbd, 0x37, 0xb1,
- 0xe1, 0xb8, 0xf2, 0xa9, 0xd2, 0x8a, 0x11, 0x84, 0x71, 0x91, 0x15, 0x89,
- 0xdc, 0x02, 0x9d, 0x0b, 0xcb, 0x6c, 0x33, 0x85, 0x34, 0x28, 0x9e, 0x20,
- 0xb2, 0xb1, 0x97, 0xdc, 0x6d, 0x0b, 0x10, 0xc1, 0x3c, 0xcd, 0x5f, 0xea,
- 0x5d, 0xd7, 0x98, 0x31, 0xc5, 0x34, 0x99, 0x5c, 0x00, 0x61, 0x55, 0xc4,
- 0x1b, 0x02, 0x5b, 0xc5, 0xe3, 0x89, 0xc8, 0xb4, 0xb8, 0x6f, 0x1e, 0x38,
- 0xf2, 0x56, 0x26, 0xe9, 0x41, 0xef, 0x3d, 0xcd, 0xac, 0x99, 0x4f, 0x59,
- 0x4a, 0x57, 0x2d, 0x4b, 0x7d, 0xae, 0xc7, 0x88, 0xfb, 0xd6, 0x98, 0x3b,
- 0xf5, 0xe5, 0xf0, 0xe8, 0x89, 0x89, 0xb9, 0x8b, 0x03, 0xcb, 0x5a, 0x23,
- 0x1f, 0xa4, 0xfd, 0xb8, 0xea, 0xfb, 0x2e, 0x9d, 0xae, 0x6a, 0x73, 0x09,
- 0xbc, 0xfc, 0xd5, 0xa0, 0xb5, 0x44, 0x82, 0xab, 0x44, 0x91, 0x2e, 0x50,
- 0x2e, 0x57, 0xc1, 0x43, 0xd8, 0x91, 0x04, 0x8b, 0xe9, 0x11, 0x2e, 0x5f,
- 0xb4, 0x3f, 0x79, 0xdf, 0x1e, 0xfb, 0x3f, 0x30, 0x00, 0x8b, 0x53, 0xe3,
- 0xb7, 0x2c, 0x1d, 0x3b, 0x4d, 0x8b, 0xdc, 0xe4, 0x64, 0x1d, 0x04, 0x58,
- 0x33, 0xaf, 0x1b, 0x55, 0xe7, 0xab, 0x0c, 0xbf, 0x30, 0x04, 0x74, 0xe4,
- 0xf3, 0x0e, 0x2f, 0x30, 0x39, 0x8d, 0x4b, 0x04, 0x8c, 0x1e, 0x75, 0x66,
- 0x66, 0x49, 0xe0, 0xbe, 0x40, 0x34, 0xc7, 0x5c, 0x5a, 0x51, 0x92, 0xba,
- 0x12, 0x3c, 0x52, 0xd5, 0x04, 0x82, 0x55, 0x2d, 0x67, 0xa5, 0xdf, 0xb7,
- 0x95, 0x7c, 0xee, 0x3f, 0xc3, 0x08, 0xba, 0x04, 0xbe, 0xc0, 0x46,
-};
-
-#if 0
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number:
- 04:00:00:00:00:01:44:4e:f0:42:47
- Signature Algorithm: sha256WithRSAEncryption
- Issuer: C=BE, O=GlobalSign nv-sa, OU=Root CA, CN=GlobalSign Root CA
- Validity
- Not Before: Feb 20 10:00:00 2014 GMT
- Not After : Feb 20 10:00:00 2024 GMT
- Subject: C=BE, O=GlobalSign nv-sa, CN=GlobalSign Organization Validation CA - SHA256 - G2
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:c7:0e:6c:3f:23:93:7f:cc:70:a5:9d:20:c3:0e:
- 53:3f:7e:c0:4e:c2:98:49:ca:47:d5:23:ef:03:34:
- 85:74:c8:a3:02:2e:46:5c:0b:7d:c9:88:9d:4f:8b:
- f0:f8:9c:6c:8c:55:35:db:bf:f2:b3:ea:fb:e3:56:
- e7:4a:46:d9:13:22:ca:36:d5:9b:c1:a8:e3:96:43:
- 93:f2:0c:bc:e6:f9:e6:e8:99:c8:63:48:78:7f:57:
- 36:69:1a:19:1d:5a:d1:d4:7d:c2:9c:d4:7f:e1:80:
- 12:ae:7a:ea:88:ea:57:d8:ca:0a:0a:3a:12:49:a2:
- 62:19:7a:0d:24:f7:37:eb:b4:73:92:7b:05:23:9b:
- 12:b5:ce:eb:29:df:a4:14:02:b9:01:a5:d4:a6:9c:
- 43:64:88:de:f8:7e:fe:e3:f5:1e:e5:fe:dc:a3:a8:
- e4:66:31:d9:4c:25:e9:18:b9:89:59:09:ae:e9:9d:
- 1c:6d:37:0f:4a:1e:35:20:28:e2:af:d4:21:8b:01:
- c4:45:ad:6e:2b:63:ab:92:6b:61:0a:4d:20:ed:73:
- ba:7c:ce:fe:16:b5:db:9f:80:f0:d6:8b:6c:d9:08:
- 79:4a:4f:78:65:da:92:bc:be:35:f9:b3:c4:f9:27:
- 80:4e:ff:96:52:e6:02:20:e1:07:73:e9:5d:2b:bd:
- b2:f1
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Key Usage: critical
- Certificate Sign, CRL Sign
- X509v3 Basic Constraints: critical
- CA:TRUE, pathlen:0
- X509v3 Subject Key Identifier:
- 96:DE:61:F1:BD:1C:16:29:53:1C:C0:CC:7D:3B:83:00:40:E6:1A:7C
- X509v3 Certificate Policies:
- Policy: X509v3 Any Policy
- CPS: https://www.globalsign.com/repository/
-
- X509v3 CRL Distribution Points:
-
- Full Name:
- URI:http://crl.globalsign.net/root.crl
-
- Authority Information Access:
- OCSP - URI:http://ocsp.globalsign.com/rootr1
-
- X509v3 Authority Key Identifier:
- keyid:60:7B:66:1A:45:0D:97:CA:89:50:2F:7D:04:CD:34:A8:FF:FC:FD:4B
-
- Signature Algorithm: sha256WithRSAEncryption
- 46:2a:ee:5e:bd:ae:01:60:37:31:11:86:71:74:b6:46:49:c8:
- 10:16:fe:2f:62:23:17:ab:1f:87:f8:82:ed:ca:df:0e:2c:df:
- 64:75:8e:e5:18:72:a7:8c:3a:8b:c9:ac:a5:77:50:f7:ef:9e:
- a4:e0:a0:8f:14:57:a3:2a:5f:ec:7e:6d:10:e6:ba:8d:b0:08:
- 87:76:0e:4c:b2:d9:51:bb:11:02:f2:5c:dd:1c:bd:f3:55:96:
- 0f:d4:06:c0:fc:e2:23:8a:24:70:d3:bb:f0:79:1a:a7:61:70:
- 83:8a:af:06:c5:20:d8:a1:63:d0:6c:ae:4f:32:d7:ae:7c:18:
- 45:75:05:29:77:df:42:40:64:64:86:be:2a:76:09:31:6f:1d:
- 24:f4:99:d0:85:fe:f2:21:08:f9:c6:f6:f1:d0:59:ed:d6:56:
- 3c:08:28:03:67:ba:f0:f9:f1:90:16:47:ae:67:e6:bc:80:48:
- e9:42:76:34:97:55:69:24:0e:83:d6:a0:2d:b4:f5:f3:79:8a:
- 49:28:74:1a:41:a1:c2:d3:24:88:35:30:60:94:17:b4:e1:04:
- 22:31:3d:3b:2f:17:06:b2:b8:9d:86:2b:5a:69:ef:83:f5:4b:
- c4:aa:b4:2a:f8:7c:a1:b1:85:94:8c:f4:0c:87:0c:f4:ac:40:
- f8:59:49:98
------BEGIN CERTIFICATE-----
-MIIEaTCCA1GgAwIBAgILBAAAAAABRE7wQkcwDQYJKoZIhvcNAQELBQAwVzELMAkG
-A1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jv
-b3QgQ0ExGzAZBgNVBAMTEkdsb2JhbFNpZ24gUm9vdCBDQTAeFw0xNDAyMjAxMDAw
-MDBaFw0yNDAyMjAxMDAwMDBaMGYxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9i
-YWxTaWduIG52LXNhMTwwOgYDVQQDEzNHbG9iYWxTaWduIE9yZ2FuaXphdGlvbiBW
-YWxpZGF0aW9uIENBIC0gU0hBMjU2IC0gRzIwggEiMA0GCSqGSIb3DQEBAQUAA4IB
-DwAwggEKAoIBAQDHDmw/I5N/zHClnSDDDlM/fsBOwphJykfVI+8DNIV0yKMCLkZc
-C33JiJ1Pi/D4nGyMVTXbv/Kz6vvjVudKRtkTIso21ZvBqOOWQ5PyDLzm+ebomchj
-SHh/VzZpGhkdWtHUfcKc1H/hgBKueuqI6lfYygoKOhJJomIZeg0k9zfrtHOSewUj
-mxK1zusp36QUArkBpdSmnENkiN74fv7j9R7l/tyjqORmMdlMJekYuYlZCa7pnRxt
-Nw9KHjUgKOKv1CGLAcRFrW4rY6uSa2EKTSDtc7p8zv4WtdufgPDWi2zZCHlKT3hl
-2pK8vjX5s8T5J4BO/5ZS5gIg4Qdz6V0rvbLxAgMBAAGjggElMIIBITAOBgNVHQ8B
-Af8EBAMCAQYwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQUlt5h8b0cFilT
-HMDMfTuDAEDmGnwwRwYDVR0gBEAwPjA8BgRVHSAAMDQwMgYIKwYBBQUHAgEWJmh0
-dHBzOi8vd3d3Lmdsb2JhbHNpZ24uY29tL3JlcG9zaXRvcnkvMDMGA1UdHwQsMCow
-KKAmoCSGImh0dHA6Ly9jcmwuZ2xvYmFsc2lnbi5uZXQvcm9vdC5jcmwwPQYIKwYB
-BQUHAQEEMTAvMC0GCCsGAQUFBzABhiFodHRwOi8vb2NzcC5nbG9iYWxzaWduLmNv
-bS9yb290cjEwHwYDVR0jBBgwFoAUYHtmGkUNl8qJUC99BM00qP/8/UswDQYJKoZI
-hvcNAQELBQADggEBAEYq7l69rgFgNzERhnF0tkZJyBAW/i9iIxerH4f4gu3K3w4s
-32R1juUYcqeMOovJrKV3UPfvnqTgoI8UV6MqX+x+bRDmuo2wCId2Dkyy2VG7EQLy
-XN0cvfNVlg/UBsD84iOKJHDTu/B5GqdhcIOKrwbFINihY9Bsrk8y1658GEV1BSl3
-30JAZGSGvip2CTFvHST0mdCF/vIhCPnG9vHQWe3WVjwIKANnuvD58ZAWR65n5ryA
-SOlCdjSXVWkkDoPWoC209fN5ikkodBpBocLTJIg1MGCUF7ThBCIxPTsvFwayuJ2G
-K1pp74P1S8SqtCr4fKGxhZSM9AyHDPSsQPhZSZg=
------END CERTIFICATE-----
-#endif
-static const unsigned char kDERCert15[] = {
- 0x30, 0x82, 0x04, 0x69, 0x30, 0x82, 0x03, 0x51, 0xa0, 0x03, 0x02, 0x01,
- 0x02, 0x02, 0x0b, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01, 0x44, 0x4e, 0xf0,
- 0x42, 0x47, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
- 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x57, 0x31, 0x0b, 0x30, 0x09, 0x06,
- 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x42, 0x45, 0x31, 0x19, 0x30, 0x17,
- 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x10, 0x47, 0x6c, 0x6f, 0x62, 0x61,
- 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x6e, 0x76, 0x2d, 0x73, 0x61, 0x31,
- 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x07, 0x52, 0x6f,
- 0x6f, 0x74, 0x20, 0x43, 0x41, 0x31, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55,
- 0x04, 0x03, 0x13, 0x12, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x53, 0x69,
- 0x67, 0x6e, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41, 0x30, 0x1e,
- 0x17, 0x0d, 0x31, 0x34, 0x30, 0x32, 0x32, 0x30, 0x31, 0x30, 0x30, 0x30,
- 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x34, 0x30, 0x32, 0x32, 0x30, 0x31,
- 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x66, 0x31, 0x0b, 0x30, 0x09,
- 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x42, 0x45, 0x31, 0x19, 0x30,
- 0x17, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x10, 0x47, 0x6c, 0x6f, 0x62,
- 0x61, 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x6e, 0x76, 0x2d, 0x73, 0x61,
- 0x31, 0x3c, 0x30, 0x3a, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x33, 0x47,
- 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x4f, 0x72,
- 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x56,
- 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x43, 0x41,
- 0x20, 0x2d, 0x20, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, 0x20, 0x2d, 0x20,
- 0x47, 0x32, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
- 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01,
- 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xc7,
- 0x0e, 0x6c, 0x3f, 0x23, 0x93, 0x7f, 0xcc, 0x70, 0xa5, 0x9d, 0x20, 0xc3,
- 0x0e, 0x53, 0x3f, 0x7e, 0xc0, 0x4e, 0xc2, 0x98, 0x49, 0xca, 0x47, 0xd5,
- 0x23, 0xef, 0x03, 0x34, 0x85, 0x74, 0xc8, 0xa3, 0x02, 0x2e, 0x46, 0x5c,
- 0x0b, 0x7d, 0xc9, 0x88, 0x9d, 0x4f, 0x8b, 0xf0, 0xf8, 0x9c, 0x6c, 0x8c,
- 0x55, 0x35, 0xdb, 0xbf, 0xf2, 0xb3, 0xea, 0xfb, 0xe3, 0x56, 0xe7, 0x4a,
- 0x46, 0xd9, 0x13, 0x22, 0xca, 0x36, 0xd5, 0x9b, 0xc1, 0xa8, 0xe3, 0x96,
- 0x43, 0x93, 0xf2, 0x0c, 0xbc, 0xe6, 0xf9, 0xe6, 0xe8, 0x99, 0xc8, 0x63,
- 0x48, 0x78, 0x7f, 0x57, 0x36, 0x69, 0x1a, 0x19, 0x1d, 0x5a, 0xd1, 0xd4,
- 0x7d, 0xc2, 0x9c, 0xd4, 0x7f, 0xe1, 0x80, 0x12, 0xae, 0x7a, 0xea, 0x88,
- 0xea, 0x57, 0xd8, 0xca, 0x0a, 0x0a, 0x3a, 0x12, 0x49, 0xa2, 0x62, 0x19,
- 0x7a, 0x0d, 0x24, 0xf7, 0x37, 0xeb, 0xb4, 0x73, 0x92, 0x7b, 0x05, 0x23,
- 0x9b, 0x12, 0xb5, 0xce, 0xeb, 0x29, 0xdf, 0xa4, 0x14, 0x02, 0xb9, 0x01,
- 0xa5, 0xd4, 0xa6, 0x9c, 0x43, 0x64, 0x88, 0xde, 0xf8, 0x7e, 0xfe, 0xe3,
- 0xf5, 0x1e, 0xe5, 0xfe, 0xdc, 0xa3, 0xa8, 0xe4, 0x66, 0x31, 0xd9, 0x4c,
- 0x25, 0xe9, 0x18, 0xb9, 0x89, 0x59, 0x09, 0xae, 0xe9, 0x9d, 0x1c, 0x6d,
- 0x37, 0x0f, 0x4a, 0x1e, 0x35, 0x20, 0x28, 0xe2, 0xaf, 0xd4, 0x21, 0x8b,
- 0x01, 0xc4, 0x45, 0xad, 0x6e, 0x2b, 0x63, 0xab, 0x92, 0x6b, 0x61, 0x0a,
- 0x4d, 0x20, 0xed, 0x73, 0xba, 0x7c, 0xce, 0xfe, 0x16, 0xb5, 0xdb, 0x9f,
- 0x80, 0xf0, 0xd6, 0x8b, 0x6c, 0xd9, 0x08, 0x79, 0x4a, 0x4f, 0x78, 0x65,
- 0xda, 0x92, 0xbc, 0xbe, 0x35, 0xf9, 0xb3, 0xc4, 0xf9, 0x27, 0x80, 0x4e,
- 0xff, 0x96, 0x52, 0xe6, 0x02, 0x20, 0xe1, 0x07, 0x73, 0xe9, 0x5d, 0x2b,
- 0xbd, 0xb2, 0xf1, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x25,
- 0x30, 0x82, 0x01, 0x21, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01,
- 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x12, 0x06, 0x03,
- 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01,
- 0xff, 0x02, 0x01, 0x00, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04,
- 0x16, 0x04, 0x14, 0x96, 0xde, 0x61, 0xf1, 0xbd, 0x1c, 0x16, 0x29, 0x53,
- 0x1c, 0xc0, 0xcc, 0x7d, 0x3b, 0x83, 0x00, 0x40, 0xe6, 0x1a, 0x7c, 0x30,
- 0x47, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x40, 0x30, 0x3e, 0x30, 0x3c,
- 0x06, 0x04, 0x55, 0x1d, 0x20, 0x00, 0x30, 0x34, 0x30, 0x32, 0x06, 0x08,
- 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x26, 0x68, 0x74,
- 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x67, 0x6c,
- 0x6f, 0x62, 0x61, 0x6c, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d,
- 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x2f,
- 0x30, 0x33, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x2c, 0x30, 0x2a, 0x30,
- 0x28, 0xa0, 0x26, 0xa0, 0x24, 0x86, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a,
- 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c,
- 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x6e, 0x65, 0x74, 0x2f, 0x72, 0x6f, 0x6f,
- 0x74, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x3d, 0x06, 0x08, 0x2b, 0x06, 0x01,
- 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x31, 0x30, 0x2f, 0x30, 0x2d, 0x06,
- 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x21, 0x68,
- 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x67,
- 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f,
- 0x6d, 0x2f, 0x72, 0x6f, 0x6f, 0x74, 0x72, 0x31, 0x30, 0x1f, 0x06, 0x03,
- 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x60, 0x7b, 0x66,
- 0x1a, 0x45, 0x0d, 0x97, 0xca, 0x89, 0x50, 0x2f, 0x7d, 0x04, 0xcd, 0x34,
- 0xa8, 0xff, 0xfc, 0xfd, 0x4b, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48,
- 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01,
- 0x00, 0x46, 0x2a, 0xee, 0x5e, 0xbd, 0xae, 0x01, 0x60, 0x37, 0x31, 0x11,
- 0x86, 0x71, 0x74, 0xb6, 0x46, 0x49, 0xc8, 0x10, 0x16, 0xfe, 0x2f, 0x62,
- 0x23, 0x17, 0xab, 0x1f, 0x87, 0xf8, 0x82, 0xed, 0xca, 0xdf, 0x0e, 0x2c,
- 0xdf, 0x64, 0x75, 0x8e, 0xe5, 0x18, 0x72, 0xa7, 0x8c, 0x3a, 0x8b, 0xc9,
- 0xac, 0xa5, 0x77, 0x50, 0xf7, 0xef, 0x9e, 0xa4, 0xe0, 0xa0, 0x8f, 0x14,
- 0x57, 0xa3, 0x2a, 0x5f, 0xec, 0x7e, 0x6d, 0x10, 0xe6, 0xba, 0x8d, 0xb0,
- 0x08, 0x87, 0x76, 0x0e, 0x4c, 0xb2, 0xd9, 0x51, 0xbb, 0x11, 0x02, 0xf2,
- 0x5c, 0xdd, 0x1c, 0xbd, 0xf3, 0x55, 0x96, 0x0f, 0xd4, 0x06, 0xc0, 0xfc,
- 0xe2, 0x23, 0x8a, 0x24, 0x70, 0xd3, 0xbb, 0xf0, 0x79, 0x1a, 0xa7, 0x61,
- 0x70, 0x83, 0x8a, 0xaf, 0x06, 0xc5, 0x20, 0xd8, 0xa1, 0x63, 0xd0, 0x6c,
- 0xae, 0x4f, 0x32, 0xd7, 0xae, 0x7c, 0x18, 0x45, 0x75, 0x05, 0x29, 0x77,
- 0xdf, 0x42, 0x40, 0x64, 0x64, 0x86, 0xbe, 0x2a, 0x76, 0x09, 0x31, 0x6f,
- 0x1d, 0x24, 0xf4, 0x99, 0xd0, 0x85, 0xfe, 0xf2, 0x21, 0x08, 0xf9, 0xc6,
- 0xf6, 0xf1, 0xd0, 0x59, 0xed, 0xd6, 0x56, 0x3c, 0x08, 0x28, 0x03, 0x67,
- 0xba, 0xf0, 0xf9, 0xf1, 0x90, 0x16, 0x47, 0xae, 0x67, 0xe6, 0xbc, 0x80,
- 0x48, 0xe9, 0x42, 0x76, 0x34, 0x97, 0x55, 0x69, 0x24, 0x0e, 0x83, 0xd6,
- 0xa0, 0x2d, 0xb4, 0xf5, 0xf3, 0x79, 0x8a, 0x49, 0x28, 0x74, 0x1a, 0x41,
- 0xa1, 0xc2, 0xd3, 0x24, 0x88, 0x35, 0x30, 0x60, 0x94, 0x17, 0xb4, 0xe1,
- 0x04, 0x22, 0x31, 0x3d, 0x3b, 0x2f, 0x17, 0x06, 0xb2, 0xb8, 0x9d, 0x86,
- 0x2b, 0x5a, 0x69, 0xef, 0x83, 0xf5, 0x4b, 0xc4, 0xaa, 0xb4, 0x2a, 0xf8,
- 0x7c, 0xa1, 0xb1, 0x85, 0x94, 0x8c, 0xf4, 0x0c, 0x87, 0x0c, 0xf4, 0xac,
- 0x40, 0xf8, 0x59, 0x49, 0x98,
-};
-
-#if 0
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number:
- 4d:5f:2c:34:08:b2:4c:20:cd:6d:50:7e:24:4d:c9:ec
- Signature Algorithm: sha1WithRSAEncryption
- Issuer: C=US, O=thawte, Inc., OU=Certification Services Division, OU=(c) 2006 thawte, Inc. - For authorized use only, CN=thawte Primary Root CA
- Validity
- Not Before: Feb 8 00:00:00 2010 GMT
- Not After : Feb 7 23:59:59 2020 GMT
- Subject: C=US, O=Thawte, Inc., CN=Thawte SSL CA
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:99:e4:85:5b:76:49:7d:2f:05:d8:c5:ac:c8:c8:
- a9:d3:dc:98:e6:d7:34:a6:2f:0c:f2:22:26:d8:a3:
- c9:14:4c:8f:05:a4:45:e8:14:0c:58:90:05:1a:b7:
- c5:c1:06:a5:80:af:bb:1d:49:6b:52:34:88:c3:59:
- e7:ef:6b:c4:27:41:8c:2b:66:1d:d0:e0:a3:97:98:
- 19:34:4b:41:d5:98:d5:c7:05:ad:a2:e4:d7:ed:0c:
- ad:4f:c1:b5:b0:21:fd:3e:50:53:b2:c4:90:d0:d4:
- 30:67:6c:9a:f1:0e:74:c4:c2:dc:8a:e8:97:ff:c9:
- 92:ae:01:8a:56:0a:98:32:b0:00:23:ec:90:1a:60:
- c3:ed:bb:3a:cb:0f:63:9f:0d:44:c9:52:e1:25:96:
- bf:ed:50:95:89:7f:56:14:b1:b7:61:1d:1c:07:8c:
- 3a:2c:f7:ff:80:de:39:45:d5:af:1a:d1:78:d8:c7:
- 71:6a:a3:19:a7:32:50:21:e9:f2:0e:a1:c6:13:03:
- 44:48:d1:66:a8:52:57:d7:11:b4:93:8b:e5:99:9f:
- 5d:e7:78:51:e5:4d:f6:b7:59:b4:76:b5:09:37:4d:
- 06:38:13:7a:1c:08:98:5c:c4:48:4a:cb:52:a0:a9:
- f8:b1:9d:8e:7b:79:b0:20:2f:3c:96:a8:11:62:47:
- bb:11
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- Authority Information Access:
- OCSP - URI:http://ocsp.thawte.com
-
- X509v3 Basic Constraints: critical
- CA:TRUE, pathlen:0
- X509v3 CRL Distribution Points:
-
- Full Name:
- URI:http://crl.thawte.com/ThawtePCA.crl
-
- X509v3 Key Usage: critical
- Certificate Sign, CRL Sign
- X509v3 Subject Alternative Name:
- DirName:/CN=VeriSignMPKI-2-9
- X509v3 Subject Key Identifier:
- A7:A2:83:BB:34:45:40:3D:FC:D5:30:4F:12:B9:3E:A1:01:9F:F6:DB
- X509v3 Authority Key Identifier:
- keyid:7B:5B:45:CF:AF:CE:CB:7A:FD:31:92:1A:6A:B6:F3:46:EB:57:48:50
-
- Signature Algorithm: sha1WithRSAEncryption
- 80:22:80:e0:6c:c8:95:16:d7:57:26:87:f3:72:34:db:c6:72:
- 56:27:3e:d3:96:f6:2e:25:91:a5:3e:33:97:a7:4b:e5:2f:fb:
- 25:7d:2f:07:61:fa:6f:83:74:4c:4c:53:72:20:a4:7a:cf:51:
- 51:56:81:88:b0:6d:1f:36:2c:c8:2b:b1:88:99:c1:fe:44:ab:
- 48:51:7c:d8:f2:44:64:2a:d8:71:a7:fb:1a:2f:f9:19:8d:34:
- b2:23:bf:c4:4c:55:1d:8e:44:e8:aa:5d:9a:dd:9f:fd:03:c7:
- ba:24:43:8d:2d:47:44:db:f6:d8:98:c8:b2:f9:da:ef:ed:29:
- 5c:69:12:fa:d1:23:96:0f:bf:9c:0d:f2:79:45:53:37:9a:56:
- 2f:e8:57:10:70:f6:ee:89:0c:49:89:9a:c1:23:f5:c2:2a:cc:
- 41:cf:22:ab:65:6e:b7:94:82:6d:2f:40:5f:58:de:eb:95:2b:
- a6:72:68:52:19:91:2a:ae:75:9d:4e:92:e6:ca:de:54:ea:18:
- ab:25:3c:e6:64:a6:79:1f:26:7d:61:ed:7d:d2:e5:71:55:d8:
- 93:17:7c:14:38:30:3c:df:86:e3:4c:ad:49:e3:97:59:ce:1b:
- 9b:2b:ce:dc:65:d4:0b:28:6b:4e:84:46:51:44:f7:33:08:2d:
- 58:97:21:ae
------BEGIN CERTIFICATE-----
-MIIEbDCCA1SgAwIBAgIQTV8sNAiyTCDNbVB+JE3J7DANBgkqhkiG9w0BAQUFADCB
-qTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMf
-Q2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIw
-MDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxHzAdBgNV
-BAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwHhcNMTAwMjA4MDAwMDAwWhcNMjAw
-MjA3MjM1OTU5WjA8MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMVGhhd3RlLCBJbmMu
-MRYwFAYDVQQDEw1UaGF3dGUgU1NMIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
-MIIBCgKCAQEAmeSFW3ZJfS8F2MWsyMip09yY5tc0pi8M8iIm2KPJFEyPBaRF6BQM
-WJAFGrfFwQalgK+7HUlrUjSIw1nn72vEJ0GMK2Yd0OCjl5gZNEtB1ZjVxwWtouTX
-7QytT8G1sCH9PlBTssSQ0NQwZ2ya8Q50xMLciuiX/8mSrgGKVgqYMrAAI+yQGmDD
-7bs6yw9jnw1EyVLhJZa/7VCViX9WFLG3YR0cB4w6LPf/gN45RdWvGtF42MdxaqMZ
-pzJQIenyDqHGEwNESNFmqFJX1xG0k4vlmZ9d53hR5U32t1m0drUJN00GOBN6HAiY
-XMRISstSoKn4sZ2Oe3mwIC88lqgRYke7EQIDAQABo4H7MIH4MDIGCCsGAQUFBwEB
-BCYwJDAiBggrBgEFBQcwAYYWaHR0cDovL29jc3AudGhhd3RlLmNvbTASBgNVHRMB
-Af8ECDAGAQH/AgEAMDQGA1UdHwQtMCswKaAnoCWGI2h0dHA6Ly9jcmwudGhhd3Rl
-LmNvbS9UaGF3dGVQQ0EuY3JsMA4GA1UdDwEB/wQEAwIBBjAoBgNVHREEITAfpB0w
-GzEZMBcGA1UEAxMQVmVyaVNpZ25NUEtJLTItOTAdBgNVHQ4EFgQUp6KDuzRFQD38
-1TBPErk+oQGf9tswHwYDVR0jBBgwFoAUe1tFz6/Oy3r9MZIaarbzRutXSFAwDQYJ
-KoZIhvcNAQEFBQADggEBAIAigOBsyJUW11cmh/NyNNvGclYnPtOW9i4lkaU+M5en
-S+Uv+yV9Lwdh+m+DdExMU3IgpHrPUVFWgYiwbR82LMgrsYiZwf5Eq0hRfNjyRGQq
-2HGn+xov+RmNNLIjv8RMVR2OROiqXZrdn/0Dx7okQ40tR0Tb9tiYyLL52u/tKVxp
-EvrRI5YPv5wN8nlFUzeaVi/oVxBw9u6JDEmJmsEj9cIqzEHPIqtlbreUgm0vQF9Y
-3uuVK6ZyaFIZkSqudZ1OkubK3lTqGKslPOZkpnkfJn1h7X3S5XFV2JMXfBQ4MDzf
-huNMrUnjl1nOG5srztxl1Asoa06ERlFE9zMILViXIa4=
------END CERTIFICATE-----
-#endif
-static const unsigned char kDERCert16[] = {
- 0x30, 0x82, 0x04, 0x6c, 0x30, 0x82, 0x03, 0x54, 0xa0, 0x03, 0x02, 0x01,
- 0x02, 0x02, 0x10, 0x4d, 0x5f, 0x2c, 0x34, 0x08, 0xb2, 0x4c, 0x20, 0xcd,
- 0x6d, 0x50, 0x7e, 0x24, 0x4d, 0xc9, 0xec, 0x30, 0x0d, 0x06, 0x09, 0x2a,
- 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x81,
- 0xa9, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
- 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13,
- 0x0c, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63,
- 0x2e, 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1f,
- 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f,
- 0x6e, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, 0x44,
- 0x69, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x31, 0x38, 0x30, 0x36, 0x06,
- 0x03, 0x55, 0x04, 0x0b, 0x13, 0x2f, 0x28, 0x63, 0x29, 0x20, 0x32, 0x30,
- 0x30, 0x36, 0x20, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2c, 0x20, 0x49,
- 0x6e, 0x63, 0x2e, 0x20, 0x2d, 0x20, 0x46, 0x6f, 0x72, 0x20, 0x61, 0x75,
- 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x20, 0x75, 0x73, 0x65,
- 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55,
- 0x04, 0x03, 0x13, 0x16, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x20, 0x50,
- 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20,
- 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x30, 0x30, 0x32, 0x30, 0x38,
- 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x30, 0x30,
- 0x32, 0x30, 0x37, 0x32, 0x33, 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x3c,
- 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55,
- 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0c,
- 0x54, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e,
- 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0d, 0x54,
- 0x68, 0x61, 0x77, 0x74, 0x65, 0x20, 0x53, 0x53, 0x4c, 0x20, 0x43, 0x41,
- 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
- 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00,
- 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0x99, 0xe4, 0x85,
- 0x5b, 0x76, 0x49, 0x7d, 0x2f, 0x05, 0xd8, 0xc5, 0xac, 0xc8, 0xc8, 0xa9,
- 0xd3, 0xdc, 0x98, 0xe6, 0xd7, 0x34, 0xa6, 0x2f, 0x0c, 0xf2, 0x22, 0x26,
- 0xd8, 0xa3, 0xc9, 0x14, 0x4c, 0x8f, 0x05, 0xa4, 0x45, 0xe8, 0x14, 0x0c,
- 0x58, 0x90, 0x05, 0x1a, 0xb7, 0xc5, 0xc1, 0x06, 0xa5, 0x80, 0xaf, 0xbb,
- 0x1d, 0x49, 0x6b, 0x52, 0x34, 0x88, 0xc3, 0x59, 0xe7, 0xef, 0x6b, 0xc4,
- 0x27, 0x41, 0x8c, 0x2b, 0x66, 0x1d, 0xd0, 0xe0, 0xa3, 0x97, 0x98, 0x19,
- 0x34, 0x4b, 0x41, 0xd5, 0x98, 0xd5, 0xc7, 0x05, 0xad, 0xa2, 0xe4, 0xd7,
- 0xed, 0x0c, 0xad, 0x4f, 0xc1, 0xb5, 0xb0, 0x21, 0xfd, 0x3e, 0x50, 0x53,
- 0xb2, 0xc4, 0x90, 0xd0, 0xd4, 0x30, 0x67, 0x6c, 0x9a, 0xf1, 0x0e, 0x74,
- 0xc4, 0xc2, 0xdc, 0x8a, 0xe8, 0x97, 0xff, 0xc9, 0x92, 0xae, 0x01, 0x8a,
- 0x56, 0x0a, 0x98, 0x32, 0xb0, 0x00, 0x23, 0xec, 0x90, 0x1a, 0x60, 0xc3,
- 0xed, 0xbb, 0x3a, 0xcb, 0x0f, 0x63, 0x9f, 0x0d, 0x44, 0xc9, 0x52, 0xe1,
- 0x25, 0x96, 0xbf, 0xed, 0x50, 0x95, 0x89, 0x7f, 0x56, 0x14, 0xb1, 0xb7,
- 0x61, 0x1d, 0x1c, 0x07, 0x8c, 0x3a, 0x2c, 0xf7, 0xff, 0x80, 0xde, 0x39,
- 0x45, 0xd5, 0xaf, 0x1a, 0xd1, 0x78, 0xd8, 0xc7, 0x71, 0x6a, 0xa3, 0x19,
- 0xa7, 0x32, 0x50, 0x21, 0xe9, 0xf2, 0x0e, 0xa1, 0xc6, 0x13, 0x03, 0x44,
- 0x48, 0xd1, 0x66, 0xa8, 0x52, 0x57, 0xd7, 0x11, 0xb4, 0x93, 0x8b, 0xe5,
- 0x99, 0x9f, 0x5d, 0xe7, 0x78, 0x51, 0xe5, 0x4d, 0xf6, 0xb7, 0x59, 0xb4,
- 0x76, 0xb5, 0x09, 0x37, 0x4d, 0x06, 0x38, 0x13, 0x7a, 0x1c, 0x08, 0x98,
- 0x5c, 0xc4, 0x48, 0x4a, 0xcb, 0x52, 0xa0, 0xa9, 0xf8, 0xb1, 0x9d, 0x8e,
- 0x7b, 0x79, 0xb0, 0x20, 0x2f, 0x3c, 0x96, 0xa8, 0x11, 0x62, 0x47, 0xbb,
- 0x11, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x81, 0xfb, 0x30, 0x81, 0xf8,
- 0x30, 0x32, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01,
- 0x04, 0x26, 0x30, 0x24, 0x30, 0x22, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05,
- 0x05, 0x07, 0x30, 0x01, 0x86, 0x16, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f,
- 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65,
- 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01,
- 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x00,
- 0x30, 0x34, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x2d, 0x30, 0x2b, 0x30,
- 0x29, 0xa0, 0x27, 0xa0, 0x25, 0x86, 0x23, 0x68, 0x74, 0x74, 0x70, 0x3a,
- 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65,
- 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x54, 0x68, 0x61, 0x77, 0x74, 0x65, 0x50,
- 0x43, 0x41, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d,
- 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x28,
- 0x06, 0x03, 0x55, 0x1d, 0x11, 0x04, 0x21, 0x30, 0x1f, 0xa4, 0x1d, 0x30,
- 0x1b, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x10,
- 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x4d, 0x50, 0x4b, 0x49,
- 0x2d, 0x32, 0x2d, 0x39, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04,
- 0x16, 0x04, 0x14, 0xa7, 0xa2, 0x83, 0xbb, 0x34, 0x45, 0x40, 0x3d, 0xfc,
- 0xd5, 0x30, 0x4f, 0x12, 0xb9, 0x3e, 0xa1, 0x01, 0x9f, 0xf6, 0xdb, 0x30,
- 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14,
- 0x7b, 0x5b, 0x45, 0xcf, 0xaf, 0xce, 0xcb, 0x7a, 0xfd, 0x31, 0x92, 0x1a,
- 0x6a, 0xb6, 0xf3, 0x46, 0xeb, 0x57, 0x48, 0x50, 0x30, 0x0d, 0x06, 0x09,
- 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03,
- 0x82, 0x01, 0x01, 0x00, 0x80, 0x22, 0x80, 0xe0, 0x6c, 0xc8, 0x95, 0x16,
- 0xd7, 0x57, 0x26, 0x87, 0xf3, 0x72, 0x34, 0xdb, 0xc6, 0x72, 0x56, 0x27,
- 0x3e, 0xd3, 0x96, 0xf6, 0x2e, 0x25, 0x91, 0xa5, 0x3e, 0x33, 0x97, 0xa7,
- 0x4b, 0xe5, 0x2f, 0xfb, 0x25, 0x7d, 0x2f, 0x07, 0x61, 0xfa, 0x6f, 0x83,
- 0x74, 0x4c, 0x4c, 0x53, 0x72, 0x20, 0xa4, 0x7a, 0xcf, 0x51, 0x51, 0x56,
- 0x81, 0x88, 0xb0, 0x6d, 0x1f, 0x36, 0x2c, 0xc8, 0x2b, 0xb1, 0x88, 0x99,
- 0xc1, 0xfe, 0x44, 0xab, 0x48, 0x51, 0x7c, 0xd8, 0xf2, 0x44, 0x64, 0x2a,
- 0xd8, 0x71, 0xa7, 0xfb, 0x1a, 0x2f, 0xf9, 0x19, 0x8d, 0x34, 0xb2, 0x23,
- 0xbf, 0xc4, 0x4c, 0x55, 0x1d, 0x8e, 0x44, 0xe8, 0xaa, 0x5d, 0x9a, 0xdd,
- 0x9f, 0xfd, 0x03, 0xc7, 0xba, 0x24, 0x43, 0x8d, 0x2d, 0x47, 0x44, 0xdb,
- 0xf6, 0xd8, 0x98, 0xc8, 0xb2, 0xf9, 0xda, 0xef, 0xed, 0x29, 0x5c, 0x69,
- 0x12, 0xfa, 0xd1, 0x23, 0x96, 0x0f, 0xbf, 0x9c, 0x0d, 0xf2, 0x79, 0x45,
- 0x53, 0x37, 0x9a, 0x56, 0x2f, 0xe8, 0x57, 0x10, 0x70, 0xf6, 0xee, 0x89,
- 0x0c, 0x49, 0x89, 0x9a, 0xc1, 0x23, 0xf5, 0xc2, 0x2a, 0xcc, 0x41, 0xcf,
- 0x22, 0xab, 0x65, 0x6e, 0xb7, 0x94, 0x82, 0x6d, 0x2f, 0x40, 0x5f, 0x58,
- 0xde, 0xeb, 0x95, 0x2b, 0xa6, 0x72, 0x68, 0x52, 0x19, 0x91, 0x2a, 0xae,
- 0x75, 0x9d, 0x4e, 0x92, 0xe6, 0xca, 0xde, 0x54, 0xea, 0x18, 0xab, 0x25,
- 0x3c, 0xe6, 0x64, 0xa6, 0x79, 0x1f, 0x26, 0x7d, 0x61, 0xed, 0x7d, 0xd2,
- 0xe5, 0x71, 0x55, 0xd8, 0x93, 0x17, 0x7c, 0x14, 0x38, 0x30, 0x3c, 0xdf,
- 0x86, 0xe3, 0x4c, 0xad, 0x49, 0xe3, 0x97, 0x59, 0xce, 0x1b, 0x9b, 0x2b,
- 0xce, 0xdc, 0x65, 0xd4, 0x0b, 0x28, 0x6b, 0x4e, 0x84, 0x46, 0x51, 0x44,
- 0xf7, 0x33, 0x08, 0x2d, 0x58, 0x97, 0x21, 0xae,
-};
-
-#if 0
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number:
- 6e:8a:90:eb:cf:f0:44:8a:72:0d:08:05:d0:82:a5:44
- Signature Algorithm: sha256WithRSAEncryption
- Issuer: C=US, O=GeoTrust Inc., CN=GeoTrust Primary Certification Authority
- Validity
- Not Before: Oct 31 00:00:00 2013 GMT
- Not After : Oct 30 23:59:59 2023 GMT
- Subject: C=US, O=GeoTrust Inc., CN=GeoTrust EV SSL CA - G4
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:d9:b4:05:f2:38:67:0f:09:e7:7c:f5:63:2a:e5:
- b9:5e:a8:11:ae:75:71:d9:4c:84:67:ad:89:5d:fc:
- 28:3d:2a:b0:a5:d5:d4:e6:30:0a:84:d4:e4:18:cb:
- 85:37:c5:46:71:eb:1c:7b:69:db:65:69:8c:30:05:
- 3e:07:e1:6f:3c:c1:0b:61:e6:38:44:fc:bc:8c:2f:
- 4e:75:57:f5:96:99:7c:3e:87:1f:0f:90:4b:70:c3:
- 3f:39:45:3b:3a:6b:cb:bb:7b:40:54:d1:8b:4b:a1:
- 72:d2:04:e9:e0:72:1a:93:11:7a:2f:f1:ab:9d:9c:
- 98:58:ae:2c:ea:77:5f:2f:2e:87:af:b8:6b:e3:e2:
- e2:3f:d6:3d:e0:96:44:df:11:55:63:52:2f:f4:26:
- 78:c4:0f:20:4d:0a:c0:68:70:15:86:38:ee:b7:76:
- 88:ab:18:8f:4f:35:1e:d4:8c:c9:db:7e:3d:44:d4:
- 36:8c:c1:37:b5:59:5b:87:f9:e9:f1:d4:c5:28:bd:
- 1d:dc:cc:96:72:d1:7a:a1:a7:20:b5:b8:af:f8:6e:
- a5:60:7b:2b:8d:1f:ee:f4:2b:d6:69:cd:af:ca:80:
- 58:29:e8:4c:00:20:8a:49:0a:6e:8e:8c:a8:d1:00:
- 12:84:b6:c5:e2:95:a2:c0:3b:a4:6b:f0:82:d0:96:
- 5d:25
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Basic Constraints: critical
- CA:TRUE, pathlen:0
- X509v3 Key Usage: critical
- Certificate Sign, CRL Sign
- Authority Information Access:
- OCSP - URI:http://g2.symcb.com
-
- X509v3 Certificate Policies:
- Policy: X509v3 Any Policy
- CPS: https://www.geotrust.com/resources/cps
-
- X509v3 CRL Distribution Points:
-
- Full Name:
- URI:http://g1.symcb.com/GeoTrustPCA.crl
-
- X509v3 Subject Alternative Name:
- DirName:/CN=SymantecPKI-1-538
- X509v3 Subject Key Identifier:
- DE:CF:5C:50:B7:AE:02:1F:15:17:AA:16:E8:0D:B5:28:9D:6A:5A:F3
- X509v3 Authority Key Identifier:
- keyid:2C:D5:50:41:97:15:8B:F0:8F:36:61:5B:4A:FB:6B:D9:99:C9:33:92
-
- Signature Algorithm: sha256WithRSAEncryption
- b4:8e:bd:07:b9:9a:85:ec:3b:67:bd:07:60:61:e6:84:d1:d4:
- ef:eb:1b:ba:0b:82:4b:95:64:b6:66:53:23:bd:b7:84:dd:e4:
- 7b:8d:09:da:cf:b2:f5:f1:c3:bf:87:84:be:4e:a6:a8:c2:e7:
- 12:39:28:34:e0:a4:56:44:40:0c:9f:88:a3:15:d3:e8:d3:5e:
- e3:1c:04:60:fb:69:36:4f:6a:7e:0c:2a:28:c1:f3:aa:58:0e:
- 6c:ce:1d:07:c3:4a:c0:9c:8d:c3:74:b1:ae:82:f0:1a:e1:f9:
- 4e:29:bd:46:de:b7:1d:f9:7d:db:d9:0f:84:cb:92:45:cc:1c:
- b3:18:f6:a0:cf:71:6f:0c:2e:9b:d2:2d:b3:99:93:83:44:ac:
- 15:aa:9b:2e:67:ec:4f:88:69:05:56:7b:8b:b2:43:a9:3a:6c:
- 1c:13:33:25:1b:fd:a8:c8:57:02:fb:1c:e0:d1:bd:3b:56:44:
- 65:c3:63:f5:1b:ef:ec:30:d9:e3:6e:2e:13:e9:39:08:2a:0c:
- 72:f3:9a:cc:f6:27:29:84:d3:ef:4c:c7:84:11:65:1f:c6:e3:
- 81:03:db:87:cc:78:f7:b5:9d:96:3e:6a:7f:bc:11:85:7a:75:
- e6:41:7d:0d:cf:f9:e5:85:69:25:8f:c7:8d:07:2d:f8:69:0f:
- cb:41:53:00
------BEGIN CERTIFICATE-----
-MIIEbjCCA1agAwIBAgIQboqQ68/wRIpyDQgF0IKlRDANBgkqhkiG9w0BAQsFADBY
-MQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjExMC8GA1UEAxMo
-R2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0xMzEw
-MzEwMDAwMDBaFw0yMzEwMzAyMzU5NTlaMEcxCzAJBgNVBAYTAlVTMRYwFAYDVQQK
-Ew1HZW9UcnVzdCBJbmMuMSAwHgYDVQQDExdHZW9UcnVzdCBFViBTU0wgQ0EgLSBH
-NDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANm0BfI4Zw8J53z1Yyrl
-uV6oEa51cdlMhGetiV38KD0qsKXV1OYwCoTU5BjLhTfFRnHrHHtp22VpjDAFPgfh
-bzzBC2HmOET8vIwvTnVX9ZaZfD6HHw+QS3DDPzlFOzpry7t7QFTRi0uhctIE6eBy
-GpMRei/xq52cmFiuLOp3Xy8uh6+4a+Pi4j/WPeCWRN8RVWNSL/QmeMQPIE0KwGhw
-FYY47rd2iKsYj081HtSMydt+PUTUNozBN7VZW4f56fHUxSi9HdzMlnLReqGnILW4
-r/hupWB7K40f7vQr1mnNr8qAWCnoTAAgikkKbo6MqNEAEoS2xeKVosA7pGvwgtCW
-XSUCAwEAAaOCAUMwggE/MBIGA1UdEwEB/wQIMAYBAf8CAQAwDgYDVR0PAQH/BAQD
-AgEGMC8GCCsGAQUFBwEBBCMwITAfBggrBgEFBQcwAYYTaHR0cDovL2cyLnN5bWNi
-LmNvbTBHBgNVHSAEQDA+MDwGBFUdIAAwNDAyBggrBgEFBQcCARYmaHR0cHM6Ly93
-d3cuZ2VvdHJ1c3QuY29tL3Jlc291cmNlcy9jcHMwNAYDVR0fBC0wKzApoCegJYYj
-aHR0cDovL2cxLnN5bWNiLmNvbS9HZW9UcnVzdFBDQS5jcmwwKQYDVR0RBCIwIKQe
-MBwxGjAYBgNVBAMTEVN5bWFudGVjUEtJLTEtNTM4MB0GA1UdDgQWBBTez1xQt64C
-HxUXqhboDbUonWpa8zAfBgNVHSMEGDAWgBQs1VBBlxWL8I82YVtK+2vZmckzkjAN
-BgkqhkiG9w0BAQsFAAOCAQEAtI69B7mahew7Z70HYGHmhNHU7+sbuguCS5VktmZT
-I723hN3ke40J2s+y9fHDv4eEvk6mqMLnEjkoNOCkVkRADJ+IoxXT6NNe4xwEYPtp
-Nk9qfgwqKMHzqlgObM4dB8NKwJyNw3SxroLwGuH5Tim9Rt63Hfl929kPhMuSRcwc
-sxj2oM9xbwwum9Its5mTg0SsFaqbLmfsT4hpBVZ7i7JDqTpsHBMzJRv9qMhXAvsc
-4NG9O1ZEZcNj9Rvv7DDZ424uE+k5CCoMcvOazPYnKYTT70zHhBFlH8bjgQPbh8x4
-97Wdlj5qf7wRhXp15kF9Dc/55YVpJY/HjQct+GkPy0FTAA==
------END CERTIFICATE-----
-#endif
-static const unsigned char kDERCert17[] = {
- 0x30, 0x82, 0x04, 0x6e, 0x30, 0x82, 0x03, 0x56, 0xa0, 0x03, 0x02, 0x01,
- 0x02, 0x02, 0x10, 0x6e, 0x8a, 0x90, 0xeb, 0xcf, 0xf0, 0x44, 0x8a, 0x72,
- 0x0d, 0x08, 0x05, 0xd0, 0x82, 0xa5, 0x44, 0x30, 0x0d, 0x06, 0x09, 0x2a,
- 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x58,
- 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55,
- 0x53, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0d,
- 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x49, 0x6e, 0x63,
- 0x2e, 0x31, 0x31, 0x30, 0x2f, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x28,
- 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x50, 0x72, 0x69,
- 0x6d, 0x61, 0x72, 0x79, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69,
- 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f,
- 0x72, 0x69, 0x74, 0x79, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x33, 0x31, 0x30,
- 0x33, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32,
- 0x33, 0x31, 0x30, 0x33, 0x30, 0x32, 0x33, 0x35, 0x39, 0x35, 0x39, 0x5a,
- 0x30, 0x47, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
- 0x02, 0x55, 0x53, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a,
- 0x13, 0x0d, 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x49,
- 0x6e, 0x63, 0x2e, 0x31, 0x20, 0x30, 0x1e, 0x06, 0x03, 0x55, 0x04, 0x03,
- 0x13, 0x17, 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x45,
- 0x56, 0x20, 0x53, 0x53, 0x4c, 0x20, 0x43, 0x41, 0x20, 0x2d, 0x20, 0x47,
- 0x34, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48,
- 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f,
- 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xd9, 0xb4,
- 0x05, 0xf2, 0x38, 0x67, 0x0f, 0x09, 0xe7, 0x7c, 0xf5, 0x63, 0x2a, 0xe5,
- 0xb9, 0x5e, 0xa8, 0x11, 0xae, 0x75, 0x71, 0xd9, 0x4c, 0x84, 0x67, 0xad,
- 0x89, 0x5d, 0xfc, 0x28, 0x3d, 0x2a, 0xb0, 0xa5, 0xd5, 0xd4, 0xe6, 0x30,
- 0x0a, 0x84, 0xd4, 0xe4, 0x18, 0xcb, 0x85, 0x37, 0xc5, 0x46, 0x71, 0xeb,
- 0x1c, 0x7b, 0x69, 0xdb, 0x65, 0x69, 0x8c, 0x30, 0x05, 0x3e, 0x07, 0xe1,
- 0x6f, 0x3c, 0xc1, 0x0b, 0x61, 0xe6, 0x38, 0x44, 0xfc, 0xbc, 0x8c, 0x2f,
- 0x4e, 0x75, 0x57, 0xf5, 0x96, 0x99, 0x7c, 0x3e, 0x87, 0x1f, 0x0f, 0x90,
- 0x4b, 0x70, 0xc3, 0x3f, 0x39, 0x45, 0x3b, 0x3a, 0x6b, 0xcb, 0xbb, 0x7b,
- 0x40, 0x54, 0xd1, 0x8b, 0x4b, 0xa1, 0x72, 0xd2, 0x04, 0xe9, 0xe0, 0x72,
- 0x1a, 0x93, 0x11, 0x7a, 0x2f, 0xf1, 0xab, 0x9d, 0x9c, 0x98, 0x58, 0xae,
- 0x2c, 0xea, 0x77, 0x5f, 0x2f, 0x2e, 0x87, 0xaf, 0xb8, 0x6b, 0xe3, 0xe2,
- 0xe2, 0x3f, 0xd6, 0x3d, 0xe0, 0x96, 0x44, 0xdf, 0x11, 0x55, 0x63, 0x52,
- 0x2f, 0xf4, 0x26, 0x78, 0xc4, 0x0f, 0x20, 0x4d, 0x0a, 0xc0, 0x68, 0x70,
- 0x15, 0x86, 0x38, 0xee, 0xb7, 0x76, 0x88, 0xab, 0x18, 0x8f, 0x4f, 0x35,
- 0x1e, 0xd4, 0x8c, 0xc9, 0xdb, 0x7e, 0x3d, 0x44, 0xd4, 0x36, 0x8c, 0xc1,
- 0x37, 0xb5, 0x59, 0x5b, 0x87, 0xf9, 0xe9, 0xf1, 0xd4, 0xc5, 0x28, 0xbd,
- 0x1d, 0xdc, 0xcc, 0x96, 0x72, 0xd1, 0x7a, 0xa1, 0xa7, 0x20, 0xb5, 0xb8,
- 0xaf, 0xf8, 0x6e, 0xa5, 0x60, 0x7b, 0x2b, 0x8d, 0x1f, 0xee, 0xf4, 0x2b,
- 0xd6, 0x69, 0xcd, 0xaf, 0xca, 0x80, 0x58, 0x29, 0xe8, 0x4c, 0x00, 0x20,
- 0x8a, 0x49, 0x0a, 0x6e, 0x8e, 0x8c, 0xa8, 0xd1, 0x00, 0x12, 0x84, 0xb6,
- 0xc5, 0xe2, 0x95, 0xa2, 0xc0, 0x3b, 0xa4, 0x6b, 0xf0, 0x82, 0xd0, 0x96,
- 0x5d, 0x25, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x43, 0x30,
- 0x82, 0x01, 0x3f, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01,
- 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x00, 0x30,
- 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03,
- 0x02, 0x01, 0x06, 0x30, 0x2f, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05,
- 0x07, 0x01, 0x01, 0x04, 0x23, 0x30, 0x21, 0x30, 0x1f, 0x06, 0x08, 0x2b,
- 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x13, 0x68, 0x74, 0x74,
- 0x70, 0x3a, 0x2f, 0x2f, 0x67, 0x32, 0x2e, 0x73, 0x79, 0x6d, 0x63, 0x62,
- 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x47, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04,
- 0x40, 0x30, 0x3e, 0x30, 0x3c, 0x06, 0x04, 0x55, 0x1d, 0x20, 0x00, 0x30,
- 0x34, 0x30, 0x32, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02,
- 0x01, 0x16, 0x26, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77,
- 0x77, 0x77, 0x2e, 0x67, 0x65, 0x6f, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e,
- 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65,
- 0x73, 0x2f, 0x63, 0x70, 0x73, 0x30, 0x34, 0x06, 0x03, 0x55, 0x1d, 0x1f,
- 0x04, 0x2d, 0x30, 0x2b, 0x30, 0x29, 0xa0, 0x27, 0xa0, 0x25, 0x86, 0x23,
- 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x67, 0x31, 0x2e, 0x73, 0x79,
- 0x6d, 0x63, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x47, 0x65, 0x6f, 0x54,
- 0x72, 0x75, 0x73, 0x74, 0x50, 0x43, 0x41, 0x2e, 0x63, 0x72, 0x6c, 0x30,
- 0x29, 0x06, 0x03, 0x55, 0x1d, 0x11, 0x04, 0x22, 0x30, 0x20, 0xa4, 0x1e,
- 0x30, 0x1c, 0x31, 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
- 0x11, 0x53, 0x79, 0x6d, 0x61, 0x6e, 0x74, 0x65, 0x63, 0x50, 0x4b, 0x49,
- 0x2d, 0x31, 0x2d, 0x35, 0x33, 0x38, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d,
- 0x0e, 0x04, 0x16, 0x04, 0x14, 0xde, 0xcf, 0x5c, 0x50, 0xb7, 0xae, 0x02,
- 0x1f, 0x15, 0x17, 0xaa, 0x16, 0xe8, 0x0d, 0xb5, 0x28, 0x9d, 0x6a, 0x5a,
- 0xf3, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16,
- 0x80, 0x14, 0x2c, 0xd5, 0x50, 0x41, 0x97, 0x15, 0x8b, 0xf0, 0x8f, 0x36,
- 0x61, 0x5b, 0x4a, 0xfb, 0x6b, 0xd9, 0x99, 0xc9, 0x33, 0x92, 0x30, 0x0d,
- 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05,
- 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0xb4, 0x8e, 0xbd, 0x07, 0xb9, 0x9a,
- 0x85, 0xec, 0x3b, 0x67, 0xbd, 0x07, 0x60, 0x61, 0xe6, 0x84, 0xd1, 0xd4,
- 0xef, 0xeb, 0x1b, 0xba, 0x0b, 0x82, 0x4b, 0x95, 0x64, 0xb6, 0x66, 0x53,
- 0x23, 0xbd, 0xb7, 0x84, 0xdd, 0xe4, 0x7b, 0x8d, 0x09, 0xda, 0xcf, 0xb2,
- 0xf5, 0xf1, 0xc3, 0xbf, 0x87, 0x84, 0xbe, 0x4e, 0xa6, 0xa8, 0xc2, 0xe7,
- 0x12, 0x39, 0x28, 0x34, 0xe0, 0xa4, 0x56, 0x44, 0x40, 0x0c, 0x9f, 0x88,
- 0xa3, 0x15, 0xd3, 0xe8, 0xd3, 0x5e, 0xe3, 0x1c, 0x04, 0x60, 0xfb, 0x69,
- 0x36, 0x4f, 0x6a, 0x7e, 0x0c, 0x2a, 0x28, 0xc1, 0xf3, 0xaa, 0x58, 0x0e,
- 0x6c, 0xce, 0x1d, 0x07, 0xc3, 0x4a, 0xc0, 0x9c, 0x8d, 0xc3, 0x74, 0xb1,
- 0xae, 0x82, 0xf0, 0x1a, 0xe1, 0xf9, 0x4e, 0x29, 0xbd, 0x46, 0xde, 0xb7,
- 0x1d, 0xf9, 0x7d, 0xdb, 0xd9, 0x0f, 0x84, 0xcb, 0x92, 0x45, 0xcc, 0x1c,
- 0xb3, 0x18, 0xf6, 0xa0, 0xcf, 0x71, 0x6f, 0x0c, 0x2e, 0x9b, 0xd2, 0x2d,
- 0xb3, 0x99, 0x93, 0x83, 0x44, 0xac, 0x15, 0xaa, 0x9b, 0x2e, 0x67, 0xec,
- 0x4f, 0x88, 0x69, 0x05, 0x56, 0x7b, 0x8b, 0xb2, 0x43, 0xa9, 0x3a, 0x6c,
- 0x1c, 0x13, 0x33, 0x25, 0x1b, 0xfd, 0xa8, 0xc8, 0x57, 0x02, 0xfb, 0x1c,
- 0xe0, 0xd1, 0xbd, 0x3b, 0x56, 0x44, 0x65, 0xc3, 0x63, 0xf5, 0x1b, 0xef,
- 0xec, 0x30, 0xd9, 0xe3, 0x6e, 0x2e, 0x13, 0xe9, 0x39, 0x08, 0x2a, 0x0c,
- 0x72, 0xf3, 0x9a, 0xcc, 0xf6, 0x27, 0x29, 0x84, 0xd3, 0xef, 0x4c, 0xc7,
- 0x84, 0x11, 0x65, 0x1f, 0xc6, 0xe3, 0x81, 0x03, 0xdb, 0x87, 0xcc, 0x78,
- 0xf7, 0xb5, 0x9d, 0x96, 0x3e, 0x6a, 0x7f, 0xbc, 0x11, 0x85, 0x7a, 0x75,
- 0xe6, 0x41, 0x7d, 0x0d, 0xcf, 0xf9, 0xe5, 0x85, 0x69, 0x25, 0x8f, 0xc7,
- 0x8d, 0x07, 0x2d, 0xf8, 0x69, 0x0f, 0xcb, 0x41, 0x53, 0x00,
-};
-
-#if 0
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number: 1828629 (0x1be715)
- Signature Algorithm: sha256WithRSAEncryption
- Issuer: C=US, O=The Go Daddy Group, Inc., OU=Go Daddy Class 2 Certification Authority
- Validity
- Not Before: Jan 1 07:00:00 2014 GMT
- Not After : May 30 07:00:00 2031 GMT
- Subject: C=US, ST=Arizona, L=Scottsdale, O=GoDaddy.com, Inc., CN=Go Daddy Root Certificate Authority - G2
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:bf:71:62:08:f1:fa:59:34:f7:1b:c9:18:a3:f7:
- 80:49:58:e9:22:83:13:a6:c5:20:43:01:3b:84:f1:
- e6:85:49:9f:27:ea:f6:84:1b:4e:a0:b4:db:70:98:
- c7:32:01:b1:05:3e:07:4e:ee:f4:fa:4f:2f:59:30:
- 22:e7:ab:19:56:6b:e2:80:07:fc:f3:16:75:80:39:
- 51:7b:e5:f9:35:b6:74:4e:a9:8d:82:13:e4:b6:3f:
- a9:03:83:fa:a2:be:8a:15:6a:7f:de:0b:c3:b6:19:
- 14:05:ca:ea:c3:a8:04:94:3b:46:7c:32:0d:f3:00:
- 66:22:c8:8d:69:6d:36:8c:11:18:b7:d3:b2:1c:60:
- b4:38:fa:02:8c:ce:d3:dd:46:07:de:0a:3e:eb:5d:
- 7c:c8:7c:fb:b0:2b:53:a4:92:62:69:51:25:05:61:
- 1a:44:81:8c:2c:a9:43:96:23:df:ac:3a:81:9a:0e:
- 29:c5:1c:a9:e9:5d:1e:b6:9e:9e:30:0a:39:ce:f1:
- 88:80:fb:4b:5d:cc:32:ec:85:62:43:25:34:02:56:
- 27:01:91:b4:3b:70:2a:3f:6e:b1:e8:9c:88:01:7d:
- 9f:d4:f9:db:53:6d:60:9d:bf:2c:e7:58:ab:b8:5f:
- 46:fc:ce:c4:1b:03:3c:09:eb:49:31:5c:69:46:b3:
- e0:47
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Basic Constraints: critical
- CA:TRUE
- X509v3 Key Usage: critical
- Certificate Sign, CRL Sign
- X509v3 Subject Key Identifier:
- 3A:9A:85:07:10:67:28:B6:EF:F6:BD:05:41:6E:20:C1:94:DA:0F:DE
- X509v3 Authority Key Identifier:
- keyid:D2:C4:B0:D2:91:D4:4C:11:71:B3:61:CB:3D:A1:FE:DD:A8:6A:D4:E3
-
- Authority Information Access:
- OCSP - URI:http://ocsp.godaddy.com/
-
- X509v3 CRL Distribution Points:
-
- Full Name:
- URI:http://crl.godaddy.com/gdroot.crl
-
- X509v3 Certificate Policies:
- Policy: X509v3 Any Policy
- CPS: https://certs.godaddy.com/repository/
-
- Signature Algorithm: sha256WithRSAEncryption
- 59:0b:53:bd:92:86:11:a7:24:7b:ed:5b:31:cf:1d:1f:6c:70:
- c5:b8:6e:be:4e:bb:f6:be:97:50:e1:30:7f:ba:28:5c:62:94:
- c2:e3:7e:33:f7:fb:42:76:85:db:95:1c:8c:22:58:75:09:0c:
- 88:65:67:39:0a:16:09:c5:a0:38:97:a4:c5:23:93:3f:b4:18:
- a6:01:06:44:91:e3:a7:69:27:b4:5a:25:7f:3a:b7:32:cd:dd:
- 84:ff:2a:38:29:33:a4:dd:67:b2:85:fe:a1:88:20:1c:50:89:
- c8:dc:2a:f6:42:03:37:4c:e6:88:df:d5:af:24:f2:b1:c3:df:
- cc:b5:ec:e0:99:5e:b7:49:54:20:3c:94:18:0c:c7:1c:52:18:
- 49:a4:6d:e1:b3:58:0b:c9:d8:ec:d9:ae:1c:32:8e:28:70:0d:
- e2:fe:a6:17:9e:84:0f:bd:57:70:b3:5a:e9:1f:a0:86:53:bb:
- ef:7c:ff:69:0b:e0:48:c3:b7:93:0b:c8:0a:54:c4:ac:5d:14:
- 67:37:6c:ca:a5:2f:31:08:37:aa:6e:6f:8c:bc:9b:e2:57:5d:
- 24:81:af:97:97:9c:84:ad:6c:ac:37:4c:66:f3:61:91:11:20:
- e4:be:30:9f:7a:a4:29:09:b0:e1:34:5f:64:77:18:40:51:df:
- 8c:30:a6:af
------BEGIN CERTIFICATE-----
-MIIEfTCCA2WgAwIBAgIDG+cVMA0GCSqGSIb3DQEBCwUAMGMxCzAJBgNVBAYTAlVT
-MSEwHwYDVQQKExhUaGUgR28gRGFkZHkgR3JvdXAsIEluYy4xMTAvBgNVBAsTKEdv
-IERhZGR5IENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTQwMTAx
-MDcwMDAwWhcNMzEwNTMwMDcwMDAwWjCBgzELMAkGA1UEBhMCVVMxEDAOBgNVBAgT
-B0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAYBgNVBAoTEUdvRGFkZHku
-Y29tLCBJbmMuMTEwLwYDVQQDEyhHbyBEYWRkeSBSb290IENlcnRpZmljYXRlIEF1
-dGhvcml0eSAtIEcyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAv3Fi
-CPH6WTT3G8kYo/eASVjpIoMTpsUgQwE7hPHmhUmfJ+r2hBtOoLTbcJjHMgGxBT4H
-Tu70+k8vWTAi56sZVmvigAf88xZ1gDlRe+X5NbZ0TqmNghPktj+pA4P6or6KFWp/
-3gvDthkUBcrqw6gElDtGfDIN8wBmIsiNaW02jBEYt9OyHGC0OPoCjM7T3UYH3go+
-6118yHz7sCtTpJJiaVElBWEaRIGMLKlDliPfrDqBmg4pxRyp6V0etp6eMAo5zvGI
-gPtLXcwy7IViQyU0AlYnAZG0O3AqP26x6JyIAX2f1PnbU21gnb8s51iruF9G/M7E
-GwM8CetJMVxpRrPgRwIDAQABo4IBFzCCARMwDwYDVR0TAQH/BAUwAwEB/zAOBgNV
-HQ8BAf8EBAMCAQYwHQYDVR0OBBYEFDqahQcQZyi27/a9BUFuIMGU2g/eMB8GA1Ud
-IwQYMBaAFNLEsNKR1EwRcbNhyz2h/t2oatTjMDQGCCsGAQUFBwEBBCgwJjAkBggr
-BgEFBQcwAYYYaHR0cDovL29jc3AuZ29kYWRkeS5jb20vMDIGA1UdHwQrMCkwJ6Al
-oCOGIWh0dHA6Ly9jcmwuZ29kYWRkeS5jb20vZ2Ryb290LmNybDBGBgNVHSAEPzA9
-MDsGBFUdIAAwMzAxBggrBgEFBQcCARYlaHR0cHM6Ly9jZXJ0cy5nb2RhZGR5LmNv
-bS9yZXBvc2l0b3J5LzANBgkqhkiG9w0BAQsFAAOCAQEAWQtTvZKGEacke+1bMc8d
-H2xwxbhuvk679r6XUOEwf7ooXGKUwuN+M/f7QnaF25UcjCJYdQkMiGVnOQoWCcWg
-OJekxSOTP7QYpgEGRJHjp2kntFolfzq3Ms3dhP8qOCkzpN1nsoX+oYggHFCJyNwq
-9kIDN0zmiN/VryTyscPfzLXs4Jlet0lUIDyUGAzHHFIYSaRt4bNYC8nY7NmuHDKO
-KHAN4v6mF56ED71XcLNa6R+ghlO773z/aQvgSMO3kwvIClTErF0UZzdsyqUvMQg3
-qm5vjLyb4lddJIGvl5echK1srDdMZvNhkREg5L4wn3qkKQmw4TRfZHcYQFHfjDCm
-rw==
------END CERTIFICATE-----
-#endif
-static const unsigned char kDERCert18[] = {
- 0x30, 0x82, 0x04, 0x7d, 0x30, 0x82, 0x03, 0x65, 0xa0, 0x03, 0x02, 0x01,
- 0x02, 0x02, 0x03, 0x1b, 0xe7, 0x15, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
- 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x63, 0x31,
- 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53,
- 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x18, 0x54,
- 0x68, 0x65, 0x20, 0x47, 0x6f, 0x20, 0x44, 0x61, 0x64, 0x64, 0x79, 0x20,
- 0x47, 0x72, 0x6f, 0x75, 0x70, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31,
- 0x31, 0x30, 0x2f, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x28, 0x47, 0x6f,
- 0x20, 0x44, 0x61, 0x64, 0x64, 0x79, 0x20, 0x43, 0x6c, 0x61, 0x73, 0x73,
- 0x20, 0x32, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61,
- 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69,
- 0x74, 0x79, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x34, 0x30, 0x31, 0x30, 0x31,
- 0x30, 0x37, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x33, 0x31, 0x30,
- 0x35, 0x33, 0x30, 0x30, 0x37, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x81,
- 0x83, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
- 0x55, 0x53, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13,
- 0x07, 0x41, 0x72, 0x69, 0x7a, 0x6f, 0x6e, 0x61, 0x31, 0x13, 0x30, 0x11,
- 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x0a, 0x53, 0x63, 0x6f, 0x74, 0x74,
- 0x73, 0x64, 0x61, 0x6c, 0x65, 0x31, 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55,
- 0x04, 0x0a, 0x13, 0x11, 0x47, 0x6f, 0x44, 0x61, 0x64, 0x64, 0x79, 0x2e,
- 0x63, 0x6f, 0x6d, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x31, 0x30,
- 0x2f, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x28, 0x47, 0x6f, 0x20, 0x44,
- 0x61, 0x64, 0x64, 0x79, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x65,
- 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75,
- 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x20, 0x2d, 0x20, 0x47, 0x32,
- 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
- 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00,
- 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xbf, 0x71, 0x62,
- 0x08, 0xf1, 0xfa, 0x59, 0x34, 0xf7, 0x1b, 0xc9, 0x18, 0xa3, 0xf7, 0x80,
- 0x49, 0x58, 0xe9, 0x22, 0x83, 0x13, 0xa6, 0xc5, 0x20, 0x43, 0x01, 0x3b,
- 0x84, 0xf1, 0xe6, 0x85, 0x49, 0x9f, 0x27, 0xea, 0xf6, 0x84, 0x1b, 0x4e,
- 0xa0, 0xb4, 0xdb, 0x70, 0x98, 0xc7, 0x32, 0x01, 0xb1, 0x05, 0x3e, 0x07,
- 0x4e, 0xee, 0xf4, 0xfa, 0x4f, 0x2f, 0x59, 0x30, 0x22, 0xe7, 0xab, 0x19,
- 0x56, 0x6b, 0xe2, 0x80, 0x07, 0xfc, 0xf3, 0x16, 0x75, 0x80, 0x39, 0x51,
- 0x7b, 0xe5, 0xf9, 0x35, 0xb6, 0x74, 0x4e, 0xa9, 0x8d, 0x82, 0x13, 0xe4,
- 0xb6, 0x3f, 0xa9, 0x03, 0x83, 0xfa, 0xa2, 0xbe, 0x8a, 0x15, 0x6a, 0x7f,
- 0xde, 0x0b, 0xc3, 0xb6, 0x19, 0x14, 0x05, 0xca, 0xea, 0xc3, 0xa8, 0x04,
- 0x94, 0x3b, 0x46, 0x7c, 0x32, 0x0d, 0xf3, 0x00, 0x66, 0x22, 0xc8, 0x8d,
- 0x69, 0x6d, 0x36, 0x8c, 0x11, 0x18, 0xb7, 0xd3, 0xb2, 0x1c, 0x60, 0xb4,
- 0x38, 0xfa, 0x02, 0x8c, 0xce, 0xd3, 0xdd, 0x46, 0x07, 0xde, 0x0a, 0x3e,
- 0xeb, 0x5d, 0x7c, 0xc8, 0x7c, 0xfb, 0xb0, 0x2b, 0x53, 0xa4, 0x92, 0x62,
- 0x69, 0x51, 0x25, 0x05, 0x61, 0x1a, 0x44, 0x81, 0x8c, 0x2c, 0xa9, 0x43,
- 0x96, 0x23, 0xdf, 0xac, 0x3a, 0x81, 0x9a, 0x0e, 0x29, 0xc5, 0x1c, 0xa9,
- 0xe9, 0x5d, 0x1e, 0xb6, 0x9e, 0x9e, 0x30, 0x0a, 0x39, 0xce, 0xf1, 0x88,
- 0x80, 0xfb, 0x4b, 0x5d, 0xcc, 0x32, 0xec, 0x85, 0x62, 0x43, 0x25, 0x34,
- 0x02, 0x56, 0x27, 0x01, 0x91, 0xb4, 0x3b, 0x70, 0x2a, 0x3f, 0x6e, 0xb1,
- 0xe8, 0x9c, 0x88, 0x01, 0x7d, 0x9f, 0xd4, 0xf9, 0xdb, 0x53, 0x6d, 0x60,
- 0x9d, 0xbf, 0x2c, 0xe7, 0x58, 0xab, 0xb8, 0x5f, 0x46, 0xfc, 0xce, 0xc4,
- 0x1b, 0x03, 0x3c, 0x09, 0xeb, 0x49, 0x31, 0x5c, 0x69, 0x46, 0xb3, 0xe0,
- 0x47, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x17, 0x30, 0x82,
- 0x01, 0x13, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff,
- 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0e, 0x06, 0x03, 0x55,
- 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30,
- 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x3a, 0x9a,
- 0x85, 0x07, 0x10, 0x67, 0x28, 0xb6, 0xef, 0xf6, 0xbd, 0x05, 0x41, 0x6e,
- 0x20, 0xc1, 0x94, 0xda, 0x0f, 0xde, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d,
- 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0xd2, 0xc4, 0xb0, 0xd2, 0x91,
- 0xd4, 0x4c, 0x11, 0x71, 0xb3, 0x61, 0xcb, 0x3d, 0xa1, 0xfe, 0xdd, 0xa8,
- 0x6a, 0xd4, 0xe3, 0x30, 0x34, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05,
- 0x07, 0x01, 0x01, 0x04, 0x28, 0x30, 0x26, 0x30, 0x24, 0x06, 0x08, 0x2b,
- 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x18, 0x68, 0x74, 0x74,
- 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x67, 0x6f, 0x64,
- 0x61, 0x64, 0x64, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x30, 0x32, 0x06,
- 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x2b, 0x30, 0x29, 0x30, 0x27, 0xa0, 0x25,
- 0xa0, 0x23, 0x86, 0x21, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63,
- 0x72, 0x6c, 0x2e, 0x67, 0x6f, 0x64, 0x61, 0x64, 0x64, 0x79, 0x2e, 0x63,
- 0x6f, 0x6d, 0x2f, 0x67, 0x64, 0x72, 0x6f, 0x6f, 0x74, 0x2e, 0x63, 0x72,
- 0x6c, 0x30, 0x46, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x3f, 0x30, 0x3d,
- 0x30, 0x3b, 0x06, 0x04, 0x55, 0x1d, 0x20, 0x00, 0x30, 0x33, 0x30, 0x31,
- 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x25,
- 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x63, 0x65, 0x72, 0x74,
- 0x73, 0x2e, 0x67, 0x6f, 0x64, 0x61, 0x64, 0x64, 0x79, 0x2e, 0x63, 0x6f,
- 0x6d, 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79,
- 0x2f, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
- 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x59, 0x0b, 0x53,
- 0xbd, 0x92, 0x86, 0x11, 0xa7, 0x24, 0x7b, 0xed, 0x5b, 0x31, 0xcf, 0x1d,
- 0x1f, 0x6c, 0x70, 0xc5, 0xb8, 0x6e, 0xbe, 0x4e, 0xbb, 0xf6, 0xbe, 0x97,
- 0x50, 0xe1, 0x30, 0x7f, 0xba, 0x28, 0x5c, 0x62, 0x94, 0xc2, 0xe3, 0x7e,
- 0x33, 0xf7, 0xfb, 0x42, 0x76, 0x85, 0xdb, 0x95, 0x1c, 0x8c, 0x22, 0x58,
- 0x75, 0x09, 0x0c, 0x88, 0x65, 0x67, 0x39, 0x0a, 0x16, 0x09, 0xc5, 0xa0,
- 0x38, 0x97, 0xa4, 0xc5, 0x23, 0x93, 0x3f, 0xb4, 0x18, 0xa6, 0x01, 0x06,
- 0x44, 0x91, 0xe3, 0xa7, 0x69, 0x27, 0xb4, 0x5a, 0x25, 0x7f, 0x3a, 0xb7,
- 0x32, 0xcd, 0xdd, 0x84, 0xff, 0x2a, 0x38, 0x29, 0x33, 0xa4, 0xdd, 0x67,
- 0xb2, 0x85, 0xfe, 0xa1, 0x88, 0x20, 0x1c, 0x50, 0x89, 0xc8, 0xdc, 0x2a,
- 0xf6, 0x42, 0x03, 0x37, 0x4c, 0xe6, 0x88, 0xdf, 0xd5, 0xaf, 0x24, 0xf2,
- 0xb1, 0xc3, 0xdf, 0xcc, 0xb5, 0xec, 0xe0, 0x99, 0x5e, 0xb7, 0x49, 0x54,
- 0x20, 0x3c, 0x94, 0x18, 0x0c, 0xc7, 0x1c, 0x52, 0x18, 0x49, 0xa4, 0x6d,
- 0xe1, 0xb3, 0x58, 0x0b, 0xc9, 0xd8, 0xec, 0xd9, 0xae, 0x1c, 0x32, 0x8e,
- 0x28, 0x70, 0x0d, 0xe2, 0xfe, 0xa6, 0x17, 0x9e, 0x84, 0x0f, 0xbd, 0x57,
- 0x70, 0xb3, 0x5a, 0xe9, 0x1f, 0xa0, 0x86, 0x53, 0xbb, 0xef, 0x7c, 0xff,
- 0x69, 0x0b, 0xe0, 0x48, 0xc3, 0xb7, 0x93, 0x0b, 0xc8, 0x0a, 0x54, 0xc4,
- 0xac, 0x5d, 0x14, 0x67, 0x37, 0x6c, 0xca, 0xa5, 0x2f, 0x31, 0x08, 0x37,
- 0xaa, 0x6e, 0x6f, 0x8c, 0xbc, 0x9b, 0xe2, 0x57, 0x5d, 0x24, 0x81, 0xaf,
- 0x97, 0x97, 0x9c, 0x84, 0xad, 0x6c, 0xac, 0x37, 0x4c, 0x66, 0xf3, 0x61,
- 0x91, 0x11, 0x20, 0xe4, 0xbe, 0x30, 0x9f, 0x7a, 0xa4, 0x29, 0x09, 0xb0,
- 0xe1, 0x34, 0x5f, 0x64, 0x77, 0x18, 0x40, 0x51, 0xdf, 0x8c, 0x30, 0xa6,
- 0xaf,
-};
-
-#if 0
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number:
- 06:9e:1d:b7:7f:cf:1d:fb:a9:7a:f5:e5:c9:a2:40:37
- Signature Algorithm: sha1WithRSAEncryption
- Issuer: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert Global Root CA
- Validity
- Not Before: Mar 8 12:00:00 2013 GMT
- Not After : Mar 8 12:00:00 2023 GMT
- Subject: C=US, O=DigiCert Inc, CN=DigiCert Secure Server CA
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:bb:57:e4:21:a9:d5:9b:60:37:7e:8e:a1:61:7f:
- 81:e2:1a:c2:75:64:d9:91:50:0b:e4:36:44:24:6e:
- 30:d2:9b:7a:27:fa:c2:6a:ae:6a:70:09:38:b9:20:
- 0a:c8:65:10:4a:88:ac:31:f2:dc:92:f2:63:a1:5d:
- 80:63:59:80:92:23:1c:e6:ef:76:4a:50:35:c9:d8:
- 71:38:b9:ed:f0:e6:42:ae:d3:38:26:79:30:f9:22:
- 94:c6:db:a6:3f:41:78:90:d8:de:5c:7e:69:7d:f8:
- 90:15:3a:d0:a1:a0:be:fa:b2:b2:19:a1:d8:2b:d1:
- ce:bf:6b:dd:49:ab:a3:92:fe:b5:ab:c8:c1:3e:ee:
- 01:00:d8:a9:44:b8:42:73:88:c3:61:f5:ab:4a:83:
- 28:0a:d2:d4:49:fa:6a:b1:cd:df:57:2c:94:e5:e2:
- ca:83:5f:b7:ba:62:5c:2f:68:a5:f0:c0:b9:fd:2b:
- d1:e9:1f:d8:1a:62:15:bd:ff:3d:a6:f7:cb:ef:e6:
- db:65:2f:25:38:ec:fb:e6:20:66:58:96:34:19:d2:
- 15:ce:21:d3:24:cc:d9:14:6f:d8:fe:55:c7:e7:6f:
- b6:0f:1a:8c:49:be:29:f2:ba:5a:9a:81:26:37:24:
- 6f:d7:48:12:6c:2e:59:f5:9c:18:bb:d9:f6:68:e2:
- df:45
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Basic Constraints: critical
- CA:TRUE, pathlen:0
- X509v3 Key Usage: critical
- Digital Signature, Certificate Sign, CRL Sign
- Authority Information Access:
- OCSP - URI:http://ocsp.digicert.com
-
- X509v3 CRL Distribution Points:
-
- Full Name:
- URI:http://crl3.digicert.com/DigiCertGlobalRootCA.crl
-
- Full Name:
- URI:http://crl4.digicert.com/DigiCertGlobalRootCA.crl
-
- X509v3 Certificate Policies:
- Policy: X509v3 Any Policy
- CPS: https://www.digicert.com/CPS
-
- X509v3 Subject Key Identifier:
- 90:71:DB:37:EB:73:C8:EF:DC:D5:1E:12:B6:34:BA:2B:5A:A0:A6:92
- X509v3 Authority Key Identifier:
- keyid:03:DE:50:35:56:D1:4C:BB:66:F0:A3:E2:1B:1B:C3:97:B2:3D:D1:55
-
- Signature Algorithm: sha1WithRSAEncryption
- 30:ce:d1:95:51:00:ae:06:0b:a1:0e:02:c0:17:ac:b6:7f:8f:
- 20:f6:40:75:74:1c:cc:78:b1:a4:4f:ea:f4:d0:c4:9d:a2:de:
- 81:07:26:1f:40:88:51:f0:1f:cf:b7:4c:40:99:d0:f4:3c:71:
- 98:73:88:97:2c:19:d7:6e:84:8f:a4:1f:9c:5a:20:e3:51:5c:
- b0:c5:9e:99:6a:4f:c8:69:f7:10:ff:4e:ad:19:d9:c9:58:b3:
- 33:ae:0c:d9:96:29:9e:71:b2:70:63:a3:b6:99:16:42:1d:65:
- f3:f7:a0:1e:7d:c5:d4:65:14:b2:62:84:d4:6c:5c:08:0c:d8:
- 6c:93:2b:b4:76:59:8a:d1:7f:ff:03:d8:c2:5d:b8:2f:22:d6:
- 38:f0:f6:9c:6b:7d:46:eb:99:74:f7:eb:4a:0e:a9:a6:04:eb:
- 7b:ce:f0:5c:6b:98:31:5a:98:40:eb:69:c4:05:f4:20:a8:ca:
- 08:3a:65:6c:38:15:f5:5c:2c:b2:55:e4:2c:6b:41:f0:be:5c:
- 46:ca:4a:29:a0:48:5e:20:d2:45:ff:05:de:34:af:70:4b:81:
- 39:e2:ca:07:57:7c:b6:31:dc:21:29:e2:be:97:0e:77:90:14:
- 51:40:e1:bf:e3:cc:1b:19:9c:25:ca:a7:06:b2:53:df:23:b2:
- cf:12:19:a3
------BEGIN CERTIFICATE-----
-MIIEjzCCA3egAwIBAgIQBp4dt3/PHfupevXlyaJANzANBgkqhkiG9w0BAQUFADBh
-MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
-d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD
-QTAeFw0xMzAzMDgxMjAwMDBaFw0yMzAzMDgxMjAwMDBaMEgxCzAJBgNVBAYTAlVT
-MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxIjAgBgNVBAMTGURpZ2lDZXJ0IFNlY3Vy
-ZSBTZXJ2ZXIgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC7V+Qh
-qdWbYDd+jqFhf4HiGsJ1ZNmRUAvkNkQkbjDSm3on+sJqrmpwCTi5IArIZRBKiKwx
-8tyS8mOhXYBjWYCSIxzm73ZKUDXJ2HE4ue3w5kKu0zgmeTD5IpTG26Y/QXiQ2N5c
-fml9+JAVOtChoL76srIZodgr0c6/a91Jq6OS/rWryME+7gEA2KlEuEJziMNh9atK
-gygK0tRJ+mqxzd9XLJTl4sqDX7e6YlwvaKXwwLn9K9HpH9gaYhW9/z2m98vv5ttl
-LyU47PvmIGZYljQZ0hXOIdMkzNkUb9j+Vcfnb7YPGoxJvinyulqagSY3JG/XSBJs
-Lln1nBi72fZo4t9FAgMBAAGjggFaMIIBVjASBgNVHRMBAf8ECDAGAQH/AgEAMA4G
-A1UdDwEB/wQEAwIBhjA0BggrBgEFBQcBAQQoMCYwJAYIKwYBBQUHMAGGGGh0dHA6
-Ly9vY3NwLmRpZ2ljZXJ0LmNvbTB7BgNVHR8EdDByMDegNaAzhjFodHRwOi8vY3Js
-My5kaWdpY2VydC5jb20vRGlnaUNlcnRHbG9iYWxSb290Q0EuY3JsMDegNaAzhjFo
-dHRwOi8vY3JsNC5kaWdpY2VydC5jb20vRGlnaUNlcnRHbG9iYWxSb290Q0EuY3Js
-MD0GA1UdIAQ2MDQwMgYEVR0gADAqMCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy5k
-aWdpY2VydC5jb20vQ1BTMB0GA1UdDgQWBBSQcds363PI79zVHhK2NLorWqCmkjAf
-BgNVHSMEGDAWgBQD3lA1VtFMu2bwo+IbG8OXsj3RVTANBgkqhkiG9w0BAQUFAAOC
-AQEAMM7RlVEArgYLoQ4CwBestn+PIPZAdXQczHixpE/q9NDEnaLegQcmH0CIUfAf
-z7dMQJnQ9DxxmHOIlywZ126Ej6QfnFog41FcsMWemWpPyGn3EP9OrRnZyVizM64M
-2ZYpnnGycGOjtpkWQh1l8/egHn3F1GUUsmKE1GxcCAzYbJMrtHZZitF//wPYwl24
-LyLWOPD2nGt9RuuZdPfrSg6ppgTre87wXGuYMVqYQOtpxAX0IKjKCDplbDgV9Vws
-slXkLGtB8L5cRspKKaBIXiDSRf8F3jSvcEuBOeLKB1d8tjHcISnivpcOd5AUUUDh
-v+PMGxmcJcqnBrJT3yOyzxIZow==
------END CERTIFICATE-----
-#endif
-static const unsigned char kDERCert19[] = {
- 0x30, 0x82, 0x04, 0x8f, 0x30, 0x82, 0x03, 0x77, 0xa0, 0x03, 0x02, 0x01,
- 0x02, 0x02, 0x10, 0x06, 0x9e, 0x1d, 0xb7, 0x7f, 0xcf, 0x1d, 0xfb, 0xa9,
- 0x7a, 0xf5, 0xe5, 0xc9, 0xa2, 0x40, 0x37, 0x30, 0x0d, 0x06, 0x09, 0x2a,
- 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x61,
- 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55,
- 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0c,
- 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, 0x6e, 0x63,
- 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x10, 0x77,
- 0x77, 0x77, 0x2e, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, 0x74, 0x2e,
- 0x63, 0x6f, 0x6d, 0x31, 0x20, 0x30, 0x1e, 0x06, 0x03, 0x55, 0x04, 0x03,
- 0x13, 0x17, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x47,
- 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43,
- 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x33, 0x30, 0x33, 0x30, 0x38, 0x31,
- 0x32, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x33, 0x30, 0x33,
- 0x30, 0x38, 0x31, 0x32, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x48, 0x31,
- 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53,
- 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0c, 0x44,
- 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, 0x6e, 0x63, 0x31,
- 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x19, 0x44, 0x69,
- 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72,
- 0x65, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x43, 0x41, 0x30,
- 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
- 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30,
- 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xbb, 0x57, 0xe4, 0x21,
- 0xa9, 0xd5, 0x9b, 0x60, 0x37, 0x7e, 0x8e, 0xa1, 0x61, 0x7f, 0x81, 0xe2,
- 0x1a, 0xc2, 0x75, 0x64, 0xd9, 0x91, 0x50, 0x0b, 0xe4, 0x36, 0x44, 0x24,
- 0x6e, 0x30, 0xd2, 0x9b, 0x7a, 0x27, 0xfa, 0xc2, 0x6a, 0xae, 0x6a, 0x70,
- 0x09, 0x38, 0xb9, 0x20, 0x0a, 0xc8, 0x65, 0x10, 0x4a, 0x88, 0xac, 0x31,
- 0xf2, 0xdc, 0x92, 0xf2, 0x63, 0xa1, 0x5d, 0x80, 0x63, 0x59, 0x80, 0x92,
- 0x23, 0x1c, 0xe6, 0xef, 0x76, 0x4a, 0x50, 0x35, 0xc9, 0xd8, 0x71, 0x38,
- 0xb9, 0xed, 0xf0, 0xe6, 0x42, 0xae, 0xd3, 0x38, 0x26, 0x79, 0x30, 0xf9,
- 0x22, 0x94, 0xc6, 0xdb, 0xa6, 0x3f, 0x41, 0x78, 0x90, 0xd8, 0xde, 0x5c,
- 0x7e, 0x69, 0x7d, 0xf8, 0x90, 0x15, 0x3a, 0xd0, 0xa1, 0xa0, 0xbe, 0xfa,
- 0xb2, 0xb2, 0x19, 0xa1, 0xd8, 0x2b, 0xd1, 0xce, 0xbf, 0x6b, 0xdd, 0x49,
- 0xab, 0xa3, 0x92, 0xfe, 0xb5, 0xab, 0xc8, 0xc1, 0x3e, 0xee, 0x01, 0x00,
- 0xd8, 0xa9, 0x44, 0xb8, 0x42, 0x73, 0x88, 0xc3, 0x61, 0xf5, 0xab, 0x4a,
- 0x83, 0x28, 0x0a, 0xd2, 0xd4, 0x49, 0xfa, 0x6a, 0xb1, 0xcd, 0xdf, 0x57,
- 0x2c, 0x94, 0xe5, 0xe2, 0xca, 0x83, 0x5f, 0xb7, 0xba, 0x62, 0x5c, 0x2f,
- 0x68, 0xa5, 0xf0, 0xc0, 0xb9, 0xfd, 0x2b, 0xd1, 0xe9, 0x1f, 0xd8, 0x1a,
- 0x62, 0x15, 0xbd, 0xff, 0x3d, 0xa6, 0xf7, 0xcb, 0xef, 0xe6, 0xdb, 0x65,
- 0x2f, 0x25, 0x38, 0xec, 0xfb, 0xe6, 0x20, 0x66, 0x58, 0x96, 0x34, 0x19,
- 0xd2, 0x15, 0xce, 0x21, 0xd3, 0x24, 0xcc, 0xd9, 0x14, 0x6f, 0xd8, 0xfe,
- 0x55, 0xc7, 0xe7, 0x6f, 0xb6, 0x0f, 0x1a, 0x8c, 0x49, 0xbe, 0x29, 0xf2,
- 0xba, 0x5a, 0x9a, 0x81, 0x26, 0x37, 0x24, 0x6f, 0xd7, 0x48, 0x12, 0x6c,
- 0x2e, 0x59, 0xf5, 0x9c, 0x18, 0xbb, 0xd9, 0xf6, 0x68, 0xe2, 0xdf, 0x45,
- 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x5a, 0x30, 0x82, 0x01,
- 0x56, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04,
- 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x00, 0x30, 0x0e, 0x06,
- 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01,
- 0x86, 0x30, 0x34, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01,
- 0x01, 0x04, 0x28, 0x30, 0x26, 0x30, 0x24, 0x06, 0x08, 0x2b, 0x06, 0x01,
- 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x18, 0x68, 0x74, 0x74, 0x70, 0x3a,
- 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x64, 0x69, 0x67, 0x69, 0x63,
- 0x65, 0x72, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x7b, 0x06, 0x03, 0x55,
- 0x1d, 0x1f, 0x04, 0x74, 0x30, 0x72, 0x30, 0x37, 0xa0, 0x35, 0xa0, 0x33,
- 0x86, 0x31, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c,
- 0x33, 0x2e, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, 0x74, 0x2e, 0x63,
- 0x6f, 0x6d, 0x2f, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x47,
- 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x52, 0x6f, 0x6f, 0x74, 0x43, 0x41, 0x2e,
- 0x63, 0x72, 0x6c, 0x30, 0x37, 0xa0, 0x35, 0xa0, 0x33, 0x86, 0x31, 0x68,
- 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x34, 0x2e, 0x64,
- 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f,
- 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x47, 0x6c, 0x6f, 0x62,
- 0x61, 0x6c, 0x52, 0x6f, 0x6f, 0x74, 0x43, 0x41, 0x2e, 0x63, 0x72, 0x6c,
- 0x30, 0x3d, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x36, 0x30, 0x34, 0x30,
- 0x32, 0x06, 0x04, 0x55, 0x1d, 0x20, 0x00, 0x30, 0x2a, 0x30, 0x28, 0x06,
- 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x1c, 0x68,
- 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x64,
- 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f,
- 0x43, 0x50, 0x53, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16,
- 0x04, 0x14, 0x90, 0x71, 0xdb, 0x37, 0xeb, 0x73, 0xc8, 0xef, 0xdc, 0xd5,
- 0x1e, 0x12, 0xb6, 0x34, 0xba, 0x2b, 0x5a, 0xa0, 0xa6, 0x92, 0x30, 0x1f,
- 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x03,
- 0xde, 0x50, 0x35, 0x56, 0xd1, 0x4c, 0xbb, 0x66, 0xf0, 0xa3, 0xe2, 0x1b,
- 0x1b, 0xc3, 0x97, 0xb2, 0x3d, 0xd1, 0x55, 0x30, 0x0d, 0x06, 0x09, 0x2a,
- 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x82,
- 0x01, 0x01, 0x00, 0x30, 0xce, 0xd1, 0x95, 0x51, 0x00, 0xae, 0x06, 0x0b,
- 0xa1, 0x0e, 0x02, 0xc0, 0x17, 0xac, 0xb6, 0x7f, 0x8f, 0x20, 0xf6, 0x40,
- 0x75, 0x74, 0x1c, 0xcc, 0x78, 0xb1, 0xa4, 0x4f, 0xea, 0xf4, 0xd0, 0xc4,
- 0x9d, 0xa2, 0xde, 0x81, 0x07, 0x26, 0x1f, 0x40, 0x88, 0x51, 0xf0, 0x1f,
- 0xcf, 0xb7, 0x4c, 0x40, 0x99, 0xd0, 0xf4, 0x3c, 0x71, 0x98, 0x73, 0x88,
- 0x97, 0x2c, 0x19, 0xd7, 0x6e, 0x84, 0x8f, 0xa4, 0x1f, 0x9c, 0x5a, 0x20,
- 0xe3, 0x51, 0x5c, 0xb0, 0xc5, 0x9e, 0x99, 0x6a, 0x4f, 0xc8, 0x69, 0xf7,
- 0x10, 0xff, 0x4e, 0xad, 0x19, 0xd9, 0xc9, 0x58, 0xb3, 0x33, 0xae, 0x0c,
- 0xd9, 0x96, 0x29, 0x9e, 0x71, 0xb2, 0x70, 0x63, 0xa3, 0xb6, 0x99, 0x16,
- 0x42, 0x1d, 0x65, 0xf3, 0xf7, 0xa0, 0x1e, 0x7d, 0xc5, 0xd4, 0x65, 0x14,
- 0xb2, 0x62, 0x84, 0xd4, 0x6c, 0x5c, 0x08, 0x0c, 0xd8, 0x6c, 0x93, 0x2b,
- 0xb4, 0x76, 0x59, 0x8a, 0xd1, 0x7f, 0xff, 0x03, 0xd8, 0xc2, 0x5d, 0xb8,
- 0x2f, 0x22, 0xd6, 0x38, 0xf0, 0xf6, 0x9c, 0x6b, 0x7d, 0x46, 0xeb, 0x99,
- 0x74, 0xf7, 0xeb, 0x4a, 0x0e, 0xa9, 0xa6, 0x04, 0xeb, 0x7b, 0xce, 0xf0,
- 0x5c, 0x6b, 0x98, 0x31, 0x5a, 0x98, 0x40, 0xeb, 0x69, 0xc4, 0x05, 0xf4,
- 0x20, 0xa8, 0xca, 0x08, 0x3a, 0x65, 0x6c, 0x38, 0x15, 0xf5, 0x5c, 0x2c,
- 0xb2, 0x55, 0xe4, 0x2c, 0x6b, 0x41, 0xf0, 0xbe, 0x5c, 0x46, 0xca, 0x4a,
- 0x29, 0xa0, 0x48, 0x5e, 0x20, 0xd2, 0x45, 0xff, 0x05, 0xde, 0x34, 0xaf,
- 0x70, 0x4b, 0x81, 0x39, 0xe2, 0xca, 0x07, 0x57, 0x7c, 0xb6, 0x31, 0xdc,
- 0x21, 0x29, 0xe2, 0xbe, 0x97, 0x0e, 0x77, 0x90, 0x14, 0x51, 0x40, 0xe1,
- 0xbf, 0xe3, 0xcc, 0x1b, 0x19, 0x9c, 0x25, 0xca, 0xa7, 0x06, 0xb2, 0x53,
- 0xdf, 0x23, 0xb2, 0xcf, 0x12, 0x19, 0xa3,
-};
-
-#if 0
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number:
- 1b:09:3b:78:60:96:da:37:bb:a4:51:94:46:c8:96:78
- Signature Algorithm: sha1WithRSAEncryption
- Issuer: C=US, O=VeriSign, Inc., OU=Class 3 Public Primary Certification Authority
- Validity
- Not Before: Nov 8 00:00:00 2006 GMT
- Not After : Nov 7 23:59:59 2021 GMT
- Subject: C=US, O=VeriSign, Inc., OU=VeriSign Trust Network, OU=(c) 2006 VeriSign, Inc. - For authorized use only, CN=VeriSign Class 3 Public Primary Certification Authority - G5
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:af:24:08:08:29:7a:35:9e:60:0c:aa:e7:4b:3b:
- 4e:dc:7c:bc:3c:45:1c:bb:2b:e0:fe:29:02:f9:57:
- 08:a3:64:85:15:27:f5:f1:ad:c8:31:89:5d:22:e8:
- 2a:aa:a6:42:b3:8f:f8:b9:55:b7:b1:b7:4b:b3:fe:
- 8f:7e:07:57:ec:ef:43:db:66:62:15:61:cf:60:0d:
- a4:d8:de:f8:e0:c3:62:08:3d:54:13:eb:49:ca:59:
- 54:85:26:e5:2b:8f:1b:9f:eb:f5:a1:91:c2:33:49:
- d8:43:63:6a:52:4b:d2:8f:e8:70:51:4d:d1:89:69:
- 7b:c7:70:f6:b3:dc:12:74:db:7b:5d:4b:56:d3:96:
- bf:15:77:a1:b0:f4:a2:25:f2:af:1c:92:67:18:e5:
- f4:06:04:ef:90:b9:e4:00:e4:dd:3a:b5:19:ff:02:
- ba:f4:3c:ee:e0:8b:eb:37:8b:ec:f4:d7:ac:f2:f6:
- f0:3d:af:dd:75:91:33:19:1d:1c:40:cb:74:24:19:
- 21:93:d9:14:fe:ac:2a:52:c7:8f:d5:04:49:e4:8d:
- 63:47:88:3c:69:83:cb:fe:47:bd:2b:7e:4f:c5:95:
- ae:0e:9d:d4:d1:43:c0:67:73:e3:14:08:7e:e5:3f:
- 9f:73:b8:33:0a:cf:5d:3f:34:87:96:8a:ee:53:e8:
- 25:15
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Basic Constraints: critical
- CA:TRUE
- X509v3 CRL Distribution Points:
-
- Full Name:
- URI:http://crl.verisign.com/pca3.crl
-
- X509v3 Key Usage: critical
- Certificate Sign, CRL Sign
- X509v3 Certificate Policies:
- Policy: X509v3 Any Policy
- CPS: https://www.verisign.com/cps
-
- X509v3 Subject Key Identifier:
- 7F:D3:65:A7:C2:DD:EC:BB:F0:30:09:F3:43:39:FA:02:AF:33:31:33
- 1.3.6.1.5.5.7.1.12:
- 0_.].[0Y0W0U..image/gif0!0.0...+..............k...j.H.,{..0%.#http://logo.verisign.com/vslogo.gif
- Authority Information Access:
- OCSP - URI:http://ocsp.verisign.com
-
- Signature Algorithm: sha1WithRSAEncryption
- a3:cd:7d:1e:f7:c7:75:8d:48:e7:56:34:4c:00:90:75:a9:51:
- a5:56:c1:6d:bc:fe:f5:53:22:e9:98:a2:ac:9a:7e:70:1e:b3:
- 8e:3b:45:e3:86:95:31:da:6d:4c:fb:34:50:80:96:cd:24:f2:
- 40:df:04:3f:e2:65:ce:34:22:61:15:ea:66:70:64:d2:f1:6e:
- f3:ca:18:59:6a:41:46:7e:82:de:19:b0:70:31:56:69:0d:0c:
- e6:1d:9d:71:58:dc:cc:de:62:f5:e1:7a:10:02:d8:7a:dc:3b:
- fa:57:bd:c9:e9:8f:46:21:39:9f:51:65:4c:8e:3a:be:28:41:
- 70:1d
------BEGIN CERTIFICATE-----
-MIIEkDCCA/mgAwIBAgIQGwk7eGCW2je7pFGURsiWeDANBgkqhkiG9w0BAQUFADBf
-MQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xNzA1BgNVBAsT
-LkNsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkw
-HhcNMDYxMTA4MDAwMDAwWhcNMjExMTA3MjM1OTU5WjCByjELMAkGA1UEBhMCVVMx
-FzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBUcnVz
-dCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJpU2lnbiwgSW5jLiAtIEZv
-ciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAz
-IFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzUwggEi
-MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvJAgIKXo1nmAMqudLO07cfLw8
-RRy7K+D+KQL5VwijZIUVJ/XxrcgxiV0i6CqqpkKzj/i5Vbext0uz/o9+B1fs70Pb
-ZmIVYc9gDaTY3vjgw2IIPVQT60nKWVSFJuUrjxuf6/WhkcIzSdhDY2pSS9KP6HBR
-TdGJaXvHcPaz3BJ023tdS1bTlr8Vd6Gw9KIl8q8ckmcY5fQGBO+QueQA5N06tRn/
-Arr0PO7gi+s3i+z016zy9vA9r911kTMZHRxAy3QkGSGT2RT+rCpSx4/VBEnkjWNH
-iDxpg8v+R70rfk/Fla4OndTRQ8Bnc+MUCH7lP59zuDMKz10/NIeWiu5T6CUVAgMB
-AAGjggFbMIIBVzAPBgNVHRMBAf8EBTADAQH/MDEGA1UdHwQqMCgwJqAkoCKGIGh0
-dHA6Ly9jcmwudmVyaXNpZ24uY29tL3BjYTMuY3JsMA4GA1UdDwEB/wQEAwIBBjA9
-BgNVHSAENjA0MDIGBFUdIAAwKjAoBggrBgEFBQcCARYcaHR0cHM6Ly93d3cudmVy
-aXNpZ24uY29tL2NwczAdBgNVHQ4EFgQUf9Nlp8Ld7LvwMAnzQzn6Aq8zMTMwbQYI
-KwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2UvZ2lmMCEwHzAHBgUrDgMCGgQU
-j+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDovL2xvZ28udmVyaXNpZ24uY29t
-L3ZzbG9nby5naWYwNAYIKwYBBQUHAQEEKDAmMCQGCCsGAQUFBzABhhhodHRwOi8v
-b2NzcC52ZXJpc2lnbi5jb20wDQYJKoZIhvcNAQEFBQADgYEAo819HvfHdY1I51Y0
-TACQdalRpVbBbbz+9VMi6ZiirJp+cB6zjjtF44aVMdptTPs0UICWzSTyQN8EP+Jl
-zjQiYRXqZnBk0vFu88oYWWpBRn6C3hmwcDFWaQ0M5h2dcVjczN5i9eF6EALYetw7
-+le9yemPRiE5n1FlTI46vihBcB0=
------END CERTIFICATE-----
-#endif
-static const unsigned char kDERCert20[] = {
- 0x30, 0x82, 0x04, 0x90, 0x30, 0x82, 0x03, 0xf9, 0xa0, 0x03, 0x02, 0x01,
- 0x02, 0x02, 0x10, 0x1b, 0x09, 0x3b, 0x78, 0x60, 0x96, 0xda, 0x37, 0xbb,
- 0xa4, 0x51, 0x94, 0x46, 0xc8, 0x96, 0x78, 0x30, 0x0d, 0x06, 0x09, 0x2a,
- 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x5f,
- 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55,
- 0x53, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0e,
- 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e,
- 0x63, 0x2e, 0x31, 0x37, 0x30, 0x35, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13,
- 0x2e, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x33, 0x20, 0x50, 0x75, 0x62,
- 0x6c, 0x69, 0x63, 0x20, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x20,
- 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f,
- 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x30,
- 0x1e, 0x17, 0x0d, 0x30, 0x36, 0x31, 0x31, 0x30, 0x38, 0x30, 0x30, 0x30,
- 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x31, 0x31, 0x31, 0x30, 0x37,
- 0x32, 0x33, 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x81, 0xca, 0x31, 0x0b,
- 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31,
- 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0e, 0x56, 0x65,
- 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e,
- 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x16, 0x56,
- 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x54, 0x72, 0x75, 0x73,
- 0x74, 0x20, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x31, 0x3a, 0x30,
- 0x38, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x31, 0x28, 0x63, 0x29, 0x20,
- 0x32, 0x30, 0x30, 0x36, 0x20, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67,
- 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x20, 0x2d, 0x20, 0x46, 0x6f,
- 0x72, 0x20, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64,
- 0x20, 0x75, 0x73, 0x65, 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x31, 0x45, 0x30,
- 0x43, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x3c, 0x56, 0x65, 0x72, 0x69,
- 0x53, 0x69, 0x67, 0x6e, 0x20, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x33,
- 0x20, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x20, 0x50, 0x72, 0x69, 0x6d,
- 0x61, 0x72, 0x79, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63,
- 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72,
- 0x69, 0x74, 0x79, 0x20, 0x2d, 0x20, 0x47, 0x35, 0x30, 0x82, 0x01, 0x22,
- 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
- 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a,
- 0x02, 0x82, 0x01, 0x01, 0x00, 0xaf, 0x24, 0x08, 0x08, 0x29, 0x7a, 0x35,
- 0x9e, 0x60, 0x0c, 0xaa, 0xe7, 0x4b, 0x3b, 0x4e, 0xdc, 0x7c, 0xbc, 0x3c,
- 0x45, 0x1c, 0xbb, 0x2b, 0xe0, 0xfe, 0x29, 0x02, 0xf9, 0x57, 0x08, 0xa3,
- 0x64, 0x85, 0x15, 0x27, 0xf5, 0xf1, 0xad, 0xc8, 0x31, 0x89, 0x5d, 0x22,
- 0xe8, 0x2a, 0xaa, 0xa6, 0x42, 0xb3, 0x8f, 0xf8, 0xb9, 0x55, 0xb7, 0xb1,
- 0xb7, 0x4b, 0xb3, 0xfe, 0x8f, 0x7e, 0x07, 0x57, 0xec, 0xef, 0x43, 0xdb,
- 0x66, 0x62, 0x15, 0x61, 0xcf, 0x60, 0x0d, 0xa4, 0xd8, 0xde, 0xf8, 0xe0,
- 0xc3, 0x62, 0x08, 0x3d, 0x54, 0x13, 0xeb, 0x49, 0xca, 0x59, 0x54, 0x85,
- 0x26, 0xe5, 0x2b, 0x8f, 0x1b, 0x9f, 0xeb, 0xf5, 0xa1, 0x91, 0xc2, 0x33,
- 0x49, 0xd8, 0x43, 0x63, 0x6a, 0x52, 0x4b, 0xd2, 0x8f, 0xe8, 0x70, 0x51,
- 0x4d, 0xd1, 0x89, 0x69, 0x7b, 0xc7, 0x70, 0xf6, 0xb3, 0xdc, 0x12, 0x74,
- 0xdb, 0x7b, 0x5d, 0x4b, 0x56, 0xd3, 0x96, 0xbf, 0x15, 0x77, 0xa1, 0xb0,
- 0xf4, 0xa2, 0x25, 0xf2, 0xaf, 0x1c, 0x92, 0x67, 0x18, 0xe5, 0xf4, 0x06,
- 0x04, 0xef, 0x90, 0xb9, 0xe4, 0x00, 0xe4, 0xdd, 0x3a, 0xb5, 0x19, 0xff,
- 0x02, 0xba, 0xf4, 0x3c, 0xee, 0xe0, 0x8b, 0xeb, 0x37, 0x8b, 0xec, 0xf4,
- 0xd7, 0xac, 0xf2, 0xf6, 0xf0, 0x3d, 0xaf, 0xdd, 0x75, 0x91, 0x33, 0x19,
- 0x1d, 0x1c, 0x40, 0xcb, 0x74, 0x24, 0x19, 0x21, 0x93, 0xd9, 0x14, 0xfe,
- 0xac, 0x2a, 0x52, 0xc7, 0x8f, 0xd5, 0x04, 0x49, 0xe4, 0x8d, 0x63, 0x47,
- 0x88, 0x3c, 0x69, 0x83, 0xcb, 0xfe, 0x47, 0xbd, 0x2b, 0x7e, 0x4f, 0xc5,
- 0x95, 0xae, 0x0e, 0x9d, 0xd4, 0xd1, 0x43, 0xc0, 0x67, 0x73, 0xe3, 0x14,
- 0x08, 0x7e, 0xe5, 0x3f, 0x9f, 0x73, 0xb8, 0x33, 0x0a, 0xcf, 0x5d, 0x3f,
- 0x34, 0x87, 0x96, 0x8a, 0xee, 0x53, 0xe8, 0x25, 0x15, 0x02, 0x03, 0x01,
- 0x00, 0x01, 0xa3, 0x82, 0x01, 0x5b, 0x30, 0x82, 0x01, 0x57, 0x30, 0x0f,
- 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, 0x30, 0x03,
- 0x01, 0x01, 0xff, 0x30, 0x31, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x2a,
- 0x30, 0x28, 0x30, 0x26, 0xa0, 0x24, 0xa0, 0x22, 0x86, 0x20, 0x68, 0x74,
- 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x76, 0x65, 0x72,
- 0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x63,
- 0x61, 0x33, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d,
- 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x3d,
- 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x36, 0x30, 0x34, 0x30, 0x32, 0x06,
- 0x04, 0x55, 0x1d, 0x20, 0x00, 0x30, 0x2a, 0x30, 0x28, 0x06, 0x08, 0x2b,
- 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x1c, 0x68, 0x74, 0x74,
- 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x76, 0x65, 0x72,
- 0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x70,
- 0x73, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14,
- 0x7f, 0xd3, 0x65, 0xa7, 0xc2, 0xdd, 0xec, 0xbb, 0xf0, 0x30, 0x09, 0xf3,
- 0x43, 0x39, 0xfa, 0x02, 0xaf, 0x33, 0x31, 0x33, 0x30, 0x6d, 0x06, 0x08,
- 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x0c, 0x04, 0x61, 0x30, 0x5f,
- 0xa1, 0x5d, 0xa0, 0x5b, 0x30, 0x59, 0x30, 0x57, 0x30, 0x55, 0x16, 0x09,
- 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2f, 0x67, 0x69, 0x66, 0x30, 0x21, 0x30,
- 0x1f, 0x30, 0x07, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x04, 0x14,
- 0x8f, 0xe5, 0xd3, 0x1a, 0x86, 0xac, 0x8d, 0x8e, 0x6b, 0xc3, 0xcf, 0x80,
- 0x6a, 0xd4, 0x48, 0x18, 0x2c, 0x7b, 0x19, 0x2e, 0x30, 0x25, 0x16, 0x23,
- 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6c, 0x6f, 0x67, 0x6f, 0x2e,
- 0x76, 0x65, 0x72, 0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d,
- 0x2f, 0x76, 0x73, 0x6c, 0x6f, 0x67, 0x6f, 0x2e, 0x67, 0x69, 0x66, 0x30,
- 0x34, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04,
- 0x28, 0x30, 0x26, 0x30, 0x24, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05,
- 0x07, 0x30, 0x01, 0x86, 0x18, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f,
- 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x76, 0x65, 0x72, 0x69, 0x73, 0x69, 0x67,
- 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48,
- 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x81, 0x81, 0x00,
- 0xa3, 0xcd, 0x7d, 0x1e, 0xf7, 0xc7, 0x75, 0x8d, 0x48, 0xe7, 0x56, 0x34,
- 0x4c, 0x00, 0x90, 0x75, 0xa9, 0x51, 0xa5, 0x56, 0xc1, 0x6d, 0xbc, 0xfe,
- 0xf5, 0x53, 0x22, 0xe9, 0x98, 0xa2, 0xac, 0x9a, 0x7e, 0x70, 0x1e, 0xb3,
- 0x8e, 0x3b, 0x45, 0xe3, 0x86, 0x95, 0x31, 0xda, 0x6d, 0x4c, 0xfb, 0x34,
- 0x50, 0x80, 0x96, 0xcd, 0x24, 0xf2, 0x40, 0xdf, 0x04, 0x3f, 0xe2, 0x65,
- 0xce, 0x34, 0x22, 0x61, 0x15, 0xea, 0x66, 0x70, 0x64, 0xd2, 0xf1, 0x6e,
- 0xf3, 0xca, 0x18, 0x59, 0x6a, 0x41, 0x46, 0x7e, 0x82, 0xde, 0x19, 0xb0,
- 0x70, 0x31, 0x56, 0x69, 0x0d, 0x0c, 0xe6, 0x1d, 0x9d, 0x71, 0x58, 0xdc,
- 0xcc, 0xde, 0x62, 0xf5, 0xe1, 0x7a, 0x10, 0x02, 0xd8, 0x7a, 0xdc, 0x3b,
- 0xfa, 0x57, 0xbd, 0xc9, 0xe9, 0x8f, 0x46, 0x21, 0x39, 0x9f, 0x51, 0x65,
- 0x4c, 0x8e, 0x3a, 0xbe, 0x28, 0x41, 0x70, 0x1d,
-};
-
-#if 0
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number:
- 01:fd:a3:eb:6e:ca:75:c8:88:43:8b:72:4b:cf:bc:91
- Signature Algorithm: sha256WithRSAEncryption
- Issuer: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert Global Root CA
- Validity
- Not Before: Mar 8 12:00:00 2013 GMT
- Not After : Mar 8 12:00:00 2023 GMT
- Subject: C=US, O=DigiCert Inc, CN=DigiCert SHA2 Secure Server CA
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:dc:ae:58:90:4d:c1:c4:30:15:90:35:5b:6e:3c:
- 82:15:f5:2c:5c:bd:e3:db:ff:71:43:fa:64:25:80:
- d4:ee:18:a2:4d:f0:66:d0:0a:73:6e:11:98:36:17:
- 64:af:37:9d:fd:fa:41:84:af:c7:af:8c:fe:1a:73:
- 4d:cf:33:97:90:a2:96:87:53:83:2b:b9:a6:75:48:
- 2d:1d:56:37:7b:da:31:32:1a:d7:ac:ab:06:f4:aa:
- 5d:4b:b7:47:46:dd:2a:93:c3:90:2e:79:80:80:ef:
- 13:04:6a:14:3b:b5:9b:92:be:c2:07:65:4e:fc:da:
- fc:ff:7a:ae:dc:5c:7e:55:31:0c:e8:39:07:a4:d7:
- be:2f:d3:0b:6a:d2:b1:df:5f:fe:57:74:53:3b:35:
- 80:dd:ae:8e:44:98:b3:9f:0e:d3:da:e0:d7:f4:6b:
- 29:ab:44:a7:4b:58:84:6d:92:4b:81:c3:da:73:8b:
- 12:97:48:90:04:45:75:1a:dd:37:31:97:92:e8:cd:
- 54:0d:3b:e4:c1:3f:39:5e:2e:b8:f3:5c:7e:10:8e:
- 86:41:00:8d:45:66:47:b0:a1:65:ce:a0:aa:29:09:
- 4e:f3:97:eb:e8:2e:ab:0f:72:a7:30:0e:fa:c7:f4:
- fd:14:77:c3:a4:5b:28:57:c2:b3:f9:82:fd:b7:45:
- 58:9b
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Basic Constraints: critical
- CA:TRUE, pathlen:0
- X509v3 Key Usage: critical
- Digital Signature, Certificate Sign, CRL Sign
- Authority Information Access:
- OCSP - URI:http://ocsp.digicert.com
-
- X509v3 CRL Distribution Points:
-
- Full Name:
- URI:http://crl3.digicert.com/DigiCertGlobalRootCA.crl
-
- Full Name:
- URI:http://crl4.digicert.com/DigiCertGlobalRootCA.crl
-
- X509v3 Certificate Policies:
- Policy: X509v3 Any Policy
- CPS: https://www.digicert.com/CPS
-
- X509v3 Subject Key Identifier:
- 0F:80:61:1C:82:31:61:D5:2F:28:E7:8D:46:38:B4:2C:E1:C6:D9:E2
- X509v3 Authority Key Identifier:
- keyid:03:DE:50:35:56:D1:4C:BB:66:F0:A3:E2:1B:1B:C3:97:B2:3D:D1:55
-
- Signature Algorithm: sha256WithRSAEncryption
- 23:3e:df:4b:d2:31:42:a5:b6:7e:42:5c:1a:44:cc:69:d1:68:
- b4:5d:4b:e0:04:21:6c:4b:e2:6d:cc:b1:e0:97:8f:a6:53:09:
- cd:aa:2a:65:e5:39:4f:1e:83:a5:6e:5c:98:a2:24:26:e6:fb:
- a1:ed:93:c7:2e:02:c6:4d:4a:bf:b0:42:df:78:da:b3:a8:f9:
- 6d:ff:21:85:53:36:60:4c:76:ce:ec:38:dc:d6:51:80:f0:c5:
- d6:e5:d4:4d:27:64:ab:9b:c7:3e:71:fb:48:97:b8:33:6d:c9:
- 13:07:ee:96:a2:1b:18:15:f6:5c:4c:40:ed:b3:c2:ec:ff:71:
- c1:e3:47:ff:d4:b9:00:b4:37:42:da:20:c9:ea:6e:8a:ee:14:
- 06:ae:7d:a2:59:98:88:a8:1b:6f:2d:f4:f2:c9:14:5f:26:cf:
- 2c:8d:7e:ed:37:c0:a9:d5:39:b9:82:bf:19:0c:ea:34:af:00:
- 21:68:f8:ad:73:e2:c9:32:da:38:25:0b:55:d3:9a:1d:f0:68:
- 86:ed:2e:41:34:ef:7c:a5:50:1d:bf:3a:f9:d3:c1:08:0c:e6:
- ed:1e:8a:58:25:e4:b8:77:ad:2d:6e:f5:52:dd:b4:74:8f:ab:
- 49:2e:9d:3b:93:34:28:1f:78:ce:94:ea:c7:bd:d3:c9:6d:1c:
- de:5c:32:f3
------BEGIN CERTIFICATE-----
-MIIElDCCA3ygAwIBAgIQAf2j627KdciIQ4tyS8+8kTANBgkqhkiG9w0BAQsFADBh
-MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
-d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD
-QTAeFw0xMzAzMDgxMjAwMDBaFw0yMzAzMDgxMjAwMDBaME0xCzAJBgNVBAYTAlVT
-MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxJzAlBgNVBAMTHkRpZ2lDZXJ0IFNIQTIg
-U2VjdXJlIFNlcnZlciBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
-ANyuWJBNwcQwFZA1W248ghX1LFy949v/cUP6ZCWA1O4Yok3wZtAKc24RmDYXZK83
-nf36QYSvx6+M/hpzTc8zl5CilodTgyu5pnVILR1WN3vaMTIa16yrBvSqXUu3R0bd
-KpPDkC55gIDvEwRqFDu1m5K+wgdlTvza/P96rtxcflUxDOg5B6TXvi/TC2rSsd9f
-/ld0Uzs1gN2ujkSYs58O09rg1/RrKatEp0tYhG2SS4HD2nOLEpdIkARFdRrdNzGX
-kujNVA075ME/OV4uuPNcfhCOhkEAjUVmR7ChZc6gqikJTvOX6+guqw9ypzAO+sf0
-/RR3w6RbKFfCs/mC/bdFWJsCAwEAAaOCAVowggFWMBIGA1UdEwEB/wQIMAYBAf8C
-AQAwDgYDVR0PAQH/BAQDAgGGMDQGCCsGAQUFBwEBBCgwJjAkBggrBgEFBQcwAYYY
-aHR0cDovL29jc3AuZGlnaWNlcnQuY29tMHsGA1UdHwR0MHIwN6A1oDOGMWh0dHA6
-Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEdsb2JhbFJvb3RDQS5jcmwwN6A1
-oDOGMWh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEdsb2JhbFJvb3RD
-QS5jcmwwPQYDVR0gBDYwNDAyBgRVHSAAMCowKAYIKwYBBQUHAgEWHGh0dHBzOi8v
-d3d3LmRpZ2ljZXJ0LmNvbS9DUFMwHQYDVR0OBBYEFA+AYRyCMWHVLyjnjUY4tCzh
-xtniMB8GA1UdIwQYMBaAFAPeUDVW0Uy7ZvCj4hsbw5eyPdFVMA0GCSqGSIb3DQEB
-CwUAA4IBAQAjPt9L0jFCpbZ+QlwaRMxp0Wi0XUvgBCFsS+JtzLHgl4+mUwnNqipl
-5TlPHoOlblyYoiQm5vuh7ZPHLgLGTUq/sELfeNqzqPlt/yGFUzZgTHbO7Djc1lGA
-8MXW5dRNJ2Srm8c+cftIl7gzbckTB+6WohsYFfZcTEDts8Ls/3HB40f/1LkAtDdC
-2iDJ6m6K7hQGrn2iWZiIqBtvLfTyyRRfJs8sjX7tN8Cp1Tm5gr8ZDOo0rwAhaPit
-c+LJMto4JQtV05od8GiG7S5BNO98pVAdvzr508EIDObtHopYJeS4d60tbvVS3bR0
-j6tJLp07kzQoH3jOlOrHvdPJbRzeXDLz
------END CERTIFICATE-----
-#endif
-static const unsigned char kDERCert21[] = {
- 0x30, 0x82, 0x04, 0x94, 0x30, 0x82, 0x03, 0x7c, 0xa0, 0x03, 0x02, 0x01,
- 0x02, 0x02, 0x10, 0x01, 0xfd, 0xa3, 0xeb, 0x6e, 0xca, 0x75, 0xc8, 0x88,
- 0x43, 0x8b, 0x72, 0x4b, 0xcf, 0xbc, 0x91, 0x30, 0x0d, 0x06, 0x09, 0x2a,
- 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x61,
- 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55,
- 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0c,
- 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, 0x6e, 0x63,
- 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x10, 0x77,
- 0x77, 0x77, 0x2e, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, 0x74, 0x2e,
- 0x63, 0x6f, 0x6d, 0x31, 0x20, 0x30, 0x1e, 0x06, 0x03, 0x55, 0x04, 0x03,
- 0x13, 0x17, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x47,
- 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43,
- 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x33, 0x30, 0x33, 0x30, 0x38, 0x31,
- 0x32, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x33, 0x30, 0x33,
- 0x30, 0x38, 0x31, 0x32, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x4d, 0x31,
- 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53,
- 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0c, 0x44,
- 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, 0x6e, 0x63, 0x31,
- 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x1e, 0x44, 0x69,
- 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x53, 0x48, 0x41, 0x32, 0x20,
- 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65,
- 0x72, 0x20, 0x43, 0x41, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09,
- 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03,
- 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01,
- 0x00, 0xdc, 0xae, 0x58, 0x90, 0x4d, 0xc1, 0xc4, 0x30, 0x15, 0x90, 0x35,
- 0x5b, 0x6e, 0x3c, 0x82, 0x15, 0xf5, 0x2c, 0x5c, 0xbd, 0xe3, 0xdb, 0xff,
- 0x71, 0x43, 0xfa, 0x64, 0x25, 0x80, 0xd4, 0xee, 0x18, 0xa2, 0x4d, 0xf0,
- 0x66, 0xd0, 0x0a, 0x73, 0x6e, 0x11, 0x98, 0x36, 0x17, 0x64, 0xaf, 0x37,
- 0x9d, 0xfd, 0xfa, 0x41, 0x84, 0xaf, 0xc7, 0xaf, 0x8c, 0xfe, 0x1a, 0x73,
- 0x4d, 0xcf, 0x33, 0x97, 0x90, 0xa2, 0x96, 0x87, 0x53, 0x83, 0x2b, 0xb9,
- 0xa6, 0x75, 0x48, 0x2d, 0x1d, 0x56, 0x37, 0x7b, 0xda, 0x31, 0x32, 0x1a,
- 0xd7, 0xac, 0xab, 0x06, 0xf4, 0xaa, 0x5d, 0x4b, 0xb7, 0x47, 0x46, 0xdd,
- 0x2a, 0x93, 0xc3, 0x90, 0x2e, 0x79, 0x80, 0x80, 0xef, 0x13, 0x04, 0x6a,
- 0x14, 0x3b, 0xb5, 0x9b, 0x92, 0xbe, 0xc2, 0x07, 0x65, 0x4e, 0xfc, 0xda,
- 0xfc, 0xff, 0x7a, 0xae, 0xdc, 0x5c, 0x7e, 0x55, 0x31, 0x0c, 0xe8, 0x39,
- 0x07, 0xa4, 0xd7, 0xbe, 0x2f, 0xd3, 0x0b, 0x6a, 0xd2, 0xb1, 0xdf, 0x5f,
- 0xfe, 0x57, 0x74, 0x53, 0x3b, 0x35, 0x80, 0xdd, 0xae, 0x8e, 0x44, 0x98,
- 0xb3, 0x9f, 0x0e, 0xd3, 0xda, 0xe0, 0xd7, 0xf4, 0x6b, 0x29, 0xab, 0x44,
- 0xa7, 0x4b, 0x58, 0x84, 0x6d, 0x92, 0x4b, 0x81, 0xc3, 0xda, 0x73, 0x8b,
- 0x12, 0x97, 0x48, 0x90, 0x04, 0x45, 0x75, 0x1a, 0xdd, 0x37, 0x31, 0x97,
- 0x92, 0xe8, 0xcd, 0x54, 0x0d, 0x3b, 0xe4, 0xc1, 0x3f, 0x39, 0x5e, 0x2e,
- 0xb8, 0xf3, 0x5c, 0x7e, 0x10, 0x8e, 0x86, 0x41, 0x00, 0x8d, 0x45, 0x66,
- 0x47, 0xb0, 0xa1, 0x65, 0xce, 0xa0, 0xaa, 0x29, 0x09, 0x4e, 0xf3, 0x97,
- 0xeb, 0xe8, 0x2e, 0xab, 0x0f, 0x72, 0xa7, 0x30, 0x0e, 0xfa, 0xc7, 0xf4,
- 0xfd, 0x14, 0x77, 0xc3, 0xa4, 0x5b, 0x28, 0x57, 0xc2, 0xb3, 0xf9, 0x82,
- 0xfd, 0xb7, 0x45, 0x58, 0x9b, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82,
- 0x01, 0x5a, 0x30, 0x82, 0x01, 0x56, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d,
- 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02,
- 0x01, 0x00, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff,
- 0x04, 0x04, 0x03, 0x02, 0x01, 0x86, 0x30, 0x34, 0x06, 0x08, 0x2b, 0x06,
- 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x28, 0x30, 0x26, 0x30, 0x24,
- 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x18,
- 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e,
- 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, 0x74, 0x2e, 0x63, 0x6f, 0x6d,
- 0x30, 0x7b, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x74, 0x30, 0x72, 0x30,
- 0x37, 0xa0, 0x35, 0xa0, 0x33, 0x86, 0x31, 0x68, 0x74, 0x74, 0x70, 0x3a,
- 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x33, 0x2e, 0x64, 0x69, 0x67, 0x69, 0x63,
- 0x65, 0x72, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x44, 0x69, 0x67, 0x69,
- 0x43, 0x65, 0x72, 0x74, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x52, 0x6f,
- 0x6f, 0x74, 0x43, 0x41, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x37, 0xa0, 0x35,
- 0xa0, 0x33, 0x86, 0x31, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63,
- 0x72, 0x6c, 0x34, 0x2e, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, 0x74,
- 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72,
- 0x74, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x52, 0x6f, 0x6f, 0x74, 0x43,
- 0x41, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x3d, 0x06, 0x03, 0x55, 0x1d, 0x20,
- 0x04, 0x36, 0x30, 0x34, 0x30, 0x32, 0x06, 0x04, 0x55, 0x1d, 0x20, 0x00,
- 0x30, 0x2a, 0x30, 0x28, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
- 0x02, 0x01, 0x16, 0x1c, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f,
- 0x77, 0x77, 0x77, 0x2e, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, 0x74,
- 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x43, 0x50, 0x53, 0x30, 0x1d, 0x06, 0x03,
- 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x0f, 0x80, 0x61, 0x1c, 0x82,
- 0x31, 0x61, 0xd5, 0x2f, 0x28, 0xe7, 0x8d, 0x46, 0x38, 0xb4, 0x2c, 0xe1,
- 0xc6, 0xd9, 0xe2, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18,
- 0x30, 0x16, 0x80, 0x14, 0x03, 0xde, 0x50, 0x35, 0x56, 0xd1, 0x4c, 0xbb,
- 0x66, 0xf0, 0xa3, 0xe2, 0x1b, 0x1b, 0xc3, 0x97, 0xb2, 0x3d, 0xd1, 0x55,
- 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
- 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x23, 0x3e, 0xdf, 0x4b,
- 0xd2, 0x31, 0x42, 0xa5, 0xb6, 0x7e, 0x42, 0x5c, 0x1a, 0x44, 0xcc, 0x69,
- 0xd1, 0x68, 0xb4, 0x5d, 0x4b, 0xe0, 0x04, 0x21, 0x6c, 0x4b, 0xe2, 0x6d,
- 0xcc, 0xb1, 0xe0, 0x97, 0x8f, 0xa6, 0x53, 0x09, 0xcd, 0xaa, 0x2a, 0x65,
- 0xe5, 0x39, 0x4f, 0x1e, 0x83, 0xa5, 0x6e, 0x5c, 0x98, 0xa2, 0x24, 0x26,
- 0xe6, 0xfb, 0xa1, 0xed, 0x93, 0xc7, 0x2e, 0x02, 0xc6, 0x4d, 0x4a, 0xbf,
- 0xb0, 0x42, 0xdf, 0x78, 0xda, 0xb3, 0xa8, 0xf9, 0x6d, 0xff, 0x21, 0x85,
- 0x53, 0x36, 0x60, 0x4c, 0x76, 0xce, 0xec, 0x38, 0xdc, 0xd6, 0x51, 0x80,
- 0xf0, 0xc5, 0xd6, 0xe5, 0xd4, 0x4d, 0x27, 0x64, 0xab, 0x9b, 0xc7, 0x3e,
- 0x71, 0xfb, 0x48, 0x97, 0xb8, 0x33, 0x6d, 0xc9, 0x13, 0x07, 0xee, 0x96,
- 0xa2, 0x1b, 0x18, 0x15, 0xf6, 0x5c, 0x4c, 0x40, 0xed, 0xb3, 0xc2, 0xec,
- 0xff, 0x71, 0xc1, 0xe3, 0x47, 0xff, 0xd4, 0xb9, 0x00, 0xb4, 0x37, 0x42,
- 0xda, 0x20, 0xc9, 0xea, 0x6e, 0x8a, 0xee, 0x14, 0x06, 0xae, 0x7d, 0xa2,
- 0x59, 0x98, 0x88, 0xa8, 0x1b, 0x6f, 0x2d, 0xf4, 0xf2, 0xc9, 0x14, 0x5f,
- 0x26, 0xcf, 0x2c, 0x8d, 0x7e, 0xed, 0x37, 0xc0, 0xa9, 0xd5, 0x39, 0xb9,
- 0x82, 0xbf, 0x19, 0x0c, 0xea, 0x34, 0xaf, 0x00, 0x21, 0x68, 0xf8, 0xad,
- 0x73, 0xe2, 0xc9, 0x32, 0xda, 0x38, 0x25, 0x0b, 0x55, 0xd3, 0x9a, 0x1d,
- 0xf0, 0x68, 0x86, 0xed, 0x2e, 0x41, 0x34, 0xef, 0x7c, 0xa5, 0x50, 0x1d,
- 0xbf, 0x3a, 0xf9, 0xd3, 0xc1, 0x08, 0x0c, 0xe6, 0xed, 0x1e, 0x8a, 0x58,
- 0x25, 0xe4, 0xb8, 0x77, 0xad, 0x2d, 0x6e, 0xf5, 0x52, 0xdd, 0xb4, 0x74,
- 0x8f, 0xab, 0x49, 0x2e, 0x9d, 0x3b, 0x93, 0x34, 0x28, 0x1f, 0x78, 0xce,
- 0x94, 0xea, 0xc7, 0xbd, 0xd3, 0xc9, 0x6d, 0x1c, 0xde, 0x5c, 0x32, 0xf3,
-};
-
-#if 0
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number:
- 0b:1d:b1:a9:19:f2:4c:3c:4e:fc:b5:7a:6a:4e:6c:bf
- Signature Algorithm: sha1WithRSAEncryption
- Issuer: C=US, O=GeoTrust Inc., CN=GeoTrust Primary Certification Authority
- Validity
- Not Before: Aug 23 00:00:00 2012 GMT
- Not After : Aug 22 23:59:59 2022 GMT
- Subject: C=US, O=GeoTrust Inc., CN=GeoTrust Extended Validation SSL CA - G2
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:9e:c6:21:cd:2e:3d:d0:bb:2a:4d:a4:7b:1f:a8:
- 1a:c2:03:a6:ff:43:62:5b:bf:91:d1:66:52:a9:81:
- 90:68:31:86:16:bb:1d:85:58:a9:7e:91:6a:1e:4c:
- 31:ca:21:c4:be:70:1b:9f:8c:e4:05:2d:9c:ed:11:
- 79:ad:8f:9c:25:86:4c:ba:f2:e5:62:79:8e:22:5f:
- 85:7c:22:35:38:23:8d:80:3c:ac:cc:2d:fc:58:f2:
- 35:bf:66:5b:eb:c1:24:f8:70:80:74:32:f9:46:de:
- 32:19:80:8c:b7:e7:1a:a1:aa:64:98:8d:ca:ce:0e:
- dc:6b:f7:e2:90:0a:6c:1c:a5:f4:90:32:52:e5:f1:
- 00:42:31:91:48:42:89:a8:5d:7f:63:8d:31:b2:d6:
- 48:5c:45:45:22:c9:c5:59:12:ab:41:94:ea:fe:9c:
- 46:4d:9a:bc:9c:e0:e2:c6:46:b3:e6:7f:dc:f5:0f:
- a3:13:45:86:6d:79:78:fc:e1:50:cf:09:86:e5:9f:
- bf:cb:3a:d4:e0:b1:d4:ff:a8:3f:7d:62:1f:c0:6d:
- 78:48:c3:d7:a3:a5:23:61:c5:3e:35:4d:b2:e5:f8:
- fd:94:4b:bc:73:53:af:e3:9a:69:55:be:cb:67:ab:
- e1:be:ef:1b:c2:4d:ac:cb:29:5c:bc:ed:b8:62:9d:
- 10:e9
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- Authority Information Access:
- OCSP - URI:http://EVSecure-ocsp.geotrust.com
-
- X509v3 Basic Constraints: critical
- CA:TRUE, pathlen:0
- X509v3 Certificate Policies:
- Policy: X509v3 Any Policy
- CPS: http://www.geotrust.com/resources/cps
-
- X509v3 CRL Distribution Points:
-
- Full Name:
- URI:http://EVSecure-crl.geotrust.com/GeoTrustPCA.crl
-
- X509v3 Key Usage: critical
- Certificate Sign, CRL Sign
- X509v3 Subject Alternative Name:
- DirName:/CN=VeriSignMPKI-2-253
- X509v3 Subject Key Identifier:
- 6F:26:56:D9:5C:E7:F7:C9:04:20:F8:1E:BA:7C:91:27:2F:8C:FA:07
- X509v3 Authority Key Identifier:
- keyid:2C:D5:50:41:97:15:8B:F0:8F:36:61:5B:4A:FB:6B:D9:99:C9:33:92
-
- Signature Algorithm: sha1WithRSAEncryption
- 92:77:e9:57:c9:eb:c4:45:6f:c9:4c:6e:7d:00:12:71:a5:e3:
- 39:fe:13:84:49:6c:e7:49:71:f5:2c:c7:c0:36:c2:08:58:f3:
- 83:75:c5:72:d8:8d:78:f4:65:ea:8c:d5:e3:a5:0e:a9:ad:eb:
- e3:a1:23:ae:93:b7:d8:75:75:4a:59:cb:f2:9e:db:40:bf:4e:
- 89:fe:95:42:29:34:7b:f4:dd:6a:0d:74:5f:c7:11:13:2e:dd:
- 11:6e:c6:e3:5b:b3:cf:a6:8d:e5:f7:67:7b:ba:b3:b3:69:70:
- 14:b0:c2:99:b4:d2:76:5b:38:17:39:45:1b:82:f1:53:b8:3d:
- 55:39:0b:7f:ff:98:ad:6e:96:9a:b6:6a:4c:7a:5e:bd:b1:86:
- 12:9d:7c:2c:62:bb:09:93:5f:3f:d8:b5:8a:c3:49:28:0f:0b:
- f9:39:22:1a:fe:5d:d3:e8:18:5f:9d:5f:b4:c0:20:c6:a9:49:
- 0d:55:73:6a:09:7a:ff:a2:99:bf:d8:bb:91:dc:30:39:ae:28:
- 4b:f6:c5:77:24:e8:d6:c6:a7:a0:4e:f2:a6:99:75:cd:dd:57:
- dd:0a:47:92:cb:bb:b7:48:fa:21:f0:69:21:ff:e5:0c:aa:0c:
- b1:ea:dd:05:1c:19:8e:d1:2a:79:68:02:5e:cc:38:e6:29:c4:
- 77:f5:19:1c
------BEGIN CERTIFICATE-----
-MIIEmjCCA4KgAwIBAgIQCx2xqRnyTDxO/LV6ak5svzANBgkqhkiG9w0BAQUFADBY
-MQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjExMC8GA1UEAxMo
-R2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0xMjA4
-MjMwMDAwMDBaFw0yMjA4MjIyMzU5NTlaMFgxCzAJBgNVBAYTAlVTMRYwFAYDVQQK
-Ew1HZW9UcnVzdCBJbmMuMTEwLwYDVQQDEyhHZW9UcnVzdCBFeHRlbmRlZCBWYWxp
-ZGF0aW9uIFNTTCBDQSAtIEcyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
-AQEAnsYhzS490LsqTaR7H6gawgOm/0NiW7+R0WZSqYGQaDGGFrsdhVipfpFqHkwx
-yiHEvnAbn4zkBS2c7RF5rY+cJYZMuvLlYnmOIl+FfCI1OCONgDyszC38WPI1v2Zb
-68Ek+HCAdDL5Rt4yGYCMt+caoapkmI3Kzg7ca/fikApsHKX0kDJS5fEAQjGRSEKJ
-qF1/Y40xstZIXEVFIsnFWRKrQZTq/pxGTZq8nODixkaz5n/c9Q+jE0WGbXl4/OFQ
-zwmG5Z+/yzrU4LHU/6g/fWIfwG14SMPXo6UjYcU+NU2y5fj9lEu8c1Ov45ppVb7L
-Z6vhvu8bwk2syylcvO24Yp0Q6QIDAQABo4IBXjCCAVowPQYIKwYBBQUHAQEEMTAv
-MC0GCCsGAQUFBzABhiFodHRwOi8vRVZTZWN1cmUtb2NzcC5nZW90cnVzdC5jb20w
-EgYDVR0TAQH/BAgwBgEB/wIBADBGBgNVHSAEPzA9MDsGBFUdIAAwMzAxBggrBgEF
-BQcCARYlaHR0cDovL3d3dy5nZW90cnVzdC5jb20vcmVzb3VyY2VzL2NwczBBBgNV
-HR8EOjA4MDagNKAyhjBodHRwOi8vRVZTZWN1cmUtY3JsLmdlb3RydXN0LmNvbS9H
-ZW9UcnVzdFBDQS5jcmwwDgYDVR0PAQH/BAQDAgEGMCoGA1UdEQQjMCGkHzAdMRsw
-GQYDVQQDExJWZXJpU2lnbk1QS0ktMi0yNTMwHQYDVR0OBBYEFG8mVtlc5/fJBCD4
-Hrp8kScvjPoHMB8GA1UdIwQYMBaAFCzVUEGXFYvwjzZhW0r7a9mZyTOSMA0GCSqG
-SIb3DQEBBQUAA4IBAQCSd+lXyevERW/JTG59ABJxpeM5/hOESWznSXH1LMfANsII
-WPODdcVy2I149GXqjNXjpQ6prevjoSOuk7fYdXVKWcvynttAv06J/pVCKTR79N1q
-DXRfxxETLt0RbsbjW7PPpo3l92d7urOzaXAUsMKZtNJ2WzgXOUUbgvFTuD1VOQt/
-/5itbpaatmpMel69sYYSnXwsYrsJk18/2LWKw0koDwv5OSIa/l3T6BhfnV+0wCDG
-qUkNVXNqCXr/opm/2LuR3DA5rihL9sV3JOjWxqegTvKmmXXN3VfdCkeSy7u3SPoh
-8Gkh/+UMqgyx6t0FHBmO0Sp5aAJezDjmKcR39Rkc
------END CERTIFICATE-----
-#endif
-static const unsigned char kDERCert22[] = {
- 0x30, 0x82, 0x04, 0x9a, 0x30, 0x82, 0x03, 0x82, 0xa0, 0x03, 0x02, 0x01,
- 0x02, 0x02, 0x10, 0x0b, 0x1d, 0xb1, 0xa9, 0x19, 0xf2, 0x4c, 0x3c, 0x4e,
- 0xfc, 0xb5, 0x7a, 0x6a, 0x4e, 0x6c, 0xbf, 0x30, 0x0d, 0x06, 0x09, 0x2a,
- 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x58,
- 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55,
- 0x53, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0d,
- 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x49, 0x6e, 0x63,
- 0x2e, 0x31, 0x31, 0x30, 0x2f, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x28,
- 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x50, 0x72, 0x69,
- 0x6d, 0x61, 0x72, 0x79, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69,
- 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f,
- 0x72, 0x69, 0x74, 0x79, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x32, 0x30, 0x38,
- 0x32, 0x33, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32,
- 0x32, 0x30, 0x38, 0x32, 0x32, 0x32, 0x33, 0x35, 0x39, 0x35, 0x39, 0x5a,
- 0x30, 0x58, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
- 0x02, 0x55, 0x53, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a,
- 0x13, 0x0d, 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x49,
- 0x6e, 0x63, 0x2e, 0x31, 0x31, 0x30, 0x2f, 0x06, 0x03, 0x55, 0x04, 0x03,
- 0x13, 0x28, 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x45,
- 0x78, 0x74, 0x65, 0x6e, 0x64, 0x65, 0x64, 0x20, 0x56, 0x61, 0x6c, 0x69,
- 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x53, 0x53, 0x4c, 0x20, 0x43,
- 0x41, 0x20, 0x2d, 0x20, 0x47, 0x32, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d,
- 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05,
- 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82,
- 0x01, 0x01, 0x00, 0x9e, 0xc6, 0x21, 0xcd, 0x2e, 0x3d, 0xd0, 0xbb, 0x2a,
- 0x4d, 0xa4, 0x7b, 0x1f, 0xa8, 0x1a, 0xc2, 0x03, 0xa6, 0xff, 0x43, 0x62,
- 0x5b, 0xbf, 0x91, 0xd1, 0x66, 0x52, 0xa9, 0x81, 0x90, 0x68, 0x31, 0x86,
- 0x16, 0xbb, 0x1d, 0x85, 0x58, 0xa9, 0x7e, 0x91, 0x6a, 0x1e, 0x4c, 0x31,
- 0xca, 0x21, 0xc4, 0xbe, 0x70, 0x1b, 0x9f, 0x8c, 0xe4, 0x05, 0x2d, 0x9c,
- 0xed, 0x11, 0x79, 0xad, 0x8f, 0x9c, 0x25, 0x86, 0x4c, 0xba, 0xf2, 0xe5,
- 0x62, 0x79, 0x8e, 0x22, 0x5f, 0x85, 0x7c, 0x22, 0x35, 0x38, 0x23, 0x8d,
- 0x80, 0x3c, 0xac, 0xcc, 0x2d, 0xfc, 0x58, 0xf2, 0x35, 0xbf, 0x66, 0x5b,
- 0xeb, 0xc1, 0x24, 0xf8, 0x70, 0x80, 0x74, 0x32, 0xf9, 0x46, 0xde, 0x32,
- 0x19, 0x80, 0x8c, 0xb7, 0xe7, 0x1a, 0xa1, 0xaa, 0x64, 0x98, 0x8d, 0xca,
- 0xce, 0x0e, 0xdc, 0x6b, 0xf7, 0xe2, 0x90, 0x0a, 0x6c, 0x1c, 0xa5, 0xf4,
- 0x90, 0x32, 0x52, 0xe5, 0xf1, 0x00, 0x42, 0x31, 0x91, 0x48, 0x42, 0x89,
- 0xa8, 0x5d, 0x7f, 0x63, 0x8d, 0x31, 0xb2, 0xd6, 0x48, 0x5c, 0x45, 0x45,
- 0x22, 0xc9, 0xc5, 0x59, 0x12, 0xab, 0x41, 0x94, 0xea, 0xfe, 0x9c, 0x46,
- 0x4d, 0x9a, 0xbc, 0x9c, 0xe0, 0xe2, 0xc6, 0x46, 0xb3, 0xe6, 0x7f, 0xdc,
- 0xf5, 0x0f, 0xa3, 0x13, 0x45, 0x86, 0x6d, 0x79, 0x78, 0xfc, 0xe1, 0x50,
- 0xcf, 0x09, 0x86, 0xe5, 0x9f, 0xbf, 0xcb, 0x3a, 0xd4, 0xe0, 0xb1, 0xd4,
- 0xff, 0xa8, 0x3f, 0x7d, 0x62, 0x1f, 0xc0, 0x6d, 0x78, 0x48, 0xc3, 0xd7,
- 0xa3, 0xa5, 0x23, 0x61, 0xc5, 0x3e, 0x35, 0x4d, 0xb2, 0xe5, 0xf8, 0xfd,
- 0x94, 0x4b, 0xbc, 0x73, 0x53, 0xaf, 0xe3, 0x9a, 0x69, 0x55, 0xbe, 0xcb,
- 0x67, 0xab, 0xe1, 0xbe, 0xef, 0x1b, 0xc2, 0x4d, 0xac, 0xcb, 0x29, 0x5c,
- 0xbc, 0xed, 0xb8, 0x62, 0x9d, 0x10, 0xe9, 0x02, 0x03, 0x01, 0x00, 0x01,
- 0xa3, 0x82, 0x01, 0x5e, 0x30, 0x82, 0x01, 0x5a, 0x30, 0x3d, 0x06, 0x08,
- 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x31, 0x30, 0x2f,
- 0x30, 0x2d, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01,
- 0x86, 0x21, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x45, 0x56, 0x53,
- 0x65, 0x63, 0x75, 0x72, 0x65, 0x2d, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x67,
- 0x65, 0x6f, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x30,
- 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30,
- 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x00, 0x30, 0x46, 0x06, 0x03, 0x55,
- 0x1d, 0x20, 0x04, 0x3f, 0x30, 0x3d, 0x30, 0x3b, 0x06, 0x04, 0x55, 0x1d,
- 0x20, 0x00, 0x30, 0x33, 0x30, 0x31, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05,
- 0x05, 0x07, 0x02, 0x01, 0x16, 0x25, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f,
- 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x67, 0x65, 0x6f, 0x74, 0x72, 0x75, 0x73,
- 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72,
- 0x63, 0x65, 0x73, 0x2f, 0x63, 0x70, 0x73, 0x30, 0x41, 0x06, 0x03, 0x55,
- 0x1d, 0x1f, 0x04, 0x3a, 0x30, 0x38, 0x30, 0x36, 0xa0, 0x34, 0xa0, 0x32,
- 0x86, 0x30, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x45, 0x56, 0x53,
- 0x65, 0x63, 0x75, 0x72, 0x65, 0x2d, 0x63, 0x72, 0x6c, 0x2e, 0x67, 0x65,
- 0x6f, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x47,
- 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x50, 0x43, 0x41, 0x2e, 0x63,
- 0x72, 0x6c, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff,
- 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x2a, 0x06, 0x03, 0x55, 0x1d,
- 0x11, 0x04, 0x23, 0x30, 0x21, 0xa4, 0x1f, 0x30, 0x1d, 0x31, 0x1b, 0x30,
- 0x19, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x12, 0x56, 0x65, 0x72, 0x69,
- 0x53, 0x69, 0x67, 0x6e, 0x4d, 0x50, 0x4b, 0x49, 0x2d, 0x32, 0x2d, 0x32,
- 0x35, 0x33, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04,
- 0x14, 0x6f, 0x26, 0x56, 0xd9, 0x5c, 0xe7, 0xf7, 0xc9, 0x04, 0x20, 0xf8,
- 0x1e, 0xba, 0x7c, 0x91, 0x27, 0x2f, 0x8c, 0xfa, 0x07, 0x30, 0x1f, 0x06,
- 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x2c, 0xd5,
- 0x50, 0x41, 0x97, 0x15, 0x8b, 0xf0, 0x8f, 0x36, 0x61, 0x5b, 0x4a, 0xfb,
- 0x6b, 0xd9, 0x99, 0xc9, 0x33, 0x92, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
- 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x82, 0x01,
- 0x01, 0x00, 0x92, 0x77, 0xe9, 0x57, 0xc9, 0xeb, 0xc4, 0x45, 0x6f, 0xc9,
- 0x4c, 0x6e, 0x7d, 0x00, 0x12, 0x71, 0xa5, 0xe3, 0x39, 0xfe, 0x13, 0x84,
- 0x49, 0x6c, 0xe7, 0x49, 0x71, 0xf5, 0x2c, 0xc7, 0xc0, 0x36, 0xc2, 0x08,
- 0x58, 0xf3, 0x83, 0x75, 0xc5, 0x72, 0xd8, 0x8d, 0x78, 0xf4, 0x65, 0xea,
- 0x8c, 0xd5, 0xe3, 0xa5, 0x0e, 0xa9, 0xad, 0xeb, 0xe3, 0xa1, 0x23, 0xae,
- 0x93, 0xb7, 0xd8, 0x75, 0x75, 0x4a, 0x59, 0xcb, 0xf2, 0x9e, 0xdb, 0x40,
- 0xbf, 0x4e, 0x89, 0xfe, 0x95, 0x42, 0x29, 0x34, 0x7b, 0xf4, 0xdd, 0x6a,
- 0x0d, 0x74, 0x5f, 0xc7, 0x11, 0x13, 0x2e, 0xdd, 0x11, 0x6e, 0xc6, 0xe3,
- 0x5b, 0xb3, 0xcf, 0xa6, 0x8d, 0xe5, 0xf7, 0x67, 0x7b, 0xba, 0xb3, 0xb3,
- 0x69, 0x70, 0x14, 0xb0, 0xc2, 0x99, 0xb4, 0xd2, 0x76, 0x5b, 0x38, 0x17,
- 0x39, 0x45, 0x1b, 0x82, 0xf1, 0x53, 0xb8, 0x3d, 0x55, 0x39, 0x0b, 0x7f,
- 0xff, 0x98, 0xad, 0x6e, 0x96, 0x9a, 0xb6, 0x6a, 0x4c, 0x7a, 0x5e, 0xbd,
- 0xb1, 0x86, 0x12, 0x9d, 0x7c, 0x2c, 0x62, 0xbb, 0x09, 0x93, 0x5f, 0x3f,
- 0xd8, 0xb5, 0x8a, 0xc3, 0x49, 0x28, 0x0f, 0x0b, 0xf9, 0x39, 0x22, 0x1a,
- 0xfe, 0x5d, 0xd3, 0xe8, 0x18, 0x5f, 0x9d, 0x5f, 0xb4, 0xc0, 0x20, 0xc6,
- 0xa9, 0x49, 0x0d, 0x55, 0x73, 0x6a, 0x09, 0x7a, 0xff, 0xa2, 0x99, 0xbf,
- 0xd8, 0xbb, 0x91, 0xdc, 0x30, 0x39, 0xae, 0x28, 0x4b, 0xf6, 0xc5, 0x77,
- 0x24, 0xe8, 0xd6, 0xc6, 0xa7, 0xa0, 0x4e, 0xf2, 0xa6, 0x99, 0x75, 0xcd,
- 0xdd, 0x57, 0xdd, 0x0a, 0x47, 0x92, 0xcb, 0xbb, 0xb7, 0x48, 0xfa, 0x21,
- 0xf0, 0x69, 0x21, 0xff, 0xe5, 0x0c, 0xaa, 0x0c, 0xb1, 0xea, 0xdd, 0x05,
- 0x1c, 0x19, 0x8e, 0xd1, 0x2a, 0x79, 0x68, 0x02, 0x5e, 0xcc, 0x38, 0xe6,
- 0x29, 0xc4, 0x77, 0xf5, 0x19, 0x1c,
-};
-
-#if 0
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number: 3740804 (0x391484)
- Signature Algorithm: sha256WithRSAEncryption
- Issuer: C=US, O=Starfield Technologies, Inc., OU=Starfield Class 2 Certification Authority
- Validity
- Not Before: Jan 1 07:00:00 2014 GMT
- Not After : May 30 07:00:00 2031 GMT
- Subject: C=US, ST=Arizona, L=Scottsdale, O=Starfield Technologies, Inc., CN=Starfield Root Certificate Authority - G2
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:bd:ed:c1:03:fc:f6:8f:fc:02:b1:6f:5b:9f:48:
- d9:9d:79:e2:a2:b7:03:61:56:18:c3:47:b6:d7:ca:
- 3d:35:2e:89:43:f7:a1:69:9b:de:8a:1a:fd:13:20:
- 9c:b4:49:77:32:29:56:fd:b9:ec:8c:dd:22:fa:72:
- dc:27:61:97:ee:f6:5a:84:ec:6e:19:b9:89:2c:dc:
- 84:5b:d5:74:fb:6b:5f:c5:89:a5:10:52:89:46:55:
- f4:b8:75:1c:e6:7f:e4:54:ae:4b:f8:55:72:57:02:
- 19:f8:17:71:59:eb:1e:28:07:74:c5:9d:48:be:6c:
- b4:f4:a4:b0:f3:64:37:79:92:c0:ec:46:5e:7f:e1:
- 6d:53:4c:62:af:cd:1f:0b:63:bb:3a:9d:fb:fc:79:
- 00:98:61:74:cf:26:82:40:63:f3:b2:72:6a:19:0d:
- 99:ca:d4:0e:75:cc:37:fb:8b:89:c1:59:f1:62:7f:
- 5f:b3:5f:65:30:f8:a7:b7:4d:76:5a:1e:76:5e:34:
- c0:e8:96:56:99:8a:b3:f0:7f:a4:cd:bd:dc:32:31:
- 7c:91:cf:e0:5f:11:f8:6b:aa:49:5c:d1:99:94:d1:
- a2:e3:63:5b:09:76:b5:56:62:e1:4b:74:1d:96:d4:
- 26:d4:08:04:59:d0:98:0e:0e:e6:de:fc:c3:ec:1f:
- 90:f1
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Basic Constraints: critical
- CA:TRUE
- X509v3 Key Usage: critical
- Certificate Sign, CRL Sign
- X509v3 Subject Key Identifier:
- 7C:0C:32:1F:A7:D9:30:7F:C4:7D:68:A3:62:A8:A1:CE:AB:07:5B:27
- X509v3 Authority Key Identifier:
- keyid:BF:5F:B7:D1:CE:DD:1F:86:F4:5B:55:AC:DC:D7:10:C2:0E:A9:88:E7
-
- Authority Information Access:
- OCSP - URI:http://ocsp.starfieldtech.com/
-
- X509v3 CRL Distribution Points:
-
- Full Name:
- URI:http://crl.starfieldtech.com/sfroot.crl
-
- X509v3 Certificate Policies:
- Policy: X509v3 Any Policy
- CPS: https://certs.starfieldtech.com/repository/
-
- Signature Algorithm: sha256WithRSAEncryption
- 85:63:c1:d9:dd:b9:ff:a9:bd:a6:19:dc:bf:13:3a:11:38:22:
- 54:b1:ac:05:10:fb:7c:b3:96:3f:31:8b:66:ff:88:f3:e1:bf:
- fb:c7:1f:00:ff:46:6a:8b:61:32:c9:01:51:76:fb:9a:c6:fa:
- 20:51:c8:46:c4:98:d7:79:a3:e3:04:72:3f:8b:4d:34:53:67:
- ec:33:2c:7b:e8:94:01:28:7c:3a:34:5b:02:77:16:8d:40:25:
- 33:b0:bc:6c:97:d7:05:7a:ff:8c:85:ce:6f:a0:53:00:17:6e:
- 1e:6c:bd:22:d7:0a:88:37:f6:7d:eb:99:41:ef:27:cb:8c:60:
- 6b:4c:01:7e:65:50:0b:4f:b8:95:9a:9a:6e:34:fd:73:3a:33:
- f1:91:d5:f3:4e:2d:74:e8:ef:d3:90:35:f1:06:68:64:d4:d0:
- 13:fd:52:d3:c6:6d:c1:3a:8a:31:dd:05:26:35:4a:8c:65:b8:
- 52:6b:81:ec:d2:9c:b5:34:10:97:9c:3e:c6:2f:ed:8e:42:42:
- 24:2e:e9:73:9a:25:f9:11:f1:f2:23:69:cb:e5:94:69:a0:d2:
- dc:b0:fc:44:89:ac:17:a8:cc:d5:37:77:16:c5:80:b9:0c:8f:
- 57:02:55:99:85:7b:49:f0:2e:5b:a0:c2:57:53:5d:a2:e8:a6:
- 37:c3:01:fa
------BEGIN CERTIFICATE-----
-MIIEoDCCA4igAwIBAgIDORSEMA0GCSqGSIb3DQEBCwUAMGgxCzAJBgNVBAYTAlVT
-MSUwIwYDVQQKExxTdGFyZmllbGQgVGVjaG5vbG9naWVzLCBJbmMuMTIwMAYDVQQL
-EylTdGFyZmllbGQgQ2xhc3MgMiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0x
-NDAxMDEwNzAwMDBaFw0zMTA1MzAwNzAwMDBaMIGPMQswCQYDVQQGEwJVUzEQMA4G
-A1UECBMHQXJpem9uYTETMBEGA1UEBxMKU2NvdHRzZGFsZTElMCMGA1UEChMcU3Rh
-cmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UEAxMpU3RhcmZpZWxkIFJv
-b3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IC0gRzIwggEiMA0GCSqGSIb3DQEBAQUA
-A4IBDwAwggEKAoIBAQC97cED/PaP/AKxb1ufSNmdeeKitwNhVhjDR7bXyj01LolD
-96Fpm96KGv0TIJy0SXcyKVb9ueyM3SL6ctwnYZfu9lqE7G4ZuYks3IRb1XT7a1/F
-iaUQUolGVfS4dRzmf+RUrkv4VXJXAhn4F3FZ6x4oB3TFnUi+bLT0pLDzZDd5ksDs
-Rl5/4W1TTGKvzR8LY7s6nfv8eQCYYXTPJoJAY/OycmoZDZnK1A51zDf7i4nBWfFi
-f1+zX2Uw+Ke3TXZaHnZeNMDollaZirPwf6TNvdwyMXyRz+BfEfhrqklc0ZmU0aLj
-Y1sJdrVWYuFLdB2W1CbUCARZ0JgODube/MPsH5DxAgMBAAGjggEpMIIBJTAPBgNV
-HRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUfAwyH6fZMH/E
-fWijYqihzqsHWycwHwYDVR0jBBgwFoAUv1+30c7dH4b0W1Ws3NcQwg6piOcwOgYI
-KwYBBQUHAQEELjAsMCoGCCsGAQUFBzABhh5odHRwOi8vb2NzcC5zdGFyZmllbGR0
-ZWNoLmNvbS8wOAYDVR0fBDEwLzAtoCugKYYnaHR0cDovL2NybC5zdGFyZmllbGR0
-ZWNoLmNvbS9zZnJvb3QuY3JsMEwGA1UdIARFMEMwQQYEVR0gADA5MDcGCCsGAQUF
-BwIBFitodHRwczovL2NlcnRzLnN0YXJmaWVsZHRlY2guY29tL3JlcG9zaXRvcnkv
-MA0GCSqGSIb3DQEBCwUAA4IBAQCFY8HZ3bn/qb2mGdy/EzoROCJUsawFEPt8s5Y/
-MYtm/4jz4b/7xx8A/0Zqi2EyyQFRdvuaxvogUchGxJjXeaPjBHI/i000U2fsMyx7
-6JQBKHw6NFsCdxaNQCUzsLxsl9cFev+Mhc5voFMAF24ebL0i1wqIN/Z965lB7yfL
-jGBrTAF+ZVALT7iVmppuNP1zOjPxkdXzTi106O/TkDXxBmhk1NAT/VLTxm3BOoox
-3QUmNUqMZbhSa4Hs0py1NBCXnD7GL+2OQkIkLulzmiX5EfHyI2nL5ZRpoNLcsPxE
-iawXqMzVN3cWxYC5DI9XAlWZhXtJ8C5boMJXU12i6KY3wwH6
------END CERTIFICATE-----
-#endif
-static const unsigned char kDERCert23[] = {
- 0x30, 0x82, 0x04, 0xa0, 0x30, 0x82, 0x03, 0x88, 0xa0, 0x03, 0x02, 0x01,
- 0x02, 0x02, 0x03, 0x39, 0x14, 0x84, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
- 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x68, 0x31,
- 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53,
- 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x1c, 0x53,
- 0x74, 0x61, 0x72, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x20, 0x54, 0x65, 0x63,
- 0x68, 0x6e, 0x6f, 0x6c, 0x6f, 0x67, 0x69, 0x65, 0x73, 0x2c, 0x20, 0x49,
- 0x6e, 0x63, 0x2e, 0x31, 0x32, 0x30, 0x30, 0x06, 0x03, 0x55, 0x04, 0x0b,
- 0x13, 0x29, 0x53, 0x74, 0x61, 0x72, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x20,
- 0x43, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x32, 0x20, 0x43, 0x65, 0x72, 0x74,
- 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75,
- 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x30, 0x1e, 0x17, 0x0d, 0x31,
- 0x34, 0x30, 0x31, 0x30, 0x31, 0x30, 0x37, 0x30, 0x30, 0x30, 0x30, 0x5a,
- 0x17, 0x0d, 0x33, 0x31, 0x30, 0x35, 0x33, 0x30, 0x30, 0x37, 0x30, 0x30,
- 0x30, 0x30, 0x5a, 0x30, 0x81, 0x8f, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03,
- 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x10, 0x30, 0x0e, 0x06,
- 0x03, 0x55, 0x04, 0x08, 0x13, 0x07, 0x41, 0x72, 0x69, 0x7a, 0x6f, 0x6e,
- 0x61, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x0a,
- 0x53, 0x63, 0x6f, 0x74, 0x74, 0x73, 0x64, 0x61, 0x6c, 0x65, 0x31, 0x25,
- 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x1c, 0x53, 0x74, 0x61,
- 0x72, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x20, 0x54, 0x65, 0x63, 0x68, 0x6e,
- 0x6f, 0x6c, 0x6f, 0x67, 0x69, 0x65, 0x73, 0x2c, 0x20, 0x49, 0x6e, 0x63,
- 0x2e, 0x31, 0x32, 0x30, 0x30, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x29,
- 0x53, 0x74, 0x61, 0x72, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x20, 0x52, 0x6f,
- 0x6f, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61,
- 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79,
- 0x20, 0x2d, 0x20, 0x47, 0x32, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06,
- 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00,
- 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01,
- 0x01, 0x00, 0xbd, 0xed, 0xc1, 0x03, 0xfc, 0xf6, 0x8f, 0xfc, 0x02, 0xb1,
- 0x6f, 0x5b, 0x9f, 0x48, 0xd9, 0x9d, 0x79, 0xe2, 0xa2, 0xb7, 0x03, 0x61,
- 0x56, 0x18, 0xc3, 0x47, 0xb6, 0xd7, 0xca, 0x3d, 0x35, 0x2e, 0x89, 0x43,
- 0xf7, 0xa1, 0x69, 0x9b, 0xde, 0x8a, 0x1a, 0xfd, 0x13, 0x20, 0x9c, 0xb4,
- 0x49, 0x77, 0x32, 0x29, 0x56, 0xfd, 0xb9, 0xec, 0x8c, 0xdd, 0x22, 0xfa,
- 0x72, 0xdc, 0x27, 0x61, 0x97, 0xee, 0xf6, 0x5a, 0x84, 0xec, 0x6e, 0x19,
- 0xb9, 0x89, 0x2c, 0xdc, 0x84, 0x5b, 0xd5, 0x74, 0xfb, 0x6b, 0x5f, 0xc5,
- 0x89, 0xa5, 0x10, 0x52, 0x89, 0x46, 0x55, 0xf4, 0xb8, 0x75, 0x1c, 0xe6,
- 0x7f, 0xe4, 0x54, 0xae, 0x4b, 0xf8, 0x55, 0x72, 0x57, 0x02, 0x19, 0xf8,
- 0x17, 0x71, 0x59, 0xeb, 0x1e, 0x28, 0x07, 0x74, 0xc5, 0x9d, 0x48, 0xbe,
- 0x6c, 0xb4, 0xf4, 0xa4, 0xb0, 0xf3, 0x64, 0x37, 0x79, 0x92, 0xc0, 0xec,
- 0x46, 0x5e, 0x7f, 0xe1, 0x6d, 0x53, 0x4c, 0x62, 0xaf, 0xcd, 0x1f, 0x0b,
- 0x63, 0xbb, 0x3a, 0x9d, 0xfb, 0xfc, 0x79, 0x00, 0x98, 0x61, 0x74, 0xcf,
- 0x26, 0x82, 0x40, 0x63, 0xf3, 0xb2, 0x72, 0x6a, 0x19, 0x0d, 0x99, 0xca,
- 0xd4, 0x0e, 0x75, 0xcc, 0x37, 0xfb, 0x8b, 0x89, 0xc1, 0x59, 0xf1, 0x62,
- 0x7f, 0x5f, 0xb3, 0x5f, 0x65, 0x30, 0xf8, 0xa7, 0xb7, 0x4d, 0x76, 0x5a,
- 0x1e, 0x76, 0x5e, 0x34, 0xc0, 0xe8, 0x96, 0x56, 0x99, 0x8a, 0xb3, 0xf0,
- 0x7f, 0xa4, 0xcd, 0xbd, 0xdc, 0x32, 0x31, 0x7c, 0x91, 0xcf, 0xe0, 0x5f,
- 0x11, 0xf8, 0x6b, 0xaa, 0x49, 0x5c, 0xd1, 0x99, 0x94, 0xd1, 0xa2, 0xe3,
- 0x63, 0x5b, 0x09, 0x76, 0xb5, 0x56, 0x62, 0xe1, 0x4b, 0x74, 0x1d, 0x96,
- 0xd4, 0x26, 0xd4, 0x08, 0x04, 0x59, 0xd0, 0x98, 0x0e, 0x0e, 0xe6, 0xde,
- 0xfc, 0xc3, 0xec, 0x1f, 0x90, 0xf1, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3,
- 0x82, 0x01, 0x29, 0x30, 0x82, 0x01, 0x25, 0x30, 0x0f, 0x06, 0x03, 0x55,
- 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff,
- 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04,
- 0x03, 0x02, 0x01, 0x06, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04,
- 0x16, 0x04, 0x14, 0x7c, 0x0c, 0x32, 0x1f, 0xa7, 0xd9, 0x30, 0x7f, 0xc4,
- 0x7d, 0x68, 0xa3, 0x62, 0xa8, 0xa1, 0xce, 0xab, 0x07, 0x5b, 0x27, 0x30,
- 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14,
- 0xbf, 0x5f, 0xb7, 0xd1, 0xce, 0xdd, 0x1f, 0x86, 0xf4, 0x5b, 0x55, 0xac,
- 0xdc, 0xd7, 0x10, 0xc2, 0x0e, 0xa9, 0x88, 0xe7, 0x30, 0x3a, 0x06, 0x08,
- 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x2e, 0x30, 0x2c,
- 0x30, 0x2a, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01,
- 0x86, 0x1e, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73,
- 0x70, 0x2e, 0x73, 0x74, 0x61, 0x72, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x74,
- 0x65, 0x63, 0x68, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x30, 0x38, 0x06, 0x03,
- 0x55, 0x1d, 0x1f, 0x04, 0x31, 0x30, 0x2f, 0x30, 0x2d, 0xa0, 0x2b, 0xa0,
- 0x29, 0x86, 0x27, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72,
- 0x6c, 0x2e, 0x73, 0x74, 0x61, 0x72, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x74,
- 0x65, 0x63, 0x68, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x73, 0x66, 0x72, 0x6f,
- 0x6f, 0x74, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x4c, 0x06, 0x03, 0x55, 0x1d,
- 0x20, 0x04, 0x45, 0x30, 0x43, 0x30, 0x41, 0x06, 0x04, 0x55, 0x1d, 0x20,
- 0x00, 0x30, 0x39, 0x30, 0x37, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05,
- 0x07, 0x02, 0x01, 0x16, 0x2b, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f,
- 0x2f, 0x63, 0x65, 0x72, 0x74, 0x73, 0x2e, 0x73, 0x74, 0x61, 0x72, 0x66,
- 0x69, 0x65, 0x6c, 0x64, 0x74, 0x65, 0x63, 0x68, 0x2e, 0x63, 0x6f, 0x6d,
- 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x2f,
- 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
- 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x85, 0x63, 0xc1, 0xd9,
- 0xdd, 0xb9, 0xff, 0xa9, 0xbd, 0xa6, 0x19, 0xdc, 0xbf, 0x13, 0x3a, 0x11,
- 0x38, 0x22, 0x54, 0xb1, 0xac, 0x05, 0x10, 0xfb, 0x7c, 0xb3, 0x96, 0x3f,
- 0x31, 0x8b, 0x66, 0xff, 0x88, 0xf3, 0xe1, 0xbf, 0xfb, 0xc7, 0x1f, 0x00,
- 0xff, 0x46, 0x6a, 0x8b, 0x61, 0x32, 0xc9, 0x01, 0x51, 0x76, 0xfb, 0x9a,
- 0xc6, 0xfa, 0x20, 0x51, 0xc8, 0x46, 0xc4, 0x98, 0xd7, 0x79, 0xa3, 0xe3,
- 0x04, 0x72, 0x3f, 0x8b, 0x4d, 0x34, 0x53, 0x67, 0xec, 0x33, 0x2c, 0x7b,
- 0xe8, 0x94, 0x01, 0x28, 0x7c, 0x3a, 0x34, 0x5b, 0x02, 0x77, 0x16, 0x8d,
- 0x40, 0x25, 0x33, 0xb0, 0xbc, 0x6c, 0x97, 0xd7, 0x05, 0x7a, 0xff, 0x8c,
- 0x85, 0xce, 0x6f, 0xa0, 0x53, 0x00, 0x17, 0x6e, 0x1e, 0x6c, 0xbd, 0x22,
- 0xd7, 0x0a, 0x88, 0x37, 0xf6, 0x7d, 0xeb, 0x99, 0x41, 0xef, 0x27, 0xcb,
- 0x8c, 0x60, 0x6b, 0x4c, 0x01, 0x7e, 0x65, 0x50, 0x0b, 0x4f, 0xb8, 0x95,
- 0x9a, 0x9a, 0x6e, 0x34, 0xfd, 0x73, 0x3a, 0x33, 0xf1, 0x91, 0xd5, 0xf3,
- 0x4e, 0x2d, 0x74, 0xe8, 0xef, 0xd3, 0x90, 0x35, 0xf1, 0x06, 0x68, 0x64,
- 0xd4, 0xd0, 0x13, 0xfd, 0x52, 0xd3, 0xc6, 0x6d, 0xc1, 0x3a, 0x8a, 0x31,
- 0xdd, 0x05, 0x26, 0x35, 0x4a, 0x8c, 0x65, 0xb8, 0x52, 0x6b, 0x81, 0xec,
- 0xd2, 0x9c, 0xb5, 0x34, 0x10, 0x97, 0x9c, 0x3e, 0xc6, 0x2f, 0xed, 0x8e,
- 0x42, 0x42, 0x24, 0x2e, 0xe9, 0x73, 0x9a, 0x25, 0xf9, 0x11, 0xf1, 0xf2,
- 0x23, 0x69, 0xcb, 0xe5, 0x94, 0x69, 0xa0, 0xd2, 0xdc, 0xb0, 0xfc, 0x44,
- 0x89, 0xac, 0x17, 0xa8, 0xcc, 0xd5, 0x37, 0x77, 0x16, 0xc5, 0x80, 0xb9,
- 0x0c, 0x8f, 0x57, 0x02, 0x55, 0x99, 0x85, 0x7b, 0x49, 0xf0, 0x2e, 0x5b,
- 0xa0, 0xc2, 0x57, 0x53, 0x5d, 0xa2, 0xe8, 0xa6, 0x37, 0xc3, 0x01, 0xfa,
-};
-
-#if 0
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number:
- 28:1c:89:29:66:14:43:80:42:63:55:3a:32:40:ae:b3
- Signature Algorithm: sha256WithRSAEncryption
- Issuer: C=US, O=GeoTrust Inc., OU=(c) 2008 GeoTrust Inc. - For authorized use only, CN=GeoTrust Primary Certification Authority - G3
- Validity
- Not Before: Jun 30 00:00:00 2015 GMT
- Not After : Jun 29 23:59:59 2025 GMT
- Subject: C=US, O=GeoTrust Inc., CN=RapidSSL SHA256 CA - G4
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:c0:9e:3a:0f:9a:b2:ba:d3:d2:dc:15:ec:d0:30:
- 54:59:30:4d:40:51:ae:42:71:71:d2:8d:53:73:81:
- fe:b8:e0:c4:96:c5:8e:7e:c2:f1:b7:63:4a:cf:a7:
- 1e:3f:a8:e7:ce:53:a0:fa:2d:f7:d6:e6:ce:70:11:
- a6:ee:e1:03:52:d2:68:de:3d:08:0d:87:fd:1c:d7:
- 0b:97:62:6d:82:30:76:1b:47:3a:c4:f7:ce:ed:1d:
- 7c:8c:b7:17:8e:53:80:1e:1d:0f:5d:8c:f9:90:e4:
- 04:1e:02:7e:cb:b0:49:ef:da:52:25:fb:fb:67:ed:
- dd:84:74:59:84:0e:f3:de:70:66:8d:e4:52:38:f7:
- 53:5a:37:13:67:0b:3e:bb:a8:58:b7:2e:ed:ff:b7:
- 5e:11:73:b9:77:45:52:67:46:ae:c4:dc:24:81:89:
- 76:0a:ca:a1:6c:66:73:04:82:aa:f5:70:6c:5f:1b:
- 9a:00:79:46:d6:7f:7a:26:17:30:cf:39:4b:2c:74:
- d9:89:44:76:10:d0:ed:f7:8b:bb:89:05:75:4d:0b:
- 0d:b3:da:e9:bf:f1:6a:7d:2a:11:db:1e:9f:8c:e3:
- c4:06:69:e1:1d:88:45:39:d1:6e:55:d8:aa:b7:9b:
- 6f:ea:f4:de:ac:17:11:92:5d:40:9b:83:7b:9a:e2:
- f7:a9
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- Authority Information Access:
- OCSP - URI:http://g.symcd.com
-
- X509v3 Basic Constraints: critical
- CA:TRUE, pathlen:0
- X509v3 Certificate Policies:
- Policy: 2.23.140.1.2.1
- CPS: https://www.geotrust.com/resources/cps
-
- X509v3 CRL Distribution Points:
-
- Full Name:
- URI:http://g.symcb.com/GeoTrustPCA-G3.crl
-
- X509v3 Extended Key Usage:
- TLS Web Server Authentication, TLS Web Client Authentication
- X509v3 Key Usage: critical
- Certificate Sign, CRL Sign
- X509v3 Subject Key Identifier:
- F3:B5:56:0C:C4:09:B0:B4:CF:1F:AA:F9:DD:23:56:F0:77:E8:A1:F9
- X509v3 Authority Key Identifier:
- keyid:C4:79:CA:8E:A1:4E:03:1D:1C:DC:6B:DB:31:5B:94:3E:3F:30:7F:2D
-
- Signature Algorithm: sha256WithRSAEncryption
- c3:7e:d8:83:4b:04:4c:55:29:2a:4f:14:9d:9a:6e:de:90:70:
- c1:a4:26:4c:88:8e:78:48:ef:bd:9c:b0:a0:f5:f0:66:fc:fe:
- 59:26:e1:79:ef:c8:b7:60:64:a8:8b:47:ea:2f:e0:83:99:da:
- 41:19:d7:c5:be:05:fa:f2:90:11:f0:0a:ff:6c:dc:05:b4:d8:
- 06:6f:a4:6f:8d:be:20:2b:54:db:f9:a2:45:83:9a:1e:a5:21:
- 89:35:1d:7c:20:5c:17:fd:04:2e:45:d8:b2:c6:f8:42:99:fc:
- 54:08:4e:4b:80:5f:39:37:ba:95:4e:a6:37:0a:9e:93:5e:87:
- 5b:e9:90:d6:a8:b6:65:08:8d:61:49:eb:83:20:a9:5d:1b:16:
- 60:62:6b:2f:54:fb:5a:02:0d:7a:27:e2:4b:e1:05:14:c2:e4:
- e9:f9:70:c0:d9:f7:34:65:0e:a2:91:4b:ac:28:f2:b7:08:0f:
- 98:ca:d7:3e:70:b6:c8:0b:f1:8b:9c:51:f8:c6:10:6c:d2:53:
- 4f:62:8c:11:00:3e:88:df:bf:e6:d2:cc:70:bd:ed:25:9c:fb:
- dd:24:0a:bd:59:91:4a:42:03:38:12:71:32:88:76:a0:8e:7c:
- bb:32:ef:88:2a:1b:d4:6a:6f:50:b9:52:67:8b:ab:30:fa:1f:
- fd:e3:24:9a
------BEGIN CERTIFICATE-----
-MIIEpjCCA46gAwIBAgIQKByJKWYUQ4BCY1U6MkCuszANBgkqhkiG9w0BAQsFADCB
-mDELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsT
-MChjKSAyMDA4IEdlb1RydXN0IEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25s
-eTE2MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhv
-cml0eSAtIEczMB4XDTE1MDYzMDAwMDAwMFoXDTI1MDYyOTIzNTk1OVowRzELMAkG
-A1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xIDAeBgNVBAMTF1JhcGlk
-U1NMIFNIQTI1NiBDQSAtIEc0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
-AQEAwJ46D5qyutPS3BXs0DBUWTBNQFGuQnFx0o1Tc4H+uODElsWOfsLxt2NKz6ce
-P6jnzlOg+i331ubOcBGm7uEDUtJo3j0IDYf9HNcLl2JtgjB2G0c6xPfO7R18jLcX
-jlOAHh0PXYz5kOQEHgJ+y7BJ79pSJfv7Z+3dhHRZhA7z3nBmjeRSOPdTWjcTZws+
-u6hYty7t/7deEXO5d0VSZ0auxNwkgYl2CsqhbGZzBIKq9XBsXxuaAHlG1n96Jhcw
-zzlLLHTZiUR2ENDt94u7iQV1TQsNs9rpv/FqfSoR2x6fjOPEBmnhHYhFOdFuVdiq
-t5tv6vTerBcRkl1Am4N7muL3qQIDAQABo4IBOjCCATYwLgYIKwYBBQUHAQEEIjAg
-MB4GCCsGAQUFBzABhhJodHRwOi8vZy5zeW1jZC5jb20wEgYDVR0TAQH/BAgwBgEB
-/wIBADBJBgNVHSAEQjBAMD4GBmeBDAECATA0MDIGCCsGAQUFBwIBFiZodHRwczov
-L3d3dy5nZW90cnVzdC5jb20vcmVzb3VyY2VzL2NwczA2BgNVHR8ELzAtMCugKaAn
-hiVodHRwOi8vZy5zeW1jYi5jb20vR2VvVHJ1c3RQQ0EtRzMuY3JsMB0GA1UdJQQW
-MBQGCCsGAQUFBwMBBggrBgEFBQcDAjAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE
-FPO1VgzECbC0zx+q+d0jVvB36KH5MB8GA1UdIwQYMBaAFMR5yo6hTgMdHNxr2zFb
-lD4/MH8tMA0GCSqGSIb3DQEBCwUAA4IBAQDDftiDSwRMVSkqTxSdmm7ekHDBpCZM
-iI54SO+9nLCg9fBm/P5ZJuF578i3YGSoi0fqL+CDmdpBGdfFvgX68pAR8Ar/bNwF
-tNgGb6Rvjb4gK1Tb+aJFg5oepSGJNR18IFwX/QQuRdiyxvhCmfxUCE5LgF85N7qV
-TqY3Cp6TXodb6ZDWqLZlCI1hSeuDIKldGxZgYmsvVPtaAg16J+JL4QUUwuTp+XDA
-2fc0ZQ6ikUusKPK3CA+Yytc+cLbIC/GLnFH4xhBs0lNPYowRAD6I37/m0sxwve0l
-nPvdJAq9WZFKQgM4EnEyiHagjny7Mu+IKhvUam9QuVJni6sw+h/94ySa
------END CERTIFICATE-----
-#endif
-static const unsigned char kDERCert24[] = {
- 0x30, 0x82, 0x04, 0xa6, 0x30, 0x82, 0x03, 0x8e, 0xa0, 0x03, 0x02, 0x01,
- 0x02, 0x02, 0x10, 0x28, 0x1c, 0x89, 0x29, 0x66, 0x14, 0x43, 0x80, 0x42,
- 0x63, 0x55, 0x3a, 0x32, 0x40, 0xae, 0xb3, 0x30, 0x0d, 0x06, 0x09, 0x2a,
- 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x81,
- 0x98, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
- 0x55, 0x53, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13,
- 0x0d, 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x49, 0x6e,
- 0x63, 0x2e, 0x31, 0x39, 0x30, 0x37, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13,
- 0x30, 0x28, 0x63, 0x29, 0x20, 0x32, 0x30, 0x30, 0x38, 0x20, 0x47, 0x65,
- 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x20,
- 0x2d, 0x20, 0x46, 0x6f, 0x72, 0x20, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72,
- 0x69, 0x7a, 0x65, 0x64, 0x20, 0x75, 0x73, 0x65, 0x20, 0x6f, 0x6e, 0x6c,
- 0x79, 0x31, 0x36, 0x30, 0x34, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x2d,
- 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x50, 0x72, 0x69,
- 0x6d, 0x61, 0x72, 0x79, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69,
- 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f,
- 0x72, 0x69, 0x74, 0x79, 0x20, 0x2d, 0x20, 0x47, 0x33, 0x30, 0x1e, 0x17,
- 0x0d, 0x31, 0x35, 0x30, 0x36, 0x33, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
- 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x35, 0x30, 0x36, 0x32, 0x39, 0x32, 0x33,
- 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x47, 0x31, 0x0b, 0x30, 0x09, 0x06,
- 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x16, 0x30, 0x14,
- 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0d, 0x47, 0x65, 0x6f, 0x54, 0x72,
- 0x75, 0x73, 0x74, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x20, 0x30, 0x1e,
- 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x17, 0x52, 0x61, 0x70, 0x69, 0x64,
- 0x53, 0x53, 0x4c, 0x20, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, 0x20, 0x43,
- 0x41, 0x20, 0x2d, 0x20, 0x47, 0x34, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d,
- 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05,
- 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82,
- 0x01, 0x01, 0x00, 0xc0, 0x9e, 0x3a, 0x0f, 0x9a, 0xb2, 0xba, 0xd3, 0xd2,
- 0xdc, 0x15, 0xec, 0xd0, 0x30, 0x54, 0x59, 0x30, 0x4d, 0x40, 0x51, 0xae,
- 0x42, 0x71, 0x71, 0xd2, 0x8d, 0x53, 0x73, 0x81, 0xfe, 0xb8, 0xe0, 0xc4,
- 0x96, 0xc5, 0x8e, 0x7e, 0xc2, 0xf1, 0xb7, 0x63, 0x4a, 0xcf, 0xa7, 0x1e,
- 0x3f, 0xa8, 0xe7, 0xce, 0x53, 0xa0, 0xfa, 0x2d, 0xf7, 0xd6, 0xe6, 0xce,
- 0x70, 0x11, 0xa6, 0xee, 0xe1, 0x03, 0x52, 0xd2, 0x68, 0xde, 0x3d, 0x08,
- 0x0d, 0x87, 0xfd, 0x1c, 0xd7, 0x0b, 0x97, 0x62, 0x6d, 0x82, 0x30, 0x76,
- 0x1b, 0x47, 0x3a, 0xc4, 0xf7, 0xce, 0xed, 0x1d, 0x7c, 0x8c, 0xb7, 0x17,
- 0x8e, 0x53, 0x80, 0x1e, 0x1d, 0x0f, 0x5d, 0x8c, 0xf9, 0x90, 0xe4, 0x04,
- 0x1e, 0x02, 0x7e, 0xcb, 0xb0, 0x49, 0xef, 0xda, 0x52, 0x25, 0xfb, 0xfb,
- 0x67, 0xed, 0xdd, 0x84, 0x74, 0x59, 0x84, 0x0e, 0xf3, 0xde, 0x70, 0x66,
- 0x8d, 0xe4, 0x52, 0x38, 0xf7, 0x53, 0x5a, 0x37, 0x13, 0x67, 0x0b, 0x3e,
- 0xbb, 0xa8, 0x58, 0xb7, 0x2e, 0xed, 0xff, 0xb7, 0x5e, 0x11, 0x73, 0xb9,
- 0x77, 0x45, 0x52, 0x67, 0x46, 0xae, 0xc4, 0xdc, 0x24, 0x81, 0x89, 0x76,
- 0x0a, 0xca, 0xa1, 0x6c, 0x66, 0x73, 0x04, 0x82, 0xaa, 0xf5, 0x70, 0x6c,
- 0x5f, 0x1b, 0x9a, 0x00, 0x79, 0x46, 0xd6, 0x7f, 0x7a, 0x26, 0x17, 0x30,
- 0xcf, 0x39, 0x4b, 0x2c, 0x74, 0xd9, 0x89, 0x44, 0x76, 0x10, 0xd0, 0xed,
- 0xf7, 0x8b, 0xbb, 0x89, 0x05, 0x75, 0x4d, 0x0b, 0x0d, 0xb3, 0xda, 0xe9,
- 0xbf, 0xf1, 0x6a, 0x7d, 0x2a, 0x11, 0xdb, 0x1e, 0x9f, 0x8c, 0xe3, 0xc4,
- 0x06, 0x69, 0xe1, 0x1d, 0x88, 0x45, 0x39, 0xd1, 0x6e, 0x55, 0xd8, 0xaa,
- 0xb7, 0x9b, 0x6f, 0xea, 0xf4, 0xde, 0xac, 0x17, 0x11, 0x92, 0x5d, 0x40,
- 0x9b, 0x83, 0x7b, 0x9a, 0xe2, 0xf7, 0xa9, 0x02, 0x03, 0x01, 0x00, 0x01,
- 0xa3, 0x82, 0x01, 0x3a, 0x30, 0x82, 0x01, 0x36, 0x30, 0x2e, 0x06, 0x08,
- 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x22, 0x30, 0x20,
- 0x30, 0x1e, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01,
- 0x86, 0x12, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x67, 0x2e, 0x73,
- 0x79, 0x6d, 0x63, 0x64, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x12, 0x06, 0x03,
- 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01,
- 0xff, 0x02, 0x01, 0x00, 0x30, 0x49, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04,
- 0x42, 0x30, 0x40, 0x30, 0x3e, 0x06, 0x06, 0x67, 0x81, 0x0c, 0x01, 0x02,
- 0x01, 0x30, 0x34, 0x30, 0x32, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05,
- 0x07, 0x02, 0x01, 0x16, 0x26, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f,
- 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x67, 0x65, 0x6f, 0x74, 0x72, 0x75, 0x73,
- 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72,
- 0x63, 0x65, 0x73, 0x2f, 0x63, 0x70, 0x73, 0x30, 0x36, 0x06, 0x03, 0x55,
- 0x1d, 0x1f, 0x04, 0x2f, 0x30, 0x2d, 0x30, 0x2b, 0xa0, 0x29, 0xa0, 0x27,
- 0x86, 0x25, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x67, 0x2e, 0x73,
- 0x79, 0x6d, 0x63, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x47, 0x65, 0x6f,
- 0x54, 0x72, 0x75, 0x73, 0x74, 0x50, 0x43, 0x41, 0x2d, 0x47, 0x33, 0x2e,
- 0x63, 0x72, 0x6c, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04, 0x16,
- 0x30, 0x14, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x01,
- 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x02, 0x30, 0x0e,
- 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02,
- 0x01, 0x06, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04,
- 0x14, 0xf3, 0xb5, 0x56, 0x0c, 0xc4, 0x09, 0xb0, 0xb4, 0xcf, 0x1f, 0xaa,
- 0xf9, 0xdd, 0x23, 0x56, 0xf0, 0x77, 0xe8, 0xa1, 0xf9, 0x30, 0x1f, 0x06,
- 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0xc4, 0x79,
- 0xca, 0x8e, 0xa1, 0x4e, 0x03, 0x1d, 0x1c, 0xdc, 0x6b, 0xdb, 0x31, 0x5b,
- 0x94, 0x3e, 0x3f, 0x30, 0x7f, 0x2d, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
- 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01,
- 0x01, 0x00, 0xc3, 0x7e, 0xd8, 0x83, 0x4b, 0x04, 0x4c, 0x55, 0x29, 0x2a,
- 0x4f, 0x14, 0x9d, 0x9a, 0x6e, 0xde, 0x90, 0x70, 0xc1, 0xa4, 0x26, 0x4c,
- 0x88, 0x8e, 0x78, 0x48, 0xef, 0xbd, 0x9c, 0xb0, 0xa0, 0xf5, 0xf0, 0x66,
- 0xfc, 0xfe, 0x59, 0x26, 0xe1, 0x79, 0xef, 0xc8, 0xb7, 0x60, 0x64, 0xa8,
- 0x8b, 0x47, 0xea, 0x2f, 0xe0, 0x83, 0x99, 0xda, 0x41, 0x19, 0xd7, 0xc5,
- 0xbe, 0x05, 0xfa, 0xf2, 0x90, 0x11, 0xf0, 0x0a, 0xff, 0x6c, 0xdc, 0x05,
- 0xb4, 0xd8, 0x06, 0x6f, 0xa4, 0x6f, 0x8d, 0xbe, 0x20, 0x2b, 0x54, 0xdb,
- 0xf9, 0xa2, 0x45, 0x83, 0x9a, 0x1e, 0xa5, 0x21, 0x89, 0x35, 0x1d, 0x7c,
- 0x20, 0x5c, 0x17, 0xfd, 0x04, 0x2e, 0x45, 0xd8, 0xb2, 0xc6, 0xf8, 0x42,
- 0x99, 0xfc, 0x54, 0x08, 0x4e, 0x4b, 0x80, 0x5f, 0x39, 0x37, 0xba, 0x95,
- 0x4e, 0xa6, 0x37, 0x0a, 0x9e, 0x93, 0x5e, 0x87, 0x5b, 0xe9, 0x90, 0xd6,
- 0xa8, 0xb6, 0x65, 0x08, 0x8d, 0x61, 0x49, 0xeb, 0x83, 0x20, 0xa9, 0x5d,
- 0x1b, 0x16, 0x60, 0x62, 0x6b, 0x2f, 0x54, 0xfb, 0x5a, 0x02, 0x0d, 0x7a,
- 0x27, 0xe2, 0x4b, 0xe1, 0x05, 0x14, 0xc2, 0xe4, 0xe9, 0xf9, 0x70, 0xc0,
- 0xd9, 0xf7, 0x34, 0x65, 0x0e, 0xa2, 0x91, 0x4b, 0xac, 0x28, 0xf2, 0xb7,
- 0x08, 0x0f, 0x98, 0xca, 0xd7, 0x3e, 0x70, 0xb6, 0xc8, 0x0b, 0xf1, 0x8b,
- 0x9c, 0x51, 0xf8, 0xc6, 0x10, 0x6c, 0xd2, 0x53, 0x4f, 0x62, 0x8c, 0x11,
- 0x00, 0x3e, 0x88, 0xdf, 0xbf, 0xe6, 0xd2, 0xcc, 0x70, 0xbd, 0xed, 0x25,
- 0x9c, 0xfb, 0xdd, 0x24, 0x0a, 0xbd, 0x59, 0x91, 0x4a, 0x42, 0x03, 0x38,
- 0x12, 0x71, 0x32, 0x88, 0x76, 0xa0, 0x8e, 0x7c, 0xbb, 0x32, 0xef, 0x88,
- 0x2a, 0x1b, 0xd4, 0x6a, 0x6f, 0x50, 0xb9, 0x52, 0x67, 0x8b, 0xab, 0x30,
- 0xfa, 0x1f, 0xfd, 0xe3, 0x24, 0x9a,
-};
-
-#if 0
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number:
- 5d:72:fb:33:76:20:f6:4c:72:80:db:e9:12:81:ff:6a
- Signature Algorithm: sha256WithRSAEncryption
- Issuer: C=US, O=thawte, Inc., OU=Certification Services Division, OU=(c) 2006 thawte, Inc. - For authorized use only, CN=thawte Primary Root CA
- Validity
- Not Before: Oct 31 00:00:00 2013 GMT
- Not After : Oct 30 23:59:59 2023 GMT
- Subject: C=US, O=thawte, Inc., CN=thawte EV SSL CA - G3
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:c4:dd:da:94:1e:32:b2:2e:a0:83:c0:a6:7d:5f:
- 65:2d:fd:27:b8:73:0e:f8:0b:a9:d4:56:26:69:98:
- 67:35:39:64:58:ce:82:6f:98:94:d1:8f:e0:90:d6:
- ed:55:4b:98:4b:d7:10:59:34:02:1b:e7:51:31:51:
- c4:38:c2:bc:db:03:5c:ca:e1:7c:dc:4f:59:97:ea:
- 07:7f:0f:85:3e:92:ea:aa:a7:d9:be:01:41:e4:62:
- 56:47:36:bd:57:91:e6:21:d3:f8:41:0b:d8:ba:e8:
- ed:81:ad:70:c0:8b:6e:f3:89:6e:27:9e:a6:a6:73:
- 59:bb:71:00:d4:4f:4b:48:e9:d5:c9:27:36:9c:7c:
- 1c:02:aa:ac:bd:3b:d1:53:83:6a:1f:e6:08:47:33:
- a7:b1:9f:02:be:9b:47:ed:33:04:dc:1c:80:27:d1:
- 4a:33:a0:8c:eb:01:47:a1:32:90:64:7b:c4:e0:84:
- c9:32:e9:dd:34:1f:8a:68:67:f3:ad:10:63:eb:ee:
- 8a:9a:b1:2a:1b:26:74:a1:2a:b0:8f:fe:52:98:46:
- 97:cf:a3:56:1c:6f:6e:99:97:8d:26:0e:a9:ec:c2:
- 53:70:fc:7a:a5:19:49:bd:b5:17:82:55:de:97:e0:
- 5d:62:84:81:f0:70:a8:34:53:4f:14:fd:3d:5d:3d:
- 6f:b9
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Basic Constraints: critical
- CA:TRUE, pathlen:0
- X509v3 Key Usage: critical
- Certificate Sign, CRL Sign
- Authority Information Access:
- OCSP - URI:http://t2.symcb.com
-
- X509v3 Certificate Policies:
- Policy: X509v3 Any Policy
- CPS: https://www.thawte.com/cps
-
- X509v3 CRL Distribution Points:
-
- Full Name:
- URI:http://t1.symcb.com/ThawtePCA.crl
-
- X509v3 Subject Alternative Name:
- DirName:/CN=SymantecPKI-1-536
- X509v3 Subject Key Identifier:
- F0:70:51:DA:D3:2A:91:4F:52:77:D7:86:77:74:0F:CE:71:1A:6C:22
- X509v3 Authority Key Identifier:
- keyid:7B:5B:45:CF:AF:CE:CB:7A:FD:31:92:1A:6A:B6:F3:46:EB:57:48:50
-
- Signature Algorithm: sha256WithRSAEncryption
- a1:2e:94:3e:9b:16:f4:58:1a:6f:c1:fa:c1:7e:43:93:b2:c3:
- f7:89:eb:13:62:5d:dd:cc:61:13:2b:1d:4e:88:79:11:62:14:
- 37:30:46:ff:89:62:10:85:2a:87:1e:f8:e2:af:fe:93:02:93:
- ca:f2:e9:46:03:6b:a1:1a:ac:d5:f0:80:1b:98:6f:b8:3a:50:
- f8:54:71:06:03:e7:84:cc:8e:61:d2:5f:4d:0c:97:02:65:b5:
- 8c:26:bc:05:98:f4:dc:c6:af:e4:57:7f:e3:dc:a1:d7:27:47:
- 2a:e0:2c:3f:09:74:dc:5a:e5:b5:7c:fa:82:9a:15:fa:74:2b:
- 84:2e:6b:ac:ef:35:a6:30:fa:47:4a:aa:36:44:f6:5a:91:07:
- d3:e4:4e:97:3f:a6:53:d8:29:33:32:6f:8b:3d:b5:a5:0d:e5:
- e4:8a:e8:f5:c0:fa:af:d8:37:28:27:c3:ed:34:31:d9:7c:a6:
- af:4d:12:4f:d0:2b:92:9c:69:95:f2:28:a6:fe:a8:c6:e0:2c:
- 4d:36:eb:11:34:d6:e1:81:99:9d:41:f2:e7:c5:57:05:0e:19:
- ca:af:42:39:1f:a7:27:5e:e0:0a:17:b8:ae:47:ab:92:f1:8a:
- 04:df:30:e0:bb:4f:8a:f9:1b:88:4f:03:b4:25:7a:78:de:2e:
- 7d:29:d1:31
------BEGIN CERTIFICATE-----
-MIIErzCCA5egAwIBAgIQXXL7M3Yg9kxygNvpEoH/ajANBgkqhkiG9w0BAQsFADCB
-qTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMf
-Q2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIw
-MDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxHzAdBgNV
-BAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwHhcNMTMxMDMxMDAwMDAwWhcNMjMx
-MDMwMjM1OTU5WjBEMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMdGhhd3RlLCBJbmMu
-MR4wHAYDVQQDExV0aGF3dGUgRVYgU1NMIENBIC0gRzMwggEiMA0GCSqGSIb3DQEB
-AQUAA4IBDwAwggEKAoIBAQDE3dqUHjKyLqCDwKZ9X2Ut/Se4cw74C6nUViZpmGc1
-OWRYzoJvmJTRj+CQ1u1VS5hL1xBZNAIb51ExUcQ4wrzbA1zK4XzcT1mX6gd/D4U+
-kuqqp9m+AUHkYlZHNr1XkeYh0/hBC9i66O2BrXDAi27ziW4nnqamc1m7cQDUT0tI
-6dXJJzacfBwCqqy9O9FTg2of5ghHM6exnwK+m0ftMwTcHIAn0UozoIzrAUehMpBk
-e8TghMky6d00H4poZ/OtEGPr7oqasSobJnShKrCP/lKYRpfPo1Ycb26Zl40mDqns
-wlNw/HqlGUm9tReCVd6X4F1ihIHwcKg0U08U/T1dPW+5AgMBAAGjggE1MIIBMTAS
-BgNVHRMBAf8ECDAGAQH/AgEAMA4GA1UdDwEB/wQEAwIBBjAvBggrBgEFBQcBAQQj
-MCEwHwYIKwYBBQUHMAGGE2h0dHA6Ly90Mi5zeW1jYi5jb20wOwYDVR0gBDQwMjAw
-BgRVHSAAMCgwJgYIKwYBBQUHAgEWGmh0dHBzOi8vd3d3LnRoYXd0ZS5jb20vY3Bz
-MDIGA1UdHwQrMCkwJ6AloCOGIWh0dHA6Ly90MS5zeW1jYi5jb20vVGhhd3RlUENB
-LmNybDApBgNVHREEIjAgpB4wHDEaMBgGA1UEAxMRU3ltYW50ZWNQS0ktMS01MzYw
-HQYDVR0OBBYEFPBwUdrTKpFPUnfXhnd0D85xGmwiMB8GA1UdIwQYMBaAFHtbRc+v
-zst6/TGSGmq280brV0hQMA0GCSqGSIb3DQEBCwUAA4IBAQChLpQ+mxb0WBpvwfrB
-fkOTssP3iesTYl3dzGETKx1OiHkRYhQ3MEb/iWIQhSqHHvjir/6TApPK8ulGA2uh
-GqzV8IAbmG+4OlD4VHEGA+eEzI5h0l9NDJcCZbWMJrwFmPTcxq/kV3/j3KHXJ0cq
-4Cw/CXTcWuW1fPqCmhX6dCuELmus7zWmMPpHSqo2RPZakQfT5E6XP6ZT2CkzMm+L
-PbWlDeXkiuj1wPqv2DcoJ8PtNDHZfKavTRJP0CuSnGmV8iim/qjG4CxNNusRNNbh
-gZmdQfLnxVcFDhnKr0I5H6cnXuAKF7iuR6uS8YoE3zDgu0+K+RuITwO0JXp43i59
-KdEx
------END CERTIFICATE-----
-#endif
-static const unsigned char kDERCert25[] = {
- 0x30, 0x82, 0x04, 0xaf, 0x30, 0x82, 0x03, 0x97, 0xa0, 0x03, 0x02, 0x01,
- 0x02, 0x02, 0x10, 0x5d, 0x72, 0xfb, 0x33, 0x76, 0x20, 0xf6, 0x4c, 0x72,
- 0x80, 0xdb, 0xe9, 0x12, 0x81, 0xff, 0x6a, 0x30, 0x0d, 0x06, 0x09, 0x2a,
- 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x81,
- 0xa9, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
- 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13,
- 0x0c, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63,
- 0x2e, 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1f,
- 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f,
- 0x6e, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, 0x44,
- 0x69, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x31, 0x38, 0x30, 0x36, 0x06,
- 0x03, 0x55, 0x04, 0x0b, 0x13, 0x2f, 0x28, 0x63, 0x29, 0x20, 0x32, 0x30,
- 0x30, 0x36, 0x20, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2c, 0x20, 0x49,
- 0x6e, 0x63, 0x2e, 0x20, 0x2d, 0x20, 0x46, 0x6f, 0x72, 0x20, 0x61, 0x75,
- 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x20, 0x75, 0x73, 0x65,
- 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55,
- 0x04, 0x03, 0x13, 0x16, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x20, 0x50,
- 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20,
- 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x33, 0x31, 0x30, 0x33, 0x31,
- 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x33, 0x31,
- 0x30, 0x33, 0x30, 0x32, 0x33, 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x44,
- 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55,
- 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0c,
- 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e,
- 0x31, 0x1e, 0x30, 0x1c, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x15, 0x74,
- 0x68, 0x61, 0x77, 0x74, 0x65, 0x20, 0x45, 0x56, 0x20, 0x53, 0x53, 0x4c,
- 0x20, 0x43, 0x41, 0x20, 0x2d, 0x20, 0x47, 0x33, 0x30, 0x82, 0x01, 0x22,
- 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
- 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a,
- 0x02, 0x82, 0x01, 0x01, 0x00, 0xc4, 0xdd, 0xda, 0x94, 0x1e, 0x32, 0xb2,
- 0x2e, 0xa0, 0x83, 0xc0, 0xa6, 0x7d, 0x5f, 0x65, 0x2d, 0xfd, 0x27, 0xb8,
- 0x73, 0x0e, 0xf8, 0x0b, 0xa9, 0xd4, 0x56, 0x26, 0x69, 0x98, 0x67, 0x35,
- 0x39, 0x64, 0x58, 0xce, 0x82, 0x6f, 0x98, 0x94, 0xd1, 0x8f, 0xe0, 0x90,
- 0xd6, 0xed, 0x55, 0x4b, 0x98, 0x4b, 0xd7, 0x10, 0x59, 0x34, 0x02, 0x1b,
- 0xe7, 0x51, 0x31, 0x51, 0xc4, 0x38, 0xc2, 0xbc, 0xdb, 0x03, 0x5c, 0xca,
- 0xe1, 0x7c, 0xdc, 0x4f, 0x59, 0x97, 0xea, 0x07, 0x7f, 0x0f, 0x85, 0x3e,
- 0x92, 0xea, 0xaa, 0xa7, 0xd9, 0xbe, 0x01, 0x41, 0xe4, 0x62, 0x56, 0x47,
- 0x36, 0xbd, 0x57, 0x91, 0xe6, 0x21, 0xd3, 0xf8, 0x41, 0x0b, 0xd8, 0xba,
- 0xe8, 0xed, 0x81, 0xad, 0x70, 0xc0, 0x8b, 0x6e, 0xf3, 0x89, 0x6e, 0x27,
- 0x9e, 0xa6, 0xa6, 0x73, 0x59, 0xbb, 0x71, 0x00, 0xd4, 0x4f, 0x4b, 0x48,
- 0xe9, 0xd5, 0xc9, 0x27, 0x36, 0x9c, 0x7c, 0x1c, 0x02, 0xaa, 0xac, 0xbd,
- 0x3b, 0xd1, 0x53, 0x83, 0x6a, 0x1f, 0xe6, 0x08, 0x47, 0x33, 0xa7, 0xb1,
- 0x9f, 0x02, 0xbe, 0x9b, 0x47, 0xed, 0x33, 0x04, 0xdc, 0x1c, 0x80, 0x27,
- 0xd1, 0x4a, 0x33, 0xa0, 0x8c, 0xeb, 0x01, 0x47, 0xa1, 0x32, 0x90, 0x64,
- 0x7b, 0xc4, 0xe0, 0x84, 0xc9, 0x32, 0xe9, 0xdd, 0x34, 0x1f, 0x8a, 0x68,
- 0x67, 0xf3, 0xad, 0x10, 0x63, 0xeb, 0xee, 0x8a, 0x9a, 0xb1, 0x2a, 0x1b,
- 0x26, 0x74, 0xa1, 0x2a, 0xb0, 0x8f, 0xfe, 0x52, 0x98, 0x46, 0x97, 0xcf,
- 0xa3, 0x56, 0x1c, 0x6f, 0x6e, 0x99, 0x97, 0x8d, 0x26, 0x0e, 0xa9, 0xec,
- 0xc2, 0x53, 0x70, 0xfc, 0x7a, 0xa5, 0x19, 0x49, 0xbd, 0xb5, 0x17, 0x82,
- 0x55, 0xde, 0x97, 0xe0, 0x5d, 0x62, 0x84, 0x81, 0xf0, 0x70, 0xa8, 0x34,
- 0x53, 0x4f, 0x14, 0xfd, 0x3d, 0x5d, 0x3d, 0x6f, 0xb9, 0x02, 0x03, 0x01,
- 0x00, 0x01, 0xa3, 0x82, 0x01, 0x35, 0x30, 0x82, 0x01, 0x31, 0x30, 0x12,
- 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06,
- 0x01, 0x01, 0xff, 0x02, 0x01, 0x00, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d,
- 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x2f,
- 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x23,
- 0x30, 0x21, 0x30, 0x1f, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
- 0x30, 0x01, 0x86, 0x13, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x74,
- 0x32, 0x2e, 0x73, 0x79, 0x6d, 0x63, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x30,
- 0x3b, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x34, 0x30, 0x32, 0x30, 0x30,
- 0x06, 0x04, 0x55, 0x1d, 0x20, 0x00, 0x30, 0x28, 0x30, 0x26, 0x06, 0x08,
- 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x1a, 0x68, 0x74,
- 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x74, 0x68,
- 0x61, 0x77, 0x74, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x70, 0x73,
- 0x30, 0x32, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x2b, 0x30, 0x29, 0x30,
- 0x27, 0xa0, 0x25, 0xa0, 0x23, 0x86, 0x21, 0x68, 0x74, 0x74, 0x70, 0x3a,
- 0x2f, 0x2f, 0x74, 0x31, 0x2e, 0x73, 0x79, 0x6d, 0x63, 0x62, 0x2e, 0x63,
- 0x6f, 0x6d, 0x2f, 0x54, 0x68, 0x61, 0x77, 0x74, 0x65, 0x50, 0x43, 0x41,
- 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x29, 0x06, 0x03, 0x55, 0x1d, 0x11, 0x04,
- 0x22, 0x30, 0x20, 0xa4, 0x1e, 0x30, 0x1c, 0x31, 0x1a, 0x30, 0x18, 0x06,
- 0x03, 0x55, 0x04, 0x03, 0x13, 0x11, 0x53, 0x79, 0x6d, 0x61, 0x6e, 0x74,
- 0x65, 0x63, 0x50, 0x4b, 0x49, 0x2d, 0x31, 0x2d, 0x35, 0x33, 0x36, 0x30,
- 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xf0, 0x70,
- 0x51, 0xda, 0xd3, 0x2a, 0x91, 0x4f, 0x52, 0x77, 0xd7, 0x86, 0x77, 0x74,
- 0x0f, 0xce, 0x71, 0x1a, 0x6c, 0x22, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d,
- 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x7b, 0x5b, 0x45, 0xcf, 0xaf,
- 0xce, 0xcb, 0x7a, 0xfd, 0x31, 0x92, 0x1a, 0x6a, 0xb6, 0xf3, 0x46, 0xeb,
- 0x57, 0x48, 0x50, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
- 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0xa1,
- 0x2e, 0x94, 0x3e, 0x9b, 0x16, 0xf4, 0x58, 0x1a, 0x6f, 0xc1, 0xfa, 0xc1,
- 0x7e, 0x43, 0x93, 0xb2, 0xc3, 0xf7, 0x89, 0xeb, 0x13, 0x62, 0x5d, 0xdd,
- 0xcc, 0x61, 0x13, 0x2b, 0x1d, 0x4e, 0x88, 0x79, 0x11, 0x62, 0x14, 0x37,
- 0x30, 0x46, 0xff, 0x89, 0x62, 0x10, 0x85, 0x2a, 0x87, 0x1e, 0xf8, 0xe2,
- 0xaf, 0xfe, 0x93, 0x02, 0x93, 0xca, 0xf2, 0xe9, 0x46, 0x03, 0x6b, 0xa1,
- 0x1a, 0xac, 0xd5, 0xf0, 0x80, 0x1b, 0x98, 0x6f, 0xb8, 0x3a, 0x50, 0xf8,
- 0x54, 0x71, 0x06, 0x03, 0xe7, 0x84, 0xcc, 0x8e, 0x61, 0xd2, 0x5f, 0x4d,
- 0x0c, 0x97, 0x02, 0x65, 0xb5, 0x8c, 0x26, 0xbc, 0x05, 0x98, 0xf4, 0xdc,
- 0xc6, 0xaf, 0xe4, 0x57, 0x7f, 0xe3, 0xdc, 0xa1, 0xd7, 0x27, 0x47, 0x2a,
- 0xe0, 0x2c, 0x3f, 0x09, 0x74, 0xdc, 0x5a, 0xe5, 0xb5, 0x7c, 0xfa, 0x82,
- 0x9a, 0x15, 0xfa, 0x74, 0x2b, 0x84, 0x2e, 0x6b, 0xac, 0xef, 0x35, 0xa6,
- 0x30, 0xfa, 0x47, 0x4a, 0xaa, 0x36, 0x44, 0xf6, 0x5a, 0x91, 0x07, 0xd3,
- 0xe4, 0x4e, 0x97, 0x3f, 0xa6, 0x53, 0xd8, 0x29, 0x33, 0x32, 0x6f, 0x8b,
- 0x3d, 0xb5, 0xa5, 0x0d, 0xe5, 0xe4, 0x8a, 0xe8, 0xf5, 0xc0, 0xfa, 0xaf,
- 0xd8, 0x37, 0x28, 0x27, 0xc3, 0xed, 0x34, 0x31, 0xd9, 0x7c, 0xa6, 0xaf,
- 0x4d, 0x12, 0x4f, 0xd0, 0x2b, 0x92, 0x9c, 0x69, 0x95, 0xf2, 0x28, 0xa6,
- 0xfe, 0xa8, 0xc6, 0xe0, 0x2c, 0x4d, 0x36, 0xeb, 0x11, 0x34, 0xd6, 0xe1,
- 0x81, 0x99, 0x9d, 0x41, 0xf2, 0xe7, 0xc5, 0x57, 0x05, 0x0e, 0x19, 0xca,
- 0xaf, 0x42, 0x39, 0x1f, 0xa7, 0x27, 0x5e, 0xe0, 0x0a, 0x17, 0xb8, 0xae,
- 0x47, 0xab, 0x92, 0xf1, 0x8a, 0x04, 0xdf, 0x30, 0xe0, 0xbb, 0x4f, 0x8a,
- 0xf9, 0x1b, 0x88, 0x4f, 0x03, 0xb4, 0x25, 0x7a, 0x78, 0xde, 0x2e, 0x7d,
- 0x29, 0xd1, 0x31,
-};
-
-#if 0
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number:
- 04:e1:e7:a4:dc:5c:f2:f3:6d:c0:2b:42:b8:5d:15:9f
- Signature Algorithm: sha256WithRSAEncryption
- Issuer: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert High Assurance EV Root CA
- Validity
- Not Before: Oct 22 12:00:00 2013 GMT
- Not After : Oct 22 12:00:00 2028 GMT
- Subject: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert SHA2 High Assurance Server CA
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:b6:e0:2f:c2:24:06:c8:6d:04:5f:d7:ef:0a:64:
- 06:b2:7d:22:26:65:16:ae:42:40:9b:ce:dc:9f:9f:
- 76:07:3e:c3:30:55:87:19:b9:4f:94:0e:5a:94:1f:
- 55:56:b4:c2:02:2a:af:d0:98:ee:0b:40:d7:c4:d0:
- 3b:72:c8:14:9e:ef:90:b1:11:a9:ae:d2:c8:b8:43:
- 3a:d9:0b:0b:d5:d5:95:f5:40:af:c8:1d:ed:4d:9c:
- 5f:57:b7:86:50:68:99:f5:8a:da:d2:c7:05:1f:a8:
- 97:c9:dc:a4:b1:82:84:2d:c6:ad:a5:9c:c7:19:82:
- a6:85:0f:5e:44:58:2a:37:8f:fd:35:f1:0b:08:27:
- 32:5a:f5:bb:8b:9e:a4:bd:51:d0:27:e2:dd:3b:42:
- 33:a3:05:28:c4:bb:28:cc:9a:ac:2b:23:0d:78:c6:
- 7b:e6:5e:71:b7:4a:3e:08:fb:81:b7:16:16:a1:9d:
- 23:12:4d:e5:d7:92:08:ac:75:a4:9c:ba:cd:17:b2:
- 1e:44:35:65:7f:53:25:39:d1:1c:0a:9a:63:1b:19:
- 92:74:68:0a:37:c2:c2:52:48:cb:39:5a:a2:b6:e1:
- 5d:c1:dd:a0:20:b8:21:a2:93:26:6f:14:4a:21:41:
- c7:ed:6d:9b:f2:48:2f:f3:03:f5:a2:68:92:53:2f:
- 5e:e3
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Basic Constraints: critical
- CA:TRUE, pathlen:0
- X509v3 Key Usage: critical
- Digital Signature, Certificate Sign, CRL Sign
- X509v3 Extended Key Usage:
- TLS Web Server Authentication, TLS Web Client Authentication
- Authority Information Access:
- OCSP - URI:http://ocsp.digicert.com
-
- X509v3 CRL Distribution Points:
-
- Full Name:
- URI:http://crl4.digicert.com/DigiCertHighAssuranceEVRootCA.crl
-
- X509v3 Certificate Policies:
- Policy: X509v3 Any Policy
- CPS: https://www.digicert.com/CPS
-
- X509v3 Subject Key Identifier:
- 51:68:FF:90:AF:02:07:75:3C:CC:D9:65:64:62:A2:12:B8:59:72:3B
- X509v3 Authority Key Identifier:
- keyid:B1:3E:C3:69:03:F8:BF:47:01:D4:98:26:1A:08:02:EF:63:64:2B:C3
-
- Signature Algorithm: sha256WithRSAEncryption
- 18:8a:95:89:03:e6:6d:df:5c:fc:1d:68:ea:4a:8f:83:d6:51:
- 2f:8d:6b:44:16:9e:ac:63:f5:d2:6e:6c:84:99:8b:aa:81:71:
- 84:5b:ed:34:4e:b0:b7:79:92:29:cc:2d:80:6a:f0:8e:20:e1:
- 79:a4:fe:03:47:13:ea:f5:86:ca:59:71:7d:f4:04:96:6b:d3:
- 59:58:3d:fe:d3:31:25:5c:18:38:84:a3:e6:9f:82:fd:8c:5b:
- 98:31:4e:cd:78:9e:1a:fd:85:cb:49:aa:f2:27:8b:99:72:fc:
- 3e:aa:d5:41:0b:da:d5:36:a1:bf:1c:6e:47:49:7f:5e:d9:48:
- 7c:03:d9:fd:8b:49:a0:98:26:42:40:eb:d6:92:11:a4:64:0a:
- 57:54:c4:f5:1d:d6:02:5e:6b:ac:ee:c4:80:9a:12:72:fa:56:
- 93:d7:ff:bf:30:85:06:30:bf:0b:7f:4e:ff:57:05:9d:24:ed:
- 85:c3:2b:fb:a6:75:a8:ac:2d:16:ef:7d:79:27:b2:eb:c2:9d:
- 0b:07:ea:aa:85:d3:01:a3:20:28:41:59:43:28:d2:81:e3:aa:
- f6:ec:7b:3b:77:b6:40:62:80:05:41:45:01:ef:17:06:3e:de:
- c0:33:9b:67:d3:61:2e:72:87:e4:69:fc:12:00:57:40:1e:70:
- f5:1e:c9:b4
------BEGIN CERTIFICATE-----
-MIIEsTCCA5mgAwIBAgIQBOHnpNxc8vNtwCtCuF0VnzANBgkqhkiG9w0BAQsFADBs
-MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
-d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j
-ZSBFViBSb290IENBMB4XDTEzMTAyMjEyMDAwMFoXDTI4MTAyMjEyMDAwMFowcDEL
-MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3
-LmRpZ2ljZXJ0LmNvbTEvMC0GA1UEAxMmRGlnaUNlcnQgU0hBMiBIaWdoIEFzc3Vy
-YW5jZSBTZXJ2ZXIgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC2
-4C/CJAbIbQRf1+8KZAayfSImZRauQkCbztyfn3YHPsMwVYcZuU+UDlqUH1VWtMIC
-Kq/QmO4LQNfE0DtyyBSe75CxEamu0si4QzrZCwvV1ZX1QK/IHe1NnF9Xt4ZQaJn1
-itrSxwUfqJfJ3KSxgoQtxq2lnMcZgqaFD15EWCo3j/018QsIJzJa9buLnqS9UdAn
-4t07QjOjBSjEuyjMmqwrIw14xnvmXnG3Sj4I+4G3FhahnSMSTeXXkgisdaScus0X
-sh5ENWV/UyU50RwKmmMbGZJ0aAo3wsJSSMs5WqK24V3B3aAguCGikyZvFEohQcft
-bZvySC/zA/WiaJJTL17jAgMBAAGjggFJMIIBRTASBgNVHRMBAf8ECDAGAQH/AgEA
-MA4GA1UdDwEB/wQEAwIBhjAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIw
-NAYIKwYBBQUHAQEEKDAmMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2Vy
-dC5jb20wSwYDVR0fBEQwQjBAoD6gPIY6aHR0cDovL2NybDQuZGlnaWNlcnQuY29t
-L0RpZ2lDZXJ0SGlnaEFzc3VyYW5jZUVWUm9vdENBLmNybDA9BgNVHSAENjA0MDIG
-BFUdIAAwKjAoBggrBgEFBQcCARYcaHR0cHM6Ly93d3cuZGlnaWNlcnQuY29tL0NQ
-UzAdBgNVHQ4EFgQUUWj/kK8CB3U8zNllZGKiErhZcjswHwYDVR0jBBgwFoAUsT7D
-aQP4v0cB1JgmGggC72NkK8MwDQYJKoZIhvcNAQELBQADggEBABiKlYkD5m3fXPwd
-aOpKj4PWUS+Na0QWnqxj9dJubISZi6qBcYRb7TROsLd5kinMLYBq8I4g4Xmk/gNH
-E+r1hspZcX30BJZr01lYPf7TMSVcGDiEo+afgv2MW5gxTs14nhr9hctJqvIni5ly
-/D6q1UEL2tU2ob8cbkdJf17ZSHwD2f2LSaCYJkJA69aSEaRkCldUxPUd1gJea6zu
-xICaEnL6VpPX/78whQYwvwt/Tv9XBZ0k7YXDK/umdaisLRbvfXknsuvCnQsH6qqF
-0wGjIChBWUMo0oHjqvbsezt3tkBigAVBRQHvFwY+3sAzm2fTYS5yh+Rp/BIAV0Ae
-cPUeybQ=
------END CERTIFICATE-----
-#endif
-static const unsigned char kDERCert26[] = {
- 0x30, 0x82, 0x04, 0xb1, 0x30, 0x82, 0x03, 0x99, 0xa0, 0x03, 0x02, 0x01,
- 0x02, 0x02, 0x10, 0x04, 0xe1, 0xe7, 0xa4, 0xdc, 0x5c, 0xf2, 0xf3, 0x6d,
- 0xc0, 0x2b, 0x42, 0xb8, 0x5d, 0x15, 0x9f, 0x30, 0x0d, 0x06, 0x09, 0x2a,
- 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x6c,
- 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55,
- 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0c,
- 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, 0x6e, 0x63,
- 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x10, 0x77,
- 0x77, 0x77, 0x2e, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, 0x74, 0x2e,
- 0x63, 0x6f, 0x6d, 0x31, 0x2b, 0x30, 0x29, 0x06, 0x03, 0x55, 0x04, 0x03,
- 0x13, 0x22, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x48,
- 0x69, 0x67, 0x68, 0x20, 0x41, 0x73, 0x73, 0x75, 0x72, 0x61, 0x6e, 0x63,
- 0x65, 0x20, 0x45, 0x56, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41,
- 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x33, 0x31, 0x30, 0x32, 0x32, 0x31, 0x32,
- 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x38, 0x31, 0x30, 0x32,
- 0x32, 0x31, 0x32, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x70, 0x31, 0x0b,
- 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31,
- 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0c, 0x44, 0x69,
- 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, 0x6e, 0x63, 0x31, 0x19,
- 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x10, 0x77, 0x77, 0x77,
- 0x2e, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, 0x74, 0x2e, 0x63, 0x6f,
- 0x6d, 0x31, 0x2f, 0x30, 0x2d, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x26,
- 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x53, 0x48, 0x41,
- 0x32, 0x20, 0x48, 0x69, 0x67, 0x68, 0x20, 0x41, 0x73, 0x73, 0x75, 0x72,
- 0x61, 0x6e, 0x63, 0x65, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20,
- 0x43, 0x41, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
- 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01,
- 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xb6,
- 0xe0, 0x2f, 0xc2, 0x24, 0x06, 0xc8, 0x6d, 0x04, 0x5f, 0xd7, 0xef, 0x0a,
- 0x64, 0x06, 0xb2, 0x7d, 0x22, 0x26, 0x65, 0x16, 0xae, 0x42, 0x40, 0x9b,
- 0xce, 0xdc, 0x9f, 0x9f, 0x76, 0x07, 0x3e, 0xc3, 0x30, 0x55, 0x87, 0x19,
- 0xb9, 0x4f, 0x94, 0x0e, 0x5a, 0x94, 0x1f, 0x55, 0x56, 0xb4, 0xc2, 0x02,
- 0x2a, 0xaf, 0xd0, 0x98, 0xee, 0x0b, 0x40, 0xd7, 0xc4, 0xd0, 0x3b, 0x72,
- 0xc8, 0x14, 0x9e, 0xef, 0x90, 0xb1, 0x11, 0xa9, 0xae, 0xd2, 0xc8, 0xb8,
- 0x43, 0x3a, 0xd9, 0x0b, 0x0b, 0xd5, 0xd5, 0x95, 0xf5, 0x40, 0xaf, 0xc8,
- 0x1d, 0xed, 0x4d, 0x9c, 0x5f, 0x57, 0xb7, 0x86, 0x50, 0x68, 0x99, 0xf5,
- 0x8a, 0xda, 0xd2, 0xc7, 0x05, 0x1f, 0xa8, 0x97, 0xc9, 0xdc, 0xa4, 0xb1,
- 0x82, 0x84, 0x2d, 0xc6, 0xad, 0xa5, 0x9c, 0xc7, 0x19, 0x82, 0xa6, 0x85,
- 0x0f, 0x5e, 0x44, 0x58, 0x2a, 0x37, 0x8f, 0xfd, 0x35, 0xf1, 0x0b, 0x08,
- 0x27, 0x32, 0x5a, 0xf5, 0xbb, 0x8b, 0x9e, 0xa4, 0xbd, 0x51, 0xd0, 0x27,
- 0xe2, 0xdd, 0x3b, 0x42, 0x33, 0xa3, 0x05, 0x28, 0xc4, 0xbb, 0x28, 0xcc,
- 0x9a, 0xac, 0x2b, 0x23, 0x0d, 0x78, 0xc6, 0x7b, 0xe6, 0x5e, 0x71, 0xb7,
- 0x4a, 0x3e, 0x08, 0xfb, 0x81, 0xb7, 0x16, 0x16, 0xa1, 0x9d, 0x23, 0x12,
- 0x4d, 0xe5, 0xd7, 0x92, 0x08, 0xac, 0x75, 0xa4, 0x9c, 0xba, 0xcd, 0x17,
- 0xb2, 0x1e, 0x44, 0x35, 0x65, 0x7f, 0x53, 0x25, 0x39, 0xd1, 0x1c, 0x0a,
- 0x9a, 0x63, 0x1b, 0x19, 0x92, 0x74, 0x68, 0x0a, 0x37, 0xc2, 0xc2, 0x52,
- 0x48, 0xcb, 0x39, 0x5a, 0xa2, 0xb6, 0xe1, 0x5d, 0xc1, 0xdd, 0xa0, 0x20,
- 0xb8, 0x21, 0xa2, 0x93, 0x26, 0x6f, 0x14, 0x4a, 0x21, 0x41, 0xc7, 0xed,
- 0x6d, 0x9b, 0xf2, 0x48, 0x2f, 0xf3, 0x03, 0xf5, 0xa2, 0x68, 0x92, 0x53,
- 0x2f, 0x5e, 0xe3, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x49,
- 0x30, 0x82, 0x01, 0x45, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01,
- 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x00,
- 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04,
- 0x03, 0x02, 0x01, 0x86, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04,
- 0x16, 0x30, 0x14, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03,
- 0x01, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x02, 0x30,
- 0x34, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04,
- 0x28, 0x30, 0x26, 0x30, 0x24, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05,
- 0x07, 0x30, 0x01, 0x86, 0x18, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f,
- 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72,
- 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x4b, 0x06, 0x03, 0x55, 0x1d, 0x1f,
- 0x04, 0x44, 0x30, 0x42, 0x30, 0x40, 0xa0, 0x3e, 0xa0, 0x3c, 0x86, 0x3a,
- 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x34, 0x2e,
- 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, 0x74, 0x2e, 0x63, 0x6f, 0x6d,
- 0x2f, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x48, 0x69, 0x67,
- 0x68, 0x41, 0x73, 0x73, 0x75, 0x72, 0x61, 0x6e, 0x63, 0x65, 0x45, 0x56,
- 0x52, 0x6f, 0x6f, 0x74, 0x43, 0x41, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x3d,
- 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x36, 0x30, 0x34, 0x30, 0x32, 0x06,
- 0x04, 0x55, 0x1d, 0x20, 0x00, 0x30, 0x2a, 0x30, 0x28, 0x06, 0x08, 0x2b,
- 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x1c, 0x68, 0x74, 0x74,
- 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x64, 0x69, 0x67,
- 0x69, 0x63, 0x65, 0x72, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x43, 0x50,
- 0x53, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14,
- 0x51, 0x68, 0xff, 0x90, 0xaf, 0x02, 0x07, 0x75, 0x3c, 0xcc, 0xd9, 0x65,
- 0x64, 0x62, 0xa2, 0x12, 0xb8, 0x59, 0x72, 0x3b, 0x30, 0x1f, 0x06, 0x03,
- 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0xb1, 0x3e, 0xc3,
- 0x69, 0x03, 0xf8, 0xbf, 0x47, 0x01, 0xd4, 0x98, 0x26, 0x1a, 0x08, 0x02,
- 0xef, 0x63, 0x64, 0x2b, 0xc3, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48,
- 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01,
- 0x00, 0x18, 0x8a, 0x95, 0x89, 0x03, 0xe6, 0x6d, 0xdf, 0x5c, 0xfc, 0x1d,
- 0x68, 0xea, 0x4a, 0x8f, 0x83, 0xd6, 0x51, 0x2f, 0x8d, 0x6b, 0x44, 0x16,
- 0x9e, 0xac, 0x63, 0xf5, 0xd2, 0x6e, 0x6c, 0x84, 0x99, 0x8b, 0xaa, 0x81,
- 0x71, 0x84, 0x5b, 0xed, 0x34, 0x4e, 0xb0, 0xb7, 0x79, 0x92, 0x29, 0xcc,
- 0x2d, 0x80, 0x6a, 0xf0, 0x8e, 0x20, 0xe1, 0x79, 0xa4, 0xfe, 0x03, 0x47,
- 0x13, 0xea, 0xf5, 0x86, 0xca, 0x59, 0x71, 0x7d, 0xf4, 0x04, 0x96, 0x6b,
- 0xd3, 0x59, 0x58, 0x3d, 0xfe, 0xd3, 0x31, 0x25, 0x5c, 0x18, 0x38, 0x84,
- 0xa3, 0xe6, 0x9f, 0x82, 0xfd, 0x8c, 0x5b, 0x98, 0x31, 0x4e, 0xcd, 0x78,
- 0x9e, 0x1a, 0xfd, 0x85, 0xcb, 0x49, 0xaa, 0xf2, 0x27, 0x8b, 0x99, 0x72,
- 0xfc, 0x3e, 0xaa, 0xd5, 0x41, 0x0b, 0xda, 0xd5, 0x36, 0xa1, 0xbf, 0x1c,
- 0x6e, 0x47, 0x49, 0x7f, 0x5e, 0xd9, 0x48, 0x7c, 0x03, 0xd9, 0xfd, 0x8b,
- 0x49, 0xa0, 0x98, 0x26, 0x42, 0x40, 0xeb, 0xd6, 0x92, 0x11, 0xa4, 0x64,
- 0x0a, 0x57, 0x54, 0xc4, 0xf5, 0x1d, 0xd6, 0x02, 0x5e, 0x6b, 0xac, 0xee,
- 0xc4, 0x80, 0x9a, 0x12, 0x72, 0xfa, 0x56, 0x93, 0xd7, 0xff, 0xbf, 0x30,
- 0x85, 0x06, 0x30, 0xbf, 0x0b, 0x7f, 0x4e, 0xff, 0x57, 0x05, 0x9d, 0x24,
- 0xed, 0x85, 0xc3, 0x2b, 0xfb, 0xa6, 0x75, 0xa8, 0xac, 0x2d, 0x16, 0xef,
- 0x7d, 0x79, 0x27, 0xb2, 0xeb, 0xc2, 0x9d, 0x0b, 0x07, 0xea, 0xaa, 0x85,
- 0xd3, 0x01, 0xa3, 0x20, 0x28, 0x41, 0x59, 0x43, 0x28, 0xd2, 0x81, 0xe3,
- 0xaa, 0xf6, 0xec, 0x7b, 0x3b, 0x77, 0xb6, 0x40, 0x62, 0x80, 0x05, 0x41,
- 0x45, 0x01, 0xef, 0x17, 0x06, 0x3e, 0xde, 0xc0, 0x33, 0x9b, 0x67, 0xd3,
- 0x61, 0x2e, 0x72, 0x87, 0xe4, 0x69, 0xfc, 0x12, 0x00, 0x57, 0x40, 0x1e,
- 0x70, 0xf5, 0x1e, 0xc9, 0xb4,
-};
-
-#if 0
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number:
- 16:87:d6:88:6d:e2:30:06:85:23:3d:bf:11:bf:65:97
- Signature Algorithm: sha256WithRSAEncryption
- Issuer: C=US, O=thawte, Inc., OU=Certification Services Division, OU=(c) 2006 thawte, Inc. - For authorized use only, CN=thawte Primary Root CA
- Validity
- Not Before: Oct 31 00:00:00 2013 GMT
- Not After : Oct 30 23:59:59 2023 GMT
- Subject: C=US, O=thawte, Inc., CN=thawte SSL CA - G2
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:b2:fc:06:fb:04:93:d2:ea:59:20:3b:44:85:97:
- 52:39:e7:10:f0:7a:e0:b0:94:40:da:46:f8:0c:28:
- bb:b9:ce:60:38:3f:d2:d8:11:42:1b:91:ad:49:ee:
- 8f:c7:de:6c:de:37:6f:fd:8b:20:3c:6d:e7:74:d3:
- dc:d5:24:88:41:80:89:ee:36:be:c4:d5:be:8d:53:
- 13:aa:e4:a5:b8:93:0a:be:ec:da:cd:3c:d4:32:56:
- ef:d0:4e:a0:b8:97:bb:39:50:1e:6e:65:c3:fd:b2:
- ce:e0:59:a9:48:09:c6:fe:be:ae:fc:3e:3b:81:20:
- 97:8b:8f:46:df:60:64:07:75:bb:1b:86:38:9f:47:
- 7b:34:ce:a1:d1:97:ad:76:d8:9f:b7:26:db:79:80:
- 36:48:f2:c5:37:f8:d9:32:ae:7c:a4:53:81:c7:99:
- a1:54:38:2f:4f:75:a0:bb:5a:a5:bb:cd:ac:02:5b:
- 19:02:d5:13:18:a7:ce:ac:74:55:12:05:8b:9b:a2:
- 95:46:64:72:38:cd:5a:1b:3a:16:a7:be:71:99:8c:
- 54:03:b8:96:6c:01:d3:3e:06:98:3f:21:81:3b:02:
- 7e:00:47:53:01:1e:0e:46:43:fb:4b:2d:dc:0b:1a:
- e8:2f:98:f8:7e:d1:99:ab:13:6c:a4:17:de:6f:f6:
- 15:f5
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Basic Constraints: critical
- CA:TRUE, pathlen:0
- X509v3 Key Usage: critical
- Certificate Sign, CRL Sign
- X509v3 CRL Distribution Points:
-
- Full Name:
- URI:http://t1.symcb.com/ThawtePCA.crl
-
- Authority Information Access:
- OCSP - URI:http://t2.symcb.com
-
- X509v3 Certificate Policies:
- Policy: 2.16.840.1.113733.1.7.54
- CPS: https://www.thawte.com/cps
-
- X509v3 Subject Alternative Name:
- DirName:/CN=SymantecPKI-1-537
- X509v3 Subject Key Identifier:
- C2:4F:48:57:FC:D1:4F:9A:C0:5D:38:7D:0E:05:DB:D9:2E:B5:52:60
- X509v3 Authority Key Identifier:
- keyid:7B:5B:45:CF:AF:CE:CB:7A:FD:31:92:1A:6A:B6:F3:46:EB:57:48:50
-
- Signature Algorithm: sha256WithRSAEncryption
- 8d:06:de:43:c9:76:02:ca:d9:23:97:5e:f3:63:d7:7d:44:c2:
- 0f:6b:0a:f5:07:e5:8b:b8:fa:e0:a3:fa:6b:80:92:b5:03:2c:
- c5:37:e0:c2:e5:95:b5:92:70:18:28:42:94:ee:4b:77:6a:01:
- 0f:8b:23:ec:56:4d:f4:00:69:e5:84:c8:e2:ea:de:5b:3e:f6:
- 3c:07:3a:94:ca:6c:27:b1:cc:83:1a:60:71:27:d2:bf:02:f5:
- 1e:44:d3:48:d5:a6:d3:76:21:00:9c:fa:98:64:eb:17:36:3f:
- eb:1b:3c:3e:a6:b1:d9:58:06:0e:72:d9:68:be:f1:a7:20:d7:
- 52:e4:a4:77:1f:71:70:9d:55:35:85:37:e1:1d:4d:94:c2:70:
- 7f:95:40:6e:4b:7d:b2:b4:29:2a:03:79:c8:b9:4c:67:61:04:
- a0:8b:27:ff:59:00:eb:55:7f:c6:b7:33:35:2d:5e:4e:ac:b8:
- ea:12:c5:e8:f7:b9:ab:be:74:92:2c:b7:d9:4d:ca:84:2f:1c:
- c2:f0:72:7c:b2:31:6e:cf:80:e5:88:07:36:51:7b:ba:61:af:
- 6d:8d:23:5b:34:a3:95:bc:a2:31:7f:f2:f5:e7:b7:e8:ef:c4:
- b5:27:32:e9:f7:9e:69:c7:2b:e8:be:bb:0c:aa:e7:ea:60:12:
- ea:26:8a:78
------BEGIN CERTIFICATE-----
-MIIEsjCCA5qgAwIBAgIQFofWiG3iMAaFIz2/Eb9llzANBgkqhkiG9w0BAQsFADCB
-qTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMf
-Q2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIw
-MDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxHzAdBgNV
-BAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwHhcNMTMxMDMxMDAwMDAwWhcNMjMx
-MDMwMjM1OTU5WjBBMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMdGhhd3RlLCBJbmMu
-MRswGQYDVQQDExJ0aGF3dGUgU1NMIENBIC0gRzIwggEiMA0GCSqGSIb3DQEBAQUA
-A4IBDwAwggEKAoIBAQCy/Ab7BJPS6lkgO0SFl1I55xDweuCwlEDaRvgMKLu5zmA4
-P9LYEUIbka1J7o/H3mzeN2/9iyA8bed009zVJIhBgInuNr7E1b6NUxOq5KW4kwq+
-7NrNPNQyVu/QTqC4l7s5UB5uZcP9ss7gWalICcb+vq78PjuBIJeLj0bfYGQHdbsb
-hjifR3s0zqHRl6122J+3Jtt5gDZI8sU3+NkyrnykU4HHmaFUOC9PdaC7WqW7zawC
-WxkC1RMYp86sdFUSBYubopVGZHI4zVobOhanvnGZjFQDuJZsAdM+Bpg/IYE7An4A
-R1MBHg5GQ/tLLdwLGugvmPh+0ZmrE2ykF95v9hX1AgMBAAGjggE7MIIBNzASBgNV
-HRMBAf8ECDAGAQH/AgEAMA4GA1UdDwEB/wQEAwIBBjAyBgNVHR8EKzApMCegJaAj
-hiFodHRwOi8vdDEuc3ltY2IuY29tL1RoYXd0ZVBDQS5jcmwwLwYIKwYBBQUHAQEE
-IzAhMB8GCCsGAQUFBzABhhNodHRwOi8vdDIuc3ltY2IuY29tMEEGA1UdIAQ6MDgw
-NgYKYIZIAYb4RQEHNjAoMCYGCCsGAQUFBwIBFhpodHRwczovL3d3dy50aGF3dGUu
-Y29tL2NwczApBgNVHREEIjAgpB4wHDEaMBgGA1UEAxMRU3ltYW50ZWNQS0ktMS01
-MzcwHQYDVR0OBBYEFMJPSFf80U+awF04fQ4F29kutVJgMB8GA1UdIwQYMBaAFHtb
-Rc+vzst6/TGSGmq280brV0hQMA0GCSqGSIb3DQEBCwUAA4IBAQCNBt5DyXYCytkj
-l17zY9d9RMIPawr1B+WLuPrgo/prgJK1AyzFN+DC5ZW1knAYKEKU7kt3agEPiyPs
-Vk30AGnlhMji6t5bPvY8BzqUymwnscyDGmBxJ9K/AvUeRNNI1abTdiEAnPqYZOsX
-Nj/rGzw+prHZWAYOctlovvGnINdS5KR3H3FwnVU1hTfhHU2UwnB/lUBuS32ytCkq
-A3nIuUxnYQSgiyf/WQDrVX/GtzM1LV5OrLjqEsXo97mrvnSSLLfZTcqELxzC8HJ8
-sjFuz4DliAc2UXu6Ya9tjSNbNKOVvKIxf/L157fo78S1JzLp955pxyvovrsMqufq
-YBLqJop4
------END CERTIFICATE-----
-#endif
-static const unsigned char kDERCert27[] = {
- 0x30, 0x82, 0x04, 0xb2, 0x30, 0x82, 0x03, 0x9a, 0xa0, 0x03, 0x02, 0x01,
- 0x02, 0x02, 0x10, 0x16, 0x87, 0xd6, 0x88, 0x6d, 0xe2, 0x30, 0x06, 0x85,
- 0x23, 0x3d, 0xbf, 0x11, 0xbf, 0x65, 0x97, 0x30, 0x0d, 0x06, 0x09, 0x2a,
- 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x81,
- 0xa9, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
- 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13,
- 0x0c, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63,
- 0x2e, 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1f,
- 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f,
- 0x6e, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, 0x44,
- 0x69, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x31, 0x38, 0x30, 0x36, 0x06,
- 0x03, 0x55, 0x04, 0x0b, 0x13, 0x2f, 0x28, 0x63, 0x29, 0x20, 0x32, 0x30,
- 0x30, 0x36, 0x20, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2c, 0x20, 0x49,
- 0x6e, 0x63, 0x2e, 0x20, 0x2d, 0x20, 0x46, 0x6f, 0x72, 0x20, 0x61, 0x75,
- 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x20, 0x75, 0x73, 0x65,
- 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55,
- 0x04, 0x03, 0x13, 0x16, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x20, 0x50,
- 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20,
- 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x33, 0x31, 0x30, 0x33, 0x31,
- 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x33, 0x31,
- 0x30, 0x33, 0x30, 0x32, 0x33, 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x41,
- 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55,
- 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0c,
- 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e,
- 0x31, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x12, 0x74,
- 0x68, 0x61, 0x77, 0x74, 0x65, 0x20, 0x53, 0x53, 0x4c, 0x20, 0x43, 0x41,
- 0x20, 0x2d, 0x20, 0x47, 0x32, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06,
- 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00,
- 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01,
- 0x01, 0x00, 0xb2, 0xfc, 0x06, 0xfb, 0x04, 0x93, 0xd2, 0xea, 0x59, 0x20,
- 0x3b, 0x44, 0x85, 0x97, 0x52, 0x39, 0xe7, 0x10, 0xf0, 0x7a, 0xe0, 0xb0,
- 0x94, 0x40, 0xda, 0x46, 0xf8, 0x0c, 0x28, 0xbb, 0xb9, 0xce, 0x60, 0x38,
- 0x3f, 0xd2, 0xd8, 0x11, 0x42, 0x1b, 0x91, 0xad, 0x49, 0xee, 0x8f, 0xc7,
- 0xde, 0x6c, 0xde, 0x37, 0x6f, 0xfd, 0x8b, 0x20, 0x3c, 0x6d, 0xe7, 0x74,
- 0xd3, 0xdc, 0xd5, 0x24, 0x88, 0x41, 0x80, 0x89, 0xee, 0x36, 0xbe, 0xc4,
- 0xd5, 0xbe, 0x8d, 0x53, 0x13, 0xaa, 0xe4, 0xa5, 0xb8, 0x93, 0x0a, 0xbe,
- 0xec, 0xda, 0xcd, 0x3c, 0xd4, 0x32, 0x56, 0xef, 0xd0, 0x4e, 0xa0, 0xb8,
- 0x97, 0xbb, 0x39, 0x50, 0x1e, 0x6e, 0x65, 0xc3, 0xfd, 0xb2, 0xce, 0xe0,
- 0x59, 0xa9, 0x48, 0x09, 0xc6, 0xfe, 0xbe, 0xae, 0xfc, 0x3e, 0x3b, 0x81,
- 0x20, 0x97, 0x8b, 0x8f, 0x46, 0xdf, 0x60, 0x64, 0x07, 0x75, 0xbb, 0x1b,
- 0x86, 0x38, 0x9f, 0x47, 0x7b, 0x34, 0xce, 0xa1, 0xd1, 0x97, 0xad, 0x76,
- 0xd8, 0x9f, 0xb7, 0x26, 0xdb, 0x79, 0x80, 0x36, 0x48, 0xf2, 0xc5, 0x37,
- 0xf8, 0xd9, 0x32, 0xae, 0x7c, 0xa4, 0x53, 0x81, 0xc7, 0x99, 0xa1, 0x54,
- 0x38, 0x2f, 0x4f, 0x75, 0xa0, 0xbb, 0x5a, 0xa5, 0xbb, 0xcd, 0xac, 0x02,
- 0x5b, 0x19, 0x02, 0xd5, 0x13, 0x18, 0xa7, 0xce, 0xac, 0x74, 0x55, 0x12,
- 0x05, 0x8b, 0x9b, 0xa2, 0x95, 0x46, 0x64, 0x72, 0x38, 0xcd, 0x5a, 0x1b,
- 0x3a, 0x16, 0xa7, 0xbe, 0x71, 0x99, 0x8c, 0x54, 0x03, 0xb8, 0x96, 0x6c,
- 0x01, 0xd3, 0x3e, 0x06, 0x98, 0x3f, 0x21, 0x81, 0x3b, 0x02, 0x7e, 0x00,
- 0x47, 0x53, 0x01, 0x1e, 0x0e, 0x46, 0x43, 0xfb, 0x4b, 0x2d, 0xdc, 0x0b,
- 0x1a, 0xe8, 0x2f, 0x98, 0xf8, 0x7e, 0xd1, 0x99, 0xab, 0x13, 0x6c, 0xa4,
- 0x17, 0xde, 0x6f, 0xf6, 0x15, 0xf5, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3,
- 0x82, 0x01, 0x3b, 0x30, 0x82, 0x01, 0x37, 0x30, 0x12, 0x06, 0x03, 0x55,
- 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff,
- 0x02, 0x01, 0x00, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01,
- 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x32, 0x06, 0x03, 0x55,
- 0x1d, 0x1f, 0x04, 0x2b, 0x30, 0x29, 0x30, 0x27, 0xa0, 0x25, 0xa0, 0x23,
- 0x86, 0x21, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x74, 0x31, 0x2e,
- 0x73, 0x79, 0x6d, 0x63, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x54, 0x68,
- 0x61, 0x77, 0x74, 0x65, 0x50, 0x43, 0x41, 0x2e, 0x63, 0x72, 0x6c, 0x30,
- 0x2f, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04,
- 0x23, 0x30, 0x21, 0x30, 0x1f, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05,
- 0x07, 0x30, 0x01, 0x86, 0x13, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f,
- 0x74, 0x32, 0x2e, 0x73, 0x79, 0x6d, 0x63, 0x62, 0x2e, 0x63, 0x6f, 0x6d,
- 0x30, 0x41, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x3a, 0x30, 0x38, 0x30,
- 0x36, 0x06, 0x0a, 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x45, 0x01, 0x07,
- 0x36, 0x30, 0x28, 0x30, 0x26, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05,
- 0x07, 0x02, 0x01, 0x16, 0x1a, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f,
- 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2e,
- 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x70, 0x73, 0x30, 0x29, 0x06, 0x03, 0x55,
- 0x1d, 0x11, 0x04, 0x22, 0x30, 0x20, 0xa4, 0x1e, 0x30, 0x1c, 0x31, 0x1a,
- 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x11, 0x53, 0x79, 0x6d,
- 0x61, 0x6e, 0x74, 0x65, 0x63, 0x50, 0x4b, 0x49, 0x2d, 0x31, 0x2d, 0x35,
- 0x33, 0x37, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04,
- 0x14, 0xc2, 0x4f, 0x48, 0x57, 0xfc, 0xd1, 0x4f, 0x9a, 0xc0, 0x5d, 0x38,
- 0x7d, 0x0e, 0x05, 0xdb, 0xd9, 0x2e, 0xb5, 0x52, 0x60, 0x30, 0x1f, 0x06,
- 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x7b, 0x5b,
- 0x45, 0xcf, 0xaf, 0xce, 0xcb, 0x7a, 0xfd, 0x31, 0x92, 0x1a, 0x6a, 0xb6,
- 0xf3, 0x46, 0xeb, 0x57, 0x48, 0x50, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
- 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01,
- 0x01, 0x00, 0x8d, 0x06, 0xde, 0x43, 0xc9, 0x76, 0x02, 0xca, 0xd9, 0x23,
- 0x97, 0x5e, 0xf3, 0x63, 0xd7, 0x7d, 0x44, 0xc2, 0x0f, 0x6b, 0x0a, 0xf5,
- 0x07, 0xe5, 0x8b, 0xb8, 0xfa, 0xe0, 0xa3, 0xfa, 0x6b, 0x80, 0x92, 0xb5,
- 0x03, 0x2c, 0xc5, 0x37, 0xe0, 0xc2, 0xe5, 0x95, 0xb5, 0x92, 0x70, 0x18,
- 0x28, 0x42, 0x94, 0xee, 0x4b, 0x77, 0x6a, 0x01, 0x0f, 0x8b, 0x23, 0xec,
- 0x56, 0x4d, 0xf4, 0x00, 0x69, 0xe5, 0x84, 0xc8, 0xe2, 0xea, 0xde, 0x5b,
- 0x3e, 0xf6, 0x3c, 0x07, 0x3a, 0x94, 0xca, 0x6c, 0x27, 0xb1, 0xcc, 0x83,
- 0x1a, 0x60, 0x71, 0x27, 0xd2, 0xbf, 0x02, 0xf5, 0x1e, 0x44, 0xd3, 0x48,
- 0xd5, 0xa6, 0xd3, 0x76, 0x21, 0x00, 0x9c, 0xfa, 0x98, 0x64, 0xeb, 0x17,
- 0x36, 0x3f, 0xeb, 0x1b, 0x3c, 0x3e, 0xa6, 0xb1, 0xd9, 0x58, 0x06, 0x0e,
- 0x72, 0xd9, 0x68, 0xbe, 0xf1, 0xa7, 0x20, 0xd7, 0x52, 0xe4, 0xa4, 0x77,
- 0x1f, 0x71, 0x70, 0x9d, 0x55, 0x35, 0x85, 0x37, 0xe1, 0x1d, 0x4d, 0x94,
- 0xc2, 0x70, 0x7f, 0x95, 0x40, 0x6e, 0x4b, 0x7d, 0xb2, 0xb4, 0x29, 0x2a,
- 0x03, 0x79, 0xc8, 0xb9, 0x4c, 0x67, 0x61, 0x04, 0xa0, 0x8b, 0x27, 0xff,
- 0x59, 0x00, 0xeb, 0x55, 0x7f, 0xc6, 0xb7, 0x33, 0x35, 0x2d, 0x5e, 0x4e,
- 0xac, 0xb8, 0xea, 0x12, 0xc5, 0xe8, 0xf7, 0xb9, 0xab, 0xbe, 0x74, 0x92,
- 0x2c, 0xb7, 0xd9, 0x4d, 0xca, 0x84, 0x2f, 0x1c, 0xc2, 0xf0, 0x72, 0x7c,
- 0xb2, 0x31, 0x6e, 0xcf, 0x80, 0xe5, 0x88, 0x07, 0x36, 0x51, 0x7b, 0xba,
- 0x61, 0xaf, 0x6d, 0x8d, 0x23, 0x5b, 0x34, 0xa3, 0x95, 0xbc, 0xa2, 0x31,
- 0x7f, 0xf2, 0xf5, 0xe7, 0xb7, 0xe8, 0xef, 0xc4, 0xb5, 0x27, 0x32, 0xe9,
- 0xf7, 0x9e, 0x69, 0xc7, 0x2b, 0xe8, 0xbe, 0xbb, 0x0c, 0xaa, 0xe7, 0xea,
- 0x60, 0x12, 0xea, 0x26, 0x8a, 0x78,
-};
-
-#if 0
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number:
- 0c:79:a9:44:b0:8c:11:95:20:92:61:5f:e2:6b:1d:83
- Signature Algorithm: sha256WithRSAEncryption
- Issuer: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert High Assurance EV Root CA
- Validity
- Not Before: Oct 22 12:00:00 2013 GMT
- Not After : Oct 22 12:00:00 2028 GMT
- Subject: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert SHA2 Extended Validation Server CA
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:d7:53:a4:04:51:f8:99:a6:16:48:4b:67:27:aa:
- 93:49:d0:39:ed:0c:b0:b0:00:87:f1:67:28:86:85:
- 8c:8e:63:da:bc:b1:40:38:e2:d3:f5:ec:a5:05:18:
- b8:3d:3e:c5:99:17:32:ec:18:8c:fa:f1:0c:a6:64:
- 21:85:cb:07:10:34:b0:52:88:2b:1f:68:9b:d2:b1:
- 8f:12:b0:b3:d2:e7:88:1f:1f:ef:38:77:54:53:5f:
- 80:79:3f:2e:1a:aa:a8:1e:4b:2b:0d:ab:b7:63:b9:
- 35:b7:7d:14:bc:59:4b:df:51:4a:d2:a1:e2:0c:e2:
- 90:82:87:6a:ae:ea:d7:64:d6:98:55:e8:fd:af:1a:
- 50:6c:54:bc:11:f2:fd:4a:f2:9d:bb:7f:0e:f4:d5:
- be:8e:16:89:12:55:d8:c0:71:34:ee:f6:dc:2d:ec:
- c4:87:25:86:8d:d8:21:e4:b0:4d:0c:89:dc:39:26:
- 17:dd:f6:d7:94:85:d8:04:21:70:9d:6f:6f:ff:5c:
- ba:19:e1:45:cb:56:57:28:7e:1c:0d:41:57:aa:b7:
- b8:27:bb:b1:e4:fa:2a:ef:21:23:75:1a:ad:2d:9b:
- 86:35:8c:9c:77:b5:73:ad:d8:94:2d:e4:f3:0c:9d:
- ee:c1:4e:62:7e:17:c0:71:9e:2c:de:f1:f9:10:28:
- 19:33
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Basic Constraints: critical
- CA:TRUE, pathlen:0
- X509v3 Key Usage: critical
- Digital Signature, Certificate Sign, CRL Sign
- X509v3 Extended Key Usage:
- TLS Web Server Authentication, TLS Web Client Authentication
- Authority Information Access:
- OCSP - URI:http://ocsp.digicert.com
-
- X509v3 CRL Distribution Points:
-
- Full Name:
- URI:http://crl4.digicert.com/DigiCertHighAssuranceEVRootCA.crl
-
- X509v3 Certificate Policies:
- Policy: X509v3 Any Policy
- CPS: https://www.digicert.com/CPS
-
- X509v3 Subject Key Identifier:
- 3D:D3:50:A5:D6:A0:AD:EE:F3:4A:60:0A:65:D3:21:D4:F8:F8:D6:0F
- X509v3 Authority Key Identifier:
- keyid:B1:3E:C3:69:03:F8:BF:47:01:D4:98:26:1A:08:02:EF:63:64:2B:C3
-
- Signature Algorithm: sha256WithRSAEncryption
- 9d:b6:d0:90:86:e1:86:02:ed:c5:a0:f0:34:1c:74:c1:8d:76:
- cc:86:0a:a8:f0:4a:8a:42:d6:3f:c8:a9:4d:ad:7c:08:ad:e6:
- b6:50:b8:a2:1a:4d:88:07:b1:29:21:dc:e7:da:c6:3c:21:e0:
- e3:11:49:70:ac:7a:1d:01:a4:ca:11:3a:57:ab:7d:57:2a:40:
- 74:fd:d3:1d:85:18:50:df:57:47:75:a1:7d:55:20:2e:47:37:
- 50:72:8c:7f:82:1b:d2:62:8f:2d:03:5a:da:c3:c8:a1:ce:2c:
- 52:a2:00:63:eb:73:ba:71:c8:49:27:23:97:64:85:9e:38:0e:
- ad:63:68:3c:ba:52:81:58:79:a3:2c:0c:df:de:6d:eb:31:f2:
- ba:a0:7c:6c:f1:2c:d4:e1:bd:77:84:37:03:ce:32:b5:c8:9a:
- 81:1a:4a:92:4e:3b:46:9a:85:fe:83:a2:f9:9e:8c:a3:cc:0d:
- 5e:b3:3d:cf:04:78:8f:14:14:7b:32:9c:c7:00:a6:5c:c4:b5:
- a1:55:8d:5a:56:68:a4:22:70:aa:3c:81:71:d9:9d:a8:45:3b:
- f4:e5:f6:a2:51:dd:c7:7b:62:e8:6f:0c:74:eb:b8:da:f8:bf:
- 87:0d:79:50:91:90:9b:18:3b:91:59:27:f1:35:28:13:ab:26:
- 7e:d5:f7:7a
------BEGIN CERTIFICATE-----
-MIIEtjCCA56gAwIBAgIQDHmpRLCMEZUgkmFf4msdgzANBgkqhkiG9w0BAQsFADBs
-MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
-d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j
-ZSBFViBSb290IENBMB4XDTEzMTAyMjEyMDAwMFoXDTI4MTAyMjEyMDAwMFowdTEL
-MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3
-LmRpZ2ljZXJ0LmNvbTE0MDIGA1UEAxMrRGlnaUNlcnQgU0hBMiBFeHRlbmRlZCBW
-YWxpZGF0aW9uIFNlcnZlciBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
-ggEBANdTpARR+JmmFkhLZyeqk0nQOe0MsLAAh/FnKIaFjI5j2ryxQDji0/XspQUY
-uD0+xZkXMuwYjPrxDKZkIYXLBxA0sFKIKx9om9KxjxKws9LniB8f7zh3VFNfgHk/
-LhqqqB5LKw2rt2O5Nbd9FLxZS99RStKh4gzikIKHaq7q12TWmFXo/a8aUGxUvBHy
-/Urynbt/DvTVvo4WiRJV2MBxNO723C3sxIclho3YIeSwTQyJ3DkmF93215SF2AQh
-cJ1vb/9cuhnhRctWVyh+HA1BV6q3uCe7seT6Ku8hI3UarS2bhjWMnHe1c63YlC3k
-8wyd7sFOYn4XwHGeLN7x+RAoGTMCAwEAAaOCAUkwggFFMBIGA1UdEwEB/wQIMAYB
-Af8CAQAwDgYDVR0PAQH/BAQDAgGGMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEF
-BQcDAjA0BggrBgEFBQcBAQQoMCYwJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRp
-Z2ljZXJ0LmNvbTBLBgNVHR8ERDBCMECgPqA8hjpodHRwOi8vY3JsNC5kaWdpY2Vy
-dC5jb20vRGlnaUNlcnRIaWdoQXNzdXJhbmNlRVZSb290Q0EuY3JsMD0GA1UdIAQ2
-MDQwMgYEVR0gADAqMCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy5kaWdpY2VydC5j
-b20vQ1BTMB0GA1UdDgQWBBQ901Cl1qCt7vNKYApl0yHU+PjWDzAfBgNVHSMEGDAW
-gBSxPsNpA/i/RwHUmCYaCALvY2QrwzANBgkqhkiG9w0BAQsFAAOCAQEAnbbQkIbh
-hgLtxaDwNBx0wY12zIYKqPBKikLWP8ipTa18CK3mtlC4ohpNiAexKSHc59rGPCHg
-4xFJcKx6HQGkyhE6V6t9VypAdP3THYUYUN9XR3WhfVUgLkc3UHKMf4Ib0mKPLQNa
-2sPIoc4sUqIAY+tzunHISScjl2SFnjgOrWNoPLpSgVh5oywM395t6zHyuqB8bPEs
-1OG9d4Q3A84ytciagRpKkk47RpqF/oOi+Z6Mo8wNXrM9zwR4jxQUezKcxwCmXMS1
-oVWNWlZopCJwqjyBcdmdqEU79OX2olHdx3ti6G8MdOu42vi/hw15UJGQmxg7kVkn
-8TUoE6smftX3eg==
------END CERTIFICATE-----
-#endif
-static const unsigned char kDERCert28[] = {
- 0x30, 0x82, 0x04, 0xb6, 0x30, 0x82, 0x03, 0x9e, 0xa0, 0x03, 0x02, 0x01,
- 0x02, 0x02, 0x10, 0x0c, 0x79, 0xa9, 0x44, 0xb0, 0x8c, 0x11, 0x95, 0x20,
- 0x92, 0x61, 0x5f, 0xe2, 0x6b, 0x1d, 0x83, 0x30, 0x0d, 0x06, 0x09, 0x2a,
- 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x6c,
- 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55,
- 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0c,
- 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, 0x6e, 0x63,
- 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x10, 0x77,
- 0x77, 0x77, 0x2e, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, 0x74, 0x2e,
- 0x63, 0x6f, 0x6d, 0x31, 0x2b, 0x30, 0x29, 0x06, 0x03, 0x55, 0x04, 0x03,
- 0x13, 0x22, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x48,
- 0x69, 0x67, 0x68, 0x20, 0x41, 0x73, 0x73, 0x75, 0x72, 0x61, 0x6e, 0x63,
- 0x65, 0x20, 0x45, 0x56, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41,
- 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x33, 0x31, 0x30, 0x32, 0x32, 0x31, 0x32,
- 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x38, 0x31, 0x30, 0x32,
- 0x32, 0x31, 0x32, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x75, 0x31, 0x0b,
- 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31,
- 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0c, 0x44, 0x69,
- 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, 0x6e, 0x63, 0x31, 0x19,
- 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x10, 0x77, 0x77, 0x77,
- 0x2e, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, 0x74, 0x2e, 0x63, 0x6f,
- 0x6d, 0x31, 0x34, 0x30, 0x32, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x2b,
- 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x53, 0x48, 0x41,
- 0x32, 0x20, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x64, 0x65, 0x64, 0x20, 0x56,
- 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x53, 0x65,
- 0x72, 0x76, 0x65, 0x72, 0x20, 0x43, 0x41, 0x30, 0x82, 0x01, 0x22, 0x30,
- 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01,
- 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02,
- 0x82, 0x01, 0x01, 0x00, 0xd7, 0x53, 0xa4, 0x04, 0x51, 0xf8, 0x99, 0xa6,
- 0x16, 0x48, 0x4b, 0x67, 0x27, 0xaa, 0x93, 0x49, 0xd0, 0x39, 0xed, 0x0c,
- 0xb0, 0xb0, 0x00, 0x87, 0xf1, 0x67, 0x28, 0x86, 0x85, 0x8c, 0x8e, 0x63,
- 0xda, 0xbc, 0xb1, 0x40, 0x38, 0xe2, 0xd3, 0xf5, 0xec, 0xa5, 0x05, 0x18,
- 0xb8, 0x3d, 0x3e, 0xc5, 0x99, 0x17, 0x32, 0xec, 0x18, 0x8c, 0xfa, 0xf1,
- 0x0c, 0xa6, 0x64, 0x21, 0x85, 0xcb, 0x07, 0x10, 0x34, 0xb0, 0x52, 0x88,
- 0x2b, 0x1f, 0x68, 0x9b, 0xd2, 0xb1, 0x8f, 0x12, 0xb0, 0xb3, 0xd2, 0xe7,
- 0x88, 0x1f, 0x1f, 0xef, 0x38, 0x77, 0x54, 0x53, 0x5f, 0x80, 0x79, 0x3f,
- 0x2e, 0x1a, 0xaa, 0xa8, 0x1e, 0x4b, 0x2b, 0x0d, 0xab, 0xb7, 0x63, 0xb9,
- 0x35, 0xb7, 0x7d, 0x14, 0xbc, 0x59, 0x4b, 0xdf, 0x51, 0x4a, 0xd2, 0xa1,
- 0xe2, 0x0c, 0xe2, 0x90, 0x82, 0x87, 0x6a, 0xae, 0xea, 0xd7, 0x64, 0xd6,
- 0x98, 0x55, 0xe8, 0xfd, 0xaf, 0x1a, 0x50, 0x6c, 0x54, 0xbc, 0x11, 0xf2,
- 0xfd, 0x4a, 0xf2, 0x9d, 0xbb, 0x7f, 0x0e, 0xf4, 0xd5, 0xbe, 0x8e, 0x16,
- 0x89, 0x12, 0x55, 0xd8, 0xc0, 0x71, 0x34, 0xee, 0xf6, 0xdc, 0x2d, 0xec,
- 0xc4, 0x87, 0x25, 0x86, 0x8d, 0xd8, 0x21, 0xe4, 0xb0, 0x4d, 0x0c, 0x89,
- 0xdc, 0x39, 0x26, 0x17, 0xdd, 0xf6, 0xd7, 0x94, 0x85, 0xd8, 0x04, 0x21,
- 0x70, 0x9d, 0x6f, 0x6f, 0xff, 0x5c, 0xba, 0x19, 0xe1, 0x45, 0xcb, 0x56,
- 0x57, 0x28, 0x7e, 0x1c, 0x0d, 0x41, 0x57, 0xaa, 0xb7, 0xb8, 0x27, 0xbb,
- 0xb1, 0xe4, 0xfa, 0x2a, 0xef, 0x21, 0x23, 0x75, 0x1a, 0xad, 0x2d, 0x9b,
- 0x86, 0x35, 0x8c, 0x9c, 0x77, 0xb5, 0x73, 0xad, 0xd8, 0x94, 0x2d, 0xe4,
- 0xf3, 0x0c, 0x9d, 0xee, 0xc1, 0x4e, 0x62, 0x7e, 0x17, 0xc0, 0x71, 0x9e,
- 0x2c, 0xde, 0xf1, 0xf9, 0x10, 0x28, 0x19, 0x33, 0x02, 0x03, 0x01, 0x00,
- 0x01, 0xa3, 0x82, 0x01, 0x49, 0x30, 0x82, 0x01, 0x45, 0x30, 0x12, 0x06,
- 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01,
- 0x01, 0xff, 0x02, 0x01, 0x00, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f,
- 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x86, 0x30, 0x1d, 0x06,
- 0x03, 0x55, 0x1d, 0x25, 0x04, 0x16, 0x30, 0x14, 0x06, 0x08, 0x2b, 0x06,
- 0x01, 0x05, 0x05, 0x07, 0x03, 0x01, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05,
- 0x05, 0x07, 0x03, 0x02, 0x30, 0x34, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05,
- 0x05, 0x07, 0x01, 0x01, 0x04, 0x28, 0x30, 0x26, 0x30, 0x24, 0x06, 0x08,
- 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x18, 0x68, 0x74,
- 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x64, 0x69,
- 0x67, 0x69, 0x63, 0x65, 0x72, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x4b,
- 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x44, 0x30, 0x42, 0x30, 0x40, 0xa0,
- 0x3e, 0xa0, 0x3c, 0x86, 0x3a, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f,
- 0x63, 0x72, 0x6c, 0x34, 0x2e, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72,
- 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65,
- 0x72, 0x74, 0x48, 0x69, 0x67, 0x68, 0x41, 0x73, 0x73, 0x75, 0x72, 0x61,
- 0x6e, 0x63, 0x65, 0x45, 0x56, 0x52, 0x6f, 0x6f, 0x74, 0x43, 0x41, 0x2e,
- 0x63, 0x72, 0x6c, 0x30, 0x3d, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x36,
- 0x30, 0x34, 0x30, 0x32, 0x06, 0x04, 0x55, 0x1d, 0x20, 0x00, 0x30, 0x2a,
- 0x30, 0x28, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01,
- 0x16, 0x1c, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77,
- 0x77, 0x2e, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, 0x74, 0x2e, 0x63,
- 0x6f, 0x6d, 0x2f, 0x43, 0x50, 0x53, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d,
- 0x0e, 0x04, 0x16, 0x04, 0x14, 0x3d, 0xd3, 0x50, 0xa5, 0xd6, 0xa0, 0xad,
- 0xee, 0xf3, 0x4a, 0x60, 0x0a, 0x65, 0xd3, 0x21, 0xd4, 0xf8, 0xf8, 0xd6,
- 0x0f, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16,
- 0x80, 0x14, 0xb1, 0x3e, 0xc3, 0x69, 0x03, 0xf8, 0xbf, 0x47, 0x01, 0xd4,
- 0x98, 0x26, 0x1a, 0x08, 0x02, 0xef, 0x63, 0x64, 0x2b, 0xc3, 0x30, 0x0d,
- 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05,
- 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x9d, 0xb6, 0xd0, 0x90, 0x86, 0xe1,
- 0x86, 0x02, 0xed, 0xc5, 0xa0, 0xf0, 0x34, 0x1c, 0x74, 0xc1, 0x8d, 0x76,
- 0xcc, 0x86, 0x0a, 0xa8, 0xf0, 0x4a, 0x8a, 0x42, 0xd6, 0x3f, 0xc8, 0xa9,
- 0x4d, 0xad, 0x7c, 0x08, 0xad, 0xe6, 0xb6, 0x50, 0xb8, 0xa2, 0x1a, 0x4d,
- 0x88, 0x07, 0xb1, 0x29, 0x21, 0xdc, 0xe7, 0xda, 0xc6, 0x3c, 0x21, 0xe0,
- 0xe3, 0x11, 0x49, 0x70, 0xac, 0x7a, 0x1d, 0x01, 0xa4, 0xca, 0x11, 0x3a,
- 0x57, 0xab, 0x7d, 0x57, 0x2a, 0x40, 0x74, 0xfd, 0xd3, 0x1d, 0x85, 0x18,
- 0x50, 0xdf, 0x57, 0x47, 0x75, 0xa1, 0x7d, 0x55, 0x20, 0x2e, 0x47, 0x37,
- 0x50, 0x72, 0x8c, 0x7f, 0x82, 0x1b, 0xd2, 0x62, 0x8f, 0x2d, 0x03, 0x5a,
- 0xda, 0xc3, 0xc8, 0xa1, 0xce, 0x2c, 0x52, 0xa2, 0x00, 0x63, 0xeb, 0x73,
- 0xba, 0x71, 0xc8, 0x49, 0x27, 0x23, 0x97, 0x64, 0x85, 0x9e, 0x38, 0x0e,
- 0xad, 0x63, 0x68, 0x3c, 0xba, 0x52, 0x81, 0x58, 0x79, 0xa3, 0x2c, 0x0c,
- 0xdf, 0xde, 0x6d, 0xeb, 0x31, 0xf2, 0xba, 0xa0, 0x7c, 0x6c, 0xf1, 0x2c,
- 0xd4, 0xe1, 0xbd, 0x77, 0x84, 0x37, 0x03, 0xce, 0x32, 0xb5, 0xc8, 0x9a,
- 0x81, 0x1a, 0x4a, 0x92, 0x4e, 0x3b, 0x46, 0x9a, 0x85, 0xfe, 0x83, 0xa2,
- 0xf9, 0x9e, 0x8c, 0xa3, 0xcc, 0x0d, 0x5e, 0xb3, 0x3d, 0xcf, 0x04, 0x78,
- 0x8f, 0x14, 0x14, 0x7b, 0x32, 0x9c, 0xc7, 0x00, 0xa6, 0x5c, 0xc4, 0xb5,
- 0xa1, 0x55, 0x8d, 0x5a, 0x56, 0x68, 0xa4, 0x22, 0x70, 0xaa, 0x3c, 0x81,
- 0x71, 0xd9, 0x9d, 0xa8, 0x45, 0x3b, 0xf4, 0xe5, 0xf6, 0xa2, 0x51, 0xdd,
- 0xc7, 0x7b, 0x62, 0xe8, 0x6f, 0x0c, 0x74, 0xeb, 0xb8, 0xda, 0xf8, 0xbf,
- 0x87, 0x0d, 0x79, 0x50, 0x91, 0x90, 0x9b, 0x18, 0x3b, 0x91, 0x59, 0x27,
- 0xf1, 0x35, 0x28, 0x13, 0xab, 0x26, 0x7e, 0xd5, 0xf7, 0x7a,
-};
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/common_cert_set_2b.inc b/chromium/net/third_party/quiche/src/quic/core/crypto/common_cert_set_2b.inc
deleted file mode 100644
index 17c64889652..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/common_cert_set_2b.inc
+++ /dev/null
@@ -1,5739 +0,0 @@
-/* This file contains common certificates. It's designed to be #included in
- * another file, in a namespace. */
-#if 0
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number:
- 36:34:9e:18:c9:9c:26:69:b6:56:2e:6c:e5:ad:71:32
- Signature Algorithm: sha256WithRSAEncryption
- Issuer: C=US, O=thawte, Inc., OU=Certification Services Division, OU=(c) 2008 thawte, Inc. - For authorized use only, CN=thawte Primary Root CA - G3
- Validity
- Not Before: May 23 00:00:00 2013 GMT
- Not After : May 22 23:59:59 2023 GMT
- Subject: C=US, O=thawte, Inc., CN=thawte SHA256 SSL CA
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:a3:63:2b:d4:ba:5d:38:ae:b0:cf:b9:4c:38:df:
- 20:7d:f1:2b:47:71:1d:8b:68:f3:56:f9:9c:da:aa:
- e5:84:26:de:a5:71:30:bc:f3:31:23:9d:e8:3b:80:
- c8:66:57:75:b6:57:0e:db:93:f5:26:8e:70:ba:64:
- 52:66:8a:2a:88:5c:44:18:4d:a8:a2:7c:bd:56:61:
- 32:90:12:f9:35:87:48:60:b0:6e:90:67:44:01:8d:
- e7:c9:0d:63:68:72:72:ab:63:3c:86:b8:1f:7d:ad:
- 88:25:a7:6a:88:29:fb:59:c6:78:71:5f:2c:ba:89:
- e6:d3:80:fd:57:ec:b9:51:5f:43:33:2e:7e:25:3b:
- a4:04:d1:60:8c:b3:44:33:93:0c:ad:2a:b6:44:a2:
- 19:3b:af:c4:90:6f:7b:05:87:86:9b:2c:6a:9d:2b:
- 6c:77:c9:00:9f:c9:cf:ac:ed:3e:1b:f7:c3:f3:d9:
- f8:6c:d4:a0:57:c4:fb:28:32:aa:33:f0:e6:ba:98:
- df:e5:c2:4e:9c:74:bf:8a:48:c2:f2:1b:f0:77:40:
- 41:07:04:b2:3a:d5:4c:c4:29:a9:11:40:3f:02:46:
- f0:91:d5:d2:81:83:86:13:b3:31:ed:46:ab:a8:87:
- 76:a9:99:7d:bc:cd:31:50:f4:a5:b5:dc:a5:32:b3:
- 8b:8b
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- Authority Information Access:
- OCSP - URI:http://ocsp.thawte.com
-
- X509v3 Basic Constraints: critical
- CA:TRUE, pathlen:0
- X509v3 Certificate Policies:
- Policy: 2.16.840.1.113733.1.7.54
- CPS: https://www.thawte.com/cps
-
- X509v3 CRL Distribution Points:
-
- Full Name:
- URI:http://crl.thawte.com/ThawtePCA-G3.crl
-
- X509v3 Key Usage: critical
- Certificate Sign, CRL Sign
- X509v3 Subject Alternative Name:
- DirName:/CN=VeriSignMPKI-2-415
- X509v3 Subject Key Identifier:
- 2B:9A:35:AE:01:18:38:30:E1:70:7A:05:E0:11:76:A3:CE:BD:90:14
- X509v3 Authority Key Identifier:
- keyid:AD:6C:AA:94:60:9C:ED:E4:FF:FA:3E:0A:74:2B:63:03:F7:B6:59:BF
-
- Signature Algorithm: sha256WithRSAEncryption
- 74:a6:56:e8:af:93:96:19:fb:26:f9:0d:b0:44:a5:cd:e9:7a:
- 48:03:74:01:6c:13:71:b7:e0:82:90:99:62:23:e3:d6:99:af:
- f0:c7:1e:9e:a8:18:21:db:b4:94:3f:34:56:1b:99:55:2f:8e:
- f0:45:33:32:b7:72:c1:13:5b:34:d3:f5:60:e5:2e:18:d1:5c:
- c5:6a:c1:aa:87:50:0c:1c:9d:64:2b:ff:1b:dc:d5:2e:61:0b:
- e7:b9:b6:91:53:86:d9:03:2a:d1:3d:7b:4a:da:2b:07:be:29:
- f2:60:42:a9:91:1a:0e:2e:3c:d1:7d:a5:13:14:02:fa:ee:8b:
- 8d:b6:c8:b8:3e:56:81:57:21:24:3f:65:c3:b4:c9:ce:5c:8d:
- 46:ac:53:f3:f9:55:74:c8:2b:fd:d2:78:70:f5:f8:11:e5:f4:
- a7:ad:20:f5:9d:f1:ec:70:f6:13:ac:e6:8c:8d:db:3f:c6:f2:
- 79:0e:ab:52:f2:cc:1b:79:27:cf:16:b3:d6:f3:c6:36:80:43:
- ec:c5:94:f0:dd:90:8d:f8:c6:52:46:56:eb:74:47:be:a6:f3:
- 19:ae:71:4c:c0:e1:e7:d4:cf:ed:d4:06:28:2a:11:3c:ba:d9:
- 41:6e:00:e7:81:37:93:e4:da:62:c6:1d:67:6f:63:b4:14:86:
- d9:a6:62:f0
------BEGIN CERTIFICATE-----
-MIIEwjCCA6qgAwIBAgIQNjSeGMmcJmm2Vi5s5a1xMjANBgkqhkiG9w0BAQsFADCB
-rjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMf
-Q2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIw
-MDggdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxJDAiBgNV
-BAMTG3RoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EgLSBHMzAeFw0xMzA1MjMwMDAwMDBa
-Fw0yMzA1MjIyMzU5NTlaMEMxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwx0aGF3dGUs
-IEluYy4xHTAbBgNVBAMTFHRoYXd0ZSBTSEEyNTYgU1NMIENBMIIBIjANBgkqhkiG
-9w0BAQEFAAOCAQ8AMIIBCgKCAQEAo2Mr1LpdOK6wz7lMON8gffErR3Edi2jzVvmc
-2qrlhCbepXEwvPMxI53oO4DIZld1tlcO25P1Jo5wumRSZooqiFxEGE2oony9VmEy
-kBL5NYdIYLBukGdEAY3nyQ1jaHJyq2M8hrgffa2IJadqiCn7WcZ4cV8suonm04D9
-V+y5UV9DMy5+JTukBNFgjLNEM5MMrSq2RKIZO6/EkG97BYeGmyxqnStsd8kAn8nP
-rO0+G/fD89n4bNSgV8T7KDKqM/Dmupjf5cJOnHS/ikjC8hvwd0BBBwSyOtVMxCmp
-EUA/AkbwkdXSgYOGE7Mx7UarqId2qZl9vM0xUPSltdylMrOLiwIDAQABo4IBRDCC
-AUAwMgYIKwYBBQUHAQEEJjAkMCIGCCsGAQUFBzABhhZodHRwOi8vb2NzcC50aGF3
-dGUuY29tMBIGA1UdEwEB/wQIMAYBAf8CAQAwQQYDVR0gBDowODA2BgpghkgBhvhF
-AQc2MCgwJgYIKwYBBQUHAgEWGmh0dHBzOi8vd3d3LnRoYXd0ZS5jb20vY3BzMDcG
-A1UdHwQwMC4wLKAqoCiGJmh0dHA6Ly9jcmwudGhhd3RlLmNvbS9UaGF3dGVQQ0Et
-RzMuY3JsMA4GA1UdDwEB/wQEAwIBBjAqBgNVHREEIzAhpB8wHTEbMBkGA1UEAxMS
-VmVyaVNpZ25NUEtJLTItNDE1MB0GA1UdDgQWBBQrmjWuARg4MOFwegXgEXajzr2Q
-FDAfBgNVHSMEGDAWgBStbKqUYJzt5P/6Pgp0K2MD97ZZvzANBgkqhkiG9w0BAQsF
-AAOCAQEAdKZW6K+Tlhn7JvkNsESlzel6SAN0AWwTcbfggpCZYiPj1pmv8McenqgY
-Idu0lD80VhuZVS+O8EUzMrdywRNbNNP1YOUuGNFcxWrBqodQDBydZCv/G9zVLmEL
-57m2kVOG2QMq0T17StorB74p8mBCqZEaDi480X2lExQC+u6LjbbIuD5WgVchJD9l
-w7TJzlyNRqxT8/lVdMgr/dJ4cPX4EeX0p60g9Z3x7HD2E6zmjI3bP8byeQ6rUvLM
-G3knzxaz1vPGNoBD7MWU8N2QjfjGUkZW63RHvqbzGa5xTMDh59TP7dQGKCoRPLrZ
-QW4A54E3k+TaYsYdZ29jtBSG2aZi8A==
------END CERTIFICATE-----
-#endif
-static const unsigned char kDERCert29[] = {
- 0x30, 0x82, 0x04, 0xc2, 0x30, 0x82, 0x03, 0xaa, 0xa0, 0x03, 0x02, 0x01,
- 0x02, 0x02, 0x10, 0x36, 0x34, 0x9e, 0x18, 0xc9, 0x9c, 0x26, 0x69, 0xb6,
- 0x56, 0x2e, 0x6c, 0xe5, 0xad, 0x71, 0x32, 0x30, 0x0d, 0x06, 0x09, 0x2a,
- 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x81,
- 0xae, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
- 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13,
- 0x0c, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63,
- 0x2e, 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1f,
- 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f,
- 0x6e, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, 0x44,
- 0x69, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x31, 0x38, 0x30, 0x36, 0x06,
- 0x03, 0x55, 0x04, 0x0b, 0x13, 0x2f, 0x28, 0x63, 0x29, 0x20, 0x32, 0x30,
- 0x30, 0x38, 0x20, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2c, 0x20, 0x49,
- 0x6e, 0x63, 0x2e, 0x20, 0x2d, 0x20, 0x46, 0x6f, 0x72, 0x20, 0x61, 0x75,
- 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x20, 0x75, 0x73, 0x65,
- 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x31, 0x24, 0x30, 0x22, 0x06, 0x03, 0x55,
- 0x04, 0x03, 0x13, 0x1b, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x20, 0x50,
- 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20,
- 0x43, 0x41, 0x20, 0x2d, 0x20, 0x47, 0x33, 0x30, 0x1e, 0x17, 0x0d, 0x31,
- 0x33, 0x30, 0x35, 0x32, 0x33, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a,
- 0x17, 0x0d, 0x32, 0x33, 0x30, 0x35, 0x32, 0x32, 0x32, 0x33, 0x35, 0x39,
- 0x35, 0x39, 0x5a, 0x30, 0x43, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55,
- 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03,
- 0x55, 0x04, 0x0a, 0x13, 0x0c, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2c,
- 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x1d, 0x30, 0x1b, 0x06, 0x03, 0x55,
- 0x04, 0x03, 0x13, 0x14, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x20, 0x53,
- 0x48, 0x41, 0x32, 0x35, 0x36, 0x20, 0x53, 0x53, 0x4c, 0x20, 0x43, 0x41,
- 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
- 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00,
- 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xa3, 0x63, 0x2b,
- 0xd4, 0xba, 0x5d, 0x38, 0xae, 0xb0, 0xcf, 0xb9, 0x4c, 0x38, 0xdf, 0x20,
- 0x7d, 0xf1, 0x2b, 0x47, 0x71, 0x1d, 0x8b, 0x68, 0xf3, 0x56, 0xf9, 0x9c,
- 0xda, 0xaa, 0xe5, 0x84, 0x26, 0xde, 0xa5, 0x71, 0x30, 0xbc, 0xf3, 0x31,
- 0x23, 0x9d, 0xe8, 0x3b, 0x80, 0xc8, 0x66, 0x57, 0x75, 0xb6, 0x57, 0x0e,
- 0xdb, 0x93, 0xf5, 0x26, 0x8e, 0x70, 0xba, 0x64, 0x52, 0x66, 0x8a, 0x2a,
- 0x88, 0x5c, 0x44, 0x18, 0x4d, 0xa8, 0xa2, 0x7c, 0xbd, 0x56, 0x61, 0x32,
- 0x90, 0x12, 0xf9, 0x35, 0x87, 0x48, 0x60, 0xb0, 0x6e, 0x90, 0x67, 0x44,
- 0x01, 0x8d, 0xe7, 0xc9, 0x0d, 0x63, 0x68, 0x72, 0x72, 0xab, 0x63, 0x3c,
- 0x86, 0xb8, 0x1f, 0x7d, 0xad, 0x88, 0x25, 0xa7, 0x6a, 0x88, 0x29, 0xfb,
- 0x59, 0xc6, 0x78, 0x71, 0x5f, 0x2c, 0xba, 0x89, 0xe6, 0xd3, 0x80, 0xfd,
- 0x57, 0xec, 0xb9, 0x51, 0x5f, 0x43, 0x33, 0x2e, 0x7e, 0x25, 0x3b, 0xa4,
- 0x04, 0xd1, 0x60, 0x8c, 0xb3, 0x44, 0x33, 0x93, 0x0c, 0xad, 0x2a, 0xb6,
- 0x44, 0xa2, 0x19, 0x3b, 0xaf, 0xc4, 0x90, 0x6f, 0x7b, 0x05, 0x87, 0x86,
- 0x9b, 0x2c, 0x6a, 0x9d, 0x2b, 0x6c, 0x77, 0xc9, 0x00, 0x9f, 0xc9, 0xcf,
- 0xac, 0xed, 0x3e, 0x1b, 0xf7, 0xc3, 0xf3, 0xd9, 0xf8, 0x6c, 0xd4, 0xa0,
- 0x57, 0xc4, 0xfb, 0x28, 0x32, 0xaa, 0x33, 0xf0, 0xe6, 0xba, 0x98, 0xdf,
- 0xe5, 0xc2, 0x4e, 0x9c, 0x74, 0xbf, 0x8a, 0x48, 0xc2, 0xf2, 0x1b, 0xf0,
- 0x77, 0x40, 0x41, 0x07, 0x04, 0xb2, 0x3a, 0xd5, 0x4c, 0xc4, 0x29, 0xa9,
- 0x11, 0x40, 0x3f, 0x02, 0x46, 0xf0, 0x91, 0xd5, 0xd2, 0x81, 0x83, 0x86,
- 0x13, 0xb3, 0x31, 0xed, 0x46, 0xab, 0xa8, 0x87, 0x76, 0xa9, 0x99, 0x7d,
- 0xbc, 0xcd, 0x31, 0x50, 0xf4, 0xa5, 0xb5, 0xdc, 0xa5, 0x32, 0xb3, 0x8b,
- 0x8b, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x44, 0x30, 0x82,
- 0x01, 0x40, 0x30, 0x32, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
- 0x01, 0x01, 0x04, 0x26, 0x30, 0x24, 0x30, 0x22, 0x06, 0x08, 0x2b, 0x06,
- 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x16, 0x68, 0x74, 0x74, 0x70,
- 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x74, 0x68, 0x61, 0x77,
- 0x74, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d,
- 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02,
- 0x01, 0x00, 0x30, 0x41, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x3a, 0x30,
- 0x38, 0x30, 0x36, 0x06, 0x0a, 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x45,
- 0x01, 0x07, 0x36, 0x30, 0x28, 0x30, 0x26, 0x06, 0x08, 0x2b, 0x06, 0x01,
- 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x1a, 0x68, 0x74, 0x74, 0x70, 0x73,
- 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x74, 0x68, 0x61, 0x77, 0x74,
- 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x70, 0x73, 0x30, 0x37, 0x06,
- 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x30, 0x30, 0x2e, 0x30, 0x2c, 0xa0, 0x2a,
- 0xa0, 0x28, 0x86, 0x26, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63,
- 0x72, 0x6c, 0x2e, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2e, 0x63, 0x6f,
- 0x6d, 0x2f, 0x54, 0x68, 0x61, 0x77, 0x74, 0x65, 0x50, 0x43, 0x41, 0x2d,
- 0x47, 0x33, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d,
- 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x2a,
- 0x06, 0x03, 0x55, 0x1d, 0x11, 0x04, 0x23, 0x30, 0x21, 0xa4, 0x1f, 0x30,
- 0x1d, 0x31, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x12,
- 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x4d, 0x50, 0x4b, 0x49,
- 0x2d, 0x32, 0x2d, 0x34, 0x31, 0x35, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d,
- 0x0e, 0x04, 0x16, 0x04, 0x14, 0x2b, 0x9a, 0x35, 0xae, 0x01, 0x18, 0x38,
- 0x30, 0xe1, 0x70, 0x7a, 0x05, 0xe0, 0x11, 0x76, 0xa3, 0xce, 0xbd, 0x90,
- 0x14, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16,
- 0x80, 0x14, 0xad, 0x6c, 0xaa, 0x94, 0x60, 0x9c, 0xed, 0xe4, 0xff, 0xfa,
- 0x3e, 0x0a, 0x74, 0x2b, 0x63, 0x03, 0xf7, 0xb6, 0x59, 0xbf, 0x30, 0x0d,
- 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05,
- 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x74, 0xa6, 0x56, 0xe8, 0xaf, 0x93,
- 0x96, 0x19, 0xfb, 0x26, 0xf9, 0x0d, 0xb0, 0x44, 0xa5, 0xcd, 0xe9, 0x7a,
- 0x48, 0x03, 0x74, 0x01, 0x6c, 0x13, 0x71, 0xb7, 0xe0, 0x82, 0x90, 0x99,
- 0x62, 0x23, 0xe3, 0xd6, 0x99, 0xaf, 0xf0, 0xc7, 0x1e, 0x9e, 0xa8, 0x18,
- 0x21, 0xdb, 0xb4, 0x94, 0x3f, 0x34, 0x56, 0x1b, 0x99, 0x55, 0x2f, 0x8e,
- 0xf0, 0x45, 0x33, 0x32, 0xb7, 0x72, 0xc1, 0x13, 0x5b, 0x34, 0xd3, 0xf5,
- 0x60, 0xe5, 0x2e, 0x18, 0xd1, 0x5c, 0xc5, 0x6a, 0xc1, 0xaa, 0x87, 0x50,
- 0x0c, 0x1c, 0x9d, 0x64, 0x2b, 0xff, 0x1b, 0xdc, 0xd5, 0x2e, 0x61, 0x0b,
- 0xe7, 0xb9, 0xb6, 0x91, 0x53, 0x86, 0xd9, 0x03, 0x2a, 0xd1, 0x3d, 0x7b,
- 0x4a, 0xda, 0x2b, 0x07, 0xbe, 0x29, 0xf2, 0x60, 0x42, 0xa9, 0x91, 0x1a,
- 0x0e, 0x2e, 0x3c, 0xd1, 0x7d, 0xa5, 0x13, 0x14, 0x02, 0xfa, 0xee, 0x8b,
- 0x8d, 0xb6, 0xc8, 0xb8, 0x3e, 0x56, 0x81, 0x57, 0x21, 0x24, 0x3f, 0x65,
- 0xc3, 0xb4, 0xc9, 0xce, 0x5c, 0x8d, 0x46, 0xac, 0x53, 0xf3, 0xf9, 0x55,
- 0x74, 0xc8, 0x2b, 0xfd, 0xd2, 0x78, 0x70, 0xf5, 0xf8, 0x11, 0xe5, 0xf4,
- 0xa7, 0xad, 0x20, 0xf5, 0x9d, 0xf1, 0xec, 0x70, 0xf6, 0x13, 0xac, 0xe6,
- 0x8c, 0x8d, 0xdb, 0x3f, 0xc6, 0xf2, 0x79, 0x0e, 0xab, 0x52, 0xf2, 0xcc,
- 0x1b, 0x79, 0x27, 0xcf, 0x16, 0xb3, 0xd6, 0xf3, 0xc6, 0x36, 0x80, 0x43,
- 0xec, 0xc5, 0x94, 0xf0, 0xdd, 0x90, 0x8d, 0xf8, 0xc6, 0x52, 0x46, 0x56,
- 0xeb, 0x74, 0x47, 0xbe, 0xa6, 0xf3, 0x19, 0xae, 0x71, 0x4c, 0xc0, 0xe1,
- 0xe7, 0xd4, 0xcf, 0xed, 0xd4, 0x06, 0x28, 0x2a, 0x11, 0x3c, 0xba, 0xd9,
- 0x41, 0x6e, 0x00, 0xe7, 0x81, 0x37, 0x93, 0xe4, 0xda, 0x62, 0xc6, 0x1d,
- 0x67, 0x6f, 0x63, 0xb4, 0x14, 0x86, 0xd9, 0xa6, 0x62, 0xf0,
-};
-
-#if 0
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number:
- 35:97:31:87:f3:87:3a:07:32:7e:ce:58:0c:9b:7e:da
- Signature Algorithm: sha1WithRSAEncryption
- Issuer: C=US, O=VeriSign, Inc., OU=Class 3 Public Primary Certification Authority
- Validity
- Not Before: Nov 8 00:00:00 2006 GMT
- Not After : Nov 7 23:59:59 2021 GMT
- Subject: C=US, O=VeriSign, Inc., OU=VeriSign Trust Network, OU=(c) 2006 VeriSign, Inc. - For authorized use only, CN=VeriSign Class 3 Public Primary Certification Authority - G5
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:af:24:08:08:29:7a:35:9e:60:0c:aa:e7:4b:3b:
- 4e:dc:7c:bc:3c:45:1c:bb:2b:e0:fe:29:02:f9:57:
- 08:a3:64:85:15:27:f5:f1:ad:c8:31:89:5d:22:e8:
- 2a:aa:a6:42:b3:8f:f8:b9:55:b7:b1:b7:4b:b3:fe:
- 8f:7e:07:57:ec:ef:43:db:66:62:15:61:cf:60:0d:
- a4:d8:de:f8:e0:c3:62:08:3d:54:13:eb:49:ca:59:
- 54:85:26:e5:2b:8f:1b:9f:eb:f5:a1:91:c2:33:49:
- d8:43:63:6a:52:4b:d2:8f:e8:70:51:4d:d1:89:69:
- 7b:c7:70:f6:b3:dc:12:74:db:7b:5d:4b:56:d3:96:
- bf:15:77:a1:b0:f4:a2:25:f2:af:1c:92:67:18:e5:
- f4:06:04:ef:90:b9:e4:00:e4:dd:3a:b5:19:ff:02:
- ba:f4:3c:ee:e0:8b:eb:37:8b:ec:f4:d7:ac:f2:f6:
- f0:3d:af:dd:75:91:33:19:1d:1c:40:cb:74:24:19:
- 21:93:d9:14:fe:ac:2a:52:c7:8f:d5:04:49:e4:8d:
- 63:47:88:3c:69:83:cb:fe:47:bd:2b:7e:4f:c5:95:
- ae:0e:9d:d4:d1:43:c0:67:73:e3:14:08:7e:e5:3f:
- 9f:73:b8:33:0a:cf:5d:3f:34:87:96:8a:ee:53:e8:
- 25:15
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Basic Constraints: critical
- CA:TRUE
- X509v3 CRL Distribution Points:
-
- Full Name:
- URI:http://crl.verisign.com/pca3.crl
-
- X509v3 Key Usage: critical
- Certificate Sign, CRL Sign
- X509v3 Certificate Policies:
- Policy: X509v3 Any Policy
- CPS: https://www.verisign.com/cps
-
- X509v3 Subject Key Identifier:
- 7F:D3:65:A7:C2:DD:EC:BB:F0:30:09:F3:43:39:FA:02:AF:33:31:33
- X509v3 Extended Key Usage:
- Netscape Server Gated Crypto, 2.16.840.1.113733.1.8.1, TLS Web Server Authentication, TLS Web Client Authentication
- 1.3.6.1.5.5.7.1.12:
- 0_.].[0Y0W0U..image/gif0!0.0...+..............k...j.H.,{..0%.#http://logo.verisign.com/vslogo.gif
- Authority Information Access:
- OCSP - URI:http://ocsp.verisign.com
-
- Signature Algorithm: sha1WithRSAEncryption
- 0f:25:ae:48:ed:1b:33:85:4c:0c:b5:c2:d7:fe:4d:d6:83:28:
- 4c:41:65:60:00:0b:77:48:71:82:fe:7f:db:5a:0e:20:cc:d2:
- ea:47:bc:64:42:61:44:34:74:30:81:81:26:8a:4a:f7:44:5d:
- 7e:34:80:a8:b8:83:e2:09:d7:6d:23:dd:89:ed:28:08:bd:63:
- 5a:11:57:08:c4:9e:da:e2:68:28:af:dd:50:3c:ec:82:21:d8:
- 00:c2:55:44:50:70:41:ad:83:17:79:ba:08:f3:2b:de:ed:34:
- 1d:44:9e:d2:04:93:f4:cb:05:17:2d:09:2d:2d:63:ef:f6:26:
- 0b:7b
------BEGIN CERTIFICATE-----
-MIIExjCCBC+gAwIBAgIQNZcxh/OHOgcyfs5YDJt+2jANBgkqhkiG9w0BAQUFADBf
-MQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xNzA1BgNVBAsT
-LkNsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkw
-HhcNMDYxMTA4MDAwMDAwWhcNMjExMTA3MjM1OTU5WjCByjELMAkGA1UEBhMCVVMx
-FzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBUcnVz
-dCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJpU2lnbiwgSW5jLiAtIEZv
-ciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAz
-IFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzUwggEi
-MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvJAgIKXo1nmAMqudLO07cfLw8
-RRy7K+D+KQL5VwijZIUVJ/XxrcgxiV0i6CqqpkKzj/i5Vbext0uz/o9+B1fs70Pb
-ZmIVYc9gDaTY3vjgw2IIPVQT60nKWVSFJuUrjxuf6/WhkcIzSdhDY2pSS9KP6HBR
-TdGJaXvHcPaz3BJ023tdS1bTlr8Vd6Gw9KIl8q8ckmcY5fQGBO+QueQA5N06tRn/
-Arr0PO7gi+s3i+z016zy9vA9r911kTMZHRxAy3QkGSGT2RT+rCpSx4/VBEnkjWNH
-iDxpg8v+R70rfk/Fla4OndTRQ8Bnc+MUCH7lP59zuDMKz10/NIeWiu5T6CUVAgMB
-AAGjggGRMIIBjTAPBgNVHRMBAf8EBTADAQH/MDEGA1UdHwQqMCgwJqAkoCKGIGh0
-dHA6Ly9jcmwudmVyaXNpZ24uY29tL3BjYTMuY3JsMA4GA1UdDwEB/wQEAwIBBjA9
-BgNVHSAENjA0MDIGBFUdIAAwKjAoBggrBgEFBQcCARYcaHR0cHM6Ly93d3cudmVy
-aXNpZ24uY29tL2NwczAdBgNVHQ4EFgQUf9Nlp8Ld7LvwMAnzQzn6Aq8zMTMwNAYD
-VR0lBC0wKwYJYIZIAYb4QgQBBgpghkgBhvhFAQgBBggrBgEFBQcDAQYIKwYBBQUH
-AwIwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2UvZ2lmMCEwHzAHBgUr
-DgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDovL2xvZ28udmVyaXNp
-Z24uY29tL3ZzbG9nby5naWYwNAYIKwYBBQUHAQEEKDAmMCQGCCsGAQUFBzABhhho
-dHRwOi8vb2NzcC52ZXJpc2lnbi5jb20wDQYJKoZIhvcNAQEFBQADgYEADyWuSO0b
-M4VMDLXC1/5N1oMoTEFlYAALd0hxgv5/21oOIMzS6ke8ZEJhRDR0MIGBJopK90Rd
-fjSAqLiD4gnXbSPdie0oCL1jWhFXCMSe2uJoKK/dUDzsgiHYAMJVRFBwQa2DF3m6
-CPMr3u00HUSe0gST9MsFFy0JLS1j7/YmC3s=
------END CERTIFICATE-----
-#endif
-static const unsigned char kDERCert30[] = {
- 0x30, 0x82, 0x04, 0xc6, 0x30, 0x82, 0x04, 0x2f, 0xa0, 0x03, 0x02, 0x01,
- 0x02, 0x02, 0x10, 0x35, 0x97, 0x31, 0x87, 0xf3, 0x87, 0x3a, 0x07, 0x32,
- 0x7e, 0xce, 0x58, 0x0c, 0x9b, 0x7e, 0xda, 0x30, 0x0d, 0x06, 0x09, 0x2a,
- 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x5f,
- 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55,
- 0x53, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0e,
- 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e,
- 0x63, 0x2e, 0x31, 0x37, 0x30, 0x35, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13,
- 0x2e, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x33, 0x20, 0x50, 0x75, 0x62,
- 0x6c, 0x69, 0x63, 0x20, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x20,
- 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f,
- 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x30,
- 0x1e, 0x17, 0x0d, 0x30, 0x36, 0x31, 0x31, 0x30, 0x38, 0x30, 0x30, 0x30,
- 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x31, 0x31, 0x31, 0x30, 0x37,
- 0x32, 0x33, 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x81, 0xca, 0x31, 0x0b,
- 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31,
- 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0e, 0x56, 0x65,
- 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e,
- 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x16, 0x56,
- 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x54, 0x72, 0x75, 0x73,
- 0x74, 0x20, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x31, 0x3a, 0x30,
- 0x38, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x31, 0x28, 0x63, 0x29, 0x20,
- 0x32, 0x30, 0x30, 0x36, 0x20, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67,
- 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x20, 0x2d, 0x20, 0x46, 0x6f,
- 0x72, 0x20, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64,
- 0x20, 0x75, 0x73, 0x65, 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x31, 0x45, 0x30,
- 0x43, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x3c, 0x56, 0x65, 0x72, 0x69,
- 0x53, 0x69, 0x67, 0x6e, 0x20, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x33,
- 0x20, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x20, 0x50, 0x72, 0x69, 0x6d,
- 0x61, 0x72, 0x79, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63,
- 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72,
- 0x69, 0x74, 0x79, 0x20, 0x2d, 0x20, 0x47, 0x35, 0x30, 0x82, 0x01, 0x22,
- 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
- 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a,
- 0x02, 0x82, 0x01, 0x01, 0x00, 0xaf, 0x24, 0x08, 0x08, 0x29, 0x7a, 0x35,
- 0x9e, 0x60, 0x0c, 0xaa, 0xe7, 0x4b, 0x3b, 0x4e, 0xdc, 0x7c, 0xbc, 0x3c,
- 0x45, 0x1c, 0xbb, 0x2b, 0xe0, 0xfe, 0x29, 0x02, 0xf9, 0x57, 0x08, 0xa3,
- 0x64, 0x85, 0x15, 0x27, 0xf5, 0xf1, 0xad, 0xc8, 0x31, 0x89, 0x5d, 0x22,
- 0xe8, 0x2a, 0xaa, 0xa6, 0x42, 0xb3, 0x8f, 0xf8, 0xb9, 0x55, 0xb7, 0xb1,
- 0xb7, 0x4b, 0xb3, 0xfe, 0x8f, 0x7e, 0x07, 0x57, 0xec, 0xef, 0x43, 0xdb,
- 0x66, 0x62, 0x15, 0x61, 0xcf, 0x60, 0x0d, 0xa4, 0xd8, 0xde, 0xf8, 0xe0,
- 0xc3, 0x62, 0x08, 0x3d, 0x54, 0x13, 0xeb, 0x49, 0xca, 0x59, 0x54, 0x85,
- 0x26, 0xe5, 0x2b, 0x8f, 0x1b, 0x9f, 0xeb, 0xf5, 0xa1, 0x91, 0xc2, 0x33,
- 0x49, 0xd8, 0x43, 0x63, 0x6a, 0x52, 0x4b, 0xd2, 0x8f, 0xe8, 0x70, 0x51,
- 0x4d, 0xd1, 0x89, 0x69, 0x7b, 0xc7, 0x70, 0xf6, 0xb3, 0xdc, 0x12, 0x74,
- 0xdb, 0x7b, 0x5d, 0x4b, 0x56, 0xd3, 0x96, 0xbf, 0x15, 0x77, 0xa1, 0xb0,
- 0xf4, 0xa2, 0x25, 0xf2, 0xaf, 0x1c, 0x92, 0x67, 0x18, 0xe5, 0xf4, 0x06,
- 0x04, 0xef, 0x90, 0xb9, 0xe4, 0x00, 0xe4, 0xdd, 0x3a, 0xb5, 0x19, 0xff,
- 0x02, 0xba, 0xf4, 0x3c, 0xee, 0xe0, 0x8b, 0xeb, 0x37, 0x8b, 0xec, 0xf4,
- 0xd7, 0xac, 0xf2, 0xf6, 0xf0, 0x3d, 0xaf, 0xdd, 0x75, 0x91, 0x33, 0x19,
- 0x1d, 0x1c, 0x40, 0xcb, 0x74, 0x24, 0x19, 0x21, 0x93, 0xd9, 0x14, 0xfe,
- 0xac, 0x2a, 0x52, 0xc7, 0x8f, 0xd5, 0x04, 0x49, 0xe4, 0x8d, 0x63, 0x47,
- 0x88, 0x3c, 0x69, 0x83, 0xcb, 0xfe, 0x47, 0xbd, 0x2b, 0x7e, 0x4f, 0xc5,
- 0x95, 0xae, 0x0e, 0x9d, 0xd4, 0xd1, 0x43, 0xc0, 0x67, 0x73, 0xe3, 0x14,
- 0x08, 0x7e, 0xe5, 0x3f, 0x9f, 0x73, 0xb8, 0x33, 0x0a, 0xcf, 0x5d, 0x3f,
- 0x34, 0x87, 0x96, 0x8a, 0xee, 0x53, 0xe8, 0x25, 0x15, 0x02, 0x03, 0x01,
- 0x00, 0x01, 0xa3, 0x82, 0x01, 0x91, 0x30, 0x82, 0x01, 0x8d, 0x30, 0x0f,
- 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, 0x30, 0x03,
- 0x01, 0x01, 0xff, 0x30, 0x31, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x2a,
- 0x30, 0x28, 0x30, 0x26, 0xa0, 0x24, 0xa0, 0x22, 0x86, 0x20, 0x68, 0x74,
- 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x76, 0x65, 0x72,
- 0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x63,
- 0x61, 0x33, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d,
- 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x3d,
- 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x36, 0x30, 0x34, 0x30, 0x32, 0x06,
- 0x04, 0x55, 0x1d, 0x20, 0x00, 0x30, 0x2a, 0x30, 0x28, 0x06, 0x08, 0x2b,
- 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x1c, 0x68, 0x74, 0x74,
- 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x76, 0x65, 0x72,
- 0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x70,
- 0x73, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14,
- 0x7f, 0xd3, 0x65, 0xa7, 0xc2, 0xdd, 0xec, 0xbb, 0xf0, 0x30, 0x09, 0xf3,
- 0x43, 0x39, 0xfa, 0x02, 0xaf, 0x33, 0x31, 0x33, 0x30, 0x34, 0x06, 0x03,
- 0x55, 0x1d, 0x25, 0x04, 0x2d, 0x30, 0x2b, 0x06, 0x09, 0x60, 0x86, 0x48,
- 0x01, 0x86, 0xf8, 0x42, 0x04, 0x01, 0x06, 0x0a, 0x60, 0x86, 0x48, 0x01,
- 0x86, 0xf8, 0x45, 0x01, 0x08, 0x01, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05,
- 0x05, 0x07, 0x03, 0x01, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
- 0x03, 0x02, 0x30, 0x6d, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
- 0x01, 0x0c, 0x04, 0x61, 0x30, 0x5f, 0xa1, 0x5d, 0xa0, 0x5b, 0x30, 0x59,
- 0x30, 0x57, 0x30, 0x55, 0x16, 0x09, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2f,
- 0x67, 0x69, 0x66, 0x30, 0x21, 0x30, 0x1f, 0x30, 0x07, 0x06, 0x05, 0x2b,
- 0x0e, 0x03, 0x02, 0x1a, 0x04, 0x14, 0x8f, 0xe5, 0xd3, 0x1a, 0x86, 0xac,
- 0x8d, 0x8e, 0x6b, 0xc3, 0xcf, 0x80, 0x6a, 0xd4, 0x48, 0x18, 0x2c, 0x7b,
- 0x19, 0x2e, 0x30, 0x25, 0x16, 0x23, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f,
- 0x2f, 0x6c, 0x6f, 0x67, 0x6f, 0x2e, 0x76, 0x65, 0x72, 0x69, 0x73, 0x69,
- 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x76, 0x73, 0x6c, 0x6f, 0x67,
- 0x6f, 0x2e, 0x67, 0x69, 0x66, 0x30, 0x34, 0x06, 0x08, 0x2b, 0x06, 0x01,
- 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x28, 0x30, 0x26, 0x30, 0x24, 0x06,
- 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x18, 0x68,
- 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x76,
- 0x65, 0x72, 0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x30,
- 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05,
- 0x05, 0x00, 0x03, 0x81, 0x81, 0x00, 0x0f, 0x25, 0xae, 0x48, 0xed, 0x1b,
- 0x33, 0x85, 0x4c, 0x0c, 0xb5, 0xc2, 0xd7, 0xfe, 0x4d, 0xd6, 0x83, 0x28,
- 0x4c, 0x41, 0x65, 0x60, 0x00, 0x0b, 0x77, 0x48, 0x71, 0x82, 0xfe, 0x7f,
- 0xdb, 0x5a, 0x0e, 0x20, 0xcc, 0xd2, 0xea, 0x47, 0xbc, 0x64, 0x42, 0x61,
- 0x44, 0x34, 0x74, 0x30, 0x81, 0x81, 0x26, 0x8a, 0x4a, 0xf7, 0x44, 0x5d,
- 0x7e, 0x34, 0x80, 0xa8, 0xb8, 0x83, 0xe2, 0x09, 0xd7, 0x6d, 0x23, 0xdd,
- 0x89, 0xed, 0x28, 0x08, 0xbd, 0x63, 0x5a, 0x11, 0x57, 0x08, 0xc4, 0x9e,
- 0xda, 0xe2, 0x68, 0x28, 0xaf, 0xdd, 0x50, 0x3c, 0xec, 0x82, 0x21, 0xd8,
- 0x00, 0xc2, 0x55, 0x44, 0x50, 0x70, 0x41, 0xad, 0x83, 0x17, 0x79, 0xba,
- 0x08, 0xf3, 0x2b, 0xde, 0xed, 0x34, 0x1d, 0x44, 0x9e, 0xd2, 0x04, 0x93,
- 0xf4, 0xcb, 0x05, 0x17, 0x2d, 0x09, 0x2d, 0x2d, 0x63, 0xef, 0xf6, 0x26,
- 0x0b, 0x7b,
-};
-
-#if 0
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number: 7 (0x7)
- Signature Algorithm: sha256WithRSAEncryption
- Issuer: C=US, ST=Arizona, L=Scottsdale, O=GoDaddy.com, Inc., CN=Go Daddy Root Certificate Authority - G2
- Validity
- Not Before: May 3 07:00:00 2011 GMT
- Not After : May 3 07:00:00 2031 GMT
- Subject: C=US, ST=Arizona, L=Scottsdale, O=GoDaddy.com, Inc., OU=http://certs.godaddy.com/repository/, CN=Go Daddy Secure Certificate Authority - G2
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:b9:e0:cb:10:d4:af:76:bd:d4:93:62:eb:30:64:
- b8:81:08:6c:c3:04:d9:62:17:8e:2f:ff:3e:65:cf:
- 8f:ce:62:e6:3c:52:1c:da:16:45:4b:55:ab:78:6b:
- 63:83:62:90:ce:0f:69:6c:99:c8:1a:14:8b:4c:cc:
- 45:33:ea:88:dc:9e:a3:af:2b:fe:80:61:9d:79:57:
- c4:cf:2e:f4:3f:30:3c:5d:47:fc:9a:16:bc:c3:37:
- 96:41:51:8e:11:4b:54:f8:28:be:d0:8c:be:f0:30:
- 38:1e:f3:b0:26:f8:66:47:63:6d:de:71:26:47:8f:
- 38:47:53:d1:46:1d:b4:e3:dc:00:ea:45:ac:bd:bc:
- 71:d9:aa:6f:00:db:db:cd:30:3a:79:4f:5f:4c:47:
- f8:1d:ef:5b:c2:c4:9d:60:3b:b1:b2:43:91:d8:a4:
- 33:4e:ea:b3:d6:27:4f:ad:25:8a:a5:c6:f4:d5:d0:
- a6:ae:74:05:64:57:88:b5:44:55:d4:2d:2a:3a:3e:
- f8:b8:bd:e9:32:0a:02:94:64:c4:16:3a:50:f1:4a:
- ae:e7:79:33:af:0c:20:07:7f:e8:df:04:39:c2:69:
- 02:6c:63:52:fa:77:c1:1b:c8:74:87:c8:b9:93:18:
- 50:54:35:4b:69:4e:bc:3b:d3:49:2e:1f:dc:c1:d2:
- 52:fb
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Basic Constraints: critical
- CA:TRUE
- X509v3 Key Usage: critical
- Certificate Sign, CRL Sign
- X509v3 Subject Key Identifier:
- 40:C2:BD:27:8E:CC:34:83:30:A2:33:D7:FB:6C:B3:F0:B4:2C:80:CE
- X509v3 Authority Key Identifier:
- keyid:3A:9A:85:07:10:67:28:B6:EF:F6:BD:05:41:6E:20:C1:94:DA:0F:DE
-
- Authority Information Access:
- OCSP - URI:http://ocsp.godaddy.com/
-
- X509v3 CRL Distribution Points:
-
- Full Name:
- URI:http://crl.godaddy.com/gdroot-g2.crl
-
- X509v3 Certificate Policies:
- Policy: X509v3 Any Policy
- CPS: https://certs.godaddy.com/repository/
-
- Signature Algorithm: sha256WithRSAEncryption
- 08:7e:6c:93:10:c8:38:b8:96:a9:90:4b:ff:a1:5f:4f:04:ef:
- 6c:3e:9c:88:06:c9:50:8f:a6:73:f7:57:31:1b:be:bc:e4:2f:
- db:f8:ba:d3:5b:e0:b4:e7:e6:79:62:0e:0c:a2:d7:6a:63:73:
- 31:b5:f5:a8:48:a4:3b:08:2d:a2:5d:90:d7:b4:7c:25:4f:11:
- 56:30:c4:b6:44:9d:7b:2c:9d:e5:5e:e6:ef:0c:61:aa:bf:e4:
- 2a:1b:ee:84:9e:b8:83:7d:c1:43:ce:44:a7:13:70:0d:91:1f:
- f4:c8:13:ad:83:60:d9:d8:72:a8:73:24:1e:b5:ac:22:0e:ca:
- 17:89:62:58:44:1b:ab:89:25:01:00:0f:cd:c4:1b:62:db:51:
- b4:d3:0f:51:2a:9b:f4:bc:73:fc:76:ce:36:a4:cd:d9:d8:2c:
- ea:ae:9b:f5:2a:b2:90:d1:4d:75:18:8a:3f:8a:41:90:23:7d:
- 5b:4b:fe:a4:03:58:9b:46:b2:c3:60:60:83:f8:7d:50:41:ce:
- c2:a1:90:c3:bb:ef:02:2f:d2:15:54:ee:44:15:d9:0a:ae:a7:
- 8a:33:ed:b1:2d:76:36:26:dc:04:eb:9f:f7:61:1f:15:dc:87:
- 6f:ee:46:96:28:ad:a1:26:7d:0a:09:a7:2e:04:a3:8d:bc:f8:
- bc:04:30:01
------BEGIN CERTIFICATE-----
-MIIE0DCCA7igAwIBAgIBBzANBgkqhkiG9w0BAQsFADCBgzELMAkGA1UEBhMCVVMx
-EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAYBgNVBAoT
-EUdvRGFkZHkuY29tLCBJbmMuMTEwLwYDVQQDEyhHbyBEYWRkeSBSb290IENlcnRp
-ZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTExMDUwMzA3MDAwMFoXDTMxMDUwMzA3
-MDAwMFowgbQxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6b25hMRMwEQYDVQQH
-EwpTY290dHNkYWxlMRowGAYDVQQKExFHb0RhZGR5LmNvbSwgSW5jLjEtMCsGA1UE
-CxMkaHR0cDovL2NlcnRzLmdvZGFkZHkuY29tL3JlcG9zaXRvcnkvMTMwMQYDVQQD
-EypHbyBEYWRkeSBTZWN1cmUgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IC0gRzIwggEi
-MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC54MsQ1K92vdSTYuswZLiBCGzD
-BNliF44v/z5lz4/OYuY8UhzaFkVLVat4a2ODYpDOD2lsmcgaFItMzEUz6ojcnqOv
-K/6AYZ15V8TPLvQ/MDxdR/yaFrzDN5ZBUY4RS1T4KL7QjL7wMDge87Am+GZHY23e
-cSZHjzhHU9FGHbTj3ADqRay9vHHZqm8A29vNMDp5T19MR/gd71vCxJ1gO7GyQ5HY
-pDNO6rPWJ0+tJYqlxvTV0KaudAVkV4i1RFXULSo6Pvi4vekyCgKUZMQWOlDxSq7n
-eTOvDCAHf+jfBDnCaQJsY1L6d8EbyHSHyLmTGFBUNUtpTrw700kuH9zB0lL7AgMB
-AAGjggEaMIIBFjAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNV
-HQ4EFgQUQMK9J47MNIMwojPX+2yz8LQsgM4wHwYDVR0jBBgwFoAUOpqFBxBnKLbv
-9r0FQW4gwZTaD94wNAYIKwYBBQUHAQEEKDAmMCQGCCsGAQUFBzABhhhodHRwOi8v
-b2NzcC5nb2RhZGR5LmNvbS8wNQYDVR0fBC4wLDAqoCigJoYkaHR0cDovL2NybC5n
-b2RhZGR5LmNvbS9nZHJvb3QtZzIuY3JsMEYGA1UdIAQ/MD0wOwYEVR0gADAzMDEG
-CCsGAQUFBwIBFiVodHRwczovL2NlcnRzLmdvZGFkZHkuY29tL3JlcG9zaXRvcnkv
-MA0GCSqGSIb3DQEBCwUAA4IBAQAIfmyTEMg4uJapkEv/oV9PBO9sPpyIBslQj6Zz
-91cxG7685C/b+LrTW+C05+Z5Yg4MotdqY3MxtfWoSKQ7CC2iXZDXtHwlTxFWMMS2
-RJ17LJ3lXubvDGGqv+QqG+6EnriDfcFDzkSnE3ANkR/0yBOtg2DZ2HKocyQetawi
-DsoXiWJYRBuriSUBAA/NxBti21G00w9RKpv0vHP8ds42pM3Z2Czqrpv1KrKQ0U11
-GIo/ikGQI31bS/6kA1ibRrLDYGCD+H1QQc7CoZDDu+8CL9IVVO5EFdkKrqeKM+2x
-LXY2JtwE65/3YR8V3Idv7kaWKK2hJn0KCacuBKONvPi8BDAB
------END CERTIFICATE-----
-#endif
-static const unsigned char kDERCert31[] = {
- 0x30, 0x82, 0x04, 0xd0, 0x30, 0x82, 0x03, 0xb8, 0xa0, 0x03, 0x02, 0x01,
- 0x02, 0x02, 0x01, 0x07, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
- 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x81, 0x83, 0x31, 0x0b,
- 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31,
- 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x07, 0x41, 0x72,
- 0x69, 0x7a, 0x6f, 0x6e, 0x61, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55,
- 0x04, 0x07, 0x13, 0x0a, 0x53, 0x63, 0x6f, 0x74, 0x74, 0x73, 0x64, 0x61,
- 0x6c, 0x65, 0x31, 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13,
- 0x11, 0x47, 0x6f, 0x44, 0x61, 0x64, 0x64, 0x79, 0x2e, 0x63, 0x6f, 0x6d,
- 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x31, 0x30, 0x2f, 0x06, 0x03,
- 0x55, 0x04, 0x03, 0x13, 0x28, 0x47, 0x6f, 0x20, 0x44, 0x61, 0x64, 0x64,
- 0x79, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69,
- 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f,
- 0x72, 0x69, 0x74, 0x79, 0x20, 0x2d, 0x20, 0x47, 0x32, 0x30, 0x1e, 0x17,
- 0x0d, 0x31, 0x31, 0x30, 0x35, 0x30, 0x33, 0x30, 0x37, 0x30, 0x30, 0x30,
- 0x30, 0x5a, 0x17, 0x0d, 0x33, 0x31, 0x30, 0x35, 0x30, 0x33, 0x30, 0x37,
- 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x81, 0xb4, 0x31, 0x0b, 0x30, 0x09,
- 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x10, 0x30,
- 0x0e, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x07, 0x41, 0x72, 0x69, 0x7a,
- 0x6f, 0x6e, 0x61, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x07,
- 0x13, 0x0a, 0x53, 0x63, 0x6f, 0x74, 0x74, 0x73, 0x64, 0x61, 0x6c, 0x65,
- 0x31, 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x11, 0x47,
- 0x6f, 0x44, 0x61, 0x64, 0x64, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x2c, 0x20,
- 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x2d, 0x30, 0x2b, 0x06, 0x03, 0x55, 0x04,
- 0x0b, 0x13, 0x24, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x65,
- 0x72, 0x74, 0x73, 0x2e, 0x67, 0x6f, 0x64, 0x61, 0x64, 0x64, 0x79, 0x2e,
- 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f,
- 0x72, 0x79, 0x2f, 0x31, 0x33, 0x30, 0x31, 0x06, 0x03, 0x55, 0x04, 0x03,
- 0x13, 0x2a, 0x47, 0x6f, 0x20, 0x44, 0x61, 0x64, 0x64, 0x79, 0x20, 0x53,
- 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66,
- 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72,
- 0x69, 0x74, 0x79, 0x20, 0x2d, 0x20, 0x47, 0x32, 0x30, 0x82, 0x01, 0x22,
- 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
- 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a,
- 0x02, 0x82, 0x01, 0x01, 0x00, 0xb9, 0xe0, 0xcb, 0x10, 0xd4, 0xaf, 0x76,
- 0xbd, 0xd4, 0x93, 0x62, 0xeb, 0x30, 0x64, 0xb8, 0x81, 0x08, 0x6c, 0xc3,
- 0x04, 0xd9, 0x62, 0x17, 0x8e, 0x2f, 0xff, 0x3e, 0x65, 0xcf, 0x8f, 0xce,
- 0x62, 0xe6, 0x3c, 0x52, 0x1c, 0xda, 0x16, 0x45, 0x4b, 0x55, 0xab, 0x78,
- 0x6b, 0x63, 0x83, 0x62, 0x90, 0xce, 0x0f, 0x69, 0x6c, 0x99, 0xc8, 0x1a,
- 0x14, 0x8b, 0x4c, 0xcc, 0x45, 0x33, 0xea, 0x88, 0xdc, 0x9e, 0xa3, 0xaf,
- 0x2b, 0xfe, 0x80, 0x61, 0x9d, 0x79, 0x57, 0xc4, 0xcf, 0x2e, 0xf4, 0x3f,
- 0x30, 0x3c, 0x5d, 0x47, 0xfc, 0x9a, 0x16, 0xbc, 0xc3, 0x37, 0x96, 0x41,
- 0x51, 0x8e, 0x11, 0x4b, 0x54, 0xf8, 0x28, 0xbe, 0xd0, 0x8c, 0xbe, 0xf0,
- 0x30, 0x38, 0x1e, 0xf3, 0xb0, 0x26, 0xf8, 0x66, 0x47, 0x63, 0x6d, 0xde,
- 0x71, 0x26, 0x47, 0x8f, 0x38, 0x47, 0x53, 0xd1, 0x46, 0x1d, 0xb4, 0xe3,
- 0xdc, 0x00, 0xea, 0x45, 0xac, 0xbd, 0xbc, 0x71, 0xd9, 0xaa, 0x6f, 0x00,
- 0xdb, 0xdb, 0xcd, 0x30, 0x3a, 0x79, 0x4f, 0x5f, 0x4c, 0x47, 0xf8, 0x1d,
- 0xef, 0x5b, 0xc2, 0xc4, 0x9d, 0x60, 0x3b, 0xb1, 0xb2, 0x43, 0x91, 0xd8,
- 0xa4, 0x33, 0x4e, 0xea, 0xb3, 0xd6, 0x27, 0x4f, 0xad, 0x25, 0x8a, 0xa5,
- 0xc6, 0xf4, 0xd5, 0xd0, 0xa6, 0xae, 0x74, 0x05, 0x64, 0x57, 0x88, 0xb5,
- 0x44, 0x55, 0xd4, 0x2d, 0x2a, 0x3a, 0x3e, 0xf8, 0xb8, 0xbd, 0xe9, 0x32,
- 0x0a, 0x02, 0x94, 0x64, 0xc4, 0x16, 0x3a, 0x50, 0xf1, 0x4a, 0xae, 0xe7,
- 0x79, 0x33, 0xaf, 0x0c, 0x20, 0x07, 0x7f, 0xe8, 0xdf, 0x04, 0x39, 0xc2,
- 0x69, 0x02, 0x6c, 0x63, 0x52, 0xfa, 0x77, 0xc1, 0x1b, 0xc8, 0x74, 0x87,
- 0xc8, 0xb9, 0x93, 0x18, 0x50, 0x54, 0x35, 0x4b, 0x69, 0x4e, 0xbc, 0x3b,
- 0xd3, 0x49, 0x2e, 0x1f, 0xdc, 0xc1, 0xd2, 0x52, 0xfb, 0x02, 0x03, 0x01,
- 0x00, 0x01, 0xa3, 0x82, 0x01, 0x1a, 0x30, 0x82, 0x01, 0x16, 0x30, 0x0f,
- 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, 0x30, 0x03,
- 0x01, 0x01, 0xff, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01,
- 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x1d, 0x06, 0x03, 0x55,
- 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x40, 0xc2, 0xbd, 0x27, 0x8e, 0xcc,
- 0x34, 0x83, 0x30, 0xa2, 0x33, 0xd7, 0xfb, 0x6c, 0xb3, 0xf0, 0xb4, 0x2c,
- 0x80, 0xce, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30,
- 0x16, 0x80, 0x14, 0x3a, 0x9a, 0x85, 0x07, 0x10, 0x67, 0x28, 0xb6, 0xef,
- 0xf6, 0xbd, 0x05, 0x41, 0x6e, 0x20, 0xc1, 0x94, 0xda, 0x0f, 0xde, 0x30,
- 0x34, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04,
- 0x28, 0x30, 0x26, 0x30, 0x24, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05,
- 0x07, 0x30, 0x01, 0x86, 0x18, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f,
- 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x67, 0x6f, 0x64, 0x61, 0x64, 0x64, 0x79,
- 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x30, 0x35, 0x06, 0x03, 0x55, 0x1d, 0x1f,
- 0x04, 0x2e, 0x30, 0x2c, 0x30, 0x2a, 0xa0, 0x28, 0xa0, 0x26, 0x86, 0x24,
- 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x67,
- 0x6f, 0x64, 0x61, 0x64, 0x64, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67,
- 0x64, 0x72, 0x6f, 0x6f, 0x74, 0x2d, 0x67, 0x32, 0x2e, 0x63, 0x72, 0x6c,
- 0x30, 0x46, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x3f, 0x30, 0x3d, 0x30,
- 0x3b, 0x06, 0x04, 0x55, 0x1d, 0x20, 0x00, 0x30, 0x33, 0x30, 0x31, 0x06,
- 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x25, 0x68,
- 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x63, 0x65, 0x72, 0x74, 0x73,
- 0x2e, 0x67, 0x6f, 0x64, 0x61, 0x64, 0x64, 0x79, 0x2e, 0x63, 0x6f, 0x6d,
- 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x2f,
- 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
- 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x08, 0x7e, 0x6c, 0x93,
- 0x10, 0xc8, 0x38, 0xb8, 0x96, 0xa9, 0x90, 0x4b, 0xff, 0xa1, 0x5f, 0x4f,
- 0x04, 0xef, 0x6c, 0x3e, 0x9c, 0x88, 0x06, 0xc9, 0x50, 0x8f, 0xa6, 0x73,
- 0xf7, 0x57, 0x31, 0x1b, 0xbe, 0xbc, 0xe4, 0x2f, 0xdb, 0xf8, 0xba, 0xd3,
- 0x5b, 0xe0, 0xb4, 0xe7, 0xe6, 0x79, 0x62, 0x0e, 0x0c, 0xa2, 0xd7, 0x6a,
- 0x63, 0x73, 0x31, 0xb5, 0xf5, 0xa8, 0x48, 0xa4, 0x3b, 0x08, 0x2d, 0xa2,
- 0x5d, 0x90, 0xd7, 0xb4, 0x7c, 0x25, 0x4f, 0x11, 0x56, 0x30, 0xc4, 0xb6,
- 0x44, 0x9d, 0x7b, 0x2c, 0x9d, 0xe5, 0x5e, 0xe6, 0xef, 0x0c, 0x61, 0xaa,
- 0xbf, 0xe4, 0x2a, 0x1b, 0xee, 0x84, 0x9e, 0xb8, 0x83, 0x7d, 0xc1, 0x43,
- 0xce, 0x44, 0xa7, 0x13, 0x70, 0x0d, 0x91, 0x1f, 0xf4, 0xc8, 0x13, 0xad,
- 0x83, 0x60, 0xd9, 0xd8, 0x72, 0xa8, 0x73, 0x24, 0x1e, 0xb5, 0xac, 0x22,
- 0x0e, 0xca, 0x17, 0x89, 0x62, 0x58, 0x44, 0x1b, 0xab, 0x89, 0x25, 0x01,
- 0x00, 0x0f, 0xcd, 0xc4, 0x1b, 0x62, 0xdb, 0x51, 0xb4, 0xd3, 0x0f, 0x51,
- 0x2a, 0x9b, 0xf4, 0xbc, 0x73, 0xfc, 0x76, 0xce, 0x36, 0xa4, 0xcd, 0xd9,
- 0xd8, 0x2c, 0xea, 0xae, 0x9b, 0xf5, 0x2a, 0xb2, 0x90, 0xd1, 0x4d, 0x75,
- 0x18, 0x8a, 0x3f, 0x8a, 0x41, 0x90, 0x23, 0x7d, 0x5b, 0x4b, 0xfe, 0xa4,
- 0x03, 0x58, 0x9b, 0x46, 0xb2, 0xc3, 0x60, 0x60, 0x83, 0xf8, 0x7d, 0x50,
- 0x41, 0xce, 0xc2, 0xa1, 0x90, 0xc3, 0xbb, 0xef, 0x02, 0x2f, 0xd2, 0x15,
- 0x54, 0xee, 0x44, 0x15, 0xd9, 0x0a, 0xae, 0xa7, 0x8a, 0x33, 0xed, 0xb1,
- 0x2d, 0x76, 0x36, 0x26, 0xdc, 0x04, 0xeb, 0x9f, 0xf7, 0x61, 0x1f, 0x15,
- 0xdc, 0x87, 0x6f, 0xee, 0x46, 0x96, 0x28, 0xad, 0xa1, 0x26, 0x7d, 0x0a,
- 0x09, 0xa7, 0x2e, 0x04, 0xa3, 0x8d, 0xbc, 0xf8, 0xbc, 0x04, 0x30, 0x01,
-};
-
-#if 0
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number:
- 0a:48:9e:88:53:7e:8a:a6:45:4d:6e:2c:4b:2a:eb:20
- Signature Algorithm: sha256WithRSAEncryption
- Issuer: C=US, O=thawte, Inc., OU=Certification Services Division, OU=(c) 2008 thawte, Inc. - For authorized use only, CN=thawte Primary Root CA - G3
- Validity
- Not Before: Apr 9 00:00:00 2013 GMT
- Not After : Apr 8 23:59:59 2023 GMT
- Subject: C=US, O=thawte, Inc., CN=thawte Extended Validation SHA256 SSL CA
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:f2:c4:bc:74:e8:25:f6:00:62:28:e3:4c:e8:b8:
- df:13:9f:8b:07:37:ef:62:4a:f1:57:09:f6:82:e8:
- 75:f0:0a:a9:27:cf:93:3b:ec:36:89:a5:6e:1d:d6:
- 54:f3:b8:04:97:72:b4:69:25:cc:d1:42:0e:5b:d5:
- 1c:7f:a2:60:6e:b1:52:1a:db:93:2f:bb:0b:0d:64:
- 53:16:cb:1c:09:24:95:29:22:b4:8a:18:00:89:fe:
- f7:1f:72:c8:e8:5c:2f:1a:1b:a2:18:b8:ef:18:5c:
- cb:b5:db:3a:4e:db:0f:ae:df:c4:79:e3:1e:aa:5c:
- a3:a4:e5:ac:61:9b:37:85:8f:48:75:1b:b9:d5:68:
- 96:e9:27:79:70:57:23:1a:bb:6c:93:90:c7:45:d7:
- 17:d2:37:2a:76:b3:cd:82:a9:4f:c0:03:7b:e1:3d:
- 7a:7e:5b:b8:85:f2:f5:15:fb:70:a9:bd:f5:50:65:
- 16:9d:e3:b6:6b:61:6e:a1:7a:9e:e8:0d:1c:f7:2a:
- 8e:69:7e:43:30:8e:78:ce:ee:65:1e:3b:9b:87:1e:
- 49:1c:f8:32:46:5d:28:46:79:2a:4e:27:5d:17:58:
- a8:37:fe:a8:13:a9:69:15:df:36:22:89:75:ba:ca:
- 01:40:2e:ed:9d:d7:0c:aa:31:ce:27:ae:57:d5:d2:
- 51:fb
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Basic Constraints: critical
- CA:TRUE, pathlen:0
- X509v3 Key Usage: critical
- Certificate Sign, CRL Sign
- Authority Information Access:
- OCSP - URI:http://ocsp.thawte.com
-
- X509v3 Certificate Policies:
- Policy: X509v3 Any Policy
- CPS: https://www.thawte.com/cps
-
- X509v3 CRL Distribution Points:
-
- Full Name:
- URI:http://crl.thawte.com/ThawtePCA-G3.crl
-
- X509v3 Subject Alternative Name:
- DirName:/CN=VeriSignMPKI-2-374
- X509v3 Subject Key Identifier:
- 3B:24:C8:31:A0:B7:5A:D0:6A:B8:D2:CA:07:74:CC:1E:24:D4:C4:DC
- X509v3 Authority Key Identifier:
- keyid:AD:6C:AA:94:60:9C:ED:E4:FF:FA:3E:0A:74:2B:63:03:F7:B6:59:BF
-
- Signature Algorithm: sha256WithRSAEncryption
- 68:98:26:aa:d4:33:c9:ba:75:70:d4:9f:49:ad:d6:c1:54:dc:
- ee:aa:56:1f:78:a7:f0:a1:a4:ee:0b:f9:12:af:df:a6:b8:ee:
- c3:cb:35:13:6a:59:2a:f8:c9:e9:4c:2f:bc:b1:bc:2b:c2:02:
- 30:e1:c3:be:c2:f0:81:8c:99:77:89:58:00:a3:cc:7f:a3:02:
- 4c:53:b2:6e:36:4f:fe:df:87:76:b3:3f:ec:5a:62:50:b6:00:
- 45:58:f2:87:ac:77:e6:d0:20:50:63:c5:e4:b2:70:15:18:90:
- 05:7b:7b:af:2b:46:be:6b:4e:1f:53:fc:84:27:ae:83:d2:8d:
- 47:53:a7:0e:1f:63:b5:ba:db:16:d8:6a:09:25:55:7d:8f:3d:
- 4a:c1:83:f9:b3:b9:a7:04:5a:c8:f3:11:04:91:53:30:d9:52:
- 87:cb:39:00:9c:ec:53:c3:02:09:7e:a7:36:8e:72:21:2f:23:
- bb:4c:c6:47:a5:a1:ee:67:c4:2f:5c:3a:47:38:61:e2:c3:1e:
- 37:92:9e:c8:2f:6b:fa:ef:d2:c3:cd:29:8d:98:f8:52:17:ed:
- b5:53:3c:df:af:c9:1b:62:ad:df:02:ee:5d:34:f6:41:4b:cb:
- c3:55:af:b1:cb:da:9c:73:d5:02:a8:2d:a7:ac:fc:e1:e5:07:
- d0:51:e8:35
------BEGIN CERTIFICATE-----
-MIIE0DCCA7igAwIBAgIQCkieiFN+iqZFTW4sSyrrIDANBgkqhkiG9w0BAQsFADCB
-rjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMf
-Q2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIw
-MDggdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxJDAiBgNV
-BAMTG3RoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EgLSBHMzAeFw0xMzA0MDkwMDAwMDBa
-Fw0yMzA0MDgyMzU5NTlaMFcxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwx0aGF3dGUs
-IEluYy4xMTAvBgNVBAMTKHRoYXd0ZSBFeHRlbmRlZCBWYWxpZGF0aW9uIFNIQTI1
-NiBTU0wgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDyxLx06CX2
-AGIo40zouN8Tn4sHN+9iSvFXCfaC6HXwCqknz5M77DaJpW4d1lTzuASXcrRpJczR
-Qg5b1Rx/omBusVIa25MvuwsNZFMWyxwJJJUpIrSKGACJ/vcfcsjoXC8aG6IYuO8Y
-XMu12zpO2w+u38R54x6qXKOk5axhmzeFj0h1G7nVaJbpJ3lwVyMau2yTkMdF1xfS
-Nyp2s82CqU/AA3vhPXp+W7iF8vUV+3CpvfVQZRad47ZrYW6hep7oDRz3Ko5pfkMw
-jnjO7mUeO5uHHkkc+DJGXShGeSpOJ10XWKg3/qgTqWkV3zYiiXW6ygFALu2d1wyq
-Mc4nrlfV0lH7AgMBAAGjggE+MIIBOjASBgNVHRMBAf8ECDAGAQH/AgEAMA4GA1Ud
-DwEB/wQEAwIBBjAyBggrBgEFBQcBAQQmMCQwIgYIKwYBBQUHMAGGFmh0dHA6Ly9v
-Y3NwLnRoYXd0ZS5jb20wOwYDVR0gBDQwMjAwBgRVHSAAMCgwJgYIKwYBBQUHAgEW
-Gmh0dHBzOi8vd3d3LnRoYXd0ZS5jb20vY3BzMDcGA1UdHwQwMC4wLKAqoCiGJmh0
-dHA6Ly9jcmwudGhhd3RlLmNvbS9UaGF3dGVQQ0EtRzMuY3JsMCoGA1UdEQQjMCGk
-HzAdMRswGQYDVQQDExJWZXJpU2lnbk1QS0ktMi0zNzQwHQYDVR0OBBYEFDskyDGg
-t1rQarjSygd0zB4k1MTcMB8GA1UdIwQYMBaAFK1sqpRgnO3k//o+CnQrYwP3tlm/
-MA0GCSqGSIb3DQEBCwUAA4IBAQBomCaq1DPJunVw1J9JrdbBVNzuqlYfeKfwoaTu
-C/kSr9+muO7DyzUTalkq+MnpTC+8sbwrwgIw4cO+wvCBjJl3iVgAo8x/owJMU7Ju
-Nk/+34d2sz/sWmJQtgBFWPKHrHfm0CBQY8XksnAVGJAFe3uvK0a+a04fU/yEJ66D
-0o1HU6cOH2O1utsW2GoJJVV9jz1KwYP5s7mnBFrI8xEEkVMw2VKHyzkAnOxTwwIJ
-fqc2jnIhLyO7TMZHpaHuZ8QvXDpHOGHiwx43kp7IL2v679LDzSmNmPhSF+21Uzzf
-r8kbYq3fAu5dNPZBS8vDVa+xy9qcc9UCqC2nrPzh5QfQUeg1
------END CERTIFICATE-----
-#endif
-static const unsigned char kDERCert32[] = {
- 0x30, 0x82, 0x04, 0xd0, 0x30, 0x82, 0x03, 0xb8, 0xa0, 0x03, 0x02, 0x01,
- 0x02, 0x02, 0x10, 0x0a, 0x48, 0x9e, 0x88, 0x53, 0x7e, 0x8a, 0xa6, 0x45,
- 0x4d, 0x6e, 0x2c, 0x4b, 0x2a, 0xeb, 0x20, 0x30, 0x0d, 0x06, 0x09, 0x2a,
- 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x81,
- 0xae, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
- 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13,
- 0x0c, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63,
- 0x2e, 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1f,
- 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f,
- 0x6e, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, 0x44,
- 0x69, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x31, 0x38, 0x30, 0x36, 0x06,
- 0x03, 0x55, 0x04, 0x0b, 0x13, 0x2f, 0x28, 0x63, 0x29, 0x20, 0x32, 0x30,
- 0x30, 0x38, 0x20, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2c, 0x20, 0x49,
- 0x6e, 0x63, 0x2e, 0x20, 0x2d, 0x20, 0x46, 0x6f, 0x72, 0x20, 0x61, 0x75,
- 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x20, 0x75, 0x73, 0x65,
- 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x31, 0x24, 0x30, 0x22, 0x06, 0x03, 0x55,
- 0x04, 0x03, 0x13, 0x1b, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x20, 0x50,
- 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20,
- 0x43, 0x41, 0x20, 0x2d, 0x20, 0x47, 0x33, 0x30, 0x1e, 0x17, 0x0d, 0x31,
- 0x33, 0x30, 0x34, 0x30, 0x39, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a,
- 0x17, 0x0d, 0x32, 0x33, 0x30, 0x34, 0x30, 0x38, 0x32, 0x33, 0x35, 0x39,
- 0x35, 0x39, 0x5a, 0x30, 0x57, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55,
- 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03,
- 0x55, 0x04, 0x0a, 0x13, 0x0c, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2c,
- 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x31, 0x30, 0x2f, 0x06, 0x03, 0x55,
- 0x04, 0x03, 0x13, 0x28, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x20, 0x45,
- 0x78, 0x74, 0x65, 0x6e, 0x64, 0x65, 0x64, 0x20, 0x56, 0x61, 0x6c, 0x69,
- 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x53, 0x48, 0x41, 0x32, 0x35,
- 0x36, 0x20, 0x53, 0x53, 0x4c, 0x20, 0x43, 0x41, 0x30, 0x82, 0x01, 0x22,
- 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
- 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a,
- 0x02, 0x82, 0x01, 0x01, 0x00, 0xf2, 0xc4, 0xbc, 0x74, 0xe8, 0x25, 0xf6,
- 0x00, 0x62, 0x28, 0xe3, 0x4c, 0xe8, 0xb8, 0xdf, 0x13, 0x9f, 0x8b, 0x07,
- 0x37, 0xef, 0x62, 0x4a, 0xf1, 0x57, 0x09, 0xf6, 0x82, 0xe8, 0x75, 0xf0,
- 0x0a, 0xa9, 0x27, 0xcf, 0x93, 0x3b, 0xec, 0x36, 0x89, 0xa5, 0x6e, 0x1d,
- 0xd6, 0x54, 0xf3, 0xb8, 0x04, 0x97, 0x72, 0xb4, 0x69, 0x25, 0xcc, 0xd1,
- 0x42, 0x0e, 0x5b, 0xd5, 0x1c, 0x7f, 0xa2, 0x60, 0x6e, 0xb1, 0x52, 0x1a,
- 0xdb, 0x93, 0x2f, 0xbb, 0x0b, 0x0d, 0x64, 0x53, 0x16, 0xcb, 0x1c, 0x09,
- 0x24, 0x95, 0x29, 0x22, 0xb4, 0x8a, 0x18, 0x00, 0x89, 0xfe, 0xf7, 0x1f,
- 0x72, 0xc8, 0xe8, 0x5c, 0x2f, 0x1a, 0x1b, 0xa2, 0x18, 0xb8, 0xef, 0x18,
- 0x5c, 0xcb, 0xb5, 0xdb, 0x3a, 0x4e, 0xdb, 0x0f, 0xae, 0xdf, 0xc4, 0x79,
- 0xe3, 0x1e, 0xaa, 0x5c, 0xa3, 0xa4, 0xe5, 0xac, 0x61, 0x9b, 0x37, 0x85,
- 0x8f, 0x48, 0x75, 0x1b, 0xb9, 0xd5, 0x68, 0x96, 0xe9, 0x27, 0x79, 0x70,
- 0x57, 0x23, 0x1a, 0xbb, 0x6c, 0x93, 0x90, 0xc7, 0x45, 0xd7, 0x17, 0xd2,
- 0x37, 0x2a, 0x76, 0xb3, 0xcd, 0x82, 0xa9, 0x4f, 0xc0, 0x03, 0x7b, 0xe1,
- 0x3d, 0x7a, 0x7e, 0x5b, 0xb8, 0x85, 0xf2, 0xf5, 0x15, 0xfb, 0x70, 0xa9,
- 0xbd, 0xf5, 0x50, 0x65, 0x16, 0x9d, 0xe3, 0xb6, 0x6b, 0x61, 0x6e, 0xa1,
- 0x7a, 0x9e, 0xe8, 0x0d, 0x1c, 0xf7, 0x2a, 0x8e, 0x69, 0x7e, 0x43, 0x30,
- 0x8e, 0x78, 0xce, 0xee, 0x65, 0x1e, 0x3b, 0x9b, 0x87, 0x1e, 0x49, 0x1c,
- 0xf8, 0x32, 0x46, 0x5d, 0x28, 0x46, 0x79, 0x2a, 0x4e, 0x27, 0x5d, 0x17,
- 0x58, 0xa8, 0x37, 0xfe, 0xa8, 0x13, 0xa9, 0x69, 0x15, 0xdf, 0x36, 0x22,
- 0x89, 0x75, 0xba, 0xca, 0x01, 0x40, 0x2e, 0xed, 0x9d, 0xd7, 0x0c, 0xaa,
- 0x31, 0xce, 0x27, 0xae, 0x57, 0xd5, 0xd2, 0x51, 0xfb, 0x02, 0x03, 0x01,
- 0x00, 0x01, 0xa3, 0x82, 0x01, 0x3e, 0x30, 0x82, 0x01, 0x3a, 0x30, 0x12,
- 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06,
- 0x01, 0x01, 0xff, 0x02, 0x01, 0x00, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d,
- 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x32,
- 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x26,
- 0x30, 0x24, 0x30, 0x22, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
- 0x30, 0x01, 0x86, 0x16, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f,
- 0x63, 0x73, 0x70, 0x2e, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2e, 0x63,
- 0x6f, 0x6d, 0x30, 0x3b, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x34, 0x30,
- 0x32, 0x30, 0x30, 0x06, 0x04, 0x55, 0x1d, 0x20, 0x00, 0x30, 0x28, 0x30,
- 0x26, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16,
- 0x1a, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77,
- 0x2e, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f,
- 0x63, 0x70, 0x73, 0x30, 0x37, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x30,
- 0x30, 0x2e, 0x30, 0x2c, 0xa0, 0x2a, 0xa0, 0x28, 0x86, 0x26, 0x68, 0x74,
- 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x74, 0x68, 0x61,
- 0x77, 0x74, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x54, 0x68, 0x61, 0x77,
- 0x74, 0x65, 0x50, 0x43, 0x41, 0x2d, 0x47, 0x33, 0x2e, 0x63, 0x72, 0x6c,
- 0x30, 0x2a, 0x06, 0x03, 0x55, 0x1d, 0x11, 0x04, 0x23, 0x30, 0x21, 0xa4,
- 0x1f, 0x30, 0x1d, 0x31, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x03,
- 0x13, 0x12, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x4d, 0x50,
- 0x4b, 0x49, 0x2d, 0x32, 0x2d, 0x33, 0x37, 0x34, 0x30, 0x1d, 0x06, 0x03,
- 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x3b, 0x24, 0xc8, 0x31, 0xa0,
- 0xb7, 0x5a, 0xd0, 0x6a, 0xb8, 0xd2, 0xca, 0x07, 0x74, 0xcc, 0x1e, 0x24,
- 0xd4, 0xc4, 0xdc, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18,
- 0x30, 0x16, 0x80, 0x14, 0xad, 0x6c, 0xaa, 0x94, 0x60, 0x9c, 0xed, 0xe4,
- 0xff, 0xfa, 0x3e, 0x0a, 0x74, 0x2b, 0x63, 0x03, 0xf7, 0xb6, 0x59, 0xbf,
- 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
- 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x68, 0x98, 0x26, 0xaa,
- 0xd4, 0x33, 0xc9, 0xba, 0x75, 0x70, 0xd4, 0x9f, 0x49, 0xad, 0xd6, 0xc1,
- 0x54, 0xdc, 0xee, 0xaa, 0x56, 0x1f, 0x78, 0xa7, 0xf0, 0xa1, 0xa4, 0xee,
- 0x0b, 0xf9, 0x12, 0xaf, 0xdf, 0xa6, 0xb8, 0xee, 0xc3, 0xcb, 0x35, 0x13,
- 0x6a, 0x59, 0x2a, 0xf8, 0xc9, 0xe9, 0x4c, 0x2f, 0xbc, 0xb1, 0xbc, 0x2b,
- 0xc2, 0x02, 0x30, 0xe1, 0xc3, 0xbe, 0xc2, 0xf0, 0x81, 0x8c, 0x99, 0x77,
- 0x89, 0x58, 0x00, 0xa3, 0xcc, 0x7f, 0xa3, 0x02, 0x4c, 0x53, 0xb2, 0x6e,
- 0x36, 0x4f, 0xfe, 0xdf, 0x87, 0x76, 0xb3, 0x3f, 0xec, 0x5a, 0x62, 0x50,
- 0xb6, 0x00, 0x45, 0x58, 0xf2, 0x87, 0xac, 0x77, 0xe6, 0xd0, 0x20, 0x50,
- 0x63, 0xc5, 0xe4, 0xb2, 0x70, 0x15, 0x18, 0x90, 0x05, 0x7b, 0x7b, 0xaf,
- 0x2b, 0x46, 0xbe, 0x6b, 0x4e, 0x1f, 0x53, 0xfc, 0x84, 0x27, 0xae, 0x83,
- 0xd2, 0x8d, 0x47, 0x53, 0xa7, 0x0e, 0x1f, 0x63, 0xb5, 0xba, 0xdb, 0x16,
- 0xd8, 0x6a, 0x09, 0x25, 0x55, 0x7d, 0x8f, 0x3d, 0x4a, 0xc1, 0x83, 0xf9,
- 0xb3, 0xb9, 0xa7, 0x04, 0x5a, 0xc8, 0xf3, 0x11, 0x04, 0x91, 0x53, 0x30,
- 0xd9, 0x52, 0x87, 0xcb, 0x39, 0x00, 0x9c, 0xec, 0x53, 0xc3, 0x02, 0x09,
- 0x7e, 0xa7, 0x36, 0x8e, 0x72, 0x21, 0x2f, 0x23, 0xbb, 0x4c, 0xc6, 0x47,
- 0xa5, 0xa1, 0xee, 0x67, 0xc4, 0x2f, 0x5c, 0x3a, 0x47, 0x38, 0x61, 0xe2,
- 0xc3, 0x1e, 0x37, 0x92, 0x9e, 0xc8, 0x2f, 0x6b, 0xfa, 0xef, 0xd2, 0xc3,
- 0xcd, 0x29, 0x8d, 0x98, 0xf8, 0x52, 0x17, 0xed, 0xb5, 0x53, 0x3c, 0xdf,
- 0xaf, 0xc9, 0x1b, 0x62, 0xad, 0xdf, 0x02, 0xee, 0x5d, 0x34, 0xf6, 0x41,
- 0x4b, 0xcb, 0xc3, 0x55, 0xaf, 0xb1, 0xcb, 0xda, 0x9c, 0x73, 0xd5, 0x02,
- 0xa8, 0x2d, 0xa7, 0xac, 0xfc, 0xe1, 0xe5, 0x07, 0xd0, 0x51, 0xe8, 0x35,
-};
-
-#if 0
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number:
- 25:0c:e8:e0:30:61:2e:9f:2b:89:f7:05:4d:7c:f8:fd
- Signature Algorithm: sha1WithRSAEncryption
- Issuer: C=US, O=VeriSign, Inc., OU=Class 3 Public Primary Certification Authority
- Validity
- Not Before: Nov 8 00:00:00 2006 GMT
- Not After : Nov 7 23:59:59 2021 GMT
- Subject: C=US, O=VeriSign, Inc., OU=VeriSign Trust Network, OU=(c) 2006 VeriSign, Inc. - For authorized use only, CN=VeriSign Class 3 Public Primary Certification Authority - G5
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:af:24:08:08:29:7a:35:9e:60:0c:aa:e7:4b:3b:
- 4e:dc:7c:bc:3c:45:1c:bb:2b:e0:fe:29:02:f9:57:
- 08:a3:64:85:15:27:f5:f1:ad:c8:31:89:5d:22:e8:
- 2a:aa:a6:42:b3:8f:f8:b9:55:b7:b1:b7:4b:b3:fe:
- 8f:7e:07:57:ec:ef:43:db:66:62:15:61:cf:60:0d:
- a4:d8:de:f8:e0:c3:62:08:3d:54:13:eb:49:ca:59:
- 54:85:26:e5:2b:8f:1b:9f:eb:f5:a1:91:c2:33:49:
- d8:43:63:6a:52:4b:d2:8f:e8:70:51:4d:d1:89:69:
- 7b:c7:70:f6:b3:dc:12:74:db:7b:5d:4b:56:d3:96:
- bf:15:77:a1:b0:f4:a2:25:f2:af:1c:92:67:18:e5:
- f4:06:04:ef:90:b9:e4:00:e4:dd:3a:b5:19:ff:02:
- ba:f4:3c:ee:e0:8b:eb:37:8b:ec:f4:d7:ac:f2:f6:
- f0:3d:af:dd:75:91:33:19:1d:1c:40:cb:74:24:19:
- 21:93:d9:14:fe:ac:2a:52:c7:8f:d5:04:49:e4:8d:
- 63:47:88:3c:69:83:cb:fe:47:bd:2b:7e:4f:c5:95:
- ae:0e:9d:d4:d1:43:c0:67:73:e3:14:08:7e:e5:3f:
- 9f:73:b8:33:0a:cf:5d:3f:34:87:96:8a:ee:53:e8:
- 25:15
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Basic Constraints: critical
- CA:TRUE
- X509v3 CRL Distribution Points:
-
- Full Name:
- URI:http://crl.verisign.com/pca3.crl
-
- X509v3 Key Usage: critical
- Certificate Sign, CRL Sign
- X509v3 Certificate Policies:
- Policy: X509v3 Any Policy
- CPS: https://www.verisign.com/cps
-
- X509v3 Subject Key Identifier:
- 7F:D3:65:A7:C2:DD:EC:BB:F0:30:09:F3:43:39:FA:02:AF:33:31:33
- 1.3.6.1.5.5.7.1.12:
- 0_.].[0Y0W0U..image/gif0!0.0...+..............k...j.H.,{..0%.#http://logo.verisign.com/vslogo.gif
- Authority Information Access:
- OCSP - URI:http://ocsp.verisign.com
-
- X509v3 Extended Key Usage:
- TLS Web Server Authentication, TLS Web Client Authentication, Code Signing, Netscape Server Gated Crypto, 2.16.840.1.113733.1.8.1
- Signature Algorithm: sha1WithRSAEncryption
- 13:02:dd:f8:e8:86:00:f2:5a:f8:f8:20:0c:59:88:62:07:ce:
- ce:f7:4e:f9:bb:59:a1:98:e5:e1:38:dd:4e:bc:66:18:d3:ad:
- eb:18:f2:0d:c9:6d:3e:4a:94:20:c3:3c:ba:bd:65:54:c6:af:
- 44:b3:10:ad:2c:6b:3e:ab:d7:07:b6:b8:81:63:c5:f9:5e:2e:
- e5:2a:67:ce:cd:33:0c:2a:d7:89:56:03:23:1f:b3:be:e8:3a:
- 08:59:b4:ec:45:35:f7:8a:5b:ff:66:cf:50:af:c6:6d:57:8d:
- 19:78:b7:b9:a2:d1:57:ea:1f:9a:4b:af:ba:c9:8e:12:7e:c6:
- bd:ff
------BEGIN CERTIFICATE-----
-MIIE0DCCBDmgAwIBAgIQJQzo4DBhLp8rifcFTXz4/TANBgkqhkiG9w0BAQUFADBf
-MQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xNzA1BgNVBAsT
-LkNsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkw
-HhcNMDYxMTA4MDAwMDAwWhcNMjExMTA3MjM1OTU5WjCByjELMAkGA1UEBhMCVVMx
-FzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBUcnVz
-dCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJpU2lnbiwgSW5jLiAtIEZv
-ciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAz
-IFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzUwggEi
-MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvJAgIKXo1nmAMqudLO07cfLw8
-RRy7K+D+KQL5VwijZIUVJ/XxrcgxiV0i6CqqpkKzj/i5Vbext0uz/o9+B1fs70Pb
-ZmIVYc9gDaTY3vjgw2IIPVQT60nKWVSFJuUrjxuf6/WhkcIzSdhDY2pSS9KP6HBR
-TdGJaXvHcPaz3BJ023tdS1bTlr8Vd6Gw9KIl8q8ckmcY5fQGBO+QueQA5N06tRn/
-Arr0PO7gi+s3i+z016zy9vA9r911kTMZHRxAy3QkGSGT2RT+rCpSx4/VBEnkjWNH
-iDxpg8v+R70rfk/Fla4OndTRQ8Bnc+MUCH7lP59zuDMKz10/NIeWiu5T6CUVAgMB
-AAGjggGbMIIBlzAPBgNVHRMBAf8EBTADAQH/MDEGA1UdHwQqMCgwJqAkoCKGIGh0
-dHA6Ly9jcmwudmVyaXNpZ24uY29tL3BjYTMuY3JsMA4GA1UdDwEB/wQEAwIBBjA9
-BgNVHSAENjA0MDIGBFUdIAAwKjAoBggrBgEFBQcCARYcaHR0cHM6Ly93d3cudmVy
-aXNpZ24uY29tL2NwczAdBgNVHQ4EFgQUf9Nlp8Ld7LvwMAnzQzn6Aq8zMTMwbQYI
-KwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2UvZ2lmMCEwHzAHBgUrDgMCGgQU
-j+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDovL2xvZ28udmVyaXNpZ24uY29t
-L3ZzbG9nby5naWYwNAYIKwYBBQUHAQEEKDAmMCQGCCsGAQUFBzABhhhodHRwOi8v
-b2NzcC52ZXJpc2lnbi5jb20wPgYDVR0lBDcwNQYIKwYBBQUHAwEGCCsGAQUFBwMC
-BggrBgEFBQcDAwYJYIZIAYb4QgQBBgpghkgBhvhFAQgBMA0GCSqGSIb3DQEBBQUA
-A4GBABMC3fjohgDyWvj4IAxZiGIHzs73Tvm7WaGY5eE43U68ZhjTresY8g3JbT5K
-lCDDPLq9ZVTGr0SzEK0saz6r1we2uIFjxfleLuUqZ87NMwwq14lWAyMfs77oOghZ
-tOxFNfeKW/9mz1Cvxm1XjRl4t7mi0VfqH5pLr7rJjhJ+xr3/
------END CERTIFICATE-----
-#endif
-static const unsigned char kDERCert33[] = {
- 0x30, 0x82, 0x04, 0xd0, 0x30, 0x82, 0x04, 0x39, 0xa0, 0x03, 0x02, 0x01,
- 0x02, 0x02, 0x10, 0x25, 0x0c, 0xe8, 0xe0, 0x30, 0x61, 0x2e, 0x9f, 0x2b,
- 0x89, 0xf7, 0x05, 0x4d, 0x7c, 0xf8, 0xfd, 0x30, 0x0d, 0x06, 0x09, 0x2a,
- 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x5f,
- 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55,
- 0x53, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0e,
- 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e,
- 0x63, 0x2e, 0x31, 0x37, 0x30, 0x35, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13,
- 0x2e, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x33, 0x20, 0x50, 0x75, 0x62,
- 0x6c, 0x69, 0x63, 0x20, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x20,
- 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f,
- 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x30,
- 0x1e, 0x17, 0x0d, 0x30, 0x36, 0x31, 0x31, 0x30, 0x38, 0x30, 0x30, 0x30,
- 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x31, 0x31, 0x31, 0x30, 0x37,
- 0x32, 0x33, 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x81, 0xca, 0x31, 0x0b,
- 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31,
- 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0e, 0x56, 0x65,
- 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e,
- 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x16, 0x56,
- 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x54, 0x72, 0x75, 0x73,
- 0x74, 0x20, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x31, 0x3a, 0x30,
- 0x38, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x31, 0x28, 0x63, 0x29, 0x20,
- 0x32, 0x30, 0x30, 0x36, 0x20, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67,
- 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x20, 0x2d, 0x20, 0x46, 0x6f,
- 0x72, 0x20, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64,
- 0x20, 0x75, 0x73, 0x65, 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x31, 0x45, 0x30,
- 0x43, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x3c, 0x56, 0x65, 0x72, 0x69,
- 0x53, 0x69, 0x67, 0x6e, 0x20, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x33,
- 0x20, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x20, 0x50, 0x72, 0x69, 0x6d,
- 0x61, 0x72, 0x79, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63,
- 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72,
- 0x69, 0x74, 0x79, 0x20, 0x2d, 0x20, 0x47, 0x35, 0x30, 0x82, 0x01, 0x22,
- 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
- 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a,
- 0x02, 0x82, 0x01, 0x01, 0x00, 0xaf, 0x24, 0x08, 0x08, 0x29, 0x7a, 0x35,
- 0x9e, 0x60, 0x0c, 0xaa, 0xe7, 0x4b, 0x3b, 0x4e, 0xdc, 0x7c, 0xbc, 0x3c,
- 0x45, 0x1c, 0xbb, 0x2b, 0xe0, 0xfe, 0x29, 0x02, 0xf9, 0x57, 0x08, 0xa3,
- 0x64, 0x85, 0x15, 0x27, 0xf5, 0xf1, 0xad, 0xc8, 0x31, 0x89, 0x5d, 0x22,
- 0xe8, 0x2a, 0xaa, 0xa6, 0x42, 0xb3, 0x8f, 0xf8, 0xb9, 0x55, 0xb7, 0xb1,
- 0xb7, 0x4b, 0xb3, 0xfe, 0x8f, 0x7e, 0x07, 0x57, 0xec, 0xef, 0x43, 0xdb,
- 0x66, 0x62, 0x15, 0x61, 0xcf, 0x60, 0x0d, 0xa4, 0xd8, 0xde, 0xf8, 0xe0,
- 0xc3, 0x62, 0x08, 0x3d, 0x54, 0x13, 0xeb, 0x49, 0xca, 0x59, 0x54, 0x85,
- 0x26, 0xe5, 0x2b, 0x8f, 0x1b, 0x9f, 0xeb, 0xf5, 0xa1, 0x91, 0xc2, 0x33,
- 0x49, 0xd8, 0x43, 0x63, 0x6a, 0x52, 0x4b, 0xd2, 0x8f, 0xe8, 0x70, 0x51,
- 0x4d, 0xd1, 0x89, 0x69, 0x7b, 0xc7, 0x70, 0xf6, 0xb3, 0xdc, 0x12, 0x74,
- 0xdb, 0x7b, 0x5d, 0x4b, 0x56, 0xd3, 0x96, 0xbf, 0x15, 0x77, 0xa1, 0xb0,
- 0xf4, 0xa2, 0x25, 0xf2, 0xaf, 0x1c, 0x92, 0x67, 0x18, 0xe5, 0xf4, 0x06,
- 0x04, 0xef, 0x90, 0xb9, 0xe4, 0x00, 0xe4, 0xdd, 0x3a, 0xb5, 0x19, 0xff,
- 0x02, 0xba, 0xf4, 0x3c, 0xee, 0xe0, 0x8b, 0xeb, 0x37, 0x8b, 0xec, 0xf4,
- 0xd7, 0xac, 0xf2, 0xf6, 0xf0, 0x3d, 0xaf, 0xdd, 0x75, 0x91, 0x33, 0x19,
- 0x1d, 0x1c, 0x40, 0xcb, 0x74, 0x24, 0x19, 0x21, 0x93, 0xd9, 0x14, 0xfe,
- 0xac, 0x2a, 0x52, 0xc7, 0x8f, 0xd5, 0x04, 0x49, 0xe4, 0x8d, 0x63, 0x47,
- 0x88, 0x3c, 0x69, 0x83, 0xcb, 0xfe, 0x47, 0xbd, 0x2b, 0x7e, 0x4f, 0xc5,
- 0x95, 0xae, 0x0e, 0x9d, 0xd4, 0xd1, 0x43, 0xc0, 0x67, 0x73, 0xe3, 0x14,
- 0x08, 0x7e, 0xe5, 0x3f, 0x9f, 0x73, 0xb8, 0x33, 0x0a, 0xcf, 0x5d, 0x3f,
- 0x34, 0x87, 0x96, 0x8a, 0xee, 0x53, 0xe8, 0x25, 0x15, 0x02, 0x03, 0x01,
- 0x00, 0x01, 0xa3, 0x82, 0x01, 0x9b, 0x30, 0x82, 0x01, 0x97, 0x30, 0x0f,
- 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, 0x30, 0x03,
- 0x01, 0x01, 0xff, 0x30, 0x31, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x2a,
- 0x30, 0x28, 0x30, 0x26, 0xa0, 0x24, 0xa0, 0x22, 0x86, 0x20, 0x68, 0x74,
- 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x76, 0x65, 0x72,
- 0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x63,
- 0x61, 0x33, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d,
- 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x3d,
- 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x36, 0x30, 0x34, 0x30, 0x32, 0x06,
- 0x04, 0x55, 0x1d, 0x20, 0x00, 0x30, 0x2a, 0x30, 0x28, 0x06, 0x08, 0x2b,
- 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x1c, 0x68, 0x74, 0x74,
- 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x76, 0x65, 0x72,
- 0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x70,
- 0x73, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14,
- 0x7f, 0xd3, 0x65, 0xa7, 0xc2, 0xdd, 0xec, 0xbb, 0xf0, 0x30, 0x09, 0xf3,
- 0x43, 0x39, 0xfa, 0x02, 0xaf, 0x33, 0x31, 0x33, 0x30, 0x6d, 0x06, 0x08,
- 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x0c, 0x04, 0x61, 0x30, 0x5f,
- 0xa1, 0x5d, 0xa0, 0x5b, 0x30, 0x59, 0x30, 0x57, 0x30, 0x55, 0x16, 0x09,
- 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2f, 0x67, 0x69, 0x66, 0x30, 0x21, 0x30,
- 0x1f, 0x30, 0x07, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x04, 0x14,
- 0x8f, 0xe5, 0xd3, 0x1a, 0x86, 0xac, 0x8d, 0x8e, 0x6b, 0xc3, 0xcf, 0x80,
- 0x6a, 0xd4, 0x48, 0x18, 0x2c, 0x7b, 0x19, 0x2e, 0x30, 0x25, 0x16, 0x23,
- 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6c, 0x6f, 0x67, 0x6f, 0x2e,
- 0x76, 0x65, 0x72, 0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d,
- 0x2f, 0x76, 0x73, 0x6c, 0x6f, 0x67, 0x6f, 0x2e, 0x67, 0x69, 0x66, 0x30,
- 0x34, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04,
- 0x28, 0x30, 0x26, 0x30, 0x24, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05,
- 0x07, 0x30, 0x01, 0x86, 0x18, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f,
- 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x76, 0x65, 0x72, 0x69, 0x73, 0x69, 0x67,
- 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x3e, 0x06, 0x03, 0x55, 0x1d, 0x25,
- 0x04, 0x37, 0x30, 0x35, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
- 0x03, 0x01, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x02,
- 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x03, 0x06, 0x09,
- 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42, 0x04, 0x01, 0x06, 0x0a, 0x60,
- 0x86, 0x48, 0x01, 0x86, 0xf8, 0x45, 0x01, 0x08, 0x01, 0x30, 0x0d, 0x06,
- 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00,
- 0x03, 0x81, 0x81, 0x00, 0x13, 0x02, 0xdd, 0xf8, 0xe8, 0x86, 0x00, 0xf2,
- 0x5a, 0xf8, 0xf8, 0x20, 0x0c, 0x59, 0x88, 0x62, 0x07, 0xce, 0xce, 0xf7,
- 0x4e, 0xf9, 0xbb, 0x59, 0xa1, 0x98, 0xe5, 0xe1, 0x38, 0xdd, 0x4e, 0xbc,
- 0x66, 0x18, 0xd3, 0xad, 0xeb, 0x18, 0xf2, 0x0d, 0xc9, 0x6d, 0x3e, 0x4a,
- 0x94, 0x20, 0xc3, 0x3c, 0xba, 0xbd, 0x65, 0x54, 0xc6, 0xaf, 0x44, 0xb3,
- 0x10, 0xad, 0x2c, 0x6b, 0x3e, 0xab, 0xd7, 0x07, 0xb6, 0xb8, 0x81, 0x63,
- 0xc5, 0xf9, 0x5e, 0x2e, 0xe5, 0x2a, 0x67, 0xce, 0xcd, 0x33, 0x0c, 0x2a,
- 0xd7, 0x89, 0x56, 0x03, 0x23, 0x1f, 0xb3, 0xbe, 0xe8, 0x3a, 0x08, 0x59,
- 0xb4, 0xec, 0x45, 0x35, 0xf7, 0x8a, 0x5b, 0xff, 0x66, 0xcf, 0x50, 0xaf,
- 0xc6, 0x6d, 0x57, 0x8d, 0x19, 0x78, 0xb7, 0xb9, 0xa2, 0xd1, 0x57, 0xea,
- 0x1f, 0x9a, 0x4b, 0xaf, 0xba, 0xc9, 0x8e, 0x12, 0x7e, 0xc6, 0xbd, 0xff,
-};
-
-#if 0
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number:
- 2c:69:e1:2f:6a:67:0b:d9:9d:d2:0f:91:9e:f0:9e:51
- Signature Algorithm: sha256WithRSAEncryption
- Issuer: C=US, O=thawte, Inc., OU=Certification Services Division, OU=(c) 2006 thawte, Inc. - For authorized use only, CN=thawte Primary Root CA
- Validity
- Not Before: Jun 10 00:00:00 2014 GMT
- Not After : Jun 9 23:59:59 2024 GMT
- Subject: C=US, O=thawte, Inc., OU=Domain Validated SSL, CN=thawte DV SSL CA - G2
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:ea:94:07:85:c8:41:2c:f6:83:12:6c:92:5f:ab:
- 1f:00:d4:96:6f:74:cd:2e:11:e9:6c:0f:39:01:b9:
- 48:90:40:39:4d:c4:a2:c8:79:6a:a5:9a:bd:91:44:
- 65:77:54:ad:ff:25:5f:ee:42:fb:b3:02:0f:ea:5d:
- 7a:dd:1a:54:9e:d7:73:42:9b:cc:79:5f:c5:4d:f4:
- b7:0b:18:39:20:7a:dd:50:01:5d:34:45:5f:4c:11:
- 0e:f5:87:26:26:b4:b0:f3:7e:71:a0:31:71:50:89:
- 68:5a:63:8a:14:62:e5:8c:3a:16:55:0d:3e:eb:aa:
- 80:1d:71:7a:e3:87:07:ab:bd:a2:74:cd:da:08:01:
- 9d:1b:cc:27:88:8c:47:d4:69:25:42:d6:bb:50:6d:
- 85:50:d0:48:82:0d:08:9f:e9:23:e3:42:c6:3c:98:
- b8:bb:6e:c5:70:13:df:19:1d:01:fd:d2:b5:4e:e6:
- 62:f4:07:fa:6b:7d:11:77:c4:62:4f:40:4e:a5:78:
- 97:ab:2c:4d:0c:a7:7c:c3:c4:50:32:9f:d0:70:9b:
- 0f:ff:ff:75:59:34:85:ad:49:d5:35:ee:4f:5b:d4:
- d4:36:95:a0:7e:e8:c5:a1:1c:bd:13:4e:7d:ee:63:
- 6a:96:19:99:c8:a7:2a:00:e6:51:8d:46:eb:30:58:
- e8:2d
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Basic Constraints: critical
- CA:TRUE, pathlen:0
- X509v3 Certificate Policies:
- Policy: 2.16.840.1.113733.1.7.54
- CPS: https://www.thawte.com/cps
-
- X509v3 Key Usage: critical
- Certificate Sign, CRL Sign
- Authority Information Access:
- OCSP - URI:http://t.symcd.com
-
- X509v3 CRL Distribution Points:
-
- Full Name:
- URI:http://t.symcb.com/ThawtePCA.crl
-
- X509v3 Subject Alternative Name:
- DirName:/CN=SymantecPKI-1-698
- X509v3 Subject Key Identifier:
- 9F:B8:C1:A9:6C:F2:F5:C0:22:2A:94:ED:5C:99:AC:D4:EC:D7:C6:07
- X509v3 Authority Key Identifier:
- keyid:7B:5B:45:CF:AF:CE:CB:7A:FD:31:92:1A:6A:B6:F3:46:EB:57:48:50
-
- Signature Algorithm: sha256WithRSAEncryption
- 53:54:f2:47:a8:02:d7:ef:aa:35:78:be:4a:08:0d:90:18:4b:
- 6d:9e:2a:53:2b:e9:54:17:77:74:29:7e:d0:37:07:05:b8:e4:
- fa:b8:b4:63:98:44:dc:c6:4f:81:06:8c:3a:be:c7:30:57:c6:
- 70:fc:d6:93:19:9f:c3:55:d7:3e:1f:72:8a:9d:30:5a:35:97:
- 32:cb:63:e4:c6:72:df:fb:68:ca:69:2f:db:cd:50:38:3e:2b:
- bb:ab:3b:82:c7:fd:4b:9b:bd:7c:41:98:ef:01:53:d8:35:8f:
- 25:c9:03:06:e6:9c:57:c1:51:0f:9e:f6:7d:93:4d:f8:76:c8:
- 3a:6b:f4:c4:8f:33:32:7f:9d:21:84:34:d9:a7:f9:92:fa:41:
- 91:61:84:05:9d:a3:79:46:ce:67:e7:81:f2:5e:ac:4c:bc:a8:
- ab:6a:6d:15:e2:9c:4e:5a:d9:63:80:bc:f7:42:eb:9a:44:c6:
- 8c:6b:06:36:b4:8b:32:89:de:c2:f1:a8:26:aa:a9:ac:ff:ea:
- 71:a6:e7:8c:41:fa:17:35:bb:b3:87:31:a9:93:c2:c8:58:e1:
- 0a:4e:95:83:9c:b9:ed:3b:a5:ef:08:e0:74:f9:c3:1b:e6:07:
- a3:ee:07:d7:42:22:79:21:a0:a1:d4:1d:26:d3:d0:d6:a6:5d:
- 2b:41:c0:79
------BEGIN CERTIFICATE-----
-MIIE0jCCA7qgAwIBAgIQLGnhL2pnC9md0g+RnvCeUTANBgkqhkiG9w0BAQsFADCB
-qTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMf
-Q2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIw
-MDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxHzAdBgNV
-BAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwHhcNMTQwNjEwMDAwMDAwWhcNMjQw
-NjA5MjM1OTU5WjBjMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMdGhhd3RlLCBJbmMu
-MR0wGwYDVQQLExREb21haW4gVmFsaWRhdGVkIFNTTDEeMBwGA1UEAxMVdGhhd3Rl
-IERWIFNTTCBDQSAtIEcyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA
-6pQHhchBLPaDEmySX6sfANSWb3TNLhHpbA85AblIkEA5TcSiyHlqpZq9kURld1St
-/yVf7kL7swIP6l163RpUntdzQpvMeV/FTfS3Cxg5IHrdUAFdNEVfTBEO9YcmJrSw
-835xoDFxUIloWmOKFGLljDoWVQ0+66qAHXF644cHq72idM3aCAGdG8wniIxH1Gkl
-Qta7UG2FUNBIgg0In+kj40LGPJi4u27FcBPfGR0B/dK1TuZi9Af6a30Rd8RiT0BO
-pXiXqyxNDKd8w8RQMp/QcJsP//91WTSFrUnVNe5PW9TUNpWgfujFoRy9E0597mNq
-lhmZyKcqAOZRjUbrMFjoLQIDAQABo4IBOTCCATUwEgYDVR0TAQH/BAgwBgEB/wIB
-ADBBBgNVHSAEOjA4MDYGCmCGSAGG+EUBBzYwKDAmBggrBgEFBQcCARYaaHR0cHM6
-Ly93d3cudGhhd3RlLmNvbS9jcHMwDgYDVR0PAQH/BAQDAgEGMC4GCCsGAQUFBwEB
-BCIwIDAeBggrBgEFBQcwAYYSaHR0cDovL3Quc3ltY2QuY29tMDEGA1UdHwQqMCgw
-JqAkoCKGIGh0dHA6Ly90LnN5bWNiLmNvbS9UaGF3dGVQQ0EuY3JsMCkGA1UdEQQi
-MCCkHjAcMRowGAYDVQQDExFTeW1hbnRlY1BLSS0xLTY5ODAdBgNVHQ4EFgQUn7jB
-qWzy9cAiKpTtXJms1OzXxgcwHwYDVR0jBBgwFoAUe1tFz6/Oy3r9MZIaarbzRutX
-SFAwDQYJKoZIhvcNAQELBQADggEBAFNU8keoAtfvqjV4vkoIDZAYS22eKlMr6VQX
-d3QpftA3BwW45Pq4tGOYRNzGT4EGjDq+xzBXxnD81pMZn8NV1z4fcoqdMFo1lzLL
-Y+TGct/7aMppL9vNUDg+K7urO4LH/UubvXxBmO8BU9g1jyXJAwbmnFfBUQ+e9n2T
-Tfh2yDpr9MSPMzJ/nSGENNmn+ZL6QZFhhAWdo3lGzmfngfJerEy8qKtqbRXinE5a
-2WOAvPdC65pExoxrBja0izKJ3sLxqCaqqaz/6nGm54xB+hc1u7OHMamTwshY4QpO
-lYOcue07pe8I4HT5wxvmB6PuB9dCInkhoKHUHSbT0NamXStBwHk=
------END CERTIFICATE-----
-#endif
-static const unsigned char kDERCert34[] = {
- 0x30, 0x82, 0x04, 0xd2, 0x30, 0x82, 0x03, 0xba, 0xa0, 0x03, 0x02, 0x01,
- 0x02, 0x02, 0x10, 0x2c, 0x69, 0xe1, 0x2f, 0x6a, 0x67, 0x0b, 0xd9, 0x9d,
- 0xd2, 0x0f, 0x91, 0x9e, 0xf0, 0x9e, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x2a,
- 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x81,
- 0xa9, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
- 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13,
- 0x0c, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63,
- 0x2e, 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1f,
- 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f,
- 0x6e, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, 0x44,
- 0x69, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x31, 0x38, 0x30, 0x36, 0x06,
- 0x03, 0x55, 0x04, 0x0b, 0x13, 0x2f, 0x28, 0x63, 0x29, 0x20, 0x32, 0x30,
- 0x30, 0x36, 0x20, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2c, 0x20, 0x49,
- 0x6e, 0x63, 0x2e, 0x20, 0x2d, 0x20, 0x46, 0x6f, 0x72, 0x20, 0x61, 0x75,
- 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x20, 0x75, 0x73, 0x65,
- 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55,
- 0x04, 0x03, 0x13, 0x16, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x20, 0x50,
- 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20,
- 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x34, 0x30, 0x36, 0x31, 0x30,
- 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x34, 0x30,
- 0x36, 0x30, 0x39, 0x32, 0x33, 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x63,
- 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55,
- 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0c,
- 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e,
- 0x31, 0x1d, 0x30, 0x1b, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x14, 0x44,
- 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x20, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61,
- 0x74, 0x65, 0x64, 0x20, 0x53, 0x53, 0x4c, 0x31, 0x1e, 0x30, 0x1c, 0x06,
- 0x03, 0x55, 0x04, 0x03, 0x13, 0x15, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65,
- 0x20, 0x44, 0x56, 0x20, 0x53, 0x53, 0x4c, 0x20, 0x43, 0x41, 0x20, 0x2d,
- 0x20, 0x47, 0x32, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a,
- 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82,
- 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00,
- 0xea, 0x94, 0x07, 0x85, 0xc8, 0x41, 0x2c, 0xf6, 0x83, 0x12, 0x6c, 0x92,
- 0x5f, 0xab, 0x1f, 0x00, 0xd4, 0x96, 0x6f, 0x74, 0xcd, 0x2e, 0x11, 0xe9,
- 0x6c, 0x0f, 0x39, 0x01, 0xb9, 0x48, 0x90, 0x40, 0x39, 0x4d, 0xc4, 0xa2,
- 0xc8, 0x79, 0x6a, 0xa5, 0x9a, 0xbd, 0x91, 0x44, 0x65, 0x77, 0x54, 0xad,
- 0xff, 0x25, 0x5f, 0xee, 0x42, 0xfb, 0xb3, 0x02, 0x0f, 0xea, 0x5d, 0x7a,
- 0xdd, 0x1a, 0x54, 0x9e, 0xd7, 0x73, 0x42, 0x9b, 0xcc, 0x79, 0x5f, 0xc5,
- 0x4d, 0xf4, 0xb7, 0x0b, 0x18, 0x39, 0x20, 0x7a, 0xdd, 0x50, 0x01, 0x5d,
- 0x34, 0x45, 0x5f, 0x4c, 0x11, 0x0e, 0xf5, 0x87, 0x26, 0x26, 0xb4, 0xb0,
- 0xf3, 0x7e, 0x71, 0xa0, 0x31, 0x71, 0x50, 0x89, 0x68, 0x5a, 0x63, 0x8a,
- 0x14, 0x62, 0xe5, 0x8c, 0x3a, 0x16, 0x55, 0x0d, 0x3e, 0xeb, 0xaa, 0x80,
- 0x1d, 0x71, 0x7a, 0xe3, 0x87, 0x07, 0xab, 0xbd, 0xa2, 0x74, 0xcd, 0xda,
- 0x08, 0x01, 0x9d, 0x1b, 0xcc, 0x27, 0x88, 0x8c, 0x47, 0xd4, 0x69, 0x25,
- 0x42, 0xd6, 0xbb, 0x50, 0x6d, 0x85, 0x50, 0xd0, 0x48, 0x82, 0x0d, 0x08,
- 0x9f, 0xe9, 0x23, 0xe3, 0x42, 0xc6, 0x3c, 0x98, 0xb8, 0xbb, 0x6e, 0xc5,
- 0x70, 0x13, 0xdf, 0x19, 0x1d, 0x01, 0xfd, 0xd2, 0xb5, 0x4e, 0xe6, 0x62,
- 0xf4, 0x07, 0xfa, 0x6b, 0x7d, 0x11, 0x77, 0xc4, 0x62, 0x4f, 0x40, 0x4e,
- 0xa5, 0x78, 0x97, 0xab, 0x2c, 0x4d, 0x0c, 0xa7, 0x7c, 0xc3, 0xc4, 0x50,
- 0x32, 0x9f, 0xd0, 0x70, 0x9b, 0x0f, 0xff, 0xff, 0x75, 0x59, 0x34, 0x85,
- 0xad, 0x49, 0xd5, 0x35, 0xee, 0x4f, 0x5b, 0xd4, 0xd4, 0x36, 0x95, 0xa0,
- 0x7e, 0xe8, 0xc5, 0xa1, 0x1c, 0xbd, 0x13, 0x4e, 0x7d, 0xee, 0x63, 0x6a,
- 0x96, 0x19, 0x99, 0xc8, 0xa7, 0x2a, 0x00, 0xe6, 0x51, 0x8d, 0x46, 0xeb,
- 0x30, 0x58, 0xe8, 0x2d, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01,
- 0x39, 0x30, 0x82, 0x01, 0x35, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13,
- 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01,
- 0x00, 0x30, 0x41, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x3a, 0x30, 0x38,
- 0x30, 0x36, 0x06, 0x0a, 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x45, 0x01,
- 0x07, 0x36, 0x30, 0x28, 0x30, 0x26, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05,
- 0x05, 0x07, 0x02, 0x01, 0x16, 0x1a, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a,
- 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65,
- 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x70, 0x73, 0x30, 0x0e, 0x06, 0x03,
- 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06,
- 0x30, 0x2e, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01,
- 0x04, 0x22, 0x30, 0x20, 0x30, 0x1e, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05,
- 0x05, 0x07, 0x30, 0x01, 0x86, 0x12, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f,
- 0x2f, 0x74, 0x2e, 0x73, 0x79, 0x6d, 0x63, 0x64, 0x2e, 0x63, 0x6f, 0x6d,
- 0x30, 0x31, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x2a, 0x30, 0x28, 0x30,
- 0x26, 0xa0, 0x24, 0xa0, 0x22, 0x86, 0x20, 0x68, 0x74, 0x74, 0x70, 0x3a,
- 0x2f, 0x2f, 0x74, 0x2e, 0x73, 0x79, 0x6d, 0x63, 0x62, 0x2e, 0x63, 0x6f,
- 0x6d, 0x2f, 0x54, 0x68, 0x61, 0x77, 0x74, 0x65, 0x50, 0x43, 0x41, 0x2e,
- 0x63, 0x72, 0x6c, 0x30, 0x29, 0x06, 0x03, 0x55, 0x1d, 0x11, 0x04, 0x22,
- 0x30, 0x20, 0xa4, 0x1e, 0x30, 0x1c, 0x31, 0x1a, 0x30, 0x18, 0x06, 0x03,
- 0x55, 0x04, 0x03, 0x13, 0x11, 0x53, 0x79, 0x6d, 0x61, 0x6e, 0x74, 0x65,
- 0x63, 0x50, 0x4b, 0x49, 0x2d, 0x31, 0x2d, 0x36, 0x39, 0x38, 0x30, 0x1d,
- 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x9f, 0xb8, 0xc1,
- 0xa9, 0x6c, 0xf2, 0xf5, 0xc0, 0x22, 0x2a, 0x94, 0xed, 0x5c, 0x99, 0xac,
- 0xd4, 0xec, 0xd7, 0xc6, 0x07, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23,
- 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x7b, 0x5b, 0x45, 0xcf, 0xaf, 0xce,
- 0xcb, 0x7a, 0xfd, 0x31, 0x92, 0x1a, 0x6a, 0xb6, 0xf3, 0x46, 0xeb, 0x57,
- 0x48, 0x50, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
- 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x53, 0x54,
- 0xf2, 0x47, 0xa8, 0x02, 0xd7, 0xef, 0xaa, 0x35, 0x78, 0xbe, 0x4a, 0x08,
- 0x0d, 0x90, 0x18, 0x4b, 0x6d, 0x9e, 0x2a, 0x53, 0x2b, 0xe9, 0x54, 0x17,
- 0x77, 0x74, 0x29, 0x7e, 0xd0, 0x37, 0x07, 0x05, 0xb8, 0xe4, 0xfa, 0xb8,
- 0xb4, 0x63, 0x98, 0x44, 0xdc, 0xc6, 0x4f, 0x81, 0x06, 0x8c, 0x3a, 0xbe,
- 0xc7, 0x30, 0x57, 0xc6, 0x70, 0xfc, 0xd6, 0x93, 0x19, 0x9f, 0xc3, 0x55,
- 0xd7, 0x3e, 0x1f, 0x72, 0x8a, 0x9d, 0x30, 0x5a, 0x35, 0x97, 0x32, 0xcb,
- 0x63, 0xe4, 0xc6, 0x72, 0xdf, 0xfb, 0x68, 0xca, 0x69, 0x2f, 0xdb, 0xcd,
- 0x50, 0x38, 0x3e, 0x2b, 0xbb, 0xab, 0x3b, 0x82, 0xc7, 0xfd, 0x4b, 0x9b,
- 0xbd, 0x7c, 0x41, 0x98, 0xef, 0x01, 0x53, 0xd8, 0x35, 0x8f, 0x25, 0xc9,
- 0x03, 0x06, 0xe6, 0x9c, 0x57, 0xc1, 0x51, 0x0f, 0x9e, 0xf6, 0x7d, 0x93,
- 0x4d, 0xf8, 0x76, 0xc8, 0x3a, 0x6b, 0xf4, 0xc4, 0x8f, 0x33, 0x32, 0x7f,
- 0x9d, 0x21, 0x84, 0x34, 0xd9, 0xa7, 0xf9, 0x92, 0xfa, 0x41, 0x91, 0x61,
- 0x84, 0x05, 0x9d, 0xa3, 0x79, 0x46, 0xce, 0x67, 0xe7, 0x81, 0xf2, 0x5e,
- 0xac, 0x4c, 0xbc, 0xa8, 0xab, 0x6a, 0x6d, 0x15, 0xe2, 0x9c, 0x4e, 0x5a,
- 0xd9, 0x63, 0x80, 0xbc, 0xf7, 0x42, 0xeb, 0x9a, 0x44, 0xc6, 0x8c, 0x6b,
- 0x06, 0x36, 0xb4, 0x8b, 0x32, 0x89, 0xde, 0xc2, 0xf1, 0xa8, 0x26, 0xaa,
- 0xa9, 0xac, 0xff, 0xea, 0x71, 0xa6, 0xe7, 0x8c, 0x41, 0xfa, 0x17, 0x35,
- 0xbb, 0xb3, 0x87, 0x31, 0xa9, 0x93, 0xc2, 0xc8, 0x58, 0xe1, 0x0a, 0x4e,
- 0x95, 0x83, 0x9c, 0xb9, 0xed, 0x3b, 0xa5, 0xef, 0x08, 0xe0, 0x74, 0xf9,
- 0xc3, 0x1b, 0xe6, 0x07, 0xa3, 0xee, 0x07, 0xd7, 0x42, 0x22, 0x79, 0x21,
- 0xa0, 0xa1, 0xd4, 0x1d, 0x26, 0xd3, 0xd0, 0xd6, 0xa6, 0x5d, 0x2b, 0x41,
- 0xc0, 0x79,
-};
-
-#if 0
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number:
- 4f:e3:e2:65:21:07:ab:20:37:41:6e:48:70:ce:d2:c2
- Signature Algorithm: sha1WithRSAEncryption
- Issuer: C=SE, O=AddTrust AB, OU=AddTrust External TTP Network, CN=AddTrust External CA Root
- Validity
- Not Before: May 25 00:00:00 2010 GMT
- Not After : May 30 10:48:38 2020 GMT
- Subject: C=US, O=Trusted Secure Certificate Authority, CN=Trusted Secure Certificate Authority
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:80:0b:42:c6:06:6c:cf:22:b3:1a:9e:11:2e:42:
- 6e:39:bf:e8:12:af:3c:42:21:12:95:40:5d:32:b1:
- 6d:1c:21:d1:34:e5:4f:a8:d1:43:a2:26:4e:30:7d:
- 73:44:2c:73:aa:c5:4d:66:01:19:d2:ea:50:59:65:
- d0:68:9d:05:a0:7c:a1:79:53:d0:21:90:59:0e:37:
- db:1e:dc:92:a7:8b:0d:c4:f5:f8:e6:ff:b5:35:1a:
- da:a8:b6:9b:20:85:65:c4:a2:4d:df:f3:94:4d:63:
- 7e:ee:89:07:af:fe:e1:ba:00:15:2d:c6:77:8e:a3:
- fe:ad:cf:26:54:5a:df:fc:d2:de:c2:ad:f6:b2:23:
- fd:a8:83:e5:65:bd:27:f7:27:1a:18:59:6a:9e:14:
- f6:b4:86:ff:1c:58:14:43:73:96:24:bf:10:43:d5:
- 5c:89:f0:ce:f7:e1:96:16:5e:18:4a:27:28:90:80:
- 18:fc:32:fe:f4:c7:b8:d6:82:3d:35:af:bb:4a:1c:
- 5b:05:78:f6:fd:55:3e:82:74:b2:73:b8:89:4e:f7:
- 1b:85:9a:d8:ca:b1:5a:b1:00:20:41:14:30:2b:14:
- 24:ed:37:0e:32:3e:23:88:39:7e:b9:d9:38:03:e2:
- 4c:d9:0d:43:41:33:10:eb:30:72:53:88:f7:52:9b:
- 4f:81
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Authority Key Identifier:
- keyid:AD:BD:98:7A:34:B4:26:F7:FA:C4:26:54:EF:03:BD:E0:24:CB:54:1A
-
- X509v3 Subject Key Identifier:
- CC:03:5B:96:5A:9E:16:CC:26:1E:BD:A3:70:FB:E3:CB:79:19:FC:4D
- X509v3 Key Usage: critical
- Certificate Sign, CRL Sign
- X509v3 Basic Constraints: critical
- CA:TRUE, pathlen:0
- X509v3 Certificate Policies:
- Policy: 1.3.6.1.4.1.6449.1.2.2.8
-
- X509v3 CRL Distribution Points:
-
- Full Name:
- URI:http://crl.usertrust.com/AddTrustExternalCARoot.crl
-
- Authority Information Access:
- CA Issuers - URI:http://crt.usertrust.com/AddTrustExternalCARoot.p7c
- CA Issuers - URI:http://crt.usertrust.com/AddTrustUTNSGCCA.crt
- OCSP - URI:http://ocsp.usertrust.com
-
- Signature Algorithm: sha1WithRSAEncryption
- 7b:f0:fc:a1:28:47:bc:2b:b4:04:73:3f:4b:dd:1e:d1:b9:cd:
- 1c:ed:7d:e5:e8:cb:51:f4:92:bf:dd:9c:0d:5c:6e:1d:95:ed:
- 5b:70:50:89:d4:67:9a:15:54:d1:90:0a:fa:09:68:06:18:bb:
- d7:27:e4:93:ff:43:48:81:3b:c8:59:49:35:ea:ac:b6:ae:46:
- b5:d4:f3:b8:c3:c6:e4:91:bf:c9:34:fd:7e:d0:59:6e:61:a1:
- 1f:48:63:54:b2:7d:46:bf:c8:fa:c3:bf:48:58:98:f6:69:84:
- a7:16:69:08:27:a4:22:cb:a2:2c:c8:df:6e:a9:ee:f8:41:df:
- 1b:a8:b7:f3:e3:ae:ce:a3:fe:d9:27:60:50:3f:04:7d:7a:44:
- ea:76:42:5c:d3:55:46:ef:27:c5:6a:4a:80:e7:35:a0:91:c6:
- 1b:a6:86:9c:5a:3b:04:83:54:34:d7:d1:88:a6:36:e9:7f:40:
- 27:da:56:0a:50:21:9d:29:8b:a0:84:ec:fe:71:23:53:04:18:
- 19:70:67:86:44:95:72:40:55:f6:dd:a3:b4:3d:2d:09:60:a5:
- e7:5f:fc:ac:3b:ec:0c:91:9f:f8:ee:6a:ba:b2:3c:fd:95:7d:
- 9a:07:f4:b0:65:43:a2:f6:df:7d:b8:21:49:84:04:ee:bd:ce:
- 53:8f:0f:29
------BEGIN CERTIFICATE-----
-MIIE5DCCA8ygAwIBAgIQT+PiZSEHqyA3QW5IcM7SwjANBgkqhkiG9w0BAQUFADBv
-MQswCQYDVQQGEwJTRTEUMBIGA1UEChMLQWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFk
-ZFRydXN0IEV4dGVybmFsIFRUUCBOZXR3b3JrMSIwIAYDVQQDExlBZGRUcnVzdCBF
-eHRlcm5hbCBDQSBSb290MB4XDTEwMDUyNTAwMDAwMFoXDTIwMDUzMDEwNDgzOFow
-azELMAkGA1UEBhMCVVMxLTArBgNVBAoTJFRydXN0ZWQgU2VjdXJlIENlcnRpZmlj
-YXRlIEF1dGhvcml0eTEtMCsGA1UEAxMkVHJ1c3RlZCBTZWN1cmUgQ2VydGlmaWNh
-dGUgQXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAgAtC
-xgZszyKzGp4RLkJuOb/oEq88QiESlUBdMrFtHCHRNOVPqNFDoiZOMH1zRCxzqsVN
-ZgEZ0upQWWXQaJ0FoHyheVPQIZBZDjfbHtySp4sNxPX45v+1NRraqLabIIVlxKJN
-3/OUTWN+7okHr/7hugAVLcZ3jqP+rc8mVFrf/NLewq32siP9qIPlZb0n9ycaGFlq
-nhT2tIb/HFgUQ3OWJL8QQ9VcifDO9+GWFl4YSicokIAY/DL+9Me41oI9Na+7Shxb
-BXj2/VU+gnSyc7iJTvcbhZrYyrFasQAgQRQwKxQk7TcOMj4jiDl+udk4A+JM2Q1D
-QTMQ6zByU4j3UptPgQIDAQABo4IBfjCCAXowHwYDVR0jBBgwFoAUrb2YejS0Jvf6
-xCZU7wO94CTLVBowHQYDVR0OBBYEFMwDW5ZanhbMJh69o3D748t5GfxNMA4GA1Ud
-DwEB/wQEAwIBBjASBgNVHRMBAf8ECDAGAQH/AgEAMBgGA1UdIAQRMA8wDQYLKwYB
-BAGyMQECAggwRAYDVR0fBD0wOzA5oDegNYYzaHR0cDovL2NybC51c2VydHJ1c3Qu
-Y29tL0FkZFRydXN0RXh0ZXJuYWxDQVJvb3QuY3JsMIGzBggrBgEFBQcBAQSBpjCB
-ozA/BggrBgEFBQcwAoYzaHR0cDovL2NydC51c2VydHJ1c3QuY29tL0FkZFRydXN0
-RXh0ZXJuYWxDQVJvb3QucDdjMDkGCCsGAQUFBzAChi1odHRwOi8vY3J0LnVzZXJ0
-cnVzdC5jb20vQWRkVHJ1c3RVVE5TR0NDQS5jcnQwJQYIKwYBBQUHMAGGGWh0dHA6
-Ly9vY3NwLnVzZXJ0cnVzdC5jb20wDQYJKoZIhvcNAQEFBQADggEBAHvw/KEoR7wr
-tARzP0vdHtG5zRztfeXoy1H0kr/dnA1cbh2V7VtwUInUZ5oVVNGQCvoJaAYYu9cn
-5JP/Q0iBO8hZSTXqrLauRrXU87jDxuSRv8k0/X7QWW5hoR9IY1SyfUa/yPrDv0hY
-mPZphKcWaQgnpCLLoizI326p7vhB3xuot/Pjrs6j/tknYFA/BH16ROp2QlzTVUbv
-J8VqSoDnNaCRxhumhpxaOwSDVDTX0YimNul/QCfaVgpQIZ0pi6CE7P5xI1MEGBlw
-Z4ZElXJAVfbdo7Q9LQlgpedf/Kw77AyRn/juarqyPP2VfZoH9LBlQ6L23324IUmE
-BO69zlOPDyk=
------END CERTIFICATE-----
-#endif
-static const unsigned char kDERCert35[] = {
- 0x30, 0x82, 0x04, 0xe4, 0x30, 0x82, 0x03, 0xcc, 0xa0, 0x03, 0x02, 0x01,
- 0x02, 0x02, 0x10, 0x4f, 0xe3, 0xe2, 0x65, 0x21, 0x07, 0xab, 0x20, 0x37,
- 0x41, 0x6e, 0x48, 0x70, 0xce, 0xd2, 0xc2, 0x30, 0x0d, 0x06, 0x09, 0x2a,
- 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x6f,
- 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x53,
- 0x45, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0b,
- 0x41, 0x64, 0x64, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x41, 0x42, 0x31,
- 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1d, 0x41, 0x64,
- 0x64, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x45, 0x78, 0x74, 0x65, 0x72,
- 0x6e, 0x61, 0x6c, 0x20, 0x54, 0x54, 0x50, 0x20, 0x4e, 0x65, 0x74, 0x77,
- 0x6f, 0x72, 0x6b, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x03,
- 0x13, 0x19, 0x41, 0x64, 0x64, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x45,
- 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x20, 0x43, 0x41, 0x20, 0x52,
- 0x6f, 0x6f, 0x74, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x30, 0x30, 0x35, 0x32,
- 0x35, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x30,
- 0x30, 0x35, 0x33, 0x30, 0x31, 0x30, 0x34, 0x38, 0x33, 0x38, 0x5a, 0x30,
- 0x6b, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
- 0x55, 0x53, 0x31, 0x2d, 0x30, 0x2b, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13,
- 0x24, 0x54, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x20, 0x53, 0x65, 0x63,
- 0x75, 0x72, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63,
- 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74,
- 0x79, 0x31, 0x2d, 0x30, 0x2b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x24,
- 0x54, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x20, 0x53, 0x65, 0x63, 0x75,
- 0x72, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61,
- 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79,
- 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
- 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00,
- 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0x80, 0x0b, 0x42,
- 0xc6, 0x06, 0x6c, 0xcf, 0x22, 0xb3, 0x1a, 0x9e, 0x11, 0x2e, 0x42, 0x6e,
- 0x39, 0xbf, 0xe8, 0x12, 0xaf, 0x3c, 0x42, 0x21, 0x12, 0x95, 0x40, 0x5d,
- 0x32, 0xb1, 0x6d, 0x1c, 0x21, 0xd1, 0x34, 0xe5, 0x4f, 0xa8, 0xd1, 0x43,
- 0xa2, 0x26, 0x4e, 0x30, 0x7d, 0x73, 0x44, 0x2c, 0x73, 0xaa, 0xc5, 0x4d,
- 0x66, 0x01, 0x19, 0xd2, 0xea, 0x50, 0x59, 0x65, 0xd0, 0x68, 0x9d, 0x05,
- 0xa0, 0x7c, 0xa1, 0x79, 0x53, 0xd0, 0x21, 0x90, 0x59, 0x0e, 0x37, 0xdb,
- 0x1e, 0xdc, 0x92, 0xa7, 0x8b, 0x0d, 0xc4, 0xf5, 0xf8, 0xe6, 0xff, 0xb5,
- 0x35, 0x1a, 0xda, 0xa8, 0xb6, 0x9b, 0x20, 0x85, 0x65, 0xc4, 0xa2, 0x4d,
- 0xdf, 0xf3, 0x94, 0x4d, 0x63, 0x7e, 0xee, 0x89, 0x07, 0xaf, 0xfe, 0xe1,
- 0xba, 0x00, 0x15, 0x2d, 0xc6, 0x77, 0x8e, 0xa3, 0xfe, 0xad, 0xcf, 0x26,
- 0x54, 0x5a, 0xdf, 0xfc, 0xd2, 0xde, 0xc2, 0xad, 0xf6, 0xb2, 0x23, 0xfd,
- 0xa8, 0x83, 0xe5, 0x65, 0xbd, 0x27, 0xf7, 0x27, 0x1a, 0x18, 0x59, 0x6a,
- 0x9e, 0x14, 0xf6, 0xb4, 0x86, 0xff, 0x1c, 0x58, 0x14, 0x43, 0x73, 0x96,
- 0x24, 0xbf, 0x10, 0x43, 0xd5, 0x5c, 0x89, 0xf0, 0xce, 0xf7, 0xe1, 0x96,
- 0x16, 0x5e, 0x18, 0x4a, 0x27, 0x28, 0x90, 0x80, 0x18, 0xfc, 0x32, 0xfe,
- 0xf4, 0xc7, 0xb8, 0xd6, 0x82, 0x3d, 0x35, 0xaf, 0xbb, 0x4a, 0x1c, 0x5b,
- 0x05, 0x78, 0xf6, 0xfd, 0x55, 0x3e, 0x82, 0x74, 0xb2, 0x73, 0xb8, 0x89,
- 0x4e, 0xf7, 0x1b, 0x85, 0x9a, 0xd8, 0xca, 0xb1, 0x5a, 0xb1, 0x00, 0x20,
- 0x41, 0x14, 0x30, 0x2b, 0x14, 0x24, 0xed, 0x37, 0x0e, 0x32, 0x3e, 0x23,
- 0x88, 0x39, 0x7e, 0xb9, 0xd9, 0x38, 0x03, 0xe2, 0x4c, 0xd9, 0x0d, 0x43,
- 0x41, 0x33, 0x10, 0xeb, 0x30, 0x72, 0x53, 0x88, 0xf7, 0x52, 0x9b, 0x4f,
- 0x81, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x7e, 0x30, 0x82,
- 0x01, 0x7a, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30,
- 0x16, 0x80, 0x14, 0xad, 0xbd, 0x98, 0x7a, 0x34, 0xb4, 0x26, 0xf7, 0xfa,
- 0xc4, 0x26, 0x54, 0xef, 0x03, 0xbd, 0xe0, 0x24, 0xcb, 0x54, 0x1a, 0x30,
- 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xcc, 0x03,
- 0x5b, 0x96, 0x5a, 0x9e, 0x16, 0xcc, 0x26, 0x1e, 0xbd, 0xa3, 0x70, 0xfb,
- 0xe3, 0xcb, 0x79, 0x19, 0xfc, 0x4d, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d,
- 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x12,
- 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06,
- 0x01, 0x01, 0xff, 0x02, 0x01, 0x00, 0x30, 0x18, 0x06, 0x03, 0x55, 0x1d,
- 0x20, 0x04, 0x11, 0x30, 0x0f, 0x30, 0x0d, 0x06, 0x0b, 0x2b, 0x06, 0x01,
- 0x04, 0x01, 0xb2, 0x31, 0x01, 0x02, 0x02, 0x08, 0x30, 0x44, 0x06, 0x03,
- 0x55, 0x1d, 0x1f, 0x04, 0x3d, 0x30, 0x3b, 0x30, 0x39, 0xa0, 0x37, 0xa0,
- 0x35, 0x86, 0x33, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72,
- 0x6c, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e,
- 0x63, 0x6f, 0x6d, 0x2f, 0x41, 0x64, 0x64, 0x54, 0x72, 0x75, 0x73, 0x74,
- 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x43, 0x41, 0x52, 0x6f,
- 0x6f, 0x74, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x81, 0xb3, 0x06, 0x08, 0x2b,
- 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x81, 0xa6, 0x30, 0x81,
- 0xa3, 0x30, 0x3f, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30,
- 0x02, 0x86, 0x33, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72,
- 0x74, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e,
- 0x63, 0x6f, 0x6d, 0x2f, 0x41, 0x64, 0x64, 0x54, 0x72, 0x75, 0x73, 0x74,
- 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x43, 0x41, 0x52, 0x6f,
- 0x6f, 0x74, 0x2e, 0x70, 0x37, 0x63, 0x30, 0x39, 0x06, 0x08, 0x2b, 0x06,
- 0x01, 0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x2d, 0x68, 0x74, 0x74, 0x70,
- 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x74, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x74,
- 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x41, 0x64, 0x64,
- 0x54, 0x72, 0x75, 0x73, 0x74, 0x55, 0x54, 0x4e, 0x53, 0x47, 0x43, 0x43,
- 0x41, 0x2e, 0x63, 0x72, 0x74, 0x30, 0x25, 0x06, 0x08, 0x2b, 0x06, 0x01,
- 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x19, 0x68, 0x74, 0x74, 0x70, 0x3a,
- 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x74,
- 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x0d, 0x06, 0x09,
- 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03,
- 0x82, 0x01, 0x01, 0x00, 0x7b, 0xf0, 0xfc, 0xa1, 0x28, 0x47, 0xbc, 0x2b,
- 0xb4, 0x04, 0x73, 0x3f, 0x4b, 0xdd, 0x1e, 0xd1, 0xb9, 0xcd, 0x1c, 0xed,
- 0x7d, 0xe5, 0xe8, 0xcb, 0x51, 0xf4, 0x92, 0xbf, 0xdd, 0x9c, 0x0d, 0x5c,
- 0x6e, 0x1d, 0x95, 0xed, 0x5b, 0x70, 0x50, 0x89, 0xd4, 0x67, 0x9a, 0x15,
- 0x54, 0xd1, 0x90, 0x0a, 0xfa, 0x09, 0x68, 0x06, 0x18, 0xbb, 0xd7, 0x27,
- 0xe4, 0x93, 0xff, 0x43, 0x48, 0x81, 0x3b, 0xc8, 0x59, 0x49, 0x35, 0xea,
- 0xac, 0xb6, 0xae, 0x46, 0xb5, 0xd4, 0xf3, 0xb8, 0xc3, 0xc6, 0xe4, 0x91,
- 0xbf, 0xc9, 0x34, 0xfd, 0x7e, 0xd0, 0x59, 0x6e, 0x61, 0xa1, 0x1f, 0x48,
- 0x63, 0x54, 0xb2, 0x7d, 0x46, 0xbf, 0xc8, 0xfa, 0xc3, 0xbf, 0x48, 0x58,
- 0x98, 0xf6, 0x69, 0x84, 0xa7, 0x16, 0x69, 0x08, 0x27, 0xa4, 0x22, 0xcb,
- 0xa2, 0x2c, 0xc8, 0xdf, 0x6e, 0xa9, 0xee, 0xf8, 0x41, 0xdf, 0x1b, 0xa8,
- 0xb7, 0xf3, 0xe3, 0xae, 0xce, 0xa3, 0xfe, 0xd9, 0x27, 0x60, 0x50, 0x3f,
- 0x04, 0x7d, 0x7a, 0x44, 0xea, 0x76, 0x42, 0x5c, 0xd3, 0x55, 0x46, 0xef,
- 0x27, 0xc5, 0x6a, 0x4a, 0x80, 0xe7, 0x35, 0xa0, 0x91, 0xc6, 0x1b, 0xa6,
- 0x86, 0x9c, 0x5a, 0x3b, 0x04, 0x83, 0x54, 0x34, 0xd7, 0xd1, 0x88, 0xa6,
- 0x36, 0xe9, 0x7f, 0x40, 0x27, 0xda, 0x56, 0x0a, 0x50, 0x21, 0x9d, 0x29,
- 0x8b, 0xa0, 0x84, 0xec, 0xfe, 0x71, 0x23, 0x53, 0x04, 0x18, 0x19, 0x70,
- 0x67, 0x86, 0x44, 0x95, 0x72, 0x40, 0x55, 0xf6, 0xdd, 0xa3, 0xb4, 0x3d,
- 0x2d, 0x09, 0x60, 0xa5, 0xe7, 0x5f, 0xfc, 0xac, 0x3b, 0xec, 0x0c, 0x91,
- 0x9f, 0xf8, 0xee, 0x6a, 0xba, 0xb2, 0x3c, 0xfd, 0x95, 0x7d, 0x9a, 0x07,
- 0xf4, 0xb0, 0x65, 0x43, 0xa2, 0xf6, 0xdf, 0x7d, 0xb8, 0x21, 0x49, 0x84,
- 0x04, 0xee, 0xbd, 0xce, 0x53, 0x8f, 0x0f, 0x29,
-};
-
-#if 0
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number: 946072060 (0x3863e9fc)
- Signature Algorithm: sha1WithRSAEncryption
- Issuer: O=Entrust.net, OU=www.entrust.net/CPS_2048 incorp. by ref. (limits liab.), OU=(c) 1999 Entrust.net Limited, CN=Entrust.net Certification Authority (2048)
- Validity
- Not Before: Dec 10 20:43:54 2009 GMT
- Not After : Dec 10 21:13:54 2019 GMT
- Subject: C=US, O=Entrust, Inc., OU=www.entrust.net/rpa is incorporated by reference, OU=(c) 2009 Entrust, Inc., CN=Entrust Certification Authority - L1C
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:97:a3:2d:3c:9e:de:05:da:13:c2:11:8d:9d:8e:
- e3:7f:c7:4b:7e:5a:9f:b3:ff:62:ab:73:c8:28:6b:
- ba:10:64:82:87:13:cd:57:18:ff:28:ce:c0:e6:0e:
- 06:91:50:29:83:d1:f2:c3:2a:db:d8:db:4e:04:cc:
- 00:eb:8b:b6:96:dc:bc:aa:fa:52:77:04:c1:db:19:
- e4:ae:9c:fd:3c:8b:03:ef:4d:bc:1a:03:65:f9:c1:
- b1:3f:72:86:f2:38:aa:19:ae:10:88:78:28:da:75:
- c3:3d:02:82:02:9c:b9:c1:65:77:76:24:4c:98:f7:
- 6d:31:38:fb:db:fe:db:37:02:76:a1:18:97:a6:cc:
- de:20:09:49:36:24:69:42:f6:e4:37:62:f1:59:6d:
- a9:3c:ed:34:9c:a3:8e:db:dc:3a:d7:f7:0a:6f:ef:
- 2e:d8:d5:93:5a:7a:ed:08:49:68:e2:41:e3:5a:90:
- c1:86:55:fc:51:43:9d:e0:b2:c4:67:b4:cb:32:31:
- 25:f0:54:9f:4b:d1:6f:db:d4:dd:fc:af:5e:6c:78:
- 90:95:de:ca:3a:48:b9:79:3c:9b:19:d6:75:05:a0:
- f9:88:d7:c1:e8:a5:09:e4:1a:15:dc:87:23:aa:b2:
- 75:8c:63:25:87:d8:f8:3d:a6:c2:cc:66:ff:a5:66:
- 68:55
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Key Usage: critical
- Certificate Sign, CRL Sign
- X509v3 Basic Constraints: critical
- CA:TRUE
- Authority Information Access:
- OCSP - URI:http://ocsp.entrust.net
-
- X509v3 CRL Distribution Points:
-
- Full Name:
- URI:http://crl.entrust.net/2048ca.crl
-
- X509v3 Certificate Policies:
- Policy: X509v3 Any Policy
- CPS: http://www.entrust.net/rpa
-
- X509v3 Subject Key Identifier:
- 1E:F1:AB:89:06:F8:49:0F:01:33:77:EE:14:7A:EE:19:7C:93:28:4D
- X509v3 Authority Key Identifier:
- keyid:55:E4:81:D1:11:80:BE:D8:89:B9:08:A3:31:F9:A1:24:09:16:B9:70
-
- Signature Algorithm: sha1WithRSAEncryption
- 07:f6:5f:82:84:7f:80:40:c7:90:34:46:42:24:03:ce:2f:ab:
- ba:83:9e:25:73:0d:ed:ac:05:69:c6:87:ed:a3:5c:f2:57:c1:
- b1:49:76:9a:4d:f2:3f:dd:e4:0e:fe:0b:3e:b9:98:d9:32:95:
- 1d:32:f4:01:ee:9c:c8:c8:e5:3f:e0:53:76:62:fc:dd:ab:6d:
- 3d:94:90:f2:c0:b3:3c:98:27:36:5e:28:97:22:fc:1b:40:d3:
- 2b:0d:ad:b5:57:6d:df:0f:e3:4b:ef:73:02:10:65:fa:1b:d0:
- ac:31:d5:e3:0f:e8:ba:32:30:83:ee:4a:d0:bf:df:22:90:7a:
- be:ec:3a:1b:c4:49:04:1d:f1:ae:80:77:3c:42:08:db:a7:3b:
- 28:a6:80:01:03:e6:39:a3:eb:df:80:59:1b:f3:2c:be:dc:72:
- 44:79:a0:6c:07:a5:6d:4d:44:8e:42:68:ca:94:7c:2e:36:ba:
- 85:9e:cd:aa:c4:5e:3c:54:be:fe:2f:ea:69:9d:1c:1e:29:9b:
- 96:d8:c8:fe:51:90:f1:24:a6:90:06:b3:f0:29:a2:ff:78:2e:
- 77:5c:45:21:d9:44:00:31:f3:be:32:4f:f5:0a:32:0d:fc:fc:
- ba:16:76:56:b2:d6:48:92:f2:8b:a6:3e:b7:ac:5c:69:ea:0b:
- 3f:66:45:b9
------BEGIN CERTIFICATE-----
-MIIE8jCCA9qgAwIBAgIEOGPp/DANBgkqhkiG9w0BAQUFADCBtDEUMBIGA1UEChML
-RW50cnVzdC5uZXQxQDA+BgNVBAsUN3d3dy5lbnRydXN0Lm5ldC9DUFNfMjA0OCBp
-bmNvcnAuIGJ5IHJlZi4gKGxpbWl0cyBsaWFiLikxJTAjBgNVBAsTHChjKSAxOTk5
-IEVudHJ1c3QubmV0IExpbWl0ZWQxMzAxBgNVBAMTKkVudHJ1c3QubmV0IENlcnRp
-ZmljYXRpb24gQXV0aG9yaXR5ICgyMDQ4KTAeFw0wOTEyMTAyMDQzNTRaFw0xOTEy
-MTAyMTEzNTRaMIGxMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNRW50cnVzdCwgSW5j
-LjE5MDcGA1UECxMwd3d3LmVudHJ1c3QubmV0L3JwYSBpcyBpbmNvcnBvcmF0ZWQg
-YnkgcmVmZXJlbmNlMR8wHQYDVQQLExYoYykgMjAwOSBFbnRydXN0LCBJbmMuMS4w
-LAYDVQQDEyVFbnRydXN0IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gTDFDMIIB
-IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAl6MtPJ7eBdoTwhGNnY7jf8dL
-flqfs/9iq3PIKGu6EGSChxPNVxj/KM7A5g4GkVApg9Hywyrb2NtOBMwA64u2lty8
-qvpSdwTB2xnkrpz9PIsD7028GgNl+cGxP3KG8jiqGa4QiHgo2nXDPQKCApy5wWV3
-diRMmPdtMTj72/7bNwJ2oRiXpszeIAlJNiRpQvbkN2LxWW2pPO00nKOO29w61/cK
-b+8u2NWTWnrtCElo4kHjWpDBhlX8UUOd4LLEZ7TLMjEl8FSfS9Fv29Td/K9ebHiQ
-ld7KOki5eTybGdZ1BaD5iNfB6KUJ5BoV3IcjqrJ1jGMlh9j4PabCzGb/pWZoVQID
-AQABo4IBCzCCAQcwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wMwYI
-KwYBBQUHAQEEJzAlMCMGCCsGAQUFBzABhhdodHRwOi8vb2NzcC5lbnRydXN0Lm5l
-dDAyBgNVHR8EKzApMCegJaAjhiFodHRwOi8vY3JsLmVudHJ1c3QubmV0LzIwNDhj
-YS5jcmwwOwYDVR0gBDQwMjAwBgRVHSAAMCgwJgYIKwYBBQUHAgEWGmh0dHA6Ly93
-d3cuZW50cnVzdC5uZXQvcnBhMB0GA1UdDgQWBBQe8auJBvhJDwEzd+4Ueu4ZfJMo
-TTAfBgNVHSMEGDAWgBRV5IHREYC+2Im5CKMx+aEkCRa5cDANBgkqhkiG9w0BAQUF
-AAOCAQEAB/ZfgoR/gEDHkDRGQiQDzi+ruoOeJXMN7awFacaH7aNc8lfBsUl2mk3y
-P93kDv4LPrmY2TKVHTL0Ae6cyMjlP+BTdmL83attPZSQ8sCzPJgnNl4olyL8G0DT
-Kw2ttVdt3w/jS+9zAhBl+hvQrDHV4w/oujIwg+5K0L/fIpB6vuw6G8RJBB3xroB3
-PEII26c7KKaAAQPmOaPr34BZG/MsvtxyRHmgbAelbU1EjkJoypR8Lja6hZ7NqsRe
-PFS+/i/qaZ0cHimbltjI/lGQ8SSmkAaz8Cmi/3gud1xFIdlEADHzvjJP9QoyDfz8
-uhZ2VrLWSJLyi6Y+t6xcaeoLP2ZFuQ==
------END CERTIFICATE-----
-#endif
-static const unsigned char kDERCert36[] = {
- 0x30, 0x82, 0x04, 0xf2, 0x30, 0x82, 0x03, 0xda, 0xa0, 0x03, 0x02, 0x01,
- 0x02, 0x02, 0x04, 0x38, 0x63, 0xe9, 0xfc, 0x30, 0x0d, 0x06, 0x09, 0x2a,
- 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x81,
- 0xb4, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0b,
- 0x45, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x6e, 0x65, 0x74, 0x31,
- 0x40, 0x30, 0x3e, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x14, 0x37, 0x77, 0x77,
- 0x77, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x6e, 0x65,
- 0x74, 0x2f, 0x43, 0x50, 0x53, 0x5f, 0x32, 0x30, 0x34, 0x38, 0x20, 0x69,
- 0x6e, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x20, 0x62, 0x79, 0x20, 0x72, 0x65,
- 0x66, 0x2e, 0x20, 0x28, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x73, 0x20, 0x6c,
- 0x69, 0x61, 0x62, 0x2e, 0x29, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55,
- 0x04, 0x0b, 0x13, 0x1c, 0x28, 0x63, 0x29, 0x20, 0x31, 0x39, 0x39, 0x39,
- 0x20, 0x45, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x6e, 0x65, 0x74,
- 0x20, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x65, 0x64, 0x31, 0x33, 0x30, 0x31,
- 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x2a, 0x45, 0x6e, 0x74, 0x72, 0x75,
- 0x73, 0x74, 0x2e, 0x6e, 0x65, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69,
- 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74,
- 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x20, 0x28, 0x32, 0x30, 0x34, 0x38,
- 0x29, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x39, 0x31, 0x32, 0x31, 0x30, 0x32,
- 0x30, 0x34, 0x33, 0x35, 0x34, 0x5a, 0x17, 0x0d, 0x31, 0x39, 0x31, 0x32,
- 0x31, 0x30, 0x32, 0x31, 0x31, 0x33, 0x35, 0x34, 0x5a, 0x30, 0x81, 0xb1,
- 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55,
- 0x53, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0d,
- 0x45, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2c, 0x20, 0x49, 0x6e, 0x63,
- 0x2e, 0x31, 0x39, 0x30, 0x37, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x30,
- 0x77, 0x77, 0x77, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e,
- 0x6e, 0x65, 0x74, 0x2f, 0x72, 0x70, 0x61, 0x20, 0x69, 0x73, 0x20, 0x69,
- 0x6e, 0x63, 0x6f, 0x72, 0x70, 0x6f, 0x72, 0x61, 0x74, 0x65, 0x64, 0x20,
- 0x62, 0x79, 0x20, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65,
- 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x16, 0x28,
- 0x63, 0x29, 0x20, 0x32, 0x30, 0x30, 0x39, 0x20, 0x45, 0x6e, 0x74, 0x72,
- 0x75, 0x73, 0x74, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x2e, 0x30,
- 0x2c, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x25, 0x45, 0x6e, 0x74, 0x72,
- 0x75, 0x73, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63,
- 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72,
- 0x69, 0x74, 0x79, 0x20, 0x2d, 0x20, 0x4c, 0x31, 0x43, 0x30, 0x82, 0x01,
- 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
- 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01,
- 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0x97, 0xa3, 0x2d, 0x3c, 0x9e, 0xde,
- 0x05, 0xda, 0x13, 0xc2, 0x11, 0x8d, 0x9d, 0x8e, 0xe3, 0x7f, 0xc7, 0x4b,
- 0x7e, 0x5a, 0x9f, 0xb3, 0xff, 0x62, 0xab, 0x73, 0xc8, 0x28, 0x6b, 0xba,
- 0x10, 0x64, 0x82, 0x87, 0x13, 0xcd, 0x57, 0x18, 0xff, 0x28, 0xce, 0xc0,
- 0xe6, 0x0e, 0x06, 0x91, 0x50, 0x29, 0x83, 0xd1, 0xf2, 0xc3, 0x2a, 0xdb,
- 0xd8, 0xdb, 0x4e, 0x04, 0xcc, 0x00, 0xeb, 0x8b, 0xb6, 0x96, 0xdc, 0xbc,
- 0xaa, 0xfa, 0x52, 0x77, 0x04, 0xc1, 0xdb, 0x19, 0xe4, 0xae, 0x9c, 0xfd,
- 0x3c, 0x8b, 0x03, 0xef, 0x4d, 0xbc, 0x1a, 0x03, 0x65, 0xf9, 0xc1, 0xb1,
- 0x3f, 0x72, 0x86, 0xf2, 0x38, 0xaa, 0x19, 0xae, 0x10, 0x88, 0x78, 0x28,
- 0xda, 0x75, 0xc3, 0x3d, 0x02, 0x82, 0x02, 0x9c, 0xb9, 0xc1, 0x65, 0x77,
- 0x76, 0x24, 0x4c, 0x98, 0xf7, 0x6d, 0x31, 0x38, 0xfb, 0xdb, 0xfe, 0xdb,
- 0x37, 0x02, 0x76, 0xa1, 0x18, 0x97, 0xa6, 0xcc, 0xde, 0x20, 0x09, 0x49,
- 0x36, 0x24, 0x69, 0x42, 0xf6, 0xe4, 0x37, 0x62, 0xf1, 0x59, 0x6d, 0xa9,
- 0x3c, 0xed, 0x34, 0x9c, 0xa3, 0x8e, 0xdb, 0xdc, 0x3a, 0xd7, 0xf7, 0x0a,
- 0x6f, 0xef, 0x2e, 0xd8, 0xd5, 0x93, 0x5a, 0x7a, 0xed, 0x08, 0x49, 0x68,
- 0xe2, 0x41, 0xe3, 0x5a, 0x90, 0xc1, 0x86, 0x55, 0xfc, 0x51, 0x43, 0x9d,
- 0xe0, 0xb2, 0xc4, 0x67, 0xb4, 0xcb, 0x32, 0x31, 0x25, 0xf0, 0x54, 0x9f,
- 0x4b, 0xd1, 0x6f, 0xdb, 0xd4, 0xdd, 0xfc, 0xaf, 0x5e, 0x6c, 0x78, 0x90,
- 0x95, 0xde, 0xca, 0x3a, 0x48, 0xb9, 0x79, 0x3c, 0x9b, 0x19, 0xd6, 0x75,
- 0x05, 0xa0, 0xf9, 0x88, 0xd7, 0xc1, 0xe8, 0xa5, 0x09, 0xe4, 0x1a, 0x15,
- 0xdc, 0x87, 0x23, 0xaa, 0xb2, 0x75, 0x8c, 0x63, 0x25, 0x87, 0xd8, 0xf8,
- 0x3d, 0xa6, 0xc2, 0xcc, 0x66, 0xff, 0xa5, 0x66, 0x68, 0x55, 0x02, 0x03,
- 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x0b, 0x30, 0x82, 0x01, 0x07, 0x30,
- 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03,
- 0x02, 0x01, 0x06, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01,
- 0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x33, 0x06, 0x08,
- 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x27, 0x30, 0x25,
- 0x30, 0x23, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01,
- 0x86, 0x17, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73,
- 0x70, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x6e, 0x65,
- 0x74, 0x30, 0x32, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x2b, 0x30, 0x29,
- 0x30, 0x27, 0xa0, 0x25, 0xa0, 0x23, 0x86, 0x21, 0x68, 0x74, 0x74, 0x70,
- 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x75,
- 0x73, 0x74, 0x2e, 0x6e, 0x65, 0x74, 0x2f, 0x32, 0x30, 0x34, 0x38, 0x63,
- 0x61, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x3b, 0x06, 0x03, 0x55, 0x1d, 0x20,
- 0x04, 0x34, 0x30, 0x32, 0x30, 0x30, 0x06, 0x04, 0x55, 0x1d, 0x20, 0x00,
- 0x30, 0x28, 0x30, 0x26, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
- 0x02, 0x01, 0x16, 0x1a, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77,
- 0x77, 0x77, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x6e,
- 0x65, 0x74, 0x2f, 0x72, 0x70, 0x61, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d,
- 0x0e, 0x04, 0x16, 0x04, 0x14, 0x1e, 0xf1, 0xab, 0x89, 0x06, 0xf8, 0x49,
- 0x0f, 0x01, 0x33, 0x77, 0xee, 0x14, 0x7a, 0xee, 0x19, 0x7c, 0x93, 0x28,
- 0x4d, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16,
- 0x80, 0x14, 0x55, 0xe4, 0x81, 0xd1, 0x11, 0x80, 0xbe, 0xd8, 0x89, 0xb9,
- 0x08, 0xa3, 0x31, 0xf9, 0xa1, 0x24, 0x09, 0x16, 0xb9, 0x70, 0x30, 0x0d,
- 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05,
- 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x07, 0xf6, 0x5f, 0x82, 0x84, 0x7f,
- 0x80, 0x40, 0xc7, 0x90, 0x34, 0x46, 0x42, 0x24, 0x03, 0xce, 0x2f, 0xab,
- 0xba, 0x83, 0x9e, 0x25, 0x73, 0x0d, 0xed, 0xac, 0x05, 0x69, 0xc6, 0x87,
- 0xed, 0xa3, 0x5c, 0xf2, 0x57, 0xc1, 0xb1, 0x49, 0x76, 0x9a, 0x4d, 0xf2,
- 0x3f, 0xdd, 0xe4, 0x0e, 0xfe, 0x0b, 0x3e, 0xb9, 0x98, 0xd9, 0x32, 0x95,
- 0x1d, 0x32, 0xf4, 0x01, 0xee, 0x9c, 0xc8, 0xc8, 0xe5, 0x3f, 0xe0, 0x53,
- 0x76, 0x62, 0xfc, 0xdd, 0xab, 0x6d, 0x3d, 0x94, 0x90, 0xf2, 0xc0, 0xb3,
- 0x3c, 0x98, 0x27, 0x36, 0x5e, 0x28, 0x97, 0x22, 0xfc, 0x1b, 0x40, 0xd3,
- 0x2b, 0x0d, 0xad, 0xb5, 0x57, 0x6d, 0xdf, 0x0f, 0xe3, 0x4b, 0xef, 0x73,
- 0x02, 0x10, 0x65, 0xfa, 0x1b, 0xd0, 0xac, 0x31, 0xd5, 0xe3, 0x0f, 0xe8,
- 0xba, 0x32, 0x30, 0x83, 0xee, 0x4a, 0xd0, 0xbf, 0xdf, 0x22, 0x90, 0x7a,
- 0xbe, 0xec, 0x3a, 0x1b, 0xc4, 0x49, 0x04, 0x1d, 0xf1, 0xae, 0x80, 0x77,
- 0x3c, 0x42, 0x08, 0xdb, 0xa7, 0x3b, 0x28, 0xa6, 0x80, 0x01, 0x03, 0xe6,
- 0x39, 0xa3, 0xeb, 0xdf, 0x80, 0x59, 0x1b, 0xf3, 0x2c, 0xbe, 0xdc, 0x72,
- 0x44, 0x79, 0xa0, 0x6c, 0x07, 0xa5, 0x6d, 0x4d, 0x44, 0x8e, 0x42, 0x68,
- 0xca, 0x94, 0x7c, 0x2e, 0x36, 0xba, 0x85, 0x9e, 0xcd, 0xaa, 0xc4, 0x5e,
- 0x3c, 0x54, 0xbe, 0xfe, 0x2f, 0xea, 0x69, 0x9d, 0x1c, 0x1e, 0x29, 0x9b,
- 0x96, 0xd8, 0xc8, 0xfe, 0x51, 0x90, 0xf1, 0x24, 0xa6, 0x90, 0x06, 0xb3,
- 0xf0, 0x29, 0xa2, 0xff, 0x78, 0x2e, 0x77, 0x5c, 0x45, 0x21, 0xd9, 0x44,
- 0x00, 0x31, 0xf3, 0xbe, 0x32, 0x4f, 0xf5, 0x0a, 0x32, 0x0d, 0xfc, 0xfc,
- 0xba, 0x16, 0x76, 0x56, 0xb2, 0xd6, 0x48, 0x92, 0xf2, 0x8b, 0xa6, 0x3e,
- 0xb7, 0xac, 0x5c, 0x69, 0xea, 0x0b, 0x3f, 0x66, 0x45, 0xb9,
-};
-
-#if 0
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number:
- 16:90:c3:29:b6:78:06:07:51:1f:05:b0:34:48:46:cb
- Signature Algorithm: sha1WithRSAEncryption
- Issuer: C=SE, O=AddTrust AB, OU=AddTrust External TTP Network, CN=AddTrust External CA Root
- Validity
- Not Before: Apr 16 00:00:00 2010 GMT
- Not After : May 30 10:48:38 2020 GMT
- Subject: C=GB, ST=Greater Manchester, L=Salford, O=COMODO CA Limited, CN=COMODO High-Assurance Secure Server CA
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:e7:87:da:c0:77:e4:bb:3a:fa:6a:24:c8:80:41:
- ac:d2:16:13:15:3d:fa:f7:f8:2a:76:dc:a8:2d:39:
- 08:ce:48:4a:be:0f:7d:f0:de:ba:bb:47:d5:bd:2d:
- d7:1b:ab:0f:20:81:23:08:72:b1:c0:11:95:0d:e6:
- ea:a9:87:ff:c7:6e:1e:4f:66:32:ba:53:bc:05:aa:
- 1c:2c:0c:ef:4d:37:47:6b:10:0c:db:c5:a0:98:7e:
- 58:db:37:d6:ae:e9:06:bd:d7:a8:65:f3:37:b9:c7:
- 6d:ce:77:c7:26:e0:d7:74:1f:a6:98:16:bb:0c:6b:
- c8:be:77:d0:ef:58:a7:29:a0:b9:b8:69:05:36:cb:
- b2:da:58:a3:0b:75:ad:3d:8b:22:82:20:3e:70:86:
- 99:1c:b9:4f:cf:77:a4:07:1a:23:63:d1:38:56:84:
- ec:bf:8f:c5:4e:f4:18:96:9b:1a:e8:93:ec:8d:af:
- 15:9c:24:f0:5a:3b:e8:0f:b9:a8:5a:01:d3:b2:1c:
- 60:c9:9c:52:04:dd:92:a7:fe:0c:ac:e2:45:8d:03:
- 61:bc:79:e0:77:2e:87:41:3c:58:5f:cb:f5:c5:77:
- f2:58:c8:4d:28:d0:9a:fa:f3:73:09:24:68:74:bc:
- 20:4c:d8:2c:b0:aa:e8:d9:4e:6d:f2:8c:24:d3:93:
- 5d:91
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Authority Key Identifier:
- keyid:AD:BD:98:7A:34:B4:26:F7:FA:C4:26:54:EF:03:BD:E0:24:CB:54:1A
-
- X509v3 Subject Key Identifier:
- 3F:D5:B5:D0:D6:44:79:50:4A:17:A3:9B:8C:4A:DC:B8:B0:22:64:6B
- X509v3 Key Usage: critical
- Certificate Sign, CRL Sign
- X509v3 Basic Constraints: critical
- CA:TRUE, pathlen:0
- X509v3 Certificate Policies:
- Policy: X509v3 Any Policy
-
- X509v3 CRL Distribution Points:
-
- Full Name:
- URI:http://crl.usertrust.com/AddTrustExternalCARoot.crl
-
- Authority Information Access:
- CA Issuers - URI:http://crt.usertrust.com/AddTrustExternalCARoot.p7c
- CA Issuers - URI:http://crt.usertrust.com/AddTrustUTNSGCCA.crt
- OCSP - URI:http://ocsp.usertrust.com
-
- Signature Algorithm: sha1WithRSAEncryption
- 13:85:1f:52:80:18:c9:53:f7:fe:2e:1a:af:cc:d9:0b:3c:c2:
- d3:85:81:10:f0:28:8d:b9:40:7e:2c:9e:8f:d6:36:86:0a:4c:
- 14:2d:d6:97:43:92:41:19:37:4b:96:9e:eb:a9:30:79:12:95:
- b3:02:36:57:ed:2b:b9:1d:98:1a:a3:18:0a:3f:9b:39:8b:cd:
- a1:49:29:4c:2f:f9:d0:95:8c:c8:4d:95:ba:a8:43:cf:33:aa:
- 25:2a:5a:0e:aa:27:c9:4e:6b:b1:e6:73:1f:b3:74:04:c3:f3:
- 4c:e2:a8:eb:67:b7:5d:b8:08:05:1a:56:9a:54:29:85:f5:29:
- 4e:80:3b:95:d0:7b:53:96:11:56:c1:02:d3:ea:b2:7f:ca:8f:
- 9c:70:4a:14:8d:5a:b9:16:60:75:d6:cd:27:1e:16:cd:5b:33:
- 8e:79:40:cf:28:48:e7:dc:71:16:4e:74:91:75:b9:2a:8c:f1:
- 70:ac:26:dd:04:b9:40:c2:85:de:1c:93:40:d0:cc:6e:c3:9b:
- aa:ef:60:65:df:60:22:f0:5a:a5:7a:a2:2f:e4:70:73:ee:3c:
- d4:26:2b:68:07:c1:20:7a:e8:98:5a:3e:7b:9f:02:8b:62:c0:
- 85:81:80:60:35:7e:a5:1d:0c:d2:9c:df:62:45:0d:db:fc:37:
- fb:f5:25:22
------BEGIN CERTIFICATE-----
-MIIE/DCCA+SgAwIBAgIQFpDDKbZ4BgdRHwWwNEhGyzANBgkqhkiG9w0BAQUFADBv
-MQswCQYDVQQGEwJTRTEUMBIGA1UEChMLQWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFk
-ZFRydXN0IEV4dGVybmFsIFRUUCBOZXR3b3JrMSIwIAYDVQQDExlBZGRUcnVzdCBF
-eHRlcm5hbCBDQSBSb290MB4XDTEwMDQxNjAwMDAwMFoXDTIwMDUzMDEwNDgzOFow
-gYkxCzAJBgNVBAYTAkdCMRswGQYDVQQIExJHcmVhdGVyIE1hbmNoZXN0ZXIxEDAO
-BgNVBAcTB1NhbGZvcmQxGjAYBgNVBAoTEUNPTU9ETyBDQSBMaW1pdGVkMS8wLQYD
-VQQDEyZDT01PRE8gSGlnaC1Bc3N1cmFuY2UgU2VjdXJlIFNlcnZlciBDQTCCASIw
-DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOeH2sB35Ls6+mokyIBBrNIWExU9
-+vf4KnbcqC05CM5ISr4PffDeurtH1b0t1xurDyCBIwhyscARlQ3m6qmH/8duHk9m
-MrpTvAWqHCwM7003R2sQDNvFoJh+WNs31q7pBr3XqGXzN7nHbc53xybg13QfppgW
-uwxryL530O9YpymgubhpBTbLstpYowt1rT2LIoIgPnCGmRy5T893pAcaI2PROFaE
-7L+PxU70GJabGuiT7I2vFZwk8Fo76A+5qFoB07IcYMmcUgTdkqf+DKziRY0DYbx5
-4Hcuh0E8WF/L9cV38ljITSjQmvrzcwkkaHS8IEzYLLCq6NlObfKMJNOTXZECAwEA
-AaOCAXcwggFzMB8GA1UdIwQYMBaAFK29mHo0tCb3+sQmVO8DveAky1QaMB0GA1Ud
-DgQWBBQ/1bXQ1kR5UEoXo5uMSty4sCJkazAOBgNVHQ8BAf8EBAMCAQYwEgYDVR0T
-AQH/BAgwBgEB/wIBADARBgNVHSAECjAIMAYGBFUdIAAwRAYDVR0fBD0wOzA5oDeg
-NYYzaHR0cDovL2NybC51c2VydHJ1c3QuY29tL0FkZFRydXN0RXh0ZXJuYWxDQVJv
-b3QuY3JsMIGzBggrBgEFBQcBAQSBpjCBozA/BggrBgEFBQcwAoYzaHR0cDovL2Ny
-dC51c2VydHJ1c3QuY29tL0FkZFRydXN0RXh0ZXJuYWxDQVJvb3QucDdjMDkGCCsG
-AQUFBzAChi1odHRwOi8vY3J0LnVzZXJ0cnVzdC5jb20vQWRkVHJ1c3RVVE5TR0ND
-QS5jcnQwJQYIKwYBBQUHMAGGGWh0dHA6Ly9vY3NwLnVzZXJ0cnVzdC5jb20wDQYJ
-KoZIhvcNAQEFBQADggEBABOFH1KAGMlT9/4uGq/M2Qs8wtOFgRDwKI25QH4sno/W
-NoYKTBQt1pdDkkEZN0uWnuupMHkSlbMCNlftK7kdmBqjGAo/mzmLzaFJKUwv+dCV
-jMhNlbqoQ88zqiUqWg6qJ8lOa7Hmcx+zdATD80ziqOtnt124CAUaVppUKYX1KU6A
-O5XQe1OWEVbBAtPqsn/Kj5xwShSNWrkWYHXWzSceFs1bM455QM8oSOfccRZOdJF1
-uSqM8XCsJt0EuUDChd4ck0DQzG7Dm6rvYGXfYCLwWqV6oi/kcHPuPNQmK2gHwSB6
-6JhaPnufAotiwIWBgGA1fqUdDNKc32JFDdv8N/v1JSI=
------END CERTIFICATE-----
-#endif
-static const unsigned char kDERCert37[] = {
- 0x30, 0x82, 0x04, 0xfc, 0x30, 0x82, 0x03, 0xe4, 0xa0, 0x03, 0x02, 0x01,
- 0x02, 0x02, 0x10, 0x16, 0x90, 0xc3, 0x29, 0xb6, 0x78, 0x06, 0x07, 0x51,
- 0x1f, 0x05, 0xb0, 0x34, 0x48, 0x46, 0xcb, 0x30, 0x0d, 0x06, 0x09, 0x2a,
- 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x6f,
- 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x53,
- 0x45, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0b,
- 0x41, 0x64, 0x64, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x41, 0x42, 0x31,
- 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1d, 0x41, 0x64,
- 0x64, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x45, 0x78, 0x74, 0x65, 0x72,
- 0x6e, 0x61, 0x6c, 0x20, 0x54, 0x54, 0x50, 0x20, 0x4e, 0x65, 0x74, 0x77,
- 0x6f, 0x72, 0x6b, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x03,
- 0x13, 0x19, 0x41, 0x64, 0x64, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x45,
- 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x20, 0x43, 0x41, 0x20, 0x52,
- 0x6f, 0x6f, 0x74, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x30, 0x30, 0x34, 0x31,
- 0x36, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x30,
- 0x30, 0x35, 0x33, 0x30, 0x31, 0x30, 0x34, 0x38, 0x33, 0x38, 0x5a, 0x30,
- 0x81, 0x89, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
- 0x02, 0x47, 0x42, 0x31, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x08,
- 0x13, 0x12, 0x47, 0x72, 0x65, 0x61, 0x74, 0x65, 0x72, 0x20, 0x4d, 0x61,
- 0x6e, 0x63, 0x68, 0x65, 0x73, 0x74, 0x65, 0x72, 0x31, 0x10, 0x30, 0x0e,
- 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x07, 0x53, 0x61, 0x6c, 0x66, 0x6f,
- 0x72, 0x64, 0x31, 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13,
- 0x11, 0x43, 0x4f, 0x4d, 0x4f, 0x44, 0x4f, 0x20, 0x43, 0x41, 0x20, 0x4c,
- 0x69, 0x6d, 0x69, 0x74, 0x65, 0x64, 0x31, 0x2f, 0x30, 0x2d, 0x06, 0x03,
- 0x55, 0x04, 0x03, 0x13, 0x26, 0x43, 0x4f, 0x4d, 0x4f, 0x44, 0x4f, 0x20,
- 0x48, 0x69, 0x67, 0x68, 0x2d, 0x41, 0x73, 0x73, 0x75, 0x72, 0x61, 0x6e,
- 0x63, 0x65, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x53, 0x65,
- 0x72, 0x76, 0x65, 0x72, 0x20, 0x43, 0x41, 0x30, 0x82, 0x01, 0x22, 0x30,
- 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01,
- 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02,
- 0x82, 0x01, 0x01, 0x00, 0xe7, 0x87, 0xda, 0xc0, 0x77, 0xe4, 0xbb, 0x3a,
- 0xfa, 0x6a, 0x24, 0xc8, 0x80, 0x41, 0xac, 0xd2, 0x16, 0x13, 0x15, 0x3d,
- 0xfa, 0xf7, 0xf8, 0x2a, 0x76, 0xdc, 0xa8, 0x2d, 0x39, 0x08, 0xce, 0x48,
- 0x4a, 0xbe, 0x0f, 0x7d, 0xf0, 0xde, 0xba, 0xbb, 0x47, 0xd5, 0xbd, 0x2d,
- 0xd7, 0x1b, 0xab, 0x0f, 0x20, 0x81, 0x23, 0x08, 0x72, 0xb1, 0xc0, 0x11,
- 0x95, 0x0d, 0xe6, 0xea, 0xa9, 0x87, 0xff, 0xc7, 0x6e, 0x1e, 0x4f, 0x66,
- 0x32, 0xba, 0x53, 0xbc, 0x05, 0xaa, 0x1c, 0x2c, 0x0c, 0xef, 0x4d, 0x37,
- 0x47, 0x6b, 0x10, 0x0c, 0xdb, 0xc5, 0xa0, 0x98, 0x7e, 0x58, 0xdb, 0x37,
- 0xd6, 0xae, 0xe9, 0x06, 0xbd, 0xd7, 0xa8, 0x65, 0xf3, 0x37, 0xb9, 0xc7,
- 0x6d, 0xce, 0x77, 0xc7, 0x26, 0xe0, 0xd7, 0x74, 0x1f, 0xa6, 0x98, 0x16,
- 0xbb, 0x0c, 0x6b, 0xc8, 0xbe, 0x77, 0xd0, 0xef, 0x58, 0xa7, 0x29, 0xa0,
- 0xb9, 0xb8, 0x69, 0x05, 0x36, 0xcb, 0xb2, 0xda, 0x58, 0xa3, 0x0b, 0x75,
- 0xad, 0x3d, 0x8b, 0x22, 0x82, 0x20, 0x3e, 0x70, 0x86, 0x99, 0x1c, 0xb9,
- 0x4f, 0xcf, 0x77, 0xa4, 0x07, 0x1a, 0x23, 0x63, 0xd1, 0x38, 0x56, 0x84,
- 0xec, 0xbf, 0x8f, 0xc5, 0x4e, 0xf4, 0x18, 0x96, 0x9b, 0x1a, 0xe8, 0x93,
- 0xec, 0x8d, 0xaf, 0x15, 0x9c, 0x24, 0xf0, 0x5a, 0x3b, 0xe8, 0x0f, 0xb9,
- 0xa8, 0x5a, 0x01, 0xd3, 0xb2, 0x1c, 0x60, 0xc9, 0x9c, 0x52, 0x04, 0xdd,
- 0x92, 0xa7, 0xfe, 0x0c, 0xac, 0xe2, 0x45, 0x8d, 0x03, 0x61, 0xbc, 0x79,
- 0xe0, 0x77, 0x2e, 0x87, 0x41, 0x3c, 0x58, 0x5f, 0xcb, 0xf5, 0xc5, 0x77,
- 0xf2, 0x58, 0xc8, 0x4d, 0x28, 0xd0, 0x9a, 0xfa, 0xf3, 0x73, 0x09, 0x24,
- 0x68, 0x74, 0xbc, 0x20, 0x4c, 0xd8, 0x2c, 0xb0, 0xaa, 0xe8, 0xd9, 0x4e,
- 0x6d, 0xf2, 0x8c, 0x24, 0xd3, 0x93, 0x5d, 0x91, 0x02, 0x03, 0x01, 0x00,
- 0x01, 0xa3, 0x82, 0x01, 0x77, 0x30, 0x82, 0x01, 0x73, 0x30, 0x1f, 0x06,
- 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0xad, 0xbd,
- 0x98, 0x7a, 0x34, 0xb4, 0x26, 0xf7, 0xfa, 0xc4, 0x26, 0x54, 0xef, 0x03,
- 0xbd, 0xe0, 0x24, 0xcb, 0x54, 0x1a, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d,
- 0x0e, 0x04, 0x16, 0x04, 0x14, 0x3f, 0xd5, 0xb5, 0xd0, 0xd6, 0x44, 0x79,
- 0x50, 0x4a, 0x17, 0xa3, 0x9b, 0x8c, 0x4a, 0xdc, 0xb8, 0xb0, 0x22, 0x64,
- 0x6b, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04,
- 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13,
- 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01,
- 0x00, 0x30, 0x11, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x0a, 0x30, 0x08,
- 0x30, 0x06, 0x06, 0x04, 0x55, 0x1d, 0x20, 0x00, 0x30, 0x44, 0x06, 0x03,
- 0x55, 0x1d, 0x1f, 0x04, 0x3d, 0x30, 0x3b, 0x30, 0x39, 0xa0, 0x37, 0xa0,
- 0x35, 0x86, 0x33, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72,
- 0x6c, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e,
- 0x63, 0x6f, 0x6d, 0x2f, 0x41, 0x64, 0x64, 0x54, 0x72, 0x75, 0x73, 0x74,
- 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x43, 0x41, 0x52, 0x6f,
- 0x6f, 0x74, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x81, 0xb3, 0x06, 0x08, 0x2b,
- 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x81, 0xa6, 0x30, 0x81,
- 0xa3, 0x30, 0x3f, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30,
- 0x02, 0x86, 0x33, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72,
- 0x74, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e,
- 0x63, 0x6f, 0x6d, 0x2f, 0x41, 0x64, 0x64, 0x54, 0x72, 0x75, 0x73, 0x74,
- 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x43, 0x41, 0x52, 0x6f,
- 0x6f, 0x74, 0x2e, 0x70, 0x37, 0x63, 0x30, 0x39, 0x06, 0x08, 0x2b, 0x06,
- 0x01, 0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x2d, 0x68, 0x74, 0x74, 0x70,
- 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x74, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x74,
- 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x41, 0x64, 0x64,
- 0x54, 0x72, 0x75, 0x73, 0x74, 0x55, 0x54, 0x4e, 0x53, 0x47, 0x43, 0x43,
- 0x41, 0x2e, 0x63, 0x72, 0x74, 0x30, 0x25, 0x06, 0x08, 0x2b, 0x06, 0x01,
- 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x19, 0x68, 0x74, 0x74, 0x70, 0x3a,
- 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x74,
- 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x0d, 0x06, 0x09,
- 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03,
- 0x82, 0x01, 0x01, 0x00, 0x13, 0x85, 0x1f, 0x52, 0x80, 0x18, 0xc9, 0x53,
- 0xf7, 0xfe, 0x2e, 0x1a, 0xaf, 0xcc, 0xd9, 0x0b, 0x3c, 0xc2, 0xd3, 0x85,
- 0x81, 0x10, 0xf0, 0x28, 0x8d, 0xb9, 0x40, 0x7e, 0x2c, 0x9e, 0x8f, 0xd6,
- 0x36, 0x86, 0x0a, 0x4c, 0x14, 0x2d, 0xd6, 0x97, 0x43, 0x92, 0x41, 0x19,
- 0x37, 0x4b, 0x96, 0x9e, 0xeb, 0xa9, 0x30, 0x79, 0x12, 0x95, 0xb3, 0x02,
- 0x36, 0x57, 0xed, 0x2b, 0xb9, 0x1d, 0x98, 0x1a, 0xa3, 0x18, 0x0a, 0x3f,
- 0x9b, 0x39, 0x8b, 0xcd, 0xa1, 0x49, 0x29, 0x4c, 0x2f, 0xf9, 0xd0, 0x95,
- 0x8c, 0xc8, 0x4d, 0x95, 0xba, 0xa8, 0x43, 0xcf, 0x33, 0xaa, 0x25, 0x2a,
- 0x5a, 0x0e, 0xaa, 0x27, 0xc9, 0x4e, 0x6b, 0xb1, 0xe6, 0x73, 0x1f, 0xb3,
- 0x74, 0x04, 0xc3, 0xf3, 0x4c, 0xe2, 0xa8, 0xeb, 0x67, 0xb7, 0x5d, 0xb8,
- 0x08, 0x05, 0x1a, 0x56, 0x9a, 0x54, 0x29, 0x85, 0xf5, 0x29, 0x4e, 0x80,
- 0x3b, 0x95, 0xd0, 0x7b, 0x53, 0x96, 0x11, 0x56, 0xc1, 0x02, 0xd3, 0xea,
- 0xb2, 0x7f, 0xca, 0x8f, 0x9c, 0x70, 0x4a, 0x14, 0x8d, 0x5a, 0xb9, 0x16,
- 0x60, 0x75, 0xd6, 0xcd, 0x27, 0x1e, 0x16, 0xcd, 0x5b, 0x33, 0x8e, 0x79,
- 0x40, 0xcf, 0x28, 0x48, 0xe7, 0xdc, 0x71, 0x16, 0x4e, 0x74, 0x91, 0x75,
- 0xb9, 0x2a, 0x8c, 0xf1, 0x70, 0xac, 0x26, 0xdd, 0x04, 0xb9, 0x40, 0xc2,
- 0x85, 0xde, 0x1c, 0x93, 0x40, 0xd0, 0xcc, 0x6e, 0xc3, 0x9b, 0xaa, 0xef,
- 0x60, 0x65, 0xdf, 0x60, 0x22, 0xf0, 0x5a, 0xa5, 0x7a, 0xa2, 0x2f, 0xe4,
- 0x70, 0x73, 0xee, 0x3c, 0xd4, 0x26, 0x2b, 0x68, 0x07, 0xc1, 0x20, 0x7a,
- 0xe8, 0x98, 0x5a, 0x3e, 0x7b, 0x9f, 0x02, 0x8b, 0x62, 0xc0, 0x85, 0x81,
- 0x80, 0x60, 0x35, 0x7e, 0xa5, 0x1d, 0x0c, 0xd2, 0x9c, 0xdf, 0x62, 0x45,
- 0x0d, 0xdb, 0xfc, 0x37, 0xfb, 0xf5, 0x25, 0x22,
-};
-
-#if 0
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number: 1372799044 (0x51d34044)
- Signature Algorithm: sha256WithRSAEncryption
- Issuer: C=US, O=Entrust, Inc., OU=www.entrust.net/CPS is incorporated by reference, OU=(c) 2006 Entrust, Inc., CN=Entrust Root Certification Authority
- Validity
- Not Before: Sep 22 17:14:57 2014 GMT
- Not After : Sep 23 01:31:53 2024 GMT
- Subject: C=US, O=Entrust, Inc., OU=See www.entrust.net/legal-terms, OU=(c) 2009 Entrust, Inc. - for authorized use only, CN=Entrust Root Certification Authority - G2
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:ba:84:b6:72:db:9e:0c:6b:e2:99:e9:30:01:a7:
- 76:ea:32:b8:95:41:1a:c9:da:61:4e:58:72:cf:fe:
- f6:82:79:bf:73:61:06:0a:a5:27:d8:b3:5f:d3:45:
- 4e:1c:72:d6:4e:32:f2:72:8a:0f:f7:83:19:d0:6a:
- 80:80:00:45:1e:b0:c7:e7:9a:bf:12:57:27:1c:a3:
- 68:2f:0a:87:bd:6a:6b:0e:5e:65:f3:1c:77:d5:d4:
- 85:8d:70:21:b4:b3:32:e7:8b:a2:d5:86:39:02:b1:
- b8:d2:47:ce:e4:c9:49:c4:3b:a7:de:fb:54:7d:57:
- be:f0:e8:6e:c2:79:b2:3a:0b:55:e2:50:98:16:32:
- 13:5c:2f:78:56:c1:c2:94:b3:f2:5a:e4:27:9a:9f:
- 24:d7:c6:ec:d0:9b:25:82:e3:cc:c2:c4:45:c5:8c:
- 97:7a:06:6b:2a:11:9f:a9:0a:6e:48:3b:6f:db:d4:
- 11:19:42:f7:8f:07:bf:f5:53:5f:9c:3e:f4:17:2c:
- e6:69:ac:4e:32:4c:62:77:ea:b7:e8:e5:bb:34:bc:
- 19:8b:ae:9c:51:e7:b7:7e:b5:53:b1:33:22:e5:6d:
- cf:70:3c:1a:fa:e2:9b:67:b6:83:f4:8d:a5:af:62:
- 4c:4d:e0:58:ac:64:34:12:03:f8:b6:8d:94:63:24:
- a4:71
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Key Usage: critical
- Certificate Sign, CRL Sign
- X509v3 Basic Constraints: critical
- CA:TRUE, pathlen:1
- Authority Information Access:
- OCSP - URI:http://ocsp.entrust.net
-
- X509v3 CRL Distribution Points:
-
- Full Name:
- URI:http://crl.entrust.net/rootca1.crl
-
- X509v3 Certificate Policies:
- Policy: X509v3 Any Policy
- CPS: http://www.entrust.net/CPS
-
- X509v3 Subject Key Identifier:
- 6A:72:26:7A:D0:1E:EF:7D:E7:3B:69:51:D4:6C:8D:9F:90:12:66:AB
- X509v3 Authority Key Identifier:
- keyid:68:90:E4:67:A4:A6:53:80:C7:86:66:A4:F1:F7:4B:43:FB:84:BD:6D
-
- Signature Algorithm: sha256WithRSAEncryption
- 69:33:83:fc:28:7a:6f:7d:ef:9d:55:eb:c5:3e:7a:9d:75:b3:
- cc:c3:38:36:d9:34:a2:28:68:18:ea:1e:69:d3:bd:e7:d0:77:
- da:b8:00:83:4e:4a:cf:6f:d1:f1:c1:22:3f:74:e4:f7:98:49:
- 9e:9b:b6:9e:e1:db:98:77:2d:56:34:b1:a8:3c:d9:fd:c0:cd:
- c7:bf:05:03:d4:02:c5:f1:e5:c6:da:08:a5:13:c7:62:23:11:
- d1:61:30:1d:60:84:45:ef:79:a8:c6:26:93:a4:b7:cd:34:b8:
- 69:c5:13:f6:91:b3:c9:45:73:76:b6:92:f6:76:0a:5b:e1:03:
- 47:b7:e9:29:4c:91:32:23:37:4a:9c:35:d8:78:fd:1d:1f:e4:
- 83:89:24:80:ad:b7:f9:cf:e4:5d:a5:d4:71:c4:85:5b:70:1f:
- db:3f:1c:01:eb:1a:45:26:31:14:cc:65:bf:67:de:ca:cc:33:
- 65:e5:41:91:d7:37:be:41:1a:96:9d:e6:8a:97:9d:a7:ce:ac:
- 4e:9a:3d:bd:01:a0:6a:d9:4f:22:00:8b:44:d5:69:62:7b:2e:
- eb:cc:ba:e7:92:7d:69:67:3d:fc:b8:7c:de:41:87:d0:69:ea:
- ba:0a:18:7a:1a:95:43:b3:79:71:28:76:6d:a1:fb:57:4a:ec:
- 4d:c8:0e:10
------BEGIN CERTIFICATE-----
-MIIE/zCCA+egAwIBAgIEUdNARDANBgkqhkiG9w0BAQsFADCBsDELMAkGA1UEBhMC
-VVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xOTA3BgNVBAsTMHd3dy5lbnRydXN0
-Lm5ldC9DUFMgaXMgaW5jb3Jwb3JhdGVkIGJ5IHJlZmVyZW5jZTEfMB0GA1UECxMW
-KGMpIDIwMDYgRW50cnVzdCwgSW5jLjEtMCsGA1UEAxMkRW50cnVzdCBSb290IENl
-cnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTE0MDkyMjE3MTQ1N1oXDTI0MDkyMzAx
-MzE1M1owgb4xCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMSgw
-JgYDVQQLEx9TZWUgd3d3LmVudHJ1c3QubmV0L2xlZ2FsLXRlcm1zMTkwNwYDVQQL
-EzAoYykgMjAwOSBFbnRydXN0LCBJbmMuIC0gZm9yIGF1dGhvcml6ZWQgdXNlIG9u
-bHkxMjAwBgNVBAMTKUVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0
-eSAtIEcyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuoS2ctueDGvi
-mekwAad26jK4lUEaydphTlhyz/72gnm/c2EGCqUn2LNf00VOHHLWTjLycooP94MZ
-0GqAgABFHrDH55q/ElcnHKNoLwqHvWprDl5l8xx31dSFjXAhtLMy54ui1YY5ArG4
-0kfO5MlJxDun3vtUfVe+8OhuwnmyOgtV4lCYFjITXC94VsHClLPyWuQnmp8k18bs
-0JslguPMwsRFxYyXegZrKhGfqQpuSDtv29QRGUL3jwe/9VNfnD70FyzmaaxOMkxi
-d+q36OW7NLwZi66cUee3frVTsTMi5W3PcDwa+uKbZ7aD9I2lr2JMTeBYrGQ0EgP4
-to2UYySkcQIDAQABo4IBDzCCAQswDgYDVR0PAQH/BAQDAgEGMBIGA1UdEwEB/wQI
-MAYBAf8CAQEwMwYIKwYBBQUHAQEEJzAlMCMGCCsGAQUFBzABhhdodHRwOi8vb2Nz
-cC5lbnRydXN0Lm5ldDAzBgNVHR8ELDAqMCigJqAkhiJodHRwOi8vY3JsLmVudHJ1
-c3QubmV0L3Jvb3RjYTEuY3JsMDsGA1UdIAQ0MDIwMAYEVR0gADAoMCYGCCsGAQUF
-BwIBFhpodHRwOi8vd3d3LmVudHJ1c3QubmV0L0NQUzAdBgNVHQ4EFgQUanImetAe
-733nO2lR1GyNn5ASZqswHwYDVR0jBBgwFoAUaJDkZ6SmU4DHhmak8fdLQ/uEvW0w
-DQYJKoZIhvcNAQELBQADggEBAGkzg/woem99751V68U+ep11s8zDODbZNKIoaBjq
-HmnTvefQd9q4AINOSs9v0fHBIj905PeYSZ6btp7h25h3LVY0sag82f3Azce/BQPU
-AsXx5cbaCKUTx2IjEdFhMB1ghEXveajGJpOkt800uGnFE/aRs8lFc3a2kvZ2Clvh
-A0e36SlMkTIjN0qcNdh4/R0f5IOJJICtt/nP5F2l1HHEhVtwH9s/HAHrGkUmMRTM
-Zb9n3srMM2XlQZHXN75BGpad5oqXnafOrE6aPb0BoGrZTyIAi0TVaWJ7LuvMuueS
-fWlnPfy4fN5Bh9Bp6roKGHoalUOzeXEodm2h+1dK7E3IDhA=
------END CERTIFICATE-----
-#endif
-static const unsigned char kDERCert38[] = {
- 0x30, 0x82, 0x04, 0xff, 0x30, 0x82, 0x03, 0xe7, 0xa0, 0x03, 0x02, 0x01,
- 0x02, 0x02, 0x04, 0x51, 0xd3, 0x40, 0x44, 0x30, 0x0d, 0x06, 0x09, 0x2a,
- 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x81,
- 0xb0, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
- 0x55, 0x53, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13,
- 0x0d, 0x45, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2c, 0x20, 0x49, 0x6e,
- 0x63, 0x2e, 0x31, 0x39, 0x30, 0x37, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13,
- 0x30, 0x77, 0x77, 0x77, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74,
- 0x2e, 0x6e, 0x65, 0x74, 0x2f, 0x43, 0x50, 0x53, 0x20, 0x69, 0x73, 0x20,
- 0x69, 0x6e, 0x63, 0x6f, 0x72, 0x70, 0x6f, 0x72, 0x61, 0x74, 0x65, 0x64,
- 0x20, 0x62, 0x79, 0x20, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63,
- 0x65, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x16,
- 0x28, 0x63, 0x29, 0x20, 0x32, 0x30, 0x30, 0x36, 0x20, 0x45, 0x6e, 0x74,
- 0x72, 0x75, 0x73, 0x74, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x2d,
- 0x30, 0x2b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x24, 0x45, 0x6e, 0x74,
- 0x72, 0x75, 0x73, 0x74, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x65,
- 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20,
- 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x30, 0x1e, 0x17,
- 0x0d, 0x31, 0x34, 0x30, 0x39, 0x32, 0x32, 0x31, 0x37, 0x31, 0x34, 0x35,
- 0x37, 0x5a, 0x17, 0x0d, 0x32, 0x34, 0x30, 0x39, 0x32, 0x33, 0x30, 0x31,
- 0x33, 0x31, 0x35, 0x33, 0x5a, 0x30, 0x81, 0xbe, 0x31, 0x0b, 0x30, 0x09,
- 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x16, 0x30,
- 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0d, 0x45, 0x6e, 0x74, 0x72,
- 0x75, 0x73, 0x74, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x28, 0x30,
- 0x26, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1f, 0x53, 0x65, 0x65, 0x20,
- 0x77, 0x77, 0x77, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e,
- 0x6e, 0x65, 0x74, 0x2f, 0x6c, 0x65, 0x67, 0x61, 0x6c, 0x2d, 0x74, 0x65,
- 0x72, 0x6d, 0x73, 0x31, 0x39, 0x30, 0x37, 0x06, 0x03, 0x55, 0x04, 0x0b,
- 0x13, 0x30, 0x28, 0x63, 0x29, 0x20, 0x32, 0x30, 0x30, 0x39, 0x20, 0x45,
- 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e,
- 0x20, 0x2d, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x61, 0x75, 0x74, 0x68, 0x6f,
- 0x72, 0x69, 0x7a, 0x65, 0x64, 0x20, 0x75, 0x73, 0x65, 0x20, 0x6f, 0x6e,
- 0x6c, 0x79, 0x31, 0x32, 0x30, 0x30, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
- 0x29, 0x45, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x20, 0x52, 0x6f, 0x6f,
- 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74,
- 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74,
- 0x79, 0x20, 0x2d, 0x20, 0x47, 0x32, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d,
- 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05,
- 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82,
- 0x01, 0x01, 0x00, 0xba, 0x84, 0xb6, 0x72, 0xdb, 0x9e, 0x0c, 0x6b, 0xe2,
- 0x99, 0xe9, 0x30, 0x01, 0xa7, 0x76, 0xea, 0x32, 0xb8, 0x95, 0x41, 0x1a,
- 0xc9, 0xda, 0x61, 0x4e, 0x58, 0x72, 0xcf, 0xfe, 0xf6, 0x82, 0x79, 0xbf,
- 0x73, 0x61, 0x06, 0x0a, 0xa5, 0x27, 0xd8, 0xb3, 0x5f, 0xd3, 0x45, 0x4e,
- 0x1c, 0x72, 0xd6, 0x4e, 0x32, 0xf2, 0x72, 0x8a, 0x0f, 0xf7, 0x83, 0x19,
- 0xd0, 0x6a, 0x80, 0x80, 0x00, 0x45, 0x1e, 0xb0, 0xc7, 0xe7, 0x9a, 0xbf,
- 0x12, 0x57, 0x27, 0x1c, 0xa3, 0x68, 0x2f, 0x0a, 0x87, 0xbd, 0x6a, 0x6b,
- 0x0e, 0x5e, 0x65, 0xf3, 0x1c, 0x77, 0xd5, 0xd4, 0x85, 0x8d, 0x70, 0x21,
- 0xb4, 0xb3, 0x32, 0xe7, 0x8b, 0xa2, 0xd5, 0x86, 0x39, 0x02, 0xb1, 0xb8,
- 0xd2, 0x47, 0xce, 0xe4, 0xc9, 0x49, 0xc4, 0x3b, 0xa7, 0xde, 0xfb, 0x54,
- 0x7d, 0x57, 0xbe, 0xf0, 0xe8, 0x6e, 0xc2, 0x79, 0xb2, 0x3a, 0x0b, 0x55,
- 0xe2, 0x50, 0x98, 0x16, 0x32, 0x13, 0x5c, 0x2f, 0x78, 0x56, 0xc1, 0xc2,
- 0x94, 0xb3, 0xf2, 0x5a, 0xe4, 0x27, 0x9a, 0x9f, 0x24, 0xd7, 0xc6, 0xec,
- 0xd0, 0x9b, 0x25, 0x82, 0xe3, 0xcc, 0xc2, 0xc4, 0x45, 0xc5, 0x8c, 0x97,
- 0x7a, 0x06, 0x6b, 0x2a, 0x11, 0x9f, 0xa9, 0x0a, 0x6e, 0x48, 0x3b, 0x6f,
- 0xdb, 0xd4, 0x11, 0x19, 0x42, 0xf7, 0x8f, 0x07, 0xbf, 0xf5, 0x53, 0x5f,
- 0x9c, 0x3e, 0xf4, 0x17, 0x2c, 0xe6, 0x69, 0xac, 0x4e, 0x32, 0x4c, 0x62,
- 0x77, 0xea, 0xb7, 0xe8, 0xe5, 0xbb, 0x34, 0xbc, 0x19, 0x8b, 0xae, 0x9c,
- 0x51, 0xe7, 0xb7, 0x7e, 0xb5, 0x53, 0xb1, 0x33, 0x22, 0xe5, 0x6d, 0xcf,
- 0x70, 0x3c, 0x1a, 0xfa, 0xe2, 0x9b, 0x67, 0xb6, 0x83, 0xf4, 0x8d, 0xa5,
- 0xaf, 0x62, 0x4c, 0x4d, 0xe0, 0x58, 0xac, 0x64, 0x34, 0x12, 0x03, 0xf8,
- 0xb6, 0x8d, 0x94, 0x63, 0x24, 0xa4, 0x71, 0x02, 0x03, 0x01, 0x00, 0x01,
- 0xa3, 0x82, 0x01, 0x0f, 0x30, 0x82, 0x01, 0x0b, 0x30, 0x0e, 0x06, 0x03,
- 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06,
- 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08,
- 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01, 0x30, 0x33, 0x06, 0x08,
- 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x27, 0x30, 0x25,
- 0x30, 0x23, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01,
- 0x86, 0x17, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73,
- 0x70, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x6e, 0x65,
- 0x74, 0x30, 0x33, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x2c, 0x30, 0x2a,
- 0x30, 0x28, 0xa0, 0x26, 0xa0, 0x24, 0x86, 0x22, 0x68, 0x74, 0x74, 0x70,
- 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x75,
- 0x73, 0x74, 0x2e, 0x6e, 0x65, 0x74, 0x2f, 0x72, 0x6f, 0x6f, 0x74, 0x63,
- 0x61, 0x31, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x3b, 0x06, 0x03, 0x55, 0x1d,
- 0x20, 0x04, 0x34, 0x30, 0x32, 0x30, 0x30, 0x06, 0x04, 0x55, 0x1d, 0x20,
- 0x00, 0x30, 0x28, 0x30, 0x26, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05,
- 0x07, 0x02, 0x01, 0x16, 0x1a, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f,
- 0x77, 0x77, 0x77, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e,
- 0x6e, 0x65, 0x74, 0x2f, 0x43, 0x50, 0x53, 0x30, 0x1d, 0x06, 0x03, 0x55,
- 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x6a, 0x72, 0x26, 0x7a, 0xd0, 0x1e,
- 0xef, 0x7d, 0xe7, 0x3b, 0x69, 0x51, 0xd4, 0x6c, 0x8d, 0x9f, 0x90, 0x12,
- 0x66, 0xab, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30,
- 0x16, 0x80, 0x14, 0x68, 0x90, 0xe4, 0x67, 0xa4, 0xa6, 0x53, 0x80, 0xc7,
- 0x86, 0x66, 0xa4, 0xf1, 0xf7, 0x4b, 0x43, 0xfb, 0x84, 0xbd, 0x6d, 0x30,
- 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b,
- 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x69, 0x33, 0x83, 0xfc, 0x28,
- 0x7a, 0x6f, 0x7d, 0xef, 0x9d, 0x55, 0xeb, 0xc5, 0x3e, 0x7a, 0x9d, 0x75,
- 0xb3, 0xcc, 0xc3, 0x38, 0x36, 0xd9, 0x34, 0xa2, 0x28, 0x68, 0x18, 0xea,
- 0x1e, 0x69, 0xd3, 0xbd, 0xe7, 0xd0, 0x77, 0xda, 0xb8, 0x00, 0x83, 0x4e,
- 0x4a, 0xcf, 0x6f, 0xd1, 0xf1, 0xc1, 0x22, 0x3f, 0x74, 0xe4, 0xf7, 0x98,
- 0x49, 0x9e, 0x9b, 0xb6, 0x9e, 0xe1, 0xdb, 0x98, 0x77, 0x2d, 0x56, 0x34,
- 0xb1, 0xa8, 0x3c, 0xd9, 0xfd, 0xc0, 0xcd, 0xc7, 0xbf, 0x05, 0x03, 0xd4,
- 0x02, 0xc5, 0xf1, 0xe5, 0xc6, 0xda, 0x08, 0xa5, 0x13, 0xc7, 0x62, 0x23,
- 0x11, 0xd1, 0x61, 0x30, 0x1d, 0x60, 0x84, 0x45, 0xef, 0x79, 0xa8, 0xc6,
- 0x26, 0x93, 0xa4, 0xb7, 0xcd, 0x34, 0xb8, 0x69, 0xc5, 0x13, 0xf6, 0x91,
- 0xb3, 0xc9, 0x45, 0x73, 0x76, 0xb6, 0x92, 0xf6, 0x76, 0x0a, 0x5b, 0xe1,
- 0x03, 0x47, 0xb7, 0xe9, 0x29, 0x4c, 0x91, 0x32, 0x23, 0x37, 0x4a, 0x9c,
- 0x35, 0xd8, 0x78, 0xfd, 0x1d, 0x1f, 0xe4, 0x83, 0x89, 0x24, 0x80, 0xad,
- 0xb7, 0xf9, 0xcf, 0xe4, 0x5d, 0xa5, 0xd4, 0x71, 0xc4, 0x85, 0x5b, 0x70,
- 0x1f, 0xdb, 0x3f, 0x1c, 0x01, 0xeb, 0x1a, 0x45, 0x26, 0x31, 0x14, 0xcc,
- 0x65, 0xbf, 0x67, 0xde, 0xca, 0xcc, 0x33, 0x65, 0xe5, 0x41, 0x91, 0xd7,
- 0x37, 0xbe, 0x41, 0x1a, 0x96, 0x9d, 0xe6, 0x8a, 0x97, 0x9d, 0xa7, 0xce,
- 0xac, 0x4e, 0x9a, 0x3d, 0xbd, 0x01, 0xa0, 0x6a, 0xd9, 0x4f, 0x22, 0x00,
- 0x8b, 0x44, 0xd5, 0x69, 0x62, 0x7b, 0x2e, 0xeb, 0xcc, 0xba, 0xe7, 0x92,
- 0x7d, 0x69, 0x67, 0x3d, 0xfc, 0xb8, 0x7c, 0xde, 0x41, 0x87, 0xd0, 0x69,
- 0xea, 0xba, 0x0a, 0x18, 0x7a, 0x1a, 0x95, 0x43, 0xb3, 0x79, 0x71, 0x28,
- 0x76, 0x6d, 0xa1, 0xfb, 0x57, 0x4a, 0xec, 0x4d, 0xc8, 0x0e, 0x10,
-};
-
-#if 0
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number: 7 (0x7)
- Signature Algorithm: sha256WithRSAEncryption
- Issuer: C=US, ST=Arizona, L=Scottsdale, O=Starfield Technologies, Inc., CN=Starfield Root Certificate Authority - G2
- Validity
- Not Before: May 3 07:00:00 2011 GMT
- Not After : May 3 07:00:00 2031 GMT
- Subject: C=US, ST=Arizona, L=Scottsdale, O=Starfield Technologies, Inc., OU=http://certs.starfieldtech.com/repository/, CN=Starfield Secure Certificate Authority - G2
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:e5:90:66:4b:ec:f9:46:71:a9:20:83:be:e9:6c:
- bf:4a:c9:48:69:81:75:4e:6d:24:f6:cb:17:13:f8:
- b0:71:59:84:7a:6b:2b:85:a4:34:b5:16:e5:cb:cc:
- e9:41:70:2c:a4:2e:d6:fa:32:7d:e1:a8:de:94:10:
- ac:31:c1:c0:d8:6a:ff:59:27:ab:76:d6:fc:0b:74:
- 6b:b8:a7:ae:3f:c4:54:f4:b4:31:44:dd:93:56:8c:
- a4:4c:5e:9b:89:cb:24:83:9b:e2:57:7d:b7:d8:12:
- 1f:c9:85:6d:f4:d1:80:f1:50:9b:87:ae:d4:0b:10:
- 05:fb:27:ba:28:6d:17:e9:0e:d6:4d:b9:39:55:06:
- ff:0a:24:05:7e:2f:c6:1d:72:6c:d4:8b:29:8c:57:
- 7d:da:d9:eb:66:1a:d3:4f:a7:df:7f:52:c4:30:c5:
- a5:c9:0e:02:c5:53:bf:77:38:68:06:24:c3:66:c8:
- 37:7e:30:1e:45:71:23:35:ff:90:d8:2a:9d:8d:e7:
- b0:92:4d:3c:7f:2a:0a:93:dc:cd:16:46:65:f7:60:
- 84:8b:76:4b:91:27:73:14:92:e0:ea:ee:8f:16:ea:
- 8d:0e:3e:76:17:bf:7d:89:80:80:44:43:e7:2d:e0:
- 43:09:75:da:36:e8:ad:db:89:3a:f5:5d:12:8e:23:
- 04:83
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Basic Constraints: critical
- CA:TRUE
- X509v3 Key Usage: critical
- Certificate Sign, CRL Sign
- X509v3 Subject Key Identifier:
- 25:45:81:68:50:26:38:3D:3B:2D:2C:BE:CD:6A:D9:B6:3D:B3:66:63
- X509v3 Authority Key Identifier:
- keyid:7C:0C:32:1F:A7:D9:30:7F:C4:7D:68:A3:62:A8:A1:CE:AB:07:5B:27
-
- Authority Information Access:
- OCSP - URI:http://ocsp.starfieldtech.com/
-
- X509v3 CRL Distribution Points:
-
- Full Name:
- URI:http://crl.starfieldtech.com/sfroot-g2.crl
-
- X509v3 Certificate Policies:
- Policy: X509v3 Any Policy
- CPS: https://certs.starfieldtech.com/repository/
-
- Signature Algorithm: sha256WithRSAEncryption
- 56:65:ca:fe:f3:3f:0a:a8:93:8b:18:c7:de:43:69:13:34:20:
- be:4e:5f:78:a8:6b:9c:db:6a:4d:41:db:c1:13:ec:dc:31:00:
- 22:5e:f7:00:9e:0c:e0:34:65:34:f9:b1:3a:4e:48:c8:12:81:
- 88:5c:5b:3e:08:53:7a:f7:1a:64:df:b8:50:61:cc:53:51:40:
- 29:4b:c2:f4:ae:3a:5f:e4:ca:ad:26:cc:4e:61:43:e5:fd:57:
- a6:37:70:ce:43:2b:b0:94:c3:92:e9:e1:5f:aa:10:49:b7:69:
- e4:e0:d0:1f:64:a4:2b:cd:1f:6f:a0:f8:84:24:18:ce:79:3d:
- a9:91:bf:54:18:13:89:99:54:11:0d:55:c5:26:0b:79:4f:5a:
- 1c:6e:f9:63:db:14:80:a4:07:ab:fa:b2:a5:b9:88:dd:91:fe:
- 65:3b:a4:a3:79:be:89:4d:e1:d0:b0:f4:c8:17:0c:0a:96:14:
- 7c:09:b7:6c:e1:c2:d8:55:d4:18:a0:aa:41:69:70:24:a3:b9:
- ef:e9:5a:dc:3e:eb:94:4a:f0:b7:de:5f:0e:76:fa:fb:fb:69:
- 03:45:40:50:ee:72:0c:a4:12:86:81:cd:13:d1:4e:c4:3c:ca:
- 4e:0d:d2:26:f1:00:b7:b4:a6:a2:e1:6e:7a:81:fd:30:ac:7a:
- 1f:c7:59:7b
------BEGIN CERTIFICATE-----
-MIIFADCCA+igAwIBAgIBBzANBgkqhkiG9w0BAQsFADCBjzELMAkGA1UEBhMCVVMx
-EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT
-HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAMTKVN0YXJmaWVs
-ZCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTExMDUwMzA3MDAw
-MFoXDTMxMDUwMzA3MDAwMFowgcYxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6
-b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFyZmllbGQgVGVj
-aG5vbG9naWVzLCBJbmMuMTMwMQYDVQQLEypodHRwOi8vY2VydHMuc3RhcmZpZWxk
-dGVjaC5jb20vcmVwb3NpdG9yeS8xNDAyBgNVBAMTK1N0YXJmaWVsZCBTZWN1cmUg
-Q2VydGlmaWNhdGUgQXV0aG9yaXR5IC0gRzIwggEiMA0GCSqGSIb3DQEBAQUAA4IB
-DwAwggEKAoIBAQDlkGZL7PlGcakgg77pbL9KyUhpgXVObST2yxcT+LBxWYR6ayuF
-pDS1FuXLzOlBcCykLtb6Mn3hqN6UEKwxwcDYav9ZJ6t21vwLdGu4p64/xFT0tDFE
-3ZNWjKRMXpuJyySDm+JXfbfYEh/JhW300YDxUJuHrtQLEAX7J7oobRfpDtZNuTlV
-Bv8KJAV+L8YdcmzUiymMV33a2etmGtNPp99/UsQwxaXJDgLFU793OGgGJMNmyDd+
-MB5FcSM1/5DYKp2N57CSTTx/KgqT3M0WRmX3YISLdkuRJ3MUkuDq7o8W6o0OPnYX
-v32JgIBEQ+ct4EMJddo26K3biTr1XRKOIwSDAgMBAAGjggEsMIIBKDAPBgNVHRMB
-Af8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUJUWBaFAmOD07LSy+
-zWrZtj2zZmMwHwYDVR0jBBgwFoAUfAwyH6fZMH/EfWijYqihzqsHWycwOgYIKwYB
-BQUHAQEELjAsMCoGCCsGAQUFBzABhh5odHRwOi8vb2NzcC5zdGFyZmllbGR0ZWNo
-LmNvbS8wOwYDVR0fBDQwMjAwoC6gLIYqaHR0cDovL2NybC5zdGFyZmllbGR0ZWNo
-LmNvbS9zZnJvb3QtZzIuY3JsMEwGA1UdIARFMEMwQQYEVR0gADA5MDcGCCsGAQUF
-BwIBFitodHRwczovL2NlcnRzLnN0YXJmaWVsZHRlY2guY29tL3JlcG9zaXRvcnkv
-MA0GCSqGSIb3DQEBCwUAA4IBAQBWZcr+8z8KqJOLGMfeQ2kTNCC+Tl94qGuc22pN
-QdvBE+zcMQAiXvcAngzgNGU0+bE6TkjIEoGIXFs+CFN69xpk37hQYcxTUUApS8L0
-rjpf5MqtJsxOYUPl/VemN3DOQyuwlMOS6eFfqhBJt2nk4NAfZKQrzR9voPiEJBjO
-eT2pkb9UGBOJmVQRDVXFJgt5T1ocbvlj2xSApAer+rKluYjdkf5lO6Sjeb6JTeHQ
-sPTIFwwKlhR8Cbds4cLYVdQYoKpBaXAko7nv6VrcPuuUSvC33l8Odvr7+2kDRUBQ
-7nIMpBKGgc0T0U7EPMpODdIm8QC3tKai4W56gf0wrHofx1l7
------END CERTIFICATE-----
-#endif
-static const unsigned char kDERCert39[] = {
- 0x30, 0x82, 0x05, 0x00, 0x30, 0x82, 0x03, 0xe8, 0xa0, 0x03, 0x02, 0x01,
- 0x02, 0x02, 0x01, 0x07, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
- 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x81, 0x8f, 0x31, 0x0b,
- 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31,
- 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x07, 0x41, 0x72,
- 0x69, 0x7a, 0x6f, 0x6e, 0x61, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55,
- 0x04, 0x07, 0x13, 0x0a, 0x53, 0x63, 0x6f, 0x74, 0x74, 0x73, 0x64, 0x61,
- 0x6c, 0x65, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13,
- 0x1c, 0x53, 0x74, 0x61, 0x72, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x20, 0x54,
- 0x65, 0x63, 0x68, 0x6e, 0x6f, 0x6c, 0x6f, 0x67, 0x69, 0x65, 0x73, 0x2c,
- 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x32, 0x30, 0x30, 0x06, 0x03, 0x55,
- 0x04, 0x03, 0x13, 0x29, 0x53, 0x74, 0x61, 0x72, 0x66, 0x69, 0x65, 0x6c,
- 0x64, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69,
- 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f,
- 0x72, 0x69, 0x74, 0x79, 0x20, 0x2d, 0x20, 0x47, 0x32, 0x30, 0x1e, 0x17,
- 0x0d, 0x31, 0x31, 0x30, 0x35, 0x30, 0x33, 0x30, 0x37, 0x30, 0x30, 0x30,
- 0x30, 0x5a, 0x17, 0x0d, 0x33, 0x31, 0x30, 0x35, 0x30, 0x33, 0x30, 0x37,
- 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x81, 0xc6, 0x31, 0x0b, 0x30, 0x09,
- 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x10, 0x30,
- 0x0e, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x07, 0x41, 0x72, 0x69, 0x7a,
- 0x6f, 0x6e, 0x61, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x07,
- 0x13, 0x0a, 0x53, 0x63, 0x6f, 0x74, 0x74, 0x73, 0x64, 0x61, 0x6c, 0x65,
- 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x1c, 0x53,
- 0x74, 0x61, 0x72, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x20, 0x54, 0x65, 0x63,
- 0x68, 0x6e, 0x6f, 0x6c, 0x6f, 0x67, 0x69, 0x65, 0x73, 0x2c, 0x20, 0x49,
- 0x6e, 0x63, 0x2e, 0x31, 0x33, 0x30, 0x31, 0x06, 0x03, 0x55, 0x04, 0x0b,
- 0x13, 0x2a, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x65, 0x72,
- 0x74, 0x73, 0x2e, 0x73, 0x74, 0x61, 0x72, 0x66, 0x69, 0x65, 0x6c, 0x64,
- 0x74, 0x65, 0x63, 0x68, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x70,
- 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x2f, 0x31, 0x34, 0x30, 0x32,
- 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x2b, 0x53, 0x74, 0x61, 0x72, 0x66,
- 0x69, 0x65, 0x6c, 0x64, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20,
- 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20,
- 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x20, 0x2d, 0x20,
- 0x47, 0x32, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
- 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01,
- 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xe5,
- 0x90, 0x66, 0x4b, 0xec, 0xf9, 0x46, 0x71, 0xa9, 0x20, 0x83, 0xbe, 0xe9,
- 0x6c, 0xbf, 0x4a, 0xc9, 0x48, 0x69, 0x81, 0x75, 0x4e, 0x6d, 0x24, 0xf6,
- 0xcb, 0x17, 0x13, 0xf8, 0xb0, 0x71, 0x59, 0x84, 0x7a, 0x6b, 0x2b, 0x85,
- 0xa4, 0x34, 0xb5, 0x16, 0xe5, 0xcb, 0xcc, 0xe9, 0x41, 0x70, 0x2c, 0xa4,
- 0x2e, 0xd6, 0xfa, 0x32, 0x7d, 0xe1, 0xa8, 0xde, 0x94, 0x10, 0xac, 0x31,
- 0xc1, 0xc0, 0xd8, 0x6a, 0xff, 0x59, 0x27, 0xab, 0x76, 0xd6, 0xfc, 0x0b,
- 0x74, 0x6b, 0xb8, 0xa7, 0xae, 0x3f, 0xc4, 0x54, 0xf4, 0xb4, 0x31, 0x44,
- 0xdd, 0x93, 0x56, 0x8c, 0xa4, 0x4c, 0x5e, 0x9b, 0x89, 0xcb, 0x24, 0x83,
- 0x9b, 0xe2, 0x57, 0x7d, 0xb7, 0xd8, 0x12, 0x1f, 0xc9, 0x85, 0x6d, 0xf4,
- 0xd1, 0x80, 0xf1, 0x50, 0x9b, 0x87, 0xae, 0xd4, 0x0b, 0x10, 0x05, 0xfb,
- 0x27, 0xba, 0x28, 0x6d, 0x17, 0xe9, 0x0e, 0xd6, 0x4d, 0xb9, 0x39, 0x55,
- 0x06, 0xff, 0x0a, 0x24, 0x05, 0x7e, 0x2f, 0xc6, 0x1d, 0x72, 0x6c, 0xd4,
- 0x8b, 0x29, 0x8c, 0x57, 0x7d, 0xda, 0xd9, 0xeb, 0x66, 0x1a, 0xd3, 0x4f,
- 0xa7, 0xdf, 0x7f, 0x52, 0xc4, 0x30, 0xc5, 0xa5, 0xc9, 0x0e, 0x02, 0xc5,
- 0x53, 0xbf, 0x77, 0x38, 0x68, 0x06, 0x24, 0xc3, 0x66, 0xc8, 0x37, 0x7e,
- 0x30, 0x1e, 0x45, 0x71, 0x23, 0x35, 0xff, 0x90, 0xd8, 0x2a, 0x9d, 0x8d,
- 0xe7, 0xb0, 0x92, 0x4d, 0x3c, 0x7f, 0x2a, 0x0a, 0x93, 0xdc, 0xcd, 0x16,
- 0x46, 0x65, 0xf7, 0x60, 0x84, 0x8b, 0x76, 0x4b, 0x91, 0x27, 0x73, 0x14,
- 0x92, 0xe0, 0xea, 0xee, 0x8f, 0x16, 0xea, 0x8d, 0x0e, 0x3e, 0x76, 0x17,
- 0xbf, 0x7d, 0x89, 0x80, 0x80, 0x44, 0x43, 0xe7, 0x2d, 0xe0, 0x43, 0x09,
- 0x75, 0xda, 0x36, 0xe8, 0xad, 0xdb, 0x89, 0x3a, 0xf5, 0x5d, 0x12, 0x8e,
- 0x23, 0x04, 0x83, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x2c,
- 0x30, 0x82, 0x01, 0x28, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01,
- 0x01, 0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0e, 0x06,
- 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01,
- 0x06, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14,
- 0x25, 0x45, 0x81, 0x68, 0x50, 0x26, 0x38, 0x3d, 0x3b, 0x2d, 0x2c, 0xbe,
- 0xcd, 0x6a, 0xd9, 0xb6, 0x3d, 0xb3, 0x66, 0x63, 0x30, 0x1f, 0x06, 0x03,
- 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x7c, 0x0c, 0x32,
- 0x1f, 0xa7, 0xd9, 0x30, 0x7f, 0xc4, 0x7d, 0x68, 0xa3, 0x62, 0xa8, 0xa1,
- 0xce, 0xab, 0x07, 0x5b, 0x27, 0x30, 0x3a, 0x06, 0x08, 0x2b, 0x06, 0x01,
- 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x2e, 0x30, 0x2c, 0x30, 0x2a, 0x06,
- 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x1e, 0x68,
- 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x73,
- 0x74, 0x61, 0x72, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x74, 0x65, 0x63, 0x68,
- 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x30, 0x3b, 0x06, 0x03, 0x55, 0x1d, 0x1f,
- 0x04, 0x34, 0x30, 0x32, 0x30, 0x30, 0xa0, 0x2e, 0xa0, 0x2c, 0x86, 0x2a,
- 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x73,
- 0x74, 0x61, 0x72, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x74, 0x65, 0x63, 0x68,
- 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x73, 0x66, 0x72, 0x6f, 0x6f, 0x74, 0x2d,
- 0x67, 0x32, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x4c, 0x06, 0x03, 0x55, 0x1d,
- 0x20, 0x04, 0x45, 0x30, 0x43, 0x30, 0x41, 0x06, 0x04, 0x55, 0x1d, 0x20,
- 0x00, 0x30, 0x39, 0x30, 0x37, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05,
- 0x07, 0x02, 0x01, 0x16, 0x2b, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f,
- 0x2f, 0x63, 0x65, 0x72, 0x74, 0x73, 0x2e, 0x73, 0x74, 0x61, 0x72, 0x66,
- 0x69, 0x65, 0x6c, 0x64, 0x74, 0x65, 0x63, 0x68, 0x2e, 0x63, 0x6f, 0x6d,
- 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x2f,
- 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
- 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x56, 0x65, 0xca, 0xfe,
- 0xf3, 0x3f, 0x0a, 0xa8, 0x93, 0x8b, 0x18, 0xc7, 0xde, 0x43, 0x69, 0x13,
- 0x34, 0x20, 0xbe, 0x4e, 0x5f, 0x78, 0xa8, 0x6b, 0x9c, 0xdb, 0x6a, 0x4d,
- 0x41, 0xdb, 0xc1, 0x13, 0xec, 0xdc, 0x31, 0x00, 0x22, 0x5e, 0xf7, 0x00,
- 0x9e, 0x0c, 0xe0, 0x34, 0x65, 0x34, 0xf9, 0xb1, 0x3a, 0x4e, 0x48, 0xc8,
- 0x12, 0x81, 0x88, 0x5c, 0x5b, 0x3e, 0x08, 0x53, 0x7a, 0xf7, 0x1a, 0x64,
- 0xdf, 0xb8, 0x50, 0x61, 0xcc, 0x53, 0x51, 0x40, 0x29, 0x4b, 0xc2, 0xf4,
- 0xae, 0x3a, 0x5f, 0xe4, 0xca, 0xad, 0x26, 0xcc, 0x4e, 0x61, 0x43, 0xe5,
- 0xfd, 0x57, 0xa6, 0x37, 0x70, 0xce, 0x43, 0x2b, 0xb0, 0x94, 0xc3, 0x92,
- 0xe9, 0xe1, 0x5f, 0xaa, 0x10, 0x49, 0xb7, 0x69, 0xe4, 0xe0, 0xd0, 0x1f,
- 0x64, 0xa4, 0x2b, 0xcd, 0x1f, 0x6f, 0xa0, 0xf8, 0x84, 0x24, 0x18, 0xce,
- 0x79, 0x3d, 0xa9, 0x91, 0xbf, 0x54, 0x18, 0x13, 0x89, 0x99, 0x54, 0x11,
- 0x0d, 0x55, 0xc5, 0x26, 0x0b, 0x79, 0x4f, 0x5a, 0x1c, 0x6e, 0xf9, 0x63,
- 0xdb, 0x14, 0x80, 0xa4, 0x07, 0xab, 0xfa, 0xb2, 0xa5, 0xb9, 0x88, 0xdd,
- 0x91, 0xfe, 0x65, 0x3b, 0xa4, 0xa3, 0x79, 0xbe, 0x89, 0x4d, 0xe1, 0xd0,
- 0xb0, 0xf4, 0xc8, 0x17, 0x0c, 0x0a, 0x96, 0x14, 0x7c, 0x09, 0xb7, 0x6c,
- 0xe1, 0xc2, 0xd8, 0x55, 0xd4, 0x18, 0xa0, 0xaa, 0x41, 0x69, 0x70, 0x24,
- 0xa3, 0xb9, 0xef, 0xe9, 0x5a, 0xdc, 0x3e, 0xeb, 0x94, 0x4a, 0xf0, 0xb7,
- 0xde, 0x5f, 0x0e, 0x76, 0xfa, 0xfb, 0xfb, 0x69, 0x03, 0x45, 0x40, 0x50,
- 0xee, 0x72, 0x0c, 0xa4, 0x12, 0x86, 0x81, 0xcd, 0x13, 0xd1, 0x4e, 0xc4,
- 0x3c, 0xca, 0x4e, 0x0d, 0xd2, 0x26, 0xf1, 0x00, 0xb7, 0xb4, 0xa6, 0xa2,
- 0xe1, 0x6e, 0x7a, 0x81, 0xfd, 0x30, 0xac, 0x7a, 0x1f, 0xc7, 0x59, 0x7b,
-};
-
-#if 0
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number: 1372807406 (0x51d360ee)
- Signature Algorithm: sha256WithRSAEncryption
- Issuer: C=US, O=Entrust, Inc., OU=See www.entrust.net/legal-terms, OU=(c) 2009 Entrust, Inc. - for authorized use only, CN=Entrust Root Certification Authority - G2
- Validity
- Not Before: Oct 22 17:05:14 2014 GMT
- Not After : Oct 23 07:33:22 2024 GMT
- Subject: C=US, O=Entrust, Inc., OU=See www.entrust.net/legal-terms, OU=(c) 2012 Entrust, Inc. - for authorized use only, CN=Entrust Certification Authority - L1K
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:da:3f:96:d0:4d:b9:2f:44:e7:db:39:5e:9b:50:
- ee:5c:a5:61:da:41:67:53:09:aa:00:9a:8e:57:7f:
- 29:6b:db:c7:e1:21:24:aa:3a:d0:8d:47:23:d2:ed:
- 72:16:f0:91:21:d2:5d:b7:b8:4b:a8:83:8f:b7:91:
- 32:68:cf:ce:25:93:2c:b2:7d:97:c8:fe:c1:b4:17:
- ba:09:9e:03:90:93:7b:7c:49:83:22:68:8a:9b:de:
- 47:c3:31:98:7a:2e:7d:40:0b:d2:ef:3e:d3:b2:8c:
- aa:8f:48:a9:ff:00:e8:29:58:06:f7:b6:93:5a:94:
- 73:26:26:ad:58:0e:e5:42:b8:d5:ea:73:79:64:68:
- 53:25:b8:84:cf:94:7a:ae:06:45:0c:a3:6b:4d:d0:
- c6:be:ea:18:a4:36:f0:92:b2:ba:1c:88:8f:3a:52:
- 7f:f7:5e:6d:83:1c:9d:f0:1f:e5:c3:d6:dd:a5:78:
- 92:3d:b0:6d:2c:ea:c9:cf:94:41:19:71:44:68:ba:
- 47:3c:04:e9:5d:ba:3e:f0:35:f7:15:b6:9e:f2:2e:
- 15:1e:3f:47:c8:c8:38:a7:73:45:5d:4d:b0:3b:b1:
- 8e:17:29:37:ea:dd:05:01:22:bb:94:36:2a:8d:5b:
- 35:fe:53:19:2f:08:46:c1:2a:b3:1a:62:1d:4e:2b:
- d9:1b
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Key Usage: critical
- Certificate Sign, CRL Sign
- X509v3 Basic Constraints:
- CA:TRUE, pathlen:0
- Authority Information Access:
- OCSP - URI:http://ocsp.entrust.net
-
- X509v3 CRL Distribution Points:
-
- Full Name:
- URI:http://crl.entrust.net/g2ca.crl
-
- X509v3 Certificate Policies:
- Policy: X509v3 Any Policy
- CPS: http://www.entrust.net/rpa
-
- X509v3 Subject Key Identifier:
- 82:A2:70:74:DD:BC:53:3F:CF:7B:D4:F7:CD:7F:A7:60:C6:0A:4C:BF
- X509v3 Authority Key Identifier:
- keyid:6A:72:26:7A:D0:1E:EF:7D:E7:3B:69:51:D4:6C:8D:9F:90:12:66:AB
-
- Signature Algorithm: sha256WithRSAEncryption
- 3f:1c:1a:5b:ff:40:22:1d:8f:35:0c:2d:aa:99:27:ab:c0:11:
- 32:70:d7:36:28:69:a5:8d:b1:27:99:42:be:c4:93:eb:48:57:
- 43:71:23:c4:e5:4e:ad:ae:43:6f:92:76:c5:19:ef:ca:bc:6f:
- 42:4c:16:9a:86:a9:04:38:c7:65:f0:f5:0c:e0:4a:df:a2:fa:
- ce:1a:11:a8:9c:69:2f:1b:df:ea:e2:32:f3:ce:4c:bc:46:0c:
- c0:89:80:d1:87:6b:a2:cf:6b:d4:7f:fd:f5:60:52:67:57:a0:
- 6d:d1:64:41:14:6d:34:62:ed:06:6c:24:f2:06:bc:28:02:af:
- 03:2d:c2:33:05:fb:cb:aa:16:e8:65:10:43:f5:69:5c:e3:81:
- 58:99:cd:6b:d3:b8:c7:7b:19:55:c9:40:ce:79:55:b8:73:89:
- e9:5c:40:66:43:12:7f:07:b8:65:56:d5:8d:c3:a7:f5:b1:b6:
- 65:9e:c0:83:36:7f:16:45:3c:74:4b:93:8a:3c:f1:2b:f5:35:
- 70:73:7b:e7:82:04:b1:18:98:0e:d4:9c:6f:1a:fc:fc:a7:33:
- a5:bb:bb:18:f3:6b:7a:5d:32:87:f7:6d:25:e4:e2:76:86:21:
- 1e:11:46:cd:76:0e:6f:4f:a4:21:71:0a:84:a7:2d:36:a9:48:
- 22:51:7e:82
------BEGIN CERTIFICATE-----
-MIIFAzCCA+ugAwIBAgIEUdNg7jANBgkqhkiG9w0BAQsFADCBvjELMAkGA1UEBhMC
-VVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50
-cnVzdC5uZXQvbGVnYWwtdGVybXMxOTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3Qs
-IEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ugb25seTEyMDAGA1UEAxMpRW50cnVz
-dCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzIwHhcNMTQxMDIyMTcw
-NTE0WhcNMjQxMDIzMDczMzIyWjCBujELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUVu
-dHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50cnVzdC5uZXQvbGVnYWwt
-dGVybXMxOTA3BgNVBAsTMChjKSAyMDEyIEVudHJ1c3QsIEluYy4gLSBmb3IgYXV0
-aG9yaXplZCB1c2Ugb25seTEuMCwGA1UEAxMlRW50cnVzdCBDZXJ0aWZpY2F0aW9u
-IEF1dGhvcml0eSAtIEwxSzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
-ANo/ltBNuS9E59s5XptQ7lylYdpBZ1MJqgCajld/KWvbx+EhJKo60I1HI9Ltchbw
-kSHSXbe4S6iDj7eRMmjPziWTLLJ9l8j+wbQXugmeA5CTe3xJgyJoipveR8MxmHou
-fUAL0u8+07KMqo9Iqf8A6ClYBve2k1qUcyYmrVgO5UK41epzeWRoUyW4hM+Ueq4G
-RQyja03Qxr7qGKQ28JKyuhyIjzpSf/debYMcnfAf5cPW3aV4kj2wbSzqyc+UQRlx
-RGi6RzwE6V26PvA19xW2nvIuFR4/R8jIOKdzRV1NsDuxjhcpN+rdBQEiu5Q2Ko1b
-Nf5TGS8IRsEqsxpiHU4r2RsCAwEAAaOCAQkwggEFMA4GA1UdDwEB/wQEAwIBBjAP
-BgNVHRMECDAGAQH/AgEAMDMGCCsGAQUFBwEBBCcwJTAjBggrBgEFBQcwAYYXaHR0
-cDovL29jc3AuZW50cnVzdC5uZXQwMAYDVR0fBCkwJzAloCOgIYYfaHR0cDovL2Ny
-bC5lbnRydXN0Lm5ldC9nMmNhLmNybDA7BgNVHSAENDAyMDAGBFUdIAAwKDAmBggr
-BgEFBQcCARYaaHR0cDovL3d3dy5lbnRydXN0Lm5ldC9ycGEwHQYDVR0OBBYEFIKi
-cHTdvFM/z3vU981/p2DGCky/MB8GA1UdIwQYMBaAFGpyJnrQHu995ztpUdRsjZ+Q
-EmarMA0GCSqGSIb3DQEBCwUAA4IBAQA/HBpb/0AiHY81DC2qmSerwBEycNc2KGml
-jbEnmUK+xJPrSFdDcSPE5U6trkNvknbFGe/KvG9CTBaahqkEOMdl8PUM4ErfovrO
-GhGonGkvG9/q4jLzzky8RgzAiYDRh2uiz2vUf/31YFJnV6Bt0WRBFG00Yu0GbCTy
-BrwoAq8DLcIzBfvLqhboZRBD9Wlc44FYmc1r07jHexlVyUDOeVW4c4npXEBmQxJ/
-B7hlVtWNw6f1sbZlnsCDNn8WRTx0S5OKPPEr9TVwc3vnggSxGJgO1JxvGvz8pzOl
-u7sY82t6XTKH920l5OJ2hiEeEUbNdg5vT6QhcQqEpy02qUgiUX6C
------END CERTIFICATE-----
-#endif
-static const unsigned char kDERCert40[] = {
- 0x30, 0x82, 0x05, 0x03, 0x30, 0x82, 0x03, 0xeb, 0xa0, 0x03, 0x02, 0x01,
- 0x02, 0x02, 0x04, 0x51, 0xd3, 0x60, 0xee, 0x30, 0x0d, 0x06, 0x09, 0x2a,
- 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x81,
- 0xbe, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
- 0x55, 0x53, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13,
- 0x0d, 0x45, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2c, 0x20, 0x49, 0x6e,
- 0x63, 0x2e, 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13,
- 0x1f, 0x53, 0x65, 0x65, 0x20, 0x77, 0x77, 0x77, 0x2e, 0x65, 0x6e, 0x74,
- 0x72, 0x75, 0x73, 0x74, 0x2e, 0x6e, 0x65, 0x74, 0x2f, 0x6c, 0x65, 0x67,
- 0x61, 0x6c, 0x2d, 0x74, 0x65, 0x72, 0x6d, 0x73, 0x31, 0x39, 0x30, 0x37,
- 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x30, 0x28, 0x63, 0x29, 0x20, 0x32,
- 0x30, 0x30, 0x39, 0x20, 0x45, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2c,
- 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x20, 0x2d, 0x20, 0x66, 0x6f, 0x72, 0x20,
- 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x20, 0x75,
- 0x73, 0x65, 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x31, 0x32, 0x30, 0x30, 0x06,
- 0x03, 0x55, 0x04, 0x03, 0x13, 0x29, 0x45, 0x6e, 0x74, 0x72, 0x75, 0x73,
- 0x74, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69,
- 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74,
- 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x20, 0x2d, 0x20, 0x47, 0x32, 0x30,
- 0x1e, 0x17, 0x0d, 0x31, 0x34, 0x31, 0x30, 0x32, 0x32, 0x31, 0x37, 0x30,
- 0x35, 0x31, 0x34, 0x5a, 0x17, 0x0d, 0x32, 0x34, 0x31, 0x30, 0x32, 0x33,
- 0x30, 0x37, 0x33, 0x33, 0x32, 0x32, 0x5a, 0x30, 0x81, 0xba, 0x31, 0x0b,
- 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31,
- 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0d, 0x45, 0x6e,
- 0x74, 0x72, 0x75, 0x73, 0x74, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31,
- 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1f, 0x53, 0x65,
- 0x65, 0x20, 0x77, 0x77, 0x77, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x75, 0x73,
- 0x74, 0x2e, 0x6e, 0x65, 0x74, 0x2f, 0x6c, 0x65, 0x67, 0x61, 0x6c, 0x2d,
- 0x74, 0x65, 0x72, 0x6d, 0x73, 0x31, 0x39, 0x30, 0x37, 0x06, 0x03, 0x55,
- 0x04, 0x0b, 0x13, 0x30, 0x28, 0x63, 0x29, 0x20, 0x32, 0x30, 0x31, 0x32,
- 0x20, 0x45, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2c, 0x20, 0x49, 0x6e,
- 0x63, 0x2e, 0x20, 0x2d, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x61, 0x75, 0x74,
- 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x20, 0x75, 0x73, 0x65, 0x20,
- 0x6f, 0x6e, 0x6c, 0x79, 0x31, 0x2e, 0x30, 0x2c, 0x06, 0x03, 0x55, 0x04,
- 0x03, 0x13, 0x25, 0x45, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x20, 0x43,
- 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e,
- 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x20, 0x2d,
- 0x20, 0x4c, 0x31, 0x4b, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09,
- 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03,
- 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01,
- 0x00, 0xda, 0x3f, 0x96, 0xd0, 0x4d, 0xb9, 0x2f, 0x44, 0xe7, 0xdb, 0x39,
- 0x5e, 0x9b, 0x50, 0xee, 0x5c, 0xa5, 0x61, 0xda, 0x41, 0x67, 0x53, 0x09,
- 0xaa, 0x00, 0x9a, 0x8e, 0x57, 0x7f, 0x29, 0x6b, 0xdb, 0xc7, 0xe1, 0x21,
- 0x24, 0xaa, 0x3a, 0xd0, 0x8d, 0x47, 0x23, 0xd2, 0xed, 0x72, 0x16, 0xf0,
- 0x91, 0x21, 0xd2, 0x5d, 0xb7, 0xb8, 0x4b, 0xa8, 0x83, 0x8f, 0xb7, 0x91,
- 0x32, 0x68, 0xcf, 0xce, 0x25, 0x93, 0x2c, 0xb2, 0x7d, 0x97, 0xc8, 0xfe,
- 0xc1, 0xb4, 0x17, 0xba, 0x09, 0x9e, 0x03, 0x90, 0x93, 0x7b, 0x7c, 0x49,
- 0x83, 0x22, 0x68, 0x8a, 0x9b, 0xde, 0x47, 0xc3, 0x31, 0x98, 0x7a, 0x2e,
- 0x7d, 0x40, 0x0b, 0xd2, 0xef, 0x3e, 0xd3, 0xb2, 0x8c, 0xaa, 0x8f, 0x48,
- 0xa9, 0xff, 0x00, 0xe8, 0x29, 0x58, 0x06, 0xf7, 0xb6, 0x93, 0x5a, 0x94,
- 0x73, 0x26, 0x26, 0xad, 0x58, 0x0e, 0xe5, 0x42, 0xb8, 0xd5, 0xea, 0x73,
- 0x79, 0x64, 0x68, 0x53, 0x25, 0xb8, 0x84, 0xcf, 0x94, 0x7a, 0xae, 0x06,
- 0x45, 0x0c, 0xa3, 0x6b, 0x4d, 0xd0, 0xc6, 0xbe, 0xea, 0x18, 0xa4, 0x36,
- 0xf0, 0x92, 0xb2, 0xba, 0x1c, 0x88, 0x8f, 0x3a, 0x52, 0x7f, 0xf7, 0x5e,
- 0x6d, 0x83, 0x1c, 0x9d, 0xf0, 0x1f, 0xe5, 0xc3, 0xd6, 0xdd, 0xa5, 0x78,
- 0x92, 0x3d, 0xb0, 0x6d, 0x2c, 0xea, 0xc9, 0xcf, 0x94, 0x41, 0x19, 0x71,
- 0x44, 0x68, 0xba, 0x47, 0x3c, 0x04, 0xe9, 0x5d, 0xba, 0x3e, 0xf0, 0x35,
- 0xf7, 0x15, 0xb6, 0x9e, 0xf2, 0x2e, 0x15, 0x1e, 0x3f, 0x47, 0xc8, 0xc8,
- 0x38, 0xa7, 0x73, 0x45, 0x5d, 0x4d, 0xb0, 0x3b, 0xb1, 0x8e, 0x17, 0x29,
- 0x37, 0xea, 0xdd, 0x05, 0x01, 0x22, 0xbb, 0x94, 0x36, 0x2a, 0x8d, 0x5b,
- 0x35, 0xfe, 0x53, 0x19, 0x2f, 0x08, 0x46, 0xc1, 0x2a, 0xb3, 0x1a, 0x62,
- 0x1d, 0x4e, 0x2b, 0xd9, 0x1b, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82,
- 0x01, 0x09, 0x30, 0x82, 0x01, 0x05, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d,
- 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x0f,
- 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff,
- 0x02, 0x01, 0x00, 0x30, 0x33, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05,
- 0x07, 0x01, 0x01, 0x04, 0x27, 0x30, 0x25, 0x30, 0x23, 0x06, 0x08, 0x2b,
- 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x17, 0x68, 0x74, 0x74,
- 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x65, 0x6e, 0x74,
- 0x72, 0x75, 0x73, 0x74, 0x2e, 0x6e, 0x65, 0x74, 0x30, 0x30, 0x06, 0x03,
- 0x55, 0x1d, 0x1f, 0x04, 0x29, 0x30, 0x27, 0x30, 0x25, 0xa0, 0x23, 0xa0,
- 0x21, 0x86, 0x1f, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72,
- 0x6c, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x6e, 0x65,
- 0x74, 0x2f, 0x67, 0x32, 0x63, 0x61, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x3b,
- 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x34, 0x30, 0x32, 0x30, 0x30, 0x06,
- 0x04, 0x55, 0x1d, 0x20, 0x00, 0x30, 0x28, 0x30, 0x26, 0x06, 0x08, 0x2b,
- 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x1a, 0x68, 0x74, 0x74,
- 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x65, 0x6e, 0x74, 0x72,
- 0x75, 0x73, 0x74, 0x2e, 0x6e, 0x65, 0x74, 0x2f, 0x72, 0x70, 0x61, 0x30,
- 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x82, 0xa2,
- 0x70, 0x74, 0xdd, 0xbc, 0x53, 0x3f, 0xcf, 0x7b, 0xd4, 0xf7, 0xcd, 0x7f,
- 0xa7, 0x60, 0xc6, 0x0a, 0x4c, 0xbf, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d,
- 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x6a, 0x72, 0x26, 0x7a, 0xd0,
- 0x1e, 0xef, 0x7d, 0xe7, 0x3b, 0x69, 0x51, 0xd4, 0x6c, 0x8d, 0x9f, 0x90,
- 0x12, 0x66, 0xab, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
- 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x3f,
- 0x1c, 0x1a, 0x5b, 0xff, 0x40, 0x22, 0x1d, 0x8f, 0x35, 0x0c, 0x2d, 0xaa,
- 0x99, 0x27, 0xab, 0xc0, 0x11, 0x32, 0x70, 0xd7, 0x36, 0x28, 0x69, 0xa5,
- 0x8d, 0xb1, 0x27, 0x99, 0x42, 0xbe, 0xc4, 0x93, 0xeb, 0x48, 0x57, 0x43,
- 0x71, 0x23, 0xc4, 0xe5, 0x4e, 0xad, 0xae, 0x43, 0x6f, 0x92, 0x76, 0xc5,
- 0x19, 0xef, 0xca, 0xbc, 0x6f, 0x42, 0x4c, 0x16, 0x9a, 0x86, 0xa9, 0x04,
- 0x38, 0xc7, 0x65, 0xf0, 0xf5, 0x0c, 0xe0, 0x4a, 0xdf, 0xa2, 0xfa, 0xce,
- 0x1a, 0x11, 0xa8, 0x9c, 0x69, 0x2f, 0x1b, 0xdf, 0xea, 0xe2, 0x32, 0xf3,
- 0xce, 0x4c, 0xbc, 0x46, 0x0c, 0xc0, 0x89, 0x80, 0xd1, 0x87, 0x6b, 0xa2,
- 0xcf, 0x6b, 0xd4, 0x7f, 0xfd, 0xf5, 0x60, 0x52, 0x67, 0x57, 0xa0, 0x6d,
- 0xd1, 0x64, 0x41, 0x14, 0x6d, 0x34, 0x62, 0xed, 0x06, 0x6c, 0x24, 0xf2,
- 0x06, 0xbc, 0x28, 0x02, 0xaf, 0x03, 0x2d, 0xc2, 0x33, 0x05, 0xfb, 0xcb,
- 0xaa, 0x16, 0xe8, 0x65, 0x10, 0x43, 0xf5, 0x69, 0x5c, 0xe3, 0x81, 0x58,
- 0x99, 0xcd, 0x6b, 0xd3, 0xb8, 0xc7, 0x7b, 0x19, 0x55, 0xc9, 0x40, 0xce,
- 0x79, 0x55, 0xb8, 0x73, 0x89, 0xe9, 0x5c, 0x40, 0x66, 0x43, 0x12, 0x7f,
- 0x07, 0xb8, 0x65, 0x56, 0xd5, 0x8d, 0xc3, 0xa7, 0xf5, 0xb1, 0xb6, 0x65,
- 0x9e, 0xc0, 0x83, 0x36, 0x7f, 0x16, 0x45, 0x3c, 0x74, 0x4b, 0x93, 0x8a,
- 0x3c, 0xf1, 0x2b, 0xf5, 0x35, 0x70, 0x73, 0x7b, 0xe7, 0x82, 0x04, 0xb1,
- 0x18, 0x98, 0x0e, 0xd4, 0x9c, 0x6f, 0x1a, 0xfc, 0xfc, 0xa7, 0x33, 0xa5,
- 0xbb, 0xbb, 0x18, 0xf3, 0x6b, 0x7a, 0x5d, 0x32, 0x87, 0xf7, 0x6d, 0x25,
- 0xe4, 0xe2, 0x76, 0x86, 0x21, 0x1e, 0x11, 0x46, 0xcd, 0x76, 0x0e, 0x6f,
- 0x4f, 0xa4, 0x21, 0x71, 0x0a, 0x84, 0xa7, 0x2d, 0x36, 0xa9, 0x48, 0x22,
- 0x51, 0x7e, 0x82,
-};
-
-#if 0
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number: 120038507 (0x727a46b)
- Signature Algorithm: sha256WithRSAEncryption
- Issuer: C=IE, O=Baltimore, OU=CyberTrust, CN=Baltimore CyberTrust Root
- Validity
- Not Before: Apr 2 14:36:10 2014 GMT
- Not After : Apr 2 14:35:52 2021 GMT
- Subject: C=NL, L=Amsterdam, O=Verizon Enterprise Solutions, OU=Cybertrust, CN=Verizon Akamai SureServer CA G14-SHA2
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:dd:6e:9e:02:69:02:b5:a3:99:2e:08:64:32:6a:
- 59:f3:c6:9e:a6:20:07:d2:48:d1:a8:93:c7:ea:47:
- 8f:83:39:40:d7:20:5d:8d:9a:ba:ab:d8:70:ec:9d:
- 88:d1:bd:62:f6:db:ec:9d:5e:35:01:76:03:23:e5:
- 6f:d2:af:46:35:59:5a:5c:d1:a8:23:c1:eb:e9:20:
- d4:49:d6:3f:00:d8:a8:22:de:43:79:81:ac:e9:a4:
- 92:f5:77:70:05:1e:5c:b6:a0:f7:90:a4:cd:ab:28:
- 2c:90:c2:e7:0f:c3:af:1c:47:59:d5:84:2e:df:26:
- 07:45:23:5a:c6:e8:90:c8:85:4b:8c:16:1e:60:f9:
- 01:13:f1:14:1f:e6:e8:14:ed:c5:d2:6f:63:28:6e:
- 72:8c:49:ae:08:72:c7:93:95:b4:0b:0c:ae:8f:9a:
- 67:84:f5:57:1b:db:81:d7:17:9d:41:11:43:19:bd:
- 6d:4a:85:ed:8f:70:25:ab:66:ab:f6:fa:6d:1c:3c:
- ab:ed:17:bd:56:84:e1:db:75:33:b2:28:4b:99:8e:
- f9:4b:82:33:50:9f:92:53:ed:fa:ad:0f:95:9c:a3:
- f2:cb:60:f0:77:1d:c9:01:8b:5f:2d:86:be:bf:36:
- b8:24:96:13:7c:c1:86:5a:6c:c1:48:2a:7f:3e:93:
- 60:c5
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Basic Constraints: critical
- CA:TRUE, pathlen:2
- X509v3 Certificate Policies:
- Policy: 1.3.6.1.4.1.6334.1.50
- CPS: https://secure.omniroot.com/repository
-
- Authority Information Access:
- OCSP - URI:http://ocsp.omniroot.com/baltimoreroot
- CA Issuers - URI:https://cacert.omniroot.com/baltimoreroot.crt
- CA Issuers - URI:https://cacert.omniroot.com/baltimoreroot.der
-
- X509v3 Key Usage: critical
- Digital Signature, Non Repudiation, Certificate Sign, CRL Sign
- X509v3 Authority Key Identifier:
- keyid:E5:9D:59:30:82:47:58:CC:AC:FA:08:54:36:86:7B:3A:B5:04:4D:F0
-
- X509v3 CRL Distribution Points:
-
- Full Name:
- URI:http://cdp1.public-trust.com/CRL/Omniroot2025.crl
-
- X509v3 Subject Key Identifier:
- F8:BD:FA:AF:73:77:C6:C7:1B:F9:4B:4D:11:A7:D1:33:AF:AF:72:11
- Signature Algorithm: sha256WithRSAEncryption
- 80:d9:7a:ed:72:05:37:8f:61:aa:73:7c:9a:6a:fc:fe:01:e2:
- 19:81:70:07:25:32:b0:f0:6f:3b:c7:6a:28:3d:e4:51:87:e6:
- 7e:82:ec:ae:48:a7:b1:77:38:c2:d6:56:af:8f:f2:01:fc:65:
- 65:10:09:f7:74:29:b5:0e:92:ee:90:98:d1:88:a2:65:b7:cd:
- 9c:0e:a7:86:98:28:bc:ae:15:83:b6:1a:d7:1d:ec:19:da:7a:
- 8e:40:f9:99:15:d5:7d:a5:ba:ab:fd:26:98:6e:9c:41:3b:b6:
- 81:18:ec:70:48:d7:6e:7f:a6:e1:77:25:d6:dd:62:e8:52:f3:
- 8c:16:39:67:e2:22:0d:77:2e:fb:11:6c:e4:dd:38:b4:27:5f:
- 03:a8:3d:44:e2:f2:84:4b:84:fd:56:a6:9e:4d:7b:a2:16:4f:
- 07:f5:34:24:72:a5:a2:fa:16:66:2a:a4:4a:0e:c8:0d:27:44:
- 9c:77:d4:12:10:87:d2:00:2c:7a:bb:8e:88:22:91:15:be:a2:
- 59:ca:34:e0:1c:61:94:86:20:33:cd:e7:4c:5d:3b:92:3e:cb:
- d6:2d:ea:54:fa:fb:af:54:f5:a8:c5:0b:ca:8b:87:00:e6:9f:
- e6:95:bf:b7:c4:a3:59:f5:16:6c:5f:3e:69:55:80:39:f6:75:
- 50:14:3e:32
------BEGIN CERTIFICATE-----
-MIIFHzCCBAegAwIBAgIEByekazANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJJ
-RTESMBAGA1UEChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYD
-VQQDExlCYWx0aW1vcmUgQ3liZXJUcnVzdCBSb290MB4XDTE0MDQwMjE0MzYxMFoX
-DTIxMDQwMjE0MzU1MlowgY0xCzAJBgNVBAYTAk5MMRIwEAYDVQQHEwlBbXN0ZXJk
-YW0xJTAjBgNVBAoTHFZlcml6b24gRW50ZXJwcmlzZSBTb2x1dGlvbnMxEzARBgNV
-BAsTCkN5YmVydHJ1c3QxLjAsBgNVBAMTJVZlcml6b24gQWthbWFpIFN1cmVTZXJ2
-ZXIgQ0EgRzE0LVNIQTIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDd
-bp4CaQK1o5kuCGQyalnzxp6mIAfSSNGok8fqR4+DOUDXIF2Nmrqr2HDsnYjRvWL2
-2+ydXjUBdgMj5W/Sr0Y1WVpc0agjwevpINRJ1j8A2Kgi3kN5gazppJL1d3AFHly2
-oPeQpM2rKCyQwucPw68cR1nVhC7fJgdFI1rG6JDIhUuMFh5g+QET8RQf5ugU7cXS
-b2MobnKMSa4IcseTlbQLDK6PmmeE9Vcb24HXF51BEUMZvW1Khe2PcCWrZqv2+m0c
-PKvtF71WhOHbdTOyKEuZjvlLgjNQn5JT7fqtD5Wco/LLYPB3HckBi18thr6/Nrgk
-lhN8wYZabMFIKn8+k2DFAgMBAAGjggG3MIIBszASBgNVHRMBAf8ECDAGAQH/AgEC
-MEwGA1UdIARFMEMwQQYJKwYBBAGxPgEyMDQwMgYIKwYBBQUHAgEWJmh0dHBzOi8v
-c2VjdXJlLm9tbmlyb290LmNvbS9yZXBvc2l0b3J5MIG6BggrBgEFBQcBAQSBrTCB
-qjAyBggrBgEFBQcwAYYmaHR0cDovL29jc3Aub21uaXJvb3QuY29tL2JhbHRpbW9y
-ZXJvb3QwOQYIKwYBBQUHMAKGLWh0dHBzOi8vY2FjZXJ0Lm9tbmlyb290LmNvbS9i
-YWx0aW1vcmVyb290LmNydDA5BggrBgEFBQcwAoYtaHR0cHM6Ly9jYWNlcnQub21u
-aXJvb3QuY29tL2JhbHRpbW9yZXJvb3QuZGVyMA4GA1UdDwEB/wQEAwIBxjAfBgNV
-HSMEGDAWgBTlnVkwgkdYzKz6CFQ2hns6tQRN8DBCBgNVHR8EOzA5MDegNaAzhjFo
-dHRwOi8vY2RwMS5wdWJsaWMtdHJ1c3QuY29tL0NSTC9PbW5pcm9vdDIwMjUuY3Js
-MB0GA1UdDgQWBBT4vfqvc3fGxxv5S00Rp9Ezr69yETANBgkqhkiG9w0BAQsFAAOC
-AQEAgNl67XIFN49hqnN8mmr8/gHiGYFwByUysPBvO8dqKD3kUYfmfoLsrkinsXc4
-wtZWr4/yAfxlZRAJ93QptQ6S7pCY0YiiZbfNnA6nhpgovK4Vg7Ya1x3sGdp6jkD5
-mRXVfaW6q/0mmG6cQTu2gRjscEjXbn+m4Xcl1t1i6FLzjBY5Z+IiDXcu+xFs5N04
-tCdfA6g9ROLyhEuE/Vamnk17ohZPB/U0JHKlovoWZiqkSg7IDSdEnHfUEhCH0gAs
-eruOiCKRFb6iWco04BxhlIYgM83nTF07kj7L1i3qVPr7r1T1qMULyouHAOaf5pW/
-t8SjWfUWbF8+aVWAOfZ1UBQ+Mg==
------END CERTIFICATE-----
-#endif
-static const unsigned char kDERCert41[] = {
- 0x30, 0x82, 0x05, 0x1f, 0x30, 0x82, 0x04, 0x07, 0xa0, 0x03, 0x02, 0x01,
- 0x02, 0x02, 0x04, 0x07, 0x27, 0xa4, 0x6b, 0x30, 0x0d, 0x06, 0x09, 0x2a,
- 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x5a,
- 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x49,
- 0x45, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x09,
- 0x42, 0x61, 0x6c, 0x74, 0x69, 0x6d, 0x6f, 0x72, 0x65, 0x31, 0x13, 0x30,
- 0x11, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x0a, 0x43, 0x79, 0x62, 0x65,
- 0x72, 0x54, 0x72, 0x75, 0x73, 0x74, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03,
- 0x55, 0x04, 0x03, 0x13, 0x19, 0x42, 0x61, 0x6c, 0x74, 0x69, 0x6d, 0x6f,
- 0x72, 0x65, 0x20, 0x43, 0x79, 0x62, 0x65, 0x72, 0x54, 0x72, 0x75, 0x73,
- 0x74, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x34,
- 0x30, 0x34, 0x30, 0x32, 0x31, 0x34, 0x33, 0x36, 0x31, 0x30, 0x5a, 0x17,
- 0x0d, 0x32, 0x31, 0x30, 0x34, 0x30, 0x32, 0x31, 0x34, 0x33, 0x35, 0x35,
- 0x32, 0x5a, 0x30, 0x81, 0x8d, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55,
- 0x04, 0x06, 0x13, 0x02, 0x4e, 0x4c, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03,
- 0x55, 0x04, 0x07, 0x13, 0x09, 0x41, 0x6d, 0x73, 0x74, 0x65, 0x72, 0x64,
- 0x61, 0x6d, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13,
- 0x1c, 0x56, 0x65, 0x72, 0x69, 0x7a, 0x6f, 0x6e, 0x20, 0x45, 0x6e, 0x74,
- 0x65, 0x72, 0x70, 0x72, 0x69, 0x73, 0x65, 0x20, 0x53, 0x6f, 0x6c, 0x75,
- 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55,
- 0x04, 0x0b, 0x13, 0x0a, 0x43, 0x79, 0x62, 0x65, 0x72, 0x74, 0x72, 0x75,
- 0x73, 0x74, 0x31, 0x2e, 0x30, 0x2c, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
- 0x25, 0x56, 0x65, 0x72, 0x69, 0x7a, 0x6f, 0x6e, 0x20, 0x41, 0x6b, 0x61,
- 0x6d, 0x61, 0x69, 0x20, 0x53, 0x75, 0x72, 0x65, 0x53, 0x65, 0x72, 0x76,
- 0x65, 0x72, 0x20, 0x43, 0x41, 0x20, 0x47, 0x31, 0x34, 0x2d, 0x53, 0x48,
- 0x41, 0x32, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
- 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01,
- 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xdd,
- 0x6e, 0x9e, 0x02, 0x69, 0x02, 0xb5, 0xa3, 0x99, 0x2e, 0x08, 0x64, 0x32,
- 0x6a, 0x59, 0xf3, 0xc6, 0x9e, 0xa6, 0x20, 0x07, 0xd2, 0x48, 0xd1, 0xa8,
- 0x93, 0xc7, 0xea, 0x47, 0x8f, 0x83, 0x39, 0x40, 0xd7, 0x20, 0x5d, 0x8d,
- 0x9a, 0xba, 0xab, 0xd8, 0x70, 0xec, 0x9d, 0x88, 0xd1, 0xbd, 0x62, 0xf6,
- 0xdb, 0xec, 0x9d, 0x5e, 0x35, 0x01, 0x76, 0x03, 0x23, 0xe5, 0x6f, 0xd2,
- 0xaf, 0x46, 0x35, 0x59, 0x5a, 0x5c, 0xd1, 0xa8, 0x23, 0xc1, 0xeb, 0xe9,
- 0x20, 0xd4, 0x49, 0xd6, 0x3f, 0x00, 0xd8, 0xa8, 0x22, 0xde, 0x43, 0x79,
- 0x81, 0xac, 0xe9, 0xa4, 0x92, 0xf5, 0x77, 0x70, 0x05, 0x1e, 0x5c, 0xb6,
- 0xa0, 0xf7, 0x90, 0xa4, 0xcd, 0xab, 0x28, 0x2c, 0x90, 0xc2, 0xe7, 0x0f,
- 0xc3, 0xaf, 0x1c, 0x47, 0x59, 0xd5, 0x84, 0x2e, 0xdf, 0x26, 0x07, 0x45,
- 0x23, 0x5a, 0xc6, 0xe8, 0x90, 0xc8, 0x85, 0x4b, 0x8c, 0x16, 0x1e, 0x60,
- 0xf9, 0x01, 0x13, 0xf1, 0x14, 0x1f, 0xe6, 0xe8, 0x14, 0xed, 0xc5, 0xd2,
- 0x6f, 0x63, 0x28, 0x6e, 0x72, 0x8c, 0x49, 0xae, 0x08, 0x72, 0xc7, 0x93,
- 0x95, 0xb4, 0x0b, 0x0c, 0xae, 0x8f, 0x9a, 0x67, 0x84, 0xf5, 0x57, 0x1b,
- 0xdb, 0x81, 0xd7, 0x17, 0x9d, 0x41, 0x11, 0x43, 0x19, 0xbd, 0x6d, 0x4a,
- 0x85, 0xed, 0x8f, 0x70, 0x25, 0xab, 0x66, 0xab, 0xf6, 0xfa, 0x6d, 0x1c,
- 0x3c, 0xab, 0xed, 0x17, 0xbd, 0x56, 0x84, 0xe1, 0xdb, 0x75, 0x33, 0xb2,
- 0x28, 0x4b, 0x99, 0x8e, 0xf9, 0x4b, 0x82, 0x33, 0x50, 0x9f, 0x92, 0x53,
- 0xed, 0xfa, 0xad, 0x0f, 0x95, 0x9c, 0xa3, 0xf2, 0xcb, 0x60, 0xf0, 0x77,
- 0x1d, 0xc9, 0x01, 0x8b, 0x5f, 0x2d, 0x86, 0xbe, 0xbf, 0x36, 0xb8, 0x24,
- 0x96, 0x13, 0x7c, 0xc1, 0x86, 0x5a, 0x6c, 0xc1, 0x48, 0x2a, 0x7f, 0x3e,
- 0x93, 0x60, 0xc5, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0xb7,
- 0x30, 0x82, 0x01, 0xb3, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01,
- 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x02,
- 0x30, 0x4c, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x45, 0x30, 0x43, 0x30,
- 0x41, 0x06, 0x09, 0x2b, 0x06, 0x01, 0x04, 0x01, 0xb1, 0x3e, 0x01, 0x32,
- 0x30, 0x34, 0x30, 0x32, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
- 0x02, 0x01, 0x16, 0x26, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f,
- 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x2e, 0x6f, 0x6d, 0x6e, 0x69, 0x72,
- 0x6f, 0x6f, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x70, 0x6f,
- 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x30, 0x81, 0xba, 0x06, 0x08, 0x2b,
- 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x81, 0xad, 0x30, 0x81,
- 0xaa, 0x30, 0x32, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30,
- 0x01, 0x86, 0x26, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63,
- 0x73, 0x70, 0x2e, 0x6f, 0x6d, 0x6e, 0x69, 0x72, 0x6f, 0x6f, 0x74, 0x2e,
- 0x63, 0x6f, 0x6d, 0x2f, 0x62, 0x61, 0x6c, 0x74, 0x69, 0x6d, 0x6f, 0x72,
- 0x65, 0x72, 0x6f, 0x6f, 0x74, 0x30, 0x39, 0x06, 0x08, 0x2b, 0x06, 0x01,
- 0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x2d, 0x68, 0x74, 0x74, 0x70, 0x73,
- 0x3a, 0x2f, 0x2f, 0x63, 0x61, 0x63, 0x65, 0x72, 0x74, 0x2e, 0x6f, 0x6d,
- 0x6e, 0x69, 0x72, 0x6f, 0x6f, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x62,
- 0x61, 0x6c, 0x74, 0x69, 0x6d, 0x6f, 0x72, 0x65, 0x72, 0x6f, 0x6f, 0x74,
- 0x2e, 0x63, 0x72, 0x74, 0x30, 0x39, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05,
- 0x05, 0x07, 0x30, 0x02, 0x86, 0x2d, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a,
- 0x2f, 0x2f, 0x63, 0x61, 0x63, 0x65, 0x72, 0x74, 0x2e, 0x6f, 0x6d, 0x6e,
- 0x69, 0x72, 0x6f, 0x6f, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x62, 0x61,
- 0x6c, 0x74, 0x69, 0x6d, 0x6f, 0x72, 0x65, 0x72, 0x6f, 0x6f, 0x74, 0x2e,
- 0x64, 0x65, 0x72, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01,
- 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0xc6, 0x30, 0x1f, 0x06, 0x03, 0x55,
- 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0xe5, 0x9d, 0x59, 0x30,
- 0x82, 0x47, 0x58, 0xcc, 0xac, 0xfa, 0x08, 0x54, 0x36, 0x86, 0x7b, 0x3a,
- 0xb5, 0x04, 0x4d, 0xf0, 0x30, 0x42, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04,
- 0x3b, 0x30, 0x39, 0x30, 0x37, 0xa0, 0x35, 0xa0, 0x33, 0x86, 0x31, 0x68,
- 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x64, 0x70, 0x31, 0x2e, 0x70,
- 0x75, 0x62, 0x6c, 0x69, 0x63, 0x2d, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e,
- 0x63, 0x6f, 0x6d, 0x2f, 0x43, 0x52, 0x4c, 0x2f, 0x4f, 0x6d, 0x6e, 0x69,
- 0x72, 0x6f, 0x6f, 0x74, 0x32, 0x30, 0x32, 0x35, 0x2e, 0x63, 0x72, 0x6c,
- 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xf8,
- 0xbd, 0xfa, 0xaf, 0x73, 0x77, 0xc6, 0xc7, 0x1b, 0xf9, 0x4b, 0x4d, 0x11,
- 0xa7, 0xd1, 0x33, 0xaf, 0xaf, 0x72, 0x11, 0x30, 0x0d, 0x06, 0x09, 0x2a,
- 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82,
- 0x01, 0x01, 0x00, 0x80, 0xd9, 0x7a, 0xed, 0x72, 0x05, 0x37, 0x8f, 0x61,
- 0xaa, 0x73, 0x7c, 0x9a, 0x6a, 0xfc, 0xfe, 0x01, 0xe2, 0x19, 0x81, 0x70,
- 0x07, 0x25, 0x32, 0xb0, 0xf0, 0x6f, 0x3b, 0xc7, 0x6a, 0x28, 0x3d, 0xe4,
- 0x51, 0x87, 0xe6, 0x7e, 0x82, 0xec, 0xae, 0x48, 0xa7, 0xb1, 0x77, 0x38,
- 0xc2, 0xd6, 0x56, 0xaf, 0x8f, 0xf2, 0x01, 0xfc, 0x65, 0x65, 0x10, 0x09,
- 0xf7, 0x74, 0x29, 0xb5, 0x0e, 0x92, 0xee, 0x90, 0x98, 0xd1, 0x88, 0xa2,
- 0x65, 0xb7, 0xcd, 0x9c, 0x0e, 0xa7, 0x86, 0x98, 0x28, 0xbc, 0xae, 0x15,
- 0x83, 0xb6, 0x1a, 0xd7, 0x1d, 0xec, 0x19, 0xda, 0x7a, 0x8e, 0x40, 0xf9,
- 0x99, 0x15, 0xd5, 0x7d, 0xa5, 0xba, 0xab, 0xfd, 0x26, 0x98, 0x6e, 0x9c,
- 0x41, 0x3b, 0xb6, 0x81, 0x18, 0xec, 0x70, 0x48, 0xd7, 0x6e, 0x7f, 0xa6,
- 0xe1, 0x77, 0x25, 0xd6, 0xdd, 0x62, 0xe8, 0x52, 0xf3, 0x8c, 0x16, 0x39,
- 0x67, 0xe2, 0x22, 0x0d, 0x77, 0x2e, 0xfb, 0x11, 0x6c, 0xe4, 0xdd, 0x38,
- 0xb4, 0x27, 0x5f, 0x03, 0xa8, 0x3d, 0x44, 0xe2, 0xf2, 0x84, 0x4b, 0x84,
- 0xfd, 0x56, 0xa6, 0x9e, 0x4d, 0x7b, 0xa2, 0x16, 0x4f, 0x07, 0xf5, 0x34,
- 0x24, 0x72, 0xa5, 0xa2, 0xfa, 0x16, 0x66, 0x2a, 0xa4, 0x4a, 0x0e, 0xc8,
- 0x0d, 0x27, 0x44, 0x9c, 0x77, 0xd4, 0x12, 0x10, 0x87, 0xd2, 0x00, 0x2c,
- 0x7a, 0xbb, 0x8e, 0x88, 0x22, 0x91, 0x15, 0xbe, 0xa2, 0x59, 0xca, 0x34,
- 0xe0, 0x1c, 0x61, 0x94, 0x86, 0x20, 0x33, 0xcd, 0xe7, 0x4c, 0x5d, 0x3b,
- 0x92, 0x3e, 0xcb, 0xd6, 0x2d, 0xea, 0x54, 0xfa, 0xfb, 0xaf, 0x54, 0xf5,
- 0xa8, 0xc5, 0x0b, 0xca, 0x8b, 0x87, 0x00, 0xe6, 0x9f, 0xe6, 0x95, 0xbf,
- 0xb7, 0xc4, 0xa3, 0x59, 0xf5, 0x16, 0x6c, 0x5f, 0x3e, 0x69, 0x55, 0x80,
- 0x39, 0xf6, 0x75, 0x50, 0x14, 0x3e, 0x32,
-};
-
-#if 0
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number:
- 7e:e1:4a:6f:6f:ef:f2:d3:7f:3f:ad:65:4d:3a:da:b4
- Signature Algorithm: sha256WithRSAEncryption
- Issuer: C=US, O=VeriSign, Inc., OU=VeriSign Trust Network, OU=(c) 2006 VeriSign, Inc. - For authorized use only, CN=VeriSign Class 3 Public Primary Certification Authority - G5
- Validity
- Not Before: Oct 31 00:00:00 2013 GMT
- Not After : Oct 30 23:59:59 2023 GMT
- Subject: C=US, O=Symantec Corporation, OU=Symantec Trust Network, CN=Symantec Class 3 EV SSL CA - G3
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:d8:a1:65:74:23:e8:2b:64:e2:32:d7:33:37:3d:
- 8e:f5:34:16:48:dd:4f:7f:87:1c:f8:44:23:13:8e:
- fb:11:d8:44:5a:18:71:8e:60:16:26:92:9b:fd:17:
- 0b:e1:71:70:42:fe:bf:fa:1c:c0:aa:a3:a7:b5:71:
- e8:ff:18:83:f6:df:10:0a:13:62:c8:3d:9c:a7:de:
- 2e:3f:0c:d9:1d:e7:2e:fb:2a:ce:c8:9a:7f:87:bf:
- d8:4c:04:15:32:c9:d1:cc:95:71:a0:4e:28:4f:84:
- d9:35:fb:e3:86:6f:94:53:e6:72:8a:63:67:2e:be:
- 69:f6:f7:6e:8e:9c:60:04:eb:29:fa:c4:47:42:d2:
- 78:98:e3:ec:0b:a5:92:dc:b7:9a:bd:80:64:2b:38:
- 7c:38:09:5b:66:f6:2d:95:7a:86:b2:34:2e:85:9e:
- 90:0e:5f:b7:5d:a4:51:72:46:70:13:bf:67:f2:b6:
- a7:4d:14:1e:6c:b9:53:ee:23:1a:4e:8d:48:55:43:
- 41:b1:89:75:6a:40:28:c5:7d:dd:d2:6e:d2:02:19:
- 2f:7b:24:94:4b:eb:f1:1a:a9:9b:e3:23:9a:ea:fa:
- 33:ab:0a:2c:b7:f4:60:08:dd:9f:1c:cd:dd:2d:01:
- 66:80:af:b3:2f:29:1d:23:b8:8a:e1:a1:70:07:0c:
- 34:0f
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- Authority Information Access:
- OCSP - URI:http://s2.symcb.com
-
- X509v3 Basic Constraints: critical
- CA:TRUE, pathlen:0
- X509v3 Certificate Policies:
- Policy: X509v3 Any Policy
- CPS: http://www.symauth.com/cps
- User Notice:
- Explicit Text: http://www.symauth.com/rpa
-
- X509v3 CRL Distribution Points:
-
- Full Name:
- URI:http://s1.symcb.com/pca3-g5.crl
-
- X509v3 Key Usage: critical
- Certificate Sign, CRL Sign
- X509v3 Subject Alternative Name:
- DirName:/CN=SymantecPKI-1-533
- X509v3 Subject Key Identifier:
- 01:59:AB:E7:DD:3A:0B:59:A6:64:63:D6:CF:20:07:57:D5:91:E7:6A
- X509v3 Authority Key Identifier:
- keyid:7F:D3:65:A7:C2:DD:EC:BB:F0:30:09:F3:43:39:FA:02:AF:33:31:33
-
- Signature Algorithm: sha256WithRSAEncryption
- 42:01:55:7b:d0:16:1a:5d:58:e8:bb:9b:a8:4d:d7:f3:d7:eb:
- 13:94:86:d6:7f:21:0b:47:bc:57:9b:92:5d:4f:05:9f:38:a4:
- 10:7c:cf:83:be:06:43:46:8d:08:bc:6a:d7:10:a6:fa:ab:af:
- 2f:61:a8:63:f2:65:df:7f:4c:88:12:88:4f:b3:69:d9:ff:27:
- c0:0a:97:91:8f:56:fb:89:c4:a8:bb:92:2d:1b:73:b0:c6:ab:
- 36:f4:96:6c:20:08:ef:0a:1e:66:24:45:4f:67:00:40:c8:07:
- 54:74:33:3b:a6:ad:bb:23:9f:66:ed:a2:44:70:34:fb:0e:ea:
- 01:fd:cf:78:74:df:a7:ad:55:b7:5f:4d:f6:d6:3f:e0:86:ce:
- 24:c7:42:a9:13:14:44:35:4b:b6:df:c9:60:ac:0c:7f:d9:93:
- 21:4b:ee:9c:e4:49:02:98:d3:60:7b:5c:bc:d5:30:2f:07:ce:
- 44:42:c4:0b:99:fe:e6:9f:fc:b0:78:86:51:6d:d1:2c:9d:c6:
- 96:fb:85:82:bb:04:2f:f7:62:80:ef:62:da:7f:f6:0e:ac:90:
- b8:56:bd:79:3f:f2:80:6e:a3:d9:b9:0f:5d:3a:07:1d:91:93:
- 86:4b:29:4c:e1:dc:b5:e1:e0:33:9d:b3:cb:36:91:4b:fe:a1:
- b4:ee:f0:f9
------BEGIN CERTIFICATE-----
-MIIFKzCCBBOgAwIBAgIQfuFKb2/v8tN/P61lTTratDANBgkqhkiG9w0BAQsFADCB
-yjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL
-ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJp
-U2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxW
-ZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0
-aG9yaXR5IC0gRzUwHhcNMTMxMDMxMDAwMDAwWhcNMjMxMDMwMjM1OTU5WjB3MQsw
-CQYDVQQGEwJVUzEdMBsGA1UEChMUU3ltYW50ZWMgQ29ycG9yYXRpb24xHzAdBgNV
-BAsTFlN5bWFudGVjIFRydXN0IE5ldHdvcmsxKDAmBgNVBAMTH1N5bWFudGVjIENs
-YXNzIDMgRVYgU1NMIENBIC0gRzMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
-AoIBAQDYoWV0I+grZOIy1zM3PY71NBZI3U9/hxz4RCMTjvsR2ERaGHGOYBYmkpv9
-FwvhcXBC/r/6HMCqo6e1cej/GIP23xAKE2LIPZyn3i4/DNkd5y77Ks7Imn+Hv9hM
-BBUyydHMlXGgTihPhNk1++OGb5RT5nKKY2cuvmn2926OnGAE6yn6xEdC0niY4+wL
-pZLct5q9gGQrOHw4CVtm9i2VeoayNC6FnpAOX7ddpFFyRnATv2fytqdNFB5suVPu
-IxpOjUhVQ0GxiXVqQCjFfd3SbtICGS97JJRL6/EaqZvjI5rq+jOrCiy39GAI3Z8c
-zd0tAWaAr7MvKR0juIrhoXAHDDQPAgMBAAGjggFdMIIBWTAvBggrBgEFBQcBAQQj
-MCEwHwYIKwYBBQUHMAGGE2h0dHA6Ly9zMi5zeW1jYi5jb20wEgYDVR0TAQH/BAgw
-BgEB/wIBADBlBgNVHSAEXjBcMFoGBFUdIAAwUjAmBggrBgEFBQcCARYaaHR0cDov
-L3d3dy5zeW1hdXRoLmNvbS9jcHMwKAYIKwYBBQUHAgIwHBoaaHR0cDovL3d3dy5z
-eW1hdXRoLmNvbS9ycGEwMAYDVR0fBCkwJzAloCOgIYYfaHR0cDovL3MxLnN5bWNi
-LmNvbS9wY2EzLWc1LmNybDAOBgNVHQ8BAf8EBAMCAQYwKQYDVR0RBCIwIKQeMBwx
-GjAYBgNVBAMTEVN5bWFudGVjUEtJLTEtNTMzMB0GA1UdDgQWBBQBWavn3ToLWaZk
-Y9bPIAdX1ZHnajAfBgNVHSMEGDAWgBR/02Wnwt3su/AwCfNDOfoCrzMxMzANBgkq
-hkiG9w0BAQsFAAOCAQEAQgFVe9AWGl1Y6LubqE3X89frE5SG1n8hC0e8V5uSXU8F
-nzikEHzPg74GQ0aNCLxq1xCm+quvL2GoY/Jl339MiBKIT7Np2f8nwAqXkY9W+4nE
-qLuSLRtzsMarNvSWbCAI7woeZiRFT2cAQMgHVHQzO6atuyOfZu2iRHA0+w7qAf3P
-eHTfp61Vt19N9tY/4IbOJMdCqRMURDVLtt/JYKwMf9mTIUvunORJApjTYHtcvNUw
-LwfORELEC5n+5p/8sHiGUW3RLJ3GlvuFgrsEL/digO9i2n/2DqyQuFa9eT/ygG6j
-2bkPXToHHZGThkspTOHcteHgM52zyzaRS/6htO7w+Q==
------END CERTIFICATE-----
-#endif
-static const unsigned char kDERCert42[] = {
- 0x30, 0x82, 0x05, 0x2b, 0x30, 0x82, 0x04, 0x13, 0xa0, 0x03, 0x02, 0x01,
- 0x02, 0x02, 0x10, 0x7e, 0xe1, 0x4a, 0x6f, 0x6f, 0xef, 0xf2, 0xd3, 0x7f,
- 0x3f, 0xad, 0x65, 0x4d, 0x3a, 0xda, 0xb4, 0x30, 0x0d, 0x06, 0x09, 0x2a,
- 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x81,
- 0xca, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
- 0x55, 0x53, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13,
- 0x0e, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49,
- 0x6e, 0x63, 0x2e, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x0b,
- 0x13, 0x16, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x54,
- 0x72, 0x75, 0x73, 0x74, 0x20, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b,
- 0x31, 0x3a, 0x30, 0x38, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x31, 0x28,
- 0x63, 0x29, 0x20, 0x32, 0x30, 0x30, 0x36, 0x20, 0x56, 0x65, 0x72, 0x69,
- 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x20, 0x2d,
- 0x20, 0x46, 0x6f, 0x72, 0x20, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69,
- 0x7a, 0x65, 0x64, 0x20, 0x75, 0x73, 0x65, 0x20, 0x6f, 0x6e, 0x6c, 0x79,
- 0x31, 0x45, 0x30, 0x43, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x3c, 0x56,
- 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x43, 0x6c, 0x61, 0x73,
- 0x73, 0x20, 0x33, 0x20, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x20, 0x50,
- 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69,
- 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74,
- 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x20, 0x2d, 0x20, 0x47, 0x35, 0x30,
- 0x1e, 0x17, 0x0d, 0x31, 0x33, 0x31, 0x30, 0x33, 0x31, 0x30, 0x30, 0x30,
- 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x33, 0x31, 0x30, 0x33, 0x30,
- 0x32, 0x33, 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x77, 0x31, 0x0b, 0x30,
- 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x1d,
- 0x30, 0x1b, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x14, 0x53, 0x79, 0x6d,
- 0x61, 0x6e, 0x74, 0x65, 0x63, 0x20, 0x43, 0x6f, 0x72, 0x70, 0x6f, 0x72,
- 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55,
- 0x04, 0x0b, 0x13, 0x16, 0x53, 0x79, 0x6d, 0x61, 0x6e, 0x74, 0x65, 0x63,
- 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x4e, 0x65, 0x74, 0x77, 0x6f,
- 0x72, 0x6b, 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
- 0x1f, 0x53, 0x79, 0x6d, 0x61, 0x6e, 0x74, 0x65, 0x63, 0x20, 0x43, 0x6c,
- 0x61, 0x73, 0x73, 0x20, 0x33, 0x20, 0x45, 0x56, 0x20, 0x53, 0x53, 0x4c,
- 0x20, 0x43, 0x41, 0x20, 0x2d, 0x20, 0x47, 0x33, 0x30, 0x82, 0x01, 0x22,
- 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
- 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a,
- 0x02, 0x82, 0x01, 0x01, 0x00, 0xd8, 0xa1, 0x65, 0x74, 0x23, 0xe8, 0x2b,
- 0x64, 0xe2, 0x32, 0xd7, 0x33, 0x37, 0x3d, 0x8e, 0xf5, 0x34, 0x16, 0x48,
- 0xdd, 0x4f, 0x7f, 0x87, 0x1c, 0xf8, 0x44, 0x23, 0x13, 0x8e, 0xfb, 0x11,
- 0xd8, 0x44, 0x5a, 0x18, 0x71, 0x8e, 0x60, 0x16, 0x26, 0x92, 0x9b, 0xfd,
- 0x17, 0x0b, 0xe1, 0x71, 0x70, 0x42, 0xfe, 0xbf, 0xfa, 0x1c, 0xc0, 0xaa,
- 0xa3, 0xa7, 0xb5, 0x71, 0xe8, 0xff, 0x18, 0x83, 0xf6, 0xdf, 0x10, 0x0a,
- 0x13, 0x62, 0xc8, 0x3d, 0x9c, 0xa7, 0xde, 0x2e, 0x3f, 0x0c, 0xd9, 0x1d,
- 0xe7, 0x2e, 0xfb, 0x2a, 0xce, 0xc8, 0x9a, 0x7f, 0x87, 0xbf, 0xd8, 0x4c,
- 0x04, 0x15, 0x32, 0xc9, 0xd1, 0xcc, 0x95, 0x71, 0xa0, 0x4e, 0x28, 0x4f,
- 0x84, 0xd9, 0x35, 0xfb, 0xe3, 0x86, 0x6f, 0x94, 0x53, 0xe6, 0x72, 0x8a,
- 0x63, 0x67, 0x2e, 0xbe, 0x69, 0xf6, 0xf7, 0x6e, 0x8e, 0x9c, 0x60, 0x04,
- 0xeb, 0x29, 0xfa, 0xc4, 0x47, 0x42, 0xd2, 0x78, 0x98, 0xe3, 0xec, 0x0b,
- 0xa5, 0x92, 0xdc, 0xb7, 0x9a, 0xbd, 0x80, 0x64, 0x2b, 0x38, 0x7c, 0x38,
- 0x09, 0x5b, 0x66, 0xf6, 0x2d, 0x95, 0x7a, 0x86, 0xb2, 0x34, 0x2e, 0x85,
- 0x9e, 0x90, 0x0e, 0x5f, 0xb7, 0x5d, 0xa4, 0x51, 0x72, 0x46, 0x70, 0x13,
- 0xbf, 0x67, 0xf2, 0xb6, 0xa7, 0x4d, 0x14, 0x1e, 0x6c, 0xb9, 0x53, 0xee,
- 0x23, 0x1a, 0x4e, 0x8d, 0x48, 0x55, 0x43, 0x41, 0xb1, 0x89, 0x75, 0x6a,
- 0x40, 0x28, 0xc5, 0x7d, 0xdd, 0xd2, 0x6e, 0xd2, 0x02, 0x19, 0x2f, 0x7b,
- 0x24, 0x94, 0x4b, 0xeb, 0xf1, 0x1a, 0xa9, 0x9b, 0xe3, 0x23, 0x9a, 0xea,
- 0xfa, 0x33, 0xab, 0x0a, 0x2c, 0xb7, 0xf4, 0x60, 0x08, 0xdd, 0x9f, 0x1c,
- 0xcd, 0xdd, 0x2d, 0x01, 0x66, 0x80, 0xaf, 0xb3, 0x2f, 0x29, 0x1d, 0x23,
- 0xb8, 0x8a, 0xe1, 0xa1, 0x70, 0x07, 0x0c, 0x34, 0x0f, 0x02, 0x03, 0x01,
- 0x00, 0x01, 0xa3, 0x82, 0x01, 0x5d, 0x30, 0x82, 0x01, 0x59, 0x30, 0x2f,
- 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x23,
- 0x30, 0x21, 0x30, 0x1f, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
- 0x30, 0x01, 0x86, 0x13, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x73,
- 0x32, 0x2e, 0x73, 0x79, 0x6d, 0x63, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x30,
- 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30,
- 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x00, 0x30, 0x65, 0x06, 0x03, 0x55,
- 0x1d, 0x20, 0x04, 0x5e, 0x30, 0x5c, 0x30, 0x5a, 0x06, 0x04, 0x55, 0x1d,
- 0x20, 0x00, 0x30, 0x52, 0x30, 0x26, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05,
- 0x05, 0x07, 0x02, 0x01, 0x16, 0x1a, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f,
- 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x73, 0x79, 0x6d, 0x61, 0x75, 0x74, 0x68,
- 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x70, 0x73, 0x30, 0x28, 0x06, 0x08,
- 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x02, 0x30, 0x1c, 0x1a, 0x1a,
- 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x73,
- 0x79, 0x6d, 0x61, 0x75, 0x74, 0x68, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72,
- 0x70, 0x61, 0x30, 0x30, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x29, 0x30,
- 0x27, 0x30, 0x25, 0xa0, 0x23, 0xa0, 0x21, 0x86, 0x1f, 0x68, 0x74, 0x74,
- 0x70, 0x3a, 0x2f, 0x2f, 0x73, 0x31, 0x2e, 0x73, 0x79, 0x6d, 0x63, 0x62,
- 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x63, 0x61, 0x33, 0x2d, 0x67, 0x35,
- 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01,
- 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x29, 0x06, 0x03,
- 0x55, 0x1d, 0x11, 0x04, 0x22, 0x30, 0x20, 0xa4, 0x1e, 0x30, 0x1c, 0x31,
- 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x11, 0x53, 0x79,
- 0x6d, 0x61, 0x6e, 0x74, 0x65, 0x63, 0x50, 0x4b, 0x49, 0x2d, 0x31, 0x2d,
- 0x35, 0x33, 0x33, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16,
- 0x04, 0x14, 0x01, 0x59, 0xab, 0xe7, 0xdd, 0x3a, 0x0b, 0x59, 0xa6, 0x64,
- 0x63, 0xd6, 0xcf, 0x20, 0x07, 0x57, 0xd5, 0x91, 0xe7, 0x6a, 0x30, 0x1f,
- 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x7f,
- 0xd3, 0x65, 0xa7, 0xc2, 0xdd, 0xec, 0xbb, 0xf0, 0x30, 0x09, 0xf3, 0x43,
- 0x39, 0xfa, 0x02, 0xaf, 0x33, 0x31, 0x33, 0x30, 0x0d, 0x06, 0x09, 0x2a,
- 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82,
- 0x01, 0x01, 0x00, 0x42, 0x01, 0x55, 0x7b, 0xd0, 0x16, 0x1a, 0x5d, 0x58,
- 0xe8, 0xbb, 0x9b, 0xa8, 0x4d, 0xd7, 0xf3, 0xd7, 0xeb, 0x13, 0x94, 0x86,
- 0xd6, 0x7f, 0x21, 0x0b, 0x47, 0xbc, 0x57, 0x9b, 0x92, 0x5d, 0x4f, 0x05,
- 0x9f, 0x38, 0xa4, 0x10, 0x7c, 0xcf, 0x83, 0xbe, 0x06, 0x43, 0x46, 0x8d,
- 0x08, 0xbc, 0x6a, 0xd7, 0x10, 0xa6, 0xfa, 0xab, 0xaf, 0x2f, 0x61, 0xa8,
- 0x63, 0xf2, 0x65, 0xdf, 0x7f, 0x4c, 0x88, 0x12, 0x88, 0x4f, 0xb3, 0x69,
- 0xd9, 0xff, 0x27, 0xc0, 0x0a, 0x97, 0x91, 0x8f, 0x56, 0xfb, 0x89, 0xc4,
- 0xa8, 0xbb, 0x92, 0x2d, 0x1b, 0x73, 0xb0, 0xc6, 0xab, 0x36, 0xf4, 0x96,
- 0x6c, 0x20, 0x08, 0xef, 0x0a, 0x1e, 0x66, 0x24, 0x45, 0x4f, 0x67, 0x00,
- 0x40, 0xc8, 0x07, 0x54, 0x74, 0x33, 0x3b, 0xa6, 0xad, 0xbb, 0x23, 0x9f,
- 0x66, 0xed, 0xa2, 0x44, 0x70, 0x34, 0xfb, 0x0e, 0xea, 0x01, 0xfd, 0xcf,
- 0x78, 0x74, 0xdf, 0xa7, 0xad, 0x55, 0xb7, 0x5f, 0x4d, 0xf6, 0xd6, 0x3f,
- 0xe0, 0x86, 0xce, 0x24, 0xc7, 0x42, 0xa9, 0x13, 0x14, 0x44, 0x35, 0x4b,
- 0xb6, 0xdf, 0xc9, 0x60, 0xac, 0x0c, 0x7f, 0xd9, 0x93, 0x21, 0x4b, 0xee,
- 0x9c, 0xe4, 0x49, 0x02, 0x98, 0xd3, 0x60, 0x7b, 0x5c, 0xbc, 0xd5, 0x30,
- 0x2f, 0x07, 0xce, 0x44, 0x42, 0xc4, 0x0b, 0x99, 0xfe, 0xe6, 0x9f, 0xfc,
- 0xb0, 0x78, 0x86, 0x51, 0x6d, 0xd1, 0x2c, 0x9d, 0xc6, 0x96, 0xfb, 0x85,
- 0x82, 0xbb, 0x04, 0x2f, 0xf7, 0x62, 0x80, 0xef, 0x62, 0xda, 0x7f, 0xf6,
- 0x0e, 0xac, 0x90, 0xb8, 0x56, 0xbd, 0x79, 0x3f, 0xf2, 0x80, 0x6e, 0xa3,
- 0xd9, 0xb9, 0x0f, 0x5d, 0x3a, 0x07, 0x1d, 0x91, 0x93, 0x86, 0x4b, 0x29,
- 0x4c, 0xe1, 0xdc, 0xb5, 0xe1, 0xe0, 0x33, 0x9d, 0xb3, 0xcb, 0x36, 0x91,
- 0x4b, 0xfe, 0xa1, 0xb4, 0xee, 0xf0, 0xf9,
-};
-
-#if 0
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number:
- 51:3f:b9:74:38:70:b7:34:40:41:8d:30:93:06:99:ff
- Signature Algorithm: sha256WithRSAEncryption
- Issuer: C=US, O=VeriSign, Inc., OU=VeriSign Trust Network, OU=(c) 2006 VeriSign, Inc. - For authorized use only, CN=VeriSign Class 3 Public Primary Certification Authority - G5
- Validity
- Not Before: Oct 31 00:00:00 2013 GMT
- Not After : Oct 30 23:59:59 2023 GMT
- Subject: C=US, O=Symantec Corporation, OU=Symantec Trust Network, CN=Symantec Class 3 Secure Server CA - G4
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:b2:d8:05:ca:1c:74:2d:b5:17:56:39:c5:4a:52:
- 09:96:e8:4b:d8:0c:f1:68:9f:9a:42:28:62:c3:a5:
- 30:53:7e:55:11:82:5b:03:7a:0d:2f:e1:79:04:c9:
- b4:96:77:19:81:01:94:59:f9:bc:f7:7a:99:27:82:
- 2d:b7:83:dd:5a:27:7f:b2:03:7a:9c:53:25:e9:48:
- 1f:46:4f:c8:9d:29:f8:be:79:56:f6:f7:fd:d9:3a:
- 68:da:8b:4b:82:33:41:12:c3:c8:3c:cc:d6:96:7a:
- 84:21:1a:22:04:03:27:17:8b:1c:68:61:93:0f:0e:
- 51:80:33:1d:b4:b5:ce:eb:7e:d0:62:ac:ee:b3:7b:
- 01:74:ef:69:35:eb:ca:d5:3d:a9:ee:97:98:ca:8d:
- aa:44:0e:25:99:4a:15:96:a4:ce:6d:02:54:1f:2a:
- 6a:26:e2:06:3a:63:48:ac:b4:4c:d1:75:93:50:ff:
- 13:2f:d6:da:e1:c6:18:f5:9f:c9:25:5d:f3:00:3a:
- de:26:4d:b4:29:09:cd:0f:3d:23:6f:16:4a:81:16:
- fb:f2:83:10:c3:b8:d6:d8:55:32:3d:f1:bd:0f:bd:
- 8c:52:95:4a:16:97:7a:52:21:63:75:2f:16:f9:c4:
- 66:be:f5:b5:09:d8:ff:27:00:cd:44:7c:6f:4b:3f:
- b0:f7
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Basic Constraints: critical
- CA:TRUE, pathlen:0
- X509v3 CRL Distribution Points:
-
- Full Name:
- URI:http://s1.symcb.com/pca3-g5.crl
-
- X509v3 Key Usage: critical
- Certificate Sign, CRL Sign
- Authority Information Access:
- OCSP - URI:http://s2.symcb.com
-
- X509v3 Certificate Policies:
- Policy: 2.16.840.1.113733.1.7.54
- CPS: http://www.symauth.com/cps
- User Notice:
- Explicit Text: http://www.symauth.com/rpa
-
- X509v3 Subject Alternative Name:
- DirName:/CN=SymantecPKI-1-534
- X509v3 Subject Key Identifier:
- 5F:60:CF:61:90:55:DF:84:43:14:8A:60:2A:B2:F5:7A:F4:43:18:EF
- X509v3 Authority Key Identifier:
- keyid:7F:D3:65:A7:C2:DD:EC:BB:F0:30:09:F3:43:39:FA:02:AF:33:31:33
-
- Signature Algorithm: sha256WithRSAEncryption
- 5e:94:56:49:dd:8e:2d:65:f5:c1:36:51:b6:03:e3:da:9e:73:
- 19:f2:1f:59:ab:58:7e:6c:26:05:2c:fa:81:d7:5c:23:17:22:
- 2c:37:93:f7:86:ec:85:e6:b0:a3:fd:1f:e2:32:a8:45:6f:e1:
- d9:fb:b9:af:d2:70:a0:32:42:65:bf:84:fe:16:2a:8f:3f:c5:
- a6:d6:a3:93:7d:43:e9:74:21:91:35:28:f4:63:e9:2e:ed:f7:
- f5:5c:7f:4b:9a:b5:20:e9:0a:bd:e0:45:10:0c:14:94:9a:5d:
- a5:e3:4b:91:e8:24:9b:46:40:65:f4:22:72:cd:99:f8:88:11:
- f5:f3:7f:e6:33:82:e6:a8:c5:7e:fe:d0:08:e2:25:58:08:71:
- 68:e6:cd:a2:e6:14:de:4e:52:24:2d:fd:e5:79:13:53:e7:5e:
- 2f:2d:4d:1b:6d:40:15:52:2b:f7:87:89:78:12:81:6e:d9:4d:
- aa:2d:78:d4:c2:2c:3d:08:5f:87:91:9e:1f:0e:b0:de:30:52:
- 64:86:89:aa:9d:66:9c:0e:76:0c:80:f2:74:d8:2a:f8:b8:3a:
- ce:d7:d6:0f:11:be:6b:ab:14:f5:bd:41:a0:22:63:89:f1:ba:
- 0f:6f:29:63:66:2d:3f:ac:8c:72:c5:fb:c7:e4:d4:0f:f2:3b:
- 4f:8c:29:c7
------BEGIN CERTIFICATE-----
-MIIFODCCBCCgAwIBAgIQUT+5dDhwtzRAQY0wkwaZ/zANBgkqhkiG9w0BAQsFADCB
-yjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL
-ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJp
-U2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxW
-ZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0
-aG9yaXR5IC0gRzUwHhcNMTMxMDMxMDAwMDAwWhcNMjMxMDMwMjM1OTU5WjB+MQsw
-CQYDVQQGEwJVUzEdMBsGA1UEChMUU3ltYW50ZWMgQ29ycG9yYXRpb24xHzAdBgNV
-BAsTFlN5bWFudGVjIFRydXN0IE5ldHdvcmsxLzAtBgNVBAMTJlN5bWFudGVjIENs
-YXNzIDMgU2VjdXJlIFNlcnZlciBDQSAtIEc0MIIBIjANBgkqhkiG9w0BAQEFAAOC
-AQ8AMIIBCgKCAQEAstgFyhx0LbUXVjnFSlIJluhL2AzxaJ+aQihiw6UwU35VEYJb
-A3oNL+F5BMm0lncZgQGUWfm893qZJ4Itt4PdWid/sgN6nFMl6UgfRk/InSn4vnlW
-9vf92Tpo2otLgjNBEsPIPMzWlnqEIRoiBAMnF4scaGGTDw5RgDMdtLXO637QYqzu
-s3sBdO9pNevK1T2p7peYyo2qRA4lmUoVlqTObQJUHypqJuIGOmNIrLRM0XWTUP8T
-L9ba4cYY9Z/JJV3zADreJk20KQnNDz0jbxZKgRb78oMQw7jW2FUyPfG9D72MUpVK
-Fpd6UiFjdS8W+cRmvvW1Cdj/JwDNRHxvSz+w9wIDAQABo4IBYzCCAV8wEgYDVR0T
-AQH/BAgwBgEB/wIBADAwBgNVHR8EKTAnMCWgI6Ahhh9odHRwOi8vczEuc3ltY2Iu
-Y29tL3BjYTMtZzUuY3JsMA4GA1UdDwEB/wQEAwIBBjAvBggrBgEFBQcBAQQjMCEw
-HwYIKwYBBQUHMAGGE2h0dHA6Ly9zMi5zeW1jYi5jb20wawYDVR0gBGQwYjBgBgpg
-hkgBhvhFAQc2MFIwJgYIKwYBBQUHAgEWGmh0dHA6Ly93d3cuc3ltYXV0aC5jb20v
-Y3BzMCgGCCsGAQUFBwICMBwaGmh0dHA6Ly93d3cuc3ltYXV0aC5jb20vcnBhMCkG
-A1UdEQQiMCCkHjAcMRowGAYDVQQDExFTeW1hbnRlY1BLSS0xLTUzNDAdBgNVHQ4E
-FgQUX2DPYZBV34RDFIpgKrL1evRDGO8wHwYDVR0jBBgwFoAUf9Nlp8Ld7LvwMAnz
-Qzn6Aq8zMTMwDQYJKoZIhvcNAQELBQADggEBAF6UVkndji1l9cE2UbYD49qecxny
-H1mrWH5sJgUs+oHXXCMXIiw3k/eG7IXmsKP9H+IyqEVv4dn7ua/ScKAyQmW/hP4W
-Ko8/xabWo5N9Q+l0IZE1KPRj6S7t9/Vcf0uatSDpCr3gRRAMFJSaXaXjS5HoJJtG
-QGX0InLNmfiIEfXzf+YzguaoxX7+0AjiJVgIcWjmzaLmFN5OUiQt/eV5E1PnXi8t
-TRttQBVSK/eHiXgSgW7ZTaoteNTCLD0IX4eRnh8OsN4wUmSGiaqdZpwOdgyA8nTY
-Kvi4Os7X1g8RvmurFPW9QaAiY4nxug9vKWNmLT+sjHLF+8fk1A/yO0+MKcc=
------END CERTIFICATE-----
-#endif
-static const unsigned char kDERCert43[] = {
- 0x30, 0x82, 0x05, 0x38, 0x30, 0x82, 0x04, 0x20, 0xa0, 0x03, 0x02, 0x01,
- 0x02, 0x02, 0x10, 0x51, 0x3f, 0xb9, 0x74, 0x38, 0x70, 0xb7, 0x34, 0x40,
- 0x41, 0x8d, 0x30, 0x93, 0x06, 0x99, 0xff, 0x30, 0x0d, 0x06, 0x09, 0x2a,
- 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x81,
- 0xca, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
- 0x55, 0x53, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13,
- 0x0e, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49,
- 0x6e, 0x63, 0x2e, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x0b,
- 0x13, 0x16, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x54,
- 0x72, 0x75, 0x73, 0x74, 0x20, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b,
- 0x31, 0x3a, 0x30, 0x38, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x31, 0x28,
- 0x63, 0x29, 0x20, 0x32, 0x30, 0x30, 0x36, 0x20, 0x56, 0x65, 0x72, 0x69,
- 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x20, 0x2d,
- 0x20, 0x46, 0x6f, 0x72, 0x20, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69,
- 0x7a, 0x65, 0x64, 0x20, 0x75, 0x73, 0x65, 0x20, 0x6f, 0x6e, 0x6c, 0x79,
- 0x31, 0x45, 0x30, 0x43, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x3c, 0x56,
- 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x43, 0x6c, 0x61, 0x73,
- 0x73, 0x20, 0x33, 0x20, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x20, 0x50,
- 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69,
- 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74,
- 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x20, 0x2d, 0x20, 0x47, 0x35, 0x30,
- 0x1e, 0x17, 0x0d, 0x31, 0x33, 0x31, 0x30, 0x33, 0x31, 0x30, 0x30, 0x30,
- 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x33, 0x31, 0x30, 0x33, 0x30,
- 0x32, 0x33, 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x7e, 0x31, 0x0b, 0x30,
- 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x1d,
- 0x30, 0x1b, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x14, 0x53, 0x79, 0x6d,
- 0x61, 0x6e, 0x74, 0x65, 0x63, 0x20, 0x43, 0x6f, 0x72, 0x70, 0x6f, 0x72,
- 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55,
- 0x04, 0x0b, 0x13, 0x16, 0x53, 0x79, 0x6d, 0x61, 0x6e, 0x74, 0x65, 0x63,
- 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x4e, 0x65, 0x74, 0x77, 0x6f,
- 0x72, 0x6b, 0x31, 0x2f, 0x30, 0x2d, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
- 0x26, 0x53, 0x79, 0x6d, 0x61, 0x6e, 0x74, 0x65, 0x63, 0x20, 0x43, 0x6c,
- 0x61, 0x73, 0x73, 0x20, 0x33, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65,
- 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x43, 0x41, 0x20, 0x2d,
- 0x20, 0x47, 0x34, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a,
- 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82,
- 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00,
- 0xb2, 0xd8, 0x05, 0xca, 0x1c, 0x74, 0x2d, 0xb5, 0x17, 0x56, 0x39, 0xc5,
- 0x4a, 0x52, 0x09, 0x96, 0xe8, 0x4b, 0xd8, 0x0c, 0xf1, 0x68, 0x9f, 0x9a,
- 0x42, 0x28, 0x62, 0xc3, 0xa5, 0x30, 0x53, 0x7e, 0x55, 0x11, 0x82, 0x5b,
- 0x03, 0x7a, 0x0d, 0x2f, 0xe1, 0x79, 0x04, 0xc9, 0xb4, 0x96, 0x77, 0x19,
- 0x81, 0x01, 0x94, 0x59, 0xf9, 0xbc, 0xf7, 0x7a, 0x99, 0x27, 0x82, 0x2d,
- 0xb7, 0x83, 0xdd, 0x5a, 0x27, 0x7f, 0xb2, 0x03, 0x7a, 0x9c, 0x53, 0x25,
- 0xe9, 0x48, 0x1f, 0x46, 0x4f, 0xc8, 0x9d, 0x29, 0xf8, 0xbe, 0x79, 0x56,
- 0xf6, 0xf7, 0xfd, 0xd9, 0x3a, 0x68, 0xda, 0x8b, 0x4b, 0x82, 0x33, 0x41,
- 0x12, 0xc3, 0xc8, 0x3c, 0xcc, 0xd6, 0x96, 0x7a, 0x84, 0x21, 0x1a, 0x22,
- 0x04, 0x03, 0x27, 0x17, 0x8b, 0x1c, 0x68, 0x61, 0x93, 0x0f, 0x0e, 0x51,
- 0x80, 0x33, 0x1d, 0xb4, 0xb5, 0xce, 0xeb, 0x7e, 0xd0, 0x62, 0xac, 0xee,
- 0xb3, 0x7b, 0x01, 0x74, 0xef, 0x69, 0x35, 0xeb, 0xca, 0xd5, 0x3d, 0xa9,
- 0xee, 0x97, 0x98, 0xca, 0x8d, 0xaa, 0x44, 0x0e, 0x25, 0x99, 0x4a, 0x15,
- 0x96, 0xa4, 0xce, 0x6d, 0x02, 0x54, 0x1f, 0x2a, 0x6a, 0x26, 0xe2, 0x06,
- 0x3a, 0x63, 0x48, 0xac, 0xb4, 0x4c, 0xd1, 0x75, 0x93, 0x50, 0xff, 0x13,
- 0x2f, 0xd6, 0xda, 0xe1, 0xc6, 0x18, 0xf5, 0x9f, 0xc9, 0x25, 0x5d, 0xf3,
- 0x00, 0x3a, 0xde, 0x26, 0x4d, 0xb4, 0x29, 0x09, 0xcd, 0x0f, 0x3d, 0x23,
- 0x6f, 0x16, 0x4a, 0x81, 0x16, 0xfb, 0xf2, 0x83, 0x10, 0xc3, 0xb8, 0xd6,
- 0xd8, 0x55, 0x32, 0x3d, 0xf1, 0xbd, 0x0f, 0xbd, 0x8c, 0x52, 0x95, 0x4a,
- 0x16, 0x97, 0x7a, 0x52, 0x21, 0x63, 0x75, 0x2f, 0x16, 0xf9, 0xc4, 0x66,
- 0xbe, 0xf5, 0xb5, 0x09, 0xd8, 0xff, 0x27, 0x00, 0xcd, 0x44, 0x7c, 0x6f,
- 0x4b, 0x3f, 0xb0, 0xf7, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01,
- 0x63, 0x30, 0x82, 0x01, 0x5f, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13,
- 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01,
- 0x00, 0x30, 0x30, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x29, 0x30, 0x27,
- 0x30, 0x25, 0xa0, 0x23, 0xa0, 0x21, 0x86, 0x1f, 0x68, 0x74, 0x74, 0x70,
- 0x3a, 0x2f, 0x2f, 0x73, 0x31, 0x2e, 0x73, 0x79, 0x6d, 0x63, 0x62, 0x2e,
- 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x63, 0x61, 0x33, 0x2d, 0x67, 0x35, 0x2e,
- 0x63, 0x72, 0x6c, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01,
- 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x2f, 0x06, 0x08, 0x2b,
- 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x23, 0x30, 0x21, 0x30,
- 0x1f, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86,
- 0x13, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x73, 0x32, 0x2e, 0x73,
- 0x79, 0x6d, 0x63, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x6b, 0x06, 0x03,
- 0x55, 0x1d, 0x20, 0x04, 0x64, 0x30, 0x62, 0x30, 0x60, 0x06, 0x0a, 0x60,
- 0x86, 0x48, 0x01, 0x86, 0xf8, 0x45, 0x01, 0x07, 0x36, 0x30, 0x52, 0x30,
- 0x26, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16,
- 0x1a, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e,
- 0x73, 0x79, 0x6d, 0x61, 0x75, 0x74, 0x68, 0x2e, 0x63, 0x6f, 0x6d, 0x2f,
- 0x63, 0x70, 0x73, 0x30, 0x28, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05,
- 0x07, 0x02, 0x02, 0x30, 0x1c, 0x1a, 0x1a, 0x68, 0x74, 0x74, 0x70, 0x3a,
- 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x73, 0x79, 0x6d, 0x61, 0x75, 0x74,
- 0x68, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x70, 0x61, 0x30, 0x29, 0x06,
- 0x03, 0x55, 0x1d, 0x11, 0x04, 0x22, 0x30, 0x20, 0xa4, 0x1e, 0x30, 0x1c,
- 0x31, 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x11, 0x53,
- 0x79, 0x6d, 0x61, 0x6e, 0x74, 0x65, 0x63, 0x50, 0x4b, 0x49, 0x2d, 0x31,
- 0x2d, 0x35, 0x33, 0x34, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04,
- 0x16, 0x04, 0x14, 0x5f, 0x60, 0xcf, 0x61, 0x90, 0x55, 0xdf, 0x84, 0x43,
- 0x14, 0x8a, 0x60, 0x2a, 0xb2, 0xf5, 0x7a, 0xf4, 0x43, 0x18, 0xef, 0x30,
- 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14,
- 0x7f, 0xd3, 0x65, 0xa7, 0xc2, 0xdd, 0xec, 0xbb, 0xf0, 0x30, 0x09, 0xf3,
- 0x43, 0x39, 0xfa, 0x02, 0xaf, 0x33, 0x31, 0x33, 0x30, 0x0d, 0x06, 0x09,
- 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03,
- 0x82, 0x01, 0x01, 0x00, 0x5e, 0x94, 0x56, 0x49, 0xdd, 0x8e, 0x2d, 0x65,
- 0xf5, 0xc1, 0x36, 0x51, 0xb6, 0x03, 0xe3, 0xda, 0x9e, 0x73, 0x19, 0xf2,
- 0x1f, 0x59, 0xab, 0x58, 0x7e, 0x6c, 0x26, 0x05, 0x2c, 0xfa, 0x81, 0xd7,
- 0x5c, 0x23, 0x17, 0x22, 0x2c, 0x37, 0x93, 0xf7, 0x86, 0xec, 0x85, 0xe6,
- 0xb0, 0xa3, 0xfd, 0x1f, 0xe2, 0x32, 0xa8, 0x45, 0x6f, 0xe1, 0xd9, 0xfb,
- 0xb9, 0xaf, 0xd2, 0x70, 0xa0, 0x32, 0x42, 0x65, 0xbf, 0x84, 0xfe, 0x16,
- 0x2a, 0x8f, 0x3f, 0xc5, 0xa6, 0xd6, 0xa3, 0x93, 0x7d, 0x43, 0xe9, 0x74,
- 0x21, 0x91, 0x35, 0x28, 0xf4, 0x63, 0xe9, 0x2e, 0xed, 0xf7, 0xf5, 0x5c,
- 0x7f, 0x4b, 0x9a, 0xb5, 0x20, 0xe9, 0x0a, 0xbd, 0xe0, 0x45, 0x10, 0x0c,
- 0x14, 0x94, 0x9a, 0x5d, 0xa5, 0xe3, 0x4b, 0x91, 0xe8, 0x24, 0x9b, 0x46,
- 0x40, 0x65, 0xf4, 0x22, 0x72, 0xcd, 0x99, 0xf8, 0x88, 0x11, 0xf5, 0xf3,
- 0x7f, 0xe6, 0x33, 0x82, 0xe6, 0xa8, 0xc5, 0x7e, 0xfe, 0xd0, 0x08, 0xe2,
- 0x25, 0x58, 0x08, 0x71, 0x68, 0xe6, 0xcd, 0xa2, 0xe6, 0x14, 0xde, 0x4e,
- 0x52, 0x24, 0x2d, 0xfd, 0xe5, 0x79, 0x13, 0x53, 0xe7, 0x5e, 0x2f, 0x2d,
- 0x4d, 0x1b, 0x6d, 0x40, 0x15, 0x52, 0x2b, 0xf7, 0x87, 0x89, 0x78, 0x12,
- 0x81, 0x6e, 0xd9, 0x4d, 0xaa, 0x2d, 0x78, 0xd4, 0xc2, 0x2c, 0x3d, 0x08,
- 0x5f, 0x87, 0x91, 0x9e, 0x1f, 0x0e, 0xb0, 0xde, 0x30, 0x52, 0x64, 0x86,
- 0x89, 0xaa, 0x9d, 0x66, 0x9c, 0x0e, 0x76, 0x0c, 0x80, 0xf2, 0x74, 0xd8,
- 0x2a, 0xf8, 0xb8, 0x3a, 0xce, 0xd7, 0xd6, 0x0f, 0x11, 0xbe, 0x6b, 0xab,
- 0x14, 0xf5, 0xbd, 0x41, 0xa0, 0x22, 0x63, 0x89, 0xf1, 0xba, 0x0f, 0x6f,
- 0x29, 0x63, 0x66, 0x2d, 0x3f, 0xac, 0x8c, 0x72, 0xc5, 0xfb, 0xc7, 0xe4,
- 0xd4, 0x0f, 0xf2, 0x3b, 0x4f, 0x8c, 0x29, 0xc7,
-};
-
-#if 0
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number: 120036009 (0x7279aa9)
- Signature Algorithm: sha256WithRSAEncryption
- Issuer: C=IE, O=Baltimore, OU=CyberTrust, CN=Baltimore CyberTrust Root
- Validity
- Not Before: Dec 19 20:07:32 2013 GMT
- Not After : Dec 19 20:06:55 2017 GMT
- Subject: C=US, ST=Washington, L=Redmond, O=Microsoft Corporation, OU=Microsoft IT, CN=Microsoft IT SSL SHA2
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (4096 bit)
- Modulus:
- 00:d1:e8:37:a7:76:8a:70:4b:19:f0:20:37:09:24:
- 37:7f:ea:fb:78:e6:05:ba:6a:ad:4e:27:0d:fc:72:
- 6a:d9:6c:21:c4:64:11:95:73:10:0a:5c:25:7b:88:
- 6c:94:04:fd:c7:db:ae:7b:dc:4a:08:b3:3e:16:f1:
- d0:ad:db:30:6d:d7:1a:1e:52:b5:3d:f0:47:19:03:
- e2:7d:a6:bd:57:13:3f:54:ea:3a:a3:b1:77:fc:42:
- f0:63:49:6a:91:80:2e:30:49:c0:8a:eb:2b:af:fe:
- 3a:eb:07:5d:06:f7:e9:fd:84:0e:91:bd:09:20:29:
- e8:6e:5d:09:ce:15:d3:e7:ef:db:50:eb:44:ef:18:
- 57:ab:04:1d:bc:31:f9:f7:7b:2a:13:cf:d1:3d:51:
- af:1b:c5:b5:7b:e7:b0:fc:53:bb:9a:e7:63:de:41:
- 33:b6:47:24:69:5d:b8:46:a7:ff:ad:ab:df:4f:7a:
- 78:25:27:21:26:34:ca:02:6e:37:51:f0:ed:58:1a:
- 60:94:f6:c4:93:d8:dd:30:24:25:d7:1c:eb:19:94:
- 35:5d:93:b2:ae:aa:29:83:73:c4:74:59:05:52:67:
- 9d:da:67:51:39:05:3a:36:ea:f2:1e:76:2b:14:ae:
- ec:3d:f9:14:99:8b:07:6e:bc:e7:0c:56:de:ac:be:
- ae:db:75:32:90:9e:63:bd:74:bf:e0:0a:ca:f8:34:
- 96:67:84:cd:d1:42:38:78:c7:99:b6:0c:ce:b6:0f:
- e9:1b:cb:f4:59:be:11:0e:cb:2c:32:c8:fa:83:29:
- 64:79:3c:8b:4b:f0:32:74:6c:f3:93:b8:96:6b:5d:
- 57:5a:68:c1:cc:0c:79:8a:19:de:f5:49:02:5e:08:
- 80:01:89:0c:32:cd:d2:d6:96:d5:4b:a0:f3:ec:bf:
- ab:f4:7d:b3:a1:b9:7c:da:4e:d7:e5:b7:ac:b9:f2:
- 25:5f:01:cb:8c:96:a8:28:ae:c1:33:5a:f6:3f:08:
- 90:dc:eb:ff:39:d8:26:c8:12:9d:1c:9a:aa:a9:c0:
- 16:8e:86:ed:67:52:96:00:7f:0d:92:3d:3d:d9:70:
- 36:e5:ea:42:6f:1f:ae:95:e5:5b:5d:f8:d0:3a:c7:
- d4:de:77:86:d0:fc:9e:4e:e2:e2:b8:a9:68:37:09:
- c4:39:e3:85:b8:89:f3:1f:6e:b7:6d:1f:4a:2f:18:
- 09:6f:de:4a:01:8f:14:c9:b7:a6:ee:a7:63:9f:33:
- a4:54:7c:42:83:68:b8:a5:df:bf:ec:b9:1a:5d:13:
- 3b:d9:ad:68:fd:20:0a:55:91:21:64:f9:d7:13:01:
- a0:08:5d:59:89:1b:44:af:a4:ac:c7:05:10:fa:41:
- 4a:a8:fb
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Basic Constraints: critical
- CA:TRUE, pathlen:0
- X509v3 Certificate Policies:
- Policy: 1.3.6.1.4.1.6334.1.0
- CPS: http://cybertrust.omniroot.com/repository.cfm
-
- X509v3 Key Usage: critical
- Digital Signature, Certificate Sign, CRL Sign
- X509v3 Extended Key Usage:
- TLS Web Server Authentication, TLS Web Client Authentication
- X509v3 Authority Key Identifier:
- keyid:E5:9D:59:30:82:47:58:CC:AC:FA:08:54:36:86:7B:3A:B5:04:4D:F0
-
- X509v3 CRL Distribution Points:
-
- Full Name:
- URI:http://cdp1.public-trust.com/CRL/Omniroot2025.crl
-
- X509v3 Subject Key Identifier:
- 51:AF:24:26:9C:F4:68:22:57:80:26:2B:3B:46:62:15:7B:1E:CC:A5
- Signature Algorithm: sha256WithRSAEncryption
- 76:85:c5:23:31:1f:b4:73:ea:a0:bc:a5:ed:df:45:43:6a:7f:
- 69:20:1b:80:b2:fb:1c:dd:aa:7f:88:d3:31:41:36:f7:fb:fb:
- 6b:ad:98:8c:78:1f:9d:11:67:3a:cd:4b:ec:a8:bc:9d:15:19:
- c4:3b:0b:a7:93:ce:e8:fc:9d:5b:e8:1f:cb:56:ae:76:43:2b:
- c7:13:51:77:41:a8:66:4c:5f:a7:d1:d7:aa:75:c5:1b:29:4c:
- c9:f4:6d:a1:5e:a1:85:93:16:c2:cb:3b:ab:14:7d:44:fd:da:
- 25:29:86:2a:fe:63:20:ca:d2:0b:c2:34:15:bb:af:5b:7f:8a:
- e0:aa:ed:45:a6:ea:79:db:d8:35:66:54:43:de:37:33:d1:e4:
- e0:cd:57:ca:71:b0:7d:e9:16:77:64:e8:59:97:b9:d5:2e:d1:
- b4:91:da:77:71:f3:4a:0f:48:d2:34:99:60:95:37:ac:1f:01:
- cd:10:9d:e8:2a:a5:20:c7:50:9b:b3:6c:49:78:2b:58:92:64:
- 89:b8:95:36:a8:34:aa:f0:41:d2:95:5a:24:54:97:4d:6e:05:
- c4:95:ad:c4:7a:a3:39:fb:79:06:8a:9b:a6:4f:d9:22:fa:44:
- 4e:36:f3:c9:0f:a6:39:e7:80:b2:5e:bf:bd:39:d1:46:e5:55:
- 47:db:bc:6e
------BEGIN CERTIFICATE-----
-MIIFhjCCBG6gAwIBAgIEByeaqTANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJJ
-RTESMBAGA1UEChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYD
-VQQDExlCYWx0aW1vcmUgQ3liZXJUcnVzdCBSb290MB4XDTEzMTIxOTIwMDczMloX
-DTE3MTIxOTIwMDY1NVowgYsxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5n
-dG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9y
-YXRpb24xFTATBgNVBAsTDE1pY3Jvc29mdCBJVDEeMBwGA1UEAxMVTWljcm9zb2Z0
-IElUIFNTTCBTSEEyMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA0eg3
-p3aKcEsZ8CA3CSQ3f+r7eOYFumqtTicN/HJq2WwhxGQRlXMQClwle4hslAT9x9uu
-e9xKCLM+FvHQrdswbdcaHlK1PfBHGQPifaa9VxM/VOo6o7F3/ELwY0lqkYAuMEnA
-iusrr/466wddBvfp/YQOkb0JICnobl0JzhXT5+/bUOtE7xhXqwQdvDH593sqE8/R
-PVGvG8W1e+ew/FO7mudj3kEztkckaV24Rqf/ravfT3p4JSchJjTKAm43UfDtWBpg
-lPbEk9jdMCQl1xzrGZQ1XZOyrqopg3PEdFkFUmed2mdROQU6NuryHnYrFK7sPfkU
-mYsHbrznDFberL6u23UykJ5jvXS/4ArK+DSWZ4TN0UI4eMeZtgzOtg/pG8v0Wb4R
-DsssMsj6gylkeTyLS/AydGzzk7iWa11XWmjBzAx5ihne9UkCXgiAAYkMMs3S1pbV
-S6Dz7L+r9H2zobl82k7X5besufIlXwHLjJaoKK7BM1r2PwiQ3Ov/OdgmyBKdHJqq
-qcAWjobtZ1KWAH8Nkj092XA25epCbx+uleVbXfjQOsfU3neG0PyeTuLiuKloNwnE
-OeOFuInzH263bR9KLxgJb95KAY8Uybem7qdjnzOkVHxCg2i4pd+/7LkaXRM72a1o
-/SAKVZEhZPnXEwGgCF1ZiRtEr6SsxwUQ+kFKqPsCAwEAAaOCASAwggEcMBIGA1Ud
-EwEB/wQIMAYBAf8CAQAwUwYDVR0gBEwwSjBIBgkrBgEEAbE+AQAwOzA5BggrBgEF
-BQcCARYtaHR0cDovL2N5YmVydHJ1c3Qub21uaXJvb3QuY29tL3JlcG9zaXRvcnku
-Y2ZtMA4GA1UdDwEB/wQEAwIBhjAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUH
-AwIwHwYDVR0jBBgwFoAU5Z1ZMIJHWMys+ghUNoZ7OrUETfAwQgYDVR0fBDswOTA3
-oDWgM4YxaHR0cDovL2NkcDEucHVibGljLXRydXN0LmNvbS9DUkwvT21uaXJvb3Qy
-MDI1LmNybDAdBgNVHQ4EFgQUUa8kJpz0aCJXgCYrO0ZiFXsezKUwDQYJKoZIhvcN
-AQELBQADggEBAHaFxSMxH7Rz6qC8pe3fRUNqf2kgG4Cy+xzdqn+I0zFBNvf7+2ut
-mIx4H50RZzrNS+yovJ0VGcQ7C6eTzuj8nVvoH8tWrnZDK8cTUXdBqGZMX6fR16p1
-xRspTMn0baFeoYWTFsLLO6sUfUT92iUphir+YyDK0gvCNBW7r1t/iuCq7UWm6nnb
-2DVmVEPeNzPR5ODNV8pxsH3pFndk6FmXudUu0bSR2ndx80oPSNI0mWCVN6wfAc0Q
-negqpSDHUJuzbEl4K1iSZIm4lTaoNKrwQdKVWiRUl01uBcSVrcR6ozn7eQaKm6ZP
-2SL6RE4288kPpjnngLJev7050UblVUfbvG4=
------END CERTIFICATE-----
-#endif
-static const unsigned char kDERCert44[] = {
- 0x30, 0x82, 0x05, 0x86, 0x30, 0x82, 0x04, 0x6e, 0xa0, 0x03, 0x02, 0x01,
- 0x02, 0x02, 0x04, 0x07, 0x27, 0x9a, 0xa9, 0x30, 0x0d, 0x06, 0x09, 0x2a,
- 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x5a,
- 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x49,
- 0x45, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x09,
- 0x42, 0x61, 0x6c, 0x74, 0x69, 0x6d, 0x6f, 0x72, 0x65, 0x31, 0x13, 0x30,
- 0x11, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x0a, 0x43, 0x79, 0x62, 0x65,
- 0x72, 0x54, 0x72, 0x75, 0x73, 0x74, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03,
- 0x55, 0x04, 0x03, 0x13, 0x19, 0x42, 0x61, 0x6c, 0x74, 0x69, 0x6d, 0x6f,
- 0x72, 0x65, 0x20, 0x43, 0x79, 0x62, 0x65, 0x72, 0x54, 0x72, 0x75, 0x73,
- 0x74, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x33,
- 0x31, 0x32, 0x31, 0x39, 0x32, 0x30, 0x30, 0x37, 0x33, 0x32, 0x5a, 0x17,
- 0x0d, 0x31, 0x37, 0x31, 0x32, 0x31, 0x39, 0x32, 0x30, 0x30, 0x36, 0x35,
- 0x35, 0x5a, 0x30, 0x81, 0x8b, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55,
- 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03,
- 0x55, 0x04, 0x08, 0x13, 0x0a, 0x57, 0x61, 0x73, 0x68, 0x69, 0x6e, 0x67,
- 0x74, 0x6f, 0x6e, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x07,
- 0x13, 0x07, 0x52, 0x65, 0x64, 0x6d, 0x6f, 0x6e, 0x64, 0x31, 0x1e, 0x30,
- 0x1c, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x15, 0x4d, 0x69, 0x63, 0x72,
- 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x20, 0x43, 0x6f, 0x72, 0x70, 0x6f, 0x72,
- 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55,
- 0x04, 0x0b, 0x13, 0x0c, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66,
- 0x74, 0x20, 0x49, 0x54, 0x31, 0x1e, 0x30, 0x1c, 0x06, 0x03, 0x55, 0x04,
- 0x03, 0x13, 0x15, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74,
- 0x20, 0x49, 0x54, 0x20, 0x53, 0x53, 0x4c, 0x20, 0x53, 0x48, 0x41, 0x32,
- 0x30, 0x82, 0x02, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
- 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x02, 0x0f, 0x00,
- 0x30, 0x82, 0x02, 0x0a, 0x02, 0x82, 0x02, 0x01, 0x00, 0xd1, 0xe8, 0x37,
- 0xa7, 0x76, 0x8a, 0x70, 0x4b, 0x19, 0xf0, 0x20, 0x37, 0x09, 0x24, 0x37,
- 0x7f, 0xea, 0xfb, 0x78, 0xe6, 0x05, 0xba, 0x6a, 0xad, 0x4e, 0x27, 0x0d,
- 0xfc, 0x72, 0x6a, 0xd9, 0x6c, 0x21, 0xc4, 0x64, 0x11, 0x95, 0x73, 0x10,
- 0x0a, 0x5c, 0x25, 0x7b, 0x88, 0x6c, 0x94, 0x04, 0xfd, 0xc7, 0xdb, 0xae,
- 0x7b, 0xdc, 0x4a, 0x08, 0xb3, 0x3e, 0x16, 0xf1, 0xd0, 0xad, 0xdb, 0x30,
- 0x6d, 0xd7, 0x1a, 0x1e, 0x52, 0xb5, 0x3d, 0xf0, 0x47, 0x19, 0x03, 0xe2,
- 0x7d, 0xa6, 0xbd, 0x57, 0x13, 0x3f, 0x54, 0xea, 0x3a, 0xa3, 0xb1, 0x77,
- 0xfc, 0x42, 0xf0, 0x63, 0x49, 0x6a, 0x91, 0x80, 0x2e, 0x30, 0x49, 0xc0,
- 0x8a, 0xeb, 0x2b, 0xaf, 0xfe, 0x3a, 0xeb, 0x07, 0x5d, 0x06, 0xf7, 0xe9,
- 0xfd, 0x84, 0x0e, 0x91, 0xbd, 0x09, 0x20, 0x29, 0xe8, 0x6e, 0x5d, 0x09,
- 0xce, 0x15, 0xd3, 0xe7, 0xef, 0xdb, 0x50, 0xeb, 0x44, 0xef, 0x18, 0x57,
- 0xab, 0x04, 0x1d, 0xbc, 0x31, 0xf9, 0xf7, 0x7b, 0x2a, 0x13, 0xcf, 0xd1,
- 0x3d, 0x51, 0xaf, 0x1b, 0xc5, 0xb5, 0x7b, 0xe7, 0xb0, 0xfc, 0x53, 0xbb,
- 0x9a, 0xe7, 0x63, 0xde, 0x41, 0x33, 0xb6, 0x47, 0x24, 0x69, 0x5d, 0xb8,
- 0x46, 0xa7, 0xff, 0xad, 0xab, 0xdf, 0x4f, 0x7a, 0x78, 0x25, 0x27, 0x21,
- 0x26, 0x34, 0xca, 0x02, 0x6e, 0x37, 0x51, 0xf0, 0xed, 0x58, 0x1a, 0x60,
- 0x94, 0xf6, 0xc4, 0x93, 0xd8, 0xdd, 0x30, 0x24, 0x25, 0xd7, 0x1c, 0xeb,
- 0x19, 0x94, 0x35, 0x5d, 0x93, 0xb2, 0xae, 0xaa, 0x29, 0x83, 0x73, 0xc4,
- 0x74, 0x59, 0x05, 0x52, 0x67, 0x9d, 0xda, 0x67, 0x51, 0x39, 0x05, 0x3a,
- 0x36, 0xea, 0xf2, 0x1e, 0x76, 0x2b, 0x14, 0xae, 0xec, 0x3d, 0xf9, 0x14,
- 0x99, 0x8b, 0x07, 0x6e, 0xbc, 0xe7, 0x0c, 0x56, 0xde, 0xac, 0xbe, 0xae,
- 0xdb, 0x75, 0x32, 0x90, 0x9e, 0x63, 0xbd, 0x74, 0xbf, 0xe0, 0x0a, 0xca,
- 0xf8, 0x34, 0x96, 0x67, 0x84, 0xcd, 0xd1, 0x42, 0x38, 0x78, 0xc7, 0x99,
- 0xb6, 0x0c, 0xce, 0xb6, 0x0f, 0xe9, 0x1b, 0xcb, 0xf4, 0x59, 0xbe, 0x11,
- 0x0e, 0xcb, 0x2c, 0x32, 0xc8, 0xfa, 0x83, 0x29, 0x64, 0x79, 0x3c, 0x8b,
- 0x4b, 0xf0, 0x32, 0x74, 0x6c, 0xf3, 0x93, 0xb8, 0x96, 0x6b, 0x5d, 0x57,
- 0x5a, 0x68, 0xc1, 0xcc, 0x0c, 0x79, 0x8a, 0x19, 0xde, 0xf5, 0x49, 0x02,
- 0x5e, 0x08, 0x80, 0x01, 0x89, 0x0c, 0x32, 0xcd, 0xd2, 0xd6, 0x96, 0xd5,
- 0x4b, 0xa0, 0xf3, 0xec, 0xbf, 0xab, 0xf4, 0x7d, 0xb3, 0xa1, 0xb9, 0x7c,
- 0xda, 0x4e, 0xd7, 0xe5, 0xb7, 0xac, 0xb9, 0xf2, 0x25, 0x5f, 0x01, 0xcb,
- 0x8c, 0x96, 0xa8, 0x28, 0xae, 0xc1, 0x33, 0x5a, 0xf6, 0x3f, 0x08, 0x90,
- 0xdc, 0xeb, 0xff, 0x39, 0xd8, 0x26, 0xc8, 0x12, 0x9d, 0x1c, 0x9a, 0xaa,
- 0xa9, 0xc0, 0x16, 0x8e, 0x86, 0xed, 0x67, 0x52, 0x96, 0x00, 0x7f, 0x0d,
- 0x92, 0x3d, 0x3d, 0xd9, 0x70, 0x36, 0xe5, 0xea, 0x42, 0x6f, 0x1f, 0xae,
- 0x95, 0xe5, 0x5b, 0x5d, 0xf8, 0xd0, 0x3a, 0xc7, 0xd4, 0xde, 0x77, 0x86,
- 0xd0, 0xfc, 0x9e, 0x4e, 0xe2, 0xe2, 0xb8, 0xa9, 0x68, 0x37, 0x09, 0xc4,
- 0x39, 0xe3, 0x85, 0xb8, 0x89, 0xf3, 0x1f, 0x6e, 0xb7, 0x6d, 0x1f, 0x4a,
- 0x2f, 0x18, 0x09, 0x6f, 0xde, 0x4a, 0x01, 0x8f, 0x14, 0xc9, 0xb7, 0xa6,
- 0xee, 0xa7, 0x63, 0x9f, 0x33, 0xa4, 0x54, 0x7c, 0x42, 0x83, 0x68, 0xb8,
- 0xa5, 0xdf, 0xbf, 0xec, 0xb9, 0x1a, 0x5d, 0x13, 0x3b, 0xd9, 0xad, 0x68,
- 0xfd, 0x20, 0x0a, 0x55, 0x91, 0x21, 0x64, 0xf9, 0xd7, 0x13, 0x01, 0xa0,
- 0x08, 0x5d, 0x59, 0x89, 0x1b, 0x44, 0xaf, 0xa4, 0xac, 0xc7, 0x05, 0x10,
- 0xfa, 0x41, 0x4a, 0xa8, 0xfb, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82,
- 0x01, 0x20, 0x30, 0x82, 0x01, 0x1c, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d,
- 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02,
- 0x01, 0x00, 0x30, 0x53, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x4c, 0x30,
- 0x4a, 0x30, 0x48, 0x06, 0x09, 0x2b, 0x06, 0x01, 0x04, 0x01, 0xb1, 0x3e,
- 0x01, 0x00, 0x30, 0x3b, 0x30, 0x39, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05,
- 0x05, 0x07, 0x02, 0x01, 0x16, 0x2d, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f,
- 0x2f, 0x63, 0x79, 0x62, 0x65, 0x72, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e,
- 0x6f, 0x6d, 0x6e, 0x69, 0x72, 0x6f, 0x6f, 0x74, 0x2e, 0x63, 0x6f, 0x6d,
- 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x2e,
- 0x63, 0x66, 0x6d, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01,
- 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x86, 0x30, 0x1d, 0x06, 0x03, 0x55,
- 0x1d, 0x25, 0x04, 0x16, 0x30, 0x14, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05,
- 0x05, 0x07, 0x03, 0x01, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
- 0x03, 0x02, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30,
- 0x16, 0x80, 0x14, 0xe5, 0x9d, 0x59, 0x30, 0x82, 0x47, 0x58, 0xcc, 0xac,
- 0xfa, 0x08, 0x54, 0x36, 0x86, 0x7b, 0x3a, 0xb5, 0x04, 0x4d, 0xf0, 0x30,
- 0x42, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x3b, 0x30, 0x39, 0x30, 0x37,
- 0xa0, 0x35, 0xa0, 0x33, 0x86, 0x31, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f,
- 0x2f, 0x63, 0x64, 0x70, 0x31, 0x2e, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63,
- 0x2d, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x43,
- 0x52, 0x4c, 0x2f, 0x4f, 0x6d, 0x6e, 0x69, 0x72, 0x6f, 0x6f, 0x74, 0x32,
- 0x30, 0x32, 0x35, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x1d, 0x06, 0x03, 0x55,
- 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x51, 0xaf, 0x24, 0x26, 0x9c, 0xf4,
- 0x68, 0x22, 0x57, 0x80, 0x26, 0x2b, 0x3b, 0x46, 0x62, 0x15, 0x7b, 0x1e,
- 0xcc, 0xa5, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
- 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x76, 0x85,
- 0xc5, 0x23, 0x31, 0x1f, 0xb4, 0x73, 0xea, 0xa0, 0xbc, 0xa5, 0xed, 0xdf,
- 0x45, 0x43, 0x6a, 0x7f, 0x69, 0x20, 0x1b, 0x80, 0xb2, 0xfb, 0x1c, 0xdd,
- 0xaa, 0x7f, 0x88, 0xd3, 0x31, 0x41, 0x36, 0xf7, 0xfb, 0xfb, 0x6b, 0xad,
- 0x98, 0x8c, 0x78, 0x1f, 0x9d, 0x11, 0x67, 0x3a, 0xcd, 0x4b, 0xec, 0xa8,
- 0xbc, 0x9d, 0x15, 0x19, 0xc4, 0x3b, 0x0b, 0xa7, 0x93, 0xce, 0xe8, 0xfc,
- 0x9d, 0x5b, 0xe8, 0x1f, 0xcb, 0x56, 0xae, 0x76, 0x43, 0x2b, 0xc7, 0x13,
- 0x51, 0x77, 0x41, 0xa8, 0x66, 0x4c, 0x5f, 0xa7, 0xd1, 0xd7, 0xaa, 0x75,
- 0xc5, 0x1b, 0x29, 0x4c, 0xc9, 0xf4, 0x6d, 0xa1, 0x5e, 0xa1, 0x85, 0x93,
- 0x16, 0xc2, 0xcb, 0x3b, 0xab, 0x14, 0x7d, 0x44, 0xfd, 0xda, 0x25, 0x29,
- 0x86, 0x2a, 0xfe, 0x63, 0x20, 0xca, 0xd2, 0x0b, 0xc2, 0x34, 0x15, 0xbb,
- 0xaf, 0x5b, 0x7f, 0x8a, 0xe0, 0xaa, 0xed, 0x45, 0xa6, 0xea, 0x79, 0xdb,
- 0xd8, 0x35, 0x66, 0x54, 0x43, 0xde, 0x37, 0x33, 0xd1, 0xe4, 0xe0, 0xcd,
- 0x57, 0xca, 0x71, 0xb0, 0x7d, 0xe9, 0x16, 0x77, 0x64, 0xe8, 0x59, 0x97,
- 0xb9, 0xd5, 0x2e, 0xd1, 0xb4, 0x91, 0xda, 0x77, 0x71, 0xf3, 0x4a, 0x0f,
- 0x48, 0xd2, 0x34, 0x99, 0x60, 0x95, 0x37, 0xac, 0x1f, 0x01, 0xcd, 0x10,
- 0x9d, 0xe8, 0x2a, 0xa5, 0x20, 0xc7, 0x50, 0x9b, 0xb3, 0x6c, 0x49, 0x78,
- 0x2b, 0x58, 0x92, 0x64, 0x89, 0xb8, 0x95, 0x36, 0xa8, 0x34, 0xaa, 0xf0,
- 0x41, 0xd2, 0x95, 0x5a, 0x24, 0x54, 0x97, 0x4d, 0x6e, 0x05, 0xc4, 0x95,
- 0xad, 0xc4, 0x7a, 0xa3, 0x39, 0xfb, 0x79, 0x06, 0x8a, 0x9b, 0xa6, 0x4f,
- 0xd9, 0x22, 0xfa, 0x44, 0x4e, 0x36, 0xf3, 0xc9, 0x0f, 0xa6, 0x39, 0xe7,
- 0x80, 0xb2, 0x5e, 0xbf, 0xbd, 0x39, 0xd1, 0x46, 0xe5, 0x55, 0x47, 0xdb,
- 0xbc, 0x6e,
-};
-
-#if 0
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number:
- 67:3f:33:4f:21:53:36:52:c3:5e:15:d2:fd:b3:02:0f
- Signature Algorithm: sha1WithRSAEncryption
- Issuer: C=CN, O=WoSign CA Limited, CN=Certification Authority of WoSign
- Validity
- Not Before: Aug 8 01:00:05 2009 GMT
- Not After : Aug 8 01:00:05 2024 GMT
- Subject: C=CN, O=WoSign CA Limited, CN=WoSign Class 3 OV Server CA
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:bc:89:be:61:51:53:c8:2b:96:75:b3:5a:d3:0e:
- 34:fe:4a:c2:9f:a3:18:83:a2:ac:e3:2e:5e:93:79:
- 0b:13:49:5e:93:b2:8f:84:10:ed:91:8f:82:ba:ad:
- 67:df:33:1b:ae:84:f2:55:b0:5b:f4:b3:9e:bc:e6:
- 04:0f:1d:ef:04:5a:a8:0b:ec:12:6d:56:19:64:70:
- 49:0f:57:92:f3:5f:21:a6:4d:b4:d2:96:2b:3c:32:
- b3:ef:8f:59:0b:14:ba:6e:a2:9e:71:db:f2:88:3f:
- 28:3b:ec:ce:be:47:ac:45:c7:8a:9e:fa:61:93:c5:
- 49:17:b6:46:b6:f7:99:16:8c:1c:6e:31:ae:69:ce:
- ed:c6:24:92:70:a1:cb:96:c3:6c:16:d0:ee:cc:4f:
- 86:33:b3:41:e6:3d:3d:db:0e:8c:33:74:bb:c3:fc:
- 0b:a7:fc:d1:71:e2:c1:0c:d4:f7:ba:3e:80:90:d4:
- 48:eb:a2:83:70:d8:db:30:07:29:89:f9:81:21:2c:
- ff:eb:47:f6:7a:6d:43:96:67:17:3e:f3:e2:73:51:
- c7:76:1e:e9:1c:a0:ec:11:1a:b1:cf:1e:2d:9c:55:
- ee:3b:c6:2d:ae:dc:66:65:91:a2:66:9c:ac:82:f1:
- a4:17:b5:d7:43:83:c3:88:a0:64:de:ca:72:45:dc:
- 38:fb
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Key Usage: critical
- Certificate Sign, CRL Sign
- X509v3 Extended Key Usage:
- TLS Web Client Authentication, TLS Web Server Authentication
- X509v3 Basic Constraints: critical
- CA:TRUE, pathlen:0
- X509v3 CRL Distribution Points:
-
- Full Name:
- URI:http://crls1.wosign.com/ca1.crl
-
- Authority Information Access:
- OCSP - URI:http://ocsp1.wosign.com/ca1
- CA Issuers - URI:http://aia1.wosign.com/ca1-class3-server.cer
-
- X509v3 Subject Key Identifier:
- 62:2E:81:D9:E3:42:79:14:A3:CD:D9:54:8A:6E:F8:DE:95:AA:8F:98
- X509v3 Authority Key Identifier:
- keyid:E1:66:CF:0E:D1:F1:B3:4B:B7:06:20:14:FE:87:12:D5:F6:FE:FB:3E
-
- X509v3 Certificate Policies:
- Policy: 1.3.6.1.4.1.36305.1.3.2
- CPS: http://www.wosign.com/policy/
-
- Signature Algorithm: sha1WithRSAEncryption
- ab:70:aa:64:c4:0b:34:91:b9:63:20:5e:b0:9c:21:ff:25:79:
- 6c:57:4e:56:44:58:83:b9:00:ce:2d:65:a8:6d:95:38:ea:82:
- 2d:55:18:60:12:7e:1a:1d:6b:62:34:2c:d9:cd:17:00:43:84:
- 3e:ad:bc:ff:26:85:1f:4a:a7:46:13:b0:7d:3b:0b:d9:4b:9d:
- b0:cf:8d:f4:05:cb:12:29:fe:e1:97:c7:b7:c7:aa:53:7e:39:
- 2d:9d:f6:d4:5e:b7:8c:15:6a:81:d2:37:1a:43:0e:cb:e6:30:
- 21:43:83:69:0f:ef:6b:cd:10:f9:84:60:cf:89:e9:88:10:01:
- af:09:f3:48:bb:07:09:75:01:84:fa:b1:1e:51:19:8f:c6:c9:
- 85:65:16:5f:e0:56:7e:b7:bf:40:c2:d4:d0:05:1f:93:63:c9:
- 24:08:3b:91:b2:35:e1:a4:8f:35:db:24:58:75:39:e4:dd:10:
- 1a:b0:df:13:12:73:9e:6d:e7:67:3c:db:1c:1c:dd:10:dd:cc:
- f4:07:09:b9:2e:e5:75:6d:97:b7:60:5b:89:70:81:d2:26:d8:
- c6:09:2b:b2:05:7f:c4:b8:14:41:1e:07:f0:48:41:63:cb:0c:
- aa:45:7e:84:f9:33:b3:58:87:bc:b1:d6:c2:65:c7:57:c6:95:
- e8:85:90:b0:62:50:f5:ee:12:f1:d8:7e:73:cb:c0:c3:a0:25:
- 17:23:37:91:ba:63:bd:84:af:f3:89:e0:51:c2:73:35:6d:63:
- 86:21:f2:73:bd:c2:47:e0:4d:7e:46:37:4b:d0:f7:61:2a:c7:
- 94:50:25:36:e8:ae:da:2e:1f:b8:08:b2:55:7c:6b:66:43:8f:
- 02:1d:dd:a7:eb:98:00:a7:25:74:f5:93:1b:6d:26:bb:1d:e5:
- b7:fc:21:25:26:d1:77:1b:a8:6e:aa:c3:4b:64:51:7f:91:0e:
- 41:5c:19:83:a1:a8:1f:94:99:43:0f:99:db:18:dc:21:6f:76:
- d1:9e:ea:a3:76:e0:f0:09:bc:b9:b4:f7:43:6c:1f:d3:2a:86:
- 6a:2f:e0:6c:f1:83:39:d7:70:db:a2:91:ab:54:be:f4:47:88:
- 8c:f0:10:d2:e4:ad:eb:7e:b1:ba:08:4b:67:04:a3:f2:e9:90:
- 2b:81:e3:74:76:3d:00:9d:d2:bb:fc:a5:a0:15:1c:28:df:10:
- 4f:47:d7:33:46:9d:b2:57:d2:c6:1f:fb:e4:59:4a:2b:28:a9:
- 13:dd:b9:e9:93:b4:88:ee:e2:5b:a0:07:25:fe:8a:2e:78:e4:
- b4:e1:d5:1d:f6:1a:3a:e3:1c:01:2a:1e:a1:86:54:9e:49:dc:
- c9:59:e3:0d:6d:5a:13:36
------BEGIN CERTIFICATE-----
-MIIFozCCA4ugAwIBAgIQZz8zTyFTNlLDXhXS/bMCDzANBgkqhkiG9w0BAQUFADBV
-MQswCQYDVQQGEwJDTjEaMBgGA1UEChMRV29TaWduIENBIExpbWl0ZWQxKjAoBgNV
-BAMTIUNlcnRpZmljYXRpb24gQXV0aG9yaXR5IG9mIFdvU2lnbjAeFw0wOTA4MDgw
-MTAwMDVaFw0yNDA4MDgwMTAwMDVaME8xCzAJBgNVBAYTAkNOMRowGAYDVQQKExFX
-b1NpZ24gQ0EgTGltaXRlZDEkMCIGA1UEAxMbV29TaWduIENsYXNzIDMgT1YgU2Vy
-dmVyIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvIm+YVFTyCuW
-dbNa0w40/krCn6MYg6Ks4y5ek3kLE0lek7KPhBDtkY+Cuq1n3zMbroTyVbBb9LOe
-vOYEDx3vBFqoC+wSbVYZZHBJD1eS818hpk200pYrPDKz749ZCxS6bqKecdvyiD8o
-O+zOvkesRceKnvphk8VJF7ZGtveZFowcbjGuac7txiSScKHLlsNsFtDuzE+GM7NB
-5j092w6MM3S7w/wLp/zRceLBDNT3uj6AkNRI66KDcNjbMAcpifmBISz/60f2em1D
-lmcXPvPic1HHdh7pHKDsERqxzx4tnFXuO8YtrtxmZZGiZpysgvGkF7XXQ4PDiKBk
-3spyRdw4+wIDAQABo4IBczCCAW8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdJQQWMBQG
-CCsGAQUFBwMCBggrBgEFBQcDATASBgNVHRMBAf8ECDAGAQH/AgEAMDAGA1UdHwQp
-MCcwJaAjoCGGH2h0dHA6Ly9jcmxzMS53b3NpZ24uY29tL2NhMS5jcmwwcQYIKwYB
-BQUHAQEEZTBjMCcGCCsGAQUFBzABhhtodHRwOi8vb2NzcDEud29zaWduLmNvbS9j
-YTEwOAYIKwYBBQUHMAKGLGh0dHA6Ly9haWExLndvc2lnbi5jb20vY2ExLWNsYXNz
-My1zZXJ2ZXIuY2VyMB0GA1UdDgQWBBRiLoHZ40J5FKPN2VSKbvjelaqPmDAfBgNV
-HSMEGDAWgBThZs8O0fGzS7cGIBT+hxLV9v77PjBFBgNVHSAEPjA8MDoGCysGAQQB
-gptRAQMCMCswKQYIKwYBBQUHAgEWHWh0dHA6Ly93d3cud29zaWduLmNvbS9wb2xp
-Y3kvMA0GCSqGSIb3DQEBBQUAA4ICAQCrcKpkxAs0kbljIF6wnCH/JXlsV05WRFiD
-uQDOLWWobZU46oItVRhgEn4aHWtiNCzZzRcAQ4Q+rbz/JoUfSqdGE7B9OwvZS52w
-z430BcsSKf7hl8e3x6pTfjktnfbUXreMFWqB0jcaQw7L5jAhQ4NpD+9rzRD5hGDP
-iemIEAGvCfNIuwcJdQGE+rEeURmPxsmFZRZf4FZ+t79AwtTQBR+TY8kkCDuRsjXh
-pI812yRYdTnk3RAasN8TEnOebednPNscHN0Q3cz0Bwm5LuV1bZe3YFuJcIHSJtjG
-CSuyBX/EuBRBHgfwSEFjywyqRX6E+TOzWIe8sdbCZcdXxpXohZCwYlD17hLx2H5z
-y8DDoCUXIzeRumO9hK/zieBRwnM1bWOGIfJzvcJH4E1+RjdL0PdhKseUUCU26K7a
-Lh+4CLJVfGtmQ48CHd2n65gApyV09ZMbbSa7HeW3/CElJtF3G6huqsNLZFF/kQ5B
-XBmDoagflJlDD5nbGNwhb3bRnuqjduDwCby5tPdDbB/TKoZqL+Bs8YM513DbopGr
-VL70R4iM8BDS5K3rfrG6CEtnBKPy6ZArgeN0dj0AndK7/KWgFRwo3xBPR9czRp2y
-V9LGH/vkWUorKKkT3bnpk7SI7uJboAcl/ooueOS04dUd9ho64xwBKh6hhlSeSdzJ
-WeMNbVoTNg==
------END CERTIFICATE-----
-#endif
-static const unsigned char kDERCert45[] = {
- 0x30, 0x82, 0x05, 0xa3, 0x30, 0x82, 0x03, 0x8b, 0xa0, 0x03, 0x02, 0x01,
- 0x02, 0x02, 0x10, 0x67, 0x3f, 0x33, 0x4f, 0x21, 0x53, 0x36, 0x52, 0xc3,
- 0x5e, 0x15, 0xd2, 0xfd, 0xb3, 0x02, 0x0f, 0x30, 0x0d, 0x06, 0x09, 0x2a,
- 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x55,
- 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x43,
- 0x4e, 0x31, 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x11,
- 0x57, 0x6f, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x43, 0x41, 0x20, 0x4c, 0x69,
- 0x6d, 0x69, 0x74, 0x65, 0x64, 0x31, 0x2a, 0x30, 0x28, 0x06, 0x03, 0x55,
- 0x04, 0x03, 0x13, 0x21, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63,
- 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72,
- 0x69, 0x74, 0x79, 0x20, 0x6f, 0x66, 0x20, 0x57, 0x6f, 0x53, 0x69, 0x67,
- 0x6e, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x39, 0x30, 0x38, 0x30, 0x38, 0x30,
- 0x31, 0x30, 0x30, 0x30, 0x35, 0x5a, 0x17, 0x0d, 0x32, 0x34, 0x30, 0x38,
- 0x30, 0x38, 0x30, 0x31, 0x30, 0x30, 0x30, 0x35, 0x5a, 0x30, 0x4f, 0x31,
- 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x43, 0x4e,
- 0x31, 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x11, 0x57,
- 0x6f, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x43, 0x41, 0x20, 0x4c, 0x69, 0x6d,
- 0x69, 0x74, 0x65, 0x64, 0x31, 0x24, 0x30, 0x22, 0x06, 0x03, 0x55, 0x04,
- 0x03, 0x13, 0x1b, 0x57, 0x6f, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x43, 0x6c,
- 0x61, 0x73, 0x73, 0x20, 0x33, 0x20, 0x4f, 0x56, 0x20, 0x53, 0x65, 0x72,
- 0x76, 0x65, 0x72, 0x20, 0x43, 0x41, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d,
- 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05,
- 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82,
- 0x01, 0x01, 0x00, 0xbc, 0x89, 0xbe, 0x61, 0x51, 0x53, 0xc8, 0x2b, 0x96,
- 0x75, 0xb3, 0x5a, 0xd3, 0x0e, 0x34, 0xfe, 0x4a, 0xc2, 0x9f, 0xa3, 0x18,
- 0x83, 0xa2, 0xac, 0xe3, 0x2e, 0x5e, 0x93, 0x79, 0x0b, 0x13, 0x49, 0x5e,
- 0x93, 0xb2, 0x8f, 0x84, 0x10, 0xed, 0x91, 0x8f, 0x82, 0xba, 0xad, 0x67,
- 0xdf, 0x33, 0x1b, 0xae, 0x84, 0xf2, 0x55, 0xb0, 0x5b, 0xf4, 0xb3, 0x9e,
- 0xbc, 0xe6, 0x04, 0x0f, 0x1d, 0xef, 0x04, 0x5a, 0xa8, 0x0b, 0xec, 0x12,
- 0x6d, 0x56, 0x19, 0x64, 0x70, 0x49, 0x0f, 0x57, 0x92, 0xf3, 0x5f, 0x21,
- 0xa6, 0x4d, 0xb4, 0xd2, 0x96, 0x2b, 0x3c, 0x32, 0xb3, 0xef, 0x8f, 0x59,
- 0x0b, 0x14, 0xba, 0x6e, 0xa2, 0x9e, 0x71, 0xdb, 0xf2, 0x88, 0x3f, 0x28,
- 0x3b, 0xec, 0xce, 0xbe, 0x47, 0xac, 0x45, 0xc7, 0x8a, 0x9e, 0xfa, 0x61,
- 0x93, 0xc5, 0x49, 0x17, 0xb6, 0x46, 0xb6, 0xf7, 0x99, 0x16, 0x8c, 0x1c,
- 0x6e, 0x31, 0xae, 0x69, 0xce, 0xed, 0xc6, 0x24, 0x92, 0x70, 0xa1, 0xcb,
- 0x96, 0xc3, 0x6c, 0x16, 0xd0, 0xee, 0xcc, 0x4f, 0x86, 0x33, 0xb3, 0x41,
- 0xe6, 0x3d, 0x3d, 0xdb, 0x0e, 0x8c, 0x33, 0x74, 0xbb, 0xc3, 0xfc, 0x0b,
- 0xa7, 0xfc, 0xd1, 0x71, 0xe2, 0xc1, 0x0c, 0xd4, 0xf7, 0xba, 0x3e, 0x80,
- 0x90, 0xd4, 0x48, 0xeb, 0xa2, 0x83, 0x70, 0xd8, 0xdb, 0x30, 0x07, 0x29,
- 0x89, 0xf9, 0x81, 0x21, 0x2c, 0xff, 0xeb, 0x47, 0xf6, 0x7a, 0x6d, 0x43,
- 0x96, 0x67, 0x17, 0x3e, 0xf3, 0xe2, 0x73, 0x51, 0xc7, 0x76, 0x1e, 0xe9,
- 0x1c, 0xa0, 0xec, 0x11, 0x1a, 0xb1, 0xcf, 0x1e, 0x2d, 0x9c, 0x55, 0xee,
- 0x3b, 0xc6, 0x2d, 0xae, 0xdc, 0x66, 0x65, 0x91, 0xa2, 0x66, 0x9c, 0xac,
- 0x82, 0xf1, 0xa4, 0x17, 0xb5, 0xd7, 0x43, 0x83, 0xc3, 0x88, 0xa0, 0x64,
- 0xde, 0xca, 0x72, 0x45, 0xdc, 0x38, 0xfb, 0x02, 0x03, 0x01, 0x00, 0x01,
- 0xa3, 0x82, 0x01, 0x73, 0x30, 0x82, 0x01, 0x6f, 0x30, 0x0e, 0x06, 0x03,
- 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06,
- 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04, 0x16, 0x30, 0x14, 0x06,
- 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x02, 0x06, 0x08, 0x2b,
- 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x01, 0x30, 0x12, 0x06, 0x03, 0x55,
- 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff,
- 0x02, 0x01, 0x00, 0x30, 0x30, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x29,
- 0x30, 0x27, 0x30, 0x25, 0xa0, 0x23, 0xa0, 0x21, 0x86, 0x1f, 0x68, 0x74,
- 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x73, 0x31, 0x2e, 0x77,
- 0x6f, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x61,
- 0x31, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x71, 0x06, 0x08, 0x2b, 0x06, 0x01,
- 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x65, 0x30, 0x63, 0x30, 0x27, 0x06,
- 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x1b, 0x68,
- 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x31, 0x2e,
- 0x77, 0x6f, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63,
- 0x61, 0x31, 0x30, 0x38, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
- 0x30, 0x02, 0x86, 0x2c, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x61,
- 0x69, 0x61, 0x31, 0x2e, 0x77, 0x6f, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63,
- 0x6f, 0x6d, 0x2f, 0x63, 0x61, 0x31, 0x2d, 0x63, 0x6c, 0x61, 0x73, 0x73,
- 0x33, 0x2d, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x63, 0x65, 0x72,
- 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x62,
- 0x2e, 0x81, 0xd9, 0xe3, 0x42, 0x79, 0x14, 0xa3, 0xcd, 0xd9, 0x54, 0x8a,
- 0x6e, 0xf8, 0xde, 0x95, 0xaa, 0x8f, 0x98, 0x30, 0x1f, 0x06, 0x03, 0x55,
- 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0xe1, 0x66, 0xcf, 0x0e,
- 0xd1, 0xf1, 0xb3, 0x4b, 0xb7, 0x06, 0x20, 0x14, 0xfe, 0x87, 0x12, 0xd5,
- 0xf6, 0xfe, 0xfb, 0x3e, 0x30, 0x45, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04,
- 0x3e, 0x30, 0x3c, 0x30, 0x3a, 0x06, 0x0b, 0x2b, 0x06, 0x01, 0x04, 0x01,
- 0x82, 0x9b, 0x51, 0x01, 0x03, 0x02, 0x30, 0x2b, 0x30, 0x29, 0x06, 0x08,
- 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x1d, 0x68, 0x74,
- 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x77, 0x6f, 0x73,
- 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x6f, 0x6c, 0x69,
- 0x63, 0x79, 0x2f, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
- 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x82, 0x02, 0x01, 0x00, 0xab,
- 0x70, 0xaa, 0x64, 0xc4, 0x0b, 0x34, 0x91, 0xb9, 0x63, 0x20, 0x5e, 0xb0,
- 0x9c, 0x21, 0xff, 0x25, 0x79, 0x6c, 0x57, 0x4e, 0x56, 0x44, 0x58, 0x83,
- 0xb9, 0x00, 0xce, 0x2d, 0x65, 0xa8, 0x6d, 0x95, 0x38, 0xea, 0x82, 0x2d,
- 0x55, 0x18, 0x60, 0x12, 0x7e, 0x1a, 0x1d, 0x6b, 0x62, 0x34, 0x2c, 0xd9,
- 0xcd, 0x17, 0x00, 0x43, 0x84, 0x3e, 0xad, 0xbc, 0xff, 0x26, 0x85, 0x1f,
- 0x4a, 0xa7, 0x46, 0x13, 0xb0, 0x7d, 0x3b, 0x0b, 0xd9, 0x4b, 0x9d, 0xb0,
- 0xcf, 0x8d, 0xf4, 0x05, 0xcb, 0x12, 0x29, 0xfe, 0xe1, 0x97, 0xc7, 0xb7,
- 0xc7, 0xaa, 0x53, 0x7e, 0x39, 0x2d, 0x9d, 0xf6, 0xd4, 0x5e, 0xb7, 0x8c,
- 0x15, 0x6a, 0x81, 0xd2, 0x37, 0x1a, 0x43, 0x0e, 0xcb, 0xe6, 0x30, 0x21,
- 0x43, 0x83, 0x69, 0x0f, 0xef, 0x6b, 0xcd, 0x10, 0xf9, 0x84, 0x60, 0xcf,
- 0x89, 0xe9, 0x88, 0x10, 0x01, 0xaf, 0x09, 0xf3, 0x48, 0xbb, 0x07, 0x09,
- 0x75, 0x01, 0x84, 0xfa, 0xb1, 0x1e, 0x51, 0x19, 0x8f, 0xc6, 0xc9, 0x85,
- 0x65, 0x16, 0x5f, 0xe0, 0x56, 0x7e, 0xb7, 0xbf, 0x40, 0xc2, 0xd4, 0xd0,
- 0x05, 0x1f, 0x93, 0x63, 0xc9, 0x24, 0x08, 0x3b, 0x91, 0xb2, 0x35, 0xe1,
- 0xa4, 0x8f, 0x35, 0xdb, 0x24, 0x58, 0x75, 0x39, 0xe4, 0xdd, 0x10, 0x1a,
- 0xb0, 0xdf, 0x13, 0x12, 0x73, 0x9e, 0x6d, 0xe7, 0x67, 0x3c, 0xdb, 0x1c,
- 0x1c, 0xdd, 0x10, 0xdd, 0xcc, 0xf4, 0x07, 0x09, 0xb9, 0x2e, 0xe5, 0x75,
- 0x6d, 0x97, 0xb7, 0x60, 0x5b, 0x89, 0x70, 0x81, 0xd2, 0x26, 0xd8, 0xc6,
- 0x09, 0x2b, 0xb2, 0x05, 0x7f, 0xc4, 0xb8, 0x14, 0x41, 0x1e, 0x07, 0xf0,
- 0x48, 0x41, 0x63, 0xcb, 0x0c, 0xaa, 0x45, 0x7e, 0x84, 0xf9, 0x33, 0xb3,
- 0x58, 0x87, 0xbc, 0xb1, 0xd6, 0xc2, 0x65, 0xc7, 0x57, 0xc6, 0x95, 0xe8,
- 0x85, 0x90, 0xb0, 0x62, 0x50, 0xf5, 0xee, 0x12, 0xf1, 0xd8, 0x7e, 0x73,
- 0xcb, 0xc0, 0xc3, 0xa0, 0x25, 0x17, 0x23, 0x37, 0x91, 0xba, 0x63, 0xbd,
- 0x84, 0xaf, 0xf3, 0x89, 0xe0, 0x51, 0xc2, 0x73, 0x35, 0x6d, 0x63, 0x86,
- 0x21, 0xf2, 0x73, 0xbd, 0xc2, 0x47, 0xe0, 0x4d, 0x7e, 0x46, 0x37, 0x4b,
- 0xd0, 0xf7, 0x61, 0x2a, 0xc7, 0x94, 0x50, 0x25, 0x36, 0xe8, 0xae, 0xda,
- 0x2e, 0x1f, 0xb8, 0x08, 0xb2, 0x55, 0x7c, 0x6b, 0x66, 0x43, 0x8f, 0x02,
- 0x1d, 0xdd, 0xa7, 0xeb, 0x98, 0x00, 0xa7, 0x25, 0x74, 0xf5, 0x93, 0x1b,
- 0x6d, 0x26, 0xbb, 0x1d, 0xe5, 0xb7, 0xfc, 0x21, 0x25, 0x26, 0xd1, 0x77,
- 0x1b, 0xa8, 0x6e, 0xaa, 0xc3, 0x4b, 0x64, 0x51, 0x7f, 0x91, 0x0e, 0x41,
- 0x5c, 0x19, 0x83, 0xa1, 0xa8, 0x1f, 0x94, 0x99, 0x43, 0x0f, 0x99, 0xdb,
- 0x18, 0xdc, 0x21, 0x6f, 0x76, 0xd1, 0x9e, 0xea, 0xa3, 0x76, 0xe0, 0xf0,
- 0x09, 0xbc, 0xb9, 0xb4, 0xf7, 0x43, 0x6c, 0x1f, 0xd3, 0x2a, 0x86, 0x6a,
- 0x2f, 0xe0, 0x6c, 0xf1, 0x83, 0x39, 0xd7, 0x70, 0xdb, 0xa2, 0x91, 0xab,
- 0x54, 0xbe, 0xf4, 0x47, 0x88, 0x8c, 0xf0, 0x10, 0xd2, 0xe4, 0xad, 0xeb,
- 0x7e, 0xb1, 0xba, 0x08, 0x4b, 0x67, 0x04, 0xa3, 0xf2, 0xe9, 0x90, 0x2b,
- 0x81, 0xe3, 0x74, 0x76, 0x3d, 0x00, 0x9d, 0xd2, 0xbb, 0xfc, 0xa5, 0xa0,
- 0x15, 0x1c, 0x28, 0xdf, 0x10, 0x4f, 0x47, 0xd7, 0x33, 0x46, 0x9d, 0xb2,
- 0x57, 0xd2, 0xc6, 0x1f, 0xfb, 0xe4, 0x59, 0x4a, 0x2b, 0x28, 0xa9, 0x13,
- 0xdd, 0xb9, 0xe9, 0x93, 0xb4, 0x88, 0xee, 0xe2, 0x5b, 0xa0, 0x07, 0x25,
- 0xfe, 0x8a, 0x2e, 0x78, 0xe4, 0xb4, 0xe1, 0xd5, 0x1d, 0xf6, 0x1a, 0x3a,
- 0xe3, 0x1c, 0x01, 0x2a, 0x1e, 0xa1, 0x86, 0x54, 0x9e, 0x49, 0xdc, 0xc9,
- 0x59, 0xe3, 0x0d, 0x6d, 0x5a, 0x13, 0x36,
-};
-
-#if 0
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number: 120040007 (0x727aa47)
- Signature Algorithm: sha256WithRSAEncryption
- Issuer: C=IE, O=Baltimore, OU=CyberTrust, CN=Baltimore CyberTrust Root
- Validity
- Not Before: May 7 17:04:09 2014 GMT
- Not After : May 7 17:03:30 2018 GMT
- Subject: C=US, ST=Washington, L=Redmond, O=Microsoft Corporation, OU=Microsoft IT, CN=Microsoft IT SSL SHA2
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (4096 bit)
- Modulus:
- 00:d1:e8:37:a7:76:8a:70:4b:19:f0:20:37:09:24:
- 37:7f:ea:fb:78:e6:05:ba:6a:ad:4e:27:0d:fc:72:
- 6a:d9:6c:21:c4:64:11:95:73:10:0a:5c:25:7b:88:
- 6c:94:04:fd:c7:db:ae:7b:dc:4a:08:b3:3e:16:f1:
- d0:ad:db:30:6d:d7:1a:1e:52:b5:3d:f0:47:19:03:
- e2:7d:a6:bd:57:13:3f:54:ea:3a:a3:b1:77:fc:42:
- f0:63:49:6a:91:80:2e:30:49:c0:8a:eb:2b:af:fe:
- 3a:eb:07:5d:06:f7:e9:fd:84:0e:91:bd:09:20:29:
- e8:6e:5d:09:ce:15:d3:e7:ef:db:50:eb:44:ef:18:
- 57:ab:04:1d:bc:31:f9:f7:7b:2a:13:cf:d1:3d:51:
- af:1b:c5:b5:7b:e7:b0:fc:53:bb:9a:e7:63:de:41:
- 33:b6:47:24:69:5d:b8:46:a7:ff:ad:ab:df:4f:7a:
- 78:25:27:21:26:34:ca:02:6e:37:51:f0:ed:58:1a:
- 60:94:f6:c4:93:d8:dd:30:24:25:d7:1c:eb:19:94:
- 35:5d:93:b2:ae:aa:29:83:73:c4:74:59:05:52:67:
- 9d:da:67:51:39:05:3a:36:ea:f2:1e:76:2b:14:ae:
- ec:3d:f9:14:99:8b:07:6e:bc:e7:0c:56:de:ac:be:
- ae:db:75:32:90:9e:63:bd:74:bf:e0:0a:ca:f8:34:
- 96:67:84:cd:d1:42:38:78:c7:99:b6:0c:ce:b6:0f:
- e9:1b:cb:f4:59:be:11:0e:cb:2c:32:c8:fa:83:29:
- 64:79:3c:8b:4b:f0:32:74:6c:f3:93:b8:96:6b:5d:
- 57:5a:68:c1:cc:0c:79:8a:19:de:f5:49:02:5e:08:
- 80:01:89:0c:32:cd:d2:d6:96:d5:4b:a0:f3:ec:bf:
- ab:f4:7d:b3:a1:b9:7c:da:4e:d7:e5:b7:ac:b9:f2:
- 25:5f:01:cb:8c:96:a8:28:ae:c1:33:5a:f6:3f:08:
- 90:dc:eb:ff:39:d8:26:c8:12:9d:1c:9a:aa:a9:c0:
- 16:8e:86:ed:67:52:96:00:7f:0d:92:3d:3d:d9:70:
- 36:e5:ea:42:6f:1f:ae:95:e5:5b:5d:f8:d0:3a:c7:
- d4:de:77:86:d0:fc:9e:4e:e2:e2:b8:a9:68:37:09:
- c4:39:e3:85:b8:89:f3:1f:6e:b7:6d:1f:4a:2f:18:
- 09:6f:de:4a:01:8f:14:c9:b7:a6:ee:a7:63:9f:33:
- a4:54:7c:42:83:68:b8:a5:df:bf:ec:b9:1a:5d:13:
- 3b:d9:ad:68:fd:20:0a:55:91:21:64:f9:d7:13:01:
- a0:08:5d:59:89:1b:44:af:a4:ac:c7:05:10:fa:41:
- 4a:a8:fb
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Basic Constraints: critical
- CA:TRUE, pathlen:0
- X509v3 Certificate Policies:
- Policy: 1.3.6.1.4.1.6334.1.0
- CPS: http://cybertrust.omniroot.com/repository.cfm
- Policy: 1.3.6.1.4.1.311.42.1
-
- Authority Information Access:
- OCSP - URI:http://ocsp.omniroot.com/baltimoreroot
-
- X509v3 Key Usage: critical
- Digital Signature, Certificate Sign, CRL Sign
- X509v3 Extended Key Usage:
- TLS Web Server Authentication, TLS Web Client Authentication, OCSP Signing
- X509v3 Authority Key Identifier:
- keyid:E5:9D:59:30:82:47:58:CC:AC:FA:08:54:36:86:7B:3A:B5:04:4D:F0
-
- X509v3 CRL Distribution Points:
-
- Full Name:
- URI:http://cdp1.public-trust.com/CRL/Omniroot2025.crl
-
- X509v3 Subject Key Identifier:
- 51:AF:24:26:9C:F4:68:22:57:80:26:2B:3B:46:62:15:7B:1E:CC:A5
- Signature Algorithm: sha256WithRSAEncryption
- 69:62:f6:84:91:00:c4:6f:82:7b:24:e1:42:a2:a5:8b:82:5c:
- a7:c5:44:cb:e7:52:76:63:d3:76:9e:78:e2:69:35:b1:38:ba:
- b0:96:c6:1f:ac:7b:c6:b2:65:77:8b:7d:8d:ae:64:b9:a5:8c:
- 17:ca:58:65:c3:ad:82:f5:c5:a2:f5:01:13:93:c6:7e:44:e5:
- c4:61:fa:03:b6:56:c1:72:e1:c8:28:c5:69:21:8f:ac:6e:fd:
- 7f:43:83:36:b8:c0:d6:a0:28:fe:1a:45:be:fd:93:8c:8d:a4:
- 64:79:1f:14:db:a1:9f:21:dc:c0:4e:7b:17:22:17:b1:b6:3c:
- d3:9b:e2:0a:a3:7e:99:b0:c1:ac:d8:f4:86:df:3c:da:7d:14:
- 9c:40:c1:7c:d2:18:6f:f1:4f:26:45:09:95:94:5c:da:d0:98:
- f8:f4:4c:82:96:10:de:ac:30:cb:2b:ae:f9:92:ea:bf:79:03:
- fc:1e:3f:ac:09:a4:3f:65:fd:91:4f:96:24:a7:ce:b4:4e:6a:
- 96:29:17:ae:c0:a8:df:17:22:f4:17:e3:dc:1c:39:06:56:10:
- ea:ea:b5:74:17:3c:4e:dd:7e:91:0a:a8:0b:78:07:a7:31:44:
- 08:31:ab:18:84:0f:12:9c:e7:de:84:2c:e9:6d:93:45:bf:a8:
- c1:3f:34:dc
------BEGIN CERTIFICATE-----
-MIIF4TCCBMmgAwIBAgIEByeqRzANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJJ
-RTESMBAGA1UEChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYD
-VQQDExlCYWx0aW1vcmUgQ3liZXJUcnVzdCBSb290MB4XDTE0MDUwNzE3MDQwOVoX
-DTE4MDUwNzE3MDMzMFowgYsxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5n
-dG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9y
-YXRpb24xFTATBgNVBAsTDE1pY3Jvc29mdCBJVDEeMBwGA1UEAxMVTWljcm9zb2Z0
-IElUIFNTTCBTSEEyMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA0eg3
-p3aKcEsZ8CA3CSQ3f+r7eOYFumqtTicN/HJq2WwhxGQRlXMQClwle4hslAT9x9uu
-e9xKCLM+FvHQrdswbdcaHlK1PfBHGQPifaa9VxM/VOo6o7F3/ELwY0lqkYAuMEnA
-iusrr/466wddBvfp/YQOkb0JICnobl0JzhXT5+/bUOtE7xhXqwQdvDH593sqE8/R
-PVGvG8W1e+ew/FO7mudj3kEztkckaV24Rqf/ravfT3p4JSchJjTKAm43UfDtWBpg
-lPbEk9jdMCQl1xzrGZQ1XZOyrqopg3PEdFkFUmed2mdROQU6NuryHnYrFK7sPfkU
-mYsHbrznDFberL6u23UykJ5jvXS/4ArK+DSWZ4TN0UI4eMeZtgzOtg/pG8v0Wb4R
-DsssMsj6gylkeTyLS/AydGzzk7iWa11XWmjBzAx5ihne9UkCXgiAAYkMMs3S1pbV
-S6Dz7L+r9H2zobl82k7X5besufIlXwHLjJaoKK7BM1r2PwiQ3Ov/OdgmyBKdHJqq
-qcAWjobtZ1KWAH8Nkj092XA25epCbx+uleVbXfjQOsfU3neG0PyeTuLiuKloNwnE
-OeOFuInzH263bR9KLxgJb95KAY8Uybem7qdjnzOkVHxCg2i4pd+/7LkaXRM72a1o
-/SAKVZEhZPnXEwGgCF1ZiRtEr6SsxwUQ+kFKqPsCAwEAAaOCAXswggF3MBIGA1Ud
-EwEB/wQIMAYBAf8CAQAwYAYDVR0gBFkwVzBIBgkrBgEEAbE+AQAwOzA5BggrBgEF
-BQcCARYtaHR0cDovL2N5YmVydHJ1c3Qub21uaXJvb3QuY29tL3JlcG9zaXRvcnku
-Y2ZtMAsGCSsGAQQBgjcqATBCBggrBgEFBQcBAQQ2MDQwMgYIKwYBBQUHMAGGJmh0
-dHA6Ly9vY3NwLm9tbmlyb290LmNvbS9iYWx0aW1vcmVyb290MA4GA1UdDwEB/wQE
-AwIBhjAnBgNVHSUEIDAeBggrBgEFBQcDAQYIKwYBBQUHAwIGCCsGAQUFBwMJMB8G
-A1UdIwQYMBaAFOWdWTCCR1jMrPoIVDaGezq1BE3wMEIGA1UdHwQ7MDkwN6A1oDOG
-MWh0dHA6Ly9jZHAxLnB1YmxpYy10cnVzdC5jb20vQ1JML09tbmlyb290MjAyNS5j
-cmwwHQYDVR0OBBYEFFGvJCac9GgiV4AmKztGYhV7HsylMA0GCSqGSIb3DQEBCwUA
-A4IBAQBpYvaEkQDEb4J7JOFCoqWLglynxUTL51J2Y9N2nnjiaTWxOLqwlsYfrHvG
-smV3i32NrmS5pYwXylhlw62C9cWi9QETk8Z+ROXEYfoDtlbBcuHIKMVpIY+sbv1/
-Q4M2uMDWoCj+GkW+/ZOMjaRkeR8U26GfIdzATnsXIhextjzTm+IKo36ZsMGs2PSG
-3zzafRScQMF80hhv8U8mRQmVlFza0Jj49EyClhDerDDLK675kuq/eQP8Hj+sCaQ/
-Zf2RT5Ykp860TmqWKReuwKjfFyL0F+PcHDkGVhDq6rV0FzxO3X6RCqgLeAenMUQI
-MasYhA8SnOfehCzpbZNFv6jBPzTc
------END CERTIFICATE-----
-#endif
-static const unsigned char kDERCert46[] = {
- 0x30, 0x82, 0x05, 0xe1, 0x30, 0x82, 0x04, 0xc9, 0xa0, 0x03, 0x02, 0x01,
- 0x02, 0x02, 0x04, 0x07, 0x27, 0xaa, 0x47, 0x30, 0x0d, 0x06, 0x09, 0x2a,
- 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x5a,
- 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x49,
- 0x45, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x09,
- 0x42, 0x61, 0x6c, 0x74, 0x69, 0x6d, 0x6f, 0x72, 0x65, 0x31, 0x13, 0x30,
- 0x11, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x0a, 0x43, 0x79, 0x62, 0x65,
- 0x72, 0x54, 0x72, 0x75, 0x73, 0x74, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03,
- 0x55, 0x04, 0x03, 0x13, 0x19, 0x42, 0x61, 0x6c, 0x74, 0x69, 0x6d, 0x6f,
- 0x72, 0x65, 0x20, 0x43, 0x79, 0x62, 0x65, 0x72, 0x54, 0x72, 0x75, 0x73,
- 0x74, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x34,
- 0x30, 0x35, 0x30, 0x37, 0x31, 0x37, 0x30, 0x34, 0x30, 0x39, 0x5a, 0x17,
- 0x0d, 0x31, 0x38, 0x30, 0x35, 0x30, 0x37, 0x31, 0x37, 0x30, 0x33, 0x33,
- 0x30, 0x5a, 0x30, 0x81, 0x8b, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55,
- 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03,
- 0x55, 0x04, 0x08, 0x13, 0x0a, 0x57, 0x61, 0x73, 0x68, 0x69, 0x6e, 0x67,
- 0x74, 0x6f, 0x6e, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x07,
- 0x13, 0x07, 0x52, 0x65, 0x64, 0x6d, 0x6f, 0x6e, 0x64, 0x31, 0x1e, 0x30,
- 0x1c, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x15, 0x4d, 0x69, 0x63, 0x72,
- 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x20, 0x43, 0x6f, 0x72, 0x70, 0x6f, 0x72,
- 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55,
- 0x04, 0x0b, 0x13, 0x0c, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66,
- 0x74, 0x20, 0x49, 0x54, 0x31, 0x1e, 0x30, 0x1c, 0x06, 0x03, 0x55, 0x04,
- 0x03, 0x13, 0x15, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74,
- 0x20, 0x49, 0x54, 0x20, 0x53, 0x53, 0x4c, 0x20, 0x53, 0x48, 0x41, 0x32,
- 0x30, 0x82, 0x02, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
- 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x02, 0x0f, 0x00,
- 0x30, 0x82, 0x02, 0x0a, 0x02, 0x82, 0x02, 0x01, 0x00, 0xd1, 0xe8, 0x37,
- 0xa7, 0x76, 0x8a, 0x70, 0x4b, 0x19, 0xf0, 0x20, 0x37, 0x09, 0x24, 0x37,
- 0x7f, 0xea, 0xfb, 0x78, 0xe6, 0x05, 0xba, 0x6a, 0xad, 0x4e, 0x27, 0x0d,
- 0xfc, 0x72, 0x6a, 0xd9, 0x6c, 0x21, 0xc4, 0x64, 0x11, 0x95, 0x73, 0x10,
- 0x0a, 0x5c, 0x25, 0x7b, 0x88, 0x6c, 0x94, 0x04, 0xfd, 0xc7, 0xdb, 0xae,
- 0x7b, 0xdc, 0x4a, 0x08, 0xb3, 0x3e, 0x16, 0xf1, 0xd0, 0xad, 0xdb, 0x30,
- 0x6d, 0xd7, 0x1a, 0x1e, 0x52, 0xb5, 0x3d, 0xf0, 0x47, 0x19, 0x03, 0xe2,
- 0x7d, 0xa6, 0xbd, 0x57, 0x13, 0x3f, 0x54, 0xea, 0x3a, 0xa3, 0xb1, 0x77,
- 0xfc, 0x42, 0xf0, 0x63, 0x49, 0x6a, 0x91, 0x80, 0x2e, 0x30, 0x49, 0xc0,
- 0x8a, 0xeb, 0x2b, 0xaf, 0xfe, 0x3a, 0xeb, 0x07, 0x5d, 0x06, 0xf7, 0xe9,
- 0xfd, 0x84, 0x0e, 0x91, 0xbd, 0x09, 0x20, 0x29, 0xe8, 0x6e, 0x5d, 0x09,
- 0xce, 0x15, 0xd3, 0xe7, 0xef, 0xdb, 0x50, 0xeb, 0x44, 0xef, 0x18, 0x57,
- 0xab, 0x04, 0x1d, 0xbc, 0x31, 0xf9, 0xf7, 0x7b, 0x2a, 0x13, 0xcf, 0xd1,
- 0x3d, 0x51, 0xaf, 0x1b, 0xc5, 0xb5, 0x7b, 0xe7, 0xb0, 0xfc, 0x53, 0xbb,
- 0x9a, 0xe7, 0x63, 0xde, 0x41, 0x33, 0xb6, 0x47, 0x24, 0x69, 0x5d, 0xb8,
- 0x46, 0xa7, 0xff, 0xad, 0xab, 0xdf, 0x4f, 0x7a, 0x78, 0x25, 0x27, 0x21,
- 0x26, 0x34, 0xca, 0x02, 0x6e, 0x37, 0x51, 0xf0, 0xed, 0x58, 0x1a, 0x60,
- 0x94, 0xf6, 0xc4, 0x93, 0xd8, 0xdd, 0x30, 0x24, 0x25, 0xd7, 0x1c, 0xeb,
- 0x19, 0x94, 0x35, 0x5d, 0x93, 0xb2, 0xae, 0xaa, 0x29, 0x83, 0x73, 0xc4,
- 0x74, 0x59, 0x05, 0x52, 0x67, 0x9d, 0xda, 0x67, 0x51, 0x39, 0x05, 0x3a,
- 0x36, 0xea, 0xf2, 0x1e, 0x76, 0x2b, 0x14, 0xae, 0xec, 0x3d, 0xf9, 0x14,
- 0x99, 0x8b, 0x07, 0x6e, 0xbc, 0xe7, 0x0c, 0x56, 0xde, 0xac, 0xbe, 0xae,
- 0xdb, 0x75, 0x32, 0x90, 0x9e, 0x63, 0xbd, 0x74, 0xbf, 0xe0, 0x0a, 0xca,
- 0xf8, 0x34, 0x96, 0x67, 0x84, 0xcd, 0xd1, 0x42, 0x38, 0x78, 0xc7, 0x99,
- 0xb6, 0x0c, 0xce, 0xb6, 0x0f, 0xe9, 0x1b, 0xcb, 0xf4, 0x59, 0xbe, 0x11,
- 0x0e, 0xcb, 0x2c, 0x32, 0xc8, 0xfa, 0x83, 0x29, 0x64, 0x79, 0x3c, 0x8b,
- 0x4b, 0xf0, 0x32, 0x74, 0x6c, 0xf3, 0x93, 0xb8, 0x96, 0x6b, 0x5d, 0x57,
- 0x5a, 0x68, 0xc1, 0xcc, 0x0c, 0x79, 0x8a, 0x19, 0xde, 0xf5, 0x49, 0x02,
- 0x5e, 0x08, 0x80, 0x01, 0x89, 0x0c, 0x32, 0xcd, 0xd2, 0xd6, 0x96, 0xd5,
- 0x4b, 0xa0, 0xf3, 0xec, 0xbf, 0xab, 0xf4, 0x7d, 0xb3, 0xa1, 0xb9, 0x7c,
- 0xda, 0x4e, 0xd7, 0xe5, 0xb7, 0xac, 0xb9, 0xf2, 0x25, 0x5f, 0x01, 0xcb,
- 0x8c, 0x96, 0xa8, 0x28, 0xae, 0xc1, 0x33, 0x5a, 0xf6, 0x3f, 0x08, 0x90,
- 0xdc, 0xeb, 0xff, 0x39, 0xd8, 0x26, 0xc8, 0x12, 0x9d, 0x1c, 0x9a, 0xaa,
- 0xa9, 0xc0, 0x16, 0x8e, 0x86, 0xed, 0x67, 0x52, 0x96, 0x00, 0x7f, 0x0d,
- 0x92, 0x3d, 0x3d, 0xd9, 0x70, 0x36, 0xe5, 0xea, 0x42, 0x6f, 0x1f, 0xae,
- 0x95, 0xe5, 0x5b, 0x5d, 0xf8, 0xd0, 0x3a, 0xc7, 0xd4, 0xde, 0x77, 0x86,
- 0xd0, 0xfc, 0x9e, 0x4e, 0xe2, 0xe2, 0xb8, 0xa9, 0x68, 0x37, 0x09, 0xc4,
- 0x39, 0xe3, 0x85, 0xb8, 0x89, 0xf3, 0x1f, 0x6e, 0xb7, 0x6d, 0x1f, 0x4a,
- 0x2f, 0x18, 0x09, 0x6f, 0xde, 0x4a, 0x01, 0x8f, 0x14, 0xc9, 0xb7, 0xa6,
- 0xee, 0xa7, 0x63, 0x9f, 0x33, 0xa4, 0x54, 0x7c, 0x42, 0x83, 0x68, 0xb8,
- 0xa5, 0xdf, 0xbf, 0xec, 0xb9, 0x1a, 0x5d, 0x13, 0x3b, 0xd9, 0xad, 0x68,
- 0xfd, 0x20, 0x0a, 0x55, 0x91, 0x21, 0x64, 0xf9, 0xd7, 0x13, 0x01, 0xa0,
- 0x08, 0x5d, 0x59, 0x89, 0x1b, 0x44, 0xaf, 0xa4, 0xac, 0xc7, 0x05, 0x10,
- 0xfa, 0x41, 0x4a, 0xa8, 0xfb, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82,
- 0x01, 0x7b, 0x30, 0x82, 0x01, 0x77, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d,
- 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02,
- 0x01, 0x00, 0x30, 0x60, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x59, 0x30,
- 0x57, 0x30, 0x48, 0x06, 0x09, 0x2b, 0x06, 0x01, 0x04, 0x01, 0xb1, 0x3e,
- 0x01, 0x00, 0x30, 0x3b, 0x30, 0x39, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05,
- 0x05, 0x07, 0x02, 0x01, 0x16, 0x2d, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f,
- 0x2f, 0x63, 0x79, 0x62, 0x65, 0x72, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e,
- 0x6f, 0x6d, 0x6e, 0x69, 0x72, 0x6f, 0x6f, 0x74, 0x2e, 0x63, 0x6f, 0x6d,
- 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x2e,
- 0x63, 0x66, 0x6d, 0x30, 0x0b, 0x06, 0x09, 0x2b, 0x06, 0x01, 0x04, 0x01,
- 0x82, 0x37, 0x2a, 0x01, 0x30, 0x42, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05,
- 0x05, 0x07, 0x01, 0x01, 0x04, 0x36, 0x30, 0x34, 0x30, 0x32, 0x06, 0x08,
- 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x26, 0x68, 0x74,
- 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x6f, 0x6d,
- 0x6e, 0x69, 0x72, 0x6f, 0x6f, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x62,
- 0x61, 0x6c, 0x74, 0x69, 0x6d, 0x6f, 0x72, 0x65, 0x72, 0x6f, 0x6f, 0x74,
- 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04,
- 0x03, 0x02, 0x01, 0x86, 0x30, 0x27, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04,
- 0x20, 0x30, 0x1e, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03,
- 0x01, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x02, 0x06,
- 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x09, 0x30, 0x1f, 0x06,
- 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0xe5, 0x9d,
- 0x59, 0x30, 0x82, 0x47, 0x58, 0xcc, 0xac, 0xfa, 0x08, 0x54, 0x36, 0x86,
- 0x7b, 0x3a, 0xb5, 0x04, 0x4d, 0xf0, 0x30, 0x42, 0x06, 0x03, 0x55, 0x1d,
- 0x1f, 0x04, 0x3b, 0x30, 0x39, 0x30, 0x37, 0xa0, 0x35, 0xa0, 0x33, 0x86,
- 0x31, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x64, 0x70, 0x31,
- 0x2e, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x2d, 0x74, 0x72, 0x75, 0x73,
- 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x43, 0x52, 0x4c, 0x2f, 0x4f, 0x6d,
- 0x6e, 0x69, 0x72, 0x6f, 0x6f, 0x74, 0x32, 0x30, 0x32, 0x35, 0x2e, 0x63,
- 0x72, 0x6c, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04,
- 0x14, 0x51, 0xaf, 0x24, 0x26, 0x9c, 0xf4, 0x68, 0x22, 0x57, 0x80, 0x26,
- 0x2b, 0x3b, 0x46, 0x62, 0x15, 0x7b, 0x1e, 0xcc, 0xa5, 0x30, 0x0d, 0x06,
- 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00,
- 0x03, 0x82, 0x01, 0x01, 0x00, 0x69, 0x62, 0xf6, 0x84, 0x91, 0x00, 0xc4,
- 0x6f, 0x82, 0x7b, 0x24, 0xe1, 0x42, 0xa2, 0xa5, 0x8b, 0x82, 0x5c, 0xa7,
- 0xc5, 0x44, 0xcb, 0xe7, 0x52, 0x76, 0x63, 0xd3, 0x76, 0x9e, 0x78, 0xe2,
- 0x69, 0x35, 0xb1, 0x38, 0xba, 0xb0, 0x96, 0xc6, 0x1f, 0xac, 0x7b, 0xc6,
- 0xb2, 0x65, 0x77, 0x8b, 0x7d, 0x8d, 0xae, 0x64, 0xb9, 0xa5, 0x8c, 0x17,
- 0xca, 0x58, 0x65, 0xc3, 0xad, 0x82, 0xf5, 0xc5, 0xa2, 0xf5, 0x01, 0x13,
- 0x93, 0xc6, 0x7e, 0x44, 0xe5, 0xc4, 0x61, 0xfa, 0x03, 0xb6, 0x56, 0xc1,
- 0x72, 0xe1, 0xc8, 0x28, 0xc5, 0x69, 0x21, 0x8f, 0xac, 0x6e, 0xfd, 0x7f,
- 0x43, 0x83, 0x36, 0xb8, 0xc0, 0xd6, 0xa0, 0x28, 0xfe, 0x1a, 0x45, 0xbe,
- 0xfd, 0x93, 0x8c, 0x8d, 0xa4, 0x64, 0x79, 0x1f, 0x14, 0xdb, 0xa1, 0x9f,
- 0x21, 0xdc, 0xc0, 0x4e, 0x7b, 0x17, 0x22, 0x17, 0xb1, 0xb6, 0x3c, 0xd3,
- 0x9b, 0xe2, 0x0a, 0xa3, 0x7e, 0x99, 0xb0, 0xc1, 0xac, 0xd8, 0xf4, 0x86,
- 0xdf, 0x3c, 0xda, 0x7d, 0x14, 0x9c, 0x40, 0xc1, 0x7c, 0xd2, 0x18, 0x6f,
- 0xf1, 0x4f, 0x26, 0x45, 0x09, 0x95, 0x94, 0x5c, 0xda, 0xd0, 0x98, 0xf8,
- 0xf4, 0x4c, 0x82, 0x96, 0x10, 0xde, 0xac, 0x30, 0xcb, 0x2b, 0xae, 0xf9,
- 0x92, 0xea, 0xbf, 0x79, 0x03, 0xfc, 0x1e, 0x3f, 0xac, 0x09, 0xa4, 0x3f,
- 0x65, 0xfd, 0x91, 0x4f, 0x96, 0x24, 0xa7, 0xce, 0xb4, 0x4e, 0x6a, 0x96,
- 0x29, 0x17, 0xae, 0xc0, 0xa8, 0xdf, 0x17, 0x22, 0xf4, 0x17, 0xe3, 0xdc,
- 0x1c, 0x39, 0x06, 0x56, 0x10, 0xea, 0xea, 0xb5, 0x74, 0x17, 0x3c, 0x4e,
- 0xdd, 0x7e, 0x91, 0x0a, 0xa8, 0x0b, 0x78, 0x07, 0xa7, 0x31, 0x44, 0x08,
- 0x31, 0xab, 0x18, 0x84, 0x0f, 0x12, 0x9c, 0xe7, 0xde, 0x84, 0x2c, 0xe9,
- 0x6d, 0x93, 0x45, 0xbf, 0xa8, 0xc1, 0x3f, 0x34, 0xdc,
-};
-
-#if 0
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number:
- 6e:cc:7a:a5:a7:03:20:09:b8:ce:bc:f4:e9:52:d4:91
- Signature Algorithm: sha1WithRSAEncryption
- Issuer: C=US, O=VeriSign, Inc., OU=VeriSign Trust Network, OU=(c) 2006 VeriSign, Inc. - For authorized use only, CN=VeriSign Class 3 Public Primary Certification Authority - G5
- Validity
- Not Before: Feb 8 00:00:00 2010 GMT
- Not After : Feb 7 23:59:59 2020 GMT
- Subject: C=US, O=VeriSign, Inc., OU=VeriSign Trust Network, OU=Terms of use at https://www.verisign.com/rpa (c)10, CN=VeriSign Class 3 Secure Server CA - G3
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:b1:87:84:1f:c2:0c:45:f5:bc:ab:25:97:a7:ad:
- a2:3e:9c:ba:f6:c1:39:b8:8b:ca:c2:ac:56:c6:e5:
- bb:65:8e:44:4f:4d:ce:6f:ed:09:4a:d4:af:4e:10:
- 9c:68:8b:2e:95:7b:89:9b:13:ca:e2:34:34:c1:f3:
- 5b:f3:49:7b:62:83:48:81:74:d1:88:78:6c:02:53:
- f9:bc:7f:43:26:57:58:33:83:3b:33:0a:17:b0:d0:
- 4e:91:24:ad:86:7d:64:12:dc:74:4a:34:a1:1d:0a:
- ea:96:1d:0b:15:fc:a3:4b:3b:ce:63:88:d0:f8:2d:
- 0c:94:86:10:ca:b6:9a:3d:ca:eb:37:9c:00:48:35:
- 86:29:50:78:e8:45:63:cd:19:41:4f:f5:95:ec:7b:
- 98:d4:c4:71:b3:50:be:28:b3:8f:a0:b9:53:9c:f5:
- ca:2c:23:a9:fd:14:06:e8:18:b4:9a:e8:3c:6e:81:
- fd:e4:cd:35:36:b3:51:d3:69:ec:12:ba:56:6e:6f:
- 9b:57:c5:8b:14:e7:0e:c7:9c:ed:4a:54:6a:c9:4d:
- c5:bf:11:b1:ae:1c:67:81:cb:44:55:33:99:7f:24:
- 9b:3f:53:45:7f:86:1a:f3:3c:fa:6d:7f:81:f5:b8:
- 4a:d3:f5:85:37:1c:b5:a6:d0:09:e4:18:7b:38:4e:
- fa:0f
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- Authority Information Access:
- OCSP - URI:http://ocsp.verisign.com
-
- X509v3 Basic Constraints: critical
- CA:TRUE, pathlen:0
- X509v3 Certificate Policies:
- Policy: 2.16.840.1.113733.1.7.23.3
- CPS: https://www.verisign.com/cps
- User Notice:
- Explicit Text: https://www.verisign.com/rpa
-
- X509v3 CRL Distribution Points:
-
- Full Name:
- URI:http://crl.verisign.com/pca3-g5.crl
-
- X509v3 Key Usage: critical
- Certificate Sign, CRL Sign
- 1.3.6.1.5.5.7.1.12:
- 0_.].[0Y0W0U..image/gif0!0.0...+..............k...j.H.,{..0%.#http://logo.verisign.com/vslogo.gif
- X509v3 Subject Alternative Name:
- DirName:/CN=VeriSignMPKI-2-6
- X509v3 Subject Key Identifier:
- 0D:44:5C:16:53:44:C1:82:7E:1D:20:AB:25:F4:01:63:D8:BE:79:A5
- X509v3 Authority Key Identifier:
- keyid:7F:D3:65:A7:C2:DD:EC:BB:F0:30:09:F3:43:39:FA:02:AF:33:31:33
-
- Signature Algorithm: sha1WithRSAEncryption
- 0c:83:24:ef:dd:c3:0c:d9:58:9c:fe:36:b6:eb:8a:80:4b:d1:
- a3:f7:9d:f3:cc:53:ef:82:9e:a3:a1:e6:97:c1:58:9d:75:6c:
- e0:1d:1b:4c:fa:d1:c1:2d:05:c0:ea:6e:b2:22:70:55:d9:20:
- 33:40:33:07:c2:65:83:fa:8f:43:37:9b:ea:0e:9a:6c:70:ee:
- f6:9c:80:3b:d9:37:f4:7a:6d:ec:d0:18:7d:49:4a:ca:99:c7:
- 19:28:a2:be:d8:77:24:f7:85:26:86:6d:87:05:40:41:67:d1:
- 27:3a:ed:dc:48:1d:22:cd:0b:0b:8b:bc:f4:b1:7b:fd:b4:99:
- a8:e9:76:2a:e1:1a:2d:87:6e:74:d3:88:dd:1e:22:c6:df:16:
- b6:2b:82:14:0a:94:5c:f2:50:ec:af:ce:ff:62:37:0d:ad:65:
- d3:06:41:53:ed:02:14:c8:b5:58:28:a1:ac:e0:5b:ec:b3:7f:
- 95:4a:fb:03:c8:ad:26:db:e6:66:78:12:4a:d9:9f:42:fb:e1:
- 98:e6:42:83:9b:8f:8f:67:24:e8:61:19:b5:dd:cd:b5:0b:26:
- 05:8e:c3:6e:c4:c8:75:b8:46:cf:e2:18:06:5e:a9:ae:a8:81:
- 9a:47:16:de:0c:28:6c:25:27:b9:de:b7:84:58:c6:1f:38:1e:
- a4:c4:cb:66
------BEGIN CERTIFICATE-----
-MIIF7DCCBNSgAwIBAgIQbsx6pacDIAm4zrz06VLUkTANBgkqhkiG9w0BAQUFADCB
-yjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL
-ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJp
-U2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxW
-ZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0
-aG9yaXR5IC0gRzUwHhcNMTAwMjA4MDAwMDAwWhcNMjAwMjA3MjM1OTU5WjCBtTEL
-MAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZW
-ZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTswOQYDVQQLEzJUZXJtcyBvZiB1c2UgYXQg
-aHR0cHM6Ly93d3cudmVyaXNpZ24uY29tL3JwYSAoYykxMDEvMC0GA1UEAxMmVmVy
-aVNpZ24gQ2xhc3MgMyBTZWN1cmUgU2VydmVyIENBIC0gRzMwggEiMA0GCSqGSIb3
-DQEBAQUAA4IBDwAwggEKAoIBAQCxh4QfwgxF9byrJZenraI+nLr2wTm4i8rCrFbG
-5btljkRPTc5v7QlK1K9OEJxoiy6Ve4mbE8riNDTB81vzSXtig0iBdNGIeGwCU/m8
-f0MmV1gzgzszChew0E6RJK2GfWQS3HRKNKEdCuqWHQsV/KNLO85jiND4LQyUhhDK
-tpo9yus3nABINYYpUHjoRWPNGUFP9ZXse5jUxHGzUL4os4+guVOc9cosI6n9FAbo
-GLSa6Dxugf3kzTU2s1HTaewSulZub5tXxYsU5w7HnO1KVGrJTcW/EbGuHGeBy0RV
-M5l/JJs/U0V/hhrzPPptf4H1uErT9YU3HLWm0AnkGHs4TvoPAgMBAAGjggHfMIIB
-2zA0BggrBgEFBQcBAQQoMCYwJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLnZlcmlz
-aWduLmNvbTASBgNVHRMBAf8ECDAGAQH/AgEAMHAGA1UdIARpMGcwZQYLYIZIAYb4
-RQEHFwMwVjAoBggrBgEFBQcCARYcaHR0cHM6Ly93d3cudmVyaXNpZ24uY29tL2Nw
-czAqBggrBgEFBQcCAjAeGhxodHRwczovL3d3dy52ZXJpc2lnbi5jb20vcnBhMDQG
-A1UdHwQtMCswKaAnoCWGI2h0dHA6Ly9jcmwudmVyaXNpZ24uY29tL3BjYTMtZzUu
-Y3JsMA4GA1UdDwEB/wQEAwIBBjBtBggrBgEFBQcBDARhMF+hXaBbMFkwVzBVFglp
-bWFnZS9naWYwITAfMAcGBSsOAwIaBBSP5dMahqyNjmvDz4Bq1EgYLHsZLjAlFiNo
-dHRwOi8vbG9nby52ZXJpc2lnbi5jb20vdnNsb2dvLmdpZjAoBgNVHREEITAfpB0w
-GzEZMBcGA1UEAxMQVmVyaVNpZ25NUEtJLTItNjAdBgNVHQ4EFgQUDURcFlNEwYJ+
-HSCrJfQBY9i+eaUwHwYDVR0jBBgwFoAUf9Nlp8Ld7LvwMAnzQzn6Aq8zMTMwDQYJ
-KoZIhvcNAQEFBQADggEBAAyDJO/dwwzZWJz+NrbrioBL0aP3nfPMU++CnqOh5pfB
-WJ11bOAdG0z60cEtBcDqbrIicFXZIDNAMwfCZYP6j0M3m+oOmmxw7vacgDvZN/R6
-bezQGH1JSsqZxxkoor7YdyT3hSaGbYcFQEFn0Sc67dxIHSLNCwuLvPSxe/20majp
-dirhGi2HbnTTiN0eIsbfFrYrghQKlFzyUOyvzv9iNw2tZdMGQVPtAhTItVgooazg
-W+yzf5VK+wPIrSbb5mZ4EkrZn0L74ZjmQoObj49nJOhhGbXdzbULJgWOw27EyHW4
-Rs/iGAZeqa6ogZpHFt4MKGwlJ7net4RYxh84HqTEy2Y=
------END CERTIFICATE-----
-#endif
-static const unsigned char kDERCert47[] = {
- 0x30, 0x82, 0x05, 0xec, 0x30, 0x82, 0x04, 0xd4, 0xa0, 0x03, 0x02, 0x01,
- 0x02, 0x02, 0x10, 0x6e, 0xcc, 0x7a, 0xa5, 0xa7, 0x03, 0x20, 0x09, 0xb8,
- 0xce, 0xbc, 0xf4, 0xe9, 0x52, 0xd4, 0x91, 0x30, 0x0d, 0x06, 0x09, 0x2a,
- 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x81,
- 0xca, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
- 0x55, 0x53, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13,
- 0x0e, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49,
- 0x6e, 0x63, 0x2e, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x0b,
- 0x13, 0x16, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x54,
- 0x72, 0x75, 0x73, 0x74, 0x20, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b,
- 0x31, 0x3a, 0x30, 0x38, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x31, 0x28,
- 0x63, 0x29, 0x20, 0x32, 0x30, 0x30, 0x36, 0x20, 0x56, 0x65, 0x72, 0x69,
- 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x20, 0x2d,
- 0x20, 0x46, 0x6f, 0x72, 0x20, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69,
- 0x7a, 0x65, 0x64, 0x20, 0x75, 0x73, 0x65, 0x20, 0x6f, 0x6e, 0x6c, 0x79,
- 0x31, 0x45, 0x30, 0x43, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x3c, 0x56,
- 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x43, 0x6c, 0x61, 0x73,
- 0x73, 0x20, 0x33, 0x20, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x20, 0x50,
- 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69,
- 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74,
- 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x20, 0x2d, 0x20, 0x47, 0x35, 0x30,
- 0x1e, 0x17, 0x0d, 0x31, 0x30, 0x30, 0x32, 0x30, 0x38, 0x30, 0x30, 0x30,
- 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x30, 0x30, 0x32, 0x30, 0x37,
- 0x32, 0x33, 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x81, 0xb5, 0x31, 0x0b,
- 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31,
- 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0e, 0x56, 0x65,
- 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e,
- 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x16, 0x56,
- 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x54, 0x72, 0x75, 0x73,
- 0x74, 0x20, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x31, 0x3b, 0x30,
- 0x39, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x32, 0x54, 0x65, 0x72, 0x6d,
- 0x73, 0x20, 0x6f, 0x66, 0x20, 0x75, 0x73, 0x65, 0x20, 0x61, 0x74, 0x20,
- 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e,
- 0x76, 0x65, 0x72, 0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d,
- 0x2f, 0x72, 0x70, 0x61, 0x20, 0x28, 0x63, 0x29, 0x31, 0x30, 0x31, 0x2f,
- 0x30, 0x2d, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x26, 0x56, 0x65, 0x72,
- 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x20,
- 0x33, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x53, 0x65, 0x72,
- 0x76, 0x65, 0x72, 0x20, 0x43, 0x41, 0x20, 0x2d, 0x20, 0x47, 0x33, 0x30,
- 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
- 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30,
- 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xb1, 0x87, 0x84, 0x1f,
- 0xc2, 0x0c, 0x45, 0xf5, 0xbc, 0xab, 0x25, 0x97, 0xa7, 0xad, 0xa2, 0x3e,
- 0x9c, 0xba, 0xf6, 0xc1, 0x39, 0xb8, 0x8b, 0xca, 0xc2, 0xac, 0x56, 0xc6,
- 0xe5, 0xbb, 0x65, 0x8e, 0x44, 0x4f, 0x4d, 0xce, 0x6f, 0xed, 0x09, 0x4a,
- 0xd4, 0xaf, 0x4e, 0x10, 0x9c, 0x68, 0x8b, 0x2e, 0x95, 0x7b, 0x89, 0x9b,
- 0x13, 0xca, 0xe2, 0x34, 0x34, 0xc1, 0xf3, 0x5b, 0xf3, 0x49, 0x7b, 0x62,
- 0x83, 0x48, 0x81, 0x74, 0xd1, 0x88, 0x78, 0x6c, 0x02, 0x53, 0xf9, 0xbc,
- 0x7f, 0x43, 0x26, 0x57, 0x58, 0x33, 0x83, 0x3b, 0x33, 0x0a, 0x17, 0xb0,
- 0xd0, 0x4e, 0x91, 0x24, 0xad, 0x86, 0x7d, 0x64, 0x12, 0xdc, 0x74, 0x4a,
- 0x34, 0xa1, 0x1d, 0x0a, 0xea, 0x96, 0x1d, 0x0b, 0x15, 0xfc, 0xa3, 0x4b,
- 0x3b, 0xce, 0x63, 0x88, 0xd0, 0xf8, 0x2d, 0x0c, 0x94, 0x86, 0x10, 0xca,
- 0xb6, 0x9a, 0x3d, 0xca, 0xeb, 0x37, 0x9c, 0x00, 0x48, 0x35, 0x86, 0x29,
- 0x50, 0x78, 0xe8, 0x45, 0x63, 0xcd, 0x19, 0x41, 0x4f, 0xf5, 0x95, 0xec,
- 0x7b, 0x98, 0xd4, 0xc4, 0x71, 0xb3, 0x50, 0xbe, 0x28, 0xb3, 0x8f, 0xa0,
- 0xb9, 0x53, 0x9c, 0xf5, 0xca, 0x2c, 0x23, 0xa9, 0xfd, 0x14, 0x06, 0xe8,
- 0x18, 0xb4, 0x9a, 0xe8, 0x3c, 0x6e, 0x81, 0xfd, 0xe4, 0xcd, 0x35, 0x36,
- 0xb3, 0x51, 0xd3, 0x69, 0xec, 0x12, 0xba, 0x56, 0x6e, 0x6f, 0x9b, 0x57,
- 0xc5, 0x8b, 0x14, 0xe7, 0x0e, 0xc7, 0x9c, 0xed, 0x4a, 0x54, 0x6a, 0xc9,
- 0x4d, 0xc5, 0xbf, 0x11, 0xb1, 0xae, 0x1c, 0x67, 0x81, 0xcb, 0x44, 0x55,
- 0x33, 0x99, 0x7f, 0x24, 0x9b, 0x3f, 0x53, 0x45, 0x7f, 0x86, 0x1a, 0xf3,
- 0x3c, 0xfa, 0x6d, 0x7f, 0x81, 0xf5, 0xb8, 0x4a, 0xd3, 0xf5, 0x85, 0x37,
- 0x1c, 0xb5, 0xa6, 0xd0, 0x09, 0xe4, 0x18, 0x7b, 0x38, 0x4e, 0xfa, 0x0f,
- 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0xdf, 0x30, 0x82, 0x01,
- 0xdb, 0x30, 0x34, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01,
- 0x01, 0x04, 0x28, 0x30, 0x26, 0x30, 0x24, 0x06, 0x08, 0x2b, 0x06, 0x01,
- 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x18, 0x68, 0x74, 0x74, 0x70, 0x3a,
- 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x76, 0x65, 0x72, 0x69, 0x73,
- 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x12, 0x06, 0x03, 0x55,
- 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff,
- 0x02, 0x01, 0x00, 0x30, 0x70, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x69,
- 0x30, 0x67, 0x30, 0x65, 0x06, 0x0b, 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8,
- 0x45, 0x01, 0x07, 0x17, 0x03, 0x30, 0x56, 0x30, 0x28, 0x06, 0x08, 0x2b,
- 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x1c, 0x68, 0x74, 0x74,
- 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x76, 0x65, 0x72,
- 0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x70,
- 0x73, 0x30, 0x2a, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02,
- 0x02, 0x30, 0x1e, 0x1a, 0x1c, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f,
- 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x76, 0x65, 0x72, 0x69, 0x73, 0x69, 0x67,
- 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x70, 0x61, 0x30, 0x34, 0x06,
- 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x2d, 0x30, 0x2b, 0x30, 0x29, 0xa0, 0x27,
- 0xa0, 0x25, 0x86, 0x23, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63,
- 0x72, 0x6c, 0x2e, 0x76, 0x65, 0x72, 0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e,
- 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x63, 0x61, 0x33, 0x2d, 0x67, 0x35, 0x2e,
- 0x63, 0x72, 0x6c, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01,
- 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x6d, 0x06, 0x08, 0x2b,
- 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x0c, 0x04, 0x61, 0x30, 0x5f, 0xa1,
- 0x5d, 0xa0, 0x5b, 0x30, 0x59, 0x30, 0x57, 0x30, 0x55, 0x16, 0x09, 0x69,
- 0x6d, 0x61, 0x67, 0x65, 0x2f, 0x67, 0x69, 0x66, 0x30, 0x21, 0x30, 0x1f,
- 0x30, 0x07, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x04, 0x14, 0x8f,
- 0xe5, 0xd3, 0x1a, 0x86, 0xac, 0x8d, 0x8e, 0x6b, 0xc3, 0xcf, 0x80, 0x6a,
- 0xd4, 0x48, 0x18, 0x2c, 0x7b, 0x19, 0x2e, 0x30, 0x25, 0x16, 0x23, 0x68,
- 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6c, 0x6f, 0x67, 0x6f, 0x2e, 0x76,
- 0x65, 0x72, 0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f,
- 0x76, 0x73, 0x6c, 0x6f, 0x67, 0x6f, 0x2e, 0x67, 0x69, 0x66, 0x30, 0x28,
- 0x06, 0x03, 0x55, 0x1d, 0x11, 0x04, 0x21, 0x30, 0x1f, 0xa4, 0x1d, 0x30,
- 0x1b, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x10,
- 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x4d, 0x50, 0x4b, 0x49,
- 0x2d, 0x32, 0x2d, 0x36, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04,
- 0x16, 0x04, 0x14, 0x0d, 0x44, 0x5c, 0x16, 0x53, 0x44, 0xc1, 0x82, 0x7e,
- 0x1d, 0x20, 0xab, 0x25, 0xf4, 0x01, 0x63, 0xd8, 0xbe, 0x79, 0xa5, 0x30,
- 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14,
- 0x7f, 0xd3, 0x65, 0xa7, 0xc2, 0xdd, 0xec, 0xbb, 0xf0, 0x30, 0x09, 0xf3,
- 0x43, 0x39, 0xfa, 0x02, 0xaf, 0x33, 0x31, 0x33, 0x30, 0x0d, 0x06, 0x09,
- 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03,
- 0x82, 0x01, 0x01, 0x00, 0x0c, 0x83, 0x24, 0xef, 0xdd, 0xc3, 0x0c, 0xd9,
- 0x58, 0x9c, 0xfe, 0x36, 0xb6, 0xeb, 0x8a, 0x80, 0x4b, 0xd1, 0xa3, 0xf7,
- 0x9d, 0xf3, 0xcc, 0x53, 0xef, 0x82, 0x9e, 0xa3, 0xa1, 0xe6, 0x97, 0xc1,
- 0x58, 0x9d, 0x75, 0x6c, 0xe0, 0x1d, 0x1b, 0x4c, 0xfa, 0xd1, 0xc1, 0x2d,
- 0x05, 0xc0, 0xea, 0x6e, 0xb2, 0x22, 0x70, 0x55, 0xd9, 0x20, 0x33, 0x40,
- 0x33, 0x07, 0xc2, 0x65, 0x83, 0xfa, 0x8f, 0x43, 0x37, 0x9b, 0xea, 0x0e,
- 0x9a, 0x6c, 0x70, 0xee, 0xf6, 0x9c, 0x80, 0x3b, 0xd9, 0x37, 0xf4, 0x7a,
- 0x6d, 0xec, 0xd0, 0x18, 0x7d, 0x49, 0x4a, 0xca, 0x99, 0xc7, 0x19, 0x28,
- 0xa2, 0xbe, 0xd8, 0x77, 0x24, 0xf7, 0x85, 0x26, 0x86, 0x6d, 0x87, 0x05,
- 0x40, 0x41, 0x67, 0xd1, 0x27, 0x3a, 0xed, 0xdc, 0x48, 0x1d, 0x22, 0xcd,
- 0x0b, 0x0b, 0x8b, 0xbc, 0xf4, 0xb1, 0x7b, 0xfd, 0xb4, 0x99, 0xa8, 0xe9,
- 0x76, 0x2a, 0xe1, 0x1a, 0x2d, 0x87, 0x6e, 0x74, 0xd3, 0x88, 0xdd, 0x1e,
- 0x22, 0xc6, 0xdf, 0x16, 0xb6, 0x2b, 0x82, 0x14, 0x0a, 0x94, 0x5c, 0xf2,
- 0x50, 0xec, 0xaf, 0xce, 0xff, 0x62, 0x37, 0x0d, 0xad, 0x65, 0xd3, 0x06,
- 0x41, 0x53, 0xed, 0x02, 0x14, 0xc8, 0xb5, 0x58, 0x28, 0xa1, 0xac, 0xe0,
- 0x5b, 0xec, 0xb3, 0x7f, 0x95, 0x4a, 0xfb, 0x03, 0xc8, 0xad, 0x26, 0xdb,
- 0xe6, 0x66, 0x78, 0x12, 0x4a, 0xd9, 0x9f, 0x42, 0xfb, 0xe1, 0x98, 0xe6,
- 0x42, 0x83, 0x9b, 0x8f, 0x8f, 0x67, 0x24, 0xe8, 0x61, 0x19, 0xb5, 0xdd,
- 0xcd, 0xb5, 0x0b, 0x26, 0x05, 0x8e, 0xc3, 0x6e, 0xc4, 0xc8, 0x75, 0xb8,
- 0x46, 0xcf, 0xe2, 0x18, 0x06, 0x5e, 0xa9, 0xae, 0xa8, 0x81, 0x9a, 0x47,
- 0x16, 0xde, 0x0c, 0x28, 0x6c, 0x25, 0x27, 0xb9, 0xde, 0xb7, 0x84, 0x58,
- 0xc6, 0x1f, 0x38, 0x1e, 0xa4, 0xc4, 0xcb, 0x66,
-};
-
-#if 0
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number:
- 2c:48:dd:93:0d:f5:59:8e:f9:3c:99:54:7a:60:ed:43
- Signature Algorithm: sha1WithRSAEncryption
- Issuer: C=US, O=VeriSign, Inc., OU=VeriSign Trust Network, OU=(c) 2006 VeriSign, Inc. - For authorized use only, CN=VeriSign Class 3 Public Primary Certification Authority - G5
- Validity
- Not Before: Nov 8 00:00:00 2006 GMT
- Not After : Nov 7 23:59:59 2016 GMT
- Subject: C=US, O=VeriSign, Inc., OU=VeriSign Trust Network, OU=Terms of use at https://www.verisign.com/rpa (c)06, CN=VeriSign Class 3 Extended Validation SSL SGC CA
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:bd:56:88:ba:88:34:64:64:cf:cd:ca:b0:ee:e7:
- 19:73:c5:72:d9:bb:45:bc:b5:a8:ff:83:be:1c:03:
- db:ed:89:b7:2e:10:1a:25:bc:55:ca:41:a1:9f:0b:
- cf:19:5e:70:b9:5e:39:4b:9e:31:1c:5f:87:ae:2a:
- aa:a8:2b:a2:1b:3b:10:23:5f:13:b1:dd:08:8c:4e:
- 14:da:83:81:e3:b5:8c:e3:68:ed:24:67:ce:56:b6:
- ac:9b:73:96:44:db:8a:8c:b3:d6:f0:71:93:8e:db:
- 71:54:4a:eb:73:59:6a:8f:70:51:2c:03:9f:97:d1:
- cc:11:7a:bc:62:0d:95:2a:c9:1c:75:57:e9:f5:c7:
- ea:ba:84:35:cb:c7:85:5a:7e:e4:4d:e1:11:97:7d:
- 0e:20:34:45:db:f1:a2:09:eb:eb:3d:9e:b8:96:43:
- 5e:34:4b:08:25:1e:43:1a:a2:d9:b7:8a:01:34:3d:
- c3:f8:e5:af:4f:8c:ff:cd:65:f0:23:4e:c5:97:b3:
- 5c:da:90:1c:82:85:0d:06:0d:c1:22:b6:7b:28:a4:
- 03:c3:4c:53:d1:58:bc:72:bc:08:39:fc:a0:76:a8:
- a8:e9:4b:6e:88:3d:e3:b3:31:25:8c:73:29:48:0e:
- 32:79:06:ed:3d:43:f4:f6:e4:e9:fc:7d:be:8e:08:
- d5:1f
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Subject Key Identifier:
- 4E:43:C8:1D:76:EF:37:53:7A:4F:F2:58:6F:94:F3:38:E2:D5:BD:DF
- X509v3 Basic Constraints: critical
- CA:TRUE, pathlen:0
- X509v3 Certificate Policies:
- Policy: X509v3 Any Policy
- CPS: https://www.verisign.com/cps
-
- X509v3 CRL Distribution Points:
-
- Full Name:
- URI:http://EVSecure-crl.verisign.com/pca3-g5.crl
-
- X509v3 Key Usage: critical
- Certificate Sign, CRL Sign
- Netscape Cert Type:
- SSL CA, S/MIME CA
- 1.3.6.1.5.5.7.1.12:
- 0_.].[0Y0W0U..image/gif0!0.0...+..............k...j.H.,{..0%.#http://logo.verisign.com/vslogo.gif
- X509v3 Subject Alternative Name:
- DirName:/CN=Class3CA2048-1-48
- X509v3 Authority Key Identifier:
- keyid:7F:D3:65:A7:C2:DD:EC:BB:F0:30:09:F3:43:39:FA:02:AF:33:31:33
-
- Authority Information Access:
- OCSP - URI:http://EVSecure-ocsp.verisign.com
-
- X509v3 Extended Key Usage:
- Netscape Server Gated Crypto, 2.16.840.1.113733.1.8.1, TLS Web Server Authentication, TLS Web Client Authentication
- Signature Algorithm: sha1WithRSAEncryption
- 27:74:a6:34:ea:1d:9d:e1:53:d6:1c:9d:0c:a7:5b:4c:a9:67:
- f2:f0:32:b7:01:0f:fb:42:18:38:de:e4:ee:49:c8:13:c9:0b:
- ec:04:c3:40:71:18:72:76:43:02:23:5d:ab:7b:c8:48:14:1a:
- c8:7b:1d:fc:f6:0a:9f:36:a1:d2:09:73:71:66:96:75:51:34:
- bf:99:30:51:67:9d:54:b7:26:45:ac:73:08:23:86:26:99:71:
- f4:8e:d7:ea:39:9b:06:09:23:bf:62:dd:a8:c4:b6:7d:a4:89:
- 07:3e:f3:6d:ae:40:59:50:79:97:37:3d:32:78:7d:b2:63:4b:
- f9:ea:08:69:0e:13:ed:e8:cf:bb:ac:05:86:ca:22:cf:88:62:
- 5d:3c:22:49:d8:63:d5:24:a6:bd:ef:5c:e3:cc:20:3b:22:ea:
- fc:44:c6:a8:e5:1f:e1:86:cd:0c:4d:8f:93:53:d9:7f:ee:a1:
- 08:a7:b3:30:96:49:70:6e:a3:6c:3d:d0:63:ef:25:66:63:cc:
- aa:b7:18:17:4e:ea:70:76:f6:ba:42:a6:80:37:09:4e:9f:66:
- 88:2e:6b:33:66:c8:c0:71:a4:41:eb:5a:e3:fc:14:2e:4b:88:
- fd:ae:6e:5b:65:e9:27:e4:bf:e4:b0:23:c1:b2:7d:5b:62:25:
- d7:3e:10:d4
------BEGIN CERTIFICATE-----
-MIIGHjCCBQagAwIBAgIQLEjdkw31WY75PJlUemDtQzANBgkqhkiG9w0BAQUFADCB
-yjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL
-ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJp
-U2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxW
-ZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0
-aG9yaXR5IC0gRzUwHhcNMDYxMTA4MDAwMDAwWhcNMTYxMTA3MjM1OTU5WjCBvjEL
-MAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZW
-ZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTswOQYDVQQLEzJUZXJtcyBvZiB1c2UgYXQg
-aHR0cHM6Ly93d3cudmVyaXNpZ24uY29tL3JwYSAoYykwNjE4MDYGA1UEAxMvVmVy
-aVNpZ24gQ2xhc3MgMyBFeHRlbmRlZCBWYWxpZGF0aW9uIFNTTCBTR0MgQ0EwggEi
-MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC9Voi6iDRkZM/NyrDu5xlzxXLZ
-u0W8taj/g74cA9vtibcuEBolvFXKQaGfC88ZXnC5XjlLnjEcX4euKqqoK6IbOxAj
-XxOx3QiMThTag4HjtYzjaO0kZ85Wtqybc5ZE24qMs9bwcZOO23FUSutzWWqPcFEs
-A5+X0cwRerxiDZUqyRx1V+n1x+q6hDXLx4VafuRN4RGXfQ4gNEXb8aIJ6+s9nriW
-Q140SwglHkMaotm3igE0PcP45a9PjP/NZfAjTsWXs1zakByChQ0GDcEitnsopAPD
-TFPRWLxyvAg5/KB2qKjpS26IPeOzMSWMcylIDjJ5Bu09Q/T25On8fb6OCNUfAgMB
-AAGjggIIMIICBDAdBgNVHQ4EFgQUTkPIHXbvN1N6T/JYb5TzOOLVvd8wEgYDVR0T
-AQH/BAgwBgEB/wIBADA9BgNVHSAENjA0MDIGBFUdIAAwKjAoBggrBgEFBQcCARYc
-aHR0cHM6Ly93d3cudmVyaXNpZ24uY29tL2NwczA9BgNVHR8ENjA0MDKgMKAuhixo
-dHRwOi8vRVZTZWN1cmUtY3JsLnZlcmlzaWduLmNvbS9wY2EzLWc1LmNybDAOBgNV
-HQ8BAf8EBAMCAQYwEQYJYIZIAYb4QgEBBAQDAgEGMG0GCCsGAQUFBwEMBGEwX6Fd
-oFswWTBXMFUWCWltYWdlL2dpZjAhMB8wBwYFKw4DAhoEFI/l0xqGrI2Oa8PPgGrU
-SBgsexkuMCUWI2h0dHA6Ly9sb2dvLnZlcmlzaWduLmNvbS92c2xvZ28uZ2lmMCkG
-A1UdEQQiMCCkHjAcMRowGAYDVQQDExFDbGFzczNDQTIwNDgtMS00ODAfBgNVHSME
-GDAWgBR/02Wnwt3su/AwCfNDOfoCrzMxMzA9BggrBgEFBQcBAQQxMC8wLQYIKwYB
-BQUHMAGGIWh0dHA6Ly9FVlNlY3VyZS1vY3NwLnZlcmlzaWduLmNvbTA0BgNVHSUE
-LTArBglghkgBhvhCBAEGCmCGSAGG+EUBCAEGCCsGAQUFBwMBBggrBgEFBQcDAjAN
-BgkqhkiG9w0BAQUFAAOCAQEAJ3SmNOodneFT1hydDKdbTKln8vAytwEP+0IYON7k
-7knIE8kL7ATDQHEYcnZDAiNdq3vISBQayHsd/PYKnzah0glzcWaWdVE0v5kwUWed
-VLcmRaxzCCOGJplx9I7X6jmbBgkjv2LdqMS2faSJBz7zba5AWVB5lzc9Mnh9smNL
-+eoIaQ4T7ejPu6wFhsoiz4hiXTwiSdhj1SSmve9c48wgOyLq/ETGqOUf4YbNDE2P
-k1PZf+6hCKezMJZJcG6jbD3QY+8lZmPMqrcYF07qcHb2ukKmgDcJTp9miC5rM2bI
-wHGkQeta4/wULkuI/a5uW2XpJ+S/5LAjwbJ9W2Il1z4Q1A==
------END CERTIFICATE-----
-#endif
-static const unsigned char kDERCert48[] = {
- 0x30, 0x82, 0x06, 0x1e, 0x30, 0x82, 0x05, 0x06, 0xa0, 0x03, 0x02, 0x01,
- 0x02, 0x02, 0x10, 0x2c, 0x48, 0xdd, 0x93, 0x0d, 0xf5, 0x59, 0x8e, 0xf9,
- 0x3c, 0x99, 0x54, 0x7a, 0x60, 0xed, 0x43, 0x30, 0x0d, 0x06, 0x09, 0x2a,
- 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x81,
- 0xca, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
- 0x55, 0x53, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13,
- 0x0e, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49,
- 0x6e, 0x63, 0x2e, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x0b,
- 0x13, 0x16, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x54,
- 0x72, 0x75, 0x73, 0x74, 0x20, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b,
- 0x31, 0x3a, 0x30, 0x38, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x31, 0x28,
- 0x63, 0x29, 0x20, 0x32, 0x30, 0x30, 0x36, 0x20, 0x56, 0x65, 0x72, 0x69,
- 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x20, 0x2d,
- 0x20, 0x46, 0x6f, 0x72, 0x20, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69,
- 0x7a, 0x65, 0x64, 0x20, 0x75, 0x73, 0x65, 0x20, 0x6f, 0x6e, 0x6c, 0x79,
- 0x31, 0x45, 0x30, 0x43, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x3c, 0x56,
- 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x43, 0x6c, 0x61, 0x73,
- 0x73, 0x20, 0x33, 0x20, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x20, 0x50,
- 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69,
- 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74,
- 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x20, 0x2d, 0x20, 0x47, 0x35, 0x30,
- 0x1e, 0x17, 0x0d, 0x30, 0x36, 0x31, 0x31, 0x30, 0x38, 0x30, 0x30, 0x30,
- 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x31, 0x36, 0x31, 0x31, 0x30, 0x37,
- 0x32, 0x33, 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x81, 0xbe, 0x31, 0x0b,
- 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31,
- 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0e, 0x56, 0x65,
- 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e,
- 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x16, 0x56,
- 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x54, 0x72, 0x75, 0x73,
- 0x74, 0x20, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x31, 0x3b, 0x30,
- 0x39, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x32, 0x54, 0x65, 0x72, 0x6d,
- 0x73, 0x20, 0x6f, 0x66, 0x20, 0x75, 0x73, 0x65, 0x20, 0x61, 0x74, 0x20,
- 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e,
- 0x76, 0x65, 0x72, 0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d,
- 0x2f, 0x72, 0x70, 0x61, 0x20, 0x28, 0x63, 0x29, 0x30, 0x36, 0x31, 0x38,
- 0x30, 0x36, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x2f, 0x56, 0x65, 0x72,
- 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x20,
- 0x33, 0x20, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x64, 0x65, 0x64, 0x20, 0x56,
- 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x53, 0x53,
- 0x4c, 0x20, 0x53, 0x47, 0x43, 0x20, 0x43, 0x41, 0x30, 0x82, 0x01, 0x22,
- 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
- 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a,
- 0x02, 0x82, 0x01, 0x01, 0x00, 0xbd, 0x56, 0x88, 0xba, 0x88, 0x34, 0x64,
- 0x64, 0xcf, 0xcd, 0xca, 0xb0, 0xee, 0xe7, 0x19, 0x73, 0xc5, 0x72, 0xd9,
- 0xbb, 0x45, 0xbc, 0xb5, 0xa8, 0xff, 0x83, 0xbe, 0x1c, 0x03, 0xdb, 0xed,
- 0x89, 0xb7, 0x2e, 0x10, 0x1a, 0x25, 0xbc, 0x55, 0xca, 0x41, 0xa1, 0x9f,
- 0x0b, 0xcf, 0x19, 0x5e, 0x70, 0xb9, 0x5e, 0x39, 0x4b, 0x9e, 0x31, 0x1c,
- 0x5f, 0x87, 0xae, 0x2a, 0xaa, 0xa8, 0x2b, 0xa2, 0x1b, 0x3b, 0x10, 0x23,
- 0x5f, 0x13, 0xb1, 0xdd, 0x08, 0x8c, 0x4e, 0x14, 0xda, 0x83, 0x81, 0xe3,
- 0xb5, 0x8c, 0xe3, 0x68, 0xed, 0x24, 0x67, 0xce, 0x56, 0xb6, 0xac, 0x9b,
- 0x73, 0x96, 0x44, 0xdb, 0x8a, 0x8c, 0xb3, 0xd6, 0xf0, 0x71, 0x93, 0x8e,
- 0xdb, 0x71, 0x54, 0x4a, 0xeb, 0x73, 0x59, 0x6a, 0x8f, 0x70, 0x51, 0x2c,
- 0x03, 0x9f, 0x97, 0xd1, 0xcc, 0x11, 0x7a, 0xbc, 0x62, 0x0d, 0x95, 0x2a,
- 0xc9, 0x1c, 0x75, 0x57, 0xe9, 0xf5, 0xc7, 0xea, 0xba, 0x84, 0x35, 0xcb,
- 0xc7, 0x85, 0x5a, 0x7e, 0xe4, 0x4d, 0xe1, 0x11, 0x97, 0x7d, 0x0e, 0x20,
- 0x34, 0x45, 0xdb, 0xf1, 0xa2, 0x09, 0xeb, 0xeb, 0x3d, 0x9e, 0xb8, 0x96,
- 0x43, 0x5e, 0x34, 0x4b, 0x08, 0x25, 0x1e, 0x43, 0x1a, 0xa2, 0xd9, 0xb7,
- 0x8a, 0x01, 0x34, 0x3d, 0xc3, 0xf8, 0xe5, 0xaf, 0x4f, 0x8c, 0xff, 0xcd,
- 0x65, 0xf0, 0x23, 0x4e, 0xc5, 0x97, 0xb3, 0x5c, 0xda, 0x90, 0x1c, 0x82,
- 0x85, 0x0d, 0x06, 0x0d, 0xc1, 0x22, 0xb6, 0x7b, 0x28, 0xa4, 0x03, 0xc3,
- 0x4c, 0x53, 0xd1, 0x58, 0xbc, 0x72, 0xbc, 0x08, 0x39, 0xfc, 0xa0, 0x76,
- 0xa8, 0xa8, 0xe9, 0x4b, 0x6e, 0x88, 0x3d, 0xe3, 0xb3, 0x31, 0x25, 0x8c,
- 0x73, 0x29, 0x48, 0x0e, 0x32, 0x79, 0x06, 0xed, 0x3d, 0x43, 0xf4, 0xf6,
- 0xe4, 0xe9, 0xfc, 0x7d, 0xbe, 0x8e, 0x08, 0xd5, 0x1f, 0x02, 0x03, 0x01,
- 0x00, 0x01, 0xa3, 0x82, 0x02, 0x08, 0x30, 0x82, 0x02, 0x04, 0x30, 0x1d,
- 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x4e, 0x43, 0xc8,
- 0x1d, 0x76, 0xef, 0x37, 0x53, 0x7a, 0x4f, 0xf2, 0x58, 0x6f, 0x94, 0xf3,
- 0x38, 0xe2, 0xd5, 0xbd, 0xdf, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13,
- 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01,
- 0x00, 0x30, 0x3d, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x36, 0x30, 0x34,
- 0x30, 0x32, 0x06, 0x04, 0x55, 0x1d, 0x20, 0x00, 0x30, 0x2a, 0x30, 0x28,
- 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x1c,
- 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e,
- 0x76, 0x65, 0x72, 0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d,
- 0x2f, 0x63, 0x70, 0x73, 0x30, 0x3d, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04,
- 0x36, 0x30, 0x34, 0x30, 0x32, 0xa0, 0x30, 0xa0, 0x2e, 0x86, 0x2c, 0x68,
- 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x45, 0x56, 0x53, 0x65, 0x63, 0x75,
- 0x72, 0x65, 0x2d, 0x63, 0x72, 0x6c, 0x2e, 0x76, 0x65, 0x72, 0x69, 0x73,
- 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x63, 0x61, 0x33,
- 0x2d, 0x67, 0x35, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x0e, 0x06, 0x03, 0x55,
- 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30,
- 0x11, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42, 0x01, 0x01,
- 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x6d, 0x06, 0x08, 0x2b, 0x06,
- 0x01, 0x05, 0x05, 0x07, 0x01, 0x0c, 0x04, 0x61, 0x30, 0x5f, 0xa1, 0x5d,
- 0xa0, 0x5b, 0x30, 0x59, 0x30, 0x57, 0x30, 0x55, 0x16, 0x09, 0x69, 0x6d,
- 0x61, 0x67, 0x65, 0x2f, 0x67, 0x69, 0x66, 0x30, 0x21, 0x30, 0x1f, 0x30,
- 0x07, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x04, 0x14, 0x8f, 0xe5,
- 0xd3, 0x1a, 0x86, 0xac, 0x8d, 0x8e, 0x6b, 0xc3, 0xcf, 0x80, 0x6a, 0xd4,
- 0x48, 0x18, 0x2c, 0x7b, 0x19, 0x2e, 0x30, 0x25, 0x16, 0x23, 0x68, 0x74,
- 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6c, 0x6f, 0x67, 0x6f, 0x2e, 0x76, 0x65,
- 0x72, 0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x76,
- 0x73, 0x6c, 0x6f, 0x67, 0x6f, 0x2e, 0x67, 0x69, 0x66, 0x30, 0x29, 0x06,
- 0x03, 0x55, 0x1d, 0x11, 0x04, 0x22, 0x30, 0x20, 0xa4, 0x1e, 0x30, 0x1c,
- 0x31, 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x11, 0x43,
- 0x6c, 0x61, 0x73, 0x73, 0x33, 0x43, 0x41, 0x32, 0x30, 0x34, 0x38, 0x2d,
- 0x31, 0x2d, 0x34, 0x38, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04,
- 0x18, 0x30, 0x16, 0x80, 0x14, 0x7f, 0xd3, 0x65, 0xa7, 0xc2, 0xdd, 0xec,
- 0xbb, 0xf0, 0x30, 0x09, 0xf3, 0x43, 0x39, 0xfa, 0x02, 0xaf, 0x33, 0x31,
- 0x33, 0x30, 0x3d, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01,
- 0x01, 0x04, 0x31, 0x30, 0x2f, 0x30, 0x2d, 0x06, 0x08, 0x2b, 0x06, 0x01,
- 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x21, 0x68, 0x74, 0x74, 0x70, 0x3a,
- 0x2f, 0x2f, 0x45, 0x56, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x2d, 0x6f,
- 0x63, 0x73, 0x70, 0x2e, 0x76, 0x65, 0x72, 0x69, 0x73, 0x69, 0x67, 0x6e,
- 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x34, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04,
- 0x2d, 0x30, 0x2b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42,
- 0x04, 0x01, 0x06, 0x0a, 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x45, 0x01,
- 0x08, 0x01, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x01,
- 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x02, 0x30, 0x0d,
- 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05,
- 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x27, 0x74, 0xa6, 0x34, 0xea, 0x1d,
- 0x9d, 0xe1, 0x53, 0xd6, 0x1c, 0x9d, 0x0c, 0xa7, 0x5b, 0x4c, 0xa9, 0x67,
- 0xf2, 0xf0, 0x32, 0xb7, 0x01, 0x0f, 0xfb, 0x42, 0x18, 0x38, 0xde, 0xe4,
- 0xee, 0x49, 0xc8, 0x13, 0xc9, 0x0b, 0xec, 0x04, 0xc3, 0x40, 0x71, 0x18,
- 0x72, 0x76, 0x43, 0x02, 0x23, 0x5d, 0xab, 0x7b, 0xc8, 0x48, 0x14, 0x1a,
- 0xc8, 0x7b, 0x1d, 0xfc, 0xf6, 0x0a, 0x9f, 0x36, 0xa1, 0xd2, 0x09, 0x73,
- 0x71, 0x66, 0x96, 0x75, 0x51, 0x34, 0xbf, 0x99, 0x30, 0x51, 0x67, 0x9d,
- 0x54, 0xb7, 0x26, 0x45, 0xac, 0x73, 0x08, 0x23, 0x86, 0x26, 0x99, 0x71,
- 0xf4, 0x8e, 0xd7, 0xea, 0x39, 0x9b, 0x06, 0x09, 0x23, 0xbf, 0x62, 0xdd,
- 0xa8, 0xc4, 0xb6, 0x7d, 0xa4, 0x89, 0x07, 0x3e, 0xf3, 0x6d, 0xae, 0x40,
- 0x59, 0x50, 0x79, 0x97, 0x37, 0x3d, 0x32, 0x78, 0x7d, 0xb2, 0x63, 0x4b,
- 0xf9, 0xea, 0x08, 0x69, 0x0e, 0x13, 0xed, 0xe8, 0xcf, 0xbb, 0xac, 0x05,
- 0x86, 0xca, 0x22, 0xcf, 0x88, 0x62, 0x5d, 0x3c, 0x22, 0x49, 0xd8, 0x63,
- 0xd5, 0x24, 0xa6, 0xbd, 0xef, 0x5c, 0xe3, 0xcc, 0x20, 0x3b, 0x22, 0xea,
- 0xfc, 0x44, 0xc6, 0xa8, 0xe5, 0x1f, 0xe1, 0x86, 0xcd, 0x0c, 0x4d, 0x8f,
- 0x93, 0x53, 0xd9, 0x7f, 0xee, 0xa1, 0x08, 0xa7, 0xb3, 0x30, 0x96, 0x49,
- 0x70, 0x6e, 0xa3, 0x6c, 0x3d, 0xd0, 0x63, 0xef, 0x25, 0x66, 0x63, 0xcc,
- 0xaa, 0xb7, 0x18, 0x17, 0x4e, 0xea, 0x70, 0x76, 0xf6, 0xba, 0x42, 0xa6,
- 0x80, 0x37, 0x09, 0x4e, 0x9f, 0x66, 0x88, 0x2e, 0x6b, 0x33, 0x66, 0xc8,
- 0xc0, 0x71, 0xa4, 0x41, 0xeb, 0x5a, 0xe3, 0xfc, 0x14, 0x2e, 0x4b, 0x88,
- 0xfd, 0xae, 0x6e, 0x5b, 0x65, 0xe9, 0x27, 0xe4, 0xbf, 0xe4, 0xb0, 0x23,
- 0xc1, 0xb2, 0x7d, 0x5b, 0x62, 0x25, 0xd7, 0x3e, 0x10, 0xd4,
-};
-
-#if 0
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number:
- 64:1b:e8:20:ce:02:08:13:f3:2d:4d:2d:95:d6:7e:67
- Signature Algorithm: sha1WithRSAEncryption
- Issuer: C=US, O=VeriSign, Inc., OU=VeriSign Trust Network, OU=(c) 2006 VeriSign, Inc. - For authorized use only, CN=VeriSign Class 3 Public Primary Certification Authority - G5
- Validity
- Not Before: Feb 8 00:00:00 2010 GMT
- Not After : Feb 7 23:59:59 2020 GMT
- Subject: C=US, O=VeriSign, Inc., OU=VeriSign Trust Network, OU=Terms of use at https://www.verisign.com/rpa (c)10, CN=VeriSign Class 3 International Server CA - G3
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:99:d6:9c:62:f0:15:f4:81:9a:41:08:59:8f:13:
- 9d:17:c9:9f:51:dc:da:b1:52:ef:ff:e3:41:dd:e0:
- df:c4:28:c6:e3:ad:79:1f:27:10:98:b8:bb:20:97:
- c1:28:44:41:0f:ea:a9:a8:52:cf:4d:4e:1b:8b:bb:
- b5:c4:76:d9:cc:56:06:ee:b3:55:20:2a:de:15:8d:
- 71:cb:54:c8:6f:17:cd:89:00:e4:dc:ff:e1:c0:1f:
- 68:71:e9:c7:29:2e:7e:bc:3b:fc:e5:bb:ab:26:54:
- 8b:66:90:cd:f6:92:b9:31:24:80:bc:9e:6c:d5:fc:
- 7e:d2:e1:4b:8c:dc:42:fa:44:4b:5f:f8:18:b5:2e:
- 30:f4:3d:12:98:d3:62:05:73:54:a6:9c:a2:1d:be:
- 52:83:3a:07:46:c4:3b:02:56:21:bf:f2:51:4f:d0:
- a6:99:39:e9:ae:a5:3f:89:9b:9c:7d:fe:4d:60:07:
- 25:20:f7:bb:d7:69:83:2b:82:93:43:37:d9:83:41:
- 1b:6b:0b:ab:4a:66:84:4f:4a:8e:de:7e:34:99:8e:
- 68:d6:ca:39:06:9b:4c:b3:9a:48:4d:13:46:b4:58:
- 21:04:c4:fb:a0:4d:ac:2e:4b:62:12:e3:fb:4d:f6:
- c9:51:00:01:1f:fc:1e:6a:81:2a:38:e0:b9:4f:d6:
- 2d:45
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Basic Constraints: critical
- CA:TRUE, pathlen:0
- X509v3 Certificate Policies:
- Policy: 2.16.840.1.113733.1.7.23.3
- CPS: https://www.verisign.com/cps
- User Notice:
- Explicit Text: https://www.verisign.com/rpa
-
- X509v3 Key Usage: critical
- Certificate Sign, CRL Sign
- 1.3.6.1.5.5.7.1.12:
- 0_.].[0Y0W0U..image/gif0!0.0...+..............k...j.H.,{..0%.#http://logo.verisign.com/vslogo.gif
- X509v3 Extended Key Usage:
- TLS Web Server Authentication, TLS Web Client Authentication, Netscape Server Gated Crypto, 2.16.840.1.113733.1.8.1
- Authority Information Access:
- OCSP - URI:http://ocsp.verisign.com
-
- X509v3 CRL Distribution Points:
-
- Full Name:
- URI:http://crl.verisign.com/pca3-g5.crl
-
- X509v3 Subject Alternative Name:
- DirName:/CN=VeriSignMPKI-2-7
- X509v3 Subject Key Identifier:
- D7:9B:7C:D8:22:A0:15:F7:DD:AD:5F:CE:29:9B:58:C3:BC:46:00:B5
- X509v3 Authority Key Identifier:
- keyid:7F:D3:65:A7:C2:DD:EC:BB:F0:30:09:F3:43:39:FA:02:AF:33:31:33
-
- Signature Algorithm: sha1WithRSAEncryption
- 71:b5:7d:73:52:4a:dd:d7:4d:34:2b:2e:af:94:46:a5:49:50:
- 02:4f:f8:2f:17:70:f2:13:dc:1f:21:86:aa:c2:4f:7c:37:3c:
- d4:46:78:ae:5d:78:6f:d1:ba:5a:bc:10:ab:58:36:c5:8c:62:
- 15:45:60:17:21:e2:d5:42:a8:77:a1:55:d8:43:04:51:f6:6e:
- ba:48:e6:5d:4c:b7:44:d3:3e:a4:d5:d6:33:9a:9f:0d:e6:d7:
- 4e:96:44:95:5a:6c:d6:a3:16:53:0e:98:43:ce:a4:b8:c3:66:
- 7a:05:5c:62:10:e8:1b:12:db:7d:2e:76:50:ff:df:d7:6b:1b:
- cc:8a:cc:71:fa:b3:40:56:7c:33:7a:77:94:5b:f5:0b:53:fb:
- 0e:5f:bc:68:fb:af:2a:ee:30:37:79:16:93:25:7f:4d:10:ff:
- 57:fb:bf:6e:3b:33:21:de:79:dc:86:17:59:2d:43:64:b7:a6:
- 66:87:ea:bc:96:46:19:1a:86:8b:6f:d7:b7:49:00:5b:db:a3:
- bf:29:9a:ee:f7:d3:33:ae:a3:f4:9e:4c:ca:5e:69:d4:1b:ad:
- b7:90:77:6a:d8:59:6f:79:ab:01:fa:55:f0:8a:21:66:e5:65:
- 6e:fd:7c:d3:df:1e:eb:7e:3f:06:90:fb:19:0b:d3:06:02:1b:
- 78:43:99:a8
------BEGIN CERTIFICATE-----
-MIIGKTCCBRGgAwIBAgIQZBvoIM4CCBPzLU0tldZ+ZzANBgkqhkiG9w0BAQUFADCB
-yjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL
-ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJp
-U2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxW
-ZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0
-aG9yaXR5IC0gRzUwHhcNMTAwMjA4MDAwMDAwWhcNMjAwMjA3MjM1OTU5WjCBvDEL
-MAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZW
-ZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTswOQYDVQQLEzJUZXJtcyBvZiB1c2UgYXQg
-aHR0cHM6Ly93d3cudmVyaXNpZ24uY29tL3JwYSAoYykxMDE2MDQGA1UEAxMtVmVy
-aVNpZ24gQ2xhc3MgMyBJbnRlcm5hdGlvbmFsIFNlcnZlciBDQSAtIEczMIIBIjAN
-BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmdacYvAV9IGaQQhZjxOdF8mfUdza
-sVLv/+NB3eDfxCjG4615HycQmLi7IJfBKERBD+qpqFLPTU4bi7u1xHbZzFYG7rNV
-ICreFY1xy1TIbxfNiQDk3P/hwB9ocenHKS5+vDv85burJlSLZpDN9pK5MSSAvJ5s
-1fx+0uFLjNxC+kRLX/gYtS4w9D0SmNNiBXNUppyiHb5SgzoHRsQ7AlYhv/JRT9Cm
-mTnprqU/iZucff5NYAclIPe712mDK4KTQzfZg0EbawurSmaET0qO3n40mY5o1so5
-BptMs5pITRNGtFghBMT7oE2sLktiEuP7TfbJUQABH/weaoEqOOC5T9YtRQIDAQAB
-o4ICFTCCAhEwEgYDVR0TAQH/BAgwBgEB/wIBADBwBgNVHSAEaTBnMGUGC2CGSAGG
-+EUBBxcDMFYwKAYIKwYBBQUHAgEWHGh0dHBzOi8vd3d3LnZlcmlzaWduLmNvbS9j
-cHMwKgYIKwYBBQUHAgIwHhocaHR0cHM6Ly93d3cudmVyaXNpZ24uY29tL3JwYTAO
-BgNVHQ8BAf8EBAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2Uv
-Z2lmMCEwHzAHBgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDov
-L2xvZ28udmVyaXNpZ24uY29tL3ZzbG9nby5naWYwNAYDVR0lBC0wKwYIKwYBBQUH
-AwEGCCsGAQUFBwMCBglghkgBhvhCBAEGCmCGSAGG+EUBCAEwNAYIKwYBBQUHAQEE
-KDAmMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC52ZXJpc2lnbi5jb20wNAYDVR0f
-BC0wKzApoCegJYYjaHR0cDovL2NybC52ZXJpc2lnbi5jb20vcGNhMy1nNS5jcmww
-KAYDVR0RBCEwH6QdMBsxGTAXBgNVBAMTEFZlcmlTaWduTVBLSS0yLTcwHQYDVR0O
-BBYEFNebfNgioBX33a1fzimbWMO8RgC1MB8GA1UdIwQYMBaAFH/TZafC3ey78DAJ
-80M5+gKvMzEzMA0GCSqGSIb3DQEBBQUAA4IBAQBxtX1zUkrd1000Ky6vlEalSVAC
-T/gvF3DyE9wfIYaqwk98NzzURniuXXhv0bpavBCrWDbFjGIVRWAXIeLVQqh3oVXY
-QwRR9m66SOZdTLdE0z6k1dYzmp8N5tdOlkSVWmzWoxZTDphDzqS4w2Z6BVxiEOgb
-Ett9LnZQ/9/XaxvMisxx+rNAVnwzeneUW/ULU/sOX7xo+68q7jA3eRaTJX9NEP9X
-+79uOzMh3nnchhdZLUNkt6Zmh+q8lkYZGoaLb9e3SQBb26O/KZru99MzrqP0nkzK
-XmnUG623kHdq2FlveasB+lXwiiFm5WVu/XzT3x7rfj8GkPsZC9MGAht4Q5mo
------END CERTIFICATE-----
-#endif
-static const unsigned char kDERCert49[] = {
- 0x30, 0x82, 0x06, 0x29, 0x30, 0x82, 0x05, 0x11, 0xa0, 0x03, 0x02, 0x01,
- 0x02, 0x02, 0x10, 0x64, 0x1b, 0xe8, 0x20, 0xce, 0x02, 0x08, 0x13, 0xf3,
- 0x2d, 0x4d, 0x2d, 0x95, 0xd6, 0x7e, 0x67, 0x30, 0x0d, 0x06, 0x09, 0x2a,
- 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x81,
- 0xca, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
- 0x55, 0x53, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13,
- 0x0e, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49,
- 0x6e, 0x63, 0x2e, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x0b,
- 0x13, 0x16, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x54,
- 0x72, 0x75, 0x73, 0x74, 0x20, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b,
- 0x31, 0x3a, 0x30, 0x38, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x31, 0x28,
- 0x63, 0x29, 0x20, 0x32, 0x30, 0x30, 0x36, 0x20, 0x56, 0x65, 0x72, 0x69,
- 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x20, 0x2d,
- 0x20, 0x46, 0x6f, 0x72, 0x20, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69,
- 0x7a, 0x65, 0x64, 0x20, 0x75, 0x73, 0x65, 0x20, 0x6f, 0x6e, 0x6c, 0x79,
- 0x31, 0x45, 0x30, 0x43, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x3c, 0x56,
- 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x43, 0x6c, 0x61, 0x73,
- 0x73, 0x20, 0x33, 0x20, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x20, 0x50,
- 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69,
- 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74,
- 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x20, 0x2d, 0x20, 0x47, 0x35, 0x30,
- 0x1e, 0x17, 0x0d, 0x31, 0x30, 0x30, 0x32, 0x30, 0x38, 0x30, 0x30, 0x30,
- 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x30, 0x30, 0x32, 0x30, 0x37,
- 0x32, 0x33, 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x81, 0xbc, 0x31, 0x0b,
- 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31,
- 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0e, 0x56, 0x65,
- 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e,
- 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x16, 0x56,
- 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x54, 0x72, 0x75, 0x73,
- 0x74, 0x20, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x31, 0x3b, 0x30,
- 0x39, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x32, 0x54, 0x65, 0x72, 0x6d,
- 0x73, 0x20, 0x6f, 0x66, 0x20, 0x75, 0x73, 0x65, 0x20, 0x61, 0x74, 0x20,
- 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e,
- 0x76, 0x65, 0x72, 0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d,
- 0x2f, 0x72, 0x70, 0x61, 0x20, 0x28, 0x63, 0x29, 0x31, 0x30, 0x31, 0x36,
- 0x30, 0x34, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x2d, 0x56, 0x65, 0x72,
- 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x20,
- 0x33, 0x20, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x74, 0x69, 0x6f,
- 0x6e, 0x61, 0x6c, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x43,
- 0x41, 0x20, 0x2d, 0x20, 0x47, 0x33, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d,
- 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05,
- 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82,
- 0x01, 0x01, 0x00, 0x99, 0xd6, 0x9c, 0x62, 0xf0, 0x15, 0xf4, 0x81, 0x9a,
- 0x41, 0x08, 0x59, 0x8f, 0x13, 0x9d, 0x17, 0xc9, 0x9f, 0x51, 0xdc, 0xda,
- 0xb1, 0x52, 0xef, 0xff, 0xe3, 0x41, 0xdd, 0xe0, 0xdf, 0xc4, 0x28, 0xc6,
- 0xe3, 0xad, 0x79, 0x1f, 0x27, 0x10, 0x98, 0xb8, 0xbb, 0x20, 0x97, 0xc1,
- 0x28, 0x44, 0x41, 0x0f, 0xea, 0xa9, 0xa8, 0x52, 0xcf, 0x4d, 0x4e, 0x1b,
- 0x8b, 0xbb, 0xb5, 0xc4, 0x76, 0xd9, 0xcc, 0x56, 0x06, 0xee, 0xb3, 0x55,
- 0x20, 0x2a, 0xde, 0x15, 0x8d, 0x71, 0xcb, 0x54, 0xc8, 0x6f, 0x17, 0xcd,
- 0x89, 0x00, 0xe4, 0xdc, 0xff, 0xe1, 0xc0, 0x1f, 0x68, 0x71, 0xe9, 0xc7,
- 0x29, 0x2e, 0x7e, 0xbc, 0x3b, 0xfc, 0xe5, 0xbb, 0xab, 0x26, 0x54, 0x8b,
- 0x66, 0x90, 0xcd, 0xf6, 0x92, 0xb9, 0x31, 0x24, 0x80, 0xbc, 0x9e, 0x6c,
- 0xd5, 0xfc, 0x7e, 0xd2, 0xe1, 0x4b, 0x8c, 0xdc, 0x42, 0xfa, 0x44, 0x4b,
- 0x5f, 0xf8, 0x18, 0xb5, 0x2e, 0x30, 0xf4, 0x3d, 0x12, 0x98, 0xd3, 0x62,
- 0x05, 0x73, 0x54, 0xa6, 0x9c, 0xa2, 0x1d, 0xbe, 0x52, 0x83, 0x3a, 0x07,
- 0x46, 0xc4, 0x3b, 0x02, 0x56, 0x21, 0xbf, 0xf2, 0x51, 0x4f, 0xd0, 0xa6,
- 0x99, 0x39, 0xe9, 0xae, 0xa5, 0x3f, 0x89, 0x9b, 0x9c, 0x7d, 0xfe, 0x4d,
- 0x60, 0x07, 0x25, 0x20, 0xf7, 0xbb, 0xd7, 0x69, 0x83, 0x2b, 0x82, 0x93,
- 0x43, 0x37, 0xd9, 0x83, 0x41, 0x1b, 0x6b, 0x0b, 0xab, 0x4a, 0x66, 0x84,
- 0x4f, 0x4a, 0x8e, 0xde, 0x7e, 0x34, 0x99, 0x8e, 0x68, 0xd6, 0xca, 0x39,
- 0x06, 0x9b, 0x4c, 0xb3, 0x9a, 0x48, 0x4d, 0x13, 0x46, 0xb4, 0x58, 0x21,
- 0x04, 0xc4, 0xfb, 0xa0, 0x4d, 0xac, 0x2e, 0x4b, 0x62, 0x12, 0xe3, 0xfb,
- 0x4d, 0xf6, 0xc9, 0x51, 0x00, 0x01, 0x1f, 0xfc, 0x1e, 0x6a, 0x81, 0x2a,
- 0x38, 0xe0, 0xb9, 0x4f, 0xd6, 0x2d, 0x45, 0x02, 0x03, 0x01, 0x00, 0x01,
- 0xa3, 0x82, 0x02, 0x15, 0x30, 0x82, 0x02, 0x11, 0x30, 0x12, 0x06, 0x03,
- 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01,
- 0xff, 0x02, 0x01, 0x00, 0x30, 0x70, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04,
- 0x69, 0x30, 0x67, 0x30, 0x65, 0x06, 0x0b, 0x60, 0x86, 0x48, 0x01, 0x86,
- 0xf8, 0x45, 0x01, 0x07, 0x17, 0x03, 0x30, 0x56, 0x30, 0x28, 0x06, 0x08,
- 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x1c, 0x68, 0x74,
- 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x76, 0x65,
- 0x72, 0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63,
- 0x70, 0x73, 0x30, 0x2a, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
- 0x02, 0x02, 0x30, 0x1e, 0x1a, 0x1c, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a,
- 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x76, 0x65, 0x72, 0x69, 0x73, 0x69,
- 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x70, 0x61, 0x30, 0x0e,
- 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02,
- 0x01, 0x06, 0x30, 0x6d, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
- 0x01, 0x0c, 0x04, 0x61, 0x30, 0x5f, 0xa1, 0x5d, 0xa0, 0x5b, 0x30, 0x59,
- 0x30, 0x57, 0x30, 0x55, 0x16, 0x09, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2f,
- 0x67, 0x69, 0x66, 0x30, 0x21, 0x30, 0x1f, 0x30, 0x07, 0x06, 0x05, 0x2b,
- 0x0e, 0x03, 0x02, 0x1a, 0x04, 0x14, 0x8f, 0xe5, 0xd3, 0x1a, 0x86, 0xac,
- 0x8d, 0x8e, 0x6b, 0xc3, 0xcf, 0x80, 0x6a, 0xd4, 0x48, 0x18, 0x2c, 0x7b,
- 0x19, 0x2e, 0x30, 0x25, 0x16, 0x23, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f,
- 0x2f, 0x6c, 0x6f, 0x67, 0x6f, 0x2e, 0x76, 0x65, 0x72, 0x69, 0x73, 0x69,
- 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x76, 0x73, 0x6c, 0x6f, 0x67,
- 0x6f, 0x2e, 0x67, 0x69, 0x66, 0x30, 0x34, 0x06, 0x03, 0x55, 0x1d, 0x25,
- 0x04, 0x2d, 0x30, 0x2b, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
- 0x03, 0x01, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x02,
- 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42, 0x04, 0x01, 0x06,
- 0x0a, 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x45, 0x01, 0x08, 0x01, 0x30,
- 0x34, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04,
- 0x28, 0x30, 0x26, 0x30, 0x24, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05,
- 0x07, 0x30, 0x01, 0x86, 0x18, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f,
- 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x76, 0x65, 0x72, 0x69, 0x73, 0x69, 0x67,
- 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x34, 0x06, 0x03, 0x55, 0x1d, 0x1f,
- 0x04, 0x2d, 0x30, 0x2b, 0x30, 0x29, 0xa0, 0x27, 0xa0, 0x25, 0x86, 0x23,
- 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x76,
- 0x65, 0x72, 0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f,
- 0x70, 0x63, 0x61, 0x33, 0x2d, 0x67, 0x35, 0x2e, 0x63, 0x72, 0x6c, 0x30,
- 0x28, 0x06, 0x03, 0x55, 0x1d, 0x11, 0x04, 0x21, 0x30, 0x1f, 0xa4, 0x1d,
- 0x30, 0x1b, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
- 0x10, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x4d, 0x50, 0x4b,
- 0x49, 0x2d, 0x32, 0x2d, 0x37, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e,
- 0x04, 0x16, 0x04, 0x14, 0xd7, 0x9b, 0x7c, 0xd8, 0x22, 0xa0, 0x15, 0xf7,
- 0xdd, 0xad, 0x5f, 0xce, 0x29, 0x9b, 0x58, 0xc3, 0xbc, 0x46, 0x00, 0xb5,
- 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80,
- 0x14, 0x7f, 0xd3, 0x65, 0xa7, 0xc2, 0xdd, 0xec, 0xbb, 0xf0, 0x30, 0x09,
- 0xf3, 0x43, 0x39, 0xfa, 0x02, 0xaf, 0x33, 0x31, 0x33, 0x30, 0x0d, 0x06,
- 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00,
- 0x03, 0x82, 0x01, 0x01, 0x00, 0x71, 0xb5, 0x7d, 0x73, 0x52, 0x4a, 0xdd,
- 0xd7, 0x4d, 0x34, 0x2b, 0x2e, 0xaf, 0x94, 0x46, 0xa5, 0x49, 0x50, 0x02,
- 0x4f, 0xf8, 0x2f, 0x17, 0x70, 0xf2, 0x13, 0xdc, 0x1f, 0x21, 0x86, 0xaa,
- 0xc2, 0x4f, 0x7c, 0x37, 0x3c, 0xd4, 0x46, 0x78, 0xae, 0x5d, 0x78, 0x6f,
- 0xd1, 0xba, 0x5a, 0xbc, 0x10, 0xab, 0x58, 0x36, 0xc5, 0x8c, 0x62, 0x15,
- 0x45, 0x60, 0x17, 0x21, 0xe2, 0xd5, 0x42, 0xa8, 0x77, 0xa1, 0x55, 0xd8,
- 0x43, 0x04, 0x51, 0xf6, 0x6e, 0xba, 0x48, 0xe6, 0x5d, 0x4c, 0xb7, 0x44,
- 0xd3, 0x3e, 0xa4, 0xd5, 0xd6, 0x33, 0x9a, 0x9f, 0x0d, 0xe6, 0xd7, 0x4e,
- 0x96, 0x44, 0x95, 0x5a, 0x6c, 0xd6, 0xa3, 0x16, 0x53, 0x0e, 0x98, 0x43,
- 0xce, 0xa4, 0xb8, 0xc3, 0x66, 0x7a, 0x05, 0x5c, 0x62, 0x10, 0xe8, 0x1b,
- 0x12, 0xdb, 0x7d, 0x2e, 0x76, 0x50, 0xff, 0xdf, 0xd7, 0x6b, 0x1b, 0xcc,
- 0x8a, 0xcc, 0x71, 0xfa, 0xb3, 0x40, 0x56, 0x7c, 0x33, 0x7a, 0x77, 0x94,
- 0x5b, 0xf5, 0x0b, 0x53, 0xfb, 0x0e, 0x5f, 0xbc, 0x68, 0xfb, 0xaf, 0x2a,
- 0xee, 0x30, 0x37, 0x79, 0x16, 0x93, 0x25, 0x7f, 0x4d, 0x10, 0xff, 0x57,
- 0xfb, 0xbf, 0x6e, 0x3b, 0x33, 0x21, 0xde, 0x79, 0xdc, 0x86, 0x17, 0x59,
- 0x2d, 0x43, 0x64, 0xb7, 0xa6, 0x66, 0x87, 0xea, 0xbc, 0x96, 0x46, 0x19,
- 0x1a, 0x86, 0x8b, 0x6f, 0xd7, 0xb7, 0x49, 0x00, 0x5b, 0xdb, 0xa3, 0xbf,
- 0x29, 0x9a, 0xee, 0xf7, 0xd3, 0x33, 0xae, 0xa3, 0xf4, 0x9e, 0x4c, 0xca,
- 0x5e, 0x69, 0xd4, 0x1b, 0xad, 0xb7, 0x90, 0x77, 0x6a, 0xd8, 0x59, 0x6f,
- 0x79, 0xab, 0x01, 0xfa, 0x55, 0xf0, 0x8a, 0x21, 0x66, 0xe5, 0x65, 0x6e,
- 0xfd, 0x7c, 0xd3, 0xdf, 0x1e, 0xeb, 0x7e, 0x3f, 0x06, 0x90, 0xfb, 0x19,
- 0x0b, 0xd3, 0x06, 0x02, 0x1b, 0x78, 0x43, 0x99, 0xa8,
-};
-
-#if 0
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number: 26 (0x1a)
- Signature Algorithm: sha1WithRSAEncryption
- Issuer: C=IL, O=StartCom Ltd., OU=Secure Digital Certificate Signing, CN=StartCom Certification Authority
- Validity
- Not Before: Oct 24 20:57:09 2007 GMT
- Not After : Oct 24 20:57:09 2017 GMT
- Subject: C=IL, O=StartCom Ltd., OU=Secure Digital Certificate Signing, CN=StartCom Class 2 Primary Intermediate Server CA
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:e2:4f:39:2f:a1:8c:9a:85:ad:08:0e:08:3e:57:
- f2:88:01:21:1b:94:a9:6c:e2:b8:db:aa:19:18:46:
- 3a:52:a1:f5:0f:f4:6e:8c:ea:96:8c:96:87:79:13:
- 40:51:2f:22:f2:0c:8b:87:0f:65:df:71:74:34:43:
- 55:b1:35:09:9b:d9:bc:1f:fa:eb:42:d0:97:40:72:
- b7:43:96:3d:ba:96:9d:5d:50:02:1c:9b:91:8d:9c:
- c0:ac:d7:bb:2f:17:d7:cb:3e:82:9d:73:eb:07:42:
- 92:b2:cd:64:b3:74:55:1b:b4:4b:86:21:2c:f7:78:
- 87:32:e0:16:e4:da:bd:4c:95:ea:a4:0a:7e:b6:0a:
- 0d:2e:8a:cf:55:ab:c3:e5:dd:41:8a:4e:e6:6f:65:
- 6c:b2:40:cf:17:5d:b9:c3:6a:0b:27:11:84:77:61:
- f6:c2:7c:ed:c0:8d:78:14:18:99:81:99:75:63:b7:
- e8:53:d3:ba:61:e9:0e:fa:a2:30:f3:46:a2:b9:c9:
- 1f:6c:80:5a:40:ac:27:ed:48:47:33:b0:54:c6:46:
- 1a:f3:35:61:c1:02:29:90:54:7e:64:4d:c4:30:52:
- 02:82:d7:df:ce:21:6e:18:91:d7:b8:ab:8c:27:17:
- b5:f0:a3:01:2f:8e:d2:2e:87:3a:3d:b4:29:67:8a:
- c4:03
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Basic Constraints: critical
- CA:TRUE
- X509v3 Key Usage: critical
- Certificate Sign, CRL Sign
- X509v3 Subject Key Identifier:
- 11:DB:23:45:FD:54:CC:6A:71:6F:84:8A:03:D7:BE:F7:01:2F:26:86
- X509v3 Authority Key Identifier:
- keyid:4E:0B:EF:1A:A4:40:5B:A5:17:69:87:30:CA:34:68:43:D0:41:AE:F2
-
- Authority Information Access:
- OCSP - URI:http://ocsp.startssl.com/ca
- CA Issuers - URI:http://www.startssl.com/sfsca.crt
-
- X509v3 CRL Distribution Points:
-
- Full Name:
- URI:http://www.startssl.com/sfsca.crl
-
- Full Name:
- URI:http://crl.startssl.com/sfsca.crl
-
- X509v3 Certificate Policies:
- Policy: 1.3.6.1.4.1.23223.1.2.1
- CPS: http://www.startssl.com/policy.pdf
- CPS: http://www.startssl.com/intermediate.pdf
-
- Signature Algorithm: sha1WithRSAEncryption
- 9d:07:e1:ee:90:76:31:67:16:45:70:8c:cb:84:8b:4b:57:68:
- 44:a5:89:c1:f2:7e:cb:28:8b:f5:e7:70:77:d5:b6:f4:0b:21:
- 60:a5:a1:74:73:24:22:80:d6:d8:ba:8d:a2:62:5d:09:35:42:
- 29:fb:39:63:45:0b:a4:b0:38:1a:68:f4:95:13:cc:e0:43:94:
- ec:eb:39:1a:ec:57:29:d9:99:6d:f5:84:cd:8e:73:ae:c9:dc:
- 6a:fa:9e:9d:16:64:93:08:c7:1c:c2:89:54:9e:77:80:90:f6:
- b9:29:76:eb:13:67:48:59:f8:2e:3a:31:b8:c9:d3:88:e5:5f:
- 4e:d2:19:3d:43:8e:d7:92:ff:cf:38:b6:e1:5b:8a:53:1d:ce:
- ac:b4:76:2f:d8:f7:40:63:d5:ee:69:f3:45:7d:a0:62:c1:61:
- c3:75:ed:b2:7b:4d:ac:21:27:30:4e:59:46:6a:93:17:ca:c8:
- 39:2d:01:73:65:5b:e9:41:9b:11:17:9c:c8:c8:4a:ef:a1:76:
- 60:2d:ae:93:ff:0c:d5:33:13:9f:4f:13:ce:dd:86:f1:fc:f8:
- 35:54:15:a8:5b:e7:85:7e:fa:37:09:ff:8b:b8:31:49:9e:0d:
- 6e:de:b4:d2:12:2d:b8:ed:c8:c3:f1:b6:42:a0:4c:97:79:df:
- fe:c3:a3:9f:a1:f4:6d:2c:84:77:a4:a2:05:e1:17:ff:31:dd:
- 9a:f3:b8:7a:c3:52:c2:11:11:b7:50:31:8a:7f:cc:e7:5a:89:
- cc:f7:86:9a:61:92:4f:2f:94:b6:98:c7:78:e0:62:4b:43:7d:
- 3c:de:d6:9a:b4:10:a1:40:9c:4b:2a:dc:b8:d0:d4:9e:fd:f1:
- 84:78:1b:0e:57:8f:69:54:42:68:7b:ea:a0:ef:75:0f:07:a2:
- 8c:73:99:ab:55:f5:07:09:d2:af:38:03:6a:90:03:0c:2f:8f:
- e2:e8:43:c2:31:e9:6f:ad:87:e5:8d:bd:4e:2c:89:4b:51:e6:
- 9c:4c:54:76:c0:12:81:53:9b:ec:a0:fc:2c:9c:da:18:95:6e:
- 1e:38:26:42:27:78:60:08:df:7f:6d:32:e8:d8:c0:6f:1f:eb:
- 26:75:9f:93:fc:7b:1b:fe:35:90:dc:53:a3:07:a6:3f:83:55:
- 0a:2b:4e:62:82:25:ce:66:30:5d:2c:e0:f9:19:1b:75:b9:9d:
- 98:56:a6:83:27:7a:d1:8f:8d:59:93:fc:3f:73:d7:2e:b4:2c:
- 95:d8:8b:f7:c9:7e:c7:fc:9d:ac:72:04:1f:d2:cc:17:f4:ed:
- 34:60:9b:9e:4a:97:04:fe:dd:72:0e:57:54:51:06:70:4d:ef:
- aa:1c:a4:82:e0:33:c7:f4
------BEGIN CERTIFICATE-----
-MIIGNDCCBBygAwIBAgIBGjANBgkqhkiG9w0BAQUFADB9MQswCQYDVQQGEwJJTDEW
-MBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwg
-Q2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3RhcnRDb20gQ2VydGlmaWNh
-dGlvbiBBdXRob3JpdHkwHhcNMDcxMDI0MjA1NzA5WhcNMTcxMDI0MjA1NzA5WjCB
-jDELMAkGA1UEBhMCSUwxFjAUBgNVBAoTDVN0YXJ0Q29tIEx0ZC4xKzApBgNVBAsT
-IlNlY3VyZSBEaWdpdGFsIENlcnRpZmljYXRlIFNpZ25pbmcxODA2BgNVBAMTL1N0
-YXJ0Q29tIENsYXNzIDIgUHJpbWFyeSBJbnRlcm1lZGlhdGUgU2VydmVyIENBMIIB
-IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4k85L6GMmoWtCA4IPlfyiAEh
-G5SpbOK426oZGEY6UqH1D/RujOqWjJaHeRNAUS8i8gyLhw9l33F0NENVsTUJm9m8
-H/rrQtCXQHK3Q5Y9upadXVACHJuRjZzArNe7LxfXyz6CnXPrB0KSss1ks3RVG7RL
-hiEs93iHMuAW5Nq9TJXqpAp+tgoNLorPVavD5d1Bik7mb2VsskDPF125w2oLJxGE
-d2H2wnztwI14FBiZgZl1Y7foU9O6YekO+qIw80aiuckfbIBaQKwn7UhHM7BUxkYa
-8zVhwQIpkFR+ZE3EMFICgtffziFuGJHXuKuMJxe18KMBL47SLoc6PbQpZ4rEAwID
-AQABo4IBrTCCAakwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYD
-VR0OBBYEFBHbI0X9VMxqcW+EigPXvvcBLyaGMB8GA1UdIwQYMBaAFE4L7xqkQFul
-F2mHMMo0aEPQQa7yMGYGCCsGAQUFBwEBBFowWDAnBggrBgEFBQcwAYYbaHR0cDov
-L29jc3Auc3RhcnRzc2wuY29tL2NhMC0GCCsGAQUFBzAChiFodHRwOi8vd3d3LnN0
-YXJ0c3NsLmNvbS9zZnNjYS5jcnQwWwYDVR0fBFQwUjAnoCWgI4YhaHR0cDovL3d3
-dy5zdGFydHNzbC5jb20vc2ZzY2EuY3JsMCegJaAjhiFodHRwOi8vY3JsLnN0YXJ0
-c3NsLmNvbS9zZnNjYS5jcmwwgYAGA1UdIAR5MHcwdQYLKwYBBAGBtTcBAgEwZjAu
-BggrBgEFBQcCARYiaHR0cDovL3d3dy5zdGFydHNzbC5jb20vcG9saWN5LnBkZjA0
-BggrBgEFBQcCARYoaHR0cDovL3d3dy5zdGFydHNzbC5jb20vaW50ZXJtZWRpYXRl
-LnBkZjANBgkqhkiG9w0BAQUFAAOCAgEAnQfh7pB2MWcWRXCMy4SLS1doRKWJwfJ+
-yyiL9edwd9W29AshYKWhdHMkIoDW2LqNomJdCTVCKfs5Y0ULpLA4Gmj0lRPM4EOU
-7Os5GuxXKdmZbfWEzY5zrsncavqenRZkkwjHHMKJVJ53gJD2uSl26xNnSFn4Ljox
-uMnTiOVfTtIZPUOO15L/zzi24VuKUx3OrLR2L9j3QGPV7mnzRX2gYsFhw3XtsntN
-rCEnME5ZRmqTF8rIOS0Bc2Vb6UGbERecyMhK76F2YC2uk/8M1TMTn08Tzt2G8fz4
-NVQVqFvnhX76Nwn/i7gxSZ4Nbt600hItuO3Iw/G2QqBMl3nf/sOjn6H0bSyEd6Si
-BeEX/zHdmvO4esNSwhERt1Axin/M51qJzPeGmmGSTy+UtpjHeOBiS0N9PN7WmrQQ
-oUCcSyrcuNDUnv3xhHgbDlePaVRCaHvqoO91DweijHOZq1X1BwnSrzgDapADDC+P
-4uhDwjHpb62H5Y29TiyJS1HmnExUdsASgVOb7KD8LJzaGJVuHjgmQid4YAjff20y
-6NjAbx/rJnWfk/x7G/41kNxTowemP4NVCitOYoIlzmYwXSzg+RkbdbmdmFamgyd6
-0Y+NWZP8P3PXLrQsldiL98l+x/ydrHIEH9LMF/TtNGCbnkqXBP7dcg5XVFEGcE3v
-qhykguAzx/Q=
------END CERTIFICATE-----
-#endif
-static const unsigned char kDERCert50[] = {
- 0x30, 0x82, 0x06, 0x34, 0x30, 0x82, 0x04, 0x1c, 0xa0, 0x03, 0x02, 0x01,
- 0x02, 0x02, 0x01, 0x1a, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
- 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x7d, 0x31, 0x0b, 0x30,
- 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x49, 0x4c, 0x31, 0x16,
- 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0d, 0x53, 0x74, 0x61,
- 0x72, 0x74, 0x43, 0x6f, 0x6d, 0x20, 0x4c, 0x74, 0x64, 0x2e, 0x31, 0x2b,
- 0x30, 0x29, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x22, 0x53, 0x65, 0x63,
- 0x75, 0x72, 0x65, 0x20, 0x44, 0x69, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x20,
- 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20,
- 0x53, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x31, 0x29, 0x30, 0x27, 0x06,
- 0x03, 0x55, 0x04, 0x03, 0x13, 0x20, 0x53, 0x74, 0x61, 0x72, 0x74, 0x43,
- 0x6f, 0x6d, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61,
- 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69,
- 0x74, 0x79, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x37, 0x31, 0x30, 0x32, 0x34,
- 0x32, 0x30, 0x35, 0x37, 0x30, 0x39, 0x5a, 0x17, 0x0d, 0x31, 0x37, 0x31,
- 0x30, 0x32, 0x34, 0x32, 0x30, 0x35, 0x37, 0x30, 0x39, 0x5a, 0x30, 0x81,
- 0x8c, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
- 0x49, 0x4c, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13,
- 0x0d, 0x53, 0x74, 0x61, 0x72, 0x74, 0x43, 0x6f, 0x6d, 0x20, 0x4c, 0x74,
- 0x64, 0x2e, 0x31, 0x2b, 0x30, 0x29, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13,
- 0x22, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x44, 0x69, 0x67, 0x69,
- 0x74, 0x61, 0x6c, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63,
- 0x61, 0x74, 0x65, 0x20, 0x53, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x31,
- 0x38, 0x30, 0x36, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x2f, 0x53, 0x74,
- 0x61, 0x72, 0x74, 0x43, 0x6f, 0x6d, 0x20, 0x43, 0x6c, 0x61, 0x73, 0x73,
- 0x20, 0x32, 0x20, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x20, 0x49,
- 0x6e, 0x74, 0x65, 0x72, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x20,
- 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x43, 0x41, 0x30, 0x82, 0x01,
- 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
- 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01,
- 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xe2, 0x4f, 0x39, 0x2f, 0xa1, 0x8c,
- 0x9a, 0x85, 0xad, 0x08, 0x0e, 0x08, 0x3e, 0x57, 0xf2, 0x88, 0x01, 0x21,
- 0x1b, 0x94, 0xa9, 0x6c, 0xe2, 0xb8, 0xdb, 0xaa, 0x19, 0x18, 0x46, 0x3a,
- 0x52, 0xa1, 0xf5, 0x0f, 0xf4, 0x6e, 0x8c, 0xea, 0x96, 0x8c, 0x96, 0x87,
- 0x79, 0x13, 0x40, 0x51, 0x2f, 0x22, 0xf2, 0x0c, 0x8b, 0x87, 0x0f, 0x65,
- 0xdf, 0x71, 0x74, 0x34, 0x43, 0x55, 0xb1, 0x35, 0x09, 0x9b, 0xd9, 0xbc,
- 0x1f, 0xfa, 0xeb, 0x42, 0xd0, 0x97, 0x40, 0x72, 0xb7, 0x43, 0x96, 0x3d,
- 0xba, 0x96, 0x9d, 0x5d, 0x50, 0x02, 0x1c, 0x9b, 0x91, 0x8d, 0x9c, 0xc0,
- 0xac, 0xd7, 0xbb, 0x2f, 0x17, 0xd7, 0xcb, 0x3e, 0x82, 0x9d, 0x73, 0xeb,
- 0x07, 0x42, 0x92, 0xb2, 0xcd, 0x64, 0xb3, 0x74, 0x55, 0x1b, 0xb4, 0x4b,
- 0x86, 0x21, 0x2c, 0xf7, 0x78, 0x87, 0x32, 0xe0, 0x16, 0xe4, 0xda, 0xbd,
- 0x4c, 0x95, 0xea, 0xa4, 0x0a, 0x7e, 0xb6, 0x0a, 0x0d, 0x2e, 0x8a, 0xcf,
- 0x55, 0xab, 0xc3, 0xe5, 0xdd, 0x41, 0x8a, 0x4e, 0xe6, 0x6f, 0x65, 0x6c,
- 0xb2, 0x40, 0xcf, 0x17, 0x5d, 0xb9, 0xc3, 0x6a, 0x0b, 0x27, 0x11, 0x84,
- 0x77, 0x61, 0xf6, 0xc2, 0x7c, 0xed, 0xc0, 0x8d, 0x78, 0x14, 0x18, 0x99,
- 0x81, 0x99, 0x75, 0x63, 0xb7, 0xe8, 0x53, 0xd3, 0xba, 0x61, 0xe9, 0x0e,
- 0xfa, 0xa2, 0x30, 0xf3, 0x46, 0xa2, 0xb9, 0xc9, 0x1f, 0x6c, 0x80, 0x5a,
- 0x40, 0xac, 0x27, 0xed, 0x48, 0x47, 0x33, 0xb0, 0x54, 0xc6, 0x46, 0x1a,
- 0xf3, 0x35, 0x61, 0xc1, 0x02, 0x29, 0x90, 0x54, 0x7e, 0x64, 0x4d, 0xc4,
- 0x30, 0x52, 0x02, 0x82, 0xd7, 0xdf, 0xce, 0x21, 0x6e, 0x18, 0x91, 0xd7,
- 0xb8, 0xab, 0x8c, 0x27, 0x17, 0xb5, 0xf0, 0xa3, 0x01, 0x2f, 0x8e, 0xd2,
- 0x2e, 0x87, 0x3a, 0x3d, 0xb4, 0x29, 0x67, 0x8a, 0xc4, 0x03, 0x02, 0x03,
- 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0xad, 0x30, 0x82, 0x01, 0xa9, 0x30,
- 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, 0x30,
- 0x03, 0x01, 0x01, 0xff, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01,
- 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x1d, 0x06, 0x03,
- 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x11, 0xdb, 0x23, 0x45, 0xfd,
- 0x54, 0xcc, 0x6a, 0x71, 0x6f, 0x84, 0x8a, 0x03, 0xd7, 0xbe, 0xf7, 0x01,
- 0x2f, 0x26, 0x86, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18,
- 0x30, 0x16, 0x80, 0x14, 0x4e, 0x0b, 0xef, 0x1a, 0xa4, 0x40, 0x5b, 0xa5,
- 0x17, 0x69, 0x87, 0x30, 0xca, 0x34, 0x68, 0x43, 0xd0, 0x41, 0xae, 0xf2,
- 0x30, 0x66, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01,
- 0x04, 0x5a, 0x30, 0x58, 0x30, 0x27, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05,
- 0x05, 0x07, 0x30, 0x01, 0x86, 0x1b, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f,
- 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x73, 0x74, 0x61, 0x72, 0x74, 0x73,
- 0x73, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x61, 0x30, 0x2d, 0x06,
- 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x21, 0x68,
- 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x73, 0x74,
- 0x61, 0x72, 0x74, 0x73, 0x73, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x73,
- 0x66, 0x73, 0x63, 0x61, 0x2e, 0x63, 0x72, 0x74, 0x30, 0x5b, 0x06, 0x03,
- 0x55, 0x1d, 0x1f, 0x04, 0x54, 0x30, 0x52, 0x30, 0x27, 0xa0, 0x25, 0xa0,
- 0x23, 0x86, 0x21, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77,
- 0x77, 0x2e, 0x73, 0x74, 0x61, 0x72, 0x74, 0x73, 0x73, 0x6c, 0x2e, 0x63,
- 0x6f, 0x6d, 0x2f, 0x73, 0x66, 0x73, 0x63, 0x61, 0x2e, 0x63, 0x72, 0x6c,
- 0x30, 0x27, 0xa0, 0x25, 0xa0, 0x23, 0x86, 0x21, 0x68, 0x74, 0x74, 0x70,
- 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x73, 0x74, 0x61, 0x72, 0x74,
- 0x73, 0x73, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x73, 0x66, 0x73, 0x63,
- 0x61, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x81, 0x80, 0x06, 0x03, 0x55, 0x1d,
- 0x20, 0x04, 0x79, 0x30, 0x77, 0x30, 0x75, 0x06, 0x0b, 0x2b, 0x06, 0x01,
- 0x04, 0x01, 0x81, 0xb5, 0x37, 0x01, 0x02, 0x01, 0x30, 0x66, 0x30, 0x2e,
- 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x22,
- 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x73,
- 0x74, 0x61, 0x72, 0x74, 0x73, 0x73, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x2f,
- 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x70, 0x64, 0x66, 0x30, 0x34,
- 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x28,
- 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x73,
- 0x74, 0x61, 0x72, 0x74, 0x73, 0x73, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x2f,
- 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65,
- 0x2e, 0x70, 0x64, 0x66, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
- 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x82, 0x02, 0x01, 0x00,
- 0x9d, 0x07, 0xe1, 0xee, 0x90, 0x76, 0x31, 0x67, 0x16, 0x45, 0x70, 0x8c,
- 0xcb, 0x84, 0x8b, 0x4b, 0x57, 0x68, 0x44, 0xa5, 0x89, 0xc1, 0xf2, 0x7e,
- 0xcb, 0x28, 0x8b, 0xf5, 0xe7, 0x70, 0x77, 0xd5, 0xb6, 0xf4, 0x0b, 0x21,
- 0x60, 0xa5, 0xa1, 0x74, 0x73, 0x24, 0x22, 0x80, 0xd6, 0xd8, 0xba, 0x8d,
- 0xa2, 0x62, 0x5d, 0x09, 0x35, 0x42, 0x29, 0xfb, 0x39, 0x63, 0x45, 0x0b,
- 0xa4, 0xb0, 0x38, 0x1a, 0x68, 0xf4, 0x95, 0x13, 0xcc, 0xe0, 0x43, 0x94,
- 0xec, 0xeb, 0x39, 0x1a, 0xec, 0x57, 0x29, 0xd9, 0x99, 0x6d, 0xf5, 0x84,
- 0xcd, 0x8e, 0x73, 0xae, 0xc9, 0xdc, 0x6a, 0xfa, 0x9e, 0x9d, 0x16, 0x64,
- 0x93, 0x08, 0xc7, 0x1c, 0xc2, 0x89, 0x54, 0x9e, 0x77, 0x80, 0x90, 0xf6,
- 0xb9, 0x29, 0x76, 0xeb, 0x13, 0x67, 0x48, 0x59, 0xf8, 0x2e, 0x3a, 0x31,
- 0xb8, 0xc9, 0xd3, 0x88, 0xe5, 0x5f, 0x4e, 0xd2, 0x19, 0x3d, 0x43, 0x8e,
- 0xd7, 0x92, 0xff, 0xcf, 0x38, 0xb6, 0xe1, 0x5b, 0x8a, 0x53, 0x1d, 0xce,
- 0xac, 0xb4, 0x76, 0x2f, 0xd8, 0xf7, 0x40, 0x63, 0xd5, 0xee, 0x69, 0xf3,
- 0x45, 0x7d, 0xa0, 0x62, 0xc1, 0x61, 0xc3, 0x75, 0xed, 0xb2, 0x7b, 0x4d,
- 0xac, 0x21, 0x27, 0x30, 0x4e, 0x59, 0x46, 0x6a, 0x93, 0x17, 0xca, 0xc8,
- 0x39, 0x2d, 0x01, 0x73, 0x65, 0x5b, 0xe9, 0x41, 0x9b, 0x11, 0x17, 0x9c,
- 0xc8, 0xc8, 0x4a, 0xef, 0xa1, 0x76, 0x60, 0x2d, 0xae, 0x93, 0xff, 0x0c,
- 0xd5, 0x33, 0x13, 0x9f, 0x4f, 0x13, 0xce, 0xdd, 0x86, 0xf1, 0xfc, 0xf8,
- 0x35, 0x54, 0x15, 0xa8, 0x5b, 0xe7, 0x85, 0x7e, 0xfa, 0x37, 0x09, 0xff,
- 0x8b, 0xb8, 0x31, 0x49, 0x9e, 0x0d, 0x6e, 0xde, 0xb4, 0xd2, 0x12, 0x2d,
- 0xb8, 0xed, 0xc8, 0xc3, 0xf1, 0xb6, 0x42, 0xa0, 0x4c, 0x97, 0x79, 0xdf,
- 0xfe, 0xc3, 0xa3, 0x9f, 0xa1, 0xf4, 0x6d, 0x2c, 0x84, 0x77, 0xa4, 0xa2,
- 0x05, 0xe1, 0x17, 0xff, 0x31, 0xdd, 0x9a, 0xf3, 0xb8, 0x7a, 0xc3, 0x52,
- 0xc2, 0x11, 0x11, 0xb7, 0x50, 0x31, 0x8a, 0x7f, 0xcc, 0xe7, 0x5a, 0x89,
- 0xcc, 0xf7, 0x86, 0x9a, 0x61, 0x92, 0x4f, 0x2f, 0x94, 0xb6, 0x98, 0xc7,
- 0x78, 0xe0, 0x62, 0x4b, 0x43, 0x7d, 0x3c, 0xde, 0xd6, 0x9a, 0xb4, 0x10,
- 0xa1, 0x40, 0x9c, 0x4b, 0x2a, 0xdc, 0xb8, 0xd0, 0xd4, 0x9e, 0xfd, 0xf1,
- 0x84, 0x78, 0x1b, 0x0e, 0x57, 0x8f, 0x69, 0x54, 0x42, 0x68, 0x7b, 0xea,
- 0xa0, 0xef, 0x75, 0x0f, 0x07, 0xa2, 0x8c, 0x73, 0x99, 0xab, 0x55, 0xf5,
- 0x07, 0x09, 0xd2, 0xaf, 0x38, 0x03, 0x6a, 0x90, 0x03, 0x0c, 0x2f, 0x8f,
- 0xe2, 0xe8, 0x43, 0xc2, 0x31, 0xe9, 0x6f, 0xad, 0x87, 0xe5, 0x8d, 0xbd,
- 0x4e, 0x2c, 0x89, 0x4b, 0x51, 0xe6, 0x9c, 0x4c, 0x54, 0x76, 0xc0, 0x12,
- 0x81, 0x53, 0x9b, 0xec, 0xa0, 0xfc, 0x2c, 0x9c, 0xda, 0x18, 0x95, 0x6e,
- 0x1e, 0x38, 0x26, 0x42, 0x27, 0x78, 0x60, 0x08, 0xdf, 0x7f, 0x6d, 0x32,
- 0xe8, 0xd8, 0xc0, 0x6f, 0x1f, 0xeb, 0x26, 0x75, 0x9f, 0x93, 0xfc, 0x7b,
- 0x1b, 0xfe, 0x35, 0x90, 0xdc, 0x53, 0xa3, 0x07, 0xa6, 0x3f, 0x83, 0x55,
- 0x0a, 0x2b, 0x4e, 0x62, 0x82, 0x25, 0xce, 0x66, 0x30, 0x5d, 0x2c, 0xe0,
- 0xf9, 0x19, 0x1b, 0x75, 0xb9, 0x9d, 0x98, 0x56, 0xa6, 0x83, 0x27, 0x7a,
- 0xd1, 0x8f, 0x8d, 0x59, 0x93, 0xfc, 0x3f, 0x73, 0xd7, 0x2e, 0xb4, 0x2c,
- 0x95, 0xd8, 0x8b, 0xf7, 0xc9, 0x7e, 0xc7, 0xfc, 0x9d, 0xac, 0x72, 0x04,
- 0x1f, 0xd2, 0xcc, 0x17, 0xf4, 0xed, 0x34, 0x60, 0x9b, 0x9e, 0x4a, 0x97,
- 0x04, 0xfe, 0xdd, 0x72, 0x0e, 0x57, 0x54, 0x51, 0x06, 0x70, 0x4d, 0xef,
- 0xaa, 0x1c, 0xa4, 0x82, 0xe0, 0x33, 0xc7, 0xf4,
-};
-
-#if 0
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number:
- 0a:5f:11:4d:03:5b:17:91:17:d2:ef:d4:03:8c:3f:3b
- Signature Algorithm: sha1WithRSAEncryption
- Issuer: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert High Assurance EV Root CA
- Validity
- Not Before: Apr 2 12:00:00 2008 GMT
- Not After : Apr 3 00:00:00 2022 GMT
- Subject: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert High Assurance CA-3
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:bf:61:0a:29:10:1f:5e:fe:34:37:51:08:f8:1e:
- fb:22:ed:61:be:0b:0d:70:4c:50:63:26:75:15:b9:
- 41:88:97:b6:f0:a0:15:bb:08:60:e0:42:e8:05:29:
- 10:87:36:8a:28:65:a8:ef:31:07:74:6d:36:97:2f:
- 28:46:66:04:c7:2a:79:26:7a:99:d5:8e:c3:6d:4f:
- a0:5e:ad:bc:3d:91:c2:59:7b:5e:36:6c:c0:53:cf:
- 00:08:32:3e:10:64:58:10:13:69:c7:0c:ee:9c:42:
- 51:00:f9:05:44:ee:24:ce:7a:1f:ed:8c:11:bd:12:
- a8:f3:15:f4:1c:7a:31:69:01:1b:a7:e6:5d:c0:9a:
- 6c:7e:09:9e:e7:52:44:4a:10:3a:23:e4:9b:b6:03:
- af:a8:9c:b4:5b:9f:d4:4b:ad:92:8c:ce:b5:11:2a:
- aa:37:18:8d:b4:c2:b8:d8:5c:06:8c:f8:ff:23:bd:
- 35:5e:d4:7c:3e:7e:83:0e:91:96:05:98:c3:b2:1f:
- e3:c8:65:eb:a9:7b:5d:a0:2c:cc:fc:3c:d9:6d:ed:
- cc:fa:4b:43:8c:c9:d4:b8:a5:61:1c:b2:40:b6:28:
- 12:df:b9:f8:5f:fe:d3:b2:c9:ef:3d:b4:1e:4b:7c:
- 1c:4c:99:36:9e:3d:eb:ec:a7:68:5e:1d:df:67:6e:
- 5e:fb
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Key Usage: critical
- Digital Signature, Certificate Sign, CRL Sign
- X509v3 Certificate Policies:
- Policy: 2.16.840.1.114412.1.3.0.2
- CPS: http://www.digicert.com/ssl-cps-repository.htm
- User Notice:
- Explicit Text:
-
- X509v3 Basic Constraints: critical
- CA:TRUE, pathlen:0
- Authority Information Access:
- OCSP - URI:http://ocsp.digicert.com
-
- X509v3 CRL Distribution Points:
-
- Full Name:
- URI:http://crl3.digicert.com/DigiCertHighAssuranceEVRootCA.crl
-
- Full Name:
- URI:http://crl4.digicert.com/DigiCertHighAssuranceEVRootCA.crl
-
- X509v3 Authority Key Identifier:
- keyid:B1:3E:C3:69:03:F8:BF:47:01:D4:98:26:1A:08:02:EF:63:64:2B:C3
-
- X509v3 Subject Key Identifier:
- 50:EA:73:89:DB:29:FB:10:8F:9E:E5:01:20:D4:DE:79:99:48:83:F7
- Signature Algorithm: sha1WithRSAEncryption
- 1e:e2:a5:48:9e:6c:db:53:38:0f:ef:a6:1a:2a:ac:e2:03:43:
- ed:9a:bc:3e:8e:75:1b:f0:fd:2e:22:59:ac:13:c0:61:e2:e7:
- fa:e9:99:cd:87:09:75:54:28:bf:46:60:dc:be:51:2c:92:f3:
- 1b:91:7c:31:08:70:e2:37:b9:c1:5b:a8:bd:a3:0b:00:fb:1a:
- 15:fd:03:ad:58:6a:c5:c7:24:99:48:47:46:31:1e:92:ef:b4:
- 5f:4e:34:c7:90:bf:31:c1:f8:b1:84:86:d0:9c:01:aa:df:8a:
- 56:06:ce:3a:e9:0e:ae:97:74:5d:d7:71:9a:42:74:5f:de:8d:
- 43:7c:de:e9:55:ed:69:00:cb:05:e0:7a:61:61:33:d1:19:4d:
- f9:08:ee:a0:39:c5:25:35:b7:2b:c4:0f:b2:dd:f1:a5:b7:0e:
- 24:c4:26:28:8d:79:77:f5:2f:f0:57:ba:7c:07:d4:e1:fc:cd:
- 5a:30:57:7e:86:10:47:dd:31:1f:d7:fc:a2:c2:bf:30:7c:5d:
- 24:aa:e8:f9:ae:5f:6a:74:c2:ce:6b:b3:46:d8:21:be:29:d4:
- 8e:5e:15:d6:42:4a:e7:32:6f:a4:b1:6b:51:83:58:be:3f:6d:
- c7:fb:da:03:21:cb:6a:16:19:4e:0a:f0:ad:84:ca:5d:94:b3:
- 5a:76:f7:61
------BEGIN CERTIFICATE-----
-MIIGWDCCBUCgAwIBAgIQCl8RTQNbF5EX0u/UA4w/OzANBgkqhkiG9w0BAQUFADBs
-MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
-d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j
-ZSBFViBSb290IENBMB4XDTA4MDQwMjEyMDAwMFoXDTIyMDQwMzAwMDAwMFowZjEL
-MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3
-LmRpZ2ljZXJ0LmNvbTElMCMGA1UEAxMcRGlnaUNlcnQgSGlnaCBBc3N1cmFuY2Ug
-Q0EtMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL9hCikQH17+NDdR
-CPge+yLtYb4LDXBMUGMmdRW5QYiXtvCgFbsIYOBC6AUpEIc2iihlqO8xB3RtNpcv
-KEZmBMcqeSZ6mdWOw21PoF6tvD2Rwll7XjZswFPPAAgyPhBkWBATaccM7pxCUQD5
-BUTuJM56H+2MEb0SqPMV9Bx6MWkBG6fmXcCabH4JnudSREoQOiPkm7YDr6ictFuf
-1EutkozOtREqqjcYjbTCuNhcBoz4/yO9NV7UfD5+gw6RlgWYw7If48hl66l7XaAs
-zPw82W3tzPpLQ4zJ1LilYRyyQLYoEt+5+F/+07LJ7z20Hkt8HEyZNp496+ynaF4d
-32duXvsCAwEAAaOCAvowggL2MA4GA1UdDwEB/wQEAwIBhjCCAcYGA1UdIASCAb0w
-ggG5MIIBtQYLYIZIAYb9bAEDAAIwggGkMDoGCCsGAQUFBwIBFi5odHRwOi8vd3d3
-LmRpZ2ljZXJ0LmNvbS9zc2wtY3BzLXJlcG9zaXRvcnkuaHRtMIIBZAYIKwYBBQUH
-AgIwggFWHoIBUgBBAG4AeQAgAHUAcwBlACAAbwBmACAAdABoAGkAcwAgAEMAZQBy
-AHQAaQBmAGkAYwBhAHQAZQAgAGMAbwBuAHMAdABpAHQAdQB0AGUAcwAgAGEAYwBj
-AGUAcAB0AGEAbgBjAGUAIABvAGYAIAB0AGgAZQAgAEQAaQBnAGkAQwBlAHIAdAAg
-AEMAUAAvAEMAUABTACAAYQBuAGQAIAB0AGgAZQAgAFIAZQBsAHkAaQBuAGcAIABQ
-AGEAcgB0AHkAIABBAGcAcgBlAGUAbQBlAG4AdAAgAHcAaABpAGMAaAAgAGwAaQBt
-AGkAdAAgAGwAaQBhAGIAaQBsAGkAdAB5ACAAYQBuAGQAIABhAHIAZQAgAGkAbgBj
-AG8AcgBwAG8AcgBhAHQAZQBkACAAaABlAHIAZQBpAG4AIABiAHkAIAByAGUAZgBl
-AHIAZQBuAGMAZQAuMBIGA1UdEwEB/wQIMAYBAf8CAQAwNAYIKwYBBQUHAQEEKDAm
-MCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20wgY8GA1UdHwSB
-hzCBhDBAoD6gPIY6aHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0SGln
-aEFzc3VyYW5jZUVWUm9vdENBLmNybDBAoD6gPIY6aHR0cDovL2NybDQuZGlnaWNl
-cnQuY29tL0RpZ2lDZXJ0SGlnaEFzc3VyYW5jZUVWUm9vdENBLmNybDAfBgNVHSME
-GDAWgBSxPsNpA/i/RwHUmCYaCALvY2QrwzAdBgNVHQ4EFgQUUOpzidsp+xCPnuUB
-INTeeZlIg/cwDQYJKoZIhvcNAQEFBQADggEBAB7ipUiebNtTOA/vphoqrOIDQ+2a
-vD6OdRvw/S4iWawTwGHi5/rpmc2HCXVUKL9GYNy+USyS8xuRfDEIcOI3ucFbqL2j
-CwD7GhX9A61YasXHJJlIR0YxHpLvtF9ONMeQvzHB+LGEhtCcAarfilYGzjrpDq6X
-dF3XcZpCdF/ejUN83ulV7WkAywXgemFhM9EZTfkI7qA5xSU1tyvED7Ld8aW3DiTE
-JiiNeXf1L/BXunwH1OH8zVowV36GEEfdMR/X/KLCvzB8XSSq6PmuX2p0ws5rs0bY
-Ib4p1I5eFdZCSucyb6Sxa1GDWL4/bcf72gMhy2oWGU4K8K2Eyl2Us1p292E=
------END CERTIFICATE-----
-#endif
-static const unsigned char kDERCert51[] = {
- 0x30, 0x82, 0x06, 0x58, 0x30, 0x82, 0x05, 0x40, 0xa0, 0x03, 0x02, 0x01,
- 0x02, 0x02, 0x10, 0x0a, 0x5f, 0x11, 0x4d, 0x03, 0x5b, 0x17, 0x91, 0x17,
- 0xd2, 0xef, 0xd4, 0x03, 0x8c, 0x3f, 0x3b, 0x30, 0x0d, 0x06, 0x09, 0x2a,
- 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x6c,
- 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55,
- 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0c,
- 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, 0x6e, 0x63,
- 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x10, 0x77,
- 0x77, 0x77, 0x2e, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, 0x74, 0x2e,
- 0x63, 0x6f, 0x6d, 0x31, 0x2b, 0x30, 0x29, 0x06, 0x03, 0x55, 0x04, 0x03,
- 0x13, 0x22, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x48,
- 0x69, 0x67, 0x68, 0x20, 0x41, 0x73, 0x73, 0x75, 0x72, 0x61, 0x6e, 0x63,
- 0x65, 0x20, 0x45, 0x56, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41,
- 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x38, 0x30, 0x34, 0x30, 0x32, 0x31, 0x32,
- 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x32, 0x30, 0x34, 0x30,
- 0x33, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x66, 0x31, 0x0b,
- 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31,
- 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0c, 0x44, 0x69,
- 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, 0x6e, 0x63, 0x31, 0x19,
- 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x10, 0x77, 0x77, 0x77,
- 0x2e, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, 0x74, 0x2e, 0x63, 0x6f,
- 0x6d, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x1c,
- 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x48, 0x69, 0x67,
- 0x68, 0x20, 0x41, 0x73, 0x73, 0x75, 0x72, 0x61, 0x6e, 0x63, 0x65, 0x20,
- 0x43, 0x41, 0x2d, 0x33, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09,
- 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03,
- 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01,
- 0x00, 0xbf, 0x61, 0x0a, 0x29, 0x10, 0x1f, 0x5e, 0xfe, 0x34, 0x37, 0x51,
- 0x08, 0xf8, 0x1e, 0xfb, 0x22, 0xed, 0x61, 0xbe, 0x0b, 0x0d, 0x70, 0x4c,
- 0x50, 0x63, 0x26, 0x75, 0x15, 0xb9, 0x41, 0x88, 0x97, 0xb6, 0xf0, 0xa0,
- 0x15, 0xbb, 0x08, 0x60, 0xe0, 0x42, 0xe8, 0x05, 0x29, 0x10, 0x87, 0x36,
- 0x8a, 0x28, 0x65, 0xa8, 0xef, 0x31, 0x07, 0x74, 0x6d, 0x36, 0x97, 0x2f,
- 0x28, 0x46, 0x66, 0x04, 0xc7, 0x2a, 0x79, 0x26, 0x7a, 0x99, 0xd5, 0x8e,
- 0xc3, 0x6d, 0x4f, 0xa0, 0x5e, 0xad, 0xbc, 0x3d, 0x91, 0xc2, 0x59, 0x7b,
- 0x5e, 0x36, 0x6c, 0xc0, 0x53, 0xcf, 0x00, 0x08, 0x32, 0x3e, 0x10, 0x64,
- 0x58, 0x10, 0x13, 0x69, 0xc7, 0x0c, 0xee, 0x9c, 0x42, 0x51, 0x00, 0xf9,
- 0x05, 0x44, 0xee, 0x24, 0xce, 0x7a, 0x1f, 0xed, 0x8c, 0x11, 0xbd, 0x12,
- 0xa8, 0xf3, 0x15, 0xf4, 0x1c, 0x7a, 0x31, 0x69, 0x01, 0x1b, 0xa7, 0xe6,
- 0x5d, 0xc0, 0x9a, 0x6c, 0x7e, 0x09, 0x9e, 0xe7, 0x52, 0x44, 0x4a, 0x10,
- 0x3a, 0x23, 0xe4, 0x9b, 0xb6, 0x03, 0xaf, 0xa8, 0x9c, 0xb4, 0x5b, 0x9f,
- 0xd4, 0x4b, 0xad, 0x92, 0x8c, 0xce, 0xb5, 0x11, 0x2a, 0xaa, 0x37, 0x18,
- 0x8d, 0xb4, 0xc2, 0xb8, 0xd8, 0x5c, 0x06, 0x8c, 0xf8, 0xff, 0x23, 0xbd,
- 0x35, 0x5e, 0xd4, 0x7c, 0x3e, 0x7e, 0x83, 0x0e, 0x91, 0x96, 0x05, 0x98,
- 0xc3, 0xb2, 0x1f, 0xe3, 0xc8, 0x65, 0xeb, 0xa9, 0x7b, 0x5d, 0xa0, 0x2c,
- 0xcc, 0xfc, 0x3c, 0xd9, 0x6d, 0xed, 0xcc, 0xfa, 0x4b, 0x43, 0x8c, 0xc9,
- 0xd4, 0xb8, 0xa5, 0x61, 0x1c, 0xb2, 0x40, 0xb6, 0x28, 0x12, 0xdf, 0xb9,
- 0xf8, 0x5f, 0xfe, 0xd3, 0xb2, 0xc9, 0xef, 0x3d, 0xb4, 0x1e, 0x4b, 0x7c,
- 0x1c, 0x4c, 0x99, 0x36, 0x9e, 0x3d, 0xeb, 0xec, 0xa7, 0x68, 0x5e, 0x1d,
- 0xdf, 0x67, 0x6e, 0x5e, 0xfb, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82,
- 0x02, 0xfa, 0x30, 0x82, 0x02, 0xf6, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d,
- 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x86, 0x30, 0x82,
- 0x01, 0xc6, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x82, 0x01, 0xbd, 0x30,
- 0x82, 0x01, 0xb9, 0x30, 0x82, 0x01, 0xb5, 0x06, 0x0b, 0x60, 0x86, 0x48,
- 0x01, 0x86, 0xfd, 0x6c, 0x01, 0x03, 0x00, 0x02, 0x30, 0x82, 0x01, 0xa4,
- 0x30, 0x3a, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01,
- 0x16, 0x2e, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77,
- 0x2e, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, 0x74, 0x2e, 0x63, 0x6f,
- 0x6d, 0x2f, 0x73, 0x73, 0x6c, 0x2d, 0x63, 0x70, 0x73, 0x2d, 0x72, 0x65,
- 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x2e, 0x68, 0x74, 0x6d,
- 0x30, 0x82, 0x01, 0x64, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
- 0x02, 0x02, 0x30, 0x82, 0x01, 0x56, 0x1e, 0x82, 0x01, 0x52, 0x00, 0x41,
- 0x00, 0x6e, 0x00, 0x79, 0x00, 0x20, 0x00, 0x75, 0x00, 0x73, 0x00, 0x65,
- 0x00, 0x20, 0x00, 0x6f, 0x00, 0x66, 0x00, 0x20, 0x00, 0x74, 0x00, 0x68,
- 0x00, 0x69, 0x00, 0x73, 0x00, 0x20, 0x00, 0x43, 0x00, 0x65, 0x00, 0x72,
- 0x00, 0x74, 0x00, 0x69, 0x00, 0x66, 0x00, 0x69, 0x00, 0x63, 0x00, 0x61,
- 0x00, 0x74, 0x00, 0x65, 0x00, 0x20, 0x00, 0x63, 0x00, 0x6f, 0x00, 0x6e,
- 0x00, 0x73, 0x00, 0x74, 0x00, 0x69, 0x00, 0x74, 0x00, 0x75, 0x00, 0x74,
- 0x00, 0x65, 0x00, 0x73, 0x00, 0x20, 0x00, 0x61, 0x00, 0x63, 0x00, 0x63,
- 0x00, 0x65, 0x00, 0x70, 0x00, 0x74, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x63,
- 0x00, 0x65, 0x00, 0x20, 0x00, 0x6f, 0x00, 0x66, 0x00, 0x20, 0x00, 0x74,
- 0x00, 0x68, 0x00, 0x65, 0x00, 0x20, 0x00, 0x44, 0x00, 0x69, 0x00, 0x67,
- 0x00, 0x69, 0x00, 0x43, 0x00, 0x65, 0x00, 0x72, 0x00, 0x74, 0x00, 0x20,
- 0x00, 0x43, 0x00, 0x50, 0x00, 0x2f, 0x00, 0x43, 0x00, 0x50, 0x00, 0x53,
- 0x00, 0x20, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x64, 0x00, 0x20, 0x00, 0x74,
- 0x00, 0x68, 0x00, 0x65, 0x00, 0x20, 0x00, 0x52, 0x00, 0x65, 0x00, 0x6c,
- 0x00, 0x79, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x67, 0x00, 0x20, 0x00, 0x50,
- 0x00, 0x61, 0x00, 0x72, 0x00, 0x74, 0x00, 0x79, 0x00, 0x20, 0x00, 0x41,
- 0x00, 0x67, 0x00, 0x72, 0x00, 0x65, 0x00, 0x65, 0x00, 0x6d, 0x00, 0x65,
- 0x00, 0x6e, 0x00, 0x74, 0x00, 0x20, 0x00, 0x77, 0x00, 0x68, 0x00, 0x69,
- 0x00, 0x63, 0x00, 0x68, 0x00, 0x20, 0x00, 0x6c, 0x00, 0x69, 0x00, 0x6d,
- 0x00, 0x69, 0x00, 0x74, 0x00, 0x20, 0x00, 0x6c, 0x00, 0x69, 0x00, 0x61,
- 0x00, 0x62, 0x00, 0x69, 0x00, 0x6c, 0x00, 0x69, 0x00, 0x74, 0x00, 0x79,
- 0x00, 0x20, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x64, 0x00, 0x20, 0x00, 0x61,
- 0x00, 0x72, 0x00, 0x65, 0x00, 0x20, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x63,
- 0x00, 0x6f, 0x00, 0x72, 0x00, 0x70, 0x00, 0x6f, 0x00, 0x72, 0x00, 0x61,
- 0x00, 0x74, 0x00, 0x65, 0x00, 0x64, 0x00, 0x20, 0x00, 0x68, 0x00, 0x65,
- 0x00, 0x72, 0x00, 0x65, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x20, 0x00, 0x62,
- 0x00, 0x79, 0x00, 0x20, 0x00, 0x72, 0x00, 0x65, 0x00, 0x66, 0x00, 0x65,
- 0x00, 0x72, 0x00, 0x65, 0x00, 0x6e, 0x00, 0x63, 0x00, 0x65, 0x00, 0x2e,
- 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08,
- 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x00, 0x30, 0x34, 0x06, 0x08,
- 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x28, 0x30, 0x26,
- 0x30, 0x24, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01,
- 0x86, 0x18, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73,
- 0x70, 0x2e, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, 0x74, 0x2e, 0x63,
- 0x6f, 0x6d, 0x30, 0x81, 0x8f, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x81,
- 0x87, 0x30, 0x81, 0x84, 0x30, 0x40, 0xa0, 0x3e, 0xa0, 0x3c, 0x86, 0x3a,
- 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x33, 0x2e,
- 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, 0x74, 0x2e, 0x63, 0x6f, 0x6d,
- 0x2f, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x48, 0x69, 0x67,
- 0x68, 0x41, 0x73, 0x73, 0x75, 0x72, 0x61, 0x6e, 0x63, 0x65, 0x45, 0x56,
- 0x52, 0x6f, 0x6f, 0x74, 0x43, 0x41, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x40,
- 0xa0, 0x3e, 0xa0, 0x3c, 0x86, 0x3a, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f,
- 0x2f, 0x63, 0x72, 0x6c, 0x34, 0x2e, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65,
- 0x72, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x44, 0x69, 0x67, 0x69, 0x43,
- 0x65, 0x72, 0x74, 0x48, 0x69, 0x67, 0x68, 0x41, 0x73, 0x73, 0x75, 0x72,
- 0x61, 0x6e, 0x63, 0x65, 0x45, 0x56, 0x52, 0x6f, 0x6f, 0x74, 0x43, 0x41,
- 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04,
- 0x18, 0x30, 0x16, 0x80, 0x14, 0xb1, 0x3e, 0xc3, 0x69, 0x03, 0xf8, 0xbf,
- 0x47, 0x01, 0xd4, 0x98, 0x26, 0x1a, 0x08, 0x02, 0xef, 0x63, 0x64, 0x2b,
- 0xc3, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14,
- 0x50, 0xea, 0x73, 0x89, 0xdb, 0x29, 0xfb, 0x10, 0x8f, 0x9e, 0xe5, 0x01,
- 0x20, 0xd4, 0xde, 0x79, 0x99, 0x48, 0x83, 0xf7, 0x30, 0x0d, 0x06, 0x09,
- 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03,
- 0x82, 0x01, 0x01, 0x00, 0x1e, 0xe2, 0xa5, 0x48, 0x9e, 0x6c, 0xdb, 0x53,
- 0x38, 0x0f, 0xef, 0xa6, 0x1a, 0x2a, 0xac, 0xe2, 0x03, 0x43, 0xed, 0x9a,
- 0xbc, 0x3e, 0x8e, 0x75, 0x1b, 0xf0, 0xfd, 0x2e, 0x22, 0x59, 0xac, 0x13,
- 0xc0, 0x61, 0xe2, 0xe7, 0xfa, 0xe9, 0x99, 0xcd, 0x87, 0x09, 0x75, 0x54,
- 0x28, 0xbf, 0x46, 0x60, 0xdc, 0xbe, 0x51, 0x2c, 0x92, 0xf3, 0x1b, 0x91,
- 0x7c, 0x31, 0x08, 0x70, 0xe2, 0x37, 0xb9, 0xc1, 0x5b, 0xa8, 0xbd, 0xa3,
- 0x0b, 0x00, 0xfb, 0x1a, 0x15, 0xfd, 0x03, 0xad, 0x58, 0x6a, 0xc5, 0xc7,
- 0x24, 0x99, 0x48, 0x47, 0x46, 0x31, 0x1e, 0x92, 0xef, 0xb4, 0x5f, 0x4e,
- 0x34, 0xc7, 0x90, 0xbf, 0x31, 0xc1, 0xf8, 0xb1, 0x84, 0x86, 0xd0, 0x9c,
- 0x01, 0xaa, 0xdf, 0x8a, 0x56, 0x06, 0xce, 0x3a, 0xe9, 0x0e, 0xae, 0x97,
- 0x74, 0x5d, 0xd7, 0x71, 0x9a, 0x42, 0x74, 0x5f, 0xde, 0x8d, 0x43, 0x7c,
- 0xde, 0xe9, 0x55, 0xed, 0x69, 0x00, 0xcb, 0x05, 0xe0, 0x7a, 0x61, 0x61,
- 0x33, 0xd1, 0x19, 0x4d, 0xf9, 0x08, 0xee, 0xa0, 0x39, 0xc5, 0x25, 0x35,
- 0xb7, 0x2b, 0xc4, 0x0f, 0xb2, 0xdd, 0xf1, 0xa5, 0xb7, 0x0e, 0x24, 0xc4,
- 0x26, 0x28, 0x8d, 0x79, 0x77, 0xf5, 0x2f, 0xf0, 0x57, 0xba, 0x7c, 0x07,
- 0xd4, 0xe1, 0xfc, 0xcd, 0x5a, 0x30, 0x57, 0x7e, 0x86, 0x10, 0x47, 0xdd,
- 0x31, 0x1f, 0xd7, 0xfc, 0xa2, 0xc2, 0xbf, 0x30, 0x7c, 0x5d, 0x24, 0xaa,
- 0xe8, 0xf9, 0xae, 0x5f, 0x6a, 0x74, 0xc2, 0xce, 0x6b, 0xb3, 0x46, 0xd8,
- 0x21, 0xbe, 0x29, 0xd4, 0x8e, 0x5e, 0x15, 0xd6, 0x42, 0x4a, 0xe7, 0x32,
- 0x6f, 0xa4, 0xb1, 0x6b, 0x51, 0x83, 0x58, 0xbe, 0x3f, 0x6d, 0xc7, 0xfb,
- 0xda, 0x03, 0x21, 0xcb, 0x6a, 0x16, 0x19, 0x4e, 0x0a, 0xf0, 0xad, 0x84,
- 0xca, 0x5d, 0x94, 0xb3, 0x5a, 0x76, 0xf7, 0x61,
-};
-
-#if 0
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number: 7250751724796726 (0x19c28530e93b36)
- Signature Algorithm: sha256WithRSAEncryption
- Issuer: C=IL, O=StartCom Ltd., OU=Secure Digital Certificate Signing, CN=StartCom Certification Authority
- Validity
- Not Before: Sep 17 22:46:36 2006 GMT
- Not After : Dec 31 23:59:59 2019 GMT
- Subject: C=CN, O=WoSign CA Limited, CN=Certification Authority of WoSign
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (4096 bit)
- Modulus:
- 00:bd:ca:8d:ac:b8:91:15:56:97:7b:6b:5c:7a:c2:
- de:6b:d9:a1:b0:c3:10:23:fa:a7:a1:b2:cc:31:fa:
- 3e:d9:a6:29:6f:16:3d:e0:6b:f8:b8:40:5f:db:39:
- a8:00:7a:8b:a0:4d:54:7d:c2:22:78:fc:8e:09:b8:
- a8:85:d7:cc:95:97:4b:74:d8:9e:7e:f0:00:e4:0e:
- 89:ae:49:28:44:1a:10:99:32:0f:25:88:53:a4:0d:
- b3:0f:12:08:16:0b:03:71:27:1c:7f:e1:db:d2:fd:
- 67:68:c4:05:5d:0a:0e:5d:70:d7:d8:97:a0:bc:53:
- 41:9a:91:8d:f4:9e:36:66:7a:7e:56:c1:90:5f:e6:
- b1:68:20:36:a4:8c:24:2c:2c:47:0b:59:76:66:30:
- b5:be:de:ed:8f:f8:9d:d3:bb:01:30:e6:f2:f3:0e:
- e0:2c:92:80:f3:85:f9:28:8a:b4:54:2e:9a:ed:f7:
- 76:fc:15:68:16:eb:4a:6c:eb:2e:12:8f:d4:cf:fe:
- 0c:c7:5c:1d:0b:7e:05:32:be:5e:b0:09:2a:42:d5:
- c9:4e:90:b3:59:0d:bb:7a:7e:cd:d5:08:5a:b4:7f:
- d8:1c:69:11:f9:27:0f:7b:06:af:54:83:18:7b:e1:
- dd:54:7a:51:68:6e:77:fc:c6:bf:52:4a:66:46:a1:
- b2:67:1a:bb:a3:4f:77:a0:be:5d:ff:fc:56:0b:43:
- 72:77:90:ca:9e:f9:f2:39:f5:0d:a9:f4:ea:d7:e7:
- b3:10:2f:30:42:37:21:cc:30:70:c9:86:98:0f:cc:
- 58:4d:83:bb:7d:e5:1a:a5:37:8d:b6:ac:32:97:00:
- 3a:63:71:24:1e:9e:37:c4:ff:74:d4:37:c0:e2:fe:
- 88:46:60:11:dd:08:3f:50:36:ab:b8:7a:a4:95:62:
- 6a:6e:b0:ca:6a:21:5a:69:f3:f3:fb:1d:70:39:95:
- f3:a7:6e:a6:81:89:a1:88:c5:3b:71:ca:a3:52:ee:
- 83:bb:fd:a0:77:f4:e4:6f:e7:42:db:6d:4a:99:8a:
- 34:48:bc:17:dc:e4:80:08:22:b6:f2:31:c0:3f:04:
- 3e:eb:9f:20:79:d6:b8:06:64:64:02:31:d7:a9:cd:
- 52:fb:84:45:69:09:00:2a:dc:55:8b:c4:06:46:4b:
- c0:4a:1d:09:5b:39:28:fd:a9:ab:ce:00:f9:2e:48:
- 4b:26:e6:30:4c:a5:58:ca:b4:44:82:4f:e7:91:1e:
- 33:c3:b0:93:ff:11:fc:81:d2:ca:1f:71:29:dd:76:
- 4f:92:25:af:1d:81:b7:0f:2f:8c:c3:06:cc:2f:27:
- a3:4a:e4:0e:99:ba:7c:1e:45:1f:7f:aa:19:45:96:
- fd:fc:3d
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Basic Constraints: critical
- CA:TRUE, pathlen:2
- X509v3 Key Usage: critical
- Certificate Sign, CRL Sign
- X509v3 Subject Key Identifier:
- E1:66:CF:0E:D1:F1:B3:4B:B7:06:20:14:FE:87:12:D5:F6:FE:FB:3E
- X509v3 Authority Key Identifier:
- keyid:4E:0B:EF:1A:A4:40:5B:A5:17:69:87:30:CA:34:68:43:D0:41:AE:F2
-
- Authority Information Access:
- OCSP - URI:http://ocsp.startssl.com/ca
- CA Issuers - URI:http://aia.startssl.com/certs/ca.crt
-
- X509v3 CRL Distribution Points:
-
- Full Name:
- URI:http://crl.startssl.com/sfsca.crl
-
- Signature Algorithm: sha256WithRSAEncryption
- b6:6d:f8:70:fb:e2:0d:4c:98:b3:07:49:15:f5:04:c4:6c:ca:
- ca:f5:68:a0:08:fe:12:6d:9c:04:06:c9:ad:9a:91:52:3e:78:
- c4:5c:ee:9f:54:1d:ee:e3:f1:5e:30:c9:49:e1:39:e0:a6:9d:
- 36:6c:57:fa:e6:34:4f:55:e8:87:a8:2c:dd:05:f1:58:12:91:
- e8:ca:ce:28:78:8f:df:07:85:01:a5:dc:45:96:05:d4:80:b2:
- 2b:05:9a:cb:9a:a5:8b:e0:3a:67:e6:73:47:be:4a:fd:27:b1:
- 88:ef:e6:ca:cf:8d:0e:26:9f:fa:5f:57:78:ad:6d:fe:ae:9b:
- 35:08:b1:c3:ba:c1:00:4a:4b:7d:14:bd:f7:f1:d3:55:18:ac:
- d0:33:70:88:6d:c4:09:71:14:a6:2b:4f:88:81:e7:0b:00:37:
- a9:15:7d:7e:d7:01:96:3f:2f:af:7b:62:ae:0a:4a:bf:4b:39:
- 2e:35:10:8b:fe:04:39:e4:3c:3a:0c:09:56:40:3a:b5:f4:c2:
- 68:0c:b5:f9:52:cd:ee:9d:f8:98:fc:78:e7:58:47:8f:1c:73:
- 58:69:33:ab:ff:dd:df:8e:24:01:77:98:19:3a:b0:66:79:bc:
- e1:08:a3:0e:4f:c1:04:b3:f3:01:c8:eb:d3:59:1c:35:d2:93:
- 1e:70:65:82:7f:db:cf:fb:c8:99:12:60:c3:44:6f:3a:80:4b:
- d7:be:21:aa:14:7a:64:cb:dd:37:43:45:5b:32:2e:45:f0:d9:
- 59:1f:6b:18:f0:7c:e9:55:36:19:61:5f:b5:7d:f1:8d:bd:88:
- e4:75:4b:98:dd:27:b0:e4:84:44:2a:61:84:57:05:82:11:1f:
- aa:35:58:f3:20:0e:af:59:ef:fa:55:72:72:0d:26:d0:9b:53:
- 49:ac:ce:37:2e:65:61:ff:f6:ec:1b:ea:f6:f1:a6:d3:d1:b5:
- 7b:be:35:f4:22:c1:bc:8d:01:bd:68:5e:83:0d:2f:ec:d6:da:
- 63:0c:27:d1:54:3e:e4:a8:d3:ce:4b:32:b8:91:94:ff:fb:5b:
- 49:2d:75:18:a8:ba:71:9a:3b:ae:d9:c0:a9:4f:87:91:ed:8b:
- 7b:6b:20:98:89:39:83:4f:80:c4:69:cc:17:c9:c8:4e:be:e4:
- a9:a5:81:76:70:06:04:32:cd:83:65:f4:bc:7d:3e:13:bc:d2:
- e8:6f:63:aa:b5:3b:da:8d:86:32:82:78:9d:d9:cc:ff:bf:57:
- 64:74:ed:28:3d:44:62:15:61:4b:f7:94:b0:0d:2a:67:1c:f0:
- cb:9b:a5:92:bf:f8:41:5a:c1:3d:60:ed:9f:bb:b8:6d:9b:ce:
- a9:6a:16:3f:7e:ea:06:f1
------BEGIN CERTIFICATE-----
-MIIGXDCCBESgAwIBAgIHGcKFMOk7NjANBgkqhkiG9w0BAQsFADB9MQswCQYDVQQG
-EwJJTDEWMBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERp
-Z2l0YWwgQ2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3RhcnRDb20gQ2Vy
-dGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDYwOTE3MjI0NjM2WhcNMTkxMjMxMjM1
-OTU5WjBVMQswCQYDVQQGEwJDTjEaMBgGA1UEChMRV29TaWduIENBIExpbWl0ZWQx
-KjAoBgNVBAMTIUNlcnRpZmljYXRpb24gQXV0aG9yaXR5IG9mIFdvU2lnbjCCAiIw
-DQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAL3Kjay4kRVWl3trXHrC3mvZobDD
-ECP6p6GyzDH6PtmmKW8WPeBr+LhAX9s5qAB6i6BNVH3CInj8jgm4qIXXzJWXS3TY
-nn7wAOQOia5JKEQaEJkyDyWIU6QNsw8SCBYLA3EnHH/h29L9Z2jEBV0KDl1w19iX
-oLxTQZqRjfSeNmZ6flbBkF/msWggNqSMJCwsRwtZdmYwtb7e7Y/4ndO7ATDm8vMO
-4CySgPOF+SiKtFQumu33dvwVaBbrSmzrLhKP1M/+DMdcHQt+BTK+XrAJKkLVyU6Q
-s1kNu3p+zdUIWrR/2BxpEfknD3sGr1SDGHvh3VR6UWhud/zGv1JKZkahsmcau6NP
-d6C+Xf/8VgtDcneQyp758jn1Dan06tfnsxAvMEI3IcwwcMmGmA/MWE2Du33lGqU3
-jbasMpcAOmNxJB6eN8T/dNQ3wOL+iEZgEd0IP1A2q7h6pJViam6wymohWmnz8/sd
-cDmV86dupoGJoYjFO3HKo1Lug7v9oHf05G/nQtttSpmKNEi8F9zkgAgitvIxwD8E
-PuufIHnWuAZkZAIx16nNUvuERWkJACrcVYvEBkZLwEodCVs5KP2pq84A+S5ISybm
-MEylWMq0RIJP55EeM8Owk/8R/IHSyh9xKd12T5Ilrx2Btw8vjMMGzC8no0rkDpm6
-fB5FH3+qGUWW/fw9AgMBAAGjggEHMIIBAzASBgNVHRMBAf8ECDAGAQH/AgECMA4G
-A1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQU4WbPDtHxs0u3BiAU/ocS1fb++z4wHwYD
-VR0jBBgwFoAUTgvvGqRAW6UXaYcwyjRoQ9BBrvIwaQYIKwYBBQUHAQEEXTBbMCcG
-CCsGAQUFBzABhhtodHRwOi8vb2NzcC5zdGFydHNzbC5jb20vY2EwMAYIKwYBBQUH
-MAKGJGh0dHA6Ly9haWEuc3RhcnRzc2wuY29tL2NlcnRzL2NhLmNydDAyBgNVHR8E
-KzApMCegJaAjhiFodHRwOi8vY3JsLnN0YXJ0c3NsLmNvbS9zZnNjYS5jcmwwDQYJ
-KoZIhvcNAQELBQADggIBALZt+HD74g1MmLMHSRX1BMRsysr1aKAI/hJtnAQGya2a
-kVI+eMRc7p9UHe7j8V4wyUnhOeCmnTZsV/rmNE9V6IeoLN0F8VgSkejKzih4j98H
-hQGl3EWWBdSAsisFmsuapYvgOmfmc0e+Sv0nsYjv5srPjQ4mn/pfV3itbf6umzUI
-scO6wQBKS30Uvffx01UYrNAzcIhtxAlxFKYrT4iB5wsAN6kVfX7XAZY/L697Yq4K
-Sr9LOS41EIv+BDnkPDoMCVZAOrX0wmgMtflSze6d+Jj8eOdYR48cc1hpM6v/3d+O
-JAF3mBk6sGZ5vOEIow5PwQSz8wHI69NZHDXSkx5wZYJ/28/7yJkSYMNEbzqAS9e+
-IaoUemTL3TdDRVsyLkXw2VkfaxjwfOlVNhlhX7V98Y29iOR1S5jdJ7DkhEQqYYRX
-BYIRH6o1WPMgDq9Z7/pVcnINJtCbU0mszjcuZWH/9uwb6vbxptPRtXu+NfQiwbyN
-Ab1oXoMNL+zW2mMMJ9FUPuSo085LMriRlP/7W0ktdRiounGaO67ZwKlPh5Hti3tr
-IJiJOYNPgMRpzBfJyE6+5KmlgXZwBgQyzYNl9Lx9PhO80uhvY6q1O9qNhjKCeJ3Z
-zP+/V2R07Sg9RGIVYUv3lLANKmcc8MubpZK/+EFawT1g7Z+7uG2bzqlqFj9+6gbx
------END CERTIFICATE-----
-#endif
-static const unsigned char kDERCert52[] = {
- 0x30, 0x82, 0x06, 0x5c, 0x30, 0x82, 0x04, 0x44, 0xa0, 0x03, 0x02, 0x01,
- 0x02, 0x02, 0x07, 0x19, 0xc2, 0x85, 0x30, 0xe9, 0x3b, 0x36, 0x30, 0x0d,
- 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05,
- 0x00, 0x30, 0x7d, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06,
- 0x13, 0x02, 0x49, 0x4c, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04,
- 0x0a, 0x13, 0x0d, 0x53, 0x74, 0x61, 0x72, 0x74, 0x43, 0x6f, 0x6d, 0x20,
- 0x4c, 0x74, 0x64, 0x2e, 0x31, 0x2b, 0x30, 0x29, 0x06, 0x03, 0x55, 0x04,
- 0x0b, 0x13, 0x22, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x44, 0x69,
- 0x67, 0x69, 0x74, 0x61, 0x6c, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66,
- 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x53, 0x69, 0x67, 0x6e, 0x69, 0x6e,
- 0x67, 0x31, 0x29, 0x30, 0x27, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x20,
- 0x53, 0x74, 0x61, 0x72, 0x74, 0x43, 0x6f, 0x6d, 0x20, 0x43, 0x65, 0x72,
- 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41,
- 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x30, 0x1e, 0x17, 0x0d,
- 0x30, 0x36, 0x30, 0x39, 0x31, 0x37, 0x32, 0x32, 0x34, 0x36, 0x33, 0x36,
- 0x5a, 0x17, 0x0d, 0x31, 0x39, 0x31, 0x32, 0x33, 0x31, 0x32, 0x33, 0x35,
- 0x39, 0x35, 0x39, 0x5a, 0x30, 0x55, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03,
- 0x55, 0x04, 0x06, 0x13, 0x02, 0x43, 0x4e, 0x31, 0x1a, 0x30, 0x18, 0x06,
- 0x03, 0x55, 0x04, 0x0a, 0x13, 0x11, 0x57, 0x6f, 0x53, 0x69, 0x67, 0x6e,
- 0x20, 0x43, 0x41, 0x20, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x65, 0x64, 0x31,
- 0x2a, 0x30, 0x28, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x21, 0x43, 0x65,
- 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20,
- 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x20, 0x6f, 0x66,
- 0x20, 0x57, 0x6f, 0x53, 0x69, 0x67, 0x6e, 0x30, 0x82, 0x02, 0x22, 0x30,
- 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01,
- 0x05, 0x00, 0x03, 0x82, 0x02, 0x0f, 0x00, 0x30, 0x82, 0x02, 0x0a, 0x02,
- 0x82, 0x02, 0x01, 0x00, 0xbd, 0xca, 0x8d, 0xac, 0xb8, 0x91, 0x15, 0x56,
- 0x97, 0x7b, 0x6b, 0x5c, 0x7a, 0xc2, 0xde, 0x6b, 0xd9, 0xa1, 0xb0, 0xc3,
- 0x10, 0x23, 0xfa, 0xa7, 0xa1, 0xb2, 0xcc, 0x31, 0xfa, 0x3e, 0xd9, 0xa6,
- 0x29, 0x6f, 0x16, 0x3d, 0xe0, 0x6b, 0xf8, 0xb8, 0x40, 0x5f, 0xdb, 0x39,
- 0xa8, 0x00, 0x7a, 0x8b, 0xa0, 0x4d, 0x54, 0x7d, 0xc2, 0x22, 0x78, 0xfc,
- 0x8e, 0x09, 0xb8, 0xa8, 0x85, 0xd7, 0xcc, 0x95, 0x97, 0x4b, 0x74, 0xd8,
- 0x9e, 0x7e, 0xf0, 0x00, 0xe4, 0x0e, 0x89, 0xae, 0x49, 0x28, 0x44, 0x1a,
- 0x10, 0x99, 0x32, 0x0f, 0x25, 0x88, 0x53, 0xa4, 0x0d, 0xb3, 0x0f, 0x12,
- 0x08, 0x16, 0x0b, 0x03, 0x71, 0x27, 0x1c, 0x7f, 0xe1, 0xdb, 0xd2, 0xfd,
- 0x67, 0x68, 0xc4, 0x05, 0x5d, 0x0a, 0x0e, 0x5d, 0x70, 0xd7, 0xd8, 0x97,
- 0xa0, 0xbc, 0x53, 0x41, 0x9a, 0x91, 0x8d, 0xf4, 0x9e, 0x36, 0x66, 0x7a,
- 0x7e, 0x56, 0xc1, 0x90, 0x5f, 0xe6, 0xb1, 0x68, 0x20, 0x36, 0xa4, 0x8c,
- 0x24, 0x2c, 0x2c, 0x47, 0x0b, 0x59, 0x76, 0x66, 0x30, 0xb5, 0xbe, 0xde,
- 0xed, 0x8f, 0xf8, 0x9d, 0xd3, 0xbb, 0x01, 0x30, 0xe6, 0xf2, 0xf3, 0x0e,
- 0xe0, 0x2c, 0x92, 0x80, 0xf3, 0x85, 0xf9, 0x28, 0x8a, 0xb4, 0x54, 0x2e,
- 0x9a, 0xed, 0xf7, 0x76, 0xfc, 0x15, 0x68, 0x16, 0xeb, 0x4a, 0x6c, 0xeb,
- 0x2e, 0x12, 0x8f, 0xd4, 0xcf, 0xfe, 0x0c, 0xc7, 0x5c, 0x1d, 0x0b, 0x7e,
- 0x05, 0x32, 0xbe, 0x5e, 0xb0, 0x09, 0x2a, 0x42, 0xd5, 0xc9, 0x4e, 0x90,
- 0xb3, 0x59, 0x0d, 0xbb, 0x7a, 0x7e, 0xcd, 0xd5, 0x08, 0x5a, 0xb4, 0x7f,
- 0xd8, 0x1c, 0x69, 0x11, 0xf9, 0x27, 0x0f, 0x7b, 0x06, 0xaf, 0x54, 0x83,
- 0x18, 0x7b, 0xe1, 0xdd, 0x54, 0x7a, 0x51, 0x68, 0x6e, 0x77, 0xfc, 0xc6,
- 0xbf, 0x52, 0x4a, 0x66, 0x46, 0xa1, 0xb2, 0x67, 0x1a, 0xbb, 0xa3, 0x4f,
- 0x77, 0xa0, 0xbe, 0x5d, 0xff, 0xfc, 0x56, 0x0b, 0x43, 0x72, 0x77, 0x90,
- 0xca, 0x9e, 0xf9, 0xf2, 0x39, 0xf5, 0x0d, 0xa9, 0xf4, 0xea, 0xd7, 0xe7,
- 0xb3, 0x10, 0x2f, 0x30, 0x42, 0x37, 0x21, 0xcc, 0x30, 0x70, 0xc9, 0x86,
- 0x98, 0x0f, 0xcc, 0x58, 0x4d, 0x83, 0xbb, 0x7d, 0xe5, 0x1a, 0xa5, 0x37,
- 0x8d, 0xb6, 0xac, 0x32, 0x97, 0x00, 0x3a, 0x63, 0x71, 0x24, 0x1e, 0x9e,
- 0x37, 0xc4, 0xff, 0x74, 0xd4, 0x37, 0xc0, 0xe2, 0xfe, 0x88, 0x46, 0x60,
- 0x11, 0xdd, 0x08, 0x3f, 0x50, 0x36, 0xab, 0xb8, 0x7a, 0xa4, 0x95, 0x62,
- 0x6a, 0x6e, 0xb0, 0xca, 0x6a, 0x21, 0x5a, 0x69, 0xf3, 0xf3, 0xfb, 0x1d,
- 0x70, 0x39, 0x95, 0xf3, 0xa7, 0x6e, 0xa6, 0x81, 0x89, 0xa1, 0x88, 0xc5,
- 0x3b, 0x71, 0xca, 0xa3, 0x52, 0xee, 0x83, 0xbb, 0xfd, 0xa0, 0x77, 0xf4,
- 0xe4, 0x6f, 0xe7, 0x42, 0xdb, 0x6d, 0x4a, 0x99, 0x8a, 0x34, 0x48, 0xbc,
- 0x17, 0xdc, 0xe4, 0x80, 0x08, 0x22, 0xb6, 0xf2, 0x31, 0xc0, 0x3f, 0x04,
- 0x3e, 0xeb, 0x9f, 0x20, 0x79, 0xd6, 0xb8, 0x06, 0x64, 0x64, 0x02, 0x31,
- 0xd7, 0xa9, 0xcd, 0x52, 0xfb, 0x84, 0x45, 0x69, 0x09, 0x00, 0x2a, 0xdc,
- 0x55, 0x8b, 0xc4, 0x06, 0x46, 0x4b, 0xc0, 0x4a, 0x1d, 0x09, 0x5b, 0x39,
- 0x28, 0xfd, 0xa9, 0xab, 0xce, 0x00, 0xf9, 0x2e, 0x48, 0x4b, 0x26, 0xe6,
- 0x30, 0x4c, 0xa5, 0x58, 0xca, 0xb4, 0x44, 0x82, 0x4f, 0xe7, 0x91, 0x1e,
- 0x33, 0xc3, 0xb0, 0x93, 0xff, 0x11, 0xfc, 0x81, 0xd2, 0xca, 0x1f, 0x71,
- 0x29, 0xdd, 0x76, 0x4f, 0x92, 0x25, 0xaf, 0x1d, 0x81, 0xb7, 0x0f, 0x2f,
- 0x8c, 0xc3, 0x06, 0xcc, 0x2f, 0x27, 0xa3, 0x4a, 0xe4, 0x0e, 0x99, 0xba,
- 0x7c, 0x1e, 0x45, 0x1f, 0x7f, 0xaa, 0x19, 0x45, 0x96, 0xfd, 0xfc, 0x3d,
- 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x07, 0x30, 0x82, 0x01,
- 0x03, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04,
- 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x02, 0x30, 0x0e, 0x06,
- 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01,
- 0x06, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14,
- 0xe1, 0x66, 0xcf, 0x0e, 0xd1, 0xf1, 0xb3, 0x4b, 0xb7, 0x06, 0x20, 0x14,
- 0xfe, 0x87, 0x12, 0xd5, 0xf6, 0xfe, 0xfb, 0x3e, 0x30, 0x1f, 0x06, 0x03,
- 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x4e, 0x0b, 0xef,
- 0x1a, 0xa4, 0x40, 0x5b, 0xa5, 0x17, 0x69, 0x87, 0x30, 0xca, 0x34, 0x68,
- 0x43, 0xd0, 0x41, 0xae, 0xf2, 0x30, 0x69, 0x06, 0x08, 0x2b, 0x06, 0x01,
- 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x5d, 0x30, 0x5b, 0x30, 0x27, 0x06,
- 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x1b, 0x68,
- 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x73,
- 0x74, 0x61, 0x72, 0x74, 0x73, 0x73, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x2f,
- 0x63, 0x61, 0x30, 0x30, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
- 0x30, 0x02, 0x86, 0x24, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x61,
- 0x69, 0x61, 0x2e, 0x73, 0x74, 0x61, 0x72, 0x74, 0x73, 0x73, 0x6c, 0x2e,
- 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x65, 0x72, 0x74, 0x73, 0x2f, 0x63, 0x61,
- 0x2e, 0x63, 0x72, 0x74, 0x30, 0x32, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04,
- 0x2b, 0x30, 0x29, 0x30, 0x27, 0xa0, 0x25, 0xa0, 0x23, 0x86, 0x21, 0x68,
- 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x73, 0x74,
- 0x61, 0x72, 0x74, 0x73, 0x73, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x73,
- 0x66, 0x73, 0x63, 0x61, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x0d, 0x06, 0x09,
- 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03,
- 0x82, 0x02, 0x01, 0x00, 0xb6, 0x6d, 0xf8, 0x70, 0xfb, 0xe2, 0x0d, 0x4c,
- 0x98, 0xb3, 0x07, 0x49, 0x15, 0xf5, 0x04, 0xc4, 0x6c, 0xca, 0xca, 0xf5,
- 0x68, 0xa0, 0x08, 0xfe, 0x12, 0x6d, 0x9c, 0x04, 0x06, 0xc9, 0xad, 0x9a,
- 0x91, 0x52, 0x3e, 0x78, 0xc4, 0x5c, 0xee, 0x9f, 0x54, 0x1d, 0xee, 0xe3,
- 0xf1, 0x5e, 0x30, 0xc9, 0x49, 0xe1, 0x39, 0xe0, 0xa6, 0x9d, 0x36, 0x6c,
- 0x57, 0xfa, 0xe6, 0x34, 0x4f, 0x55, 0xe8, 0x87, 0xa8, 0x2c, 0xdd, 0x05,
- 0xf1, 0x58, 0x12, 0x91, 0xe8, 0xca, 0xce, 0x28, 0x78, 0x8f, 0xdf, 0x07,
- 0x85, 0x01, 0xa5, 0xdc, 0x45, 0x96, 0x05, 0xd4, 0x80, 0xb2, 0x2b, 0x05,
- 0x9a, 0xcb, 0x9a, 0xa5, 0x8b, 0xe0, 0x3a, 0x67, 0xe6, 0x73, 0x47, 0xbe,
- 0x4a, 0xfd, 0x27, 0xb1, 0x88, 0xef, 0xe6, 0xca, 0xcf, 0x8d, 0x0e, 0x26,
- 0x9f, 0xfa, 0x5f, 0x57, 0x78, 0xad, 0x6d, 0xfe, 0xae, 0x9b, 0x35, 0x08,
- 0xb1, 0xc3, 0xba, 0xc1, 0x00, 0x4a, 0x4b, 0x7d, 0x14, 0xbd, 0xf7, 0xf1,
- 0xd3, 0x55, 0x18, 0xac, 0xd0, 0x33, 0x70, 0x88, 0x6d, 0xc4, 0x09, 0x71,
- 0x14, 0xa6, 0x2b, 0x4f, 0x88, 0x81, 0xe7, 0x0b, 0x00, 0x37, 0xa9, 0x15,
- 0x7d, 0x7e, 0xd7, 0x01, 0x96, 0x3f, 0x2f, 0xaf, 0x7b, 0x62, 0xae, 0x0a,
- 0x4a, 0xbf, 0x4b, 0x39, 0x2e, 0x35, 0x10, 0x8b, 0xfe, 0x04, 0x39, 0xe4,
- 0x3c, 0x3a, 0x0c, 0x09, 0x56, 0x40, 0x3a, 0xb5, 0xf4, 0xc2, 0x68, 0x0c,
- 0xb5, 0xf9, 0x52, 0xcd, 0xee, 0x9d, 0xf8, 0x98, 0xfc, 0x78, 0xe7, 0x58,
- 0x47, 0x8f, 0x1c, 0x73, 0x58, 0x69, 0x33, 0xab, 0xff, 0xdd, 0xdf, 0x8e,
- 0x24, 0x01, 0x77, 0x98, 0x19, 0x3a, 0xb0, 0x66, 0x79, 0xbc, 0xe1, 0x08,
- 0xa3, 0x0e, 0x4f, 0xc1, 0x04, 0xb3, 0xf3, 0x01, 0xc8, 0xeb, 0xd3, 0x59,
- 0x1c, 0x35, 0xd2, 0x93, 0x1e, 0x70, 0x65, 0x82, 0x7f, 0xdb, 0xcf, 0xfb,
- 0xc8, 0x99, 0x12, 0x60, 0xc3, 0x44, 0x6f, 0x3a, 0x80, 0x4b, 0xd7, 0xbe,
- 0x21, 0xaa, 0x14, 0x7a, 0x64, 0xcb, 0xdd, 0x37, 0x43, 0x45, 0x5b, 0x32,
- 0x2e, 0x45, 0xf0, 0xd9, 0x59, 0x1f, 0x6b, 0x18, 0xf0, 0x7c, 0xe9, 0x55,
- 0x36, 0x19, 0x61, 0x5f, 0xb5, 0x7d, 0xf1, 0x8d, 0xbd, 0x88, 0xe4, 0x75,
- 0x4b, 0x98, 0xdd, 0x27, 0xb0, 0xe4, 0x84, 0x44, 0x2a, 0x61, 0x84, 0x57,
- 0x05, 0x82, 0x11, 0x1f, 0xaa, 0x35, 0x58, 0xf3, 0x20, 0x0e, 0xaf, 0x59,
- 0xef, 0xfa, 0x55, 0x72, 0x72, 0x0d, 0x26, 0xd0, 0x9b, 0x53, 0x49, 0xac,
- 0xce, 0x37, 0x2e, 0x65, 0x61, 0xff, 0xf6, 0xec, 0x1b, 0xea, 0xf6, 0xf1,
- 0xa6, 0xd3, 0xd1, 0xb5, 0x7b, 0xbe, 0x35, 0xf4, 0x22, 0xc1, 0xbc, 0x8d,
- 0x01, 0xbd, 0x68, 0x5e, 0x83, 0x0d, 0x2f, 0xec, 0xd6, 0xda, 0x63, 0x0c,
- 0x27, 0xd1, 0x54, 0x3e, 0xe4, 0xa8, 0xd3, 0xce, 0x4b, 0x32, 0xb8, 0x91,
- 0x94, 0xff, 0xfb, 0x5b, 0x49, 0x2d, 0x75, 0x18, 0xa8, 0xba, 0x71, 0x9a,
- 0x3b, 0xae, 0xd9, 0xc0, 0xa9, 0x4f, 0x87, 0x91, 0xed, 0x8b, 0x7b, 0x6b,
- 0x20, 0x98, 0x89, 0x39, 0x83, 0x4f, 0x80, 0xc4, 0x69, 0xcc, 0x17, 0xc9,
- 0xc8, 0x4e, 0xbe, 0xe4, 0xa9, 0xa5, 0x81, 0x76, 0x70, 0x06, 0x04, 0x32,
- 0xcd, 0x83, 0x65, 0xf4, 0xbc, 0x7d, 0x3e, 0x13, 0xbc, 0xd2, 0xe8, 0x6f,
- 0x63, 0xaa, 0xb5, 0x3b, 0xda, 0x8d, 0x86, 0x32, 0x82, 0x78, 0x9d, 0xd9,
- 0xcc, 0xff, 0xbf, 0x57, 0x64, 0x74, 0xed, 0x28, 0x3d, 0x44, 0x62, 0x15,
- 0x61, 0x4b, 0xf7, 0x94, 0xb0, 0x0d, 0x2a, 0x67, 0x1c, 0xf0, 0xcb, 0x9b,
- 0xa5, 0x92, 0xbf, 0xf8, 0x41, 0x5a, 0xc1, 0x3d, 0x60, 0xed, 0x9f, 0xbb,
- 0xb8, 0x6d, 0x9b, 0xce, 0xa9, 0x6a, 0x16, 0x3f, 0x7e, 0xea, 0x06, 0xf1,
-};
-
-#if 0
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number:
- 03:37:b9:28:34:7c:60:a6:ae:c5:ad:b1:21:7f:38:60
- Signature Algorithm: sha1WithRSAEncryption
- Issuer: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert High Assurance EV Root CA
- Validity
- Not Before: Nov 9 12:00:00 2007 GMT
- Not After : Nov 10 00:00:00 2021 GMT
- Subject: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert High Assurance EV CA-1
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:f3:96:62:d8:75:6e:19:ff:3f:34:7c:49:4f:31:
- 7e:0d:04:4e:99:81:e2:b3:85:55:91:30:b1:c0:af:
- 70:bb:2c:a8:e7:18:aa:3f:78:f7:90:68:52:86:01:
- 88:97:e2:3b:06:65:90:aa:bd:65:76:c2:ec:be:10:
- 5b:37:78:83:60:75:45:c6:bd:74:aa:b6:9f:a4:3a:
- 01:50:17:c4:39:69:b9:f1:4f:ef:82:c1:ca:f3:4a:
- db:cc:9e:50:4f:4d:40:a3:3a:90:e7:86:66:bc:f0:
- 3e:76:28:4c:d1:75:80:9e:6a:35:14:35:03:9e:db:
- 0c:8c:c2:28:ad:50:b2:ce:f6:91:a3:c3:a5:0a:58:
- 49:f6:75:44:6c:ba:f9:ce:e9:ab:3a:02:e0:4d:f3:
- ac:e2:7a:e0:60:22:05:3c:82:d3:52:e2:f3:9c:47:
- f8:3b:d8:b2:4b:93:56:4a:bf:70:ab:3e:e9:68:c8:
- 1d:8f:58:1d:2a:4d:5e:27:3d:ad:0a:59:2f:5a:11:
- 20:40:d9:68:04:68:2d:f4:c0:84:0b:0a:1b:78:df:
- ed:1a:58:dc:fb:41:5a:6d:6b:f2:ed:1c:ee:5c:32:
- b6:5c:ec:d7:a6:03:32:a6:e8:de:b7:28:27:59:88:
- 80:ff:7b:ad:89:58:d5:1e:14:a4:f2:b0:70:d4:a0:
- 3e:a7
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Key Usage: critical
- Digital Signature, Certificate Sign, CRL Sign
- X509v3 Extended Key Usage:
- TLS Web Server Authentication, TLS Web Client Authentication, Code Signing, E-mail Protection, Time Stamping
- X509v3 Certificate Policies:
- Policy: 2.16.840.1.114412.2.1
- CPS: http://www.digicert.com/ssl-cps-repository.htm
- User Notice:
- Explicit Text:
-
- X509v3 Basic Constraints: critical
- CA:TRUE, pathlen:0
- Authority Information Access:
- OCSP - URI:http://ocsp.digicert.com
- CA Issuers - URI:http://www.digicert.com/CACerts/DigiCertHighAssuranceEVRootCA.crt
-
- X509v3 CRL Distribution Points:
-
- Full Name:
- URI:http://crl3.digicert.com/DigiCertHighAssuranceEVRootCA.crl
-
- Full Name:
- URI:http://crl4.digicert.com/DigiCertHighAssuranceEVRootCA.crl
-
- X509v3 Subject Key Identifier:
- 4C:58:CB:25:F0:41:4F:52:F4:28:C8:81:43:9B:A6:A8:A0:E6:92:E5
- X509v3 Authority Key Identifier:
- keyid:B1:3E:C3:69:03:F8:BF:47:01:D4:98:26:1A:08:02:EF:63:64:2B:C3
-
- Signature Algorithm: sha1WithRSAEncryption
- 4c:7a:17:87:28:5d:17:bc:b2:32:73:bf:cd:2e:f5:58:31:1d:
- f0:b1:71:54:9c:d6:9b:67:93:db:2f:03:3e:16:6f:1e:03:c9:
- 53:84:a3:56:60:1e:78:94:1b:a2:a8:6f:a3:a4:8b:52:91:d7:
- dd:5c:95:bb:ef:b5:16:49:e9:a5:42:4f:34:f2:47:ff:ae:81:
- 7f:13:54:b7:20:c4:70:15:cb:81:0a:81:cb:74:57:dc:9c:df:
- 24:a4:29:0c:18:f0:1c:e4:ae:07:33:ec:f1:49:3e:55:cf:6e:
- 4f:0d:54:7b:d3:c9:e8:15:48:d4:c5:bb:dc:35:1c:77:45:07:
- 48:45:85:bd:d7:7e:53:b8:c0:16:d9:95:cd:8b:8d:7d:c9:60:
- 4f:d1:a2:9b:e3:d0:30:d6:b4:73:36:e6:d2:f9:03:b2:e3:a4:
- f5:e5:b8:3e:04:49:00:ba:2e:a6:4a:72:83:72:9d:f7:0b:8c:
- a9:89:e7:b3:d7:64:1f:d6:e3:60:cb:03:c4:dc:88:e9:9d:25:
- 01:00:71:cb:03:b4:29:60:25:8f:f9:46:d1:7b:71:ae:cd:53:
- 12:5b:84:8e:c2:0f:c7:ed:93:19:d9:c9:fa:8f:58:34:76:32:
- 2f:ae:e1:50:14:61:d4:a8:58:a3:c8:30:13:23:ef:c6:25:8c:
- 36:8f:1c:80
------BEGIN CERTIFICATE-----
-MIIG5jCCBc6gAwIBAgIQAze5KDR8YKauxa2xIX84YDANBgkqhkiG9w0BAQUFADBs
-MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
-d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j
-ZSBFViBSb290IENBMB4XDTA3MTEwOTEyMDAwMFoXDTIxMTExMDAwMDAwMFowaTEL
-MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3
-LmRpZ2ljZXJ0LmNvbTEoMCYGA1UEAxMfRGlnaUNlcnQgSGlnaCBBc3N1cmFuY2Ug
-RVYgQ0EtMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAPOWYth1bhn/
-PzR8SU8xfg0ETpmB4rOFVZEwscCvcLssqOcYqj9495BoUoYBiJfiOwZlkKq9ZXbC
-7L4QWzd4g2B1Rca9dKq2n6Q6AVAXxDlpufFP74LByvNK28yeUE9NQKM6kOeGZrzw
-PnYoTNF1gJ5qNRQ1A57bDIzCKK1Qss72kaPDpQpYSfZ1RGy6+c7pqzoC4E3zrOJ6
-4GAiBTyC01Li85xH+DvYskuTVkq/cKs+6WjIHY9YHSpNXic9rQpZL1oRIEDZaARo
-LfTAhAsKG3jf7RpY3PtBWm1r8u0c7lwytlzs16YDMqbo3rcoJ1mIgP97rYlY1R4U
-pPKwcNSgPqcCAwEAAaOCA4UwggOBMA4GA1UdDwEB/wQEAwIBhjA7BgNVHSUENDAy
-BggrBgEFBQcDAQYIKwYBBQUHAwIGCCsGAQUFBwMDBggrBgEFBQcDBAYIKwYBBQUH
-AwgwggHEBgNVHSAEggG7MIIBtzCCAbMGCWCGSAGG/WwCATCCAaQwOgYIKwYBBQUH
-AgEWLmh0dHA6Ly93d3cuZGlnaWNlcnQuY29tL3NzbC1jcHMtcmVwb3NpdG9yeS5o
-dG0wggFkBggrBgEFBQcCAjCCAVYeggFSAEEAbgB5ACAAdQBzAGUAIABvAGYAIAB0
-AGgAaQBzACAAQwBlAHIAdABpAGYAaQBjAGEAdABlACAAYwBvAG4AcwB0AGkAdAB1
-AHQAZQBzACAAYQBjAGMAZQBwAHQAYQBuAGMAZQAgAG8AZgAgAHQAaABlACAARABp
-AGcAaQBDAGUAcgB0ACAARQBWACAAQwBQAFMAIABhAG4AZAAgAHQAaABlACAAUgBl
-AGwAeQBpAG4AZwAgAFAAYQByAHQAeQAgAEEAZwByAGUAZQBtAGUAbgB0ACAAdwBo
-AGkAYwBoACAAbABpAG0AaQB0ACAAbABpAGEAYgBpAGwAaQB0AHkAIABhAG4AZAAg
-AGEAcgBlACAAaQBuAGMAbwByAHAAbwByAGEAdABlAGQAIABoAGUAcgBlAGkAbgAg
-AGIAeQAgAHIAZQBmAGUAcgBlAG4AYwBlAC4wEgYDVR0TAQH/BAgwBgEB/wIBADCB
-gwYIKwYBBQUHAQEEdzB1MCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2Vy
-dC5jb20wTQYIKwYBBQUHMAKGQWh0dHA6Ly93d3cuZGlnaWNlcnQuY29tL0NBQ2Vy
-dHMvRGlnaUNlcnRIaWdoQXNzdXJhbmNlRVZSb290Q0EuY3J0MIGPBgNVHR8EgYcw
-gYQwQKA+oDyGOmh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEhpZ2hB
-c3N1cmFuY2VFVlJvb3RDQS5jcmwwQKA+oDyGOmh0dHA6Ly9jcmw0LmRpZ2ljZXJ0
-LmNvbS9EaWdpQ2VydEhpZ2hBc3N1cmFuY2VFVlJvb3RDQS5jcmwwHQYDVR0OBBYE
-FExYyyXwQU9S9CjIgUObpqig5pLlMB8GA1UdIwQYMBaAFLE+w2kD+L9HAdSYJhoI
-Au9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQBMeheHKF0XvLIyc7/NLvVYMR3wsXFU
-nNabZ5PbLwM+Fm8eA8lThKNWYB54lBuiqG+jpItSkdfdXJW777UWSemlQk808kf/
-roF/E1S3IMRwFcuBCoHLdFfcnN8kpCkMGPAc5K4HM+zxST5Vz25PDVR708noFUjU
-xbvcNRx3RQdIRYW9135TuMAW2ZXNi419yWBP0aKb49Aw1rRzNubS+QOy46T15bg+
-BEkAui6mSnKDcp33C4ypieez12Qf1uNgywPE3IjpnSUBAHHLA7QpYCWP+UbRe3Gu
-zVMSW4SOwg/H7ZMZ2cn6j1g0djIvruFQFGHUqFijyDATI+/GJYw2jxyA
------END CERTIFICATE-----
-#endif
-static const unsigned char kDERCert53[] = {
- 0x30, 0x82, 0x06, 0xe6, 0x30, 0x82, 0x05, 0xce, 0xa0, 0x03, 0x02, 0x01,
- 0x02, 0x02, 0x10, 0x03, 0x37, 0xb9, 0x28, 0x34, 0x7c, 0x60, 0xa6, 0xae,
- 0xc5, 0xad, 0xb1, 0x21, 0x7f, 0x38, 0x60, 0x30, 0x0d, 0x06, 0x09, 0x2a,
- 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x6c,
- 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55,
- 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0c,
- 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, 0x6e, 0x63,
- 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x10, 0x77,
- 0x77, 0x77, 0x2e, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, 0x74, 0x2e,
- 0x63, 0x6f, 0x6d, 0x31, 0x2b, 0x30, 0x29, 0x06, 0x03, 0x55, 0x04, 0x03,
- 0x13, 0x22, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x48,
- 0x69, 0x67, 0x68, 0x20, 0x41, 0x73, 0x73, 0x75, 0x72, 0x61, 0x6e, 0x63,
- 0x65, 0x20, 0x45, 0x56, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41,
- 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x37, 0x31, 0x31, 0x30, 0x39, 0x31, 0x32,
- 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x31, 0x31, 0x31, 0x31,
- 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x69, 0x31, 0x0b,
- 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31,
- 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0c, 0x44, 0x69,
- 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, 0x6e, 0x63, 0x31, 0x19,
- 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x10, 0x77, 0x77, 0x77,
- 0x2e, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, 0x74, 0x2e, 0x63, 0x6f,
- 0x6d, 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x1f,
- 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x48, 0x69, 0x67,
- 0x68, 0x20, 0x41, 0x73, 0x73, 0x75, 0x72, 0x61, 0x6e, 0x63, 0x65, 0x20,
- 0x45, 0x56, 0x20, 0x43, 0x41, 0x2d, 0x31, 0x30, 0x82, 0x01, 0x22, 0x30,
- 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01,
- 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02,
- 0x82, 0x01, 0x01, 0x00, 0xf3, 0x96, 0x62, 0xd8, 0x75, 0x6e, 0x19, 0xff,
- 0x3f, 0x34, 0x7c, 0x49, 0x4f, 0x31, 0x7e, 0x0d, 0x04, 0x4e, 0x99, 0x81,
- 0xe2, 0xb3, 0x85, 0x55, 0x91, 0x30, 0xb1, 0xc0, 0xaf, 0x70, 0xbb, 0x2c,
- 0xa8, 0xe7, 0x18, 0xaa, 0x3f, 0x78, 0xf7, 0x90, 0x68, 0x52, 0x86, 0x01,
- 0x88, 0x97, 0xe2, 0x3b, 0x06, 0x65, 0x90, 0xaa, 0xbd, 0x65, 0x76, 0xc2,
- 0xec, 0xbe, 0x10, 0x5b, 0x37, 0x78, 0x83, 0x60, 0x75, 0x45, 0xc6, 0xbd,
- 0x74, 0xaa, 0xb6, 0x9f, 0xa4, 0x3a, 0x01, 0x50, 0x17, 0xc4, 0x39, 0x69,
- 0xb9, 0xf1, 0x4f, 0xef, 0x82, 0xc1, 0xca, 0xf3, 0x4a, 0xdb, 0xcc, 0x9e,
- 0x50, 0x4f, 0x4d, 0x40, 0xa3, 0x3a, 0x90, 0xe7, 0x86, 0x66, 0xbc, 0xf0,
- 0x3e, 0x76, 0x28, 0x4c, 0xd1, 0x75, 0x80, 0x9e, 0x6a, 0x35, 0x14, 0x35,
- 0x03, 0x9e, 0xdb, 0x0c, 0x8c, 0xc2, 0x28, 0xad, 0x50, 0xb2, 0xce, 0xf6,
- 0x91, 0xa3, 0xc3, 0xa5, 0x0a, 0x58, 0x49, 0xf6, 0x75, 0x44, 0x6c, 0xba,
- 0xf9, 0xce, 0xe9, 0xab, 0x3a, 0x02, 0xe0, 0x4d, 0xf3, 0xac, 0xe2, 0x7a,
- 0xe0, 0x60, 0x22, 0x05, 0x3c, 0x82, 0xd3, 0x52, 0xe2, 0xf3, 0x9c, 0x47,
- 0xf8, 0x3b, 0xd8, 0xb2, 0x4b, 0x93, 0x56, 0x4a, 0xbf, 0x70, 0xab, 0x3e,
- 0xe9, 0x68, 0xc8, 0x1d, 0x8f, 0x58, 0x1d, 0x2a, 0x4d, 0x5e, 0x27, 0x3d,
- 0xad, 0x0a, 0x59, 0x2f, 0x5a, 0x11, 0x20, 0x40, 0xd9, 0x68, 0x04, 0x68,
- 0x2d, 0xf4, 0xc0, 0x84, 0x0b, 0x0a, 0x1b, 0x78, 0xdf, 0xed, 0x1a, 0x58,
- 0xdc, 0xfb, 0x41, 0x5a, 0x6d, 0x6b, 0xf2, 0xed, 0x1c, 0xee, 0x5c, 0x32,
- 0xb6, 0x5c, 0xec, 0xd7, 0xa6, 0x03, 0x32, 0xa6, 0xe8, 0xde, 0xb7, 0x28,
- 0x27, 0x59, 0x88, 0x80, 0xff, 0x7b, 0xad, 0x89, 0x58, 0xd5, 0x1e, 0x14,
- 0xa4, 0xf2, 0xb0, 0x70, 0xd4, 0xa0, 0x3e, 0xa7, 0x02, 0x03, 0x01, 0x00,
- 0x01, 0xa3, 0x82, 0x03, 0x85, 0x30, 0x82, 0x03, 0x81, 0x30, 0x0e, 0x06,
- 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01,
- 0x86, 0x30, 0x3b, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04, 0x34, 0x30, 0x32,
- 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x01, 0x06, 0x08,
- 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x02, 0x06, 0x08, 0x2b, 0x06,
- 0x01, 0x05, 0x05, 0x07, 0x03, 0x03, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05,
- 0x05, 0x07, 0x03, 0x04, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
- 0x03, 0x08, 0x30, 0x82, 0x01, 0xc4, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04,
- 0x82, 0x01, 0xbb, 0x30, 0x82, 0x01, 0xb7, 0x30, 0x82, 0x01, 0xb3, 0x06,
- 0x09, 0x60, 0x86, 0x48, 0x01, 0x86, 0xfd, 0x6c, 0x02, 0x01, 0x30, 0x82,
- 0x01, 0xa4, 0x30, 0x3a, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
- 0x02, 0x01, 0x16, 0x2e, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77,
- 0x77, 0x77, 0x2e, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, 0x74, 0x2e,
- 0x63, 0x6f, 0x6d, 0x2f, 0x73, 0x73, 0x6c, 0x2d, 0x63, 0x70, 0x73, 0x2d,
- 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x2e, 0x68,
- 0x74, 0x6d, 0x30, 0x82, 0x01, 0x64, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05,
- 0x05, 0x07, 0x02, 0x02, 0x30, 0x82, 0x01, 0x56, 0x1e, 0x82, 0x01, 0x52,
- 0x00, 0x41, 0x00, 0x6e, 0x00, 0x79, 0x00, 0x20, 0x00, 0x75, 0x00, 0x73,
- 0x00, 0x65, 0x00, 0x20, 0x00, 0x6f, 0x00, 0x66, 0x00, 0x20, 0x00, 0x74,
- 0x00, 0x68, 0x00, 0x69, 0x00, 0x73, 0x00, 0x20, 0x00, 0x43, 0x00, 0x65,
- 0x00, 0x72, 0x00, 0x74, 0x00, 0x69, 0x00, 0x66, 0x00, 0x69, 0x00, 0x63,
- 0x00, 0x61, 0x00, 0x74, 0x00, 0x65, 0x00, 0x20, 0x00, 0x63, 0x00, 0x6f,
- 0x00, 0x6e, 0x00, 0x73, 0x00, 0x74, 0x00, 0x69, 0x00, 0x74, 0x00, 0x75,
- 0x00, 0x74, 0x00, 0x65, 0x00, 0x73, 0x00, 0x20, 0x00, 0x61, 0x00, 0x63,
- 0x00, 0x63, 0x00, 0x65, 0x00, 0x70, 0x00, 0x74, 0x00, 0x61, 0x00, 0x6e,
- 0x00, 0x63, 0x00, 0x65, 0x00, 0x20, 0x00, 0x6f, 0x00, 0x66, 0x00, 0x20,
- 0x00, 0x74, 0x00, 0x68, 0x00, 0x65, 0x00, 0x20, 0x00, 0x44, 0x00, 0x69,
- 0x00, 0x67, 0x00, 0x69, 0x00, 0x43, 0x00, 0x65, 0x00, 0x72, 0x00, 0x74,
- 0x00, 0x20, 0x00, 0x45, 0x00, 0x56, 0x00, 0x20, 0x00, 0x43, 0x00, 0x50,
- 0x00, 0x53, 0x00, 0x20, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x64, 0x00, 0x20,
- 0x00, 0x74, 0x00, 0x68, 0x00, 0x65, 0x00, 0x20, 0x00, 0x52, 0x00, 0x65,
- 0x00, 0x6c, 0x00, 0x79, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x67, 0x00, 0x20,
- 0x00, 0x50, 0x00, 0x61, 0x00, 0x72, 0x00, 0x74, 0x00, 0x79, 0x00, 0x20,
- 0x00, 0x41, 0x00, 0x67, 0x00, 0x72, 0x00, 0x65, 0x00, 0x65, 0x00, 0x6d,
- 0x00, 0x65, 0x00, 0x6e, 0x00, 0x74, 0x00, 0x20, 0x00, 0x77, 0x00, 0x68,
- 0x00, 0x69, 0x00, 0x63, 0x00, 0x68, 0x00, 0x20, 0x00, 0x6c, 0x00, 0x69,
- 0x00, 0x6d, 0x00, 0x69, 0x00, 0x74, 0x00, 0x20, 0x00, 0x6c, 0x00, 0x69,
- 0x00, 0x61, 0x00, 0x62, 0x00, 0x69, 0x00, 0x6c, 0x00, 0x69, 0x00, 0x74,
- 0x00, 0x79, 0x00, 0x20, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x64, 0x00, 0x20,
- 0x00, 0x61, 0x00, 0x72, 0x00, 0x65, 0x00, 0x20, 0x00, 0x69, 0x00, 0x6e,
- 0x00, 0x63, 0x00, 0x6f, 0x00, 0x72, 0x00, 0x70, 0x00, 0x6f, 0x00, 0x72,
- 0x00, 0x61, 0x00, 0x74, 0x00, 0x65, 0x00, 0x64, 0x00, 0x20, 0x00, 0x68,
- 0x00, 0x65, 0x00, 0x72, 0x00, 0x65, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x20,
- 0x00, 0x62, 0x00, 0x79, 0x00, 0x20, 0x00, 0x72, 0x00, 0x65, 0x00, 0x66,
- 0x00, 0x65, 0x00, 0x72, 0x00, 0x65, 0x00, 0x6e, 0x00, 0x63, 0x00, 0x65,
- 0x00, 0x2e, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff,
- 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x00, 0x30, 0x81,
- 0x83, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04,
- 0x77, 0x30, 0x75, 0x30, 0x24, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05,
- 0x07, 0x30, 0x01, 0x86, 0x18, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f,
- 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72,
- 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x4d, 0x06, 0x08, 0x2b, 0x06, 0x01,
- 0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x41, 0x68, 0x74, 0x74, 0x70, 0x3a,
- 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65,
- 0x72, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x43, 0x41, 0x43, 0x65, 0x72,
- 0x74, 0x73, 0x2f, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x48,
- 0x69, 0x67, 0x68, 0x41, 0x73, 0x73, 0x75, 0x72, 0x61, 0x6e, 0x63, 0x65,
- 0x45, 0x56, 0x52, 0x6f, 0x6f, 0x74, 0x43, 0x41, 0x2e, 0x63, 0x72, 0x74,
- 0x30, 0x81, 0x8f, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x81, 0x87, 0x30,
- 0x81, 0x84, 0x30, 0x40, 0xa0, 0x3e, 0xa0, 0x3c, 0x86, 0x3a, 0x68, 0x74,
- 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x33, 0x2e, 0x64, 0x69,
- 0x67, 0x69, 0x63, 0x65, 0x72, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x44,
- 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x48, 0x69, 0x67, 0x68, 0x41,
- 0x73, 0x73, 0x75, 0x72, 0x61, 0x6e, 0x63, 0x65, 0x45, 0x56, 0x52, 0x6f,
- 0x6f, 0x74, 0x43, 0x41, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x40, 0xa0, 0x3e,
- 0xa0, 0x3c, 0x86, 0x3a, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63,
- 0x72, 0x6c, 0x34, 0x2e, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, 0x74,
- 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72,
- 0x74, 0x48, 0x69, 0x67, 0x68, 0x41, 0x73, 0x73, 0x75, 0x72, 0x61, 0x6e,
- 0x63, 0x65, 0x45, 0x56, 0x52, 0x6f, 0x6f, 0x74, 0x43, 0x41, 0x2e, 0x63,
- 0x72, 0x6c, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04,
- 0x14, 0x4c, 0x58, 0xcb, 0x25, 0xf0, 0x41, 0x4f, 0x52, 0xf4, 0x28, 0xc8,
- 0x81, 0x43, 0x9b, 0xa6, 0xa8, 0xa0, 0xe6, 0x92, 0xe5, 0x30, 0x1f, 0x06,
- 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0xb1, 0x3e,
- 0xc3, 0x69, 0x03, 0xf8, 0xbf, 0x47, 0x01, 0xd4, 0x98, 0x26, 0x1a, 0x08,
- 0x02, 0xef, 0x63, 0x64, 0x2b, 0xc3, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
- 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x82, 0x01,
- 0x01, 0x00, 0x4c, 0x7a, 0x17, 0x87, 0x28, 0x5d, 0x17, 0xbc, 0xb2, 0x32,
- 0x73, 0xbf, 0xcd, 0x2e, 0xf5, 0x58, 0x31, 0x1d, 0xf0, 0xb1, 0x71, 0x54,
- 0x9c, 0xd6, 0x9b, 0x67, 0x93, 0xdb, 0x2f, 0x03, 0x3e, 0x16, 0x6f, 0x1e,
- 0x03, 0xc9, 0x53, 0x84, 0xa3, 0x56, 0x60, 0x1e, 0x78, 0x94, 0x1b, 0xa2,
- 0xa8, 0x6f, 0xa3, 0xa4, 0x8b, 0x52, 0x91, 0xd7, 0xdd, 0x5c, 0x95, 0xbb,
- 0xef, 0xb5, 0x16, 0x49, 0xe9, 0xa5, 0x42, 0x4f, 0x34, 0xf2, 0x47, 0xff,
- 0xae, 0x81, 0x7f, 0x13, 0x54, 0xb7, 0x20, 0xc4, 0x70, 0x15, 0xcb, 0x81,
- 0x0a, 0x81, 0xcb, 0x74, 0x57, 0xdc, 0x9c, 0xdf, 0x24, 0xa4, 0x29, 0x0c,
- 0x18, 0xf0, 0x1c, 0xe4, 0xae, 0x07, 0x33, 0xec, 0xf1, 0x49, 0x3e, 0x55,
- 0xcf, 0x6e, 0x4f, 0x0d, 0x54, 0x7b, 0xd3, 0xc9, 0xe8, 0x15, 0x48, 0xd4,
- 0xc5, 0xbb, 0xdc, 0x35, 0x1c, 0x77, 0x45, 0x07, 0x48, 0x45, 0x85, 0xbd,
- 0xd7, 0x7e, 0x53, 0xb8, 0xc0, 0x16, 0xd9, 0x95, 0xcd, 0x8b, 0x8d, 0x7d,
- 0xc9, 0x60, 0x4f, 0xd1, 0xa2, 0x9b, 0xe3, 0xd0, 0x30, 0xd6, 0xb4, 0x73,
- 0x36, 0xe6, 0xd2, 0xf9, 0x03, 0xb2, 0xe3, 0xa4, 0xf5, 0xe5, 0xb8, 0x3e,
- 0x04, 0x49, 0x00, 0xba, 0x2e, 0xa6, 0x4a, 0x72, 0x83, 0x72, 0x9d, 0xf7,
- 0x0b, 0x8c, 0xa9, 0x89, 0xe7, 0xb3, 0xd7, 0x64, 0x1f, 0xd6, 0xe3, 0x60,
- 0xcb, 0x03, 0xc4, 0xdc, 0x88, 0xe9, 0x9d, 0x25, 0x01, 0x00, 0x71, 0xcb,
- 0x03, 0xb4, 0x29, 0x60, 0x25, 0x8f, 0xf9, 0x46, 0xd1, 0x7b, 0x71, 0xae,
- 0xcd, 0x53, 0x12, 0x5b, 0x84, 0x8e, 0xc2, 0x0f, 0xc7, 0xed, 0x93, 0x19,
- 0xd9, 0xc9, 0xfa, 0x8f, 0x58, 0x34, 0x76, 0x32, 0x2f, 0xae, 0xe1, 0x50,
- 0x14, 0x61, 0xd4, 0xa8, 0x58, 0xa3, 0xc8, 0x30, 0x13, 0x23, 0xef, 0xc6,
- 0x25, 0x8c, 0x36, 0x8f, 0x1c, 0x80,
-};
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/common_cert_set_3.c b/chromium/net/third_party/quiche/src/quic/core/crypto/common_cert_set_3.c
deleted file mode 100644
index e387b1b20b8..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/common_cert_set_3.c
+++ /dev/null
@@ -1,118 +0,0 @@
-/* This file contains common certificates. It's designed to be #included in
- * another file, in a namespace. */
-
-#include "quic/core/crypto/common_cert_set_3a.inc"
-#include "quic/core/crypto/common_cert_set_3b.inc"
-
-static const size_t kNumCerts = 52;
-static const unsigned char* const kCerts[] = {
- kDERCert0,
- kDERCert1,
- kDERCert2,
- kDERCert3,
- kDERCert4,
- kDERCert5,
- kDERCert6,
- kDERCert7,
- kDERCert8,
- kDERCert9,
- kDERCert10,
- kDERCert11,
- kDERCert12,
- kDERCert13,
- kDERCert14,
- kDERCert15,
- kDERCert16,
- kDERCert17,
- kDERCert18,
- kDERCert19,
- kDERCert20,
- kDERCert21,
- kDERCert22,
- kDERCert23,
- kDERCert24,
- kDERCert25,
- kDERCert26,
- kDERCert27,
- kDERCert28,
- kDERCert29,
- kDERCert30,
- kDERCert31,
- kDERCert32,
- kDERCert33,
- kDERCert34,
- kDERCert35,
- kDERCert36,
- kDERCert37,
- kDERCert38,
- kDERCert39,
- kDERCert40,
- kDERCert41,
- kDERCert42,
- kDERCert43,
- kDERCert44,
- kDERCert45,
- kDERCert46,
- kDERCert47,
- kDERCert48,
- kDERCert49,
- kDERCert50,
- kDERCert51,
-};
-
-static const size_t kLens[] = {
- 897,
- 911,
- 1012,
- 1049,
- 1065,
- 1096,
- 1097,
- 1101,
- 1105,
- 1105,
- 1107,
- 1117,
- 1127,
- 1133,
- 1136,
- 1138,
- 1139,
- 1145,
- 1149,
- 1153,
- 1167,
- 1172,
- 1174,
- 1174,
- 1176,
- 1188,
- 1194,
- 1196,
- 1203,
- 1205,
- 1206,
- 1208,
- 1209,
- 1210,
- 1222,
- 1227,
- 1236,
- 1236,
- 1238,
- 1283,
- 1284,
- 1287,
- 1298,
- 1315,
- 1327,
- 1340,
- 1357,
- 1418,
- 1447,
- 1509,
- 1513,
- 1632,
-};
-
-static const uint64_t kHash = UINT64_C(0x918215a28680ed7e);
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/common_cert_set_3a.inc b/chromium/net/third_party/quiche/src/quic/core/crypto/common_cert_set_3a.inc
deleted file mode 100644
index d5bff198414..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/common_cert_set_3a.inc
+++ /dev/null
@@ -1,5033 +0,0 @@
-/* This file contains common certificates. It's designed to be #included in
- * another file, in a namespace. */
-
-#if 0
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number: 1227750 (0x12bbe6)
- Signature Algorithm: sha1WithRSAEncryption
- Issuer: C=US, O=Equifax, OU=Equifax Secure Certificate Authority
- Validity
- Not Before: May 21 04:00:00 2002 GMT
- Not After : Aug 21 04:00:00 2018 GMT
- Subject: C=US, O=GeoTrust Inc., CN=GeoTrust Global CA
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:da:cc:18:63:30:fd:f4:17:23:1a:56:7e:5b:df:
- 3c:6c:38:e4:71:b7:78:91:d4:bc:a1:d8:4c:f8:a8:
- 43:b6:03:e9:4d:21:07:08:88:da:58:2f:66:39:29:
- bd:05:78:8b:9d:38:e8:05:b7:6a:7e:71:a4:e6:c4:
- 60:a6:b0:ef:80:e4:89:28:0f:9e:25:d6:ed:83:f3:
- ad:a6:91:c7:98:c9:42:18:35:14:9d:ad:98:46:92:
- 2e:4f:ca:f1:87:43:c1:16:95:57:2d:50:ef:89:2d:
- 80:7a:57:ad:f2:ee:5f:6b:d2:00:8d:b9:14:f8:14:
- 15:35:d9:c0:46:a3:7b:72:c8:91:bf:c9:55:2b:cd:
- d0:97:3e:9c:26:64:cc:df:ce:83:19:71:ca:4e:e6:
- d4:d5:7b:a9:19:cd:55:de:c8:ec:d2:5e:38:53:e5:
- 5c:4f:8c:2d:fe:50:23:36:fc:66:e6:cb:8e:a4:39:
- 19:00:b7:95:02:39:91:0b:0e:fe:38:2e:d1:1d:05:
- 9a:f6:4d:3e:6f:0f:07:1d:af:2c:1e:8f:60:39:e2:
- fa:36:53:13:39:d4:5e:26:2b:db:3d:a8:14:bd:32:
- eb:18:03:28:52:04:71:e5:ab:33:3d:e1:38:bb:07:
- 36:84:62:9c:79:ea:16:30:f4:5f:c0:2b:e8:71:6b:
- e4:f9
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Authority Key Identifier:
- keyid:48:E6:68:F9:2B:D2:B2:95:D7:47:D8:23:20:10:4F:33:98:90:9F:D4
-
- X509v3 Subject Key Identifier:
- C0:7A:98:68:8D:89:FB:AB:05:64:0C:11:7D:AA:7D:65:B8:CA:CC:4E
- X509v3 Basic Constraints: critical
- CA:TRUE
- X509v3 Key Usage: critical
- Certificate Sign, CRL Sign
- X509v3 CRL Distribution Points:
-
- Full Name:
- URI:http://crl.geotrust.com/crls/secureca.crl
-
- X509v3 Certificate Policies:
- Policy: X509v3 Any Policy
- CPS: https://www.geotrust.com/resources/repository
-
- Signature Algorithm: sha1WithRSAEncryption
- 76:e1:12:6e:4e:4b:16:12:86:30:06:b2:81:08:cf:f0:08:c7:
- c7:71:7e:66:ee:c2:ed:d4:3b:1f:ff:f0:f0:c8:4e:d6:43:38:
- b0:b9:30:7d:18:d0:55:83:a2:6a:cb:36:11:9c:e8:48:66:a3:
- 6d:7f:b8:13:d4:47:fe:8b:5a:5c:73:fc:ae:d9:1b:32:19:38:
- ab:97:34:14:aa:96:d2:eb:a3:1c:14:08:49:b6:bb:e5:91:ef:
- 83:36:eb:1d:56:6f:ca:da:bc:73:63:90:e4:7f:7b:3e:22:cb:
- 3d:07:ed:5f:38:74:9c:e3:03:50:4e:a1:af:98:ee:61:f2:84:
- 3f:12
------BEGIN CERTIFICATE-----
-MIIDfTCCAuagAwIBAgIDErvmMA0GCSqGSIb3DQEBBQUAME4xCzAJBgNVBAYTAlVT
-MRAwDgYDVQQKEwdFcXVpZmF4MS0wKwYDVQQLEyRFcXVpZmF4IFNlY3VyZSBDZXJ0
-aWZpY2F0ZSBBdXRob3JpdHkwHhcNMDIwNTIxMDQwMDAwWhcNMTgwODIxMDQwMDAw
-WjBCMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEbMBkGA1UE
-AxMSR2VvVHJ1c3QgR2xvYmFsIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
-CgKCAQEA2swYYzD99BcjGlZ+W988bDjkcbd4kdS8odhM+KhDtgPpTSEHCIjaWC9m
-OSm9BXiLnTjoBbdqfnGk5sRgprDvgOSJKA+eJdbtg/OtppHHmMlCGDUUna2YRpIu
-T8rxh0PBFpVXLVDviS2Aelet8u5fa9IAjbkU+BQVNdnARqN7csiRv8lVK83Qlz6c
-JmTM386DGXHKTubU1XupGc1V3sjs0l44U+VcT4wt/lAjNvxm5suOpDkZALeVAjmR
-Cw7+OC7RHQWa9k0+bw8HHa8sHo9gOeL6NlMTOdReJivbPagUvTLrGAMoUgRx5asz
-PeE4uwc2hGKceeoWMPRfwCvocWvk+QIDAQABo4HwMIHtMB8GA1UdIwQYMBaAFEjm
-aPkr0rKV10fYIyAQTzOYkJ/UMB0GA1UdDgQWBBTAephojYn7qwVkDBF9qn1luMrM
-TjAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjA6BgNVHR8EMzAxMC+g
-LaArhilodHRwOi8vY3JsLmdlb3RydXN0LmNvbS9jcmxzL3NlY3VyZWNhLmNybDBO
-BgNVHSAERzBFMEMGBFUdIAAwOzA5BggrBgEFBQcCARYtaHR0cHM6Ly93d3cuZ2Vv
-dHJ1c3QuY29tL3Jlc291cmNlcy9yZXBvc2l0b3J5MA0GCSqGSIb3DQEBBQUAA4GB
-AHbhEm5OSxYShjAGsoEIz/AIx8dxfmbuwu3UOx//8PDITtZDOLC5MH0Y0FWDomrL
-NhGc6Ehmo21/uBPUR/6LWlxz/K7ZGzIZOKuXNBSqltLroxwUCEm2u+WR74M26x1W
-b8ravHNjkOR/ez4iyz0H7V84dJzjA1BOoa+Y7mHyhD8S
------END CERTIFICATE-----
-#endif
-static const unsigned char kDERCert0[] = {
- 0x30, 0x82, 0x03, 0x7d, 0x30, 0x82, 0x02, 0xe6, 0xa0, 0x03, 0x02, 0x01,
- 0x02, 0x02, 0x03, 0x12, 0xbb, 0xe6, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
- 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x4e, 0x31,
- 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53,
- 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x07, 0x45,
- 0x71, 0x75, 0x69, 0x66, 0x61, 0x78, 0x31, 0x2d, 0x30, 0x2b, 0x06, 0x03,
- 0x55, 0x04, 0x0b, 0x13, 0x24, 0x45, 0x71, 0x75, 0x69, 0x66, 0x61, 0x78,
- 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74,
- 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68,
- 0x6f, 0x72, 0x69, 0x74, 0x79, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x32, 0x30,
- 0x35, 0x32, 0x31, 0x30, 0x34, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d,
- 0x31, 0x38, 0x30, 0x38, 0x32, 0x31, 0x30, 0x34, 0x30, 0x30, 0x30, 0x30,
- 0x5a, 0x30, 0x42, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06,
- 0x13, 0x02, 0x55, 0x53, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04,
- 0x0a, 0x13, 0x0d, 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20,
- 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04,
- 0x03, 0x13, 0x12, 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20,
- 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x20, 0x43, 0x41, 0x30, 0x82, 0x01,
- 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
- 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01,
- 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xda, 0xcc, 0x18, 0x63, 0x30, 0xfd,
- 0xf4, 0x17, 0x23, 0x1a, 0x56, 0x7e, 0x5b, 0xdf, 0x3c, 0x6c, 0x38, 0xe4,
- 0x71, 0xb7, 0x78, 0x91, 0xd4, 0xbc, 0xa1, 0xd8, 0x4c, 0xf8, 0xa8, 0x43,
- 0xb6, 0x03, 0xe9, 0x4d, 0x21, 0x07, 0x08, 0x88, 0xda, 0x58, 0x2f, 0x66,
- 0x39, 0x29, 0xbd, 0x05, 0x78, 0x8b, 0x9d, 0x38, 0xe8, 0x05, 0xb7, 0x6a,
- 0x7e, 0x71, 0xa4, 0xe6, 0xc4, 0x60, 0xa6, 0xb0, 0xef, 0x80, 0xe4, 0x89,
- 0x28, 0x0f, 0x9e, 0x25, 0xd6, 0xed, 0x83, 0xf3, 0xad, 0xa6, 0x91, 0xc7,
- 0x98, 0xc9, 0x42, 0x18, 0x35, 0x14, 0x9d, 0xad, 0x98, 0x46, 0x92, 0x2e,
- 0x4f, 0xca, 0xf1, 0x87, 0x43, 0xc1, 0x16, 0x95, 0x57, 0x2d, 0x50, 0xef,
- 0x89, 0x2d, 0x80, 0x7a, 0x57, 0xad, 0xf2, 0xee, 0x5f, 0x6b, 0xd2, 0x00,
- 0x8d, 0xb9, 0x14, 0xf8, 0x14, 0x15, 0x35, 0xd9, 0xc0, 0x46, 0xa3, 0x7b,
- 0x72, 0xc8, 0x91, 0xbf, 0xc9, 0x55, 0x2b, 0xcd, 0xd0, 0x97, 0x3e, 0x9c,
- 0x26, 0x64, 0xcc, 0xdf, 0xce, 0x83, 0x19, 0x71, 0xca, 0x4e, 0xe6, 0xd4,
- 0xd5, 0x7b, 0xa9, 0x19, 0xcd, 0x55, 0xde, 0xc8, 0xec, 0xd2, 0x5e, 0x38,
- 0x53, 0xe5, 0x5c, 0x4f, 0x8c, 0x2d, 0xfe, 0x50, 0x23, 0x36, 0xfc, 0x66,
- 0xe6, 0xcb, 0x8e, 0xa4, 0x39, 0x19, 0x00, 0xb7, 0x95, 0x02, 0x39, 0x91,
- 0x0b, 0x0e, 0xfe, 0x38, 0x2e, 0xd1, 0x1d, 0x05, 0x9a, 0xf6, 0x4d, 0x3e,
- 0x6f, 0x0f, 0x07, 0x1d, 0xaf, 0x2c, 0x1e, 0x8f, 0x60, 0x39, 0xe2, 0xfa,
- 0x36, 0x53, 0x13, 0x39, 0xd4, 0x5e, 0x26, 0x2b, 0xdb, 0x3d, 0xa8, 0x14,
- 0xbd, 0x32, 0xeb, 0x18, 0x03, 0x28, 0x52, 0x04, 0x71, 0xe5, 0xab, 0x33,
- 0x3d, 0xe1, 0x38, 0xbb, 0x07, 0x36, 0x84, 0x62, 0x9c, 0x79, 0xea, 0x16,
- 0x30, 0xf4, 0x5f, 0xc0, 0x2b, 0xe8, 0x71, 0x6b, 0xe4, 0xf9, 0x02, 0x03,
- 0x01, 0x00, 0x01, 0xa3, 0x81, 0xf0, 0x30, 0x81, 0xed, 0x30, 0x1f, 0x06,
- 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x48, 0xe6,
- 0x68, 0xf9, 0x2b, 0xd2, 0xb2, 0x95, 0xd7, 0x47, 0xd8, 0x23, 0x20, 0x10,
- 0x4f, 0x33, 0x98, 0x90, 0x9f, 0xd4, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d,
- 0x0e, 0x04, 0x16, 0x04, 0x14, 0xc0, 0x7a, 0x98, 0x68, 0x8d, 0x89, 0xfb,
- 0xab, 0x05, 0x64, 0x0c, 0x11, 0x7d, 0xaa, 0x7d, 0x65, 0xb8, 0xca, 0xcc,
- 0x4e, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04,
- 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d,
- 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x3a,
- 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x33, 0x30, 0x31, 0x30, 0x2f, 0xa0,
- 0x2d, 0xa0, 0x2b, 0x86, 0x29, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f,
- 0x63, 0x72, 0x6c, 0x2e, 0x67, 0x65, 0x6f, 0x74, 0x72, 0x75, 0x73, 0x74,
- 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x72, 0x6c, 0x73, 0x2f, 0x73, 0x65,
- 0x63, 0x75, 0x72, 0x65, 0x63, 0x61, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x4e,
- 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x47, 0x30, 0x45, 0x30, 0x43, 0x06,
- 0x04, 0x55, 0x1d, 0x20, 0x00, 0x30, 0x3b, 0x30, 0x39, 0x06, 0x08, 0x2b,
- 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x2d, 0x68, 0x74, 0x74,
- 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x67, 0x65, 0x6f,
- 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65,
- 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x2f, 0x72, 0x65, 0x70, 0x6f,
- 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
- 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x81, 0x81,
- 0x00, 0x76, 0xe1, 0x12, 0x6e, 0x4e, 0x4b, 0x16, 0x12, 0x86, 0x30, 0x06,
- 0xb2, 0x81, 0x08, 0xcf, 0xf0, 0x08, 0xc7, 0xc7, 0x71, 0x7e, 0x66, 0xee,
- 0xc2, 0xed, 0xd4, 0x3b, 0x1f, 0xff, 0xf0, 0xf0, 0xc8, 0x4e, 0xd6, 0x43,
- 0x38, 0xb0, 0xb9, 0x30, 0x7d, 0x18, 0xd0, 0x55, 0x83, 0xa2, 0x6a, 0xcb,
- 0x36, 0x11, 0x9c, 0xe8, 0x48, 0x66, 0xa3, 0x6d, 0x7f, 0xb8, 0x13, 0xd4,
- 0x47, 0xfe, 0x8b, 0x5a, 0x5c, 0x73, 0xfc, 0xae, 0xd9, 0x1b, 0x32, 0x19,
- 0x38, 0xab, 0x97, 0x34, 0x14, 0xaa, 0x96, 0xd2, 0xeb, 0xa3, 0x1c, 0x14,
- 0x08, 0x49, 0xb6, 0xbb, 0xe5, 0x91, 0xef, 0x83, 0x36, 0xeb, 0x1d, 0x56,
- 0x6f, 0xca, 0xda, 0xbc, 0x73, 0x63, 0x90, 0xe4, 0x7f, 0x7b, 0x3e, 0x22,
- 0xcb, 0x3d, 0x07, 0xed, 0x5f, 0x38, 0x74, 0x9c, 0xe3, 0x03, 0x50, 0x4e,
- 0xa1, 0xaf, 0x98, 0xee, 0x61, 0xf2, 0x84, 0x3f, 0x12,
-};
-
-#if 0
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number: 880226 (0xd6e62)
- Signature Algorithm: sha1WithRSAEncryption
- Issuer: C=US, O=Equifax, OU=Equifax Secure Certificate Authority
- Validity
- Not Before: Nov 27 00:00:00 2006 GMT
- Not After : Aug 21 16:15:00 2018 GMT
- Subject: C=US, O=GeoTrust Inc., CN=GeoTrust Primary Certification Authority
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:be:b8:15:7b:ff:d4:7c:7d:67:ad:83:64:7b:c8:
- 42:53:2d:df:f6:84:08:20:61:d6:01:59:6a:9c:44:
- 11:af:ef:76:fd:95:7e:ce:61:30:bb:7a:83:5f:02:
- bd:01:66:ca:ee:15:8d:6f:a1:30:9c:bd:a1:85:9e:
- 94:3a:f3:56:88:00:31:cf:d8:ee:6a:96:02:d9:ed:
- 03:8c:fb:75:6d:e7:ea:b8:55:16:05:16:9a:f4:e0:
- 5e:b1:88:c0:64:85:5c:15:4d:88:c7:b7:ba:e0:75:
- e9:ad:05:3d:9d:c7:89:48:e0:bb:28:c8:03:e1:30:
- 93:64:5e:52:c0:59:70:22:35:57:88:8a:f1:95:0a:
- 83:d7:bc:31:73:01:34:ed:ef:46:71:e0:6b:02:a8:
- 35:72:6b:97:9b:66:e0:cb:1c:79:5f:d8:1a:04:68:
- 1e:47:02:e6:9d:60:e2:36:97:01:df:ce:35:92:df:
- be:67:c7:6d:77:59:3b:8f:9d:d6:90:15:94:bc:42:
- 34:10:c1:39:f9:b1:27:3e:7e:d6:8a:75:c5:b2:af:
- 96:d3:a2:de:9b:e4:98:be:7d:e1:e9:81:ad:b6:6f:
- fc:d7:0e:da:e0:34:b0:0d:1a:77:e7:e3:08:98:ef:
- 58:fa:9c:84:b7:36:af:c2:df:ac:d2:f4:10:06:70:
- 71:35
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Key Usage: critical
- Certificate Sign, CRL Sign
- X509v3 Subject Key Identifier:
- 2C:D5:50:41:97:15:8B:F0:8F:36:61:5B:4A:FB:6B:D9:99:C9:33:92
- X509v3 Authority Key Identifier:
- keyid:48:E6:68:F9:2B:D2:B2:95:D7:47:D8:23:20:10:4F:33:98:90:9F:D4
-
- X509v3 Basic Constraints: critical
- CA:TRUE
- X509v3 CRL Distribution Points:
-
- Full Name:
- URI:http://crl.geotrust.com/crls/secureca.crl
-
- X509v3 Certificate Policies:
- Policy: X509v3 Any Policy
- CPS: http://www.geotrust.com/resources/cps
-
- Signature Algorithm: sha1WithRSAEncryption
- af:f3:0e:d6:72:ab:c7:a9:97:ca:2a:6b:84:39:de:79:a9:f0:
- 81:e5:08:67:ab:d7:2f:20:02:01:71:0c:04:22:c9:1e:88:95:
- 03:c9:49:3a:af:67:08:49:b0:d5:08:f5:20:3d:80:91:a0:c5:
- 87:a3:fb:c9:a3:17:91:f9:a8:2f:ae:e9:0f:df:96:72:0f:75:
- 17:80:5d:78:01:4d:9f:1f:6d:7b:d8:f5:42:38:23:1a:99:93:
- f4:83:be:3b:35:74:e7:37:13:35:7a:ac:b4:b6:90:82:6c:27:
- a4:e0:ec:9e:35:bd:bf:e5:29:a1:47:9f:5b:32:fc:e9:99:7d:
- 2b:39
------BEGIN CERTIFICATE-----
-MIIDizCCAvSgAwIBAgIDDW5iMA0GCSqGSIb3DQEBBQUAME4xCzAJBgNVBAYTAlVT
-MRAwDgYDVQQKEwdFcXVpZmF4MS0wKwYDVQQLEyRFcXVpZmF4IFNlY3VyZSBDZXJ0
-aWZpY2F0ZSBBdXRob3JpdHkwHhcNMDYxMTI3MDAwMDAwWhcNMTgwODIxMTYxNTAw
-WjBYMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjExMC8GA1UE
-AxMoR2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASIw
-DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL64FXv/1Hx9Z62DZHvIQlMt3/aE
-CCBh1gFZapxEEa/vdv2Vfs5hMLt6g18CvQFmyu4VjW+hMJy9oYWelDrzVogAMc/Y
-7mqWAtntA4z7dW3n6rhVFgUWmvTgXrGIwGSFXBVNiMe3uuB16a0FPZ3HiUjguyjI
-A+Ewk2ReUsBZcCI1V4iK8ZUKg9e8MXMBNO3vRnHgawKoNXJrl5tm4MsceV/YGgRo
-HkcC5p1g4jaXAd/ONZLfvmfHbXdZO4+d1pAVlLxCNBDBOfmxJz5+1op1xbKvltOi
-3pvkmL594emBrbZv/NcO2uA0sA0ad+fjCJjvWPqchLc2r8LfrNL0EAZwcTUCAwEA
-AaOB6DCB5TAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFCzVUEGXFYvwjzZhW0r7
-a9mZyTOSMB8GA1UdIwQYMBaAFEjmaPkr0rKV10fYIyAQTzOYkJ/UMA8GA1UdEwEB
-/wQFMAMBAf8wOgYDVR0fBDMwMTAvoC2gK4YpaHR0cDovL2NybC5nZW90cnVzdC5j
-b20vY3Jscy9zZWN1cmVjYS5jcmwwRgYDVR0gBD8wPTA7BgRVHSAAMDMwMQYIKwYB
-BQUHAgEWJWh0dHA6Ly93d3cuZ2VvdHJ1c3QuY29tL3Jlc291cmNlcy9jcHMwDQYJ
-KoZIhvcNAQEFBQADgYEAr/MO1nKrx6mXyiprhDneeanwgeUIZ6vXLyACAXEMBCLJ
-HoiVA8lJOq9nCEmw1Qj1ID2AkaDFh6P7yaMXkfmoL67pD9+Wcg91F4BdeAFNnx9t
-e9j1QjgjGpmT9IO+OzV05zcTNXqstLaQgmwnpODsnjW9v+UpoUefWzL86Zl9Kzk=
------END CERTIFICATE-----
-#endif
-static const unsigned char kDERCert1[] = {
- 0x30, 0x82, 0x03, 0x8b, 0x30, 0x82, 0x02, 0xf4, 0xa0, 0x03, 0x02, 0x01,
- 0x02, 0x02, 0x03, 0x0d, 0x6e, 0x62, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
- 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x4e, 0x31,
- 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53,
- 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x07, 0x45,
- 0x71, 0x75, 0x69, 0x66, 0x61, 0x78, 0x31, 0x2d, 0x30, 0x2b, 0x06, 0x03,
- 0x55, 0x04, 0x0b, 0x13, 0x24, 0x45, 0x71, 0x75, 0x69, 0x66, 0x61, 0x78,
- 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74,
- 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68,
- 0x6f, 0x72, 0x69, 0x74, 0x79, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x36, 0x31,
- 0x31, 0x32, 0x37, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d,
- 0x31, 0x38, 0x30, 0x38, 0x32, 0x31, 0x31, 0x36, 0x31, 0x35, 0x30, 0x30,
- 0x5a, 0x30, 0x58, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06,
- 0x13, 0x02, 0x55, 0x53, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04,
- 0x0a, 0x13, 0x0d, 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20,
- 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x31, 0x30, 0x2f, 0x06, 0x03, 0x55, 0x04,
- 0x03, 0x13, 0x28, 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20,
- 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x20, 0x43, 0x65, 0x72, 0x74,
- 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75,
- 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x30, 0x82, 0x01, 0x22, 0x30,
- 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01,
- 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02,
- 0x82, 0x01, 0x01, 0x00, 0xbe, 0xb8, 0x15, 0x7b, 0xff, 0xd4, 0x7c, 0x7d,
- 0x67, 0xad, 0x83, 0x64, 0x7b, 0xc8, 0x42, 0x53, 0x2d, 0xdf, 0xf6, 0x84,
- 0x08, 0x20, 0x61, 0xd6, 0x01, 0x59, 0x6a, 0x9c, 0x44, 0x11, 0xaf, 0xef,
- 0x76, 0xfd, 0x95, 0x7e, 0xce, 0x61, 0x30, 0xbb, 0x7a, 0x83, 0x5f, 0x02,
- 0xbd, 0x01, 0x66, 0xca, 0xee, 0x15, 0x8d, 0x6f, 0xa1, 0x30, 0x9c, 0xbd,
- 0xa1, 0x85, 0x9e, 0x94, 0x3a, 0xf3, 0x56, 0x88, 0x00, 0x31, 0xcf, 0xd8,
- 0xee, 0x6a, 0x96, 0x02, 0xd9, 0xed, 0x03, 0x8c, 0xfb, 0x75, 0x6d, 0xe7,
- 0xea, 0xb8, 0x55, 0x16, 0x05, 0x16, 0x9a, 0xf4, 0xe0, 0x5e, 0xb1, 0x88,
- 0xc0, 0x64, 0x85, 0x5c, 0x15, 0x4d, 0x88, 0xc7, 0xb7, 0xba, 0xe0, 0x75,
- 0xe9, 0xad, 0x05, 0x3d, 0x9d, 0xc7, 0x89, 0x48, 0xe0, 0xbb, 0x28, 0xc8,
- 0x03, 0xe1, 0x30, 0x93, 0x64, 0x5e, 0x52, 0xc0, 0x59, 0x70, 0x22, 0x35,
- 0x57, 0x88, 0x8a, 0xf1, 0x95, 0x0a, 0x83, 0xd7, 0xbc, 0x31, 0x73, 0x01,
- 0x34, 0xed, 0xef, 0x46, 0x71, 0xe0, 0x6b, 0x02, 0xa8, 0x35, 0x72, 0x6b,
- 0x97, 0x9b, 0x66, 0xe0, 0xcb, 0x1c, 0x79, 0x5f, 0xd8, 0x1a, 0x04, 0x68,
- 0x1e, 0x47, 0x02, 0xe6, 0x9d, 0x60, 0xe2, 0x36, 0x97, 0x01, 0xdf, 0xce,
- 0x35, 0x92, 0xdf, 0xbe, 0x67, 0xc7, 0x6d, 0x77, 0x59, 0x3b, 0x8f, 0x9d,
- 0xd6, 0x90, 0x15, 0x94, 0xbc, 0x42, 0x34, 0x10, 0xc1, 0x39, 0xf9, 0xb1,
- 0x27, 0x3e, 0x7e, 0xd6, 0x8a, 0x75, 0xc5, 0xb2, 0xaf, 0x96, 0xd3, 0xa2,
- 0xde, 0x9b, 0xe4, 0x98, 0xbe, 0x7d, 0xe1, 0xe9, 0x81, 0xad, 0xb6, 0x6f,
- 0xfc, 0xd7, 0x0e, 0xda, 0xe0, 0x34, 0xb0, 0x0d, 0x1a, 0x77, 0xe7, 0xe3,
- 0x08, 0x98, 0xef, 0x58, 0xfa, 0x9c, 0x84, 0xb7, 0x36, 0xaf, 0xc2, 0xdf,
- 0xac, 0xd2, 0xf4, 0x10, 0x06, 0x70, 0x71, 0x35, 0x02, 0x03, 0x01, 0x00,
- 0x01, 0xa3, 0x81, 0xe8, 0x30, 0x81, 0xe5, 0x30, 0x0e, 0x06, 0x03, 0x55,
- 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30,
- 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x2c, 0xd5,
- 0x50, 0x41, 0x97, 0x15, 0x8b, 0xf0, 0x8f, 0x36, 0x61, 0x5b, 0x4a, 0xfb,
- 0x6b, 0xd9, 0x99, 0xc9, 0x33, 0x92, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d,
- 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x48, 0xe6, 0x68, 0xf9, 0x2b,
- 0xd2, 0xb2, 0x95, 0xd7, 0x47, 0xd8, 0x23, 0x20, 0x10, 0x4f, 0x33, 0x98,
- 0x90, 0x9f, 0xd4, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01,
- 0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x3a, 0x06, 0x03,
- 0x55, 0x1d, 0x1f, 0x04, 0x33, 0x30, 0x31, 0x30, 0x2f, 0xa0, 0x2d, 0xa0,
- 0x2b, 0x86, 0x29, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72,
- 0x6c, 0x2e, 0x67, 0x65, 0x6f, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63,
- 0x6f, 0x6d, 0x2f, 0x63, 0x72, 0x6c, 0x73, 0x2f, 0x73, 0x65, 0x63, 0x75,
- 0x72, 0x65, 0x63, 0x61, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x46, 0x06, 0x03,
- 0x55, 0x1d, 0x20, 0x04, 0x3f, 0x30, 0x3d, 0x30, 0x3b, 0x06, 0x04, 0x55,
- 0x1d, 0x20, 0x00, 0x30, 0x33, 0x30, 0x31, 0x06, 0x08, 0x2b, 0x06, 0x01,
- 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x25, 0x68, 0x74, 0x74, 0x70, 0x3a,
- 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x67, 0x65, 0x6f, 0x74, 0x72, 0x75,
- 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75,
- 0x72, 0x63, 0x65, 0x73, 0x2f, 0x63, 0x70, 0x73, 0x30, 0x0d, 0x06, 0x09,
- 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03,
- 0x81, 0x81, 0x00, 0xaf, 0xf3, 0x0e, 0xd6, 0x72, 0xab, 0xc7, 0xa9, 0x97,
- 0xca, 0x2a, 0x6b, 0x84, 0x39, 0xde, 0x79, 0xa9, 0xf0, 0x81, 0xe5, 0x08,
- 0x67, 0xab, 0xd7, 0x2f, 0x20, 0x02, 0x01, 0x71, 0x0c, 0x04, 0x22, 0xc9,
- 0x1e, 0x88, 0x95, 0x03, 0xc9, 0x49, 0x3a, 0xaf, 0x67, 0x08, 0x49, 0xb0,
- 0xd5, 0x08, 0xf5, 0x20, 0x3d, 0x80, 0x91, 0xa0, 0xc5, 0x87, 0xa3, 0xfb,
- 0xc9, 0xa3, 0x17, 0x91, 0xf9, 0xa8, 0x2f, 0xae, 0xe9, 0x0f, 0xdf, 0x96,
- 0x72, 0x0f, 0x75, 0x17, 0x80, 0x5d, 0x78, 0x01, 0x4d, 0x9f, 0x1f, 0x6d,
- 0x7b, 0xd8, 0xf5, 0x42, 0x38, 0x23, 0x1a, 0x99, 0x93, 0xf4, 0x83, 0xbe,
- 0x3b, 0x35, 0x74, 0xe7, 0x37, 0x13, 0x35, 0x7a, 0xac, 0xb4, 0xb6, 0x90,
- 0x82, 0x6c, 0x27, 0xa4, 0xe0, 0xec, 0x9e, 0x35, 0xbd, 0xbf, 0xe5, 0x29,
- 0xa1, 0x47, 0x9f, 0x5b, 0x32, 0xfc, 0xe9, 0x99, 0x7d, 0x2b, 0x39,
-};
-
-#if 0
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number: 146066 (0x23a92)
- Signature Algorithm: sha256WithRSAEncryption
- Issuer: C=US, O=GeoTrust Inc., CN=GeoTrust Global CA
- Validity
- Not Before: Apr 1 00:00:00 2015 GMT
- Not After : Dec 31 23:59:59 2017 GMT
- Subject: C=US, O=Google Inc, CN=Google Internet Authority G2
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:9c:2a:04:77:5c:d8:50:91:3a:06:a3:82:e0:d8:
- 50:48:bc:89:3f:f1:19:70:1a:88:46:7e:e0:8f:c5:
- f1:89:ce:21:ee:5a:fe:61:0d:b7:32:44:89:a0:74:
- 0b:53:4f:55:a4:ce:82:62:95:ee:eb:59:5f:c6:e1:
- 05:80:12:c4:5e:94:3f:bc:5b:48:38:f4:53:f7:24:
- e6:fb:91:e9:15:c4:cf:f4:53:0d:f4:4a:fc:9f:54:
- de:7d:be:a0:6b:6f:87:c0:d0:50:1f:28:30:03:40:
- da:08:73:51:6c:7f:ff:3a:3c:a7:37:06:8e:bd:4b:
- 11:04:eb:7d:24:de:e6:f9:fc:31:71:fb:94:d5:60:
- f3:2e:4a:af:42:d2:cb:ea:c4:6a:1a:b2:cc:53:dd:
- 15:4b:8b:1f:c8:19:61:1f:cd:9d:a8:3e:63:2b:84:
- 35:69:65:84:c8:19:c5:46:22:f8:53:95:be:e3:80:
- 4a:10:c6:2a:ec:ba:97:20:11:c7:39:99:10:04:a0:
- f0:61:7a:95:25:8c:4e:52:75:e2:b6:ed:08:ca:14:
- fc:ce:22:6a:b3:4e:cf:46:03:97:97:03:7e:c0:b1:
- de:7b:af:45:33:cf:ba:3e:71:b7:de:f4:25:25:c2:
- 0d:35:89:9d:9d:fb:0e:11:79:89:1e:37:c5:af:8e:
- 72:69
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Authority Key Identifier:
- keyid:C0:7A:98:68:8D:89:FB:AB:05:64:0C:11:7D:AA:7D:65:B8:CA:CC:4E
-
- X509v3 Subject Key Identifier:
- 4A:DD:06:16:1B:BC:F6:68:B5:76:F5:81:B6:BB:62:1A:BA:5A:81:2F
- X509v3 Key Usage: critical
- Certificate Sign, CRL Sign
- Authority Information Access:
- OCSP - URI:http://g.symcd.com
-
- X509v3 Basic Constraints: critical
- CA:TRUE, pathlen:0
- X509v3 CRL Distribution Points:
-
- Full Name:
- URI:http://g.symcb.com/crls/gtglobal.crl
-
- X509v3 Certificate Policies:
- Policy: 1.3.6.1.4.1.11129.2.5.1
-
- Signature Algorithm: sha256WithRSAEncryption
- 08:4e:04:a7:80:7f:10:16:43:5e:02:ad:d7:42:80:f4:b0:8e:
- d2:ae:b3:eb:11:7d:90:84:18:7d:e7:90:15:fb:49:7f:a8:99:
- 05:91:bb:7a:c9:d6:3c:37:18:09:9a:b6:c7:92:20:07:35:33:
- 09:e4:28:63:72:0d:b4:e0:32:9c:87:98:c4:1b:76:89:67:c1:
- 50:58:b0:13:aa:13:1a:1b:32:a5:be:ea:11:95:4c:48:63:49:
- e9:99:5d:20:37:cc:fe:2a:69:51:16:95:4b:a9:de:49:82:c0:
- 10:70:f4:2c:f3:ec:bc:24:24:d0:4e:ac:a5:d9:5e:1e:6d:92:
- c1:a7:ac:48:35:81:f9:e5:e4:9c:65:69:cd:87:a4:41:50:3f:
- 2e:57:a5:91:51:12:58:0e:8c:09:a1:ac:7a:a4:12:a5:27:f3:
- 9a:10:97:7d:55:03:06:f7:66:58:5f:5f:64:e1:ab:5d:6d:a5:
- 39:48:75:98:4c:29:5a:3a:8d:d3:2b:ca:9c:55:04:bf:f4:e6:
- 14:d5:80:ac:26:ed:17:89:a6:93:6c:5c:a4:cc:b8:f0:66:8e:
- 64:e3:7d:9a:e2:00:b3:49:c7:e4:0a:aa:dd:5b:83:c7:70:90:
- 46:4e:be:d0:db:59:96:6c:2e:f5:16:36:de:71:cc:01:c2:12:
- c1:21:c6:16
------BEGIN CERTIFICATE-----
-MIID8DCCAtigAwIBAgIDAjqSMA0GCSqGSIb3DQEBCwUAMEIxCzAJBgNVBAYTAlVT
-MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i
-YWwgQ0EwHhcNMTUwNDAxMDAwMDAwWhcNMTcxMjMxMjM1OTU5WjBJMQswCQYDVQQG
-EwJVUzETMBEGA1UEChMKR29vZ2xlIEluYzElMCMGA1UEAxMcR29vZ2xlIEludGVy
-bmV0IEF1dGhvcml0eSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
-AJwqBHdc2FCROgajguDYUEi8iT/xGXAaiEZ+4I/F8YnOIe5a/mENtzJEiaB0C1NP
-VaTOgmKV7utZX8bhBYASxF6UP7xbSDj0U/ck5vuR6RXEz/RTDfRK/J9U3n2+oGtv
-h8DQUB8oMANA2ghzUWx//zo8pzcGjr1LEQTrfSTe5vn8MXH7lNVg8y5Kr0LSy+rE
-ahqyzFPdFUuLH8gZYR/Nnag+YyuENWllhMgZxUYi+FOVvuOAShDGKuy6lyARxzmZ
-EASg8GF6lSWMTlJ14rbtCMoU/M4iarNOz0YDl5cDfsCx3nuvRTPPuj5xt970JSXC
-DTWJnZ37DhF5iR43xa+OcmkCAwEAAaOB5zCB5DAfBgNVHSMEGDAWgBTAephojYn7
-qwVkDBF9qn1luMrMTjAdBgNVHQ4EFgQUSt0GFhu89mi1dvWBtrtiGrpagS8wDgYD
-VR0PAQH/BAQDAgEGMC4GCCsGAQUFBwEBBCIwIDAeBggrBgEFBQcwAYYSaHR0cDov
-L2cuc3ltY2QuY29tMBIGA1UdEwEB/wQIMAYBAf8CAQAwNQYDVR0fBC4wLDAqoCig
-JoYkaHR0cDovL2cuc3ltY2IuY29tL2NybHMvZ3RnbG9iYWwuY3JsMBcGA1UdIAQQ
-MA4wDAYKKwYBBAHWeQIFATANBgkqhkiG9w0BAQsFAAOCAQEACE4Ep4B/EBZDXgKt
-10KA9LCO0q6z6xF9kIQYfeeQFftJf6iZBZG7esnWPDcYCZq2x5IgBzUzCeQoY3IN
-tOAynIeYxBt2iWfBUFiwE6oTGhsypb7qEZVMSGNJ6ZldIDfM/ippURaVS6neSYLA
-EHD0LPPsvCQk0E6spdleHm2SwaesSDWB+eXknGVpzYekQVA/LlelkVESWA6MCaGs
-eqQSpSfzmhCXfVUDBvdmWF9fZOGrXW2lOUh1mEwpWjqN0yvKnFUEv/TmFNWArCbt
-F4mmk2xcpMy48GaOZON9muIAs0nH5Aqq3VuDx3CQRk6+0NtZlmwu9RY23nHMAcIS
-wSHGFg==
------END CERTIFICATE-----
-#endif
-static const unsigned char kDERCert2[] = {
- 0x30, 0x82, 0x03, 0xf0, 0x30, 0x82, 0x02, 0xd8, 0xa0, 0x03, 0x02, 0x01,
- 0x02, 0x02, 0x03, 0x02, 0x3a, 0x92, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
- 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x42, 0x31,
- 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53,
- 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0d, 0x47,
- 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x49, 0x6e, 0x63, 0x2e,
- 0x31, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x12, 0x47,
- 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x47, 0x6c, 0x6f, 0x62,
- 0x61, 0x6c, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x35, 0x30,
- 0x34, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d,
- 0x31, 0x37, 0x31, 0x32, 0x33, 0x31, 0x32, 0x33, 0x35, 0x39, 0x35, 0x39,
- 0x5a, 0x30, 0x49, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06,
- 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04,
- 0x0a, 0x13, 0x0a, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x20, 0x49, 0x6e,
- 0x63, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x1c,
- 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x74, 0x65, 0x72,
- 0x6e, 0x65, 0x74, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74,
- 0x79, 0x20, 0x47, 0x32, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09,
- 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03,
- 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01,
- 0x00, 0x9c, 0x2a, 0x04, 0x77, 0x5c, 0xd8, 0x50, 0x91, 0x3a, 0x06, 0xa3,
- 0x82, 0xe0, 0xd8, 0x50, 0x48, 0xbc, 0x89, 0x3f, 0xf1, 0x19, 0x70, 0x1a,
- 0x88, 0x46, 0x7e, 0xe0, 0x8f, 0xc5, 0xf1, 0x89, 0xce, 0x21, 0xee, 0x5a,
- 0xfe, 0x61, 0x0d, 0xb7, 0x32, 0x44, 0x89, 0xa0, 0x74, 0x0b, 0x53, 0x4f,
- 0x55, 0xa4, 0xce, 0x82, 0x62, 0x95, 0xee, 0xeb, 0x59, 0x5f, 0xc6, 0xe1,
- 0x05, 0x80, 0x12, 0xc4, 0x5e, 0x94, 0x3f, 0xbc, 0x5b, 0x48, 0x38, 0xf4,
- 0x53, 0xf7, 0x24, 0xe6, 0xfb, 0x91, 0xe9, 0x15, 0xc4, 0xcf, 0xf4, 0x53,
- 0x0d, 0xf4, 0x4a, 0xfc, 0x9f, 0x54, 0xde, 0x7d, 0xbe, 0xa0, 0x6b, 0x6f,
- 0x87, 0xc0, 0xd0, 0x50, 0x1f, 0x28, 0x30, 0x03, 0x40, 0xda, 0x08, 0x73,
- 0x51, 0x6c, 0x7f, 0xff, 0x3a, 0x3c, 0xa7, 0x37, 0x06, 0x8e, 0xbd, 0x4b,
- 0x11, 0x04, 0xeb, 0x7d, 0x24, 0xde, 0xe6, 0xf9, 0xfc, 0x31, 0x71, 0xfb,
- 0x94, 0xd5, 0x60, 0xf3, 0x2e, 0x4a, 0xaf, 0x42, 0xd2, 0xcb, 0xea, 0xc4,
- 0x6a, 0x1a, 0xb2, 0xcc, 0x53, 0xdd, 0x15, 0x4b, 0x8b, 0x1f, 0xc8, 0x19,
- 0x61, 0x1f, 0xcd, 0x9d, 0xa8, 0x3e, 0x63, 0x2b, 0x84, 0x35, 0x69, 0x65,
- 0x84, 0xc8, 0x19, 0xc5, 0x46, 0x22, 0xf8, 0x53, 0x95, 0xbe, 0xe3, 0x80,
- 0x4a, 0x10, 0xc6, 0x2a, 0xec, 0xba, 0x97, 0x20, 0x11, 0xc7, 0x39, 0x99,
- 0x10, 0x04, 0xa0, 0xf0, 0x61, 0x7a, 0x95, 0x25, 0x8c, 0x4e, 0x52, 0x75,
- 0xe2, 0xb6, 0xed, 0x08, 0xca, 0x14, 0xfc, 0xce, 0x22, 0x6a, 0xb3, 0x4e,
- 0xcf, 0x46, 0x03, 0x97, 0x97, 0x03, 0x7e, 0xc0, 0xb1, 0xde, 0x7b, 0xaf,
- 0x45, 0x33, 0xcf, 0xba, 0x3e, 0x71, 0xb7, 0xde, 0xf4, 0x25, 0x25, 0xc2,
- 0x0d, 0x35, 0x89, 0x9d, 0x9d, 0xfb, 0x0e, 0x11, 0x79, 0x89, 0x1e, 0x37,
- 0xc5, 0xaf, 0x8e, 0x72, 0x69, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x81,
- 0xe7, 0x30, 0x81, 0xe4, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04,
- 0x18, 0x30, 0x16, 0x80, 0x14, 0xc0, 0x7a, 0x98, 0x68, 0x8d, 0x89, 0xfb,
- 0xab, 0x05, 0x64, 0x0c, 0x11, 0x7d, 0xaa, 0x7d, 0x65, 0xb8, 0xca, 0xcc,
- 0x4e, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14,
- 0x4a, 0xdd, 0x06, 0x16, 0x1b, 0xbc, 0xf6, 0x68, 0xb5, 0x76, 0xf5, 0x81,
- 0xb6, 0xbb, 0x62, 0x1a, 0xba, 0x5a, 0x81, 0x2f, 0x30, 0x0e, 0x06, 0x03,
- 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06,
- 0x30, 0x2e, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01,
- 0x04, 0x22, 0x30, 0x20, 0x30, 0x1e, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05,
- 0x05, 0x07, 0x30, 0x01, 0x86, 0x12, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f,
- 0x2f, 0x67, 0x2e, 0x73, 0x79, 0x6d, 0x63, 0x64, 0x2e, 0x63, 0x6f, 0x6d,
- 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08,
- 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x00, 0x30, 0x35, 0x06, 0x03,
- 0x55, 0x1d, 0x1f, 0x04, 0x2e, 0x30, 0x2c, 0x30, 0x2a, 0xa0, 0x28, 0xa0,
- 0x26, 0x86, 0x24, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x67, 0x2e,
- 0x73, 0x79, 0x6d, 0x63, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x72,
- 0x6c, 0x73, 0x2f, 0x67, 0x74, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x2e,
- 0x63, 0x72, 0x6c, 0x30, 0x17, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x10,
- 0x30, 0x0e, 0x30, 0x0c, 0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01, 0xd6,
- 0x79, 0x02, 0x05, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
- 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00,
- 0x08, 0x4e, 0x04, 0xa7, 0x80, 0x7f, 0x10, 0x16, 0x43, 0x5e, 0x02, 0xad,
- 0xd7, 0x42, 0x80, 0xf4, 0xb0, 0x8e, 0xd2, 0xae, 0xb3, 0xeb, 0x11, 0x7d,
- 0x90, 0x84, 0x18, 0x7d, 0xe7, 0x90, 0x15, 0xfb, 0x49, 0x7f, 0xa8, 0x99,
- 0x05, 0x91, 0xbb, 0x7a, 0xc9, 0xd6, 0x3c, 0x37, 0x18, 0x09, 0x9a, 0xb6,
- 0xc7, 0x92, 0x20, 0x07, 0x35, 0x33, 0x09, 0xe4, 0x28, 0x63, 0x72, 0x0d,
- 0xb4, 0xe0, 0x32, 0x9c, 0x87, 0x98, 0xc4, 0x1b, 0x76, 0x89, 0x67, 0xc1,
- 0x50, 0x58, 0xb0, 0x13, 0xaa, 0x13, 0x1a, 0x1b, 0x32, 0xa5, 0xbe, 0xea,
- 0x11, 0x95, 0x4c, 0x48, 0x63, 0x49, 0xe9, 0x99, 0x5d, 0x20, 0x37, 0xcc,
- 0xfe, 0x2a, 0x69, 0x51, 0x16, 0x95, 0x4b, 0xa9, 0xde, 0x49, 0x82, 0xc0,
- 0x10, 0x70, 0xf4, 0x2c, 0xf3, 0xec, 0xbc, 0x24, 0x24, 0xd0, 0x4e, 0xac,
- 0xa5, 0xd9, 0x5e, 0x1e, 0x6d, 0x92, 0xc1, 0xa7, 0xac, 0x48, 0x35, 0x81,
- 0xf9, 0xe5, 0xe4, 0x9c, 0x65, 0x69, 0xcd, 0x87, 0xa4, 0x41, 0x50, 0x3f,
- 0x2e, 0x57, 0xa5, 0x91, 0x51, 0x12, 0x58, 0x0e, 0x8c, 0x09, 0xa1, 0xac,
- 0x7a, 0xa4, 0x12, 0xa5, 0x27, 0xf3, 0x9a, 0x10, 0x97, 0x7d, 0x55, 0x03,
- 0x06, 0xf7, 0x66, 0x58, 0x5f, 0x5f, 0x64, 0xe1, 0xab, 0x5d, 0x6d, 0xa5,
- 0x39, 0x48, 0x75, 0x98, 0x4c, 0x29, 0x5a, 0x3a, 0x8d, 0xd3, 0x2b, 0xca,
- 0x9c, 0x55, 0x04, 0xbf, 0xf4, 0xe6, 0x14, 0xd5, 0x80, 0xac, 0x26, 0xed,
- 0x17, 0x89, 0xa6, 0x93, 0x6c, 0x5c, 0xa4, 0xcc, 0xb8, 0xf0, 0x66, 0x8e,
- 0x64, 0xe3, 0x7d, 0x9a, 0xe2, 0x00, 0xb3, 0x49, 0xc7, 0xe4, 0x0a, 0xaa,
- 0xdd, 0x5b, 0x83, 0xc7, 0x70, 0x90, 0x46, 0x4e, 0xbe, 0xd0, 0xdb, 0x59,
- 0x96, 0x6c, 0x2e, 0xf5, 0x16, 0x36, 0xde, 0x71, 0xcc, 0x01, 0xc2, 0x12,
- 0xc1, 0x21, 0xc6, 0x16,
-};
-
-#if 0
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number: 120033005 (0x7278eed)
- Signature Algorithm: sha1WithRSAEncryption
- Issuer: C=US, O=GTE Corporation, OU=GTE CyberTrust Solutions, Inc., CN=GTE CyberTrust Global Root
- Validity
- Not Before: Apr 18 16:36:18 2012 GMT
- Not After : Aug 13 16:35:17 2018 GMT
- Subject: C=IE, O=Baltimore, OU=CyberTrust, CN=Baltimore CyberTrust Root
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:a3:04:bb:22:ab:98:3d:57:e8:26:72:9a:b5:79:
- d4:29:e2:e1:e8:95:80:b1:b0:e3:5b:8e:2b:29:9a:
- 64:df:a1:5d:ed:b0:09:05:6d:db:28:2e:ce:62:a2:
- 62:fe:b4:88:da:12:eb:38:eb:21:9d:c0:41:2b:01:
- 52:7b:88:77:d3:1c:8f:c7:ba:b9:88:b5:6a:09:e7:
- 73:e8:11:40:a7:d1:cc:ca:62:8d:2d:e5:8f:0b:a6:
- 50:d2:a8:50:c3:28:ea:f5:ab:25:87:8a:9a:96:1c:
- a9:67:b8:3f:0c:d5:f7:f9:52:13:2f:c2:1b:d5:70:
- 70:f0:8f:c0:12:ca:06:cb:9a:e1:d9:ca:33:7a:77:
- d6:f8:ec:b9:f1:68:44:42:48:13:d2:c0:c2:a4:ae:
- 5e:60:fe:b6:a6:05:fc:b4:dd:07:59:02:d4:59:18:
- 98:63:f5:a5:63:e0:90:0c:7d:5d:b2:06:7a:f3:85:
- ea:eb:d4:03:ae:5e:84:3e:5f:ff:15:ed:69:bc:f9:
- 39:36:72:75:cf:77:52:4d:f3:c9:90:2c:b9:3d:e5:
- c9:23:53:3f:1f:24:98:21:5c:07:99:29:bd:c6:3a:
- ec:e7:6e:86:3a:6b:97:74:63:33:bd:68:18:31:f0:
- 78:8d:76:bf:fc:9e:8e:5d:2a:86:a7:4d:90:dc:27:
- 1a:39
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Basic Constraints: critical
- CA:TRUE, pathlen:3
- X509v3 Certificate Policies:
- Policy: X509v3 Any Policy
- CPS: http://cybertrust.omniroot.com/repository
-
- X509v3 Key Usage: critical
- Certificate Sign, CRL Sign
- X509v3 Authority Key Identifier:
- DirName:/C=US/O=GTE Corporation/OU=GTE CyberTrust Solutions, Inc./CN=GTE CyberTrust Global Root
- serial:01:A5
-
- X509v3 CRL Distribution Points:
-
- Full Name:
- URI:http://www.public-trust.com/cgi-bin/CRL/2018/cdp.crl
-
- Signature Algorithm: sha1WithRSAEncryption
- 93:1d:fe:8b:ae:46:ec:cb:a9:0f:ab:e5:ef:ca:b2:68:16:68:
- d8:8f:fa:13:a9:af:b3:cb:2d:e7:4b:6e:8e:69:2a:c2:2b:10:
- 0a:8d:f6:ae:73:b6:b9:fb:14:fd:5f:6d:b8:50:b6:c4:8a:d6:
- 40:7e:d7:c3:cb:73:dc:c9:5d:5b:af:b0:41:b5:37:eb:ea:dc:
- 20:91:c4:34:6a:f4:a1:f3:96:9d:37:86:97:e1:71:a4:dd:7d:
- fa:44:84:94:ae:d7:09:04:22:76:0f:64:51:35:a9:24:0f:f9:
- 0b:db:32:da:c2:fe:c1:b9:2a:5c:7a:27:13:ca:b1:48:3a:71:
- d0:43
------BEGIN CERTIFICATE-----
-MIIEFTCCA36gAwIBAgIEByeO7TANBgkqhkiG9w0BAQUFADB1MQswCQYDVQQGEwJV
-UzEYMBYGA1UEChMPR1RFIENvcnBvcmF0aW9uMScwJQYDVQQLEx5HVEUgQ3liZXJU
-cnVzdCBTb2x1dGlvbnMsIEluYy4xIzAhBgNVBAMTGkdURSBDeWJlclRydXN0IEds
-b2JhbCBSb290MB4XDTEyMDQxODE2MzYxOFoXDTE4MDgxMzE2MzUxN1owWjELMAkG
-A1UEBhMCSUUxEjAQBgNVBAoTCUJhbHRpbW9yZTETMBEGA1UECxMKQ3liZXJUcnVz
-dDEiMCAGA1UEAxMZQmFsdGltb3JlIEN5YmVyVHJ1c3QgUm9vdDCCASIwDQYJKoZI
-hvcNAQEBBQADggEPADCCAQoCggEBAKMEuyKrmD1X6CZymrV51Cni4eiVgLGw41uO
-KymaZN+hXe2wCQVt2yguzmKiYv60iNoS6zjrIZ3AQSsBUnuId9Mcj8e6uYi1agnn
-c+gRQKfRzMpijS3ljwumUNKoUMMo6vWrJYeKmpYcqWe4PwzV9/lSEy/CG9VwcPCP
-wBLKBsua4dnKM3p31vjsufFoREJIE9LAwqSuXmD+tqYF/LTdB1kC1FkYmGP1pWPg
-kAx9XbIGevOF6uvUA65ehD5f/xXtabz5OTZydc93Uk3zyZAsuT3lySNTPx8kmCFc
-B5kpvcY67Oduhjprl3RjM71oGDHweI12v/yejl0qhqdNkNwnGjkCAwEAAaOCAUcw
-ggFDMBIGA1UdEwEB/wQIMAYBAf8CAQMwSgYDVR0gBEMwQTA/BgRVHSAAMDcwNQYI
-KwYBBQUHAgEWKWh0dHA6Ly9jeWJlcnRydXN0Lm9tbmlyb290LmNvbS9yZXBvc2l0
-b3J5MA4GA1UdDwEB/wQEAwIBBjCBiQYDVR0jBIGBMH+heaR3MHUxCzAJBgNVBAYT
-AlVTMRgwFgYDVQQKEw9HVEUgQ29ycG9yYXRpb24xJzAlBgNVBAsTHkdURSBDeWJl
-clRydXN0IFNvbHV0aW9ucywgSW5jLjEjMCEGA1UEAxMaR1RFIEN5YmVyVHJ1c3Qg
-R2xvYmFsIFJvb3SCAgGlMEUGA1UdHwQ+MDwwOqA4oDaGNGh0dHA6Ly93d3cucHVi
-bGljLXRydXN0LmNvbS9jZ2ktYmluL0NSTC8yMDE4L2NkcC5jcmwwDQYJKoZIhvcN
-AQEFBQADgYEAkx3+i65G7MupD6vl78qyaBZo2I/6E6mvs8st50tujmkqwisQCo32
-rnO2ufsU/V9tuFC2xIrWQH7Xw8tz3MldW6+wQbU36+rcIJHENGr0ofOWnTeGl+Fx
-pN19+kSElK7XCQQidg9kUTWpJA/5C9sy2sL+wbkqXHonE8qxSDpx0EM=
------END CERTIFICATE-----
-#endif
-static const unsigned char kDERCert3[] = {
- 0x30, 0x82, 0x04, 0x15, 0x30, 0x82, 0x03, 0x7e, 0xa0, 0x03, 0x02, 0x01,
- 0x02, 0x02, 0x04, 0x07, 0x27, 0x8e, 0xed, 0x30, 0x0d, 0x06, 0x09, 0x2a,
- 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x75,
- 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55,
- 0x53, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0f,
- 0x47, 0x54, 0x45, 0x20, 0x43, 0x6f, 0x72, 0x70, 0x6f, 0x72, 0x61, 0x74,
- 0x69, 0x6f, 0x6e, 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x0b,
- 0x13, 0x1e, 0x47, 0x54, 0x45, 0x20, 0x43, 0x79, 0x62, 0x65, 0x72, 0x54,
- 0x72, 0x75, 0x73, 0x74, 0x20, 0x53, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f,
- 0x6e, 0x73, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x23, 0x30, 0x21,
- 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x1a, 0x47, 0x54, 0x45, 0x20, 0x43,
- 0x79, 0x62, 0x65, 0x72, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x47, 0x6c,
- 0x6f, 0x62, 0x61, 0x6c, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x30, 0x1e, 0x17,
- 0x0d, 0x31, 0x32, 0x30, 0x34, 0x31, 0x38, 0x31, 0x36, 0x33, 0x36, 0x31,
- 0x38, 0x5a, 0x17, 0x0d, 0x31, 0x38, 0x30, 0x38, 0x31, 0x33, 0x31, 0x36,
- 0x33, 0x35, 0x31, 0x37, 0x5a, 0x30, 0x5a, 0x31, 0x0b, 0x30, 0x09, 0x06,
- 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x49, 0x45, 0x31, 0x12, 0x30, 0x10,
- 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x09, 0x42, 0x61, 0x6c, 0x74, 0x69,
- 0x6d, 0x6f, 0x72, 0x65, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04,
- 0x0b, 0x13, 0x0a, 0x43, 0x79, 0x62, 0x65, 0x72, 0x54, 0x72, 0x75, 0x73,
- 0x74, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x19,
- 0x42, 0x61, 0x6c, 0x74, 0x69, 0x6d, 0x6f, 0x72, 0x65, 0x20, 0x43, 0x79,
- 0x62, 0x65, 0x72, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x52, 0x6f, 0x6f,
- 0x74, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48,
- 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f,
- 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xa3, 0x04,
- 0xbb, 0x22, 0xab, 0x98, 0x3d, 0x57, 0xe8, 0x26, 0x72, 0x9a, 0xb5, 0x79,
- 0xd4, 0x29, 0xe2, 0xe1, 0xe8, 0x95, 0x80, 0xb1, 0xb0, 0xe3, 0x5b, 0x8e,
- 0x2b, 0x29, 0x9a, 0x64, 0xdf, 0xa1, 0x5d, 0xed, 0xb0, 0x09, 0x05, 0x6d,
- 0xdb, 0x28, 0x2e, 0xce, 0x62, 0xa2, 0x62, 0xfe, 0xb4, 0x88, 0xda, 0x12,
- 0xeb, 0x38, 0xeb, 0x21, 0x9d, 0xc0, 0x41, 0x2b, 0x01, 0x52, 0x7b, 0x88,
- 0x77, 0xd3, 0x1c, 0x8f, 0xc7, 0xba, 0xb9, 0x88, 0xb5, 0x6a, 0x09, 0xe7,
- 0x73, 0xe8, 0x11, 0x40, 0xa7, 0xd1, 0xcc, 0xca, 0x62, 0x8d, 0x2d, 0xe5,
- 0x8f, 0x0b, 0xa6, 0x50, 0xd2, 0xa8, 0x50, 0xc3, 0x28, 0xea, 0xf5, 0xab,
- 0x25, 0x87, 0x8a, 0x9a, 0x96, 0x1c, 0xa9, 0x67, 0xb8, 0x3f, 0x0c, 0xd5,
- 0xf7, 0xf9, 0x52, 0x13, 0x2f, 0xc2, 0x1b, 0xd5, 0x70, 0x70, 0xf0, 0x8f,
- 0xc0, 0x12, 0xca, 0x06, 0xcb, 0x9a, 0xe1, 0xd9, 0xca, 0x33, 0x7a, 0x77,
- 0xd6, 0xf8, 0xec, 0xb9, 0xf1, 0x68, 0x44, 0x42, 0x48, 0x13, 0xd2, 0xc0,
- 0xc2, 0xa4, 0xae, 0x5e, 0x60, 0xfe, 0xb6, 0xa6, 0x05, 0xfc, 0xb4, 0xdd,
- 0x07, 0x59, 0x02, 0xd4, 0x59, 0x18, 0x98, 0x63, 0xf5, 0xa5, 0x63, 0xe0,
- 0x90, 0x0c, 0x7d, 0x5d, 0xb2, 0x06, 0x7a, 0xf3, 0x85, 0xea, 0xeb, 0xd4,
- 0x03, 0xae, 0x5e, 0x84, 0x3e, 0x5f, 0xff, 0x15, 0xed, 0x69, 0xbc, 0xf9,
- 0x39, 0x36, 0x72, 0x75, 0xcf, 0x77, 0x52, 0x4d, 0xf3, 0xc9, 0x90, 0x2c,
- 0xb9, 0x3d, 0xe5, 0xc9, 0x23, 0x53, 0x3f, 0x1f, 0x24, 0x98, 0x21, 0x5c,
- 0x07, 0x99, 0x29, 0xbd, 0xc6, 0x3a, 0xec, 0xe7, 0x6e, 0x86, 0x3a, 0x6b,
- 0x97, 0x74, 0x63, 0x33, 0xbd, 0x68, 0x18, 0x31, 0xf0, 0x78, 0x8d, 0x76,
- 0xbf, 0xfc, 0x9e, 0x8e, 0x5d, 0x2a, 0x86, 0xa7, 0x4d, 0x90, 0xdc, 0x27,
- 0x1a, 0x39, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x47, 0x30,
- 0x82, 0x01, 0x43, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01,
- 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x03, 0x30,
- 0x4a, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x43, 0x30, 0x41, 0x30, 0x3f,
- 0x06, 0x04, 0x55, 0x1d, 0x20, 0x00, 0x30, 0x37, 0x30, 0x35, 0x06, 0x08,
- 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x29, 0x68, 0x74,
- 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x79, 0x62, 0x65, 0x72, 0x74, 0x72,
- 0x75, 0x73, 0x74, 0x2e, 0x6f, 0x6d, 0x6e, 0x69, 0x72, 0x6f, 0x6f, 0x74,
- 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74,
- 0x6f, 0x72, 0x79, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01,
- 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x81, 0x89, 0x06, 0x03,
- 0x55, 0x1d, 0x23, 0x04, 0x81, 0x81, 0x30, 0x7f, 0xa1, 0x79, 0xa4, 0x77,
- 0x30, 0x75, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
- 0x02, 0x55, 0x53, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x0a,
- 0x13, 0x0f, 0x47, 0x54, 0x45, 0x20, 0x43, 0x6f, 0x72, 0x70, 0x6f, 0x72,
- 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, 0x55,
- 0x04, 0x0b, 0x13, 0x1e, 0x47, 0x54, 0x45, 0x20, 0x43, 0x79, 0x62, 0x65,
- 0x72, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x53, 0x6f, 0x6c, 0x75, 0x74,
- 0x69, 0x6f, 0x6e, 0x73, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x23,
- 0x30, 0x21, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x1a, 0x47, 0x54, 0x45,
- 0x20, 0x43, 0x79, 0x62, 0x65, 0x72, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20,
- 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x82,
- 0x02, 0x01, 0xa5, 0x30, 0x45, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x3e,
- 0x30, 0x3c, 0x30, 0x3a, 0xa0, 0x38, 0xa0, 0x36, 0x86, 0x34, 0x68, 0x74,
- 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x70, 0x75, 0x62,
- 0x6c, 0x69, 0x63, 0x2d, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63, 0x6f,
- 0x6d, 0x2f, 0x63, 0x67, 0x69, 0x2d, 0x62, 0x69, 0x6e, 0x2f, 0x43, 0x52,
- 0x4c, 0x2f, 0x32, 0x30, 0x31, 0x38, 0x2f, 0x63, 0x64, 0x70, 0x2e, 0x63,
- 0x72, 0x6c, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
- 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x81, 0x81, 0x00, 0x93, 0x1d, 0xfe,
- 0x8b, 0xae, 0x46, 0xec, 0xcb, 0xa9, 0x0f, 0xab, 0xe5, 0xef, 0xca, 0xb2,
- 0x68, 0x16, 0x68, 0xd8, 0x8f, 0xfa, 0x13, 0xa9, 0xaf, 0xb3, 0xcb, 0x2d,
- 0xe7, 0x4b, 0x6e, 0x8e, 0x69, 0x2a, 0xc2, 0x2b, 0x10, 0x0a, 0x8d, 0xf6,
- 0xae, 0x73, 0xb6, 0xb9, 0xfb, 0x14, 0xfd, 0x5f, 0x6d, 0xb8, 0x50, 0xb6,
- 0xc4, 0x8a, 0xd6, 0x40, 0x7e, 0xd7, 0xc3, 0xcb, 0x73, 0xdc, 0xc9, 0x5d,
- 0x5b, 0xaf, 0xb0, 0x41, 0xb5, 0x37, 0xeb, 0xea, 0xdc, 0x20, 0x91, 0xc4,
- 0x34, 0x6a, 0xf4, 0xa1, 0xf3, 0x96, 0x9d, 0x37, 0x86, 0x97, 0xe1, 0x71,
- 0xa4, 0xdd, 0x7d, 0xfa, 0x44, 0x84, 0x94, 0xae, 0xd7, 0x09, 0x04, 0x22,
- 0x76, 0x0f, 0x64, 0x51, 0x35, 0xa9, 0x24, 0x0f, 0xf9, 0x0b, 0xdb, 0x32,
- 0xda, 0xc2, 0xfe, 0xc1, 0xb9, 0x2a, 0x5c, 0x7a, 0x27, 0x13, 0xca, 0xb1,
- 0x48, 0x3a, 0x71, 0xd0, 0x43,
-};
-
-#if 0
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number: 146039 (0x23a77)
- Signature Algorithm: sha256WithRSAEncryption
- Issuer: C=US, O=GeoTrust Inc., CN=GeoTrust Global CA
- Validity
- Not Before: Aug 29 21:39:32 2014 GMT
- Not After : May 20 21:39:32 2022 GMT
- Subject: C=US, O=GeoTrust Inc., CN=RapidSSL SHA256 CA - G3
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:af:54:9b:d9:58:5d:1e:2c:56:c6:d5:e8:7f:f4:
- 7d:16:03:ff:d0:8b:5a:e4:8e:a7:dd:54:2e:d4:04:
- c0:5d:98:9c:8d:90:0f:bc:10:65:5f:da:9a:d6:44:
- 7c:c0:9f:b5:e9:4a:8c:0b:06:43:04:bb:f4:96:e2:
- 26:f6:61:01:91:66:31:22:c3:34:34:5f:3f:3f:91:
- 2f:44:5f:dc:c7:14:b6:03:9f:86:4b:0e:a3:ff:a0:
- 80:02:83:c3:d3:1f:69:52:d6:9d:64:0f:c9:83:e7:
- 1b:c4:70:ac:94:e7:c3:a4:6a:2c:bd:b8:9e:69:d8:
- be:0a:8f:16:63:5a:68:71:80:7b:30:de:15:04:bf:
- cc:d3:bf:3e:48:05:55:7a:b3:d7:10:0c:03:fc:9b:
- fd:08:a7:8c:8c:db:a7:8e:f1:1e:63:dc:b3:01:2f:
- 7f:af:57:c3:3c:48:a7:83:68:21:a7:2f:e7:a7:3f:
- f0:b5:0c:fc:f5:84:d1:53:bc:0e:72:4f:60:0c:42:
- b8:98:ad:19:88:57:d7:04:ec:87:bf:7e:87:4e:a3:
- 21:f9:53:fd:36:98:48:8d:d6:f8:bb:48:f2:29:c8:
- 64:d1:cc:54:48:53:8b:af:b7:65:1e:bf:29:33:29:
- d9:29:60:48:f8:ff:91:bc:57:58:e5:35:2e:bb:69:
- b6:59
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Authority Key Identifier:
- keyid:C0:7A:98:68:8D:89:FB:AB:05:64:0C:11:7D:AA:7D:65:B8:CA:CC:4E
-
- X509v3 Subject Key Identifier:
- C3:9C:F3:FC:D3:46:08:34:BB:CE:46:7F:A0:7C:5B:F3:E2:08:CB:59
- X509v3 Basic Constraints: critical
- CA:TRUE, pathlen:0
- X509v3 Key Usage: critical
- Certificate Sign, CRL Sign
- X509v3 CRL Distribution Points:
-
- Full Name:
- URI:http://g.symcb.com/crls/gtglobal.crl
-
- Authority Information Access:
- OCSP - URI:http://g.symcd.com
-
- X509v3 Certificate Policies:
- Policy: 2.16.840.1.113733.1.7.54
- CPS: http://www.geotrust.com/resources/cps
-
- Signature Algorithm: sha256WithRSAEncryption
- a3:58:1e:c6:43:32:ac:ac:2f:93:78:b7:ea:ae:54:40:47:2d:
- 7e:78:8d:50:f6:f8:66:ac:d6:4f:73:d6:44:ef:af:0b:cc:5b:
- c1:f4:4f:9a:8f:49:7e:60:af:c2:27:c7:16:f1:fb:93:81:90:
- a9:7c:ef:6f:7e:6e:45:94:16:84:bd:ec:49:f1:c4:0e:f4:af:
- 04:59:83:87:0f:2c:3b:97:c3:5a:12:9b:7b:04:35:7b:a3:95:
- 33:08:7b:93:71:22:42:b3:a9:d9:6f:4f:81:92:fc:07:b6:79:
- bc:84:4a:9d:77:09:f1:c5:89:f2:f0:b4:9c:54:aa:12:7b:0d:
- ba:4f:ef:93:19:ec:ef:7d:4e:61:a3:8e:76:9c:59:cf:8c:94:
- b1:84:97:f7:1a:b9:07:b8:b2:c6:4f:13:79:db:bf:4f:51:1b:
- 7f:69:0d:51:2a:c1:d6:15:ff:37:51:34:65:51:f4:1e:be:38:
- 6a:ec:0e:ab:bf:3d:7b:39:05:7b:f4:f3:fb:1a:a1:d0:c8:7e:
- 4e:64:8d:cd:8c:61:55:90:fe:3a:ca:5d:25:0f:f8:1d:a3:4a:
- 74:56:4f:1a:55:40:70:75:25:a6:33:2e:ba:4b:a5:5d:53:9a:
- 0d:30:e1:8d:5f:61:2c:af:cc:ef:b0:99:a1:80:ff:0b:f2:62:
- 4c:70:26:98
------BEGIN CERTIFICATE-----
-MIIEJTCCAw2gAwIBAgIDAjp3MA0GCSqGSIb3DQEBCwUAMEIxCzAJBgNVBAYTAlVT
-MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i
-YWwgQ0EwHhcNMTQwODI5MjEzOTMyWhcNMjIwNTIwMjEzOTMyWjBHMQswCQYDVQQG
-EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEgMB4GA1UEAxMXUmFwaWRTU0wg
-U0hBMjU2IENBIC0gRzMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCv
-VJvZWF0eLFbG1eh/9H0WA//Qi1rkjqfdVC7UBMBdmJyNkA+8EGVf2prWRHzAn7Xp
-SowLBkMEu/SW4ib2YQGRZjEiwzQ0Xz8/kS9EX9zHFLYDn4ZLDqP/oIACg8PTH2lS
-1p1kD8mD5xvEcKyU58Okaiy9uJ5p2L4KjxZjWmhxgHsw3hUEv8zTvz5IBVV6s9cQ
-DAP8m/0Ip4yM26eO8R5j3LMBL3+vV8M8SKeDaCGnL+enP/C1DPz1hNFTvA5yT2AM
-QriYrRmIV9cE7Ie/fodOoyH5U/02mEiN1vi7SPIpyGTRzFRIU4uvt2UevykzKdkp
-YEj4/5G8V1jlNS67abZZAgMBAAGjggEdMIIBGTAfBgNVHSMEGDAWgBTAephojYn7
-qwVkDBF9qn1luMrMTjAdBgNVHQ4EFgQUw5zz/NNGCDS7zkZ/oHxb8+IIy1kwEgYD
-VR0TAQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAQYwNQYDVR0fBC4wLDAqoCig
-JoYkaHR0cDovL2cuc3ltY2IuY29tL2NybHMvZ3RnbG9iYWwuY3JsMC4GCCsGAQUF
-BwEBBCIwIDAeBggrBgEFBQcwAYYSaHR0cDovL2cuc3ltY2QuY29tMEwGA1UdIARF
-MEMwQQYKYIZIAYb4RQEHNjAzMDEGCCsGAQUFBwIBFiVodHRwOi8vd3d3Lmdlb3Ry
-dXN0LmNvbS9yZXNvdXJjZXMvY3BzMA0GCSqGSIb3DQEBCwUAA4IBAQCjWB7GQzKs
-rC+TeLfqrlRARy1+eI1Q9vhmrNZPc9ZE768LzFvB9E+aj0l+YK/CJ8cW8fuTgZCp
-fO9vfm5FlBaEvexJ8cQO9K8EWYOHDyw7l8NaEpt7BDV7o5UzCHuTcSJCs6nZb0+B
-kvwHtnm8hEqddwnxxYny8LScVKoSew26T++TGezvfU5ho452nFnPjJSxhJf3GrkH
-uLLGTxN5279PURt/aQ1RKsHWFf83UTRlUfQevjhq7A6rvz17OQV79PP7GqHQyH5O
-ZI3NjGFVkP46yl0lD/gdo0p0Vk8aVUBwdSWmMy66S6VdU5oNMOGNX2Esr8zvsJmh
-gP8L8mJMcCaY
------END CERTIFICATE-----
-#endif
-static const unsigned char kDERCert4[] = {
- 0x30, 0x82, 0x04, 0x25, 0x30, 0x82, 0x03, 0x0d, 0xa0, 0x03, 0x02, 0x01,
- 0x02, 0x02, 0x03, 0x02, 0x3a, 0x77, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
- 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x42, 0x31,
- 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53,
- 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0d, 0x47,
- 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x49, 0x6e, 0x63, 0x2e,
- 0x31, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x12, 0x47,
- 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x47, 0x6c, 0x6f, 0x62,
- 0x61, 0x6c, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x34, 0x30,
- 0x38, 0x32, 0x39, 0x32, 0x31, 0x33, 0x39, 0x33, 0x32, 0x5a, 0x17, 0x0d,
- 0x32, 0x32, 0x30, 0x35, 0x32, 0x30, 0x32, 0x31, 0x33, 0x39, 0x33, 0x32,
- 0x5a, 0x30, 0x47, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06,
- 0x13, 0x02, 0x55, 0x53, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04,
- 0x0a, 0x13, 0x0d, 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20,
- 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x20, 0x30, 0x1e, 0x06, 0x03, 0x55, 0x04,
- 0x03, 0x13, 0x17, 0x52, 0x61, 0x70, 0x69, 0x64, 0x53, 0x53, 0x4c, 0x20,
- 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, 0x20, 0x43, 0x41, 0x20, 0x2d, 0x20,
- 0x47, 0x33, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
- 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01,
- 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xaf,
- 0x54, 0x9b, 0xd9, 0x58, 0x5d, 0x1e, 0x2c, 0x56, 0xc6, 0xd5, 0xe8, 0x7f,
- 0xf4, 0x7d, 0x16, 0x03, 0xff, 0xd0, 0x8b, 0x5a, 0xe4, 0x8e, 0xa7, 0xdd,
- 0x54, 0x2e, 0xd4, 0x04, 0xc0, 0x5d, 0x98, 0x9c, 0x8d, 0x90, 0x0f, 0xbc,
- 0x10, 0x65, 0x5f, 0xda, 0x9a, 0xd6, 0x44, 0x7c, 0xc0, 0x9f, 0xb5, 0xe9,
- 0x4a, 0x8c, 0x0b, 0x06, 0x43, 0x04, 0xbb, 0xf4, 0x96, 0xe2, 0x26, 0xf6,
- 0x61, 0x01, 0x91, 0x66, 0x31, 0x22, 0xc3, 0x34, 0x34, 0x5f, 0x3f, 0x3f,
- 0x91, 0x2f, 0x44, 0x5f, 0xdc, 0xc7, 0x14, 0xb6, 0x03, 0x9f, 0x86, 0x4b,
- 0x0e, 0xa3, 0xff, 0xa0, 0x80, 0x02, 0x83, 0xc3, 0xd3, 0x1f, 0x69, 0x52,
- 0xd6, 0x9d, 0x64, 0x0f, 0xc9, 0x83, 0xe7, 0x1b, 0xc4, 0x70, 0xac, 0x94,
- 0xe7, 0xc3, 0xa4, 0x6a, 0x2c, 0xbd, 0xb8, 0x9e, 0x69, 0xd8, 0xbe, 0x0a,
- 0x8f, 0x16, 0x63, 0x5a, 0x68, 0x71, 0x80, 0x7b, 0x30, 0xde, 0x15, 0x04,
- 0xbf, 0xcc, 0xd3, 0xbf, 0x3e, 0x48, 0x05, 0x55, 0x7a, 0xb3, 0xd7, 0x10,
- 0x0c, 0x03, 0xfc, 0x9b, 0xfd, 0x08, 0xa7, 0x8c, 0x8c, 0xdb, 0xa7, 0x8e,
- 0xf1, 0x1e, 0x63, 0xdc, 0xb3, 0x01, 0x2f, 0x7f, 0xaf, 0x57, 0xc3, 0x3c,
- 0x48, 0xa7, 0x83, 0x68, 0x21, 0xa7, 0x2f, 0xe7, 0xa7, 0x3f, 0xf0, 0xb5,
- 0x0c, 0xfc, 0xf5, 0x84, 0xd1, 0x53, 0xbc, 0x0e, 0x72, 0x4f, 0x60, 0x0c,
- 0x42, 0xb8, 0x98, 0xad, 0x19, 0x88, 0x57, 0xd7, 0x04, 0xec, 0x87, 0xbf,
- 0x7e, 0x87, 0x4e, 0xa3, 0x21, 0xf9, 0x53, 0xfd, 0x36, 0x98, 0x48, 0x8d,
- 0xd6, 0xf8, 0xbb, 0x48, 0xf2, 0x29, 0xc8, 0x64, 0xd1, 0xcc, 0x54, 0x48,
- 0x53, 0x8b, 0xaf, 0xb7, 0x65, 0x1e, 0xbf, 0x29, 0x33, 0x29, 0xd9, 0x29,
- 0x60, 0x48, 0xf8, 0xff, 0x91, 0xbc, 0x57, 0x58, 0xe5, 0x35, 0x2e, 0xbb,
- 0x69, 0xb6, 0x59, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x1d,
- 0x30, 0x82, 0x01, 0x19, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04,
- 0x18, 0x30, 0x16, 0x80, 0x14, 0xc0, 0x7a, 0x98, 0x68, 0x8d, 0x89, 0xfb,
- 0xab, 0x05, 0x64, 0x0c, 0x11, 0x7d, 0xaa, 0x7d, 0x65, 0xb8, 0xca, 0xcc,
- 0x4e, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14,
- 0xc3, 0x9c, 0xf3, 0xfc, 0xd3, 0x46, 0x08, 0x34, 0xbb, 0xce, 0x46, 0x7f,
- 0xa0, 0x7c, 0x5b, 0xf3, 0xe2, 0x08, 0xcb, 0x59, 0x30, 0x12, 0x06, 0x03,
- 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01,
- 0xff, 0x02, 0x01, 0x00, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01,
- 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x35, 0x06, 0x03,
- 0x55, 0x1d, 0x1f, 0x04, 0x2e, 0x30, 0x2c, 0x30, 0x2a, 0xa0, 0x28, 0xa0,
- 0x26, 0x86, 0x24, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x67, 0x2e,
- 0x73, 0x79, 0x6d, 0x63, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x72,
- 0x6c, 0x73, 0x2f, 0x67, 0x74, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x2e,
- 0x63, 0x72, 0x6c, 0x30, 0x2e, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05,
- 0x07, 0x01, 0x01, 0x04, 0x22, 0x30, 0x20, 0x30, 0x1e, 0x06, 0x08, 0x2b,
- 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x12, 0x68, 0x74, 0x74,
- 0x70, 0x3a, 0x2f, 0x2f, 0x67, 0x2e, 0x73, 0x79, 0x6d, 0x63, 0x64, 0x2e,
- 0x63, 0x6f, 0x6d, 0x30, 0x4c, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x45,
- 0x30, 0x43, 0x30, 0x41, 0x06, 0x0a, 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8,
- 0x45, 0x01, 0x07, 0x36, 0x30, 0x33, 0x30, 0x31, 0x06, 0x08, 0x2b, 0x06,
- 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x25, 0x68, 0x74, 0x74, 0x70,
- 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x67, 0x65, 0x6f, 0x74, 0x72,
- 0x75, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x73, 0x6f,
- 0x75, 0x72, 0x63, 0x65, 0x73, 0x2f, 0x63, 0x70, 0x73, 0x30, 0x0d, 0x06,
- 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00,
- 0x03, 0x82, 0x01, 0x01, 0x00, 0xa3, 0x58, 0x1e, 0xc6, 0x43, 0x32, 0xac,
- 0xac, 0x2f, 0x93, 0x78, 0xb7, 0xea, 0xae, 0x54, 0x40, 0x47, 0x2d, 0x7e,
- 0x78, 0x8d, 0x50, 0xf6, 0xf8, 0x66, 0xac, 0xd6, 0x4f, 0x73, 0xd6, 0x44,
- 0xef, 0xaf, 0x0b, 0xcc, 0x5b, 0xc1, 0xf4, 0x4f, 0x9a, 0x8f, 0x49, 0x7e,
- 0x60, 0xaf, 0xc2, 0x27, 0xc7, 0x16, 0xf1, 0xfb, 0x93, 0x81, 0x90, 0xa9,
- 0x7c, 0xef, 0x6f, 0x7e, 0x6e, 0x45, 0x94, 0x16, 0x84, 0xbd, 0xec, 0x49,
- 0xf1, 0xc4, 0x0e, 0xf4, 0xaf, 0x04, 0x59, 0x83, 0x87, 0x0f, 0x2c, 0x3b,
- 0x97, 0xc3, 0x5a, 0x12, 0x9b, 0x7b, 0x04, 0x35, 0x7b, 0xa3, 0x95, 0x33,
- 0x08, 0x7b, 0x93, 0x71, 0x22, 0x42, 0xb3, 0xa9, 0xd9, 0x6f, 0x4f, 0x81,
- 0x92, 0xfc, 0x07, 0xb6, 0x79, 0xbc, 0x84, 0x4a, 0x9d, 0x77, 0x09, 0xf1,
- 0xc5, 0x89, 0xf2, 0xf0, 0xb4, 0x9c, 0x54, 0xaa, 0x12, 0x7b, 0x0d, 0xba,
- 0x4f, 0xef, 0x93, 0x19, 0xec, 0xef, 0x7d, 0x4e, 0x61, 0xa3, 0x8e, 0x76,
- 0x9c, 0x59, 0xcf, 0x8c, 0x94, 0xb1, 0x84, 0x97, 0xf7, 0x1a, 0xb9, 0x07,
- 0xb8, 0xb2, 0xc6, 0x4f, 0x13, 0x79, 0xdb, 0xbf, 0x4f, 0x51, 0x1b, 0x7f,
- 0x69, 0x0d, 0x51, 0x2a, 0xc1, 0xd6, 0x15, 0xff, 0x37, 0x51, 0x34, 0x65,
- 0x51, 0xf4, 0x1e, 0xbe, 0x38, 0x6a, 0xec, 0x0e, 0xab, 0xbf, 0x3d, 0x7b,
- 0x39, 0x05, 0x7b, 0xf4, 0xf3, 0xfb, 0x1a, 0xa1, 0xd0, 0xc8, 0x7e, 0x4e,
- 0x64, 0x8d, 0xcd, 0x8c, 0x61, 0x55, 0x90, 0xfe, 0x3a, 0xca, 0x5d, 0x25,
- 0x0f, 0xf8, 0x1d, 0xa3, 0x4a, 0x74, 0x56, 0x4f, 0x1a, 0x55, 0x40, 0x70,
- 0x75, 0x25, 0xa6, 0x33, 0x2e, 0xba, 0x4b, 0xa5, 0x5d, 0x53, 0x9a, 0x0d,
- 0x30, 0xe1, 0x8d, 0x5f, 0x61, 0x2c, 0xaf, 0xcc, 0xef, 0xb0, 0x99, 0xa1,
- 0x80, 0xff, 0x0b, 0xf2, 0x62, 0x4c, 0x70, 0x26, 0x98,
-};
-
-#if 0
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number: 146040 (0x23a78)
- Signature Algorithm: sha256WithRSAEncryption
- Issuer: C=US, O=GeoTrust Inc., CN=GeoTrust Global CA
- Validity
- Not Before: Aug 29 22:24:58 2014 GMT
- Not After : May 20 22:24:58 2022 GMT
- Subject: C=US, O=GeoTrust Inc., OU=Domain Validated SSL, CN=GeoTrust DV SSL CA - G4
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:df:41:94:7a:da:f7:e4:31:43:b6:ea:01:1b:5c:
- ce:63:ea:fa:6d:a3:d9:6a:ee:2d:9a:75:f9:d5:9c:
- 5b:bd:34:df:d8:1c:c9:6d:d8:04:88:da:6e:b5:b7:
- b5:f0:30:ae:40:d6:5d:fa:c4:53:c1:d4:22:9d:04:
- 4e:11:a6:95:d5:45:7c:41:05:58:e0:4c:dd:f9:ee:
- 55:bd:5f:46:dc:ad:13:08:9d:2c:e4:f7:82:e6:07:
- 2b:9e:0e:8c:34:a1:ce:c4:a1:e0:81:70:86:00:06:
- 3f:2d:ea:7c:9b:28:ae:1b:28:8b:39:09:d3:e7:f0:
- 45:a4:b1:ba:11:67:90:55:7b:8f:de:ed:38:5c:a1:
- e1:e3:83:c4:c3:72:91:4f:98:ee:1c:c2:80:aa:64:
- a5:3e:83:62:1c:cc:e0:9e:f8:5a:c0:13:12:7d:a2:
- a7:8b:a3:e7:9f:2a:d7:9b:ca:cb:ed:97:01:9c:28:
- 84:51:04:50:41:bc:b4:fc:78:e9:1b:cf:14:ea:1f:
- 0f:fc:2e:01:32:8d:b6:35:cb:0a:18:3b:ec:5a:3e:
- 3c:1b:d3:99:43:1e:2f:f7:bd:f3:5b:12:b9:07:5e:
- ed:3e:d1:a9:87:cc:77:72:27:d4:d9:75:a2:63:4b:
- 93:36:bd:e5:5c:d7:bf:5f:79:0d:b3:32:a7:0b:b2:
- 63:23
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Authority Key Identifier:
- keyid:C0:7A:98:68:8D:89:FB:AB:05:64:0C:11:7D:AA:7D:65:B8:CA:CC:4E
-
- X509v3 Subject Key Identifier:
- 0B:50:EC:77:EF:2A:9B:FF:EC:03:A1:0A:FF:AD:C6:E4:2A:18:C7:3E
- X509v3 Basic Constraints: critical
- CA:TRUE, pathlen:0
- X509v3 Key Usage: critical
- Certificate Sign, CRL Sign
- X509v3 CRL Distribution Points:
-
- Full Name:
- URI:http://g.symcb.com/crls/gtglobal.crl
-
- Authority Information Access:
- OCSP - URI:http://g.symcd.com
-
- X509v3 Certificate Policies:
- Policy: 2.16.840.1.113733.1.7.54
- CPS: http://www.geotrust.com/resources/cps
-
- Signature Algorithm: sha256WithRSAEncryption
- 33:24:d5:90:aa:29:0c:35:b9:2f:c3:c7:42:93:c0:c6:10:4b:
- 03:08:76:84:10:a2:e0:e7:53:12:27:f2:0a:da:7f:3a:dc:fd:
- 5c:79:5a:8f:17:74:43:53:b1:d5:d1:5d:59:b9:a6:84:64:ca:
- f1:3a:0a:59:96:10:bf:a9:81:57:8b:5c:87:dc:7f:e3:e4:bb:
- 05:7a:a0:32:09:13:4e:10:81:28:1f:9c:03:62:bc:f4:01:b5:
- 29:83:46:07:b9:e7:b8:5d:c8:e9:d1:dd:ad:3b:f8:34:db:c1:
- d1:95:a9:91:18:ed:3c:2c:37:11:4d:cc:fe:53:3e:50:43:f9:
- c3:56:41:ac:53:9b:6c:05:b2:9a:e2:e0:59:57:30:32:b6:26:
- 4e:13:25:cd:fa:48:70:0f:75:55:60:11:f5:3b:d5:5e:5a:3c:
- 8b:5b:0f:0f:62:42:48:61:85:8b:10:f4:c1:88:bf:7f:5f:8a:
- c2:d7:cd:2b:94:5c:1f:34:4a:08:af:eb:ae:89:a8:48:75:55:
- 95:1d:bb:c0:9a:01:b9:f4:03:22:3e:d4:e6:52:30:0d:67:b9:
- c0:91:fd:2d:4c:30:8e:bd:8c:a5:04:91:bb:a4:ab:7f:0f:d8:
- 6f:f0:66:00:c9:a3:5c:f5:b0:8f:83:e6:9c:5a:e6:b6:b9:c5:
- bc:be:e4:02
------BEGIN CERTIFICATE-----
-MIIERDCCAyygAwIBAgIDAjp4MA0GCSqGSIb3DQEBCwUAMEIxCzAJBgNVBAYTAlVT
-MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i
-YWwgQ0EwHhcNMTQwODI5MjIyNDU4WhcNMjIwNTIwMjIyNDU4WjBmMQswCQYDVQQG
-EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEdMBsGA1UECxMURG9tYWluIFZh
-bGlkYXRlZCBTU0wxIDAeBgNVBAMTF0dlb1RydXN0IERWIFNTTCBDQSAtIEc0MIIB
-IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA30GUetr35DFDtuoBG1zOY+r6
-baPZau4tmnX51ZxbvTTf2BzJbdgEiNputbe18DCuQNZd+sRTwdQinQROEaaV1UV8
-QQVY4Ezd+e5VvV9G3K0TCJ0s5PeC5gcrng6MNKHOxKHggXCGAAY/Lep8myiuGyiL
-OQnT5/BFpLG6EWeQVXuP3u04XKHh44PEw3KRT5juHMKAqmSlPoNiHMzgnvhawBMS
-faKni6PnnyrXm8rL7ZcBnCiEUQRQQby0/HjpG88U6h8P/C4BMo22NcsKGDvsWj48
-G9OZQx4v973zWxK5B17tPtGph8x3cifU2XWiY0uTNr3lXNe/X3kNszKnC7JjIwID
-AQABo4IBHTCCARkwHwYDVR0jBBgwFoAUwHqYaI2J+6sFZAwRfap9ZbjKzE4wHQYD
-VR0OBBYEFAtQ7HfvKpv/7AOhCv+txuQqGMc+MBIGA1UdEwEB/wQIMAYBAf8CAQAw
-DgYDVR0PAQH/BAQDAgEGMDUGA1UdHwQuMCwwKqAooCaGJGh0dHA6Ly9nLnN5bWNi
-LmNvbS9jcmxzL2d0Z2xvYmFsLmNybDAuBggrBgEFBQcBAQQiMCAwHgYIKwYBBQUH
-MAGGEmh0dHA6Ly9nLnN5bWNkLmNvbTBMBgNVHSAERTBDMEEGCmCGSAGG+EUBBzYw
-MzAxBggrBgEFBQcCARYlaHR0cDovL3d3dy5nZW90cnVzdC5jb20vcmVzb3VyY2Vz
-L2NwczANBgkqhkiG9w0BAQsFAAOCAQEAMyTVkKopDDW5L8PHQpPAxhBLAwh2hBCi
-4OdTEifyCtp/Otz9XHlajxd0Q1Ox1dFdWbmmhGTK8ToKWZYQv6mBV4tch9x/4+S7
-BXqgMgkTThCBKB+cA2K89AG1KYNGB7nnuF3I6dHdrTv4NNvB0ZWpkRjtPCw3EU3M
-/lM+UEP5w1ZBrFObbAWymuLgWVcwMrYmThMlzfpIcA91VWAR9TvVXlo8i1sPD2JC
-SGGFixD0wYi/f1+KwtfNK5RcHzRKCK/rromoSHVVlR27wJoBufQDIj7U5lIwDWe5
-wJH9LUwwjr2MpQSRu6Srfw/Yb/BmAMmjXPWwj4PmnFrmtrnFvL7kAg==
------END CERTIFICATE-----
-#endif
-static const unsigned char kDERCert5[] = {
- 0x30, 0x82, 0x04, 0x44, 0x30, 0x82, 0x03, 0x2c, 0xa0, 0x03, 0x02, 0x01,
- 0x02, 0x02, 0x03, 0x02, 0x3a, 0x78, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
- 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x42, 0x31,
- 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53,
- 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0d, 0x47,
- 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x49, 0x6e, 0x63, 0x2e,
- 0x31, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x12, 0x47,
- 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x47, 0x6c, 0x6f, 0x62,
- 0x61, 0x6c, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x34, 0x30,
- 0x38, 0x32, 0x39, 0x32, 0x32, 0x32, 0x34, 0x35, 0x38, 0x5a, 0x17, 0x0d,
- 0x32, 0x32, 0x30, 0x35, 0x32, 0x30, 0x32, 0x32, 0x32, 0x34, 0x35, 0x38,
- 0x5a, 0x30, 0x66, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06,
- 0x13, 0x02, 0x55, 0x53, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04,
- 0x0a, 0x13, 0x0d, 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20,
- 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x1d, 0x30, 0x1b, 0x06, 0x03, 0x55, 0x04,
- 0x0b, 0x13, 0x14, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x20, 0x56, 0x61,
- 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x64, 0x20, 0x53, 0x53, 0x4c, 0x31,
- 0x20, 0x30, 0x1e, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x17, 0x47, 0x65,
- 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x44, 0x56, 0x20, 0x53, 0x53,
- 0x4c, 0x20, 0x43, 0x41, 0x20, 0x2d, 0x20, 0x47, 0x34, 0x30, 0x82, 0x01,
- 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
- 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01,
- 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xdf, 0x41, 0x94, 0x7a, 0xda, 0xf7,
- 0xe4, 0x31, 0x43, 0xb6, 0xea, 0x01, 0x1b, 0x5c, 0xce, 0x63, 0xea, 0xfa,
- 0x6d, 0xa3, 0xd9, 0x6a, 0xee, 0x2d, 0x9a, 0x75, 0xf9, 0xd5, 0x9c, 0x5b,
- 0xbd, 0x34, 0xdf, 0xd8, 0x1c, 0xc9, 0x6d, 0xd8, 0x04, 0x88, 0xda, 0x6e,
- 0xb5, 0xb7, 0xb5, 0xf0, 0x30, 0xae, 0x40, 0xd6, 0x5d, 0xfa, 0xc4, 0x53,
- 0xc1, 0xd4, 0x22, 0x9d, 0x04, 0x4e, 0x11, 0xa6, 0x95, 0xd5, 0x45, 0x7c,
- 0x41, 0x05, 0x58, 0xe0, 0x4c, 0xdd, 0xf9, 0xee, 0x55, 0xbd, 0x5f, 0x46,
- 0xdc, 0xad, 0x13, 0x08, 0x9d, 0x2c, 0xe4, 0xf7, 0x82, 0xe6, 0x07, 0x2b,
- 0x9e, 0x0e, 0x8c, 0x34, 0xa1, 0xce, 0xc4, 0xa1, 0xe0, 0x81, 0x70, 0x86,
- 0x00, 0x06, 0x3f, 0x2d, 0xea, 0x7c, 0x9b, 0x28, 0xae, 0x1b, 0x28, 0x8b,
- 0x39, 0x09, 0xd3, 0xe7, 0xf0, 0x45, 0xa4, 0xb1, 0xba, 0x11, 0x67, 0x90,
- 0x55, 0x7b, 0x8f, 0xde, 0xed, 0x38, 0x5c, 0xa1, 0xe1, 0xe3, 0x83, 0xc4,
- 0xc3, 0x72, 0x91, 0x4f, 0x98, 0xee, 0x1c, 0xc2, 0x80, 0xaa, 0x64, 0xa5,
- 0x3e, 0x83, 0x62, 0x1c, 0xcc, 0xe0, 0x9e, 0xf8, 0x5a, 0xc0, 0x13, 0x12,
- 0x7d, 0xa2, 0xa7, 0x8b, 0xa3, 0xe7, 0x9f, 0x2a, 0xd7, 0x9b, 0xca, 0xcb,
- 0xed, 0x97, 0x01, 0x9c, 0x28, 0x84, 0x51, 0x04, 0x50, 0x41, 0xbc, 0xb4,
- 0xfc, 0x78, 0xe9, 0x1b, 0xcf, 0x14, 0xea, 0x1f, 0x0f, 0xfc, 0x2e, 0x01,
- 0x32, 0x8d, 0xb6, 0x35, 0xcb, 0x0a, 0x18, 0x3b, 0xec, 0x5a, 0x3e, 0x3c,
- 0x1b, 0xd3, 0x99, 0x43, 0x1e, 0x2f, 0xf7, 0xbd, 0xf3, 0x5b, 0x12, 0xb9,
- 0x07, 0x5e, 0xed, 0x3e, 0xd1, 0xa9, 0x87, 0xcc, 0x77, 0x72, 0x27, 0xd4,
- 0xd9, 0x75, 0xa2, 0x63, 0x4b, 0x93, 0x36, 0xbd, 0xe5, 0x5c, 0xd7, 0xbf,
- 0x5f, 0x79, 0x0d, 0xb3, 0x32, 0xa7, 0x0b, 0xb2, 0x63, 0x23, 0x02, 0x03,
- 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x1d, 0x30, 0x82, 0x01, 0x19, 0x30,
- 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14,
- 0xc0, 0x7a, 0x98, 0x68, 0x8d, 0x89, 0xfb, 0xab, 0x05, 0x64, 0x0c, 0x11,
- 0x7d, 0xaa, 0x7d, 0x65, 0xb8, 0xca, 0xcc, 0x4e, 0x30, 0x1d, 0x06, 0x03,
- 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x0b, 0x50, 0xec, 0x77, 0xef,
- 0x2a, 0x9b, 0xff, 0xec, 0x03, 0xa1, 0x0a, 0xff, 0xad, 0xc6, 0xe4, 0x2a,
- 0x18, 0xc7, 0x3e, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01,
- 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x00, 0x30,
- 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03,
- 0x02, 0x01, 0x06, 0x30, 0x35, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x2e,
- 0x30, 0x2c, 0x30, 0x2a, 0xa0, 0x28, 0xa0, 0x26, 0x86, 0x24, 0x68, 0x74,
- 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x67, 0x2e, 0x73, 0x79, 0x6d, 0x63, 0x62,
- 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x72, 0x6c, 0x73, 0x2f, 0x67, 0x74,
- 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x2e,
- 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x22,
- 0x30, 0x20, 0x30, 0x1e, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
- 0x30, 0x01, 0x86, 0x12, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x67,
- 0x2e, 0x73, 0x79, 0x6d, 0x63, 0x64, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x4c,
- 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x45, 0x30, 0x43, 0x30, 0x41, 0x06,
- 0x0a, 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x45, 0x01, 0x07, 0x36, 0x30,
- 0x33, 0x30, 0x31, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02,
- 0x01, 0x16, 0x25, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77,
- 0x77, 0x2e, 0x67, 0x65, 0x6f, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63,
- 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73,
- 0x2f, 0x63, 0x70, 0x73, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
- 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00,
- 0x33, 0x24, 0xd5, 0x90, 0xaa, 0x29, 0x0c, 0x35, 0xb9, 0x2f, 0xc3, 0xc7,
- 0x42, 0x93, 0xc0, 0xc6, 0x10, 0x4b, 0x03, 0x08, 0x76, 0x84, 0x10, 0xa2,
- 0xe0, 0xe7, 0x53, 0x12, 0x27, 0xf2, 0x0a, 0xda, 0x7f, 0x3a, 0xdc, 0xfd,
- 0x5c, 0x79, 0x5a, 0x8f, 0x17, 0x74, 0x43, 0x53, 0xb1, 0xd5, 0xd1, 0x5d,
- 0x59, 0xb9, 0xa6, 0x84, 0x64, 0xca, 0xf1, 0x3a, 0x0a, 0x59, 0x96, 0x10,
- 0xbf, 0xa9, 0x81, 0x57, 0x8b, 0x5c, 0x87, 0xdc, 0x7f, 0xe3, 0xe4, 0xbb,
- 0x05, 0x7a, 0xa0, 0x32, 0x09, 0x13, 0x4e, 0x10, 0x81, 0x28, 0x1f, 0x9c,
- 0x03, 0x62, 0xbc, 0xf4, 0x01, 0xb5, 0x29, 0x83, 0x46, 0x07, 0xb9, 0xe7,
- 0xb8, 0x5d, 0xc8, 0xe9, 0xd1, 0xdd, 0xad, 0x3b, 0xf8, 0x34, 0xdb, 0xc1,
- 0xd1, 0x95, 0xa9, 0x91, 0x18, 0xed, 0x3c, 0x2c, 0x37, 0x11, 0x4d, 0xcc,
- 0xfe, 0x53, 0x3e, 0x50, 0x43, 0xf9, 0xc3, 0x56, 0x41, 0xac, 0x53, 0x9b,
- 0x6c, 0x05, 0xb2, 0x9a, 0xe2, 0xe0, 0x59, 0x57, 0x30, 0x32, 0xb6, 0x26,
- 0x4e, 0x13, 0x25, 0xcd, 0xfa, 0x48, 0x70, 0x0f, 0x75, 0x55, 0x60, 0x11,
- 0xf5, 0x3b, 0xd5, 0x5e, 0x5a, 0x3c, 0x8b, 0x5b, 0x0f, 0x0f, 0x62, 0x42,
- 0x48, 0x61, 0x85, 0x8b, 0x10, 0xf4, 0xc1, 0x88, 0xbf, 0x7f, 0x5f, 0x8a,
- 0xc2, 0xd7, 0xcd, 0x2b, 0x94, 0x5c, 0x1f, 0x34, 0x4a, 0x08, 0xaf, 0xeb,
- 0xae, 0x89, 0xa8, 0x48, 0x75, 0x55, 0x95, 0x1d, 0xbb, 0xc0, 0x9a, 0x01,
- 0xb9, 0xf4, 0x03, 0x22, 0x3e, 0xd4, 0xe6, 0x52, 0x30, 0x0d, 0x67, 0xb9,
- 0xc0, 0x91, 0xfd, 0x2d, 0x4c, 0x30, 0x8e, 0xbd, 0x8c, 0xa5, 0x04, 0x91,
- 0xbb, 0xa4, 0xab, 0x7f, 0x0f, 0xd8, 0x6f, 0xf0, 0x66, 0x00, 0xc9, 0xa3,
- 0x5c, 0xf5, 0xb0, 0x8f, 0x83, 0xe6, 0x9c, 0x5a, 0xe6, 0xb6, 0xb9, 0xc5,
- 0xbc, 0xbe, 0xe4, 0x02,
-};
-
-#if 0
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number:
- 33:65:50:08:79:ad:73:e2:30:b9:e0:1d:0d:7f:ac:91
- Signature Algorithm: sha1WithRSAEncryption
- Issuer: C=ZA, ST=Western Cape, L=Cape Town, O=Thawte Consulting cc, OU=Certification Services Division, CN=Thawte Premium Server CA/emailAddress=premium-server@thawte.com
- Validity
- Not Before: Nov 17 00:00:00 2006 GMT
- Not After : Dec 30 23:59:59 2020 GMT
- Subject: C=US, O=thawte, Inc., OU=Certification Services Division, OU=(c) 2006 thawte, Inc. - For authorized use only, CN=thawte Primary Root CA
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:ac:a0:f0:fb:80:59:d4:9c:c7:a4:cf:9d:a1:59:
- 73:09:10:45:0c:0d:2c:6e:68:f1:6c:5b:48:68:49:
- 59:37:fc:0b:33:19:c2:77:7f:cc:10:2d:95:34:1c:
- e6:eb:4d:09:a7:1c:d2:b8:c9:97:36:02:b7:89:d4:
- 24:5f:06:c0:cc:44:94:94:8d:02:62:6f:eb:5a:dd:
- 11:8d:28:9a:5c:84:90:10:7a:0d:bd:74:66:2f:6a:
- 38:a0:e2:d5:54:44:eb:1d:07:9f:07:ba:6f:ee:e9:
- fd:4e:0b:29:f5:3e:84:a0:01:f1:9c:ab:f8:1c:7e:
- 89:a4:e8:a1:d8:71:65:0d:a3:51:7b:ee:bc:d2:22:
- 60:0d:b9:5b:9d:df:ba:fc:51:5b:0b:af:98:b2:e9:
- 2e:e9:04:e8:62:87:de:2b:c8:d7:4e:c1:4c:64:1e:
- dd:cf:87:58:ba:4a:4f:ca:68:07:1d:1c:9d:4a:c6:
- d5:2f:91:cc:7c:71:72:1c:c5:c0:67:eb:32:fd:c9:
- 92:5c:94:da:85:c0:9b:bf:53:7d:2b:09:f4:8c:9d:
- 91:1f:97:6a:52:cb:de:09:36:a4:77:d8:7b:87:50:
- 44:d5:3e:6e:29:69:fb:39:49:26:1e:09:a5:80:7b:
- 40:2d:eb:e8:27:85:c9:fe:61:fd:7e:e6:7c:97:1d:
- d5:9d
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Basic Constraints: critical
- CA:TRUE
- X509v3 Certificate Policies:
- Policy: X509v3 Any Policy
- CPS: https://www.thawte.com/cps
-
- X509v3 Key Usage: critical
- Certificate Sign, CRL Sign
- X509v3 Subject Key Identifier:
- 7B:5B:45:CF:AF:CE:CB:7A:FD:31:92:1A:6A:B6:F3:46:EB:57:48:50
- X509v3 CRL Distribution Points:
-
- Full Name:
- URI:http://crl.thawte.com/ThawtePremiumServerCA.crl
-
- Signature Algorithm: sha1WithRSAEncryption
- 84:a8:4c:c9:3e:2a:bc:9a:e2:cc:8f:0b:b2:25:77:c4:61:89:
- 89:63:5a:d4:a3:15:40:d4:fb:5e:3f:b4:43:ea:63:17:2b:6b:
- 99:74:9e:09:a8:dd:d4:56:15:2e:7a:79:31:5f:63:96:53:1b:
- 34:d9:15:ea:4f:6d:70:ca:be:f6:82:a9:ed:da:85:77:cc:76:
- 1c:6a:81:0a:21:d8:41:99:7f:5e:2e:82:c1:e8:aa:f7:93:81:
- 05:aa:92:b4:1f:b7:9a:c0:07:17:f5:cb:c6:b4:4c:0e:d7:56:
- dc:71:20:74:38:d6:74:c6:d6:8f:6b:af:8b:8d:a0:6c:29:0b:
- 61:e0
------BEGIN CERTIFICATE-----
-MIIERTCCA66gAwIBAgIQM2VQCHmtc+IwueAdDX+skTANBgkqhkiG9w0BAQUFADCB
-zjELMAkGA1UEBhMCWkExFTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJ
-Q2FwZSBUb3duMR0wGwYDVQQKExRUaGF3dGUgQ29uc3VsdGluZyBjYzEoMCYGA1UE
-CxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjEhMB8GA1UEAxMYVGhh
-d3RlIFByZW1pdW0gU2VydmVyIENBMSgwJgYJKoZIhvcNAQkBFhlwcmVtaXVtLXNl
-cnZlckB0aGF3dGUuY29tMB4XDTA2MTExNzAwMDAwMFoXDTIwMTIzMDIzNTk1OVow
-gakxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwx0aGF3dGUsIEluYy4xKDAmBgNVBAsT
-H0NlcnRpZmljYXRpb24gU2VydmljZXMgRGl2aXNpb24xODA2BgNVBAsTLyhjKSAy
-MDA2IHRoYXd0ZSwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MR8wHQYD
-VQQDExZ0aGF3dGUgUHJpbWFyeSBSb290IENBMIIBIjANBgkqhkiG9w0BAQEFAAOC
-AQ8AMIIBCgKCAQEArKDw+4BZ1JzHpM+doVlzCRBFDA0sbmjxbFtIaElZN/wLMxnC
-d3/MEC2VNBzm600JpxzSuMmXNgK3idQkXwbAzESUlI0CYm/rWt0RjSiaXISQEHoN
-vXRmL2o4oOLVVETrHQefB7pv7un9Tgsp9T6EoAHxnKv4HH6JpOih2HFlDaNRe+68
-0iJgDblbnd+6/FFbC6+Ysuku6QToYofeK8jXTsFMZB7dz4dYukpPymgHHRydSsbV
-L5HMfHFyHMXAZ+sy/cmSXJTahcCbv1N9Kwn0jJ2RH5dqUsveCTakd9h7h1BE1T5u
-KWn7OUkmHgmlgHtALevoJ4XJ/mH9fuZ8lx3VnQIDAQABo4HCMIG/MA8GA1UdEwEB
-/wQFMAMBAf8wOwYDVR0gBDQwMjAwBgRVHSAAMCgwJgYIKwYBBQUHAgEWGmh0dHBz
-Oi8vd3d3LnRoYXd0ZS5jb20vY3BzMA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQU
-e1tFz6/Oy3r9MZIaarbzRutXSFAwQAYDVR0fBDkwNzA1oDOgMYYvaHR0cDovL2Ny
-bC50aGF3dGUuY29tL1RoYXd0ZVByZW1pdW1TZXJ2ZXJDQS5jcmwwDQYJKoZIhvcN
-AQEFBQADgYEAhKhMyT4qvJrizI8LsiV3xGGJiWNa1KMVQNT7Xj+0Q+pjFytrmXSe
-Cajd1FYVLnp5MV9jllMbNNkV6k9tcMq+9oKp7dqFd8x2HGqBCiHYQZl/Xi6Cweiq
-95OBBaqStB+3msAHF/XLxrRMDtdW3HEgdDjWdMbWj2uvi42gbCkLYeA=
------END CERTIFICATE-----
-#endif
-static const unsigned char kDERCert6[] = {
- 0x30, 0x82, 0x04, 0x45, 0x30, 0x82, 0x03, 0xae, 0xa0, 0x03, 0x02, 0x01,
- 0x02, 0x02, 0x10, 0x33, 0x65, 0x50, 0x08, 0x79, 0xad, 0x73, 0xe2, 0x30,
- 0xb9, 0xe0, 0x1d, 0x0d, 0x7f, 0xac, 0x91, 0x30, 0x0d, 0x06, 0x09, 0x2a,
- 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x81,
- 0xce, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
- 0x5a, 0x41, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13,
- 0x0c, 0x57, 0x65, 0x73, 0x74, 0x65, 0x72, 0x6e, 0x20, 0x43, 0x61, 0x70,
- 0x65, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x09,
- 0x43, 0x61, 0x70, 0x65, 0x20, 0x54, 0x6f, 0x77, 0x6e, 0x31, 0x1d, 0x30,
- 0x1b, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x14, 0x54, 0x68, 0x61, 0x77,
- 0x74, 0x65, 0x20, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x74, 0x69, 0x6e,
- 0x67, 0x20, 0x63, 0x63, 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, 0x04,
- 0x0b, 0x13, 0x1f, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61,
- 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
- 0x73, 0x20, 0x44, 0x69, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x31, 0x21,
- 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x18, 0x54, 0x68, 0x61,
- 0x77, 0x74, 0x65, 0x20, 0x50, 0x72, 0x65, 0x6d, 0x69, 0x75, 0x6d, 0x20,
- 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x43, 0x41, 0x31, 0x28, 0x30,
- 0x26, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01,
- 0x16, 0x19, 0x70, 0x72, 0x65, 0x6d, 0x69, 0x75, 0x6d, 0x2d, 0x73, 0x65,
- 0x72, 0x76, 0x65, 0x72, 0x40, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2e,
- 0x63, 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x36, 0x31, 0x31, 0x31,
- 0x37, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x30,
- 0x31, 0x32, 0x33, 0x30, 0x32, 0x33, 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30,
- 0x81, 0xa9, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
- 0x02, 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0a,
- 0x13, 0x0c, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2c, 0x20, 0x49, 0x6e,
- 0x63, 0x2e, 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13,
- 0x1f, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69,
- 0x6f, 0x6e, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20,
- 0x44, 0x69, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x31, 0x38, 0x30, 0x36,
- 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x2f, 0x28, 0x63, 0x29, 0x20, 0x32,
- 0x30, 0x30, 0x36, 0x20, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2c, 0x20,
- 0x49, 0x6e, 0x63, 0x2e, 0x20, 0x2d, 0x20, 0x46, 0x6f, 0x72, 0x20, 0x61,
- 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x20, 0x75, 0x73,
- 0x65, 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03,
- 0x55, 0x04, 0x03, 0x13, 0x16, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x20,
- 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x20, 0x52, 0x6f, 0x6f, 0x74,
- 0x20, 0x43, 0x41, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a,
- 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82,
- 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00,
- 0xac, 0xa0, 0xf0, 0xfb, 0x80, 0x59, 0xd4, 0x9c, 0xc7, 0xa4, 0xcf, 0x9d,
- 0xa1, 0x59, 0x73, 0x09, 0x10, 0x45, 0x0c, 0x0d, 0x2c, 0x6e, 0x68, 0xf1,
- 0x6c, 0x5b, 0x48, 0x68, 0x49, 0x59, 0x37, 0xfc, 0x0b, 0x33, 0x19, 0xc2,
- 0x77, 0x7f, 0xcc, 0x10, 0x2d, 0x95, 0x34, 0x1c, 0xe6, 0xeb, 0x4d, 0x09,
- 0xa7, 0x1c, 0xd2, 0xb8, 0xc9, 0x97, 0x36, 0x02, 0xb7, 0x89, 0xd4, 0x24,
- 0x5f, 0x06, 0xc0, 0xcc, 0x44, 0x94, 0x94, 0x8d, 0x02, 0x62, 0x6f, 0xeb,
- 0x5a, 0xdd, 0x11, 0x8d, 0x28, 0x9a, 0x5c, 0x84, 0x90, 0x10, 0x7a, 0x0d,
- 0xbd, 0x74, 0x66, 0x2f, 0x6a, 0x38, 0xa0, 0xe2, 0xd5, 0x54, 0x44, 0xeb,
- 0x1d, 0x07, 0x9f, 0x07, 0xba, 0x6f, 0xee, 0xe9, 0xfd, 0x4e, 0x0b, 0x29,
- 0xf5, 0x3e, 0x84, 0xa0, 0x01, 0xf1, 0x9c, 0xab, 0xf8, 0x1c, 0x7e, 0x89,
- 0xa4, 0xe8, 0xa1, 0xd8, 0x71, 0x65, 0x0d, 0xa3, 0x51, 0x7b, 0xee, 0xbc,
- 0xd2, 0x22, 0x60, 0x0d, 0xb9, 0x5b, 0x9d, 0xdf, 0xba, 0xfc, 0x51, 0x5b,
- 0x0b, 0xaf, 0x98, 0xb2, 0xe9, 0x2e, 0xe9, 0x04, 0xe8, 0x62, 0x87, 0xde,
- 0x2b, 0xc8, 0xd7, 0x4e, 0xc1, 0x4c, 0x64, 0x1e, 0xdd, 0xcf, 0x87, 0x58,
- 0xba, 0x4a, 0x4f, 0xca, 0x68, 0x07, 0x1d, 0x1c, 0x9d, 0x4a, 0xc6, 0xd5,
- 0x2f, 0x91, 0xcc, 0x7c, 0x71, 0x72, 0x1c, 0xc5, 0xc0, 0x67, 0xeb, 0x32,
- 0xfd, 0xc9, 0x92, 0x5c, 0x94, 0xda, 0x85, 0xc0, 0x9b, 0xbf, 0x53, 0x7d,
- 0x2b, 0x09, 0xf4, 0x8c, 0x9d, 0x91, 0x1f, 0x97, 0x6a, 0x52, 0xcb, 0xde,
- 0x09, 0x36, 0xa4, 0x77, 0xd8, 0x7b, 0x87, 0x50, 0x44, 0xd5, 0x3e, 0x6e,
- 0x29, 0x69, 0xfb, 0x39, 0x49, 0x26, 0x1e, 0x09, 0xa5, 0x80, 0x7b, 0x40,
- 0x2d, 0xeb, 0xe8, 0x27, 0x85, 0xc9, 0xfe, 0x61, 0xfd, 0x7e, 0xe6, 0x7c,
- 0x97, 0x1d, 0xd5, 0x9d, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x81, 0xc2,
- 0x30, 0x81, 0xbf, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01,
- 0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x3b, 0x06, 0x03,
- 0x55, 0x1d, 0x20, 0x04, 0x34, 0x30, 0x32, 0x30, 0x30, 0x06, 0x04, 0x55,
- 0x1d, 0x20, 0x00, 0x30, 0x28, 0x30, 0x26, 0x06, 0x08, 0x2b, 0x06, 0x01,
- 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x1a, 0x68, 0x74, 0x74, 0x70, 0x73,
- 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x74, 0x68, 0x61, 0x77, 0x74,
- 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x70, 0x73, 0x30, 0x0e, 0x06,
- 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01,
- 0x06, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14,
- 0x7b, 0x5b, 0x45, 0xcf, 0xaf, 0xce, 0xcb, 0x7a, 0xfd, 0x31, 0x92, 0x1a,
- 0x6a, 0xb6, 0xf3, 0x46, 0xeb, 0x57, 0x48, 0x50, 0x30, 0x40, 0x06, 0x03,
- 0x55, 0x1d, 0x1f, 0x04, 0x39, 0x30, 0x37, 0x30, 0x35, 0xa0, 0x33, 0xa0,
- 0x31, 0x86, 0x2f, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72,
- 0x6c, 0x2e, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2e, 0x63, 0x6f, 0x6d,
- 0x2f, 0x54, 0x68, 0x61, 0x77, 0x74, 0x65, 0x50, 0x72, 0x65, 0x6d, 0x69,
- 0x75, 0x6d, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x43, 0x41, 0x2e, 0x63,
- 0x72, 0x6c, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
- 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x81, 0x81, 0x00, 0x84, 0xa8, 0x4c,
- 0xc9, 0x3e, 0x2a, 0xbc, 0x9a, 0xe2, 0xcc, 0x8f, 0x0b, 0xb2, 0x25, 0x77,
- 0xc4, 0x61, 0x89, 0x89, 0x63, 0x5a, 0xd4, 0xa3, 0x15, 0x40, 0xd4, 0xfb,
- 0x5e, 0x3f, 0xb4, 0x43, 0xea, 0x63, 0x17, 0x2b, 0x6b, 0x99, 0x74, 0x9e,
- 0x09, 0xa8, 0xdd, 0xd4, 0x56, 0x15, 0x2e, 0x7a, 0x79, 0x31, 0x5f, 0x63,
- 0x96, 0x53, 0x1b, 0x34, 0xd9, 0x15, 0xea, 0x4f, 0x6d, 0x70, 0xca, 0xbe,
- 0xf6, 0x82, 0xa9, 0xed, 0xda, 0x85, 0x77, 0xcc, 0x76, 0x1c, 0x6a, 0x81,
- 0x0a, 0x21, 0xd8, 0x41, 0x99, 0x7f, 0x5e, 0x2e, 0x82, 0xc1, 0xe8, 0xaa,
- 0xf7, 0x93, 0x81, 0x05, 0xaa, 0x92, 0xb4, 0x1f, 0xb7, 0x9a, 0xc0, 0x07,
- 0x17, 0xf5, 0xcb, 0xc6, 0xb4, 0x4c, 0x0e, 0xd7, 0x56, 0xdc, 0x71, 0x20,
- 0x74, 0x38, 0xd6, 0x74, 0xc6, 0xd6, 0x8f, 0x6b, 0xaf, 0x8b, 0x8d, 0xa0,
- 0x6c, 0x29, 0x0b, 0x61, 0xe0,
-};
-
-#if 0
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number:
- 06:7f:94:57:85:87:e8:ac:77:de:b2:53:32:5b:bc:99:8b:56:0d
- Signature Algorithm: sha256WithRSAEncryption
- Issuer: C=US, O=Amazon, CN=Amazon Root CA 1
- Validity
- Not Before: Oct 22 00:00:00 2015 GMT
- Not After : Oct 19 00:00:00 2025 GMT
- Subject: C=US, O=Amazon, OU=Server CA 1B, CN=Amazon
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:c2:4e:16:67:dd:ce:bc:6a:c8:37:5a:ec:3a:30:
- b0:1d:e6:d1:12:e8:12:28:48:cc:e8:29:c1:b9:6e:
- 53:d5:a3:eb:03:39:1a:cc:77:87:f6:01:b9:d9:70:
- cc:cf:6b:8d:e3:e3:03:71:86:99:6d:cb:a6:94:2a:
- 4e:13:d6:a7:bd:04:ec:0a:16:3c:0a:eb:39:b1:c4:
- b5:58:a3:b6:c7:56:25:ec:3e:52:7a:a8:e3:29:16:
- 07:b9:6e:50:cf:fb:5f:31:f8:1d:ba:03:4a:62:89:
- 03:ae:3e:47:f2:0f:27:91:e3:14:20:85:f8:fa:e9:
- 8a:35:f5:5f:9e:99:4d:e7:6b:37:ef:a4:50:3e:44:
- ec:fa:5a:85:66:07:9c:7e:17:6a:55:f3:17:8a:35:
- 1e:ee:e9:ac:c3:75:4e:58:55:7d:53:6b:0a:6b:9b:
- 14:42:d7:e5:ac:01:89:b3:ea:a3:fe:cf:c0:2b:0c:
- 84:c2:d8:53:15:cb:67:f0:d0:88:ca:3a:d1:17:73:
- f5:5f:9a:d4:c5:72:1e:7e:01:f1:98:30:63:2a:aa:
- f2:7a:2d:c5:e2:02:1a:86:e5:32:3e:0e:bd:11:b4:
- cf:3c:93:ef:17:50:10:9e:43:c2:06:2a:e0:0d:68:
- be:d3:88:8b:4a:65:8c:4a:d4:c3:2e:4c:9b:55:f4:
- 86:e5
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Basic Constraints: critical
- CA:TRUE, pathlen:0
- X509v3 Key Usage: critical
- Digital Signature, Certificate Sign, CRL Sign
- X509v3 Subject Key Identifier:
- 59:A4:66:06:52:A0:7B:95:92:3C:A3:94:07:27:96:74:5B:F9:3D:D0
- X509v3 Authority Key Identifier:
- keyid:84:18:CC:85:34:EC:BC:0C:94:94:2E:08:59:9C:C7:B2:10:4E:0A:08
-
- Authority Information Access:
- OCSP - URI:http://ocsp.rootca1.amazontrust.com
- CA Issuers - URI:http://crt.rootca1.amazontrust.com/rootca1.cer
-
- X509v3 CRL Distribution Points:
-
- Full Name:
- URI:http://crl.rootca1.amazontrust.com/rootca1.crl
-
- X509v3 Certificate Policies:
- Policy: 2.23.140.1.2.1
-
- Signature Algorithm: sha256WithRSAEncryption
- 85:92:be:35:bb:79:cf:a3:81:42:1c:e4:e3:63:73:53:39:52:
- 35:e7:d1:ad:fd:ae:99:8a:ac:89:12:2f:bb:e7:6f:9a:d5:4e:
- 72:ea:20:30:61:f9:97:b2:cd:a5:27:02:45:a8:ca:76:3e:98:
- 4a:83:9e:b6:e6:45:e0:f2:43:f6:08:de:6d:e8:6e:db:31:07:
- 13:f0:2f:31:0d:93:6d:61:37:7b:58:f0:fc:51:98:91:28:02:
- 4f:05:76:b7:d3:f0:1b:c2:e6:5e:d0:66:85:11:0f:2e:81:c6:
- 10:81:29:fe:20:60:48:f3:f2:f0:84:13:53:65:35:15:11:6b:
- 82:51:40:55:57:5f:18:b5:b0:22:3e:ad:f2:5e:a3:01:e3:c3:
- b3:f9:cb:41:5a:e6:52:91:bb:e4:36:87:4f:2d:a9:a4:07:68:
- 35:ba:94:72:cd:0e:ea:0e:7d:57:f2:79:fc:37:c5:7b:60:9e:
- b2:eb:c0:2d:90:77:0d:49:10:27:a5:38:ad:c4:12:a3:b4:a3:
- c8:48:b3:15:0b:1e:e2:e2:19:dc:c4:76:52:c8:bc:8a:41:78:
- 70:d9:6d:97:b3:4a:8b:78:2d:5e:b4:0f:a3:4c:60:ca:e1:47:
- cb:78:2d:12:17:b1:52:8b:ca:39:2c:bd:b5:2f:c2:33:02:96:
- ab:da:94:7f
------BEGIN CERTIFICATE-----
-MIIESTCCAzGgAwIBAgITBn+UV4WH6Kx33rJTMlu8mYtWDTANBgkqhkiG9w0BAQsF
-ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6
-b24gUm9vdCBDQSAxMB4XDTE1MTAyMjAwMDAwMFoXDTI1MTAxOTAwMDAwMFowRjEL
-MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEVMBMGA1UECxMMU2VydmVyIENB
-IDFCMQ8wDQYDVQQDEwZBbWF6b24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
-AoIBAQDCThZn3c68asg3Wuw6MLAd5tES6BIoSMzoKcG5blPVo+sDORrMd4f2AbnZ
-cMzPa43j4wNxhplty6aUKk4T1qe9BOwKFjwK6zmxxLVYo7bHViXsPlJ6qOMpFge5
-blDP+18x+B26A0piiQOuPkfyDyeR4xQghfj66Yo19V+emU3nazfvpFA+ROz6WoVm
-B5x+F2pV8xeKNR7u6azDdU5YVX1TawprmxRC1+WsAYmz6qP+z8ArDITC2FMVy2fw
-0IjKOtEXc/VfmtTFch5+AfGYMGMqqvJ6LcXiAhqG5TI+Dr0RtM88k+8XUBCeQ8IG
-KuANaL7TiItKZYxK1MMuTJtV9IblAgMBAAGjggE7MIIBNzASBgNVHRMBAf8ECDAG
-AQH/AgEAMA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUWaRmBlKge5WSPKOUByeW
-dFv5PdAwHwYDVR0jBBgwFoAUhBjMhTTsvAyUlC4IWZzHshBOCggwewYIKwYBBQUH
-AQEEbzBtMC8GCCsGAQUFBzABhiNodHRwOi8vb2NzcC5yb290Y2ExLmFtYXpvbnRy
-dXN0LmNvbTA6BggrBgEFBQcwAoYuaHR0cDovL2NydC5yb290Y2ExLmFtYXpvbnRy
-dXN0LmNvbS9yb290Y2ExLmNlcjA/BgNVHR8EODA2MDSgMqAwhi5odHRwOi8vY3Js
-LnJvb3RjYTEuYW1hem9udHJ1c3QuY29tL3Jvb3RjYTEuY3JsMBMGA1UdIAQMMAow
-CAYGZ4EMAQIBMA0GCSqGSIb3DQEBCwUAA4IBAQCFkr41u3nPo4FCHOTjY3NTOVI1
-59Gt/a6ZiqyJEi+752+a1U5y6iAwYfmXss2lJwJFqMp2PphKg5625kXg8kP2CN5t
-6G7bMQcT8C8xDZNtYTd7WPD8UZiRKAJPBXa30/AbwuZe0GaFEQ8ugcYQgSn+IGBI
-8/LwhBNTZTUVEWuCUUBVV18YtbAiPq3yXqMB48Oz+ctBWuZSkbvkNodPLamkB2g1
-upRyzQ7qDn1X8nn8N8V7YJ6y68AtkHcNSRAnpTitxBKjtKPISLMVCx7i4hncxHZS
-yLyKQXhw2W2Xs0qLeC1etA+jTGDK4UfLeC0SF7FSi8o5LL21L8IzApar2pR/
------END CERTIFICATE-----
-#endif
-static const unsigned char kDERCert7[] = {
- 0x30, 0x82, 0x04, 0x49, 0x30, 0x82, 0x03, 0x31, 0xa0, 0x03, 0x02, 0x01,
- 0x02, 0x02, 0x13, 0x06, 0x7f, 0x94, 0x57, 0x85, 0x87, 0xe8, 0xac, 0x77,
- 0xde, 0xb2, 0x53, 0x32, 0x5b, 0xbc, 0x99, 0x8b, 0x56, 0x0d, 0x30, 0x0d,
- 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05,
- 0x00, 0x30, 0x39, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06,
- 0x13, 0x02, 0x55, 0x53, 0x31, 0x0f, 0x30, 0x0d, 0x06, 0x03, 0x55, 0x04,
- 0x0a, 0x13, 0x06, 0x41, 0x6d, 0x61, 0x7a, 0x6f, 0x6e, 0x31, 0x19, 0x30,
- 0x17, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x10, 0x41, 0x6d, 0x61, 0x7a,
- 0x6f, 0x6e, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41, 0x20, 0x31,
- 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x35, 0x31, 0x30, 0x32, 0x32, 0x30, 0x30,
- 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x35, 0x31, 0x30, 0x31,
- 0x39, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x46, 0x31, 0x0b,
- 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31,
- 0x0f, 0x30, 0x0d, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x06, 0x41, 0x6d,
- 0x61, 0x7a, 0x6f, 0x6e, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04,
- 0x0b, 0x13, 0x0c, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x43, 0x41,
- 0x20, 0x31, 0x42, 0x31, 0x0f, 0x30, 0x0d, 0x06, 0x03, 0x55, 0x04, 0x03,
- 0x13, 0x06, 0x41, 0x6d, 0x61, 0x7a, 0x6f, 0x6e, 0x30, 0x82, 0x01, 0x22,
- 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
- 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a,
- 0x02, 0x82, 0x01, 0x01, 0x00, 0xc2, 0x4e, 0x16, 0x67, 0xdd, 0xce, 0xbc,
- 0x6a, 0xc8, 0x37, 0x5a, 0xec, 0x3a, 0x30, 0xb0, 0x1d, 0xe6, 0xd1, 0x12,
- 0xe8, 0x12, 0x28, 0x48, 0xcc, 0xe8, 0x29, 0xc1, 0xb9, 0x6e, 0x53, 0xd5,
- 0xa3, 0xeb, 0x03, 0x39, 0x1a, 0xcc, 0x77, 0x87, 0xf6, 0x01, 0xb9, 0xd9,
- 0x70, 0xcc, 0xcf, 0x6b, 0x8d, 0xe3, 0xe3, 0x03, 0x71, 0x86, 0x99, 0x6d,
- 0xcb, 0xa6, 0x94, 0x2a, 0x4e, 0x13, 0xd6, 0xa7, 0xbd, 0x04, 0xec, 0x0a,
- 0x16, 0x3c, 0x0a, 0xeb, 0x39, 0xb1, 0xc4, 0xb5, 0x58, 0xa3, 0xb6, 0xc7,
- 0x56, 0x25, 0xec, 0x3e, 0x52, 0x7a, 0xa8, 0xe3, 0x29, 0x16, 0x07, 0xb9,
- 0x6e, 0x50, 0xcf, 0xfb, 0x5f, 0x31, 0xf8, 0x1d, 0xba, 0x03, 0x4a, 0x62,
- 0x89, 0x03, 0xae, 0x3e, 0x47, 0xf2, 0x0f, 0x27, 0x91, 0xe3, 0x14, 0x20,
- 0x85, 0xf8, 0xfa, 0xe9, 0x8a, 0x35, 0xf5, 0x5f, 0x9e, 0x99, 0x4d, 0xe7,
- 0x6b, 0x37, 0xef, 0xa4, 0x50, 0x3e, 0x44, 0xec, 0xfa, 0x5a, 0x85, 0x66,
- 0x07, 0x9c, 0x7e, 0x17, 0x6a, 0x55, 0xf3, 0x17, 0x8a, 0x35, 0x1e, 0xee,
- 0xe9, 0xac, 0xc3, 0x75, 0x4e, 0x58, 0x55, 0x7d, 0x53, 0x6b, 0x0a, 0x6b,
- 0x9b, 0x14, 0x42, 0xd7, 0xe5, 0xac, 0x01, 0x89, 0xb3, 0xea, 0xa3, 0xfe,
- 0xcf, 0xc0, 0x2b, 0x0c, 0x84, 0xc2, 0xd8, 0x53, 0x15, 0xcb, 0x67, 0xf0,
- 0xd0, 0x88, 0xca, 0x3a, 0xd1, 0x17, 0x73, 0xf5, 0x5f, 0x9a, 0xd4, 0xc5,
- 0x72, 0x1e, 0x7e, 0x01, 0xf1, 0x98, 0x30, 0x63, 0x2a, 0xaa, 0xf2, 0x7a,
- 0x2d, 0xc5, 0xe2, 0x02, 0x1a, 0x86, 0xe5, 0x32, 0x3e, 0x0e, 0xbd, 0x11,
- 0xb4, 0xcf, 0x3c, 0x93, 0xef, 0x17, 0x50, 0x10, 0x9e, 0x43, 0xc2, 0x06,
- 0x2a, 0xe0, 0x0d, 0x68, 0xbe, 0xd3, 0x88, 0x8b, 0x4a, 0x65, 0x8c, 0x4a,
- 0xd4, 0xc3, 0x2e, 0x4c, 0x9b, 0x55, 0xf4, 0x86, 0xe5, 0x02, 0x03, 0x01,
- 0x00, 0x01, 0xa3, 0x82, 0x01, 0x3b, 0x30, 0x82, 0x01, 0x37, 0x30, 0x12,
- 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06,
- 0x01, 0x01, 0xff, 0x02, 0x01, 0x00, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d,
- 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x86, 0x30, 0x1d,
- 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x59, 0xa4, 0x66,
- 0x06, 0x52, 0xa0, 0x7b, 0x95, 0x92, 0x3c, 0xa3, 0x94, 0x07, 0x27, 0x96,
- 0x74, 0x5b, 0xf9, 0x3d, 0xd0, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23,
- 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x84, 0x18, 0xcc, 0x85, 0x34, 0xec,
- 0xbc, 0x0c, 0x94, 0x94, 0x2e, 0x08, 0x59, 0x9c, 0xc7, 0xb2, 0x10, 0x4e,
- 0x0a, 0x08, 0x30, 0x7b, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
- 0x01, 0x01, 0x04, 0x6f, 0x30, 0x6d, 0x30, 0x2f, 0x06, 0x08, 0x2b, 0x06,
- 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x23, 0x68, 0x74, 0x74, 0x70,
- 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x72, 0x6f, 0x6f, 0x74,
- 0x63, 0x61, 0x31, 0x2e, 0x61, 0x6d, 0x61, 0x7a, 0x6f, 0x6e, 0x74, 0x72,
- 0x75, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x3a, 0x06, 0x08, 0x2b,
- 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x2e, 0x68, 0x74, 0x74,
- 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x74, 0x2e, 0x72, 0x6f, 0x6f, 0x74,
- 0x63, 0x61, 0x31, 0x2e, 0x61, 0x6d, 0x61, 0x7a, 0x6f, 0x6e, 0x74, 0x72,
- 0x75, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x6f, 0x6f, 0x74,
- 0x63, 0x61, 0x31, 0x2e, 0x63, 0x65, 0x72, 0x30, 0x3f, 0x06, 0x03, 0x55,
- 0x1d, 0x1f, 0x04, 0x38, 0x30, 0x36, 0x30, 0x34, 0xa0, 0x32, 0xa0, 0x30,
- 0x86, 0x2e, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c,
- 0x2e, 0x72, 0x6f, 0x6f, 0x74, 0x63, 0x61, 0x31, 0x2e, 0x61, 0x6d, 0x61,
- 0x7a, 0x6f, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d,
- 0x2f, 0x72, 0x6f, 0x6f, 0x74, 0x63, 0x61, 0x31, 0x2e, 0x63, 0x72, 0x6c,
- 0x30, 0x13, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x0c, 0x30, 0x0a, 0x30,
- 0x08, 0x06, 0x06, 0x67, 0x81, 0x0c, 0x01, 0x02, 0x01, 0x30, 0x0d, 0x06,
- 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00,
- 0x03, 0x82, 0x01, 0x01, 0x00, 0x85, 0x92, 0xbe, 0x35, 0xbb, 0x79, 0xcf,
- 0xa3, 0x81, 0x42, 0x1c, 0xe4, 0xe3, 0x63, 0x73, 0x53, 0x39, 0x52, 0x35,
- 0xe7, 0xd1, 0xad, 0xfd, 0xae, 0x99, 0x8a, 0xac, 0x89, 0x12, 0x2f, 0xbb,
- 0xe7, 0x6f, 0x9a, 0xd5, 0x4e, 0x72, 0xea, 0x20, 0x30, 0x61, 0xf9, 0x97,
- 0xb2, 0xcd, 0xa5, 0x27, 0x02, 0x45, 0xa8, 0xca, 0x76, 0x3e, 0x98, 0x4a,
- 0x83, 0x9e, 0xb6, 0xe6, 0x45, 0xe0, 0xf2, 0x43, 0xf6, 0x08, 0xde, 0x6d,
- 0xe8, 0x6e, 0xdb, 0x31, 0x07, 0x13, 0xf0, 0x2f, 0x31, 0x0d, 0x93, 0x6d,
- 0x61, 0x37, 0x7b, 0x58, 0xf0, 0xfc, 0x51, 0x98, 0x91, 0x28, 0x02, 0x4f,
- 0x05, 0x76, 0xb7, 0xd3, 0xf0, 0x1b, 0xc2, 0xe6, 0x5e, 0xd0, 0x66, 0x85,
- 0x11, 0x0f, 0x2e, 0x81, 0xc6, 0x10, 0x81, 0x29, 0xfe, 0x20, 0x60, 0x48,
- 0xf3, 0xf2, 0xf0, 0x84, 0x13, 0x53, 0x65, 0x35, 0x15, 0x11, 0x6b, 0x82,
- 0x51, 0x40, 0x55, 0x57, 0x5f, 0x18, 0xb5, 0xb0, 0x22, 0x3e, 0xad, 0xf2,
- 0x5e, 0xa3, 0x01, 0xe3, 0xc3, 0xb3, 0xf9, 0xcb, 0x41, 0x5a, 0xe6, 0x52,
- 0x91, 0xbb, 0xe4, 0x36, 0x87, 0x4f, 0x2d, 0xa9, 0xa4, 0x07, 0x68, 0x35,
- 0xba, 0x94, 0x72, 0xcd, 0x0e, 0xea, 0x0e, 0x7d, 0x57, 0xf2, 0x79, 0xfc,
- 0x37, 0xc5, 0x7b, 0x60, 0x9e, 0xb2, 0xeb, 0xc0, 0x2d, 0x90, 0x77, 0x0d,
- 0x49, 0x10, 0x27, 0xa5, 0x38, 0xad, 0xc4, 0x12, 0xa3, 0xb4, 0xa3, 0xc8,
- 0x48, 0xb3, 0x15, 0x0b, 0x1e, 0xe2, 0xe2, 0x19, 0xdc, 0xc4, 0x76, 0x52,
- 0xc8, 0xbc, 0x8a, 0x41, 0x78, 0x70, 0xd9, 0x6d, 0x97, 0xb3, 0x4a, 0x8b,
- 0x78, 0x2d, 0x5e, 0xb4, 0x0f, 0xa3, 0x4c, 0x60, 0xca, 0xe1, 0x47, 0xcb,
- 0x78, 0x2d, 0x12, 0x17, 0xb1, 0x52, 0x8b, 0xca, 0x39, 0x2c, 0xbd, 0xb5,
- 0x2f, 0xc2, 0x33, 0x02, 0x96, 0xab, 0xda, 0x94, 0x7f,
-};
-
-#if 0
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number: 146033 (0x23a71)
- Signature Algorithm: sha256WithRSAEncryption
- Issuer: C=US, O=GeoTrust Inc., CN=GeoTrust Global CA
- Validity
- Not Before: Dec 11 23:45:51 2013 GMT
- Not After : May 20 23:45:51 2022 GMT
- Subject: C=US, O=GeoTrust Inc., CN=RapidSSL SHA256 CA
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:bb:58:c1:12:01:2e:97:d8:7d:18:aa:c8:c2:e5:
- 85:e2:17:6c:60:2e:c9:8d:31:05:39:1a:06:98:56:
- dd:54:d7:11:8c:59:5b:3d:b1:54:ae:4b:21:85:32:
- 16:5f:54:86:e6:d9:b1:d8:60:89:6b:58:be:72:da:
- a0:00:42:76:b1:27:59:4c:cd:e3:ba:d4:5c:d9:a6:
- 7f:bb:2b:75:d5:46:44:bd:ec:40:5c:59:b7:dd:59:
- 9f:f1:6a:f7:06:fc:d6:2f:19:8a:95:12:ba:9a:ca:
- d5:30:d2:38:fc:19:3b:5b:15:3b:36:d0:43:4d:d1:
- 65:a1:d4:8b:c1:60:41:b3:d6:70:17:cc:39:c0:9c:
- 0c:a0:3d:b7:11:22:4e:ce:d9:a9:7a:d2:2a:62:9c:
- a0:0b:4e:2a:d7:c3:61:5a:85:dd:5c:10:b9:54:3d:
- 2d:03:f8:49:f0:bc:92:b7:b7:9c:31:c7:e9:b8:aa:
- 82:0b:05:b9:31:cd:08:5b:bb:22:0b:f6:9c:8e:8a:
- 55:1c:76:43:76:f0:e2:6e:f0:df:a8:29:75:e7:c8:
- a4:87:8b:6a:f1:bb:08:c9:36:18:65:ee:50:43:b8:
- 5d:72:d5:28:39:e1:53:3e:25:2c:da:2b:4f:dd:8a:
- 9e:50:50:e0:6f:9a:c4:d5:19:26:89:01:75:73:09:
- 9b:3b
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Authority Key Identifier:
- keyid:C0:7A:98:68:8D:89:FB:AB:05:64:0C:11:7D:AA:7D:65:B8:CA:CC:4E
-
- X509v3 Subject Key Identifier:
- 97:C2:27:50:9E:C2:C9:EC:0C:88:32:C8:7C:AD:E2:A6:01:4F:DA:6F
- X509v3 Basic Constraints: critical
- CA:TRUE, pathlen:0
- X509v3 Key Usage: critical
- Certificate Sign, CRL Sign
- X509v3 CRL Distribution Points:
-
- Full Name:
- URI:http://g1.symcb.com/crls/gtglobal.crl
-
- Authority Information Access:
- OCSP - URI:http://g2.symcb.com
-
- X509v3 Certificate Policies:
- Policy: 2.16.840.1.113733.1.7.54
- CPS: http://www.geotrust.com/resources/cps
-
- X509v3 Subject Alternative Name:
- DirName:/CN=SymantecPKI-1-569
- Signature Algorithm: sha256WithRSAEncryption
- 35:eb:e1:8b:20:56:94:ba:7a:bd:79:a9:f6:e3:fe:6e:38:b4:
- 32:c1:a3:db:58:56:20:3e:7d:c7:3a:b1:67:69:d5:79:14:1b:
- f6:fa:ec:60:f2:79:cd:0a:0c:60:8a:74:4c:a3:93:2a:a0:f0:
- 51:7f:cd:e9:f9:92:fd:96:ab:45:f5:62:3d:3f:60:46:50:13:
- 3d:20:13:18:2e:94:46:ae:d5:21:fe:43:a1:c9:23:fe:53:c4:
- bf:1a:d8:ac:3a:ca:de:66:97:23:ae:d3:df:4a:4d:73:1f:6f:
- 31:a2:51:04:16:6a:00:eb:f9:8d:43:81:f0:50:a1:1f:a6:ca:
- 3a:f3:28:3c:5f:51:ac:d7:0a:45:77:4b:0e:52:62:1b:d8:38:
- 51:a0:92:2d:3f:90:6e:c8:7e:40:9f:20:46:15:5d:e0:50:7c:
- e1:76:af:5e:ed:11:d3:2f:13:b9:b8:25:a4:af:58:09:af:35:
- b4:62:54:85:e3:48:de:bc:d2:90:7a:7a:a4:84:0d:a3:42:f2:
- 51:c0:d4:ad:53:65:5d:6c:f8:3f:1f:06:f2:4f:cb:97:a0:4a:
- 59:c6:78:d1:e8:03:b9:85:6d:2c:ba:e1:5f:b6:ad:2b:3e:25:
- 79:c5:8b:56:d5:e3:09:80:ea:c1:27:c2:d9:0e:ec:47:0a:e9:
- d0:ca:fc:d8
------BEGIN CERTIFICATE-----
-MIIETTCCAzWgAwIBAgIDAjpxMA0GCSqGSIb3DQEBCwUAMEIxCzAJBgNVBAYTAlVT
-MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i
-YWwgQ0EwHhcNMTMxMjExMjM0NTUxWhcNMjIwNTIwMjM0NTUxWjBCMQswCQYDVQQG
-EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEbMBkGA1UEAxMSUmFwaWRTU0wg
-U0hBMjU2IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAu1jBEgEu
-l9h9GKrIwuWF4hdsYC7JjTEFORoGmFbdVNcRjFlbPbFUrkshhTIWX1SG5tmx2GCJ
-a1i+ctqgAEJ2sSdZTM3jutRc2aZ/uyt11UZEvexAXFm33Vmf8Wr3BvzWLxmKlRK6
-msrVMNI4/Bk7WxU7NtBDTdFlodSLwWBBs9ZwF8w5wJwMoD23ESJOztmpetIqYpyg
-C04q18NhWoXdXBC5VD0tA/hJ8LySt7ecMcfpuKqCCwW5Mc0IW7siC/acjopVHHZD
-dvDibvDfqCl158ikh4tq8bsIyTYYZe5QQ7hdctUoOeFTPiUs2itP3YqeUFDgb5rE
-1RkmiQF1cwmbOwIDAQABo4IBSjCCAUYwHwYDVR0jBBgwFoAUwHqYaI2J+6sFZAwR
-fap9ZbjKzE4wHQYDVR0OBBYEFJfCJ1CewsnsDIgyyHyt4qYBT9pvMBIGA1UdEwEB
-/wQIMAYBAf8CAQAwDgYDVR0PAQH/BAQDAgEGMDYGA1UdHwQvMC0wK6ApoCeGJWh0
-dHA6Ly9nMS5zeW1jYi5jb20vY3Jscy9ndGdsb2JhbC5jcmwwLwYIKwYBBQUHAQEE
-IzAhMB8GCCsGAQUFBzABhhNodHRwOi8vZzIuc3ltY2IuY29tMEwGA1UdIARFMEMw
-QQYKYIZIAYb4RQEHNjAzMDEGCCsGAQUFBwIBFiVodHRwOi8vd3d3Lmdlb3RydXN0
-LmNvbS9yZXNvdXJjZXMvY3BzMCkGA1UdEQQiMCCkHjAcMRowGAYDVQQDExFTeW1h
-bnRlY1BLSS0xLTU2OTANBgkqhkiG9w0BAQsFAAOCAQEANevhiyBWlLp6vXmp9uP+
-bji0MsGj21hWID59xzqxZ2nVeRQb9vrsYPJ5zQoMYIp0TKOTKqDwUX/N6fmS/Zar
-RfViPT9gRlATPSATGC6URq7VIf5Dockj/lPEvxrYrDrK3maXI67T30pNcx9vMaJR
-BBZqAOv5jUOB8FChH6bKOvMoPF9RrNcKRXdLDlJiG9g4UaCSLT+Qbsh+QJ8gRhVd
-4FB84XavXu0R0y8TubglpK9YCa81tGJUheNI3rzSkHp6pIQNo0LyUcDUrVNlXWz4
-Px8G8k/Ll6BKWcZ40egDuYVtLLrhX7atKz4lecWLVtXjCYDqwSfC2Q7sRwrp0Mr8
-2A==
------END CERTIFICATE-----
-#endif
-static const unsigned char kDERCert8[] = {
- 0x30, 0x82, 0x04, 0x4d, 0x30, 0x82, 0x03, 0x35, 0xa0, 0x03, 0x02, 0x01,
- 0x02, 0x02, 0x03, 0x02, 0x3a, 0x71, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
- 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x42, 0x31,
- 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53,
- 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0d, 0x47,
- 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x49, 0x6e, 0x63, 0x2e,
- 0x31, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x12, 0x47,
- 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x47, 0x6c, 0x6f, 0x62,
- 0x61, 0x6c, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x33, 0x31,
- 0x32, 0x31, 0x31, 0x32, 0x33, 0x34, 0x35, 0x35, 0x31, 0x5a, 0x17, 0x0d,
- 0x32, 0x32, 0x30, 0x35, 0x32, 0x30, 0x32, 0x33, 0x34, 0x35, 0x35, 0x31,
- 0x5a, 0x30, 0x42, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06,
- 0x13, 0x02, 0x55, 0x53, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04,
- 0x0a, 0x13, 0x0d, 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20,
- 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04,
- 0x03, 0x13, 0x12, 0x52, 0x61, 0x70, 0x69, 0x64, 0x53, 0x53, 0x4c, 0x20,
- 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, 0x20, 0x43, 0x41, 0x30, 0x82, 0x01,
- 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
- 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01,
- 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xbb, 0x58, 0xc1, 0x12, 0x01, 0x2e,
- 0x97, 0xd8, 0x7d, 0x18, 0xaa, 0xc8, 0xc2, 0xe5, 0x85, 0xe2, 0x17, 0x6c,
- 0x60, 0x2e, 0xc9, 0x8d, 0x31, 0x05, 0x39, 0x1a, 0x06, 0x98, 0x56, 0xdd,
- 0x54, 0xd7, 0x11, 0x8c, 0x59, 0x5b, 0x3d, 0xb1, 0x54, 0xae, 0x4b, 0x21,
- 0x85, 0x32, 0x16, 0x5f, 0x54, 0x86, 0xe6, 0xd9, 0xb1, 0xd8, 0x60, 0x89,
- 0x6b, 0x58, 0xbe, 0x72, 0xda, 0xa0, 0x00, 0x42, 0x76, 0xb1, 0x27, 0x59,
- 0x4c, 0xcd, 0xe3, 0xba, 0xd4, 0x5c, 0xd9, 0xa6, 0x7f, 0xbb, 0x2b, 0x75,
- 0xd5, 0x46, 0x44, 0xbd, 0xec, 0x40, 0x5c, 0x59, 0xb7, 0xdd, 0x59, 0x9f,
- 0xf1, 0x6a, 0xf7, 0x06, 0xfc, 0xd6, 0x2f, 0x19, 0x8a, 0x95, 0x12, 0xba,
- 0x9a, 0xca, 0xd5, 0x30, 0xd2, 0x38, 0xfc, 0x19, 0x3b, 0x5b, 0x15, 0x3b,
- 0x36, 0xd0, 0x43, 0x4d, 0xd1, 0x65, 0xa1, 0xd4, 0x8b, 0xc1, 0x60, 0x41,
- 0xb3, 0xd6, 0x70, 0x17, 0xcc, 0x39, 0xc0, 0x9c, 0x0c, 0xa0, 0x3d, 0xb7,
- 0x11, 0x22, 0x4e, 0xce, 0xd9, 0xa9, 0x7a, 0xd2, 0x2a, 0x62, 0x9c, 0xa0,
- 0x0b, 0x4e, 0x2a, 0xd7, 0xc3, 0x61, 0x5a, 0x85, 0xdd, 0x5c, 0x10, 0xb9,
- 0x54, 0x3d, 0x2d, 0x03, 0xf8, 0x49, 0xf0, 0xbc, 0x92, 0xb7, 0xb7, 0x9c,
- 0x31, 0xc7, 0xe9, 0xb8, 0xaa, 0x82, 0x0b, 0x05, 0xb9, 0x31, 0xcd, 0x08,
- 0x5b, 0xbb, 0x22, 0x0b, 0xf6, 0x9c, 0x8e, 0x8a, 0x55, 0x1c, 0x76, 0x43,
- 0x76, 0xf0, 0xe2, 0x6e, 0xf0, 0xdf, 0xa8, 0x29, 0x75, 0xe7, 0xc8, 0xa4,
- 0x87, 0x8b, 0x6a, 0xf1, 0xbb, 0x08, 0xc9, 0x36, 0x18, 0x65, 0xee, 0x50,
- 0x43, 0xb8, 0x5d, 0x72, 0xd5, 0x28, 0x39, 0xe1, 0x53, 0x3e, 0x25, 0x2c,
- 0xda, 0x2b, 0x4f, 0xdd, 0x8a, 0x9e, 0x50, 0x50, 0xe0, 0x6f, 0x9a, 0xc4,
- 0xd5, 0x19, 0x26, 0x89, 0x01, 0x75, 0x73, 0x09, 0x9b, 0x3b, 0x02, 0x03,
- 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x4a, 0x30, 0x82, 0x01, 0x46, 0x30,
- 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14,
- 0xc0, 0x7a, 0x98, 0x68, 0x8d, 0x89, 0xfb, 0xab, 0x05, 0x64, 0x0c, 0x11,
- 0x7d, 0xaa, 0x7d, 0x65, 0xb8, 0xca, 0xcc, 0x4e, 0x30, 0x1d, 0x06, 0x03,
- 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x97, 0xc2, 0x27, 0x50, 0x9e,
- 0xc2, 0xc9, 0xec, 0x0c, 0x88, 0x32, 0xc8, 0x7c, 0xad, 0xe2, 0xa6, 0x01,
- 0x4f, 0xda, 0x6f, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01,
- 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x00, 0x30,
- 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03,
- 0x02, 0x01, 0x06, 0x30, 0x36, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x2f,
- 0x30, 0x2d, 0x30, 0x2b, 0xa0, 0x29, 0xa0, 0x27, 0x86, 0x25, 0x68, 0x74,
- 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x67, 0x31, 0x2e, 0x73, 0x79, 0x6d, 0x63,
- 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x72, 0x6c, 0x73, 0x2f, 0x67,
- 0x74, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x2e, 0x63, 0x72, 0x6c, 0x30,
- 0x2f, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04,
- 0x23, 0x30, 0x21, 0x30, 0x1f, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05,
- 0x07, 0x30, 0x01, 0x86, 0x13, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f,
- 0x67, 0x32, 0x2e, 0x73, 0x79, 0x6d, 0x63, 0x62, 0x2e, 0x63, 0x6f, 0x6d,
- 0x30, 0x4c, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x45, 0x30, 0x43, 0x30,
- 0x41, 0x06, 0x0a, 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x45, 0x01, 0x07,
- 0x36, 0x30, 0x33, 0x30, 0x31, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05,
- 0x07, 0x02, 0x01, 0x16, 0x25, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f,
- 0x77, 0x77, 0x77, 0x2e, 0x67, 0x65, 0x6f, 0x74, 0x72, 0x75, 0x73, 0x74,
- 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63,
- 0x65, 0x73, 0x2f, 0x63, 0x70, 0x73, 0x30, 0x29, 0x06, 0x03, 0x55, 0x1d,
- 0x11, 0x04, 0x22, 0x30, 0x20, 0xa4, 0x1e, 0x30, 0x1c, 0x31, 0x1a, 0x30,
- 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x11, 0x53, 0x79, 0x6d, 0x61,
- 0x6e, 0x74, 0x65, 0x63, 0x50, 0x4b, 0x49, 0x2d, 0x31, 0x2d, 0x35, 0x36,
- 0x39, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
- 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x35, 0xeb, 0xe1,
- 0x8b, 0x20, 0x56, 0x94, 0xba, 0x7a, 0xbd, 0x79, 0xa9, 0xf6, 0xe3, 0xfe,
- 0x6e, 0x38, 0xb4, 0x32, 0xc1, 0xa3, 0xdb, 0x58, 0x56, 0x20, 0x3e, 0x7d,
- 0xc7, 0x3a, 0xb1, 0x67, 0x69, 0xd5, 0x79, 0x14, 0x1b, 0xf6, 0xfa, 0xec,
- 0x60, 0xf2, 0x79, 0xcd, 0x0a, 0x0c, 0x60, 0x8a, 0x74, 0x4c, 0xa3, 0x93,
- 0x2a, 0xa0, 0xf0, 0x51, 0x7f, 0xcd, 0xe9, 0xf9, 0x92, 0xfd, 0x96, 0xab,
- 0x45, 0xf5, 0x62, 0x3d, 0x3f, 0x60, 0x46, 0x50, 0x13, 0x3d, 0x20, 0x13,
- 0x18, 0x2e, 0x94, 0x46, 0xae, 0xd5, 0x21, 0xfe, 0x43, 0xa1, 0xc9, 0x23,
- 0xfe, 0x53, 0xc4, 0xbf, 0x1a, 0xd8, 0xac, 0x3a, 0xca, 0xde, 0x66, 0x97,
- 0x23, 0xae, 0xd3, 0xdf, 0x4a, 0x4d, 0x73, 0x1f, 0x6f, 0x31, 0xa2, 0x51,
- 0x04, 0x16, 0x6a, 0x00, 0xeb, 0xf9, 0x8d, 0x43, 0x81, 0xf0, 0x50, 0xa1,
- 0x1f, 0xa6, 0xca, 0x3a, 0xf3, 0x28, 0x3c, 0x5f, 0x51, 0xac, 0xd7, 0x0a,
- 0x45, 0x77, 0x4b, 0x0e, 0x52, 0x62, 0x1b, 0xd8, 0x38, 0x51, 0xa0, 0x92,
- 0x2d, 0x3f, 0x90, 0x6e, 0xc8, 0x7e, 0x40, 0x9f, 0x20, 0x46, 0x15, 0x5d,
- 0xe0, 0x50, 0x7c, 0xe1, 0x76, 0xaf, 0x5e, 0xed, 0x11, 0xd3, 0x2f, 0x13,
- 0xb9, 0xb8, 0x25, 0xa4, 0xaf, 0x58, 0x09, 0xaf, 0x35, 0xb4, 0x62, 0x54,
- 0x85, 0xe3, 0x48, 0xde, 0xbc, 0xd2, 0x90, 0x7a, 0x7a, 0xa4, 0x84, 0x0d,
- 0xa3, 0x42, 0xf2, 0x51, 0xc0, 0xd4, 0xad, 0x53, 0x65, 0x5d, 0x6c, 0xf8,
- 0x3f, 0x1f, 0x06, 0xf2, 0x4f, 0xcb, 0x97, 0xa0, 0x4a, 0x59, 0xc6, 0x78,
- 0xd1, 0xe8, 0x03, 0xb9, 0x85, 0x6d, 0x2c, 0xba, 0xe1, 0x5f, 0xb6, 0xad,
- 0x2b, 0x3e, 0x25, 0x79, 0xc5, 0x8b, 0x56, 0xd5, 0xe3, 0x09, 0x80, 0xea,
- 0xc1, 0x27, 0xc2, 0xd9, 0x0e, 0xec, 0x47, 0x0a, 0xe9, 0xd0, 0xca, 0xfc,
- 0xd8,
-};
-
-#if 0
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number:
- 04:00:00:00:00:01:44:4e:f0:36:31
- Signature Algorithm: sha256WithRSAEncryption
- Issuer: C=BE, O=GlobalSign nv-sa, OU=Root CA, CN=GlobalSign Root CA
- Validity
- Not Before: Feb 20 10:00:00 2014 GMT
- Not After : Feb 20 10:00:00 2024 GMT
- Subject: C=BE, O=GlobalSign nv-sa, CN=AlphaSSL CA - SHA256 - G2
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:da:01:ec:e4:ec:73:60:fb:7e:8f:6a:b7:c6:17:
- e3:92:64:32:d4:ac:00:d9:a2:0f:b9:ed:ee:6b:8a:
- 86:ca:92:67:d9:74:d7:5d:47:02:3c:8f:40:d6:9e:
- 6d:14:cd:c3:da:29:39:a7:0f:05:0a:68:a2:66:1a:
- 1e:c4:b2:8b:76:58:e5:ab:5d:1d:8f:40:b3:39:8b:
- ef:1e:83:7d:22:d0:e3:a9:00:2e:ec:53:cf:62:19:
- 85:44:28:4c:c0:27:cb:7b:0e:ec:10:64:00:10:a4:
- 05:cc:a0:72:be:41:6c:31:5b:48:e4:b1:ec:b9:23:
- eb:55:4d:d0:7d:62:4a:a5:b4:a5:a4:59:85:c5:25:
- 91:a6:fe:a6:09:9f:06:10:6d:8f:81:0c:64:40:5e:
- 73:00:9a:e0:2e:65:98:54:10:00:70:98:c8:e1:ed:
- 34:5f:d8:9c:c7:0d:c0:d6:23:59:45:fc:fe:55:7a:
- 86:ee:94:60:22:f1:ae:d1:e6:55:46:f6:99:c5:1b:
- 08:74:5f:ac:b0:64:84:8f:89:38:1c:a1:a7:90:21:
- 4f:02:6e:bd:e0:61:67:d4:f8:42:87:0f:0a:f7:c9:
- 04:6d:2a:a9:2f:ef:42:a5:df:dd:a3:53:db:98:1e:
- 81:f9:9a:72:7b:5a:de:4f:3e:7f:a2:58:a0:e2:17:
- ad:67
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Key Usage: critical
- Certificate Sign, CRL Sign
- X509v3 Basic Constraints: critical
- CA:TRUE, pathlen:0
- X509v3 Subject Key Identifier:
- F5:CD:D5:3C:08:50:F9:6A:4F:3A:B7:97:DA:56:83:E6:69:D2:68:F7
- X509v3 Certificate Policies:
- Policy: X509v3 Any Policy
- CPS: https://www.alphassl.com/repository/
-
- X509v3 CRL Distribution Points:
-
- Full Name:
- URI:http://crl.globalsign.net/root.crl
-
- Authority Information Access:
- OCSP - URI:http://ocsp.globalsign.com/rootr1
-
- X509v3 Authority Key Identifier:
- keyid:60:7B:66:1A:45:0D:97:CA:89:50:2F:7D:04:CD:34:A8:FF:FC:FD:4B
-
- Signature Algorithm: sha256WithRSAEncryption
- 60:40:68:16:47:e7:16:8d:db:5c:a1:56:2a:cb:f4:5c:9b:b0:
- 1e:a2:4b:f5:cb:02:3f:f8:0b:a1:f2:a7:42:d4:b7:4c:eb:e3:
- 66:80:f3:25:43:78:2e:1b:17:56:07:52:18:cb:d1:a8:ec:e6:
- fb:73:3e:a4:62:8c:80:b4:d2:c5:12:73:a3:d3:fa:02:38:be:
- 63:3d:84:b8:99:c1:f1:ba:f7:9f:c3:40:d1:58:18:53:c1:62:
- dd:af:18:42:7f:34:4e:c5:43:d5:71:b0:30:00:c7:e3:90:ae:
- 3f:57:86:97:ce:ea:0c:12:8e:22:70:e3:66:a7:54:7f:2e:28:
- cb:d4:54:d0:b3:1e:62:67:08:f9:27:e1:cb:e3:66:b8:24:1b:
- 89:6a:89:44:65:f2:d9:4c:d2:58:1c:8c:4e:c0:95:a1:d4:ef:
- 67:2f:38:20:e8:2e:ff:96:51:f0:ba:d8:3d:92:70:47:65:1c:
- 9e:73:72:b4:60:0c:5c:e2:d1:73:76:e0:af:4e:e2:e5:37:a5:
- 45:2f:8a:23:3e:87:c7:30:e6:31:38:7c:f4:dd:52:ca:f3:53:
- 04:25:57:56:66:94:e8:0b:ee:e6:03:14:4e:ee:fd:6d:94:64:
- 9e:5e:ce:79:d4:b2:a6:cf:40:b1:44:a8:3e:87:19:5e:e9:f8:
- 21:16:59:53
------BEGIN CERTIFICATE-----
-MIIETTCCAzWgAwIBAgILBAAAAAABRE7wNjEwDQYJKoZIhvcNAQELBQAwVzELMAkG
-A1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jv
-b3QgQ0ExGzAZBgNVBAMTEkdsb2JhbFNpZ24gUm9vdCBDQTAeFw0xNDAyMjAxMDAw
-MDBaFw0yNDAyMjAxMDAwMDBaMEwxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9i
-YWxTaWduIG52LXNhMSIwIAYDVQQDExlBbHBoYVNTTCBDQSAtIFNIQTI1NiAtIEcy
-MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2gHs5OxzYPt+j2q3xhfj
-kmQy1KwA2aIPue3ua4qGypJn2XTXXUcCPI9A1p5tFM3D2ik5pw8FCmiiZhoexLKL
-dljlq10dj0CzOYvvHoN9ItDjqQAu7FPPYhmFRChMwCfLew7sEGQAEKQFzKByvkFs
-MVtI5LHsuSPrVU3QfWJKpbSlpFmFxSWRpv6mCZ8GEG2PgQxkQF5zAJrgLmWYVBAA
-cJjI4e00X9icxw3A1iNZRfz+VXqG7pRgIvGu0eZVRvaZxRsIdF+ssGSEj4k4HKGn
-kCFPAm694GFn1PhChw8K98kEbSqpL+9Cpd/do1PbmB6B+Zpye1reTz5/olig4het
-ZwIDAQABo4IBIzCCAR8wDgYDVR0PAQH/BAQDAgEGMBIGA1UdEwEB/wQIMAYBAf8C
-AQAwHQYDVR0OBBYEFPXN1TwIUPlqTzq3l9pWg+Zp0mj3MEUGA1UdIAQ+MDwwOgYE
-VR0gADAyMDAGCCsGAQUFBwIBFiRodHRwczovL3d3dy5hbHBoYXNzbC5jb20vcmVw
-b3NpdG9yeS8wMwYDVR0fBCwwKjAooCagJIYiaHR0cDovL2NybC5nbG9iYWxzaWdu
-Lm5ldC9yb290LmNybDA9BggrBgEFBQcBAQQxMC8wLQYIKwYBBQUHMAGGIWh0dHA6
-Ly9vY3NwLmdsb2JhbHNpZ24uY29tL3Jvb3RyMTAfBgNVHSMEGDAWgBRge2YaRQ2X
-yolQL30EzTSo//z9SzANBgkqhkiG9w0BAQsFAAOCAQEAYEBoFkfnFo3bXKFWKsv0
-XJuwHqJL9csCP/gLofKnQtS3TOvjZoDzJUN4LhsXVgdSGMvRqOzm+3M+pGKMgLTS
-xRJzo9P6Aji+Yz2EuJnB8br3n8NA0VgYU8Fi3a8YQn80TsVD1XGwMADH45CuP1eG
-l87qDBKOInDjZqdUfy4oy9RU0LMeYmcI+Sfhy+NmuCQbiWqJRGXy2UzSWByMTsCV
-odTvZy84IOgu/5ZR8LrYPZJwR2UcnnNytGAMXOLRc3bgr07i5TelRS+KIz6HxzDm
-MTh89N1SyvNTBCVXVmaU6Avu5gMUTu79bZRknl7OedSyps9AsUSoPocZXun4IRZZ
-Uw==
------END CERTIFICATE-----
-#endif
-static const unsigned char kDERCert9[] = {
- 0x30, 0x82, 0x04, 0x4d, 0x30, 0x82, 0x03, 0x35, 0xa0, 0x03, 0x02, 0x01,
- 0x02, 0x02, 0x0b, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01, 0x44, 0x4e, 0xf0,
- 0x36, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
- 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x57, 0x31, 0x0b, 0x30, 0x09, 0x06,
- 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x42, 0x45, 0x31, 0x19, 0x30, 0x17,
- 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x10, 0x47, 0x6c, 0x6f, 0x62, 0x61,
- 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x6e, 0x76, 0x2d, 0x73, 0x61, 0x31,
- 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x07, 0x52, 0x6f,
- 0x6f, 0x74, 0x20, 0x43, 0x41, 0x31, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55,
- 0x04, 0x03, 0x13, 0x12, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x53, 0x69,
- 0x67, 0x6e, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41, 0x30, 0x1e,
- 0x17, 0x0d, 0x31, 0x34, 0x30, 0x32, 0x32, 0x30, 0x31, 0x30, 0x30, 0x30,
- 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x34, 0x30, 0x32, 0x32, 0x30, 0x31,
- 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x4c, 0x31, 0x0b, 0x30, 0x09,
- 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x42, 0x45, 0x31, 0x19, 0x30,
- 0x17, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x10, 0x47, 0x6c, 0x6f, 0x62,
- 0x61, 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x6e, 0x76, 0x2d, 0x73, 0x61,
- 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x19, 0x41,
- 0x6c, 0x70, 0x68, 0x61, 0x53, 0x53, 0x4c, 0x20, 0x43, 0x41, 0x20, 0x2d,
- 0x20, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, 0x20, 0x2d, 0x20, 0x47, 0x32,
- 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
- 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00,
- 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xda, 0x01, 0xec,
- 0xe4, 0xec, 0x73, 0x60, 0xfb, 0x7e, 0x8f, 0x6a, 0xb7, 0xc6, 0x17, 0xe3,
- 0x92, 0x64, 0x32, 0xd4, 0xac, 0x00, 0xd9, 0xa2, 0x0f, 0xb9, 0xed, 0xee,
- 0x6b, 0x8a, 0x86, 0xca, 0x92, 0x67, 0xd9, 0x74, 0xd7, 0x5d, 0x47, 0x02,
- 0x3c, 0x8f, 0x40, 0xd6, 0x9e, 0x6d, 0x14, 0xcd, 0xc3, 0xda, 0x29, 0x39,
- 0xa7, 0x0f, 0x05, 0x0a, 0x68, 0xa2, 0x66, 0x1a, 0x1e, 0xc4, 0xb2, 0x8b,
- 0x76, 0x58, 0xe5, 0xab, 0x5d, 0x1d, 0x8f, 0x40, 0xb3, 0x39, 0x8b, 0xef,
- 0x1e, 0x83, 0x7d, 0x22, 0xd0, 0xe3, 0xa9, 0x00, 0x2e, 0xec, 0x53, 0xcf,
- 0x62, 0x19, 0x85, 0x44, 0x28, 0x4c, 0xc0, 0x27, 0xcb, 0x7b, 0x0e, 0xec,
- 0x10, 0x64, 0x00, 0x10, 0xa4, 0x05, 0xcc, 0xa0, 0x72, 0xbe, 0x41, 0x6c,
- 0x31, 0x5b, 0x48, 0xe4, 0xb1, 0xec, 0xb9, 0x23, 0xeb, 0x55, 0x4d, 0xd0,
- 0x7d, 0x62, 0x4a, 0xa5, 0xb4, 0xa5, 0xa4, 0x59, 0x85, 0xc5, 0x25, 0x91,
- 0xa6, 0xfe, 0xa6, 0x09, 0x9f, 0x06, 0x10, 0x6d, 0x8f, 0x81, 0x0c, 0x64,
- 0x40, 0x5e, 0x73, 0x00, 0x9a, 0xe0, 0x2e, 0x65, 0x98, 0x54, 0x10, 0x00,
- 0x70, 0x98, 0xc8, 0xe1, 0xed, 0x34, 0x5f, 0xd8, 0x9c, 0xc7, 0x0d, 0xc0,
- 0xd6, 0x23, 0x59, 0x45, 0xfc, 0xfe, 0x55, 0x7a, 0x86, 0xee, 0x94, 0x60,
- 0x22, 0xf1, 0xae, 0xd1, 0xe6, 0x55, 0x46, 0xf6, 0x99, 0xc5, 0x1b, 0x08,
- 0x74, 0x5f, 0xac, 0xb0, 0x64, 0x84, 0x8f, 0x89, 0x38, 0x1c, 0xa1, 0xa7,
- 0x90, 0x21, 0x4f, 0x02, 0x6e, 0xbd, 0xe0, 0x61, 0x67, 0xd4, 0xf8, 0x42,
- 0x87, 0x0f, 0x0a, 0xf7, 0xc9, 0x04, 0x6d, 0x2a, 0xa9, 0x2f, 0xef, 0x42,
- 0xa5, 0xdf, 0xdd, 0xa3, 0x53, 0xdb, 0x98, 0x1e, 0x81, 0xf9, 0x9a, 0x72,
- 0x7b, 0x5a, 0xde, 0x4f, 0x3e, 0x7f, 0xa2, 0x58, 0xa0, 0xe2, 0x17, 0xad,
- 0x67, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x23, 0x30, 0x82,
- 0x01, 0x1f, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff,
- 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d,
- 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02,
- 0x01, 0x00, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04,
- 0x14, 0xf5, 0xcd, 0xd5, 0x3c, 0x08, 0x50, 0xf9, 0x6a, 0x4f, 0x3a, 0xb7,
- 0x97, 0xda, 0x56, 0x83, 0xe6, 0x69, 0xd2, 0x68, 0xf7, 0x30, 0x45, 0x06,
- 0x03, 0x55, 0x1d, 0x20, 0x04, 0x3e, 0x30, 0x3c, 0x30, 0x3a, 0x06, 0x04,
- 0x55, 0x1d, 0x20, 0x00, 0x30, 0x32, 0x30, 0x30, 0x06, 0x08, 0x2b, 0x06,
- 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x24, 0x68, 0x74, 0x74, 0x70,
- 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x61, 0x6c, 0x70, 0x68,
- 0x61, 0x73, 0x73, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x70,
- 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x2f, 0x30, 0x33, 0x06, 0x03,
- 0x55, 0x1d, 0x1f, 0x04, 0x2c, 0x30, 0x2a, 0x30, 0x28, 0xa0, 0x26, 0xa0,
- 0x24, 0x86, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72,
- 0x6c, 0x2e, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x73, 0x69, 0x67, 0x6e,
- 0x2e, 0x6e, 0x65, 0x74, 0x2f, 0x72, 0x6f, 0x6f, 0x74, 0x2e, 0x63, 0x72,
- 0x6c, 0x30, 0x3d, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01,
- 0x01, 0x04, 0x31, 0x30, 0x2f, 0x30, 0x2d, 0x06, 0x08, 0x2b, 0x06, 0x01,
- 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x21, 0x68, 0x74, 0x74, 0x70, 0x3a,
- 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x67, 0x6c, 0x6f, 0x62, 0x61,
- 0x6c, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x6f,
- 0x6f, 0x74, 0x72, 0x31, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04,
- 0x18, 0x30, 0x16, 0x80, 0x14, 0x60, 0x7b, 0x66, 0x1a, 0x45, 0x0d, 0x97,
- 0xca, 0x89, 0x50, 0x2f, 0x7d, 0x04, 0xcd, 0x34, 0xa8, 0xff, 0xfc, 0xfd,
- 0x4b, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
- 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x60, 0x40, 0x68,
- 0x16, 0x47, 0xe7, 0x16, 0x8d, 0xdb, 0x5c, 0xa1, 0x56, 0x2a, 0xcb, 0xf4,
- 0x5c, 0x9b, 0xb0, 0x1e, 0xa2, 0x4b, 0xf5, 0xcb, 0x02, 0x3f, 0xf8, 0x0b,
- 0xa1, 0xf2, 0xa7, 0x42, 0xd4, 0xb7, 0x4c, 0xeb, 0xe3, 0x66, 0x80, 0xf3,
- 0x25, 0x43, 0x78, 0x2e, 0x1b, 0x17, 0x56, 0x07, 0x52, 0x18, 0xcb, 0xd1,
- 0xa8, 0xec, 0xe6, 0xfb, 0x73, 0x3e, 0xa4, 0x62, 0x8c, 0x80, 0xb4, 0xd2,
- 0xc5, 0x12, 0x73, 0xa3, 0xd3, 0xfa, 0x02, 0x38, 0xbe, 0x63, 0x3d, 0x84,
- 0xb8, 0x99, 0xc1, 0xf1, 0xba, 0xf7, 0x9f, 0xc3, 0x40, 0xd1, 0x58, 0x18,
- 0x53, 0xc1, 0x62, 0xdd, 0xaf, 0x18, 0x42, 0x7f, 0x34, 0x4e, 0xc5, 0x43,
- 0xd5, 0x71, 0xb0, 0x30, 0x00, 0xc7, 0xe3, 0x90, 0xae, 0x3f, 0x57, 0x86,
- 0x97, 0xce, 0xea, 0x0c, 0x12, 0x8e, 0x22, 0x70, 0xe3, 0x66, 0xa7, 0x54,
- 0x7f, 0x2e, 0x28, 0xcb, 0xd4, 0x54, 0xd0, 0xb3, 0x1e, 0x62, 0x67, 0x08,
- 0xf9, 0x27, 0xe1, 0xcb, 0xe3, 0x66, 0xb8, 0x24, 0x1b, 0x89, 0x6a, 0x89,
- 0x44, 0x65, 0xf2, 0xd9, 0x4c, 0xd2, 0x58, 0x1c, 0x8c, 0x4e, 0xc0, 0x95,
- 0xa1, 0xd4, 0xef, 0x67, 0x2f, 0x38, 0x20, 0xe8, 0x2e, 0xff, 0x96, 0x51,
- 0xf0, 0xba, 0xd8, 0x3d, 0x92, 0x70, 0x47, 0x65, 0x1c, 0x9e, 0x73, 0x72,
- 0xb4, 0x60, 0x0c, 0x5c, 0xe2, 0xd1, 0x73, 0x76, 0xe0, 0xaf, 0x4e, 0xe2,
- 0xe5, 0x37, 0xa5, 0x45, 0x2f, 0x8a, 0x23, 0x3e, 0x87, 0xc7, 0x30, 0xe6,
- 0x31, 0x38, 0x7c, 0xf4, 0xdd, 0x52, 0xca, 0xf3, 0x53, 0x04, 0x25, 0x57,
- 0x56, 0x66, 0x94, 0xe8, 0x0b, 0xee, 0xe6, 0x03, 0x14, 0x4e, 0xee, 0xfd,
- 0x6d, 0x94, 0x64, 0x9e, 0x5e, 0xce, 0x79, 0xd4, 0xb2, 0xa6, 0xcf, 0x40,
- 0xb1, 0x44, 0xa8, 0x3e, 0x87, 0x19, 0x5e, 0xe9, 0xf8, 0x21, 0x16, 0x59,
- 0x53,
-};
-
-#if 0
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number: 146031 (0x23a6f)
- Signature Algorithm: sha256WithRSAEncryption
- Issuer: C=US, O=GeoTrust Inc., CN=GeoTrust Global CA
- Validity
- Not Before: Nov 5 21:36:50 2013 GMT
- Not After : May 20 21:36:50 2022 GMT
- Subject: C=US, O=GeoTrust Inc., CN=GeoTrust SSL CA - G3
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:e3:be:7e:0a:86:a3:cf:6b:6d:3d:2b:a1:97:ad:
- 49:24:4d:d7:77:b9:34:79:08:a5:9e:a2:9e:de:47:
- 12:92:3d:7e:ea:19:86:b1:e8:4f:3d:5f:f7:d0:a7:
- 77:9a:5b:1f:0a:03:b5:19:53:db:a5:21:94:69:63:
- 9d:6a:4c:91:0c:10:47:be:11:fa:6c:86:25:b7:ab:
- 04:68:42:38:09:65:f0:14:da:19:9e:fa:6b:0b:ab:
- 62:ef:8d:a7:ef:63:70:23:a8:af:81:f3:d1:6e:88:
- 67:53:ec:12:a4:29:75:8a:a7:f2:57:3d:a2:83:98:
- 97:f2:0a:7d:d4:e7:43:6e:30:78:62:22:59:59:b8:
- 71:27:45:aa:0f:66:c6:55:3f:fa:32:17:2b:31:8f:
- 46:a0:fa:69:14:7c:9d:9f:5a:e2:eb:33:4e:10:a6:
- b3:ed:77:63:d8:c3:9e:f4:dd:df:79:9a:7a:d4:ee:
- de:dd:9a:cc:c3:b7:a9:5d:cc:11:3a:07:bb:6f:97:
- a4:01:23:47:95:1f:a3:77:fa:58:92:c6:c7:d0:bd:
- cf:93:18:42:b7:7e:f7:9e:65:ea:d5:3b:ca:ed:ac:
- c5:70:a1:fe:d4:10:9a:f0:12:04:44:ac:1a:5b:78:
- 50:45:57:4c:6f:bd:80:cb:81:5c:2d:b3:bc:76:a1:
- 1e:65
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Authority Key Identifier:
- keyid:C0:7A:98:68:8D:89:FB:AB:05:64:0C:11:7D:AA:7D:65:B8:CA:CC:4E
-
- X509v3 Subject Key Identifier:
- D2:6F:F7:96:F4:85:3F:72:3C:30:7D:23:DA:85:78:9B:A3:7C:5A:7C
- X509v3 Basic Constraints: critical
- CA:TRUE, pathlen:0
- X509v3 Key Usage: critical
- Certificate Sign, CRL Sign
- X509v3 CRL Distribution Points:
-
- Full Name:
- URI:http://g1.symcb.com/crls/gtglobal.crl
-
- Authority Information Access:
- OCSP - URI:http://g2.symcb.com
-
- X509v3 Certificate Policies:
- Policy: 2.16.840.1.113733.1.7.54
- CPS: http://www.geotrust.com/resources/cps
-
- X509v3 Subject Alternative Name:
- DirName:/CN=SymantecPKI-1-539
- Signature Algorithm: sha256WithRSAEncryption
- a0:d4:f7:2c:fb:74:0b:7f:64:f1:cd:43:6a:9f:62:53:1c:02:
- 7c:98:90:a2:ee:4f:68:d4:20:1a:73:12:3e:77:b3:50:eb:72:
- bc:ee:88:be:7f:17:ea:77:8f:83:61:95:4f:84:a1:cb:32:4f:
- 6c:21:be:d2:69:96:7d:63:bd:dc:2b:a8:1f:d0:13:84:70:fe:
- f6:35:95:89:f9:a6:77:b0:46:c8:bb:b7:13:f5:c9:60:69:d6:
- 4c:fe:d2:8e:ef:d3:60:c1:80:80:e1:e7:fb:8b:6f:21:79:4a:
- e0:dc:a9:1b:c1:b7:fb:c3:49:59:5c:b5:77:07:44:d4:97:fc:
- 49:00:89:6f:06:4e:01:70:19:ac:2f:11:c0:e2:e6:0f:2f:86:
- 4b:8d:7b:c3:b9:a7:2e:f4:f1:ac:16:3e:39:49:51:9e:17:4b:
- 4f:10:3a:5b:a5:a8:92:6f:fd:fa:d6:0b:03:4d:47:56:57:19:
- f3:cb:6b:f5:f3:d6:cf:b0:f5:f5:a3:11:d2:20:53:13:34:37:
- 05:2c:43:5a:63:df:8d:40:d6:85:1e:51:e9:51:17:1e:03:56:
- c9:f1:30:ad:e7:9b:11:a2:b9:d0:31:81:9b:68:b1:d9:e8:f3:
- e6:94:7e:c7:ae:13:2f:87:ed:d0:25:b0:68:f9:de:08:5a:f3:
- 29:cc:d4:92
------BEGIN CERTIFICATE-----
-MIIETzCCAzegAwIBAgIDAjpvMA0GCSqGSIb3DQEBCwUAMEIxCzAJBgNVBAYTAlVT
-MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i
-YWwgQ0EwHhcNMTMxMTA1MjEzNjUwWhcNMjIwNTIwMjEzNjUwWjBEMQswCQYDVQQG
-EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEdMBsGA1UEAxMUR2VvVHJ1c3Qg
-U1NMIENBIC0gRzMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDjvn4K
-hqPPa209K6GXrUkkTdd3uTR5CKWeop7eRxKSPX7qGYax6E89X/fQp3eaWx8KA7UZ
-U9ulIZRpY51qTJEMEEe+EfpshiW3qwRoQjgJZfAU2hme+msLq2LvjafvY3AjqK+B
-89FuiGdT7BKkKXWKp/JXPaKDmJfyCn3U50NuMHhiIllZuHEnRaoPZsZVP/oyFysx
-j0ag+mkUfJ2fWuLrM04QprPtd2PYw5703d95mnrU7t7dmszDt6ldzBE6B7tvl6QB
-I0eVH6N3+liSxsfQvc+TGEK3fveeZerVO8rtrMVwof7UEJrwEgRErBpbeFBFV0xv
-vYDLgVwts7x2oR5lAgMBAAGjggFKMIIBRjAfBgNVHSMEGDAWgBTAephojYn7qwVk
-DBF9qn1luMrMTjAdBgNVHQ4EFgQU0m/3lvSFP3I8MH0j2oV4m6N8WnwwEgYDVR0T
-AQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAQYwNgYDVR0fBC8wLTAroCmgJ4Yl
-aHR0cDovL2cxLnN5bWNiLmNvbS9jcmxzL2d0Z2xvYmFsLmNybDAvBggrBgEFBQcB
-AQQjMCEwHwYIKwYBBQUHMAGGE2h0dHA6Ly9nMi5zeW1jYi5jb20wTAYDVR0gBEUw
-QzBBBgpghkgBhvhFAQc2MDMwMQYIKwYBBQUHAgEWJWh0dHA6Ly93d3cuZ2VvdHJ1
-c3QuY29tL3Jlc291cmNlcy9jcHMwKQYDVR0RBCIwIKQeMBwxGjAYBgNVBAMTEVN5
-bWFudGVjUEtJLTEtNTM5MA0GCSqGSIb3DQEBCwUAA4IBAQCg1Pcs+3QLf2TxzUNq
-n2JTHAJ8mJCi7k9o1CAacxI+d7NQ63K87oi+fxfqd4+DYZVPhKHLMk9sIb7SaZZ9
-Y73cK6gf0BOEcP72NZWJ+aZ3sEbIu7cT9clgadZM/tKO79NgwYCA4ef7i28heUrg
-3Kkbwbf7w0lZXLV3B0TUl/xJAIlvBk4BcBmsLxHA4uYPL4ZLjXvDuacu9PGsFj45
-SVGeF0tPEDpbpaiSb/361gsDTUdWVxnzy2v189bPsPX1oxHSIFMTNDcFLENaY9+N
-QNaFHlHpURceA1bJ8TCt55sRornQMYGbaLHZ6PPmlH7HrhMvh+3QJbBo+d4IWvMp
-zNSS
------END CERTIFICATE-----
-#endif
-static const unsigned char kDERCert10[] = {
- 0x30, 0x82, 0x04, 0x4f, 0x30, 0x82, 0x03, 0x37, 0xa0, 0x03, 0x02, 0x01,
- 0x02, 0x02, 0x03, 0x02, 0x3a, 0x6f, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
- 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x42, 0x31,
- 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53,
- 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0d, 0x47,
- 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x49, 0x6e, 0x63, 0x2e,
- 0x31, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x12, 0x47,
- 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x47, 0x6c, 0x6f, 0x62,
- 0x61, 0x6c, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x33, 0x31,
- 0x31, 0x30, 0x35, 0x32, 0x31, 0x33, 0x36, 0x35, 0x30, 0x5a, 0x17, 0x0d,
- 0x32, 0x32, 0x30, 0x35, 0x32, 0x30, 0x32, 0x31, 0x33, 0x36, 0x35, 0x30,
- 0x5a, 0x30, 0x44, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06,
- 0x13, 0x02, 0x55, 0x53, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04,
- 0x0a, 0x13, 0x0d, 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20,
- 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x1d, 0x30, 0x1b, 0x06, 0x03, 0x55, 0x04,
- 0x03, 0x13, 0x14, 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20,
- 0x53, 0x53, 0x4c, 0x20, 0x43, 0x41, 0x20, 0x2d, 0x20, 0x47, 0x33, 0x30,
- 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
- 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30,
- 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xe3, 0xbe, 0x7e, 0x0a,
- 0x86, 0xa3, 0xcf, 0x6b, 0x6d, 0x3d, 0x2b, 0xa1, 0x97, 0xad, 0x49, 0x24,
- 0x4d, 0xd7, 0x77, 0xb9, 0x34, 0x79, 0x08, 0xa5, 0x9e, 0xa2, 0x9e, 0xde,
- 0x47, 0x12, 0x92, 0x3d, 0x7e, 0xea, 0x19, 0x86, 0xb1, 0xe8, 0x4f, 0x3d,
- 0x5f, 0xf7, 0xd0, 0xa7, 0x77, 0x9a, 0x5b, 0x1f, 0x0a, 0x03, 0xb5, 0x19,
- 0x53, 0xdb, 0xa5, 0x21, 0x94, 0x69, 0x63, 0x9d, 0x6a, 0x4c, 0x91, 0x0c,
- 0x10, 0x47, 0xbe, 0x11, 0xfa, 0x6c, 0x86, 0x25, 0xb7, 0xab, 0x04, 0x68,
- 0x42, 0x38, 0x09, 0x65, 0xf0, 0x14, 0xda, 0x19, 0x9e, 0xfa, 0x6b, 0x0b,
- 0xab, 0x62, 0xef, 0x8d, 0xa7, 0xef, 0x63, 0x70, 0x23, 0xa8, 0xaf, 0x81,
- 0xf3, 0xd1, 0x6e, 0x88, 0x67, 0x53, 0xec, 0x12, 0xa4, 0x29, 0x75, 0x8a,
- 0xa7, 0xf2, 0x57, 0x3d, 0xa2, 0x83, 0x98, 0x97, 0xf2, 0x0a, 0x7d, 0xd4,
- 0xe7, 0x43, 0x6e, 0x30, 0x78, 0x62, 0x22, 0x59, 0x59, 0xb8, 0x71, 0x27,
- 0x45, 0xaa, 0x0f, 0x66, 0xc6, 0x55, 0x3f, 0xfa, 0x32, 0x17, 0x2b, 0x31,
- 0x8f, 0x46, 0xa0, 0xfa, 0x69, 0x14, 0x7c, 0x9d, 0x9f, 0x5a, 0xe2, 0xeb,
- 0x33, 0x4e, 0x10, 0xa6, 0xb3, 0xed, 0x77, 0x63, 0xd8, 0xc3, 0x9e, 0xf4,
- 0xdd, 0xdf, 0x79, 0x9a, 0x7a, 0xd4, 0xee, 0xde, 0xdd, 0x9a, 0xcc, 0xc3,
- 0xb7, 0xa9, 0x5d, 0xcc, 0x11, 0x3a, 0x07, 0xbb, 0x6f, 0x97, 0xa4, 0x01,
- 0x23, 0x47, 0x95, 0x1f, 0xa3, 0x77, 0xfa, 0x58, 0x92, 0xc6, 0xc7, 0xd0,
- 0xbd, 0xcf, 0x93, 0x18, 0x42, 0xb7, 0x7e, 0xf7, 0x9e, 0x65, 0xea, 0xd5,
- 0x3b, 0xca, 0xed, 0xac, 0xc5, 0x70, 0xa1, 0xfe, 0xd4, 0x10, 0x9a, 0xf0,
- 0x12, 0x04, 0x44, 0xac, 0x1a, 0x5b, 0x78, 0x50, 0x45, 0x57, 0x4c, 0x6f,
- 0xbd, 0x80, 0xcb, 0x81, 0x5c, 0x2d, 0xb3, 0xbc, 0x76, 0xa1, 0x1e, 0x65,
- 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x4a, 0x30, 0x82, 0x01,
- 0x46, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16,
- 0x80, 0x14, 0xc0, 0x7a, 0x98, 0x68, 0x8d, 0x89, 0xfb, 0xab, 0x05, 0x64,
- 0x0c, 0x11, 0x7d, 0xaa, 0x7d, 0x65, 0xb8, 0xca, 0xcc, 0x4e, 0x30, 0x1d,
- 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xd2, 0x6f, 0xf7,
- 0x96, 0xf4, 0x85, 0x3f, 0x72, 0x3c, 0x30, 0x7d, 0x23, 0xda, 0x85, 0x78,
- 0x9b, 0xa3, 0x7c, 0x5a, 0x7c, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13,
- 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01,
- 0x00, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04,
- 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x36, 0x06, 0x03, 0x55, 0x1d, 0x1f,
- 0x04, 0x2f, 0x30, 0x2d, 0x30, 0x2b, 0xa0, 0x29, 0xa0, 0x27, 0x86, 0x25,
- 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x67, 0x31, 0x2e, 0x73, 0x79,
- 0x6d, 0x63, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x72, 0x6c, 0x73,
- 0x2f, 0x67, 0x74, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x2e, 0x63, 0x72,
- 0x6c, 0x30, 0x2f, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01,
- 0x01, 0x04, 0x23, 0x30, 0x21, 0x30, 0x1f, 0x06, 0x08, 0x2b, 0x06, 0x01,
- 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x13, 0x68, 0x74, 0x74, 0x70, 0x3a,
- 0x2f, 0x2f, 0x67, 0x32, 0x2e, 0x73, 0x79, 0x6d, 0x63, 0x62, 0x2e, 0x63,
- 0x6f, 0x6d, 0x30, 0x4c, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x45, 0x30,
- 0x43, 0x30, 0x41, 0x06, 0x0a, 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x45,
- 0x01, 0x07, 0x36, 0x30, 0x33, 0x30, 0x31, 0x06, 0x08, 0x2b, 0x06, 0x01,
- 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x25, 0x68, 0x74, 0x74, 0x70, 0x3a,
- 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x67, 0x65, 0x6f, 0x74, 0x72, 0x75,
- 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75,
- 0x72, 0x63, 0x65, 0x73, 0x2f, 0x63, 0x70, 0x73, 0x30, 0x29, 0x06, 0x03,
- 0x55, 0x1d, 0x11, 0x04, 0x22, 0x30, 0x20, 0xa4, 0x1e, 0x30, 0x1c, 0x31,
- 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x11, 0x53, 0x79,
- 0x6d, 0x61, 0x6e, 0x74, 0x65, 0x63, 0x50, 0x4b, 0x49, 0x2d, 0x31, 0x2d,
- 0x35, 0x33, 0x39, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
- 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0xa0,
- 0xd4, 0xf7, 0x2c, 0xfb, 0x74, 0x0b, 0x7f, 0x64, 0xf1, 0xcd, 0x43, 0x6a,
- 0x9f, 0x62, 0x53, 0x1c, 0x02, 0x7c, 0x98, 0x90, 0xa2, 0xee, 0x4f, 0x68,
- 0xd4, 0x20, 0x1a, 0x73, 0x12, 0x3e, 0x77, 0xb3, 0x50, 0xeb, 0x72, 0xbc,
- 0xee, 0x88, 0xbe, 0x7f, 0x17, 0xea, 0x77, 0x8f, 0x83, 0x61, 0x95, 0x4f,
- 0x84, 0xa1, 0xcb, 0x32, 0x4f, 0x6c, 0x21, 0xbe, 0xd2, 0x69, 0x96, 0x7d,
- 0x63, 0xbd, 0xdc, 0x2b, 0xa8, 0x1f, 0xd0, 0x13, 0x84, 0x70, 0xfe, 0xf6,
- 0x35, 0x95, 0x89, 0xf9, 0xa6, 0x77, 0xb0, 0x46, 0xc8, 0xbb, 0xb7, 0x13,
- 0xf5, 0xc9, 0x60, 0x69, 0xd6, 0x4c, 0xfe, 0xd2, 0x8e, 0xef, 0xd3, 0x60,
- 0xc1, 0x80, 0x80, 0xe1, 0xe7, 0xfb, 0x8b, 0x6f, 0x21, 0x79, 0x4a, 0xe0,
- 0xdc, 0xa9, 0x1b, 0xc1, 0xb7, 0xfb, 0xc3, 0x49, 0x59, 0x5c, 0xb5, 0x77,
- 0x07, 0x44, 0xd4, 0x97, 0xfc, 0x49, 0x00, 0x89, 0x6f, 0x06, 0x4e, 0x01,
- 0x70, 0x19, 0xac, 0x2f, 0x11, 0xc0, 0xe2, 0xe6, 0x0f, 0x2f, 0x86, 0x4b,
- 0x8d, 0x7b, 0xc3, 0xb9, 0xa7, 0x2e, 0xf4, 0xf1, 0xac, 0x16, 0x3e, 0x39,
- 0x49, 0x51, 0x9e, 0x17, 0x4b, 0x4f, 0x10, 0x3a, 0x5b, 0xa5, 0xa8, 0x92,
- 0x6f, 0xfd, 0xfa, 0xd6, 0x0b, 0x03, 0x4d, 0x47, 0x56, 0x57, 0x19, 0xf3,
- 0xcb, 0x6b, 0xf5, 0xf3, 0xd6, 0xcf, 0xb0, 0xf5, 0xf5, 0xa3, 0x11, 0xd2,
- 0x20, 0x53, 0x13, 0x34, 0x37, 0x05, 0x2c, 0x43, 0x5a, 0x63, 0xdf, 0x8d,
- 0x40, 0xd6, 0x85, 0x1e, 0x51, 0xe9, 0x51, 0x17, 0x1e, 0x03, 0x56, 0xc9,
- 0xf1, 0x30, 0xad, 0xe7, 0x9b, 0x11, 0xa2, 0xb9, 0xd0, 0x31, 0x81, 0x9b,
- 0x68, 0xb1, 0xd9, 0xe8, 0xf3, 0xe6, 0x94, 0x7e, 0xc7, 0xae, 0x13, 0x2f,
- 0x87, 0xed, 0xd0, 0x25, 0xb0, 0x68, 0xf9, 0xde, 0x08, 0x5a, 0xf3, 0x29,
- 0xcc, 0xd4, 0x92,
-};
-
-#if 0
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number: 146019 (0x23a63)
- Signature Algorithm: sha1WithRSAEncryption
- Issuer: C=US, O=GeoTrust Inc., CN=GeoTrust Global CA
- Validity
- Not Before: Aug 27 20:40:40 2012 GMT
- Not After : May 20 20:40:40 2022 GMT
- Subject: C=US, O=GeoTrust Inc., CN=GeoTrust SSL CA - G2
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:b9:27:f9:4f:d8:f6:b7:15:3f:8f:cd:ce:d6:8d:
- 1c:6b:fd:7f:da:54:21:4e:03:d8:ca:d0:72:52:15:
- b8:c9:82:5b:58:79:84:ff:24:72:6f:f2:69:7f:bc:
- 96:d9:9a:7a:c3:3e:a9:cf:50:22:13:0e:86:19:db:
- e8:49:ef:8b:e6:d6:47:f2:fd:73:45:08:ae:8f:ac:
- 5e:b6:f8:9e:7c:f7:10:ff:92:43:66:ef:1c:d4:ee:
- a1:46:88:11:89:49:79:7a:25:ce:4b:6a:f0:d7:1c:
- 76:1a:29:3c:c9:e4:fd:1e:85:dc:e0:31:65:05:47:
- 16:ac:0a:07:4b:2e:70:5e:6b:06:a7:6b:3a:6c:af:
- 05:12:c4:b2:11:25:d6:3e:97:29:f0:83:6c:57:1c:
- d8:a5:ef:cc:ec:fd:d6:12:f1:3f:db:40:b4:ae:0f:
- 18:d3:c5:af:40:92:5d:07:5e:4e:fe:62:17:37:89:
- e9:8b:74:26:a2:ed:b8:0a:e7:6c:15:5b:35:90:72:
- dd:d8:4d:21:d4:40:23:5c:8f:ee:80:31:16:ab:68:
- 55:f4:0e:3b:54:e9:04:4d:f0:cc:4e:81:5e:e9:6f:
- 52:69:4e:be:a6:16:6d:42:f5:51:ff:e0:0b:56:3c:
- 98:4f:73:8f:0e:6f:1a:23:f1:c9:c8:d9:df:bc:ec:
- 52:d7
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Authority Key Identifier:
- keyid:C0:7A:98:68:8D:89:FB:AB:05:64:0C:11:7D:AA:7D:65:B8:CA:CC:4E
-
- X509v3 Subject Key Identifier:
- 11:4A:D0:73:39:D5:5B:69:08:5C:BA:3D:BF:64:9A:A8:8B:1C:55:BC
- X509v3 Basic Constraints: critical
- CA:TRUE, pathlen:0
- X509v3 Key Usage: critical
- Certificate Sign, CRL Sign
- X509v3 CRL Distribution Points:
-
- Full Name:
- URI:http://crl.geotrust.com/crls/gtglobal.crl
-
- Authority Information Access:
- OCSP - URI:http://ocsp.geotrust.com
-
- X509v3 Certificate Policies:
- Policy: 2.16.840.1.113733.1.7.54
- CPS: http://www.geotrust.com/resources/cps
-
- X509v3 Subject Alternative Name:
- DirName:/CN=VeriSignMPKI-2-254
- Signature Algorithm: sha1WithRSAEncryption
- 3c:e5:3d:5a:1b:a2:37:2a:e3:46:cf:36:96:18:3c:7b:f1:84:
- c5:57:86:77:40:9d:35:f0:12:f0:78:18:fb:22:a4:de:98:4b:
- 78:81:e6:4d:86:e3:91:0f:42:e3:b9:dc:a0:d6:ff:a9:f8:b1:
- 79:97:99:d1:c3:6c:42:a5:92:94:e0:5d:0c:33:18:25:c9:2b:
- 95:53:e0:e5:a9:0c:7d:47:fe:7f:51:31:44:5e:f7:2a:1e:35:
- a2:94:32:f7:c9:ee:c0:b6:c6:9a:ac:de:99:21:6a:23:a0:38:
- 64:ee:a3:c4:88:73:32:3b:50:ce:bf:ad:d3:75:1e:a6:f4:e9:
- f9:42:6b:60:b2:dd:45:fd:5d:57:08:ce:2d:50:e6:12:32:16:
- 13:8a:f2:94:a2:9b:47:a8:86:7f:d9:98:e5:f7:e5:76:74:64:
- d8:91:bc:84:16:28:d8:25:44:30:7e:82:d8:ac:b1:e4:c0:e4:
- 15:6c:db:b6:24:27:02:2a:01:12:85:ba:31:88:58:47:74:e3:
- b8:d2:64:a6:c3:32:59:2e:29:4b:45:f1:5b:89:49:2e:82:9a:
- c6:18:15:44:d0:2e:64:01:15:68:38:f9:f6:f9:66:03:0c:55:
- 1b:9d:bf:00:40:ae:f0:48:27:4c:e0:80:5e:2d:b9:2a:15:7a:
- bc:66:f8:35
------BEGIN CERTIFICATE-----
-MIIEWTCCA0GgAwIBAgIDAjpjMA0GCSqGSIb3DQEBBQUAMEIxCzAJBgNVBAYTAlVT
-MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i
-YWwgQ0EwHhcNMTIwODI3MjA0MDQwWhcNMjIwNTIwMjA0MDQwWjBEMQswCQYDVQQG
-EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEdMBsGA1UEAxMUR2VvVHJ1c3Qg
-U1NMIENBIC0gRzIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC5J/lP
-2Pa3FT+Pzc7WjRxr/X/aVCFOA9jK0HJSFbjJgltYeYT/JHJv8ml/vJbZmnrDPqnP
-UCITDoYZ2+hJ74vm1kfy/XNFCK6PrF62+J589xD/kkNm7xzU7qFGiBGJSXl6Jc5L
-avDXHHYaKTzJ5P0ehdzgMWUFRxasCgdLLnBeawanazpsrwUSxLIRJdY+lynwg2xX
-HNil78zs/dYS8T/bQLSuDxjTxa9Akl0HXk7+Yhc3iemLdCai7bgK52wVWzWQct3Y
-TSHUQCNcj+6AMRaraFX0DjtU6QRN8MxOgV7pb1JpTr6mFm1C9VH/4AtWPJhPc48O
-bxoj8cnI2d+87FLXAgMBAAGjggFUMIIBUDAfBgNVHSMEGDAWgBTAephojYn7qwVk
-DBF9qn1luMrMTjAdBgNVHQ4EFgQUEUrQcznVW2kIXLo9v2SaqIscVbwwEgYDVR0T
-AQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAQYwOgYDVR0fBDMwMTAvoC2gK4Yp
-aHR0cDovL2NybC5nZW90cnVzdC5jb20vY3Jscy9ndGdsb2JhbC5jcmwwNAYIKwYB
-BQUHAQEEKDAmMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5nZW90cnVzdC5jb20w
-TAYDVR0gBEUwQzBBBgpghkgBhvhFAQc2MDMwMQYIKwYBBQUHAgEWJWh0dHA6Ly93
-d3cuZ2VvdHJ1c3QuY29tL3Jlc291cmNlcy9jcHMwKgYDVR0RBCMwIaQfMB0xGzAZ
-BgNVBAMTElZlcmlTaWduTVBLSS0yLTI1NDANBgkqhkiG9w0BAQUFAAOCAQEAPOU9
-WhuiNyrjRs82lhg8e/GExVeGd0CdNfAS8HgY+yKk3phLeIHmTYbjkQ9C47ncoNb/
-qfixeZeZ0cNsQqWSlOBdDDMYJckrlVPg5akMfUf+f1ExRF73Kh41opQy98nuwLbG
-mqzemSFqI6A4ZO6jxIhzMjtQzr+t03UepvTp+UJrYLLdRf1dVwjOLVDmEjIWE4ry
-lKKbR6iGf9mY5ffldnRk2JG8hBYo2CVEMH6C2Kyx5MDkFWzbtiQnAioBEoW6MYhY
-R3TjuNJkpsMyWS4pS0XxW4lJLoKaxhgVRNAuZAEVaDj59vlmAwxVG52/AECu8Egn
-TOCAXi25KhV6vGb4NQ==
------END CERTIFICATE-----
-#endif
-static const unsigned char kDERCert11[] = {
- 0x30, 0x82, 0x04, 0x59, 0x30, 0x82, 0x03, 0x41, 0xa0, 0x03, 0x02, 0x01,
- 0x02, 0x02, 0x03, 0x02, 0x3a, 0x63, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
- 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x42, 0x31,
- 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53,
- 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0d, 0x47,
- 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x49, 0x6e, 0x63, 0x2e,
- 0x31, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x12, 0x47,
- 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x47, 0x6c, 0x6f, 0x62,
- 0x61, 0x6c, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x32, 0x30,
- 0x38, 0x32, 0x37, 0x32, 0x30, 0x34, 0x30, 0x34, 0x30, 0x5a, 0x17, 0x0d,
- 0x32, 0x32, 0x30, 0x35, 0x32, 0x30, 0x32, 0x30, 0x34, 0x30, 0x34, 0x30,
- 0x5a, 0x30, 0x44, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06,
- 0x13, 0x02, 0x55, 0x53, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04,
- 0x0a, 0x13, 0x0d, 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20,
- 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x1d, 0x30, 0x1b, 0x06, 0x03, 0x55, 0x04,
- 0x03, 0x13, 0x14, 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20,
- 0x53, 0x53, 0x4c, 0x20, 0x43, 0x41, 0x20, 0x2d, 0x20, 0x47, 0x32, 0x30,
- 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
- 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30,
- 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xb9, 0x27, 0xf9, 0x4f,
- 0xd8, 0xf6, 0xb7, 0x15, 0x3f, 0x8f, 0xcd, 0xce, 0xd6, 0x8d, 0x1c, 0x6b,
- 0xfd, 0x7f, 0xda, 0x54, 0x21, 0x4e, 0x03, 0xd8, 0xca, 0xd0, 0x72, 0x52,
- 0x15, 0xb8, 0xc9, 0x82, 0x5b, 0x58, 0x79, 0x84, 0xff, 0x24, 0x72, 0x6f,
- 0xf2, 0x69, 0x7f, 0xbc, 0x96, 0xd9, 0x9a, 0x7a, 0xc3, 0x3e, 0xa9, 0xcf,
- 0x50, 0x22, 0x13, 0x0e, 0x86, 0x19, 0xdb, 0xe8, 0x49, 0xef, 0x8b, 0xe6,
- 0xd6, 0x47, 0xf2, 0xfd, 0x73, 0x45, 0x08, 0xae, 0x8f, 0xac, 0x5e, 0xb6,
- 0xf8, 0x9e, 0x7c, 0xf7, 0x10, 0xff, 0x92, 0x43, 0x66, 0xef, 0x1c, 0xd4,
- 0xee, 0xa1, 0x46, 0x88, 0x11, 0x89, 0x49, 0x79, 0x7a, 0x25, 0xce, 0x4b,
- 0x6a, 0xf0, 0xd7, 0x1c, 0x76, 0x1a, 0x29, 0x3c, 0xc9, 0xe4, 0xfd, 0x1e,
- 0x85, 0xdc, 0xe0, 0x31, 0x65, 0x05, 0x47, 0x16, 0xac, 0x0a, 0x07, 0x4b,
- 0x2e, 0x70, 0x5e, 0x6b, 0x06, 0xa7, 0x6b, 0x3a, 0x6c, 0xaf, 0x05, 0x12,
- 0xc4, 0xb2, 0x11, 0x25, 0xd6, 0x3e, 0x97, 0x29, 0xf0, 0x83, 0x6c, 0x57,
- 0x1c, 0xd8, 0xa5, 0xef, 0xcc, 0xec, 0xfd, 0xd6, 0x12, 0xf1, 0x3f, 0xdb,
- 0x40, 0xb4, 0xae, 0x0f, 0x18, 0xd3, 0xc5, 0xaf, 0x40, 0x92, 0x5d, 0x07,
- 0x5e, 0x4e, 0xfe, 0x62, 0x17, 0x37, 0x89, 0xe9, 0x8b, 0x74, 0x26, 0xa2,
- 0xed, 0xb8, 0x0a, 0xe7, 0x6c, 0x15, 0x5b, 0x35, 0x90, 0x72, 0xdd, 0xd8,
- 0x4d, 0x21, 0xd4, 0x40, 0x23, 0x5c, 0x8f, 0xee, 0x80, 0x31, 0x16, 0xab,
- 0x68, 0x55, 0xf4, 0x0e, 0x3b, 0x54, 0xe9, 0x04, 0x4d, 0xf0, 0xcc, 0x4e,
- 0x81, 0x5e, 0xe9, 0x6f, 0x52, 0x69, 0x4e, 0xbe, 0xa6, 0x16, 0x6d, 0x42,
- 0xf5, 0x51, 0xff, 0xe0, 0x0b, 0x56, 0x3c, 0x98, 0x4f, 0x73, 0x8f, 0x0e,
- 0x6f, 0x1a, 0x23, 0xf1, 0xc9, 0xc8, 0xd9, 0xdf, 0xbc, 0xec, 0x52, 0xd7,
- 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x54, 0x30, 0x82, 0x01,
- 0x50, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16,
- 0x80, 0x14, 0xc0, 0x7a, 0x98, 0x68, 0x8d, 0x89, 0xfb, 0xab, 0x05, 0x64,
- 0x0c, 0x11, 0x7d, 0xaa, 0x7d, 0x65, 0xb8, 0xca, 0xcc, 0x4e, 0x30, 0x1d,
- 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x11, 0x4a, 0xd0,
- 0x73, 0x39, 0xd5, 0x5b, 0x69, 0x08, 0x5c, 0xba, 0x3d, 0xbf, 0x64, 0x9a,
- 0xa8, 0x8b, 0x1c, 0x55, 0xbc, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13,
- 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01,
- 0x00, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04,
- 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x3a, 0x06, 0x03, 0x55, 0x1d, 0x1f,
- 0x04, 0x33, 0x30, 0x31, 0x30, 0x2f, 0xa0, 0x2d, 0xa0, 0x2b, 0x86, 0x29,
- 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x67,
- 0x65, 0x6f, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f,
- 0x63, 0x72, 0x6c, 0x73, 0x2f, 0x67, 0x74, 0x67, 0x6c, 0x6f, 0x62, 0x61,
- 0x6c, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x34, 0x06, 0x08, 0x2b, 0x06, 0x01,
- 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x28, 0x30, 0x26, 0x30, 0x24, 0x06,
- 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x18, 0x68,
- 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x67,
- 0x65, 0x6f, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x30,
- 0x4c, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x45, 0x30, 0x43, 0x30, 0x41,
- 0x06, 0x0a, 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x45, 0x01, 0x07, 0x36,
- 0x30, 0x33, 0x30, 0x31, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
- 0x02, 0x01, 0x16, 0x25, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77,
- 0x77, 0x77, 0x2e, 0x67, 0x65, 0x6f, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e,
- 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65,
- 0x73, 0x2f, 0x63, 0x70, 0x73, 0x30, 0x2a, 0x06, 0x03, 0x55, 0x1d, 0x11,
- 0x04, 0x23, 0x30, 0x21, 0xa4, 0x1f, 0x30, 0x1d, 0x31, 0x1b, 0x30, 0x19,
- 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x12, 0x56, 0x65, 0x72, 0x69, 0x53,
- 0x69, 0x67, 0x6e, 0x4d, 0x50, 0x4b, 0x49, 0x2d, 0x32, 0x2d, 0x32, 0x35,
- 0x34, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
- 0x01, 0x05, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x3c, 0xe5, 0x3d,
- 0x5a, 0x1b, 0xa2, 0x37, 0x2a, 0xe3, 0x46, 0xcf, 0x36, 0x96, 0x18, 0x3c,
- 0x7b, 0xf1, 0x84, 0xc5, 0x57, 0x86, 0x77, 0x40, 0x9d, 0x35, 0xf0, 0x12,
- 0xf0, 0x78, 0x18, 0xfb, 0x22, 0xa4, 0xde, 0x98, 0x4b, 0x78, 0x81, 0xe6,
- 0x4d, 0x86, 0xe3, 0x91, 0x0f, 0x42, 0xe3, 0xb9, 0xdc, 0xa0, 0xd6, 0xff,
- 0xa9, 0xf8, 0xb1, 0x79, 0x97, 0x99, 0xd1, 0xc3, 0x6c, 0x42, 0xa5, 0x92,
- 0x94, 0xe0, 0x5d, 0x0c, 0x33, 0x18, 0x25, 0xc9, 0x2b, 0x95, 0x53, 0xe0,
- 0xe5, 0xa9, 0x0c, 0x7d, 0x47, 0xfe, 0x7f, 0x51, 0x31, 0x44, 0x5e, 0xf7,
- 0x2a, 0x1e, 0x35, 0xa2, 0x94, 0x32, 0xf7, 0xc9, 0xee, 0xc0, 0xb6, 0xc6,
- 0x9a, 0xac, 0xde, 0x99, 0x21, 0x6a, 0x23, 0xa0, 0x38, 0x64, 0xee, 0xa3,
- 0xc4, 0x88, 0x73, 0x32, 0x3b, 0x50, 0xce, 0xbf, 0xad, 0xd3, 0x75, 0x1e,
- 0xa6, 0xf4, 0xe9, 0xf9, 0x42, 0x6b, 0x60, 0xb2, 0xdd, 0x45, 0xfd, 0x5d,
- 0x57, 0x08, 0xce, 0x2d, 0x50, 0xe6, 0x12, 0x32, 0x16, 0x13, 0x8a, 0xf2,
- 0x94, 0xa2, 0x9b, 0x47, 0xa8, 0x86, 0x7f, 0xd9, 0x98, 0xe5, 0xf7, 0xe5,
- 0x76, 0x74, 0x64, 0xd8, 0x91, 0xbc, 0x84, 0x16, 0x28, 0xd8, 0x25, 0x44,
- 0x30, 0x7e, 0x82, 0xd8, 0xac, 0xb1, 0xe4, 0xc0, 0xe4, 0x15, 0x6c, 0xdb,
- 0xb6, 0x24, 0x27, 0x02, 0x2a, 0x01, 0x12, 0x85, 0xba, 0x31, 0x88, 0x58,
- 0x47, 0x74, 0xe3, 0xb8, 0xd2, 0x64, 0xa6, 0xc3, 0x32, 0x59, 0x2e, 0x29,
- 0x4b, 0x45, 0xf1, 0x5b, 0x89, 0x49, 0x2e, 0x82, 0x9a, 0xc6, 0x18, 0x15,
- 0x44, 0xd0, 0x2e, 0x64, 0x01, 0x15, 0x68, 0x38, 0xf9, 0xf6, 0xf9, 0x66,
- 0x03, 0x0c, 0x55, 0x1b, 0x9d, 0xbf, 0x00, 0x40, 0xae, 0xf0, 0x48, 0x27,
- 0x4c, 0xe0, 0x80, 0x5e, 0x2d, 0xb9, 0x2a, 0x15, 0x7a, 0xbc, 0x66, 0xf8,
- 0x35,
-};
-
-#if 0
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number:
- 04:00:00:00:00:01:44:4e:f0:3e:20
- Signature Algorithm: sha256WithRSAEncryption
- Issuer: C=BE, O=GlobalSign nv-sa, OU=Root CA, CN=GlobalSign Root CA
- Validity
- Not Before: Feb 20 10:00:00 2014 GMT
- Not After : Feb 20 10:00:00 2024 GMT
- Subject: C=BE, O=GlobalSign nv-sa, CN=GlobalSign Domain Validation CA - SHA256 - G2
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:a9:dd:cc:0e:b3:e2:32:39:dd:49:22:a8:13:69:
- 93:87:88:e1:0c:ee:71:7d:bd:90:87:96:5d:59:f2:
- cc:b3:d2:58:57:57:f9:46:ef:6c:26:d8:36:42:8e:
- 7e:30:b3:2f:9a:3e:53:7b:1f:6e:b6:a2:4c:45:1f:
- 3c:d3:15:93:1c:89:ed:3c:f4:57:de:ca:bd:ec:06:
- 9a:6a:2a:a0:19:52:7f:51:d1:74:39:08:9f:ab:eb:
- d7:86:13:15:97:ae:36:c3:54:66:0e:5a:f2:a0:73:
- 85:31:e3:b2:64:14:6a:ff:a5:a2:8e:24:bb:bd:85:
- 52:15:a2:79:ee:f0:b5:ee:3d:b8:f4:7d:80:bc:d9:
- 90:35:65:b8:17:a9:ad:b3:98:9f:a0:7e:7d:6e:fb:
- 3f:ad:7c:c2:1b:59:36:96:da:37:32:4b:4b:5d:35:
- 02:63:8e:db:a7:cf:62:ee:cc:2e:d4:8d:c9:bd:3c:
- 6a:91:72:a2:22:a7:72:2d:20:d1:fa:ca:37:da:18:
- 98:e6:16:24:71:25:4b:c4:e5:7b:89:52:09:02:fd:
- 59:2b:04:6e:ca:07:81:d4:b3:da:da:db:e3:cc:80:
- a8:56:07:06:7c:96:08:37:9d:db:38:b6:62:34:91:
- 62:07:74:01:38:d8:72:30:e2:eb:90:71:26:62:c0:
- 57:f3
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Key Usage: critical
- Certificate Sign, CRL Sign
- X509v3 Basic Constraints: critical
- CA:TRUE, pathlen:0
- X509v3 Subject Key Identifier:
- EA:4E:7C:D4:80:2D:E5:15:81:86:26:8C:82:6D:C0:98:A4:CF:97:0F
- X509v3 Certificate Policies:
- Policy: X509v3 Any Policy
- CPS: https://www.globalsign.com/repository/
-
- X509v3 CRL Distribution Points:
-
- Full Name:
- URI:http://crl.globalsign.net/root.crl
-
- Authority Information Access:
- OCSP - URI:http://ocsp.globalsign.com/rootr1
-
- X509v3 Authority Key Identifier:
- keyid:60:7B:66:1A:45:0D:97:CA:89:50:2F:7D:04:CD:34:A8:FF:FC:FD:4B
-
- Signature Algorithm: sha256WithRSAEncryption
- d7:45:9e:a0:dc:e0:e3:61:5a:0b:7d:77:84:17:2d:65:5a:82:
- 9a:8d:a3:27:2a:85:f7:c9:ef:e9:86:fd:d4:47:cd:01:52:96:
- c5:43:bd:37:b1:e1:b8:f2:a9:d2:8a:11:84:71:91:15:89:dc:
- 02:9d:0b:cb:6c:33:85:34:28:9e:20:b2:b1:97:dc:6d:0b:10:
- c1:3c:cd:5f:ea:5d:d7:98:31:c5:34:99:5c:00:61:55:c4:1b:
- 02:5b:c5:e3:89:c8:b4:b8:6f:1e:38:f2:56:26:e9:41:ef:3d:
- cd:ac:99:4f:59:4a:57:2d:4b:7d:ae:c7:88:fb:d6:98:3b:f5:
- e5:f0:e8:89:89:b9:8b:03:cb:5a:23:1f:a4:fd:b8:ea:fb:2e:
- 9d:ae:6a:73:09:bc:fc:d5:a0:b5:44:82:ab:44:91:2e:50:2e:
- 57:c1:43:d8:91:04:8b:e9:11:2e:5f:b4:3f:79:df:1e:fb:3f:
- 30:00:8b:53:e3:b7:2c:1d:3b:4d:8b:dc:e4:64:1d:04:58:33:
- af:1b:55:e7:ab:0c:bf:30:04:74:e4:f3:0e:2f:30:39:8d:4b:
- 04:8c:1e:75:66:66:49:e0:be:40:34:c7:5c:5a:51:92:ba:12:
- 3c:52:d5:04:82:55:2d:67:a5:df:b7:95:7c:ee:3f:c3:08:ba:
- 04:be:c0:46
------BEGIN CERTIFICATE-----
-MIIEYzCCA0ugAwIBAgILBAAAAAABRE7wPiAwDQYJKoZIhvcNAQELBQAwVzELMAkG
-A1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jv
-b3QgQ0ExGzAZBgNVBAMTEkdsb2JhbFNpZ24gUm9vdCBDQTAeFw0xNDAyMjAxMDAw
-MDBaFw0yNDAyMjAxMDAwMDBaMGAxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9i
-YWxTaWduIG52LXNhMTYwNAYDVQQDEy1HbG9iYWxTaWduIERvbWFpbiBWYWxpZGF0
-aW9uIENBIC0gU0hBMjU2IC0gRzIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
-AoIBAQCp3cwOs+IyOd1JIqgTaZOHiOEM7nF9vZCHll1Z8syz0lhXV/lG72wm2DZC
-jn4wsy+aPlN7H262okxFHzzTFZMcie089Ffeyr3sBppqKqAZUn9R0XQ5CJ+r69eG
-ExWXrjbDVGYOWvKgc4Ux47JkFGr/paKOJLu9hVIVonnu8LXuPbj0fYC82ZA1ZbgX
-qa2zmJ+gfn1u+z+tfMIbWTaW2jcyS0tdNQJjjtunz2LuzC7Ujcm9PGqRcqIip3It
-INH6yjfaGJjmFiRxJUvE5XuJUgkC/VkrBG7KB4HUs9ra2+PMgKhWBwZ8lgg3nds4
-tmI0kWIHdAE42HIw4uuQcSZiwFfzAgMBAAGjggElMIIBITAOBgNVHQ8BAf8EBAMC
-AQYwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQU6k581IAt5RWBhiaMgm3A
-mKTPlw8wRwYDVR0gBEAwPjA8BgRVHSAAMDQwMgYIKwYBBQUHAgEWJmh0dHBzOi8v
-d3d3Lmdsb2JhbHNpZ24uY29tL3JlcG9zaXRvcnkvMDMGA1UdHwQsMCowKKAmoCSG
-Imh0dHA6Ly9jcmwuZ2xvYmFsc2lnbi5uZXQvcm9vdC5jcmwwPQYIKwYBBQUHAQEE
-MTAvMC0GCCsGAQUFBzABhiFodHRwOi8vb2NzcC5nbG9iYWxzaWduLmNvbS9yb290
-cjEwHwYDVR0jBBgwFoAUYHtmGkUNl8qJUC99BM00qP/8/UswDQYJKoZIhvcNAQEL
-BQADggEBANdFnqDc4ONhWgt9d4QXLWVagpqNoycqhffJ7+mG/dRHzQFSlsVDvTex
-4bjyqdKKEYRxkRWJ3AKdC8tsM4U0KJ4gsrGX3G0LEME8zV/qXdeYMcU0mVwAYVXE
-GwJbxeOJyLS4bx448lYm6UHvPc2smU9ZSlctS32ux4j71pg79eXw6ImJuYsDy1oj
-H6T9uOr7Lp2uanMJvPzVoLVEgqtEkS5QLlfBQ9iRBIvpES5ftD953x77PzAAi1Pj
-tywdO02L3ORkHQRYM68bVeerDL8wBHTk8w4vMDmNSwSMHnVmZkngvkA0x1xaUZK6
-EjxS1QSCVS1npd+3lXzuP8MIugS+wEY=
------END CERTIFICATE-----
-#endif
-static const unsigned char kDERCert12[] = {
- 0x30, 0x82, 0x04, 0x63, 0x30, 0x82, 0x03, 0x4b, 0xa0, 0x03, 0x02, 0x01,
- 0x02, 0x02, 0x0b, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01, 0x44, 0x4e, 0xf0,
- 0x3e, 0x20, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
- 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x57, 0x31, 0x0b, 0x30, 0x09, 0x06,
- 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x42, 0x45, 0x31, 0x19, 0x30, 0x17,
- 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x10, 0x47, 0x6c, 0x6f, 0x62, 0x61,
- 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x6e, 0x76, 0x2d, 0x73, 0x61, 0x31,
- 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x07, 0x52, 0x6f,
- 0x6f, 0x74, 0x20, 0x43, 0x41, 0x31, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55,
- 0x04, 0x03, 0x13, 0x12, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x53, 0x69,
- 0x67, 0x6e, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41, 0x30, 0x1e,
- 0x17, 0x0d, 0x31, 0x34, 0x30, 0x32, 0x32, 0x30, 0x31, 0x30, 0x30, 0x30,
- 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x34, 0x30, 0x32, 0x32, 0x30, 0x31,
- 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x60, 0x31, 0x0b, 0x30, 0x09,
- 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x42, 0x45, 0x31, 0x19, 0x30,
- 0x17, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x10, 0x47, 0x6c, 0x6f, 0x62,
- 0x61, 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x6e, 0x76, 0x2d, 0x73, 0x61,
- 0x31, 0x36, 0x30, 0x34, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x2d, 0x47,
- 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x44, 0x6f,
- 0x6d, 0x61, 0x69, 0x6e, 0x20, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74,
- 0x69, 0x6f, 0x6e, 0x20, 0x43, 0x41, 0x20, 0x2d, 0x20, 0x53, 0x48, 0x41,
- 0x32, 0x35, 0x36, 0x20, 0x2d, 0x20, 0x47, 0x32, 0x30, 0x82, 0x01, 0x22,
- 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
- 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a,
- 0x02, 0x82, 0x01, 0x01, 0x00, 0xa9, 0xdd, 0xcc, 0x0e, 0xb3, 0xe2, 0x32,
- 0x39, 0xdd, 0x49, 0x22, 0xa8, 0x13, 0x69, 0x93, 0x87, 0x88, 0xe1, 0x0c,
- 0xee, 0x71, 0x7d, 0xbd, 0x90, 0x87, 0x96, 0x5d, 0x59, 0xf2, 0xcc, 0xb3,
- 0xd2, 0x58, 0x57, 0x57, 0xf9, 0x46, 0xef, 0x6c, 0x26, 0xd8, 0x36, 0x42,
- 0x8e, 0x7e, 0x30, 0xb3, 0x2f, 0x9a, 0x3e, 0x53, 0x7b, 0x1f, 0x6e, 0xb6,
- 0xa2, 0x4c, 0x45, 0x1f, 0x3c, 0xd3, 0x15, 0x93, 0x1c, 0x89, 0xed, 0x3c,
- 0xf4, 0x57, 0xde, 0xca, 0xbd, 0xec, 0x06, 0x9a, 0x6a, 0x2a, 0xa0, 0x19,
- 0x52, 0x7f, 0x51, 0xd1, 0x74, 0x39, 0x08, 0x9f, 0xab, 0xeb, 0xd7, 0x86,
- 0x13, 0x15, 0x97, 0xae, 0x36, 0xc3, 0x54, 0x66, 0x0e, 0x5a, 0xf2, 0xa0,
- 0x73, 0x85, 0x31, 0xe3, 0xb2, 0x64, 0x14, 0x6a, 0xff, 0xa5, 0xa2, 0x8e,
- 0x24, 0xbb, 0xbd, 0x85, 0x52, 0x15, 0xa2, 0x79, 0xee, 0xf0, 0xb5, 0xee,
- 0x3d, 0xb8, 0xf4, 0x7d, 0x80, 0xbc, 0xd9, 0x90, 0x35, 0x65, 0xb8, 0x17,
- 0xa9, 0xad, 0xb3, 0x98, 0x9f, 0xa0, 0x7e, 0x7d, 0x6e, 0xfb, 0x3f, 0xad,
- 0x7c, 0xc2, 0x1b, 0x59, 0x36, 0x96, 0xda, 0x37, 0x32, 0x4b, 0x4b, 0x5d,
- 0x35, 0x02, 0x63, 0x8e, 0xdb, 0xa7, 0xcf, 0x62, 0xee, 0xcc, 0x2e, 0xd4,
- 0x8d, 0xc9, 0xbd, 0x3c, 0x6a, 0x91, 0x72, 0xa2, 0x22, 0xa7, 0x72, 0x2d,
- 0x20, 0xd1, 0xfa, 0xca, 0x37, 0xda, 0x18, 0x98, 0xe6, 0x16, 0x24, 0x71,
- 0x25, 0x4b, 0xc4, 0xe5, 0x7b, 0x89, 0x52, 0x09, 0x02, 0xfd, 0x59, 0x2b,
- 0x04, 0x6e, 0xca, 0x07, 0x81, 0xd4, 0xb3, 0xda, 0xda, 0xdb, 0xe3, 0xcc,
- 0x80, 0xa8, 0x56, 0x07, 0x06, 0x7c, 0x96, 0x08, 0x37, 0x9d, 0xdb, 0x38,
- 0xb6, 0x62, 0x34, 0x91, 0x62, 0x07, 0x74, 0x01, 0x38, 0xd8, 0x72, 0x30,
- 0xe2, 0xeb, 0x90, 0x71, 0x26, 0x62, 0xc0, 0x57, 0xf3, 0x02, 0x03, 0x01,
- 0x00, 0x01, 0xa3, 0x82, 0x01, 0x25, 0x30, 0x82, 0x01, 0x21, 0x30, 0x0e,
- 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02,
- 0x01, 0x06, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff,
- 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x00, 0x30, 0x1d,
- 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xea, 0x4e, 0x7c,
- 0xd4, 0x80, 0x2d, 0xe5, 0x15, 0x81, 0x86, 0x26, 0x8c, 0x82, 0x6d, 0xc0,
- 0x98, 0xa4, 0xcf, 0x97, 0x0f, 0x30, 0x47, 0x06, 0x03, 0x55, 0x1d, 0x20,
- 0x04, 0x40, 0x30, 0x3e, 0x30, 0x3c, 0x06, 0x04, 0x55, 0x1d, 0x20, 0x00,
- 0x30, 0x34, 0x30, 0x32, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
- 0x02, 0x01, 0x16, 0x26, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f,
- 0x77, 0x77, 0x77, 0x2e, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x73, 0x69,
- 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73,
- 0x69, 0x74, 0x6f, 0x72, 0x79, 0x2f, 0x30, 0x33, 0x06, 0x03, 0x55, 0x1d,
- 0x1f, 0x04, 0x2c, 0x30, 0x2a, 0x30, 0x28, 0xa0, 0x26, 0xa0, 0x24, 0x86,
- 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e,
- 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x6e,
- 0x65, 0x74, 0x2f, 0x72, 0x6f, 0x6f, 0x74, 0x2e, 0x63, 0x72, 0x6c, 0x30,
- 0x3d, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04,
- 0x31, 0x30, 0x2f, 0x30, 0x2d, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05,
- 0x07, 0x30, 0x01, 0x86, 0x21, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f,
- 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x73,
- 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x6f, 0x6f, 0x74,
- 0x72, 0x31, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30,
- 0x16, 0x80, 0x14, 0x60, 0x7b, 0x66, 0x1a, 0x45, 0x0d, 0x97, 0xca, 0x89,
- 0x50, 0x2f, 0x7d, 0x04, 0xcd, 0x34, 0xa8, 0xff, 0xfc, 0xfd, 0x4b, 0x30,
- 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b,
- 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0xd7, 0x45, 0x9e, 0xa0, 0xdc,
- 0xe0, 0xe3, 0x61, 0x5a, 0x0b, 0x7d, 0x77, 0x84, 0x17, 0x2d, 0x65, 0x5a,
- 0x82, 0x9a, 0x8d, 0xa3, 0x27, 0x2a, 0x85, 0xf7, 0xc9, 0xef, 0xe9, 0x86,
- 0xfd, 0xd4, 0x47, 0xcd, 0x01, 0x52, 0x96, 0xc5, 0x43, 0xbd, 0x37, 0xb1,
- 0xe1, 0xb8, 0xf2, 0xa9, 0xd2, 0x8a, 0x11, 0x84, 0x71, 0x91, 0x15, 0x89,
- 0xdc, 0x02, 0x9d, 0x0b, 0xcb, 0x6c, 0x33, 0x85, 0x34, 0x28, 0x9e, 0x20,
- 0xb2, 0xb1, 0x97, 0xdc, 0x6d, 0x0b, 0x10, 0xc1, 0x3c, 0xcd, 0x5f, 0xea,
- 0x5d, 0xd7, 0x98, 0x31, 0xc5, 0x34, 0x99, 0x5c, 0x00, 0x61, 0x55, 0xc4,
- 0x1b, 0x02, 0x5b, 0xc5, 0xe3, 0x89, 0xc8, 0xb4, 0xb8, 0x6f, 0x1e, 0x38,
- 0xf2, 0x56, 0x26, 0xe9, 0x41, 0xef, 0x3d, 0xcd, 0xac, 0x99, 0x4f, 0x59,
- 0x4a, 0x57, 0x2d, 0x4b, 0x7d, 0xae, 0xc7, 0x88, 0xfb, 0xd6, 0x98, 0x3b,
- 0xf5, 0xe5, 0xf0, 0xe8, 0x89, 0x89, 0xb9, 0x8b, 0x03, 0xcb, 0x5a, 0x23,
- 0x1f, 0xa4, 0xfd, 0xb8, 0xea, 0xfb, 0x2e, 0x9d, 0xae, 0x6a, 0x73, 0x09,
- 0xbc, 0xfc, 0xd5, 0xa0, 0xb5, 0x44, 0x82, 0xab, 0x44, 0x91, 0x2e, 0x50,
- 0x2e, 0x57, 0xc1, 0x43, 0xd8, 0x91, 0x04, 0x8b, 0xe9, 0x11, 0x2e, 0x5f,
- 0xb4, 0x3f, 0x79, 0xdf, 0x1e, 0xfb, 0x3f, 0x30, 0x00, 0x8b, 0x53, 0xe3,
- 0xb7, 0x2c, 0x1d, 0x3b, 0x4d, 0x8b, 0xdc, 0xe4, 0x64, 0x1d, 0x04, 0x58,
- 0x33, 0xaf, 0x1b, 0x55, 0xe7, 0xab, 0x0c, 0xbf, 0x30, 0x04, 0x74, 0xe4,
- 0xf3, 0x0e, 0x2f, 0x30, 0x39, 0x8d, 0x4b, 0x04, 0x8c, 0x1e, 0x75, 0x66,
- 0x66, 0x49, 0xe0, 0xbe, 0x40, 0x34, 0xc7, 0x5c, 0x5a, 0x51, 0x92, 0xba,
- 0x12, 0x3c, 0x52, 0xd5, 0x04, 0x82, 0x55, 0x2d, 0x67, 0xa5, 0xdf, 0xb7,
- 0x95, 0x7c, 0xee, 0x3f, 0xc3, 0x08, 0xba, 0x04, 0xbe, 0xc0, 0x46,
-};
-
-#if 0
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number:
- 04:00:00:00:00:01:44:4e:f0:42:47
- Signature Algorithm: sha256WithRSAEncryption
- Issuer: C=BE, O=GlobalSign nv-sa, OU=Root CA, CN=GlobalSign Root CA
- Validity
- Not Before: Feb 20 10:00:00 2014 GMT
- Not After : Feb 20 10:00:00 2024 GMT
- Subject: C=BE, O=GlobalSign nv-sa, CN=GlobalSign Organization Validation CA - SHA256 - G2
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:c7:0e:6c:3f:23:93:7f:cc:70:a5:9d:20:c3:0e:
- 53:3f:7e:c0:4e:c2:98:49:ca:47:d5:23:ef:03:34:
- 85:74:c8:a3:02:2e:46:5c:0b:7d:c9:88:9d:4f:8b:
- f0:f8:9c:6c:8c:55:35:db:bf:f2:b3:ea:fb:e3:56:
- e7:4a:46:d9:13:22:ca:36:d5:9b:c1:a8:e3:96:43:
- 93:f2:0c:bc:e6:f9:e6:e8:99:c8:63:48:78:7f:57:
- 36:69:1a:19:1d:5a:d1:d4:7d:c2:9c:d4:7f:e1:80:
- 12:ae:7a:ea:88:ea:57:d8:ca:0a:0a:3a:12:49:a2:
- 62:19:7a:0d:24:f7:37:eb:b4:73:92:7b:05:23:9b:
- 12:b5:ce:eb:29:df:a4:14:02:b9:01:a5:d4:a6:9c:
- 43:64:88:de:f8:7e:fe:e3:f5:1e:e5:fe:dc:a3:a8:
- e4:66:31:d9:4c:25:e9:18:b9:89:59:09:ae:e9:9d:
- 1c:6d:37:0f:4a:1e:35:20:28:e2:af:d4:21:8b:01:
- c4:45:ad:6e:2b:63:ab:92:6b:61:0a:4d:20:ed:73:
- ba:7c:ce:fe:16:b5:db:9f:80:f0:d6:8b:6c:d9:08:
- 79:4a:4f:78:65:da:92:bc:be:35:f9:b3:c4:f9:27:
- 80:4e:ff:96:52:e6:02:20:e1:07:73:e9:5d:2b:bd:
- b2:f1
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Key Usage: critical
- Certificate Sign, CRL Sign
- X509v3 Basic Constraints: critical
- CA:TRUE, pathlen:0
- X509v3 Subject Key Identifier:
- 96:DE:61:F1:BD:1C:16:29:53:1C:C0:CC:7D:3B:83:00:40:E6:1A:7C
- X509v3 Certificate Policies:
- Policy: X509v3 Any Policy
- CPS: https://www.globalsign.com/repository/
-
- X509v3 CRL Distribution Points:
-
- Full Name:
- URI:http://crl.globalsign.net/root.crl
-
- Authority Information Access:
- OCSP - URI:http://ocsp.globalsign.com/rootr1
-
- X509v3 Authority Key Identifier:
- keyid:60:7B:66:1A:45:0D:97:CA:89:50:2F:7D:04:CD:34:A8:FF:FC:FD:4B
-
- Signature Algorithm: sha256WithRSAEncryption
- 46:2a:ee:5e:bd:ae:01:60:37:31:11:86:71:74:b6:46:49:c8:
- 10:16:fe:2f:62:23:17:ab:1f:87:f8:82:ed:ca:df:0e:2c:df:
- 64:75:8e:e5:18:72:a7:8c:3a:8b:c9:ac:a5:77:50:f7:ef:9e:
- a4:e0:a0:8f:14:57:a3:2a:5f:ec:7e:6d:10:e6:ba:8d:b0:08:
- 87:76:0e:4c:b2:d9:51:bb:11:02:f2:5c:dd:1c:bd:f3:55:96:
- 0f:d4:06:c0:fc:e2:23:8a:24:70:d3:bb:f0:79:1a:a7:61:70:
- 83:8a:af:06:c5:20:d8:a1:63:d0:6c:ae:4f:32:d7:ae:7c:18:
- 45:75:05:29:77:df:42:40:64:64:86:be:2a:76:09:31:6f:1d:
- 24:f4:99:d0:85:fe:f2:21:08:f9:c6:f6:f1:d0:59:ed:d6:56:
- 3c:08:28:03:67:ba:f0:f9:f1:90:16:47:ae:67:e6:bc:80:48:
- e9:42:76:34:97:55:69:24:0e:83:d6:a0:2d:b4:f5:f3:79:8a:
- 49:28:74:1a:41:a1:c2:d3:24:88:35:30:60:94:17:b4:e1:04:
- 22:31:3d:3b:2f:17:06:b2:b8:9d:86:2b:5a:69:ef:83:f5:4b:
- c4:aa:b4:2a:f8:7c:a1:b1:85:94:8c:f4:0c:87:0c:f4:ac:40:
- f8:59:49:98
------BEGIN CERTIFICATE-----
-MIIEaTCCA1GgAwIBAgILBAAAAAABRE7wQkcwDQYJKoZIhvcNAQELBQAwVzELMAkG
-A1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jv
-b3QgQ0ExGzAZBgNVBAMTEkdsb2JhbFNpZ24gUm9vdCBDQTAeFw0xNDAyMjAxMDAw
-MDBaFw0yNDAyMjAxMDAwMDBaMGYxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9i
-YWxTaWduIG52LXNhMTwwOgYDVQQDEzNHbG9iYWxTaWduIE9yZ2FuaXphdGlvbiBW
-YWxpZGF0aW9uIENBIC0gU0hBMjU2IC0gRzIwggEiMA0GCSqGSIb3DQEBAQUAA4IB
-DwAwggEKAoIBAQDHDmw/I5N/zHClnSDDDlM/fsBOwphJykfVI+8DNIV0yKMCLkZc
-C33JiJ1Pi/D4nGyMVTXbv/Kz6vvjVudKRtkTIso21ZvBqOOWQ5PyDLzm+ebomchj
-SHh/VzZpGhkdWtHUfcKc1H/hgBKueuqI6lfYygoKOhJJomIZeg0k9zfrtHOSewUj
-mxK1zusp36QUArkBpdSmnENkiN74fv7j9R7l/tyjqORmMdlMJekYuYlZCa7pnRxt
-Nw9KHjUgKOKv1CGLAcRFrW4rY6uSa2EKTSDtc7p8zv4WtdufgPDWi2zZCHlKT3hl
-2pK8vjX5s8T5J4BO/5ZS5gIg4Qdz6V0rvbLxAgMBAAGjggElMIIBITAOBgNVHQ8B
-Af8EBAMCAQYwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQUlt5h8b0cFilT
-HMDMfTuDAEDmGnwwRwYDVR0gBEAwPjA8BgRVHSAAMDQwMgYIKwYBBQUHAgEWJmh0
-dHBzOi8vd3d3Lmdsb2JhbHNpZ24uY29tL3JlcG9zaXRvcnkvMDMGA1UdHwQsMCow
-KKAmoCSGImh0dHA6Ly9jcmwuZ2xvYmFsc2lnbi5uZXQvcm9vdC5jcmwwPQYIKwYB
-BQUHAQEEMTAvMC0GCCsGAQUFBzABhiFodHRwOi8vb2NzcC5nbG9iYWxzaWduLmNv
-bS9yb290cjEwHwYDVR0jBBgwFoAUYHtmGkUNl8qJUC99BM00qP/8/UswDQYJKoZI
-hvcNAQELBQADggEBAEYq7l69rgFgNzERhnF0tkZJyBAW/i9iIxerH4f4gu3K3w4s
-32R1juUYcqeMOovJrKV3UPfvnqTgoI8UV6MqX+x+bRDmuo2wCId2Dkyy2VG7EQLy
-XN0cvfNVlg/UBsD84iOKJHDTu/B5GqdhcIOKrwbFINihY9Bsrk8y1658GEV1BSl3
-30JAZGSGvip2CTFvHST0mdCF/vIhCPnG9vHQWe3WVjwIKANnuvD58ZAWR65n5ryA
-SOlCdjSXVWkkDoPWoC209fN5ikkodBpBocLTJIg1MGCUF7ThBCIxPTsvFwayuJ2G
-K1pp74P1S8SqtCr4fKGxhZSM9AyHDPSsQPhZSZg=
------END CERTIFICATE-----
-#endif
-static const unsigned char kDERCert13[] = {
- 0x30, 0x82, 0x04, 0x69, 0x30, 0x82, 0x03, 0x51, 0xa0, 0x03, 0x02, 0x01,
- 0x02, 0x02, 0x0b, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01, 0x44, 0x4e, 0xf0,
- 0x42, 0x47, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
- 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x57, 0x31, 0x0b, 0x30, 0x09, 0x06,
- 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x42, 0x45, 0x31, 0x19, 0x30, 0x17,
- 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x10, 0x47, 0x6c, 0x6f, 0x62, 0x61,
- 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x6e, 0x76, 0x2d, 0x73, 0x61, 0x31,
- 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x07, 0x52, 0x6f,
- 0x6f, 0x74, 0x20, 0x43, 0x41, 0x31, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55,
- 0x04, 0x03, 0x13, 0x12, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x53, 0x69,
- 0x67, 0x6e, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41, 0x30, 0x1e,
- 0x17, 0x0d, 0x31, 0x34, 0x30, 0x32, 0x32, 0x30, 0x31, 0x30, 0x30, 0x30,
- 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x34, 0x30, 0x32, 0x32, 0x30, 0x31,
- 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x66, 0x31, 0x0b, 0x30, 0x09,
- 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x42, 0x45, 0x31, 0x19, 0x30,
- 0x17, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x10, 0x47, 0x6c, 0x6f, 0x62,
- 0x61, 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x6e, 0x76, 0x2d, 0x73, 0x61,
- 0x31, 0x3c, 0x30, 0x3a, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x33, 0x47,
- 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x4f, 0x72,
- 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x56,
- 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x43, 0x41,
- 0x20, 0x2d, 0x20, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, 0x20, 0x2d, 0x20,
- 0x47, 0x32, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
- 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01,
- 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xc7,
- 0x0e, 0x6c, 0x3f, 0x23, 0x93, 0x7f, 0xcc, 0x70, 0xa5, 0x9d, 0x20, 0xc3,
- 0x0e, 0x53, 0x3f, 0x7e, 0xc0, 0x4e, 0xc2, 0x98, 0x49, 0xca, 0x47, 0xd5,
- 0x23, 0xef, 0x03, 0x34, 0x85, 0x74, 0xc8, 0xa3, 0x02, 0x2e, 0x46, 0x5c,
- 0x0b, 0x7d, 0xc9, 0x88, 0x9d, 0x4f, 0x8b, 0xf0, 0xf8, 0x9c, 0x6c, 0x8c,
- 0x55, 0x35, 0xdb, 0xbf, 0xf2, 0xb3, 0xea, 0xfb, 0xe3, 0x56, 0xe7, 0x4a,
- 0x46, 0xd9, 0x13, 0x22, 0xca, 0x36, 0xd5, 0x9b, 0xc1, 0xa8, 0xe3, 0x96,
- 0x43, 0x93, 0xf2, 0x0c, 0xbc, 0xe6, 0xf9, 0xe6, 0xe8, 0x99, 0xc8, 0x63,
- 0x48, 0x78, 0x7f, 0x57, 0x36, 0x69, 0x1a, 0x19, 0x1d, 0x5a, 0xd1, 0xd4,
- 0x7d, 0xc2, 0x9c, 0xd4, 0x7f, 0xe1, 0x80, 0x12, 0xae, 0x7a, 0xea, 0x88,
- 0xea, 0x57, 0xd8, 0xca, 0x0a, 0x0a, 0x3a, 0x12, 0x49, 0xa2, 0x62, 0x19,
- 0x7a, 0x0d, 0x24, 0xf7, 0x37, 0xeb, 0xb4, 0x73, 0x92, 0x7b, 0x05, 0x23,
- 0x9b, 0x12, 0xb5, 0xce, 0xeb, 0x29, 0xdf, 0xa4, 0x14, 0x02, 0xb9, 0x01,
- 0xa5, 0xd4, 0xa6, 0x9c, 0x43, 0x64, 0x88, 0xde, 0xf8, 0x7e, 0xfe, 0xe3,
- 0xf5, 0x1e, 0xe5, 0xfe, 0xdc, 0xa3, 0xa8, 0xe4, 0x66, 0x31, 0xd9, 0x4c,
- 0x25, 0xe9, 0x18, 0xb9, 0x89, 0x59, 0x09, 0xae, 0xe9, 0x9d, 0x1c, 0x6d,
- 0x37, 0x0f, 0x4a, 0x1e, 0x35, 0x20, 0x28, 0xe2, 0xaf, 0xd4, 0x21, 0x8b,
- 0x01, 0xc4, 0x45, 0xad, 0x6e, 0x2b, 0x63, 0xab, 0x92, 0x6b, 0x61, 0x0a,
- 0x4d, 0x20, 0xed, 0x73, 0xba, 0x7c, 0xce, 0xfe, 0x16, 0xb5, 0xdb, 0x9f,
- 0x80, 0xf0, 0xd6, 0x8b, 0x6c, 0xd9, 0x08, 0x79, 0x4a, 0x4f, 0x78, 0x65,
- 0xda, 0x92, 0xbc, 0xbe, 0x35, 0xf9, 0xb3, 0xc4, 0xf9, 0x27, 0x80, 0x4e,
- 0xff, 0x96, 0x52, 0xe6, 0x02, 0x20, 0xe1, 0x07, 0x73, 0xe9, 0x5d, 0x2b,
- 0xbd, 0xb2, 0xf1, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x25,
- 0x30, 0x82, 0x01, 0x21, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01,
- 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x12, 0x06, 0x03,
- 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01,
- 0xff, 0x02, 0x01, 0x00, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04,
- 0x16, 0x04, 0x14, 0x96, 0xde, 0x61, 0xf1, 0xbd, 0x1c, 0x16, 0x29, 0x53,
- 0x1c, 0xc0, 0xcc, 0x7d, 0x3b, 0x83, 0x00, 0x40, 0xe6, 0x1a, 0x7c, 0x30,
- 0x47, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x40, 0x30, 0x3e, 0x30, 0x3c,
- 0x06, 0x04, 0x55, 0x1d, 0x20, 0x00, 0x30, 0x34, 0x30, 0x32, 0x06, 0x08,
- 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x26, 0x68, 0x74,
- 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x67, 0x6c,
- 0x6f, 0x62, 0x61, 0x6c, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d,
- 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x2f,
- 0x30, 0x33, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x2c, 0x30, 0x2a, 0x30,
- 0x28, 0xa0, 0x26, 0xa0, 0x24, 0x86, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a,
- 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c,
- 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x6e, 0x65, 0x74, 0x2f, 0x72, 0x6f, 0x6f,
- 0x74, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x3d, 0x06, 0x08, 0x2b, 0x06, 0x01,
- 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x31, 0x30, 0x2f, 0x30, 0x2d, 0x06,
- 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x21, 0x68,
- 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x67,
- 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f,
- 0x6d, 0x2f, 0x72, 0x6f, 0x6f, 0x74, 0x72, 0x31, 0x30, 0x1f, 0x06, 0x03,
- 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x60, 0x7b, 0x66,
- 0x1a, 0x45, 0x0d, 0x97, 0xca, 0x89, 0x50, 0x2f, 0x7d, 0x04, 0xcd, 0x34,
- 0xa8, 0xff, 0xfc, 0xfd, 0x4b, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48,
- 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01,
- 0x00, 0x46, 0x2a, 0xee, 0x5e, 0xbd, 0xae, 0x01, 0x60, 0x37, 0x31, 0x11,
- 0x86, 0x71, 0x74, 0xb6, 0x46, 0x49, 0xc8, 0x10, 0x16, 0xfe, 0x2f, 0x62,
- 0x23, 0x17, 0xab, 0x1f, 0x87, 0xf8, 0x82, 0xed, 0xca, 0xdf, 0x0e, 0x2c,
- 0xdf, 0x64, 0x75, 0x8e, 0xe5, 0x18, 0x72, 0xa7, 0x8c, 0x3a, 0x8b, 0xc9,
- 0xac, 0xa5, 0x77, 0x50, 0xf7, 0xef, 0x9e, 0xa4, 0xe0, 0xa0, 0x8f, 0x14,
- 0x57, 0xa3, 0x2a, 0x5f, 0xec, 0x7e, 0x6d, 0x10, 0xe6, 0xba, 0x8d, 0xb0,
- 0x08, 0x87, 0x76, 0x0e, 0x4c, 0xb2, 0xd9, 0x51, 0xbb, 0x11, 0x02, 0xf2,
- 0x5c, 0xdd, 0x1c, 0xbd, 0xf3, 0x55, 0x96, 0x0f, 0xd4, 0x06, 0xc0, 0xfc,
- 0xe2, 0x23, 0x8a, 0x24, 0x70, 0xd3, 0xbb, 0xf0, 0x79, 0x1a, 0xa7, 0x61,
- 0x70, 0x83, 0x8a, 0xaf, 0x06, 0xc5, 0x20, 0xd8, 0xa1, 0x63, 0xd0, 0x6c,
- 0xae, 0x4f, 0x32, 0xd7, 0xae, 0x7c, 0x18, 0x45, 0x75, 0x05, 0x29, 0x77,
- 0xdf, 0x42, 0x40, 0x64, 0x64, 0x86, 0xbe, 0x2a, 0x76, 0x09, 0x31, 0x6f,
- 0x1d, 0x24, 0xf4, 0x99, 0xd0, 0x85, 0xfe, 0xf2, 0x21, 0x08, 0xf9, 0xc6,
- 0xf6, 0xf1, 0xd0, 0x59, 0xed, 0xd6, 0x56, 0x3c, 0x08, 0x28, 0x03, 0x67,
- 0xba, 0xf0, 0xf9, 0xf1, 0x90, 0x16, 0x47, 0xae, 0x67, 0xe6, 0xbc, 0x80,
- 0x48, 0xe9, 0x42, 0x76, 0x34, 0x97, 0x55, 0x69, 0x24, 0x0e, 0x83, 0xd6,
- 0xa0, 0x2d, 0xb4, 0xf5, 0xf3, 0x79, 0x8a, 0x49, 0x28, 0x74, 0x1a, 0x41,
- 0xa1, 0xc2, 0xd3, 0x24, 0x88, 0x35, 0x30, 0x60, 0x94, 0x17, 0xb4, 0xe1,
- 0x04, 0x22, 0x31, 0x3d, 0x3b, 0x2f, 0x17, 0x06, 0xb2, 0xb8, 0x9d, 0x86,
- 0x2b, 0x5a, 0x69, 0xef, 0x83, 0xf5, 0x4b, 0xc4, 0xaa, 0xb4, 0x2a, 0xf8,
- 0x7c, 0xa1, 0xb1, 0x85, 0x94, 0x8c, 0xf4, 0x0c, 0x87, 0x0c, 0xf4, 0xac,
- 0x40, 0xf8, 0x59, 0x49, 0x98,
-};
-
-#if 0
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number:
- 4d:5f:2c:34:08:b2:4c:20:cd:6d:50:7e:24:4d:c9:ec
- Signature Algorithm: sha1WithRSAEncryption
- Issuer: C=US, O=thawte, Inc., OU=Certification Services Division, OU=(c) 2006 thawte, Inc. - For authorized use only, CN=thawte Primary Root CA
- Validity
- Not Before: Feb 8 00:00:00 2010 GMT
- Not After : Feb 7 23:59:59 2020 GMT
- Subject: C=US, O=Thawte, Inc., CN=Thawte SSL CA
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:99:e4:85:5b:76:49:7d:2f:05:d8:c5:ac:c8:c8:
- a9:d3:dc:98:e6:d7:34:a6:2f:0c:f2:22:26:d8:a3:
- c9:14:4c:8f:05:a4:45:e8:14:0c:58:90:05:1a:b7:
- c5:c1:06:a5:80:af:bb:1d:49:6b:52:34:88:c3:59:
- e7:ef:6b:c4:27:41:8c:2b:66:1d:d0:e0:a3:97:98:
- 19:34:4b:41:d5:98:d5:c7:05:ad:a2:e4:d7:ed:0c:
- ad:4f:c1:b5:b0:21:fd:3e:50:53:b2:c4:90:d0:d4:
- 30:67:6c:9a:f1:0e:74:c4:c2:dc:8a:e8:97:ff:c9:
- 92:ae:01:8a:56:0a:98:32:b0:00:23:ec:90:1a:60:
- c3:ed:bb:3a:cb:0f:63:9f:0d:44:c9:52:e1:25:96:
- bf:ed:50:95:89:7f:56:14:b1:b7:61:1d:1c:07:8c:
- 3a:2c:f7:ff:80:de:39:45:d5:af:1a:d1:78:d8:c7:
- 71:6a:a3:19:a7:32:50:21:e9:f2:0e:a1:c6:13:03:
- 44:48:d1:66:a8:52:57:d7:11:b4:93:8b:e5:99:9f:
- 5d:e7:78:51:e5:4d:f6:b7:59:b4:76:b5:09:37:4d:
- 06:38:13:7a:1c:08:98:5c:c4:48:4a:cb:52:a0:a9:
- f8:b1:9d:8e:7b:79:b0:20:2f:3c:96:a8:11:62:47:
- bb:11
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- Authority Information Access:
- OCSP - URI:http://ocsp.thawte.com
-
- X509v3 Basic Constraints: critical
- CA:TRUE, pathlen:0
- X509v3 CRL Distribution Points:
-
- Full Name:
- URI:http://crl.thawte.com/ThawtePCA.crl
-
- X509v3 Key Usage: critical
- Certificate Sign, CRL Sign
- X509v3 Subject Alternative Name:
- DirName:/CN=VeriSignMPKI-2-9
- X509v3 Subject Key Identifier:
- A7:A2:83:BB:34:45:40:3D:FC:D5:30:4F:12:B9:3E:A1:01:9F:F6:DB
- X509v3 Authority Key Identifier:
- keyid:7B:5B:45:CF:AF:CE:CB:7A:FD:31:92:1A:6A:B6:F3:46:EB:57:48:50
-
- Signature Algorithm: sha1WithRSAEncryption
- 80:22:80:e0:6c:c8:95:16:d7:57:26:87:f3:72:34:db:c6:72:
- 56:27:3e:d3:96:f6:2e:25:91:a5:3e:33:97:a7:4b:e5:2f:fb:
- 25:7d:2f:07:61:fa:6f:83:74:4c:4c:53:72:20:a4:7a:cf:51:
- 51:56:81:88:b0:6d:1f:36:2c:c8:2b:b1:88:99:c1:fe:44:ab:
- 48:51:7c:d8:f2:44:64:2a:d8:71:a7:fb:1a:2f:f9:19:8d:34:
- b2:23:bf:c4:4c:55:1d:8e:44:e8:aa:5d:9a:dd:9f:fd:03:c7:
- ba:24:43:8d:2d:47:44:db:f6:d8:98:c8:b2:f9:da:ef:ed:29:
- 5c:69:12:fa:d1:23:96:0f:bf:9c:0d:f2:79:45:53:37:9a:56:
- 2f:e8:57:10:70:f6:ee:89:0c:49:89:9a:c1:23:f5:c2:2a:cc:
- 41:cf:22:ab:65:6e:b7:94:82:6d:2f:40:5f:58:de:eb:95:2b:
- a6:72:68:52:19:91:2a:ae:75:9d:4e:92:e6:ca:de:54:ea:18:
- ab:25:3c:e6:64:a6:79:1f:26:7d:61:ed:7d:d2:e5:71:55:d8:
- 93:17:7c:14:38:30:3c:df:86:e3:4c:ad:49:e3:97:59:ce:1b:
- 9b:2b:ce:dc:65:d4:0b:28:6b:4e:84:46:51:44:f7:33:08:2d:
- 58:97:21:ae
------BEGIN CERTIFICATE-----
-MIIEbDCCA1SgAwIBAgIQTV8sNAiyTCDNbVB+JE3J7DANBgkqhkiG9w0BAQUFADCB
-qTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMf
-Q2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIw
-MDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxHzAdBgNV
-BAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwHhcNMTAwMjA4MDAwMDAwWhcNMjAw
-MjA3MjM1OTU5WjA8MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMVGhhd3RlLCBJbmMu
-MRYwFAYDVQQDEw1UaGF3dGUgU1NMIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
-MIIBCgKCAQEAmeSFW3ZJfS8F2MWsyMip09yY5tc0pi8M8iIm2KPJFEyPBaRF6BQM
-WJAFGrfFwQalgK+7HUlrUjSIw1nn72vEJ0GMK2Yd0OCjl5gZNEtB1ZjVxwWtouTX
-7QytT8G1sCH9PlBTssSQ0NQwZ2ya8Q50xMLciuiX/8mSrgGKVgqYMrAAI+yQGmDD
-7bs6yw9jnw1EyVLhJZa/7VCViX9WFLG3YR0cB4w6LPf/gN45RdWvGtF42MdxaqMZ
-pzJQIenyDqHGEwNESNFmqFJX1xG0k4vlmZ9d53hR5U32t1m0drUJN00GOBN6HAiY
-XMRISstSoKn4sZ2Oe3mwIC88lqgRYke7EQIDAQABo4H7MIH4MDIGCCsGAQUFBwEB
-BCYwJDAiBggrBgEFBQcwAYYWaHR0cDovL29jc3AudGhhd3RlLmNvbTASBgNVHRMB
-Af8ECDAGAQH/AgEAMDQGA1UdHwQtMCswKaAnoCWGI2h0dHA6Ly9jcmwudGhhd3Rl
-LmNvbS9UaGF3dGVQQ0EuY3JsMA4GA1UdDwEB/wQEAwIBBjAoBgNVHREEITAfpB0w
-GzEZMBcGA1UEAxMQVmVyaVNpZ25NUEtJLTItOTAdBgNVHQ4EFgQUp6KDuzRFQD38
-1TBPErk+oQGf9tswHwYDVR0jBBgwFoAUe1tFz6/Oy3r9MZIaarbzRutXSFAwDQYJ
-KoZIhvcNAQEFBQADggEBAIAigOBsyJUW11cmh/NyNNvGclYnPtOW9i4lkaU+M5en
-S+Uv+yV9Lwdh+m+DdExMU3IgpHrPUVFWgYiwbR82LMgrsYiZwf5Eq0hRfNjyRGQq
-2HGn+xov+RmNNLIjv8RMVR2OROiqXZrdn/0Dx7okQ40tR0Tb9tiYyLL52u/tKVxp
-EvrRI5YPv5wN8nlFUzeaVi/oVxBw9u6JDEmJmsEj9cIqzEHPIqtlbreUgm0vQF9Y
-3uuVK6ZyaFIZkSqudZ1OkubK3lTqGKslPOZkpnkfJn1h7X3S5XFV2JMXfBQ4MDzf
-huNMrUnjl1nOG5srztxl1Asoa06ERlFE9zMILViXIa4=
------END CERTIFICATE-----
-#endif
-static const unsigned char kDERCert14[] = {
- 0x30, 0x82, 0x04, 0x6c, 0x30, 0x82, 0x03, 0x54, 0xa0, 0x03, 0x02, 0x01,
- 0x02, 0x02, 0x10, 0x4d, 0x5f, 0x2c, 0x34, 0x08, 0xb2, 0x4c, 0x20, 0xcd,
- 0x6d, 0x50, 0x7e, 0x24, 0x4d, 0xc9, 0xec, 0x30, 0x0d, 0x06, 0x09, 0x2a,
- 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x81,
- 0xa9, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
- 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13,
- 0x0c, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63,
- 0x2e, 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1f,
- 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f,
- 0x6e, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, 0x44,
- 0x69, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x31, 0x38, 0x30, 0x36, 0x06,
- 0x03, 0x55, 0x04, 0x0b, 0x13, 0x2f, 0x28, 0x63, 0x29, 0x20, 0x32, 0x30,
- 0x30, 0x36, 0x20, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2c, 0x20, 0x49,
- 0x6e, 0x63, 0x2e, 0x20, 0x2d, 0x20, 0x46, 0x6f, 0x72, 0x20, 0x61, 0x75,
- 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x20, 0x75, 0x73, 0x65,
- 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55,
- 0x04, 0x03, 0x13, 0x16, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x20, 0x50,
- 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20,
- 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x30, 0x30, 0x32, 0x30, 0x38,
- 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x30, 0x30,
- 0x32, 0x30, 0x37, 0x32, 0x33, 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x3c,
- 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55,
- 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0c,
- 0x54, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e,
- 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0d, 0x54,
- 0x68, 0x61, 0x77, 0x74, 0x65, 0x20, 0x53, 0x53, 0x4c, 0x20, 0x43, 0x41,
- 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
- 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00,
- 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0x99, 0xe4, 0x85,
- 0x5b, 0x76, 0x49, 0x7d, 0x2f, 0x05, 0xd8, 0xc5, 0xac, 0xc8, 0xc8, 0xa9,
- 0xd3, 0xdc, 0x98, 0xe6, 0xd7, 0x34, 0xa6, 0x2f, 0x0c, 0xf2, 0x22, 0x26,
- 0xd8, 0xa3, 0xc9, 0x14, 0x4c, 0x8f, 0x05, 0xa4, 0x45, 0xe8, 0x14, 0x0c,
- 0x58, 0x90, 0x05, 0x1a, 0xb7, 0xc5, 0xc1, 0x06, 0xa5, 0x80, 0xaf, 0xbb,
- 0x1d, 0x49, 0x6b, 0x52, 0x34, 0x88, 0xc3, 0x59, 0xe7, 0xef, 0x6b, 0xc4,
- 0x27, 0x41, 0x8c, 0x2b, 0x66, 0x1d, 0xd0, 0xe0, 0xa3, 0x97, 0x98, 0x19,
- 0x34, 0x4b, 0x41, 0xd5, 0x98, 0xd5, 0xc7, 0x05, 0xad, 0xa2, 0xe4, 0xd7,
- 0xed, 0x0c, 0xad, 0x4f, 0xc1, 0xb5, 0xb0, 0x21, 0xfd, 0x3e, 0x50, 0x53,
- 0xb2, 0xc4, 0x90, 0xd0, 0xd4, 0x30, 0x67, 0x6c, 0x9a, 0xf1, 0x0e, 0x74,
- 0xc4, 0xc2, 0xdc, 0x8a, 0xe8, 0x97, 0xff, 0xc9, 0x92, 0xae, 0x01, 0x8a,
- 0x56, 0x0a, 0x98, 0x32, 0xb0, 0x00, 0x23, 0xec, 0x90, 0x1a, 0x60, 0xc3,
- 0xed, 0xbb, 0x3a, 0xcb, 0x0f, 0x63, 0x9f, 0x0d, 0x44, 0xc9, 0x52, 0xe1,
- 0x25, 0x96, 0xbf, 0xed, 0x50, 0x95, 0x89, 0x7f, 0x56, 0x14, 0xb1, 0xb7,
- 0x61, 0x1d, 0x1c, 0x07, 0x8c, 0x3a, 0x2c, 0xf7, 0xff, 0x80, 0xde, 0x39,
- 0x45, 0xd5, 0xaf, 0x1a, 0xd1, 0x78, 0xd8, 0xc7, 0x71, 0x6a, 0xa3, 0x19,
- 0xa7, 0x32, 0x50, 0x21, 0xe9, 0xf2, 0x0e, 0xa1, 0xc6, 0x13, 0x03, 0x44,
- 0x48, 0xd1, 0x66, 0xa8, 0x52, 0x57, 0xd7, 0x11, 0xb4, 0x93, 0x8b, 0xe5,
- 0x99, 0x9f, 0x5d, 0xe7, 0x78, 0x51, 0xe5, 0x4d, 0xf6, 0xb7, 0x59, 0xb4,
- 0x76, 0xb5, 0x09, 0x37, 0x4d, 0x06, 0x38, 0x13, 0x7a, 0x1c, 0x08, 0x98,
- 0x5c, 0xc4, 0x48, 0x4a, 0xcb, 0x52, 0xa0, 0xa9, 0xf8, 0xb1, 0x9d, 0x8e,
- 0x7b, 0x79, 0xb0, 0x20, 0x2f, 0x3c, 0x96, 0xa8, 0x11, 0x62, 0x47, 0xbb,
- 0x11, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x81, 0xfb, 0x30, 0x81, 0xf8,
- 0x30, 0x32, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01,
- 0x04, 0x26, 0x30, 0x24, 0x30, 0x22, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05,
- 0x05, 0x07, 0x30, 0x01, 0x86, 0x16, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f,
- 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65,
- 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01,
- 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x00,
- 0x30, 0x34, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x2d, 0x30, 0x2b, 0x30,
- 0x29, 0xa0, 0x27, 0xa0, 0x25, 0x86, 0x23, 0x68, 0x74, 0x74, 0x70, 0x3a,
- 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65,
- 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x54, 0x68, 0x61, 0x77, 0x74, 0x65, 0x50,
- 0x43, 0x41, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d,
- 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x28,
- 0x06, 0x03, 0x55, 0x1d, 0x11, 0x04, 0x21, 0x30, 0x1f, 0xa4, 0x1d, 0x30,
- 0x1b, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x10,
- 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x4d, 0x50, 0x4b, 0x49,
- 0x2d, 0x32, 0x2d, 0x39, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04,
- 0x16, 0x04, 0x14, 0xa7, 0xa2, 0x83, 0xbb, 0x34, 0x45, 0x40, 0x3d, 0xfc,
- 0xd5, 0x30, 0x4f, 0x12, 0xb9, 0x3e, 0xa1, 0x01, 0x9f, 0xf6, 0xdb, 0x30,
- 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14,
- 0x7b, 0x5b, 0x45, 0xcf, 0xaf, 0xce, 0xcb, 0x7a, 0xfd, 0x31, 0x92, 0x1a,
- 0x6a, 0xb6, 0xf3, 0x46, 0xeb, 0x57, 0x48, 0x50, 0x30, 0x0d, 0x06, 0x09,
- 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03,
- 0x82, 0x01, 0x01, 0x00, 0x80, 0x22, 0x80, 0xe0, 0x6c, 0xc8, 0x95, 0x16,
- 0xd7, 0x57, 0x26, 0x87, 0xf3, 0x72, 0x34, 0xdb, 0xc6, 0x72, 0x56, 0x27,
- 0x3e, 0xd3, 0x96, 0xf6, 0x2e, 0x25, 0x91, 0xa5, 0x3e, 0x33, 0x97, 0xa7,
- 0x4b, 0xe5, 0x2f, 0xfb, 0x25, 0x7d, 0x2f, 0x07, 0x61, 0xfa, 0x6f, 0x83,
- 0x74, 0x4c, 0x4c, 0x53, 0x72, 0x20, 0xa4, 0x7a, 0xcf, 0x51, 0x51, 0x56,
- 0x81, 0x88, 0xb0, 0x6d, 0x1f, 0x36, 0x2c, 0xc8, 0x2b, 0xb1, 0x88, 0x99,
- 0xc1, 0xfe, 0x44, 0xab, 0x48, 0x51, 0x7c, 0xd8, 0xf2, 0x44, 0x64, 0x2a,
- 0xd8, 0x71, 0xa7, 0xfb, 0x1a, 0x2f, 0xf9, 0x19, 0x8d, 0x34, 0xb2, 0x23,
- 0xbf, 0xc4, 0x4c, 0x55, 0x1d, 0x8e, 0x44, 0xe8, 0xaa, 0x5d, 0x9a, 0xdd,
- 0x9f, 0xfd, 0x03, 0xc7, 0xba, 0x24, 0x43, 0x8d, 0x2d, 0x47, 0x44, 0xdb,
- 0xf6, 0xd8, 0x98, 0xc8, 0xb2, 0xf9, 0xda, 0xef, 0xed, 0x29, 0x5c, 0x69,
- 0x12, 0xfa, 0xd1, 0x23, 0x96, 0x0f, 0xbf, 0x9c, 0x0d, 0xf2, 0x79, 0x45,
- 0x53, 0x37, 0x9a, 0x56, 0x2f, 0xe8, 0x57, 0x10, 0x70, 0xf6, 0xee, 0x89,
- 0x0c, 0x49, 0x89, 0x9a, 0xc1, 0x23, 0xf5, 0xc2, 0x2a, 0xcc, 0x41, 0xcf,
- 0x22, 0xab, 0x65, 0x6e, 0xb7, 0x94, 0x82, 0x6d, 0x2f, 0x40, 0x5f, 0x58,
- 0xde, 0xeb, 0x95, 0x2b, 0xa6, 0x72, 0x68, 0x52, 0x19, 0x91, 0x2a, 0xae,
- 0x75, 0x9d, 0x4e, 0x92, 0xe6, 0xca, 0xde, 0x54, 0xea, 0x18, 0xab, 0x25,
- 0x3c, 0xe6, 0x64, 0xa6, 0x79, 0x1f, 0x26, 0x7d, 0x61, 0xed, 0x7d, 0xd2,
- 0xe5, 0x71, 0x55, 0xd8, 0x93, 0x17, 0x7c, 0x14, 0x38, 0x30, 0x3c, 0xdf,
- 0x86, 0xe3, 0x4c, 0xad, 0x49, 0xe3, 0x97, 0x59, 0xce, 0x1b, 0x9b, 0x2b,
- 0xce, 0xdc, 0x65, 0xd4, 0x0b, 0x28, 0x6b, 0x4e, 0x84, 0x46, 0x51, 0x44,
- 0xf7, 0x33, 0x08, 0x2d, 0x58, 0x97, 0x21, 0xae,
-};
-
-#if 0
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number:
- 6e:8a:90:eb:cf:f0:44:8a:72:0d:08:05:d0:82:a5:44
- Signature Algorithm: sha256WithRSAEncryption
- Issuer: C=US, O=GeoTrust Inc., CN=GeoTrust Primary Certification Authority
- Validity
- Not Before: Oct 31 00:00:00 2013 GMT
- Not After : Oct 30 23:59:59 2023 GMT
- Subject: C=US, O=GeoTrust Inc., CN=GeoTrust EV SSL CA - G4
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:d9:b4:05:f2:38:67:0f:09:e7:7c:f5:63:2a:e5:
- b9:5e:a8:11:ae:75:71:d9:4c:84:67:ad:89:5d:fc:
- 28:3d:2a:b0:a5:d5:d4:e6:30:0a:84:d4:e4:18:cb:
- 85:37:c5:46:71:eb:1c:7b:69:db:65:69:8c:30:05:
- 3e:07:e1:6f:3c:c1:0b:61:e6:38:44:fc:bc:8c:2f:
- 4e:75:57:f5:96:99:7c:3e:87:1f:0f:90:4b:70:c3:
- 3f:39:45:3b:3a:6b:cb:bb:7b:40:54:d1:8b:4b:a1:
- 72:d2:04:e9:e0:72:1a:93:11:7a:2f:f1:ab:9d:9c:
- 98:58:ae:2c:ea:77:5f:2f:2e:87:af:b8:6b:e3:e2:
- e2:3f:d6:3d:e0:96:44:df:11:55:63:52:2f:f4:26:
- 78:c4:0f:20:4d:0a:c0:68:70:15:86:38:ee:b7:76:
- 88:ab:18:8f:4f:35:1e:d4:8c:c9:db:7e:3d:44:d4:
- 36:8c:c1:37:b5:59:5b:87:f9:e9:f1:d4:c5:28:bd:
- 1d:dc:cc:96:72:d1:7a:a1:a7:20:b5:b8:af:f8:6e:
- a5:60:7b:2b:8d:1f:ee:f4:2b:d6:69:cd:af:ca:80:
- 58:29:e8:4c:00:20:8a:49:0a:6e:8e:8c:a8:d1:00:
- 12:84:b6:c5:e2:95:a2:c0:3b:a4:6b:f0:82:d0:96:
- 5d:25
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Basic Constraints: critical
- CA:TRUE, pathlen:0
- X509v3 Key Usage: critical
- Certificate Sign, CRL Sign
- Authority Information Access:
- OCSP - URI:http://g2.symcb.com
-
- X509v3 Certificate Policies:
- Policy: X509v3 Any Policy
- CPS: https://www.geotrust.com/resources/cps
-
- X509v3 CRL Distribution Points:
-
- Full Name:
- URI:http://g1.symcb.com/GeoTrustPCA.crl
-
- X509v3 Subject Alternative Name:
- DirName:/CN=SymantecPKI-1-538
- X509v3 Subject Key Identifier:
- DE:CF:5C:50:B7:AE:02:1F:15:17:AA:16:E8:0D:B5:28:9D:6A:5A:F3
- X509v3 Authority Key Identifier:
- keyid:2C:D5:50:41:97:15:8B:F0:8F:36:61:5B:4A:FB:6B:D9:99:C9:33:92
-
- Signature Algorithm: sha256WithRSAEncryption
- b4:8e:bd:07:b9:9a:85:ec:3b:67:bd:07:60:61:e6:84:d1:d4:
- ef:eb:1b:ba:0b:82:4b:95:64:b6:66:53:23:bd:b7:84:dd:e4:
- 7b:8d:09:da:cf:b2:f5:f1:c3:bf:87:84:be:4e:a6:a8:c2:e7:
- 12:39:28:34:e0:a4:56:44:40:0c:9f:88:a3:15:d3:e8:d3:5e:
- e3:1c:04:60:fb:69:36:4f:6a:7e:0c:2a:28:c1:f3:aa:58:0e:
- 6c:ce:1d:07:c3:4a:c0:9c:8d:c3:74:b1:ae:82:f0:1a:e1:f9:
- 4e:29:bd:46:de:b7:1d:f9:7d:db:d9:0f:84:cb:92:45:cc:1c:
- b3:18:f6:a0:cf:71:6f:0c:2e:9b:d2:2d:b3:99:93:83:44:ac:
- 15:aa:9b:2e:67:ec:4f:88:69:05:56:7b:8b:b2:43:a9:3a:6c:
- 1c:13:33:25:1b:fd:a8:c8:57:02:fb:1c:e0:d1:bd:3b:56:44:
- 65:c3:63:f5:1b:ef:ec:30:d9:e3:6e:2e:13:e9:39:08:2a:0c:
- 72:f3:9a:cc:f6:27:29:84:d3:ef:4c:c7:84:11:65:1f:c6:e3:
- 81:03:db:87:cc:78:f7:b5:9d:96:3e:6a:7f:bc:11:85:7a:75:
- e6:41:7d:0d:cf:f9:e5:85:69:25:8f:c7:8d:07:2d:f8:69:0f:
- cb:41:53:00
------BEGIN CERTIFICATE-----
-MIIEbjCCA1agAwIBAgIQboqQ68/wRIpyDQgF0IKlRDANBgkqhkiG9w0BAQsFADBY
-MQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjExMC8GA1UEAxMo
-R2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0xMzEw
-MzEwMDAwMDBaFw0yMzEwMzAyMzU5NTlaMEcxCzAJBgNVBAYTAlVTMRYwFAYDVQQK
-Ew1HZW9UcnVzdCBJbmMuMSAwHgYDVQQDExdHZW9UcnVzdCBFViBTU0wgQ0EgLSBH
-NDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANm0BfI4Zw8J53z1Yyrl
-uV6oEa51cdlMhGetiV38KD0qsKXV1OYwCoTU5BjLhTfFRnHrHHtp22VpjDAFPgfh
-bzzBC2HmOET8vIwvTnVX9ZaZfD6HHw+QS3DDPzlFOzpry7t7QFTRi0uhctIE6eBy
-GpMRei/xq52cmFiuLOp3Xy8uh6+4a+Pi4j/WPeCWRN8RVWNSL/QmeMQPIE0KwGhw
-FYY47rd2iKsYj081HtSMydt+PUTUNozBN7VZW4f56fHUxSi9HdzMlnLReqGnILW4
-r/hupWB7K40f7vQr1mnNr8qAWCnoTAAgikkKbo6MqNEAEoS2xeKVosA7pGvwgtCW
-XSUCAwEAAaOCAUMwggE/MBIGA1UdEwEB/wQIMAYBAf8CAQAwDgYDVR0PAQH/BAQD
-AgEGMC8GCCsGAQUFBwEBBCMwITAfBggrBgEFBQcwAYYTaHR0cDovL2cyLnN5bWNi
-LmNvbTBHBgNVHSAEQDA+MDwGBFUdIAAwNDAyBggrBgEFBQcCARYmaHR0cHM6Ly93
-d3cuZ2VvdHJ1c3QuY29tL3Jlc291cmNlcy9jcHMwNAYDVR0fBC0wKzApoCegJYYj
-aHR0cDovL2cxLnN5bWNiLmNvbS9HZW9UcnVzdFBDQS5jcmwwKQYDVR0RBCIwIKQe
-MBwxGjAYBgNVBAMTEVN5bWFudGVjUEtJLTEtNTM4MB0GA1UdDgQWBBTez1xQt64C
-HxUXqhboDbUonWpa8zAfBgNVHSMEGDAWgBQs1VBBlxWL8I82YVtK+2vZmckzkjAN
-BgkqhkiG9w0BAQsFAAOCAQEAtI69B7mahew7Z70HYGHmhNHU7+sbuguCS5VktmZT
-I723hN3ke40J2s+y9fHDv4eEvk6mqMLnEjkoNOCkVkRADJ+IoxXT6NNe4xwEYPtp
-Nk9qfgwqKMHzqlgObM4dB8NKwJyNw3SxroLwGuH5Tim9Rt63Hfl929kPhMuSRcwc
-sxj2oM9xbwwum9Its5mTg0SsFaqbLmfsT4hpBVZ7i7JDqTpsHBMzJRv9qMhXAvsc
-4NG9O1ZEZcNj9Rvv7DDZ424uE+k5CCoMcvOazPYnKYTT70zHhBFlH8bjgQPbh8x4
-97Wdlj5qf7wRhXp15kF9Dc/55YVpJY/HjQct+GkPy0FTAA==
------END CERTIFICATE-----
-#endif
-static const unsigned char kDERCert15[] = {
- 0x30, 0x82, 0x04, 0x6e, 0x30, 0x82, 0x03, 0x56, 0xa0, 0x03, 0x02, 0x01,
- 0x02, 0x02, 0x10, 0x6e, 0x8a, 0x90, 0xeb, 0xcf, 0xf0, 0x44, 0x8a, 0x72,
- 0x0d, 0x08, 0x05, 0xd0, 0x82, 0xa5, 0x44, 0x30, 0x0d, 0x06, 0x09, 0x2a,
- 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x58,
- 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55,
- 0x53, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0d,
- 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x49, 0x6e, 0x63,
- 0x2e, 0x31, 0x31, 0x30, 0x2f, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x28,
- 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x50, 0x72, 0x69,
- 0x6d, 0x61, 0x72, 0x79, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69,
- 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f,
- 0x72, 0x69, 0x74, 0x79, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x33, 0x31, 0x30,
- 0x33, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32,
- 0x33, 0x31, 0x30, 0x33, 0x30, 0x32, 0x33, 0x35, 0x39, 0x35, 0x39, 0x5a,
- 0x30, 0x47, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
- 0x02, 0x55, 0x53, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a,
- 0x13, 0x0d, 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x49,
- 0x6e, 0x63, 0x2e, 0x31, 0x20, 0x30, 0x1e, 0x06, 0x03, 0x55, 0x04, 0x03,
- 0x13, 0x17, 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x45,
- 0x56, 0x20, 0x53, 0x53, 0x4c, 0x20, 0x43, 0x41, 0x20, 0x2d, 0x20, 0x47,
- 0x34, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48,
- 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f,
- 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xd9, 0xb4,
- 0x05, 0xf2, 0x38, 0x67, 0x0f, 0x09, 0xe7, 0x7c, 0xf5, 0x63, 0x2a, 0xe5,
- 0xb9, 0x5e, 0xa8, 0x11, 0xae, 0x75, 0x71, 0xd9, 0x4c, 0x84, 0x67, 0xad,
- 0x89, 0x5d, 0xfc, 0x28, 0x3d, 0x2a, 0xb0, 0xa5, 0xd5, 0xd4, 0xe6, 0x30,
- 0x0a, 0x84, 0xd4, 0xe4, 0x18, 0xcb, 0x85, 0x37, 0xc5, 0x46, 0x71, 0xeb,
- 0x1c, 0x7b, 0x69, 0xdb, 0x65, 0x69, 0x8c, 0x30, 0x05, 0x3e, 0x07, 0xe1,
- 0x6f, 0x3c, 0xc1, 0x0b, 0x61, 0xe6, 0x38, 0x44, 0xfc, 0xbc, 0x8c, 0x2f,
- 0x4e, 0x75, 0x57, 0xf5, 0x96, 0x99, 0x7c, 0x3e, 0x87, 0x1f, 0x0f, 0x90,
- 0x4b, 0x70, 0xc3, 0x3f, 0x39, 0x45, 0x3b, 0x3a, 0x6b, 0xcb, 0xbb, 0x7b,
- 0x40, 0x54, 0xd1, 0x8b, 0x4b, 0xa1, 0x72, 0xd2, 0x04, 0xe9, 0xe0, 0x72,
- 0x1a, 0x93, 0x11, 0x7a, 0x2f, 0xf1, 0xab, 0x9d, 0x9c, 0x98, 0x58, 0xae,
- 0x2c, 0xea, 0x77, 0x5f, 0x2f, 0x2e, 0x87, 0xaf, 0xb8, 0x6b, 0xe3, 0xe2,
- 0xe2, 0x3f, 0xd6, 0x3d, 0xe0, 0x96, 0x44, 0xdf, 0x11, 0x55, 0x63, 0x52,
- 0x2f, 0xf4, 0x26, 0x78, 0xc4, 0x0f, 0x20, 0x4d, 0x0a, 0xc0, 0x68, 0x70,
- 0x15, 0x86, 0x38, 0xee, 0xb7, 0x76, 0x88, 0xab, 0x18, 0x8f, 0x4f, 0x35,
- 0x1e, 0xd4, 0x8c, 0xc9, 0xdb, 0x7e, 0x3d, 0x44, 0xd4, 0x36, 0x8c, 0xc1,
- 0x37, 0xb5, 0x59, 0x5b, 0x87, 0xf9, 0xe9, 0xf1, 0xd4, 0xc5, 0x28, 0xbd,
- 0x1d, 0xdc, 0xcc, 0x96, 0x72, 0xd1, 0x7a, 0xa1, 0xa7, 0x20, 0xb5, 0xb8,
- 0xaf, 0xf8, 0x6e, 0xa5, 0x60, 0x7b, 0x2b, 0x8d, 0x1f, 0xee, 0xf4, 0x2b,
- 0xd6, 0x69, 0xcd, 0xaf, 0xca, 0x80, 0x58, 0x29, 0xe8, 0x4c, 0x00, 0x20,
- 0x8a, 0x49, 0x0a, 0x6e, 0x8e, 0x8c, 0xa8, 0xd1, 0x00, 0x12, 0x84, 0xb6,
- 0xc5, 0xe2, 0x95, 0xa2, 0xc0, 0x3b, 0xa4, 0x6b, 0xf0, 0x82, 0xd0, 0x96,
- 0x5d, 0x25, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x43, 0x30,
- 0x82, 0x01, 0x3f, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01,
- 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x00, 0x30,
- 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03,
- 0x02, 0x01, 0x06, 0x30, 0x2f, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05,
- 0x07, 0x01, 0x01, 0x04, 0x23, 0x30, 0x21, 0x30, 0x1f, 0x06, 0x08, 0x2b,
- 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x13, 0x68, 0x74, 0x74,
- 0x70, 0x3a, 0x2f, 0x2f, 0x67, 0x32, 0x2e, 0x73, 0x79, 0x6d, 0x63, 0x62,
- 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x47, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04,
- 0x40, 0x30, 0x3e, 0x30, 0x3c, 0x06, 0x04, 0x55, 0x1d, 0x20, 0x00, 0x30,
- 0x34, 0x30, 0x32, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02,
- 0x01, 0x16, 0x26, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77,
- 0x77, 0x77, 0x2e, 0x67, 0x65, 0x6f, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e,
- 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65,
- 0x73, 0x2f, 0x63, 0x70, 0x73, 0x30, 0x34, 0x06, 0x03, 0x55, 0x1d, 0x1f,
- 0x04, 0x2d, 0x30, 0x2b, 0x30, 0x29, 0xa0, 0x27, 0xa0, 0x25, 0x86, 0x23,
- 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x67, 0x31, 0x2e, 0x73, 0x79,
- 0x6d, 0x63, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x47, 0x65, 0x6f, 0x54,
- 0x72, 0x75, 0x73, 0x74, 0x50, 0x43, 0x41, 0x2e, 0x63, 0x72, 0x6c, 0x30,
- 0x29, 0x06, 0x03, 0x55, 0x1d, 0x11, 0x04, 0x22, 0x30, 0x20, 0xa4, 0x1e,
- 0x30, 0x1c, 0x31, 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
- 0x11, 0x53, 0x79, 0x6d, 0x61, 0x6e, 0x74, 0x65, 0x63, 0x50, 0x4b, 0x49,
- 0x2d, 0x31, 0x2d, 0x35, 0x33, 0x38, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d,
- 0x0e, 0x04, 0x16, 0x04, 0x14, 0xde, 0xcf, 0x5c, 0x50, 0xb7, 0xae, 0x02,
- 0x1f, 0x15, 0x17, 0xaa, 0x16, 0xe8, 0x0d, 0xb5, 0x28, 0x9d, 0x6a, 0x5a,
- 0xf3, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16,
- 0x80, 0x14, 0x2c, 0xd5, 0x50, 0x41, 0x97, 0x15, 0x8b, 0xf0, 0x8f, 0x36,
- 0x61, 0x5b, 0x4a, 0xfb, 0x6b, 0xd9, 0x99, 0xc9, 0x33, 0x92, 0x30, 0x0d,
- 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05,
- 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0xb4, 0x8e, 0xbd, 0x07, 0xb9, 0x9a,
- 0x85, 0xec, 0x3b, 0x67, 0xbd, 0x07, 0x60, 0x61, 0xe6, 0x84, 0xd1, 0xd4,
- 0xef, 0xeb, 0x1b, 0xba, 0x0b, 0x82, 0x4b, 0x95, 0x64, 0xb6, 0x66, 0x53,
- 0x23, 0xbd, 0xb7, 0x84, 0xdd, 0xe4, 0x7b, 0x8d, 0x09, 0xda, 0xcf, 0xb2,
- 0xf5, 0xf1, 0xc3, 0xbf, 0x87, 0x84, 0xbe, 0x4e, 0xa6, 0xa8, 0xc2, 0xe7,
- 0x12, 0x39, 0x28, 0x34, 0xe0, 0xa4, 0x56, 0x44, 0x40, 0x0c, 0x9f, 0x88,
- 0xa3, 0x15, 0xd3, 0xe8, 0xd3, 0x5e, 0xe3, 0x1c, 0x04, 0x60, 0xfb, 0x69,
- 0x36, 0x4f, 0x6a, 0x7e, 0x0c, 0x2a, 0x28, 0xc1, 0xf3, 0xaa, 0x58, 0x0e,
- 0x6c, 0xce, 0x1d, 0x07, 0xc3, 0x4a, 0xc0, 0x9c, 0x8d, 0xc3, 0x74, 0xb1,
- 0xae, 0x82, 0xf0, 0x1a, 0xe1, 0xf9, 0x4e, 0x29, 0xbd, 0x46, 0xde, 0xb7,
- 0x1d, 0xf9, 0x7d, 0xdb, 0xd9, 0x0f, 0x84, 0xcb, 0x92, 0x45, 0xcc, 0x1c,
- 0xb3, 0x18, 0xf6, 0xa0, 0xcf, 0x71, 0x6f, 0x0c, 0x2e, 0x9b, 0xd2, 0x2d,
- 0xb3, 0x99, 0x93, 0x83, 0x44, 0xac, 0x15, 0xaa, 0x9b, 0x2e, 0x67, 0xec,
- 0x4f, 0x88, 0x69, 0x05, 0x56, 0x7b, 0x8b, 0xb2, 0x43, 0xa9, 0x3a, 0x6c,
- 0x1c, 0x13, 0x33, 0x25, 0x1b, 0xfd, 0xa8, 0xc8, 0x57, 0x02, 0xfb, 0x1c,
- 0xe0, 0xd1, 0xbd, 0x3b, 0x56, 0x44, 0x65, 0xc3, 0x63, 0xf5, 0x1b, 0xef,
- 0xec, 0x30, 0xd9, 0xe3, 0x6e, 0x2e, 0x13, 0xe9, 0x39, 0x08, 0x2a, 0x0c,
- 0x72, 0xf3, 0x9a, 0xcc, 0xf6, 0x27, 0x29, 0x84, 0xd3, 0xef, 0x4c, 0xc7,
- 0x84, 0x11, 0x65, 0x1f, 0xc6, 0xe3, 0x81, 0x03, 0xdb, 0x87, 0xcc, 0x78,
- 0xf7, 0xb5, 0x9d, 0x96, 0x3e, 0x6a, 0x7f, 0xbc, 0x11, 0x85, 0x7a, 0x75,
- 0xe6, 0x41, 0x7d, 0x0d, 0xcf, 0xf9, 0xe5, 0x85, 0x69, 0x25, 0x8f, 0xc7,
- 0x8d, 0x07, 0x2d, 0xf8, 0x69, 0x0f, 0xcb, 0x41, 0x53, 0x00,
-};
-
-#if 0
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number: 146035 (0x23a73)
- Signature Algorithm: sha256WithRSAEncryption
- Issuer: C=US, O=GeoTrust Inc., CN=GeoTrust Global CA
- Validity
- Not Before: Jun 11 22:02:59 2014 GMT
- Not After : May 20 22:02:59 2022 GMT
- Subject: C=US, O=GeoTrust Inc., OU=Domain Validated SSL, CN=GeoTrust DV SSL CA - G3
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:b3:44:3a:6c:b0:ae:cb:14:f9:8c:19:74:34:5c:
- a9:69:e3:88:53:77:a5:a7:ff:bd:d1:3c:0d:27:e4:
- de:ad:7f:bc:d1:90:58:93:d6:a6:da:39:9c:ad:e1:
- 0e:56:46:ee:95:9e:10:68:4c:9c:2b:f6:6a:3a:8b:
- 80:81:87:06:57:25:1a:56:52:94:dd:90:eb:67:3b:
- de:fa:ae:36:68:d3:62:69:f6:6c:82:24:44:4f:87:
- 5c:98:11:95:64:6b:e8:0c:d1:dd:e6:27:97:ae:cc:
- e2:91:6a:41:12:b6:ab:e5:cc:6e:cc:23:b8:63:8a:
- 1f:31:93:2d:06:c4:f7:e8:3d:58:cd:97:08:46:6c:
- 7b:74:c0:f8:fc:31:3b:a7:7f:d7:8f:b0:c9:15:63:
- 50:7a:12:4d:f5:12:1e:a3:7e:55:e3:75:b7:ea:1e:
- ea:31:2c:08:4e:d8:cb:43:74:89:24:bc:d2:0e:1e:
- f0:db:05:24:f6:8a:bf:10:27:84:41:1a:f6:18:53:
- ee:91:d0:54:17:d3:7d:3e:7e:b2:7d:a8:bf:db:b9:
- 21:2a:f0:89:b9:08:6e:5a:b3:5e:ea:82:b8:7e:27:
- 0b:cc:56:73:81:05:4f:e3:96:2d:71:d5:78:a7:60:
- c3:d7:ec:aa:39:1a:05:39:82:81:e0:15:2c:35:d1:
- ee:25
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Authority Key Identifier:
- keyid:C0:7A:98:68:8D:89:FB:AB:05:64:0C:11:7D:AA:7D:65:B8:CA:CC:4E
-
- X509v3 Subject Key Identifier:
- AD:65:22:85:90:D0:3B:E3:A1:49:8B:37:F9:F1:0B:1D:5F:17:A0:77
- X509v3 Basic Constraints: critical
- CA:TRUE, pathlen:0
- X509v3 Key Usage: critical
- Certificate Sign, CRL Sign
- X509v3 CRL Distribution Points:
-
- Full Name:
- URI:http://g.symcb.com/crls/gtglobal.crl
-
- Authority Information Access:
- OCSP - URI:http://g.symcd.com
-
- X509v3 Certificate Policies:
- Policy: 2.16.840.1.113733.1.7.54
- CPS: http://www.geotrust.com/resources/cps
-
- X509v3 Subject Alternative Name:
- DirName:/CN=SymantecPKI-1-699
- Signature Algorithm: sha256WithRSAEncryption
- 4e:27:b8:1a:c7:3b:dc:5d:bb:9e:1a:35:23:1e:88:55:90:d1:
- ec:86:9c:88:b7:e0:1f:67:87:e2:7c:b5:43:03:0e:b6:02:e8:
- e0:ff:86:84:19:71:e9:f2:4b:f5:9e:2e:2e:5e:db:ab:d6:1c:
- 4e:c4:3e:b8:2c:78:86:71:10:ae:8d:c5:70:bf:a4:f9:89:e6:
- b4:ed:e8:4b:ed:7c:09:2a:09:08:06:3e:d4:e1:de:82:92:0c:
- 34:30:35:0a:c1:60:75:ca:b6:55:6b:aa:00:42:cb:3f:fb:10:
- e1:fb:85:c1:21:90:72:2b:6e:c0:e8:9d:d9:b5:5a:50:8e:34:
- 1e:bb:38:a7:3c:31:bd:7a:f2:43:8b:eb:16:ca:ad:9b:de:6b:
- 1e:f8:4f:b6:5e:4a:29:1f:7a:14:ee:91:f4:94:4f:a4:bd:9b:
- 76:7a:bc:f1:51:7a:96:a8:81:0e:83:87:3f:8b:ae:5e:32:9b:
- 34:9e:b2:e7:db:2f:ec:02:a0:e1:fd:51:52:fe:2c:db:36:ba:
- c1:d6:5e:4b:58:6d:de:c6:e1:e1:fa:9a:03:2c:5b:a2:e1:b3:
- 9b:f9:36:ec:c1:73:fa:33:12:66:95:e3:69:10:b6:d7:aa:33:
- fa:f6:9d:41:6d:96:2a:ba:be:83:31:41:7f:0c:0a:d2:69:d6:
- fc:35:4c:c3
------BEGIN CERTIFICATE-----
-MIIEbzCCA1egAwIBAgIDAjpzMA0GCSqGSIb3DQEBCwUAMEIxCzAJBgNVBAYTAlVT
-MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i
-YWwgQ0EwHhcNMTQwNjExMjIwMjU5WhcNMjIwNTIwMjIwMjU5WjBmMQswCQYDVQQG
-EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEdMBsGA1UECxMURG9tYWluIFZh
-bGlkYXRlZCBTU0wxIDAeBgNVBAMTF0dlb1RydXN0IERWIFNTTCBDQSAtIEczMIIB
-IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAs0Q6bLCuyxT5jBl0NFypaeOI
-U3elp/+90TwNJ+TerX+80ZBYk9am2jmcreEOVkbulZ4QaEycK/ZqOouAgYcGVyUa
-VlKU3ZDrZzve+q42aNNiafZsgiRET4dcmBGVZGvoDNHd5ieXrszikWpBErar5cxu
-zCO4Y4ofMZMtBsT36D1YzZcIRmx7dMD4/DE7p3/Xj7DJFWNQehJN9RIeo35V43W3
-6h7qMSwITtjLQ3SJJLzSDh7w2wUk9oq/ECeEQRr2GFPukdBUF9N9Pn6yfai/27kh
-KvCJuQhuWrNe6oK4ficLzFZzgQVP45YtcdV4p2DD1+yqORoFOYKB4BUsNdHuJQID
-AQABo4IBSDCCAUQwHwYDVR0jBBgwFoAUwHqYaI2J+6sFZAwRfap9ZbjKzE4wHQYD
-VR0OBBYEFK1lIoWQ0DvjoUmLN/nxCx1fF6B3MBIGA1UdEwEB/wQIMAYBAf8CAQAw
-DgYDVR0PAQH/BAQDAgEGMDUGA1UdHwQuMCwwKqAooCaGJGh0dHA6Ly9nLnN5bWNi
-LmNvbS9jcmxzL2d0Z2xvYmFsLmNybDAuBggrBgEFBQcBAQQiMCAwHgYIKwYBBQUH
-MAGGEmh0dHA6Ly9nLnN5bWNkLmNvbTBMBgNVHSAERTBDMEEGCmCGSAGG+EUBBzYw
-MzAxBggrBgEFBQcCARYlaHR0cDovL3d3dy5nZW90cnVzdC5jb20vcmVzb3VyY2Vz
-L2NwczApBgNVHREEIjAgpB4wHDEaMBgGA1UEAxMRU3ltYW50ZWNQS0ktMS02OTkw
-DQYJKoZIhvcNAQELBQADggEBAE4nuBrHO9xdu54aNSMeiFWQ0eyGnIi34B9nh+J8
-tUMDDrYC6OD/hoQZcenyS/WeLi5e26vWHE7EPrgseIZxEK6NxXC/pPmJ5rTt6Evt
-fAkqCQgGPtTh3oKSDDQwNQrBYHXKtlVrqgBCyz/7EOH7hcEhkHIrbsDondm1WlCO
-NB67OKc8Mb168kOL6xbKrZveax74T7ZeSikfehTukfSUT6S9m3Z6vPFRepaogQ6D
-hz+Lrl4ymzSesufbL+wCoOH9UVL+LNs2usHWXktYbd7G4eH6mgMsW6Lhs5v5NuzB
-c/ozEmaV42kQtteqM/r2nUFtliq6voMxQX8MCtJp1vw1TMM=
------END CERTIFICATE-----
-#endif
-static const unsigned char kDERCert16[] = {
- 0x30, 0x82, 0x04, 0x6f, 0x30, 0x82, 0x03, 0x57, 0xa0, 0x03, 0x02, 0x01,
- 0x02, 0x02, 0x03, 0x02, 0x3a, 0x73, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
- 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x42, 0x31,
- 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53,
- 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0d, 0x47,
- 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x49, 0x6e, 0x63, 0x2e,
- 0x31, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x12, 0x47,
- 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x47, 0x6c, 0x6f, 0x62,
- 0x61, 0x6c, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x34, 0x30,
- 0x36, 0x31, 0x31, 0x32, 0x32, 0x30, 0x32, 0x35, 0x39, 0x5a, 0x17, 0x0d,
- 0x32, 0x32, 0x30, 0x35, 0x32, 0x30, 0x32, 0x32, 0x30, 0x32, 0x35, 0x39,
- 0x5a, 0x30, 0x66, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06,
- 0x13, 0x02, 0x55, 0x53, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04,
- 0x0a, 0x13, 0x0d, 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20,
- 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x1d, 0x30, 0x1b, 0x06, 0x03, 0x55, 0x04,
- 0x0b, 0x13, 0x14, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x20, 0x56, 0x61,
- 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x64, 0x20, 0x53, 0x53, 0x4c, 0x31,
- 0x20, 0x30, 0x1e, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x17, 0x47, 0x65,
- 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x44, 0x56, 0x20, 0x53, 0x53,
- 0x4c, 0x20, 0x43, 0x41, 0x20, 0x2d, 0x20, 0x47, 0x33, 0x30, 0x82, 0x01,
- 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
- 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01,
- 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xb3, 0x44, 0x3a, 0x6c, 0xb0, 0xae,
- 0xcb, 0x14, 0xf9, 0x8c, 0x19, 0x74, 0x34, 0x5c, 0xa9, 0x69, 0xe3, 0x88,
- 0x53, 0x77, 0xa5, 0xa7, 0xff, 0xbd, 0xd1, 0x3c, 0x0d, 0x27, 0xe4, 0xde,
- 0xad, 0x7f, 0xbc, 0xd1, 0x90, 0x58, 0x93, 0xd6, 0xa6, 0xda, 0x39, 0x9c,
- 0xad, 0xe1, 0x0e, 0x56, 0x46, 0xee, 0x95, 0x9e, 0x10, 0x68, 0x4c, 0x9c,
- 0x2b, 0xf6, 0x6a, 0x3a, 0x8b, 0x80, 0x81, 0x87, 0x06, 0x57, 0x25, 0x1a,
- 0x56, 0x52, 0x94, 0xdd, 0x90, 0xeb, 0x67, 0x3b, 0xde, 0xfa, 0xae, 0x36,
- 0x68, 0xd3, 0x62, 0x69, 0xf6, 0x6c, 0x82, 0x24, 0x44, 0x4f, 0x87, 0x5c,
- 0x98, 0x11, 0x95, 0x64, 0x6b, 0xe8, 0x0c, 0xd1, 0xdd, 0xe6, 0x27, 0x97,
- 0xae, 0xcc, 0xe2, 0x91, 0x6a, 0x41, 0x12, 0xb6, 0xab, 0xe5, 0xcc, 0x6e,
- 0xcc, 0x23, 0xb8, 0x63, 0x8a, 0x1f, 0x31, 0x93, 0x2d, 0x06, 0xc4, 0xf7,
- 0xe8, 0x3d, 0x58, 0xcd, 0x97, 0x08, 0x46, 0x6c, 0x7b, 0x74, 0xc0, 0xf8,
- 0xfc, 0x31, 0x3b, 0xa7, 0x7f, 0xd7, 0x8f, 0xb0, 0xc9, 0x15, 0x63, 0x50,
- 0x7a, 0x12, 0x4d, 0xf5, 0x12, 0x1e, 0xa3, 0x7e, 0x55, 0xe3, 0x75, 0xb7,
- 0xea, 0x1e, 0xea, 0x31, 0x2c, 0x08, 0x4e, 0xd8, 0xcb, 0x43, 0x74, 0x89,
- 0x24, 0xbc, 0xd2, 0x0e, 0x1e, 0xf0, 0xdb, 0x05, 0x24, 0xf6, 0x8a, 0xbf,
- 0x10, 0x27, 0x84, 0x41, 0x1a, 0xf6, 0x18, 0x53, 0xee, 0x91, 0xd0, 0x54,
- 0x17, 0xd3, 0x7d, 0x3e, 0x7e, 0xb2, 0x7d, 0xa8, 0xbf, 0xdb, 0xb9, 0x21,
- 0x2a, 0xf0, 0x89, 0xb9, 0x08, 0x6e, 0x5a, 0xb3, 0x5e, 0xea, 0x82, 0xb8,
- 0x7e, 0x27, 0x0b, 0xcc, 0x56, 0x73, 0x81, 0x05, 0x4f, 0xe3, 0x96, 0x2d,
- 0x71, 0xd5, 0x78, 0xa7, 0x60, 0xc3, 0xd7, 0xec, 0xaa, 0x39, 0x1a, 0x05,
- 0x39, 0x82, 0x81, 0xe0, 0x15, 0x2c, 0x35, 0xd1, 0xee, 0x25, 0x02, 0x03,
- 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x48, 0x30, 0x82, 0x01, 0x44, 0x30,
- 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14,
- 0xc0, 0x7a, 0x98, 0x68, 0x8d, 0x89, 0xfb, 0xab, 0x05, 0x64, 0x0c, 0x11,
- 0x7d, 0xaa, 0x7d, 0x65, 0xb8, 0xca, 0xcc, 0x4e, 0x30, 0x1d, 0x06, 0x03,
- 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xad, 0x65, 0x22, 0x85, 0x90,
- 0xd0, 0x3b, 0xe3, 0xa1, 0x49, 0x8b, 0x37, 0xf9, 0xf1, 0x0b, 0x1d, 0x5f,
- 0x17, 0xa0, 0x77, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01,
- 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x00, 0x30,
- 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03,
- 0x02, 0x01, 0x06, 0x30, 0x35, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x2e,
- 0x30, 0x2c, 0x30, 0x2a, 0xa0, 0x28, 0xa0, 0x26, 0x86, 0x24, 0x68, 0x74,
- 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x67, 0x2e, 0x73, 0x79, 0x6d, 0x63, 0x62,
- 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x72, 0x6c, 0x73, 0x2f, 0x67, 0x74,
- 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x2e,
- 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x22,
- 0x30, 0x20, 0x30, 0x1e, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
- 0x30, 0x01, 0x86, 0x12, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x67,
- 0x2e, 0x73, 0x79, 0x6d, 0x63, 0x64, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x4c,
- 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x45, 0x30, 0x43, 0x30, 0x41, 0x06,
- 0x0a, 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x45, 0x01, 0x07, 0x36, 0x30,
- 0x33, 0x30, 0x31, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02,
- 0x01, 0x16, 0x25, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77,
- 0x77, 0x2e, 0x67, 0x65, 0x6f, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63,
- 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73,
- 0x2f, 0x63, 0x70, 0x73, 0x30, 0x29, 0x06, 0x03, 0x55, 0x1d, 0x11, 0x04,
- 0x22, 0x30, 0x20, 0xa4, 0x1e, 0x30, 0x1c, 0x31, 0x1a, 0x30, 0x18, 0x06,
- 0x03, 0x55, 0x04, 0x03, 0x13, 0x11, 0x53, 0x79, 0x6d, 0x61, 0x6e, 0x74,
- 0x65, 0x63, 0x50, 0x4b, 0x49, 0x2d, 0x31, 0x2d, 0x36, 0x39, 0x39, 0x30,
- 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b,
- 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x4e, 0x27, 0xb8, 0x1a, 0xc7,
- 0x3b, 0xdc, 0x5d, 0xbb, 0x9e, 0x1a, 0x35, 0x23, 0x1e, 0x88, 0x55, 0x90,
- 0xd1, 0xec, 0x86, 0x9c, 0x88, 0xb7, 0xe0, 0x1f, 0x67, 0x87, 0xe2, 0x7c,
- 0xb5, 0x43, 0x03, 0x0e, 0xb6, 0x02, 0xe8, 0xe0, 0xff, 0x86, 0x84, 0x19,
- 0x71, 0xe9, 0xf2, 0x4b, 0xf5, 0x9e, 0x2e, 0x2e, 0x5e, 0xdb, 0xab, 0xd6,
- 0x1c, 0x4e, 0xc4, 0x3e, 0xb8, 0x2c, 0x78, 0x86, 0x71, 0x10, 0xae, 0x8d,
- 0xc5, 0x70, 0xbf, 0xa4, 0xf9, 0x89, 0xe6, 0xb4, 0xed, 0xe8, 0x4b, 0xed,
- 0x7c, 0x09, 0x2a, 0x09, 0x08, 0x06, 0x3e, 0xd4, 0xe1, 0xde, 0x82, 0x92,
- 0x0c, 0x34, 0x30, 0x35, 0x0a, 0xc1, 0x60, 0x75, 0xca, 0xb6, 0x55, 0x6b,
- 0xaa, 0x00, 0x42, 0xcb, 0x3f, 0xfb, 0x10, 0xe1, 0xfb, 0x85, 0xc1, 0x21,
- 0x90, 0x72, 0x2b, 0x6e, 0xc0, 0xe8, 0x9d, 0xd9, 0xb5, 0x5a, 0x50, 0x8e,
- 0x34, 0x1e, 0xbb, 0x38, 0xa7, 0x3c, 0x31, 0xbd, 0x7a, 0xf2, 0x43, 0x8b,
- 0xeb, 0x16, 0xca, 0xad, 0x9b, 0xde, 0x6b, 0x1e, 0xf8, 0x4f, 0xb6, 0x5e,
- 0x4a, 0x29, 0x1f, 0x7a, 0x14, 0xee, 0x91, 0xf4, 0x94, 0x4f, 0xa4, 0xbd,
- 0x9b, 0x76, 0x7a, 0xbc, 0xf1, 0x51, 0x7a, 0x96, 0xa8, 0x81, 0x0e, 0x83,
- 0x87, 0x3f, 0x8b, 0xae, 0x5e, 0x32, 0x9b, 0x34, 0x9e, 0xb2, 0xe7, 0xdb,
- 0x2f, 0xec, 0x02, 0xa0, 0xe1, 0xfd, 0x51, 0x52, 0xfe, 0x2c, 0xdb, 0x36,
- 0xba, 0xc1, 0xd6, 0x5e, 0x4b, 0x58, 0x6d, 0xde, 0xc6, 0xe1, 0xe1, 0xfa,
- 0x9a, 0x03, 0x2c, 0x5b, 0xa2, 0xe1, 0xb3, 0x9b, 0xf9, 0x36, 0xec, 0xc1,
- 0x73, 0xfa, 0x33, 0x12, 0x66, 0x95, 0xe3, 0x69, 0x10, 0xb6, 0xd7, 0xaa,
- 0x33, 0xfa, 0xf6, 0x9d, 0x41, 0x6d, 0x96, 0x2a, 0xba, 0xbe, 0x83, 0x31,
- 0x41, 0x7f, 0x0c, 0x0a, 0xd2, 0x69, 0xd6, 0xfc, 0x35, 0x4c, 0xc3,
-};
-
-#if 0
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number: 12037640545166866303 (0xa70e4a4c3482b77f)
- Signature Algorithm: sha256WithRSAEncryption
- Issuer: C=US, O=Starfield Technologies, Inc., OU=Starfield Class 2 Certification Authority
- Validity
- Not Before: Sep 2 00:00:00 2009 GMT
- Not After : Jun 28 17:39:16 2034 GMT
- Subject: C=US, ST=Arizona, L=Scottsdale, O=Starfield Technologies, Inc., CN=Starfield Services Root Certificate Authority - G2
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:d5:0c:3a:c4:2a:f9:4e:e2:f5:be:19:97:5f:8e:
- 88:53:b1:1f:3f:cb:cf:9f:20:13:6d:29:3a:c8:0f:
- 7d:3c:f7:6b:76:38:63:d9:36:60:a8:9b:5e:5c:00:
- 80:b2:2f:59:7f:f6:87:f9:25:43:86:e7:69:1b:52:
- 9a:90:e1:71:e3:d8:2d:0d:4e:6f:f6:c8:49:d9:b6:
- f3:1a:56:ae:2b:b6:74:14:eb:cf:fb:26:e3:1a:ba:
- 1d:96:2e:6a:3b:58:94:89:47:56:ff:25:a0:93:70:
- 53:83:da:84:74:14:c3:67:9e:04:68:3a:df:8e:40:
- 5a:1d:4a:4e:cf:43:91:3b:e7:56:d6:00:70:cb:52:
- ee:7b:7d:ae:3a:e7:bc:31:f9:45:f6:c2:60:cf:13:
- 59:02:2b:80:cc:34:47:df:b9:de:90:65:6d:02:cf:
- 2c:91:a6:a6:e7:de:85:18:49:7c:66:4e:a3:3a:6d:
- a9:b5:ee:34:2e:ba:0d:03:b8:33:df:47:eb:b1:6b:
- 8d:25:d9:9b:ce:81:d1:45:46:32:96:70:87:de:02:
- 0e:49:43:85:b6:6c:73:bb:64:ea:61:41:ac:c9:d4:
- 54:df:87:2f:c7:22:b2:26:cc:9f:59:54:68:9f:fc:
- be:2a:2f:c4:55:1c:75:40:60:17:85:02:55:39:8b:
- 7f:05
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Basic Constraints: critical
- CA:TRUE
- X509v3 Key Usage: critical
- Digital Signature, Certificate Sign, CRL Sign
- X509v3 Subject Key Identifier:
- 9C:5F:00:DF:AA:01:D7:30:2B:38:88:A2:B8:6D:4A:9C:F2:11:91:83
- X509v3 Authority Key Identifier:
- keyid:BF:5F:B7:D1:CE:DD:1F:86:F4:5B:55:AC:DC:D7:10:C2:0E:A9:88:E7
-
- Authority Information Access:
- OCSP - URI:http://o.ss2.us/
- CA Issuers - URI:http://x.ss2.us/x.cer
-
- X509v3 CRL Distribution Points:
-
- Full Name:
- URI:http://s.ss2.us/r.crl
-
- X509v3 Certificate Policies:
- Policy: X509v3 Any Policy
-
- Signature Algorithm: sha256WithRSAEncryption
- 23:1d:e3:8a:57:ca:7d:e9:17:79:4c:f1:1e:55:fd:cc:53:6e:
- 3e:47:0f:df:c6:55:f2:b2:04:36:ed:80:1f:53:c4:5d:34:28:
- 6b:be:c7:55:fc:67:ea:cb:3f:7f:90:b2:33:cd:1b:58:10:82:
- 02:f8:f8:2f:f5:13:60:d4:05:ce:f1:81:08:c1:dd:a7:75:97:
- 4f:18:b9:6d:de:f7:93:91:08:ba:7e:40:2c:ed:c1:ea:bb:76:
- 9e:33:06:77:1d:0d:08:7f:53:dd:1b:64:ab:82:27:f1:69:d5:
- 4d:5e:ae:f4:a1:c3:75:a7:58:44:2d:f2:3c:70:98:ac:ba:69:
- b6:95:77:7f:0f:31:5e:2c:fc:a0:87:3a:47:69:f0:79:5f:f4:
- 14:54:a4:95:5e:11:78:12:60:27:ce:9f:c2:77:ff:23:53:77:
- 5d:ba:ff:ea:59:e7:db:cf:af:92:96:ef:24:9a:35:10:7a:9c:
- 91:c6:0e:7d:99:f6:3f:19:df:f5:72:54:e1:15:a9:07:59:7b:
- 83:bf:52:2e:46:8c:b2:00:64:76:1c:48:d3:d8:79:e8:6e:56:
- cc:ae:2c:03:90:d7:19:38:99:e4:ca:09:19:5b:ff:07:96:b0:
- a8:7f:34:49:df:56:a9:f7:b0:5f:ed:33:ed:8c:47:b7:30:03:
- 5d:f4:03:8c
------BEGIN CERTIFICATE-----
-MIIEdTCCA12gAwIBAgIJAKcOSkw0grd/MA0GCSqGSIb3DQEBCwUAMGgxCzAJBgNV
-BAYTAlVTMSUwIwYDVQQKExxTdGFyZmllbGQgVGVjaG5vbG9naWVzLCBJbmMuMTIw
-MAYDVQQLEylTdGFyZmllbGQgQ2xhc3MgMiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0
-eTAeFw0wOTA5MDIwMDAwMDBaFw0zNDA2MjgxNzM5MTZaMIGYMQswCQYDVQQGEwJV
-UzEQMA4GA1UECBMHQXJpem9uYTETMBEGA1UEBxMKU2NvdHRzZGFsZTElMCMGA1UE
-ChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjE7MDkGA1UEAxMyU3RhcmZp
-ZWxkIFNlcnZpY2VzIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IC0gRzIwggEi
-MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDVDDrEKvlO4vW+GZdfjohTsR8/
-y8+fIBNtKTrID30892t2OGPZNmCom15cAICyL1l/9of5JUOG52kbUpqQ4XHj2C0N
-Tm/2yEnZtvMaVq4rtnQU68/7JuMauh2WLmo7WJSJR1b/JaCTcFOD2oR0FMNnngRo
-Ot+OQFodSk7PQ5E751bWAHDLUu57fa4657wx+UX2wmDPE1kCK4DMNEffud6QZW0C
-zyyRpqbn3oUYSXxmTqM6bam17jQuug0DuDPfR+uxa40l2ZvOgdFFRjKWcIfeAg5J
-Q4W2bHO7ZOphQazJ1FTfhy/HIrImzJ9ZVGif/L4qL8RVHHVAYBeFAlU5i38FAgMB
-AAGjgfAwge0wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0O
-BBYEFJxfAN+qAdcwKziIorhtSpzyEZGDMB8GA1UdIwQYMBaAFL9ft9HO3R+G9FtV
-rNzXEMIOqYjnME8GCCsGAQUFBwEBBEMwQTAcBggrBgEFBQcwAYYQaHR0cDovL28u
-c3MyLnVzLzAhBggrBgEFBQcwAoYVaHR0cDovL3guc3MyLnVzL3guY2VyMCYGA1Ud
-HwQfMB0wG6AZoBeGFWh0dHA6Ly9zLnNzMi51cy9yLmNybDARBgNVHSAECjAIMAYG
-BFUdIAAwDQYJKoZIhvcNAQELBQADggEBACMd44pXyn3pF3lM8R5V/cxTbj5HD9/G
-VfKyBDbtgB9TxF00KGu+x1X8Z+rLP3+QsjPNG1gQggL4+C/1E2DUBc7xgQjB3ad1
-l08YuW3e95ORCLp+QCztweq7dp4zBncdDQh/U90bZKuCJ/Fp1U1ervShw3WnWEQt
-8jxwmKy6abaVd38PMV4s/KCHOkdp8Hlf9BRUpJVeEXgSYCfOn8J3/yNTd126/+pZ
-59vPr5KW7ySaNRB6nJHGDn2Z9j8Z3/VyVOEVqQdZe4O/Ui5GjLIAZHYcSNPYeehu
-VsyuLAOQ1xk4meTKCRlb/weWsKh/NEnfVqn3sF/tM+2MR7cwA130A4w=
------END CERTIFICATE-----
-#endif
-static const unsigned char kDERCert17[] = {
- 0x30, 0x82, 0x04, 0x75, 0x30, 0x82, 0x03, 0x5d, 0xa0, 0x03, 0x02, 0x01,
- 0x02, 0x02, 0x09, 0x00, 0xa7, 0x0e, 0x4a, 0x4c, 0x34, 0x82, 0xb7, 0x7f,
- 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
- 0x0b, 0x05, 0x00, 0x30, 0x68, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55,
- 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03,
- 0x55, 0x04, 0x0a, 0x13, 0x1c, 0x53, 0x74, 0x61, 0x72, 0x66, 0x69, 0x65,
- 0x6c, 0x64, 0x20, 0x54, 0x65, 0x63, 0x68, 0x6e, 0x6f, 0x6c, 0x6f, 0x67,
- 0x69, 0x65, 0x73, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x32, 0x30,
- 0x30, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x29, 0x53, 0x74, 0x61, 0x72,
- 0x66, 0x69, 0x65, 0x6c, 0x64, 0x20, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x20,
- 0x32, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74,
- 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74,
- 0x79, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x39, 0x30, 0x39, 0x30, 0x32, 0x30,
- 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x33, 0x34, 0x30, 0x36,
- 0x32, 0x38, 0x31, 0x37, 0x33, 0x39, 0x31, 0x36, 0x5a, 0x30, 0x81, 0x98,
- 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55,
- 0x53, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x07,
- 0x41, 0x72, 0x69, 0x7a, 0x6f, 0x6e, 0x61, 0x31, 0x13, 0x30, 0x11, 0x06,
- 0x03, 0x55, 0x04, 0x07, 0x13, 0x0a, 0x53, 0x63, 0x6f, 0x74, 0x74, 0x73,
- 0x64, 0x61, 0x6c, 0x65, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04,
- 0x0a, 0x13, 0x1c, 0x53, 0x74, 0x61, 0x72, 0x66, 0x69, 0x65, 0x6c, 0x64,
- 0x20, 0x54, 0x65, 0x63, 0x68, 0x6e, 0x6f, 0x6c, 0x6f, 0x67, 0x69, 0x65,
- 0x73, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x3b, 0x30, 0x39, 0x06,
- 0x03, 0x55, 0x04, 0x03, 0x13, 0x32, 0x53, 0x74, 0x61, 0x72, 0x66, 0x69,
- 0x65, 0x6c, 0x64, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73,
- 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66,
- 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72,
- 0x69, 0x74, 0x79, 0x20, 0x2d, 0x20, 0x47, 0x32, 0x30, 0x82, 0x01, 0x22,
- 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
- 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a,
- 0x02, 0x82, 0x01, 0x01, 0x00, 0xd5, 0x0c, 0x3a, 0xc4, 0x2a, 0xf9, 0x4e,
- 0xe2, 0xf5, 0xbe, 0x19, 0x97, 0x5f, 0x8e, 0x88, 0x53, 0xb1, 0x1f, 0x3f,
- 0xcb, 0xcf, 0x9f, 0x20, 0x13, 0x6d, 0x29, 0x3a, 0xc8, 0x0f, 0x7d, 0x3c,
- 0xf7, 0x6b, 0x76, 0x38, 0x63, 0xd9, 0x36, 0x60, 0xa8, 0x9b, 0x5e, 0x5c,
- 0x00, 0x80, 0xb2, 0x2f, 0x59, 0x7f, 0xf6, 0x87, 0xf9, 0x25, 0x43, 0x86,
- 0xe7, 0x69, 0x1b, 0x52, 0x9a, 0x90, 0xe1, 0x71, 0xe3, 0xd8, 0x2d, 0x0d,
- 0x4e, 0x6f, 0xf6, 0xc8, 0x49, 0xd9, 0xb6, 0xf3, 0x1a, 0x56, 0xae, 0x2b,
- 0xb6, 0x74, 0x14, 0xeb, 0xcf, 0xfb, 0x26, 0xe3, 0x1a, 0xba, 0x1d, 0x96,
- 0x2e, 0x6a, 0x3b, 0x58, 0x94, 0x89, 0x47, 0x56, 0xff, 0x25, 0xa0, 0x93,
- 0x70, 0x53, 0x83, 0xda, 0x84, 0x74, 0x14, 0xc3, 0x67, 0x9e, 0x04, 0x68,
- 0x3a, 0xdf, 0x8e, 0x40, 0x5a, 0x1d, 0x4a, 0x4e, 0xcf, 0x43, 0x91, 0x3b,
- 0xe7, 0x56, 0xd6, 0x00, 0x70, 0xcb, 0x52, 0xee, 0x7b, 0x7d, 0xae, 0x3a,
- 0xe7, 0xbc, 0x31, 0xf9, 0x45, 0xf6, 0xc2, 0x60, 0xcf, 0x13, 0x59, 0x02,
- 0x2b, 0x80, 0xcc, 0x34, 0x47, 0xdf, 0xb9, 0xde, 0x90, 0x65, 0x6d, 0x02,
- 0xcf, 0x2c, 0x91, 0xa6, 0xa6, 0xe7, 0xde, 0x85, 0x18, 0x49, 0x7c, 0x66,
- 0x4e, 0xa3, 0x3a, 0x6d, 0xa9, 0xb5, 0xee, 0x34, 0x2e, 0xba, 0x0d, 0x03,
- 0xb8, 0x33, 0xdf, 0x47, 0xeb, 0xb1, 0x6b, 0x8d, 0x25, 0xd9, 0x9b, 0xce,
- 0x81, 0xd1, 0x45, 0x46, 0x32, 0x96, 0x70, 0x87, 0xde, 0x02, 0x0e, 0x49,
- 0x43, 0x85, 0xb6, 0x6c, 0x73, 0xbb, 0x64, 0xea, 0x61, 0x41, 0xac, 0xc9,
- 0xd4, 0x54, 0xdf, 0x87, 0x2f, 0xc7, 0x22, 0xb2, 0x26, 0xcc, 0x9f, 0x59,
- 0x54, 0x68, 0x9f, 0xfc, 0xbe, 0x2a, 0x2f, 0xc4, 0x55, 0x1c, 0x75, 0x40,
- 0x60, 0x17, 0x85, 0x02, 0x55, 0x39, 0x8b, 0x7f, 0x05, 0x02, 0x03, 0x01,
- 0x00, 0x01, 0xa3, 0x81, 0xf0, 0x30, 0x81, 0xed, 0x30, 0x0f, 0x06, 0x03,
- 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01,
- 0xff, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04,
- 0x04, 0x03, 0x02, 0x01, 0x86, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e,
- 0x04, 0x16, 0x04, 0x14, 0x9c, 0x5f, 0x00, 0xdf, 0xaa, 0x01, 0xd7, 0x30,
- 0x2b, 0x38, 0x88, 0xa2, 0xb8, 0x6d, 0x4a, 0x9c, 0xf2, 0x11, 0x91, 0x83,
- 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80,
- 0x14, 0xbf, 0x5f, 0xb7, 0xd1, 0xce, 0xdd, 0x1f, 0x86, 0xf4, 0x5b, 0x55,
- 0xac, 0xdc, 0xd7, 0x10, 0xc2, 0x0e, 0xa9, 0x88, 0xe7, 0x30, 0x4f, 0x06,
- 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x43, 0x30,
- 0x41, 0x30, 0x1c, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30,
- 0x01, 0x86, 0x10, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x2e,
- 0x73, 0x73, 0x32, 0x2e, 0x75, 0x73, 0x2f, 0x30, 0x21, 0x06, 0x08, 0x2b,
- 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x15, 0x68, 0x74, 0x74,
- 0x70, 0x3a, 0x2f, 0x2f, 0x78, 0x2e, 0x73, 0x73, 0x32, 0x2e, 0x75, 0x73,
- 0x2f, 0x78, 0x2e, 0x63, 0x65, 0x72, 0x30, 0x26, 0x06, 0x03, 0x55, 0x1d,
- 0x1f, 0x04, 0x1f, 0x30, 0x1d, 0x30, 0x1b, 0xa0, 0x19, 0xa0, 0x17, 0x86,
- 0x15, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x73, 0x2e, 0x73, 0x73,
- 0x32, 0x2e, 0x75, 0x73, 0x2f, 0x72, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x11,
- 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x0a, 0x30, 0x08, 0x30, 0x06, 0x06,
- 0x04, 0x55, 0x1d, 0x20, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48,
- 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01,
- 0x00, 0x23, 0x1d, 0xe3, 0x8a, 0x57, 0xca, 0x7d, 0xe9, 0x17, 0x79, 0x4c,
- 0xf1, 0x1e, 0x55, 0xfd, 0xcc, 0x53, 0x6e, 0x3e, 0x47, 0x0f, 0xdf, 0xc6,
- 0x55, 0xf2, 0xb2, 0x04, 0x36, 0xed, 0x80, 0x1f, 0x53, 0xc4, 0x5d, 0x34,
- 0x28, 0x6b, 0xbe, 0xc7, 0x55, 0xfc, 0x67, 0xea, 0xcb, 0x3f, 0x7f, 0x90,
- 0xb2, 0x33, 0xcd, 0x1b, 0x58, 0x10, 0x82, 0x02, 0xf8, 0xf8, 0x2f, 0xf5,
- 0x13, 0x60, 0xd4, 0x05, 0xce, 0xf1, 0x81, 0x08, 0xc1, 0xdd, 0xa7, 0x75,
- 0x97, 0x4f, 0x18, 0xb9, 0x6d, 0xde, 0xf7, 0x93, 0x91, 0x08, 0xba, 0x7e,
- 0x40, 0x2c, 0xed, 0xc1, 0xea, 0xbb, 0x76, 0x9e, 0x33, 0x06, 0x77, 0x1d,
- 0x0d, 0x08, 0x7f, 0x53, 0xdd, 0x1b, 0x64, 0xab, 0x82, 0x27, 0xf1, 0x69,
- 0xd5, 0x4d, 0x5e, 0xae, 0xf4, 0xa1, 0xc3, 0x75, 0xa7, 0x58, 0x44, 0x2d,
- 0xf2, 0x3c, 0x70, 0x98, 0xac, 0xba, 0x69, 0xb6, 0x95, 0x77, 0x7f, 0x0f,
- 0x31, 0x5e, 0x2c, 0xfc, 0xa0, 0x87, 0x3a, 0x47, 0x69, 0xf0, 0x79, 0x5f,
- 0xf4, 0x14, 0x54, 0xa4, 0x95, 0x5e, 0x11, 0x78, 0x12, 0x60, 0x27, 0xce,
- 0x9f, 0xc2, 0x77, 0xff, 0x23, 0x53, 0x77, 0x5d, 0xba, 0xff, 0xea, 0x59,
- 0xe7, 0xdb, 0xcf, 0xaf, 0x92, 0x96, 0xef, 0x24, 0x9a, 0x35, 0x10, 0x7a,
- 0x9c, 0x91, 0xc6, 0x0e, 0x7d, 0x99, 0xf6, 0x3f, 0x19, 0xdf, 0xf5, 0x72,
- 0x54, 0xe1, 0x15, 0xa9, 0x07, 0x59, 0x7b, 0x83, 0xbf, 0x52, 0x2e, 0x46,
- 0x8c, 0xb2, 0x00, 0x64, 0x76, 0x1c, 0x48, 0xd3, 0xd8, 0x79, 0xe8, 0x6e,
- 0x56, 0xcc, 0xae, 0x2c, 0x03, 0x90, 0xd7, 0x19, 0x38, 0x99, 0xe4, 0xca,
- 0x09, 0x19, 0x5b, 0xff, 0x07, 0x96, 0xb0, 0xa8, 0x7f, 0x34, 0x49, 0xdf,
- 0x56, 0xa9, 0xf7, 0xb0, 0x5f, 0xed, 0x33, 0xed, 0x8c, 0x47, 0xb7, 0x30,
- 0x03, 0x5d, 0xf4, 0x03, 0x8c,
-};
-
-#if 0
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number: 120038006 (0x727a276)
- Signature Algorithm: sha256WithRSAEncryption
- Issuer: C=IE, O=Baltimore, OU=CyberTrust, CN=Baltimore CyberTrust Root
- Validity
- Not Before: Feb 27 18:09:27 2014 GMT
- Not After : Jun 9 17:07:29 2020 GMT
- Subject: C=JP, O=Cybertrust Japan Co., Ltd., CN=Cybertrust Japan Public CA G3
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:94:56:a3:45:44:54:aa:60:64:bf:b8:57:9f:4e:
- db:d4:79:68:5f:13:05:f4:3f:cd:25:dd:3c:5e:58:
- 77:1c:9d:e6:9f:e3:32:49:ef:02:3a:34:53:8d:52:
- e5:e3:39:66:1f:e7:33:61:b6:27:c6:24:55:50:27:
- 02:65:f0:b0:8c:41:8d:30:5e:47:5b:82:6f:c7:9c:
- a3:28:43:6d:58:7b:c8:15:98:4e:25:6f:cb:76:27:
- 5b:0b:2c:2c:b5:98:23:e7:8b:7c:fd:77:1a:c4:52:
- ba:5d:19:ee:78:21:4d:21:9a:d9:12:7c:33:15:6b:
- 1a:c9:81:ea:da:da:57:b7:d5:2f:ce:1f:4b:fc:b4:
- 33:e0:a0:c9:94:27:bb:27:40:b6:90:db:ac:9e:75:
- a6:11:2b:49:19:2d:c3:c2:43:07:09:bb:3d:6e:88:
- a3:e3:8a:c5:d2:86:f6:65:5b:34:c3:9f:4c:02:e5:
- 09:ba:2c:c6:76:66:eb:d1:76:25:f4:30:13:fb:58:
- 60:a8:58:e3:51:6f:4b:08:04:61:8d:ac:a9:30:2f:
- 52:41:a3:22:c1:33:59:ab:7b:59:f9:93:67:4b:c9:
- 89:75:52:ef:29:49:34:93:1c:9c:93:73:9c:19:ce:
- 5c:18:cd:4c:09:27:c1:3f:f5:49:ec:f4:e2:df:4b:
- af:8f
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Basic Constraints: critical
- CA:TRUE, pathlen:0
- X509v3 Certificate Policies:
- Policy: 1.3.6.1.4.1.6334.1.0
- CPS: http://cybertrust.omniroot.com/repository.cfm
-
- Authority Information Access:
- OCSP - URI:http://ocsp.omniroot.com/baltimoreroot
-
- X509v3 Key Usage: critical
- Certificate Sign, CRL Sign
- X509v3 Authority Key Identifier:
- keyid:E5:9D:59:30:82:47:58:CC:AC:FA:08:54:36:86:7B:3A:B5:04:4D:F0
-
- X509v3 CRL Distribution Points:
-
- Full Name:
- URI:http://cdp1.public-trust.com/CRL/Omniroot2025.crl
-
- X509v3 Subject Key Identifier:
- 73:A8:08:53:29:B8:15:FB:99:80:E5:C5:37:D8:F8:39:7B:A4:13:06
- Signature Algorithm: sha256WithRSAEncryption
- 68:df:fe:72:54:4e:1b:fb:5c:6e:5a:45:46:cf:42:be:b2:02:
- 9c:9d:90:6a:09:2e:b7:36:64:24:b6:b1:e2:48:67:ce:17:46:
- 9b:23:75:78:11:f6:c6:09:38:42:62:96:97:30:7b:51:77:df:
- 33:b5:00:51:29:d5:24:fe:b7:98:a2:ac:6c:a1:13:7f:ca:f3:
- b7:a6:52:c2:16:0d:ec:3a:bf:a3:37:77:4f:ae:7b:55:1d:46:
- e9:10:da:c3:b4:05:5c:5b:f6:48:21:00:89:f4:bb:38:8e:1e:
- 33:f3:49:97:81:31:6c:16:74:08:91:17:c0:d3:25:b3:bc:c1:
- 15:b5:a4:cd:84:4d:b9:c8:eb:c5:59:42:10:14:25:79:f8:db:
- b6:d0:e6:d3:a0:14:7c:17:1c:20:1e:ed:99:90:65:c0:41:71:
- c3:ab:3f:29:41:67:f9:e2:d1:98:e3:f8:df:3a:b8:ca:a3:6f:
- 68:8b:6c:9f:6e:88:7c:9d:41:5c:ba:cb:19:05:83:9c:99:f4:
- 1a:d2:24:69:57:0a:0f:7a:c3:1b:2c:4b:06:d3:2a:97:7e:07:
- b0:f9:20:5a:b5:92:4b:5b:a8:eb:eb:36:33:47:36:da:72:9c:
- bf:68:45:81:31:be:d2:fd:3b:e9:72:d5:70:dd:a6:de:5f:0d:
- b6:5e:00:49
------BEGIN CERTIFICATE-----
-MIIEeTCCA2GgAwIBAgIEByeidjANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJJ
-RTESMBAGA1UEChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYD
-VQQDExlCYWx0aW1vcmUgQ3liZXJUcnVzdCBSb290MB4XDTE0MDIyNzE4MDkyN1oX
-DTIwMDYwOTE3MDcyOVowWjELMAkGA1UEBhMCSlAxIzAhBgNVBAoTGkN5YmVydHJ1
-c3QgSmFwYW4gQ28uLCBMdGQuMSYwJAYDVQQDEx1DeWJlcnRydXN0IEphcGFuIFB1
-YmxpYyBDQSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJRWo0VE
-VKpgZL+4V59O29R5aF8TBfQ/zSXdPF5Ydxyd5p/jMknvAjo0U41S5eM5Zh/nM2G2
-J8YkVVAnAmXwsIxBjTBeR1uCb8ecoyhDbVh7yBWYTiVvy3YnWwssLLWYI+eLfP13
-GsRSul0Z7nghTSGa2RJ8MxVrGsmB6traV7fVL84fS/y0M+CgyZQnuydAtpDbrJ51
-phErSRktw8JDBwm7PW6Io+OKxdKG9mVbNMOfTALlCbosxnZm69F2JfQwE/tYYKhY
-41FvSwgEYY2sqTAvUkGjIsEzWat7WfmTZ0vJiXVS7ylJNJMcnJNznBnOXBjNTAkn
-wT/1Sez04t9Lr48CAwEAAaOCAUUwggFBMBIGA1UdEwEB/wQIMAYBAf8CAQAwUwYD
-VR0gBEwwSjBIBgkrBgEEAbE+AQAwOzA5BggrBgEFBQcCARYtaHR0cDovL2N5YmVy
-dHJ1c3Qub21uaXJvb3QuY29tL3JlcG9zaXRvcnkuY2ZtMEIGCCsGAQUFBwEBBDYw
-NDAyBggrBgEFBQcwAYYmaHR0cDovL29jc3Aub21uaXJvb3QuY29tL2JhbHRpbW9y
-ZXJvb3QwDgYDVR0PAQH/BAQDAgEGMB8GA1UdIwQYMBaAFOWdWTCCR1jMrPoIVDaG
-ezq1BE3wMEIGA1UdHwQ7MDkwN6A1oDOGMWh0dHA6Ly9jZHAxLnB1YmxpYy10cnVz
-dC5jb20vQ1JML09tbmlyb290MjAyNS5jcmwwHQYDVR0OBBYEFHOoCFMpuBX7mYDl
-xTfY+Dl7pBMGMA0GCSqGSIb3DQEBCwUAA4IBAQBo3/5yVE4b+1xuWkVGz0K+sgKc
-nZBqCS63NmQktrHiSGfOF0abI3V4EfbGCThCYpaXMHtRd98ztQBRKdUk/reYoqxs
-oRN/yvO3plLCFg3sOr+jN3dPrntVHUbpENrDtAVcW/ZIIQCJ9Ls4jh4z80mXgTFs
-FnQIkRfA0yWzvMEVtaTNhE25yOvFWUIQFCV5+Nu20ObToBR8FxwgHu2ZkGXAQXHD
-qz8pQWf54tGY4/jfOrjKo29oi2yfboh8nUFcussZBYOcmfQa0iRpVwoPesMbLEsG
-0yqXfgew+SBatZJLW6jr6zYzRzbacpy/aEWBMb7S/TvpctVw3abeXw22XgBJ
------END CERTIFICATE-----
-#endif
-static const unsigned char kDERCert18[] = {
- 0x30, 0x82, 0x04, 0x79, 0x30, 0x82, 0x03, 0x61, 0xa0, 0x03, 0x02, 0x01,
- 0x02, 0x02, 0x04, 0x07, 0x27, 0xa2, 0x76, 0x30, 0x0d, 0x06, 0x09, 0x2a,
- 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x5a,
- 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x49,
- 0x45, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x09,
- 0x42, 0x61, 0x6c, 0x74, 0x69, 0x6d, 0x6f, 0x72, 0x65, 0x31, 0x13, 0x30,
- 0x11, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x0a, 0x43, 0x79, 0x62, 0x65,
- 0x72, 0x54, 0x72, 0x75, 0x73, 0x74, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03,
- 0x55, 0x04, 0x03, 0x13, 0x19, 0x42, 0x61, 0x6c, 0x74, 0x69, 0x6d, 0x6f,
- 0x72, 0x65, 0x20, 0x43, 0x79, 0x62, 0x65, 0x72, 0x54, 0x72, 0x75, 0x73,
- 0x74, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x34,
- 0x30, 0x32, 0x32, 0x37, 0x31, 0x38, 0x30, 0x39, 0x32, 0x37, 0x5a, 0x17,
- 0x0d, 0x32, 0x30, 0x30, 0x36, 0x30, 0x39, 0x31, 0x37, 0x30, 0x37, 0x32,
- 0x39, 0x5a, 0x30, 0x5a, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04,
- 0x06, 0x13, 0x02, 0x4a, 0x50, 0x31, 0x23, 0x30, 0x21, 0x06, 0x03, 0x55,
- 0x04, 0x0a, 0x13, 0x1a, 0x43, 0x79, 0x62, 0x65, 0x72, 0x74, 0x72, 0x75,
- 0x73, 0x74, 0x20, 0x4a, 0x61, 0x70, 0x61, 0x6e, 0x20, 0x43, 0x6f, 0x2e,
- 0x2c, 0x20, 0x4c, 0x74, 0x64, 0x2e, 0x31, 0x26, 0x30, 0x24, 0x06, 0x03,
- 0x55, 0x04, 0x03, 0x13, 0x1d, 0x43, 0x79, 0x62, 0x65, 0x72, 0x74, 0x72,
- 0x75, 0x73, 0x74, 0x20, 0x4a, 0x61, 0x70, 0x61, 0x6e, 0x20, 0x50, 0x75,
- 0x62, 0x6c, 0x69, 0x63, 0x20, 0x43, 0x41, 0x20, 0x47, 0x33, 0x30, 0x82,
- 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
- 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82,
- 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0x94, 0x56, 0xa3, 0x45, 0x44,
- 0x54, 0xaa, 0x60, 0x64, 0xbf, 0xb8, 0x57, 0x9f, 0x4e, 0xdb, 0xd4, 0x79,
- 0x68, 0x5f, 0x13, 0x05, 0xf4, 0x3f, 0xcd, 0x25, 0xdd, 0x3c, 0x5e, 0x58,
- 0x77, 0x1c, 0x9d, 0xe6, 0x9f, 0xe3, 0x32, 0x49, 0xef, 0x02, 0x3a, 0x34,
- 0x53, 0x8d, 0x52, 0xe5, 0xe3, 0x39, 0x66, 0x1f, 0xe7, 0x33, 0x61, 0xb6,
- 0x27, 0xc6, 0x24, 0x55, 0x50, 0x27, 0x02, 0x65, 0xf0, 0xb0, 0x8c, 0x41,
- 0x8d, 0x30, 0x5e, 0x47, 0x5b, 0x82, 0x6f, 0xc7, 0x9c, 0xa3, 0x28, 0x43,
- 0x6d, 0x58, 0x7b, 0xc8, 0x15, 0x98, 0x4e, 0x25, 0x6f, 0xcb, 0x76, 0x27,
- 0x5b, 0x0b, 0x2c, 0x2c, 0xb5, 0x98, 0x23, 0xe7, 0x8b, 0x7c, 0xfd, 0x77,
- 0x1a, 0xc4, 0x52, 0xba, 0x5d, 0x19, 0xee, 0x78, 0x21, 0x4d, 0x21, 0x9a,
- 0xd9, 0x12, 0x7c, 0x33, 0x15, 0x6b, 0x1a, 0xc9, 0x81, 0xea, 0xda, 0xda,
- 0x57, 0xb7, 0xd5, 0x2f, 0xce, 0x1f, 0x4b, 0xfc, 0xb4, 0x33, 0xe0, 0xa0,
- 0xc9, 0x94, 0x27, 0xbb, 0x27, 0x40, 0xb6, 0x90, 0xdb, 0xac, 0x9e, 0x75,
- 0xa6, 0x11, 0x2b, 0x49, 0x19, 0x2d, 0xc3, 0xc2, 0x43, 0x07, 0x09, 0xbb,
- 0x3d, 0x6e, 0x88, 0xa3, 0xe3, 0x8a, 0xc5, 0xd2, 0x86, 0xf6, 0x65, 0x5b,
- 0x34, 0xc3, 0x9f, 0x4c, 0x02, 0xe5, 0x09, 0xba, 0x2c, 0xc6, 0x76, 0x66,
- 0xeb, 0xd1, 0x76, 0x25, 0xf4, 0x30, 0x13, 0xfb, 0x58, 0x60, 0xa8, 0x58,
- 0xe3, 0x51, 0x6f, 0x4b, 0x08, 0x04, 0x61, 0x8d, 0xac, 0xa9, 0x30, 0x2f,
- 0x52, 0x41, 0xa3, 0x22, 0xc1, 0x33, 0x59, 0xab, 0x7b, 0x59, 0xf9, 0x93,
- 0x67, 0x4b, 0xc9, 0x89, 0x75, 0x52, 0xef, 0x29, 0x49, 0x34, 0x93, 0x1c,
- 0x9c, 0x93, 0x73, 0x9c, 0x19, 0xce, 0x5c, 0x18, 0xcd, 0x4c, 0x09, 0x27,
- 0xc1, 0x3f, 0xf5, 0x49, 0xec, 0xf4, 0xe2, 0xdf, 0x4b, 0xaf, 0x8f, 0x02,
- 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x45, 0x30, 0x82, 0x01, 0x41,
- 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08,
- 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x00, 0x30, 0x53, 0x06, 0x03,
- 0x55, 0x1d, 0x20, 0x04, 0x4c, 0x30, 0x4a, 0x30, 0x48, 0x06, 0x09, 0x2b,
- 0x06, 0x01, 0x04, 0x01, 0xb1, 0x3e, 0x01, 0x00, 0x30, 0x3b, 0x30, 0x39,
- 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x2d,
- 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x79, 0x62, 0x65, 0x72,
- 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x6f, 0x6d, 0x6e, 0x69, 0x72, 0x6f,
- 0x6f, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73,
- 0x69, 0x74, 0x6f, 0x72, 0x79, 0x2e, 0x63, 0x66, 0x6d, 0x30, 0x42, 0x06,
- 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x36, 0x30,
- 0x34, 0x30, 0x32, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30,
- 0x01, 0x86, 0x26, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63,
- 0x73, 0x70, 0x2e, 0x6f, 0x6d, 0x6e, 0x69, 0x72, 0x6f, 0x6f, 0x74, 0x2e,
- 0x63, 0x6f, 0x6d, 0x2f, 0x62, 0x61, 0x6c, 0x74, 0x69, 0x6d, 0x6f, 0x72,
- 0x65, 0x72, 0x6f, 0x6f, 0x74, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f,
- 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x1f, 0x06,
- 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0xe5, 0x9d,
- 0x59, 0x30, 0x82, 0x47, 0x58, 0xcc, 0xac, 0xfa, 0x08, 0x54, 0x36, 0x86,
- 0x7b, 0x3a, 0xb5, 0x04, 0x4d, 0xf0, 0x30, 0x42, 0x06, 0x03, 0x55, 0x1d,
- 0x1f, 0x04, 0x3b, 0x30, 0x39, 0x30, 0x37, 0xa0, 0x35, 0xa0, 0x33, 0x86,
- 0x31, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x64, 0x70, 0x31,
- 0x2e, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x2d, 0x74, 0x72, 0x75, 0x73,
- 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x43, 0x52, 0x4c, 0x2f, 0x4f, 0x6d,
- 0x6e, 0x69, 0x72, 0x6f, 0x6f, 0x74, 0x32, 0x30, 0x32, 0x35, 0x2e, 0x63,
- 0x72, 0x6c, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04,
- 0x14, 0x73, 0xa8, 0x08, 0x53, 0x29, 0xb8, 0x15, 0xfb, 0x99, 0x80, 0xe5,
- 0xc5, 0x37, 0xd8, 0xf8, 0x39, 0x7b, 0xa4, 0x13, 0x06, 0x30, 0x0d, 0x06,
- 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00,
- 0x03, 0x82, 0x01, 0x01, 0x00, 0x68, 0xdf, 0xfe, 0x72, 0x54, 0x4e, 0x1b,
- 0xfb, 0x5c, 0x6e, 0x5a, 0x45, 0x46, 0xcf, 0x42, 0xbe, 0xb2, 0x02, 0x9c,
- 0x9d, 0x90, 0x6a, 0x09, 0x2e, 0xb7, 0x36, 0x64, 0x24, 0xb6, 0xb1, 0xe2,
- 0x48, 0x67, 0xce, 0x17, 0x46, 0x9b, 0x23, 0x75, 0x78, 0x11, 0xf6, 0xc6,
- 0x09, 0x38, 0x42, 0x62, 0x96, 0x97, 0x30, 0x7b, 0x51, 0x77, 0xdf, 0x33,
- 0xb5, 0x00, 0x51, 0x29, 0xd5, 0x24, 0xfe, 0xb7, 0x98, 0xa2, 0xac, 0x6c,
- 0xa1, 0x13, 0x7f, 0xca, 0xf3, 0xb7, 0xa6, 0x52, 0xc2, 0x16, 0x0d, 0xec,
- 0x3a, 0xbf, 0xa3, 0x37, 0x77, 0x4f, 0xae, 0x7b, 0x55, 0x1d, 0x46, 0xe9,
- 0x10, 0xda, 0xc3, 0xb4, 0x05, 0x5c, 0x5b, 0xf6, 0x48, 0x21, 0x00, 0x89,
- 0xf4, 0xbb, 0x38, 0x8e, 0x1e, 0x33, 0xf3, 0x49, 0x97, 0x81, 0x31, 0x6c,
- 0x16, 0x74, 0x08, 0x91, 0x17, 0xc0, 0xd3, 0x25, 0xb3, 0xbc, 0xc1, 0x15,
- 0xb5, 0xa4, 0xcd, 0x84, 0x4d, 0xb9, 0xc8, 0xeb, 0xc5, 0x59, 0x42, 0x10,
- 0x14, 0x25, 0x79, 0xf8, 0xdb, 0xb6, 0xd0, 0xe6, 0xd3, 0xa0, 0x14, 0x7c,
- 0x17, 0x1c, 0x20, 0x1e, 0xed, 0x99, 0x90, 0x65, 0xc0, 0x41, 0x71, 0xc3,
- 0xab, 0x3f, 0x29, 0x41, 0x67, 0xf9, 0xe2, 0xd1, 0x98, 0xe3, 0xf8, 0xdf,
- 0x3a, 0xb8, 0xca, 0xa3, 0x6f, 0x68, 0x8b, 0x6c, 0x9f, 0x6e, 0x88, 0x7c,
- 0x9d, 0x41, 0x5c, 0xba, 0xcb, 0x19, 0x05, 0x83, 0x9c, 0x99, 0xf4, 0x1a,
- 0xd2, 0x24, 0x69, 0x57, 0x0a, 0x0f, 0x7a, 0xc3, 0x1b, 0x2c, 0x4b, 0x06,
- 0xd3, 0x2a, 0x97, 0x7e, 0x07, 0xb0, 0xf9, 0x20, 0x5a, 0xb5, 0x92, 0x4b,
- 0x5b, 0xa8, 0xeb, 0xeb, 0x36, 0x33, 0x47, 0x36, 0xda, 0x72, 0x9c, 0xbf,
- 0x68, 0x45, 0x81, 0x31, 0xbe, 0xd2, 0xfd, 0x3b, 0xe9, 0x72, 0xd5, 0x70,
- 0xdd, 0xa6, 0xde, 0x5f, 0x0d, 0xb6, 0x5e, 0x00, 0x49,
-};
-
-#if 0
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number: 1828629 (0x1be715)
- Signature Algorithm: sha256WithRSAEncryption
- Issuer: C=US, O=The Go Daddy Group, Inc., OU=Go Daddy Class 2 Certification Authority
- Validity
- Not Before: Jan 1 07:00:00 2014 GMT
- Not After : May 30 07:00:00 2031 GMT
- Subject: C=US, ST=Arizona, L=Scottsdale, O=GoDaddy.com, Inc., CN=Go Daddy Root Certificate Authority - G2
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:bf:71:62:08:f1:fa:59:34:f7:1b:c9:18:a3:f7:
- 80:49:58:e9:22:83:13:a6:c5:20:43:01:3b:84:f1:
- e6:85:49:9f:27:ea:f6:84:1b:4e:a0:b4:db:70:98:
- c7:32:01:b1:05:3e:07:4e:ee:f4:fa:4f:2f:59:30:
- 22:e7:ab:19:56:6b:e2:80:07:fc:f3:16:75:80:39:
- 51:7b:e5:f9:35:b6:74:4e:a9:8d:82:13:e4:b6:3f:
- a9:03:83:fa:a2:be:8a:15:6a:7f:de:0b:c3:b6:19:
- 14:05:ca:ea:c3:a8:04:94:3b:46:7c:32:0d:f3:00:
- 66:22:c8:8d:69:6d:36:8c:11:18:b7:d3:b2:1c:60:
- b4:38:fa:02:8c:ce:d3:dd:46:07:de:0a:3e:eb:5d:
- 7c:c8:7c:fb:b0:2b:53:a4:92:62:69:51:25:05:61:
- 1a:44:81:8c:2c:a9:43:96:23:df:ac:3a:81:9a:0e:
- 29:c5:1c:a9:e9:5d:1e:b6:9e:9e:30:0a:39:ce:f1:
- 88:80:fb:4b:5d:cc:32:ec:85:62:43:25:34:02:56:
- 27:01:91:b4:3b:70:2a:3f:6e:b1:e8:9c:88:01:7d:
- 9f:d4:f9:db:53:6d:60:9d:bf:2c:e7:58:ab:b8:5f:
- 46:fc:ce:c4:1b:03:3c:09:eb:49:31:5c:69:46:b3:
- e0:47
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Basic Constraints: critical
- CA:TRUE
- X509v3 Key Usage: critical
- Certificate Sign, CRL Sign
- X509v3 Subject Key Identifier:
- 3A:9A:85:07:10:67:28:B6:EF:F6:BD:05:41:6E:20:C1:94:DA:0F:DE
- X509v3 Authority Key Identifier:
- keyid:D2:C4:B0:D2:91:D4:4C:11:71:B3:61:CB:3D:A1:FE:DD:A8:6A:D4:E3
-
- Authority Information Access:
- OCSP - URI:http://ocsp.godaddy.com/
-
- X509v3 CRL Distribution Points:
-
- Full Name:
- URI:http://crl.godaddy.com/gdroot.crl
-
- X509v3 Certificate Policies:
- Policy: X509v3 Any Policy
- CPS: https://certs.godaddy.com/repository/
-
- Signature Algorithm: sha256WithRSAEncryption
- 59:0b:53:bd:92:86:11:a7:24:7b:ed:5b:31:cf:1d:1f:6c:70:
- c5:b8:6e:be:4e:bb:f6:be:97:50:e1:30:7f:ba:28:5c:62:94:
- c2:e3:7e:33:f7:fb:42:76:85:db:95:1c:8c:22:58:75:09:0c:
- 88:65:67:39:0a:16:09:c5:a0:38:97:a4:c5:23:93:3f:b4:18:
- a6:01:06:44:91:e3:a7:69:27:b4:5a:25:7f:3a:b7:32:cd:dd:
- 84:ff:2a:38:29:33:a4:dd:67:b2:85:fe:a1:88:20:1c:50:89:
- c8:dc:2a:f6:42:03:37:4c:e6:88:df:d5:af:24:f2:b1:c3:df:
- cc:b5:ec:e0:99:5e:b7:49:54:20:3c:94:18:0c:c7:1c:52:18:
- 49:a4:6d:e1:b3:58:0b:c9:d8:ec:d9:ae:1c:32:8e:28:70:0d:
- e2:fe:a6:17:9e:84:0f:bd:57:70:b3:5a:e9:1f:a0:86:53:bb:
- ef:7c:ff:69:0b:e0:48:c3:b7:93:0b:c8:0a:54:c4:ac:5d:14:
- 67:37:6c:ca:a5:2f:31:08:37:aa:6e:6f:8c:bc:9b:e2:57:5d:
- 24:81:af:97:97:9c:84:ad:6c:ac:37:4c:66:f3:61:91:11:20:
- e4:be:30:9f:7a:a4:29:09:b0:e1:34:5f:64:77:18:40:51:df:
- 8c:30:a6:af
------BEGIN CERTIFICATE-----
-MIIEfTCCA2WgAwIBAgIDG+cVMA0GCSqGSIb3DQEBCwUAMGMxCzAJBgNVBAYTAlVT
-MSEwHwYDVQQKExhUaGUgR28gRGFkZHkgR3JvdXAsIEluYy4xMTAvBgNVBAsTKEdv
-IERhZGR5IENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTQwMTAx
-MDcwMDAwWhcNMzEwNTMwMDcwMDAwWjCBgzELMAkGA1UEBhMCVVMxEDAOBgNVBAgT
-B0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAYBgNVBAoTEUdvRGFkZHku
-Y29tLCBJbmMuMTEwLwYDVQQDEyhHbyBEYWRkeSBSb290IENlcnRpZmljYXRlIEF1
-dGhvcml0eSAtIEcyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAv3Fi
-CPH6WTT3G8kYo/eASVjpIoMTpsUgQwE7hPHmhUmfJ+r2hBtOoLTbcJjHMgGxBT4H
-Tu70+k8vWTAi56sZVmvigAf88xZ1gDlRe+X5NbZ0TqmNghPktj+pA4P6or6KFWp/
-3gvDthkUBcrqw6gElDtGfDIN8wBmIsiNaW02jBEYt9OyHGC0OPoCjM7T3UYH3go+
-6118yHz7sCtTpJJiaVElBWEaRIGMLKlDliPfrDqBmg4pxRyp6V0etp6eMAo5zvGI
-gPtLXcwy7IViQyU0AlYnAZG0O3AqP26x6JyIAX2f1PnbU21gnb8s51iruF9G/M7E
-GwM8CetJMVxpRrPgRwIDAQABo4IBFzCCARMwDwYDVR0TAQH/BAUwAwEB/zAOBgNV
-HQ8BAf8EBAMCAQYwHQYDVR0OBBYEFDqahQcQZyi27/a9BUFuIMGU2g/eMB8GA1Ud
-IwQYMBaAFNLEsNKR1EwRcbNhyz2h/t2oatTjMDQGCCsGAQUFBwEBBCgwJjAkBggr
-BgEFBQcwAYYYaHR0cDovL29jc3AuZ29kYWRkeS5jb20vMDIGA1UdHwQrMCkwJ6Al
-oCOGIWh0dHA6Ly9jcmwuZ29kYWRkeS5jb20vZ2Ryb290LmNybDBGBgNVHSAEPzA9
-MDsGBFUdIAAwMzAxBggrBgEFBQcCARYlaHR0cHM6Ly9jZXJ0cy5nb2RhZGR5LmNv
-bS9yZXBvc2l0b3J5LzANBgkqhkiG9w0BAQsFAAOCAQEAWQtTvZKGEacke+1bMc8d
-H2xwxbhuvk679r6XUOEwf7ooXGKUwuN+M/f7QnaF25UcjCJYdQkMiGVnOQoWCcWg
-OJekxSOTP7QYpgEGRJHjp2kntFolfzq3Ms3dhP8qOCkzpN1nsoX+oYggHFCJyNwq
-9kIDN0zmiN/VryTyscPfzLXs4Jlet0lUIDyUGAzHHFIYSaRt4bNYC8nY7NmuHDKO
-KHAN4v6mF56ED71XcLNa6R+ghlO773z/aQvgSMO3kwvIClTErF0UZzdsyqUvMQg3
-qm5vjLyb4lddJIGvl5echK1srDdMZvNhkREg5L4wn3qkKQmw4TRfZHcYQFHfjDCm
-rw==
------END CERTIFICATE-----
-#endif
-static const unsigned char kDERCert19[] = {
- 0x30, 0x82, 0x04, 0x7d, 0x30, 0x82, 0x03, 0x65, 0xa0, 0x03, 0x02, 0x01,
- 0x02, 0x02, 0x03, 0x1b, 0xe7, 0x15, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
- 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x63, 0x31,
- 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53,
- 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x18, 0x54,
- 0x68, 0x65, 0x20, 0x47, 0x6f, 0x20, 0x44, 0x61, 0x64, 0x64, 0x79, 0x20,
- 0x47, 0x72, 0x6f, 0x75, 0x70, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31,
- 0x31, 0x30, 0x2f, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x28, 0x47, 0x6f,
- 0x20, 0x44, 0x61, 0x64, 0x64, 0x79, 0x20, 0x43, 0x6c, 0x61, 0x73, 0x73,
- 0x20, 0x32, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61,
- 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69,
- 0x74, 0x79, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x34, 0x30, 0x31, 0x30, 0x31,
- 0x30, 0x37, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x33, 0x31, 0x30,
- 0x35, 0x33, 0x30, 0x30, 0x37, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x81,
- 0x83, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
- 0x55, 0x53, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13,
- 0x07, 0x41, 0x72, 0x69, 0x7a, 0x6f, 0x6e, 0x61, 0x31, 0x13, 0x30, 0x11,
- 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x0a, 0x53, 0x63, 0x6f, 0x74, 0x74,
- 0x73, 0x64, 0x61, 0x6c, 0x65, 0x31, 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55,
- 0x04, 0x0a, 0x13, 0x11, 0x47, 0x6f, 0x44, 0x61, 0x64, 0x64, 0x79, 0x2e,
- 0x63, 0x6f, 0x6d, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x31, 0x30,
- 0x2f, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x28, 0x47, 0x6f, 0x20, 0x44,
- 0x61, 0x64, 0x64, 0x79, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x65,
- 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75,
- 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x20, 0x2d, 0x20, 0x47, 0x32,
- 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
- 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00,
- 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xbf, 0x71, 0x62,
- 0x08, 0xf1, 0xfa, 0x59, 0x34, 0xf7, 0x1b, 0xc9, 0x18, 0xa3, 0xf7, 0x80,
- 0x49, 0x58, 0xe9, 0x22, 0x83, 0x13, 0xa6, 0xc5, 0x20, 0x43, 0x01, 0x3b,
- 0x84, 0xf1, 0xe6, 0x85, 0x49, 0x9f, 0x27, 0xea, 0xf6, 0x84, 0x1b, 0x4e,
- 0xa0, 0xb4, 0xdb, 0x70, 0x98, 0xc7, 0x32, 0x01, 0xb1, 0x05, 0x3e, 0x07,
- 0x4e, 0xee, 0xf4, 0xfa, 0x4f, 0x2f, 0x59, 0x30, 0x22, 0xe7, 0xab, 0x19,
- 0x56, 0x6b, 0xe2, 0x80, 0x07, 0xfc, 0xf3, 0x16, 0x75, 0x80, 0x39, 0x51,
- 0x7b, 0xe5, 0xf9, 0x35, 0xb6, 0x74, 0x4e, 0xa9, 0x8d, 0x82, 0x13, 0xe4,
- 0xb6, 0x3f, 0xa9, 0x03, 0x83, 0xfa, 0xa2, 0xbe, 0x8a, 0x15, 0x6a, 0x7f,
- 0xde, 0x0b, 0xc3, 0xb6, 0x19, 0x14, 0x05, 0xca, 0xea, 0xc3, 0xa8, 0x04,
- 0x94, 0x3b, 0x46, 0x7c, 0x32, 0x0d, 0xf3, 0x00, 0x66, 0x22, 0xc8, 0x8d,
- 0x69, 0x6d, 0x36, 0x8c, 0x11, 0x18, 0xb7, 0xd3, 0xb2, 0x1c, 0x60, 0xb4,
- 0x38, 0xfa, 0x02, 0x8c, 0xce, 0xd3, 0xdd, 0x46, 0x07, 0xde, 0x0a, 0x3e,
- 0xeb, 0x5d, 0x7c, 0xc8, 0x7c, 0xfb, 0xb0, 0x2b, 0x53, 0xa4, 0x92, 0x62,
- 0x69, 0x51, 0x25, 0x05, 0x61, 0x1a, 0x44, 0x81, 0x8c, 0x2c, 0xa9, 0x43,
- 0x96, 0x23, 0xdf, 0xac, 0x3a, 0x81, 0x9a, 0x0e, 0x29, 0xc5, 0x1c, 0xa9,
- 0xe9, 0x5d, 0x1e, 0xb6, 0x9e, 0x9e, 0x30, 0x0a, 0x39, 0xce, 0xf1, 0x88,
- 0x80, 0xfb, 0x4b, 0x5d, 0xcc, 0x32, 0xec, 0x85, 0x62, 0x43, 0x25, 0x34,
- 0x02, 0x56, 0x27, 0x01, 0x91, 0xb4, 0x3b, 0x70, 0x2a, 0x3f, 0x6e, 0xb1,
- 0xe8, 0x9c, 0x88, 0x01, 0x7d, 0x9f, 0xd4, 0xf9, 0xdb, 0x53, 0x6d, 0x60,
- 0x9d, 0xbf, 0x2c, 0xe7, 0x58, 0xab, 0xb8, 0x5f, 0x46, 0xfc, 0xce, 0xc4,
- 0x1b, 0x03, 0x3c, 0x09, 0xeb, 0x49, 0x31, 0x5c, 0x69, 0x46, 0xb3, 0xe0,
- 0x47, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x17, 0x30, 0x82,
- 0x01, 0x13, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff,
- 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0e, 0x06, 0x03, 0x55,
- 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30,
- 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x3a, 0x9a,
- 0x85, 0x07, 0x10, 0x67, 0x28, 0xb6, 0xef, 0xf6, 0xbd, 0x05, 0x41, 0x6e,
- 0x20, 0xc1, 0x94, 0xda, 0x0f, 0xde, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d,
- 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0xd2, 0xc4, 0xb0, 0xd2, 0x91,
- 0xd4, 0x4c, 0x11, 0x71, 0xb3, 0x61, 0xcb, 0x3d, 0xa1, 0xfe, 0xdd, 0xa8,
- 0x6a, 0xd4, 0xe3, 0x30, 0x34, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05,
- 0x07, 0x01, 0x01, 0x04, 0x28, 0x30, 0x26, 0x30, 0x24, 0x06, 0x08, 0x2b,
- 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x18, 0x68, 0x74, 0x74,
- 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x67, 0x6f, 0x64,
- 0x61, 0x64, 0x64, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x30, 0x32, 0x06,
- 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x2b, 0x30, 0x29, 0x30, 0x27, 0xa0, 0x25,
- 0xa0, 0x23, 0x86, 0x21, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63,
- 0x72, 0x6c, 0x2e, 0x67, 0x6f, 0x64, 0x61, 0x64, 0x64, 0x79, 0x2e, 0x63,
- 0x6f, 0x6d, 0x2f, 0x67, 0x64, 0x72, 0x6f, 0x6f, 0x74, 0x2e, 0x63, 0x72,
- 0x6c, 0x30, 0x46, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x3f, 0x30, 0x3d,
- 0x30, 0x3b, 0x06, 0x04, 0x55, 0x1d, 0x20, 0x00, 0x30, 0x33, 0x30, 0x31,
- 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x25,
- 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x63, 0x65, 0x72, 0x74,
- 0x73, 0x2e, 0x67, 0x6f, 0x64, 0x61, 0x64, 0x64, 0x79, 0x2e, 0x63, 0x6f,
- 0x6d, 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79,
- 0x2f, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
- 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x59, 0x0b, 0x53,
- 0xbd, 0x92, 0x86, 0x11, 0xa7, 0x24, 0x7b, 0xed, 0x5b, 0x31, 0xcf, 0x1d,
- 0x1f, 0x6c, 0x70, 0xc5, 0xb8, 0x6e, 0xbe, 0x4e, 0xbb, 0xf6, 0xbe, 0x97,
- 0x50, 0xe1, 0x30, 0x7f, 0xba, 0x28, 0x5c, 0x62, 0x94, 0xc2, 0xe3, 0x7e,
- 0x33, 0xf7, 0xfb, 0x42, 0x76, 0x85, 0xdb, 0x95, 0x1c, 0x8c, 0x22, 0x58,
- 0x75, 0x09, 0x0c, 0x88, 0x65, 0x67, 0x39, 0x0a, 0x16, 0x09, 0xc5, 0xa0,
- 0x38, 0x97, 0xa4, 0xc5, 0x23, 0x93, 0x3f, 0xb4, 0x18, 0xa6, 0x01, 0x06,
- 0x44, 0x91, 0xe3, 0xa7, 0x69, 0x27, 0xb4, 0x5a, 0x25, 0x7f, 0x3a, 0xb7,
- 0x32, 0xcd, 0xdd, 0x84, 0xff, 0x2a, 0x38, 0x29, 0x33, 0xa4, 0xdd, 0x67,
- 0xb2, 0x85, 0xfe, 0xa1, 0x88, 0x20, 0x1c, 0x50, 0x89, 0xc8, 0xdc, 0x2a,
- 0xf6, 0x42, 0x03, 0x37, 0x4c, 0xe6, 0x88, 0xdf, 0xd5, 0xaf, 0x24, 0xf2,
- 0xb1, 0xc3, 0xdf, 0xcc, 0xb5, 0xec, 0xe0, 0x99, 0x5e, 0xb7, 0x49, 0x54,
- 0x20, 0x3c, 0x94, 0x18, 0x0c, 0xc7, 0x1c, 0x52, 0x18, 0x49, 0xa4, 0x6d,
- 0xe1, 0xb3, 0x58, 0x0b, 0xc9, 0xd8, 0xec, 0xd9, 0xae, 0x1c, 0x32, 0x8e,
- 0x28, 0x70, 0x0d, 0xe2, 0xfe, 0xa6, 0x17, 0x9e, 0x84, 0x0f, 0xbd, 0x57,
- 0x70, 0xb3, 0x5a, 0xe9, 0x1f, 0xa0, 0x86, 0x53, 0xbb, 0xef, 0x7c, 0xff,
- 0x69, 0x0b, 0xe0, 0x48, 0xc3, 0xb7, 0x93, 0x0b, 0xc8, 0x0a, 0x54, 0xc4,
- 0xac, 0x5d, 0x14, 0x67, 0x37, 0x6c, 0xca, 0xa5, 0x2f, 0x31, 0x08, 0x37,
- 0xaa, 0x6e, 0x6f, 0x8c, 0xbc, 0x9b, 0xe2, 0x57, 0x5d, 0x24, 0x81, 0xaf,
- 0x97, 0x97, 0x9c, 0x84, 0xad, 0x6c, 0xac, 0x37, 0x4c, 0x66, 0xf3, 0x61,
- 0x91, 0x11, 0x20, 0xe4, 0xbe, 0x30, 0x9f, 0x7a, 0xa4, 0x29, 0x09, 0xb0,
- 0xe1, 0x34, 0x5f, 0x64, 0x77, 0x18, 0x40, 0x51, 0xdf, 0x8c, 0x30, 0xa6,
- 0xaf,
-};
-
-#if 0
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number:
- 46:f0:8c:db:cf:2c:54:66:ef:33:01:dd:5f:34
- Signature Algorithm: sha256WithRSAEncryption
- Issuer: C=BE, O=GlobalSign nv-sa, OU=Root CA, CN=GlobalSign Root CA
- Validity
- Not Before: Aug 19 00:00:00 2015 GMT
- Not After : Aug 19 00:00:00 2025 GMT
- Subject: C=BE, O=GlobalSign nv-sa, CN=GlobalSign CloudSSL CA - SHA256 - G3
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:a3:c0:75:e1:32:98:e5:d9:ae:84:7c:8d:e8:23:
- 5f:46:95:5b:4c:a2:25:70:d7:90:04:85:80:c9:b5:
- f4:8a:65:4d:92:cb:a5:c4:42:a0:b6:79:25:31:ed:
- f1:85:20:cd:13:51:3d:67:ac:97:4d:68:9b:33:86:
- 5c:b3:7b:2d:aa:df:77:a0:61:d1:f5:3c:fb:9a:fc:
- d3:d5:94:ca:c9:1e:80:1b:90:90:c8:ac:8d:f6:60:
- 17:9c:31:b8:c5:61:a2:e2:6e:57:25:08:6f:24:99:
- 99:cf:94:bf:c7:8b:6b:b0:1f:ca:14:fa:18:9b:6c:
- 10:7c:99:2b:da:4a:63:e5:b2:4e:c2:fd:3e:10:0b:
- 48:f4:77:0b:2f:f0:96:4b:3a:ee:bd:35:de:85:8d:
- da:13:0e:ce:01:c4:71:d3:d3:77:c5:08:a6:60:39:
- 25:a7:27:69:5c:83:d1:6f:76:78:ee:c5:44:5b:45:
- bd:29:3b:e2:c6:09:0f:a2:be:2b:dc:e3:5c:da:5a:
- 6f:8e:e7:c9:07:6b:7e:a1:c0:53:95:82:89:e0:78:
- 5c:72:a8:6c:be:67:6b:ab:e7:33:d9:87:f2:f8:5c:
- 27:f4:f6:2a:3b:87:ef:da:c2:47:da:bf:ac:eb:27:
- 64:7b:4c:53:eb:34:e1:2f:9b:20:4d:54:12:6b:7d:
- 28:bd
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Key Usage: critical
- Certificate Sign, CRL Sign
- X509v3 Extended Key Usage:
- TLS Web Server Authentication, TLS Web Client Authentication
- X509v3 Basic Constraints: critical
- CA:TRUE, pathlen:0
- X509v3 Subject Key Identifier:
- A9:2B:87:E1:CE:24:47:3B:1B:BF:CF:85:37:02:55:9D:0D:94:58:E6
- X509v3 Authority Key Identifier:
- keyid:60:7B:66:1A:45:0D:97:CA:89:50:2F:7D:04:CD:34:A8:FF:FC:FD:4B
-
- Authority Information Access:
- OCSP - URI:http://ocsp.globalsign.com/rootr1
-
- X509v3 CRL Distribution Points:
-
- Full Name:
- URI:http://crl.globalsign.com/root.crl
-
- X509v3 Certificate Policies:
- Policy: 1.3.6.1.4.1.4146.1.20
- Policy: 2.23.140.1.2.2
- CPS: https://www.globalsign.com/repository/
-
- Signature Algorithm: sha256WithRSAEncryption
- a2:1d:69:8a:0a:8e:c4:14:83:2a:2a:12:4d:39:27:90:4e:f0:
- 8d:ac:d2:96:62:47:36:5e:92:d1:fa:c5:93:b5:37:07:65:29:
- d2:f4:53:50:6b:c9:f4:fe:34:f5:dd:b8:1d:fa:fc:dc:14:ac:
- 56:94:27:9c:42:aa:04:4d:b7:ed:58:d9:99:d2:49:e6:20:2f:
- d3:a7:77:b8:2a:89:1a:ef:a7:cf:86:2d:d6:53:e9:0b:93:9c:
- 4e:ab:d9:45:ee:a4:84:85:ff:34:e4:0e:c0:bb:a5:ce:5f:95:
- 89:85:70:aa:c1:5d:ec:cf:2b:d3:d9:83:df:03:ca:81:a7:02:
- 32:b7:77:61:10:25:4e:d9:74:f3:d9:79:82:b5:26:70:b4:52:
- bc:8f:33:d7:8a:ae:19:d0:fc:92:ad:2f:ba:3c:a0:48:58:47:
- 5e:fd:20:56:95:20:c1:72:1d:ab:66:99:a4:d5:78:37:48:1b:
- 9f:b2:4c:37:67:7a:fd:42:d2:d3:56:9e:d3:1d:8e:c4:0c:68:
- 96:b6:47:51:10:f7:7b:eb:15:09:64:f5:f9:f0:63:16:2d:3d:
- df:23:42:3a:93:63:cc:ab:af:4f:57:06:c7:fe:14:55:62:ce:
- 27:11:19:e1:f4:42:ed:22:30:6b:35:1a:4a:05:80:a4:65:df:
- cc:cb:6f:d0
------BEGIN CERTIFICATE-----
-MIIEizCCA3OgAwIBAgIORvCM288sVGbvMwHdXzQwDQYJKoZIhvcNAQELBQAwVzEL
-MAkGA1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsT
-B1Jvb3QgQ0ExGzAZBgNVBAMTEkdsb2JhbFNpZ24gUm9vdCBDQTAeFw0xNTA4MTkw
-MDAwMDBaFw0yNTA4MTkwMDAwMDBaMFcxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBH
-bG9iYWxTaWduIG52LXNhMS0wKwYDVQQDEyRHbG9iYWxTaWduIENsb3VkU1NMIENB
-IC0gU0hBMjU2IC0gRzMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCj
-wHXhMpjl2a6EfI3oI19GlVtMoiVw15AEhYDJtfSKZU2Sy6XEQqC2eSUx7fGFIM0T
-UT1nrJdNaJszhlyzey2q33egYdH1PPua/NPVlMrJHoAbkJDIrI32YBecMbjFYaLi
-blclCG8kmZnPlL/Hi2uwH8oU+hibbBB8mSvaSmPlsk7C/T4QC0j0dwsv8JZLOu69
-Nd6FjdoTDs4BxHHT03fFCKZgOSWnJ2lcg9FvdnjuxURbRb0pO+LGCQ+ivivc41za
-Wm+O58kHa36hwFOVgongeFxyqGy+Z2ur5zPZh/L4XCf09io7h+/awkfav6zrJ2R7
-TFPrNOEvmyBNVBJrfSi9AgMBAAGjggFTMIIBTzAOBgNVHQ8BAf8EBAMCAQYwHQYD
-VR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMBIGA1UdEwEB/wQIMAYBAf8CAQAw
-HQYDVR0OBBYEFKkrh+HOJEc7G7/PhTcCVZ0NlFjmMB8GA1UdIwQYMBaAFGB7ZhpF
-DZfKiVAvfQTNNKj//P1LMD0GCCsGAQUFBwEBBDEwLzAtBggrBgEFBQcwAYYhaHR0
-cDovL29jc3AuZ2xvYmFsc2lnbi5jb20vcm9vdHIxMDMGA1UdHwQsMCowKKAmoCSG
-Imh0dHA6Ly9jcmwuZ2xvYmFsc2lnbi5jb20vcm9vdC5jcmwwVgYDVR0gBE8wTTAL
-BgkrBgEEAaAyARQwPgYGZ4EMAQICMDQwMgYIKwYBBQUHAgEWJmh0dHBzOi8vd3d3
-Lmdsb2JhbHNpZ24uY29tL3JlcG9zaXRvcnkvMA0GCSqGSIb3DQEBCwUAA4IBAQCi
-HWmKCo7EFIMqKhJNOSeQTvCNrNKWYkc2XpLR+sWTtTcHZSnS9FNQa8n0/jT13bgd
-+vzcFKxWlCecQqoETbftWNmZ0knmIC/Tp3e4Koka76fPhi3WU+kLk5xOq9lF7qSE
-hf805A7Au6XOX5WJhXCqwV3szyvT2YPfA8qBpwIyt3dhECVO2XTz2XmCtSZwtFK8
-jzPXiq4Z0PySrS+6PKBIWEde/SBWlSDBch2rZpmk1Xg3SBufskw3Z3r9QtLTVp7T
-HY7EDGiWtkdREPd76xUJZPX58GMWLT3fI0I6k2PMq69PVwbH/hRVYs4nERnh9ELt
-IjBrNRpKBYCkZd/My2/Q
------END CERTIFICATE-----
-#endif
-static const unsigned char kDERCert20[] = {
- 0x30, 0x82, 0x04, 0x8b, 0x30, 0x82, 0x03, 0x73, 0xa0, 0x03, 0x02, 0x01,
- 0x02, 0x02, 0x0e, 0x46, 0xf0, 0x8c, 0xdb, 0xcf, 0x2c, 0x54, 0x66, 0xef,
- 0x33, 0x01, 0xdd, 0x5f, 0x34, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48,
- 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x57, 0x31, 0x0b,
- 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x42, 0x45, 0x31,
- 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x10, 0x47, 0x6c,
- 0x6f, 0x62, 0x61, 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x6e, 0x76, 0x2d,
- 0x73, 0x61, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13,
- 0x07, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41, 0x31, 0x1b, 0x30, 0x19,
- 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x12, 0x47, 0x6c, 0x6f, 0x62, 0x61,
- 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43,
- 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x35, 0x30, 0x38, 0x31, 0x39, 0x30,
- 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x35, 0x30, 0x38,
- 0x31, 0x39, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x57, 0x31,
- 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x42, 0x45,
- 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x10, 0x47,
- 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x6e, 0x76,
- 0x2d, 0x73, 0x61, 0x31, 0x2d, 0x30, 0x2b, 0x06, 0x03, 0x55, 0x04, 0x03,
- 0x13, 0x24, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x53, 0x69, 0x67, 0x6e,
- 0x20, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x53, 0x53, 0x4c, 0x20, 0x43, 0x41,
- 0x20, 0x2d, 0x20, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, 0x20, 0x2d, 0x20,
- 0x47, 0x33, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
- 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01,
- 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xa3,
- 0xc0, 0x75, 0xe1, 0x32, 0x98, 0xe5, 0xd9, 0xae, 0x84, 0x7c, 0x8d, 0xe8,
- 0x23, 0x5f, 0x46, 0x95, 0x5b, 0x4c, 0xa2, 0x25, 0x70, 0xd7, 0x90, 0x04,
- 0x85, 0x80, 0xc9, 0xb5, 0xf4, 0x8a, 0x65, 0x4d, 0x92, 0xcb, 0xa5, 0xc4,
- 0x42, 0xa0, 0xb6, 0x79, 0x25, 0x31, 0xed, 0xf1, 0x85, 0x20, 0xcd, 0x13,
- 0x51, 0x3d, 0x67, 0xac, 0x97, 0x4d, 0x68, 0x9b, 0x33, 0x86, 0x5c, 0xb3,
- 0x7b, 0x2d, 0xaa, 0xdf, 0x77, 0xa0, 0x61, 0xd1, 0xf5, 0x3c, 0xfb, 0x9a,
- 0xfc, 0xd3, 0xd5, 0x94, 0xca, 0xc9, 0x1e, 0x80, 0x1b, 0x90, 0x90, 0xc8,
- 0xac, 0x8d, 0xf6, 0x60, 0x17, 0x9c, 0x31, 0xb8, 0xc5, 0x61, 0xa2, 0xe2,
- 0x6e, 0x57, 0x25, 0x08, 0x6f, 0x24, 0x99, 0x99, 0xcf, 0x94, 0xbf, 0xc7,
- 0x8b, 0x6b, 0xb0, 0x1f, 0xca, 0x14, 0xfa, 0x18, 0x9b, 0x6c, 0x10, 0x7c,
- 0x99, 0x2b, 0xda, 0x4a, 0x63, 0xe5, 0xb2, 0x4e, 0xc2, 0xfd, 0x3e, 0x10,
- 0x0b, 0x48, 0xf4, 0x77, 0x0b, 0x2f, 0xf0, 0x96, 0x4b, 0x3a, 0xee, 0xbd,
- 0x35, 0xde, 0x85, 0x8d, 0xda, 0x13, 0x0e, 0xce, 0x01, 0xc4, 0x71, 0xd3,
- 0xd3, 0x77, 0xc5, 0x08, 0xa6, 0x60, 0x39, 0x25, 0xa7, 0x27, 0x69, 0x5c,
- 0x83, 0xd1, 0x6f, 0x76, 0x78, 0xee, 0xc5, 0x44, 0x5b, 0x45, 0xbd, 0x29,
- 0x3b, 0xe2, 0xc6, 0x09, 0x0f, 0xa2, 0xbe, 0x2b, 0xdc, 0xe3, 0x5c, 0xda,
- 0x5a, 0x6f, 0x8e, 0xe7, 0xc9, 0x07, 0x6b, 0x7e, 0xa1, 0xc0, 0x53, 0x95,
- 0x82, 0x89, 0xe0, 0x78, 0x5c, 0x72, 0xa8, 0x6c, 0xbe, 0x67, 0x6b, 0xab,
- 0xe7, 0x33, 0xd9, 0x87, 0xf2, 0xf8, 0x5c, 0x27, 0xf4, 0xf6, 0x2a, 0x3b,
- 0x87, 0xef, 0xda, 0xc2, 0x47, 0xda, 0xbf, 0xac, 0xeb, 0x27, 0x64, 0x7b,
- 0x4c, 0x53, 0xeb, 0x34, 0xe1, 0x2f, 0x9b, 0x20, 0x4d, 0x54, 0x12, 0x6b,
- 0x7d, 0x28, 0xbd, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x53,
- 0x30, 0x82, 0x01, 0x4f, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01,
- 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x1d, 0x06, 0x03,
- 0x55, 0x1d, 0x25, 0x04, 0x16, 0x30, 0x14, 0x06, 0x08, 0x2b, 0x06, 0x01,
- 0x05, 0x05, 0x07, 0x03, 0x01, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05,
- 0x07, 0x03, 0x02, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01,
- 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x00, 0x30,
- 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xa9, 0x2b,
- 0x87, 0xe1, 0xce, 0x24, 0x47, 0x3b, 0x1b, 0xbf, 0xcf, 0x85, 0x37, 0x02,
- 0x55, 0x9d, 0x0d, 0x94, 0x58, 0xe6, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d,
- 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x60, 0x7b, 0x66, 0x1a, 0x45,
- 0x0d, 0x97, 0xca, 0x89, 0x50, 0x2f, 0x7d, 0x04, 0xcd, 0x34, 0xa8, 0xff,
- 0xfc, 0xfd, 0x4b, 0x30, 0x3d, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05,
- 0x07, 0x01, 0x01, 0x04, 0x31, 0x30, 0x2f, 0x30, 0x2d, 0x06, 0x08, 0x2b,
- 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x21, 0x68, 0x74, 0x74,
- 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x67, 0x6c, 0x6f,
- 0x62, 0x61, 0x6c, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f,
- 0x72, 0x6f, 0x6f, 0x74, 0x72, 0x31, 0x30, 0x33, 0x06, 0x03, 0x55, 0x1d,
- 0x1f, 0x04, 0x2c, 0x30, 0x2a, 0x30, 0x28, 0xa0, 0x26, 0xa0, 0x24, 0x86,
- 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e,
- 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63,
- 0x6f, 0x6d, 0x2f, 0x72, 0x6f, 0x6f, 0x74, 0x2e, 0x63, 0x72, 0x6c, 0x30,
- 0x56, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x4f, 0x30, 0x4d, 0x30, 0x0b,
- 0x06, 0x09, 0x2b, 0x06, 0x01, 0x04, 0x01, 0xa0, 0x32, 0x01, 0x14, 0x30,
- 0x3e, 0x06, 0x06, 0x67, 0x81, 0x0c, 0x01, 0x02, 0x02, 0x30, 0x34, 0x30,
- 0x32, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16,
- 0x26, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77,
- 0x2e, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x73, 0x69, 0x67, 0x6e, 0x2e,
- 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f,
- 0x72, 0x79, 0x2f, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
- 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0xa2,
- 0x1d, 0x69, 0x8a, 0x0a, 0x8e, 0xc4, 0x14, 0x83, 0x2a, 0x2a, 0x12, 0x4d,
- 0x39, 0x27, 0x90, 0x4e, 0xf0, 0x8d, 0xac, 0xd2, 0x96, 0x62, 0x47, 0x36,
- 0x5e, 0x92, 0xd1, 0xfa, 0xc5, 0x93, 0xb5, 0x37, 0x07, 0x65, 0x29, 0xd2,
- 0xf4, 0x53, 0x50, 0x6b, 0xc9, 0xf4, 0xfe, 0x34, 0xf5, 0xdd, 0xb8, 0x1d,
- 0xfa, 0xfc, 0xdc, 0x14, 0xac, 0x56, 0x94, 0x27, 0x9c, 0x42, 0xaa, 0x04,
- 0x4d, 0xb7, 0xed, 0x58, 0xd9, 0x99, 0xd2, 0x49, 0xe6, 0x20, 0x2f, 0xd3,
- 0xa7, 0x77, 0xb8, 0x2a, 0x89, 0x1a, 0xef, 0xa7, 0xcf, 0x86, 0x2d, 0xd6,
- 0x53, 0xe9, 0x0b, 0x93, 0x9c, 0x4e, 0xab, 0xd9, 0x45, 0xee, 0xa4, 0x84,
- 0x85, 0xff, 0x34, 0xe4, 0x0e, 0xc0, 0xbb, 0xa5, 0xce, 0x5f, 0x95, 0x89,
- 0x85, 0x70, 0xaa, 0xc1, 0x5d, 0xec, 0xcf, 0x2b, 0xd3, 0xd9, 0x83, 0xdf,
- 0x03, 0xca, 0x81, 0xa7, 0x02, 0x32, 0xb7, 0x77, 0x61, 0x10, 0x25, 0x4e,
- 0xd9, 0x74, 0xf3, 0xd9, 0x79, 0x82, 0xb5, 0x26, 0x70, 0xb4, 0x52, 0xbc,
- 0x8f, 0x33, 0xd7, 0x8a, 0xae, 0x19, 0xd0, 0xfc, 0x92, 0xad, 0x2f, 0xba,
- 0x3c, 0xa0, 0x48, 0x58, 0x47, 0x5e, 0xfd, 0x20, 0x56, 0x95, 0x20, 0xc1,
- 0x72, 0x1d, 0xab, 0x66, 0x99, 0xa4, 0xd5, 0x78, 0x37, 0x48, 0x1b, 0x9f,
- 0xb2, 0x4c, 0x37, 0x67, 0x7a, 0xfd, 0x42, 0xd2, 0xd3, 0x56, 0x9e, 0xd3,
- 0x1d, 0x8e, 0xc4, 0x0c, 0x68, 0x96, 0xb6, 0x47, 0x51, 0x10, 0xf7, 0x7b,
- 0xeb, 0x15, 0x09, 0x64, 0xf5, 0xf9, 0xf0, 0x63, 0x16, 0x2d, 0x3d, 0xdf,
- 0x23, 0x42, 0x3a, 0x93, 0x63, 0xcc, 0xab, 0xaf, 0x4f, 0x57, 0x06, 0xc7,
- 0xfe, 0x14, 0x55, 0x62, 0xce, 0x27, 0x11, 0x19, 0xe1, 0xf4, 0x42, 0xed,
- 0x22, 0x30, 0x6b, 0x35, 0x1a, 0x4a, 0x05, 0x80, 0xa4, 0x65, 0xdf, 0xcc,
- 0xcb, 0x6f, 0xd0,
-};
-
-#if 0
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number:
- 1b:09:3b:78:60:96:da:37:bb:a4:51:94:46:c8:96:78
- Signature Algorithm: sha1WithRSAEncryption
- Issuer: C=US, O=VeriSign, Inc., OU=Class 3 Public Primary Certification Authority
- Validity
- Not Before: Nov 8 00:00:00 2006 GMT
- Not After : Nov 7 23:59:59 2021 GMT
- Subject: C=US, O=VeriSign, Inc., OU=VeriSign Trust Network, OU=(c) 2006 VeriSign, Inc. - For authorized use only, CN=VeriSign Class 3 Public Primary Certification Authority - G5
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:af:24:08:08:29:7a:35:9e:60:0c:aa:e7:4b:3b:
- 4e:dc:7c:bc:3c:45:1c:bb:2b:e0:fe:29:02:f9:57:
- 08:a3:64:85:15:27:f5:f1:ad:c8:31:89:5d:22:e8:
- 2a:aa:a6:42:b3:8f:f8:b9:55:b7:b1:b7:4b:b3:fe:
- 8f:7e:07:57:ec:ef:43:db:66:62:15:61:cf:60:0d:
- a4:d8:de:f8:e0:c3:62:08:3d:54:13:eb:49:ca:59:
- 54:85:26:e5:2b:8f:1b:9f:eb:f5:a1:91:c2:33:49:
- d8:43:63:6a:52:4b:d2:8f:e8:70:51:4d:d1:89:69:
- 7b:c7:70:f6:b3:dc:12:74:db:7b:5d:4b:56:d3:96:
- bf:15:77:a1:b0:f4:a2:25:f2:af:1c:92:67:18:e5:
- f4:06:04:ef:90:b9:e4:00:e4:dd:3a:b5:19:ff:02:
- ba:f4:3c:ee:e0:8b:eb:37:8b:ec:f4:d7:ac:f2:f6:
- f0:3d:af:dd:75:91:33:19:1d:1c:40:cb:74:24:19:
- 21:93:d9:14:fe:ac:2a:52:c7:8f:d5:04:49:e4:8d:
- 63:47:88:3c:69:83:cb:fe:47:bd:2b:7e:4f:c5:95:
- ae:0e:9d:d4:d1:43:c0:67:73:e3:14:08:7e:e5:3f:
- 9f:73:b8:33:0a:cf:5d:3f:34:87:96:8a:ee:53:e8:
- 25:15
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Basic Constraints: critical
- CA:TRUE
- X509v3 CRL Distribution Points:
-
- Full Name:
- URI:http://crl.verisign.com/pca3.crl
-
- X509v3 Key Usage: critical
- Certificate Sign, CRL Sign
- X509v3 Certificate Policies:
- Policy: X509v3 Any Policy
- CPS: https://www.verisign.com/cps
-
- X509v3 Subject Key Identifier:
- 7F:D3:65:A7:C2:DD:EC:BB:F0:30:09:F3:43:39:FA:02:AF:33:31:33
- 1.3.6.1.5.5.7.1.12:
- 0_.].[0Y0W0U..image/gif0!0.0...+..............k...j.H.,{..0%.#http://logo.verisign.com/vslogo.gif
- Authority Information Access:
- OCSP - URI:http://ocsp.verisign.com
-
- Signature Algorithm: sha1WithRSAEncryption
- a3:cd:7d:1e:f7:c7:75:8d:48:e7:56:34:4c:00:90:75:a9:51:
- a5:56:c1:6d:bc:fe:f5:53:22:e9:98:a2:ac:9a:7e:70:1e:b3:
- 8e:3b:45:e3:86:95:31:da:6d:4c:fb:34:50:80:96:cd:24:f2:
- 40:df:04:3f:e2:65:ce:34:22:61:15:ea:66:70:64:d2:f1:6e:
- f3:ca:18:59:6a:41:46:7e:82:de:19:b0:70:31:56:69:0d:0c:
- e6:1d:9d:71:58:dc:cc:de:62:f5:e1:7a:10:02:d8:7a:dc:3b:
- fa:57:bd:c9:e9:8f:46:21:39:9f:51:65:4c:8e:3a:be:28:41:
- 70:1d
------BEGIN CERTIFICATE-----
-MIIEkDCCA/mgAwIBAgIQGwk7eGCW2je7pFGURsiWeDANBgkqhkiG9w0BAQUFADBf
-MQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xNzA1BgNVBAsT
-LkNsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkw
-HhcNMDYxMTA4MDAwMDAwWhcNMjExMTA3MjM1OTU5WjCByjELMAkGA1UEBhMCVVMx
-FzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBUcnVz
-dCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJpU2lnbiwgSW5jLiAtIEZv
-ciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAz
-IFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzUwggEi
-MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvJAgIKXo1nmAMqudLO07cfLw8
-RRy7K+D+KQL5VwijZIUVJ/XxrcgxiV0i6CqqpkKzj/i5Vbext0uz/o9+B1fs70Pb
-ZmIVYc9gDaTY3vjgw2IIPVQT60nKWVSFJuUrjxuf6/WhkcIzSdhDY2pSS9KP6HBR
-TdGJaXvHcPaz3BJ023tdS1bTlr8Vd6Gw9KIl8q8ckmcY5fQGBO+QueQA5N06tRn/
-Arr0PO7gi+s3i+z016zy9vA9r911kTMZHRxAy3QkGSGT2RT+rCpSx4/VBEnkjWNH
-iDxpg8v+R70rfk/Fla4OndTRQ8Bnc+MUCH7lP59zuDMKz10/NIeWiu5T6CUVAgMB
-AAGjggFbMIIBVzAPBgNVHRMBAf8EBTADAQH/MDEGA1UdHwQqMCgwJqAkoCKGIGh0
-dHA6Ly9jcmwudmVyaXNpZ24uY29tL3BjYTMuY3JsMA4GA1UdDwEB/wQEAwIBBjA9
-BgNVHSAENjA0MDIGBFUdIAAwKjAoBggrBgEFBQcCARYcaHR0cHM6Ly93d3cudmVy
-aXNpZ24uY29tL2NwczAdBgNVHQ4EFgQUf9Nlp8Ld7LvwMAnzQzn6Aq8zMTMwbQYI
-KwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2UvZ2lmMCEwHzAHBgUrDgMCGgQU
-j+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDovL2xvZ28udmVyaXNpZ24uY29t
-L3ZzbG9nby5naWYwNAYIKwYBBQUHAQEEKDAmMCQGCCsGAQUFBzABhhhodHRwOi8v
-b2NzcC52ZXJpc2lnbi5jb20wDQYJKoZIhvcNAQEFBQADgYEAo819HvfHdY1I51Y0
-TACQdalRpVbBbbz+9VMi6ZiirJp+cB6zjjtF44aVMdptTPs0UICWzSTyQN8EP+Jl
-zjQiYRXqZnBk0vFu88oYWWpBRn6C3hmwcDFWaQ0M5h2dcVjczN5i9eF6EALYetw7
-+le9yemPRiE5n1FlTI46vihBcB0=
------END CERTIFICATE-----
-#endif
-static const unsigned char kDERCert21[] = {
- 0x30, 0x82, 0x04, 0x90, 0x30, 0x82, 0x03, 0xf9, 0xa0, 0x03, 0x02, 0x01,
- 0x02, 0x02, 0x10, 0x1b, 0x09, 0x3b, 0x78, 0x60, 0x96, 0xda, 0x37, 0xbb,
- 0xa4, 0x51, 0x94, 0x46, 0xc8, 0x96, 0x78, 0x30, 0x0d, 0x06, 0x09, 0x2a,
- 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x5f,
- 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55,
- 0x53, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0e,
- 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e,
- 0x63, 0x2e, 0x31, 0x37, 0x30, 0x35, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13,
- 0x2e, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x33, 0x20, 0x50, 0x75, 0x62,
- 0x6c, 0x69, 0x63, 0x20, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x20,
- 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f,
- 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x30,
- 0x1e, 0x17, 0x0d, 0x30, 0x36, 0x31, 0x31, 0x30, 0x38, 0x30, 0x30, 0x30,
- 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x31, 0x31, 0x31, 0x30, 0x37,
- 0x32, 0x33, 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x81, 0xca, 0x31, 0x0b,
- 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31,
- 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0e, 0x56, 0x65,
- 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e,
- 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x16, 0x56,
- 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x54, 0x72, 0x75, 0x73,
- 0x74, 0x20, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x31, 0x3a, 0x30,
- 0x38, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x31, 0x28, 0x63, 0x29, 0x20,
- 0x32, 0x30, 0x30, 0x36, 0x20, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67,
- 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x20, 0x2d, 0x20, 0x46, 0x6f,
- 0x72, 0x20, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64,
- 0x20, 0x75, 0x73, 0x65, 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x31, 0x45, 0x30,
- 0x43, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x3c, 0x56, 0x65, 0x72, 0x69,
- 0x53, 0x69, 0x67, 0x6e, 0x20, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x33,
- 0x20, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x20, 0x50, 0x72, 0x69, 0x6d,
- 0x61, 0x72, 0x79, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63,
- 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72,
- 0x69, 0x74, 0x79, 0x20, 0x2d, 0x20, 0x47, 0x35, 0x30, 0x82, 0x01, 0x22,
- 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
- 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a,
- 0x02, 0x82, 0x01, 0x01, 0x00, 0xaf, 0x24, 0x08, 0x08, 0x29, 0x7a, 0x35,
- 0x9e, 0x60, 0x0c, 0xaa, 0xe7, 0x4b, 0x3b, 0x4e, 0xdc, 0x7c, 0xbc, 0x3c,
- 0x45, 0x1c, 0xbb, 0x2b, 0xe0, 0xfe, 0x29, 0x02, 0xf9, 0x57, 0x08, 0xa3,
- 0x64, 0x85, 0x15, 0x27, 0xf5, 0xf1, 0xad, 0xc8, 0x31, 0x89, 0x5d, 0x22,
- 0xe8, 0x2a, 0xaa, 0xa6, 0x42, 0xb3, 0x8f, 0xf8, 0xb9, 0x55, 0xb7, 0xb1,
- 0xb7, 0x4b, 0xb3, 0xfe, 0x8f, 0x7e, 0x07, 0x57, 0xec, 0xef, 0x43, 0xdb,
- 0x66, 0x62, 0x15, 0x61, 0xcf, 0x60, 0x0d, 0xa4, 0xd8, 0xde, 0xf8, 0xe0,
- 0xc3, 0x62, 0x08, 0x3d, 0x54, 0x13, 0xeb, 0x49, 0xca, 0x59, 0x54, 0x85,
- 0x26, 0xe5, 0x2b, 0x8f, 0x1b, 0x9f, 0xeb, 0xf5, 0xa1, 0x91, 0xc2, 0x33,
- 0x49, 0xd8, 0x43, 0x63, 0x6a, 0x52, 0x4b, 0xd2, 0x8f, 0xe8, 0x70, 0x51,
- 0x4d, 0xd1, 0x89, 0x69, 0x7b, 0xc7, 0x70, 0xf6, 0xb3, 0xdc, 0x12, 0x74,
- 0xdb, 0x7b, 0x5d, 0x4b, 0x56, 0xd3, 0x96, 0xbf, 0x15, 0x77, 0xa1, 0xb0,
- 0xf4, 0xa2, 0x25, 0xf2, 0xaf, 0x1c, 0x92, 0x67, 0x18, 0xe5, 0xf4, 0x06,
- 0x04, 0xef, 0x90, 0xb9, 0xe4, 0x00, 0xe4, 0xdd, 0x3a, 0xb5, 0x19, 0xff,
- 0x02, 0xba, 0xf4, 0x3c, 0xee, 0xe0, 0x8b, 0xeb, 0x37, 0x8b, 0xec, 0xf4,
- 0xd7, 0xac, 0xf2, 0xf6, 0xf0, 0x3d, 0xaf, 0xdd, 0x75, 0x91, 0x33, 0x19,
- 0x1d, 0x1c, 0x40, 0xcb, 0x74, 0x24, 0x19, 0x21, 0x93, 0xd9, 0x14, 0xfe,
- 0xac, 0x2a, 0x52, 0xc7, 0x8f, 0xd5, 0x04, 0x49, 0xe4, 0x8d, 0x63, 0x47,
- 0x88, 0x3c, 0x69, 0x83, 0xcb, 0xfe, 0x47, 0xbd, 0x2b, 0x7e, 0x4f, 0xc5,
- 0x95, 0xae, 0x0e, 0x9d, 0xd4, 0xd1, 0x43, 0xc0, 0x67, 0x73, 0xe3, 0x14,
- 0x08, 0x7e, 0xe5, 0x3f, 0x9f, 0x73, 0xb8, 0x33, 0x0a, 0xcf, 0x5d, 0x3f,
- 0x34, 0x87, 0x96, 0x8a, 0xee, 0x53, 0xe8, 0x25, 0x15, 0x02, 0x03, 0x01,
- 0x00, 0x01, 0xa3, 0x82, 0x01, 0x5b, 0x30, 0x82, 0x01, 0x57, 0x30, 0x0f,
- 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, 0x30, 0x03,
- 0x01, 0x01, 0xff, 0x30, 0x31, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x2a,
- 0x30, 0x28, 0x30, 0x26, 0xa0, 0x24, 0xa0, 0x22, 0x86, 0x20, 0x68, 0x74,
- 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x76, 0x65, 0x72,
- 0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x63,
- 0x61, 0x33, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d,
- 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x3d,
- 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x36, 0x30, 0x34, 0x30, 0x32, 0x06,
- 0x04, 0x55, 0x1d, 0x20, 0x00, 0x30, 0x2a, 0x30, 0x28, 0x06, 0x08, 0x2b,
- 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x1c, 0x68, 0x74, 0x74,
- 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x76, 0x65, 0x72,
- 0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x70,
- 0x73, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14,
- 0x7f, 0xd3, 0x65, 0xa7, 0xc2, 0xdd, 0xec, 0xbb, 0xf0, 0x30, 0x09, 0xf3,
- 0x43, 0x39, 0xfa, 0x02, 0xaf, 0x33, 0x31, 0x33, 0x30, 0x6d, 0x06, 0x08,
- 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x0c, 0x04, 0x61, 0x30, 0x5f,
- 0xa1, 0x5d, 0xa0, 0x5b, 0x30, 0x59, 0x30, 0x57, 0x30, 0x55, 0x16, 0x09,
- 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2f, 0x67, 0x69, 0x66, 0x30, 0x21, 0x30,
- 0x1f, 0x30, 0x07, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x04, 0x14,
- 0x8f, 0xe5, 0xd3, 0x1a, 0x86, 0xac, 0x8d, 0x8e, 0x6b, 0xc3, 0xcf, 0x80,
- 0x6a, 0xd4, 0x48, 0x18, 0x2c, 0x7b, 0x19, 0x2e, 0x30, 0x25, 0x16, 0x23,
- 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6c, 0x6f, 0x67, 0x6f, 0x2e,
- 0x76, 0x65, 0x72, 0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d,
- 0x2f, 0x76, 0x73, 0x6c, 0x6f, 0x67, 0x6f, 0x2e, 0x67, 0x69, 0x66, 0x30,
- 0x34, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04,
- 0x28, 0x30, 0x26, 0x30, 0x24, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05,
- 0x07, 0x30, 0x01, 0x86, 0x18, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f,
- 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x76, 0x65, 0x72, 0x69, 0x73, 0x69, 0x67,
- 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48,
- 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x81, 0x81, 0x00,
- 0xa3, 0xcd, 0x7d, 0x1e, 0xf7, 0xc7, 0x75, 0x8d, 0x48, 0xe7, 0x56, 0x34,
- 0x4c, 0x00, 0x90, 0x75, 0xa9, 0x51, 0xa5, 0x56, 0xc1, 0x6d, 0xbc, 0xfe,
- 0xf5, 0x53, 0x22, 0xe9, 0x98, 0xa2, 0xac, 0x9a, 0x7e, 0x70, 0x1e, 0xb3,
- 0x8e, 0x3b, 0x45, 0xe3, 0x86, 0x95, 0x31, 0xda, 0x6d, 0x4c, 0xfb, 0x34,
- 0x50, 0x80, 0x96, 0xcd, 0x24, 0xf2, 0x40, 0xdf, 0x04, 0x3f, 0xe2, 0x65,
- 0xce, 0x34, 0x22, 0x61, 0x15, 0xea, 0x66, 0x70, 0x64, 0xd2, 0xf1, 0x6e,
- 0xf3, 0xca, 0x18, 0x59, 0x6a, 0x41, 0x46, 0x7e, 0x82, 0xde, 0x19, 0xb0,
- 0x70, 0x31, 0x56, 0x69, 0x0d, 0x0c, 0xe6, 0x1d, 0x9d, 0x71, 0x58, 0xdc,
- 0xcc, 0xde, 0x62, 0xf5, 0xe1, 0x7a, 0x10, 0x02, 0xd8, 0x7a, 0xdc, 0x3b,
- 0xfa, 0x57, 0xbd, 0xc9, 0xe9, 0x8f, 0x46, 0x21, 0x39, 0x9f, 0x51, 0x65,
- 0x4c, 0x8e, 0x3a, 0xbe, 0x28, 0x41, 0x70, 0x1d,
-};
-
-#if 0
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number:
- 0a:01:41:42:00:00:01:53:85:73:6a:0b:85:ec:a7:08
- Signature Algorithm: sha256WithRSAEncryption
- Issuer: O=Digital Signature Trust Co., CN=DST Root CA X3
- Validity
- Not Before: Mar 17 16:40:46 2016 GMT
- Not After : Mar 17 16:40:46 2021 GMT
- Subject: C=US, O=Let's Encrypt, CN=Let's Encrypt Authority X3
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:9c:d3:0c:f0:5a:e5:2e:47:b7:72:5d:37:83:b3:
- 68:63:30:ea:d7:35:26:19:25:e1:bd:be:35:f1:70:
- 92:2f:b7:b8:4b:41:05:ab:a9:9e:35:08:58:ec:b1:
- 2a:c4:68:87:0b:a3:e3:75:e4:e6:f3:a7:62:71:ba:
- 79:81:60:1f:d7:91:9a:9f:f3:d0:78:67:71:c8:69:
- 0e:95:91:cf:fe:e6:99:e9:60:3c:48:cc:7e:ca:4d:
- 77:12:24:9d:47:1b:5a:eb:b9:ec:1e:37:00:1c:9c:
- ac:7b:a7:05:ea:ce:4a:eb:bd:41:e5:36:98:b9:cb:
- fd:6d:3c:96:68:df:23:2a:42:90:0c:86:74:67:c8:
- 7f:a5:9a:b8:52:61:14:13:3f:65:e9:82:87:cb:db:
- fa:0e:56:f6:86:89:f3:85:3f:97:86:af:b0:dc:1a:
- ef:6b:0d:95:16:7d:c4:2b:a0:65:b2:99:04:36:75:
- 80:6b:ac:4a:f3:1b:90:49:78:2f:a2:96:4f:2a:20:
- 25:29:04:c6:74:c0:d0:31:cd:8f:31:38:95:16:ba:
- a8:33:b8:43:f1:b1:1f:c3:30:7f:a2:79:31:13:3d:
- 2d:36:f8:e3:fc:f2:33:6a:b9:39:31:c5:af:c4:8d:
- 0d:1d:64:16:33:aa:fa:84:29:b6:d4:0b:c0:d8:7d:
- c3:93
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Basic Constraints: critical
- CA:TRUE, pathlen:0
- X509v3 Key Usage: critical
- Digital Signature, Certificate Sign, CRL Sign
- Authority Information Access:
- OCSP - URI:http://isrg.trustid.ocsp.identrust.com
- CA Issuers - URI:http://apps.identrust.com/roots/dstrootcax3.p7c
-
- X509v3 Authority Key Identifier:
- keyid:C4:A7:B1:A4:7B:2C:71:FA:DB:E1:4B:90:75:FF:C4:15:60:85:89:10
-
- X509v3 Certificate Policies:
- Policy: 2.23.140.1.2.1
- Policy: 1.3.6.1.4.1.44947.1.1.1
- CPS: http://cps.root-x1.letsencrypt.org
-
- X509v3 CRL Distribution Points:
-
- Full Name:
- URI:http://crl.identrust.com/DSTROOTCAX3CRL.crl
-
- X509v3 Subject Key Identifier:
- A8:4A:6A:63:04:7D:DD:BA:E6:D1:39:B7:A6:45:65:EF:F3:A8:EC:A1
- Signature Algorithm: sha256WithRSAEncryption
- dd:33:d7:11:f3:63:58:38:dd:18:15:fb:09:55:be:76:56:b9:
- 70:48:a5:69:47:27:7b:c2:24:08:92:f1:5a:1f:4a:12:29:37:
- 24:74:51:1c:62:68:b8:cd:95:70:67:e5:f7:a4:bc:4e:28:51:
- cd:9b:e8:ae:87:9d:ea:d8:ba:5a:a1:01:9a:dc:f0:dd:6a:1d:
- 6a:d8:3e:57:23:9e:a6:1e:04:62:9a:ff:d7:05:ca:b7:1f:3f:
- c0:0a:48:bc:94:b0:b6:65:62:e0:c1:54:e5:a3:2a:ad:20:c4:
- e9:e6:bb:dc:c8:f6:b5:c3:32:a3:98:cc:77:a8:e6:79:65:07:
- 2b:cb:28:fe:3a:16:52:81:ce:52:0c:2e:5f:83:e8:d5:06:33:
- fb:77:6c:ce:40:ea:32:9e:1f:92:5c:41:c1:74:6c:5b:5d:0a:
- 5f:33:cc:4d:9f:ac:38:f0:2f:7b:2c:62:9d:d9:a3:91:6f:25:
- 1b:2f:90:b1:19:46:3d:f6:7e:1b:a6:7a:87:b9:a3:7a:6d:18:
- fa:25:a5:91:87:15:e0:f2:16:2f:58:b0:06:2f:2c:68:26:c6:
- 4b:98:cd:da:9f:0c:f9:7f:90:ed:43:4a:12:44:4e:6f:73:7a:
- 28:ea:a4:aa:6e:7b:4c:7d:87:dd:e0:c9:02:44:a7:87:af:c3:
- 34:5b:b4:42
------BEGIN CERTIFICATE-----
-MIIEkjCCA3qgAwIBAgIQCgFBQgAAAVOFc2oLheynCDANBgkqhkiG9w0BAQsFADA/
-MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT
-DkRTVCBSb290IENBIFgzMB4XDTE2MDMxNzE2NDA0NloXDTIxMDMxNzE2NDA0Nlow
-SjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUxldCdzIEVuY3J5cHQxIzAhBgNVBAMT
-GkxldCdzIEVuY3J5cHQgQXV0aG9yaXR5IFgzMIIBIjANBgkqhkiG9w0BAQEFAAOC
-AQ8AMIIBCgKCAQEAnNMM8FrlLke3cl03g7NoYzDq1zUmGSXhvb418XCSL7e4S0EF
-q6meNQhY7LEqxGiHC6PjdeTm86dicbp5gWAf15Gan/PQeGdxyGkOlZHP/uaZ6WA8
-SMx+yk13EiSdRxta67nsHjcAHJyse6cF6s5K671B5TaYucv9bTyWaN8jKkKQDIZ0
-Z8h/pZq4UmEUEz9l6YKHy9v6Dlb2honzhT+Xhq+w3Brvaw2VFn3EK6BlspkENnWA
-a6xK8xuQSXgvopZPKiAlKQTGdMDQMc2PMTiVFrqoM7hD8bEfwzB/onkxEz0tNvjj
-/PIzark5McWvxI0NHWQWM6r6hCm21AvA2H3DkwIDAQABo4IBfTCCAXkwEgYDVR0T
-AQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAYYwfwYIKwYBBQUHAQEEczBxMDIG
-CCsGAQUFBzABhiZodHRwOi8vaXNyZy50cnVzdGlkLm9jc3AuaWRlbnRydXN0LmNv
-bTA7BggrBgEFBQcwAoYvaHR0cDovL2FwcHMuaWRlbnRydXN0LmNvbS9yb290cy9k
-c3Ryb290Y2F4My5wN2MwHwYDVR0jBBgwFoAUxKexpHsscfrb4UuQdf/EFWCFiRAw
-VAYDVR0gBE0wSzAIBgZngQwBAgEwPwYLKwYBBAGC3xMBAQEwMDAuBggrBgEFBQcC
-ARYiaHR0cDovL2Nwcy5yb290LXgxLmxldHNlbmNyeXB0Lm9yZzA8BgNVHR8ENTAz
-MDGgL6AthitodHRwOi8vY3JsLmlkZW50cnVzdC5jb20vRFNUUk9PVENBWDNDUkwu
-Y3JsMB0GA1UdDgQWBBSoSmpjBH3duubRObemRWXv86jsoTANBgkqhkiG9w0BAQsF
-AAOCAQEA3TPXEfNjWDjdGBX7CVW+dla5cEilaUcne8IkCJLxWh9KEik3JHRRHGJo
-uM2VcGfl96S8TihRzZvoroed6ti6WqEBmtzw3Wodatg+VyOeph4EYpr/1wXKtx8/
-wApIvJSwtmVi4MFU5aMqrSDE6ea73Mj2tcMyo5jMd6jmeWUHK8so/joWUoHOUgwu
-X4Po1QYz+3dszkDqMp4fklxBwXRsW10KXzPMTZ+sOPAveyxindmjkW8lGy+QsRlG
-PfZ+G6Z6h7mjem0Y+iWlkYcV4PIWL1iwBi8saCbGS5jN2p8M+X+Q7UNKEkROb3N6
-KOqkqm57TH2H3eDJAkSnh6/DNFu0Qg==
------END CERTIFICATE-----
-#endif
-static const unsigned char kDERCert22[] = {
- 0x30, 0x82, 0x04, 0x92, 0x30, 0x82, 0x03, 0x7a, 0xa0, 0x03, 0x02, 0x01,
- 0x02, 0x02, 0x10, 0x0a, 0x01, 0x41, 0x42, 0x00, 0x00, 0x01, 0x53, 0x85,
- 0x73, 0x6a, 0x0b, 0x85, 0xec, 0xa7, 0x08, 0x30, 0x0d, 0x06, 0x09, 0x2a,
- 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x3f,
- 0x31, 0x24, 0x30, 0x22, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x1b, 0x44,
- 0x69, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x20, 0x53, 0x69, 0x67, 0x6e, 0x61,
- 0x74, 0x75, 0x72, 0x65, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x43,
- 0x6f, 0x2e, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
- 0x0e, 0x44, 0x53, 0x54, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41,
- 0x20, 0x58, 0x33, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x36, 0x30, 0x33, 0x31,
- 0x37, 0x31, 0x36, 0x34, 0x30, 0x34, 0x36, 0x5a, 0x17, 0x0d, 0x32, 0x31,
- 0x30, 0x33, 0x31, 0x37, 0x31, 0x36, 0x34, 0x30, 0x34, 0x36, 0x5a, 0x30,
- 0x4a, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
- 0x55, 0x53, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13,
- 0x0d, 0x4c, 0x65, 0x74, 0x27, 0x73, 0x20, 0x45, 0x6e, 0x63, 0x72, 0x79,
- 0x70, 0x74, 0x31, 0x23, 0x30, 0x21, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
- 0x1a, 0x4c, 0x65, 0x74, 0x27, 0x73, 0x20, 0x45, 0x6e, 0x63, 0x72, 0x79,
- 0x70, 0x74, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79,
- 0x20, 0x58, 0x33, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a,
- 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82,
- 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00,
- 0x9c, 0xd3, 0x0c, 0xf0, 0x5a, 0xe5, 0x2e, 0x47, 0xb7, 0x72, 0x5d, 0x37,
- 0x83, 0xb3, 0x68, 0x63, 0x30, 0xea, 0xd7, 0x35, 0x26, 0x19, 0x25, 0xe1,
- 0xbd, 0xbe, 0x35, 0xf1, 0x70, 0x92, 0x2f, 0xb7, 0xb8, 0x4b, 0x41, 0x05,
- 0xab, 0xa9, 0x9e, 0x35, 0x08, 0x58, 0xec, 0xb1, 0x2a, 0xc4, 0x68, 0x87,
- 0x0b, 0xa3, 0xe3, 0x75, 0xe4, 0xe6, 0xf3, 0xa7, 0x62, 0x71, 0xba, 0x79,
- 0x81, 0x60, 0x1f, 0xd7, 0x91, 0x9a, 0x9f, 0xf3, 0xd0, 0x78, 0x67, 0x71,
- 0xc8, 0x69, 0x0e, 0x95, 0x91, 0xcf, 0xfe, 0xe6, 0x99, 0xe9, 0x60, 0x3c,
- 0x48, 0xcc, 0x7e, 0xca, 0x4d, 0x77, 0x12, 0x24, 0x9d, 0x47, 0x1b, 0x5a,
- 0xeb, 0xb9, 0xec, 0x1e, 0x37, 0x00, 0x1c, 0x9c, 0xac, 0x7b, 0xa7, 0x05,
- 0xea, 0xce, 0x4a, 0xeb, 0xbd, 0x41, 0xe5, 0x36, 0x98, 0xb9, 0xcb, 0xfd,
- 0x6d, 0x3c, 0x96, 0x68, 0xdf, 0x23, 0x2a, 0x42, 0x90, 0x0c, 0x86, 0x74,
- 0x67, 0xc8, 0x7f, 0xa5, 0x9a, 0xb8, 0x52, 0x61, 0x14, 0x13, 0x3f, 0x65,
- 0xe9, 0x82, 0x87, 0xcb, 0xdb, 0xfa, 0x0e, 0x56, 0xf6, 0x86, 0x89, 0xf3,
- 0x85, 0x3f, 0x97, 0x86, 0xaf, 0xb0, 0xdc, 0x1a, 0xef, 0x6b, 0x0d, 0x95,
- 0x16, 0x7d, 0xc4, 0x2b, 0xa0, 0x65, 0xb2, 0x99, 0x04, 0x36, 0x75, 0x80,
- 0x6b, 0xac, 0x4a, 0xf3, 0x1b, 0x90, 0x49, 0x78, 0x2f, 0xa2, 0x96, 0x4f,
- 0x2a, 0x20, 0x25, 0x29, 0x04, 0xc6, 0x74, 0xc0, 0xd0, 0x31, 0xcd, 0x8f,
- 0x31, 0x38, 0x95, 0x16, 0xba, 0xa8, 0x33, 0xb8, 0x43, 0xf1, 0xb1, 0x1f,
- 0xc3, 0x30, 0x7f, 0xa2, 0x79, 0x31, 0x13, 0x3d, 0x2d, 0x36, 0xf8, 0xe3,
- 0xfc, 0xf2, 0x33, 0x6a, 0xb9, 0x39, 0x31, 0xc5, 0xaf, 0xc4, 0x8d, 0x0d,
- 0x1d, 0x64, 0x16, 0x33, 0xaa, 0xfa, 0x84, 0x29, 0xb6, 0xd4, 0x0b, 0xc0,
- 0xd8, 0x7d, 0xc3, 0x93, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01,
- 0x7d, 0x30, 0x82, 0x01, 0x79, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13,
- 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01,
- 0x00, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04,
- 0x04, 0x03, 0x02, 0x01, 0x86, 0x30, 0x7f, 0x06, 0x08, 0x2b, 0x06, 0x01,
- 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x73, 0x30, 0x71, 0x30, 0x32, 0x06,
- 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x26, 0x68,
- 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x69, 0x73, 0x72, 0x67, 0x2e, 0x74,
- 0x72, 0x75, 0x73, 0x74, 0x69, 0x64, 0x2e, 0x6f, 0x63, 0x73, 0x70, 0x2e,
- 0x69, 0x64, 0x65, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63, 0x6f,
- 0x6d, 0x30, 0x3b, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30,
- 0x02, 0x86, 0x2f, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x61, 0x70,
- 0x70, 0x73, 0x2e, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74,
- 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x6f, 0x6f, 0x74, 0x73, 0x2f, 0x64,
- 0x73, 0x74, 0x72, 0x6f, 0x6f, 0x74, 0x63, 0x61, 0x78, 0x33, 0x2e, 0x70,
- 0x37, 0x63, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30,
- 0x16, 0x80, 0x14, 0xc4, 0xa7, 0xb1, 0xa4, 0x7b, 0x2c, 0x71, 0xfa, 0xdb,
- 0xe1, 0x4b, 0x90, 0x75, 0xff, 0xc4, 0x15, 0x60, 0x85, 0x89, 0x10, 0x30,
- 0x54, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x4d, 0x30, 0x4b, 0x30, 0x08,
- 0x06, 0x06, 0x67, 0x81, 0x0c, 0x01, 0x02, 0x01, 0x30, 0x3f, 0x06, 0x0b,
- 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0xdf, 0x13, 0x01, 0x01, 0x01, 0x30,
- 0x30, 0x30, 0x2e, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02,
- 0x01, 0x16, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x70,
- 0x73, 0x2e, 0x72, 0x6f, 0x6f, 0x74, 0x2d, 0x78, 0x31, 0x2e, 0x6c, 0x65,
- 0x74, 0x73, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x2e, 0x6f, 0x72,
- 0x67, 0x30, 0x3c, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x35, 0x30, 0x33,
- 0x30, 0x31, 0xa0, 0x2f, 0xa0, 0x2d, 0x86, 0x2b, 0x68, 0x74, 0x74, 0x70,
- 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x69, 0x64, 0x65, 0x6e, 0x74,
- 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x44, 0x53, 0x54,
- 0x52, 0x4f, 0x4f, 0x54, 0x43, 0x41, 0x58, 0x33, 0x43, 0x52, 0x4c, 0x2e,
- 0x63, 0x72, 0x6c, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16,
- 0x04, 0x14, 0xa8, 0x4a, 0x6a, 0x63, 0x04, 0x7d, 0xdd, 0xba, 0xe6, 0xd1,
- 0x39, 0xb7, 0xa6, 0x45, 0x65, 0xef, 0xf3, 0xa8, 0xec, 0xa1, 0x30, 0x0d,
- 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05,
- 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0xdd, 0x33, 0xd7, 0x11, 0xf3, 0x63,
- 0x58, 0x38, 0xdd, 0x18, 0x15, 0xfb, 0x09, 0x55, 0xbe, 0x76, 0x56, 0xb9,
- 0x70, 0x48, 0xa5, 0x69, 0x47, 0x27, 0x7b, 0xc2, 0x24, 0x08, 0x92, 0xf1,
- 0x5a, 0x1f, 0x4a, 0x12, 0x29, 0x37, 0x24, 0x74, 0x51, 0x1c, 0x62, 0x68,
- 0xb8, 0xcd, 0x95, 0x70, 0x67, 0xe5, 0xf7, 0xa4, 0xbc, 0x4e, 0x28, 0x51,
- 0xcd, 0x9b, 0xe8, 0xae, 0x87, 0x9d, 0xea, 0xd8, 0xba, 0x5a, 0xa1, 0x01,
- 0x9a, 0xdc, 0xf0, 0xdd, 0x6a, 0x1d, 0x6a, 0xd8, 0x3e, 0x57, 0x23, 0x9e,
- 0xa6, 0x1e, 0x04, 0x62, 0x9a, 0xff, 0xd7, 0x05, 0xca, 0xb7, 0x1f, 0x3f,
- 0xc0, 0x0a, 0x48, 0xbc, 0x94, 0xb0, 0xb6, 0x65, 0x62, 0xe0, 0xc1, 0x54,
- 0xe5, 0xa3, 0x2a, 0xad, 0x20, 0xc4, 0xe9, 0xe6, 0xbb, 0xdc, 0xc8, 0xf6,
- 0xb5, 0xc3, 0x32, 0xa3, 0x98, 0xcc, 0x77, 0xa8, 0xe6, 0x79, 0x65, 0x07,
- 0x2b, 0xcb, 0x28, 0xfe, 0x3a, 0x16, 0x52, 0x81, 0xce, 0x52, 0x0c, 0x2e,
- 0x5f, 0x83, 0xe8, 0xd5, 0x06, 0x33, 0xfb, 0x77, 0x6c, 0xce, 0x40, 0xea,
- 0x32, 0x9e, 0x1f, 0x92, 0x5c, 0x41, 0xc1, 0x74, 0x6c, 0x5b, 0x5d, 0x0a,
- 0x5f, 0x33, 0xcc, 0x4d, 0x9f, 0xac, 0x38, 0xf0, 0x2f, 0x7b, 0x2c, 0x62,
- 0x9d, 0xd9, 0xa3, 0x91, 0x6f, 0x25, 0x1b, 0x2f, 0x90, 0xb1, 0x19, 0x46,
- 0x3d, 0xf6, 0x7e, 0x1b, 0xa6, 0x7a, 0x87, 0xb9, 0xa3, 0x7a, 0x6d, 0x18,
- 0xfa, 0x25, 0xa5, 0x91, 0x87, 0x15, 0xe0, 0xf2, 0x16, 0x2f, 0x58, 0xb0,
- 0x06, 0x2f, 0x2c, 0x68, 0x26, 0xc6, 0x4b, 0x98, 0xcd, 0xda, 0x9f, 0x0c,
- 0xf9, 0x7f, 0x90, 0xed, 0x43, 0x4a, 0x12, 0x44, 0x4e, 0x6f, 0x73, 0x7a,
- 0x28, 0xea, 0xa4, 0xaa, 0x6e, 0x7b, 0x4c, 0x7d, 0x87, 0xdd, 0xe0, 0xc9,
- 0x02, 0x44, 0xa7, 0x87, 0xaf, 0xc3, 0x34, 0x5b, 0xb4, 0x42,
-};
-
-#if 0
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number:
- 06:7f:94:4a:2a:27:cd:f3:fa:c2:ae:2b:01:f9:08:ee:b9:c4:c6
- Signature Algorithm: sha256WithRSAEncryption
- Issuer: C=US, ST=Arizona, L=Scottsdale, O=Starfield Technologies, Inc., CN=Starfield Services Root Certificate Authority - G2
- Validity
- Not Before: May 25 12:00:00 2015 GMT
- Not After : Dec 31 01:00:00 2037 GMT
- Subject: C=US, O=Amazon, CN=Amazon Root CA 1
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:b2:78:80:71:ca:78:d5:e3:71:af:47:80:50:74:
- 7d:6e:d8:d7:88:76:f4:99:68:f7:58:21:60:f9:74:
- 84:01:2f:ac:02:2d:86:d3:a0:43:7a:4e:b2:a4:d0:
- 36:ba:01:be:8d:db:48:c8:07:17:36:4c:f4:ee:88:
- 23:c7:3e:eb:37:f5:b5:19:f8:49:68:b0:de:d7:b9:
- 76:38:1d:61:9e:a4:fe:82:36:a5:e5:4a:56:e4:45:
- e1:f9:fd:b4:16:fa:74:da:9c:9b:35:39:2f:fa:b0:
- 20:50:06:6c:7a:d0:80:b2:a6:f9:af:ec:47:19:8f:
- 50:38:07:dc:a2:87:39:58:f8:ba:d5:a9:f9:48:67:
- 30:96:ee:94:78:5e:6f:89:a3:51:c0:30:86:66:a1:
- 45:66:ba:54:eb:a3:c3:91:f9:48:dc:ff:d1:e8:30:
- 2d:7d:2d:74:70:35:d7:88:24:f7:9e:c4:59:6e:bb:
- 73:87:17:f2:32:46:28:b8:43:fa:b7:1d:aa:ca:b4:
- f2:9f:24:0e:2d:4b:f7:71:5c:5e:69:ff:ea:95:02:
- cb:38:8a:ae:50:38:6f:db:fb:2d:62:1b:c5:c7:1e:
- 54:e1:77:e0:67:c8:0f:9c:87:23:d6:3f:40:20:7f:
- 20:80:c4:80:4c:3e:3b:24:26:8e:04:ae:6c:9a:c8:
- aa:0d
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Basic Constraints: critical
- CA:TRUE
- X509v3 Key Usage: critical
- Digital Signature, Certificate Sign, CRL Sign
- X509v3 Subject Key Identifier:
- 84:18:CC:85:34:EC:BC:0C:94:94:2E:08:59:9C:C7:B2:10:4E:0A:08
- X509v3 Authority Key Identifier:
- keyid:9C:5F:00:DF:AA:01:D7:30:2B:38:88:A2:B8:6D:4A:9C:F2:11:91:83
-
- Authority Information Access:
- OCSP - URI:http://ocsp.rootg2.amazontrust.com
- CA Issuers - URI:http://crt.rootg2.amazontrust.com/rootg2.cer
-
- X509v3 CRL Distribution Points:
-
- Full Name:
- URI:http://crl.rootg2.amazontrust.com/rootg2.crl
-
- X509v3 Certificate Policies:
- Policy: X509v3 Any Policy
-
- Signature Algorithm: sha256WithRSAEncryption
- 62:37:42:5c:bc:10:b5:3e:8b:2c:e9:0c:9b:6c:45:e2:07:00:
- 7a:f9:c5:58:0b:b9:08:8c:3e:ed:b3:25:3c:b5:6f:50:e4:cd:
- 35:6a:a7:93:34:96:32:21:a9:48:44:ab:9c:ed:3d:b4:aa:73:
- 6d:e4:7f:16:80:89:6c:cf:28:03:18:83:47:79:a3:10:7e:30:
- 5b:ac:3b:b0:60:e0:77:d4:08:a6:e1:1d:7c:5e:c0:bb:f9:9a:
- 7b:22:9d:a7:00:09:7e:ac:46:17:83:dc:9c:26:57:99:30:39:
- 62:96:8f:ed:da:de:aa:c5:cc:1b:3e:ca:43:68:6c:57:16:bc:
- d5:0e:20:2e:fe:ff:c2:6a:5d:2e:a0:4a:6d:14:58:87:94:e6:
- 39:31:5f:7c:73:cb:90:88:6a:84:11:96:27:a6:ed:d9:81:46:
- a6:7e:a3:72:00:0a:52:3e:83:88:07:63:77:89:69:17:0f:39:
- 85:d2:ab:08:45:4d:d0:51:3a:fd:5d:5d:37:64:4c:7e:30:b2:
- 55:24:42:9d:36:b0:5d:9c:17:81:61:f1:ca:f9:10:02:24:ab:
- eb:0d:74:91:8d:7b:45:29:50:39:88:b2:a6:89:35:25:1e:14:
- 6a:47:23:31:2f:5c:9a:fa:ad:9a:0e:62:51:a4:2a:a9:c4:f9:
- 34:9d:21:18
------BEGIN CERTIFICATE-----
-MIIEkjCCA3qgAwIBAgITBn+USionzfP6wq4rAfkI7rnExjANBgkqhkiG9w0BAQsF
-ADCBmDELMAkGA1UEBhMCVVMxEDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNj
-b3R0c2RhbGUxJTAjBgNVBAoTHFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4x
-OzA5BgNVBAMTMlN0YXJmaWVsZCBTZXJ2aWNlcyBSb290IENlcnRpZmljYXRlIEF1
-dGhvcml0eSAtIEcyMB4XDTE1MDUyNTEyMDAwMFoXDTM3MTIzMTAxMDAwMFowOTEL
-MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJv
-b3QgQ0EgMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALJ4gHHKeNXj
-ca9HgFB0fW7Y14h29Jlo91ghYPl0hAEvrAIthtOgQ3pOsqTQNroBvo3bSMgHFzZM
-9O6II8c+6zf1tRn4SWiw3te5djgdYZ6k/oI2peVKVuRF4fn9tBb6dNqcmzU5L/qw
-IFAGbHrQgLKm+a/sRxmPUDgH3KKHOVj4utWp+UhnMJbulHheb4mjUcAwhmahRWa6
-VOujw5H5SNz/0egwLX0tdHA114gk957EWW67c4cX8jJGKLhD+rcdqsq08p8kDi1L
-93FcXmn/6pUCyziKrlA4b9v7LWIbxcceVOF34GfID5yHI9Y/QCB/IIDEgEw+OyQm
-jgSubJrIqg0CAwEAAaOCATEwggEtMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/
-BAQDAgGGMB0GA1UdDgQWBBSEGMyFNOy8DJSULghZnMeyEE4KCDAfBgNVHSMEGDAW
-gBScXwDfqgHXMCs4iKK4bUqc8hGRgzB4BggrBgEFBQcBAQRsMGowLgYIKwYBBQUH
-MAGGImh0dHA6Ly9vY3NwLnJvb3RnMi5hbWF6b250cnVzdC5jb20wOAYIKwYBBQUH
-MAKGLGh0dHA6Ly9jcnQucm9vdGcyLmFtYXpvbnRydXN0LmNvbS9yb290ZzIuY2Vy
-MD0GA1UdHwQ2MDQwMqAwoC6GLGh0dHA6Ly9jcmwucm9vdGcyLmFtYXpvbnRydXN0
-LmNvbS9yb290ZzIuY3JsMBEGA1UdIAQKMAgwBgYEVR0gADANBgkqhkiG9w0BAQsF
-AAOCAQEAYjdCXLwQtT6LLOkMm2xF4gcAevnFWAu5CIw+7bMlPLVvUOTNNWqnkzSW
-MiGpSESrnO09tKpzbeR/FoCJbM8oAxiDR3mjEH4wW6w7sGDgd9QIpuEdfF7Au/ma
-eyKdpwAJfqxGF4PcnCZXmTA5YpaP7dreqsXMGz7KQ2hsVxa81Q4gLv7/wmpdLqBK
-bRRYh5TmOTFffHPLkIhqhBGWJ6bt2YFGpn6jcgAKUj6DiAdjd4lpFw85hdKrCEVN
-0FE6/V1dN2RMfjCyVSRCnTawXZwXgWHxyvkQAiSr6w10kY17RSlQOYiypok1JR4U
-akcjMS9cmvqtmg5iUaQqqcT5NJ0hGA==
------END CERTIFICATE-----
-#endif
-static const unsigned char kDERCert23[] = {
- 0x30, 0x82, 0x04, 0x92, 0x30, 0x82, 0x03, 0x7a, 0xa0, 0x03, 0x02, 0x01,
- 0x02, 0x02, 0x13, 0x06, 0x7f, 0x94, 0x4a, 0x2a, 0x27, 0xcd, 0xf3, 0xfa,
- 0xc2, 0xae, 0x2b, 0x01, 0xf9, 0x08, 0xee, 0xb9, 0xc4, 0xc6, 0x30, 0x0d,
- 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05,
- 0x00, 0x30, 0x81, 0x98, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04,
- 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55,
- 0x04, 0x08, 0x13, 0x07, 0x41, 0x72, 0x69, 0x7a, 0x6f, 0x6e, 0x61, 0x31,
- 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x0a, 0x53, 0x63,
- 0x6f, 0x74, 0x74, 0x73, 0x64, 0x61, 0x6c, 0x65, 0x31, 0x25, 0x30, 0x23,
- 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x1c, 0x53, 0x74, 0x61, 0x72, 0x66,
- 0x69, 0x65, 0x6c, 0x64, 0x20, 0x54, 0x65, 0x63, 0x68, 0x6e, 0x6f, 0x6c,
- 0x6f, 0x67, 0x69, 0x65, 0x73, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31,
- 0x3b, 0x30, 0x39, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x32, 0x53, 0x74,
- 0x61, 0x72, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x20, 0x53, 0x65, 0x72, 0x76,
- 0x69, 0x63, 0x65, 0x73, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x65,
- 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75,
- 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x20, 0x2d, 0x20, 0x47, 0x32,
- 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x35, 0x30, 0x35, 0x32, 0x35, 0x31, 0x32,
- 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x33, 0x37, 0x31, 0x32, 0x33,
- 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x39, 0x31, 0x0b,
- 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31,
- 0x0f, 0x30, 0x0d, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x06, 0x41, 0x6d,
- 0x61, 0x7a, 0x6f, 0x6e, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04,
- 0x03, 0x13, 0x10, 0x41, 0x6d, 0x61, 0x7a, 0x6f, 0x6e, 0x20, 0x52, 0x6f,
- 0x6f, 0x74, 0x20, 0x43, 0x41, 0x20, 0x31, 0x30, 0x82, 0x01, 0x22, 0x30,
- 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01,
- 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02,
- 0x82, 0x01, 0x01, 0x00, 0xb2, 0x78, 0x80, 0x71, 0xca, 0x78, 0xd5, 0xe3,
- 0x71, 0xaf, 0x47, 0x80, 0x50, 0x74, 0x7d, 0x6e, 0xd8, 0xd7, 0x88, 0x76,
- 0xf4, 0x99, 0x68, 0xf7, 0x58, 0x21, 0x60, 0xf9, 0x74, 0x84, 0x01, 0x2f,
- 0xac, 0x02, 0x2d, 0x86, 0xd3, 0xa0, 0x43, 0x7a, 0x4e, 0xb2, 0xa4, 0xd0,
- 0x36, 0xba, 0x01, 0xbe, 0x8d, 0xdb, 0x48, 0xc8, 0x07, 0x17, 0x36, 0x4c,
- 0xf4, 0xee, 0x88, 0x23, 0xc7, 0x3e, 0xeb, 0x37, 0xf5, 0xb5, 0x19, 0xf8,
- 0x49, 0x68, 0xb0, 0xde, 0xd7, 0xb9, 0x76, 0x38, 0x1d, 0x61, 0x9e, 0xa4,
- 0xfe, 0x82, 0x36, 0xa5, 0xe5, 0x4a, 0x56, 0xe4, 0x45, 0xe1, 0xf9, 0xfd,
- 0xb4, 0x16, 0xfa, 0x74, 0xda, 0x9c, 0x9b, 0x35, 0x39, 0x2f, 0xfa, 0xb0,
- 0x20, 0x50, 0x06, 0x6c, 0x7a, 0xd0, 0x80, 0xb2, 0xa6, 0xf9, 0xaf, 0xec,
- 0x47, 0x19, 0x8f, 0x50, 0x38, 0x07, 0xdc, 0xa2, 0x87, 0x39, 0x58, 0xf8,
- 0xba, 0xd5, 0xa9, 0xf9, 0x48, 0x67, 0x30, 0x96, 0xee, 0x94, 0x78, 0x5e,
- 0x6f, 0x89, 0xa3, 0x51, 0xc0, 0x30, 0x86, 0x66, 0xa1, 0x45, 0x66, 0xba,
- 0x54, 0xeb, 0xa3, 0xc3, 0x91, 0xf9, 0x48, 0xdc, 0xff, 0xd1, 0xe8, 0x30,
- 0x2d, 0x7d, 0x2d, 0x74, 0x70, 0x35, 0xd7, 0x88, 0x24, 0xf7, 0x9e, 0xc4,
- 0x59, 0x6e, 0xbb, 0x73, 0x87, 0x17, 0xf2, 0x32, 0x46, 0x28, 0xb8, 0x43,
- 0xfa, 0xb7, 0x1d, 0xaa, 0xca, 0xb4, 0xf2, 0x9f, 0x24, 0x0e, 0x2d, 0x4b,
- 0xf7, 0x71, 0x5c, 0x5e, 0x69, 0xff, 0xea, 0x95, 0x02, 0xcb, 0x38, 0x8a,
- 0xae, 0x50, 0x38, 0x6f, 0xdb, 0xfb, 0x2d, 0x62, 0x1b, 0xc5, 0xc7, 0x1e,
- 0x54, 0xe1, 0x77, 0xe0, 0x67, 0xc8, 0x0f, 0x9c, 0x87, 0x23, 0xd6, 0x3f,
- 0x40, 0x20, 0x7f, 0x20, 0x80, 0xc4, 0x80, 0x4c, 0x3e, 0x3b, 0x24, 0x26,
- 0x8e, 0x04, 0xae, 0x6c, 0x9a, 0xc8, 0xaa, 0x0d, 0x02, 0x03, 0x01, 0x00,
- 0x01, 0xa3, 0x82, 0x01, 0x31, 0x30, 0x82, 0x01, 0x2d, 0x30, 0x0f, 0x06,
- 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, 0x30, 0x03, 0x01,
- 0x01, 0xff, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff,
- 0x04, 0x04, 0x03, 0x02, 0x01, 0x86, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d,
- 0x0e, 0x04, 0x16, 0x04, 0x14, 0x84, 0x18, 0xcc, 0x85, 0x34, 0xec, 0xbc,
- 0x0c, 0x94, 0x94, 0x2e, 0x08, 0x59, 0x9c, 0xc7, 0xb2, 0x10, 0x4e, 0x0a,
- 0x08, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16,
- 0x80, 0x14, 0x9c, 0x5f, 0x00, 0xdf, 0xaa, 0x01, 0xd7, 0x30, 0x2b, 0x38,
- 0x88, 0xa2, 0xb8, 0x6d, 0x4a, 0x9c, 0xf2, 0x11, 0x91, 0x83, 0x30, 0x78,
- 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x6c,
- 0x30, 0x6a, 0x30, 0x2e, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
- 0x30, 0x01, 0x86, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f,
- 0x63, 0x73, 0x70, 0x2e, 0x72, 0x6f, 0x6f, 0x74, 0x67, 0x32, 0x2e, 0x61,
- 0x6d, 0x61, 0x7a, 0x6f, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63,
- 0x6f, 0x6d, 0x30, 0x38, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
- 0x30, 0x02, 0x86, 0x2c, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63,
- 0x72, 0x74, 0x2e, 0x72, 0x6f, 0x6f, 0x74, 0x67, 0x32, 0x2e, 0x61, 0x6d,
- 0x61, 0x7a, 0x6f, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63, 0x6f,
- 0x6d, 0x2f, 0x72, 0x6f, 0x6f, 0x74, 0x67, 0x32, 0x2e, 0x63, 0x65, 0x72,
- 0x30, 0x3d, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x36, 0x30, 0x34, 0x30,
- 0x32, 0xa0, 0x30, 0xa0, 0x2e, 0x86, 0x2c, 0x68, 0x74, 0x74, 0x70, 0x3a,
- 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x72, 0x6f, 0x6f, 0x74, 0x67, 0x32,
- 0x2e, 0x61, 0x6d, 0x61, 0x7a, 0x6f, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74,
- 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x6f, 0x6f, 0x74, 0x67, 0x32, 0x2e,
- 0x63, 0x72, 0x6c, 0x30, 0x11, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x0a,
- 0x30, 0x08, 0x30, 0x06, 0x06, 0x04, 0x55, 0x1d, 0x20, 0x00, 0x30, 0x0d,
- 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05,
- 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x62, 0x37, 0x42, 0x5c, 0xbc, 0x10,
- 0xb5, 0x3e, 0x8b, 0x2c, 0xe9, 0x0c, 0x9b, 0x6c, 0x45, 0xe2, 0x07, 0x00,
- 0x7a, 0xf9, 0xc5, 0x58, 0x0b, 0xb9, 0x08, 0x8c, 0x3e, 0xed, 0xb3, 0x25,
- 0x3c, 0xb5, 0x6f, 0x50, 0xe4, 0xcd, 0x35, 0x6a, 0xa7, 0x93, 0x34, 0x96,
- 0x32, 0x21, 0xa9, 0x48, 0x44, 0xab, 0x9c, 0xed, 0x3d, 0xb4, 0xaa, 0x73,
- 0x6d, 0xe4, 0x7f, 0x16, 0x80, 0x89, 0x6c, 0xcf, 0x28, 0x03, 0x18, 0x83,
- 0x47, 0x79, 0xa3, 0x10, 0x7e, 0x30, 0x5b, 0xac, 0x3b, 0xb0, 0x60, 0xe0,
- 0x77, 0xd4, 0x08, 0xa6, 0xe1, 0x1d, 0x7c, 0x5e, 0xc0, 0xbb, 0xf9, 0x9a,
- 0x7b, 0x22, 0x9d, 0xa7, 0x00, 0x09, 0x7e, 0xac, 0x46, 0x17, 0x83, 0xdc,
- 0x9c, 0x26, 0x57, 0x99, 0x30, 0x39, 0x62, 0x96, 0x8f, 0xed, 0xda, 0xde,
- 0xaa, 0xc5, 0xcc, 0x1b, 0x3e, 0xca, 0x43, 0x68, 0x6c, 0x57, 0x16, 0xbc,
- 0xd5, 0x0e, 0x20, 0x2e, 0xfe, 0xff, 0xc2, 0x6a, 0x5d, 0x2e, 0xa0, 0x4a,
- 0x6d, 0x14, 0x58, 0x87, 0x94, 0xe6, 0x39, 0x31, 0x5f, 0x7c, 0x73, 0xcb,
- 0x90, 0x88, 0x6a, 0x84, 0x11, 0x96, 0x27, 0xa6, 0xed, 0xd9, 0x81, 0x46,
- 0xa6, 0x7e, 0xa3, 0x72, 0x00, 0x0a, 0x52, 0x3e, 0x83, 0x88, 0x07, 0x63,
- 0x77, 0x89, 0x69, 0x17, 0x0f, 0x39, 0x85, 0xd2, 0xab, 0x08, 0x45, 0x4d,
- 0xd0, 0x51, 0x3a, 0xfd, 0x5d, 0x5d, 0x37, 0x64, 0x4c, 0x7e, 0x30, 0xb2,
- 0x55, 0x24, 0x42, 0x9d, 0x36, 0xb0, 0x5d, 0x9c, 0x17, 0x81, 0x61, 0xf1,
- 0xca, 0xf9, 0x10, 0x02, 0x24, 0xab, 0xeb, 0x0d, 0x74, 0x91, 0x8d, 0x7b,
- 0x45, 0x29, 0x50, 0x39, 0x88, 0xb2, 0xa6, 0x89, 0x35, 0x25, 0x1e, 0x14,
- 0x6a, 0x47, 0x23, 0x31, 0x2f, 0x5c, 0x9a, 0xfa, 0xad, 0x9a, 0x0e, 0x62,
- 0x51, 0xa4, 0x2a, 0xa9, 0xc4, 0xf9, 0x34, 0x9d, 0x21, 0x18,
-};
-
-#if 0
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number:
- 01:fd:a3:eb:6e:ca:75:c8:88:43:8b:72:4b:cf:bc:91
- Signature Algorithm: sha256WithRSAEncryption
- Issuer: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert Global Root CA
- Validity
- Not Before: Mar 8 12:00:00 2013 GMT
- Not After : Mar 8 12:00:00 2023 GMT
- Subject: C=US, O=DigiCert Inc, CN=DigiCert SHA2 Secure Server CA
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:dc:ae:58:90:4d:c1:c4:30:15:90:35:5b:6e:3c:
- 82:15:f5:2c:5c:bd:e3:db:ff:71:43:fa:64:25:80:
- d4:ee:18:a2:4d:f0:66:d0:0a:73:6e:11:98:36:17:
- 64:af:37:9d:fd:fa:41:84:af:c7:af:8c:fe:1a:73:
- 4d:cf:33:97:90:a2:96:87:53:83:2b:b9:a6:75:48:
- 2d:1d:56:37:7b:da:31:32:1a:d7:ac:ab:06:f4:aa:
- 5d:4b:b7:47:46:dd:2a:93:c3:90:2e:79:80:80:ef:
- 13:04:6a:14:3b:b5:9b:92:be:c2:07:65:4e:fc:da:
- fc:ff:7a:ae:dc:5c:7e:55:31:0c:e8:39:07:a4:d7:
- be:2f:d3:0b:6a:d2:b1:df:5f:fe:57:74:53:3b:35:
- 80:dd:ae:8e:44:98:b3:9f:0e:d3:da:e0:d7:f4:6b:
- 29:ab:44:a7:4b:58:84:6d:92:4b:81:c3:da:73:8b:
- 12:97:48:90:04:45:75:1a:dd:37:31:97:92:e8:cd:
- 54:0d:3b:e4:c1:3f:39:5e:2e:b8:f3:5c:7e:10:8e:
- 86:41:00:8d:45:66:47:b0:a1:65:ce:a0:aa:29:09:
- 4e:f3:97:eb:e8:2e:ab:0f:72:a7:30:0e:fa:c7:f4:
- fd:14:77:c3:a4:5b:28:57:c2:b3:f9:82:fd:b7:45:
- 58:9b
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Basic Constraints: critical
- CA:TRUE, pathlen:0
- X509v3 Key Usage: critical
- Digital Signature, Certificate Sign, CRL Sign
- Authority Information Access:
- OCSP - URI:http://ocsp.digicert.com
-
- X509v3 CRL Distribution Points:
-
- Full Name:
- URI:http://crl3.digicert.com/DigiCertGlobalRootCA.crl
-
- Full Name:
- URI:http://crl4.digicert.com/DigiCertGlobalRootCA.crl
-
- X509v3 Certificate Policies:
- Policy: X509v3 Any Policy
- CPS: https://www.digicert.com/CPS
-
- X509v3 Subject Key Identifier:
- 0F:80:61:1C:82:31:61:D5:2F:28:E7:8D:46:38:B4:2C:E1:C6:D9:E2
- X509v3 Authority Key Identifier:
- keyid:03:DE:50:35:56:D1:4C:BB:66:F0:A3:E2:1B:1B:C3:97:B2:3D:D1:55
-
- Signature Algorithm: sha256WithRSAEncryption
- 23:3e:df:4b:d2:31:42:a5:b6:7e:42:5c:1a:44:cc:69:d1:68:
- b4:5d:4b:e0:04:21:6c:4b:e2:6d:cc:b1:e0:97:8f:a6:53:09:
- cd:aa:2a:65:e5:39:4f:1e:83:a5:6e:5c:98:a2:24:26:e6:fb:
- a1:ed:93:c7:2e:02:c6:4d:4a:bf:b0:42:df:78:da:b3:a8:f9:
- 6d:ff:21:85:53:36:60:4c:76:ce:ec:38:dc:d6:51:80:f0:c5:
- d6:e5:d4:4d:27:64:ab:9b:c7:3e:71:fb:48:97:b8:33:6d:c9:
- 13:07:ee:96:a2:1b:18:15:f6:5c:4c:40:ed:b3:c2:ec:ff:71:
- c1:e3:47:ff:d4:b9:00:b4:37:42:da:20:c9:ea:6e:8a:ee:14:
- 06:ae:7d:a2:59:98:88:a8:1b:6f:2d:f4:f2:c9:14:5f:26:cf:
- 2c:8d:7e:ed:37:c0:a9:d5:39:b9:82:bf:19:0c:ea:34:af:00:
- 21:68:f8:ad:73:e2:c9:32:da:38:25:0b:55:d3:9a:1d:f0:68:
- 86:ed:2e:41:34:ef:7c:a5:50:1d:bf:3a:f9:d3:c1:08:0c:e6:
- ed:1e:8a:58:25:e4:b8:77:ad:2d:6e:f5:52:dd:b4:74:8f:ab:
- 49:2e:9d:3b:93:34:28:1f:78:ce:94:ea:c7:bd:d3:c9:6d:1c:
- de:5c:32:f3
------BEGIN CERTIFICATE-----
-MIIElDCCA3ygAwIBAgIQAf2j627KdciIQ4tyS8+8kTANBgkqhkiG9w0BAQsFADBh
-MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
-d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD
-QTAeFw0xMzAzMDgxMjAwMDBaFw0yMzAzMDgxMjAwMDBaME0xCzAJBgNVBAYTAlVT
-MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxJzAlBgNVBAMTHkRpZ2lDZXJ0IFNIQTIg
-U2VjdXJlIFNlcnZlciBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
-ANyuWJBNwcQwFZA1W248ghX1LFy949v/cUP6ZCWA1O4Yok3wZtAKc24RmDYXZK83
-nf36QYSvx6+M/hpzTc8zl5CilodTgyu5pnVILR1WN3vaMTIa16yrBvSqXUu3R0bd
-KpPDkC55gIDvEwRqFDu1m5K+wgdlTvza/P96rtxcflUxDOg5B6TXvi/TC2rSsd9f
-/ld0Uzs1gN2ujkSYs58O09rg1/RrKatEp0tYhG2SS4HD2nOLEpdIkARFdRrdNzGX
-kujNVA075ME/OV4uuPNcfhCOhkEAjUVmR7ChZc6gqikJTvOX6+guqw9ypzAO+sf0
-/RR3w6RbKFfCs/mC/bdFWJsCAwEAAaOCAVowggFWMBIGA1UdEwEB/wQIMAYBAf8C
-AQAwDgYDVR0PAQH/BAQDAgGGMDQGCCsGAQUFBwEBBCgwJjAkBggrBgEFBQcwAYYY
-aHR0cDovL29jc3AuZGlnaWNlcnQuY29tMHsGA1UdHwR0MHIwN6A1oDOGMWh0dHA6
-Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEdsb2JhbFJvb3RDQS5jcmwwN6A1
-oDOGMWh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEdsb2JhbFJvb3RD
-QS5jcmwwPQYDVR0gBDYwNDAyBgRVHSAAMCowKAYIKwYBBQUHAgEWHGh0dHBzOi8v
-d3d3LmRpZ2ljZXJ0LmNvbS9DUFMwHQYDVR0OBBYEFA+AYRyCMWHVLyjnjUY4tCzh
-xtniMB8GA1UdIwQYMBaAFAPeUDVW0Uy7ZvCj4hsbw5eyPdFVMA0GCSqGSIb3DQEB
-CwUAA4IBAQAjPt9L0jFCpbZ+QlwaRMxp0Wi0XUvgBCFsS+JtzLHgl4+mUwnNqipl
-5TlPHoOlblyYoiQm5vuh7ZPHLgLGTUq/sELfeNqzqPlt/yGFUzZgTHbO7Djc1lGA
-8MXW5dRNJ2Srm8c+cftIl7gzbckTB+6WohsYFfZcTEDts8Ls/3HB40f/1LkAtDdC
-2iDJ6m6K7hQGrn2iWZiIqBtvLfTyyRRfJs8sjX7tN8Cp1Tm5gr8ZDOo0rwAhaPit
-c+LJMto4JQtV05od8GiG7S5BNO98pVAdvzr508EIDObtHopYJeS4d60tbvVS3bR0
-j6tJLp07kzQoH3jOlOrHvdPJbRzeXDLz
------END CERTIFICATE-----
-#endif
-static const unsigned char kDERCert24[] = {
- 0x30, 0x82, 0x04, 0x94, 0x30, 0x82, 0x03, 0x7c, 0xa0, 0x03, 0x02, 0x01,
- 0x02, 0x02, 0x10, 0x01, 0xfd, 0xa3, 0xeb, 0x6e, 0xca, 0x75, 0xc8, 0x88,
- 0x43, 0x8b, 0x72, 0x4b, 0xcf, 0xbc, 0x91, 0x30, 0x0d, 0x06, 0x09, 0x2a,
- 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x61,
- 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55,
- 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0c,
- 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, 0x6e, 0x63,
- 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x10, 0x77,
- 0x77, 0x77, 0x2e, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, 0x74, 0x2e,
- 0x63, 0x6f, 0x6d, 0x31, 0x20, 0x30, 0x1e, 0x06, 0x03, 0x55, 0x04, 0x03,
- 0x13, 0x17, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x47,
- 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43,
- 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x33, 0x30, 0x33, 0x30, 0x38, 0x31,
- 0x32, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x33, 0x30, 0x33,
- 0x30, 0x38, 0x31, 0x32, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x4d, 0x31,
- 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53,
- 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0c, 0x44,
- 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, 0x6e, 0x63, 0x31,
- 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x1e, 0x44, 0x69,
- 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x53, 0x48, 0x41, 0x32, 0x20,
- 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65,
- 0x72, 0x20, 0x43, 0x41, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09,
- 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03,
- 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01,
- 0x00, 0xdc, 0xae, 0x58, 0x90, 0x4d, 0xc1, 0xc4, 0x30, 0x15, 0x90, 0x35,
- 0x5b, 0x6e, 0x3c, 0x82, 0x15, 0xf5, 0x2c, 0x5c, 0xbd, 0xe3, 0xdb, 0xff,
- 0x71, 0x43, 0xfa, 0x64, 0x25, 0x80, 0xd4, 0xee, 0x18, 0xa2, 0x4d, 0xf0,
- 0x66, 0xd0, 0x0a, 0x73, 0x6e, 0x11, 0x98, 0x36, 0x17, 0x64, 0xaf, 0x37,
- 0x9d, 0xfd, 0xfa, 0x41, 0x84, 0xaf, 0xc7, 0xaf, 0x8c, 0xfe, 0x1a, 0x73,
- 0x4d, 0xcf, 0x33, 0x97, 0x90, 0xa2, 0x96, 0x87, 0x53, 0x83, 0x2b, 0xb9,
- 0xa6, 0x75, 0x48, 0x2d, 0x1d, 0x56, 0x37, 0x7b, 0xda, 0x31, 0x32, 0x1a,
- 0xd7, 0xac, 0xab, 0x06, 0xf4, 0xaa, 0x5d, 0x4b, 0xb7, 0x47, 0x46, 0xdd,
- 0x2a, 0x93, 0xc3, 0x90, 0x2e, 0x79, 0x80, 0x80, 0xef, 0x13, 0x04, 0x6a,
- 0x14, 0x3b, 0xb5, 0x9b, 0x92, 0xbe, 0xc2, 0x07, 0x65, 0x4e, 0xfc, 0xda,
- 0xfc, 0xff, 0x7a, 0xae, 0xdc, 0x5c, 0x7e, 0x55, 0x31, 0x0c, 0xe8, 0x39,
- 0x07, 0xa4, 0xd7, 0xbe, 0x2f, 0xd3, 0x0b, 0x6a, 0xd2, 0xb1, 0xdf, 0x5f,
- 0xfe, 0x57, 0x74, 0x53, 0x3b, 0x35, 0x80, 0xdd, 0xae, 0x8e, 0x44, 0x98,
- 0xb3, 0x9f, 0x0e, 0xd3, 0xda, 0xe0, 0xd7, 0xf4, 0x6b, 0x29, 0xab, 0x44,
- 0xa7, 0x4b, 0x58, 0x84, 0x6d, 0x92, 0x4b, 0x81, 0xc3, 0xda, 0x73, 0x8b,
- 0x12, 0x97, 0x48, 0x90, 0x04, 0x45, 0x75, 0x1a, 0xdd, 0x37, 0x31, 0x97,
- 0x92, 0xe8, 0xcd, 0x54, 0x0d, 0x3b, 0xe4, 0xc1, 0x3f, 0x39, 0x5e, 0x2e,
- 0xb8, 0xf3, 0x5c, 0x7e, 0x10, 0x8e, 0x86, 0x41, 0x00, 0x8d, 0x45, 0x66,
- 0x47, 0xb0, 0xa1, 0x65, 0xce, 0xa0, 0xaa, 0x29, 0x09, 0x4e, 0xf3, 0x97,
- 0xeb, 0xe8, 0x2e, 0xab, 0x0f, 0x72, 0xa7, 0x30, 0x0e, 0xfa, 0xc7, 0xf4,
- 0xfd, 0x14, 0x77, 0xc3, 0xa4, 0x5b, 0x28, 0x57, 0xc2, 0xb3, 0xf9, 0x82,
- 0xfd, 0xb7, 0x45, 0x58, 0x9b, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82,
- 0x01, 0x5a, 0x30, 0x82, 0x01, 0x56, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d,
- 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02,
- 0x01, 0x00, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff,
- 0x04, 0x04, 0x03, 0x02, 0x01, 0x86, 0x30, 0x34, 0x06, 0x08, 0x2b, 0x06,
- 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x28, 0x30, 0x26, 0x30, 0x24,
- 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x18,
- 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e,
- 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, 0x74, 0x2e, 0x63, 0x6f, 0x6d,
- 0x30, 0x7b, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x74, 0x30, 0x72, 0x30,
- 0x37, 0xa0, 0x35, 0xa0, 0x33, 0x86, 0x31, 0x68, 0x74, 0x74, 0x70, 0x3a,
- 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x33, 0x2e, 0x64, 0x69, 0x67, 0x69, 0x63,
- 0x65, 0x72, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x44, 0x69, 0x67, 0x69,
- 0x43, 0x65, 0x72, 0x74, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x52, 0x6f,
- 0x6f, 0x74, 0x43, 0x41, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x37, 0xa0, 0x35,
- 0xa0, 0x33, 0x86, 0x31, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63,
- 0x72, 0x6c, 0x34, 0x2e, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, 0x74,
- 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72,
- 0x74, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x52, 0x6f, 0x6f, 0x74, 0x43,
- 0x41, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x3d, 0x06, 0x03, 0x55, 0x1d, 0x20,
- 0x04, 0x36, 0x30, 0x34, 0x30, 0x32, 0x06, 0x04, 0x55, 0x1d, 0x20, 0x00,
- 0x30, 0x2a, 0x30, 0x28, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
- 0x02, 0x01, 0x16, 0x1c, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f,
- 0x77, 0x77, 0x77, 0x2e, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, 0x74,
- 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x43, 0x50, 0x53, 0x30, 0x1d, 0x06, 0x03,
- 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x0f, 0x80, 0x61, 0x1c, 0x82,
- 0x31, 0x61, 0xd5, 0x2f, 0x28, 0xe7, 0x8d, 0x46, 0x38, 0xb4, 0x2c, 0xe1,
- 0xc6, 0xd9, 0xe2, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18,
- 0x30, 0x16, 0x80, 0x14, 0x03, 0xde, 0x50, 0x35, 0x56, 0xd1, 0x4c, 0xbb,
- 0x66, 0xf0, 0xa3, 0xe2, 0x1b, 0x1b, 0xc3, 0x97, 0xb2, 0x3d, 0xd1, 0x55,
- 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
- 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x23, 0x3e, 0xdf, 0x4b,
- 0xd2, 0x31, 0x42, 0xa5, 0xb6, 0x7e, 0x42, 0x5c, 0x1a, 0x44, 0xcc, 0x69,
- 0xd1, 0x68, 0xb4, 0x5d, 0x4b, 0xe0, 0x04, 0x21, 0x6c, 0x4b, 0xe2, 0x6d,
- 0xcc, 0xb1, 0xe0, 0x97, 0x8f, 0xa6, 0x53, 0x09, 0xcd, 0xaa, 0x2a, 0x65,
- 0xe5, 0x39, 0x4f, 0x1e, 0x83, 0xa5, 0x6e, 0x5c, 0x98, 0xa2, 0x24, 0x26,
- 0xe6, 0xfb, 0xa1, 0xed, 0x93, 0xc7, 0x2e, 0x02, 0xc6, 0x4d, 0x4a, 0xbf,
- 0xb0, 0x42, 0xdf, 0x78, 0xda, 0xb3, 0xa8, 0xf9, 0x6d, 0xff, 0x21, 0x85,
- 0x53, 0x36, 0x60, 0x4c, 0x76, 0xce, 0xec, 0x38, 0xdc, 0xd6, 0x51, 0x80,
- 0xf0, 0xc5, 0xd6, 0xe5, 0xd4, 0x4d, 0x27, 0x64, 0xab, 0x9b, 0xc7, 0x3e,
- 0x71, 0xfb, 0x48, 0x97, 0xb8, 0x33, 0x6d, 0xc9, 0x13, 0x07, 0xee, 0x96,
- 0xa2, 0x1b, 0x18, 0x15, 0xf6, 0x5c, 0x4c, 0x40, 0xed, 0xb3, 0xc2, 0xec,
- 0xff, 0x71, 0xc1, 0xe3, 0x47, 0xff, 0xd4, 0xb9, 0x00, 0xb4, 0x37, 0x42,
- 0xda, 0x20, 0xc9, 0xea, 0x6e, 0x8a, 0xee, 0x14, 0x06, 0xae, 0x7d, 0xa2,
- 0x59, 0x98, 0x88, 0xa8, 0x1b, 0x6f, 0x2d, 0xf4, 0xf2, 0xc9, 0x14, 0x5f,
- 0x26, 0xcf, 0x2c, 0x8d, 0x7e, 0xed, 0x37, 0xc0, 0xa9, 0xd5, 0x39, 0xb9,
- 0x82, 0xbf, 0x19, 0x0c, 0xea, 0x34, 0xaf, 0x00, 0x21, 0x68, 0xf8, 0xad,
- 0x73, 0xe2, 0xc9, 0x32, 0xda, 0x38, 0x25, 0x0b, 0x55, 0xd3, 0x9a, 0x1d,
- 0xf0, 0x68, 0x86, 0xed, 0x2e, 0x41, 0x34, 0xef, 0x7c, 0xa5, 0x50, 0x1d,
- 0xbf, 0x3a, 0xf9, 0xd3, 0xc1, 0x08, 0x0c, 0xe6, 0xed, 0x1e, 0x8a, 0x58,
- 0x25, 0xe4, 0xb8, 0x77, 0xad, 0x2d, 0x6e, 0xf5, 0x52, 0xdd, 0xb4, 0x74,
- 0x8f, 0xab, 0x49, 0x2e, 0x9d, 0x3b, 0x93, 0x34, 0x28, 0x1f, 0x78, 0xce,
- 0x94, 0xea, 0xc7, 0xbd, 0xd3, 0xc9, 0x6d, 0x1c, 0xde, 0x5c, 0x32, 0xf3,
-};
-
-#if 0
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number: 3740804 (0x391484)
- Signature Algorithm: sha256WithRSAEncryption
- Issuer: C=US, O=Starfield Technologies, Inc., OU=Starfield Class 2 Certification Authority
- Validity
- Not Before: Jan 1 07:00:00 2014 GMT
- Not After : May 30 07:00:00 2031 GMT
- Subject: C=US, ST=Arizona, L=Scottsdale, O=Starfield Technologies, Inc., CN=Starfield Root Certificate Authority - G2
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:bd:ed:c1:03:fc:f6:8f:fc:02:b1:6f:5b:9f:48:
- d9:9d:79:e2:a2:b7:03:61:56:18:c3:47:b6:d7:ca:
- 3d:35:2e:89:43:f7:a1:69:9b:de:8a:1a:fd:13:20:
- 9c:b4:49:77:32:29:56:fd:b9:ec:8c:dd:22:fa:72:
- dc:27:61:97:ee:f6:5a:84:ec:6e:19:b9:89:2c:dc:
- 84:5b:d5:74:fb:6b:5f:c5:89:a5:10:52:89:46:55:
- f4:b8:75:1c:e6:7f:e4:54:ae:4b:f8:55:72:57:02:
- 19:f8:17:71:59:eb:1e:28:07:74:c5:9d:48:be:6c:
- b4:f4:a4:b0:f3:64:37:79:92:c0:ec:46:5e:7f:e1:
- 6d:53:4c:62:af:cd:1f:0b:63:bb:3a:9d:fb:fc:79:
- 00:98:61:74:cf:26:82:40:63:f3:b2:72:6a:19:0d:
- 99:ca:d4:0e:75:cc:37:fb:8b:89:c1:59:f1:62:7f:
- 5f:b3:5f:65:30:f8:a7:b7:4d:76:5a:1e:76:5e:34:
- c0:e8:96:56:99:8a:b3:f0:7f:a4:cd:bd:dc:32:31:
- 7c:91:cf:e0:5f:11:f8:6b:aa:49:5c:d1:99:94:d1:
- a2:e3:63:5b:09:76:b5:56:62:e1:4b:74:1d:96:d4:
- 26:d4:08:04:59:d0:98:0e:0e:e6:de:fc:c3:ec:1f:
- 90:f1
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Basic Constraints: critical
- CA:TRUE
- X509v3 Key Usage: critical
- Certificate Sign, CRL Sign
- X509v3 Subject Key Identifier:
- 7C:0C:32:1F:A7:D9:30:7F:C4:7D:68:A3:62:A8:A1:CE:AB:07:5B:27
- X509v3 Authority Key Identifier:
- keyid:BF:5F:B7:D1:CE:DD:1F:86:F4:5B:55:AC:DC:D7:10:C2:0E:A9:88:E7
-
- Authority Information Access:
- OCSP - URI:http://ocsp.starfieldtech.com/
-
- X509v3 CRL Distribution Points:
-
- Full Name:
- URI:http://crl.starfieldtech.com/sfroot.crl
-
- X509v3 Certificate Policies:
- Policy: X509v3 Any Policy
- CPS: https://certs.starfieldtech.com/repository/
-
- Signature Algorithm: sha256WithRSAEncryption
- 85:63:c1:d9:dd:b9:ff:a9:bd:a6:19:dc:bf:13:3a:11:38:22:
- 54:b1:ac:05:10:fb:7c:b3:96:3f:31:8b:66:ff:88:f3:e1:bf:
- fb:c7:1f:00:ff:46:6a:8b:61:32:c9:01:51:76:fb:9a:c6:fa:
- 20:51:c8:46:c4:98:d7:79:a3:e3:04:72:3f:8b:4d:34:53:67:
- ec:33:2c:7b:e8:94:01:28:7c:3a:34:5b:02:77:16:8d:40:25:
- 33:b0:bc:6c:97:d7:05:7a:ff:8c:85:ce:6f:a0:53:00:17:6e:
- 1e:6c:bd:22:d7:0a:88:37:f6:7d:eb:99:41:ef:27:cb:8c:60:
- 6b:4c:01:7e:65:50:0b:4f:b8:95:9a:9a:6e:34:fd:73:3a:33:
- f1:91:d5:f3:4e:2d:74:e8:ef:d3:90:35:f1:06:68:64:d4:d0:
- 13:fd:52:d3:c6:6d:c1:3a:8a:31:dd:05:26:35:4a:8c:65:b8:
- 52:6b:81:ec:d2:9c:b5:34:10:97:9c:3e:c6:2f:ed:8e:42:42:
- 24:2e:e9:73:9a:25:f9:11:f1:f2:23:69:cb:e5:94:69:a0:d2:
- dc:b0:fc:44:89:ac:17:a8:cc:d5:37:77:16:c5:80:b9:0c:8f:
- 57:02:55:99:85:7b:49:f0:2e:5b:a0:c2:57:53:5d:a2:e8:a6:
- 37:c3:01:fa
------BEGIN CERTIFICATE-----
-MIIEoDCCA4igAwIBAgIDORSEMA0GCSqGSIb3DQEBCwUAMGgxCzAJBgNVBAYTAlVT
-MSUwIwYDVQQKExxTdGFyZmllbGQgVGVjaG5vbG9naWVzLCBJbmMuMTIwMAYDVQQL
-EylTdGFyZmllbGQgQ2xhc3MgMiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0x
-NDAxMDEwNzAwMDBaFw0zMTA1MzAwNzAwMDBaMIGPMQswCQYDVQQGEwJVUzEQMA4G
-A1UECBMHQXJpem9uYTETMBEGA1UEBxMKU2NvdHRzZGFsZTElMCMGA1UEChMcU3Rh
-cmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UEAxMpU3RhcmZpZWxkIFJv
-b3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IC0gRzIwggEiMA0GCSqGSIb3DQEBAQUA
-A4IBDwAwggEKAoIBAQC97cED/PaP/AKxb1ufSNmdeeKitwNhVhjDR7bXyj01LolD
-96Fpm96KGv0TIJy0SXcyKVb9ueyM3SL6ctwnYZfu9lqE7G4ZuYks3IRb1XT7a1/F
-iaUQUolGVfS4dRzmf+RUrkv4VXJXAhn4F3FZ6x4oB3TFnUi+bLT0pLDzZDd5ksDs
-Rl5/4W1TTGKvzR8LY7s6nfv8eQCYYXTPJoJAY/OycmoZDZnK1A51zDf7i4nBWfFi
-f1+zX2Uw+Ke3TXZaHnZeNMDollaZirPwf6TNvdwyMXyRz+BfEfhrqklc0ZmU0aLj
-Y1sJdrVWYuFLdB2W1CbUCARZ0JgODube/MPsH5DxAgMBAAGjggEpMIIBJTAPBgNV
-HRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUfAwyH6fZMH/E
-fWijYqihzqsHWycwHwYDVR0jBBgwFoAUv1+30c7dH4b0W1Ws3NcQwg6piOcwOgYI
-KwYBBQUHAQEELjAsMCoGCCsGAQUFBzABhh5odHRwOi8vb2NzcC5zdGFyZmllbGR0
-ZWNoLmNvbS8wOAYDVR0fBDEwLzAtoCugKYYnaHR0cDovL2NybC5zdGFyZmllbGR0
-ZWNoLmNvbS9zZnJvb3QuY3JsMEwGA1UdIARFMEMwQQYEVR0gADA5MDcGCCsGAQUF
-BwIBFitodHRwczovL2NlcnRzLnN0YXJmaWVsZHRlY2guY29tL3JlcG9zaXRvcnkv
-MA0GCSqGSIb3DQEBCwUAA4IBAQCFY8HZ3bn/qb2mGdy/EzoROCJUsawFEPt8s5Y/
-MYtm/4jz4b/7xx8A/0Zqi2EyyQFRdvuaxvogUchGxJjXeaPjBHI/i000U2fsMyx7
-6JQBKHw6NFsCdxaNQCUzsLxsl9cFev+Mhc5voFMAF24ebL0i1wqIN/Z965lB7yfL
-jGBrTAF+ZVALT7iVmppuNP1zOjPxkdXzTi106O/TkDXxBmhk1NAT/VLTxm3BOoox
-3QUmNUqMZbhSa4Hs0py1NBCXnD7GL+2OQkIkLulzmiX5EfHyI2nL5ZRpoNLcsPxE
-iawXqMzVN3cWxYC5DI9XAlWZhXtJ8C5boMJXU12i6KY3wwH6
------END CERTIFICATE-----
-#endif
-static const unsigned char kDERCert25[] = {
- 0x30, 0x82, 0x04, 0xa0, 0x30, 0x82, 0x03, 0x88, 0xa0, 0x03, 0x02, 0x01,
- 0x02, 0x02, 0x03, 0x39, 0x14, 0x84, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
- 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x68, 0x31,
- 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53,
- 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x1c, 0x53,
- 0x74, 0x61, 0x72, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x20, 0x54, 0x65, 0x63,
- 0x68, 0x6e, 0x6f, 0x6c, 0x6f, 0x67, 0x69, 0x65, 0x73, 0x2c, 0x20, 0x49,
- 0x6e, 0x63, 0x2e, 0x31, 0x32, 0x30, 0x30, 0x06, 0x03, 0x55, 0x04, 0x0b,
- 0x13, 0x29, 0x53, 0x74, 0x61, 0x72, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x20,
- 0x43, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x32, 0x20, 0x43, 0x65, 0x72, 0x74,
- 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75,
- 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x30, 0x1e, 0x17, 0x0d, 0x31,
- 0x34, 0x30, 0x31, 0x30, 0x31, 0x30, 0x37, 0x30, 0x30, 0x30, 0x30, 0x5a,
- 0x17, 0x0d, 0x33, 0x31, 0x30, 0x35, 0x33, 0x30, 0x30, 0x37, 0x30, 0x30,
- 0x30, 0x30, 0x5a, 0x30, 0x81, 0x8f, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03,
- 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x10, 0x30, 0x0e, 0x06,
- 0x03, 0x55, 0x04, 0x08, 0x13, 0x07, 0x41, 0x72, 0x69, 0x7a, 0x6f, 0x6e,
- 0x61, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x0a,
- 0x53, 0x63, 0x6f, 0x74, 0x74, 0x73, 0x64, 0x61, 0x6c, 0x65, 0x31, 0x25,
- 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x1c, 0x53, 0x74, 0x61,
- 0x72, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x20, 0x54, 0x65, 0x63, 0x68, 0x6e,
- 0x6f, 0x6c, 0x6f, 0x67, 0x69, 0x65, 0x73, 0x2c, 0x20, 0x49, 0x6e, 0x63,
- 0x2e, 0x31, 0x32, 0x30, 0x30, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x29,
- 0x53, 0x74, 0x61, 0x72, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x20, 0x52, 0x6f,
- 0x6f, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61,
- 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79,
- 0x20, 0x2d, 0x20, 0x47, 0x32, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06,
- 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00,
- 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01,
- 0x01, 0x00, 0xbd, 0xed, 0xc1, 0x03, 0xfc, 0xf6, 0x8f, 0xfc, 0x02, 0xb1,
- 0x6f, 0x5b, 0x9f, 0x48, 0xd9, 0x9d, 0x79, 0xe2, 0xa2, 0xb7, 0x03, 0x61,
- 0x56, 0x18, 0xc3, 0x47, 0xb6, 0xd7, 0xca, 0x3d, 0x35, 0x2e, 0x89, 0x43,
- 0xf7, 0xa1, 0x69, 0x9b, 0xde, 0x8a, 0x1a, 0xfd, 0x13, 0x20, 0x9c, 0xb4,
- 0x49, 0x77, 0x32, 0x29, 0x56, 0xfd, 0xb9, 0xec, 0x8c, 0xdd, 0x22, 0xfa,
- 0x72, 0xdc, 0x27, 0x61, 0x97, 0xee, 0xf6, 0x5a, 0x84, 0xec, 0x6e, 0x19,
- 0xb9, 0x89, 0x2c, 0xdc, 0x84, 0x5b, 0xd5, 0x74, 0xfb, 0x6b, 0x5f, 0xc5,
- 0x89, 0xa5, 0x10, 0x52, 0x89, 0x46, 0x55, 0xf4, 0xb8, 0x75, 0x1c, 0xe6,
- 0x7f, 0xe4, 0x54, 0xae, 0x4b, 0xf8, 0x55, 0x72, 0x57, 0x02, 0x19, 0xf8,
- 0x17, 0x71, 0x59, 0xeb, 0x1e, 0x28, 0x07, 0x74, 0xc5, 0x9d, 0x48, 0xbe,
- 0x6c, 0xb4, 0xf4, 0xa4, 0xb0, 0xf3, 0x64, 0x37, 0x79, 0x92, 0xc0, 0xec,
- 0x46, 0x5e, 0x7f, 0xe1, 0x6d, 0x53, 0x4c, 0x62, 0xaf, 0xcd, 0x1f, 0x0b,
- 0x63, 0xbb, 0x3a, 0x9d, 0xfb, 0xfc, 0x79, 0x00, 0x98, 0x61, 0x74, 0xcf,
- 0x26, 0x82, 0x40, 0x63, 0xf3, 0xb2, 0x72, 0x6a, 0x19, 0x0d, 0x99, 0xca,
- 0xd4, 0x0e, 0x75, 0xcc, 0x37, 0xfb, 0x8b, 0x89, 0xc1, 0x59, 0xf1, 0x62,
- 0x7f, 0x5f, 0xb3, 0x5f, 0x65, 0x30, 0xf8, 0xa7, 0xb7, 0x4d, 0x76, 0x5a,
- 0x1e, 0x76, 0x5e, 0x34, 0xc0, 0xe8, 0x96, 0x56, 0x99, 0x8a, 0xb3, 0xf0,
- 0x7f, 0xa4, 0xcd, 0xbd, 0xdc, 0x32, 0x31, 0x7c, 0x91, 0xcf, 0xe0, 0x5f,
- 0x11, 0xf8, 0x6b, 0xaa, 0x49, 0x5c, 0xd1, 0x99, 0x94, 0xd1, 0xa2, 0xe3,
- 0x63, 0x5b, 0x09, 0x76, 0xb5, 0x56, 0x62, 0xe1, 0x4b, 0x74, 0x1d, 0x96,
- 0xd4, 0x26, 0xd4, 0x08, 0x04, 0x59, 0xd0, 0x98, 0x0e, 0x0e, 0xe6, 0xde,
- 0xfc, 0xc3, 0xec, 0x1f, 0x90, 0xf1, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3,
- 0x82, 0x01, 0x29, 0x30, 0x82, 0x01, 0x25, 0x30, 0x0f, 0x06, 0x03, 0x55,
- 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff,
- 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04,
- 0x03, 0x02, 0x01, 0x06, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04,
- 0x16, 0x04, 0x14, 0x7c, 0x0c, 0x32, 0x1f, 0xa7, 0xd9, 0x30, 0x7f, 0xc4,
- 0x7d, 0x68, 0xa3, 0x62, 0xa8, 0xa1, 0xce, 0xab, 0x07, 0x5b, 0x27, 0x30,
- 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14,
- 0xbf, 0x5f, 0xb7, 0xd1, 0xce, 0xdd, 0x1f, 0x86, 0xf4, 0x5b, 0x55, 0xac,
- 0xdc, 0xd7, 0x10, 0xc2, 0x0e, 0xa9, 0x88, 0xe7, 0x30, 0x3a, 0x06, 0x08,
- 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x2e, 0x30, 0x2c,
- 0x30, 0x2a, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01,
- 0x86, 0x1e, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73,
- 0x70, 0x2e, 0x73, 0x74, 0x61, 0x72, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x74,
- 0x65, 0x63, 0x68, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x30, 0x38, 0x06, 0x03,
- 0x55, 0x1d, 0x1f, 0x04, 0x31, 0x30, 0x2f, 0x30, 0x2d, 0xa0, 0x2b, 0xa0,
- 0x29, 0x86, 0x27, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72,
- 0x6c, 0x2e, 0x73, 0x74, 0x61, 0x72, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x74,
- 0x65, 0x63, 0x68, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x73, 0x66, 0x72, 0x6f,
- 0x6f, 0x74, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x4c, 0x06, 0x03, 0x55, 0x1d,
- 0x20, 0x04, 0x45, 0x30, 0x43, 0x30, 0x41, 0x06, 0x04, 0x55, 0x1d, 0x20,
- 0x00, 0x30, 0x39, 0x30, 0x37, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05,
- 0x07, 0x02, 0x01, 0x16, 0x2b, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f,
- 0x2f, 0x63, 0x65, 0x72, 0x74, 0x73, 0x2e, 0x73, 0x74, 0x61, 0x72, 0x66,
- 0x69, 0x65, 0x6c, 0x64, 0x74, 0x65, 0x63, 0x68, 0x2e, 0x63, 0x6f, 0x6d,
- 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x2f,
- 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
- 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x85, 0x63, 0xc1, 0xd9,
- 0xdd, 0xb9, 0xff, 0xa9, 0xbd, 0xa6, 0x19, 0xdc, 0xbf, 0x13, 0x3a, 0x11,
- 0x38, 0x22, 0x54, 0xb1, 0xac, 0x05, 0x10, 0xfb, 0x7c, 0xb3, 0x96, 0x3f,
- 0x31, 0x8b, 0x66, 0xff, 0x88, 0xf3, 0xe1, 0xbf, 0xfb, 0xc7, 0x1f, 0x00,
- 0xff, 0x46, 0x6a, 0x8b, 0x61, 0x32, 0xc9, 0x01, 0x51, 0x76, 0xfb, 0x9a,
- 0xc6, 0xfa, 0x20, 0x51, 0xc8, 0x46, 0xc4, 0x98, 0xd7, 0x79, 0xa3, 0xe3,
- 0x04, 0x72, 0x3f, 0x8b, 0x4d, 0x34, 0x53, 0x67, 0xec, 0x33, 0x2c, 0x7b,
- 0xe8, 0x94, 0x01, 0x28, 0x7c, 0x3a, 0x34, 0x5b, 0x02, 0x77, 0x16, 0x8d,
- 0x40, 0x25, 0x33, 0xb0, 0xbc, 0x6c, 0x97, 0xd7, 0x05, 0x7a, 0xff, 0x8c,
- 0x85, 0xce, 0x6f, 0xa0, 0x53, 0x00, 0x17, 0x6e, 0x1e, 0x6c, 0xbd, 0x22,
- 0xd7, 0x0a, 0x88, 0x37, 0xf6, 0x7d, 0xeb, 0x99, 0x41, 0xef, 0x27, 0xcb,
- 0x8c, 0x60, 0x6b, 0x4c, 0x01, 0x7e, 0x65, 0x50, 0x0b, 0x4f, 0xb8, 0x95,
- 0x9a, 0x9a, 0x6e, 0x34, 0xfd, 0x73, 0x3a, 0x33, 0xf1, 0x91, 0xd5, 0xf3,
- 0x4e, 0x2d, 0x74, 0xe8, 0xef, 0xd3, 0x90, 0x35, 0xf1, 0x06, 0x68, 0x64,
- 0xd4, 0xd0, 0x13, 0xfd, 0x52, 0xd3, 0xc6, 0x6d, 0xc1, 0x3a, 0x8a, 0x31,
- 0xdd, 0x05, 0x26, 0x35, 0x4a, 0x8c, 0x65, 0xb8, 0x52, 0x6b, 0x81, 0xec,
- 0xd2, 0x9c, 0xb5, 0x34, 0x10, 0x97, 0x9c, 0x3e, 0xc6, 0x2f, 0xed, 0x8e,
- 0x42, 0x42, 0x24, 0x2e, 0xe9, 0x73, 0x9a, 0x25, 0xf9, 0x11, 0xf1, 0xf2,
- 0x23, 0x69, 0xcb, 0xe5, 0x94, 0x69, 0xa0, 0xd2, 0xdc, 0xb0, 0xfc, 0x44,
- 0x89, 0xac, 0x17, 0xa8, 0xcc, 0xd5, 0x37, 0x77, 0x16, 0xc5, 0x80, 0xb9,
- 0x0c, 0x8f, 0x57, 0x02, 0x55, 0x99, 0x85, 0x7b, 0x49, 0xf0, 0x2e, 0x5b,
- 0xa0, 0xc2, 0x57, 0x53, 0x5d, 0xa2, 0xe8, 0xa6, 0x37, 0xc3, 0x01, 0xfa,
-};
-
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/common_cert_set_3b.inc b/chromium/net/third_party/quiche/src/quic/core/crypto/common_cert_set_3b.inc
deleted file mode 100644
index f175f240509..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/common_cert_set_3b.inc
+++ /dev/null
@@ -1,5717 +0,0 @@
-#if 0
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number:
- 28:1c:89:29:66:14:43:80:42:63:55:3a:32:40:ae:b3
- Signature Algorithm: sha256WithRSAEncryption
- Issuer: C=US, O=GeoTrust Inc., OU=(c) 2008 GeoTrust Inc. - For authorized use only, CN=GeoTrust Primary Certification Authority - G3
- Validity
- Not Before: Jun 30 00:00:00 2015 GMT
- Not After : Jun 29 23:59:59 2025 GMT
- Subject: C=US, O=GeoTrust Inc., CN=RapidSSL SHA256 CA - G4
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:c0:9e:3a:0f:9a:b2:ba:d3:d2:dc:15:ec:d0:30:
- 54:59:30:4d:40:51:ae:42:71:71:d2:8d:53:73:81:
- fe:b8:e0:c4:96:c5:8e:7e:c2:f1:b7:63:4a:cf:a7:
- 1e:3f:a8:e7:ce:53:a0:fa:2d:f7:d6:e6:ce:70:11:
- a6:ee:e1:03:52:d2:68:de:3d:08:0d:87:fd:1c:d7:
- 0b:97:62:6d:82:30:76:1b:47:3a:c4:f7:ce:ed:1d:
- 7c:8c:b7:17:8e:53:80:1e:1d:0f:5d:8c:f9:90:e4:
- 04:1e:02:7e:cb:b0:49:ef:da:52:25:fb:fb:67:ed:
- dd:84:74:59:84:0e:f3:de:70:66:8d:e4:52:38:f7:
- 53:5a:37:13:67:0b:3e:bb:a8:58:b7:2e:ed:ff:b7:
- 5e:11:73:b9:77:45:52:67:46:ae:c4:dc:24:81:89:
- 76:0a:ca:a1:6c:66:73:04:82:aa:f5:70:6c:5f:1b:
- 9a:00:79:46:d6:7f:7a:26:17:30:cf:39:4b:2c:74:
- d9:89:44:76:10:d0:ed:f7:8b:bb:89:05:75:4d:0b:
- 0d:b3:da:e9:bf:f1:6a:7d:2a:11:db:1e:9f:8c:e3:
- c4:06:69:e1:1d:88:45:39:d1:6e:55:d8:aa:b7:9b:
- 6f:ea:f4:de:ac:17:11:92:5d:40:9b:83:7b:9a:e2:
- f7:a9
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- Authority Information Access:
- OCSP - URI:http://g.symcd.com
-
- X509v3 Basic Constraints: critical
- CA:TRUE, pathlen:0
- X509v3 Certificate Policies:
- Policy: 2.23.140.1.2.1
- CPS: https://www.geotrust.com/resources/cps
-
- X509v3 CRL Distribution Points:
-
- Full Name:
- URI:http://g.symcb.com/GeoTrustPCA-G3.crl
-
- X509v3 Extended Key Usage:
- TLS Web Server Authentication, TLS Web Client Authentication
- X509v3 Key Usage: critical
- Certificate Sign, CRL Sign
- X509v3 Subject Key Identifier:
- F3:B5:56:0C:C4:09:B0:B4:CF:1F:AA:F9:DD:23:56:F0:77:E8:A1:F9
- X509v3 Authority Key Identifier:
- keyid:C4:79:CA:8E:A1:4E:03:1D:1C:DC:6B:DB:31:5B:94:3E:3F:30:7F:2D
-
- Signature Algorithm: sha256WithRSAEncryption
- c3:7e:d8:83:4b:04:4c:55:29:2a:4f:14:9d:9a:6e:de:90:70:
- c1:a4:26:4c:88:8e:78:48:ef:bd:9c:b0:a0:f5:f0:66:fc:fe:
- 59:26:e1:79:ef:c8:b7:60:64:a8:8b:47:ea:2f:e0:83:99:da:
- 41:19:d7:c5:be:05:fa:f2:90:11:f0:0a:ff:6c:dc:05:b4:d8:
- 06:6f:a4:6f:8d:be:20:2b:54:db:f9:a2:45:83:9a:1e:a5:21:
- 89:35:1d:7c:20:5c:17:fd:04:2e:45:d8:b2:c6:f8:42:99:fc:
- 54:08:4e:4b:80:5f:39:37:ba:95:4e:a6:37:0a:9e:93:5e:87:
- 5b:e9:90:d6:a8:b6:65:08:8d:61:49:eb:83:20:a9:5d:1b:16:
- 60:62:6b:2f:54:fb:5a:02:0d:7a:27:e2:4b:e1:05:14:c2:e4:
- e9:f9:70:c0:d9:f7:34:65:0e:a2:91:4b:ac:28:f2:b7:08:0f:
- 98:ca:d7:3e:70:b6:c8:0b:f1:8b:9c:51:f8:c6:10:6c:d2:53:
- 4f:62:8c:11:00:3e:88:df:bf:e6:d2:cc:70:bd:ed:25:9c:fb:
- dd:24:0a:bd:59:91:4a:42:03:38:12:71:32:88:76:a0:8e:7c:
- bb:32:ef:88:2a:1b:d4:6a:6f:50:b9:52:67:8b:ab:30:fa:1f:
- fd:e3:24:9a
------BEGIN CERTIFICATE-----
-MIIEpjCCA46gAwIBAgIQKByJKWYUQ4BCY1U6MkCuszANBgkqhkiG9w0BAQsFADCB
-mDELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsT
-MChjKSAyMDA4IEdlb1RydXN0IEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25s
-eTE2MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhv
-cml0eSAtIEczMB4XDTE1MDYzMDAwMDAwMFoXDTI1MDYyOTIzNTk1OVowRzELMAkG
-A1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xIDAeBgNVBAMTF1JhcGlk
-U1NMIFNIQTI1NiBDQSAtIEc0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
-AQEAwJ46D5qyutPS3BXs0DBUWTBNQFGuQnFx0o1Tc4H+uODElsWOfsLxt2NKz6ce
-P6jnzlOg+i331ubOcBGm7uEDUtJo3j0IDYf9HNcLl2JtgjB2G0c6xPfO7R18jLcX
-jlOAHh0PXYz5kOQEHgJ+y7BJ79pSJfv7Z+3dhHRZhA7z3nBmjeRSOPdTWjcTZws+
-u6hYty7t/7deEXO5d0VSZ0auxNwkgYl2CsqhbGZzBIKq9XBsXxuaAHlG1n96Jhcw
-zzlLLHTZiUR2ENDt94u7iQV1TQsNs9rpv/FqfSoR2x6fjOPEBmnhHYhFOdFuVdiq
-t5tv6vTerBcRkl1Am4N7muL3qQIDAQABo4IBOjCCATYwLgYIKwYBBQUHAQEEIjAg
-MB4GCCsGAQUFBzABhhJodHRwOi8vZy5zeW1jZC5jb20wEgYDVR0TAQH/BAgwBgEB
-/wIBADBJBgNVHSAEQjBAMD4GBmeBDAECATA0MDIGCCsGAQUFBwIBFiZodHRwczov
-L3d3dy5nZW90cnVzdC5jb20vcmVzb3VyY2VzL2NwczA2BgNVHR8ELzAtMCugKaAn
-hiVodHRwOi8vZy5zeW1jYi5jb20vR2VvVHJ1c3RQQ0EtRzMuY3JsMB0GA1UdJQQW
-MBQGCCsGAQUFBwMBBggrBgEFBQcDAjAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE
-FPO1VgzECbC0zx+q+d0jVvB36KH5MB8GA1UdIwQYMBaAFMR5yo6hTgMdHNxr2zFb
-lD4/MH8tMA0GCSqGSIb3DQEBCwUAA4IBAQDDftiDSwRMVSkqTxSdmm7ekHDBpCZM
-iI54SO+9nLCg9fBm/P5ZJuF578i3YGSoi0fqL+CDmdpBGdfFvgX68pAR8Ar/bNwF
-tNgGb6Rvjb4gK1Tb+aJFg5oepSGJNR18IFwX/QQuRdiyxvhCmfxUCE5LgF85N7qV
-TqY3Cp6TXodb6ZDWqLZlCI1hSeuDIKldGxZgYmsvVPtaAg16J+JL4QUUwuTp+XDA
-2fc0ZQ6ikUusKPK3CA+Yytc+cLbIC/GLnFH4xhBs0lNPYowRAD6I37/m0sxwve0l
-nPvdJAq9WZFKQgM4EnEyiHagjny7Mu+IKhvUam9QuVJni6sw+h/94ySa
------END CERTIFICATE-----
-#endif
-static const unsigned char kDERCert26[] = {
- 0x30, 0x82, 0x04, 0xa6, 0x30, 0x82, 0x03, 0x8e, 0xa0, 0x03, 0x02, 0x01,
- 0x02, 0x02, 0x10, 0x28, 0x1c, 0x89, 0x29, 0x66, 0x14, 0x43, 0x80, 0x42,
- 0x63, 0x55, 0x3a, 0x32, 0x40, 0xae, 0xb3, 0x30, 0x0d, 0x06, 0x09, 0x2a,
- 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x81,
- 0x98, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
- 0x55, 0x53, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13,
- 0x0d, 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x49, 0x6e,
- 0x63, 0x2e, 0x31, 0x39, 0x30, 0x37, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13,
- 0x30, 0x28, 0x63, 0x29, 0x20, 0x32, 0x30, 0x30, 0x38, 0x20, 0x47, 0x65,
- 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x20,
- 0x2d, 0x20, 0x46, 0x6f, 0x72, 0x20, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72,
- 0x69, 0x7a, 0x65, 0x64, 0x20, 0x75, 0x73, 0x65, 0x20, 0x6f, 0x6e, 0x6c,
- 0x79, 0x31, 0x36, 0x30, 0x34, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x2d,
- 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x50, 0x72, 0x69,
- 0x6d, 0x61, 0x72, 0x79, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69,
- 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f,
- 0x72, 0x69, 0x74, 0x79, 0x20, 0x2d, 0x20, 0x47, 0x33, 0x30, 0x1e, 0x17,
- 0x0d, 0x31, 0x35, 0x30, 0x36, 0x33, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
- 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x35, 0x30, 0x36, 0x32, 0x39, 0x32, 0x33,
- 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x47, 0x31, 0x0b, 0x30, 0x09, 0x06,
- 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x16, 0x30, 0x14,
- 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0d, 0x47, 0x65, 0x6f, 0x54, 0x72,
- 0x75, 0x73, 0x74, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x20, 0x30, 0x1e,
- 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x17, 0x52, 0x61, 0x70, 0x69, 0x64,
- 0x53, 0x53, 0x4c, 0x20, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, 0x20, 0x43,
- 0x41, 0x20, 0x2d, 0x20, 0x47, 0x34, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d,
- 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05,
- 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82,
- 0x01, 0x01, 0x00, 0xc0, 0x9e, 0x3a, 0x0f, 0x9a, 0xb2, 0xba, 0xd3, 0xd2,
- 0xdc, 0x15, 0xec, 0xd0, 0x30, 0x54, 0x59, 0x30, 0x4d, 0x40, 0x51, 0xae,
- 0x42, 0x71, 0x71, 0xd2, 0x8d, 0x53, 0x73, 0x81, 0xfe, 0xb8, 0xe0, 0xc4,
- 0x96, 0xc5, 0x8e, 0x7e, 0xc2, 0xf1, 0xb7, 0x63, 0x4a, 0xcf, 0xa7, 0x1e,
- 0x3f, 0xa8, 0xe7, 0xce, 0x53, 0xa0, 0xfa, 0x2d, 0xf7, 0xd6, 0xe6, 0xce,
- 0x70, 0x11, 0xa6, 0xee, 0xe1, 0x03, 0x52, 0xd2, 0x68, 0xde, 0x3d, 0x08,
- 0x0d, 0x87, 0xfd, 0x1c, 0xd7, 0x0b, 0x97, 0x62, 0x6d, 0x82, 0x30, 0x76,
- 0x1b, 0x47, 0x3a, 0xc4, 0xf7, 0xce, 0xed, 0x1d, 0x7c, 0x8c, 0xb7, 0x17,
- 0x8e, 0x53, 0x80, 0x1e, 0x1d, 0x0f, 0x5d, 0x8c, 0xf9, 0x90, 0xe4, 0x04,
- 0x1e, 0x02, 0x7e, 0xcb, 0xb0, 0x49, 0xef, 0xda, 0x52, 0x25, 0xfb, 0xfb,
- 0x67, 0xed, 0xdd, 0x84, 0x74, 0x59, 0x84, 0x0e, 0xf3, 0xde, 0x70, 0x66,
- 0x8d, 0xe4, 0x52, 0x38, 0xf7, 0x53, 0x5a, 0x37, 0x13, 0x67, 0x0b, 0x3e,
- 0xbb, 0xa8, 0x58, 0xb7, 0x2e, 0xed, 0xff, 0xb7, 0x5e, 0x11, 0x73, 0xb9,
- 0x77, 0x45, 0x52, 0x67, 0x46, 0xae, 0xc4, 0xdc, 0x24, 0x81, 0x89, 0x76,
- 0x0a, 0xca, 0xa1, 0x6c, 0x66, 0x73, 0x04, 0x82, 0xaa, 0xf5, 0x70, 0x6c,
- 0x5f, 0x1b, 0x9a, 0x00, 0x79, 0x46, 0xd6, 0x7f, 0x7a, 0x26, 0x17, 0x30,
- 0xcf, 0x39, 0x4b, 0x2c, 0x74, 0xd9, 0x89, 0x44, 0x76, 0x10, 0xd0, 0xed,
- 0xf7, 0x8b, 0xbb, 0x89, 0x05, 0x75, 0x4d, 0x0b, 0x0d, 0xb3, 0xda, 0xe9,
- 0xbf, 0xf1, 0x6a, 0x7d, 0x2a, 0x11, 0xdb, 0x1e, 0x9f, 0x8c, 0xe3, 0xc4,
- 0x06, 0x69, 0xe1, 0x1d, 0x88, 0x45, 0x39, 0xd1, 0x6e, 0x55, 0xd8, 0xaa,
- 0xb7, 0x9b, 0x6f, 0xea, 0xf4, 0xde, 0xac, 0x17, 0x11, 0x92, 0x5d, 0x40,
- 0x9b, 0x83, 0x7b, 0x9a, 0xe2, 0xf7, 0xa9, 0x02, 0x03, 0x01, 0x00, 0x01,
- 0xa3, 0x82, 0x01, 0x3a, 0x30, 0x82, 0x01, 0x36, 0x30, 0x2e, 0x06, 0x08,
- 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x22, 0x30, 0x20,
- 0x30, 0x1e, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01,
- 0x86, 0x12, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x67, 0x2e, 0x73,
- 0x79, 0x6d, 0x63, 0x64, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x12, 0x06, 0x03,
- 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01,
- 0xff, 0x02, 0x01, 0x00, 0x30, 0x49, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04,
- 0x42, 0x30, 0x40, 0x30, 0x3e, 0x06, 0x06, 0x67, 0x81, 0x0c, 0x01, 0x02,
- 0x01, 0x30, 0x34, 0x30, 0x32, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05,
- 0x07, 0x02, 0x01, 0x16, 0x26, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f,
- 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x67, 0x65, 0x6f, 0x74, 0x72, 0x75, 0x73,
- 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72,
- 0x63, 0x65, 0x73, 0x2f, 0x63, 0x70, 0x73, 0x30, 0x36, 0x06, 0x03, 0x55,
- 0x1d, 0x1f, 0x04, 0x2f, 0x30, 0x2d, 0x30, 0x2b, 0xa0, 0x29, 0xa0, 0x27,
- 0x86, 0x25, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x67, 0x2e, 0x73,
- 0x79, 0x6d, 0x63, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x47, 0x65, 0x6f,
- 0x54, 0x72, 0x75, 0x73, 0x74, 0x50, 0x43, 0x41, 0x2d, 0x47, 0x33, 0x2e,
- 0x63, 0x72, 0x6c, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04, 0x16,
- 0x30, 0x14, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x01,
- 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x02, 0x30, 0x0e,
- 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02,
- 0x01, 0x06, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04,
- 0x14, 0xf3, 0xb5, 0x56, 0x0c, 0xc4, 0x09, 0xb0, 0xb4, 0xcf, 0x1f, 0xaa,
- 0xf9, 0xdd, 0x23, 0x56, 0xf0, 0x77, 0xe8, 0xa1, 0xf9, 0x30, 0x1f, 0x06,
- 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0xc4, 0x79,
- 0xca, 0x8e, 0xa1, 0x4e, 0x03, 0x1d, 0x1c, 0xdc, 0x6b, 0xdb, 0x31, 0x5b,
- 0x94, 0x3e, 0x3f, 0x30, 0x7f, 0x2d, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
- 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01,
- 0x01, 0x00, 0xc3, 0x7e, 0xd8, 0x83, 0x4b, 0x04, 0x4c, 0x55, 0x29, 0x2a,
- 0x4f, 0x14, 0x9d, 0x9a, 0x6e, 0xde, 0x90, 0x70, 0xc1, 0xa4, 0x26, 0x4c,
- 0x88, 0x8e, 0x78, 0x48, 0xef, 0xbd, 0x9c, 0xb0, 0xa0, 0xf5, 0xf0, 0x66,
- 0xfc, 0xfe, 0x59, 0x26, 0xe1, 0x79, 0xef, 0xc8, 0xb7, 0x60, 0x64, 0xa8,
- 0x8b, 0x47, 0xea, 0x2f, 0xe0, 0x83, 0x99, 0xda, 0x41, 0x19, 0xd7, 0xc5,
- 0xbe, 0x05, 0xfa, 0xf2, 0x90, 0x11, 0xf0, 0x0a, 0xff, 0x6c, 0xdc, 0x05,
- 0xb4, 0xd8, 0x06, 0x6f, 0xa4, 0x6f, 0x8d, 0xbe, 0x20, 0x2b, 0x54, 0xdb,
- 0xf9, 0xa2, 0x45, 0x83, 0x9a, 0x1e, 0xa5, 0x21, 0x89, 0x35, 0x1d, 0x7c,
- 0x20, 0x5c, 0x17, 0xfd, 0x04, 0x2e, 0x45, 0xd8, 0xb2, 0xc6, 0xf8, 0x42,
- 0x99, 0xfc, 0x54, 0x08, 0x4e, 0x4b, 0x80, 0x5f, 0x39, 0x37, 0xba, 0x95,
- 0x4e, 0xa6, 0x37, 0x0a, 0x9e, 0x93, 0x5e, 0x87, 0x5b, 0xe9, 0x90, 0xd6,
- 0xa8, 0xb6, 0x65, 0x08, 0x8d, 0x61, 0x49, 0xeb, 0x83, 0x20, 0xa9, 0x5d,
- 0x1b, 0x16, 0x60, 0x62, 0x6b, 0x2f, 0x54, 0xfb, 0x5a, 0x02, 0x0d, 0x7a,
- 0x27, 0xe2, 0x4b, 0xe1, 0x05, 0x14, 0xc2, 0xe4, 0xe9, 0xf9, 0x70, 0xc0,
- 0xd9, 0xf7, 0x34, 0x65, 0x0e, 0xa2, 0x91, 0x4b, 0xac, 0x28, 0xf2, 0xb7,
- 0x08, 0x0f, 0x98, 0xca, 0xd7, 0x3e, 0x70, 0xb6, 0xc8, 0x0b, 0xf1, 0x8b,
- 0x9c, 0x51, 0xf8, 0xc6, 0x10, 0x6c, 0xd2, 0x53, 0x4f, 0x62, 0x8c, 0x11,
- 0x00, 0x3e, 0x88, 0xdf, 0xbf, 0xe6, 0xd2, 0xcc, 0x70, 0xbd, 0xed, 0x25,
- 0x9c, 0xfb, 0xdd, 0x24, 0x0a, 0xbd, 0x59, 0x91, 0x4a, 0x42, 0x03, 0x38,
- 0x12, 0x71, 0x32, 0x88, 0x76, 0xa0, 0x8e, 0x7c, 0xbb, 0x32, 0xef, 0x88,
- 0x2a, 0x1b, 0xd4, 0x6a, 0x6f, 0x50, 0xb9, 0x52, 0x67, 0x8b, 0xab, 0x30,
- 0xfa, 0x1f, 0xfd, 0xe3, 0x24, 0x9a,
-};
-
-#if 0
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number:
- e4:05:47:83:0e:0c:64:52:97:6f:7a:35:49:c0:dd:48
- Signature Algorithm: sha256WithRSAEncryption
- Issuer: C=PL, O=Unizeto Technologies S.A., OU=Certum Certification Authority, CN=Certum Trusted Network CA
- Validity
- Not Before: Jan 21 12:00:00 2015 GMT
- Not After : Jan 18 12:00:00 2025 GMT
- Subject: C=RU, O=Yandex LLC, OU=Yandex Certification Authority, CN=Yandex CA
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:a6:05:24:76:61:b9:9e:42:60:22:63:85:59:e5:
- 9d:88:0d:df:ef:21:64:5a:26:94:71:3a:a4:7f:2b:
- 53:c3:ac:7b:ba:95:42:6d:6a:5b:d6:7e:78:0c:67:
- 40:98:2f:6a:2d:d0:b7:18:3a:7e:99:60:01:e5:27:
- bf:ff:49:f5:cd:c4:58:c3:4c:e1:70:d5:fd:08:a8:
- 79:95:76:1c:0e:05:41:fa:bd:80:38:2a:87:4f:c1:
- 67:42:aa:17:a6:ee:a7:8c:8e:ef:2d:7f:7a:1d:05:
- 17:8f:7e:3b:92:35:f5:68:ed:93:03:55:23:4f:4b:
- a2:00:86:65:91:0f:eb:f6:3c:d5:db:6d:0e:ed:e8:
- 7c:3a:c8:ba:b7:53:c1:a4:d8:40:02:e5:b5:a2:ca:
- bf:da:9c:94:0d:fc:c5:1c:2a:59:88:62:57:93:2e:
- 11:f0:38:2c:7a:81:2a:f2:25:15:17:35:70:2c:4b:
- f7:23:4c:82:ef:33:9f:c2:9a:0b:a3:e2:5d:6b:38:
- 77:f9:60:33:cf:2e:7b:56:b7:13:93:1f:34:97:71:
- 99:76:02:46:35:14:7c:dc:ca:48:8a:0a:72:4b:78:
- 6d:82:34:96:13:45:cf:02:2f:50:13:39:43:89:c0:
- e1:74:d7:28:71:21:e5:aa:97:0e:ee:46:ec:93:f7:
- 23:7d
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Basic Constraints: critical
- CA:TRUE
- X509v3 Subject Key Identifier:
- 37:5C:E3:19:E0:B2:8E:A1:A8:4E:D2:CF:AB:D0:DC:E3:0B:5C:35:4D
- X509v3 Authority Key Identifier:
- keyid:08:76:CD:CB:07:FF:24:F6:C5:CD:ED:BB:90:BC:E2:84:37:46:75:F7
-
- X509v3 Key Usage: critical
- Certificate Sign, CRL Sign
- X509v3 CRL Distribution Points:
-
- Full Name:
- URI:http://crl.certum.pl/ctnca.crl
-
- Authority Information Access:
- OCSP - URI:http://subca.ocsp-certum.com
- CA Issuers - URI:http://repository.certum.pl/ctnca.cer
-
- X509v3 Certificate Policies:
- Policy: X509v3 Any Policy
- CPS: http://www.certum.pl/CPS
-
- Signature Algorithm: sha256WithRSAEncryption
- 02:5e:8e:7b:e0:66:a1:c6:ab:8b:18:1f:0e:b9:c4:cd:71:db:
- 44:5c:03:7d:65:ea:b8:47:b5:1e:ce:24:70:a0:7f:d3:df:66:
- 4b:8c:90:e2:a5:ed:9b:94:36:b4:a8:be:f0:74:8c:26:92:75:
- 9d:56:50:9e:ad:d0:1a:a0:df:a4:14:56:10:75:93:7a:c1:f4:
- 53:a0:76:74:2c:72:ba:b5:d1:c9:e2:dc:46:86:3f:1d:f6:33:
- 87:59:ec:9c:dc:2d:1e:4d:43:1a:ce:ba:d9:87:7e:e2:47:45:
- 72:3d:28:03:c9:0a:4d:e0:57:a3:5e:6e:7e:cc:5a:c8:c4:78:
- 01:57:68:7a:38:3b:53:36:e7:92:6d:8a:2c:2f:d7:8b:b6:34:
- a8:d1:b6:f8:5e:3b:ab:ed:a5:8f:39:6f:45:ad:cb:63:ed:6a:
- 64:c9:10:a7:03:08:12:53:b1:1c:af:ca:f7:53:fc:d8:29:4b:
- 1b:fb:38:cd:c0:63:ff:5f:e4:b9:8d:5e:aa:2b:d2:c3:22:35:
- 31:f6:30:0e:53:32:f4:93:c5:43:cb:c8:f0:15:56:8f:00:19:
- 87:ca:78:22:8d:a0:2e:db:2f:a0:c3:7e:29:5d:91:25:84:1d:
- 1d:39:ab:1b:c5:d6:91:fe:69:0e:46:80:bc:45:7b:35:53:2a:
- df:00:b6:77
------BEGIN CERTIFICATE-----
-MIIEqDCCA5CgAwIBAgIRAOQFR4MODGRSl296NUnA3UgwDQYJKoZIhvcNAQELBQAw
-fjELMAkGA1UEBhMCUEwxIjAgBgNVBAoTGVVuaXpldG8gVGVjaG5vbG9naWVzIFMu
-QS4xJzAlBgNVBAsTHkNlcnR1bSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEiMCAG
-A1UEAxMZQ2VydHVtIFRydXN0ZWQgTmV0d29yayBDQTAeFw0xNTAxMjExMjAwMDBa
-Fw0yNTAxMTgxMjAwMDBaMF8xCzAJBgNVBAYTAlJVMRMwEQYDVQQKEwpZYW5kZXgg
-TExDMScwJQYDVQQLEx5ZYW5kZXggQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxEjAQ
-BgNVBAMTCVlhbmRleCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
-AKYFJHZhuZ5CYCJjhVnlnYgN3+8hZFomlHE6pH8rU8Ose7qVQm1qW9Z+eAxnQJgv
-ai3Qtxg6fplgAeUnv/9J9c3EWMNM4XDV/QioeZV2HA4FQfq9gDgqh0/BZ0KqF6bu
-p4yO7y1/eh0FF49+O5I19WjtkwNVI09LogCGZZEP6/Y81dttDu3ofDrIurdTwaTY
-QALltaLKv9qclA38xRwqWYhiV5MuEfA4LHqBKvIlFRc1cCxL9yNMgu8zn8KaC6Pi
-XWs4d/lgM88ue1a3E5MfNJdxmXYCRjUUfNzKSIoKckt4bYI0lhNFzwIvUBM5Q4nA
-4XTXKHEh5aqXDu5G7JP3I30CAwEAAaOCAT4wggE6MA8GA1UdEwEB/wQFMAMBAf8w
-HQYDVR0OBBYEFDdc4xngso6hqE7Sz6vQ3OMLXDVNMB8GA1UdIwQYMBaAFAh2zcsH
-/yT2xc3tu5C84oQ3RnX3MA4GA1UdDwEB/wQEAwIBBjAvBgNVHR8EKDAmMCSgIqAg
-hh5odHRwOi8vY3JsLmNlcnR1bS5wbC9jdG5jYS5jcmwwawYIKwYBBQUHAQEEXzBd
-MCgGCCsGAQUFBzABhhxodHRwOi8vc3ViY2Eub2NzcC1jZXJ0dW0uY29tMDEGCCsG
-AQUFBzAChiVodHRwOi8vcmVwb3NpdG9yeS5jZXJ0dW0ucGwvY3RuY2EuY2VyMDkG
-A1UdIAQyMDAwLgYEVR0gADAmMCQGCCsGAQUFBwIBFhhodHRwOi8vd3d3LmNlcnR1
-bS5wbC9DUFMwDQYJKoZIhvcNAQELBQADggEBAAJejnvgZqHGq4sYHw65xM1x20Rc
-A31l6rhHtR7OJHCgf9PfZkuMkOKl7ZuUNrSovvB0jCaSdZ1WUJ6t0Bqg36QUVhB1
-k3rB9FOgdnQscrq10cni3EaGPx32M4dZ7JzcLR5NQxrOutmHfuJHRXI9KAPJCk3g
-V6Nebn7MWsjEeAFXaHo4O1M255Jtiiwv14u2NKjRtvheO6vtpY85b0Wty2PtamTJ
-EKcDCBJTsRyvyvdT/NgpSxv7OM3AY/9f5LmNXqor0sMiNTH2MA5TMvSTxUPLyPAV
-Vo8AGYfKeCKNoC7bL6DDfildkSWEHR05qxvF1pH+aQ5GgLxFezVTKt8Atnc=
------END CERTIFICATE-----
-#endif
-static const unsigned char kDERCert27[] = {
- 0x30, 0x82, 0x04, 0xa8, 0x30, 0x82, 0x03, 0x90, 0xa0, 0x03, 0x02, 0x01,
- 0x02, 0x02, 0x11, 0x00, 0xe4, 0x05, 0x47, 0x83, 0x0e, 0x0c, 0x64, 0x52,
- 0x97, 0x6f, 0x7a, 0x35, 0x49, 0xc0, 0xdd, 0x48, 0x30, 0x0d, 0x06, 0x09,
- 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30,
- 0x7e, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
- 0x50, 0x4c, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13,
- 0x19, 0x55, 0x6e, 0x69, 0x7a, 0x65, 0x74, 0x6f, 0x20, 0x54, 0x65, 0x63,
- 0x68, 0x6e, 0x6f, 0x6c, 0x6f, 0x67, 0x69, 0x65, 0x73, 0x20, 0x53, 0x2e,
- 0x41, 0x2e, 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13,
- 0x1e, 0x43, 0x65, 0x72, 0x74, 0x75, 0x6d, 0x20, 0x43, 0x65, 0x72, 0x74,
- 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75,
- 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31, 0x22, 0x30, 0x20, 0x06,
- 0x03, 0x55, 0x04, 0x03, 0x13, 0x19, 0x43, 0x65, 0x72, 0x74, 0x75, 0x6d,
- 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x20, 0x4e, 0x65, 0x74,
- 0x77, 0x6f, 0x72, 0x6b, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31,
- 0x35, 0x30, 0x31, 0x32, 0x31, 0x31, 0x32, 0x30, 0x30, 0x30, 0x30, 0x5a,
- 0x17, 0x0d, 0x32, 0x35, 0x30, 0x31, 0x31, 0x38, 0x31, 0x32, 0x30, 0x30,
- 0x30, 0x30, 0x5a, 0x30, 0x5f, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55,
- 0x04, 0x06, 0x13, 0x02, 0x52, 0x55, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03,
- 0x55, 0x04, 0x0a, 0x13, 0x0a, 0x59, 0x61, 0x6e, 0x64, 0x65, 0x78, 0x20,
- 0x4c, 0x4c, 0x43, 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x0b,
- 0x13, 0x1e, 0x59, 0x61, 0x6e, 0x64, 0x65, 0x78, 0x20, 0x43, 0x65, 0x72,
- 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41,
- 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31, 0x12, 0x30, 0x10,
- 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x09, 0x59, 0x61, 0x6e, 0x64, 0x65,
- 0x78, 0x20, 0x43, 0x41, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09,
- 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03,
- 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01,
- 0x00, 0xa6, 0x05, 0x24, 0x76, 0x61, 0xb9, 0x9e, 0x42, 0x60, 0x22, 0x63,
- 0x85, 0x59, 0xe5, 0x9d, 0x88, 0x0d, 0xdf, 0xef, 0x21, 0x64, 0x5a, 0x26,
- 0x94, 0x71, 0x3a, 0xa4, 0x7f, 0x2b, 0x53, 0xc3, 0xac, 0x7b, 0xba, 0x95,
- 0x42, 0x6d, 0x6a, 0x5b, 0xd6, 0x7e, 0x78, 0x0c, 0x67, 0x40, 0x98, 0x2f,
- 0x6a, 0x2d, 0xd0, 0xb7, 0x18, 0x3a, 0x7e, 0x99, 0x60, 0x01, 0xe5, 0x27,
- 0xbf, 0xff, 0x49, 0xf5, 0xcd, 0xc4, 0x58, 0xc3, 0x4c, 0xe1, 0x70, 0xd5,
- 0xfd, 0x08, 0xa8, 0x79, 0x95, 0x76, 0x1c, 0x0e, 0x05, 0x41, 0xfa, 0xbd,
- 0x80, 0x38, 0x2a, 0x87, 0x4f, 0xc1, 0x67, 0x42, 0xaa, 0x17, 0xa6, 0xee,
- 0xa7, 0x8c, 0x8e, 0xef, 0x2d, 0x7f, 0x7a, 0x1d, 0x05, 0x17, 0x8f, 0x7e,
- 0x3b, 0x92, 0x35, 0xf5, 0x68, 0xed, 0x93, 0x03, 0x55, 0x23, 0x4f, 0x4b,
- 0xa2, 0x00, 0x86, 0x65, 0x91, 0x0f, 0xeb, 0xf6, 0x3c, 0xd5, 0xdb, 0x6d,
- 0x0e, 0xed, 0xe8, 0x7c, 0x3a, 0xc8, 0xba, 0xb7, 0x53, 0xc1, 0xa4, 0xd8,
- 0x40, 0x02, 0xe5, 0xb5, 0xa2, 0xca, 0xbf, 0xda, 0x9c, 0x94, 0x0d, 0xfc,
- 0xc5, 0x1c, 0x2a, 0x59, 0x88, 0x62, 0x57, 0x93, 0x2e, 0x11, 0xf0, 0x38,
- 0x2c, 0x7a, 0x81, 0x2a, 0xf2, 0x25, 0x15, 0x17, 0x35, 0x70, 0x2c, 0x4b,
- 0xf7, 0x23, 0x4c, 0x82, 0xef, 0x33, 0x9f, 0xc2, 0x9a, 0x0b, 0xa3, 0xe2,
- 0x5d, 0x6b, 0x38, 0x77, 0xf9, 0x60, 0x33, 0xcf, 0x2e, 0x7b, 0x56, 0xb7,
- 0x13, 0x93, 0x1f, 0x34, 0x97, 0x71, 0x99, 0x76, 0x02, 0x46, 0x35, 0x14,
- 0x7c, 0xdc, 0xca, 0x48, 0x8a, 0x0a, 0x72, 0x4b, 0x78, 0x6d, 0x82, 0x34,
- 0x96, 0x13, 0x45, 0xcf, 0x02, 0x2f, 0x50, 0x13, 0x39, 0x43, 0x89, 0xc0,
- 0xe1, 0x74, 0xd7, 0x28, 0x71, 0x21, 0xe5, 0xaa, 0x97, 0x0e, 0xee, 0x46,
- 0xec, 0x93, 0xf7, 0x23, 0x7d, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82,
- 0x01, 0x3e, 0x30, 0x82, 0x01, 0x3a, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d,
- 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30,
- 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x37, 0x5c,
- 0xe3, 0x19, 0xe0, 0xb2, 0x8e, 0xa1, 0xa8, 0x4e, 0xd2, 0xcf, 0xab, 0xd0,
- 0xdc, 0xe3, 0x0b, 0x5c, 0x35, 0x4d, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d,
- 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x08, 0x76, 0xcd, 0xcb, 0x07,
- 0xff, 0x24, 0xf6, 0xc5, 0xcd, 0xed, 0xbb, 0x90, 0xbc, 0xe2, 0x84, 0x37,
- 0x46, 0x75, 0xf7, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01,
- 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x2f, 0x06, 0x03, 0x55,
- 0x1d, 0x1f, 0x04, 0x28, 0x30, 0x26, 0x30, 0x24, 0xa0, 0x22, 0xa0, 0x20,
- 0x86, 0x1e, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c,
- 0x2e, 0x63, 0x65, 0x72, 0x74, 0x75, 0x6d, 0x2e, 0x70, 0x6c, 0x2f, 0x63,
- 0x74, 0x6e, 0x63, 0x61, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x6b, 0x06, 0x08,
- 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x5f, 0x30, 0x5d,
- 0x30, 0x28, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01,
- 0x86, 0x1c, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x73, 0x75, 0x62,
- 0x63, 0x61, 0x2e, 0x6f, 0x63, 0x73, 0x70, 0x2d, 0x63, 0x65, 0x72, 0x74,
- 0x75, 0x6d, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x31, 0x06, 0x08, 0x2b, 0x06,
- 0x01, 0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x25, 0x68, 0x74, 0x74, 0x70,
- 0x3a, 0x2f, 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72,
- 0x79, 0x2e, 0x63, 0x65, 0x72, 0x74, 0x75, 0x6d, 0x2e, 0x70, 0x6c, 0x2f,
- 0x63, 0x74, 0x6e, 0x63, 0x61, 0x2e, 0x63, 0x65, 0x72, 0x30, 0x39, 0x06,
- 0x03, 0x55, 0x1d, 0x20, 0x04, 0x32, 0x30, 0x30, 0x30, 0x2e, 0x06, 0x04,
- 0x55, 0x1d, 0x20, 0x00, 0x30, 0x26, 0x30, 0x24, 0x06, 0x08, 0x2b, 0x06,
- 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x18, 0x68, 0x74, 0x74, 0x70,
- 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x63, 0x65, 0x72, 0x74, 0x75,
- 0x6d, 0x2e, 0x70, 0x6c, 0x2f, 0x43, 0x50, 0x53, 0x30, 0x0d, 0x06, 0x09,
- 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03,
- 0x82, 0x01, 0x01, 0x00, 0x02, 0x5e, 0x8e, 0x7b, 0xe0, 0x66, 0xa1, 0xc6,
- 0xab, 0x8b, 0x18, 0x1f, 0x0e, 0xb9, 0xc4, 0xcd, 0x71, 0xdb, 0x44, 0x5c,
- 0x03, 0x7d, 0x65, 0xea, 0xb8, 0x47, 0xb5, 0x1e, 0xce, 0x24, 0x70, 0xa0,
- 0x7f, 0xd3, 0xdf, 0x66, 0x4b, 0x8c, 0x90, 0xe2, 0xa5, 0xed, 0x9b, 0x94,
- 0x36, 0xb4, 0xa8, 0xbe, 0xf0, 0x74, 0x8c, 0x26, 0x92, 0x75, 0x9d, 0x56,
- 0x50, 0x9e, 0xad, 0xd0, 0x1a, 0xa0, 0xdf, 0xa4, 0x14, 0x56, 0x10, 0x75,
- 0x93, 0x7a, 0xc1, 0xf4, 0x53, 0xa0, 0x76, 0x74, 0x2c, 0x72, 0xba, 0xb5,
- 0xd1, 0xc9, 0xe2, 0xdc, 0x46, 0x86, 0x3f, 0x1d, 0xf6, 0x33, 0x87, 0x59,
- 0xec, 0x9c, 0xdc, 0x2d, 0x1e, 0x4d, 0x43, 0x1a, 0xce, 0xba, 0xd9, 0x87,
- 0x7e, 0xe2, 0x47, 0x45, 0x72, 0x3d, 0x28, 0x03, 0xc9, 0x0a, 0x4d, 0xe0,
- 0x57, 0xa3, 0x5e, 0x6e, 0x7e, 0xcc, 0x5a, 0xc8, 0xc4, 0x78, 0x01, 0x57,
- 0x68, 0x7a, 0x38, 0x3b, 0x53, 0x36, 0xe7, 0x92, 0x6d, 0x8a, 0x2c, 0x2f,
- 0xd7, 0x8b, 0xb6, 0x34, 0xa8, 0xd1, 0xb6, 0xf8, 0x5e, 0x3b, 0xab, 0xed,
- 0xa5, 0x8f, 0x39, 0x6f, 0x45, 0xad, 0xcb, 0x63, 0xed, 0x6a, 0x64, 0xc9,
- 0x10, 0xa7, 0x03, 0x08, 0x12, 0x53, 0xb1, 0x1c, 0xaf, 0xca, 0xf7, 0x53,
- 0xfc, 0xd8, 0x29, 0x4b, 0x1b, 0xfb, 0x38, 0xcd, 0xc0, 0x63, 0xff, 0x5f,
- 0xe4, 0xb9, 0x8d, 0x5e, 0xaa, 0x2b, 0xd2, 0xc3, 0x22, 0x35, 0x31, 0xf6,
- 0x30, 0x0e, 0x53, 0x32, 0xf4, 0x93, 0xc5, 0x43, 0xcb, 0xc8, 0xf0, 0x15,
- 0x56, 0x8f, 0x00, 0x19, 0x87, 0xca, 0x78, 0x22, 0x8d, 0xa0, 0x2e, 0xdb,
- 0x2f, 0xa0, 0xc3, 0x7e, 0x29, 0x5d, 0x91, 0x25, 0x84, 0x1d, 0x1d, 0x39,
- 0xab, 0x1b, 0xc5, 0xd6, 0x91, 0xfe, 0x69, 0x0e, 0x46, 0x80, 0xbc, 0x45,
- 0x7b, 0x35, 0x53, 0x2a, 0xdf, 0x00, 0xb6, 0x77,
-};
-
-#if 0
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number:
- 5d:72:fb:33:76:20:f6:4c:72:80:db:e9:12:81:ff:6a
- Signature Algorithm: sha256WithRSAEncryption
- Issuer: C=US, O=thawte, Inc., OU=Certification Services Division, OU=(c) 2006 thawte, Inc. - For authorized use only, CN=thawte Primary Root CA
- Validity
- Not Before: Oct 31 00:00:00 2013 GMT
- Not After : Oct 30 23:59:59 2023 GMT
- Subject: C=US, O=thawte, Inc., CN=thawte EV SSL CA - G3
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:c4:dd:da:94:1e:32:b2:2e:a0:83:c0:a6:7d:5f:
- 65:2d:fd:27:b8:73:0e:f8:0b:a9:d4:56:26:69:98:
- 67:35:39:64:58:ce:82:6f:98:94:d1:8f:e0:90:d6:
- ed:55:4b:98:4b:d7:10:59:34:02:1b:e7:51:31:51:
- c4:38:c2:bc:db:03:5c:ca:e1:7c:dc:4f:59:97:ea:
- 07:7f:0f:85:3e:92:ea:aa:a7:d9:be:01:41:e4:62:
- 56:47:36:bd:57:91:e6:21:d3:f8:41:0b:d8:ba:e8:
- ed:81:ad:70:c0:8b:6e:f3:89:6e:27:9e:a6:a6:73:
- 59:bb:71:00:d4:4f:4b:48:e9:d5:c9:27:36:9c:7c:
- 1c:02:aa:ac:bd:3b:d1:53:83:6a:1f:e6:08:47:33:
- a7:b1:9f:02:be:9b:47:ed:33:04:dc:1c:80:27:d1:
- 4a:33:a0:8c:eb:01:47:a1:32:90:64:7b:c4:e0:84:
- c9:32:e9:dd:34:1f:8a:68:67:f3:ad:10:63:eb:ee:
- 8a:9a:b1:2a:1b:26:74:a1:2a:b0:8f:fe:52:98:46:
- 97:cf:a3:56:1c:6f:6e:99:97:8d:26:0e:a9:ec:c2:
- 53:70:fc:7a:a5:19:49:bd:b5:17:82:55:de:97:e0:
- 5d:62:84:81:f0:70:a8:34:53:4f:14:fd:3d:5d:3d:
- 6f:b9
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Basic Constraints: critical
- CA:TRUE, pathlen:0
- X509v3 Key Usage: critical
- Certificate Sign, CRL Sign
- Authority Information Access:
- OCSP - URI:http://t2.symcb.com
-
- X509v3 Certificate Policies:
- Policy: X509v3 Any Policy
- CPS: https://www.thawte.com/cps
-
- X509v3 CRL Distribution Points:
-
- Full Name:
- URI:http://t1.symcb.com/ThawtePCA.crl
-
- X509v3 Subject Alternative Name:
- DirName:/CN=SymantecPKI-1-536
- X509v3 Subject Key Identifier:
- F0:70:51:DA:D3:2A:91:4F:52:77:D7:86:77:74:0F:CE:71:1A:6C:22
- X509v3 Authority Key Identifier:
- keyid:7B:5B:45:CF:AF:CE:CB:7A:FD:31:92:1A:6A:B6:F3:46:EB:57:48:50
-
- Signature Algorithm: sha256WithRSAEncryption
- a1:2e:94:3e:9b:16:f4:58:1a:6f:c1:fa:c1:7e:43:93:b2:c3:
- f7:89:eb:13:62:5d:dd:cc:61:13:2b:1d:4e:88:79:11:62:14:
- 37:30:46:ff:89:62:10:85:2a:87:1e:f8:e2:af:fe:93:02:93:
- ca:f2:e9:46:03:6b:a1:1a:ac:d5:f0:80:1b:98:6f:b8:3a:50:
- f8:54:71:06:03:e7:84:cc:8e:61:d2:5f:4d:0c:97:02:65:b5:
- 8c:26:bc:05:98:f4:dc:c6:af:e4:57:7f:e3:dc:a1:d7:27:47:
- 2a:e0:2c:3f:09:74:dc:5a:e5:b5:7c:fa:82:9a:15:fa:74:2b:
- 84:2e:6b:ac:ef:35:a6:30:fa:47:4a:aa:36:44:f6:5a:91:07:
- d3:e4:4e:97:3f:a6:53:d8:29:33:32:6f:8b:3d:b5:a5:0d:e5:
- e4:8a:e8:f5:c0:fa:af:d8:37:28:27:c3:ed:34:31:d9:7c:a6:
- af:4d:12:4f:d0:2b:92:9c:69:95:f2:28:a6:fe:a8:c6:e0:2c:
- 4d:36:eb:11:34:d6:e1:81:99:9d:41:f2:e7:c5:57:05:0e:19:
- ca:af:42:39:1f:a7:27:5e:e0:0a:17:b8:ae:47:ab:92:f1:8a:
- 04:df:30:e0:bb:4f:8a:f9:1b:88:4f:03:b4:25:7a:78:de:2e:
- 7d:29:d1:31
------BEGIN CERTIFICATE-----
-MIIErzCCA5egAwIBAgIQXXL7M3Yg9kxygNvpEoH/ajANBgkqhkiG9w0BAQsFADCB
-qTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMf
-Q2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIw
-MDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxHzAdBgNV
-BAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwHhcNMTMxMDMxMDAwMDAwWhcNMjMx
-MDMwMjM1OTU5WjBEMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMdGhhd3RlLCBJbmMu
-MR4wHAYDVQQDExV0aGF3dGUgRVYgU1NMIENBIC0gRzMwggEiMA0GCSqGSIb3DQEB
-AQUAA4IBDwAwggEKAoIBAQDE3dqUHjKyLqCDwKZ9X2Ut/Se4cw74C6nUViZpmGc1
-OWRYzoJvmJTRj+CQ1u1VS5hL1xBZNAIb51ExUcQ4wrzbA1zK4XzcT1mX6gd/D4U+
-kuqqp9m+AUHkYlZHNr1XkeYh0/hBC9i66O2BrXDAi27ziW4nnqamc1m7cQDUT0tI
-6dXJJzacfBwCqqy9O9FTg2of5ghHM6exnwK+m0ftMwTcHIAn0UozoIzrAUehMpBk
-e8TghMky6d00H4poZ/OtEGPr7oqasSobJnShKrCP/lKYRpfPo1Ycb26Zl40mDqns
-wlNw/HqlGUm9tReCVd6X4F1ihIHwcKg0U08U/T1dPW+5AgMBAAGjggE1MIIBMTAS
-BgNVHRMBAf8ECDAGAQH/AgEAMA4GA1UdDwEB/wQEAwIBBjAvBggrBgEFBQcBAQQj
-MCEwHwYIKwYBBQUHMAGGE2h0dHA6Ly90Mi5zeW1jYi5jb20wOwYDVR0gBDQwMjAw
-BgRVHSAAMCgwJgYIKwYBBQUHAgEWGmh0dHBzOi8vd3d3LnRoYXd0ZS5jb20vY3Bz
-MDIGA1UdHwQrMCkwJ6AloCOGIWh0dHA6Ly90MS5zeW1jYi5jb20vVGhhd3RlUENB
-LmNybDApBgNVHREEIjAgpB4wHDEaMBgGA1UEAxMRU3ltYW50ZWNQS0ktMS01MzYw
-HQYDVR0OBBYEFPBwUdrTKpFPUnfXhnd0D85xGmwiMB8GA1UdIwQYMBaAFHtbRc+v
-zst6/TGSGmq280brV0hQMA0GCSqGSIb3DQEBCwUAA4IBAQChLpQ+mxb0WBpvwfrB
-fkOTssP3iesTYl3dzGETKx1OiHkRYhQ3MEb/iWIQhSqHHvjir/6TApPK8ulGA2uh
-GqzV8IAbmG+4OlD4VHEGA+eEzI5h0l9NDJcCZbWMJrwFmPTcxq/kV3/j3KHXJ0cq
-4Cw/CXTcWuW1fPqCmhX6dCuELmus7zWmMPpHSqo2RPZakQfT5E6XP6ZT2CkzMm+L
-PbWlDeXkiuj1wPqv2DcoJ8PtNDHZfKavTRJP0CuSnGmV8iim/qjG4CxNNusRNNbh
-gZmdQfLnxVcFDhnKr0I5H6cnXuAKF7iuR6uS8YoE3zDgu0+K+RuITwO0JXp43i59
-KdEx
------END CERTIFICATE-----
-#endif
-static const unsigned char kDERCert28[] = {
- 0x30, 0x82, 0x04, 0xaf, 0x30, 0x82, 0x03, 0x97, 0xa0, 0x03, 0x02, 0x01,
- 0x02, 0x02, 0x10, 0x5d, 0x72, 0xfb, 0x33, 0x76, 0x20, 0xf6, 0x4c, 0x72,
- 0x80, 0xdb, 0xe9, 0x12, 0x81, 0xff, 0x6a, 0x30, 0x0d, 0x06, 0x09, 0x2a,
- 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x81,
- 0xa9, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
- 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13,
- 0x0c, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63,
- 0x2e, 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1f,
- 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f,
- 0x6e, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, 0x44,
- 0x69, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x31, 0x38, 0x30, 0x36, 0x06,
- 0x03, 0x55, 0x04, 0x0b, 0x13, 0x2f, 0x28, 0x63, 0x29, 0x20, 0x32, 0x30,
- 0x30, 0x36, 0x20, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2c, 0x20, 0x49,
- 0x6e, 0x63, 0x2e, 0x20, 0x2d, 0x20, 0x46, 0x6f, 0x72, 0x20, 0x61, 0x75,
- 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x20, 0x75, 0x73, 0x65,
- 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55,
- 0x04, 0x03, 0x13, 0x16, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x20, 0x50,
- 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20,
- 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x33, 0x31, 0x30, 0x33, 0x31,
- 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x33, 0x31,
- 0x30, 0x33, 0x30, 0x32, 0x33, 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x44,
- 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55,
- 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0c,
- 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e,
- 0x31, 0x1e, 0x30, 0x1c, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x15, 0x74,
- 0x68, 0x61, 0x77, 0x74, 0x65, 0x20, 0x45, 0x56, 0x20, 0x53, 0x53, 0x4c,
- 0x20, 0x43, 0x41, 0x20, 0x2d, 0x20, 0x47, 0x33, 0x30, 0x82, 0x01, 0x22,
- 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
- 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a,
- 0x02, 0x82, 0x01, 0x01, 0x00, 0xc4, 0xdd, 0xda, 0x94, 0x1e, 0x32, 0xb2,
- 0x2e, 0xa0, 0x83, 0xc0, 0xa6, 0x7d, 0x5f, 0x65, 0x2d, 0xfd, 0x27, 0xb8,
- 0x73, 0x0e, 0xf8, 0x0b, 0xa9, 0xd4, 0x56, 0x26, 0x69, 0x98, 0x67, 0x35,
- 0x39, 0x64, 0x58, 0xce, 0x82, 0x6f, 0x98, 0x94, 0xd1, 0x8f, 0xe0, 0x90,
- 0xd6, 0xed, 0x55, 0x4b, 0x98, 0x4b, 0xd7, 0x10, 0x59, 0x34, 0x02, 0x1b,
- 0xe7, 0x51, 0x31, 0x51, 0xc4, 0x38, 0xc2, 0xbc, 0xdb, 0x03, 0x5c, 0xca,
- 0xe1, 0x7c, 0xdc, 0x4f, 0x59, 0x97, 0xea, 0x07, 0x7f, 0x0f, 0x85, 0x3e,
- 0x92, 0xea, 0xaa, 0xa7, 0xd9, 0xbe, 0x01, 0x41, 0xe4, 0x62, 0x56, 0x47,
- 0x36, 0xbd, 0x57, 0x91, 0xe6, 0x21, 0xd3, 0xf8, 0x41, 0x0b, 0xd8, 0xba,
- 0xe8, 0xed, 0x81, 0xad, 0x70, 0xc0, 0x8b, 0x6e, 0xf3, 0x89, 0x6e, 0x27,
- 0x9e, 0xa6, 0xa6, 0x73, 0x59, 0xbb, 0x71, 0x00, 0xd4, 0x4f, 0x4b, 0x48,
- 0xe9, 0xd5, 0xc9, 0x27, 0x36, 0x9c, 0x7c, 0x1c, 0x02, 0xaa, 0xac, 0xbd,
- 0x3b, 0xd1, 0x53, 0x83, 0x6a, 0x1f, 0xe6, 0x08, 0x47, 0x33, 0xa7, 0xb1,
- 0x9f, 0x02, 0xbe, 0x9b, 0x47, 0xed, 0x33, 0x04, 0xdc, 0x1c, 0x80, 0x27,
- 0xd1, 0x4a, 0x33, 0xa0, 0x8c, 0xeb, 0x01, 0x47, 0xa1, 0x32, 0x90, 0x64,
- 0x7b, 0xc4, 0xe0, 0x84, 0xc9, 0x32, 0xe9, 0xdd, 0x34, 0x1f, 0x8a, 0x68,
- 0x67, 0xf3, 0xad, 0x10, 0x63, 0xeb, 0xee, 0x8a, 0x9a, 0xb1, 0x2a, 0x1b,
- 0x26, 0x74, 0xa1, 0x2a, 0xb0, 0x8f, 0xfe, 0x52, 0x98, 0x46, 0x97, 0xcf,
- 0xa3, 0x56, 0x1c, 0x6f, 0x6e, 0x99, 0x97, 0x8d, 0x26, 0x0e, 0xa9, 0xec,
- 0xc2, 0x53, 0x70, 0xfc, 0x7a, 0xa5, 0x19, 0x49, 0xbd, 0xb5, 0x17, 0x82,
- 0x55, 0xde, 0x97, 0xe0, 0x5d, 0x62, 0x84, 0x81, 0xf0, 0x70, 0xa8, 0x34,
- 0x53, 0x4f, 0x14, 0xfd, 0x3d, 0x5d, 0x3d, 0x6f, 0xb9, 0x02, 0x03, 0x01,
- 0x00, 0x01, 0xa3, 0x82, 0x01, 0x35, 0x30, 0x82, 0x01, 0x31, 0x30, 0x12,
- 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06,
- 0x01, 0x01, 0xff, 0x02, 0x01, 0x00, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d,
- 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x2f,
- 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x23,
- 0x30, 0x21, 0x30, 0x1f, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
- 0x30, 0x01, 0x86, 0x13, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x74,
- 0x32, 0x2e, 0x73, 0x79, 0x6d, 0x63, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x30,
- 0x3b, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x34, 0x30, 0x32, 0x30, 0x30,
- 0x06, 0x04, 0x55, 0x1d, 0x20, 0x00, 0x30, 0x28, 0x30, 0x26, 0x06, 0x08,
- 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x1a, 0x68, 0x74,
- 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x74, 0x68,
- 0x61, 0x77, 0x74, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x70, 0x73,
- 0x30, 0x32, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x2b, 0x30, 0x29, 0x30,
- 0x27, 0xa0, 0x25, 0xa0, 0x23, 0x86, 0x21, 0x68, 0x74, 0x74, 0x70, 0x3a,
- 0x2f, 0x2f, 0x74, 0x31, 0x2e, 0x73, 0x79, 0x6d, 0x63, 0x62, 0x2e, 0x63,
- 0x6f, 0x6d, 0x2f, 0x54, 0x68, 0x61, 0x77, 0x74, 0x65, 0x50, 0x43, 0x41,
- 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x29, 0x06, 0x03, 0x55, 0x1d, 0x11, 0x04,
- 0x22, 0x30, 0x20, 0xa4, 0x1e, 0x30, 0x1c, 0x31, 0x1a, 0x30, 0x18, 0x06,
- 0x03, 0x55, 0x04, 0x03, 0x13, 0x11, 0x53, 0x79, 0x6d, 0x61, 0x6e, 0x74,
- 0x65, 0x63, 0x50, 0x4b, 0x49, 0x2d, 0x31, 0x2d, 0x35, 0x33, 0x36, 0x30,
- 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xf0, 0x70,
- 0x51, 0xda, 0xd3, 0x2a, 0x91, 0x4f, 0x52, 0x77, 0xd7, 0x86, 0x77, 0x74,
- 0x0f, 0xce, 0x71, 0x1a, 0x6c, 0x22, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d,
- 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x7b, 0x5b, 0x45, 0xcf, 0xaf,
- 0xce, 0xcb, 0x7a, 0xfd, 0x31, 0x92, 0x1a, 0x6a, 0xb6, 0xf3, 0x46, 0xeb,
- 0x57, 0x48, 0x50, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
- 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0xa1,
- 0x2e, 0x94, 0x3e, 0x9b, 0x16, 0xf4, 0x58, 0x1a, 0x6f, 0xc1, 0xfa, 0xc1,
- 0x7e, 0x43, 0x93, 0xb2, 0xc3, 0xf7, 0x89, 0xeb, 0x13, 0x62, 0x5d, 0xdd,
- 0xcc, 0x61, 0x13, 0x2b, 0x1d, 0x4e, 0x88, 0x79, 0x11, 0x62, 0x14, 0x37,
- 0x30, 0x46, 0xff, 0x89, 0x62, 0x10, 0x85, 0x2a, 0x87, 0x1e, 0xf8, 0xe2,
- 0xaf, 0xfe, 0x93, 0x02, 0x93, 0xca, 0xf2, 0xe9, 0x46, 0x03, 0x6b, 0xa1,
- 0x1a, 0xac, 0xd5, 0xf0, 0x80, 0x1b, 0x98, 0x6f, 0xb8, 0x3a, 0x50, 0xf8,
- 0x54, 0x71, 0x06, 0x03, 0xe7, 0x84, 0xcc, 0x8e, 0x61, 0xd2, 0x5f, 0x4d,
- 0x0c, 0x97, 0x02, 0x65, 0xb5, 0x8c, 0x26, 0xbc, 0x05, 0x98, 0xf4, 0xdc,
- 0xc6, 0xaf, 0xe4, 0x57, 0x7f, 0xe3, 0xdc, 0xa1, 0xd7, 0x27, 0x47, 0x2a,
- 0xe0, 0x2c, 0x3f, 0x09, 0x74, 0xdc, 0x5a, 0xe5, 0xb5, 0x7c, 0xfa, 0x82,
- 0x9a, 0x15, 0xfa, 0x74, 0x2b, 0x84, 0x2e, 0x6b, 0xac, 0xef, 0x35, 0xa6,
- 0x30, 0xfa, 0x47, 0x4a, 0xaa, 0x36, 0x44, 0xf6, 0x5a, 0x91, 0x07, 0xd3,
- 0xe4, 0x4e, 0x97, 0x3f, 0xa6, 0x53, 0xd8, 0x29, 0x33, 0x32, 0x6f, 0x8b,
- 0x3d, 0xb5, 0xa5, 0x0d, 0xe5, 0xe4, 0x8a, 0xe8, 0xf5, 0xc0, 0xfa, 0xaf,
- 0xd8, 0x37, 0x28, 0x27, 0xc3, 0xed, 0x34, 0x31, 0xd9, 0x7c, 0xa6, 0xaf,
- 0x4d, 0x12, 0x4f, 0xd0, 0x2b, 0x92, 0x9c, 0x69, 0x95, 0xf2, 0x28, 0xa6,
- 0xfe, 0xa8, 0xc6, 0xe0, 0x2c, 0x4d, 0x36, 0xeb, 0x11, 0x34, 0xd6, 0xe1,
- 0x81, 0x99, 0x9d, 0x41, 0xf2, 0xe7, 0xc5, 0x57, 0x05, 0x0e, 0x19, 0xca,
- 0xaf, 0x42, 0x39, 0x1f, 0xa7, 0x27, 0x5e, 0xe0, 0x0a, 0x17, 0xb8, 0xae,
- 0x47, 0xab, 0x92, 0xf1, 0x8a, 0x04, 0xdf, 0x30, 0xe0, 0xbb, 0x4f, 0x8a,
- 0xf9, 0x1b, 0x88, 0x4f, 0x03, 0xb4, 0x25, 0x7a, 0x78, 0xde, 0x2e, 0x7d,
- 0x29, 0xd1, 0x31,
-};
-
-#if 0
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number:
- 04:e1:e7:a4:dc:5c:f2:f3:6d:c0:2b:42:b8:5d:15:9f
- Signature Algorithm: sha256WithRSAEncryption
- Issuer: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert High Assurance EV Root CA
- Validity
- Not Before: Oct 22 12:00:00 2013 GMT
- Not After : Oct 22 12:00:00 2028 GMT
- Subject: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert SHA2 High Assurance Server CA
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:b6:e0:2f:c2:24:06:c8:6d:04:5f:d7:ef:0a:64:
- 06:b2:7d:22:26:65:16:ae:42:40:9b:ce:dc:9f:9f:
- 76:07:3e:c3:30:55:87:19:b9:4f:94:0e:5a:94:1f:
- 55:56:b4:c2:02:2a:af:d0:98:ee:0b:40:d7:c4:d0:
- 3b:72:c8:14:9e:ef:90:b1:11:a9:ae:d2:c8:b8:43:
- 3a:d9:0b:0b:d5:d5:95:f5:40:af:c8:1d:ed:4d:9c:
- 5f:57:b7:86:50:68:99:f5:8a:da:d2:c7:05:1f:a8:
- 97:c9:dc:a4:b1:82:84:2d:c6:ad:a5:9c:c7:19:82:
- a6:85:0f:5e:44:58:2a:37:8f:fd:35:f1:0b:08:27:
- 32:5a:f5:bb:8b:9e:a4:bd:51:d0:27:e2:dd:3b:42:
- 33:a3:05:28:c4:bb:28:cc:9a:ac:2b:23:0d:78:c6:
- 7b:e6:5e:71:b7:4a:3e:08:fb:81:b7:16:16:a1:9d:
- 23:12:4d:e5:d7:92:08:ac:75:a4:9c:ba:cd:17:b2:
- 1e:44:35:65:7f:53:25:39:d1:1c:0a:9a:63:1b:19:
- 92:74:68:0a:37:c2:c2:52:48:cb:39:5a:a2:b6:e1:
- 5d:c1:dd:a0:20:b8:21:a2:93:26:6f:14:4a:21:41:
- c7:ed:6d:9b:f2:48:2f:f3:03:f5:a2:68:92:53:2f:
- 5e:e3
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Basic Constraints: critical
- CA:TRUE, pathlen:0
- X509v3 Key Usage: critical
- Digital Signature, Certificate Sign, CRL Sign
- X509v3 Extended Key Usage:
- TLS Web Server Authentication, TLS Web Client Authentication
- Authority Information Access:
- OCSP - URI:http://ocsp.digicert.com
-
- X509v3 CRL Distribution Points:
-
- Full Name:
- URI:http://crl4.digicert.com/DigiCertHighAssuranceEVRootCA.crl
-
- X509v3 Certificate Policies:
- Policy: X509v3 Any Policy
- CPS: https://www.digicert.com/CPS
-
- X509v3 Subject Key Identifier:
- 51:68:FF:90:AF:02:07:75:3C:CC:D9:65:64:62:A2:12:B8:59:72:3B
- X509v3 Authority Key Identifier:
- keyid:B1:3E:C3:69:03:F8:BF:47:01:D4:98:26:1A:08:02:EF:63:64:2B:C3
-
- Signature Algorithm: sha256WithRSAEncryption
- 18:8a:95:89:03:e6:6d:df:5c:fc:1d:68:ea:4a:8f:83:d6:51:
- 2f:8d:6b:44:16:9e:ac:63:f5:d2:6e:6c:84:99:8b:aa:81:71:
- 84:5b:ed:34:4e:b0:b7:79:92:29:cc:2d:80:6a:f0:8e:20:e1:
- 79:a4:fe:03:47:13:ea:f5:86:ca:59:71:7d:f4:04:96:6b:d3:
- 59:58:3d:fe:d3:31:25:5c:18:38:84:a3:e6:9f:82:fd:8c:5b:
- 98:31:4e:cd:78:9e:1a:fd:85:cb:49:aa:f2:27:8b:99:72:fc:
- 3e:aa:d5:41:0b:da:d5:36:a1:bf:1c:6e:47:49:7f:5e:d9:48:
- 7c:03:d9:fd:8b:49:a0:98:26:42:40:eb:d6:92:11:a4:64:0a:
- 57:54:c4:f5:1d:d6:02:5e:6b:ac:ee:c4:80:9a:12:72:fa:56:
- 93:d7:ff:bf:30:85:06:30:bf:0b:7f:4e:ff:57:05:9d:24:ed:
- 85:c3:2b:fb:a6:75:a8:ac:2d:16:ef:7d:79:27:b2:eb:c2:9d:
- 0b:07:ea:aa:85:d3:01:a3:20:28:41:59:43:28:d2:81:e3:aa:
- f6:ec:7b:3b:77:b6:40:62:80:05:41:45:01:ef:17:06:3e:de:
- c0:33:9b:67:d3:61:2e:72:87:e4:69:fc:12:00:57:40:1e:70:
- f5:1e:c9:b4
------BEGIN CERTIFICATE-----
-MIIEsTCCA5mgAwIBAgIQBOHnpNxc8vNtwCtCuF0VnzANBgkqhkiG9w0BAQsFADBs
-MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
-d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j
-ZSBFViBSb290IENBMB4XDTEzMTAyMjEyMDAwMFoXDTI4MTAyMjEyMDAwMFowcDEL
-MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3
-LmRpZ2ljZXJ0LmNvbTEvMC0GA1UEAxMmRGlnaUNlcnQgU0hBMiBIaWdoIEFzc3Vy
-YW5jZSBTZXJ2ZXIgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC2
-4C/CJAbIbQRf1+8KZAayfSImZRauQkCbztyfn3YHPsMwVYcZuU+UDlqUH1VWtMIC
-Kq/QmO4LQNfE0DtyyBSe75CxEamu0si4QzrZCwvV1ZX1QK/IHe1NnF9Xt4ZQaJn1
-itrSxwUfqJfJ3KSxgoQtxq2lnMcZgqaFD15EWCo3j/018QsIJzJa9buLnqS9UdAn
-4t07QjOjBSjEuyjMmqwrIw14xnvmXnG3Sj4I+4G3FhahnSMSTeXXkgisdaScus0X
-sh5ENWV/UyU50RwKmmMbGZJ0aAo3wsJSSMs5WqK24V3B3aAguCGikyZvFEohQcft
-bZvySC/zA/WiaJJTL17jAgMBAAGjggFJMIIBRTASBgNVHRMBAf8ECDAGAQH/AgEA
-MA4GA1UdDwEB/wQEAwIBhjAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIw
-NAYIKwYBBQUHAQEEKDAmMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2Vy
-dC5jb20wSwYDVR0fBEQwQjBAoD6gPIY6aHR0cDovL2NybDQuZGlnaWNlcnQuY29t
-L0RpZ2lDZXJ0SGlnaEFzc3VyYW5jZUVWUm9vdENBLmNybDA9BgNVHSAENjA0MDIG
-BFUdIAAwKjAoBggrBgEFBQcCARYcaHR0cHM6Ly93d3cuZGlnaWNlcnQuY29tL0NQ
-UzAdBgNVHQ4EFgQUUWj/kK8CB3U8zNllZGKiErhZcjswHwYDVR0jBBgwFoAUsT7D
-aQP4v0cB1JgmGggC72NkK8MwDQYJKoZIhvcNAQELBQADggEBABiKlYkD5m3fXPwd
-aOpKj4PWUS+Na0QWnqxj9dJubISZi6qBcYRb7TROsLd5kinMLYBq8I4g4Xmk/gNH
-E+r1hspZcX30BJZr01lYPf7TMSVcGDiEo+afgv2MW5gxTs14nhr9hctJqvIni5ly
-/D6q1UEL2tU2ob8cbkdJf17ZSHwD2f2LSaCYJkJA69aSEaRkCldUxPUd1gJea6zu
-xICaEnL6VpPX/78whQYwvwt/Tv9XBZ0k7YXDK/umdaisLRbvfXknsuvCnQsH6qqF
-0wGjIChBWUMo0oHjqvbsezt3tkBigAVBRQHvFwY+3sAzm2fTYS5yh+Rp/BIAV0Ae
-cPUeybQ=
------END CERTIFICATE-----
-#endif
-static const unsigned char kDERCert29[] = {
- 0x30, 0x82, 0x04, 0xb1, 0x30, 0x82, 0x03, 0x99, 0xa0, 0x03, 0x02, 0x01,
- 0x02, 0x02, 0x10, 0x04, 0xe1, 0xe7, 0xa4, 0xdc, 0x5c, 0xf2, 0xf3, 0x6d,
- 0xc0, 0x2b, 0x42, 0xb8, 0x5d, 0x15, 0x9f, 0x30, 0x0d, 0x06, 0x09, 0x2a,
- 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x6c,
- 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55,
- 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0c,
- 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, 0x6e, 0x63,
- 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x10, 0x77,
- 0x77, 0x77, 0x2e, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, 0x74, 0x2e,
- 0x63, 0x6f, 0x6d, 0x31, 0x2b, 0x30, 0x29, 0x06, 0x03, 0x55, 0x04, 0x03,
- 0x13, 0x22, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x48,
- 0x69, 0x67, 0x68, 0x20, 0x41, 0x73, 0x73, 0x75, 0x72, 0x61, 0x6e, 0x63,
- 0x65, 0x20, 0x45, 0x56, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41,
- 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x33, 0x31, 0x30, 0x32, 0x32, 0x31, 0x32,
- 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x38, 0x31, 0x30, 0x32,
- 0x32, 0x31, 0x32, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x70, 0x31, 0x0b,
- 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31,
- 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0c, 0x44, 0x69,
- 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, 0x6e, 0x63, 0x31, 0x19,
- 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x10, 0x77, 0x77, 0x77,
- 0x2e, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, 0x74, 0x2e, 0x63, 0x6f,
- 0x6d, 0x31, 0x2f, 0x30, 0x2d, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x26,
- 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x53, 0x48, 0x41,
- 0x32, 0x20, 0x48, 0x69, 0x67, 0x68, 0x20, 0x41, 0x73, 0x73, 0x75, 0x72,
- 0x61, 0x6e, 0x63, 0x65, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20,
- 0x43, 0x41, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
- 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01,
- 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xb6,
- 0xe0, 0x2f, 0xc2, 0x24, 0x06, 0xc8, 0x6d, 0x04, 0x5f, 0xd7, 0xef, 0x0a,
- 0x64, 0x06, 0xb2, 0x7d, 0x22, 0x26, 0x65, 0x16, 0xae, 0x42, 0x40, 0x9b,
- 0xce, 0xdc, 0x9f, 0x9f, 0x76, 0x07, 0x3e, 0xc3, 0x30, 0x55, 0x87, 0x19,
- 0xb9, 0x4f, 0x94, 0x0e, 0x5a, 0x94, 0x1f, 0x55, 0x56, 0xb4, 0xc2, 0x02,
- 0x2a, 0xaf, 0xd0, 0x98, 0xee, 0x0b, 0x40, 0xd7, 0xc4, 0xd0, 0x3b, 0x72,
- 0xc8, 0x14, 0x9e, 0xef, 0x90, 0xb1, 0x11, 0xa9, 0xae, 0xd2, 0xc8, 0xb8,
- 0x43, 0x3a, 0xd9, 0x0b, 0x0b, 0xd5, 0xd5, 0x95, 0xf5, 0x40, 0xaf, 0xc8,
- 0x1d, 0xed, 0x4d, 0x9c, 0x5f, 0x57, 0xb7, 0x86, 0x50, 0x68, 0x99, 0xf5,
- 0x8a, 0xda, 0xd2, 0xc7, 0x05, 0x1f, 0xa8, 0x97, 0xc9, 0xdc, 0xa4, 0xb1,
- 0x82, 0x84, 0x2d, 0xc6, 0xad, 0xa5, 0x9c, 0xc7, 0x19, 0x82, 0xa6, 0x85,
- 0x0f, 0x5e, 0x44, 0x58, 0x2a, 0x37, 0x8f, 0xfd, 0x35, 0xf1, 0x0b, 0x08,
- 0x27, 0x32, 0x5a, 0xf5, 0xbb, 0x8b, 0x9e, 0xa4, 0xbd, 0x51, 0xd0, 0x27,
- 0xe2, 0xdd, 0x3b, 0x42, 0x33, 0xa3, 0x05, 0x28, 0xc4, 0xbb, 0x28, 0xcc,
- 0x9a, 0xac, 0x2b, 0x23, 0x0d, 0x78, 0xc6, 0x7b, 0xe6, 0x5e, 0x71, 0xb7,
- 0x4a, 0x3e, 0x08, 0xfb, 0x81, 0xb7, 0x16, 0x16, 0xa1, 0x9d, 0x23, 0x12,
- 0x4d, 0xe5, 0xd7, 0x92, 0x08, 0xac, 0x75, 0xa4, 0x9c, 0xba, 0xcd, 0x17,
- 0xb2, 0x1e, 0x44, 0x35, 0x65, 0x7f, 0x53, 0x25, 0x39, 0xd1, 0x1c, 0x0a,
- 0x9a, 0x63, 0x1b, 0x19, 0x92, 0x74, 0x68, 0x0a, 0x37, 0xc2, 0xc2, 0x52,
- 0x48, 0xcb, 0x39, 0x5a, 0xa2, 0xb6, 0xe1, 0x5d, 0xc1, 0xdd, 0xa0, 0x20,
- 0xb8, 0x21, 0xa2, 0x93, 0x26, 0x6f, 0x14, 0x4a, 0x21, 0x41, 0xc7, 0xed,
- 0x6d, 0x9b, 0xf2, 0x48, 0x2f, 0xf3, 0x03, 0xf5, 0xa2, 0x68, 0x92, 0x53,
- 0x2f, 0x5e, 0xe3, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x49,
- 0x30, 0x82, 0x01, 0x45, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01,
- 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x00,
- 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04,
- 0x03, 0x02, 0x01, 0x86, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04,
- 0x16, 0x30, 0x14, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03,
- 0x01, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x02, 0x30,
- 0x34, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04,
- 0x28, 0x30, 0x26, 0x30, 0x24, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05,
- 0x07, 0x30, 0x01, 0x86, 0x18, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f,
- 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72,
- 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x4b, 0x06, 0x03, 0x55, 0x1d, 0x1f,
- 0x04, 0x44, 0x30, 0x42, 0x30, 0x40, 0xa0, 0x3e, 0xa0, 0x3c, 0x86, 0x3a,
- 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x34, 0x2e,
- 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, 0x74, 0x2e, 0x63, 0x6f, 0x6d,
- 0x2f, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x48, 0x69, 0x67,
- 0x68, 0x41, 0x73, 0x73, 0x75, 0x72, 0x61, 0x6e, 0x63, 0x65, 0x45, 0x56,
- 0x52, 0x6f, 0x6f, 0x74, 0x43, 0x41, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x3d,
- 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x36, 0x30, 0x34, 0x30, 0x32, 0x06,
- 0x04, 0x55, 0x1d, 0x20, 0x00, 0x30, 0x2a, 0x30, 0x28, 0x06, 0x08, 0x2b,
- 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x1c, 0x68, 0x74, 0x74,
- 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x64, 0x69, 0x67,
- 0x69, 0x63, 0x65, 0x72, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x43, 0x50,
- 0x53, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14,
- 0x51, 0x68, 0xff, 0x90, 0xaf, 0x02, 0x07, 0x75, 0x3c, 0xcc, 0xd9, 0x65,
- 0x64, 0x62, 0xa2, 0x12, 0xb8, 0x59, 0x72, 0x3b, 0x30, 0x1f, 0x06, 0x03,
- 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0xb1, 0x3e, 0xc3,
- 0x69, 0x03, 0xf8, 0xbf, 0x47, 0x01, 0xd4, 0x98, 0x26, 0x1a, 0x08, 0x02,
- 0xef, 0x63, 0x64, 0x2b, 0xc3, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48,
- 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01,
- 0x00, 0x18, 0x8a, 0x95, 0x89, 0x03, 0xe6, 0x6d, 0xdf, 0x5c, 0xfc, 0x1d,
- 0x68, 0xea, 0x4a, 0x8f, 0x83, 0xd6, 0x51, 0x2f, 0x8d, 0x6b, 0x44, 0x16,
- 0x9e, 0xac, 0x63, 0xf5, 0xd2, 0x6e, 0x6c, 0x84, 0x99, 0x8b, 0xaa, 0x81,
- 0x71, 0x84, 0x5b, 0xed, 0x34, 0x4e, 0xb0, 0xb7, 0x79, 0x92, 0x29, 0xcc,
- 0x2d, 0x80, 0x6a, 0xf0, 0x8e, 0x20, 0xe1, 0x79, 0xa4, 0xfe, 0x03, 0x47,
- 0x13, 0xea, 0xf5, 0x86, 0xca, 0x59, 0x71, 0x7d, 0xf4, 0x04, 0x96, 0x6b,
- 0xd3, 0x59, 0x58, 0x3d, 0xfe, 0xd3, 0x31, 0x25, 0x5c, 0x18, 0x38, 0x84,
- 0xa3, 0xe6, 0x9f, 0x82, 0xfd, 0x8c, 0x5b, 0x98, 0x31, 0x4e, 0xcd, 0x78,
- 0x9e, 0x1a, 0xfd, 0x85, 0xcb, 0x49, 0xaa, 0xf2, 0x27, 0x8b, 0x99, 0x72,
- 0xfc, 0x3e, 0xaa, 0xd5, 0x41, 0x0b, 0xda, 0xd5, 0x36, 0xa1, 0xbf, 0x1c,
- 0x6e, 0x47, 0x49, 0x7f, 0x5e, 0xd9, 0x48, 0x7c, 0x03, 0xd9, 0xfd, 0x8b,
- 0x49, 0xa0, 0x98, 0x26, 0x42, 0x40, 0xeb, 0xd6, 0x92, 0x11, 0xa4, 0x64,
- 0x0a, 0x57, 0x54, 0xc4, 0xf5, 0x1d, 0xd6, 0x02, 0x5e, 0x6b, 0xac, 0xee,
- 0xc4, 0x80, 0x9a, 0x12, 0x72, 0xfa, 0x56, 0x93, 0xd7, 0xff, 0xbf, 0x30,
- 0x85, 0x06, 0x30, 0xbf, 0x0b, 0x7f, 0x4e, 0xff, 0x57, 0x05, 0x9d, 0x24,
- 0xed, 0x85, 0xc3, 0x2b, 0xfb, 0xa6, 0x75, 0xa8, 0xac, 0x2d, 0x16, 0xef,
- 0x7d, 0x79, 0x27, 0xb2, 0xeb, 0xc2, 0x9d, 0x0b, 0x07, 0xea, 0xaa, 0x85,
- 0xd3, 0x01, 0xa3, 0x20, 0x28, 0x41, 0x59, 0x43, 0x28, 0xd2, 0x81, 0xe3,
- 0xaa, 0xf6, 0xec, 0x7b, 0x3b, 0x77, 0xb6, 0x40, 0x62, 0x80, 0x05, 0x41,
- 0x45, 0x01, 0xef, 0x17, 0x06, 0x3e, 0xde, 0xc0, 0x33, 0x9b, 0x67, 0xd3,
- 0x61, 0x2e, 0x72, 0x87, 0xe4, 0x69, 0xfc, 0x12, 0x00, 0x57, 0x40, 0x1e,
- 0x70, 0xf5, 0x1e, 0xc9, 0xb4,
-};
-
-#if 0
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number:
- 16:87:d6:88:6d:e2:30:06:85:23:3d:bf:11:bf:65:97
- Signature Algorithm: sha256WithRSAEncryption
- Issuer: C=US, O=thawte, Inc., OU=Certification Services Division, OU=(c) 2006 thawte, Inc. - For authorized use only, CN=thawte Primary Root CA
- Validity
- Not Before: Oct 31 00:00:00 2013 GMT
- Not After : Oct 30 23:59:59 2023 GMT
- Subject: C=US, O=thawte, Inc., CN=thawte SSL CA - G2
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:b2:fc:06:fb:04:93:d2:ea:59:20:3b:44:85:97:
- 52:39:e7:10:f0:7a:e0:b0:94:40:da:46:f8:0c:28:
- bb:b9:ce:60:38:3f:d2:d8:11:42:1b:91:ad:49:ee:
- 8f:c7:de:6c:de:37:6f:fd:8b:20:3c:6d:e7:74:d3:
- dc:d5:24:88:41:80:89:ee:36:be:c4:d5:be:8d:53:
- 13:aa:e4:a5:b8:93:0a:be:ec:da:cd:3c:d4:32:56:
- ef:d0:4e:a0:b8:97:bb:39:50:1e:6e:65:c3:fd:b2:
- ce:e0:59:a9:48:09:c6:fe:be:ae:fc:3e:3b:81:20:
- 97:8b:8f:46:df:60:64:07:75:bb:1b:86:38:9f:47:
- 7b:34:ce:a1:d1:97:ad:76:d8:9f:b7:26:db:79:80:
- 36:48:f2:c5:37:f8:d9:32:ae:7c:a4:53:81:c7:99:
- a1:54:38:2f:4f:75:a0:bb:5a:a5:bb:cd:ac:02:5b:
- 19:02:d5:13:18:a7:ce:ac:74:55:12:05:8b:9b:a2:
- 95:46:64:72:38:cd:5a:1b:3a:16:a7:be:71:99:8c:
- 54:03:b8:96:6c:01:d3:3e:06:98:3f:21:81:3b:02:
- 7e:00:47:53:01:1e:0e:46:43:fb:4b:2d:dc:0b:1a:
- e8:2f:98:f8:7e:d1:99:ab:13:6c:a4:17:de:6f:f6:
- 15:f5
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Basic Constraints: critical
- CA:TRUE, pathlen:0
- X509v3 Key Usage: critical
- Certificate Sign, CRL Sign
- X509v3 CRL Distribution Points:
-
- Full Name:
- URI:http://t1.symcb.com/ThawtePCA.crl
-
- Authority Information Access:
- OCSP - URI:http://t2.symcb.com
-
- X509v3 Certificate Policies:
- Policy: 2.16.840.1.113733.1.7.54
- CPS: https://www.thawte.com/cps
-
- X509v3 Subject Alternative Name:
- DirName:/CN=SymantecPKI-1-537
- X509v3 Subject Key Identifier:
- C2:4F:48:57:FC:D1:4F:9A:C0:5D:38:7D:0E:05:DB:D9:2E:B5:52:60
- X509v3 Authority Key Identifier:
- keyid:7B:5B:45:CF:AF:CE:CB:7A:FD:31:92:1A:6A:B6:F3:46:EB:57:48:50
-
- Signature Algorithm: sha256WithRSAEncryption
- 8d:06:de:43:c9:76:02:ca:d9:23:97:5e:f3:63:d7:7d:44:c2:
- 0f:6b:0a:f5:07:e5:8b:b8:fa:e0:a3:fa:6b:80:92:b5:03:2c:
- c5:37:e0:c2:e5:95:b5:92:70:18:28:42:94:ee:4b:77:6a:01:
- 0f:8b:23:ec:56:4d:f4:00:69:e5:84:c8:e2:ea:de:5b:3e:f6:
- 3c:07:3a:94:ca:6c:27:b1:cc:83:1a:60:71:27:d2:bf:02:f5:
- 1e:44:d3:48:d5:a6:d3:76:21:00:9c:fa:98:64:eb:17:36:3f:
- eb:1b:3c:3e:a6:b1:d9:58:06:0e:72:d9:68:be:f1:a7:20:d7:
- 52:e4:a4:77:1f:71:70:9d:55:35:85:37:e1:1d:4d:94:c2:70:
- 7f:95:40:6e:4b:7d:b2:b4:29:2a:03:79:c8:b9:4c:67:61:04:
- a0:8b:27:ff:59:00:eb:55:7f:c6:b7:33:35:2d:5e:4e:ac:b8:
- ea:12:c5:e8:f7:b9:ab:be:74:92:2c:b7:d9:4d:ca:84:2f:1c:
- c2:f0:72:7c:b2:31:6e:cf:80:e5:88:07:36:51:7b:ba:61:af:
- 6d:8d:23:5b:34:a3:95:bc:a2:31:7f:f2:f5:e7:b7:e8:ef:c4:
- b5:27:32:e9:f7:9e:69:c7:2b:e8:be:bb:0c:aa:e7:ea:60:12:
- ea:26:8a:78
------BEGIN CERTIFICATE-----
-MIIEsjCCA5qgAwIBAgIQFofWiG3iMAaFIz2/Eb9llzANBgkqhkiG9w0BAQsFADCB
-qTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMf
-Q2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIw
-MDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxHzAdBgNV
-BAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwHhcNMTMxMDMxMDAwMDAwWhcNMjMx
-MDMwMjM1OTU5WjBBMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMdGhhd3RlLCBJbmMu
-MRswGQYDVQQDExJ0aGF3dGUgU1NMIENBIC0gRzIwggEiMA0GCSqGSIb3DQEBAQUA
-A4IBDwAwggEKAoIBAQCy/Ab7BJPS6lkgO0SFl1I55xDweuCwlEDaRvgMKLu5zmA4
-P9LYEUIbka1J7o/H3mzeN2/9iyA8bed009zVJIhBgInuNr7E1b6NUxOq5KW4kwq+
-7NrNPNQyVu/QTqC4l7s5UB5uZcP9ss7gWalICcb+vq78PjuBIJeLj0bfYGQHdbsb
-hjifR3s0zqHRl6122J+3Jtt5gDZI8sU3+NkyrnykU4HHmaFUOC9PdaC7WqW7zawC
-WxkC1RMYp86sdFUSBYubopVGZHI4zVobOhanvnGZjFQDuJZsAdM+Bpg/IYE7An4A
-R1MBHg5GQ/tLLdwLGugvmPh+0ZmrE2ykF95v9hX1AgMBAAGjggE7MIIBNzASBgNV
-HRMBAf8ECDAGAQH/AgEAMA4GA1UdDwEB/wQEAwIBBjAyBgNVHR8EKzApMCegJaAj
-hiFodHRwOi8vdDEuc3ltY2IuY29tL1RoYXd0ZVBDQS5jcmwwLwYIKwYBBQUHAQEE
-IzAhMB8GCCsGAQUFBzABhhNodHRwOi8vdDIuc3ltY2IuY29tMEEGA1UdIAQ6MDgw
-NgYKYIZIAYb4RQEHNjAoMCYGCCsGAQUFBwIBFhpodHRwczovL3d3dy50aGF3dGUu
-Y29tL2NwczApBgNVHREEIjAgpB4wHDEaMBgGA1UEAxMRU3ltYW50ZWNQS0ktMS01
-MzcwHQYDVR0OBBYEFMJPSFf80U+awF04fQ4F29kutVJgMB8GA1UdIwQYMBaAFHtb
-Rc+vzst6/TGSGmq280brV0hQMA0GCSqGSIb3DQEBCwUAA4IBAQCNBt5DyXYCytkj
-l17zY9d9RMIPawr1B+WLuPrgo/prgJK1AyzFN+DC5ZW1knAYKEKU7kt3agEPiyPs
-Vk30AGnlhMji6t5bPvY8BzqUymwnscyDGmBxJ9K/AvUeRNNI1abTdiEAnPqYZOsX
-Nj/rGzw+prHZWAYOctlovvGnINdS5KR3H3FwnVU1hTfhHU2UwnB/lUBuS32ytCkq
-A3nIuUxnYQSgiyf/WQDrVX/GtzM1LV5OrLjqEsXo97mrvnSSLLfZTcqELxzC8HJ8
-sjFuz4DliAc2UXu6Ya9tjSNbNKOVvKIxf/L157fo78S1JzLp955pxyvovrsMqufq
-YBLqJop4
------END CERTIFICATE-----
-#endif
-static const unsigned char kDERCert30[] = {
- 0x30, 0x82, 0x04, 0xb2, 0x30, 0x82, 0x03, 0x9a, 0xa0, 0x03, 0x02, 0x01,
- 0x02, 0x02, 0x10, 0x16, 0x87, 0xd6, 0x88, 0x6d, 0xe2, 0x30, 0x06, 0x85,
- 0x23, 0x3d, 0xbf, 0x11, 0xbf, 0x65, 0x97, 0x30, 0x0d, 0x06, 0x09, 0x2a,
- 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x81,
- 0xa9, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
- 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13,
- 0x0c, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63,
- 0x2e, 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1f,
- 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f,
- 0x6e, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, 0x44,
- 0x69, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x31, 0x38, 0x30, 0x36, 0x06,
- 0x03, 0x55, 0x04, 0x0b, 0x13, 0x2f, 0x28, 0x63, 0x29, 0x20, 0x32, 0x30,
- 0x30, 0x36, 0x20, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2c, 0x20, 0x49,
- 0x6e, 0x63, 0x2e, 0x20, 0x2d, 0x20, 0x46, 0x6f, 0x72, 0x20, 0x61, 0x75,
- 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x20, 0x75, 0x73, 0x65,
- 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55,
- 0x04, 0x03, 0x13, 0x16, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x20, 0x50,
- 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20,
- 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x33, 0x31, 0x30, 0x33, 0x31,
- 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x33, 0x31,
- 0x30, 0x33, 0x30, 0x32, 0x33, 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x41,
- 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55,
- 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0c,
- 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e,
- 0x31, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x12, 0x74,
- 0x68, 0x61, 0x77, 0x74, 0x65, 0x20, 0x53, 0x53, 0x4c, 0x20, 0x43, 0x41,
- 0x20, 0x2d, 0x20, 0x47, 0x32, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06,
- 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00,
- 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01,
- 0x01, 0x00, 0xb2, 0xfc, 0x06, 0xfb, 0x04, 0x93, 0xd2, 0xea, 0x59, 0x20,
- 0x3b, 0x44, 0x85, 0x97, 0x52, 0x39, 0xe7, 0x10, 0xf0, 0x7a, 0xe0, 0xb0,
- 0x94, 0x40, 0xda, 0x46, 0xf8, 0x0c, 0x28, 0xbb, 0xb9, 0xce, 0x60, 0x38,
- 0x3f, 0xd2, 0xd8, 0x11, 0x42, 0x1b, 0x91, 0xad, 0x49, 0xee, 0x8f, 0xc7,
- 0xde, 0x6c, 0xde, 0x37, 0x6f, 0xfd, 0x8b, 0x20, 0x3c, 0x6d, 0xe7, 0x74,
- 0xd3, 0xdc, 0xd5, 0x24, 0x88, 0x41, 0x80, 0x89, 0xee, 0x36, 0xbe, 0xc4,
- 0xd5, 0xbe, 0x8d, 0x53, 0x13, 0xaa, 0xe4, 0xa5, 0xb8, 0x93, 0x0a, 0xbe,
- 0xec, 0xda, 0xcd, 0x3c, 0xd4, 0x32, 0x56, 0xef, 0xd0, 0x4e, 0xa0, 0xb8,
- 0x97, 0xbb, 0x39, 0x50, 0x1e, 0x6e, 0x65, 0xc3, 0xfd, 0xb2, 0xce, 0xe0,
- 0x59, 0xa9, 0x48, 0x09, 0xc6, 0xfe, 0xbe, 0xae, 0xfc, 0x3e, 0x3b, 0x81,
- 0x20, 0x97, 0x8b, 0x8f, 0x46, 0xdf, 0x60, 0x64, 0x07, 0x75, 0xbb, 0x1b,
- 0x86, 0x38, 0x9f, 0x47, 0x7b, 0x34, 0xce, 0xa1, 0xd1, 0x97, 0xad, 0x76,
- 0xd8, 0x9f, 0xb7, 0x26, 0xdb, 0x79, 0x80, 0x36, 0x48, 0xf2, 0xc5, 0x37,
- 0xf8, 0xd9, 0x32, 0xae, 0x7c, 0xa4, 0x53, 0x81, 0xc7, 0x99, 0xa1, 0x54,
- 0x38, 0x2f, 0x4f, 0x75, 0xa0, 0xbb, 0x5a, 0xa5, 0xbb, 0xcd, 0xac, 0x02,
- 0x5b, 0x19, 0x02, 0xd5, 0x13, 0x18, 0xa7, 0xce, 0xac, 0x74, 0x55, 0x12,
- 0x05, 0x8b, 0x9b, 0xa2, 0x95, 0x46, 0x64, 0x72, 0x38, 0xcd, 0x5a, 0x1b,
- 0x3a, 0x16, 0xa7, 0xbe, 0x71, 0x99, 0x8c, 0x54, 0x03, 0xb8, 0x96, 0x6c,
- 0x01, 0xd3, 0x3e, 0x06, 0x98, 0x3f, 0x21, 0x81, 0x3b, 0x02, 0x7e, 0x00,
- 0x47, 0x53, 0x01, 0x1e, 0x0e, 0x46, 0x43, 0xfb, 0x4b, 0x2d, 0xdc, 0x0b,
- 0x1a, 0xe8, 0x2f, 0x98, 0xf8, 0x7e, 0xd1, 0x99, 0xab, 0x13, 0x6c, 0xa4,
- 0x17, 0xde, 0x6f, 0xf6, 0x15, 0xf5, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3,
- 0x82, 0x01, 0x3b, 0x30, 0x82, 0x01, 0x37, 0x30, 0x12, 0x06, 0x03, 0x55,
- 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff,
- 0x02, 0x01, 0x00, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01,
- 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x32, 0x06, 0x03, 0x55,
- 0x1d, 0x1f, 0x04, 0x2b, 0x30, 0x29, 0x30, 0x27, 0xa0, 0x25, 0xa0, 0x23,
- 0x86, 0x21, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x74, 0x31, 0x2e,
- 0x73, 0x79, 0x6d, 0x63, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x54, 0x68,
- 0x61, 0x77, 0x74, 0x65, 0x50, 0x43, 0x41, 0x2e, 0x63, 0x72, 0x6c, 0x30,
- 0x2f, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04,
- 0x23, 0x30, 0x21, 0x30, 0x1f, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05,
- 0x07, 0x30, 0x01, 0x86, 0x13, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f,
- 0x74, 0x32, 0x2e, 0x73, 0x79, 0x6d, 0x63, 0x62, 0x2e, 0x63, 0x6f, 0x6d,
- 0x30, 0x41, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x3a, 0x30, 0x38, 0x30,
- 0x36, 0x06, 0x0a, 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x45, 0x01, 0x07,
- 0x36, 0x30, 0x28, 0x30, 0x26, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05,
- 0x07, 0x02, 0x01, 0x16, 0x1a, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f,
- 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2e,
- 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x70, 0x73, 0x30, 0x29, 0x06, 0x03, 0x55,
- 0x1d, 0x11, 0x04, 0x22, 0x30, 0x20, 0xa4, 0x1e, 0x30, 0x1c, 0x31, 0x1a,
- 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x11, 0x53, 0x79, 0x6d,
- 0x61, 0x6e, 0x74, 0x65, 0x63, 0x50, 0x4b, 0x49, 0x2d, 0x31, 0x2d, 0x35,
- 0x33, 0x37, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04,
- 0x14, 0xc2, 0x4f, 0x48, 0x57, 0xfc, 0xd1, 0x4f, 0x9a, 0xc0, 0x5d, 0x38,
- 0x7d, 0x0e, 0x05, 0xdb, 0xd9, 0x2e, 0xb5, 0x52, 0x60, 0x30, 0x1f, 0x06,
- 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x7b, 0x5b,
- 0x45, 0xcf, 0xaf, 0xce, 0xcb, 0x7a, 0xfd, 0x31, 0x92, 0x1a, 0x6a, 0xb6,
- 0xf3, 0x46, 0xeb, 0x57, 0x48, 0x50, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
- 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01,
- 0x01, 0x00, 0x8d, 0x06, 0xde, 0x43, 0xc9, 0x76, 0x02, 0xca, 0xd9, 0x23,
- 0x97, 0x5e, 0xf3, 0x63, 0xd7, 0x7d, 0x44, 0xc2, 0x0f, 0x6b, 0x0a, 0xf5,
- 0x07, 0xe5, 0x8b, 0xb8, 0xfa, 0xe0, 0xa3, 0xfa, 0x6b, 0x80, 0x92, 0xb5,
- 0x03, 0x2c, 0xc5, 0x37, 0xe0, 0xc2, 0xe5, 0x95, 0xb5, 0x92, 0x70, 0x18,
- 0x28, 0x42, 0x94, 0xee, 0x4b, 0x77, 0x6a, 0x01, 0x0f, 0x8b, 0x23, 0xec,
- 0x56, 0x4d, 0xf4, 0x00, 0x69, 0xe5, 0x84, 0xc8, 0xe2, 0xea, 0xde, 0x5b,
- 0x3e, 0xf6, 0x3c, 0x07, 0x3a, 0x94, 0xca, 0x6c, 0x27, 0xb1, 0xcc, 0x83,
- 0x1a, 0x60, 0x71, 0x27, 0xd2, 0xbf, 0x02, 0xf5, 0x1e, 0x44, 0xd3, 0x48,
- 0xd5, 0xa6, 0xd3, 0x76, 0x21, 0x00, 0x9c, 0xfa, 0x98, 0x64, 0xeb, 0x17,
- 0x36, 0x3f, 0xeb, 0x1b, 0x3c, 0x3e, 0xa6, 0xb1, 0xd9, 0x58, 0x06, 0x0e,
- 0x72, 0xd9, 0x68, 0xbe, 0xf1, 0xa7, 0x20, 0xd7, 0x52, 0xe4, 0xa4, 0x77,
- 0x1f, 0x71, 0x70, 0x9d, 0x55, 0x35, 0x85, 0x37, 0xe1, 0x1d, 0x4d, 0x94,
- 0xc2, 0x70, 0x7f, 0x95, 0x40, 0x6e, 0x4b, 0x7d, 0xb2, 0xb4, 0x29, 0x2a,
- 0x03, 0x79, 0xc8, 0xb9, 0x4c, 0x67, 0x61, 0x04, 0xa0, 0x8b, 0x27, 0xff,
- 0x59, 0x00, 0xeb, 0x55, 0x7f, 0xc6, 0xb7, 0x33, 0x35, 0x2d, 0x5e, 0x4e,
- 0xac, 0xb8, 0xea, 0x12, 0xc5, 0xe8, 0xf7, 0xb9, 0xab, 0xbe, 0x74, 0x92,
- 0x2c, 0xb7, 0xd9, 0x4d, 0xca, 0x84, 0x2f, 0x1c, 0xc2, 0xf0, 0x72, 0x7c,
- 0xb2, 0x31, 0x6e, 0xcf, 0x80, 0xe5, 0x88, 0x07, 0x36, 0x51, 0x7b, 0xba,
- 0x61, 0xaf, 0x6d, 0x8d, 0x23, 0x5b, 0x34, 0xa3, 0x95, 0xbc, 0xa2, 0x31,
- 0x7f, 0xf2, 0xf5, 0xe7, 0xb7, 0xe8, 0xef, 0xc4, 0xb5, 0x27, 0x32, 0xe9,
- 0xf7, 0x9e, 0x69, 0xc7, 0x2b, 0xe8, 0xbe, 0xbb, 0x0c, 0xaa, 0xe7, 0xea,
- 0x60, 0x12, 0xea, 0x26, 0x8a, 0x78,
-};
-
-#if 0
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number:
- 93:92:85:40:01:65:71:5f:94:7f:28:8f:ef:c9:9b:28
- Signature Algorithm: sha256WithRSAEncryption
- Issuer: C=PL, O=Unizeto Sp. z o.o., CN=Certum CA
- Validity
- Not Before: Oct 22 12:07:37 2008 GMT
- Not After : Jun 10 10:46:39 2027 GMT
- Subject: C=PL, O=Unizeto Technologies S.A., OU=Certum Certification Authority, CN=Certum Trusted Network CA
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:e3:fb:7d:a3:72:ba:c2:f0:c9:14:87:f5:6b:01:
- 4e:e1:6e:40:07:ba:6d:27:5d:7f:f7:5b:2d:b3:5a:
- c7:51:5f:ab:a4:32:a6:61:87:b6:6e:0f:86:d2:30:
- 02:97:f8:d7:69:57:a1:18:39:5d:6a:64:79:c6:01:
- 59:ac:3c:31:4a:38:7c:d2:04:d2:4b:28:e8:20:5f:
- 3b:07:a2:cc:4d:73:db:f3:ae:4f:c7:56:d5:5a:a7:
- 96:89:fa:f3:ab:68:d4:23:86:59:27:cf:09:27:bc:
- ac:6e:72:83:1c:30:72:df:e0:a2:e9:d2:e1:74:75:
- 19:bd:2a:9e:7b:15:54:04:1b:d7:43:39:ad:55:28:
- c5:e2:1a:bb:f4:c0:e4:ae:38:49:33:cc:76:85:9f:
- 39:45:d2:a4:9e:f2:12:8c:51:f8:7c:e4:2d:7f:f5:
- ac:5f:eb:16:9f:b1:2d:d1:ba:cc:91:42:77:4c:25:
- c9:90:38:6f:db:f0:cc:fb:8e:1e:97:59:3e:d5:60:
- 4e:e6:05:28:ed:49:79:13:4b:ba:48:db:2f:f9:72:
- d3:39:ca:fe:1f:d8:34:72:f5:b4:40:cf:31:01:c3:
- ec:de:11:2d:17:5d:1f:b8:50:d1:5e:19:a7:69:de:
- 07:33:28:ca:50:95:f9:a7:54:cb:54:86:50:45:a9:
- f9:49
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Basic Constraints: critical
- CA:TRUE
- X509v3 Subject Key Identifier:
- 08:76:CD:CB:07:FF:24:F6:C5:CD:ED:BB:90:BC:E2:84:37:46:75:F7
- X509v3 Authority Key Identifier:
- DirName:/C=PL/O=Unizeto Sp. z o.o./CN=Certum CA
- serial:01:00:20
-
- X509v3 Key Usage: critical
- Certificate Sign, CRL Sign
- X509v3 CRL Distribution Points:
-
- Full Name:
- URI:http://crl.certum.pl/ca.crl
-
- Authority Information Access:
- OCSP - URI:http://subca.ocsp-certum.com
- CA Issuers - URI:http://repository.certum.pl/ca.cer
-
- X509v3 Certificate Policies:
- Policy: X509v3 Any Policy
- CPS: http://www.certum.pl/CPS
-
- Signature Algorithm: sha256WithRSAEncryption
- 8d:e6:fd:40:66:a3:4c:9c:a7:ab:a1:da:84:dd:1c:30:07:e6:
- db:c7:2d:ec:83:a1:56:e4:1d:3c:26:a1:a5:09:2b:e8:7d:62:
- be:b2:75:94:dd:08:f2:7f:28:41:e4:80:67:02:4e:8a:8f:c3:
- 35:d0:d5:a9:27:28:ea:d2:f4:ab:06:86:43:ae:8c:e3:f9:88:
- 7d:e0:db:bd:42:81:80:02:12:75:b2:e8:17:71:ab:21:95:31:
- 46:42:0d:88:10:39:d3:6f:ec:2f:42:ea:40:53:62:bf:eb:ca:
- 78:9e:ab:a2:d5:2e:05:ea:33:ab:e9:d6:97:94:42:5e:04:ed:
- 2c:ed:6a:9c:7a:95:7d:05:2a:05:7f:08:5d:66:ad:61:d4:76:
- ac:75:96:97:73:63:bd:1a:41:59:29:a5:5e:22:83:c3:8b:59:
- fa:9a:a2:f6:bd:30:bf:72:1d:1c:99:86:9c:f2:85:3c:1d:f7:
- 26:96:2f:2e:f9:02:b1:b5:a9:50:e8:38:fa:9b:0a:5e:b4:04:
- c0:ce:4e:39:2c:ca:0b:5b:62:f0:4d:58:50:34:99:e6:9a:2c:
- d2:90:d7:09:81:d6:c0:aa:5e:ce:fe:d2:f7:a1:ba:4b:d9:d6:
- 86:8e:19:1f:a6:06:47:42:72:e0:56:0a:00:1c:78:b9:8d:cc:
- 99:04:37:49
------BEGIN CERTIFICATE-----
-MIIEtDCCA5ygAwIBAgIRAJOShUABZXFflH8oj+/JmygwDQYJKoZIhvcNAQELBQAw
-PjELMAkGA1UEBhMCUEwxGzAZBgNVBAoTElVuaXpldG8gU3AuIHogby5vLjESMBAG
-A1UEAxMJQ2VydHVtIENBMB4XDTA4MTAyMjEyMDczN1oXDTI3MDYxMDEwNDYzOVow
-fjELMAkGA1UEBhMCUEwxIjAgBgNVBAoTGVVuaXpldG8gVGVjaG5vbG9naWVzIFMu
-QS4xJzAlBgNVBAsTHkNlcnR1bSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEiMCAG
-A1UEAxMZQ2VydHVtIFRydXN0ZWQgTmV0d29yayBDQTCCASIwDQYJKoZIhvcNAQEB
-BQADggEPADCCAQoCggEBAOP7faNyusLwyRSH9WsBTuFuQAe6bSddf/dbLbNax1Ff
-q6QypmGHtm4PhtIwApf412lXoRg5XWpkecYBWaw8MUo4fNIE0kso6CBfOweizE1z
-2/OuT8dW1Vqnlon686to1COGWSfPCSe8rG5ygxwwct/gounS4XR1Gb0qnnsVVAQb
-10M5rVUoxeIau/TA5K44STPMdoWfOUXSpJ7yEoxR+HzkLX/1rF/rFp+xLdG6zJFC
-d0wlyZA4b9vwzPuOHpdZPtVgTuYFKO1JeRNLukjbL/ly0znK/h/YNHL1tEDPMQHD
-7N4RLRddH7hQ0V4Zp2neBzMoylCV+adUy1SGUEWp+UkCAwEAAaOCAWswggFnMA8G
-A1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFAh2zcsH/yT2xc3tu5C84oQ3RnX3MFIG
-A1UdIwRLMEmhQqRAMD4xCzAJBgNVBAYTAlBMMRswGQYDVQQKExJVbml6ZXRvIFNw
-LiB6IG8uby4xEjAQBgNVBAMTCUNlcnR1bSBDQYIDAQAgMA4GA1UdDwEB/wQEAwIB
-BjAsBgNVHR8EJTAjMCGgH6AdhhtodHRwOi8vY3JsLmNlcnR1bS5wbC9jYS5jcmww
-aAYIKwYBBQUHAQEEXDBaMCgGCCsGAQUFBzABhhxodHRwOi8vc3ViY2Eub2NzcC1j
-ZXJ0dW0uY29tMC4GCCsGAQUFBzAChiJodHRwOi8vcmVwb3NpdG9yeS5jZXJ0dW0u
-cGwvY2EuY2VyMDkGA1UdIAQyMDAwLgYEVR0gADAmMCQGCCsGAQUFBwIBFhhodHRw
-Oi8vd3d3LmNlcnR1bS5wbC9DUFMwDQYJKoZIhvcNAQELBQADggEBAI3m/UBmo0yc
-p6uh2oTdHDAH5tvHLeyDoVbkHTwmoaUJK+h9Yr6ydZTdCPJ/KEHkgGcCToqPwzXQ
-1aknKOrS9KsGhkOujOP5iH3g271CgYACEnWy6BdxqyGVMUZCDYgQOdNv7C9C6kBT
-Yr/rynieq6LVLgXqM6vp1peUQl4E7Sztapx6lX0FKgV/CF1mrWHUdqx1lpdzY70a
-QVkppV4ig8OLWfqaova9ML9yHRyZhpzyhTwd9yaWLy75ArG1qVDoOPqbCl60BMDO
-TjksygtbYvBNWFA0meaaLNKQ1wmB1sCqXs7+0vehukvZ1oaOGR+mBkdCcuBWCgAc
-eLmNzJkEN0k=
------END CERTIFICATE-----
-#endif
-static const unsigned char kDERCert31[] = {
- 0x30, 0x82, 0x04, 0xb4, 0x30, 0x82, 0x03, 0x9c, 0xa0, 0x03, 0x02, 0x01,
- 0x02, 0x02, 0x11, 0x00, 0x93, 0x92, 0x85, 0x40, 0x01, 0x65, 0x71, 0x5f,
- 0x94, 0x7f, 0x28, 0x8f, 0xef, 0xc9, 0x9b, 0x28, 0x30, 0x0d, 0x06, 0x09,
- 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30,
- 0x3e, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
- 0x50, 0x4c, 0x31, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13,
- 0x12, 0x55, 0x6e, 0x69, 0x7a, 0x65, 0x74, 0x6f, 0x20, 0x53, 0x70, 0x2e,
- 0x20, 0x7a, 0x20, 0x6f, 0x2e, 0x6f, 0x2e, 0x31, 0x12, 0x30, 0x10, 0x06,
- 0x03, 0x55, 0x04, 0x03, 0x13, 0x09, 0x43, 0x65, 0x72, 0x74, 0x75, 0x6d,
- 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x38, 0x31, 0x30, 0x32,
- 0x32, 0x31, 0x32, 0x30, 0x37, 0x33, 0x37, 0x5a, 0x17, 0x0d, 0x32, 0x37,
- 0x30, 0x36, 0x31, 0x30, 0x31, 0x30, 0x34, 0x36, 0x33, 0x39, 0x5a, 0x30,
- 0x7e, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
- 0x50, 0x4c, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13,
- 0x19, 0x55, 0x6e, 0x69, 0x7a, 0x65, 0x74, 0x6f, 0x20, 0x54, 0x65, 0x63,
- 0x68, 0x6e, 0x6f, 0x6c, 0x6f, 0x67, 0x69, 0x65, 0x73, 0x20, 0x53, 0x2e,
- 0x41, 0x2e, 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13,
- 0x1e, 0x43, 0x65, 0x72, 0x74, 0x75, 0x6d, 0x20, 0x43, 0x65, 0x72, 0x74,
- 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75,
- 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31, 0x22, 0x30, 0x20, 0x06,
- 0x03, 0x55, 0x04, 0x03, 0x13, 0x19, 0x43, 0x65, 0x72, 0x74, 0x75, 0x6d,
- 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x20, 0x4e, 0x65, 0x74,
- 0x77, 0x6f, 0x72, 0x6b, 0x20, 0x43, 0x41, 0x30, 0x82, 0x01, 0x22, 0x30,
- 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01,
- 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02,
- 0x82, 0x01, 0x01, 0x00, 0xe3, 0xfb, 0x7d, 0xa3, 0x72, 0xba, 0xc2, 0xf0,
- 0xc9, 0x14, 0x87, 0xf5, 0x6b, 0x01, 0x4e, 0xe1, 0x6e, 0x40, 0x07, 0xba,
- 0x6d, 0x27, 0x5d, 0x7f, 0xf7, 0x5b, 0x2d, 0xb3, 0x5a, 0xc7, 0x51, 0x5f,
- 0xab, 0xa4, 0x32, 0xa6, 0x61, 0x87, 0xb6, 0x6e, 0x0f, 0x86, 0xd2, 0x30,
- 0x02, 0x97, 0xf8, 0xd7, 0x69, 0x57, 0xa1, 0x18, 0x39, 0x5d, 0x6a, 0x64,
- 0x79, 0xc6, 0x01, 0x59, 0xac, 0x3c, 0x31, 0x4a, 0x38, 0x7c, 0xd2, 0x04,
- 0xd2, 0x4b, 0x28, 0xe8, 0x20, 0x5f, 0x3b, 0x07, 0xa2, 0xcc, 0x4d, 0x73,
- 0xdb, 0xf3, 0xae, 0x4f, 0xc7, 0x56, 0xd5, 0x5a, 0xa7, 0x96, 0x89, 0xfa,
- 0xf3, 0xab, 0x68, 0xd4, 0x23, 0x86, 0x59, 0x27, 0xcf, 0x09, 0x27, 0xbc,
- 0xac, 0x6e, 0x72, 0x83, 0x1c, 0x30, 0x72, 0xdf, 0xe0, 0xa2, 0xe9, 0xd2,
- 0xe1, 0x74, 0x75, 0x19, 0xbd, 0x2a, 0x9e, 0x7b, 0x15, 0x54, 0x04, 0x1b,
- 0xd7, 0x43, 0x39, 0xad, 0x55, 0x28, 0xc5, 0xe2, 0x1a, 0xbb, 0xf4, 0xc0,
- 0xe4, 0xae, 0x38, 0x49, 0x33, 0xcc, 0x76, 0x85, 0x9f, 0x39, 0x45, 0xd2,
- 0xa4, 0x9e, 0xf2, 0x12, 0x8c, 0x51, 0xf8, 0x7c, 0xe4, 0x2d, 0x7f, 0xf5,
- 0xac, 0x5f, 0xeb, 0x16, 0x9f, 0xb1, 0x2d, 0xd1, 0xba, 0xcc, 0x91, 0x42,
- 0x77, 0x4c, 0x25, 0xc9, 0x90, 0x38, 0x6f, 0xdb, 0xf0, 0xcc, 0xfb, 0x8e,
- 0x1e, 0x97, 0x59, 0x3e, 0xd5, 0x60, 0x4e, 0xe6, 0x05, 0x28, 0xed, 0x49,
- 0x79, 0x13, 0x4b, 0xba, 0x48, 0xdb, 0x2f, 0xf9, 0x72, 0xd3, 0x39, 0xca,
- 0xfe, 0x1f, 0xd8, 0x34, 0x72, 0xf5, 0xb4, 0x40, 0xcf, 0x31, 0x01, 0xc3,
- 0xec, 0xde, 0x11, 0x2d, 0x17, 0x5d, 0x1f, 0xb8, 0x50, 0xd1, 0x5e, 0x19,
- 0xa7, 0x69, 0xde, 0x07, 0x33, 0x28, 0xca, 0x50, 0x95, 0xf9, 0xa7, 0x54,
- 0xcb, 0x54, 0x86, 0x50, 0x45, 0xa9, 0xf9, 0x49, 0x02, 0x03, 0x01, 0x00,
- 0x01, 0xa3, 0x82, 0x01, 0x6b, 0x30, 0x82, 0x01, 0x67, 0x30, 0x0f, 0x06,
- 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, 0x30, 0x03, 0x01,
- 0x01, 0xff, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04,
- 0x14, 0x08, 0x76, 0xcd, 0xcb, 0x07, 0xff, 0x24, 0xf6, 0xc5, 0xcd, 0xed,
- 0xbb, 0x90, 0xbc, 0xe2, 0x84, 0x37, 0x46, 0x75, 0xf7, 0x30, 0x52, 0x06,
- 0x03, 0x55, 0x1d, 0x23, 0x04, 0x4b, 0x30, 0x49, 0xa1, 0x42, 0xa4, 0x40,
- 0x30, 0x3e, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
- 0x02, 0x50, 0x4c, 0x31, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x0a,
- 0x13, 0x12, 0x55, 0x6e, 0x69, 0x7a, 0x65, 0x74, 0x6f, 0x20, 0x53, 0x70,
- 0x2e, 0x20, 0x7a, 0x20, 0x6f, 0x2e, 0x6f, 0x2e, 0x31, 0x12, 0x30, 0x10,
- 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x09, 0x43, 0x65, 0x72, 0x74, 0x75,
- 0x6d, 0x20, 0x43, 0x41, 0x82, 0x03, 0x01, 0x00, 0x20, 0x30, 0x0e, 0x06,
- 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01,
- 0x06, 0x30, 0x2c, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x25, 0x30, 0x23,
- 0x30, 0x21, 0xa0, 0x1f, 0xa0, 0x1d, 0x86, 0x1b, 0x68, 0x74, 0x74, 0x70,
- 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x63, 0x65, 0x72, 0x74, 0x75,
- 0x6d, 0x2e, 0x70, 0x6c, 0x2f, 0x63, 0x61, 0x2e, 0x63, 0x72, 0x6c, 0x30,
- 0x68, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04,
- 0x5c, 0x30, 0x5a, 0x30, 0x28, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05,
- 0x07, 0x30, 0x01, 0x86, 0x1c, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f,
- 0x73, 0x75, 0x62, 0x63, 0x61, 0x2e, 0x6f, 0x63, 0x73, 0x70, 0x2d, 0x63,
- 0x65, 0x72, 0x74, 0x75, 0x6d, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x2e, 0x06,
- 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x22, 0x68,
- 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69,
- 0x74, 0x6f, 0x72, 0x79, 0x2e, 0x63, 0x65, 0x72, 0x74, 0x75, 0x6d, 0x2e,
- 0x70, 0x6c, 0x2f, 0x63, 0x61, 0x2e, 0x63, 0x65, 0x72, 0x30, 0x39, 0x06,
- 0x03, 0x55, 0x1d, 0x20, 0x04, 0x32, 0x30, 0x30, 0x30, 0x2e, 0x06, 0x04,
- 0x55, 0x1d, 0x20, 0x00, 0x30, 0x26, 0x30, 0x24, 0x06, 0x08, 0x2b, 0x06,
- 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x18, 0x68, 0x74, 0x74, 0x70,
- 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x63, 0x65, 0x72, 0x74, 0x75,
- 0x6d, 0x2e, 0x70, 0x6c, 0x2f, 0x43, 0x50, 0x53, 0x30, 0x0d, 0x06, 0x09,
- 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03,
- 0x82, 0x01, 0x01, 0x00, 0x8d, 0xe6, 0xfd, 0x40, 0x66, 0xa3, 0x4c, 0x9c,
- 0xa7, 0xab, 0xa1, 0xda, 0x84, 0xdd, 0x1c, 0x30, 0x07, 0xe6, 0xdb, 0xc7,
- 0x2d, 0xec, 0x83, 0xa1, 0x56, 0xe4, 0x1d, 0x3c, 0x26, 0xa1, 0xa5, 0x09,
- 0x2b, 0xe8, 0x7d, 0x62, 0xbe, 0xb2, 0x75, 0x94, 0xdd, 0x08, 0xf2, 0x7f,
- 0x28, 0x41, 0xe4, 0x80, 0x67, 0x02, 0x4e, 0x8a, 0x8f, 0xc3, 0x35, 0xd0,
- 0xd5, 0xa9, 0x27, 0x28, 0xea, 0xd2, 0xf4, 0xab, 0x06, 0x86, 0x43, 0xae,
- 0x8c, 0xe3, 0xf9, 0x88, 0x7d, 0xe0, 0xdb, 0xbd, 0x42, 0x81, 0x80, 0x02,
- 0x12, 0x75, 0xb2, 0xe8, 0x17, 0x71, 0xab, 0x21, 0x95, 0x31, 0x46, 0x42,
- 0x0d, 0x88, 0x10, 0x39, 0xd3, 0x6f, 0xec, 0x2f, 0x42, 0xea, 0x40, 0x53,
- 0x62, 0xbf, 0xeb, 0xca, 0x78, 0x9e, 0xab, 0xa2, 0xd5, 0x2e, 0x05, 0xea,
- 0x33, 0xab, 0xe9, 0xd6, 0x97, 0x94, 0x42, 0x5e, 0x04, 0xed, 0x2c, 0xed,
- 0x6a, 0x9c, 0x7a, 0x95, 0x7d, 0x05, 0x2a, 0x05, 0x7f, 0x08, 0x5d, 0x66,
- 0xad, 0x61, 0xd4, 0x76, 0xac, 0x75, 0x96, 0x97, 0x73, 0x63, 0xbd, 0x1a,
- 0x41, 0x59, 0x29, 0xa5, 0x5e, 0x22, 0x83, 0xc3, 0x8b, 0x59, 0xfa, 0x9a,
- 0xa2, 0xf6, 0xbd, 0x30, 0xbf, 0x72, 0x1d, 0x1c, 0x99, 0x86, 0x9c, 0xf2,
- 0x85, 0x3c, 0x1d, 0xf7, 0x26, 0x96, 0x2f, 0x2e, 0xf9, 0x02, 0xb1, 0xb5,
- 0xa9, 0x50, 0xe8, 0x38, 0xfa, 0x9b, 0x0a, 0x5e, 0xb4, 0x04, 0xc0, 0xce,
- 0x4e, 0x39, 0x2c, 0xca, 0x0b, 0x5b, 0x62, 0xf0, 0x4d, 0x58, 0x50, 0x34,
- 0x99, 0xe6, 0x9a, 0x2c, 0xd2, 0x90, 0xd7, 0x09, 0x81, 0xd6, 0xc0, 0xaa,
- 0x5e, 0xce, 0xfe, 0xd2, 0xf7, 0xa1, 0xba, 0x4b, 0xd9, 0xd6, 0x86, 0x8e,
- 0x19, 0x1f, 0xa6, 0x06, 0x47, 0x42, 0x72, 0xe0, 0x56, 0x0a, 0x00, 0x1c,
- 0x78, 0xb9, 0x8d, 0xcc, 0x99, 0x04, 0x37, 0x49,
-};
-
-#if 0
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number:
- 48:e9:94:40:d4:36:49:1c:b8:b8:82:3d:09:43:94:c7
- Signature Algorithm: sha256WithRSAEncryption
- Issuer: C=US, O=GeoTrust Inc., OU=(c) 2008 GeoTrust Inc. - For authorized use only, CN=GeoTrust Primary Certification Authority - G3
- Validity
- Not Before: Jun 10 00:00:00 2014 GMT
- Not After : Jun 9 23:59:59 2024 GMT
- Subject: C=US, O=GeoTrust Inc., CN=RapidSSL SHA256 CA - G2
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:c4:95:63:28:d0:4e:30:45:af:8b:97:34:14:45:
- f8:5c:58:4a:fa:33:8e:6e:9c:60:ab:f3:86:ff:34:
- 74:b2:2b:be:a1:8c:d5:a2:a3:60:7a:40:b9:e1:fc:
- 22:ca:67:ba:60:aa:c7:9a:f9:06:7f:ee:f7:ba:85:
- 05:b0:03:ff:72:ae:15:41:4a:98:64:d7:17:4b:54:
- ef:05:c6:98:07:93:27:3e:4f:dc:0f:c6:7b:8b:e7:
- f3:06:5e:8d:e8:b4:ae:29:b4:1e:1e:2d:16:90:d3:
- ea:aa:e7:8c:3b:6d:af:36:59:ff:c5:0a:fa:c7:4c:
- bd:36:8b:64:c4:4a:f5:ce:33:f9:07:be:7f:45:90:
- a8:08:14:b0:d0:a5:4f:df:82:80:da:1b:ee:c3:13:
- b0:98:f5:0f:f9:7e:76:b5:e6:b9:5d:68:b9:5c:50:
- 90:89:a4:36:b1:70:16:ea:b1:10:b5:6a:76:df:e1:
- bb:fc:78:f2:72:99:cf:c9:a2:d4:73:54:77:bf:c0:
- 39:77:e5:ae:12:c5:78:5a:19:45:d4:41:19:d3:7c:
- f5:6f:99:6b:d7:8b:bc:2d:09:9d:4b:10:61:c0:da:
- 52:c3:af:22:43:c6:eb:37:7e:63:74:30:0d:6a:71:
- 8e:de:5d:5b:8a:c8:c5:d7:9b:29:e8:ae:b6:25:61:
- 81:eb
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- Authority Information Access:
- OCSP - URI:http://g.symcd.com
-
- X509v3 Basic Constraints: critical
- CA:TRUE, pathlen:0
- X509v3 Certificate Policies:
- Policy: 2.16.840.1.113733.1.7.54
- CPS: http://www.geotrust.com/resources/cps
-
- X509v3 CRL Distribution Points:
-
- Full Name:
- URI:http://g.symcb.com/GeoTrustPCA-G3.crl
-
- X509v3 Key Usage: critical
- Certificate Sign, CRL Sign
- X509v3 Subject Alternative Name:
- DirName:/CN=SymantecPKI-1-697
- X509v3 Subject Key Identifier:
- 4C:F4:BF:E8:3B:BE:C2:24:F3:1B:47:3B:B5:6E:48:8E:16:AB:AF:12
- X509v3 Authority Key Identifier:
- keyid:C4:79:CA:8E:A1:4E:03:1D:1C:DC:6B:DB:31:5B:94:3E:3F:30:7F:2D
-
- Signature Algorithm: sha256WithRSAEncryption
- 7a:53:b5:de:b6:ef:52:a3:5f:8a:f5:89:f1:42:cc:5e:46:88:
- ae:a5:08:87:51:de:0f:0f:02:eb:0c:82:78:e3:73:7d:71:bd:
- 43:e9:ca:8a:3f:e0:25:92:9b:33:33:74:49:5e:00:d9:73:14:
- 1c:0b:46:76:1c:8a:0d:4d:8c:6c:7e:4b:f7:60:d8:81:78:a0:
- 78:d0:25:62:ab:10:ca:22:e8:1c:19:dd:52:83:64:05:e5:87:
- 66:ae:e7:7a:a4:3b:3e:d8:70:7a:76:a2:67:39:d4:c9:fa:e5:
- b7:1e:41:e2:09:39:88:1c:18:55:0a:c4:41:af:b2:f3:f3:0f:
- 42:14:61:74:81:e3:da:87:5a:9a:4d:8b:d3:c9:8f:89:66:13:
- 29:11:e4:ff:e2:df:8e:96:0c:5a:a1:aa:6b:9b:fd:fc:03:3b:
- 55:0d:a6:a2:25:48:17:1f:42:a8:da:6c:7e:69:6e:a0:df:67:
- d2:6d:f4:0e:6a:12:79:f5:7c:c8:a5:32:1c:c4:31:b2:e6:bb:
- a8:6b:6a:a2:8a:60:69:c0:57:7d:b2:f2:31:0c:98:65:32:ec:
- 08:5a:ce:c6:98:e9:21:97:3f:2c:79:29:03:f5:f6:94:2b:53:
- 31:f3:93:68:57:e1:d7:4f:3a:d1:61:a1:60:ce:b9:ab:98:ae:
- 35:54:63:8b
------BEGIN CERTIFICATE-----
-MIIEtTCCA52gAwIBAgIQSOmUQNQ2SRy4uII9CUOUxzANBgkqhkiG9w0BAQsFADCB
-mDELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsT
-MChjKSAyMDA4IEdlb1RydXN0IEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25s
-eTE2MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhv
-cml0eSAtIEczMB4XDTE0MDYxMDAwMDAwMFoXDTI0MDYwOTIzNTk1OVowRzELMAkG
-A1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xIDAeBgNVBAMTF1JhcGlk
-U1NMIFNIQTI1NiBDQSAtIEcyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
-AQEAxJVjKNBOMEWvi5c0FEX4XFhK+jOObpxgq/OG/zR0siu+oYzVoqNgekC54fwi
-yme6YKrHmvkGf+73uoUFsAP/cq4VQUqYZNcXS1TvBcaYB5MnPk/cD8Z7i+fzBl6N
-6LSuKbQeHi0WkNPqqueMO22vNln/xQr6x0y9NotkxEr1zjP5B75/RZCoCBSw0KVP
-34KA2hvuwxOwmPUP+X52tea5XWi5XFCQiaQ2sXAW6rEQtWp23+G7/HjycpnPyaLU
-c1R3v8A5d+WuEsV4WhlF1EEZ03z1b5lr14u8LQmdSxBhwNpSw68iQ8brN35jdDAN
-anGO3l1bisjF15sp6K62JWGB6wIDAQABo4IBSTCCAUUwLgYIKwYBBQUHAQEEIjAg
-MB4GCCsGAQUFBzABhhJodHRwOi8vZy5zeW1jZC5jb20wEgYDVR0TAQH/BAgwBgEB
-/wIBADBMBgNVHSAERTBDMEEGCmCGSAGG+EUBBzYwMzAxBggrBgEFBQcCARYlaHR0
-cDovL3d3dy5nZW90cnVzdC5jb20vcmVzb3VyY2VzL2NwczA2BgNVHR8ELzAtMCug
-KaAnhiVodHRwOi8vZy5zeW1jYi5jb20vR2VvVHJ1c3RQQ0EtRzMuY3JsMA4GA1Ud
-DwEB/wQEAwIBBjApBgNVHREEIjAgpB4wHDEaMBgGA1UEAxMRU3ltYW50ZWNQS0kt
-MS02OTcwHQYDVR0OBBYEFEz0v+g7vsIk8xtHO7VuSI4Wq68SMB8GA1UdIwQYMBaA
-FMR5yo6hTgMdHNxr2zFblD4/MH8tMA0GCSqGSIb3DQEBCwUAA4IBAQB6U7Xetu9S
-o1+K9YnxQsxeRoiupQiHUd4PDwLrDIJ443N9cb1D6cqKP+AlkpszM3RJXgDZcxQc
-C0Z2HIoNTYxsfkv3YNiBeKB40CViqxDKIugcGd1Sg2QF5Ydmrud6pDs+2HB6dqJn
-OdTJ+uW3HkHiCTmIHBhVCsRBr7Lz8w9CFGF0gePah1qaTYvTyY+JZhMpEeT/4t+O
-lgxaoaprm/38AztVDaaiJUgXH0Ko2mx+aW6g32fSbfQOahJ59XzIpTIcxDGy5ruo
-a2qiimBpwFd9svIxDJhlMuwIWs7GmOkhlz8seSkD9faUK1Mx85NoV+HXTzrRYaFg
-zrmrmK41VGOL
------END CERTIFICATE-----
-#endif
-static const unsigned char kDERCert32[] = {
- 0x30, 0x82, 0x04, 0xb5, 0x30, 0x82, 0x03, 0x9d, 0xa0, 0x03, 0x02, 0x01,
- 0x02, 0x02, 0x10, 0x48, 0xe9, 0x94, 0x40, 0xd4, 0x36, 0x49, 0x1c, 0xb8,
- 0xb8, 0x82, 0x3d, 0x09, 0x43, 0x94, 0xc7, 0x30, 0x0d, 0x06, 0x09, 0x2a,
- 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x81,
- 0x98, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
- 0x55, 0x53, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13,
- 0x0d, 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x49, 0x6e,
- 0x63, 0x2e, 0x31, 0x39, 0x30, 0x37, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13,
- 0x30, 0x28, 0x63, 0x29, 0x20, 0x32, 0x30, 0x30, 0x38, 0x20, 0x47, 0x65,
- 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x20,
- 0x2d, 0x20, 0x46, 0x6f, 0x72, 0x20, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72,
- 0x69, 0x7a, 0x65, 0x64, 0x20, 0x75, 0x73, 0x65, 0x20, 0x6f, 0x6e, 0x6c,
- 0x79, 0x31, 0x36, 0x30, 0x34, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x2d,
- 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x50, 0x72, 0x69,
- 0x6d, 0x61, 0x72, 0x79, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69,
- 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f,
- 0x72, 0x69, 0x74, 0x79, 0x20, 0x2d, 0x20, 0x47, 0x33, 0x30, 0x1e, 0x17,
- 0x0d, 0x31, 0x34, 0x30, 0x36, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
- 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x34, 0x30, 0x36, 0x30, 0x39, 0x32, 0x33,
- 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x47, 0x31, 0x0b, 0x30, 0x09, 0x06,
- 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x16, 0x30, 0x14,
- 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0d, 0x47, 0x65, 0x6f, 0x54, 0x72,
- 0x75, 0x73, 0x74, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x20, 0x30, 0x1e,
- 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x17, 0x52, 0x61, 0x70, 0x69, 0x64,
- 0x53, 0x53, 0x4c, 0x20, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, 0x20, 0x43,
- 0x41, 0x20, 0x2d, 0x20, 0x47, 0x32, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d,
- 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05,
- 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82,
- 0x01, 0x01, 0x00, 0xc4, 0x95, 0x63, 0x28, 0xd0, 0x4e, 0x30, 0x45, 0xaf,
- 0x8b, 0x97, 0x34, 0x14, 0x45, 0xf8, 0x5c, 0x58, 0x4a, 0xfa, 0x33, 0x8e,
- 0x6e, 0x9c, 0x60, 0xab, 0xf3, 0x86, 0xff, 0x34, 0x74, 0xb2, 0x2b, 0xbe,
- 0xa1, 0x8c, 0xd5, 0xa2, 0xa3, 0x60, 0x7a, 0x40, 0xb9, 0xe1, 0xfc, 0x22,
- 0xca, 0x67, 0xba, 0x60, 0xaa, 0xc7, 0x9a, 0xf9, 0x06, 0x7f, 0xee, 0xf7,
- 0xba, 0x85, 0x05, 0xb0, 0x03, 0xff, 0x72, 0xae, 0x15, 0x41, 0x4a, 0x98,
- 0x64, 0xd7, 0x17, 0x4b, 0x54, 0xef, 0x05, 0xc6, 0x98, 0x07, 0x93, 0x27,
- 0x3e, 0x4f, 0xdc, 0x0f, 0xc6, 0x7b, 0x8b, 0xe7, 0xf3, 0x06, 0x5e, 0x8d,
- 0xe8, 0xb4, 0xae, 0x29, 0xb4, 0x1e, 0x1e, 0x2d, 0x16, 0x90, 0xd3, 0xea,
- 0xaa, 0xe7, 0x8c, 0x3b, 0x6d, 0xaf, 0x36, 0x59, 0xff, 0xc5, 0x0a, 0xfa,
- 0xc7, 0x4c, 0xbd, 0x36, 0x8b, 0x64, 0xc4, 0x4a, 0xf5, 0xce, 0x33, 0xf9,
- 0x07, 0xbe, 0x7f, 0x45, 0x90, 0xa8, 0x08, 0x14, 0xb0, 0xd0, 0xa5, 0x4f,
- 0xdf, 0x82, 0x80, 0xda, 0x1b, 0xee, 0xc3, 0x13, 0xb0, 0x98, 0xf5, 0x0f,
- 0xf9, 0x7e, 0x76, 0xb5, 0xe6, 0xb9, 0x5d, 0x68, 0xb9, 0x5c, 0x50, 0x90,
- 0x89, 0xa4, 0x36, 0xb1, 0x70, 0x16, 0xea, 0xb1, 0x10, 0xb5, 0x6a, 0x76,
- 0xdf, 0xe1, 0xbb, 0xfc, 0x78, 0xf2, 0x72, 0x99, 0xcf, 0xc9, 0xa2, 0xd4,
- 0x73, 0x54, 0x77, 0xbf, 0xc0, 0x39, 0x77, 0xe5, 0xae, 0x12, 0xc5, 0x78,
- 0x5a, 0x19, 0x45, 0xd4, 0x41, 0x19, 0xd3, 0x7c, 0xf5, 0x6f, 0x99, 0x6b,
- 0xd7, 0x8b, 0xbc, 0x2d, 0x09, 0x9d, 0x4b, 0x10, 0x61, 0xc0, 0xda, 0x52,
- 0xc3, 0xaf, 0x22, 0x43, 0xc6, 0xeb, 0x37, 0x7e, 0x63, 0x74, 0x30, 0x0d,
- 0x6a, 0x71, 0x8e, 0xde, 0x5d, 0x5b, 0x8a, 0xc8, 0xc5, 0xd7, 0x9b, 0x29,
- 0xe8, 0xae, 0xb6, 0x25, 0x61, 0x81, 0xeb, 0x02, 0x03, 0x01, 0x00, 0x01,
- 0xa3, 0x82, 0x01, 0x49, 0x30, 0x82, 0x01, 0x45, 0x30, 0x2e, 0x06, 0x08,
- 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x22, 0x30, 0x20,
- 0x30, 0x1e, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01,
- 0x86, 0x12, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x67, 0x2e, 0x73,
- 0x79, 0x6d, 0x63, 0x64, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x12, 0x06, 0x03,
- 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01,
- 0xff, 0x02, 0x01, 0x00, 0x30, 0x4c, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04,
- 0x45, 0x30, 0x43, 0x30, 0x41, 0x06, 0x0a, 0x60, 0x86, 0x48, 0x01, 0x86,
- 0xf8, 0x45, 0x01, 0x07, 0x36, 0x30, 0x33, 0x30, 0x31, 0x06, 0x08, 0x2b,
- 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x25, 0x68, 0x74, 0x74,
- 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x67, 0x65, 0x6f, 0x74,
- 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x73,
- 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x2f, 0x63, 0x70, 0x73, 0x30, 0x36,
- 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x2f, 0x30, 0x2d, 0x30, 0x2b, 0xa0,
- 0x29, 0xa0, 0x27, 0x86, 0x25, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f,
- 0x67, 0x2e, 0x73, 0x79, 0x6d, 0x63, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f,
- 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x50, 0x43, 0x41, 0x2d,
- 0x47, 0x33, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d,
- 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x29,
- 0x06, 0x03, 0x55, 0x1d, 0x11, 0x04, 0x22, 0x30, 0x20, 0xa4, 0x1e, 0x30,
- 0x1c, 0x31, 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x11,
- 0x53, 0x79, 0x6d, 0x61, 0x6e, 0x74, 0x65, 0x63, 0x50, 0x4b, 0x49, 0x2d,
- 0x31, 0x2d, 0x36, 0x39, 0x37, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e,
- 0x04, 0x16, 0x04, 0x14, 0x4c, 0xf4, 0xbf, 0xe8, 0x3b, 0xbe, 0xc2, 0x24,
- 0xf3, 0x1b, 0x47, 0x3b, 0xb5, 0x6e, 0x48, 0x8e, 0x16, 0xab, 0xaf, 0x12,
- 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80,
- 0x14, 0xc4, 0x79, 0xca, 0x8e, 0xa1, 0x4e, 0x03, 0x1d, 0x1c, 0xdc, 0x6b,
- 0xdb, 0x31, 0x5b, 0x94, 0x3e, 0x3f, 0x30, 0x7f, 0x2d, 0x30, 0x0d, 0x06,
- 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00,
- 0x03, 0x82, 0x01, 0x01, 0x00, 0x7a, 0x53, 0xb5, 0xde, 0xb6, 0xef, 0x52,
- 0xa3, 0x5f, 0x8a, 0xf5, 0x89, 0xf1, 0x42, 0xcc, 0x5e, 0x46, 0x88, 0xae,
- 0xa5, 0x08, 0x87, 0x51, 0xde, 0x0f, 0x0f, 0x02, 0xeb, 0x0c, 0x82, 0x78,
- 0xe3, 0x73, 0x7d, 0x71, 0xbd, 0x43, 0xe9, 0xca, 0x8a, 0x3f, 0xe0, 0x25,
- 0x92, 0x9b, 0x33, 0x33, 0x74, 0x49, 0x5e, 0x00, 0xd9, 0x73, 0x14, 0x1c,
- 0x0b, 0x46, 0x76, 0x1c, 0x8a, 0x0d, 0x4d, 0x8c, 0x6c, 0x7e, 0x4b, 0xf7,
- 0x60, 0xd8, 0x81, 0x78, 0xa0, 0x78, 0xd0, 0x25, 0x62, 0xab, 0x10, 0xca,
- 0x22, 0xe8, 0x1c, 0x19, 0xdd, 0x52, 0x83, 0x64, 0x05, 0xe5, 0x87, 0x66,
- 0xae, 0xe7, 0x7a, 0xa4, 0x3b, 0x3e, 0xd8, 0x70, 0x7a, 0x76, 0xa2, 0x67,
- 0x39, 0xd4, 0xc9, 0xfa, 0xe5, 0xb7, 0x1e, 0x41, 0xe2, 0x09, 0x39, 0x88,
- 0x1c, 0x18, 0x55, 0x0a, 0xc4, 0x41, 0xaf, 0xb2, 0xf3, 0xf3, 0x0f, 0x42,
- 0x14, 0x61, 0x74, 0x81, 0xe3, 0xda, 0x87, 0x5a, 0x9a, 0x4d, 0x8b, 0xd3,
- 0xc9, 0x8f, 0x89, 0x66, 0x13, 0x29, 0x11, 0xe4, 0xff, 0xe2, 0xdf, 0x8e,
- 0x96, 0x0c, 0x5a, 0xa1, 0xaa, 0x6b, 0x9b, 0xfd, 0xfc, 0x03, 0x3b, 0x55,
- 0x0d, 0xa6, 0xa2, 0x25, 0x48, 0x17, 0x1f, 0x42, 0xa8, 0xda, 0x6c, 0x7e,
- 0x69, 0x6e, 0xa0, 0xdf, 0x67, 0xd2, 0x6d, 0xf4, 0x0e, 0x6a, 0x12, 0x79,
- 0xf5, 0x7c, 0xc8, 0xa5, 0x32, 0x1c, 0xc4, 0x31, 0xb2, 0xe6, 0xbb, 0xa8,
- 0x6b, 0x6a, 0xa2, 0x8a, 0x60, 0x69, 0xc0, 0x57, 0x7d, 0xb2, 0xf2, 0x31,
- 0x0c, 0x98, 0x65, 0x32, 0xec, 0x08, 0x5a, 0xce, 0xc6, 0x98, 0xe9, 0x21,
- 0x97, 0x3f, 0x2c, 0x79, 0x29, 0x03, 0xf5, 0xf6, 0x94, 0x2b, 0x53, 0x31,
- 0xf3, 0x93, 0x68, 0x57, 0xe1, 0xd7, 0x4f, 0x3a, 0xd1, 0x61, 0xa1, 0x60,
- 0xce, 0xb9, 0xab, 0x98, 0xae, 0x35, 0x54, 0x63, 0x8b,
-};
-
-#if 0
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number:
- 0c:79:a9:44:b0:8c:11:95:20:92:61:5f:e2:6b:1d:83
- Signature Algorithm: sha256WithRSAEncryption
- Issuer: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert High Assurance EV Root CA
- Validity
- Not Before: Oct 22 12:00:00 2013 GMT
- Not After : Oct 22 12:00:00 2028 GMT
- Subject: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert SHA2 Extended Validation Server CA
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:d7:53:a4:04:51:f8:99:a6:16:48:4b:67:27:aa:
- 93:49:d0:39:ed:0c:b0:b0:00:87:f1:67:28:86:85:
- 8c:8e:63:da:bc:b1:40:38:e2:d3:f5:ec:a5:05:18:
- b8:3d:3e:c5:99:17:32:ec:18:8c:fa:f1:0c:a6:64:
- 21:85:cb:07:10:34:b0:52:88:2b:1f:68:9b:d2:b1:
- 8f:12:b0:b3:d2:e7:88:1f:1f:ef:38:77:54:53:5f:
- 80:79:3f:2e:1a:aa:a8:1e:4b:2b:0d:ab:b7:63:b9:
- 35:b7:7d:14:bc:59:4b:df:51:4a:d2:a1:e2:0c:e2:
- 90:82:87:6a:ae:ea:d7:64:d6:98:55:e8:fd:af:1a:
- 50:6c:54:bc:11:f2:fd:4a:f2:9d:bb:7f:0e:f4:d5:
- be:8e:16:89:12:55:d8:c0:71:34:ee:f6:dc:2d:ec:
- c4:87:25:86:8d:d8:21:e4:b0:4d:0c:89:dc:39:26:
- 17:dd:f6:d7:94:85:d8:04:21:70:9d:6f:6f:ff:5c:
- ba:19:e1:45:cb:56:57:28:7e:1c:0d:41:57:aa:b7:
- b8:27:bb:b1:e4:fa:2a:ef:21:23:75:1a:ad:2d:9b:
- 86:35:8c:9c:77:b5:73:ad:d8:94:2d:e4:f3:0c:9d:
- ee:c1:4e:62:7e:17:c0:71:9e:2c:de:f1:f9:10:28:
- 19:33
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Basic Constraints: critical
- CA:TRUE, pathlen:0
- X509v3 Key Usage: critical
- Digital Signature, Certificate Sign, CRL Sign
- X509v3 Extended Key Usage:
- TLS Web Server Authentication, TLS Web Client Authentication
- Authority Information Access:
- OCSP - URI:http://ocsp.digicert.com
-
- X509v3 CRL Distribution Points:
-
- Full Name:
- URI:http://crl4.digicert.com/DigiCertHighAssuranceEVRootCA.crl
-
- X509v3 Certificate Policies:
- Policy: X509v3 Any Policy
- CPS: https://www.digicert.com/CPS
-
- X509v3 Subject Key Identifier:
- 3D:D3:50:A5:D6:A0:AD:EE:F3:4A:60:0A:65:D3:21:D4:F8:F8:D6:0F
- X509v3 Authority Key Identifier:
- keyid:B1:3E:C3:69:03:F8:BF:47:01:D4:98:26:1A:08:02:EF:63:64:2B:C3
-
- Signature Algorithm: sha256WithRSAEncryption
- 9d:b6:d0:90:86:e1:86:02:ed:c5:a0:f0:34:1c:74:c1:8d:76:
- cc:86:0a:a8:f0:4a:8a:42:d6:3f:c8:a9:4d:ad:7c:08:ad:e6:
- b6:50:b8:a2:1a:4d:88:07:b1:29:21:dc:e7:da:c6:3c:21:e0:
- e3:11:49:70:ac:7a:1d:01:a4:ca:11:3a:57:ab:7d:57:2a:40:
- 74:fd:d3:1d:85:18:50:df:57:47:75:a1:7d:55:20:2e:47:37:
- 50:72:8c:7f:82:1b:d2:62:8f:2d:03:5a:da:c3:c8:a1:ce:2c:
- 52:a2:00:63:eb:73:ba:71:c8:49:27:23:97:64:85:9e:38:0e:
- ad:63:68:3c:ba:52:81:58:79:a3:2c:0c:df:de:6d:eb:31:f2:
- ba:a0:7c:6c:f1:2c:d4:e1:bd:77:84:37:03:ce:32:b5:c8:9a:
- 81:1a:4a:92:4e:3b:46:9a:85:fe:83:a2:f9:9e:8c:a3:cc:0d:
- 5e:b3:3d:cf:04:78:8f:14:14:7b:32:9c:c7:00:a6:5c:c4:b5:
- a1:55:8d:5a:56:68:a4:22:70:aa:3c:81:71:d9:9d:a8:45:3b:
- f4:e5:f6:a2:51:dd:c7:7b:62:e8:6f:0c:74:eb:b8:da:f8:bf:
- 87:0d:79:50:91:90:9b:18:3b:91:59:27:f1:35:28:13:ab:26:
- 7e:d5:f7:7a
------BEGIN CERTIFICATE-----
-MIIEtjCCA56gAwIBAgIQDHmpRLCMEZUgkmFf4msdgzANBgkqhkiG9w0BAQsFADBs
-MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
-d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j
-ZSBFViBSb290IENBMB4XDTEzMTAyMjEyMDAwMFoXDTI4MTAyMjEyMDAwMFowdTEL
-MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3
-LmRpZ2ljZXJ0LmNvbTE0MDIGA1UEAxMrRGlnaUNlcnQgU0hBMiBFeHRlbmRlZCBW
-YWxpZGF0aW9uIFNlcnZlciBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
-ggEBANdTpARR+JmmFkhLZyeqk0nQOe0MsLAAh/FnKIaFjI5j2ryxQDji0/XspQUY
-uD0+xZkXMuwYjPrxDKZkIYXLBxA0sFKIKx9om9KxjxKws9LniB8f7zh3VFNfgHk/
-LhqqqB5LKw2rt2O5Nbd9FLxZS99RStKh4gzikIKHaq7q12TWmFXo/a8aUGxUvBHy
-/Urynbt/DvTVvo4WiRJV2MBxNO723C3sxIclho3YIeSwTQyJ3DkmF93215SF2AQh
-cJ1vb/9cuhnhRctWVyh+HA1BV6q3uCe7seT6Ku8hI3UarS2bhjWMnHe1c63YlC3k
-8wyd7sFOYn4XwHGeLN7x+RAoGTMCAwEAAaOCAUkwggFFMBIGA1UdEwEB/wQIMAYB
-Af8CAQAwDgYDVR0PAQH/BAQDAgGGMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEF
-BQcDAjA0BggrBgEFBQcBAQQoMCYwJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRp
-Z2ljZXJ0LmNvbTBLBgNVHR8ERDBCMECgPqA8hjpodHRwOi8vY3JsNC5kaWdpY2Vy
-dC5jb20vRGlnaUNlcnRIaWdoQXNzdXJhbmNlRVZSb290Q0EuY3JsMD0GA1UdIAQ2
-MDQwMgYEVR0gADAqMCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy5kaWdpY2VydC5j
-b20vQ1BTMB0GA1UdDgQWBBQ901Cl1qCt7vNKYApl0yHU+PjWDzAfBgNVHSMEGDAW
-gBSxPsNpA/i/RwHUmCYaCALvY2QrwzANBgkqhkiG9w0BAQsFAAOCAQEAnbbQkIbh
-hgLtxaDwNBx0wY12zIYKqPBKikLWP8ipTa18CK3mtlC4ohpNiAexKSHc59rGPCHg
-4xFJcKx6HQGkyhE6V6t9VypAdP3THYUYUN9XR3WhfVUgLkc3UHKMf4Ib0mKPLQNa
-2sPIoc4sUqIAY+tzunHISScjl2SFnjgOrWNoPLpSgVh5oywM395t6zHyuqB8bPEs
-1OG9d4Q3A84ytciagRpKkk47RpqF/oOi+Z6Mo8wNXrM9zwR4jxQUezKcxwCmXMS1
-oVWNWlZopCJwqjyBcdmdqEU79OX2olHdx3ti6G8MdOu42vi/hw15UJGQmxg7kVkn
-8TUoE6smftX3eg==
------END CERTIFICATE-----
-#endif
-static const unsigned char kDERCert33[] = {
- 0x30, 0x82, 0x04, 0xb6, 0x30, 0x82, 0x03, 0x9e, 0xa0, 0x03, 0x02, 0x01,
- 0x02, 0x02, 0x10, 0x0c, 0x79, 0xa9, 0x44, 0xb0, 0x8c, 0x11, 0x95, 0x20,
- 0x92, 0x61, 0x5f, 0xe2, 0x6b, 0x1d, 0x83, 0x30, 0x0d, 0x06, 0x09, 0x2a,
- 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x6c,
- 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55,
- 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0c,
- 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, 0x6e, 0x63,
- 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x10, 0x77,
- 0x77, 0x77, 0x2e, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, 0x74, 0x2e,
- 0x63, 0x6f, 0x6d, 0x31, 0x2b, 0x30, 0x29, 0x06, 0x03, 0x55, 0x04, 0x03,
- 0x13, 0x22, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x48,
- 0x69, 0x67, 0x68, 0x20, 0x41, 0x73, 0x73, 0x75, 0x72, 0x61, 0x6e, 0x63,
- 0x65, 0x20, 0x45, 0x56, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41,
- 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x33, 0x31, 0x30, 0x32, 0x32, 0x31, 0x32,
- 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x38, 0x31, 0x30, 0x32,
- 0x32, 0x31, 0x32, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x75, 0x31, 0x0b,
- 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31,
- 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0c, 0x44, 0x69,
- 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, 0x6e, 0x63, 0x31, 0x19,
- 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x10, 0x77, 0x77, 0x77,
- 0x2e, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, 0x74, 0x2e, 0x63, 0x6f,
- 0x6d, 0x31, 0x34, 0x30, 0x32, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x2b,
- 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x53, 0x48, 0x41,
- 0x32, 0x20, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x64, 0x65, 0x64, 0x20, 0x56,
- 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x53, 0x65,
- 0x72, 0x76, 0x65, 0x72, 0x20, 0x43, 0x41, 0x30, 0x82, 0x01, 0x22, 0x30,
- 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01,
- 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02,
- 0x82, 0x01, 0x01, 0x00, 0xd7, 0x53, 0xa4, 0x04, 0x51, 0xf8, 0x99, 0xa6,
- 0x16, 0x48, 0x4b, 0x67, 0x27, 0xaa, 0x93, 0x49, 0xd0, 0x39, 0xed, 0x0c,
- 0xb0, 0xb0, 0x00, 0x87, 0xf1, 0x67, 0x28, 0x86, 0x85, 0x8c, 0x8e, 0x63,
- 0xda, 0xbc, 0xb1, 0x40, 0x38, 0xe2, 0xd3, 0xf5, 0xec, 0xa5, 0x05, 0x18,
- 0xb8, 0x3d, 0x3e, 0xc5, 0x99, 0x17, 0x32, 0xec, 0x18, 0x8c, 0xfa, 0xf1,
- 0x0c, 0xa6, 0x64, 0x21, 0x85, 0xcb, 0x07, 0x10, 0x34, 0xb0, 0x52, 0x88,
- 0x2b, 0x1f, 0x68, 0x9b, 0xd2, 0xb1, 0x8f, 0x12, 0xb0, 0xb3, 0xd2, 0xe7,
- 0x88, 0x1f, 0x1f, 0xef, 0x38, 0x77, 0x54, 0x53, 0x5f, 0x80, 0x79, 0x3f,
- 0x2e, 0x1a, 0xaa, 0xa8, 0x1e, 0x4b, 0x2b, 0x0d, 0xab, 0xb7, 0x63, 0xb9,
- 0x35, 0xb7, 0x7d, 0x14, 0xbc, 0x59, 0x4b, 0xdf, 0x51, 0x4a, 0xd2, 0xa1,
- 0xe2, 0x0c, 0xe2, 0x90, 0x82, 0x87, 0x6a, 0xae, 0xea, 0xd7, 0x64, 0xd6,
- 0x98, 0x55, 0xe8, 0xfd, 0xaf, 0x1a, 0x50, 0x6c, 0x54, 0xbc, 0x11, 0xf2,
- 0xfd, 0x4a, 0xf2, 0x9d, 0xbb, 0x7f, 0x0e, 0xf4, 0xd5, 0xbe, 0x8e, 0x16,
- 0x89, 0x12, 0x55, 0xd8, 0xc0, 0x71, 0x34, 0xee, 0xf6, 0xdc, 0x2d, 0xec,
- 0xc4, 0x87, 0x25, 0x86, 0x8d, 0xd8, 0x21, 0xe4, 0xb0, 0x4d, 0x0c, 0x89,
- 0xdc, 0x39, 0x26, 0x17, 0xdd, 0xf6, 0xd7, 0x94, 0x85, 0xd8, 0x04, 0x21,
- 0x70, 0x9d, 0x6f, 0x6f, 0xff, 0x5c, 0xba, 0x19, 0xe1, 0x45, 0xcb, 0x56,
- 0x57, 0x28, 0x7e, 0x1c, 0x0d, 0x41, 0x57, 0xaa, 0xb7, 0xb8, 0x27, 0xbb,
- 0xb1, 0xe4, 0xfa, 0x2a, 0xef, 0x21, 0x23, 0x75, 0x1a, 0xad, 0x2d, 0x9b,
- 0x86, 0x35, 0x8c, 0x9c, 0x77, 0xb5, 0x73, 0xad, 0xd8, 0x94, 0x2d, 0xe4,
- 0xf3, 0x0c, 0x9d, 0xee, 0xc1, 0x4e, 0x62, 0x7e, 0x17, 0xc0, 0x71, 0x9e,
- 0x2c, 0xde, 0xf1, 0xf9, 0x10, 0x28, 0x19, 0x33, 0x02, 0x03, 0x01, 0x00,
- 0x01, 0xa3, 0x82, 0x01, 0x49, 0x30, 0x82, 0x01, 0x45, 0x30, 0x12, 0x06,
- 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01,
- 0x01, 0xff, 0x02, 0x01, 0x00, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f,
- 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x86, 0x30, 0x1d, 0x06,
- 0x03, 0x55, 0x1d, 0x25, 0x04, 0x16, 0x30, 0x14, 0x06, 0x08, 0x2b, 0x06,
- 0x01, 0x05, 0x05, 0x07, 0x03, 0x01, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05,
- 0x05, 0x07, 0x03, 0x02, 0x30, 0x34, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05,
- 0x05, 0x07, 0x01, 0x01, 0x04, 0x28, 0x30, 0x26, 0x30, 0x24, 0x06, 0x08,
- 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x18, 0x68, 0x74,
- 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x64, 0x69,
- 0x67, 0x69, 0x63, 0x65, 0x72, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x4b,
- 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x44, 0x30, 0x42, 0x30, 0x40, 0xa0,
- 0x3e, 0xa0, 0x3c, 0x86, 0x3a, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f,
- 0x63, 0x72, 0x6c, 0x34, 0x2e, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72,
- 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65,
- 0x72, 0x74, 0x48, 0x69, 0x67, 0x68, 0x41, 0x73, 0x73, 0x75, 0x72, 0x61,
- 0x6e, 0x63, 0x65, 0x45, 0x56, 0x52, 0x6f, 0x6f, 0x74, 0x43, 0x41, 0x2e,
- 0x63, 0x72, 0x6c, 0x30, 0x3d, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x36,
- 0x30, 0x34, 0x30, 0x32, 0x06, 0x04, 0x55, 0x1d, 0x20, 0x00, 0x30, 0x2a,
- 0x30, 0x28, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01,
- 0x16, 0x1c, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77,
- 0x77, 0x2e, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, 0x74, 0x2e, 0x63,
- 0x6f, 0x6d, 0x2f, 0x43, 0x50, 0x53, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d,
- 0x0e, 0x04, 0x16, 0x04, 0x14, 0x3d, 0xd3, 0x50, 0xa5, 0xd6, 0xa0, 0xad,
- 0xee, 0xf3, 0x4a, 0x60, 0x0a, 0x65, 0xd3, 0x21, 0xd4, 0xf8, 0xf8, 0xd6,
- 0x0f, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16,
- 0x80, 0x14, 0xb1, 0x3e, 0xc3, 0x69, 0x03, 0xf8, 0xbf, 0x47, 0x01, 0xd4,
- 0x98, 0x26, 0x1a, 0x08, 0x02, 0xef, 0x63, 0x64, 0x2b, 0xc3, 0x30, 0x0d,
- 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05,
- 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x9d, 0xb6, 0xd0, 0x90, 0x86, 0xe1,
- 0x86, 0x02, 0xed, 0xc5, 0xa0, 0xf0, 0x34, 0x1c, 0x74, 0xc1, 0x8d, 0x76,
- 0xcc, 0x86, 0x0a, 0xa8, 0xf0, 0x4a, 0x8a, 0x42, 0xd6, 0x3f, 0xc8, 0xa9,
- 0x4d, 0xad, 0x7c, 0x08, 0xad, 0xe6, 0xb6, 0x50, 0xb8, 0xa2, 0x1a, 0x4d,
- 0x88, 0x07, 0xb1, 0x29, 0x21, 0xdc, 0xe7, 0xda, 0xc6, 0x3c, 0x21, 0xe0,
- 0xe3, 0x11, 0x49, 0x70, 0xac, 0x7a, 0x1d, 0x01, 0xa4, 0xca, 0x11, 0x3a,
- 0x57, 0xab, 0x7d, 0x57, 0x2a, 0x40, 0x74, 0xfd, 0xd3, 0x1d, 0x85, 0x18,
- 0x50, 0xdf, 0x57, 0x47, 0x75, 0xa1, 0x7d, 0x55, 0x20, 0x2e, 0x47, 0x37,
- 0x50, 0x72, 0x8c, 0x7f, 0x82, 0x1b, 0xd2, 0x62, 0x8f, 0x2d, 0x03, 0x5a,
- 0xda, 0xc3, 0xc8, 0xa1, 0xce, 0x2c, 0x52, 0xa2, 0x00, 0x63, 0xeb, 0x73,
- 0xba, 0x71, 0xc8, 0x49, 0x27, 0x23, 0x97, 0x64, 0x85, 0x9e, 0x38, 0x0e,
- 0xad, 0x63, 0x68, 0x3c, 0xba, 0x52, 0x81, 0x58, 0x79, 0xa3, 0x2c, 0x0c,
- 0xdf, 0xde, 0x6d, 0xeb, 0x31, 0xf2, 0xba, 0xa0, 0x7c, 0x6c, 0xf1, 0x2c,
- 0xd4, 0xe1, 0xbd, 0x77, 0x84, 0x37, 0x03, 0xce, 0x32, 0xb5, 0xc8, 0x9a,
- 0x81, 0x1a, 0x4a, 0x92, 0x4e, 0x3b, 0x46, 0x9a, 0x85, 0xfe, 0x83, 0xa2,
- 0xf9, 0x9e, 0x8c, 0xa3, 0xcc, 0x0d, 0x5e, 0xb3, 0x3d, 0xcf, 0x04, 0x78,
- 0x8f, 0x14, 0x14, 0x7b, 0x32, 0x9c, 0xc7, 0x00, 0xa6, 0x5c, 0xc4, 0xb5,
- 0xa1, 0x55, 0x8d, 0x5a, 0x56, 0x68, 0xa4, 0x22, 0x70, 0xaa, 0x3c, 0x81,
- 0x71, 0xd9, 0x9d, 0xa8, 0x45, 0x3b, 0xf4, 0xe5, 0xf6, 0xa2, 0x51, 0xdd,
- 0xc7, 0x7b, 0x62, 0xe8, 0x6f, 0x0c, 0x74, 0xeb, 0xb8, 0xda, 0xf8, 0xbf,
- 0x87, 0x0d, 0x79, 0x50, 0x91, 0x90, 0x9b, 0x18, 0x3b, 0x91, 0x59, 0x27,
- 0xf1, 0x35, 0x28, 0x13, 0xab, 0x26, 0x7e, 0xd5, 0xf7, 0x7a,
-};
-
-#if 0
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number:
- 36:34:9e:18:c9:9c:26:69:b6:56:2e:6c:e5:ad:71:32
- Signature Algorithm: sha256WithRSAEncryption
- Issuer: C=US, O=thawte, Inc., OU=Certification Services Division, OU=(c) 2008 thawte, Inc. - For authorized use only, CN=thawte Primary Root CA - G3
- Validity
- Not Before: May 23 00:00:00 2013 GMT
- Not After : May 22 23:59:59 2023 GMT
- Subject: C=US, O=thawte, Inc., CN=thawte SHA256 SSL CA
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:a3:63:2b:d4:ba:5d:38:ae:b0:cf:b9:4c:38:df:
- 20:7d:f1:2b:47:71:1d:8b:68:f3:56:f9:9c:da:aa:
- e5:84:26:de:a5:71:30:bc:f3:31:23:9d:e8:3b:80:
- c8:66:57:75:b6:57:0e:db:93:f5:26:8e:70:ba:64:
- 52:66:8a:2a:88:5c:44:18:4d:a8:a2:7c:bd:56:61:
- 32:90:12:f9:35:87:48:60:b0:6e:90:67:44:01:8d:
- e7:c9:0d:63:68:72:72:ab:63:3c:86:b8:1f:7d:ad:
- 88:25:a7:6a:88:29:fb:59:c6:78:71:5f:2c:ba:89:
- e6:d3:80:fd:57:ec:b9:51:5f:43:33:2e:7e:25:3b:
- a4:04:d1:60:8c:b3:44:33:93:0c:ad:2a:b6:44:a2:
- 19:3b:af:c4:90:6f:7b:05:87:86:9b:2c:6a:9d:2b:
- 6c:77:c9:00:9f:c9:cf:ac:ed:3e:1b:f7:c3:f3:d9:
- f8:6c:d4:a0:57:c4:fb:28:32:aa:33:f0:e6:ba:98:
- df:e5:c2:4e:9c:74:bf:8a:48:c2:f2:1b:f0:77:40:
- 41:07:04:b2:3a:d5:4c:c4:29:a9:11:40:3f:02:46:
- f0:91:d5:d2:81:83:86:13:b3:31:ed:46:ab:a8:87:
- 76:a9:99:7d:bc:cd:31:50:f4:a5:b5:dc:a5:32:b3:
- 8b:8b
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- Authority Information Access:
- OCSP - URI:http://ocsp.thawte.com
-
- X509v3 Basic Constraints: critical
- CA:TRUE, pathlen:0
- X509v3 Certificate Policies:
- Policy: 2.16.840.1.113733.1.7.54
- CPS: https://www.thawte.com/cps
-
- X509v3 CRL Distribution Points:
-
- Full Name:
- URI:http://crl.thawte.com/ThawtePCA-G3.crl
-
- X509v3 Key Usage: critical
- Certificate Sign, CRL Sign
- X509v3 Subject Alternative Name:
- DirName:/CN=VeriSignMPKI-2-415
- X509v3 Subject Key Identifier:
- 2B:9A:35:AE:01:18:38:30:E1:70:7A:05:E0:11:76:A3:CE:BD:90:14
- X509v3 Authority Key Identifier:
- keyid:AD:6C:AA:94:60:9C:ED:E4:FF:FA:3E:0A:74:2B:63:03:F7:B6:59:BF
-
- Signature Algorithm: sha256WithRSAEncryption
- 74:a6:56:e8:af:93:96:19:fb:26:f9:0d:b0:44:a5:cd:e9:7a:
- 48:03:74:01:6c:13:71:b7:e0:82:90:99:62:23:e3:d6:99:af:
- f0:c7:1e:9e:a8:18:21:db:b4:94:3f:34:56:1b:99:55:2f:8e:
- f0:45:33:32:b7:72:c1:13:5b:34:d3:f5:60:e5:2e:18:d1:5c:
- c5:6a:c1:aa:87:50:0c:1c:9d:64:2b:ff:1b:dc:d5:2e:61:0b:
- e7:b9:b6:91:53:86:d9:03:2a:d1:3d:7b:4a:da:2b:07:be:29:
- f2:60:42:a9:91:1a:0e:2e:3c:d1:7d:a5:13:14:02:fa:ee:8b:
- 8d:b6:c8:b8:3e:56:81:57:21:24:3f:65:c3:b4:c9:ce:5c:8d:
- 46:ac:53:f3:f9:55:74:c8:2b:fd:d2:78:70:f5:f8:11:e5:f4:
- a7:ad:20:f5:9d:f1:ec:70:f6:13:ac:e6:8c:8d:db:3f:c6:f2:
- 79:0e:ab:52:f2:cc:1b:79:27:cf:16:b3:d6:f3:c6:36:80:43:
- ec:c5:94:f0:dd:90:8d:f8:c6:52:46:56:eb:74:47:be:a6:f3:
- 19:ae:71:4c:c0:e1:e7:d4:cf:ed:d4:06:28:2a:11:3c:ba:d9:
- 41:6e:00:e7:81:37:93:e4:da:62:c6:1d:67:6f:63:b4:14:86:
- d9:a6:62:f0
------BEGIN CERTIFICATE-----
-MIIEwjCCA6qgAwIBAgIQNjSeGMmcJmm2Vi5s5a1xMjANBgkqhkiG9w0BAQsFADCB
-rjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMf
-Q2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIw
-MDggdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxJDAiBgNV
-BAMTG3RoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EgLSBHMzAeFw0xMzA1MjMwMDAwMDBa
-Fw0yMzA1MjIyMzU5NTlaMEMxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwx0aGF3dGUs
-IEluYy4xHTAbBgNVBAMTFHRoYXd0ZSBTSEEyNTYgU1NMIENBMIIBIjANBgkqhkiG
-9w0BAQEFAAOCAQ8AMIIBCgKCAQEAo2Mr1LpdOK6wz7lMON8gffErR3Edi2jzVvmc
-2qrlhCbepXEwvPMxI53oO4DIZld1tlcO25P1Jo5wumRSZooqiFxEGE2oony9VmEy
-kBL5NYdIYLBukGdEAY3nyQ1jaHJyq2M8hrgffa2IJadqiCn7WcZ4cV8suonm04D9
-V+y5UV9DMy5+JTukBNFgjLNEM5MMrSq2RKIZO6/EkG97BYeGmyxqnStsd8kAn8nP
-rO0+G/fD89n4bNSgV8T7KDKqM/Dmupjf5cJOnHS/ikjC8hvwd0BBBwSyOtVMxCmp
-EUA/AkbwkdXSgYOGE7Mx7UarqId2qZl9vM0xUPSltdylMrOLiwIDAQABo4IBRDCC
-AUAwMgYIKwYBBQUHAQEEJjAkMCIGCCsGAQUFBzABhhZodHRwOi8vb2NzcC50aGF3
-dGUuY29tMBIGA1UdEwEB/wQIMAYBAf8CAQAwQQYDVR0gBDowODA2BgpghkgBhvhF
-AQc2MCgwJgYIKwYBBQUHAgEWGmh0dHBzOi8vd3d3LnRoYXd0ZS5jb20vY3BzMDcG
-A1UdHwQwMC4wLKAqoCiGJmh0dHA6Ly9jcmwudGhhd3RlLmNvbS9UaGF3dGVQQ0Et
-RzMuY3JsMA4GA1UdDwEB/wQEAwIBBjAqBgNVHREEIzAhpB8wHTEbMBkGA1UEAxMS
-VmVyaVNpZ25NUEtJLTItNDE1MB0GA1UdDgQWBBQrmjWuARg4MOFwegXgEXajzr2Q
-FDAfBgNVHSMEGDAWgBStbKqUYJzt5P/6Pgp0K2MD97ZZvzANBgkqhkiG9w0BAQsF
-AAOCAQEAdKZW6K+Tlhn7JvkNsESlzel6SAN0AWwTcbfggpCZYiPj1pmv8McenqgY
-Idu0lD80VhuZVS+O8EUzMrdywRNbNNP1YOUuGNFcxWrBqodQDBydZCv/G9zVLmEL
-57m2kVOG2QMq0T17StorB74p8mBCqZEaDi480X2lExQC+u6LjbbIuD5WgVchJD9l
-w7TJzlyNRqxT8/lVdMgr/dJ4cPX4EeX0p60g9Z3x7HD2E6zmjI3bP8byeQ6rUvLM
-G3knzxaz1vPGNoBD7MWU8N2QjfjGUkZW63RHvqbzGa5xTMDh59TP7dQGKCoRPLrZ
-QW4A54E3k+TaYsYdZ29jtBSG2aZi8A==
------END CERTIFICATE-----
-#endif
-static const unsigned char kDERCert34[] = {
- 0x30, 0x82, 0x04, 0xc2, 0x30, 0x82, 0x03, 0xaa, 0xa0, 0x03, 0x02, 0x01,
- 0x02, 0x02, 0x10, 0x36, 0x34, 0x9e, 0x18, 0xc9, 0x9c, 0x26, 0x69, 0xb6,
- 0x56, 0x2e, 0x6c, 0xe5, 0xad, 0x71, 0x32, 0x30, 0x0d, 0x06, 0x09, 0x2a,
- 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x81,
- 0xae, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
- 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13,
- 0x0c, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63,
- 0x2e, 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1f,
- 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f,
- 0x6e, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, 0x44,
- 0x69, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x31, 0x38, 0x30, 0x36, 0x06,
- 0x03, 0x55, 0x04, 0x0b, 0x13, 0x2f, 0x28, 0x63, 0x29, 0x20, 0x32, 0x30,
- 0x30, 0x38, 0x20, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2c, 0x20, 0x49,
- 0x6e, 0x63, 0x2e, 0x20, 0x2d, 0x20, 0x46, 0x6f, 0x72, 0x20, 0x61, 0x75,
- 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x20, 0x75, 0x73, 0x65,
- 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x31, 0x24, 0x30, 0x22, 0x06, 0x03, 0x55,
- 0x04, 0x03, 0x13, 0x1b, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x20, 0x50,
- 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20,
- 0x43, 0x41, 0x20, 0x2d, 0x20, 0x47, 0x33, 0x30, 0x1e, 0x17, 0x0d, 0x31,
- 0x33, 0x30, 0x35, 0x32, 0x33, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a,
- 0x17, 0x0d, 0x32, 0x33, 0x30, 0x35, 0x32, 0x32, 0x32, 0x33, 0x35, 0x39,
- 0x35, 0x39, 0x5a, 0x30, 0x43, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55,
- 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03,
- 0x55, 0x04, 0x0a, 0x13, 0x0c, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2c,
- 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x1d, 0x30, 0x1b, 0x06, 0x03, 0x55,
- 0x04, 0x03, 0x13, 0x14, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x20, 0x53,
- 0x48, 0x41, 0x32, 0x35, 0x36, 0x20, 0x53, 0x53, 0x4c, 0x20, 0x43, 0x41,
- 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
- 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00,
- 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xa3, 0x63, 0x2b,
- 0xd4, 0xba, 0x5d, 0x38, 0xae, 0xb0, 0xcf, 0xb9, 0x4c, 0x38, 0xdf, 0x20,
- 0x7d, 0xf1, 0x2b, 0x47, 0x71, 0x1d, 0x8b, 0x68, 0xf3, 0x56, 0xf9, 0x9c,
- 0xda, 0xaa, 0xe5, 0x84, 0x26, 0xde, 0xa5, 0x71, 0x30, 0xbc, 0xf3, 0x31,
- 0x23, 0x9d, 0xe8, 0x3b, 0x80, 0xc8, 0x66, 0x57, 0x75, 0xb6, 0x57, 0x0e,
- 0xdb, 0x93, 0xf5, 0x26, 0x8e, 0x70, 0xba, 0x64, 0x52, 0x66, 0x8a, 0x2a,
- 0x88, 0x5c, 0x44, 0x18, 0x4d, 0xa8, 0xa2, 0x7c, 0xbd, 0x56, 0x61, 0x32,
- 0x90, 0x12, 0xf9, 0x35, 0x87, 0x48, 0x60, 0xb0, 0x6e, 0x90, 0x67, 0x44,
- 0x01, 0x8d, 0xe7, 0xc9, 0x0d, 0x63, 0x68, 0x72, 0x72, 0xab, 0x63, 0x3c,
- 0x86, 0xb8, 0x1f, 0x7d, 0xad, 0x88, 0x25, 0xa7, 0x6a, 0x88, 0x29, 0xfb,
- 0x59, 0xc6, 0x78, 0x71, 0x5f, 0x2c, 0xba, 0x89, 0xe6, 0xd3, 0x80, 0xfd,
- 0x57, 0xec, 0xb9, 0x51, 0x5f, 0x43, 0x33, 0x2e, 0x7e, 0x25, 0x3b, 0xa4,
- 0x04, 0xd1, 0x60, 0x8c, 0xb3, 0x44, 0x33, 0x93, 0x0c, 0xad, 0x2a, 0xb6,
- 0x44, 0xa2, 0x19, 0x3b, 0xaf, 0xc4, 0x90, 0x6f, 0x7b, 0x05, 0x87, 0x86,
- 0x9b, 0x2c, 0x6a, 0x9d, 0x2b, 0x6c, 0x77, 0xc9, 0x00, 0x9f, 0xc9, 0xcf,
- 0xac, 0xed, 0x3e, 0x1b, 0xf7, 0xc3, 0xf3, 0xd9, 0xf8, 0x6c, 0xd4, 0xa0,
- 0x57, 0xc4, 0xfb, 0x28, 0x32, 0xaa, 0x33, 0xf0, 0xe6, 0xba, 0x98, 0xdf,
- 0xe5, 0xc2, 0x4e, 0x9c, 0x74, 0xbf, 0x8a, 0x48, 0xc2, 0xf2, 0x1b, 0xf0,
- 0x77, 0x40, 0x41, 0x07, 0x04, 0xb2, 0x3a, 0xd5, 0x4c, 0xc4, 0x29, 0xa9,
- 0x11, 0x40, 0x3f, 0x02, 0x46, 0xf0, 0x91, 0xd5, 0xd2, 0x81, 0x83, 0x86,
- 0x13, 0xb3, 0x31, 0xed, 0x46, 0xab, 0xa8, 0x87, 0x76, 0xa9, 0x99, 0x7d,
- 0xbc, 0xcd, 0x31, 0x50, 0xf4, 0xa5, 0xb5, 0xdc, 0xa5, 0x32, 0xb3, 0x8b,
- 0x8b, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x44, 0x30, 0x82,
- 0x01, 0x40, 0x30, 0x32, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
- 0x01, 0x01, 0x04, 0x26, 0x30, 0x24, 0x30, 0x22, 0x06, 0x08, 0x2b, 0x06,
- 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x16, 0x68, 0x74, 0x74, 0x70,
- 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x74, 0x68, 0x61, 0x77,
- 0x74, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d,
- 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02,
- 0x01, 0x00, 0x30, 0x41, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x3a, 0x30,
- 0x38, 0x30, 0x36, 0x06, 0x0a, 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x45,
- 0x01, 0x07, 0x36, 0x30, 0x28, 0x30, 0x26, 0x06, 0x08, 0x2b, 0x06, 0x01,
- 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x1a, 0x68, 0x74, 0x74, 0x70, 0x73,
- 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x74, 0x68, 0x61, 0x77, 0x74,
- 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x70, 0x73, 0x30, 0x37, 0x06,
- 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x30, 0x30, 0x2e, 0x30, 0x2c, 0xa0, 0x2a,
- 0xa0, 0x28, 0x86, 0x26, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63,
- 0x72, 0x6c, 0x2e, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2e, 0x63, 0x6f,
- 0x6d, 0x2f, 0x54, 0x68, 0x61, 0x77, 0x74, 0x65, 0x50, 0x43, 0x41, 0x2d,
- 0x47, 0x33, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d,
- 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x2a,
- 0x06, 0x03, 0x55, 0x1d, 0x11, 0x04, 0x23, 0x30, 0x21, 0xa4, 0x1f, 0x30,
- 0x1d, 0x31, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x12,
- 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x4d, 0x50, 0x4b, 0x49,
- 0x2d, 0x32, 0x2d, 0x34, 0x31, 0x35, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d,
- 0x0e, 0x04, 0x16, 0x04, 0x14, 0x2b, 0x9a, 0x35, 0xae, 0x01, 0x18, 0x38,
- 0x30, 0xe1, 0x70, 0x7a, 0x05, 0xe0, 0x11, 0x76, 0xa3, 0xce, 0xbd, 0x90,
- 0x14, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16,
- 0x80, 0x14, 0xad, 0x6c, 0xaa, 0x94, 0x60, 0x9c, 0xed, 0xe4, 0xff, 0xfa,
- 0x3e, 0x0a, 0x74, 0x2b, 0x63, 0x03, 0xf7, 0xb6, 0x59, 0xbf, 0x30, 0x0d,
- 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05,
- 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x74, 0xa6, 0x56, 0xe8, 0xaf, 0x93,
- 0x96, 0x19, 0xfb, 0x26, 0xf9, 0x0d, 0xb0, 0x44, 0xa5, 0xcd, 0xe9, 0x7a,
- 0x48, 0x03, 0x74, 0x01, 0x6c, 0x13, 0x71, 0xb7, 0xe0, 0x82, 0x90, 0x99,
- 0x62, 0x23, 0xe3, 0xd6, 0x99, 0xaf, 0xf0, 0xc7, 0x1e, 0x9e, 0xa8, 0x18,
- 0x21, 0xdb, 0xb4, 0x94, 0x3f, 0x34, 0x56, 0x1b, 0x99, 0x55, 0x2f, 0x8e,
- 0xf0, 0x45, 0x33, 0x32, 0xb7, 0x72, 0xc1, 0x13, 0x5b, 0x34, 0xd3, 0xf5,
- 0x60, 0xe5, 0x2e, 0x18, 0xd1, 0x5c, 0xc5, 0x6a, 0xc1, 0xaa, 0x87, 0x50,
- 0x0c, 0x1c, 0x9d, 0x64, 0x2b, 0xff, 0x1b, 0xdc, 0xd5, 0x2e, 0x61, 0x0b,
- 0xe7, 0xb9, 0xb6, 0x91, 0x53, 0x86, 0xd9, 0x03, 0x2a, 0xd1, 0x3d, 0x7b,
- 0x4a, 0xda, 0x2b, 0x07, 0xbe, 0x29, 0xf2, 0x60, 0x42, 0xa9, 0x91, 0x1a,
- 0x0e, 0x2e, 0x3c, 0xd1, 0x7d, 0xa5, 0x13, 0x14, 0x02, 0xfa, 0xee, 0x8b,
- 0x8d, 0xb6, 0xc8, 0xb8, 0x3e, 0x56, 0x81, 0x57, 0x21, 0x24, 0x3f, 0x65,
- 0xc3, 0xb4, 0xc9, 0xce, 0x5c, 0x8d, 0x46, 0xac, 0x53, 0xf3, 0xf9, 0x55,
- 0x74, 0xc8, 0x2b, 0xfd, 0xd2, 0x78, 0x70, 0xf5, 0xf8, 0x11, 0xe5, 0xf4,
- 0xa7, 0xad, 0x20, 0xf5, 0x9d, 0xf1, 0xec, 0x70, 0xf6, 0x13, 0xac, 0xe6,
- 0x8c, 0x8d, 0xdb, 0x3f, 0xc6, 0xf2, 0x79, 0x0e, 0xab, 0x52, 0xf2, 0xcc,
- 0x1b, 0x79, 0x27, 0xcf, 0x16, 0xb3, 0xd6, 0xf3, 0xc6, 0x36, 0x80, 0x43,
- 0xec, 0xc5, 0x94, 0xf0, 0xdd, 0x90, 0x8d, 0xf8, 0xc6, 0x52, 0x46, 0x56,
- 0xeb, 0x74, 0x47, 0xbe, 0xa6, 0xf3, 0x19, 0xae, 0x71, 0x4c, 0xc0, 0xe1,
- 0xe7, 0xd4, 0xcf, 0xed, 0xd4, 0x06, 0x28, 0x2a, 0x11, 0x3c, 0xba, 0xd9,
- 0x41, 0x6e, 0x00, 0xe7, 0x81, 0x37, 0x93, 0xe4, 0xda, 0x62, 0xc6, 0x1d,
- 0x67, 0x6f, 0x63, 0xb4, 0x14, 0x86, 0xd9, 0xa6, 0x62, 0xf0,
-};
-
-#if 0
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number:
- 41:82:12:7d:12:d9:c6:b3:21:39:43:12:56:64:00:b8
- Signature Algorithm: sha256WithRSAEncryption
- Issuer: C=US, O=GeoTrust Inc., OU=(c) 2008 GeoTrust Inc. - For authorized use only, CN=GeoTrust Primary Certification Authority - G3
- Validity
- Not Before: May 23 00:00:00 2013 GMT
- Not After : May 22 23:59:59 2023 GMT
- Subject: C=US, O=GeoTrust Inc., CN=GeoTrust SHA256 SSL CA
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:c6:a9:0b:5d:17:a5:7d:c6:cf:2a:ef:c6:66:d1:
- 42:1e:5f:83:78:68:91:af:e6:a7:8b:f0:1d:44:01:
- 0a:19:ca:9c:d4:8b:1d:e1:a1:90:a3:c1:5b:b4:d7:
- 5b:6a:8b:fc:0e:49:1e:c2:62:29:fe:80:15:39:8b:
- 81:2a:27:b5:fb:12:a8:05:22:0b:c5:2c:f5:d9:98:
- dd:16:2f:3b:66:e7:62:a2:43:32:ac:8f:b5:85:c8:
- 52:06:2c:5c:c0:77:fa:67:f7:83:e8:5e:05:8d:c8:
- ab:a1:16:32:8a:d2:40:ec:86:3a:1c:23:a9:8d:b5:
- 00:de:72:bd:85:55:fe:06:01:60:5d:ad:b3:e0:65:
- 73:a5:92:14:9e:94:56:6f:93:ee:af:a9:3a:30:25:
- 4a:8e:09:84:ef:b7:d2:d5:d7:9b:49:cd:e9:c0:5e:
- 67:71:22:ac:50:90:43:20:5d:a1:a3:15:83:fd:fc:
- a7:39:bc:6b:65:48:12:60:ff:dd:23:b3:3a:aa:f4:
- 9f:9c:37:53:41:a2:47:93:81:33:09:e5:22:c6:c8:
- 1c:49:a1:6e:8d:cc:83:b3:9a:cd:ea:43:f2:19:d3:
- 24:cb:a8:29:ae:52:cc:f4:08:27:b0:84:ea:ce:27:
- b5:e1:34:13:73:92:5c:87:86:2a:c6:b0:68:36:ad:
- cb:09
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- Authority Information Access:
- OCSP - URI:http://pca-g3-ocsp.geotrust.com
-
- X509v3 Basic Constraints: critical
- CA:TRUE, pathlen:0
- X509v3 Certificate Policies:
- Policy: 2.16.840.1.113733.1.7.54
- CPS: http://www.geotrust.com/resources/cps
-
- X509v3 CRL Distribution Points:
-
- Full Name:
- URI:http://crl.geotrust.com/GeoTrustPCA-G3.crl
-
- X509v3 Key Usage: critical
- Certificate Sign, CRL Sign
- X509v3 Subject Alternative Name:
- DirName:/CN=VeriSignMPKI-2-416
- X509v3 Subject Key Identifier:
- 14:67:8E:ED:83:4F:D6:1E:9D:40:04:0C:04:46:A1:70:34:B2:0F:72
- X509v3 Authority Key Identifier:
- keyid:C4:79:CA:8E:A1:4E:03:1D:1C:DC:6B:DB:31:5B:94:3E:3F:30:7F:2D
-
- Signature Algorithm: sha256WithRSAEncryption
- 10:10:ea:f2:10:d6:08:46:e2:c1:8f:3e:36:59:c8:2b:0f:fe:
- 4d:ec:e3:f8:b6:56:31:78:25:d4:76:f2:08:dd:ef:3f:cd:8b:
- 1c:7e:aa:7f:fc:0b:a8:23:64:51:b3:87:d6:09:fa:22:fa:c7:
- 0a:51:e8:ce:b8:f6:03:70:e0:1b:5a:b9:b1:b2:93:11:10:f9:
- 97:05:07:29:6c:6d:57:25:54:e8:f9:66:9b:0e:fb:db:9f:ee:
- 96:6f:65:cb:1f:d8:55:ce:31:fa:cf:02:f4:d0:7f:50:66:ff:
- 2f:79:9b:a5:c2:df:d6:cf:c8:15:83:96:84:98:b2:46:d4:5f:
- 13:a8:3e:a7:34:9c:05:38:da:cf:d6:69:95:a9:26:87:76:01:
- d7:b2:51:0f:81:69:46:26:1c:99:b6:83:58:e3:3b:58:8f:dc:
- b4:71:c0:b9:bf:42:9c:1c:03:9e:e4:46:a8:ea:b9:c1:cd:f6:
- 5b:a9:3c:96:fb:79:a4:33:73:a7:9e:78:b9:70:dc:72:74:c4:
- 32:c8:00:1b:c9:ef:48:d3:fb:3a:9b:fa:fe:7a:9a:40:69:1c:
- c8:da:28:37:0b:d3:a3:b9:7e:96:cc:2b:28:c3:56:6c:6f:e9:
- db:52:b1:fa:9a:fb:e7:af:b5:97:a6:22:c3:c5:a8:93:b1:00:
- c9:07:b2:7d
------BEGIN CERTIFICATE-----
-MIIExzCCA6+gAwIBAgIQQYISfRLZxrMhOUMSVmQAuDANBgkqhkiG9w0BAQsFADCB
-mDELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsT
-MChjKSAyMDA4IEdlb1RydXN0IEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25s
-eTE2MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhv
-cml0eSAtIEczMB4XDTEzMDUyMzAwMDAwMFoXDTIzMDUyMjIzNTk1OVowRjELMAkG
-A1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xHzAdBgNVBAMTFkdlb1Ry
-dXN0IFNIQTI1NiBTU0wgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
-AQDGqQtdF6V9xs8q78Zm0UIeX4N4aJGv5qeL8B1EAQoZypzUix3hoZCjwVu011tq
-i/wOSR7CYin+gBU5i4EqJ7X7EqgFIgvFLPXZmN0WLztm52KiQzKsj7WFyFIGLFzA
-d/pn94PoXgWNyKuhFjKK0kDshjocI6mNtQDecr2FVf4GAWBdrbPgZXOlkhSelFZv
-k+6vqTowJUqOCYTvt9LV15tJzenAXmdxIqxQkEMgXaGjFYP9/Kc5vGtlSBJg/90j
-szqq9J+cN1NBokeTgTMJ5SLGyBxJoW6NzIOzms3qQ/IZ0yTLqCmuUsz0CCewhOrO
-J7XhNBNzklyHhirGsGg2rcsJAgMBAAGjggFcMIIBWDA7BggrBgEFBQcBAQQvMC0w
-KwYIKwYBBQUHMAGGH2h0dHA6Ly9wY2EtZzMtb2NzcC5nZW90cnVzdC5jb20wEgYD
-VR0TAQH/BAgwBgEB/wIBADBMBgNVHSAERTBDMEEGCmCGSAGG+EUBBzYwMzAxBggr
-BgEFBQcCARYlaHR0cDovL3d3dy5nZW90cnVzdC5jb20vcmVzb3VyY2VzL2NwczA7
-BgNVHR8ENDAyMDCgLqAshipodHRwOi8vY3JsLmdlb3RydXN0LmNvbS9HZW9UcnVz
-dFBDQS1HMy5jcmwwDgYDVR0PAQH/BAQDAgEGMCoGA1UdEQQjMCGkHzAdMRswGQYD
-VQQDExJWZXJpU2lnbk1QS0ktMi00MTYwHQYDVR0OBBYEFBRnju2DT9YenUAEDARG
-oXA0sg9yMB8GA1UdIwQYMBaAFMR5yo6hTgMdHNxr2zFblD4/MH8tMA0GCSqGSIb3
-DQEBCwUAA4IBAQAQEOryENYIRuLBjz42WcgrD/5N7OP4tlYxeCXUdvII3e8/zYsc
-fqp//AuoI2RRs4fWCfoi+scKUejOuPYDcOAbWrmxspMREPmXBQcpbG1XJVTo+Wab
-Dvvbn+6Wb2XLH9hVzjH6zwL00H9QZv8veZulwt/Wz8gVg5aEmLJG1F8TqD6nNJwF
-ONrP1mmVqSaHdgHXslEPgWlGJhyZtoNY4ztYj9y0ccC5v0KcHAOe5Eao6rnBzfZb
-qTyW+3mkM3Onnni5cNxydMQyyAAbye9I0/s6m/r+eppAaRzI2ig3C9OjuX6WzCso
-w1Zsb+nbUrH6mvvnr7WXpiLDxaiTsQDJB7J9
------END CERTIFICATE-----
-#endif
-static const unsigned char kDERCert35[] = {
- 0x30, 0x82, 0x04, 0xc7, 0x30, 0x82, 0x03, 0xaf, 0xa0, 0x03, 0x02, 0x01,
- 0x02, 0x02, 0x10, 0x41, 0x82, 0x12, 0x7d, 0x12, 0xd9, 0xc6, 0xb3, 0x21,
- 0x39, 0x43, 0x12, 0x56, 0x64, 0x00, 0xb8, 0x30, 0x0d, 0x06, 0x09, 0x2a,
- 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x81,
- 0x98, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
- 0x55, 0x53, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13,
- 0x0d, 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x49, 0x6e,
- 0x63, 0x2e, 0x31, 0x39, 0x30, 0x37, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13,
- 0x30, 0x28, 0x63, 0x29, 0x20, 0x32, 0x30, 0x30, 0x38, 0x20, 0x47, 0x65,
- 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x20,
- 0x2d, 0x20, 0x46, 0x6f, 0x72, 0x20, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72,
- 0x69, 0x7a, 0x65, 0x64, 0x20, 0x75, 0x73, 0x65, 0x20, 0x6f, 0x6e, 0x6c,
- 0x79, 0x31, 0x36, 0x30, 0x34, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x2d,
- 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x50, 0x72, 0x69,
- 0x6d, 0x61, 0x72, 0x79, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69,
- 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f,
- 0x72, 0x69, 0x74, 0x79, 0x20, 0x2d, 0x20, 0x47, 0x33, 0x30, 0x1e, 0x17,
- 0x0d, 0x31, 0x33, 0x30, 0x35, 0x32, 0x33, 0x30, 0x30, 0x30, 0x30, 0x30,
- 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x33, 0x30, 0x35, 0x32, 0x32, 0x32, 0x33,
- 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x46, 0x31, 0x0b, 0x30, 0x09, 0x06,
- 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x16, 0x30, 0x14,
- 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0d, 0x47, 0x65, 0x6f, 0x54, 0x72,
- 0x75, 0x73, 0x74, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x1f, 0x30, 0x1d,
- 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x16, 0x47, 0x65, 0x6f, 0x54, 0x72,
- 0x75, 0x73, 0x74, 0x20, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, 0x20, 0x53,
- 0x53, 0x4c, 0x20, 0x43, 0x41, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06,
- 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00,
- 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01,
- 0x01, 0x00, 0xc6, 0xa9, 0x0b, 0x5d, 0x17, 0xa5, 0x7d, 0xc6, 0xcf, 0x2a,
- 0xef, 0xc6, 0x66, 0xd1, 0x42, 0x1e, 0x5f, 0x83, 0x78, 0x68, 0x91, 0xaf,
- 0xe6, 0xa7, 0x8b, 0xf0, 0x1d, 0x44, 0x01, 0x0a, 0x19, 0xca, 0x9c, 0xd4,
- 0x8b, 0x1d, 0xe1, 0xa1, 0x90, 0xa3, 0xc1, 0x5b, 0xb4, 0xd7, 0x5b, 0x6a,
- 0x8b, 0xfc, 0x0e, 0x49, 0x1e, 0xc2, 0x62, 0x29, 0xfe, 0x80, 0x15, 0x39,
- 0x8b, 0x81, 0x2a, 0x27, 0xb5, 0xfb, 0x12, 0xa8, 0x05, 0x22, 0x0b, 0xc5,
- 0x2c, 0xf5, 0xd9, 0x98, 0xdd, 0x16, 0x2f, 0x3b, 0x66, 0xe7, 0x62, 0xa2,
- 0x43, 0x32, 0xac, 0x8f, 0xb5, 0x85, 0xc8, 0x52, 0x06, 0x2c, 0x5c, 0xc0,
- 0x77, 0xfa, 0x67, 0xf7, 0x83, 0xe8, 0x5e, 0x05, 0x8d, 0xc8, 0xab, 0xa1,
- 0x16, 0x32, 0x8a, 0xd2, 0x40, 0xec, 0x86, 0x3a, 0x1c, 0x23, 0xa9, 0x8d,
- 0xb5, 0x00, 0xde, 0x72, 0xbd, 0x85, 0x55, 0xfe, 0x06, 0x01, 0x60, 0x5d,
- 0xad, 0xb3, 0xe0, 0x65, 0x73, 0xa5, 0x92, 0x14, 0x9e, 0x94, 0x56, 0x6f,
- 0x93, 0xee, 0xaf, 0xa9, 0x3a, 0x30, 0x25, 0x4a, 0x8e, 0x09, 0x84, 0xef,
- 0xb7, 0xd2, 0xd5, 0xd7, 0x9b, 0x49, 0xcd, 0xe9, 0xc0, 0x5e, 0x67, 0x71,
- 0x22, 0xac, 0x50, 0x90, 0x43, 0x20, 0x5d, 0xa1, 0xa3, 0x15, 0x83, 0xfd,
- 0xfc, 0xa7, 0x39, 0xbc, 0x6b, 0x65, 0x48, 0x12, 0x60, 0xff, 0xdd, 0x23,
- 0xb3, 0x3a, 0xaa, 0xf4, 0x9f, 0x9c, 0x37, 0x53, 0x41, 0xa2, 0x47, 0x93,
- 0x81, 0x33, 0x09, 0xe5, 0x22, 0xc6, 0xc8, 0x1c, 0x49, 0xa1, 0x6e, 0x8d,
- 0xcc, 0x83, 0xb3, 0x9a, 0xcd, 0xea, 0x43, 0xf2, 0x19, 0xd3, 0x24, 0xcb,
- 0xa8, 0x29, 0xae, 0x52, 0xcc, 0xf4, 0x08, 0x27, 0xb0, 0x84, 0xea, 0xce,
- 0x27, 0xb5, 0xe1, 0x34, 0x13, 0x73, 0x92, 0x5c, 0x87, 0x86, 0x2a, 0xc6,
- 0xb0, 0x68, 0x36, 0xad, 0xcb, 0x09, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3,
- 0x82, 0x01, 0x5c, 0x30, 0x82, 0x01, 0x58, 0x30, 0x3b, 0x06, 0x08, 0x2b,
- 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x2f, 0x30, 0x2d, 0x30,
- 0x2b, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86,
- 0x1f, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x70, 0x63, 0x61, 0x2d,
- 0x67, 0x33, 0x2d, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x67, 0x65, 0x6f, 0x74,
- 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x12, 0x06, 0x03,
- 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01,
- 0xff, 0x02, 0x01, 0x00, 0x30, 0x4c, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04,
- 0x45, 0x30, 0x43, 0x30, 0x41, 0x06, 0x0a, 0x60, 0x86, 0x48, 0x01, 0x86,
- 0xf8, 0x45, 0x01, 0x07, 0x36, 0x30, 0x33, 0x30, 0x31, 0x06, 0x08, 0x2b,
- 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x25, 0x68, 0x74, 0x74,
- 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x67, 0x65, 0x6f, 0x74,
- 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x73,
- 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x2f, 0x63, 0x70, 0x73, 0x30, 0x3b,
- 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x34, 0x30, 0x32, 0x30, 0x30, 0xa0,
- 0x2e, 0xa0, 0x2c, 0x86, 0x2a, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f,
- 0x63, 0x72, 0x6c, 0x2e, 0x67, 0x65, 0x6f, 0x74, 0x72, 0x75, 0x73, 0x74,
- 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73,
- 0x74, 0x50, 0x43, 0x41, 0x2d, 0x47, 0x33, 0x2e, 0x63, 0x72, 0x6c, 0x30,
- 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03,
- 0x02, 0x01, 0x06, 0x30, 0x2a, 0x06, 0x03, 0x55, 0x1d, 0x11, 0x04, 0x23,
- 0x30, 0x21, 0xa4, 0x1f, 0x30, 0x1d, 0x31, 0x1b, 0x30, 0x19, 0x06, 0x03,
- 0x55, 0x04, 0x03, 0x13, 0x12, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67,
- 0x6e, 0x4d, 0x50, 0x4b, 0x49, 0x2d, 0x32, 0x2d, 0x34, 0x31, 0x36, 0x30,
- 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x14, 0x67,
- 0x8e, 0xed, 0x83, 0x4f, 0xd6, 0x1e, 0x9d, 0x40, 0x04, 0x0c, 0x04, 0x46,
- 0xa1, 0x70, 0x34, 0xb2, 0x0f, 0x72, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d,
- 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0xc4, 0x79, 0xca, 0x8e, 0xa1,
- 0x4e, 0x03, 0x1d, 0x1c, 0xdc, 0x6b, 0xdb, 0x31, 0x5b, 0x94, 0x3e, 0x3f,
- 0x30, 0x7f, 0x2d, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
- 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x10,
- 0x10, 0xea, 0xf2, 0x10, 0xd6, 0x08, 0x46, 0xe2, 0xc1, 0x8f, 0x3e, 0x36,
- 0x59, 0xc8, 0x2b, 0x0f, 0xfe, 0x4d, 0xec, 0xe3, 0xf8, 0xb6, 0x56, 0x31,
- 0x78, 0x25, 0xd4, 0x76, 0xf2, 0x08, 0xdd, 0xef, 0x3f, 0xcd, 0x8b, 0x1c,
- 0x7e, 0xaa, 0x7f, 0xfc, 0x0b, 0xa8, 0x23, 0x64, 0x51, 0xb3, 0x87, 0xd6,
- 0x09, 0xfa, 0x22, 0xfa, 0xc7, 0x0a, 0x51, 0xe8, 0xce, 0xb8, 0xf6, 0x03,
- 0x70, 0xe0, 0x1b, 0x5a, 0xb9, 0xb1, 0xb2, 0x93, 0x11, 0x10, 0xf9, 0x97,
- 0x05, 0x07, 0x29, 0x6c, 0x6d, 0x57, 0x25, 0x54, 0xe8, 0xf9, 0x66, 0x9b,
- 0x0e, 0xfb, 0xdb, 0x9f, 0xee, 0x96, 0x6f, 0x65, 0xcb, 0x1f, 0xd8, 0x55,
- 0xce, 0x31, 0xfa, 0xcf, 0x02, 0xf4, 0xd0, 0x7f, 0x50, 0x66, 0xff, 0x2f,
- 0x79, 0x9b, 0xa5, 0xc2, 0xdf, 0xd6, 0xcf, 0xc8, 0x15, 0x83, 0x96, 0x84,
- 0x98, 0xb2, 0x46, 0xd4, 0x5f, 0x13, 0xa8, 0x3e, 0xa7, 0x34, 0x9c, 0x05,
- 0x38, 0xda, 0xcf, 0xd6, 0x69, 0x95, 0xa9, 0x26, 0x87, 0x76, 0x01, 0xd7,
- 0xb2, 0x51, 0x0f, 0x81, 0x69, 0x46, 0x26, 0x1c, 0x99, 0xb6, 0x83, 0x58,
- 0xe3, 0x3b, 0x58, 0x8f, 0xdc, 0xb4, 0x71, 0xc0, 0xb9, 0xbf, 0x42, 0x9c,
- 0x1c, 0x03, 0x9e, 0xe4, 0x46, 0xa8, 0xea, 0xb9, 0xc1, 0xcd, 0xf6, 0x5b,
- 0xa9, 0x3c, 0x96, 0xfb, 0x79, 0xa4, 0x33, 0x73, 0xa7, 0x9e, 0x78, 0xb9,
- 0x70, 0xdc, 0x72, 0x74, 0xc4, 0x32, 0xc8, 0x00, 0x1b, 0xc9, 0xef, 0x48,
- 0xd3, 0xfb, 0x3a, 0x9b, 0xfa, 0xfe, 0x7a, 0x9a, 0x40, 0x69, 0x1c, 0xc8,
- 0xda, 0x28, 0x37, 0x0b, 0xd3, 0xa3, 0xb9, 0x7e, 0x96, 0xcc, 0x2b, 0x28,
- 0xc3, 0x56, 0x6c, 0x6f, 0xe9, 0xdb, 0x52, 0xb1, 0xfa, 0x9a, 0xfb, 0xe7,
- 0xaf, 0xb5, 0x97, 0xa6, 0x22, 0xc3, 0xc5, 0xa8, 0x93, 0xb1, 0x00, 0xc9,
- 0x07, 0xb2, 0x7d,
-};
-
-#if 0
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number: 7 (0x7)
- Signature Algorithm: sha256WithRSAEncryption
- Issuer: C=US, ST=Arizona, L=Scottsdale, O=GoDaddy.com, Inc., CN=Go Daddy Root Certificate Authority - G2
- Validity
- Not Before: May 3 07:00:00 2011 GMT
- Not After : May 3 07:00:00 2031 GMT
- Subject: C=US, ST=Arizona, L=Scottsdale, O=GoDaddy.com, Inc., OU=http://certs.godaddy.com/repository/, CN=Go Daddy Secure Certificate Authority - G2
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:b9:e0:cb:10:d4:af:76:bd:d4:93:62:eb:30:64:
- b8:81:08:6c:c3:04:d9:62:17:8e:2f:ff:3e:65:cf:
- 8f:ce:62:e6:3c:52:1c:da:16:45:4b:55:ab:78:6b:
- 63:83:62:90:ce:0f:69:6c:99:c8:1a:14:8b:4c:cc:
- 45:33:ea:88:dc:9e:a3:af:2b:fe:80:61:9d:79:57:
- c4:cf:2e:f4:3f:30:3c:5d:47:fc:9a:16:bc:c3:37:
- 96:41:51:8e:11:4b:54:f8:28:be:d0:8c:be:f0:30:
- 38:1e:f3:b0:26:f8:66:47:63:6d:de:71:26:47:8f:
- 38:47:53:d1:46:1d:b4:e3:dc:00:ea:45:ac:bd:bc:
- 71:d9:aa:6f:00:db:db:cd:30:3a:79:4f:5f:4c:47:
- f8:1d:ef:5b:c2:c4:9d:60:3b:b1:b2:43:91:d8:a4:
- 33:4e:ea:b3:d6:27:4f:ad:25:8a:a5:c6:f4:d5:d0:
- a6:ae:74:05:64:57:88:b5:44:55:d4:2d:2a:3a:3e:
- f8:b8:bd:e9:32:0a:02:94:64:c4:16:3a:50:f1:4a:
- ae:e7:79:33:af:0c:20:07:7f:e8:df:04:39:c2:69:
- 02:6c:63:52:fa:77:c1:1b:c8:74:87:c8:b9:93:18:
- 50:54:35:4b:69:4e:bc:3b:d3:49:2e:1f:dc:c1:d2:
- 52:fb
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Basic Constraints: critical
- CA:TRUE
- X509v3 Key Usage: critical
- Certificate Sign, CRL Sign
- X509v3 Subject Key Identifier:
- 40:C2:BD:27:8E:CC:34:83:30:A2:33:D7:FB:6C:B3:F0:B4:2C:80:CE
- X509v3 Authority Key Identifier:
- keyid:3A:9A:85:07:10:67:28:B6:EF:F6:BD:05:41:6E:20:C1:94:DA:0F:DE
-
- Authority Information Access:
- OCSP - URI:http://ocsp.godaddy.com/
-
- X509v3 CRL Distribution Points:
-
- Full Name:
- URI:http://crl.godaddy.com/gdroot-g2.crl
-
- X509v3 Certificate Policies:
- Policy: X509v3 Any Policy
- CPS: https://certs.godaddy.com/repository/
-
- Signature Algorithm: sha256WithRSAEncryption
- 08:7e:6c:93:10:c8:38:b8:96:a9:90:4b:ff:a1:5f:4f:04:ef:
- 6c:3e:9c:88:06:c9:50:8f:a6:73:f7:57:31:1b:be:bc:e4:2f:
- db:f8:ba:d3:5b:e0:b4:e7:e6:79:62:0e:0c:a2:d7:6a:63:73:
- 31:b5:f5:a8:48:a4:3b:08:2d:a2:5d:90:d7:b4:7c:25:4f:11:
- 56:30:c4:b6:44:9d:7b:2c:9d:e5:5e:e6:ef:0c:61:aa:bf:e4:
- 2a:1b:ee:84:9e:b8:83:7d:c1:43:ce:44:a7:13:70:0d:91:1f:
- f4:c8:13:ad:83:60:d9:d8:72:a8:73:24:1e:b5:ac:22:0e:ca:
- 17:89:62:58:44:1b:ab:89:25:01:00:0f:cd:c4:1b:62:db:51:
- b4:d3:0f:51:2a:9b:f4:bc:73:fc:76:ce:36:a4:cd:d9:d8:2c:
- ea:ae:9b:f5:2a:b2:90:d1:4d:75:18:8a:3f:8a:41:90:23:7d:
- 5b:4b:fe:a4:03:58:9b:46:b2:c3:60:60:83:f8:7d:50:41:ce:
- c2:a1:90:c3:bb:ef:02:2f:d2:15:54:ee:44:15:d9:0a:ae:a7:
- 8a:33:ed:b1:2d:76:36:26:dc:04:eb:9f:f7:61:1f:15:dc:87:
- 6f:ee:46:96:28:ad:a1:26:7d:0a:09:a7:2e:04:a3:8d:bc:f8:
- bc:04:30:01
------BEGIN CERTIFICATE-----
-MIIE0DCCA7igAwIBAgIBBzANBgkqhkiG9w0BAQsFADCBgzELMAkGA1UEBhMCVVMx
-EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAYBgNVBAoT
-EUdvRGFkZHkuY29tLCBJbmMuMTEwLwYDVQQDEyhHbyBEYWRkeSBSb290IENlcnRp
-ZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTExMDUwMzA3MDAwMFoXDTMxMDUwMzA3
-MDAwMFowgbQxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6b25hMRMwEQYDVQQH
-EwpTY290dHNkYWxlMRowGAYDVQQKExFHb0RhZGR5LmNvbSwgSW5jLjEtMCsGA1UE
-CxMkaHR0cDovL2NlcnRzLmdvZGFkZHkuY29tL3JlcG9zaXRvcnkvMTMwMQYDVQQD
-EypHbyBEYWRkeSBTZWN1cmUgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IC0gRzIwggEi
-MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC54MsQ1K92vdSTYuswZLiBCGzD
-BNliF44v/z5lz4/OYuY8UhzaFkVLVat4a2ODYpDOD2lsmcgaFItMzEUz6ojcnqOv
-K/6AYZ15V8TPLvQ/MDxdR/yaFrzDN5ZBUY4RS1T4KL7QjL7wMDge87Am+GZHY23e
-cSZHjzhHU9FGHbTj3ADqRay9vHHZqm8A29vNMDp5T19MR/gd71vCxJ1gO7GyQ5HY
-pDNO6rPWJ0+tJYqlxvTV0KaudAVkV4i1RFXULSo6Pvi4vekyCgKUZMQWOlDxSq7n
-eTOvDCAHf+jfBDnCaQJsY1L6d8EbyHSHyLmTGFBUNUtpTrw700kuH9zB0lL7AgMB
-AAGjggEaMIIBFjAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNV
-HQ4EFgQUQMK9J47MNIMwojPX+2yz8LQsgM4wHwYDVR0jBBgwFoAUOpqFBxBnKLbv
-9r0FQW4gwZTaD94wNAYIKwYBBQUHAQEEKDAmMCQGCCsGAQUFBzABhhhodHRwOi8v
-b2NzcC5nb2RhZGR5LmNvbS8wNQYDVR0fBC4wLDAqoCigJoYkaHR0cDovL2NybC5n
-b2RhZGR5LmNvbS9nZHJvb3QtZzIuY3JsMEYGA1UdIAQ/MD0wOwYEVR0gADAzMDEG
-CCsGAQUFBwIBFiVodHRwczovL2NlcnRzLmdvZGFkZHkuY29tL3JlcG9zaXRvcnkv
-MA0GCSqGSIb3DQEBCwUAA4IBAQAIfmyTEMg4uJapkEv/oV9PBO9sPpyIBslQj6Zz
-91cxG7685C/b+LrTW+C05+Z5Yg4MotdqY3MxtfWoSKQ7CC2iXZDXtHwlTxFWMMS2
-RJ17LJ3lXubvDGGqv+QqG+6EnriDfcFDzkSnE3ANkR/0yBOtg2DZ2HKocyQetawi
-DsoXiWJYRBuriSUBAA/NxBti21G00w9RKpv0vHP8ds42pM3Z2Czqrpv1KrKQ0U11
-GIo/ikGQI31bS/6kA1ibRrLDYGCD+H1QQc7CoZDDu+8CL9IVVO5EFdkKrqeKM+2x
-LXY2JtwE65/3YR8V3Idv7kaWKK2hJn0KCacuBKONvPi8BDAB
------END CERTIFICATE-----
-#endif
-static const unsigned char kDERCert36[] = {
- 0x30, 0x82, 0x04, 0xd0, 0x30, 0x82, 0x03, 0xb8, 0xa0, 0x03, 0x02, 0x01,
- 0x02, 0x02, 0x01, 0x07, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
- 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x81, 0x83, 0x31, 0x0b,
- 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31,
- 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x07, 0x41, 0x72,
- 0x69, 0x7a, 0x6f, 0x6e, 0x61, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55,
- 0x04, 0x07, 0x13, 0x0a, 0x53, 0x63, 0x6f, 0x74, 0x74, 0x73, 0x64, 0x61,
- 0x6c, 0x65, 0x31, 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13,
- 0x11, 0x47, 0x6f, 0x44, 0x61, 0x64, 0x64, 0x79, 0x2e, 0x63, 0x6f, 0x6d,
- 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x31, 0x30, 0x2f, 0x06, 0x03,
- 0x55, 0x04, 0x03, 0x13, 0x28, 0x47, 0x6f, 0x20, 0x44, 0x61, 0x64, 0x64,
- 0x79, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69,
- 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f,
- 0x72, 0x69, 0x74, 0x79, 0x20, 0x2d, 0x20, 0x47, 0x32, 0x30, 0x1e, 0x17,
- 0x0d, 0x31, 0x31, 0x30, 0x35, 0x30, 0x33, 0x30, 0x37, 0x30, 0x30, 0x30,
- 0x30, 0x5a, 0x17, 0x0d, 0x33, 0x31, 0x30, 0x35, 0x30, 0x33, 0x30, 0x37,
- 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x81, 0xb4, 0x31, 0x0b, 0x30, 0x09,
- 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x10, 0x30,
- 0x0e, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x07, 0x41, 0x72, 0x69, 0x7a,
- 0x6f, 0x6e, 0x61, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x07,
- 0x13, 0x0a, 0x53, 0x63, 0x6f, 0x74, 0x74, 0x73, 0x64, 0x61, 0x6c, 0x65,
- 0x31, 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x11, 0x47,
- 0x6f, 0x44, 0x61, 0x64, 0x64, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x2c, 0x20,
- 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x2d, 0x30, 0x2b, 0x06, 0x03, 0x55, 0x04,
- 0x0b, 0x13, 0x24, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x65,
- 0x72, 0x74, 0x73, 0x2e, 0x67, 0x6f, 0x64, 0x61, 0x64, 0x64, 0x79, 0x2e,
- 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f,
- 0x72, 0x79, 0x2f, 0x31, 0x33, 0x30, 0x31, 0x06, 0x03, 0x55, 0x04, 0x03,
- 0x13, 0x2a, 0x47, 0x6f, 0x20, 0x44, 0x61, 0x64, 0x64, 0x79, 0x20, 0x53,
- 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66,
- 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72,
- 0x69, 0x74, 0x79, 0x20, 0x2d, 0x20, 0x47, 0x32, 0x30, 0x82, 0x01, 0x22,
- 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
- 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a,
- 0x02, 0x82, 0x01, 0x01, 0x00, 0xb9, 0xe0, 0xcb, 0x10, 0xd4, 0xaf, 0x76,
- 0xbd, 0xd4, 0x93, 0x62, 0xeb, 0x30, 0x64, 0xb8, 0x81, 0x08, 0x6c, 0xc3,
- 0x04, 0xd9, 0x62, 0x17, 0x8e, 0x2f, 0xff, 0x3e, 0x65, 0xcf, 0x8f, 0xce,
- 0x62, 0xe6, 0x3c, 0x52, 0x1c, 0xda, 0x16, 0x45, 0x4b, 0x55, 0xab, 0x78,
- 0x6b, 0x63, 0x83, 0x62, 0x90, 0xce, 0x0f, 0x69, 0x6c, 0x99, 0xc8, 0x1a,
- 0x14, 0x8b, 0x4c, 0xcc, 0x45, 0x33, 0xea, 0x88, 0xdc, 0x9e, 0xa3, 0xaf,
- 0x2b, 0xfe, 0x80, 0x61, 0x9d, 0x79, 0x57, 0xc4, 0xcf, 0x2e, 0xf4, 0x3f,
- 0x30, 0x3c, 0x5d, 0x47, 0xfc, 0x9a, 0x16, 0xbc, 0xc3, 0x37, 0x96, 0x41,
- 0x51, 0x8e, 0x11, 0x4b, 0x54, 0xf8, 0x28, 0xbe, 0xd0, 0x8c, 0xbe, 0xf0,
- 0x30, 0x38, 0x1e, 0xf3, 0xb0, 0x26, 0xf8, 0x66, 0x47, 0x63, 0x6d, 0xde,
- 0x71, 0x26, 0x47, 0x8f, 0x38, 0x47, 0x53, 0xd1, 0x46, 0x1d, 0xb4, 0xe3,
- 0xdc, 0x00, 0xea, 0x45, 0xac, 0xbd, 0xbc, 0x71, 0xd9, 0xaa, 0x6f, 0x00,
- 0xdb, 0xdb, 0xcd, 0x30, 0x3a, 0x79, 0x4f, 0x5f, 0x4c, 0x47, 0xf8, 0x1d,
- 0xef, 0x5b, 0xc2, 0xc4, 0x9d, 0x60, 0x3b, 0xb1, 0xb2, 0x43, 0x91, 0xd8,
- 0xa4, 0x33, 0x4e, 0xea, 0xb3, 0xd6, 0x27, 0x4f, 0xad, 0x25, 0x8a, 0xa5,
- 0xc6, 0xf4, 0xd5, 0xd0, 0xa6, 0xae, 0x74, 0x05, 0x64, 0x57, 0x88, 0xb5,
- 0x44, 0x55, 0xd4, 0x2d, 0x2a, 0x3a, 0x3e, 0xf8, 0xb8, 0xbd, 0xe9, 0x32,
- 0x0a, 0x02, 0x94, 0x64, 0xc4, 0x16, 0x3a, 0x50, 0xf1, 0x4a, 0xae, 0xe7,
- 0x79, 0x33, 0xaf, 0x0c, 0x20, 0x07, 0x7f, 0xe8, 0xdf, 0x04, 0x39, 0xc2,
- 0x69, 0x02, 0x6c, 0x63, 0x52, 0xfa, 0x77, 0xc1, 0x1b, 0xc8, 0x74, 0x87,
- 0xc8, 0xb9, 0x93, 0x18, 0x50, 0x54, 0x35, 0x4b, 0x69, 0x4e, 0xbc, 0x3b,
- 0xd3, 0x49, 0x2e, 0x1f, 0xdc, 0xc1, 0xd2, 0x52, 0xfb, 0x02, 0x03, 0x01,
- 0x00, 0x01, 0xa3, 0x82, 0x01, 0x1a, 0x30, 0x82, 0x01, 0x16, 0x30, 0x0f,
- 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, 0x30, 0x03,
- 0x01, 0x01, 0xff, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01,
- 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x1d, 0x06, 0x03, 0x55,
- 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x40, 0xc2, 0xbd, 0x27, 0x8e, 0xcc,
- 0x34, 0x83, 0x30, 0xa2, 0x33, 0xd7, 0xfb, 0x6c, 0xb3, 0xf0, 0xb4, 0x2c,
- 0x80, 0xce, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30,
- 0x16, 0x80, 0x14, 0x3a, 0x9a, 0x85, 0x07, 0x10, 0x67, 0x28, 0xb6, 0xef,
- 0xf6, 0xbd, 0x05, 0x41, 0x6e, 0x20, 0xc1, 0x94, 0xda, 0x0f, 0xde, 0x30,
- 0x34, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04,
- 0x28, 0x30, 0x26, 0x30, 0x24, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05,
- 0x07, 0x30, 0x01, 0x86, 0x18, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f,
- 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x67, 0x6f, 0x64, 0x61, 0x64, 0x64, 0x79,
- 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x30, 0x35, 0x06, 0x03, 0x55, 0x1d, 0x1f,
- 0x04, 0x2e, 0x30, 0x2c, 0x30, 0x2a, 0xa0, 0x28, 0xa0, 0x26, 0x86, 0x24,
- 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x67,
- 0x6f, 0x64, 0x61, 0x64, 0x64, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67,
- 0x64, 0x72, 0x6f, 0x6f, 0x74, 0x2d, 0x67, 0x32, 0x2e, 0x63, 0x72, 0x6c,
- 0x30, 0x46, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x3f, 0x30, 0x3d, 0x30,
- 0x3b, 0x06, 0x04, 0x55, 0x1d, 0x20, 0x00, 0x30, 0x33, 0x30, 0x31, 0x06,
- 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x25, 0x68,
- 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x63, 0x65, 0x72, 0x74, 0x73,
- 0x2e, 0x67, 0x6f, 0x64, 0x61, 0x64, 0x64, 0x79, 0x2e, 0x63, 0x6f, 0x6d,
- 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x2f,
- 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
- 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x08, 0x7e, 0x6c, 0x93,
- 0x10, 0xc8, 0x38, 0xb8, 0x96, 0xa9, 0x90, 0x4b, 0xff, 0xa1, 0x5f, 0x4f,
- 0x04, 0xef, 0x6c, 0x3e, 0x9c, 0x88, 0x06, 0xc9, 0x50, 0x8f, 0xa6, 0x73,
- 0xf7, 0x57, 0x31, 0x1b, 0xbe, 0xbc, 0xe4, 0x2f, 0xdb, 0xf8, 0xba, 0xd3,
- 0x5b, 0xe0, 0xb4, 0xe7, 0xe6, 0x79, 0x62, 0x0e, 0x0c, 0xa2, 0xd7, 0x6a,
- 0x63, 0x73, 0x31, 0xb5, 0xf5, 0xa8, 0x48, 0xa4, 0x3b, 0x08, 0x2d, 0xa2,
- 0x5d, 0x90, 0xd7, 0xb4, 0x7c, 0x25, 0x4f, 0x11, 0x56, 0x30, 0xc4, 0xb6,
- 0x44, 0x9d, 0x7b, 0x2c, 0x9d, 0xe5, 0x5e, 0xe6, 0xef, 0x0c, 0x61, 0xaa,
- 0xbf, 0xe4, 0x2a, 0x1b, 0xee, 0x84, 0x9e, 0xb8, 0x83, 0x7d, 0xc1, 0x43,
- 0xce, 0x44, 0xa7, 0x13, 0x70, 0x0d, 0x91, 0x1f, 0xf4, 0xc8, 0x13, 0xad,
- 0x83, 0x60, 0xd9, 0xd8, 0x72, 0xa8, 0x73, 0x24, 0x1e, 0xb5, 0xac, 0x22,
- 0x0e, 0xca, 0x17, 0x89, 0x62, 0x58, 0x44, 0x1b, 0xab, 0x89, 0x25, 0x01,
- 0x00, 0x0f, 0xcd, 0xc4, 0x1b, 0x62, 0xdb, 0x51, 0xb4, 0xd3, 0x0f, 0x51,
- 0x2a, 0x9b, 0xf4, 0xbc, 0x73, 0xfc, 0x76, 0xce, 0x36, 0xa4, 0xcd, 0xd9,
- 0xd8, 0x2c, 0xea, 0xae, 0x9b, 0xf5, 0x2a, 0xb2, 0x90, 0xd1, 0x4d, 0x75,
- 0x18, 0x8a, 0x3f, 0x8a, 0x41, 0x90, 0x23, 0x7d, 0x5b, 0x4b, 0xfe, 0xa4,
- 0x03, 0x58, 0x9b, 0x46, 0xb2, 0xc3, 0x60, 0x60, 0x83, 0xf8, 0x7d, 0x50,
- 0x41, 0xce, 0xc2, 0xa1, 0x90, 0xc3, 0xbb, 0xef, 0x02, 0x2f, 0xd2, 0x15,
- 0x54, 0xee, 0x44, 0x15, 0xd9, 0x0a, 0xae, 0xa7, 0x8a, 0x33, 0xed, 0xb1,
- 0x2d, 0x76, 0x36, 0x26, 0xdc, 0x04, 0xeb, 0x9f, 0xf7, 0x61, 0x1f, 0x15,
- 0xdc, 0x87, 0x6f, 0xee, 0x46, 0x96, 0x28, 0xad, 0xa1, 0x26, 0x7d, 0x0a,
- 0x09, 0xa7, 0x2e, 0x04, 0xa3, 0x8d, 0xbc, 0xf8, 0xbc, 0x04, 0x30, 0x01,
-};
-
-#if 0
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number:
- 25:0c:e8:e0:30:61:2e:9f:2b:89:f7:05:4d:7c:f8:fd
- Signature Algorithm: sha1WithRSAEncryption
- Issuer: C=US, O=VeriSign, Inc., OU=Class 3 Public Primary Certification Authority
- Validity
- Not Before: Nov 8 00:00:00 2006 GMT
- Not After : Nov 7 23:59:59 2021 GMT
- Subject: C=US, O=VeriSign, Inc., OU=VeriSign Trust Network, OU=(c) 2006 VeriSign, Inc. - For authorized use only, CN=VeriSign Class 3 Public Primary Certification Authority - G5
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:af:24:08:08:29:7a:35:9e:60:0c:aa:e7:4b:3b:
- 4e:dc:7c:bc:3c:45:1c:bb:2b:e0:fe:29:02:f9:57:
- 08:a3:64:85:15:27:f5:f1:ad:c8:31:89:5d:22:e8:
- 2a:aa:a6:42:b3:8f:f8:b9:55:b7:b1:b7:4b:b3:fe:
- 8f:7e:07:57:ec:ef:43:db:66:62:15:61:cf:60:0d:
- a4:d8:de:f8:e0:c3:62:08:3d:54:13:eb:49:ca:59:
- 54:85:26:e5:2b:8f:1b:9f:eb:f5:a1:91:c2:33:49:
- d8:43:63:6a:52:4b:d2:8f:e8:70:51:4d:d1:89:69:
- 7b:c7:70:f6:b3:dc:12:74:db:7b:5d:4b:56:d3:96:
- bf:15:77:a1:b0:f4:a2:25:f2:af:1c:92:67:18:e5:
- f4:06:04:ef:90:b9:e4:00:e4:dd:3a:b5:19:ff:02:
- ba:f4:3c:ee:e0:8b:eb:37:8b:ec:f4:d7:ac:f2:f6:
- f0:3d:af:dd:75:91:33:19:1d:1c:40:cb:74:24:19:
- 21:93:d9:14:fe:ac:2a:52:c7:8f:d5:04:49:e4:8d:
- 63:47:88:3c:69:83:cb:fe:47:bd:2b:7e:4f:c5:95:
- ae:0e:9d:d4:d1:43:c0:67:73:e3:14:08:7e:e5:3f:
- 9f:73:b8:33:0a:cf:5d:3f:34:87:96:8a:ee:53:e8:
- 25:15
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Basic Constraints: critical
- CA:TRUE
- X509v3 CRL Distribution Points:
-
- Full Name:
- URI:http://crl.verisign.com/pca3.crl
-
- X509v3 Key Usage: critical
- Certificate Sign, CRL Sign
- X509v3 Certificate Policies:
- Policy: X509v3 Any Policy
- CPS: https://www.verisign.com/cps
-
- X509v3 Subject Key Identifier:
- 7F:D3:65:A7:C2:DD:EC:BB:F0:30:09:F3:43:39:FA:02:AF:33:31:33
- 1.3.6.1.5.5.7.1.12:
- 0_.].[0Y0W0U..image/gif0!0.0...+..............k...j.H.,{..0%.#http://logo.verisign.com/vslogo.gif
- Authority Information Access:
- OCSP - URI:http://ocsp.verisign.com
-
- X509v3 Extended Key Usage:
- TLS Web Server Authentication, TLS Web Client Authentication, Code Signing, Netscape Server Gated Crypto, 2.16.840.1.113733.1.8.1
- Signature Algorithm: sha1WithRSAEncryption
- 13:02:dd:f8:e8:86:00:f2:5a:f8:f8:20:0c:59:88:62:07:ce:
- ce:f7:4e:f9:bb:59:a1:98:e5:e1:38:dd:4e:bc:66:18:d3:ad:
- eb:18:f2:0d:c9:6d:3e:4a:94:20:c3:3c:ba:bd:65:54:c6:af:
- 44:b3:10:ad:2c:6b:3e:ab:d7:07:b6:b8:81:63:c5:f9:5e:2e:
- e5:2a:67:ce:cd:33:0c:2a:d7:89:56:03:23:1f:b3:be:e8:3a:
- 08:59:b4:ec:45:35:f7:8a:5b:ff:66:cf:50:af:c6:6d:57:8d:
- 19:78:b7:b9:a2:d1:57:ea:1f:9a:4b:af:ba:c9:8e:12:7e:c6:
- bd:ff
------BEGIN CERTIFICATE-----
-MIIE0DCCBDmgAwIBAgIQJQzo4DBhLp8rifcFTXz4/TANBgkqhkiG9w0BAQUFADBf
-MQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xNzA1BgNVBAsT
-LkNsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkw
-HhcNMDYxMTA4MDAwMDAwWhcNMjExMTA3MjM1OTU5WjCByjELMAkGA1UEBhMCVVMx
-FzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBUcnVz
-dCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJpU2lnbiwgSW5jLiAtIEZv
-ciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAz
-IFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzUwggEi
-MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvJAgIKXo1nmAMqudLO07cfLw8
-RRy7K+D+KQL5VwijZIUVJ/XxrcgxiV0i6CqqpkKzj/i5Vbext0uz/o9+B1fs70Pb
-ZmIVYc9gDaTY3vjgw2IIPVQT60nKWVSFJuUrjxuf6/WhkcIzSdhDY2pSS9KP6HBR
-TdGJaXvHcPaz3BJ023tdS1bTlr8Vd6Gw9KIl8q8ckmcY5fQGBO+QueQA5N06tRn/
-Arr0PO7gi+s3i+z016zy9vA9r911kTMZHRxAy3QkGSGT2RT+rCpSx4/VBEnkjWNH
-iDxpg8v+R70rfk/Fla4OndTRQ8Bnc+MUCH7lP59zuDMKz10/NIeWiu5T6CUVAgMB
-AAGjggGbMIIBlzAPBgNVHRMBAf8EBTADAQH/MDEGA1UdHwQqMCgwJqAkoCKGIGh0
-dHA6Ly9jcmwudmVyaXNpZ24uY29tL3BjYTMuY3JsMA4GA1UdDwEB/wQEAwIBBjA9
-BgNVHSAENjA0MDIGBFUdIAAwKjAoBggrBgEFBQcCARYcaHR0cHM6Ly93d3cudmVy
-aXNpZ24uY29tL2NwczAdBgNVHQ4EFgQUf9Nlp8Ld7LvwMAnzQzn6Aq8zMTMwbQYI
-KwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2UvZ2lmMCEwHzAHBgUrDgMCGgQU
-j+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDovL2xvZ28udmVyaXNpZ24uY29t
-L3ZzbG9nby5naWYwNAYIKwYBBQUHAQEEKDAmMCQGCCsGAQUFBzABhhhodHRwOi8v
-b2NzcC52ZXJpc2lnbi5jb20wPgYDVR0lBDcwNQYIKwYBBQUHAwEGCCsGAQUFBwMC
-BggrBgEFBQcDAwYJYIZIAYb4QgQBBgpghkgBhvhFAQgBMA0GCSqGSIb3DQEBBQUA
-A4GBABMC3fjohgDyWvj4IAxZiGIHzs73Tvm7WaGY5eE43U68ZhjTresY8g3JbT5K
-lCDDPLq9ZVTGr0SzEK0saz6r1we2uIFjxfleLuUqZ87NMwwq14lWAyMfs77oOghZ
-tOxFNfeKW/9mz1Cvxm1XjRl4t7mi0VfqH5pLr7rJjhJ+xr3/
------END CERTIFICATE-----
-#endif
-static const unsigned char kDERCert37[] = {
- 0x30, 0x82, 0x04, 0xd0, 0x30, 0x82, 0x04, 0x39, 0xa0, 0x03, 0x02, 0x01,
- 0x02, 0x02, 0x10, 0x25, 0x0c, 0xe8, 0xe0, 0x30, 0x61, 0x2e, 0x9f, 0x2b,
- 0x89, 0xf7, 0x05, 0x4d, 0x7c, 0xf8, 0xfd, 0x30, 0x0d, 0x06, 0x09, 0x2a,
- 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x5f,
- 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55,
- 0x53, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0e,
- 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e,
- 0x63, 0x2e, 0x31, 0x37, 0x30, 0x35, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13,
- 0x2e, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x33, 0x20, 0x50, 0x75, 0x62,
- 0x6c, 0x69, 0x63, 0x20, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x20,
- 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f,
- 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x30,
- 0x1e, 0x17, 0x0d, 0x30, 0x36, 0x31, 0x31, 0x30, 0x38, 0x30, 0x30, 0x30,
- 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x31, 0x31, 0x31, 0x30, 0x37,
- 0x32, 0x33, 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x81, 0xca, 0x31, 0x0b,
- 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31,
- 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0e, 0x56, 0x65,
- 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e,
- 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x16, 0x56,
- 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x54, 0x72, 0x75, 0x73,
- 0x74, 0x20, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x31, 0x3a, 0x30,
- 0x38, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x31, 0x28, 0x63, 0x29, 0x20,
- 0x32, 0x30, 0x30, 0x36, 0x20, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67,
- 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x20, 0x2d, 0x20, 0x46, 0x6f,
- 0x72, 0x20, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64,
- 0x20, 0x75, 0x73, 0x65, 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x31, 0x45, 0x30,
- 0x43, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x3c, 0x56, 0x65, 0x72, 0x69,
- 0x53, 0x69, 0x67, 0x6e, 0x20, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x33,
- 0x20, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x20, 0x50, 0x72, 0x69, 0x6d,
- 0x61, 0x72, 0x79, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63,
- 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72,
- 0x69, 0x74, 0x79, 0x20, 0x2d, 0x20, 0x47, 0x35, 0x30, 0x82, 0x01, 0x22,
- 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
- 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a,
- 0x02, 0x82, 0x01, 0x01, 0x00, 0xaf, 0x24, 0x08, 0x08, 0x29, 0x7a, 0x35,
- 0x9e, 0x60, 0x0c, 0xaa, 0xe7, 0x4b, 0x3b, 0x4e, 0xdc, 0x7c, 0xbc, 0x3c,
- 0x45, 0x1c, 0xbb, 0x2b, 0xe0, 0xfe, 0x29, 0x02, 0xf9, 0x57, 0x08, 0xa3,
- 0x64, 0x85, 0x15, 0x27, 0xf5, 0xf1, 0xad, 0xc8, 0x31, 0x89, 0x5d, 0x22,
- 0xe8, 0x2a, 0xaa, 0xa6, 0x42, 0xb3, 0x8f, 0xf8, 0xb9, 0x55, 0xb7, 0xb1,
- 0xb7, 0x4b, 0xb3, 0xfe, 0x8f, 0x7e, 0x07, 0x57, 0xec, 0xef, 0x43, 0xdb,
- 0x66, 0x62, 0x15, 0x61, 0xcf, 0x60, 0x0d, 0xa4, 0xd8, 0xde, 0xf8, 0xe0,
- 0xc3, 0x62, 0x08, 0x3d, 0x54, 0x13, 0xeb, 0x49, 0xca, 0x59, 0x54, 0x85,
- 0x26, 0xe5, 0x2b, 0x8f, 0x1b, 0x9f, 0xeb, 0xf5, 0xa1, 0x91, 0xc2, 0x33,
- 0x49, 0xd8, 0x43, 0x63, 0x6a, 0x52, 0x4b, 0xd2, 0x8f, 0xe8, 0x70, 0x51,
- 0x4d, 0xd1, 0x89, 0x69, 0x7b, 0xc7, 0x70, 0xf6, 0xb3, 0xdc, 0x12, 0x74,
- 0xdb, 0x7b, 0x5d, 0x4b, 0x56, 0xd3, 0x96, 0xbf, 0x15, 0x77, 0xa1, 0xb0,
- 0xf4, 0xa2, 0x25, 0xf2, 0xaf, 0x1c, 0x92, 0x67, 0x18, 0xe5, 0xf4, 0x06,
- 0x04, 0xef, 0x90, 0xb9, 0xe4, 0x00, 0xe4, 0xdd, 0x3a, 0xb5, 0x19, 0xff,
- 0x02, 0xba, 0xf4, 0x3c, 0xee, 0xe0, 0x8b, 0xeb, 0x37, 0x8b, 0xec, 0xf4,
- 0xd7, 0xac, 0xf2, 0xf6, 0xf0, 0x3d, 0xaf, 0xdd, 0x75, 0x91, 0x33, 0x19,
- 0x1d, 0x1c, 0x40, 0xcb, 0x74, 0x24, 0x19, 0x21, 0x93, 0xd9, 0x14, 0xfe,
- 0xac, 0x2a, 0x52, 0xc7, 0x8f, 0xd5, 0x04, 0x49, 0xe4, 0x8d, 0x63, 0x47,
- 0x88, 0x3c, 0x69, 0x83, 0xcb, 0xfe, 0x47, 0xbd, 0x2b, 0x7e, 0x4f, 0xc5,
- 0x95, 0xae, 0x0e, 0x9d, 0xd4, 0xd1, 0x43, 0xc0, 0x67, 0x73, 0xe3, 0x14,
- 0x08, 0x7e, 0xe5, 0x3f, 0x9f, 0x73, 0xb8, 0x33, 0x0a, 0xcf, 0x5d, 0x3f,
- 0x34, 0x87, 0x96, 0x8a, 0xee, 0x53, 0xe8, 0x25, 0x15, 0x02, 0x03, 0x01,
- 0x00, 0x01, 0xa3, 0x82, 0x01, 0x9b, 0x30, 0x82, 0x01, 0x97, 0x30, 0x0f,
- 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, 0x30, 0x03,
- 0x01, 0x01, 0xff, 0x30, 0x31, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x2a,
- 0x30, 0x28, 0x30, 0x26, 0xa0, 0x24, 0xa0, 0x22, 0x86, 0x20, 0x68, 0x74,
- 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x76, 0x65, 0x72,
- 0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x63,
- 0x61, 0x33, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d,
- 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x3d,
- 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x36, 0x30, 0x34, 0x30, 0x32, 0x06,
- 0x04, 0x55, 0x1d, 0x20, 0x00, 0x30, 0x2a, 0x30, 0x28, 0x06, 0x08, 0x2b,
- 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x1c, 0x68, 0x74, 0x74,
- 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x76, 0x65, 0x72,
- 0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x70,
- 0x73, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14,
- 0x7f, 0xd3, 0x65, 0xa7, 0xc2, 0xdd, 0xec, 0xbb, 0xf0, 0x30, 0x09, 0xf3,
- 0x43, 0x39, 0xfa, 0x02, 0xaf, 0x33, 0x31, 0x33, 0x30, 0x6d, 0x06, 0x08,
- 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x0c, 0x04, 0x61, 0x30, 0x5f,
- 0xa1, 0x5d, 0xa0, 0x5b, 0x30, 0x59, 0x30, 0x57, 0x30, 0x55, 0x16, 0x09,
- 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2f, 0x67, 0x69, 0x66, 0x30, 0x21, 0x30,
- 0x1f, 0x30, 0x07, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x04, 0x14,
- 0x8f, 0xe5, 0xd3, 0x1a, 0x86, 0xac, 0x8d, 0x8e, 0x6b, 0xc3, 0xcf, 0x80,
- 0x6a, 0xd4, 0x48, 0x18, 0x2c, 0x7b, 0x19, 0x2e, 0x30, 0x25, 0x16, 0x23,
- 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6c, 0x6f, 0x67, 0x6f, 0x2e,
- 0x76, 0x65, 0x72, 0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d,
- 0x2f, 0x76, 0x73, 0x6c, 0x6f, 0x67, 0x6f, 0x2e, 0x67, 0x69, 0x66, 0x30,
- 0x34, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04,
- 0x28, 0x30, 0x26, 0x30, 0x24, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05,
- 0x07, 0x30, 0x01, 0x86, 0x18, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f,
- 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x76, 0x65, 0x72, 0x69, 0x73, 0x69, 0x67,
- 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x3e, 0x06, 0x03, 0x55, 0x1d, 0x25,
- 0x04, 0x37, 0x30, 0x35, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
- 0x03, 0x01, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x02,
- 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x03, 0x06, 0x09,
- 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42, 0x04, 0x01, 0x06, 0x0a, 0x60,
- 0x86, 0x48, 0x01, 0x86, 0xf8, 0x45, 0x01, 0x08, 0x01, 0x30, 0x0d, 0x06,
- 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00,
- 0x03, 0x81, 0x81, 0x00, 0x13, 0x02, 0xdd, 0xf8, 0xe8, 0x86, 0x00, 0xf2,
- 0x5a, 0xf8, 0xf8, 0x20, 0x0c, 0x59, 0x88, 0x62, 0x07, 0xce, 0xce, 0xf7,
- 0x4e, 0xf9, 0xbb, 0x59, 0xa1, 0x98, 0xe5, 0xe1, 0x38, 0xdd, 0x4e, 0xbc,
- 0x66, 0x18, 0xd3, 0xad, 0xeb, 0x18, 0xf2, 0x0d, 0xc9, 0x6d, 0x3e, 0x4a,
- 0x94, 0x20, 0xc3, 0x3c, 0xba, 0xbd, 0x65, 0x54, 0xc6, 0xaf, 0x44, 0xb3,
- 0x10, 0xad, 0x2c, 0x6b, 0x3e, 0xab, 0xd7, 0x07, 0xb6, 0xb8, 0x81, 0x63,
- 0xc5, 0xf9, 0x5e, 0x2e, 0xe5, 0x2a, 0x67, 0xce, 0xcd, 0x33, 0x0c, 0x2a,
- 0xd7, 0x89, 0x56, 0x03, 0x23, 0x1f, 0xb3, 0xbe, 0xe8, 0x3a, 0x08, 0x59,
- 0xb4, 0xec, 0x45, 0x35, 0xf7, 0x8a, 0x5b, 0xff, 0x66, 0xcf, 0x50, 0xaf,
- 0xc6, 0x6d, 0x57, 0x8d, 0x19, 0x78, 0xb7, 0xb9, 0xa2, 0xd1, 0x57, 0xea,
- 0x1f, 0x9a, 0x4b, 0xaf, 0xba, 0xc9, 0x8e, 0x12, 0x7e, 0xc6, 0xbd, 0xff,
-};
-
-#if 0
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number:
- 2c:69:e1:2f:6a:67:0b:d9:9d:d2:0f:91:9e:f0:9e:51
- Signature Algorithm: sha256WithRSAEncryption
- Issuer: C=US, O=thawte, Inc., OU=Certification Services Division, OU=(c) 2006 thawte, Inc. - For authorized use only, CN=thawte Primary Root CA
- Validity
- Not Before: Jun 10 00:00:00 2014 GMT
- Not After : Jun 9 23:59:59 2024 GMT
- Subject: C=US, O=thawte, Inc., OU=Domain Validated SSL, CN=thawte DV SSL CA - G2
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:ea:94:07:85:c8:41:2c:f6:83:12:6c:92:5f:ab:
- 1f:00:d4:96:6f:74:cd:2e:11:e9:6c:0f:39:01:b9:
- 48:90:40:39:4d:c4:a2:c8:79:6a:a5:9a:bd:91:44:
- 65:77:54:ad:ff:25:5f:ee:42:fb:b3:02:0f:ea:5d:
- 7a:dd:1a:54:9e:d7:73:42:9b:cc:79:5f:c5:4d:f4:
- b7:0b:18:39:20:7a:dd:50:01:5d:34:45:5f:4c:11:
- 0e:f5:87:26:26:b4:b0:f3:7e:71:a0:31:71:50:89:
- 68:5a:63:8a:14:62:e5:8c:3a:16:55:0d:3e:eb:aa:
- 80:1d:71:7a:e3:87:07:ab:bd:a2:74:cd:da:08:01:
- 9d:1b:cc:27:88:8c:47:d4:69:25:42:d6:bb:50:6d:
- 85:50:d0:48:82:0d:08:9f:e9:23:e3:42:c6:3c:98:
- b8:bb:6e:c5:70:13:df:19:1d:01:fd:d2:b5:4e:e6:
- 62:f4:07:fa:6b:7d:11:77:c4:62:4f:40:4e:a5:78:
- 97:ab:2c:4d:0c:a7:7c:c3:c4:50:32:9f:d0:70:9b:
- 0f:ff:ff:75:59:34:85:ad:49:d5:35:ee:4f:5b:d4:
- d4:36:95:a0:7e:e8:c5:a1:1c:bd:13:4e:7d:ee:63:
- 6a:96:19:99:c8:a7:2a:00:e6:51:8d:46:eb:30:58:
- e8:2d
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Basic Constraints: critical
- CA:TRUE, pathlen:0
- X509v3 Certificate Policies:
- Policy: 2.16.840.1.113733.1.7.54
- CPS: https://www.thawte.com/cps
-
- X509v3 Key Usage: critical
- Certificate Sign, CRL Sign
- Authority Information Access:
- OCSP - URI:http://t.symcd.com
-
- X509v3 CRL Distribution Points:
-
- Full Name:
- URI:http://t.symcb.com/ThawtePCA.crl
-
- X509v3 Subject Alternative Name:
- DirName:/CN=SymantecPKI-1-698
- X509v3 Subject Key Identifier:
- 9F:B8:C1:A9:6C:F2:F5:C0:22:2A:94:ED:5C:99:AC:D4:EC:D7:C6:07
- X509v3 Authority Key Identifier:
- keyid:7B:5B:45:CF:AF:CE:CB:7A:FD:31:92:1A:6A:B6:F3:46:EB:57:48:50
-
- Signature Algorithm: sha256WithRSAEncryption
- 53:54:f2:47:a8:02:d7:ef:aa:35:78:be:4a:08:0d:90:18:4b:
- 6d:9e:2a:53:2b:e9:54:17:77:74:29:7e:d0:37:07:05:b8:e4:
- fa:b8:b4:63:98:44:dc:c6:4f:81:06:8c:3a:be:c7:30:57:c6:
- 70:fc:d6:93:19:9f:c3:55:d7:3e:1f:72:8a:9d:30:5a:35:97:
- 32:cb:63:e4:c6:72:df:fb:68:ca:69:2f:db:cd:50:38:3e:2b:
- bb:ab:3b:82:c7:fd:4b:9b:bd:7c:41:98:ef:01:53:d8:35:8f:
- 25:c9:03:06:e6:9c:57:c1:51:0f:9e:f6:7d:93:4d:f8:76:c8:
- 3a:6b:f4:c4:8f:33:32:7f:9d:21:84:34:d9:a7:f9:92:fa:41:
- 91:61:84:05:9d:a3:79:46:ce:67:e7:81:f2:5e:ac:4c:bc:a8:
- ab:6a:6d:15:e2:9c:4e:5a:d9:63:80:bc:f7:42:eb:9a:44:c6:
- 8c:6b:06:36:b4:8b:32:89:de:c2:f1:a8:26:aa:a9:ac:ff:ea:
- 71:a6:e7:8c:41:fa:17:35:bb:b3:87:31:a9:93:c2:c8:58:e1:
- 0a:4e:95:83:9c:b9:ed:3b:a5:ef:08:e0:74:f9:c3:1b:e6:07:
- a3:ee:07:d7:42:22:79:21:a0:a1:d4:1d:26:d3:d0:d6:a6:5d:
- 2b:41:c0:79
------BEGIN CERTIFICATE-----
-MIIE0jCCA7qgAwIBAgIQLGnhL2pnC9md0g+RnvCeUTANBgkqhkiG9w0BAQsFADCB
-qTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMf
-Q2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIw
-MDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxHzAdBgNV
-BAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwHhcNMTQwNjEwMDAwMDAwWhcNMjQw
-NjA5MjM1OTU5WjBjMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMdGhhd3RlLCBJbmMu
-MR0wGwYDVQQLExREb21haW4gVmFsaWRhdGVkIFNTTDEeMBwGA1UEAxMVdGhhd3Rl
-IERWIFNTTCBDQSAtIEcyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA
-6pQHhchBLPaDEmySX6sfANSWb3TNLhHpbA85AblIkEA5TcSiyHlqpZq9kURld1St
-/yVf7kL7swIP6l163RpUntdzQpvMeV/FTfS3Cxg5IHrdUAFdNEVfTBEO9YcmJrSw
-835xoDFxUIloWmOKFGLljDoWVQ0+66qAHXF644cHq72idM3aCAGdG8wniIxH1Gkl
-Qta7UG2FUNBIgg0In+kj40LGPJi4u27FcBPfGR0B/dK1TuZi9Af6a30Rd8RiT0BO
-pXiXqyxNDKd8w8RQMp/QcJsP//91WTSFrUnVNe5PW9TUNpWgfujFoRy9E0597mNq
-lhmZyKcqAOZRjUbrMFjoLQIDAQABo4IBOTCCATUwEgYDVR0TAQH/BAgwBgEB/wIB
-ADBBBgNVHSAEOjA4MDYGCmCGSAGG+EUBBzYwKDAmBggrBgEFBQcCARYaaHR0cHM6
-Ly93d3cudGhhd3RlLmNvbS9jcHMwDgYDVR0PAQH/BAQDAgEGMC4GCCsGAQUFBwEB
-BCIwIDAeBggrBgEFBQcwAYYSaHR0cDovL3Quc3ltY2QuY29tMDEGA1UdHwQqMCgw
-JqAkoCKGIGh0dHA6Ly90LnN5bWNiLmNvbS9UaGF3dGVQQ0EuY3JsMCkGA1UdEQQi
-MCCkHjAcMRowGAYDVQQDExFTeW1hbnRlY1BLSS0xLTY5ODAdBgNVHQ4EFgQUn7jB
-qWzy9cAiKpTtXJms1OzXxgcwHwYDVR0jBBgwFoAUe1tFz6/Oy3r9MZIaarbzRutX
-SFAwDQYJKoZIhvcNAQELBQADggEBAFNU8keoAtfvqjV4vkoIDZAYS22eKlMr6VQX
-d3QpftA3BwW45Pq4tGOYRNzGT4EGjDq+xzBXxnD81pMZn8NV1z4fcoqdMFo1lzLL
-Y+TGct/7aMppL9vNUDg+K7urO4LH/UubvXxBmO8BU9g1jyXJAwbmnFfBUQ+e9n2T
-Tfh2yDpr9MSPMzJ/nSGENNmn+ZL6QZFhhAWdo3lGzmfngfJerEy8qKtqbRXinE5a
-2WOAvPdC65pExoxrBja0izKJ3sLxqCaqqaz/6nGm54xB+hc1u7OHMamTwshY4QpO
-lYOcue07pe8I4HT5wxvmB6PuB9dCInkhoKHUHSbT0NamXStBwHk=
------END CERTIFICATE-----
-#endif
-static const unsigned char kDERCert38[] = {
- 0x30, 0x82, 0x04, 0xd2, 0x30, 0x82, 0x03, 0xba, 0xa0, 0x03, 0x02, 0x01,
- 0x02, 0x02, 0x10, 0x2c, 0x69, 0xe1, 0x2f, 0x6a, 0x67, 0x0b, 0xd9, 0x9d,
- 0xd2, 0x0f, 0x91, 0x9e, 0xf0, 0x9e, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x2a,
- 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x81,
- 0xa9, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
- 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13,
- 0x0c, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63,
- 0x2e, 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1f,
- 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f,
- 0x6e, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, 0x44,
- 0x69, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x31, 0x38, 0x30, 0x36, 0x06,
- 0x03, 0x55, 0x04, 0x0b, 0x13, 0x2f, 0x28, 0x63, 0x29, 0x20, 0x32, 0x30,
- 0x30, 0x36, 0x20, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2c, 0x20, 0x49,
- 0x6e, 0x63, 0x2e, 0x20, 0x2d, 0x20, 0x46, 0x6f, 0x72, 0x20, 0x61, 0x75,
- 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x20, 0x75, 0x73, 0x65,
- 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55,
- 0x04, 0x03, 0x13, 0x16, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x20, 0x50,
- 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20,
- 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x34, 0x30, 0x36, 0x31, 0x30,
- 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x34, 0x30,
- 0x36, 0x30, 0x39, 0x32, 0x33, 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x63,
- 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55,
- 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0c,
- 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e,
- 0x31, 0x1d, 0x30, 0x1b, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x14, 0x44,
- 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x20, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61,
- 0x74, 0x65, 0x64, 0x20, 0x53, 0x53, 0x4c, 0x31, 0x1e, 0x30, 0x1c, 0x06,
- 0x03, 0x55, 0x04, 0x03, 0x13, 0x15, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65,
- 0x20, 0x44, 0x56, 0x20, 0x53, 0x53, 0x4c, 0x20, 0x43, 0x41, 0x20, 0x2d,
- 0x20, 0x47, 0x32, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a,
- 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82,
- 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00,
- 0xea, 0x94, 0x07, 0x85, 0xc8, 0x41, 0x2c, 0xf6, 0x83, 0x12, 0x6c, 0x92,
- 0x5f, 0xab, 0x1f, 0x00, 0xd4, 0x96, 0x6f, 0x74, 0xcd, 0x2e, 0x11, 0xe9,
- 0x6c, 0x0f, 0x39, 0x01, 0xb9, 0x48, 0x90, 0x40, 0x39, 0x4d, 0xc4, 0xa2,
- 0xc8, 0x79, 0x6a, 0xa5, 0x9a, 0xbd, 0x91, 0x44, 0x65, 0x77, 0x54, 0xad,
- 0xff, 0x25, 0x5f, 0xee, 0x42, 0xfb, 0xb3, 0x02, 0x0f, 0xea, 0x5d, 0x7a,
- 0xdd, 0x1a, 0x54, 0x9e, 0xd7, 0x73, 0x42, 0x9b, 0xcc, 0x79, 0x5f, 0xc5,
- 0x4d, 0xf4, 0xb7, 0x0b, 0x18, 0x39, 0x20, 0x7a, 0xdd, 0x50, 0x01, 0x5d,
- 0x34, 0x45, 0x5f, 0x4c, 0x11, 0x0e, 0xf5, 0x87, 0x26, 0x26, 0xb4, 0xb0,
- 0xf3, 0x7e, 0x71, 0xa0, 0x31, 0x71, 0x50, 0x89, 0x68, 0x5a, 0x63, 0x8a,
- 0x14, 0x62, 0xe5, 0x8c, 0x3a, 0x16, 0x55, 0x0d, 0x3e, 0xeb, 0xaa, 0x80,
- 0x1d, 0x71, 0x7a, 0xe3, 0x87, 0x07, 0xab, 0xbd, 0xa2, 0x74, 0xcd, 0xda,
- 0x08, 0x01, 0x9d, 0x1b, 0xcc, 0x27, 0x88, 0x8c, 0x47, 0xd4, 0x69, 0x25,
- 0x42, 0xd6, 0xbb, 0x50, 0x6d, 0x85, 0x50, 0xd0, 0x48, 0x82, 0x0d, 0x08,
- 0x9f, 0xe9, 0x23, 0xe3, 0x42, 0xc6, 0x3c, 0x98, 0xb8, 0xbb, 0x6e, 0xc5,
- 0x70, 0x13, 0xdf, 0x19, 0x1d, 0x01, 0xfd, 0xd2, 0xb5, 0x4e, 0xe6, 0x62,
- 0xf4, 0x07, 0xfa, 0x6b, 0x7d, 0x11, 0x77, 0xc4, 0x62, 0x4f, 0x40, 0x4e,
- 0xa5, 0x78, 0x97, 0xab, 0x2c, 0x4d, 0x0c, 0xa7, 0x7c, 0xc3, 0xc4, 0x50,
- 0x32, 0x9f, 0xd0, 0x70, 0x9b, 0x0f, 0xff, 0xff, 0x75, 0x59, 0x34, 0x85,
- 0xad, 0x49, 0xd5, 0x35, 0xee, 0x4f, 0x5b, 0xd4, 0xd4, 0x36, 0x95, 0xa0,
- 0x7e, 0xe8, 0xc5, 0xa1, 0x1c, 0xbd, 0x13, 0x4e, 0x7d, 0xee, 0x63, 0x6a,
- 0x96, 0x19, 0x99, 0xc8, 0xa7, 0x2a, 0x00, 0xe6, 0x51, 0x8d, 0x46, 0xeb,
- 0x30, 0x58, 0xe8, 0x2d, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01,
- 0x39, 0x30, 0x82, 0x01, 0x35, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13,
- 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01,
- 0x00, 0x30, 0x41, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x3a, 0x30, 0x38,
- 0x30, 0x36, 0x06, 0x0a, 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x45, 0x01,
- 0x07, 0x36, 0x30, 0x28, 0x30, 0x26, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05,
- 0x05, 0x07, 0x02, 0x01, 0x16, 0x1a, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a,
- 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65,
- 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x70, 0x73, 0x30, 0x0e, 0x06, 0x03,
- 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06,
- 0x30, 0x2e, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01,
- 0x04, 0x22, 0x30, 0x20, 0x30, 0x1e, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05,
- 0x05, 0x07, 0x30, 0x01, 0x86, 0x12, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f,
- 0x2f, 0x74, 0x2e, 0x73, 0x79, 0x6d, 0x63, 0x64, 0x2e, 0x63, 0x6f, 0x6d,
- 0x30, 0x31, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x2a, 0x30, 0x28, 0x30,
- 0x26, 0xa0, 0x24, 0xa0, 0x22, 0x86, 0x20, 0x68, 0x74, 0x74, 0x70, 0x3a,
- 0x2f, 0x2f, 0x74, 0x2e, 0x73, 0x79, 0x6d, 0x63, 0x62, 0x2e, 0x63, 0x6f,
- 0x6d, 0x2f, 0x54, 0x68, 0x61, 0x77, 0x74, 0x65, 0x50, 0x43, 0x41, 0x2e,
- 0x63, 0x72, 0x6c, 0x30, 0x29, 0x06, 0x03, 0x55, 0x1d, 0x11, 0x04, 0x22,
- 0x30, 0x20, 0xa4, 0x1e, 0x30, 0x1c, 0x31, 0x1a, 0x30, 0x18, 0x06, 0x03,
- 0x55, 0x04, 0x03, 0x13, 0x11, 0x53, 0x79, 0x6d, 0x61, 0x6e, 0x74, 0x65,
- 0x63, 0x50, 0x4b, 0x49, 0x2d, 0x31, 0x2d, 0x36, 0x39, 0x38, 0x30, 0x1d,
- 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x9f, 0xb8, 0xc1,
- 0xa9, 0x6c, 0xf2, 0xf5, 0xc0, 0x22, 0x2a, 0x94, 0xed, 0x5c, 0x99, 0xac,
- 0xd4, 0xec, 0xd7, 0xc6, 0x07, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23,
- 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x7b, 0x5b, 0x45, 0xcf, 0xaf, 0xce,
- 0xcb, 0x7a, 0xfd, 0x31, 0x92, 0x1a, 0x6a, 0xb6, 0xf3, 0x46, 0xeb, 0x57,
- 0x48, 0x50, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
- 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x53, 0x54,
- 0xf2, 0x47, 0xa8, 0x02, 0xd7, 0xef, 0xaa, 0x35, 0x78, 0xbe, 0x4a, 0x08,
- 0x0d, 0x90, 0x18, 0x4b, 0x6d, 0x9e, 0x2a, 0x53, 0x2b, 0xe9, 0x54, 0x17,
- 0x77, 0x74, 0x29, 0x7e, 0xd0, 0x37, 0x07, 0x05, 0xb8, 0xe4, 0xfa, 0xb8,
- 0xb4, 0x63, 0x98, 0x44, 0xdc, 0xc6, 0x4f, 0x81, 0x06, 0x8c, 0x3a, 0xbe,
- 0xc7, 0x30, 0x57, 0xc6, 0x70, 0xfc, 0xd6, 0x93, 0x19, 0x9f, 0xc3, 0x55,
- 0xd7, 0x3e, 0x1f, 0x72, 0x8a, 0x9d, 0x30, 0x5a, 0x35, 0x97, 0x32, 0xcb,
- 0x63, 0xe4, 0xc6, 0x72, 0xdf, 0xfb, 0x68, 0xca, 0x69, 0x2f, 0xdb, 0xcd,
- 0x50, 0x38, 0x3e, 0x2b, 0xbb, 0xab, 0x3b, 0x82, 0xc7, 0xfd, 0x4b, 0x9b,
- 0xbd, 0x7c, 0x41, 0x98, 0xef, 0x01, 0x53, 0xd8, 0x35, 0x8f, 0x25, 0xc9,
- 0x03, 0x06, 0xe6, 0x9c, 0x57, 0xc1, 0x51, 0x0f, 0x9e, 0xf6, 0x7d, 0x93,
- 0x4d, 0xf8, 0x76, 0xc8, 0x3a, 0x6b, 0xf4, 0xc4, 0x8f, 0x33, 0x32, 0x7f,
- 0x9d, 0x21, 0x84, 0x34, 0xd9, 0xa7, 0xf9, 0x92, 0xfa, 0x41, 0x91, 0x61,
- 0x84, 0x05, 0x9d, 0xa3, 0x79, 0x46, 0xce, 0x67, 0xe7, 0x81, 0xf2, 0x5e,
- 0xac, 0x4c, 0xbc, 0xa8, 0xab, 0x6a, 0x6d, 0x15, 0xe2, 0x9c, 0x4e, 0x5a,
- 0xd9, 0x63, 0x80, 0xbc, 0xf7, 0x42, 0xeb, 0x9a, 0x44, 0xc6, 0x8c, 0x6b,
- 0x06, 0x36, 0xb4, 0x8b, 0x32, 0x89, 0xde, 0xc2, 0xf1, 0xa8, 0x26, 0xaa,
- 0xa9, 0xac, 0xff, 0xea, 0x71, 0xa6, 0xe7, 0x8c, 0x41, 0xfa, 0x17, 0x35,
- 0xbb, 0xb3, 0x87, 0x31, 0xa9, 0x93, 0xc2, 0xc8, 0x58, 0xe1, 0x0a, 0x4e,
- 0x95, 0x83, 0x9c, 0xb9, 0xed, 0x3b, 0xa5, 0xef, 0x08, 0xe0, 0x74, 0xf9,
- 0xc3, 0x1b, 0xe6, 0x07, 0xa3, 0xee, 0x07, 0xd7, 0x42, 0x22, 0x79, 0x21,
- 0xa0, 0xa1, 0xd4, 0x1d, 0x26, 0xd3, 0xd0, 0xd6, 0xa6, 0x5d, 0x2b, 0x41,
- 0xc0, 0x79,
-};
-
-#if 0
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number: 1372799044 (0x51d34044)
- Signature Algorithm: sha256WithRSAEncryption
- Issuer: C=US, O=Entrust, Inc., OU=www.entrust.net/CPS is incorporated by reference, OU=(c) 2006 Entrust, Inc., CN=Entrust Root Certification Authority
- Validity
- Not Before: Sep 22 17:14:57 2014 GMT
- Not After : Sep 23 01:31:53 2024 GMT
- Subject: C=US, O=Entrust, Inc., OU=See www.entrust.net/legal-terms, OU=(c) 2009 Entrust, Inc. - for authorized use only, CN=Entrust Root Certification Authority - G2
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:ba:84:b6:72:db:9e:0c:6b:e2:99:e9:30:01:a7:
- 76:ea:32:b8:95:41:1a:c9:da:61:4e:58:72:cf:fe:
- f6:82:79:bf:73:61:06:0a:a5:27:d8:b3:5f:d3:45:
- 4e:1c:72:d6:4e:32:f2:72:8a:0f:f7:83:19:d0:6a:
- 80:80:00:45:1e:b0:c7:e7:9a:bf:12:57:27:1c:a3:
- 68:2f:0a:87:bd:6a:6b:0e:5e:65:f3:1c:77:d5:d4:
- 85:8d:70:21:b4:b3:32:e7:8b:a2:d5:86:39:02:b1:
- b8:d2:47:ce:e4:c9:49:c4:3b:a7:de:fb:54:7d:57:
- be:f0:e8:6e:c2:79:b2:3a:0b:55:e2:50:98:16:32:
- 13:5c:2f:78:56:c1:c2:94:b3:f2:5a:e4:27:9a:9f:
- 24:d7:c6:ec:d0:9b:25:82:e3:cc:c2:c4:45:c5:8c:
- 97:7a:06:6b:2a:11:9f:a9:0a:6e:48:3b:6f:db:d4:
- 11:19:42:f7:8f:07:bf:f5:53:5f:9c:3e:f4:17:2c:
- e6:69:ac:4e:32:4c:62:77:ea:b7:e8:e5:bb:34:bc:
- 19:8b:ae:9c:51:e7:b7:7e:b5:53:b1:33:22:e5:6d:
- cf:70:3c:1a:fa:e2:9b:67:b6:83:f4:8d:a5:af:62:
- 4c:4d:e0:58:ac:64:34:12:03:f8:b6:8d:94:63:24:
- a4:71
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Key Usage: critical
- Certificate Sign, CRL Sign
- X509v3 Basic Constraints: critical
- CA:TRUE, pathlen:1
- Authority Information Access:
- OCSP - URI:http://ocsp.entrust.net
-
- X509v3 CRL Distribution Points:
-
- Full Name:
- URI:http://crl.entrust.net/rootca1.crl
-
- X509v3 Certificate Policies:
- Policy: X509v3 Any Policy
- CPS: http://www.entrust.net/CPS
-
- X509v3 Subject Key Identifier:
- 6A:72:26:7A:D0:1E:EF:7D:E7:3B:69:51:D4:6C:8D:9F:90:12:66:AB
- X509v3 Authority Key Identifier:
- keyid:68:90:E4:67:A4:A6:53:80:C7:86:66:A4:F1:F7:4B:43:FB:84:BD:6D
-
- Signature Algorithm: sha256WithRSAEncryption
- 69:33:83:fc:28:7a:6f:7d:ef:9d:55:eb:c5:3e:7a:9d:75:b3:
- cc:c3:38:36:d9:34:a2:28:68:18:ea:1e:69:d3:bd:e7:d0:77:
- da:b8:00:83:4e:4a:cf:6f:d1:f1:c1:22:3f:74:e4:f7:98:49:
- 9e:9b:b6:9e:e1:db:98:77:2d:56:34:b1:a8:3c:d9:fd:c0:cd:
- c7:bf:05:03:d4:02:c5:f1:e5:c6:da:08:a5:13:c7:62:23:11:
- d1:61:30:1d:60:84:45:ef:79:a8:c6:26:93:a4:b7:cd:34:b8:
- 69:c5:13:f6:91:b3:c9:45:73:76:b6:92:f6:76:0a:5b:e1:03:
- 47:b7:e9:29:4c:91:32:23:37:4a:9c:35:d8:78:fd:1d:1f:e4:
- 83:89:24:80:ad:b7:f9:cf:e4:5d:a5:d4:71:c4:85:5b:70:1f:
- db:3f:1c:01:eb:1a:45:26:31:14:cc:65:bf:67:de:ca:cc:33:
- 65:e5:41:91:d7:37:be:41:1a:96:9d:e6:8a:97:9d:a7:ce:ac:
- 4e:9a:3d:bd:01:a0:6a:d9:4f:22:00:8b:44:d5:69:62:7b:2e:
- eb:cc:ba:e7:92:7d:69:67:3d:fc:b8:7c:de:41:87:d0:69:ea:
- ba:0a:18:7a:1a:95:43:b3:79:71:28:76:6d:a1:fb:57:4a:ec:
- 4d:c8:0e:10
------BEGIN CERTIFICATE-----
-MIIE/zCCA+egAwIBAgIEUdNARDANBgkqhkiG9w0BAQsFADCBsDELMAkGA1UEBhMC
-VVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xOTA3BgNVBAsTMHd3dy5lbnRydXN0
-Lm5ldC9DUFMgaXMgaW5jb3Jwb3JhdGVkIGJ5IHJlZmVyZW5jZTEfMB0GA1UECxMW
-KGMpIDIwMDYgRW50cnVzdCwgSW5jLjEtMCsGA1UEAxMkRW50cnVzdCBSb290IENl
-cnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTE0MDkyMjE3MTQ1N1oXDTI0MDkyMzAx
-MzE1M1owgb4xCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMSgw
-JgYDVQQLEx9TZWUgd3d3LmVudHJ1c3QubmV0L2xlZ2FsLXRlcm1zMTkwNwYDVQQL
-EzAoYykgMjAwOSBFbnRydXN0LCBJbmMuIC0gZm9yIGF1dGhvcml6ZWQgdXNlIG9u
-bHkxMjAwBgNVBAMTKUVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0
-eSAtIEcyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuoS2ctueDGvi
-mekwAad26jK4lUEaydphTlhyz/72gnm/c2EGCqUn2LNf00VOHHLWTjLycooP94MZ
-0GqAgABFHrDH55q/ElcnHKNoLwqHvWprDl5l8xx31dSFjXAhtLMy54ui1YY5ArG4
-0kfO5MlJxDun3vtUfVe+8OhuwnmyOgtV4lCYFjITXC94VsHClLPyWuQnmp8k18bs
-0JslguPMwsRFxYyXegZrKhGfqQpuSDtv29QRGUL3jwe/9VNfnD70FyzmaaxOMkxi
-d+q36OW7NLwZi66cUee3frVTsTMi5W3PcDwa+uKbZ7aD9I2lr2JMTeBYrGQ0EgP4
-to2UYySkcQIDAQABo4IBDzCCAQswDgYDVR0PAQH/BAQDAgEGMBIGA1UdEwEB/wQI
-MAYBAf8CAQEwMwYIKwYBBQUHAQEEJzAlMCMGCCsGAQUFBzABhhdodHRwOi8vb2Nz
-cC5lbnRydXN0Lm5ldDAzBgNVHR8ELDAqMCigJqAkhiJodHRwOi8vY3JsLmVudHJ1
-c3QubmV0L3Jvb3RjYTEuY3JsMDsGA1UdIAQ0MDIwMAYEVR0gADAoMCYGCCsGAQUF
-BwIBFhpodHRwOi8vd3d3LmVudHJ1c3QubmV0L0NQUzAdBgNVHQ4EFgQUanImetAe
-733nO2lR1GyNn5ASZqswHwYDVR0jBBgwFoAUaJDkZ6SmU4DHhmak8fdLQ/uEvW0w
-DQYJKoZIhvcNAQELBQADggEBAGkzg/woem99751V68U+ep11s8zDODbZNKIoaBjq
-HmnTvefQd9q4AINOSs9v0fHBIj905PeYSZ6btp7h25h3LVY0sag82f3Azce/BQPU
-AsXx5cbaCKUTx2IjEdFhMB1ghEXveajGJpOkt800uGnFE/aRs8lFc3a2kvZ2Clvh
-A0e36SlMkTIjN0qcNdh4/R0f5IOJJICtt/nP5F2l1HHEhVtwH9s/HAHrGkUmMRTM
-Zb9n3srMM2XlQZHXN75BGpad5oqXnafOrE6aPb0BoGrZTyIAi0TVaWJ7LuvMuueS
-fWlnPfy4fN5Bh9Bp6roKGHoalUOzeXEodm2h+1dK7E3IDhA=
------END CERTIFICATE-----
-#endif
-static const unsigned char kDERCert39[] = {
- 0x30, 0x82, 0x04, 0xff, 0x30, 0x82, 0x03, 0xe7, 0xa0, 0x03, 0x02, 0x01,
- 0x02, 0x02, 0x04, 0x51, 0xd3, 0x40, 0x44, 0x30, 0x0d, 0x06, 0x09, 0x2a,
- 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x81,
- 0xb0, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
- 0x55, 0x53, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13,
- 0x0d, 0x45, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2c, 0x20, 0x49, 0x6e,
- 0x63, 0x2e, 0x31, 0x39, 0x30, 0x37, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13,
- 0x30, 0x77, 0x77, 0x77, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74,
- 0x2e, 0x6e, 0x65, 0x74, 0x2f, 0x43, 0x50, 0x53, 0x20, 0x69, 0x73, 0x20,
- 0x69, 0x6e, 0x63, 0x6f, 0x72, 0x70, 0x6f, 0x72, 0x61, 0x74, 0x65, 0x64,
- 0x20, 0x62, 0x79, 0x20, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63,
- 0x65, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x16,
- 0x28, 0x63, 0x29, 0x20, 0x32, 0x30, 0x30, 0x36, 0x20, 0x45, 0x6e, 0x74,
- 0x72, 0x75, 0x73, 0x74, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x2d,
- 0x30, 0x2b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x24, 0x45, 0x6e, 0x74,
- 0x72, 0x75, 0x73, 0x74, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x65,
- 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20,
- 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x30, 0x1e, 0x17,
- 0x0d, 0x31, 0x34, 0x30, 0x39, 0x32, 0x32, 0x31, 0x37, 0x31, 0x34, 0x35,
- 0x37, 0x5a, 0x17, 0x0d, 0x32, 0x34, 0x30, 0x39, 0x32, 0x33, 0x30, 0x31,
- 0x33, 0x31, 0x35, 0x33, 0x5a, 0x30, 0x81, 0xbe, 0x31, 0x0b, 0x30, 0x09,
- 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x16, 0x30,
- 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0d, 0x45, 0x6e, 0x74, 0x72,
- 0x75, 0x73, 0x74, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x28, 0x30,
- 0x26, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1f, 0x53, 0x65, 0x65, 0x20,
- 0x77, 0x77, 0x77, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e,
- 0x6e, 0x65, 0x74, 0x2f, 0x6c, 0x65, 0x67, 0x61, 0x6c, 0x2d, 0x74, 0x65,
- 0x72, 0x6d, 0x73, 0x31, 0x39, 0x30, 0x37, 0x06, 0x03, 0x55, 0x04, 0x0b,
- 0x13, 0x30, 0x28, 0x63, 0x29, 0x20, 0x32, 0x30, 0x30, 0x39, 0x20, 0x45,
- 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e,
- 0x20, 0x2d, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x61, 0x75, 0x74, 0x68, 0x6f,
- 0x72, 0x69, 0x7a, 0x65, 0x64, 0x20, 0x75, 0x73, 0x65, 0x20, 0x6f, 0x6e,
- 0x6c, 0x79, 0x31, 0x32, 0x30, 0x30, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
- 0x29, 0x45, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x20, 0x52, 0x6f, 0x6f,
- 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74,
- 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74,
- 0x79, 0x20, 0x2d, 0x20, 0x47, 0x32, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d,
- 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05,
- 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82,
- 0x01, 0x01, 0x00, 0xba, 0x84, 0xb6, 0x72, 0xdb, 0x9e, 0x0c, 0x6b, 0xe2,
- 0x99, 0xe9, 0x30, 0x01, 0xa7, 0x76, 0xea, 0x32, 0xb8, 0x95, 0x41, 0x1a,
- 0xc9, 0xda, 0x61, 0x4e, 0x58, 0x72, 0xcf, 0xfe, 0xf6, 0x82, 0x79, 0xbf,
- 0x73, 0x61, 0x06, 0x0a, 0xa5, 0x27, 0xd8, 0xb3, 0x5f, 0xd3, 0x45, 0x4e,
- 0x1c, 0x72, 0xd6, 0x4e, 0x32, 0xf2, 0x72, 0x8a, 0x0f, 0xf7, 0x83, 0x19,
- 0xd0, 0x6a, 0x80, 0x80, 0x00, 0x45, 0x1e, 0xb0, 0xc7, 0xe7, 0x9a, 0xbf,
- 0x12, 0x57, 0x27, 0x1c, 0xa3, 0x68, 0x2f, 0x0a, 0x87, 0xbd, 0x6a, 0x6b,
- 0x0e, 0x5e, 0x65, 0xf3, 0x1c, 0x77, 0xd5, 0xd4, 0x85, 0x8d, 0x70, 0x21,
- 0xb4, 0xb3, 0x32, 0xe7, 0x8b, 0xa2, 0xd5, 0x86, 0x39, 0x02, 0xb1, 0xb8,
- 0xd2, 0x47, 0xce, 0xe4, 0xc9, 0x49, 0xc4, 0x3b, 0xa7, 0xde, 0xfb, 0x54,
- 0x7d, 0x57, 0xbe, 0xf0, 0xe8, 0x6e, 0xc2, 0x79, 0xb2, 0x3a, 0x0b, 0x55,
- 0xe2, 0x50, 0x98, 0x16, 0x32, 0x13, 0x5c, 0x2f, 0x78, 0x56, 0xc1, 0xc2,
- 0x94, 0xb3, 0xf2, 0x5a, 0xe4, 0x27, 0x9a, 0x9f, 0x24, 0xd7, 0xc6, 0xec,
- 0xd0, 0x9b, 0x25, 0x82, 0xe3, 0xcc, 0xc2, 0xc4, 0x45, 0xc5, 0x8c, 0x97,
- 0x7a, 0x06, 0x6b, 0x2a, 0x11, 0x9f, 0xa9, 0x0a, 0x6e, 0x48, 0x3b, 0x6f,
- 0xdb, 0xd4, 0x11, 0x19, 0x42, 0xf7, 0x8f, 0x07, 0xbf, 0xf5, 0x53, 0x5f,
- 0x9c, 0x3e, 0xf4, 0x17, 0x2c, 0xe6, 0x69, 0xac, 0x4e, 0x32, 0x4c, 0x62,
- 0x77, 0xea, 0xb7, 0xe8, 0xe5, 0xbb, 0x34, 0xbc, 0x19, 0x8b, 0xae, 0x9c,
- 0x51, 0xe7, 0xb7, 0x7e, 0xb5, 0x53, 0xb1, 0x33, 0x22, 0xe5, 0x6d, 0xcf,
- 0x70, 0x3c, 0x1a, 0xfa, 0xe2, 0x9b, 0x67, 0xb6, 0x83, 0xf4, 0x8d, 0xa5,
- 0xaf, 0x62, 0x4c, 0x4d, 0xe0, 0x58, 0xac, 0x64, 0x34, 0x12, 0x03, 0xf8,
- 0xb6, 0x8d, 0x94, 0x63, 0x24, 0xa4, 0x71, 0x02, 0x03, 0x01, 0x00, 0x01,
- 0xa3, 0x82, 0x01, 0x0f, 0x30, 0x82, 0x01, 0x0b, 0x30, 0x0e, 0x06, 0x03,
- 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06,
- 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08,
- 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01, 0x30, 0x33, 0x06, 0x08,
- 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x27, 0x30, 0x25,
- 0x30, 0x23, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01,
- 0x86, 0x17, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73,
- 0x70, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x6e, 0x65,
- 0x74, 0x30, 0x33, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x2c, 0x30, 0x2a,
- 0x30, 0x28, 0xa0, 0x26, 0xa0, 0x24, 0x86, 0x22, 0x68, 0x74, 0x74, 0x70,
- 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x75,
- 0x73, 0x74, 0x2e, 0x6e, 0x65, 0x74, 0x2f, 0x72, 0x6f, 0x6f, 0x74, 0x63,
- 0x61, 0x31, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x3b, 0x06, 0x03, 0x55, 0x1d,
- 0x20, 0x04, 0x34, 0x30, 0x32, 0x30, 0x30, 0x06, 0x04, 0x55, 0x1d, 0x20,
- 0x00, 0x30, 0x28, 0x30, 0x26, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05,
- 0x07, 0x02, 0x01, 0x16, 0x1a, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f,
- 0x77, 0x77, 0x77, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e,
- 0x6e, 0x65, 0x74, 0x2f, 0x43, 0x50, 0x53, 0x30, 0x1d, 0x06, 0x03, 0x55,
- 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x6a, 0x72, 0x26, 0x7a, 0xd0, 0x1e,
- 0xef, 0x7d, 0xe7, 0x3b, 0x69, 0x51, 0xd4, 0x6c, 0x8d, 0x9f, 0x90, 0x12,
- 0x66, 0xab, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30,
- 0x16, 0x80, 0x14, 0x68, 0x90, 0xe4, 0x67, 0xa4, 0xa6, 0x53, 0x80, 0xc7,
- 0x86, 0x66, 0xa4, 0xf1, 0xf7, 0x4b, 0x43, 0xfb, 0x84, 0xbd, 0x6d, 0x30,
- 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b,
- 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x69, 0x33, 0x83, 0xfc, 0x28,
- 0x7a, 0x6f, 0x7d, 0xef, 0x9d, 0x55, 0xeb, 0xc5, 0x3e, 0x7a, 0x9d, 0x75,
- 0xb3, 0xcc, 0xc3, 0x38, 0x36, 0xd9, 0x34, 0xa2, 0x28, 0x68, 0x18, 0xea,
- 0x1e, 0x69, 0xd3, 0xbd, 0xe7, 0xd0, 0x77, 0xda, 0xb8, 0x00, 0x83, 0x4e,
- 0x4a, 0xcf, 0x6f, 0xd1, 0xf1, 0xc1, 0x22, 0x3f, 0x74, 0xe4, 0xf7, 0x98,
- 0x49, 0x9e, 0x9b, 0xb6, 0x9e, 0xe1, 0xdb, 0x98, 0x77, 0x2d, 0x56, 0x34,
- 0xb1, 0xa8, 0x3c, 0xd9, 0xfd, 0xc0, 0xcd, 0xc7, 0xbf, 0x05, 0x03, 0xd4,
- 0x02, 0xc5, 0xf1, 0xe5, 0xc6, 0xda, 0x08, 0xa5, 0x13, 0xc7, 0x62, 0x23,
- 0x11, 0xd1, 0x61, 0x30, 0x1d, 0x60, 0x84, 0x45, 0xef, 0x79, 0xa8, 0xc6,
- 0x26, 0x93, 0xa4, 0xb7, 0xcd, 0x34, 0xb8, 0x69, 0xc5, 0x13, 0xf6, 0x91,
- 0xb3, 0xc9, 0x45, 0x73, 0x76, 0xb6, 0x92, 0xf6, 0x76, 0x0a, 0x5b, 0xe1,
- 0x03, 0x47, 0xb7, 0xe9, 0x29, 0x4c, 0x91, 0x32, 0x23, 0x37, 0x4a, 0x9c,
- 0x35, 0xd8, 0x78, 0xfd, 0x1d, 0x1f, 0xe4, 0x83, 0x89, 0x24, 0x80, 0xad,
- 0xb7, 0xf9, 0xcf, 0xe4, 0x5d, 0xa5, 0xd4, 0x71, 0xc4, 0x85, 0x5b, 0x70,
- 0x1f, 0xdb, 0x3f, 0x1c, 0x01, 0xeb, 0x1a, 0x45, 0x26, 0x31, 0x14, 0xcc,
- 0x65, 0xbf, 0x67, 0xde, 0xca, 0xcc, 0x33, 0x65, 0xe5, 0x41, 0x91, 0xd7,
- 0x37, 0xbe, 0x41, 0x1a, 0x96, 0x9d, 0xe6, 0x8a, 0x97, 0x9d, 0xa7, 0xce,
- 0xac, 0x4e, 0x9a, 0x3d, 0xbd, 0x01, 0xa0, 0x6a, 0xd9, 0x4f, 0x22, 0x00,
- 0x8b, 0x44, 0xd5, 0x69, 0x62, 0x7b, 0x2e, 0xeb, 0xcc, 0xba, 0xe7, 0x92,
- 0x7d, 0x69, 0x67, 0x3d, 0xfc, 0xb8, 0x7c, 0xde, 0x41, 0x87, 0xd0, 0x69,
- 0xea, 0xba, 0x0a, 0x18, 0x7a, 0x1a, 0x95, 0x43, 0xb3, 0x79, 0x71, 0x28,
- 0x76, 0x6d, 0xa1, 0xfb, 0x57, 0x4a, 0xec, 0x4d, 0xc8, 0x0e, 0x10,
-};
-
-#if 0
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number: 7 (0x7)
- Signature Algorithm: sha256WithRSAEncryption
- Issuer: C=US, ST=Arizona, L=Scottsdale, O=Starfield Technologies, Inc., CN=Starfield Root Certificate Authority - G2
- Validity
- Not Before: May 3 07:00:00 2011 GMT
- Not After : May 3 07:00:00 2031 GMT
- Subject: C=US, ST=Arizona, L=Scottsdale, O=Starfield Technologies, Inc., OU=http://certs.starfieldtech.com/repository/, CN=Starfield Secure Certificate Authority - G2
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:e5:90:66:4b:ec:f9:46:71:a9:20:83:be:e9:6c:
- bf:4a:c9:48:69:81:75:4e:6d:24:f6:cb:17:13:f8:
- b0:71:59:84:7a:6b:2b:85:a4:34:b5:16:e5:cb:cc:
- e9:41:70:2c:a4:2e:d6:fa:32:7d:e1:a8:de:94:10:
- ac:31:c1:c0:d8:6a:ff:59:27:ab:76:d6:fc:0b:74:
- 6b:b8:a7:ae:3f:c4:54:f4:b4:31:44:dd:93:56:8c:
- a4:4c:5e:9b:89:cb:24:83:9b:e2:57:7d:b7:d8:12:
- 1f:c9:85:6d:f4:d1:80:f1:50:9b:87:ae:d4:0b:10:
- 05:fb:27:ba:28:6d:17:e9:0e:d6:4d:b9:39:55:06:
- ff:0a:24:05:7e:2f:c6:1d:72:6c:d4:8b:29:8c:57:
- 7d:da:d9:eb:66:1a:d3:4f:a7:df:7f:52:c4:30:c5:
- a5:c9:0e:02:c5:53:bf:77:38:68:06:24:c3:66:c8:
- 37:7e:30:1e:45:71:23:35:ff:90:d8:2a:9d:8d:e7:
- b0:92:4d:3c:7f:2a:0a:93:dc:cd:16:46:65:f7:60:
- 84:8b:76:4b:91:27:73:14:92:e0:ea:ee:8f:16:ea:
- 8d:0e:3e:76:17:bf:7d:89:80:80:44:43:e7:2d:e0:
- 43:09:75:da:36:e8:ad:db:89:3a:f5:5d:12:8e:23:
- 04:83
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Basic Constraints: critical
- CA:TRUE
- X509v3 Key Usage: critical
- Certificate Sign, CRL Sign
- X509v3 Subject Key Identifier:
- 25:45:81:68:50:26:38:3D:3B:2D:2C:BE:CD:6A:D9:B6:3D:B3:66:63
- X509v3 Authority Key Identifier:
- keyid:7C:0C:32:1F:A7:D9:30:7F:C4:7D:68:A3:62:A8:A1:CE:AB:07:5B:27
-
- Authority Information Access:
- OCSP - URI:http://ocsp.starfieldtech.com/
-
- X509v3 CRL Distribution Points:
-
- Full Name:
- URI:http://crl.starfieldtech.com/sfroot-g2.crl
-
- X509v3 Certificate Policies:
- Policy: X509v3 Any Policy
- CPS: https://certs.starfieldtech.com/repository/
-
- Signature Algorithm: sha256WithRSAEncryption
- 56:65:ca:fe:f3:3f:0a:a8:93:8b:18:c7:de:43:69:13:34:20:
- be:4e:5f:78:a8:6b:9c:db:6a:4d:41:db:c1:13:ec:dc:31:00:
- 22:5e:f7:00:9e:0c:e0:34:65:34:f9:b1:3a:4e:48:c8:12:81:
- 88:5c:5b:3e:08:53:7a:f7:1a:64:df:b8:50:61:cc:53:51:40:
- 29:4b:c2:f4:ae:3a:5f:e4:ca:ad:26:cc:4e:61:43:e5:fd:57:
- a6:37:70:ce:43:2b:b0:94:c3:92:e9:e1:5f:aa:10:49:b7:69:
- e4:e0:d0:1f:64:a4:2b:cd:1f:6f:a0:f8:84:24:18:ce:79:3d:
- a9:91:bf:54:18:13:89:99:54:11:0d:55:c5:26:0b:79:4f:5a:
- 1c:6e:f9:63:db:14:80:a4:07:ab:fa:b2:a5:b9:88:dd:91:fe:
- 65:3b:a4:a3:79:be:89:4d:e1:d0:b0:f4:c8:17:0c:0a:96:14:
- 7c:09:b7:6c:e1:c2:d8:55:d4:18:a0:aa:41:69:70:24:a3:b9:
- ef:e9:5a:dc:3e:eb:94:4a:f0:b7:de:5f:0e:76:fa:fb:fb:69:
- 03:45:40:50:ee:72:0c:a4:12:86:81:cd:13:d1:4e:c4:3c:ca:
- 4e:0d:d2:26:f1:00:b7:b4:a6:a2:e1:6e:7a:81:fd:30:ac:7a:
- 1f:c7:59:7b
------BEGIN CERTIFICATE-----
-MIIFADCCA+igAwIBAgIBBzANBgkqhkiG9w0BAQsFADCBjzELMAkGA1UEBhMCVVMx
-EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT
-HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAMTKVN0YXJmaWVs
-ZCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTExMDUwMzA3MDAw
-MFoXDTMxMDUwMzA3MDAwMFowgcYxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6
-b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFyZmllbGQgVGVj
-aG5vbG9naWVzLCBJbmMuMTMwMQYDVQQLEypodHRwOi8vY2VydHMuc3RhcmZpZWxk
-dGVjaC5jb20vcmVwb3NpdG9yeS8xNDAyBgNVBAMTK1N0YXJmaWVsZCBTZWN1cmUg
-Q2VydGlmaWNhdGUgQXV0aG9yaXR5IC0gRzIwggEiMA0GCSqGSIb3DQEBAQUAA4IB
-DwAwggEKAoIBAQDlkGZL7PlGcakgg77pbL9KyUhpgXVObST2yxcT+LBxWYR6ayuF
-pDS1FuXLzOlBcCykLtb6Mn3hqN6UEKwxwcDYav9ZJ6t21vwLdGu4p64/xFT0tDFE
-3ZNWjKRMXpuJyySDm+JXfbfYEh/JhW300YDxUJuHrtQLEAX7J7oobRfpDtZNuTlV
-Bv8KJAV+L8YdcmzUiymMV33a2etmGtNPp99/UsQwxaXJDgLFU793OGgGJMNmyDd+
-MB5FcSM1/5DYKp2N57CSTTx/KgqT3M0WRmX3YISLdkuRJ3MUkuDq7o8W6o0OPnYX
-v32JgIBEQ+ct4EMJddo26K3biTr1XRKOIwSDAgMBAAGjggEsMIIBKDAPBgNVHRMB
-Af8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUJUWBaFAmOD07LSy+
-zWrZtj2zZmMwHwYDVR0jBBgwFoAUfAwyH6fZMH/EfWijYqihzqsHWycwOgYIKwYB
-BQUHAQEELjAsMCoGCCsGAQUFBzABhh5odHRwOi8vb2NzcC5zdGFyZmllbGR0ZWNo
-LmNvbS8wOwYDVR0fBDQwMjAwoC6gLIYqaHR0cDovL2NybC5zdGFyZmllbGR0ZWNo
-LmNvbS9zZnJvb3QtZzIuY3JsMEwGA1UdIARFMEMwQQYEVR0gADA5MDcGCCsGAQUF
-BwIBFitodHRwczovL2NlcnRzLnN0YXJmaWVsZHRlY2guY29tL3JlcG9zaXRvcnkv
-MA0GCSqGSIb3DQEBCwUAA4IBAQBWZcr+8z8KqJOLGMfeQ2kTNCC+Tl94qGuc22pN
-QdvBE+zcMQAiXvcAngzgNGU0+bE6TkjIEoGIXFs+CFN69xpk37hQYcxTUUApS8L0
-rjpf5MqtJsxOYUPl/VemN3DOQyuwlMOS6eFfqhBJt2nk4NAfZKQrzR9voPiEJBjO
-eT2pkb9UGBOJmVQRDVXFJgt5T1ocbvlj2xSApAer+rKluYjdkf5lO6Sjeb6JTeHQ
-sPTIFwwKlhR8Cbds4cLYVdQYoKpBaXAko7nv6VrcPuuUSvC33l8Odvr7+2kDRUBQ
-7nIMpBKGgc0T0U7EPMpODdIm8QC3tKai4W56gf0wrHofx1l7
------END CERTIFICATE-----
-#endif
-static const unsigned char kDERCert40[] = {
- 0x30, 0x82, 0x05, 0x00, 0x30, 0x82, 0x03, 0xe8, 0xa0, 0x03, 0x02, 0x01,
- 0x02, 0x02, 0x01, 0x07, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
- 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x81, 0x8f, 0x31, 0x0b,
- 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31,
- 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x07, 0x41, 0x72,
- 0x69, 0x7a, 0x6f, 0x6e, 0x61, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55,
- 0x04, 0x07, 0x13, 0x0a, 0x53, 0x63, 0x6f, 0x74, 0x74, 0x73, 0x64, 0x61,
- 0x6c, 0x65, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13,
- 0x1c, 0x53, 0x74, 0x61, 0x72, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x20, 0x54,
- 0x65, 0x63, 0x68, 0x6e, 0x6f, 0x6c, 0x6f, 0x67, 0x69, 0x65, 0x73, 0x2c,
- 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x32, 0x30, 0x30, 0x06, 0x03, 0x55,
- 0x04, 0x03, 0x13, 0x29, 0x53, 0x74, 0x61, 0x72, 0x66, 0x69, 0x65, 0x6c,
- 0x64, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69,
- 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f,
- 0x72, 0x69, 0x74, 0x79, 0x20, 0x2d, 0x20, 0x47, 0x32, 0x30, 0x1e, 0x17,
- 0x0d, 0x31, 0x31, 0x30, 0x35, 0x30, 0x33, 0x30, 0x37, 0x30, 0x30, 0x30,
- 0x30, 0x5a, 0x17, 0x0d, 0x33, 0x31, 0x30, 0x35, 0x30, 0x33, 0x30, 0x37,
- 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x81, 0xc6, 0x31, 0x0b, 0x30, 0x09,
- 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x10, 0x30,
- 0x0e, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x07, 0x41, 0x72, 0x69, 0x7a,
- 0x6f, 0x6e, 0x61, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x07,
- 0x13, 0x0a, 0x53, 0x63, 0x6f, 0x74, 0x74, 0x73, 0x64, 0x61, 0x6c, 0x65,
- 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x1c, 0x53,
- 0x74, 0x61, 0x72, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x20, 0x54, 0x65, 0x63,
- 0x68, 0x6e, 0x6f, 0x6c, 0x6f, 0x67, 0x69, 0x65, 0x73, 0x2c, 0x20, 0x49,
- 0x6e, 0x63, 0x2e, 0x31, 0x33, 0x30, 0x31, 0x06, 0x03, 0x55, 0x04, 0x0b,
- 0x13, 0x2a, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x65, 0x72,
- 0x74, 0x73, 0x2e, 0x73, 0x74, 0x61, 0x72, 0x66, 0x69, 0x65, 0x6c, 0x64,
- 0x74, 0x65, 0x63, 0x68, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x70,
- 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x2f, 0x31, 0x34, 0x30, 0x32,
- 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x2b, 0x53, 0x74, 0x61, 0x72, 0x66,
- 0x69, 0x65, 0x6c, 0x64, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20,
- 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20,
- 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x20, 0x2d, 0x20,
- 0x47, 0x32, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
- 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01,
- 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xe5,
- 0x90, 0x66, 0x4b, 0xec, 0xf9, 0x46, 0x71, 0xa9, 0x20, 0x83, 0xbe, 0xe9,
- 0x6c, 0xbf, 0x4a, 0xc9, 0x48, 0x69, 0x81, 0x75, 0x4e, 0x6d, 0x24, 0xf6,
- 0xcb, 0x17, 0x13, 0xf8, 0xb0, 0x71, 0x59, 0x84, 0x7a, 0x6b, 0x2b, 0x85,
- 0xa4, 0x34, 0xb5, 0x16, 0xe5, 0xcb, 0xcc, 0xe9, 0x41, 0x70, 0x2c, 0xa4,
- 0x2e, 0xd6, 0xfa, 0x32, 0x7d, 0xe1, 0xa8, 0xde, 0x94, 0x10, 0xac, 0x31,
- 0xc1, 0xc0, 0xd8, 0x6a, 0xff, 0x59, 0x27, 0xab, 0x76, 0xd6, 0xfc, 0x0b,
- 0x74, 0x6b, 0xb8, 0xa7, 0xae, 0x3f, 0xc4, 0x54, 0xf4, 0xb4, 0x31, 0x44,
- 0xdd, 0x93, 0x56, 0x8c, 0xa4, 0x4c, 0x5e, 0x9b, 0x89, 0xcb, 0x24, 0x83,
- 0x9b, 0xe2, 0x57, 0x7d, 0xb7, 0xd8, 0x12, 0x1f, 0xc9, 0x85, 0x6d, 0xf4,
- 0xd1, 0x80, 0xf1, 0x50, 0x9b, 0x87, 0xae, 0xd4, 0x0b, 0x10, 0x05, 0xfb,
- 0x27, 0xba, 0x28, 0x6d, 0x17, 0xe9, 0x0e, 0xd6, 0x4d, 0xb9, 0x39, 0x55,
- 0x06, 0xff, 0x0a, 0x24, 0x05, 0x7e, 0x2f, 0xc6, 0x1d, 0x72, 0x6c, 0xd4,
- 0x8b, 0x29, 0x8c, 0x57, 0x7d, 0xda, 0xd9, 0xeb, 0x66, 0x1a, 0xd3, 0x4f,
- 0xa7, 0xdf, 0x7f, 0x52, 0xc4, 0x30, 0xc5, 0xa5, 0xc9, 0x0e, 0x02, 0xc5,
- 0x53, 0xbf, 0x77, 0x38, 0x68, 0x06, 0x24, 0xc3, 0x66, 0xc8, 0x37, 0x7e,
- 0x30, 0x1e, 0x45, 0x71, 0x23, 0x35, 0xff, 0x90, 0xd8, 0x2a, 0x9d, 0x8d,
- 0xe7, 0xb0, 0x92, 0x4d, 0x3c, 0x7f, 0x2a, 0x0a, 0x93, 0xdc, 0xcd, 0x16,
- 0x46, 0x65, 0xf7, 0x60, 0x84, 0x8b, 0x76, 0x4b, 0x91, 0x27, 0x73, 0x14,
- 0x92, 0xe0, 0xea, 0xee, 0x8f, 0x16, 0xea, 0x8d, 0x0e, 0x3e, 0x76, 0x17,
- 0xbf, 0x7d, 0x89, 0x80, 0x80, 0x44, 0x43, 0xe7, 0x2d, 0xe0, 0x43, 0x09,
- 0x75, 0xda, 0x36, 0xe8, 0xad, 0xdb, 0x89, 0x3a, 0xf5, 0x5d, 0x12, 0x8e,
- 0x23, 0x04, 0x83, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x2c,
- 0x30, 0x82, 0x01, 0x28, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01,
- 0x01, 0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0e, 0x06,
- 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01,
- 0x06, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14,
- 0x25, 0x45, 0x81, 0x68, 0x50, 0x26, 0x38, 0x3d, 0x3b, 0x2d, 0x2c, 0xbe,
- 0xcd, 0x6a, 0xd9, 0xb6, 0x3d, 0xb3, 0x66, 0x63, 0x30, 0x1f, 0x06, 0x03,
- 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x7c, 0x0c, 0x32,
- 0x1f, 0xa7, 0xd9, 0x30, 0x7f, 0xc4, 0x7d, 0x68, 0xa3, 0x62, 0xa8, 0xa1,
- 0xce, 0xab, 0x07, 0x5b, 0x27, 0x30, 0x3a, 0x06, 0x08, 0x2b, 0x06, 0x01,
- 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x2e, 0x30, 0x2c, 0x30, 0x2a, 0x06,
- 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x1e, 0x68,
- 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x73,
- 0x74, 0x61, 0x72, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x74, 0x65, 0x63, 0x68,
- 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x30, 0x3b, 0x06, 0x03, 0x55, 0x1d, 0x1f,
- 0x04, 0x34, 0x30, 0x32, 0x30, 0x30, 0xa0, 0x2e, 0xa0, 0x2c, 0x86, 0x2a,
- 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x73,
- 0x74, 0x61, 0x72, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x74, 0x65, 0x63, 0x68,
- 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x73, 0x66, 0x72, 0x6f, 0x6f, 0x74, 0x2d,
- 0x67, 0x32, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x4c, 0x06, 0x03, 0x55, 0x1d,
- 0x20, 0x04, 0x45, 0x30, 0x43, 0x30, 0x41, 0x06, 0x04, 0x55, 0x1d, 0x20,
- 0x00, 0x30, 0x39, 0x30, 0x37, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05,
- 0x07, 0x02, 0x01, 0x16, 0x2b, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f,
- 0x2f, 0x63, 0x65, 0x72, 0x74, 0x73, 0x2e, 0x73, 0x74, 0x61, 0x72, 0x66,
- 0x69, 0x65, 0x6c, 0x64, 0x74, 0x65, 0x63, 0x68, 0x2e, 0x63, 0x6f, 0x6d,
- 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x2f,
- 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
- 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x56, 0x65, 0xca, 0xfe,
- 0xf3, 0x3f, 0x0a, 0xa8, 0x93, 0x8b, 0x18, 0xc7, 0xde, 0x43, 0x69, 0x13,
- 0x34, 0x20, 0xbe, 0x4e, 0x5f, 0x78, 0xa8, 0x6b, 0x9c, 0xdb, 0x6a, 0x4d,
- 0x41, 0xdb, 0xc1, 0x13, 0xec, 0xdc, 0x31, 0x00, 0x22, 0x5e, 0xf7, 0x00,
- 0x9e, 0x0c, 0xe0, 0x34, 0x65, 0x34, 0xf9, 0xb1, 0x3a, 0x4e, 0x48, 0xc8,
- 0x12, 0x81, 0x88, 0x5c, 0x5b, 0x3e, 0x08, 0x53, 0x7a, 0xf7, 0x1a, 0x64,
- 0xdf, 0xb8, 0x50, 0x61, 0xcc, 0x53, 0x51, 0x40, 0x29, 0x4b, 0xc2, 0xf4,
- 0xae, 0x3a, 0x5f, 0xe4, 0xca, 0xad, 0x26, 0xcc, 0x4e, 0x61, 0x43, 0xe5,
- 0xfd, 0x57, 0xa6, 0x37, 0x70, 0xce, 0x43, 0x2b, 0xb0, 0x94, 0xc3, 0x92,
- 0xe9, 0xe1, 0x5f, 0xaa, 0x10, 0x49, 0xb7, 0x69, 0xe4, 0xe0, 0xd0, 0x1f,
- 0x64, 0xa4, 0x2b, 0xcd, 0x1f, 0x6f, 0xa0, 0xf8, 0x84, 0x24, 0x18, 0xce,
- 0x79, 0x3d, 0xa9, 0x91, 0xbf, 0x54, 0x18, 0x13, 0x89, 0x99, 0x54, 0x11,
- 0x0d, 0x55, 0xc5, 0x26, 0x0b, 0x79, 0x4f, 0x5a, 0x1c, 0x6e, 0xf9, 0x63,
- 0xdb, 0x14, 0x80, 0xa4, 0x07, 0xab, 0xfa, 0xb2, 0xa5, 0xb9, 0x88, 0xdd,
- 0x91, 0xfe, 0x65, 0x3b, 0xa4, 0xa3, 0x79, 0xbe, 0x89, 0x4d, 0xe1, 0xd0,
- 0xb0, 0xf4, 0xc8, 0x17, 0x0c, 0x0a, 0x96, 0x14, 0x7c, 0x09, 0xb7, 0x6c,
- 0xe1, 0xc2, 0xd8, 0x55, 0xd4, 0x18, 0xa0, 0xaa, 0x41, 0x69, 0x70, 0x24,
- 0xa3, 0xb9, 0xef, 0xe9, 0x5a, 0xdc, 0x3e, 0xeb, 0x94, 0x4a, 0xf0, 0xb7,
- 0xde, 0x5f, 0x0e, 0x76, 0xfa, 0xfb, 0xfb, 0x69, 0x03, 0x45, 0x40, 0x50,
- 0xee, 0x72, 0x0c, 0xa4, 0x12, 0x86, 0x81, 0xcd, 0x13, 0xd1, 0x4e, 0xc4,
- 0x3c, 0xca, 0x4e, 0x0d, 0xd2, 0x26, 0xf1, 0x00, 0xb7, 0xb4, 0xa6, 0xa2,
- 0xe1, 0x6e, 0x7a, 0x81, 0xfd, 0x30, 0xac, 0x7a, 0x1f, 0xc7, 0x59, 0x7b,
-};
-
-#if 0
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number: 1372807406 (0x51d360ee)
- Signature Algorithm: sha256WithRSAEncryption
- Issuer: C=US, O=Entrust, Inc., OU=See www.entrust.net/legal-terms, OU=(c) 2009 Entrust, Inc. - for authorized use only, CN=Entrust Root Certification Authority - G2
- Validity
- Not Before: Oct 22 17:05:14 2014 GMT
- Not After : Oct 23 07:33:22 2024 GMT
- Subject: C=US, O=Entrust, Inc., OU=See www.entrust.net/legal-terms, OU=(c) 2012 Entrust, Inc. - for authorized use only, CN=Entrust Certification Authority - L1K
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:da:3f:96:d0:4d:b9:2f:44:e7:db:39:5e:9b:50:
- ee:5c:a5:61:da:41:67:53:09:aa:00:9a:8e:57:7f:
- 29:6b:db:c7:e1:21:24:aa:3a:d0:8d:47:23:d2:ed:
- 72:16:f0:91:21:d2:5d:b7:b8:4b:a8:83:8f:b7:91:
- 32:68:cf:ce:25:93:2c:b2:7d:97:c8:fe:c1:b4:17:
- ba:09:9e:03:90:93:7b:7c:49:83:22:68:8a:9b:de:
- 47:c3:31:98:7a:2e:7d:40:0b:d2:ef:3e:d3:b2:8c:
- aa:8f:48:a9:ff:00:e8:29:58:06:f7:b6:93:5a:94:
- 73:26:26:ad:58:0e:e5:42:b8:d5:ea:73:79:64:68:
- 53:25:b8:84:cf:94:7a:ae:06:45:0c:a3:6b:4d:d0:
- c6:be:ea:18:a4:36:f0:92:b2:ba:1c:88:8f:3a:52:
- 7f:f7:5e:6d:83:1c:9d:f0:1f:e5:c3:d6:dd:a5:78:
- 92:3d:b0:6d:2c:ea:c9:cf:94:41:19:71:44:68:ba:
- 47:3c:04:e9:5d:ba:3e:f0:35:f7:15:b6:9e:f2:2e:
- 15:1e:3f:47:c8:c8:38:a7:73:45:5d:4d:b0:3b:b1:
- 8e:17:29:37:ea:dd:05:01:22:bb:94:36:2a:8d:5b:
- 35:fe:53:19:2f:08:46:c1:2a:b3:1a:62:1d:4e:2b:
- d9:1b
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Key Usage: critical
- Certificate Sign, CRL Sign
- X509v3 Basic Constraints:
- CA:TRUE, pathlen:0
- Authority Information Access:
- OCSP - URI:http://ocsp.entrust.net
-
- X509v3 CRL Distribution Points:
-
- Full Name:
- URI:http://crl.entrust.net/g2ca.crl
-
- X509v3 Certificate Policies:
- Policy: X509v3 Any Policy
- CPS: http://www.entrust.net/rpa
-
- X509v3 Subject Key Identifier:
- 82:A2:70:74:DD:BC:53:3F:CF:7B:D4:F7:CD:7F:A7:60:C6:0A:4C:BF
- X509v3 Authority Key Identifier:
- keyid:6A:72:26:7A:D0:1E:EF:7D:E7:3B:69:51:D4:6C:8D:9F:90:12:66:AB
-
- Signature Algorithm: sha256WithRSAEncryption
- 3f:1c:1a:5b:ff:40:22:1d:8f:35:0c:2d:aa:99:27:ab:c0:11:
- 32:70:d7:36:28:69:a5:8d:b1:27:99:42:be:c4:93:eb:48:57:
- 43:71:23:c4:e5:4e:ad:ae:43:6f:92:76:c5:19:ef:ca:bc:6f:
- 42:4c:16:9a:86:a9:04:38:c7:65:f0:f5:0c:e0:4a:df:a2:fa:
- ce:1a:11:a8:9c:69:2f:1b:df:ea:e2:32:f3:ce:4c:bc:46:0c:
- c0:89:80:d1:87:6b:a2:cf:6b:d4:7f:fd:f5:60:52:67:57:a0:
- 6d:d1:64:41:14:6d:34:62:ed:06:6c:24:f2:06:bc:28:02:af:
- 03:2d:c2:33:05:fb:cb:aa:16:e8:65:10:43:f5:69:5c:e3:81:
- 58:99:cd:6b:d3:b8:c7:7b:19:55:c9:40:ce:79:55:b8:73:89:
- e9:5c:40:66:43:12:7f:07:b8:65:56:d5:8d:c3:a7:f5:b1:b6:
- 65:9e:c0:83:36:7f:16:45:3c:74:4b:93:8a:3c:f1:2b:f5:35:
- 70:73:7b:e7:82:04:b1:18:98:0e:d4:9c:6f:1a:fc:fc:a7:33:
- a5:bb:bb:18:f3:6b:7a:5d:32:87:f7:6d:25:e4:e2:76:86:21:
- 1e:11:46:cd:76:0e:6f:4f:a4:21:71:0a:84:a7:2d:36:a9:48:
- 22:51:7e:82
------BEGIN CERTIFICATE-----
-MIIFAzCCA+ugAwIBAgIEUdNg7jANBgkqhkiG9w0BAQsFADCBvjELMAkGA1UEBhMC
-VVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50
-cnVzdC5uZXQvbGVnYWwtdGVybXMxOTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3Qs
-IEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ugb25seTEyMDAGA1UEAxMpRW50cnVz
-dCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzIwHhcNMTQxMDIyMTcw
-NTE0WhcNMjQxMDIzMDczMzIyWjCBujELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUVu
-dHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50cnVzdC5uZXQvbGVnYWwt
-dGVybXMxOTA3BgNVBAsTMChjKSAyMDEyIEVudHJ1c3QsIEluYy4gLSBmb3IgYXV0
-aG9yaXplZCB1c2Ugb25seTEuMCwGA1UEAxMlRW50cnVzdCBDZXJ0aWZpY2F0aW9u
-IEF1dGhvcml0eSAtIEwxSzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
-ANo/ltBNuS9E59s5XptQ7lylYdpBZ1MJqgCajld/KWvbx+EhJKo60I1HI9Ltchbw
-kSHSXbe4S6iDj7eRMmjPziWTLLJ9l8j+wbQXugmeA5CTe3xJgyJoipveR8MxmHou
-fUAL0u8+07KMqo9Iqf8A6ClYBve2k1qUcyYmrVgO5UK41epzeWRoUyW4hM+Ueq4G
-RQyja03Qxr7qGKQ28JKyuhyIjzpSf/debYMcnfAf5cPW3aV4kj2wbSzqyc+UQRlx
-RGi6RzwE6V26PvA19xW2nvIuFR4/R8jIOKdzRV1NsDuxjhcpN+rdBQEiu5Q2Ko1b
-Nf5TGS8IRsEqsxpiHU4r2RsCAwEAAaOCAQkwggEFMA4GA1UdDwEB/wQEAwIBBjAP
-BgNVHRMECDAGAQH/AgEAMDMGCCsGAQUFBwEBBCcwJTAjBggrBgEFBQcwAYYXaHR0
-cDovL29jc3AuZW50cnVzdC5uZXQwMAYDVR0fBCkwJzAloCOgIYYfaHR0cDovL2Ny
-bC5lbnRydXN0Lm5ldC9nMmNhLmNybDA7BgNVHSAENDAyMDAGBFUdIAAwKDAmBggr
-BgEFBQcCARYaaHR0cDovL3d3dy5lbnRydXN0Lm5ldC9ycGEwHQYDVR0OBBYEFIKi
-cHTdvFM/z3vU981/p2DGCky/MB8GA1UdIwQYMBaAFGpyJnrQHu995ztpUdRsjZ+Q
-EmarMA0GCSqGSIb3DQEBCwUAA4IBAQA/HBpb/0AiHY81DC2qmSerwBEycNc2KGml
-jbEnmUK+xJPrSFdDcSPE5U6trkNvknbFGe/KvG9CTBaahqkEOMdl8PUM4ErfovrO
-GhGonGkvG9/q4jLzzky8RgzAiYDRh2uiz2vUf/31YFJnV6Bt0WRBFG00Yu0GbCTy
-BrwoAq8DLcIzBfvLqhboZRBD9Wlc44FYmc1r07jHexlVyUDOeVW4c4npXEBmQxJ/
-B7hlVtWNw6f1sbZlnsCDNn8WRTx0S5OKPPEr9TVwc3vnggSxGJgO1JxvGvz8pzOl
-u7sY82t6XTKH920l5OJ2hiEeEUbNdg5vT6QhcQqEpy02qUgiUX6C
------END CERTIFICATE-----
-#endif
-static const unsigned char kDERCert41[] = {
- 0x30, 0x82, 0x05, 0x03, 0x30, 0x82, 0x03, 0xeb, 0xa0, 0x03, 0x02, 0x01,
- 0x02, 0x02, 0x04, 0x51, 0xd3, 0x60, 0xee, 0x30, 0x0d, 0x06, 0x09, 0x2a,
- 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x81,
- 0xbe, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
- 0x55, 0x53, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13,
- 0x0d, 0x45, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2c, 0x20, 0x49, 0x6e,
- 0x63, 0x2e, 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13,
- 0x1f, 0x53, 0x65, 0x65, 0x20, 0x77, 0x77, 0x77, 0x2e, 0x65, 0x6e, 0x74,
- 0x72, 0x75, 0x73, 0x74, 0x2e, 0x6e, 0x65, 0x74, 0x2f, 0x6c, 0x65, 0x67,
- 0x61, 0x6c, 0x2d, 0x74, 0x65, 0x72, 0x6d, 0x73, 0x31, 0x39, 0x30, 0x37,
- 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x30, 0x28, 0x63, 0x29, 0x20, 0x32,
- 0x30, 0x30, 0x39, 0x20, 0x45, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2c,
- 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x20, 0x2d, 0x20, 0x66, 0x6f, 0x72, 0x20,
- 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x20, 0x75,
- 0x73, 0x65, 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x31, 0x32, 0x30, 0x30, 0x06,
- 0x03, 0x55, 0x04, 0x03, 0x13, 0x29, 0x45, 0x6e, 0x74, 0x72, 0x75, 0x73,
- 0x74, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69,
- 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74,
- 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x20, 0x2d, 0x20, 0x47, 0x32, 0x30,
- 0x1e, 0x17, 0x0d, 0x31, 0x34, 0x31, 0x30, 0x32, 0x32, 0x31, 0x37, 0x30,
- 0x35, 0x31, 0x34, 0x5a, 0x17, 0x0d, 0x32, 0x34, 0x31, 0x30, 0x32, 0x33,
- 0x30, 0x37, 0x33, 0x33, 0x32, 0x32, 0x5a, 0x30, 0x81, 0xba, 0x31, 0x0b,
- 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31,
- 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0d, 0x45, 0x6e,
- 0x74, 0x72, 0x75, 0x73, 0x74, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31,
- 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1f, 0x53, 0x65,
- 0x65, 0x20, 0x77, 0x77, 0x77, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x75, 0x73,
- 0x74, 0x2e, 0x6e, 0x65, 0x74, 0x2f, 0x6c, 0x65, 0x67, 0x61, 0x6c, 0x2d,
- 0x74, 0x65, 0x72, 0x6d, 0x73, 0x31, 0x39, 0x30, 0x37, 0x06, 0x03, 0x55,
- 0x04, 0x0b, 0x13, 0x30, 0x28, 0x63, 0x29, 0x20, 0x32, 0x30, 0x31, 0x32,
- 0x20, 0x45, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2c, 0x20, 0x49, 0x6e,
- 0x63, 0x2e, 0x20, 0x2d, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x61, 0x75, 0x74,
- 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x20, 0x75, 0x73, 0x65, 0x20,
- 0x6f, 0x6e, 0x6c, 0x79, 0x31, 0x2e, 0x30, 0x2c, 0x06, 0x03, 0x55, 0x04,
- 0x03, 0x13, 0x25, 0x45, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x20, 0x43,
- 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e,
- 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x20, 0x2d,
- 0x20, 0x4c, 0x31, 0x4b, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09,
- 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03,
- 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01,
- 0x00, 0xda, 0x3f, 0x96, 0xd0, 0x4d, 0xb9, 0x2f, 0x44, 0xe7, 0xdb, 0x39,
- 0x5e, 0x9b, 0x50, 0xee, 0x5c, 0xa5, 0x61, 0xda, 0x41, 0x67, 0x53, 0x09,
- 0xaa, 0x00, 0x9a, 0x8e, 0x57, 0x7f, 0x29, 0x6b, 0xdb, 0xc7, 0xe1, 0x21,
- 0x24, 0xaa, 0x3a, 0xd0, 0x8d, 0x47, 0x23, 0xd2, 0xed, 0x72, 0x16, 0xf0,
- 0x91, 0x21, 0xd2, 0x5d, 0xb7, 0xb8, 0x4b, 0xa8, 0x83, 0x8f, 0xb7, 0x91,
- 0x32, 0x68, 0xcf, 0xce, 0x25, 0x93, 0x2c, 0xb2, 0x7d, 0x97, 0xc8, 0xfe,
- 0xc1, 0xb4, 0x17, 0xba, 0x09, 0x9e, 0x03, 0x90, 0x93, 0x7b, 0x7c, 0x49,
- 0x83, 0x22, 0x68, 0x8a, 0x9b, 0xde, 0x47, 0xc3, 0x31, 0x98, 0x7a, 0x2e,
- 0x7d, 0x40, 0x0b, 0xd2, 0xef, 0x3e, 0xd3, 0xb2, 0x8c, 0xaa, 0x8f, 0x48,
- 0xa9, 0xff, 0x00, 0xe8, 0x29, 0x58, 0x06, 0xf7, 0xb6, 0x93, 0x5a, 0x94,
- 0x73, 0x26, 0x26, 0xad, 0x58, 0x0e, 0xe5, 0x42, 0xb8, 0xd5, 0xea, 0x73,
- 0x79, 0x64, 0x68, 0x53, 0x25, 0xb8, 0x84, 0xcf, 0x94, 0x7a, 0xae, 0x06,
- 0x45, 0x0c, 0xa3, 0x6b, 0x4d, 0xd0, 0xc6, 0xbe, 0xea, 0x18, 0xa4, 0x36,
- 0xf0, 0x92, 0xb2, 0xba, 0x1c, 0x88, 0x8f, 0x3a, 0x52, 0x7f, 0xf7, 0x5e,
- 0x6d, 0x83, 0x1c, 0x9d, 0xf0, 0x1f, 0xe5, 0xc3, 0xd6, 0xdd, 0xa5, 0x78,
- 0x92, 0x3d, 0xb0, 0x6d, 0x2c, 0xea, 0xc9, 0xcf, 0x94, 0x41, 0x19, 0x71,
- 0x44, 0x68, 0xba, 0x47, 0x3c, 0x04, 0xe9, 0x5d, 0xba, 0x3e, 0xf0, 0x35,
- 0xf7, 0x15, 0xb6, 0x9e, 0xf2, 0x2e, 0x15, 0x1e, 0x3f, 0x47, 0xc8, 0xc8,
- 0x38, 0xa7, 0x73, 0x45, 0x5d, 0x4d, 0xb0, 0x3b, 0xb1, 0x8e, 0x17, 0x29,
- 0x37, 0xea, 0xdd, 0x05, 0x01, 0x22, 0xbb, 0x94, 0x36, 0x2a, 0x8d, 0x5b,
- 0x35, 0xfe, 0x53, 0x19, 0x2f, 0x08, 0x46, 0xc1, 0x2a, 0xb3, 0x1a, 0x62,
- 0x1d, 0x4e, 0x2b, 0xd9, 0x1b, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82,
- 0x01, 0x09, 0x30, 0x82, 0x01, 0x05, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d,
- 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x0f,
- 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff,
- 0x02, 0x01, 0x00, 0x30, 0x33, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05,
- 0x07, 0x01, 0x01, 0x04, 0x27, 0x30, 0x25, 0x30, 0x23, 0x06, 0x08, 0x2b,
- 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x17, 0x68, 0x74, 0x74,
- 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x65, 0x6e, 0x74,
- 0x72, 0x75, 0x73, 0x74, 0x2e, 0x6e, 0x65, 0x74, 0x30, 0x30, 0x06, 0x03,
- 0x55, 0x1d, 0x1f, 0x04, 0x29, 0x30, 0x27, 0x30, 0x25, 0xa0, 0x23, 0xa0,
- 0x21, 0x86, 0x1f, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72,
- 0x6c, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x6e, 0x65,
- 0x74, 0x2f, 0x67, 0x32, 0x63, 0x61, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x3b,
- 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x34, 0x30, 0x32, 0x30, 0x30, 0x06,
- 0x04, 0x55, 0x1d, 0x20, 0x00, 0x30, 0x28, 0x30, 0x26, 0x06, 0x08, 0x2b,
- 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x1a, 0x68, 0x74, 0x74,
- 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x65, 0x6e, 0x74, 0x72,
- 0x75, 0x73, 0x74, 0x2e, 0x6e, 0x65, 0x74, 0x2f, 0x72, 0x70, 0x61, 0x30,
- 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x82, 0xa2,
- 0x70, 0x74, 0xdd, 0xbc, 0x53, 0x3f, 0xcf, 0x7b, 0xd4, 0xf7, 0xcd, 0x7f,
- 0xa7, 0x60, 0xc6, 0x0a, 0x4c, 0xbf, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d,
- 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x6a, 0x72, 0x26, 0x7a, 0xd0,
- 0x1e, 0xef, 0x7d, 0xe7, 0x3b, 0x69, 0x51, 0xd4, 0x6c, 0x8d, 0x9f, 0x90,
- 0x12, 0x66, 0xab, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
- 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x3f,
- 0x1c, 0x1a, 0x5b, 0xff, 0x40, 0x22, 0x1d, 0x8f, 0x35, 0x0c, 0x2d, 0xaa,
- 0x99, 0x27, 0xab, 0xc0, 0x11, 0x32, 0x70, 0xd7, 0x36, 0x28, 0x69, 0xa5,
- 0x8d, 0xb1, 0x27, 0x99, 0x42, 0xbe, 0xc4, 0x93, 0xeb, 0x48, 0x57, 0x43,
- 0x71, 0x23, 0xc4, 0xe5, 0x4e, 0xad, 0xae, 0x43, 0x6f, 0x92, 0x76, 0xc5,
- 0x19, 0xef, 0xca, 0xbc, 0x6f, 0x42, 0x4c, 0x16, 0x9a, 0x86, 0xa9, 0x04,
- 0x38, 0xc7, 0x65, 0xf0, 0xf5, 0x0c, 0xe0, 0x4a, 0xdf, 0xa2, 0xfa, 0xce,
- 0x1a, 0x11, 0xa8, 0x9c, 0x69, 0x2f, 0x1b, 0xdf, 0xea, 0xe2, 0x32, 0xf3,
- 0xce, 0x4c, 0xbc, 0x46, 0x0c, 0xc0, 0x89, 0x80, 0xd1, 0x87, 0x6b, 0xa2,
- 0xcf, 0x6b, 0xd4, 0x7f, 0xfd, 0xf5, 0x60, 0x52, 0x67, 0x57, 0xa0, 0x6d,
- 0xd1, 0x64, 0x41, 0x14, 0x6d, 0x34, 0x62, 0xed, 0x06, 0x6c, 0x24, 0xf2,
- 0x06, 0xbc, 0x28, 0x02, 0xaf, 0x03, 0x2d, 0xc2, 0x33, 0x05, 0xfb, 0xcb,
- 0xaa, 0x16, 0xe8, 0x65, 0x10, 0x43, 0xf5, 0x69, 0x5c, 0xe3, 0x81, 0x58,
- 0x99, 0xcd, 0x6b, 0xd3, 0xb8, 0xc7, 0x7b, 0x19, 0x55, 0xc9, 0x40, 0xce,
- 0x79, 0x55, 0xb8, 0x73, 0x89, 0xe9, 0x5c, 0x40, 0x66, 0x43, 0x12, 0x7f,
- 0x07, 0xb8, 0x65, 0x56, 0xd5, 0x8d, 0xc3, 0xa7, 0xf5, 0xb1, 0xb6, 0x65,
- 0x9e, 0xc0, 0x83, 0x36, 0x7f, 0x16, 0x45, 0x3c, 0x74, 0x4b, 0x93, 0x8a,
- 0x3c, 0xf1, 0x2b, 0xf5, 0x35, 0x70, 0x73, 0x7b, 0xe7, 0x82, 0x04, 0xb1,
- 0x18, 0x98, 0x0e, 0xd4, 0x9c, 0x6f, 0x1a, 0xfc, 0xfc, 0xa7, 0x33, 0xa5,
- 0xbb, 0xbb, 0x18, 0xf3, 0x6b, 0x7a, 0x5d, 0x32, 0x87, 0xf7, 0x6d, 0x25,
- 0xe4, 0xe2, 0x76, 0x86, 0x21, 0x1e, 0x11, 0x46, 0xcd, 0x76, 0x0e, 0x6f,
- 0x4f, 0xa4, 0x21, 0x71, 0x0a, 0x84, 0xa7, 0x2d, 0x36, 0xa9, 0x48, 0x22,
- 0x51, 0x7e, 0x82,
-};
-
-#if 0
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number:
- 0e:e9:4c:c3:00:00:00:00:51:d3:77:85
- Signature Algorithm: sha256WithRSAEncryption
- Issuer: C=US, O=Entrust, Inc., OU=See www.entrust.net/legal-terms, OU=(c) 2009 Entrust, Inc. - for authorized use only, CN=Entrust Root Certification Authority - G2
- Validity
- Not Before: Oct 5 19:13:56 2015 GMT
- Not After : Dec 5 19:43:56 2030 GMT
- Subject: C=US, O=Entrust, Inc., OU=See www.entrust.net/legal-terms, OU=(c) 2012 Entrust, Inc. - for authorized use only, CN=Entrust Certification Authority - L1K
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:da:3f:96:d0:4d:b9:2f:44:e7:db:39:5e:9b:50:
- ee:5c:a5:61:da:41:67:53:09:aa:00:9a:8e:57:7f:
- 29:6b:db:c7:e1:21:24:aa:3a:d0:8d:47:23:d2:ed:
- 72:16:f0:91:21:d2:5d:b7:b8:4b:a8:83:8f:b7:91:
- 32:68:cf:ce:25:93:2c:b2:7d:97:c8:fe:c1:b4:17:
- ba:09:9e:03:90:93:7b:7c:49:83:22:68:8a:9b:de:
- 47:c3:31:98:7a:2e:7d:40:0b:d2:ef:3e:d3:b2:8c:
- aa:8f:48:a9:ff:00:e8:29:58:06:f7:b6:93:5a:94:
- 73:26:26:ad:58:0e:e5:42:b8:d5:ea:73:79:64:68:
- 53:25:b8:84:cf:94:7a:ae:06:45:0c:a3:6b:4d:d0:
- c6:be:ea:18:a4:36:f0:92:b2:ba:1c:88:8f:3a:52:
- 7f:f7:5e:6d:83:1c:9d:f0:1f:e5:c3:d6:dd:a5:78:
- 92:3d:b0:6d:2c:ea:c9:cf:94:41:19:71:44:68:ba:
- 47:3c:04:e9:5d:ba:3e:f0:35:f7:15:b6:9e:f2:2e:
- 15:1e:3f:47:c8:c8:38:a7:73:45:5d:4d:b0:3b:b1:
- 8e:17:29:37:ea:dd:05:01:22:bb:94:36:2a:8d:5b:
- 35:fe:53:19:2f:08:46:c1:2a:b3:1a:62:1d:4e:2b:
- d9:1b
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Key Usage: critical
- Certificate Sign, CRL Sign
- X509v3 Basic Constraints: critical
- CA:TRUE, pathlen:0
- Authority Information Access:
- OCSP - URI:http://ocsp.entrust.net
-
- X509v3 CRL Distribution Points:
-
- Full Name:
- URI:http://crl.entrust.net/g2ca.crl
-
- X509v3 Certificate Policies:
- Policy: X509v3 Any Policy
- CPS: http://www.entrust.net/rpa
-
- X509v3 Subject Key Identifier:
- 82:A2:70:74:DD:BC:53:3F:CF:7B:D4:F7:CD:7F:A7:60:C6:0A:4C:BF
- X509v3 Authority Key Identifier:
- keyid:6A:72:26:7A:D0:1E:EF:7D:E7:3B:69:51:D4:6C:8D:9F:90:12:66:AB
-
- Signature Algorithm: sha256WithRSAEncryption
- 39:d5:8e:98:83:61:c8:2c:63:d3:70:1d:19:30:cb:f6:09:ac:
- cc:69:d5:c9:dc:37:41:f2:32:0f:ef:74:c3:58:f6:78:27:09:
- 34:08:95:92:2f:d7:df:b8:a3:fd:0e:81:e9:a4:9c:d3:3f:4d:
- 68:2b:15:31:0a:15:cc:52:04:93:e8:93:50:c3:d9:b1:e2:e1:
- 68:b7:3a:09:74:f1:34:58:0a:3f:77:98:40:b8:e6:68:ff:5d:
- e4:c8:46:c5:ec:81:d7:c9:82:18:5c:83:ce:71:d8:bc:bf:ac:
- 99:02:93:db:94:98:84:d2:9c:a6:b5:fe:5c:bb:f0:4a:af:21:
- ac:c2:3f:49:24:67:d6:2e:8e:cf:ac:cc:64:15:18:72:e5:6c:
- 77:d3:52:a8:b9:dd:8d:ac:00:4a:35:19:d4:6f:73:a3:75:ef:
- 6b:64:c3:e0:8d:83:12:a1:8a:e7:0e:86:4d:d8:b4:20:1b:be:
- 6a:a5:8c:4b:68:66:e3:2b:c7:58:0b:fb:56:10:d4:91:fb:1d:
- d3:31:58:10:8c:44:e3:75:7b:10:9d:b5:38:b1:f6:aa:ca:81:
- 64:6c:e8:f2:e2:81:55:97:51:7f:e1:c2:27:50:a2:c9:3c:5b:
- 00:43:f6:5b:b9:d5:a5:fc:ff:07:50:40:67:07:b0:55:f0:b7:
- 7e:6e:2d:cc
------BEGIN CERTIFICATE-----
-MIIFDjCCA/agAwIBAgIMDulMwwAAAABR03eFMA0GCSqGSIb3DQEBCwUAMIG+MQsw
-CQYDVQQGEwJVUzEWMBQGA1UEChMNRW50cnVzdCwgSW5jLjEoMCYGA1UECxMfU2Vl
-IHd3dy5lbnRydXN0Lm5ldC9sZWdhbC10ZXJtczE5MDcGA1UECxMwKGMpIDIwMDkg
-RW50cnVzdCwgSW5jLiAtIGZvciBhdXRob3JpemVkIHVzZSBvbmx5MTIwMAYDVQQD
-EylFbnRydXN0IFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMjAeFw0x
-NTEwMDUxOTEzNTZaFw0zMDEyMDUxOTQzNTZaMIG6MQswCQYDVQQGEwJVUzEWMBQG
-A1UEChMNRW50cnVzdCwgSW5jLjEoMCYGA1UECxMfU2VlIHd3dy5lbnRydXN0Lm5l
-dC9sZWdhbC10ZXJtczE5MDcGA1UECxMwKGMpIDIwMTIgRW50cnVzdCwgSW5jLiAt
-IGZvciBhdXRob3JpemVkIHVzZSBvbmx5MS4wLAYDVQQDEyVFbnRydXN0IENlcnRp
-ZmljYXRpb24gQXV0aG9yaXR5IC0gTDFLMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
-MIIBCgKCAQEA2j+W0E25L0Tn2zlem1DuXKVh2kFnUwmqAJqOV38pa9vH4SEkqjrQ
-jUcj0u1yFvCRIdJdt7hLqIOPt5EyaM/OJZMssn2XyP7BtBe6CZ4DkJN7fEmDImiK
-m95HwzGYei59QAvS7z7Tsoyqj0ip/wDoKVgG97aTWpRzJiatWA7lQrjV6nN5ZGhT
-JbiEz5R6rgZFDKNrTdDGvuoYpDbwkrK6HIiPOlJ/915tgxyd8B/lw9bdpXiSPbBt
-LOrJz5RBGXFEaLpHPATpXbo+8DX3Fbae8i4VHj9HyMg4p3NFXU2wO7GOFyk36t0F
-ASK7lDYqjVs1/lMZLwhGwSqzGmIdTivZGwIDAQABo4IBDDCCAQgwDgYDVR0PAQH/
-BAQDAgEGMBIGA1UdEwEB/wQIMAYBAf8CAQAwMwYIKwYBBQUHAQEEJzAlMCMGCCsG
-AQUFBzABhhdodHRwOi8vb2NzcC5lbnRydXN0Lm5ldDAwBgNVHR8EKTAnMCWgI6Ah
-hh9odHRwOi8vY3JsLmVudHJ1c3QubmV0L2cyY2EuY3JsMDsGA1UdIAQ0MDIwMAYE
-VR0gADAoMCYGCCsGAQUFBwIBFhpodHRwOi8vd3d3LmVudHJ1c3QubmV0L3JwYTAd
-BgNVHQ4EFgQUgqJwdN28Uz/Pe9T3zX+nYMYKTL8wHwYDVR0jBBgwFoAUanImetAe
-733nO2lR1GyNn5ASZqswDQYJKoZIhvcNAQELBQADggEBADnVjpiDYcgsY9NwHRkw
-y/YJrMxp1cncN0HyMg/vdMNY9ngnCTQIlZIv19+4o/0OgemknNM/TWgrFTEKFcxS
-BJPok1DD2bHi4Wi3Ogl08TRYCj93mEC45mj/XeTIRsXsgdfJghhcg85x2Ly/rJkC
-k9uUmITSnKa1/ly78EqvIazCP0kkZ9Yujs+szGQVGHLlbHfTUqi53Y2sAEo1GdRv
-c6N172tkw+CNgxKhiucOhk3YtCAbvmqljEtoZuMrx1gL+1YQ1JH7HdMxWBCMRON1
-exCdtTix9qrKgWRs6PLigVWXUX/hwidQosk8WwBD9lu51aX8/wdQQGcHsFXwt35u
-Lcw=
------END CERTIFICATE-----
-#endif
-static const unsigned char kDERCert42[] = {
- 0x30, 0x82, 0x05, 0x0e, 0x30, 0x82, 0x03, 0xf6, 0xa0, 0x03, 0x02, 0x01,
- 0x02, 0x02, 0x0c, 0x0e, 0xe9, 0x4c, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x51,
- 0xd3, 0x77, 0x85, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
- 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x81, 0xbe, 0x31, 0x0b, 0x30,
- 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x16,
- 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0d, 0x45, 0x6e, 0x74,
- 0x72, 0x75, 0x73, 0x74, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x28,
- 0x30, 0x26, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1f, 0x53, 0x65, 0x65,
- 0x20, 0x77, 0x77, 0x77, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74,
- 0x2e, 0x6e, 0x65, 0x74, 0x2f, 0x6c, 0x65, 0x67, 0x61, 0x6c, 0x2d, 0x74,
- 0x65, 0x72, 0x6d, 0x73, 0x31, 0x39, 0x30, 0x37, 0x06, 0x03, 0x55, 0x04,
- 0x0b, 0x13, 0x30, 0x28, 0x63, 0x29, 0x20, 0x32, 0x30, 0x30, 0x39, 0x20,
- 0x45, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2c, 0x20, 0x49, 0x6e, 0x63,
- 0x2e, 0x20, 0x2d, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x61, 0x75, 0x74, 0x68,
- 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x20, 0x75, 0x73, 0x65, 0x20, 0x6f,
- 0x6e, 0x6c, 0x79, 0x31, 0x32, 0x30, 0x30, 0x06, 0x03, 0x55, 0x04, 0x03,
- 0x13, 0x29, 0x45, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x20, 0x52, 0x6f,
- 0x6f, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61,
- 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69,
- 0x74, 0x79, 0x20, 0x2d, 0x20, 0x47, 0x32, 0x30, 0x1e, 0x17, 0x0d, 0x31,
- 0x35, 0x31, 0x30, 0x30, 0x35, 0x31, 0x39, 0x31, 0x33, 0x35, 0x36, 0x5a,
- 0x17, 0x0d, 0x33, 0x30, 0x31, 0x32, 0x30, 0x35, 0x31, 0x39, 0x34, 0x33,
- 0x35, 0x36, 0x5a, 0x30, 0x81, 0xba, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03,
- 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x16, 0x30, 0x14, 0x06,
- 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0d, 0x45, 0x6e, 0x74, 0x72, 0x75, 0x73,
- 0x74, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x28, 0x30, 0x26, 0x06,
- 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1f, 0x53, 0x65, 0x65, 0x20, 0x77, 0x77,
- 0x77, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x6e, 0x65,
- 0x74, 0x2f, 0x6c, 0x65, 0x67, 0x61, 0x6c, 0x2d, 0x74, 0x65, 0x72, 0x6d,
- 0x73, 0x31, 0x39, 0x30, 0x37, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x30,
- 0x28, 0x63, 0x29, 0x20, 0x32, 0x30, 0x31, 0x32, 0x20, 0x45, 0x6e, 0x74,
- 0x72, 0x75, 0x73, 0x74, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x20, 0x2d,
- 0x20, 0x66, 0x6f, 0x72, 0x20, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69,
- 0x7a, 0x65, 0x64, 0x20, 0x75, 0x73, 0x65, 0x20, 0x6f, 0x6e, 0x6c, 0x79,
- 0x31, 0x2e, 0x30, 0x2c, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x25, 0x45,
- 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69,
- 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74,
- 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x20, 0x2d, 0x20, 0x4c, 0x31, 0x4b,
- 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
- 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00,
- 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xda, 0x3f, 0x96,
- 0xd0, 0x4d, 0xb9, 0x2f, 0x44, 0xe7, 0xdb, 0x39, 0x5e, 0x9b, 0x50, 0xee,
- 0x5c, 0xa5, 0x61, 0xda, 0x41, 0x67, 0x53, 0x09, 0xaa, 0x00, 0x9a, 0x8e,
- 0x57, 0x7f, 0x29, 0x6b, 0xdb, 0xc7, 0xe1, 0x21, 0x24, 0xaa, 0x3a, 0xd0,
- 0x8d, 0x47, 0x23, 0xd2, 0xed, 0x72, 0x16, 0xf0, 0x91, 0x21, 0xd2, 0x5d,
- 0xb7, 0xb8, 0x4b, 0xa8, 0x83, 0x8f, 0xb7, 0x91, 0x32, 0x68, 0xcf, 0xce,
- 0x25, 0x93, 0x2c, 0xb2, 0x7d, 0x97, 0xc8, 0xfe, 0xc1, 0xb4, 0x17, 0xba,
- 0x09, 0x9e, 0x03, 0x90, 0x93, 0x7b, 0x7c, 0x49, 0x83, 0x22, 0x68, 0x8a,
- 0x9b, 0xde, 0x47, 0xc3, 0x31, 0x98, 0x7a, 0x2e, 0x7d, 0x40, 0x0b, 0xd2,
- 0xef, 0x3e, 0xd3, 0xb2, 0x8c, 0xaa, 0x8f, 0x48, 0xa9, 0xff, 0x00, 0xe8,
- 0x29, 0x58, 0x06, 0xf7, 0xb6, 0x93, 0x5a, 0x94, 0x73, 0x26, 0x26, 0xad,
- 0x58, 0x0e, 0xe5, 0x42, 0xb8, 0xd5, 0xea, 0x73, 0x79, 0x64, 0x68, 0x53,
- 0x25, 0xb8, 0x84, 0xcf, 0x94, 0x7a, 0xae, 0x06, 0x45, 0x0c, 0xa3, 0x6b,
- 0x4d, 0xd0, 0xc6, 0xbe, 0xea, 0x18, 0xa4, 0x36, 0xf0, 0x92, 0xb2, 0xba,
- 0x1c, 0x88, 0x8f, 0x3a, 0x52, 0x7f, 0xf7, 0x5e, 0x6d, 0x83, 0x1c, 0x9d,
- 0xf0, 0x1f, 0xe5, 0xc3, 0xd6, 0xdd, 0xa5, 0x78, 0x92, 0x3d, 0xb0, 0x6d,
- 0x2c, 0xea, 0xc9, 0xcf, 0x94, 0x41, 0x19, 0x71, 0x44, 0x68, 0xba, 0x47,
- 0x3c, 0x04, 0xe9, 0x5d, 0xba, 0x3e, 0xf0, 0x35, 0xf7, 0x15, 0xb6, 0x9e,
- 0xf2, 0x2e, 0x15, 0x1e, 0x3f, 0x47, 0xc8, 0xc8, 0x38, 0xa7, 0x73, 0x45,
- 0x5d, 0x4d, 0xb0, 0x3b, 0xb1, 0x8e, 0x17, 0x29, 0x37, 0xea, 0xdd, 0x05,
- 0x01, 0x22, 0xbb, 0x94, 0x36, 0x2a, 0x8d, 0x5b, 0x35, 0xfe, 0x53, 0x19,
- 0x2f, 0x08, 0x46, 0xc1, 0x2a, 0xb3, 0x1a, 0x62, 0x1d, 0x4e, 0x2b, 0xd9,
- 0x1b, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x0c, 0x30, 0x82,
- 0x01, 0x08, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff,
- 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d,
- 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02,
- 0x01, 0x00, 0x30, 0x33, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
- 0x01, 0x01, 0x04, 0x27, 0x30, 0x25, 0x30, 0x23, 0x06, 0x08, 0x2b, 0x06,
- 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x17, 0x68, 0x74, 0x74, 0x70,
- 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x65, 0x6e, 0x74, 0x72,
- 0x75, 0x73, 0x74, 0x2e, 0x6e, 0x65, 0x74, 0x30, 0x30, 0x06, 0x03, 0x55,
- 0x1d, 0x1f, 0x04, 0x29, 0x30, 0x27, 0x30, 0x25, 0xa0, 0x23, 0xa0, 0x21,
- 0x86, 0x1f, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c,
- 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x6e, 0x65, 0x74,
- 0x2f, 0x67, 0x32, 0x63, 0x61, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x3b, 0x06,
- 0x03, 0x55, 0x1d, 0x20, 0x04, 0x34, 0x30, 0x32, 0x30, 0x30, 0x06, 0x04,
- 0x55, 0x1d, 0x20, 0x00, 0x30, 0x28, 0x30, 0x26, 0x06, 0x08, 0x2b, 0x06,
- 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x1a, 0x68, 0x74, 0x74, 0x70,
- 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x75,
- 0x73, 0x74, 0x2e, 0x6e, 0x65, 0x74, 0x2f, 0x72, 0x70, 0x61, 0x30, 0x1d,
- 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x82, 0xa2, 0x70,
- 0x74, 0xdd, 0xbc, 0x53, 0x3f, 0xcf, 0x7b, 0xd4, 0xf7, 0xcd, 0x7f, 0xa7,
- 0x60, 0xc6, 0x0a, 0x4c, 0xbf, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23,
- 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x6a, 0x72, 0x26, 0x7a, 0xd0, 0x1e,
- 0xef, 0x7d, 0xe7, 0x3b, 0x69, 0x51, 0xd4, 0x6c, 0x8d, 0x9f, 0x90, 0x12,
- 0x66, 0xab, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
- 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x39, 0xd5,
- 0x8e, 0x98, 0x83, 0x61, 0xc8, 0x2c, 0x63, 0xd3, 0x70, 0x1d, 0x19, 0x30,
- 0xcb, 0xf6, 0x09, 0xac, 0xcc, 0x69, 0xd5, 0xc9, 0xdc, 0x37, 0x41, 0xf2,
- 0x32, 0x0f, 0xef, 0x74, 0xc3, 0x58, 0xf6, 0x78, 0x27, 0x09, 0x34, 0x08,
- 0x95, 0x92, 0x2f, 0xd7, 0xdf, 0xb8, 0xa3, 0xfd, 0x0e, 0x81, 0xe9, 0xa4,
- 0x9c, 0xd3, 0x3f, 0x4d, 0x68, 0x2b, 0x15, 0x31, 0x0a, 0x15, 0xcc, 0x52,
- 0x04, 0x93, 0xe8, 0x93, 0x50, 0xc3, 0xd9, 0xb1, 0xe2, 0xe1, 0x68, 0xb7,
- 0x3a, 0x09, 0x74, 0xf1, 0x34, 0x58, 0x0a, 0x3f, 0x77, 0x98, 0x40, 0xb8,
- 0xe6, 0x68, 0xff, 0x5d, 0xe4, 0xc8, 0x46, 0xc5, 0xec, 0x81, 0xd7, 0xc9,
- 0x82, 0x18, 0x5c, 0x83, 0xce, 0x71, 0xd8, 0xbc, 0xbf, 0xac, 0x99, 0x02,
- 0x93, 0xdb, 0x94, 0x98, 0x84, 0xd2, 0x9c, 0xa6, 0xb5, 0xfe, 0x5c, 0xbb,
- 0xf0, 0x4a, 0xaf, 0x21, 0xac, 0xc2, 0x3f, 0x49, 0x24, 0x67, 0xd6, 0x2e,
- 0x8e, 0xcf, 0xac, 0xcc, 0x64, 0x15, 0x18, 0x72, 0xe5, 0x6c, 0x77, 0xd3,
- 0x52, 0xa8, 0xb9, 0xdd, 0x8d, 0xac, 0x00, 0x4a, 0x35, 0x19, 0xd4, 0x6f,
- 0x73, 0xa3, 0x75, 0xef, 0x6b, 0x64, 0xc3, 0xe0, 0x8d, 0x83, 0x12, 0xa1,
- 0x8a, 0xe7, 0x0e, 0x86, 0x4d, 0xd8, 0xb4, 0x20, 0x1b, 0xbe, 0x6a, 0xa5,
- 0x8c, 0x4b, 0x68, 0x66, 0xe3, 0x2b, 0xc7, 0x58, 0x0b, 0xfb, 0x56, 0x10,
- 0xd4, 0x91, 0xfb, 0x1d, 0xd3, 0x31, 0x58, 0x10, 0x8c, 0x44, 0xe3, 0x75,
- 0x7b, 0x10, 0x9d, 0xb5, 0x38, 0xb1, 0xf6, 0xaa, 0xca, 0x81, 0x64, 0x6c,
- 0xe8, 0xf2, 0xe2, 0x81, 0x55, 0x97, 0x51, 0x7f, 0xe1, 0xc2, 0x27, 0x50,
- 0xa2, 0xc9, 0x3c, 0x5b, 0x00, 0x43, 0xf6, 0x5b, 0xb9, 0xd5, 0xa5, 0xfc,
- 0xff, 0x07, 0x50, 0x40, 0x67, 0x07, 0xb0, 0x55, 0xf0, 0xb7, 0x7e, 0x6e,
- 0x2d, 0xcc,
-};
-
-#if 0
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number: 120038507 (0x727a46b)
- Signature Algorithm: sha256WithRSAEncryption
- Issuer: C=IE, O=Baltimore, OU=CyberTrust, CN=Baltimore CyberTrust Root
- Validity
- Not Before: Apr 2 14:36:10 2014 GMT
- Not After : Apr 2 14:35:52 2021 GMT
- Subject: C=NL, L=Amsterdam, O=Verizon Enterprise Solutions, OU=Cybertrust, CN=Verizon Akamai SureServer CA G14-SHA2
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:dd:6e:9e:02:69:02:b5:a3:99:2e:08:64:32:6a:
- 59:f3:c6:9e:a6:20:07:d2:48:d1:a8:93:c7:ea:47:
- 8f:83:39:40:d7:20:5d:8d:9a:ba:ab:d8:70:ec:9d:
- 88:d1:bd:62:f6:db:ec:9d:5e:35:01:76:03:23:e5:
- 6f:d2:af:46:35:59:5a:5c:d1:a8:23:c1:eb:e9:20:
- d4:49:d6:3f:00:d8:a8:22:de:43:79:81:ac:e9:a4:
- 92:f5:77:70:05:1e:5c:b6:a0:f7:90:a4:cd:ab:28:
- 2c:90:c2:e7:0f:c3:af:1c:47:59:d5:84:2e:df:26:
- 07:45:23:5a:c6:e8:90:c8:85:4b:8c:16:1e:60:f9:
- 01:13:f1:14:1f:e6:e8:14:ed:c5:d2:6f:63:28:6e:
- 72:8c:49:ae:08:72:c7:93:95:b4:0b:0c:ae:8f:9a:
- 67:84:f5:57:1b:db:81:d7:17:9d:41:11:43:19:bd:
- 6d:4a:85:ed:8f:70:25:ab:66:ab:f6:fa:6d:1c:3c:
- ab:ed:17:bd:56:84:e1:db:75:33:b2:28:4b:99:8e:
- f9:4b:82:33:50:9f:92:53:ed:fa:ad:0f:95:9c:a3:
- f2:cb:60:f0:77:1d:c9:01:8b:5f:2d:86:be:bf:36:
- b8:24:96:13:7c:c1:86:5a:6c:c1:48:2a:7f:3e:93:
- 60:c5
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Basic Constraints: critical
- CA:TRUE, pathlen:2
- X509v3 Certificate Policies:
- Policy: 1.3.6.1.4.1.6334.1.50
- CPS: https://secure.omniroot.com/repository
-
- Authority Information Access:
- OCSP - URI:http://ocsp.omniroot.com/baltimoreroot
- CA Issuers - URI:https://cacert.omniroot.com/baltimoreroot.crt
- CA Issuers - URI:https://cacert.omniroot.com/baltimoreroot.der
-
- X509v3 Key Usage: critical
- Digital Signature, Non Repudiation, Certificate Sign, CRL Sign
- X509v3 Authority Key Identifier:
- keyid:E5:9D:59:30:82:47:58:CC:AC:FA:08:54:36:86:7B:3A:B5:04:4D:F0
-
- X509v3 CRL Distribution Points:
-
- Full Name:
- URI:http://cdp1.public-trust.com/CRL/Omniroot2025.crl
-
- X509v3 Subject Key Identifier:
- F8:BD:FA:AF:73:77:C6:C7:1B:F9:4B:4D:11:A7:D1:33:AF:AF:72:11
- Signature Algorithm: sha256WithRSAEncryption
- 80:d9:7a:ed:72:05:37:8f:61:aa:73:7c:9a:6a:fc:fe:01:e2:
- 19:81:70:07:25:32:b0:f0:6f:3b:c7:6a:28:3d:e4:51:87:e6:
- 7e:82:ec:ae:48:a7:b1:77:38:c2:d6:56:af:8f:f2:01:fc:65:
- 65:10:09:f7:74:29:b5:0e:92:ee:90:98:d1:88:a2:65:b7:cd:
- 9c:0e:a7:86:98:28:bc:ae:15:83:b6:1a:d7:1d:ec:19:da:7a:
- 8e:40:f9:99:15:d5:7d:a5:ba:ab:fd:26:98:6e:9c:41:3b:b6:
- 81:18:ec:70:48:d7:6e:7f:a6:e1:77:25:d6:dd:62:e8:52:f3:
- 8c:16:39:67:e2:22:0d:77:2e:fb:11:6c:e4:dd:38:b4:27:5f:
- 03:a8:3d:44:e2:f2:84:4b:84:fd:56:a6:9e:4d:7b:a2:16:4f:
- 07:f5:34:24:72:a5:a2:fa:16:66:2a:a4:4a:0e:c8:0d:27:44:
- 9c:77:d4:12:10:87:d2:00:2c:7a:bb:8e:88:22:91:15:be:a2:
- 59:ca:34:e0:1c:61:94:86:20:33:cd:e7:4c:5d:3b:92:3e:cb:
- d6:2d:ea:54:fa:fb:af:54:f5:a8:c5:0b:ca:8b:87:00:e6:9f:
- e6:95:bf:b7:c4:a3:59:f5:16:6c:5f:3e:69:55:80:39:f6:75:
- 50:14:3e:32
------BEGIN CERTIFICATE-----
-MIIFHzCCBAegAwIBAgIEByekazANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJJ
-RTESMBAGA1UEChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYD
-VQQDExlCYWx0aW1vcmUgQ3liZXJUcnVzdCBSb290MB4XDTE0MDQwMjE0MzYxMFoX
-DTIxMDQwMjE0MzU1MlowgY0xCzAJBgNVBAYTAk5MMRIwEAYDVQQHEwlBbXN0ZXJk
-YW0xJTAjBgNVBAoTHFZlcml6b24gRW50ZXJwcmlzZSBTb2x1dGlvbnMxEzARBgNV
-BAsTCkN5YmVydHJ1c3QxLjAsBgNVBAMTJVZlcml6b24gQWthbWFpIFN1cmVTZXJ2
-ZXIgQ0EgRzE0LVNIQTIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDd
-bp4CaQK1o5kuCGQyalnzxp6mIAfSSNGok8fqR4+DOUDXIF2Nmrqr2HDsnYjRvWL2
-2+ydXjUBdgMj5W/Sr0Y1WVpc0agjwevpINRJ1j8A2Kgi3kN5gazppJL1d3AFHly2
-oPeQpM2rKCyQwucPw68cR1nVhC7fJgdFI1rG6JDIhUuMFh5g+QET8RQf5ugU7cXS
-b2MobnKMSa4IcseTlbQLDK6PmmeE9Vcb24HXF51BEUMZvW1Khe2PcCWrZqv2+m0c
-PKvtF71WhOHbdTOyKEuZjvlLgjNQn5JT7fqtD5Wco/LLYPB3HckBi18thr6/Nrgk
-lhN8wYZabMFIKn8+k2DFAgMBAAGjggG3MIIBszASBgNVHRMBAf8ECDAGAQH/AgEC
-MEwGA1UdIARFMEMwQQYJKwYBBAGxPgEyMDQwMgYIKwYBBQUHAgEWJmh0dHBzOi8v
-c2VjdXJlLm9tbmlyb290LmNvbS9yZXBvc2l0b3J5MIG6BggrBgEFBQcBAQSBrTCB
-qjAyBggrBgEFBQcwAYYmaHR0cDovL29jc3Aub21uaXJvb3QuY29tL2JhbHRpbW9y
-ZXJvb3QwOQYIKwYBBQUHMAKGLWh0dHBzOi8vY2FjZXJ0Lm9tbmlyb290LmNvbS9i
-YWx0aW1vcmVyb290LmNydDA5BggrBgEFBQcwAoYtaHR0cHM6Ly9jYWNlcnQub21u
-aXJvb3QuY29tL2JhbHRpbW9yZXJvb3QuZGVyMA4GA1UdDwEB/wQEAwIBxjAfBgNV
-HSMEGDAWgBTlnVkwgkdYzKz6CFQ2hns6tQRN8DBCBgNVHR8EOzA5MDegNaAzhjFo
-dHRwOi8vY2RwMS5wdWJsaWMtdHJ1c3QuY29tL0NSTC9PbW5pcm9vdDIwMjUuY3Js
-MB0GA1UdDgQWBBT4vfqvc3fGxxv5S00Rp9Ezr69yETANBgkqhkiG9w0BAQsFAAOC
-AQEAgNl67XIFN49hqnN8mmr8/gHiGYFwByUysPBvO8dqKD3kUYfmfoLsrkinsXc4
-wtZWr4/yAfxlZRAJ93QptQ6S7pCY0YiiZbfNnA6nhpgovK4Vg7Ya1x3sGdp6jkD5
-mRXVfaW6q/0mmG6cQTu2gRjscEjXbn+m4Xcl1t1i6FLzjBY5Z+IiDXcu+xFs5N04
-tCdfA6g9ROLyhEuE/Vamnk17ohZPB/U0JHKlovoWZiqkSg7IDSdEnHfUEhCH0gAs
-eruOiCKRFb6iWco04BxhlIYgM83nTF07kj7L1i3qVPr7r1T1qMULyouHAOaf5pW/
-t8SjWfUWbF8+aVWAOfZ1UBQ+Mg==
------END CERTIFICATE-----
-#endif
-static const unsigned char kDERCert43[] = {
- 0x30, 0x82, 0x05, 0x1f, 0x30, 0x82, 0x04, 0x07, 0xa0, 0x03, 0x02, 0x01,
- 0x02, 0x02, 0x04, 0x07, 0x27, 0xa4, 0x6b, 0x30, 0x0d, 0x06, 0x09, 0x2a,
- 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x5a,
- 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x49,
- 0x45, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x09,
- 0x42, 0x61, 0x6c, 0x74, 0x69, 0x6d, 0x6f, 0x72, 0x65, 0x31, 0x13, 0x30,
- 0x11, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x0a, 0x43, 0x79, 0x62, 0x65,
- 0x72, 0x54, 0x72, 0x75, 0x73, 0x74, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03,
- 0x55, 0x04, 0x03, 0x13, 0x19, 0x42, 0x61, 0x6c, 0x74, 0x69, 0x6d, 0x6f,
- 0x72, 0x65, 0x20, 0x43, 0x79, 0x62, 0x65, 0x72, 0x54, 0x72, 0x75, 0x73,
- 0x74, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x34,
- 0x30, 0x34, 0x30, 0x32, 0x31, 0x34, 0x33, 0x36, 0x31, 0x30, 0x5a, 0x17,
- 0x0d, 0x32, 0x31, 0x30, 0x34, 0x30, 0x32, 0x31, 0x34, 0x33, 0x35, 0x35,
- 0x32, 0x5a, 0x30, 0x81, 0x8d, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55,
- 0x04, 0x06, 0x13, 0x02, 0x4e, 0x4c, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03,
- 0x55, 0x04, 0x07, 0x13, 0x09, 0x41, 0x6d, 0x73, 0x74, 0x65, 0x72, 0x64,
- 0x61, 0x6d, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13,
- 0x1c, 0x56, 0x65, 0x72, 0x69, 0x7a, 0x6f, 0x6e, 0x20, 0x45, 0x6e, 0x74,
- 0x65, 0x72, 0x70, 0x72, 0x69, 0x73, 0x65, 0x20, 0x53, 0x6f, 0x6c, 0x75,
- 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55,
- 0x04, 0x0b, 0x13, 0x0a, 0x43, 0x79, 0x62, 0x65, 0x72, 0x74, 0x72, 0x75,
- 0x73, 0x74, 0x31, 0x2e, 0x30, 0x2c, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
- 0x25, 0x56, 0x65, 0x72, 0x69, 0x7a, 0x6f, 0x6e, 0x20, 0x41, 0x6b, 0x61,
- 0x6d, 0x61, 0x69, 0x20, 0x53, 0x75, 0x72, 0x65, 0x53, 0x65, 0x72, 0x76,
- 0x65, 0x72, 0x20, 0x43, 0x41, 0x20, 0x47, 0x31, 0x34, 0x2d, 0x53, 0x48,
- 0x41, 0x32, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
- 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01,
- 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xdd,
- 0x6e, 0x9e, 0x02, 0x69, 0x02, 0xb5, 0xa3, 0x99, 0x2e, 0x08, 0x64, 0x32,
- 0x6a, 0x59, 0xf3, 0xc6, 0x9e, 0xa6, 0x20, 0x07, 0xd2, 0x48, 0xd1, 0xa8,
- 0x93, 0xc7, 0xea, 0x47, 0x8f, 0x83, 0x39, 0x40, 0xd7, 0x20, 0x5d, 0x8d,
- 0x9a, 0xba, 0xab, 0xd8, 0x70, 0xec, 0x9d, 0x88, 0xd1, 0xbd, 0x62, 0xf6,
- 0xdb, 0xec, 0x9d, 0x5e, 0x35, 0x01, 0x76, 0x03, 0x23, 0xe5, 0x6f, 0xd2,
- 0xaf, 0x46, 0x35, 0x59, 0x5a, 0x5c, 0xd1, 0xa8, 0x23, 0xc1, 0xeb, 0xe9,
- 0x20, 0xd4, 0x49, 0xd6, 0x3f, 0x00, 0xd8, 0xa8, 0x22, 0xde, 0x43, 0x79,
- 0x81, 0xac, 0xe9, 0xa4, 0x92, 0xf5, 0x77, 0x70, 0x05, 0x1e, 0x5c, 0xb6,
- 0xa0, 0xf7, 0x90, 0xa4, 0xcd, 0xab, 0x28, 0x2c, 0x90, 0xc2, 0xe7, 0x0f,
- 0xc3, 0xaf, 0x1c, 0x47, 0x59, 0xd5, 0x84, 0x2e, 0xdf, 0x26, 0x07, 0x45,
- 0x23, 0x5a, 0xc6, 0xe8, 0x90, 0xc8, 0x85, 0x4b, 0x8c, 0x16, 0x1e, 0x60,
- 0xf9, 0x01, 0x13, 0xf1, 0x14, 0x1f, 0xe6, 0xe8, 0x14, 0xed, 0xc5, 0xd2,
- 0x6f, 0x63, 0x28, 0x6e, 0x72, 0x8c, 0x49, 0xae, 0x08, 0x72, 0xc7, 0x93,
- 0x95, 0xb4, 0x0b, 0x0c, 0xae, 0x8f, 0x9a, 0x67, 0x84, 0xf5, 0x57, 0x1b,
- 0xdb, 0x81, 0xd7, 0x17, 0x9d, 0x41, 0x11, 0x43, 0x19, 0xbd, 0x6d, 0x4a,
- 0x85, 0xed, 0x8f, 0x70, 0x25, 0xab, 0x66, 0xab, 0xf6, 0xfa, 0x6d, 0x1c,
- 0x3c, 0xab, 0xed, 0x17, 0xbd, 0x56, 0x84, 0xe1, 0xdb, 0x75, 0x33, 0xb2,
- 0x28, 0x4b, 0x99, 0x8e, 0xf9, 0x4b, 0x82, 0x33, 0x50, 0x9f, 0x92, 0x53,
- 0xed, 0xfa, 0xad, 0x0f, 0x95, 0x9c, 0xa3, 0xf2, 0xcb, 0x60, 0xf0, 0x77,
- 0x1d, 0xc9, 0x01, 0x8b, 0x5f, 0x2d, 0x86, 0xbe, 0xbf, 0x36, 0xb8, 0x24,
- 0x96, 0x13, 0x7c, 0xc1, 0x86, 0x5a, 0x6c, 0xc1, 0x48, 0x2a, 0x7f, 0x3e,
- 0x93, 0x60, 0xc5, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0xb7,
- 0x30, 0x82, 0x01, 0xb3, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01,
- 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x02,
- 0x30, 0x4c, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x45, 0x30, 0x43, 0x30,
- 0x41, 0x06, 0x09, 0x2b, 0x06, 0x01, 0x04, 0x01, 0xb1, 0x3e, 0x01, 0x32,
- 0x30, 0x34, 0x30, 0x32, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
- 0x02, 0x01, 0x16, 0x26, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f,
- 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x2e, 0x6f, 0x6d, 0x6e, 0x69, 0x72,
- 0x6f, 0x6f, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x70, 0x6f,
- 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x30, 0x81, 0xba, 0x06, 0x08, 0x2b,
- 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x81, 0xad, 0x30, 0x81,
- 0xaa, 0x30, 0x32, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30,
- 0x01, 0x86, 0x26, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63,
- 0x73, 0x70, 0x2e, 0x6f, 0x6d, 0x6e, 0x69, 0x72, 0x6f, 0x6f, 0x74, 0x2e,
- 0x63, 0x6f, 0x6d, 0x2f, 0x62, 0x61, 0x6c, 0x74, 0x69, 0x6d, 0x6f, 0x72,
- 0x65, 0x72, 0x6f, 0x6f, 0x74, 0x30, 0x39, 0x06, 0x08, 0x2b, 0x06, 0x01,
- 0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x2d, 0x68, 0x74, 0x74, 0x70, 0x73,
- 0x3a, 0x2f, 0x2f, 0x63, 0x61, 0x63, 0x65, 0x72, 0x74, 0x2e, 0x6f, 0x6d,
- 0x6e, 0x69, 0x72, 0x6f, 0x6f, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x62,
- 0x61, 0x6c, 0x74, 0x69, 0x6d, 0x6f, 0x72, 0x65, 0x72, 0x6f, 0x6f, 0x74,
- 0x2e, 0x63, 0x72, 0x74, 0x30, 0x39, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05,
- 0x05, 0x07, 0x30, 0x02, 0x86, 0x2d, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a,
- 0x2f, 0x2f, 0x63, 0x61, 0x63, 0x65, 0x72, 0x74, 0x2e, 0x6f, 0x6d, 0x6e,
- 0x69, 0x72, 0x6f, 0x6f, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x62, 0x61,
- 0x6c, 0x74, 0x69, 0x6d, 0x6f, 0x72, 0x65, 0x72, 0x6f, 0x6f, 0x74, 0x2e,
- 0x64, 0x65, 0x72, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01,
- 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0xc6, 0x30, 0x1f, 0x06, 0x03, 0x55,
- 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0xe5, 0x9d, 0x59, 0x30,
- 0x82, 0x47, 0x58, 0xcc, 0xac, 0xfa, 0x08, 0x54, 0x36, 0x86, 0x7b, 0x3a,
- 0xb5, 0x04, 0x4d, 0xf0, 0x30, 0x42, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04,
- 0x3b, 0x30, 0x39, 0x30, 0x37, 0xa0, 0x35, 0xa0, 0x33, 0x86, 0x31, 0x68,
- 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x64, 0x70, 0x31, 0x2e, 0x70,
- 0x75, 0x62, 0x6c, 0x69, 0x63, 0x2d, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e,
- 0x63, 0x6f, 0x6d, 0x2f, 0x43, 0x52, 0x4c, 0x2f, 0x4f, 0x6d, 0x6e, 0x69,
- 0x72, 0x6f, 0x6f, 0x74, 0x32, 0x30, 0x32, 0x35, 0x2e, 0x63, 0x72, 0x6c,
- 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xf8,
- 0xbd, 0xfa, 0xaf, 0x73, 0x77, 0xc6, 0xc7, 0x1b, 0xf9, 0x4b, 0x4d, 0x11,
- 0xa7, 0xd1, 0x33, 0xaf, 0xaf, 0x72, 0x11, 0x30, 0x0d, 0x06, 0x09, 0x2a,
- 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82,
- 0x01, 0x01, 0x00, 0x80, 0xd9, 0x7a, 0xed, 0x72, 0x05, 0x37, 0x8f, 0x61,
- 0xaa, 0x73, 0x7c, 0x9a, 0x6a, 0xfc, 0xfe, 0x01, 0xe2, 0x19, 0x81, 0x70,
- 0x07, 0x25, 0x32, 0xb0, 0xf0, 0x6f, 0x3b, 0xc7, 0x6a, 0x28, 0x3d, 0xe4,
- 0x51, 0x87, 0xe6, 0x7e, 0x82, 0xec, 0xae, 0x48, 0xa7, 0xb1, 0x77, 0x38,
- 0xc2, 0xd6, 0x56, 0xaf, 0x8f, 0xf2, 0x01, 0xfc, 0x65, 0x65, 0x10, 0x09,
- 0xf7, 0x74, 0x29, 0xb5, 0x0e, 0x92, 0xee, 0x90, 0x98, 0xd1, 0x88, 0xa2,
- 0x65, 0xb7, 0xcd, 0x9c, 0x0e, 0xa7, 0x86, 0x98, 0x28, 0xbc, 0xae, 0x15,
- 0x83, 0xb6, 0x1a, 0xd7, 0x1d, 0xec, 0x19, 0xda, 0x7a, 0x8e, 0x40, 0xf9,
- 0x99, 0x15, 0xd5, 0x7d, 0xa5, 0xba, 0xab, 0xfd, 0x26, 0x98, 0x6e, 0x9c,
- 0x41, 0x3b, 0xb6, 0x81, 0x18, 0xec, 0x70, 0x48, 0xd7, 0x6e, 0x7f, 0xa6,
- 0xe1, 0x77, 0x25, 0xd6, 0xdd, 0x62, 0xe8, 0x52, 0xf3, 0x8c, 0x16, 0x39,
- 0x67, 0xe2, 0x22, 0x0d, 0x77, 0x2e, 0xfb, 0x11, 0x6c, 0xe4, 0xdd, 0x38,
- 0xb4, 0x27, 0x5f, 0x03, 0xa8, 0x3d, 0x44, 0xe2, 0xf2, 0x84, 0x4b, 0x84,
- 0xfd, 0x56, 0xa6, 0x9e, 0x4d, 0x7b, 0xa2, 0x16, 0x4f, 0x07, 0xf5, 0x34,
- 0x24, 0x72, 0xa5, 0xa2, 0xfa, 0x16, 0x66, 0x2a, 0xa4, 0x4a, 0x0e, 0xc8,
- 0x0d, 0x27, 0x44, 0x9c, 0x77, 0xd4, 0x12, 0x10, 0x87, 0xd2, 0x00, 0x2c,
- 0x7a, 0xbb, 0x8e, 0x88, 0x22, 0x91, 0x15, 0xbe, 0xa2, 0x59, 0xca, 0x34,
- 0xe0, 0x1c, 0x61, 0x94, 0x86, 0x20, 0x33, 0xcd, 0xe7, 0x4c, 0x5d, 0x3b,
- 0x92, 0x3e, 0xcb, 0xd6, 0x2d, 0xea, 0x54, 0xfa, 0xfb, 0xaf, 0x54, 0xf5,
- 0xa8, 0xc5, 0x0b, 0xca, 0x8b, 0x87, 0x00, 0xe6, 0x9f, 0xe6, 0x95, 0xbf,
- 0xb7, 0xc4, 0xa3, 0x59, 0xf5, 0x16, 0x6c, 0x5f, 0x3e, 0x69, 0x55, 0x80,
- 0x39, 0xf6, 0x75, 0x50, 0x14, 0x3e, 0x32,
-};
-
-#if 0
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number:
- 7e:e1:4a:6f:6f:ef:f2:d3:7f:3f:ad:65:4d:3a:da:b4
- Signature Algorithm: sha256WithRSAEncryption
- Issuer: C=US, O=VeriSign, Inc., OU=VeriSign Trust Network, OU=(c) 2006 VeriSign, Inc. - For authorized use only, CN=VeriSign Class 3 Public Primary Certification Authority - G5
- Validity
- Not Before: Oct 31 00:00:00 2013 GMT
- Not After : Oct 30 23:59:59 2023 GMT
- Subject: C=US, O=Symantec Corporation, OU=Symantec Trust Network, CN=Symantec Class 3 EV SSL CA - G3
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:d8:a1:65:74:23:e8:2b:64:e2:32:d7:33:37:3d:
- 8e:f5:34:16:48:dd:4f:7f:87:1c:f8:44:23:13:8e:
- fb:11:d8:44:5a:18:71:8e:60:16:26:92:9b:fd:17:
- 0b:e1:71:70:42:fe:bf:fa:1c:c0:aa:a3:a7:b5:71:
- e8:ff:18:83:f6:df:10:0a:13:62:c8:3d:9c:a7:de:
- 2e:3f:0c:d9:1d:e7:2e:fb:2a:ce:c8:9a:7f:87:bf:
- d8:4c:04:15:32:c9:d1:cc:95:71:a0:4e:28:4f:84:
- d9:35:fb:e3:86:6f:94:53:e6:72:8a:63:67:2e:be:
- 69:f6:f7:6e:8e:9c:60:04:eb:29:fa:c4:47:42:d2:
- 78:98:e3:ec:0b:a5:92:dc:b7:9a:bd:80:64:2b:38:
- 7c:38:09:5b:66:f6:2d:95:7a:86:b2:34:2e:85:9e:
- 90:0e:5f:b7:5d:a4:51:72:46:70:13:bf:67:f2:b6:
- a7:4d:14:1e:6c:b9:53:ee:23:1a:4e:8d:48:55:43:
- 41:b1:89:75:6a:40:28:c5:7d:dd:d2:6e:d2:02:19:
- 2f:7b:24:94:4b:eb:f1:1a:a9:9b:e3:23:9a:ea:fa:
- 33:ab:0a:2c:b7:f4:60:08:dd:9f:1c:cd:dd:2d:01:
- 66:80:af:b3:2f:29:1d:23:b8:8a:e1:a1:70:07:0c:
- 34:0f
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- Authority Information Access:
- OCSP - URI:http://s2.symcb.com
-
- X509v3 Basic Constraints: critical
- CA:TRUE, pathlen:0
- X509v3 Certificate Policies:
- Policy: X509v3 Any Policy
- CPS: http://www.symauth.com/cps
- User Notice:
- Explicit Text: http://www.symauth.com/rpa
-
- X509v3 CRL Distribution Points:
-
- Full Name:
- URI:http://s1.symcb.com/pca3-g5.crl
-
- X509v3 Key Usage: critical
- Certificate Sign, CRL Sign
- X509v3 Subject Alternative Name:
- DirName:/CN=SymantecPKI-1-533
- X509v3 Subject Key Identifier:
- 01:59:AB:E7:DD:3A:0B:59:A6:64:63:D6:CF:20:07:57:D5:91:E7:6A
- X509v3 Authority Key Identifier:
- keyid:7F:D3:65:A7:C2:DD:EC:BB:F0:30:09:F3:43:39:FA:02:AF:33:31:33
-
- Signature Algorithm: sha256WithRSAEncryption
- 42:01:55:7b:d0:16:1a:5d:58:e8:bb:9b:a8:4d:d7:f3:d7:eb:
- 13:94:86:d6:7f:21:0b:47:bc:57:9b:92:5d:4f:05:9f:38:a4:
- 10:7c:cf:83:be:06:43:46:8d:08:bc:6a:d7:10:a6:fa:ab:af:
- 2f:61:a8:63:f2:65:df:7f:4c:88:12:88:4f:b3:69:d9:ff:27:
- c0:0a:97:91:8f:56:fb:89:c4:a8:bb:92:2d:1b:73:b0:c6:ab:
- 36:f4:96:6c:20:08:ef:0a:1e:66:24:45:4f:67:00:40:c8:07:
- 54:74:33:3b:a6:ad:bb:23:9f:66:ed:a2:44:70:34:fb:0e:ea:
- 01:fd:cf:78:74:df:a7:ad:55:b7:5f:4d:f6:d6:3f:e0:86:ce:
- 24:c7:42:a9:13:14:44:35:4b:b6:df:c9:60:ac:0c:7f:d9:93:
- 21:4b:ee:9c:e4:49:02:98:d3:60:7b:5c:bc:d5:30:2f:07:ce:
- 44:42:c4:0b:99:fe:e6:9f:fc:b0:78:86:51:6d:d1:2c:9d:c6:
- 96:fb:85:82:bb:04:2f:f7:62:80:ef:62:da:7f:f6:0e:ac:90:
- b8:56:bd:79:3f:f2:80:6e:a3:d9:b9:0f:5d:3a:07:1d:91:93:
- 86:4b:29:4c:e1:dc:b5:e1:e0:33:9d:b3:cb:36:91:4b:fe:a1:
- b4:ee:f0:f9
------BEGIN CERTIFICATE-----
-MIIFKzCCBBOgAwIBAgIQfuFKb2/v8tN/P61lTTratDANBgkqhkiG9w0BAQsFADCB
-yjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL
-ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJp
-U2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxW
-ZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0
-aG9yaXR5IC0gRzUwHhcNMTMxMDMxMDAwMDAwWhcNMjMxMDMwMjM1OTU5WjB3MQsw
-CQYDVQQGEwJVUzEdMBsGA1UEChMUU3ltYW50ZWMgQ29ycG9yYXRpb24xHzAdBgNV
-BAsTFlN5bWFudGVjIFRydXN0IE5ldHdvcmsxKDAmBgNVBAMTH1N5bWFudGVjIENs
-YXNzIDMgRVYgU1NMIENBIC0gRzMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
-AoIBAQDYoWV0I+grZOIy1zM3PY71NBZI3U9/hxz4RCMTjvsR2ERaGHGOYBYmkpv9
-FwvhcXBC/r/6HMCqo6e1cej/GIP23xAKE2LIPZyn3i4/DNkd5y77Ks7Imn+Hv9hM
-BBUyydHMlXGgTihPhNk1++OGb5RT5nKKY2cuvmn2926OnGAE6yn6xEdC0niY4+wL
-pZLct5q9gGQrOHw4CVtm9i2VeoayNC6FnpAOX7ddpFFyRnATv2fytqdNFB5suVPu
-IxpOjUhVQ0GxiXVqQCjFfd3SbtICGS97JJRL6/EaqZvjI5rq+jOrCiy39GAI3Z8c
-zd0tAWaAr7MvKR0juIrhoXAHDDQPAgMBAAGjggFdMIIBWTAvBggrBgEFBQcBAQQj
-MCEwHwYIKwYBBQUHMAGGE2h0dHA6Ly9zMi5zeW1jYi5jb20wEgYDVR0TAQH/BAgw
-BgEB/wIBADBlBgNVHSAEXjBcMFoGBFUdIAAwUjAmBggrBgEFBQcCARYaaHR0cDov
-L3d3dy5zeW1hdXRoLmNvbS9jcHMwKAYIKwYBBQUHAgIwHBoaaHR0cDovL3d3dy5z
-eW1hdXRoLmNvbS9ycGEwMAYDVR0fBCkwJzAloCOgIYYfaHR0cDovL3MxLnN5bWNi
-LmNvbS9wY2EzLWc1LmNybDAOBgNVHQ8BAf8EBAMCAQYwKQYDVR0RBCIwIKQeMBwx
-GjAYBgNVBAMTEVN5bWFudGVjUEtJLTEtNTMzMB0GA1UdDgQWBBQBWavn3ToLWaZk
-Y9bPIAdX1ZHnajAfBgNVHSMEGDAWgBR/02Wnwt3su/AwCfNDOfoCrzMxMzANBgkq
-hkiG9w0BAQsFAAOCAQEAQgFVe9AWGl1Y6LubqE3X89frE5SG1n8hC0e8V5uSXU8F
-nzikEHzPg74GQ0aNCLxq1xCm+quvL2GoY/Jl339MiBKIT7Np2f8nwAqXkY9W+4nE
-qLuSLRtzsMarNvSWbCAI7woeZiRFT2cAQMgHVHQzO6atuyOfZu2iRHA0+w7qAf3P
-eHTfp61Vt19N9tY/4IbOJMdCqRMURDVLtt/JYKwMf9mTIUvunORJApjTYHtcvNUw
-LwfORELEC5n+5p/8sHiGUW3RLJ3GlvuFgrsEL/digO9i2n/2DqyQuFa9eT/ygG6j
-2bkPXToHHZGThkspTOHcteHgM52zyzaRS/6htO7w+Q==
------END CERTIFICATE-----
-#endif
-static const unsigned char kDERCert44[] = {
- 0x30, 0x82, 0x05, 0x2b, 0x30, 0x82, 0x04, 0x13, 0xa0, 0x03, 0x02, 0x01,
- 0x02, 0x02, 0x10, 0x7e, 0xe1, 0x4a, 0x6f, 0x6f, 0xef, 0xf2, 0xd3, 0x7f,
- 0x3f, 0xad, 0x65, 0x4d, 0x3a, 0xda, 0xb4, 0x30, 0x0d, 0x06, 0x09, 0x2a,
- 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x81,
- 0xca, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
- 0x55, 0x53, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13,
- 0x0e, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49,
- 0x6e, 0x63, 0x2e, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x0b,
- 0x13, 0x16, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x54,
- 0x72, 0x75, 0x73, 0x74, 0x20, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b,
- 0x31, 0x3a, 0x30, 0x38, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x31, 0x28,
- 0x63, 0x29, 0x20, 0x32, 0x30, 0x30, 0x36, 0x20, 0x56, 0x65, 0x72, 0x69,
- 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x20, 0x2d,
- 0x20, 0x46, 0x6f, 0x72, 0x20, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69,
- 0x7a, 0x65, 0x64, 0x20, 0x75, 0x73, 0x65, 0x20, 0x6f, 0x6e, 0x6c, 0x79,
- 0x31, 0x45, 0x30, 0x43, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x3c, 0x56,
- 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x43, 0x6c, 0x61, 0x73,
- 0x73, 0x20, 0x33, 0x20, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x20, 0x50,
- 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69,
- 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74,
- 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x20, 0x2d, 0x20, 0x47, 0x35, 0x30,
- 0x1e, 0x17, 0x0d, 0x31, 0x33, 0x31, 0x30, 0x33, 0x31, 0x30, 0x30, 0x30,
- 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x33, 0x31, 0x30, 0x33, 0x30,
- 0x32, 0x33, 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x77, 0x31, 0x0b, 0x30,
- 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x1d,
- 0x30, 0x1b, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x14, 0x53, 0x79, 0x6d,
- 0x61, 0x6e, 0x74, 0x65, 0x63, 0x20, 0x43, 0x6f, 0x72, 0x70, 0x6f, 0x72,
- 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55,
- 0x04, 0x0b, 0x13, 0x16, 0x53, 0x79, 0x6d, 0x61, 0x6e, 0x74, 0x65, 0x63,
- 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x4e, 0x65, 0x74, 0x77, 0x6f,
- 0x72, 0x6b, 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
- 0x1f, 0x53, 0x79, 0x6d, 0x61, 0x6e, 0x74, 0x65, 0x63, 0x20, 0x43, 0x6c,
- 0x61, 0x73, 0x73, 0x20, 0x33, 0x20, 0x45, 0x56, 0x20, 0x53, 0x53, 0x4c,
- 0x20, 0x43, 0x41, 0x20, 0x2d, 0x20, 0x47, 0x33, 0x30, 0x82, 0x01, 0x22,
- 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
- 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a,
- 0x02, 0x82, 0x01, 0x01, 0x00, 0xd8, 0xa1, 0x65, 0x74, 0x23, 0xe8, 0x2b,
- 0x64, 0xe2, 0x32, 0xd7, 0x33, 0x37, 0x3d, 0x8e, 0xf5, 0x34, 0x16, 0x48,
- 0xdd, 0x4f, 0x7f, 0x87, 0x1c, 0xf8, 0x44, 0x23, 0x13, 0x8e, 0xfb, 0x11,
- 0xd8, 0x44, 0x5a, 0x18, 0x71, 0x8e, 0x60, 0x16, 0x26, 0x92, 0x9b, 0xfd,
- 0x17, 0x0b, 0xe1, 0x71, 0x70, 0x42, 0xfe, 0xbf, 0xfa, 0x1c, 0xc0, 0xaa,
- 0xa3, 0xa7, 0xb5, 0x71, 0xe8, 0xff, 0x18, 0x83, 0xf6, 0xdf, 0x10, 0x0a,
- 0x13, 0x62, 0xc8, 0x3d, 0x9c, 0xa7, 0xde, 0x2e, 0x3f, 0x0c, 0xd9, 0x1d,
- 0xe7, 0x2e, 0xfb, 0x2a, 0xce, 0xc8, 0x9a, 0x7f, 0x87, 0xbf, 0xd8, 0x4c,
- 0x04, 0x15, 0x32, 0xc9, 0xd1, 0xcc, 0x95, 0x71, 0xa0, 0x4e, 0x28, 0x4f,
- 0x84, 0xd9, 0x35, 0xfb, 0xe3, 0x86, 0x6f, 0x94, 0x53, 0xe6, 0x72, 0x8a,
- 0x63, 0x67, 0x2e, 0xbe, 0x69, 0xf6, 0xf7, 0x6e, 0x8e, 0x9c, 0x60, 0x04,
- 0xeb, 0x29, 0xfa, 0xc4, 0x47, 0x42, 0xd2, 0x78, 0x98, 0xe3, 0xec, 0x0b,
- 0xa5, 0x92, 0xdc, 0xb7, 0x9a, 0xbd, 0x80, 0x64, 0x2b, 0x38, 0x7c, 0x38,
- 0x09, 0x5b, 0x66, 0xf6, 0x2d, 0x95, 0x7a, 0x86, 0xb2, 0x34, 0x2e, 0x85,
- 0x9e, 0x90, 0x0e, 0x5f, 0xb7, 0x5d, 0xa4, 0x51, 0x72, 0x46, 0x70, 0x13,
- 0xbf, 0x67, 0xf2, 0xb6, 0xa7, 0x4d, 0x14, 0x1e, 0x6c, 0xb9, 0x53, 0xee,
- 0x23, 0x1a, 0x4e, 0x8d, 0x48, 0x55, 0x43, 0x41, 0xb1, 0x89, 0x75, 0x6a,
- 0x40, 0x28, 0xc5, 0x7d, 0xdd, 0xd2, 0x6e, 0xd2, 0x02, 0x19, 0x2f, 0x7b,
- 0x24, 0x94, 0x4b, 0xeb, 0xf1, 0x1a, 0xa9, 0x9b, 0xe3, 0x23, 0x9a, 0xea,
- 0xfa, 0x33, 0xab, 0x0a, 0x2c, 0xb7, 0xf4, 0x60, 0x08, 0xdd, 0x9f, 0x1c,
- 0xcd, 0xdd, 0x2d, 0x01, 0x66, 0x80, 0xaf, 0xb3, 0x2f, 0x29, 0x1d, 0x23,
- 0xb8, 0x8a, 0xe1, 0xa1, 0x70, 0x07, 0x0c, 0x34, 0x0f, 0x02, 0x03, 0x01,
- 0x00, 0x01, 0xa3, 0x82, 0x01, 0x5d, 0x30, 0x82, 0x01, 0x59, 0x30, 0x2f,
- 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x23,
- 0x30, 0x21, 0x30, 0x1f, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
- 0x30, 0x01, 0x86, 0x13, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x73,
- 0x32, 0x2e, 0x73, 0x79, 0x6d, 0x63, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x30,
- 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30,
- 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x00, 0x30, 0x65, 0x06, 0x03, 0x55,
- 0x1d, 0x20, 0x04, 0x5e, 0x30, 0x5c, 0x30, 0x5a, 0x06, 0x04, 0x55, 0x1d,
- 0x20, 0x00, 0x30, 0x52, 0x30, 0x26, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05,
- 0x05, 0x07, 0x02, 0x01, 0x16, 0x1a, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f,
- 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x73, 0x79, 0x6d, 0x61, 0x75, 0x74, 0x68,
- 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x70, 0x73, 0x30, 0x28, 0x06, 0x08,
- 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x02, 0x30, 0x1c, 0x1a, 0x1a,
- 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x73,
- 0x79, 0x6d, 0x61, 0x75, 0x74, 0x68, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72,
- 0x70, 0x61, 0x30, 0x30, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x29, 0x30,
- 0x27, 0x30, 0x25, 0xa0, 0x23, 0xa0, 0x21, 0x86, 0x1f, 0x68, 0x74, 0x74,
- 0x70, 0x3a, 0x2f, 0x2f, 0x73, 0x31, 0x2e, 0x73, 0x79, 0x6d, 0x63, 0x62,
- 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x63, 0x61, 0x33, 0x2d, 0x67, 0x35,
- 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01,
- 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x29, 0x06, 0x03,
- 0x55, 0x1d, 0x11, 0x04, 0x22, 0x30, 0x20, 0xa4, 0x1e, 0x30, 0x1c, 0x31,
- 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x11, 0x53, 0x79,
- 0x6d, 0x61, 0x6e, 0x74, 0x65, 0x63, 0x50, 0x4b, 0x49, 0x2d, 0x31, 0x2d,
- 0x35, 0x33, 0x33, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16,
- 0x04, 0x14, 0x01, 0x59, 0xab, 0xe7, 0xdd, 0x3a, 0x0b, 0x59, 0xa6, 0x64,
- 0x63, 0xd6, 0xcf, 0x20, 0x07, 0x57, 0xd5, 0x91, 0xe7, 0x6a, 0x30, 0x1f,
- 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x7f,
- 0xd3, 0x65, 0xa7, 0xc2, 0xdd, 0xec, 0xbb, 0xf0, 0x30, 0x09, 0xf3, 0x43,
- 0x39, 0xfa, 0x02, 0xaf, 0x33, 0x31, 0x33, 0x30, 0x0d, 0x06, 0x09, 0x2a,
- 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82,
- 0x01, 0x01, 0x00, 0x42, 0x01, 0x55, 0x7b, 0xd0, 0x16, 0x1a, 0x5d, 0x58,
- 0xe8, 0xbb, 0x9b, 0xa8, 0x4d, 0xd7, 0xf3, 0xd7, 0xeb, 0x13, 0x94, 0x86,
- 0xd6, 0x7f, 0x21, 0x0b, 0x47, 0xbc, 0x57, 0x9b, 0x92, 0x5d, 0x4f, 0x05,
- 0x9f, 0x38, 0xa4, 0x10, 0x7c, 0xcf, 0x83, 0xbe, 0x06, 0x43, 0x46, 0x8d,
- 0x08, 0xbc, 0x6a, 0xd7, 0x10, 0xa6, 0xfa, 0xab, 0xaf, 0x2f, 0x61, 0xa8,
- 0x63, 0xf2, 0x65, 0xdf, 0x7f, 0x4c, 0x88, 0x12, 0x88, 0x4f, 0xb3, 0x69,
- 0xd9, 0xff, 0x27, 0xc0, 0x0a, 0x97, 0x91, 0x8f, 0x56, 0xfb, 0x89, 0xc4,
- 0xa8, 0xbb, 0x92, 0x2d, 0x1b, 0x73, 0xb0, 0xc6, 0xab, 0x36, 0xf4, 0x96,
- 0x6c, 0x20, 0x08, 0xef, 0x0a, 0x1e, 0x66, 0x24, 0x45, 0x4f, 0x67, 0x00,
- 0x40, 0xc8, 0x07, 0x54, 0x74, 0x33, 0x3b, 0xa6, 0xad, 0xbb, 0x23, 0x9f,
- 0x66, 0xed, 0xa2, 0x44, 0x70, 0x34, 0xfb, 0x0e, 0xea, 0x01, 0xfd, 0xcf,
- 0x78, 0x74, 0xdf, 0xa7, 0xad, 0x55, 0xb7, 0x5f, 0x4d, 0xf6, 0xd6, 0x3f,
- 0xe0, 0x86, 0xce, 0x24, 0xc7, 0x42, 0xa9, 0x13, 0x14, 0x44, 0x35, 0x4b,
- 0xb6, 0xdf, 0xc9, 0x60, 0xac, 0x0c, 0x7f, 0xd9, 0x93, 0x21, 0x4b, 0xee,
- 0x9c, 0xe4, 0x49, 0x02, 0x98, 0xd3, 0x60, 0x7b, 0x5c, 0xbc, 0xd5, 0x30,
- 0x2f, 0x07, 0xce, 0x44, 0x42, 0xc4, 0x0b, 0x99, 0xfe, 0xe6, 0x9f, 0xfc,
- 0xb0, 0x78, 0x86, 0x51, 0x6d, 0xd1, 0x2c, 0x9d, 0xc6, 0x96, 0xfb, 0x85,
- 0x82, 0xbb, 0x04, 0x2f, 0xf7, 0x62, 0x80, 0xef, 0x62, 0xda, 0x7f, 0xf6,
- 0x0e, 0xac, 0x90, 0xb8, 0x56, 0xbd, 0x79, 0x3f, 0xf2, 0x80, 0x6e, 0xa3,
- 0xd9, 0xb9, 0x0f, 0x5d, 0x3a, 0x07, 0x1d, 0x91, 0x93, 0x86, 0x4b, 0x29,
- 0x4c, 0xe1, 0xdc, 0xb5, 0xe1, 0xe0, 0x33, 0x9d, 0xb3, 0xcb, 0x36, 0x91,
- 0x4b, 0xfe, 0xa1, 0xb4, 0xee, 0xf0, 0xf9,
-};
-
-#if 0
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number:
- 51:3f:b9:74:38:70:b7:34:40:41:8d:30:93:06:99:ff
- Signature Algorithm: sha256WithRSAEncryption
- Issuer: C=US, O=VeriSign, Inc., OU=VeriSign Trust Network, OU=(c) 2006 VeriSign, Inc. - For authorized use only, CN=VeriSign Class 3 Public Primary Certification Authority - G5
- Validity
- Not Before: Oct 31 00:00:00 2013 GMT
- Not After : Oct 30 23:59:59 2023 GMT
- Subject: C=US, O=Symantec Corporation, OU=Symantec Trust Network, CN=Symantec Class 3 Secure Server CA - G4
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:b2:d8:05:ca:1c:74:2d:b5:17:56:39:c5:4a:52:
- 09:96:e8:4b:d8:0c:f1:68:9f:9a:42:28:62:c3:a5:
- 30:53:7e:55:11:82:5b:03:7a:0d:2f:e1:79:04:c9:
- b4:96:77:19:81:01:94:59:f9:bc:f7:7a:99:27:82:
- 2d:b7:83:dd:5a:27:7f:b2:03:7a:9c:53:25:e9:48:
- 1f:46:4f:c8:9d:29:f8:be:79:56:f6:f7:fd:d9:3a:
- 68:da:8b:4b:82:33:41:12:c3:c8:3c:cc:d6:96:7a:
- 84:21:1a:22:04:03:27:17:8b:1c:68:61:93:0f:0e:
- 51:80:33:1d:b4:b5:ce:eb:7e:d0:62:ac:ee:b3:7b:
- 01:74:ef:69:35:eb:ca:d5:3d:a9:ee:97:98:ca:8d:
- aa:44:0e:25:99:4a:15:96:a4:ce:6d:02:54:1f:2a:
- 6a:26:e2:06:3a:63:48:ac:b4:4c:d1:75:93:50:ff:
- 13:2f:d6:da:e1:c6:18:f5:9f:c9:25:5d:f3:00:3a:
- de:26:4d:b4:29:09:cd:0f:3d:23:6f:16:4a:81:16:
- fb:f2:83:10:c3:b8:d6:d8:55:32:3d:f1:bd:0f:bd:
- 8c:52:95:4a:16:97:7a:52:21:63:75:2f:16:f9:c4:
- 66:be:f5:b5:09:d8:ff:27:00:cd:44:7c:6f:4b:3f:
- b0:f7
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Basic Constraints: critical
- CA:TRUE, pathlen:0
- X509v3 CRL Distribution Points:
-
- Full Name:
- URI:http://s1.symcb.com/pca3-g5.crl
-
- X509v3 Key Usage: critical
- Certificate Sign, CRL Sign
- Authority Information Access:
- OCSP - URI:http://s2.symcb.com
-
- X509v3 Certificate Policies:
- Policy: 2.16.840.1.113733.1.7.54
- CPS: http://www.symauth.com/cps
- User Notice:
- Explicit Text: http://www.symauth.com/rpa
-
- X509v3 Subject Alternative Name:
- DirName:/CN=SymantecPKI-1-534
- X509v3 Subject Key Identifier:
- 5F:60:CF:61:90:55:DF:84:43:14:8A:60:2A:B2:F5:7A:F4:43:18:EF
- X509v3 Authority Key Identifier:
- keyid:7F:D3:65:A7:C2:DD:EC:BB:F0:30:09:F3:43:39:FA:02:AF:33:31:33
-
- Signature Algorithm: sha256WithRSAEncryption
- 5e:94:56:49:dd:8e:2d:65:f5:c1:36:51:b6:03:e3:da:9e:73:
- 19:f2:1f:59:ab:58:7e:6c:26:05:2c:fa:81:d7:5c:23:17:22:
- 2c:37:93:f7:86:ec:85:e6:b0:a3:fd:1f:e2:32:a8:45:6f:e1:
- d9:fb:b9:af:d2:70:a0:32:42:65:bf:84:fe:16:2a:8f:3f:c5:
- a6:d6:a3:93:7d:43:e9:74:21:91:35:28:f4:63:e9:2e:ed:f7:
- f5:5c:7f:4b:9a:b5:20:e9:0a:bd:e0:45:10:0c:14:94:9a:5d:
- a5:e3:4b:91:e8:24:9b:46:40:65:f4:22:72:cd:99:f8:88:11:
- f5:f3:7f:e6:33:82:e6:a8:c5:7e:fe:d0:08:e2:25:58:08:71:
- 68:e6:cd:a2:e6:14:de:4e:52:24:2d:fd:e5:79:13:53:e7:5e:
- 2f:2d:4d:1b:6d:40:15:52:2b:f7:87:89:78:12:81:6e:d9:4d:
- aa:2d:78:d4:c2:2c:3d:08:5f:87:91:9e:1f:0e:b0:de:30:52:
- 64:86:89:aa:9d:66:9c:0e:76:0c:80:f2:74:d8:2a:f8:b8:3a:
- ce:d7:d6:0f:11:be:6b:ab:14:f5:bd:41:a0:22:63:89:f1:ba:
- 0f:6f:29:63:66:2d:3f:ac:8c:72:c5:fb:c7:e4:d4:0f:f2:3b:
- 4f:8c:29:c7
------BEGIN CERTIFICATE-----
-MIIFODCCBCCgAwIBAgIQUT+5dDhwtzRAQY0wkwaZ/zANBgkqhkiG9w0BAQsFADCB
-yjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL
-ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJp
-U2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxW
-ZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0
-aG9yaXR5IC0gRzUwHhcNMTMxMDMxMDAwMDAwWhcNMjMxMDMwMjM1OTU5WjB+MQsw
-CQYDVQQGEwJVUzEdMBsGA1UEChMUU3ltYW50ZWMgQ29ycG9yYXRpb24xHzAdBgNV
-BAsTFlN5bWFudGVjIFRydXN0IE5ldHdvcmsxLzAtBgNVBAMTJlN5bWFudGVjIENs
-YXNzIDMgU2VjdXJlIFNlcnZlciBDQSAtIEc0MIIBIjANBgkqhkiG9w0BAQEFAAOC
-AQ8AMIIBCgKCAQEAstgFyhx0LbUXVjnFSlIJluhL2AzxaJ+aQihiw6UwU35VEYJb
-A3oNL+F5BMm0lncZgQGUWfm893qZJ4Itt4PdWid/sgN6nFMl6UgfRk/InSn4vnlW
-9vf92Tpo2otLgjNBEsPIPMzWlnqEIRoiBAMnF4scaGGTDw5RgDMdtLXO637QYqzu
-s3sBdO9pNevK1T2p7peYyo2qRA4lmUoVlqTObQJUHypqJuIGOmNIrLRM0XWTUP8T
-L9ba4cYY9Z/JJV3zADreJk20KQnNDz0jbxZKgRb78oMQw7jW2FUyPfG9D72MUpVK
-Fpd6UiFjdS8W+cRmvvW1Cdj/JwDNRHxvSz+w9wIDAQABo4IBYzCCAV8wEgYDVR0T
-AQH/BAgwBgEB/wIBADAwBgNVHR8EKTAnMCWgI6Ahhh9odHRwOi8vczEuc3ltY2Iu
-Y29tL3BjYTMtZzUuY3JsMA4GA1UdDwEB/wQEAwIBBjAvBggrBgEFBQcBAQQjMCEw
-HwYIKwYBBQUHMAGGE2h0dHA6Ly9zMi5zeW1jYi5jb20wawYDVR0gBGQwYjBgBgpg
-hkgBhvhFAQc2MFIwJgYIKwYBBQUHAgEWGmh0dHA6Ly93d3cuc3ltYXV0aC5jb20v
-Y3BzMCgGCCsGAQUFBwICMBwaGmh0dHA6Ly93d3cuc3ltYXV0aC5jb20vcnBhMCkG
-A1UdEQQiMCCkHjAcMRowGAYDVQQDExFTeW1hbnRlY1BLSS0xLTUzNDAdBgNVHQ4E
-FgQUX2DPYZBV34RDFIpgKrL1evRDGO8wHwYDVR0jBBgwFoAUf9Nlp8Ld7LvwMAnz
-Qzn6Aq8zMTMwDQYJKoZIhvcNAQELBQADggEBAF6UVkndji1l9cE2UbYD49qecxny
-H1mrWH5sJgUs+oHXXCMXIiw3k/eG7IXmsKP9H+IyqEVv4dn7ua/ScKAyQmW/hP4W
-Ko8/xabWo5N9Q+l0IZE1KPRj6S7t9/Vcf0uatSDpCr3gRRAMFJSaXaXjS5HoJJtG
-QGX0InLNmfiIEfXzf+YzguaoxX7+0AjiJVgIcWjmzaLmFN5OUiQt/eV5E1PnXi8t
-TRttQBVSK/eHiXgSgW7ZTaoteNTCLD0IX4eRnh8OsN4wUmSGiaqdZpwOdgyA8nTY
-Kvi4Os7X1g8RvmurFPW9QaAiY4nxug9vKWNmLT+sjHLF+8fk1A/yO0+MKcc=
------END CERTIFICATE-----
-#endif
-static const unsigned char kDERCert45[] = {
- 0x30, 0x82, 0x05, 0x38, 0x30, 0x82, 0x04, 0x20, 0xa0, 0x03, 0x02, 0x01,
- 0x02, 0x02, 0x10, 0x51, 0x3f, 0xb9, 0x74, 0x38, 0x70, 0xb7, 0x34, 0x40,
- 0x41, 0x8d, 0x30, 0x93, 0x06, 0x99, 0xff, 0x30, 0x0d, 0x06, 0x09, 0x2a,
- 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x81,
- 0xca, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
- 0x55, 0x53, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13,
- 0x0e, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49,
- 0x6e, 0x63, 0x2e, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x0b,
- 0x13, 0x16, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x54,
- 0x72, 0x75, 0x73, 0x74, 0x20, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b,
- 0x31, 0x3a, 0x30, 0x38, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x31, 0x28,
- 0x63, 0x29, 0x20, 0x32, 0x30, 0x30, 0x36, 0x20, 0x56, 0x65, 0x72, 0x69,
- 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x20, 0x2d,
- 0x20, 0x46, 0x6f, 0x72, 0x20, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69,
- 0x7a, 0x65, 0x64, 0x20, 0x75, 0x73, 0x65, 0x20, 0x6f, 0x6e, 0x6c, 0x79,
- 0x31, 0x45, 0x30, 0x43, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x3c, 0x56,
- 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x43, 0x6c, 0x61, 0x73,
- 0x73, 0x20, 0x33, 0x20, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x20, 0x50,
- 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69,
- 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74,
- 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x20, 0x2d, 0x20, 0x47, 0x35, 0x30,
- 0x1e, 0x17, 0x0d, 0x31, 0x33, 0x31, 0x30, 0x33, 0x31, 0x30, 0x30, 0x30,
- 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x33, 0x31, 0x30, 0x33, 0x30,
- 0x32, 0x33, 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x7e, 0x31, 0x0b, 0x30,
- 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x1d,
- 0x30, 0x1b, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x14, 0x53, 0x79, 0x6d,
- 0x61, 0x6e, 0x74, 0x65, 0x63, 0x20, 0x43, 0x6f, 0x72, 0x70, 0x6f, 0x72,
- 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55,
- 0x04, 0x0b, 0x13, 0x16, 0x53, 0x79, 0x6d, 0x61, 0x6e, 0x74, 0x65, 0x63,
- 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x4e, 0x65, 0x74, 0x77, 0x6f,
- 0x72, 0x6b, 0x31, 0x2f, 0x30, 0x2d, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
- 0x26, 0x53, 0x79, 0x6d, 0x61, 0x6e, 0x74, 0x65, 0x63, 0x20, 0x43, 0x6c,
- 0x61, 0x73, 0x73, 0x20, 0x33, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65,
- 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x43, 0x41, 0x20, 0x2d,
- 0x20, 0x47, 0x34, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a,
- 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82,
- 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00,
- 0xb2, 0xd8, 0x05, 0xca, 0x1c, 0x74, 0x2d, 0xb5, 0x17, 0x56, 0x39, 0xc5,
- 0x4a, 0x52, 0x09, 0x96, 0xe8, 0x4b, 0xd8, 0x0c, 0xf1, 0x68, 0x9f, 0x9a,
- 0x42, 0x28, 0x62, 0xc3, 0xa5, 0x30, 0x53, 0x7e, 0x55, 0x11, 0x82, 0x5b,
- 0x03, 0x7a, 0x0d, 0x2f, 0xe1, 0x79, 0x04, 0xc9, 0xb4, 0x96, 0x77, 0x19,
- 0x81, 0x01, 0x94, 0x59, 0xf9, 0xbc, 0xf7, 0x7a, 0x99, 0x27, 0x82, 0x2d,
- 0xb7, 0x83, 0xdd, 0x5a, 0x27, 0x7f, 0xb2, 0x03, 0x7a, 0x9c, 0x53, 0x25,
- 0xe9, 0x48, 0x1f, 0x46, 0x4f, 0xc8, 0x9d, 0x29, 0xf8, 0xbe, 0x79, 0x56,
- 0xf6, 0xf7, 0xfd, 0xd9, 0x3a, 0x68, 0xda, 0x8b, 0x4b, 0x82, 0x33, 0x41,
- 0x12, 0xc3, 0xc8, 0x3c, 0xcc, 0xd6, 0x96, 0x7a, 0x84, 0x21, 0x1a, 0x22,
- 0x04, 0x03, 0x27, 0x17, 0x8b, 0x1c, 0x68, 0x61, 0x93, 0x0f, 0x0e, 0x51,
- 0x80, 0x33, 0x1d, 0xb4, 0xb5, 0xce, 0xeb, 0x7e, 0xd0, 0x62, 0xac, 0xee,
- 0xb3, 0x7b, 0x01, 0x74, 0xef, 0x69, 0x35, 0xeb, 0xca, 0xd5, 0x3d, 0xa9,
- 0xee, 0x97, 0x98, 0xca, 0x8d, 0xaa, 0x44, 0x0e, 0x25, 0x99, 0x4a, 0x15,
- 0x96, 0xa4, 0xce, 0x6d, 0x02, 0x54, 0x1f, 0x2a, 0x6a, 0x26, 0xe2, 0x06,
- 0x3a, 0x63, 0x48, 0xac, 0xb4, 0x4c, 0xd1, 0x75, 0x93, 0x50, 0xff, 0x13,
- 0x2f, 0xd6, 0xda, 0xe1, 0xc6, 0x18, 0xf5, 0x9f, 0xc9, 0x25, 0x5d, 0xf3,
- 0x00, 0x3a, 0xde, 0x26, 0x4d, 0xb4, 0x29, 0x09, 0xcd, 0x0f, 0x3d, 0x23,
- 0x6f, 0x16, 0x4a, 0x81, 0x16, 0xfb, 0xf2, 0x83, 0x10, 0xc3, 0xb8, 0xd6,
- 0xd8, 0x55, 0x32, 0x3d, 0xf1, 0xbd, 0x0f, 0xbd, 0x8c, 0x52, 0x95, 0x4a,
- 0x16, 0x97, 0x7a, 0x52, 0x21, 0x63, 0x75, 0x2f, 0x16, 0xf9, 0xc4, 0x66,
- 0xbe, 0xf5, 0xb5, 0x09, 0xd8, 0xff, 0x27, 0x00, 0xcd, 0x44, 0x7c, 0x6f,
- 0x4b, 0x3f, 0xb0, 0xf7, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01,
- 0x63, 0x30, 0x82, 0x01, 0x5f, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13,
- 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01,
- 0x00, 0x30, 0x30, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x29, 0x30, 0x27,
- 0x30, 0x25, 0xa0, 0x23, 0xa0, 0x21, 0x86, 0x1f, 0x68, 0x74, 0x74, 0x70,
- 0x3a, 0x2f, 0x2f, 0x73, 0x31, 0x2e, 0x73, 0x79, 0x6d, 0x63, 0x62, 0x2e,
- 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x63, 0x61, 0x33, 0x2d, 0x67, 0x35, 0x2e,
- 0x63, 0x72, 0x6c, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01,
- 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x2f, 0x06, 0x08, 0x2b,
- 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x23, 0x30, 0x21, 0x30,
- 0x1f, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86,
- 0x13, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x73, 0x32, 0x2e, 0x73,
- 0x79, 0x6d, 0x63, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x6b, 0x06, 0x03,
- 0x55, 0x1d, 0x20, 0x04, 0x64, 0x30, 0x62, 0x30, 0x60, 0x06, 0x0a, 0x60,
- 0x86, 0x48, 0x01, 0x86, 0xf8, 0x45, 0x01, 0x07, 0x36, 0x30, 0x52, 0x30,
- 0x26, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16,
- 0x1a, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e,
- 0x73, 0x79, 0x6d, 0x61, 0x75, 0x74, 0x68, 0x2e, 0x63, 0x6f, 0x6d, 0x2f,
- 0x63, 0x70, 0x73, 0x30, 0x28, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05,
- 0x07, 0x02, 0x02, 0x30, 0x1c, 0x1a, 0x1a, 0x68, 0x74, 0x74, 0x70, 0x3a,
- 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x73, 0x79, 0x6d, 0x61, 0x75, 0x74,
- 0x68, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x70, 0x61, 0x30, 0x29, 0x06,
- 0x03, 0x55, 0x1d, 0x11, 0x04, 0x22, 0x30, 0x20, 0xa4, 0x1e, 0x30, 0x1c,
- 0x31, 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x11, 0x53,
- 0x79, 0x6d, 0x61, 0x6e, 0x74, 0x65, 0x63, 0x50, 0x4b, 0x49, 0x2d, 0x31,
- 0x2d, 0x35, 0x33, 0x34, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04,
- 0x16, 0x04, 0x14, 0x5f, 0x60, 0xcf, 0x61, 0x90, 0x55, 0xdf, 0x84, 0x43,
- 0x14, 0x8a, 0x60, 0x2a, 0xb2, 0xf5, 0x7a, 0xf4, 0x43, 0x18, 0xef, 0x30,
- 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14,
- 0x7f, 0xd3, 0x65, 0xa7, 0xc2, 0xdd, 0xec, 0xbb, 0xf0, 0x30, 0x09, 0xf3,
- 0x43, 0x39, 0xfa, 0x02, 0xaf, 0x33, 0x31, 0x33, 0x30, 0x0d, 0x06, 0x09,
- 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03,
- 0x82, 0x01, 0x01, 0x00, 0x5e, 0x94, 0x56, 0x49, 0xdd, 0x8e, 0x2d, 0x65,
- 0xf5, 0xc1, 0x36, 0x51, 0xb6, 0x03, 0xe3, 0xda, 0x9e, 0x73, 0x19, 0xf2,
- 0x1f, 0x59, 0xab, 0x58, 0x7e, 0x6c, 0x26, 0x05, 0x2c, 0xfa, 0x81, 0xd7,
- 0x5c, 0x23, 0x17, 0x22, 0x2c, 0x37, 0x93, 0xf7, 0x86, 0xec, 0x85, 0xe6,
- 0xb0, 0xa3, 0xfd, 0x1f, 0xe2, 0x32, 0xa8, 0x45, 0x6f, 0xe1, 0xd9, 0xfb,
- 0xb9, 0xaf, 0xd2, 0x70, 0xa0, 0x32, 0x42, 0x65, 0xbf, 0x84, 0xfe, 0x16,
- 0x2a, 0x8f, 0x3f, 0xc5, 0xa6, 0xd6, 0xa3, 0x93, 0x7d, 0x43, 0xe9, 0x74,
- 0x21, 0x91, 0x35, 0x28, 0xf4, 0x63, 0xe9, 0x2e, 0xed, 0xf7, 0xf5, 0x5c,
- 0x7f, 0x4b, 0x9a, 0xb5, 0x20, 0xe9, 0x0a, 0xbd, 0xe0, 0x45, 0x10, 0x0c,
- 0x14, 0x94, 0x9a, 0x5d, 0xa5, 0xe3, 0x4b, 0x91, 0xe8, 0x24, 0x9b, 0x46,
- 0x40, 0x65, 0xf4, 0x22, 0x72, 0xcd, 0x99, 0xf8, 0x88, 0x11, 0xf5, 0xf3,
- 0x7f, 0xe6, 0x33, 0x82, 0xe6, 0xa8, 0xc5, 0x7e, 0xfe, 0xd0, 0x08, 0xe2,
- 0x25, 0x58, 0x08, 0x71, 0x68, 0xe6, 0xcd, 0xa2, 0xe6, 0x14, 0xde, 0x4e,
- 0x52, 0x24, 0x2d, 0xfd, 0xe5, 0x79, 0x13, 0x53, 0xe7, 0x5e, 0x2f, 0x2d,
- 0x4d, 0x1b, 0x6d, 0x40, 0x15, 0x52, 0x2b, 0xf7, 0x87, 0x89, 0x78, 0x12,
- 0x81, 0x6e, 0xd9, 0x4d, 0xaa, 0x2d, 0x78, 0xd4, 0xc2, 0x2c, 0x3d, 0x08,
- 0x5f, 0x87, 0x91, 0x9e, 0x1f, 0x0e, 0xb0, 0xde, 0x30, 0x52, 0x64, 0x86,
- 0x89, 0xaa, 0x9d, 0x66, 0x9c, 0x0e, 0x76, 0x0c, 0x80, 0xf2, 0x74, 0xd8,
- 0x2a, 0xf8, 0xb8, 0x3a, 0xce, 0xd7, 0xd6, 0x0f, 0x11, 0xbe, 0x6b, 0xab,
- 0x14, 0xf5, 0xbd, 0x41, 0xa0, 0x22, 0x63, 0x89, 0xf1, 0xba, 0x0f, 0x6f,
- 0x29, 0x63, 0x66, 0x2d, 0x3f, 0xac, 0x8c, 0x72, 0xc5, 0xfb, 0xc7, 0xe4,
- 0xd4, 0x0f, 0xf2, 0x3b, 0x4f, 0x8c, 0x29, 0xc7,
-};
-
-#if 0
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number:
- 69:87:94:19:d9:e3:62:70:74:9d:bb:e5:9d:c6:68:5e
- Signature Algorithm: sha256WithRSAEncryption
- Issuer: C=US, O=VeriSign, Inc., OU=VeriSign Trust Network, OU=(c) 2008 VeriSign, Inc. - For authorized use only, CN=VeriSign Universal Root Certification Authority
- Validity
- Not Before: Apr 9 00:00:00 2013 GMT
- Not After : Apr 8 23:59:59 2023 GMT
- Subject: C=US, O=Symantec Corporation, OU=Symantec Trust Network, CN=Symantec Class 3 Secure Server SHA256 SSL CA
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:be:38:16:51:8b:80:db:ea:0e:4d:ec:e8:3f:5c:
- c4:7c:a2:5d:ed:3b:af:a5:d6:9e:10:35:2c:e3:c5:
- e5:a8:de:8c:86:17:26:e6:de:0b:51:4a:2c:d0:fb:
- d1:14:5a:72:f7:c9:dd:b8:83:1c:c6:46:8c:31:25:
- 91:0e:59:17:a3:d0:13:8c:92:c1:af:81:54:4e:bc:
- 62:02:9e:aa:a7:1a:57:d8:ca:a6:99:7a:70:56:4f:
- 98:07:2e:4b:96:d0:4c:39:53:b9:61:2f:3b:76:7c:
- 8e:05:9e:99:44:d1:03:54:77:29:2b:56:2a:aa:61:
- e4:84:2f:12:15:3c:bd:d7:8a:e8:09:1e:56:f1:b5:
- 14:ac:8a:84:ce:ae:78:a2:60:0a:53:7e:13:4c:1a:
- 40:70:0e:52:59:ff:5a:68:2e:4c:46:13:3b:39:09:
- 82:78:02:35:49:20:08:82:b3:b1:6c:89:0f:6e:1e:
- 35:25:b0:2c:24:83:e3:c5:50:2c:ba:46:90:45:87:
- 0d:72:ff:5d:11:38:c5:91:76:c5:2c:fb:05:2a:82:
- 95:a1:59:63:e3:d0:26:58:cd:67:56:3a:ba:df:7c:
- d2:d2:3b:d8:de:1a:7a:77:e4:0c:8c:0b:eb:2b:c2:
- 22:b0:bd:55:ba:d9:b9:55:d1:22:7a:c6:02:4e:3f:
- c3:35
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Basic Constraints: critical
- CA:TRUE, pathlen:0
- X509v3 CRL Distribution Points:
-
- Full Name:
- URI:http://crl.ws.symantec.com/universal-root.crl
-
- X509v3 Key Usage: critical
- Certificate Sign, CRL Sign
- Authority Information Access:
- OCSP - URI:http://ocsp.ws.symantec.com
-
- X509v3 Certificate Policies:
- Policy: 2.16.840.1.113733.1.7.54
- CPS: http://www.symauth.com/cps
- User Notice:
- Explicit Text: http://www.symauth.com/rpa
-
- X509v3 Subject Alternative Name:
- DirName:/CN=VeriSignMPKI-2-373
- X509v3 Subject Key Identifier:
- DB:62:20:FB:7D:02:89:7C:D2:3B:6F:C7:E4:32:6C:05:52:1D:AD:B1
- X509v3 Authority Key Identifier:
- keyid:B6:77:FA:69:48:47:9F:53:12:D5:C2:EA:07:32:76:07:D1:97:07:19
-
- Signature Algorithm: sha256WithRSAEncryption
- 19:cc:95:e2:2f:7b:49:d0:48:90:53:f4:07:b1:20:44:35:70:
- 14:d5:44:37:31:ef:ef:70:d1:2d:4c:e9:2d:b0:53:91:01:4c:
- 54:e7:7d:9b:da:3a:ff:b7:cb:14:ad:30:0f:69:1a:2a:f0:bc:
- cd:35:eb:48:dc:b9:87:fd:cf:b1:5a:f6:05:da:3c:64:e6:2b:
- e6:dc:73:5e:9a:d8:0c:9b:d2:97:b3:e8:fa:87:95:53:e1:99:
- ad:88:e8:fa:bc:09:4d:a2:c4:6a:1b:28:3b:2d:c3:21:15:ee:
- 14:fa:9d:98:10:eb:9f:3e:e6:24:24:5f:7a:1c:05:bb:9a:31:
- 23:58:79:4c:ec:6d:18:19:4d:51:1f:08:61:bd:91:05:0c:5a:
- 9c:26:fc:0b:a5:20:25:bf:6a:1b:2b:f7:02:09:72:69:83:32:
- 14:c3:60:5b:7e:fd:9a:32:fa:b4:95:0e:1a:f9:3b:09:a4:54:
- 47:9a:0c:ce:32:af:d1:21:cc:7f:d2:06:ef:60:0e:62:6f:6f:
- 81:1a:17:9d:c8:cb:28:cc:e2:5f:6e:2c:7a:b4:cb:47:7c:74:
- 68:7b:48:71:02:9c:23:09:f3:5a:ae:5f:42:2e:5f:2b:59:2d:
- 52:88:e5:8d:0b:b3:a8:61:f9:4b:9b:55:d6:da:b1:92:3b:bf:
- c3:9b:f9:2c
------BEGIN CERTIFICATE-----
-MIIFSTCCBDGgAwIBAgIQaYeUGdnjYnB0nbvlncZoXjANBgkqhkiG9w0BAQsFADCB
-vTELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL
-ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwOCBWZXJp
-U2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MTgwNgYDVQQDEy9W
-ZXJpU2lnbiBVbml2ZXJzYWwgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAe
-Fw0xMzA0MDkwMDAwMDBaFw0yMzA0MDgyMzU5NTlaMIGEMQswCQYDVQQGEwJVUzEd
-MBsGA1UEChMUU3ltYW50ZWMgQ29ycG9yYXRpb24xHzAdBgNVBAsTFlN5bWFudGVj
-IFRydXN0IE5ldHdvcmsxNTAzBgNVBAMTLFN5bWFudGVjIENsYXNzIDMgU2VjdXJl
-IFNlcnZlciBTSEEyNTYgU1NMIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
-CgKCAQEAvjgWUYuA2+oOTezoP1zEfKJd7TuvpdaeEDUs48XlqN6Mhhcm5t4LUUos
-0PvRFFpy98nduIMcxkaMMSWRDlkXo9ATjJLBr4FUTrxiAp6qpxpX2MqmmXpwVk+Y
-By5LltBMOVO5YS87dnyOBZ6ZRNEDVHcpK1YqqmHkhC8SFTy914roCR5W8bUUrIqE
-zq54omAKU34TTBpAcA5SWf9aaC5MRhM7OQmCeAI1SSAIgrOxbIkPbh41JbAsJIPj
-xVAsukaQRYcNcv9dETjFkXbFLPsFKoKVoVlj49AmWM1nVjq633zS0jvY3hp6d+QM
-jAvrK8IisL1Vutm5VdEiesYCTj/DNQIDAQABo4IBejCCAXYwEgYDVR0TAQH/BAgw
-BgEB/wIBADA+BgNVHR8ENzA1MDOgMaAvhi1odHRwOi8vY3JsLndzLnN5bWFudGVj
-LmNvbS91bml2ZXJzYWwtcm9vdC5jcmwwDgYDVR0PAQH/BAQDAgEGMDcGCCsGAQUF
-BwEBBCswKTAnBggrBgEFBQcwAYYbaHR0cDovL29jc3Aud3Muc3ltYW50ZWMuY29t
-MGsGA1UdIARkMGIwYAYKYIZIAYb4RQEHNjBSMCYGCCsGAQUFBwIBFhpodHRwOi8v
-d3d3LnN5bWF1dGguY29tL2NwczAoBggrBgEFBQcCAjAcGhpodHRwOi8vd3d3LnN5
-bWF1dGguY29tL3JwYTAqBgNVHREEIzAhpB8wHTEbMBkGA1UEAxMSVmVyaVNpZ25N
-UEtJLTItMzczMB0GA1UdDgQWBBTbYiD7fQKJfNI7b8fkMmwFUh2tsTAfBgNVHSME
-GDAWgBS2d/ppSEefUxLVwuoHMnYH0ZcHGTANBgkqhkiG9w0BAQsFAAOCAQEAGcyV
-4i97SdBIkFP0B7EgRDVwFNVENzHv73DRLUzpLbBTkQFMVOd9m9o6/7fLFK0wD2ka
-KvC8zTXrSNy5h/3PsVr2Bdo8ZOYr5txzXprYDJvSl7Po+oeVU+GZrYjo+rwJTaLE
-ahsoOy3DIRXuFPqdmBDrnz7mJCRfehwFu5oxI1h5TOxtGBlNUR8IYb2RBQxanCb8
-C6UgJb9qGyv3AglyaYMyFMNgW379mjL6tJUOGvk7CaRUR5oMzjKv0SHMf9IG72AO
-Ym9vgRoXncjLKMziX24serTLR3x0aHtIcQKcIwnzWq5fQi5fK1ktUojljQuzqGH5
-S5tV1tqxkju/w5v5LA==
------END CERTIFICATE-----
-#endif
-static const unsigned char kDERCert46[] = {
- 0x30, 0x82, 0x05, 0x49, 0x30, 0x82, 0x04, 0x31, 0xa0, 0x03, 0x02, 0x01,
- 0x02, 0x02, 0x10, 0x69, 0x87, 0x94, 0x19, 0xd9, 0xe3, 0x62, 0x70, 0x74,
- 0x9d, 0xbb, 0xe5, 0x9d, 0xc6, 0x68, 0x5e, 0x30, 0x0d, 0x06, 0x09, 0x2a,
- 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x81,
- 0xbd, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
- 0x55, 0x53, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13,
- 0x0e, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49,
- 0x6e, 0x63, 0x2e, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x0b,
- 0x13, 0x16, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x54,
- 0x72, 0x75, 0x73, 0x74, 0x20, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b,
- 0x31, 0x3a, 0x30, 0x38, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x31, 0x28,
- 0x63, 0x29, 0x20, 0x32, 0x30, 0x30, 0x38, 0x20, 0x56, 0x65, 0x72, 0x69,
- 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x20, 0x2d,
- 0x20, 0x46, 0x6f, 0x72, 0x20, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69,
- 0x7a, 0x65, 0x64, 0x20, 0x75, 0x73, 0x65, 0x20, 0x6f, 0x6e, 0x6c, 0x79,
- 0x31, 0x38, 0x30, 0x36, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x2f, 0x56,
- 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x55, 0x6e, 0x69, 0x76,
- 0x65, 0x72, 0x73, 0x61, 0x6c, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43,
- 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e,
- 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x30, 0x1e,
- 0x17, 0x0d, 0x31, 0x33, 0x30, 0x34, 0x30, 0x39, 0x30, 0x30, 0x30, 0x30,
- 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x33, 0x30, 0x34, 0x30, 0x38, 0x32,
- 0x33, 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x81, 0x84, 0x31, 0x0b, 0x30,
- 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x1d,
- 0x30, 0x1b, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x14, 0x53, 0x79, 0x6d,
- 0x61, 0x6e, 0x74, 0x65, 0x63, 0x20, 0x43, 0x6f, 0x72, 0x70, 0x6f, 0x72,
- 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55,
- 0x04, 0x0b, 0x13, 0x16, 0x53, 0x79, 0x6d, 0x61, 0x6e, 0x74, 0x65, 0x63,
- 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x4e, 0x65, 0x74, 0x77, 0x6f,
- 0x72, 0x6b, 0x31, 0x35, 0x30, 0x33, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
- 0x2c, 0x53, 0x79, 0x6d, 0x61, 0x6e, 0x74, 0x65, 0x63, 0x20, 0x43, 0x6c,
- 0x61, 0x73, 0x73, 0x20, 0x33, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65,
- 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x53, 0x48, 0x41, 0x32,
- 0x35, 0x36, 0x20, 0x53, 0x53, 0x4c, 0x20, 0x43, 0x41, 0x30, 0x82, 0x01,
- 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
- 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01,
- 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xbe, 0x38, 0x16, 0x51, 0x8b, 0x80,
- 0xdb, 0xea, 0x0e, 0x4d, 0xec, 0xe8, 0x3f, 0x5c, 0xc4, 0x7c, 0xa2, 0x5d,
- 0xed, 0x3b, 0xaf, 0xa5, 0xd6, 0x9e, 0x10, 0x35, 0x2c, 0xe3, 0xc5, 0xe5,
- 0xa8, 0xde, 0x8c, 0x86, 0x17, 0x26, 0xe6, 0xde, 0x0b, 0x51, 0x4a, 0x2c,
- 0xd0, 0xfb, 0xd1, 0x14, 0x5a, 0x72, 0xf7, 0xc9, 0xdd, 0xb8, 0x83, 0x1c,
- 0xc6, 0x46, 0x8c, 0x31, 0x25, 0x91, 0x0e, 0x59, 0x17, 0xa3, 0xd0, 0x13,
- 0x8c, 0x92, 0xc1, 0xaf, 0x81, 0x54, 0x4e, 0xbc, 0x62, 0x02, 0x9e, 0xaa,
- 0xa7, 0x1a, 0x57, 0xd8, 0xca, 0xa6, 0x99, 0x7a, 0x70, 0x56, 0x4f, 0x98,
- 0x07, 0x2e, 0x4b, 0x96, 0xd0, 0x4c, 0x39, 0x53, 0xb9, 0x61, 0x2f, 0x3b,
- 0x76, 0x7c, 0x8e, 0x05, 0x9e, 0x99, 0x44, 0xd1, 0x03, 0x54, 0x77, 0x29,
- 0x2b, 0x56, 0x2a, 0xaa, 0x61, 0xe4, 0x84, 0x2f, 0x12, 0x15, 0x3c, 0xbd,
- 0xd7, 0x8a, 0xe8, 0x09, 0x1e, 0x56, 0xf1, 0xb5, 0x14, 0xac, 0x8a, 0x84,
- 0xce, 0xae, 0x78, 0xa2, 0x60, 0x0a, 0x53, 0x7e, 0x13, 0x4c, 0x1a, 0x40,
- 0x70, 0x0e, 0x52, 0x59, 0xff, 0x5a, 0x68, 0x2e, 0x4c, 0x46, 0x13, 0x3b,
- 0x39, 0x09, 0x82, 0x78, 0x02, 0x35, 0x49, 0x20, 0x08, 0x82, 0xb3, 0xb1,
- 0x6c, 0x89, 0x0f, 0x6e, 0x1e, 0x35, 0x25, 0xb0, 0x2c, 0x24, 0x83, 0xe3,
- 0xc5, 0x50, 0x2c, 0xba, 0x46, 0x90, 0x45, 0x87, 0x0d, 0x72, 0xff, 0x5d,
- 0x11, 0x38, 0xc5, 0x91, 0x76, 0xc5, 0x2c, 0xfb, 0x05, 0x2a, 0x82, 0x95,
- 0xa1, 0x59, 0x63, 0xe3, 0xd0, 0x26, 0x58, 0xcd, 0x67, 0x56, 0x3a, 0xba,
- 0xdf, 0x7c, 0xd2, 0xd2, 0x3b, 0xd8, 0xde, 0x1a, 0x7a, 0x77, 0xe4, 0x0c,
- 0x8c, 0x0b, 0xeb, 0x2b, 0xc2, 0x22, 0xb0, 0xbd, 0x55, 0xba, 0xd9, 0xb9,
- 0x55, 0xd1, 0x22, 0x7a, 0xc6, 0x02, 0x4e, 0x3f, 0xc3, 0x35, 0x02, 0x03,
- 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x7a, 0x30, 0x82, 0x01, 0x76, 0x30,
- 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30,
- 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x00, 0x30, 0x3e, 0x06, 0x03, 0x55,
- 0x1d, 0x1f, 0x04, 0x37, 0x30, 0x35, 0x30, 0x33, 0xa0, 0x31, 0xa0, 0x2f,
- 0x86, 0x2d, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c,
- 0x2e, 0x77, 0x73, 0x2e, 0x73, 0x79, 0x6d, 0x61, 0x6e, 0x74, 0x65, 0x63,
- 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73,
- 0x61, 0x6c, 0x2d, 0x72, 0x6f, 0x6f, 0x74, 0x2e, 0x63, 0x72, 0x6c, 0x30,
- 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03,
- 0x02, 0x01, 0x06, 0x30, 0x37, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05,
- 0x07, 0x01, 0x01, 0x04, 0x2b, 0x30, 0x29, 0x30, 0x27, 0x06, 0x08, 0x2b,
- 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x1b, 0x68, 0x74, 0x74,
- 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x77, 0x73, 0x2e,
- 0x73, 0x79, 0x6d, 0x61, 0x6e, 0x74, 0x65, 0x63, 0x2e, 0x63, 0x6f, 0x6d,
- 0x30, 0x6b, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x64, 0x30, 0x62, 0x30,
- 0x60, 0x06, 0x0a, 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x45, 0x01, 0x07,
- 0x36, 0x30, 0x52, 0x30, 0x26, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05,
- 0x07, 0x02, 0x01, 0x16, 0x1a, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f,
- 0x77, 0x77, 0x77, 0x2e, 0x73, 0x79, 0x6d, 0x61, 0x75, 0x74, 0x68, 0x2e,
- 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x70, 0x73, 0x30, 0x28, 0x06, 0x08, 0x2b,
- 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x02, 0x30, 0x1c, 0x1a, 0x1a, 0x68,
- 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x73, 0x79,
- 0x6d, 0x61, 0x75, 0x74, 0x68, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x70,
- 0x61, 0x30, 0x2a, 0x06, 0x03, 0x55, 0x1d, 0x11, 0x04, 0x23, 0x30, 0x21,
- 0xa4, 0x1f, 0x30, 0x1d, 0x31, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04,
- 0x03, 0x13, 0x12, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x4d,
- 0x50, 0x4b, 0x49, 0x2d, 0x32, 0x2d, 0x33, 0x37, 0x33, 0x30, 0x1d, 0x06,
- 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xdb, 0x62, 0x20, 0xfb,
- 0x7d, 0x02, 0x89, 0x7c, 0xd2, 0x3b, 0x6f, 0xc7, 0xe4, 0x32, 0x6c, 0x05,
- 0x52, 0x1d, 0xad, 0xb1, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04,
- 0x18, 0x30, 0x16, 0x80, 0x14, 0xb6, 0x77, 0xfa, 0x69, 0x48, 0x47, 0x9f,
- 0x53, 0x12, 0xd5, 0xc2, 0xea, 0x07, 0x32, 0x76, 0x07, 0xd1, 0x97, 0x07,
- 0x19, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
- 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x19, 0xcc, 0x95,
- 0xe2, 0x2f, 0x7b, 0x49, 0xd0, 0x48, 0x90, 0x53, 0xf4, 0x07, 0xb1, 0x20,
- 0x44, 0x35, 0x70, 0x14, 0xd5, 0x44, 0x37, 0x31, 0xef, 0xef, 0x70, 0xd1,
- 0x2d, 0x4c, 0xe9, 0x2d, 0xb0, 0x53, 0x91, 0x01, 0x4c, 0x54, 0xe7, 0x7d,
- 0x9b, 0xda, 0x3a, 0xff, 0xb7, 0xcb, 0x14, 0xad, 0x30, 0x0f, 0x69, 0x1a,
- 0x2a, 0xf0, 0xbc, 0xcd, 0x35, 0xeb, 0x48, 0xdc, 0xb9, 0x87, 0xfd, 0xcf,
- 0xb1, 0x5a, 0xf6, 0x05, 0xda, 0x3c, 0x64, 0xe6, 0x2b, 0xe6, 0xdc, 0x73,
- 0x5e, 0x9a, 0xd8, 0x0c, 0x9b, 0xd2, 0x97, 0xb3, 0xe8, 0xfa, 0x87, 0x95,
- 0x53, 0xe1, 0x99, 0xad, 0x88, 0xe8, 0xfa, 0xbc, 0x09, 0x4d, 0xa2, 0xc4,
- 0x6a, 0x1b, 0x28, 0x3b, 0x2d, 0xc3, 0x21, 0x15, 0xee, 0x14, 0xfa, 0x9d,
- 0x98, 0x10, 0xeb, 0x9f, 0x3e, 0xe6, 0x24, 0x24, 0x5f, 0x7a, 0x1c, 0x05,
- 0xbb, 0x9a, 0x31, 0x23, 0x58, 0x79, 0x4c, 0xec, 0x6d, 0x18, 0x19, 0x4d,
- 0x51, 0x1f, 0x08, 0x61, 0xbd, 0x91, 0x05, 0x0c, 0x5a, 0x9c, 0x26, 0xfc,
- 0x0b, 0xa5, 0x20, 0x25, 0xbf, 0x6a, 0x1b, 0x2b, 0xf7, 0x02, 0x09, 0x72,
- 0x69, 0x83, 0x32, 0x14, 0xc3, 0x60, 0x5b, 0x7e, 0xfd, 0x9a, 0x32, 0xfa,
- 0xb4, 0x95, 0x0e, 0x1a, 0xf9, 0x3b, 0x09, 0xa4, 0x54, 0x47, 0x9a, 0x0c,
- 0xce, 0x32, 0xaf, 0xd1, 0x21, 0xcc, 0x7f, 0xd2, 0x06, 0xef, 0x60, 0x0e,
- 0x62, 0x6f, 0x6f, 0x81, 0x1a, 0x17, 0x9d, 0xc8, 0xcb, 0x28, 0xcc, 0xe2,
- 0x5f, 0x6e, 0x2c, 0x7a, 0xb4, 0xcb, 0x47, 0x7c, 0x74, 0x68, 0x7b, 0x48,
- 0x71, 0x02, 0x9c, 0x23, 0x09, 0xf3, 0x5a, 0xae, 0x5f, 0x42, 0x2e, 0x5f,
- 0x2b, 0x59, 0x2d, 0x52, 0x88, 0xe5, 0x8d, 0x0b, 0xb3, 0xa8, 0x61, 0xf9,
- 0x4b, 0x9b, 0x55, 0xd6, 0xda, 0xb1, 0x92, 0x3b, 0xbf, 0xc3, 0x9b, 0xf9,
- 0x2c,
-};
-
-#if 0
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number: 120036009 (0x7279aa9)
- Signature Algorithm: sha256WithRSAEncryption
- Issuer: C=IE, O=Baltimore, OU=CyberTrust, CN=Baltimore CyberTrust Root
- Validity
- Not Before: Dec 19 20:07:32 2013 GMT
- Not After : Dec 19 20:06:55 2017 GMT
- Subject: C=US, ST=Washington, L=Redmond, O=Microsoft Corporation, OU=Microsoft IT, CN=Microsoft IT SSL SHA2
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (4096 bit)
- Modulus:
- 00:d1:e8:37:a7:76:8a:70:4b:19:f0:20:37:09:24:
- 37:7f:ea:fb:78:e6:05:ba:6a:ad:4e:27:0d:fc:72:
- 6a:d9:6c:21:c4:64:11:95:73:10:0a:5c:25:7b:88:
- 6c:94:04:fd:c7:db:ae:7b:dc:4a:08:b3:3e:16:f1:
- d0:ad:db:30:6d:d7:1a:1e:52:b5:3d:f0:47:19:03:
- e2:7d:a6:bd:57:13:3f:54:ea:3a:a3:b1:77:fc:42:
- f0:63:49:6a:91:80:2e:30:49:c0:8a:eb:2b:af:fe:
- 3a:eb:07:5d:06:f7:e9:fd:84:0e:91:bd:09:20:29:
- e8:6e:5d:09:ce:15:d3:e7:ef:db:50:eb:44:ef:18:
- 57:ab:04:1d:bc:31:f9:f7:7b:2a:13:cf:d1:3d:51:
- af:1b:c5:b5:7b:e7:b0:fc:53:bb:9a:e7:63:de:41:
- 33:b6:47:24:69:5d:b8:46:a7:ff:ad:ab:df:4f:7a:
- 78:25:27:21:26:34:ca:02:6e:37:51:f0:ed:58:1a:
- 60:94:f6:c4:93:d8:dd:30:24:25:d7:1c:eb:19:94:
- 35:5d:93:b2:ae:aa:29:83:73:c4:74:59:05:52:67:
- 9d:da:67:51:39:05:3a:36:ea:f2:1e:76:2b:14:ae:
- ec:3d:f9:14:99:8b:07:6e:bc:e7:0c:56:de:ac:be:
- ae:db:75:32:90:9e:63:bd:74:bf:e0:0a:ca:f8:34:
- 96:67:84:cd:d1:42:38:78:c7:99:b6:0c:ce:b6:0f:
- e9:1b:cb:f4:59:be:11:0e:cb:2c:32:c8:fa:83:29:
- 64:79:3c:8b:4b:f0:32:74:6c:f3:93:b8:96:6b:5d:
- 57:5a:68:c1:cc:0c:79:8a:19:de:f5:49:02:5e:08:
- 80:01:89:0c:32:cd:d2:d6:96:d5:4b:a0:f3:ec:bf:
- ab:f4:7d:b3:a1:b9:7c:da:4e:d7:e5:b7:ac:b9:f2:
- 25:5f:01:cb:8c:96:a8:28:ae:c1:33:5a:f6:3f:08:
- 90:dc:eb:ff:39:d8:26:c8:12:9d:1c:9a:aa:a9:c0:
- 16:8e:86:ed:67:52:96:00:7f:0d:92:3d:3d:d9:70:
- 36:e5:ea:42:6f:1f:ae:95:e5:5b:5d:f8:d0:3a:c7:
- d4:de:77:86:d0:fc:9e:4e:e2:e2:b8:a9:68:37:09:
- c4:39:e3:85:b8:89:f3:1f:6e:b7:6d:1f:4a:2f:18:
- 09:6f:de:4a:01:8f:14:c9:b7:a6:ee:a7:63:9f:33:
- a4:54:7c:42:83:68:b8:a5:df:bf:ec:b9:1a:5d:13:
- 3b:d9:ad:68:fd:20:0a:55:91:21:64:f9:d7:13:01:
- a0:08:5d:59:89:1b:44:af:a4:ac:c7:05:10:fa:41:
- 4a:a8:fb
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Basic Constraints: critical
- CA:TRUE, pathlen:0
- X509v3 Certificate Policies:
- Policy: 1.3.6.1.4.1.6334.1.0
- CPS: http://cybertrust.omniroot.com/repository.cfm
-
- X509v3 Key Usage: critical
- Digital Signature, Certificate Sign, CRL Sign
- X509v3 Extended Key Usage:
- TLS Web Server Authentication, TLS Web Client Authentication
- X509v3 Authority Key Identifier:
- keyid:E5:9D:59:30:82:47:58:CC:AC:FA:08:54:36:86:7B:3A:B5:04:4D:F0
-
- X509v3 CRL Distribution Points:
-
- Full Name:
- URI:http://cdp1.public-trust.com/CRL/Omniroot2025.crl
-
- X509v3 Subject Key Identifier:
- 51:AF:24:26:9C:F4:68:22:57:80:26:2B:3B:46:62:15:7B:1E:CC:A5
- Signature Algorithm: sha256WithRSAEncryption
- 76:85:c5:23:31:1f:b4:73:ea:a0:bc:a5:ed:df:45:43:6a:7f:
- 69:20:1b:80:b2:fb:1c:dd:aa:7f:88:d3:31:41:36:f7:fb:fb:
- 6b:ad:98:8c:78:1f:9d:11:67:3a:cd:4b:ec:a8:bc:9d:15:19:
- c4:3b:0b:a7:93:ce:e8:fc:9d:5b:e8:1f:cb:56:ae:76:43:2b:
- c7:13:51:77:41:a8:66:4c:5f:a7:d1:d7:aa:75:c5:1b:29:4c:
- c9:f4:6d:a1:5e:a1:85:93:16:c2:cb:3b:ab:14:7d:44:fd:da:
- 25:29:86:2a:fe:63:20:ca:d2:0b:c2:34:15:bb:af:5b:7f:8a:
- e0:aa:ed:45:a6:ea:79:db:d8:35:66:54:43:de:37:33:d1:e4:
- e0:cd:57:ca:71:b0:7d:e9:16:77:64:e8:59:97:b9:d5:2e:d1:
- b4:91:da:77:71:f3:4a:0f:48:d2:34:99:60:95:37:ac:1f:01:
- cd:10:9d:e8:2a:a5:20:c7:50:9b:b3:6c:49:78:2b:58:92:64:
- 89:b8:95:36:a8:34:aa:f0:41:d2:95:5a:24:54:97:4d:6e:05:
- c4:95:ad:c4:7a:a3:39:fb:79:06:8a:9b:a6:4f:d9:22:fa:44:
- 4e:36:f3:c9:0f:a6:39:e7:80:b2:5e:bf:bd:39:d1:46:e5:55:
- 47:db:bc:6e
------BEGIN CERTIFICATE-----
-MIIFhjCCBG6gAwIBAgIEByeaqTANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJJ
-RTESMBAGA1UEChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYD
-VQQDExlCYWx0aW1vcmUgQ3liZXJUcnVzdCBSb290MB4XDTEzMTIxOTIwMDczMloX
-DTE3MTIxOTIwMDY1NVowgYsxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5n
-dG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9y
-YXRpb24xFTATBgNVBAsTDE1pY3Jvc29mdCBJVDEeMBwGA1UEAxMVTWljcm9zb2Z0
-IElUIFNTTCBTSEEyMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA0eg3
-p3aKcEsZ8CA3CSQ3f+r7eOYFumqtTicN/HJq2WwhxGQRlXMQClwle4hslAT9x9uu
-e9xKCLM+FvHQrdswbdcaHlK1PfBHGQPifaa9VxM/VOo6o7F3/ELwY0lqkYAuMEnA
-iusrr/466wddBvfp/YQOkb0JICnobl0JzhXT5+/bUOtE7xhXqwQdvDH593sqE8/R
-PVGvG8W1e+ew/FO7mudj3kEztkckaV24Rqf/ravfT3p4JSchJjTKAm43UfDtWBpg
-lPbEk9jdMCQl1xzrGZQ1XZOyrqopg3PEdFkFUmed2mdROQU6NuryHnYrFK7sPfkU
-mYsHbrznDFberL6u23UykJ5jvXS/4ArK+DSWZ4TN0UI4eMeZtgzOtg/pG8v0Wb4R
-DsssMsj6gylkeTyLS/AydGzzk7iWa11XWmjBzAx5ihne9UkCXgiAAYkMMs3S1pbV
-S6Dz7L+r9H2zobl82k7X5besufIlXwHLjJaoKK7BM1r2PwiQ3Ov/OdgmyBKdHJqq
-qcAWjobtZ1KWAH8Nkj092XA25epCbx+uleVbXfjQOsfU3neG0PyeTuLiuKloNwnE
-OeOFuInzH263bR9KLxgJb95KAY8Uybem7qdjnzOkVHxCg2i4pd+/7LkaXRM72a1o
-/SAKVZEhZPnXEwGgCF1ZiRtEr6SsxwUQ+kFKqPsCAwEAAaOCASAwggEcMBIGA1Ud
-EwEB/wQIMAYBAf8CAQAwUwYDVR0gBEwwSjBIBgkrBgEEAbE+AQAwOzA5BggrBgEF
-BQcCARYtaHR0cDovL2N5YmVydHJ1c3Qub21uaXJvb3QuY29tL3JlcG9zaXRvcnku
-Y2ZtMA4GA1UdDwEB/wQEAwIBhjAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUH
-AwIwHwYDVR0jBBgwFoAU5Z1ZMIJHWMys+ghUNoZ7OrUETfAwQgYDVR0fBDswOTA3
-oDWgM4YxaHR0cDovL2NkcDEucHVibGljLXRydXN0LmNvbS9DUkwvT21uaXJvb3Qy
-MDI1LmNybDAdBgNVHQ4EFgQUUa8kJpz0aCJXgCYrO0ZiFXsezKUwDQYJKoZIhvcN
-AQELBQADggEBAHaFxSMxH7Rz6qC8pe3fRUNqf2kgG4Cy+xzdqn+I0zFBNvf7+2ut
-mIx4H50RZzrNS+yovJ0VGcQ7C6eTzuj8nVvoH8tWrnZDK8cTUXdBqGZMX6fR16p1
-xRspTMn0baFeoYWTFsLLO6sUfUT92iUphir+YyDK0gvCNBW7r1t/iuCq7UWm6nnb
-2DVmVEPeNzPR5ODNV8pxsH3pFndk6FmXudUu0bSR2ndx80oPSNI0mWCVN6wfAc0Q
-negqpSDHUJuzbEl4K1iSZIm4lTaoNKrwQdKVWiRUl01uBcSVrcR6ozn7eQaKm6ZP
-2SL6RE4288kPpjnngLJev7050UblVUfbvG4=
------END CERTIFICATE-----
-#endif
-static const unsigned char kDERCert47[] = {
- 0x30, 0x82, 0x05, 0x86, 0x30, 0x82, 0x04, 0x6e, 0xa0, 0x03, 0x02, 0x01,
- 0x02, 0x02, 0x04, 0x07, 0x27, 0x9a, 0xa9, 0x30, 0x0d, 0x06, 0x09, 0x2a,
- 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x5a,
- 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x49,
- 0x45, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x09,
- 0x42, 0x61, 0x6c, 0x74, 0x69, 0x6d, 0x6f, 0x72, 0x65, 0x31, 0x13, 0x30,
- 0x11, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x0a, 0x43, 0x79, 0x62, 0x65,
- 0x72, 0x54, 0x72, 0x75, 0x73, 0x74, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03,
- 0x55, 0x04, 0x03, 0x13, 0x19, 0x42, 0x61, 0x6c, 0x74, 0x69, 0x6d, 0x6f,
- 0x72, 0x65, 0x20, 0x43, 0x79, 0x62, 0x65, 0x72, 0x54, 0x72, 0x75, 0x73,
- 0x74, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x33,
- 0x31, 0x32, 0x31, 0x39, 0x32, 0x30, 0x30, 0x37, 0x33, 0x32, 0x5a, 0x17,
- 0x0d, 0x31, 0x37, 0x31, 0x32, 0x31, 0x39, 0x32, 0x30, 0x30, 0x36, 0x35,
- 0x35, 0x5a, 0x30, 0x81, 0x8b, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55,
- 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03,
- 0x55, 0x04, 0x08, 0x13, 0x0a, 0x57, 0x61, 0x73, 0x68, 0x69, 0x6e, 0x67,
- 0x74, 0x6f, 0x6e, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x07,
- 0x13, 0x07, 0x52, 0x65, 0x64, 0x6d, 0x6f, 0x6e, 0x64, 0x31, 0x1e, 0x30,
- 0x1c, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x15, 0x4d, 0x69, 0x63, 0x72,
- 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x20, 0x43, 0x6f, 0x72, 0x70, 0x6f, 0x72,
- 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55,
- 0x04, 0x0b, 0x13, 0x0c, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66,
- 0x74, 0x20, 0x49, 0x54, 0x31, 0x1e, 0x30, 0x1c, 0x06, 0x03, 0x55, 0x04,
- 0x03, 0x13, 0x15, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74,
- 0x20, 0x49, 0x54, 0x20, 0x53, 0x53, 0x4c, 0x20, 0x53, 0x48, 0x41, 0x32,
- 0x30, 0x82, 0x02, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
- 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x02, 0x0f, 0x00,
- 0x30, 0x82, 0x02, 0x0a, 0x02, 0x82, 0x02, 0x01, 0x00, 0xd1, 0xe8, 0x37,
- 0xa7, 0x76, 0x8a, 0x70, 0x4b, 0x19, 0xf0, 0x20, 0x37, 0x09, 0x24, 0x37,
- 0x7f, 0xea, 0xfb, 0x78, 0xe6, 0x05, 0xba, 0x6a, 0xad, 0x4e, 0x27, 0x0d,
- 0xfc, 0x72, 0x6a, 0xd9, 0x6c, 0x21, 0xc4, 0x64, 0x11, 0x95, 0x73, 0x10,
- 0x0a, 0x5c, 0x25, 0x7b, 0x88, 0x6c, 0x94, 0x04, 0xfd, 0xc7, 0xdb, 0xae,
- 0x7b, 0xdc, 0x4a, 0x08, 0xb3, 0x3e, 0x16, 0xf1, 0xd0, 0xad, 0xdb, 0x30,
- 0x6d, 0xd7, 0x1a, 0x1e, 0x52, 0xb5, 0x3d, 0xf0, 0x47, 0x19, 0x03, 0xe2,
- 0x7d, 0xa6, 0xbd, 0x57, 0x13, 0x3f, 0x54, 0xea, 0x3a, 0xa3, 0xb1, 0x77,
- 0xfc, 0x42, 0xf0, 0x63, 0x49, 0x6a, 0x91, 0x80, 0x2e, 0x30, 0x49, 0xc0,
- 0x8a, 0xeb, 0x2b, 0xaf, 0xfe, 0x3a, 0xeb, 0x07, 0x5d, 0x06, 0xf7, 0xe9,
- 0xfd, 0x84, 0x0e, 0x91, 0xbd, 0x09, 0x20, 0x29, 0xe8, 0x6e, 0x5d, 0x09,
- 0xce, 0x15, 0xd3, 0xe7, 0xef, 0xdb, 0x50, 0xeb, 0x44, 0xef, 0x18, 0x57,
- 0xab, 0x04, 0x1d, 0xbc, 0x31, 0xf9, 0xf7, 0x7b, 0x2a, 0x13, 0xcf, 0xd1,
- 0x3d, 0x51, 0xaf, 0x1b, 0xc5, 0xb5, 0x7b, 0xe7, 0xb0, 0xfc, 0x53, 0xbb,
- 0x9a, 0xe7, 0x63, 0xde, 0x41, 0x33, 0xb6, 0x47, 0x24, 0x69, 0x5d, 0xb8,
- 0x46, 0xa7, 0xff, 0xad, 0xab, 0xdf, 0x4f, 0x7a, 0x78, 0x25, 0x27, 0x21,
- 0x26, 0x34, 0xca, 0x02, 0x6e, 0x37, 0x51, 0xf0, 0xed, 0x58, 0x1a, 0x60,
- 0x94, 0xf6, 0xc4, 0x93, 0xd8, 0xdd, 0x30, 0x24, 0x25, 0xd7, 0x1c, 0xeb,
- 0x19, 0x94, 0x35, 0x5d, 0x93, 0xb2, 0xae, 0xaa, 0x29, 0x83, 0x73, 0xc4,
- 0x74, 0x59, 0x05, 0x52, 0x67, 0x9d, 0xda, 0x67, 0x51, 0x39, 0x05, 0x3a,
- 0x36, 0xea, 0xf2, 0x1e, 0x76, 0x2b, 0x14, 0xae, 0xec, 0x3d, 0xf9, 0x14,
- 0x99, 0x8b, 0x07, 0x6e, 0xbc, 0xe7, 0x0c, 0x56, 0xde, 0xac, 0xbe, 0xae,
- 0xdb, 0x75, 0x32, 0x90, 0x9e, 0x63, 0xbd, 0x74, 0xbf, 0xe0, 0x0a, 0xca,
- 0xf8, 0x34, 0x96, 0x67, 0x84, 0xcd, 0xd1, 0x42, 0x38, 0x78, 0xc7, 0x99,
- 0xb6, 0x0c, 0xce, 0xb6, 0x0f, 0xe9, 0x1b, 0xcb, 0xf4, 0x59, 0xbe, 0x11,
- 0x0e, 0xcb, 0x2c, 0x32, 0xc8, 0xfa, 0x83, 0x29, 0x64, 0x79, 0x3c, 0x8b,
- 0x4b, 0xf0, 0x32, 0x74, 0x6c, 0xf3, 0x93, 0xb8, 0x96, 0x6b, 0x5d, 0x57,
- 0x5a, 0x68, 0xc1, 0xcc, 0x0c, 0x79, 0x8a, 0x19, 0xde, 0xf5, 0x49, 0x02,
- 0x5e, 0x08, 0x80, 0x01, 0x89, 0x0c, 0x32, 0xcd, 0xd2, 0xd6, 0x96, 0xd5,
- 0x4b, 0xa0, 0xf3, 0xec, 0xbf, 0xab, 0xf4, 0x7d, 0xb3, 0xa1, 0xb9, 0x7c,
- 0xda, 0x4e, 0xd7, 0xe5, 0xb7, 0xac, 0xb9, 0xf2, 0x25, 0x5f, 0x01, 0xcb,
- 0x8c, 0x96, 0xa8, 0x28, 0xae, 0xc1, 0x33, 0x5a, 0xf6, 0x3f, 0x08, 0x90,
- 0xdc, 0xeb, 0xff, 0x39, 0xd8, 0x26, 0xc8, 0x12, 0x9d, 0x1c, 0x9a, 0xaa,
- 0xa9, 0xc0, 0x16, 0x8e, 0x86, 0xed, 0x67, 0x52, 0x96, 0x00, 0x7f, 0x0d,
- 0x92, 0x3d, 0x3d, 0xd9, 0x70, 0x36, 0xe5, 0xea, 0x42, 0x6f, 0x1f, 0xae,
- 0x95, 0xe5, 0x5b, 0x5d, 0xf8, 0xd0, 0x3a, 0xc7, 0xd4, 0xde, 0x77, 0x86,
- 0xd0, 0xfc, 0x9e, 0x4e, 0xe2, 0xe2, 0xb8, 0xa9, 0x68, 0x37, 0x09, 0xc4,
- 0x39, 0xe3, 0x85, 0xb8, 0x89, 0xf3, 0x1f, 0x6e, 0xb7, 0x6d, 0x1f, 0x4a,
- 0x2f, 0x18, 0x09, 0x6f, 0xde, 0x4a, 0x01, 0x8f, 0x14, 0xc9, 0xb7, 0xa6,
- 0xee, 0xa7, 0x63, 0x9f, 0x33, 0xa4, 0x54, 0x7c, 0x42, 0x83, 0x68, 0xb8,
- 0xa5, 0xdf, 0xbf, 0xec, 0xb9, 0x1a, 0x5d, 0x13, 0x3b, 0xd9, 0xad, 0x68,
- 0xfd, 0x20, 0x0a, 0x55, 0x91, 0x21, 0x64, 0xf9, 0xd7, 0x13, 0x01, 0xa0,
- 0x08, 0x5d, 0x59, 0x89, 0x1b, 0x44, 0xaf, 0xa4, 0xac, 0xc7, 0x05, 0x10,
- 0xfa, 0x41, 0x4a, 0xa8, 0xfb, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82,
- 0x01, 0x20, 0x30, 0x82, 0x01, 0x1c, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d,
- 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02,
- 0x01, 0x00, 0x30, 0x53, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x4c, 0x30,
- 0x4a, 0x30, 0x48, 0x06, 0x09, 0x2b, 0x06, 0x01, 0x04, 0x01, 0xb1, 0x3e,
- 0x01, 0x00, 0x30, 0x3b, 0x30, 0x39, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05,
- 0x05, 0x07, 0x02, 0x01, 0x16, 0x2d, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f,
- 0x2f, 0x63, 0x79, 0x62, 0x65, 0x72, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e,
- 0x6f, 0x6d, 0x6e, 0x69, 0x72, 0x6f, 0x6f, 0x74, 0x2e, 0x63, 0x6f, 0x6d,
- 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x2e,
- 0x63, 0x66, 0x6d, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01,
- 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x86, 0x30, 0x1d, 0x06, 0x03, 0x55,
- 0x1d, 0x25, 0x04, 0x16, 0x30, 0x14, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05,
- 0x05, 0x07, 0x03, 0x01, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
- 0x03, 0x02, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30,
- 0x16, 0x80, 0x14, 0xe5, 0x9d, 0x59, 0x30, 0x82, 0x47, 0x58, 0xcc, 0xac,
- 0xfa, 0x08, 0x54, 0x36, 0x86, 0x7b, 0x3a, 0xb5, 0x04, 0x4d, 0xf0, 0x30,
- 0x42, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x3b, 0x30, 0x39, 0x30, 0x37,
- 0xa0, 0x35, 0xa0, 0x33, 0x86, 0x31, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f,
- 0x2f, 0x63, 0x64, 0x70, 0x31, 0x2e, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63,
- 0x2d, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x43,
- 0x52, 0x4c, 0x2f, 0x4f, 0x6d, 0x6e, 0x69, 0x72, 0x6f, 0x6f, 0x74, 0x32,
- 0x30, 0x32, 0x35, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x1d, 0x06, 0x03, 0x55,
- 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x51, 0xaf, 0x24, 0x26, 0x9c, 0xf4,
- 0x68, 0x22, 0x57, 0x80, 0x26, 0x2b, 0x3b, 0x46, 0x62, 0x15, 0x7b, 0x1e,
- 0xcc, 0xa5, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
- 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x76, 0x85,
- 0xc5, 0x23, 0x31, 0x1f, 0xb4, 0x73, 0xea, 0xa0, 0xbc, 0xa5, 0xed, 0xdf,
- 0x45, 0x43, 0x6a, 0x7f, 0x69, 0x20, 0x1b, 0x80, 0xb2, 0xfb, 0x1c, 0xdd,
- 0xaa, 0x7f, 0x88, 0xd3, 0x31, 0x41, 0x36, 0xf7, 0xfb, 0xfb, 0x6b, 0xad,
- 0x98, 0x8c, 0x78, 0x1f, 0x9d, 0x11, 0x67, 0x3a, 0xcd, 0x4b, 0xec, 0xa8,
- 0xbc, 0x9d, 0x15, 0x19, 0xc4, 0x3b, 0x0b, 0xa7, 0x93, 0xce, 0xe8, 0xfc,
- 0x9d, 0x5b, 0xe8, 0x1f, 0xcb, 0x56, 0xae, 0x76, 0x43, 0x2b, 0xc7, 0x13,
- 0x51, 0x77, 0x41, 0xa8, 0x66, 0x4c, 0x5f, 0xa7, 0xd1, 0xd7, 0xaa, 0x75,
- 0xc5, 0x1b, 0x29, 0x4c, 0xc9, 0xf4, 0x6d, 0xa1, 0x5e, 0xa1, 0x85, 0x93,
- 0x16, 0xc2, 0xcb, 0x3b, 0xab, 0x14, 0x7d, 0x44, 0xfd, 0xda, 0x25, 0x29,
- 0x86, 0x2a, 0xfe, 0x63, 0x20, 0xca, 0xd2, 0x0b, 0xc2, 0x34, 0x15, 0xbb,
- 0xaf, 0x5b, 0x7f, 0x8a, 0xe0, 0xaa, 0xed, 0x45, 0xa6, 0xea, 0x79, 0xdb,
- 0xd8, 0x35, 0x66, 0x54, 0x43, 0xde, 0x37, 0x33, 0xd1, 0xe4, 0xe0, 0xcd,
- 0x57, 0xca, 0x71, 0xb0, 0x7d, 0xe9, 0x16, 0x77, 0x64, 0xe8, 0x59, 0x97,
- 0xb9, 0xd5, 0x2e, 0xd1, 0xb4, 0x91, 0xda, 0x77, 0x71, 0xf3, 0x4a, 0x0f,
- 0x48, 0xd2, 0x34, 0x99, 0x60, 0x95, 0x37, 0xac, 0x1f, 0x01, 0xcd, 0x10,
- 0x9d, 0xe8, 0x2a, 0xa5, 0x20, 0xc7, 0x50, 0x9b, 0xb3, 0x6c, 0x49, 0x78,
- 0x2b, 0x58, 0x92, 0x64, 0x89, 0xb8, 0x95, 0x36, 0xa8, 0x34, 0xaa, 0xf0,
- 0x41, 0xd2, 0x95, 0x5a, 0x24, 0x54, 0x97, 0x4d, 0x6e, 0x05, 0xc4, 0x95,
- 0xad, 0xc4, 0x7a, 0xa3, 0x39, 0xfb, 0x79, 0x06, 0x8a, 0x9b, 0xa6, 0x4f,
- 0xd9, 0x22, 0xfa, 0x44, 0x4e, 0x36, 0xf3, 0xc9, 0x0f, 0xa6, 0x39, 0xe7,
- 0x80, 0xb2, 0x5e, 0xbf, 0xbd, 0x39, 0xd1, 0x46, 0xe5, 0x55, 0x47, 0xdb,
- 0xbc, 0x6e,
-};
-
-#if 0
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number:
- 75:96:c2:3e:fa:89:59:45:6e:79:f7:17:ba:cf:64:f3
- Signature Algorithm: sha256WithRSAEncryption
- Issuer: C=CN, O=WoSign CA Limited, CN=Certification Authority of WoSign
- Validity
- Not Before: Nov 8 00:58:58 2014 GMT
- Not After : Nov 8 00:58:58 2029 GMT
- Subject: C=CN, O=WoSign CA Limited, CN=WoSign Class 3 OV Server CA G2
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:d6:74:87:af:99:c0:57:96:99:c2:89:74:3c:92:
- 55:99:bf:1f:07:00:35:05:26:96:16:5b:03:c1:42:
- 37:33:be:3f:0d:4f:ff:bb:94:26:91:d7:14:16:78:
- 1b:f7:13:a2:4b:4c:e5:5c:a7:10:40:35:59:30:d1:
- 77:99:e3:9d:29:c2:be:31:95:bd:92:61:5b:b0:23:
- fb:67:58:d5:52:e4:7b:2f:f0:73:1c:73:94:55:ba:
- c8:68:59:02:10:10:e4:f7:11:f0:c3:b6:d7:ae:56:
- 80:00:9e:65:64:a6:83:91:41:e6:ed:a7:7a:65:a5:
- 1f:30:2e:13:3c:bf:df:63:97:f3:96:f0:52:32:b4:
- f4:7b:98:57:ed:36:4f:f7:21:4a:28:9d:dd:1c:92:
- b3:4d:8d:9c:58:8b:17:21:d8:dc:a1:b7:ae:73:78:
- 8a:c4:b6:e9:7f:28:8e:9a:d5:2e:9e:39:e9:da:59:
- 74:e3:c8:97:10:32:94:19:59:d4:0f:89:57:44:e6:
- e5:2b:17:30:62:52:98:7f:ab:0d:a5:01:ea:04:41:
- ca:fa:13:0e:3b:87:06:ba:bd:47:31:d7:63:03:01:
- f4:be:a1:37:11:9f:1e:01:95:4e:0f:3f:54:1e:92:
- a6:9f:30:8c:fe:98:e8:56:96:66:04:e1:35:fe:59:
- ac:57
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Key Usage: critical
- Certificate Sign, CRL Sign
- X509v3 Extended Key Usage:
- TLS Web Client Authentication, TLS Web Server Authentication
- X509v3 Basic Constraints: critical
- CA:TRUE, pathlen:0
- X509v3 CRL Distribution Points:
-
- Full Name:
- URI:http://crls1.wosign.com/ca1.crl
-
- Authority Information Access:
- OCSP - URI:http://ocsp1.wosign.com/ca1
- CA Issuers - URI:http://aia1.wosign.com/ca1g2-server3.cer
-
- X509v3 Subject Key Identifier:
- F9:8B:EC:04:38:6A:3F:AA:06:C6:94:AD:73:95:2A:B0:C8:E6:B8:FB
- X509v3 Authority Key Identifier:
- keyid:E1:66:CF:0E:D1:F1:B3:4B:B7:06:20:14:FE:87:12:D5:F6:FE:FB:3E
-
- X509v3 Certificate Policies:
- Policy: 1.3.6.1.4.1.36305.6.3.2.1
- CPS: http://www.wosign.com/policy/
-
- Signature Algorithm: sha256WithRSAEncryption
- 5e:67:ba:78:32:05:b6:b7:af:e7:de:6a:7a:82:64:0e:a0:0b:
- f2:9e:9a:ba:c6:2b:6f:56:3a:b4:62:57:ab:7c:ad:60:50:96:
- 34:9c:a3:88:cf:d9:8f:50:af:f6:f0:00:36:1b:1f:1f:87:55:
- 3c:60:9a:f0:b0:0d:9a:80:2d:8a:3b:be:05:b3:d7:a0:80:b6:
- b8:19:eb:51:db:ec:64:54:f1:1a:89:4a:48:a1:4d:3f:31:7d:
- c4:79:94:4b:f1:de:ab:83:af:5f:86:be:96:1c:b3:3e:1c:e7:
- bc:96:b2:e8:5a:ac:b5:58:cb:3c:56:6f:0a:a7:a5:d0:36:89:
- 82:26:8c:b9:1f:b6:eb:8f:7e:78:fc:5b:8b:79:1c:d6:df:47:
- a7:56:f4:98:4e:c7:a9:d5:0e:75:56:06:7f:b4:37:46:08:c6:
- e9:4f:8b:5b:43:1c:e0:45:3e:95:20:71:c0:1c:98:16:ef:f2:
- 78:df:ac:4d:bb:bf:56:0e:cf:85:af:cf:bf:04:ed:72:6b:fd:
- 1f:57:0e:58:91:44:11:58:3b:62:3b:09:78:b3:a4:75:6a:ec:
- b3:c2:2b:32:cc:b3:8d:c3:a3:6e:dc:8a:d5:e8:4a:c4:0b:7b:
- db:30:5d:95:33:c3:d1:a3:69:64:5b:a8:aa:96:48:73:73:e3:
- c9:b9:24:df:17:75:aa:af:07:3a:cf:be:9b:8a:80:a7:bf:7c:
- e2:e9:2a:e6:fd:b0:2c:e7:e6:e6:7e:b3:35:15:65:00:f4:e1:
- 39:73:0e:28:4b:f0:0c:98:9e:3a:eb:ce:7b:7a:9e:40:c1:50:
- 65:96:9a:e7:4b:77:cd:dd:cb:7d:97:b4:ea:09:b2:e9:49:28:
- c3:30:e0:87:15:f0:26:ea:d8:03:fd:ec:da:08:83:65:dc:77:
- c5:6e:3d:34:f7:87:c3:1c:1d:26:33:ec:33:ac:c6:99:53:ab:
- 60:f4:b0:d9:ee:64:5a:33:07:70:13:74:88:07:f5:86:f9:18:
- d3:b2:47:c8:ae:03:4a:53:de:1c:65:d6:0a:2e:3a:51:93:ee:
- b7:e3:6f:0a:fb:e9:fe:4e:e8:bb:1d:c2:97:ab:0a:b9:ed:36:
- 32:1b:4d:a1:cc:03:a6:9d:b3:d9:1c:d5:67:e2:8f:74:3c:92:
- 2a:74:b1:56:50:df:53:15:d7:21:d6:eb:f3:fb:63:e3:20:2c:
- 0a:74:37:0b:c1:a1:35:6a:84:70:f4:45:f8:b2:b6:81:49:aa:
- fd:54:45:90:4d:e7:04:07:5f:78:14:dd:3a:bb:2b:f9:72:50:
- ec:68:ea:3c:a8:d1:80:bb:be:35:43:97:c3:32:b2:f5:aa:ad:
- c9:7f:83:9f:7d:69:1e:15
------BEGIN CERTIFICATE-----
-MIIFozCCA4ugAwIBAgIQdZbCPvqJWUVuefcXus9k8zANBgkqhkiG9w0BAQsFADBV
-MQswCQYDVQQGEwJDTjEaMBgGA1UEChMRV29TaWduIENBIExpbWl0ZWQxKjAoBgNV
-BAMTIUNlcnRpZmljYXRpb24gQXV0aG9yaXR5IG9mIFdvU2lnbjAeFw0xNDExMDgw
-MDU4NThaFw0yOTExMDgwMDU4NThaMFIxCzAJBgNVBAYTAkNOMRowGAYDVQQKExFX
-b1NpZ24gQ0EgTGltaXRlZDEnMCUGA1UEAxMeV29TaWduIENsYXNzIDMgT1YgU2Vy
-dmVyIENBIEcyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1nSHr5nA
-V5aZwol0PJJVmb8fBwA1BSaWFlsDwUI3M74/DU//u5QmkdcUFngb9xOiS0zlXKcQ
-QDVZMNF3meOdKcK+MZW9kmFbsCP7Z1jVUuR7L/BzHHOUVbrIaFkCEBDk9xHww7bX
-rlaAAJ5lZKaDkUHm7ad6ZaUfMC4TPL/fY5fzlvBSMrT0e5hX7TZP9yFKKJ3dHJKz
-TY2cWIsXIdjcobeuc3iKxLbpfyiOmtUunjnp2ll048iXEDKUGVnUD4lXROblKxcw
-YlKYf6sNpQHqBEHK+hMOO4cGur1HMddjAwH0vqE3EZ8eAZVODz9UHpKmnzCM/pjo
-VpZmBOE1/lmsVwIDAQABo4IBcDCCAWwwDgYDVR0PAQH/BAQDAgEGMB0GA1UdJQQW
-MBQGCCsGAQUFBwMCBggrBgEFBQcDATASBgNVHRMBAf8ECDAGAQH/AgEAMDAGA1Ud
-HwQpMCcwJaAjoCGGH2h0dHA6Ly9jcmxzMS53b3NpZ24uY29tL2NhMS5jcmwwbQYI
-KwYBBQUHAQEEYTBfMCcGCCsGAQUFBzABhhtodHRwOi8vb2NzcDEud29zaWduLmNv
-bS9jYTEwNAYIKwYBBQUHMAKGKGh0dHA6Ly9haWExLndvc2lnbi5jb20vY2ExZzIt
-c2VydmVyMy5jZXIwHQYDVR0OBBYEFPmL7AQ4aj+qBsaUrXOVKrDI5rj7MB8GA1Ud
-IwQYMBaAFOFmzw7R8bNLtwYgFP6HEtX2/vs+MEYGA1UdIAQ/MD0wOwYMKwYBBAGC
-m1EGAwIBMCswKQYIKwYBBQUHAgEWHWh0dHA6Ly93d3cud29zaWduLmNvbS9wb2xp
-Y3kvMA0GCSqGSIb3DQEBCwUAA4ICAQBeZ7p4MgW2t6/n3mp6gmQOoAvynpq6xitv
-Vjq0YlerfK1gUJY0nKOIz9mPUK/28AA2Gx8fh1U8YJrwsA2agC2KO74Fs9eggLa4
-GetR2+xkVPEaiUpIoU0/MX3EeZRL8d6rg69fhr6WHLM+HOe8lrLoWqy1WMs8Vm8K
-p6XQNomCJoy5H7brj354/FuLeRzW30enVvSYTsep1Q51VgZ/tDdGCMbpT4tbQxzg
-RT6VIHHAHJgW7/J436xNu79WDs+Fr8+/BO1ya/0fVw5YkUQRWDtiOwl4s6R1auyz
-wisyzLONw6Nu3IrV6ErEC3vbMF2VM8PRo2lkW6iqlkhzc+PJuSTfF3Wqrwc6z76b
-ioCnv3zi6Srm/bAs5+bmfrM1FWUA9OE5cw4oS/AMmJ466857ep5AwVBllprnS3fN
-3ct9l7TqCbLpSSjDMOCHFfAm6tgD/ezaCINl3HfFbj0094fDHB0mM+wzrMaZU6tg
-9LDZ7mRaMwdwE3SIB/WG+RjTskfIrgNKU94cZdYKLjpRk+63428K++n+Tui7HcKX
-qwq57TYyG02hzAOmnbPZHNVn4o90PJIqdLFWUN9TFdch1uvz+2PjICwKdDcLwaE1
-aoRw9EX4sraBSar9VEWQTecEB194FN06uyv5clDsaOo8qNGAu741Q5fDMrL1qq3J
-f4OffWkeFQ==
------END CERTIFICATE-----
-#endif
-static const unsigned char kDERCert48[] = {
- 0x30, 0x82, 0x05, 0xa3, 0x30, 0x82, 0x03, 0x8b, 0xa0, 0x03, 0x02, 0x01,
- 0x02, 0x02, 0x10, 0x75, 0x96, 0xc2, 0x3e, 0xfa, 0x89, 0x59, 0x45, 0x6e,
- 0x79, 0xf7, 0x17, 0xba, 0xcf, 0x64, 0xf3, 0x30, 0x0d, 0x06, 0x09, 0x2a,
- 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x55,
- 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x43,
- 0x4e, 0x31, 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x11,
- 0x57, 0x6f, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x43, 0x41, 0x20, 0x4c, 0x69,
- 0x6d, 0x69, 0x74, 0x65, 0x64, 0x31, 0x2a, 0x30, 0x28, 0x06, 0x03, 0x55,
- 0x04, 0x03, 0x13, 0x21, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63,
- 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72,
- 0x69, 0x74, 0x79, 0x20, 0x6f, 0x66, 0x20, 0x57, 0x6f, 0x53, 0x69, 0x67,
- 0x6e, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x34, 0x31, 0x31, 0x30, 0x38, 0x30,
- 0x30, 0x35, 0x38, 0x35, 0x38, 0x5a, 0x17, 0x0d, 0x32, 0x39, 0x31, 0x31,
- 0x30, 0x38, 0x30, 0x30, 0x35, 0x38, 0x35, 0x38, 0x5a, 0x30, 0x52, 0x31,
- 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x43, 0x4e,
- 0x31, 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x11, 0x57,
- 0x6f, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x43, 0x41, 0x20, 0x4c, 0x69, 0x6d,
- 0x69, 0x74, 0x65, 0x64, 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04,
- 0x03, 0x13, 0x1e, 0x57, 0x6f, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x43, 0x6c,
- 0x61, 0x73, 0x73, 0x20, 0x33, 0x20, 0x4f, 0x56, 0x20, 0x53, 0x65, 0x72,
- 0x76, 0x65, 0x72, 0x20, 0x43, 0x41, 0x20, 0x47, 0x32, 0x30, 0x82, 0x01,
- 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
- 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01,
- 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xd6, 0x74, 0x87, 0xaf, 0x99, 0xc0,
- 0x57, 0x96, 0x99, 0xc2, 0x89, 0x74, 0x3c, 0x92, 0x55, 0x99, 0xbf, 0x1f,
- 0x07, 0x00, 0x35, 0x05, 0x26, 0x96, 0x16, 0x5b, 0x03, 0xc1, 0x42, 0x37,
- 0x33, 0xbe, 0x3f, 0x0d, 0x4f, 0xff, 0xbb, 0x94, 0x26, 0x91, 0xd7, 0x14,
- 0x16, 0x78, 0x1b, 0xf7, 0x13, 0xa2, 0x4b, 0x4c, 0xe5, 0x5c, 0xa7, 0x10,
- 0x40, 0x35, 0x59, 0x30, 0xd1, 0x77, 0x99, 0xe3, 0x9d, 0x29, 0xc2, 0xbe,
- 0x31, 0x95, 0xbd, 0x92, 0x61, 0x5b, 0xb0, 0x23, 0xfb, 0x67, 0x58, 0xd5,
- 0x52, 0xe4, 0x7b, 0x2f, 0xf0, 0x73, 0x1c, 0x73, 0x94, 0x55, 0xba, 0xc8,
- 0x68, 0x59, 0x02, 0x10, 0x10, 0xe4, 0xf7, 0x11, 0xf0, 0xc3, 0xb6, 0xd7,
- 0xae, 0x56, 0x80, 0x00, 0x9e, 0x65, 0x64, 0xa6, 0x83, 0x91, 0x41, 0xe6,
- 0xed, 0xa7, 0x7a, 0x65, 0xa5, 0x1f, 0x30, 0x2e, 0x13, 0x3c, 0xbf, 0xdf,
- 0x63, 0x97, 0xf3, 0x96, 0xf0, 0x52, 0x32, 0xb4, 0xf4, 0x7b, 0x98, 0x57,
- 0xed, 0x36, 0x4f, 0xf7, 0x21, 0x4a, 0x28, 0x9d, 0xdd, 0x1c, 0x92, 0xb3,
- 0x4d, 0x8d, 0x9c, 0x58, 0x8b, 0x17, 0x21, 0xd8, 0xdc, 0xa1, 0xb7, 0xae,
- 0x73, 0x78, 0x8a, 0xc4, 0xb6, 0xe9, 0x7f, 0x28, 0x8e, 0x9a, 0xd5, 0x2e,
- 0x9e, 0x39, 0xe9, 0xda, 0x59, 0x74, 0xe3, 0xc8, 0x97, 0x10, 0x32, 0x94,
- 0x19, 0x59, 0xd4, 0x0f, 0x89, 0x57, 0x44, 0xe6, 0xe5, 0x2b, 0x17, 0x30,
- 0x62, 0x52, 0x98, 0x7f, 0xab, 0x0d, 0xa5, 0x01, 0xea, 0x04, 0x41, 0xca,
- 0xfa, 0x13, 0x0e, 0x3b, 0x87, 0x06, 0xba, 0xbd, 0x47, 0x31, 0xd7, 0x63,
- 0x03, 0x01, 0xf4, 0xbe, 0xa1, 0x37, 0x11, 0x9f, 0x1e, 0x01, 0x95, 0x4e,
- 0x0f, 0x3f, 0x54, 0x1e, 0x92, 0xa6, 0x9f, 0x30, 0x8c, 0xfe, 0x98, 0xe8,
- 0x56, 0x96, 0x66, 0x04, 0xe1, 0x35, 0xfe, 0x59, 0xac, 0x57, 0x02, 0x03,
- 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x70, 0x30, 0x82, 0x01, 0x6c, 0x30,
- 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03,
- 0x02, 0x01, 0x06, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04, 0x16,
- 0x30, 0x14, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x02,
- 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x01, 0x30, 0x12,
- 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06,
- 0x01, 0x01, 0xff, 0x02, 0x01, 0x00, 0x30, 0x30, 0x06, 0x03, 0x55, 0x1d,
- 0x1f, 0x04, 0x29, 0x30, 0x27, 0x30, 0x25, 0xa0, 0x23, 0xa0, 0x21, 0x86,
- 0x1f, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x73,
- 0x31, 0x2e, 0x77, 0x6f, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d,
- 0x2f, 0x63, 0x61, 0x31, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x6d, 0x06, 0x08,
- 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x61, 0x30, 0x5f,
- 0x30, 0x27, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01,
- 0x86, 0x1b, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73,
- 0x70, 0x31, 0x2e, 0x77, 0x6f, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f,
- 0x6d, 0x2f, 0x63, 0x61, 0x31, 0x30, 0x34, 0x06, 0x08, 0x2b, 0x06, 0x01,
- 0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x28, 0x68, 0x74, 0x74, 0x70, 0x3a,
- 0x2f, 0x2f, 0x61, 0x69, 0x61, 0x31, 0x2e, 0x77, 0x6f, 0x73, 0x69, 0x67,
- 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x61, 0x31, 0x67, 0x32, 0x2d,
- 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x33, 0x2e, 0x63, 0x65, 0x72, 0x30,
- 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xf9, 0x8b,
- 0xec, 0x04, 0x38, 0x6a, 0x3f, 0xaa, 0x06, 0xc6, 0x94, 0xad, 0x73, 0x95,
- 0x2a, 0xb0, 0xc8, 0xe6, 0xb8, 0xfb, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d,
- 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0xe1, 0x66, 0xcf, 0x0e, 0xd1,
- 0xf1, 0xb3, 0x4b, 0xb7, 0x06, 0x20, 0x14, 0xfe, 0x87, 0x12, 0xd5, 0xf6,
- 0xfe, 0xfb, 0x3e, 0x30, 0x46, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x3f,
- 0x30, 0x3d, 0x30, 0x3b, 0x06, 0x0c, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82,
- 0x9b, 0x51, 0x06, 0x03, 0x02, 0x01, 0x30, 0x2b, 0x30, 0x29, 0x06, 0x08,
- 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x1d, 0x68, 0x74,
- 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x77, 0x6f, 0x73,
- 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x6f, 0x6c, 0x69,
- 0x63, 0x79, 0x2f, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
- 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x02, 0x01, 0x00, 0x5e,
- 0x67, 0xba, 0x78, 0x32, 0x05, 0xb6, 0xb7, 0xaf, 0xe7, 0xde, 0x6a, 0x7a,
- 0x82, 0x64, 0x0e, 0xa0, 0x0b, 0xf2, 0x9e, 0x9a, 0xba, 0xc6, 0x2b, 0x6f,
- 0x56, 0x3a, 0xb4, 0x62, 0x57, 0xab, 0x7c, 0xad, 0x60, 0x50, 0x96, 0x34,
- 0x9c, 0xa3, 0x88, 0xcf, 0xd9, 0x8f, 0x50, 0xaf, 0xf6, 0xf0, 0x00, 0x36,
- 0x1b, 0x1f, 0x1f, 0x87, 0x55, 0x3c, 0x60, 0x9a, 0xf0, 0xb0, 0x0d, 0x9a,
- 0x80, 0x2d, 0x8a, 0x3b, 0xbe, 0x05, 0xb3, 0xd7, 0xa0, 0x80, 0xb6, 0xb8,
- 0x19, 0xeb, 0x51, 0xdb, 0xec, 0x64, 0x54, 0xf1, 0x1a, 0x89, 0x4a, 0x48,
- 0xa1, 0x4d, 0x3f, 0x31, 0x7d, 0xc4, 0x79, 0x94, 0x4b, 0xf1, 0xde, 0xab,
- 0x83, 0xaf, 0x5f, 0x86, 0xbe, 0x96, 0x1c, 0xb3, 0x3e, 0x1c, 0xe7, 0xbc,
- 0x96, 0xb2, 0xe8, 0x5a, 0xac, 0xb5, 0x58, 0xcb, 0x3c, 0x56, 0x6f, 0x0a,
- 0xa7, 0xa5, 0xd0, 0x36, 0x89, 0x82, 0x26, 0x8c, 0xb9, 0x1f, 0xb6, 0xeb,
- 0x8f, 0x7e, 0x78, 0xfc, 0x5b, 0x8b, 0x79, 0x1c, 0xd6, 0xdf, 0x47, 0xa7,
- 0x56, 0xf4, 0x98, 0x4e, 0xc7, 0xa9, 0xd5, 0x0e, 0x75, 0x56, 0x06, 0x7f,
- 0xb4, 0x37, 0x46, 0x08, 0xc6, 0xe9, 0x4f, 0x8b, 0x5b, 0x43, 0x1c, 0xe0,
- 0x45, 0x3e, 0x95, 0x20, 0x71, 0xc0, 0x1c, 0x98, 0x16, 0xef, 0xf2, 0x78,
- 0xdf, 0xac, 0x4d, 0xbb, 0xbf, 0x56, 0x0e, 0xcf, 0x85, 0xaf, 0xcf, 0xbf,
- 0x04, 0xed, 0x72, 0x6b, 0xfd, 0x1f, 0x57, 0x0e, 0x58, 0x91, 0x44, 0x11,
- 0x58, 0x3b, 0x62, 0x3b, 0x09, 0x78, 0xb3, 0xa4, 0x75, 0x6a, 0xec, 0xb3,
- 0xc2, 0x2b, 0x32, 0xcc, 0xb3, 0x8d, 0xc3, 0xa3, 0x6e, 0xdc, 0x8a, 0xd5,
- 0xe8, 0x4a, 0xc4, 0x0b, 0x7b, 0xdb, 0x30, 0x5d, 0x95, 0x33, 0xc3, 0xd1,
- 0xa3, 0x69, 0x64, 0x5b, 0xa8, 0xaa, 0x96, 0x48, 0x73, 0x73, 0xe3, 0xc9,
- 0xb9, 0x24, 0xdf, 0x17, 0x75, 0xaa, 0xaf, 0x07, 0x3a, 0xcf, 0xbe, 0x9b,
- 0x8a, 0x80, 0xa7, 0xbf, 0x7c, 0xe2, 0xe9, 0x2a, 0xe6, 0xfd, 0xb0, 0x2c,
- 0xe7, 0xe6, 0xe6, 0x7e, 0xb3, 0x35, 0x15, 0x65, 0x00, 0xf4, 0xe1, 0x39,
- 0x73, 0x0e, 0x28, 0x4b, 0xf0, 0x0c, 0x98, 0x9e, 0x3a, 0xeb, 0xce, 0x7b,
- 0x7a, 0x9e, 0x40, 0xc1, 0x50, 0x65, 0x96, 0x9a, 0xe7, 0x4b, 0x77, 0xcd,
- 0xdd, 0xcb, 0x7d, 0x97, 0xb4, 0xea, 0x09, 0xb2, 0xe9, 0x49, 0x28, 0xc3,
- 0x30, 0xe0, 0x87, 0x15, 0xf0, 0x26, 0xea, 0xd8, 0x03, 0xfd, 0xec, 0xda,
- 0x08, 0x83, 0x65, 0xdc, 0x77, 0xc5, 0x6e, 0x3d, 0x34, 0xf7, 0x87, 0xc3,
- 0x1c, 0x1d, 0x26, 0x33, 0xec, 0x33, 0xac, 0xc6, 0x99, 0x53, 0xab, 0x60,
- 0xf4, 0xb0, 0xd9, 0xee, 0x64, 0x5a, 0x33, 0x07, 0x70, 0x13, 0x74, 0x88,
- 0x07, 0xf5, 0x86, 0xf9, 0x18, 0xd3, 0xb2, 0x47, 0xc8, 0xae, 0x03, 0x4a,
- 0x53, 0xde, 0x1c, 0x65, 0xd6, 0x0a, 0x2e, 0x3a, 0x51, 0x93, 0xee, 0xb7,
- 0xe3, 0x6f, 0x0a, 0xfb, 0xe9, 0xfe, 0x4e, 0xe8, 0xbb, 0x1d, 0xc2, 0x97,
- 0xab, 0x0a, 0xb9, 0xed, 0x36, 0x32, 0x1b, 0x4d, 0xa1, 0xcc, 0x03, 0xa6,
- 0x9d, 0xb3, 0xd9, 0x1c, 0xd5, 0x67, 0xe2, 0x8f, 0x74, 0x3c, 0x92, 0x2a,
- 0x74, 0xb1, 0x56, 0x50, 0xdf, 0x53, 0x15, 0xd7, 0x21, 0xd6, 0xeb, 0xf3,
- 0xfb, 0x63, 0xe3, 0x20, 0x2c, 0x0a, 0x74, 0x37, 0x0b, 0xc1, 0xa1, 0x35,
- 0x6a, 0x84, 0x70, 0xf4, 0x45, 0xf8, 0xb2, 0xb6, 0x81, 0x49, 0xaa, 0xfd,
- 0x54, 0x45, 0x90, 0x4d, 0xe7, 0x04, 0x07, 0x5f, 0x78, 0x14, 0xdd, 0x3a,
- 0xbb, 0x2b, 0xf9, 0x72, 0x50, 0xec, 0x68, 0xea, 0x3c, 0xa8, 0xd1, 0x80,
- 0xbb, 0xbe, 0x35, 0x43, 0x97, 0xc3, 0x32, 0xb2, 0xf5, 0xaa, 0xad, 0xc9,
- 0x7f, 0x83, 0x9f, 0x7d, 0x69, 0x1e, 0x15,
-};
-
-#if 0
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number: 120040007 (0x727aa47)
- Signature Algorithm: sha256WithRSAEncryption
- Issuer: C=IE, O=Baltimore, OU=CyberTrust, CN=Baltimore CyberTrust Root
- Validity
- Not Before: May 7 17:04:09 2014 GMT
- Not After : May 7 17:03:30 2018 GMT
- Subject: C=US, ST=Washington, L=Redmond, O=Microsoft Corporation, OU=Microsoft IT, CN=Microsoft IT SSL SHA2
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (4096 bit)
- Modulus:
- 00:d1:e8:37:a7:76:8a:70:4b:19:f0:20:37:09:24:
- 37:7f:ea:fb:78:e6:05:ba:6a:ad:4e:27:0d:fc:72:
- 6a:d9:6c:21:c4:64:11:95:73:10:0a:5c:25:7b:88:
- 6c:94:04:fd:c7:db:ae:7b:dc:4a:08:b3:3e:16:f1:
- d0:ad:db:30:6d:d7:1a:1e:52:b5:3d:f0:47:19:03:
- e2:7d:a6:bd:57:13:3f:54:ea:3a:a3:b1:77:fc:42:
- f0:63:49:6a:91:80:2e:30:49:c0:8a:eb:2b:af:fe:
- 3a:eb:07:5d:06:f7:e9:fd:84:0e:91:bd:09:20:29:
- e8:6e:5d:09:ce:15:d3:e7:ef:db:50:eb:44:ef:18:
- 57:ab:04:1d:bc:31:f9:f7:7b:2a:13:cf:d1:3d:51:
- af:1b:c5:b5:7b:e7:b0:fc:53:bb:9a:e7:63:de:41:
- 33:b6:47:24:69:5d:b8:46:a7:ff:ad:ab:df:4f:7a:
- 78:25:27:21:26:34:ca:02:6e:37:51:f0:ed:58:1a:
- 60:94:f6:c4:93:d8:dd:30:24:25:d7:1c:eb:19:94:
- 35:5d:93:b2:ae:aa:29:83:73:c4:74:59:05:52:67:
- 9d:da:67:51:39:05:3a:36:ea:f2:1e:76:2b:14:ae:
- ec:3d:f9:14:99:8b:07:6e:bc:e7:0c:56:de:ac:be:
- ae:db:75:32:90:9e:63:bd:74:bf:e0:0a:ca:f8:34:
- 96:67:84:cd:d1:42:38:78:c7:99:b6:0c:ce:b6:0f:
- e9:1b:cb:f4:59:be:11:0e:cb:2c:32:c8:fa:83:29:
- 64:79:3c:8b:4b:f0:32:74:6c:f3:93:b8:96:6b:5d:
- 57:5a:68:c1:cc:0c:79:8a:19:de:f5:49:02:5e:08:
- 80:01:89:0c:32:cd:d2:d6:96:d5:4b:a0:f3:ec:bf:
- ab:f4:7d:b3:a1:b9:7c:da:4e:d7:e5:b7:ac:b9:f2:
- 25:5f:01:cb:8c:96:a8:28:ae:c1:33:5a:f6:3f:08:
- 90:dc:eb:ff:39:d8:26:c8:12:9d:1c:9a:aa:a9:c0:
- 16:8e:86:ed:67:52:96:00:7f:0d:92:3d:3d:d9:70:
- 36:e5:ea:42:6f:1f:ae:95:e5:5b:5d:f8:d0:3a:c7:
- d4:de:77:86:d0:fc:9e:4e:e2:e2:b8:a9:68:37:09:
- c4:39:e3:85:b8:89:f3:1f:6e:b7:6d:1f:4a:2f:18:
- 09:6f:de:4a:01:8f:14:c9:b7:a6:ee:a7:63:9f:33:
- a4:54:7c:42:83:68:b8:a5:df:bf:ec:b9:1a:5d:13:
- 3b:d9:ad:68:fd:20:0a:55:91:21:64:f9:d7:13:01:
- a0:08:5d:59:89:1b:44:af:a4:ac:c7:05:10:fa:41:
- 4a:a8:fb
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Basic Constraints: critical
- CA:TRUE, pathlen:0
- X509v3 Certificate Policies:
- Policy: 1.3.6.1.4.1.6334.1.0
- CPS: http://cybertrust.omniroot.com/repository.cfm
- Policy: 1.3.6.1.4.1.311.42.1
-
- Authority Information Access:
- OCSP - URI:http://ocsp.omniroot.com/baltimoreroot
-
- X509v3 Key Usage: critical
- Digital Signature, Certificate Sign, CRL Sign
- X509v3 Extended Key Usage:
- TLS Web Server Authentication, TLS Web Client Authentication, OCSP Signing
- X509v3 Authority Key Identifier:
- keyid:E5:9D:59:30:82:47:58:CC:AC:FA:08:54:36:86:7B:3A:B5:04:4D:F0
-
- X509v3 CRL Distribution Points:
-
- Full Name:
- URI:http://cdp1.public-trust.com/CRL/Omniroot2025.crl
-
- X509v3 Subject Key Identifier:
- 51:AF:24:26:9C:F4:68:22:57:80:26:2B:3B:46:62:15:7B:1E:CC:A5
- Signature Algorithm: sha256WithRSAEncryption
- 69:62:f6:84:91:00:c4:6f:82:7b:24:e1:42:a2:a5:8b:82:5c:
- a7:c5:44:cb:e7:52:76:63:d3:76:9e:78:e2:69:35:b1:38:ba:
- b0:96:c6:1f:ac:7b:c6:b2:65:77:8b:7d:8d:ae:64:b9:a5:8c:
- 17:ca:58:65:c3:ad:82:f5:c5:a2:f5:01:13:93:c6:7e:44:e5:
- c4:61:fa:03:b6:56:c1:72:e1:c8:28:c5:69:21:8f:ac:6e:fd:
- 7f:43:83:36:b8:c0:d6:a0:28:fe:1a:45:be:fd:93:8c:8d:a4:
- 64:79:1f:14:db:a1:9f:21:dc:c0:4e:7b:17:22:17:b1:b6:3c:
- d3:9b:e2:0a:a3:7e:99:b0:c1:ac:d8:f4:86:df:3c:da:7d:14:
- 9c:40:c1:7c:d2:18:6f:f1:4f:26:45:09:95:94:5c:da:d0:98:
- f8:f4:4c:82:96:10:de:ac:30:cb:2b:ae:f9:92:ea:bf:79:03:
- fc:1e:3f:ac:09:a4:3f:65:fd:91:4f:96:24:a7:ce:b4:4e:6a:
- 96:29:17:ae:c0:a8:df:17:22:f4:17:e3:dc:1c:39:06:56:10:
- ea:ea:b5:74:17:3c:4e:dd:7e:91:0a:a8:0b:78:07:a7:31:44:
- 08:31:ab:18:84:0f:12:9c:e7:de:84:2c:e9:6d:93:45:bf:a8:
- c1:3f:34:dc
------BEGIN CERTIFICATE-----
-MIIF4TCCBMmgAwIBAgIEByeqRzANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJJ
-RTESMBAGA1UEChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYD
-VQQDExlCYWx0aW1vcmUgQ3liZXJUcnVzdCBSb290MB4XDTE0MDUwNzE3MDQwOVoX
-DTE4MDUwNzE3MDMzMFowgYsxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5n
-dG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9y
-YXRpb24xFTATBgNVBAsTDE1pY3Jvc29mdCBJVDEeMBwGA1UEAxMVTWljcm9zb2Z0
-IElUIFNTTCBTSEEyMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA0eg3
-p3aKcEsZ8CA3CSQ3f+r7eOYFumqtTicN/HJq2WwhxGQRlXMQClwle4hslAT9x9uu
-e9xKCLM+FvHQrdswbdcaHlK1PfBHGQPifaa9VxM/VOo6o7F3/ELwY0lqkYAuMEnA
-iusrr/466wddBvfp/YQOkb0JICnobl0JzhXT5+/bUOtE7xhXqwQdvDH593sqE8/R
-PVGvG8W1e+ew/FO7mudj3kEztkckaV24Rqf/ravfT3p4JSchJjTKAm43UfDtWBpg
-lPbEk9jdMCQl1xzrGZQ1XZOyrqopg3PEdFkFUmed2mdROQU6NuryHnYrFK7sPfkU
-mYsHbrznDFberL6u23UykJ5jvXS/4ArK+DSWZ4TN0UI4eMeZtgzOtg/pG8v0Wb4R
-DsssMsj6gylkeTyLS/AydGzzk7iWa11XWmjBzAx5ihne9UkCXgiAAYkMMs3S1pbV
-S6Dz7L+r9H2zobl82k7X5besufIlXwHLjJaoKK7BM1r2PwiQ3Ov/OdgmyBKdHJqq
-qcAWjobtZ1KWAH8Nkj092XA25epCbx+uleVbXfjQOsfU3neG0PyeTuLiuKloNwnE
-OeOFuInzH263bR9KLxgJb95KAY8Uybem7qdjnzOkVHxCg2i4pd+/7LkaXRM72a1o
-/SAKVZEhZPnXEwGgCF1ZiRtEr6SsxwUQ+kFKqPsCAwEAAaOCAXswggF3MBIGA1Ud
-EwEB/wQIMAYBAf8CAQAwYAYDVR0gBFkwVzBIBgkrBgEEAbE+AQAwOzA5BggrBgEF
-BQcCARYtaHR0cDovL2N5YmVydHJ1c3Qub21uaXJvb3QuY29tL3JlcG9zaXRvcnku
-Y2ZtMAsGCSsGAQQBgjcqATBCBggrBgEFBQcBAQQ2MDQwMgYIKwYBBQUHMAGGJmh0
-dHA6Ly9vY3NwLm9tbmlyb290LmNvbS9iYWx0aW1vcmVyb290MA4GA1UdDwEB/wQE
-AwIBhjAnBgNVHSUEIDAeBggrBgEFBQcDAQYIKwYBBQUHAwIGCCsGAQUFBwMJMB8G
-A1UdIwQYMBaAFOWdWTCCR1jMrPoIVDaGezq1BE3wMEIGA1UdHwQ7MDkwN6A1oDOG
-MWh0dHA6Ly9jZHAxLnB1YmxpYy10cnVzdC5jb20vQ1JML09tbmlyb290MjAyNS5j
-cmwwHQYDVR0OBBYEFFGvJCac9GgiV4AmKztGYhV7HsylMA0GCSqGSIb3DQEBCwUA
-A4IBAQBpYvaEkQDEb4J7JOFCoqWLglynxUTL51J2Y9N2nnjiaTWxOLqwlsYfrHvG
-smV3i32NrmS5pYwXylhlw62C9cWi9QETk8Z+ROXEYfoDtlbBcuHIKMVpIY+sbv1/
-Q4M2uMDWoCj+GkW+/ZOMjaRkeR8U26GfIdzATnsXIhextjzTm+IKo36ZsMGs2PSG
-3zzafRScQMF80hhv8U8mRQmVlFza0Jj49EyClhDerDDLK675kuq/eQP8Hj+sCaQ/
-Zf2RT5Ykp860TmqWKReuwKjfFyL0F+PcHDkGVhDq6rV0FzxO3X6RCqgLeAenMUQI
-MasYhA8SnOfehCzpbZNFv6jBPzTc
------END CERTIFICATE-----
-#endif
-static const unsigned char kDERCert49[] = {
- 0x30, 0x82, 0x05, 0xe1, 0x30, 0x82, 0x04, 0xc9, 0xa0, 0x03, 0x02, 0x01,
- 0x02, 0x02, 0x04, 0x07, 0x27, 0xaa, 0x47, 0x30, 0x0d, 0x06, 0x09, 0x2a,
- 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x5a,
- 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x49,
- 0x45, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x09,
- 0x42, 0x61, 0x6c, 0x74, 0x69, 0x6d, 0x6f, 0x72, 0x65, 0x31, 0x13, 0x30,
- 0x11, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x0a, 0x43, 0x79, 0x62, 0x65,
- 0x72, 0x54, 0x72, 0x75, 0x73, 0x74, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03,
- 0x55, 0x04, 0x03, 0x13, 0x19, 0x42, 0x61, 0x6c, 0x74, 0x69, 0x6d, 0x6f,
- 0x72, 0x65, 0x20, 0x43, 0x79, 0x62, 0x65, 0x72, 0x54, 0x72, 0x75, 0x73,
- 0x74, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x34,
- 0x30, 0x35, 0x30, 0x37, 0x31, 0x37, 0x30, 0x34, 0x30, 0x39, 0x5a, 0x17,
- 0x0d, 0x31, 0x38, 0x30, 0x35, 0x30, 0x37, 0x31, 0x37, 0x30, 0x33, 0x33,
- 0x30, 0x5a, 0x30, 0x81, 0x8b, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55,
- 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03,
- 0x55, 0x04, 0x08, 0x13, 0x0a, 0x57, 0x61, 0x73, 0x68, 0x69, 0x6e, 0x67,
- 0x74, 0x6f, 0x6e, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x07,
- 0x13, 0x07, 0x52, 0x65, 0x64, 0x6d, 0x6f, 0x6e, 0x64, 0x31, 0x1e, 0x30,
- 0x1c, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x15, 0x4d, 0x69, 0x63, 0x72,
- 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x20, 0x43, 0x6f, 0x72, 0x70, 0x6f, 0x72,
- 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55,
- 0x04, 0x0b, 0x13, 0x0c, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66,
- 0x74, 0x20, 0x49, 0x54, 0x31, 0x1e, 0x30, 0x1c, 0x06, 0x03, 0x55, 0x04,
- 0x03, 0x13, 0x15, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74,
- 0x20, 0x49, 0x54, 0x20, 0x53, 0x53, 0x4c, 0x20, 0x53, 0x48, 0x41, 0x32,
- 0x30, 0x82, 0x02, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
- 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x02, 0x0f, 0x00,
- 0x30, 0x82, 0x02, 0x0a, 0x02, 0x82, 0x02, 0x01, 0x00, 0xd1, 0xe8, 0x37,
- 0xa7, 0x76, 0x8a, 0x70, 0x4b, 0x19, 0xf0, 0x20, 0x37, 0x09, 0x24, 0x37,
- 0x7f, 0xea, 0xfb, 0x78, 0xe6, 0x05, 0xba, 0x6a, 0xad, 0x4e, 0x27, 0x0d,
- 0xfc, 0x72, 0x6a, 0xd9, 0x6c, 0x21, 0xc4, 0x64, 0x11, 0x95, 0x73, 0x10,
- 0x0a, 0x5c, 0x25, 0x7b, 0x88, 0x6c, 0x94, 0x04, 0xfd, 0xc7, 0xdb, 0xae,
- 0x7b, 0xdc, 0x4a, 0x08, 0xb3, 0x3e, 0x16, 0xf1, 0xd0, 0xad, 0xdb, 0x30,
- 0x6d, 0xd7, 0x1a, 0x1e, 0x52, 0xb5, 0x3d, 0xf0, 0x47, 0x19, 0x03, 0xe2,
- 0x7d, 0xa6, 0xbd, 0x57, 0x13, 0x3f, 0x54, 0xea, 0x3a, 0xa3, 0xb1, 0x77,
- 0xfc, 0x42, 0xf0, 0x63, 0x49, 0x6a, 0x91, 0x80, 0x2e, 0x30, 0x49, 0xc0,
- 0x8a, 0xeb, 0x2b, 0xaf, 0xfe, 0x3a, 0xeb, 0x07, 0x5d, 0x06, 0xf7, 0xe9,
- 0xfd, 0x84, 0x0e, 0x91, 0xbd, 0x09, 0x20, 0x29, 0xe8, 0x6e, 0x5d, 0x09,
- 0xce, 0x15, 0xd3, 0xe7, 0xef, 0xdb, 0x50, 0xeb, 0x44, 0xef, 0x18, 0x57,
- 0xab, 0x04, 0x1d, 0xbc, 0x31, 0xf9, 0xf7, 0x7b, 0x2a, 0x13, 0xcf, 0xd1,
- 0x3d, 0x51, 0xaf, 0x1b, 0xc5, 0xb5, 0x7b, 0xe7, 0xb0, 0xfc, 0x53, 0xbb,
- 0x9a, 0xe7, 0x63, 0xde, 0x41, 0x33, 0xb6, 0x47, 0x24, 0x69, 0x5d, 0xb8,
- 0x46, 0xa7, 0xff, 0xad, 0xab, 0xdf, 0x4f, 0x7a, 0x78, 0x25, 0x27, 0x21,
- 0x26, 0x34, 0xca, 0x02, 0x6e, 0x37, 0x51, 0xf0, 0xed, 0x58, 0x1a, 0x60,
- 0x94, 0xf6, 0xc4, 0x93, 0xd8, 0xdd, 0x30, 0x24, 0x25, 0xd7, 0x1c, 0xeb,
- 0x19, 0x94, 0x35, 0x5d, 0x93, 0xb2, 0xae, 0xaa, 0x29, 0x83, 0x73, 0xc4,
- 0x74, 0x59, 0x05, 0x52, 0x67, 0x9d, 0xda, 0x67, 0x51, 0x39, 0x05, 0x3a,
- 0x36, 0xea, 0xf2, 0x1e, 0x76, 0x2b, 0x14, 0xae, 0xec, 0x3d, 0xf9, 0x14,
- 0x99, 0x8b, 0x07, 0x6e, 0xbc, 0xe7, 0x0c, 0x56, 0xde, 0xac, 0xbe, 0xae,
- 0xdb, 0x75, 0x32, 0x90, 0x9e, 0x63, 0xbd, 0x74, 0xbf, 0xe0, 0x0a, 0xca,
- 0xf8, 0x34, 0x96, 0x67, 0x84, 0xcd, 0xd1, 0x42, 0x38, 0x78, 0xc7, 0x99,
- 0xb6, 0x0c, 0xce, 0xb6, 0x0f, 0xe9, 0x1b, 0xcb, 0xf4, 0x59, 0xbe, 0x11,
- 0x0e, 0xcb, 0x2c, 0x32, 0xc8, 0xfa, 0x83, 0x29, 0x64, 0x79, 0x3c, 0x8b,
- 0x4b, 0xf0, 0x32, 0x74, 0x6c, 0xf3, 0x93, 0xb8, 0x96, 0x6b, 0x5d, 0x57,
- 0x5a, 0x68, 0xc1, 0xcc, 0x0c, 0x79, 0x8a, 0x19, 0xde, 0xf5, 0x49, 0x02,
- 0x5e, 0x08, 0x80, 0x01, 0x89, 0x0c, 0x32, 0xcd, 0xd2, 0xd6, 0x96, 0xd5,
- 0x4b, 0xa0, 0xf3, 0xec, 0xbf, 0xab, 0xf4, 0x7d, 0xb3, 0xa1, 0xb9, 0x7c,
- 0xda, 0x4e, 0xd7, 0xe5, 0xb7, 0xac, 0xb9, 0xf2, 0x25, 0x5f, 0x01, 0xcb,
- 0x8c, 0x96, 0xa8, 0x28, 0xae, 0xc1, 0x33, 0x5a, 0xf6, 0x3f, 0x08, 0x90,
- 0xdc, 0xeb, 0xff, 0x39, 0xd8, 0x26, 0xc8, 0x12, 0x9d, 0x1c, 0x9a, 0xaa,
- 0xa9, 0xc0, 0x16, 0x8e, 0x86, 0xed, 0x67, 0x52, 0x96, 0x00, 0x7f, 0x0d,
- 0x92, 0x3d, 0x3d, 0xd9, 0x70, 0x36, 0xe5, 0xea, 0x42, 0x6f, 0x1f, 0xae,
- 0x95, 0xe5, 0x5b, 0x5d, 0xf8, 0xd0, 0x3a, 0xc7, 0xd4, 0xde, 0x77, 0x86,
- 0xd0, 0xfc, 0x9e, 0x4e, 0xe2, 0xe2, 0xb8, 0xa9, 0x68, 0x37, 0x09, 0xc4,
- 0x39, 0xe3, 0x85, 0xb8, 0x89, 0xf3, 0x1f, 0x6e, 0xb7, 0x6d, 0x1f, 0x4a,
- 0x2f, 0x18, 0x09, 0x6f, 0xde, 0x4a, 0x01, 0x8f, 0x14, 0xc9, 0xb7, 0xa6,
- 0xee, 0xa7, 0x63, 0x9f, 0x33, 0xa4, 0x54, 0x7c, 0x42, 0x83, 0x68, 0xb8,
- 0xa5, 0xdf, 0xbf, 0xec, 0xb9, 0x1a, 0x5d, 0x13, 0x3b, 0xd9, 0xad, 0x68,
- 0xfd, 0x20, 0x0a, 0x55, 0x91, 0x21, 0x64, 0xf9, 0xd7, 0x13, 0x01, 0xa0,
- 0x08, 0x5d, 0x59, 0x89, 0x1b, 0x44, 0xaf, 0xa4, 0xac, 0xc7, 0x05, 0x10,
- 0xfa, 0x41, 0x4a, 0xa8, 0xfb, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82,
- 0x01, 0x7b, 0x30, 0x82, 0x01, 0x77, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d,
- 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02,
- 0x01, 0x00, 0x30, 0x60, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x59, 0x30,
- 0x57, 0x30, 0x48, 0x06, 0x09, 0x2b, 0x06, 0x01, 0x04, 0x01, 0xb1, 0x3e,
- 0x01, 0x00, 0x30, 0x3b, 0x30, 0x39, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05,
- 0x05, 0x07, 0x02, 0x01, 0x16, 0x2d, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f,
- 0x2f, 0x63, 0x79, 0x62, 0x65, 0x72, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e,
- 0x6f, 0x6d, 0x6e, 0x69, 0x72, 0x6f, 0x6f, 0x74, 0x2e, 0x63, 0x6f, 0x6d,
- 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x2e,
- 0x63, 0x66, 0x6d, 0x30, 0x0b, 0x06, 0x09, 0x2b, 0x06, 0x01, 0x04, 0x01,
- 0x82, 0x37, 0x2a, 0x01, 0x30, 0x42, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05,
- 0x05, 0x07, 0x01, 0x01, 0x04, 0x36, 0x30, 0x34, 0x30, 0x32, 0x06, 0x08,
- 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x26, 0x68, 0x74,
- 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x6f, 0x6d,
- 0x6e, 0x69, 0x72, 0x6f, 0x6f, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x62,
- 0x61, 0x6c, 0x74, 0x69, 0x6d, 0x6f, 0x72, 0x65, 0x72, 0x6f, 0x6f, 0x74,
- 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04,
- 0x03, 0x02, 0x01, 0x86, 0x30, 0x27, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04,
- 0x20, 0x30, 0x1e, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03,
- 0x01, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x02, 0x06,
- 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x09, 0x30, 0x1f, 0x06,
- 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0xe5, 0x9d,
- 0x59, 0x30, 0x82, 0x47, 0x58, 0xcc, 0xac, 0xfa, 0x08, 0x54, 0x36, 0x86,
- 0x7b, 0x3a, 0xb5, 0x04, 0x4d, 0xf0, 0x30, 0x42, 0x06, 0x03, 0x55, 0x1d,
- 0x1f, 0x04, 0x3b, 0x30, 0x39, 0x30, 0x37, 0xa0, 0x35, 0xa0, 0x33, 0x86,
- 0x31, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x64, 0x70, 0x31,
- 0x2e, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x2d, 0x74, 0x72, 0x75, 0x73,
- 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x43, 0x52, 0x4c, 0x2f, 0x4f, 0x6d,
- 0x6e, 0x69, 0x72, 0x6f, 0x6f, 0x74, 0x32, 0x30, 0x32, 0x35, 0x2e, 0x63,
- 0x72, 0x6c, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04,
- 0x14, 0x51, 0xaf, 0x24, 0x26, 0x9c, 0xf4, 0x68, 0x22, 0x57, 0x80, 0x26,
- 0x2b, 0x3b, 0x46, 0x62, 0x15, 0x7b, 0x1e, 0xcc, 0xa5, 0x30, 0x0d, 0x06,
- 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00,
- 0x03, 0x82, 0x01, 0x01, 0x00, 0x69, 0x62, 0xf6, 0x84, 0x91, 0x00, 0xc4,
- 0x6f, 0x82, 0x7b, 0x24, 0xe1, 0x42, 0xa2, 0xa5, 0x8b, 0x82, 0x5c, 0xa7,
- 0xc5, 0x44, 0xcb, 0xe7, 0x52, 0x76, 0x63, 0xd3, 0x76, 0x9e, 0x78, 0xe2,
- 0x69, 0x35, 0xb1, 0x38, 0xba, 0xb0, 0x96, 0xc6, 0x1f, 0xac, 0x7b, 0xc6,
- 0xb2, 0x65, 0x77, 0x8b, 0x7d, 0x8d, 0xae, 0x64, 0xb9, 0xa5, 0x8c, 0x17,
- 0xca, 0x58, 0x65, 0xc3, 0xad, 0x82, 0xf5, 0xc5, 0xa2, 0xf5, 0x01, 0x13,
- 0x93, 0xc6, 0x7e, 0x44, 0xe5, 0xc4, 0x61, 0xfa, 0x03, 0xb6, 0x56, 0xc1,
- 0x72, 0xe1, 0xc8, 0x28, 0xc5, 0x69, 0x21, 0x8f, 0xac, 0x6e, 0xfd, 0x7f,
- 0x43, 0x83, 0x36, 0xb8, 0xc0, 0xd6, 0xa0, 0x28, 0xfe, 0x1a, 0x45, 0xbe,
- 0xfd, 0x93, 0x8c, 0x8d, 0xa4, 0x64, 0x79, 0x1f, 0x14, 0xdb, 0xa1, 0x9f,
- 0x21, 0xdc, 0xc0, 0x4e, 0x7b, 0x17, 0x22, 0x17, 0xb1, 0xb6, 0x3c, 0xd3,
- 0x9b, 0xe2, 0x0a, 0xa3, 0x7e, 0x99, 0xb0, 0xc1, 0xac, 0xd8, 0xf4, 0x86,
- 0xdf, 0x3c, 0xda, 0x7d, 0x14, 0x9c, 0x40, 0xc1, 0x7c, 0xd2, 0x18, 0x6f,
- 0xf1, 0x4f, 0x26, 0x45, 0x09, 0x95, 0x94, 0x5c, 0xda, 0xd0, 0x98, 0xf8,
- 0xf4, 0x4c, 0x82, 0x96, 0x10, 0xde, 0xac, 0x30, 0xcb, 0x2b, 0xae, 0xf9,
- 0x92, 0xea, 0xbf, 0x79, 0x03, 0xfc, 0x1e, 0x3f, 0xac, 0x09, 0xa4, 0x3f,
- 0x65, 0xfd, 0x91, 0x4f, 0x96, 0x24, 0xa7, 0xce, 0xb4, 0x4e, 0x6a, 0x96,
- 0x29, 0x17, 0xae, 0xc0, 0xa8, 0xdf, 0x17, 0x22, 0xf4, 0x17, 0xe3, 0xdc,
- 0x1c, 0x39, 0x06, 0x56, 0x10, 0xea, 0xea, 0xb5, 0x74, 0x17, 0x3c, 0x4e,
- 0xdd, 0x7e, 0x91, 0x0a, 0xa8, 0x0b, 0x78, 0x07, 0xa7, 0x31, 0x44, 0x08,
- 0x31, 0xab, 0x18, 0x84, 0x0f, 0x12, 0x9c, 0xe7, 0xde, 0x84, 0x2c, 0xe9,
- 0x6d, 0x93, 0x45, 0xbf, 0xa8, 0xc1, 0x3f, 0x34, 0xdc,
-};
-
-#if 0
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number:
- 13:8b:fe:f3:32:94:f9:d8:16:f9:45:c2:71:95:29:98
- Signature Algorithm: sha256WithRSAEncryption
- Issuer: C=IL, O=StartCom Ltd., OU=Secure Digital Certificate Signing, CN=StartCom Certification Authority
- Validity
- Not Before: Dec 16 01:00:05 2015 GMT
- Not After : Dec 16 01:00:05 2030 GMT
- Subject: C=IL, O=StartCom Ltd., OU=StartCom Certification Authority, CN=StartCom Class 3 OV Server CA
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:af:67:1c:6f:e5:45:e0:d7:46:4b:75:2c:b6:80:
- f2:9a:17:4d:2d:ff:de:ae:d2:d4:00:8a:3a:b8:31:
- fe:8e:37:9e:fa:aa:d5:a3:5b:16:12:c1:19:3e:34:
- 85:96:c3:be:d3:b3:43:f4:8d:6f:16:bd:30:ba:07:
- fc:d8:9a:c1:79:89:80:6d:a0:8c:be:dd:37:f7:eb:
- 05:d3:53:7f:57:58:76:55:b6:a8:a8:86:44:b8:bb:
- d0:13:da:fd:8f:e1:f2:cd:a0:15:38:55:56:ce:26:
- cf:7c:93:75:29:7a:0a:ab:fb:ba:09:38:20:11:57:
- 07:5d:7f:49:9f:2a:4a:67:1e:9e:58:e9:c7:7f:f9:
- c3:ed:fe:5f:4d:af:b8:4f:9d:df:69:2d:69:1b:3a:
- 58:81:69:63:30:ea:87:8d:0f:52:9d:5a:da:39:44:
- ba:9f:89:9f:36:b6:c2:19:5c:d9:26:78:d9:ae:5e:
- fc:95:90:bf:e8:11:c0:47:0f:77:89:dd:6a:28:4f:
- 0a:bc:32:64:57:43:3d:08:65:93:e5:45:ae:dd:28:
- 0c:27:2c:8e:a6:2b:09:03:5d:a1:78:d2:8c:ab:b6:
- 6b:b9:46:c9:19:00:39:b9:bf:c6:13:2b:73:72:1f:
- f2:3e:37:b8:e8:b9:14:65:88:4d:e2:f1:1b:d8:a5:
- 1d:3b
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Key Usage: critical
- Certificate Sign, CRL Sign
- X509v3 Extended Key Usage:
- TLS Web Client Authentication, TLS Web Server Authentication
- X509v3 Basic Constraints: critical
- CA:TRUE, pathlen:0
- X509v3 CRL Distribution Points:
-
- Full Name:
- URI:http://crl.startssl.com/sfsca.crl
-
- Authority Information Access:
- OCSP - URI:http://ocsp.startssl.com
- CA Issuers - URI:http://aia.startssl.com/certs/ca.crt
-
- X509v3 Subject Key Identifier:
- B1:3F:1C:92:7B:92:B0:5A:25:B3:38:FB:9C:07:A4:26:50:32:E3:51
- X509v3 Authority Key Identifier:
- keyid:4E:0B:EF:1A:A4:40:5B:A5:17:69:87:30:CA:34:68:43:D0:41:AE:F2
-
- X509v3 Certificate Policies:
- Policy: X509v3 Any Policy
- CPS: http://www.startssl.com/policy
-
- Signature Algorithm: sha256WithRSAEncryption
- 85:f2:e8:14:d3:1b:c1:a1:16:1d:a4:f4:4d:ba:51:8b:5c:52:
- b1:54:54:12:16:17:9c:96:78:6f:d3:bf:df:43:36:f5:12:89:
- 61:72:44:df:1c:9b:09:4f:60:26:68:c1:e6:66:50:70:b3:6a:
- f1:a8:6a:0c:1e:2e:93:f1:ee:07:3e:09:dd:30:45:b2:56:8e:
- dc:2c:5c:ab:49:fa:b9:04:03:40:15:7a:b5:30:e0:1d:91:8f:
- a6:d6:6f:1f:99:a0:84:95:39:bd:ac:77:7f:72:4b:dd:2d:ae:
- ff:a8:58:1d:46:27:d4:83:c7:69:64:9f:19:bb:10:f8:04:42:
- 87:59:5d:02:b1:d6:e5:c8:da:43:30:a3:e8:37:a5:d2:48:0b:
- a2:83:4e:9d:4f:83:58:9d:d7:47:22:b1:89:f0:89:3b:3d:28:
- 43:2c:9b:17:7c:03:ee:9d:26:25:e0:04:b8:1d:04:57:42:47:
- da:58:69:f0:d3:29:ab:12:02:99:2b:2a:d8:9d:a0:1f:54:5e:
- 23:9a:0c:d2:99:58:c4:a1:e5:49:c2:25:a7:64:20:52:2e:e7:
- 89:f5:19:c0:8b:d0:63:b1:78:1e:be:01:47:be:76:81:46:f1:
- 99:1f:94:9a:be:fa:82:15:b5:84:84:79:75:93:ba:9f:b5:e4:
- 9b:c2:cb:69:5c:bd:1f:55:0a:a7:26:30:05:51:be:65:ee:57:
- a9:6a:df:bd:f9:36:2f:ad:1e:46:41:2b:b1:88:d0:88:25:85:
- 40:17:79:bf:3d:8d:e2:f4:2d:ea:30:31:df:a1:40:cb:35:ff:
- 82:9f:f5:99:3c:4a:fd:9d:a1:d1:55:cc:20:a8:1c:d8:20:05:
- ab:b3:14:65:95:53:d8:e8:8e:57:c5:77:6b:2d:4d:88:e9:5d:
- 62:d5:a2:f8:70:e1:70:eb:45:23:0e:f0:00:46:c2:48:31:e8:
- e7:36:80:36:2d:22:f2:01:27:53:eb:ce:a7:69:49:82:bf:e7:
- 0f:9c:f3:20:2e:f5:fa:5d:ce:ea:58:3a:8f:d8:aa:7d:30:b7:
- 74:96:7c:3d:6e:b4:ec:4a:3b:59:b6:a9:50:0d:0f:05:06:70:
- 26:b9:95:91:d1:5e:24:8c:8f:ca:74:57:97:90:8b:5a:b7:fe:
- 8d:ad:d8:e8:c2:06:bc:08:56:21:02:12:53:c6:9f:86:04:58:
- ca:2d:f8:03:0d:57:0b:1c:37:bd:f0:5a:35:f2:fe:3b:d6:a4:
- 37:15:e9:f8:08:92:96:3d:74:c8:b5:5c:6e:65:08:e7:df:69:
- 73:9c:ec:e3:30:5a:a6:df:5c:be:da:7f:00:ee:a5:da:2b:5c:
- 1e:2a:6a:c0:a3:ae:1e:f1
------BEGIN CERTIFICATE-----
-MIIF5TCCA82gAwIBAgIQE4v+8zKU+dgW+UXCcZUpmDANBgkqhkiG9w0BAQsFADB9
-MQswCQYDVQQGEwJJTDEWMBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMi
-U2VjdXJlIERpZ2l0YWwgQ2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3Rh
-cnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTUxMjE2MDEwMDA1WhcN
-MzAxMjE2MDEwMDA1WjB4MQswCQYDVQQGEwJJTDEWMBQGA1UEChMNU3RhcnRDb20g
-THRkLjEpMCcGA1UECxMgU3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkx
-JjAkBgNVBAMTHVN0YXJ0Q29tIENsYXNzIDMgT1YgU2VydmVyIENBMIIBIjANBgkq
-hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAr2ccb+VF4NdGS3UstoDymhdNLf/ertLU
-AIo6uDH+jjee+qrVo1sWEsEZPjSFlsO+07ND9I1vFr0wugf82JrBeYmAbaCMvt03
-9+sF01N/V1h2VbaoqIZEuLvQE9r9j+HyzaAVOFVWzibPfJN1KXoKq/u6CTggEVcH
-XX9JnypKZx6eWOnHf/nD7f5fTa+4T53faS1pGzpYgWljMOqHjQ9SnVraOUS6n4mf
-NrbCGVzZJnjZrl78lZC/6BHARw93id1qKE8KvDJkV0M9CGWT5UWu3SgMJyyOpisJ
-A12heNKMq7ZruUbJGQA5ub/GEytzch/yPje46LkUZYhN4vEb2KUdOwIDAQABo4IB
-ZDCCAWAwDgYDVR0PAQH/BAQDAgEGMB0GA1UdJQQWMBQGCCsGAQUFBwMCBggrBgEF
-BQcDATASBgNVHRMBAf8ECDAGAQH/AgEAMDIGA1UdHwQrMCkwJ6AloCOGIWh0dHA6
-Ly9jcmwuc3RhcnRzc2wuY29tL3Nmc2NhLmNybDBmBggrBgEFBQcBAQRaMFgwJAYI
-KwYBBQUHMAGGGGh0dHA6Ly9vY3NwLnN0YXJ0c3NsLmNvbTAwBggrBgEFBQcwAoYk
-aHR0cDovL2FpYS5zdGFydHNzbC5jb20vY2VydHMvY2EuY3J0MB0GA1UdDgQWBBSx
-PxySe5KwWiWzOPucB6QmUDLjUTAfBgNVHSMEGDAWgBROC+8apEBbpRdphzDKNGhD
-0EGu8jA/BgNVHSAEODA2MDQGBFUdIAAwLDAqBggrBgEFBQcCARYeaHR0cDovL3d3
-dy5zdGFydHNzbC5jb20vcG9saWN5MA0GCSqGSIb3DQEBCwUAA4ICAQCF8ugU0xvB
-oRYdpPRNulGLXFKxVFQSFheclnhv07/fQzb1EolhckTfHJsJT2AmaMHmZlBws2rx
-qGoMHi6T8e4HPgndMEWyVo7cLFyrSfq5BANAFXq1MOAdkY+m1m8fmaCElTm9rHd/
-ckvdLa7/qFgdRifUg8dpZJ8ZuxD4BEKHWV0CsdblyNpDMKPoN6XSSAuig06dT4NY
-nddHIrGJ8Ik7PShDLJsXfAPunSYl4AS4HQRXQkfaWGnw0ymrEgKZKyrYnaAfVF4j
-mgzSmVjEoeVJwiWnZCBSLueJ9RnAi9BjsXgevgFHvnaBRvGZH5SavvqCFbWEhHl1
-k7qfteSbwstpXL0fVQqnJjAFUb5l7lepat+9+TYvrR5GQSuxiNCIJYVAF3m/PY3i
-9C3qMDHfoUDLNf+Cn/WZPEr9naHRVcwgqBzYIAWrsxRllVPY6I5XxXdrLU2I6V1i
-1aL4cOFw60UjDvAARsJIMejnNoA2LSLyASdT686naUmCv+cPnPMgLvX6Xc7qWDqP
-2Kp9MLd0lnw9brTsSjtZtqlQDQ8FBnAmuZWR0V4kjI/KdFeXkItat/6Nrdjowga8
-CFYhAhJTxp+GBFjKLfgDDVcLHDe98Fo18v471qQ3Fen4CJKWPXTItVxuZQjn32lz
-nOzjMFqm31y+2n8A7qXaK1weKmrAo64e8Q==
------END CERTIFICATE-----
-#endif
-static const unsigned char kDERCert50[] = {
- 0x30, 0x82, 0x05, 0xe5, 0x30, 0x82, 0x03, 0xcd, 0xa0, 0x03, 0x02, 0x01,
- 0x02, 0x02, 0x10, 0x13, 0x8b, 0xfe, 0xf3, 0x32, 0x94, 0xf9, 0xd8, 0x16,
- 0xf9, 0x45, 0xc2, 0x71, 0x95, 0x29, 0x98, 0x30, 0x0d, 0x06, 0x09, 0x2a,
- 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x7d,
- 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x49,
- 0x4c, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0d,
- 0x53, 0x74, 0x61, 0x72, 0x74, 0x43, 0x6f, 0x6d, 0x20, 0x4c, 0x74, 0x64,
- 0x2e, 0x31, 0x2b, 0x30, 0x29, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x22,
- 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x44, 0x69, 0x67, 0x69, 0x74,
- 0x61, 0x6c, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61,
- 0x74, 0x65, 0x20, 0x53, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x31, 0x29,
- 0x30, 0x27, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x20, 0x53, 0x74, 0x61,
- 0x72, 0x74, 0x43, 0x6f, 0x6d, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66,
- 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68,
- 0x6f, 0x72, 0x69, 0x74, 0x79, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x35, 0x31,
- 0x32, 0x31, 0x36, 0x30, 0x31, 0x30, 0x30, 0x30, 0x35, 0x5a, 0x17, 0x0d,
- 0x33, 0x30, 0x31, 0x32, 0x31, 0x36, 0x30, 0x31, 0x30, 0x30, 0x30, 0x35,
- 0x5a, 0x30, 0x78, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06,
- 0x13, 0x02, 0x49, 0x4c, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04,
- 0x0a, 0x13, 0x0d, 0x53, 0x74, 0x61, 0x72, 0x74, 0x43, 0x6f, 0x6d, 0x20,
- 0x4c, 0x74, 0x64, 0x2e, 0x31, 0x29, 0x30, 0x27, 0x06, 0x03, 0x55, 0x04,
- 0x0b, 0x13, 0x20, 0x53, 0x74, 0x61, 0x72, 0x74, 0x43, 0x6f, 0x6d, 0x20,
- 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f,
- 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31,
- 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x1d, 0x53, 0x74,
- 0x61, 0x72, 0x74, 0x43, 0x6f, 0x6d, 0x20, 0x43, 0x6c, 0x61, 0x73, 0x73,
- 0x20, 0x33, 0x20, 0x4f, 0x56, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72,
- 0x20, 0x43, 0x41, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a,
- 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82,
- 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00,
- 0xaf, 0x67, 0x1c, 0x6f, 0xe5, 0x45, 0xe0, 0xd7, 0x46, 0x4b, 0x75, 0x2c,
- 0xb6, 0x80, 0xf2, 0x9a, 0x17, 0x4d, 0x2d, 0xff, 0xde, 0xae, 0xd2, 0xd4,
- 0x00, 0x8a, 0x3a, 0xb8, 0x31, 0xfe, 0x8e, 0x37, 0x9e, 0xfa, 0xaa, 0xd5,
- 0xa3, 0x5b, 0x16, 0x12, 0xc1, 0x19, 0x3e, 0x34, 0x85, 0x96, 0xc3, 0xbe,
- 0xd3, 0xb3, 0x43, 0xf4, 0x8d, 0x6f, 0x16, 0xbd, 0x30, 0xba, 0x07, 0xfc,
- 0xd8, 0x9a, 0xc1, 0x79, 0x89, 0x80, 0x6d, 0xa0, 0x8c, 0xbe, 0xdd, 0x37,
- 0xf7, 0xeb, 0x05, 0xd3, 0x53, 0x7f, 0x57, 0x58, 0x76, 0x55, 0xb6, 0xa8,
- 0xa8, 0x86, 0x44, 0xb8, 0xbb, 0xd0, 0x13, 0xda, 0xfd, 0x8f, 0xe1, 0xf2,
- 0xcd, 0xa0, 0x15, 0x38, 0x55, 0x56, 0xce, 0x26, 0xcf, 0x7c, 0x93, 0x75,
- 0x29, 0x7a, 0x0a, 0xab, 0xfb, 0xba, 0x09, 0x38, 0x20, 0x11, 0x57, 0x07,
- 0x5d, 0x7f, 0x49, 0x9f, 0x2a, 0x4a, 0x67, 0x1e, 0x9e, 0x58, 0xe9, 0xc7,
- 0x7f, 0xf9, 0xc3, 0xed, 0xfe, 0x5f, 0x4d, 0xaf, 0xb8, 0x4f, 0x9d, 0xdf,
- 0x69, 0x2d, 0x69, 0x1b, 0x3a, 0x58, 0x81, 0x69, 0x63, 0x30, 0xea, 0x87,
- 0x8d, 0x0f, 0x52, 0x9d, 0x5a, 0xda, 0x39, 0x44, 0xba, 0x9f, 0x89, 0x9f,
- 0x36, 0xb6, 0xc2, 0x19, 0x5c, 0xd9, 0x26, 0x78, 0xd9, 0xae, 0x5e, 0xfc,
- 0x95, 0x90, 0xbf, 0xe8, 0x11, 0xc0, 0x47, 0x0f, 0x77, 0x89, 0xdd, 0x6a,
- 0x28, 0x4f, 0x0a, 0xbc, 0x32, 0x64, 0x57, 0x43, 0x3d, 0x08, 0x65, 0x93,
- 0xe5, 0x45, 0xae, 0xdd, 0x28, 0x0c, 0x27, 0x2c, 0x8e, 0xa6, 0x2b, 0x09,
- 0x03, 0x5d, 0xa1, 0x78, 0xd2, 0x8c, 0xab, 0xb6, 0x6b, 0xb9, 0x46, 0xc9,
- 0x19, 0x00, 0x39, 0xb9, 0xbf, 0xc6, 0x13, 0x2b, 0x73, 0x72, 0x1f, 0xf2,
- 0x3e, 0x37, 0xb8, 0xe8, 0xb9, 0x14, 0x65, 0x88, 0x4d, 0xe2, 0xf1, 0x1b,
- 0xd8, 0xa5, 0x1d, 0x3b, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01,
- 0x64, 0x30, 0x82, 0x01, 0x60, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f,
- 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x1d, 0x06,
- 0x03, 0x55, 0x1d, 0x25, 0x04, 0x16, 0x30, 0x14, 0x06, 0x08, 0x2b, 0x06,
- 0x01, 0x05, 0x05, 0x07, 0x03, 0x02, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05,
- 0x05, 0x07, 0x03, 0x01, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01,
- 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x00,
- 0x30, 0x32, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x2b, 0x30, 0x29, 0x30,
- 0x27, 0xa0, 0x25, 0xa0, 0x23, 0x86, 0x21, 0x68, 0x74, 0x74, 0x70, 0x3a,
- 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x73, 0x74, 0x61, 0x72, 0x74, 0x73,
- 0x73, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x73, 0x66, 0x73, 0x63, 0x61,
- 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x66, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05,
- 0x05, 0x07, 0x01, 0x01, 0x04, 0x5a, 0x30, 0x58, 0x30, 0x24, 0x06, 0x08,
- 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x18, 0x68, 0x74,
- 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x73, 0x74,
- 0x61, 0x72, 0x74, 0x73, 0x73, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x30,
- 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x24,
- 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x61, 0x69, 0x61, 0x2e, 0x73,
- 0x74, 0x61, 0x72, 0x74, 0x73, 0x73, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x2f,
- 0x63, 0x65, 0x72, 0x74, 0x73, 0x2f, 0x63, 0x61, 0x2e, 0x63, 0x72, 0x74,
- 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xb1,
- 0x3f, 0x1c, 0x92, 0x7b, 0x92, 0xb0, 0x5a, 0x25, 0xb3, 0x38, 0xfb, 0x9c,
- 0x07, 0xa4, 0x26, 0x50, 0x32, 0xe3, 0x51, 0x30, 0x1f, 0x06, 0x03, 0x55,
- 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x4e, 0x0b, 0xef, 0x1a,
- 0xa4, 0x40, 0x5b, 0xa5, 0x17, 0x69, 0x87, 0x30, 0xca, 0x34, 0x68, 0x43,
- 0xd0, 0x41, 0xae, 0xf2, 0x30, 0x3f, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04,
- 0x38, 0x30, 0x36, 0x30, 0x34, 0x06, 0x04, 0x55, 0x1d, 0x20, 0x00, 0x30,
- 0x2c, 0x30, 0x2a, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02,
- 0x01, 0x16, 0x1e, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77,
- 0x77, 0x2e, 0x73, 0x74, 0x61, 0x72, 0x74, 0x73, 0x73, 0x6c, 0x2e, 0x63,
- 0x6f, 0x6d, 0x2f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x30, 0x0d, 0x06,
- 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00,
- 0x03, 0x82, 0x02, 0x01, 0x00, 0x85, 0xf2, 0xe8, 0x14, 0xd3, 0x1b, 0xc1,
- 0xa1, 0x16, 0x1d, 0xa4, 0xf4, 0x4d, 0xba, 0x51, 0x8b, 0x5c, 0x52, 0xb1,
- 0x54, 0x54, 0x12, 0x16, 0x17, 0x9c, 0x96, 0x78, 0x6f, 0xd3, 0xbf, 0xdf,
- 0x43, 0x36, 0xf5, 0x12, 0x89, 0x61, 0x72, 0x44, 0xdf, 0x1c, 0x9b, 0x09,
- 0x4f, 0x60, 0x26, 0x68, 0xc1, 0xe6, 0x66, 0x50, 0x70, 0xb3, 0x6a, 0xf1,
- 0xa8, 0x6a, 0x0c, 0x1e, 0x2e, 0x93, 0xf1, 0xee, 0x07, 0x3e, 0x09, 0xdd,
- 0x30, 0x45, 0xb2, 0x56, 0x8e, 0xdc, 0x2c, 0x5c, 0xab, 0x49, 0xfa, 0xb9,
- 0x04, 0x03, 0x40, 0x15, 0x7a, 0xb5, 0x30, 0xe0, 0x1d, 0x91, 0x8f, 0xa6,
- 0xd6, 0x6f, 0x1f, 0x99, 0xa0, 0x84, 0x95, 0x39, 0xbd, 0xac, 0x77, 0x7f,
- 0x72, 0x4b, 0xdd, 0x2d, 0xae, 0xff, 0xa8, 0x58, 0x1d, 0x46, 0x27, 0xd4,
- 0x83, 0xc7, 0x69, 0x64, 0x9f, 0x19, 0xbb, 0x10, 0xf8, 0x04, 0x42, 0x87,
- 0x59, 0x5d, 0x02, 0xb1, 0xd6, 0xe5, 0xc8, 0xda, 0x43, 0x30, 0xa3, 0xe8,
- 0x37, 0xa5, 0xd2, 0x48, 0x0b, 0xa2, 0x83, 0x4e, 0x9d, 0x4f, 0x83, 0x58,
- 0x9d, 0xd7, 0x47, 0x22, 0xb1, 0x89, 0xf0, 0x89, 0x3b, 0x3d, 0x28, 0x43,
- 0x2c, 0x9b, 0x17, 0x7c, 0x03, 0xee, 0x9d, 0x26, 0x25, 0xe0, 0x04, 0xb8,
- 0x1d, 0x04, 0x57, 0x42, 0x47, 0xda, 0x58, 0x69, 0xf0, 0xd3, 0x29, 0xab,
- 0x12, 0x02, 0x99, 0x2b, 0x2a, 0xd8, 0x9d, 0xa0, 0x1f, 0x54, 0x5e, 0x23,
- 0x9a, 0x0c, 0xd2, 0x99, 0x58, 0xc4, 0xa1, 0xe5, 0x49, 0xc2, 0x25, 0xa7,
- 0x64, 0x20, 0x52, 0x2e, 0xe7, 0x89, 0xf5, 0x19, 0xc0, 0x8b, 0xd0, 0x63,
- 0xb1, 0x78, 0x1e, 0xbe, 0x01, 0x47, 0xbe, 0x76, 0x81, 0x46, 0xf1, 0x99,
- 0x1f, 0x94, 0x9a, 0xbe, 0xfa, 0x82, 0x15, 0xb5, 0x84, 0x84, 0x79, 0x75,
- 0x93, 0xba, 0x9f, 0xb5, 0xe4, 0x9b, 0xc2, 0xcb, 0x69, 0x5c, 0xbd, 0x1f,
- 0x55, 0x0a, 0xa7, 0x26, 0x30, 0x05, 0x51, 0xbe, 0x65, 0xee, 0x57, 0xa9,
- 0x6a, 0xdf, 0xbd, 0xf9, 0x36, 0x2f, 0xad, 0x1e, 0x46, 0x41, 0x2b, 0xb1,
- 0x88, 0xd0, 0x88, 0x25, 0x85, 0x40, 0x17, 0x79, 0xbf, 0x3d, 0x8d, 0xe2,
- 0xf4, 0x2d, 0xea, 0x30, 0x31, 0xdf, 0xa1, 0x40, 0xcb, 0x35, 0xff, 0x82,
- 0x9f, 0xf5, 0x99, 0x3c, 0x4a, 0xfd, 0x9d, 0xa1, 0xd1, 0x55, 0xcc, 0x20,
- 0xa8, 0x1c, 0xd8, 0x20, 0x05, 0xab, 0xb3, 0x14, 0x65, 0x95, 0x53, 0xd8,
- 0xe8, 0x8e, 0x57, 0xc5, 0x77, 0x6b, 0x2d, 0x4d, 0x88, 0xe9, 0x5d, 0x62,
- 0xd5, 0xa2, 0xf8, 0x70, 0xe1, 0x70, 0xeb, 0x45, 0x23, 0x0e, 0xf0, 0x00,
- 0x46, 0xc2, 0x48, 0x31, 0xe8, 0xe7, 0x36, 0x80, 0x36, 0x2d, 0x22, 0xf2,
- 0x01, 0x27, 0x53, 0xeb, 0xce, 0xa7, 0x69, 0x49, 0x82, 0xbf, 0xe7, 0x0f,
- 0x9c, 0xf3, 0x20, 0x2e, 0xf5, 0xfa, 0x5d, 0xce, 0xea, 0x58, 0x3a, 0x8f,
- 0xd8, 0xaa, 0x7d, 0x30, 0xb7, 0x74, 0x96, 0x7c, 0x3d, 0x6e, 0xb4, 0xec,
- 0x4a, 0x3b, 0x59, 0xb6, 0xa9, 0x50, 0x0d, 0x0f, 0x05, 0x06, 0x70, 0x26,
- 0xb9, 0x95, 0x91, 0xd1, 0x5e, 0x24, 0x8c, 0x8f, 0xca, 0x74, 0x57, 0x97,
- 0x90, 0x8b, 0x5a, 0xb7, 0xfe, 0x8d, 0xad, 0xd8, 0xe8, 0xc2, 0x06, 0xbc,
- 0x08, 0x56, 0x21, 0x02, 0x12, 0x53, 0xc6, 0x9f, 0x86, 0x04, 0x58, 0xca,
- 0x2d, 0xf8, 0x03, 0x0d, 0x57, 0x0b, 0x1c, 0x37, 0xbd, 0xf0, 0x5a, 0x35,
- 0xf2, 0xfe, 0x3b, 0xd6, 0xa4, 0x37, 0x15, 0xe9, 0xf8, 0x08, 0x92, 0x96,
- 0x3d, 0x74, 0xc8, 0xb5, 0x5c, 0x6e, 0x65, 0x08, 0xe7, 0xdf, 0x69, 0x73,
- 0x9c, 0xec, 0xe3, 0x30, 0x5a, 0xa6, 0xdf, 0x5c, 0xbe, 0xda, 0x7f, 0x00,
- 0xee, 0xa5, 0xda, 0x2b, 0x5c, 0x1e, 0x2a, 0x6a, 0xc0, 0xa3, 0xae, 0x1e,
- 0xf1,
-};
-
-#if 0
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number: 7250751724796726 (0x19c28530e93b36)
- Signature Algorithm: sha256WithRSAEncryption
- Issuer: C=IL, O=StartCom Ltd., OU=Secure Digital Certificate Signing, CN=StartCom Certification Authority
- Validity
- Not Before: Sep 17 22:46:36 2006 GMT
- Not After : Dec 31 23:59:59 2019 GMT
- Subject: C=CN, O=WoSign CA Limited, CN=Certification Authority of WoSign
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (4096 bit)
- Modulus:
- 00:bd:ca:8d:ac:b8:91:15:56:97:7b:6b:5c:7a:c2:
- de:6b:d9:a1:b0:c3:10:23:fa:a7:a1:b2:cc:31:fa:
- 3e:d9:a6:29:6f:16:3d:e0:6b:f8:b8:40:5f:db:39:
- a8:00:7a:8b:a0:4d:54:7d:c2:22:78:fc:8e:09:b8:
- a8:85:d7:cc:95:97:4b:74:d8:9e:7e:f0:00:e4:0e:
- 89:ae:49:28:44:1a:10:99:32:0f:25:88:53:a4:0d:
- b3:0f:12:08:16:0b:03:71:27:1c:7f:e1:db:d2:fd:
- 67:68:c4:05:5d:0a:0e:5d:70:d7:d8:97:a0:bc:53:
- 41:9a:91:8d:f4:9e:36:66:7a:7e:56:c1:90:5f:e6:
- b1:68:20:36:a4:8c:24:2c:2c:47:0b:59:76:66:30:
- b5:be:de:ed:8f:f8:9d:d3:bb:01:30:e6:f2:f3:0e:
- e0:2c:92:80:f3:85:f9:28:8a:b4:54:2e:9a:ed:f7:
- 76:fc:15:68:16:eb:4a:6c:eb:2e:12:8f:d4:cf:fe:
- 0c:c7:5c:1d:0b:7e:05:32:be:5e:b0:09:2a:42:d5:
- c9:4e:90:b3:59:0d:bb:7a:7e:cd:d5:08:5a:b4:7f:
- d8:1c:69:11:f9:27:0f:7b:06:af:54:83:18:7b:e1:
- dd:54:7a:51:68:6e:77:fc:c6:bf:52:4a:66:46:a1:
- b2:67:1a:bb:a3:4f:77:a0:be:5d:ff:fc:56:0b:43:
- 72:77:90:ca:9e:f9:f2:39:f5:0d:a9:f4:ea:d7:e7:
- b3:10:2f:30:42:37:21:cc:30:70:c9:86:98:0f:cc:
- 58:4d:83:bb:7d:e5:1a:a5:37:8d:b6:ac:32:97:00:
- 3a:63:71:24:1e:9e:37:c4:ff:74:d4:37:c0:e2:fe:
- 88:46:60:11:dd:08:3f:50:36:ab:b8:7a:a4:95:62:
- 6a:6e:b0:ca:6a:21:5a:69:f3:f3:fb:1d:70:39:95:
- f3:a7:6e:a6:81:89:a1:88:c5:3b:71:ca:a3:52:ee:
- 83:bb:fd:a0:77:f4:e4:6f:e7:42:db:6d:4a:99:8a:
- 34:48:bc:17:dc:e4:80:08:22:b6:f2:31:c0:3f:04:
- 3e:eb:9f:20:79:d6:b8:06:64:64:02:31:d7:a9:cd:
- 52:fb:84:45:69:09:00:2a:dc:55:8b:c4:06:46:4b:
- c0:4a:1d:09:5b:39:28:fd:a9:ab:ce:00:f9:2e:48:
- 4b:26:e6:30:4c:a5:58:ca:b4:44:82:4f:e7:91:1e:
- 33:c3:b0:93:ff:11:fc:81:d2:ca:1f:71:29:dd:76:
- 4f:92:25:af:1d:81:b7:0f:2f:8c:c3:06:cc:2f:27:
- a3:4a:e4:0e:99:ba:7c:1e:45:1f:7f:aa:19:45:96:
- fd:fc:3d
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Basic Constraints: critical
- CA:TRUE, pathlen:2
- X509v3 Key Usage: critical
- Certificate Sign, CRL Sign
- X509v3 Subject Key Identifier:
- E1:66:CF:0E:D1:F1:B3:4B:B7:06:20:14:FE:87:12:D5:F6:FE:FB:3E
- X509v3 Authority Key Identifier:
- keyid:4E:0B:EF:1A:A4:40:5B:A5:17:69:87:30:CA:34:68:43:D0:41:AE:F2
-
- Authority Information Access:
- OCSP - URI:http://ocsp.startssl.com/ca
- CA Issuers - URI:http://aia.startssl.com/certs/ca.crt
-
- X509v3 CRL Distribution Points:
-
- Full Name:
- URI:http://crl.startssl.com/sfsca.crl
-
- Signature Algorithm: sha256WithRSAEncryption
- b6:6d:f8:70:fb:e2:0d:4c:98:b3:07:49:15:f5:04:c4:6c:ca:
- ca:f5:68:a0:08:fe:12:6d:9c:04:06:c9:ad:9a:91:52:3e:78:
- c4:5c:ee:9f:54:1d:ee:e3:f1:5e:30:c9:49:e1:39:e0:a6:9d:
- 36:6c:57:fa:e6:34:4f:55:e8:87:a8:2c:dd:05:f1:58:12:91:
- e8:ca:ce:28:78:8f:df:07:85:01:a5:dc:45:96:05:d4:80:b2:
- 2b:05:9a:cb:9a:a5:8b:e0:3a:67:e6:73:47:be:4a:fd:27:b1:
- 88:ef:e6:ca:cf:8d:0e:26:9f:fa:5f:57:78:ad:6d:fe:ae:9b:
- 35:08:b1:c3:ba:c1:00:4a:4b:7d:14:bd:f7:f1:d3:55:18:ac:
- d0:33:70:88:6d:c4:09:71:14:a6:2b:4f:88:81:e7:0b:00:37:
- a9:15:7d:7e:d7:01:96:3f:2f:af:7b:62:ae:0a:4a:bf:4b:39:
- 2e:35:10:8b:fe:04:39:e4:3c:3a:0c:09:56:40:3a:b5:f4:c2:
- 68:0c:b5:f9:52:cd:ee:9d:f8:98:fc:78:e7:58:47:8f:1c:73:
- 58:69:33:ab:ff:dd:df:8e:24:01:77:98:19:3a:b0:66:79:bc:
- e1:08:a3:0e:4f:c1:04:b3:f3:01:c8:eb:d3:59:1c:35:d2:93:
- 1e:70:65:82:7f:db:cf:fb:c8:99:12:60:c3:44:6f:3a:80:4b:
- d7:be:21:aa:14:7a:64:cb:dd:37:43:45:5b:32:2e:45:f0:d9:
- 59:1f:6b:18:f0:7c:e9:55:36:19:61:5f:b5:7d:f1:8d:bd:88:
- e4:75:4b:98:dd:27:b0:e4:84:44:2a:61:84:57:05:82:11:1f:
- aa:35:58:f3:20:0e:af:59:ef:fa:55:72:72:0d:26:d0:9b:53:
- 49:ac:ce:37:2e:65:61:ff:f6:ec:1b:ea:f6:f1:a6:d3:d1:b5:
- 7b:be:35:f4:22:c1:bc:8d:01:bd:68:5e:83:0d:2f:ec:d6:da:
- 63:0c:27:d1:54:3e:e4:a8:d3:ce:4b:32:b8:91:94:ff:fb:5b:
- 49:2d:75:18:a8:ba:71:9a:3b:ae:d9:c0:a9:4f:87:91:ed:8b:
- 7b:6b:20:98:89:39:83:4f:80:c4:69:cc:17:c9:c8:4e:be:e4:
- a9:a5:81:76:70:06:04:32:cd:83:65:f4:bc:7d:3e:13:bc:d2:
- e8:6f:63:aa:b5:3b:da:8d:86:32:82:78:9d:d9:cc:ff:bf:57:
- 64:74:ed:28:3d:44:62:15:61:4b:f7:94:b0:0d:2a:67:1c:f0:
- cb:9b:a5:92:bf:f8:41:5a:c1:3d:60:ed:9f:bb:b8:6d:9b:ce:
- a9:6a:16:3f:7e:ea:06:f1
------BEGIN CERTIFICATE-----
-MIIGXDCCBESgAwIBAgIHGcKFMOk7NjANBgkqhkiG9w0BAQsFADB9MQswCQYDVQQG
-EwJJTDEWMBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERp
-Z2l0YWwgQ2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3RhcnRDb20gQ2Vy
-dGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDYwOTE3MjI0NjM2WhcNMTkxMjMxMjM1
-OTU5WjBVMQswCQYDVQQGEwJDTjEaMBgGA1UEChMRV29TaWduIENBIExpbWl0ZWQx
-KjAoBgNVBAMTIUNlcnRpZmljYXRpb24gQXV0aG9yaXR5IG9mIFdvU2lnbjCCAiIw
-DQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAL3Kjay4kRVWl3trXHrC3mvZobDD
-ECP6p6GyzDH6PtmmKW8WPeBr+LhAX9s5qAB6i6BNVH3CInj8jgm4qIXXzJWXS3TY
-nn7wAOQOia5JKEQaEJkyDyWIU6QNsw8SCBYLA3EnHH/h29L9Z2jEBV0KDl1w19iX
-oLxTQZqRjfSeNmZ6flbBkF/msWggNqSMJCwsRwtZdmYwtb7e7Y/4ndO7ATDm8vMO
-4CySgPOF+SiKtFQumu33dvwVaBbrSmzrLhKP1M/+DMdcHQt+BTK+XrAJKkLVyU6Q
-s1kNu3p+zdUIWrR/2BxpEfknD3sGr1SDGHvh3VR6UWhud/zGv1JKZkahsmcau6NP
-d6C+Xf/8VgtDcneQyp758jn1Dan06tfnsxAvMEI3IcwwcMmGmA/MWE2Du33lGqU3
-jbasMpcAOmNxJB6eN8T/dNQ3wOL+iEZgEd0IP1A2q7h6pJViam6wymohWmnz8/sd
-cDmV86dupoGJoYjFO3HKo1Lug7v9oHf05G/nQtttSpmKNEi8F9zkgAgitvIxwD8E
-PuufIHnWuAZkZAIx16nNUvuERWkJACrcVYvEBkZLwEodCVs5KP2pq84A+S5ISybm
-MEylWMq0RIJP55EeM8Owk/8R/IHSyh9xKd12T5Ilrx2Btw8vjMMGzC8no0rkDpm6
-fB5FH3+qGUWW/fw9AgMBAAGjggEHMIIBAzASBgNVHRMBAf8ECDAGAQH/AgECMA4G
-A1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQU4WbPDtHxs0u3BiAU/ocS1fb++z4wHwYD
-VR0jBBgwFoAUTgvvGqRAW6UXaYcwyjRoQ9BBrvIwaQYIKwYBBQUHAQEEXTBbMCcG
-CCsGAQUFBzABhhtodHRwOi8vb2NzcC5zdGFydHNzbC5jb20vY2EwMAYIKwYBBQUH
-MAKGJGh0dHA6Ly9haWEuc3RhcnRzc2wuY29tL2NlcnRzL2NhLmNydDAyBgNVHR8E
-KzApMCegJaAjhiFodHRwOi8vY3JsLnN0YXJ0c3NsLmNvbS9zZnNjYS5jcmwwDQYJ
-KoZIhvcNAQELBQADggIBALZt+HD74g1MmLMHSRX1BMRsysr1aKAI/hJtnAQGya2a
-kVI+eMRc7p9UHe7j8V4wyUnhOeCmnTZsV/rmNE9V6IeoLN0F8VgSkejKzih4j98H
-hQGl3EWWBdSAsisFmsuapYvgOmfmc0e+Sv0nsYjv5srPjQ4mn/pfV3itbf6umzUI
-scO6wQBKS30Uvffx01UYrNAzcIhtxAlxFKYrT4iB5wsAN6kVfX7XAZY/L697Yq4K
-Sr9LOS41EIv+BDnkPDoMCVZAOrX0wmgMtflSze6d+Jj8eOdYR48cc1hpM6v/3d+O
-JAF3mBk6sGZ5vOEIow5PwQSz8wHI69NZHDXSkx5wZYJ/28/7yJkSYMNEbzqAS9e+
-IaoUemTL3TdDRVsyLkXw2VkfaxjwfOlVNhlhX7V98Y29iOR1S5jdJ7DkhEQqYYRX
-BYIRH6o1WPMgDq9Z7/pVcnINJtCbU0mszjcuZWH/9uwb6vbxptPRtXu+NfQiwbyN
-Ab1oXoMNL+zW2mMMJ9FUPuSo085LMriRlP/7W0ktdRiounGaO67ZwKlPh5Hti3tr
-IJiJOYNPgMRpzBfJyE6+5KmlgXZwBgQyzYNl9Lx9PhO80uhvY6q1O9qNhjKCeJ3Z
-zP+/V2R07Sg9RGIVYUv3lLANKmcc8MubpZK/+EFawT1g7Z+7uG2bzqlqFj9+6gbx
------END CERTIFICATE-----
-#endif
-static const unsigned char kDERCert51[] = {
- 0x30, 0x82, 0x06, 0x5c, 0x30, 0x82, 0x04, 0x44, 0xa0, 0x03, 0x02, 0x01,
- 0x02, 0x02, 0x07, 0x19, 0xc2, 0x85, 0x30, 0xe9, 0x3b, 0x36, 0x30, 0x0d,
- 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05,
- 0x00, 0x30, 0x7d, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06,
- 0x13, 0x02, 0x49, 0x4c, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04,
- 0x0a, 0x13, 0x0d, 0x53, 0x74, 0x61, 0x72, 0x74, 0x43, 0x6f, 0x6d, 0x20,
- 0x4c, 0x74, 0x64, 0x2e, 0x31, 0x2b, 0x30, 0x29, 0x06, 0x03, 0x55, 0x04,
- 0x0b, 0x13, 0x22, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x44, 0x69,
- 0x67, 0x69, 0x74, 0x61, 0x6c, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66,
- 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x53, 0x69, 0x67, 0x6e, 0x69, 0x6e,
- 0x67, 0x31, 0x29, 0x30, 0x27, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x20,
- 0x53, 0x74, 0x61, 0x72, 0x74, 0x43, 0x6f, 0x6d, 0x20, 0x43, 0x65, 0x72,
- 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41,
- 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x30, 0x1e, 0x17, 0x0d,
- 0x30, 0x36, 0x30, 0x39, 0x31, 0x37, 0x32, 0x32, 0x34, 0x36, 0x33, 0x36,
- 0x5a, 0x17, 0x0d, 0x31, 0x39, 0x31, 0x32, 0x33, 0x31, 0x32, 0x33, 0x35,
- 0x39, 0x35, 0x39, 0x5a, 0x30, 0x55, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03,
- 0x55, 0x04, 0x06, 0x13, 0x02, 0x43, 0x4e, 0x31, 0x1a, 0x30, 0x18, 0x06,
- 0x03, 0x55, 0x04, 0x0a, 0x13, 0x11, 0x57, 0x6f, 0x53, 0x69, 0x67, 0x6e,
- 0x20, 0x43, 0x41, 0x20, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x65, 0x64, 0x31,
- 0x2a, 0x30, 0x28, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x21, 0x43, 0x65,
- 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20,
- 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x20, 0x6f, 0x66,
- 0x20, 0x57, 0x6f, 0x53, 0x69, 0x67, 0x6e, 0x30, 0x82, 0x02, 0x22, 0x30,
- 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01,
- 0x05, 0x00, 0x03, 0x82, 0x02, 0x0f, 0x00, 0x30, 0x82, 0x02, 0x0a, 0x02,
- 0x82, 0x02, 0x01, 0x00, 0xbd, 0xca, 0x8d, 0xac, 0xb8, 0x91, 0x15, 0x56,
- 0x97, 0x7b, 0x6b, 0x5c, 0x7a, 0xc2, 0xde, 0x6b, 0xd9, 0xa1, 0xb0, 0xc3,
- 0x10, 0x23, 0xfa, 0xa7, 0xa1, 0xb2, 0xcc, 0x31, 0xfa, 0x3e, 0xd9, 0xa6,
- 0x29, 0x6f, 0x16, 0x3d, 0xe0, 0x6b, 0xf8, 0xb8, 0x40, 0x5f, 0xdb, 0x39,
- 0xa8, 0x00, 0x7a, 0x8b, 0xa0, 0x4d, 0x54, 0x7d, 0xc2, 0x22, 0x78, 0xfc,
- 0x8e, 0x09, 0xb8, 0xa8, 0x85, 0xd7, 0xcc, 0x95, 0x97, 0x4b, 0x74, 0xd8,
- 0x9e, 0x7e, 0xf0, 0x00, 0xe4, 0x0e, 0x89, 0xae, 0x49, 0x28, 0x44, 0x1a,
- 0x10, 0x99, 0x32, 0x0f, 0x25, 0x88, 0x53, 0xa4, 0x0d, 0xb3, 0x0f, 0x12,
- 0x08, 0x16, 0x0b, 0x03, 0x71, 0x27, 0x1c, 0x7f, 0xe1, 0xdb, 0xd2, 0xfd,
- 0x67, 0x68, 0xc4, 0x05, 0x5d, 0x0a, 0x0e, 0x5d, 0x70, 0xd7, 0xd8, 0x97,
- 0xa0, 0xbc, 0x53, 0x41, 0x9a, 0x91, 0x8d, 0xf4, 0x9e, 0x36, 0x66, 0x7a,
- 0x7e, 0x56, 0xc1, 0x90, 0x5f, 0xe6, 0xb1, 0x68, 0x20, 0x36, 0xa4, 0x8c,
- 0x24, 0x2c, 0x2c, 0x47, 0x0b, 0x59, 0x76, 0x66, 0x30, 0xb5, 0xbe, 0xde,
- 0xed, 0x8f, 0xf8, 0x9d, 0xd3, 0xbb, 0x01, 0x30, 0xe6, 0xf2, 0xf3, 0x0e,
- 0xe0, 0x2c, 0x92, 0x80, 0xf3, 0x85, 0xf9, 0x28, 0x8a, 0xb4, 0x54, 0x2e,
- 0x9a, 0xed, 0xf7, 0x76, 0xfc, 0x15, 0x68, 0x16, 0xeb, 0x4a, 0x6c, 0xeb,
- 0x2e, 0x12, 0x8f, 0xd4, 0xcf, 0xfe, 0x0c, 0xc7, 0x5c, 0x1d, 0x0b, 0x7e,
- 0x05, 0x32, 0xbe, 0x5e, 0xb0, 0x09, 0x2a, 0x42, 0xd5, 0xc9, 0x4e, 0x90,
- 0xb3, 0x59, 0x0d, 0xbb, 0x7a, 0x7e, 0xcd, 0xd5, 0x08, 0x5a, 0xb4, 0x7f,
- 0xd8, 0x1c, 0x69, 0x11, 0xf9, 0x27, 0x0f, 0x7b, 0x06, 0xaf, 0x54, 0x83,
- 0x18, 0x7b, 0xe1, 0xdd, 0x54, 0x7a, 0x51, 0x68, 0x6e, 0x77, 0xfc, 0xc6,
- 0xbf, 0x52, 0x4a, 0x66, 0x46, 0xa1, 0xb2, 0x67, 0x1a, 0xbb, 0xa3, 0x4f,
- 0x77, 0xa0, 0xbe, 0x5d, 0xff, 0xfc, 0x56, 0x0b, 0x43, 0x72, 0x77, 0x90,
- 0xca, 0x9e, 0xf9, 0xf2, 0x39, 0xf5, 0x0d, 0xa9, 0xf4, 0xea, 0xd7, 0xe7,
- 0xb3, 0x10, 0x2f, 0x30, 0x42, 0x37, 0x21, 0xcc, 0x30, 0x70, 0xc9, 0x86,
- 0x98, 0x0f, 0xcc, 0x58, 0x4d, 0x83, 0xbb, 0x7d, 0xe5, 0x1a, 0xa5, 0x37,
- 0x8d, 0xb6, 0xac, 0x32, 0x97, 0x00, 0x3a, 0x63, 0x71, 0x24, 0x1e, 0x9e,
- 0x37, 0xc4, 0xff, 0x74, 0xd4, 0x37, 0xc0, 0xe2, 0xfe, 0x88, 0x46, 0x60,
- 0x11, 0xdd, 0x08, 0x3f, 0x50, 0x36, 0xab, 0xb8, 0x7a, 0xa4, 0x95, 0x62,
- 0x6a, 0x6e, 0xb0, 0xca, 0x6a, 0x21, 0x5a, 0x69, 0xf3, 0xf3, 0xfb, 0x1d,
- 0x70, 0x39, 0x95, 0xf3, 0xa7, 0x6e, 0xa6, 0x81, 0x89, 0xa1, 0x88, 0xc5,
- 0x3b, 0x71, 0xca, 0xa3, 0x52, 0xee, 0x83, 0xbb, 0xfd, 0xa0, 0x77, 0xf4,
- 0xe4, 0x6f, 0xe7, 0x42, 0xdb, 0x6d, 0x4a, 0x99, 0x8a, 0x34, 0x48, 0xbc,
- 0x17, 0xdc, 0xe4, 0x80, 0x08, 0x22, 0xb6, 0xf2, 0x31, 0xc0, 0x3f, 0x04,
- 0x3e, 0xeb, 0x9f, 0x20, 0x79, 0xd6, 0xb8, 0x06, 0x64, 0x64, 0x02, 0x31,
- 0xd7, 0xa9, 0xcd, 0x52, 0xfb, 0x84, 0x45, 0x69, 0x09, 0x00, 0x2a, 0xdc,
- 0x55, 0x8b, 0xc4, 0x06, 0x46, 0x4b, 0xc0, 0x4a, 0x1d, 0x09, 0x5b, 0x39,
- 0x28, 0xfd, 0xa9, 0xab, 0xce, 0x00, 0xf9, 0x2e, 0x48, 0x4b, 0x26, 0xe6,
- 0x30, 0x4c, 0xa5, 0x58, 0xca, 0xb4, 0x44, 0x82, 0x4f, 0xe7, 0x91, 0x1e,
- 0x33, 0xc3, 0xb0, 0x93, 0xff, 0x11, 0xfc, 0x81, 0xd2, 0xca, 0x1f, 0x71,
- 0x29, 0xdd, 0x76, 0x4f, 0x92, 0x25, 0xaf, 0x1d, 0x81, 0xb7, 0x0f, 0x2f,
- 0x8c, 0xc3, 0x06, 0xcc, 0x2f, 0x27, 0xa3, 0x4a, 0xe4, 0x0e, 0x99, 0xba,
- 0x7c, 0x1e, 0x45, 0x1f, 0x7f, 0xaa, 0x19, 0x45, 0x96, 0xfd, 0xfc, 0x3d,
- 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x07, 0x30, 0x82, 0x01,
- 0x03, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04,
- 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x02, 0x30, 0x0e, 0x06,
- 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01,
- 0x06, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14,
- 0xe1, 0x66, 0xcf, 0x0e, 0xd1, 0xf1, 0xb3, 0x4b, 0xb7, 0x06, 0x20, 0x14,
- 0xfe, 0x87, 0x12, 0xd5, 0xf6, 0xfe, 0xfb, 0x3e, 0x30, 0x1f, 0x06, 0x03,
- 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x4e, 0x0b, 0xef,
- 0x1a, 0xa4, 0x40, 0x5b, 0xa5, 0x17, 0x69, 0x87, 0x30, 0xca, 0x34, 0x68,
- 0x43, 0xd0, 0x41, 0xae, 0xf2, 0x30, 0x69, 0x06, 0x08, 0x2b, 0x06, 0x01,
- 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x5d, 0x30, 0x5b, 0x30, 0x27, 0x06,
- 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x1b, 0x68,
- 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x73,
- 0x74, 0x61, 0x72, 0x74, 0x73, 0x73, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x2f,
- 0x63, 0x61, 0x30, 0x30, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
- 0x30, 0x02, 0x86, 0x24, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x61,
- 0x69, 0x61, 0x2e, 0x73, 0x74, 0x61, 0x72, 0x74, 0x73, 0x73, 0x6c, 0x2e,
- 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x65, 0x72, 0x74, 0x73, 0x2f, 0x63, 0x61,
- 0x2e, 0x63, 0x72, 0x74, 0x30, 0x32, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04,
- 0x2b, 0x30, 0x29, 0x30, 0x27, 0xa0, 0x25, 0xa0, 0x23, 0x86, 0x21, 0x68,
- 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x73, 0x74,
- 0x61, 0x72, 0x74, 0x73, 0x73, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x73,
- 0x66, 0x73, 0x63, 0x61, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x0d, 0x06, 0x09,
- 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03,
- 0x82, 0x02, 0x01, 0x00, 0xb6, 0x6d, 0xf8, 0x70, 0xfb, 0xe2, 0x0d, 0x4c,
- 0x98, 0xb3, 0x07, 0x49, 0x15, 0xf5, 0x04, 0xc4, 0x6c, 0xca, 0xca, 0xf5,
- 0x68, 0xa0, 0x08, 0xfe, 0x12, 0x6d, 0x9c, 0x04, 0x06, 0xc9, 0xad, 0x9a,
- 0x91, 0x52, 0x3e, 0x78, 0xc4, 0x5c, 0xee, 0x9f, 0x54, 0x1d, 0xee, 0xe3,
- 0xf1, 0x5e, 0x30, 0xc9, 0x49, 0xe1, 0x39, 0xe0, 0xa6, 0x9d, 0x36, 0x6c,
- 0x57, 0xfa, 0xe6, 0x34, 0x4f, 0x55, 0xe8, 0x87, 0xa8, 0x2c, 0xdd, 0x05,
- 0xf1, 0x58, 0x12, 0x91, 0xe8, 0xca, 0xce, 0x28, 0x78, 0x8f, 0xdf, 0x07,
- 0x85, 0x01, 0xa5, 0xdc, 0x45, 0x96, 0x05, 0xd4, 0x80, 0xb2, 0x2b, 0x05,
- 0x9a, 0xcb, 0x9a, 0xa5, 0x8b, 0xe0, 0x3a, 0x67, 0xe6, 0x73, 0x47, 0xbe,
- 0x4a, 0xfd, 0x27, 0xb1, 0x88, 0xef, 0xe6, 0xca, 0xcf, 0x8d, 0x0e, 0x26,
- 0x9f, 0xfa, 0x5f, 0x57, 0x78, 0xad, 0x6d, 0xfe, 0xae, 0x9b, 0x35, 0x08,
- 0xb1, 0xc3, 0xba, 0xc1, 0x00, 0x4a, 0x4b, 0x7d, 0x14, 0xbd, 0xf7, 0xf1,
- 0xd3, 0x55, 0x18, 0xac, 0xd0, 0x33, 0x70, 0x88, 0x6d, 0xc4, 0x09, 0x71,
- 0x14, 0xa6, 0x2b, 0x4f, 0x88, 0x81, 0xe7, 0x0b, 0x00, 0x37, 0xa9, 0x15,
- 0x7d, 0x7e, 0xd7, 0x01, 0x96, 0x3f, 0x2f, 0xaf, 0x7b, 0x62, 0xae, 0x0a,
- 0x4a, 0xbf, 0x4b, 0x39, 0x2e, 0x35, 0x10, 0x8b, 0xfe, 0x04, 0x39, 0xe4,
- 0x3c, 0x3a, 0x0c, 0x09, 0x56, 0x40, 0x3a, 0xb5, 0xf4, 0xc2, 0x68, 0x0c,
- 0xb5, 0xf9, 0x52, 0xcd, 0xee, 0x9d, 0xf8, 0x98, 0xfc, 0x78, 0xe7, 0x58,
- 0x47, 0x8f, 0x1c, 0x73, 0x58, 0x69, 0x33, 0xab, 0xff, 0xdd, 0xdf, 0x8e,
- 0x24, 0x01, 0x77, 0x98, 0x19, 0x3a, 0xb0, 0x66, 0x79, 0xbc, 0xe1, 0x08,
- 0xa3, 0x0e, 0x4f, 0xc1, 0x04, 0xb3, 0xf3, 0x01, 0xc8, 0xeb, 0xd3, 0x59,
- 0x1c, 0x35, 0xd2, 0x93, 0x1e, 0x70, 0x65, 0x82, 0x7f, 0xdb, 0xcf, 0xfb,
- 0xc8, 0x99, 0x12, 0x60, 0xc3, 0x44, 0x6f, 0x3a, 0x80, 0x4b, 0xd7, 0xbe,
- 0x21, 0xaa, 0x14, 0x7a, 0x64, 0xcb, 0xdd, 0x37, 0x43, 0x45, 0x5b, 0x32,
- 0x2e, 0x45, 0xf0, 0xd9, 0x59, 0x1f, 0x6b, 0x18, 0xf0, 0x7c, 0xe9, 0x55,
- 0x36, 0x19, 0x61, 0x5f, 0xb5, 0x7d, 0xf1, 0x8d, 0xbd, 0x88, 0xe4, 0x75,
- 0x4b, 0x98, 0xdd, 0x27, 0xb0, 0xe4, 0x84, 0x44, 0x2a, 0x61, 0x84, 0x57,
- 0x05, 0x82, 0x11, 0x1f, 0xaa, 0x35, 0x58, 0xf3, 0x20, 0x0e, 0xaf, 0x59,
- 0xef, 0xfa, 0x55, 0x72, 0x72, 0x0d, 0x26, 0xd0, 0x9b, 0x53, 0x49, 0xac,
- 0xce, 0x37, 0x2e, 0x65, 0x61, 0xff, 0xf6, 0xec, 0x1b, 0xea, 0xf6, 0xf1,
- 0xa6, 0xd3, 0xd1, 0xb5, 0x7b, 0xbe, 0x35, 0xf4, 0x22, 0xc1, 0xbc, 0x8d,
- 0x01, 0xbd, 0x68, 0x5e, 0x83, 0x0d, 0x2f, 0xec, 0xd6, 0xda, 0x63, 0x0c,
- 0x27, 0xd1, 0x54, 0x3e, 0xe4, 0xa8, 0xd3, 0xce, 0x4b, 0x32, 0xb8, 0x91,
- 0x94, 0xff, 0xfb, 0x5b, 0x49, 0x2d, 0x75, 0x18, 0xa8, 0xba, 0x71, 0x9a,
- 0x3b, 0xae, 0xd9, 0xc0, 0xa9, 0x4f, 0x87, 0x91, 0xed, 0x8b, 0x7b, 0x6b,
- 0x20, 0x98, 0x89, 0x39, 0x83, 0x4f, 0x80, 0xc4, 0x69, 0xcc, 0x17, 0xc9,
- 0xc8, 0x4e, 0xbe, 0xe4, 0xa9, 0xa5, 0x81, 0x76, 0x70, 0x06, 0x04, 0x32,
- 0xcd, 0x83, 0x65, 0xf4, 0xbc, 0x7d, 0x3e, 0x13, 0xbc, 0xd2, 0xe8, 0x6f,
- 0x63, 0xaa, 0xb5, 0x3b, 0xda, 0x8d, 0x86, 0x32, 0x82, 0x78, 0x9d, 0xd9,
- 0xcc, 0xff, 0xbf, 0x57, 0x64, 0x74, 0xed, 0x28, 0x3d, 0x44, 0x62, 0x15,
- 0x61, 0x4b, 0xf7, 0x94, 0xb0, 0x0d, 0x2a, 0x67, 0x1c, 0xf0, 0xcb, 0x9b,
- 0xa5, 0x92, 0xbf, 0xf8, 0x41, 0x5a, 0xc1, 0x3d, 0x60, 0xed, 0x9f, 0xbb,
- 0xb8, 0x6d, 0x9b, 0xce, 0xa9, 0x6a, 0x16, 0x3f, 0x7e, 0xea, 0x06, 0xf1,
-};
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/common_cert_set_empty.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/common_cert_set_empty.cc
deleted file mode 100644
index f5d246dd768..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/common_cert_set_empty.cc
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright (c) 2013 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 "quic/core/crypto/common_cert_set.h"
-
-#include <cstddef>
-
-#include "absl/base/macros.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_utils.h"
-
-namespace quic {
-
-namespace {
-
-class CommonCertSetsEmpty : public CommonCertSets {
- public:
- // CommonCertSets interface.
- absl::string_view GetCommonHashes() const override {
- return absl::string_view();
- }
-
- absl::string_view GetCert(uint64_t /* hash */,
- uint32_t /* index */) const override {
- return absl::string_view();
- }
-
- bool MatchCert(absl::string_view /* cert */,
- absl::string_view /* common_set_hashes */,
- uint64_t* /* out_hash */,
- uint32_t* /* out_index */) const override {
- return false;
- }
-
- CommonCertSetsEmpty() {}
- CommonCertSetsEmpty(const CommonCertSetsEmpty&) = delete;
- CommonCertSetsEmpty& operator=(const CommonCertSetsEmpty&) = delete;
- ~CommonCertSetsEmpty() override {}
-};
-
-} // anonymous namespace
-
-CommonCertSets::~CommonCertSets() {}
-
-// static
-const CommonCertSets* CommonCertSets::GetInstanceQUIC() {
- static CommonCertSetsEmpty* certs = new CommonCertSetsEmpty();
- return certs;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/common_cert_set_test.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/common_cert_set_test.cc
deleted file mode 100644
index b5f91f38b8c..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/common_cert_set_test.cc
+++ /dev/null
@@ -1,253 +0,0 @@
-// Copyright (c) 2013 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 "quic/core/crypto/common_cert_set.h"
-
-#include <cstdint>
-
-#include "absl/strings/string_view.h"
-#include "quic/platform/api/quic_test.h"
-
-namespace quic {
-namespace test {
-
-// Google Internet Authority cert from v2 of the cert set.
-static const unsigned char kGIACertificate2[] = {
- 0x30, 0x82, 0x03, 0xf0, 0x30, 0x82, 0x02, 0xd8, 0xa0, 0x03, 0x02, 0x01,
- 0x02, 0x02, 0x03, 0x02, 0x3a, 0x83, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
- 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x42, 0x31,
- 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53,
- 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0d, 0x47,
- 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x49, 0x6e, 0x63, 0x2e,
- 0x31, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x12, 0x47,
- 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x47, 0x6c, 0x6f, 0x62,
- 0x61, 0x6c, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x33, 0x30,
- 0x34, 0x30, 0x35, 0x31, 0x35, 0x31, 0x35, 0x35, 0x36, 0x5a, 0x17, 0x0d,
- 0x31, 0x36, 0x31, 0x32, 0x33, 0x31, 0x32, 0x33, 0x35, 0x39, 0x35, 0x39,
- 0x5a, 0x30, 0x49, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06,
- 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04,
- 0x0a, 0x13, 0x0a, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x20, 0x49, 0x6e,
- 0x63, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x1c,
- 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x74, 0x65, 0x72,
- 0x6e, 0x65, 0x74, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74,
- 0x79, 0x20, 0x47, 0x32, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09,
- 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03,
- 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01,
- 0x00, 0x9c, 0x2a, 0x04, 0x77, 0x5c, 0xd8, 0x50, 0x91, 0x3a, 0x06, 0xa3,
- 0x82, 0xe0, 0xd8, 0x50, 0x48, 0xbc, 0x89, 0x3f, 0xf1, 0x19, 0x70, 0x1a,
- 0x88, 0x46, 0x7e, 0xe0, 0x8f, 0xc5, 0xf1, 0x89, 0xce, 0x21, 0xee, 0x5a,
- 0xfe, 0x61, 0x0d, 0xb7, 0x32, 0x44, 0x89, 0xa0, 0x74, 0x0b, 0x53, 0x4f,
- 0x55, 0xa4, 0xce, 0x82, 0x62, 0x95, 0xee, 0xeb, 0x59, 0x5f, 0xc6, 0xe1,
- 0x05, 0x80, 0x12, 0xc4, 0x5e, 0x94, 0x3f, 0xbc, 0x5b, 0x48, 0x38, 0xf4,
- 0x53, 0xf7, 0x24, 0xe6, 0xfb, 0x91, 0xe9, 0x15, 0xc4, 0xcf, 0xf4, 0x53,
- 0x0d, 0xf4, 0x4a, 0xfc, 0x9f, 0x54, 0xde, 0x7d, 0xbe, 0xa0, 0x6b, 0x6f,
- 0x87, 0xc0, 0xd0, 0x50, 0x1f, 0x28, 0x30, 0x03, 0x40, 0xda, 0x08, 0x73,
- 0x51, 0x6c, 0x7f, 0xff, 0x3a, 0x3c, 0xa7, 0x37, 0x06, 0x8e, 0xbd, 0x4b,
- 0x11, 0x04, 0xeb, 0x7d, 0x24, 0xde, 0xe6, 0xf9, 0xfc, 0x31, 0x71, 0xfb,
- 0x94, 0xd5, 0x60, 0xf3, 0x2e, 0x4a, 0xaf, 0x42, 0xd2, 0xcb, 0xea, 0xc4,
- 0x6a, 0x1a, 0xb2, 0xcc, 0x53, 0xdd, 0x15, 0x4b, 0x8b, 0x1f, 0xc8, 0x19,
- 0x61, 0x1f, 0xcd, 0x9d, 0xa8, 0x3e, 0x63, 0x2b, 0x84, 0x35, 0x69, 0x65,
- 0x84, 0xc8, 0x19, 0xc5, 0x46, 0x22, 0xf8, 0x53, 0x95, 0xbe, 0xe3, 0x80,
- 0x4a, 0x10, 0xc6, 0x2a, 0xec, 0xba, 0x97, 0x20, 0x11, 0xc7, 0x39, 0x99,
- 0x10, 0x04, 0xa0, 0xf0, 0x61, 0x7a, 0x95, 0x25, 0x8c, 0x4e, 0x52, 0x75,
- 0xe2, 0xb6, 0xed, 0x08, 0xca, 0x14, 0xfc, 0xce, 0x22, 0x6a, 0xb3, 0x4e,
- 0xcf, 0x46, 0x03, 0x97, 0x97, 0x03, 0x7e, 0xc0, 0xb1, 0xde, 0x7b, 0xaf,
- 0x45, 0x33, 0xcf, 0xba, 0x3e, 0x71, 0xb7, 0xde, 0xf4, 0x25, 0x25, 0xc2,
- 0x0d, 0x35, 0x89, 0x9d, 0x9d, 0xfb, 0x0e, 0x11, 0x79, 0x89, 0x1e, 0x37,
- 0xc5, 0xaf, 0x8e, 0x72, 0x69, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x81,
- 0xe7, 0x30, 0x81, 0xe4, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04,
- 0x18, 0x30, 0x16, 0x80, 0x14, 0xc0, 0x7a, 0x98, 0x68, 0x8d, 0x89, 0xfb,
- 0xab, 0x05, 0x64, 0x0c, 0x11, 0x7d, 0xaa, 0x7d, 0x65, 0xb8, 0xca, 0xcc,
- 0x4e, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14,
- 0x4a, 0xdd, 0x06, 0x16, 0x1b, 0xbc, 0xf6, 0x68, 0xb5, 0x76, 0xf5, 0x81,
- 0xb6, 0xbb, 0x62, 0x1a, 0xba, 0x5a, 0x81, 0x2f, 0x30, 0x0e, 0x06, 0x03,
- 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06,
- 0x30, 0x2e, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01,
- 0x04, 0x22, 0x30, 0x20, 0x30, 0x1e, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05,
- 0x05, 0x07, 0x30, 0x01, 0x86, 0x12, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f,
- 0x2f, 0x67, 0x2e, 0x73, 0x79, 0x6d, 0x63, 0x64, 0x2e, 0x63, 0x6f, 0x6d,
- 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08,
- 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x00, 0x30, 0x35, 0x06, 0x03,
- 0x55, 0x1d, 0x1f, 0x04, 0x2e, 0x30, 0x2c, 0x30, 0x2a, 0xa0, 0x28, 0xa0,
- 0x26, 0x86, 0x24, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x67, 0x2e,
- 0x73, 0x79, 0x6d, 0x63, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x72,
- 0x6c, 0x73, 0x2f, 0x67, 0x74, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x2e,
- 0x63, 0x72, 0x6c, 0x30, 0x17, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x10,
- 0x30, 0x0e, 0x30, 0x0c, 0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01, 0xd6,
- 0x79, 0x02, 0x05, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
- 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00,
- 0xaa, 0xfa, 0xa9, 0x20, 0xcd, 0x6a, 0x67, 0x83, 0xed, 0x5e, 0xd4, 0x7e,
- 0xde, 0x1d, 0xc4, 0x7f, 0xe0, 0x25, 0x06, 0x00, 0xc5, 0x24, 0xfb, 0xa9,
- 0xc8, 0x2d, 0x6d, 0x7e, 0xde, 0x9d, 0x82, 0x65, 0x2c, 0x81, 0x63, 0x34,
- 0x66, 0x3e, 0xe9, 0x52, 0xc2, 0x08, 0xb4, 0xcb, 0x2f, 0xf7, 0x5f, 0x99,
- 0x3a, 0x6a, 0x9c, 0x50, 0x7a, 0x85, 0x05, 0x8c, 0x7d, 0xd1, 0x2a, 0x48,
- 0x84, 0xd3, 0x09, 0x6c, 0x7c, 0xc2, 0xcd, 0x35, 0x9f, 0xf3, 0x82, 0xee,
- 0x52, 0xde, 0x68, 0x5f, 0xe4, 0x00, 0x8a, 0x17, 0x20, 0x96, 0xf7, 0x29,
- 0x8d, 0x9a, 0x4d, 0xcb, 0xa8, 0xde, 0x86, 0xc8, 0x0d, 0x6f, 0x56, 0x87,
- 0x03, 0x7d, 0x03, 0x3f, 0xdc, 0xfa, 0x79, 0x7d, 0x21, 0x19, 0xf9, 0xc8,
- 0x3a, 0x2f, 0x51, 0x76, 0x8c, 0xc7, 0x41, 0x92, 0x71, 0x8f, 0x25, 0xce,
- 0x37, 0xf8, 0x4a, 0x4c, 0x00, 0x23, 0xef, 0xc4, 0x35, 0x10, 0xae, 0xe0,
- 0x23, 0x80, 0x73, 0x7c, 0x4d, 0x34, 0x2e, 0xc8, 0x6e, 0x90, 0xd6, 0x10,
- 0x1e, 0x99, 0x84, 0x73, 0x1a, 0x70, 0xf2, 0xed, 0x55, 0x0e, 0xee, 0x17,
- 0x06, 0xea, 0x67, 0xee, 0x32, 0xeb, 0x2c, 0xdd, 0x67, 0x07, 0x3f, 0xf6,
- 0x8b, 0xc2, 0x70, 0xde, 0x5b, 0x00, 0xe6, 0xbb, 0x1b, 0xd3, 0x36, 0x1a,
- 0x22, 0x6c, 0x6c, 0xb0, 0x35, 0x42, 0x6c, 0x90, 0x09, 0x3d, 0x93, 0xe9,
- 0x64, 0x09, 0x22, 0x0e, 0x85, 0x06, 0x9f, 0xc2, 0x73, 0x21, 0xd3, 0xe6,
- 0x5f, 0x80, 0xe4, 0x8d, 0x85, 0x22, 0x3a, 0x73, 0x03, 0xb1, 0x60, 0x8e,
- 0xae, 0x68, 0xe2, 0xf4, 0x3e, 0x97, 0xe7, 0x60, 0x12, 0x09, 0x68, 0x36,
- 0xde, 0x3a, 0xd6, 0xe2, 0x43, 0x95, 0x5b, 0x37, 0x81, 0x92, 0x81, 0x1f,
- 0xbb, 0x8d, 0xd7, 0xad, 0x52, 0x64, 0x16, 0x57, 0x96, 0xd9, 0x5e, 0x34,
- 0x7e, 0xc8, 0x35, 0xd8,
-};
-
-// Google Internet Authority cert from v3 of the cert set.
-static const unsigned char kGIACertificate3[] = {
- 0x30, 0x82, 0x03, 0xf0, 0x30, 0x82, 0x02, 0xd8, 0xa0, 0x03, 0x02, 0x01,
- 0x02, 0x02, 0x03, 0x02, 0x3a, 0x92, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
- 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x42, 0x31,
- 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53,
- 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0d, 0x47,
- 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x49, 0x6e, 0x63, 0x2e,
- 0x31, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x12, 0x47,
- 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x47, 0x6c, 0x6f, 0x62,
- 0x61, 0x6c, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x35, 0x30,
- 0x34, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d,
- 0x31, 0x37, 0x31, 0x32, 0x33, 0x31, 0x32, 0x33, 0x35, 0x39, 0x35, 0x39,
- 0x5a, 0x30, 0x49, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06,
- 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04,
- 0x0a, 0x13, 0x0a, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x20, 0x49, 0x6e,
- 0x63, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x1c,
- 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x74, 0x65, 0x72,
- 0x6e, 0x65, 0x74, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74,
- 0x79, 0x20, 0x47, 0x32, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09,
- 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03,
- 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01,
- 0x00, 0x9c, 0x2a, 0x04, 0x77, 0x5c, 0xd8, 0x50, 0x91, 0x3a, 0x06, 0xa3,
- 0x82, 0xe0, 0xd8, 0x50, 0x48, 0xbc, 0x89, 0x3f, 0xf1, 0x19, 0x70, 0x1a,
- 0x88, 0x46, 0x7e, 0xe0, 0x8f, 0xc5, 0xf1, 0x89, 0xce, 0x21, 0xee, 0x5a,
- 0xfe, 0x61, 0x0d, 0xb7, 0x32, 0x44, 0x89, 0xa0, 0x74, 0x0b, 0x53, 0x4f,
- 0x55, 0xa4, 0xce, 0x82, 0x62, 0x95, 0xee, 0xeb, 0x59, 0x5f, 0xc6, 0xe1,
- 0x05, 0x80, 0x12, 0xc4, 0x5e, 0x94, 0x3f, 0xbc, 0x5b, 0x48, 0x38, 0xf4,
- 0x53, 0xf7, 0x24, 0xe6, 0xfb, 0x91, 0xe9, 0x15, 0xc4, 0xcf, 0xf4, 0x53,
- 0x0d, 0xf4, 0x4a, 0xfc, 0x9f, 0x54, 0xde, 0x7d, 0xbe, 0xa0, 0x6b, 0x6f,
- 0x87, 0xc0, 0xd0, 0x50, 0x1f, 0x28, 0x30, 0x03, 0x40, 0xda, 0x08, 0x73,
- 0x51, 0x6c, 0x7f, 0xff, 0x3a, 0x3c, 0xa7, 0x37, 0x06, 0x8e, 0xbd, 0x4b,
- 0x11, 0x04, 0xeb, 0x7d, 0x24, 0xde, 0xe6, 0xf9, 0xfc, 0x31, 0x71, 0xfb,
- 0x94, 0xd5, 0x60, 0xf3, 0x2e, 0x4a, 0xaf, 0x42, 0xd2, 0xcb, 0xea, 0xc4,
- 0x6a, 0x1a, 0xb2, 0xcc, 0x53, 0xdd, 0x15, 0x4b, 0x8b, 0x1f, 0xc8, 0x19,
- 0x61, 0x1f, 0xcd, 0x9d, 0xa8, 0x3e, 0x63, 0x2b, 0x84, 0x35, 0x69, 0x65,
- 0x84, 0xc8, 0x19, 0xc5, 0x46, 0x22, 0xf8, 0x53, 0x95, 0xbe, 0xe3, 0x80,
- 0x4a, 0x10, 0xc6, 0x2a, 0xec, 0xba, 0x97, 0x20, 0x11, 0xc7, 0x39, 0x99,
- 0x10, 0x04, 0xa0, 0xf0, 0x61, 0x7a, 0x95, 0x25, 0x8c, 0x4e, 0x52, 0x75,
- 0xe2, 0xb6, 0xed, 0x08, 0xca, 0x14, 0xfc, 0xce, 0x22, 0x6a, 0xb3, 0x4e,
- 0xcf, 0x46, 0x03, 0x97, 0x97, 0x03, 0x7e, 0xc0, 0xb1, 0xde, 0x7b, 0xaf,
- 0x45, 0x33, 0xcf, 0xba, 0x3e, 0x71, 0xb7, 0xde, 0xf4, 0x25, 0x25, 0xc2,
- 0x0d, 0x35, 0x89, 0x9d, 0x9d, 0xfb, 0x0e, 0x11, 0x79, 0x89, 0x1e, 0x37,
- 0xc5, 0xaf, 0x8e, 0x72, 0x69, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x81,
- 0xe7, 0x30, 0x81, 0xe4, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04,
- 0x18, 0x30, 0x16, 0x80, 0x14, 0xc0, 0x7a, 0x98, 0x68, 0x8d, 0x89, 0xfb,
- 0xab, 0x05, 0x64, 0x0c, 0x11, 0x7d, 0xaa, 0x7d, 0x65, 0xb8, 0xca, 0xcc,
- 0x4e, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14,
- 0x4a, 0xdd, 0x06, 0x16, 0x1b, 0xbc, 0xf6, 0x68, 0xb5, 0x76, 0xf5, 0x81,
- 0xb6, 0xbb, 0x62, 0x1a, 0xba, 0x5a, 0x81, 0x2f, 0x30, 0x0e, 0x06, 0x03,
- 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06,
- 0x30, 0x2e, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01,
- 0x04, 0x22, 0x30, 0x20, 0x30, 0x1e, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05,
- 0x05, 0x07, 0x30, 0x01, 0x86, 0x12, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f,
- 0x2f, 0x67, 0x2e, 0x73, 0x79, 0x6d, 0x63, 0x64, 0x2e, 0x63, 0x6f, 0x6d,
- 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08,
- 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x00, 0x30, 0x35, 0x06, 0x03,
- 0x55, 0x1d, 0x1f, 0x04, 0x2e, 0x30, 0x2c, 0x30, 0x2a, 0xa0, 0x28, 0xa0,
- 0x26, 0x86, 0x24, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x67, 0x2e,
- 0x73, 0x79, 0x6d, 0x63, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x72,
- 0x6c, 0x73, 0x2f, 0x67, 0x74, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x2e,
- 0x63, 0x72, 0x6c, 0x30, 0x17, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x10,
- 0x30, 0x0e, 0x30, 0x0c, 0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01, 0xd6,
- 0x79, 0x02, 0x05, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
- 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00,
- 0x08, 0x4e, 0x04, 0xa7, 0x80, 0x7f, 0x10, 0x16, 0x43, 0x5e, 0x02, 0xad,
- 0xd7, 0x42, 0x80, 0xf4, 0xb0, 0x8e, 0xd2, 0xae, 0xb3, 0xeb, 0x11, 0x7d,
- 0x90, 0x84, 0x18, 0x7d, 0xe7, 0x90, 0x15, 0xfb, 0x49, 0x7f, 0xa8, 0x99,
- 0x05, 0x91, 0xbb, 0x7a, 0xc9, 0xd6, 0x3c, 0x37, 0x18, 0x09, 0x9a, 0xb6,
- 0xc7, 0x92, 0x20, 0x07, 0x35, 0x33, 0x09, 0xe4, 0x28, 0x63, 0x72, 0x0d,
- 0xb4, 0xe0, 0x32, 0x9c, 0x87, 0x98, 0xc4, 0x1b, 0x76, 0x89, 0x67, 0xc1,
- 0x50, 0x58, 0xb0, 0x13, 0xaa, 0x13, 0x1a, 0x1b, 0x32, 0xa5, 0xbe, 0xea,
- 0x11, 0x95, 0x4c, 0x48, 0x63, 0x49, 0xe9, 0x99, 0x5d, 0x20, 0x37, 0xcc,
- 0xfe, 0x2a, 0x69, 0x51, 0x16, 0x95, 0x4b, 0xa9, 0xde, 0x49, 0x82, 0xc0,
- 0x10, 0x70, 0xf4, 0x2c, 0xf3, 0xec, 0xbc, 0x24, 0x24, 0xd0, 0x4e, 0xac,
- 0xa5, 0xd9, 0x5e, 0x1e, 0x6d, 0x92, 0xc1, 0xa7, 0xac, 0x48, 0x35, 0x81,
- 0xf9, 0xe5, 0xe4, 0x9c, 0x65, 0x69, 0xcd, 0x87, 0xa4, 0x41, 0x50, 0x3f,
- 0x2e, 0x57, 0xa5, 0x91, 0x51, 0x12, 0x58, 0x0e, 0x8c, 0x09, 0xa1, 0xac,
- 0x7a, 0xa4, 0x12, 0xa5, 0x27, 0xf3, 0x9a, 0x10, 0x97, 0x7d, 0x55, 0x03,
- 0x06, 0xf7, 0x66, 0x58, 0x5f, 0x5f, 0x64, 0xe1, 0xab, 0x5d, 0x6d, 0xa5,
- 0x39, 0x48, 0x75, 0x98, 0x4c, 0x29, 0x5a, 0x3a, 0x8d, 0xd3, 0x2b, 0xca,
- 0x9c, 0x55, 0x04, 0xbf, 0xf4, 0xe6, 0x14, 0xd5, 0x80, 0xac, 0x26, 0xed,
- 0x17, 0x89, 0xa6, 0x93, 0x6c, 0x5c, 0xa4, 0xcc, 0xb8, 0xf0, 0x66, 0x8e,
- 0x64, 0xe3, 0x7d, 0x9a, 0xe2, 0x00, 0xb3, 0x49, 0xc7, 0xe4, 0x0a, 0xaa,
- 0xdd, 0x5b, 0x83, 0xc7, 0x70, 0x90, 0x46, 0x4e, 0xbe, 0xd0, 0xdb, 0x59,
- 0x96, 0x6c, 0x2e, 0xf5, 0x16, 0x36, 0xde, 0x71, 0xcc, 0x01, 0xc2, 0x12,
- 0xc1, 0x21, 0xc6, 0x16,
-};
-
-class CommonCertSetsTest : public QuicTest {};
-
-TEST_F(CommonCertSetsTest, FindGIA_2) {
- absl::string_view gia(reinterpret_cast<const char*>(kGIACertificate2),
- sizeof(kGIACertificate2));
-
- const CommonCertSets* sets(CommonCertSets::GetInstanceQUIC());
- // Common Cert Set 2's hash.
- const uint64_t in_hash = UINT64_C(0xe81a92926081e801);
- uint64_t hash;
- uint32_t index;
- ASSERT_TRUE(
- sets->MatchCert(gia,
- absl::string_view(reinterpret_cast<const char*>(&in_hash),
- sizeof(in_hash)),
- &hash, &index));
- EXPECT_EQ(in_hash, hash);
-
- absl::string_view gia_copy = sets->GetCert(hash, index);
- EXPECT_FALSE(gia_copy.empty());
- ASSERT_EQ(gia.size(), gia_copy.size());
- EXPECT_EQ(0, memcmp(gia.data(), gia_copy.data(), gia.size()));
-}
-
-TEST_F(CommonCertSetsTest, FindGIA_3) {
- absl::string_view gia(reinterpret_cast<const char*>(kGIACertificate3),
- sizeof(kGIACertificate3));
-
- const CommonCertSets* sets(CommonCertSets::GetInstanceQUIC());
- // Common Cert Set 3's hash.
- const uint64_t in_hash = UINT64_C(0x918215a28680ed7e);
- uint64_t hash;
- uint32_t index;
- ASSERT_TRUE(
- sets->MatchCert(gia,
- absl::string_view(reinterpret_cast<const char*>(&in_hash),
- sizeof(in_hash)),
- &hash, &index));
- EXPECT_EQ(in_hash, hash);
-
- absl::string_view gia_copy = sets->GetCert(hash, index);
- EXPECT_FALSE(gia_copy.empty());
- ASSERT_EQ(gia.size(), gia_copy.size());
- EXPECT_EQ(0, memcmp(gia.data(), gia_copy.data(), gia.size()));
-}
-
-TEST_F(CommonCertSetsTest, NonMatch) {
- const CommonCertSets* sets(CommonCertSets::GetInstanceQUIC());
- absl::string_view not_a_cert("hello");
- const uint64_t in_hash = UINT64_C(0xc9fef74053f99f39);
- uint64_t hash;
- uint32_t index;
- EXPECT_FALSE(
- sets->MatchCert(not_a_cert,
- absl::string_view(reinterpret_cast<const char*>(&in_hash),
- sizeof(in_hash)),
- &hash, &index));
-}
-
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_framer.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_framer.cc
deleted file mode 100644
index cf6e123d833..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_framer.cc
+++ /dev/null
@@ -1,358 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/crypto/crypto_framer.h"
-
-#include <string>
-#include <utility>
-
-#include "absl/base/attributes.h"
-#include "absl/strings/str_cat.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/crypto/crypto_protocol.h"
-#include "quic/core/quic_data_reader.h"
-#include "quic/core/quic_data_writer.h"
-#include "quic/core/quic_packets.h"
-#include "quic/platform/api/quic_logging.h"
-#include "common/quiche_endian.h"
-
-namespace quic {
-
-namespace {
-
-const size_t kQuicTagSize = sizeof(QuicTag);
-const size_t kCryptoEndOffsetSize = sizeof(uint32_t);
-const size_t kNumEntriesSize = sizeof(uint16_t);
-
-// OneShotVisitor is a framer visitor that records a single handshake message.
-class OneShotVisitor : public CryptoFramerVisitorInterface {
- public:
- OneShotVisitor() : error_(false) {}
-
- void OnError(CryptoFramer* /*framer*/) override { error_ = true; }
-
- void OnHandshakeMessage(const CryptoHandshakeMessage& message) override {
- out_ = std::make_unique<CryptoHandshakeMessage>(message);
- }
-
- bool error() const { return error_; }
-
- std::unique_ptr<CryptoHandshakeMessage> release() { return std::move(out_); }
-
- private:
- std::unique_ptr<CryptoHandshakeMessage> out_;
- bool error_;
-};
-
-} // namespace
-
-CryptoFramer::CryptoFramer()
- : visitor_(nullptr),
- error_detail_(""),
- num_entries_(0),
- values_len_(0),
- process_truncated_messages_(false) {
- Clear();
-}
-
-CryptoFramer::~CryptoFramer() {}
-
-// static
-std::unique_ptr<CryptoHandshakeMessage> CryptoFramer::ParseMessage(
- absl::string_view in) {
- OneShotVisitor visitor;
- CryptoFramer framer;
-
- framer.set_visitor(&visitor);
- if (!framer.ProcessInput(in) || visitor.error() ||
- framer.InputBytesRemaining()) {
- return nullptr;
- }
-
- return visitor.release();
-}
-
-QuicErrorCode CryptoFramer::error() const {
- return error_;
-}
-
-const std::string& CryptoFramer::error_detail() const {
- return error_detail_;
-}
-
-bool CryptoFramer::ProcessInput(absl::string_view input,
- EncryptionLevel /*level*/) {
- return ProcessInput(input);
-}
-
-bool CryptoFramer::ProcessInput(absl::string_view input) {
- QUICHE_DCHECK_EQ(QUIC_NO_ERROR, error_);
- if (error_ != QUIC_NO_ERROR) {
- return false;
- }
- error_ = Process(input);
- if (error_ != QUIC_NO_ERROR) {
- QUICHE_DCHECK(!error_detail_.empty());
- visitor_->OnError(this);
- return false;
- }
-
- return true;
-}
-
-size_t CryptoFramer::InputBytesRemaining() const {
- return buffer_.length();
-}
-
-bool CryptoFramer::HasTag(QuicTag tag) const {
- if (state_ != STATE_READING_VALUES) {
- return false;
- }
- for (const auto& it : tags_and_lengths_) {
- if (it.first == tag) {
- return true;
- }
- }
- return false;
-}
-
-void CryptoFramer::ForceHandshake() {
- QuicDataReader reader(buffer_.data(), buffer_.length(),
- quiche::HOST_BYTE_ORDER);
- for (const std::pair<QuicTag, size_t>& item : tags_and_lengths_) {
- absl::string_view value;
- if (reader.BytesRemaining() < item.second) {
- break;
- }
- reader.ReadStringPiece(&value, item.second);
- message_.SetStringPiece(item.first, value);
- }
- visitor_->OnHandshakeMessage(message_);
-}
-
-// static
-std::unique_ptr<QuicData> CryptoFramer::ConstructHandshakeMessage(
- const CryptoHandshakeMessage& message) {
- size_t num_entries = message.tag_value_map().size();
- size_t pad_length = 0;
- bool need_pad_tag = false;
- bool need_pad_value = false;
-
- size_t len = message.size();
- if (len < message.minimum_size()) {
- need_pad_tag = true;
- need_pad_value = true;
- num_entries++;
-
- size_t delta = message.minimum_size() - len;
- const size_t overhead = kQuicTagSize + kCryptoEndOffsetSize;
- if (delta > overhead) {
- pad_length = delta - overhead;
- }
- len += overhead + pad_length;
- }
-
- if (num_entries > kMaxEntries) {
- return nullptr;
- }
-
- std::unique_ptr<char[]> buffer(new char[len]);
- QuicDataWriter writer(len, buffer.get(), quiche::HOST_BYTE_ORDER);
- if (!writer.WriteTag(message.tag())) {
- QUICHE_DCHECK(false) << "Failed to write message tag.";
- return nullptr;
- }
- if (!writer.WriteUInt16(static_cast<uint16_t>(num_entries))) {
- QUICHE_DCHECK(false) << "Failed to write size.";
- return nullptr;
- }
- if (!writer.WriteUInt16(0)) {
- QUICHE_DCHECK(false) << "Failed to write padding.";
- return nullptr;
- }
-
- uint32_t end_offset = 0;
- // Tags and offsets
- for (auto it = message.tag_value_map().begin();
- it != message.tag_value_map().end(); ++it) {
- if (it->first == kPAD && need_pad_tag) {
- // Existing PAD tags are only checked when padding needs to be added
- // because parts of the code may need to reserialize received messages
- // and those messages may, legitimately include padding.
- QUICHE_DCHECK(false)
- << "Message needed padding but already contained a PAD tag";
- return nullptr;
- }
-
- if (it->first > kPAD && need_pad_tag) {
- need_pad_tag = false;
- if (!WritePadTag(&writer, pad_length, &end_offset)) {
- return nullptr;
- }
- }
-
- if (!writer.WriteTag(it->first)) {
- QUICHE_DCHECK(false) << "Failed to write tag.";
- return nullptr;
- }
- end_offset += it->second.length();
- if (!writer.WriteUInt32(end_offset)) {
- QUICHE_DCHECK(false) << "Failed to write end offset.";
- return nullptr;
- }
- }
-
- if (need_pad_tag) {
- if (!WritePadTag(&writer, pad_length, &end_offset)) {
- return nullptr;
- }
- }
-
- // Values
- for (auto it = message.tag_value_map().begin();
- it != message.tag_value_map().end(); ++it) {
- if (it->first > kPAD && need_pad_value) {
- need_pad_value = false;
- if (!writer.WriteRepeatedByte('-', pad_length)) {
- QUICHE_DCHECK(false) << "Failed to write padding.";
- return nullptr;
- }
- }
-
- if (!writer.WriteBytes(it->second.data(), it->second.length())) {
- QUICHE_DCHECK(false) << "Failed to write value.";
- return nullptr;
- }
- }
-
- if (need_pad_value) {
- if (!writer.WriteRepeatedByte('-', pad_length)) {
- QUICHE_DCHECK(false) << "Failed to write padding.";
- return nullptr;
- }
- }
-
- return std::make_unique<QuicData>(buffer.release(), len, true);
-}
-
-void CryptoFramer::Clear() {
- message_.Clear();
- tags_and_lengths_.clear();
- error_ = QUIC_NO_ERROR;
- error_detail_ = "";
- state_ = STATE_READING_TAG;
-}
-
-QuicErrorCode CryptoFramer::Process(absl::string_view input) {
- // Add this data to the buffer.
- buffer_.append(input.data(), input.length());
- QuicDataReader reader(buffer_.data(), buffer_.length(),
- quiche::HOST_BYTE_ORDER);
-
- switch (state_) {
- case STATE_READING_TAG:
- if (reader.BytesRemaining() < kQuicTagSize) {
- break;
- }
- QuicTag message_tag;
- reader.ReadTag(&message_tag);
- message_.set_tag(message_tag);
- state_ = STATE_READING_NUM_ENTRIES;
- ABSL_FALLTHROUGH_INTENDED;
- case STATE_READING_NUM_ENTRIES:
- if (reader.BytesRemaining() < kNumEntriesSize + sizeof(uint16_t)) {
- break;
- }
- reader.ReadUInt16(&num_entries_);
- if (num_entries_ > kMaxEntries) {
- error_detail_ = absl::StrCat(num_entries_, " entries");
- return QUIC_CRYPTO_TOO_MANY_ENTRIES;
- }
- uint16_t padding;
- reader.ReadUInt16(&padding);
-
- tags_and_lengths_.reserve(num_entries_);
- state_ = STATE_READING_TAGS_AND_LENGTHS;
- values_len_ = 0;
- ABSL_FALLTHROUGH_INTENDED;
- case STATE_READING_TAGS_AND_LENGTHS: {
- if (reader.BytesRemaining() <
- num_entries_ * (kQuicTagSize + kCryptoEndOffsetSize)) {
- break;
- }
-
- uint32_t last_end_offset = 0;
- for (unsigned i = 0; i < num_entries_; ++i) {
- QuicTag tag;
- reader.ReadTag(&tag);
- if (i > 0 && tag <= tags_and_lengths_[i - 1].first) {
- if (tag == tags_and_lengths_[i - 1].first) {
- error_detail_ = absl::StrCat("Duplicate tag:", tag);
- return QUIC_CRYPTO_DUPLICATE_TAG;
- }
- error_detail_ = absl::StrCat("Tag ", tag, " out of order");
- return QUIC_CRYPTO_TAGS_OUT_OF_ORDER;
- }
-
- uint32_t end_offset;
- reader.ReadUInt32(&end_offset);
-
- if (end_offset < last_end_offset) {
- error_detail_ =
- absl::StrCat("End offset: ", end_offset, " vs ", last_end_offset);
- return QUIC_CRYPTO_TAGS_OUT_OF_ORDER;
- }
- tags_and_lengths_.push_back(std::make_pair(
- tag, static_cast<size_t>(end_offset - last_end_offset)));
- last_end_offset = end_offset;
- }
- values_len_ = last_end_offset;
- state_ = STATE_READING_VALUES;
- ABSL_FALLTHROUGH_INTENDED;
- }
- case STATE_READING_VALUES:
- if (reader.BytesRemaining() < values_len_) {
- if (!process_truncated_messages_) {
- break;
- }
- QUIC_LOG(ERROR) << "Trunacted message. Missing "
- << values_len_ - reader.BytesRemaining() << " bytes.";
- }
- for (const std::pair<QuicTag, size_t>& item : tags_and_lengths_) {
- absl::string_view value;
- if (!reader.ReadStringPiece(&value, item.second)) {
- QUICHE_DCHECK(process_truncated_messages_);
- // Store an empty value.
- message_.SetStringPiece(item.first, "");
- continue;
- }
- message_.SetStringPiece(item.first, value);
- }
- visitor_->OnHandshakeMessage(message_);
- Clear();
- state_ = STATE_READING_TAG;
- break;
- }
- // Save any remaining data.
- buffer_ = std::string(reader.PeekRemainingPayload());
- return QUIC_NO_ERROR;
-}
-
-// static
-bool CryptoFramer::WritePadTag(QuicDataWriter* writer,
- size_t pad_length,
- uint32_t* end_offset) {
- if (!writer->WriteTag(kPAD)) {
- QUICHE_DCHECK(false) << "Failed to write tag.";
- return false;
- }
- *end_offset += pad_length;
- if (!writer->WriteUInt32(*end_offset)) {
- QUICHE_DCHECK(false) << "Failed to write end offset.";
- return false;
- }
- return true;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_framer.h b/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_framer.h
deleted file mode 100644
index e3c6c63c746..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_framer.h
+++ /dev/null
@@ -1,137 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_CRYPTO_CRYPTO_FRAMER_H_
-#define QUICHE_QUIC_CORE_CRYPTO_CRYPTO_FRAMER_H_
-
-#include <cstddef>
-#include <cstdint>
-#include <memory>
-#include <string>
-#include <utility>
-#include <vector>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/crypto/crypto_handshake_message.h"
-#include "quic/core/crypto/crypto_message_parser.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-class CryptoFramer;
-class QuicData;
-class QuicDataWriter;
-
-class QUIC_EXPORT_PRIVATE CryptoFramerVisitorInterface {
- public:
- virtual ~CryptoFramerVisitorInterface() {}
-
- // Called if an error is detected.
- virtual void OnError(CryptoFramer* framer) = 0;
-
- // Called when a complete handshake message has been parsed.
- virtual void OnHandshakeMessage(const CryptoHandshakeMessage& message) = 0;
-};
-
-// A class for framing the crypto messages that are exchanged in a QUIC
-// session.
-class QUIC_EXPORT_PRIVATE CryptoFramer : public CryptoMessageParser {
- public:
- CryptoFramer();
-
- ~CryptoFramer() override;
-
- // ParseMessage parses exactly one message from the given
- // absl::string_view. If there is an error, the message is truncated,
- // or the message has trailing garbage then nullptr will be returned.
- static std::unique_ptr<CryptoHandshakeMessage> ParseMessage(
- absl::string_view in);
-
- // Set callbacks to be called from the framer. A visitor must be set, or
- // else the framer will crash. It is acceptable for the visitor to do
- // nothing. If this is called multiple times, only the last visitor
- // will be used. |visitor| will be owned by the framer.
- void set_visitor(CryptoFramerVisitorInterface* visitor) {
- visitor_ = visitor;
- }
-
- QuicErrorCode error() const override;
- const std::string& error_detail() const override;
-
- // Processes input data, which must be delivered in order. Returns
- // false if there was an error, and true otherwise. ProcessInput optionally
- // takes an EncryptionLevel, but it is ignored. The variant with the
- // EncryptionLevel is provided to match the CryptoMessageParser interface.
- bool ProcessInput(absl::string_view input, EncryptionLevel level) override;
- bool ProcessInput(absl::string_view input);
-
- // Returns the number of bytes of buffered input data remaining to be
- // parsed.
- size_t InputBytesRemaining() const override;
-
- // Checks if the specified tag has been seen. Returns |true| if it
- // has, and |false| if it has not or a CHLO has not been seen.
- bool HasTag(QuicTag tag) const;
-
- // Even if the CHLO has not been fully received, force processing of
- // the handshake message. This is dangerous and should not be used
- // except as a mechanism of last resort.
- void ForceHandshake();
-
- // Returns a new QuicData owned by the caller that contains a serialized
- // |message|, or nullptr if there was an error.
- static std::unique_ptr<QuicData> ConstructHandshakeMessage(
- const CryptoHandshakeMessage& message);
-
- // Debug only method which permits processing truncated messages.
- void set_process_truncated_messages(bool process_truncated_messages) {
- process_truncated_messages_ = process_truncated_messages;
- }
-
- private:
- // Clears per-message state. Does not clear the visitor.
- void Clear();
-
- // Process does does the work of |ProcessInput|, but returns an error code,
- // doesn't set error_ and doesn't call |visitor_->OnError()|.
- QuicErrorCode Process(absl::string_view input);
-
- static bool WritePadTag(QuicDataWriter* writer,
- size_t pad_length,
- uint32_t* end_offset);
-
- // Represents the current state of the parsing state machine.
- enum CryptoFramerState {
- STATE_READING_TAG,
- STATE_READING_NUM_ENTRIES,
- STATE_READING_TAGS_AND_LENGTHS,
- STATE_READING_VALUES
- };
-
- // Visitor to invoke when messages are parsed.
- CryptoFramerVisitorInterface* visitor_;
- // Last error.
- QuicErrorCode error_;
- // Remaining unparsed data.
- std::string buffer_;
- // Current state of the parsing.
- CryptoFramerState state_;
- // The message currently being parsed.
- CryptoHandshakeMessage message_;
- // The issue which caused |error_|
- std::string error_detail_;
- // Number of entires in the message currently being parsed.
- uint16_t num_entries_;
- // tags_and_lengths_ contains the tags that are currently being parsed and
- // their lengths.
- std::vector<std::pair<QuicTag, size_t>> tags_and_lengths_;
- // Cumulative length of all values in the message currently being parsed.
- size_t values_len_;
- // Set to true to allow of processing of truncated messages for debugging.
- bool process_truncated_messages_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_CRYPTO_CRYPTO_FRAMER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_framer_test.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_framer_test.cc
deleted file mode 100644
index 656a00a6ced..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_framer_test.cc
+++ /dev/null
@@ -1,466 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/crypto/crypto_framer.h"
-
-#include <map>
-#include <memory>
-#include <vector>
-
-#include "absl/base/macros.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/crypto/crypto_handshake.h"
-#include "quic/core/crypto/crypto_protocol.h"
-#include "quic/core/quic_packets.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/crypto_test_utils.h"
-#include "quic/test_tools/quic_test_utils.h"
-#include "common/test_tools/quiche_test_utils.h"
-
-namespace quic {
-namespace test {
-namespace {
-
-char* AsChars(unsigned char* data) {
- return reinterpret_cast<char*>(data);
-}
-
-class TestCryptoVisitor : public CryptoFramerVisitorInterface {
- public:
- TestCryptoVisitor() : error_count_(0) {}
-
- void OnError(CryptoFramer* framer) override {
- QUIC_DLOG(ERROR) << "CryptoFramer Error: " << framer->error();
- ++error_count_;
- }
-
- void OnHandshakeMessage(const CryptoHandshakeMessage& message) override {
- messages_.push_back(message);
- }
-
- // Counters from the visitor callbacks.
- int error_count_;
-
- std::vector<CryptoHandshakeMessage> messages_;
-};
-
-TEST(CryptoFramerTest, ConstructHandshakeMessage) {
- CryptoHandshakeMessage message;
- message.set_tag(0xFFAA7733);
- message.SetStringPiece(0x12345678, "abcdef");
- message.SetStringPiece(0x12345679, "ghijk");
- message.SetStringPiece(0x1234567A, "lmnopqr");
-
- unsigned char packet[] = {
- // tag
- 0x33, 0x77, 0xAA, 0xFF,
- // num entries
- 0x03, 0x00,
- // padding
- 0x00, 0x00,
- // tag 1
- 0x78, 0x56, 0x34, 0x12,
- // end offset 1
- 0x06, 0x00, 0x00, 0x00,
- // tag 2
- 0x79, 0x56, 0x34, 0x12,
- // end offset 2
- 0x0b, 0x00, 0x00, 0x00,
- // tag 3
- 0x7A, 0x56, 0x34, 0x12,
- // end offset 3
- 0x12, 0x00, 0x00, 0x00,
- // value 1
- 'a', 'b', 'c', 'd', 'e', 'f',
- // value 2
- 'g', 'h', 'i', 'j', 'k',
- // value 3
- 'l', 'm', 'n', 'o', 'p', 'q', 'r',
- };
-
- CryptoFramer framer;
- std::unique_ptr<QuicData> data = framer.ConstructHandshakeMessage(message);
- ASSERT_TRUE(data != nullptr);
- quiche::test::CompareCharArraysWithHexError(
- "constructed packet", data->data(), data->length(), AsChars(packet),
- ABSL_ARRAYSIZE(packet));
-}
-
-TEST(CryptoFramerTest, ConstructHandshakeMessageWithTwoKeys) {
- CryptoHandshakeMessage message;
- message.set_tag(0xFFAA7733);
- message.SetStringPiece(0x12345678, "abcdef");
- message.SetStringPiece(0x12345679, "ghijk");
-
- unsigned char packet[] = {
- // tag
- 0x33, 0x77, 0xAA, 0xFF,
- // num entries
- 0x02, 0x00,
- // padding
- 0x00, 0x00,
- // tag 1
- 0x78, 0x56, 0x34, 0x12,
- // end offset 1
- 0x06, 0x00, 0x00, 0x00,
- // tag 2
- 0x79, 0x56, 0x34, 0x12,
- // end offset 2
- 0x0b, 0x00, 0x00, 0x00,
- // value 1
- 'a', 'b', 'c', 'd', 'e', 'f',
- // value 2
- 'g', 'h', 'i', 'j', 'k',
- };
-
- CryptoFramer framer;
- std::unique_ptr<QuicData> data = framer.ConstructHandshakeMessage(message);
- ASSERT_TRUE(data != nullptr);
-
- quiche::test::CompareCharArraysWithHexError(
- "constructed packet", data->data(), data->length(), AsChars(packet),
- ABSL_ARRAYSIZE(packet));
-}
-
-TEST(CryptoFramerTest, ConstructHandshakeMessageZeroLength) {
- CryptoHandshakeMessage message;
- message.set_tag(0xFFAA7733);
- message.SetStringPiece(0x12345678, "");
-
- unsigned char packet[] = {
- // tag
- 0x33, 0x77, 0xAA, 0xFF,
- // num entries
- 0x01, 0x00,
- // padding
- 0x00, 0x00,
- // tag 1
- 0x78, 0x56, 0x34, 0x12,
- // end offset 1
- 0x00, 0x00, 0x00, 0x00,
- };
-
- CryptoFramer framer;
- std::unique_ptr<QuicData> data = framer.ConstructHandshakeMessage(message);
- ASSERT_TRUE(data != nullptr);
-
- quiche::test::CompareCharArraysWithHexError(
- "constructed packet", data->data(), data->length(), AsChars(packet),
- ABSL_ARRAYSIZE(packet));
-}
-
-TEST(CryptoFramerTest, ConstructHandshakeMessageTooManyEntries) {
- CryptoHandshakeMessage message;
- message.set_tag(0xFFAA7733);
- for (uint32_t key = 1; key <= kMaxEntries + 1; ++key) {
- message.SetStringPiece(key, "abcdef");
- }
-
- CryptoFramer framer;
- std::unique_ptr<QuicData> data = framer.ConstructHandshakeMessage(message);
- EXPECT_TRUE(data == nullptr);
-}
-
-TEST(CryptoFramerTest, ConstructHandshakeMessageMinimumSize) {
- CryptoHandshakeMessage message;
- message.set_tag(0xFFAA7733);
- message.SetStringPiece(0x01020304, "test");
- message.set_minimum_size(64);
-
- unsigned char packet[] = {
- // tag
- 0x33, 0x77, 0xAA, 0xFF,
- // num entries
- 0x02, 0x00,
- // padding
- 0x00, 0x00,
- // tag 1
- 'P', 'A', 'D', 0,
- // end offset 1
- 0x24, 0x00, 0x00, 0x00,
- // tag 2
- 0x04, 0x03, 0x02, 0x01,
- // end offset 2
- 0x28, 0x00, 0x00, 0x00,
- // 36 bytes of padding.
- '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-',
- '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-',
- '-', '-', '-', '-', '-', '-',
- // value 2
- 't', 'e', 's', 't',
- };
-
- CryptoFramer framer;
- std::unique_ptr<QuicData> data = framer.ConstructHandshakeMessage(message);
- ASSERT_TRUE(data != nullptr);
-
- quiche::test::CompareCharArraysWithHexError(
- "constructed packet", data->data(), data->length(), AsChars(packet),
- ABSL_ARRAYSIZE(packet));
-}
-
-TEST(CryptoFramerTest, ConstructHandshakeMessageMinimumSizePadLast) {
- CryptoHandshakeMessage message;
- message.set_tag(0xFFAA7733);
- message.SetStringPiece(1, "");
- message.set_minimum_size(64);
-
- unsigned char packet[] = {
- // tag
- 0x33, 0x77, 0xAA, 0xFF,
- // num entries
- 0x02, 0x00,
- // padding
- 0x00, 0x00,
- // tag 1
- 0x01, 0x00, 0x00, 0x00,
- // end offset 1
- 0x00, 0x00, 0x00, 0x00,
- // tag 2
- 'P', 'A', 'D', 0,
- // end offset 2
- 0x28, 0x00, 0x00, 0x00,
- // 40 bytes of padding.
- '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-',
- '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-',
- '-', '-', '-', '-', '-', '-', '-', '-', '-', '-',
- };
-
- CryptoFramer framer;
- std::unique_ptr<QuicData> data = framer.ConstructHandshakeMessage(message);
- ASSERT_TRUE(data != nullptr);
-
- quiche::test::CompareCharArraysWithHexError(
- "constructed packet", data->data(), data->length(), AsChars(packet),
- ABSL_ARRAYSIZE(packet));
-}
-
-TEST(CryptoFramerTest, ProcessInput) {
- test::TestCryptoVisitor visitor;
- CryptoFramer framer;
- framer.set_visitor(&visitor);
-
- unsigned char input[] = {
- // tag
- 0x33, 0x77, 0xAA, 0xFF,
- // num entries
- 0x02, 0x00,
- // padding
- 0x00, 0x00,
- // tag 1
- 0x78, 0x56, 0x34, 0x12,
- // end offset 1
- 0x06, 0x00, 0x00, 0x00,
- // tag 2
- 0x79, 0x56, 0x34, 0x12,
- // end offset 2
- 0x0b, 0x00, 0x00, 0x00,
- // value 1
- 'a', 'b', 'c', 'd', 'e', 'f',
- // value 2
- 'g', 'h', 'i', 'j', 'k',
- };
-
- EXPECT_TRUE(framer.ProcessInput(
- absl::string_view(AsChars(input), ABSL_ARRAYSIZE(input))));
- EXPECT_EQ(0u, framer.InputBytesRemaining());
- EXPECT_EQ(0, visitor.error_count_);
- ASSERT_EQ(1u, visitor.messages_.size());
- const CryptoHandshakeMessage& message = visitor.messages_[0];
- EXPECT_EQ(0xFFAA7733, message.tag());
- EXPECT_EQ(2u, message.tag_value_map().size());
- EXPECT_EQ("abcdef", crypto_test_utils::GetValueForTag(message, 0x12345678));
- EXPECT_EQ("ghijk", crypto_test_utils::GetValueForTag(message, 0x12345679));
-}
-
-TEST(CryptoFramerTest, ProcessInputWithThreeKeys) {
- test::TestCryptoVisitor visitor;
- CryptoFramer framer;
- framer.set_visitor(&visitor);
-
- unsigned char input[] = {
- // tag
- 0x33, 0x77, 0xAA, 0xFF,
- // num entries
- 0x03, 0x00,
- // padding
- 0x00, 0x00,
- // tag 1
- 0x78, 0x56, 0x34, 0x12,
- // end offset 1
- 0x06, 0x00, 0x00, 0x00,
- // tag 2
- 0x79, 0x56, 0x34, 0x12,
- // end offset 2
- 0x0b, 0x00, 0x00, 0x00,
- // tag 3
- 0x7A, 0x56, 0x34, 0x12,
- // end offset 3
- 0x12, 0x00, 0x00, 0x00,
- // value 1
- 'a', 'b', 'c', 'd', 'e', 'f',
- // value 2
- 'g', 'h', 'i', 'j', 'k',
- // value 3
- 'l', 'm', 'n', 'o', 'p', 'q', 'r',
- };
-
- EXPECT_TRUE(framer.ProcessInput(
- absl::string_view(AsChars(input), ABSL_ARRAYSIZE(input))));
- EXPECT_EQ(0u, framer.InputBytesRemaining());
- EXPECT_EQ(0, visitor.error_count_);
- ASSERT_EQ(1u, visitor.messages_.size());
- const CryptoHandshakeMessage& message = visitor.messages_[0];
- EXPECT_EQ(0xFFAA7733, message.tag());
- EXPECT_EQ(3u, message.tag_value_map().size());
- EXPECT_EQ("abcdef", crypto_test_utils::GetValueForTag(message, 0x12345678));
- EXPECT_EQ("ghijk", crypto_test_utils::GetValueForTag(message, 0x12345679));
- EXPECT_EQ("lmnopqr", crypto_test_utils::GetValueForTag(message, 0x1234567A));
-}
-
-TEST(CryptoFramerTest, ProcessInputIncrementally) {
- test::TestCryptoVisitor visitor;
- CryptoFramer framer;
- framer.set_visitor(&visitor);
-
- unsigned char input[] = {
- // tag
- 0x33, 0x77, 0xAA, 0xFF,
- // num entries
- 0x02, 0x00,
- // padding
- 0x00, 0x00,
- // tag 1
- 0x78, 0x56, 0x34, 0x12,
- // end offset 1
- 0x06, 0x00, 0x00, 0x00,
- // tag 2
- 0x79, 0x56, 0x34, 0x12,
- // end offset 2
- 0x0b, 0x00, 0x00, 0x00,
- // value 1
- 'a', 'b', 'c', 'd', 'e', 'f',
- // value 2
- 'g', 'h', 'i', 'j', 'k',
- };
-
- for (size_t i = 0; i < ABSL_ARRAYSIZE(input); i++) {
- EXPECT_TRUE(framer.ProcessInput(absl::string_view(AsChars(input) + i, 1)));
- }
- EXPECT_EQ(0u, framer.InputBytesRemaining());
- ASSERT_EQ(1u, visitor.messages_.size());
- const CryptoHandshakeMessage& message = visitor.messages_[0];
- EXPECT_EQ(0xFFAA7733, message.tag());
- EXPECT_EQ(2u, message.tag_value_map().size());
- EXPECT_EQ("abcdef", crypto_test_utils::GetValueForTag(message, 0x12345678));
- EXPECT_EQ("ghijk", crypto_test_utils::GetValueForTag(message, 0x12345679));
-}
-
-TEST(CryptoFramerTest, ProcessInputTagsOutOfOrder) {
- test::TestCryptoVisitor visitor;
- CryptoFramer framer;
- framer.set_visitor(&visitor);
-
- unsigned char input[] = {
- // tag
- 0x33, 0x77, 0xAA, 0xFF,
- // num entries
- 0x02, 0x00,
- // padding
- 0x00, 0x00,
- // tag 1
- 0x78, 0x56, 0x34, 0x13,
- // end offset 1
- 0x01, 0x00, 0x00, 0x00,
- // tag 2
- 0x79, 0x56, 0x34, 0x12,
- // end offset 2
- 0x02, 0x00, 0x00, 0x00,
- };
-
- EXPECT_FALSE(framer.ProcessInput(
- absl::string_view(AsChars(input), ABSL_ARRAYSIZE(input))));
- EXPECT_THAT(framer.error(), IsError(QUIC_CRYPTO_TAGS_OUT_OF_ORDER));
- EXPECT_EQ(1, visitor.error_count_);
-}
-
-TEST(CryptoFramerTest, ProcessEndOffsetsOutOfOrder) {
- test::TestCryptoVisitor visitor;
- CryptoFramer framer;
- framer.set_visitor(&visitor);
-
- unsigned char input[] = {
- // tag
- 0x33, 0x77, 0xAA, 0xFF,
- // num entries
- 0x02, 0x00,
- // padding
- 0x00, 0x00,
- // tag 1
- 0x79, 0x56, 0x34, 0x12,
- // end offset 1
- 0x01, 0x00, 0x00, 0x00,
- // tag 2
- 0x78, 0x56, 0x34, 0x13,
- // end offset 2
- 0x00, 0x00, 0x00, 0x00,
- };
-
- EXPECT_FALSE(framer.ProcessInput(
- absl::string_view(AsChars(input), ABSL_ARRAYSIZE(input))));
- EXPECT_THAT(framer.error(), IsError(QUIC_CRYPTO_TAGS_OUT_OF_ORDER));
- EXPECT_EQ(1, visitor.error_count_);
-}
-
-TEST(CryptoFramerTest, ProcessInputTooManyEntries) {
- test::TestCryptoVisitor visitor;
- CryptoFramer framer;
- framer.set_visitor(&visitor);
-
- unsigned char input[] = {
- // tag
- 0x33, 0x77, 0xAA, 0xFF,
- // num entries
- 0xA0, 0x00,
- // padding
- 0x00, 0x00,
- };
-
- EXPECT_FALSE(framer.ProcessInput(
- absl::string_view(AsChars(input), ABSL_ARRAYSIZE(input))));
- EXPECT_THAT(framer.error(), IsError(QUIC_CRYPTO_TOO_MANY_ENTRIES));
- EXPECT_EQ(1, visitor.error_count_);
-}
-
-TEST(CryptoFramerTest, ProcessInputZeroLength) {
- test::TestCryptoVisitor visitor;
- CryptoFramer framer;
- framer.set_visitor(&visitor);
-
- unsigned char input[] = {
- // tag
- 0x33, 0x77, 0xAA, 0xFF,
- // num entries
- 0x02, 0x00,
- // padding
- 0x00, 0x00,
- // tag 1
- 0x78, 0x56, 0x34, 0x12,
- // end offset 1
- 0x00, 0x00, 0x00, 0x00,
- // tag 2
- 0x79, 0x56, 0x34, 0x12,
- // end offset 2
- 0x05, 0x00, 0x00, 0x00,
- };
-
- EXPECT_TRUE(framer.ProcessInput(
- absl::string_view(AsChars(input), ABSL_ARRAYSIZE(input))));
- EXPECT_EQ(0, visitor.error_count_);
-}
-
-} // namespace
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_handshake.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_handshake.cc
deleted file mode 100644
index 05194a5cc3b..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_handshake.cc
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright (c) 2013 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 "quic/core/crypto/crypto_handshake.h"
-
-#include "quic/core/crypto/common_cert_set.h"
-#include "quic/core/crypto/key_exchange.h"
-#include "quic/core/crypto/quic_decrypter.h"
-#include "quic/core/crypto/quic_encrypter.h"
-
-namespace quic {
-
-QuicCryptoNegotiatedParameters::QuicCryptoNegotiatedParameters()
- : key_exchange(0),
- aead(0),
- token_binding_key_param(0),
- sct_supported_by_client(false) {}
-
-QuicCryptoNegotiatedParameters::~QuicCryptoNegotiatedParameters() {}
-
-CrypterPair::CrypterPair() {}
-
-CrypterPair::~CrypterPair() {}
-
-// static
-const char QuicCryptoConfig::kInitialLabel[] = "QUIC key expansion";
-
-// static
-const char QuicCryptoConfig::kCETVLabel[] = "QUIC CETV block";
-
-// static
-const char QuicCryptoConfig::kForwardSecureLabel[] =
- "QUIC forward secure key expansion";
-
-QuicCryptoConfig::QuicCryptoConfig()
- : common_cert_sets(CommonCertSets::GetInstanceQUIC()) {}
-
-QuicCryptoConfig::~QuicCryptoConfig() {}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_handshake.h b/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_handshake.h
deleted file mode 100644
index 2c5c588ba51..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_handshake.h
+++ /dev/null
@@ -1,193 +0,0 @@
-// Copyright (c) 2013 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_CRYPTO_CRYPTO_HANDSHAKE_H_
-#define QUICHE_QUIC_CORE_CRYPTO_CRYPTO_HANDSHAKE_H_
-
-#include <memory>
-#include <string>
-#include <vector>
-
-#include "quic/core/quic_packets.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-class CommonCertSets;
-class SynchronousKeyExchange;
-class QuicDecrypter;
-class QuicEncrypter;
-
-// HandshakeFailureReason enum values are uploaded to UMA, they cannot be
-// changed.
-enum HandshakeFailureReason {
- HANDSHAKE_OK = 0,
-
- // Failure reasons for an invalid client nonce in CHLO.
- //
- // The default error value for nonce verification failures from strike
- // register (covers old strike registers and unknown failures).
- CLIENT_NONCE_UNKNOWN_FAILURE = 1,
- // Client nonce had incorrect length.
- CLIENT_NONCE_INVALID_FAILURE = 2,
- // Client nonce is not unique.
- CLIENT_NONCE_NOT_UNIQUE_FAILURE = 3,
- // Client orbit is invalid or incorrect.
- CLIENT_NONCE_INVALID_ORBIT_FAILURE = 4,
- // Client nonce's timestamp is not in the strike register's valid time range.
- CLIENT_NONCE_INVALID_TIME_FAILURE = 5,
- // Strike register's RPC call timed out, client nonce couldn't be verified.
- CLIENT_NONCE_STRIKE_REGISTER_TIMEOUT = 6,
- // Strike register is down, client nonce couldn't be verified.
- CLIENT_NONCE_STRIKE_REGISTER_FAILURE = 7,
-
- // Failure reasons for an invalid server nonce in CHLO.
- //
- // Unbox of server nonce failed.
- SERVER_NONCE_DECRYPTION_FAILURE = 8,
- // Decrypted server nonce had incorrect length.
- SERVER_NONCE_INVALID_FAILURE = 9,
- // Server nonce is not unique.
- SERVER_NONCE_NOT_UNIQUE_FAILURE = 10,
- // Server nonce's timestamp is not in the strike register's valid time range.
- SERVER_NONCE_INVALID_TIME_FAILURE = 11,
- // The server requires handshake confirmation.
- SERVER_NONCE_REQUIRED_FAILURE = 20,
-
- // Failure reasons for an invalid server config in CHLO.
- //
- // Missing Server config id (kSCID) tag.
- SERVER_CONFIG_INCHOATE_HELLO_FAILURE = 12,
- // Couldn't find the Server config id (kSCID).
- SERVER_CONFIG_UNKNOWN_CONFIG_FAILURE = 13,
-
- // Failure reasons for an invalid source-address token.
- //
- // Missing Source-address token (kSourceAddressTokenTag) tag.
- SOURCE_ADDRESS_TOKEN_INVALID_FAILURE = 14,
- // Unbox of Source-address token failed.
- SOURCE_ADDRESS_TOKEN_DECRYPTION_FAILURE = 15,
- // Couldn't parse the unbox'ed Source-address token.
- SOURCE_ADDRESS_TOKEN_PARSE_FAILURE = 16,
- // Source-address token is for a different IP address.
- SOURCE_ADDRESS_TOKEN_DIFFERENT_IP_ADDRESS_FAILURE = 17,
- // The source-address token has a timestamp in the future.
- SOURCE_ADDRESS_TOKEN_CLOCK_SKEW_FAILURE = 18,
- // The source-address token has expired.
- SOURCE_ADDRESS_TOKEN_EXPIRED_FAILURE = 19,
-
- // The expected leaf certificate hash could not be validated.
- INVALID_EXPECTED_LEAF_CERTIFICATE = 21,
-
- MAX_FAILURE_REASON = 22,
-};
-
-// These errors will be packed into an uint32_t and we don't want to set the
-// most significant bit, which may be misinterpreted as the sign bit.
-static_assert(MAX_FAILURE_REASON <= 32, "failure reason out of sync");
-
-// A CrypterPair contains the encrypter and decrypter for an encryption level.
-struct QUIC_EXPORT_PRIVATE CrypterPair {
- CrypterPair();
- CrypterPair(CrypterPair&&) = default;
- ~CrypterPair();
-
- std::unique_ptr<QuicEncrypter> encrypter;
- std::unique_ptr<QuicDecrypter> decrypter;
-};
-
-// Parameters negotiated by the crypto handshake.
-struct QUIC_EXPORT_PRIVATE QuicCryptoNegotiatedParameters
- : public QuicReferenceCounted {
- // Initializes the members to 0 or empty values.
- QuicCryptoNegotiatedParameters();
-
- QuicTag key_exchange;
- QuicTag aead;
- std::string initial_premaster_secret;
- std::string forward_secure_premaster_secret;
- // initial_subkey_secret is used as the PRK input to the HKDF used when
- // performing key extraction that needs to happen before forward-secure keys
- // are available.
- std::string initial_subkey_secret;
- // subkey_secret is used as the PRK input to the HKDF used for key extraction.
- std::string subkey_secret;
- CrypterPair initial_crypters;
- CrypterPair forward_secure_crypters;
- // Normalized SNI: converted to lower case and trailing '.' removed.
- std::string sni;
- std::string client_nonce;
- std::string server_nonce;
- // hkdf_input_suffix contains the HKDF input following the label: the
- // ConnectionId, client hello and server config. This is only populated in the
- // client because only the client needs to derive the forward secure keys at a
- // later time from the initial keys.
- std::string hkdf_input_suffix;
- // cached_certs contains the cached certificates that a client used when
- // sending a client hello.
- std::vector<std::string> cached_certs;
- // client_key_exchange is used by clients to store the ephemeral KeyExchange
- // for the connection.
- std::unique_ptr<SynchronousKeyExchange> client_key_exchange;
- // channel_id is set by servers to a ChannelID key when the client correctly
- // proves possession of the corresponding private key. It consists of 32
- // bytes of x coordinate, followed by 32 bytes of y coordinate. Both values
- // are big-endian and the pair is a P-256 public key.
- std::string channel_id;
- QuicTag token_binding_key_param;
-
- // Used when generating proof signature when sending server config updates.
-
- // Used to generate cert chain when sending server config updates.
- std::string client_common_set_hashes;
- std::string client_cached_cert_hashes;
-
- // Default to false; set to true if the client indicates that it supports sct
- // by sending CSCT tag with an empty value in client hello.
- bool sct_supported_by_client;
-
- // Parameters only populated for TLS handshakes. These will be 0 for
- // connections not using TLS, or if the TLS handshake is not finished yet.
- uint16_t cipher_suite = 0;
- uint16_t key_exchange_group = 0;
- uint16_t peer_signature_algorithm = 0;
-
- protected:
- ~QuicCryptoNegotiatedParameters() override;
-};
-
-// QuicCryptoConfig contains common configuration between clients and servers.
-class QUIC_EXPORT_PRIVATE QuicCryptoConfig {
- public:
- // kInitialLabel is a constant that is used when deriving the initial
- // (non-forward secure) keys for the connection in order to tie the resulting
- // key to this protocol.
- static const char kInitialLabel[];
-
- // kCETVLabel is a constant that is used when deriving the keys for the
- // encrypted tag/value block in the client hello.
- static const char kCETVLabel[];
-
- // kForwardSecureLabel is a constant that is used when deriving the forward
- // secure keys for the connection in order to tie the resulting key to this
- // protocol.
- static const char kForwardSecureLabel[];
-
- QuicCryptoConfig();
- QuicCryptoConfig(const QuicCryptoConfig&) = delete;
- QuicCryptoConfig& operator=(const QuicCryptoConfig&) = delete;
- ~QuicCryptoConfig();
-
- // Key exchange methods. The following two members' values correspond by
- // index.
- QuicTagVector kexs;
- // Authenticated encryption with associated data (AEAD) algorithms.
- QuicTagVector aead;
-
- const CommonCertSets* common_cert_sets;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_CRYPTO_CRYPTO_HANDSHAKE_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_handshake_message.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_handshake_message.cc
deleted file mode 100644
index b591becf4f9..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_handshake_message.cc
+++ /dev/null
@@ -1,382 +0,0 @@
-// Copyright (c) 2013 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 "quic/core/crypto/crypto_handshake_message.h"
-
-#include <memory>
-#include <string>
-
-#include "absl/strings/escaping.h"
-#include "absl/strings/str_cat.h"
-#include "absl/strings/str_format.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/crypto/crypto_framer.h"
-#include "quic/core/crypto/crypto_protocol.h"
-#include "quic/core/crypto/crypto_utils.h"
-#include "quic/core/quic_socket_address_coder.h"
-#include "quic/core/quic_utils.h"
-#include "common/quiche_endian.h"
-
-namespace quic {
-
-CryptoHandshakeMessage::CryptoHandshakeMessage() : tag_(0), minimum_size_(0) {}
-
-CryptoHandshakeMessage::CryptoHandshakeMessage(
- const CryptoHandshakeMessage& other)
- : tag_(other.tag_),
- tag_value_map_(other.tag_value_map_),
- minimum_size_(other.minimum_size_) {
- // Don't copy serialized_. unique_ptr doesn't have a copy constructor.
- // The new object can lazily reconstruct serialized_.
-}
-
-CryptoHandshakeMessage::CryptoHandshakeMessage(CryptoHandshakeMessage&& other) =
- default;
-
-CryptoHandshakeMessage::~CryptoHandshakeMessage() {}
-
-CryptoHandshakeMessage& CryptoHandshakeMessage::operator=(
- const CryptoHandshakeMessage& other) {
- tag_ = other.tag_;
- tag_value_map_ = other.tag_value_map_;
- // Don't copy serialized_. unique_ptr doesn't have an assignment operator.
- // However, invalidate serialized_.
- serialized_.reset();
- minimum_size_ = other.minimum_size_;
- return *this;
-}
-
-CryptoHandshakeMessage& CryptoHandshakeMessage::operator=(
- CryptoHandshakeMessage&& other) = default;
-
-bool CryptoHandshakeMessage::operator==(
- const CryptoHandshakeMessage& rhs) const {
- return tag_ == rhs.tag_ && tag_value_map_ == rhs.tag_value_map_ &&
- minimum_size_ == rhs.minimum_size_;
-}
-
-bool CryptoHandshakeMessage::operator!=(
- const CryptoHandshakeMessage& rhs) const {
- return !(*this == rhs);
-}
-
-void CryptoHandshakeMessage::Clear() {
- tag_ = 0;
- tag_value_map_.clear();
- minimum_size_ = 0;
- serialized_.reset();
-}
-
-const QuicData& CryptoHandshakeMessage::GetSerialized() const {
- if (!serialized_) {
- serialized_ = CryptoFramer::ConstructHandshakeMessage(*this);
- }
- return *serialized_;
-}
-
-void CryptoHandshakeMessage::MarkDirty() {
- serialized_.reset();
-}
-
-void CryptoHandshakeMessage::SetVersionVector(
- QuicTag tag,
- ParsedQuicVersionVector versions) {
- QuicVersionLabelVector version_labels;
- for (const ParsedQuicVersion& version : versions) {
- version_labels.push_back(
- quiche::QuicheEndian::HostToNet32(CreateQuicVersionLabel(version)));
- }
- SetVector(tag, version_labels);
-}
-
-void CryptoHandshakeMessage::SetVersion(QuicTag tag,
- ParsedQuicVersion version) {
- SetValue(tag,
- quiche::QuicheEndian::HostToNet32(CreateQuicVersionLabel(version)));
-}
-
-void CryptoHandshakeMessage::SetStringPiece(QuicTag tag,
- absl::string_view value) {
- tag_value_map_[tag] = std::string(value);
-}
-
-void CryptoHandshakeMessage::Erase(QuicTag tag) {
- tag_value_map_.erase(tag);
-}
-
-QuicErrorCode CryptoHandshakeMessage::GetTaglist(
- QuicTag tag,
- QuicTagVector* out_tags) const {
- auto it = tag_value_map_.find(tag);
- QuicErrorCode ret = QUIC_NO_ERROR;
-
- if (it == tag_value_map_.end()) {
- ret = QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND;
- } else if (it->second.size() % sizeof(QuicTag) != 0) {
- ret = QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER;
- }
-
- if (ret != QUIC_NO_ERROR) {
- out_tags->clear();
- return ret;
- }
-
- size_t num_tags = it->second.size() / sizeof(QuicTag);
- out_tags->resize(num_tags);
- for (size_t i = 0; i < num_tags; ++i) {
- QuicTag tag;
- memcpy(&tag, it->second.data() + i * sizeof(tag), sizeof(tag));
- (*out_tags)[i] = tag;
- }
- return ret;
-}
-
-QuicErrorCode CryptoHandshakeMessage::GetVersionLabelList(
- QuicTag tag,
- QuicVersionLabelVector* out) const {
- QuicErrorCode error = GetTaglist(tag, out);
- if (error != QUIC_NO_ERROR) {
- return error;
- }
-
- for (size_t i = 0; i < out->size(); ++i) {
- (*out)[i] = quiche::QuicheEndian::HostToNet32((*out)[i]);
- }
-
- return QUIC_NO_ERROR;
-}
-
-QuicErrorCode CryptoHandshakeMessage::GetVersionLabel(
- QuicTag tag,
- QuicVersionLabel* out) const {
- QuicErrorCode error = GetUint32(tag, out);
- if (error != QUIC_NO_ERROR) {
- return error;
- }
-
- *out = quiche::QuicheEndian::HostToNet32(*out);
- return QUIC_NO_ERROR;
-}
-
-bool CryptoHandshakeMessage::GetStringPiece(QuicTag tag,
- absl::string_view* out) const {
- auto it = tag_value_map_.find(tag);
- if (it == tag_value_map_.end()) {
- return false;
- }
- *out = it->second;
- return true;
-}
-
-bool CryptoHandshakeMessage::HasStringPiece(QuicTag tag) const {
- return tag_value_map_.find(tag) != tag_value_map_.end();
-}
-
-QuicErrorCode CryptoHandshakeMessage::GetNthValue24(
- QuicTag tag,
- unsigned index,
- absl::string_view* out) const {
- absl::string_view value;
- if (!GetStringPiece(tag, &value)) {
- return QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND;
- }
-
- for (unsigned i = 0;; i++) {
- if (value.empty()) {
- return QUIC_CRYPTO_MESSAGE_INDEX_NOT_FOUND;
- }
- if (value.size() < 3) {
- return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER;
- }
-
- const unsigned char* data =
- reinterpret_cast<const unsigned char*>(value.data());
- size_t size = static_cast<size_t>(data[0]) |
- (static_cast<size_t>(data[1]) << 8) |
- (static_cast<size_t>(data[2]) << 16);
- value.remove_prefix(3);
-
- if (value.size() < size) {
- return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER;
- }
-
- if (i == index) {
- *out = absl::string_view(value.data(), size);
- return QUIC_NO_ERROR;
- }
-
- value.remove_prefix(size);
- }
-}
-
-QuicErrorCode CryptoHandshakeMessage::GetUint32(QuicTag tag,
- uint32_t* out) const {
- return GetPOD(tag, out, sizeof(uint32_t));
-}
-
-QuicErrorCode CryptoHandshakeMessage::GetUint64(QuicTag tag,
- uint64_t* out) const {
- return GetPOD(tag, out, sizeof(uint64_t));
-}
-
-QuicErrorCode CryptoHandshakeMessage::GetStatelessResetToken(
- QuicTag tag,
- StatelessResetToken* out) const {
- return GetPOD(tag, out, kStatelessResetTokenLength);
-}
-
-size_t CryptoHandshakeMessage::size() const {
- size_t ret = sizeof(QuicTag) + sizeof(uint16_t) /* number of entries */ +
- sizeof(uint16_t) /* padding */;
- ret += (sizeof(QuicTag) + sizeof(uint32_t) /* end offset */) *
- tag_value_map_.size();
- for (auto i = tag_value_map_.begin(); i != tag_value_map_.end(); ++i) {
- ret += i->second.size();
- }
-
- return ret;
-}
-
-void CryptoHandshakeMessage::set_minimum_size(size_t min_bytes) {
- if (min_bytes == minimum_size_) {
- return;
- }
- serialized_.reset();
- minimum_size_ = min_bytes;
-}
-
-size_t CryptoHandshakeMessage::minimum_size() const {
- return minimum_size_;
-}
-
-std::string CryptoHandshakeMessage::DebugString() const {
- return DebugStringInternal(0);
-}
-
-QuicErrorCode CryptoHandshakeMessage::GetPOD(QuicTag tag,
- void* out,
- size_t len) const {
- auto it = tag_value_map_.find(tag);
- QuicErrorCode ret = QUIC_NO_ERROR;
-
- if (it == tag_value_map_.end()) {
- ret = QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND;
- } else if (it->second.size() != len) {
- ret = QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER;
- }
-
- if (ret != QUIC_NO_ERROR) {
- memset(out, 0, len);
- return ret;
- }
-
- memcpy(out, it->second.data(), len);
- return ret;
-}
-
-std::string CryptoHandshakeMessage::DebugStringInternal(size_t indent) const {
- std::string ret =
- std::string(2 * indent, ' ') + QuicTagToString(tag_) + "<\n";
- ++indent;
- for (auto it = tag_value_map_.begin(); it != tag_value_map_.end(); ++it) {
- ret += std::string(2 * indent, ' ') + QuicTagToString(it->first) + ": ";
-
- bool done = false;
- switch (it->first) {
- case kICSL:
- case kCFCW:
- case kSFCW:
- case kIRTT:
- case kMIUS:
- case kMIBS:
- case kTCID:
- case kMAD:
- // uint32_t value
- if (it->second.size() == 4) {
- uint32_t value;
- memcpy(&value, it->second.data(), sizeof(value));
- absl::StrAppend(&ret, value);
- done = true;
- }
- break;
- case kKEXS:
- case kAEAD:
- case kCOPT:
- case kPDMD:
- case kVER:
- // tag lists
- if (it->second.size() % sizeof(QuicTag) == 0) {
- for (size_t j = 0; j < it->second.size(); j += sizeof(QuicTag)) {
- QuicTag tag;
- memcpy(&tag, it->second.data() + j, sizeof(tag));
- if (j > 0) {
- ret += ",";
- }
- ret += "'" + QuicTagToString(tag) + "'";
- }
- done = true;
- }
- break;
- case kRREJ:
- // uint32_t lists
- if (it->second.size() % sizeof(uint32_t) == 0) {
- for (size_t j = 0; j < it->second.size(); j += sizeof(uint32_t)) {
- uint32_t value;
- memcpy(&value, it->second.data() + j, sizeof(value));
- if (j > 0) {
- ret += ",";
- }
- ret += CryptoUtils::HandshakeFailureReasonToString(
- static_cast<HandshakeFailureReason>(value));
- }
- done = true;
- }
- break;
- case kCADR:
- // IP address and port
- if (!it->second.empty()) {
- QuicSocketAddressCoder decoder;
- if (decoder.Decode(it->second.data(), it->second.size())) {
- ret += QuicSocketAddress(decoder.ip(), decoder.port()).ToString();
- done = true;
- }
- }
- break;
- case kSCFG:
- // nested messages.
- if (!it->second.empty()) {
- std::unique_ptr<CryptoHandshakeMessage> msg(
- CryptoFramer::ParseMessage(it->second));
- if (msg) {
- ret += "\n";
- ret += msg->DebugStringInternal(indent + 1);
-
- done = true;
- }
- }
- break;
- case kPAD:
- ret += absl::StrFormat("(%d bytes of padding)", it->second.size());
- done = true;
- break;
- case kSNI:
- case kUAID:
- ret += "\"" + it->second + "\"";
- done = true;
- break;
- }
-
- if (!done) {
- // If there's no specific format for this tag, or the value is invalid,
- // then just use hex.
- ret += "0x" + absl::BytesToHexString(it->second);
- }
- ret += "\n";
- }
- --indent;
- ret += std::string(2 * indent, ' ') + ">";
- return ret;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_handshake_message.h b/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_handshake_message.h
deleted file mode 100644
index 9550c153e49..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_handshake_message.h
+++ /dev/null
@@ -1,160 +0,0 @@
-// Copyright (c) 2013 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_CRYPTO_CRYPTO_HANDSHAKE_MESSAGE_H_
-#define QUICHE_QUIC_CORE_CRYPTO_CRYPTO_HANDSHAKE_MESSAGE_H_
-
-#include <cstddef>
-#include <cstdint>
-#include <memory>
-#include <string>
-#include <vector>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// An intermediate format of a handshake message that's convenient for a
-// CryptoFramer to serialize from or parse into.
-class QUIC_EXPORT_PRIVATE CryptoHandshakeMessage {
- public:
- CryptoHandshakeMessage();
- CryptoHandshakeMessage(const CryptoHandshakeMessage& other);
- CryptoHandshakeMessage(CryptoHandshakeMessage&& other);
- ~CryptoHandshakeMessage();
-
- CryptoHandshakeMessage& operator=(const CryptoHandshakeMessage& other);
- CryptoHandshakeMessage& operator=(CryptoHandshakeMessage&& other);
-
- bool operator==(const CryptoHandshakeMessage& rhs) const;
- bool operator!=(const CryptoHandshakeMessage& rhs) const;
-
- // Clears state.
- void Clear();
-
- // GetSerialized returns the serialized form of this message and caches the
- // result. Subsequently altering the message does not invalidate the cache.
- const QuicData& GetSerialized() const;
-
- // MarkDirty invalidates the cache created by |GetSerialized|.
- void MarkDirty();
-
- // SetValue sets an element with the given tag to the raw, memory contents of
- // |v|.
- template <class T>
- void SetValue(QuicTag tag, const T& v) {
- tag_value_map_[tag] =
- std::string(reinterpret_cast<const char*>(&v), sizeof(v));
- }
-
- // SetVector sets an element with the given tag to the raw contents of an
- // array of elements in |v|.
- template <class T>
- void SetVector(QuicTag tag, const std::vector<T>& v) {
- if (v.empty()) {
- tag_value_map_[tag] = std::string();
- } else {
- tag_value_map_[tag] = std::string(reinterpret_cast<const char*>(&v[0]),
- v.size() * sizeof(T));
- }
- }
-
- // Sets an element with the given tag to the on-the-wire representation of
- // |version|.
- void SetVersion(QuicTag tag, ParsedQuicVersion version);
-
- // Sets an element with the given tag to the on-the-wire representation of
- // the elements in |versions|.
- void SetVersionVector(QuicTag tag, ParsedQuicVersionVector versions);
-
- // Returns the message tag.
- QuicTag tag() const { return tag_; }
- // Sets the message tag.
- void set_tag(QuicTag tag) { tag_ = tag; }
-
- const QuicTagValueMap& tag_value_map() const { return tag_value_map_; }
-
- void SetStringPiece(QuicTag tag, absl::string_view value);
-
- // Erase removes a tag/value, if present, from the message.
- void Erase(QuicTag tag);
-
- // GetTaglist finds an element with the given tag containing zero or more
- // tags. If such a tag doesn't exist, it returns an error code. Otherwise it
- // populates |out_tags| with the tags and returns QUIC_NO_ERROR.
- QuicErrorCode GetTaglist(QuicTag tag, QuicTagVector* out_tags) const;
-
- // GetVersionLabelList finds an element with the given tag containing zero or
- // more version labels. If such a tag doesn't exist, it returns an error code.
- // Otherwise it populates |out| with the labels and returns QUIC_NO_ERROR.
- QuicErrorCode GetVersionLabelList(QuicTag tag,
- QuicVersionLabelVector* out) const;
-
- // GetVersionLabel finds an element with the given tag containing a single
- // version label. If such a tag doesn't exist, it returns an error code.
- // Otherwise it populates |out| with the label and returns QUIC_NO_ERROR.
- QuicErrorCode GetVersionLabel(QuicTag tag, QuicVersionLabel* out) const;
-
- bool GetStringPiece(QuicTag tag, absl::string_view* out) const;
- bool HasStringPiece(QuicTag tag) const;
-
- // GetNthValue24 interprets the value with the given tag to be a series of
- // 24-bit, length prefixed values and it returns the subvalue with the given
- // index.
- QuicErrorCode GetNthValue24(QuicTag tag,
- unsigned index,
- absl::string_view* out) const;
- QuicErrorCode GetUint32(QuicTag tag, uint32_t* out) const;
- QuicErrorCode GetUint64(QuicTag tag, uint64_t* out) const;
-
- QuicErrorCode GetStatelessResetToken(QuicTag tag,
- StatelessResetToken* out) const;
-
- // size returns 4 (message tag) + 2 (uint16_t, number of entries) +
- // (4 (tag) + 4 (end offset))*tag_value_map_.size() + ∑ value sizes.
- size_t size() const;
-
- // set_minimum_size sets the minimum number of bytes that the message should
- // consume. The CryptoFramer will add a PAD tag as needed when serializing in
- // order to ensure this. Setting a value of 0 disables padding.
- //
- // Padding is useful in order to ensure that messages are a minimum size. A
- // QUIC server can require a minimum size in order to reduce the
- // amplification factor of any mirror DoS attack.
- void set_minimum_size(size_t min_bytes);
-
- size_t minimum_size() const;
-
- // DebugString returns a multi-line, string representation of the message
- // suitable for including in debug output.
- std::string DebugString() const;
-
- private:
- // GetPOD is a utility function for extracting a plain-old-data value. If
- // |tag| exists in the message, and has a value of exactly |len| bytes then
- // it copies |len| bytes of data into |out|. Otherwise |len| bytes at |out|
- // are zeroed out.
- //
- // If used to copy integers then this assumes that the machine is
- // little-endian.
- QuicErrorCode GetPOD(QuicTag tag, void* out, size_t len) const;
-
- std::string DebugStringInternal(size_t indent) const;
-
- QuicTag tag_;
- QuicTagValueMap tag_value_map_;
-
- size_t minimum_size_;
-
- // The serialized form of the handshake message. This member is constructed
- // lazily.
- mutable std::unique_ptr<QuicData> serialized_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_CRYPTO_CRYPTO_HANDSHAKE_MESSAGE_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_handshake_message_test.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_handshake_message_test.cc
deleted file mode 100644
index 4ace2e36b77..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_handshake_message_test.cc
+++ /dev/null
@@ -1,105 +0,0 @@
-// Copyright (c) 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/crypto/crypto_handshake_message.h"
-
-#include "quic/core/crypto/crypto_handshake.h"
-#include "quic/core/crypto/crypto_protocol.h"
-#include "quic/platform/api/quic_test.h"
-#include "common/quiche_endian.h"
-
-namespace quic {
-namespace test {
-namespace {
-
-TEST(CryptoHandshakeMessageTest, DebugString) {
- const char* str = "SHLO<\n>";
-
- CryptoHandshakeMessage message;
- message.set_tag(kSHLO);
- EXPECT_EQ(str, message.DebugString());
-
- // Test copy
- CryptoHandshakeMessage message2(message);
- EXPECT_EQ(str, message2.DebugString());
-
- // Test move
- CryptoHandshakeMessage message3(std::move(message));
- EXPECT_EQ(str, message3.DebugString());
-
- // Test assign
- CryptoHandshakeMessage message4 = message3;
- EXPECT_EQ(str, message4.DebugString());
-
- // Test move-assign
- CryptoHandshakeMessage message5 = std::move(message3);
- EXPECT_EQ(str, message5.DebugString());
-}
-
-TEST(CryptoHandshakeMessageTest, DebugStringWithUintVector) {
- const char* str =
- "REJ <\n RREJ: "
- "SOURCE_ADDRESS_TOKEN_DIFFERENT_IP_ADDRESS_FAILURE,"
- "CLIENT_NONCE_NOT_UNIQUE_FAILURE\n>";
-
- CryptoHandshakeMessage message;
- message.set_tag(kREJ);
- std::vector<uint32_t> reasons = {
- SOURCE_ADDRESS_TOKEN_DIFFERENT_IP_ADDRESS_FAILURE,
- CLIENT_NONCE_NOT_UNIQUE_FAILURE};
- message.SetVector(kRREJ, reasons);
- EXPECT_EQ(str, message.DebugString());
-
- // Test copy
- CryptoHandshakeMessage message2(message);
- EXPECT_EQ(str, message2.DebugString());
-
- // Test move
- CryptoHandshakeMessage message3(std::move(message));
- EXPECT_EQ(str, message3.DebugString());
-
- // Test assign
- CryptoHandshakeMessage message4 = message3;
- EXPECT_EQ(str, message4.DebugString());
-
- // Test move-assign
- CryptoHandshakeMessage message5 = std::move(message3);
- EXPECT_EQ(str, message5.DebugString());
-}
-
-TEST(CryptoHandshakeMessageTest, DebugStringWithTagVector) {
- const char* str = "CHLO<\n COPT: 'TBBR','PAD ','BYTE'\n>";
-
- CryptoHandshakeMessage message;
- message.set_tag(kCHLO);
- message.SetVector(kCOPT, QuicTagVector{kTBBR, kPAD, kBYTE});
- EXPECT_EQ(str, message.DebugString());
-
- // Test copy
- CryptoHandshakeMessage message2(message);
- EXPECT_EQ(str, message2.DebugString());
-
- // Test move
- CryptoHandshakeMessage message3(std::move(message));
- EXPECT_EQ(str, message3.DebugString());
-
- // Test assign
- CryptoHandshakeMessage message4 = message3;
- EXPECT_EQ(str, message4.DebugString());
-
- // Test move-assign
- CryptoHandshakeMessage message5 = std::move(message3);
- EXPECT_EQ(str, message5.DebugString());
-}
-
-TEST(CryptoHandshakeMessageTest, HasStringPiece) {
- CryptoHandshakeMessage message;
- EXPECT_FALSE(message.HasStringPiece(kALPN));
- message.SetStringPiece(kALPN, "foo");
- EXPECT_TRUE(message.HasStringPiece(kALPN));
-}
-
-} // namespace
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_message_parser.h b/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_message_parser.h
deleted file mode 100644
index 5b29dbf7364..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_message_parser.h
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_CRYPTO_CRYPTO_MESSAGE_PARSER_H_
-#define QUICHE_QUIC_CORE_CRYPTO_CRYPTO_MESSAGE_PARSER_H_
-
-#include <string>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_error_codes.h"
-#include "quic/core/quic_types.h"
-
-namespace quic {
-
-class QUIC_EXPORT_PRIVATE CryptoMessageParser {
- public:
- virtual ~CryptoMessageParser() {}
-
- virtual QuicErrorCode error() const = 0;
- virtual const std::string& error_detail() const = 0;
-
- // Processes input data, which must be delivered in order. The input data
- // being processed was received at encryption level |level|. Returns
- // false if there was an error, and true otherwise.
- virtual bool ProcessInput(absl::string_view input, EncryptionLevel level) = 0;
-
- // Returns the number of bytes of buffered input data remaining to be
- // parsed.
- virtual size_t InputBytesRemaining() const = 0;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_CRYPTO_CRYPTO_MESSAGE_PARSER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_message_printer_bin.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_message_printer_bin.cc
deleted file mode 100644
index 0159e3004e5..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_message_printer_bin.cc
+++ /dev/null
@@ -1,61 +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.
-
-// Dumps the contents of a QUIC crypto handshake message in a human readable
-// format.
-//
-// Usage: crypto_message_printer_bin <hex of message>
-
-#include <iostream>
-#include <string>
-
-#include "absl/strings/escaping.h"
-#include "quic/core/crypto/crypto_framer.h"
-#include "quic/core/quic_utils.h"
-#include "common/platform/api/quiche_command_line_flags.h"
-
-using std::cerr;
-using std::cout;
-using std::endl;
-
-namespace quic {
-
-class CryptoMessagePrinter : public ::quic::CryptoFramerVisitorInterface {
- public:
- void OnHandshakeMessage(const CryptoHandshakeMessage& message) override {
- cout << message.DebugString() << endl;
- }
-
- void OnError(CryptoFramer* framer) override {
- cerr << "Error code: " << framer->error() << endl;
- cerr << "Error details: " << framer->error_detail() << endl;
- }
-};
-
-} // namespace quic
-
-int main(int argc, char* argv[]) {
- const char* usage = "Usage: crypto_message_printer <hex>";
- std::vector<std::string> messages =
- quiche::QuicheParseCommandLineFlags(usage, argc, argv);
- if (messages.size() != 1) {
- quiche::QuichePrintCommandLineFlagHelp(usage);
- exit(0);
- }
-
- quic::CryptoMessagePrinter printer;
- quic::CryptoFramer framer;
- framer.set_visitor(&printer);
- framer.set_process_truncated_messages(true);
- std::string input = absl::HexStringToBytes(messages[0]);
- if (!framer.ProcessInput(input)) {
- return 1;
- }
- if (framer.InputBytesRemaining() != 0) {
- cerr << "Input partially consumed. " << framer.InputBytesRemaining()
- << " bytes remaining." << endl;
- return 2;
- }
- return 0;
-}
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_protocol.h b/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_protocol.h
deleted file mode 100644
index 0ebe0e430b8..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_protocol.h
+++ /dev/null
@@ -1,510 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_CRYPTO_CRYPTO_PROTOCOL_H_
-#define QUICHE_QUIC_CORE_CRYPTO_CRYPTO_PROTOCOL_H_
-
-#include <cstddef>
-#include <string>
-
-#include "quic/core/quic_tag.h"
-
-// Version and Crypto tags are written to the wire with a big-endian
-// representation of the name of the tag. For example
-// the client hello tag (CHLO) will be written as the
-// following 4 bytes: 'C' 'H' 'L' 'O'. Since it is
-// stored in memory as a little endian uint32_t, we need
-// to reverse the order of the bytes.
-//
-// We use a macro to ensure that no static initialisers are created. Use the
-// MakeQuicTag function in normal code.
-#define TAG(a, b, c, d) \
- static_cast<QuicTag>((d << 24) + (c << 16) + (b << 8) + a)
-
-namespace quic {
-
-using ServerConfigID = std::string;
-
-// The following tags have been deprecated and should not be reused:
-// "1CON", "BBQ4", "NCON", "RCID", "SREJ", "TBKP", "TB10", "SCLS", "SMHL",
-// "QNZR", "B2HI", "H2PR", "FIFO", "LIFO", "RRWS", "QNSP", "B2CL", "CHSP",
-// "BPTE", "ACKD", "AKD2", "AKD4", "MAD1", "MAD4", "MAD5", "ACD0", "ACKQ"
-
-// clang-format off
-const QuicTag kCHLO = TAG('C', 'H', 'L', 'O'); // Client hello
-const QuicTag kSHLO = TAG('S', 'H', 'L', 'O'); // Server hello
-const QuicTag kSCFG = TAG('S', 'C', 'F', 'G'); // Server config
-const QuicTag kREJ = TAG('R', 'E', 'J', '\0'); // Reject
-const QuicTag kCETV = TAG('C', 'E', 'T', 'V'); // Client encrypted tag-value
- // pairs
-const QuicTag kPRST = TAG('P', 'R', 'S', 'T'); // Public reset
-const QuicTag kSCUP = TAG('S', 'C', 'U', 'P'); // Server config update
-const QuicTag kALPN = TAG('A', 'L', 'P', 'N'); // Application-layer protocol
-
-// Key exchange methods
-const QuicTag kP256 = TAG('P', '2', '5', '6'); // ECDH, Curve P-256
-const QuicTag kC255 = TAG('C', '2', '5', '5'); // ECDH, Curve25519
-
-// AEAD algorithms
-const QuicTag kAESG = TAG('A', 'E', 'S', 'G'); // AES128 + GCM-12
-const QuicTag kCC20 = TAG('C', 'C', '2', '0'); // ChaCha20 + Poly1305 RFC7539
-
-// Congestion control feedback types
-const QuicTag kQBIC = TAG('Q', 'B', 'I', 'C'); // TCP cubic
-
-// Connection options (COPT) values
-const QuicTag kAFCW = TAG('A', 'F', 'C', 'W'); // Auto-tune flow control
- // receive windows.
-const QuicTag kIFW5 = TAG('I', 'F', 'W', '5'); // Set initial size
- // of stream flow control
- // receive window to
- // 32KB. (2^5 KB).
-const QuicTag kIFW6 = TAG('I', 'F', 'W', '6'); // Set initial size
- // of stream flow control
- // receive window to
- // 64KB. (2^6 KB).
-const QuicTag kIFW7 = TAG('I', 'F', 'W', '7'); // Set initial size
- // of stream flow control
- // receive window to
- // 128KB. (2^7 KB).
-const QuicTag kIFW8 = TAG('I', 'F', 'W', '8'); // Set initial size
- // of stream flow control
- // receive window to
- // 256KB. (2^8 KB).
-const QuicTag kIFW9 = TAG('I', 'F', 'W', '9'); // Set initial size
- // of stream flow control
- // receive window to
- // 512KB. (2^9 KB).
-const QuicTag kIFWA = TAG('I', 'F', 'W', 'a'); // Set initial size
- // of stream flow control
- // receive window to
- // 1MB. (2^0xa KB).
-const QuicTag kTBBR = TAG('T', 'B', 'B', 'R'); // Reduced Buffer Bloat TCP
-const QuicTag k1RTT = TAG('1', 'R', 'T', 'T'); // STARTUP in BBR for 1 RTT
-const QuicTag k2RTT = TAG('2', 'R', 'T', 'T'); // STARTUP in BBR for 2 RTTs
-const QuicTag kLRTT = TAG('L', 'R', 'T', 'T'); // Exit STARTUP in BBR on loss
-const QuicTag kBBS1 = TAG('B', 'B', 'S', '1'); // DEPRECATED
-const QuicTag kBBS2 = TAG('B', 'B', 'S', '2'); // More aggressive packet
- // conservation in BBR STARTUP
-const QuicTag kBBS3 = TAG('B', 'B', 'S', '3'); // Slowstart packet
- // conservation in BBR STARTUP
-const QuicTag kBBS4 = TAG('B', 'B', 'S', '4'); // DEPRECATED
-const QuicTag kBBS5 = TAG('B', 'B', 'S', '5'); // DEPRECATED
-const QuicTag kBBRR = TAG('B', 'B', 'R', 'R'); // Rate-based recovery in BBR
-const QuicTag kBBR1 = TAG('B', 'B', 'R', '1'); // DEPRECATED
-const QuicTag kBBR2 = TAG('B', 'B', 'R', '2'); // DEPRECATED
-const QuicTag kBBR3 = TAG('B', 'B', 'R', '3'); // Fully drain the queue once
- // per cycle
-const QuicTag kBBR4 = TAG('B', 'B', 'R', '4'); // 20 RTT ack aggregation
-const QuicTag kBBR5 = TAG('B', 'B', 'R', '5'); // 40 RTT ack aggregation
-const QuicTag kBBR9 = TAG('B', 'B', 'R', '9'); // DEPRECATED
-const QuicTag kBBRA = TAG('B', 'B', 'R', 'A'); // Starts a new ack aggregation
- // epoch if a full round has
- // passed
-const QuicTag kBBRB = TAG('B', 'B', 'R', 'B'); // Use send rate in BBR's
- // MaxAckHeightTracker
-const QuicTag kBBRS = TAG('B', 'B', 'R', 'S'); // DEPRECATED
-const QuicTag kBBQ1 = TAG('B', 'B', 'Q', '1'); // BBR with lower 2.77 STARTUP
- // pacing and CWND gain.
-const QuicTag kBBQ2 = TAG('B', 'B', 'Q', '2'); // BBRv2 with 2.885 STARTUP and
- // DRAIN CWND gain.
-const QuicTag kBBQ3 = TAG('B', 'B', 'Q', '3'); // BBR with ack aggregation
- // compensation in STARTUP.
-const QuicTag kBBQ5 = TAG('B', 'B', 'Q', '5'); // Expire ack aggregation upon
- // bandwidth increase in
- // STARTUP.
-const QuicTag kBBQ6 = TAG('B', 'B', 'Q', '6'); // Reduce STARTUP gain to 25%
- // more than BW increase.
-const QuicTag kBBQ7 = TAG('B', 'B', 'Q', '7'); // Reduce bw_lo by
- // bytes_lost/min_rtt.
-const QuicTag kBBQ8 = TAG('B', 'B', 'Q', '8'); // Reduce bw_lo by
- // bw_lo * bytes_lost/inflight
-const QuicTag kBBQ9 = TAG('B', 'B', 'Q', '9'); // Reduce bw_lo by
- // bw_lo * bytes_lost/cwnd
-const QuicTag kBBQ0 = TAG('B', 'B', 'Q', '0'); // Increase bytes_acked in
- // PROBE_UP when app limited.
-const QuicTag kRENO = TAG('R', 'E', 'N', 'O'); // Reno Congestion Control
-const QuicTag kTPCC = TAG('P', 'C', 'C', '\0'); // Performance-Oriented
- // Congestion Control
-const QuicTag kBYTE = TAG('B', 'Y', 'T', 'E'); // TCP cubic or reno in bytes
-const QuicTag kIW03 = TAG('I', 'W', '0', '3'); // Force ICWND to 3
-const QuicTag kIW10 = TAG('I', 'W', '1', '0'); // Force ICWND to 10
-const QuicTag kIW20 = TAG('I', 'W', '2', '0'); // Force ICWND to 20
-const QuicTag kIW50 = TAG('I', 'W', '5', '0'); // Force ICWND to 50
-const QuicTag kB2ON = TAG('B', '2', 'O', 'N'); // Enable BBRv2
-const QuicTag kB2NA = TAG('B', '2', 'N', 'A'); // For BBRv2, do not add ack
- // height to queueing threshold
-const QuicTag kB2NE = TAG('B', '2', 'N', 'E'); // For BBRv2, always exit
- // STARTUP on loss, even if
- // bandwidth growth exceeds
- // threshold.
-const QuicTag kB2RP = TAG('B', '2', 'R', 'P'); // For BBRv2, run PROBE_RTT on
- // the regular schedule
-const QuicTag kB2LO = TAG('B', '2', 'L', 'O'); // Ignore inflight_lo in BBR2
-const QuicTag kB2HR = TAG('B', '2', 'H', 'R'); // 15% inflight_hi headroom.
-const QuicTag kB2SL = TAG('B', '2', 'S', 'L'); // When exiting STARTUP due to
- // loss, set inflight_hi to the
- // max of bdp and max bytes
- // delivered in round.
-const QuicTag kB2H2 = TAG('B', '2', 'H', '2'); // When exiting PROBE_UP due to
- // loss, set inflight_hi to the
- // max of inflight@send and max
- // bytes delivered in round.
-const QuicTag kB2RC = TAG('B', '2', 'R', 'C'); // Disable Reno-coexistence for
- // BBR2.
-const QuicTag kBSAO = TAG('B', 'S', 'A', 'O'); // Avoid Overestimation in
- // Bandwidth Sampler with ack
- // aggregation
-const QuicTag kB2DL = TAG('B', '2', 'D', 'L'); // Increase inflight_hi based
- // on delievered, not inflight.
-const QuicTag kB201 = TAG('B', '2', '0', '1'); // In PROBE_UP, check if cwnd
- // limited before aggregation
- // epoch, instead of ack event.
-const QuicTag kB202 = TAG('B', '2', '0', '2'); // Do not exit PROBE_UP if
- // inflight dips below 1.25*BW.
-const QuicTag kB203 = TAG('B', '2', '0', '3'); // Ignore inflight_hi until
- // PROBE_UP is exited.
-const QuicTag kB204 = TAG('B', '2', '0', '4'); // Reduce extra acked when
- // MaxBW incrases.
-const QuicTag kB205 = TAG('B', '2', '0', '5'); // Add extra acked to CWND in
- // STARTUP.
-const QuicTag kB206 = TAG('B', '2', '0', '6'); // Exit STARTUP after 2 losses.
-const QuicTag kB207 = TAG('B', '2', '0', '7'); // Exit STARTUP on persistent
- // queue
-const QuicTag kNTLP = TAG('N', 'T', 'L', 'P'); // No tail loss probe
-const QuicTag k1TLP = TAG('1', 'T', 'L', 'P'); // 1 tail loss probe
-const QuicTag k1RTO = TAG('1', 'R', 'T', 'O'); // Send 1 packet upon RTO
-const QuicTag kNRTO = TAG('N', 'R', 'T', 'O'); // CWND reduction on loss
-const QuicTag kTIME = TAG('T', 'I', 'M', 'E'); // Time based loss detection
-const QuicTag kATIM = TAG('A', 'T', 'I', 'M'); // Adaptive time loss detection
-const QuicTag kMIN1 = TAG('M', 'I', 'N', '1'); // Min CWND of 1 packet
-const QuicTag kMIN4 = TAG('M', 'I', 'N', '4'); // Min CWND of 4 packets,
- // with a min rate of 1 BDP.
-const QuicTag kTLPR = TAG('T', 'L', 'P', 'R'); // Tail loss probe delay of
- // 0.5RTT.
-const QuicTag kMAD0 = TAG('M', 'A', 'D', '0'); // Ignore ack delay
-const QuicTag kMAD2 = TAG('M', 'A', 'D', '2'); // No min TLP
-const QuicTag kMAD3 = TAG('M', 'A', 'D', '3'); // No min RTO
-const QuicTag k1ACK = TAG('1', 'A', 'C', 'K'); // 1 fast ack for reordering
-const QuicTag kAKD3 = TAG('A', 'K', 'D', '3'); // Ack decimation style acking
- // with 1/8 RTT acks.
-const QuicTag kAKDU = TAG('A', 'K', 'D', 'U'); // Unlimited number of packets
- // received before acking
-const QuicTag kAFFE = TAG('A', 'F', 'F', 'E'); // Enable client receiving
- // AckFrequencyFrame.
-const QuicTag kAFF1 = TAG('A', 'F', 'F', '1'); // Use SRTT in building
- // AckFrequencyFrame.
-const QuicTag kAFF2 = TAG('A', 'F', 'F', '2'); // Send AckFrequencyFrame upon
- // handshake completion.
-const QuicTag kSSLR = TAG('S', 'S', 'L', 'R'); // Slow Start Large Reduction.
-const QuicTag kNPRR = TAG('N', 'P', 'R', 'R'); // Pace at unity instead of PRR
-const QuicTag k2RTO = TAG('2', 'R', 'T', 'O'); // Close connection on 2 RTOs
-const QuicTag k3RTO = TAG('3', 'R', 'T', 'O'); // Close connection on 3 RTOs
-const QuicTag k4RTO = TAG('4', 'R', 'T', 'O'); // Close connection on 4 RTOs
-const QuicTag k5RTO = TAG('5', 'R', 'T', 'O'); // Close connection on 5 RTOs
-const QuicTag k6RTO = TAG('6', 'R', 'T', 'O'); // Close connection on 6 RTOs
-const QuicTag kCBHD = TAG('C', 'B', 'H', 'D'); // Client only blackhole
- // detection.
-const QuicTag kNBHD = TAG('N', 'B', 'H', 'D'); // No blackhole detection.
-const QuicTag kCONH = TAG('C', 'O', 'N', 'H'); // Conservative Handshake
- // Retransmissions.
-const QuicTag kLFAK = TAG('L', 'F', 'A', 'K'); // Don't invoke FACK on the
- // first ack.
-const QuicTag kSTMP = TAG('S', 'T', 'M', 'P'); // DEPRECATED
-const QuicTag kEACK = TAG('E', 'A', 'C', 'K'); // Bundle ack-eliciting frame
- // with an ACK after PTO/RTO
-
-const QuicTag kILD0 = TAG('I', 'L', 'D', '0'); // IETF style loss detection
- // (default with 1/8 RTT time
- // threshold)
-const QuicTag kILD1 = TAG('I', 'L', 'D', '1'); // IETF style loss detection
- // with 1/4 RTT time threshold
-const QuicTag kILD2 = TAG('I', 'L', 'D', '2'); // IETF style loss detection
- // with adaptive packet
- // threshold
-const QuicTag kILD3 = TAG('I', 'L', 'D', '3'); // IETF style loss detection
- // with 1/4 RTT time threshold
- // and adaptive packet
- // threshold
-const QuicTag kILD4 = TAG('I', 'L', 'D', '4'); // IETF style loss detection
- // with both adaptive time
- // threshold (default 1/4 RTT)
- // and adaptive packet
- // threshold
-const QuicTag kRUNT = TAG('R', 'U', 'N', 'T'); // No packet threshold loss
- // detection for "runt" packet.
-const QuicTag kNSTP = TAG('N', 'S', 'T', 'P'); // No stop waiting frames.
-const QuicTag kNRTT = TAG('N', 'R', 'T', 'T'); // Ignore initial RTT
-
-const QuicTag k1PTO = TAG('1', 'P', 'T', 'O'); // Send 1 packet upon PTO.
-const QuicTag k2PTO = TAG('2', 'P', 'T', 'O'); // Send 2 packets upon PTO.
-
-const QuicTag k6PTO = TAG('6', 'P', 'T', 'O'); // Closes connection on 6
- // consecutive PTOs.
-const QuicTag k7PTO = TAG('7', 'P', 'T', 'O'); // Closes connection on 7
- // consecutive PTOs.
-const QuicTag k8PTO = TAG('8', 'P', 'T', 'O'); // Closes connection on 8
- // consecutive PTOs.
-const QuicTag kPTOS = TAG('P', 'T', 'O', 'S'); // Skip packet number before
- // sending the last PTO.
-const QuicTag kPTOA = TAG('P', 'T', 'O', 'A'); // Do not add max ack delay
- // when computing PTO timeout
- // if an immediate ACK is
- // expected.
-const QuicTag kPEB1 = TAG('P', 'E', 'B', '1'); // Start exponential backoff
- // since 1st PTO.
-const QuicTag kPEB2 = TAG('P', 'E', 'B', '2'); // Start exponential backoff
- // since 2nd PTO.
-const QuicTag kPVS1 = TAG('P', 'V', 'S', '1'); // Use 2 * rttvar when
- // calculating PTO timeout.
-const QuicTag kPAG1 = TAG('P', 'A', 'G', '1'); // Make 1st PTO more aggressive
-const QuicTag kPAG2 = TAG('P', 'A', 'G', '2'); // Make first 2 PTOs more
- // aggressive
-const QuicTag kPSDA = TAG('P', 'S', 'D', 'A'); // Use standard deviation when
- // calculating PTO timeout.
-const QuicTag kPLE1 = TAG('P', 'L', 'E', '1'); // Arm the 1st PTO with
- // earliest in flight sent time
- // and at least 0.5*srtt from
- // last sent packet.
-const QuicTag kPLE2 = TAG('P', 'L', 'E', '2'); // Arm the 1st PTO with
- // earliest in flight sent time
- // and at least 1.5*srtt from
- // last sent packet.
-const QuicTag kAPTO = TAG('A', 'P', 'T', 'O'); // Use 1.5 * initial RTT before
- // any RTT sample is available.
-
-const QuicTag kELDT = TAG('E', 'L', 'D', 'T'); // Enable Loss Detection Tuning
-
-// TODO(haoyuewang) Remove RVCM option once
-// --quic_remove_connection_migration_connection_option is deprecated.
-const QuicTag kRVCM = TAG('R', 'V', 'C', 'M'); // Validate the new address
- // upon client address change.
-
-// Optional support of truncated Connection IDs. If sent by a peer, the value
-// is the minimum number of bytes allowed for the connection ID sent to the
-// peer.
-const QuicTag kTCID = TAG('T', 'C', 'I', 'D'); // Connection ID truncation.
-
-// Multipath option.
-const QuicTag kMPTH = TAG('M', 'P', 'T', 'H'); // Enable multipath.
-
-const QuicTag kNCMR = TAG('N', 'C', 'M', 'R'); // Do not attempt connection
- // migration.
-
-// Allows disabling defer_send_in_response_to_packets in QuicConnection.
-const QuicTag kDFER = TAG('D', 'F', 'E', 'R'); // Do not defer sending.
-
-// Disable Pacing offload option.
-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 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.
-const QuicTag kBWS4 = TAG('B', 'W', 'S', '4'); // QUIC Initial CWND - Enabled.
-const QuicTag kBWS5 = TAG('B', 'W', 'S', '5'); // QUIC Initial CWND up and down
-const QuicTag kBWS6 = TAG('B', 'W', 'S', '6'); // QUIC Initial CWND - Enabled
- // with 0.5 * default
- // multiplier.
-const QuicTag kBWP0 = TAG('B', 'W', 'P', '0'); // QUIC Initial CWND - SPDY
- // priority 0.
-const QuicTag kBWP1 = TAG('B', 'W', 'P', '1'); // QUIC Initial CWND - SPDY
- // priorities 0 and 1.
-const QuicTag kBWP2 = TAG('B', 'W', 'P', '2'); // QUIC Initial CWND - SPDY
- // priorities 0, 1 and 2.
-const QuicTag kBWP3 = TAG('B', 'W', 'P', '3'); // QUIC Initial CWND - SPDY
- // priorities 0, 1, 2 and 3.
-const QuicTag kBWP4 = TAG('B', 'W', 'P', '4'); // QUIC Initial CWND - SPDY
- // priorities >= 0, 1, 2, 3 and
- // 4.
-const QuicTag kBWG4 = TAG('B', 'W', 'G', '4'); // QUIC Initial CWND -
- // Bandwidth model 1.
-const QuicTag kBWG7 = TAG('B', 'W', 'G', '7'); // QUIC Initial CWND -
- // Bandwidth model 2.
-const QuicTag kBWG8 = TAG('B', 'W', 'G', '8'); // QUIC Initial CWND -
- // Bandwidth model 3.
-const QuicTag kBWS7 = TAG('B', 'W', 'S', '7'); // QUIC Initial CWND - Enabled
- // with 0.75 * default
- // multiplier.
-const QuicTag kBWM3 = TAG('B', 'W', 'M', '3'); // Consider overshooting if
- // bytes lost after bandwidth
- // resumption * 3 > IW.
-const QuicTag kBWM4 = TAG('B', 'W', 'M', '4'); // Consider overshooting if
- // bytes lost after bandwidth
- // resumption * 4 > IW.
-const QuicTag kICW1 = TAG('I', 'C', 'W', '1'); // Max initial congestion window
- // 100.
-const QuicTag kDTOS = TAG('D', 'T', 'O', 'S'); // Enable overshooting
- // detection.
-
-const QuicTag kFIDT = TAG('F', 'I', 'D', 'T'); // Extend idle timer by PTO
- // instead of the whole idle
- // timeout.
-
-const QuicTag k3AFF = TAG('3', 'A', 'F', 'F'); // 3 anti amplification factor.
-const QuicTag k10AF = TAG('1', '0', 'A', 'F'); // 10 anti amplification factor.
-
-// Enable path MTU discovery experiment.
-const QuicTag kMTUH = TAG('M', 'T', 'U', 'H'); // High-target MTU discovery.
-const QuicTag kMTUL = TAG('M', 'T', 'U', 'L'); // Low-target MTU discovery.
-
-const QuicTag kNSLC = TAG('N', 'S', 'L', 'C'); // Always send connection close
- // for idle timeout.
-const QuicTag kNCHP = TAG('N', 'C', 'H', 'P'); // No chaos protection.
-const QuicTag kNBPE = TAG('N', 'B', 'P', 'E'); // No BoringSSL Permutes
- // TLS Extensions.
-
-// Proof types (i.e. certificate types)
-// NOTE: although it would be silly to do so, specifying both kX509 and kX59R
-// is allowed and is equivalent to specifying only kX509.
-const QuicTag kX509 = TAG('X', '5', '0', '9'); // X.509 certificate, all key
- // types
-const QuicTag kX59R = TAG('X', '5', '9', 'R'); // X.509 certificate, RSA keys
- // only
-const QuicTag kCHID = TAG('C', 'H', 'I', 'D'); // Channel ID.
-
-// Client hello tags
-const QuicTag kVER = TAG('V', 'E', 'R', '\0'); // Version
-const QuicTag kNONC = TAG('N', 'O', 'N', 'C'); // The client's nonce
-const QuicTag kNONP = TAG('N', 'O', 'N', 'P'); // The client's proof nonce
-const QuicTag kKEXS = TAG('K', 'E', 'X', 'S'); // Key exchange methods
-const QuicTag kAEAD = TAG('A', 'E', 'A', 'D'); // Authenticated
- // encryption algorithms
-const QuicTag kCOPT = TAG('C', 'O', 'P', 'T'); // Connection options
-const QuicTag kCLOP = TAG('C', 'L', 'O', 'P'); // Client connection options
-const QuicTag kICSL = TAG('I', 'C', 'S', 'L'); // Idle network timeout
-const QuicTag kMIBS = TAG('M', 'I', 'D', 'S'); // Max incoming bidi streams
-const QuicTag kMIUS = TAG('M', 'I', 'U', 'S'); // Max incoming unidi streams
-const QuicTag kADE = TAG('A', 'D', 'E', 0); // Ack Delay Exponent (IETF
- // QUIC ACK Frame Only).
-const QuicTag kIRTT = TAG('I', 'R', 'T', 'T'); // Estimated initial RTT in us.
-const QuicTag kTRTT = TAG('T', 'R', 'T', 'T'); // If server receives an rtt
- // from an address token, set
- // it as the initial rtt.
-const QuicTag kSNI = TAG('S', 'N', 'I', '\0'); // Server name
- // indication
-const QuicTag kPUBS = TAG('P', 'U', 'B', 'S'); // Public key values
-const QuicTag kSCID = TAG('S', 'C', 'I', 'D'); // Server config id
-const QuicTag kORBT = TAG('O', 'B', 'I', 'T'); // Server orbit.
-const QuicTag kPDMD = TAG('P', 'D', 'M', 'D'); // Proof demand.
-const QuicTag kPROF = TAG('P', 'R', 'O', 'F'); // Proof (signature).
-const QuicTag kCCS = TAG('C', 'C', 'S', 0); // Common certificate set
-const QuicTag kCCRT = TAG('C', 'C', 'R', 'T'); // Cached certificate
-const QuicTag kEXPY = TAG('E', 'X', 'P', 'Y'); // Expiry
-const QuicTag kSTTL = TAG('S', 'T', 'T', 'L'); // Server Config TTL
-const QuicTag kSFCW = TAG('S', 'F', 'C', 'W'); // Initial stream flow control
- // receive window.
-const QuicTag kCFCW = TAG('C', 'F', 'C', 'W'); // Initial session/connection
- // flow control receive window.
-const QuicTag kUAID = TAG('U', 'A', 'I', 'D'); // Client's User Agent ID.
-const QuicTag kXLCT = TAG('X', 'L', 'C', 'T'); // Expected leaf certificate.
-const QuicTag kQLVE = TAG('Q', 'L', 'V', 'E'); // Legacy Version
- // Encapsulation.
-
-const QuicTag kPDP1 = TAG('P', 'D', 'P', '1'); // Path degrading triggered
- // at 1PTO.
-
-const QuicTag kPDP2 = TAG('P', 'D', 'P', '2'); // Path degrading triggered
- // at 2PTO.
-
-const QuicTag kPDP3 = TAG('P', 'D', 'P', '3'); // Path degrading triggered
- // at 3PTO.
-
-const QuicTag kPDP4 = TAG('P', 'D', 'P', '4'); // Path degrading triggered
- // at 4PTO.
-
-const QuicTag kPDP5 = TAG('P', 'D', 'P', '5'); // Path degrading triggered
- // at 5PTO.
-
-const QuicTag kQNZ2 = TAG('Q', 'N', 'Z', '2'); // Turn off QUIC crypto 0-RTT.
-
-const QuicTag kMAD = TAG('M', 'A', 'D', 0); // Max Ack Delay (IETF QUIC)
-
-const QuicTag kIGNP = TAG('I', 'G', 'N', 'P'); // Do not use PING only packet
- // for RTT measure or
- // congestion control.
-
-const QuicTag kSRWP = TAG('S', 'R', 'W', 'P'); // Enable retransmittable on
- // wire PING (ROWP) on the
- // server side.
-
-// Client Hints triggers.
-const QuicTag kGWCH = TAG('G', 'W', 'C', 'H');
-const QuicTag kYTCH = TAG('Y', 'T', 'C', 'H');
-const QuicTag kACH0 = TAG('A', 'C', 'H', '0');
-
-// Rejection tags
-const QuicTag kRREJ = TAG('R', 'R', 'E', 'J'); // Reasons for server sending
-
-// Server hello tags
-const QuicTag kCADR = TAG('C', 'A', 'D', 'R'); // Client IP address and port
-const QuicTag kASAD = TAG('A', 'S', 'A', 'D'); // Alternate Server IP address
- // and port.
-const QuicTag kSRST = TAG('S', 'R', 'S', 'T'); // Stateless reset token used
- // in IETF public reset packet
-
-// CETV tags
-const QuicTag kCIDK = TAG('C', 'I', 'D', 'K'); // ChannelID key
-const QuicTag kCIDS = TAG('C', 'I', 'D', 'S'); // ChannelID signature
-
-// Public reset tags
-const QuicTag kRNON = TAG('R', 'N', 'O', 'N'); // Public reset nonce proof
-const QuicTag kRSEQ = TAG('R', 'S', 'E', 'Q'); // Rejected packet number
-
-// Universal tags
-const QuicTag kPAD = TAG('P', 'A', 'D', '\0'); // Padding
-
-// Stats collection tags
-const QuicTag kEPID = TAG('E', 'P', 'I', 'D'); // Endpoint identifier.
-
-// clang-format on
-
-// These tags have a special form so that they appear either at the beginning
-// or the end of a handshake message. Since handshake messages are sorted by
-// tag value, the tags with 0 at the end will sort first and those with 255 at
-// the end will sort last.
-//
-// The certificate chain should have a tag that will cause it to be sorted at
-// the end of any handshake messages because it's likely to be large and the
-// client might be able to get everything that it needs from the small values at
-// the beginning.
-//
-// Likewise tags with random values should be towards the beginning of the
-// message because the server mightn't hold state for a rejected client hello
-// and therefore the client may have issues reassembling the rejection message
-// in the event that it sent two client hellos.
-const QuicTag kServerNonceTag = TAG('S', 'N', 'O', 0); // The server's nonce
-const QuicTag kSourceAddressTokenTag =
- TAG('S', 'T', 'K', 0); // Source-address token
-const QuicTag kCertificateTag = TAG('C', 'R', 'T', 255); // Certificate chain
-const QuicTag kCertificateSCTTag =
- TAG('C', 'S', 'C', 'T'); // Signed cert timestamp (RFC6962) of leaf cert.
-
-#undef TAG
-
-const size_t kMaxEntries = 128; // Max number of entries in a message.
-
-const size_t kNonceSize = 32; // Size in bytes of the connection nonce.
-
-const size_t kOrbitSize = 8; // Number of bytes in an orbit value.
-
-// kProofSignatureLabel is prepended to the CHLO hash and server configs before
-// signing to avoid any cross-protocol attacks on the signature.
-const char kProofSignatureLabel[] = "QUIC CHLO and server config signature";
-
-// kClientHelloMinimumSize is the minimum size of a client hello. Client hellos
-// will have PAD tags added in order to ensure this minimum is met and client
-// hellos smaller than this will be an error. This minimum size reduces the
-// amplification factor of any mirror DoS attack.
-//
-// A client may pad an inchoate client hello to a size larger than
-// kClientHelloMinimumSize to make it more likely to receive a complete
-// rejection message.
-const size_t kClientHelloMinimumSize = 1024;
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_CRYPTO_CRYPTO_PROTOCOL_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_secret_boxer.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_secret_boxer.cc
deleted file mode 100644
index a4a7a2a615d..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_secret_boxer.cc
+++ /dev/null
@@ -1,148 +0,0 @@
-// Copyright (c) 2013 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 <cstdint>
-#include <string>
-
-#include "quic/core/crypto/crypto_secret_boxer.h"
-
-#include "absl/strings/string_view.h"
-#include "third_party/boringssl/src/include/openssl/aead.h"
-#include "third_party/boringssl/src/include/openssl/err.h"
-#include "quic/core/crypto/quic_random.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-// kSIVNonceSize contains the number of bytes of nonce in each AES-GCM-SIV box.
-// AES-GCM-SIV takes a 12-byte nonce and, since the messages are so small, each
-// key is good for more than 2^64 source-address tokens. See table 1 of
-// https://eprint.iacr.org/2017/168.pdf
-static const size_t kSIVNonceSize = 12;
-
-// AES-GCM-SIV comes in AES-128 and AES-256 flavours. The AES-256 version is
-// used here so that the key size matches the 256-bit XSalsa20 keys that we
-// used to use.
-static const size_t kBoxKeySize = 32;
-
-struct CryptoSecretBoxer::State {
- // ctxs are the initialised AEAD contexts. These objects contain the
- // scheduled AES state for each of the keys.
- std::vector<bssl::UniquePtr<EVP_AEAD_CTX>> ctxs;
-};
-
-CryptoSecretBoxer::CryptoSecretBoxer() {}
-
-CryptoSecretBoxer::~CryptoSecretBoxer() {}
-
-// static
-size_t CryptoSecretBoxer::GetKeySize() {
- return kBoxKeySize;
-}
-
-// kAEAD is the AEAD used for boxing: AES-256-GCM-SIV.
-static const EVP_AEAD* (*const kAEAD)() = EVP_aead_aes_256_gcm_siv;
-
-bool CryptoSecretBoxer::SetKeys(const std::vector<std::string>& keys) {
- if (keys.empty()) {
- QUIC_LOG(DFATAL) << "No keys supplied!";
- return false;
- }
- const EVP_AEAD* const aead = kAEAD();
- std::unique_ptr<State> new_state(new State);
-
- for (const std::string& key : keys) {
- QUICHE_DCHECK_EQ(kBoxKeySize, key.size());
- bssl::UniquePtr<EVP_AEAD_CTX> ctx(
- EVP_AEAD_CTX_new(aead, reinterpret_cast<const uint8_t*>(key.data()),
- key.size(), EVP_AEAD_DEFAULT_TAG_LENGTH));
- if (!ctx) {
- ERR_clear_error();
- QUIC_LOG(DFATAL) << "EVP_AEAD_CTX_init failed";
- return false;
- }
-
- new_state->ctxs.push_back(std::move(ctx));
- }
-
- QuicWriterMutexLock l(&lock_);
- state_ = std::move(new_state);
- return true;
-}
-
-std::string CryptoSecretBoxer::Box(QuicRandom* rand,
- absl::string_view plaintext) const {
- // The box is formatted as:
- // 12 bytes of random nonce
- // n bytes of ciphertext
- // 16 bytes of authenticator
- size_t out_len =
- kSIVNonceSize + plaintext.size() + EVP_AEAD_max_overhead(kAEAD());
-
- std::string ret;
- ret.resize(out_len);
- uint8_t* out = reinterpret_cast<uint8_t*>(const_cast<char*>(ret.data()));
-
- // Write kSIVNonceSize bytes of random nonce to the beginning of the output
- // buffer.
- rand->RandBytes(out, kSIVNonceSize);
- const uint8_t* const nonce = out;
- out += kSIVNonceSize;
- out_len -= kSIVNonceSize;
-
- size_t bytes_written;
- {
- QuicReaderMutexLock l(&lock_);
- if (!EVP_AEAD_CTX_seal(state_->ctxs[0].get(), out, &bytes_written, out_len,
- nonce, kSIVNonceSize,
- reinterpret_cast<const uint8_t*>(plaintext.data()),
- plaintext.size(), nullptr, 0)) {
- ERR_clear_error();
- QUIC_LOG(DFATAL) << "EVP_AEAD_CTX_seal failed";
- return "";
- }
- }
-
- QUICHE_DCHECK_EQ(out_len, bytes_written);
- return ret;
-}
-
-bool CryptoSecretBoxer::Unbox(absl::string_view in_ciphertext,
- std::string* out_storage,
- absl::string_view* out) const {
- if (in_ciphertext.size() < kSIVNonceSize) {
- return false;
- }
-
- const uint8_t* const nonce =
- reinterpret_cast<const uint8_t*>(in_ciphertext.data());
- const uint8_t* const ciphertext = nonce + kSIVNonceSize;
- const size_t ciphertext_len = in_ciphertext.size() - kSIVNonceSize;
-
- out_storage->resize(ciphertext_len);
-
- bool ok = false;
- {
- QuicReaderMutexLock l(&lock_);
- for (const bssl::UniquePtr<EVP_AEAD_CTX>& ctx : state_->ctxs) {
- size_t bytes_written;
- if (EVP_AEAD_CTX_open(ctx.get(),
- reinterpret_cast<uint8_t*>(
- const_cast<char*>(out_storage->data())),
- &bytes_written, ciphertext_len, nonce,
- kSIVNonceSize, ciphertext, ciphertext_len, nullptr,
- 0)) {
- ok = true;
- *out = absl::string_view(out_storage->data(), bytes_written);
- break;
- }
-
- ERR_clear_error();
- }
- }
-
- return ok;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_secret_boxer.h b/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_secret_boxer.h
deleted file mode 100644
index e2cd0377786..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_secret_boxer.h
+++ /dev/null
@@ -1,69 +0,0 @@
-// Copyright (c) 2013 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_CRYPTO_CRYPTO_SECRET_BOXER_H_
-#define QUICHE_QUIC_CORE_CRYPTO_CRYPTO_SECRET_BOXER_H_
-
-#include <cstddef>
-#include <memory>
-#include <string>
-#include <vector>
-
-#include "absl/strings/string_view.h"
-#include "quic/platform/api/quic_export.h"
-#include "quic/platform/api/quic_mutex.h"
-
-namespace quic {
-
-class QuicRandom;
-
-// CryptoSecretBoxer encrypts small chunks of plaintext (called 'boxing') and
-// then, later, can authenticate+decrypt the resulting boxes. This object is
-// thread-safe.
-class QUIC_EXPORT_PRIVATE CryptoSecretBoxer {
- public:
- CryptoSecretBoxer();
- CryptoSecretBoxer(const CryptoSecretBoxer&) = delete;
- CryptoSecretBoxer& operator=(const CryptoSecretBoxer&) = delete;
- ~CryptoSecretBoxer();
-
- // GetKeySize returns the number of bytes in a key.
- static size_t GetKeySize();
-
- // SetKeys sets a list of encryption keys. The first key in the list will be
- // used by |Box|, but all supplied keys will be tried by |Unbox|, to handle
- // key skew across the fleet. This must be called before |Box| or |Unbox|.
- // Keys must be |GetKeySize()| bytes long. No change is made if any key is
- // invalid, or if there are no keys supplied.
- bool SetKeys(const std::vector<std::string>& keys);
-
- // Box encrypts |plaintext| using a random nonce generated from |rand| and
- // returns the resulting ciphertext. Since an authenticator and nonce are
- // included, the result will be slightly larger than |plaintext|. The first
- // key in the vector supplied to |SetKeys| will be used. |SetKeys| must be
- // called before calling this method.
- std::string Box(QuicRandom* rand, absl::string_view plaintext) const;
-
- // Unbox takes the result of a previous call to |Box| in |ciphertext| and
- // authenticates+decrypts it. If |ciphertext| cannot be decrypted with any of
- // the supplied keys, the function returns false. Otherwise, |out_storage| is
- // used to store the result and |out| is set to point into |out_storage| and
- // contains the original plaintext.
- bool Unbox(absl::string_view ciphertext,
- std::string* out_storage,
- absl::string_view* out) const;
-
- private:
- struct State;
-
- mutable QuicMutex lock_;
-
- // state_ is an opaque pointer to whatever additional state the concrete
- // implementation of CryptoSecretBoxer requires.
- std::unique_ptr<State> state_ QUIC_GUARDED_BY(lock_);
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_CRYPTO_CRYPTO_SECRET_BOXER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_secret_boxer_test.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_secret_boxer_test.cc
deleted file mode 100644
index 7b07d96d11d..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_secret_boxer_test.cc
+++ /dev/null
@@ -1,82 +0,0 @@
-// Copyright (c) 2013 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 "quic/core/crypto/crypto_secret_boxer.h"
-
-#include <string>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/crypto/quic_random.h"
-#include "quic/platform/api/quic_test.h"
-
-namespace quic {
-namespace test {
-
-class CryptoSecretBoxerTest : public QuicTest {};
-
-TEST_F(CryptoSecretBoxerTest, BoxAndUnbox) {
- absl::string_view message("hello world");
-
- CryptoSecretBoxer boxer;
- boxer.SetKeys({std::string(CryptoSecretBoxer::GetKeySize(), 0x11)});
-
- const std::string box = boxer.Box(QuicRandom::GetInstance(), message);
-
- std::string storage;
- absl::string_view result;
- EXPECT_TRUE(boxer.Unbox(box, &storage, &result));
- EXPECT_EQ(result, message);
-
- EXPECT_FALSE(boxer.Unbox(std::string(1, 'X') + box, &storage, &result));
- EXPECT_FALSE(
- boxer.Unbox(box.substr(1, std::string::npos), &storage, &result));
- EXPECT_FALSE(boxer.Unbox(std::string(), &storage, &result));
- EXPECT_FALSE(boxer.Unbox(
- std::string(1, box[0] ^ 0x80) + box.substr(1, std::string::npos),
- &storage, &result));
-}
-
-// Helper function to test whether one boxer can decode the output of another.
-static bool CanDecode(const CryptoSecretBoxer& decoder,
- const CryptoSecretBoxer& encoder) {
- absl::string_view message("hello world");
- const std::string boxed = encoder.Box(QuicRandom::GetInstance(), message);
- std::string storage;
- absl::string_view result;
- bool ok = decoder.Unbox(boxed, &storage, &result);
- if (ok) {
- EXPECT_EQ(result, message);
- }
- return ok;
-}
-
-TEST_F(CryptoSecretBoxerTest, MultipleKeys) {
- std::string key_11(CryptoSecretBoxer::GetKeySize(), 0x11);
- std::string key_12(CryptoSecretBoxer::GetKeySize(), 0x12);
-
- CryptoSecretBoxer boxer_11, boxer_12, boxer;
- EXPECT_TRUE(boxer_11.SetKeys({key_11}));
- EXPECT_TRUE(boxer_12.SetKeys({key_12}));
- EXPECT_TRUE(boxer.SetKeys({key_12, key_11}));
-
- // Neither single-key boxer can decode the other's tokens.
- EXPECT_FALSE(CanDecode(boxer_11, boxer_12));
- EXPECT_FALSE(CanDecode(boxer_12, boxer_11));
-
- // |boxer| encodes with the first key, which is key_12.
- EXPECT_TRUE(CanDecode(boxer_12, boxer));
- EXPECT_FALSE(CanDecode(boxer_11, boxer));
-
- // The boxer with both keys can decode tokens from either single-key boxer.
- EXPECT_TRUE(CanDecode(boxer, boxer_11));
- EXPECT_TRUE(CanDecode(boxer, boxer_12));
-
- // After we flush key_11 from |boxer|, it can no longer decode tokens from
- // |boxer_11|.
- EXPECT_TRUE(boxer.SetKeys({key_12}));
- EXPECT_FALSE(CanDecode(boxer, boxer_11));
-}
-
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_server_test.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_server_test.cc
deleted file mode 100644
index 46a7120fda9..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_server_test.cc
+++ /dev/null
@@ -1,1132 +0,0 @@
-// Copyright (c) 2013 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 <algorithm>
-#include <cstdint>
-#include <memory>
-#include <ostream>
-#include <string>
-#include <utility>
-#include <vector>
-
-#include "absl/base/macros.h"
-#include "absl/strings/escaping.h"
-#include "absl/strings/match.h"
-#include "absl/strings/str_cat.h"
-#include "absl/strings/string_view.h"
-#include "third_party/boringssl/src/include/openssl/sha.h"
-#include "quic/core/crypto/cert_compressor.h"
-#include "quic/core/crypto/common_cert_set.h"
-#include "quic/core/crypto/crypto_handshake.h"
-#include "quic/core/crypto/crypto_utils.h"
-#include "quic/core/crypto/proof_source.h"
-#include "quic/core/crypto/quic_crypto_server_config.h"
-#include "quic/core/crypto/quic_random.h"
-#include "quic/core/proto/crypto_server_config_proto.h"
-#include "quic/core/quic_socket_address_coder.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/crypto_test_utils.h"
-#include "quic/test_tools/failing_proof_source.h"
-#include "quic/test_tools/mock_clock.h"
-#include "quic/test_tools/mock_random.h"
-#include "quic/test_tools/quic_crypto_server_config_peer.h"
-#include "quic/test_tools/quic_test_utils.h"
-#include "common/quiche_endian.h"
-
-namespace quic {
-namespace test {
-
-namespace {
-
-class DummyProofVerifierCallback : public ProofVerifierCallback {
- public:
- DummyProofVerifierCallback() {}
- ~DummyProofVerifierCallback() override {}
-
- void Run(bool /*ok*/,
- const std::string& /*error_details*/,
- std::unique_ptr<ProofVerifyDetails>* /*details*/) override {
- QUICHE_DCHECK(false);
- }
-};
-
-const char kOldConfigId[] = "old-config-id";
-
-} // namespace
-
-struct TestParams {
- friend std::ostream& operator<<(std::ostream& os, const TestParams& p) {
- os << " versions: "
- << ParsedQuicVersionVectorToString(p.supported_versions) << " }";
- return os;
- }
-
- // Versions supported by client and server.
- ParsedQuicVersionVector supported_versions;
-};
-
-// Used by ::testing::PrintToStringParamName().
-std::string PrintToString(const TestParams& p) {
- std::string rv = ParsedQuicVersionVectorToString(p.supported_versions);
- std::replace(rv.begin(), rv.end(), ',', '_');
- return rv;
-}
-
-// Constructs various test permutations.
-std::vector<TestParams> GetTestParams() {
- std::vector<TestParams> params;
-
- // Start with all versions, remove highest on each iteration.
- ParsedQuicVersionVector supported_versions = AllSupportedVersions();
- while (!supported_versions.empty()) {
- params.push_back({supported_versions});
- supported_versions.erase(supported_versions.begin());
- }
-
- return params;
-}
-
-class CryptoServerTest : public QuicTestWithParam<TestParams> {
- public:
- CryptoServerTest()
- : rand_(QuicRandom::GetInstance()),
- client_address_(QuicIpAddress::Loopback4(), 1234),
- client_version_(UnsupportedQuicVersion()),
- config_(QuicCryptoServerConfig::TESTING,
- rand_,
- crypto_test_utils::ProofSourceForTesting(),
- KeyExchangeSource::Default()),
- peer_(&config_),
- compressed_certs_cache_(
- QuicCompressedCertsCache::kQuicCompressedCertsCacheSize),
- params_(new QuicCryptoNegotiatedParameters),
- signed_config_(new QuicSignedServerConfig),
- chlo_packet_size_(kDefaultMaxPacketSize) {
- supported_versions_ = GetParam().supported_versions;
- config_.set_enable_serving_sct(true);
-
- client_version_ = supported_versions_.front();
- client_version_label_ = CreateQuicVersionLabel(client_version_);
- client_version_string_ =
- std::string(reinterpret_cast<const char*>(&client_version_label_),
- sizeof(client_version_label_));
- }
-
- void SetUp() override {
- QuicCryptoServerConfig::ConfigOptions old_config_options;
- old_config_options.id = kOldConfigId;
- config_.AddDefaultConfig(rand_, &clock_, old_config_options);
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(1000));
- QuicServerConfigProtobuf primary_config =
- config_.GenerateConfig(rand_, &clock_, config_options_);
- primary_config.set_primary_time(clock_.WallNow().ToUNIXSeconds());
- std::unique_ptr<CryptoHandshakeMessage> msg(
- config_.AddConfig(primary_config, clock_.WallNow()));
-
- absl::string_view orbit;
- QUICHE_CHECK(msg->GetStringPiece(kORBT, &orbit));
- QUICHE_CHECK_EQ(sizeof(orbit_), orbit.size());
- memcpy(orbit_, orbit.data(), orbit.size());
-
- char public_value[32];
- memset(public_value, 42, sizeof(public_value));
-
- nonce_hex_ = "#" + absl::BytesToHexString(GenerateNonce());
- pub_hex_ = "#" + absl::BytesToHexString(
- absl::string_view(public_value, sizeof(public_value)));
-
- CryptoHandshakeMessage client_hello =
- crypto_test_utils::CreateCHLO({{"PDMD", "X509"},
- {"AEAD", "AESG"},
- {"KEXS", "C255"},
- {"PUBS", pub_hex_},
- {"NONC", nonce_hex_},
- {"CSCT", ""},
- {"VER\0", client_version_string_}},
- kClientHelloMinimumSize);
- ShouldSucceed(client_hello);
- // The message should be rejected because the source-address token is
- // missing.
- CheckRejectTag();
- const HandshakeFailureReason kRejectReasons[] = {
- SERVER_CONFIG_INCHOATE_HELLO_FAILURE};
- CheckRejectReasons(kRejectReasons, ABSL_ARRAYSIZE(kRejectReasons));
-
- absl::string_view srct;
- ASSERT_TRUE(out_.GetStringPiece(kSourceAddressTokenTag, &srct));
- srct_hex_ = "#" + absl::BytesToHexString(srct);
-
- absl::string_view scfg;
- ASSERT_TRUE(out_.GetStringPiece(kSCFG, &scfg));
- server_config_ = CryptoFramer::ParseMessage(scfg);
-
- absl::string_view scid;
- ASSERT_TRUE(server_config_->GetStringPiece(kSCID, &scid));
- scid_hex_ = "#" + absl::BytesToHexString(scid);
-
- signed_config_ = QuicReferenceCountedPointer<QuicSignedServerConfig>(
- new QuicSignedServerConfig());
- QUICHE_DCHECK(signed_config_->chain.get() == nullptr);
- }
-
- // Helper used to accept the result of ValidateClientHello and pass
- // it on to ProcessClientHello.
- class ValidateCallback : public ValidateClientHelloResultCallback {
- public:
- ValidateCallback(CryptoServerTest* test,
- bool should_succeed,
- const char* error_substr,
- bool* called)
- : test_(test),
- should_succeed_(should_succeed),
- error_substr_(error_substr),
- called_(called) {
- *called_ = false;
- }
-
- void Run(QuicReferenceCountedPointer<Result> result,
- std::unique_ptr<ProofSource::Details> /* details */) override {
- ASSERT_FALSE(*called_);
- test_->ProcessValidationResult(std::move(result), should_succeed_,
- error_substr_);
- *called_ = true;
- }
-
- private:
- CryptoServerTest* test_;
- const bool should_succeed_;
- const char* const error_substr_;
- bool* called_;
- };
-
- void CheckServerHello(const CryptoHandshakeMessage& server_hello) {
- QuicVersionLabelVector versions;
- server_hello.GetVersionLabelList(kVER, &versions);
- ASSERT_EQ(supported_versions_.size(), versions.size());
- for (size_t i = 0; i < versions.size(); ++i) {
- EXPECT_EQ(CreateQuicVersionLabel(supported_versions_[i]), versions[i]);
- }
-
- absl::string_view address;
- ASSERT_TRUE(server_hello.GetStringPiece(kCADR, &address));
- QuicSocketAddressCoder decoder;
- ASSERT_TRUE(decoder.Decode(address.data(), address.size()));
- EXPECT_EQ(client_address_.host(), decoder.ip());
- EXPECT_EQ(client_address_.port(), decoder.port());
- }
-
- void ShouldSucceed(const CryptoHandshakeMessage& message) {
- bool called = false;
- QuicSocketAddress server_address(QuicIpAddress::Any4(), 5);
- config_.ValidateClientHello(
- message, client_address_, server_address,
- supported_versions_.front().transport_version, &clock_, signed_config_,
- std::make_unique<ValidateCallback>(this, true, "", &called));
- EXPECT_TRUE(called);
- }
-
- void ShouldFailMentioning(const char* error_substr,
- const CryptoHandshakeMessage& message) {
- bool called = false;
- ShouldFailMentioning(error_substr, message, &called);
- EXPECT_TRUE(called);
- }
-
- void ShouldFailMentioning(const char* error_substr,
- const CryptoHandshakeMessage& message,
- bool* called) {
- QuicSocketAddress server_address(QuicIpAddress::Any4(), 5);
- config_.ValidateClientHello(
- message, client_address_, server_address,
- supported_versions_.front().transport_version, &clock_, signed_config_,
- std::make_unique<ValidateCallback>(this, false, error_substr, called));
- }
-
- class ProcessCallback : public ProcessClientHelloResultCallback {
- public:
- ProcessCallback(
- QuicReferenceCountedPointer<ValidateCallback::Result> result,
- bool should_succeed,
- const char* error_substr,
- bool* called,
- CryptoHandshakeMessage* out)
- : result_(std::move(result)),
- should_succeed_(should_succeed),
- error_substr_(error_substr),
- called_(called),
- out_(out) {
- *called_ = false;
- }
-
- void Run(QuicErrorCode error,
- const std::string& error_details,
- std::unique_ptr<CryptoHandshakeMessage> message,
- std::unique_ptr<DiversificationNonce> /*diversification_nonce*/,
- std::unique_ptr<ProofSource::Details> /*proof_source_details*/)
- override {
- if (should_succeed_) {
- ASSERT_EQ(error, QUIC_NO_ERROR)
- << "Message failed with error " << error_details << ": "
- << result_->client_hello.DebugString();
- } else {
- ASSERT_NE(error, QUIC_NO_ERROR)
- << "Message didn't fail: " << result_->client_hello.DebugString();
- EXPECT_TRUE(absl::StrContains(error_details, error_substr_))
- << error_substr_ << " not in " << error_details;
- }
- if (message != nullptr) {
- *out_ = *message;
- }
- *called_ = true;
- }
-
- private:
- const QuicReferenceCountedPointer<ValidateCallback::Result> result_;
- const bool should_succeed_;
- const char* const error_substr_;
- bool* called_;
- CryptoHandshakeMessage* out_;
- };
-
- void ProcessValidationResult(
- QuicReferenceCountedPointer<ValidateCallback::Result> result,
- bool should_succeed,
- const char* error_substr) {
- QuicSocketAddress server_address(QuicIpAddress::Any4(), 5);
- bool called;
- config_.ProcessClientHello(
- result, /*reject_only=*/false,
- /*connection_id=*/TestConnectionId(1), server_address, client_address_,
- supported_versions_.front(), supported_versions_, &clock_, rand_,
- &compressed_certs_cache_, params_, signed_config_,
- /*total_framing_overhead=*/50, chlo_packet_size_,
- std::make_unique<ProcessCallback>(result, should_succeed, error_substr,
- &called, &out_));
- EXPECT_TRUE(called);
- }
-
- std::string GenerateNonce() {
- std::string nonce;
- CryptoUtils::GenerateNonce(
- clock_.WallNow(), rand_,
- absl::string_view(reinterpret_cast<const char*>(orbit_),
- sizeof(orbit_)),
- &nonce);
- return nonce;
- }
-
- void CheckRejectReasons(
- const HandshakeFailureReason* expected_handshake_failures,
- size_t expected_count) {
- QuicTagVector reject_reasons;
- static_assert(sizeof(QuicTag) == sizeof(uint32_t), "header out of sync");
- QuicErrorCode error_code = out_.GetTaglist(kRREJ, &reject_reasons);
- ASSERT_THAT(error_code, IsQuicNoError());
-
- EXPECT_EQ(expected_count, reject_reasons.size());
- for (size_t i = 0; i < reject_reasons.size(); ++i) {
- EXPECT_EQ(static_cast<QuicTag>(expected_handshake_failures[i]),
- reject_reasons[i]);
- }
- }
-
- void CheckRejectTag() {
- ASSERT_EQ(kREJ, out_.tag()) << QuicTagToString(out_.tag());
- }
-
- std::string XlctHexString() {
- uint64_t xlct = crypto_test_utils::LeafCertHashForTesting();
- return "#" + absl::BytesToHexString(absl::string_view(
- reinterpret_cast<char*>(&xlct), sizeof(xlct)));
- }
-
- protected:
- QuicRandom* const rand_;
- MockRandom rand_for_id_generation_;
- MockClock clock_;
- QuicSocketAddress client_address_;
- ParsedQuicVersionVector supported_versions_;
- ParsedQuicVersion client_version_;
- QuicVersionLabel client_version_label_;
- std::string client_version_string_;
- QuicCryptoServerConfig config_;
- QuicCryptoServerConfigPeer peer_;
- QuicCompressedCertsCache compressed_certs_cache_;
- QuicCryptoServerConfig::ConfigOptions config_options_;
- QuicReferenceCountedPointer<QuicCryptoNegotiatedParameters> params_;
- QuicReferenceCountedPointer<QuicSignedServerConfig> signed_config_;
- CryptoHandshakeMessage out_;
- uint8_t orbit_[kOrbitSize];
- size_t chlo_packet_size_;
-
- // These strings contain hex escaped values from the server suitable for using
- // when constructing client hello messages.
- std::string nonce_hex_, pub_hex_, srct_hex_, scid_hex_;
- std::unique_ptr<CryptoHandshakeMessage> server_config_;
-};
-
-INSTANTIATE_TEST_SUITE_P(CryptoServerTests,
- CryptoServerTest,
- ::testing::ValuesIn(GetTestParams()),
- ::testing::PrintToStringParamName());
-
-TEST_P(CryptoServerTest, BadSNI) {
- // clang-format off
- std::vector<std::string> badSNIs = {
- "",
- "#00",
- "#ff00",
- "127.0.0.1",
- "ffee::1",
- };
- // clang-format on
-
- for (const std::string& bad_sni : badSNIs) {
- CryptoHandshakeMessage msg = crypto_test_utils::CreateCHLO(
- {{"PDMD", "X509"}, {"SNI", bad_sni}, {"VER\0", client_version_string_}},
- kClientHelloMinimumSize);
- ShouldFailMentioning("SNI", msg);
- const HandshakeFailureReason kRejectReasons[] = {
- SERVER_CONFIG_INCHOATE_HELLO_FAILURE};
- CheckRejectReasons(kRejectReasons, ABSL_ARRAYSIZE(kRejectReasons));
- }
-
- // Check that SNIs without dots are allowed
- CryptoHandshakeMessage msg = crypto_test_utils::CreateCHLO(
- {{"PDMD", "X509"}, {"SNI", "foo"}, {"VER\0", client_version_string_}},
- kClientHelloMinimumSize);
- ShouldSucceed(msg);
-}
-
-TEST_P(CryptoServerTest, DefaultCert) {
- // Check that the server replies with a default certificate when no SNI is
- // specified. The CHLO is constructed to generate a REJ with certs, so must
- // not contain a valid STK, and must include PDMD.
- CryptoHandshakeMessage msg =
- crypto_test_utils::CreateCHLO({{"AEAD", "AESG"},
- {"KEXS", "C255"},
- {"PUBS", pub_hex_},
- {"NONC", nonce_hex_},
- {"PDMD", "X509"},
- {"VER\0", client_version_string_}},
- kClientHelloMinimumSize);
-
- ShouldSucceed(msg);
- absl::string_view cert, proof, cert_sct;
- EXPECT_TRUE(out_.GetStringPiece(kCertificateTag, &cert));
- EXPECT_TRUE(out_.GetStringPiece(kPROF, &proof));
- EXPECT_TRUE(out_.GetStringPiece(kCertificateSCTTag, &cert_sct));
- EXPECT_NE(0u, cert.size());
- EXPECT_NE(0u, proof.size());
- const HandshakeFailureReason kRejectReasons[] = {
- SERVER_CONFIG_INCHOATE_HELLO_FAILURE};
- CheckRejectReasons(kRejectReasons, ABSL_ARRAYSIZE(kRejectReasons));
- EXPECT_LT(0u, cert_sct.size());
-}
-
-TEST_P(CryptoServerTest, RejectTooLarge) {
- // Check that the server replies with no certificate when a CHLO is
- // constructed with a PDMD but no SKT when the REJ would be too large.
- CryptoHandshakeMessage msg =
- crypto_test_utils::CreateCHLO({{"PDMD", "X509"},
- {"AEAD", "AESG"},
- {"KEXS", "C255"},
- {"PUBS", pub_hex_},
- {"NONC", nonce_hex_},
- {"PDMD", "X509"},
- {"VER\0", client_version_string_}},
- kClientHelloMinimumSize);
-
- // The REJ will be larger than the CHLO so no PROF or CRT will be sent.
- config_.set_chlo_multiplier(1);
-
- ShouldSucceed(msg);
- absl::string_view cert, proof, cert_sct;
- EXPECT_FALSE(out_.GetStringPiece(kCertificateTag, &cert));
- EXPECT_FALSE(out_.GetStringPiece(kPROF, &proof));
- EXPECT_FALSE(out_.GetStringPiece(kCertificateSCTTag, &cert_sct));
- const HandshakeFailureReason kRejectReasons[] = {
- SERVER_CONFIG_INCHOATE_HELLO_FAILURE};
- CheckRejectReasons(kRejectReasons, ABSL_ARRAYSIZE(kRejectReasons));
-}
-
-TEST_P(CryptoServerTest, RejectNotTooLarge) {
- // When the CHLO packet is large enough, ensure that a full REJ is sent.
- chlo_packet_size_ *= 5;
-
- CryptoHandshakeMessage msg =
- crypto_test_utils::CreateCHLO({{"PDMD", "X509"},
- {"AEAD", "AESG"},
- {"KEXS", "C255"},
- {"PUBS", pub_hex_},
- {"NONC", nonce_hex_},
- {"PDMD", "X509"},
- {"VER\0", client_version_string_}},
- kClientHelloMinimumSize);
-
- // The REJ will be larger than the CHLO so no PROF or CRT will be sent.
- config_.set_chlo_multiplier(1);
-
- ShouldSucceed(msg);
- absl::string_view cert, proof, cert_sct;
- EXPECT_TRUE(out_.GetStringPiece(kCertificateTag, &cert));
- EXPECT_TRUE(out_.GetStringPiece(kPROF, &proof));
- EXPECT_TRUE(out_.GetStringPiece(kCertificateSCTTag, &cert_sct));
- const HandshakeFailureReason kRejectReasons[] = {
- SERVER_CONFIG_INCHOATE_HELLO_FAILURE};
- CheckRejectReasons(kRejectReasons, ABSL_ARRAYSIZE(kRejectReasons));
-}
-
-TEST_P(CryptoServerTest, RejectTooLargeButValidSTK) {
- // Check that the server replies with no certificate when a CHLO is
- // constructed with a PDMD but no SKT when the REJ would be too large.
- CryptoHandshakeMessage msg =
- crypto_test_utils::CreateCHLO({{"PDMD", "X509"},
- {"AEAD", "AESG"},
- {"KEXS", "C255"},
- {"PUBS", pub_hex_},
- {"NONC", nonce_hex_},
- {"#004b5453", srct_hex_},
- {"PDMD", "X509"},
- {"VER\0", client_version_string_}},
- kClientHelloMinimumSize);
-
- // The REJ will be larger than the CHLO so no PROF or CRT will be sent.
- config_.set_chlo_multiplier(1);
-
- ShouldSucceed(msg);
- absl::string_view cert, proof, cert_sct;
- EXPECT_TRUE(out_.GetStringPiece(kCertificateTag, &cert));
- EXPECT_TRUE(out_.GetStringPiece(kPROF, &proof));
- EXPECT_TRUE(out_.GetStringPiece(kCertificateSCTTag, &cert_sct));
- EXPECT_NE(0u, cert.size());
- EXPECT_NE(0u, proof.size());
- const HandshakeFailureReason kRejectReasons[] = {
- SERVER_CONFIG_INCHOATE_HELLO_FAILURE};
- CheckRejectReasons(kRejectReasons, ABSL_ARRAYSIZE(kRejectReasons));
-}
-
-TEST_P(CryptoServerTest, BadSourceAddressToken) {
- // Invalid source-address tokens should be ignored.
- // clang-format off
- static const char* const kBadSourceAddressTokens[] = {
- "",
- "foo",
- "#0000",
- "#0000000000000000000000000000000000000000",
- };
- // clang-format on
-
- for (size_t i = 0; i < ABSL_ARRAYSIZE(kBadSourceAddressTokens); i++) {
- CryptoHandshakeMessage msg =
- crypto_test_utils::CreateCHLO({{"PDMD", "X509"},
- {"STK", kBadSourceAddressTokens[i]},
- {"VER\0", client_version_string_}},
- kClientHelloMinimumSize);
- ShouldSucceed(msg);
- const HandshakeFailureReason kRejectReasons[] = {
- SERVER_CONFIG_INCHOATE_HELLO_FAILURE};
- CheckRejectReasons(kRejectReasons, ABSL_ARRAYSIZE(kRejectReasons));
- }
-}
-
-TEST_P(CryptoServerTest, BadClientNonce) {
- // clang-format off
- static const char* const kBadNonces[] = {
- "",
- "#0000",
- "#0000000000000000000000000000000000000000",
- };
- // clang-format on
-
- for (size_t i = 0; i < ABSL_ARRAYSIZE(kBadNonces); i++) {
- // Invalid nonces should be ignored, in an inchoate CHLO.
-
- CryptoHandshakeMessage msg =
- crypto_test_utils::CreateCHLO({{"PDMD", "X509"},
- {"NONC", kBadNonces[i]},
- {"VER\0", client_version_string_}},
- kClientHelloMinimumSize);
-
- ShouldSucceed(msg);
- const HandshakeFailureReason kRejectReasons[] = {
- SERVER_CONFIG_INCHOATE_HELLO_FAILURE};
- CheckRejectReasons(kRejectReasons, ABSL_ARRAYSIZE(kRejectReasons));
-
- // Invalid nonces should result in CLIENT_NONCE_INVALID_FAILURE.
- CryptoHandshakeMessage msg1 =
- crypto_test_utils::CreateCHLO({{"PDMD", "X509"},
- {"AEAD", "AESG"},
- {"KEXS", "C255"},
- {"SCID", scid_hex_},
- {"#004b5453", srct_hex_},
- {"PUBS", pub_hex_},
- {"NONC", kBadNonces[i]},
- {"NONP", kBadNonces[i]},
- {"XLCT", XlctHexString()},
- {"VER\0", client_version_string_}},
- kClientHelloMinimumSize);
-
- ShouldSucceed(msg1);
-
- CheckRejectTag();
- const HandshakeFailureReason kRejectReasons1[] = {
- CLIENT_NONCE_INVALID_FAILURE};
- CheckRejectReasons(kRejectReasons1, ABSL_ARRAYSIZE(kRejectReasons1));
- }
-}
-
-TEST_P(CryptoServerTest, NoClientNonce) {
- // No client nonces should result in INCHOATE_HELLO_FAILURE.
-
- CryptoHandshakeMessage msg = crypto_test_utils::CreateCHLO(
- {{"PDMD", "X509"}, {"VER\0", client_version_string_}},
- kClientHelloMinimumSize);
-
- ShouldSucceed(msg);
- const HandshakeFailureReason kRejectReasons[] = {
- SERVER_CONFIG_INCHOATE_HELLO_FAILURE};
- CheckRejectReasons(kRejectReasons, ABSL_ARRAYSIZE(kRejectReasons));
-
- CryptoHandshakeMessage msg1 =
- crypto_test_utils::CreateCHLO({{"PDMD", "X509"},
- {"AEAD", "AESG"},
- {"KEXS", "C255"},
- {"SCID", scid_hex_},
- {"#004b5453", srct_hex_},
- {"PUBS", pub_hex_},
- {"XLCT", XlctHexString()},
- {"VER\0", client_version_string_}},
- kClientHelloMinimumSize);
-
- ShouldSucceed(msg1);
- CheckRejectTag();
- const HandshakeFailureReason kRejectReasons1[] = {
- SERVER_CONFIG_INCHOATE_HELLO_FAILURE};
- CheckRejectReasons(kRejectReasons1, ABSL_ARRAYSIZE(kRejectReasons1));
-}
-
-TEST_P(CryptoServerTest, DowngradeAttack) {
- if (supported_versions_.size() == 1) {
- // No downgrade attack is possible if the server only supports one version.
- return;
- }
- // Set the client's preferred version to a supported version that
- // is not the "current" version (supported_versions_.front()).
- std::string bad_version =
- ParsedQuicVersionToString(supported_versions_.back());
-
- CryptoHandshakeMessage msg = crypto_test_utils::CreateCHLO(
- {{"PDMD", "X509"}, {"VER\0", bad_version}}, kClientHelloMinimumSize);
-
- ShouldFailMentioning("Downgrade", msg);
- const HandshakeFailureReason kRejectReasons[] = {
- SERVER_CONFIG_INCHOATE_HELLO_FAILURE};
- CheckRejectReasons(kRejectReasons, ABSL_ARRAYSIZE(kRejectReasons));
-}
-
-TEST_P(CryptoServerTest, CorruptServerConfig) {
- // This tests corrupted server config.
- CryptoHandshakeMessage msg = crypto_test_utils::CreateCHLO(
- {{"PDMD", "X509"},
- {"AEAD", "AESG"},
- {"KEXS", "C255"},
- {"SCID", (std::string(1, 'X') + scid_hex_)},
- {"#004b5453", srct_hex_},
- {"PUBS", pub_hex_},
- {"NONC", nonce_hex_},
- {"VER\0", client_version_string_}},
- kClientHelloMinimumSize);
-
- ShouldSucceed(msg);
- CheckRejectTag();
- const HandshakeFailureReason kRejectReasons[] = {
- SERVER_CONFIG_UNKNOWN_CONFIG_FAILURE};
- CheckRejectReasons(kRejectReasons, ABSL_ARRAYSIZE(kRejectReasons));
-}
-
-TEST_P(CryptoServerTest, CorruptSourceAddressToken) {
- // This tests corrupted source address token.
- CryptoHandshakeMessage msg = crypto_test_utils::CreateCHLO(
- {{"PDMD", "X509"},
- {"AEAD", "AESG"},
- {"KEXS", "C255"},
- {"SCID", scid_hex_},
- {"#004b5453", (std::string(1, 'X') + srct_hex_)},
- {"PUBS", pub_hex_},
- {"NONC", nonce_hex_},
- {"XLCT", XlctHexString()},
- {"VER\0", client_version_string_}},
- kClientHelloMinimumSize);
-
- ShouldSucceed(msg);
- CheckRejectTag();
- const HandshakeFailureReason kRejectReasons[] = {
- SOURCE_ADDRESS_TOKEN_DECRYPTION_FAILURE};
- CheckRejectReasons(kRejectReasons, ABSL_ARRAYSIZE(kRejectReasons));
-}
-
-TEST_P(CryptoServerTest, CorruptSourceAddressTokenIsStillAccepted) {
- // This tests corrupted source address token.
- CryptoHandshakeMessage msg = crypto_test_utils::CreateCHLO(
- {{"PDMD", "X509"},
- {"AEAD", "AESG"},
- {"KEXS", "C255"},
- {"SCID", scid_hex_},
- {"#004b5453", (std::string(1, 'X') + srct_hex_)},
- {"PUBS", pub_hex_},
- {"NONC", nonce_hex_},
- {"XLCT", XlctHexString()},
- {"VER\0", client_version_string_}},
- kClientHelloMinimumSize);
-
- config_.set_validate_source_address_token(false);
-
- ShouldSucceed(msg);
- EXPECT_EQ(kSHLO, out_.tag());
-}
-
-TEST_P(CryptoServerTest, CorruptClientNonceAndSourceAddressToken) {
- // This test corrupts client nonce and source address token.
- CryptoHandshakeMessage msg = crypto_test_utils::CreateCHLO(
- {{"PDMD", "X509"},
- {"AEAD", "AESG"},
- {"KEXS", "C255"},
- {"SCID", scid_hex_},
- {"#004b5453", (std::string(1, 'X') + srct_hex_)},
- {"PUBS", pub_hex_},
- {"NONC", (std::string(1, 'X') + nonce_hex_)},
- {"XLCT", XlctHexString()},
- {"VER\0", client_version_string_}},
- kClientHelloMinimumSize);
-
- ShouldSucceed(msg);
- CheckRejectTag();
- const HandshakeFailureReason kRejectReasons[] = {
- SOURCE_ADDRESS_TOKEN_DECRYPTION_FAILURE, CLIENT_NONCE_INVALID_FAILURE};
- CheckRejectReasons(kRejectReasons, ABSL_ARRAYSIZE(kRejectReasons));
-}
-
-TEST_P(CryptoServerTest, CorruptMultipleTags) {
- // This test corrupts client nonce, server nonce and source address token.
- CryptoHandshakeMessage msg = crypto_test_utils::CreateCHLO(
- {{"PDMD", "X509"},
- {"AEAD", "AESG"},
- {"KEXS", "C255"},
- {"SCID", scid_hex_},
- {"#004b5453", (std::string(1, 'X') + srct_hex_)},
- {"PUBS", pub_hex_},
- {"NONC", (std::string(1, 'X') + nonce_hex_)},
- {"NONP", (std::string(1, 'X') + nonce_hex_)},
- {"SNO\0", (std::string(1, 'X') + nonce_hex_)},
- {"XLCT", XlctHexString()},
- {"VER\0", client_version_string_}},
- kClientHelloMinimumSize);
-
- ShouldSucceed(msg);
- CheckRejectTag();
-
- const HandshakeFailureReason kRejectReasons[] = {
- SOURCE_ADDRESS_TOKEN_DECRYPTION_FAILURE, CLIENT_NONCE_INVALID_FAILURE};
- CheckRejectReasons(kRejectReasons, ABSL_ARRAYSIZE(kRejectReasons));
-}
-
-TEST_P(CryptoServerTest, NoServerNonce) {
- // When no server nonce is present and no strike register is configured,
- // the CHLO should be rejected.
- CryptoHandshakeMessage msg =
- crypto_test_utils::CreateCHLO({{"PDMD", "X509"},
- {"AEAD", "AESG"},
- {"KEXS", "C255"},
- {"SCID", scid_hex_},
- {"#004b5453", srct_hex_},
- {"PUBS", pub_hex_},
- {"NONC", nonce_hex_},
- {"NONP", nonce_hex_},
- {"XLCT", XlctHexString()},
- {"VER\0", client_version_string_}},
- kClientHelloMinimumSize);
-
- ShouldSucceed(msg);
-
- // Even without a server nonce, this ClientHello should be accepted in
- // version 33.
- ASSERT_EQ(kSHLO, out_.tag());
- CheckServerHello(out_);
-}
-
-TEST_P(CryptoServerTest, ProofForSuppliedServerConfig) {
- client_address_ = QuicSocketAddress(QuicIpAddress::Loopback6(), 1234);
-
- CryptoHandshakeMessage msg =
- crypto_test_utils::CreateCHLO({{"AEAD", "AESG"},
- {"KEXS", "C255"},
- {"PDMD", "X509"},
- {"SCID", kOldConfigId},
- {"#004b5453", srct_hex_},
- {"PUBS", pub_hex_},
- {"NONC", nonce_hex_},
- {"NONP", "123456789012345678901234567890"},
- {"VER\0", client_version_string_},
- {"XLCT", XlctHexString()}},
- kClientHelloMinimumSize);
-
- ShouldSucceed(msg);
- // The message should be rejected because the source-address token is no
- // longer valid.
- CheckRejectTag();
- const HandshakeFailureReason kRejectReasons[] = {
- SOURCE_ADDRESS_TOKEN_DIFFERENT_IP_ADDRESS_FAILURE};
- CheckRejectReasons(kRejectReasons, ABSL_ARRAYSIZE(kRejectReasons));
-
- absl::string_view cert, proof, scfg_str;
- EXPECT_TRUE(out_.GetStringPiece(kCertificateTag, &cert));
- EXPECT_TRUE(out_.GetStringPiece(kPROF, &proof));
- EXPECT_TRUE(out_.GetStringPiece(kSCFG, &scfg_str));
- std::unique_ptr<CryptoHandshakeMessage> scfg(
- CryptoFramer::ParseMessage(scfg_str));
- absl::string_view scid;
- EXPECT_TRUE(scfg->GetStringPiece(kSCID, &scid));
- EXPECT_NE(scid, kOldConfigId);
-
- // Get certs from compressed certs.
- const CommonCertSets* common_cert_sets(CommonCertSets::GetInstanceQUIC());
- std::vector<std::string> cached_certs;
-
- std::vector<std::string> certs;
- ASSERT_TRUE(CertCompressor::DecompressChain(cert, cached_certs,
- common_cert_sets, &certs));
-
- // Check that the proof in the REJ message is valid.
- std::unique_ptr<ProofVerifier> proof_verifier(
- crypto_test_utils::ProofVerifierForTesting());
- std::unique_ptr<ProofVerifyContext> verify_context(
- crypto_test_utils::ProofVerifyContextForTesting());
- std::unique_ptr<ProofVerifyDetails> details;
- std::string error_details;
- std::unique_ptr<ProofVerifierCallback> callback(
- new DummyProofVerifierCallback());
- const std::string chlo_hash =
- CryptoUtils::HashHandshakeMessage(msg, Perspective::IS_SERVER);
- EXPECT_EQ(QUIC_SUCCESS,
- proof_verifier->VerifyProof(
- "test.example.com", 443, (std::string(scfg_str)),
- client_version_.transport_version, chlo_hash, certs, "",
- (std::string(proof)), verify_context.get(), &error_details,
- &details, std::move(callback)));
-}
-
-TEST_P(CryptoServerTest, RejectInvalidXlct) {
- CryptoHandshakeMessage msg =
- crypto_test_utils::CreateCHLO({{"PDMD", "X509"},
- {"AEAD", "AESG"},
- {"KEXS", "C255"},
- {"SCID", scid_hex_},
- {"#004b5453", srct_hex_},
- {"PUBS", pub_hex_},
- {"NONC", nonce_hex_},
- {"VER\0", client_version_string_},
- {"XLCT", "#0102030405060708"}},
- kClientHelloMinimumSize);
-
- // If replay protection isn't disabled, then
- // QuicCryptoServerConfig::EvaluateClientHello will leave info.unique as false
- // and cause ProcessClientHello to exit early (and generate a REJ message).
- config_.set_replay_protection(false);
-
- ShouldSucceed(msg);
-
- const HandshakeFailureReason kRejectReasons[] = {
- INVALID_EXPECTED_LEAF_CERTIFICATE};
-
- CheckRejectReasons(kRejectReasons, ABSL_ARRAYSIZE(kRejectReasons));
-}
-
-TEST_P(CryptoServerTest, ValidXlct) {
- CryptoHandshakeMessage msg =
- crypto_test_utils::CreateCHLO({{"PDMD", "X509"},
- {"AEAD", "AESG"},
- {"KEXS", "C255"},
- {"SCID", scid_hex_},
- {"#004b5453", srct_hex_},
- {"PUBS", pub_hex_},
- {"NONC", nonce_hex_},
- {"VER\0", client_version_string_},
- {"XLCT", XlctHexString()}},
- kClientHelloMinimumSize);
-
- // If replay protection isn't disabled, then
- // QuicCryptoServerConfig::EvaluateClientHello will leave info.unique as false
- // and cause ProcessClientHello to exit early (and generate a REJ message).
- config_.set_replay_protection(false);
-
- ShouldSucceed(msg);
- EXPECT_EQ(kSHLO, out_.tag());
-}
-
-TEST_P(CryptoServerTest, NonceInSHLO) {
- CryptoHandshakeMessage msg =
- crypto_test_utils::CreateCHLO({{"PDMD", "X509"},
- {"AEAD", "AESG"},
- {"KEXS", "C255"},
- {"SCID", scid_hex_},
- {"#004b5453", srct_hex_},
- {"PUBS", pub_hex_},
- {"NONC", nonce_hex_},
- {"VER\0", client_version_string_},
- {"XLCT", XlctHexString()}},
- kClientHelloMinimumSize);
-
- // If replay protection isn't disabled, then
- // QuicCryptoServerConfig::EvaluateClientHello will leave info.unique as false
- // and cause ProcessClientHello to exit early (and generate a REJ message).
- config_.set_replay_protection(false);
-
- ShouldSucceed(msg);
- EXPECT_EQ(kSHLO, out_.tag());
-
- absl::string_view nonce;
- EXPECT_TRUE(out_.GetStringPiece(kServerNonceTag, &nonce));
-}
-
-TEST_P(CryptoServerTest, ProofSourceFailure) {
- // Install a ProofSource which will unconditionally fail
- peer_.ResetProofSource(std::unique_ptr<ProofSource>(new FailingProofSource));
-
- CryptoHandshakeMessage msg =
- crypto_test_utils::CreateCHLO({{"AEAD", "AESG"},
- {"KEXS", "C255"},
- {"SCID", scid_hex_},
- {"PUBS", pub_hex_},
- {"NONC", nonce_hex_},
- {"PDMD", "X509"},
- {"VER\0", client_version_string_}},
- kClientHelloMinimumSize);
-
- // Just ensure that we don't crash as occurred in b/33916924.
- ShouldFailMentioning("", msg);
-}
-
-// Regression test for crbug.com/723604
-// For 2RTT, if the first CHLO from the client contains hashes of cached
-// certs (stored in CCRT tag) but the second CHLO does not, then the second REJ
-// from the server should not contain hashes of cached certs.
-TEST_P(CryptoServerTest, TwoRttServerDropCachedCerts) {
- // Send inchoate CHLO to get cert chain from server. This CHLO is only for
- // the purpose of getting the server's certs; it is not part of the 2RTT
- // handshake.
- CryptoHandshakeMessage msg = crypto_test_utils::CreateCHLO(
- {{"PDMD", "X509"}, {"VER\0", client_version_string_}},
- kClientHelloMinimumSize);
- ShouldSucceed(msg);
-
- // Decompress cert chain from server to individual certs.
- absl::string_view certs_compressed;
- ASSERT_TRUE(out_.GetStringPiece(kCertificateTag, &certs_compressed));
- ASSERT_NE(0u, certs_compressed.size());
- std::vector<std::string> certs;
- ASSERT_TRUE(CertCompressor::DecompressChain(
- certs_compressed, /*cached_certs=*/{}, /*common_sets=*/nullptr, &certs));
-
- // Start 2-RTT. Client sends CHLO with bad source-address token and hashes of
- // the certs, which tells the server that the client has cached those certs.
- config_.set_chlo_multiplier(1);
- const char kBadSourceAddressToken[] = "";
- msg.SetStringPiece(kSourceAddressTokenTag, kBadSourceAddressToken);
- std::vector<uint64_t> hashes(certs.size());
- for (size_t i = 0; i < certs.size(); ++i) {
- hashes[i] = QuicUtils::QuicUtils::FNV1a_64_Hash(certs[i]);
- }
- msg.SetVector(kCCRT, hashes);
- ShouldSucceed(msg);
-
- // Server responds with inchoate REJ containing valid source-address token.
- absl::string_view srct;
- ASSERT_TRUE(out_.GetStringPiece(kSourceAddressTokenTag, &srct));
-
- // Client now drops cached certs; sends CHLO with updated source-address
- // token but no hashes of certs.
- msg.SetStringPiece(kSourceAddressTokenTag, srct);
- msg.Erase(kCCRT);
- ShouldSucceed(msg);
-
- // Server response's cert chain should not contain hashes of
- // previously-cached certs.
- ASSERT_TRUE(out_.GetStringPiece(kCertificateTag, &certs_compressed));
- ASSERT_NE(0u, certs_compressed.size());
- ASSERT_TRUE(CertCompressor::DecompressChain(
- certs_compressed, /*cached_certs=*/{}, /*common_sets=*/nullptr, &certs));
-}
-
-class CryptoServerConfigGenerationTest : public QuicTest {};
-
-TEST_F(CryptoServerConfigGenerationTest, Determinism) {
- // Test that using a deterministic PRNG causes the server-config to be
- // deterministic.
-
- MockRandom rand_a, rand_b;
- const QuicCryptoServerConfig::ConfigOptions options;
- MockClock clock;
-
- QuicCryptoServerConfig a(QuicCryptoServerConfig::TESTING, &rand_a,
- crypto_test_utils::ProofSourceForTesting(),
- KeyExchangeSource::Default());
- QuicCryptoServerConfig b(QuicCryptoServerConfig::TESTING, &rand_b,
- crypto_test_utils::ProofSourceForTesting(),
- KeyExchangeSource::Default());
- std::unique_ptr<CryptoHandshakeMessage> scfg_a(
- a.AddDefaultConfig(&rand_a, &clock, options));
- std::unique_ptr<CryptoHandshakeMessage> scfg_b(
- b.AddDefaultConfig(&rand_b, &clock, options));
-
- ASSERT_EQ(scfg_a->DebugString(), scfg_b->DebugString());
-}
-
-TEST_F(CryptoServerConfigGenerationTest, SCIDVaries) {
- // This test ensures that the server config ID varies for different server
- // configs.
-
- MockRandom rand_a, rand_b;
- const QuicCryptoServerConfig::ConfigOptions options;
- MockClock clock;
-
- QuicCryptoServerConfig a(QuicCryptoServerConfig::TESTING, &rand_a,
- crypto_test_utils::ProofSourceForTesting(),
- KeyExchangeSource::Default());
- rand_b.ChangeValue();
- QuicCryptoServerConfig b(QuicCryptoServerConfig::TESTING, &rand_b,
- crypto_test_utils::ProofSourceForTesting(),
- KeyExchangeSource::Default());
- std::unique_ptr<CryptoHandshakeMessage> scfg_a(
- a.AddDefaultConfig(&rand_a, &clock, options));
- std::unique_ptr<CryptoHandshakeMessage> scfg_b(
- b.AddDefaultConfig(&rand_b, &clock, options));
-
- absl::string_view scid_a, scid_b;
- EXPECT_TRUE(scfg_a->GetStringPiece(kSCID, &scid_a));
- EXPECT_TRUE(scfg_b->GetStringPiece(kSCID, &scid_b));
-
- EXPECT_NE(scid_a, scid_b);
-}
-
-TEST_F(CryptoServerConfigGenerationTest, SCIDIsHashOfServerConfig) {
- MockRandom rand_a;
- const QuicCryptoServerConfig::ConfigOptions options;
- MockClock clock;
-
- QuicCryptoServerConfig a(QuicCryptoServerConfig::TESTING, &rand_a,
- crypto_test_utils::ProofSourceForTesting(),
- KeyExchangeSource::Default());
- std::unique_ptr<CryptoHandshakeMessage> scfg(
- a.AddDefaultConfig(&rand_a, &clock, options));
-
- absl::string_view scid;
- EXPECT_TRUE(scfg->GetStringPiece(kSCID, &scid));
- // Need to take a copy of |scid| has we're about to call |Erase|.
- const std::string scid_str(scid);
-
- scfg->Erase(kSCID);
- scfg->MarkDirty();
- const QuicData& serialized(scfg->GetSerialized());
-
- uint8_t digest[SHA256_DIGEST_LENGTH];
- SHA256(reinterpret_cast<const uint8_t*>(serialized.data()),
- serialized.length(), digest);
-
- // scid is a SHA-256 hash, truncated to 16 bytes.
- ASSERT_EQ(scid.size(), 16u);
- EXPECT_EQ(0, memcmp(digest, scid_str.c_str(), scid.size()));
-}
-
-// Those tests were declared incorrectly and thus never ran in first place.
-// TODO(b/147891553): figure out if we should fix or delete those.
-#if 0
-
-class CryptoServerTestNoConfig : public CryptoServerTest {
- public:
- void SetUp() override {
- // Deliberately don't add a config so that we can test this situation.
- }
-};
-
-INSTANTIATE_TEST_SUITE_P(CryptoServerTestsNoConfig,
- CryptoServerTestNoConfig,
- ::testing::ValuesIn(GetTestParams()),
- ::testing::PrintToStringParamName());
-
-TEST_P(CryptoServerTestNoConfig, DontCrash) {
- CryptoHandshakeMessage msg = crypto_test_utils::CreateCHLO(
- {{"PDMD", "X509"}, {"VER\0", client_version_string_}},
- kClientHelloMinimumSize);
-
- ShouldFailMentioning("No config", msg);
-
- const HandshakeFailureReason kRejectReasons[] = {
- SERVER_CONFIG_INCHOATE_HELLO_FAILURE};
- CheckRejectReasons(kRejectReasons, ABSL_ARRAYSIZE(kRejectReasons));
-}
-
-class CryptoServerTestOldVersion : public CryptoServerTest {
- public:
- void SetUp() override {
- client_version_ = supported_versions_.back();
- client_version_string_ = ParsedQuicVersionToString(client_version_);
- CryptoServerTest::SetUp();
- }
-};
-
-INSTANTIATE_TEST_SUITE_P(CryptoServerTestsOldVersion,
- CryptoServerTestOldVersion,
- ::testing::ValuesIn(GetTestParams()),
- ::testing::PrintToStringParamName());
-
-TEST_P(CryptoServerTestOldVersion, ServerIgnoresXlct) {
- CryptoHandshakeMessage msg =
- crypto_test_utils::CreateCHLO({{"PDMD", "X509"},
- {"AEAD", "AESG"},
- {"KEXS", "C255"},
- {"SCID", scid_hex_},
- {"#004b5453", srct_hex_},
- {"PUBS", pub_hex_},
- {"NONC", nonce_hex_},
- {"VER\0", client_version_string_},
- {"XLCT", "#0100000000000000"}},
- kClientHelloMinimumSize);
-
- // If replay protection isn't disabled, then
- // QuicCryptoServerConfig::EvaluateClientHello will leave info.unique as false
- // and cause ProcessClientHello to exit early (and generate a REJ message).
- config_.set_replay_protection(false);
-
- ShouldSucceed(msg);
- EXPECT_EQ(kSHLO, out_.tag());
-}
-
-TEST_P(CryptoServerTestOldVersion, XlctNotRequired) {
- CryptoHandshakeMessage msg =
- crypto_test_utils::CreateCHLO({{"PDMD", "X509"},
- {"AEAD", "AESG"},
- {"KEXS", "C255"},
- {"SCID", scid_hex_},
- {"#004b5453", srct_hex_},
- {"PUBS", pub_hex_},
- {"NONC", nonce_hex_},
- {"VER\0", client_version_string_}},
- kClientHelloMinimumSize);
-
- // If replay protection isn't disabled, then
- // QuicCryptoServerConfig::EvaluateClientHello will leave info.unique as false
- // and cause ProcessClientHello to exit early (and generate a REJ message).
- config_.set_replay_protection(false);
-
- ShouldSucceed(msg);
- EXPECT_EQ(kSHLO, out_.tag());
-}
-
-#endif // 0
-
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_utils.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_utils.cc
deleted file mode 100644
index 05bbdfe6321..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_utils.cc
+++ /dev/null
@@ -1,788 +0,0 @@
-// Copyright (c) 2013 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 "quic/core/crypto/crypto_utils.h"
-
-#include <memory>
-#include <string>
-#include <utility>
-
-#include "absl/base/macros.h"
-#include "absl/strings/str_cat.h"
-#include "absl/strings/string_view.h"
-#include "third_party/boringssl/src/include/openssl/bytestring.h"
-#include "third_party/boringssl/src/include/openssl/hkdf.h"
-#include "third_party/boringssl/src/include/openssl/mem.h"
-#include "third_party/boringssl/src/include/openssl/sha.h"
-#include "quic/core/crypto/aes_128_gcm_12_decrypter.h"
-#include "quic/core/crypto/aes_128_gcm_12_encrypter.h"
-#include "quic/core/crypto/aes_128_gcm_decrypter.h"
-#include "quic/core/crypto/aes_128_gcm_encrypter.h"
-#include "quic/core/crypto/crypto_handshake.h"
-#include "quic/core/crypto/crypto_protocol.h"
-#include "quic/core/crypto/null_decrypter.h"
-#include "quic/core/crypto/null_encrypter.h"
-#include "quic/core/crypto/quic_decrypter.h"
-#include "quic/core/crypto/quic_encrypter.h"
-#include "quic/core/crypto/quic_hkdf.h"
-#include "quic/core/crypto/quic_random.h"
-#include "quic/core/quic_connection_id.h"
-#include "quic/core/quic_constants.h"
-#include "quic/core/quic_data_writer.h"
-#include "quic/core/quic_time.h"
-#include "quic/core/quic_utils.h"
-#include "quic/core/quic_versions.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_logging.h"
-#include "common/quiche_endian.h"
-
-namespace quic {
-
-namespace {
-
-// Implements the HKDF-Expand-Label function as defined in section 7.1 of RFC
-// 8446, except that it uses "quic " as the prefix instead of "tls13 ", as
-// specified by draft-ietf-quic-tls-14. The HKDF-Expand-Label function takes 4
-// explicit arguments (Secret, Label, Context, and Length), as well as
-// implicit PRF which is the hash function negotiated by TLS. Its use in QUIC
-// (as needed by the QUIC stack, instead of as used internally by the TLS
-// stack) is only for deriving initial secrets for obfuscation and for
-// calculating packet protection keys and IVs from the corresponding packet
-// protection secret. Neither of these uses need a Context (a zero-length
-// context is provided), so this argument is omitted here.
-//
-// The implicit PRF is explicitly passed into HkdfExpandLabel as |prf|; the
-// 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,
- const std::string& label, size_t out_len) {
- bssl::ScopedCBB quic_hkdf_label;
- CBB inner_label;
- const char label_prefix[] = "tls13 ";
- // 19 = size(u16) + size(u8) + len("tls13 ") + len ("client in") + size(u8)
- static const size_t max_quic_hkdf_label_length = 19;
- if (!CBB_init(quic_hkdf_label.get(), max_quic_hkdf_label_length) ||
- !CBB_add_u16(quic_hkdf_label.get(), out_len) ||
- !CBB_add_u8_length_prefixed(quic_hkdf_label.get(), &inner_label) ||
- !CBB_add_bytes(&inner_label,
- reinterpret_cast<const uint8_t*>(label_prefix),
- ABSL_ARRAYSIZE(label_prefix) - 1) ||
- !CBB_add_bytes(&inner_label,
- reinterpret_cast<const uint8_t*>(label.data()),
- label.size()) ||
- !CBB_add_u8(quic_hkdf_label.get(), 0) ||
- !CBB_flush(quic_hkdf_label.get())) {
- QUIC_LOG(ERROR) << "Building HKDF label failed";
- return std::vector<uint8_t>();
- }
- std::vector<uint8_t> out;
- out.resize(out_len);
- if (!HKDF_expand(out.data(), out_len, prf, secret.data(), secret.size(),
- CBB_data(quic_hkdf_label.get()),
- CBB_len(quic_hkdf_label.get()))) {
- QUIC_LOG(ERROR) << "Running HKDF-Expand-Label failed";
- return std::vector<uint8_t>();
- }
- return out;
-}
-
-} // namespace
-
-const std::string getLabelForVersion(const ParsedQuicVersion& version,
- const absl::string_view& predicate) {
- static_assert(SupportedVersions().size() == 6u,
- "Supported versions out of sync with HKDF labels");
- if (version == ParsedQuicVersion::V2Draft01()) {
- return absl::StrCat("quicv2 ", predicate);
- } else {
- return absl::StrCat("quic ", predicate);
- }
-}
-
-void CryptoUtils::InitializeCrypterSecrets(
- const EVP_MD* prf, const std::vector<uint8_t>& pp_secret,
- const ParsedQuicVersion& version, QuicCrypter* crypter) {
- SetKeyAndIV(prf, pp_secret, version, crypter);
- std::vector<uint8_t> header_protection_key = GenerateHeaderProtectionKey(
- prf, pp_secret, version, crypter->GetKeySize());
- crypter->SetHeaderProtectionKey(
- absl::string_view(reinterpret_cast<char*>(header_protection_key.data()),
- header_protection_key.size()));
-}
-
-void CryptoUtils::SetKeyAndIV(const EVP_MD* prf,
- const std::vector<uint8_t>& pp_secret,
- const ParsedQuicVersion& version,
- QuicCrypter* crypter) {
- std::vector<uint8_t> key =
- HkdfExpandLabel(prf, pp_secret, getLabelForVersion(version, "key"),
- crypter->GetKeySize());
- std::vector<uint8_t> iv = HkdfExpandLabel(
- prf, pp_secret, getLabelForVersion(version, "iv"), crypter->GetIVSize());
- crypter->SetKey(
- absl::string_view(reinterpret_cast<char*>(key.data()), key.size()));
- crypter->SetIV(
- absl::string_view(reinterpret_cast<char*>(iv.data()), iv.size()));
-}
-
-std::vector<uint8_t> CryptoUtils::GenerateHeaderProtectionKey(
- const EVP_MD* prf, const std::vector<uint8_t>& pp_secret,
- const ParsedQuicVersion& version, size_t out_len) {
- return HkdfExpandLabel(prf, pp_secret, getLabelForVersion(version, "hp"),
- out_len);
-}
-
-std::vector<uint8_t> CryptoUtils::GenerateNextKeyPhaseSecret(
- const EVP_MD* prf, const ParsedQuicVersion& version,
- const std::vector<uint8_t>& current_secret) {
- return HkdfExpandLabel(prf, current_secret, getLabelForVersion(version, "ku"),
- current_secret.size());
-}
-
-namespace {
-
-// Salt from https://tools.ietf.org/html/draft-ietf-quic-tls-29#section-5.2
-const uint8_t kDraft29InitialSalt[] = {0xaf, 0xbf, 0xec, 0x28, 0x99, 0x93, 0xd2,
- 0x4c, 0x9e, 0x97, 0x86, 0xf1, 0x9c, 0x61,
- 0x11, 0xe0, 0x43, 0x90, 0xa8, 0x99};
-const uint8_t kRFCv1InitialSalt[] = {0x38, 0x76, 0x2c, 0xf7, 0xf5, 0x59, 0x34,
- 0xb3, 0x4d, 0x17, 0x9a, 0xe6, 0xa4, 0xc8,
- 0x0c, 0xad, 0xcc, 0xbb, 0x7f, 0x0a};
-const uint8_t kV2Draft01InitialSalt[] = {
- 0xa7, 0x07, 0xc2, 0x03, 0xa5, 0x9b, 0x47, 0x18, 0x4a, 0x1d,
- 0x62, 0xca, 0x57, 0x04, 0x06, 0xea, 0x7a, 0xe3, 0xe5, 0xd3};
-
-// Salts used by deployed versions of QUIC. When introducing a new version,
-// generate a new salt by running `openssl rand -hex 20`.
-
-// Salt to use for initial obfuscators in version Q050.
-const uint8_t kQ050Salt[] = {0x50, 0x45, 0x74, 0xef, 0xd0, 0x66, 0xfe,
- 0x2f, 0x9d, 0x94, 0x5c, 0xfc, 0xdb, 0xd3,
- 0xa7, 0xf0, 0xd3, 0xb5, 0x6b, 0x45};
-// Salt to use for initial obfuscators in
-// ParsedQuicVersion::ReservedForNegotiation().
-const uint8_t kReservedForNegotiationSalt[] = {
- 0xf9, 0x64, 0xbf, 0x45, 0x3a, 0x1f, 0x1b, 0x80, 0xa5, 0xf8,
- 0x82, 0x03, 0x77, 0xd4, 0xaf, 0xca, 0x58, 0x0e, 0xe7, 0x43};
-
-const uint8_t* InitialSaltForVersion(const ParsedQuicVersion& version,
- size_t* out_len) {
- static_assert(SupportedVersions().size() == 6u,
- "Supported versions out of sync with initial encryption salts");
- if (version == ParsedQuicVersion::V2Draft01()) {
- *out_len = ABSL_ARRAYSIZE(kV2Draft01InitialSalt);
- return kV2Draft01InitialSalt;
- } else if (version == ParsedQuicVersion::RFCv1()) {
- *out_len = ABSL_ARRAYSIZE(kRFCv1InitialSalt);
- return kRFCv1InitialSalt;
- } else if (version == ParsedQuicVersion::Draft29()) {
- *out_len = ABSL_ARRAYSIZE(kDraft29InitialSalt);
- return kDraft29InitialSalt;
- } else if (version == ParsedQuicVersion::Q050()) {
- *out_len = ABSL_ARRAYSIZE(kQ050Salt);
- return kQ050Salt;
- } else if (version == ParsedQuicVersion::ReservedForNegotiation()) {
- *out_len = ABSL_ARRAYSIZE(kReservedForNegotiationSalt);
- return kReservedForNegotiationSalt;
- }
- QUIC_BUG(quic_bug_10699_1)
- << "No initial obfuscation salt for version " << version;
- *out_len = ABSL_ARRAYSIZE(kReservedForNegotiationSalt);
- return kReservedForNegotiationSalt;
-}
-
-const char kPreSharedKeyLabel[] = "QUIC PSK";
-
-// Retry Integrity Protection Keys and Nonces.
-// https://tools.ietf.org/html/draft-ietf-quic-tls-29#section-5.8
-// When introducing a new Google version, generate a new key by running
-// `openssl rand -hex 16`.
-const uint8_t kDraft29RetryIntegrityKey[] = {0xcc, 0xce, 0x18, 0x7e, 0xd0, 0x9a,
- 0x09, 0xd0, 0x57, 0x28, 0x15, 0x5a,
- 0x6c, 0xb9, 0x6b, 0xe1};
-const uint8_t kDraft29RetryIntegrityNonce[] = {
- 0xe5, 0x49, 0x30, 0xf9, 0x7f, 0x21, 0x36, 0xf0, 0x53, 0x0a, 0x8c, 0x1c};
-const uint8_t kRFCv1RetryIntegrityKey[] = {0xbe, 0x0c, 0x69, 0x0b, 0x9f, 0x66,
- 0x57, 0x5a, 0x1d, 0x76, 0x6b, 0x54,
- 0xe3, 0x68, 0xc8, 0x4e};
-const uint8_t kRFCv1RetryIntegrityNonce[] = {
- 0x46, 0x15, 0x99, 0xd3, 0x5d, 0x63, 0x2b, 0xf2, 0x23, 0x98, 0x25, 0xbb};
-const uint8_t kV2Draft01RetryIntegrityKey[] = {
- 0xba, 0x85, 0x8d, 0xc7, 0xb4, 0x3d, 0xe5, 0xdb,
- 0xf8, 0x76, 0x17, 0xff, 0x4a, 0xb2, 0x53, 0xdb};
-const uint8_t kV2Draft01RetryIntegrityNonce[] = {
- 0x14, 0x1b, 0x99, 0xc2, 0x39, 0xb0, 0x3e, 0x78, 0x5d, 0x6a, 0x2e, 0x9f};
-// Retry integrity key used by ParsedQuicVersion::ReservedForNegotiation().
-const uint8_t kReservedForNegotiationRetryIntegrityKey[] = {
- 0xf2, 0xcd, 0x8f, 0xe0, 0x36, 0xd0, 0x25, 0x35,
- 0x03, 0xe6, 0x7c, 0x7b, 0xd2, 0x44, 0xca, 0xd9};
-// When introducing a new Google version, generate a new nonce by running
-// `openssl rand -hex 12`.
-// Retry integrity nonce used by ParsedQuicVersion::ReservedForNegotiation().
-const uint8_t kReservedForNegotiationRetryIntegrityNonce[] = {
- 0x35, 0x9f, 0x16, 0xd1, 0xed, 0x80, 0x90, 0x8e, 0xec, 0x85, 0xc4, 0xd6};
-
-bool RetryIntegrityKeysForVersion(const ParsedQuicVersion& version,
- absl::string_view* key,
- absl::string_view* nonce) {
- static_assert(SupportedVersions().size() == 6u,
- "Supported versions out of sync with retry integrity keys");
- if (!version.UsesTls()) {
- QUIC_BUG(quic_bug_10699_2)
- << "Attempted to get retry integrity keys for invalid version "
- << version;
- return false;
- } else if (version == ParsedQuicVersion::V2Draft01()) {
- *key = absl::string_view(
- reinterpret_cast<const char*>(kV2Draft01RetryIntegrityKey),
- ABSL_ARRAYSIZE(kV2Draft01RetryIntegrityKey));
- *nonce = absl::string_view(
- reinterpret_cast<const char*>(kV2Draft01RetryIntegrityNonce),
- ABSL_ARRAYSIZE(kV2Draft01RetryIntegrityNonce));
- return true;
- } else if (version == ParsedQuicVersion::RFCv1()) {
- *key = absl::string_view(
- reinterpret_cast<const char*>(kRFCv1RetryIntegrityKey),
- ABSL_ARRAYSIZE(kRFCv1RetryIntegrityKey));
- *nonce = absl::string_view(
- reinterpret_cast<const char*>(kRFCv1RetryIntegrityNonce),
- ABSL_ARRAYSIZE(kRFCv1RetryIntegrityNonce));
- return true;
- } else if (version == ParsedQuicVersion::Draft29()) {
- *key = absl::string_view(
- reinterpret_cast<const char*>(kDraft29RetryIntegrityKey),
- ABSL_ARRAYSIZE(kDraft29RetryIntegrityKey));
- *nonce = absl::string_view(
- reinterpret_cast<const char*>(kDraft29RetryIntegrityNonce),
- ABSL_ARRAYSIZE(kDraft29RetryIntegrityNonce));
- return true;
- } else if (version == ParsedQuicVersion::ReservedForNegotiation()) {
- *key = absl::string_view(
- reinterpret_cast<const char*>(kReservedForNegotiationRetryIntegrityKey),
- ABSL_ARRAYSIZE(kReservedForNegotiationRetryIntegrityKey));
- *nonce = absl::string_view(
- reinterpret_cast<const char*>(
- kReservedForNegotiationRetryIntegrityNonce),
- ABSL_ARRAYSIZE(kReservedForNegotiationRetryIntegrityNonce));
- return true;
- }
- QUIC_BUG(quic_bug_10699_3)
- << "Attempted to get retry integrity keys for version " << version;
- return false;
-}
-
-} // namespace
-
-// static
-void CryptoUtils::CreateInitialObfuscators(Perspective perspective,
- ParsedQuicVersion version,
- QuicConnectionId connection_id,
- CrypterPair* crypters) {
- QUIC_DLOG(INFO) << "Creating "
- << (perspective == Perspective::IS_CLIENT ? "client"
- : "server")
- << " crypters for version " << version << " with CID "
- << connection_id;
- if (!version.UsesInitialObfuscators()) {
- crypters->encrypter = std::make_unique<NullEncrypter>(perspective);
- crypters->decrypter = std::make_unique<NullDecrypter>(perspective);
- return;
- }
- QUIC_BUG_IF(quic_bug_12871_1, !QuicUtils::IsConnectionIdValidForVersion(
- connection_id, version.transport_version))
- << "CreateTlsInitialCrypters: attempted to use connection ID "
- << connection_id << " which is invalid with version " << version;
- const EVP_MD* hash = EVP_sha256();
-
- size_t salt_len;
- const uint8_t* salt = InitialSaltForVersion(version, &salt_len);
- std::vector<uint8_t> handshake_secret;
- handshake_secret.resize(EVP_MAX_MD_SIZE);
- size_t handshake_secret_len;
- const bool hkdf_extract_success =
- HKDF_extract(handshake_secret.data(), &handshake_secret_len, hash,
- reinterpret_cast<const uint8_t*>(connection_id.data()),
- connection_id.length(), salt, salt_len);
- QUIC_BUG_IF(quic_bug_12871_2, !hkdf_extract_success)
- << "HKDF_extract failed when creating initial crypters";
- handshake_secret.resize(handshake_secret_len);
-
- const std::string client_label = "client in";
- const std::string server_label = "server in";
- std::string encryption_label, decryption_label;
- if (perspective == Perspective::IS_CLIENT) {
- encryption_label = client_label;
- decryption_label = server_label;
- } else {
- encryption_label = server_label;
- decryption_label = client_label;
- }
- std::vector<uint8_t> encryption_secret = HkdfExpandLabel(
- hash, handshake_secret, encryption_label, EVP_MD_size(hash));
- crypters->encrypter = std::make_unique<Aes128GcmEncrypter>();
- InitializeCrypterSecrets(hash, encryption_secret, version,
- crypters->encrypter.get());
-
- std::vector<uint8_t> decryption_secret = HkdfExpandLabel(
- hash, handshake_secret, decryption_label, EVP_MD_size(hash));
- crypters->decrypter = std::make_unique<Aes128GcmDecrypter>();
- InitializeCrypterSecrets(hash, decryption_secret, version,
- crypters->decrypter.get());
-}
-
-// static
-bool CryptoUtils::ValidateRetryIntegrityTag(
- ParsedQuicVersion version, QuicConnectionId original_connection_id,
- absl::string_view retry_without_tag, absl::string_view integrity_tag) {
- unsigned char computed_integrity_tag[kRetryIntegrityTagLength];
- if (integrity_tag.length() != ABSL_ARRAYSIZE(computed_integrity_tag)) {
- QUIC_BUG(quic_bug_10699_4)
- << "Invalid retry integrity tag length " << integrity_tag.length();
- return false;
- }
- char retry_pseudo_packet[kMaxIncomingPacketSize + 256];
- QuicDataWriter writer(ABSL_ARRAYSIZE(retry_pseudo_packet),
- retry_pseudo_packet);
- if (!writer.WriteLengthPrefixedConnectionId(original_connection_id)) {
- QUIC_BUG(quic_bug_10699_5)
- << "Failed to write original connection ID in retry pseudo packet";
- return false;
- }
- if (!writer.WriteStringPiece(retry_without_tag)) {
- QUIC_BUG(quic_bug_10699_6)
- << "Failed to write retry without tag in retry pseudo packet";
- return false;
- }
- absl::string_view key;
- absl::string_view nonce;
- if (!RetryIntegrityKeysForVersion(version, &key, &nonce)) {
- // RetryIntegrityKeysForVersion already logs failures.
- return false;
- }
- Aes128GcmEncrypter crypter;
- crypter.SetKey(key);
- absl::string_view associated_data(writer.data(), writer.length());
- absl::string_view plaintext; // Plaintext is empty.
- if (!crypter.Encrypt(nonce, associated_data, plaintext,
- computed_integrity_tag)) {
- QUIC_BUG(quic_bug_10699_7) << "Failed to compute retry integrity tag";
- return false;
- }
- if (CRYPTO_memcmp(computed_integrity_tag, integrity_tag.data(),
- ABSL_ARRAYSIZE(computed_integrity_tag)) != 0) {
- QUIC_DLOG(ERROR) << "Failed to validate retry integrity tag";
- return false;
- }
- return true;
-}
-
-// static
-void CryptoUtils::GenerateNonce(QuicWallTime now, QuicRandom* random_generator,
- absl::string_view orbit, std::string* nonce) {
- // a 4-byte timestamp + 28 random bytes.
- nonce->reserve(kNonceSize);
- nonce->resize(kNonceSize);
-
- uint32_t gmt_unix_time = static_cast<uint32_t>(now.ToUNIXSeconds());
- // The time in the nonce must be encoded in big-endian because the
- // strike-register depends on the nonces being ordered by time.
- (*nonce)[0] = static_cast<char>(gmt_unix_time >> 24);
- (*nonce)[1] = static_cast<char>(gmt_unix_time >> 16);
- (*nonce)[2] = static_cast<char>(gmt_unix_time >> 8);
- (*nonce)[3] = static_cast<char>(gmt_unix_time);
- size_t bytes_written = 4;
-
- if (orbit.size() == 8) {
- memcpy(&(*nonce)[bytes_written], orbit.data(), orbit.size());
- bytes_written += orbit.size();
- }
-
- random_generator->RandBytes(&(*nonce)[bytes_written],
- kNonceSize - bytes_written);
-}
-
-// static
-bool CryptoUtils::DeriveKeys(
- const ParsedQuicVersion& version, absl::string_view premaster_secret,
- QuicTag aead, absl::string_view client_nonce,
- absl::string_view server_nonce, absl::string_view pre_shared_key,
- const std::string& hkdf_input, Perspective perspective,
- Diversification diversification, CrypterPair* crypters,
- std::string* subkey_secret) {
- // If the connection is using PSK, concatenate it with the pre-master secret.
- std::unique_ptr<char[]> psk_premaster_secret;
- if (!pre_shared_key.empty()) {
- const absl::string_view label(kPreSharedKeyLabel);
- const size_t psk_premaster_secret_size = label.size() + 1 +
- pre_shared_key.size() + 8 +
- premaster_secret.size() + 8;
-
- psk_premaster_secret = std::make_unique<char[]>(psk_premaster_secret_size);
- QuicDataWriter writer(psk_premaster_secret_size, psk_premaster_secret.get(),
- quiche::HOST_BYTE_ORDER);
-
- if (!writer.WriteStringPiece(label) || !writer.WriteUInt8(0) ||
- !writer.WriteStringPiece(pre_shared_key) ||
- !writer.WriteUInt64(pre_shared_key.size()) ||
- !writer.WriteStringPiece(premaster_secret) ||
- !writer.WriteUInt64(premaster_secret.size()) ||
- writer.remaining() != 0) {
- return false;
- }
-
- premaster_secret = absl::string_view(psk_premaster_secret.get(),
- psk_premaster_secret_size);
- }
-
- crypters->encrypter = QuicEncrypter::Create(version, aead);
- crypters->decrypter = QuicDecrypter::Create(version, aead);
-
- size_t key_bytes = crypters->encrypter->GetKeySize();
- size_t nonce_prefix_bytes = crypters->encrypter->GetNoncePrefixSize();
- if (version.UsesInitialObfuscators()) {
- nonce_prefix_bytes = crypters->encrypter->GetIVSize();
- }
- size_t subkey_secret_bytes =
- subkey_secret == nullptr ? 0 : premaster_secret.length();
-
- absl::string_view nonce = client_nonce;
- std::string nonce_storage;
- if (!server_nonce.empty()) {
- nonce_storage = std::string(client_nonce) + std::string(server_nonce);
- nonce = nonce_storage;
- }
-
- QuicHKDF hkdf(premaster_secret, nonce, hkdf_input, key_bytes,
- nonce_prefix_bytes, subkey_secret_bytes);
-
- // Key derivation depends on the key diversification method being employed.
- // both the client and the server support never doing key diversification.
- // The server also supports immediate diversification, and the client
- // supports pending diversification.
- switch (diversification.mode()) {
- case Diversification::NEVER: {
- if (perspective == Perspective::IS_SERVER) {
- if (!crypters->encrypter->SetKey(hkdf.server_write_key()) ||
- !crypters->encrypter->SetNoncePrefixOrIV(version,
- hkdf.server_write_iv()) ||
- !crypters->encrypter->SetHeaderProtectionKey(
- hkdf.server_hp_key()) ||
- !crypters->decrypter->SetKey(hkdf.client_write_key()) ||
- !crypters->decrypter->SetNoncePrefixOrIV(version,
- hkdf.client_write_iv()) ||
- !crypters->decrypter->SetHeaderProtectionKey(
- hkdf.client_hp_key())) {
- return false;
- }
- } else {
- if (!crypters->encrypter->SetKey(hkdf.client_write_key()) ||
- !crypters->encrypter->SetNoncePrefixOrIV(version,
- hkdf.client_write_iv()) ||
- !crypters->encrypter->SetHeaderProtectionKey(
- hkdf.client_hp_key()) ||
- !crypters->decrypter->SetKey(hkdf.server_write_key()) ||
- !crypters->decrypter->SetNoncePrefixOrIV(version,
- hkdf.server_write_iv()) ||
- !crypters->decrypter->SetHeaderProtectionKey(
- hkdf.server_hp_key())) {
- return false;
- }
- }
- break;
- }
- case Diversification::PENDING: {
- if (perspective == Perspective::IS_SERVER) {
- QUIC_BUG(quic_bug_10699_8)
- << "Pending diversification is only for clients.";
- return false;
- }
-
- if (!crypters->encrypter->SetKey(hkdf.client_write_key()) ||
- !crypters->encrypter->SetNoncePrefixOrIV(version,
- hkdf.client_write_iv()) ||
- !crypters->encrypter->SetHeaderProtectionKey(hkdf.client_hp_key()) ||
- !crypters->decrypter->SetPreliminaryKey(hkdf.server_write_key()) ||
- !crypters->decrypter->SetNoncePrefixOrIV(version,
- hkdf.server_write_iv()) ||
- !crypters->decrypter->SetHeaderProtectionKey(hkdf.server_hp_key())) {
- return false;
- }
- break;
- }
- case Diversification::NOW: {
- if (perspective == Perspective::IS_CLIENT) {
- QUIC_BUG(quic_bug_10699_9)
- << "Immediate diversification is only for servers.";
- return false;
- }
-
- std::string key, nonce_prefix;
- QuicDecrypter::DiversifyPreliminaryKey(
- hkdf.server_write_key(), hkdf.server_write_iv(),
- *diversification.nonce(), key_bytes, nonce_prefix_bytes, &key,
- &nonce_prefix);
- if (!crypters->decrypter->SetKey(hkdf.client_write_key()) ||
- !crypters->decrypter->SetNoncePrefixOrIV(version,
- hkdf.client_write_iv()) ||
- !crypters->decrypter->SetHeaderProtectionKey(hkdf.client_hp_key()) ||
- !crypters->encrypter->SetKey(key) ||
- !crypters->encrypter->SetNoncePrefixOrIV(version, nonce_prefix) ||
- !crypters->encrypter->SetHeaderProtectionKey(hkdf.server_hp_key())) {
- return false;
- }
- break;
- }
- default:
- QUICHE_DCHECK(false);
- }
-
- if (subkey_secret != nullptr) {
- *subkey_secret = std::string(hkdf.subkey_secret());
- }
-
- return true;
-}
-
-// static
-uint64_t CryptoUtils::ComputeLeafCertHash(absl::string_view cert) {
- return QuicUtils::FNV1a_64_Hash(cert);
-}
-
-QuicErrorCode CryptoUtils::ValidateServerHello(
- const CryptoHandshakeMessage& server_hello,
- const ParsedQuicVersionVector& negotiated_versions,
- std::string* error_details) {
- QUICHE_DCHECK(error_details != nullptr);
-
- if (server_hello.tag() != kSHLO) {
- *error_details = "Bad tag";
- return QUIC_INVALID_CRYPTO_MESSAGE_TYPE;
- }
-
- QuicVersionLabelVector supported_version_labels;
- if (server_hello.GetVersionLabelList(kVER, &supported_version_labels) !=
- QUIC_NO_ERROR) {
- *error_details = "server hello missing version list";
- return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER;
- }
-
- return ValidateServerHelloVersions(supported_version_labels,
- negotiated_versions, error_details);
-}
-
-QuicErrorCode CryptoUtils::ValidateServerHelloVersions(
- const QuicVersionLabelVector& server_versions,
- const ParsedQuicVersionVector& negotiated_versions,
- std::string* error_details) {
- if (!negotiated_versions.empty()) {
- bool mismatch = server_versions.size() != negotiated_versions.size();
- for (size_t i = 0; i < server_versions.size() && !mismatch; ++i) {
- mismatch =
- server_versions[i] != CreateQuicVersionLabel(negotiated_versions[i]);
- }
- // The server sent a list of supported versions, and the connection
- // reports that there was a version negotiation during the handshake.
- // Ensure that these two lists are identical.
- if (mismatch) {
- *error_details = absl::StrCat(
- "Downgrade attack detected: ServerVersions(", server_versions.size(),
- ")[", QuicVersionLabelVectorToString(server_versions, ",", 30),
- "] NegotiatedVersions(", negotiated_versions.size(), ")[",
- ParsedQuicVersionVectorToString(negotiated_versions, ",", 30), "]");
- return QUIC_VERSION_NEGOTIATION_MISMATCH;
- }
- }
- return QUIC_NO_ERROR;
-}
-
-QuicErrorCode CryptoUtils::ValidateClientHello(
- const CryptoHandshakeMessage& client_hello, ParsedQuicVersion version,
- const ParsedQuicVersionVector& supported_versions,
- std::string* error_details) {
- if (client_hello.tag() != kCHLO) {
- *error_details = "Bad tag";
- return QUIC_INVALID_CRYPTO_MESSAGE_TYPE;
- }
-
- // If the client's preferred version is not the version we are currently
- // speaking, then the client went through a version negotiation. In this
- // case, we need to make sure that we actually do not support this version
- // and that it wasn't a downgrade attack.
- QuicVersionLabel client_version_label;
- if (client_hello.GetVersionLabel(kVER, &client_version_label) !=
- QUIC_NO_ERROR) {
- *error_details = "client hello missing version list";
- return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER;
- }
- return ValidateClientHelloVersion(client_version_label, version,
- supported_versions, error_details);
-}
-
-QuicErrorCode CryptoUtils::ValidateClientHelloVersion(
- QuicVersionLabel client_version, ParsedQuicVersion connection_version,
- const ParsedQuicVersionVector& supported_versions,
- std::string* error_details) {
- if (client_version != CreateQuicVersionLabel(connection_version)) {
- // Check to see if |client_version| is actually on the supported versions
- // list. If not, the server doesn't support that version and it's not a
- // downgrade attack.
- for (size_t i = 0; i < supported_versions.size(); ++i) {
- if (client_version == CreateQuicVersionLabel(supported_versions[i])) {
- *error_details = absl::StrCat(
- "Downgrade attack detected: ClientVersion[",
- QuicVersionLabelToString(client_version), "] ConnectionVersion[",
- ParsedQuicVersionToString(connection_version),
- "] SupportedVersions(", supported_versions.size(), ")[",
- ParsedQuicVersionVectorToString(supported_versions, ",", 30), "]");
- return QUIC_VERSION_NEGOTIATION_MISMATCH;
- }
- }
- }
- return QUIC_NO_ERROR;
-}
-
-// static
-bool CryptoUtils::ValidateChosenVersion(
- const QuicVersionLabel& version_information_chosen_version,
- const ParsedQuicVersion& session_version, std::string* error_details) {
- if (version_information_chosen_version !=
- CreateQuicVersionLabel(session_version)) {
- *error_details = absl::StrCat(
- "Detected version mismatch: version_information contained ",
- QuicVersionLabelToString(version_information_chosen_version),
- " instead of ", ParsedQuicVersionToString(session_version));
- return false;
- }
- return true;
-}
-
-// static
-bool CryptoUtils::ValidateServerVersions(
- const QuicVersionLabelVector& version_information_other_versions,
- const ParsedQuicVersion& session_version,
- const ParsedQuicVersionVector& client_original_supported_versions,
- std::string* error_details) {
- if (client_original_supported_versions.empty()) {
- // We did not receive a version negotiation packet.
- return true;
- }
- // Parse the server's other versions.
- ParsedQuicVersionVector parsed_other_versions =
- ParseQuicVersionLabelVector(version_information_other_versions);
- // Find the first version that we originally supported that is listed in the
- // server's other versions.
- ParsedQuicVersion expected_version = ParsedQuicVersion::Unsupported();
- for (const ParsedQuicVersion& client_version :
- client_original_supported_versions) {
- if (std::find(parsed_other_versions.begin(), parsed_other_versions.end(),
- client_version) != parsed_other_versions.end()) {
- expected_version = client_version;
- break;
- }
- }
- if (expected_version != session_version) {
- *error_details = absl::StrCat(
- "Downgrade attack detected: used ",
- ParsedQuicVersionToString(session_version), " but ServerVersions(",
- version_information_other_versions.size(), ")[",
- QuicVersionLabelVectorToString(version_information_other_versions, ",",
- 30),
- "] ClientOriginalVersions(", client_original_supported_versions.size(),
- ")[",
- ParsedQuicVersionVectorToString(client_original_supported_versions, ",",
- 30),
- "]");
- return false;
- }
- return true;
-}
-
-#define RETURN_STRING_LITERAL(x) \
- case x: \
- return #x
-
-// Returns the name of the HandshakeFailureReason as a char*
-// static
-const char* CryptoUtils::HandshakeFailureReasonToString(
- HandshakeFailureReason reason) {
- switch (reason) {
- RETURN_STRING_LITERAL(HANDSHAKE_OK);
- RETURN_STRING_LITERAL(CLIENT_NONCE_UNKNOWN_FAILURE);
- RETURN_STRING_LITERAL(CLIENT_NONCE_INVALID_FAILURE);
- RETURN_STRING_LITERAL(CLIENT_NONCE_NOT_UNIQUE_FAILURE);
- RETURN_STRING_LITERAL(CLIENT_NONCE_INVALID_ORBIT_FAILURE);
- RETURN_STRING_LITERAL(CLIENT_NONCE_INVALID_TIME_FAILURE);
- RETURN_STRING_LITERAL(CLIENT_NONCE_STRIKE_REGISTER_TIMEOUT);
- RETURN_STRING_LITERAL(CLIENT_NONCE_STRIKE_REGISTER_FAILURE);
-
- RETURN_STRING_LITERAL(SERVER_NONCE_DECRYPTION_FAILURE);
- RETURN_STRING_LITERAL(SERVER_NONCE_INVALID_FAILURE);
- RETURN_STRING_LITERAL(SERVER_NONCE_NOT_UNIQUE_FAILURE);
- RETURN_STRING_LITERAL(SERVER_NONCE_INVALID_TIME_FAILURE);
- RETURN_STRING_LITERAL(SERVER_NONCE_REQUIRED_FAILURE);
-
- RETURN_STRING_LITERAL(SERVER_CONFIG_INCHOATE_HELLO_FAILURE);
- RETURN_STRING_LITERAL(SERVER_CONFIG_UNKNOWN_CONFIG_FAILURE);
-
- RETURN_STRING_LITERAL(SOURCE_ADDRESS_TOKEN_INVALID_FAILURE);
- RETURN_STRING_LITERAL(SOURCE_ADDRESS_TOKEN_DECRYPTION_FAILURE);
- RETURN_STRING_LITERAL(SOURCE_ADDRESS_TOKEN_PARSE_FAILURE);
- RETURN_STRING_LITERAL(SOURCE_ADDRESS_TOKEN_DIFFERENT_IP_ADDRESS_FAILURE);
- RETURN_STRING_LITERAL(SOURCE_ADDRESS_TOKEN_CLOCK_SKEW_FAILURE);
- RETURN_STRING_LITERAL(SOURCE_ADDRESS_TOKEN_EXPIRED_FAILURE);
-
- RETURN_STRING_LITERAL(INVALID_EXPECTED_LEAF_CERTIFICATE);
- RETURN_STRING_LITERAL(MAX_FAILURE_REASON);
- }
- // Return a default value so that we return this when |reason| doesn't match
- // any HandshakeFailureReason.. This can happen when the message by the peer
- // (attacker) has invalid reason.
- return "INVALID_HANDSHAKE_FAILURE_REASON";
-}
-
-#undef RETURN_STRING_LITERAL // undef for jumbo builds
-
-// static
-std::string CryptoUtils::EarlyDataReasonToString(
- ssl_early_data_reason_t reason) {
- const char* reason_string = SSL_early_data_reason_string(reason);
- if (reason_string != nullptr) {
- return std::string("ssl_early_data_") + reason_string;
- }
- QUIC_BUG_IF(quic_bug_12871_3,
- reason < 0 || reason > ssl_early_data_reason_max_value)
- << "Unknown ssl_early_data_reason_t " << reason;
- return "unknown ssl_early_data_reason_t";
-}
-
-// static
-std::string CryptoUtils::HashHandshakeMessage(
- const CryptoHandshakeMessage& message, Perspective /*perspective*/) {
- std::string output;
- const QuicData& serialized = message.GetSerialized();
- uint8_t digest[SHA256_DIGEST_LENGTH];
- SHA256(reinterpret_cast<const uint8_t*>(serialized.data()),
- serialized.length(), digest);
- output.assign(reinterpret_cast<const char*>(digest), sizeof(digest));
- return output;
-}
-
-// static
-bool CryptoUtils::GetSSLCapabilities(const SSL* ssl,
- bssl::UniquePtr<uint8_t>* capabilities,
- size_t* capabilities_len) {
- uint8_t* buffer;
- CBB cbb;
-
- if (!CBB_init(&cbb, 128) || !SSL_serialize_capabilities(ssl, &cbb) ||
- !CBB_finish(&cbb, &buffer, capabilities_len)) {
- return false;
- }
-
- *capabilities = bssl::UniquePtr<uint8_t>(buffer);
- return true;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_utils.h b/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_utils.h
deleted file mode 100644
index fce62018823..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_utils.h
+++ /dev/null
@@ -1,255 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Some helpers for quic crypto
-
-#ifndef QUICHE_QUIC_CORE_CRYPTO_CRYPTO_UTILS_H_
-#define QUICHE_QUIC_CORE_CRYPTO_CRYPTO_UTILS_H_
-
-#include <cstddef>
-#include <cstdint>
-#include <string>
-
-#include "absl/strings/string_view.h"
-#include "third_party/boringssl/src/include/openssl/evp.h"
-#include "third_party/boringssl/src/include/openssl/ssl.h"
-#include "quic/core/crypto/crypto_handshake.h"
-#include "quic/core/crypto/crypto_handshake_message.h"
-#include "quic/core/crypto/crypto_protocol.h"
-#include "quic/core/crypto/quic_crypter.h"
-#include "quic/core/quic_connection_id.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_time.h"
-#include "quic/core/quic_versions.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-class QuicRandom;
-
-class QUIC_EXPORT_PRIVATE CryptoUtils {
- public:
- CryptoUtils() = delete;
-
- // Diversification is a utility class that's used to act like a union type.
- // Values can be created by calling the functions like |NoDiversification|,
- // below.
- class QUIC_EXPORT_PRIVATE Diversification {
- public:
- enum Mode {
- NEVER, // Key diversification will never be used. Forward secure
- // crypters will always use this mode.
-
- PENDING, // Key diversification will happen when a nonce is later
- // received. This should only be used by clients initial
- // decrypters which are waiting on the divesification nonce
- // from the server.
-
- NOW, // Key diversification will happen immediate based on the nonce.
- // This should only be used by servers initial encrypters.
- };
-
- Diversification(const Diversification& diversification) = default;
-
- static Diversification Never() { return Diversification(NEVER, nullptr); }
- static Diversification Pending() {
- return Diversification(PENDING, nullptr);
- }
- static Diversification Now(DiversificationNonce* nonce) {
- return Diversification(NOW, nonce);
- }
-
- Mode mode() const { return mode_; }
- DiversificationNonce* nonce() const {
- QUICHE_DCHECK_EQ(mode_, NOW);
- return nonce_;
- }
-
- private:
- Diversification(Mode mode, DiversificationNonce* nonce)
- : mode_(mode), nonce_(nonce) {}
-
- Mode mode_;
- DiversificationNonce* nonce_;
- };
-
- // InitializeCrypterSecrets derives the key and IV and header protection key
- // from the given packet protection secret |pp_secret| and sets those fields
- // on the given QuicCrypter |*crypter|.
- // This follows the derivation described in section 7.3 of RFC 8446, except
- // with the label prefix in HKDF-Expand-Label changed from "tls13 " to "quic "
- // as described in draft-ietf-quic-tls-14, section 5.1, or "quicv2 " as
- // described in draft-ietf-quic-v2-01.
- static void InitializeCrypterSecrets(const EVP_MD* prf,
- const std::vector<uint8_t>& pp_secret,
- const ParsedQuicVersion& version,
- QuicCrypter* crypter);
-
- // Derives the key and IV from the packet protection secret and sets those
- // fields on the given QuicCrypter |*crypter|, but does not set the header
- // protection key. GenerateHeaderProtectionKey/SetHeaderProtectionKey must be
- // called before using |crypter|.
- static void SetKeyAndIV(const EVP_MD* prf,
- const std::vector<uint8_t>& pp_secret,
- 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 ParsedQuicVersion& version, size_t out_len);
-
- // Given a secret for key phase n, return the secret for phase n+1.
- static std::vector<uint8_t> GenerateNextKeyPhaseSecret(
- const EVP_MD* prf, const ParsedQuicVersion& version,
- const std::vector<uint8_t>& current_secret);
-
- // IETF QUIC encrypts ENCRYPTION_INITIAL messages with a version-specific key
- // (to prevent network observers that are not aware of that QUIC version from
- // making decisions based on the TLS handshake). This packet protection secret
- // is derived from the connection ID in the client's Initial packet.
- //
- // This function takes that |connection_id| and creates the encrypter and
- // decrypter (put in |*crypters|) to use for this packet protection, as well
- // as setting the key and IV on those crypters. For older versions of QUIC
- // that do not use the new IETF style ENCRYPTION_INITIAL obfuscators, this
- // function puts a NullEncrypter and NullDecrypter in |*crypters|.
- static void CreateInitialObfuscators(Perspective perspective,
- ParsedQuicVersion version,
- QuicConnectionId connection_id,
- CrypterPair* crypters);
-
- // IETF QUIC Retry packets carry a retry integrity tag to detect packet
- // corruption and make it harder for an attacker to spoof. This function
- // checks whether a given retry packet is valid.
- static bool ValidateRetryIntegrityTag(ParsedQuicVersion version,
- QuicConnectionId original_connection_id,
- absl::string_view retry_without_tag,
- absl::string_view integrity_tag);
-
- // Generates the connection nonce. The nonce is formed as:
- // <4 bytes> current time
- // <8 bytes> |orbit| (or random if |orbit| is empty)
- // <20 bytes> random
- static void GenerateNonce(QuicWallTime now, QuicRandom* random_generator,
- absl::string_view orbit, std::string* nonce);
-
- // DeriveKeys populates |crypters->encrypter|, |crypters->decrypter|, and
- // |subkey_secret| (optional -- may be null) given the contents of
- // |premaster_secret|, |client_nonce|, |server_nonce| and |hkdf_input|. |aead|
- // determines which cipher will be used. |perspective| controls whether the
- // server's keys are assigned to |encrypter| or |decrypter|. |server_nonce| is
- // optional and, if non-empty, is mixed into the key derivation.
- // |subkey_secret| will have the same length as |premaster_secret|.
- //
- // If |pre_shared_key| is non-empty, it is incorporated into the key
- // derivation parameters. If it is empty, the key derivation is unaltered.
- //
- // If the mode of |diversification| is NEVER, the the crypters will be
- // configured to never perform key diversification. If the mode is
- // NOW (which is only for servers, then the encrypter will be keyed via a
- // two-step process that uses the nonce from |diversification|.
- // If the mode is PENDING (which is only for servres), then the
- // decrypter will only be keyed to a preliminary state: a call to
- // |SetDiversificationNonce| with a diversification nonce will be needed to
- // complete keying.
- static bool DeriveKeys(const ParsedQuicVersion& version,
- absl::string_view premaster_secret, QuicTag aead,
- absl::string_view client_nonce,
- absl::string_view server_nonce,
- absl::string_view pre_shared_key,
- const std::string& hkdf_input, Perspective perspective,
- Diversification diversification, CrypterPair* crypters,
- std::string* subkey_secret);
-
- // Computes the FNV-1a hash of the provided DER-encoded cert for use in the
- // XLCT tag.
- static uint64_t ComputeLeafCertHash(absl::string_view cert);
-
- // Validates that |server_hello| is actually an SHLO message and that it is
- // not part of a downgrade attack.
- //
- // Returns QUIC_NO_ERROR if this is the case or returns the appropriate error
- // code and sets |error_details|.
- static QuicErrorCode ValidateServerHello(
- const CryptoHandshakeMessage& server_hello,
- const ParsedQuicVersionVector& negotiated_versions,
- std::string* error_details);
-
- // Validates that the |server_versions| received do not indicate that the
- // ServerHello is part of a downgrade attack. |negotiated_versions| must
- // contain the list of versions received in the server's version negotiation
- // packet (or be empty if no such packet was received).
- //
- // Returns QUIC_NO_ERROR if this is the case or returns the appropriate error
- // code and sets |error_details|.
- static QuicErrorCode ValidateServerHelloVersions(
- const QuicVersionLabelVector& server_versions,
- const ParsedQuicVersionVector& negotiated_versions,
- std::string* error_details);
-
- // Validates that |client_hello| is actually a CHLO and that this is not part
- // of a downgrade attack.
- // This includes verifiying versions and detecting downgrade attacks.
- //
- // Returns QUIC_NO_ERROR if this is the case or returns the appropriate error
- // code and sets |error_details|.
- static QuicErrorCode ValidateClientHello(
- const CryptoHandshakeMessage& client_hello, ParsedQuicVersion version,
- const ParsedQuicVersionVector& supported_versions,
- std::string* error_details);
-
- // Validates that the |client_version| received does not indicate that a
- // downgrade attack has occurred. |connection_version| is the version of the
- // QuicConnection, and |supported_versions| is all versions that that
- // QuicConnection supports.
- //
- // Returns QUIC_NO_ERROR if this is the case or returns the appropriate error
- // code and sets |error_details|.
- static QuicErrorCode ValidateClientHelloVersion(
- QuicVersionLabel client_version, ParsedQuicVersion connection_version,
- const ParsedQuicVersionVector& supported_versions,
- std::string* error_details);
-
- // Validates that the chosen version from the version_information matches the
- // version from the session. Returns true if they match, otherwise returns
- // false and fills in |error_details|.
- static bool ValidateChosenVersion(
- const QuicVersionLabel& version_information_chosen_version,
- const ParsedQuicVersion& session_version, std::string* error_details);
-
- // Validates that there was no downgrade attack involving a version
- // negotiation packet. This verifies that if the client was initially
- // configured with |client_original_supported_versions| and it had received a
- // version negotiation packet with |version_information_other_versions|, then
- // it would have selected |session_version|. Returns true if they match (or if
- // |client_original_supported_versions| is empty indicating no version
- // negotiation packet was received), otherwise returns
- // false and fills in |error_details|.
- static bool ValidateServerVersions(
- const QuicVersionLabelVector& version_information_other_versions,
- const ParsedQuicVersion& session_version,
- const ParsedQuicVersionVector& client_original_supported_versions,
- std::string* error_details);
-
- // Returns the name of the HandshakeFailureReason as a char*
- static const char* HandshakeFailureReasonToString(
- HandshakeFailureReason reason);
-
- // Returns the name of an ssl_early_data_reason_t as a char*
- static std::string EarlyDataReasonToString(ssl_early_data_reason_t reason);
-
- // Returns a hash of the serialized |message|.
- static std::string HashHandshakeMessage(const CryptoHandshakeMessage& message,
- Perspective perspective);
-
- // Wraps SSL_serialize_capabilities. Return nullptr if failed.
- static bool GetSSLCapabilities(const SSL* ssl,
- bssl::UniquePtr<uint8_t>* capabilities,
- size_t* capabilities_len);
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_CRYPTO_CRYPTO_UTILS_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_utils_test.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_utils_test.cc
deleted file mode 100644
index f0d944b4fea..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_utils_test.cc
+++ /dev/null
@@ -1,262 +0,0 @@
-// Copyright (c) 2013 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 "quic/core/crypto/crypto_utils.h"
-
-#include <string>
-
-#include "absl/base/macros.h"
-#include "absl/strings/escaping.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/quic_test_utils.h"
-#include "common/test_tools/quiche_test_utils.h"
-
-namespace quic {
-namespace test {
-namespace {
-
-class CryptoUtilsTest : public QuicTest {};
-
-TEST_F(CryptoUtilsTest, HandshakeFailureReasonToString) {
- EXPECT_STREQ("HANDSHAKE_OK",
- CryptoUtils::HandshakeFailureReasonToString(HANDSHAKE_OK));
- EXPECT_STREQ("CLIENT_NONCE_UNKNOWN_FAILURE",
- CryptoUtils::HandshakeFailureReasonToString(
- CLIENT_NONCE_UNKNOWN_FAILURE));
- EXPECT_STREQ("CLIENT_NONCE_INVALID_FAILURE",
- CryptoUtils::HandshakeFailureReasonToString(
- CLIENT_NONCE_INVALID_FAILURE));
- EXPECT_STREQ("CLIENT_NONCE_NOT_UNIQUE_FAILURE",
- CryptoUtils::HandshakeFailureReasonToString(
- CLIENT_NONCE_NOT_UNIQUE_FAILURE));
- EXPECT_STREQ("CLIENT_NONCE_INVALID_ORBIT_FAILURE",
- CryptoUtils::HandshakeFailureReasonToString(
- CLIENT_NONCE_INVALID_ORBIT_FAILURE));
- EXPECT_STREQ("CLIENT_NONCE_INVALID_TIME_FAILURE",
- CryptoUtils::HandshakeFailureReasonToString(
- CLIENT_NONCE_INVALID_TIME_FAILURE));
- EXPECT_STREQ("CLIENT_NONCE_STRIKE_REGISTER_TIMEOUT",
- CryptoUtils::HandshakeFailureReasonToString(
- CLIENT_NONCE_STRIKE_REGISTER_TIMEOUT));
- EXPECT_STREQ("CLIENT_NONCE_STRIKE_REGISTER_FAILURE",
- CryptoUtils::HandshakeFailureReasonToString(
- CLIENT_NONCE_STRIKE_REGISTER_FAILURE));
- EXPECT_STREQ("SERVER_NONCE_DECRYPTION_FAILURE",
- CryptoUtils::HandshakeFailureReasonToString(
- SERVER_NONCE_DECRYPTION_FAILURE));
- EXPECT_STREQ("SERVER_NONCE_INVALID_FAILURE",
- CryptoUtils::HandshakeFailureReasonToString(
- SERVER_NONCE_INVALID_FAILURE));
- EXPECT_STREQ("SERVER_NONCE_NOT_UNIQUE_FAILURE",
- CryptoUtils::HandshakeFailureReasonToString(
- SERVER_NONCE_NOT_UNIQUE_FAILURE));
- EXPECT_STREQ("SERVER_NONCE_INVALID_TIME_FAILURE",
- CryptoUtils::HandshakeFailureReasonToString(
- SERVER_NONCE_INVALID_TIME_FAILURE));
- EXPECT_STREQ("SERVER_NONCE_REQUIRED_FAILURE",
- CryptoUtils::HandshakeFailureReasonToString(
- SERVER_NONCE_REQUIRED_FAILURE));
- EXPECT_STREQ("SERVER_CONFIG_INCHOATE_HELLO_FAILURE",
- CryptoUtils::HandshakeFailureReasonToString(
- SERVER_CONFIG_INCHOATE_HELLO_FAILURE));
- EXPECT_STREQ("SERVER_CONFIG_UNKNOWN_CONFIG_FAILURE",
- CryptoUtils::HandshakeFailureReasonToString(
- SERVER_CONFIG_UNKNOWN_CONFIG_FAILURE));
- EXPECT_STREQ("SOURCE_ADDRESS_TOKEN_INVALID_FAILURE",
- CryptoUtils::HandshakeFailureReasonToString(
- SOURCE_ADDRESS_TOKEN_INVALID_FAILURE));
- EXPECT_STREQ("SOURCE_ADDRESS_TOKEN_DECRYPTION_FAILURE",
- CryptoUtils::HandshakeFailureReasonToString(
- SOURCE_ADDRESS_TOKEN_DECRYPTION_FAILURE));
- EXPECT_STREQ("SOURCE_ADDRESS_TOKEN_PARSE_FAILURE",
- CryptoUtils::HandshakeFailureReasonToString(
- SOURCE_ADDRESS_TOKEN_PARSE_FAILURE));
- EXPECT_STREQ("SOURCE_ADDRESS_TOKEN_DIFFERENT_IP_ADDRESS_FAILURE",
- CryptoUtils::HandshakeFailureReasonToString(
- SOURCE_ADDRESS_TOKEN_DIFFERENT_IP_ADDRESS_FAILURE));
- EXPECT_STREQ("SOURCE_ADDRESS_TOKEN_CLOCK_SKEW_FAILURE",
- CryptoUtils::HandshakeFailureReasonToString(
- SOURCE_ADDRESS_TOKEN_CLOCK_SKEW_FAILURE));
- EXPECT_STREQ("SOURCE_ADDRESS_TOKEN_EXPIRED_FAILURE",
- CryptoUtils::HandshakeFailureReasonToString(
- SOURCE_ADDRESS_TOKEN_EXPIRED_FAILURE));
- EXPECT_STREQ("INVALID_EXPECTED_LEAF_CERTIFICATE",
- CryptoUtils::HandshakeFailureReasonToString(
- INVALID_EXPECTED_LEAF_CERTIFICATE));
- EXPECT_STREQ("MAX_FAILURE_REASON",
- CryptoUtils::HandshakeFailureReasonToString(MAX_FAILURE_REASON));
- EXPECT_STREQ(
- "INVALID_HANDSHAKE_FAILURE_REASON",
- CryptoUtils::HandshakeFailureReasonToString(
- static_cast<HandshakeFailureReason>(MAX_FAILURE_REASON + 1)));
-}
-
-TEST_F(CryptoUtilsTest, AuthTagLengths) {
- for (const auto& version : AllSupportedVersions()) {
- for (QuicTag algo : {kAESG, kCC20}) {
- SCOPED_TRACE(version);
- std::unique_ptr<QuicEncrypter> encrypter(
- QuicEncrypter::Create(version, algo));
- size_t auth_tag_size = 12;
- if (version.UsesInitialObfuscators()) {
- auth_tag_size = 16;
- }
- EXPECT_EQ(encrypter->GetCiphertextSize(0), auth_tag_size);
- }
- }
-}
-
-TEST_F(CryptoUtilsTest, ValidateChosenVersion) {
- for (const ParsedQuicVersion& v1 : AllSupportedVersions()) {
- for (const ParsedQuicVersion& v2 : AllSupportedVersions()) {
- std::string error_details;
- bool success = CryptoUtils::ValidateChosenVersion(
- CreateQuicVersionLabel(v1), v2, &error_details);
- EXPECT_EQ(success, v1 == v2);
- EXPECT_EQ(success, error_details.empty());
- }
- }
-}
-
-TEST_F(CryptoUtilsTest, ValidateServerVersionsNoVersionNegotiation) {
- QuicVersionLabelVector version_information_other_versions;
- ParsedQuicVersionVector client_original_supported_versions;
- for (const ParsedQuicVersion& version : AllSupportedVersions()) {
- std::string error_details;
- EXPECT_TRUE(CryptoUtils::ValidateServerVersions(
- version_information_other_versions, version,
- client_original_supported_versions, &error_details));
- EXPECT_TRUE(error_details.empty());
- }
-}
-
-TEST_F(CryptoUtilsTest, ValidateServerVersionsWithVersionNegotiation) {
- for (const ParsedQuicVersion& version : AllSupportedVersions()) {
- QuicVersionLabelVector version_information_other_versions{
- CreateQuicVersionLabel(version)};
- ParsedQuicVersionVector client_original_supported_versions{
- ParsedQuicVersion::ReservedForNegotiation(), version};
- std::string error_details;
- EXPECT_TRUE(CryptoUtils::ValidateServerVersions(
- version_information_other_versions, version,
- client_original_supported_versions, &error_details));
- EXPECT_TRUE(error_details.empty());
- }
-}
-
-TEST_F(CryptoUtilsTest, ValidateServerVersionsWithDowngrade) {
- if (AllSupportedVersions().size() <= 1) {
- // We are not vulnerable to downgrade if we only support one version.
- return;
- }
- ParsedQuicVersion client_version = AllSupportedVersions().front();
- ParsedQuicVersion server_version = AllSupportedVersions().back();
- ASSERT_NE(client_version, server_version);
- QuicVersionLabelVector version_information_other_versions{
- CreateQuicVersionLabel(client_version)};
- ParsedQuicVersionVector client_original_supported_versions{
- ParsedQuicVersion::ReservedForNegotiation(), server_version};
- std::string error_details;
- EXPECT_FALSE(CryptoUtils::ValidateServerVersions(
- version_information_other_versions, server_version,
- client_original_supported_versions, &error_details));
- EXPECT_FALSE(error_details.empty());
-}
-
-// Test that the library is using the correct labels for each version, and
-// therefore generating correct obfuscators, using the test vectors in appendix
-// A of each RFC or internet-draft.
-TEST_F(CryptoUtilsTest, ValidateCryptoLabels) {
- // if the number of HTTP/3 QUIC versions has changed, we need to change the
- // expected_keys hardcoded into this test. Regrettably, this is not a
- // compile-time constant.
- EXPECT_EQ(AllSupportedVersionsWithTls().size(), 3u);
- const char draft_29_key[] = {// test vector from draft-ietf-quic-tls-29, A.1
- 0x14,
- static_cast<char>(0x9d),
- 0x0b,
- 0x16,
- 0x62,
- static_cast<char>(0xab),
- static_cast<char>(0x87),
- 0x1f,
- static_cast<char>(0xbe),
- 0x63,
- static_cast<char>(0xc4),
- static_cast<char>(0x9b),
- 0x5e,
- 0x65,
- 0x5a,
- 0x5d};
- const char v1_key[] = {// test vector from RFC 9001, A.1
- static_cast<char>(0xcf),
- 0x3a,
- 0x53,
- 0x31,
- 0x65,
- 0x3c,
- 0x36,
- 0x4c,
- static_cast<char>(0x88),
- static_cast<char>(0xf0),
- static_cast<char>(0xf3),
- 0x79,
- static_cast<char>(0xb6),
- 0x06,
- 0x7e,
- 0x37};
- const char v2_01_key[] = {// test vector from draft-ietf-quic-v2-01
- 0x15,
- static_cast<char>(0xd5),
- static_cast<char>(0xb4),
- static_cast<char>(0xd9),
- static_cast<char>(0xa2),
- static_cast<char>(0xb8),
- static_cast<char>(0x91),
- 0x6a,
- static_cast<char>(0xa3),
- static_cast<char>(0x9b),
- 0x1b,
- static_cast<char>(0xfe),
- 0x57,
- 0x4d,
- 0x2a,
- static_cast<char>(0xad)};
- const char connection_id[] = // test vector from both docs
- {static_cast<char>(0x83),
- static_cast<char>(0x94),
- static_cast<char>(0xc8),
- static_cast<char>(0xf0),
- 0x3e,
- 0x51,
- 0x57,
- 0x08};
- const QuicConnectionId cid(connection_id, sizeof(connection_id));
- const char* key_str;
- size_t key_size;
- for (const ParsedQuicVersion& version : AllSupportedVersionsWithTls()) {
- if (version == ParsedQuicVersion::Draft29()) {
- key_str = draft_29_key;
- key_size = sizeof(draft_29_key);
- } else if (version == ParsedQuicVersion::RFCv1()) {
- key_str = v1_key;
- key_size = sizeof(v1_key);
- } else { // draft-ietf-quic-v2-01
- key_str = v2_01_key;
- key_size = sizeof(v2_01_key);
- }
- const absl::string_view expected_key{key_str, key_size};
-
- CrypterPair crypters;
- CryptoUtils::CreateInitialObfuscators(Perspective::IS_SERVER, version, cid,
- &crypters);
- EXPECT_EQ(crypters.encrypter->GetKey(), expected_key);
- }
-}
-
-} // namespace
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/curve25519_key_exchange.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/curve25519_key_exchange.cc
deleted file mode 100644
index bdf3a081d02..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/curve25519_key_exchange.cc
+++ /dev/null
@@ -1,87 +0,0 @@
-// Copyright (c) 2013 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 "quic/core/crypto/curve25519_key_exchange.h"
-
-#include <cstdint>
-#include <cstring>
-#include <string>
-
-#include "absl/memory/memory.h"
-#include "absl/strings/string_view.h"
-#include "third_party/boringssl/src/include/openssl/curve25519.h"
-#include "quic/core/crypto/quic_random.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-
-namespace quic {
-
-Curve25519KeyExchange::Curve25519KeyExchange() {}
-
-Curve25519KeyExchange::~Curve25519KeyExchange() {}
-
-// static
-std::unique_ptr<Curve25519KeyExchange> Curve25519KeyExchange::New(
- QuicRandom* rand) {
- std::unique_ptr<Curve25519KeyExchange> result =
- New(Curve25519KeyExchange::NewPrivateKey(rand));
- QUIC_BUG_IF(quic_bug_12891_1, result == nullptr);
- return result;
-}
-
-// static
-std::unique_ptr<Curve25519KeyExchange> Curve25519KeyExchange::New(
- absl::string_view private_key) {
- // We don't want to #include the BoringSSL headers in the public header file,
- // so we use literals for the sizes of private_key_ and public_key_. Here we
- // assert that those values are equal to the values from the BoringSSL
- // header.
- static_assert(
- sizeof(Curve25519KeyExchange::private_key_) == X25519_PRIVATE_KEY_LEN,
- "header out of sync");
- static_assert(
- sizeof(Curve25519KeyExchange::public_key_) == X25519_PUBLIC_VALUE_LEN,
- "header out of sync");
-
- if (private_key.size() != X25519_PRIVATE_KEY_LEN) {
- return nullptr;
- }
-
- // Use absl::WrapUnique(new) instead of std::make_unique because
- // Curve25519KeyExchange has a private constructor.
- auto ka = absl::WrapUnique(new Curve25519KeyExchange);
- memcpy(ka->private_key_, private_key.data(), X25519_PRIVATE_KEY_LEN);
- X25519_public_from_private(ka->public_key_, ka->private_key_);
- return ka;
-}
-
-// static
-std::string Curve25519KeyExchange::NewPrivateKey(QuicRandom* rand) {
- uint8_t private_key[X25519_PRIVATE_KEY_LEN];
- rand->RandBytes(private_key, sizeof(private_key));
- return std::string(reinterpret_cast<char*>(private_key), sizeof(private_key));
-}
-
-bool Curve25519KeyExchange::CalculateSharedKeySync(
- absl::string_view peer_public_value,
- std::string* shared_key) const {
- if (peer_public_value.size() != X25519_PUBLIC_VALUE_LEN) {
- return false;
- }
-
- uint8_t result[X25519_PUBLIC_VALUE_LEN];
- if (!X25519(result, private_key_,
- reinterpret_cast<const uint8_t*>(peer_public_value.data()))) {
- return false;
- }
-
- shared_key->assign(reinterpret_cast<char*>(result), sizeof(result));
- return true;
-}
-
-absl::string_view Curve25519KeyExchange::public_value() const {
- return absl::string_view(reinterpret_cast<const char*>(public_key_),
- sizeof(public_key_));
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/curve25519_key_exchange.h b/chromium/net/third_party/quiche/src/quic/core/crypto/curve25519_key_exchange.h
deleted file mode 100644
index b6a12b634c4..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/curve25519_key_exchange.h
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright (c) 2013 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_CRYPTO_CURVE25519_KEY_EXCHANGE_H_
-#define QUICHE_QUIC_CORE_CRYPTO_CURVE25519_KEY_EXCHANGE_H_
-
-#include <cstdint>
-#include <string>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/crypto/key_exchange.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-class QuicRandom;
-
-// Curve25519KeyExchange implements a SynchronousKeyExchange using
-// elliptic-curve Diffie-Hellman on curve25519. See http://cr.yp.to/ecdh.html
-class QUIC_EXPORT_PRIVATE Curve25519KeyExchange
- : public SynchronousKeyExchange {
- public:
- ~Curve25519KeyExchange() override;
-
- // New generates a private key and then creates new key-exchange object.
- static std::unique_ptr<Curve25519KeyExchange> New(QuicRandom* rand);
-
- // New creates a new key-exchange object from a private key. If |private_key|
- // is invalid, nullptr is returned.
- static std::unique_ptr<Curve25519KeyExchange> New(
- absl::string_view private_key);
-
- // NewPrivateKey returns a private key, generated from |rand|, suitable for
- // passing to |New|.
- static std::string NewPrivateKey(QuicRandom* rand);
-
- // SynchronousKeyExchange interface.
- bool CalculateSharedKeySync(absl::string_view peer_public_value,
- std::string* shared_key) const override;
- absl::string_view public_value() const override;
- QuicTag type() const override { return kC255; }
-
- private:
- Curve25519KeyExchange();
-
- uint8_t private_key_[32];
- uint8_t public_key_[32];
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_CRYPTO_CURVE25519_KEY_EXCHANGE_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/curve25519_key_exchange_test.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/curve25519_key_exchange_test.cc
deleted file mode 100644
index 968b9693a4c..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/curve25519_key_exchange_test.cc
+++ /dev/null
@@ -1,104 +0,0 @@
-// Copyright (c) 2013 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 "quic/core/crypto/curve25519_key_exchange.h"
-
-#include <memory>
-#include <string>
-#include <utility>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/crypto/quic_random.h"
-#include "quic/platform/api/quic_test.h"
-
-namespace quic {
-namespace test {
-
-class Curve25519KeyExchangeTest : public QuicTest {
- public:
- // Holds the result of a key exchange callback.
- class TestCallbackResult {
- public:
- void set_ok(bool ok) { ok_ = ok; }
- bool ok() { return ok_; }
-
- private:
- bool ok_ = false;
- };
-
- // Key exchange callback which sets the result into the specified
- // TestCallbackResult.
- class TestCallback : public AsynchronousKeyExchange::Callback {
- public:
- TestCallback(TestCallbackResult* result) : result_(result) {}
- virtual ~TestCallback() = default;
-
- void Run(bool ok) { result_->set_ok(ok); }
-
- private:
- TestCallbackResult* result_;
- };
-};
-
-// SharedKey just tests that the basic key exchange identity holds: that both
-// parties end up with the same key.
-TEST_F(Curve25519KeyExchangeTest, SharedKey) {
- QuicRandom* const rand = QuicRandom::GetInstance();
-
- for (int i = 0; i < 5; i++) {
- const std::string alice_key(Curve25519KeyExchange::NewPrivateKey(rand));
- const std::string bob_key(Curve25519KeyExchange::NewPrivateKey(rand));
-
- std::unique_ptr<Curve25519KeyExchange> alice(
- Curve25519KeyExchange::New(alice_key));
- std::unique_ptr<Curve25519KeyExchange> bob(
- Curve25519KeyExchange::New(bob_key));
-
- const absl::string_view alice_public(alice->public_value());
- const absl::string_view bob_public(bob->public_value());
-
- std::string alice_shared, bob_shared;
- ASSERT_TRUE(alice->CalculateSharedKeySync(bob_public, &alice_shared));
- ASSERT_TRUE(bob->CalculateSharedKeySync(alice_public, &bob_shared));
- ASSERT_EQ(alice_shared, bob_shared);
- }
-}
-
-// SharedKeyAsync just tests that the basic asynchronous key exchange identity
-// holds: that both parties end up with the same key.
-TEST_F(Curve25519KeyExchangeTest, SharedKeyAsync) {
- QuicRandom* const rand = QuicRandom::GetInstance();
-
- for (int i = 0; i < 5; i++) {
- const std::string alice_key(Curve25519KeyExchange::NewPrivateKey(rand));
- const std::string bob_key(Curve25519KeyExchange::NewPrivateKey(rand));
-
- std::unique_ptr<Curve25519KeyExchange> alice(
- Curve25519KeyExchange::New(alice_key));
- std::unique_ptr<Curve25519KeyExchange> bob(
- Curve25519KeyExchange::New(bob_key));
-
- const absl::string_view alice_public(alice->public_value());
- const absl::string_view bob_public(bob->public_value());
-
- std::string alice_shared, bob_shared;
- TestCallbackResult alice_result;
- ASSERT_FALSE(alice_result.ok());
- alice->CalculateSharedKeyAsync(
- bob_public, &alice_shared,
- std::make_unique<TestCallback>(&alice_result));
- ASSERT_TRUE(alice_result.ok());
- TestCallbackResult bob_result;
- ASSERT_FALSE(bob_result.ok());
- bob->CalculateSharedKeyAsync(alice_public, &bob_shared,
- std::make_unique<TestCallback>(&bob_result));
- ASSERT_TRUE(bob_result.ok());
- ASSERT_EQ(alice_shared, bob_shared);
- ASSERT_NE(0u, alice_shared.length());
- ASSERT_NE(0u, bob_shared.length());
- }
-}
-
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/key_exchange.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/key_exchange.cc
deleted file mode 100644
index c97d5ddb512..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/key_exchange.cc
+++ /dev/null
@@ -1,43 +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 "quic/core/crypto/key_exchange.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/crypto/curve25519_key_exchange.h"
-#include "quic/core/crypto/p256_key_exchange.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-
-namespace quic {
-
-std::unique_ptr<SynchronousKeyExchange> CreateLocalSynchronousKeyExchange(
- QuicTag type,
- absl::string_view private_key) {
- switch (type) {
- case kC255:
- return Curve25519KeyExchange::New(private_key);
- case kP256:
- return P256KeyExchange::New(private_key);
- default:
- QUIC_BUG(quic_bug_10712_1)
- << "Unknown key exchange method: " << QuicTagToString(type);
- return nullptr;
- }
-}
-
-std::unique_ptr<SynchronousKeyExchange> CreateLocalSynchronousKeyExchange(
- QuicTag type,
- QuicRandom* rand) {
- switch (type) {
- case kC255:
- return Curve25519KeyExchange::New(rand);
- case kP256:
- return P256KeyExchange::New();
- default:
- QUIC_BUG(quic_bug_10712_2)
- << "Unknown key exchange method: " << QuicTagToString(type);
- return nullptr;
- }
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/key_exchange.h b/chromium/net/third_party/quiche/src/quic/core/crypto/key_exchange.h
deleted file mode 100644
index 0937caaef31..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/key_exchange.h
+++ /dev/null
@@ -1,105 +0,0 @@
-// Copyright (c) 2013 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_CRYPTO_KEY_EXCHANGE_H_
-#define QUICHE_QUIC_CORE_CRYPTO_KEY_EXCHANGE_H_
-
-#include <memory>
-#include <string>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/crypto/crypto_protocol.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-class QuicRandom;
-
-// Interface for a Diffie-Hellman key exchange with an asynchronous interface.
-// This allows for implementations which hold the private key locally, as well
-// as ones which make an RPC to an external key-exchange service.
-class QUIC_EXPORT_PRIVATE AsynchronousKeyExchange {
- public:
- virtual ~AsynchronousKeyExchange() = default;
-
- // Callback base class for receiving the results of an async call to
- // CalculateSharedKeys.
- class QUIC_EXPORT_PRIVATE Callback {
- public:
- Callback() = default;
- virtual ~Callback() = default;
-
- // Invoked upon completion of CalculateSharedKeysAsync.
- //
- // |ok| indicates whether the operation completed successfully. If false,
- // then the value pointed to by |shared_key| passed in to
- // CalculateSharedKeyAsync is undefined.
- virtual void Run(bool ok) = 0;
-
- private:
- Callback(const Callback&) = delete;
- Callback& operator=(const Callback&) = delete;
- };
-
- // CalculateSharedKey computes the shared key between a private key which is
- // conceptually owned by this object (though it may not be physically located
- // in this process) and a public value from the peer. Callers should expect
- // that |callback| might be invoked synchronously. Results will be written
- // into |*shared_key|.
- virtual void CalculateSharedKeyAsync(
- absl::string_view peer_public_value,
- std::string* shared_key,
- std::unique_ptr<Callback> callback) const = 0;
-
- // Tag indicating the key-exchange algorithm this object will use.
- virtual QuicTag type() const = 0;
-};
-
-// Interface for a Diffie-Hellman key exchange with both synchronous and
-// asynchronous interfaces. Only implementations which hold the private key
-// locally should implement this interface.
-class QUIC_EXPORT_PRIVATE SynchronousKeyExchange
- : public AsynchronousKeyExchange {
- public:
- virtual ~SynchronousKeyExchange() = default;
-
- // AyncKeyExchange API. Note that this method is marked 'final.' Subclasses
- // should implement CalculateSharedKeySync only.
- void CalculateSharedKeyAsync(absl::string_view peer_public_value,
- std::string* shared_key,
- std::unique_ptr<Callback> callback) const final {
- const bool ok = CalculateSharedKeySync(peer_public_value, shared_key);
- callback->Run(ok);
- }
-
- // CalculateSharedKey computes the shared key between a local private key and
- // a public value from the peer. Results will be written into |*shared_key|.
- virtual bool CalculateSharedKeySync(absl::string_view peer_public_value,
- std::string* shared_key) const = 0;
-
- // public_value returns the local public key which can be sent to a peer in
- // order to complete a key exchange. The returned absl::string_view is
- // a reference to a member of this object and is only valid for as long as it
- // exists.
- virtual absl::string_view public_value() const = 0;
-};
-
-// Create a SynchronousKeyExchange object which will use a keypair generated
-// from |private_key|, and a key-exchange algorithm specified by |type|, which
-// must be one of {kC255, kC256}. Returns nullptr if |private_key| or |type| is
-// invalid.
-std::unique_ptr<SynchronousKeyExchange> CreateLocalSynchronousKeyExchange(
- QuicTag type,
- absl::string_view private_key);
-
-// Create a SynchronousKeyExchange object which will use a keypair generated
-// from |rand|, and a key-exchange algorithm specified by |type|, which must be
-// one of {kC255, kC256}. Returns nullptr if |type| is invalid.
-std::unique_ptr<SynchronousKeyExchange> CreateLocalSynchronousKeyExchange(
- QuicTag type,
- QuicRandom* rand);
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_CRYPTO_KEY_EXCHANGE_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/null_decrypter.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/null_decrypter.cc
deleted file mode 100644
index fd611bd3695..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/null_decrypter.cc
+++ /dev/null
@@ -1,136 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/crypto/null_decrypter.h"
-
-#include <cstdint>
-
-#include "absl/numeric/int128.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_data_reader.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "common/quiche_endian.h"
-
-namespace quic {
-
-NullDecrypter::NullDecrypter(Perspective perspective)
- : perspective_(perspective) {}
-
-bool NullDecrypter::SetKey(absl::string_view key) {
- return key.empty();
-}
-
-bool NullDecrypter::SetNoncePrefix(absl::string_view nonce_prefix) {
- return nonce_prefix.empty();
-}
-
-bool NullDecrypter::SetIV(absl::string_view iv) {
- return iv.empty();
-}
-
-bool NullDecrypter::SetHeaderProtectionKey(absl::string_view key) {
- return key.empty();
-}
-
-bool NullDecrypter::SetPreliminaryKey(absl::string_view /*key*/) {
- QUIC_BUG(quic_bug_10652_1) << "Should not be called";
- return false;
-}
-
-bool NullDecrypter::SetDiversificationNonce(
- const DiversificationNonce& /*nonce*/) {
- QUIC_BUG(quic_bug_10652_2) << "Should not be called";
- return true;
-}
-
-bool NullDecrypter::DecryptPacket(uint64_t /*packet_number*/,
- absl::string_view associated_data,
- absl::string_view ciphertext,
- char* output,
- size_t* output_length,
- size_t max_output_length) {
- QuicDataReader reader(ciphertext.data(), ciphertext.length(),
- quiche::HOST_BYTE_ORDER);
- absl::uint128 hash;
-
- if (!ReadHash(&reader, &hash)) {
- return false;
- }
-
- absl::string_view plaintext = reader.ReadRemainingPayload();
- if (plaintext.length() > max_output_length) {
- QUIC_BUG(quic_bug_10652_3)
- << "Output buffer must be larger than the plaintext.";
- return false;
- }
- if (hash != ComputeHash(associated_data, plaintext)) {
- return false;
- }
- // Copy the plaintext to output.
- memcpy(output, plaintext.data(), plaintext.length());
- *output_length = plaintext.length();
- return true;
-}
-
-std::string NullDecrypter::GenerateHeaderProtectionMask(
- QuicDataReader* /*sample_reader*/) {
- return std::string(5, 0);
-}
-
-size_t NullDecrypter::GetKeySize() const {
- return 0;
-}
-
-size_t NullDecrypter::GetNoncePrefixSize() const {
- return 0;
-}
-
-size_t NullDecrypter::GetIVSize() const {
- return 0;
-}
-
-absl::string_view NullDecrypter::GetKey() const {
- return absl::string_view();
-}
-
-absl::string_view NullDecrypter::GetNoncePrefix() const {
- return absl::string_view();
-}
-
-uint32_t NullDecrypter::cipher_id() const {
- return 0;
-}
-
-QuicPacketCount NullDecrypter::GetIntegrityLimit() const {
- return std::numeric_limits<QuicPacketCount>::max();
-}
-
-bool NullDecrypter::ReadHash(QuicDataReader* reader, absl::uint128* hash) {
- uint64_t lo;
- uint32_t hi;
- if (!reader->ReadUInt64(&lo) || !reader->ReadUInt32(&hi)) {
- return false;
- }
- *hash = absl::MakeUint128(hi, lo);
- return true;
-}
-
-absl::uint128 NullDecrypter::ComputeHash(const absl::string_view data1,
- const absl::string_view data2) const {
- absl::uint128 correct_hash;
- if (perspective_ == Perspective::IS_CLIENT) {
- // Peer is a server.
- correct_hash = QuicUtils::FNV1a_128_Hash_Three(data1, data2, "Server");
- } else {
- // Peer is a client.
- correct_hash = QuicUtils::FNV1a_128_Hash_Three(data1, data2, "Client");
- }
- absl::uint128 mask = absl::MakeUint128(UINT64_C(0x0), UINT64_C(0xffffffff));
- mask <<= 96;
- correct_hash &= ~mask;
- return correct_hash;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/null_decrypter.h b/chromium/net/third_party/quiche/src/quic/core/crypto/null_decrypter.h
deleted file mode 100644
index b36fa82848b..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/null_decrypter.h
+++ /dev/null
@@ -1,65 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_CRYPTO_NULL_DECRYPTER_H_
-#define QUICHE_QUIC_CORE_CRYPTO_NULL_DECRYPTER_H_
-
-#include <cstddef>
-#include <cstdint>
-
-#include "absl/numeric/int128.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/crypto/quic_decrypter.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-class QuicDataReader;
-
-// A NullDecrypter is a QuicDecrypter used before a crypto negotiation
-// has occurred. It does not actually decrypt the payload, but does
-// verify a hash (fnv128) over both the payload and associated data.
-class QUIC_EXPORT_PRIVATE NullDecrypter : public QuicDecrypter {
- public:
- explicit NullDecrypter(Perspective perspective);
- NullDecrypter(const NullDecrypter&) = delete;
- NullDecrypter& operator=(const NullDecrypter&) = delete;
- ~NullDecrypter() override {}
-
- // QuicDecrypter implementation
- bool SetKey(absl::string_view key) override;
- bool SetNoncePrefix(absl::string_view nonce_prefix) override;
- bool SetIV(absl::string_view iv) override;
- bool SetHeaderProtectionKey(absl::string_view key) override;
- bool SetPreliminaryKey(absl::string_view key) override;
- bool SetDiversificationNonce(const DiversificationNonce& nonce) override;
- bool DecryptPacket(uint64_t packet_number,
- absl::string_view associated_data,
- absl::string_view ciphertext,
- char* output,
- size_t* output_length,
- size_t max_output_length) override;
- std::string GenerateHeaderProtectionMask(
- QuicDataReader* sample_reader) override;
- size_t GetKeySize() const override;
- size_t GetNoncePrefixSize() const override;
- size_t GetIVSize() const override;
- absl::string_view GetKey() const override;
- absl::string_view GetNoncePrefix() const override;
-
- uint32_t cipher_id() const override;
- QuicPacketCount GetIntegrityLimit() const override;
-
- private:
- bool ReadHash(QuicDataReader* reader, absl::uint128* hash);
- absl::uint128 ComputeHash(absl::string_view data1,
- absl::string_view data2) const;
-
- Perspective perspective_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_CRYPTO_NULL_DECRYPTER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/null_decrypter_test.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/null_decrypter_test.cc
deleted file mode 100644
index 394fcfb3ed8..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/null_decrypter_test.cc
+++ /dev/null
@@ -1,136 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/crypto/null_decrypter.h"
-#include "absl/base/macros.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/quic_test_utils.h"
-
-namespace quic {
-namespace test {
-
-class NullDecrypterTest : public QuicTestWithParam<bool> {};
-
-TEST_F(NullDecrypterTest, DecryptClient) {
- unsigned char expected[] = {
- // fnv hash
- 0x97,
- 0xdc,
- 0x27,
- 0x2f,
- 0x18,
- 0xa8,
- 0x56,
- 0x73,
- 0xdf,
- 0x8d,
- 0x1d,
- 0xd0,
- // payload
- 'g',
- 'o',
- 'o',
- 'd',
- 'b',
- 'y',
- 'e',
- '!',
- };
- const char* data = reinterpret_cast<const char*>(expected);
- size_t len = ABSL_ARRAYSIZE(expected);
- NullDecrypter decrypter(Perspective::IS_SERVER);
- char buffer[256];
- size_t length = 0;
- ASSERT_TRUE(decrypter.DecryptPacket(
- 0, "hello world!", absl::string_view(data, len), buffer, &length, 256));
- EXPECT_LT(0u, length);
- EXPECT_EQ("goodbye!", absl::string_view(buffer, length));
-}
-
-TEST_F(NullDecrypterTest, DecryptServer) {
- unsigned char expected[] = {
- // fnv hash
- 0x63,
- 0x5e,
- 0x08,
- 0x03,
- 0x32,
- 0x80,
- 0x8f,
- 0x73,
- 0xdf,
- 0x8d,
- 0x1d,
- 0x1a,
- // payload
- 'g',
- 'o',
- 'o',
- 'd',
- 'b',
- 'y',
- 'e',
- '!',
- };
- const char* data = reinterpret_cast<const char*>(expected);
- size_t len = ABSL_ARRAYSIZE(expected);
- NullDecrypter decrypter(Perspective::IS_CLIENT);
- char buffer[256];
- size_t length = 0;
- ASSERT_TRUE(decrypter.DecryptPacket(
- 0, "hello world!", absl::string_view(data, len), buffer, &length, 256));
- EXPECT_LT(0u, length);
- EXPECT_EQ("goodbye!", absl::string_view(buffer, length));
-}
-
-TEST_F(NullDecrypterTest, BadHash) {
- unsigned char expected[] = {
- // fnv hash
- 0x46,
- 0x11,
- 0xea,
- 0x5f,
- 0xcf,
- 0x1d,
- 0x66,
- 0x5b,
- 0xba,
- 0xf0,
- 0xbc,
- 0xfd,
- // payload
- 'g',
- 'o',
- 'o',
- 'd',
- 'b',
- 'y',
- 'e',
- '!',
- };
- const char* data = reinterpret_cast<const char*>(expected);
- size_t len = ABSL_ARRAYSIZE(expected);
- NullDecrypter decrypter(Perspective::IS_CLIENT);
- char buffer[256];
- size_t length = 0;
- ASSERT_FALSE(decrypter.DecryptPacket(
- 0, "hello world!", absl::string_view(data, len), buffer, &length, 256));
-}
-
-TEST_F(NullDecrypterTest, ShortInput) {
- unsigned char expected[] = {
- // fnv hash (truncated)
- 0x46, 0x11, 0xea, 0x5f, 0xcf, 0x1d, 0x66, 0x5b, 0xba, 0xf0, 0xbc,
- };
- const char* data = reinterpret_cast<const char*>(expected);
- size_t len = ABSL_ARRAYSIZE(expected);
- NullDecrypter decrypter(Perspective::IS_CLIENT);
- char buffer[256];
- size_t length = 0;
- ASSERT_FALSE(decrypter.DecryptPacket(
- 0, "hello world!", absl::string_view(data, len), buffer, &length, 256));
-}
-
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/null_encrypter.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/null_encrypter.cc
deleted file mode 100644
index a38532148b6..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/null_encrypter.cc
+++ /dev/null
@@ -1,103 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/crypto/null_encrypter.h"
-
-#include "absl/numeric/int128.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_data_writer.h"
-#include "quic/core/quic_utils.h"
-
-namespace quic {
-
-const size_t kHashSizeShort = 12; // size of uint128 serialized short
-
-NullEncrypter::NullEncrypter(Perspective perspective)
- : perspective_(perspective) {}
-
-bool NullEncrypter::SetKey(absl::string_view key) {
- return key.empty();
-}
-
-bool NullEncrypter::SetNoncePrefix(absl::string_view nonce_prefix) {
- return nonce_prefix.empty();
-}
-
-bool NullEncrypter::SetIV(absl::string_view iv) {
- return iv.empty();
-}
-
-bool NullEncrypter::SetHeaderProtectionKey(absl::string_view key) {
- return key.empty();
-}
-
-bool NullEncrypter::EncryptPacket(uint64_t /*packet_number*/,
- absl::string_view associated_data,
- absl::string_view plaintext,
- char* output,
- size_t* output_length,
- size_t max_output_length) {
- const size_t len = plaintext.size() + GetHashLength();
- if (max_output_length < len) {
- return false;
- }
- absl::uint128 hash;
- if (perspective_ == Perspective::IS_SERVER) {
- hash =
- QuicUtils::FNV1a_128_Hash_Three(associated_data, plaintext, "Server");
- } else {
- hash =
- QuicUtils::FNV1a_128_Hash_Three(associated_data, plaintext, "Client");
- }
- // TODO(ianswett): memmove required for in place encryption. Placing the
- // hash at the end would allow use of memcpy, doing nothing for in place.
- memmove(output + GetHashLength(), plaintext.data(), plaintext.length());
- QuicUtils::SerializeUint128Short(hash,
- reinterpret_cast<unsigned char*>(output));
- *output_length = len;
- return true;
-}
-
-std::string NullEncrypter::GenerateHeaderProtectionMask(
- absl::string_view /*sample*/) {
- return std::string(5, 0);
-}
-
-size_t NullEncrypter::GetKeySize() const {
- return 0;
-}
-
-size_t NullEncrypter::GetNoncePrefixSize() const {
- return 0;
-}
-
-size_t NullEncrypter::GetIVSize() const {
- return 0;
-}
-
-size_t NullEncrypter::GetMaxPlaintextSize(size_t ciphertext_size) const {
- return ciphertext_size - std::min(ciphertext_size, GetHashLength());
-}
-
-size_t NullEncrypter::GetCiphertextSize(size_t plaintext_size) const {
- return plaintext_size + GetHashLength();
-}
-
-QuicPacketCount NullEncrypter::GetConfidentialityLimit() const {
- return std::numeric_limits<QuicPacketCount>::max();
-}
-
-absl::string_view NullEncrypter::GetKey() const {
- return absl::string_view();
-}
-
-absl::string_view NullEncrypter::GetNoncePrefix() const {
- return absl::string_view();
-}
-
-size_t NullEncrypter::GetHashLength() const {
- return kHashSizeShort;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/null_encrypter.h b/chromium/net/third_party/quiche/src/quic/core/crypto/null_encrypter.h
deleted file mode 100644
index 9df1906db31..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/null_encrypter.h
+++ /dev/null
@@ -1,56 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_CRYPTO_NULL_ENCRYPTER_H_
-#define QUICHE_QUIC_CORE_CRYPTO_NULL_ENCRYPTER_H_
-
-#include <cstddef>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/crypto/quic_encrypter.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// A NullEncrypter is a QuicEncrypter used before a crypto negotiation
-// has occurred. It does not actually encrypt the payload, but does
-// generate a MAC (fnv128) over both the payload and associated data.
-class QUIC_EXPORT_PRIVATE NullEncrypter : public QuicEncrypter {
- public:
- explicit NullEncrypter(Perspective perspective);
- NullEncrypter(const NullEncrypter&) = delete;
- NullEncrypter& operator=(const NullEncrypter&) = delete;
- ~NullEncrypter() override {}
-
- // QuicEncrypter implementation
- bool SetKey(absl::string_view key) override;
- bool SetNoncePrefix(absl::string_view nonce_prefix) override;
- bool SetIV(absl::string_view iv) override;
- bool SetHeaderProtectionKey(absl::string_view key) override;
- bool EncryptPacket(uint64_t packet_number,
- absl::string_view associated_data,
- absl::string_view plaintext,
- char* output,
- size_t* output_length,
- size_t max_output_length) override;
- std::string GenerateHeaderProtectionMask(absl::string_view sample) override;
- size_t GetKeySize() const override;
- size_t GetNoncePrefixSize() const override;
- size_t GetIVSize() const override;
- size_t GetMaxPlaintextSize(size_t ciphertext_size) const override;
- size_t GetCiphertextSize(size_t plaintext_size) const override;
- QuicPacketCount GetConfidentialityLimit() const override;
- absl::string_view GetKey() const override;
- absl::string_view GetNoncePrefix() const override;
-
- private:
- size_t GetHashLength() const;
-
- Perspective perspective_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_CRYPTO_NULL_ENCRYPTER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/null_encrypter_test.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/null_encrypter_test.cc
deleted file mode 100644
index 6924f8a3672..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/null_encrypter_test.cc
+++ /dev/null
@@ -1,102 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/crypto/null_encrypter.h"
-#include "absl/base/macros.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/quic_test_utils.h"
-#include "common/test_tools/quiche_test_utils.h"
-
-namespace quic {
-namespace test {
-
-class NullEncrypterTest : public QuicTestWithParam<bool> {};
-
-TEST_F(NullEncrypterTest, EncryptClient) {
- unsigned char expected[] = {
- // fnv hash
- 0x97,
- 0xdc,
- 0x27,
- 0x2f,
- 0x18,
- 0xa8,
- 0x56,
- 0x73,
- 0xdf,
- 0x8d,
- 0x1d,
- 0xd0,
- // payload
- 'g',
- 'o',
- 'o',
- 'd',
- 'b',
- 'y',
- 'e',
- '!',
- };
- char encrypted[256];
- size_t encrypted_len = 0;
- NullEncrypter encrypter(Perspective::IS_CLIENT);
- ASSERT_TRUE(encrypter.EncryptPacket(0, "hello world!", "goodbye!", encrypted,
- &encrypted_len, 256));
- quiche::test::CompareCharArraysWithHexError(
- "encrypted data", encrypted, encrypted_len,
- reinterpret_cast<const char*>(expected), ABSL_ARRAYSIZE(expected));
-}
-
-TEST_F(NullEncrypterTest, EncryptServer) {
- unsigned char expected[] = {
- // fnv hash
- 0x63,
- 0x5e,
- 0x08,
- 0x03,
- 0x32,
- 0x80,
- 0x8f,
- 0x73,
- 0xdf,
- 0x8d,
- 0x1d,
- 0x1a,
- // payload
- 'g',
- 'o',
- 'o',
- 'd',
- 'b',
- 'y',
- 'e',
- '!',
- };
- char encrypted[256];
- size_t encrypted_len = 0;
- NullEncrypter encrypter(Perspective::IS_SERVER);
- ASSERT_TRUE(encrypter.EncryptPacket(0, "hello world!", "goodbye!", encrypted,
- &encrypted_len, 256));
- quiche::test::CompareCharArraysWithHexError(
- "encrypted data", encrypted, encrypted_len,
- reinterpret_cast<const char*>(expected), ABSL_ARRAYSIZE(expected));
-}
-
-TEST_F(NullEncrypterTest, GetMaxPlaintextSize) {
- NullEncrypter encrypter(Perspective::IS_CLIENT);
- EXPECT_EQ(1000u, encrypter.GetMaxPlaintextSize(1012));
- EXPECT_EQ(100u, encrypter.GetMaxPlaintextSize(112));
- EXPECT_EQ(10u, encrypter.GetMaxPlaintextSize(22));
- EXPECT_EQ(0u, encrypter.GetMaxPlaintextSize(11));
-}
-
-TEST_F(NullEncrypterTest, GetCiphertextSize) {
- NullEncrypter encrypter(Perspective::IS_CLIENT);
- EXPECT_EQ(1012u, encrypter.GetCiphertextSize(1000));
- EXPECT_EQ(112u, encrypter.GetCiphertextSize(100));
- EXPECT_EQ(22u, encrypter.GetCiphertextSize(10));
-}
-
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/p256_key_exchange.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/p256_key_exchange.cc
deleted file mode 100644
index 2a13c2e5a5c..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/p256_key_exchange.cc
+++ /dev/null
@@ -1,122 +0,0 @@
-// Copyright (c) 2013 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 "quic/core/crypto/p256_key_exchange.h"
-
-#include <cstdint>
-#include <cstring>
-#include <memory>
-#include <string>
-#include <utility>
-
-#include "absl/memory/memory.h"
-#include "absl/strings/string_view.h"
-#include "third_party/boringssl/src/include/openssl/ec.h"
-#include "third_party/boringssl/src/include/openssl/ecdh.h"
-#include "third_party/boringssl/src/include/openssl/err.h"
-#include "third_party/boringssl/src/include/openssl/evp.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-P256KeyExchange::P256KeyExchange(bssl::UniquePtr<EC_KEY> private_key,
- const uint8_t* public_key)
- : private_key_(std::move(private_key)) {
- memcpy(public_key_, public_key, sizeof(public_key_));
-}
-
-P256KeyExchange::~P256KeyExchange() {}
-
-// static
-std::unique_ptr<P256KeyExchange> P256KeyExchange::New() {
- return New(P256KeyExchange::NewPrivateKey());
-}
-
-// static
-std::unique_ptr<P256KeyExchange> P256KeyExchange::New(absl::string_view key) {
- if (key.empty()) {
- QUIC_DLOG(INFO) << "Private key is empty";
- return nullptr;
- }
-
- const uint8_t* keyp = reinterpret_cast<const uint8_t*>(key.data());
- bssl::UniquePtr<EC_KEY> private_key(
- d2i_ECPrivateKey(nullptr, &keyp, key.size()));
- if (!private_key.get() || !EC_KEY_check_key(private_key.get())) {
- QUIC_DLOG(INFO) << "Private key is invalid.";
- return nullptr;
- }
-
- uint8_t public_key[kUncompressedP256PointBytes];
- if (EC_POINT_point2oct(EC_KEY_get0_group(private_key.get()),
- EC_KEY_get0_public_key(private_key.get()),
- POINT_CONVERSION_UNCOMPRESSED, public_key,
- sizeof(public_key), nullptr) != sizeof(public_key)) {
- QUIC_DLOG(INFO) << "Can't get public key.";
- return nullptr;
- }
-
- return absl::WrapUnique(
- new P256KeyExchange(std::move(private_key), public_key));
-}
-
-// static
-std::string P256KeyExchange::NewPrivateKey() {
- bssl::UniquePtr<EC_KEY> key(EC_KEY_new_by_curve_name(NID_X9_62_prime256v1));
- if (!key.get() || !EC_KEY_generate_key(key.get())) {
- QUIC_DLOG(INFO) << "Can't generate a new private key.";
- return std::string();
- }
-
- int key_len = i2d_ECPrivateKey(key.get(), nullptr);
- if (key_len <= 0) {
- QUIC_DLOG(INFO) << "Can't convert private key to string";
- return std::string();
- }
- std::unique_ptr<uint8_t[]> private_key(new uint8_t[key_len]);
- uint8_t* keyp = private_key.get();
- if (!i2d_ECPrivateKey(key.get(), &keyp)) {
- QUIC_DLOG(INFO) << "Can't convert private key to string.";
- return std::string();
- }
- return std::string(reinterpret_cast<char*>(private_key.get()), key_len);
-}
-
-bool P256KeyExchange::CalculateSharedKeySync(
- absl::string_view peer_public_value,
- std::string* shared_key) const {
- if (peer_public_value.size() != kUncompressedP256PointBytes) {
- QUIC_DLOG(INFO) << "Peer public value is invalid";
- return false;
- }
-
- bssl::UniquePtr<EC_POINT> point(
- EC_POINT_new(EC_KEY_get0_group(private_key_.get())));
- if (!point.get() ||
- !EC_POINT_oct2point(/* also test if point is on curve */
- EC_KEY_get0_group(private_key_.get()), point.get(),
- reinterpret_cast<const uint8_t*>(
- peer_public_value.data()),
- peer_public_value.size(), nullptr)) {
- QUIC_DLOG(INFO) << "Can't convert peer public value to curve point.";
- return false;
- }
-
- uint8_t result[kP256FieldBytes];
- if (ECDH_compute_key(result, sizeof(result), point.get(), private_key_.get(),
- nullptr) != sizeof(result)) {
- QUIC_DLOG(INFO) << "Can't compute ECDH shared key.";
- return false;
- }
-
- shared_key->assign(reinterpret_cast<char*>(result), sizeof(result));
- return true;
-}
-
-absl::string_view P256KeyExchange::public_value() const {
- return absl::string_view(reinterpret_cast<const char*>(public_key_),
- sizeof(public_key_));
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/p256_key_exchange.h b/chromium/net/third_party/quiche/src/quic/core/crypto/p256_key_exchange.h
deleted file mode 100644
index 7c2125572a6..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/p256_key_exchange.h
+++ /dev/null
@@ -1,68 +0,0 @@
-// Copyright (c) 2013 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_CRYPTO_P256_KEY_EXCHANGE_H_
-#define QUICHE_QUIC_CORE_CRYPTO_P256_KEY_EXCHANGE_H_
-
-#include <cstdint>
-#include <string>
-
-#include "absl/strings/string_view.h"
-#include "third_party/boringssl/src/include/openssl/base.h"
-#include "quic/core/crypto/key_exchange.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// P256KeyExchange implements a SynchronousKeyExchange using elliptic-curve
-// Diffie-Hellman on NIST P-256.
-class QUIC_EXPORT_PRIVATE P256KeyExchange : public SynchronousKeyExchange {
- public:
- ~P256KeyExchange() override;
-
- // New generates a private key and then creates new key-exchange object.
- static std::unique_ptr<P256KeyExchange> New();
-
- // New creates a new key-exchange object from a private key. If |private_key|
- // is invalid, nullptr is returned.
- static std::unique_ptr<P256KeyExchange> New(absl::string_view private_key);
-
- // NewPrivateKey returns a private key, suitable for passing to |New|.
- // If |NewPrivateKey| can't generate a private key, it returns an empty
- // string.
- static std::string NewPrivateKey();
-
- // SynchronousKeyExchange interface.
- bool CalculateSharedKeySync(absl::string_view peer_public_value,
- std::string* shared_key) const override;
- absl::string_view public_value() const override;
- QuicTag type() const override { return kP256; }
-
- private:
- enum {
- // A P-256 field element consists of 32 bytes.
- kP256FieldBytes = 32,
- // A P-256 point in uncompressed form consists of 0x04 (to denote
- // that the point is uncompressed) followed by two, 32-byte field
- // elements.
- kUncompressedP256PointBytes = 1 + 2 * kP256FieldBytes,
- // The first byte in an uncompressed P-256 point.
- kUncompressedECPointForm = 0x04,
- };
-
- // P256KeyExchange wraps |private_key|, and expects |public_key| consists of
- // |kUncompressedP256PointBytes| bytes.
- P256KeyExchange(bssl::UniquePtr<EC_KEY> private_key,
- const uint8_t* public_key);
- P256KeyExchange(const P256KeyExchange&) = delete;
- P256KeyExchange& operator=(const P256KeyExchange&) = delete;
-
- bssl::UniquePtr<EC_KEY> private_key_;
- // The public key stored as an uncompressed P-256 point.
- uint8_t public_key_[kUncompressedP256PointBytes];
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_CRYPTO_P256_KEY_EXCHANGE_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/p256_key_exchange_test.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/p256_key_exchange_test.cc
deleted file mode 100644
index 4d183567f50..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/p256_key_exchange_test.cc
+++ /dev/null
@@ -1,109 +0,0 @@
-// Copyright (c) 2013 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 "quic/core/crypto/p256_key_exchange.h"
-
-#include <memory>
-#include <string>
-#include <utility>
-
-#include "absl/strings/string_view.h"
-#include "quic/platform/api/quic_test.h"
-
-namespace quic {
-namespace test {
-
-class P256KeyExchangeTest : public QuicTest {
- public:
- // Holds the result of a key exchange callback.
- class TestCallbackResult {
- public:
- void set_ok(bool ok) { ok_ = ok; }
- bool ok() { return ok_; }
-
- private:
- bool ok_ = false;
- };
-
- // Key exchange callback which sets the result into the specified
- // TestCallbackResult.
- class TestCallback : public AsynchronousKeyExchange::Callback {
- public:
- TestCallback(TestCallbackResult* result) : result_(result) {}
- virtual ~TestCallback() = default;
-
- void Run(bool ok) { result_->set_ok(ok); }
-
- private:
- TestCallbackResult* result_;
- };
-};
-
-// SharedKeyAsync just tests that the basic asynchronous key exchange identity
-// holds: that both parties end up with the same key.
-TEST_F(P256KeyExchangeTest, SharedKey) {
- for (int i = 0; i < 5; i++) {
- std::string alice_private(P256KeyExchange::NewPrivateKey());
- std::string bob_private(P256KeyExchange::NewPrivateKey());
-
- ASSERT_FALSE(alice_private.empty());
- ASSERT_FALSE(bob_private.empty());
- ASSERT_NE(alice_private, bob_private);
-
- std::unique_ptr<P256KeyExchange> alice(P256KeyExchange::New(alice_private));
- std::unique_ptr<P256KeyExchange> bob(P256KeyExchange::New(bob_private));
-
- ASSERT_TRUE(alice != nullptr);
- ASSERT_TRUE(bob != nullptr);
-
- const absl::string_view alice_public(alice->public_value());
- const absl::string_view bob_public(bob->public_value());
-
- std::string alice_shared, bob_shared;
- ASSERT_TRUE(alice->CalculateSharedKeySync(bob_public, &alice_shared));
- ASSERT_TRUE(bob->CalculateSharedKeySync(alice_public, &bob_shared));
- ASSERT_EQ(alice_shared, bob_shared);
- }
-}
-
-// SharedKey just tests that the basic key exchange identity holds: that both
-// parties end up with the same key.
-TEST_F(P256KeyExchangeTest, AsyncSharedKey) {
- for (int i = 0; i < 5; i++) {
- std::string alice_private(P256KeyExchange::NewPrivateKey());
- std::string bob_private(P256KeyExchange::NewPrivateKey());
-
- ASSERT_FALSE(alice_private.empty());
- ASSERT_FALSE(bob_private.empty());
- ASSERT_NE(alice_private, bob_private);
-
- std::unique_ptr<P256KeyExchange> alice(P256KeyExchange::New(alice_private));
- std::unique_ptr<P256KeyExchange> bob(P256KeyExchange::New(bob_private));
-
- ASSERT_TRUE(alice != nullptr);
- ASSERT_TRUE(bob != nullptr);
-
- const absl::string_view alice_public(alice->public_value());
- const absl::string_view bob_public(bob->public_value());
-
- std::string alice_shared, bob_shared;
- TestCallbackResult alice_result;
- ASSERT_FALSE(alice_result.ok());
- alice->CalculateSharedKeyAsync(
- bob_public, &alice_shared,
- std::make_unique<TestCallback>(&alice_result));
- ASSERT_TRUE(alice_result.ok());
- TestCallbackResult bob_result;
- ASSERT_FALSE(bob_result.ok());
- bob->CalculateSharedKeyAsync(alice_public, &bob_shared,
- std::make_unique<TestCallback>(&bob_result));
- ASSERT_TRUE(bob_result.ok());
- ASSERT_EQ(alice_shared, bob_shared);
- ASSERT_NE(0u, alice_shared.length());
- ASSERT_NE(0u, bob_shared.length());
- }
-}
-
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/proof_source.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/proof_source.cc
deleted file mode 100644
index 9cb85c2d3f7..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/proof_source.cc
+++ /dev/null
@@ -1,59 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/crypto/proof_source.h"
-
-#include <string>
-
-#include "quic/platform/api/quic_bug_tracker.h"
-
-namespace quic {
-
-CryptoBuffers::~CryptoBuffers() {
- for (size_t i = 0; i < value.size(); i++) {
- CRYPTO_BUFFER_free(value[i]);
- }
-}
-
-ProofSource::Chain::Chain(const std::vector<std::string>& certs)
- : certs(certs) {}
-
-ProofSource::Chain::~Chain() {}
-
-CryptoBuffers ProofSource::Chain::ToCryptoBuffers() const {
- CryptoBuffers crypto_buffers;
- crypto_buffers.value.reserve(certs.size());
- for (size_t i = 0; i < certs.size(); i++) {
- crypto_buffers.value.push_back(
- CRYPTO_BUFFER_new(reinterpret_cast<const uint8_t*>(certs[i].data()),
- certs[i].length(), nullptr));
- }
- return crypto_buffers;
-}
-
-bool ValidateCertAndKey(
- const QuicReferenceCountedPointer<ProofSource::Chain>& chain,
- const CertificatePrivateKey& key) {
- if (chain.get() == nullptr || chain->certs.empty()) {
- QUIC_BUG(quic_proof_source_empty_chain) << "Certificate chain is empty";
- return false;
- }
-
- std::unique_ptr<CertificateView> leaf =
- CertificateView::ParseSingleCertificate(chain->certs[0]);
- if (leaf == nullptr) {
- QUIC_BUG(quic_proof_source_unparsable_leaf_cert)
- << "Unabled to parse leaf certificate";
- return false;
- }
-
- if (!key.MatchesPublicKey(*leaf)) {
- QUIC_BUG(quic_proof_source_key_mismatch)
- << "Private key does not match the leaf certificate";
- return false;
- }
- return true;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/proof_source.h b/chromium/net/third_party/quiche/src/quic/core/crypto/proof_source.h
deleted file mode 100644
index 2eb755a9213..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/proof_source.h
+++ /dev/null
@@ -1,355 +0,0 @@
-// Copyright (c) 2013 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_CRYPTO_PROOF_SOURCE_H_
-#define QUICHE_QUIC_CORE_CRYPTO_PROOF_SOURCE_H_
-
-#include <memory>
-#include <string>
-#include <vector>
-
-#include "absl/strings/string_view.h"
-#include "third_party/boringssl/src/include/openssl/ssl.h"
-#include "quic/core/crypto/certificate_view.h"
-#include "quic/core/crypto/quic_crypto_proof.h"
-#include "quic/core/quic_versions.h"
-#include "quic/platform/api/quic_export.h"
-#include "quic/platform/api/quic_reference_counted.h"
-#include "quic/platform/api/quic_socket_address.h"
-
-namespace quic {
-
-namespace test {
-class FakeProofSourceHandle;
-} // namespace test
-
-// CryptoBuffers is a RAII class to own a std::vector<CRYPTO_BUFFER*> and the
-// buffers the elements point to.
-struct QUIC_EXPORT_PRIVATE CryptoBuffers {
- CryptoBuffers() = default;
- CryptoBuffers(const CryptoBuffers&) = delete;
- CryptoBuffers(CryptoBuffers&&) = default;
- ~CryptoBuffers();
-
- std::vector<CRYPTO_BUFFER*> value;
-};
-
-// ProofSource is an interface by which a QUIC server can obtain certificate
-// chains and signatures that prove its identity.
-class QUIC_EXPORT_PRIVATE ProofSource {
- public:
- // Chain is a reference-counted wrapper for a vector of stringified
- // certificates.
- struct QUIC_EXPORT_PRIVATE Chain : public QuicReferenceCounted {
- explicit Chain(const std::vector<std::string>& certs);
- Chain(const Chain&) = delete;
- Chain& operator=(const Chain&) = delete;
-
- CryptoBuffers ToCryptoBuffers() const;
-
- const std::vector<std::string> certs;
-
- protected:
- ~Chain() override;
- };
-
- // Details is an abstract class which acts as a container for any
- // implementation-specific details that a ProofSource wants to return.
- class QUIC_EXPORT_PRIVATE Details {
- public:
- virtual ~Details() {}
- };
-
- // Callback base class for receiving the results of an async call to GetProof.
- class QUIC_EXPORT_PRIVATE Callback {
- public:
- Callback() {}
- virtual ~Callback() {}
-
- // Invoked upon completion of GetProof.
- //
- // |ok| indicates whether the operation completed successfully. If false,
- // the values of the remaining three arguments are undefined.
- //
- // |chain| is a reference-counted pointer to an object representing the
- // certificate chain.
- //
- // |signature| contains the signature of the server config.
- //
- // |leaf_cert_sct| holds the signed timestamp (RFC6962) of the leaf cert.
- //
- // |details| holds a pointer to an object representing the statistics, if
- // any, gathered during the operation of GetProof. If no stats are
- // available, this will be nullptr.
- virtual void Run(bool ok,
- const QuicReferenceCountedPointer<Chain>& chain,
- const QuicCryptoProof& proof,
- std::unique_ptr<Details> details) = 0;
-
- private:
- Callback(const Callback&) = delete;
- Callback& operator=(const Callback&) = delete;
- };
-
- // Base class for signalling the completion of a call to ComputeTlsSignature.
- class QUIC_EXPORT_PRIVATE SignatureCallback {
- public:
- SignatureCallback() {}
- virtual ~SignatureCallback() = default;
-
- // Invoked upon completion of ComputeTlsSignature.
- //
- // |ok| indicates whether the operation completed successfully.
- //
- // |signature| contains the signature of the data provided to
- // ComputeTlsSignature. Its value is undefined if |ok| is false.
- //
- // |details| holds a pointer to an object representing the statistics, if
- // any, gathered during the operation of ComputeTlsSignature. If no stats
- // are available, this will be nullptr.
- virtual void Run(bool ok,
- std::string signature,
- std::unique_ptr<Details> details) = 0;
-
- private:
- SignatureCallback(const SignatureCallback&) = delete;
- SignatureCallback& operator=(const SignatureCallback&) = delete;
- };
-
- virtual ~ProofSource() {}
-
- // GetProof finds a certificate chain for |hostname| (in leaf-first order),
- // and calculates a signature of |server_config| using that chain.
- //
- // The signature uses SHA-256 as the hash function and PSS padding when the
- // key is RSA.
- //
- // The signature uses SHA-256 as the hash function when the key is ECDSA.
- // The signature may use an ECDSA key.
- //
- // The signature depends on |chlo_hash| which means that the signature can not
- // be cached.
- //
- // |hostname| may be empty to signify that a default certificate should be
- // used.
- //
- // This function may be called concurrently.
- //
- // Callers should expect that |callback| might be invoked synchronously.
- virtual void GetProof(const QuicSocketAddress& server_address,
- const QuicSocketAddress& client_address,
- const std::string& hostname,
- const std::string& server_config,
- QuicTransportVersion transport_version,
- absl::string_view chlo_hash,
- std::unique_ptr<Callback> callback) = 0;
-
- // Returns the certificate chain for |hostname| in leaf-first order.
- //
- // Sets *cert_matched_sni to true if the certificate matched the given
- // hostname, false if a default cert not matching the hostname was used.
- virtual QuicReferenceCountedPointer<Chain> GetCertChain(
- const QuicSocketAddress& server_address,
- const QuicSocketAddress& client_address, const std::string& hostname,
- bool* cert_matched_sni) = 0;
-
- // Computes a signature using the private key of the certificate for
- // |hostname|. The value in |in| is signed using the algorithm specified by
- // |signature_algorithm|, which is an |SSL_SIGN_*| value (as defined in TLS
- // 1.3). Implementations can only assume that |in| is valid during the call to
- // ComputeTlsSignature - an implementation computing signatures asynchronously
- // must copy it if the value to be signed is used outside of this function.
- //
- // Callers should expect that |callback| might be invoked synchronously.
- virtual void ComputeTlsSignature(
- const QuicSocketAddress& server_address,
- const QuicSocketAddress& client_address,
- const std::string& hostname,
- uint16_t signature_algorithm,
- absl::string_view in,
- std::unique_ptr<SignatureCallback> callback) = 0;
-
- // Return the list of TLS signature algorithms that is acceptable by the
- // ComputeTlsSignature method. If the entire BoringSSL's default list of
- // supported signature algorithms are acceptable, return an empty list.
- //
- // If returns a non-empty list, ComputeTlsSignature will only be called with a
- // algorithm in the list.
- virtual absl::InlinedVector<uint16_t, 8> SupportedTlsSignatureAlgorithms()
- const = 0;
-
- class QUIC_EXPORT_PRIVATE DecryptCallback {
- public:
- DecryptCallback() = default;
- virtual ~DecryptCallback() = default;
-
- virtual void Run(std::vector<uint8_t> plaintext) = 0;
-
- private:
- DecryptCallback(const Callback&) = delete;
- DecryptCallback& operator=(const Callback&) = delete;
- };
-
- // TicketCrypter is an interface for managing encryption and decryption of TLS
- // session tickets. A TicketCrypter gets used as an
- // SSL_CTX_set_ticket_aead_method in BoringSSL, which has a synchronous
- // Encrypt/Seal operation and a potentially asynchronous Decrypt/Open
- // operation. This interface allows for ticket decryptions to be performed on
- // a remote service.
- class QUIC_EXPORT_PRIVATE TicketCrypter {
- public:
- TicketCrypter() = default;
- virtual ~TicketCrypter() = default;
-
- // MaxOverhead returns the maximum number of bytes of overhead that may get
- // added when encrypting the ticket.
- virtual size_t MaxOverhead() = 0;
-
- // Encrypt takes a serialized TLS session ticket in |in|, encrypts it, and
- // returns the encrypted ticket. The resulting value must not be larger than
- // MaxOverhead bytes larger than |in|. If encryption fails, this method
- // returns an empty vector.
- //
- // If |encryption_key| is nonempty, this method should use it for minting
- // TLS resumption tickets. If it is empty, this method may use an
- // internally cached encryption key, if available.
- virtual std::vector<uint8_t> Encrypt(absl::string_view in,
- absl::string_view encryption_key) = 0;
-
- // Decrypt takes an encrypted ticket |in|, decrypts it, and calls
- // |callback->Run| with the decrypted ticket, which must not be larger than
- // |in|. If decryption fails, the callback is invoked with an empty
- // vector.
- virtual void Decrypt(absl::string_view in,
- std::unique_ptr<DecryptCallback> callback) = 0;
- };
-
- // Returns the TicketCrypter used for encrypting and decrypting TLS
- // session tickets, or nullptr if that functionality is not supported. The
- // TicketCrypter returned (if not nullptr) must be valid for the lifetime of
- // the ProofSource, and the caller does not take ownership of said
- // TicketCrypter.
- virtual TicketCrypter* GetTicketCrypter() = 0;
-};
-
-// ProofSourceHandleCallback is an interface that contains the callbacks when
-// the operations in ProofSourceHandle completes.
-// TODO(wub): Consider deprecating ProofSource by moving all functionalities of
-// ProofSource into ProofSourceHandle.
-class QUIC_EXPORT_PRIVATE ProofSourceHandleCallback {
- public:
- virtual ~ProofSourceHandleCallback() = default;
-
- // Called when a ProofSourceHandle::SelectCertificate operation completes.
- // |ok| indicates whether the operation was successful.
- // |is_sync| indicates whether the operation completed synchronously, i.e.
- // whether it is completed before ProofSourceHandle::SelectCertificate
- // returned.
- // |chain| the certificate chain in leaf-first order.
- // |handshake_hints| (optional) handshake hints that can be used by
- // SSL_set_handshake_hints.
- // |ticket_encryption_key| (optional) encryption key to be used for minting
- // TLS resumption tickets.
- // |cert_matched_sni| is true if the certificate matched the SNI hostname,
- // false if a non-matching default cert was used.
- // |delayed_ssl_config| contains SSL configs to be applied on the SSL object.
- //
- // When called asynchronously(is_sync=false), this method will be responsible
- // to continue the handshake from where it left off.
- virtual void OnSelectCertificateDone(
- bool ok, bool is_sync, const ProofSource::Chain* chain,
- absl::string_view handshake_hints,
- absl::string_view ticket_encryption_key, bool cert_matched_sni,
- QuicDelayedSSLConfig delayed_ssl_config) = 0;
-
- // Called when a ProofSourceHandle::ComputeSignature operation completes.
- virtual void OnComputeSignatureDone(
- bool ok,
- bool is_sync,
- std::string signature,
- std::unique_ptr<ProofSource::Details> details) = 0;
-
- // Return true iff ProofSourceHandle::ComputeSignature won't be called later.
- // The handle can use this function to release resources promptly.
- virtual bool WillNotCallComputeSignature() const = 0;
-};
-
-// ProofSourceHandle is an interface by which a TlsServerHandshaker can obtain
-// certificate chains and signatures that prove its identity.
-// The operations this interface supports are similar to those in ProofSource,
-// the main difference is that ProofSourceHandle is per-handshaker, so
-// an implementation can have states that are shared by multiple calls on the
-// same handle.
-//
-// A handle object is owned by a TlsServerHandshaker. Since there might be an
-// async operation pending when the handle destructs, an implementation must
-// ensure when such operations finish, their corresponding callback method won't
-// be invoked.
-//
-// A handle will have at most one async operation pending at a time.
-class QUIC_EXPORT_PRIVATE ProofSourceHandle {
- public:
- virtual ~ProofSourceHandle() = default;
-
- // Close the handle. Cancel the pending operation, if any.
- // Once called, any completion method on |callback()| won't be invoked, and
- // future SelectCertificate and ComputeSignature calls should return failure.
- virtual void CloseHandle() = 0;
-
- // Starts a select certificate operation. If the operation is not cancelled
- // when it completes, callback()->OnSelectCertificateDone will be invoked.
- //
- // server_address and client_address should be normalized by the caller before
- // sending down to this function.
- //
- // If the operation is handled synchronously:
- // - QUIC_SUCCESS or QUIC_FAILURE will be returned.
- // - callback()->OnSelectCertificateDone should be invoked before the function
- // returns.
- //
- // If the operation is handled asynchronously:
- // - QUIC_PENDING will be returned.
- // - When the operation is done, callback()->OnSelectCertificateDone should be
- // invoked.
- virtual QuicAsyncStatus SelectCertificate(
- const QuicSocketAddress& server_address,
- const QuicSocketAddress& client_address,
- absl::string_view ssl_capabilities,
- const std::string& hostname,
- absl::string_view client_hello,
- const std::string& alpn,
- absl::optional<std::string> alps,
- const std::vector<uint8_t>& quic_transport_params,
- const absl::optional<std::vector<uint8_t>>& early_data_context,
- const QuicSSLConfig& ssl_config) = 0;
-
- // Starts a compute signature operation. If the operation is not cancelled
- // when it completes, callback()->OnComputeSignatureDone will be invoked.
- //
- // See the comments of SelectCertificate for sync vs. async operations.
- virtual QuicAsyncStatus ComputeSignature(
- const QuicSocketAddress& server_address,
- const QuicSocketAddress& client_address,
- const std::string& hostname,
- uint16_t signature_algorithm,
- absl::string_view in,
- size_t max_signature_size) = 0;
-
- protected:
- // Returns the object that will be notified when an operation completes.
- virtual ProofSourceHandleCallback* callback() = 0;
-
- private:
- friend class test::FakeProofSourceHandle;
-};
-
-// Returns true if |chain| contains a parsable DER-encoded X.509 leaf cert and
-// it matches with |key|.
-QUIC_EXPORT_PRIVATE bool ValidateCertAndKey(
- const QuicReferenceCountedPointer<ProofSource::Chain>& chain,
- const CertificatePrivateKey& key);
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_CRYPTO_PROOF_SOURCE_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/proof_source_x509.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/proof_source_x509.cc
deleted file mode 100644
index 986ee32ae05..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/proof_source_x509.cc
+++ /dev/null
@@ -1,148 +0,0 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/crypto/proof_source_x509.h"
-
-#include <memory>
-
-#include "absl/strings/str_cat.h"
-#include "absl/strings/string_view.h"
-#include "third_party/boringssl/src/include/openssl/ssl.h"
-#include "quic/core/crypto/certificate_view.h"
-#include "quic/core/crypto/crypto_protocol.h"
-#include "quic/core/quic_data_writer.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "common/quiche_endian.h"
-
-namespace quic {
-
-std::unique_ptr<ProofSourceX509> ProofSourceX509::Create(
- QuicReferenceCountedPointer<Chain> default_chain,
- CertificatePrivateKey default_key) {
- std::unique_ptr<ProofSourceX509> result(new ProofSourceX509());
- if (!result->AddCertificateChain(default_chain, std::move(default_key))) {
- return nullptr;
- }
- result->default_certificate_ = &result->certificates_.front();
- return result;
-}
-
-void ProofSourceX509::GetProof(
- const QuicSocketAddress& /*server_address*/,
- const QuicSocketAddress& /*client_address*/,
- const std::string& hostname,
- const std::string& server_config,
- QuicTransportVersion /*transport_version*/,
- absl::string_view chlo_hash,
- 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) {
- 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);
- callback->Run(/*ok=*/!proof.signature.empty(), certificate->chain, proof,
- nullptr);
-}
-
-QuicReferenceCountedPointer<ProofSource::Chain> ProofSourceX509::GetCertChain(
- const QuicSocketAddress& /*server_address*/,
- const QuicSocketAddress& /*client_address*/, const std::string& hostname,
- bool* cert_matched_sni) {
- return GetCertificate(hostname, cert_matched_sni)->chain;
-}
-
-void ProofSourceX509::ComputeTlsSignature(
- const QuicSocketAddress& /*server_address*/,
- const QuicSocketAddress& /*client_address*/,
- const std::string& hostname,
- uint16_t signature_algorithm,
- absl::string_view in,
- std::unique_ptr<ProofSource::SignatureCallback> callback) {
- 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 {};
-}
-
-ProofSource::TicketCrypter* ProofSourceX509::GetTicketCrypter() {
- return nullptr;
-}
-
-bool ProofSourceX509::AddCertificateChain(
- QuicReferenceCountedPointer<Chain> chain,
- CertificatePrivateKey key) {
- if (chain->certs.empty()) {
- QUIC_BUG(quic_bug_10644_1) << "Empty certificate chain supplied.";
- return false;
- }
-
- std::unique_ptr<CertificateView> leaf =
- CertificateView::ParseSingleCertificate(chain->certs[0]);
- if (leaf == nullptr) {
- QUIC_BUG(quic_bug_10644_2)
- << "Unable to parse X.509 leaf certificate in the supplied chain.";
- return false;
- }
- if (!key.MatchesPublicKey(*leaf)) {
- QUIC_BUG(quic_bug_10644_3)
- << "Private key does not match the leaf certificate.";
- return false;
- }
-
- certificates_.push_front(Certificate{
- chain,
- std::move(key),
- });
- Certificate* certificate = &certificates_.front();
-
- for (absl::string_view host : leaf->subject_alt_name_domains()) {
- certificate_map_[std::string(host)] = certificate;
- }
- return true;
-}
-
-ProofSourceX509::Certificate* ProofSourceX509::GetCertificate(
- const std::string& hostname, bool* cert_matched_sni) const {
- auto it = certificate_map_.find(hostname);
- if (it != certificate_map_.end()) {
- *cert_matched_sni = true;
- return it->second;
- }
- auto dot_pos = hostname.find('.');
- if (dot_pos != std::string::npos) {
- std::string wildcard = absl::StrCat("*", hostname.substr(dot_pos));
- it = certificate_map_.find(wildcard);
- if (it != certificate_map_.end()) {
- *cert_matched_sni = true;
- return it->second;
- }
- }
- *cert_matched_sni = false;
- return default_certificate_;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/proof_source_x509.h b/chromium/net/third_party/quiche/src/quic/core/crypto/proof_source_x509.h
deleted file mode 100644
index 4b7ae51c83b..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/proof_source_x509.h
+++ /dev/null
@@ -1,78 +0,0 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_CRYPTO_PROOF_SOURCE_X509_H_
-#define QUICHE_QUIC_CORE_CRYPTO_PROOF_SOURCE_X509_H_
-
-#include <forward_list>
-#include <memory>
-
-#include "absl/base/attributes.h"
-#include "absl/container/node_hash_map.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/crypto/certificate_view.h"
-#include "quic/core/crypto/proof_source.h"
-#include "quic/platform/api/quic_containers.h"
-
-namespace quic {
-
-// ProofSourceX509 accepts X.509 certificates with private keys and picks a
-// certificate internally based on its SubjectAltName value.
-class QUIC_EXPORT_PRIVATE ProofSourceX509 : public ProofSource {
- public:
- // Creates a proof source that uses |default_chain| when no SubjectAltName
- // value matches. Returns nullptr if |default_chain| is invalid.
- static std::unique_ptr<ProofSourceX509> Create(
- QuicReferenceCountedPointer<Chain> default_chain,
- CertificatePrivateKey default_key);
-
- // ProofSource implementation.
- void GetProof(const QuicSocketAddress& server_address,
- const QuicSocketAddress& client_address,
- const std::string& hostname,
- const std::string& server_config,
- QuicTransportVersion transport_version,
- absl::string_view chlo_hash,
- std::unique_ptr<Callback> callback) override;
- QuicReferenceCountedPointer<Chain> GetCertChain(
- const QuicSocketAddress& server_address,
- const QuicSocketAddress& client_address, const std::string& hostname,
- bool* cert_matched_sni) override;
- void ComputeTlsSignature(
- const QuicSocketAddress& server_address,
- 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;
- TicketCrypter* GetTicketCrypter() override;
-
- // Adds a certificate chain to the verifier. Returns false if the chain is
- // not valid. Newer certificates will override older certificates with the
- // same SubjectAltName value.
- ABSL_MUST_USE_RESULT bool AddCertificateChain(
- QuicReferenceCountedPointer<Chain> chain,
- CertificatePrivateKey key);
-
- private:
- ProofSourceX509() = default;
-
- struct QUIC_EXPORT_PRIVATE Certificate {
- QuicReferenceCountedPointer<Chain> chain;
- CertificatePrivateKey key;
- };
-
- // Looks up certficiate for hostname, returns the default if no certificate is
- // found.
- Certificate* GetCertificate(const std::string& hostname,
- bool* cert_matched_sni) const;
-
- std::forward_list<Certificate> certificates_;
- Certificate* default_certificate_;
- absl::node_hash_map<std::string, Certificate*> certificate_map_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_CRYPTO_PROOF_SOURCE_X509_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/proof_source_x509_test.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/proof_source_x509_test.cc
deleted file mode 100644
index 1a9462f7dc3..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/proof_source_x509_test.cc
+++ /dev/null
@@ -1,142 +0,0 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/crypto/proof_source_x509.h"
-
-#include <memory>
-
-#include "absl/strings/string_view.h"
-#include "third_party/boringssl/src/include/openssl/ssl.h"
-#include "quic/core/crypto/certificate_view.h"
-#include "quic/core/crypto/proof_source.h"
-#include "quic/platform/api/quic_expect_bug.h"
-#include "quic/platform/api/quic_ip_address.h"
-#include "quic/platform/api/quic_reference_counted.h"
-#include "quic/platform/api/quic_socket_address.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/test_certificates.h"
-
-namespace quic {
-namespace test {
-namespace {
-
-QuicReferenceCountedPointer<ProofSource::Chain> MakeChain(
- absl::string_view cert) {
- return QuicReferenceCountedPointer<ProofSource::Chain>(
- new ProofSource::Chain(std::vector<std::string>{std::string(cert)}));
-}
-
-class ProofSourceX509Test : public QuicTest {
- public:
- ProofSourceX509Test()
- : test_chain_(MakeChain(kTestCertificate)),
- wildcard_chain_(MakeChain(kWildcardCertificate)),
- test_key_(
- CertificatePrivateKey::LoadFromDer(kTestCertificatePrivateKey)),
- wildcard_key_(CertificatePrivateKey::LoadFromDer(
- kWildcardCertificatePrivateKey)) {
- QUICHE_CHECK(test_key_ != nullptr);
- QUICHE_CHECK(wildcard_key_ != nullptr);
- }
-
- protected:
- QuicReferenceCountedPointer<ProofSource::Chain> test_chain_, wildcard_chain_;
- std::unique_ptr<CertificatePrivateKey> test_key_, wildcard_key_;
-};
-
-TEST_F(ProofSourceX509Test, AddCertificates) {
- std::unique_ptr<ProofSourceX509> proof_source =
- ProofSourceX509::Create(test_chain_, std::move(*test_key_));
- ASSERT_TRUE(proof_source != nullptr);
- EXPECT_TRUE(proof_source->AddCertificateChain(wildcard_chain_,
- std::move(*wildcard_key_)));
-}
-
-TEST_F(ProofSourceX509Test, AddCertificateKeyMismatch) {
- std::unique_ptr<ProofSourceX509> proof_source =
- ProofSourceX509::Create(test_chain_, std::move(*test_key_));
- ASSERT_TRUE(proof_source != nullptr);
- test_key_ = CertificatePrivateKey::LoadFromDer(kTestCertificatePrivateKey);
- EXPECT_QUIC_BUG((void)proof_source->AddCertificateChain(
- wildcard_chain_, std::move(*test_key_)),
- "Private key does not match");
-}
-
-TEST_F(ProofSourceX509Test, CertificateSelection) {
- std::unique_ptr<ProofSourceX509> proof_source =
- ProofSourceX509::Create(test_chain_, std::move(*test_key_));
- ASSERT_TRUE(proof_source != nullptr);
- ASSERT_TRUE(proof_source->AddCertificateChain(wildcard_chain_,
- std::move(*wildcard_key_)));
-
- // Default certificate.
- bool cert_matched_sni;
- EXPECT_EQ(proof_source
- ->GetCertChain(QuicSocketAddress(), QuicSocketAddress(),
- "unknown.test", &cert_matched_sni)
- ->certs[0],
- kTestCertificate);
- EXPECT_FALSE(cert_matched_sni);
- // mail.example.org is explicitly a SubjectAltName in kTestCertificate.
- EXPECT_EQ(proof_source
- ->GetCertChain(QuicSocketAddress(), QuicSocketAddress(),
- "mail.example.org", &cert_matched_sni)
- ->certs[0],
- kTestCertificate);
- EXPECT_TRUE(cert_matched_sni);
- // www.foo.test is in kWildcardCertificate.
- EXPECT_EQ(proof_source
- ->GetCertChain(QuicSocketAddress(), QuicSocketAddress(),
- "www.foo.test", &cert_matched_sni)
- ->certs[0],
- kWildcardCertificate);
- EXPECT_TRUE(cert_matched_sni);
- // *.wildcard.test is in kWildcardCertificate.
- EXPECT_EQ(proof_source
- ->GetCertChain(QuicSocketAddress(), QuicSocketAddress(),
- "www.wildcard.test", &cert_matched_sni)
- ->certs[0],
- kWildcardCertificate);
- EXPECT_TRUE(cert_matched_sni);
- EXPECT_EQ(proof_source
- ->GetCertChain(QuicSocketAddress(), QuicSocketAddress(),
- "etc.wildcard.test", &cert_matched_sni)
- ->certs[0],
- kWildcardCertificate);
- EXPECT_TRUE(cert_matched_sni);
- // wildcard.test itself is not in kWildcardCertificate.
- EXPECT_EQ(proof_source
- ->GetCertChain(QuicSocketAddress(), QuicSocketAddress(),
- "wildcard.test", &cert_matched_sni)
- ->certs[0],
- kTestCertificate);
- EXPECT_FALSE(cert_matched_sni);
-}
-
-TEST_F(ProofSourceX509Test, TlsSignature) {
- class Callback : public ProofSource::SignatureCallback {
- public:
- void Run(bool ok,
- std::string signature,
- std::unique_ptr<ProofSource::Details> /*details*/) override {
- ASSERT_TRUE(ok);
- std::unique_ptr<CertificateView> view =
- CertificateView::ParseSingleCertificate(kTestCertificate);
- EXPECT_TRUE(view->VerifySignature("Test data", signature,
- SSL_SIGN_RSA_PSS_RSAE_SHA256));
- }
- };
-
- std::unique_ptr<ProofSourceX509> proof_source =
- ProofSourceX509::Create(test_chain_, std::move(*test_key_));
- ASSERT_TRUE(proof_source != nullptr);
-
- proof_source->ComputeTlsSignature(QuicSocketAddress(), QuicSocketAddress(),
- "example.com", SSL_SIGN_RSA_PSS_RSAE_SHA256,
- "Test data", std::make_unique<Callback>());
-}
-
-} // namespace
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/proof_verifier.h b/chromium/net/third_party/quiche/src/quic/core/crypto/proof_verifier.h
deleted file mode 100644
index a487fa5beb9..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/proof_verifier.h
+++ /dev/null
@@ -1,128 +0,0 @@
-// Copyright (c) 2013 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_CRYPTO_PROOF_VERIFIER_H_
-#define QUICHE_QUIC_CORE_CRYPTO_PROOF_VERIFIER_H_
-
-#include <memory>
-#include <string>
-#include <vector>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_versions.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// ProofVerifyDetails is an abstract class that acts as a container for any
-// implementation specific details that a ProofVerifier wishes to return. These
-// details are saved in the CachedState for the origin in question.
-class QUIC_EXPORT_PRIVATE ProofVerifyDetails {
- public:
- virtual ~ProofVerifyDetails() {}
-
- // Returns an new ProofVerifyDetails object with the same contents
- // as this one.
- virtual ProofVerifyDetails* Clone() const = 0;
-};
-
-// ProofVerifyContext is an abstract class that acts as a container for any
-// implementation specific context that a ProofVerifier needs.
-class QUIC_EXPORT_PRIVATE ProofVerifyContext {
- public:
- virtual ~ProofVerifyContext() {}
-};
-
-// ProofVerifierCallback provides a generic mechanism for a ProofVerifier to
-// call back after an asynchronous verification.
-class QUIC_EXPORT_PRIVATE ProofVerifierCallback {
- public:
- virtual ~ProofVerifierCallback() {}
-
- // Run is called on the original thread to mark the completion of an
- // asynchonous verification. If |ok| is true then the certificate is valid
- // and |error_details| is unused. Otherwise, |error_details| contains a
- // description of the error. |details| contains implementation-specific
- // details of the verification. |Run| may take ownership of |details| by
- // calling |release| on it.
- virtual void Run(bool ok,
- const std::string& error_details,
- std::unique_ptr<ProofVerifyDetails>* details) = 0;
-};
-
-// A ProofVerifier checks the signature on a server config, and the certificate
-// chain that backs the public key.
-class QUIC_EXPORT_PRIVATE ProofVerifier {
- public:
- virtual ~ProofVerifier() {}
-
- // VerifyProof checks that |signature| is a valid signature of
- // |server_config| by the public key in the leaf certificate of |certs|, and
- // that |certs| is a valid chain for |hostname|. On success, it returns
- // QUIC_SUCCESS. On failure, it returns QUIC_FAILURE and sets |*error_details|
- // to a description of the problem. In either case it may set |*details|,
- // which the caller takes ownership of.
- //
- // |context| specifies an implementation specific struct (which may be nullptr
- // for some implementations) that provides useful information for the
- // verifier, e.g. logging handles.
- //
- // This function may also return QUIC_PENDING, in which case the ProofVerifier
- // will call back, on the original thread, via |callback| when complete.
- //
- // The signature uses SHA-256 as the hash function and PSS padding in the
- // case of RSA.
- virtual 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) = 0;
-
- // VerifyCertChain checks that |certs| is a valid chain for |hostname|. On
- // success, it returns QUIC_SUCCESS. On failure, it returns QUIC_FAILURE and
- // sets |*error_details| to a description of the problem. In either case it
- // may set |*details|, which the caller takes ownership of.
- //
- // |context| specifies an implementation specific struct (which may be nullptr
- // for some implementations) that provides useful information for the
- // verifier, e.g. logging handles.
- //
- // If certificate verification fails, a TLS alert will be sent when closing
- // the connection. This alert defaults to certificate_unknown. By setting
- // |*out_alert|, a different alert can be sent to provide a more specific
- // reason why verification failed.
- //
- // This function may also return QUIC_PENDING, in which case the ProofVerifier
- // will call back, on the original thread, via |callback| when complete.
- // In this case, the ProofVerifier will take ownership of |callback|.
- virtual 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) = 0;
-
- // Returns a ProofVerifyContext instance which can be use for subsequent
- // verifications. Applications may chose create a different context and
- // supply it for verifications instead.
- virtual std::unique_ptr<ProofVerifyContext> CreateDefaultContext() = 0;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_CRYPTO_PROOF_VERIFIER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/quic_client_session_cache.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/quic_client_session_cache.cc
deleted file mode 100644
index 5ce935d5066..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/quic_client_session_cache.cc
+++ /dev/null
@@ -1,174 +0,0 @@
-// Copyright (c) 2021 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 "quic/core/crypto/quic_client_session_cache.h"
-
-#include "quic/core/quic_clock.h"
-
-namespace quic {
-
-namespace {
-
-const size_t kDefaultMaxEntries = 1024;
-// Returns false if the SSL |session| doesn't exist or it is expired at |now|.
-bool IsValid(SSL_SESSION* session, uint64_t now) {
- if (!session) return false;
-
- // now_u64 may be slightly behind because of differences in how
- // time is calculated at this layer versus BoringSSL.
- // Add a second of wiggle room to account for this.
- return !(now + 1 < SSL_SESSION_get_time(session) ||
- now >= SSL_SESSION_get_time(session) +
- SSL_SESSION_get_timeout(session));
-}
-
-bool DoApplicationStatesMatch(const ApplicationState* state,
- ApplicationState* other) {
- if ((state && !other) || (!state && other)) return false;
- if ((!state && !other) || *state == *other) return true;
- return false;
-}
-
-} // namespace
-
-QuicClientSessionCache::QuicClientSessionCache()
- : QuicClientSessionCache(kDefaultMaxEntries) {}
-
-QuicClientSessionCache::QuicClientSessionCache(size_t max_entries)
- : cache_(max_entries) {}
-
-QuicClientSessionCache::~QuicClientSessionCache() { Clear(); }
-
-void QuicClientSessionCache::Insert(const QuicServerId& server_id,
- bssl::UniquePtr<SSL_SESSION> session,
- const TransportParameters& params,
- const ApplicationState* application_state) {
- QUICHE_DCHECK(session) << "TLS session is not inserted into client cache.";
- auto iter = cache_.Lookup(server_id);
- if (iter == cache_.end()) {
- CreateAndInsertEntry(server_id, std::move(session), params,
- application_state);
- return;
- }
-
- QUICHE_DCHECK(iter->second->params);
- // The states are both the same, so only need to insert sessions.
- if (params == *iter->second->params &&
- DoApplicationStatesMatch(application_state,
- iter->second->application_state.get())) {
- iter->second->PushSession(std::move(session));
- return;
- }
- // Erase the existing entry because this Insert call must come from a
- // different QUIC session.
- cache_.Erase(iter);
- CreateAndInsertEntry(server_id, std::move(session), params,
- application_state);
-}
-
-std::unique_ptr<QuicResumptionState> QuicClientSessionCache::Lookup(
- const QuicServerId& server_id, QuicWallTime now, const SSL_CTX* /*ctx*/) {
- auto iter = cache_.Lookup(server_id);
- if (iter == cache_.end()) return nullptr;
-
- if (!IsValid(iter->second->PeekSession(), now.ToUNIXSeconds())) {
- QUIC_DLOG(INFO) << "TLS Session expired for host:" << server_id.host();
- cache_.Erase(iter);
- return nullptr;
- }
- auto state = std::make_unique<QuicResumptionState>();
- state->tls_session = iter->second->PopSession();
- if (iter->second->params != nullptr) {
- state->transport_params =
- std::make_unique<TransportParameters>(*iter->second->params);
- }
- if (iter->second->application_state != nullptr) {
- state->application_state =
- std::make_unique<ApplicationState>(*iter->second->application_state);
- }
- if (GetQuicReloadableFlag(quic_tls_use_token_in_session_cache) &&
- !iter->second->token.empty()) {
- state->token = iter->second->token;
- // Clear token after use.
- iter->second->token.clear();
- }
-
- return state;
-}
-
-void QuicClientSessionCache::ClearEarlyData(const QuicServerId& server_id) {
- auto iter = cache_.Lookup(server_id);
- if (iter == cache_.end()) return;
- for (auto& session : iter->second->sessions) {
- if (session) {
- QUIC_DLOG(INFO) << "Clear early data for for host: " << server_id.host();
- session.reset(SSL_SESSION_copy_without_early_data(session.get()));
- }
- }
-}
-
-void QuicClientSessionCache::OnNewTokenReceived(const QuicServerId& server_id,
- absl::string_view token) {
- if (token.empty()) {
- return;
- }
- auto iter = cache_.Lookup(server_id);
- if (iter == cache_.end()) {
- return;
- }
- iter->second->token = std::string(token);
-}
-
-void QuicClientSessionCache::RemoveExpiredEntries(QuicWallTime now) {
- auto iter = cache_.begin();
- while (iter != cache_.end()) {
- if (!IsValid(iter->second->PeekSession(), now.ToUNIXSeconds())) {
- iter = cache_.Erase(iter);
- } else {
- ++iter;
- }
- }
-}
-
-void QuicClientSessionCache::Clear() { cache_.Clear(); }
-
-void QuicClientSessionCache::CreateAndInsertEntry(
- const QuicServerId& server_id, bssl::UniquePtr<SSL_SESSION> session,
- const TransportParameters& params,
- const ApplicationState* application_state) {
- auto entry = std::make_unique<Entry>();
- entry->PushSession(std::move(session));
- entry->params = std::make_unique<TransportParameters>(params);
- if (application_state) {
- entry->application_state =
- std::make_unique<ApplicationState>(*application_state);
- }
- cache_.Insert(server_id, std::move(entry));
-}
-
-QuicClientSessionCache::Entry::Entry() = default;
-QuicClientSessionCache::Entry::Entry(Entry&&) = default;
-QuicClientSessionCache::Entry::~Entry() = default;
-
-void QuicClientSessionCache::Entry::PushSession(
- bssl::UniquePtr<SSL_SESSION> session) {
- if (sessions[0] != nullptr) {
- sessions[1] = std::move(sessions[0]);
- }
- sessions[0] = std::move(session);
-}
-
-bssl::UniquePtr<SSL_SESSION> QuicClientSessionCache::Entry::PopSession() {
- if (sessions[0] == nullptr) return nullptr;
- bssl::UniquePtr<SSL_SESSION> session = std::move(sessions[0]);
- sessions[0] = std::move(sessions[1]);
- sessions[1] = nullptr;
- return session;
-}
-
-SSL_SESSION* QuicClientSessionCache::Entry::PeekSession() {
- return sessions[0].get();
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/quic_client_session_cache.h b/chromium/net/third_party/quiche/src/quic/core/crypto/quic_client_session_cache.h
deleted file mode 100644
index 38678af6b9b..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/quic_client_session_cache.h
+++ /dev/null
@@ -1,82 +0,0 @@
-// Copyright (c) 2021 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_CRYPTO_QUIC_CLIENT_SESSION_CACHE_H_
-#define QUICHE_QUIC_CORE_CRYPTO_QUIC_CLIENT_SESSION_CACHE_H_
-
-#include <memory>
-
-#include "quic/core/crypto/quic_crypto_client_config.h"
-#include "quic/core/quic_lru_cache.h"
-#include "quic/core/quic_server_id.h"
-
-namespace quic {
-
-namespace test {
-class QuicClientSessionCachePeer;
-} // namespace test
-
-// QuicClientSessionCache maps from QuicServerId to information used to resume
-// TLS sessions for that server.
-class QUIC_EXPORT_PRIVATE QuicClientSessionCache : public SessionCache {
- public:
- QuicClientSessionCache();
- explicit QuicClientSessionCache(size_t max_entries);
- ~QuicClientSessionCache() override;
-
- void Insert(const QuicServerId& server_id,
- bssl::UniquePtr<SSL_SESSION> session,
- const TransportParameters& params,
- const ApplicationState* application_state) override;
-
- std::unique_ptr<QuicResumptionState> Lookup(const QuicServerId& server_id,
- QuicWallTime now,
- const SSL_CTX* ctx) override;
-
- void ClearEarlyData(const QuicServerId& server_id) override;
-
- void OnNewTokenReceived(const QuicServerId& server_id,
- absl::string_view token) override;
-
- void RemoveExpiredEntries(QuicWallTime now) override;
-
- void Clear() override;
-
- size_t size() const { return cache_.Size(); }
-
- private:
- friend class test::QuicClientSessionCachePeer;
-
- struct QUIC_EXPORT_PRIVATE Entry {
- Entry();
- Entry(Entry&&);
- ~Entry();
-
- // Adds a new |session| onto sessions, dropping the oldest one if two are
- // already stored.
- void PushSession(bssl::UniquePtr<SSL_SESSION> session);
-
- // Retrieves the latest session from the entry, meanwhile removing it.
- bssl::UniquePtr<SSL_SESSION> PopSession();
-
- SSL_SESSION* PeekSession();
-
- bssl::UniquePtr<SSL_SESSION> sessions[2];
- std::unique_ptr<TransportParameters> params;
- std::unique_ptr<ApplicationState> application_state;
- std::string token; // An opaque string received in NEW_TOKEN frame.
- };
-
- // Creates a new entry and insert into |cache_|.
- void CreateAndInsertEntry(const QuicServerId& server_id,
- bssl::UniquePtr<SSL_SESSION> session,
- const TransportParameters& params,
- const ApplicationState* application_state);
-
- QuicLRUCache<QuicServerId, Entry, QuicServerIdHash> cache_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_CRYPTO_QUIC_CLIENT_SESSION_CACHE_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/quic_client_session_cache_test.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/quic_client_session_cache_test.cc
deleted file mode 100644
index 8fd6d2522ba..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/quic_client_session_cache_test.cc
+++ /dev/null
@@ -1,440 +0,0 @@
-// Copyright (c) 2021 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 "quic/core/crypto/quic_client_session_cache.h"
-
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/mock_clock.h"
-#include "common/quiche_text_utils.h"
-
-namespace quic {
-namespace test {
-namespace {
-
-const QuicTime::Delta kTimeout = QuicTime::Delta::FromSeconds(1000);
-const QuicVersionLabel kFakeVersionLabel = 0x01234567;
-const QuicVersionLabel kFakeVersionLabel2 = 0x89ABCDEF;
-const uint64_t kFakeIdleTimeoutMilliseconds = 12012;
-const uint8_t kFakeStatelessResetTokenData[16] = {
- 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
- 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F};
-const uint64_t kFakeMaxPacketSize = 9001;
-const uint64_t kFakeInitialMaxData = 101;
-const bool kFakeDisableMigration = true;
-const auto kCustomParameter1 =
- static_cast<TransportParameters::TransportParameterId>(0xffcd);
-const char* kCustomParameter1Value = "foo";
-const auto kCustomParameter2 =
- static_cast<TransportParameters::TransportParameterId>(0xff34);
-const char* kCustomParameter2Value = "bar";
-
-std::vector<uint8_t> CreateFakeStatelessResetToken() {
- return std::vector<uint8_t>(
- kFakeStatelessResetTokenData,
- kFakeStatelessResetTokenData + sizeof(kFakeStatelessResetTokenData));
-}
-
-TransportParameters::LegacyVersionInformation
-CreateFakeLegacyVersionInformation() {
- TransportParameters::LegacyVersionInformation legacy_version_information;
- legacy_version_information.version = kFakeVersionLabel;
- legacy_version_information.supported_versions.push_back(kFakeVersionLabel);
- legacy_version_information.supported_versions.push_back(kFakeVersionLabel2);
- return legacy_version_information;
-}
-
-TransportParameters::VersionInformation CreateFakeVersionInformation() {
- TransportParameters::VersionInformation version_information;
- version_information.chosen_version = kFakeVersionLabel;
- version_information.other_versions.push_back(kFakeVersionLabel);
- return version_information;
-}
-
-// Make a TransportParameters that has a few fields set to help test comparison.
-std::unique_ptr<TransportParameters> MakeFakeTransportParams() {
- auto params = std::make_unique<TransportParameters>();
- params->perspective = Perspective::IS_CLIENT;
- params->legacy_version_information = CreateFakeLegacyVersionInformation();
- params->version_information = CreateFakeVersionInformation();
- params->max_idle_timeout_ms.set_value(kFakeIdleTimeoutMilliseconds);
- params->stateless_reset_token = CreateFakeStatelessResetToken();
- params->max_udp_payload_size.set_value(kFakeMaxPacketSize);
- params->initial_max_data.set_value(kFakeInitialMaxData);
- params->disable_active_migration = kFakeDisableMigration;
- params->custom_parameters[kCustomParameter1] = kCustomParameter1Value;
- params->custom_parameters[kCustomParameter2] = kCustomParameter2Value;
- return params;
-}
-
-// Generated by running TlsClientHandshakerTest.ZeroRttResumption and in
-// TlsClientHandshaker::InsertSession calling SSL_SESSION_to_bytes to serialize
-// the received 0-RTT capable ticket.
-static const char kCachedSession[] =
- "30820ad7020101020203040402130104206594ce84e61a866b56163c4ba09079aebf1d4f"
- "6cbcbd38dc9d7066a38a76c9cf0420ec9062063582a4cc0a44f9ff93256a195153ba6032"
- "0cf3c9189990932d838adaa10602046196f7b9a205020302a300a382039f3082039b3082"
- "0183a00302010202021001300d06092a864886f70d010105050030623111300f06035504"
- "030c08426f677573204941310b300906035504080c024d41310b30090603550406130255"
- "533121301f06092a864886f70d0109011612626f67757340626f6775732d69612e636f6d"
- "3110300e060355040a0c07426f6775734941301e170d3231303132383136323030315a17"
- "0d3331303132363136323030315a3069311d301b06035504030c14746573745f6563632e"
- "6578616d706c652e636f6d310b300906035504080c024d41310b30090603550406130255"
- "53311e301c06092a864886f70d010901160f626f67757340626f6775732e636f6d310e30"
- "0c060355040a0c05426f6775733059301306072a8648ce3d020106082a8648ce3d030107"
- "034200041ba5e2b6f24e64990b9f24ae6d23473d8c77fbcfb7f554f36559529a69a57170"
- "a10a81b7fe4a36ebf37b0a8c5e467a8443d8b8c002892aa5c1194bd843f42c9aa31f301d"
- "301b0603551d11041430128210746573742e6578616d706c652e636f6d300d06092a8648"
- "86f70d0101050500038202010019921d54ac06948763d609215f64f5d6540e3da886c6c9"
- "61bc737a437719b4621416ef1229f39282d7d3234e1a5d57535473066233bd246eec8e96"
- "1e0633cf4fe014c800e62599981820ec33d92e74ded0fa2953db1d81e19cb6890b6305b6"
- "3ede8d3e9fcf3c09f3f57283acf08aa57be4ee9a68d00bb3e2ded5920c619b5d83e5194a"
- "adb77ae5d61ed3e0a5670f0ae61cc3197329f0e71e3364dcab0405e9e4a6646adef8f022"
- "6415ec16c8046307b1769029fe780bd576114dde2fa9b4a32aa70bc436549a24ee4907a9"
- "045f6457ce8dfd8d62cc65315afe798ae1a948eefd70b035d415e73569c48fb20085de1a"
- "87de039e6b0b9a5fcb4069df27f3a7a1409e72d1ac739c72f29ef786134207e61c79855f"
- "c22e3ee5f6ad59a7b1ff0f18d79776f1c95efaebbebe381664132a58a1e7ff689945b7e0"
- "88634b0872feeefbf6be020884b994c6a7ff435f2b3f609077ff97cb509cfa17ff479b34"
- "e633e4b5bc46b20c5f27c80a2e2943f795a928acd5a3fc43c3af8425ad600c048b41d87e"
- "6361bc72fc4e5e44680a3d325674ba6ffa760d2fc7d9e4847a8e0dd9d35a543324e18b94"
- "2d42af6391ed1dd54a39e3f4a4c6b32486eb4ba72815dbd89c56fc053743a0b0483ce676"
- "15defce6800c629b99d0cbc56da162487f475b7c246099eaf1e6d10a022b2f49c6af1da3"
- "e8ed66096f267c4a76976b9572db7456ef90278330a4020400aa81b60481b3494e534543"
- "55524500f3439e548c21d2ad6e5634cc1cc0045730819702010102020304040213010400"
- "0420ec9062063582a4cc0a44f9ff93256a195153ba60320cf3c9189990932d838adaa106"
- "02046196f7b9a205020302a300a4020400b20302011db5060404130800cdb807020500ff"
- "ffffffb9050203093a80ba0404026833bb030101ffbc23042100d27d985bfce04833f02d"
- "38366b219f4def42bc4ba1b01844d1778db11731487dbd020400be020400b20302011db3"
- "8205da308205d6308203bea00302010202021000300d06092a864886f70d010105050030"
- "62310b3009060355040613025553310b300906035504080c024d413110300e060355040a"
- "0c07426f67757343413111300f06035504030c08426f6775732043413121301f06092a86"
- "4886f70d0109011612626f67757340626f6775732d63612e636f6d3020170d3231303132"
- "383136313935385a180f32303730303531313136313935385a30623111300f0603550403"
- "0c08426f677573204941310b300906035504080c024d41310b3009060355040613025553"
- "3121301f06092a864886f70d0109011612626f67757340626f6775732d69612e636f6d31"
- "10300e060355040a0c07426f677573494130820222300d06092a864886f70d0101010500"
- "0382020f003082020a028202010096c03a0ffc61bcedcd5ec9bf6f848b8a066b43f08377"
- "3af518a6a0044f22e666e24d2ae741954e344302c4be04612185bd53bcd848eb322bf900"
- "724eb0848047d647033ffbddb00f01d1de7c1cdb684f83c9bf5fd18ff60afad5a53b0d7d"
- "2c2a50abc38df019cd7f50194d05bc4597a1ef8570ea04069a2c36d74496af126573ca18"
- "8e470009b56250fadf2a04e837ee3837b36b1f08b7a0cfe2533d05f26484ce4e30203d01"
- "517fffd3da63d0341079ddce16e9ab4dbf9d4049e5cc52326031e645dd682fe6220d9e0e"
- "95451f5a82f3e1720dc13e8499466426a0bdbea9f6a76b3c9228dd3c79ab4dcc4c145ef0"
- "e78d1ee8bfd4650692d7e28a54bed809d8f7b37fe24c586be59cc46638531cb291c8c156"
- "8f08d67e768e51563e95a639c1f138b275ffad6a6a2a042ba9e26ad63c2ce63b600013f0"
- "a6f0703ee51c4f457f7bab0391c2fc4c5bb3213742c9cf9941bff68cc2e1cc96139d35ed"
- "1885244ddde0bf658416c486701841b81f7b17503d08c59a4db08a2a80755e007aa3b6c7"
- "eadcaa9e07c8325f3689f100de23970b12c9d9f6d0a8fb35ba0fd75c64410318db4a13ac"
- "3972ad16cdf6408af37013c7bcd7c42f20d6d04c3e39436c7531e8dafa219dd04b784ef0"
- "3c70ee5a4782b33cafa925aa3deca62a14aed704f179b932efabc2b0c5c15a8a99bfc9e6"
- "189dce7da50ea303594b6af9c933dd54b6e9d17c472d0203010001a38193308190300f06"
- "03551d130101ff040530030101ff301d0603551d0e041604141a98e80029a80992b7e5e0"
- "068ab9b3486cd839d6301f0603551d23041830168014780beeefe2fa419c48a438bdb30b"
- "e37ef0b7a94e300b0603551d0f0404030202a430130603551d25040c300a06082b060105"
- "05070301301b0603551d11041430128207426f67757343418207426f6775734941300d06"
- "092a864886f70d010105050003820201009e822ed8064b1aabaddf1340010ea147f68c06"
- "5a5a599ea305349f1b0e545a00817d6e55c7bf85560fab429ca72186c4d520b52f5cc121"
- "abd068b06f3111494431d2522efa54642f907059e7db80b73bb5ecf621377195b8700bba"
- "df798cece8c67a9571548d0e6592e81ae5d934877cb170aef18d3b97f635600fe0890d98"
- "f88b33fe3d1fd34c1c915beae4e5c0b133f476c40b21d220f16ce9cdd9e8f97a36a31723"
- "68875f052c9271648d9cb54687c6fdc3ea96f2908003bc5e5e79de00a21da7b8429f8b08"
- "af4c4d34641e386d72eabf5f01f106363f2ffd18969bf0bb9a4d17627c6427ff772c4308"
- "83c276feef5fc6dba9582c22fdbe9df7e8dfca375695f028ed588df54f3c86462dbf4c07"
- "91d80ca738988a1419c86bb4dd8d738b746921f01f39422e5ffd488b6f00195b996e6392"
- "3a820a32cd78b5989f339c0fcf4f269103964a30a16347d0ffdc8df1f3653ddc1515fa09"
- "22c7aef1af1fbcb23e93ae7622ab1ee11fcfa98319bad4c37c091cad46bd0337b3cc78b5"
- "5b9f1ea7994acc1f89c49a0b4cb540d2137e266fd43e56a9b5b778217b6f77df530e1eaf"
- "b3417262b5ddb86d3c6c5ac51e3f326c650dcc2434473973b7182c66220d1f3871bde7ee"
- "47d3f359d3d4c5bdd61baa684c03db4c75f9d6690c9e6e3abe6eaf5fa2c33c4daf26b373"
- "d85a1e8a7d671ac4a0a97b14e36e81280de4593bbb12da7695b5060404130800cdb60301"
- "0100b70402020403b807020500ffffffffb9050203093a80ba0404026833bb030101ffbd"
- "020400be020400";
-
-class QuicClientSessionCacheTest : public QuicTest {
- public:
- QuicClientSessionCacheTest() : ssl_ctx_(SSL_CTX_new(TLS_method())) {
- clock_.AdvanceTime(QuicTime::Delta::FromSeconds(1));
- }
-
- protected:
- bssl::UniquePtr<SSL_SESSION> NewSSLSession() {
- std::string cached_session =
- absl::HexStringToBytes(absl::string_view(kCachedSession));
- SSL_SESSION* session = SSL_SESSION_from_bytes(
- reinterpret_cast<const uint8_t*>(cached_session.data()),
- cached_session.size(), ssl_ctx_.get());
- QUICHE_DCHECK(session);
- return bssl::UniquePtr<SSL_SESSION>(session);
- }
-
- bssl::UniquePtr<SSL_SESSION> MakeTestSession(
- QuicTime::Delta timeout = kTimeout) {
- bssl::UniquePtr<SSL_SESSION> session = NewSSLSession();
- SSL_SESSION_set_time(session.get(), clock_.WallNow().ToUNIXSeconds());
- SSL_SESSION_set_timeout(session.get(), timeout.ToSeconds());
- return session;
- }
-
- bssl::UniquePtr<SSL_CTX> ssl_ctx_;
- MockClock clock_;
-};
-
-// Tests that simple insertion and lookup work correctly.
-TEST_F(QuicClientSessionCacheTest, SingleSession) {
- QuicClientSessionCache cache;
-
- auto params = MakeFakeTransportParams();
- auto session = MakeTestSession();
- QuicServerId id1("a.com", 443);
-
- auto params2 = MakeFakeTransportParams();
- auto session2 = MakeTestSession();
- SSL_SESSION* unowned2 = session2.get();
- QuicServerId id2("b.com", 443);
-
- EXPECT_EQ(nullptr, cache.Lookup(id1, clock_.WallNow(), ssl_ctx_.get()));
- EXPECT_EQ(nullptr, cache.Lookup(id2, clock_.WallNow(), ssl_ctx_.get()));
- EXPECT_EQ(0u, cache.size());
-
- cache.Insert(id1, std::move(session), *params, nullptr);
- EXPECT_EQ(1u, cache.size());
- EXPECT_EQ(
- *params,
- *(cache.Lookup(id1, clock_.WallNow(), ssl_ctx_.get())->transport_params));
- EXPECT_EQ(nullptr, cache.Lookup(id2, clock_.WallNow(), ssl_ctx_.get()));
- // No session is available for id1, even though the entry exists.
- EXPECT_EQ(1u, cache.size());
- EXPECT_EQ(nullptr, cache.Lookup(id1, clock_.WallNow(), ssl_ctx_.get()));
- // Lookup() will trigger a deletion of invalid entry.
- EXPECT_EQ(0u, cache.size());
-
- auto session3 = MakeTestSession();
- SSL_SESSION* unowned3 = session3.get();
- QuicServerId id3("c.com", 443);
- cache.Insert(id3, std::move(session3), *params, nullptr);
- cache.Insert(id2, std::move(session2), *params2, nullptr);
- EXPECT_EQ(2u, cache.size());
- EXPECT_EQ(
- unowned2,
- cache.Lookup(id2, clock_.WallNow(), ssl_ctx_.get())->tls_session.get());
- EXPECT_EQ(
- unowned3,
- cache.Lookup(id3, clock_.WallNow(), ssl_ctx_.get())->tls_session.get());
-
- // Verify that the cache is cleared after Lookups.
- EXPECT_EQ(nullptr, cache.Lookup(id1, clock_.WallNow(), ssl_ctx_.get()));
- EXPECT_EQ(nullptr, cache.Lookup(id2, clock_.WallNow(), ssl_ctx_.get()));
- EXPECT_EQ(nullptr, cache.Lookup(id3, clock_.WallNow(), ssl_ctx_.get()));
- EXPECT_EQ(0u, cache.size());
-}
-
-TEST_F(QuicClientSessionCacheTest, MultipleSessions) {
- QuicClientSessionCache cache;
-
- auto params = MakeFakeTransportParams();
- auto session = MakeTestSession();
- QuicServerId id1("a.com", 443);
- auto session2 = MakeTestSession();
- SSL_SESSION* unowned2 = session2.get();
- auto session3 = MakeTestSession();
- SSL_SESSION* unowned3 = session3.get();
-
- cache.Insert(id1, std::move(session), *params, nullptr);
- cache.Insert(id1, std::move(session2), *params, nullptr);
- cache.Insert(id1, std::move(session3), *params, nullptr);
- // The latest session is popped first.
- EXPECT_EQ(
- unowned3,
- cache.Lookup(id1, clock_.WallNow(), ssl_ctx_.get())->tls_session.get());
- EXPECT_EQ(
- unowned2,
- cache.Lookup(id1, clock_.WallNow(), ssl_ctx_.get())->tls_session.get());
- // Only two sessions are cached.
- EXPECT_EQ(nullptr, cache.Lookup(id1, clock_.WallNow(), ssl_ctx_.get()));
-}
-
-// Test that when a different TransportParameter is inserted for
-// the same server id, the existing entry is removed.
-TEST_F(QuicClientSessionCacheTest, DifferentTransportParams) {
- QuicClientSessionCache cache;
-
- auto params = MakeFakeTransportParams();
- auto session = MakeTestSession();
- QuicServerId id1("a.com", 443);
- auto session2 = MakeTestSession();
- auto session3 = MakeTestSession();
- SSL_SESSION* unowned3 = session3.get();
-
- cache.Insert(id1, std::move(session), *params, nullptr);
- cache.Insert(id1, std::move(session2), *params, nullptr);
- // tweak the transport parameters a little bit.
- params->perspective = Perspective::IS_SERVER;
- cache.Insert(id1, std::move(session3), *params, nullptr);
- auto resumption_state = cache.Lookup(id1, clock_.WallNow(), ssl_ctx_.get());
- EXPECT_EQ(unowned3, resumption_state->tls_session.get());
- EXPECT_EQ(*params.get(), *resumption_state->transport_params);
- EXPECT_EQ(nullptr, cache.Lookup(id1, clock_.WallNow(), ssl_ctx_.get()));
-}
-
-TEST_F(QuicClientSessionCacheTest, DifferentApplicationState) {
- QuicClientSessionCache cache;
-
- auto params = MakeFakeTransportParams();
- auto session = MakeTestSession();
- QuicServerId id1("a.com", 443);
- auto session2 = MakeTestSession();
- auto session3 = MakeTestSession();
- SSL_SESSION* unowned3 = session3.get();
- ApplicationState state;
- state.push_back('a');
-
- cache.Insert(id1, std::move(session), *params, &state);
- cache.Insert(id1, std::move(session2), *params, &state);
- cache.Insert(id1, std::move(session3), *params, nullptr);
- auto resumption_state = cache.Lookup(id1, clock_.WallNow(), ssl_ctx_.get());
- EXPECT_EQ(unowned3, resumption_state->tls_session.get());
- EXPECT_EQ(nullptr, resumption_state->application_state);
- EXPECT_EQ(nullptr, cache.Lookup(id1, clock_.WallNow(), ssl_ctx_.get()));
-}
-
-TEST_F(QuicClientSessionCacheTest, BothStatesDifferent) {
- QuicClientSessionCache cache;
-
- auto params = MakeFakeTransportParams();
- auto session = MakeTestSession();
- QuicServerId id1("a.com", 443);
- auto session2 = MakeTestSession();
- auto session3 = MakeTestSession();
- SSL_SESSION* unowned3 = session3.get();
- ApplicationState state;
- state.push_back('a');
-
- cache.Insert(id1, std::move(session), *params, &state);
- cache.Insert(id1, std::move(session2), *params, &state);
- params->perspective = Perspective::IS_SERVER;
- cache.Insert(id1, std::move(session3), *params, nullptr);
- auto resumption_state = cache.Lookup(id1, clock_.WallNow(), ssl_ctx_.get());
- EXPECT_EQ(unowned3, resumption_state->tls_session.get());
- EXPECT_EQ(*params.get(), *resumption_state->transport_params);
- EXPECT_EQ(nullptr, resumption_state->application_state);
- EXPECT_EQ(nullptr, cache.Lookup(id1, clock_.WallNow(), ssl_ctx_.get()));
-}
-
-// When the size limit is exceeded, the oldest entry should be erased.
-TEST_F(QuicClientSessionCacheTest, SizeLimit) {
- QuicClientSessionCache cache(2);
-
- auto params = MakeFakeTransportParams();
- auto session = MakeTestSession();
- QuicServerId id1("a.com", 443);
-
- auto session2 = MakeTestSession();
- SSL_SESSION* unowned2 = session2.get();
- QuicServerId id2("b.com", 443);
-
- auto session3 = MakeTestSession();
- SSL_SESSION* unowned3 = session3.get();
- QuicServerId id3("c.com", 443);
-
- cache.Insert(id1, std::move(session), *params, nullptr);
- cache.Insert(id2, std::move(session2), *params, nullptr);
- cache.Insert(id3, std::move(session3), *params, nullptr);
-
- EXPECT_EQ(2u, cache.size());
- EXPECT_EQ(
- unowned2,
- cache.Lookup(id2, clock_.WallNow(), ssl_ctx_.get())->tls_session.get());
- EXPECT_EQ(
- unowned3,
- cache.Lookup(id3, clock_.WallNow(), ssl_ctx_.get())->tls_session.get());
- EXPECT_EQ(nullptr, cache.Lookup(id1, clock_.WallNow(), ssl_ctx_.get()));
-}
-
-TEST_F(QuicClientSessionCacheTest, ClearEarlyData) {
- QuicClientSessionCache cache;
- SSL_CTX_set_early_data_enabled(ssl_ctx_.get(), 1);
- auto params = MakeFakeTransportParams();
- auto session = MakeTestSession();
- QuicServerId id1("a.com", 443);
- auto session2 = MakeTestSession();
-
- EXPECT_TRUE(SSL_SESSION_early_data_capable(session.get()));
- EXPECT_TRUE(SSL_SESSION_early_data_capable(session2.get()));
-
- cache.Insert(id1, std::move(session), *params, nullptr);
- cache.Insert(id1, std::move(session2), *params, nullptr);
-
- cache.ClearEarlyData(id1);
-
- auto resumption_state = cache.Lookup(id1, clock_.WallNow(), ssl_ctx_.get());
- EXPECT_FALSE(
- SSL_SESSION_early_data_capable(resumption_state->tls_session.get()));
- resumption_state = cache.Lookup(id1, clock_.WallNow(), ssl_ctx_.get());
- EXPECT_FALSE(
- SSL_SESSION_early_data_capable(resumption_state->tls_session.get()));
- EXPECT_EQ(nullptr, cache.Lookup(id1, clock_.WallNow(), ssl_ctx_.get()));
-}
-
-// Expired session isn't considered valid and nullptr will be returned upon
-// Lookup.
-TEST_F(QuicClientSessionCacheTest, Expiration) {
- QuicClientSessionCache cache;
-
- auto params = MakeFakeTransportParams();
- auto session = MakeTestSession();
- QuicServerId id1("a.com", 443);
-
- auto session2 = MakeTestSession(3 * kTimeout);
- SSL_SESSION* unowned2 = session2.get();
- QuicServerId id2("b.com", 443);
-
- cache.Insert(id1, std::move(session), *params, nullptr);
- cache.Insert(id2, std::move(session2), *params, nullptr);
-
- EXPECT_EQ(2u, cache.size());
- // Expire the session.
- clock_.AdvanceTime(kTimeout * 2);
- // The entry has not been removed yet.
- EXPECT_EQ(2u, cache.size());
-
- EXPECT_EQ(nullptr, cache.Lookup(id1, clock_.WallNow(), ssl_ctx_.get()));
- EXPECT_EQ(1u, cache.size());
- EXPECT_EQ(
- unowned2,
- cache.Lookup(id2, clock_.WallNow(), ssl_ctx_.get())->tls_session.get());
- EXPECT_EQ(1u, cache.size());
-}
-
-TEST_F(QuicClientSessionCacheTest, RemoveExpiredEntriesAndClear) {
- QuicClientSessionCache cache;
-
- auto params = MakeFakeTransportParams();
- auto session = MakeTestSession();
- quic::QuicServerId id1("a.com", 443);
-
- auto session2 = MakeTestSession(3 * kTimeout);
- quic::QuicServerId id2("b.com", 443);
-
- cache.Insert(id1, std::move(session), *params, nullptr);
- cache.Insert(id2, std::move(session2), *params, nullptr);
-
- EXPECT_EQ(2u, cache.size());
- // Expire the session.
- clock_.AdvanceTime(kTimeout * 2);
- // The entry has not been removed yet.
- EXPECT_EQ(2u, cache.size());
-
- // Flush expired sessions.
- cache.RemoveExpiredEntries(clock_.WallNow());
-
- // session is expired and should be flushed.
- EXPECT_EQ(nullptr, cache.Lookup(id1, clock_.WallNow(), ssl_ctx_.get()));
- EXPECT_EQ(1u, cache.size());
-
- cache.Clear();
- EXPECT_EQ(0u, cache.size());
-}
-
-} // namespace
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/quic_compressed_certs_cache.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/quic_compressed_certs_cache.cc
deleted file mode 100644
index 6377a647810..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/quic_compressed_certs_cache.cc
+++ /dev/null
@@ -1,133 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <string>
-
-#include "quic/core/crypto/quic_compressed_certs_cache.h"
-
-namespace quic {
-
-namespace {
-
-// Inline helper function for extending a 64-bit |seed| in-place with a 64-bit
-// |value|. Based on Boost's hash_combine function.
-inline void hash_combine(uint64_t* seed, const uint64_t& val) {
- (*seed) ^= val + 0x9e3779b9 + ((*seed) << 6) + ((*seed) >> 2);
-}
-
-} // namespace
-
-const size_t QuicCompressedCertsCache::kQuicCompressedCertsCacheSize = 225;
-
-QuicCompressedCertsCache::UncompressedCerts::UncompressedCerts()
- : chain(nullptr),
- client_common_set_hashes(nullptr),
- client_cached_cert_hashes(nullptr) {}
-
-QuicCompressedCertsCache::UncompressedCerts::UncompressedCerts(
- const QuicReferenceCountedPointer<ProofSource::Chain>& chain,
- const std::string* client_common_set_hashes,
- const std::string* client_cached_cert_hashes)
- : chain(chain),
- client_common_set_hashes(client_common_set_hashes),
- client_cached_cert_hashes(client_cached_cert_hashes) {}
-
-QuicCompressedCertsCache::UncompressedCerts::~UncompressedCerts() {}
-
-QuicCompressedCertsCache::CachedCerts::CachedCerts() {}
-
-QuicCompressedCertsCache::CachedCerts::CachedCerts(
- const UncompressedCerts& uncompressed_certs,
- const std::string& compressed_cert)
- : chain_(uncompressed_certs.chain),
- client_common_set_hashes_(*uncompressed_certs.client_common_set_hashes),
- client_cached_cert_hashes_(*uncompressed_certs.client_cached_cert_hashes),
- compressed_cert_(compressed_cert) {}
-
-QuicCompressedCertsCache::CachedCerts::CachedCerts(const CachedCerts& other) =
- default;
-
-QuicCompressedCertsCache::CachedCerts::~CachedCerts() {}
-
-bool QuicCompressedCertsCache::CachedCerts::MatchesUncompressedCerts(
- const UncompressedCerts& uncompressed_certs) const {
- return (client_common_set_hashes_ ==
- *uncompressed_certs.client_common_set_hashes &&
- client_cached_cert_hashes_ ==
- *uncompressed_certs.client_cached_cert_hashes &&
- chain_ == uncompressed_certs.chain);
-}
-
-const std::string* QuicCompressedCertsCache::CachedCerts::compressed_cert()
- const {
- return &compressed_cert_;
-}
-
-QuicCompressedCertsCache::QuicCompressedCertsCache(int64_t max_num_certs)
- : certs_cache_(max_num_certs) {}
-
-QuicCompressedCertsCache::~QuicCompressedCertsCache() {
- // Underlying cache must be cleared before destruction.
- certs_cache_.Clear();
-}
-
-const std::string* QuicCompressedCertsCache::GetCompressedCert(
- const QuicReferenceCountedPointer<ProofSource::Chain>& chain,
- const std::string& client_common_set_hashes,
- const std::string& client_cached_cert_hashes) {
- UncompressedCerts uncompressed_certs(chain, &client_common_set_hashes,
- &client_cached_cert_hashes);
-
- uint64_t key = ComputeUncompressedCertsHash(uncompressed_certs);
-
- CachedCerts* cached_value = nullptr;
- auto iter = certs_cache_.Lookup(key);
- if (iter != certs_cache_.end()) {
- cached_value = iter->second.get();
- }
- if (cached_value != nullptr &&
- cached_value->MatchesUncompressedCerts(uncompressed_certs)) {
- return cached_value->compressed_cert();
- }
- return nullptr;
-}
-
-void QuicCompressedCertsCache::Insert(
- const QuicReferenceCountedPointer<ProofSource::Chain>& chain,
- const std::string& client_common_set_hashes,
- const std::string& client_cached_cert_hashes,
- const std::string& compressed_cert) {
- UncompressedCerts uncompressed_certs(chain, &client_common_set_hashes,
- &client_cached_cert_hashes);
-
- uint64_t key = ComputeUncompressedCertsHash(uncompressed_certs);
-
- // Insert one unit to the cache.
- std::unique_ptr<CachedCerts> cached_certs(
- new CachedCerts(uncompressed_certs, compressed_cert));
- certs_cache_.Insert(key, std::move(cached_certs));
-}
-
-size_t QuicCompressedCertsCache::MaxSize() {
- return certs_cache_.MaxSize();
-}
-
-size_t QuicCompressedCertsCache::Size() {
- return certs_cache_.Size();
-}
-
-uint64_t QuicCompressedCertsCache::ComputeUncompressedCertsHash(
- const UncompressedCerts& uncompressed_certs) {
- uint64_t hash =
- std::hash<std::string>()(*uncompressed_certs.client_common_set_hashes);
- uint64_t h =
- std::hash<std::string>()(*uncompressed_certs.client_cached_cert_hashes);
- hash_combine(&hash, h);
-
- hash_combine(&hash,
- reinterpret_cast<uint64_t>(uncompressed_certs.chain.get()));
- return hash;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/quic_compressed_certs_cache.h b/chromium/net/third_party/quiche/src/quic/core/crypto/quic_compressed_certs_cache.h
deleted file mode 100644
index 9f6929ab242..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/quic_compressed_certs_cache.h
+++ /dev/null
@@ -1,108 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_CRYPTO_QUIC_COMPRESSED_CERTS_CACHE_H_
-#define QUICHE_QUIC_CORE_CRYPTO_QUIC_COMPRESSED_CERTS_CACHE_H_
-
-#include <string>
-#include <vector>
-
-#include "quic/core/crypto/proof_source.h"
-#include "quic/core/quic_lru_cache.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// QuicCompressedCertsCache is a cache to track most recently compressed certs.
-class QUIC_EXPORT_PRIVATE QuicCompressedCertsCache {
- public:
- explicit QuicCompressedCertsCache(int64_t max_num_certs);
- ~QuicCompressedCertsCache();
-
- // Returns the pointer to the cached compressed cert if
- // |chain, client_common_set_hashes, client_cached_cert_hashes| hits cache.
- // Otherwise, return nullptr.
- // Returned pointer might become invalid on the next call to Insert().
- const std::string* GetCompressedCert(
- const QuicReferenceCountedPointer<ProofSource::Chain>& chain,
- const std::string& client_common_set_hashes,
- const std::string& client_cached_cert_hashes);
-
- // Inserts the specified
- // |chain, client_common_set_hashes,
- // client_cached_cert_hashes, compressed_cert| tuple to the cache.
- // If the insertion causes the cache to become overfull, entries will
- // be deleted in an LRU order to make room.
- void Insert(const QuicReferenceCountedPointer<ProofSource::Chain>& chain,
- const std::string& client_common_set_hashes,
- const std::string& client_cached_cert_hashes,
- const std::string& compressed_cert);
-
- // Returns max number of cache entries the cache can carry.
- size_t MaxSize();
-
- // Returns current number of cache entries in the cache.
- size_t Size();
-
- // Default size of the QuicCompressedCertsCache per server side investigation.
- static const size_t kQuicCompressedCertsCacheSize;
-
- private:
- // A wrapper of the tuple:
- // |chain, client_common_set_hashes, client_cached_cert_hashes|
- // to identify uncompressed representation of certs.
- struct QUIC_EXPORT_PRIVATE UncompressedCerts {
- UncompressedCerts();
- UncompressedCerts(
- const QuicReferenceCountedPointer<ProofSource::Chain>& chain,
- const std::string* client_common_set_hashes,
- const std::string* client_cached_cert_hashes);
- ~UncompressedCerts();
-
- const QuicReferenceCountedPointer<ProofSource::Chain> chain;
- const std::string* client_common_set_hashes;
- const std::string* client_cached_cert_hashes;
- };
-
- // Certs stored by QuicCompressedCertsCache where uncompressed certs data is
- // used to identify the uncompressed representation of certs and
- // |compressed_cert| is the cached compressed representation.
- class QUIC_EXPORT_PRIVATE CachedCerts {
- public:
- CachedCerts();
- CachedCerts(const UncompressedCerts& uncompressed_certs,
- const std::string& compressed_cert);
- CachedCerts(const CachedCerts& other);
- ~CachedCerts();
-
- // Returns true if the |uncompressed_certs| matches uncompressed
- // representation of this cert.
- bool MatchesUncompressedCerts(
- const UncompressedCerts& uncompressed_certs) const;
-
- const std::string* compressed_cert() const;
-
- private:
- // Uncompressed certs data.
- QuicReferenceCountedPointer<ProofSource::Chain> chain_;
- const std::string client_common_set_hashes_;
- const std::string client_cached_cert_hashes_;
-
- // Cached compressed representation derived from uncompressed certs.
- const std::string compressed_cert_;
- };
-
- // Computes a uint64_t hash for |uncompressed_certs|.
- uint64_t ComputeUncompressedCertsHash(
- const UncompressedCerts& uncompressed_certs);
-
- // Key is a unit64_t hash for UncompressedCerts. Stored associated value is
- // CachedCerts which has both original uncompressed certs data and the
- // compressed representation of the certs.
- QuicLRUCache<uint64_t, CachedCerts> certs_cache_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_CRYPTO_QUIC_COMPRESSED_CERTS_CACHE_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/quic_compressed_certs_cache_test.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/quic_compressed_certs_cache_test.cc
deleted file mode 100644
index 8af7f373ea7..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/quic_compressed_certs_cache_test.cc
+++ /dev/null
@@ -1,98 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/crypto/quic_compressed_certs_cache.h"
-
-#include <string>
-
-#include "absl/strings/str_cat.h"
-#include "quic/core/crypto/cert_compressor.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/crypto_test_utils.h"
-
-namespace quic {
-
-namespace test {
-
-namespace {
-
-class QuicCompressedCertsCacheTest : public QuicTest {
- public:
- QuicCompressedCertsCacheTest()
- : certs_cache_(QuicCompressedCertsCache::kQuicCompressedCertsCacheSize) {}
-
- protected:
- QuicCompressedCertsCache certs_cache_;
-};
-
-TEST_F(QuicCompressedCertsCacheTest, CacheHit) {
- std::vector<std::string> certs = {"leaf cert", "intermediate cert",
- "root cert"};
- QuicReferenceCountedPointer<ProofSource::Chain> chain(
- new ProofSource::Chain(certs));
- std::string common_certs = "common certs";
- std::string cached_certs = "cached certs";
- std::string compressed = "compressed cert";
-
- certs_cache_.Insert(chain, common_certs, cached_certs, compressed);
-
- const std::string* cached_value =
- certs_cache_.GetCompressedCert(chain, common_certs, cached_certs);
- ASSERT_NE(nullptr, cached_value);
- EXPECT_EQ(*cached_value, compressed);
-}
-
-TEST_F(QuicCompressedCertsCacheTest, CacheMiss) {
- std::vector<std::string> certs = {"leaf cert", "intermediate cert",
- "root cert"};
- QuicReferenceCountedPointer<ProofSource::Chain> chain(
- new ProofSource::Chain(certs));
-
- std::string common_certs = "common certs";
- std::string cached_certs = "cached certs";
- std::string compressed = "compressed cert";
-
- certs_cache_.Insert(chain, common_certs, cached_certs, compressed);
-
- EXPECT_EQ(nullptr, certs_cache_.GetCompressedCert(
- chain, "mismatched common certs", cached_certs));
- EXPECT_EQ(nullptr, certs_cache_.GetCompressedCert(chain, common_certs,
- "mismatched cached certs"));
-
- // A different chain though with equivalent certs should get a cache miss.
- QuicReferenceCountedPointer<ProofSource::Chain> chain2(
- new ProofSource::Chain(certs));
- EXPECT_EQ(nullptr,
- certs_cache_.GetCompressedCert(chain2, common_certs, cached_certs));
-}
-
-TEST_F(QuicCompressedCertsCacheTest, CacheMissDueToEviction) {
- // Test cache returns a miss when a queried uncompressed certs was cached but
- // then evicted.
- std::vector<std::string> certs = {"leaf cert", "intermediate cert",
- "root cert"};
- QuicReferenceCountedPointer<ProofSource::Chain> chain(
- new ProofSource::Chain(certs));
-
- std::string common_certs = "common certs";
- std::string cached_certs = "cached certs";
- std::string compressed = "compressed cert";
- certs_cache_.Insert(chain, common_certs, cached_certs, compressed);
-
- // Insert another kQuicCompressedCertsCacheSize certs to evict the first
- // cached cert.
- for (unsigned int i = 0;
- i < QuicCompressedCertsCache::kQuicCompressedCertsCacheSize; i++) {
- EXPECT_EQ(certs_cache_.Size(), i + 1);
- certs_cache_.Insert(chain, absl::StrCat(i), "", absl::StrCat(i));
- }
- EXPECT_EQ(certs_cache_.MaxSize(), certs_cache_.Size());
-
- EXPECT_EQ(nullptr,
- certs_cache_.GetCompressedCert(chain, common_certs, cached_certs));
-}
-
-} // namespace
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/quic_crypter.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/quic_crypter.cc
deleted file mode 100644
index d41ce21f269..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/quic_crypter.cc
+++ /dev/null
@@ -1,18 +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 "quic/core/crypto/quic_crypter.h"
-#include "absl/strings/string_view.h"
-
-namespace quic {
-
-bool QuicCrypter::SetNoncePrefixOrIV(const ParsedQuicVersion& version,
- absl::string_view nonce_prefix_or_iv) {
- if (version.UsesInitialObfuscators()) {
- return SetIV(nonce_prefix_or_iv);
- }
- return SetNoncePrefix(nonce_prefix_or_iv);
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/quic_crypter.h b/chromium/net/third_party/quiche/src/quic/core/crypto/quic_crypter.h
deleted file mode 100644
index 001b6ecd95f..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/quic_crypter.h
+++ /dev/null
@@ -1,94 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_CRYPTO_QUIC_CRYPTER_H_
-#define QUICHE_QUIC_CORE_CRYPTO_QUIC_CRYPTER_H_
-
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_versions.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// QuicCrypter is the parent class for QuicEncrypter and QuicDecrypter.
-// Its purpose is to provide an interface for using methods that are common to
-// both classes when operations are being done that apply to both encrypters and
-// decrypters.
-class QUIC_EXPORT_PRIVATE QuicCrypter {
- public:
- virtual ~QuicCrypter() {}
-
- // Sets the symmetric encryption/decryption key. Returns true on success,
- // false on failure.
- //
- // NOTE: The key is the client_write_key or server_write_key derived from
- // the master secret.
- virtual bool SetKey(absl::string_view key) = 0;
-
- // Sets the fixed initial bytes of the nonce. Returns true on success,
- // false on failure. This method must only be used with Google QUIC crypters.
- //
- // NOTE: The nonce prefix is the client_write_iv or server_write_iv
- // derived from the master secret. A 64-bit packet number will
- // be appended to form the nonce.
- //
- // <------------ 64 bits ----------->
- // +---------------------+----------------------------------+
- // | Fixed prefix | packet number |
- // +---------------------+----------------------------------+
- // Nonce format
- //
- // The security of the nonce format requires that QUIC never reuse a
- // packet number, even when retransmitting a lost packet.
- virtual bool SetNoncePrefix(absl::string_view nonce_prefix) = 0;
-
- // Sets |iv| as the initialization vector to use when constructing the nonce.
- // Returns true on success, false on failure. This method must only be used
- // with IETF QUIC crypters.
- //
- // Google QUIC and IETF QUIC use different nonce constructions. This method
- // must be used when using IETF QUIC; SetNoncePrefix must be used when using
- // Google QUIC.
- //
- // The nonce is constructed as follows (draft-ietf-quic-tls-14 section 5.2):
- //
- // <---------------- max(8, N_MIN) bytes ----------------->
- // +--------------------------------------------------------+
- // | packet protection IV |
- // +--------------------------------------------------------+
- // XOR
- // <------------ 64 bits ----------->
- // +---------------------+----------------------------------+
- // | zeroes | reconstructed packet number |
- // +---------------------+----------------------------------+
- //
- // The nonce is the packet protection IV (|iv|) XOR'd with the left-padded
- // reconstructed packet number.
- //
- // The security of the nonce format requires that QUIC never reuse a
- // packet number, even when retransmitting a lost packet.
- virtual bool SetIV(absl::string_view iv) = 0;
-
- // Calls SetNoncePrefix or SetIV depending on whether |version| uses the
- // Google QUIC crypto or IETF QUIC nonce construction.
- virtual bool SetNoncePrefixOrIV(const ParsedQuicVersion& version,
- absl::string_view nonce_prefix_or_iv);
-
- // Sets the key to use for header protection.
- virtual bool SetHeaderProtectionKey(absl::string_view key) = 0;
-
- // GetKeySize, GetIVSize, and GetNoncePrefixSize are used to know how many
- // bytes of key material needs to be derived from the master secret.
-
- // Returns the size in bytes of a key for the algorithm.
- virtual size_t GetKeySize() const = 0;
- // Returns the size in bytes of an IV to use with the algorithm.
- virtual size_t GetIVSize() const = 0;
- // Returns the size in bytes of the fixed initial part of the nonce.
- virtual size_t GetNoncePrefixSize() const = 0;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_CRYPTO_QUIC_CRYPTER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/quic_crypto_client_config.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/quic_crypto_client_config.cc
deleted file mode 100644
index 1b1790adc75..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/quic_crypto_client_config.cc
+++ /dev/null
@@ -1,873 +0,0 @@
-// Copyright 2013 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 "quic/core/crypto/quic_crypto_client_config.h"
-
-#include <algorithm>
-#include <memory>
-#include <string>
-
-#include "absl/base/macros.h"
-#include "absl/memory/memory.h"
-#include "absl/strings/match.h"
-#include "absl/strings/string_view.h"
-#include "third_party/boringssl/src/include/openssl/ssl.h"
-#include "quic/core/crypto/cert_compressor.h"
-#include "quic/core/crypto/chacha20_poly1305_encrypter.h"
-#include "quic/core/crypto/common_cert_set.h"
-#include "quic/core/crypto/crypto_framer.h"
-#include "quic/core/crypto/crypto_protocol.h"
-#include "quic/core/crypto/crypto_utils.h"
-#include "quic/core/crypto/curve25519_key_exchange.h"
-#include "quic/core/crypto/key_exchange.h"
-#include "quic/core/crypto/p256_key_exchange.h"
-#include "quic/core/crypto/proof_verifier.h"
-#include "quic/core/crypto/quic_encrypter.h"
-#include "quic/core/crypto/quic_random.h"
-#include "quic/core/crypto/tls_client_connection.h"
-#include "quic/core/quic_connection_id.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_client_stats.h"
-#include "quic/platform/api/quic_hostname_utils.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-namespace {
-
-// Tracks the reason (the state of the server config) for sending inchoate
-// ClientHello to the server.
-void RecordInchoateClientHelloReason(
- QuicCryptoClientConfig::CachedState::ServerConfigState state) {
- QUIC_CLIENT_HISTOGRAM_ENUM(
- "QuicInchoateClientHelloReason", state,
- QuicCryptoClientConfig::CachedState::SERVER_CONFIG_COUNT, "");
-}
-
-// Tracks the state of the QUIC server information loaded from the disk cache.
-void RecordDiskCacheServerConfigState(
- QuicCryptoClientConfig::CachedState::ServerConfigState state) {
- QUIC_CLIENT_HISTOGRAM_ENUM(
- "QuicServerInfo.DiskCacheState", state,
- QuicCryptoClientConfig::CachedState::SERVER_CONFIG_COUNT, "");
-}
-
-} // namespace
-
-QuicCryptoClientConfig::QuicCryptoClientConfig(
- std::unique_ptr<ProofVerifier> proof_verifier)
- : QuicCryptoClientConfig(std::move(proof_verifier), nullptr) {}
-
-QuicCryptoClientConfig::QuicCryptoClientConfig(
- std::unique_ptr<ProofVerifier> proof_verifier,
- std::unique_ptr<SessionCache> session_cache)
- : proof_verifier_(std::move(proof_verifier)),
- session_cache_(std::move(session_cache)),
- ssl_ctx_(TlsClientConnection::CreateSslCtx(
- !GetQuicFlag(FLAGS_quic_disable_client_tls_zero_rtt))) {
- QUICHE_DCHECK(proof_verifier_.get());
- SetDefaults();
-}
-
-QuicCryptoClientConfig::~QuicCryptoClientConfig() {}
-
-QuicCryptoClientConfig::CachedState::CachedState()
- : server_config_valid_(false),
- expiration_time_(QuicWallTime::Zero()),
- generation_counter_(0) {}
-
-QuicCryptoClientConfig::CachedState::~CachedState() {}
-
-bool QuicCryptoClientConfig::CachedState::IsComplete(QuicWallTime now) const {
- if (server_config_.empty()) {
- RecordInchoateClientHelloReason(SERVER_CONFIG_EMPTY);
- return false;
- }
-
- if (!server_config_valid_) {
- RecordInchoateClientHelloReason(SERVER_CONFIG_INVALID);
- return false;
- }
-
- const CryptoHandshakeMessage* scfg = GetServerConfig();
- if (!scfg) {
- // Should be impossible short of cache corruption.
- RecordInchoateClientHelloReason(SERVER_CONFIG_CORRUPTED);
- QUICHE_DCHECK(false);
- return false;
- }
-
- if (now.IsBefore(expiration_time_)) {
- return true;
- }
-
- QUIC_CLIENT_HISTOGRAM_TIMES(
- "QuicClientHelloServerConfig.InvalidDuration",
- QuicTime::Delta::FromSeconds(now.ToUNIXSeconds() -
- expiration_time_.ToUNIXSeconds()),
- QuicTime::Delta::FromSeconds(60), // 1 min.
- QuicTime::Delta::FromSeconds(20 * 24 * 3600), // 20 days.
- 50, "");
- RecordInchoateClientHelloReason(SERVER_CONFIG_EXPIRED);
- return false;
-}
-
-bool QuicCryptoClientConfig::CachedState::IsEmpty() const {
- return server_config_.empty();
-}
-
-const CryptoHandshakeMessage*
-QuicCryptoClientConfig::CachedState::GetServerConfig() const {
- if (server_config_.empty()) {
- return nullptr;
- }
-
- if (!scfg_) {
- scfg_ = CryptoFramer::ParseMessage(server_config_);
- QUICHE_DCHECK(scfg_.get());
- }
- return scfg_.get();
-}
-
-QuicCryptoClientConfig::CachedState::ServerConfigState
-QuicCryptoClientConfig::CachedState::SetServerConfig(
- absl::string_view server_config,
- QuicWallTime now,
- QuicWallTime expiry_time,
- std::string* error_details) {
- const bool matches_existing = server_config == server_config_;
-
- // Even if the new server config matches the existing one, we still wish to
- // reject it if it has expired.
- std::unique_ptr<CryptoHandshakeMessage> new_scfg_storage;
- const CryptoHandshakeMessage* new_scfg;
-
- if (!matches_existing) {
- new_scfg_storage = CryptoFramer::ParseMessage(server_config);
- new_scfg = new_scfg_storage.get();
- } else {
- new_scfg = GetServerConfig();
- }
-
- if (!new_scfg) {
- *error_details = "SCFG invalid";
- return SERVER_CONFIG_INVALID;
- }
-
- if (expiry_time.IsZero()) {
- uint64_t expiry_seconds;
- if (new_scfg->GetUint64(kEXPY, &expiry_seconds) != QUIC_NO_ERROR) {
- *error_details = "SCFG missing EXPY";
- return SERVER_CONFIG_INVALID_EXPIRY;
- }
- expiration_time_ = QuicWallTime::FromUNIXSeconds(expiry_seconds);
- } else {
- expiration_time_ = expiry_time;
- }
-
- if (now.IsAfter(expiration_time_)) {
- *error_details = "SCFG has expired";
- return SERVER_CONFIG_EXPIRED;
- }
-
- if (!matches_existing) {
- server_config_ = std::string(server_config);
- SetProofInvalid();
- scfg_ = std::move(new_scfg_storage);
- }
- return SERVER_CONFIG_VALID;
-}
-
-void QuicCryptoClientConfig::CachedState::InvalidateServerConfig() {
- server_config_.clear();
- scfg_.reset();
- SetProofInvalid();
-}
-
-void QuicCryptoClientConfig::CachedState::SetProof(
- const std::vector<std::string>& certs,
- absl::string_view cert_sct,
- absl::string_view chlo_hash,
- absl::string_view signature) {
- bool has_changed = signature != server_config_sig_ ||
- chlo_hash != chlo_hash_ || certs_.size() != certs.size();
-
- if (!has_changed) {
- for (size_t i = 0; i < certs_.size(); i++) {
- if (certs_[i] != certs[i]) {
- has_changed = true;
- break;
- }
- }
- }
-
- if (!has_changed) {
- return;
- }
-
- // If the proof has changed then it needs to be revalidated.
- SetProofInvalid();
- certs_ = certs;
- cert_sct_ = std::string(cert_sct);
- chlo_hash_ = std::string(chlo_hash);
- server_config_sig_ = std::string(signature);
-}
-
-void QuicCryptoClientConfig::CachedState::Clear() {
- server_config_.clear();
- source_address_token_.clear();
- certs_.clear();
- cert_sct_.clear();
- chlo_hash_.clear();
- server_config_sig_.clear();
- server_config_valid_ = false;
- proof_verify_details_.reset();
- scfg_.reset();
- ++generation_counter_;
-}
-
-void QuicCryptoClientConfig::CachedState::ClearProof() {
- SetProofInvalid();
- certs_.clear();
- cert_sct_.clear();
- chlo_hash_.clear();
- server_config_sig_.clear();
-}
-
-void QuicCryptoClientConfig::CachedState::SetProofValid() {
- server_config_valid_ = true;
-}
-
-void QuicCryptoClientConfig::CachedState::SetProofInvalid() {
- server_config_valid_ = false;
- ++generation_counter_;
-}
-
-bool QuicCryptoClientConfig::CachedState::Initialize(
- absl::string_view server_config,
- absl::string_view source_address_token,
- const std::vector<std::string>& certs,
- const std::string& cert_sct,
- absl::string_view chlo_hash,
- absl::string_view signature,
- QuicWallTime now,
- QuicWallTime expiration_time) {
- QUICHE_DCHECK(server_config_.empty());
-
- if (server_config.empty()) {
- RecordDiskCacheServerConfigState(SERVER_CONFIG_EMPTY);
- return false;
- }
-
- std::string error_details;
- ServerConfigState state =
- SetServerConfig(server_config, now, expiration_time, &error_details);
- RecordDiskCacheServerConfigState(state);
- if (state != SERVER_CONFIG_VALID) {
- QUIC_DVLOG(1) << "SetServerConfig failed with " << error_details;
- return false;
- }
-
- chlo_hash_.assign(chlo_hash.data(), chlo_hash.size());
- server_config_sig_.assign(signature.data(), signature.size());
- source_address_token_.assign(source_address_token.data(),
- source_address_token.size());
- certs_ = certs;
- cert_sct_ = cert_sct;
- return true;
-}
-
-const std::string& QuicCryptoClientConfig::CachedState::server_config() const {
- return server_config_;
-}
-
-const std::string& QuicCryptoClientConfig::CachedState::source_address_token()
- const {
- return source_address_token_;
-}
-
-const std::vector<std::string>& QuicCryptoClientConfig::CachedState::certs()
- const {
- return certs_;
-}
-
-const std::string& QuicCryptoClientConfig::CachedState::cert_sct() const {
- return cert_sct_;
-}
-
-const std::string& QuicCryptoClientConfig::CachedState::chlo_hash() const {
- return chlo_hash_;
-}
-
-const std::string& QuicCryptoClientConfig::CachedState::signature() const {
- return server_config_sig_;
-}
-
-bool QuicCryptoClientConfig::CachedState::proof_valid() const {
- return server_config_valid_;
-}
-
-uint64_t QuicCryptoClientConfig::CachedState::generation_counter() const {
- return generation_counter_;
-}
-
-const ProofVerifyDetails*
-QuicCryptoClientConfig::CachedState::proof_verify_details() const {
- return proof_verify_details_.get();
-}
-
-void QuicCryptoClientConfig::CachedState::set_source_address_token(
- absl::string_view token) {
- source_address_token_ = std::string(token);
-}
-
-void QuicCryptoClientConfig::CachedState::set_cert_sct(
- absl::string_view cert_sct) {
- cert_sct_ = std::string(cert_sct);
-}
-
-void QuicCryptoClientConfig::CachedState::SetProofVerifyDetails(
- ProofVerifyDetails* details) {
- proof_verify_details_.reset(details);
-}
-
-void QuicCryptoClientConfig::CachedState::InitializeFrom(
- const QuicCryptoClientConfig::CachedState& other) {
- QUICHE_DCHECK(server_config_.empty());
- QUICHE_DCHECK(!server_config_valid_);
- server_config_ = other.server_config_;
- source_address_token_ = other.source_address_token_;
- certs_ = other.certs_;
- cert_sct_ = other.cert_sct_;
- chlo_hash_ = other.chlo_hash_;
- server_config_sig_ = other.server_config_sig_;
- server_config_valid_ = other.server_config_valid_;
- expiration_time_ = other.expiration_time_;
- if (other.proof_verify_details_ != nullptr) {
- proof_verify_details_.reset(other.proof_verify_details_->Clone());
- }
- ++generation_counter_;
-}
-
-void QuicCryptoClientConfig::SetDefaults() {
- // Key exchange methods.
- kexs = {kC255, kP256};
-
- // Authenticated encryption algorithms. Prefer AES-GCM if hardware-supported
- // fast implementation is available.
- if (EVP_has_aes_hardware() == 1) {
- aead = {kAESG, kCC20};
- } else {
- aead = {kCC20, kAESG};
- }
-}
-
-QuicCryptoClientConfig::CachedState* QuicCryptoClientConfig::LookupOrCreate(
- const QuicServerId& server_id) {
- auto it = cached_states_.find(server_id);
- if (it != cached_states_.end()) {
- return it->second.get();
- }
-
- CachedState* cached = new CachedState;
- cached_states_.insert(std::make_pair(server_id, absl::WrapUnique(cached)));
- bool cache_populated = PopulateFromCanonicalConfig(server_id, cached);
- QUIC_CLIENT_HISTOGRAM_BOOL(
- "QuicCryptoClientConfig.PopulatedFromCanonicalConfig", cache_populated,
- "");
- return cached;
-}
-
-void QuicCryptoClientConfig::ClearCachedStates(const ServerIdFilter& filter) {
- for (auto it = cached_states_.begin(); it != cached_states_.end(); ++it) {
- if (filter.Matches(it->first))
- it->second->Clear();
- }
-}
-
-void QuicCryptoClientConfig::FillInchoateClientHello(
- const QuicServerId& server_id,
- const ParsedQuicVersion preferred_version,
- const CachedState* cached,
- QuicRandom* rand,
- bool demand_x509_proof,
- QuicReferenceCountedPointer<QuicCryptoNegotiatedParameters> out_params,
- CryptoHandshakeMessage* out) const {
- out->set_tag(kCHLO);
- out->set_minimum_size(1);
-
- // Server name indication. We only send SNI if it's a valid domain name, as
- // per the spec.
- if (QuicHostnameUtils::IsValidSNI(server_id.host())) {
- out->SetStringPiece(kSNI, server_id.host());
- }
- out->SetVersion(kVER, preferred_version);
-
- if (!user_agent_id_.empty()) {
- out->SetStringPiece(kUAID, user_agent_id_);
- }
-
- if (!alpn_.empty()) {
- out->SetStringPiece(kALPN, alpn_);
- }
-
- // Even though this is an inchoate CHLO, send the SCID so that
- // the STK can be validated by the server.
- const CryptoHandshakeMessage* scfg = cached->GetServerConfig();
- if (scfg != nullptr) {
- absl::string_view scid;
- if (scfg->GetStringPiece(kSCID, &scid)) {
- out->SetStringPiece(kSCID, scid);
- }
- }
-
- if (!cached->source_address_token().empty()) {
- out->SetStringPiece(kSourceAddressTokenTag, cached->source_address_token());
- }
-
- if (!demand_x509_proof) {
- return;
- }
-
- char proof_nonce[32];
- rand->RandBytes(proof_nonce, ABSL_ARRAYSIZE(proof_nonce));
- out->SetStringPiece(
- kNONP, absl::string_view(proof_nonce, ABSL_ARRAYSIZE(proof_nonce)));
-
- out->SetVector(kPDMD, QuicTagVector{kX509});
-
- if (GetQuicRestartFlag(quic_no_common_cert_set)) {
- // Client only. No flag count.
- } else if (common_cert_sets) {
- out->SetStringPiece(kCCS, common_cert_sets->GetCommonHashes());
- }
-
- out->SetStringPiece(kCertificateSCTTag, "");
-
- const std::vector<std::string>& certs = cached->certs();
- // We save |certs| in the QuicCryptoNegotiatedParameters so that, if the
- // client config is being used for multiple connections, another connection
- // doesn't update the cached certificates and cause us to be unable to
- // process the server's compressed certificate chain.
- out_params->cached_certs = certs;
- if (!certs.empty()) {
- std::vector<uint64_t> hashes;
- hashes.reserve(certs.size());
- for (auto i = certs.begin(); i != certs.end(); ++i) {
- hashes.push_back(QuicUtils::FNV1a_64_Hash(*i));
- }
- out->SetVector(kCCRT, hashes);
- }
-}
-
-QuicErrorCode QuicCryptoClientConfig::FillClientHello(
- const QuicServerId& server_id,
- QuicConnectionId connection_id,
- const ParsedQuicVersion preferred_version,
- const ParsedQuicVersion actual_version,
- const CachedState* cached,
- QuicWallTime now,
- QuicRandom* rand,
- QuicReferenceCountedPointer<QuicCryptoNegotiatedParameters> out_params,
- CryptoHandshakeMessage* out,
- std::string* error_details) const {
- QUICHE_DCHECK(error_details != nullptr);
- QUIC_BUG_IF(quic_bug_12943_2,
- !QuicUtils::IsConnectionIdValidForVersion(
- connection_id, preferred_version.transport_version))
- << "FillClientHello: attempted to use connection ID " << connection_id
- << " which is invalid with version " << preferred_version;
-
- FillInchoateClientHello(server_id, preferred_version, cached, rand,
- /* demand_x509_proof= */ true, out_params, out);
-
- out->set_minimum_size(1);
-
- const CryptoHandshakeMessage* scfg = cached->GetServerConfig();
- if (!scfg) {
- // This should never happen as our caller should have checked
- // cached->IsComplete() before calling this function.
- *error_details = "Handshake not ready";
- return QUIC_CRYPTO_INTERNAL_ERROR;
- }
-
- absl::string_view scid;
- if (!scfg->GetStringPiece(kSCID, &scid)) {
- *error_details = "SCFG missing SCID";
- return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER;
- }
- out->SetStringPiece(kSCID, scid);
-
- out->SetStringPiece(kCertificateSCTTag, "");
-
- QuicTagVector their_aeads;
- QuicTagVector their_key_exchanges;
- if (scfg->GetTaglist(kAEAD, &their_aeads) != QUIC_NO_ERROR ||
- scfg->GetTaglist(kKEXS, &their_key_exchanges) != QUIC_NO_ERROR) {
- *error_details = "Missing AEAD or KEXS";
- return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER;
- }
-
- // AEAD: the work loads on the client and server are symmetric. Since the
- // client is more likely to be CPU-constrained, break the tie by favoring
- // the client's preference.
- // Key exchange: the client does more work than the server, so favor the
- // client's preference.
- size_t key_exchange_index;
- if (!FindMutualQuicTag(aead, their_aeads, &out_params->aead, nullptr) ||
- !FindMutualQuicTag(kexs, their_key_exchanges, &out_params->key_exchange,
- &key_exchange_index)) {
- *error_details = "Unsupported AEAD or KEXS";
- return QUIC_CRYPTO_NO_SUPPORT;
- }
- out->SetVector(kAEAD, QuicTagVector{out_params->aead});
- out->SetVector(kKEXS, QuicTagVector{out_params->key_exchange});
-
- absl::string_view public_value;
- if (scfg->GetNthValue24(kPUBS, key_exchange_index, &public_value) !=
- QUIC_NO_ERROR) {
- *error_details = "Missing public value";
- return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER;
- }
-
- absl::string_view orbit;
- if (!scfg->GetStringPiece(kORBT, &orbit) || orbit.size() != kOrbitSize) {
- *error_details = "SCFG missing OBIT";
- return QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND;
- }
-
- CryptoUtils::GenerateNonce(now, rand, orbit, &out_params->client_nonce);
- out->SetStringPiece(kNONC, out_params->client_nonce);
- if (!out_params->server_nonce.empty()) {
- out->SetStringPiece(kServerNonceTag, out_params->server_nonce);
- }
-
- switch (out_params->key_exchange) {
- case kC255:
- out_params->client_key_exchange = Curve25519KeyExchange::New(
- Curve25519KeyExchange::NewPrivateKey(rand));
- break;
- case kP256:
- out_params->client_key_exchange =
- P256KeyExchange::New(P256KeyExchange::NewPrivateKey());
- break;
- default:
- QUICHE_DCHECK(false);
- *error_details = "Configured to support an unknown key exchange";
- return QUIC_CRYPTO_INTERNAL_ERROR;
- }
-
- if (!out_params->client_key_exchange->CalculateSharedKeySync(
- public_value, &out_params->initial_premaster_secret)) {
- *error_details = "Key exchange failure";
- return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER;
- }
- out->SetStringPiece(kPUBS, out_params->client_key_exchange->public_value());
-
- const std::vector<std::string>& certs = cached->certs();
- if (certs.empty()) {
- *error_details = "No certs to calculate XLCT";
- return QUIC_CRYPTO_INTERNAL_ERROR;
- }
- out->SetValue(kXLCT, CryptoUtils::ComputeLeafCertHash(certs[0]));
-
- // Derive the symmetric keys and set up the encrypters and decrypters.
- // Set the following members of out_params:
- // out_params->hkdf_input_suffix
- // out_params->initial_crypters
- out_params->hkdf_input_suffix.clear();
- out_params->hkdf_input_suffix.append(connection_id.data(),
- connection_id.length());
- const QuicData& client_hello_serialized = out->GetSerialized();
- out_params->hkdf_input_suffix.append(client_hello_serialized.data(),
- client_hello_serialized.length());
- out_params->hkdf_input_suffix.append(cached->server_config());
- if (certs.empty()) {
- *error_details = "No certs found to include in KDF";
- return QUIC_CRYPTO_INTERNAL_ERROR;
- }
- out_params->hkdf_input_suffix.append(certs[0]);
-
- std::string hkdf_input;
- const size_t label_len = strlen(QuicCryptoConfig::kInitialLabel) + 1;
- hkdf_input.reserve(label_len + out_params->hkdf_input_suffix.size());
- hkdf_input.append(QuicCryptoConfig::kInitialLabel, label_len);
- hkdf_input.append(out_params->hkdf_input_suffix);
-
- std::string* subkey_secret = &out_params->initial_subkey_secret;
-
- if (!CryptoUtils::DeriveKeys(
- actual_version, out_params->initial_premaster_secret,
- out_params->aead, out_params->client_nonce, out_params->server_nonce,
- pre_shared_key_, hkdf_input, Perspective::IS_CLIENT,
- CryptoUtils::Diversification::Pending(),
- &out_params->initial_crypters, subkey_secret)) {
- *error_details = "Symmetric key setup failed";
- return QUIC_CRYPTO_SYMMETRIC_KEY_SETUP_FAILED;
- }
-
- return QUIC_NO_ERROR;
-}
-
-QuicErrorCode QuicCryptoClientConfig::CacheNewServerConfig(
- const CryptoHandshakeMessage& message,
- QuicWallTime now,
- QuicTransportVersion /*version*/,
- absl::string_view chlo_hash,
- const std::vector<std::string>& cached_certs,
- CachedState* cached,
- std::string* error_details) {
- QUICHE_DCHECK(error_details != nullptr);
-
- absl::string_view scfg;
- if (!message.GetStringPiece(kSCFG, &scfg)) {
- *error_details = "Missing SCFG";
- return QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND;
- }
-
- QuicWallTime expiration_time = QuicWallTime::Zero();
- uint64_t expiry_seconds;
- if (message.GetUint64(kSTTL, &expiry_seconds) == QUIC_NO_ERROR) {
- // Only cache configs for a maximum of 1 week.
- expiration_time = now.Add(QuicTime::Delta::FromSeconds(
- std::min(expiry_seconds, kNumSecondsPerWeek)));
- }
-
- CachedState::ServerConfigState state =
- cached->SetServerConfig(scfg, now, expiration_time, error_details);
- if (state == CachedState::SERVER_CONFIG_EXPIRED) {
- return QUIC_CRYPTO_SERVER_CONFIG_EXPIRED;
- }
- // TODO(rtenneti): Return more specific error code than returning
- // QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER.
- if (state != CachedState::SERVER_CONFIG_VALID) {
- return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER;
- }
-
- absl::string_view token;
- if (message.GetStringPiece(kSourceAddressTokenTag, &token)) {
- cached->set_source_address_token(token);
- }
-
- absl::string_view proof, cert_bytes, cert_sct;
- bool has_proof = message.GetStringPiece(kPROF, &proof);
- bool has_cert = message.GetStringPiece(kCertificateTag, &cert_bytes);
- if (has_proof && has_cert) {
- std::vector<std::string> certs;
- if (!CertCompressor::DecompressChain(cert_bytes, cached_certs,
- common_cert_sets, &certs)) {
- *error_details = "Certificate data invalid";
- return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER;
- }
-
- message.GetStringPiece(kCertificateSCTTag, &cert_sct);
- cached->SetProof(certs, cert_sct, chlo_hash, proof);
- } else {
- // Secure QUIC: clear existing proof as we have been sent a new SCFG
- // without matching proof/certs.
- cached->ClearProof();
-
- if (has_proof && !has_cert) {
- *error_details = "Certificate missing";
- return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER;
- }
-
- if (!has_proof && has_cert) {
- *error_details = "Proof missing";
- return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER;
- }
- }
-
- return QUIC_NO_ERROR;
-}
-
-QuicErrorCode QuicCryptoClientConfig::ProcessRejection(
- const CryptoHandshakeMessage& rej,
- QuicWallTime now,
- const QuicTransportVersion version,
- absl::string_view chlo_hash,
- CachedState* cached,
- QuicReferenceCountedPointer<QuicCryptoNegotiatedParameters> out_params,
- std::string* error_details) {
- QUICHE_DCHECK(error_details != nullptr);
-
- if (rej.tag() != kREJ) {
- *error_details = "Message is not REJ";
- return QUIC_CRYPTO_INTERNAL_ERROR;
- }
-
- QuicErrorCode error =
- CacheNewServerConfig(rej, now, version, chlo_hash,
- out_params->cached_certs, cached, error_details);
- if (error != QUIC_NO_ERROR) {
- return error;
- }
-
- absl::string_view nonce;
- if (rej.GetStringPiece(kServerNonceTag, &nonce)) {
- out_params->server_nonce = std::string(nonce);
- }
-
- return QUIC_NO_ERROR;
-}
-
-QuicErrorCode QuicCryptoClientConfig::ProcessServerHello(
- const CryptoHandshakeMessage& server_hello,
- QuicConnectionId /*connection_id*/,
- ParsedQuicVersion version,
- const ParsedQuicVersionVector& negotiated_versions,
- CachedState* cached,
- QuicReferenceCountedPointer<QuicCryptoNegotiatedParameters> out_params,
- std::string* error_details) {
- QUICHE_DCHECK(error_details != nullptr);
-
- QuicErrorCode valid = CryptoUtils::ValidateServerHello(
- server_hello, negotiated_versions, error_details);
- if (valid != QUIC_NO_ERROR) {
- return valid;
- }
-
- // Learn about updated source address tokens.
- absl::string_view token;
- if (server_hello.GetStringPiece(kSourceAddressTokenTag, &token)) {
- cached->set_source_address_token(token);
- }
-
- absl::string_view shlo_nonce;
- if (!server_hello.GetStringPiece(kServerNonceTag, &shlo_nonce)) {
- *error_details = "server hello missing server nonce";
- return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER;
- }
-
- // TODO(agl):
- // learn about updated SCFGs.
-
- absl::string_view public_value;
- if (!server_hello.GetStringPiece(kPUBS, &public_value)) {
- *error_details = "server hello missing forward secure public value";
- return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER;
- }
-
- if (!out_params->client_key_exchange->CalculateSharedKeySync(
- public_value, &out_params->forward_secure_premaster_secret)) {
- *error_details = "Key exchange failure";
- return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER;
- }
-
- std::string hkdf_input;
- const size_t label_len = strlen(QuicCryptoConfig::kForwardSecureLabel) + 1;
- hkdf_input.reserve(label_len + out_params->hkdf_input_suffix.size());
- hkdf_input.append(QuicCryptoConfig::kForwardSecureLabel, label_len);
- hkdf_input.append(out_params->hkdf_input_suffix);
-
- if (!CryptoUtils::DeriveKeys(
- version, out_params->forward_secure_premaster_secret,
- out_params->aead, out_params->client_nonce,
- shlo_nonce.empty() ? out_params->server_nonce : shlo_nonce,
- pre_shared_key_, hkdf_input, Perspective::IS_CLIENT,
- CryptoUtils::Diversification::Never(),
- &out_params->forward_secure_crypters, &out_params->subkey_secret)) {
- *error_details = "Symmetric key setup failed";
- return QUIC_CRYPTO_SYMMETRIC_KEY_SETUP_FAILED;
- }
-
- return QUIC_NO_ERROR;
-}
-
-QuicErrorCode QuicCryptoClientConfig::ProcessServerConfigUpdate(
- const CryptoHandshakeMessage& server_config_update,
- QuicWallTime now,
- const QuicTransportVersion version,
- absl::string_view chlo_hash,
- CachedState* cached,
- QuicReferenceCountedPointer<QuicCryptoNegotiatedParameters> out_params,
- std::string* error_details) {
- QUICHE_DCHECK(error_details != nullptr);
-
- if (server_config_update.tag() != kSCUP) {
- *error_details = "ServerConfigUpdate must have kSCUP tag.";
- return QUIC_INVALID_CRYPTO_MESSAGE_TYPE;
- }
- return CacheNewServerConfig(server_config_update, now, version, chlo_hash,
- out_params->cached_certs, cached, error_details);
-}
-
-ProofVerifier* QuicCryptoClientConfig::proof_verifier() const {
- return proof_verifier_.get();
-}
-
-SessionCache* QuicCryptoClientConfig::session_cache() const {
- return session_cache_.get();
-}
-
-ClientProofSource* QuicCryptoClientConfig::proof_source() const {
- return proof_source_.get();
-}
-
-void QuicCryptoClientConfig::set_proof_source(
- std::unique_ptr<ClientProofSource> proof_source) {
- proof_source_ = std::move(proof_source);
-}
-
-SSL_CTX* QuicCryptoClientConfig::ssl_ctx() const {
- return ssl_ctx_.get();
-}
-
-void QuicCryptoClientConfig::InitializeFrom(
- const QuicServerId& server_id,
- const QuicServerId& canonical_server_id,
- QuicCryptoClientConfig* canonical_crypto_config) {
- CachedState* canonical_cached =
- canonical_crypto_config->LookupOrCreate(canonical_server_id);
- if (!canonical_cached->proof_valid()) {
- return;
- }
- CachedState* cached = LookupOrCreate(server_id);
- cached->InitializeFrom(*canonical_cached);
-}
-
-void QuicCryptoClientConfig::AddCanonicalSuffix(const std::string& suffix) {
- canonical_suffixes_.push_back(suffix);
-}
-
-bool QuicCryptoClientConfig::PopulateFromCanonicalConfig(
- const QuicServerId& server_id, CachedState* cached) {
- QUICHE_DCHECK(cached->IsEmpty());
- size_t i = 0;
- for (; i < canonical_suffixes_.size(); ++i) {
- if (absl::EndsWithIgnoreCase(server_id.host(), canonical_suffixes_[i])) {
- break;
- }
- }
- if (i == canonical_suffixes_.size()) {
- return false;
- }
-
- QuicServerId suffix_server_id(canonical_suffixes_[i], server_id.port(),
- server_id.privacy_mode_enabled());
- auto it = canonical_server_map_.lower_bound(suffix_server_id);
- if (it == canonical_server_map_.end() || it->first != suffix_server_id) {
- // This is the first host we've seen which matches the suffix, so make it
- // canonical. Use |it| as position hint for faster insertion.
- canonical_server_map_.insert(
- it, std::make_pair(std::move(suffix_server_id), std::move(server_id)));
- return false;
- }
-
- const QuicServerId& canonical_server_id = it->second;
- CachedState* canonical_state = cached_states_[canonical_server_id].get();
- if (!canonical_state->proof_valid()) {
- return false;
- }
-
- // Update canonical version to point at the "most recent" entry.
- it->second = server_id;
-
- cached->InitializeFrom(*canonical_state);
- return true;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/quic_crypto_client_config.h b/chromium/net/third_party/quiche/src/quic/core/crypto/quic_crypto_client_config.h
deleted file mode 100644
index 9c71acafa08..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/quic_crypto_client_config.h
+++ /dev/null
@@ -1,479 +0,0 @@
-// Copyright 2013 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_CRYPTO_QUIC_CRYPTO_CLIENT_CONFIG_H_
-#define QUICHE_QUIC_CORE_CRYPTO_QUIC_CRYPTO_CLIENT_CONFIG_H_
-
-#include <cstdint>
-#include <map>
-#include <memory>
-#include <string>
-#include <vector>
-
-#include "absl/strings/string_view.h"
-#include "third_party/boringssl/src/include/openssl/base.h"
-#include "third_party/boringssl/src/include/openssl/ssl.h"
-#include "quic/core/crypto/client_proof_source.h"
-#include "quic/core/crypto/crypto_handshake.h"
-#include "quic/core/crypto/crypto_protocol.h"
-#include "quic/core/crypto/transport_parameters.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_server_id.h"
-#include "quic/platform/api/quic_export.h"
-#include "quic/platform/api/quic_reference_counted.h"
-
-namespace quic {
-
-class CryptoHandshakeMessage;
-class ProofVerifier;
-class ProofVerifyDetails;
-class QuicRandom;
-
-// QuicResumptionState stores the state a client needs for performing connection
-// resumption.
-struct QUIC_EXPORT_PRIVATE QuicResumptionState {
- // |tls_session| holds the cryptographic state necessary for a resumption. It
- // includes the ALPN negotiated on the connection where the ticket was
- // received.
- bssl::UniquePtr<SSL_SESSION> tls_session;
-
- // If the application using QUIC doesn't support 0-RTT handshakes or the
- // client didn't receive a 0-RTT capable session ticket from the server,
- // |transport_params| will be null. Otherwise, it will contain the transport
- // parameters received from the server on the original connection.
- std::unique_ptr<TransportParameters> transport_params = nullptr;
-
- // If |transport_params| is null, then |application_state| is ignored and
- // should be empty. |application_state| contains serialized state that the
- // client received from the server at the application layer that the client
- // needs to remember when performing a 0-RTT handshake.
- std::unique_ptr<ApplicationState> application_state = nullptr;
-
- // Opaque token received in NEW_TOKEN frame if any.
- std::string token;
-};
-
-// SessionCache is an interface for managing storing and retrieving
-// QuicResumptionState structs.
-class QUIC_EXPORT_PRIVATE SessionCache {
- public:
- virtual ~SessionCache() {}
-
- // Inserts |session|, |params|, and |application_states| into the cache, keyed
- // by |server_id|. Insert is first called after all three values are present.
- // The ownership of |session| is transferred to the cache, while other two are
- // copied. Multiple sessions might need to be inserted for a connection.
- // SessionCache implementations should support storing
- // multiple entries per server ID.
- virtual void Insert(const QuicServerId& server_id,
- bssl::UniquePtr<SSL_SESSION> session,
- const TransportParameters& params,
- const ApplicationState* application_state) = 0;
-
- // Lookup is called once at the beginning of each TLS handshake to potentially
- // provide the saved state both for the TLS handshake and for sending 0-RTT
- // data (if supported). Lookup may return a nullptr. Implementations should
- // delete cache entries after returning them in Lookup so that session tickets
- // are used only once.
- virtual std::unique_ptr<QuicResumptionState> Lookup(
- const QuicServerId& server_id, QuicWallTime now, const SSL_CTX* ctx) = 0;
-
- // Called when 0-RTT is rejected. Disables early data for all the TLS tickets
- // associated with |server_id|.
- virtual void ClearEarlyData(const QuicServerId& server_id) = 0;
-
- // Called when NEW_TOKEN frame is received.
- virtual void OnNewTokenReceived(const QuicServerId& server_id,
- absl::string_view token) = 0;
-
- // Called to remove expired entries.
- virtual void RemoveExpiredEntries(QuicWallTime now) = 0;
-
- // Clear the session cache.
- virtual void Clear() = 0;
-};
-
-// QuicCryptoClientConfig contains crypto-related configuration settings for a
-// client. Note that this object isn't thread-safe. It's designed to be used on
-// a single thread at a time.
-class QUIC_EXPORT_PRIVATE QuicCryptoClientConfig : public QuicCryptoConfig {
- public:
- // A CachedState contains the information that the client needs in order to
- // perform a 0-RTT handshake with a server. This information can be reused
- // over several connections to the same server.
- class QUIC_EXPORT_PRIVATE CachedState {
- public:
- // Enum to track if the server config is valid or not. If it is not valid,
- // it specifies why it is invalid.
- enum ServerConfigState {
- // WARNING: Do not change the numerical values of any of server config
- // state. Do not remove deprecated server config states - just comment
- // them as deprecated.
- SERVER_CONFIG_EMPTY = 0,
- SERVER_CONFIG_INVALID = 1,
- SERVER_CONFIG_CORRUPTED = 2,
- SERVER_CONFIG_EXPIRED = 3,
- SERVER_CONFIG_INVALID_EXPIRY = 4,
- SERVER_CONFIG_VALID = 5,
- // NOTE: Add new server config states only immediately above this line.
- // Make sure to update the QuicServerConfigState enum in
- // tools/metrics/histograms/histograms.xml accordingly.
- SERVER_CONFIG_COUNT
- };
-
- CachedState();
- CachedState(const CachedState&) = delete;
- CachedState& operator=(const CachedState&) = delete;
- ~CachedState();
-
- // IsComplete returns true if this object contains enough information to
- // perform a handshake with the server. |now| is used to judge whether any
- // cached server config has expired.
- bool IsComplete(QuicWallTime now) const;
-
- // IsEmpty returns true if |server_config_| is empty.
- bool IsEmpty() const;
-
- // GetServerConfig returns the parsed contents of |server_config|, or
- // nullptr if |server_config| is empty. The return value is owned by this
- // object and is destroyed when this object is.
- const CryptoHandshakeMessage* GetServerConfig() const;
-
- // SetServerConfig checks that |server_config| parses correctly and stores
- // it in |server_config_|. |now| is used to judge whether |server_config|
- // has expired.
- ServerConfigState SetServerConfig(absl::string_view server_config,
- QuicWallTime now,
- QuicWallTime expiry_time,
- std::string* error_details);
-
- // InvalidateServerConfig clears the cached server config (if any).
- void InvalidateServerConfig();
-
- // SetProof stores a cert chain, cert signed timestamp and signature.
- void SetProof(const std::vector<std::string>& certs,
- absl::string_view cert_sct,
- absl::string_view chlo_hash,
- absl::string_view signature);
-
- // Clears all the data.
- void Clear();
-
- // Clears the certificate chain and signature and invalidates the proof.
- void ClearProof();
-
- // SetProofValid records that the certificate chain and signature have been
- // validated and that it's safe to assume that the server is legitimate.
- // (Note: this does not check the chain or signature.)
- void SetProofValid();
-
- // If the server config or the proof has changed then it needs to be
- // revalidated. Helper function to keep server_config_valid_ and
- // generation_counter_ in sync.
- void SetProofInvalid();
-
- const std::string& server_config() const;
- const std::string& source_address_token() const;
- const std::vector<std::string>& certs() const;
- const std::string& cert_sct() const;
- const std::string& chlo_hash() const;
- const std::string& signature() const;
- bool proof_valid() const;
- uint64_t generation_counter() const;
- const ProofVerifyDetails* proof_verify_details() const;
-
- void set_source_address_token(absl::string_view token);
-
- void set_cert_sct(absl::string_view cert_sct);
-
- // SetProofVerifyDetails takes ownership of |details|.
- void SetProofVerifyDetails(ProofVerifyDetails* details);
-
- // Copy the |server_config_|, |source_address_token_|, |certs_|,
- // |expiration_time_|, |cert_sct_|, |chlo_hash_| and |server_config_sig_|
- // from the |other|. The remaining fields, |generation_counter_|,
- // |proof_verify_details_|, and |scfg_| remain unchanged.
- void InitializeFrom(const CachedState& other);
-
- // Initializes this cached state based on the arguments provided.
- // Returns false if there is a problem parsing the server config.
- bool Initialize(absl::string_view server_config,
- absl::string_view source_address_token,
- const std::vector<std::string>& certs,
- const std::string& cert_sct,
- absl::string_view chlo_hash,
- absl::string_view signature,
- QuicWallTime now,
- QuicWallTime expiration_time);
-
- private:
- std::string server_config_; // A serialized handshake message.
- std::string source_address_token_; // An opaque proof of IP ownership.
- std::vector<std::string> certs_; // A list of certificates in leaf-first
- // order.
- std::string cert_sct_; // Signed timestamp of the leaf cert.
- std::string chlo_hash_; // Hash of the CHLO message.
- std::string server_config_sig_; // A signature of |server_config_|.
- bool server_config_valid_; // True if |server_config_| is correctly
- // signed and |certs_| has been validated.
- QuicWallTime expiration_time_; // Time when the config is no longer valid.
- // Generation counter associated with the |server_config_|, |certs_| and
- // |server_config_sig_| combination. It is incremented whenever we set
- // server_config_valid_ to false.
- uint64_t generation_counter_;
-
- std::unique_ptr<ProofVerifyDetails> proof_verify_details_;
-
- // scfg contains the cached, parsed value of |server_config|.
- mutable std::unique_ptr<CryptoHandshakeMessage> scfg_;
- };
-
- // Used to filter server ids for partial config deletion.
- class QUIC_EXPORT_PRIVATE ServerIdFilter {
- public:
- virtual ~ServerIdFilter() {}
-
- // Returns true if |server_id| matches the filter.
- virtual bool Matches(const QuicServerId& server_id) const = 0;
- };
-
- // DEPRECATED: Use the constructor below instead.
- explicit QuicCryptoClientConfig(
- std::unique_ptr<ProofVerifier> proof_verifier);
- QuicCryptoClientConfig(std::unique_ptr<ProofVerifier> proof_verifier,
- std::unique_ptr<SessionCache> session_cache);
- QuicCryptoClientConfig(const QuicCryptoClientConfig&) = delete;
- QuicCryptoClientConfig& operator=(const QuicCryptoClientConfig&) = delete;
- ~QuicCryptoClientConfig();
-
- // LookupOrCreate returns a CachedState for the given |server_id|. If no such
- // CachedState currently exists, it will be created and cached.
- CachedState* LookupOrCreate(const QuicServerId& server_id);
-
- // Delete CachedState objects whose server ids match |filter| from
- // cached_states.
- void ClearCachedStates(const ServerIdFilter& filter);
-
- // FillInchoateClientHello sets |out| to be a CHLO message that elicits a
- // source-address token or SCFG from a server. If |cached| is non-nullptr, the
- // source-address token will be taken from it. |out_params| is used in order
- // to store the cached certs that were sent as hints to the server in
- // |out_params->cached_certs|. |preferred_version| is the version of the
- // QUIC protocol that this client chose to use initially. This allows the
- // server to detect downgrade attacks. If |demand_x509_proof| is true,
- // then |out| will include an X509 proof demand, and the associated
- // certificate related fields.
- void FillInchoateClientHello(
- const QuicServerId& server_id,
- const ParsedQuicVersion preferred_version,
- const CachedState* cached,
- QuicRandom* rand,
- bool demand_x509_proof,
- QuicReferenceCountedPointer<QuicCryptoNegotiatedParameters> out_params,
- CryptoHandshakeMessage* out) const;
-
- // FillClientHello sets |out| to be a CHLO message based on the configuration
- // of this object. This object must have cached enough information about
- // the server's hostname in order to perform a handshake. This can be checked
- // with the |IsComplete| member of |CachedState|.
- //
- // |now| and |rand| are used to generate the nonce and |out_params| is
- // filled with the results of the handshake that the server is expected to
- // accept. |preferred_version| is the version of the QUIC protocol that this
- // client chose to use initially. This allows the server to detect downgrade
- // attacks.
- //
- // If |channel_id_key| is not null, it is used to sign a secret value derived
- // from the client and server's keys, and the Channel ID public key and the
- // signature are placed in the CETV value of the CHLO.
- QuicErrorCode FillClientHello(
- const QuicServerId& server_id,
- QuicConnectionId connection_id,
- const ParsedQuicVersion preferred_version,
- const ParsedQuicVersion actual_version,
- const CachedState* cached,
- QuicWallTime now,
- QuicRandom* rand,
- QuicReferenceCountedPointer<QuicCryptoNegotiatedParameters> out_params,
- CryptoHandshakeMessage* out,
- std::string* error_details) const;
-
- // ProcessRejection processes a REJ message from a server and updates the
- // cached information about that server. After this, |IsComplete| may return
- // true for that server's CachedState. If the rejection message contains state
- // about a future handshake (i.e. an nonce value from the server), then it
- // will be saved in |out_params|. |now| is used to judge whether the server
- // config in the rejection message has expired.
- QuicErrorCode ProcessRejection(
- const CryptoHandshakeMessage& rej,
- QuicWallTime now,
- QuicTransportVersion version,
- absl::string_view chlo_hash,
- CachedState* cached,
- QuicReferenceCountedPointer<QuicCryptoNegotiatedParameters> out_params,
- std::string* error_details);
-
- // ProcessServerHello processes the message in |server_hello|, updates the
- // cached information about that server, writes the negotiated parameters to
- // |out_params| and returns QUIC_NO_ERROR. If |server_hello| is unacceptable
- // then it puts an error message in |error_details| and returns an error
- // code. |version| is the QUIC version for the current connection.
- // |negotiated_versions| contains the list of version, if any, that were
- // present in a version negotiation packet previously received from the
- // server. The contents of this list will be compared against the list of
- // versions provided in the VER tag of the server hello.
- QuicErrorCode ProcessServerHello(
- const CryptoHandshakeMessage& server_hello,
- QuicConnectionId connection_id,
- ParsedQuicVersion version,
- const ParsedQuicVersionVector& negotiated_versions,
- CachedState* cached,
- QuicReferenceCountedPointer<QuicCryptoNegotiatedParameters> out_params,
- std::string* error_details);
-
- // Processes the message in |server_config_update|, updating the cached source
- // address token, and server config.
- // If |server_config_update| is invalid then |error_details| will contain an
- // error message, and an error code will be returned. If all has gone well
- // QUIC_NO_ERROR is returned.
- QuicErrorCode ProcessServerConfigUpdate(
- const CryptoHandshakeMessage& server_config_update, QuicWallTime now,
- const QuicTransportVersion version, absl::string_view chlo_hash,
- CachedState* cached,
- QuicReferenceCountedPointer<QuicCryptoNegotiatedParameters> out_params,
- std::string* error_details);
-
- ProofVerifier* proof_verifier() const;
- SessionCache* session_cache() const;
- ClientProofSource* proof_source() const;
- void set_proof_source(std::unique_ptr<ClientProofSource> proof_source);
- SSL_CTX* ssl_ctx() const;
-
- // Initialize the CachedState from |canonical_crypto_config| for the
- // |canonical_server_id| as the initial CachedState for |server_id|. We will
- // copy config data only if |canonical_crypto_config| has valid proof.
- void InitializeFrom(const QuicServerId& server_id,
- const QuicServerId& canonical_server_id,
- QuicCryptoClientConfig* canonical_crypto_config);
-
- // Adds |suffix| as a domain suffix for which the server's crypto config
- // is expected to be shared among servers with the domain suffix. If a server
- // matches this suffix, then the server config from another server with the
- // suffix will be used to initialize the cached state for this server.
- void AddCanonicalSuffix(const std::string& suffix);
-
- // Saves the |user_agent_id| that will be passed in QUIC's CHLO message.
- void set_user_agent_id(const std::string& user_agent_id) {
- user_agent_id_ = user_agent_id;
- }
-
- // Returns the user_agent_id that will be provided in the client hello
- // handshake message.
- const std::string& user_agent_id() const { return user_agent_id_; }
-
- void set_tls_signature_algorithms(std::string signature_algorithms) {
- tls_signature_algorithms_ = std::move(signature_algorithms);
- }
-
- const absl::optional<std::string>& tls_signature_algorithms() const {
- return tls_signature_algorithms_;
- }
-
- // Saves the |alpn| that will be passed in QUIC's CHLO message.
- void set_alpn(const std::string& alpn) { alpn_ = alpn; }
-
- // Saves the pre-shared key used during the handshake.
- void set_pre_shared_key(absl::string_view psk) {
- pre_shared_key_ = std::string(psk);
- }
-
- // Returns the pre-shared key used during the handshake.
- const std::string& pre_shared_key() const { return pre_shared_key_; }
-
- bool pad_inchoate_hello() const { return pad_inchoate_hello_; }
- void set_pad_inchoate_hello(bool new_value) {
- pad_inchoate_hello_ = new_value;
- }
-
- bool pad_full_hello() const { return pad_full_hello_; }
- void set_pad_full_hello(bool new_value) { pad_full_hello_ = new_value; }
-
- SessionCache* mutable_session_cache() { return session_cache_.get(); }
-
- private:
- // Sets the members to reasonable, default values.
- void SetDefaults();
-
- // CacheNewServerConfig checks for SCFG, STK, PROF, and CRT tags in |message|,
- // verifies them, and stores them in the cached state if they validate.
- // This is used on receipt of a REJ from a server, or when a server sends
- // updated server config during a connection.
- QuicErrorCode CacheNewServerConfig(
- const CryptoHandshakeMessage& message,
- QuicWallTime now,
- QuicTransportVersion version,
- absl::string_view chlo_hash,
- const std::vector<std::string>& cached_certs,
- CachedState* cached,
- std::string* error_details);
-
- // If the suffix of the hostname in |server_id| is in |canonical_suffixes_|,
- // then populate |cached| with the canonical cached state from
- // |canonical_server_map_| for that suffix. Returns true if |cached| is
- // initialized with canonical cached state.
- bool PopulateFromCanonicalConfig(const QuicServerId& server_id,
- CachedState* cached);
-
- // cached_states_ maps from the server_id to the cached information about
- // that server.
- std::map<QuicServerId, std::unique_ptr<CachedState>> cached_states_;
-
- // Contains a map of servers which could share the same server config. Map
- // from a canonical host suffix/port/scheme to a representative server with
- // the canonical suffix, which has a plausible set of initial certificates
- // (or at least server public key).
- std::map<QuicServerId, QuicServerId> canonical_server_map_;
-
- // Contains list of suffixes (for exmaple ".c.youtube.com",
- // ".googlevideo.com") of canonical hostnames.
- std::vector<std::string> canonical_suffixes_;
-
- std::unique_ptr<ProofVerifier> proof_verifier_;
- std::unique_ptr<SessionCache> session_cache_;
- std::unique_ptr<ClientProofSource> proof_source_;
-
- bssl::UniquePtr<SSL_CTX> ssl_ctx_;
-
- // The |user_agent_id_| passed in QUIC's CHLO message.
- std::string user_agent_id_;
-
- // The |alpn_| passed in QUIC's CHLO message.
- std::string alpn_;
-
- // If non-empty, the client will operate in the pre-shared key mode by
- // incorporating |pre_shared_key_| into the key schedule.
- std::string pre_shared_key_;
-
- // If set, configure the client to use the specified signature algorithms, via
- // SSL_set1_sigalgs_list. TLS only.
- absl::optional<std::string> tls_signature_algorithms_;
-
- // In QUIC, technically, client hello should be fully padded.
- // However, fully padding on slow network connection (e.g. 50kbps) can add
- // 150ms latency to one roundtrip. Therefore, you can disable padding of
- // individual messages. It is recommend to leave at least one message in
- // each direction fully padded (e.g. full CHLO and SHLO), but if you know
- // the lower-bound MTU, you don't need to pad all of them (keep in mind that
- // it's not OK to do it according to the standard).
- //
- // Also, if you disable padding, you must disable (change) the
- // anti-amplification protection. You should only do so if you have some
- // other means of verifying the client.
- bool pad_inchoate_hello_ = true;
- bool pad_full_hello_ = true;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_CRYPTO_QUIC_CRYPTO_CLIENT_CONFIG_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/quic_crypto_client_config_test.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/quic_crypto_client_config_test.cc
deleted file mode 100644
index 5bcf01cd074..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/quic_crypto_client_config_test.cc
+++ /dev/null
@@ -1,550 +0,0 @@
-// Copyright 2013 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 "quic/core/crypto/quic_crypto_client_config.h"
-
-#include <string>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/crypto/proof_verifier.h"
-#include "quic/core/quic_server_id.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_expect_bug.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/crypto_test_utils.h"
-#include "quic/test_tools/mock_random.h"
-#include "quic/test_tools/quic_test_utils.h"
-
-using testing::StartsWith;
-
-namespace quic {
-namespace test {
-namespace {
-
-class TestProofVerifyDetails : public ProofVerifyDetails {
- ~TestProofVerifyDetails() override {}
-
- // ProofVerifyDetails implementation
- ProofVerifyDetails* Clone() const override {
- return new TestProofVerifyDetails;
- }
-};
-
-class OneServerIdFilter : public QuicCryptoClientConfig::ServerIdFilter {
- public:
- explicit OneServerIdFilter(const QuicServerId* server_id)
- : server_id_(*server_id) {}
-
- bool Matches(const QuicServerId& server_id) const override {
- return server_id == server_id_;
- }
-
- private:
- const QuicServerId server_id_;
-};
-
-class AllServerIdsFilter : public QuicCryptoClientConfig::ServerIdFilter {
- public:
- bool Matches(const QuicServerId& /*server_id*/) const override {
- return true;
- }
-};
-
-} // namespace
-
-class QuicCryptoClientConfigTest : public QuicTest {};
-
-TEST_F(QuicCryptoClientConfigTest, CachedState_IsEmpty) {
- QuicCryptoClientConfig::CachedState state;
- EXPECT_TRUE(state.IsEmpty());
-}
-
-TEST_F(QuicCryptoClientConfigTest, CachedState_IsComplete) {
- QuicCryptoClientConfig::CachedState state;
- EXPECT_FALSE(state.IsComplete(QuicWallTime::FromUNIXSeconds(0)));
-}
-
-TEST_F(QuicCryptoClientConfigTest, CachedState_GenerationCounter) {
- QuicCryptoClientConfig::CachedState state;
- EXPECT_EQ(0u, state.generation_counter());
- state.SetProofInvalid();
- EXPECT_EQ(1u, state.generation_counter());
-}
-
-TEST_F(QuicCryptoClientConfigTest, CachedState_SetProofVerifyDetails) {
- QuicCryptoClientConfig::CachedState state;
- EXPECT_TRUE(state.proof_verify_details() == nullptr);
- ProofVerifyDetails* details = new TestProofVerifyDetails;
- state.SetProofVerifyDetails(details);
- EXPECT_EQ(details, state.proof_verify_details());
-}
-
-TEST_F(QuicCryptoClientConfigTest, CachedState_InitializeFrom) {
- QuicCryptoClientConfig::CachedState state;
- QuicCryptoClientConfig::CachedState other;
- state.set_source_address_token("TOKEN");
- // TODO(rch): Populate other fields of |state|.
- other.InitializeFrom(state);
- EXPECT_EQ(state.server_config(), other.server_config());
- EXPECT_EQ(state.source_address_token(), other.source_address_token());
- EXPECT_EQ(state.certs(), other.certs());
- EXPECT_EQ(1u, other.generation_counter());
-}
-
-TEST_F(QuicCryptoClientConfigTest, InchoateChlo) {
- QuicCryptoClientConfig::CachedState state;
- QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting());
- config.set_user_agent_id("quic-tester");
- config.set_alpn("hq");
- QuicReferenceCountedPointer<QuicCryptoNegotiatedParameters> params(
- new QuicCryptoNegotiatedParameters);
- CryptoHandshakeMessage msg;
- QuicServerId server_id("www.google.com", 443, false);
- MockRandom rand;
- config.FillInchoateClientHello(server_id, QuicVersionMax(), &state, &rand,
- /* demand_x509_proof= */ true, params, &msg);
-
- QuicVersionLabel cver;
- EXPECT_THAT(msg.GetVersionLabel(kVER, &cver), IsQuicNoError());
- EXPECT_EQ(CreateQuicVersionLabel(QuicVersionMax()), cver);
- absl::string_view proof_nonce;
- EXPECT_TRUE(msg.GetStringPiece(kNONP, &proof_nonce));
- EXPECT_EQ(std::string(32, 'r'), proof_nonce);
- absl::string_view user_agent_id;
- EXPECT_TRUE(msg.GetStringPiece(kUAID, &user_agent_id));
- EXPECT_EQ("quic-tester", user_agent_id);
- absl::string_view alpn;
- EXPECT_TRUE(msg.GetStringPiece(kALPN, &alpn));
- EXPECT_EQ("hq", alpn);
- EXPECT_EQ(msg.minimum_size(), 1u);
-}
-
-TEST_F(QuicCryptoClientConfigTest, InchoateChloIsNotPadded) {
- QuicCryptoClientConfig::CachedState state;
- QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting());
- config.set_pad_inchoate_hello(false);
- config.set_user_agent_id("quic-tester");
- config.set_alpn("hq");
- QuicReferenceCountedPointer<QuicCryptoNegotiatedParameters> params(
- new QuicCryptoNegotiatedParameters);
- CryptoHandshakeMessage msg;
- QuicServerId server_id("www.google.com", 443, false);
- MockRandom rand;
- config.FillInchoateClientHello(server_id, QuicVersionMax(), &state, &rand,
- /* demand_x509_proof= */ true, params, &msg);
-
- EXPECT_EQ(msg.minimum_size(), 1u);
-}
-
-// Make sure AES-GCM is the preferred encryption algorithm if it has hardware
-// acceleration.
-TEST_F(QuicCryptoClientConfigTest, PreferAesGcm) {
- QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting());
- if (EVP_has_aes_hardware() == 1) {
- EXPECT_EQ(kAESG, config.aead[0]);
- } else {
- EXPECT_EQ(kCC20, config.aead[0]);
- }
-}
-
-TEST_F(QuicCryptoClientConfigTest, InchoateChloSecure) {
- QuicCryptoClientConfig::CachedState state;
- QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting());
- QuicReferenceCountedPointer<QuicCryptoNegotiatedParameters> params(
- new QuicCryptoNegotiatedParameters);
- CryptoHandshakeMessage msg;
- QuicServerId server_id("www.google.com", 443, false);
- MockRandom rand;
- config.FillInchoateClientHello(server_id, QuicVersionMax(), &state, &rand,
- /* demand_x509_proof= */ true, params, &msg);
-
- QuicTag pdmd;
- EXPECT_THAT(msg.GetUint32(kPDMD, &pdmd), IsQuicNoError());
- EXPECT_EQ(kX509, pdmd);
- absl::string_view scid;
- EXPECT_FALSE(msg.GetStringPiece(kSCID, &scid));
-}
-
-TEST_F(QuicCryptoClientConfigTest, InchoateChloSecureWithSCIDNoEXPY) {
- // Test that a config with no EXPY is still valid when a non-zero
- // expiry time is passed in.
- QuicCryptoClientConfig::CachedState state;
- CryptoHandshakeMessage scfg;
- scfg.set_tag(kSCFG);
- scfg.SetStringPiece(kSCID, "12345678");
- std::string details;
- QuicWallTime now = QuicWallTime::FromUNIXSeconds(1);
- QuicWallTime expiry = QuicWallTime::FromUNIXSeconds(2);
- state.SetServerConfig(scfg.GetSerialized().AsStringPiece(), now, expiry,
- &details);
- EXPECT_FALSE(state.IsEmpty());
-
- QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting());
- QuicReferenceCountedPointer<QuicCryptoNegotiatedParameters> params(
- new QuicCryptoNegotiatedParameters);
- CryptoHandshakeMessage msg;
- QuicServerId server_id("www.google.com", 443, false);
- MockRandom rand;
- config.FillInchoateClientHello(server_id, QuicVersionMax(), &state, &rand,
- /* demand_x509_proof= */ true, params, &msg);
-
- absl::string_view scid;
- EXPECT_TRUE(msg.GetStringPiece(kSCID, &scid));
- EXPECT_EQ("12345678", scid);
-}
-
-TEST_F(QuicCryptoClientConfigTest, InchoateChloSecureWithSCID) {
- QuicCryptoClientConfig::CachedState state;
- CryptoHandshakeMessage scfg;
- scfg.set_tag(kSCFG);
- uint64_t future = 1;
- scfg.SetValue(kEXPY, future);
- scfg.SetStringPiece(kSCID, "12345678");
- std::string details;
- state.SetServerConfig(scfg.GetSerialized().AsStringPiece(),
- QuicWallTime::FromUNIXSeconds(1),
- QuicWallTime::FromUNIXSeconds(0), &details);
- EXPECT_FALSE(state.IsEmpty());
-
- QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting());
- QuicReferenceCountedPointer<QuicCryptoNegotiatedParameters> params(
- new QuicCryptoNegotiatedParameters);
- CryptoHandshakeMessage msg;
- QuicServerId server_id("www.google.com", 443, false);
- MockRandom rand;
- config.FillInchoateClientHello(server_id, QuicVersionMax(), &state, &rand,
- /* demand_x509_proof= */ true, params, &msg);
-
- absl::string_view scid;
- EXPECT_TRUE(msg.GetStringPiece(kSCID, &scid));
- EXPECT_EQ("12345678", scid);
-}
-
-TEST_F(QuicCryptoClientConfigTest, FillClientHello) {
- QuicCryptoClientConfig::CachedState state;
- QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting());
- QuicReferenceCountedPointer<QuicCryptoNegotiatedParameters> params(
- new QuicCryptoNegotiatedParameters);
- QuicConnectionId kConnectionId = TestConnectionId(1234);
- std::string error_details;
- MockRandom rand;
- CryptoHandshakeMessage chlo;
- QuicServerId server_id("www.google.com", 443, false);
- config.FillClientHello(server_id, kConnectionId, QuicVersionMax(),
- QuicVersionMax(), &state, QuicWallTime::Zero(), &rand,
- params, &chlo, &error_details);
-
- // Verify that the version label has been set correctly in the CHLO.
- QuicVersionLabel cver;
- EXPECT_THAT(chlo.GetVersionLabel(kVER, &cver), IsQuicNoError());
- EXPECT_EQ(CreateQuicVersionLabel(QuicVersionMax()), cver);
-}
-
-TEST_F(QuicCryptoClientConfigTest, FillClientHelloNoPadding) {
- QuicCryptoClientConfig::CachedState state;
- QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting());
- config.set_pad_full_hello(false);
- QuicReferenceCountedPointer<QuicCryptoNegotiatedParameters> params(
- new QuicCryptoNegotiatedParameters);
- QuicConnectionId kConnectionId = TestConnectionId(1234);
- std::string error_details;
- MockRandom rand;
- CryptoHandshakeMessage chlo;
- QuicServerId server_id("www.google.com", 443, false);
- config.FillClientHello(server_id, kConnectionId, QuicVersionMax(),
- QuicVersionMax(), &state, QuicWallTime::Zero(), &rand,
- params, &chlo, &error_details);
-
- // Verify that the version label has been set correctly in the CHLO.
- QuicVersionLabel cver;
- EXPECT_THAT(chlo.GetVersionLabel(kVER, &cver), IsQuicNoError());
- EXPECT_EQ(CreateQuicVersionLabel(QuicVersionMax()), cver);
- EXPECT_EQ(chlo.minimum_size(), 1u);
-}
-
-TEST_F(QuicCryptoClientConfigTest, ProcessServerDowngradeAttack) {
- ParsedQuicVersionVector supported_versions = AllSupportedVersions();
- if (supported_versions.size() == 1) {
- // No downgrade attack is possible if the client only supports one version.
- return;
- }
-
- ParsedQuicVersionVector supported_version_vector;
- for (size_t i = supported_versions.size(); i > 0; --i) {
- supported_version_vector.push_back(supported_versions[i - 1]);
- }
-
- CryptoHandshakeMessage msg;
- msg.set_tag(kSHLO);
- msg.SetVersionVector(kVER, supported_version_vector);
-
- QuicCryptoClientConfig::CachedState cached;
- QuicReferenceCountedPointer<QuicCryptoNegotiatedParameters> out_params(
- new QuicCryptoNegotiatedParameters);
- std::string error;
- QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting());
- EXPECT_THAT(config.ProcessServerHello(
- msg, EmptyQuicConnectionId(), supported_versions.front(),
- supported_versions, &cached, out_params, &error),
- IsError(QUIC_VERSION_NEGOTIATION_MISMATCH));
- EXPECT_THAT(error, StartsWith("Downgrade attack detected: ServerVersions"));
-}
-
-TEST_F(QuicCryptoClientConfigTest, InitializeFrom) {
- QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting());
- QuicServerId canonical_server_id("www.google.com", 443, false);
- QuicCryptoClientConfig::CachedState* state =
- config.LookupOrCreate(canonical_server_id);
- // TODO(rch): Populate other fields of |state|.
- state->set_source_address_token("TOKEN");
- state->SetProofValid();
-
- QuicServerId other_server_id("mail.google.com", 443, false);
- config.InitializeFrom(other_server_id, canonical_server_id, &config);
- QuicCryptoClientConfig::CachedState* other =
- config.LookupOrCreate(other_server_id);
-
- EXPECT_EQ(state->server_config(), other->server_config());
- EXPECT_EQ(state->source_address_token(), other->source_address_token());
- EXPECT_EQ(state->certs(), other->certs());
- EXPECT_EQ(1u, other->generation_counter());
-}
-
-TEST_F(QuicCryptoClientConfigTest, Canonical) {
- QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting());
- config.AddCanonicalSuffix(".google.com");
- QuicServerId canonical_id1("www.google.com", 443, false);
- QuicServerId canonical_id2("mail.google.com", 443, false);
- QuicCryptoClientConfig::CachedState* state =
- config.LookupOrCreate(canonical_id1);
- // TODO(rch): Populate other fields of |state|.
- state->set_source_address_token("TOKEN");
- state->SetProofValid();
-
- QuicCryptoClientConfig::CachedState* other =
- config.LookupOrCreate(canonical_id2);
-
- EXPECT_TRUE(state->IsEmpty());
- EXPECT_EQ(state->server_config(), other->server_config());
- EXPECT_EQ(state->source_address_token(), other->source_address_token());
- EXPECT_EQ(state->certs(), other->certs());
- EXPECT_EQ(1u, other->generation_counter());
-
- QuicServerId different_id("mail.google.org", 443, false);
- EXPECT_TRUE(config.LookupOrCreate(different_id)->IsEmpty());
-}
-
-TEST_F(QuicCryptoClientConfigTest, CanonicalNotUsedIfNotValid) {
- QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting());
- config.AddCanonicalSuffix(".google.com");
- QuicServerId canonical_id1("www.google.com", 443, false);
- QuicServerId canonical_id2("mail.google.com", 443, false);
- QuicCryptoClientConfig::CachedState* state =
- config.LookupOrCreate(canonical_id1);
- // TODO(rch): Populate other fields of |state|.
- state->set_source_address_token("TOKEN");
-
- // Do not set the proof as valid, and check that it is not used
- // as a canonical entry.
- EXPECT_TRUE(config.LookupOrCreate(canonical_id2)->IsEmpty());
-}
-
-TEST_F(QuicCryptoClientConfigTest, ClearCachedStates) {
- QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting());
-
- // Create two states on different origins.
- struct TestCase {
- TestCase(const std::string& host, QuicCryptoClientConfig* config)
- : server_id(host, 443, false),
- state(config->LookupOrCreate(server_id)) {
- // TODO(rch): Populate other fields of |state|.
- CryptoHandshakeMessage scfg;
- scfg.set_tag(kSCFG);
- uint64_t future = 1;
- scfg.SetValue(kEXPY, future);
- scfg.SetStringPiece(kSCID, "12345678");
- std::string details;
- state->SetServerConfig(scfg.GetSerialized().AsStringPiece(),
- QuicWallTime::FromUNIXSeconds(0),
- QuicWallTime::FromUNIXSeconds(future), &details);
-
- std::vector<std::string> certs(1);
- certs[0] = "Hello Cert for " + host;
- state->SetProof(certs, "cert_sct", "chlo_hash", "signature");
- state->set_source_address_token("TOKEN");
- state->SetProofValid();
-
- // The generation counter starts at 2, because proof has been once
- // invalidated in SetServerConfig().
- EXPECT_EQ(2u, state->generation_counter());
- }
-
- QuicServerId server_id;
- QuicCryptoClientConfig::CachedState* state;
- } test_cases[] = {TestCase("www.google.com", &config),
- TestCase("www.example.com", &config)};
-
- // Verify LookupOrCreate returns the same data.
- for (const TestCase& test_case : test_cases) {
- QuicCryptoClientConfig::CachedState* other =
- config.LookupOrCreate(test_case.server_id);
- EXPECT_EQ(test_case.state, other);
- EXPECT_EQ(2u, other->generation_counter());
- }
-
- // Clear the cached state for www.google.com.
- OneServerIdFilter google_com_filter(&test_cases[0].server_id);
- config.ClearCachedStates(google_com_filter);
-
- // Verify LookupOrCreate doesn't have any data for google.com.
- QuicCryptoClientConfig::CachedState* cleared_cache =
- config.LookupOrCreate(test_cases[0].server_id);
-
- EXPECT_EQ(test_cases[0].state, cleared_cache);
- EXPECT_FALSE(cleared_cache->proof_valid());
- EXPECT_TRUE(cleared_cache->server_config().empty());
- EXPECT_TRUE(cleared_cache->certs().empty());
- EXPECT_TRUE(cleared_cache->cert_sct().empty());
- EXPECT_TRUE(cleared_cache->signature().empty());
- EXPECT_EQ(3u, cleared_cache->generation_counter());
-
- // But it still does for www.example.com.
- QuicCryptoClientConfig::CachedState* existing_cache =
- config.LookupOrCreate(test_cases[1].server_id);
-
- EXPECT_EQ(test_cases[1].state, existing_cache);
- EXPECT_TRUE(existing_cache->proof_valid());
- EXPECT_FALSE(existing_cache->server_config().empty());
- EXPECT_FALSE(existing_cache->certs().empty());
- EXPECT_FALSE(existing_cache->cert_sct().empty());
- EXPECT_FALSE(existing_cache->signature().empty());
- EXPECT_EQ(2u, existing_cache->generation_counter());
-
- // Clear all cached states.
- AllServerIdsFilter all_server_ids;
- config.ClearCachedStates(all_server_ids);
-
- // The data for www.example.com should now be cleared as well.
- cleared_cache = config.LookupOrCreate(test_cases[1].server_id);
-
- EXPECT_EQ(test_cases[1].state, cleared_cache);
- EXPECT_FALSE(cleared_cache->proof_valid());
- EXPECT_TRUE(cleared_cache->server_config().empty());
- EXPECT_TRUE(cleared_cache->certs().empty());
- EXPECT_TRUE(cleared_cache->cert_sct().empty());
- EXPECT_TRUE(cleared_cache->signature().empty());
- EXPECT_EQ(3u, cleared_cache->generation_counter());
-}
-
-TEST_F(QuicCryptoClientConfigTest, ProcessReject) {
- CryptoHandshakeMessage rej;
- crypto_test_utils::FillInDummyReject(&rej);
-
- // Now process the rejection.
- QuicCryptoClientConfig::CachedState cached;
- QuicReferenceCountedPointer<QuicCryptoNegotiatedParameters> out_params(
- new QuicCryptoNegotiatedParameters);
- std::string error;
- QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting());
- EXPECT_THAT(
- config.ProcessRejection(
- rej, QuicWallTime::FromUNIXSeconds(0),
- AllSupportedVersionsWithQuicCrypto().front().transport_version, "",
- &cached, out_params, &error),
- IsQuicNoError());
-}
-
-TEST_F(QuicCryptoClientConfigTest, ProcessRejectWithLongTTL) {
- CryptoHandshakeMessage rej;
- crypto_test_utils::FillInDummyReject(&rej);
- QuicTime::Delta one_week = QuicTime::Delta::FromSeconds(kNumSecondsPerWeek);
- int64_t long_ttl = 3 * one_week.ToSeconds();
- rej.SetValue(kSTTL, long_ttl);
-
- // Now process the rejection.
- QuicCryptoClientConfig::CachedState cached;
- QuicReferenceCountedPointer<QuicCryptoNegotiatedParameters> out_params(
- new QuicCryptoNegotiatedParameters);
- std::string error;
- QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting());
- EXPECT_THAT(
- config.ProcessRejection(
- rej, QuicWallTime::FromUNIXSeconds(0),
- AllSupportedVersionsWithQuicCrypto().front().transport_version, "",
- &cached, out_params, &error),
- IsQuicNoError());
- cached.SetProofValid();
- EXPECT_FALSE(cached.IsComplete(QuicWallTime::FromUNIXSeconds(long_ttl)));
- EXPECT_FALSE(
- cached.IsComplete(QuicWallTime::FromUNIXSeconds(one_week.ToSeconds())));
- EXPECT_TRUE(cached.IsComplete(
- QuicWallTime::FromUNIXSeconds(one_week.ToSeconds() - 1)));
-}
-
-TEST_F(QuicCryptoClientConfigTest, ServerNonceinSHLO) {
- // Test that the server must include a nonce in the SHLO.
- CryptoHandshakeMessage msg;
- msg.set_tag(kSHLO);
- // Choose the latest version.
- ParsedQuicVersionVector supported_versions;
- ParsedQuicVersion version = AllSupportedVersions().front();
- supported_versions.push_back(version);
- msg.SetVersionVector(kVER, supported_versions);
-
- QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting());
- QuicCryptoClientConfig::CachedState cached;
- QuicReferenceCountedPointer<QuicCryptoNegotiatedParameters> out_params(
- new QuicCryptoNegotiatedParameters);
- std::string error_details;
- EXPECT_THAT(config.ProcessServerHello(msg, EmptyQuicConnectionId(), version,
- supported_versions, &cached, out_params,
- &error_details),
- IsError(QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER));
- EXPECT_EQ("server hello missing server nonce", error_details);
-}
-
-// Test that PopulateFromCanonicalConfig() handles the case of multiple entries
-// in |canonical_server_map_|.
-TEST_F(QuicCryptoClientConfigTest, MultipleCanonicalEntries) {
- QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting());
- config.AddCanonicalSuffix(".google.com");
- QuicServerId canonical_server_id1("www.google.com", 443, false);
- QuicCryptoClientConfig::CachedState* state1 =
- config.LookupOrCreate(canonical_server_id1);
-
- CryptoHandshakeMessage scfg;
- scfg.set_tag(kSCFG);
- scfg.SetStringPiece(kSCID, "12345678");
- std::string details;
- QuicWallTime now = QuicWallTime::FromUNIXSeconds(1);
- QuicWallTime expiry = QuicWallTime::FromUNIXSeconds(2);
- state1->SetServerConfig(scfg.GetSerialized().AsStringPiece(), now, expiry,
- &details);
- state1->set_source_address_token("TOKEN");
- state1->SetProofValid();
- EXPECT_FALSE(state1->IsEmpty());
-
- // This will have the same |suffix_server_id| as |canonical_server_id1|,
- // therefore |*state2| will be initialized from |*state1|.
- QuicServerId canonical_server_id2("mail.google.com", 443, false);
- QuicCryptoClientConfig::CachedState* state2 =
- config.LookupOrCreate(canonical_server_id2);
- EXPECT_FALSE(state2->IsEmpty());
- const CryptoHandshakeMessage* const scfg2 = state2->GetServerConfig();
- ASSERT_TRUE(scfg2);
- EXPECT_EQ(kSCFG, scfg2->tag());
-
- // With a different |suffix_server_id|, this will return an empty CachedState.
- config.AddCanonicalSuffix(".example.com");
- QuicServerId canonical_server_id3("www.example.com", 443, false);
- QuicCryptoClientConfig::CachedState* state3 =
- config.LookupOrCreate(canonical_server_id3);
- EXPECT_TRUE(state3->IsEmpty());
- const CryptoHandshakeMessage* const scfg3 = state3->GetServerConfig();
- EXPECT_FALSE(scfg3);
-}
-
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/quic_crypto_proof.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/quic_crypto_proof.cc
deleted file mode 100644
index 1e5f3c4a965..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/quic_crypto_proof.cc
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/crypto/quic_crypto_proof.h"
-
-namespace quic {
-
-QuicCryptoProof::QuicCryptoProof()
- : send_expect_ct_header(false), cert_matched_sni(false) {}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/quic_crypto_proof.h b/chromium/net/third_party/quiche/src/quic/core/crypto/quic_crypto_proof.h
deleted file mode 100644
index 53e09612857..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/quic_crypto_proof.h
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_CRYPTO_QUIC_CRYPTO_PROOF_H_
-#define QUICHE_QUIC_CORE_CRYPTO_QUIC_CRYPTO_PROOF_H_
-
-#include <string>
-
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// Contains the crypto-related data provided by ProofSource
-struct QUIC_EXPORT_PRIVATE QuicCryptoProof {
- QuicCryptoProof();
-
- // Signature generated by ProofSource
- std::string signature;
- // SCTList (RFC6962) to be sent to the client, if it supports receiving it.
- std::string leaf_cert_scts;
- // Should the Expect-CT header be sent on the connection where the
- // certificate is used.
- bool send_expect_ct_header;
- // Did the selected leaf certificate contain a SubjectAltName that included
- // the requested SNI.
- bool cert_matched_sni;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_CRYPTO_QUIC_CRYPTO_PROOF_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/quic_crypto_server_config.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/quic_crypto_server_config.cc
deleted file mode 100644
index 71c177552a0..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/quic_crypto_server_config.cc
+++ /dev/null
@@ -1,1899 +0,0 @@
-// Copyright 2013 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 "quic/core/crypto/quic_crypto_server_config.h"
-
-#include <algorithm>
-#include <cstdlib>
-#include <memory>
-#include <string>
-#include <utility>
-
-#include "absl/base/attributes.h"
-#include "absl/strings/escaping.h"
-#include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
-#include "third_party/boringssl/src/include/openssl/sha.h"
-#include "third_party/boringssl/src/include/openssl/ssl.h"
-#include "quic/core/crypto/aes_128_gcm_12_decrypter.h"
-#include "quic/core/crypto/aes_128_gcm_12_encrypter.h"
-#include "quic/core/crypto/cert_compressor.h"
-#include "quic/core/crypto/certificate_view.h"
-#include "quic/core/crypto/chacha20_poly1305_encrypter.h"
-#include "quic/core/crypto/channel_id.h"
-#include "quic/core/crypto/crypto_framer.h"
-#include "quic/core/crypto/crypto_handshake_message.h"
-#include "quic/core/crypto/crypto_utils.h"
-#include "quic/core/crypto/curve25519_key_exchange.h"
-#include "quic/core/crypto/key_exchange.h"
-#include "quic/core/crypto/p256_key_exchange.h"
-#include "quic/core/crypto/proof_source.h"
-#include "quic/core/crypto/quic_decrypter.h"
-#include "quic/core/crypto/quic_encrypter.h"
-#include "quic/core/crypto/quic_hkdf.h"
-#include "quic/core/crypto/quic_random.h"
-#include "quic/core/crypto/tls_server_connection.h"
-#include "quic/core/proto/crypto_server_config_proto.h"
-#include "quic/core/proto/source_address_token_proto.h"
-#include "quic/core/quic_clock.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_socket_address_coder.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_flag_utils.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_hostname_utils.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/platform/api/quic_reference_counted.h"
-#include "quic/platform/api/quic_socket_address.h"
-#include "quic/platform/api/quic_testvalue.h"
-
-namespace quic {
-
-namespace {
-
-// kMultiplier is the multiple of the CHLO message size that a REJ message
-// must stay under when the client doesn't present a valid source-address
-// token. This is used to protect QUIC from amplification attacks.
-// TODO(rch): Reduce this to 2 again once b/25933682 is fixed.
-const size_t kMultiplier = 3;
-
-const int kMaxTokenAddresses = 4;
-
-std::string DeriveSourceAddressTokenKey(
- absl::string_view source_address_token_secret) {
- QuicHKDF hkdf(source_address_token_secret, absl::string_view() /* no salt */,
- "QUIC source address token key",
- CryptoSecretBoxer::GetKeySize(), 0 /* no fixed IV needed */,
- 0 /* no subkey secret */);
- return std::string(hkdf.server_write_key());
-}
-
-// Default source for creating KeyExchange objects.
-class DefaultKeyExchangeSource : public KeyExchangeSource {
- public:
- DefaultKeyExchangeSource() = default;
- ~DefaultKeyExchangeSource() override = default;
-
- std::unique_ptr<AsynchronousKeyExchange> Create(
- std::string /*server_config_id*/,
- bool /* is_fallback */,
- QuicTag type,
- absl::string_view private_key) override {
- if (private_key.empty()) {
- QUIC_LOG(WARNING) << "Server config contains key exchange method without "
- "corresponding private key of type "
- << QuicTagToString(type);
- return nullptr;
- }
-
- std::unique_ptr<SynchronousKeyExchange> ka =
- CreateLocalSynchronousKeyExchange(type, private_key);
- if (!ka) {
- QUIC_LOG(WARNING) << "Failed to create key exchange method of type "
- << QuicTagToString(type);
- }
- return ka;
- }
-};
-
-// Returns true if the PDMD field from the client hello demands an X509
-// certificate.
-bool ClientDemandsX509Proof(const CryptoHandshakeMessage& client_hello) {
- QuicTagVector their_proof_demands;
-
- if (client_hello.GetTaglist(kPDMD, &their_proof_demands) != QUIC_NO_ERROR) {
- return false;
- }
-
- for (const QuicTag tag : their_proof_demands) {
- if (tag == kX509) {
- return true;
- }
- }
- return false;
-}
-
-} // namespace
-
-// static
-std::unique_ptr<KeyExchangeSource> KeyExchangeSource::Default() {
- return std::make_unique<DefaultKeyExchangeSource>();
-}
-
-class ValidateClientHelloHelper {
- public:
- // Note: stores a pointer to a unique_ptr, and std::moves the unique_ptr when
- // ValidationComplete is called.
- ValidateClientHelloHelper(
- QuicReferenceCountedPointer<ValidateClientHelloResultCallback::Result>
- result,
- std::unique_ptr<ValidateClientHelloResultCallback>* done_cb)
- : result_(std::move(result)), done_cb_(done_cb) {}
- ValidateClientHelloHelper(const ValidateClientHelloHelper&) = delete;
- ValidateClientHelloHelper& operator=(const ValidateClientHelloHelper&) =
- delete;
-
- ~ValidateClientHelloHelper() {
- QUIC_BUG_IF(quic_bug_12963_1, done_cb_ != nullptr)
- << "Deleting ValidateClientHelloHelper with a pending callback.";
- }
-
- void ValidationComplete(
- QuicErrorCode error_code,
- const char* error_details,
- std::unique_ptr<ProofSource::Details> proof_source_details) {
- result_->error_code = error_code;
- result_->error_details = error_details;
- (*done_cb_)->Run(std::move(result_), std::move(proof_source_details));
- DetachCallback();
- }
-
- void DetachCallback() {
- QUIC_BUG_IF(quic_bug_10630_1, done_cb_ == nullptr)
- << "Callback already detached.";
- done_cb_ = nullptr;
- }
-
- private:
- QuicReferenceCountedPointer<ValidateClientHelloResultCallback::Result>
- result_;
- std::unique_ptr<ValidateClientHelloResultCallback>* done_cb_;
-};
-
-// static
-const char QuicCryptoServerConfig::TESTING[] = "secret string for testing";
-
-ClientHelloInfo::ClientHelloInfo(const QuicIpAddress& in_client_ip,
- QuicWallTime in_now)
- : client_ip(in_client_ip), now(in_now), valid_source_address_token(false) {}
-
-ClientHelloInfo::ClientHelloInfo(const ClientHelloInfo& other) = default;
-
-ClientHelloInfo::~ClientHelloInfo() {}
-
-PrimaryConfigChangedCallback::PrimaryConfigChangedCallback() {}
-
-PrimaryConfigChangedCallback::~PrimaryConfigChangedCallback() {}
-
-ValidateClientHelloResultCallback::Result::Result(
- const CryptoHandshakeMessage& in_client_hello,
- QuicIpAddress in_client_ip,
- QuicWallTime in_now)
- : client_hello(in_client_hello),
- info(in_client_ip, in_now),
- error_code(QUIC_NO_ERROR) {}
-
-ValidateClientHelloResultCallback::Result::~Result() {}
-
-ValidateClientHelloResultCallback::ValidateClientHelloResultCallback() {}
-
-ValidateClientHelloResultCallback::~ValidateClientHelloResultCallback() {}
-
-ProcessClientHelloResultCallback::ProcessClientHelloResultCallback() {}
-
-ProcessClientHelloResultCallback::~ProcessClientHelloResultCallback() {}
-
-QuicCryptoServerConfig::ConfigOptions::ConfigOptions()
- : expiry_time(QuicWallTime::Zero()),
- channel_id_enabled(false),
- p256(false) {}
-
-QuicCryptoServerConfig::ConfigOptions::ConfigOptions(
- const ConfigOptions& other) = default;
-
-QuicCryptoServerConfig::ConfigOptions::~ConfigOptions() {}
-
-QuicCryptoServerConfig::ProcessClientHelloContext::
- ~ProcessClientHelloContext() {
- if (done_cb_ != nullptr) {
- QUIC_LOG(WARNING)
- << "Deleting ProcessClientHelloContext with a pending callback.";
- }
-}
-
-void QuicCryptoServerConfig::ProcessClientHelloContext::Fail(
- QuicErrorCode error,
- const std::string& error_details) {
- done_cb_->Run(error, error_details, nullptr, nullptr, nullptr);
- done_cb_ = nullptr;
-}
-
-void QuicCryptoServerConfig::ProcessClientHelloContext::Succeed(
- std::unique_ptr<CryptoHandshakeMessage> message,
- std::unique_ptr<DiversificationNonce> diversification_nonce,
- std::unique_ptr<ProofSource::Details> proof_source_details) {
- done_cb_->Run(QUIC_NO_ERROR, std::string(), std::move(message),
- std::move(diversification_nonce),
- std::move(proof_source_details));
- done_cb_ = nullptr;
-}
-
-QuicCryptoServerConfig::QuicCryptoServerConfig(
- absl::string_view source_address_token_secret,
- QuicRandom* server_nonce_entropy,
- std::unique_ptr<ProofSource> proof_source,
- std::unique_ptr<KeyExchangeSource> key_exchange_source)
- : replay_protection_(true),
- chlo_multiplier_(kMultiplier),
- configs_lock_(),
- primary_config_(nullptr),
- next_config_promotion_time_(QuicWallTime::Zero()),
- proof_source_(std::move(proof_source)),
- key_exchange_source_(std::move(key_exchange_source)),
- ssl_ctx_(TlsServerConnection::CreateSslCtx(proof_source_.get())),
- source_address_token_future_secs_(3600),
- source_address_token_lifetime_secs_(86400),
- enable_serving_sct_(false),
- rejection_observer_(nullptr),
- pad_rej_(true),
- pad_shlo_(true),
- validate_chlo_size_(true),
- validate_source_address_token_(true) {
- QUICHE_DCHECK(proof_source_.get());
- source_address_token_boxer_.SetKeys(
- {DeriveSourceAddressTokenKey(source_address_token_secret)});
-
- // Generate a random key and orbit for server nonces.
- server_nonce_entropy->RandBytes(server_nonce_orbit_,
- sizeof(server_nonce_orbit_));
- const size_t key_size = server_nonce_boxer_.GetKeySize();
- std::unique_ptr<uint8_t[]> key_bytes(new uint8_t[key_size]);
- server_nonce_entropy->RandBytes(key_bytes.get(), key_size);
-
- server_nonce_boxer_.SetKeys(
- {std::string(reinterpret_cast<char*>(key_bytes.get()), key_size)});
-}
-
-QuicCryptoServerConfig::~QuicCryptoServerConfig() {}
-
-// static
-QuicServerConfigProtobuf QuicCryptoServerConfig::GenerateConfig(
- QuicRandom* rand,
- const QuicClock* clock,
- const ConfigOptions& options) {
- CryptoHandshakeMessage msg;
-
- const std::string curve25519_private_key =
- Curve25519KeyExchange::NewPrivateKey(rand);
- std::unique_ptr<Curve25519KeyExchange> curve25519 =
- Curve25519KeyExchange::New(curve25519_private_key);
- absl::string_view curve25519_public_value = curve25519->public_value();
-
- std::string encoded_public_values;
- // First three bytes encode the length of the public value.
- QUICHE_DCHECK_LT(curve25519_public_value.size(), (1U << 24));
- encoded_public_values.push_back(
- static_cast<char>(curve25519_public_value.size()));
- encoded_public_values.push_back(
- static_cast<char>(curve25519_public_value.size() >> 8));
- encoded_public_values.push_back(
- static_cast<char>(curve25519_public_value.size() >> 16));
- encoded_public_values.append(curve25519_public_value.data(),
- curve25519_public_value.size());
-
- std::string p256_private_key;
- if (options.p256) {
- p256_private_key = P256KeyExchange::NewPrivateKey();
- std::unique_ptr<P256KeyExchange> p256(
- P256KeyExchange::New(p256_private_key));
- absl::string_view p256_public_value = p256->public_value();
-
- QUICHE_DCHECK_LT(p256_public_value.size(), (1U << 24));
- encoded_public_values.push_back(
- static_cast<char>(p256_public_value.size()));
- encoded_public_values.push_back(
- static_cast<char>(p256_public_value.size() >> 8));
- encoded_public_values.push_back(
- static_cast<char>(p256_public_value.size() >> 16));
- encoded_public_values.append(p256_public_value.data(),
- p256_public_value.size());
- }
-
- msg.set_tag(kSCFG);
- if (options.p256) {
- msg.SetVector(kKEXS, QuicTagVector{kC255, kP256});
- } else {
- msg.SetVector(kKEXS, QuicTagVector{kC255});
- }
- msg.SetVector(kAEAD, QuicTagVector{kAESG, kCC20});
- msg.SetStringPiece(kPUBS, encoded_public_values);
-
- if (options.expiry_time.IsZero()) {
- const QuicWallTime now = clock->WallNow();
- const QuicWallTime expiry = now.Add(QuicTime::Delta::FromSeconds(
- 60 * 60 * 24 * 180 /* 180 days, ~six months */));
- const uint64_t expiry_seconds = expiry.ToUNIXSeconds();
- msg.SetValue(kEXPY, expiry_seconds);
- } else {
- msg.SetValue(kEXPY, options.expiry_time.ToUNIXSeconds());
- }
-
- char orbit_bytes[kOrbitSize];
- if (options.orbit.size() == sizeof(orbit_bytes)) {
- memcpy(orbit_bytes, options.orbit.data(), sizeof(orbit_bytes));
- } else {
- QUICHE_DCHECK(options.orbit.empty());
- rand->RandBytes(orbit_bytes, sizeof(orbit_bytes));
- }
- msg.SetStringPiece(kORBT,
- absl::string_view(orbit_bytes, sizeof(orbit_bytes)));
-
- if (options.channel_id_enabled) {
- msg.SetVector(kPDMD, QuicTagVector{kCHID});
- }
-
- if (options.id.empty()) {
- // We need to ensure that the SCID changes whenever the server config does
- // thus we make it a hash of the rest of the server config.
- std::unique_ptr<QuicData> serialized =
- CryptoFramer::ConstructHandshakeMessage(msg);
-
- uint8_t scid_bytes[SHA256_DIGEST_LENGTH];
- SHA256(reinterpret_cast<const uint8_t*>(serialized->data()),
- serialized->length(), scid_bytes);
- // The SCID is a truncated SHA-256 digest.
- static_assert(16 <= SHA256_DIGEST_LENGTH, "SCID length too high.");
- msg.SetStringPiece(
- kSCID,
- absl::string_view(reinterpret_cast<const char*>(scid_bytes), 16));
- } else {
- msg.SetStringPiece(kSCID, options.id);
- }
- // Don't put new tags below this point. The SCID generation should hash over
- // everything but itself and so extra tags should be added prior to the
- // preceding if block.
-
- std::unique_ptr<QuicData> serialized =
- CryptoFramer::ConstructHandshakeMessage(msg);
-
- QuicServerConfigProtobuf config;
- config.set_config(std::string(serialized->AsStringPiece()));
- QuicServerConfigProtobuf::PrivateKey* curve25519_key = config.add_key();
- curve25519_key->set_tag(kC255);
- curve25519_key->set_private_key(curve25519_private_key);
-
- if (options.p256) {
- QuicServerConfigProtobuf::PrivateKey* p256_key = config.add_key();
- p256_key->set_tag(kP256);
- p256_key->set_private_key(p256_private_key);
- }
-
- return config;
-}
-
-std::unique_ptr<CryptoHandshakeMessage> QuicCryptoServerConfig::AddConfig(
- const QuicServerConfigProtobuf& protobuf,
- const QuicWallTime now) {
- std::unique_ptr<CryptoHandshakeMessage> msg =
- CryptoFramer::ParseMessage(protobuf.config());
-
- if (!msg) {
- QUIC_LOG(WARNING) << "Failed to parse server config message";
- return nullptr;
- }
-
- QuicReferenceCountedPointer<Config> config =
- ParseConfigProtobuf(protobuf, /* is_fallback = */ false);
- if (!config) {
- QUIC_LOG(WARNING) << "Failed to parse server config message";
- return nullptr;
- }
-
- {
- QuicWriterMutexLock locked(&configs_lock_);
- if (configs_.find(config->id) != configs_.end()) {
- QUIC_LOG(WARNING) << "Failed to add config because another with the same "
- "server config id already exists: "
- << absl::BytesToHexString(config->id);
- return nullptr;
- }
-
- configs_[config->id] = config;
- SelectNewPrimaryConfig(now);
- QUICHE_DCHECK(primary_config_.get());
- QUICHE_DCHECK_EQ(configs_.find(primary_config_->id)->second.get(),
- primary_config_.get());
- }
-
- return msg;
-}
-
-std::unique_ptr<CryptoHandshakeMessage>
-QuicCryptoServerConfig::AddDefaultConfig(QuicRandom* rand,
- const QuicClock* clock,
- const ConfigOptions& options) {
- return AddConfig(GenerateConfig(rand, clock, options), clock->WallNow());
-}
-
-bool QuicCryptoServerConfig::SetConfigs(
- const std::vector<QuicServerConfigProtobuf>& protobufs,
- const QuicServerConfigProtobuf* fallback_protobuf,
- const QuicWallTime now) {
- std::vector<QuicReferenceCountedPointer<Config>> parsed_configs;
- for (auto& protobuf : protobufs) {
- QuicReferenceCountedPointer<Config> config =
- ParseConfigProtobuf(protobuf, /* is_fallback = */ false);
- if (!config) {
- QUIC_LOG(WARNING) << "Rejecting QUIC configs because of above errors";
- return false;
- }
-
- parsed_configs.push_back(config);
- }
-
- QuicReferenceCountedPointer<Config> fallback_config;
- if (fallback_protobuf != nullptr) {
- fallback_config =
- ParseConfigProtobuf(*fallback_protobuf, /* is_fallback = */ true);
- if (!fallback_config) {
- QUIC_LOG(WARNING) << "Rejecting QUIC configs because of above errors";
- return false;
- }
- QUIC_LOG(INFO) << "Fallback config has scid "
- << absl::BytesToHexString(fallback_config->id);
- parsed_configs.push_back(fallback_config);
- } else {
- QUIC_LOG(INFO) << "No fallback config provided";
- }
-
- if (parsed_configs.empty()) {
- QUIC_LOG(WARNING)
- << "Rejecting QUIC configs because new config list is empty.";
- return false;
- }
-
- QUIC_LOG(INFO) << "Updating configs:";
-
- QuicWriterMutexLock locked(&configs_lock_);
- ConfigMap new_configs;
-
- for (const QuicReferenceCountedPointer<Config>& config : parsed_configs) {
- auto it = configs_.find(config->id);
- if (it != configs_.end()) {
- QUIC_LOG(INFO) << "Keeping scid: " << absl::BytesToHexString(config->id)
- << " orbit: "
- << absl::BytesToHexString(absl::string_view(
- reinterpret_cast<const char*>(config->orbit),
- kOrbitSize))
- << " new primary_time "
- << config->primary_time.ToUNIXSeconds()
- << " old primary_time "
- << it->second->primary_time.ToUNIXSeconds()
- << " new priority " << config->priority << " old priority "
- << it->second->priority;
- // Update primary_time and priority.
- it->second->primary_time = config->primary_time;
- it->second->priority = config->priority;
- new_configs.insert(*it);
- } else {
- QUIC_LOG(INFO) << "Adding scid: " << absl::BytesToHexString(config->id)
- << " orbit: "
- << absl::BytesToHexString(absl::string_view(
- reinterpret_cast<const char*>(config->orbit),
- kOrbitSize))
- << " primary_time " << config->primary_time.ToUNIXSeconds()
- << " priority " << config->priority;
- new_configs.emplace(config->id, config);
- }
- }
-
- configs_ = std::move(new_configs);
- fallback_config_ = fallback_config;
- SelectNewPrimaryConfig(now);
- QUICHE_DCHECK(primary_config_.get());
- QUICHE_DCHECK_EQ(configs_.find(primary_config_->id)->second.get(),
- primary_config_.get());
-
- return true;
-}
-
-void QuicCryptoServerConfig::SetSourceAddressTokenKeys(
- const std::vector<std::string>& keys) {
- // TODO(b/208866709)
- source_address_token_boxer_.SetKeys(keys);
-}
-
-std::vector<std::string> QuicCryptoServerConfig::GetConfigIds() const {
- QuicReaderMutexLock locked(&configs_lock_);
- std::vector<std::string> scids;
- for (auto it = configs_.begin(); it != configs_.end(); ++it) {
- scids.push_back(it->first);
- }
- return scids;
-}
-
-void QuicCryptoServerConfig::ValidateClientHello(
- const CryptoHandshakeMessage& client_hello,
- const QuicSocketAddress& client_address,
- const QuicSocketAddress& server_address,
- QuicTransportVersion version,
- const QuicClock* clock,
- QuicReferenceCountedPointer<QuicSignedServerConfig> signed_config,
- std::unique_ptr<ValidateClientHelloResultCallback> done_cb) const {
- const QuicWallTime now(clock->WallNow());
-
- QuicReferenceCountedPointer<ValidateClientHelloResultCallback::Result> result(
- new ValidateClientHelloResultCallback::Result(
- client_hello, client_address.host(), now));
-
- absl::string_view requested_scid;
- // We ignore here the return value from GetStringPiece. If there is no SCID
- // tag, EvaluateClientHello will discover that because GetCurrentConfigs will
- // not have found the requested config (i.e. because none of the configs will
- // have an empty string as its id).
- client_hello.GetStringPiece(kSCID, &requested_scid);
- Configs configs;
- if (!GetCurrentConfigs(now, requested_scid,
- /* old_primary_config = */ nullptr, &configs)) {
- result->error_code = QUIC_CRYPTO_INTERNAL_ERROR;
- result->error_details = "No configurations loaded";
- }
- signed_config->config = configs.primary;
-
- if (result->error_code == QUIC_NO_ERROR) {
- // QUIC requires a new proof for each CHLO so clear any existing proof.
- signed_config->chain = nullptr;
- signed_config->proof.signature = "";
- signed_config->proof.leaf_cert_scts = "";
- EvaluateClientHello(server_address, client_address, version, configs,
- result, std::move(done_cb));
- } else {
- done_cb->Run(result, /* details = */ nullptr);
- }
-}
-
-class QuicCryptoServerConfig::ProcessClientHelloCallback
- : public ProofSource::Callback {
- public:
- ProcessClientHelloCallback(const QuicCryptoServerConfig* config,
- std::unique_ptr<ProcessClientHelloContext> context,
- const Configs& configs)
- : config_(config), context_(std::move(context)), configs_(configs) {}
-
- void Run(bool ok,
- const QuicReferenceCountedPointer<ProofSource::Chain>& chain,
- const QuicCryptoProof& proof,
- std::unique_ptr<ProofSource::Details> details) override {
- if (ok) {
- context_->signed_config()->chain = chain;
- context_->signed_config()->proof = proof;
- }
- config_->ProcessClientHelloAfterGetProof(!ok, std::move(details),
- std::move(context_), configs_);
- }
-
- private:
- const QuicCryptoServerConfig* config_;
- std::unique_ptr<ProcessClientHelloContext> context_;
- const Configs configs_;
-};
-
-class QuicCryptoServerConfig::ProcessClientHelloAfterGetProofCallback
- : public AsynchronousKeyExchange::Callback {
- public:
- ProcessClientHelloAfterGetProofCallback(
- const QuicCryptoServerConfig* config,
- std::unique_ptr<ProofSource::Details> proof_source_details,
- QuicTag key_exchange_type,
- std::unique_ptr<CryptoHandshakeMessage> out,
- absl::string_view public_value,
- std::unique_ptr<ProcessClientHelloContext> context,
- const Configs& configs)
- : config_(config),
- proof_source_details_(std::move(proof_source_details)),
- key_exchange_type_(key_exchange_type),
- out_(std::move(out)),
- public_value_(public_value),
- context_(std::move(context)),
- configs_(configs) {}
-
- void Run(bool ok) override {
- config_->ProcessClientHelloAfterCalculateSharedKeys(
- !ok, std::move(proof_source_details_), key_exchange_type_,
- std::move(out_), public_value_, std::move(context_), configs_);
- }
-
- private:
- const QuicCryptoServerConfig* config_;
- std::unique_ptr<ProofSource::Details> proof_source_details_;
- const QuicTag key_exchange_type_;
- std::unique_ptr<CryptoHandshakeMessage> out_;
- const std::string public_value_;
- std::unique_ptr<ProcessClientHelloContext> context_;
- const Configs configs_;
- std::unique_ptr<ProcessClientHelloResultCallback> done_cb_;
-};
-
-class QuicCryptoServerConfig::SendRejectWithFallbackConfigCallback
- : public ProofSource::Callback {
- public:
- SendRejectWithFallbackConfigCallback(
- const QuicCryptoServerConfig* config,
- std::unique_ptr<ProcessClientHelloContext> context,
- QuicReferenceCountedPointer<Config> fallback_config)
- : config_(config),
- context_(std::move(context)),
- fallback_config_(fallback_config) {}
-
- // Capture |chain| and |proof| into the signed config, and then invoke
- // SendRejectWithFallbackConfigAfterGetProof.
- void Run(bool ok,
- const QuicReferenceCountedPointer<ProofSource::Chain>& chain,
- const QuicCryptoProof& proof,
- std::unique_ptr<ProofSource::Details> details) override {
- if (ok) {
- context_->signed_config()->chain = chain;
- context_->signed_config()->proof = proof;
- }
- config_->SendRejectWithFallbackConfigAfterGetProof(
- !ok, std::move(details), std::move(context_), fallback_config_);
- }
-
- private:
- const QuicCryptoServerConfig* config_;
- std::unique_ptr<ProcessClientHelloContext> context_;
- QuicReferenceCountedPointer<Config> fallback_config_;
-};
-
-void QuicCryptoServerConfig::ProcessClientHello(
- QuicReferenceCountedPointer<ValidateClientHelloResultCallback::Result>
- validate_chlo_result,
- bool reject_only,
- QuicConnectionId connection_id,
- const QuicSocketAddress& server_address,
- const QuicSocketAddress& client_address,
- ParsedQuicVersion version,
- const ParsedQuicVersionVector& supported_versions,
- const QuicClock* clock,
- QuicRandom* rand,
- QuicCompressedCertsCache* compressed_certs_cache,
- QuicReferenceCountedPointer<QuicCryptoNegotiatedParameters> params,
- QuicReferenceCountedPointer<QuicSignedServerConfig> signed_config,
- QuicByteCount total_framing_overhead,
- QuicByteCount chlo_packet_size,
- std::unique_ptr<ProcessClientHelloResultCallback> done_cb) const {
- QUICHE_DCHECK(done_cb);
- auto context = std::make_unique<ProcessClientHelloContext>(
- validate_chlo_result, reject_only, connection_id, server_address,
- client_address, version, supported_versions, clock, rand,
- compressed_certs_cache, params, signed_config, total_framing_overhead,
- chlo_packet_size, std::move(done_cb));
-
- // Verify that various parts of the CHLO are valid
- std::string error_details;
- QuicErrorCode valid = CryptoUtils::ValidateClientHello(
- context->client_hello(), context->version(),
- context->supported_versions(), &error_details);
- if (valid != QUIC_NO_ERROR) {
- context->Fail(valid, error_details);
- return;
- }
-
- absl::string_view requested_scid;
- context->client_hello().GetStringPiece(kSCID, &requested_scid);
- Configs configs;
- if (!GetCurrentConfigs(context->clock()->WallNow(), requested_scid,
- signed_config->config, &configs)) {
- context->Fail(QUIC_CRYPTO_INTERNAL_ERROR, "No configurations loaded");
- return;
- }
-
- if (context->validate_chlo_result()->error_code != QUIC_NO_ERROR) {
- context->Fail(context->validate_chlo_result()->error_code,
- context->validate_chlo_result()->error_details);
- return;
- }
-
- if (!ClientDemandsX509Proof(context->client_hello())) {
- context->Fail(QUIC_UNSUPPORTED_PROOF_DEMAND, "Missing or invalid PDMD");
- return;
- }
-
- // No need to get a new proof if one was already generated.
- if (!context->signed_config()->chain) {
- const std::string chlo_hash = CryptoUtils::HashHandshakeMessage(
- context->client_hello(), Perspective::IS_SERVER);
- const QuicSocketAddress server_address = context->server_address();
- const std::string sni = std::string(context->info().sni);
- const QuicTransportVersion transport_version = context->transport_version();
-
- auto cb = std::make_unique<ProcessClientHelloCallback>(
- this, std::move(context), configs);
-
- QUICHE_DCHECK(proof_source_.get());
- proof_source_->GetProof(server_address, client_address, sni,
- configs.primary->serialized, transport_version,
- chlo_hash, std::move(cb));
- return;
- }
-
- ProcessClientHelloAfterGetProof(
- /* found_error = */ false, /* proof_source_details = */ nullptr,
- std::move(context), configs);
-}
-
-void QuicCryptoServerConfig::ProcessClientHelloAfterGetProof(
- bool found_error,
- std::unique_ptr<ProofSource::Details> proof_source_details,
- std::unique_ptr<ProcessClientHelloContext> context,
- const Configs& configs) const {
- QUIC_BUG_IF(quic_bug_12963_2,
- !QuicUtils::IsConnectionIdValidForVersion(
- context->connection_id(), context->transport_version()))
- << "ProcessClientHelloAfterGetProof: attempted to use connection ID "
- << context->connection_id() << " which is invalid with version "
- << context->version();
-
- if (context->info().reject_reasons.empty()) {
- if (!context->signed_config() || !context->signed_config()->chain) {
- // No chain.
- context->validate_chlo_result()->info.reject_reasons.push_back(
- SERVER_CONFIG_UNKNOWN_CONFIG_FAILURE);
- } else if (!ValidateExpectedLeafCertificate(
- context->client_hello(),
- context->signed_config()->chain->certs)) {
- // Has chain but leaf is invalid.
- context->validate_chlo_result()->info.reject_reasons.push_back(
- INVALID_EXPECTED_LEAF_CERTIFICATE);
- }
- }
-
- if (found_error) {
- context->Fail(QUIC_HANDSHAKE_FAILED, "Failed to get proof");
- return;
- }
-
- auto out_diversification_nonce = std::make_unique<DiversificationNonce>();
-
- absl::string_view cert_sct;
- if (context->client_hello().GetStringPiece(kCertificateSCTTag, &cert_sct) &&
- cert_sct.empty()) {
- context->params()->sct_supported_by_client = true;
- }
-
- auto out = std::make_unique<CryptoHandshakeMessage>();
- if (!context->info().reject_reasons.empty() || !configs.requested) {
- BuildRejectionAndRecordStats(*context, *configs.primary,
- context->info().reject_reasons, out.get());
- context->Succeed(std::move(out), std::move(out_diversification_nonce),
- std::move(proof_source_details));
- return;
- }
-
- if (context->reject_only()) {
- context->Succeed(std::move(out), std::move(out_diversification_nonce),
- std::move(proof_source_details));
- return;
- }
-
- QuicTagVector their_aeads;
- QuicTagVector their_key_exchanges;
- if (context->client_hello().GetTaglist(kAEAD, &their_aeads) !=
- QUIC_NO_ERROR ||
- context->client_hello().GetTaglist(kKEXS, &their_key_exchanges) !=
- QUIC_NO_ERROR ||
- their_aeads.size() != 1 || their_key_exchanges.size() != 1) {
- context->Fail(QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER,
- "Missing or invalid AEAD or KEXS");
- return;
- }
-
- size_t key_exchange_index;
- if (!FindMutualQuicTag(configs.requested->aead, their_aeads,
- &context->params()->aead, nullptr) ||
- !FindMutualQuicTag(configs.requested->kexs, their_key_exchanges,
- &context->params()->key_exchange,
- &key_exchange_index)) {
- context->Fail(QUIC_CRYPTO_NO_SUPPORT, "Unsupported AEAD or KEXS");
- return;
- }
-
- absl::string_view public_value;
- if (!context->client_hello().GetStringPiece(kPUBS, &public_value)) {
- context->Fail(QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER,
- "Missing public value");
- return;
- }
-
- // Allow testing a specific adversarial case in which a client sends a public
- // value of incorrect size.
- AdjustTestValue("quic::QuicCryptoServerConfig::public_value_adjust",
- &public_value);
-
- const AsynchronousKeyExchange* key_exchange =
- configs.requested->key_exchanges[key_exchange_index].get();
- std::string* initial_premaster_secret =
- &context->params()->initial_premaster_secret;
- auto cb = std::make_unique<ProcessClientHelloAfterGetProofCallback>(
- this, std::move(proof_source_details), key_exchange->type(),
- std::move(out), public_value, std::move(context), configs);
- key_exchange->CalculateSharedKeyAsync(public_value, initial_premaster_secret,
- std::move(cb));
-}
-
-void QuicCryptoServerConfig::ProcessClientHelloAfterCalculateSharedKeys(
- bool found_error,
- std::unique_ptr<ProofSource::Details> proof_source_details,
- QuicTag key_exchange_type,
- std::unique_ptr<CryptoHandshakeMessage> out,
- absl::string_view public_value,
- std::unique_ptr<ProcessClientHelloContext> context,
- const Configs& configs) const {
- QUIC_BUG_IF(quic_bug_12963_3,
- !QuicUtils::IsConnectionIdValidForVersion(
- context->connection_id(), context->transport_version()))
- << "ProcessClientHelloAfterCalculateSharedKeys:"
- " attempted to use connection ID "
- << context->connection_id() << " which is invalid with version "
- << context->version();
-
- if (found_error) {
- // If we are already using the fallback config, or there is no fallback
- // config to use, just bail out of the handshake.
- if (configs.fallback == nullptr ||
- context->signed_config()->config == configs.fallback) {
- context->Fail(QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER,
- "Failed to calculate shared key");
- } else {
- SendRejectWithFallbackConfig(std::move(context), configs.fallback);
- }
- return;
- }
-
- if (!context->info().sni.empty()) {
- context->params()->sni =
- QuicHostnameUtils::NormalizeHostname(context->info().sni);
- }
-
- std::string hkdf_suffix;
- const QuicData& client_hello_serialized =
- context->client_hello().GetSerialized();
- hkdf_suffix.reserve(context->connection_id().length() +
- client_hello_serialized.length() +
- configs.requested->serialized.size());
- hkdf_suffix.append(context->connection_id().data(),
- context->connection_id().length());
- hkdf_suffix.append(client_hello_serialized.data(),
- client_hello_serialized.length());
- hkdf_suffix.append(configs.requested->serialized);
- QUICHE_DCHECK(proof_source_.get());
- if (context->signed_config()->chain->certs.empty()) {
- context->Fail(QUIC_CRYPTO_INTERNAL_ERROR, "Failed to get certs");
- return;
- }
- hkdf_suffix.append(context->signed_config()->chain->certs.at(0));
-
- absl::string_view cetv_ciphertext;
- if (configs.requested->channel_id_enabled &&
- context->client_hello().GetStringPiece(kCETV, &cetv_ciphertext)) {
- CryptoHandshakeMessage client_hello_copy(context->client_hello());
- client_hello_copy.Erase(kCETV);
- client_hello_copy.Erase(kPAD);
-
- const QuicData& client_hello_copy_serialized =
- client_hello_copy.GetSerialized();
- std::string hkdf_input;
- hkdf_input.append(QuicCryptoConfig::kCETVLabel,
- strlen(QuicCryptoConfig::kCETVLabel) + 1);
- hkdf_input.append(context->connection_id().data(),
- context->connection_id().length());
- hkdf_input.append(client_hello_copy_serialized.data(),
- client_hello_copy_serialized.length());
- hkdf_input.append(configs.requested->serialized);
-
- CrypterPair crypters;
- if (!CryptoUtils::DeriveKeys(
- context->version(), context->params()->initial_premaster_secret,
- context->params()->aead, context->info().client_nonce,
- context->info().server_nonce, pre_shared_key_, hkdf_input,
- Perspective::IS_SERVER, CryptoUtils::Diversification::Never(),
- &crypters, nullptr /* subkey secret */)) {
- context->Fail(QUIC_CRYPTO_SYMMETRIC_KEY_SETUP_FAILED,
- "Symmetric key setup failed");
- return;
- }
-
- char plaintext[kMaxOutgoingPacketSize];
- size_t plaintext_length = 0;
- const bool success = crypters.decrypter->DecryptPacket(
- 0 /* packet number */, absl::string_view() /* associated data */,
- cetv_ciphertext, plaintext, &plaintext_length, kMaxOutgoingPacketSize);
- if (!success) {
- context->Fail(QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER,
- "CETV decryption failure");
- return;
- }
- std::unique_ptr<CryptoHandshakeMessage> cetv(CryptoFramer::ParseMessage(
- absl::string_view(plaintext, plaintext_length)));
- if (!cetv) {
- context->Fail(QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER, "CETV parse error");
- return;
- }
-
- absl::string_view key, signature;
- if (cetv->GetStringPiece(kCIDK, &key) &&
- cetv->GetStringPiece(kCIDS, &signature)) {
- if (!ChannelIDVerifier::Verify(key, hkdf_input, signature)) {
- context->Fail(QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER,
- "ChannelID signature failure");
- return;
- }
-
- context->params()->channel_id = std::string(key);
- }
- }
-
- std::string hkdf_input;
- size_t label_len = strlen(QuicCryptoConfig::kInitialLabel) + 1;
- hkdf_input.reserve(label_len + hkdf_suffix.size());
- hkdf_input.append(QuicCryptoConfig::kInitialLabel, label_len);
- hkdf_input.append(hkdf_suffix);
-
- auto out_diversification_nonce = std::make_unique<DiversificationNonce>();
- context->rand()->RandBytes(out_diversification_nonce->data(),
- out_diversification_nonce->size());
- CryptoUtils::Diversification diversification =
- CryptoUtils::Diversification::Now(out_diversification_nonce.get());
- if (!CryptoUtils::DeriveKeys(
- context->version(), context->params()->initial_premaster_secret,
- context->params()->aead, context->info().client_nonce,
- context->info().server_nonce, pre_shared_key_, hkdf_input,
- Perspective::IS_SERVER, diversification,
- &context->params()->initial_crypters,
- &context->params()->initial_subkey_secret)) {
- context->Fail(QUIC_CRYPTO_SYMMETRIC_KEY_SETUP_FAILED,
- "Symmetric key setup failed");
- return;
- }
-
- std::string forward_secure_public_value;
- std::unique_ptr<SynchronousKeyExchange> forward_secure_key_exchange =
- CreateLocalSynchronousKeyExchange(key_exchange_type, context->rand());
- if (!forward_secure_key_exchange) {
- QUIC_DLOG(WARNING) << "Failed to create keypair";
- context->Fail(QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER,
- "Failed to create keypair");
- return;
- }
-
- forward_secure_public_value =
- std::string(forward_secure_key_exchange->public_value());
- if (!forward_secure_key_exchange->CalculateSharedKeySync(
- public_value, &context->params()->forward_secure_premaster_secret)) {
- context->Fail(QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER,
- "Invalid public value");
- return;
- }
-
- std::string forward_secure_hkdf_input;
- label_len = strlen(QuicCryptoConfig::kForwardSecureLabel) + 1;
- forward_secure_hkdf_input.reserve(label_len + hkdf_suffix.size());
- forward_secure_hkdf_input.append(QuicCryptoConfig::kForwardSecureLabel,
- label_len);
- forward_secure_hkdf_input.append(hkdf_suffix);
-
- std::string shlo_nonce;
- shlo_nonce = NewServerNonce(context->rand(), context->info().now);
- out->SetStringPiece(kServerNonceTag, shlo_nonce);
-
- if (!CryptoUtils::DeriveKeys(
- context->version(),
- context->params()->forward_secure_premaster_secret,
- context->params()->aead, context->info().client_nonce,
- shlo_nonce.empty() ? context->info().server_nonce : shlo_nonce,
- pre_shared_key_, forward_secure_hkdf_input, Perspective::IS_SERVER,
- CryptoUtils::Diversification::Never(),
- &context->params()->forward_secure_crypters,
- &context->params()->subkey_secret)) {
- context->Fail(QUIC_CRYPTO_SYMMETRIC_KEY_SETUP_FAILED,
- "Symmetric key setup failed");
- return;
- }
-
- out->set_tag(kSHLO);
- out->SetVersionVector(kVER, context->supported_versions());
- out->SetStringPiece(
- kSourceAddressTokenTag,
- NewSourceAddressToken(*configs.requested->source_address_token_boxer,
- context->info().source_address_tokens,
- context->client_address().host(), context->rand(),
- context->info().now, nullptr));
- QuicSocketAddressCoder address_coder(context->client_address());
- out->SetStringPiece(kCADR, address_coder.Encode());
- out->SetStringPiece(kPUBS, forward_secure_public_value);
-
- context->Succeed(std::move(out), std::move(out_diversification_nonce),
- std::move(proof_source_details));
-}
-
-void QuicCryptoServerConfig::SendRejectWithFallbackConfig(
- std::unique_ptr<ProcessClientHelloContext> context,
- QuicReferenceCountedPointer<Config> fallback_config) const {
- // We failed to calculate a shared initial key, likely because we tried to use
- // a remote key-exchange service which could not be reached. We want to send
- // a REJ which tells the client to use a different ServerConfig which
- // corresponds to a local keypair. To generate the REJ we need to request a
- // new proof.
- const std::string chlo_hash = CryptoUtils::HashHandshakeMessage(
- context->client_hello(), Perspective::IS_SERVER);
- const QuicSocketAddress server_address = context->server_address();
- const std::string sni(context->info().sni);
- const QuicTransportVersion transport_version = context->transport_version();
-
- const QuicSocketAddress& client_address = context->client_address();
- auto cb = std::make_unique<SendRejectWithFallbackConfigCallback>(
- this, std::move(context), fallback_config);
- proof_source_->GetProof(server_address, client_address, sni,
- fallback_config->serialized, transport_version,
- chlo_hash, std::move(cb));
-}
-
-void QuicCryptoServerConfig::SendRejectWithFallbackConfigAfterGetProof(
- bool found_error,
- std::unique_ptr<ProofSource::Details> proof_source_details,
- std::unique_ptr<ProcessClientHelloContext> context,
- QuicReferenceCountedPointer<Config> fallback_config) const {
- if (found_error) {
- context->Fail(QUIC_HANDSHAKE_FAILED, "Failed to get proof");
- return;
- }
-
- auto out = std::make_unique<CryptoHandshakeMessage>();
- BuildRejectionAndRecordStats(*context, *fallback_config,
- {SERVER_CONFIG_UNKNOWN_CONFIG_FAILURE},
- out.get());
-
- context->Succeed(std::move(out), std::make_unique<DiversificationNonce>(),
- std::move(proof_source_details));
-}
-
-QuicReferenceCountedPointer<QuicCryptoServerConfig::Config>
-QuicCryptoServerConfig::GetConfigWithScid(
- absl::string_view requested_scid) const {
- configs_lock_.AssertReaderHeld();
-
- if (!requested_scid.empty()) {
- auto it = configs_.find((std::string(requested_scid)));
- if (it != configs_.end()) {
- // We'll use the config that the client requested in order to do
- // key-agreement.
- return QuicReferenceCountedPointer<Config>(it->second);
- }
- }
-
- return QuicReferenceCountedPointer<Config>();
-}
-
-bool QuicCryptoServerConfig::GetCurrentConfigs(
- const QuicWallTime& now,
- absl::string_view requested_scid,
- QuicReferenceCountedPointer<Config> old_primary_config,
- Configs* configs) const {
- QuicReaderMutexLock locked(&configs_lock_);
-
- if (!primary_config_) {
- return false;
- }
-
- if (IsNextConfigReady(now)) {
- configs_lock_.ReaderUnlock();
- configs_lock_.WriterLock();
- SelectNewPrimaryConfig(now);
- QUICHE_DCHECK(primary_config_.get());
- QUICHE_DCHECK_EQ(configs_.find(primary_config_->id)->second.get(),
- primary_config_.get());
- configs_lock_.WriterUnlock();
- configs_lock_.ReaderLock();
- }
-
- if (old_primary_config != nullptr) {
- configs->primary = old_primary_config;
- } else {
- configs->primary = primary_config_;
- }
- configs->requested = GetConfigWithScid(requested_scid);
- configs->fallback = fallback_config_;
-
- return true;
-}
-
-// ConfigPrimaryTimeLessThan is a comparator that implements "less than" for
-// Config's based on their primary_time.
-// static
-bool QuicCryptoServerConfig::ConfigPrimaryTimeLessThan(
- const QuicReferenceCountedPointer<Config>& a,
- const QuicReferenceCountedPointer<Config>& b) {
- if (a->primary_time.IsBefore(b->primary_time) ||
- b->primary_time.IsBefore(a->primary_time)) {
- // Primary times differ.
- return a->primary_time.IsBefore(b->primary_time);
- } else if (a->priority != b->priority) {
- // Primary times are equal, sort backwards by priority.
- return a->priority < b->priority;
- } else {
- // Primary times and priorities are equal, sort by config id.
- return a->id < b->id;
- }
-}
-
-void QuicCryptoServerConfig::SelectNewPrimaryConfig(
- const QuicWallTime now) const {
- std::vector<QuicReferenceCountedPointer<Config>> configs;
- configs.reserve(configs_.size());
-
- for (auto it = configs_.begin(); it != configs_.end(); ++it) {
- // TODO(avd) Exclude expired configs?
- configs.push_back(it->second);
- }
-
- if (configs.empty()) {
- if (primary_config_ != nullptr) {
- QUIC_BUG(quic_bug_10630_2)
- << "No valid QUIC server config. Keeping the current config.";
- } else {
- QUIC_BUG(quic_bug_10630_3) << "No valid QUIC server config.";
- }
- return;
- }
-
- std::sort(configs.begin(), configs.end(), ConfigPrimaryTimeLessThan);
-
- QuicReferenceCountedPointer<Config> best_candidate = configs[0];
-
- for (size_t i = 0; i < configs.size(); ++i) {
- const QuicReferenceCountedPointer<Config> config(configs[i]);
- if (!config->primary_time.IsAfter(now)) {
- if (config->primary_time.IsAfter(best_candidate->primary_time)) {
- best_candidate = config;
- }
- continue;
- }
-
- // This is the first config with a primary_time in the future. Thus the
- // previous Config should be the primary and this one should determine the
- // next_config_promotion_time_.
- QuicReferenceCountedPointer<Config> new_primary = best_candidate;
- if (i == 0) {
- // We need the primary_time of the next config.
- if (configs.size() > 1) {
- next_config_promotion_time_ = configs[1]->primary_time;
- } else {
- next_config_promotion_time_ = QuicWallTime::Zero();
- }
- } else {
- next_config_promotion_time_ = config->primary_time;
- }
-
- if (primary_config_) {
- primary_config_->is_primary = false;
- }
- primary_config_ = new_primary;
- new_primary->is_primary = true;
- QUIC_DLOG(INFO) << "New primary config. orbit: "
- << absl::BytesToHexString(
- absl::string_view(reinterpret_cast<const char*>(
- primary_config_->orbit),
- kOrbitSize));
- if (primary_config_changed_cb_ != nullptr) {
- primary_config_changed_cb_->Run(primary_config_->id);
- }
-
- return;
- }
-
- // All config's primary times are in the past. We should make the most recent
- // and highest priority candidate primary.
- QuicReferenceCountedPointer<Config> new_primary = best_candidate;
- if (primary_config_) {
- primary_config_->is_primary = false;
- }
- primary_config_ = new_primary;
- new_primary->is_primary = true;
- QUIC_DLOG(INFO) << "New primary config. orbit: "
- << absl::BytesToHexString(absl::string_view(
- reinterpret_cast<const char*>(primary_config_->orbit),
- kOrbitSize))
- << " scid: " << absl::BytesToHexString(primary_config_->id);
- next_config_promotion_time_ = QuicWallTime::Zero();
- if (primary_config_changed_cb_ != nullptr) {
- primary_config_changed_cb_->Run(primary_config_->id);
- }
-}
-
-void QuicCryptoServerConfig::EvaluateClientHello(
- const QuicSocketAddress& /*server_address*/,
- const QuicSocketAddress& /*client_address*/,
- QuicTransportVersion /*version*/,
- const Configs& configs,
- QuicReferenceCountedPointer<ValidateClientHelloResultCallback::Result>
- client_hello_state,
- std::unique_ptr<ValidateClientHelloResultCallback> done_cb) const {
- ValidateClientHelloHelper helper(client_hello_state, &done_cb);
-
- const CryptoHandshakeMessage& client_hello = client_hello_state->client_hello;
- ClientHelloInfo* info = &(client_hello_state->info);
-
- if (client_hello.GetStringPiece(kSNI, &info->sni) &&
- !QuicHostnameUtils::IsValidSNI(info->sni)) {
- helper.ValidationComplete(QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER,
- "Invalid SNI name", nullptr);
- return;
- }
-
- client_hello.GetStringPiece(kUAID, &info->user_agent_id);
-
- HandshakeFailureReason source_address_token_error = MAX_FAILURE_REASON;
- if (validate_source_address_token_) {
- absl::string_view srct;
- if (client_hello.GetStringPiece(kSourceAddressTokenTag, &srct)) {
- Config& config =
- configs.requested != nullptr ? *configs.requested : *configs.primary;
- source_address_token_error =
- ParseSourceAddressToken(*config.source_address_token_boxer, srct,
- info->source_address_tokens);
-
- if (source_address_token_error == HANDSHAKE_OK) {
- source_address_token_error = ValidateSourceAddressTokens(
- info->source_address_tokens, info->client_ip, info->now,
- &client_hello_state->cached_network_params);
- }
- info->valid_source_address_token =
- (source_address_token_error == HANDSHAKE_OK);
- } else {
- source_address_token_error = SOURCE_ADDRESS_TOKEN_INVALID_FAILURE;
- }
- } else {
- source_address_token_error = HANDSHAKE_OK;
- info->valid_source_address_token = true;
- }
-
- if (!configs.requested) {
- absl::string_view requested_scid;
- if (client_hello.GetStringPiece(kSCID, &requested_scid)) {
- info->reject_reasons.push_back(SERVER_CONFIG_UNKNOWN_CONFIG_FAILURE);
- } else {
- info->reject_reasons.push_back(SERVER_CONFIG_INCHOATE_HELLO_FAILURE);
- }
- // No server config with the requested ID.
- helper.ValidationComplete(QUIC_NO_ERROR, "", nullptr);
- return;
- }
-
- if (!client_hello.GetStringPiece(kNONC, &info->client_nonce)) {
- info->reject_reasons.push_back(SERVER_CONFIG_INCHOATE_HELLO_FAILURE);
- // Report no client nonce as INCHOATE_HELLO_FAILURE.
- helper.ValidationComplete(QUIC_NO_ERROR, "", nullptr);
- return;
- }
-
- if (source_address_token_error != HANDSHAKE_OK) {
- info->reject_reasons.push_back(source_address_token_error);
- // No valid source address token.
- }
-
- if (info->client_nonce.size() != kNonceSize) {
- info->reject_reasons.push_back(CLIENT_NONCE_INVALID_FAILURE);
- // Invalid client nonce.
- QUIC_LOG_FIRST_N(ERROR, 2)
- << "Invalid client nonce: " << client_hello.DebugString();
- QUIC_DLOG(INFO) << "Invalid client nonce.";
- }
-
- // Server nonce is optional, and used for key derivation if present.
- client_hello.GetStringPiece(kServerNonceTag, &info->server_nonce);
-
- // If the server nonce is empty and we're requiring handshake confirmation
- // for DoS reasons then we must reject the CHLO.
- if (GetQuicReloadableFlag(quic_require_handshake_confirmation) &&
- info->server_nonce.empty()) {
- info->reject_reasons.push_back(SERVER_NONCE_REQUIRED_FAILURE);
- }
- helper.ValidationComplete(QUIC_NO_ERROR, "",
- std::unique_ptr<ProofSource::Details>());
-}
-
-void QuicCryptoServerConfig::BuildServerConfigUpdateMessage(
- QuicTransportVersion version,
- absl::string_view chlo_hash,
- const SourceAddressTokens& previous_source_address_tokens,
- const QuicSocketAddress& server_address,
- const QuicSocketAddress& client_address,
- const QuicClock* clock,
- QuicRandom* rand,
- QuicCompressedCertsCache* compressed_certs_cache,
- const QuicCryptoNegotiatedParameters& params,
- const CachedNetworkParameters* cached_network_params,
- std::unique_ptr<BuildServerConfigUpdateMessageResultCallback> cb) const {
- std::string serialized;
- std::string source_address_token;
- const CommonCertSets* common_cert_sets;
- {
- QuicReaderMutexLock locked(&configs_lock_);
- serialized = primary_config_->serialized;
- common_cert_sets = primary_config_->common_cert_sets;
- source_address_token = NewSourceAddressToken(
- *primary_config_->source_address_token_boxer,
- previous_source_address_tokens, client_address.host(), rand,
- clock->WallNow(), cached_network_params);
- }
-
- CryptoHandshakeMessage message;
- message.set_tag(kSCUP);
- message.SetStringPiece(kSCFG, serialized);
- message.SetStringPiece(kSourceAddressTokenTag, source_address_token);
-
- auto proof_source_cb =
- std::make_unique<BuildServerConfigUpdateMessageProofSourceCallback>(
- this, compressed_certs_cache, common_cert_sets, params,
- std::move(message), std::move(cb));
-
- proof_source_->GetProof(server_address, client_address, params.sni,
- serialized, version, chlo_hash,
- std::move(proof_source_cb));
-}
-
-QuicCryptoServerConfig::BuildServerConfigUpdateMessageProofSourceCallback::
- ~BuildServerConfigUpdateMessageProofSourceCallback() {}
-
-QuicCryptoServerConfig::BuildServerConfigUpdateMessageProofSourceCallback::
- BuildServerConfigUpdateMessageProofSourceCallback(
- const QuicCryptoServerConfig* config,
- QuicCompressedCertsCache* compressed_certs_cache,
- const CommonCertSets* common_cert_sets,
- const QuicCryptoNegotiatedParameters& params,
- CryptoHandshakeMessage message,
- std::unique_ptr<BuildServerConfigUpdateMessageResultCallback> cb)
- : config_(config),
- compressed_certs_cache_(compressed_certs_cache),
- common_cert_sets_(common_cert_sets),
- client_common_set_hashes_(params.client_common_set_hashes),
- client_cached_cert_hashes_(params.client_cached_cert_hashes),
- sct_supported_by_client_(params.sct_supported_by_client),
- sni_(params.sni),
- message_(std::move(message)),
- cb_(std::move(cb)) {}
-
-void QuicCryptoServerConfig::BuildServerConfigUpdateMessageProofSourceCallback::
- Run(bool ok,
- const QuicReferenceCountedPointer<ProofSource::Chain>& chain,
- const QuicCryptoProof& proof,
- std::unique_ptr<ProofSource::Details> details) {
- config_->FinishBuildServerConfigUpdateMessage(
- compressed_certs_cache_, common_cert_sets_, client_common_set_hashes_,
- client_cached_cert_hashes_, sct_supported_by_client_, sni_, ok, chain,
- proof.signature, proof.leaf_cert_scts, std::move(details),
- std::move(message_), std::move(cb_));
-}
-
-void QuicCryptoServerConfig::FinishBuildServerConfigUpdateMessage(
- QuicCompressedCertsCache* compressed_certs_cache,
- const CommonCertSets* common_cert_sets,
- const std::string& client_common_set_hashes,
- const std::string& client_cached_cert_hashes,
- bool sct_supported_by_client,
- const std::string& sni,
- bool ok,
- const QuicReferenceCountedPointer<ProofSource::Chain>& chain,
- const std::string& signature,
- const std::string& leaf_cert_sct,
- std::unique_ptr<ProofSource::Details> /*details*/,
- CryptoHandshakeMessage message,
- std::unique_ptr<BuildServerConfigUpdateMessageResultCallback> cb) const {
- if (!ok) {
- cb->Run(false, message);
- return;
- }
-
- const std::string compressed =
- CompressChain(compressed_certs_cache, chain, client_common_set_hashes,
- client_cached_cert_hashes, common_cert_sets);
-
- message.SetStringPiece(kCertificateTag, compressed);
- message.SetStringPiece(kPROF, signature);
- if (sct_supported_by_client && enable_serving_sct_) {
- if (leaf_cert_sct.empty()) {
- QUIC_LOG_EVERY_N_SEC(WARNING, 60)
- << "SCT is expected but it is empty. SNI: " << sni;
- } else {
- message.SetStringPiece(kCertificateSCTTag, leaf_cert_sct);
- }
- }
-
- cb->Run(true, message);
-}
-
-void QuicCryptoServerConfig::BuildRejectionAndRecordStats(
- const ProcessClientHelloContext& context,
- const Config& config,
- const std::vector<uint32_t>& reject_reasons,
- CryptoHandshakeMessage* out) const {
- BuildRejection(context, config, reject_reasons, out);
- if (rejection_observer_ != nullptr) {
- rejection_observer_->OnRejectionBuilt(reject_reasons, out);
- }
-}
-
-void QuicCryptoServerConfig::BuildRejection(
- const ProcessClientHelloContext& context,
- const Config& config,
- const std::vector<uint32_t>& reject_reasons,
- CryptoHandshakeMessage* out) const {
- const QuicWallTime now = context.clock()->WallNow();
-
- out->set_tag(kREJ);
- out->SetStringPiece(kSCFG, config.serialized);
- out->SetStringPiece(
- kSourceAddressTokenTag,
- NewSourceAddressToken(
- *config.source_address_token_boxer,
- context.info().source_address_tokens, context.info().client_ip,
- context.rand(), context.info().now,
- &context.validate_chlo_result()->cached_network_params));
- out->SetValue(kSTTL, config.expiry_time.AbsoluteDifference(now).ToSeconds());
- if (replay_protection_) {
- out->SetStringPiece(kServerNonceTag,
- NewServerNonce(context.rand(), context.info().now));
- }
-
- // Send client the reject reason for debugging purposes.
- QUICHE_DCHECK_LT(0u, reject_reasons.size());
- out->SetVector(kRREJ, reject_reasons);
-
- // The client may have requested a certificate chain.
- if (!ClientDemandsX509Proof(context.client_hello())) {
- QUIC_BUG(quic_bug_10630_4)
- << "x509 certificates not supported in proof demand";
- return;
- }
-
- absl::string_view client_common_set_hashes;
- if (context.client_hello().GetStringPiece(kCCS, &client_common_set_hashes)) {
- context.params()->client_common_set_hashes =
- std::string(client_common_set_hashes);
- }
-
- absl::string_view client_cached_cert_hashes;
- if (context.client_hello().GetStringPiece(kCCRT,
- &client_cached_cert_hashes)) {
- context.params()->client_cached_cert_hashes =
- std::string(client_cached_cert_hashes);
- } else {
- context.params()->client_cached_cert_hashes.clear();
- }
-
- const std::string compressed = CompressChain(
- context.compressed_certs_cache(), context.signed_config()->chain,
- context.params()->client_common_set_hashes,
- context.params()->client_cached_cert_hashes, config.common_cert_sets);
-
- QUICHE_DCHECK_GT(context.chlo_packet_size(), context.client_hello().size());
- // kREJOverheadBytes is a very rough estimate of how much of a REJ
- // message is taken up by things other than the certificates.
- // STK: 56 bytes
- // SNO: 56 bytes
- // SCFG
- // SCID: 16 bytes
- // PUBS: 38 bytes
- const size_t kREJOverheadBytes = 166;
- // max_unverified_size is the number of bytes that the certificate chain,
- // signature, and (optionally) signed certificate timestamp can consume before
- // we will demand a valid source-address token.
- const size_t max_unverified_size =
- chlo_multiplier_ *
- (context.chlo_packet_size() - context.total_framing_overhead()) -
- kREJOverheadBytes;
- static_assert(kClientHelloMinimumSize * kMultiplier >= kREJOverheadBytes,
- "overhead calculation may underflow");
- bool should_return_sct =
- context.params()->sct_supported_by_client && enable_serving_sct_;
- const std::string& cert_sct = context.signed_config()->proof.leaf_cert_scts;
- const size_t sct_size = should_return_sct ? cert_sct.size() : 0;
- const size_t total_size = context.signed_config()->proof.signature.size() +
- compressed.size() + sct_size;
- if (context.info().valid_source_address_token ||
- total_size < max_unverified_size) {
- out->SetStringPiece(kCertificateTag, compressed);
- out->SetStringPiece(kPROF, context.signed_config()->proof.signature);
- if (should_return_sct) {
- if (cert_sct.empty()) {
- // Log SNI and subject name for the leaf cert if its SCT is empty.
- // This is for debugging b/28342827.
- const std::vector<std::string>& certs =
- context.signed_config()->chain->certs;
- std::string ca_subject;
- if (!certs.empty()) {
- std::unique_ptr<CertificateView> view =
- CertificateView::ParseSingleCertificate(certs[0]);
- if (view != nullptr) {
- absl::optional<std::string> maybe_ca_subject =
- view->GetHumanReadableSubject();
- if (maybe_ca_subject.has_value()) {
- ca_subject = *maybe_ca_subject;
- }
- }
- }
- QUIC_LOG_EVERY_N_SEC(WARNING, 60)
- << "SCT is expected but it is empty. sni: '"
- << context.params()->sni << "' cert subject: '" << ca_subject
- << "'";
- } else {
- out->SetStringPiece(kCertificateSCTTag, cert_sct);
- }
- }
- } else {
- QUIC_LOG_EVERY_N_SEC(WARNING, 60)
- << "Sending inchoate REJ for hostname: " << context.info().sni
- << " signature: " << context.signed_config()->proof.signature.size()
- << " cert: " << compressed.size() << " sct:" << sct_size
- << " total: " << total_size << " max: " << max_unverified_size;
- }
-}
-
-std::string QuicCryptoServerConfig::CompressChain(
- QuicCompressedCertsCache* compressed_certs_cache,
- const QuicReferenceCountedPointer<ProofSource::Chain>& chain,
- const std::string& client_common_set_hashes,
- const std::string& client_cached_cert_hashes,
- const CommonCertSets* common_sets) {
- // Check whether the compressed certs is available in the cache.
- QUICHE_DCHECK(compressed_certs_cache);
- const std::string* cached_value = compressed_certs_cache->GetCompressedCert(
- chain, client_common_set_hashes, client_cached_cert_hashes);
- if (cached_value) {
- return *cached_value;
- }
- std::string compressed =
- CertCompressor::CompressChain(chain->certs, client_common_set_hashes,
- client_cached_cert_hashes, common_sets);
- // Insert the newly compressed cert to cache.
- compressed_certs_cache->Insert(chain, client_common_set_hashes,
- client_cached_cert_hashes, compressed);
- return compressed;
-}
-
-QuicReferenceCountedPointer<QuicCryptoServerConfig::Config>
-QuicCryptoServerConfig::ParseConfigProtobuf(
- const QuicServerConfigProtobuf& protobuf,
- bool is_fallback) const {
- std::unique_ptr<CryptoHandshakeMessage> msg =
- CryptoFramer::ParseMessage(protobuf.config());
-
- if (!msg) {
- QUIC_LOG(WARNING) << "Failed to parse server config message";
- return nullptr;
- }
-
- if (msg->tag() != kSCFG) {
- QUIC_LOG(WARNING) << "Server config message has tag " << msg->tag()
- << ", but expected " << kSCFG;
- return nullptr;
- }
-
- QuicReferenceCountedPointer<Config> config(new Config);
- config->serialized = protobuf.config();
- config->source_address_token_boxer = &source_address_token_boxer_;
-
- if (protobuf.has_primary_time()) {
- config->primary_time =
- QuicWallTime::FromUNIXSeconds(protobuf.primary_time());
- }
-
- config->priority = protobuf.priority();
-
- absl::string_view scid;
- if (!msg->GetStringPiece(kSCID, &scid)) {
- QUIC_LOG(WARNING) << "Server config message is missing SCID";
- return nullptr;
- }
- QUICHE_DCHECK(!scid.empty());
- config->id = std::string(scid);
-
- if (msg->GetTaglist(kAEAD, &config->aead) != QUIC_NO_ERROR) {
- QUIC_LOG(WARNING) << "Server config message is missing AEAD";
- return nullptr;
- }
-
- QuicTagVector kexs_tags;
- if (msg->GetTaglist(kKEXS, &kexs_tags) != QUIC_NO_ERROR) {
- QUIC_LOG(WARNING) << "Server config message is missing KEXS";
- return nullptr;
- }
-
- absl::string_view orbit;
- if (!msg->GetStringPiece(kORBT, &orbit)) {
- QUIC_LOG(WARNING) << "Server config message is missing ORBT";
- return nullptr;
- }
-
- if (orbit.size() != kOrbitSize) {
- QUIC_LOG(WARNING) << "Orbit value in server config is the wrong length."
- " Got "
- << orbit.size() << " want " << kOrbitSize;
- return nullptr;
- }
- static_assert(sizeof(config->orbit) == kOrbitSize, "incorrect orbit size");
- memcpy(config->orbit, orbit.data(), sizeof(config->orbit));
-
- QuicTagVector proof_demand_tags;
- if (msg->GetTaglist(kPDMD, &proof_demand_tags) == QUIC_NO_ERROR) {
- for (QuicTag tag : proof_demand_tags) {
- if (tag == kCHID) {
- config->channel_id_enabled = true;
- break;
- }
- }
- }
-
- for (size_t i = 0; i < kexs_tags.size(); i++) {
- const QuicTag tag = kexs_tags[i];
- std::string private_key;
-
- config->kexs.push_back(tag);
-
- for (int j = 0; j < protobuf.key_size(); j++) {
- const QuicServerConfigProtobuf::PrivateKey& key = protobuf.key(i);
- if (key.tag() == tag) {
- private_key = key.private_key();
- break;
- }
- }
-
- std::unique_ptr<AsynchronousKeyExchange> ka =
- key_exchange_source_->Create(config->id, is_fallback, tag, private_key);
- if (!ka) {
- return nullptr;
- }
- for (const auto& key_exchange : config->key_exchanges) {
- if (key_exchange->type() == tag) {
- QUIC_LOG(WARNING) << "Duplicate key exchange in config: " << tag;
- return nullptr;
- }
- }
-
- config->key_exchanges.push_back(std::move(ka));
- }
-
- uint64_t expiry_seconds;
- if (msg->GetUint64(kEXPY, &expiry_seconds) != QUIC_NO_ERROR) {
- QUIC_LOG(WARNING) << "Server config message is missing EXPY";
- return nullptr;
- }
- config->expiry_time = QuicWallTime::FromUNIXSeconds(expiry_seconds);
-
- return config;
-}
-
-void QuicCryptoServerConfig::set_replay_protection(bool on) {
- replay_protection_ = on;
-}
-
-void QuicCryptoServerConfig::set_chlo_multiplier(size_t multiplier) {
- chlo_multiplier_ = multiplier;
-}
-
-void QuicCryptoServerConfig::set_source_address_token_future_secs(
- uint32_t future_secs) {
- source_address_token_future_secs_ = future_secs;
-}
-
-void QuicCryptoServerConfig::set_source_address_token_lifetime_secs(
- uint32_t lifetime_secs) {
- source_address_token_lifetime_secs_ = lifetime_secs;
-}
-
-void QuicCryptoServerConfig::set_enable_serving_sct(bool enable_serving_sct) {
- enable_serving_sct_ = enable_serving_sct;
-}
-
-void QuicCryptoServerConfig::AcquirePrimaryConfigChangedCb(
- std::unique_ptr<PrimaryConfigChangedCallback> cb) {
- QuicWriterMutexLock locked(&configs_lock_);
- primary_config_changed_cb_ = std::move(cb);
-}
-
-std::string QuicCryptoServerConfig::NewSourceAddressToken(
- const CryptoSecretBoxer& crypto_secret_boxer,
- const SourceAddressTokens& previous_tokens,
- const QuicIpAddress& ip,
- QuicRandom* rand,
- QuicWallTime now,
- const CachedNetworkParameters* cached_network_params) const {
- SourceAddressTokens source_address_tokens;
- SourceAddressToken* source_address_token = source_address_tokens.add_tokens();
- source_address_token->set_ip(ip.DualStacked().ToPackedString());
- source_address_token->set_timestamp(now.ToUNIXSeconds());
- if (cached_network_params != nullptr) {
- *(source_address_token->mutable_cached_network_parameters()) =
- *cached_network_params;
- }
-
- // Append previous tokens.
- for (const SourceAddressToken& token : previous_tokens.tokens()) {
- if (source_address_tokens.tokens_size() > kMaxTokenAddresses) {
- break;
- }
-
- if (token.ip() == source_address_token->ip()) {
- // It's for the same IP address.
- continue;
- }
-
- if (ValidateSourceAddressTokenTimestamp(token, now) != HANDSHAKE_OK) {
- continue;
- }
-
- *(source_address_tokens.add_tokens()) = token;
- }
-
- return crypto_secret_boxer.Box(rand,
- source_address_tokens.SerializeAsString());
-}
-
-int QuicCryptoServerConfig::NumberOfConfigs() const {
- QuicReaderMutexLock locked(&configs_lock_);
- return configs_.size();
-}
-
-ProofSource* QuicCryptoServerConfig::proof_source() const {
- return proof_source_.get();
-}
-
-SSL_CTX* QuicCryptoServerConfig::ssl_ctx() const {
- return ssl_ctx_.get();
-}
-
-HandshakeFailureReason QuicCryptoServerConfig::ParseSourceAddressToken(
- const CryptoSecretBoxer& crypto_secret_boxer, absl::string_view token,
- SourceAddressTokens& tokens) const {
- std::string storage;
- absl::string_view plaintext;
- if (!crypto_secret_boxer.Unbox(token, &storage, &plaintext)) {
- return SOURCE_ADDRESS_TOKEN_DECRYPTION_FAILURE;
- }
-
- if (!tokens.ParseFromArray(plaintext.data(), plaintext.size())) {
- // Some clients might still be using the old source token format so
- // attempt to parse that format.
- // TODO(rch): remove this code once the new format is ubiquitous.
- SourceAddressToken token;
- if (!token.ParseFromArray(plaintext.data(), plaintext.size())) {
- return SOURCE_ADDRESS_TOKEN_PARSE_FAILURE;
- }
- *tokens.add_tokens() = token;
- }
-
- return HANDSHAKE_OK;
-}
-
-HandshakeFailureReason QuicCryptoServerConfig::ValidateSourceAddressTokens(
- const SourceAddressTokens& source_address_tokens,
- const QuicIpAddress& ip,
- QuicWallTime now,
- CachedNetworkParameters* cached_network_params) const {
- HandshakeFailureReason reason =
- SOURCE_ADDRESS_TOKEN_DIFFERENT_IP_ADDRESS_FAILURE;
- for (const SourceAddressToken& token : source_address_tokens.tokens()) {
- reason = ValidateSingleSourceAddressToken(token, ip, now);
- if (reason == HANDSHAKE_OK) {
- if (cached_network_params != nullptr &&
- token.has_cached_network_parameters()) {
- *cached_network_params = token.cached_network_parameters();
- }
- break;
- }
- }
- return reason;
-}
-
-HandshakeFailureReason QuicCryptoServerConfig::ValidateSingleSourceAddressToken(
- const SourceAddressToken& source_address_token,
- const QuicIpAddress& ip,
- QuicWallTime now) const {
- if (source_address_token.ip() != ip.DualStacked().ToPackedString()) {
- // It's for a different IP address.
- return SOURCE_ADDRESS_TOKEN_DIFFERENT_IP_ADDRESS_FAILURE;
- }
-
- return ValidateSourceAddressTokenTimestamp(source_address_token, now);
-}
-
-HandshakeFailureReason
-QuicCryptoServerConfig::ValidateSourceAddressTokenTimestamp(
- const SourceAddressToken& source_address_token,
- QuicWallTime now) const {
- const QuicWallTime timestamp(
- QuicWallTime::FromUNIXSeconds(source_address_token.timestamp()));
- const QuicTime::Delta delta(now.AbsoluteDifference(timestamp));
-
- if (now.IsBefore(timestamp) &&
- delta.ToSeconds() > source_address_token_future_secs_) {
- return SOURCE_ADDRESS_TOKEN_CLOCK_SKEW_FAILURE;
- }
-
- if (now.IsAfter(timestamp) &&
- delta.ToSeconds() > source_address_token_lifetime_secs_) {
- return SOURCE_ADDRESS_TOKEN_EXPIRED_FAILURE;
- }
-
- return HANDSHAKE_OK;
-}
-
-// kServerNoncePlaintextSize is the number of bytes in an unencrypted server
-// nonce.
-static const size_t kServerNoncePlaintextSize =
- 4 /* timestamp */ + 20 /* random bytes */;
-
-std::string QuicCryptoServerConfig::NewServerNonce(QuicRandom* rand,
- QuicWallTime now) const {
- const uint32_t timestamp = static_cast<uint32_t>(now.ToUNIXSeconds());
-
- uint8_t server_nonce[kServerNoncePlaintextSize];
- static_assert(sizeof(server_nonce) > sizeof(timestamp), "nonce too small");
- server_nonce[0] = static_cast<uint8_t>(timestamp >> 24);
- server_nonce[1] = static_cast<uint8_t>(timestamp >> 16);
- server_nonce[2] = static_cast<uint8_t>(timestamp >> 8);
- server_nonce[3] = static_cast<uint8_t>(timestamp);
- rand->RandBytes(&server_nonce[sizeof(timestamp)],
- sizeof(server_nonce) - sizeof(timestamp));
-
- return server_nonce_boxer_.Box(
- rand, absl::string_view(reinterpret_cast<char*>(server_nonce),
- sizeof(server_nonce)));
-}
-
-bool QuicCryptoServerConfig::ValidateExpectedLeafCertificate(
- const CryptoHandshakeMessage& client_hello,
- const std::vector<std::string>& certs) const {
- if (certs.empty()) {
- return false;
- }
-
- uint64_t hash_from_client;
- if (client_hello.GetUint64(kXLCT, &hash_from_client) != QUIC_NO_ERROR) {
- return false;
- }
- return CryptoUtils::ComputeLeafCertHash(certs.at(0)) == hash_from_client;
-}
-
-bool QuicCryptoServerConfig::IsNextConfigReady(QuicWallTime now) const {
- return !next_config_promotion_time_.IsZero() &&
- !next_config_promotion_time_.IsAfter(now);
-}
-
-QuicCryptoServerConfig::Config::Config()
- : channel_id_enabled(false),
- is_primary(false),
- primary_time(QuicWallTime::Zero()),
- expiry_time(QuicWallTime::Zero()),
- priority(0),
- source_address_token_boxer(nullptr) {}
-
-QuicCryptoServerConfig::Config::~Config() {}
-
-QuicSignedServerConfig::QuicSignedServerConfig() {}
-QuicSignedServerConfig::~QuicSignedServerConfig() {}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/quic_crypto_server_config.h b/chromium/net/third_party/quiche/src/quic/core/crypto/quic_crypto_server_config.h
deleted file mode 100644
index 799058d70ff..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/quic_crypto_server_config.h
+++ /dev/null
@@ -1,967 +0,0 @@
-// Copyright 2013 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_CRYPTO_QUIC_CRYPTO_SERVER_CONFIG_H_
-#define QUICHE_QUIC_CORE_CRYPTO_QUIC_CRYPTO_SERVER_CONFIG_H_
-
-#include <cstddef>
-#include <cstdint>
-#include <map>
-#include <memory>
-#include <string>
-#include <vector>
-
-#include "absl/strings/string_view.h"
-#include "third_party/boringssl/src/include/openssl/base.h"
-#include "quic/core/crypto/crypto_handshake.h"
-#include "quic/core/crypto/crypto_handshake_message.h"
-#include "quic/core/crypto/crypto_protocol.h"
-#include "quic/core/crypto/crypto_secret_boxer.h"
-#include "quic/core/crypto/key_exchange.h"
-#include "quic/core/crypto/proof_source.h"
-#include "quic/core/crypto/quic_compressed_certs_cache.h"
-#include "quic/core/crypto/quic_crypto_proof.h"
-#include "quic/core/proto/cached_network_parameters_proto.h"
-#include "quic/core/proto/source_address_token_proto.h"
-#include "quic/core/quic_time.h"
-#include "quic/platform/api/quic_export.h"
-#include "quic/platform/api/quic_mutex.h"
-#include "quic/platform/api/quic_reference_counted.h"
-#include "quic/platform/api/quic_socket_address.h"
-
-namespace quic {
-
-class CryptoHandshakeMessage;
-class ProofSource;
-class QuicClock;
-class QuicRandom;
-class QuicServerConfigProtobuf;
-struct QuicSignedServerConfig;
-
-// ClientHelloInfo contains information about a client hello message that is
-// only kept for as long as it's being processed.
-struct QUIC_EXPORT_PRIVATE ClientHelloInfo {
- ClientHelloInfo(const QuicIpAddress& in_client_ip, QuicWallTime in_now);
- ClientHelloInfo(const ClientHelloInfo& other);
- ~ClientHelloInfo();
-
- // Inputs to EvaluateClientHello.
- const QuicIpAddress client_ip;
- const QuicWallTime now;
-
- // Outputs from EvaluateClientHello.
- bool valid_source_address_token;
- absl::string_view sni;
- absl::string_view client_nonce;
- absl::string_view server_nonce;
- absl::string_view user_agent_id;
- SourceAddressTokens source_address_tokens;
-
- // Errors from EvaluateClientHello.
- std::vector<uint32_t> reject_reasons;
- static_assert(sizeof(QuicTag) == sizeof(uint32_t), "header out of sync");
-};
-
-namespace test {
-class QuicCryptoServerConfigPeer;
-} // namespace test
-
-// Hook that allows application code to subscribe to primary config changes.
-class QUIC_EXPORT_PRIVATE PrimaryConfigChangedCallback {
- public:
- PrimaryConfigChangedCallback();
- PrimaryConfigChangedCallback(const PrimaryConfigChangedCallback&) = delete;
- PrimaryConfigChangedCallback& operator=(const PrimaryConfigChangedCallback&) =
- delete;
- virtual ~PrimaryConfigChangedCallback();
- virtual void Run(const std::string& scid) = 0;
-};
-
-// Callback used to accept the result of the |client_hello| validation step.
-class QUIC_EXPORT_PRIVATE ValidateClientHelloResultCallback {
- public:
- // Opaque token that holds information about the client_hello and
- // its validity. Can be interpreted by calling ProcessClientHello.
- struct QUIC_EXPORT_PRIVATE Result : public QuicReferenceCounted {
- Result(const CryptoHandshakeMessage& in_client_hello,
- QuicIpAddress in_client_ip,
- QuicWallTime in_now);
-
- CryptoHandshakeMessage client_hello;
- ClientHelloInfo info;
- QuicErrorCode error_code;
- std::string error_details;
-
- // Populated if the CHLO STK contained a CachedNetworkParameters proto.
- CachedNetworkParameters cached_network_params;
-
- protected:
- ~Result() override;
- };
-
- ValidateClientHelloResultCallback();
- ValidateClientHelloResultCallback(const ValidateClientHelloResultCallback&) =
- delete;
- ValidateClientHelloResultCallback& operator=(
- const ValidateClientHelloResultCallback&) = delete;
- virtual ~ValidateClientHelloResultCallback();
- virtual void Run(QuicReferenceCountedPointer<Result> result,
- std::unique_ptr<ProofSource::Details> details) = 0;
-};
-
-// Callback used to accept the result of the ProcessClientHello method.
-class QUIC_EXPORT_PRIVATE ProcessClientHelloResultCallback {
- public:
- ProcessClientHelloResultCallback();
- ProcessClientHelloResultCallback(const ProcessClientHelloResultCallback&) =
- delete;
- ProcessClientHelloResultCallback& operator=(
- const ProcessClientHelloResultCallback&) = delete;
- virtual ~ProcessClientHelloResultCallback();
- virtual void Run(QuicErrorCode error,
- const std::string& error_details,
- std::unique_ptr<CryptoHandshakeMessage> message,
- std::unique_ptr<DiversificationNonce> diversification_nonce,
- std::unique_ptr<ProofSource::Details> details) = 0;
-};
-
-// Callback used to receive the results of a call to
-// BuildServerConfigUpdateMessage.
-class QUIC_EXPORT_PRIVATE BuildServerConfigUpdateMessageResultCallback {
- public:
- BuildServerConfigUpdateMessageResultCallback() = default;
- virtual ~BuildServerConfigUpdateMessageResultCallback() {}
- BuildServerConfigUpdateMessageResultCallback(
- const BuildServerConfigUpdateMessageResultCallback&) = delete;
- BuildServerConfigUpdateMessageResultCallback& operator=(
- const BuildServerConfigUpdateMessageResultCallback&) = delete;
- virtual void Run(bool ok, const CryptoHandshakeMessage& message) = 0;
-};
-
-// Object that is interested in built rejections (which include REJ, SREJ and
-// cheap SREJ).
-class QUIC_EXPORT_PRIVATE RejectionObserver {
- public:
- RejectionObserver() = default;
- virtual ~RejectionObserver() {}
- RejectionObserver(const RejectionObserver&) = delete;
- RejectionObserver& operator=(const RejectionObserver&) = delete;
- // Called after a rejection is built.
- virtual void OnRejectionBuilt(const std::vector<uint32_t>& reasons,
- CryptoHandshakeMessage* out) const = 0;
-};
-
-// Factory for creating KeyExchange objects.
-class QUIC_EXPORT_PRIVATE KeyExchangeSource {
- public:
- virtual ~KeyExchangeSource() = default;
-
- // Returns the default KeyExchangeSource.
- static std::unique_ptr<KeyExchangeSource> Default();
-
- // Create a new KeyExchange using the curve specified by |type| using the
- // specified private key. |private_key| may be empty for key-exchange
- // mechanisms which do not hold the private key in-process. If |is_fallback|
- // is set, |private_key| is required to be set, and a local key-exchange
- // object should be returned.
- virtual std::unique_ptr<AsynchronousKeyExchange> Create(
- std::string server_config_id,
- bool is_fallback,
- QuicTag type,
- absl::string_view private_key) = 0;
-};
-
-// QuicCryptoServerConfig contains the crypto configuration of a QUIC server.
-// Unlike a client, a QUIC server can have multiple configurations active in
-// order to support clients resuming with a previous configuration.
-// TODO(agl): when adding configurations at runtime is added, this object will
-// need to consider locking.
-class QUIC_EXPORT_PRIVATE QuicCryptoServerConfig {
- public:
- // ConfigOptions contains options for generating server configs.
- struct QUIC_EXPORT_PRIVATE ConfigOptions {
- ConfigOptions();
- ConfigOptions(const ConfigOptions& other);
- ~ConfigOptions();
-
- // expiry_time is the time, in UNIX seconds, when the server config will
- // expire. If unset, it defaults to the current time plus six months.
- QuicWallTime expiry_time;
- // channel_id_enabled controls whether the server config will indicate
- // support for ChannelIDs.
- bool channel_id_enabled;
- // id contains the server config id for the resulting config. If empty, a
- // random id is generated.
- std::string id;
- // orbit contains the kOrbitSize bytes of the orbit value for the server
- // config. If |orbit| is empty then a random orbit is generated.
- std::string orbit;
- // p256 determines whether a P-256 public key will be included in the
- // server config. Note that this breaks deterministic server-config
- // generation since P-256 key generation doesn't use the QuicRandom given
- // to GenerateConfig().
- bool p256;
- };
-
- // |source_address_token_secret|: secret key material used for encrypting and
- // decrypting source address tokens. It can be of any length as it is fed
- // into a KDF before use. In tests, use TESTING.
- // |server_nonce_entropy|: an entropy source used to generate the orbit and
- // key for server nonces, which are always local to a given instance of a
- // server. Not owned.
- // |proof_source|: provides certificate chains and signatures.
- // |key_exchange_source|: provides key-exchange functionality.
- QuicCryptoServerConfig(
- absl::string_view source_address_token_secret,
- QuicRandom* server_nonce_entropy,
- std::unique_ptr<ProofSource> proof_source,
- std::unique_ptr<KeyExchangeSource> key_exchange_source);
- QuicCryptoServerConfig(const QuicCryptoServerConfig&) = delete;
- QuicCryptoServerConfig& operator=(const QuicCryptoServerConfig&) = delete;
- ~QuicCryptoServerConfig();
-
- // TESTING is a magic parameter for passing to the constructor in tests.
- static const char TESTING[];
-
- // Generates a QuicServerConfigProtobuf protobuf suitable for
- // AddConfig and SetConfigs.
- static QuicServerConfigProtobuf GenerateConfig(QuicRandom* rand,
- const QuicClock* clock,
- const ConfigOptions& options);
-
- // AddConfig adds a QuicServerConfigProtobuf to the available configurations.
- // It returns the SCFG message from the config if successful. |now| is used in
- // conjunction with |protobuf->primary_time()| to determine whether the
- // config should be made primary.
- std::unique_ptr<CryptoHandshakeMessage> AddConfig(
- const QuicServerConfigProtobuf& protobuf,
- QuicWallTime now);
-
- // AddDefaultConfig calls GenerateConfig to create a config and then calls
- // AddConfig to add it. See the comment for |GenerateConfig| for details of
- // the arguments.
- std::unique_ptr<CryptoHandshakeMessage> AddDefaultConfig(
- QuicRandom* rand,
- const QuicClock* clock,
- const ConfigOptions& options);
-
- // SetConfigs takes a vector of config protobufs and the current time.
- // Configs are assumed to be uniquely identified by their server config ID.
- // Previously unknown configs are added and possibly made the primary config
- // depending on their |primary_time| and the value of |now|. Configs that are
- // known, but are missing from the protobufs are deleted, unless they are
- // currently the primary config. SetConfigs returns false if any errors were
- // encountered and no changes to the QuicCryptoServerConfig will occur.
- bool SetConfigs(const std::vector<QuicServerConfigProtobuf>& protobufs,
- const QuicServerConfigProtobuf* fallback_protobuf,
- QuicWallTime now);
-
- // SetSourceAddressTokenKeys sets the keys to be tried, in order, when
- // decrypting a source address token. Note that these keys are used *without*
- // passing them through a KDF, in contradistinction to the
- // |source_address_token_secret| argument to the constructor.
- void SetSourceAddressTokenKeys(const std::vector<std::string>& keys);
-
- // Get the server config ids for all known configs.
- std::vector<std::string> GetConfigIds() const;
-
- // Checks |client_hello| for gross errors and determines whether it can be
- // shown to be fresh (i.e. not a replay). The result of the validation step
- // must be interpreted by calling QuicCryptoServerConfig::ProcessClientHello
- // from the done_cb.
- //
- // ValidateClientHello may invoke the done_cb before unrolling the
- // stack if it is able to assess the validity of the client_nonce
- // without asynchronous operations.
- //
- // client_hello: the incoming client hello message.
- // client_ip: the IP address of the client, which is used to generate and
- // validate source-address tokens.
- // server_address: the IP address and port of the server. The IP address and
- // port may be used for certificate selection.
- // version: protocol version used for this connection.
- // clock: used to validate client nonces and ephemeral keys.
- // signed_config: in/out parameter to which will be written the crypto proof
- // used in reply to a proof demand. The pointed-to-object must live until
- // the callback is invoked.
- // done_cb: single-use callback that accepts an opaque
- // ValidatedClientHelloMsg token that holds information about
- // the client hello. The callback will always be called exactly
- // once, either under the current call stack, or after the
- // completion of an asynchronous operation.
- void ValidateClientHello(
- const CryptoHandshakeMessage& client_hello,
- const QuicSocketAddress& client_address,
- const QuicSocketAddress& server_address, QuicTransportVersion version,
- const QuicClock* clock,
- QuicReferenceCountedPointer<QuicSignedServerConfig> signed_config,
- std::unique_ptr<ValidateClientHelloResultCallback> done_cb) const;
-
- // ProcessClientHello processes |client_hello| and decides whether to accept
- // or reject the connection. If the connection is to be accepted, |done_cb| is
- // invoked with the contents of the ServerHello and QUIC_NO_ERROR. Otherwise
- // |done_cb| is called with a REJ or SREJ message and QUIC_NO_ERROR.
- //
- // validate_chlo_result: Output from the asynchronous call to
- // ValidateClientHello. Contains the client hello message and
- // information about it.
- // reject_only: Only generate rejections, not server hello messages.
- // connection_id: the ConnectionId for the connection, which is used in key
- // derivation.
- // server_ip: the IP address of the server. The IP address may be used for
- // certificate selection.
- // client_address: the IP address and port of the client. The IP address is
- // used to generate and validate source-address tokens.
- // version: version of the QUIC protocol in use for this connection
- // supported_versions: versions of the QUIC protocol that this server
- // supports.
- // clock: used to validate client nonces and ephemeral keys.
- // rand: an entropy source
- // compressed_certs_cache: the cache that caches a set of most recently used
- // certs. Owned by QuicDispatcher.
- // params: the state of the handshake. This may be updated with a server
- // nonce when we send a rejection.
- // signed_config: output structure containing the crypto proof used in reply
- // to a proof demand.
- // total_framing_overhead: the total per-packet overhead for a stream frame
- // chlo_packet_size: the size, in bytes, of the CHLO packet
- // done_cb: the callback invoked on completion
- void ProcessClientHello(
- QuicReferenceCountedPointer<ValidateClientHelloResultCallback::Result>
- validate_chlo_result,
- bool reject_only, QuicConnectionId connection_id,
- const QuicSocketAddress& server_address,
- const QuicSocketAddress& client_address, ParsedQuicVersion version,
- const ParsedQuicVersionVector& supported_versions, const QuicClock* clock,
- QuicRandom* rand, QuicCompressedCertsCache* compressed_certs_cache,
- QuicReferenceCountedPointer<QuicCryptoNegotiatedParameters> params,
- QuicReferenceCountedPointer<QuicSignedServerConfig> signed_config,
- QuicByteCount total_framing_overhead, QuicByteCount chlo_packet_size,
- std::unique_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
- // chain and proof in the case of secure QUIC. Passes true to |cb| if the
- // message was generated successfully, and false otherwise. This method
- // assumes ownership of |cb|.
- //
- // |cached_network_params| is optional, and can be nullptr.
- void BuildServerConfigUpdateMessage(
- QuicTransportVersion version,
- absl::string_view chlo_hash,
- const SourceAddressTokens& previous_source_address_tokens,
- const QuicSocketAddress& server_address,
- const QuicSocketAddress& client_address,
- const QuicClock* clock,
- QuicRandom* rand,
- QuicCompressedCertsCache* compressed_certs_cache,
- const QuicCryptoNegotiatedParameters& params,
- const CachedNetworkParameters* cached_network_params,
- std::unique_ptr<BuildServerConfigUpdateMessageResultCallback> cb) const;
-
- // set_replay_protection controls whether replay protection is enabled. If
- // replay protection is disabled then no strike registers are needed and
- // frontends can share an orbit value without a shared strike-register.
- // However, an attacker can duplicate a handshake and cause a client's
- // request to be processed twice.
- void set_replay_protection(bool on);
-
- // set_chlo_multiplier specifies the multiple of the CHLO message size
- // that a REJ message must stay under when the client doesn't present a
- // valid source-address token.
- void set_chlo_multiplier(size_t multiplier);
-
- // When sender is allowed to not pad client hello (not standards compliant),
- // we need to disable the client hello check.
- void set_validate_chlo_size(bool new_value) {
- validate_chlo_size_ = new_value;
- }
-
- // Returns whether the sender is allowed to not pad the client hello.
- bool validate_chlo_size() const { return validate_chlo_size_; }
-
- // When QUIC is tunneled through some other mechanism, source token validation
- // may be disabled. Do not disable it if you are not providing other
- // protection. (|true| protects against UDP amplification attack.).
- void set_validate_source_address_token(bool new_value) {
- validate_source_address_token_ = new_value;
- }
-
- // set_source_address_token_future_secs sets the number of seconds into the
- // future that source-address tokens will be accepted from. Since
- // source-address tokens are authenticated, this should only happen if
- // another, valid server has clock-skew.
- void set_source_address_token_future_secs(uint32_t future_secs);
-
- // set_source_address_token_lifetime_secs sets the number of seconds that a
- // source-address token will be valid for.
- void set_source_address_token_lifetime_secs(uint32_t lifetime_secs);
-
- // set_enable_serving_sct enables or disables serving signed cert timestamp
- // (RFC6962) in server hello.
- void set_enable_serving_sct(bool enable_serving_sct);
-
- // Set and take ownership of the callback to invoke on primary config changes.
- void AcquirePrimaryConfigChangedCb(
- std::unique_ptr<PrimaryConfigChangedCallback> cb);
-
- // Returns the number of configs this object owns.
- int NumberOfConfigs() const;
-
- // NewSourceAddressToken returns a fresh source address token for the given
- // IP address. |previous_tokens| is the received tokens, and can be empty.
- // |cached_network_params| is optional, and can be nullptr.
- std::string NewSourceAddressToken(
- const CryptoSecretBoxer& crypto_secret_boxer,
- const SourceAddressTokens& previous_tokens,
- const QuicIpAddress& ip,
- QuicRandom* rand,
- QuicWallTime now,
- const CachedNetworkParameters* cached_network_params) const;
-
- // ParseSourceAddressToken parses the source address tokens contained in
- // the encrypted |token|, and populates |tokens| with the parsed tokens.
- // Returns HANDSHAKE_OK if |token| could be parsed, or the reason for the
- // failure.
- HandshakeFailureReason ParseSourceAddressToken(
- const CryptoSecretBoxer& crypto_secret_boxer, absl::string_view token,
- SourceAddressTokens& tokens) const;
-
- // ValidateSourceAddressTokens returns HANDSHAKE_OK if the source address
- // tokens in |tokens| contain a valid and timely token for the IP address
- // |ip| given that the current time is |now|. Otherwise it returns the
- // reason for failure. |cached_network_params| is populated if the valid
- // token contains a CachedNetworkParameters proto.
- HandshakeFailureReason ValidateSourceAddressTokens(
- const SourceAddressTokens& tokens,
- const QuicIpAddress& ip,
- QuicWallTime now,
- CachedNetworkParameters* cached_network_params) const;
-
- // Callers retain the ownership of |rejection_observer| which must outlive the
- // config.
- void set_rejection_observer(RejectionObserver* rejection_observer) {
- rejection_observer_ = rejection_observer;
- }
-
- ProofSource* proof_source() const;
-
- SSL_CTX* ssl_ctx() const;
-
- // Pre-shared key used during the handshake.
- const std::string& pre_shared_key() const { return pre_shared_key_; }
- void set_pre_shared_key(absl::string_view psk) {
- pre_shared_key_ = std::string(psk);
- }
-
- bool pad_rej() const { return pad_rej_; }
- void set_pad_rej(bool new_value) { pad_rej_ = new_value; }
-
- bool pad_shlo() const { return pad_shlo_; }
- void set_pad_shlo(bool new_value) { pad_shlo_ = new_value; }
-
- const CryptoSecretBoxer& source_address_token_boxer() const {
- return source_address_token_boxer_;
- }
-
- private:
- friend class test::QuicCryptoServerConfigPeer;
- friend struct QuicSignedServerConfig;
-
- // Config represents a server config: a collection of preferences and
- // Diffie-Hellman public values.
- class QUIC_EXPORT_PRIVATE Config : public QuicCryptoConfig,
- public QuicReferenceCounted {
- public:
- Config();
- Config(const Config&) = delete;
- Config& operator=(const Config&) = delete;
-
- // TODO(rtenneti): since this is a class, we should probably do
- // getters/setters here.
- // |serialized| contains the bytes of this server config, suitable for
- // sending on the wire.
- std::string serialized;
- // id contains the SCID of this server config.
- std::string id;
- // orbit contains the orbit value for this config: an opaque identifier
- // used to identify clusters of server frontends.
- unsigned char orbit[kOrbitSize];
-
- // key_exchanges contains key exchange objects. The values correspond,
- // one-to-one, with the tags in |kexs| from the parent class.
- std::vector<std::unique_ptr<AsynchronousKeyExchange>> key_exchanges;
-
- // channel_id_enabled is true if the config in |serialized| specifies that
- // ChannelIDs are supported.
- bool channel_id_enabled;
-
- // is_primary is true if this config is the one that we'll give out to
- // clients as the current one.
- bool is_primary;
-
- // primary_time contains the timestamp when this config should become the
- // primary config. A value of QuicWallTime::Zero() means that this config
- // will not be promoted at a specific time.
- QuicWallTime primary_time;
-
- // expiry_time contains the timestamp when this config expires.
- QuicWallTime expiry_time;
-
- // Secondary sort key for use when selecting primary configs and
- // there are multiple configs with the same primary time.
- // Smaller numbers mean higher priority.
- uint64_t priority;
-
- // source_address_token_boxer_ is used to protect the
- // source-address tokens that are given to clients.
- // Points to either source_address_token_boxer_storage or the
- // default boxer provided by QuicCryptoServerConfig.
- const CryptoSecretBoxer* source_address_token_boxer;
-
- // Holds the override source_address_token_boxer instance if the
- // Config is not using the default source address token boxer
- // instance provided by QuicCryptoServerConfig.
- std::unique_ptr<CryptoSecretBoxer> source_address_token_boxer_storage;
-
- private:
- ~Config() override;
- };
-
- using ConfigMap =
- std::map<ServerConfigID, QuicReferenceCountedPointer<Config>>;
-
- // Get a ref to the config with a given server config id.
- QuicReferenceCountedPointer<Config> GetConfigWithScid(
- absl::string_view requested_scid) const
- QUIC_SHARED_LOCKS_REQUIRED(configs_lock_);
-
- // A snapshot of the configs associated with an in-progress handshake.
- struct QUIC_EXPORT_PRIVATE Configs {
- QuicReferenceCountedPointer<Config> requested;
- QuicReferenceCountedPointer<Config> primary;
- QuicReferenceCountedPointer<Config> fallback;
- };
-
- // Get a snapshot of the current configs associated with a handshake. If this
- // method was called earlier in this handshake |old_primary_config| should be
- // set to the primary config returned from that invocation, otherwise nullptr.
- //
- // Returns true if any configs are loaded. If false is returned, |configs| is
- // not modified.
- bool GetCurrentConfigs(const QuicWallTime& now,
- absl::string_view requested_scid,
- QuicReferenceCountedPointer<Config> old_primary_config,
- Configs* configs) const;
-
- // ConfigPrimaryTimeLessThan returns true if a->primary_time <
- // b->primary_time.
- static bool ConfigPrimaryTimeLessThan(
- const QuicReferenceCountedPointer<Config>& a,
- const QuicReferenceCountedPointer<Config>& b);
-
- // SelectNewPrimaryConfig reevaluates the primary config based on the
- // "primary_time" deadlines contained in each.
- void SelectNewPrimaryConfig(QuicWallTime now) const
- QUIC_EXCLUSIVE_LOCKS_REQUIRED(configs_lock_);
-
- // EvaluateClientHello checks |client_hello_state->client_hello| for gross
- // errors and determines whether it is fresh (i.e. not a replay). The results
- // are written to |client_hello_state->info|.
- void EvaluateClientHello(
- const QuicSocketAddress& server_address,
- const QuicSocketAddress& client_address,
- QuicTransportVersion version,
- const Configs& configs,
- QuicReferenceCountedPointer<ValidateClientHelloResultCallback::Result>
- client_hello_state,
- std::unique_ptr<ValidateClientHelloResultCallback> done_cb) const;
-
- // Convenience class which carries the arguments passed to
- // |ProcessClientHellp| along.
- class QUIC_EXPORT_PRIVATE ProcessClientHelloContext {
- public:
- ProcessClientHelloContext(
- QuicReferenceCountedPointer<ValidateClientHelloResultCallback::Result>
- validate_chlo_result,
- bool reject_only,
- QuicConnectionId connection_id,
- const QuicSocketAddress& server_address,
- const QuicSocketAddress& client_address,
- ParsedQuicVersion version,
- const ParsedQuicVersionVector& supported_versions,
- const QuicClock* clock,
- QuicRandom* rand,
- QuicCompressedCertsCache* compressed_certs_cache,
- QuicReferenceCountedPointer<QuicCryptoNegotiatedParameters> params,
- QuicReferenceCountedPointer<QuicSignedServerConfig> signed_config,
- QuicByteCount total_framing_overhead,
- QuicByteCount chlo_packet_size,
- std::unique_ptr<ProcessClientHelloResultCallback> done_cb)
- : validate_chlo_result_(validate_chlo_result),
- reject_only_(reject_only),
- connection_id_(connection_id),
- server_address_(server_address),
- client_address_(client_address),
- version_(version),
- supported_versions_(supported_versions),
- clock_(clock),
- rand_(rand),
- compressed_certs_cache_(compressed_certs_cache),
- params_(params),
- signed_config_(signed_config),
- total_framing_overhead_(total_framing_overhead),
- chlo_packet_size_(chlo_packet_size),
- done_cb_(std::move(done_cb)) {}
-
- ~ProcessClientHelloContext();
-
- // Invoke |done_cb_| with an error status
- void Fail(QuicErrorCode error, const std::string& error_details);
-
- // Invoke |done_cb_| with a success status
- void Succeed(std::unique_ptr<CryptoHandshakeMessage> message,
- std::unique_ptr<DiversificationNonce> diversification_nonce,
- std::unique_ptr<ProofSource::Details> proof_source_details);
-
- // Member accessors
- QuicReferenceCountedPointer<ValidateClientHelloResultCallback::Result>
- validate_chlo_result() const {
- return validate_chlo_result_;
- }
- bool reject_only() const { return reject_only_; }
- QuicConnectionId connection_id() const { return connection_id_; }
- QuicSocketAddress server_address() const { return server_address_; }
- QuicSocketAddress client_address() const { return client_address_; }
- ParsedQuicVersion version() const { return version_; }
- ParsedQuicVersionVector supported_versions() const {
- return supported_versions_;
- }
- const QuicClock* clock() const { return clock_; }
- QuicRandom* rand() const { return rand_; } // NOLINT
- QuicCompressedCertsCache* compressed_certs_cache() const {
- return compressed_certs_cache_;
- }
- QuicReferenceCountedPointer<QuicCryptoNegotiatedParameters> params() const {
- return params_;
- }
- QuicReferenceCountedPointer<QuicSignedServerConfig> signed_config() const {
- return signed_config_;
- }
- QuicByteCount total_framing_overhead() const {
- return total_framing_overhead_;
- }
- QuicByteCount chlo_packet_size() const { return chlo_packet_size_; }
-
- // Derived value accessors
- const CryptoHandshakeMessage& client_hello() const {
- return validate_chlo_result()->client_hello;
- }
- const ClientHelloInfo& info() const { return validate_chlo_result()->info; }
- QuicTransportVersion transport_version() const {
- return version().transport_version;
- }
-
- private:
- const QuicReferenceCountedPointer<ValidateClientHelloResultCallback::Result>
- validate_chlo_result_;
- const bool reject_only_;
- const QuicConnectionId connection_id_;
- const QuicSocketAddress server_address_;
- const QuicSocketAddress client_address_;
- const ParsedQuicVersion version_;
- const ParsedQuicVersionVector supported_versions_;
- const QuicClock* const clock_;
- QuicRandom* const rand_;
- QuicCompressedCertsCache* const compressed_certs_cache_;
- const QuicReferenceCountedPointer<QuicCryptoNegotiatedParameters> params_;
- const QuicReferenceCountedPointer<QuicSignedServerConfig> signed_config_;
- const QuicByteCount total_framing_overhead_;
- const QuicByteCount chlo_packet_size_;
- std::unique_ptr<ProcessClientHelloResultCallback> done_cb_;
- };
-
- // Callback class for bridging between ProcessClientHello and
- // ProcessClientHelloAfterGetProof.
- class ProcessClientHelloCallback;
- friend class ProcessClientHelloCallback;
-
- // Portion of ProcessClientHello which executes after GetProof.
- void ProcessClientHelloAfterGetProof(
- bool found_error,
- std::unique_ptr<ProofSource::Details> proof_source_details,
- std::unique_ptr<ProcessClientHelloContext> context,
- const Configs& configs) const;
-
- // Callback class for bridging between ProcessClientHelloAfterGetProof and
- // ProcessClientHelloAfterCalculateSharedKeys.
- class ProcessClientHelloAfterGetProofCallback;
- friend class ProcessClientHelloAfterGetProofCallback;
-
- // Portion of ProcessClientHello which executes after CalculateSharedKeys.
- void ProcessClientHelloAfterCalculateSharedKeys(
- bool found_error,
- std::unique_ptr<ProofSource::Details> proof_source_details,
- QuicTag key_exchange_type,
- std::unique_ptr<CryptoHandshakeMessage> out,
- absl::string_view public_value,
- std::unique_ptr<ProcessClientHelloContext> context,
- const Configs& configs) const;
-
- // Send a REJ which contains a different ServerConfig than the one the client
- // originally used. This is necessary in cases where we discover in the
- // middle of the handshake that the private key for the ServerConfig the
- // client used is not accessible.
- void SendRejectWithFallbackConfig(
- std::unique_ptr<ProcessClientHelloContext> context,
- QuicReferenceCountedPointer<Config> fallback_config) const;
-
- // Callback class for bridging between SendRejectWithFallbackConfig and
- // SendRejectWithFallbackConfigAfterGetProof.
- class SendRejectWithFallbackConfigCallback;
- friend class SendRejectWithFallbackConfigCallback;
-
- // Portion of ProcessClientHello which executes after GetProof in the case
- // where we have received a CHLO but need to reject it due to the ServerConfig
- // private keys being inaccessible.
- void SendRejectWithFallbackConfigAfterGetProof(
- bool found_error,
- std::unique_ptr<ProofSource::Details> proof_source_details,
- std::unique_ptr<ProcessClientHelloContext> context,
- QuicReferenceCountedPointer<Config> fallback_config) const;
-
- // BuildRejectionAndRecordStats calls |BuildRejection| below and also informs
- // the RejectionObserver.
- void BuildRejectionAndRecordStats(const ProcessClientHelloContext& context,
- const Config& config,
- const std::vector<uint32_t>& reject_reasons,
- CryptoHandshakeMessage* out) const;
-
- // BuildRejection sets |out| to be a REJ message in reply to |client_hello|.
- void BuildRejection(const ProcessClientHelloContext& context,
- const Config& config,
- const std::vector<uint32_t>& reject_reasons,
- CryptoHandshakeMessage* out) const;
-
- // CompressChain compresses the certificates in |chain->certs| and returns a
- // compressed representation. |common_sets| contains the common certificate
- // sets known locally and |client_common_set_hashes| contains the hashes of
- // the common sets known to the peer. |client_cached_cert_hashes| contains
- // 64-bit, FNV-1a hashes of certificates that the peer already possesses.
- static std::string CompressChain(
- QuicCompressedCertsCache* compressed_certs_cache,
- const QuicReferenceCountedPointer<ProofSource::Chain>& chain,
- const std::string& client_common_set_hashes,
- const std::string& client_cached_cert_hashes,
- const CommonCertSets* common_sets);
-
- // ParseConfigProtobuf parses the given config protobuf and returns a
- // QuicReferenceCountedPointer<Config> if successful. The caller adopts the
- // reference to the Config. On error, ParseConfigProtobuf returns nullptr.
- QuicReferenceCountedPointer<Config> ParseConfigProtobuf(
- const QuicServerConfigProtobuf& protobuf,
- bool is_fallback) const;
-
- // ValidateSingleSourceAddressToken returns HANDSHAKE_OK if the source
- // address token in |token| is a timely token for the IP address |ip|
- // given that the current time is |now|. Otherwise it returns the reason
- // for failure.
- HandshakeFailureReason ValidateSingleSourceAddressToken(
- const SourceAddressToken& token,
- const QuicIpAddress& ip,
- QuicWallTime now) const;
-
- // Returns HANDSHAKE_OK if the source address token in |token| is a timely
- // token given that the current time is |now|. Otherwise it returns the
- // reason for failure.
- HandshakeFailureReason ValidateSourceAddressTokenTimestamp(
- const SourceAddressToken& token,
- QuicWallTime now) const;
-
- // NewServerNonce generates and encrypts a random nonce.
- std::string NewServerNonce(QuicRandom* rand, QuicWallTime now) const;
-
- // ValidateExpectedLeafCertificate checks the |client_hello| to see if it has
- // an XLCT tag, and if so, verifies that its value matches the hash of the
- // server's leaf certificate. |certs| is used to compare against the XLCT
- // value. This method returns true if the XLCT tag is not present, or if the
- // XLCT tag is present and valid. It returns false otherwise.
- bool ValidateExpectedLeafCertificate(
- const CryptoHandshakeMessage& client_hello,
- const std::vector<std::string>& certs) const;
-
- // Callback to receive the results of ProofSource::GetProof. Note: this
- // callback has no cancellation support, since the lifetime of the ProofSource
- // is controlled by this object via unique ownership. If that ownership
- // stricture changes, this decision may need to be revisited.
- class BuildServerConfigUpdateMessageProofSourceCallback
- : public ProofSource::Callback {
- public:
- BuildServerConfigUpdateMessageProofSourceCallback(
- const BuildServerConfigUpdateMessageProofSourceCallback&) = delete;
- ~BuildServerConfigUpdateMessageProofSourceCallback() override;
- void operator=(const BuildServerConfigUpdateMessageProofSourceCallback&) =
- delete;
- BuildServerConfigUpdateMessageProofSourceCallback(
- const QuicCryptoServerConfig* config,
- QuicCompressedCertsCache* compressed_certs_cache,
- const CommonCertSets* common_cert_sets,
- const QuicCryptoNegotiatedParameters& params,
- CryptoHandshakeMessage message,
- std::unique_ptr<BuildServerConfigUpdateMessageResultCallback> cb);
-
- void Run(bool ok,
- const QuicReferenceCountedPointer<ProofSource::Chain>& chain,
- const QuicCryptoProof& proof,
- std::unique_ptr<ProofSource::Details> details) override;
-
- private:
- const QuicCryptoServerConfig* config_;
- QuicCompressedCertsCache* compressed_certs_cache_;
- const CommonCertSets* common_cert_sets_;
- const std::string client_common_set_hashes_;
- const std::string client_cached_cert_hashes_;
- const bool sct_supported_by_client_;
- const std::string sni_;
- CryptoHandshakeMessage message_;
- std::unique_ptr<BuildServerConfigUpdateMessageResultCallback> cb_;
- };
-
- // Invoked by BuildServerConfigUpdateMessageProofSourceCallback::Run once
- // the proof has been acquired. Finishes building the server config update
- // message and invokes |cb|.
- void FinishBuildServerConfigUpdateMessage(
- QuicCompressedCertsCache* compressed_certs_cache,
- const CommonCertSets* common_cert_sets,
- const std::string& client_common_set_hashes,
- const std::string& client_cached_cert_hashes,
- bool sct_supported_by_client,
- const std::string& sni,
- bool ok,
- const QuicReferenceCountedPointer<ProofSource::Chain>& chain,
- const std::string& signature,
- const std::string& leaf_cert_sct,
- std::unique_ptr<ProofSource::Details> details,
- CryptoHandshakeMessage message,
- std::unique_ptr<BuildServerConfigUpdateMessageResultCallback> cb) const;
-
- // Returns true if the next config promotion should happen now.
- bool IsNextConfigReady(QuicWallTime now) const
- QUIC_SHARED_LOCKS_REQUIRED(configs_lock_);
-
- // replay_protection_ controls whether the server enforces that handshakes
- // aren't replays.
- bool replay_protection_;
-
- // The multiple of the CHLO message size that a REJ message must stay under
- // when the client doesn't present a valid source-address token. This is
- // used to protect QUIC from amplification attacks.
- size_t chlo_multiplier_;
-
- // configs_ satisfies the following invariants:
- // 1) configs_.empty() <-> primary_config_ == nullptr
- // 2) primary_config_ != nullptr -> primary_config_->is_primary
- // 3) ∀ c∈configs_, c->is_primary <-> c == primary_config_
- mutable QuicMutex configs_lock_;
-
- // configs_ contains all active server configs. It's expected that there are
- // about half-a-dozen configs active at any one time.
- ConfigMap configs_ QUIC_GUARDED_BY(configs_lock_);
-
- // primary_config_ points to a Config (which is also in |configs_|) which is
- // the primary config - i.e. the one that we'll give out to new clients.
- mutable QuicReferenceCountedPointer<Config> primary_config_
- QUIC_GUARDED_BY(configs_lock_);
-
- // fallback_config_ points to a Config (which is also in |configs_|) which is
- // the fallback config, which will be used if the other configs are unuseable
- // for some reason.
- //
- // TODO(b/112548056): This is currently always nullptr.
- QuicReferenceCountedPointer<Config> fallback_config_
- QUIC_GUARDED_BY(configs_lock_);
-
- // next_config_promotion_time_ contains the nearest, future time when an
- // active config will be promoted to primary.
- mutable QuicWallTime next_config_promotion_time_
- QUIC_GUARDED_BY(configs_lock_);
-
- // Callback to invoke when the primary config changes.
- std::unique_ptr<PrimaryConfigChangedCallback> primary_config_changed_cb_
- QUIC_GUARDED_BY(configs_lock_);
-
- // Used to protect the source-address tokens that are given to clients.
- CryptoSecretBoxer source_address_token_boxer_;
-
- // server_nonce_boxer_ is used to encrypt and validate suggested server
- // nonces.
- CryptoSecretBoxer server_nonce_boxer_;
-
- // server_nonce_orbit_ contains the random, per-server orbit values that this
- // server will use to generate server nonces (the moral equivalent of a SYN
- // cookies).
- uint8_t server_nonce_orbit_[8];
-
- // proof_source_ contains an object that can provide certificate chains and
- // signatures.
- std::unique_ptr<ProofSource> proof_source_;
-
- // key_exchange_source_ contains an object that can provide key exchange
- // objects.
- std::unique_ptr<KeyExchangeSource> key_exchange_source_;
-
- // ssl_ctx_ contains the server configuration for doing TLS handshakes.
- bssl::UniquePtr<SSL_CTX> ssl_ctx_;
-
- // These fields store configuration values. See the comments for their
- // respective setter functions.
- uint32_t source_address_token_future_secs_;
- uint32_t source_address_token_lifetime_secs_;
-
- // Enable serving SCT or not.
- bool enable_serving_sct_;
-
- // Does not own this observer.
- RejectionObserver* rejection_observer_;
-
- // If non-empty, the server will operate in the pre-shared key mode by
- // incorporating |pre_shared_key_| into the key schedule.
- std::string pre_shared_key_;
-
- // Whether REJ message should be padded to max packet size.
- bool pad_rej_;
-
- // Whether SHLO message should be padded to max packet size.
- bool pad_shlo_;
-
- // If client is allowed to send a small client hello (by disabling padding),
- // server MUST not check for the client hello size.
- // DO NOT disable this unless you have some other way of validating client.
- // (e.g. in realtime scenarios, where quic is tunneled through ICE, ICE will
- // do its own peer validation using STUN pings with ufrag/upass).
- bool validate_chlo_size_;
-
- // When source address is validated by some other means (e.g. when using ICE),
- // source address token validation may be disabled.
- bool validate_source_address_token_;
-};
-
-struct QUIC_EXPORT_PRIVATE QuicSignedServerConfig
- : public QuicReferenceCounted {
- QuicSignedServerConfig();
-
- QuicCryptoProof proof;
- QuicReferenceCountedPointer<ProofSource::Chain> chain;
- // The server config that is used for this proof (and the rest of the
- // request).
- QuicReferenceCountedPointer<QuicCryptoServerConfig::Config> config;
- std::string primary_scid;
-
- protected:
- ~QuicSignedServerConfig() override;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_CRYPTO_QUIC_CRYPTO_SERVER_CONFIG_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/quic_crypto_server_config_test.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/quic_crypto_server_config_test.cc
deleted file mode 100644
index 484e46eee6a..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/quic_crypto_server_config_test.cc
+++ /dev/null
@@ -1,513 +0,0 @@
-// Copyright 2013 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 "quic/core/crypto/quic_crypto_server_config.h"
-
-#include <stdarg.h>
-
-#include <memory>
-#include <string>
-
-#include "absl/strings/match.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/crypto/cert_compressor.h"
-#include "quic/core/crypto/chacha20_poly1305_encrypter.h"
-#include "quic/core/crypto/crypto_handshake_message.h"
-#include "quic/core/crypto/crypto_secret_boxer.h"
-#include "quic/core/crypto/quic_random.h"
-#include "quic/core/proto/crypto_server_config_proto.h"
-#include "quic/core/quic_time.h"
-#include "quic/core/quic_versions.h"
-#include "quic/platform/api/quic_socket_address.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/crypto_test_utils.h"
-#include "quic/test_tools/mock_clock.h"
-#include "quic/test_tools/quic_crypto_server_config_peer.h"
-#include "quic/test_tools/quic_test_utils.h"
-
-namespace quic {
-namespace test {
-using ::testing::Not;
-
-// NOTE: This matcher depends on the wire format of serialzied protocol buffers,
-// which may change in the future.
-// Switch to ::testing::EqualsProto once it is available in Chromium.
-MATCHER_P(SerializedProtoEquals, message, "") {
- std::string expected_serialized, actual_serialized;
- message.SerializeToString(&expected_serialized);
- arg.SerializeToString(&actual_serialized);
- return expected_serialized == actual_serialized;
-}
-
-class QuicCryptoServerConfigTest : public QuicTest {};
-
-TEST_F(QuicCryptoServerConfigTest, ServerConfig) {
- QuicRandom* rand = QuicRandom::GetInstance();
- QuicCryptoServerConfig server(QuicCryptoServerConfig::TESTING, rand,
- crypto_test_utils::ProofSourceForTesting(),
- KeyExchangeSource::Default());
- MockClock clock;
-
- std::unique_ptr<CryptoHandshakeMessage> message(server.AddDefaultConfig(
- rand, &clock, QuicCryptoServerConfig::ConfigOptions()));
-
- // The default configuration should have AES-GCM and at least one ChaCha20
- // cipher.
- QuicTagVector aead;
- ASSERT_THAT(message->GetTaglist(kAEAD, &aead), IsQuicNoError());
- EXPECT_THAT(aead, ::testing::Contains(kAESG));
- EXPECT_LE(1u, aead.size());
-}
-
-TEST_F(QuicCryptoServerConfigTest, CompressCerts) {
- QuicCompressedCertsCache compressed_certs_cache(
- QuicCompressedCertsCache::kQuicCompressedCertsCacheSize);
-
- QuicRandom* rand = QuicRandom::GetInstance();
- QuicCryptoServerConfig server(QuicCryptoServerConfig::TESTING, rand,
- crypto_test_utils::ProofSourceForTesting(),
- KeyExchangeSource::Default());
- QuicCryptoServerConfigPeer peer(&server);
-
- std::vector<std::string> certs = {"testcert"};
- QuicReferenceCountedPointer<ProofSource::Chain> chain(
- new ProofSource::Chain(certs));
-
- std::string compressed = QuicCryptoServerConfigPeer::CompressChain(
- &compressed_certs_cache, chain, "", "", nullptr);
-
- EXPECT_EQ(compressed_certs_cache.Size(), 1u);
-}
-
-TEST_F(QuicCryptoServerConfigTest, CompressSameCertsTwice) {
- QuicCompressedCertsCache compressed_certs_cache(
- QuicCompressedCertsCache::kQuicCompressedCertsCacheSize);
-
- QuicRandom* rand = QuicRandom::GetInstance();
- QuicCryptoServerConfig server(QuicCryptoServerConfig::TESTING, rand,
- crypto_test_utils::ProofSourceForTesting(),
- KeyExchangeSource::Default());
- QuicCryptoServerConfigPeer peer(&server);
-
- // Compress the certs for the first time.
- std::vector<std::string> certs = {"testcert"};
- QuicReferenceCountedPointer<ProofSource::Chain> chain(
- new ProofSource::Chain(certs));
- std::string common_certs = "";
- std::string cached_certs = "";
-
- std::string compressed = QuicCryptoServerConfigPeer::CompressChain(
- &compressed_certs_cache, chain, common_certs, cached_certs, nullptr);
- EXPECT_EQ(compressed_certs_cache.Size(), 1u);
-
- // Compress the same certs, should use cache if available.
- std::string compressed2 = QuicCryptoServerConfigPeer::CompressChain(
- &compressed_certs_cache, chain, common_certs, cached_certs, nullptr);
- EXPECT_EQ(compressed, compressed2);
- EXPECT_EQ(compressed_certs_cache.Size(), 1u);
-}
-
-TEST_F(QuicCryptoServerConfigTest, CompressDifferentCerts) {
- // This test compresses a set of similar but not identical certs. Cache if
- // used should return cache miss and add all the compressed certs.
- QuicCompressedCertsCache compressed_certs_cache(
- QuicCompressedCertsCache::kQuicCompressedCertsCacheSize);
-
- QuicRandom* rand = QuicRandom::GetInstance();
- QuicCryptoServerConfig server(QuicCryptoServerConfig::TESTING, rand,
- crypto_test_utils::ProofSourceForTesting(),
- KeyExchangeSource::Default());
- QuicCryptoServerConfigPeer peer(&server);
-
- std::vector<std::string> certs = {"testcert"};
- QuicReferenceCountedPointer<ProofSource::Chain> chain(
- new ProofSource::Chain(certs));
- std::string common_certs = "";
- std::string cached_certs = "";
-
- std::string compressed = QuicCryptoServerConfigPeer::CompressChain(
- &compressed_certs_cache, chain, common_certs, cached_certs, nullptr);
- EXPECT_EQ(compressed_certs_cache.Size(), 1u);
-
- // Compress a similar certs which only differs in the chain.
- QuicReferenceCountedPointer<ProofSource::Chain> chain2(
- new ProofSource::Chain(certs));
-
- std::string compressed2 = QuicCryptoServerConfigPeer::CompressChain(
- &compressed_certs_cache, chain2, common_certs, cached_certs, nullptr);
- EXPECT_EQ(compressed_certs_cache.Size(), 2u);
-
- // Compress a similar certs which only differs in common certs field.
- static const uint64_t set_hash = 42;
- std::unique_ptr<CommonCertSets> common_sets(
- crypto_test_utils::MockCommonCertSets(certs[0], set_hash, 1));
- absl::string_view different_common_certs(
- reinterpret_cast<const char*>(&set_hash), sizeof(set_hash));
- std::string compressed3 = QuicCryptoServerConfigPeer::CompressChain(
- &compressed_certs_cache, chain, std::string(different_common_certs),
- cached_certs, common_sets.get());
- EXPECT_EQ(compressed_certs_cache.Size(), 3u);
-}
-
-class SourceAddressTokenTest : public QuicTest {
- public:
- SourceAddressTokenTest()
- : ip4_(QuicIpAddress::Loopback4()),
- ip4_dual_(ip4_.DualStacked()),
- ip6_(QuicIpAddress::Loopback6()),
- original_time_(QuicWallTime::Zero()),
- rand_(QuicRandom::GetInstance()),
- server_(QuicCryptoServerConfig::TESTING,
- rand_,
- crypto_test_utils::ProofSourceForTesting(),
- KeyExchangeSource::Default()),
- peer_(&server_) {
- // Advance the clock to some non-zero time.
- clock_.AdvanceTime(QuicTime::Delta::FromSeconds(1000000));
- original_time_ = clock_.WallNow();
-
- primary_config_ = server_.AddDefaultConfig(
- rand_, &clock_, QuicCryptoServerConfig::ConfigOptions());
- }
-
- std::string NewSourceAddressToken(std::string config_id,
- const QuicIpAddress& ip) {
- return NewSourceAddressToken(config_id, ip, nullptr);
- }
-
- std::string NewSourceAddressToken(
- std::string config_id,
- const QuicIpAddress& ip,
- const SourceAddressTokens& previous_tokens) {
- return peer_.NewSourceAddressToken(config_id, previous_tokens, ip, rand_,
- clock_.WallNow(), nullptr);
- }
-
- std::string NewSourceAddressToken(
- std::string config_id,
- const QuicIpAddress& ip,
- CachedNetworkParameters* cached_network_params) {
- SourceAddressTokens previous_tokens;
- return peer_.NewSourceAddressToken(config_id, previous_tokens, ip, rand_,
- clock_.WallNow(), cached_network_params);
- }
-
- HandshakeFailureReason ValidateSourceAddressTokens(std::string config_id,
- absl::string_view srct,
- const QuicIpAddress& ip) {
- return ValidateSourceAddressTokens(config_id, srct, ip, nullptr);
- }
-
- HandshakeFailureReason ValidateSourceAddressTokens(
- std::string config_id,
- absl::string_view srct,
- const QuicIpAddress& ip,
- CachedNetworkParameters* cached_network_params) {
- return peer_.ValidateSourceAddressTokens(
- config_id, srct, ip, clock_.WallNow(), cached_network_params);
- }
-
- const std::string kPrimary = "<primary>";
- const std::string kOverride = "Config with custom source address token key";
-
- QuicIpAddress ip4_;
- QuicIpAddress ip4_dual_;
- QuicIpAddress ip6_;
-
- MockClock clock_;
- QuicWallTime original_time_;
- QuicRandom* rand_ = QuicRandom::GetInstance();
- QuicCryptoServerConfig server_;
- QuicCryptoServerConfigPeer peer_;
- // Stores the primary config.
- std::unique_ptr<CryptoHandshakeMessage> primary_config_;
- std::unique_ptr<QuicServerConfigProtobuf> override_config_protobuf_;
-};
-
-// Test basic behavior of source address tokens including being specific
-// to a single IP address and server config.
-TEST_F(SourceAddressTokenTest, SourceAddressToken) {
- // Primary config generates configs that validate successfully.
- const std::string token4 = NewSourceAddressToken(kPrimary, ip4_);
- const std::string token4d = NewSourceAddressToken(kPrimary, ip4_dual_);
- const std::string token6 = NewSourceAddressToken(kPrimary, ip6_);
- EXPECT_EQ(HANDSHAKE_OK, ValidateSourceAddressTokens(kPrimary, token4, ip4_));
- ASSERT_EQ(HANDSHAKE_OK,
- ValidateSourceAddressTokens(kPrimary, token4, ip4_dual_));
- ASSERT_EQ(SOURCE_ADDRESS_TOKEN_DIFFERENT_IP_ADDRESS_FAILURE,
- ValidateSourceAddressTokens(kPrimary, token4, ip6_));
- ASSERT_EQ(HANDSHAKE_OK, ValidateSourceAddressTokens(kPrimary, token4d, ip4_));
- ASSERT_EQ(HANDSHAKE_OK,
- ValidateSourceAddressTokens(kPrimary, token4d, ip4_dual_));
- ASSERT_EQ(SOURCE_ADDRESS_TOKEN_DIFFERENT_IP_ADDRESS_FAILURE,
- ValidateSourceAddressTokens(kPrimary, token4d, ip6_));
- ASSERT_EQ(HANDSHAKE_OK, ValidateSourceAddressTokens(kPrimary, token6, ip6_));
-}
-
-TEST_F(SourceAddressTokenTest, SourceAddressTokenExpiration) {
- const std::string token = NewSourceAddressToken(kPrimary, ip4_);
-
- // Validation fails if the token is from the future.
- clock_.AdvanceTime(QuicTime::Delta::FromSeconds(-3600 * 2));
- ASSERT_EQ(SOURCE_ADDRESS_TOKEN_CLOCK_SKEW_FAILURE,
- ValidateSourceAddressTokens(kPrimary, token, ip4_));
-
- // Validation fails after tokens expire.
- clock_.AdvanceTime(QuicTime::Delta::FromSeconds(86400 * 7));
- ASSERT_EQ(SOURCE_ADDRESS_TOKEN_EXPIRED_FAILURE,
- ValidateSourceAddressTokens(kPrimary, token, ip4_));
-}
-
-TEST_F(SourceAddressTokenTest, SourceAddressTokenWithNetworkParams) {
- // Make sure that if the source address token contains CachedNetworkParameters
- // that this gets written to ValidateSourceAddressToken output argument.
- CachedNetworkParameters cached_network_params_input;
- cached_network_params_input.set_bandwidth_estimate_bytes_per_second(1234);
- const std::string token4_with_cached_network_params =
- NewSourceAddressToken(kPrimary, ip4_, &cached_network_params_input);
-
- CachedNetworkParameters cached_network_params_output;
- EXPECT_THAT(cached_network_params_output,
- Not(SerializedProtoEquals(cached_network_params_input)));
- ValidateSourceAddressTokens(kPrimary, token4_with_cached_network_params, ip4_,
- &cached_network_params_output);
- EXPECT_THAT(cached_network_params_output,
- SerializedProtoEquals(cached_network_params_input));
-}
-
-// Test the ability for a source address token to be valid for multiple
-// addresses.
-TEST_F(SourceAddressTokenTest, SourceAddressTokenMultipleAddresses) {
- QuicWallTime now = clock_.WallNow();
-
- // Now create a token which is usable for both addresses.
- SourceAddressToken previous_token;
- previous_token.set_ip(ip6_.DualStacked().ToPackedString());
- previous_token.set_timestamp(now.ToUNIXSeconds());
- SourceAddressTokens previous_tokens;
- (*previous_tokens.add_tokens()) = previous_token;
- const std::string token4or6 =
- NewSourceAddressToken(kPrimary, ip4_, previous_tokens);
-
- EXPECT_EQ(HANDSHAKE_OK,
- ValidateSourceAddressTokens(kPrimary, token4or6, ip4_));
- ASSERT_EQ(HANDSHAKE_OK,
- ValidateSourceAddressTokens(kPrimary, token4or6, ip6_));
-}
-
-class CryptoServerConfigsTest : public QuicTest {
- public:
- CryptoServerConfigsTest()
- : rand_(QuicRandom::GetInstance()),
- config_(QuicCryptoServerConfig::TESTING,
- rand_,
- crypto_test_utils::ProofSourceForTesting(),
- KeyExchangeSource::Default()),
- test_peer_(&config_) {}
-
- void SetUp() override {
- clock_.AdvanceTime(QuicTime::Delta::FromSeconds(1000));
- }
-
- // SetConfigs constructs suitable config protobufs and calls SetConfigs on
- // |config_|.
- // Each struct in the input vector contains 3 elements.
- // The first is the server config ID of a Config. The second is
- // the |primary_time| of that Config, given in epoch seconds. (Although note
- // that, in these tests, time is set to 1000 seconds since the epoch.).
- // The third is the priority.
- //
- // For example:
- // SetConfigs(std::vector<ServerConfigIDWithTimeAndPriority>()); // calls
- // |config_.SetConfigs| with no protobufs.
- //
- // // Calls |config_.SetConfigs| with two protobufs: one for a Config with
- // // a |primary_time| of 900 and priority 1, and another with
- // // a |primary_time| of 1000 and priority 2.
-
- // CheckConfigs(
- // {{"id1", 900, 1},
- // {"id2", 1000, 2}});
- //
- // If the server config id starts with "INVALID" then the generated protobuf
- // will be invalid.
- struct ServerConfigIDWithTimeAndPriority {
- ServerConfigID server_config_id;
- int primary_time;
- int priority;
- };
- void SetConfigs(std::vector<ServerConfigIDWithTimeAndPriority> configs) {
- const char kOrbit[] = "12345678";
-
- bool has_invalid = false;
-
- std::vector<QuicServerConfigProtobuf> protobufs;
- for (const auto& config : configs) {
- const ServerConfigID& server_config_id = config.server_config_id;
- const int primary_time = config.primary_time;
- const int priority = config.priority;
-
- QuicCryptoServerConfig::ConfigOptions options;
- options.id = server_config_id;
- options.orbit = kOrbit;
- QuicServerConfigProtobuf protobuf =
- QuicCryptoServerConfig::GenerateConfig(rand_, &clock_, options);
- protobuf.set_primary_time(primary_time);
- protobuf.set_priority(priority);
- if (absl::StartsWith(std::string(server_config_id), "INVALID")) {
- protobuf.clear_key();
- has_invalid = true;
- }
- protobufs.push_back(std::move(protobuf));
- }
-
- ASSERT_EQ(!has_invalid && !configs.empty(),
- config_.SetConfigs(protobufs, /* fallback_protobuf = */ nullptr,
- clock_.WallNow()));
- }
-
- protected:
- QuicRandom* const rand_;
- MockClock clock_;
- QuicCryptoServerConfig config_;
- QuicCryptoServerConfigPeer test_peer_;
-};
-
-TEST_F(CryptoServerConfigsTest, NoConfigs) {
- test_peer_.CheckConfigs(std::vector<std::pair<std::string, bool>>());
-}
-
-TEST_F(CryptoServerConfigsTest, MakePrimaryFirst) {
- // Make sure that "b" is primary even though "a" comes first.
- SetConfigs({{"a", 1100, 1}, {"b", 900, 1}});
- test_peer_.CheckConfigs({{"a", false}, {"b", true}});
-}
-
-TEST_F(CryptoServerConfigsTest, MakePrimarySecond) {
- // Make sure that a remains primary after b is added.
- SetConfigs({{"a", 900, 1}, {"b", 1100, 1}});
- test_peer_.CheckConfigs({{"a", true}, {"b", false}});
-}
-
-TEST_F(CryptoServerConfigsTest, Delete) {
- // Ensure that configs get deleted when removed.
- SetConfigs({{"a", 800, 1}, {"b", 900, 1}, {"c", 1100, 1}});
- test_peer_.CheckConfigs({{"a", false}, {"b", true}, {"c", false}});
- SetConfigs({{"b", 900, 1}, {"c", 1100, 1}});
- test_peer_.CheckConfigs({{"b", true}, {"c", false}});
-}
-
-TEST_F(CryptoServerConfigsTest, DeletePrimary) {
- // Ensure that deleting the primary config works.
- SetConfigs({{"a", 800, 1}, {"b", 900, 1}, {"c", 1100, 1}});
- test_peer_.CheckConfigs({{"a", false}, {"b", true}, {"c", false}});
- SetConfigs({{"a", 800, 1}, {"c", 1100, 1}});
- test_peer_.CheckConfigs({{"a", true}, {"c", false}});
-}
-
-TEST_F(CryptoServerConfigsTest, FailIfDeletingAllConfigs) {
- // Ensure that configs get deleted when removed.
- SetConfigs({{"a", 800, 1}, {"b", 900, 1}});
- test_peer_.CheckConfigs({{"a", false}, {"b", true}});
- SetConfigs(std::vector<ServerConfigIDWithTimeAndPriority>());
- // Config change is rejected, still using old configs.
- test_peer_.CheckConfigs({{"a", false}, {"b", true}});
-}
-
-TEST_F(CryptoServerConfigsTest, ChangePrimaryTime) {
- // Check that updates to primary time get picked up.
- SetConfigs({{"a", 400, 1}, {"b", 800, 1}, {"c", 1200, 1}});
- test_peer_.SelectNewPrimaryConfig(500);
- test_peer_.CheckConfigs({{"a", true}, {"b", false}, {"c", false}});
- SetConfigs({{"a", 1200, 1}, {"b", 800, 1}, {"c", 400, 1}});
- test_peer_.SelectNewPrimaryConfig(500);
- test_peer_.CheckConfigs({{"a", false}, {"b", false}, {"c", true}});
-}
-
-TEST_F(CryptoServerConfigsTest, AllConfigsInThePast) {
- // Check that the most recent config is selected.
- SetConfigs({{"a", 400, 1}, {"b", 800, 1}, {"c", 1200, 1}});
- test_peer_.SelectNewPrimaryConfig(1500);
- test_peer_.CheckConfigs({{"a", false}, {"b", false}, {"c", true}});
-}
-
-TEST_F(CryptoServerConfigsTest, AllConfigsInTheFuture) {
- // Check that the first config is selected.
- SetConfigs({{"a", 400, 1}, {"b", 800, 1}, {"c", 1200, 1}});
- test_peer_.SelectNewPrimaryConfig(100);
- test_peer_.CheckConfigs({{"a", true}, {"b", false}, {"c", false}});
-}
-
-TEST_F(CryptoServerConfigsTest, SortByPriority) {
- // Check that priority is used to decide on a primary config when
- // configs have the same primary time.
- SetConfigs({{"a", 900, 1}, {"b", 900, 2}, {"c", 900, 3}});
- test_peer_.CheckConfigs({{"a", true}, {"b", false}, {"c", false}});
- test_peer_.SelectNewPrimaryConfig(800);
- test_peer_.CheckConfigs({{"a", true}, {"b", false}, {"c", false}});
- test_peer_.SelectNewPrimaryConfig(1000);
- test_peer_.CheckConfigs({{"a", true}, {"b", false}, {"c", false}});
-
- // Change priorities and expect sort order to change.
- SetConfigs({{"a", 900, 2}, {"b", 900, 1}, {"c", 900, 0}});
- test_peer_.CheckConfigs({{"a", false}, {"b", false}, {"c", true}});
- test_peer_.SelectNewPrimaryConfig(800);
- test_peer_.CheckConfigs({{"a", false}, {"b", false}, {"c", true}});
- test_peer_.SelectNewPrimaryConfig(1000);
- test_peer_.CheckConfigs({{"a", false}, {"b", false}, {"c", true}});
-}
-
-TEST_F(CryptoServerConfigsTest, AdvancePrimary) {
- // Check that a new primary config is enabled at the right time.
- SetConfigs({{"a", 900, 1}, {"b", 1100, 1}});
- test_peer_.SelectNewPrimaryConfig(1000);
- test_peer_.CheckConfigs({{"a", true}, {"b", false}});
- test_peer_.SelectNewPrimaryConfig(1101);
- test_peer_.CheckConfigs({{"a", false}, {"b", true}});
-}
-
-class ValidateCallback : public ValidateClientHelloResultCallback {
- public:
- void Run(QuicReferenceCountedPointer<Result> /*result*/,
- std::unique_ptr<ProofSource::Details> /*details*/) override {}
-};
-
-TEST_F(CryptoServerConfigsTest, AdvancePrimaryViaValidate) {
- // Check that a new primary config is enabled at the right time.
- SetConfigs({{"a", 900, 1}, {"b", 1100, 1}});
- test_peer_.SelectNewPrimaryConfig(1000);
- test_peer_.CheckConfigs({{"a", true}, {"b", false}});
- CryptoHandshakeMessage client_hello;
- QuicSocketAddress client_address;
- QuicSocketAddress server_address;
- QuicTransportVersion transport_version = QUIC_VERSION_UNSUPPORTED;
- for (const ParsedQuicVersion& version : AllSupportedVersions()) {
- if (version.handshake_protocol == PROTOCOL_QUIC_CRYPTO) {
- transport_version = version.transport_version;
- break;
- }
- }
- ASSERT_NE(transport_version, QUIC_VERSION_UNSUPPORTED);
- MockClock clock;
- QuicReferenceCountedPointer<QuicSignedServerConfig> signed_config(
- new QuicSignedServerConfig);
- std::unique_ptr<ValidateClientHelloResultCallback> done_cb(
- new ValidateCallback);
- clock.AdvanceTime(QuicTime::Delta::FromSeconds(1100));
- config_.ValidateClientHello(client_hello, client_address, server_address,
- transport_version, &clock, signed_config,
- std::move(done_cb));
- test_peer_.CheckConfigs({{"a", false}, {"b", true}});
-}
-
-TEST_F(CryptoServerConfigsTest, InvalidConfigs) {
- // Ensure that invalid configs don't change anything.
- SetConfigs({{"a", 800, 1}, {"b", 900, 1}, {"c", 1100, 1}});
- test_peer_.CheckConfigs({{"a", false}, {"b", true}, {"c", false}});
- SetConfigs({{"a", 800, 1}, {"c", 1100, 1}, {"INVALID1", 1000, 1}});
- test_peer_.CheckConfigs({{"a", false}, {"b", true}, {"c", false}});
-}
-
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/quic_decrypter.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/quic_decrypter.cc
deleted file mode 100644
index bd3a0c385e7..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/quic_decrypter.cc
+++ /dev/null
@@ -1,80 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/crypto/quic_decrypter.h"
-
-#include <string>
-#include <utility>
-
-#include "absl/strings/string_view.h"
-#include "third_party/boringssl/src/include/openssl/tls1.h"
-#include "quic/core/crypto/aes_128_gcm_12_decrypter.h"
-#include "quic/core/crypto/aes_128_gcm_decrypter.h"
-#include "quic/core/crypto/aes_256_gcm_decrypter.h"
-#include "quic/core/crypto/chacha20_poly1305_decrypter.h"
-#include "quic/core/crypto/chacha20_poly1305_tls_decrypter.h"
-#include "quic/core/crypto/crypto_protocol.h"
-#include "quic/core/crypto/null_decrypter.h"
-#include "quic/core/crypto/quic_hkdf.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-// static
-std::unique_ptr<QuicDecrypter> QuicDecrypter::Create(
- const ParsedQuicVersion& version,
- QuicTag algorithm) {
- switch (algorithm) {
- case kAESG:
- if (version.UsesInitialObfuscators()) {
- return std::make_unique<Aes128GcmDecrypter>();
- } else {
- return std::make_unique<Aes128Gcm12Decrypter>();
- }
- case kCC20:
- if (version.UsesInitialObfuscators()) {
- return std::make_unique<ChaCha20Poly1305TlsDecrypter>();
- } else {
- return std::make_unique<ChaCha20Poly1305Decrypter>();
- }
- default:
- QUIC_LOG(FATAL) << "Unsupported algorithm: " << algorithm;
- return nullptr;
- }
-}
-
-// static
-std::unique_ptr<QuicDecrypter> QuicDecrypter::CreateFromCipherSuite(
- uint32_t cipher_suite) {
- switch (cipher_suite) {
- case TLS1_CK_AES_128_GCM_SHA256:
- return std::make_unique<Aes128GcmDecrypter>();
- case TLS1_CK_AES_256_GCM_SHA384:
- return std::make_unique<Aes256GcmDecrypter>();
- case TLS1_CK_CHACHA20_POLY1305_SHA256:
- return std::make_unique<ChaCha20Poly1305TlsDecrypter>();
- default:
- QUIC_BUG(quic_bug_10660_1) << "TLS cipher suite is unknown to QUIC";
- return nullptr;
- }
-}
-
-// static
-void QuicDecrypter::DiversifyPreliminaryKey(absl::string_view preliminary_key,
- absl::string_view nonce_prefix,
- const DiversificationNonce& nonce,
- size_t key_size,
- size_t nonce_prefix_size,
- std::string* out_key,
- std::string* out_nonce_prefix) {
- QuicHKDF hkdf((std::string(preliminary_key)) + (std::string(nonce_prefix)),
- absl::string_view(nonce.data(), nonce.size()),
- "QUIC key diversification", 0, key_size, 0, nonce_prefix_size,
- 0);
- *out_key = std::string(hkdf.server_write_key());
- *out_nonce_prefix = std::string(hkdf.server_write_iv());
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/quic_decrypter.h b/chromium/net/third_party/quiche/src/quic/core/crypto/quic_decrypter.h
deleted file mode 100644
index 73f84c9481d..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/quic_decrypter.h
+++ /dev/null
@@ -1,95 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_CRYPTO_QUIC_DECRYPTER_H_
-#define QUICHE_QUIC_CORE_CRYPTO_QUIC_DECRYPTER_H_
-
-#include <cstddef>
-#include <cstdint>
-#include <memory>
-#include <string>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/crypto/quic_crypter.h"
-#include "quic/core/quic_data_reader.h"
-#include "quic/core/quic_packets.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-class QUIC_EXPORT_PRIVATE QuicDecrypter : public QuicCrypter {
- public:
- virtual ~QuicDecrypter() {}
-
- static std::unique_ptr<QuicDecrypter> Create(const ParsedQuicVersion& version,
- QuicTag algorithm);
-
- // Creates an IETF QuicDecrypter based on |cipher_suite| which must be an id
- // returned by SSL_CIPHER_get_id. The caller is responsible for taking
- // ownership of the new QuicDecrypter.
- static std::unique_ptr<QuicDecrypter> CreateFromCipherSuite(
- uint32_t cipher_suite);
-
- // Sets the encryption key. Returns true on success, false on failure.
- // |DecryptPacket| may not be called until |SetDiversificationNonce| is
- // called and the preliminary keying material will be combined with that
- // nonce in order to create the actual key and nonce-prefix.
- //
- // If this function is called, neither |SetKey| nor |SetNoncePrefix| may be
- // called.
- virtual bool SetPreliminaryKey(absl::string_view key) = 0;
-
- // SetDiversificationNonce uses |nonce| to derive final keys based on the
- // input keying material given by calling |SetPreliminaryKey|.
- //
- // Calling this function is a no-op if |SetPreliminaryKey| hasn't been
- // called.
- virtual bool SetDiversificationNonce(const DiversificationNonce& nonce) = 0;
-
- // Populates |output| with the decrypted |ciphertext| and populates
- // |output_length| with the length. Returns 0 if there is an error.
- // |output| size is specified by |max_output_length| and must be
- // at least as large as the ciphertext. |packet_number| is
- // appended to the |nonce_prefix| value provided in SetNoncePrefix()
- // to form the nonce.
- // TODO(wtc): add a way for DecryptPacket to report decryption failure due
- // to non-authentic inputs, as opposed to other reasons for failure.
- virtual bool DecryptPacket(uint64_t packet_number,
- absl::string_view associated_data,
- absl::string_view ciphertext,
- char* output,
- size_t* output_length,
- size_t max_output_length) = 0;
-
- // Reads a sample of ciphertext from |sample_reader| and uses the header
- // protection key to generate a mask to use for header protection. If
- // successful, this function returns this mask, which is at least 5 bytes
- // long. Callers can detect failure by checking if the output string is empty.
- virtual std::string GenerateHeaderProtectionMask(
- QuicDataReader* sample_reader) = 0;
-
- // The ID of the cipher. Return 0x03000000 ORed with the 'cryptographic suite
- // selector'.
- virtual uint32_t cipher_id() const = 0;
-
- // Returns the maximum number of packets that can safely fail decryption with
- // this decrypter.
- virtual QuicPacketCount GetIntegrityLimit() const = 0;
-
- // For use by unit tests only.
- virtual absl::string_view GetKey() const = 0;
- virtual absl::string_view GetNoncePrefix() const = 0;
-
- static void DiversifyPreliminaryKey(absl::string_view preliminary_key,
- absl::string_view nonce_prefix,
- const DiversificationNonce& nonce,
- size_t key_size,
- size_t nonce_prefix_size,
- std::string* out_key,
- std::string* out_nonce_prefix);
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_CRYPTO_QUIC_DECRYPTER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/quic_encrypter.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/quic_encrypter.cc
deleted file mode 100644
index 70a936743a2..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/quic_encrypter.cc
+++ /dev/null
@@ -1,61 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/crypto/quic_encrypter.h"
-
-#include <utility>
-
-#include "third_party/boringssl/src/include/openssl/tls1.h"
-#include "quic/core/crypto/aes_128_gcm_12_encrypter.h"
-#include "quic/core/crypto/aes_128_gcm_encrypter.h"
-#include "quic/core/crypto/aes_256_gcm_encrypter.h"
-#include "quic/core/crypto/chacha20_poly1305_encrypter.h"
-#include "quic/core/crypto/chacha20_poly1305_tls_encrypter.h"
-#include "quic/core/crypto/crypto_protocol.h"
-#include "quic/core/crypto/null_encrypter.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-// static
-std::unique_ptr<QuicEncrypter> QuicEncrypter::Create(
- const ParsedQuicVersion& version,
- QuicTag algorithm) {
- switch (algorithm) {
- case kAESG:
- if (version.UsesInitialObfuscators()) {
- return std::make_unique<Aes128GcmEncrypter>();
- } else {
- return std::make_unique<Aes128Gcm12Encrypter>();
- }
- case kCC20:
- if (version.UsesInitialObfuscators()) {
- return std::make_unique<ChaCha20Poly1305TlsEncrypter>();
- } else {
- return std::make_unique<ChaCha20Poly1305Encrypter>();
- }
- default:
- QUIC_LOG(FATAL) << "Unsupported algorithm: " << algorithm;
- return nullptr;
- }
-}
-
-// static
-std::unique_ptr<QuicEncrypter> QuicEncrypter::CreateFromCipherSuite(
- uint32_t cipher_suite) {
- switch (cipher_suite) {
- case TLS1_CK_AES_128_GCM_SHA256:
- return std::make_unique<Aes128GcmEncrypter>();
- case TLS1_CK_AES_256_GCM_SHA384:
- return std::make_unique<Aes256GcmEncrypter>();
- case TLS1_CK_CHACHA20_POLY1305_SHA256:
- return std::make_unique<ChaCha20Poly1305TlsEncrypter>();
- default:
- QUIC_BUG(quic_bug_10711_1) << "TLS cipher suite is unknown to QUIC";
- return nullptr;
- }
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/quic_encrypter.h b/chromium/net/third_party/quiche/src/quic/core/crypto/quic_encrypter.h
deleted file mode 100644
index 5465e393246..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/quic_encrypter.h
+++ /dev/null
@@ -1,71 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_CRYPTO_QUIC_ENCRYPTER_H_
-#define QUICHE_QUIC_CORE_CRYPTO_QUIC_ENCRYPTER_H_
-
-#include <cstddef>
-#include <memory>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/crypto/quic_crypter.h"
-#include "quic/core/quic_packets.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-class QUIC_EXPORT_PRIVATE QuicEncrypter : public QuicCrypter {
- public:
- virtual ~QuicEncrypter() {}
-
- static std::unique_ptr<QuicEncrypter> Create(const ParsedQuicVersion& version,
- QuicTag algorithm);
-
- // Creates an IETF QuicEncrypter based on |cipher_suite| which must be an id
- // returned by SSL_CIPHER_get_id. The caller is responsible for taking
- // ownership of the new QuicEncrypter.
- static std::unique_ptr<QuicEncrypter> CreateFromCipherSuite(
- uint32_t cipher_suite);
-
- // Writes encrypted |plaintext| and a MAC over |plaintext| and
- // |associated_data| into output. Sets |output_length| to the number of
- // bytes written. Returns true on success or false if there was an error.
- // |packet_number| is appended to the |nonce_prefix| value provided in
- // SetNoncePrefix() to form the nonce. |output| must not overlap with
- // |associated_data|. If |output| overlaps with |plaintext| then
- // |plaintext| must be <= |output|.
- virtual bool EncryptPacket(uint64_t packet_number,
- absl::string_view associated_data,
- absl::string_view plaintext,
- char* output,
- size_t* output_length,
- size_t max_output_length) = 0;
-
- // Takes a |sample| of ciphertext and uses the header protection key to
- // generate a mask to use for header protection, and returns that mask. On
- // success, the mask will be at least 5 bytes long; on failure the string will
- // be empty.
- virtual std::string GenerateHeaderProtectionMask(
- absl::string_view sample) = 0;
-
- // Returns the maximum length of plaintext that can be encrypted
- // to ciphertext no larger than |ciphertext_size|.
- virtual size_t GetMaxPlaintextSize(size_t ciphertext_size) const = 0;
-
- // Returns the length of the ciphertext that would be generated by encrypting
- // to plaintext of size |plaintext_size|.
- virtual size_t GetCiphertextSize(size_t plaintext_size) const = 0;
-
- // Returns the maximum number of packets that can be safely encrypted with
- // this encrypter.
- virtual QuicPacketCount GetConfidentialityLimit() const = 0;
-
- // For use by unit tests only.
- virtual absl::string_view GetKey() const = 0;
- virtual absl::string_view GetNoncePrefix() const = 0;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_CRYPTO_QUIC_ENCRYPTER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/quic_hkdf.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/quic_hkdf.cc
deleted file mode 100644
index 8dcf104fdf3..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/quic_hkdf.cc
+++ /dev/null
@@ -1,107 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/crypto/quic_hkdf.h"
-
-#include <memory>
-
-#include "absl/strings/string_view.h"
-#include "third_party/boringssl/src/include/openssl/digest.h"
-#include "third_party/boringssl/src/include/openssl/hkdf.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-const size_t kSHA256HashLength = 32;
-const size_t kMaxKeyMaterialSize = kSHA256HashLength * 256;
-
-QuicHKDF::QuicHKDF(absl::string_view secret,
- absl::string_view salt,
- absl::string_view info,
- size_t key_bytes_to_generate,
- size_t iv_bytes_to_generate,
- size_t subkey_secret_bytes_to_generate)
- : QuicHKDF(secret,
- salt,
- info,
- key_bytes_to_generate,
- key_bytes_to_generate,
- iv_bytes_to_generate,
- iv_bytes_to_generate,
- subkey_secret_bytes_to_generate) {}
-
-QuicHKDF::QuicHKDF(absl::string_view secret,
- absl::string_view salt,
- absl::string_view info,
- size_t client_key_bytes_to_generate,
- size_t server_key_bytes_to_generate,
- size_t client_iv_bytes_to_generate,
- size_t server_iv_bytes_to_generate,
- size_t subkey_secret_bytes_to_generate) {
- const size_t material_length =
- 2 * client_key_bytes_to_generate + client_iv_bytes_to_generate +
- 2 * server_key_bytes_to_generate + server_iv_bytes_to_generate +
- subkey_secret_bytes_to_generate;
- QUICHE_DCHECK_LT(material_length, kMaxKeyMaterialSize);
-
- output_.resize(material_length);
- // On Windows, when the size of output_ is zero, dereference of 0'th element
- // results in a crash. C++11 solves this problem by adding a data() getter
- // method to std::vector.
- if (output_.empty()) {
- return;
- }
-
- ::HKDF(&output_[0], output_.size(), ::EVP_sha256(),
- reinterpret_cast<const uint8_t*>(secret.data()), secret.size(),
- reinterpret_cast<const uint8_t*>(salt.data()), salt.size(),
- reinterpret_cast<const uint8_t*>(info.data()), info.size());
-
- size_t j = 0;
- if (client_key_bytes_to_generate) {
- client_write_key_ = absl::string_view(reinterpret_cast<char*>(&output_[j]),
- client_key_bytes_to_generate);
- j += client_key_bytes_to_generate;
- }
-
- if (server_key_bytes_to_generate) {
- server_write_key_ = absl::string_view(reinterpret_cast<char*>(&output_[j]),
- server_key_bytes_to_generate);
- j += server_key_bytes_to_generate;
- }
-
- if (client_iv_bytes_to_generate) {
- client_write_iv_ = absl::string_view(reinterpret_cast<char*>(&output_[j]),
- client_iv_bytes_to_generate);
- j += client_iv_bytes_to_generate;
- }
-
- if (server_iv_bytes_to_generate) {
- server_write_iv_ = absl::string_view(reinterpret_cast<char*>(&output_[j]),
- server_iv_bytes_to_generate);
- j += server_iv_bytes_to_generate;
- }
-
- if (subkey_secret_bytes_to_generate) {
- subkey_secret_ = absl::string_view(reinterpret_cast<char*>(&output_[j]),
- subkey_secret_bytes_to_generate);
- j += subkey_secret_bytes_to_generate;
- }
- // Repeat client and server key bytes for header protection keys.
- if (client_key_bytes_to_generate) {
- client_hp_key_ = absl::string_view(reinterpret_cast<char*>(&output_[j]),
- client_key_bytes_to_generate);
- j += client_key_bytes_to_generate;
- }
-
- if (server_key_bytes_to_generate) {
- server_hp_key_ = absl::string_view(reinterpret_cast<char*>(&output_[j]),
- server_key_bytes_to_generate);
- j += server_key_bytes_to_generate;
- }
-}
-
-QuicHKDF::~QuicHKDF() {}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/quic_hkdf.h b/chromium/net/third_party/quiche/src/quic/core/crypto/quic_hkdf.h
deleted file mode 100644
index 9a14bc46497..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/quic_hkdf.h
+++ /dev/null
@@ -1,76 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_CRYPTO_QUIC_HKDF_H_
-#define QUICHE_QUIC_CORE_CRYPTO_QUIC_HKDF_H_
-
-#include <vector>
-
-#include "absl/strings/string_view.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// QuicHKDF implements the key derivation function specified in RFC 5869
-// (using SHA-256) and outputs key material, as needed by QUIC.
-// See https://tools.ietf.org/html/rfc5869 for details.
-class QUIC_EXPORT_PRIVATE QuicHKDF {
- public:
- // |secret|: the input shared secret (or, from RFC 5869, the IKM).
- // |salt|: an (optional) public salt / non-secret random value. While
- // optional, callers are strongly recommended to provide a salt. There is no
- // added security value in making this larger than the SHA-256 block size of
- // 64 bytes.
- // |info|: an (optional) label to distinguish different uses of HKDF. It is
- // optional context and application specific information (can be a zero-length
- // string).
- // |key_bytes_to_generate|: the number of bytes of key material to generate
- // for both client and server.
- // |iv_bytes_to_generate|: the number of bytes of IV to generate for both
- // client and server.
- // |subkey_secret_bytes_to_generate|: the number of bytes of subkey secret to
- // generate, shared between client and server.
- QuicHKDF(absl::string_view secret,
- absl::string_view salt,
- absl::string_view info,
- size_t key_bytes_to_generate,
- size_t iv_bytes_to_generate,
- size_t subkey_secret_bytes_to_generate);
-
- // An alternative constructor that allows the client and server key/IV
- // lengths to be different.
- QuicHKDF(absl::string_view secret,
- absl::string_view salt,
- absl::string_view info,
- size_t client_key_bytes_to_generate,
- size_t server_key_bytes_to_generate,
- size_t client_iv_bytes_to_generate,
- size_t server_iv_bytes_to_generate,
- size_t subkey_secret_bytes_to_generate);
-
- ~QuicHKDF();
-
- absl::string_view client_write_key() const { return client_write_key_; }
- absl::string_view client_write_iv() const { return client_write_iv_; }
- absl::string_view server_write_key() const { return server_write_key_; }
- absl::string_view server_write_iv() const { return server_write_iv_; }
- absl::string_view subkey_secret() const { return subkey_secret_; }
- absl::string_view client_hp_key() const { return client_hp_key_; }
- absl::string_view server_hp_key() const { return server_hp_key_; }
-
- private:
- std::vector<uint8_t> output_;
-
- absl::string_view client_write_key_;
- absl::string_view server_write_key_;
- absl::string_view client_write_iv_;
- absl::string_view server_write_iv_;
- absl::string_view subkey_secret_;
- absl::string_view client_hp_key_;
- absl::string_view server_hp_key_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_CRYPTO_QUIC_HKDF_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/quic_hkdf_test.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/quic_hkdf_test.cc
deleted file mode 100644
index e23d3f2a1e9..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/quic_hkdf_test.cc
+++ /dev/null
@@ -1,91 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/crypto/quic_hkdf.h"
-
-#include <string>
-
-#include "absl/base/macros.h"
-#include "absl/strings/escaping.h"
-#include "quic/platform/api/quic_test.h"
-
-namespace quic {
-namespace test {
-namespace {
-
-struct HKDFInput {
- const char* key_hex;
- const char* salt_hex;
- const char* info_hex;
- const char* output_hex;
-};
-
-// These test cases are taken from
-// https://tools.ietf.org/html/rfc5869#appendix-A.
-static const HKDFInput kHKDFInputs[] = {
- {
- "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b",
- "000102030405060708090a0b0c",
- "f0f1f2f3f4f5f6f7f8f9",
- "3cb25f25faacd57a90434f64d0362f2a2d2d0a90cf1a5a4c5db02d56ecc4c5bf340072"
- "08d5"
- "b887185865",
- },
- {
- "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122"
- "2324"
- "25262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f4041424344454647"
- "4849"
- "4a4b4c4d4e4f",
- "606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182"
- "8384"
- "85868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7"
- "a8a9"
- "aaabacadaeaf",
- "b0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2"
- "d3d4"
- "d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7"
- "f8f9"
- "fafbfcfdfeff",
- "b11e398dc80327a1c8e7f78c596a49344f012eda2d4efad8a050cc4c19afa97c59045a"
- "99ca"
- "c7827271cb41c65e590e09da3275600c2f09b8367793a9aca3db71cc30c58179ec3e87"
- "c14c"
- "01d5c1f3434f1d87",
- },
- {
- "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b",
- "",
- "",
- "8da4e775a563c18f715f802a063c5a31b8a11f5c5ee1879ec3454e5f3c738d2d9d2013"
- "95fa"
- "a4b61a96c8",
- },
-};
-
-class QuicHKDFTest : public QuicTest {};
-
-TEST_F(QuicHKDFTest, HKDF) {
- for (size_t i = 0; i < ABSL_ARRAYSIZE(kHKDFInputs); i++) {
- const HKDFInput& test(kHKDFInputs[i]);
- SCOPED_TRACE(i);
-
- const std::string key = absl::HexStringToBytes(test.key_hex);
- const std::string salt = absl::HexStringToBytes(test.salt_hex);
- const std::string info = absl::HexStringToBytes(test.info_hex);
- const std::string expected = absl::HexStringToBytes(test.output_hex);
-
- // We set the key_length to the length of the expected output and then take
- // the result from the first key, which is the client write key.
- QuicHKDF hkdf(key, salt, info, expected.size(), 0, 0);
-
- ASSERT_EQ(expected.size(), hkdf.client_write_key().size());
- EXPECT_EQ(0, memcmp(expected.data(), hkdf.client_write_key().data(),
- expected.size()));
- }
-}
-
-} // namespace
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/quic_random.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/quic_random.cc
deleted file mode 100644
index d3190c626e7..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/quic_random.cc
+++ /dev/null
@@ -1,100 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/crypto/quic_random.h"
-#include <cstdint>
-#include <cstring>
-
-#include "third_party/boringssl/src/include/openssl/rand.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_logging.h"
-#include "common/platform/api/quiche_logging.h"
-
-namespace quic {
-
-namespace {
-
-// Insecure randomness in DefaultRandom uses an implementation of
-// xoshiro256++ 1.0 based on code in the public domain from
-// <http://prng.di.unimi.it/xoshiro256plusplus.c>.
-
-inline uint64_t Xoshiro256InitializeRngStateMember() {
- uint64_t result;
- RAND_bytes(reinterpret_cast<uint8_t*>(&result), sizeof(result));
- return result;
-}
-
-inline uint64_t Xoshiro256PlusPlusRotLeft(uint64_t x, int k) {
- return (x << k) | (x >> (64 - k));
-}
-
-uint64_t Xoshiro256PlusPlus() {
- static thread_local uint64_t rng_state[4] = {
- Xoshiro256InitializeRngStateMember(),
- Xoshiro256InitializeRngStateMember(),
- Xoshiro256InitializeRngStateMember(),
- Xoshiro256InitializeRngStateMember()};
- const uint64_t result =
- Xoshiro256PlusPlusRotLeft(rng_state[0] + rng_state[3], 23) + rng_state[0];
- const uint64_t t = rng_state[1] << 17;
- rng_state[2] ^= rng_state[0];
- rng_state[3] ^= rng_state[1];
- rng_state[1] ^= rng_state[2];
- rng_state[0] ^= rng_state[3];
- rng_state[2] ^= t;
- rng_state[3] = Xoshiro256PlusPlusRotLeft(rng_state[3], 45);
- return result;
-}
-
-class DefaultRandom : public QuicRandom {
- public:
- DefaultRandom() {}
- DefaultRandom(const DefaultRandom&) = delete;
- DefaultRandom& operator=(const DefaultRandom&) = delete;
- ~DefaultRandom() override {}
-
- // QuicRandom implementation
- void RandBytes(void* data, size_t len) override;
- uint64_t RandUint64() override;
- void InsecureRandBytes(void* data, size_t len) override;
- uint64_t InsecureRandUint64() override;
-};
-
-void DefaultRandom::RandBytes(void* data, size_t len) {
- RAND_bytes(reinterpret_cast<uint8_t*>(data), len);
-}
-
-uint64_t DefaultRandom::RandUint64() {
- uint64_t value;
- RandBytes(&value, sizeof(value));
- return value;
-}
-
-void DefaultRandom::InsecureRandBytes(void* data, size_t len) {
- while (len >= sizeof(uint64_t)) {
- uint64_t random_bytes64 = Xoshiro256PlusPlus();
- memcpy(data, &random_bytes64, sizeof(uint64_t));
- data = reinterpret_cast<char*>(data) + sizeof(uint64_t);
- len -= sizeof(uint64_t);
- }
- if (len > 0) {
- QUICHE_DCHECK_LT(len, sizeof(uint64_t));
- uint64_t random_bytes64 = Xoshiro256PlusPlus();
- memcpy(data, &random_bytes64, len);
- }
-}
-
-uint64_t DefaultRandom::InsecureRandUint64() {
- return Xoshiro256PlusPlus();
-}
-
-} // namespace
-
-// static
-QuicRandom* QuicRandom::GetInstance() {
- static DefaultRandom* random = new DefaultRandom();
- return random;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/quic_random.h b/chromium/net/third_party/quiche/src/quic/core/crypto/quic_random.h
deleted file mode 100644
index 4d7bf943ac4..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/quic_random.h
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_CRYPTO_QUIC_RANDOM_H_
-#define QUICHE_QUIC_CORE_CRYPTO_QUIC_RANDOM_H_
-
-#include <cstddef>
-#include <cstdint>
-
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// The interface for a random number generator.
-class QUIC_EXPORT_PRIVATE QuicRandom {
- public:
- virtual ~QuicRandom() {}
-
- // Returns the default random number generator, which is cryptographically
- // secure and thread-safe.
- static QuicRandom* GetInstance();
-
- // Generates |len| random bytes in the |data| buffer.
- virtual void RandBytes(void* data, size_t len) = 0;
-
- // Returns a random number in the range [0, kuint64max].
- virtual uint64_t RandUint64() = 0;
-
- // Generates |len| random bytes in the |data| buffer. This MUST NOT be used
- // for any application that requires cryptographically-secure randomness.
- virtual void InsecureRandBytes(void* data, size_t len) = 0;
-
- // Returns a random number in the range [0, kuint64max]. This MUST NOT be used
- // for any application that requires cryptographically-secure randomness.
- virtual uint64_t InsecureRandUint64() = 0;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_CRYPTO_QUIC_RANDOM_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/quic_random_test.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/quic_random_test.cc
deleted file mode 100644
index ab279185fa7..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/quic_random_test.cc
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/crypto/quic_random.h"
-
-#include "quic/platform/api/quic_test.h"
-
-namespace quic {
-namespace test {
-
-class QuicRandomTest : public QuicTest {};
-
-TEST_F(QuicRandomTest, RandBytes) {
- unsigned char buf1[16];
- unsigned char buf2[16];
- memset(buf1, 0xaf, sizeof(buf1));
- memset(buf2, 0xaf, sizeof(buf2));
- ASSERT_EQ(0, memcmp(buf1, buf2, sizeof(buf1)));
-
- QuicRandom* rng = QuicRandom::GetInstance();
- rng->RandBytes(buf1, sizeof(buf1));
- EXPECT_NE(0, memcmp(buf1, buf2, sizeof(buf1)));
-}
-
-TEST_F(QuicRandomTest, RandUint64) {
- QuicRandom* rng = QuicRandom::GetInstance();
- uint64_t value1 = rng->RandUint64();
- uint64_t value2 = rng->RandUint64();
- EXPECT_NE(value1, value2);
-}
-
-TEST_F(QuicRandomTest, InsecureRandBytes) {
- unsigned char buf1[16];
- unsigned char buf2[16];
- memset(buf1, 0xaf, sizeof(buf1));
- memset(buf2, 0xaf, sizeof(buf2));
- ASSERT_EQ(0, memcmp(buf1, buf2, sizeof(buf1)));
-
- QuicRandom* rng = QuicRandom::GetInstance();
- rng->InsecureRandBytes(buf1, sizeof(buf1));
- EXPECT_NE(0, memcmp(buf1, buf2, sizeof(buf1)));
-}
-
-TEST_F(QuicRandomTest, InsecureRandUint64) {
- QuicRandom* rng = QuicRandom::GetInstance();
- uint64_t value1 = rng->InsecureRandUint64();
- uint64_t value2 = rng->InsecureRandUint64();
- EXPECT_NE(value1, value2);
-}
-
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/tls_client_connection.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/tls_client_connection.cc
deleted file mode 100644
index 8e31bba71a5..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/tls_client_connection.cc
+++ /dev/null
@@ -1,50 +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 "quic/core/crypto/tls_client_connection.h"
-
-namespace quic {
-
-TlsClientConnection::TlsClientConnection(SSL_CTX* ssl_ctx,
- Delegate* delegate,
- QuicSSLConfig ssl_config)
- : TlsConnection(ssl_ctx,
- delegate->ConnectionDelegate(),
- std::move(ssl_config)),
- delegate_(delegate) {}
-
-// static
-bssl::UniquePtr<SSL_CTX> TlsClientConnection::CreateSslCtx(
- bool enable_early_data) {
- bssl::UniquePtr<SSL_CTX> ssl_ctx = TlsConnection::CreateSslCtx();
- // Configure certificate verification.
- SSL_CTX_set_custom_verify(ssl_ctx.get(), SSL_VERIFY_PEER, &VerifyCallback);
- int reverify_on_resume_enabled = 1;
- SSL_CTX_set_reverify_on_resume(ssl_ctx.get(), reverify_on_resume_enabled);
-
- // Configure session caching.
- SSL_CTX_set_session_cache_mode(
- ssl_ctx.get(), SSL_SESS_CACHE_CLIENT | SSL_SESS_CACHE_NO_INTERNAL);
- SSL_CTX_sess_set_new_cb(ssl_ctx.get(), NewSessionCallback);
-
- // TODO(wub): Always enable early data on the SSL_CTX, but allow it to be
- // overridden on the SSL object, via QuicSSLConfig.
- SSL_CTX_set_early_data_enabled(ssl_ctx.get(), enable_early_data);
- return ssl_ctx;
-}
-
-void TlsClientConnection::SetCertChain(
- const std::vector<CRYPTO_BUFFER*>& cert_chain, EVP_PKEY* privkey) {
- SSL_set_chain_and_key(ssl(), cert_chain.data(), cert_chain.size(), privkey,
- /*privkey_method=*/nullptr);
-}
-
-// static
-int TlsClientConnection::NewSessionCallback(SSL* ssl, SSL_SESSION* session) {
- static_cast<TlsClientConnection*>(ConnectionFromSsl(ssl))
- ->delegate_->InsertSession(bssl::UniquePtr<SSL_SESSION>(session));
- return 1;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/tls_client_connection.h b/chromium/net/third_party/quiche/src/quic/core/crypto/tls_client_connection.h
deleted file mode 100644
index 574441ef1cd..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/tls_client_connection.h
+++ /dev/null
@@ -1,55 +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_CORE_CRYPTO_TLS_CLIENT_CONNECTION_H_
-#define QUICHE_QUIC_CORE_CRYPTO_TLS_CLIENT_CONNECTION_H_
-
-#include "quic/core/crypto/tls_connection.h"
-
-namespace quic {
-
-// TlsClientConnection receives calls for client-specific BoringSSL callbacks
-// and calls its Delegate for the implementation of those callbacks.
-class QUIC_EXPORT_PRIVATE TlsClientConnection : public TlsConnection {
- public:
- // A TlsClientConnection::Delegate implements the client-specific methods that
- // are set as callbacks for an SSL object.
- class QUIC_EXPORT_PRIVATE Delegate {
- public:
- virtual ~Delegate() {}
-
- protected:
- // Called when a NewSessionTicket is received from the server.
- virtual void InsertSession(bssl::UniquePtr<SSL_SESSION> session) = 0;
-
- // Provides the delegate for callbacks that are shared between client and
- // server.
- virtual TlsConnection::Delegate* ConnectionDelegate() = 0;
-
- friend class TlsClientConnection;
- };
-
- TlsClientConnection(SSL_CTX* ssl_ctx,
- Delegate* delegate,
- QuicSSLConfig ssl_config);
-
- // Creates and configures an SSL_CTX that is appropriate for clients to use.
- static bssl::UniquePtr<SSL_CTX> CreateSslCtx(bool enable_early_data);
-
- // Set the client cert and private key to be used on this connection, if
- // requested by the server.
- void SetCertChain(const std::vector<CRYPTO_BUFFER*>& cert_chain,
- EVP_PKEY* privkey);
-
- private:
- // Registered as the callback for SSL_CTX_sess_set_new_cb, which calls
- // Delegate::InsertSession.
- static int NewSessionCallback(SSL* ssl, SSL_SESSION* session);
-
- Delegate* delegate_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_CRYPTO_TLS_CLIENT_CONNECTION_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/tls_connection.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/tls_connection.cc
deleted file mode 100644
index 901ae66e3c1..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/tls_connection.cc
+++ /dev/null
@@ -1,207 +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 "quic/core/crypto/tls_connection.h"
-
-#include "absl/strings/string_view.h"
-#include "third_party/boringssl/src/include/openssl/ssl.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-
-namespace quic {
-
-namespace {
-
-// BoringSSL allows storing extra data off of some of its data structures,
-// including the SSL struct. To allow for multiple callers to store data, each
-// caller can use a different index for setting and getting data. These indices
-// are globals handed out by calling SSL_get_ex_new_index.
-//
-// SslIndexSingleton calls SSL_get_ex_new_index on its construction, and then
-// provides this index to be used in calls to SSL_get_ex_data/SSL_set_ex_data.
-// This is used to store in the SSL struct a pointer to the TlsConnection which
-// owns it.
-class SslIndexSingleton {
- public:
- static SslIndexSingleton* GetInstance() {
- static SslIndexSingleton* instance = new SslIndexSingleton();
- return instance;
- }
-
- int ssl_ex_data_index_connection() const {
- return ssl_ex_data_index_connection_;
- }
-
- private:
- SslIndexSingleton() {
- CRYPTO_library_init();
- ssl_ex_data_index_connection_ =
- SSL_get_ex_new_index(0, nullptr, nullptr, nullptr, nullptr);
- QUICHE_CHECK_LE(0, ssl_ex_data_index_connection_);
- }
-
- SslIndexSingleton(const SslIndexSingleton&) = delete;
- SslIndexSingleton& operator=(const SslIndexSingleton&) = delete;
-
- // The index to supply to SSL_get_ex_data/SSL_set_ex_data for getting/setting
- // the TlsConnection pointer.
- int ssl_ex_data_index_connection_;
-};
-
-} // namespace
-
-// static
-EncryptionLevel TlsConnection::QuicEncryptionLevel(
- enum ssl_encryption_level_t level) {
- switch (level) {
- case ssl_encryption_initial:
- return ENCRYPTION_INITIAL;
- case ssl_encryption_early_data:
- return ENCRYPTION_ZERO_RTT;
- case ssl_encryption_handshake:
- return ENCRYPTION_HANDSHAKE;
- case ssl_encryption_application:
- return ENCRYPTION_FORWARD_SECURE;
- default:
- QUIC_BUG(quic_bug_10698_1)
- << "Invalid ssl_encryption_level_t " << static_cast<int>(level);
- return ENCRYPTION_INITIAL;
- }
-}
-
-// static
-enum ssl_encryption_level_t TlsConnection::BoringEncryptionLevel(
- EncryptionLevel level) {
- switch (level) {
- case ENCRYPTION_INITIAL:
- return ssl_encryption_initial;
- case ENCRYPTION_HANDSHAKE:
- return ssl_encryption_handshake;
- case ENCRYPTION_ZERO_RTT:
- return ssl_encryption_early_data;
- case ENCRYPTION_FORWARD_SECURE:
- return ssl_encryption_application;
- default:
- QUIC_BUG(quic_bug_10698_2)
- << "Invalid encryption level " << static_cast<int>(level);
- return ssl_encryption_initial;
- }
-}
-
-TlsConnection::TlsConnection(SSL_CTX* ssl_ctx,
- TlsConnection::Delegate* delegate,
- QuicSSLConfig ssl_config)
- : delegate_(delegate),
- ssl_(SSL_new(ssl_ctx)),
- ssl_config_(std::move(ssl_config)) {
- SSL_set_ex_data(
- ssl(), SslIndexSingleton::GetInstance()->ssl_ex_data_index_connection(),
- this);
- if (ssl_config_.early_data_enabled.has_value()) {
- const int early_data_enabled = *ssl_config_.early_data_enabled ? 1 : 0;
- SSL_set_early_data_enabled(ssl(), early_data_enabled);
- }
- if (ssl_config_.signing_algorithm_prefs.has_value()) {
- SSL_set_signing_algorithm_prefs(
- ssl(), ssl_config_.signing_algorithm_prefs->data(),
- ssl_config_.signing_algorithm_prefs->size());
- }
- if (ssl_config_.disable_ticket_support.has_value()) {
- if (*ssl_config_.disable_ticket_support) {
- SSL_set_options(ssl(), SSL_OP_NO_TICKET);
- }
- }
-}
-
-void TlsConnection::EnableInfoCallback() {
- SSL_set_info_callback(
- ssl(), +[](const SSL* ssl, int type, int value) {
- ConnectionFromSsl(ssl)->delegate_->InfoCallback(type, value);
- });
-}
-
-// static
-bssl::UniquePtr<SSL_CTX> TlsConnection::CreateSslCtx() {
- CRYPTO_library_init();
- bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(TLS_with_buffers_method()));
- SSL_CTX_set_min_proto_version(ssl_ctx.get(), TLS1_3_VERSION);
- SSL_CTX_set_max_proto_version(ssl_ctx.get(), TLS1_3_VERSION);
- SSL_CTX_set_quic_method(ssl_ctx.get(), &kSslQuicMethod);
- return ssl_ctx;
-}
-
-// static
-TlsConnection* TlsConnection::ConnectionFromSsl(const SSL* ssl) {
- return reinterpret_cast<TlsConnection*>(SSL_get_ex_data(
- ssl, SslIndexSingleton::GetInstance()->ssl_ex_data_index_connection()));
-}
-
-// static
-enum ssl_verify_result_t TlsConnection::VerifyCallback(SSL* ssl,
- uint8_t* out_alert) {
- return ConnectionFromSsl(ssl)->delegate_->VerifyCert(out_alert);
-}
-
-const SSL_QUIC_METHOD TlsConnection::kSslQuicMethod{
- TlsConnection::SetReadSecretCallback, TlsConnection::SetWriteSecretCallback,
- TlsConnection::WriteMessageCallback, TlsConnection::FlushFlightCallback,
- TlsConnection::SendAlertCallback};
-
-// static
-int TlsConnection::SetReadSecretCallback(SSL* ssl,
- enum ssl_encryption_level_t level,
- 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)) {
- return 0;
- }
- return 1;
-}
-
-// static
-int TlsConnection::SetWriteSecretCallback(SSL* ssl,
- enum ssl_encryption_level_t level,
- 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);
- return 1;
-}
-
-// static
-int TlsConnection::WriteMessageCallback(SSL* ssl,
- enum ssl_encryption_level_t level,
- const uint8_t* data,
- size_t len) {
- ConnectionFromSsl(ssl)->delegate_->WriteMessage(
- QuicEncryptionLevel(level),
- absl::string_view(reinterpret_cast<const char*>(data), len));
- return 1;
-}
-
-// static
-int TlsConnection::FlushFlightCallback(SSL* ssl) {
- ConnectionFromSsl(ssl)->delegate_->FlushFlight();
- return 1;
-}
-
-// static
-int TlsConnection::SendAlertCallback(SSL* ssl,
- enum ssl_encryption_level_t level,
- uint8_t desc) {
- ConnectionFromSsl(ssl)->delegate_->SendAlert(QuicEncryptionLevel(level),
- desc);
- return 1;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/tls_connection.h b/chromium/net/third_party/quiche/src/quic/core/crypto/tls_connection.h
deleted file mode 100644
index a7a869ad1cd..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/tls_connection.h
+++ /dev/null
@@ -1,157 +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_CORE_CRYPTO_TLS_CONNECTION_H_
-#define QUICHE_QUIC_CORE_CRYPTO_TLS_CONNECTION_H_
-
-#include <vector>
-
-#include "absl/strings/string_view.h"
-#include "third_party/boringssl/src/include/openssl/ssl.h"
-#include "quic/core/quic_types.h"
-
-namespace quic {
-
-// TlsConnection wraps BoringSSL's SSL object which represents a single TLS
-// connection. Callbacks set in BoringSSL which are called with an SSL* argument
-// will get dispatched to the TlsConnection object owning that SSL. In turn, the
-// TlsConnection will delegate the implementation of that callback to its
-// Delegate.
-//
-// The owner of the TlsConnection is responsible for driving the TLS handshake
-// (and other interactions with the SSL*). This class only handles mapping
-// callbacks to the correct instance.
-class QUIC_EXPORT_PRIVATE TlsConnection {
- public:
- // A TlsConnection::Delegate implements the methods that are set as callbacks
- // of TlsConnection.
- class QUIC_EXPORT_PRIVATE Delegate {
- public:
- virtual ~Delegate() {}
-
- protected:
- // Certificate management functions:
-
- // Verifies the peer's certificate chain. It may use
- // SSL_get0_peer_certificates to get the cert chain. This method returns
- // ssl_verify_ok if the cert is valid, ssl_verify_invalid if it is invalid,
- // or ssl_verify_retry if verification is happening asynchronously.
- virtual enum ssl_verify_result_t VerifyCert(uint8_t* out_alert) = 0;
-
- // QUIC-TLS interface functions:
-
- // SetWriteSecret provides the encryption secret used to encrypt messages at
- // encryption level |level|. The secret provided here is the one from the
- // TLS 1.3 key schedule (RFC 8446 section 7.1), in particular the handshake
- // 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;
-
- // 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.
- virtual bool SetReadSecret(EncryptionLevel level,
- const SSL_CIPHER* cipher,
- const std::vector<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
- // at encryption level |level|.
- virtual void WriteMessage(EncryptionLevel level,
- absl::string_view data) = 0;
-
- // FlushFlight is called to signal that the current flight of messages have
- // all been written (via calls to WriteMessage) and can be flushed to the
- // underlying transport.
- virtual void FlushFlight() = 0;
-
- // SendAlert causes this TlsConnection to close the QUIC connection with an
- // error code corersponding to the TLS alert description |desc| sent at
- // level |level|.
- virtual void SendAlert(EncryptionLevel level, uint8_t desc) = 0;
-
- // Informational callback from BoringSSL. This callback is disabled by
- // default, but can be enabled by TlsConnection::EnableInfoCallback.
- //
- // See |SSL_CTX_set_info_callback| for the meaning of |type| and |value|.
- virtual void InfoCallback(int type, int value) = 0;
-
- friend class TlsConnection;
- };
-
- TlsConnection(const TlsConnection&) = delete;
- TlsConnection& operator=(const TlsConnection&) = delete;
-
- // Configure the SSL such that delegate_->InfoCallback will be called.
- void EnableInfoCallback();
-
- // Functions to convert between BoringSSL's enum ssl_encryption_level_t and
- // QUIC's EncryptionLevel.
- static EncryptionLevel QuicEncryptionLevel(enum ssl_encryption_level_t level);
- static enum ssl_encryption_level_t BoringEncryptionLevel(
- EncryptionLevel level);
-
- SSL* ssl() const { return ssl_.get(); }
-
- const QuicSSLConfig& ssl_config() const { return ssl_config_; }
-
- protected:
- // TlsConnection does not take ownership of |ssl_ctx| or |delegate|; they must
- // outlive the TlsConnection object.
- TlsConnection(SSL_CTX* ssl_ctx, Delegate* delegate, QuicSSLConfig ssl_config);
-
- // Creates an SSL_CTX and configures it with the options that are appropriate
- // for both client and server. The caller is responsible for ownership of the
- // newly created struct.
- static bssl::UniquePtr<SSL_CTX> CreateSslCtx();
-
- // From a given SSL* |ssl|, returns a pointer to the TlsConnection that it
- // belongs to. This helper method allows the callbacks set in BoringSSL to be
- // dispatched to the correct TlsConnection from the SSL* passed into the
- // callback.
- static TlsConnection* ConnectionFromSsl(const SSL* ssl);
-
- // Registered as the callback for SSL(_CTX)_set_custom_verify. The
- // implementation is delegated to Delegate::VerifyCert.
- static enum ssl_verify_result_t VerifyCallback(SSL* ssl, uint8_t* out_alert);
-
- QuicSSLConfig& mutable_ssl_config() { return ssl_config_; }
-
- private:
- // TlsConnection implements SSL_QUIC_METHOD, which provides the interface
- // between BoringSSL's TLS stack and a QUIC implementation.
- static const SSL_QUIC_METHOD kSslQuicMethod;
-
- // The following static functions make up the members of kSslQuicMethod:
- static int SetReadSecretCallback(SSL* ssl,
- enum ssl_encryption_level_t level,
- const SSL_CIPHER* cipher,
- const uint8_t* secret,
- size_t secret_len);
- static int SetWriteSecretCallback(SSL* ssl,
- enum ssl_encryption_level_t level,
- const SSL_CIPHER* cipher,
- const uint8_t* secret,
- size_t secret_len);
- static int WriteMessageCallback(SSL* ssl,
- enum ssl_encryption_level_t level,
- const uint8_t* data,
- size_t len);
- static int FlushFlightCallback(SSL* ssl);
- static int SendAlertCallback(SSL* ssl,
- enum ssl_encryption_level_t level,
- uint8_t desc);
-
- Delegate* delegate_;
- bssl::UniquePtr<SSL> ssl_;
- QuicSSLConfig ssl_config_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_CRYPTO_TLS_CONNECTION_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/tls_server_connection.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/tls_server_connection.cc
deleted file mode 100644
index 007bdbb1a17..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/tls_server_connection.cc
+++ /dev/null
@@ -1,186 +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 "quic/core/crypto/tls_server_connection.h"
-
-#include "absl/strings/string_view.h"
-#include "third_party/boringssl/src/include/openssl/ssl.h"
-#include "quic/core/crypto/proof_source.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_flag_utils.h"
-#include "quic/platform/api/quic_flags.h"
-
-namespace quic {
-
-TlsServerConnection::TlsServerConnection(SSL_CTX* ssl_ctx, Delegate* delegate,
- QuicSSLConfig ssl_config)
- : TlsConnection(ssl_ctx, delegate->ConnectionDelegate(),
- std::move(ssl_config)),
- delegate_(delegate) {
- // By default, cert verify callback is not installed on ssl(), so only need to
- // UpdateCertVerifyCallback() if client_cert_mode is not kNone.
- if (TlsConnection::ssl_config().client_cert_mode != ClientCertMode::kNone) {
- UpdateCertVerifyCallback();
- }
-}
-
-// static
-bssl::UniquePtr<SSL_CTX> TlsServerConnection::CreateSslCtx(
- ProofSource* proof_source) {
- bssl::UniquePtr<SSL_CTX> ssl_ctx = TlsConnection::CreateSslCtx();
-
- // Server does not request/verify client certs by default. Individual server
- // connections may call SSL_set_custom_verify on their SSL object to request
- // client certs.
-
- SSL_CTX_set_tlsext_servername_callback(ssl_ctx.get(),
- &TlsExtServernameCallback);
- SSL_CTX_set_alpn_select_cb(ssl_ctx.get(), &SelectAlpnCallback, nullptr);
- // We don't actually need the TicketCrypter here, but we need to know
- // whether it's set.
- if (proof_source->GetTicketCrypter()) {
- QUIC_CODE_COUNT(quic_session_tickets_enabled);
- SSL_CTX_set_ticket_aead_method(ssl_ctx.get(),
- &TlsServerConnection::kSessionTicketMethod);
- } else {
- QUIC_CODE_COUNT(quic_session_tickets_disabled);
- }
-
- SSL_CTX_set_early_data_enabled(ssl_ctx.get(), 1);
-
- SSL_CTX_set_select_certificate_cb(
- ssl_ctx.get(), &TlsServerConnection::EarlySelectCertCallback);
- SSL_CTX_set_options(ssl_ctx.get(), SSL_OP_CIPHER_SERVER_PREFERENCE);
- return ssl_ctx;
-}
-
-void TlsServerConnection::SetCertChain(
- const std::vector<CRYPTO_BUFFER*>& cert_chain) {
- SSL_set_chain_and_key(ssl(), cert_chain.data(), cert_chain.size(), nullptr,
- &TlsServerConnection::kPrivateKeyMethod);
-}
-
-void TlsServerConnection::SetClientCertMode(ClientCertMode client_cert_mode) {
- if (ssl_config().client_cert_mode == client_cert_mode) {
- return;
- }
-
- mutable_ssl_config().client_cert_mode = client_cert_mode;
- UpdateCertVerifyCallback();
-}
-
-void TlsServerConnection::UpdateCertVerifyCallback() {
- const ClientCertMode client_cert_mode = ssl_config().client_cert_mode;
- if (client_cert_mode == ClientCertMode::kNone) {
- SSL_set_custom_verify(ssl(), SSL_VERIFY_NONE, nullptr);
- return;
- }
-
- int mode = SSL_VERIFY_PEER;
- if (client_cert_mode == ClientCertMode::kRequire) {
- mode |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
- } else {
- QUICHE_DCHECK_EQ(client_cert_mode, ClientCertMode::kRequest);
- }
- SSL_set_custom_verify(ssl(), mode, &VerifyCallback);
-}
-
-const SSL_PRIVATE_KEY_METHOD TlsServerConnection::kPrivateKeyMethod{
- &TlsServerConnection::PrivateKeySign,
- nullptr, // decrypt
- &TlsServerConnection::PrivateKeyComplete,
-};
-
-// static
-TlsServerConnection* TlsServerConnection::ConnectionFromSsl(SSL* ssl) {
- return static_cast<TlsServerConnection*>(
- TlsConnection::ConnectionFromSsl(ssl));
-}
-
-// static
-ssl_select_cert_result_t TlsServerConnection::EarlySelectCertCallback(
- const SSL_CLIENT_HELLO* client_hello) {
- return ConnectionFromSsl(client_hello->ssl)
- ->delegate_->EarlySelectCertCallback(client_hello);
-}
-
-// static
-int TlsServerConnection::TlsExtServernameCallback(SSL* ssl,
- int* out_alert,
- void* /*arg*/) {
- return ConnectionFromSsl(ssl)->delegate_->TlsExtServernameCallback(out_alert);
-}
-
-// static
-int TlsServerConnection::SelectAlpnCallback(SSL* ssl,
- const uint8_t** out,
- uint8_t* out_len,
- const uint8_t* in,
- unsigned in_len,
- void* /*arg*/) {
- return ConnectionFromSsl(ssl)->delegate_->SelectAlpn(out, out_len, in,
- in_len);
-}
-
-// static
-ssl_private_key_result_t TlsServerConnection::PrivateKeySign(SSL* ssl,
- uint8_t* out,
- size_t* out_len,
- size_t max_out,
- uint16_t sig_alg,
- const uint8_t* in,
- size_t in_len) {
- return ConnectionFromSsl(ssl)->delegate_->PrivateKeySign(
- out, out_len, max_out, sig_alg,
- absl::string_view(reinterpret_cast<const char*>(in), in_len));
-}
-
-// static
-ssl_private_key_result_t TlsServerConnection::PrivateKeyComplete(
- SSL* ssl,
- uint8_t* out,
- size_t* out_len,
- size_t max_out) {
- return ConnectionFromSsl(ssl)->delegate_->PrivateKeyComplete(out, out_len,
- max_out);
-}
-
-// static
-const SSL_TICKET_AEAD_METHOD TlsServerConnection::kSessionTicketMethod{
- TlsServerConnection::SessionTicketMaxOverhead,
- TlsServerConnection::SessionTicketSeal,
- TlsServerConnection::SessionTicketOpen,
-};
-
-// static
-size_t TlsServerConnection::SessionTicketMaxOverhead(SSL* ssl) {
- return ConnectionFromSsl(ssl)->delegate_->SessionTicketMaxOverhead();
-}
-
-// static
-int TlsServerConnection::SessionTicketSeal(SSL* ssl,
- uint8_t* out,
- size_t* out_len,
- size_t max_out_len,
- const uint8_t* in,
- size_t in_len) {
- return ConnectionFromSsl(ssl)->delegate_->SessionTicketSeal(
- out, out_len, max_out_len,
- absl::string_view(reinterpret_cast<const char*>(in), in_len));
-}
-
-// static
-enum ssl_ticket_aead_result_t TlsServerConnection::SessionTicketOpen(
- SSL* ssl,
- uint8_t* out,
- size_t* out_len,
- size_t max_out_len,
- const uint8_t* in,
- size_t in_len) {
- return ConnectionFromSsl(ssl)->delegate_->SessionTicketOpen(
- out, out_len, max_out_len,
- absl::string_view(reinterpret_cast<const char*>(in), in_len));
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/tls_server_connection.h b/chromium/net/third_party/quiche/src/quic/core/crypto/tls_server_connection.h
deleted file mode 100644
index 976620dba33..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/tls_server_connection.h
+++ /dev/null
@@ -1,200 +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_CORE_CRYPTO_TLS_SERVER_CONNECTION_H_
-#define QUICHE_QUIC_CORE_CRYPTO_TLS_SERVER_CONNECTION_H_
-
-#include "absl/strings/string_view.h"
-#include "quic/core/crypto/proof_source.h"
-#include "quic/core/crypto/tls_connection.h"
-
-namespace quic {
-
-// TlsServerConnection receives calls for client-specific BoringSSL callbacks
-// and calls its Delegate for the implementation of those callbacks.
-class QUIC_EXPORT_PRIVATE TlsServerConnection : public TlsConnection {
- public:
- // A TlsServerConnection::Delegate implement the server-specific methods that
- // are set as callbacks for an SSL object.
- class QUIC_EXPORT_PRIVATE Delegate {
- public:
- virtual ~Delegate() {}
-
- protected:
- // Called from BoringSSL right after SNI is extracted, which is very early
- // in the handshake process.
- virtual ssl_select_cert_result_t EarlySelectCertCallback(
- const SSL_CLIENT_HELLO* client_hello) = 0;
-
- // Called after the ClientHello extensions have been successfully parsed.
- // Returns an SSL_TLSEXT_ERR_* value (see
- // https://commondatastorage.googleapis.com/chromium-boringssl-docs/ssl.h.html#SSL_CTX_set_tlsext_servername_callback).
- //
- // On success, return SSL_TLSEXT_ERR_OK causes the server_name extension to
- // be acknowledged in the ServerHello, or return SSL_TLSEXT_ERR_NOACK which
- // causes it to be not acknowledged.
- //
- // If the function returns SSL_TLSEXT_ERR_ALERT_FATAL, then it puts in
- // |*out_alert| the TLS alert value that the server will send.
- //
- virtual int TlsExtServernameCallback(int* out_alert) = 0;
-
- // Selects which ALPN to use based on the list sent by the client.
- virtual int SelectAlpn(const uint8_t** out,
- uint8_t* out_len,
- const uint8_t* in,
- unsigned in_len) = 0;
-
- // Signs |in| using the signature algorithm specified by |sig_alg| (an
- // SSL_SIGN_* value). If the signing operation cannot be completed
- // synchronously, ssl_private_key_retry is returned. If there is an error
- // signing, or if the signature is longer than |max_out|, then
- // ssl_private_key_failure is returned. Otherwise, ssl_private_key_success
- // is returned with the signature put in |*out| and the length in
- // |*out_len|.
- virtual ssl_private_key_result_t PrivateKeySign(uint8_t* out,
- size_t* out_len,
- size_t max_out,
- uint16_t sig_alg,
- absl::string_view in) = 0;
-
- // When PrivateKeySign returns ssl_private_key_retry, PrivateKeyComplete
- // will be called after the async sign operation has completed.
- // PrivateKeyComplete puts the resulting signature in |*out| and length in
- // |*out_len|. If the length is greater than |max_out| or if there was an
- // error in signing, then ssl_private_key_failure is returned. Otherwise,
- // ssl_private_key_success is returned.
- virtual ssl_private_key_result_t PrivateKeyComplete(uint8_t* out,
- size_t* out_len,
- size_t max_out) = 0;
-
- // The following functions are used to implement an SSL_TICKET_AEAD_METHOD.
- // See
- // https://commondatastorage.googleapis.com/chromium-boringssl-docs/ssl.h.html#ssl_ticket_aead_result_t
- // for details on the BoringSSL API.
-
- // SessionTicketMaxOverhead returns the maximum number of bytes of overhead
- // that SessionTicketSeal may add when encrypting a session ticket.
- virtual size_t SessionTicketMaxOverhead() = 0;
-
- // SessionTicketSeal encrypts the session ticket in |in|, putting the
- // resulting encrypted ticket in |out|, writing the length of the bytes
- // written to |*out_len|, which is no larger than |max_out_len|. It returns
- // 1 on success and 0 on error.
- virtual int SessionTicketSeal(uint8_t* out,
- size_t* out_len,
- size_t max_out_len,
- absl::string_view in) = 0;
-
- // SessionTicketOpen is called when BoringSSL has an encrypted session
- // ticket |in| and wants the ticket decrypted. This decryption operation can
- // happen synchronously or asynchronously.
- //
- // If the decrypted ticket is not available at the time of the function
- // call, this function returns ssl_ticket_aead_retry. If this function
- // returns ssl_ticket_aead_retry, then SSL_do_handshake will return
- // SSL_ERROR_PENDING_TICKET. Once the pending ticket decryption has
- // completed, SSL_do_handshake needs to be called again.
- //
- // When this function is called and the decrypted ticket is available
- // (either the ticket was decrypted synchronously, or an asynchronous
- // operation has completed and SSL_do_handshake has been called again), the
- // decrypted ticket is put in |out|, and the length of that output is
- // written to |*out_len|, not to exceed |max_out_len|, and
- // ssl_ticket_aead_success is returned. If the ticket cannot be decrypted
- // and should be ignored, this function returns
- // ssl_ticket_aead_ignore_ticket and a full handshake will be performed
- // instead. If a fatal error occurs, ssl_ticket_aead_error can be returned
- // which will terminate the handshake.
- virtual enum ssl_ticket_aead_result_t SessionTicketOpen(
- uint8_t* out,
- size_t* out_len,
- size_t max_out_len,
- absl::string_view in) = 0;
-
- // Provides the delegate for callbacks that are shared between client and
- // server.
- virtual TlsConnection::Delegate* ConnectionDelegate() = 0;
-
- friend class TlsServerConnection;
- };
-
- TlsServerConnection(SSL_CTX* ssl_ctx,
- Delegate* delegate,
- QuicSSLConfig ssl_config);
-
- // Creates and configures an SSL_CTX that is appropriate for servers to use.
- static bssl::UniquePtr<SSL_CTX> CreateSslCtx(ProofSource* proof_source);
-
- void SetCertChain(const std::vector<CRYPTO_BUFFER*>& cert_chain);
-
- // Set the client cert mode to be used on this connection. This should be
- // called right after cert selection at the latest, otherwise it is too late
- // to has an effect.
- void SetClientCertMode(ClientCertMode client_cert_mode);
-
- private:
- // Specialization of TlsConnection::ConnectionFromSsl.
- static TlsServerConnection* ConnectionFromSsl(SSL* ssl);
-
- static ssl_select_cert_result_t EarlySelectCertCallback(
- const SSL_CLIENT_HELLO* client_hello);
-
- // These functions are registered as callbacks in BoringSSL and delegate their
- // implementation to the matching methods in Delegate above.
- static int TlsExtServernameCallback(SSL* ssl, int* out_alert, void* arg);
- static int SelectAlpnCallback(SSL* ssl,
- const uint8_t** out,
- uint8_t* out_len,
- const uint8_t* in,
- unsigned in_len,
- void* arg);
-
- // |kPrivateKeyMethod| is a vtable pointing to PrivateKeySign and
- // PrivateKeyComplete used by the TLS stack to compute the signature for the
- // CertificateVerify message (using the server's private key).
- static const SSL_PRIVATE_KEY_METHOD kPrivateKeyMethod;
-
- // The following functions make up the contents of |kPrivateKeyMethod|.
- static ssl_private_key_result_t PrivateKeySign(SSL* ssl,
- uint8_t* out,
- size_t* out_len,
- size_t max_out,
- uint16_t sig_alg,
- const uint8_t* in,
- size_t in_len);
- static ssl_private_key_result_t PrivateKeyComplete(SSL* ssl,
- uint8_t* out,
- size_t* out_len,
- size_t max_out);
-
- // Implementation of SSL_TICKET_AEAD_METHOD which delegates to corresponding
- // methods in TlsServerConnection::Delegate (a.k.a. TlsServerHandshaker).
- static const SSL_TICKET_AEAD_METHOD kSessionTicketMethod;
-
- // The following functions make up the contents of |kSessionTicketMethod|.
- static size_t SessionTicketMaxOverhead(SSL* ssl);
- static int SessionTicketSeal(SSL* ssl,
- uint8_t* out,
- size_t* out_len,
- size_t max_out_len,
- const uint8_t* in,
- size_t in_len);
- static enum ssl_ticket_aead_result_t SessionTicketOpen(SSL* ssl,
- uint8_t* out,
- size_t* out_len,
- size_t max_out_len,
- const uint8_t* in,
- size_t in_len);
-
- // Install custom verify callback on ssl() if |ssl_config().client_cert_mode|
- // is not ClientCertMode::kNone. Uninstall otherwise.
- void UpdateCertVerifyCallback();
-
- Delegate* delegate_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_CRYPTO_TLS_SERVER_CONNECTION_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/transport_parameters.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/transport_parameters.cc
deleted file mode 100644
index 0d828db2d2b..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/transport_parameters.cc
+++ /dev/null
@@ -1,1604 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/crypto/transport_parameters.h"
-
-#include <cstdint>
-#include <cstring>
-#include <forward_list>
-#include <memory>
-#include <utility>
-
-#include "absl/strings/escaping.h"
-#include "absl/strings/str_cat.h"
-#include "absl/strings/string_view.h"
-#include "third_party/boringssl/src/include/openssl/digest.h"
-#include "third_party/boringssl/src/include/openssl/sha.h"
-#include "quic/core/quic_connection_id.h"
-#include "quic/core/quic_data_reader.h"
-#include "quic/core/quic_data_writer.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_utils.h"
-#include "quic/core/quic_versions.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_flag_utils.h"
-
-namespace quic {
-
-// Values of the TransportParameterId enum as defined in the
-// "Transport Parameter Encoding" section of draft-ietf-quic-transport.
-// When parameters are encoded, one of these enum values is used to indicate
-// which parameter is encoded. The supported draft version is noted in
-// transport_parameters.h.
-enum TransportParameters::TransportParameterId : uint64_t {
- kOriginalDestinationConnectionId = 0,
- kMaxIdleTimeout = 1,
- kStatelessResetToken = 2,
- kMaxPacketSize = 3,
- kInitialMaxData = 4,
- kInitialMaxStreamDataBidiLocal = 5,
- kInitialMaxStreamDataBidiRemote = 6,
- kInitialMaxStreamDataUni = 7,
- kInitialMaxStreamsBidi = 8,
- kInitialMaxStreamsUni = 9,
- kAckDelayExponent = 0xa,
- kMaxAckDelay = 0xb,
- kDisableActiveMigration = 0xc,
- kPreferredAddress = 0xd,
- kActiveConnectionIdLimit = 0xe,
- kInitialSourceConnectionId = 0xf,
- kRetrySourceConnectionId = 0x10,
-
- kMaxDatagramFrameSize = 0x20,
-
- kInitialRoundTripTime = 0x3127,
- kGoogleConnectionOptions = 0x3128,
- // 0x3129 was used to convey the user agent string.
- // 0x312A was used only in T050 to indicate support for HANDSHAKE_DONE.
- // 0x312B was used to indicate that QUIC+TLS key updates were not supported.
- // 0x4751 was used for non-standard Google-specific parameters encoded as a
- // Google QUIC_CRYPTO CHLO, it has been replaced by individual parameters.
- kGoogleQuicVersion =
- 0x4752, // Used to transmit version and supported_versions.
-
- kMinAckDelay = 0xDE1A, // draft-iyengar-quic-delayed-ack.
- kVersionInformation = 0xFF73DB, // draft-ietf-quic-version-negotiation.
-};
-
-namespace {
-
-// The following constants define minimum and maximum allowed values for some of
-// the parameters. These come from the "Transport Parameter Definitions"
-// section of draft-ietf-quic-transport.
-constexpr uint64_t kMinMaxPacketSizeTransportParam = 1200;
-constexpr uint64_t kMaxAckDelayExponentTransportParam = 20;
-constexpr uint64_t kDefaultAckDelayExponentTransportParam = 3;
-constexpr uint64_t kMaxMaxAckDelayTransportParam = 16383;
-constexpr uint64_t kDefaultMaxAckDelayTransportParam = 25;
-constexpr uint64_t kMinActiveConnectionIdLimitTransportParam = 2;
-constexpr uint64_t kDefaultActiveConnectionIdLimitTransportParam = 2;
-
-std::string TransportParameterIdToString(
- TransportParameters::TransportParameterId param_id) {
- switch (param_id) {
- case TransportParameters::kOriginalDestinationConnectionId:
- return "original_destination_connection_id";
- case TransportParameters::kMaxIdleTimeout:
- return "max_idle_timeout";
- case TransportParameters::kStatelessResetToken:
- return "stateless_reset_token";
- case TransportParameters::kMaxPacketSize:
- return "max_udp_payload_size";
- case TransportParameters::kInitialMaxData:
- return "initial_max_data";
- case TransportParameters::kInitialMaxStreamDataBidiLocal:
- return "initial_max_stream_data_bidi_local";
- case TransportParameters::kInitialMaxStreamDataBidiRemote:
- return "initial_max_stream_data_bidi_remote";
- case TransportParameters::kInitialMaxStreamDataUni:
- return "initial_max_stream_data_uni";
- case TransportParameters::kInitialMaxStreamsBidi:
- return "initial_max_streams_bidi";
- case TransportParameters::kInitialMaxStreamsUni:
- return "initial_max_streams_uni";
- case TransportParameters::kAckDelayExponent:
- return "ack_delay_exponent";
- case TransportParameters::kMaxAckDelay:
- return "max_ack_delay";
- case TransportParameters::kDisableActiveMigration:
- return "disable_active_migration";
- case TransportParameters::kPreferredAddress:
- return "preferred_address";
- case TransportParameters::kActiveConnectionIdLimit:
- return "active_connection_id_limit";
- case TransportParameters::kInitialSourceConnectionId:
- return "initial_source_connection_id";
- case TransportParameters::kRetrySourceConnectionId:
- return "retry_source_connection_id";
- case TransportParameters::kMaxDatagramFrameSize:
- return "max_datagram_frame_size";
- case TransportParameters::kInitialRoundTripTime:
- return "initial_round_trip_time";
- case TransportParameters::kGoogleConnectionOptions:
- return "google_connection_options";
- case TransportParameters::kGoogleQuicVersion:
- return "google-version";
- case TransportParameters::kMinAckDelay:
- return "min_ack_delay_us";
- case TransportParameters::kVersionInformation:
- return "version_information";
- }
- return absl::StrCat("Unknown(", param_id, ")");
-}
-
-bool TransportParameterIdIsKnown(
- TransportParameters::TransportParameterId param_id) {
- switch (param_id) {
- case TransportParameters::kOriginalDestinationConnectionId:
- case TransportParameters::kMaxIdleTimeout:
- case TransportParameters::kStatelessResetToken:
- case TransportParameters::kMaxPacketSize:
- case TransportParameters::kInitialMaxData:
- case TransportParameters::kInitialMaxStreamDataBidiLocal:
- case TransportParameters::kInitialMaxStreamDataBidiRemote:
- case TransportParameters::kInitialMaxStreamDataUni:
- case TransportParameters::kInitialMaxStreamsBidi:
- case TransportParameters::kInitialMaxStreamsUni:
- case TransportParameters::kAckDelayExponent:
- case TransportParameters::kMaxAckDelay:
- case TransportParameters::kDisableActiveMigration:
- case TransportParameters::kPreferredAddress:
- case TransportParameters::kActiveConnectionIdLimit:
- case TransportParameters::kInitialSourceConnectionId:
- case TransportParameters::kRetrySourceConnectionId:
- case TransportParameters::kMaxDatagramFrameSize:
- case TransportParameters::kInitialRoundTripTime:
- case TransportParameters::kGoogleConnectionOptions:
- case TransportParameters::kGoogleQuicVersion:
- case TransportParameters::kMinAckDelay:
- return true;
- case TransportParameters::kVersionInformation:
- return GetQuicReloadableFlag(quic_version_information);
- }
- return false;
-}
-
-} // namespace
-
-TransportParameters::IntegerParameter::IntegerParameter(
- TransportParameters::TransportParameterId param_id,
- uint64_t default_value,
- uint64_t min_value,
- uint64_t max_value)
- : param_id_(param_id),
- value_(default_value),
- default_value_(default_value),
- min_value_(min_value),
- max_value_(max_value),
- has_been_read_(false) {
- QUICHE_DCHECK_LE(min_value, default_value);
- QUICHE_DCHECK_LE(default_value, max_value);
- QUICHE_DCHECK_LE(max_value, kVarInt62MaxValue);
-}
-
-TransportParameters::IntegerParameter::IntegerParameter(
- TransportParameters::TransportParameterId param_id)
- : TransportParameters::IntegerParameter::IntegerParameter(
- param_id,
- 0,
- 0,
- kVarInt62MaxValue) {}
-
-void TransportParameters::IntegerParameter::set_value(uint64_t value) {
- value_ = value;
-}
-
-uint64_t TransportParameters::IntegerParameter::value() const {
- return value_;
-}
-
-bool TransportParameters::IntegerParameter::IsValid() const {
- return min_value_ <= value_ && value_ <= max_value_;
-}
-
-bool TransportParameters::IntegerParameter::Write(
- QuicDataWriter* writer) const {
- QUICHE_DCHECK(IsValid());
- if (value_ == default_value_) {
- // Do not write if the value is default.
- return true;
- }
- if (!writer->WriteVarInt62(param_id_)) {
- QUIC_BUG(quic_bug_10743_1) << "Failed to write param_id for " << *this;
- return false;
- }
- const QuicVariableLengthIntegerLength value_length =
- QuicDataWriter::GetVarInt62Len(value_);
- if (!writer->WriteVarInt62(value_length)) {
- QUIC_BUG(quic_bug_10743_2) << "Failed to write value_length for " << *this;
- return false;
- }
- if (!writer->WriteVarInt62(value_, value_length)) {
- QUIC_BUG(quic_bug_10743_3) << "Failed to write value for " << *this;
- return false;
- }
- return true;
-}
-
-bool TransportParameters::IntegerParameter::Read(QuicDataReader* reader,
- std::string* error_details) {
- if (has_been_read_) {
- *error_details =
- "Received a second " + TransportParameterIdToString(param_id_);
- return false;
- }
- has_been_read_ = true;
-
- if (!reader->ReadVarInt62(&value_)) {
- *error_details =
- "Failed to parse value for " + TransportParameterIdToString(param_id_);
- return false;
- }
- if (!reader->IsDoneReading()) {
- *error_details =
- absl::StrCat("Received unexpected ", reader->BytesRemaining(),
- " bytes after parsing ", this->ToString(false));
- return false;
- }
- return true;
-}
-
-std::string TransportParameters::IntegerParameter::ToString(
- bool for_use_in_list) const {
- if (for_use_in_list && value_ == default_value_) {
- return "";
- }
- std::string rv = for_use_in_list ? " " : "";
- absl::StrAppend(&rv, TransportParameterIdToString(param_id_), " ", value_);
- if (!IsValid()) {
- rv += " (Invalid)";
- }
- return rv;
-}
-
-std::ostream& operator<<(std::ostream& os,
- const TransportParameters::IntegerParameter& param) {
- os << param.ToString(/*for_use_in_list=*/false);
- return os;
-}
-
-TransportParameters::PreferredAddress::PreferredAddress()
- : ipv4_socket_address(QuicIpAddress::Any4(), 0),
- ipv6_socket_address(QuicIpAddress::Any6(), 0),
- connection_id(EmptyQuicConnectionId()),
- stateless_reset_token(kStatelessResetTokenLength, 0) {}
-
-TransportParameters::PreferredAddress::~PreferredAddress() {}
-
-bool TransportParameters::PreferredAddress::operator==(
- const PreferredAddress& rhs) const {
- return ipv4_socket_address == rhs.ipv4_socket_address &&
- ipv6_socket_address == rhs.ipv6_socket_address &&
- connection_id == rhs.connection_id &&
- stateless_reset_token == rhs.stateless_reset_token;
-}
-
-bool TransportParameters::PreferredAddress::operator!=(
- const PreferredAddress& rhs) const {
- return !(*this == rhs);
-}
-
-std::ostream& operator<<(
- std::ostream& os,
- const TransportParameters::PreferredAddress& preferred_address) {
- os << preferred_address.ToString();
- return os;
-}
-
-std::string TransportParameters::PreferredAddress::ToString() const {
- return "[" + ipv4_socket_address.ToString() + " " +
- ipv6_socket_address.ToString() + " connection_id " +
- connection_id.ToString() + " stateless_reset_token " +
- absl::BytesToHexString(absl::string_view(
- reinterpret_cast<const char*>(stateless_reset_token.data()),
- stateless_reset_token.size())) +
- "]";
-}
-
-TransportParameters::LegacyVersionInformation::LegacyVersionInformation()
- : version(0) {}
-
-bool TransportParameters::LegacyVersionInformation::operator==(
- const LegacyVersionInformation& rhs) const {
- return version == rhs.version && supported_versions == rhs.supported_versions;
-}
-
-bool TransportParameters::LegacyVersionInformation::operator!=(
- const LegacyVersionInformation& rhs) const {
- return !(*this == rhs);
-}
-
-std::string TransportParameters::LegacyVersionInformation::ToString() const {
- std::string rv =
- absl::StrCat("legacy[version ", QuicVersionLabelToString(version));
- if (!supported_versions.empty()) {
- absl::StrAppend(&rv,
- " supported_versions " +
- QuicVersionLabelVectorToString(supported_versions));
- }
- absl::StrAppend(&rv, "]");
- return rv;
-}
-
-std::ostream& operator<<(std::ostream& os,
- const TransportParameters::LegacyVersionInformation&
- legacy_version_information) {
- os << legacy_version_information.ToString();
- return os;
-}
-
-TransportParameters::VersionInformation::VersionInformation()
- : chosen_version(0) {}
-
-bool TransportParameters::VersionInformation::operator==(
- const VersionInformation& rhs) const {
- return chosen_version == rhs.chosen_version &&
- other_versions == rhs.other_versions;
-}
-
-bool TransportParameters::VersionInformation::operator!=(
- const VersionInformation& rhs) const {
- return !(*this == rhs);
-}
-
-std::string TransportParameters::VersionInformation::ToString() const {
- std::string rv = absl::StrCat("[chosen_version ",
- QuicVersionLabelToString(chosen_version));
- if (!other_versions.empty()) {
- absl::StrAppend(&rv, " other_versions " +
- QuicVersionLabelVectorToString(other_versions));
- }
- absl::StrAppend(&rv, "]");
- return rv;
-}
-
-std::ostream& operator<<(
- std::ostream& os,
- const TransportParameters::VersionInformation& version_information) {
- os << version_information.ToString();
- return os;
-}
-
-std::ostream& operator<<(std::ostream& os, const TransportParameters& params) {
- os << params.ToString();
- return os;
-}
-
-std::string TransportParameters::ToString() const {
- std::string rv = "[";
- if (perspective == Perspective::IS_SERVER) {
- rv += "Server";
- } else {
- rv += "Client";
- }
- if (legacy_version_information.has_value()) {
- rv += " " + legacy_version_information.value().ToString();
- }
- if (version_information.has_value()) {
- rv += " " + version_information.value().ToString();
- }
- if (original_destination_connection_id.has_value()) {
- rv += " " + TransportParameterIdToString(kOriginalDestinationConnectionId) +
- " " + original_destination_connection_id.value().ToString();
- }
- rv += max_idle_timeout_ms.ToString(/*for_use_in_list=*/true);
- if (!stateless_reset_token.empty()) {
- rv += " " + TransportParameterIdToString(kStatelessResetToken) + " " +
- absl::BytesToHexString(absl::string_view(
- reinterpret_cast<const char*>(stateless_reset_token.data()),
- stateless_reset_token.size()));
- }
- rv += max_udp_payload_size.ToString(/*for_use_in_list=*/true);
- rv += initial_max_data.ToString(/*for_use_in_list=*/true);
- rv += initial_max_stream_data_bidi_local.ToString(/*for_use_in_list=*/true);
- rv += initial_max_stream_data_bidi_remote.ToString(/*for_use_in_list=*/true);
- rv += initial_max_stream_data_uni.ToString(/*for_use_in_list=*/true);
- rv += initial_max_streams_bidi.ToString(/*for_use_in_list=*/true);
- rv += initial_max_streams_uni.ToString(/*for_use_in_list=*/true);
- rv += ack_delay_exponent.ToString(/*for_use_in_list=*/true);
- rv += max_ack_delay.ToString(/*for_use_in_list=*/true);
- rv += min_ack_delay_us.ToString(/*for_use_in_list=*/true);
- if (disable_active_migration) {
- rv += " " + TransportParameterIdToString(kDisableActiveMigration);
- }
- if (preferred_address) {
- rv += " " + TransportParameterIdToString(kPreferredAddress) + " " +
- preferred_address->ToString();
- }
- rv += active_connection_id_limit.ToString(/*for_use_in_list=*/true);
- if (initial_source_connection_id.has_value()) {
- rv += " " + TransportParameterIdToString(kInitialSourceConnectionId) + " " +
- initial_source_connection_id.value().ToString();
- }
- if (retry_source_connection_id.has_value()) {
- rv += " " + TransportParameterIdToString(kRetrySourceConnectionId) + " " +
- retry_source_connection_id.value().ToString();
- }
- rv += max_datagram_frame_size.ToString(/*for_use_in_list=*/true);
- rv += initial_round_trip_time_us.ToString(/*for_use_in_list=*/true);
- if (google_connection_options.has_value()) {
- rv += " " + TransportParameterIdToString(kGoogleConnectionOptions) + " ";
- bool first = true;
- for (const QuicTag& connection_option : google_connection_options.value()) {
- if (first) {
- first = false;
- } else {
- rv += ",";
- }
- rv += QuicTagToString(connection_option);
- }
- }
- for (const auto& kv : custom_parameters) {
- absl::StrAppend(&rv, " 0x", absl::Hex(static_cast<uint32_t>(kv.first)),
- "=");
- static constexpr size_t kMaxPrintableLength = 32;
- if (kv.second.length() <= kMaxPrintableLength) {
- rv += absl::BytesToHexString(kv.second);
- } else {
- absl::string_view truncated(kv.second.data(), kMaxPrintableLength);
- rv += absl::StrCat(absl::BytesToHexString(truncated), "...(length ",
- kv.second.length(), ")");
- }
- }
- rv += "]";
- return rv;
-}
-
-TransportParameters::TransportParameters()
- : max_idle_timeout_ms(kMaxIdleTimeout),
- max_udp_payload_size(kMaxPacketSize, kDefaultMaxPacketSizeTransportParam,
- kMinMaxPacketSizeTransportParam, kVarInt62MaxValue),
- initial_max_data(kInitialMaxData),
- initial_max_stream_data_bidi_local(kInitialMaxStreamDataBidiLocal),
- initial_max_stream_data_bidi_remote(kInitialMaxStreamDataBidiRemote),
- initial_max_stream_data_uni(kInitialMaxStreamDataUni),
- initial_max_streams_bidi(kInitialMaxStreamsBidi),
- initial_max_streams_uni(kInitialMaxStreamsUni),
- ack_delay_exponent(kAckDelayExponent,
- kDefaultAckDelayExponentTransportParam, 0,
- kMaxAckDelayExponentTransportParam),
- max_ack_delay(kMaxAckDelay, kDefaultMaxAckDelayTransportParam, 0,
- kMaxMaxAckDelayTransportParam),
- min_ack_delay_us(kMinAckDelay, 0, 0,
- kMaxMaxAckDelayTransportParam * kNumMicrosPerMilli),
- disable_active_migration(false),
- active_connection_id_limit(kActiveConnectionIdLimit,
- kDefaultActiveConnectionIdLimitTransportParam,
- kMinActiveConnectionIdLimitTransportParam,
- kVarInt62MaxValue),
- max_datagram_frame_size(kMaxDatagramFrameSize),
- initial_round_trip_time_us(kInitialRoundTripTime)
-// Important note: any new transport parameters must be added
-// to TransportParameters::AreValid, SerializeTransportParameters and
-// ParseTransportParameters, TransportParameters's custom copy constructor, the
-// operator==, and TransportParametersTest.Comparator.
-{}
-
-TransportParameters::TransportParameters(const TransportParameters& other)
- : perspective(other.perspective),
- legacy_version_information(other.legacy_version_information),
- version_information(other.version_information),
- original_destination_connection_id(
- other.original_destination_connection_id),
- max_idle_timeout_ms(other.max_idle_timeout_ms),
- stateless_reset_token(other.stateless_reset_token),
- max_udp_payload_size(other.max_udp_payload_size),
- initial_max_data(other.initial_max_data),
- initial_max_stream_data_bidi_local(
- other.initial_max_stream_data_bidi_local),
- initial_max_stream_data_bidi_remote(
- other.initial_max_stream_data_bidi_remote),
- initial_max_stream_data_uni(other.initial_max_stream_data_uni),
- initial_max_streams_bidi(other.initial_max_streams_bidi),
- initial_max_streams_uni(other.initial_max_streams_uni),
- ack_delay_exponent(other.ack_delay_exponent),
- max_ack_delay(other.max_ack_delay),
- min_ack_delay_us(other.min_ack_delay_us),
- disable_active_migration(other.disable_active_migration),
- active_connection_id_limit(other.active_connection_id_limit),
- initial_source_connection_id(other.initial_source_connection_id),
- retry_source_connection_id(other.retry_source_connection_id),
- max_datagram_frame_size(other.max_datagram_frame_size),
- initial_round_trip_time_us(other.initial_round_trip_time_us),
- google_connection_options(other.google_connection_options),
- custom_parameters(other.custom_parameters) {
- if (other.preferred_address) {
- preferred_address = std::make_unique<TransportParameters::PreferredAddress>(
- *other.preferred_address);
- }
-}
-
-bool TransportParameters::operator==(const TransportParameters& rhs) const {
- if (!(perspective == rhs.perspective &&
- legacy_version_information == rhs.legacy_version_information &&
- version_information == rhs.version_information &&
- original_destination_connection_id ==
- rhs.original_destination_connection_id &&
- max_idle_timeout_ms.value() == rhs.max_idle_timeout_ms.value() &&
- stateless_reset_token == rhs.stateless_reset_token &&
- max_udp_payload_size.value() == rhs.max_udp_payload_size.value() &&
- initial_max_data.value() == rhs.initial_max_data.value() &&
- initial_max_stream_data_bidi_local.value() ==
- rhs.initial_max_stream_data_bidi_local.value() &&
- initial_max_stream_data_bidi_remote.value() ==
- rhs.initial_max_stream_data_bidi_remote.value() &&
- initial_max_stream_data_uni.value() ==
- rhs.initial_max_stream_data_uni.value() &&
- initial_max_streams_bidi.value() ==
- rhs.initial_max_streams_bidi.value() &&
- initial_max_streams_uni.value() ==
- rhs.initial_max_streams_uni.value() &&
- ack_delay_exponent.value() == rhs.ack_delay_exponent.value() &&
- max_ack_delay.value() == rhs.max_ack_delay.value() &&
- min_ack_delay_us.value() == rhs.min_ack_delay_us.value() &&
- disable_active_migration == rhs.disable_active_migration &&
- active_connection_id_limit.value() ==
- rhs.active_connection_id_limit.value() &&
- initial_source_connection_id == rhs.initial_source_connection_id &&
- retry_source_connection_id == rhs.retry_source_connection_id &&
- max_datagram_frame_size.value() ==
- rhs.max_datagram_frame_size.value() &&
- initial_round_trip_time_us.value() ==
- rhs.initial_round_trip_time_us.value() &&
- google_connection_options == rhs.google_connection_options &&
- custom_parameters == rhs.custom_parameters)) {
- return false;
- }
-
- if ((!preferred_address && rhs.preferred_address) ||
- (preferred_address && !rhs.preferred_address)) {
- return false;
- }
- if (preferred_address && rhs.preferred_address &&
- *preferred_address != *rhs.preferred_address) {
- return false;
- }
-
- return true;
-}
-
-bool TransportParameters::operator!=(const TransportParameters& rhs) const {
- return !(*this == rhs);
-}
-
-bool TransportParameters::AreValid(std::string* error_details) const {
- QUICHE_DCHECK(perspective == Perspective::IS_CLIENT ||
- perspective == Perspective::IS_SERVER);
- if (perspective == Perspective::IS_CLIENT && !stateless_reset_token.empty()) {
- *error_details = "Client cannot send stateless reset token";
- return false;
- }
- if (perspective == Perspective::IS_CLIENT &&
- original_destination_connection_id.has_value()) {
- *error_details = "Client cannot send original_destination_connection_id";
- return false;
- }
- if (!stateless_reset_token.empty() &&
- stateless_reset_token.size() != kStatelessResetTokenLength) {
- *error_details = absl::StrCat("Stateless reset token has bad length ",
- stateless_reset_token.size());
- return false;
- }
- if (perspective == Perspective::IS_CLIENT && preferred_address) {
- *error_details = "Client cannot send preferred address";
- return false;
- }
- if (preferred_address && preferred_address->stateless_reset_token.size() !=
- kStatelessResetTokenLength) {
- *error_details =
- absl::StrCat("Preferred address stateless reset token has bad length ",
- preferred_address->stateless_reset_token.size());
- return false;
- }
- if (preferred_address &&
- (!preferred_address->ipv4_socket_address.host().IsIPv4() ||
- !preferred_address->ipv6_socket_address.host().IsIPv6())) {
- QUIC_BUG(quic_bug_10743_4) << "Preferred address family failure";
- *error_details = "Internal preferred address family failure";
- return false;
- }
- if (perspective == Perspective::IS_CLIENT &&
- retry_source_connection_id.has_value()) {
- *error_details = "Client cannot send retry_source_connection_id";
- return false;
- }
- for (const auto& kv : custom_parameters) {
- if (TransportParameterIdIsKnown(kv.first)) {
- *error_details = absl::StrCat("Using custom_parameters with known ID ",
- TransportParameterIdToString(kv.first),
- " is not allowed");
- return false;
- }
- }
- if (perspective == Perspective::IS_SERVER &&
- initial_round_trip_time_us.value() > 0) {
- *error_details = "Server cannot send initial round trip time";
- return false;
- }
- if (version_information.has_value()) {
- const QuicVersionLabel& chosen_version =
- version_information.value().chosen_version;
- const QuicVersionLabelVector& other_versions =
- version_information.value().other_versions;
- if (chosen_version == 0) {
- *error_details = "Invalid chosen version";
- return false;
- }
- if (perspective == Perspective::IS_CLIENT &&
- std::find(other_versions.begin(), other_versions.end(),
- chosen_version) == other_versions.end()) {
- // When sent by the client, chosen_version needs to be present in
- // other_versions because other_versions lists the compatible versions and
- // the chosen version is part of that list. When sent by the server,
- // other_version contains the list of fully-deployed versions which is
- // generally equal to the list of supported versions but can slightly
- // differ during removal of versions across a server fleet. See
- // draft-ietf-quic-version-negotiation for details.
- *error_details = "Client chosen version not in other versions";
- return false;
- }
- }
- const bool ok =
- max_idle_timeout_ms.IsValid() && max_udp_payload_size.IsValid() &&
- initial_max_data.IsValid() &&
- initial_max_stream_data_bidi_local.IsValid() &&
- initial_max_stream_data_bidi_remote.IsValid() &&
- initial_max_stream_data_uni.IsValid() &&
- initial_max_streams_bidi.IsValid() && initial_max_streams_uni.IsValid() &&
- ack_delay_exponent.IsValid() && max_ack_delay.IsValid() &&
- min_ack_delay_us.IsValid() && active_connection_id_limit.IsValid() &&
- max_datagram_frame_size.IsValid() && initial_round_trip_time_us.IsValid();
- if (!ok) {
- *error_details = "Invalid transport parameters " + this->ToString();
- }
- return ok;
-}
-
-TransportParameters::~TransportParameters() = default;
-
-bool SerializeTransportParameters(ParsedQuicVersion /*version*/,
- const TransportParameters& in,
- std::vector<uint8_t>* out) {
- std::string error_details;
- if (!in.AreValid(&error_details)) {
- QUIC_BUG(invalid transport parameters)
- << "Not serializing invalid transport parameters: " << error_details;
- return false;
- }
- if (!in.legacy_version_information.has_value() ||
- in.legacy_version_information.value().version == 0 ||
- (in.perspective == Perspective::IS_SERVER &&
- in.legacy_version_information.value().supported_versions.empty())) {
- QUIC_BUG(missing versions) << "Refusing to serialize without versions";
- return false;
- }
- TransportParameters::ParameterMap custom_parameters = in.custom_parameters;
- for (const auto& kv : custom_parameters) {
- if (kv.first % 31 == 27) {
- // See the "Reserved Transport Parameters" section of RFC 9000.
- QUIC_BUG(custom_parameters with GREASE)
- << "Serializing custom_parameters with GREASE ID " << kv.first
- << " is not allowed";
- return false;
- }
- }
-
- // Maximum length of the GREASE transport parameter (see below).
- static constexpr size_t kMaxGreaseLength = 16;
-
- // Empirically transport parameters generally fit within 128 bytes, but we
- // need to allocate the size up front. Integer transport parameters
- // have a maximum encoded length of 24 bytes (3 variable length integers),
- // other transport parameters have a length of 16 + the maximum value length.
- static constexpr size_t kTypeAndValueLength = 2 * sizeof(uint64_t);
- static constexpr size_t kIntegerParameterLength =
- kTypeAndValueLength + sizeof(uint64_t);
- static constexpr size_t kStatelessResetParameterLength =
- kTypeAndValueLength + 16 /* stateless reset token length */;
- static constexpr size_t kConnectionIdParameterLength =
- kTypeAndValueLength + 255 /* maximum connection ID length */;
- static constexpr size_t kPreferredAddressParameterLength =
- kTypeAndValueLength + 4 /*IPv4 address */ + 2 /* IPv4 port */ +
- 16 /* IPv6 address */ + 1 /* Connection ID length */ +
- 255 /* maximum connection ID length */ + 16 /* stateless reset token */;
- static constexpr size_t kKnownTransportParamLength =
- kConnectionIdParameterLength + // original_destination_connection_id
- kIntegerParameterLength + // max_idle_timeout
- kStatelessResetParameterLength + // stateless_reset_token
- kIntegerParameterLength + // max_udp_payload_size
- kIntegerParameterLength + // initial_max_data
- kIntegerParameterLength + // initial_max_stream_data_bidi_local
- kIntegerParameterLength + // initial_max_stream_data_bidi_remote
- kIntegerParameterLength + // initial_max_stream_data_uni
- kIntegerParameterLength + // initial_max_streams_bidi
- kIntegerParameterLength + // initial_max_streams_uni
- kIntegerParameterLength + // ack_delay_exponent
- kIntegerParameterLength + // max_ack_delay
- kIntegerParameterLength + // min_ack_delay_us
- kTypeAndValueLength + // disable_active_migration
- kPreferredAddressParameterLength + // preferred_address
- kIntegerParameterLength + // active_connection_id_limit
- kConnectionIdParameterLength + // initial_source_connection_id
- kConnectionIdParameterLength + // retry_source_connection_id
- kIntegerParameterLength + // max_datagram_frame_size
- kIntegerParameterLength + // initial_round_trip_time_us
- kTypeAndValueLength + // google_connection_options
- kTypeAndValueLength; // google-version
-
- std::vector<TransportParameters::TransportParameterId> parameter_ids = {
- TransportParameters::kOriginalDestinationConnectionId,
- TransportParameters::kMaxIdleTimeout,
- TransportParameters::kStatelessResetToken,
- TransportParameters::kMaxPacketSize,
- TransportParameters::kInitialMaxData,
- TransportParameters::kInitialMaxStreamDataBidiLocal,
- TransportParameters::kInitialMaxStreamDataBidiRemote,
- TransportParameters::kInitialMaxStreamDataUni,
- TransportParameters::kInitialMaxStreamsBidi,
- TransportParameters::kInitialMaxStreamsUni,
- TransportParameters::kAckDelayExponent,
- TransportParameters::kMaxAckDelay,
- TransportParameters::kMinAckDelay,
- TransportParameters::kActiveConnectionIdLimit,
- TransportParameters::kMaxDatagramFrameSize,
- TransportParameters::kInitialRoundTripTime,
- TransportParameters::kDisableActiveMigration,
- TransportParameters::kPreferredAddress,
- TransportParameters::kInitialSourceConnectionId,
- TransportParameters::kRetrySourceConnectionId,
- TransportParameters::kGoogleConnectionOptions,
- TransportParameters::kGoogleQuicVersion,
- TransportParameters::kVersionInformation,
- };
-
- size_t max_transport_param_length = kKnownTransportParamLength;
- // google_connection_options.
- if (in.google_connection_options.has_value()) {
- max_transport_param_length +=
- in.google_connection_options.value().size() * sizeof(QuicTag);
- }
- // Google-specific version extension.
- if (in.legacy_version_information.has_value()) {
- max_transport_param_length +=
- sizeof(in.legacy_version_information.value().version) +
- 1 /* versions length */ +
- in.legacy_version_information.value().supported_versions.size() *
- sizeof(QuicVersionLabel);
- }
- // version_information.
- if (in.version_information.has_value()) {
- max_transport_param_length +=
- sizeof(in.version_information.value().chosen_version) +
- // Add one for the added GREASE version.
- (in.version_information.value().other_versions.size() + 1) *
- sizeof(QuicVersionLabel);
- }
-
- // Add a random GREASE transport parameter, as defined in the
- // "Reserved Transport Parameters" section of RFC 9000.
- // This forces receivers to support unexpected input.
- QuicRandom* random = QuicRandom::GetInstance();
- // Transport parameter identifiers are 62 bits long so we need to
- // ensure that the output of the computation below fits in 62 bits.
- uint64_t grease_id64 = random->RandUint64() % ((1ULL << 62) - 31);
- // Make sure grease_id % 31 == 27. Note that this is not uniformely
- // distributed but is acceptable since no security depends on this
- // randomness.
- grease_id64 = (grease_id64 / 31) * 31 + 27;
- TransportParameters::TransportParameterId grease_id =
- static_cast<TransportParameters::TransportParameterId>(grease_id64);
- const size_t grease_length = random->RandUint64() % kMaxGreaseLength;
- QUICHE_DCHECK_GE(kMaxGreaseLength, grease_length);
- char grease_contents[kMaxGreaseLength];
- random->RandBytes(grease_contents, grease_length);
- custom_parameters[grease_id] = std::string(grease_contents, grease_length);
-
- // Custom parameters.
- for (const auto& kv : custom_parameters) {
- max_transport_param_length += kTypeAndValueLength + kv.second.length();
- parameter_ids.push_back(kv.first);
- }
-
- // Randomize order of sent transport parameters by walking the array
- // backwards and swapping each element with a random earlier one.
- for (size_t i = parameter_ids.size() - 1; i > 0; i--) {
- std::swap(parameter_ids[i],
- parameter_ids[random->InsecureRandUint64() % (i + 1)]);
- }
-
- out->resize(max_transport_param_length);
- QuicDataWriter writer(out->size(), reinterpret_cast<char*>(out->data()));
-
- for (TransportParameters::TransportParameterId parameter_id : parameter_ids) {
- switch (parameter_id) {
- // original_destination_connection_id
- case TransportParameters::kOriginalDestinationConnectionId: {
- if (in.original_destination_connection_id.has_value()) {
- QUICHE_DCHECK_EQ(Perspective::IS_SERVER, in.perspective);
- QuicConnectionId original_destination_connection_id =
- in.original_destination_connection_id.value();
- if (!writer.WriteVarInt62(
- TransportParameters::kOriginalDestinationConnectionId) ||
- !writer.WriteStringPieceVarInt62(absl::string_view(
- original_destination_connection_id.data(),
- original_destination_connection_id.length()))) {
- QUIC_BUG(Failed to write original_destination_connection_id)
- << "Failed to write original_destination_connection_id "
- << original_destination_connection_id << " for " << in;
- return false;
- }
- }
- } break;
- // max_idle_timeout
- case TransportParameters::kMaxIdleTimeout: {
- if (!in.max_idle_timeout_ms.Write(&writer)) {
- QUIC_BUG(Failed to write idle_timeout)
- << "Failed to write idle_timeout for " << in;
- return false;
- }
- } break;
- // stateless_reset_token
- case TransportParameters::kStatelessResetToken: {
- if (!in.stateless_reset_token.empty()) {
- QUICHE_DCHECK_EQ(kStatelessResetTokenLength,
- in.stateless_reset_token.size());
- QUICHE_DCHECK_EQ(Perspective::IS_SERVER, in.perspective);
- if (!writer.WriteVarInt62(
- TransportParameters::kStatelessResetToken) ||
- !writer.WriteStringPieceVarInt62(
- absl::string_view(reinterpret_cast<const char*>(
- in.stateless_reset_token.data()),
- in.stateless_reset_token.size()))) {
- QUIC_BUG(Failed to write stateless_reset_token)
- << "Failed to write stateless_reset_token of length "
- << in.stateless_reset_token.size() << " for " << in;
- return false;
- }
- }
- } break;
- // max_udp_payload_size
- case TransportParameters::kMaxPacketSize: {
- if (!in.max_udp_payload_size.Write(&writer)) {
- QUIC_BUG(Failed to write max_udp_payload_size)
- << "Failed to write max_udp_payload_size for " << in;
- return false;
- }
- } break;
- // initial_max_data
- case TransportParameters::kInitialMaxData: {
- if (!in.initial_max_data.Write(&writer)) {
- QUIC_BUG(Failed to write initial_max_data)
- << "Failed to write initial_max_data for " << in;
- return false;
- }
- } break;
- // initial_max_stream_data_bidi_local
- case TransportParameters::kInitialMaxStreamDataBidiLocal: {
- if (!in.initial_max_stream_data_bidi_local.Write(&writer)) {
- QUIC_BUG(Failed to write initial_max_stream_data_bidi_local)
- << "Failed to write initial_max_stream_data_bidi_local for "
- << in;
- return false;
- }
- } break;
- // initial_max_stream_data_bidi_remote
- case TransportParameters::kInitialMaxStreamDataBidiRemote: {
- if (!in.initial_max_stream_data_bidi_remote.Write(&writer)) {
- QUIC_BUG(Failed to write initial_max_stream_data_bidi_remote)
- << "Failed to write initial_max_stream_data_bidi_remote for "
- << in;
- return false;
- }
- } break;
- // initial_max_stream_data_uni
- case TransportParameters::kInitialMaxStreamDataUni: {
- if (!in.initial_max_stream_data_uni.Write(&writer)) {
- QUIC_BUG(Failed to write initial_max_stream_data_uni)
- << "Failed to write initial_max_stream_data_uni for " << in;
- return false;
- }
- } break;
- // initial_max_streams_bidi
- case TransportParameters::kInitialMaxStreamsBidi: {
- if (!in.initial_max_streams_bidi.Write(&writer)) {
- QUIC_BUG(Failed to write initial_max_streams_bidi)
- << "Failed to write initial_max_streams_bidi for " << in;
- return false;
- }
- } break;
- // initial_max_streams_uni
- case TransportParameters::kInitialMaxStreamsUni: {
- if (!in.initial_max_streams_uni.Write(&writer)) {
- QUIC_BUG(Failed to write initial_max_streams_uni)
- << "Failed to write initial_max_streams_uni for " << in;
- return false;
- }
- } break;
- // ack_delay_exponent
- case TransportParameters::kAckDelayExponent: {
- if (!in.ack_delay_exponent.Write(&writer)) {
- QUIC_BUG(Failed to write ack_delay_exponent)
- << "Failed to write ack_delay_exponent for " << in;
- return false;
- }
- } break;
- // max_ack_delay
- case TransportParameters::kMaxAckDelay: {
- if (!in.max_ack_delay.Write(&writer)) {
- QUIC_BUG(Failed to write max_ack_delay)
- << "Failed to write max_ack_delay for " << in;
- return false;
- }
- } break;
- // min_ack_delay_us
- case TransportParameters::kMinAckDelay: {
- if (!in.min_ack_delay_us.Write(&writer)) {
- QUIC_BUG(Failed to write min_ack_delay_us)
- << "Failed to write min_ack_delay_us for " << in;
- return false;
- }
- } break;
- // active_connection_id_limit
- case TransportParameters::kActiveConnectionIdLimit: {
- if (!in.active_connection_id_limit.Write(&writer)) {
- QUIC_BUG(Failed to write active_connection_id_limit)
- << "Failed to write active_connection_id_limit for " << in;
- return false;
- }
- } break;
- // max_datagram_frame_size
- case TransportParameters::kMaxDatagramFrameSize: {
- if (!in.max_datagram_frame_size.Write(&writer)) {
- QUIC_BUG(Failed to write max_datagram_frame_size)
- << "Failed to write max_datagram_frame_size for " << in;
- return false;
- }
- } break;
- // initial_round_trip_time_us
- case TransportParameters::kInitialRoundTripTime: {
- if (!in.initial_round_trip_time_us.Write(&writer)) {
- QUIC_BUG(Failed to write initial_round_trip_time_us)
- << "Failed to write initial_round_trip_time_us for " << in;
- return false;
- }
- } break;
- // disable_active_migration
- case TransportParameters::kDisableActiveMigration: {
- if (in.disable_active_migration) {
- if (!writer.WriteVarInt62(
- TransportParameters::kDisableActiveMigration) ||
- !writer.WriteVarInt62(/* transport parameter length */ 0)) {
- QUIC_BUG(Failed to write disable_active_migration)
- << "Failed to write disable_active_migration for " << in;
- return false;
- }
- }
- } break;
- // preferred_address
- case TransportParameters::kPreferredAddress: {
- if (in.preferred_address) {
- std::string v4_address_bytes =
- in.preferred_address->ipv4_socket_address.host().ToPackedString();
- std::string v6_address_bytes =
- in.preferred_address->ipv6_socket_address.host().ToPackedString();
- if (v4_address_bytes.length() != 4 ||
- v6_address_bytes.length() != 16 ||
- in.preferred_address->stateless_reset_token.size() !=
- kStatelessResetTokenLength) {
- QUIC_BUG(quic_bug_10743_12)
- << "Bad lengths " << *in.preferred_address;
- return false;
- }
- const uint64_t preferred_address_length =
- v4_address_bytes.length() + /* IPv4 port */ sizeof(uint16_t) +
- v6_address_bytes.length() + /* IPv6 port */ sizeof(uint16_t) +
- /* connection ID length byte */ sizeof(uint8_t) +
- in.preferred_address->connection_id.length() +
- in.preferred_address->stateless_reset_token.size();
- if (!writer.WriteVarInt62(TransportParameters::kPreferredAddress) ||
- !writer.WriteVarInt62(
- /* transport parameter length */ preferred_address_length) ||
- !writer.WriteStringPiece(v4_address_bytes) ||
- !writer.WriteUInt16(
- in.preferred_address->ipv4_socket_address.port()) ||
- !writer.WriteStringPiece(v6_address_bytes) ||
- !writer.WriteUInt16(
- in.preferred_address->ipv6_socket_address.port()) ||
- !writer.WriteUInt8(
- in.preferred_address->connection_id.length()) ||
- !writer.WriteBytes(
- in.preferred_address->connection_id.data(),
- in.preferred_address->connection_id.length()) ||
- !writer.WriteBytes(
- in.preferred_address->stateless_reset_token.data(),
- in.preferred_address->stateless_reset_token.size())) {
- QUIC_BUG(Failed to write preferred_address)
- << "Failed to write preferred_address for " << in;
- return false;
- }
- }
- } break;
- // initial_source_connection_id
- case TransportParameters::kInitialSourceConnectionId: {
- if (in.initial_source_connection_id.has_value()) {
- QuicConnectionId initial_source_connection_id =
- in.initial_source_connection_id.value();
- if (!writer.WriteVarInt62(
- TransportParameters::kInitialSourceConnectionId) ||
- !writer.WriteStringPieceVarInt62(
- absl::string_view(initial_source_connection_id.data(),
- initial_source_connection_id.length()))) {
- QUIC_BUG(Failed to write initial_source_connection_id)
- << "Failed to write initial_source_connection_id "
- << initial_source_connection_id << " for " << in;
- return false;
- }
- }
- } break;
- // retry_source_connection_id
- case TransportParameters::kRetrySourceConnectionId: {
- if (in.retry_source_connection_id.has_value()) {
- QUICHE_DCHECK_EQ(Perspective::IS_SERVER, in.perspective);
- QuicConnectionId retry_source_connection_id =
- in.retry_source_connection_id.value();
- if (!writer.WriteVarInt62(
- TransportParameters::kRetrySourceConnectionId) ||
- !writer.WriteStringPieceVarInt62(
- absl::string_view(retry_source_connection_id.data(),
- retry_source_connection_id.length()))) {
- QUIC_BUG(Failed to write retry_source_connection_id)
- << "Failed to write retry_source_connection_id "
- << retry_source_connection_id << " for " << in;
- return false;
- }
- }
- } break;
- // Google-specific connection options.
- case TransportParameters::kGoogleConnectionOptions: {
- if (in.google_connection_options.has_value()) {
- static_assert(
- sizeof(in.google_connection_options.value().front()) == 4,
- "bad size");
- uint64_t connection_options_length =
- in.google_connection_options.value().size() * 4;
- if (!writer.WriteVarInt62(
- TransportParameters::kGoogleConnectionOptions) ||
- !writer.WriteVarInt62(
- /* transport parameter length */ connection_options_length)) {
- QUIC_BUG(Failed to write google_connection_options)
- << "Failed to write google_connection_options of length "
- << connection_options_length << " for " << in;
- return false;
- }
- for (const QuicTag& connection_option :
- in.google_connection_options.value()) {
- if (!writer.WriteTag(connection_option)) {
- QUIC_BUG(Failed to write google_connection_option)
- << "Failed to write google_connection_option "
- << QuicTagToString(connection_option) << " for " << in;
- return false;
- }
- }
- }
- } break;
- // Google-specific version extension.
- case TransportParameters::kGoogleQuicVersion: {
- if (!in.legacy_version_information.has_value()) {
- break;
- }
- static_assert(sizeof(QuicVersionLabel) == sizeof(uint32_t),
- "bad length");
- uint64_t google_version_length =
- sizeof(in.legacy_version_information.value().version);
- if (in.perspective == Perspective::IS_SERVER) {
- google_version_length +=
- /* versions length */ sizeof(uint8_t) +
- sizeof(QuicVersionLabel) * in.legacy_version_information.value()
- .supported_versions.size();
- }
- if (!writer.WriteVarInt62(TransportParameters::kGoogleQuicVersion) ||
- !writer.WriteVarInt62(
- /* transport parameter length */ google_version_length) ||
- !writer.WriteUInt32(
- in.legacy_version_information.value().version)) {
- QUIC_BUG(Failed to write Google version extension)
- << "Failed to write Google version extension for " << in;
- return false;
- }
- if (in.perspective == Perspective::IS_SERVER) {
- if (!writer.WriteUInt8(sizeof(QuicVersionLabel) *
- in.legacy_version_information.value()
- .supported_versions.size())) {
- QUIC_BUG(Failed to write versions length)
- << "Failed to write versions length for " << in;
- return false;
- }
- for (QuicVersionLabel version_label :
- in.legacy_version_information.value().supported_versions) {
- if (!writer.WriteUInt32(version_label)) {
- QUIC_BUG(Failed to write supported version)
- << "Failed to write supported version for " << in;
- return false;
- }
- }
- }
- } break;
- // version_information.
- case TransportParameters::kVersionInformation: {
- if (!in.version_information.has_value()) {
- break;
- }
- static_assert(sizeof(QuicVersionLabel) == sizeof(uint32_t),
- "bad length");
- QuicVersionLabelVector other_versions =
- in.version_information.value().other_versions;
- // Insert one GREASE version at a random index.
- const size_t grease_index =
- random->InsecureRandUint64() % (other_versions.size() + 1);
- other_versions.insert(
- other_versions.begin() + grease_index,
- CreateQuicVersionLabel(QuicVersionReservedForNegotiation()));
- const uint64_t version_information_length =
- sizeof(in.version_information.value().chosen_version) +
- sizeof(QuicVersionLabel) * other_versions.size();
- if (!writer.WriteVarInt62(TransportParameters::kVersionInformation) ||
- !writer.WriteVarInt62(
- /* transport parameter length */ version_information_length) ||
- !writer.WriteUInt32(
- in.version_information.value().chosen_version)) {
- QUIC_BUG(Failed to write chosen version)
- << "Failed to write chosen version for " << in;
- return false;
- }
- for (QuicVersionLabel version_label : other_versions) {
- if (!writer.WriteUInt32(version_label)) {
- QUIC_BUG(Failed to write other version)
- << "Failed to write other version for " << in;
- return false;
- }
- }
- } break;
- // Custom parameters and GREASE.
- default: {
- auto it = custom_parameters.find(parameter_id);
- if (it == custom_parameters.end()) {
- QUIC_BUG(Unknown parameter) << "Unknown parameter " << parameter_id;
- return false;
- }
- if (!writer.WriteVarInt62(parameter_id) ||
- !writer.WriteStringPieceVarInt62(it->second)) {
- QUIC_BUG(Failed to write custom parameter)
- << "Failed to write custom parameter " << parameter_id;
- return false;
- }
- } break;
- }
- }
-
- out->resize(writer.length());
-
- QUIC_DLOG(INFO) << "Serialized " << in << " as " << writer.length()
- << " bytes";
-
- return true;
-}
-
-bool ParseTransportParameters(ParsedQuicVersion version,
- Perspective perspective,
- const uint8_t* in,
- size_t in_len,
- TransportParameters* out,
- std::string* error_details) {
- out->perspective = perspective;
- QuicDataReader reader(reinterpret_cast<const char*>(in), in_len);
-
- while (!reader.IsDoneReading()) {
- uint64_t param_id64;
- if (!reader.ReadVarInt62(&param_id64)) {
- *error_details = "Failed to parse transport parameter ID";
- return false;
- }
- TransportParameters::TransportParameterId param_id =
- static_cast<TransportParameters::TransportParameterId>(param_id64);
- absl::string_view value;
- if (!reader.ReadStringPieceVarInt62(&value)) {
- *error_details =
- "Failed to read length and value of transport parameter " +
- TransportParameterIdToString(param_id);
- return false;
- }
- QuicDataReader value_reader(value);
- bool parse_success = true;
- switch (param_id) {
- case TransportParameters::kOriginalDestinationConnectionId: {
- if (out->original_destination_connection_id.has_value()) {
- *error_details =
- "Received a second original_destination_connection_id";
- return false;
- }
- const size_t connection_id_length = value_reader.BytesRemaining();
- if (!QuicUtils::IsConnectionIdLengthValidForVersion(
- connection_id_length, version.transport_version)) {
- *error_details = absl::StrCat(
- "Received original_destination_connection_id of invalid length ",
- connection_id_length);
- return false;
- }
- QuicConnectionId original_destination_connection_id;
- if (!value_reader.ReadConnectionId(&original_destination_connection_id,
- connection_id_length)) {
- *error_details = "Failed to read original_destination_connection_id";
- return false;
- }
- out->original_destination_connection_id =
- original_destination_connection_id;
- } break;
- case TransportParameters::kMaxIdleTimeout:
- parse_success =
- out->max_idle_timeout_ms.Read(&value_reader, error_details);
- break;
- case TransportParameters::kStatelessResetToken: {
- if (!out->stateless_reset_token.empty()) {
- *error_details = "Received a second stateless_reset_token";
- return false;
- }
- absl::string_view stateless_reset_token =
- value_reader.ReadRemainingPayload();
- if (stateless_reset_token.length() != kStatelessResetTokenLength) {
- *error_details =
- absl::StrCat("Received stateless_reset_token of invalid length ",
- stateless_reset_token.length());
- return false;
- }
- out->stateless_reset_token.assign(
- stateless_reset_token.data(),
- stateless_reset_token.data() + stateless_reset_token.length());
- } break;
- case TransportParameters::kMaxPacketSize:
- parse_success =
- out->max_udp_payload_size.Read(&value_reader, error_details);
- break;
- case TransportParameters::kInitialMaxData:
- parse_success =
- out->initial_max_data.Read(&value_reader, error_details);
- break;
- case TransportParameters::kInitialMaxStreamDataBidiLocal:
- parse_success = out->initial_max_stream_data_bidi_local.Read(
- &value_reader, error_details);
- break;
- case TransportParameters::kInitialMaxStreamDataBidiRemote:
- parse_success = out->initial_max_stream_data_bidi_remote.Read(
- &value_reader, error_details);
- break;
- case TransportParameters::kInitialMaxStreamDataUni:
- parse_success =
- out->initial_max_stream_data_uni.Read(&value_reader, error_details);
- break;
- case TransportParameters::kInitialMaxStreamsBidi:
- parse_success =
- out->initial_max_streams_bidi.Read(&value_reader, error_details);
- break;
- case TransportParameters::kInitialMaxStreamsUni:
- parse_success =
- out->initial_max_streams_uni.Read(&value_reader, error_details);
- break;
- case TransportParameters::kAckDelayExponent:
- parse_success =
- out->ack_delay_exponent.Read(&value_reader, error_details);
- break;
- case TransportParameters::kMaxAckDelay:
- parse_success = out->max_ack_delay.Read(&value_reader, error_details);
- break;
- case TransportParameters::kDisableActiveMigration:
- if (out->disable_active_migration) {
- *error_details = "Received a second disable_active_migration";
- return false;
- }
- out->disable_active_migration = true;
- break;
- case TransportParameters::kPreferredAddress: {
- TransportParameters::PreferredAddress preferred_address;
- uint16_t ipv4_port, ipv6_port;
- in_addr ipv4_address;
- in6_addr ipv6_address;
- preferred_address.stateless_reset_token.resize(
- kStatelessResetTokenLength);
- if (!value_reader.ReadBytes(&ipv4_address, sizeof(ipv4_address)) ||
- !value_reader.ReadUInt16(&ipv4_port) ||
- !value_reader.ReadBytes(&ipv6_address, sizeof(ipv6_address)) ||
- !value_reader.ReadUInt16(&ipv6_port) ||
- !value_reader.ReadLengthPrefixedConnectionId(
- &preferred_address.connection_id) ||
- !value_reader.ReadBytes(&preferred_address.stateless_reset_token[0],
- kStatelessResetTokenLength)) {
- *error_details = "Failed to read preferred_address";
- return false;
- }
- preferred_address.ipv4_socket_address =
- QuicSocketAddress(QuicIpAddress(ipv4_address), ipv4_port);
- preferred_address.ipv6_socket_address =
- QuicSocketAddress(QuicIpAddress(ipv6_address), ipv6_port);
- if (!preferred_address.ipv4_socket_address.host().IsIPv4() ||
- !preferred_address.ipv6_socket_address.host().IsIPv6()) {
- *error_details = "Received preferred_address of bad families " +
- preferred_address.ToString();
- return false;
- }
- if (!QuicUtils::IsConnectionIdValidForVersion(
- preferred_address.connection_id, version.transport_version)) {
- *error_details = "Received invalid preferred_address connection ID " +
- preferred_address.ToString();
- return false;
- }
- out->preferred_address =
- std::make_unique<TransportParameters::PreferredAddress>(
- preferred_address);
- } break;
- case TransportParameters::kActiveConnectionIdLimit:
- parse_success =
- out->active_connection_id_limit.Read(&value_reader, error_details);
- break;
- case TransportParameters::kInitialSourceConnectionId: {
- if (out->initial_source_connection_id.has_value()) {
- *error_details = "Received a second initial_source_connection_id";
- return false;
- }
- const size_t connection_id_length = value_reader.BytesRemaining();
- if (!QuicUtils::IsConnectionIdLengthValidForVersion(
- connection_id_length, version.transport_version)) {
- *error_details = absl::StrCat(
- "Received initial_source_connection_id of invalid length ",
- connection_id_length);
- return false;
- }
- QuicConnectionId initial_source_connection_id;
- if (!value_reader.ReadConnectionId(&initial_source_connection_id,
- connection_id_length)) {
- *error_details = "Failed to read initial_source_connection_id";
- return false;
- }
- out->initial_source_connection_id = initial_source_connection_id;
- } break;
- case TransportParameters::kRetrySourceConnectionId: {
- if (out->retry_source_connection_id.has_value()) {
- *error_details = "Received a second retry_source_connection_id";
- return false;
- }
- const size_t connection_id_length = value_reader.BytesRemaining();
- if (!QuicUtils::IsConnectionIdLengthValidForVersion(
- connection_id_length, version.transport_version)) {
- *error_details = absl::StrCat(
- "Received retry_source_connection_id of invalid length ",
- connection_id_length);
- return false;
- }
- QuicConnectionId retry_source_connection_id;
- if (!value_reader.ReadConnectionId(&retry_source_connection_id,
- connection_id_length)) {
- *error_details = "Failed to read retry_source_connection_id";
- return false;
- }
- out->retry_source_connection_id = retry_source_connection_id;
- } break;
- case TransportParameters::kMaxDatagramFrameSize:
- parse_success =
- out->max_datagram_frame_size.Read(&value_reader, error_details);
- break;
- case TransportParameters::kInitialRoundTripTime:
- parse_success =
- out->initial_round_trip_time_us.Read(&value_reader, error_details);
- break;
- case TransportParameters::kGoogleConnectionOptions: {
- if (out->google_connection_options.has_value()) {
- *error_details = "Received a second google_connection_options";
- return false;
- }
- out->google_connection_options = QuicTagVector{};
- while (!value_reader.IsDoneReading()) {
- QuicTag connection_option;
- if (!value_reader.ReadTag(&connection_option)) {
- *error_details = "Failed to read a google_connection_options";
- return false;
- }
- out->google_connection_options.value().push_back(connection_option);
- }
- } break;
- case TransportParameters::kGoogleQuicVersion: {
- if (!out->legacy_version_information.has_value()) {
- out->legacy_version_information =
- TransportParameters::LegacyVersionInformation();
- }
- if (!value_reader.ReadUInt32(
- &out->legacy_version_information.value().version)) {
- *error_details = "Failed to read Google version extension version";
- return false;
- }
- if (perspective == Perspective::IS_SERVER) {
- uint8_t versions_length;
- if (!value_reader.ReadUInt8(&versions_length)) {
- *error_details = "Failed to parse Google supported versions length";
- return false;
- }
- const uint8_t num_versions = versions_length / sizeof(uint32_t);
- for (uint8_t i = 0; i < num_versions; ++i) {
- QuicVersionLabel version;
- if (!value_reader.ReadUInt32(&version)) {
- *error_details = "Failed to parse Google supported version";
- return false;
- }
- out->legacy_version_information.value()
- .supported_versions.push_back(version);
- }
- }
- } break;
- case TransportParameters::kVersionInformation: {
- if (!GetQuicReloadableFlag(quic_version_information)) {
- // This duplicates the default case and will be removed when this flag
- // is deprecated.
- if (out->custom_parameters.find(param_id) !=
- out->custom_parameters.end()) {
- *error_details = "Received a second unknown parameter" +
- TransportParameterIdToString(param_id);
- return false;
- }
- out->custom_parameters[param_id] =
- std::string(value_reader.ReadRemainingPayload());
- break;
- }
- QUIC_RELOADABLE_FLAG_COUNT_N(quic_version_information, 2, 2);
- if (out->version_information.has_value()) {
- *error_details = "Received a second version_information";
- return false;
- }
- out->version_information = TransportParameters::VersionInformation();
- if (!value_reader.ReadUInt32(
- &out->version_information.value().chosen_version)) {
- *error_details = "Failed to read chosen version";
- return false;
- }
- while (!value_reader.IsDoneReading()) {
- QuicVersionLabel other_version;
- if (!value_reader.ReadUInt32(&other_version)) {
- *error_details = "Failed to parse other version";
- return false;
- }
- out->version_information.value().other_versions.push_back(
- other_version);
- }
- } break;
- case TransportParameters::kMinAckDelay:
- parse_success =
- out->min_ack_delay_us.Read(&value_reader, error_details);
- break;
- default:
- if (out->custom_parameters.find(param_id) !=
- out->custom_parameters.end()) {
- *error_details = "Received a second unknown parameter" +
- TransportParameterIdToString(param_id);
- return false;
- }
- out->custom_parameters[param_id] =
- std::string(value_reader.ReadRemainingPayload());
- break;
- }
- if (!parse_success) {
- QUICHE_DCHECK(!error_details->empty());
- return false;
- }
- if (!value_reader.IsDoneReading()) {
- *error_details = absl::StrCat(
- "Received unexpected ", value_reader.BytesRemaining(),
- " bytes after parsing ", TransportParameterIdToString(param_id));
- return false;
- }
- }
-
- if (!out->AreValid(error_details)) {
- QUICHE_DCHECK(!error_details->empty());
- return false;
- }
-
- QUIC_DLOG(INFO) << "Parsed transport parameters " << *out << " from "
- << in_len << " bytes";
-
- return true;
-}
-
-namespace {
-
-bool DigestUpdateIntegerParam(
- EVP_MD_CTX* hash_ctx,
- const TransportParameters::IntegerParameter& param) {
- uint64_t value = param.value();
- return EVP_DigestUpdate(hash_ctx, &value, sizeof(value));
-}
-
-} // namespace
-
-bool SerializeTransportParametersForTicket(
- const TransportParameters& in,
- const std::vector<uint8_t>& application_data,
- std::vector<uint8_t>* out) {
- std::string error_details;
- if (!in.AreValid(&error_details)) {
- QUIC_BUG(quic_bug_10743_26)
- << "Not serializing invalid transport parameters: " << error_details;
- return false;
- }
-
- out->resize(SHA256_DIGEST_LENGTH + 1);
- const uint8_t serialization_version = 0;
- (*out)[0] = serialization_version;
-
- bssl::ScopedEVP_MD_CTX hash_ctx;
- // Write application data:
- uint64_t app_data_len = application_data.size();
- const uint64_t parameter_version = 0;
- // The format of the input to the hash function is as follows:
- // - The application data, prefixed with a 64-bit length field.
- // - Transport parameters:
- // - A 64-bit version field indicating which version of encoding is used
- // for transport parameters.
- // - A list of 64-bit integers representing the relevant parameters.
- //
- // When changing which parameters are included, additional parameters can be
- // added to the end of the list without changing the version field. New
- // parameters that are variable length must be length prefixed. If
- // parameters are removed from the list, the version field must be
- // incremented.
- //
- // Integers happen to be written in host byte order, not network byte order.
- if (!EVP_DigestInit(hash_ctx.get(), EVP_sha256()) ||
- !EVP_DigestUpdate(hash_ctx.get(), &app_data_len, sizeof(app_data_len)) ||
- !EVP_DigestUpdate(hash_ctx.get(), application_data.data(),
- application_data.size()) ||
- !EVP_DigestUpdate(hash_ctx.get(), &parameter_version,
- sizeof(parameter_version))) {
- QUIC_BUG(quic_bug_10743_27)
- << "Unexpected failure of EVP_Digest functions when hashing "
- "Transport Parameters for ticket";
- return false;
- }
-
- // Write transport parameters specified by draft-ietf-quic-transport-28,
- // section 7.4.1, that are remembered for 0-RTT.
- if (!DigestUpdateIntegerParam(hash_ctx.get(), in.initial_max_data) ||
- !DigestUpdateIntegerParam(hash_ctx.get(),
- in.initial_max_stream_data_bidi_local) ||
- !DigestUpdateIntegerParam(hash_ctx.get(),
- in.initial_max_stream_data_bidi_remote) ||
- !DigestUpdateIntegerParam(hash_ctx.get(),
- in.initial_max_stream_data_uni) ||
- !DigestUpdateIntegerParam(hash_ctx.get(), in.initial_max_streams_bidi) ||
- !DigestUpdateIntegerParam(hash_ctx.get(), in.initial_max_streams_uni) ||
- !DigestUpdateIntegerParam(hash_ctx.get(),
- in.active_connection_id_limit)) {
- QUIC_BUG(quic_bug_10743_28)
- << "Unexpected failure of EVP_Digest functions when hashing "
- "Transport Parameters for ticket";
- return false;
- }
- uint8_t disable_active_migration = in.disable_active_migration ? 1 : 0;
- if (!EVP_DigestUpdate(hash_ctx.get(), &disable_active_migration,
- sizeof(disable_active_migration)) ||
- !EVP_DigestFinal(hash_ctx.get(), out->data() + 1, nullptr)) {
- QUIC_BUG(quic_bug_10743_29)
- << "Unexpected failure of EVP_Digest functions when hashing "
- "Transport Parameters for ticket";
- return false;
- }
- return true;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/transport_parameters.h b/chromium/net/third_party/quiche/src/quic/core/crypto/transport_parameters.h
deleted file mode 100644
index 1b6f51684fa..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/transport_parameters.h
+++ /dev/null
@@ -1,314 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_CRYPTO_TRANSPORT_PARAMETERS_H_
-#define QUICHE_QUIC_CORE_CRYPTO_TRANSPORT_PARAMETERS_H_
-
-#include <memory>
-#include <vector>
-
-#include "absl/container/flat_hash_map.h"
-#include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
-#include "quic/core/quic_connection_id.h"
-#include "quic/core/quic_data_reader.h"
-#include "quic/core/quic_data_writer.h"
-#include "quic/core/quic_tag.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_versions.h"
-#include "quic/platform/api/quic_containers.h"
-#include "quic/platform/api/quic_socket_address.h"
-
-namespace quic {
-
-// TransportParameters contains parameters for QUIC's transport layer that are
-// exchanged during the TLS handshake. This struct is a mirror of the struct in
-// the "Transport Parameter Encoding" section of draft-ietf-quic-transport.
-// This struct currently uses the values from draft 29.
-struct QUIC_EXPORT_PRIVATE TransportParameters {
- // The identifier used to differentiate transport parameters.
- enum TransportParameterId : uint64_t;
- // A map used to specify custom parameters.
- using ParameterMap = absl::flat_hash_map<TransportParameterId, std::string>;
- // Represents an individual QUIC transport parameter that only encodes a
- // variable length integer. Can only be created inside the constructor for
- // TransportParameters.
- class QUIC_EXPORT_PRIVATE IntegerParameter {
- public:
- // Forbid constructing and copying apart from TransportParameters.
- IntegerParameter() = delete;
- IntegerParameter& operator=(const IntegerParameter&) = delete;
- // Sets the value of this transport parameter.
- void set_value(uint64_t value);
- // Gets the value of this transport parameter.
- uint64_t value() const;
- // Validates whether the current value is valid.
- bool IsValid() const;
- // Writes to a crypto byte buffer, used during serialization. Does not write
- // anything if the value is equal to the parameter's default value.
- // Returns whether the write was successful.
- bool Write(QuicDataWriter* writer) const;
- // Reads from a crypto byte string, used during parsing.
- // Returns whether the read was successful.
- // On failure, this method will write a human-readable error message to
- // |error_details|.
- bool Read(QuicDataReader* reader, std::string* error_details);
- // operator<< allows easily logging integer transport parameters.
- friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
- std::ostream& os,
- const IntegerParameter& param);
-
- private:
- friend struct TransportParameters;
- // Constructors for initial setup used by TransportParameters only.
- // This constructor sets |default_value| and |min_value| to 0, and
- // |max_value| to kVarInt62MaxValue.
- explicit IntegerParameter(TransportParameterId param_id);
- IntegerParameter(TransportParameterId param_id,
- uint64_t default_value,
- uint64_t min_value,
- uint64_t max_value);
- IntegerParameter(const IntegerParameter& other) = default;
- IntegerParameter(IntegerParameter&& other) = default;
- // Human-readable string representation.
- std::string ToString(bool for_use_in_list) const;
-
- // Number used to indicate this transport parameter.
- TransportParameterId param_id_;
- // Current value of the transport parameter.
- uint64_t value_;
- // Default value of this transport parameter, as per IETF specification.
- const uint64_t default_value_;
- // Minimum value of this transport parameter, as per IETF specification.
- const uint64_t min_value_;
- // Maximum value of this transport parameter, as per IETF specification.
- const uint64_t max_value_;
- // Ensures this parameter is not parsed twice in the same message.
- bool has_been_read_;
- };
-
- // Represents the preferred_address transport parameter that a server can
- // send to clients.
- struct QUIC_EXPORT_PRIVATE PreferredAddress {
- PreferredAddress();
- PreferredAddress(const PreferredAddress& other) = default;
- PreferredAddress(PreferredAddress&& other) = default;
- ~PreferredAddress();
- bool operator==(const PreferredAddress& rhs) const;
- bool operator!=(const PreferredAddress& rhs) const;
-
- QuicSocketAddress ipv4_socket_address;
- QuicSocketAddress ipv6_socket_address;
- QuicConnectionId connection_id;
- std::vector<uint8_t> stateless_reset_token;
-
- // Allows easily logging.
- std::string ToString() const;
- friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
- std::ostream& os,
- const TransportParameters& params);
- };
-
- // LegacyVersionInformation represents the Google QUIC downgrade prevention
- // mechanism ported to QUIC+TLS. It is exchanged using transport parameter ID
- // 0x4752 and will eventually be deprecated in favor of
- // draft-ietf-quic-version-negotiation.
- struct QUIC_EXPORT_PRIVATE LegacyVersionInformation {
- LegacyVersionInformation();
- LegacyVersionInformation(const LegacyVersionInformation& other) = default;
- LegacyVersionInformation& operator=(const LegacyVersionInformation& other) =
- default;
- LegacyVersionInformation& operator=(LegacyVersionInformation&& other) =
- default;
- LegacyVersionInformation(LegacyVersionInformation&& other) = default;
- ~LegacyVersionInformation() = default;
- bool operator==(const LegacyVersionInformation& rhs) const;
- bool operator!=(const LegacyVersionInformation& rhs) const;
- // When sent by the client, |version| is the initial version offered by the
- // client (before any version negotiation packets) for this connection. When
- // sent by the server, |version| is the version that is in use.
- QuicVersionLabel version;
-
- // When sent by the server, |supported_versions| contains a list of all
- // versions that the server would send in a version negotiation packet. When
- // sent by the client, this is empty.
- QuicVersionLabelVector supported_versions;
-
- // Allows easily logging.
- std::string ToString() const;
- friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
- std::ostream& os,
- const LegacyVersionInformation& legacy_version_information);
- };
-
- // Version information used for version downgrade prevention and compatible
- // version negotiation. See draft-ietf-quic-version-negotiation-05.
- struct QUIC_EXPORT_PRIVATE VersionInformation {
- VersionInformation();
- VersionInformation(const VersionInformation& other) = default;
- VersionInformation& operator=(const VersionInformation& other) = default;
- VersionInformation& operator=(VersionInformation&& other) = default;
- VersionInformation(VersionInformation&& other) = default;
- ~VersionInformation() = default;
- bool operator==(const VersionInformation& rhs) const;
- bool operator!=(const VersionInformation& rhs) const;
-
- // Version that the sender has chosen to use on this connection.
- QuicVersionLabel chosen_version;
-
- // When sent by the client, |other_versions| contains all the versions that
- // this first flight is compatible with. When sent by the server,
- // |other_versions| contains all of the versions supported by the server.
- QuicVersionLabelVector other_versions;
-
- // Allows easily logging.
- std::string ToString() const;
- friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
- std::ostream& os, const VersionInformation& version_information);
- };
-
- TransportParameters();
- TransportParameters(const TransportParameters& other);
- ~TransportParameters();
- bool operator==(const TransportParameters& rhs) const;
- bool operator!=(const TransportParameters& rhs) const;
-
- // Represents the sender of the transport parameters. When |perspective| is
- // Perspective::IS_CLIENT, this struct is being used in the client_hello
- // handshake message; when it is Perspective::IS_SERVER, it is being used in
- // the encrypted_extensions handshake message.
- Perspective perspective;
-
- // Google QUIC downgrade prevention mechanism sent over QUIC+TLS.
- absl::optional<LegacyVersionInformation> legacy_version_information;
-
- // IETF downgrade prevention and compatible version negotiation, see
- // draft-ietf-quic-version-negotiation.
- absl::optional<VersionInformation> version_information;
-
- // The value of the Destination Connection ID field from the first
- // Initial packet sent by the client.
- absl::optional<QuicConnectionId> original_destination_connection_id;
-
- // Maximum idle timeout expressed in milliseconds.
- IntegerParameter max_idle_timeout_ms;
-
- // Stateless reset token used in verifying stateless resets.
- std::vector<uint8_t> stateless_reset_token;
-
- // Limits the size of packets that the endpoint is willing to receive.
- // This indicates that packets larger than this limit will be dropped.
- IntegerParameter max_udp_payload_size;
-
- // Contains the initial value for the maximum amount of data that can
- // be sent on the connection.
- IntegerParameter initial_max_data;
-
- // Initial flow control limit for locally-initiated bidirectional streams.
- IntegerParameter initial_max_stream_data_bidi_local;
-
- // Initial flow control limit for peer-initiated bidirectional streams.
- IntegerParameter initial_max_stream_data_bidi_remote;
-
- // Initial flow control limit for unidirectional streams.
- IntegerParameter initial_max_stream_data_uni;
-
- // Initial maximum number of bidirectional streams the peer may initiate.
- IntegerParameter initial_max_streams_bidi;
-
- // Initial maximum number of unidirectional streams the peer may initiate.
- IntegerParameter initial_max_streams_uni;
-
- // Exponent used to decode the ACK Delay field in ACK frames.
- IntegerParameter ack_delay_exponent;
-
- // Maximum amount of time in milliseconds by which the endpoint will
- // delay sending acknowledgments.
- IntegerParameter max_ack_delay;
-
- // Minimum amount of time in microseconds by which the endpoint will
- // delay sending acknowledgments. Used to enable sender control of ack delay.
- IntegerParameter min_ack_delay_us;
-
- // Indicates lack of support for connection migration.
- bool disable_active_migration;
-
- // Used to effect a change in server address at the end of the handshake.
- std::unique_ptr<PreferredAddress> preferred_address;
-
- // Maximum number of connection IDs from the peer that an endpoint is willing
- // to store.
- IntegerParameter active_connection_id_limit;
-
- // The value that the endpoint included in the Source Connection ID field of
- // the first Initial packet it sent.
- absl::optional<QuicConnectionId> initial_source_connection_id;
-
- // The value that the server included in the Source Connection ID field of a
- // Retry packet it sent.
- absl::optional<QuicConnectionId> retry_source_connection_id;
-
- // Indicates support for the DATAGRAM frame and the maximum frame size that
- // the sender accepts. See draft-ietf-quic-datagram.
- IntegerParameter max_datagram_frame_size;
-
- // Google-specific transport parameter that carries an estimate of the
- // initial round-trip time in microseconds.
- IntegerParameter initial_round_trip_time_us;
-
- // Google-specific connection options.
- absl::optional<QuicTagVector> google_connection_options;
-
- // Validates whether transport parameters are valid according to
- // the specification. If the transport parameters are not valid, this method
- // will write a human-readable error message to |error_details|.
- bool AreValid(std::string* error_details) const;
-
- // Custom parameters that may be specific to application protocol.
- ParameterMap custom_parameters;
-
- // Allows easily logging transport parameters.
- std::string ToString() const;
- friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
- std::ostream& os,
- const TransportParameters& params);
-};
-
-// Serializes a TransportParameters struct into the format for sending it in a
-// 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);
-
-// 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.
-// |perspective| indicates whether the input came from a client or a server.
-// This method returns true if the input was successfully parsed.
-// On failure, this method will write a human-readable error message to
-// |error_details|.
-QUIC_EXPORT_PRIVATE bool ParseTransportParameters(ParsedQuicVersion version,
- Perspective perspective,
- const uint8_t* in,
- size_t in_len,
- TransportParameters* out,
- std::string* error_details);
-
-// Serializes |in| and |application_data| in a deterministic format so that
-// multiple calls to SerializeTransportParametersForTicket with the same inputs
-// will generate the same output, and if the inputs differ, then the output will
-// differ. The output of this function is used by the server in
-// SSL_set_quic_early_data_context to determine whether early data should be
-// accepted: Early data will only be accepted if the inputs to this function
-// match what they were on the connection that issued an early data capable
-// ticket.
-QUIC_EXPORT_PRIVATE bool SerializeTransportParametersForTicket(
- const TransportParameters& in,
- const std::vector<uint8_t>& application_data,
- std::vector<uint8_t>* out);
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_CRYPTO_TRANSPORT_PARAMETERS_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/transport_parameters_test.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/transport_parameters_test.cc
deleted file mode 100644
index c9df18a3d8a..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/transport_parameters_test.cc
+++ /dev/null
@@ -1,1139 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/crypto/transport_parameters.h"
-
-#include <cstring>
-#include <utility>
-
-#include "absl/base/macros.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/crypto/crypto_protocol.h"
-#include "quic/core/quic_connection_id.h"
-#include "quic/core/quic_tag.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_versions.h"
-#include "quic/platform/api/quic_expect_bug.h"
-#include "quic/platform/api/quic_ip_address.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/quic_test_utils.h"
-
-namespace quic {
-namespace test {
-namespace {
-
-const QuicVersionLabel kFakeVersionLabel = 0x01234567;
-const QuicVersionLabel kFakeVersionLabel2 = 0x89ABCDEF;
-const uint64_t kFakeIdleTimeoutMilliseconds = 12012;
-const uint64_t kFakeInitialMaxData = 101;
-const uint64_t kFakeInitialMaxStreamDataBidiLocal = 2001;
-const uint64_t kFakeInitialMaxStreamDataBidiRemote = 2002;
-const uint64_t kFakeInitialMaxStreamDataUni = 3000;
-const uint64_t kFakeInitialMaxStreamsBidi = 21;
-const uint64_t kFakeInitialMaxStreamsUni = 22;
-const bool kFakeDisableMigration = true;
-const uint64_t kFakeInitialRoundTripTime = 53;
-const uint8_t kFakePreferredStatelessResetTokenData[16] = {
- 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
- 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F};
-
-const auto kCustomParameter1 =
- static_cast<TransportParameters::TransportParameterId>(0xffcd);
-const char* kCustomParameter1Value = "foo";
-const auto kCustomParameter2 =
- static_cast<TransportParameters::TransportParameterId>(0xff34);
-const char* kCustomParameter2Value = "bar";
-
-QuicConnectionId CreateFakeOriginalDestinationConnectionId() {
- return TestConnectionId(0x1337);
-}
-
-QuicConnectionId CreateFakeInitialSourceConnectionId() {
- return TestConnectionId(0x2345);
-}
-
-QuicConnectionId CreateFakeRetrySourceConnectionId() {
- return TestConnectionId(0x9876);
-}
-
-QuicConnectionId CreateFakePreferredConnectionId() {
- return TestConnectionId(0xBEEF);
-}
-
-std::vector<uint8_t> CreateFakePreferredStatelessResetToken() {
- return std::vector<uint8_t>(
- kFakePreferredStatelessResetTokenData,
- kFakePreferredStatelessResetTokenData +
- sizeof(kFakePreferredStatelessResetTokenData));
-}
-
-QuicSocketAddress CreateFakeV4SocketAddress() {
- QuicIpAddress ipv4_address;
- if (!ipv4_address.FromString("65.66.67.68")) { // 0x41, 0x42, 0x43, 0x44
- QUIC_LOG(FATAL) << "Failed to create IPv4 address";
- return QuicSocketAddress();
- }
- return QuicSocketAddress(ipv4_address, 0x4884);
-}
-
-QuicSocketAddress CreateFakeV6SocketAddress() {
- QuicIpAddress ipv6_address;
- if (!ipv6_address.FromString("6061:6263:6465:6667:6869:6A6B:6C6D:6E6F")) {
- QUIC_LOG(FATAL) << "Failed to create IPv6 address";
- return QuicSocketAddress();
- }
- return QuicSocketAddress(ipv6_address, 0x6336);
-}
-
-std::unique_ptr<TransportParameters::PreferredAddress>
-CreateFakePreferredAddress() {
- TransportParameters::PreferredAddress preferred_address;
- preferred_address.ipv4_socket_address = CreateFakeV4SocketAddress();
- preferred_address.ipv6_socket_address = CreateFakeV6SocketAddress();
- preferred_address.connection_id = CreateFakePreferredConnectionId();
- preferred_address.stateless_reset_token =
- CreateFakePreferredStatelessResetToken();
- return std::make_unique<TransportParameters::PreferredAddress>(
- preferred_address);
-}
-
-TransportParameters::LegacyVersionInformation
-CreateFakeLegacyVersionInformationClient() {
- TransportParameters::LegacyVersionInformation legacy_version_information;
- legacy_version_information.version = kFakeVersionLabel;
- return legacy_version_information;
-}
-
-TransportParameters::LegacyVersionInformation
-CreateFakeLegacyVersionInformationServer() {
- TransportParameters::LegacyVersionInformation legacy_version_information =
- CreateFakeLegacyVersionInformationClient();
- legacy_version_information.supported_versions.push_back(kFakeVersionLabel);
- legacy_version_information.supported_versions.push_back(kFakeVersionLabel2);
- return legacy_version_information;
-}
-
-TransportParameters::VersionInformation CreateFakeVersionInformation() {
- TransportParameters::VersionInformation version_information;
- version_information.chosen_version = kFakeVersionLabel;
- version_information.other_versions.push_back(kFakeVersionLabel);
- version_information.other_versions.push_back(kFakeVersionLabel2);
- return version_information;
-}
-
-QuicTagVector CreateFakeGoogleConnectionOptions() {
- return {kALPN, MakeQuicTag('E', 'F', 'G', 0x00),
- MakeQuicTag('H', 'I', 'J', 0xff)};
-}
-
-void RemoveGreaseParameters(TransportParameters* params) {
- std::vector<TransportParameters::TransportParameterId> grease_params;
- for (const auto& kv : params->custom_parameters) {
- if (kv.first % 31 == 27) {
- grease_params.push_back(kv.first);
- }
- }
- EXPECT_EQ(grease_params.size(), 1u);
- for (TransportParameters::TransportParameterId param_id : grease_params) {
- params->custom_parameters.erase(param_id);
- }
- // Remove all GREASE versions from version_information.other_versions.
- if (params->version_information.has_value()) {
- QuicVersionLabelVector& other_versions =
- params->version_information.value().other_versions;
- for (auto it = other_versions.begin(); it != other_versions.end();) {
- if ((*it & 0x0f0f0f0f) == 0x0a0a0a0a) {
- it = other_versions.erase(it);
- } else {
- ++it;
- }
- }
- }
-}
-
-} // namespace
-
-class TransportParametersTest : public QuicTestWithParam<ParsedQuicVersion> {
- protected:
- TransportParametersTest() : version_(GetParam()) {}
-
- ParsedQuicVersion version_;
-};
-
-INSTANTIATE_TEST_SUITE_P(TransportParametersTests,
- TransportParametersTest,
- ::testing::ValuesIn(AllSupportedVersionsWithTls()),
- ::testing::PrintToStringParamName());
-
-TEST_P(TransportParametersTest, Comparator) {
- TransportParameters orig_params;
- TransportParameters new_params;
- // Test comparison on primitive members.
- orig_params.perspective = Perspective::IS_CLIENT;
- new_params.perspective = Perspective::IS_SERVER;
- EXPECT_NE(orig_params, new_params);
- EXPECT_FALSE(orig_params == new_params);
- EXPECT_TRUE(orig_params != new_params);
- new_params.perspective = Perspective::IS_CLIENT;
- orig_params.legacy_version_information =
- CreateFakeLegacyVersionInformationClient();
- new_params.legacy_version_information =
- CreateFakeLegacyVersionInformationClient();
- orig_params.version_information = CreateFakeVersionInformation();
- new_params.version_information = CreateFakeVersionInformation();
- orig_params.disable_active_migration = true;
- new_params.disable_active_migration = true;
- EXPECT_EQ(orig_params, new_params);
- EXPECT_TRUE(orig_params == new_params);
- EXPECT_FALSE(orig_params != new_params);
-
- // Test comparison on vectors.
- orig_params.legacy_version_information.value().supported_versions.push_back(
- kFakeVersionLabel);
- new_params.legacy_version_information.value().supported_versions.push_back(
- kFakeVersionLabel2);
- EXPECT_NE(orig_params, new_params);
- EXPECT_FALSE(orig_params == new_params);
- EXPECT_TRUE(orig_params != new_params);
- new_params.legacy_version_information.value().supported_versions.pop_back();
- new_params.legacy_version_information.value().supported_versions.push_back(
- kFakeVersionLabel);
- orig_params.stateless_reset_token = CreateStatelessResetTokenForTest();
- new_params.stateless_reset_token = CreateStatelessResetTokenForTest();
- EXPECT_EQ(orig_params, new_params);
- EXPECT_TRUE(orig_params == new_params);
- EXPECT_FALSE(orig_params != new_params);
-
- // Test comparison on IntegerParameters.
- orig_params.max_udp_payload_size.set_value(kMaxPacketSizeForTest);
- new_params.max_udp_payload_size.set_value(kMaxPacketSizeForTest + 1);
- EXPECT_NE(orig_params, new_params);
- EXPECT_FALSE(orig_params == new_params);
- EXPECT_TRUE(orig_params != new_params);
- new_params.max_udp_payload_size.set_value(kMaxPacketSizeForTest);
- EXPECT_EQ(orig_params, new_params);
- EXPECT_TRUE(orig_params == new_params);
- EXPECT_FALSE(orig_params != new_params);
-
- // Test comparison on PreferredAddress
- orig_params.preferred_address = CreateFakePreferredAddress();
- EXPECT_NE(orig_params, new_params);
- EXPECT_FALSE(orig_params == new_params);
- EXPECT_TRUE(orig_params != new_params);
- new_params.preferred_address = CreateFakePreferredAddress();
- EXPECT_EQ(orig_params, new_params);
- EXPECT_TRUE(orig_params == new_params);
- EXPECT_FALSE(orig_params != new_params);
-
- // Test comparison on CustomMap
- orig_params.custom_parameters[kCustomParameter1] = kCustomParameter1Value;
- orig_params.custom_parameters[kCustomParameter2] = kCustomParameter2Value;
-
- new_params.custom_parameters[kCustomParameter2] = kCustomParameter2Value;
- new_params.custom_parameters[kCustomParameter1] = kCustomParameter1Value;
- EXPECT_EQ(orig_params, new_params);
- EXPECT_TRUE(orig_params == new_params);
- EXPECT_FALSE(orig_params != new_params);
-
- // Test comparison on connection IDs.
- orig_params.initial_source_connection_id =
- CreateFakeInitialSourceConnectionId();
- new_params.initial_source_connection_id = absl::nullopt;
- EXPECT_NE(orig_params, new_params);
- EXPECT_FALSE(orig_params == new_params);
- EXPECT_TRUE(orig_params != new_params);
- new_params.initial_source_connection_id = TestConnectionId(0xbadbad);
- EXPECT_NE(orig_params, new_params);
- EXPECT_FALSE(orig_params == new_params);
- EXPECT_TRUE(orig_params != new_params);
- new_params.initial_source_connection_id =
- CreateFakeInitialSourceConnectionId();
- EXPECT_EQ(orig_params, new_params);
- EXPECT_TRUE(orig_params == new_params);
- EXPECT_FALSE(orig_params != new_params);
-}
-
-TEST_P(TransportParametersTest, CopyConstructor) {
- TransportParameters orig_params;
- orig_params.perspective = Perspective::IS_CLIENT;
- orig_params.legacy_version_information =
- CreateFakeLegacyVersionInformationClient();
- orig_params.version_information = CreateFakeVersionInformation();
- orig_params.original_destination_connection_id =
- CreateFakeOriginalDestinationConnectionId();
- orig_params.max_idle_timeout_ms.set_value(kFakeIdleTimeoutMilliseconds);
- orig_params.stateless_reset_token = CreateStatelessResetTokenForTest();
- orig_params.max_udp_payload_size.set_value(kMaxPacketSizeForTest);
- orig_params.initial_max_data.set_value(kFakeInitialMaxData);
- orig_params.initial_max_stream_data_bidi_local.set_value(
- kFakeInitialMaxStreamDataBidiLocal);
- orig_params.initial_max_stream_data_bidi_remote.set_value(
- kFakeInitialMaxStreamDataBidiRemote);
- orig_params.initial_max_stream_data_uni.set_value(
- kFakeInitialMaxStreamDataUni);
- orig_params.initial_max_streams_bidi.set_value(kFakeInitialMaxStreamsBidi);
- orig_params.initial_max_streams_uni.set_value(kFakeInitialMaxStreamsUni);
- orig_params.ack_delay_exponent.set_value(kAckDelayExponentForTest);
- orig_params.max_ack_delay.set_value(kMaxAckDelayForTest);
- orig_params.min_ack_delay_us.set_value(kMinAckDelayUsForTest);
- orig_params.disable_active_migration = kFakeDisableMigration;
- orig_params.preferred_address = CreateFakePreferredAddress();
- orig_params.active_connection_id_limit.set_value(
- kActiveConnectionIdLimitForTest);
- orig_params.initial_source_connection_id =
- CreateFakeInitialSourceConnectionId();
- orig_params.retry_source_connection_id = CreateFakeRetrySourceConnectionId();
- orig_params.initial_round_trip_time_us.set_value(kFakeInitialRoundTripTime);
- orig_params.google_connection_options = CreateFakeGoogleConnectionOptions();
- orig_params.custom_parameters[kCustomParameter1] = kCustomParameter1Value;
- orig_params.custom_parameters[kCustomParameter2] = kCustomParameter2Value;
-
- TransportParameters new_params(orig_params);
- EXPECT_EQ(new_params, orig_params);
-}
-
-TEST_P(TransportParametersTest, RoundTripClient) {
- TransportParameters orig_params;
- orig_params.perspective = Perspective::IS_CLIENT;
- orig_params.legacy_version_information =
- CreateFakeLegacyVersionInformationClient();
- if (GetQuicReloadableFlag(quic_version_information)) {
- orig_params.version_information = CreateFakeVersionInformation();
- }
- orig_params.max_idle_timeout_ms.set_value(kFakeIdleTimeoutMilliseconds);
- orig_params.max_udp_payload_size.set_value(kMaxPacketSizeForTest);
- orig_params.initial_max_data.set_value(kFakeInitialMaxData);
- orig_params.initial_max_stream_data_bidi_local.set_value(
- kFakeInitialMaxStreamDataBidiLocal);
- orig_params.initial_max_stream_data_bidi_remote.set_value(
- kFakeInitialMaxStreamDataBidiRemote);
- orig_params.initial_max_stream_data_uni.set_value(
- kFakeInitialMaxStreamDataUni);
- orig_params.initial_max_streams_bidi.set_value(kFakeInitialMaxStreamsBidi);
- orig_params.initial_max_streams_uni.set_value(kFakeInitialMaxStreamsUni);
- orig_params.ack_delay_exponent.set_value(kAckDelayExponentForTest);
- orig_params.max_ack_delay.set_value(kMaxAckDelayForTest);
- orig_params.min_ack_delay_us.set_value(kMinAckDelayUsForTest);
- orig_params.disable_active_migration = kFakeDisableMigration;
- orig_params.active_connection_id_limit.set_value(
- kActiveConnectionIdLimitForTest);
- orig_params.initial_source_connection_id =
- CreateFakeInitialSourceConnectionId();
- orig_params.initial_round_trip_time_us.set_value(kFakeInitialRoundTripTime);
- orig_params.google_connection_options = CreateFakeGoogleConnectionOptions();
- orig_params.custom_parameters[kCustomParameter1] = kCustomParameter1Value;
- orig_params.custom_parameters[kCustomParameter2] = kCustomParameter2Value;
-
- std::vector<uint8_t> serialized;
- ASSERT_TRUE(SerializeTransportParameters(version_, orig_params, &serialized));
-
- TransportParameters new_params;
- std::string error_details;
- ASSERT_TRUE(ParseTransportParameters(version_, Perspective::IS_CLIENT,
- serialized.data(), serialized.size(),
- &new_params, &error_details))
- << error_details;
- EXPECT_TRUE(error_details.empty());
- RemoveGreaseParameters(&new_params);
- EXPECT_EQ(new_params, orig_params);
-}
-
-TEST_P(TransportParametersTest, RoundTripServer) {
- TransportParameters orig_params;
- orig_params.perspective = Perspective::IS_SERVER;
- orig_params.legacy_version_information =
- CreateFakeLegacyVersionInformationServer();
- if (GetQuicReloadableFlag(quic_version_information)) {
- orig_params.version_information = CreateFakeVersionInformation();
- }
- orig_params.original_destination_connection_id =
- CreateFakeOriginalDestinationConnectionId();
- orig_params.max_idle_timeout_ms.set_value(kFakeIdleTimeoutMilliseconds);
- orig_params.stateless_reset_token = CreateStatelessResetTokenForTest();
- orig_params.max_udp_payload_size.set_value(kMaxPacketSizeForTest);
- orig_params.initial_max_data.set_value(kFakeInitialMaxData);
- orig_params.initial_max_stream_data_bidi_local.set_value(
- kFakeInitialMaxStreamDataBidiLocal);
- orig_params.initial_max_stream_data_bidi_remote.set_value(
- kFakeInitialMaxStreamDataBidiRemote);
- orig_params.initial_max_stream_data_uni.set_value(
- kFakeInitialMaxStreamDataUni);
- orig_params.initial_max_streams_bidi.set_value(kFakeInitialMaxStreamsBidi);
- orig_params.initial_max_streams_uni.set_value(kFakeInitialMaxStreamsUni);
- orig_params.ack_delay_exponent.set_value(kAckDelayExponentForTest);
- orig_params.max_ack_delay.set_value(kMaxAckDelayForTest);
- orig_params.min_ack_delay_us.set_value(kMinAckDelayUsForTest);
- orig_params.disable_active_migration = kFakeDisableMigration;
- orig_params.preferred_address = CreateFakePreferredAddress();
- orig_params.active_connection_id_limit.set_value(
- kActiveConnectionIdLimitForTest);
- orig_params.initial_source_connection_id =
- CreateFakeInitialSourceConnectionId();
- orig_params.retry_source_connection_id = CreateFakeRetrySourceConnectionId();
- orig_params.google_connection_options = CreateFakeGoogleConnectionOptions();
-
- std::vector<uint8_t> serialized;
- ASSERT_TRUE(SerializeTransportParameters(version_, orig_params, &serialized));
-
- TransportParameters new_params;
- std::string error_details;
- ASSERT_TRUE(ParseTransportParameters(version_, Perspective::IS_SERVER,
- serialized.data(), serialized.size(),
- &new_params, &error_details))
- << error_details;
- EXPECT_TRUE(error_details.empty());
- RemoveGreaseParameters(&new_params);
- EXPECT_EQ(new_params, orig_params);
-}
-
-TEST_P(TransportParametersTest, AreValid) {
- {
- TransportParameters params;
- std::string error_details;
- params.perspective = Perspective::IS_CLIENT;
- EXPECT_TRUE(params.AreValid(&error_details));
- EXPECT_TRUE(error_details.empty());
- }
- {
- TransportParameters params;
- std::string error_details;
- params.perspective = Perspective::IS_CLIENT;
- EXPECT_TRUE(params.AreValid(&error_details));
- EXPECT_TRUE(error_details.empty());
- params.max_idle_timeout_ms.set_value(kFakeIdleTimeoutMilliseconds);
- EXPECT_TRUE(params.AreValid(&error_details));
- EXPECT_TRUE(error_details.empty());
- params.max_idle_timeout_ms.set_value(601000);
- EXPECT_TRUE(params.AreValid(&error_details));
- EXPECT_TRUE(error_details.empty());
- }
- {
- TransportParameters params;
- std::string error_details;
- params.perspective = Perspective::IS_CLIENT;
- EXPECT_TRUE(params.AreValid(&error_details));
- EXPECT_TRUE(error_details.empty());
- params.max_udp_payload_size.set_value(1200);
- EXPECT_TRUE(params.AreValid(&error_details));
- EXPECT_TRUE(error_details.empty());
- params.max_udp_payload_size.set_value(65535);
- EXPECT_TRUE(params.AreValid(&error_details));
- EXPECT_TRUE(error_details.empty());
- params.max_udp_payload_size.set_value(9999999);
- EXPECT_TRUE(params.AreValid(&error_details));
- EXPECT_TRUE(error_details.empty());
- params.max_udp_payload_size.set_value(0);
- error_details = "";
- EXPECT_FALSE(params.AreValid(&error_details));
- EXPECT_EQ(error_details,
- "Invalid transport parameters [Client max_udp_payload_size 0 "
- "(Invalid)]");
- params.max_udp_payload_size.set_value(1199);
- error_details = "";
- EXPECT_FALSE(params.AreValid(&error_details));
- EXPECT_EQ(error_details,
- "Invalid transport parameters [Client max_udp_payload_size 1199 "
- "(Invalid)]");
- }
- {
- TransportParameters params;
- std::string error_details;
- params.perspective = Perspective::IS_CLIENT;
- EXPECT_TRUE(params.AreValid(&error_details));
- EXPECT_TRUE(error_details.empty());
- params.ack_delay_exponent.set_value(0);
- EXPECT_TRUE(params.AreValid(&error_details));
- EXPECT_TRUE(error_details.empty());
- params.ack_delay_exponent.set_value(20);
- EXPECT_TRUE(params.AreValid(&error_details));
- EXPECT_TRUE(error_details.empty());
- params.ack_delay_exponent.set_value(21);
- EXPECT_FALSE(params.AreValid(&error_details));
- EXPECT_EQ(error_details,
- "Invalid transport parameters [Client ack_delay_exponent 21 "
- "(Invalid)]");
- }
- {
- TransportParameters params;
- std::string error_details;
- params.perspective = Perspective::IS_CLIENT;
- EXPECT_TRUE(params.AreValid(&error_details));
- EXPECT_TRUE(error_details.empty());
- params.active_connection_id_limit.set_value(2);
- EXPECT_TRUE(params.AreValid(&error_details));
- EXPECT_TRUE(error_details.empty());
- params.active_connection_id_limit.set_value(999999);
- EXPECT_TRUE(params.AreValid(&error_details));
- EXPECT_TRUE(error_details.empty());
- params.active_connection_id_limit.set_value(1);
- EXPECT_FALSE(params.AreValid(&error_details));
- EXPECT_EQ(error_details,
- "Invalid transport parameters [Client active_connection_id_limit"
- " 1 (Invalid)]");
- params.active_connection_id_limit.set_value(0);
- EXPECT_FALSE(params.AreValid(&error_details));
- EXPECT_EQ(error_details,
- "Invalid transport parameters [Client active_connection_id_limit"
- " 0 (Invalid)]");
- }
-}
-
-TEST_P(TransportParametersTest, NoClientParamsWithStatelessResetToken) {
- TransportParameters orig_params;
- orig_params.perspective = Perspective::IS_CLIENT;
- orig_params.legacy_version_information =
- CreateFakeLegacyVersionInformationClient();
- orig_params.max_idle_timeout_ms.set_value(kFakeIdleTimeoutMilliseconds);
- orig_params.stateless_reset_token = CreateStatelessResetTokenForTest();
- 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),
- "Not serializing invalid transport parameters: Client cannot send "
- "stateless reset token");
- EXPECT_FALSE(ok);
-}
-
-TEST_P(TransportParametersTest, ParseClientParams) {
- // clang-format off
- const uint8_t kClientParams[] = {
- // max_idle_timeout
- 0x01, // parameter id
- 0x02, // length
- 0x6e, 0xec, // value
- // max_udp_payload_size
- 0x03, // parameter id
- 0x02, // length
- 0x63, 0x29, // value
- // initial_max_data
- 0x04, // parameter id
- 0x02, // length
- 0x40, 0x65, // value
- // initial_max_stream_data_bidi_local
- 0x05, // parameter id
- 0x02, // length
- 0x47, 0xD1, // value
- // initial_max_stream_data_bidi_remote
- 0x06, // parameter id
- 0x02, // length
- 0x47, 0xD2, // value
- // initial_max_stream_data_uni
- 0x07, // parameter id
- 0x02, // length
- 0x4B, 0xB8, // value
- // initial_max_streams_bidi
- 0x08, // parameter id
- 0x01, // length
- 0x15, // value
- // initial_max_streams_uni
- 0x09, // parameter id
- 0x01, // length
- 0x16, // value
- // ack_delay_exponent
- 0x0a, // parameter id
- 0x01, // length
- 0x0a, // value
- // max_ack_delay
- 0x0b, // parameter id
- 0x01, // length
- 0x33, // value
- // min_ack_delay_us
- 0x80, 0x00, 0xde, 0x1a, // parameter id
- 0x02, // length
- 0x43, 0xe8, // value
- // disable_active_migration
- 0x0c, // parameter id
- 0x00, // length
- // active_connection_id_limit
- 0x0e, // parameter id
- 0x01, // length
- 0x34, // value
- // initial_source_connection_id
- 0x0f, // parameter id
- 0x08, // length
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x45,
- // initial_round_trip_time_us
- 0x71, 0x27, // parameter id
- 0x01, // length
- 0x35, // value
- // google_connection_options
- 0x71, 0x28, // parameter id
- 0x0c, // length
- 'A', 'L', 'P', 'N', // value
- 'E', 'F', 'G', 0x00,
- 'H', 'I', 'J', 0xff,
- // Google version extension
- 0x80, 0x00, 0x47, 0x52, // parameter id
- 0x04, // length
- 0x01, 0x23, 0x45, 0x67, // initial version
- // version_information
- 0x80, 0xFF, 0x73, 0xDB, // parameter id
- 0x0C, // length
- 0x01, 0x23, 0x45, 0x67, // chosen version
- 0x01, 0x23, 0x45, 0x67, // other version 1
- 0x89, 0xab, 0xcd, 0xef, // other version 2
- };
- // clang-format on
- const uint8_t* client_params =
- reinterpret_cast<const uint8_t*>(kClientParams);
- size_t client_params_length = ABSL_ARRAYSIZE(kClientParams);
- TransportParameters new_params;
- std::string error_details;
- ASSERT_TRUE(ParseTransportParameters(version_, Perspective::IS_CLIENT,
- client_params, client_params_length,
- &new_params, &error_details))
- << error_details;
- EXPECT_TRUE(error_details.empty());
- EXPECT_EQ(Perspective::IS_CLIENT, new_params.perspective);
- ASSERT_TRUE(new_params.legacy_version_information.has_value());
- EXPECT_EQ(kFakeVersionLabel,
- new_params.legacy_version_information.value().version);
- EXPECT_TRUE(
- new_params.legacy_version_information.value().supported_versions.empty());
- if (GetQuicReloadableFlag(quic_version_information)) {
- ASSERT_TRUE(new_params.version_information.has_value());
- EXPECT_EQ(new_params.version_information.value(),
- CreateFakeVersionInformation());
- }
- EXPECT_FALSE(new_params.original_destination_connection_id.has_value());
- EXPECT_EQ(kFakeIdleTimeoutMilliseconds,
- new_params.max_idle_timeout_ms.value());
- EXPECT_TRUE(new_params.stateless_reset_token.empty());
- EXPECT_EQ(kMaxPacketSizeForTest, new_params.max_udp_payload_size.value());
- EXPECT_EQ(kFakeInitialMaxData, new_params.initial_max_data.value());
- EXPECT_EQ(kFakeInitialMaxStreamDataBidiLocal,
- new_params.initial_max_stream_data_bidi_local.value());
- EXPECT_EQ(kFakeInitialMaxStreamDataBidiRemote,
- new_params.initial_max_stream_data_bidi_remote.value());
- EXPECT_EQ(kFakeInitialMaxStreamDataUni,
- new_params.initial_max_stream_data_uni.value());
- EXPECT_EQ(kFakeInitialMaxStreamsBidi,
- new_params.initial_max_streams_bidi.value());
- EXPECT_EQ(kFakeInitialMaxStreamsUni,
- new_params.initial_max_streams_uni.value());
- EXPECT_EQ(kAckDelayExponentForTest, new_params.ack_delay_exponent.value());
- EXPECT_EQ(kMaxAckDelayForTest, new_params.max_ack_delay.value());
- EXPECT_EQ(kMinAckDelayUsForTest, new_params.min_ack_delay_us.value());
- EXPECT_EQ(kFakeDisableMigration, new_params.disable_active_migration);
- EXPECT_EQ(kActiveConnectionIdLimitForTest,
- new_params.active_connection_id_limit.value());
- ASSERT_TRUE(new_params.initial_source_connection_id.has_value());
- EXPECT_EQ(CreateFakeInitialSourceConnectionId(),
- new_params.initial_source_connection_id.value());
- EXPECT_FALSE(new_params.retry_source_connection_id.has_value());
- EXPECT_EQ(kFakeInitialRoundTripTime,
- new_params.initial_round_trip_time_us.value());
- ASSERT_TRUE(new_params.google_connection_options.has_value());
- EXPECT_EQ(CreateFakeGoogleConnectionOptions(),
- new_params.google_connection_options.value());
-}
-
-TEST_P(TransportParametersTest,
- ParseClientParamsFailsWithFullStatelessResetToken) {
- // clang-format off
- const uint8_t kClientParamsWithFullToken[] = {
- // max_idle_timeout
- 0x01, // parameter id
- 0x02, // length
- 0x6e, 0xec, // value
- // stateless_reset_token
- 0x02, // parameter id
- 0x10, // length
- 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
- 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F,
- // max_udp_payload_size
- 0x03, // parameter id
- 0x02, // length
- 0x63, 0x29, // value
- // initial_max_data
- 0x04, // parameter id
- 0x02, // length
- 0x40, 0x65, // value
- };
- // clang-format on
- const uint8_t* client_params =
- reinterpret_cast<const uint8_t*>(kClientParamsWithFullToken);
- size_t client_params_length = ABSL_ARRAYSIZE(kClientParamsWithFullToken);
- TransportParameters out_params;
- std::string error_details;
- EXPECT_FALSE(ParseTransportParameters(version_, Perspective::IS_CLIENT,
- client_params, client_params_length,
- &out_params, &error_details));
- EXPECT_EQ(error_details, "Client cannot send stateless reset token");
-}
-
-TEST_P(TransportParametersTest,
- ParseClientParamsFailsWithEmptyStatelessResetToken) {
- // clang-format off
- const uint8_t kClientParamsWithEmptyToken[] = {
- // max_idle_timeout
- 0x01, // parameter id
- 0x02, // length
- 0x6e, 0xec, // value
- // stateless_reset_token
- 0x02, // parameter id
- 0x00, // length
- // max_udp_payload_size
- 0x03, // parameter id
- 0x02, // length
- 0x63, 0x29, // value
- // initial_max_data
- 0x04, // parameter id
- 0x02, // length
- 0x40, 0x65, // value
- };
- // clang-format on
- const uint8_t* client_params =
- reinterpret_cast<const uint8_t*>(kClientParamsWithEmptyToken);
- size_t client_params_length = ABSL_ARRAYSIZE(kClientParamsWithEmptyToken);
- TransportParameters out_params;
- std::string error_details;
- EXPECT_FALSE(ParseTransportParameters(version_, Perspective::IS_CLIENT,
- client_params, client_params_length,
- &out_params, &error_details));
- EXPECT_EQ(error_details,
- "Received stateless_reset_token of invalid length 0");
-}
-
-TEST_P(TransportParametersTest, ParseClientParametersRepeated) {
- // clang-format off
- const uint8_t kClientParamsRepeated[] = {
- // max_idle_timeout
- 0x01, // parameter id
- 0x02, // length
- 0x6e, 0xec, // value
- // max_udp_payload_size
- 0x03, // parameter id
- 0x02, // length
- 0x63, 0x29, // value
- // max_idle_timeout (repeated)
- 0x01, // parameter id
- 0x02, // length
- 0x6e, 0xec, // value
- };
- // clang-format on
- const uint8_t* client_params =
- reinterpret_cast<const uint8_t*>(kClientParamsRepeated);
- size_t client_params_length = ABSL_ARRAYSIZE(kClientParamsRepeated);
- TransportParameters out_params;
- std::string error_details;
- EXPECT_FALSE(ParseTransportParameters(version_, Perspective::IS_CLIENT,
- client_params, client_params_length,
- &out_params, &error_details));
- EXPECT_EQ(error_details, "Received a second max_idle_timeout");
-}
-
-TEST_P(TransportParametersTest, ParseServerParams) {
- // clang-format off
- const uint8_t kServerParams[] = {
- // original_destination_connection_id
- 0x00, // parameter id
- 0x08, // length
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x37,
- // max_idle_timeout
- 0x01, // parameter id
- 0x02, // length
- 0x6e, 0xec, // value
- // stateless_reset_token
- 0x02, // parameter id
- 0x10, // length
- 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
- 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F,
- // max_udp_payload_size
- 0x03, // parameter id
- 0x02, // length
- 0x63, 0x29, // value
- // initial_max_data
- 0x04, // parameter id
- 0x02, // length
- 0x40, 0x65, // value
- // initial_max_stream_data_bidi_local
- 0x05, // parameter id
- 0x02, // length
- 0x47, 0xD1, // value
- // initial_max_stream_data_bidi_remote
- 0x06, // parameter id
- 0x02, // length
- 0x47, 0xD2, // value
- // initial_max_stream_data_uni
- 0x07, // parameter id
- 0x02, // length
- 0x4B, 0xB8, // value
- // initial_max_streams_bidi
- 0x08, // parameter id
- 0x01, // length
- 0x15, // value
- // initial_max_streams_uni
- 0x09, // parameter id
- 0x01, // length
- 0x16, // value
- // ack_delay_exponent
- 0x0a, // parameter id
- 0x01, // length
- 0x0a, // value
- // max_ack_delay
- 0x0b, // parameter id
- 0x01, // length
- 0x33, // value
- // min_ack_delay_us
- 0x80, 0x00, 0xde, 0x1a, // parameter id
- 0x02, // length
- 0x43, 0xe8, // value
- // disable_active_migration
- 0x0c, // parameter id
- 0x00, // length
- // preferred_address
- 0x0d, // parameter id
- 0x31, // length
- 0x41, 0x42, 0x43, 0x44, // IPv4 address
- 0x48, 0x84, // IPv4 port
- 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, // IPv6 address
- 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
- 0x63, 0x36, // IPv6 port
- 0x08, // connection ID length
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBE, 0xEF, // connection ID
- 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, // stateless reset token
- 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,
- // active_connection_id_limit
- 0x0e, // parameter id
- 0x01, // length
- 0x34, // value
- // initial_source_connection_id
- 0x0f, // parameter id
- 0x08, // length
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x45,
- // retry_source_connection_id
- 0x10, // parameter id
- 0x08, // length
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98, 0x76,
- // google_connection_options
- 0x71, 0x28, // parameter id
- 0x0c, // length
- 'A', 'L', 'P', 'N', // value
- 'E', 'F', 'G', 0x00,
- 'H', 'I', 'J', 0xff,
- // Google version extension
- 0x80, 0x00, 0x47, 0x52, // parameter id
- 0x0d, // length
- 0x01, 0x23, 0x45, 0x67, // negotiated_version
- 0x08, // length of supported versions array
- 0x01, 0x23, 0x45, 0x67,
- 0x89, 0xab, 0xcd, 0xef,
- // version_information
- 0x80, 0xFF, 0x73, 0xDB, // parameter id
- 0x0C, // length
- 0x01, 0x23, 0x45, 0x67, // chosen version
- 0x01, 0x23, 0x45, 0x67, // other version 1
- 0x89, 0xab, 0xcd, 0xef, // other version 2
- };
- // clang-format on
- const uint8_t* server_params =
- reinterpret_cast<const uint8_t*>(kServerParams);
- size_t server_params_length = ABSL_ARRAYSIZE(kServerParams);
- TransportParameters new_params;
- std::string error_details;
- ASSERT_TRUE(ParseTransportParameters(version_, Perspective::IS_SERVER,
- server_params, server_params_length,
- &new_params, &error_details))
- << error_details;
- EXPECT_TRUE(error_details.empty());
- EXPECT_EQ(Perspective::IS_SERVER, new_params.perspective);
- ASSERT_TRUE(new_params.legacy_version_information.has_value());
- EXPECT_EQ(kFakeVersionLabel,
- new_params.legacy_version_information.value().version);
- ASSERT_EQ(
- 2u,
- new_params.legacy_version_information.value().supported_versions.size());
- EXPECT_EQ(
- kFakeVersionLabel,
- new_params.legacy_version_information.value().supported_versions[0]);
- EXPECT_EQ(
- kFakeVersionLabel2,
- new_params.legacy_version_information.value().supported_versions[1]);
- if (GetQuicReloadableFlag(quic_version_information)) {
- ASSERT_TRUE(new_params.version_information.has_value());
- EXPECT_EQ(new_params.version_information.value(),
- CreateFakeVersionInformation());
- }
- ASSERT_TRUE(new_params.original_destination_connection_id.has_value());
- EXPECT_EQ(CreateFakeOriginalDestinationConnectionId(),
- new_params.original_destination_connection_id.value());
- EXPECT_EQ(kFakeIdleTimeoutMilliseconds,
- new_params.max_idle_timeout_ms.value());
- EXPECT_EQ(CreateStatelessResetTokenForTest(),
- new_params.stateless_reset_token);
- EXPECT_EQ(kMaxPacketSizeForTest, new_params.max_udp_payload_size.value());
- EXPECT_EQ(kFakeInitialMaxData, new_params.initial_max_data.value());
- EXPECT_EQ(kFakeInitialMaxStreamDataBidiLocal,
- new_params.initial_max_stream_data_bidi_local.value());
- EXPECT_EQ(kFakeInitialMaxStreamDataBidiRemote,
- new_params.initial_max_stream_data_bidi_remote.value());
- EXPECT_EQ(kFakeInitialMaxStreamDataUni,
- new_params.initial_max_stream_data_uni.value());
- EXPECT_EQ(kFakeInitialMaxStreamsBidi,
- new_params.initial_max_streams_bidi.value());
- EXPECT_EQ(kFakeInitialMaxStreamsUni,
- new_params.initial_max_streams_uni.value());
- EXPECT_EQ(kAckDelayExponentForTest, new_params.ack_delay_exponent.value());
- EXPECT_EQ(kMaxAckDelayForTest, new_params.max_ack_delay.value());
- EXPECT_EQ(kMinAckDelayUsForTest, new_params.min_ack_delay_us.value());
- EXPECT_EQ(kFakeDisableMigration, new_params.disable_active_migration);
- ASSERT_NE(nullptr, new_params.preferred_address.get());
- EXPECT_EQ(CreateFakeV4SocketAddress(),
- new_params.preferred_address->ipv4_socket_address);
- EXPECT_EQ(CreateFakeV6SocketAddress(),
- new_params.preferred_address->ipv6_socket_address);
- EXPECT_EQ(CreateFakePreferredConnectionId(),
- new_params.preferred_address->connection_id);
- EXPECT_EQ(CreateFakePreferredStatelessResetToken(),
- new_params.preferred_address->stateless_reset_token);
- EXPECT_EQ(kActiveConnectionIdLimitForTest,
- new_params.active_connection_id_limit.value());
- ASSERT_TRUE(new_params.initial_source_connection_id.has_value());
- EXPECT_EQ(CreateFakeInitialSourceConnectionId(),
- new_params.initial_source_connection_id.value());
- ASSERT_TRUE(new_params.retry_source_connection_id.has_value());
- EXPECT_EQ(CreateFakeRetrySourceConnectionId(),
- new_params.retry_source_connection_id.value());
- ASSERT_TRUE(new_params.google_connection_options.has_value());
- EXPECT_EQ(CreateFakeGoogleConnectionOptions(),
- new_params.google_connection_options.value());
-}
-
-TEST_P(TransportParametersTest, ParseServerParametersRepeated) {
- // clang-format off
- const uint8_t kServerParamsRepeated[] = {
- // original_destination_connection_id
- 0x00, // parameter id
- 0x08, // length
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x37,
- // max_idle_timeout
- 0x01, // parameter id
- 0x02, // length
- 0x6e, 0xec, // value
- // stateless_reset_token
- 0x02, // parameter id
- 0x10, // length
- 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
- 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
- // max_idle_timeout (repeated)
- 0x01, // parameter id
- 0x02, // length
- 0x6e, 0xec, // value
- };
- // clang-format on
- const uint8_t* server_params =
- reinterpret_cast<const uint8_t*>(kServerParamsRepeated);
- size_t server_params_length = ABSL_ARRAYSIZE(kServerParamsRepeated);
- TransportParameters out_params;
- std::string error_details;
- EXPECT_FALSE(ParseTransportParameters(version_, Perspective::IS_SERVER,
- server_params, server_params_length,
- &out_params, &error_details));
- EXPECT_EQ(error_details, "Received a second max_idle_timeout");
-}
-
-TEST_P(TransportParametersTest,
- ParseServerParametersEmptyOriginalConnectionId) {
- // clang-format off
- const uint8_t kServerParamsEmptyOriginalConnectionId[] = {
- // original_destination_connection_id
- 0x00, // parameter id
- 0x00, // length
- // max_idle_timeout
- 0x01, // parameter id
- 0x02, // length
- 0x6e, 0xec, // value
- // stateless_reset_token
- 0x02, // parameter id
- 0x10, // length
- 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
- 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
- };
- // clang-format on
- const uint8_t* server_params =
- reinterpret_cast<const uint8_t*>(kServerParamsEmptyOriginalConnectionId);
- size_t server_params_length =
- ABSL_ARRAYSIZE(kServerParamsEmptyOriginalConnectionId);
- TransportParameters out_params;
- std::string error_details;
- ASSERT_TRUE(ParseTransportParameters(version_, Perspective::IS_SERVER,
- server_params, server_params_length,
- &out_params, &error_details))
- << error_details;
- ASSERT_TRUE(out_params.original_destination_connection_id.has_value());
- EXPECT_EQ(out_params.original_destination_connection_id.value(),
- EmptyQuicConnectionId());
-}
-
-TEST_P(TransportParametersTest, VeryLongCustomParameter) {
- // Ensure we can handle a 70KB custom parameter on both send and receive.
- std::string custom_value(70000, '?');
- TransportParameters orig_params;
- orig_params.perspective = Perspective::IS_CLIENT;
- orig_params.legacy_version_information =
- CreateFakeLegacyVersionInformationClient();
- orig_params.custom_parameters[kCustomParameter1] = custom_value;
-
- std::vector<uint8_t> serialized;
- ASSERT_TRUE(SerializeTransportParameters(version_, orig_params, &serialized));
-
- TransportParameters new_params;
- std::string error_details;
- ASSERT_TRUE(ParseTransportParameters(version_, Perspective::IS_CLIENT,
- serialized.data(), serialized.size(),
- &new_params, &error_details))
- << error_details;
- EXPECT_TRUE(error_details.empty());
- RemoveGreaseParameters(&new_params);
- EXPECT_EQ(new_params, orig_params);
-}
-
-TEST_P(TransportParametersTest, SerializationOrderIsRandom) {
- TransportParameters orig_params;
- orig_params.perspective = Perspective::IS_CLIENT;
- orig_params.legacy_version_information =
- CreateFakeLegacyVersionInformationClient();
- orig_params.max_idle_timeout_ms.set_value(kFakeIdleTimeoutMilliseconds);
- orig_params.max_udp_payload_size.set_value(kMaxPacketSizeForTest);
- orig_params.initial_max_data.set_value(kFakeInitialMaxData);
- orig_params.initial_max_stream_data_bidi_local.set_value(
- kFakeInitialMaxStreamDataBidiLocal);
- orig_params.initial_max_stream_data_bidi_remote.set_value(
- kFakeInitialMaxStreamDataBidiRemote);
- orig_params.initial_max_stream_data_uni.set_value(
- kFakeInitialMaxStreamDataUni);
- orig_params.initial_max_streams_bidi.set_value(kFakeInitialMaxStreamsBidi);
- orig_params.initial_max_streams_uni.set_value(kFakeInitialMaxStreamsUni);
- orig_params.ack_delay_exponent.set_value(kAckDelayExponentForTest);
- orig_params.max_ack_delay.set_value(kMaxAckDelayForTest);
- orig_params.min_ack_delay_us.set_value(kMinAckDelayUsForTest);
- orig_params.disable_active_migration = kFakeDisableMigration;
- orig_params.active_connection_id_limit.set_value(
- kActiveConnectionIdLimitForTest);
- orig_params.initial_source_connection_id =
- CreateFakeInitialSourceConnectionId();
- orig_params.initial_round_trip_time_us.set_value(kFakeInitialRoundTripTime);
- orig_params.google_connection_options = CreateFakeGoogleConnectionOptions();
- orig_params.custom_parameters[kCustomParameter1] = kCustomParameter1Value;
- orig_params.custom_parameters[kCustomParameter2] = kCustomParameter2Value;
-
- std::vector<uint8_t> first_serialized;
- ASSERT_TRUE(
- SerializeTransportParameters(version_, 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));
- if (serialized != first_serialized) {
- return;
- }
- }
-}
-
-class TransportParametersTicketSerializationTest : public QuicTest {
- protected:
- void SetUp() override {
- original_params_.perspective = Perspective::IS_SERVER;
- original_params_.legacy_version_information =
- CreateFakeLegacyVersionInformationServer();
- original_params_.original_destination_connection_id =
- CreateFakeOriginalDestinationConnectionId();
- original_params_.max_idle_timeout_ms.set_value(
- kFakeIdleTimeoutMilliseconds);
- original_params_.stateless_reset_token = CreateStatelessResetTokenForTest();
- original_params_.max_udp_payload_size.set_value(kMaxPacketSizeForTest);
- original_params_.initial_max_data.set_value(kFakeInitialMaxData);
- original_params_.initial_max_stream_data_bidi_local.set_value(
- kFakeInitialMaxStreamDataBidiLocal);
- original_params_.initial_max_stream_data_bidi_remote.set_value(
- kFakeInitialMaxStreamDataBidiRemote);
- original_params_.initial_max_stream_data_uni.set_value(
- kFakeInitialMaxStreamDataUni);
- original_params_.initial_max_streams_bidi.set_value(
- kFakeInitialMaxStreamsBidi);
- original_params_.initial_max_streams_uni.set_value(
- kFakeInitialMaxStreamsUni);
- original_params_.ack_delay_exponent.set_value(kAckDelayExponentForTest);
- original_params_.max_ack_delay.set_value(kMaxAckDelayForTest);
- original_params_.min_ack_delay_us.set_value(kMinAckDelayUsForTest);
- original_params_.disable_active_migration = kFakeDisableMigration;
- original_params_.preferred_address = CreateFakePreferredAddress();
- original_params_.active_connection_id_limit.set_value(
- kActiveConnectionIdLimitForTest);
- original_params_.initial_source_connection_id =
- CreateFakeInitialSourceConnectionId();
- original_params_.retry_source_connection_id =
- CreateFakeRetrySourceConnectionId();
- original_params_.google_connection_options =
- CreateFakeGoogleConnectionOptions();
-
- ASSERT_TRUE(SerializeTransportParametersForTicket(
- original_params_, application_state_, &original_serialized_params_));
- }
-
- TransportParameters original_params_;
- std::vector<uint8_t> application_state_ = {0, 1};
- std::vector<uint8_t> original_serialized_params_;
-};
-
-TEST_F(TransportParametersTicketSerializationTest,
- StatelessResetTokenDoesntChangeOutput) {
- // Test that changing the stateless reset token doesn't change the ticket
- // serialization.
- TransportParameters new_params = original_params_;
- new_params.stateless_reset_token = CreateFakePreferredStatelessResetToken();
- EXPECT_NE(new_params, original_params_);
-
- std::vector<uint8_t> serialized;
- ASSERT_TRUE(SerializeTransportParametersForTicket(
- new_params, application_state_, &serialized));
- EXPECT_EQ(original_serialized_params_, serialized);
-}
-
-TEST_F(TransportParametersTicketSerializationTest,
- ConnectionIDDoesntChangeOutput) {
- // Changing original destination CID doesn't change serialization.
- TransportParameters new_params = original_params_;
- new_params.original_destination_connection_id = TestConnectionId(0xCAFE);
- EXPECT_NE(new_params, original_params_);
-
- std::vector<uint8_t> serialized;
- ASSERT_TRUE(SerializeTransportParametersForTicket(
- new_params, application_state_, &serialized));
- EXPECT_EQ(original_serialized_params_, serialized);
-}
-
-TEST_F(TransportParametersTicketSerializationTest, StreamLimitChangesOutput) {
- // Changing a stream limit does change the serialization.
- TransportParameters new_params = original_params_;
- new_params.initial_max_stream_data_bidi_local.set_value(
- kFakeInitialMaxStreamDataBidiLocal + 1);
- EXPECT_NE(new_params, original_params_);
-
- std::vector<uint8_t> serialized;
- ASSERT_TRUE(SerializeTransportParametersForTicket(
- new_params, application_state_, &serialized));
- EXPECT_NE(original_serialized_params_, serialized);
-}
-
-TEST_F(TransportParametersTicketSerializationTest,
- ApplicationStateChangesOutput) {
- // Changing the application state changes the serialization.
- std::vector<uint8_t> new_application_state = {0};
- EXPECT_NE(new_application_state, application_state_);
-
- std::vector<uint8_t> serialized;
- ASSERT_TRUE(SerializeTransportParametersForTicket(
- original_params_, new_application_state, &serialized));
- EXPECT_NE(original_serialized_params_, serialized);
-}
-
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/frames/quic_ack_frame.cc b/chromium/net/third_party/quiche/src/quic/core/frames/quic_ack_frame.cc
deleted file mode 100644
index 724833e02f0..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/frames/quic_ack_frame.cc
+++ /dev/null
@@ -1,190 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/frames/quic_ack_frame.h"
-
-#include "quic/core/quic_constants.h"
-#include "quic/core/quic_interval.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_flag_utils.h"
-
-namespace quic {
-
-namespace {
-
-const QuicPacketCount kMaxPrintRange = 128;
-
-} // namespace
-
-bool IsAwaitingPacket(const QuicAckFrame& ack_frame,
- QuicPacketNumber packet_number,
- QuicPacketNumber peer_least_packet_awaiting_ack) {
- QUICHE_DCHECK(packet_number.IsInitialized());
- return (!peer_least_packet_awaiting_ack.IsInitialized() ||
- packet_number >= peer_least_packet_awaiting_ack) &&
- !ack_frame.packets.Contains(packet_number);
-}
-
-QuicAckFrame::QuicAckFrame() = default;
-
-QuicAckFrame::QuicAckFrame(const QuicAckFrame& other) = default;
-
-QuicAckFrame::~QuicAckFrame() {}
-
-std::ostream& operator<<(std::ostream& os, const QuicAckFrame& ack_frame) {
- os << "{ largest_acked: " << LargestAcked(ack_frame)
- << ", ack_delay_time: " << ack_frame.ack_delay_time.ToMicroseconds()
- << ", packets: [ " << ack_frame.packets << " ]"
- << ", received_packets: [ ";
- for (const std::pair<QuicPacketNumber, QuicTime>& p :
- ack_frame.received_packet_times) {
- os << p.first << " at " << p.second.ToDebuggingValue() << " ";
- }
- os << " ]";
- os << ", ecn_counters_populated: " << ack_frame.ecn_counters_populated;
- if (ack_frame.ecn_counters_populated) {
- os << ", ect_0_count: " << ack_frame.ect_0_count
- << ", ect_1_count: " << ack_frame.ect_1_count
- << ", ecn_ce_count: " << ack_frame.ecn_ce_count;
- }
-
- os << " }\n";
- return os;
-}
-
-void QuicAckFrame::Clear() {
- largest_acked.Clear();
- ack_delay_time = QuicTime::Delta::Infinite();
- received_packet_times.clear();
- packets.Clear();
-}
-
-PacketNumberQueue::PacketNumberQueue() {}
-PacketNumberQueue::PacketNumberQueue(const PacketNumberQueue& other) = default;
-PacketNumberQueue::PacketNumberQueue(PacketNumberQueue&& other) = default;
-PacketNumberQueue::~PacketNumberQueue() {}
-
-PacketNumberQueue& PacketNumberQueue::operator=(
- const PacketNumberQueue& other) = default;
-PacketNumberQueue& PacketNumberQueue::operator=(PacketNumberQueue&& other) =
- default;
-
-void PacketNumberQueue::Add(QuicPacketNumber packet_number) {
- if (!packet_number.IsInitialized()) {
- return;
- }
- packet_number_intervals_.AddOptimizedForAppend(packet_number,
- packet_number + 1);
-}
-
-void PacketNumberQueue::AddRange(QuicPacketNumber lower,
- QuicPacketNumber higher) {
- if (!lower.IsInitialized() || !higher.IsInitialized() || lower >= higher) {
- return;
- }
-
- packet_number_intervals_.AddOptimizedForAppend(lower, higher);
-}
-
-bool PacketNumberQueue::RemoveUpTo(QuicPacketNumber higher) {
- if (!higher.IsInitialized() || Empty()) {
- return false;
- }
- return packet_number_intervals_.TrimLessThan(higher);
-}
-
-void PacketNumberQueue::RemoveSmallestInterval() {
- // TODO(wub): Move this QUIC_BUG to upper level.
- QUIC_BUG_IF(quic_bug_12614_1, packet_number_intervals_.Size() < 2)
- << (Empty() ? "No intervals to remove."
- : "Can't remove the last interval.");
- packet_number_intervals_.PopFront();
-}
-
-void PacketNumberQueue::Clear() {
- packet_number_intervals_.Clear();
-}
-
-bool PacketNumberQueue::Contains(QuicPacketNumber packet_number) const {
- if (!packet_number.IsInitialized()) {
- return false;
- }
- return packet_number_intervals_.Contains(packet_number);
-}
-
-bool PacketNumberQueue::Empty() const {
- return packet_number_intervals_.Empty();
-}
-
-QuicPacketNumber PacketNumberQueue::Min() const {
- QUICHE_DCHECK(!Empty());
- return packet_number_intervals_.begin()->min();
-}
-
-QuicPacketNumber PacketNumberQueue::Max() const {
- QUICHE_DCHECK(!Empty());
- return packet_number_intervals_.rbegin()->max() - 1;
-}
-
-QuicPacketCount PacketNumberQueue::NumPacketsSlow() const {
- QuicPacketCount n_packets = 0;
- for (const auto& interval : packet_number_intervals_) {
- n_packets += interval.Length();
- }
- return n_packets;
-}
-
-size_t PacketNumberQueue::NumIntervals() const {
- return packet_number_intervals_.Size();
-}
-
-PacketNumberQueue::const_iterator PacketNumberQueue::begin() const {
- return packet_number_intervals_.begin();
-}
-
-PacketNumberQueue::const_iterator PacketNumberQueue::end() const {
- return packet_number_intervals_.end();
-}
-
-PacketNumberQueue::const_reverse_iterator PacketNumberQueue::rbegin() const {
- return packet_number_intervals_.rbegin();
-}
-
-PacketNumberQueue::const_reverse_iterator PacketNumberQueue::rend() const {
- return packet_number_intervals_.rend();
-}
-
-QuicPacketCount PacketNumberQueue::LastIntervalLength() const {
- QUICHE_DCHECK(!Empty());
- return packet_number_intervals_.rbegin()->Length();
-}
-
-// Largest min...max range for packet numbers where we print the numbers
-// explicitly. If bigger than this, we print as a range [a,d] rather
-// than [a b c d]
-
-std::ostream& operator<<(std::ostream& os, const PacketNumberQueue& q) {
- for (const QuicInterval<QuicPacketNumber>& interval : q) {
- // Print as a range if there is a pathological condition.
- if ((interval.min() >= interval.max()) ||
- (interval.max() - interval.min() > kMaxPrintRange)) {
- // If min>max, it's really a bug, so QUIC_BUG it to
- // catch it in development.
- QUIC_BUG_IF(quic_bug_12614_2, interval.min() >= interval.max())
- << "Ack Range minimum (" << interval.min() << "Not less than max ("
- << interval.max() << ")";
- // print range as min...max rather than full list.
- // in the event of a bug, the list could be very big.
- os << interval.min() << "..." << (interval.max() - 1) << " ";
- } else {
- for (QuicPacketNumber packet_number = interval.min();
- packet_number < interval.max(); ++packet_number) {
- os << packet_number << " ";
- }
- }
- }
- return os;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/frames/quic_ack_frame.h b/chromium/net/third_party/quiche/src/quic/core/frames/quic_ack_frame.h
deleted file mode 100644
index c9c46d41d3c..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/frames/quic_ack_frame.h
+++ /dev/null
@@ -1,148 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_FRAMES_QUIC_ACK_FRAME_H_
-#define QUICHE_QUIC_CORE_FRAMES_QUIC_ACK_FRAME_H_
-
-#include <ostream>
-
-#include "quic/core/quic_interval.h"
-#include "quic/core/quic_interval_set.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_containers.h"
-#include "quic/platform/api/quic_export.h"
-#include "quic/platform/api/quic_flags.h"
-
-namespace quic {
-
-// A sequence of packet numbers where each number is unique. Intended to be used
-// in a sliding window fashion, where smaller old packet numbers are removed and
-// larger new packet numbers are added, with the occasional random access.
-class QUIC_EXPORT_PRIVATE PacketNumberQueue {
- public:
- PacketNumberQueue();
- PacketNumberQueue(const PacketNumberQueue& other);
- PacketNumberQueue(PacketNumberQueue&& other);
- ~PacketNumberQueue();
-
- PacketNumberQueue& operator=(const PacketNumberQueue& other);
- PacketNumberQueue& operator=(PacketNumberQueue&& other);
-
- using const_iterator = QuicIntervalSet<QuicPacketNumber>::const_iterator;
- using const_reverse_iterator =
- QuicIntervalSet<QuicPacketNumber>::const_reverse_iterator;
-
- // Adds |packet_number| to the set of packets in the queue.
- void Add(QuicPacketNumber packet_number);
-
- // Adds packets between [lower, higher) to the set of packets in the queue.
- // No-op if |higher| < |lower|.
- // NOTE(wub): Only used in tests as of Nov 2019.
- void AddRange(QuicPacketNumber lower, QuicPacketNumber higher);
-
- // Removes packets with values less than |higher| from the set of packets in
- // the queue. Returns true if packets were removed.
- bool RemoveUpTo(QuicPacketNumber higher);
-
- // Removes the smallest interval in the queue.
- void RemoveSmallestInterval();
-
- // Clear this packet number queue.
- void Clear();
-
- // Returns true if the queue contains |packet_number|.
- bool Contains(QuicPacketNumber packet_number) const;
-
- // Returns true if the queue is empty.
- bool Empty() const;
-
- // Returns the minimum packet number stored in the queue. It is undefined
- // behavior to call this if the queue is empty.
- QuicPacketNumber Min() const;
-
- // Returns the maximum packet number stored in the queue. It is undefined
- // behavior to call this if the queue is empty.
- QuicPacketNumber Max() const;
-
- // Returns the number of unique packets stored in the queue. Inefficient; only
- // exposed for testing.
- QuicPacketCount NumPacketsSlow() const;
-
- // Returns the number of disjoint packet number intervals contained in the
- // queue.
- size_t NumIntervals() const;
-
- // Returns the length of last interval.
- QuicPacketCount LastIntervalLength() const;
-
- // Returns iterators over the packet number intervals.
- const_iterator begin() const;
- const_iterator end() const;
- const_reverse_iterator rbegin() const;
- const_reverse_iterator rend() const;
-
- friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
- std::ostream& os,
- const PacketNumberQueue& q);
-
- private:
- QuicIntervalSet<QuicPacketNumber> packet_number_intervals_;
-};
-
-struct QUIC_EXPORT_PRIVATE QuicAckFrame {
- QuicAckFrame();
- QuicAckFrame(const QuicAckFrame& other);
- ~QuicAckFrame();
-
- void Clear();
-
- friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
- std::ostream& os,
- const QuicAckFrame& ack_frame);
-
- // The highest packet number we've observed from the peer. When |packets| is
- // not empty, it should always be equal to packets.Max(). The |LargestAcked|
- // function ensures this invariant in debug mode.
- QuicPacketNumber largest_acked;
-
- // Time elapsed since largest_observed() was received until this Ack frame was
- // sent.
- QuicTime::Delta ack_delay_time = QuicTime::Delta::Infinite();
-
- // Vector of <packet_number, time> for when packets arrived.
- // For IETF versions, packet numbers and timestamps in this vector are both in
- // ascending orders. Packets received out of order are not saved here.
- PacketTimeVector received_packet_times;
-
- // Set of packets.
- PacketNumberQueue packets;
-
- // ECN counters, used only in version 99's ACK frame and valid only when
- // |ecn_counters_populated| is true.
- bool ecn_counters_populated = false;
- QuicPacketCount ect_0_count = 0;
- QuicPacketCount ect_1_count = 0;
- QuicPacketCount ecn_ce_count = 0;
-};
-
-// The highest acked packet number we've observed from the peer. If no packets
-// have been observed, return 0.
-inline QUIC_EXPORT_PRIVATE QuicPacketNumber
-LargestAcked(const QuicAckFrame& frame) {
- QUICHE_DCHECK(frame.packets.Empty() ||
- frame.packets.Max() == frame.largest_acked);
- return frame.largest_acked;
-}
-
-// True if the packet number is greater than largest_observed or is listed
-// as missing.
-// Always returns false for packet numbers less than least_unacked.
-QUIC_EXPORT_PRIVATE bool IsAwaitingPacket(
- const QuicAckFrame& ack_frame,
- QuicPacketNumber packet_number,
- QuicPacketNumber peer_least_packet_awaiting_ack);
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_FRAMES_QUIC_ACK_FRAME_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/frames/quic_ack_frequency_frame.cc b/chromium/net/third_party/quiche/src/quic/core/frames/quic_ack_frequency_frame.cc
deleted file mode 100644
index 4bbfa17e160..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/frames/quic_ack_frequency_frame.cc
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright (c) 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/frames/quic_ack_frequency_frame.h"
-#include <cstdint>
-#include <limits>
-
-namespace quic {
-
-QuicAckFrequencyFrame::QuicAckFrequencyFrame(
- QuicControlFrameId control_frame_id,
- uint64_t sequence_number,
- uint64_t packet_tolerance,
- QuicTime::Delta max_ack_delay)
- : control_frame_id(control_frame_id),
- sequence_number(sequence_number),
- packet_tolerance(packet_tolerance),
- max_ack_delay(max_ack_delay) {}
-
-std::ostream& operator<<(std::ostream& os, const QuicAckFrequencyFrame& frame) {
- os << "{ control_frame_id: " << frame.control_frame_id
- << ", sequence_number: " << frame.sequence_number
- << ", packet_tolerance: " << frame.packet_tolerance
- << ", max_ack_delay_ms: " << frame.max_ack_delay.ToMilliseconds()
- << ", ignore_order: " << frame.ignore_order << " }\n";
- return os;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/frames/quic_ack_frequency_frame.h b/chromium/net/third_party/quiche/src/quic/core/frames/quic_ack_frequency_frame.h
deleted file mode 100644
index 68e08e49113..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/frames/quic_ack_frequency_frame.h
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright (c) 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_FRAMES_QUIC_ACK_FREQUENCY_FRAME_H_
-#define QUICHE_QUIC_CORE_FRAMES_QUIC_ACK_FREQUENCY_FRAME_H_
-
-#include <cstdint>
-#include <ostream>
-
-#include "quic/core/quic_constants.h"
-#include "quic/core/quic_time.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// A frame that allows sender control of acknowledgement delays.
-struct QUIC_EXPORT_PRIVATE QuicAckFrequencyFrame {
- friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
- std::ostream& os,
- const QuicAckFrequencyFrame& ack_frequency_frame);
-
- QuicAckFrequencyFrame() = default;
- QuicAckFrequencyFrame(QuicControlFrameId control_frame_id,
- uint64_t sequence_number,
- uint64_t packet_tolerance,
- QuicTime::Delta max_ack_delay);
-
- // A unique identifier of this control frame. 0 when this frame is
- // received, and non-zero when sent.
- QuicControlFrameId control_frame_id = kInvalidControlFrameId;
-
- // If true, do not ack immediately upon observeation of packet reordering.
- bool ignore_order = false;
-
- // Sequence number assigned to the ACK_FREQUENCY frame by the sender to allow
- // receivers to ignore obsolete frames.
- uint64_t sequence_number = 0;
-
- // The maximum number of ack-eliciting packets after which the receiver sends
- // an acknowledgement. Invald if == 0.
- uint64_t packet_tolerance = 2;
-
- // The maximum time that ack packets can be delayed.
- QuicTime::Delta max_ack_delay =
- QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_FRAMES_QUIC_ACK_FREQUENCY_FRAME_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/frames/quic_blocked_frame.cc b/chromium/net/third_party/quiche/src/quic/core/frames/quic_blocked_frame.cc
deleted file mode 100644
index 1d46a12790a..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/frames/quic_blocked_frame.cc
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/frames/quic_blocked_frame.h"
-
-namespace quic {
-
-QuicBlockedFrame::QuicBlockedFrame(QuicControlFrameId control_frame_id,
- QuicStreamId stream_id)
- : control_frame_id(control_frame_id), stream_id(stream_id), offset(0) {}
-
-QuicBlockedFrame::QuicBlockedFrame(QuicControlFrameId control_frame_id,
- QuicStreamId stream_id,
- QuicStreamOffset offset)
- : control_frame_id(control_frame_id),
- stream_id(stream_id),
- offset(offset) {}
-
-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";
- return os;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/frames/quic_blocked_frame.h b/chromium/net/third_party/quiche/src/quic/core/frames/quic_blocked_frame.h
deleted file mode 100644
index f979fe0d7e5..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/frames/quic_blocked_frame.h
+++ /dev/null
@@ -1,48 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_FRAMES_QUIC_BLOCKED_FRAME_H_
-#define QUICHE_QUIC_CORE_FRAMES_QUIC_BLOCKED_FRAME_H_
-
-#include <ostream>
-
-#include "quic/core/quic_constants.h"
-#include "quic/core/quic_types.h"
-
-namespace quic {
-
-// The BLOCKED frame is used to indicate to the remote endpoint that this
-// endpoint believes itself to be flow-control blocked but otherwise ready to
-// send data. The BLOCKED frame is purely advisory and optional.
-// Based on SPDY's BLOCKED frame (undocumented as of 2014-01-28).
-struct QUIC_EXPORT_PRIVATE QuicBlockedFrame {
- QuicBlockedFrame() = default;
- QuicBlockedFrame(QuicControlFrameId control_frame_id, QuicStreamId stream_id);
- QuicBlockedFrame(QuicControlFrameId control_frame_id,
- QuicStreamId stream_id,
- QuicStreamOffset offset);
-
- friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
- std::ostream& os,
- const QuicBlockedFrame& b);
-
- // A unique identifier of this control frame. 0 when this frame is received,
- // and non-zero when sent.
- QuicControlFrameId control_frame_id = kInvalidControlFrameId;
-
- // 0 is a special case meaning the connection is blocked, rather than a
- // stream. So stream_id 0 corresponds to a BLOCKED frame and non-0
- // corresponds to a STREAM_BLOCKED.
- // TODO(fkastenholz): This should be converted to use
- // QuicUtils::GetInvalidStreamId to get the correct invalid stream id value
- // and not rely on 0.
- QuicStreamId stream_id = 0;
-
- // For Google QUIC, the offset is ignored.
- QuicStreamOffset offset = 0;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_FRAMES_QUIC_BLOCKED_FRAME_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/frames/quic_connection_close_frame.cc b/chromium/net/third_party/quiche/src/quic/core/frames/quic_connection_close_frame.cc
deleted file mode 100644
index e17c3e76c7c..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/frames/quic_connection_close_frame.cc
+++ /dev/null
@@ -1,76 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/frames/quic_connection_close_frame.h"
-
-#include <memory>
-
-#include "quic/core/quic_constants.h"
-#include "quic/core/quic_error_codes.h"
-#include "quic/core/quic_types.h"
-
-namespace quic {
-
-QuicConnectionCloseFrame::QuicConnectionCloseFrame(
- QuicTransportVersion transport_version,
- QuicErrorCode error_code,
- QuicIetfTransportErrorCodes ietf_error,
- std::string error_phrase,
- uint64_t frame_type)
- : quic_error_code(error_code), error_details(error_phrase) {
- if (!VersionHasIetfQuicFrames(transport_version)) {
- close_type = GOOGLE_QUIC_CONNECTION_CLOSE;
- wire_error_code = error_code;
- transport_close_frame_type = 0;
- return;
- }
- QuicErrorCodeToIetfMapping mapping =
- QuicErrorCodeToTransportErrorCode(error_code);
- if (ietf_error != NO_IETF_QUIC_ERROR) {
- wire_error_code = ietf_error;
- } else {
- wire_error_code = mapping.error_code;
- }
- if (mapping.is_transport_close) {
- // Maps to a transport close
- close_type = IETF_QUIC_TRANSPORT_CONNECTION_CLOSE;
- transport_close_frame_type = frame_type;
- return;
- }
- // Maps to an application close.
- close_type = IETF_QUIC_APPLICATION_CONNECTION_CLOSE;
- transport_close_frame_type = 0;
-}
-
-std::ostream& operator<<(
- std::ostream& os,
- const QuicConnectionCloseFrame& connection_close_frame) {
- os << "{ Close type: " << connection_close_frame.close_type;
- switch (connection_close_frame.close_type) {
- case IETF_QUIC_TRANSPORT_CONNECTION_CLOSE:
- os << ", wire_error_code: "
- << static_cast<QuicIetfTransportErrorCodes>(
- connection_close_frame.wire_error_code);
- break;
- case IETF_QUIC_APPLICATION_CONNECTION_CLOSE:
- os << ", wire_error_code: " << connection_close_frame.wire_error_code;
- break;
- case GOOGLE_QUIC_CONNECTION_CLOSE:
- // Do not log, value same as |quic_error_code|.
- break;
- }
- os << ", quic_error_code: "
- << QuicErrorCodeToString(connection_close_frame.quic_error_code)
- << ", error_details: '" << connection_close_frame.error_details << "'";
- if (connection_close_frame.close_type ==
- IETF_QUIC_TRANSPORT_CONNECTION_CLOSE) {
- os << ", frame_type: "
- << static_cast<QuicIetfFrameType>(
- connection_close_frame.transport_close_frame_type);
- }
- os << "}\n";
- return os;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/frames/quic_connection_close_frame.h b/chromium/net/third_party/quiche/src/quic/core/frames/quic_connection_close_frame.h
deleted file mode 100644
index 66a90ad7d34..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/frames/quic_connection_close_frame.h
+++ /dev/null
@@ -1,69 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_FRAMES_QUIC_CONNECTION_CLOSE_FRAME_H_
-#define QUICHE_QUIC_CORE_FRAMES_QUIC_CONNECTION_CLOSE_FRAME_H_
-
-#include <ostream>
-#include <string>
-
-#include "quic/core/quic_error_codes.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_versions.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-struct QUIC_EXPORT_PRIVATE QuicConnectionCloseFrame {
- QuicConnectionCloseFrame() = default;
-
- // Builds a connection close frame based on the transport version
- // and the mapping of error_code. THIS IS THE PREFERRED C'TOR
- // TO USE IF YOU NEED TO CREATE A CONNECTION-CLOSE-FRAME AND
- // HAVE IT BE CORRECT FOR THE VERSION AND CODE MAPPINGS.
- // |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_code| will be used.
- QuicConnectionCloseFrame(QuicTransportVersion transport_version,
- QuicErrorCode error_code,
- QuicIetfTransportErrorCodes ietf_error,
- std::string error_phrase,
- uint64_t transport_close_frame_type);
-
- friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
- std::ostream& os,
- const QuicConnectionCloseFrame& c);
-
- // Indicates whether the the frame is a Google QUIC CONNECTION_CLOSE frame,
- // an IETF QUIC CONNECTION_CLOSE frame with transport error code,
- // or an IETF QUIC CONNECTION_CLOSE frame with application error code.
- QuicConnectionCloseType close_type = GOOGLE_QUIC_CONNECTION_CLOSE;
-
- // The error code on the wire. For Google QUIC frames, this has the same
- // value as |quic_error_code|.
- uint64_t wire_error_code = QUIC_NO_ERROR;
-
- // The underlying error. For Google QUIC frames, this has the same value as
- // |wire_error_code|. For sent IETF QUIC frames, this is the error that
- // triggered the closure of the connection. For received IETF QUIC frames,
- // this is parsed from the Reason Phrase field of the CONNECTION_CLOSE frame,
- // or QUIC_IETF_GQUIC_ERROR_MISSING.
- QuicErrorCode quic_error_code = QUIC_NO_ERROR;
-
- // String with additional error details. |quic_error_code| and a colon will be
- // prepended to the error details when sending IETF QUIC frames, and parsed
- // into |quic_error_code| upon receipt, when present.
- std::string error_details;
-
- // The frame type present in the IETF transport connection close frame.
- // Not populated for the Google QUIC or application connection close frames.
- // Contains the type of frame that triggered the connection close. Made a
- // uint64, as opposed to the QuicIetfFrameType, to support possible
- // extensions as well as reporting invalid frame types received from the peer.
- uint64_t transport_close_frame_type = 0;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_FRAMES_QUIC_CONNECTION_CLOSE_FRAME_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/frames/quic_crypto_frame.cc b/chromium/net/third_party/quiche/src/quic/core/frames/quic_crypto_frame.cc
deleted file mode 100644
index 7b72beb10c9..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/frames/quic_crypto_frame.cc
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/frames/quic_crypto_frame.h"
-
-#include "absl/strings/string_view.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-QuicCryptoFrame::QuicCryptoFrame(EncryptionLevel level,
- QuicStreamOffset offset,
- QuicPacketLength data_length)
- : QuicCryptoFrame(level, offset, nullptr, data_length) {}
-
-QuicCryptoFrame::QuicCryptoFrame(EncryptionLevel level,
- QuicStreamOffset offset,
- absl::string_view data)
- : QuicCryptoFrame(level, offset, data.data(), data.length()) {}
-
-QuicCryptoFrame::QuicCryptoFrame(EncryptionLevel level,
- QuicStreamOffset offset,
- const char* data_buffer,
- QuicPacketLength data_length)
- : level(level),
- data_length(data_length),
- data_buffer(data_buffer),
- offset(offset) {}
-
-QuicCryptoFrame::~QuicCryptoFrame() {}
-
-std::ostream& operator<<(std::ostream& os,
- const QuicCryptoFrame& stream_frame) {
- os << "{ level: " << stream_frame.level << ", offset: " << stream_frame.offset
- << ", length: " << stream_frame.data_length << " }\n";
- return os;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/frames/quic_crypto_frame.h b/chromium/net/third_party/quiche/src/quic/core/frames/quic_crypto_frame.h
deleted file mode 100644
index e1e79a6c4cb..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/frames/quic_crypto_frame.h
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_FRAMES_QUIC_CRYPTO_FRAME_H_
-#define QUICHE_QUIC_CORE_FRAMES_QUIC_CRYPTO_FRAME_H_
-
-#include <memory>
-#include <ostream>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_buffer_allocator.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-struct QUIC_EXPORT_PRIVATE QuicCryptoFrame {
- QuicCryptoFrame() = default;
- QuicCryptoFrame(EncryptionLevel level,
- QuicStreamOffset offset,
- QuicPacketLength data_length);
- QuicCryptoFrame(EncryptionLevel level,
- QuicStreamOffset offset,
- absl::string_view data);
- ~QuicCryptoFrame();
-
- friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
- const QuicCryptoFrame& s);
-
- // 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|.
- EncryptionLevel level = ENCRYPTION_INITIAL;
- QuicPacketLength data_length = 0;
- // When reading, |data_buffer| points to the data that was received in the
- // frame. |data_buffer| is not used when writing.
- const char* data_buffer = nullptr;
- QuicStreamOffset offset = 0; // Location of this data in the stream.
-
- QuicCryptoFrame(EncryptionLevel level,
- QuicStreamOffset offset,
- const char* data_buffer,
- QuicPacketLength data_length);
-};
-static_assert(sizeof(QuicCryptoFrame) <= 64,
- "Keep the QuicCryptoFrame size to a cacheline.");
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_FRAMES_QUIC_CRYPTO_FRAME_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/frames/quic_frame.cc b/chromium/net/third_party/quiche/src/quic/core/frames/quic_frame.cc
deleted file mode 100644
index c31b45e322e..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/frames/quic_frame.cc
+++ /dev/null
@@ -1,531 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/frames/quic_frame.h"
-
-#include "quic/core/frames/quic_new_connection_id_frame.h"
-#include "quic/core/frames/quic_retire_connection_id_frame.h"
-#include "quic/core/quic_buffer_allocator.h"
-#include "quic/core/quic_constants.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-QuicFrame::QuicFrame() {}
-
-QuicFrame::QuicFrame(QuicPaddingFrame padding_frame)
- : padding_frame(padding_frame) {}
-
-QuicFrame::QuicFrame(QuicStreamFrame stream_frame)
- : stream_frame(stream_frame) {}
-
-QuicFrame::QuicFrame(QuicHandshakeDoneFrame handshake_done_frame)
- : handshake_done_frame(handshake_done_frame) {}
-
-QuicFrame::QuicFrame(QuicCryptoFrame* crypto_frame)
- : type(CRYPTO_FRAME), crypto_frame(crypto_frame) {}
-
-QuicFrame::QuicFrame(QuicAckFrame* frame) : type(ACK_FRAME), ack_frame(frame) {}
-
-QuicFrame::QuicFrame(QuicMtuDiscoveryFrame frame)
- : mtu_discovery_frame(frame) {}
-
-QuicFrame::QuicFrame(QuicStopWaitingFrame frame) : stop_waiting_frame(frame) {}
-
-QuicFrame::QuicFrame(QuicPingFrame frame) : ping_frame(frame) {}
-
-QuicFrame::QuicFrame(QuicRstStreamFrame* frame)
- : type(RST_STREAM_FRAME), rst_stream_frame(frame) {}
-
-QuicFrame::QuicFrame(QuicConnectionCloseFrame* frame)
- : type(CONNECTION_CLOSE_FRAME), connection_close_frame(frame) {}
-
-QuicFrame::QuicFrame(QuicGoAwayFrame* frame)
- : type(GOAWAY_FRAME), goaway_frame(frame) {}
-
-QuicFrame::QuicFrame(QuicWindowUpdateFrame* frame)
- : type(WINDOW_UPDATE_FRAME), window_update_frame(frame) {}
-
-QuicFrame::QuicFrame(QuicBlockedFrame* frame)
- : type(BLOCKED_FRAME), blocked_frame(frame) {}
-
-QuicFrame::QuicFrame(QuicNewConnectionIdFrame* frame)
- : type(NEW_CONNECTION_ID_FRAME), new_connection_id_frame(frame) {}
-
-QuicFrame::QuicFrame(QuicRetireConnectionIdFrame* frame)
- : type(RETIRE_CONNECTION_ID_FRAME), retire_connection_id_frame(frame) {}
-
-QuicFrame::QuicFrame(QuicMaxStreamsFrame frame) : max_streams_frame(frame) {}
-
-QuicFrame::QuicFrame(QuicStreamsBlockedFrame frame)
- : streams_blocked_frame(frame) {}
-
-QuicFrame::QuicFrame(QuicPathResponseFrame* frame)
- : type(PATH_RESPONSE_FRAME), path_response_frame(frame) {}
-
-QuicFrame::QuicFrame(QuicPathChallengeFrame* frame)
- : type(PATH_CHALLENGE_FRAME), path_challenge_frame(frame) {}
-
-QuicFrame::QuicFrame(QuicStopSendingFrame* frame)
- : type(STOP_SENDING_FRAME), stop_sending_frame(frame) {}
-
-QuicFrame::QuicFrame(QuicMessageFrame* frame)
- : type(MESSAGE_FRAME), message_frame(frame) {}
-
-QuicFrame::QuicFrame(QuicNewTokenFrame* frame)
- : type(NEW_TOKEN_FRAME), new_token_frame(frame) {}
-
-QuicFrame::QuicFrame(QuicAckFrequencyFrame* frame)
- : type(ACK_FREQUENCY_FRAME), ack_frequency_frame(frame) {}
-
-void DeleteFrames(QuicFrames* frames) {
- for (QuicFrame& frame : *frames) {
- DeleteFrame(&frame);
- }
- frames->clear();
-}
-
-void DeleteFrame(QuicFrame* frame) {
-#if QUIC_FRAME_DEBUG
- // If the frame is not inlined, check that it can be safely deleted.
- if (frame->type != PADDING_FRAME && frame->type != MTU_DISCOVERY_FRAME &&
- frame->type != PING_FRAME && frame->type != MAX_STREAMS_FRAME &&
- frame->type != STOP_WAITING_FRAME &&
- frame->type != STREAMS_BLOCKED_FRAME && frame->type != STREAM_FRAME &&
- frame->type != HANDSHAKE_DONE_FRAME) {
- QUICHE_CHECK(!frame->delete_forbidden) << *frame;
- }
-#endif // QUIC_FRAME_DEBUG
- switch (frame->type) {
- // Frames smaller than a pointer are inlined, so don't need to be deleted.
- case PADDING_FRAME:
- case MTU_DISCOVERY_FRAME:
- case PING_FRAME:
- case MAX_STREAMS_FRAME:
- case STOP_WAITING_FRAME:
- case STREAMS_BLOCKED_FRAME:
- case STREAM_FRAME:
- case HANDSHAKE_DONE_FRAME:
- break;
- case ACK_FRAME:
- delete frame->ack_frame;
- break;
- case RST_STREAM_FRAME:
- delete frame->rst_stream_frame;
- break;
- case CONNECTION_CLOSE_FRAME:
- delete frame->connection_close_frame;
- break;
- case GOAWAY_FRAME:
- delete frame->goaway_frame;
- break;
- case BLOCKED_FRAME:
- delete frame->blocked_frame;
- break;
- case WINDOW_UPDATE_FRAME:
- delete frame->window_update_frame;
- break;
- case PATH_CHALLENGE_FRAME:
- delete frame->path_challenge_frame;
- break;
- case STOP_SENDING_FRAME:
- delete frame->stop_sending_frame;
- break;
- case NEW_CONNECTION_ID_FRAME:
- delete frame->new_connection_id_frame;
- break;
- case RETIRE_CONNECTION_ID_FRAME:
- delete frame->retire_connection_id_frame;
- break;
- case PATH_RESPONSE_FRAME:
- delete frame->path_response_frame;
- break;
- case MESSAGE_FRAME:
- delete frame->message_frame;
- break;
- case CRYPTO_FRAME:
- delete frame->crypto_frame;
- break;
- case NEW_TOKEN_FRAME:
- delete frame->new_token_frame;
- break;
- case ACK_FREQUENCY_FRAME:
- delete frame->ack_frequency_frame;
- break;
- case NUM_FRAME_TYPES:
- QUICHE_DCHECK(false) << "Cannot delete type: " << frame->type;
- }
-}
-
-void RemoveFramesForStream(QuicFrames* frames, QuicStreamId stream_id) {
- auto it = frames->begin();
- while (it != frames->end()) {
- if (it->type != STREAM_FRAME || it->stream_frame.stream_id != stream_id) {
- ++it;
- continue;
- }
- it = frames->erase(it);
- }
-}
-
-bool IsControlFrame(QuicFrameType type) {
- switch (type) {
- case RST_STREAM_FRAME:
- case GOAWAY_FRAME:
- case WINDOW_UPDATE_FRAME:
- case BLOCKED_FRAME:
- case STREAMS_BLOCKED_FRAME:
- case MAX_STREAMS_FRAME:
- case PING_FRAME:
- case STOP_SENDING_FRAME:
- case NEW_CONNECTION_ID_FRAME:
- case RETIRE_CONNECTION_ID_FRAME:
- case HANDSHAKE_DONE_FRAME:
- case ACK_FREQUENCY_FRAME:
- case NEW_TOKEN_FRAME:
- return true;
- default:
- return false;
- }
-}
-
-QuicControlFrameId GetControlFrameId(const QuicFrame& frame) {
- switch (frame.type) {
- case RST_STREAM_FRAME:
- return frame.rst_stream_frame->control_frame_id;
- case GOAWAY_FRAME:
- return frame.goaway_frame->control_frame_id;
- case WINDOW_UPDATE_FRAME:
- return frame.window_update_frame->control_frame_id;
- case BLOCKED_FRAME:
- return frame.blocked_frame->control_frame_id;
- case STREAMS_BLOCKED_FRAME:
- return frame.streams_blocked_frame.control_frame_id;
- case MAX_STREAMS_FRAME:
- return frame.max_streams_frame.control_frame_id;
- case PING_FRAME:
- return frame.ping_frame.control_frame_id;
- case STOP_SENDING_FRAME:
- return frame.stop_sending_frame->control_frame_id;
- case NEW_CONNECTION_ID_FRAME:
- return frame.new_connection_id_frame->control_frame_id;
- case RETIRE_CONNECTION_ID_FRAME:
- return frame.retire_connection_id_frame->control_frame_id;
- case HANDSHAKE_DONE_FRAME:
- return frame.handshake_done_frame.control_frame_id;
- case ACK_FREQUENCY_FRAME:
- return frame.ack_frequency_frame->control_frame_id;
- case NEW_TOKEN_FRAME:
- return frame.new_token_frame->control_frame_id;
- default:
- return kInvalidControlFrameId;
- }
-}
-
-void SetControlFrameId(QuicControlFrameId control_frame_id, QuicFrame* frame) {
- switch (frame->type) {
- case RST_STREAM_FRAME:
- frame->rst_stream_frame->control_frame_id = control_frame_id;
- return;
- case GOAWAY_FRAME:
- frame->goaway_frame->control_frame_id = control_frame_id;
- return;
- case WINDOW_UPDATE_FRAME:
- frame->window_update_frame->control_frame_id = control_frame_id;
- return;
- case BLOCKED_FRAME:
- frame->blocked_frame->control_frame_id = control_frame_id;
- return;
- case PING_FRAME:
- frame->ping_frame.control_frame_id = control_frame_id;
- return;
- case STREAMS_BLOCKED_FRAME:
- frame->streams_blocked_frame.control_frame_id = control_frame_id;
- return;
- case MAX_STREAMS_FRAME:
- frame->max_streams_frame.control_frame_id = control_frame_id;
- return;
- case STOP_SENDING_FRAME:
- frame->stop_sending_frame->control_frame_id = control_frame_id;
- return;
- case NEW_CONNECTION_ID_FRAME:
- frame->new_connection_id_frame->control_frame_id = control_frame_id;
- return;
- case RETIRE_CONNECTION_ID_FRAME:
- frame->retire_connection_id_frame->control_frame_id = control_frame_id;
- return;
- case HANDSHAKE_DONE_FRAME:
- frame->handshake_done_frame.control_frame_id = control_frame_id;
- return;
- case ACK_FREQUENCY_FRAME:
- frame->ack_frequency_frame->control_frame_id = control_frame_id;
- return;
- case NEW_TOKEN_FRAME:
- frame->new_token_frame->control_frame_id = control_frame_id;
- return;
- default:
- QUIC_BUG(quic_bug_12594_1)
- << "Try to set control frame id of a frame without control frame id";
- }
-}
-
-QuicFrame CopyRetransmittableControlFrame(const QuicFrame& frame) {
- QuicFrame copy;
- switch (frame.type) {
- case RST_STREAM_FRAME:
- copy = QuicFrame(new QuicRstStreamFrame(*frame.rst_stream_frame));
- break;
- case GOAWAY_FRAME:
- copy = QuicFrame(new QuicGoAwayFrame(*frame.goaway_frame));
- break;
- case WINDOW_UPDATE_FRAME:
- copy = QuicFrame(new QuicWindowUpdateFrame(*frame.window_update_frame));
- break;
- case BLOCKED_FRAME:
- copy = QuicFrame(new QuicBlockedFrame(*frame.blocked_frame));
- break;
- case PING_FRAME:
- copy = QuicFrame(QuicPingFrame(frame.ping_frame.control_frame_id));
- break;
- case STOP_SENDING_FRAME:
- copy = QuicFrame(new QuicStopSendingFrame(*frame.stop_sending_frame));
- break;
- case NEW_CONNECTION_ID_FRAME:
- copy = QuicFrame(
- new QuicNewConnectionIdFrame(*frame.new_connection_id_frame));
- break;
- case RETIRE_CONNECTION_ID_FRAME:
- copy = QuicFrame(
- new QuicRetireConnectionIdFrame(*frame.retire_connection_id_frame));
- break;
- case STREAMS_BLOCKED_FRAME:
- copy = QuicFrame(QuicStreamsBlockedFrame(frame.streams_blocked_frame));
- break;
- case MAX_STREAMS_FRAME:
- copy = QuicFrame(QuicMaxStreamsFrame(frame.max_streams_frame));
- break;
- case HANDSHAKE_DONE_FRAME:
- copy = QuicFrame(
- QuicHandshakeDoneFrame(frame.handshake_done_frame.control_frame_id));
- break;
- case ACK_FREQUENCY_FRAME:
- copy = QuicFrame(new QuicAckFrequencyFrame(*frame.ack_frequency_frame));
- break;
- case NEW_TOKEN_FRAME:
- copy = QuicFrame(new QuicNewTokenFrame(*frame.new_token_frame));
- break;
- default:
- QUIC_BUG(quic_bug_10533_1)
- << "Try to copy a non-retransmittable control frame: " << frame;
- copy = QuicFrame(QuicPingFrame(kInvalidControlFrameId));
- break;
- }
- return copy;
-}
-
-QuicFrame CopyQuicFrame(QuicBufferAllocator* allocator,
- const QuicFrame& frame) {
- QuicFrame copy;
- switch (frame.type) {
- case PADDING_FRAME:
- copy = QuicFrame(QuicPaddingFrame(frame.padding_frame));
- break;
- case RST_STREAM_FRAME:
- copy = QuicFrame(new QuicRstStreamFrame(*frame.rst_stream_frame));
- break;
- case CONNECTION_CLOSE_FRAME:
- copy = QuicFrame(
- new QuicConnectionCloseFrame(*frame.connection_close_frame));
- break;
- case GOAWAY_FRAME:
- copy = QuicFrame(new QuicGoAwayFrame(*frame.goaway_frame));
- break;
- case WINDOW_UPDATE_FRAME:
- copy = QuicFrame(new QuicWindowUpdateFrame(*frame.window_update_frame));
- break;
- case BLOCKED_FRAME:
- copy = QuicFrame(new QuicBlockedFrame(*frame.blocked_frame));
- break;
- case STOP_WAITING_FRAME:
- copy = QuicFrame(QuicStopWaitingFrame(frame.stop_waiting_frame));
- break;
- case PING_FRAME:
- copy = QuicFrame(QuicPingFrame(frame.ping_frame.control_frame_id));
- break;
- case CRYPTO_FRAME:
- copy = QuicFrame(new QuicCryptoFrame(*frame.crypto_frame));
- break;
- case STREAM_FRAME:
- copy = QuicFrame(QuicStreamFrame(frame.stream_frame));
- break;
- case ACK_FRAME:
- copy = QuicFrame(new QuicAckFrame(*frame.ack_frame));
- break;
- case MTU_DISCOVERY_FRAME:
- copy = QuicFrame(QuicMtuDiscoveryFrame(frame.mtu_discovery_frame));
- break;
- case NEW_CONNECTION_ID_FRAME:
- copy = QuicFrame(
- new QuicNewConnectionIdFrame(*frame.new_connection_id_frame));
- break;
- case MAX_STREAMS_FRAME:
- copy = QuicFrame(QuicMaxStreamsFrame(frame.max_streams_frame));
- break;
- case STREAMS_BLOCKED_FRAME:
- copy = QuicFrame(QuicStreamsBlockedFrame(frame.streams_blocked_frame));
- break;
- case PATH_RESPONSE_FRAME:
- copy = QuicFrame(new QuicPathResponseFrame(*frame.path_response_frame));
- break;
- case PATH_CHALLENGE_FRAME:
- copy = QuicFrame(new QuicPathChallengeFrame(*frame.path_challenge_frame));
- break;
- case STOP_SENDING_FRAME:
- copy = QuicFrame(new QuicStopSendingFrame(*frame.stop_sending_frame));
- break;
- case MESSAGE_FRAME:
- copy = QuicFrame(new QuicMessageFrame(frame.message_frame->message_id));
- copy.message_frame->data = frame.message_frame->data;
- copy.message_frame->message_length = frame.message_frame->message_length;
- for (const auto& slice : frame.message_frame->message_data) {
- QuicBuffer buffer = QuicBuffer::Copy(allocator, slice.AsStringView());
- copy.message_frame->message_data.push_back(
- QuicMemSlice(std::move(buffer)));
- }
- break;
- case NEW_TOKEN_FRAME:
- copy = QuicFrame(new QuicNewTokenFrame(*frame.new_token_frame));
- break;
- case RETIRE_CONNECTION_ID_FRAME:
- copy = QuicFrame(
- new QuicRetireConnectionIdFrame(*frame.retire_connection_id_frame));
- break;
- case HANDSHAKE_DONE_FRAME:
- copy = QuicFrame(
- QuicHandshakeDoneFrame(frame.handshake_done_frame.control_frame_id));
- break;
- case ACK_FREQUENCY_FRAME:
- copy = QuicFrame(new QuicAckFrequencyFrame(*frame.ack_frequency_frame));
- break;
- default:
- QUIC_BUG(quic_bug_10533_2) << "Cannot copy frame: " << frame;
- copy = QuicFrame(QuicPingFrame(kInvalidControlFrameId));
- break;
- }
- return copy;
-}
-
-QuicFrames CopyQuicFrames(QuicBufferAllocator* allocator,
- const QuicFrames& frames) {
- QuicFrames copy;
- for (const auto& frame : frames) {
- copy.push_back(CopyQuicFrame(allocator, frame));
- }
- return copy;
-}
-
-std::ostream& operator<<(std::ostream& os, const QuicFrame& frame) {
- switch (frame.type) {
- case PADDING_FRAME: {
- os << "type { PADDING_FRAME } " << frame.padding_frame;
- break;
- }
- case RST_STREAM_FRAME: {
- os << "type { RST_STREAM_FRAME } " << *(frame.rst_stream_frame);
- break;
- }
- case CONNECTION_CLOSE_FRAME: {
- os << "type { CONNECTION_CLOSE_FRAME } "
- << *(frame.connection_close_frame);
- break;
- }
- case GOAWAY_FRAME: {
- os << "type { GOAWAY_FRAME } " << *(frame.goaway_frame);
- break;
- }
- case WINDOW_UPDATE_FRAME: {
- os << "type { WINDOW_UPDATE_FRAME } " << *(frame.window_update_frame);
- break;
- }
- case BLOCKED_FRAME: {
- os << "type { BLOCKED_FRAME } " << *(frame.blocked_frame);
- break;
- }
- case STREAM_FRAME: {
- os << "type { STREAM_FRAME } " << frame.stream_frame;
- break;
- }
- case ACK_FRAME: {
- os << "type { ACK_FRAME } " << *(frame.ack_frame);
- break;
- }
- case STOP_WAITING_FRAME: {
- os << "type { STOP_WAITING_FRAME } " << frame.stop_waiting_frame;
- break;
- }
- case PING_FRAME: {
- os << "type { PING_FRAME } " << frame.ping_frame;
- break;
- }
- case CRYPTO_FRAME: {
- os << "type { CRYPTO_FRAME } " << *(frame.crypto_frame);
- break;
- }
- case MTU_DISCOVERY_FRAME: {
- os << "type { MTU_DISCOVERY_FRAME } ";
- break;
- }
- case NEW_CONNECTION_ID_FRAME:
- os << "type { NEW_CONNECTION_ID } " << *(frame.new_connection_id_frame);
- break;
- case RETIRE_CONNECTION_ID_FRAME:
- os << "type { RETIRE_CONNECTION_ID } "
- << *(frame.retire_connection_id_frame);
- break;
- case MAX_STREAMS_FRAME:
- os << "type { MAX_STREAMS } " << frame.max_streams_frame;
- break;
- case STREAMS_BLOCKED_FRAME:
- os << "type { STREAMS_BLOCKED } " << frame.streams_blocked_frame;
- break;
- case PATH_RESPONSE_FRAME:
- os << "type { PATH_RESPONSE } " << *(frame.path_response_frame);
- break;
- case PATH_CHALLENGE_FRAME:
- os << "type { PATH_CHALLENGE } " << *(frame.path_challenge_frame);
- break;
- case STOP_SENDING_FRAME:
- os << "type { STOP_SENDING } " << *(frame.stop_sending_frame);
- break;
- case MESSAGE_FRAME:
- os << "type { MESSAGE_FRAME }" << *(frame.message_frame);
- break;
- case NEW_TOKEN_FRAME:
- os << "type { NEW_TOKEN_FRAME }" << *(frame.new_token_frame);
- break;
- case HANDSHAKE_DONE_FRAME:
- os << "type { HANDSHAKE_DONE_FRAME } " << frame.handshake_done_frame;
- break;
- case ACK_FREQUENCY_FRAME:
- os << "type { ACK_FREQUENCY_FRAME } " << *(frame.ack_frequency_frame);
- break;
- default: {
- QUIC_LOG(ERROR) << "Unknown frame type: " << frame.type;
- break;
- }
- }
- return os;
-}
-
-std::string QuicFramesToString(const QuicFrames& frames) {
- std::ostringstream os;
- for (const QuicFrame& frame : frames) {
- os << frame;
- }
- return os.str();
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/frames/quic_frame.h b/chromium/net/third_party/quiche/src/quic/core/frames/quic_frame.h
deleted file mode 100644
index 9ee45689117..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/frames/quic_frame.h
+++ /dev/null
@@ -1,178 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_FRAMES_QUIC_FRAME_H_
-#define QUICHE_QUIC_CORE_FRAMES_QUIC_FRAME_H_
-
-#include <ostream>
-#include <type_traits>
-#include <vector>
-
-#include "absl/container/inlined_vector.h"
-#include "quic/core/frames/quic_ack_frame.h"
-#include "quic/core/frames/quic_ack_frequency_frame.h"
-#include "quic/core/frames/quic_blocked_frame.h"
-#include "quic/core/frames/quic_connection_close_frame.h"
-#include "quic/core/frames/quic_crypto_frame.h"
-#include "quic/core/frames/quic_goaway_frame.h"
-#include "quic/core/frames/quic_handshake_done_frame.h"
-#include "quic/core/frames/quic_max_streams_frame.h"
-#include "quic/core/frames/quic_message_frame.h"
-#include "quic/core/frames/quic_mtu_discovery_frame.h"
-#include "quic/core/frames/quic_new_connection_id_frame.h"
-#include "quic/core/frames/quic_new_token_frame.h"
-#include "quic/core/frames/quic_padding_frame.h"
-#include "quic/core/frames/quic_path_challenge_frame.h"
-#include "quic/core/frames/quic_path_response_frame.h"
-#include "quic/core/frames/quic_ping_frame.h"
-#include "quic/core/frames/quic_retire_connection_id_frame.h"
-#include "quic/core/frames/quic_rst_stream_frame.h"
-#include "quic/core/frames/quic_stop_sending_frame.h"
-#include "quic/core/frames/quic_stop_waiting_frame.h"
-#include "quic/core/frames/quic_stream_frame.h"
-#include "quic/core/frames/quic_streams_blocked_frame.h"
-#include "quic/core/frames/quic_window_update_frame.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_containers.h"
-#include "quic/platform/api/quic_export.h"
-
-#ifndef QUIC_FRAME_DEBUG
-#if !defined(NDEBUG) || defined(ADDRESS_SANITIZER)
-#define QUIC_FRAME_DEBUG 1
-#else // !defined(NDEBUG) || defined(ADDRESS_SANITIZER)
-#define QUIC_FRAME_DEBUG 0
-#endif // !defined(NDEBUG) || defined(ADDRESS_SANITIZER)
-#endif // QUIC_FRAME_DEBUG
-
-namespace quic {
-
-struct QUIC_EXPORT_PRIVATE QuicFrame {
- QuicFrame();
- // Please keep the constructors in the same order as the union below.
- explicit QuicFrame(QuicPaddingFrame padding_frame);
- explicit QuicFrame(QuicMtuDiscoveryFrame frame);
- explicit QuicFrame(QuicPingFrame frame);
- explicit QuicFrame(QuicMaxStreamsFrame frame);
- explicit QuicFrame(QuicStopWaitingFrame frame);
- explicit QuicFrame(QuicStreamsBlockedFrame frame);
- explicit QuicFrame(QuicStreamFrame stream_frame);
- explicit QuicFrame(QuicHandshakeDoneFrame handshake_done_frame);
-
- explicit QuicFrame(QuicAckFrame* frame);
- explicit QuicFrame(QuicRstStreamFrame* frame);
- explicit QuicFrame(QuicConnectionCloseFrame* frame);
- explicit QuicFrame(QuicGoAwayFrame* frame);
- explicit QuicFrame(QuicWindowUpdateFrame* frame);
- explicit QuicFrame(QuicBlockedFrame* frame);
- explicit QuicFrame(QuicNewConnectionIdFrame* frame);
- explicit QuicFrame(QuicRetireConnectionIdFrame* frame);
- explicit QuicFrame(QuicNewTokenFrame* frame);
- explicit QuicFrame(QuicPathResponseFrame* frame);
- explicit QuicFrame(QuicPathChallengeFrame* frame);
- explicit QuicFrame(QuicStopSendingFrame* frame);
- explicit QuicFrame(QuicMessageFrame* message_frame);
- explicit QuicFrame(QuicCryptoFrame* crypto_frame);
- explicit QuicFrame(QuicAckFrequencyFrame* ack_frequency_frame);
-
- QUIC_EXPORT_PRIVATE friend std::ostream& operator<<(std::ostream& os,
- const QuicFrame& frame);
-
- union {
- // Inlined frames.
- // Overlapping inlined frames have a |type| field at the same 0 offset as
- // QuicFrame does for out of line frames below, allowing use of the
- // remaining 7 bytes after offset for frame-type specific fields.
- QuicPaddingFrame padding_frame;
- QuicMtuDiscoveryFrame mtu_discovery_frame;
- QuicPingFrame ping_frame;
- QuicMaxStreamsFrame max_streams_frame;
- QuicStopWaitingFrame stop_waiting_frame;
- QuicStreamsBlockedFrame streams_blocked_frame;
- QuicStreamFrame stream_frame;
- QuicHandshakeDoneFrame handshake_done_frame;
-
- // Out of line frames.
- struct {
- QuicFrameType type;
-
-#if QUIC_FRAME_DEBUG
- bool delete_forbidden = false;
-#endif // QUIC_FRAME_DEBUG
-
- // TODO(wub): These frames can also be inlined without increasing the size
- // of QuicFrame: QuicRstStreamFrame, QuicWindowUpdateFrame,
- // QuicBlockedFrame, QuicPathResponseFrame, QuicPathChallengeFrame and
- // QuicStopSendingFrame.
- union {
- QuicAckFrame* ack_frame;
- QuicRstStreamFrame* rst_stream_frame;
- QuicConnectionCloseFrame* connection_close_frame;
- QuicGoAwayFrame* goaway_frame;
- QuicWindowUpdateFrame* window_update_frame;
- QuicBlockedFrame* blocked_frame;
- QuicNewConnectionIdFrame* new_connection_id_frame;
- QuicRetireConnectionIdFrame* retire_connection_id_frame;
- QuicPathResponseFrame* path_response_frame;
- QuicPathChallengeFrame* path_challenge_frame;
- QuicStopSendingFrame* stop_sending_frame;
- QuicMessageFrame* message_frame;
- QuicCryptoFrame* crypto_frame;
- QuicAckFrequencyFrame* ack_frequency_frame;
- QuicNewTokenFrame* new_token_frame;
- };
- };
- };
-};
-
-static_assert(std::is_standard_layout<QuicFrame>::value,
- "QuicFrame must have a standard layout");
-static_assert(sizeof(QuicFrame) <= 24,
- "Frames larger than 24 bytes should be referenced by pointer.");
-static_assert(offsetof(QuicStreamFrame, type) == offsetof(QuicFrame, type),
- "Offset of |type| must match in QuicFrame and QuicStreamFrame");
-
-// A inline size of 1 is chosen to optimize the typical use case of
-// 1-stream-frame in QuicTransmissionInfo.retransmittable_frames.
-using QuicFrames = absl::InlinedVector<QuicFrame, 1>;
-
-// Deletes all the sub-frames contained in |frames|.
-QUIC_EXPORT_PRIVATE void DeleteFrames(QuicFrames* frames);
-
-// Delete the sub-frame contained in |frame|.
-QUIC_EXPORT_PRIVATE void DeleteFrame(QuicFrame* frame);
-
-// Deletes all the QuicStreamFrames for the specified |stream_id|.
-QUIC_EXPORT_PRIVATE void RemoveFramesForStream(QuicFrames* frames,
- QuicStreamId stream_id);
-
-// Returns true if |type| is a retransmittable control frame.
-QUIC_EXPORT_PRIVATE bool IsControlFrame(QuicFrameType type);
-
-// Returns control_frame_id of |frame|. Returns kInvalidControlFrameId if
-// |frame| does not have a valid control_frame_id.
-QUIC_EXPORT_PRIVATE QuicControlFrameId
-GetControlFrameId(const QuicFrame& frame);
-
-// Sets control_frame_id of |frame| to |control_frame_id|.
-QUIC_EXPORT_PRIVATE void SetControlFrameId(QuicControlFrameId control_frame_id,
- QuicFrame* frame);
-
-// Returns a copy of |frame|.
-QUIC_EXPORT_PRIVATE QuicFrame
-CopyRetransmittableControlFrame(const QuicFrame& frame);
-
-// Returns a copy of |frame|.
-QUIC_EXPORT_PRIVATE QuicFrame CopyQuicFrame(QuicBufferAllocator* allocator,
- const QuicFrame& frame);
-
-// Returns a copy of |frames|.
-QUIC_EXPORT_PRIVATE QuicFrames CopyQuicFrames(QuicBufferAllocator* allocator,
- const QuicFrames& frames);
-
-// Human-readable description suitable for logging.
-QUIC_EXPORT_PRIVATE std::string QuicFramesToString(const QuicFrames& frames);
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_FRAMES_QUIC_FRAME_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/frames/quic_frames_test.cc b/chromium/net/third_party/quiche/src/quic/core/frames/quic_frames_test.cc
deleted file mode 100644
index 43eabf7ef79..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/frames/quic_frames_test.cc
+++ /dev/null
@@ -1,834 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/frames/quic_ack_frame.h"
-#include "quic/core/frames/quic_blocked_frame.h"
-#include "quic/core/frames/quic_connection_close_frame.h"
-#include "quic/core/frames/quic_frame.h"
-#include "quic/core/frames/quic_goaway_frame.h"
-#include "quic/core/frames/quic_mtu_discovery_frame.h"
-#include "quic/core/frames/quic_new_connection_id_frame.h"
-#include "quic/core/frames/quic_padding_frame.h"
-#include "quic/core/frames/quic_ping_frame.h"
-#include "quic/core/frames/quic_rst_stream_frame.h"
-#include "quic/core/frames/quic_stop_waiting_frame.h"
-#include "quic/core/frames/quic_stream_frame.h"
-#include "quic/core/frames/quic_window_update_frame.h"
-#include "quic/core/quic_interval.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_expect_bug.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/quic_test_utils.h"
-
-namespace quic {
-namespace test {
-namespace {
-
-class QuicFramesTest : public QuicTest {};
-
-TEST_F(QuicFramesTest, AckFrameToString) {
- QuicAckFrame frame;
- frame.largest_acked = QuicPacketNumber(5);
- frame.ack_delay_time = QuicTime::Delta::FromMicroseconds(3);
- frame.packets.Add(QuicPacketNumber(4));
- frame.packets.Add(QuicPacketNumber(5));
- frame.received_packet_times = {
- {QuicPacketNumber(6),
- QuicTime::Zero() + QuicTime::Delta::FromMicroseconds(7)}};
- std::ostringstream stream;
- stream << frame;
- EXPECT_EQ(
- "{ largest_acked: 5, ack_delay_time: 3, packets: [ 4 5 ], "
- "received_packets: [ 6 at 7 ], ecn_counters_populated: 0 }\n",
- stream.str());
- QuicFrame quic_frame(&frame);
- EXPECT_FALSE(IsControlFrame(quic_frame.type));
-}
-
-TEST_F(QuicFramesTest, BigAckFrameToString) {
- QuicAckFrame frame;
- frame.largest_acked = QuicPacketNumber(500);
- frame.ack_delay_time = QuicTime::Delta::FromMicroseconds(3);
- frame.packets.AddRange(QuicPacketNumber(4), QuicPacketNumber(501));
- frame.received_packet_times = {
- {QuicPacketNumber(500),
- QuicTime::Zero() + QuicTime::Delta::FromMicroseconds(7)}};
- std::ostringstream stream;
- stream << frame;
- EXPECT_EQ(
- "{ largest_acked: 500, ack_delay_time: 3, packets: [ 4...500 ], "
- "received_packets: [ 500 at 7 ], ecn_counters_populated: 0 }\n",
- stream.str());
- QuicFrame quic_frame(&frame);
- EXPECT_FALSE(IsControlFrame(quic_frame.type));
-}
-
-TEST_F(QuicFramesTest, PaddingFrameToString) {
- QuicPaddingFrame frame;
- frame.num_padding_bytes = 1;
- std::ostringstream stream;
- stream << frame;
- EXPECT_EQ("{ num_padding_bytes: 1 }\n", stream.str());
- QuicFrame quic_frame(frame);
- EXPECT_FALSE(IsControlFrame(quic_frame.type));
-}
-
-TEST_F(QuicFramesTest, RstStreamFrameToString) {
- QuicRstStreamFrame rst_stream;
- QuicFrame frame(&rst_stream);
- SetControlFrameId(1, &frame);
- EXPECT_EQ(1u, GetControlFrameId(frame));
- rst_stream.stream_id = 1;
- rst_stream.byte_offset = 3;
- rst_stream.error_code = QUIC_STREAM_CANCELLED;
- std::ostringstream stream;
- stream << rst_stream;
- EXPECT_EQ(
- "{ control_frame_id: 1, stream_id: 1, byte_offset: 3, error_code: 6, "
- "ietf_error_code: 0 }\n",
- stream.str());
- EXPECT_TRUE(IsControlFrame(frame.type));
-}
-
-TEST_F(QuicFramesTest, StopSendingFrameToString) {
- QuicStopSendingFrame stop_sending;
- QuicFrame frame(&stop_sending);
- SetControlFrameId(1, &frame);
- EXPECT_EQ(1u, GetControlFrameId(frame));
- stop_sending.stream_id = 321;
- stop_sending.error_code = QUIC_STREAM_CANCELLED;
- stop_sending.ietf_error_code =
- static_cast<uint64_t>(QuicHttp3ErrorCode::REQUEST_CANCELLED);
- std::ostringstream stream;
- stream << stop_sending;
- EXPECT_EQ(
- "{ control_frame_id: 1, stream_id: 321, error_code: 6, ietf_error_code: "
- "268 }\n",
- stream.str());
-}
-
-TEST_F(QuicFramesTest, NewConnectionIdFrameToString) {
- QuicNewConnectionIdFrame new_connection_id_frame;
- QuicFrame frame(&new_connection_id_frame);
- SetControlFrameId(1, &frame);
- QuicFrame frame_copy = CopyRetransmittableControlFrame(frame);
- EXPECT_EQ(1u, GetControlFrameId(frame_copy));
- new_connection_id_frame.connection_id = TestConnectionId(2);
- new_connection_id_frame.sequence_number = 2u;
- new_connection_id_frame.retire_prior_to = 1u;
- new_connection_id_frame.stateless_reset_token =
- StatelessResetToken{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1};
- std::ostringstream stream;
- stream << new_connection_id_frame;
- EXPECT_EQ(
- "{ control_frame_id: 1, connection_id: 0000000000000002, "
- "sequence_number: 2, retire_prior_to: 1 }\n",
- stream.str());
- EXPECT_TRUE(IsControlFrame(frame_copy.type));
- DeleteFrame(&frame_copy);
-}
-
-TEST_F(QuicFramesTest, RetireConnectionIdFrameToString) {
- QuicRetireConnectionIdFrame retire_connection_id_frame;
- QuicFrame frame(&retire_connection_id_frame);
- SetControlFrameId(1, &frame);
- QuicFrame frame_copy = CopyRetransmittableControlFrame(frame);
- EXPECT_EQ(1u, GetControlFrameId(frame_copy));
- retire_connection_id_frame.sequence_number = 1u;
- std::ostringstream stream;
- stream << retire_connection_id_frame;
- EXPECT_EQ("{ control_frame_id: 1, sequence_number: 1 }\n", stream.str());
- EXPECT_TRUE(IsControlFrame(frame_copy.type));
- DeleteFrame(&frame_copy);
-}
-
-TEST_F(QuicFramesTest, StreamsBlockedFrameToString) {
- QuicStreamsBlockedFrame streams_blocked;
- QuicFrame frame(streams_blocked);
- SetControlFrameId(1, &frame);
- EXPECT_EQ(1u, GetControlFrameId(frame));
- // QuicStreamsBlocked is copied into a QuicFrame (as opposed to putting a
- // pointer to it into QuicFrame) so need to work with the copy in |frame| and
- // not the original one, streams_blocked.
- frame.streams_blocked_frame.stream_count = 321;
- frame.streams_blocked_frame.unidirectional = false;
- std::ostringstream stream;
- stream << frame.streams_blocked_frame;
- EXPECT_EQ("{ control_frame_id: 1, stream count: 321, bidirectional }\n",
- stream.str());
- EXPECT_TRUE(IsControlFrame(frame.type));
-}
-
-TEST_F(QuicFramesTest, MaxStreamsFrameToString) {
- QuicMaxStreamsFrame max_streams;
- QuicFrame frame(max_streams);
- SetControlFrameId(1, &frame);
- EXPECT_EQ(1u, GetControlFrameId(frame));
- // QuicMaxStreams is copied into a QuicFrame (as opposed to putting a
- // pointer to it into QuicFrame) so need to work with the copy in |frame| and
- // not the original one, max_streams.
- frame.max_streams_frame.stream_count = 321;
- frame.max_streams_frame.unidirectional = true;
- std::ostringstream stream;
- stream << frame.max_streams_frame;
- EXPECT_EQ("{ control_frame_id: 1, stream_count: 321, unidirectional }\n",
- stream.str());
- EXPECT_TRUE(IsControlFrame(frame.type));
-}
-
-TEST_F(QuicFramesTest, ConnectionCloseFrameToString) {
- QuicConnectionCloseFrame frame;
- frame.quic_error_code = QUIC_NETWORK_IDLE_TIMEOUT;
- frame.error_details = "No recent network activity.";
- std::ostringstream stream;
- stream << frame;
- // Note that "extracted_error_code: 122" is QUIC_IETF_GQUIC_ERROR_MISSING,
- // indicating that, in fact, no extended error code was available from the
- // underlying frame.
- EXPECT_EQ(
- "{ Close type: GOOGLE_QUIC_CONNECTION_CLOSE, "
- "quic_error_code: QUIC_NETWORK_IDLE_TIMEOUT, "
- "error_details: 'No recent network activity.'}\n",
- stream.str());
- QuicFrame quic_frame(&frame);
- EXPECT_FALSE(IsControlFrame(quic_frame.type));
-}
-
-TEST_F(QuicFramesTest, TransportConnectionCloseFrameToString) {
- QuicConnectionCloseFrame frame;
- frame.close_type = IETF_QUIC_TRANSPORT_CONNECTION_CLOSE;
- frame.wire_error_code = FINAL_SIZE_ERROR;
- frame.quic_error_code = QUIC_NETWORK_IDLE_TIMEOUT;
- frame.error_details = "No recent network activity.";
- frame.transport_close_frame_type = IETF_STREAM;
- std::ostringstream stream;
- stream << frame;
- EXPECT_EQ(
- "{ Close type: IETF_QUIC_TRANSPORT_CONNECTION_CLOSE, "
- "wire_error_code: FINAL_SIZE_ERROR, "
- "quic_error_code: QUIC_NETWORK_IDLE_TIMEOUT, "
- "error_details: 'No recent "
- "network activity.', "
- "frame_type: IETF_STREAM"
- "}\n",
- stream.str());
- QuicFrame quic_frame(&frame);
- EXPECT_FALSE(IsControlFrame(quic_frame.type));
-}
-
-TEST_F(QuicFramesTest, GoAwayFrameToString) {
- QuicGoAwayFrame goaway_frame;
- QuicFrame frame(&goaway_frame);
- SetControlFrameId(2, &frame);
- EXPECT_EQ(2u, GetControlFrameId(frame));
- goaway_frame.error_code = QUIC_NETWORK_IDLE_TIMEOUT;
- goaway_frame.last_good_stream_id = 2;
- goaway_frame.reason_phrase = "Reason";
- std::ostringstream stream;
- stream << goaway_frame;
- EXPECT_EQ(
- "{ control_frame_id: 2, error_code: 25, last_good_stream_id: 2, "
- "reason_phrase: "
- "'Reason' }\n",
- stream.str());
- EXPECT_TRUE(IsControlFrame(frame.type));
-}
-
-TEST_F(QuicFramesTest, WindowUpdateFrameToString) {
- QuicWindowUpdateFrame window_update;
- QuicFrame frame(&window_update);
- SetControlFrameId(3, &frame);
- EXPECT_EQ(3u, GetControlFrameId(frame));
- std::ostringstream stream;
- window_update.stream_id = 1;
- window_update.max_data = 2;
- stream << window_update;
- EXPECT_EQ("{ control_frame_id: 3, stream_id: 1, max_data: 2 }\n",
- stream.str());
- EXPECT_TRUE(IsControlFrame(frame.type));
-}
-
-TEST_F(QuicFramesTest, BlockedFrameToString) {
- QuicBlockedFrame blocked;
- QuicFrame frame(&blocked);
- SetControlFrameId(4, &frame);
- EXPECT_EQ(4u, GetControlFrameId(frame));
- blocked.stream_id = 1;
- std::ostringstream stream;
- stream << blocked;
- EXPECT_EQ("{ control_frame_id: 4, stream_id: 1 }\n", stream.str());
- EXPECT_TRUE(IsControlFrame(frame.type));
-}
-
-TEST_F(QuicFramesTest, PingFrameToString) {
- QuicPingFrame ping;
- QuicFrame frame(ping);
- SetControlFrameId(5, &frame);
- EXPECT_EQ(5u, GetControlFrameId(frame));
- std::ostringstream stream;
- stream << frame.ping_frame;
- EXPECT_EQ("{ control_frame_id: 5 }\n", stream.str());
- EXPECT_TRUE(IsControlFrame(frame.type));
-}
-
-TEST_F(QuicFramesTest, HandshakeDoneFrameToString) {
- QuicHandshakeDoneFrame handshake_done;
- QuicFrame frame(handshake_done);
- SetControlFrameId(6, &frame);
- EXPECT_EQ(6u, GetControlFrameId(frame));
- std::ostringstream stream;
- stream << frame.handshake_done_frame;
- EXPECT_EQ("{ control_frame_id: 6 }\n", stream.str());
- EXPECT_TRUE(IsControlFrame(frame.type));
-}
-
-TEST_F(QuicFramesTest, QuicAckFreuqncyFrameToString) {
- QuicAckFrequencyFrame ack_frequency_frame;
- ack_frequency_frame.sequence_number = 1;
- ack_frequency_frame.packet_tolerance = 2;
- ack_frequency_frame.max_ack_delay = QuicTime::Delta::FromMilliseconds(25);
- ack_frequency_frame.ignore_order = false;
- QuicFrame frame(&ack_frequency_frame);
- ASSERT_EQ(ACK_FREQUENCY_FRAME, frame.type);
- SetControlFrameId(6, &frame);
- EXPECT_EQ(6u, GetControlFrameId(frame));
- std::ostringstream stream;
- stream << *frame.ack_frequency_frame;
- EXPECT_EQ(
- "{ control_frame_id: 6, sequence_number: 1, packet_tolerance: 2, "
- "max_ack_delay_ms: 25, ignore_order: 0 }\n",
- stream.str());
- EXPECT_TRUE(IsControlFrame(frame.type));
-}
-
-TEST_F(QuicFramesTest, StreamFrameToString) {
- QuicStreamFrame frame;
- frame.stream_id = 1;
- frame.fin = false;
- frame.offset = 2;
- frame.data_length = 3;
- std::ostringstream stream;
- stream << frame;
- EXPECT_EQ("{ stream_id: 1, fin: 0, offset: 2, length: 3 }\n", stream.str());
- EXPECT_FALSE(IsControlFrame(frame.type));
-}
-
-TEST_F(QuicFramesTest, StopWaitingFrameToString) {
- QuicStopWaitingFrame frame;
- frame.least_unacked = QuicPacketNumber(2);
- std::ostringstream stream;
- stream << frame;
- EXPECT_EQ("{ least_unacked: 2 }\n", stream.str());
- QuicFrame quic_frame(frame);
- EXPECT_FALSE(IsControlFrame(quic_frame.type));
-}
-
-TEST_F(QuicFramesTest, IsAwaitingPacket) {
- QuicAckFrame ack_frame1;
- ack_frame1.largest_acked = QuicPacketNumber(10u);
- ack_frame1.packets.AddRange(QuicPacketNumber(1), QuicPacketNumber(11));
- EXPECT_TRUE(
- IsAwaitingPacket(ack_frame1, QuicPacketNumber(11u), QuicPacketNumber()));
- EXPECT_FALSE(
- IsAwaitingPacket(ack_frame1, QuicPacketNumber(1u), QuicPacketNumber()));
-
- ack_frame1.packets.Add(QuicPacketNumber(12));
- EXPECT_TRUE(
- IsAwaitingPacket(ack_frame1, QuicPacketNumber(11u), QuicPacketNumber()));
-
- QuicAckFrame ack_frame2;
- ack_frame2.largest_acked = QuicPacketNumber(100u);
- ack_frame2.packets.AddRange(QuicPacketNumber(21), QuicPacketNumber(100));
- EXPECT_FALSE(IsAwaitingPacket(ack_frame2, QuicPacketNumber(11u),
- QuicPacketNumber(20u)));
- EXPECT_FALSE(IsAwaitingPacket(ack_frame2, QuicPacketNumber(80u),
- QuicPacketNumber(20u)));
- EXPECT_TRUE(IsAwaitingPacket(ack_frame2, QuicPacketNumber(101u),
- QuicPacketNumber(20u)));
-
- ack_frame2.packets.AddRange(QuicPacketNumber(102), QuicPacketNumber(200));
- EXPECT_TRUE(IsAwaitingPacket(ack_frame2, QuicPacketNumber(101u),
- QuicPacketNumber(20u)));
-}
-
-TEST_F(QuicFramesTest, AddPacket) {
- QuicAckFrame ack_frame1;
- ack_frame1.packets.Add(QuicPacketNumber(1));
- ack_frame1.packets.Add(QuicPacketNumber(99));
-
- EXPECT_EQ(2u, ack_frame1.packets.NumIntervals());
- EXPECT_EQ(QuicPacketNumber(1u), ack_frame1.packets.Min());
- EXPECT_EQ(QuicPacketNumber(99u), ack_frame1.packets.Max());
-
- std::vector<QuicInterval<QuicPacketNumber>> expected_intervals;
- expected_intervals.emplace_back(
- QuicInterval<QuicPacketNumber>(QuicPacketNumber(1), QuicPacketNumber(2)));
- expected_intervals.emplace_back(QuicInterval<QuicPacketNumber>(
- QuicPacketNumber(99), QuicPacketNumber(100)));
-
- const std::vector<QuicInterval<QuicPacketNumber>> actual_intervals(
- ack_frame1.packets.begin(), ack_frame1.packets.end());
-
- EXPECT_EQ(expected_intervals, actual_intervals);
-
- ack_frame1.packets.Add(QuicPacketNumber(20));
- const std::vector<QuicInterval<QuicPacketNumber>> actual_intervals2(
- ack_frame1.packets.begin(), ack_frame1.packets.end());
-
- std::vector<QuicInterval<QuicPacketNumber>> expected_intervals2;
- expected_intervals2.emplace_back(
- QuicInterval<QuicPacketNumber>(QuicPacketNumber(1), QuicPacketNumber(2)));
- expected_intervals2.emplace_back(QuicInterval<QuicPacketNumber>(
- QuicPacketNumber(20), QuicPacketNumber(21)));
- expected_intervals2.emplace_back(QuicInterval<QuicPacketNumber>(
- QuicPacketNumber(99), QuicPacketNumber(100)));
-
- EXPECT_EQ(3u, ack_frame1.packets.NumIntervals());
- EXPECT_EQ(expected_intervals2, actual_intervals2);
-
- ack_frame1.packets.Add(QuicPacketNumber(19));
- ack_frame1.packets.Add(QuicPacketNumber(21));
-
- const std::vector<QuicInterval<QuicPacketNumber>> actual_intervals3(
- ack_frame1.packets.begin(), ack_frame1.packets.end());
-
- std::vector<QuicInterval<QuicPacketNumber>> expected_intervals3;
- expected_intervals3.emplace_back(
- QuicInterval<QuicPacketNumber>(QuicPacketNumber(1), QuicPacketNumber(2)));
- expected_intervals3.emplace_back(QuicInterval<QuicPacketNumber>(
- QuicPacketNumber(19), QuicPacketNumber(22)));
- expected_intervals3.emplace_back(QuicInterval<QuicPacketNumber>(
- QuicPacketNumber(99), QuicPacketNumber(100)));
-
- EXPECT_EQ(expected_intervals3, actual_intervals3);
-
- ack_frame1.packets.Add(QuicPacketNumber(20));
-
- const std::vector<QuicInterval<QuicPacketNumber>> actual_intervals4(
- ack_frame1.packets.begin(), ack_frame1.packets.end());
-
- EXPECT_EQ(expected_intervals3, actual_intervals4);
-
- QuicAckFrame ack_frame2;
- ack_frame2.packets.Add(QuicPacketNumber(20));
- ack_frame2.packets.Add(QuicPacketNumber(40));
- ack_frame2.packets.Add(QuicPacketNumber(60));
- ack_frame2.packets.Add(QuicPacketNumber(10));
- ack_frame2.packets.Add(QuicPacketNumber(80));
-
- const std::vector<QuicInterval<QuicPacketNumber>> actual_intervals5(
- ack_frame2.packets.begin(), ack_frame2.packets.end());
-
- std::vector<QuicInterval<QuicPacketNumber>> expected_intervals5;
- expected_intervals5.emplace_back(QuicInterval<QuicPacketNumber>(
- QuicPacketNumber(10), QuicPacketNumber(11)));
- expected_intervals5.emplace_back(QuicInterval<QuicPacketNumber>(
- QuicPacketNumber(20), QuicPacketNumber(21)));
- expected_intervals5.emplace_back(QuicInterval<QuicPacketNumber>(
- QuicPacketNumber(40), QuicPacketNumber(41)));
- expected_intervals5.emplace_back(QuicInterval<QuicPacketNumber>(
- QuicPacketNumber(60), QuicPacketNumber(61)));
- expected_intervals5.emplace_back(QuicInterval<QuicPacketNumber>(
- QuicPacketNumber(80), QuicPacketNumber(81)));
-
- EXPECT_EQ(expected_intervals5, actual_intervals5);
-}
-
-TEST_F(QuicFramesTest, AddInterval) {
- QuicAckFrame ack_frame1;
- ack_frame1.packets.AddRange(QuicPacketNumber(1), QuicPacketNumber(10));
- ack_frame1.packets.AddRange(QuicPacketNumber(50), QuicPacketNumber(100));
-
- EXPECT_EQ(2u, ack_frame1.packets.NumIntervals());
- EXPECT_EQ(QuicPacketNumber(1u), ack_frame1.packets.Min());
- EXPECT_EQ(QuicPacketNumber(99u), ack_frame1.packets.Max());
-
- std::vector<QuicInterval<QuicPacketNumber>> expected_intervals{
- {QuicPacketNumber(1), QuicPacketNumber(10)},
- {QuicPacketNumber(50), QuicPacketNumber(100)},
- };
-
- const std::vector<QuicInterval<QuicPacketNumber>> actual_intervals(
- ack_frame1.packets.begin(), ack_frame1.packets.end());
-
- EXPECT_EQ(expected_intervals, actual_intervals);
-
- // Add a range in the middle.
- ack_frame1.packets.AddRange(QuicPacketNumber(20), QuicPacketNumber(30));
-
- const std::vector<QuicInterval<QuicPacketNumber>> actual_intervals2(
- ack_frame1.packets.begin(), ack_frame1.packets.end());
-
- std::vector<QuicInterval<QuicPacketNumber>> expected_intervals2{
- {QuicPacketNumber(1), QuicPacketNumber(10)},
- {QuicPacketNumber(20), QuicPacketNumber(30)},
- {QuicPacketNumber(50), QuicPacketNumber(100)},
- };
-
- EXPECT_EQ(expected_intervals2.size(), ack_frame1.packets.NumIntervals());
- EXPECT_EQ(expected_intervals2, actual_intervals2);
-
- // Add ranges at both ends.
- QuicAckFrame ack_frame2;
- ack_frame2.packets.AddRange(QuicPacketNumber(20), QuicPacketNumber(25));
- ack_frame2.packets.AddRange(QuicPacketNumber(40), QuicPacketNumber(45));
- ack_frame2.packets.AddRange(QuicPacketNumber(60), QuicPacketNumber(65));
- ack_frame2.packets.AddRange(QuicPacketNumber(10), QuicPacketNumber(15));
- ack_frame2.packets.AddRange(QuicPacketNumber(80), QuicPacketNumber(85));
-
- const std::vector<QuicInterval<QuicPacketNumber>> actual_intervals8(
- ack_frame2.packets.begin(), ack_frame2.packets.end());
-
- std::vector<QuicInterval<QuicPacketNumber>> expected_intervals8{
- {QuicPacketNumber(10), QuicPacketNumber(15)},
- {QuicPacketNumber(20), QuicPacketNumber(25)},
- {QuicPacketNumber(40), QuicPacketNumber(45)},
- {QuicPacketNumber(60), QuicPacketNumber(65)},
- {QuicPacketNumber(80), QuicPacketNumber(85)},
- };
-
- EXPECT_EQ(expected_intervals8, actual_intervals8);
-}
-
-TEST_F(QuicFramesTest, AddAdjacentForward) {
- QuicAckFrame ack_frame1;
- ack_frame1.packets.Add(QuicPacketNumber(49));
- ack_frame1.packets.AddRange(QuicPacketNumber(50), QuicPacketNumber(60));
- ack_frame1.packets.AddRange(QuicPacketNumber(60), QuicPacketNumber(70));
- ack_frame1.packets.AddRange(QuicPacketNumber(70), QuicPacketNumber(100));
-
- std::vector<QuicInterval<QuicPacketNumber>> expected_intervals;
- expected_intervals.emplace_back(QuicInterval<QuicPacketNumber>(
- QuicPacketNumber(49), QuicPacketNumber(100)));
-
- const std::vector<QuicInterval<QuicPacketNumber>> actual_intervals(
- ack_frame1.packets.begin(), ack_frame1.packets.end());
-
- EXPECT_EQ(expected_intervals, actual_intervals);
-}
-
-TEST_F(QuicFramesTest, AddAdjacentReverse) {
- QuicAckFrame ack_frame1;
- ack_frame1.packets.AddRange(QuicPacketNumber(70), QuicPacketNumber(100));
- ack_frame1.packets.AddRange(QuicPacketNumber(60), QuicPacketNumber(70));
- ack_frame1.packets.AddRange(QuicPacketNumber(50), QuicPacketNumber(60));
- ack_frame1.packets.Add(QuicPacketNumber(49));
-
- std::vector<QuicInterval<QuicPacketNumber>> expected_intervals;
- expected_intervals.emplace_back(QuicInterval<QuicPacketNumber>(
- QuicPacketNumber(49), QuicPacketNumber(100)));
-
- const std::vector<QuicInterval<QuicPacketNumber>> actual_intervals(
- ack_frame1.packets.begin(), ack_frame1.packets.end());
-
- EXPECT_EQ(expected_intervals, actual_intervals);
-}
-
-TEST_F(QuicFramesTest, RemoveSmallestInterval) {
- QuicAckFrame ack_frame1;
- ack_frame1.largest_acked = QuicPacketNumber(100u);
- ack_frame1.packets.AddRange(QuicPacketNumber(51), QuicPacketNumber(60));
- ack_frame1.packets.AddRange(QuicPacketNumber(71), QuicPacketNumber(80));
- ack_frame1.packets.AddRange(QuicPacketNumber(91), QuicPacketNumber(100));
- ack_frame1.packets.RemoveSmallestInterval();
- EXPECT_EQ(2u, ack_frame1.packets.NumIntervals());
- EXPECT_EQ(QuicPacketNumber(71u), ack_frame1.packets.Min());
- EXPECT_EQ(QuicPacketNumber(99u), ack_frame1.packets.Max());
-
- ack_frame1.packets.RemoveSmallestInterval();
- EXPECT_EQ(1u, ack_frame1.packets.NumIntervals());
- EXPECT_EQ(QuicPacketNumber(91u), ack_frame1.packets.Min());
- EXPECT_EQ(QuicPacketNumber(99u), ack_frame1.packets.Max());
-}
-
-TEST_F(QuicFramesTest, CopyQuicFrames) {
- QuicFrames frames;
- QuicMessageFrame* message_frame =
- new QuicMessageFrame(1, MemSliceFromString("message"));
- // Construct a frame list.
- for (uint8_t i = 0; i < NUM_FRAME_TYPES; ++i) {
- switch (i) {
- case PADDING_FRAME:
- frames.push_back(QuicFrame(QuicPaddingFrame(-1)));
- break;
- case RST_STREAM_FRAME:
- frames.push_back(QuicFrame(new QuicRstStreamFrame()));
- break;
- case CONNECTION_CLOSE_FRAME:
- frames.push_back(QuicFrame(new QuicConnectionCloseFrame()));
- break;
- case GOAWAY_FRAME:
- frames.push_back(QuicFrame(new QuicGoAwayFrame()));
- break;
- case WINDOW_UPDATE_FRAME:
- frames.push_back(QuicFrame(new QuicWindowUpdateFrame()));
- break;
- case BLOCKED_FRAME:
- frames.push_back(QuicFrame(new QuicBlockedFrame()));
- break;
- case STOP_WAITING_FRAME:
- frames.push_back(QuicFrame(QuicStopWaitingFrame()));
- break;
- case PING_FRAME:
- frames.push_back(QuicFrame(QuicPingFrame()));
- break;
- case CRYPTO_FRAME:
- frames.push_back(QuicFrame(new QuicCryptoFrame()));
- break;
- case STREAM_FRAME:
- frames.push_back(QuicFrame(QuicStreamFrame()));
- break;
- case ACK_FRAME:
- frames.push_back(QuicFrame(new QuicAckFrame()));
- break;
- case MTU_DISCOVERY_FRAME:
- frames.push_back(QuicFrame(QuicMtuDiscoveryFrame()));
- break;
- case NEW_CONNECTION_ID_FRAME:
- frames.push_back(QuicFrame(new QuicNewConnectionIdFrame()));
- break;
- case MAX_STREAMS_FRAME:
- frames.push_back(QuicFrame(QuicMaxStreamsFrame()));
- break;
- case STREAMS_BLOCKED_FRAME:
- frames.push_back(QuicFrame(QuicStreamsBlockedFrame()));
- break;
- case PATH_RESPONSE_FRAME:
- frames.push_back(QuicFrame(new QuicPathResponseFrame()));
- break;
- case PATH_CHALLENGE_FRAME:
- frames.push_back(QuicFrame(new QuicPathChallengeFrame()));
- break;
- case STOP_SENDING_FRAME:
- frames.push_back(QuicFrame(new QuicStopSendingFrame()));
- break;
- case MESSAGE_FRAME:
- frames.push_back(QuicFrame(message_frame));
- break;
- case NEW_TOKEN_FRAME:
- frames.push_back(QuicFrame(new QuicNewTokenFrame()));
- break;
- case RETIRE_CONNECTION_ID_FRAME:
- frames.push_back(QuicFrame(new QuicRetireConnectionIdFrame()));
- break;
- case HANDSHAKE_DONE_FRAME:
- frames.push_back(QuicFrame(QuicHandshakeDoneFrame()));
- break;
- case ACK_FREQUENCY_FRAME:
- frames.push_back(QuicFrame(new QuicAckFrequencyFrame()));
- break;
- default:
- ASSERT_TRUE(false)
- << "Please fix CopyQuicFrames if a new frame type is added.";
- break;
- }
- }
-
- QuicFrames copy = CopyQuicFrames(SimpleBufferAllocator::Get(), frames);
- ASSERT_EQ(NUM_FRAME_TYPES, copy.size());
- for (uint8_t i = 0; i < NUM_FRAME_TYPES; ++i) {
- EXPECT_EQ(i, copy[i].type);
- if (i != MESSAGE_FRAME) {
- continue;
- }
- // Verify message frame is correctly copied.
- EXPECT_EQ(1u, copy[i].message_frame->message_id);
- EXPECT_EQ(nullptr, copy[i].message_frame->data);
- EXPECT_EQ(7u, copy[i].message_frame->message_length);
- ASSERT_EQ(1u, copy[i].message_frame->message_data.size());
- EXPECT_EQ(0, memcmp(copy[i].message_frame->message_data[0].data(),
- frames[i].message_frame->message_data[0].data(), 7));
- }
- DeleteFrames(&frames);
- DeleteFrames(&copy);
-}
-
-class PacketNumberQueueTest : public QuicTest {};
-
-// Tests that a queue contains the expected data after calls to Add().
-TEST_F(PacketNumberQueueTest, AddRange) {
- PacketNumberQueue queue;
- queue.AddRange(QuicPacketNumber(1), QuicPacketNumber(51));
- queue.Add(QuicPacketNumber(53));
-
- EXPECT_FALSE(queue.Contains(QuicPacketNumber()));
- for (int i = 1; i < 51; ++i) {
- EXPECT_TRUE(queue.Contains(QuicPacketNumber(i)));
- }
- EXPECT_FALSE(queue.Contains(QuicPacketNumber(51)));
- EXPECT_FALSE(queue.Contains(QuicPacketNumber(52)));
- EXPECT_TRUE(queue.Contains(QuicPacketNumber(53)));
- EXPECT_FALSE(queue.Contains(QuicPacketNumber(54)));
- EXPECT_EQ(51u, queue.NumPacketsSlow());
- EXPECT_EQ(QuicPacketNumber(1u), queue.Min());
- EXPECT_EQ(QuicPacketNumber(53u), queue.Max());
-
- queue.Add(QuicPacketNumber(70));
- EXPECT_EQ(QuicPacketNumber(70u), queue.Max());
-}
-
-// Tests Contains function
-TEST_F(PacketNumberQueueTest, Contains) {
- PacketNumberQueue queue;
- EXPECT_FALSE(queue.Contains(QuicPacketNumber()));
- queue.AddRange(QuicPacketNumber(5), QuicPacketNumber(10));
- queue.Add(QuicPacketNumber(20));
-
- for (int i = 1; i < 5; ++i) {
- EXPECT_FALSE(queue.Contains(QuicPacketNumber(i)));
- }
-
- for (int i = 5; i < 10; ++i) {
- EXPECT_TRUE(queue.Contains(QuicPacketNumber(i)));
- }
- for (int i = 10; i < 20; ++i) {
- EXPECT_FALSE(queue.Contains(QuicPacketNumber(i)));
- }
- EXPECT_TRUE(queue.Contains(QuicPacketNumber(20)));
- EXPECT_FALSE(queue.Contains(QuicPacketNumber(21)));
-
- PacketNumberQueue queue2;
- EXPECT_FALSE(queue2.Contains(QuicPacketNumber(1)));
- for (int i = 1; i < 51; ++i) {
- queue2.Add(QuicPacketNumber(2 * i));
- }
- EXPECT_FALSE(queue2.Contains(QuicPacketNumber()));
- for (int i = 1; i < 51; ++i) {
- if (i % 2 == 0) {
- EXPECT_TRUE(queue2.Contains(QuicPacketNumber(i)));
- } else {
- EXPECT_FALSE(queue2.Contains(QuicPacketNumber(i)));
- }
- }
- EXPECT_FALSE(queue2.Contains(QuicPacketNumber(101)));
-}
-
-// Tests that a queue contains the expected data after calls to RemoveUpTo().
-TEST_F(PacketNumberQueueTest, Removal) {
- PacketNumberQueue queue;
- EXPECT_FALSE(queue.Contains(QuicPacketNumber(51)));
- queue.AddRange(QuicPacketNumber(1), QuicPacketNumber(100));
-
- EXPECT_TRUE(queue.RemoveUpTo(QuicPacketNumber(51)));
- EXPECT_FALSE(queue.RemoveUpTo(QuicPacketNumber(51)));
-
- EXPECT_FALSE(queue.Contains(QuicPacketNumber()));
- for (int i = 1; i < 51; ++i) {
- EXPECT_FALSE(queue.Contains(QuicPacketNumber(i)));
- }
- for (int i = 51; i < 100; ++i) {
- EXPECT_TRUE(queue.Contains(QuicPacketNumber(i)));
- }
- EXPECT_EQ(49u, queue.NumPacketsSlow());
- EXPECT_EQ(QuicPacketNumber(51u), queue.Min());
- EXPECT_EQ(QuicPacketNumber(99u), queue.Max());
-
- PacketNumberQueue queue2;
- queue2.AddRange(QuicPacketNumber(1), QuicPacketNumber(5));
- EXPECT_TRUE(queue2.RemoveUpTo(QuicPacketNumber(3)));
- EXPECT_TRUE(queue2.RemoveUpTo(QuicPacketNumber(50)));
- EXPECT_TRUE(queue2.Empty());
-}
-
-// Tests that a queue is empty when all of its elements are removed.
-TEST_F(PacketNumberQueueTest, Empty) {
- PacketNumberQueue queue;
- EXPECT_TRUE(queue.Empty());
- EXPECT_EQ(0u, queue.NumPacketsSlow());
-
- queue.AddRange(QuicPacketNumber(1), QuicPacketNumber(100));
- EXPECT_TRUE(queue.RemoveUpTo(QuicPacketNumber(100)));
- EXPECT_TRUE(queue.Empty());
- EXPECT_EQ(0u, queue.NumPacketsSlow());
-}
-
-// Tests that logging the state of a PacketNumberQueue does not crash.
-TEST_F(PacketNumberQueueTest, LogDoesNotCrash) {
- std::ostringstream oss;
- PacketNumberQueue queue;
- oss << queue;
-
- queue.Add(QuicPacketNumber(1));
- queue.AddRange(QuicPacketNumber(50), QuicPacketNumber(100));
- oss << queue;
-}
-
-// Tests that the iterators returned from a packet queue iterate over the queue.
-TEST_F(PacketNumberQueueTest, Iterators) {
- PacketNumberQueue queue;
- queue.AddRange(QuicPacketNumber(1), QuicPacketNumber(100));
-
- const std::vector<QuicInterval<QuicPacketNumber>> actual_intervals(
- queue.begin(), queue.end());
-
- PacketNumberQueue queue2;
- for (int i = 1; i < 100; i++) {
- queue2.AddRange(QuicPacketNumber(i), QuicPacketNumber(i + 1));
- }
-
- const std::vector<QuicInterval<QuicPacketNumber>> actual_intervals2(
- queue2.begin(), queue2.end());
-
- std::vector<QuicInterval<QuicPacketNumber>> expected_intervals;
- expected_intervals.emplace_back(QuicInterval<QuicPacketNumber>(
- QuicPacketNumber(1), QuicPacketNumber(100)));
- EXPECT_EQ(expected_intervals, actual_intervals);
- EXPECT_EQ(expected_intervals, actual_intervals2);
- EXPECT_EQ(actual_intervals, actual_intervals2);
-}
-
-TEST_F(PacketNumberQueueTest, ReversedIterators) {
- PacketNumberQueue queue;
- queue.AddRange(QuicPacketNumber(1), QuicPacketNumber(100));
- PacketNumberQueue queue2;
- for (int i = 1; i < 100; i++) {
- queue2.AddRange(QuicPacketNumber(i), QuicPacketNumber(i + 1));
- }
- const std::vector<QuicInterval<QuicPacketNumber>> actual_intervals(
- queue.rbegin(), queue.rend());
- const std::vector<QuicInterval<QuicPacketNumber>> actual_intervals2(
- queue2.rbegin(), queue2.rend());
-
- std::vector<QuicInterval<QuicPacketNumber>> expected_intervals;
- expected_intervals.emplace_back(QuicInterval<QuicPacketNumber>(
- QuicPacketNumber(1), QuicPacketNumber(100)));
-
- EXPECT_EQ(expected_intervals, actual_intervals);
- EXPECT_EQ(expected_intervals, actual_intervals2);
- EXPECT_EQ(actual_intervals, actual_intervals2);
-
- PacketNumberQueue queue3;
- for (int i = 1; i < 20; i++) {
- queue3.Add(QuicPacketNumber(2 * i));
- }
-
- auto begin = queue3.begin();
- auto end = queue3.end();
- --end;
- auto rbegin = queue3.rbegin();
- auto rend = queue3.rend();
- --rend;
-
- EXPECT_EQ(*begin, *rend);
- EXPECT_EQ(*rbegin, *end);
-}
-
-TEST_F(PacketNumberQueueTest, IntervalLengthAndRemoveInterval) {
- PacketNumberQueue queue;
- queue.AddRange(QuicPacketNumber(1), QuicPacketNumber(10));
- queue.AddRange(QuicPacketNumber(20), QuicPacketNumber(30));
- queue.AddRange(QuicPacketNumber(40), QuicPacketNumber(50));
- EXPECT_EQ(3u, queue.NumIntervals());
- EXPECT_EQ(10u, queue.LastIntervalLength());
-
- EXPECT_TRUE(queue.RemoveUpTo(QuicPacketNumber(25)));
- EXPECT_EQ(2u, queue.NumIntervals());
- EXPECT_EQ(10u, queue.LastIntervalLength());
- EXPECT_EQ(QuicPacketNumber(25u), queue.Min());
- EXPECT_EQ(QuicPacketNumber(49u), queue.Max());
-}
-
-} // namespace
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/frames/quic_goaway_frame.cc b/chromium/net/third_party/quiche/src/quic/core/frames/quic_goaway_frame.cc
deleted file mode 100644
index c73e6cb7bfb..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/frames/quic_goaway_frame.cc
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <string>
-
-#include "quic/core/frames/quic_goaway_frame.h"
-
-namespace quic {
-
-QuicGoAwayFrame::QuicGoAwayFrame(QuicControlFrameId control_frame_id,
- QuicErrorCode error_code,
- QuicStreamId last_good_stream_id,
- const std::string& reason)
- : control_frame_id(control_frame_id),
- error_code(error_code),
- last_good_stream_id(last_good_stream_id),
- reason_phrase(reason) {}
-
-std::ostream& operator<<(std::ostream& os,
- const QuicGoAwayFrame& goaway_frame) {
- os << "{ control_frame_id: " << goaway_frame.control_frame_id
- << ", error_code: " << goaway_frame.error_code
- << ", last_good_stream_id: " << goaway_frame.last_good_stream_id
- << ", reason_phrase: '" << goaway_frame.reason_phrase << "' }\n";
- return os;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/frames/quic_goaway_frame.h b/chromium/net/third_party/quiche/src/quic/core/frames/quic_goaway_frame.h
deleted file mode 100644
index 436c7a3b774..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/frames/quic_goaway_frame.h
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_FRAMES_QUIC_GOAWAY_FRAME_H_
-#define QUICHE_QUIC_CORE_FRAMES_QUIC_GOAWAY_FRAME_H_
-
-#include <ostream>
-#include <string>
-
-#include "quic/core/quic_constants.h"
-#include "quic/core/quic_error_codes.h"
-#include "quic/core/quic_types.h"
-
-namespace quic {
-
-struct QUIC_EXPORT_PRIVATE QuicGoAwayFrame {
- QuicGoAwayFrame() = default;
- QuicGoAwayFrame(QuicControlFrameId control_frame_id,
- QuicErrorCode error_code,
- QuicStreamId last_good_stream_id,
- const std::string& reason);
-
- friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
- const QuicGoAwayFrame& g);
-
- // A unique identifier of this control frame. 0 when this frame is received,
- // and non-zero when sent.
- QuicControlFrameId control_frame_id = kInvalidControlFrameId;
- QuicErrorCode error_code = QUIC_NO_ERROR;
- QuicStreamId last_good_stream_id = 0;
- std::string reason_phrase;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_FRAMES_QUIC_GOAWAY_FRAME_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/frames/quic_handshake_done_frame.cc b/chromium/net/third_party/quiche/src/quic/core/frames/quic_handshake_done_frame.cc
deleted file mode 100644
index 9501ff889b1..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/frames/quic_handshake_done_frame.cc
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright (c) 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/frames/quic_handshake_done_frame.h"
-
-namespace quic {
-
-QuicHandshakeDoneFrame::QuicHandshakeDoneFrame()
- : QuicInlinedFrame(HANDSHAKE_DONE_FRAME) {}
-
-QuicHandshakeDoneFrame::QuicHandshakeDoneFrame(
- QuicControlFrameId control_frame_id)
- : QuicInlinedFrame(HANDSHAKE_DONE_FRAME),
- control_frame_id(control_frame_id) {}
-
-std::ostream& operator<<(std::ostream& os,
- const QuicHandshakeDoneFrame& handshake_done_frame) {
- os << "{ control_frame_id: " << handshake_done_frame.control_frame_id
- << " }\n";
- return os;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/frames/quic_handshake_done_frame.h b/chromium/net/third_party/quiche/src/quic/core/frames/quic_handshake_done_frame.h
deleted file mode 100644
index 69fc68cbd42..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/frames/quic_handshake_done_frame.h
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright (c) 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_FRAMES_QUIC_HANDSHAKE_DONE_FRAME_H_
-#define QUICHE_QUIC_CORE_FRAMES_QUIC_HANDSHAKE_DONE_FRAME_H_
-
-#include "quic/core/frames/quic_inlined_frame.h"
-#include "quic/core/quic_constants.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// A HANDSHAKE_DONE frame contains no payload, and it is retransmittable,
-// and ACK'd just like other normal frames.
-struct QUIC_EXPORT_PRIVATE QuicHandshakeDoneFrame
- : public QuicInlinedFrame<QuicHandshakeDoneFrame> {
- QuicHandshakeDoneFrame();
- explicit QuicHandshakeDoneFrame(QuicControlFrameId control_frame_id);
-
- friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
- std::ostream& os,
- const QuicHandshakeDoneFrame& handshake_done_frame);
-
- QuicFrameType type;
-
- // A unique identifier of this control frame. 0 when this frame is received,
- // and non-zero when sent.
- QuicControlFrameId control_frame_id = kInvalidControlFrameId;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_FRAMES_QUIC_HANDSHAKE_DONE_FRAME_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/frames/quic_inlined_frame.h b/chromium/net/third_party/quiche/src/quic/core/frames/quic_inlined_frame.h
deleted file mode 100644
index 1ef15321209..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/frames/quic_inlined_frame.h
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_FRAMES_QUIC_INLINED_FRAME_H_
-#define QUICHE_QUIC_CORE_FRAMES_QUIC_INLINED_FRAME_H_
-
-#include <type_traits>
-
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// QuicInlinedFrame is the base class of all frame types that is inlined in the
-// QuicFrame class. It gurantees all inlined frame types contain a 'type' field
-// at offset 0, such that QuicFrame.type can get the correct frame type for both
-// inline and out-of-line frame types.
-template <typename DerivedT>
-struct QUIC_EXPORT_PRIVATE QuicInlinedFrame {
- QuicInlinedFrame(QuicFrameType type) {
- static_cast<DerivedT*>(this)->type = type;
- static_assert(std::is_standard_layout<DerivedT>::value,
- "Inlined frame must have a standard layout");
- static_assert(offsetof(DerivedT, type) == 0,
- "type must be the first field.");
- static_assert(sizeof(DerivedT) <= 24,
- "Frames larger than 24 bytes should not be inlined.");
- }
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_FRAMES_QUIC_INLINED_FRAME_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/frames/quic_max_streams_frame.cc b/chromium/net/third_party/quiche/src/quic/core/frames/quic_max_streams_frame.cc
deleted file mode 100644
index b2574e8db12..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/frames/quic_max_streams_frame.cc
+++ /dev/null
@@ -1,28 +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 "quic/core/frames/quic_max_streams_frame.h"
-
-namespace quic {
-
-QuicMaxStreamsFrame::QuicMaxStreamsFrame()
- : QuicInlinedFrame(MAX_STREAMS_FRAME) {}
-
-QuicMaxStreamsFrame::QuicMaxStreamsFrame(QuicControlFrameId control_frame_id,
- QuicStreamCount stream_count,
- bool unidirectional)
- : QuicInlinedFrame(MAX_STREAMS_FRAME),
- control_frame_id(control_frame_id),
- stream_count(stream_count),
- unidirectional(unidirectional) {}
-
-std::ostream& operator<<(std::ostream& os, const QuicMaxStreamsFrame& frame) {
- os << "{ control_frame_id: " << frame.control_frame_id
- << ", stream_count: " << frame.stream_count
- << ((frame.unidirectional) ? ", unidirectional }\n"
- : ", bidirectional }\n");
- return os;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/frames/quic_max_streams_frame.h b/chromium/net/third_party/quiche/src/quic/core/frames/quic_max_streams_frame.h
deleted file mode 100644
index 8b0231ef0df..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/frames/quic_max_streams_frame.h
+++ /dev/null
@@ -1,45 +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_CORE_FRAMES_QUIC_MAX_STREAMS_FRAME_H_
-#define QUICHE_QUIC_CORE_FRAMES_QUIC_MAX_STREAMS_FRAME_H_
-
-#include <ostream>
-
-#include "quic/core/frames/quic_inlined_frame.h"
-#include "quic/core/quic_constants.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// IETF format MAX_STREAMS frame.
-// This frame is used by the sender to inform the peer of the number of
-// streams that the peer may open and that the sender will accept.
-struct QUIC_EXPORT_PRIVATE QuicMaxStreamsFrame
- : public QuicInlinedFrame<QuicMaxStreamsFrame> {
- QuicMaxStreamsFrame();
- QuicMaxStreamsFrame(QuicControlFrameId control_frame_id,
- QuicStreamCount stream_count,
- bool unidirectional);
-
- friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
- std::ostream& os,
- const QuicMaxStreamsFrame& frame);
-
- QuicFrameType type;
-
- // A unique identifier of this control frame. 0 when this frame is received,
- // and non-zero when sent.
- QuicControlFrameId control_frame_id = kInvalidControlFrameId;
-
- // The number of streams that may be opened.
- QuicStreamCount stream_count = 0;
- // Whether uni- or bi-directional streams
- bool unidirectional = false;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_FRAMES_QUIC_MAX_STREAMS_FRAME_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/frames/quic_message_frame.cc b/chromium/net/third_party/quiche/src/quic/core/frames/quic_message_frame.cc
deleted file mode 100644
index 1ac0de67035..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/frames/quic_message_frame.cc
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/frames/quic_message_frame.h"
-
-#include "quic/core/quic_constants.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/platform/api/quic_mem_slice.h"
-
-namespace quic {
-
-QuicMessageFrame::QuicMessageFrame(QuicMessageId message_id)
- : message_id(message_id), data(nullptr), message_length(0) {}
-
-QuicMessageFrame::QuicMessageFrame(QuicMessageId message_id,
- absl::Span<QuicMemSlice> span)
- : message_id(message_id), data(nullptr), message_length(0) {
- for (QuicMemSlice& slice : span) {
- if (slice.empty()) {
- continue;
- }
- message_length += slice.length();
- message_data.push_back(std::move(slice));
- }
-}
-QuicMessageFrame::QuicMessageFrame(QuicMessageId message_id, QuicMemSlice slice)
- : QuicMessageFrame(message_id, absl::MakeSpan(&slice, 1)) {}
-
-QuicMessageFrame::QuicMessageFrame(const char* data, QuicPacketLength length)
- : message_id(0), data(data), message_length(length) {}
-
-QuicMessageFrame::~QuicMessageFrame() {}
-
-std::ostream& operator<<(std::ostream& os, const QuicMessageFrame& s) {
- os << " message_id: " << s.message_id
- << ", message_length: " << s.message_length << " }\n";
- return os;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/frames/quic_message_frame.h b/chromium/net/third_party/quiche/src/quic/core/frames/quic_message_frame.h
deleted file mode 100644
index 1d090c902e1..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/frames/quic_message_frame.h
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_FRAMES_QUIC_MESSAGE_FRAME_H_
-#define QUICHE_QUIC_CORE_FRAMES_QUIC_MESSAGE_FRAME_H_
-
-#include "absl/container/inlined_vector.h"
-#include "absl/types/span.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_containers.h"
-#include "quic/platform/api/quic_export.h"
-#include "quic/platform/api/quic_mem_slice.h"
-
-namespace quic {
-
-using QuicMessageData = absl::InlinedVector<QuicMemSlice, 1>;
-
-struct QUIC_EXPORT_PRIVATE QuicMessageFrame {
- QuicMessageFrame() = default;
- explicit QuicMessageFrame(QuicMessageId message_id);
- QuicMessageFrame(QuicMessageId message_id, absl::Span<QuicMemSlice> span);
- QuicMessageFrame(QuicMessageId message_id, QuicMemSlice slice);
- QuicMessageFrame(const char* data, QuicPacketLength length);
-
- QuicMessageFrame(const QuicMessageFrame& other) = delete;
- QuicMessageFrame& operator=(const QuicMessageFrame& other) = delete;
-
- QuicMessageFrame(QuicMessageFrame&& other) = default;
- QuicMessageFrame& operator=(QuicMessageFrame&& other) = default;
-
- ~QuicMessageFrame();
-
- friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
- std::ostream& os,
- const QuicMessageFrame& s);
-
- // message_id is only used on the sender side and does not get serialized on
- // wire.
- QuicMessageId message_id = 0;
- // Not owned, only used on read path.
- const char* data = nullptr;
- // Total length of message_data, must be fit into one packet.
- QuicPacketLength message_length = 0;
-
- // The actual message data which is reference counted, used on write path.
- QuicMessageData message_data;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_FRAMES_QUIC_MESSAGE_FRAME_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/frames/quic_mtu_discovery_frame.h b/chromium/net/third_party/quiche/src/quic/core/frames/quic_mtu_discovery_frame.h
deleted file mode 100644
index 014af3a07b4..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/frames/quic_mtu_discovery_frame.h
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_FRAMES_QUIC_MTU_DISCOVERY_FRAME_H_
-#define QUICHE_QUIC_CORE_FRAMES_QUIC_MTU_DISCOVERY_FRAME_H_
-
-#include "quic/core/frames/quic_inlined_frame.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// A path MTU discovery frame contains no payload and is serialized as a ping
-// frame.
-struct QUIC_EXPORT_PRIVATE QuicMtuDiscoveryFrame
- : public QuicInlinedFrame<QuicMtuDiscoveryFrame> {
- QuicMtuDiscoveryFrame() : QuicInlinedFrame(MTU_DISCOVERY_FRAME) {}
-
- QuicFrameType type;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_FRAMES_QUIC_MTU_DISCOVERY_FRAME_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/frames/quic_new_connection_id_frame.cc b/chromium/net/third_party/quiche/src/quic/core/frames/quic_new_connection_id_frame.cc
deleted file mode 100644
index b4c68ff78dd..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/frames/quic_new_connection_id_frame.cc
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/frames/quic_new_connection_id_frame.h"
-
-namespace quic {
-
-QuicNewConnectionIdFrame::QuicNewConnectionIdFrame(
- QuicControlFrameId control_frame_id,
- QuicConnectionId connection_id,
- QuicConnectionIdSequenceNumber sequence_number,
- StatelessResetToken stateless_reset_token,
- uint64_t retire_prior_to)
- : control_frame_id(control_frame_id),
- connection_id(connection_id),
- sequence_number(sequence_number),
- stateless_reset_token(stateless_reset_token),
- retire_prior_to(retire_prior_to) {
- QUICHE_DCHECK(retire_prior_to <= sequence_number);
-}
-
-std::ostream& operator<<(std::ostream& os,
- const QuicNewConnectionIdFrame& frame) {
- os << "{ control_frame_id: " << frame.control_frame_id
- << ", connection_id: " << frame.connection_id
- << ", sequence_number: " << frame.sequence_number
- << ", retire_prior_to: " << frame.retire_prior_to << " }\n";
- return os;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/frames/quic_new_connection_id_frame.h b/chromium/net/third_party/quiche/src/quic/core/frames/quic_new_connection_id_frame.h
deleted file mode 100644
index 235d2af792b..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/frames/quic_new_connection_id_frame.h
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_FRAMES_QUIC_NEW_CONNECTION_ID_FRAME_H_
-#define QUICHE_QUIC_CORE_FRAMES_QUIC_NEW_CONNECTION_ID_FRAME_H_
-
-#include <ostream>
-
-#include "quic/core/quic_connection_id.h"
-#include "quic/core/quic_constants.h"
-#include "quic/core/quic_error_codes.h"
-#include "quic/core/quic_types.h"
-
-namespace quic {
-
-struct QUIC_EXPORT_PRIVATE QuicNewConnectionIdFrame {
- QuicNewConnectionIdFrame() = default;
- QuicNewConnectionIdFrame(QuicControlFrameId control_frame_id,
- QuicConnectionId connection_id,
- QuicConnectionIdSequenceNumber sequence_number,
- StatelessResetToken stateless_reset_token,
- uint64_t retire_prior_to);
-
- friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
- std::ostream& os,
- const QuicNewConnectionIdFrame& frame);
-
- // A unique identifier of this control frame. 0 when this frame is received,
- // and non-zero when sent.
- QuicControlFrameId control_frame_id = kInvalidControlFrameId;
- QuicConnectionId connection_id = EmptyQuicConnectionId();
- QuicConnectionIdSequenceNumber sequence_number = 0;
- StatelessResetToken stateless_reset_token;
- uint64_t retire_prior_to = 0;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_FRAMES_QUIC_NEW_CONNECTION_ID_FRAME_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/frames/quic_new_token_frame.cc b/chromium/net/third_party/quiche/src/quic/core/frames/quic_new_token_frame.cc
deleted file mode 100644
index 8642fd93265..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/frames/quic_new_token_frame.cc
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/frames/quic_new_token_frame.h"
-
-#include "absl/strings/escaping.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-QuicNewTokenFrame::QuicNewTokenFrame(QuicControlFrameId control_frame_id,
- absl::string_view token)
- : control_frame_id(control_frame_id),
- token(std::string(token.data(), token.length())) {}
-
-std::ostream& operator<<(std::ostream& os, const QuicNewTokenFrame& s) {
- os << "{ control_frame_id: " << s.control_frame_id
- << ", token: " << absl::BytesToHexString(s.token) << " }\n";
- return os;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/frames/quic_new_token_frame.h b/chromium/net/third_party/quiche/src/quic/core/frames/quic_new_token_frame.h
deleted file mode 100644
index 805216bf919..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/frames/quic_new_token_frame.h
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_FRAMES_QUIC_NEW_TOKEN_FRAME_H_
-#define QUICHE_QUIC_CORE_FRAMES_QUIC_NEW_TOKEN_FRAME_H_
-
-#include <memory>
-#include <ostream>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_buffer_allocator.h"
-#include "quic/core/quic_constants.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-struct QUIC_EXPORT_PRIVATE QuicNewTokenFrame {
- QuicNewTokenFrame() = default;
- QuicNewTokenFrame(QuicControlFrameId control_frame_id,
- absl::string_view token);
-
- friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
- std::ostream& os,
- const QuicNewTokenFrame& s);
-
- // A unique identifier of this control frame. 0 when this frame is received,
- // and non-zero when sent.
- QuicControlFrameId control_frame_id = kInvalidControlFrameId;
-
- std::string token;
-};
-static_assert(sizeof(QuicNewTokenFrame) <= 64,
- "Keep the QuicNewTokenFrame size to a cacheline.");
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_FRAMES_QUIC_NEW_TOKEN_FRAME_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/frames/quic_padding_frame.cc b/chromium/net/third_party/quiche/src/quic/core/frames/quic_padding_frame.cc
deleted file mode 100644
index 5679a2bf55a..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/frames/quic_padding_frame.cc
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/frames/quic_padding_frame.h"
-
-namespace quic {
-
-std::ostream& operator<<(std::ostream& os,
- const QuicPaddingFrame& padding_frame) {
- os << "{ num_padding_bytes: " << padding_frame.num_padding_bytes << " }\n";
- return os;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/frames/quic_padding_frame.h b/chromium/net/third_party/quiche/src/quic/core/frames/quic_padding_frame.h
deleted file mode 100644
index 146721e6228..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/frames/quic_padding_frame.h
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_FRAMES_QUIC_PADDING_FRAME_H_
-#define QUICHE_QUIC_CORE_FRAMES_QUIC_PADDING_FRAME_H_
-
-#include <cstdint>
-#include <ostream>
-
-#include "quic/core/frames/quic_inlined_frame.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// A padding frame contains no payload.
-struct QUIC_EXPORT_PRIVATE QuicPaddingFrame
- : public QuicInlinedFrame<QuicPaddingFrame> {
- QuicPaddingFrame() : QuicInlinedFrame(PADDING_FRAME) {}
- explicit QuicPaddingFrame(int num_padding_bytes)
- : QuicInlinedFrame(PADDING_FRAME), num_padding_bytes(num_padding_bytes) {}
-
- friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
- std::ostream& os,
- const QuicPaddingFrame& padding_frame);
-
- QuicFrameType type;
-
- // -1: full padding to the end of a max-sized packet
- // otherwise: only pad up to num_padding_bytes bytes
- int num_padding_bytes = -1;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_FRAMES_QUIC_PADDING_FRAME_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/frames/quic_path_challenge_frame.cc b/chromium/net/third_party/quiche/src/quic/core/frames/quic_path_challenge_frame.cc
deleted file mode 100644
index 0f88bb83160..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/frames/quic_path_challenge_frame.cc
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/frames/quic_path_challenge_frame.h"
-
-#include "absl/strings/escaping.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-
-namespace quic {
-
-QuicPathChallengeFrame::QuicPathChallengeFrame(
- QuicControlFrameId control_frame_id,
- const QuicPathFrameBuffer& data_buff)
- : control_frame_id(control_frame_id) {
- memcpy(data_buffer.data(), data_buff.data(), data_buffer.size());
-}
-
-QuicPathChallengeFrame::~QuicPathChallengeFrame() {}
-
-std::ostream& operator<<(std::ostream& os,
- const QuicPathChallengeFrame& frame) {
- os << "{ control_frame_id: " << frame.control_frame_id << ", data: "
- << absl::BytesToHexString(absl::string_view(
- reinterpret_cast<const char*>(frame.data_buffer.data()),
- frame.data_buffer.size()))
- << " }\n";
- return os;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/frames/quic_path_challenge_frame.h b/chromium/net/third_party/quiche/src/quic/core/frames/quic_path_challenge_frame.h
deleted file mode 100644
index 6966775a30d..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/frames/quic_path_challenge_frame.h
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_FRAMES_QUIC_PATH_CHALLENGE_FRAME_H_
-#define QUICHE_QUIC_CORE_FRAMES_QUIC_PATH_CHALLENGE_FRAME_H_
-
-#include <memory>
-#include <ostream>
-
-#include "quic/core/quic_constants.h"
-#include "quic/core/quic_types.h"
-
-namespace quic {
-
-struct QUIC_EXPORT_PRIVATE QuicPathChallengeFrame {
- QuicPathChallengeFrame() = default;
- QuicPathChallengeFrame(QuicControlFrameId control_frame_id,
- const QuicPathFrameBuffer& data_buff);
- ~QuicPathChallengeFrame();
-
- friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
- std::ostream& os,
- const QuicPathChallengeFrame& frame);
-
- // A unique identifier of this control frame. 0 when this frame is received,
- // and non-zero when sent.
- QuicControlFrameId control_frame_id = kInvalidControlFrameId;
-
- QuicPathFrameBuffer data_buffer{};
-};
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_FRAMES_QUIC_PATH_CHALLENGE_FRAME_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/frames/quic_path_response_frame.cc b/chromium/net/third_party/quiche/src/quic/core/frames/quic_path_response_frame.cc
deleted file mode 100644
index f802b131b30..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/frames/quic_path_response_frame.cc
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/frames/quic_path_response_frame.h"
-
-#include "absl/strings/escaping.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-
-namespace quic {
-
-QuicPathResponseFrame::QuicPathResponseFrame(
- QuicControlFrameId control_frame_id,
- const QuicPathFrameBuffer& data_buff)
- : control_frame_id(control_frame_id) {
- memcpy(data_buffer.data(), data_buff.data(), data_buffer.size());
-}
-
-QuicPathResponseFrame::~QuicPathResponseFrame() {}
-
-std::ostream& operator<<(std::ostream& os, const QuicPathResponseFrame& frame) {
- os << "{ control_frame_id: " << frame.control_frame_id << ", data: "
- << absl::BytesToHexString(absl::string_view(
- reinterpret_cast<const char*>(frame.data_buffer.data()),
- frame.data_buffer.size()))
- << " }\n";
- return os;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/frames/quic_path_response_frame.h b/chromium/net/third_party/quiche/src/quic/core/frames/quic_path_response_frame.h
deleted file mode 100644
index a4a75be208b..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/frames/quic_path_response_frame.h
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_FRAMES_QUIC_PATH_RESPONSE_FRAME_H_
-#define QUICHE_QUIC_CORE_FRAMES_QUIC_PATH_RESPONSE_FRAME_H_
-
-#include <memory>
-#include <ostream>
-
-#include "quic/core/quic_constants.h"
-#include "quic/core/quic_types.h"
-
-namespace quic {
-
-struct QUIC_EXPORT_PRIVATE QuicPathResponseFrame {
- QuicPathResponseFrame() = default;
- QuicPathResponseFrame(QuicControlFrameId control_frame_id,
- const QuicPathFrameBuffer& data_buff);
- ~QuicPathResponseFrame();
-
- friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
- std::ostream& os,
- const QuicPathResponseFrame& frame);
-
- // A unique identifier of this control frame. 0 when this frame is received,
- // and non-zero when sent.
- QuicControlFrameId control_frame_id = kInvalidControlFrameId;
-
- QuicPathFrameBuffer data_buffer{};
-};
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_FRAMES_QUIC_PATH_RESPONSE_FRAME_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/frames/quic_ping_frame.cc b/chromium/net/third_party/quiche/src/quic/core/frames/quic_ping_frame.cc
deleted file mode 100644
index d4e6daa7114..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/frames/quic_ping_frame.cc
+++ /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.
-
-#include "quic/core/frames/quic_ping_frame.h"
-
-namespace quic {
-
-QuicPingFrame::QuicPingFrame() : QuicInlinedFrame(PING_FRAME) {}
-
-QuicPingFrame::QuicPingFrame(QuicControlFrameId control_frame_id)
- : QuicInlinedFrame(PING_FRAME), control_frame_id(control_frame_id) {}
-
-std::ostream& operator<<(std::ostream& os, const QuicPingFrame& ping_frame) {
- os << "{ control_frame_id: " << ping_frame.control_frame_id << " }\n";
- return os;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/frames/quic_ping_frame.h b/chromium/net/third_party/quiche/src/quic/core/frames/quic_ping_frame.h
deleted file mode 100644
index 012d73d29ec..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/frames/quic_ping_frame.h
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_FRAMES_QUIC_PING_FRAME_H_
-#define QUICHE_QUIC_CORE_FRAMES_QUIC_PING_FRAME_H_
-
-#include "quic/core/frames/quic_inlined_frame.h"
-#include "quic/core/quic_constants.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// A ping frame contains no payload, though it is retransmittable,
-// and ACK'd just like other normal frames.
-struct QUIC_EXPORT_PRIVATE QuicPingFrame
- : public QuicInlinedFrame<QuicPingFrame> {
- QuicPingFrame();
- explicit QuicPingFrame(QuicControlFrameId control_frame_id);
-
- friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
- std::ostream& os,
- const QuicPingFrame& ping_frame);
-
- QuicFrameType type;
-
- // A unique identifier of this control frame. 0 when this frame is received,
- // and non-zero when sent.
- QuicControlFrameId control_frame_id = kInvalidControlFrameId;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_FRAMES_QUIC_PING_FRAME_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/frames/quic_retire_connection_id_frame.cc b/chromium/net/third_party/quiche/src/quic/core/frames/quic_retire_connection_id_frame.cc
deleted file mode 100644
index c3009f0ea80..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/frames/quic_retire_connection_id_frame.cc
+++ /dev/null
@@ -1,21 +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 "quic/core/frames/quic_retire_connection_id_frame.h"
-
-namespace quic {
-
-QuicRetireConnectionIdFrame::QuicRetireConnectionIdFrame(
- QuicControlFrameId control_frame_id,
- QuicConnectionIdSequenceNumber sequence_number)
- : control_frame_id(control_frame_id), sequence_number(sequence_number) {}
-
-std::ostream& operator<<(std::ostream& os,
- const QuicRetireConnectionIdFrame& frame) {
- os << "{ control_frame_id: " << frame.control_frame_id
- << ", sequence_number: " << frame.sequence_number << " }\n";
- return os;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/frames/quic_retire_connection_id_frame.h b/chromium/net/third_party/quiche/src/quic/core/frames/quic_retire_connection_id_frame.h
deleted file mode 100644
index 3a8a4dac986..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/frames/quic_retire_connection_id_frame.h
+++ /dev/null
@@ -1,33 +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_CORE_FRAMES_QUIC_RETIRE_CONNECTION_ID_FRAME_H_
-#define QUICHE_QUIC_CORE_FRAMES_QUIC_RETIRE_CONNECTION_ID_FRAME_H_
-
-#include <ostream>
-
-#include "quic/core/quic_constants.h"
-#include "quic/core/quic_error_codes.h"
-#include "quic/core/quic_types.h"
-
-namespace quic {
-
-struct QUIC_EXPORT_PRIVATE QuicRetireConnectionIdFrame {
- QuicRetireConnectionIdFrame() = default;
- QuicRetireConnectionIdFrame(QuicControlFrameId control_frame_id,
- QuicConnectionIdSequenceNumber sequence_number);
-
- friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
- std::ostream& os,
- const QuicRetireConnectionIdFrame& frame);
-
- // A unique identifier of this control frame. 0 when this frame is received,
- // and non-zero when sent.
- QuicControlFrameId control_frame_id = kInvalidControlFrameId;
- QuicConnectionIdSequenceNumber sequence_number = 0;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_FRAMES_QUIC_RETIRE_CONNECTION_ID_FRAME_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/frames/quic_rst_stream_frame.cc b/chromium/net/third_party/quiche/src/quic/core/frames/quic_rst_stream_frame.cc
deleted file mode 100644
index 873868c3d5c..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/frames/quic_rst_stream_frame.cc
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/frames/quic_rst_stream_frame.h"
-
-#include "quic/core/quic_error_codes.h"
-
-namespace quic {
-
-QuicRstStreamFrame::QuicRstStreamFrame(QuicControlFrameId control_frame_id,
- QuicStreamId stream_id,
- QuicRstStreamErrorCode error_code,
- QuicStreamOffset bytes_written)
- : control_frame_id(control_frame_id),
- stream_id(stream_id),
- error_code(error_code),
- ietf_error_code(RstStreamErrorCodeToIetfResetStreamErrorCode(error_code)),
- byte_offset(bytes_written) {}
-
-QuicRstStreamFrame::QuicRstStreamFrame(QuicControlFrameId control_frame_id,
- QuicStreamId stream_id,
- QuicResetStreamError error,
- QuicStreamOffset bytes_written)
- : control_frame_id(control_frame_id),
- stream_id(stream_id),
- error_code(error.internal_code()),
- ietf_error_code(error.ietf_application_code()),
- byte_offset(bytes_written) {}
-
-std::ostream& operator<<(std::ostream& os,
- const QuicRstStreamFrame& rst_frame) {
- os << "{ control_frame_id: " << rst_frame.control_frame_id
- << ", stream_id: " << rst_frame.stream_id
- << ", byte_offset: " << rst_frame.byte_offset
- << ", error_code: " << rst_frame.error_code
- << ", ietf_error_code: " << rst_frame.ietf_error_code << " }\n";
- return os;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/frames/quic_rst_stream_frame.h b/chromium/net/third_party/quiche/src/quic/core/frames/quic_rst_stream_frame.h
deleted file mode 100644
index 744a227c8ff..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/frames/quic_rst_stream_frame.h
+++ /dev/null
@@ -1,58 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_FRAMES_QUIC_RST_STREAM_FRAME_H_
-#define QUICHE_QUIC_CORE_FRAMES_QUIC_RST_STREAM_FRAME_H_
-
-#include <ostream>
-
-#include "quic/core/quic_constants.h"
-#include "quic/core/quic_error_codes.h"
-#include "quic/core/quic_types.h"
-
-namespace quic {
-
-struct QUIC_EXPORT_PRIVATE QuicRstStreamFrame {
- QuicRstStreamFrame() = default;
- QuicRstStreamFrame(QuicControlFrameId control_frame_id,
- QuicStreamId stream_id, QuicRstStreamErrorCode error_code,
- QuicStreamOffset bytes_written);
- QuicRstStreamFrame(QuicControlFrameId control_frame_id,
- QuicStreamId stream_id, QuicResetStreamError error,
- QuicStreamOffset bytes_written);
-
- friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
- std::ostream& os, const QuicRstStreamFrame& r);
-
- // A unique identifier of this control frame. 0 when this frame is received,
- // and non-zero when sent.
- QuicControlFrameId control_frame_id = kInvalidControlFrameId;
-
- QuicStreamId stream_id = 0;
-
- // When using Google QUIC: the RST_STREAM error code on the wire.
- // When using IETF QUIC: for an outgoing RESET_STREAM frame, the error code
- // generated by the application that determines |ietf_error_code| to be sent
- // on the wire; for an incoming RESET_STREAM frame, the error code inferred
- // from the |ietf_error_code| received on the wire.
- QuicRstStreamErrorCode error_code = QUIC_STREAM_NO_ERROR;
-
- // Application error code of RESET_STREAM frame. Used for IETF QUIC only.
- uint64_t ietf_error_code = 0;
-
- // Used to update flow control windows. On termination of a stream, both
- // endpoints must inform the peer of the number of bytes they have sent on
- // that stream. This can be done through normal termination (data packet with
- // FIN) or through a RST.
- QuicStreamOffset byte_offset = 0;
-
- // Returns a tuple of both |error_code| and |ietf_error_code|.
- QuicResetStreamError error() const {
- return QuicResetStreamError(error_code, ietf_error_code);
- }
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_FRAMES_QUIC_RST_STREAM_FRAME_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/frames/quic_stop_sending_frame.cc b/chromium/net/third_party/quiche/src/quic/core/frames/quic_stop_sending_frame.cc
deleted file mode 100644
index 396288ead41..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/frames/quic_stop_sending_frame.cc
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/frames/quic_stop_sending_frame.h"
-
-#include "quic/core/quic_error_codes.h"
-
-namespace quic {
-
-QuicStopSendingFrame::QuicStopSendingFrame(QuicControlFrameId control_frame_id,
- QuicStreamId stream_id,
- QuicRstStreamErrorCode error_code)
- : QuicStopSendingFrame(control_frame_id, stream_id,
- QuicResetStreamError::FromInternal(error_code)) {}
-
-QuicStopSendingFrame::QuicStopSendingFrame(QuicControlFrameId control_frame_id,
- QuicStreamId stream_id,
- QuicResetStreamError error)
- : control_frame_id(control_frame_id),
- stream_id(stream_id),
- error_code(error.internal_code()),
- ietf_error_code(error.ietf_application_code()) {}
-
-std::ostream& operator<<(std::ostream& os, const QuicStopSendingFrame& frame) {
- os << "{ control_frame_id: " << frame.control_frame_id
- << ", stream_id: " << frame.stream_id
- << ", error_code: " << frame.error_code
- << ", ietf_error_code: " << frame.ietf_error_code << " }\n";
- return os;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/frames/quic_stop_sending_frame.h b/chromium/net/third_party/quiche/src/quic/core/frames/quic_stop_sending_frame.h
deleted file mode 100644
index b575e756cb7..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/frames/quic_stop_sending_frame.h
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_FRAMES_QUIC_STOP_SENDING_FRAME_H_
-#define QUICHE_QUIC_CORE_FRAMES_QUIC_STOP_SENDING_FRAME_H_
-
-#include <ostream>
-
-#include "quic/core/quic_constants.h"
-#include "quic/core/quic_error_codes.h"
-#include "quic/core/quic_types.h"
-
-namespace quic {
-
-struct QUIC_EXPORT_PRIVATE QuicStopSendingFrame {
- QuicStopSendingFrame() = default;
- QuicStopSendingFrame(QuicControlFrameId control_frame_id,
- QuicStreamId stream_id,
- QuicRstStreamErrorCode error_code);
- QuicStopSendingFrame(QuicControlFrameId control_frame_id,
- QuicStreamId stream_id, QuicResetStreamError error);
-
- friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
- std::ostream& os,
- const QuicStopSendingFrame& frame);
-
- // A unique identifier of this control frame. 0 when this frame is received,
- // and non-zero when sent.
- QuicControlFrameId control_frame_id = kInvalidControlFrameId;
- QuicStreamId stream_id = 0;
-
- // For an outgoing frame, the error code generated by the application that
- // determines |ietf_error_code| to be sent on the wire; for an incoming frame,
- // the error code inferred from |ietf_error_code| received on the wire.
- QuicRstStreamErrorCode error_code = QUIC_STREAM_NO_ERROR;
-
- // On-the-wire application error code of the frame.
- uint64_t ietf_error_code = 0;
-
- // Returns a tuple of both |error_code| and |ietf_error_code|.
- QuicResetStreamError error() const {
- return QuicResetStreamError(error_code, ietf_error_code);
- }
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_FRAMES_QUIC_STOP_SENDING_FRAME_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/frames/quic_stop_waiting_frame.cc b/chromium/net/third_party/quiche/src/quic/core/frames/quic_stop_waiting_frame.cc
deleted file mode 100644
index c5ce9389dc3..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/frames/quic_stop_waiting_frame.cc
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/frames/quic_stop_waiting_frame.h"
-
-#include "quic/core/quic_constants.h"
-
-namespace quic {
-
-QuicStopWaitingFrame::QuicStopWaitingFrame()
- : QuicInlinedFrame(STOP_WAITING_FRAME) {}
-
-std::ostream& operator<<(std::ostream& os,
- const QuicStopWaitingFrame& sent_info) {
- os << "{ least_unacked: " << sent_info.least_unacked << " }\n";
- return os;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/frames/quic_stop_waiting_frame.h b/chromium/net/third_party/quiche/src/quic/core/frames/quic_stop_waiting_frame.h
deleted file mode 100644
index fda5c614dc2..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/frames/quic_stop_waiting_frame.h
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_FRAMES_QUIC_STOP_WAITING_FRAME_H_
-#define QUICHE_QUIC_CORE_FRAMES_QUIC_STOP_WAITING_FRAME_H_
-
-#include <ostream>
-
-#include "quic/core/frames/quic_inlined_frame.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-struct QUIC_EXPORT_PRIVATE QuicStopWaitingFrame
- : public QuicInlinedFrame<QuicStopWaitingFrame> {
- QuicStopWaitingFrame();
-
- friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
- std::ostream& os,
- const QuicStopWaitingFrame& s);
-
- QuicFrameType type;
-
- // The lowest packet we've sent which is unacked, and we expect an ack for.
- QuicPacketNumber least_unacked;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_FRAMES_QUIC_STOP_WAITING_FRAME_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/frames/quic_stream_frame.cc b/chromium/net/third_party/quiche/src/quic/core/frames/quic_stream_frame.cc
deleted file mode 100644
index c383c8f168e..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/frames/quic_stream_frame.cc
+++ /dev/null
@@ -1,56 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/frames/quic_stream_frame.h"
-
-#include "absl/strings/string_view.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-QuicStreamFrame::QuicStreamFrame() : QuicInlinedFrame(STREAM_FRAME) {}
-
-QuicStreamFrame::QuicStreamFrame(QuicStreamId stream_id,
- bool fin,
- QuicStreamOffset offset,
- absl::string_view data)
- : QuicStreamFrame(stream_id, fin, offset, data.data(), data.length()) {}
-
-QuicStreamFrame::QuicStreamFrame(QuicStreamId stream_id,
- bool fin,
- QuicStreamOffset offset,
- QuicPacketLength data_length)
- : QuicStreamFrame(stream_id, fin, offset, nullptr, data_length) {}
-
-QuicStreamFrame::QuicStreamFrame(QuicStreamId stream_id,
- bool fin,
- QuicStreamOffset offset,
- const char* data_buffer,
- QuicPacketLength data_length)
- : QuicInlinedFrame(STREAM_FRAME),
- fin(fin),
- data_length(data_length),
- stream_id(stream_id),
- data_buffer(data_buffer),
- offset(offset) {}
-
-std::ostream& operator<<(std::ostream& os,
- const QuicStreamFrame& stream_frame) {
- os << "{ stream_id: " << stream_frame.stream_id
- << ", fin: " << stream_frame.fin << ", offset: " << stream_frame.offset
- << ", length: " << stream_frame.data_length << " }\n";
- return os;
-}
-
-bool QuicStreamFrame::operator==(const QuicStreamFrame& rhs) const {
- return fin == rhs.fin && data_length == rhs.data_length &&
- stream_id == rhs.stream_id && data_buffer == rhs.data_buffer &&
- offset == rhs.offset;
-}
-
-bool QuicStreamFrame::operator!=(const QuicStreamFrame& rhs) const {
- return !(*this == rhs);
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/frames/quic_stream_frame.h b/chromium/net/third_party/quiche/src/quic/core/frames/quic_stream_frame.h
deleted file mode 100644
index 9ba8ccc1606..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/frames/quic_stream_frame.h
+++ /dev/null
@@ -1,58 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_FRAMES_QUIC_STREAM_FRAME_H_
-#define QUICHE_QUIC_CORE_FRAMES_QUIC_STREAM_FRAME_H_
-
-#include <memory>
-#include <ostream>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/frames/quic_inlined_frame.h"
-#include "quic/core/quic_buffer_allocator.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-struct QUIC_EXPORT_PRIVATE QuicStreamFrame
- : public QuicInlinedFrame<QuicStreamFrame> {
- QuicStreamFrame();
- QuicStreamFrame(QuicStreamId stream_id,
- bool fin,
- QuicStreamOffset offset,
- absl::string_view data);
- QuicStreamFrame(QuicStreamId stream_id,
- bool fin,
- QuicStreamOffset offset,
- QuicPacketLength data_length);
-
- friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
- const QuicStreamFrame& s);
-
- bool operator==(const QuicStreamFrame& rhs) const;
-
- bool operator!=(const QuicStreamFrame& rhs) const;
-
- QuicFrameType type;
- bool fin = false;
- QuicPacketLength data_length = 0;
- // TODO(wub): Change to a QuicUtils::GetInvalidStreamId when it is not version
- // dependent.
- QuicStreamId stream_id = -1;
- const char* data_buffer = nullptr; // Not owned.
- QuicStreamOffset offset = 0; // Location of this data in the stream.
-
- QuicStreamFrame(QuicStreamId stream_id,
- bool fin,
- QuicStreamOffset offset,
- const char* data_buffer,
- QuicPacketLength data_length);
-};
-static_assert(sizeof(QuicStreamFrame) <= 64,
- "Keep the QuicStreamFrame size to a cacheline.");
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_FRAMES_QUIC_STREAM_FRAME_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/frames/quic_streams_blocked_frame.cc b/chromium/net/third_party/quiche/src/quic/core/frames/quic_streams_blocked_frame.cc
deleted file mode 100644
index 4ec8caa5def..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/frames/quic_streams_blocked_frame.cc
+++ /dev/null
@@ -1,31 +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 "quic/core/frames/quic_streams_blocked_frame.h"
-
-namespace quic {
-
-QuicStreamsBlockedFrame::QuicStreamsBlockedFrame()
- : QuicInlinedFrame(STREAMS_BLOCKED_FRAME) {}
-
-QuicStreamsBlockedFrame::QuicStreamsBlockedFrame(
- QuicControlFrameId control_frame_id,
- QuicStreamCount stream_count,
- bool unidirectional)
- : QuicInlinedFrame(STREAMS_BLOCKED_FRAME),
- control_frame_id(control_frame_id),
- stream_count(stream_count),
- unidirectional(unidirectional) {}
-
-std::ostream& operator<<(std::ostream& os,
- const QuicStreamsBlockedFrame& frame) {
- os << "{ control_frame_id: " << frame.control_frame_id
- << ", stream count: " << frame.stream_count
- << ((frame.unidirectional) ? ", unidirectional }\n"
- : ", bidirectional }\n");
-
- return os;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/frames/quic_streams_blocked_frame.h b/chromium/net/third_party/quiche/src/quic/core/frames/quic_streams_blocked_frame.h
deleted file mode 100644
index 2d738901776..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/frames/quic_streams_blocked_frame.h
+++ /dev/null
@@ -1,46 +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_CORE_FRAMES_QUIC_STREAMS_BLOCKED_FRAME_H_
-#define QUICHE_QUIC_CORE_FRAMES_QUIC_STREAMS_BLOCKED_FRAME_H_
-
-#include <ostream>
-
-#include "quic/core/frames/quic_inlined_frame.h"
-#include "quic/core/quic_constants.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// IETF format STREAMS_BLOCKED frame.
-// The sender uses this to inform the peer that the sender wished to
-// open a new stream, exceeding the limit on the number of streams.
-struct QUIC_EXPORT_PRIVATE QuicStreamsBlockedFrame
- : public QuicInlinedFrame<QuicStreamsBlockedFrame> {
- QuicStreamsBlockedFrame();
- QuicStreamsBlockedFrame(QuicControlFrameId control_frame_id,
- QuicStreamCount stream_count,
- bool unidirectional);
-
- friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
- std::ostream& os,
- const QuicStreamsBlockedFrame& frame);
-
- QuicFrameType type;
-
- // A unique identifier of this control frame. 0 when this frame is received,
- // and non-zero when sent.
- QuicControlFrameId control_frame_id = kInvalidControlFrameId;
-
- // The number of streams that the sender wishes to exceed
- QuicStreamCount stream_count = 0;
-
- // Whether uni- or bi-directional streams
- bool unidirectional = false;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_FRAMES_QUIC_STREAMS_BLOCKED_FRAME_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/frames/quic_window_update_frame.cc b/chromium/net/third_party/quiche/src/quic/core/frames/quic_window_update_frame.cc
deleted file mode 100644
index 4f21b5711ab..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/frames/quic_window_update_frame.cc
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/frames/quic_window_update_frame.h"
-
-namespace quic {
-
-QuicWindowUpdateFrame::QuicWindowUpdateFrame(
- QuicControlFrameId control_frame_id,
- QuicStreamId stream_id,
- QuicByteCount max_data)
- : control_frame_id(control_frame_id),
- stream_id(stream_id),
- max_data(max_data) {}
-
-std::ostream& operator<<(std::ostream& os,
- const QuicWindowUpdateFrame& window_update_frame) {
- os << "{ control_frame_id: " << window_update_frame.control_frame_id
- << ", stream_id: " << window_update_frame.stream_id
- << ", max_data: " << window_update_frame.max_data << " }\n";
- return os;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/frames/quic_window_update_frame.h b/chromium/net/third_party/quiche/src/quic/core/frames/quic_window_update_frame.h
deleted file mode 100644
index 372a4ea598e..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/frames/quic_window_update_frame.h
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_FRAMES_QUIC_WINDOW_UPDATE_FRAME_H_
-#define QUICHE_QUIC_CORE_FRAMES_QUIC_WINDOW_UPDATE_FRAME_H_
-
-#include <ostream>
-
-#include "quic/core/quic_constants.h"
-#include "quic/core/quic_types.h"
-
-namespace quic {
-
-// Flow control updates per-stream and at the connection level.
-// Based on SPDY's WINDOW_UPDATE frame, but uses an absolute max data bytes
-// rather than a window delta.
-struct QUIC_EXPORT_PRIVATE QuicWindowUpdateFrame {
- QuicWindowUpdateFrame() = default;
- QuicWindowUpdateFrame(QuicControlFrameId control_frame_id,
- QuicStreamId stream_id,
- QuicByteCount max_data);
-
- friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
- std::ostream& os,
- const QuicWindowUpdateFrame& w);
-
- // A unique identifier of this control frame. 0 when this frame is received,
- // and non-zero when sent.
- QuicControlFrameId control_frame_id = kInvalidControlFrameId;
-
- // The stream this frame applies to. 0 is a special case meaning the overall
- // connection rather than a specific stream.
- QuicStreamId stream_id = 0;
-
- // Maximum data allowed in the stream or connection. The receiver of this
- // frame must not send data which would exceedes this restriction.
- QuicByteCount max_data = 0;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_FRAMES_QUIC_WINDOW_UPDATE_FRAME_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/handshaker_delegate_interface.h b/chromium/net/third_party/quiche/src/quic/core/handshaker_delegate_interface.h
deleted file mode 100644
index 7fbc5ae33db..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/handshaker_delegate_interface.h
+++ /dev/null
@@ -1,85 +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_CORE_HANDSHAKER_DELEGATE_INTERFACE_H_
-#define QUICHE_QUIC_CORE_HANDSHAKER_DELEGATE_INTERFACE_H_
-
-#include "quic/core/crypto/transport_parameters.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_versions.h"
-
-namespace quic {
-
-class QuicDecrypter;
-class QuicEncrypter;
-
-// Pure virtual class to get notified when particular handshake events occurred.
-class QUIC_EXPORT_PRIVATE HandshakerDelegateInterface {
- public:
- virtual ~HandshakerDelegateInterface() {}
-
- // Called when new decryption key of |level| is available. Returns true if
- // decrypter is set successfully, otherwise, returns false.
- virtual bool OnNewDecryptionKeyAvailable(
- EncryptionLevel level, std::unique_ptr<QuicDecrypter> decrypter,
- bool set_alternative_decrypter, bool latch_once_used) = 0;
-
- // Called when new encryption key of |level| is available.
- virtual void OnNewEncryptionKeyAvailable(
- EncryptionLevel level, std::unique_ptr<QuicEncrypter> encrypter) = 0;
-
- // Called to set default encryption level to |level|. Only used in QUIC
- // crypto.
- virtual void SetDefaultEncryptionLevel(EncryptionLevel level) = 0;
-
- // Called when both 1-RTT read and write keys are available. Only used in TLS
- // handshake.
- virtual void OnTlsHandshakeComplete() = 0;
-
- // Called to discard old decryption keys to stop processing packets of
- // encryption |level|.
- virtual void DiscardOldDecryptionKey(EncryptionLevel level) = 0;
-
- // Called to discard old encryption keys (and neuter obsolete data).
- // TODO(fayang): consider to combine this with DiscardOldDecryptionKey.
- virtual void DiscardOldEncryptionKey(EncryptionLevel level) = 0;
-
- // Called to neuter ENCRYPTION_INITIAL data (without discarding initial keys).
- virtual void NeuterUnencryptedData() = 0;
-
- // Called to neuter data of HANDSHAKE_DATA packet number space. Only used in
- // QUIC crypto. This is called 1) when a client switches to forward secure
- // encryption level and 2) a server successfully processes a forward secure
- // packet.
- virtual void NeuterHandshakeData() = 0;
-
- // Called when 0-RTT data is rejected by the server. This is only called in
- // TLS handshakes and only called on clients.
- virtual void OnZeroRttRejected(int reason) = 0;
-
- // Fills in |params| with values from the delegate's QuicConfig.
- // Returns whether the operation succeeded.
- virtual bool FillTransportParameters(TransportParameters* params) = 0;
-
- // Read |params| and apply the values to the delegate's QuicConfig.
- // On failure, returns a QuicErrorCode and saves a detailed error in
- // |error_details|.
- virtual QuicErrorCode ProcessTransportParameters(
- const TransportParameters& params, bool is_resumption,
- std::string* error_details) = 0;
-
- // Called at the end of an handshake operation callback.
- virtual void OnHandshakeCallbackDone() = 0;
-
- // Whether a packet flusher is currently attached.
- virtual bool PacketFlusherAttached() const = 0;
-
- // Get the QUIC version currently in use. tls_handshaker needs this to pass
- // to crypto_utils to apply version-dependent HKDF labels.
- virtual ParsedQuicVersion parsed_version() const = 0;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_HANDSHAKER_DELEGATE_INTERFACE_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/http/capsule.cc b/chromium/net/third_party/quiche/src/quic/core/http/capsule.cc
deleted file mode 100644
index 21df166de3c..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/http/capsule.cc
+++ /dev/null
@@ -1,749 +0,0 @@
-// Copyright (c) 2021 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 "quic/core/http/capsule.h"
-
-#include <type_traits>
-
-#include "absl/strings/escaping.h"
-#include "absl/strings/str_cat.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/http/http_frames.h"
-#include "quic/core/quic_data_reader.h"
-#include "quic/core/quic_data_writer.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "common/platform/api/quiche_logging.h"
-
-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";
- }
- return absl::StrCat("Unknown(", static_cast<uint64_t>(capsule_type), ")");
-}
-
-std::ostream& operator<<(std::ostream& os, const CapsuleType& capsule_type) {
- os << CapsuleTypeToString(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:
- static_assert(
- std::is_standard_layout<LegacyDatagramCapsule>::value &&
- std::is_trivially_destructible<LegacyDatagramCapsule>::value,
- "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 &&
- std::is_trivially_destructible<
- DatagramWithoutContextCapsule>::value,
- "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 &&
- std::is_trivially_destructible<
- CloseWebTransportSessionCapsule>::value,
- "All capsule structs must have these properties");
- close_web_transport_session_capsule_ = CloseWebTransportSessionCapsule();
- break;
- default:
- unknown_capsule_data_ = absl::string_view();
- break;
- }
-}
-
-// 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);
- capsule.datagram_without_context_capsule().http_datagram_payload =
- http_datagram_payload;
- return capsule;
-}
-
-// 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);
- capsule.close_web_transport_session_capsule().error_code = error_code;
- capsule.close_web_transport_session_capsule().error_message = error_message;
- return capsule;
-}
-
-// static
-Capsule Capsule::Unknown(uint64_t capsule_type,
- absl::string_view unknown_capsule_data) {
- Capsule capsule(static_cast<CapsuleType>(capsule_type));
- capsule.unknown_capsule_data() = unknown_capsule_data;
- return capsule;
-}
-
-Capsule& Capsule::operator=(const Capsule& other) {
- capsule_type_ = other.capsule_type_;
- switch (capsule_type_) {
- 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_;
- break;
- default:
- unknown_capsule_data_ = other.unknown_capsule_data_;
- break;
- }
- return *this;
-}
-
-Capsule::Capsule(const Capsule& other) : Capsule(other.capsule_type_) {
- *this = other;
-}
-
-bool Capsule::operator==(const Capsule& other) const {
- if (capsule_type_ != other.capsule_type_) {
- return false;
- }
- 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;
- 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 &&
- close_web_transport_session_capsule_.error_message ==
- other.close_web_transport_session_capsule_.error_message;
- default:
- return unknown_capsule_data_ == other.unknown_capsule_data_;
- }
-}
-
-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, "[",
- absl::BytesToHexString(
- 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,
- ",error_message=\"",
- close_web_transport_session_capsule_.error_message, "\")");
- break;
- default:
- absl::StrAppend(&rv, "[", absl::BytesToHexString(unknown_capsule_data_),
- "]");
- break;
- }
- return rv;
-}
-
-std::ostream& operator<<(std::ostream& os, const Capsule& capsule) {
- os << capsule.ToString();
- return os;
-}
-
-CapsuleParser::CapsuleParser(Visitor* visitor) : visitor_(visitor) {
- QUICHE_DCHECK_NE(visitor_, nullptr);
-}
-
-QuicBuffer SerializeCapsule(const Capsule& capsule,
- QuicBufferAllocator* allocator) {
- QuicByteCount capsule_type_length = QuicDataWriter::GetVarInt62Len(
- static_cast<uint64_t>(capsule.capsule_type()));
- QuicByteCount capsule_data_length;
- switch (capsule.capsule_type()) {
- 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) +
- capsule.close_web_transport_session_capsule().error_message.size();
- break;
- default:
- capsule_data_length = capsule.unknown_capsule_data().length();
- break;
- }
- QuicByteCount capsule_length_length =
- QuicDataWriter::GetVarInt62Len(capsule_data_length);
- QuicByteCount total_capsule_length =
- capsule_type_length + capsule_length_length + capsule_data_length;
- QuicBuffer buffer(allocator, total_capsule_length);
- QuicDataWriter writer(buffer.size(), buffer.data());
- if (!writer.WriteVarInt62(static_cast<uint64_t>(capsule.capsule_type()))) {
- QUIC_BUG(capsule type write fail) << "Failed to write CAPSULE type";
- return QuicBuffer();
- }
- if (!writer.WriteVarInt62(capsule_data_length)) {
- QUIC_BUG(capsule length write fail) << "Failed to write CAPSULE length";
- return QuicBuffer();
- }
- 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 QuicBuffer();
- }
- }
- if (!writer.WriteStringPiece(
- capsule.legacy_datagram_capsule().http_datagram_payload)) {
- QUIC_BUG(datagram capsule payload write fail)
- << "Failed to write LEGACY_DATAGRAM CAPSULE payload";
- return QuicBuffer();
- }
- 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 QuicBuffer();
- }
- 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 QuicBuffer();
- }
- break;
- case CapsuleType::DATAGRAM_WITHOUT_CONTEXT:
- if (!writer.WriteStringPiece(capsule.datagram_without_context_capsule()
- .http_datagram_payload)) {
- QUIC_BUG(datagram capsule payload write fail)
- << "Failed to write DATAGRAM_WITHOUT_CONTEXT CAPSULE payload";
- return QuicBuffer();
- }
- 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 QuicBuffer();
- }
- 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 QuicBuffer();
- }
- 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 QuicBuffer();
- }
- 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 QuicBuffer();
- }
- 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 QuicBuffer();
- }
- 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 QuicBuffer();
- }
- 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 QuicBuffer();
- }
- 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 QuicBuffer();
- }
- break;
- case CapsuleType::CLOSE_WEBTRANSPORT_SESSION:
- if (!writer.WriteUInt32(
- capsule.close_web_transport_session_capsule().error_code)) {
- QUIC_BUG(close webtransport session capsule error code write fail)
- << "Failed to write CLOSE_WEBTRANSPORT_SESSION error code";
- return QuicBuffer();
- }
- if (!writer.WriteStringPiece(
- capsule.close_web_transport_session_capsule().error_message)) {
- QUIC_BUG(close webtransport session capsule error message write fail)
- << "Failed to write CLOSE_WEBTRANSPORT_SESSION error message";
- return QuicBuffer();
- }
- break;
- default:
- if (!writer.WriteStringPiece(capsule.unknown_capsule_data())) {
- QUIC_BUG(capsule data write fail) << "Failed to write CAPSULE data";
- return QuicBuffer();
- }
- break;
- }
- if (writer.remaining() != 0) {
- QUIC_BUG(capsule write length mismatch)
- << "CAPSULE serialization wrote " << writer.length() << " instead of "
- << writer.capacity();
- return QuicBuffer();
- }
- return buffer;
-}
-
-bool CapsuleParser::IngestCapsuleFragment(absl::string_view capsule_fragment) {
- if (parsing_error_occurred_) {
- return false;
- }
- absl::StrAppend(&buffered_data_, capsule_fragment);
- while (true) {
- const size_t buffered_data_read = AttemptParseCapsule();
- if (parsing_error_occurred_) {
- QUICHE_DCHECK_EQ(buffered_data_read, 0u);
- buffered_data_.clear();
- return false;
- }
- if (buffered_data_read == 0) {
- break;
- }
- buffered_data_.erase(0, buffered_data_read);
- }
- static constexpr size_t kMaxCapsuleBufferSize = 1024 * 1024;
- if (buffered_data_.size() > kMaxCapsuleBufferSize) {
- buffered_data_.clear();
- ReportParseFailure("Refusing to buffer too much capsule data");
- return false;
- }
- return true;
-}
-
-size_t CapsuleParser::AttemptParseCapsule() {
- QUICHE_DCHECK(!parsing_error_occurred_);
- if (buffered_data_.empty()) {
- return 0;
- }
- QuicDataReader capsule_fragment_reader(buffered_data_);
- uint64_t capsule_type64;
- if (!capsule_fragment_reader.ReadVarInt62(&capsule_type64)) {
- QUIC_DVLOG(2) << "Partial read: not enough data to read capsule type";
- return 0;
- }
- absl::string_view capsule_data;
- if (!capsule_fragment_reader.ReadStringPieceVarInt62(&capsule_data)) {
- QUIC_DVLOG(2) << "Partial read: not enough data to read capsule length or "
- "full capsule data";
- return 0;
- }
- QuicDataReader capsule_data_reader(capsule_data);
- 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)) {
- ReportParseFailure(
- "Unable to parse capsule CLOSE_WEBTRANSPORT_SESSION error code");
- return 0;
- }
- capsule.close_web_transport_session_capsule().error_message =
- capsule_data_reader.ReadRemainingPayload();
- break;
- default:
- capsule.unknown_capsule_data() =
- capsule_data_reader.ReadRemainingPayload();
- }
- if (!visitor_->OnCapsule(capsule)) {
- ReportParseFailure("Visitor failed to process capsule");
- return 0;
- }
- return capsule_fragment_reader.PreviouslyReadPayload().length();
-}
-
-void CapsuleParser::ReportParseFailure(const std::string& error_message) {
- if (parsing_error_occurred_) {
- QUIC_BUG(multiple parse errors) << "Experienced multiple parse failures";
- return;
- }
- parsing_error_occurred_ = true;
- visitor_->OnCapsuleParseFailure(error_message);
-}
-
-void CapsuleParser::ErrorIfThereIsRemainingBufferedData() {
- if (parsing_error_occurred_) {
- return;
- }
- if (!buffered_data_.empty()) {
- ReportParseFailure("Incomplete capsule left at the end of the stream");
- }
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/http/capsule.h b/chromium/net/third_party/quiche/src/quic/core/http/capsule.h
deleted file mode 100644
index 42190bba5bf..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/http/capsule.h
+++ /dev/null
@@ -1,291 +0,0 @@
-// Copyright (c) 2021 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_HTTP_CAPSULE_H_
-#define QUICHE_QUIC_CORE_HTTP_CAPSULE_H_
-
-#include <cstdint>
-#include <string>
-
-#include "absl/strings/str_cat.h"
-#include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
-#include "quic/core/quic_buffer_allocator.h"
-#include "quic/core/quic_data_reader.h"
-#include "quic/core/quic_types.h"
-#include "common/platform/api/quiche_logging.h"
-
-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,
- CLOSE_WEBTRANSPORT_SESSION = 0x2843,
-};
-
-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;
-};
-
-// Capsule from draft-ietf-masque-h3-datagram.
-// IMPORTANT NOTE: Capsule does not own any of the absl::string_view memory it
-// points to. Strings saved into a capsule must outlive the capsule object. Any
-// code that sees a capsule in a callback needs to either process it immediately
-// or perform its own deep copy.
-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 = "");
- static Capsule Unknown(
- uint64_t capsule_type,
- absl::string_view unknown_capsule_data = absl::string_view());
-
- explicit Capsule(CapsuleType capsule_type);
- Capsule(const Capsule& other);
- Capsule& operator=(const Capsule& other);
- bool operator==(const Capsule& other) const;
-
- // Human-readable information string for debugging purposes.
- std::string ToString() const;
- friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
- const Capsule& capsule);
-
- CapsuleType capsule_type() const { return capsule_type_; }
- LegacyDatagramCapsule& legacy_datagram_capsule() {
- QUICHE_DCHECK_EQ(capsule_type_, CapsuleType::LEGACY_DATAGRAM);
- return legacy_datagram_capsule_;
- }
- const LegacyDatagramCapsule& legacy_datagram_capsule() const {
- 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_;
- }
- const DatagramWithoutContextCapsule& datagram_without_context_capsule()
- const {
- 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_;
- }
- const CloseWebTransportSessionCapsule& close_web_transport_session_capsule()
- const {
- QUICHE_DCHECK_EQ(capsule_type_, CapsuleType::CLOSE_WEBTRANSPORT_SESSION);
- return close_web_transport_session_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_;
- }
-
- private:
- 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_;
- };
-};
-
-namespace test {
-class CapsuleParserPeer;
-} // namespace test
-
-class QUIC_EXPORT_PRIVATE CapsuleParser {
- public:
- class QUIC_EXPORT_PRIVATE Visitor {
- public:
- virtual ~Visitor() {}
-
- // Called when a capsule has been successfully parsed. The return value
- // indicates whether the contents of the capsule are valid: if false is
- // returned, the parse operation will be considered failed and
- // OnCapsuleParseFailure will be called. Note that since Capsule does not
- // own the memory backing its string_views, that memory is only valid until
- // this callback returns. Visitors that wish to access the capsule later
- // MUST make a deep copy before this returns.
- virtual bool OnCapsule(const Capsule& capsule) = 0;
-
- virtual void OnCapsuleParseFailure(const std::string& error_message) = 0;
- };
-
- // |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.
- bool IngestCapsuleFragment(absl::string_view capsule_fragment);
-
- void ErrorIfThereIsRemainingBufferedData();
-
- friend class test::CapsuleParserPeer;
-
- private:
- // Attempts to parse a single capsule from |buffered_data_|. If a full capsule
- // is not available, returns 0. If a parsing error occurs, returns 0.
- // Otherwise, returns the number of bytes in the parsed capsule.
- 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.
- Visitor* visitor_;
-
- std::string buffered_data_;
-};
-
-// Serializes |capsule| into a newly allocated buffer.
-QUIC_EXPORT_PRIVATE QuicBuffer SerializeCapsule(const Capsule& capsule,
- QuicBufferAllocator* allocator);
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_HTTP_CAPSULE_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/http/capsule_test.cc b/chromium/net/third_party/quiche/src/quic/core/http/capsule_test.cc
deleted file mode 100644
index 2dfdef41b21..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/http/capsule_test.cc
+++ /dev/null
@@ -1,364 +0,0 @@
-// Copyright (c) 2021 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 "quic/core/http/capsule.h"
-
-#include <cstddef>
-#include <deque>
-#include <string>
-#include <vector>
-
-#include "absl/strings/escaping.h"
-#include "absl/strings/string_view.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/quic_test_utils.h"
-#include "common/test_tools/quiche_test_utils.h"
-
-using ::testing::_;
-using ::testing::InSequence;
-using ::testing::Return;
-
-namespace quic {
-namespace test {
-
-class CapsuleParserPeer {
- public:
- static std::string* buffered_data(CapsuleParser* capsule_parser) {
- return &capsule_parser->buffered_data_;
- }
-};
-
-namespace {
-
-constexpr DatagramFormatType kFakeFormatType =
- static_cast<DatagramFormatType>(0x123456);
-constexpr ContextCloseCode kFakeCloseCode =
- static_cast<ContextCloseCode>(0x654321);
-
-class MockCapsuleParserVisitor : public CapsuleParser::Visitor {
- public:
- MockCapsuleParserVisitor() {
- ON_CALL(*this, OnCapsule(_)).WillByDefault(Return(true));
- }
- ~MockCapsuleParserVisitor() override = default;
- MOCK_METHOD(bool, OnCapsule, (const Capsule& capsule), (override));
- MOCK_METHOD(void, OnCapsuleParseFailure, (const std::string& error_message),
- (override));
-};
-
-class CapsuleTest : public QuicTest {
- public:
- CapsuleTest() : capsule_parser_(&visitor_) {}
-
- void ValidateParserIsEmpty() {
- EXPECT_CALL(visitor_, OnCapsule(_)).Times(0);
- EXPECT_CALL(visitor_, OnCapsuleParseFailure(_)).Times(0);
- capsule_parser_.ErrorIfThereIsRemainingBufferedData();
- EXPECT_TRUE(CapsuleParserPeer::buffered_data(&capsule_parser_)->empty());
- }
-
- void TestSerialization(const Capsule& capsule,
- const std::string& expected_bytes) {
- QuicBuffer serialized_capsule =
- SerializeCapsule(capsule, SimpleBufferAllocator::Get());
- quiche::test::CompareCharArraysWithHexError(
- "Serialized capsule", serialized_capsule.data(),
- serialized_capsule.size(), expected_bytes.data(),
- expected_bytes.size());
- }
-
- ::testing::StrictMock<MockCapsuleParserVisitor> visitor_;
- CapsuleParser capsule_parser_;
-};
-
-TEST_F(CapsuleTest, LegacyDatagramCapsule) {
- std::string capsule_fragment = absl::HexStringToBytes(
- "80ff37a0" // LEGACY_DATAGRAM capsule type
- "08" // capsule length
- "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);
- {
- EXPECT_CALL(visitor_, OnCapsule(expected_capsule));
- ASSERT_TRUE(capsule_parser_.IngestCapsuleFragment(capsule_fragment));
- }
- ValidateParserIsEmpty();
- TestSerialization(expected_capsule, capsule_fragment);
-}
-
-TEST_F(CapsuleTest, DatagramWithoutContextCapsule) {
- std::string capsule_fragment = absl::HexStringToBytes(
- "80ff37a5" // DATAGRAM_WITHOUT_CONTEXT capsule type
- "08" // capsule length
- "a1a2a3a4a5a6a7a8" // HTTP Datagram payload
- );
- std::string datagram_payload = absl::HexStringToBytes("a1a2a3a4a5a6a7a8");
- Capsule expected_capsule = Capsule::DatagramWithoutContext(datagram_payload);
- {
- EXPECT_CALL(visitor_, OnCapsule(expected_capsule));
- ASSERT_TRUE(capsule_parser_.IngestCapsuleFragment(capsule_fragment));
- }
- ValidateParserIsEmpty();
- 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
- "09" // capsule length
- "00001234" // 0x1234 error code
- "68656c6c6f" // "hello" error message
- );
- Capsule expected_capsule = Capsule::CloseWebTransportSession(
- /*error_code=*/0x1234, /*error_message=*/"hello");
- {
- EXPECT_CALL(visitor_, OnCapsule(expected_capsule));
- ASSERT_TRUE(capsule_parser_.IngestCapsuleFragment(capsule_fragment));
- }
- ValidateParserIsEmpty();
- TestSerialization(expected_capsule, capsule_fragment);
-}
-
-TEST_F(CapsuleTest, UnknownCapsule) {
- std::string capsule_fragment = absl::HexStringToBytes(
- "33" // unknown capsule type of 0x33
- "08" // capsule length
- "a1a2a3a4a5a6a7a8" // unknown capsule data
- );
- std::string unknown_capsule_data = absl::HexStringToBytes("a1a2a3a4a5a6a7a8");
- Capsule expected_capsule = Capsule::Unknown(0x33, unknown_capsule_data);
- {
- EXPECT_CALL(visitor_, OnCapsule(expected_capsule));
- ASSERT_TRUE(capsule_parser_.IngestCapsuleFragment(capsule_fragment));
- }
- ValidateParserIsEmpty();
- TestSerialization(expected_capsule, capsule_fragment);
-}
-
-TEST_F(CapsuleTest, TwoCapsules) {
- std::string capsule_fragment = absl::HexStringToBytes(
- "80ff37a5" // DATAGRAM_WITHOUT_CONTEXT capsule type
- "08" // capsule length
- "a1a2a3a4a5a6a7a8" // HTTP Datagram payload
- "80ff37a5" // DATAGRAM_WITHOUT_CONTEXT capsule type
- "08" // capsule length
- "b1b2b3b4b5b6b7b8" // HTTP Datagram payload
- );
- std::string datagram_payload1 = absl::HexStringToBytes("a1a2a3a4a5a6a7a8");
- std::string datagram_payload2 = absl::HexStringToBytes("b1b2b3b4b5b6b7b8");
- Capsule expected_capsule1 =
- Capsule::DatagramWithoutContext(datagram_payload1);
- Capsule expected_capsule2 =
- Capsule::DatagramWithoutContext(datagram_payload2);
- {
- InSequence s;
- EXPECT_CALL(visitor_, OnCapsule(expected_capsule1));
- EXPECT_CALL(visitor_, OnCapsule(expected_capsule2));
- ASSERT_TRUE(capsule_parser_.IngestCapsuleFragment(capsule_fragment));
- }
- ValidateParserIsEmpty();
-}
-
-TEST_F(CapsuleTest, TwoCapsulesPartialReads) {
- std::string capsule_fragment1 = absl::HexStringToBytes(
- "80ff37a5" // first capsule DATAGRAM_WITHOUT_CONTEXT capsule type
- "08" // frist capsule length
- "a1a2a3a4" // first half of HTTP Datagram payload of first capsule
- );
- std::string capsule_fragment2 = absl::HexStringToBytes(
- "a5a6a7a8" // second half of HTTP Datagram payload 1
- "80ff37a5" // second capsule DATAGRAM_WITHOUT_CONTEXT capsule type
- );
- std::string capsule_fragment3 = absl::HexStringToBytes(
- "08" // second capsule length
- "b1b2b3b4b5b6b7b8" // HTTP Datagram payload of second capsule
- );
- capsule_parser_.ErrorIfThereIsRemainingBufferedData();
- std::string datagram_payload1 = absl::HexStringToBytes("a1a2a3a4a5a6a7a8");
- std::string datagram_payload2 = absl::HexStringToBytes("b1b2b3b4b5b6b7b8");
- Capsule expected_capsule1 =
- Capsule::DatagramWithoutContext(datagram_payload1);
- Capsule expected_capsule2 =
- Capsule::DatagramWithoutContext(datagram_payload2);
- {
- InSequence s;
- EXPECT_CALL(visitor_, OnCapsule(expected_capsule1));
- EXPECT_CALL(visitor_, OnCapsule(expected_capsule2));
- ASSERT_TRUE(capsule_parser_.IngestCapsuleFragment(capsule_fragment1));
- ASSERT_TRUE(capsule_parser_.IngestCapsuleFragment(capsule_fragment2));
- ASSERT_TRUE(capsule_parser_.IngestCapsuleFragment(capsule_fragment3));
- }
- ValidateParserIsEmpty();
-}
-
-TEST_F(CapsuleTest, TwoCapsulesOneByteAtATime) {
- std::string capsule_fragment = absl::HexStringToBytes(
- "80ff37a5" // DATAGRAM_WITHOUT_CONTEXT capsule type
- "08" // capsule length
- "a1a2a3a4a5a6a7a8" // HTTP Datagram payload
- "80ff37a5" // DATAGRAM_WITHOUT_CONTEXT capsule type
- "08" // capsule length
- "b1b2b3b4b5b6b7b8" // HTTP Datagram payload
- );
- std::string datagram_payload1 = absl::HexStringToBytes("a1a2a3a4a5a6a7a8");
- std::string datagram_payload2 = absl::HexStringToBytes("b1b2b3b4b5b6b7b8");
- Capsule expected_capsule1 =
- Capsule::DatagramWithoutContext(datagram_payload1);
- Capsule expected_capsule2 =
- Capsule::DatagramWithoutContext(datagram_payload2);
- for (size_t i = 0; i < capsule_fragment.size(); i++) {
- if (i < capsule_fragment.size() / 2 - 1) {
- EXPECT_CALL(visitor_, OnCapsule(_)).Times(0);
- ASSERT_TRUE(
- capsule_parser_.IngestCapsuleFragment(capsule_fragment.substr(i, 1)));
- } else if (i == capsule_fragment.size() / 2 - 1) {
- EXPECT_CALL(visitor_, OnCapsule(expected_capsule1));
- ASSERT_TRUE(
- capsule_parser_.IngestCapsuleFragment(capsule_fragment.substr(i, 1)));
- EXPECT_TRUE(CapsuleParserPeer::buffered_data(&capsule_parser_)->empty());
- } else if (i < capsule_fragment.size() - 1) {
- EXPECT_CALL(visitor_, OnCapsule(_)).Times(0);
- ASSERT_TRUE(
- capsule_parser_.IngestCapsuleFragment(capsule_fragment.substr(i, 1)));
- } else {
- EXPECT_CALL(visitor_, OnCapsule(expected_capsule2));
- ASSERT_TRUE(
- capsule_parser_.IngestCapsuleFragment(capsule_fragment.substr(i, 1)));
- EXPECT_TRUE(CapsuleParserPeer::buffered_data(&capsule_parser_)->empty());
- }
- }
- capsule_parser_.ErrorIfThereIsRemainingBufferedData();
- EXPECT_TRUE(CapsuleParserPeer::buffered_data(&capsule_parser_)->empty());
-}
-
-TEST_F(CapsuleTest, PartialCapsuleThenError) {
- std::string capsule_fragment = absl::HexStringToBytes(
- "80ff37a5" // DATAGRAM_WITHOUT_CONTEXT capsule type
- "08" // capsule length
- "a1a2a3a4" // first half of HTTP Datagram payload
- );
- EXPECT_CALL(visitor_, OnCapsule(_)).Times(0);
- {
- EXPECT_CALL(visitor_, OnCapsuleParseFailure(_)).Times(0);
- ASSERT_TRUE(capsule_parser_.IngestCapsuleFragment(capsule_fragment));
- }
- {
- EXPECT_CALL(visitor_,
- OnCapsuleParseFailure(
- "Incomplete capsule left at the end of the stream"));
- capsule_parser_.ErrorIfThereIsRemainingBufferedData();
- }
-}
-
-TEST_F(CapsuleTest, RejectOverlyLongCapsule) {
- std::string capsule_fragment = absl::HexStringToBytes(
- "33" // unknown capsule type of 0x33
- "80123456" // capsule length
- ) +
- std::string(1111111, '?');
- EXPECT_CALL(visitor_, OnCapsuleParseFailure(
- "Refusing to buffer too much capsule data"));
- EXPECT_FALSE(capsule_parser_.IngestCapsuleFragment(capsule_fragment));
-}
-
-} // namespace
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/http/end_to_end_test.cc b/chromium/net/third_party/quiche/src/quic/core/http/end_to_end_test.cc
deleted file mode 100644
index cad9cacb022..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/http/end_to_end_test.cc
+++ /dev/null
@@ -1,6991 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <cstddef>
-#include <cstdint>
-#include <list>
-#include <memory>
-#include <ostream>
-#include <string>
-#include <utility>
-#include <vector>
-
-#include "absl/strings/str_cat.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/crypto/null_encrypter.h"
-#include "quic/core/crypto/quic_client_session_cache.h"
-#include "quic/core/http/http_constants.h"
-#include "quic/core/http/quic_spdy_client_stream.h"
-#include "quic/core/http/web_transport_http3.h"
-#include "quic/core/quic_connection.h"
-#include "quic/core/quic_data_writer.h"
-#include "quic/core/quic_epoll_connection_helper.h"
-#include "quic/core/quic_error_codes.h"
-#include "quic/core/quic_framer.h"
-#include "quic/core/quic_packet_creator.h"
-#include "quic/core/quic_packet_writer_wrapper.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_session.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_epoll.h"
-#include "quic/platform/api/quic_error_code_wrappers.h"
-#include "quic/platform/api/quic_expect_bug.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/platform/api/quic_port_utils.h"
-#include "quic/platform/api/quic_sleep.h"
-#include "quic/platform/api/quic_socket_address.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/platform/api/quic_test_loopback.h"
-#include "quic/test_tools/bad_packet_writer.h"
-#include "quic/test_tools/crypto_test_utils.h"
-#include "quic/test_tools/packet_dropping_test_writer.h"
-#include "quic/test_tools/packet_reordering_writer.h"
-#include "quic/test_tools/qpack/qpack_encoder_peer.h"
-#include "quic/test_tools/qpack/qpack_encoder_test_utils.h"
-#include "quic/test_tools/qpack/qpack_test_utils.h"
-#include "quic/test_tools/quic_client_peer.h"
-#include "quic/test_tools/quic_client_session_cache_peer.h"
-#include "quic/test_tools/quic_config_peer.h"
-#include "quic/test_tools/quic_connection_peer.h"
-#include "quic/test_tools/quic_dispatcher_peer.h"
-#include "quic/test_tools/quic_flow_controller_peer.h"
-#include "quic/test_tools/quic_sent_packet_manager_peer.h"
-#include "quic/test_tools/quic_server_peer.h"
-#include "quic/test_tools/quic_session_peer.h"
-#include "quic/test_tools/quic_spdy_session_peer.h"
-#include "quic/test_tools/quic_spdy_stream_peer.h"
-#include "quic/test_tools/quic_stream_id_manager_peer.h"
-#include "quic/test_tools/quic_stream_peer.h"
-#include "quic/test_tools/quic_stream_sequencer_peer.h"
-#include "quic/test_tools/quic_test_backend.h"
-#include "quic/test_tools/quic_test_client.h"
-#include "quic/test_tools/quic_test_server.h"
-#include "quic/test_tools/quic_test_utils.h"
-#include "quic/test_tools/quic_transport_test_tools.h"
-#include "quic/test_tools/server_thread.h"
-#include "quic/tools/quic_backend_response.h"
-#include "quic/tools/quic_client.h"
-#include "quic/tools/quic_memory_cache_backend.h"
-#include "quic/tools/quic_server.h"
-#include "quic/tools/quic_simple_client_stream.h"
-#include "quic/tools/quic_simple_server_stream.h"
-
-using spdy::kV3LowestPriority;
-using spdy::SpdyFramer;
-using spdy::SpdyHeaderBlock;
-using spdy::SpdySerializedFrame;
-using spdy::SpdySettingsIR;
-using ::testing::_;
-using ::testing::Assign;
-using ::testing::Invoke;
-using ::testing::NiceMock;
-using ::testing::UnorderedElementsAreArray;
-
-namespace quic {
-namespace test {
-namespace {
-
-const char kFooResponseBody[] = "Artichoke hearts make me happy.";
-const char kBarResponseBody[] = "Palm hearts are pretty delicious, also.";
-const char kTestUserAgentId[] = "quic/core/http/end_to_end_test.cc";
-const float kSessionToStreamRatio = 1.5;
-
-// Run all tests with the cross products of all versions.
-struct TestParams {
- TestParams(const ParsedQuicVersion& version, QuicTag congestion_control_tag)
- : version(version), congestion_control_tag(congestion_control_tag) {}
-
- friend std::ostream& operator<<(std::ostream& os, const TestParams& p) {
- os << "{ version: " << ParsedQuicVersionToString(p.version);
- os << " congestion_control_tag: "
- << QuicTagToString(p.congestion_control_tag) << " }";
- return os;
- }
-
- ParsedQuicVersion version;
- QuicTag congestion_control_tag;
-};
-
-// Used by ::testing::PrintToStringParamName().
-std::string PrintToString(const TestParams& p) {
- std::string rv = absl::StrCat(ParsedQuicVersionToString(p.version), "_",
- QuicTagToString(p.congestion_control_tag));
- std::replace(rv.begin(), rv.end(), ',', '_');
- std::replace(rv.begin(), rv.end(), ' ', '_');
- return rv;
-}
-
-// 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.
-
- return params;
-}
-
-void WriteHeadersOnStream(QuicSpdyStream* stream) {
- // Since QuicSpdyStream uses QuicHeaderList::empty() to detect too large
- // headers, it also fails when receiving empty headers.
- SpdyHeaderBlock headers;
- headers[":authority"] = "test.example.com:443";
- headers[":path"] = "/path";
- headers[":method"] = "GET";
- headers[":scheme"] = "https";
- stream->WriteHeaders(std::move(headers), /* fin = */ false, nullptr);
-}
-
-class ServerDelegate : public PacketDroppingTestWriter::Delegate {
- public:
- explicit ServerDelegate(QuicDispatcher* dispatcher)
- : dispatcher_(dispatcher) {}
- ~ServerDelegate() override = default;
- void OnCanWrite() override { dispatcher_->OnCanWrite(); }
-
- private:
- QuicDispatcher* dispatcher_;
-};
-
-class ClientDelegate : public PacketDroppingTestWriter::Delegate {
- public:
- explicit ClientDelegate(QuicClient* client) : client_(client) {}
- ~ClientDelegate() override = default;
- void OnCanWrite() override {
- QuicEpollEvent event(EPOLLOUT);
- client_->epoll_network_helper()->OnEvent(client_->GetLatestFD(), &event);
- }
-
- private:
- QuicClient* client_;
-};
-
-class EndToEndTest : public QuicTestWithParam<TestParams> {
- protected:
- EndToEndTest()
- : initialized_(false),
- connect_to_server_on_initialize_(true),
- server_address_(QuicSocketAddress(TestLoopback(),
- QuicPickServerPortForTestsOrDie())),
- server_hostname_("test.example.com"),
- client_writer_(nullptr),
- server_writer_(nullptr),
- version_(GetParam().version),
- client_supported_versions_({version_}),
- server_supported_versions_(CurrentSupportedVersions()),
- chlo_multiplier_(0),
- stream_factory_(nullptr),
- expected_server_connection_id_length_(kQuicDefaultConnectionIdLength) {
- QUIC_LOG(INFO) << "Using Configuration: " << GetParam();
-
- // Use different flow control windows for client/server.
- client_config_.SetInitialStreamFlowControlWindowToSend(
- 2 * kInitialStreamFlowControlWindowForTest);
- client_config_.SetInitialSessionFlowControlWindowToSend(
- 2 * kInitialSessionFlowControlWindowForTest);
- server_config_.SetInitialStreamFlowControlWindowToSend(
- 3 * kInitialStreamFlowControlWindowForTest);
- server_config_.SetInitialSessionFlowControlWindowToSend(
- 3 * kInitialSessionFlowControlWindowForTest);
-
- // The default idle timeouts can be too strict when running on a busy
- // machine.
- const QuicTime::Delta timeout = QuicTime::Delta::FromSeconds(30);
- client_config_.set_max_time_before_crypto_handshake(timeout);
- client_config_.set_max_idle_time_before_crypto_handshake(timeout);
- server_config_.set_max_time_before_crypto_handshake(timeout);
- server_config_.set_max_idle_time_before_crypto_handshake(timeout);
-
- AddToCache("/foo", 200, kFooResponseBody);
- AddToCache("/bar", 200, kBarResponseBody);
- // Enable fixes for bugs found in tests and prod.
- }
-
- ~EndToEndTest() override { QuicRecyclePort(server_address_.port()); }
-
- virtual void CreateClientWithWriter() {
- client_.reset(CreateQuicClient(client_writer_));
- }
-
- QuicTestClient* CreateQuicClient(QuicPacketWriterWrapper* writer) {
- QuicTestClient* client =
- new QuicTestClient(server_address_, server_hostname_, client_config_,
- client_supported_versions_,
- crypto_test_utils::ProofVerifierForTesting(),
- std::make_unique<QuicClientSessionCache>());
- client->SetUserAgentID(kTestUserAgentId);
- client->UseWriter(writer);
- if (!pre_shared_key_client_.empty()) {
- client->client()->SetPreSharedKey(pre_shared_key_client_);
- }
- client->UseConnectionIdLength(override_server_connection_id_length_);
- 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;
- }
-
- void set_smaller_flow_control_receive_window() {
- const uint32_t kClientIFCW = 64 * 1024;
- const uint32_t kServerIFCW = 1024 * 1024;
- set_client_initial_stream_flow_control_receive_window(kClientIFCW);
- set_client_initial_session_flow_control_receive_window(
- kSessionToStreamRatio * kClientIFCW);
- set_server_initial_stream_flow_control_receive_window(kServerIFCW);
- set_server_initial_session_flow_control_receive_window(
- kSessionToStreamRatio * kServerIFCW);
- }
-
- void set_client_initial_stream_flow_control_receive_window(uint32_t window) {
- ASSERT_TRUE(client_ == nullptr);
- QUIC_DLOG(INFO) << "Setting client initial stream flow control window: "
- << window;
- client_config_.SetInitialStreamFlowControlWindowToSend(window);
- }
-
- void set_client_initial_session_flow_control_receive_window(uint32_t window) {
- ASSERT_TRUE(client_ == nullptr);
- QUIC_DLOG(INFO) << "Setting client initial session flow control window: "
- << window;
- client_config_.SetInitialSessionFlowControlWindowToSend(window);
- }
-
- void set_client_initial_max_stream_data_incoming_bidirectional(
- uint32_t window) {
- ASSERT_TRUE(client_ == nullptr);
- QUIC_DLOG(INFO)
- << "Setting client initial max stream data incoming bidirectional: "
- << window;
- client_config_.SetInitialMaxStreamDataBytesIncomingBidirectionalToSend(
- window);
- }
-
- void set_server_initial_max_stream_data_outgoing_bidirectional(
- uint32_t window) {
- ASSERT_TRUE(client_ == nullptr);
- QUIC_DLOG(INFO)
- << "Setting server initial max stream data outgoing bidirectional: "
- << window;
- server_config_.SetInitialMaxStreamDataBytesOutgoingBidirectionalToSend(
- window);
- }
-
- void set_server_initial_stream_flow_control_receive_window(uint32_t window) {
- ASSERT_TRUE(server_thread_ == nullptr);
- QUIC_DLOG(INFO) << "Setting server initial stream flow control window: "
- << window;
- server_config_.SetInitialStreamFlowControlWindowToSend(window);
- }
-
- void set_server_initial_session_flow_control_receive_window(uint32_t window) {
- ASSERT_TRUE(server_thread_ == nullptr);
- QUIC_DLOG(INFO) << "Setting server initial session flow control window: "
- << window;
- server_config_.SetInitialSessionFlowControlWindowToSend(window);
- }
-
- const QuicSentPacketManager* GetSentPacketManagerFromFirstServerSession() {
- QuicConnection* server_connection = GetServerConnection();
- if (server_connection == nullptr) {
- ADD_FAILURE() << "Missing server connection";
- return nullptr;
- }
- return &server_connection->sent_packet_manager();
- }
-
- const QuicSentPacketManager* GetSentPacketManagerFromClientSession() {
- QuicConnection* client_connection = GetClientConnection();
- if (client_connection == nullptr) {
- ADD_FAILURE() << "Missing client connection";
- return nullptr;
- }
- return &client_connection->sent_packet_manager();
- }
-
- QuicSpdyClientSession* GetClientSession() {
- if (!client_) {
- ADD_FAILURE() << "Missing QuicTestClient";
- return nullptr;
- }
- if (client_->client() == nullptr) {
- ADD_FAILURE() << "Missing MockableQuicClient";
- return nullptr;
- }
- return client_->client()->client_session();
- }
-
- QuicConnection* GetClientConnection() {
- QuicSpdyClientSession* client_session = GetClientSession();
- if (client_session == nullptr) {
- ADD_FAILURE() << "Missing client session";
- return nullptr;
- }
- return client_session->connection();
- }
-
- QuicConnection* GetServerConnection() {
- QuicSpdySession* server_session = GetServerSession();
- if (server_session == nullptr) {
- ADD_FAILURE() << "Missing server session";
- return nullptr;
- }
- return server_session->connection();
- }
-
- QuicSpdySession* GetServerSession() {
- if (!server_thread_) {
- ADD_FAILURE() << "Missing server thread";
- return nullptr;
- }
- QuicServer* quic_server = server_thread_->server();
- if (quic_server == nullptr) {
- ADD_FAILURE() << "Missing server";
- return nullptr;
- }
- QuicDispatcher* dispatcher = QuicServerPeer::GetDispatcher(quic_server);
- if (dispatcher == nullptr) {
- ADD_FAILURE() << "Missing dispatcher";
- return nullptr;
- }
- if (dispatcher->NumSessions() == 0) {
- ADD_FAILURE() << "Empty dispatcher session map";
- return nullptr;
- }
- EXPECT_EQ(1u, dispatcher->NumSessions());
- return static_cast<QuicSpdySession*>(
- QuicDispatcherPeer::GetFirstSessionIfAny(dispatcher));
- }
-
- bool Initialize() {
- 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);
- copt = client_extra_copts_;
-
- // TODO(nimia): Consider setting the congestion control algorithm for the
- // client as well according to the test parameter.
- copt.push_back(GetParam().congestion_control_tag);
- copt.push_back(k2PTO);
- if (version_.HasIetfQuicFrames()) {
- copt.push_back(kILD0);
- }
- copt.push_back(kPLE1);
- if (!GetQuicReloadableFlag(
- quic_remove_connection_migration_connection_option)) {
- copt.push_back(kRVCM);
- }
- client_config_.SetConnectionOptionsToSend(copt);
-
- // Start the server first, because CreateQuicClient() attempts
- // to connect to the server.
- StartServer();
-
- if (!connect_to_server_on_initialize_) {
- initialized_ = true;
- return true;
- }
-
- CreateClientWithWriter();
- if (!client_) {
- ADD_FAILURE() << "Missing QuicTestClient";
- return false;
- }
- MockableQuicClient* client = client_->client();
- if (client == nullptr) {
- ADD_FAILURE() << "Missing MockableQuicClient";
- return false;
- }
- static QuicEpollEvent event(EPOLLOUT);
- if (client_writer_ != nullptr) {
- QuicConnection* client_connection = GetClientConnection();
- if (client_connection == nullptr) {
- ADD_FAILURE() << "Missing client connection";
- return false;
- }
- client_writer_->Initialize(
- QuicConnectionPeer::GetHelper(client_connection),
- QuicConnectionPeer::GetAlarmFactory(client_connection),
- std::make_unique<ClientDelegate>(client));
- }
- initialized_ = true;
- return client->connected();
- }
-
- void SetUp() override {
- // The ownership of these gets transferred to the QuicPacketWriterWrapper
- // when Initialize() is executed.
- client_writer_ = new PacketDroppingTestWriter();
- server_writer_ = new PacketDroppingTestWriter();
- }
-
- void TearDown() override {
- EXPECT_TRUE(initialized_) << "You must call Initialize() in every test "
- << "case. Otherwise, your test will leak memory.";
- QuicConnection* client_connection = GetClientConnection();
- if (client_connection != nullptr) {
- client_connection->set_debug_visitor(nullptr);
- } else {
- ADD_FAILURE() << "Missing client connection";
- }
- StopServer();
- }
-
- void StartServer() {
- auto* test_server = new 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_);
- if (chlo_multiplier_ != 0) {
- server_thread_->server()->SetChloMultiplier(chlo_multiplier_);
- }
- if (!pre_shared_key_server_.empty()) {
- server_thread_->server()->SetPreSharedKey(pre_shared_key_server_);
- }
- server_thread_->Initialize();
- server_address_ =
- QuicSocketAddress(server_address_.host(), server_thread_->GetPort());
- QuicDispatcher* dispatcher =
- QuicServerPeer::GetDispatcher(server_thread_->server());
- QuicDispatcherPeer::UseWriter(dispatcher, server_writer_);
-
- server_writer_->Initialize(QuicDispatcherPeer::GetHelper(dispatcher),
- QuicDispatcherPeer::GetAlarmFactory(dispatcher),
- std::make_unique<ServerDelegate>(dispatcher));
- if (stream_factory_ != nullptr) {
- static_cast<QuicTestServer*>(server_thread_->server())
- ->SetSpdyStreamFactory(stream_factory_);
- }
-
- server_thread_->Start();
- }
-
- void StopServer() {
- if (server_thread_) {
- server_thread_->Quit();
- server_thread_->Join();
- }
- }
-
- void AddToCache(absl::string_view path, int response_code,
- absl::string_view body) {
- memory_cache_backend_.AddSimpleResponse(server_hostname_, path,
- response_code, body);
- }
-
- void SetPacketLossPercentage(int32_t loss) {
- client_writer_->set_fake_packet_loss_percentage(loss);
- server_writer_->set_fake_packet_loss_percentage(loss);
- }
-
- void SetPacketSendDelay(QuicTime::Delta delay) {
- client_writer_->set_fake_packet_delay(delay);
- server_writer_->set_fake_packet_delay(delay);
- }
-
- void SetReorderPercentage(int32_t reorder) {
- client_writer_->set_fake_reorder_percentage(reorder);
- server_writer_->set_fake_reorder_percentage(reorder);
- }
-
- // Verifies that the client and server connections were both free of packets
- // being discarded, based on connection stats.
- // Calls server_thread_ Pause() and Resume(), which may only be called once
- // per test.
- void VerifyCleanConnection(bool had_packet_loss) {
- QuicConnection* client_connection = GetClientConnection();
- if (client_connection == nullptr) {
- ADD_FAILURE() << "Missing client connection";
- return;
- }
- QuicConnectionStats client_stats = client_connection->GetStats();
- // TODO(ianswett): Determine why this becomes even more flaky with BBR
- // enabled. b/62141144
- if (!had_packet_loss && !GetQuicReloadableFlag(quic_default_to_bbr)) {
- EXPECT_EQ(0u, client_stats.packets_lost);
- }
- EXPECT_EQ(0u, client_stats.packets_discarded);
- // When client starts with an unsupported version, the version negotiation
- // packet sent by server for the old connection (respond for the connection
- // close packet) will be dropped by the client.
- if (!ServerSendsVersionNegotiation()) {
- EXPECT_EQ(0u, client_stats.packets_dropped);
- }
- if (!version_.UsesTls()) {
- // Only enforce this for QUIC crypto because accounting of number of
- // packets received, processed gets complicated with packets coalescing
- // and key dropping. For example, a received undecryptable coalesced
- // packet can be processed later and each sub-packet increases
- // packets_processed.
- EXPECT_EQ(client_stats.packets_received, client_stats.packets_processed);
- }
-
- if (!server_thread_) {
- ADD_FAILURE() << "Missing server thread";
- return;
- }
- server_thread_->Pause();
- QuicSpdySession* server_session = GetServerSession();
- if (server_session != nullptr) {
- QuicConnection* server_connection = server_session->connection();
- if (server_connection != nullptr) {
- QuicConnectionStats server_stats = server_connection->GetStats();
- if (!had_packet_loss) {
- EXPECT_EQ(0u, server_stats.packets_lost);
- }
- EXPECT_EQ(0u, server_stats.packets_discarded);
- } else {
- ADD_FAILURE() << "Missing server connection";
- }
- } else {
- ADD_FAILURE() << "Missing server session";
- }
- // TODO(ianswett): Restore the check for packets_dropped equals 0.
- // The expect for packets received is equal to packets processed fails
- // due to version negotiation packets.
- server_thread_->Resume();
- }
-
- // Returns true when client starts with an unsupported version, and client
- // closes connection when version negotiation is received.
- bool ServerSendsVersionNegotiation() {
- return client_supported_versions_[0] != version_;
- }
-
- bool SupportsIetfQuicWithTls(ParsedQuicVersion version) {
- return version.HasIetfInvariantHeader() &&
- version.handshake_protocol == PROTOCOL_TLS1_3;
- }
-
- static void ExpectFlowControlsSynced(QuicSession* client,
- QuicSession* server) {
- EXPECT_EQ(
- QuicFlowControllerPeer::SendWindowSize(client->flow_controller()),
- QuicFlowControllerPeer::ReceiveWindowSize(server->flow_controller()));
- EXPECT_EQ(
- QuicFlowControllerPeer::ReceiveWindowSize(client->flow_controller()),
- QuicFlowControllerPeer::SendWindowSize(server->flow_controller()));
- }
-
- static void ExpectFlowControlsSynced(QuicStream* client, QuicStream* server) {
- EXPECT_EQ(QuicStreamPeer::SendWindowSize(client),
- QuicStreamPeer::ReceiveWindowSize(server));
- EXPECT_EQ(QuicStreamPeer::ReceiveWindowSize(client),
- QuicStreamPeer::SendWindowSize(server));
- }
-
- // Must be called before Initialize to have effect.
- void SetSpdyStreamFactory(QuicTestServer::StreamFactory* factory) {
- stream_factory_ = factory;
- }
-
- QuicStreamId GetNthClientInitiatedBidirectionalId(int n) {
- return GetNthClientInitiatedBidirectionalStreamId(
- version_.transport_version, n);
- }
-
- QuicStreamId GetNthServerInitiatedBidirectionalId(int n) {
- return GetNthServerInitiatedBidirectionalStreamId(
- version_.transport_version, n);
- }
-
- bool CheckResponseHeaders(QuicTestClient* client,
- const std::string& expected_status) {
- const spdy::SpdyHeaderBlock* response_headers = client->response_headers();
- auto it = response_headers->find(":status");
- if (it == response_headers->end()) {
- ADD_FAILURE() << "Did not find :status header in response";
- return false;
- }
- if (it->second != expected_status) {
- ADD_FAILURE() << "Got bad :status response: \"" << it->second << "\"";
- return false;
- }
- return true;
- }
-
- bool CheckResponseHeaders(QuicTestClient* client) {
- return CheckResponseHeaders(client, "200");
- }
-
- bool CheckResponseHeaders(const std::string& expected_status) {
- return CheckResponseHeaders(client_.get(), expected_status);
- }
-
- bool CheckResponseHeaders() { return CheckResponseHeaders(client_.get()); }
-
- bool CheckResponse(QuicTestClient* client,
- const std::string& received_response,
- const std::string& expected_response) {
- EXPECT_THAT(client_->stream_error(), IsQuicStreamNoError());
- EXPECT_THAT(client_->connection_error(), IsQuicNoError());
-
- if (received_response.empty() && !expected_response.empty()) {
- ADD_FAILURE() << "Failed to get any response for request";
- return false;
- }
- if (received_response != expected_response) {
- ADD_FAILURE() << "Got wrong response: \"" << received_response << "\"";
- return false;
- }
- return CheckResponseHeaders(client);
- }
-
- bool SendSynchronousRequestAndCheckResponse(
- QuicTestClient* client, const std::string& request,
- const std::string& expected_response) {
- std::string received_response = client->SendSynchronousRequest(request);
- return CheckResponse(client, received_response, expected_response);
- }
-
- bool SendSynchronousRequestAndCheckResponse(
- const std::string& request, const std::string& expected_response) {
- return SendSynchronousRequestAndCheckResponse(client_.get(), request,
- expected_response);
- }
-
- bool SendSynchronousFooRequestAndCheckResponse(QuicTestClient* client) {
- return SendSynchronousRequestAndCheckResponse(client, "/foo",
- kFooResponseBody);
- }
-
- bool SendSynchronousFooRequestAndCheckResponse() {
- return SendSynchronousFooRequestAndCheckResponse(client_.get());
- }
-
- bool SendSynchronousBarRequestAndCheckResponse() {
- std::string received_response = client_->SendSynchronousRequest("/bar");
- return CheckResponse(client_.get(), received_response, kBarResponseBody);
- }
-
- bool WaitForFooResponseAndCheckIt(QuicTestClient* client) {
- client->WaitForResponse();
- std::string received_response = client->response_body();
- return CheckResponse(client_.get(), received_response, kFooResponseBody);
- }
-
- bool WaitForFooResponseAndCheckIt() {
- return WaitForFooResponseAndCheckIt(client_.get());
- }
-
- WebTransportHttp3* CreateWebTransportSession(
- const std::string& path, bool wait_for_server_response,
- QuicSpdyStream** connect_stream_out = nullptr) {
- // Wait until we receive the settings from the server indicating
- // WebTransport support.
- client_->WaitUntil(
- 2000, [this]() { return GetClientSession()->SupportsWebTransport(); });
- if (!GetClientSession()->SupportsWebTransport()) {
- return nullptr;
- }
-
- spdy::SpdyHeaderBlock headers;
- headers[":scheme"] = "https";
- headers[":authority"] = "localhost";
- headers[":path"] = path;
- headers[":method"] = "CONNECT";
- headers[":protocol"] = "webtransport";
-
- client_->SendMessage(headers, "", /*fin=*/false);
- QuicSpdyStream* stream = client_->latest_created_stream();
- if (stream->web_transport() == nullptr) {
- return nullptr;
- }
- WebTransportSessionId id = client_->latest_created_stream()->id();
- QuicSpdySession* client_session = GetClientSession();
- if (client_session->GetWebTransportSession(id) == nullptr) {
- return nullptr;
- }
- WebTransportHttp3* session = client_session->GetWebTransportSession(id);
- if (wait_for_server_response) {
- client_->WaitUntil(-1,
- [stream]() { return stream->headers_decompressed(); });
- EXPECT_TRUE(session->ready());
- }
- if (connect_stream_out != nullptr) {
- *connect_stream_out = stream;
- }
- return session;
- }
-
- NiceMock<MockClientVisitor>& SetupWebTransportVisitor(
- WebTransportHttp3* session) {
- auto visitor_owned = std::make_unique<NiceMock<MockClientVisitor>>();
- NiceMock<MockClientVisitor>& visitor = *visitor_owned;
- session->SetVisitor(std::move(visitor_owned));
- return visitor;
- }
-
- std::string ReadDataFromWebTransportStreamUntilFin(
- WebTransportStream* stream, MockStreamVisitor* visitor = nullptr) {
- QuicStreamId id = stream->GetStreamId();
- std::string buffer;
-
- // Try reading data if immediately available.
- WebTransportStream::ReadResult result = stream->Read(&buffer);
- if (result.fin) {
- return buffer;
- }
-
- while (true) {
- bool can_read = false;
- if (visitor == nullptr) {
- auto visitor_owned = std::make_unique<MockStreamVisitor>();
- visitor = visitor_owned.get();
- stream->SetVisitor(std::move(visitor_owned));
- }
- EXPECT_CALL(*visitor, OnCanRead()).WillOnce(Assign(&can_read, true));
- client_->WaitUntil(5000 /*ms*/, [&can_read]() { return can_read; });
- if (!can_read) {
- ADD_FAILURE() << "Waiting for readable data on stream " << id
- << " timed out";
- return buffer;
- }
- if (GetClientSession()->GetOrCreateSpdyDataStream(id) == nullptr) {
- ADD_FAILURE() << "Stream " << id
- << " was deleted while waiting for incoming data";
- return buffer;
- }
-
- result = stream->Read(&buffer);
- if (result.fin) {
- return buffer;
- }
- if (result.bytes_read == 0) {
- ADD_FAILURE() << "No progress made while reading from stream "
- << stream->GetStreamId();
- return buffer;
- }
- }
- }
-
- void ReadAllIncomingWebTransportUnidirectionalStreams(
- WebTransportSession* session) {
- while (true) {
- WebTransportStream* received_stream =
- session->AcceptIncomingUnidirectionalStream();
- if (received_stream == nullptr) {
- break;
- }
- received_webtransport_unidirectional_streams_.push_back(
- ReadDataFromWebTransportStreamUntilFin(received_stream));
- }
- }
-
- void WaitForNewConnectionIds() {
- // Wait until a new server CID is available for another migration.
- const auto* client_connection = GetClientConnection();
- while (!QuicConnectionPeer::HasUnusedPeerIssuedConnectionId(
- client_connection) ||
- (!client_connection->client_connection_id().IsEmpty() &&
- !QuicConnectionPeer::HasSelfIssuedConnectionIdToConsume(
- client_connection))) {
- client_->client()->WaitForEvents();
- }
- }
-
- ScopedEnvironmentForThreads environment_;
- bool initialized_;
- // If true, the Initialize() function will create |client_| and starts to
- // connect to the server.
- // Default is true.
- bool connect_to_server_on_initialize_;
- QuicSocketAddress server_address_;
- std::string server_hostname_;
- QuicTestBackend memory_cache_backend_;
- std::unique_ptr<ServerThread> server_thread_;
- std::unique_ptr<QuicTestClient> client_;
- QuicConnectionDebugVisitor* connection_debug_visitor_ = nullptr;
- PacketDroppingTestWriter* client_writer_;
- PacketDroppingTestWriter* server_writer_;
- QuicConfig client_config_;
- QuicConfig server_config_;
- ParsedQuicVersion version_;
- ParsedQuicVersionVector client_supported_versions_;
- ParsedQuicVersionVector server_supported_versions_;
- QuicTagVector client_extra_copts_;
- size_t chlo_multiplier_;
- 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_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_;
-};
-
-// Run all end to end tests with all supported versions.
-INSTANTIATE_TEST_SUITE_P(EndToEndTests, EndToEndTest,
- ::testing::ValuesIn(GetTestParams()),
- ::testing::PrintToStringParamName());
-
-TEST_P(EndToEndTest, HandshakeSuccessful) {
- SetQuicReloadableFlag(quic_delay_sequencer_buffer_allocation_until_new_data,
- true);
- ASSERT_TRUE(Initialize());
- EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
- ASSERT_TRUE(server_thread_);
- server_thread_->WaitForCryptoHandshakeConfirmed();
- QuicSpdyClientSession* client_session = GetClientSession();
- ASSERT_TRUE(client_session);
- QuicCryptoStream* client_crypto_stream =
- QuicSessionPeer::GetMutableCryptoStream(client_session);
- ASSERT_TRUE(client_crypto_stream);
- QuicStreamSequencer* client_sequencer =
- QuicStreamPeer::sequencer(client_crypto_stream);
- ASSERT_TRUE(client_sequencer);
- EXPECT_FALSE(
- QuicStreamSequencerPeer::IsUnderlyingBufferAllocated(client_sequencer));
-
- // We've had bugs in the past where the connections could end up on the wrong
- // version. This was never diagnosed but could have been due to in-connection
- // version negotiation back when that existed. At this point in time, our test
- // setup ensures that connections here always use |version_|, but we add this
- // sanity check out of paranoia to catch a regression of this type.
- QuicConnection* client_connection = GetClientConnection();
- ASSERT_TRUE(client_connection);
- EXPECT_EQ(client_connection->version(), version_);
-
- server_thread_->Pause();
- QuicSpdySession* server_session = GetServerSession();
- QuicConnection* server_connection = nullptr;
- QuicCryptoStream* server_crypto_stream = nullptr;
- QuicStreamSequencer* server_sequencer = nullptr;
- if (server_session != nullptr) {
- server_connection = server_session->connection();
- server_crypto_stream =
- QuicSessionPeer::GetMutableCryptoStream(server_session);
- } else {
- ADD_FAILURE() << "Missing server session";
- }
- if (server_crypto_stream != nullptr) {
- server_sequencer = QuicStreamPeer::sequencer(server_crypto_stream);
- } else {
- ADD_FAILURE() << "Missing server crypto stream";
- }
- if (server_sequencer != nullptr) {
- EXPECT_FALSE(
- QuicStreamSequencerPeer::IsUnderlyingBufferAllocated(server_sequencer));
- } else {
- ADD_FAILURE() << "Missing server sequencer";
- }
- if (server_connection != nullptr) {
- EXPECT_EQ(server_connection->version(), version_);
- } else {
- ADD_FAILURE() << "Missing server connection";
- }
- server_thread_->Resume();
-}
-
-TEST_P(EndToEndTest, ExportKeyingMaterial) {
- ASSERT_TRUE(Initialize());
- if (!version_.UsesTls()) {
- return;
- }
- const char* kExportLabel = "label";
- const int kExportLen = 30;
- std::string client_keying_material_export, server_keying_material_export;
-
- EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
- ASSERT_TRUE(server_thread_);
- server_thread_->WaitForCryptoHandshakeConfirmed();
-
- server_thread_->Pause();
- QuicSpdySession* server_session = GetServerSession();
- QuicCryptoStream* server_crypto_stream = nullptr;
- if (server_session != nullptr) {
- server_crypto_stream =
- QuicSessionPeer::GetMutableCryptoStream(server_session);
- } else {
- ADD_FAILURE() << "Missing server session";
- }
- if (server_crypto_stream != nullptr) {
- ASSERT_TRUE(server_crypto_stream->ExportKeyingMaterial(
- kExportLabel, /*context=*/"", kExportLen,
- &server_keying_material_export));
-
- } else {
- ADD_FAILURE() << "Missing server crypto stream";
- }
- server_thread_->Resume();
-
- QuicSpdyClientSession* client_session = GetClientSession();
- ASSERT_TRUE(client_session);
- QuicCryptoStream* client_crypto_stream =
- QuicSessionPeer::GetMutableCryptoStream(client_session);
- ASSERT_TRUE(client_crypto_stream);
- ASSERT_TRUE(client_crypto_stream->ExportKeyingMaterial(
- kExportLabel, /*context=*/"", kExportLen,
- &client_keying_material_export));
- ASSERT_EQ(client_keying_material_export.size(),
- static_cast<size_t>(kExportLen));
- EXPECT_EQ(client_keying_material_export, server_keying_material_export);
-}
-
-TEST_P(EndToEndTest, SimpleRequestResponse) {
- ASSERT_TRUE(Initialize());
-
- SendSynchronousFooRequestAndCheckResponse();
- EXPECT_FALSE(client_->client()->EarlyDataAccepted());
- EXPECT_FALSE(client_->client()->ReceivedInchoateReject());
- if (version_.UsesHttp3()) {
- QuicSpdyClientSession* client_session = GetClientSession();
- ASSERT_TRUE(client_session);
- EXPECT_TRUE(QuicSpdySessionPeer::GetSendControlStream(client_session));
- EXPECT_TRUE(QuicSpdySessionPeer::GetReceiveControlStream(client_session));
- server_thread_->Pause();
- QuicSpdySession* server_session = GetServerSession();
- if (server_session != nullptr) {
- EXPECT_TRUE(QuicSpdySessionPeer::GetSendControlStream(server_session));
- EXPECT_TRUE(QuicSpdySessionPeer::GetReceiveControlStream(server_session));
- } else {
- ADD_FAILURE() << "Missing server session";
- }
- server_thread_->Resume();
- }
- QuicConnectionStats client_stats = GetClientConnection()->GetStats();
- EXPECT_TRUE(client_stats.handshake_completion_time.IsInitialized());
-}
-
-TEST_P(EndToEndTest, HandshakeConfirmed) {
- ASSERT_TRUE(Initialize());
- if (!version_.UsesTls()) {
- return;
- }
- SendSynchronousFooRequestAndCheckResponse();
- // Verify handshake state.
- QuicSpdyClientSession* client_session = GetClientSession();
- ASSERT_TRUE(client_session);
- EXPECT_EQ(HANDSHAKE_CONFIRMED, client_session->GetHandshakeState());
- server_thread_->Pause();
- QuicSpdySession* server_session = GetServerSession();
- if (server_session != nullptr) {
- EXPECT_EQ(HANDSHAKE_CONFIRMED, server_session->GetHandshakeState());
- } else {
- ADD_FAILURE() << "Missing server session";
- }
- server_thread_->Resume();
- client_->Disconnect();
-}
-
-TEST_P(EndToEndTest, SendAndReceiveCoalescedPackets) {
- ASSERT_TRUE(Initialize());
- if (!version_.CanSendCoalescedPackets()) {
- return;
- }
- SendSynchronousFooRequestAndCheckResponse();
- // Verify client successfully processes coalesced packets.
- QuicConnection* client_connection = GetClientConnection();
- ASSERT_TRUE(client_connection);
- QuicConnectionStats client_stats = client_connection->GetStats();
- EXPECT_LT(0u, client_stats.num_coalesced_packets_received);
- EXPECT_EQ(client_stats.num_coalesced_packets_processed,
- client_stats.num_coalesced_packets_received);
- // TODO(fayang): verify server successfully processes coalesced packets.
-}
-
-// Simple transaction, but set a non-default ack delay at the client
-// and ensure it gets to the server.
-TEST_P(EndToEndTest, SimpleRequestResponseWithAckDelayChange) {
- // Force the ACK delay to be something other than the default.
- constexpr uint32_t kClientMaxAckDelay = kDefaultDelayedAckTimeMs + 100u;
- client_config_.SetMaxAckDelayToSendMs(kClientMaxAckDelay);
- ASSERT_TRUE(Initialize());
-
- SendSynchronousFooRequestAndCheckResponse();
- EXPECT_FALSE(client_->client()->EarlyDataAccepted());
- EXPECT_FALSE(client_->client()->ReceivedInchoateReject());
-
- server_thread_->Pause();
- const QuicSentPacketManager* server_sent_packet_manager =
- GetSentPacketManagerFromFirstServerSession();
- if (server_sent_packet_manager != nullptr) {
- EXPECT_EQ(
- kClientMaxAckDelay,
- server_sent_packet_manager->peer_max_ack_delay().ToMilliseconds());
- } else {
- ADD_FAILURE() << "Missing server sent packet manager";
- }
- server_thread_->Resume();
-}
-
-// Simple transaction, but set a non-default ack exponent at the client
-// and ensure it gets to the server.
-TEST_P(EndToEndTest, SimpleRequestResponseWithAckExponentChange) {
- const uint32_t kClientAckDelayExponent = 19;
- EXPECT_NE(kClientAckDelayExponent, kDefaultAckDelayExponent);
- // Force the ACK exponent to be something other than the default.
- // Note that it is sent only with QUIC+TLS.
- client_config_.SetAckDelayExponentToSend(kClientAckDelayExponent);
- ASSERT_TRUE(Initialize());
-
- SendSynchronousFooRequestAndCheckResponse();
-
- EXPECT_FALSE(client_->client()->EarlyDataAccepted());
- EXPECT_FALSE(client_->client()->ReceivedInchoateReject());
- server_thread_->Pause();
- QuicConnection* server_connection = GetServerConnection();
- if (server_connection != nullptr) {
- if (version_.UsesTls()) {
- // Should be only sent with QUIC+TLS.
- EXPECT_EQ(kClientAckDelayExponent,
- server_connection->framer().peer_ack_delay_exponent());
- } else {
- // No change for QUIC_CRYPTO.
- EXPECT_EQ(kDefaultAckDelayExponent,
- server_connection->framer().peer_ack_delay_exponent());
- }
- // No change, regardless of version.
- EXPECT_EQ(kDefaultAckDelayExponent,
- server_connection->framer().local_ack_delay_exponent());
- } else {
- ADD_FAILURE() << "Missing server connection";
- }
- server_thread_->Resume();
-}
-
-TEST_P(EndToEndTest, SimpleRequestResponseForcedVersionNegotiation) {
- client_supported_versions_.insert(client_supported_versions_.begin(),
- QuicVersionReservedForNegotiation());
- NiceMock<MockQuicConnectionDebugVisitor> visitor;
- connection_debug_visitor_ = &visitor;
- EXPECT_CALL(visitor, OnVersionNegotiationPacket(_)).Times(1);
- ASSERT_TRUE(Initialize());
- ASSERT_TRUE(ServerSendsVersionNegotiation());
-
- SendSynchronousFooRequestAndCheckResponse();
-
- EXPECT_FALSE(client_->client()->EarlyDataAccepted());
- EXPECT_FALSE(client_->client()->ReceivedInchoateReject());
-}
-
-TEST_P(EndToEndTest, ForcedVersionNegotiation) {
- client_supported_versions_.insert(client_supported_versions_.begin(),
- QuicVersionReservedForNegotiation());
- ASSERT_TRUE(Initialize());
- ASSERT_TRUE(ServerSendsVersionNegotiation());
-
- SendSynchronousFooRequestAndCheckResponse();
-}
-
-TEST_P(EndToEndTest, SimpleRequestResponseZeroConnectionID) {
- if (!version_.AllowsVariableLengthConnectionIds()) {
- ASSERT_TRUE(Initialize());
- return;
- }
- override_server_connection_id_length_ = 0;
- expected_server_connection_id_length_ = 0;
- ASSERT_TRUE(Initialize());
-
- SendSynchronousFooRequestAndCheckResponse();
- EXPECT_FALSE(client_->client()->EarlyDataAccepted());
- EXPECT_FALSE(client_->client()->ReceivedInchoateReject());
- QuicConnection* client_connection = GetClientConnection();
- ASSERT_TRUE(client_connection);
- EXPECT_EQ(client_connection->connection_id(),
- QuicUtils::CreateZeroConnectionId(version_.transport_version));
-}
-
-TEST_P(EndToEndTest, ZeroConnectionID) {
- if (!version_.AllowsVariableLengthConnectionIds()) {
- ASSERT_TRUE(Initialize());
- return;
- }
- override_server_connection_id_length_ = 0;
- expected_server_connection_id_length_ = 0;
- ASSERT_TRUE(Initialize());
-
- SendSynchronousFooRequestAndCheckResponse();
- QuicConnection* client_connection = GetClientConnection();
- ASSERT_TRUE(client_connection);
- EXPECT_EQ(client_connection->connection_id(),
- QuicUtils::CreateZeroConnectionId(version_.transport_version));
-}
-
-TEST_P(EndToEndTest, BadConnectionIdLength) {
- if (!version_.AllowsVariableLengthConnectionIds()) {
- ASSERT_TRUE(Initialize());
- return;
- }
- override_server_connection_id_length_ = 9;
- ASSERT_TRUE(Initialize());
- SendSynchronousFooRequestAndCheckResponse();
- EXPECT_EQ(kQuicDefaultConnectionIdLength, client_->client()
- ->client_session()
- ->connection()
- ->connection_id()
- .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());
- return;
- }
- override_client_connection_id_length_ = kQuicDefaultConnectionIdLength;
- ASSERT_TRUE(Initialize());
- SendSynchronousFooRequestAndCheckResponse();
- EXPECT_EQ(override_client_connection_id_length_, client_->client()
- ->client_session()
- ->connection()
- ->client_connection_id()
- .length());
-}
-
-TEST_P(EndToEndTest, ForcedVersionNegotiationAndClientConnectionId) {
- if (!version_.SupportsClientConnectionIds()) {
- ASSERT_TRUE(Initialize());
- return;
- }
- client_supported_versions_.insert(client_supported_versions_.begin(),
- QuicVersionReservedForNegotiation());
- override_client_connection_id_length_ = kQuicDefaultConnectionIdLength;
- ASSERT_TRUE(Initialize());
- ASSERT_TRUE(ServerSendsVersionNegotiation());
- SendSynchronousFooRequestAndCheckResponse();
- EXPECT_EQ(override_client_connection_id_length_, client_->client()
- ->client_session()
- ->connection()
- ->client_connection_id()
- .length());
-}
-
-TEST_P(EndToEndTest, ForcedVersionNegotiationAndBadConnectionIdLength) {
- if (!version_.AllowsVariableLengthConnectionIds()) {
- ASSERT_TRUE(Initialize());
- return;
- }
- client_supported_versions_.insert(client_supported_versions_.begin(),
- QuicVersionReservedForNegotiation());
- override_server_connection_id_length_ = 9;
- ASSERT_TRUE(Initialize());
- ASSERT_TRUE(ServerSendsVersionNegotiation());
- SendSynchronousFooRequestAndCheckResponse();
- EXPECT_EQ(kQuicDefaultConnectionIdLength, client_->client()
- ->client_session()
- ->connection()
- ->connection_id()
- .length());
-}
-
-// Forced Version Negotiation with a client connection ID and a long
-// connection ID.
-TEST_P(EndToEndTest, ForcedVersNegoAndClientCIDAndLongCID) {
- if (!version_.SupportsClientConnectionIds() ||
- !version_.AllowsVariableLengthConnectionIds()) {
- 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());
- SendSynchronousFooRequestAndCheckResponse();
- EXPECT_EQ(kQuicDefaultConnectionIdLength, client_->client()
- ->client_session()
- ->connection()
- ->connection_id()
- .length());
- EXPECT_EQ(override_client_connection_id_length_, client_->client()
- ->client_session()
- ->connection()
- ->client_connection_id()
- .length());
-}
-
-TEST_P(EndToEndTest, MixGoodAndBadConnectionIdLengths) {
- if (!version_.AllowsVariableLengthConnectionIds()) {
- ASSERT_TRUE(Initialize());
- return;
- }
-
- // Start client_ which will use a bad connection ID length.
- override_server_connection_id_length_ = 9;
- ASSERT_TRUE(Initialize());
- override_server_connection_id_length_ = -1;
-
- // Start client2 which will use a good connection ID length.
- std::unique_ptr<QuicTestClient> client2(CreateQuicClient(nullptr));
- SpdyHeaderBlock headers;
- headers[":method"] = "POST";
- headers[":path"] = "/foo";
- headers[":scheme"] = "https";
- headers[":authority"] = server_hostname_;
- headers["content-length"] = "3";
- client2->SendMessage(headers, "", /*fin=*/false);
- client2->SendData("eep", true);
-
- SendSynchronousFooRequestAndCheckResponse();
- EXPECT_EQ(kQuicDefaultConnectionIdLength, client_->client()
- ->client_session()
- ->connection()
- ->connection_id()
- .length());
-
- WaitForFooResponseAndCheckIt(client2.get());
- EXPECT_EQ(kQuicDefaultConnectionIdLength, client2->client()
- ->client_session()
- ->connection()
- ->connection_id()
- .length());
-}
-
-TEST_P(EndToEndTest, SimpleRequestResponseWithIetfDraftSupport) {
- if (!version_.HasIetfQuicFrames()) {
- ASSERT_TRUE(Initialize());
- return;
- }
- QuicVersionInitializeSupportForIetfDraft();
- ASSERT_TRUE(Initialize());
-
- SendSynchronousFooRequestAndCheckResponse();
-}
-
-TEST_P(EndToEndTest, SimpleRequestResponseWithLargeReject) {
- chlo_multiplier_ = 1;
- ASSERT_TRUE(Initialize());
-
- SendSynchronousFooRequestAndCheckResponse();
- EXPECT_FALSE(client_->client()->EarlyDataAccepted());
- if (version_.UsesTls()) {
- // REJ messages are a QUIC crypto feature, so TLS always returns false.
- EXPECT_FALSE(client_->client()->ReceivedInchoateReject());
- } else {
- EXPECT_TRUE(client_->client()->ReceivedInchoateReject());
- }
-}
-
-TEST_P(EndToEndTest, SimpleRequestResponsev6) {
- server_address_ =
- QuicSocketAddress(QuicIpAddress::Loopback6(), server_address_.port());
- ASSERT_TRUE(Initialize());
-
- SendSynchronousFooRequestAndCheckResponse();
-}
-
-TEST_P(EndToEndTest,
- ClientDoesNotAllowServerDataOnServerInitiatedBidirectionalStreams) {
- set_client_initial_max_stream_data_incoming_bidirectional(0);
- ASSERT_TRUE(Initialize());
- SendSynchronousFooRequestAndCheckResponse();
-}
-
-TEST_P(EndToEndTest,
- ServerDoesNotAllowClientDataOnServerInitiatedBidirectionalStreams) {
- set_server_initial_max_stream_data_outgoing_bidirectional(0);
- ASSERT_TRUE(Initialize());
- SendSynchronousFooRequestAndCheckResponse();
-}
-
-TEST_P(EndToEndTest,
- BothEndpointsDisallowDataOnServerInitiatedBidirectionalStreams) {
- set_client_initial_max_stream_data_incoming_bidirectional(0);
- set_server_initial_max_stream_data_outgoing_bidirectional(0);
- ASSERT_TRUE(Initialize());
- SendSynchronousFooRequestAndCheckResponse();
-}
-
-// Regression test for a bug where we would always fail to decrypt the first
-// initial packet. Undecryptable packets can be seen after the handshake
-// is complete due to dropping the initial keys at that point, so we only test
-// for undecryptable packets before then.
-TEST_P(EndToEndTest, NoUndecryptablePacketsBeforeHandshakeComplete) {
- ASSERT_TRUE(Initialize());
-
- SendSynchronousFooRequestAndCheckResponse();
-
- QuicConnection* client_connection = GetClientConnection();
- ASSERT_TRUE(client_connection);
- QuicConnectionStats client_stats = client_connection->GetStats();
- EXPECT_EQ(
- 0u,
- client_stats.undecryptable_packets_received_before_handshake_complete);
-
- server_thread_->Pause();
- QuicConnection* server_connection = GetServerConnection();
- if (server_connection != nullptr) {
- QuicConnectionStats server_stats = server_connection->GetStats();
- EXPECT_EQ(
- 0u,
- server_stats.undecryptable_packets_received_before_handshake_complete);
- } else {
- ADD_FAILURE() << "Missing server connection";
- }
- server_thread_->Resume();
-}
-
-TEST_P(EndToEndTest, SeparateFinPacket) {
- ASSERT_TRUE(Initialize());
-
- // Send a request in two parts: the request and then an empty packet with FIN.
- SpdyHeaderBlock headers;
- headers[":method"] = "POST";
- headers[":path"] = "/foo";
- headers[":scheme"] = "https";
- headers[":authority"] = server_hostname_;
- client_->SendMessage(headers, "", /*fin=*/false);
- client_->SendData("", true);
- WaitForFooResponseAndCheckIt();
-
- // Now do the same thing but with a content length.
- headers["content-length"] = "3";
- client_->SendMessage(headers, "", /*fin=*/false);
- client_->SendData("foo", true);
- WaitForFooResponseAndCheckIt();
-}
-
-TEST_P(EndToEndTest, MultipleRequestResponse) {
- ASSERT_TRUE(Initialize());
-
- SendSynchronousFooRequestAndCheckResponse();
- SendSynchronousBarRequestAndCheckResponse();
-}
-
-TEST_P(EndToEndTest, MultipleRequestResponseZeroConnectionID) {
- if (!version_.AllowsVariableLengthConnectionIds()) {
- ASSERT_TRUE(Initialize());
- return;
- }
- override_server_connection_id_length_ = 0;
- expected_server_connection_id_length_ = 0;
- ASSERT_TRUE(Initialize());
-
- SendSynchronousFooRequestAndCheckResponse();
- SendSynchronousBarRequestAndCheckResponse();
-}
-
-TEST_P(EndToEndTest, MultipleStreams) {
- // Verifies quic_test_client can track responses of all active streams.
- ASSERT_TRUE(Initialize());
-
- const int kNumRequests = 10;
-
- SpdyHeaderBlock headers;
- headers[":method"] = "POST";
- headers[":path"] = "/foo";
- headers[":scheme"] = "https";
- headers[":authority"] = server_hostname_;
- headers["content-length"] = "3";
-
- for (int i = 0; i < kNumRequests; ++i) {
- client_->SendMessage(headers, "bar", /*fin=*/true);
- }
-
- while (kNumRequests > client_->num_responses()) {
- client_->ClearPerRequestState();
- ASSERT_TRUE(WaitForFooResponseAndCheckIt());
- }
-}
-
-TEST_P(EndToEndTest, MultipleClients) {
- ASSERT_TRUE(Initialize());
- std::unique_ptr<QuicTestClient> client2(CreateQuicClient(nullptr));
-
- SpdyHeaderBlock headers;
- headers[":method"] = "POST";
- headers[":path"] = "/foo";
- headers[":scheme"] = "https";
- headers[":authority"] = server_hostname_;
- headers["content-length"] = "3";
-
- client_->SendMessage(headers, "", /*fin=*/false);
- client2->SendMessage(headers, "", /*fin=*/false);
-
- client_->SendData("bar", true);
- WaitForFooResponseAndCheckIt();
-
- client2->SendData("eep", true);
- WaitForFooResponseAndCheckIt(client2.get());
-}
-
-TEST_P(EndToEndTest, RequestOverMultiplePackets) {
- // Send a large enough request to guarantee fragmentation.
- std::string huge_request =
- "/some/path?query=" + std::string(kMaxOutgoingPacketSize, '.');
- AddToCache(huge_request, 200, kBarResponseBody);
-
- ASSERT_TRUE(Initialize());
-
- SendSynchronousRequestAndCheckResponse(huge_request, kBarResponseBody);
-}
-
-TEST_P(EndToEndTest, MultiplePacketsRandomOrder) {
- // Send a large enough request to guarantee fragmentation.
- std::string huge_request =
- "/some/path?query=" + std::string(kMaxOutgoingPacketSize, '.');
- AddToCache(huge_request, 200, kBarResponseBody);
-
- ASSERT_TRUE(Initialize());
- SetPacketSendDelay(QuicTime::Delta::FromMilliseconds(2));
- SetReorderPercentage(50);
-
- SendSynchronousRequestAndCheckResponse(huge_request, kBarResponseBody);
-}
-
-TEST_P(EndToEndTest, PostMissingBytes) {
- ASSERT_TRUE(Initialize());
-
- // Add a content length header with no body.
- SpdyHeaderBlock headers;
- headers[":method"] = "POST";
- headers[":path"] = "/foo";
- headers[":scheme"] = "https";
- headers[":authority"] = server_hostname_;
- headers["content-length"] = "3";
-
- // This should be detected as stream fin without complete request,
- // triggering an error response.
- client_->SendCustomSynchronousRequest(headers, "");
- EXPECT_EQ(QuicSimpleServerStream::kErrorResponseBody,
- client_->response_body());
- CheckResponseHeaders("500");
-}
-
-TEST_P(EndToEndTest, LargePostNoPacketLoss) {
- ASSERT_TRUE(Initialize());
-
- EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
-
- // 1 MB body.
- std::string body(1024 * 1024, 'a');
- SpdyHeaderBlock headers;
- headers[":method"] = "POST";
- headers[":path"] = "/foo";
- headers[":scheme"] = "https";
- headers[":authority"] = server_hostname_;
-
- EXPECT_EQ(kFooResponseBody,
- client_->SendCustomSynchronousRequest(headers, body));
- // TODO(ianswett): There should not be packet loss in this test, but on some
- // platforms the receive buffer overflows.
- VerifyCleanConnection(true);
-}
-
-TEST_P(EndToEndTest, LargePostNoPacketLoss1sRTT) {
- ASSERT_TRUE(Initialize());
- SetPacketSendDelay(QuicTime::Delta::FromMilliseconds(1000));
-
- EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
-
- // 100 KB body.
- std::string body(100 * 1024, 'a');
- SpdyHeaderBlock headers;
- headers[":method"] = "POST";
- headers[":path"] = "/foo";
- headers[":scheme"] = "https";
- headers[":authority"] = server_hostname_;
-
- EXPECT_EQ(kFooResponseBody,
- client_->SendCustomSynchronousRequest(headers, body));
- VerifyCleanConnection(false);
-}
-
-TEST_P(EndToEndTest, LargePostWithPacketLoss) {
- // Connect with lower fake packet loss than we'd like to test.
- // Until b/10126687 is fixed, losing handshake packets is pretty
- // brutal.
- // Disable blackhole detection as this test is testing loss recovery.
- client_extra_copts_.push_back(kNBHD);
- SetPacketLossPercentage(5);
- ASSERT_TRUE(Initialize());
- EXPECT_TRUE(client_->client()->WaitForHandshakeConfirmed());
- SetPacketLossPercentage(30);
-
- // 10 KB body.
- std::string body(1024 * 10, 'a');
- SpdyHeaderBlock headers;
- headers[":method"] = "POST";
- headers[":path"] = "/foo";
- headers[":scheme"] = "https";
- headers[":authority"] = server_hostname_;
-
- EXPECT_EQ(kFooResponseBody,
- client_->SendCustomSynchronousRequest(headers, body));
- VerifyCleanConnection(true);
-}
-
-// Regression test for b/80090281.
-TEST_P(EndToEndTest, LargePostWithPacketLossAndAlwaysBundleWindowUpdates) {
- // Disable blackhole detection as this test is testing loss recovery.
- client_extra_copts_.push_back(kNBHD);
- ASSERT_TRUE(Initialize());
- EXPECT_TRUE(client_->client()->WaitForHandshakeConfirmed());
- server_thread_->WaitForCryptoHandshakeConfirmed();
-
- // Normally server only bundles a retransmittable frame once every other
- // kMaxConsecutiveNonRetransmittablePackets ack-only packets. Setting the max
- // to 0 to reliably reproduce b/80090281.
- server_thread_->Schedule([this]() {
- QuicConnection* server_connection = GetServerConnection();
- if (server_connection != nullptr) {
- QuicConnectionPeer::
- SetMaxConsecutiveNumPacketsWithNoRetransmittableFrames(
- server_connection, 0);
- } else {
- ADD_FAILURE() << "Missing server connection";
- }
- });
-
- SetPacketLossPercentage(30);
-
- // 10 KB body.
- std::string body(1024 * 10, 'a');
- SpdyHeaderBlock headers;
- headers[":method"] = "POST";
- headers[":path"] = "/foo";
- headers[":scheme"] = "https";
- headers[":authority"] = server_hostname_;
-
- EXPECT_EQ(kFooResponseBody,
- client_->SendCustomSynchronousRequest(headers, body));
- VerifyCleanConnection(true);
-}
-
-TEST_P(EndToEndTest, LargePostWithPacketLossAndBlockedSocket) {
- // Connect with lower fake packet loss than we'd like to test. Until
- // b/10126687 is fixed, losing handshake packets is pretty brutal.
- // Disable blackhole detection as this test is testing loss recovery.
- client_extra_copts_.push_back(kNBHD);
- SetPacketLossPercentage(5);
- ASSERT_TRUE(Initialize());
- EXPECT_TRUE(client_->client()->WaitForHandshakeConfirmed());
- SetPacketLossPercentage(10);
- client_writer_->set_fake_blocked_socket_percentage(10);
-
- // 10 KB body.
- std::string body(1024 * 10, 'a');
- SpdyHeaderBlock headers;
- headers[":method"] = "POST";
- headers[":path"] = "/foo";
- headers[":scheme"] = "https";
- headers[":authority"] = server_hostname_;
-
- EXPECT_EQ(kFooResponseBody,
- client_->SendCustomSynchronousRequest(headers, body));
-}
-
-TEST_P(EndToEndTest, LargePostNoPacketLossWithDelayAndReordering) {
- ASSERT_TRUE(Initialize());
- EXPECT_TRUE(client_->client()->WaitForHandshakeConfirmed());
- // Both of these must be called when the writer is not actively used.
- SetPacketSendDelay(QuicTime::Delta::FromMilliseconds(2));
- SetReorderPercentage(30);
-
- // 1 MB body.
- std::string body(1024 * 1024, 'a');
- SpdyHeaderBlock headers;
- headers[":method"] = "POST";
- headers[":path"] = "/foo";
- headers[":scheme"] = "https";
- headers[":authority"] = server_hostname_;
-
- EXPECT_EQ(kFooResponseBody,
- client_->SendCustomSynchronousRequest(headers, body));
-}
-
-TEST_P(EndToEndTest, AddressToken) {
- client_extra_copts_.push_back(kTRTT);
- ASSERT_TRUE(Initialize());
- if (!version_.HasIetfQuicFrames()) {
- return;
- }
-
- SendSynchronousFooRequestAndCheckResponse();
- QuicSpdyClientSession* client_session = GetClientSession();
- ASSERT_TRUE(client_session);
- EXPECT_FALSE(client_session->EarlyDataAccepted());
- EXPECT_FALSE(client_session->ReceivedInchoateReject());
- EXPECT_FALSE(client_->client()->EarlyDataAccepted());
- EXPECT_FALSE(client_->client()->ReceivedInchoateReject());
-
- client_->Disconnect();
-
- // The 0-RTT handshake should succeed.
- client_->Connect();
- EXPECT_TRUE(client_->client()->WaitForHandshakeConfirmed());
- ASSERT_TRUE(client_->client()->connected());
- SendSynchronousFooRequestAndCheckResponse();
-
- client_session = GetClientSession();
- ASSERT_TRUE(client_session);
- EXPECT_TRUE(client_session->EarlyDataAccepted());
- EXPECT_TRUE(client_->client()->EarlyDataAccepted());
-
- server_thread_->Pause();
- QuicSpdySession* server_session = GetServerSession();
- QuicConnection* server_connection = GetServerConnection();
- if (server_session != nullptr && server_connection != nullptr) {
- // Verify address is validated via validating token received in INITIAL
- // packet.
- EXPECT_FALSE(
- server_connection->GetStats().address_validated_via_decrypting_packet);
- EXPECT_TRUE(server_connection->GetStats().address_validated_via_token);
-
- // Verify the server received a cached min_rtt from the token and used it as
- // the initial rtt.
- const CachedNetworkParameters* server_received_network_params =
- static_cast<const QuicCryptoServerStreamBase*>(
- server_session->GetCryptoStream())
- ->PreviousCachedNetworkParams();
- if (GetQuicReloadableFlag(
- quic_add_cached_network_parameters_to_address_token2)) {
- ASSERT_NE(server_received_network_params, nullptr);
- // QuicSentPacketManager::SetInitialRtt clamps the initial_rtt to between
- // [min_initial_rtt, max_initial_rtt].
- const QuicTime::Delta min_initial_rtt =
- QuicTime::Delta::FromMicroseconds(kMinInitialRoundTripTimeUs);
- const QuicTime::Delta max_initial_rtt =
- QuicTime::Delta::FromMicroseconds(kMaxInitialRoundTripTimeUs);
- const QuicTime::Delta expected_initial_rtt =
- std::max(min_initial_rtt,
- std::min(max_initial_rtt,
- QuicTime::Delta::FromMilliseconds(
- server_received_network_params->min_rtt_ms())));
- EXPECT_EQ(
- server_connection->sent_packet_manager().GetRttStats()->initial_rtt(),
- expected_initial_rtt);
- } else {
- EXPECT_EQ(server_received_network_params, nullptr);
- }
- } else {
- ADD_FAILURE() << "Missing server connection";
- }
-
- server_thread_->Resume();
-
- client_->Disconnect();
-
- // Regression test for b/206087883.
- // Mock server crash.
- StopServer();
-
- // The handshake fails due to idle timeout.
- client_->Connect();
- ASSERT_FALSE(client_->client()->WaitForOneRttKeysAvailable());
- client_->WaitForWriteToFlush();
- client_->WaitForResponse();
- ASSERT_FALSE(client_->client()->connected());
- EXPECT_THAT(client_->connection_error(), IsError(QUIC_NETWORK_IDLE_TIMEOUT));
-
- // Server restarts.
- server_writer_ = new PacketDroppingTestWriter();
- StartServer();
-
- // Client re-connect.
- client_->Connect();
- ASSERT_TRUE(client_->client()->WaitForHandshakeConfirmed());
- client_->WaitForWriteToFlush();
- client_->WaitForResponse();
- ASSERT_TRUE(client_->client()->connected());
- client_session = GetClientSession();
- ASSERT_TRUE(client_session);
- EXPECT_FALSE(client_session->EarlyDataAccepted());
- EXPECT_FALSE(client_->client()->EarlyDataAccepted());
- server_thread_->Pause();
- server_session = GetServerSession();
- server_connection = GetServerConnection();
- if (!GetQuicReloadableFlag(quic_tls_use_token_in_session_cache)) {
- // Address token is reused.
- if (server_session != nullptr && server_connection != nullptr) {
- // Verify address is validated via validating token received in INITIAL
- // packet.
- EXPECT_FALSE(server_connection->GetStats()
- .address_validated_via_decrypting_packet);
- EXPECT_TRUE(server_connection->GetStats().address_validated_via_token);
- } else {
- ADD_FAILURE() << "Missing server connection";
- }
- } else {
- // Verify address token is only used once.
- if (server_session != nullptr && server_connection != nullptr) {
- // Verify address is validated via decrypting packet.
- EXPECT_TRUE(server_connection->GetStats()
- .address_validated_via_decrypting_packet);
- EXPECT_FALSE(server_connection->GetStats().address_validated_via_token);
- } else {
- ADD_FAILURE() << "Missing server connection";
- }
- }
- server_thread_->Resume();
-
- client_->Disconnect();
-}
-
-TEST_P(EndToEndTest, AddressTokenRefreshedByServer) {
- SetQuicReloadableFlag(quic_add_cached_network_parameters_to_address_token2,
- true);
- ASSERT_TRUE(Initialize());
- if (!version_.HasIetfQuicFrames()) {
- return;
- }
-
- QuicCryptoClientConfig* client_crypto_config =
- client_->client()->crypto_config();
- QuicServerId server_id = client_->client()->server_id();
-
- SendSynchronousFooRequestAndCheckResponse();
- EXPECT_FALSE(GetClientSession()->EarlyDataAccepted());
-
- client_->Disconnect();
-
- QuicClientSessionCache* session_cache = static_cast<QuicClientSessionCache*>(
- client_crypto_config->mutable_session_cache());
- std::string old_address_token;
- if (GetQuicReloadableFlag(quic_tls_use_token_in_session_cache)) {
- old_address_token =
- QuicClientSessionCachePeer::GetToken(session_cache, server_id);
- } else {
- old_address_token =
- client_crypto_config->LookupOrCreate(server_id)->source_address_token();
- }
- ASSERT_TRUE(!old_address_token.empty());
-
- SetQuicReloadableFlag(quic_add_cached_network_parameters_to_address_token2,
- false);
-
- // The 0-RTT handshake should succeed.
- client_->Connect();
- EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
- ASSERT_TRUE(client_->client()->connected());
- SendSynchronousFooRequestAndCheckResponse();
-
- EXPECT_TRUE(GetClientSession()->EarlyDataAccepted());
-
- server_thread_->Pause();
- QuicSpdySession* server_session = GetServerSession();
- QuicConnection* server_connection = GetServerConnection();
- ASSERT_TRUE(server_session != nullptr && server_connection != nullptr);
- // Verify address is validated via validating token received in INITIAL
- // packet.
- EXPECT_FALSE(
- server_connection->GetStats().address_validated_via_decrypting_packet);
- EXPECT_TRUE(server_connection->GetStats().address_validated_via_token);
-
- server_thread_->Resume();
-
- client_->Disconnect();
-
- std::string new_address_token;
- if (GetQuicReloadableFlag(quic_tls_use_token_in_session_cache)) {
- new_address_token =
- QuicClientSessionCachePeer::GetToken(session_cache, server_id);
- } else {
- new_address_token =
- client_crypto_config->LookupOrCreate(server_id)->source_address_token();
- }
- ASSERT_TRUE(!new_address_token.empty());
- ASSERT_NE(new_address_token, old_address_token);
-}
-
-// Verify that client does not reuse a source address token.
-TEST_P(EndToEndTest, AddressTokenNotReusedByClient) {
- ASSERT_TRUE(Initialize());
- if (!version_.HasIetfQuicFrames()) {
- return;
- }
-
- QuicCryptoClientConfig* client_crypto_config =
- client_->client()->crypto_config();
- QuicServerId server_id = client_->client()->server_id();
-
- SendSynchronousFooRequestAndCheckResponse();
- EXPECT_FALSE(GetClientSession()->EarlyDataAccepted());
-
- client_->Disconnect();
-
- QuicClientSessionCache* session_cache = static_cast<QuicClientSessionCache*>(
- client_crypto_config->mutable_session_cache());
- std::string old_address_token;
- if (GetQuicReloadableFlag(quic_tls_use_token_in_session_cache)) {
- old_address_token =
- QuicClientSessionCachePeer::GetToken(session_cache, server_id);
- } else {
- old_address_token =
- client_crypto_config->LookupOrCreate(server_id)->source_address_token();
- }
- ASSERT_TRUE(!old_address_token.empty());
-
- // Pause the server thread again to blackhole packets from client.
- server_thread_->Pause();
- client_->Connect();
- EXPECT_FALSE(client_->client()->WaitForOneRttKeysAvailable());
- EXPECT_FALSE(client_->client()->connected());
-
- std::string new_address_token;
- if (GetQuicReloadableFlag(quic_tls_use_token_in_session_cache)) {
- new_address_token =
- QuicClientSessionCachePeer::GetToken(session_cache, server_id);
- // Verify address token gets cleared.
- ASSERT_TRUE(new_address_token.empty());
- } else {
- new_address_token =
- client_crypto_config->LookupOrCreate(server_id)->source_address_token();
- ASSERT_FALSE(new_address_token.empty());
- }
- server_thread_->Resume();
-}
-
-TEST_P(EndToEndTest, LargePostZeroRTTFailure) {
- // Send a request and then disconnect. This prepares the client to attempt
- // a 0-RTT handshake for the next request.
- ASSERT_TRUE(Initialize());
-
- std::string body(20480, 'a');
- SpdyHeaderBlock headers;
- headers[":method"] = "POST";
- headers[":path"] = "/foo";
- headers[":scheme"] = "https";
- headers[":authority"] = server_hostname_;
-
- EXPECT_EQ(kFooResponseBody,
- client_->SendCustomSynchronousRequest(headers, body));
- QuicSpdyClientSession* client_session = GetClientSession();
- ASSERT_TRUE(client_session);
- EXPECT_FALSE(client_session->EarlyDataAccepted());
- EXPECT_FALSE(client_session->ReceivedInchoateReject());
- EXPECT_FALSE(client_->client()->EarlyDataAccepted());
- EXPECT_FALSE(client_->client()->ReceivedInchoateReject());
-
- client_->Disconnect();
-
- // The 0-RTT handshake should succeed.
- client_->Connect();
- EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
- ASSERT_TRUE(client_->client()->connected());
- EXPECT_EQ(kFooResponseBody,
- client_->SendCustomSynchronousRequest(headers, body));
-
- client_session = GetClientSession();
- ASSERT_TRUE(client_session);
- EXPECT_TRUE(client_session->EarlyDataAccepted());
- EXPECT_TRUE(client_->client()->EarlyDataAccepted());
-
- client_->Disconnect();
-
- // Restart the server so that the 0-RTT handshake will take 1 RTT.
- StopServer();
- server_writer_ = new PacketDroppingTestWriter();
- StartServer();
-
- client_->Connect();
- EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
- ASSERT_TRUE(client_->client()->connected());
- EXPECT_EQ(kFooResponseBody,
- client_->SendCustomSynchronousRequest(headers, body));
- client_session = GetClientSession();
- ASSERT_TRUE(client_session);
- EXPECT_FALSE(client_session->EarlyDataAccepted());
- EXPECT_FALSE(client_session->ReceivedInchoateReject());
- EXPECT_FALSE(client_->client()->EarlyDataAccepted());
- EXPECT_FALSE(client_->client()->ReceivedInchoateReject());
- VerifyCleanConnection(false);
-}
-
-// Regression test for b/168020146.
-TEST_P(EndToEndTest, MultipleZeroRtt) {
- ASSERT_TRUE(Initialize());
-
- EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
- QuicSpdyClientSession* client_session = GetClientSession();
- ASSERT_TRUE(client_session);
- EXPECT_FALSE(client_session->EarlyDataAccepted());
- EXPECT_FALSE(client_session->ReceivedInchoateReject());
- EXPECT_FALSE(client_->client()->EarlyDataAccepted());
- EXPECT_FALSE(client_->client()->ReceivedInchoateReject());
-
- client_->Disconnect();
-
- // The 0-RTT handshake should succeed.
- client_->Connect();
- EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
- ASSERT_TRUE(client_->client()->connected());
- EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
-
- client_session = GetClientSession();
- ASSERT_TRUE(client_session);
- EXPECT_TRUE(client_session->EarlyDataAccepted());
- EXPECT_TRUE(client_->client()->EarlyDataAccepted());
-
- client_->Disconnect();
-
- client_->Connect();
- EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
- ASSERT_TRUE(client_->client()->connected());
- EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
-
- client_session = GetClientSession();
- ASSERT_TRUE(client_session);
- EXPECT_TRUE(client_session->EarlyDataAccepted());
- EXPECT_TRUE(client_->client()->EarlyDataAccepted());
-
- client_->Disconnect();
-}
-
-TEST_P(EndToEndTest, SynchronousRequestZeroRTTFailure) {
- // Send a request and then disconnect. This prepares the client to attempt
- // a 0-RTT handshake for the next request.
- ASSERT_TRUE(Initialize());
-
- EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
- QuicSpdyClientSession* client_session = GetClientSession();
- ASSERT_TRUE(client_session);
- EXPECT_FALSE(client_session->EarlyDataAccepted());
- EXPECT_FALSE(client_session->ReceivedInchoateReject());
- EXPECT_FALSE(client_->client()->EarlyDataAccepted());
- EXPECT_FALSE(client_->client()->ReceivedInchoateReject());
-
- client_->Disconnect();
-
- // The 0-RTT handshake should succeed.
- client_->Connect();
- EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
- ASSERT_TRUE(client_->client()->connected());
- EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
-
- client_session = GetClientSession();
- ASSERT_TRUE(client_session);
- EXPECT_TRUE(client_session->EarlyDataAccepted());
- EXPECT_TRUE(client_->client()->EarlyDataAccepted());
-
- client_->Disconnect();
-
- // Restart the server so that the 0-RTT handshake will take 1 RTT.
- StopServer();
- server_writer_ = new PacketDroppingTestWriter();
- StartServer();
-
- client_->Connect();
- EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
- ASSERT_TRUE(client_->client()->connected());
- EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
-
- client_session = GetClientSession();
- ASSERT_TRUE(client_session);
- EXPECT_FALSE(client_session->EarlyDataAccepted());
- EXPECT_FALSE(client_session->ReceivedInchoateReject());
- EXPECT_FALSE(client_->client()->EarlyDataAccepted());
- EXPECT_FALSE(client_->client()->ReceivedInchoateReject());
-
- VerifyCleanConnection(false);
-}
-
-TEST_P(EndToEndTest, LargePostSynchronousRequest) {
- // Send a request and then disconnect. This prepares the client to attempt
- // a 0-RTT handshake for the next request.
- ASSERT_TRUE(Initialize());
-
- std::string body(20480, 'a');
- SpdyHeaderBlock headers;
- headers[":method"] = "POST";
- headers[":path"] = "/foo";
- headers[":scheme"] = "https";
- headers[":authority"] = server_hostname_;
-
- EXPECT_EQ(kFooResponseBody,
- client_->SendCustomSynchronousRequest(headers, body));
- QuicSpdyClientSession* client_session = GetClientSession();
- ASSERT_TRUE(client_session);
- EXPECT_FALSE(client_session->EarlyDataAccepted());
- EXPECT_FALSE(client_session->ReceivedInchoateReject());
- EXPECT_FALSE(client_->client()->EarlyDataAccepted());
- EXPECT_FALSE(client_->client()->ReceivedInchoateReject());
-
- client_->Disconnect();
-
- // The 0-RTT handshake should succeed.
- client_->Connect();
- EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
- ASSERT_TRUE(client_->client()->connected());
- EXPECT_EQ(kFooResponseBody,
- client_->SendCustomSynchronousRequest(headers, body));
-
- client_session = GetClientSession();
- ASSERT_TRUE(client_session);
- EXPECT_TRUE(client_session->EarlyDataAccepted());
- EXPECT_TRUE(client_->client()->EarlyDataAccepted());
-
- client_->Disconnect();
-
- // Restart the server so that the 0-RTT handshake will take 1 RTT.
- StopServer();
- server_writer_ = new PacketDroppingTestWriter();
- StartServer();
-
- client_->Connect();
- EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
- ASSERT_TRUE(client_->client()->connected());
- EXPECT_EQ(kFooResponseBody,
- client_->SendCustomSynchronousRequest(headers, body));
-
- client_session = GetClientSession();
- ASSERT_TRUE(client_session);
- EXPECT_FALSE(client_session->EarlyDataAccepted());
- EXPECT_FALSE(client_session->ReceivedInchoateReject());
- EXPECT_FALSE(client_->client()->EarlyDataAccepted());
- EXPECT_FALSE(client_->client()->ReceivedInchoateReject());
-
- VerifyCleanConnection(false);
-}
-
-// This is a regression test for b/162595387
-TEST_P(EndToEndTest, PostZeroRTTRequestDuringHandshake) {
- if (!version_.UsesTls()) {
- // This test is TLS specific.
- ASSERT_TRUE(Initialize());
- return;
- }
- // Send a request and then disconnect. This prepares the client to attempt
- // a 0-RTT handshake for the next request.
- NiceMock<MockQuicConnectionDebugVisitor> visitor;
- connection_debug_visitor_ = &visitor;
- ASSERT_TRUE(Initialize());
-
- SendSynchronousFooRequestAndCheckResponse();
- QuicSpdyClientSession* client_session = GetClientSession();
- ASSERT_TRUE(client_session);
- EXPECT_FALSE(client_session->EarlyDataAccepted());
- EXPECT_FALSE(client_session->ReceivedInchoateReject());
- EXPECT_FALSE(client_->client()->EarlyDataAccepted());
- EXPECT_FALSE(client_->client()->ReceivedInchoateReject());
-
- client_->Disconnect();
-
- // The 0-RTT handshake should succeed.
- ON_CALL(visitor, OnCryptoFrame(_))
- .WillByDefault(Invoke([this](const QuicCryptoFrame& frame) {
- if (frame.level != ENCRYPTION_HANDSHAKE) {
- return;
- }
- // At this point in the handshake, the client should have derived
- // ENCRYPTION_ZERO_RTT keys (thus set encryption_established). It
- // should also have set ENCRYPTION_HANDSHAKE keys after receiving
- // the server's ENCRYPTION_INITIAL flight.
- EXPECT_TRUE(
- GetClientSession()->GetCryptoStream()->encryption_established());
- EXPECT_TRUE(
- GetClientConnection()->framer().HasEncrypterOfEncryptionLevel(
- ENCRYPTION_HANDSHAKE));
- SpdyHeaderBlock headers;
- headers[":method"] = "POST";
- headers[":path"] = "/foo";
- headers[":scheme"] = "https";
- headers[":authority"] = server_hostname_;
- EXPECT_GT(
- client_->SendMessage(headers, "", /*fin*/ true, /*flush*/ false),
- 0);
- }));
- client_->Connect();
- ASSERT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
- client_->WaitForWriteToFlush();
- client_->WaitForResponse();
- ASSERT_TRUE(client_->client()->connected());
- EXPECT_EQ(kFooResponseBody, client_->response_body());
-
- client_session = GetClientSession();
- ASSERT_TRUE(client_session);
- EXPECT_TRUE(client_session->EarlyDataAccepted());
- EXPECT_TRUE(client_->client()->EarlyDataAccepted());
-}
-
-// Regression test for b/166836136.
-TEST_P(EndToEndTest, RetransmissionAfterZeroRTTRejectBeforeOneRtt) {
- if (!version_.UsesTls()) {
- // This test is TLS specific.
- ASSERT_TRUE(Initialize());
- return;
- }
- // Send a request and then disconnect. This prepares the client to attempt
- // a 0-RTT handshake for the next request.
- NiceMock<MockQuicConnectionDebugVisitor> visitor;
- connection_debug_visitor_ = &visitor;
- ASSERT_TRUE(Initialize());
-
- SendSynchronousFooRequestAndCheckResponse();
- QuicSpdyClientSession* client_session = GetClientSession();
- ASSERT_TRUE(client_session);
- EXPECT_FALSE(client_session->EarlyDataAccepted());
- EXPECT_FALSE(client_session->ReceivedInchoateReject());
- EXPECT_FALSE(client_->client()->EarlyDataAccepted());
- EXPECT_FALSE(client_->client()->ReceivedInchoateReject());
-
- client_->Disconnect();
-
- client_->Connect();
- EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
- ASSERT_TRUE(client_->client()->connected());
- EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
-
- client_session = GetClientSession();
- ASSERT_TRUE(client_session);
- EXPECT_TRUE(client_session->EarlyDataAccepted());
- EXPECT_TRUE(client_->client()->EarlyDataAccepted());
-
- client_->Disconnect();
-
- // Restart the server so that the 0-RTT handshake will take 1 RTT.
- StopServer();
- server_writer_ = new PacketDroppingTestWriter();
- StartServer();
-
- ON_CALL(visitor, OnZeroRttRejected(_)).WillByDefault(Invoke([this]() {
- EXPECT_FALSE(GetClientSession()->IsEncryptionEstablished());
- }));
-
- // The 0-RTT handshake should fail.
- client_->Connect();
- ASSERT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
- client_->WaitForWriteToFlush();
- client_->WaitForResponse();
- ASSERT_TRUE(client_->client()->connected());
-
- client_session = GetClientSession();
- ASSERT_TRUE(client_session);
- EXPECT_FALSE(client_session->EarlyDataAccepted());
- EXPECT_FALSE(client_->client()->EarlyDataAccepted());
-}
-
-TEST_P(EndToEndTest, RejectWithPacketLoss) {
- // In this test, we intentionally drop the first packet from the
- // server, which corresponds with the initial REJ response from
- // the server.
- server_writer_->set_fake_drop_first_n_packets(1);
- ASSERT_TRUE(Initialize());
-}
-
-TEST_P(EndToEndTest, SetInitialReceivedConnectionOptions) {
- QuicTagVector initial_received_options;
- initial_received_options.push_back(kTBBR);
- initial_received_options.push_back(kIW10);
- initial_received_options.push_back(kPRST);
- EXPECT_TRUE(server_config_.SetInitialReceivedConnectionOptions(
- initial_received_options));
-
- ASSERT_TRUE(Initialize());
- EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
- server_thread_->WaitForCryptoHandshakeConfirmed();
-
- EXPECT_FALSE(server_config_.SetInitialReceivedConnectionOptions(
- initial_received_options));
-
- // Verify that server's configuration is correct.
- server_thread_->Pause();
- EXPECT_TRUE(server_config_.HasReceivedConnectionOptions());
- EXPECT_TRUE(
- ContainsQuicTag(server_config_.ReceivedConnectionOptions(), kTBBR));
- EXPECT_TRUE(
- ContainsQuicTag(server_config_.ReceivedConnectionOptions(), kIW10));
- EXPECT_TRUE(
- ContainsQuicTag(server_config_.ReceivedConnectionOptions(), kPRST));
-}
-
-TEST_P(EndToEndTest, LargePostSmallBandwidthLargeBuffer) {
- ASSERT_TRUE(Initialize());
- SetPacketSendDelay(QuicTime::Delta::FromMicroseconds(1));
- // 256KB per second with a 256KB buffer from server to client. Wireless
- // clients commonly have larger buffers, but our max CWND is 200.
- server_writer_->set_max_bandwidth_and_buffer_size(
- QuicBandwidth::FromBytesPerSecond(256 * 1024), 256 * 1024);
-
- EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
-
- // 1 MB body.
- std::string body(1024 * 1024, 'a');
- SpdyHeaderBlock headers;
- headers[":method"] = "POST";
- headers[":path"] = "/foo";
- headers[":scheme"] = "https";
- headers[":authority"] = server_hostname_;
-
- EXPECT_EQ(kFooResponseBody,
- client_->SendCustomSynchronousRequest(headers, body));
- // This connection may drop packets, because the buffer is smaller than the
- // max CWND.
- VerifyCleanConnection(true);
-}
-
-TEST_P(EndToEndTest, DoNotSetSendAlarmIfConnectionFlowControlBlocked) {
- // Regression test for b/14677858.
- // Test that the resume write alarm is not set in QuicConnection::OnCanWrite
- // if currently connection level flow control blocked. If set, this results in
- // an infinite loop in the EpollServer, as the alarm fires and is immediately
- // rescheduled.
- ASSERT_TRUE(Initialize());
- EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
-
- // Ensure both stream and connection level are flow control blocked by setting
- // the send window offset to 0.
- const uint64_t flow_control_window =
- server_config_.GetInitialStreamFlowControlWindowToSend();
- QuicSpdyClientStream* stream = client_->GetOrCreateStream();
- QuicSession* session = GetClientSession();
- ASSERT_TRUE(session);
- QuicStreamPeer::SetSendWindowOffset(stream, 0);
- QuicFlowControllerPeer::SetSendWindowOffset(session->flow_controller(), 0);
- EXPECT_TRUE(stream->IsFlowControlBlocked());
- EXPECT_TRUE(session->flow_controller()->IsBlocked());
-
- // Make sure that the stream has data pending so that it will be marked as
- // write blocked when it receives a stream level WINDOW_UPDATE.
- stream->WriteOrBufferBody("hello", false);
-
- // The stream now attempts to write, fails because it is still connection
- // level flow control blocked, and is added to the write blocked list.
- QuicWindowUpdateFrame window_update(kInvalidControlFrameId, stream->id(),
- 2 * flow_control_window);
- stream->OnWindowUpdateFrame(window_update);
-
- // Prior to fixing b/14677858 this call would result in an infinite loop in
- // Chromium. As a proxy for detecting this, we now check whether the
- // send alarm is set after OnCanWrite. It should not be, as the
- // connection is still flow control blocked.
- session->connection()->OnCanWrite();
-
- QuicAlarm* send_alarm =
- QuicConnectionPeer::GetSendAlarm(session->connection());
- EXPECT_FALSE(send_alarm->IsSet());
-}
-
-TEST_P(EndToEndTest, InvalidStream) {
- ASSERT_TRUE(Initialize());
- EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
-
- std::string body(kMaxOutgoingPacketSize, 'a');
- SpdyHeaderBlock headers;
- headers[":method"] = "POST";
- headers[":path"] = "/foo";
- headers[":scheme"] = "https";
- headers[":authority"] = server_hostname_;
-
- // Force the client to write with a stream ID belonging to a nonexistent
- // server-side stream.
- QuicSpdySession* session = GetClientSession();
- ASSERT_TRUE(session);
- QuicSessionPeer::SetNextOutgoingBidirectionalStreamId(
- session, GetNthServerInitiatedBidirectionalId(0));
-
- client_->SendCustomSynchronousRequest(headers, body);
- EXPECT_THAT(client_->stream_error(),
- IsStreamError(QUIC_STREAM_CONNECTION_ERROR));
- EXPECT_THAT(client_->connection_error(), IsError(QUIC_INVALID_STREAM_ID));
-}
-
-// Test that the server resets the stream if the client sends a request
-// with overly large headers.
-TEST_P(EndToEndTest, LargeHeaders) {
- ASSERT_TRUE(Initialize());
- EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
-
- std::string body(kMaxOutgoingPacketSize, 'a');
- SpdyHeaderBlock headers;
- headers[":method"] = "POST";
- headers[":path"] = "/foo";
- headers[":scheme"] = "https";
- headers[":authority"] = server_hostname_;
- headers["key1"] = std::string(15 * 1024, 'a');
- headers["key2"] = std::string(15 * 1024, 'a');
- headers["key3"] = std::string(15 * 1024, 'a');
-
- client_->SendCustomSynchronousRequest(headers, body);
-
- if (version_.UsesHttp3()) {
- // QuicSpdyStream::OnHeadersTooLarge() resets the stream with
- // QUIC_HEADERS_TOO_LARGE. This is sent as H3_EXCESSIVE_LOAD, the closest
- // HTTP/3 error code, and translated back to QUIC_STREAM_EXCESSIVE_LOAD on
- // the receiving side.
- EXPECT_THAT(client_->stream_error(),
- IsStreamError(QUIC_STREAM_EXCESSIVE_LOAD));
- } else {
- EXPECT_THAT(client_->stream_error(), IsStreamError(QUIC_HEADERS_TOO_LARGE));
- }
- EXPECT_THAT(client_->connection_error(), IsQuicNoError());
-}
-
-TEST_P(EndToEndTest, EarlyResponseWithQuicStreamNoError) {
- ASSERT_TRUE(Initialize());
- EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
-
- std::string large_body(1024 * 1024, 'a');
- SpdyHeaderBlock headers;
- headers[":method"] = "POST";
- headers[":path"] = "/foo";
- headers[":scheme"] = "https";
- headers[":authority"] = server_hostname_;
- // Insert an invalid content_length field in request to trigger an early
- // response from server.
- headers["content-length"] = "-3";
-
- client_->SendCustomSynchronousRequest(headers, large_body);
- EXPECT_EQ("bad", client_->response_body());
- CheckResponseHeaders("500");
- EXPECT_THAT(client_->stream_error(), IsQuicStreamNoError());
- EXPECT_THAT(client_->connection_error(), IsQuicNoError());
-}
-
-// TODO(rch): this test seems to cause net_unittests timeouts :|
-TEST_P(EndToEndTest, QUIC_TEST_DISABLED_IN_CHROME(MultipleTermination)) {
- ASSERT_TRUE(Initialize());
-
- // Set the offset so we won't frame. Otherwise when we pick up termination
- // before HTTP framing is complete, we send an error and close the stream,
- // and the second write is picked up as writing on a closed stream.
- QuicSpdyClientStream* stream = client_->GetOrCreateStream();
- ASSERT_TRUE(stream != nullptr);
- QuicStreamPeer::SetStreamBytesWritten(3, stream);
-
- client_->SendData("bar", true);
- client_->WaitForWriteToFlush();
-
- // By default the stream protects itself from writes after terminte is set.
- // Override this to test the server handling buggy clients.
- QuicStreamPeer::SetWriteSideClosed(false, client_->GetOrCreateStream());
-
- EXPECT_QUIC_BUG(client_->SendData("eep", true), "Fin already buffered");
-}
-
-TEST_P(EndToEndTest, Timeout) {
- client_config_.SetIdleNetworkTimeout(QuicTime::Delta::FromMicroseconds(500));
- // Note: we do NOT ASSERT_TRUE: we may time out during initial handshake:
- // that's enough to validate timeout in this case.
- Initialize();
- while (client_->client()->connected()) {
- client_->client()->WaitForEvents();
- }
-}
-
-TEST_P(EndToEndTest, MaxDynamicStreamsLimitRespected) {
- // Set a limit on maximum number of incoming dynamic streams.
- // Make sure the limit is respected by the peer.
- const uint32_t kServerMaxDynamicStreams = 1;
- server_config_.SetMaxBidirectionalStreamsToSend(kServerMaxDynamicStreams);
- ASSERT_TRUE(Initialize());
- if (version_.HasIetfQuicFrames()) {
- // Do not run this test for /IETF QUIC. This test relies on the fact that
- // Google QUIC allows a small number of additional streams beyond the
- // negotiated limit, which is not supported in IETF QUIC. Note that the test
- // needs to be here, after calling Initialize(), because all tests end up
- // calling EndToEndTest::TearDown(), which asserts that Initialize has been
- // called and then proceeds to tear things down -- which fails if they are
- // not properly set up.
- return;
- }
- EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
-
- // Make the client misbehave after negotiation.
- const int kServerMaxStreams = kMaxStreamsMinimumIncrement + 1;
- QuicSpdyClientSession* client_session = GetClientSession();
- ASSERT_TRUE(client_session);
- QuicSessionPeer::SetMaxOpenOutgoingStreams(client_session,
- kServerMaxStreams + 1);
-
- SpdyHeaderBlock headers;
- headers[":method"] = "POST";
- headers[":path"] = "/foo";
- headers[":scheme"] = "https";
- headers[":authority"] = server_hostname_;
- headers["content-length"] = "3";
-
- // The server supports a small number of additional streams beyond the
- // negotiated limit. Open enough streams to go beyond that limit.
- for (int i = 0; i < kServerMaxStreams + 1; ++i) {
- client_->SendMessage(headers, "", /*fin=*/false);
- }
- client_->WaitForResponse();
-
- EXPECT_TRUE(client_->connected());
- EXPECT_THAT(client_->stream_error(), IsStreamError(QUIC_REFUSED_STREAM));
- EXPECT_THAT(client_->connection_error(), IsQuicNoError());
-}
-
-TEST_P(EndToEndTest, SetIndependentMaxDynamicStreamsLimits) {
- // Each endpoint can set max dynamic streams independently.
- const uint32_t kClientMaxDynamicStreams = 4;
- const uint32_t kServerMaxDynamicStreams = 3;
- client_config_.SetMaxBidirectionalStreamsToSend(kClientMaxDynamicStreams);
- server_config_.SetMaxBidirectionalStreamsToSend(kServerMaxDynamicStreams);
- client_config_.SetMaxUnidirectionalStreamsToSend(kClientMaxDynamicStreams);
- server_config_.SetMaxUnidirectionalStreamsToSend(kServerMaxDynamicStreams);
-
- ASSERT_TRUE(Initialize());
- EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
-
- // The client has received the server's limit and vice versa.
- QuicSpdyClientSession* client_session = GetClientSession();
- ASSERT_TRUE(client_session);
- // The value returned by max_allowed... includes the Crypto and Header
- // stream (created as a part of initialization). The config. values,
- // above, are treated as "number of requests/responses" - that is, they do
- // not include the static Crypto and Header streams. Reduce the value
- // returned by max_allowed... by 2 to remove the static streams from the
- // count.
- size_t client_max_open_outgoing_bidirectional_streams =
- version_.HasIetfQuicFrames()
- ? QuicSessionPeer::ietf_streamid_manager(client_session)
- ->max_outgoing_bidirectional_streams()
- : QuicSessionPeer::GetStreamIdManager(client_session)
- ->max_open_outgoing_streams();
- size_t client_max_open_outgoing_unidirectional_streams =
- version_.HasIetfQuicFrames()
- ? QuicSessionPeer::ietf_streamid_manager(client_session)
- ->max_outgoing_unidirectional_streams() -
- kHttp3StaticUnidirectionalStreamCount
- : QuicSessionPeer::GetStreamIdManager(client_session)
- ->max_open_outgoing_streams();
- EXPECT_EQ(kServerMaxDynamicStreams,
- client_max_open_outgoing_bidirectional_streams);
- EXPECT_EQ(kServerMaxDynamicStreams,
- client_max_open_outgoing_unidirectional_streams);
- server_thread_->Pause();
- QuicSession* server_session = GetServerSession();
- if (server_session != nullptr) {
- size_t server_max_open_outgoing_bidirectional_streams =
- version_.HasIetfQuicFrames()
- ? QuicSessionPeer::ietf_streamid_manager(server_session)
- ->max_outgoing_bidirectional_streams()
- : QuicSessionPeer::GetStreamIdManager(server_session)
- ->max_open_outgoing_streams();
- size_t server_max_open_outgoing_unidirectional_streams =
- version_.HasIetfQuicFrames()
- ? QuicSessionPeer::ietf_streamid_manager(server_session)
- ->max_outgoing_unidirectional_streams() -
- kHttp3StaticUnidirectionalStreamCount
- : QuicSessionPeer::GetStreamIdManager(server_session)
- ->max_open_outgoing_streams();
- EXPECT_EQ(kClientMaxDynamicStreams,
- server_max_open_outgoing_bidirectional_streams);
- EXPECT_EQ(kClientMaxDynamicStreams,
- server_max_open_outgoing_unidirectional_streams);
- } else {
- ADD_FAILURE() << "Missing server session";
- }
- server_thread_->Resume();
-}
-
-TEST_P(EndToEndTest, NegotiateCongestionControl) {
- ASSERT_TRUE(Initialize());
-
- EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
-
- CongestionControlType expected_congestion_control_type = kRenoBytes;
- switch (GetParam().congestion_control_tag) {
- case kRENO:
- expected_congestion_control_type = kRenoBytes;
- break;
- case kTBBR:
- expected_congestion_control_type = kBBR;
- break;
- case kQBIC:
- expected_congestion_control_type = kCubicBytes;
- break;
- case kB2ON:
- expected_congestion_control_type = kBBRv2;
- break;
- default:
- QUIC_DLOG(FATAL) << "Unexpected congestion control tag";
- }
-
- server_thread_->Pause();
- const QuicSentPacketManager* server_sent_packet_manager =
- GetSentPacketManagerFromFirstServerSession();
- if (server_sent_packet_manager != nullptr) {
- EXPECT_EQ(
- expected_congestion_control_type,
- QuicSentPacketManagerPeer::GetSendAlgorithm(*server_sent_packet_manager)
- ->GetCongestionControlType());
- } else {
- ADD_FAILURE() << "Missing server sent packet manager";
- }
- server_thread_->Resume();
-}
-
-TEST_P(EndToEndTest, ClientSuggestsRTT) {
- // Client suggests initial RTT, verify it is used.
- const QuicTime::Delta kInitialRTT = QuicTime::Delta::FromMicroseconds(20000);
- client_config_.SetInitialRoundTripTimeUsToSend(kInitialRTT.ToMicroseconds());
-
- ASSERT_TRUE(Initialize());
- EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
- ASSERT_TRUE(server_thread_);
- server_thread_->WaitForCryptoHandshakeConfirmed();
-
- // Pause the server so we can access the server's internals without races.
- server_thread_->Pause();
- const QuicSentPacketManager* client_sent_packet_manager =
- GetSentPacketManagerFromClientSession();
- const QuicSentPacketManager* server_sent_packet_manager =
- GetSentPacketManagerFromFirstServerSession();
- if (client_sent_packet_manager != nullptr &&
- server_sent_packet_manager != nullptr) {
- EXPECT_EQ(kInitialRTT,
- client_sent_packet_manager->GetRttStats()->initial_rtt());
- EXPECT_EQ(kInitialRTT,
- server_sent_packet_manager->GetRttStats()->initial_rtt());
- } else {
- ADD_FAILURE() << "Missing sent packet manager";
- }
- server_thread_->Resume();
-}
-
-TEST_P(EndToEndTest, ClientSuggestsIgnoredRTT) {
- // Client suggests initial RTT, but also specifies NRTT, so it's not used.
- const QuicTime::Delta kInitialRTT = QuicTime::Delta::FromMicroseconds(20000);
- client_config_.SetInitialRoundTripTimeUsToSend(kInitialRTT.ToMicroseconds());
- QuicTagVector options;
- options.push_back(kNRTT);
- client_config_.SetConnectionOptionsToSend(options);
-
- ASSERT_TRUE(Initialize());
- EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
- ASSERT_TRUE(server_thread_);
- server_thread_->WaitForCryptoHandshakeConfirmed();
-
- // Pause the server so we can access the server's internals without races.
- server_thread_->Pause();
- const QuicSentPacketManager* client_sent_packet_manager =
- GetSentPacketManagerFromClientSession();
- const QuicSentPacketManager* server_sent_packet_manager =
- GetSentPacketManagerFromFirstServerSession();
- if (client_sent_packet_manager != nullptr &&
- server_sent_packet_manager != nullptr) {
- EXPECT_EQ(kInitialRTT,
- client_sent_packet_manager->GetRttStats()->initial_rtt());
- EXPECT_EQ(kInitialRTT,
- server_sent_packet_manager->GetRttStats()->initial_rtt());
- } else {
- ADD_FAILURE() << "Missing sent packet manager";
- }
- server_thread_->Resume();
-}
-
-// Regression test for b/171378845
-TEST_P(EndToEndTest, ClientDisablesGQuicZeroRtt) {
- if (version_.UsesTls()) {
- // This feature is gQUIC only.
- ASSERT_TRUE(Initialize());
- return;
- }
- QuicTagVector options;
- options.push_back(kQNZ2);
- client_config_.SetClientConnectionOptions(options);
-
- ASSERT_TRUE(Initialize());
-
- EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
- QuicSpdyClientSession* client_session = GetClientSession();
- ASSERT_TRUE(client_session);
- EXPECT_FALSE(client_session->EarlyDataAccepted());
- EXPECT_FALSE(client_session->ReceivedInchoateReject());
- EXPECT_FALSE(client_->client()->EarlyDataAccepted());
- EXPECT_FALSE(client_->client()->ReceivedInchoateReject());
-
- client_->Disconnect();
-
- // Make sure that the request succeeds but 0-RTT was not used.
- client_->Connect();
- EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
- ASSERT_TRUE(client_->client()->connected());
- EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
-
- client_session = GetClientSession();
- ASSERT_TRUE(client_session);
- EXPECT_FALSE(client_session->EarlyDataAccepted());
- EXPECT_FALSE(client_->client()->EarlyDataAccepted());
-}
-
-TEST_P(EndToEndTest, MaxInitialRTT) {
- // Client tries to suggest twice the server's max initial rtt and the server
- // uses the max.
- client_config_.SetInitialRoundTripTimeUsToSend(2 *
- kMaxInitialRoundTripTimeUs);
-
- ASSERT_TRUE(Initialize());
- EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
- ASSERT_TRUE(server_thread_);
- server_thread_->WaitForCryptoHandshakeConfirmed();
-
- // Pause the server so we can access the server's internals without races.
- server_thread_->Pause();
- const QuicSentPacketManager* client_sent_packet_manager =
- GetSentPacketManagerFromClientSession();
- const QuicSentPacketManager* server_sent_packet_manager =
- GetSentPacketManagerFromFirstServerSession();
- if (client_sent_packet_manager != nullptr &&
- server_sent_packet_manager != nullptr) {
- // Now that acks have been exchanged, the RTT estimate has decreased on the
- // server and is not infinite on the client.
- EXPECT_FALSE(
- client_sent_packet_manager->GetRttStats()->smoothed_rtt().IsInfinite());
- const RttStats* server_rtt_stats =
- server_sent_packet_manager->GetRttStats();
- EXPECT_EQ(static_cast<int64_t>(kMaxInitialRoundTripTimeUs),
- server_rtt_stats->initial_rtt().ToMicroseconds());
- EXPECT_GE(static_cast<int64_t>(kMaxInitialRoundTripTimeUs),
- server_rtt_stats->smoothed_rtt().ToMicroseconds());
- } else {
- ADD_FAILURE() << "Missing sent packet manager";
- }
- server_thread_->Resume();
-}
-
-TEST_P(EndToEndTest, MinInitialRTT) {
- // Client tries to suggest 0 and the server uses the default.
- client_config_.SetInitialRoundTripTimeUsToSend(0);
-
- ASSERT_TRUE(Initialize());
- EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
- server_thread_->WaitForCryptoHandshakeConfirmed();
-
- // Pause the server so we can access the server's internals without races.
- server_thread_->Pause();
- const QuicSentPacketManager* client_sent_packet_manager =
- GetSentPacketManagerFromClientSession();
- const QuicSentPacketManager* server_sent_packet_manager =
- GetSentPacketManagerFromFirstServerSession();
- if (client_sent_packet_manager != nullptr &&
- server_sent_packet_manager != nullptr) {
- // Now that acks have been exchanged, the RTT estimate has decreased on the
- // server and is not infinite on the client.
- EXPECT_FALSE(
- client_sent_packet_manager->GetRttStats()->smoothed_rtt().IsInfinite());
- // Expect the default rtt of 100ms.
- EXPECT_EQ(QuicTime::Delta::FromMilliseconds(100),
- server_sent_packet_manager->GetRttStats()->initial_rtt());
- // Ensure the bandwidth is valid.
- client_sent_packet_manager->BandwidthEstimate();
- server_sent_packet_manager->BandwidthEstimate();
- } else {
- ADD_FAILURE() << "Missing sent packet manager";
- }
- server_thread_->Resume();
-}
-
-TEST_P(EndToEndTest, 0ByteConnectionId) {
- if (version_.HasIetfInvariantHeader()) {
- // SetBytesForConnectionIdToSend only applies to Google QUIC encoding.
- ASSERT_TRUE(Initialize());
- return;
- }
- client_config_.SetBytesForConnectionIdToSend(0);
- ASSERT_TRUE(Initialize());
-
- SendSynchronousFooRequestAndCheckResponse();
- QuicConnection* client_connection = GetClientConnection();
- ASSERT_TRUE(client_connection);
- QuicPacketHeader* header =
- QuicConnectionPeer::GetLastHeader(client_connection);
- EXPECT_EQ(CONNECTION_ID_ABSENT, header->source_connection_id_included);
-}
-
-TEST_P(EndToEndTest, 8ByteConnectionId) {
- if (version_.HasIetfInvariantHeader()) {
- // SetBytesForConnectionIdToSend only applies to Google QUIC encoding.
- ASSERT_TRUE(Initialize());
- return;
- }
- client_config_.SetBytesForConnectionIdToSend(8);
- ASSERT_TRUE(Initialize());
-
- SendSynchronousFooRequestAndCheckResponse();
- QuicConnection* client_connection = GetClientConnection();
- ASSERT_TRUE(client_connection);
- QuicPacketHeader* header =
- QuicConnectionPeer::GetLastHeader(client_connection);
- EXPECT_EQ(CONNECTION_ID_PRESENT, header->destination_connection_id_included);
-}
-
-TEST_P(EndToEndTest, 15ByteConnectionId) {
- if (version_.HasIetfInvariantHeader()) {
- // SetBytesForConnectionIdToSend only applies to Google QUIC encoding.
- ASSERT_TRUE(Initialize());
- return;
- }
- client_config_.SetBytesForConnectionIdToSend(15);
- ASSERT_TRUE(Initialize());
-
- // Our server is permissive and allows for out of bounds values.
- SendSynchronousFooRequestAndCheckResponse();
- QuicConnection* client_connection = GetClientConnection();
- ASSERT_TRUE(client_connection);
- QuicPacketHeader* header =
- QuicConnectionPeer::GetLastHeader(client_connection);
- EXPECT_EQ(CONNECTION_ID_PRESENT, header->destination_connection_id_included);
-}
-
-TEST_P(EndToEndTest, ResetConnection) {
- ASSERT_TRUE(Initialize());
-
- SendSynchronousFooRequestAndCheckResponse();
- client_->ResetConnection();
- EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
- SendSynchronousBarRequestAndCheckResponse();
-}
-
-// Regression test for b/180737158.
-TEST_P(
- EndToEndTest,
- HalfRttResponseBlocksShloRetransmissionWithoutTokenBasedAddressValidation) {
- // Turn off token based address validation to make the server get constrained
- // by amplification factor during handshake.
- SetQuicFlag(FLAGS_quic_reject_retry_token_in_initial_packet, true);
- ASSERT_TRUE(Initialize());
- if (!version_.SupportsAntiAmplificationLimit()) {
- return;
- }
- // Perform a full 1-RTT handshake to get the new session ticket such that the
- // next connection will perform a 0-RTT handshake.
- EXPECT_TRUE(client_->client()->WaitForHandshakeConfirmed());
- client_->Disconnect();
-
- server_thread_->Pause();
- // Drop the 1st server packet which is the coalesced INITIAL + HANDSHAKE +
- // 1RTT.
- PacketDroppingTestWriter* writer = new PacketDroppingTestWriter();
- writer->set_fake_drop_first_n_packets(1);
- QuicDispatcherPeer::UseWriter(
- QuicServerPeer::GetDispatcher(server_thread_->server()), writer);
- server_thread_->Resume();
-
- // Large response (100KB) for 0-RTT request.
- std::string large_body(102400, 'a');
- AddToCache("/large_response", 200, large_body);
- SendSynchronousRequestAndCheckResponse(client_.get(), "/large_response",
- large_body);
-}
-
-TEST_P(EndToEndTest, MaxStreamsUberTest) {
- // Connect with lower fake packet loss than we'd like to test. Until
- // b/10126687 is fixed, losing handshake packets is pretty brutal.
- SetPacketLossPercentage(1);
- ASSERT_TRUE(Initialize());
- std::string large_body(10240, 'a');
- int max_streams = 100;
-
- AddToCache("/large_response", 200, large_body);
-
- EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
- SetPacketLossPercentage(10);
-
- for (int i = 0; i < max_streams; ++i) {
- EXPECT_LT(0, client_->SendRequest("/large_response"));
- }
-
- // WaitForEvents waits 50ms and returns true if there are outstanding
- // requests.
- while (client_->client()->WaitForEvents()) {
- ASSERT_TRUE(client_->connected());
- }
-}
-
-TEST_P(EndToEndTest, StreamCancelErrorTest) {
- ASSERT_TRUE(Initialize());
- std::string small_body(256, 'a');
-
- AddToCache("/small_response", 200, small_body);
-
- EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
-
- QuicSession* session = GetClientSession();
- ASSERT_TRUE(session);
- // Lose the request.
- SetPacketLossPercentage(100);
- EXPECT_LT(0, client_->SendRequest("/small_response"));
- client_->client()->WaitForEvents();
- // Transmit the cancel, and ensure the connection is torn down properly.
- SetPacketLossPercentage(0);
- QuicStreamId stream_id = GetNthClientInitiatedBidirectionalId(0);
- QuicConnection* client_connection = GetClientConnection();
- ASSERT_TRUE(client_connection);
- const QuicPacketCount packets_sent_before =
- client_connection->GetStats().packets_sent;
- session->ResetStream(stream_id, QUIC_STREAM_CANCELLED);
- const QuicPacketCount packets_sent_now =
- client_connection->GetStats().packets_sent;
-
- if (version_.UsesHttp3()) {
- // Make sure 2 packets were sent, one for QPACK instructions, another for
- // RESET_STREAM and STOP_SENDING.
- EXPECT_EQ(packets_sent_before + 2, packets_sent_now);
- }
-
- // WaitForEvents waits 50ms and returns true if there are outstanding
- // requests.
- while (client_->client()->WaitForEvents()) {
- ASSERT_TRUE(client_->connected());
- }
- // It should be completely fine to RST a stream before any data has been
- // received for that stream.
- EXPECT_THAT(client_->connection_error(), IsQuicNoError());
-}
-
-TEST_P(EndToEndTest, ConnectionMigrationClientIPChanged) {
- ASSERT_TRUE(Initialize());
- SendSynchronousFooRequestAndCheckResponse();
-
- // Store the client IP address which was used to send the first request.
- QuicIpAddress old_host =
- client_->client()->network_helper()->GetLatestClientAddress().host();
-
- // Migrate socket to the new IP address.
- QuicIpAddress new_host = TestLoopback(2);
- EXPECT_NE(old_host, new_host);
- ASSERT_TRUE(client_->client()->MigrateSocket(new_host));
-
- // Send a request using the new socket.
- SendSynchronousBarRequestAndCheckResponse();
-
- if (!version_.HasIetfQuicFrames() ||
- !client_->client()->session()->connection()->validate_client_address()) {
- return;
- }
- QuicConnection* client_connection = GetClientConnection();
- ASSERT_TRUE(client_connection);
- EXPECT_EQ(1u,
- client_connection->GetStats().num_connectivity_probing_received);
-
- // Send another request.
- SendSynchronousBarRequestAndCheckResponse();
- // By the time the 2nd request is completed, the PATH_RESPONSE must have been
- // received by the server.
- server_thread_->Pause();
- QuicConnection* server_connection = GetServerConnection();
- if (server_connection != nullptr) {
- EXPECT_FALSE(server_connection->HasPendingPathValidation());
- EXPECT_EQ(1u, server_connection->GetStats().num_validated_peer_migration);
- } else {
- ADD_FAILURE() << "Missing server connection";
- }
- server_thread_->Resume();
-}
-
-TEST_P(EndToEndTest, IetfConnectionMigrationClientIPChangedMultipleTimes) {
- ASSERT_TRUE(Initialize());
- if (!GetClientConnection()->connection_migration_use_new_cid()) {
- return;
- }
- SendSynchronousFooRequestAndCheckResponse();
-
- // Store the client IP address which was used to send the first request.
- QuicIpAddress host0 =
- client_->client()->network_helper()->GetLatestClientAddress().host();
- QuicConnection* client_connection = GetClientConnection();
- ASSERT_TRUE(client_connection != nullptr);
-
- // Migrate socket to a new IP address.
- QuicIpAddress host1 = TestLoopback(2);
- EXPECT_NE(host0, host1);
- ASSERT_TRUE(
- QuicConnectionPeer::HasUnusedPeerIssuedConnectionId(client_connection));
- QuicConnectionId server_cid0 = client_connection->connection_id();
- EXPECT_TRUE(QuicConnectionPeer::GetServerConnectionIdOnAlternativePath(
- client_connection)
- .IsEmpty());
- EXPECT_TRUE(client_->client()->MigrateSocket(host1));
- QuicConnectionId server_cid1 = client_connection->connection_id();
- EXPECT_FALSE(server_cid1.IsEmpty());
- EXPECT_NE(server_cid0, server_cid1);
- EXPECT_TRUE(QuicConnectionPeer::GetServerConnectionIdOnAlternativePath(
- client_connection)
- .IsEmpty());
-
- // Send a request using the new socket.
- SendSynchronousBarRequestAndCheckResponse();
- EXPECT_EQ(1u,
- client_connection->GetStats().num_connectivity_probing_received);
-
- // Send another request and wait for response making sure path response is
- // received at server.
- SendSynchronousBarRequestAndCheckResponse();
-
- // Migrate socket to a new IP address.
- WaitForNewConnectionIds();
- EXPECT_EQ(1u, client_connection->GetStats().num_retire_connection_id_sent);
- QuicIpAddress host2 = TestLoopback(3);
- EXPECT_NE(host0, host2);
- EXPECT_NE(host1, host2);
- EXPECT_TRUE(QuicConnectionPeer::GetServerConnectionIdOnAlternativePath(
- client_connection)
- .IsEmpty());
- EXPECT_TRUE(client_->client()->MigrateSocket(host2));
- QuicConnectionId server_cid2 = client_connection->connection_id();
- EXPECT_FALSE(server_cid2.IsEmpty());
- EXPECT_NE(server_cid0, server_cid2);
- EXPECT_NE(server_cid1, server_cid2);
- EXPECT_TRUE(QuicConnectionPeer::GetServerConnectionIdOnAlternativePath(
- client_connection)
- .IsEmpty());
-
- // Send another request using the new socket and wait for response making sure
- // path response is received at server.
- SendSynchronousBarRequestAndCheckResponse();
- EXPECT_EQ(2u,
- client_connection->GetStats().num_connectivity_probing_received);
-
- // Migrate socket back to an old IP address.
- WaitForNewConnectionIds();
- EXPECT_EQ(2u, client_connection->GetStats().num_retire_connection_id_sent);
- EXPECT_TRUE(QuicConnectionPeer::GetServerConnectionIdOnAlternativePath(
- client_connection)
- .IsEmpty());
- EXPECT_TRUE(client_->client()->MigrateSocket(host1));
- QuicConnectionId server_cid3 = client_connection->connection_id();
- EXPECT_FALSE(server_cid3.IsEmpty());
- EXPECT_NE(server_cid0, server_cid3);
- EXPECT_NE(server_cid1, server_cid3);
- EXPECT_NE(server_cid2, server_cid3);
- EXPECT_TRUE(QuicConnectionPeer::GetServerConnectionIdOnAlternativePath(
- client_connection)
- .IsEmpty());
- const auto* client_packet_creator =
- QuicConnectionPeer::GetPacketCreator(client_connection);
- EXPECT_TRUE(client_packet_creator->GetClientConnectionId().IsEmpty());
- EXPECT_EQ(server_cid3, client_packet_creator->GetServerConnectionId());
-
- // Send another request using the new socket and wait for response making sure
- // path response is received at server.
- SendSynchronousBarRequestAndCheckResponse();
- // Even this is an old path, server has forgotten about it and thus needs to
- // validate the path again.
- EXPECT_EQ(3u,
- client_connection->GetStats().num_connectivity_probing_received);
-
- WaitForNewConnectionIds();
- EXPECT_EQ(3u, client_connection->GetStats().num_retire_connection_id_sent);
-
- server_thread_->Pause();
- QuicConnection* server_connection = GetServerConnection();
- // By the time the 2nd request is completed, the PATH_RESPONSE must have been
- // received by the server.
- EXPECT_FALSE(server_connection->HasPendingPathValidation());
- EXPECT_EQ(3u, server_connection->GetStats().num_validated_peer_migration);
- EXPECT_EQ(server_cid3, server_connection->connection_id());
- const auto* server_packet_creator =
- QuicConnectionPeer::GetPacketCreator(server_connection);
- EXPECT_EQ(server_cid3, server_packet_creator->GetServerConnectionId());
- EXPECT_TRUE(QuicConnectionPeer::GetServerConnectionIdOnAlternativePath(
- server_connection)
- .IsEmpty());
- EXPECT_EQ(4u, server_connection->GetStats().num_new_connection_id_sent);
- server_thread_->Resume();
-}
-
-TEST_P(EndToEndTest,
- ConnectionMigrationWithNonZeroConnectionIDClientIPChangedMultipleTimes) {
- if (!version_.SupportsClientConnectionIds()) {
- ASSERT_TRUE(Initialize());
- return;
- }
- override_client_connection_id_length_ = kQuicDefaultConnectionIdLength;
- ASSERT_TRUE(Initialize());
- if (!GetClientConnection()->connection_migration_use_new_cid()) {
- return;
- }
- SendSynchronousFooRequestAndCheckResponse();
-
- // Store the client IP address which was used to send the first request.
- QuicIpAddress host0 =
- client_->client()->network_helper()->GetLatestClientAddress().host();
- QuicConnection* client_connection = GetClientConnection();
- ASSERT_TRUE(client_connection != nullptr);
-
- // Migrate socket to a new IP address.
- QuicIpAddress host1 = TestLoopback(2);
- EXPECT_NE(host0, host1);
- ASSERT_TRUE(
- QuicConnectionPeer::HasUnusedPeerIssuedConnectionId(client_connection));
- QuicConnectionId server_cid0 = client_connection->connection_id();
- QuicConnectionId client_cid0 = client_connection->client_connection_id();
- EXPECT_TRUE(QuicConnectionPeer::GetServerConnectionIdOnAlternativePath(
- client_connection)
- .IsEmpty());
- EXPECT_TRUE(QuicConnectionPeer::GetClientConnectionIdOnAlternativePath(
- client_connection)
- .IsEmpty());
- EXPECT_TRUE(client_->client()->MigrateSocket(host1));
- QuicConnectionId server_cid1 = client_connection->connection_id();
- QuicConnectionId client_cid1 = client_connection->client_connection_id();
- EXPECT_FALSE(server_cid1.IsEmpty());
- EXPECT_FALSE(client_cid1.IsEmpty());
- EXPECT_NE(server_cid0, server_cid1);
- EXPECT_NE(client_cid0, client_cid1);
- EXPECT_TRUE(QuicConnectionPeer::GetServerConnectionIdOnAlternativePath(
- client_connection)
- .IsEmpty());
- EXPECT_TRUE(QuicConnectionPeer::GetClientConnectionIdOnAlternativePath(
- client_connection)
- .IsEmpty());
-
- // Send another request to ensure that the server will have time to finish the
- // reverse path validation and send address token.
- SendSynchronousBarRequestAndCheckResponse();
- EXPECT_EQ(1u,
- client_connection->GetStats().num_connectivity_probing_received);
-
- // Migrate socket to a new IP address.
- WaitForNewConnectionIds();
- EXPECT_EQ(1u, client_connection->GetStats().num_retire_connection_id_sent);
- EXPECT_EQ(2u, client_connection->GetStats().num_new_connection_id_sent);
- QuicIpAddress host2 = TestLoopback(3);
- EXPECT_NE(host0, host2);
- EXPECT_NE(host1, host2);
- EXPECT_TRUE(client_->client()->MigrateSocket(host2));
- QuicConnectionId server_cid2 = client_connection->connection_id();
- QuicConnectionId client_cid2 = client_connection->client_connection_id();
- EXPECT_FALSE(server_cid2.IsEmpty());
- EXPECT_NE(server_cid0, server_cid2);
- EXPECT_NE(server_cid1, server_cid2);
- EXPECT_FALSE(client_cid2.IsEmpty());
- EXPECT_NE(client_cid0, client_cid2);
- EXPECT_NE(client_cid1, client_cid2);
- EXPECT_TRUE(QuicConnectionPeer::GetServerConnectionIdOnAlternativePath(
- client_connection)
- .IsEmpty());
- EXPECT_TRUE(QuicConnectionPeer::GetClientConnectionIdOnAlternativePath(
- client_connection)
- .IsEmpty());
-
- // Send another request to ensure that the server will have time to finish the
- // reverse path validation and send address token.
- SendSynchronousBarRequestAndCheckResponse();
- EXPECT_EQ(2u,
- client_connection->GetStats().num_connectivity_probing_received);
-
- // Migrate socket back to an old IP address.
- WaitForNewConnectionIds();
- EXPECT_EQ(2u, client_connection->GetStats().num_retire_connection_id_sent);
- EXPECT_EQ(3u, client_connection->GetStats().num_new_connection_id_sent);
- EXPECT_TRUE(client_->client()->MigrateSocket(host1));
- QuicConnectionId server_cid3 = client_connection->connection_id();
- QuicConnectionId client_cid3 = client_connection->client_connection_id();
- EXPECT_FALSE(server_cid3.IsEmpty());
- EXPECT_NE(server_cid0, server_cid3);
- EXPECT_NE(server_cid1, server_cid3);
- EXPECT_NE(server_cid2, server_cid3);
- EXPECT_FALSE(client_cid3.IsEmpty());
- EXPECT_NE(client_cid0, client_cid3);
- EXPECT_NE(client_cid1, client_cid3);
- EXPECT_NE(client_cid2, client_cid3);
- const auto* client_packet_creator =
- QuicConnectionPeer::GetPacketCreator(client_connection);
- EXPECT_EQ(client_cid3, client_packet_creator->GetClientConnectionId());
- EXPECT_EQ(server_cid3, client_packet_creator->GetServerConnectionId());
- EXPECT_TRUE(QuicConnectionPeer::GetServerConnectionIdOnAlternativePath(
- client_connection)
- .IsEmpty());
-
- // Send another request to ensure that the server will have time to finish the
- // reverse path validation and send address token.
- SendSynchronousBarRequestAndCheckResponse();
- // Even this is an old path, server has forgotten about it and thus needs to
- // validate the path again.
- EXPECT_EQ(3u,
- client_connection->GetStats().num_connectivity_probing_received);
-
- WaitForNewConnectionIds();
- EXPECT_EQ(3u, client_connection->GetStats().num_retire_connection_id_sent);
- EXPECT_EQ(4u, client_connection->GetStats().num_new_connection_id_sent);
-
- server_thread_->Pause();
- // By the time the 2nd request is completed, the PATH_RESPONSE must have been
- // received by the server.
- QuicConnection* server_connection = GetServerConnection();
- EXPECT_FALSE(server_connection->HasPendingPathValidation());
- EXPECT_EQ(3u, server_connection->GetStats().num_validated_peer_migration);
- EXPECT_EQ(server_cid3, server_connection->connection_id());
- EXPECT_EQ(client_cid3, server_connection->client_connection_id());
- EXPECT_TRUE(QuicConnectionPeer::GetServerConnectionIdOnAlternativePath(
- server_connection)
- .IsEmpty());
- const auto* server_packet_creator =
- QuicConnectionPeer::GetPacketCreator(server_connection);
- EXPECT_EQ(client_cid3, server_packet_creator->GetClientConnectionId());
- EXPECT_EQ(server_cid3, server_packet_creator->GetServerConnectionId());
- EXPECT_EQ(3u, server_connection->GetStats().num_retire_connection_id_sent);
- EXPECT_EQ(4u, server_connection->GetStats().num_new_connection_id_sent);
- server_thread_->Resume();
-}
-
-TEST_P(EndToEndTest, ConnectionMigrationNewTokenForNewIp) {
- ASSERT_TRUE(Initialize());
- if (!version_.HasIetfQuicFrames() ||
- !client_->client()->session()->connection()->validate_client_address()) {
- return;
- }
- SendSynchronousFooRequestAndCheckResponse();
-
- // Store the client IP address which was used to send the first request.
- QuicIpAddress old_host =
- client_->client()->network_helper()->GetLatestClientAddress().host();
-
- // Migrate socket to the new IP address.
- QuicIpAddress new_host = TestLoopback(2);
- EXPECT_NE(old_host, new_host);
- ASSERT_TRUE(client_->client()->MigrateSocket(new_host));
-
- // Send a request using the new socket.
- SendSynchronousBarRequestAndCheckResponse();
- QuicConnection* client_connection = GetClientConnection();
- ASSERT_TRUE(client_connection);
- EXPECT_EQ(1u,
- client_connection->GetStats().num_connectivity_probing_received);
-
- // Send another request to ensure that the server will have time to finish the
- // reverse path validation and send address token.
- SendSynchronousBarRequestAndCheckResponse();
-
- client_->Disconnect();
- // The 0-RTT handshake should succeed.
- client_->Connect();
- EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
- ASSERT_TRUE(client_->client()->connected());
- SendSynchronousFooRequestAndCheckResponse();
-
- EXPECT_TRUE(GetClientSession()->EarlyDataAccepted());
- EXPECT_TRUE(client_->client()->EarlyDataAccepted());
-
- server_thread_->Pause();
- QuicConnection* server_connection = GetServerConnection();
- if (server_connection != nullptr) {
- // Verify address is validated via validating token received in INITIAL
- // packet.
- EXPECT_FALSE(
- server_connection->GetStats().address_validated_via_decrypting_packet);
- EXPECT_TRUE(server_connection->GetStats().address_validated_via_token);
- } else {
- ADD_FAILURE() << "Missing server connection";
- }
- server_thread_->Resume();
- client_->Disconnect();
-}
-
-// A writer which copies the packet and send the copy with a specified self
-// address and then send the same packet with the original self address.
-class DuplicatePacketWithSpoofedSelfAddressWriter
- : public QuicPacketWriterWrapper {
- public:
- WriteResult WritePacket(const char* buffer, size_t buf_len,
- const QuicIpAddress& self_address,
- const QuicSocketAddress& peer_address,
- PerPacketOptions* options) override {
- if (self_address_to_overwrite_.IsInitialized()) {
- // Send the same packet on the overwriting address before sending on the
- // actual self address.
- QuicPacketWriterWrapper::WritePacket(
- buffer, buf_len, self_address_to_overwrite_, peer_address, options);
- }
- return QuicPacketWriterWrapper::WritePacket(buffer, buf_len, self_address,
- peer_address, options);
- }
-
- void set_self_address_to_overwrite(const QuicIpAddress& self_address) {
- self_address_to_overwrite_ = self_address;
- }
-
- private:
- QuicIpAddress self_address_to_overwrite_;
-};
-
-TEST_P(EndToEndTest, ClientAddressSpoofedForSomePeriod) {
- ASSERT_TRUE(Initialize());
- if (!GetClientConnection()->connection_migration_use_new_cid()) {
- return;
- }
- auto writer = new DuplicatePacketWithSpoofedSelfAddressWriter();
- client_.reset(CreateQuicClient(writer));
-
- // Make sure client has unused peer connection ID before migration.
- SendSynchronousFooRequestAndCheckResponse();
- ASSERT_TRUE(QuicConnectionPeer::HasUnusedPeerIssuedConnectionId(
- GetClientConnection()));
-
- QuicIpAddress real_host =
- client_->client()->session()->connection()->self_address().host();
- ASSERT_TRUE(client_->MigrateSocket(real_host));
- SendSynchronousFooRequestAndCheckResponse();
- EXPECT_EQ(
- 0u, GetClientConnection()->GetStats().num_connectivity_probing_received);
- EXPECT_EQ(
- real_host,
- client_->client()->network_helper()->GetLatestClientAddress().host());
- client_->WaitForDelayedAcks();
-
- std::string large_body(10240, 'a');
- AddToCache("/large_response", 200, large_body);
-
- QuicIpAddress spoofed_host = TestLoopback(2);
- writer->set_self_address_to_overwrite(spoofed_host);
-
- client_->SendRequest("/large_response");
- QuicConnection* client_connection = GetClientConnection();
- QuicPacketCount num_packets_received =
- client_connection->GetStats().packets_received;
-
- while (client_->client()->WaitForEvents() && client_->connected()) {
- if (client_connection->GetStats().packets_received > num_packets_received) {
- // Ideally the client won't receive any packets till the server finds out
- // the new client address is not working. But there are 2 corner cases:
- // 1) Before the server received the packet from spoofed address, it might
- // send packets to the real client address. So the client will immediately
- // switch back to use the original address;
- // 2) Between the server fails reverse path validation and the client
- // receives packets again, the client might sent some packets with the
- // spoofed address and triggers another migration.
- // In both corner cases, the attempted migration should fail and fall back
- // to the working path.
- writer->set_self_address_to_overwrite(QuicIpAddress());
- }
- }
- client_->WaitForResponse();
- EXPECT_EQ(large_body, client_->response_body());
-}
-
-TEST_P(EndToEndTest,
- AsynchronousConnectionMigrationClientIPChangedMultipleTimes) {
- ASSERT_TRUE(Initialize());
- if (!GetClientConnection()->connection_migration_use_new_cid()) {
- return;
- }
- client_.reset(CreateQuicClient(nullptr));
-
- SendSynchronousFooRequestAndCheckResponse();
-
- // Store the client IP address which was used to send the first request.
- QuicIpAddress host0 =
- client_->client()->network_helper()->GetLatestClientAddress().host();
- QuicConnection* client_connection = GetClientConnection();
- QuicConnectionId server_cid0 = client_connection->connection_id();
- // Server should have one new connection ID upon handshake completion.
- ASSERT_TRUE(
- QuicConnectionPeer::HasUnusedPeerIssuedConnectionId(client_connection));
-
- // Migrate socket to new IP address #1.
- QuicIpAddress host1 = TestLoopback(2);
- EXPECT_NE(host0, host1);
- ASSERT_TRUE(client_->client()->ValidateAndMigrateSocket(host1));
- while (client_->client()->HasPendingPathValidation()) {
- client_->client()->WaitForEvents();
- }
- EXPECT_EQ(host1, client_->client()->session()->self_address().host());
- EXPECT_EQ(1u,
- client_connection->GetStats().num_connectivity_probing_received);
- QuicConnectionId server_cid1 = client_connection->connection_id();
- EXPECT_NE(server_cid0, server_cid1);
- EXPECT_TRUE(QuicConnectionPeer::GetServerConnectionIdOnAlternativePath(
- client_connection)
- .IsEmpty());
-
- // Send a request using the new socket.
- SendSynchronousBarRequestAndCheckResponse();
-
- // Migrate socket to new IP address #2.
- WaitForNewConnectionIds();
- QuicIpAddress host2 = TestLoopback(3);
- EXPECT_NE(host0, host1);
- ASSERT_TRUE(client_->client()->ValidateAndMigrateSocket(host2));
-
- while (client_->client()->HasPendingPathValidation()) {
- client_->client()->WaitForEvents();
- }
- EXPECT_EQ(host2, client_->client()->session()->self_address().host());
- EXPECT_EQ(2u,
- client_connection->GetStats().num_connectivity_probing_received);
- QuicConnectionId server_cid2 = client_connection->connection_id();
- EXPECT_NE(server_cid0, server_cid2);
- EXPECT_NE(server_cid1, server_cid2);
- EXPECT_TRUE(QuicConnectionPeer::GetServerConnectionIdOnAlternativePath(
- client_connection)
- .IsEmpty());
-
- // Send a request using the new socket.
- SendSynchronousBarRequestAndCheckResponse();
-
- // Migrate socket back to IP address #1.
- WaitForNewConnectionIds();
- ASSERT_TRUE(client_->client()->ValidateAndMigrateSocket(host1));
-
- while (client_->client()->HasPendingPathValidation()) {
- client_->client()->WaitForEvents();
- }
- EXPECT_EQ(host1, client_->client()->session()->self_address().host());
- EXPECT_EQ(3u,
- client_connection->GetStats().num_connectivity_probing_received);
- QuicConnectionId server_cid3 = client_connection->connection_id();
- EXPECT_NE(server_cid0, server_cid3);
- EXPECT_NE(server_cid1, server_cid3);
- EXPECT_NE(server_cid2, server_cid3);
- EXPECT_TRUE(QuicConnectionPeer::GetServerConnectionIdOnAlternativePath(
- client_connection)
- .IsEmpty());
-
- // Send a request using the new socket.
- SendSynchronousBarRequestAndCheckResponse();
- server_thread_->Pause();
- const QuicConnection* server_connection = GetServerConnection();
- EXPECT_EQ(server_connection->connection_id(), server_cid3);
- EXPECT_TRUE(QuicConnectionPeer::GetServerConnectionIdOnAlternativePath(
- server_connection)
- .IsEmpty());
- server_thread_->Resume();
-
- // There should be 1 new connection ID issued by the server.
- WaitForNewConnectionIds();
-}
-
-TEST_P(EndToEndTest,
- AsynchronousConnectionMigrationClientIPChangedWithNonEmptyClientCID) {
- if (!version_.SupportsClientConnectionIds()) {
- ASSERT_TRUE(Initialize());
- return;
- }
- override_client_connection_id_length_ = kQuicDefaultConnectionIdLength;
- ASSERT_TRUE(Initialize());
- if (!GetClientConnection()->connection_migration_use_new_cid()) {
- return;
- }
- client_.reset(CreateQuicClient(nullptr));
-
- SendSynchronousFooRequestAndCheckResponse();
-
- // Store the client IP address which was used to send the first request.
- QuicIpAddress old_host =
- client_->client()->network_helper()->GetLatestClientAddress().host();
- auto* client_connection = GetClientConnection();
- QuicConnectionId client_cid0 = client_connection->client_connection_id();
- QuicConnectionId server_cid0 = client_connection->connection_id();
-
- // Migrate socket to the new IP address.
- QuicIpAddress new_host = TestLoopback(2);
- EXPECT_NE(old_host, new_host);
- ASSERT_TRUE(client_->client()->ValidateAndMigrateSocket(new_host));
-
- while (client_->client()->HasPendingPathValidation()) {
- client_->client()->WaitForEvents();
- }
- EXPECT_EQ(new_host, client_->client()->session()->self_address().host());
- EXPECT_EQ(1u,
- client_connection->GetStats().num_connectivity_probing_received);
- QuicConnectionId client_cid1 = client_connection->client_connection_id();
- QuicConnectionId server_cid1 = client_connection->connection_id();
- const auto* client_packet_creator =
- QuicConnectionPeer::GetPacketCreator(client_connection);
- EXPECT_EQ(client_cid1, client_packet_creator->GetClientConnectionId());
- EXPECT_EQ(server_cid1, client_packet_creator->GetServerConnectionId());
- // Send a request using the new socket.
- SendSynchronousBarRequestAndCheckResponse();
-
- server_thread_->Pause();
- QuicConnection* server_connection = GetServerConnection();
- EXPECT_EQ(client_cid1, server_connection->client_connection_id());
- EXPECT_EQ(server_cid1, server_connection->connection_id());
- const auto* server_packet_creator =
- QuicConnectionPeer::GetPacketCreator(server_connection);
- EXPECT_EQ(client_cid1, server_packet_creator->GetClientConnectionId());
- EXPECT_EQ(server_cid1, server_packet_creator->GetServerConnectionId());
- server_thread_->Resume();
-}
-
-TEST_P(EndToEndTest, ConnectionMigrationClientPortChanged) {
- // Tests that the client's port can change during an established QUIC
- // connection, and that doing so does not result in the connection being
- // closed by the server.
- ASSERT_TRUE(Initialize());
-
- SendSynchronousFooRequestAndCheckResponse();
-
- // Store the client address which was used to send the first request.
- QuicSocketAddress old_address =
- client_->client()->network_helper()->GetLatestClientAddress();
- int old_fd = client_->client()->GetLatestFD();
-
- // Create a new socket before closing the old one, which will result in a new
- // ephemeral port.
- QuicClientPeer::CreateUDPSocketAndBind(client_->client());
-
- // Stop listening and close the old FD.
- QuicClientPeer::CleanUpUDPSocket(client_->client(), old_fd);
-
- // The packet writer needs to be updated to use the new FD.
- client_->client()->network_helper()->CreateQuicPacketWriter();
-
- // Change the internal state of the client and connection to use the new port,
- // this is done because in a real NAT rebinding the client wouldn't see any
- // port change, and so expects no change to incoming port.
- // This is kind of ugly, but needed as we are simply swapping out the client
- // FD rather than any more complex NAT rebinding simulation.
- int new_port =
- client_->client()->network_helper()->GetLatestClientAddress().port();
- QuicClientPeer::SetClientPort(client_->client(), new_port);
- QuicConnection* client_connection = GetClientConnection();
- ASSERT_TRUE(client_connection);
- QuicConnectionPeer::SetSelfAddress(
- client_connection,
- QuicSocketAddress(client_connection->self_address().host(), new_port));
-
- // Register the new FD for epoll events.
- int new_fd = client_->client()->GetLatestFD();
- QuicEpollServer* eps = client_->epoll_server();
- eps->RegisterFD(new_fd, client_->client()->epoll_network_helper(),
- EPOLLIN | EPOLLOUT | EPOLLET);
-
- // Send a second request, using the new FD.
- SendSynchronousBarRequestAndCheckResponse();
-
- // Verify that the client's ephemeral port is different.
- QuicSocketAddress new_address =
- client_->client()->network_helper()->GetLatestClientAddress();
- EXPECT_EQ(old_address.host(), new_address.host());
- EXPECT_NE(old_address.port(), new_address.port());
-
- if (!version_.HasIetfQuicFrames() ||
- !GetClientConnection()->validate_client_address()) {
- return;
- }
-
- server_thread_->Pause();
- QuicConnection* server_connection = GetServerConnection();
- if (server_connection != nullptr) {
- EXPECT_FALSE(server_connection->HasPendingPathValidation());
- EXPECT_EQ(1u, server_connection->GetStats().num_validated_peer_migration);
- } else {
- ADD_FAILURE() << "Missing server connection";
- }
- server_thread_->Resume();
-}
-
-TEST_P(EndToEndTest, NegotiatedInitialCongestionWindow) {
- SetQuicReloadableFlag(quic_unified_iw_options, true);
- client_extra_copts_.push_back(kIW03);
-
- ASSERT_TRUE(Initialize());
-
- // Values are exchanged during crypto handshake, so wait for that to finish.
- EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
- server_thread_->WaitForCryptoHandshakeConfirmed();
- server_thread_->Pause();
- QuicConnection* server_connection = GetServerConnection();
- if (server_connection != nullptr) {
- QuicPacketCount cwnd =
- server_connection->sent_packet_manager().initial_congestion_window();
- EXPECT_EQ(3u, cwnd);
- } else {
- ADD_FAILURE() << "Missing server connection";
- }
- server_thread_->Resume();
-}
-
-TEST_P(EndToEndTest, DifferentFlowControlWindows) {
- // Client and server can set different initial flow control receive windows.
- // These are sent in CHLO/SHLO. Tests that these values are exchanged properly
- // in the crypto handshake.
- const uint32_t kClientStreamIFCW = 123456;
- const uint32_t kClientSessionIFCW = 234567;
- set_client_initial_stream_flow_control_receive_window(kClientStreamIFCW);
- set_client_initial_session_flow_control_receive_window(kClientSessionIFCW);
-
- uint32_t kServerStreamIFCW = 32 * 1024;
- uint32_t kServerSessionIFCW = 48 * 1024;
- set_server_initial_stream_flow_control_receive_window(kServerStreamIFCW);
- set_server_initial_session_flow_control_receive_window(kServerSessionIFCW);
-
- ASSERT_TRUE(Initialize());
-
- // Values are exchanged during crypto handshake, so wait for that to finish.
- EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
- server_thread_->WaitForCryptoHandshakeConfirmed();
-
- // Open a data stream to make sure the stream level flow control is updated.
- QuicSpdyClientStream* stream = client_->GetOrCreateStream();
- WriteHeadersOnStream(stream);
- stream->WriteOrBufferBody("hello", false);
-
- if (!version_.UsesTls()) {
- // IFWA only exists with QUIC_CRYPTO.
- // Client should have the right values for server's receive window.
- ASSERT_TRUE(client_->client()
- ->client_session()
- ->config()
- ->HasReceivedInitialStreamFlowControlWindowBytes());
- EXPECT_EQ(kServerStreamIFCW,
- client_->client()
- ->client_session()
- ->config()
- ->ReceivedInitialStreamFlowControlWindowBytes());
- ASSERT_TRUE(client_->client()
- ->client_session()
- ->config()
- ->HasReceivedInitialSessionFlowControlWindowBytes());
- EXPECT_EQ(kServerSessionIFCW,
- client_->client()
- ->client_session()
- ->config()
- ->ReceivedInitialSessionFlowControlWindowBytes());
- }
- EXPECT_EQ(kServerStreamIFCW, QuicStreamPeer::SendWindowOffset(stream));
- QuicSpdyClientSession* client_session = GetClientSession();
- ASSERT_TRUE(client_session);
- EXPECT_EQ(kServerSessionIFCW, QuicFlowControllerPeer::SendWindowOffset(
- client_session->flow_controller()));
-
- // Server should have the right values for client's receive window.
- server_thread_->Pause();
- QuicSpdySession* server_session = GetServerSession();
- if (server_session == nullptr) {
- ADD_FAILURE() << "Missing server session";
- server_thread_->Resume();
- return;
- }
- QuicConfig server_config = *server_session->config();
- EXPECT_EQ(kClientSessionIFCW, QuicFlowControllerPeer::SendWindowOffset(
- server_session->flow_controller()));
- server_thread_->Resume();
- if (version_.UsesTls()) {
- // IFWA only exists with QUIC_CRYPTO.
- return;
- }
- ASSERT_TRUE(server_config.HasReceivedInitialStreamFlowControlWindowBytes());
- EXPECT_EQ(kClientStreamIFCW,
- server_config.ReceivedInitialStreamFlowControlWindowBytes());
- ASSERT_TRUE(server_config.HasReceivedInitialSessionFlowControlWindowBytes());
- EXPECT_EQ(kClientSessionIFCW,
- server_config.ReceivedInitialSessionFlowControlWindowBytes());
-}
-
-// Test negotiation of IFWA connection option.
-TEST_P(EndToEndTest, NegotiatedServerInitialFlowControlWindow) {
- const uint32_t kClientStreamIFCW = 123456;
- const uint32_t kClientSessionIFCW = 234567;
- set_client_initial_stream_flow_control_receive_window(kClientStreamIFCW);
- set_client_initial_session_flow_control_receive_window(kClientSessionIFCW);
-
- uint32_t kServerStreamIFCW = 32 * 1024;
- uint32_t kServerSessionIFCW = 48 * 1024;
- set_server_initial_stream_flow_control_receive_window(kServerStreamIFCW);
- set_server_initial_session_flow_control_receive_window(kServerSessionIFCW);
-
- // Bump the window.
- const uint32_t kExpectedStreamIFCW = 1024 * 1024;
- const uint32_t kExpectedSessionIFCW = 1.5 * 1024 * 1024;
- client_extra_copts_.push_back(kIFWA);
-
- ASSERT_TRUE(Initialize());
-
- // Values are exchanged during crypto handshake, so wait for that to finish.
- EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
- server_thread_->WaitForCryptoHandshakeConfirmed();
-
- // Open a data stream to make sure the stream level flow control is updated.
- QuicSpdyClientStream* stream = client_->GetOrCreateStream();
- WriteHeadersOnStream(stream);
- stream->WriteOrBufferBody("hello", false);
-
- QuicSpdyClientSession* client_session = GetClientSession();
- ASSERT_TRUE(client_session);
-
- if (!version_.UsesTls()) {
- // IFWA only exists with QUIC_CRYPTO.
- // Client should have the right values for server's receive window.
- ASSERT_TRUE(client_session->config()
- ->HasReceivedInitialStreamFlowControlWindowBytes());
- EXPECT_EQ(kExpectedStreamIFCW,
- client_session->config()
- ->ReceivedInitialStreamFlowControlWindowBytes());
- ASSERT_TRUE(client_session->config()
- ->HasReceivedInitialSessionFlowControlWindowBytes());
- EXPECT_EQ(kExpectedSessionIFCW,
- client_session->config()
- ->ReceivedInitialSessionFlowControlWindowBytes());
- }
- EXPECT_EQ(kExpectedStreamIFCW, QuicStreamPeer::SendWindowOffset(stream));
- EXPECT_EQ(kExpectedSessionIFCW, QuicFlowControllerPeer::SendWindowOffset(
- client_session->flow_controller()));
-}
-
-TEST_P(EndToEndTest, HeadersAndCryptoStreamsNoConnectionFlowControl) {
- // The special headers and crypto streams should be subject to per-stream flow
- // control limits, but should not be subject to connection level flow control
- const uint32_t kStreamIFCW = 32 * 1024;
- const uint32_t kSessionIFCW = 48 * 1024;
- set_client_initial_stream_flow_control_receive_window(kStreamIFCW);
- set_client_initial_session_flow_control_receive_window(kSessionIFCW);
- set_server_initial_stream_flow_control_receive_window(kStreamIFCW);
- set_server_initial_session_flow_control_receive_window(kSessionIFCW);
-
- ASSERT_TRUE(Initialize());
-
- // Wait for crypto handshake to finish. This should have contributed to the
- // crypto stream flow control window, but not affected the session flow
- // control window.
- EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
- server_thread_->WaitForCryptoHandshakeConfirmed();
-
- QuicSpdyClientSession* client_session = GetClientSession();
- ASSERT_TRUE(client_session);
- QuicCryptoStream* crypto_stream =
- QuicSessionPeer::GetMutableCryptoStream(client_session);
- ASSERT_TRUE(crypto_stream);
- // In v47 and later, the crypto handshake (sent in CRYPTO frames) is not
- // subject to flow control.
- if (!version_.UsesCryptoFrames()) {
- EXPECT_LT(QuicStreamPeer::SendWindowSize(crypto_stream), kStreamIFCW);
- }
- // When stream type is enabled, control streams will send settings and
- // contribute to flow control windows, so this expectation is no longer valid.
- if (!version_.UsesHttp3()) {
- EXPECT_EQ(kSessionIFCW, QuicFlowControllerPeer::SendWindowSize(
- client_session->flow_controller()));
- }
-
- // Send a request with no body, and verify that the connection level window
- // has not been affected.
- EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
-
- // No headers stream in IETF QUIC.
- if (version_.UsesHttp3()) {
- return;
- }
-
- QuicHeadersStream* headers_stream =
- QuicSpdySessionPeer::GetHeadersStream(client_session);
- ASSERT_TRUE(headers_stream);
- EXPECT_LT(QuicStreamPeer::SendWindowSize(headers_stream), kStreamIFCW);
- EXPECT_EQ(kSessionIFCW, QuicFlowControllerPeer::SendWindowSize(
- client_session->flow_controller()));
-
- // Server should be in a similar state: connection flow control window should
- // not have any bytes marked as received.
- server_thread_->Pause();
- QuicSession* server_session = GetServerSession();
- if (server_session != nullptr) {
- QuicFlowController* server_connection_flow_controller =
- server_session->flow_controller();
- EXPECT_EQ(kSessionIFCW, QuicFlowControllerPeer::ReceiveWindowSize(
- server_connection_flow_controller));
- } else {
- ADD_FAILURE() << "Missing server session";
- }
- server_thread_->Resume();
-}
-
-TEST_P(EndToEndTest, FlowControlsSynced) {
- set_smaller_flow_control_receive_window();
-
- ASSERT_TRUE(Initialize());
-
- EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
- server_thread_->WaitForCryptoHandshakeConfirmed();
-
- QuicSpdySession* const client_session = GetClientSession();
- ASSERT_TRUE(client_session);
-
- if (version_.UsesHttp3()) {
- // Make sure that the client has received the initial SETTINGS frame, which
- // is sent in the first packet on the control stream.
- while (!QuicSpdySessionPeer::GetReceiveControlStream(client_session)) {
- client_->client()->WaitForEvents();
- ASSERT_TRUE(client_->connected());
- }
- }
-
- // Make sure that all data sent by the client has been received by the server
- // (and the ack received by the client).
- while (client_session->HasUnackedStreamData()) {
- client_->client()->WaitForEvents();
- ASSERT_TRUE(client_->connected());
- }
-
- server_thread_->Pause();
-
- QuicSpdySession* const server_session = GetServerSession();
- if (server_session == nullptr) {
- ADD_FAILURE() << "Missing server session";
- server_thread_->Resume();
- return;
- }
- ExpectFlowControlsSynced(client_session, server_session);
-
- // Check control streams.
- if (version_.UsesHttp3()) {
- ExpectFlowControlsSynced(
- QuicSpdySessionPeer::GetReceiveControlStream(client_session),
- QuicSpdySessionPeer::GetSendControlStream(server_session));
- ExpectFlowControlsSynced(
- QuicSpdySessionPeer::GetSendControlStream(client_session),
- QuicSpdySessionPeer::GetReceiveControlStream(server_session));
- }
-
- // Check crypto stream.
- if (!version_.UsesCryptoFrames()) {
- ExpectFlowControlsSynced(
- QuicSessionPeer::GetMutableCryptoStream(client_session),
- QuicSessionPeer::GetMutableCryptoStream(server_session));
- }
-
- // Check headers stream.
- if (!version_.UsesHttp3()) {
- SpdyFramer spdy_framer(SpdyFramer::ENABLE_COMPRESSION);
- SpdySettingsIR settings_frame;
- settings_frame.AddSetting(spdy::SETTINGS_MAX_HEADER_LIST_SIZE,
- kDefaultMaxUncompressedHeaderSize);
- SpdySerializedFrame frame(spdy_framer.SerializeFrame(settings_frame));
-
- QuicHeadersStream* client_header_stream =
- QuicSpdySessionPeer::GetHeadersStream(client_session);
- QuicHeadersStream* server_header_stream =
- QuicSpdySessionPeer::GetHeadersStream(server_session);
- // Both client and server are sending this SETTINGS frame, and the send
- // window is consumed. But because of timing issue, the server may send or
- // not send the frame, and the client may send/ not send / receive / not
- // receive the frame.
- // TODO(fayang): Rewrite this part because it is hacky.
- QuicByteCount win_difference1 =
- QuicStreamPeer::ReceiveWindowSize(server_header_stream) -
- QuicStreamPeer::SendWindowSize(client_header_stream);
- if (win_difference1 != 0) {
- EXPECT_EQ(frame.size(), win_difference1);
- }
-
- QuicByteCount win_difference2 =
- QuicStreamPeer::ReceiveWindowSize(client_header_stream) -
- QuicStreamPeer::SendWindowSize(server_header_stream);
- if (win_difference2 != 0) {
- EXPECT_EQ(frame.size(), win_difference2);
- }
-
- // Client *may* have received the SETTINGs frame.
- // TODO(fayang): Rewrite this part because it is hacky.
- float ratio1 = static_cast<float>(QuicFlowControllerPeer::ReceiveWindowSize(
- client_session->flow_controller())) /
- QuicStreamPeer::ReceiveWindowSize(
- QuicSpdySessionPeer::GetHeadersStream(client_session));
- float ratio2 = static_cast<float>(QuicFlowControllerPeer::ReceiveWindowSize(
- client_session->flow_controller())) /
- (QuicStreamPeer::ReceiveWindowSize(
- QuicSpdySessionPeer::GetHeadersStream(client_session)) +
- frame.size());
- EXPECT_TRUE(ratio1 == kSessionToStreamRatio ||
- ratio2 == kSessionToStreamRatio);
- }
-
- server_thread_->Resume();
-}
-
-TEST_P(EndToEndTest, RequestWithNoBodyWillNeverSendStreamFrameWithFIN) {
- // A stream created on receipt of a simple request with no body will never get
- // a stream frame with a FIN. Verify that we don't keep track of the stream in
- // the locally closed streams map: it will never be removed if so.
- ASSERT_TRUE(Initialize());
-
- // Send a simple headers only request, and receive response.
- SendSynchronousFooRequestAndCheckResponse();
-
- // Now verify that the server is not waiting for a final FIN or RST.
- server_thread_->Pause();
- QuicSession* server_session = GetServerSession();
- if (server_session != nullptr) {
- EXPECT_EQ(0u, QuicSessionPeer::GetLocallyClosedStreamsHighestOffset(
- server_session)
- .size());
- } else {
- ADD_FAILURE() << "Missing server session";
- }
- server_thread_->Resume();
-}
-
-// TestAckListener counts how many bytes are acked during its lifetime.
-class TestAckListener : public QuicAckListenerInterface {
- public:
- TestAckListener() {}
-
- void OnPacketAcked(int acked_bytes,
- QuicTime::Delta /*delta_largest_observed*/) override {
- total_bytes_acked_ += acked_bytes;
- }
-
- void OnPacketRetransmitted(int /*retransmitted_bytes*/) override {}
-
- int total_bytes_acked() const { return total_bytes_acked_; }
-
- protected:
- // Object is ref counted.
- ~TestAckListener() override {}
-
- private:
- int total_bytes_acked_ = 0;
-};
-
-class TestResponseListener : public QuicSpdyClientBase::ResponseListener {
- public:
- void OnCompleteResponse(QuicStreamId id,
- const SpdyHeaderBlock& response_headers,
- const std::string& response_body) override {
- QUIC_DVLOG(1) << "response for stream " << id << " "
- << response_headers.DebugString() << "\n"
- << response_body;
- }
-};
-
-TEST_P(EndToEndTest, AckNotifierWithPacketLossAndBlockedSocket) {
- // Verify that even in the presence of packet loss and occasionally blocked
- // socket, an AckNotifierDelegate will get informed that the data it is
- // interested in has been ACKed. This tests end-to-end ACK notification, and
- // demonstrates that retransmissions do not break this functionality.
- // Disable blackhole detection as this test is testing loss recovery.
- client_extra_copts_.push_back(kNBHD);
- SetPacketLossPercentage(5);
- ASSERT_TRUE(Initialize());
- // Wait for the server SHLO before upping the packet loss.
- EXPECT_TRUE(client_->client()->WaitForHandshakeConfirmed());
- SetPacketLossPercentage(30);
- client_writer_->set_fake_blocked_socket_percentage(10);
-
- // Wait for SETTINGS frame from server that sets QPACK dynamic table capacity
- // to make sure request headers will be compressed using the dynamic table.
- if (version_.UsesHttp3()) {
- while (true) {
- // Waits for up to 50 ms.
- client_->client()->WaitForEvents();
- ASSERT_TRUE(client_->connected());
- QuicSpdyClientSession* client_session = GetClientSession();
- if (client_session == nullptr) {
- ADD_FAILURE() << "Missing client session";
- return;
- }
- QpackEncoder* qpack_encoder = client_session->qpack_encoder();
- if (qpack_encoder == nullptr) {
- ADD_FAILURE() << "Missing QPACK encoder";
- return;
- }
- QpackEncoderHeaderTable* header_table =
- QpackEncoderPeer::header_table(qpack_encoder);
- if (header_table == nullptr) {
- ADD_FAILURE() << "Missing header table";
- return;
- }
- if (header_table->dynamic_table_capacity() > 0) {
- break;
- }
- }
- }
-
- // Create a POST request and send the headers only.
- SpdyHeaderBlock headers;
- headers[":method"] = "POST";
- headers[":path"] = "/foo";
- headers[":scheme"] = "https";
- headers[":authority"] = server_hostname_;
-
- client_->SendMessage(headers, "", /*fin=*/false);
-
- // Size of headers on the request stream. This is zero if headers are sent on
- // the header stream.
- size_t header_size = 0;
- if (version_.UsesHttp3()) {
- // Determine size of headers after QPACK compression.
- NoopDecoderStreamErrorDelegate decoder_stream_error_delegate;
- NoopQpackStreamSenderDelegate encoder_stream_sender_delegate;
- QpackEncoder qpack_encoder(&decoder_stream_error_delegate);
- qpack_encoder.set_qpack_stream_sender_delegate(
- &encoder_stream_sender_delegate);
-
- qpack_encoder.SetMaximumDynamicTableCapacity(
- kDefaultQpackMaxDynamicTableCapacity);
- qpack_encoder.SetDynamicTableCapacity(kDefaultQpackMaxDynamicTableCapacity);
- qpack_encoder.SetMaximumBlockedStreams(kDefaultMaximumBlockedStreams);
-
- std::string encoded_headers = qpack_encoder.EncodeHeaderList(
- /* stream_id = */ 0, headers, nullptr);
- header_size = encoded_headers.size();
- }
-
- // Test the AckNotifier's ability to track multiple packets by making the
- // request body exceed the size of a single packet.
- std::string request_string = "a request body bigger than one packet" +
- std::string(kMaxOutgoingPacketSize, '.');
-
- const int expected_bytes_acked = header_size + request_string.length();
-
- // The TestAckListener will cause a failure if not notified.
- QuicReferenceCountedPointer<TestAckListener> ack_listener(
- new TestAckListener());
-
- // Send the request, and register the delegate for ACKs.
- client_->SendData(request_string, true, ack_listener);
- WaitForFooResponseAndCheckIt();
-
- // Send another request to flush out any pending ACKs on the server.
- SendSynchronousBarRequestAndCheckResponse();
-
- // Make sure the delegate does get the notification it expects.
- while (ack_listener->total_bytes_acked() < expected_bytes_acked) {
- // Waits for up to 50 ms.
- client_->client()->WaitForEvents();
- ASSERT_TRUE(client_->connected());
- }
- EXPECT_EQ(ack_listener->total_bytes_acked(), expected_bytes_acked)
- << " header_size " << header_size << " request length "
- << request_string.length();
-}
-
-// Send a public reset from the server.
-TEST_P(EndToEndTest, ServerSendPublicReset) {
- ASSERT_TRUE(Initialize());
-
- EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
- QuicSpdySession* client_session = GetClientSession();
- ASSERT_TRUE(client_session);
- QuicConfig* config = client_session->config();
- ASSERT_TRUE(config);
- EXPECT_TRUE(config->HasReceivedStatelessResetToken());
- StatelessResetToken stateless_reset_token =
- config->ReceivedStatelessResetToken();
-
- // Send the public reset.
- QuicConnection* client_connection = GetClientConnection();
- ASSERT_TRUE(client_connection);
- QuicConnectionId connection_id = client_connection->connection_id();
- QuicPublicResetPacket header;
- header.connection_id = connection_id;
- QuicFramer framer(server_supported_versions_, QuicTime::Zero(),
- Perspective::IS_SERVER, kQuicDefaultConnectionIdLength);
- std::unique_ptr<QuicEncryptedPacket> packet;
- if (version_.HasIetfInvariantHeader()) {
- packet = framer.BuildIetfStatelessResetPacket(
- connection_id, /*received_packet_length=*/100, stateless_reset_token);
- } else {
- packet = framer.BuildPublicResetPacket(header);
- }
- // We must pause the server's thread in order to call WritePacket without
- // race conditions.
- server_thread_->Pause();
- auto client_address = client_connection->self_address();
- server_writer_->WritePacket(packet->data(), packet->length(),
- server_address_.host(), client_address, nullptr);
- server_thread_->Resume();
-
- // The request should fail.
- EXPECT_EQ("", client_->SendSynchronousRequest("/foo"));
- EXPECT_TRUE(client_->response_headers()->empty());
- EXPECT_THAT(client_->connection_error(), IsError(QUIC_PUBLIC_RESET));
-}
-
-// Send a public reset from the server for a different connection ID.
-// It should be ignored.
-TEST_P(EndToEndTest, ServerSendPublicResetWithDifferentConnectionId) {
- ASSERT_TRUE(Initialize());
-
- EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
- QuicSpdySession* client_session = GetClientSession();
- ASSERT_TRUE(client_session);
- QuicConfig* config = client_session->config();
- ASSERT_TRUE(config);
- EXPECT_TRUE(config->HasReceivedStatelessResetToken());
- StatelessResetToken stateless_reset_token =
- config->ReceivedStatelessResetToken();
- // Send the public reset.
- QuicConnection* client_connection = GetClientConnection();
- ASSERT_TRUE(client_connection);
- QuicConnectionId incorrect_connection_id = TestConnectionId(
- TestConnectionIdToUInt64(client_connection->connection_id()) + 1);
- QuicPublicResetPacket header;
- header.connection_id = incorrect_connection_id;
- QuicFramer framer(server_supported_versions_, QuicTime::Zero(),
- Perspective::IS_SERVER, kQuicDefaultConnectionIdLength);
- std::unique_ptr<QuicEncryptedPacket> packet;
- NiceMock<MockQuicConnectionDebugVisitor> visitor;
- client_connection->set_debug_visitor(&visitor);
- if (version_.HasIetfInvariantHeader()) {
- packet = framer.BuildIetfStatelessResetPacket(
- incorrect_connection_id, /*received_packet_length=*/100,
- stateless_reset_token);
- EXPECT_CALL(visitor, OnIncorrectConnectionId(incorrect_connection_id))
- .Times(0);
- } else {
- packet = framer.BuildPublicResetPacket(header);
- EXPECT_CALL(visitor, OnIncorrectConnectionId(incorrect_connection_id))
- .Times(1);
- }
- // We must pause the server's thread in order to call WritePacket without
- // race conditions.
- server_thread_->Pause();
- auto client_address = client_connection->self_address();
- server_writer_->WritePacket(packet->data(), packet->length(),
- server_address_.host(), client_address, nullptr);
- server_thread_->Resume();
-
- if (version_.HasIetfInvariantHeader()) {
- // The request should fail. IETF stateless reset does not include connection
- // ID.
- EXPECT_EQ("", client_->SendSynchronousRequest("/foo"));
- EXPECT_TRUE(client_->response_headers()->empty());
- EXPECT_THAT(client_->connection_error(), IsError(QUIC_PUBLIC_RESET));
- } else {
- // The connection should be unaffected.
- SendSynchronousFooRequestAndCheckResponse();
- }
-
- client_connection->set_debug_visitor(nullptr);
-}
-
-// Send a public reset from the client for a different connection ID.
-// It should be ignored.
-TEST_P(EndToEndTest, ClientSendPublicResetWithDifferentConnectionId) {
- ASSERT_TRUE(Initialize());
-
- // Send the public reset.
- QuicConnection* client_connection = GetClientConnection();
- ASSERT_TRUE(client_connection);
- QuicConnectionId incorrect_connection_id = TestConnectionId(
- TestConnectionIdToUInt64(client_connection->connection_id()) + 1);
- QuicPublicResetPacket header;
- header.connection_id = incorrect_connection_id;
- QuicFramer framer(server_supported_versions_, QuicTime::Zero(),
- Perspective::IS_CLIENT, kQuicDefaultConnectionIdLength);
- std::unique_ptr<QuicEncryptedPacket> packet(
- framer.BuildPublicResetPacket(header));
- client_writer_->WritePacket(
- packet->data(), packet->length(),
- client_->client()->network_helper()->GetLatestClientAddress().host(),
- server_address_, nullptr);
-
- // The connection should be unaffected.
- SendSynchronousFooRequestAndCheckResponse();
-}
-
-// Send a version negotiation packet from the server for a different
-// connection ID. It should be ignored.
-TEST_P(EndToEndTest, ServerSendVersionNegotiationWithDifferentConnectionId) {
- ASSERT_TRUE(Initialize());
-
- EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
-
- // Send the version negotiation packet.
- QuicConnection* client_connection = GetClientConnection();
- ASSERT_TRUE(client_connection);
- QuicConnectionId incorrect_connection_id = TestConnectionId(
- TestConnectionIdToUInt64(client_connection->connection_id()) + 1);
- std::unique_ptr<QuicEncryptedPacket> packet(
- QuicFramer::BuildVersionNegotiationPacket(
- incorrect_connection_id, EmptyQuicConnectionId(),
- version_.HasIetfInvariantHeader(),
- version_.HasLengthPrefixedConnectionIds(),
- server_supported_versions_));
- NiceMock<MockQuicConnectionDebugVisitor> visitor;
- client_connection->set_debug_visitor(&visitor);
- EXPECT_CALL(visitor, OnIncorrectConnectionId(incorrect_connection_id))
- .Times(1);
- // We must pause the server's thread in order to call WritePacket without
- // race conditions.
- server_thread_->Pause();
- server_writer_->WritePacket(
- packet->data(), packet->length(), server_address_.host(),
- client_->client()->network_helper()->GetLatestClientAddress(), nullptr);
- server_thread_->Resume();
-
- // The connection should be unaffected.
- SendSynchronousFooRequestAndCheckResponse();
-
- client_connection->set_debug_visitor(nullptr);
-}
-
-// DowngradePacketWriter is a client writer which will intercept all the client
-// writes for |target_version| and reply to them with version negotiation
-// packets to attempt a version downgrade attack. Once the client has downgraded
-// to a different version, the writer stops intercepting. |server_thread| must
-// start off paused, and will be resumed once interception is done.
-class DowngradePacketWriter : public PacketDroppingTestWriter {
- public:
- explicit DowngradePacketWriter(
- const ParsedQuicVersion& target_version,
- const ParsedQuicVersionVector& supported_versions, QuicTestClient* client,
- QuicPacketWriter* server_writer, ServerThread* server_thread)
- : target_version_(target_version),
- supported_versions_(supported_versions),
- client_(client),
- server_writer_(server_writer),
- server_thread_(server_thread) {}
- ~DowngradePacketWriter() override {}
-
- WriteResult WritePacket(const char* buffer, size_t buf_len,
- const QuicIpAddress& self_address,
- const QuicSocketAddress& peer_address,
- quic::PerPacketOptions* options) override {
- if (!intercept_enabled_) {
- return PacketDroppingTestWriter::WritePacket(
- buffer, buf_len, self_address, peer_address, options);
- }
- PacketHeaderFormat format;
- QuicLongHeaderType long_packet_type;
- bool version_present, has_length_prefix;
- QuicVersionLabel version_label;
- ParsedQuicVersion parsed_version = ParsedQuicVersion::Unsupported();
- QuicConnectionId destination_connection_id, source_connection_id;
- absl::optional<absl::string_view> retry_token;
- std::string detailed_error;
- if (QuicFramer::ParsePublicHeaderDispatcher(
- QuicEncryptedPacket(buffer, buf_len),
- kQuicDefaultConnectionIdLength, &format, &long_packet_type,
- &version_present, &has_length_prefix, &version_label,
- &parsed_version, &destination_connection_id, &source_connection_id,
- &retry_token, &detailed_error) != QUIC_NO_ERROR) {
- ADD_FAILURE() << "Failed to parse our own packet: " << detailed_error;
- return WriteResult(WRITE_STATUS_ERROR, 0);
- }
- if (!version_present || parsed_version != target_version_) {
- // Client is sending with another version, the attack has succeeded so we
- // can stop intercepting.
- intercept_enabled_ = false;
- server_thread_->Resume();
- // Pass the client-sent packet through.
- return WritePacket(buffer, buf_len, self_address, peer_address, options);
- }
- // Send a version negotiation packet.
- std::unique_ptr<QuicEncryptedPacket> packet(
- QuicFramer::BuildVersionNegotiationPacket(
- destination_connection_id, source_connection_id,
- parsed_version.HasIetfInvariantHeader(), has_length_prefix,
- supported_versions_));
- server_writer_->WritePacket(
- packet->data(), packet->length(), peer_address.host(),
- client_->client()->network_helper()->GetLatestClientAddress(), nullptr);
- // Drop the client-sent packet but pretend it was sent.
- return WriteResult(WRITE_STATUS_OK, buf_len);
- }
-
- private:
- bool intercept_enabled_ = true;
- ParsedQuicVersion target_version_;
- ParsedQuicVersionVector supported_versions_;
- QuicTestClient* client_; // Unowned.
- QuicPacketWriter* server_writer_; // Unowned.
- ServerThread* server_thread_; // Unowned.
-};
-
-TEST_P(EndToEndTest, VersionNegotiationDowngradeAttackIsDetected) {
- ParsedQuicVersion target_version = server_supported_versions_.back();
- if (!version_.UsesTls() || target_version == version_) {
- ASSERT_TRUE(Initialize());
- return;
- }
- SetQuicReloadableFlag(quic_version_information, true);
- connect_to_server_on_initialize_ = false;
- client_supported_versions_.insert(client_supported_versions_.begin(),
- target_version);
- ParsedQuicVersionVector downgrade_versions{version_};
- ASSERT_TRUE(Initialize());
- ASSERT_TRUE(server_thread_);
- // Pause the server thread to allow our DowngradePacketWriter to write version
- // negotiation packets in a thread-safe manner. It will be resumed by the
- // DowngradePacketWriter.
- server_thread_->Pause();
- client_.reset(new QuicTestClient(server_address_, server_hostname_,
- client_config_, client_supported_versions_,
- crypto_test_utils::ProofVerifierForTesting(),
- std::make_unique<QuicClientSessionCache>()));
- delete client_writer_;
- client_writer_ = new DowngradePacketWriter(target_version, downgrade_versions,
- client_.get(), server_writer_,
- server_thread_.get());
- client_->UseWriter(client_writer_);
- // Have the client attempt to send a request.
- client_->Connect();
- EXPECT_TRUE(client_->SendSynchronousRequest("/foo").empty());
- // Make sure the downgrade is detected and the handshake fails.
- EXPECT_THAT(client_->connection_error(), IsError(QUIC_HANDSHAKE_FAILED));
-}
-
-// A bad header shouldn't tear down the connection, because the receiver can't
-// tell the connection ID.
-TEST_P(EndToEndTest, BadPacketHeaderTruncated) {
- ASSERT_TRUE(Initialize());
-
- // Start the connection.
- SendSynchronousFooRequestAndCheckResponse();
-
- // Packet with invalid public flags.
- char packet[] = {// public flags (8 byte connection_id)
- 0x3C,
- // truncated connection ID
- 0x11};
- client_writer_->WritePacket(
- &packet[0], sizeof(packet),
- client_->client()->network_helper()->GetLatestClientAddress().host(),
- server_address_, nullptr);
- EXPECT_TRUE(server_thread_->WaitUntil(
- [&] {
- return QuicDispatcherPeer::GetAndClearLastError(
- QuicServerPeer::GetDispatcher(server_thread_->server())) ==
- QUIC_INVALID_PACKET_HEADER;
- },
- QuicTime::Delta::FromSeconds(5)));
-
- // The connection should not be terminated.
- SendSynchronousFooRequestAndCheckResponse();
-}
-
-// A bad header shouldn't tear down the connection, because the receiver can't
-// tell the connection ID.
-TEST_P(EndToEndTest, BadPacketHeaderFlags) {
- ASSERT_TRUE(Initialize());
-
- // Start the connection.
- SendSynchronousFooRequestAndCheckResponse();
-
- // Packet with invalid public flags.
- uint8_t packet[] = {
- // invalid public flags
- 0xFF,
- // connection_id
- 0x10,
- 0x32,
- 0x54,
- 0x76,
- 0x98,
- 0xBA,
- 0xDC,
- 0xFE,
- // packet sequence number
- 0xBC,
- 0x9A,
- 0x78,
- 0x56,
- 0x34,
- 0x12,
- // private flags
- 0x00,
- };
- client_writer_->WritePacket(
- reinterpret_cast<const char*>(packet), sizeof(packet),
- client_->client()->network_helper()->GetLatestClientAddress().host(),
- server_address_, nullptr);
-
- EXPECT_TRUE(server_thread_->WaitUntil(
- [&] {
- return QuicDispatcherPeer::GetAndClearLastError(
- QuicServerPeer::GetDispatcher(server_thread_->server())) ==
- QUIC_INVALID_PACKET_HEADER;
- },
- QuicTime::Delta::FromSeconds(5)));
-
- // The connection should not be terminated.
- SendSynchronousFooRequestAndCheckResponse();
-}
-
-// Send a packet from the client with bad encrypted data. The server should not
-// tear down the connection.
-TEST_P(EndToEndTest, BadEncryptedData) {
- ASSERT_TRUE(Initialize());
-
- // Start the connection.
- SendSynchronousFooRequestAndCheckResponse();
-
- QuicConnection* client_connection = GetClientConnection();
- ASSERT_TRUE(client_connection);
- std::unique_ptr<QuicEncryptedPacket> packet(ConstructEncryptedPacket(
- client_connection->connection_id(), EmptyQuicConnectionId(), false, false,
- 1, "At least 20 characters.", CONNECTION_ID_PRESENT, CONNECTION_ID_ABSENT,
- PACKET_4BYTE_PACKET_NUMBER));
- // Damage the encrypted data.
- std::string damaged_packet(packet->data(), packet->length());
- damaged_packet[30] ^= 0x01;
- QUIC_DLOG(INFO) << "Sending bad packet.";
- client_writer_->WritePacket(
- damaged_packet.data(), damaged_packet.length(),
- client_->client()->network_helper()->GetLatestClientAddress().host(),
- server_address_, nullptr);
- // Give the server time to process the packet.
- QuicSleep(QuicTime::Delta::FromSeconds(1));
- // This error is sent to the connection's OnError (which ignores it), so the
- // dispatcher doesn't see it.
- // Pause the server so we can access the server's internals without races.
- server_thread_->Pause();
- QuicDispatcher* dispatcher =
- QuicServerPeer::GetDispatcher(server_thread_->server());
- if (dispatcher != nullptr) {
- EXPECT_THAT(QuicDispatcherPeer::GetAndClearLastError(dispatcher),
- IsQuicNoError());
- } else {
- ADD_FAILURE() << "Missing dispatcher";
- }
- server_thread_->Resume();
-
- // The connection should not be terminated.
- SendSynchronousFooRequestAndCheckResponse();
-}
-
-TEST_P(EndToEndTest, CanceledStreamDoesNotBecomeZombie) {
- ASSERT_TRUE(Initialize());
- EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
- // Lose the request.
- SetPacketLossPercentage(100);
- SpdyHeaderBlock headers;
- headers[":method"] = "POST";
- headers[":path"] = "/foo";
- headers[":scheme"] = "https";
- headers[":authority"] = server_hostname_;
- client_->SendMessage(headers, "test_body", /*fin=*/false);
- QuicSpdyClientStream* stream = client_->GetOrCreateStream();
-
- // Cancel the stream.
- stream->Reset(QUIC_STREAM_CANCELLED);
- QuicSession* session = GetClientSession();
- ASSERT_TRUE(session);
- // Verify canceled stream does not become zombie.
- EXPECT_EQ(1u, QuicSessionPeer::closed_streams(session).size());
-}
-
-// A test stream that gives |response_body_| as an error response body.
-class ServerStreamWithErrorResponseBody : public QuicSimpleServerStream {
- public:
- ServerStreamWithErrorResponseBody(
- QuicStreamId id, QuicSpdySession* session,
- QuicSimpleServerBackend* quic_simple_server_backend,
- std::string response_body)
- : QuicSimpleServerStream(id, session, BIDIRECTIONAL,
- quic_simple_server_backend),
- response_body_(std::move(response_body)) {}
-
- ~ServerStreamWithErrorResponseBody() override = default;
-
- protected:
- void SendErrorResponse() override {
- QUIC_DLOG(INFO) << "Sending error response for stream " << id();
- SpdyHeaderBlock headers;
- headers[":status"] = "500";
- headers["content-length"] = absl::StrCat(response_body_.size());
- // This method must call CloseReadSide to cause the test case, StopReading
- // is not sufficient.
- QuicStreamPeer::CloseReadSide(this);
- SendHeadersAndBody(std::move(headers), response_body_);
- }
-
- std::string response_body_;
-};
-
-class StreamWithErrorFactory : public QuicTestServer::StreamFactory {
- public:
- explicit StreamWithErrorFactory(std::string response_body)
- : response_body_(std::move(response_body)) {}
-
- ~StreamWithErrorFactory() override = default;
-
- QuicSimpleServerStream* CreateStream(
- QuicStreamId id, QuicSpdySession* session,
- QuicSimpleServerBackend* quic_simple_server_backend) override {
- return new ServerStreamWithErrorResponseBody(
- id, session, quic_simple_server_backend, response_body_);
- }
-
- private:
- std::string response_body_;
-};
-
-// A test server stream that drops all received body.
-class ServerStreamThatDropsBody : public QuicSimpleServerStream {
- public:
- ServerStreamThatDropsBody(QuicStreamId id, QuicSpdySession* session,
- QuicSimpleServerBackend* quic_simple_server_backend)
- : QuicSimpleServerStream(id, session, BIDIRECTIONAL,
- quic_simple_server_backend) {}
-
- ~ServerStreamThatDropsBody() override = default;
-
- protected:
- void OnBodyAvailable() override {
- while (HasBytesToRead()) {
- struct iovec iov;
- if (GetReadableRegions(&iov, 1) == 0) {
- // No more data to read.
- break;
- }
- QUIC_DVLOG(1) << "Processed " << iov.iov_len << " bytes for stream "
- << id();
- MarkConsumed(iov.iov_len);
- }
-
- if (!sequencer()->IsClosed()) {
- sequencer()->SetUnblocked();
- return;
- }
-
- // If the sequencer is closed, then all the body, including the fin, has
- // been consumed.
- OnFinRead();
-
- if (write_side_closed() || fin_buffered()) {
- return;
- }
-
- SendResponse();
- }
-};
-
-class ServerStreamThatDropsBodyFactory : public QuicTestServer::StreamFactory {
- public:
- ServerStreamThatDropsBodyFactory() = default;
-
- ~ServerStreamThatDropsBodyFactory() override = default;
-
- QuicSimpleServerStream* CreateStream(
- QuicStreamId id, QuicSpdySession* session,
- QuicSimpleServerBackend* quic_simple_server_backend) override {
- return new ServerStreamThatDropsBody(id, session,
- quic_simple_server_backend);
- }
-};
-
-// A test server stream that sends response with body size greater than 4GB.
-class ServerStreamThatSendsHugeResponse : public QuicSimpleServerStream {
- public:
- ServerStreamThatSendsHugeResponse(
- QuicStreamId id, QuicSpdySession* session,
- QuicSimpleServerBackend* quic_simple_server_backend, int64_t body_bytes)
- : QuicSimpleServerStream(id, session, BIDIRECTIONAL,
- quic_simple_server_backend),
- body_bytes_(body_bytes) {}
-
- ~ServerStreamThatSendsHugeResponse() override = default;
-
- protected:
- void SendResponse() override {
- QuicBackendResponse response;
- std::string body(body_bytes_, 'a');
- response.set_body(body);
- SendHeadersAndBodyAndTrailers(response.headers().Clone(), response.body(),
- response.trailers().Clone());
- }
-
- private:
- // Use a explicit int64_t rather than size_t to simulate a 64-bit server
- // talking to a 32-bit client.
- int64_t body_bytes_;
-};
-
-class ServerStreamThatSendsHugeResponseFactory
- : public QuicTestServer::StreamFactory {
- public:
- explicit ServerStreamThatSendsHugeResponseFactory(int64_t body_bytes)
- : body_bytes_(body_bytes) {}
-
- ~ServerStreamThatSendsHugeResponseFactory() override = default;
-
- QuicSimpleServerStream* CreateStream(
- QuicStreamId id, QuicSpdySession* session,
- QuicSimpleServerBackend* quic_simple_server_backend) override {
- return new ServerStreamThatSendsHugeResponse(
- id, session, quic_simple_server_backend, body_bytes_);
- }
-
- int64_t body_bytes_;
-};
-
-TEST_P(EndToEndTest, EarlyResponseFinRecording) {
- set_smaller_flow_control_receive_window();
-
- // Verify that an incoming FIN is recorded in a stream object even if the read
- // side has been closed. This prevents an entry from being made in
- // locally_close_streams_highest_offset_ (which will never be deleted).
- // To set up the test condition, the server must do the following in order:
- // start sending the response and call CloseReadSide
- // receive the FIN of the request
- // send the FIN of the response
-
- // The response body must be larger than the flow control window so the server
- // must receive a window update from the client before it can finish sending
- // it.
- uint32_t response_body_size =
- 2 * client_config_.GetInitialStreamFlowControlWindowToSend();
- std::string response_body(response_body_size, 'a');
-
- StreamWithErrorFactory stream_factory(response_body);
- SetSpdyStreamFactory(&stream_factory);
-
- ASSERT_TRUE(Initialize());
-
- EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
-
- // A POST that gets an early error response, after the headers are received
- // and before the body is received, due to invalid content-length.
- // Set an invalid content-length, so the request will receive an early 500
- // response.
- SpdyHeaderBlock headers;
- headers[":method"] = "POST";
- headers[":path"] = "/garbage";
- headers[":scheme"] = "https";
- headers[":authority"] = server_hostname_;
- headers["content-length"] = "-1";
-
- // The body must be large enough that the FIN will be in a different packet
- // than the end of the headers, but short enough to not require a flow control
- // update. This allows headers processing to trigger the error response
- // before the request FIN is processed but receive the request FIN before the
- // response is sent completely.
- const uint32_t kRequestBodySize = kMaxOutgoingPacketSize + 10;
- std::string request_body(kRequestBodySize, 'a');
-
- // Send the request.
- client_->SendMessage(headers, request_body);
- client_->WaitForResponse();
- CheckResponseHeaders("500");
-
- // Pause the server so we can access the server's internals without races.
- server_thread_->Pause();
-
- QuicDispatcher* dispatcher =
- QuicServerPeer::GetDispatcher(server_thread_->server());
- QuicSession* server_session =
- QuicDispatcherPeer::GetFirstSessionIfAny(dispatcher);
- EXPECT_TRUE(server_session != nullptr);
-
- // The stream is not waiting for the arrival of the peer's final offset.
- EXPECT_EQ(
- 0u, QuicSessionPeer::GetLocallyClosedStreamsHighestOffset(server_session)
- .size());
-
- server_thread_->Resume();
-}
-
-TEST_P(EndToEndTest, Trailers) {
- // Test sending and receiving HTTP/2 Trailers (trailing HEADERS frames).
- ASSERT_TRUE(Initialize());
- EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
-
- // Set reordering to ensure that Trailers arriving before body is ok.
- SetPacketSendDelay(QuicTime::Delta::FromMilliseconds(2));
- SetReorderPercentage(30);
-
- // Add a response with headers, body, and trailers.
- const std::string kBody = "body content";
-
- SpdyHeaderBlock headers;
- headers[":status"] = "200";
- headers["content-length"] = absl::StrCat(kBody.size());
-
- SpdyHeaderBlock trailers;
- trailers["some-trailing-header"] = "trailing-header-value";
-
- memory_cache_backend_.AddResponse(server_hostname_, "/trailer_url",
- std::move(headers), kBody,
- trailers.Clone());
-
- SendSynchronousRequestAndCheckResponse("/trailer_url", kBody);
- EXPECT_EQ(trailers, client_->response_trailers());
-}
-
-// TODO(fayang): this test seems to cause net_unittests timeouts :|
-TEST_P(EndToEndTest, DISABLED_TestHugePostWithPacketLoss) {
- // This test tests a huge post with introduced packet loss from client to
- // server and body size greater than 4GB, making sure QUIC code does not break
- // for 32-bit builds.
- ServerStreamThatDropsBodyFactory stream_factory;
- SetSpdyStreamFactory(&stream_factory);
- ASSERT_TRUE(Initialize());
- // Set client's epoll server's time out to 0 to make this test be finished
- // within a short time.
- client_->epoll_server()->set_timeout_in_us(0);
-
- EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
- SetPacketLossPercentage(1);
- // To avoid storing the whole request body in memory, use a loop to repeatedly
- // send body size of kSizeBytes until the whole request body size is reached.
- const int kSizeBytes = 128 * 1024;
- // Request body size is 4G plus one more kSizeBytes.
- int64_t request_body_size_bytes = pow(2, 32) + kSizeBytes;
- ASSERT_LT(INT64_C(4294967296), request_body_size_bytes);
- std::string body(kSizeBytes, 'a');
-
- SpdyHeaderBlock headers;
- headers[":method"] = "POST";
- headers[":path"] = "/foo";
- headers[":scheme"] = "https";
- headers[":authority"] = server_hostname_;
- headers["content-length"] = absl::StrCat(request_body_size_bytes);
-
- client_->SendMessage(headers, "", /*fin=*/false);
-
- for (int i = 0; i < request_body_size_bytes / kSizeBytes; ++i) {
- bool fin = (i == request_body_size_bytes - 1);
- client_->SendData(std::string(body.data(), kSizeBytes), fin);
- client_->client()->WaitForEvents();
- }
- VerifyCleanConnection(true);
-}
-
-// TODO(fayang): this test seems to cause net_unittests timeouts :|
-TEST_P(EndToEndTest, DISABLED_TestHugeResponseWithPacketLoss) {
- // This test tests a huge response with introduced loss from server to client
- // and body size greater than 4GB, making sure QUIC code does not break for
- // 32-bit builds.
- const int kSizeBytes = 128 * 1024;
- int64_t response_body_size_bytes = pow(2, 32) + kSizeBytes;
- ASSERT_LT(4294967296, response_body_size_bytes);
- ServerStreamThatSendsHugeResponseFactory stream_factory(
- response_body_size_bytes);
- SetSpdyStreamFactory(&stream_factory);
-
- StartServer();
-
- // Use a quic client that drops received body.
- QuicTestClient* client =
- new QuicTestClient(server_address_, server_hostname_, client_config_,
- client_supported_versions_);
- client->client()->set_drop_response_body(true);
- client->UseWriter(client_writer_);
- client->Connect();
- client_.reset(client);
- static QuicEpollEvent event(EPOLLOUT);
- QuicConnection* client_connection = GetClientConnection();
- ASSERT_TRUE(client_connection);
- client_writer_->Initialize(
- QuicConnectionPeer::GetHelper(client_connection),
- QuicConnectionPeer::GetAlarmFactory(client_connection),
- std::make_unique<ClientDelegate>(client_->client()));
- initialized_ = true;
- ASSERT_TRUE(client_->client()->connected());
-
- EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
- SetPacketLossPercentage(1);
- client_->SendRequest("/huge_response");
- client_->WaitForResponse();
- VerifyCleanConnection(true);
-}
-
-// Regression test for b/111515567
-TEST_P(EndToEndTest, AgreeOnStopWaiting) {
- ASSERT_TRUE(Initialize());
- EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
-
- QuicConnection* client_connection = GetClientConnection();
- ASSERT_TRUE(client_connection);
- server_thread_->Pause();
- QuicConnection* server_connection = GetServerConnection();
- if (server_connection != nullptr) {
- // Verify client and server connections agree on the value of
- // no_stop_waiting_frames.
- EXPECT_EQ(QuicConnectionPeer::GetNoStopWaitingFrames(client_connection),
- QuicConnectionPeer::GetNoStopWaitingFrames(server_connection));
- } else {
- ADD_FAILURE() << "Missing server connection";
- }
- server_thread_->Resume();
-}
-
-// Regression test for b/111515567
-TEST_P(EndToEndTest, AgreeOnStopWaitingWithNoStopWaitingOption) {
- QuicTagVector options;
- options.push_back(kNSTP);
- client_config_.SetConnectionOptionsToSend(options);
- ASSERT_TRUE(Initialize());
- EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
-
- QuicConnection* client_connection = GetClientConnection();
- ASSERT_TRUE(client_connection);
- server_thread_->Pause();
- QuicConnection* server_connection = GetServerConnection();
- if (server_connection != nullptr) {
- // Verify client and server connections agree on the value of
- // no_stop_waiting_frames.
- EXPECT_EQ(QuicConnectionPeer::GetNoStopWaitingFrames(client_connection),
- QuicConnectionPeer::GetNoStopWaitingFrames(server_connection));
- } else {
- ADD_FAILURE() << "Missing server connection";
- }
- server_thread_->Resume();
-}
-
-TEST_P(EndToEndTest, ReleaseHeadersStreamBufferWhenIdle) {
- // Tests that when client side has no active request and no waiting
- // PUSH_PROMISE, its headers stream's sequencer buffer should be released.
- ASSERT_TRUE(Initialize());
- client_->SendSynchronousRequest("/foo");
- if (version_.UsesHttp3()) {
- return;
- }
- QuicSpdyClientSession* client_session = GetClientSession();
- ASSERT_TRUE(client_session);
- QuicHeadersStream* headers_stream =
- QuicSpdySessionPeer::GetHeadersStream(client_session);
- ASSERT_TRUE(headers_stream);
- QuicStreamSequencer* sequencer = QuicStreamPeer::sequencer(headers_stream);
- ASSERT_TRUE(sequencer);
- EXPECT_FALSE(QuicStreamSequencerPeer::IsUnderlyingBufferAllocated(sequencer));
-}
-
-// A single large header value causes a different error than the total size of
-// headers exceeding a smaller limit, tested at EndToEndTest.LargeHeaders.
-TEST_P(EndToEndTest, WayTooLongRequestHeaders) {
- ASSERT_TRUE(Initialize());
-
- SpdyHeaderBlock headers;
- headers[":method"] = "GET";
- headers[":path"] = "/foo";
- headers[":scheme"] = "https";
- headers[":authority"] = server_hostname_;
- headers["key"] = std::string(2 * 1024 * 1024, 'a');
-
- client_->SendMessage(headers, "");
- client_->WaitForResponse();
- if (version_.UsesHttp3()) {
- EXPECT_THAT(client_->connection_error(),
- IsError(QUIC_QPACK_DECOMPRESSION_FAILED));
- } else {
- EXPECT_THAT(client_->connection_error(),
- IsError(QUIC_HPACK_VALUE_TOO_LONG));
- }
-}
-
-class WindowUpdateObserver : public QuicConnectionDebugVisitor {
- public:
- WindowUpdateObserver() : num_window_update_frames_(0), num_ping_frames_(0) {}
-
- size_t num_window_update_frames() const { return num_window_update_frames_; }
-
- size_t num_ping_frames() const { return num_ping_frames_; }
-
- void OnWindowUpdateFrame(const QuicWindowUpdateFrame& /*frame*/,
- const QuicTime& /*receive_time*/) override {
- ++num_window_update_frames_;
- }
-
- void OnPingFrame(const QuicPingFrame& /*frame*/,
- const QuicTime::Delta /*ping_received_delay*/) override {
- ++num_ping_frames_;
- }
-
- private:
- size_t num_window_update_frames_;
- size_t num_ping_frames_;
-};
-
-TEST_P(EndToEndTest, WindowUpdateInAck) {
- ASSERT_TRUE(Initialize());
- EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
- WindowUpdateObserver observer;
- QuicConnection* client_connection = GetClientConnection();
- ASSERT_TRUE(client_connection);
- client_connection->set_debug_visitor(&observer);
- // 100KB body.
- std::string body(100 * 1024, 'a');
- SpdyHeaderBlock headers;
- headers[":method"] = "POST";
- headers[":path"] = "/foo";
- headers[":scheme"] = "https";
- headers[":authority"] = server_hostname_;
-
- EXPECT_EQ(kFooResponseBody,
- client_->SendCustomSynchronousRequest(headers, body));
- client_->Disconnect();
- EXPECT_LT(0u, observer.num_window_update_frames());
- EXPECT_EQ(0u, observer.num_ping_frames());
- client_connection->set_debug_visitor(nullptr);
-}
-
-TEST_P(EndToEndTest, SendStatelessResetTokenInShlo) {
- ASSERT_TRUE(Initialize());
- EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
- QuicSpdyClientSession* client_session = GetClientSession();
- ASSERT_TRUE(client_session);
- QuicConfig* config = client_session->config();
- ASSERT_TRUE(config);
- EXPECT_TRUE(config->HasReceivedStatelessResetToken());
- QuicConnection* client_connection = client_session->connection();
- ASSERT_TRUE(client_connection);
- EXPECT_EQ(QuicUtils::GenerateStatelessResetToken(
- client_connection->connection_id()),
- config->ReceivedStatelessResetToken());
- client_->Disconnect();
-}
-
-// Regression test for b/116200989.
-TEST_P(EndToEndTest,
- SendStatelessResetIfServerConnectionClosedLocallyDuringHandshake) {
- connect_to_server_on_initialize_ = false;
- ASSERT_TRUE(Initialize());
-
- ASSERT_TRUE(server_thread_);
- server_thread_->Pause();
- QuicDispatcher* dispatcher =
- QuicServerPeer::GetDispatcher(server_thread_->server());
- if (dispatcher == nullptr) {
- ADD_FAILURE() << "Missing dispatcher";
- server_thread_->Resume();
- return;
- }
- if (dispatcher->NumSessions() > 0) {
- ADD_FAILURE() << "Dispatcher session map not empty";
- server_thread_->Resume();
- return;
- }
- // Note: this writer will only used by the server connection, not the time
- // wait list.
- QuicDispatcherPeer::UseWriter(
- dispatcher,
- // This cause the first server-sent packet, a.k.a REJ, to fail.
- new BadPacketWriter(/*packet_causing_write_error=*/0, EPERM));
- server_thread_->Resume();
-
- client_.reset(CreateQuicClient(client_writer_));
- EXPECT_EQ("", client_->SendSynchronousRequest("/foo"));
- EXPECT_THAT(client_->connection_error(), IsError(QUIC_HANDSHAKE_FAILED));
-}
-
-// Regression test for b/116200989.
-TEST_P(EndToEndTest,
- SendStatelessResetIfServerConnectionClosedLocallyAfterHandshake) {
- // Prevent the connection from expiring in the time wait list.
- SetQuicFlag(FLAGS_quic_time_wait_list_seconds, 10000);
- connect_to_server_on_initialize_ = false;
- ASSERT_TRUE(Initialize());
-
- // big_response_body is 64K, which is about 48 full-sized packets.
- const size_t kBigResponseBodySize = 65536;
- QuicData big_response_body(new char[kBigResponseBodySize](),
- kBigResponseBodySize, /*owns_buffer=*/true);
- AddToCache("/big_response", 200, big_response_body.AsStringPiece());
-
- ASSERT_TRUE(server_thread_);
- server_thread_->Pause();
- QuicDispatcher* dispatcher =
- QuicServerPeer::GetDispatcher(server_thread_->server());
- if (dispatcher == nullptr) {
- ADD_FAILURE() << "Missing dispatcher";
- server_thread_->Resume();
- return;
- }
- if (dispatcher->NumSessions() > 0) {
- ADD_FAILURE() << "Dispatcher session map not empty";
- server_thread_->Resume();
- return;
- }
- QuicDispatcherPeer::UseWriter(
- dispatcher,
- // This will cause an server write error with EPERM, while sending the
- // response for /big_response.
- new BadPacketWriter(/*packet_causing_write_error=*/20, EPERM));
- server_thread_->Resume();
-
- client_.reset(CreateQuicClient(client_writer_));
-
- // First, a /foo request with small response should succeed.
- SendSynchronousFooRequestAndCheckResponse();
-
- // Second, a /big_response request with big response should fail.
- EXPECT_LT(client_->SendSynchronousRequest("/big_response").length(),
- kBigResponseBodySize);
- EXPECT_THAT(client_->connection_error(), IsError(QUIC_PUBLIC_RESET));
-}
-
-// Regression test of b/70782529.
-TEST_P(EndToEndTest, DoNotCrashOnPacketWriteError) {
- ASSERT_TRUE(Initialize());
- BadPacketWriter* bad_writer =
- new BadPacketWriter(/*packet_causing_write_error=*/5,
- /*error_code=*/90);
- std::unique_ptr<QuicTestClient> client(CreateQuicClient(bad_writer));
-
- // 1 MB body.
- std::string body(1024 * 1024, 'a');
- SpdyHeaderBlock headers;
- headers[":method"] = "POST";
- headers[":path"] = "/foo";
- headers[":scheme"] = "https";
- headers[":authority"] = server_hostname_;
-
- client->SendCustomSynchronousRequest(headers, body);
-}
-
-// Regression test for b/71711996. This test sends a connectivity probing packet
-// as its last sent packet, and makes sure the server's ACK of that packet does
-// not cause the client to fail.
-TEST_P(EndToEndTest, LastPacketSentIsConnectivityProbing) {
- ASSERT_TRUE(Initialize());
-
- SendSynchronousFooRequestAndCheckResponse();
-
- // Wait for the client's ACK (of the response) to be received by the server.
- client_->WaitForDelayedAcks();
-
- // We are sending a connectivity probing packet from an unchanged client
- // address, so the server will not respond to us with a connectivity probing
- // packet, however the server should send an ack-only packet to us.
- client_->SendConnectivityProbing();
-
- // Wait for the server's last ACK to be received by the client.
- client_->WaitForDelayedAcks();
-}
-
-TEST_P(EndToEndTest, PreSharedKey) {
- client_config_.set_max_time_before_crypto_handshake(
- QuicTime::Delta::FromSeconds(5));
- client_config_.set_max_idle_time_before_crypto_handshake(
- QuicTime::Delta::FromSeconds(5));
- pre_shared_key_client_ = "foobar";
- pre_shared_key_server_ = "foobar";
-
- if (version_.UsesTls()) {
- // TODO(b/154162689) add PSK support to QUIC+TLS.
- bool ok = true;
- EXPECT_QUIC_BUG(ok = Initialize(),
- "QUIC client pre-shared keys not yet supported with TLS");
- EXPECT_FALSE(ok);
- return;
- }
-
- ASSERT_TRUE(Initialize());
-
- SendSynchronousFooRequestAndCheckResponse();
-}
-
-// TODO: reenable once we have a way to make this run faster.
-TEST_P(EndToEndTest, QUIC_TEST_DISABLED_IN_CHROME(PreSharedKeyMismatch)) {
- client_config_.set_max_time_before_crypto_handshake(
- QuicTime::Delta::FromSeconds(1));
- client_config_.set_max_idle_time_before_crypto_handshake(
- QuicTime::Delta::FromSeconds(1));
- pre_shared_key_client_ = "foo";
- pre_shared_key_server_ = "bar";
-
- if (version_.UsesTls()) {
- // TODO(b/154162689) add PSK support to QUIC+TLS.
- bool ok = true;
- EXPECT_QUIC_BUG(ok = Initialize(),
- "QUIC client pre-shared keys not yet supported with TLS");
- EXPECT_FALSE(ok);
- return;
- }
-
- // One of two things happens when Initialize() returns:
- // 1. Crypto handshake has completed, and it is unsuccessful. Initialize()
- // returns false.
- // 2. Crypto handshake has not completed, Initialize() returns true. The call
- // to WaitForCryptoHandshakeConfirmed() will wait for the handshake and
- // return whether it is successful.
- ASSERT_FALSE(Initialize() && client_->client()->WaitForOneRttKeysAvailable());
- EXPECT_THAT(client_->connection_error(), IsError(QUIC_HANDSHAKE_TIMEOUT));
-}
-
-// TODO: reenable once we have a way to make this run faster.
-TEST_P(EndToEndTest, QUIC_TEST_DISABLED_IN_CHROME(PreSharedKeyNoClient)) {
- client_config_.set_max_time_before_crypto_handshake(
- QuicTime::Delta::FromSeconds(1));
- client_config_.set_max_idle_time_before_crypto_handshake(
- QuicTime::Delta::FromSeconds(1));
- pre_shared_key_server_ = "foobar";
-
- if (version_.UsesTls()) {
- // TODO(b/154162689) add PSK support to QUIC+TLS.
- bool ok = true;
- EXPECT_QUIC_BUG(ok = Initialize(),
- "QUIC server pre-shared keys not yet supported with TLS");
- EXPECT_FALSE(ok);
- return;
- }
-
- ASSERT_FALSE(Initialize() && client_->client()->WaitForOneRttKeysAvailable());
- EXPECT_THAT(client_->connection_error(), IsError(QUIC_HANDSHAKE_TIMEOUT));
-}
-
-// TODO: reenable once we have a way to make this run faster.
-TEST_P(EndToEndTest, QUIC_TEST_DISABLED_IN_CHROME(PreSharedKeyNoServer)) {
- client_config_.set_max_time_before_crypto_handshake(
- QuicTime::Delta::FromSeconds(1));
- client_config_.set_max_idle_time_before_crypto_handshake(
- QuicTime::Delta::FromSeconds(1));
- pre_shared_key_client_ = "foobar";
-
- if (version_.UsesTls()) {
- // TODO(b/154162689) add PSK support to QUIC+TLS.
- bool ok = true;
- EXPECT_QUIC_BUG(ok = Initialize(),
- "QUIC client pre-shared keys not yet supported with TLS");
- EXPECT_FALSE(ok);
- return;
- }
-
- ASSERT_FALSE(Initialize() && client_->client()->WaitForOneRttKeysAvailable());
- EXPECT_THAT(client_->connection_error(), IsError(QUIC_HANDSHAKE_TIMEOUT));
-}
-
-TEST_P(EndToEndTest, RequestAndStreamRstInOnePacket) {
- // Regression test for b/80234898.
- ASSERT_TRUE(Initialize());
-
- // INCOMPLETE_RESPONSE will cause the server to not to send the trailer
- // (and the FIN) after the response body.
- std::string response_body(1305, 'a');
- SpdyHeaderBlock response_headers;
- response_headers[":status"] = absl::StrCat(200);
- response_headers["content-length"] = absl::StrCat(response_body.length());
- memory_cache_backend_.AddSpecialResponse(
- server_hostname_, "/test_url", std::move(response_headers), response_body,
- QuicBackendResponse::INCOMPLETE_RESPONSE);
-
- EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
- client_->WaitForDelayedAcks();
-
- QuicConnection* client_connection = GetClientConnection();
- ASSERT_TRUE(client_connection);
- const QuicPacketCount packets_sent_before =
- client_connection->GetStats().packets_sent;
-
- client_->SendRequestAndRstTogether("/test_url");
-
- // Expect exactly one packet is sent from the block above.
- ASSERT_EQ(packets_sent_before + 1,
- client_connection->GetStats().packets_sent);
-
- // Wait for the connection to become idle.
- client_->WaitForDelayedAcks();
-
- // The real expectation is the test does not crash or timeout.
- EXPECT_THAT(client_->connection_error(), IsQuicNoError());
-}
-
-TEST_P(EndToEndTest, ResetStreamOnTtlExpires) {
- ASSERT_TRUE(Initialize());
- EXPECT_TRUE(client_->client()->WaitForHandshakeConfirmed());
- SetPacketLossPercentage(30);
-
- QuicSpdyClientStream* stream = client_->GetOrCreateStream();
- // Set a TTL which expires immediately.
- stream->MaybeSetTtl(QuicTime::Delta::FromMicroseconds(1));
-
- WriteHeadersOnStream(stream);
- // 1 MB body.
- std::string body(1024 * 1024, 'a');
- stream->WriteOrBufferBody(body, true);
- client_->WaitForResponse();
- EXPECT_THAT(client_->stream_error(), IsStreamError(QUIC_STREAM_TTL_EXPIRED));
-}
-
-TEST_P(EndToEndTest, SendMessages) {
- if (!version_.SupportsMessageFrames()) {
- Initialize();
- return;
- }
- ASSERT_TRUE(Initialize());
- EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
- QuicSession* client_session = GetClientSession();
- ASSERT_TRUE(client_session);
- QuicConnection* client_connection = client_session->connection();
- ASSERT_TRUE(client_connection);
-
- SetPacketLossPercentage(30);
- ASSERT_GT(kMaxOutgoingPacketSize,
- client_session->GetCurrentLargestMessagePayload());
- ASSERT_LT(0, client_session->GetCurrentLargestMessagePayload());
-
- std::string message_string(kMaxOutgoingPacketSize, 'a');
- QuicRandom* random =
- QuicConnectionPeer::GetHelper(client_connection)->GetRandomGenerator();
- {
- QuicConnection::ScopedPacketFlusher flusher(client_session->connection());
- // Verify the largest message gets successfully sent.
- EXPECT_EQ(MessageResult(MESSAGE_STATUS_SUCCESS, 1),
- client_session->SendMessage(MemSliceFromString(absl::string_view(
- message_string.data(),
- client_session->GetCurrentLargestMessagePayload()))));
- // Send more messages with size (0, largest_payload] until connection is
- // write blocked.
- const int kTestMaxNumberOfMessages = 100;
- for (size_t i = 2; i <= kTestMaxNumberOfMessages; ++i) {
- size_t message_length =
- random->RandUint64() %
- client_session->GetGuaranteedLargestMessagePayload() +
- 1;
- MessageResult result = client_session->SendMessage(MemSliceFromString(
- absl::string_view(message_string.data(), message_length)));
- if (result.status == MESSAGE_STATUS_BLOCKED) {
- // Connection is write blocked.
- break;
- }
- EXPECT_EQ(MessageResult(MESSAGE_STATUS_SUCCESS, i), result);
- }
- }
-
- client_->WaitForDelayedAcks();
- EXPECT_EQ(MESSAGE_STATUS_TOO_LARGE,
- client_session
- ->SendMessage(MemSliceFromString(absl::string_view(
- message_string.data(),
- client_session->GetCurrentLargestMessagePayload() + 1)))
- .status);
- EXPECT_THAT(client_->connection_error(), IsQuicNoError());
-}
-
-class EndToEndPacketReorderingTest : public EndToEndTest {
- public:
- void CreateClientWithWriter() override {
- QUIC_LOG(ERROR) << "create client with reorder_writer_";
- reorder_writer_ = new PacketReorderingWriter();
- client_.reset(EndToEndTest::CreateQuicClient(reorder_writer_));
- }
-
- void SetUp() override {
- // Don't initialize client writer in base class.
- server_writer_ = new PacketDroppingTestWriter();
- }
-
- protected:
- PacketReorderingWriter* reorder_writer_;
-};
-
-INSTANTIATE_TEST_SUITE_P(EndToEndPacketReorderingTests,
- EndToEndPacketReorderingTest,
- ::testing::ValuesIn(GetTestParams()),
- ::testing::PrintToStringParamName());
-
-TEST_P(EndToEndPacketReorderingTest, ReorderedConnectivityProbing) {
- ASSERT_TRUE(Initialize());
- if (version_.HasIetfQuicFrames()) {
- return;
- }
-
- // Finish one request to make sure handshake established.
- EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
-
- // Wait for the connection to become idle, to make sure the packet gets
- // delayed is the connectivity probing packet.
- client_->WaitForDelayedAcks();
-
- QuicSocketAddress old_addr =
- client_->client()->network_helper()->GetLatestClientAddress();
-
- // Migrate socket to the new IP address.
- QuicIpAddress new_host = TestLoopback(2);
- EXPECT_NE(old_addr.host(), new_host);
- ASSERT_TRUE(client_->client()->MigrateSocket(new_host));
-
- // Write a connectivity probing after the next /foo request.
- reorder_writer_->SetDelay(1);
- client_->SendConnectivityProbing();
-
- ASSERT_TRUE(client_->MigrateSocketWithSpecifiedPort(old_addr.host(),
- old_addr.port()));
-
- // The (delayed) connectivity probing will be sent after this request.
- EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
-
- // Send yet another request after the connectivity probing, when this request
- // returns, the probing is guaranteed to have been received by the server, and
- // the server's response to probing is guaranteed to have been received by the
- // client.
- EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
-
- server_thread_->Pause();
- QuicConnection* server_connection = GetServerConnection();
- if (server_connection != nullptr) {
- EXPECT_EQ(1u,
- server_connection->GetStats().num_connectivity_probing_received);
- } else {
- ADD_FAILURE() << "Missing server connection";
- }
- server_thread_->Resume();
-
- // Server definitely responded to the connectivity probing. Sometime it also
- // sends a padded ping that is not a connectivity probing, which is recognized
- // as connectivity probing because client's self address is ANY.
- QuicConnection* client_connection = GetClientConnection();
- ASSERT_TRUE(client_connection);
- EXPECT_LE(1u,
- client_connection->GetStats().num_connectivity_probing_received);
-}
-
-// A writer which holds the next packet to be sent till ReleasePacket() is
-// called.
-class PacketHoldingWriter : public QuicPacketWriterWrapper {
- public:
- WriteResult WritePacket(const char* buffer, size_t buf_len,
- const QuicIpAddress& self_address,
- const QuicSocketAddress& peer_address,
- PerPacketOptions* options) override {
- if (!hold_next_packet_) {
- return QuicPacketWriterWrapper::WritePacket(buffer, buf_len, self_address,
- peer_address, options);
- }
- QUIC_DLOG(INFO) << "Packet is held by the writer";
- packet_content_ = std::string(buffer, buf_len);
- self_address_ = self_address;
- peer_address_ = peer_address;
- options_ = (options == nullptr ? nullptr : options->Clone());
- hold_next_packet_ = false;
- return WriteResult(WRITE_STATUS_OK, buf_len);
- }
-
- void HoldNextPacket() {
- QUICHE_DCHECK(packet_content_.empty())
- << "There is already one packet on hold.";
- hold_next_packet_ = true;
- }
-
- void ReleasePacket() {
- QUIC_DLOG(INFO) << "Release packet";
- ASSERT_EQ(WRITE_STATUS_OK,
- QuicPacketWriterWrapper::WritePacket(
- packet_content_.data(), packet_content_.length(),
- self_address_, peer_address_, options_.release())
- .status);
- packet_content_.clear();
- }
-
- private:
- bool hold_next_packet_{false};
- std::string packet_content_;
- QuicIpAddress self_address_;
- QuicSocketAddress peer_address_;
- std::unique_ptr<PerPacketOptions> options_;
-};
-
-TEST_P(EndToEndTest, ClientValidateNewNetwork) {
- ASSERT_TRUE(Initialize());
- if (!version_.HasIetfQuicFrames() ||
- !GetClientConnection()->validate_client_address()) {
- return;
- }
- client_.reset(EndToEndTest::CreateQuicClient(nullptr));
- SendSynchronousFooRequestAndCheckResponse();
-
- // Store the client IP address which was used to send the first request.
- QuicIpAddress old_host =
- client_->client()->network_helper()->GetLatestClientAddress().host();
-
- // Migrate socket to the new IP address.
- QuicIpAddress new_host = TestLoopback(2);
- EXPECT_NE(old_host, new_host);
-
- client_->client()->ValidateNewNetwork(new_host);
- // Send a request using the old socket.
- EXPECT_EQ(kBarResponseBody, client_->SendSynchronousRequest("/bar"));
- // Client should have received a PATH_CHALLENGE.
- QuicConnection* client_connection = GetClientConnection();
- ASSERT_TRUE(client_connection);
- EXPECT_EQ(1u,
- client_connection->GetStats().num_connectivity_probing_received);
-
- // Send another request to make sure THE server will receive PATH_RESPONSE.
- client_->SendSynchronousRequest("/eep");
-
- server_thread_->Pause();
- QuicConnection* server_connection = GetServerConnection();
- if (server_connection != nullptr) {
- EXPECT_EQ(1u,
- server_connection->GetStats().num_connectivity_probing_received);
- } else {
- ADD_FAILURE() << "Missing server connection";
- }
- server_thread_->Resume();
-}
-
-TEST_P(EndToEndPacketReorderingTest, ReorderedPathChallenge) {
- ASSERT_TRUE(Initialize());
- if (!version_.HasIetfQuicFrames() ||
- !client_->client()->session()->connection()->use_path_validator()) {
- return;
- }
- client_.reset(EndToEndTest::CreateQuicClient(nullptr));
-
- // Finish one request to make sure handshake established.
- EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
-
- // Wait for the connection to become idle, to make sure the packet gets
- // delayed is the connectivity probing packet.
- client_->WaitForDelayedAcks();
-
- QuicSocketAddress old_addr =
- client_->client()->network_helper()->GetLatestClientAddress();
-
- // Migrate socket to the new IP address.
- QuicIpAddress new_host = TestLoopback(2);
- EXPECT_NE(old_addr.host(), new_host);
-
- // Setup writer wrapper to hold the probing packet.
- auto holding_writer = new PacketHoldingWriter();
- client_->UseWriter(holding_writer);
- // Write a connectivity probing after the next /foo request.
- holding_writer->HoldNextPacket();
-
- // A packet with PATH_CHALLENGE will be held in the writer.
- client_->client()->ValidateNewNetwork(new_host);
-
- // Send (on-hold) PATH_CHALLENGE after this request.
- client_->SendRequest("/foo");
- holding_writer->ReleasePacket();
-
- client_->WaitForResponse();
-
- EXPECT_EQ(kFooResponseBody, client_->response_body());
- // Send yet another request after the PATH_CHALLENGE, when this request
- // returns, the probing is guaranteed to have been received by the server, and
- // the server's response to probing is guaranteed to have been received by the
- // client.
- EXPECT_EQ(kBarResponseBody, client_->SendSynchronousRequest("/bar"));
-
- // Client should have received a PATH_CHALLENGE.
- QuicConnection* client_connection = GetClientConnection();
- ASSERT_TRUE(client_connection);
- EXPECT_EQ(client_connection->validate_client_address() ? 1u : 0,
- client_connection->GetStats().num_connectivity_probing_received);
-
- server_thread_->Pause();
- QuicConnection* server_connection = GetServerConnection();
- if (server_connection != nullptr) {
- EXPECT_EQ(1u,
- server_connection->GetStats().num_connectivity_probing_received);
- } else {
- ADD_FAILURE() << "Missing server connection";
- }
- server_thread_->Resume();
-}
-
-TEST_P(EndToEndPacketReorderingTest, PathValidationFailure) {
- ASSERT_TRUE(Initialize());
- if (!version_.HasIetfQuicFrames() ||
- !client_->client()->session()->connection()->use_path_validator()) {
- return;
- }
-
- client_.reset(CreateQuicClient(nullptr));
- // Finish one request to make sure handshake established.
- EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
-
- // Wait for the connection to become idle, to make sure the packet gets
- // delayed is the connectivity probing packet.
- client_->WaitForDelayedAcks();
-
- QuicSocketAddress old_addr = client_->client()->session()->self_address();
-
- // Migrate socket to the new IP address.
- QuicIpAddress new_host = TestLoopback(2);
- EXPECT_NE(old_addr.host(), new_host);
-
- // Drop PATH_RESPONSE packets to timeout the path validation.
- server_writer_->set_fake_packet_loss_percentage(100);
- ASSERT_TRUE(client_->client()->ValidateAndMigrateSocket(new_host));
- while (client_->client()->HasPendingPathValidation()) {
- client_->client()->WaitForEvents();
- }
- EXPECT_EQ(old_addr, client_->client()->session()->self_address());
- server_writer_->set_fake_packet_loss_percentage(0);
- EXPECT_EQ(kBarResponseBody, client_->SendSynchronousRequest("/bar"));
-
- server_thread_->Pause();
- QuicConnection* server_connection = GetServerConnection();
- if (server_connection != nullptr) {
- EXPECT_EQ(3u,
- server_connection->GetStats().num_connectivity_probing_received);
- } else {
- ADD_FAILURE() << "Missing server connection";
- }
- server_thread_->Resume();
-}
-
-TEST_P(EndToEndPacketReorderingTest, MigrateAgainAfterPathValidationFailure) {
- ASSERT_TRUE(Initialize());
- if (!GetClientConnection()->connection_migration_use_new_cid()) {
- return;
- }
-
- client_.reset(CreateQuicClient(nullptr));
- // Finish one request to make sure handshake established.
- EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
-
- // Wait for the connection to become idle, to make sure the packet gets
- // delayed is the connectivity probing packet.
- client_->WaitForDelayedAcks();
-
- QuicSocketAddress addr1 = client_->client()->session()->self_address();
- QuicConnection* client_connection = GetClientConnection();
- QuicConnectionId server_cid1 = client_connection->connection_id();
-
- // Migrate socket to the new IP address.
- QuicIpAddress host2 = TestLoopback(2);
- EXPECT_NE(addr1.host(), host2);
-
- // Drop PATH_RESPONSE packets to timeout the path validation.
- server_writer_->set_fake_packet_loss_percentage(100);
- ASSERT_TRUE(
- QuicConnectionPeer::HasUnusedPeerIssuedConnectionId(client_connection));
-
- ASSERT_TRUE(client_->client()->ValidateAndMigrateSocket(host2));
-
- QuicConnectionId server_cid2 =
- QuicConnectionPeer::GetServerConnectionIdOnAlternativePath(
- client_connection);
- EXPECT_FALSE(server_cid2.IsEmpty());
- EXPECT_NE(server_cid2, server_cid1);
- // Wait until path validation fails at the client.
- while (client_->client()->HasPendingPathValidation()) {
- EXPECT_EQ(server_cid2,
- QuicConnectionPeer::GetServerConnectionIdOnAlternativePath(
- client_connection));
- client_->client()->WaitForEvents();
- }
- EXPECT_EQ(addr1, client_->client()->session()->self_address());
- EXPECT_EQ(server_cid1, GetClientConnection()->connection_id());
-
- server_writer_->set_fake_packet_loss_percentage(0);
- EXPECT_EQ(kBarResponseBody, client_->SendSynchronousRequest("/bar"));
-
- WaitForNewConnectionIds();
- EXPECT_EQ(1u, client_connection->GetStats().num_retire_connection_id_sent);
- EXPECT_EQ(0u, client_connection->GetStats().num_new_connection_id_sent);
-
- server_thread_->Pause();
- QuicConnection* server_connection = GetServerConnection();
- // Server has received 3 path challenges.
- EXPECT_EQ(3u,
- server_connection->GetStats().num_connectivity_probing_received);
- EXPECT_EQ(server_cid1, server_connection->connection_id());
- EXPECT_EQ(0u, server_connection->GetStats().num_retire_connection_id_sent);
- EXPECT_EQ(2u, server_connection->GetStats().num_new_connection_id_sent);
- server_thread_->Resume();
-
- // Migrate socket to a new IP address again.
- QuicIpAddress host3 = TestLoopback(3);
- EXPECT_NE(addr1.host(), host3);
- EXPECT_NE(host2, host3);
-
- WaitForNewConnectionIds();
- EXPECT_EQ(1u, client_connection->GetStats().num_retire_connection_id_sent);
- EXPECT_EQ(0u, client_connection->GetStats().num_new_connection_id_sent);
-
- ASSERT_TRUE(client_->client()->ValidateAndMigrateSocket(host3));
- QuicConnectionId server_cid3 =
- QuicConnectionPeer::GetServerConnectionIdOnAlternativePath(
- client_connection);
- EXPECT_FALSE(server_cid3.IsEmpty());
- EXPECT_NE(server_cid1, server_cid3);
- EXPECT_NE(server_cid2, server_cid3);
- while (client_->client()->HasPendingPathValidation()) {
- client_->client()->WaitForEvents();
- }
- EXPECT_EQ(host3, client_->client()->session()->self_address().host());
- EXPECT_EQ(server_cid3, GetClientConnection()->connection_id());
- EXPECT_TRUE(QuicConnectionPeer::GetServerConnectionIdOnAlternativePath(
- client_connection)
- .IsEmpty());
- EXPECT_EQ(kBarResponseBody, client_->SendSynchronousRequest("/bar"));
-
- // Server should send a new connection ID to client.
- WaitForNewConnectionIds();
- EXPECT_EQ(2u, client_connection->GetStats().num_retire_connection_id_sent);
- EXPECT_EQ(0u, client_connection->GetStats().num_new_connection_id_sent);
-}
-
-TEST_P(EndToEndPacketReorderingTest,
- MigrateAgainAfterPathValidationFailureWithNonZeroClientCid) {
- if (!version_.SupportsClientConnectionIds()) {
- ASSERT_TRUE(Initialize());
- return;
- }
- SetQuicReloadableFlag(quic_retire_cid_on_reverse_path_validation_failure,
- true);
- override_client_connection_id_length_ = kQuicDefaultConnectionIdLength;
- ASSERT_TRUE(Initialize());
- if (!GetClientConnection()->connection_migration_use_new_cid()) {
- return;
- }
-
- client_.reset(CreateQuicClient(nullptr));
- // Finish one request to make sure handshake established.
- EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
-
- // Wait for the connection to become idle, to make sure the packet gets
- // delayed is the connectivity probing packet.
- client_->WaitForDelayedAcks();
-
- QuicSocketAddress addr1 = client_->client()->session()->self_address();
- QuicConnection* client_connection = GetClientConnection();
- QuicConnectionId server_cid1 = client_connection->connection_id();
- QuicConnectionId client_cid1 = client_connection->client_connection_id();
-
- // Migrate socket to the new IP address.
- QuicIpAddress host2 = TestLoopback(2);
- EXPECT_NE(addr1.host(), host2);
-
- // Drop PATH_RESPONSE packets to timeout the path validation.
- server_writer_->set_fake_packet_loss_percentage(100);
- ASSERT_TRUE(
- QuicConnectionPeer::HasUnusedPeerIssuedConnectionId(client_connection));
- ASSERT_TRUE(client_->client()->ValidateAndMigrateSocket(host2));
- QuicConnectionId server_cid2 =
- QuicConnectionPeer::GetServerConnectionIdOnAlternativePath(
- client_connection);
- EXPECT_FALSE(server_cid2.IsEmpty());
- EXPECT_NE(server_cid2, server_cid1);
- QuicConnectionId client_cid2 =
- QuicConnectionPeer::GetClientConnectionIdOnAlternativePath(
- client_connection);
- EXPECT_FALSE(client_cid2.IsEmpty());
- EXPECT_NE(client_cid2, client_cid1);
- while (client_->client()->HasPendingPathValidation()) {
- EXPECT_EQ(server_cid2,
- QuicConnectionPeer::GetServerConnectionIdOnAlternativePath(
- client_connection));
- client_->client()->WaitForEvents();
- }
- EXPECT_EQ(addr1, client_->client()->session()->self_address());
- EXPECT_EQ(server_cid1, GetClientConnection()->connection_id());
- EXPECT_TRUE(QuicConnectionPeer::GetServerConnectionIdOnAlternativePath(
- client_connection)
- .IsEmpty());
- server_writer_->set_fake_packet_loss_percentage(0);
- EXPECT_EQ(kBarResponseBody, client_->SendSynchronousRequest("/bar"));
- WaitForNewConnectionIds();
- EXPECT_EQ(1u, client_connection->GetStats().num_retire_connection_id_sent);
- EXPECT_EQ(2u, client_connection->GetStats().num_new_connection_id_sent);
-
- server_thread_->Pause();
- QuicConnection* server_connection = GetServerConnection();
- if (server_connection != nullptr) {
- EXPECT_EQ(3u,
- server_connection->GetStats().num_connectivity_probing_received);
- EXPECT_EQ(server_cid1, server_connection->connection_id());
- } else {
- ADD_FAILURE() << "Missing server connection";
- }
- EXPECT_EQ(1u, server_connection->GetStats().num_retire_connection_id_sent);
- EXPECT_EQ(2u, server_connection->GetStats().num_new_connection_id_sent);
- server_thread_->Resume();
-
- // Migrate socket to a new IP address again.
- QuicIpAddress host3 = TestLoopback(3);
- EXPECT_NE(addr1.host(), host3);
- EXPECT_NE(host2, host3);
- ASSERT_TRUE(client_->client()->ValidateAndMigrateSocket(host3));
-
- QuicConnectionId server_cid3 =
- QuicConnectionPeer::GetServerConnectionIdOnAlternativePath(
- client_connection);
- EXPECT_FALSE(server_cid3.IsEmpty());
- EXPECT_NE(server_cid1, server_cid3);
- EXPECT_NE(server_cid2, server_cid3);
- QuicConnectionId client_cid3 =
- QuicConnectionPeer::GetClientConnectionIdOnAlternativePath(
- client_connection);
- EXPECT_NE(client_cid1, client_cid3);
- EXPECT_NE(client_cid2, client_cid3);
- while (client_->client()->HasPendingPathValidation()) {
- client_->client()->WaitForEvents();
- }
- EXPECT_EQ(host3, client_->client()->session()->self_address().host());
- EXPECT_EQ(server_cid3, GetClientConnection()->connection_id());
- EXPECT_TRUE(QuicConnectionPeer::GetServerConnectionIdOnAlternativePath(
- client_connection)
- .IsEmpty());
- EXPECT_EQ(kBarResponseBody, client_->SendSynchronousRequest("/bar"));
-
- // Server should send new server connection ID to client and retires old
- // client connection ID.
- WaitForNewConnectionIds();
- EXPECT_EQ(2u, client_connection->GetStats().num_retire_connection_id_sent);
- EXPECT_EQ(3u, client_connection->GetStats().num_new_connection_id_sent);
-}
-
-TEST_P(EndToEndPacketReorderingTest, Buffer0RttRequest) {
- ASSERT_TRUE(Initialize());
- // Finish one request to make sure handshake established.
- client_->SendSynchronousRequest("/foo");
- // 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);
- // 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;
- headers[":method"] = "POST";
- headers[":path"] = "/bar";
- headers[":scheme"] = "https";
- headers[":authority"] = server_hostname_;
-
- client_->SendMessage(headers, "");
- client_->WaitForResponse();
- EXPECT_EQ(kBarResponseBody, client_->response_body());
- 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_TRUE(client_->client()->EarlyDataAccepted());
-}
-
-TEST_P(EndToEndTest, SimpleStopSendingRstStreamTest) {
- ASSERT_TRUE(Initialize());
-
- // Send a request without a fin, to keep the stream open
- SpdyHeaderBlock headers;
- headers[":method"] = "POST";
- headers[":path"] = "/foo";
- headers[":scheme"] = "https";
- headers[":authority"] = server_hostname_;
- client_->SendMessage(headers, "", /*fin=*/false);
- // Stream should be open
- ASSERT_NE(nullptr, client_->latest_created_stream());
- EXPECT_FALSE(client_->latest_created_stream()->write_side_closed());
- EXPECT_FALSE(
- QuicStreamPeer::read_side_closed(client_->latest_created_stream()));
-
- // Send a RST_STREAM+STOP_SENDING on the stream
- // Code is not important.
- client_->latest_created_stream()->Reset(QUIC_BAD_APPLICATION_PAYLOAD);
- client_->WaitForResponse();
-
- // Stream should be gone.
- ASSERT_EQ(nullptr, client_->latest_created_stream());
-}
-
-class BadShloPacketWriter : public QuicPacketWriterWrapper {
- public:
- BadShloPacketWriter(ParsedQuicVersion version)
- : error_returned_(false), version_(version) {}
- ~BadShloPacketWriter() override {}
-
- WriteResult WritePacket(const char* buffer, size_t buf_len,
- const QuicIpAddress& self_address,
- const QuicSocketAddress& peer_address,
- quic::PerPacketOptions* options) override {
- const WriteResult result = QuicPacketWriterWrapper::WritePacket(
- buffer, buf_len, self_address, peer_address, options);
- const uint8_t type_byte = buffer[0];
- if (!error_returned_ && (type_byte & FLAGS_LONG_HEADER) &&
- TypeByteIsServerHello(type_byte)) {
- QUIC_DVLOG(1) << "Return write error for packet containing ServerHello";
- error_returned_ = true;
- return WriteResult(WRITE_STATUS_ERROR, QUIC_EMSGSIZE);
- }
- return result;
- }
-
- bool TypeByteIsServerHello(uint8_t type_byte) {
- if (version_.UsesV2PacketTypes()) {
- return ((type_byte & 0x30) >> 4) == 3;
- }
- if (version_.UsesQuicCrypto()) {
- // ENCRYPTION_ZERO_RTT packet.
- return ((type_byte & 0x30) >> 4) == 1;
- }
- // ENCRYPTION_HANDSHAKE packet.
- return ((type_byte & 0x30) >> 4) == 2;
- }
-
- private:
- bool error_returned_;
- ParsedQuicVersion version_;
-};
-
-TEST_P(EndToEndTest, ConnectionCloseBeforeHandshakeComplete) {
- if (!version_.HasIetfInvariantHeader()) {
- // Only runs for IETF QUIC header.
- Initialize();
- return;
- }
- // This test ensures ZERO_RTT_PROTECTED connection close could close a client
- // which has switched to forward secure.
- connect_to_server_on_initialize_ = false;
- ASSERT_TRUE(Initialize());
- server_thread_->Pause();
- QuicDispatcher* dispatcher =
- QuicServerPeer::GetDispatcher(server_thread_->server());
- if (dispatcher == nullptr) {
- ADD_FAILURE() << "Missing dispatcher";
- server_thread_->Resume();
- return;
- }
- if (dispatcher->NumSessions() > 0) {
- ADD_FAILURE() << "Dispatcher session map not empty";
- server_thread_->Resume();
- return;
- }
- // Note: this writer will only used by the server connection, not the time
- // wait list.
- QuicDispatcherPeer::UseWriter(
- dispatcher,
- // This causes the first server sent ZERO_RTT_PROTECTED packet (i.e.,
- // SHLO) to be sent, but WRITE_ERROR is returned. Such that a
- // ZERO_RTT_PROTECTED connection close would be sent to a client with
- // encryption level FORWARD_SECURE.
- new BadShloPacketWriter(version_));
- server_thread_->Resume();
-
- client_.reset(CreateQuicClient(client_writer_));
- EXPECT_EQ("", client_->SendSynchronousRequest("/foo"));
- // Verify ZERO_RTT_PROTECTED connection close is successfully processed by
- // client which switches to FORWARD_SECURE.
- EXPECT_THAT(client_->connection_error(), IsError(QUIC_PACKET_WRITE_ERROR));
-}
-
-class BadShloPacketWriter2 : public QuicPacketWriterWrapper {
- public:
- BadShloPacketWriter2(ParsedQuicVersion version)
- : error_returned_(false), version_(version) {}
- ~BadShloPacketWriter2() override {}
-
- WriteResult WritePacket(const char* buffer, size_t buf_len,
- const QuicIpAddress& self_address,
- const QuicSocketAddress& peer_address,
- quic::PerPacketOptions* options) override {
- const uint8_t type_byte = buffer[0];
-
- if (type_byte & FLAGS_LONG_HEADER) {
- if (((type_byte & 0x30 >> 4) == (version_.UsesV2PacketTypes() ? 2 : 1)) ||
- ((type_byte & 0x7F) == 0x7C)) {
- QUIC_DVLOG(1) << "Dropping ZERO_RTT_PACKET packet";
- return WriteResult(WRITE_STATUS_OK, buf_len);
- }
- } else if (!error_returned_) {
- QUIC_DVLOG(1) << "Return write error for short header packet";
- error_returned_ = true;
- return WriteResult(WRITE_STATUS_ERROR, QUIC_EMSGSIZE);
- }
- return QuicPacketWriterWrapper::WritePacket(buffer, buf_len, self_address,
- peer_address, options);
- }
-
- private:
- bool error_returned_;
- ParsedQuicVersion version_;
-};
-
-TEST_P(EndToEndTest, ForwardSecureConnectionClose) {
- // This test ensures ZERO_RTT_PROTECTED connection close is sent to a client
- // which has ZERO_RTT_PROTECTED encryption level.
- connect_to_server_on_initialize_ = !version_.HasIetfInvariantHeader();
- ASSERT_TRUE(Initialize());
- if (!version_.HasIetfInvariantHeader()) {
- // Only runs for IETF QUIC header.
- return;
- }
- server_thread_->Pause();
- QuicDispatcher* dispatcher =
- QuicServerPeer::GetDispatcher(server_thread_->server());
- if (dispatcher == nullptr) {
- ADD_FAILURE() << "Missing dispatcher";
- server_thread_->Resume();
- return;
- }
- if (dispatcher->NumSessions() > 0) {
- ADD_FAILURE() << "Dispatcher session map not empty";
- server_thread_->Resume();
- return;
- }
- // Note: this writer will only used by the server connection, not the time
- // wait list.
- QuicDispatcherPeer::UseWriter(
- dispatcher,
- // This causes the all server sent ZERO_RTT_PROTECTED packets to be
- // dropped, and first short header packet causes write error.
- new BadShloPacketWriter2(version_));
- server_thread_->Resume();
- client_.reset(CreateQuicClient(client_writer_));
- EXPECT_EQ("", client_->SendSynchronousRequest("/foo"));
- // Verify ZERO_RTT_PROTECTED connection close is successfully processed by
- // client.
- EXPECT_THAT(client_->connection_error(), IsError(QUIC_PACKET_WRITE_ERROR));
-}
-
-// Test that the stream id manager closes the connection if a stream
-// in excess of the allowed maximum.
-TEST_P(EndToEndTest, TooBigStreamIdClosesConnection) {
- // Has to be before version test, see EndToEndTest::TearDown()
- ASSERT_TRUE(Initialize());
- if (!version_.HasIetfQuicFrames()) {
- // Only runs for IETF QUIC.
- return;
- }
- EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
-
- std::string body(kMaxOutgoingPacketSize, 'a');
- SpdyHeaderBlock headers;
- headers[":method"] = "POST";
- headers[":path"] = "/foo";
- headers[":scheme"] = "https";
- headers[":authority"] = server_hostname_;
-
- // Force the client to write with a stream ID that exceeds the limit.
- QuicSpdySession* client_session = GetClientSession();
- ASSERT_TRUE(client_session);
- QuicStreamIdManager* stream_id_manager =
- QuicSessionPeer::ietf_bidirectional_stream_id_manager(client_session);
- ASSERT_TRUE(stream_id_manager);
- QuicStreamCount max_number_of_streams =
- stream_id_manager->outgoing_max_streams();
- QuicSessionPeer::SetNextOutgoingBidirectionalStreamId(
- client_session,
- GetNthClientInitiatedBidirectionalId(max_number_of_streams + 1));
- client_->SendCustomSynchronousRequest(headers, body);
- EXPECT_THAT(client_->stream_error(),
- IsStreamError(QUIC_STREAM_CONNECTION_ERROR));
- EXPECT_THAT(client_session->error(), IsError(QUIC_INVALID_STREAM_ID));
- EXPECT_EQ(IETF_QUIC_TRANSPORT_CONNECTION_CLOSE, client_session->close_type());
- EXPECT_TRUE(
- IS_IETF_STREAM_FRAME(client_session->transport_close_frame_type()));
-}
-
-TEST_P(EndToEndTest, CustomTransportParameters) {
- if (!version_.UsesTls()) {
- // Custom transport parameters are only supported with TLS.
- ASSERT_TRUE(Initialize());
- return;
- }
- constexpr auto kCustomParameter =
- static_cast<TransportParameters::TransportParameterId>(0xff34);
- client_config_.custom_transport_parameters_to_send()[kCustomParameter] =
- "test";
- NiceMock<MockQuicConnectionDebugVisitor> visitor;
- connection_debug_visitor_ = &visitor;
- EXPECT_CALL(visitor, OnTransportParametersSent(_))
- .WillOnce(Invoke([kCustomParameter](
- const TransportParameters& transport_parameters) {
- ASSERT_NE(transport_parameters.custom_parameters.find(kCustomParameter),
- transport_parameters.custom_parameters.end());
- EXPECT_EQ(transport_parameters.custom_parameters.at(kCustomParameter),
- "test");
- }));
- EXPECT_CALL(visitor, OnTransportParametersReceived(_)).Times(1);
- ASSERT_TRUE(Initialize());
-
- EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
-
- server_thread_->Pause();
- QuicSpdySession* server_session = GetServerSession();
- QuicConfig* server_config = nullptr;
- if (server_session != nullptr) {
- server_config = server_session->config();
- } else {
- ADD_FAILURE() << "Missing server session";
- }
- if (server_config != nullptr) {
- if (server_config->received_custom_transport_parameters().find(
- kCustomParameter) !=
- server_config->received_custom_transport_parameters().end()) {
- EXPECT_EQ(server_config->received_custom_transport_parameters().at(
- kCustomParameter),
- "test");
- } else {
- ADD_FAILURE() << "Did not find custom parameter";
- }
- } else {
- ADD_FAILURE() << "Missing server config";
- }
- server_thread_->Resume();
-}
-
-TEST_P(EndToEndTest, LegacyVersionEncapsulation) {
- if (!version_.HasLongHeaderLengths()) {
- // Decapsulating Legacy Version Encapsulation packets from these versions
- // is not currently supported in QuicDispatcher.
- ASSERT_TRUE(Initialize());
- return;
- }
- client_config_.SetClientConnectionOptions(QuicTagVector{kQLVE});
- ASSERT_TRUE(Initialize());
- SendSynchronousFooRequestAndCheckResponse();
- QuicConnection* client_connection = GetClientConnection();
- ASSERT_TRUE(client_connection);
- EXPECT_GT(
- client_connection->GetStats().sent_legacy_version_encapsulated_packets,
- 0u);
-}
-
-TEST_P(EndToEndTest, LegacyVersionEncapsulationWithMultiPacketChlo) {
- if (!version_.HasLongHeaderLengths()) {
- // Decapsulating Legacy Version Encapsulation packets from these versions
- // is not currently supported in QuicDispatcher.
- ASSERT_TRUE(Initialize());
- return;
- }
- if (!version_.UsesTls()) {
- // This test uses custom transport parameters to increase the size of the
- // CHLO, and those are only supported with TLS.
- ASSERT_TRUE(Initialize());
- return;
- }
- client_config_.SetClientConnectionOptions(QuicTagVector{kQLVE});
- constexpr auto kCustomParameter =
- static_cast<TransportParameters::TransportParameterId>(0xff34);
- client_config_.custom_transport_parameters_to_send()[kCustomParameter] =
- std::string(2000, '?');
- ASSERT_TRUE(Initialize());
- SendSynchronousFooRequestAndCheckResponse();
- QuicConnection* client_connection = GetClientConnection();
- ASSERT_TRUE(client_connection);
- EXPECT_GT(
- client_connection->GetStats().sent_legacy_version_encapsulated_packets,
- 0u);
-}
-
-TEST_P(EndToEndTest, LegacyVersionEncapsulationWithVersionNegotiation) {
- if (!version_.HasLongHeaderLengths()) {
- // Decapsulating Legacy Version Encapsulation packets from these versions
- // is not currently supported in QuicDispatcher.
- ASSERT_TRUE(Initialize());
- return;
- }
- client_supported_versions_.insert(client_supported_versions_.begin(),
- QuicVersionReservedForNegotiation());
- client_config_.SetClientConnectionOptions(QuicTagVector{kQLVE});
- ASSERT_TRUE(Initialize());
- SendSynchronousFooRequestAndCheckResponse();
- QuicConnection* client_connection = GetClientConnection();
- ASSERT_TRUE(client_connection);
- EXPECT_GT(
- client_connection->GetStats().sent_legacy_version_encapsulated_packets,
- 0u);
-}
-
-TEST_P(EndToEndTest, LegacyVersionEncapsulationWithLoss) {
- if (!version_.HasLongHeaderLengths()) {
- // Decapsulating Legacy Version Encapsulation packets from these versions
- // is not currently supported in QuicDispatcher.
- ASSERT_TRUE(Initialize());
- return;
- }
- SetPacketLossPercentage(30);
- client_config_.SetClientConnectionOptions(QuicTagVector{kQLVE});
- // Disable blackhole detection as this test is testing loss recovery.
- client_extra_copts_.push_back(kNBHD);
- ASSERT_TRUE(Initialize());
- SendSynchronousFooRequestAndCheckResponse();
- QuicConnection* client_connection = GetClientConnection();
- ASSERT_TRUE(client_connection);
- EXPECT_GT(
- client_connection->GetStats().sent_legacy_version_encapsulated_packets,
- 0u);
-}
-
-// Testing packet writer that makes a copy of the first sent packets before
-// sending them. Useful for tests that need access to sent packets.
-class CopyingPacketWriter : public PacketDroppingTestWriter {
- public:
- explicit CopyingPacketWriter(int num_packets_to_copy)
- : num_packets_to_copy_(num_packets_to_copy) {}
- WriteResult WritePacket(const char* buffer, size_t buf_len,
- const QuicIpAddress& self_address,
- const QuicSocketAddress& peer_address,
- PerPacketOptions* options) override {
- if (num_packets_to_copy_ > 0) {
- num_packets_to_copy_--;
- packets_.push_back(
- QuicEncryptedPacket(buffer, buf_len, /*owns_buffer=*/false).Clone());
- }
- return PacketDroppingTestWriter::WritePacket(buffer, buf_len, self_address,
- peer_address, options);
- }
-
- std::vector<std::unique_ptr<QuicEncryptedPacket>>& packets() {
- return packets_;
- }
-
- private:
- int num_packets_to_copy_;
- std::vector<std::unique_ptr<QuicEncryptedPacket>> packets_;
-};
-
-TEST_P(EndToEndTest, ChaosProtectionDisabled) {
- if (!version_.UsesCryptoFrames()) {
- ASSERT_TRUE(Initialize());
- return;
- }
- // Replace the client's writer with one that'll save the first packet.
- auto copying_writer = new CopyingPacketWriter(1);
- delete client_writer_;
- client_writer_ = copying_writer;
- // Disable chaos protection and perform an HTTP request.
- client_config_.SetClientConnectionOptions(QuicTagVector{kNCHP});
- ASSERT_TRUE(Initialize());
- SendSynchronousFooRequestAndCheckResponse();
- // Parse the saved packet to make sure it's valid.
- SimpleQuicFramer validation_framer({version_});
- validation_framer.framer()->SetInitialObfuscators(
- GetClientConnection()->connection_id());
- 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
- // can inspect the contents of this packet.
-}
-
-TEST_P(EndToEndTest, DisablePermuteTlsExtensions) {
- if (!version_.UsesTls()) {
- ASSERT_TRUE(Initialize());
- return;
- }
- // Disable TLS extension permutation and perform an HTTP request.
- client_config_.SetClientConnectionOptions(QuicTagVector{kNBPE});
- ASSERT_TRUE(Initialize());
- EXPECT_FALSE(GetClientSession()->permutes_tls_extensions());
- SendSynchronousFooRequestAndCheckResponse();
-}
-
-TEST_P(EndToEndTest, KeyUpdateInitiatedByClient) {
- if (!version_.UsesTls()) {
- // Key Update is only supported in TLS handshake.
- ASSERT_TRUE(Initialize());
- return;
- }
-
- ASSERT_TRUE(Initialize());
-
- SendSynchronousFooRequestAndCheckResponse();
- QuicConnection* client_connection = GetClientConnection();
- ASSERT_TRUE(client_connection);
- EXPECT_EQ(0u, client_connection->GetStats().key_update_count);
-
- EXPECT_TRUE(
- client_connection->InitiateKeyUpdate(KeyUpdateReason::kLocalForTests));
- SendSynchronousFooRequestAndCheckResponse();
- EXPECT_EQ(1u, client_connection->GetStats().key_update_count);
-
- SendSynchronousFooRequestAndCheckResponse();
- EXPECT_EQ(1u, client_connection->GetStats().key_update_count);
-
- EXPECT_TRUE(
- client_connection->InitiateKeyUpdate(KeyUpdateReason::kLocalForTests));
- SendSynchronousFooRequestAndCheckResponse();
- EXPECT_EQ(2u, client_connection->GetStats().key_update_count);
-
- server_thread_->Pause();
- QuicConnection* server_connection = GetServerConnection();
- if (server_connection) {
- QuicConnectionStats server_stats = server_connection->GetStats();
- EXPECT_EQ(2u, server_stats.key_update_count);
- } else {
- ADD_FAILURE() << "Missing server connection";
- }
- server_thread_->Resume();
-}
-
-TEST_P(EndToEndTest, KeyUpdateInitiatedByServer) {
- if (!version_.UsesTls()) {
- // Key Update is only supported in TLS handshake.
- ASSERT_TRUE(Initialize());
- return;
- }
-
- ASSERT_TRUE(Initialize());
-
- SendSynchronousFooRequestAndCheckResponse();
- QuicConnection* client_connection = GetClientConnection();
- ASSERT_TRUE(client_connection);
- EXPECT_EQ(0u, client_connection->GetStats().key_update_count);
-
- // Use WaitUntil to ensure the server had executed the key update predicate
- // before sending the Foo request, otherwise the test can be flaky if it
- // receives the Foo request before executing the key update.
- server_thread_->WaitUntil(
- [this]() {
- QuicConnection* server_connection = GetServerConnection();
- if (server_connection != nullptr) {
- if (!server_connection->IsKeyUpdateAllowed()) {
- // Server may not have received ack from client yet for the current
- // key phase, wait a bit and try again.
- return false;
- }
- EXPECT_TRUE(server_connection->InitiateKeyUpdate(
- KeyUpdateReason::kLocalForTests));
- } else {
- ADD_FAILURE() << "Missing server connection";
- }
- return true;
- },
- QuicTime::Delta::FromSeconds(5));
-
- SendSynchronousFooRequestAndCheckResponse();
- EXPECT_EQ(1u, client_connection->GetStats().key_update_count);
-
- SendSynchronousFooRequestAndCheckResponse();
- EXPECT_EQ(1u, client_connection->GetStats().key_update_count);
-
- server_thread_->WaitUntil(
- [this]() {
- QuicConnection* server_connection = GetServerConnection();
- if (server_connection != nullptr) {
- if (!server_connection->IsKeyUpdateAllowed()) {
- return false;
- }
- EXPECT_TRUE(server_connection->InitiateKeyUpdate(
- KeyUpdateReason::kLocalForTests));
- } else {
- ADD_FAILURE() << "Missing server connection";
- }
- return true;
- },
- QuicTime::Delta::FromSeconds(5));
-
- SendSynchronousFooRequestAndCheckResponse();
- EXPECT_EQ(2u, client_connection->GetStats().key_update_count);
-
- server_thread_->Pause();
- QuicConnection* server_connection = GetServerConnection();
- if (server_connection) {
- QuicConnectionStats server_stats = server_connection->GetStats();
- EXPECT_EQ(2u, server_stats.key_update_count);
- } else {
- ADD_FAILURE() << "Missing server connection";
- }
- server_thread_->Resume();
-}
-
-TEST_P(EndToEndTest, KeyUpdateInitiatedByBoth) {
- if (!version_.UsesTls()) {
- // Key Update is only supported in TLS handshake.
- ASSERT_TRUE(Initialize());
- return;
- }
-
- ASSERT_TRUE(Initialize());
-
- SendSynchronousFooRequestAndCheckResponse();
-
- // Use WaitUntil to ensure the server had executed the key update predicate
- // before the client sends the Foo request, otherwise the Foo request from
- // the client could trigger the server key update before the server can
- // initiate the key update locally. That would mean the test is no longer
- // hitting the intended test state of both sides locally initiating a key
- // update before receiving a packet in the new key phase from the other side.
- // Additionally the test would fail since InitiateKeyUpdate() would not allow
- // to do another key update yet and return false.
- server_thread_->WaitUntil(
- [this]() {
- QuicConnection* server_connection = GetServerConnection();
- if (server_connection != nullptr) {
- if (!server_connection->IsKeyUpdateAllowed()) {
- // Server may not have received ack from client yet for the current
- // key phase, wait a bit and try again.
- return false;
- }
- EXPECT_TRUE(server_connection->InitiateKeyUpdate(
- KeyUpdateReason::kLocalForTests));
- } else {
- ADD_FAILURE() << "Missing server connection";
- }
- return true;
- },
- QuicTime::Delta::FromSeconds(5));
- QuicConnection* client_connection = GetClientConnection();
- ASSERT_TRUE(client_connection);
- EXPECT_TRUE(
- client_connection->InitiateKeyUpdate(KeyUpdateReason::kLocalForTests));
-
- SendSynchronousFooRequestAndCheckResponse();
- EXPECT_EQ(1u, client_connection->GetStats().key_update_count);
-
- SendSynchronousFooRequestAndCheckResponse();
- EXPECT_EQ(1u, client_connection->GetStats().key_update_count);
-
- server_thread_->WaitUntil(
- [this]() {
- QuicConnection* server_connection = GetServerConnection();
- if (server_connection != nullptr) {
- if (!server_connection->IsKeyUpdateAllowed()) {
- return false;
- }
- EXPECT_TRUE(server_connection->InitiateKeyUpdate(
- KeyUpdateReason::kLocalForTests));
- } else {
- ADD_FAILURE() << "Missing server connection";
- }
- return true;
- },
- QuicTime::Delta::FromSeconds(5));
- EXPECT_TRUE(
- client_connection->InitiateKeyUpdate(KeyUpdateReason::kLocalForTests));
-
- SendSynchronousFooRequestAndCheckResponse();
- EXPECT_EQ(2u, client_connection->GetStats().key_update_count);
-
- server_thread_->Pause();
- QuicConnection* server_connection = GetServerConnection();
- if (server_connection) {
- QuicConnectionStats server_stats = server_connection->GetStats();
- EXPECT_EQ(2u, server_stats.key_update_count);
- } else {
- ADD_FAILURE() << "Missing server connection";
- }
- server_thread_->Resume();
-}
-
-TEST_P(EndToEndTest, KeyUpdateInitiatedByConfidentialityLimit) {
- SetQuicFlag(FLAGS_quic_key_update_confidentiality_limit, 16U);
-
- if (!version_.UsesTls()) {
- // Key Update is only supported in TLS handshake.
- ASSERT_TRUE(Initialize());
- return;
- }
-
- ASSERT_TRUE(Initialize());
-
- QuicConnection* client_connection = GetClientConnection();
- ASSERT_TRUE(client_connection);
- EXPECT_EQ(0u, client_connection->GetStats().key_update_count);
-
- server_thread_->WaitUntil(
- [this]() {
- QuicConnection* server_connection = GetServerConnection();
- if (server_connection != nullptr) {
- EXPECT_EQ(0u, server_connection->GetStats().key_update_count);
- } else {
- ADD_FAILURE() << "Missing server connection";
- }
- return true;
- },
- QuicTime::Delta::FromSeconds(5));
-
- for (uint64_t i = 0;
- i < GetQuicFlag(FLAGS_quic_key_update_confidentiality_limit); ++i) {
- SendSynchronousFooRequestAndCheckResponse();
- }
-
- // Don't know exactly how many packets will be sent in each request/response,
- // so just test that at least one key update occurred.
- EXPECT_LE(1u, client_connection->GetStats().key_update_count);
-
- server_thread_->Pause();
- QuicConnection* server_connection = GetServerConnection();
- if (server_connection) {
- QuicConnectionStats server_stats = server_connection->GetStats();
- EXPECT_LE(1u, server_stats.key_update_count);
- } else {
- ADD_FAILURE() << "Missing server connection";
- }
- server_thread_->Resume();
-}
-
-TEST_P(EndToEndTest, TlsResumptionEnabledOnTheFly) {
- SetQuicFlag(FLAGS_quic_disable_server_tls_resumption, true);
- ASSERT_TRUE(Initialize());
-
- if (!version_.UsesTls()) {
- // This test is TLS specific.
- return;
- }
-
- // Send the first request. Client should not have a resumption ticket.
- SendSynchronousFooRequestAndCheckResponse();
- QuicSpdyClientSession* client_session = GetClientSession();
- ASSERT_TRUE(client_session);
- EXPECT_EQ(client_session->GetCryptoStream()->EarlyDataReason(),
- ssl_early_data_no_session_offered);
- EXPECT_FALSE(client_session->EarlyDataAccepted());
- client_->Disconnect();
-
- SetQuicFlag(FLAGS_quic_disable_server_tls_resumption, false);
-
- // Send the second request. Client should still have no resumption ticket, but
- // it will receive one which can be used by the next request.
- client_->Connect();
- SendSynchronousFooRequestAndCheckResponse();
-
- client_session = GetClientSession();
- ASSERT_TRUE(client_session);
- EXPECT_EQ(client_session->GetCryptoStream()->EarlyDataReason(),
- ssl_early_data_no_session_offered);
- EXPECT_FALSE(client_session->EarlyDataAccepted());
- client_->Disconnect();
-
- // Send the third request in 0RTT.
- client_->Connect();
- SendSynchronousFooRequestAndCheckResponse();
-
- client_session = GetClientSession();
- ASSERT_TRUE(client_session);
- EXPECT_TRUE(client_session->EarlyDataAccepted());
- client_->Disconnect();
-}
-
-TEST_P(EndToEndTest, TlsResumptionDisabledOnTheFly) {
- SetQuicFlag(FLAGS_quic_disable_server_tls_resumption, false);
- ASSERT_TRUE(Initialize());
-
- if (!version_.UsesTls()) {
- // This test is TLS specific.
- return;
- }
-
- // Send the first request and then disconnect.
- SendSynchronousFooRequestAndCheckResponse();
- QuicSpdyClientSession* client_session = GetClientSession();
- ASSERT_TRUE(client_session);
- EXPECT_FALSE(client_session->EarlyDataAccepted());
- client_->Disconnect();
-
- // Send the second request in 0RTT.
- client_->Connect();
- SendSynchronousFooRequestAndCheckResponse();
-
- client_session = GetClientSession();
- ASSERT_TRUE(client_session);
- EXPECT_TRUE(client_session->EarlyDataAccepted());
- client_->Disconnect();
-
- SetQuicFlag(FLAGS_quic_disable_server_tls_resumption, true);
-
- // Send the third request. The client should try resumption but server should
- // decline it.
- client_->Connect();
- SendSynchronousFooRequestAndCheckResponse();
-
- client_session = GetClientSession();
- ASSERT_TRUE(client_session);
- EXPECT_FALSE(client_session->EarlyDataAccepted());
- EXPECT_EQ(client_session->GetCryptoStream()->EarlyDataReason(),
- ssl_early_data_session_not_resumed);
- client_->Disconnect();
-
- // Keep sending until the client runs out of resumption tickets.
- for (int i = 0; i < 10; ++i) {
- client_->Connect();
- SendSynchronousFooRequestAndCheckResponse();
-
- client_session = GetClientSession();
- ASSERT_TRUE(client_session);
- EXPECT_FALSE(client_session->EarlyDataAccepted());
- const auto early_data_reason =
- client_session->GetCryptoStream()->EarlyDataReason();
- client_->Disconnect();
-
- if (early_data_reason != ssl_early_data_session_not_resumed) {
- EXPECT_EQ(early_data_reason, ssl_early_data_unsupported_for_session);
- return;
- }
- }
-
- ADD_FAILURE() << "Client should not have 10 resumption tickets.";
-}
-
-TEST_P(EndToEndTest, WebTransportSessionSetup) {
- enable_web_transport_ = true;
- ASSERT_TRUE(Initialize());
-
- if (!version_.UsesHttp3()) {
- return;
- }
-
- WebTransportHttp3* web_transport =
- CreateWebTransportSession("/echo", /*wait_for_server_response=*/true);
- ASSERT_NE(web_transport, nullptr);
-
- server_thread_->Pause();
- QuicSpdySession* server_session = GetServerSession();
- EXPECT_TRUE(server_session->GetWebTransportSession(web_transport->id()) !=
- nullptr);
- server_thread_->Resume();
-}
-
-TEST_P(EndToEndTest, WebTransportSessionSetupWithEchoWithSuffix) {
- enable_web_transport_ = true;
- ASSERT_TRUE(Initialize());
-
- if (!version_.UsesHttp3()) {
- return;
- }
-
- // "/echoFoo" should be accepted as "echo" with "set-header" query.
- WebTransportHttp3* web_transport = CreateWebTransportSession(
- "/echoFoo?set-header=bar:baz", /*wait_for_server_response=*/true);
- ASSERT_NE(web_transport, nullptr);
-
- server_thread_->Pause();
- QuicSpdySession* server_session = GetServerSession();
- EXPECT_TRUE(server_session->GetWebTransportSession(web_transport->id()) !=
- nullptr);
- server_thread_->Resume();
- const spdy::SpdyHeaderBlock* response_headers = client_->response_headers();
- auto it = response_headers->find("bar");
- EXPECT_NE(it, response_headers->end());
- EXPECT_EQ(it->second, "baz");
-}
-
-TEST_P(EndToEndTest, WebTransportSessionWithLoss) {
- enable_web_transport_ = true;
- // Enable loss to verify all permutations of receiving SETTINGS and
- // request/response data.
- SetPacketLossPercentage(30);
- ASSERT_TRUE(Initialize());
-
- if (!version_.UsesHttp3()) {
- return;
- }
-
- WebTransportHttp3* web_transport =
- CreateWebTransportSession("/echo", /*wait_for_server_response=*/true);
- ASSERT_NE(web_transport, nullptr);
-
- server_thread_->Pause();
- QuicSpdySession* server_session = GetServerSession();
- EXPECT_TRUE(server_session->GetWebTransportSession(web_transport->id()) !=
- nullptr);
- server_thread_->Resume();
-}
-
-TEST_P(EndToEndTest, WebTransportSessionUnidirectionalStream) {
- enable_web_transport_ = true;
- ASSERT_TRUE(Initialize());
-
- if (!version_.UsesHttp3()) {
- return;
- }
-
- WebTransportHttp3* session =
- CreateWebTransportSession("/echo", /*wait_for_server_response=*/true);
- ASSERT_TRUE(session != nullptr);
- NiceMock<MockClientVisitor>& visitor = SetupWebTransportVisitor(session);
-
- WebTransportStream* outgoing_stream =
- session->OpenOutgoingUnidirectionalStream();
- ASSERT_TRUE(outgoing_stream != nullptr);
-
- auto stream_visitor = std::make_unique<NiceMock<MockStreamVisitor>>();
- bool data_acknowledged = false;
- EXPECT_CALL(*stream_visitor, OnWriteSideInDataRecvdState())
- .WillOnce(Assign(&data_acknowledged, true));
- outgoing_stream->SetVisitor(std::move(stream_visitor));
-
- EXPECT_TRUE(outgoing_stream->Write("test"));
- EXPECT_TRUE(outgoing_stream->SendFin());
-
- bool stream_received = false;
- EXPECT_CALL(visitor, OnIncomingUnidirectionalStreamAvailable())
- .WillOnce(Assign(&stream_received, true));
- client_->WaitUntil(2000, [&stream_received]() { return stream_received; });
- EXPECT_TRUE(stream_received);
- WebTransportStream* received_stream =
- session->AcceptIncomingUnidirectionalStream();
- ASSERT_TRUE(received_stream != nullptr);
- std::string received_data;
- WebTransportStream::ReadResult result = received_stream->Read(&received_data);
- EXPECT_EQ(received_data, "test");
- EXPECT_TRUE(result.fin);
-
- client_->WaitUntil(2000,
- [&data_acknowledged]() { return data_acknowledged; });
- EXPECT_TRUE(data_acknowledged);
-}
-
-TEST_P(EndToEndTest, WebTransportSessionUnidirectionalStreamSentEarly) {
- enable_web_transport_ = true;
- SetPacketLossPercentage(30);
- ASSERT_TRUE(Initialize());
-
- if (!version_.UsesHttp3()) {
- return;
- }
-
- WebTransportHttp3* session =
- CreateWebTransportSession("/echo", /*wait_for_server_response=*/false);
- ASSERT_TRUE(session != nullptr);
- NiceMock<MockClientVisitor>& visitor = SetupWebTransportVisitor(session);
-
- WebTransportStream* outgoing_stream =
- session->OpenOutgoingUnidirectionalStream();
- ASSERT_TRUE(outgoing_stream != nullptr);
- EXPECT_TRUE(outgoing_stream->Write("test"));
- EXPECT_TRUE(outgoing_stream->SendFin());
-
- bool stream_received = false;
- EXPECT_CALL(visitor, OnIncomingUnidirectionalStreamAvailable())
- .WillOnce(Assign(&stream_received, true));
- client_->WaitUntil(5000, [&stream_received]() { return stream_received; });
- EXPECT_TRUE(stream_received);
- WebTransportStream* received_stream =
- session->AcceptIncomingUnidirectionalStream();
- ASSERT_TRUE(received_stream != nullptr);
- std::string received_data;
- WebTransportStream::ReadResult result = received_stream->Read(&received_data);
- EXPECT_EQ(received_data, "test");
- EXPECT_TRUE(result.fin);
-}
-
-TEST_P(EndToEndTest, WebTransportSessionBidirectionalStream) {
- enable_web_transport_ = true;
- ASSERT_TRUE(Initialize());
-
- if (!version_.UsesHttp3()) {
- return;
- }
-
- WebTransportHttp3* session =
- CreateWebTransportSession("/echo", /*wait_for_server_response=*/true);
- ASSERT_TRUE(session != nullptr);
-
- WebTransportStream* stream = session->OpenOutgoingBidirectionalStream();
- ASSERT_TRUE(stream != nullptr);
-
- auto stream_visitor_owned = std::make_unique<NiceMock<MockStreamVisitor>>();
- MockStreamVisitor* stream_visitor = stream_visitor_owned.get();
- bool data_acknowledged = false;
- EXPECT_CALL(*stream_visitor, OnWriteSideInDataRecvdState())
- .WillOnce(Assign(&data_acknowledged, true));
- stream->SetVisitor(std::move(stream_visitor_owned));
-
- EXPECT_TRUE(stream->Write("test"));
- EXPECT_TRUE(stream->SendFin());
-
- std::string received_data =
- ReadDataFromWebTransportStreamUntilFin(stream, stream_visitor);
- EXPECT_EQ(received_data, "test");
-
- client_->WaitUntil(2000,
- [&data_acknowledged]() { return data_acknowledged; });
- EXPECT_TRUE(data_acknowledged);
-}
-
-TEST_P(EndToEndTest, WebTransportSessionBidirectionalStreamWithBuffering) {
- enable_web_transport_ = true;
- SetPacketLossPercentage(30);
- ASSERT_TRUE(Initialize());
-
- if (!version_.UsesHttp3()) {
- return;
- }
-
- WebTransportHttp3* session =
- CreateWebTransportSession("/echo", /*wait_for_server_response=*/false);
- ASSERT_TRUE(session != nullptr);
-
- WebTransportStream* stream = session->OpenOutgoingBidirectionalStream();
- ASSERT_TRUE(stream != nullptr);
- EXPECT_TRUE(stream->Write("test"));
- EXPECT_TRUE(stream->SendFin());
-
- std::string received_data = ReadDataFromWebTransportStreamUntilFin(stream);
- EXPECT_EQ(received_data, "test");
-}
-
-TEST_P(EndToEndTest, WebTransportSessionServerBidirectionalStream) {
- enable_web_transport_ = true;
- ASSERT_TRUE(Initialize());
-
- if (!version_.UsesHttp3()) {
- return;
- }
-
- WebTransportHttp3* session =
- CreateWebTransportSession("/echo", /*wait_for_server_response=*/false);
- ASSERT_TRUE(session != nullptr);
- NiceMock<MockClientVisitor>& visitor = SetupWebTransportVisitor(session);
-
- bool stream_received = false;
- EXPECT_CALL(visitor, OnIncomingBidirectionalStreamAvailable())
- .WillOnce(Assign(&stream_received, true));
- client_->WaitUntil(5000, [&stream_received]() { return stream_received; });
- EXPECT_TRUE(stream_received);
-
- WebTransportStream* stream = session->AcceptIncomingBidirectionalStream();
- ASSERT_TRUE(stream != nullptr);
- EXPECT_TRUE(stream->Write("test"));
- EXPECT_TRUE(stream->SendFin());
-
- std::string received_data = ReadDataFromWebTransportStreamUntilFin(stream);
- EXPECT_EQ(received_data, "test");
-}
-
-TEST_P(EndToEndTest, WebTransportDatagrams) {
- enable_web_transport_ = true;
- ASSERT_TRUE(Initialize());
-
- if (!version_.UsesHttp3()) {
- return;
- }
-
- WebTransportHttp3* session =
- CreateWebTransportSession("/echo", /*wait_for_server_response=*/true);
- ASSERT_TRUE(session != nullptr);
- NiceMock<MockClientVisitor>& visitor = SetupWebTransportVisitor(session);
-
- 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);
-}
-
-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<MockClientVisitor>& visitor = SetupWebTransportVisitor(session);
-
- 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());
-
- if (!version_.UsesHttp3()) {
- return;
- }
-
- WebTransportHttp3* session =
- CreateWebTransportSession("/echo", /*wait_for_server_response=*/true);
- ASSERT_TRUE(session != nullptr);
- NiceMock<MockClientVisitor>& visitor = SetupWebTransportVisitor(session);
-
- WebTransportStream* stream = session->OpenOutgoingBidirectionalStream();
- ASSERT_TRUE(stream != nullptr);
- QuicStreamId stream_id = stream->GetStreamId();
- EXPECT_TRUE(stream->Write("test"));
- // Keep stream open.
-
- bool close_received = false;
- EXPECT_CALL(visitor, OnSessionClosed(42, "test error"))
- .WillOnce(Assign(&close_received, true));
- session->CloseSession(42, "test error");
- client_->WaitUntil(2000, [&]() { return close_received; });
- EXPECT_TRUE(close_received);
-
- QuicSpdyStream* spdy_stream =
- GetClientSession()->GetOrCreateSpdyDataStream(stream_id);
- EXPECT_TRUE(spdy_stream == nullptr);
-}
-
-TEST_P(EndToEndTest, WebTransportSessionCloseWithoutCapsule) {
- enable_web_transport_ = true;
- ASSERT_TRUE(Initialize());
-
- if (!version_.UsesHttp3()) {
- return;
- }
-
- WebTransportHttp3* session =
- CreateWebTransportSession("/echo", /*wait_for_server_response=*/true);
- ASSERT_TRUE(session != nullptr);
- NiceMock<MockClientVisitor>& visitor = SetupWebTransportVisitor(session);
-
- WebTransportStream* stream = session->OpenOutgoingBidirectionalStream();
- ASSERT_TRUE(stream != nullptr);
- QuicStreamId stream_id = stream->GetStreamId();
- EXPECT_TRUE(stream->Write("test"));
- // Keep stream open.
-
- bool close_received = false;
- EXPECT_CALL(visitor, OnSessionClosed(0, ""))
- .WillOnce(Assign(&close_received, true));
- session->CloseSessionWithFinOnlyForTests();
- client_->WaitUntil(2000, [&]() { return close_received; });
- EXPECT_TRUE(close_received);
-
- QuicSpdyStream* spdy_stream =
- GetClientSession()->GetOrCreateSpdyDataStream(stream_id);
- EXPECT_TRUE(spdy_stream == nullptr);
-}
-
-TEST_P(EndToEndTest, WebTransportSessionReceiveClose) {
- enable_web_transport_ = true;
- ASSERT_TRUE(Initialize());
-
- if (!version_.UsesHttp3()) {
- return;
- }
-
- WebTransportHttp3* session = CreateWebTransportSession(
- "/session-close", /*wait_for_server_response=*/true);
- ASSERT_TRUE(session != nullptr);
- NiceMock<MockClientVisitor>& visitor = SetupWebTransportVisitor(session);
-
- WebTransportStream* stream = session->OpenOutgoingUnidirectionalStream();
- ASSERT_TRUE(stream != nullptr);
- QuicStreamId stream_id = stream->GetStreamId();
- EXPECT_TRUE(stream->Write("42 test error"));
- EXPECT_TRUE(stream->SendFin());
-
- // Have some other streams open pending, to ensure they are closed properly.
- stream = session->OpenOutgoingUnidirectionalStream();
- stream = session->OpenOutgoingBidirectionalStream();
-
- bool close_received = false;
- EXPECT_CALL(visitor, OnSessionClosed(42, "test error"))
- .WillOnce(Assign(&close_received, true));
- client_->WaitUntil(2000, [&]() { return close_received; });
- EXPECT_TRUE(close_received);
-
- QuicSpdyStream* spdy_stream =
- GetClientSession()->GetOrCreateSpdyDataStream(stream_id);
- EXPECT_TRUE(spdy_stream == nullptr);
-}
-
-TEST_P(EndToEndTest, WebTransportSessionStreamTermination) {
- enable_web_transport_ = true;
- ASSERT_TRUE(Initialize());
-
- if (!version_.UsesHttp3()) {
- return;
- }
-
- WebTransportHttp3* session =
- CreateWebTransportSession("/resets", /*wait_for_server_response=*/true);
- ASSERT_TRUE(session != nullptr);
-
- NiceMock<MockClientVisitor>& visitor = SetupWebTransportVisitor(session);
- EXPECT_CALL(visitor, OnIncomingUnidirectionalStreamAvailable())
- .WillRepeatedly([this, session]() {
- ReadAllIncomingWebTransportUnidirectionalStreams(session);
- });
-
- WebTransportStream* stream = session->OpenOutgoingBidirectionalStream();
- QuicStreamId id1 = stream->GetStreamId();
- ASSERT_TRUE(stream != nullptr);
- EXPECT_TRUE(stream->Write("test"));
- stream->ResetWithUserCode(42);
-
- // This read fails if the stream is closed in both directions, since that
- // results in stream object being deleted.
- std::string received_data = ReadDataFromWebTransportStreamUntilFin(stream);
- EXPECT_LE(received_data.size(), 4u);
-
- stream = session->OpenOutgoingBidirectionalStream();
- QuicStreamId id2 = stream->GetStreamId();
- ASSERT_TRUE(stream != nullptr);
- EXPECT_TRUE(stream->Write("test"));
- stream->SendStopSending(24);
-
- std::array<std::string, 2> expected_log = {
- absl::StrCat("Received reset for stream ", id1, " with error code 42"),
- absl::StrCat("Received stop sending for stream ", id2,
- " with error code 24"),
- };
- client_->WaitUntil(2000, [this, &expected_log]() {
- return received_webtransport_unidirectional_streams_.size() >=
- expected_log.size();
- });
- EXPECT_THAT(received_webtransport_unidirectional_streams_,
- UnorderedElementsAreArray(expected_log));
-
- // Since we closed the read side, cleanly closing the write side should result
- // in the stream getting deleted.
- ASSERT_TRUE(GetClientSession()->GetOrCreateSpdyDataStream(id2) != nullptr);
- EXPECT_TRUE(stream->SendFin());
- EXPECT_TRUE(client_->WaitUntil(2000, [this, id2]() {
- return GetClientSession()->GetOrCreateSpdyDataStream(id2) == nullptr;
- }));
-}
-
-TEST_P(EndToEndTest, WebTransportSession404) {
- enable_web_transport_ = true;
- ASSERT_TRUE(Initialize());
-
- if (!version_.UsesHttp3()) {
- return;
- }
-
- WebTransportHttp3* session = CreateWebTransportSession(
- "/does-not-exist", /*wait_for_server_response=*/false);
- ASSERT_TRUE(session != nullptr);
- QuicSpdyStream* connect_stream = client_->latest_created_stream();
- QuicStreamId connect_stream_id = connect_stream->id();
-
- WebTransportStream* stream = session->OpenOutgoingBidirectionalStream();
- ASSERT_TRUE(stream != nullptr);
- EXPECT_TRUE(stream->Write("test"));
- EXPECT_TRUE(stream->SendFin());
-
- EXPECT_TRUE(client_->WaitUntil(-1, [this, connect_stream_id]() {
- return GetClientSession()->GetOrCreateSpdyDataStream(connect_stream_id) ==
- nullptr;
- }));
-}
-
-TEST_P(EndToEndTest, InvalidExtendedConnect) {
- SetQuicReloadableFlag(quic_verify_request_headers_2, true);
- SetQuicReloadableFlag(quic_act_upon_invalid_header, true);
- ASSERT_TRUE(Initialize());
-
- if (!version_.UsesHttp3()) {
- return;
- }
- // Missing :path header.
- spdy::SpdyHeaderBlock headers;
- headers[":scheme"] = "https";
- headers[":authority"] = "localhost";
- headers[":method"] = "CONNECT";
- headers[":protocol"] = "webtransport";
-
- client_->SendMessage(headers, "", /*fin=*/false);
- client_->WaitForResponse();
- // An early response should be received.
- CheckResponseHeaders("400");
-}
-
-TEST_P(EndToEndTest, RejectExtendedConnect) {
- SetQuicReloadableFlag(quic_verify_request_headers_2, true);
- SetQuicReloadableFlag(quic_act_upon_invalid_header, true);
- // Disable extended CONNECT.
- memory_cache_backend_.set_enable_extended_connect(false);
- ASSERT_TRUE(Initialize());
-
- if (!version_.UsesHttp3()) {
- return;
- }
- // This extended CONNECT should be rejected.
- spdy::SpdyHeaderBlock headers;
- headers[":scheme"] = "https";
- headers[":authority"] = "localhost";
- headers[":method"] = "CONNECT";
- headers[":path"] = "/echo";
- headers[":protocol"] = "webtransport";
-
- client_->SendMessage(headers, "", /*fin=*/false);
- client_->WaitForResponse();
- CheckResponseHeaders("400");
-
- // Vanilla CONNECT should be accepted.
- spdy::SpdyHeaderBlock headers2;
- headers2[":authority"] = "localhost";
- headers2[":method"] = "CONNECT";
-
- client_->SendMessage(headers2, "body", /*fin=*/true);
- client_->WaitForResponse();
- // No :path header, so 404.
- CheckResponseHeaders("404");
-}
-
-TEST_P(EndToEndTest, RejectInvalidRequestHeader) {
- SetQuicReloadableFlag(quic_verify_request_headers_2, true);
- SetQuicReloadableFlag(quic_act_upon_invalid_header, true);
- ASSERT_TRUE(Initialize());
-
- spdy::SpdyHeaderBlock headers;
- headers[":scheme"] = "https";
- headers[":authority"] = "localhost";
- headers[":method"] = "GET";
- headers[":path"] = "/echo";
- // transfer-encoding header is not allowed.
- headers["transfer-encoding"] = "chunk";
-
- client_->SendMessage(headers, "", /*fin=*/false);
- client_->WaitForResponse();
- CheckResponseHeaders("400");
-}
-
-TEST_P(EndToEndTest, RejectTransferEncodingResponse) {
- SetQuicReloadableFlag(quic_verify_request_headers_2, true);
- SetQuicReloadableFlag(quic_act_upon_invalid_header, true);
- ASSERT_TRUE(Initialize());
-
- // Add a response with transfer-encoding headers.
- SpdyHeaderBlock headers;
- headers[":status"] = "200";
- headers["transfer-encoding"] = "gzip";
-
- SpdyHeaderBlock trailers;
- trailers["some-trailing-header"] = "trailing-header-value";
-
- memory_cache_backend_.AddResponse(server_hostname_, "/eep",
- std::move(headers), "", trailers.Clone());
-
- std::string received_response = client_->SendSynchronousRequest("/eep");
- EXPECT_THAT(client_->stream_error(),
- IsStreamError(QUIC_BAD_APPLICATION_PAYLOAD));
-}
-
-TEST_P(EndToEndTest, RejectUpperCaseRequest) {
- SetQuicReloadableFlag(quic_verify_request_headers_2, true);
- SetQuicReloadableFlag(quic_act_upon_invalid_header, true);
- ASSERT_TRUE(Initialize());
-
- spdy::SpdyHeaderBlock headers;
- headers[":scheme"] = "https";
- headers[":authority"] = "localhost";
- headers[":method"] = "GET";
- headers[":path"] = "/echo";
- headers["UpperCaseHeader"] = "foo";
-
- client_->SendMessage(headers, "", /*fin=*/false);
- client_->WaitForResponse();
- CheckResponseHeaders("400");
-}
-
-TEST_P(EndToEndTest, RejectRequestWithInvalidToken) {
- SetQuicReloadableFlag(quic_verify_request_headers_2, true);
- SetQuicReloadableFlag(quic_act_upon_invalid_header, true);
- ASSERT_TRUE(Initialize());
-
- spdy::SpdyHeaderBlock headers;
- headers[":scheme"] = "https";
- headers[":authority"] = "localhost";
- headers[":method"] = "GET";
- headers[":path"] = "/echo";
- headers["invalid,header"] = "foo";
-
- client_->SendMessage(headers, "", /*fin=*/false);
- client_->WaitForResponse();
- CheckResponseHeaders("400");
-}
-
-} // namespace
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/http/http_constants.cc b/chromium/net/third_party/quiche/src/quic/core/http/http_constants.cc
deleted file mode 100644
index 94d42fe23ed..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/http/http_constants.cc
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright (c) 2021 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 "quic/core/http/http_constants.h"
-
-#include "absl/strings/str_cat.h"
-
-namespace quic {
-
-#define RETURN_STRING_LITERAL(x) \
- case x: \
- return #x;
-
-std::string H3SettingsToString(Http3AndQpackSettingsIdentifiers identifier) {
- switch (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_WEBTRANS_DRAFT00);
- RETURN_STRING_LITERAL(SETTINGS_ENABLE_CONNECT_PROTOCOL);
- }
- return absl::StrCat("UNSUPPORTED_SETTINGS_TYPE(", identifier, ")");
-}
-
-const absl::string_view kUserAgentHeaderName = "user-agent";
-
-#undef RETURN_STRING_LITERAL // undef for jumbo builds
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/http/http_constants.h b/chromium/net/third_party/quiche/src/quic/core/http/http_constants.h
deleted file mode 100644
index 213b7d90c59..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/http/http_constants.h
+++ /dev/null
@@ -1,76 +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_CORE_HTTP_HTTP_CONSTANTS_H_
-#define QUICHE_QUIC_CORE_HTTP_HTTP_CONSTANTS_H_
-
-#include <cstdint>
-#include <string>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// Unidirectional stream types.
-enum : uint64_t {
- // https://quicwg.org/base-drafts/draft-ietf-quic-http.html#unidirectional-streams
- kControlStream = 0x00,
- kServerPushStream = 0x01,
- // https://quicwg.org/base-drafts/draft-ietf-quic-qpack.html#enc-dec-stream-def
- kQpackEncoderStream = 0x02,
- kQpackDecoderStream = 0x03,
- // https://ietf-wg-webtrans.github.io/draft-ietf-webtrans-http3/draft-ietf-webtrans-http3.html#name-unidirectional-streams
- kWebTransportUnidirectionalStream = 0x54,
-};
-
-// This includes control stream, QPACK encoder stream, and QPACK decoder stream.
-enum : QuicStreamCount { kHttp3StaticUnidirectionalStreamCount = 3 };
-
-// HTTP/3 and QPACK settings identifiers.
-// https://quicwg.org/base-drafts/draft-ietf-quic-http.html#settings-parameters
-// https://quicwg.org/base-drafts/draft-ietf-quic-qpack.html#configuration
-enum Http3AndQpackSettingsIdentifiers : uint64_t {
- // Same value as spdy::SETTINGS_HEADER_TABLE_SIZE.
- SETTINGS_QPACK_MAX_TABLE_CAPACITY = 0x01,
- // 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-webtrans-http3-00
- SETTINGS_WEBTRANS_DRAFT00 = 0x2b603742,
- // draft-ietf-httpbis-h3-websockets
- SETTINGS_ENABLE_CONNECT_PROTOCOL = 0x08,
-};
-
-// Returns HTTP/3 SETTINGS identifier as a string.
-QUIC_EXPORT std::string H3SettingsToString(
- Http3AndQpackSettingsIdentifiers identifier);
-
-// Default maximum dynamic table capacity, communicated via
-// SETTINGS_QPACK_MAX_TABLE_CAPACITY.
-enum : QuicByteCount {
- kDefaultQpackMaxDynamicTableCapacity = 64 * 1024 // 64 KB
-};
-
-// Default limit on the size of uncompressed headers,
-// communicated via SETTINGS_MAX_HEADER_LIST_SIZE.
-enum : QuicByteCount {
- kDefaultMaxUncompressedHeaderSize = 16 * 1024 // 16 KB
-};
-
-// Default limit on number of blocked streams, communicated via
-// SETTINGS_QPACK_BLOCKED_STREAMS.
-enum : uint64_t { kDefaultMaximumBlockedStreams = 100 };
-
-ABSL_CONST_INIT QUIC_EXPORT_PRIVATE extern const absl::string_view
- kUserAgentHeaderName;
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_HTTP_HTTP_CONSTANTS_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/http/http_decoder.cc b/chromium/net/third_party/quiche/src/quic/core/http/http_decoder.cc
deleted file mode 100644
index 02aa123ed7a..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/http/http_decoder.cc
+++ /dev/null
@@ -1,674 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/http/http_decoder.h"
-
-#include <cstdint>
-
-#include "absl/base/attributes.h"
-#include "absl/strings/string_view.h"
-#include "http2/http2_constants.h"
-#include "quic/core/http/http_frames.h"
-#include "quic/core/quic_data_reader.h"
-#include "quic/core/quic_error_codes.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_flag_utils.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-namespace {
-
-// Limit on the payload length for frames that are buffered by HttpDecoder.
-// If a frame header indicating a payload length exceeding this limit is
-// received, HttpDecoder closes the connection. Does not apply to frames that
-// are not buffered here but each payload fragment is immediately passed to
-// Visitor, like HEADERS, DATA, and unknown frames.
-constexpr QuicByteCount kPayloadLengthLimit = 1024 * 1024;
-
-} // anonymous namespace
-
-HttpDecoder::HttpDecoder(Visitor* visitor) : HttpDecoder(visitor, Options()) {}
-HttpDecoder::HttpDecoder(Visitor* visitor, Options options)
- : visitor_(visitor),
- allow_web_transport_stream_(options.allow_web_transport_stream),
- state_(STATE_READING_FRAME_TYPE),
- current_frame_type_(0),
- current_length_field_length_(0),
- remaining_length_field_length_(0),
- current_frame_length_(0),
- remaining_frame_length_(0),
- current_type_field_length_(0),
- remaining_type_field_length_(0),
- error_(QUIC_NO_ERROR),
- error_detail_("") {
- QUICHE_DCHECK(visitor_);
-}
-
-HttpDecoder::~HttpDecoder() {}
-
-// static
-bool HttpDecoder::DecodeSettings(const char* data,
- QuicByteCount len,
- SettingsFrame* frame) {
- QuicDataReader reader(data, len);
- uint64_t frame_type;
- if (!reader.ReadVarInt62(&frame_type)) {
- QUIC_DLOG(ERROR) << "Unable to read frame type.";
- return false;
- }
-
- if (frame_type != static_cast<uint64_t>(HttpFrameType::SETTINGS)) {
- QUIC_DLOG(ERROR) << "Invalid frame type " << frame_type;
- return false;
- }
-
- absl::string_view frame_contents;
- if (!reader.ReadStringPieceVarInt62(&frame_contents)) {
- QUIC_DLOG(ERROR) << "Failed to read SETTINGS frame contents";
- return false;
- }
-
- QuicDataReader frame_reader(frame_contents);
-
- while (!frame_reader.IsDoneReading()) {
- uint64_t id;
- if (!frame_reader.ReadVarInt62(&id)) {
- QUIC_DLOG(ERROR) << "Unable to read setting identifier.";
- return false;
- }
- uint64_t content;
- if (!frame_reader.ReadVarInt62(&content)) {
- QUIC_DLOG(ERROR) << "Unable to read setting value.";
- return false;
- }
- auto result = frame->values.insert({id, content});
- if (!result.second) {
- QUIC_DLOG(ERROR) << "Duplicate setting identifier.";
- return false;
- }
- }
- return true;
-}
-
-QuicByteCount HttpDecoder::ProcessInput(const char* data, QuicByteCount len) {
- QUICHE_DCHECK_EQ(QUIC_NO_ERROR, error_);
- QUICHE_DCHECK_NE(STATE_ERROR, state_);
-
- QuicDataReader reader(data, len);
- bool continue_processing = true;
- // BufferOrParsePayload() and FinishParsing() may need to be called even if
- // there is no more data so that they can finish processing the current frame.
- while (continue_processing && (reader.BytesRemaining() != 0 ||
- state_ == STATE_BUFFER_OR_PARSE_PAYLOAD ||
- state_ == STATE_FINISH_PARSING)) {
- // |continue_processing| must have been set to false upon error.
- QUICHE_DCHECK_EQ(QUIC_NO_ERROR, error_);
- QUICHE_DCHECK_NE(STATE_ERROR, state_);
-
- switch (state_) {
- case STATE_READING_FRAME_TYPE:
- continue_processing = ReadFrameType(&reader);
- break;
- case STATE_READING_FRAME_LENGTH:
- continue_processing = ReadFrameLength(&reader);
- break;
- case STATE_BUFFER_OR_PARSE_PAYLOAD:
- continue_processing = BufferOrParsePayload(&reader);
- break;
- case STATE_READING_FRAME_PAYLOAD:
- continue_processing = ReadFramePayload(&reader);
- break;
- case STATE_FINISH_PARSING:
- continue_processing = FinishParsing();
- break;
- case STATE_PARSING_NO_LONGER_POSSIBLE:
- continue_processing = false;
- QUIC_BUG(HttpDecoder PARSING_NO_LONGER_POSSIBLE)
- << "HttpDecoder called after an indefinite-length frame has been "
- "received";
- RaiseError(QUIC_INTERNAL_ERROR,
- "HttpDecoder called after an indefinite-length frame has "
- "been received");
- break;
- case STATE_ERROR:
- break;
- default:
- QUIC_BUG(quic_bug_10411_1) << "Invalid state: " << state_;
- }
- }
-
- return len - reader.BytesRemaining();
-}
-
-bool HttpDecoder::ReadFrameType(QuicDataReader* reader) {
- QUICHE_DCHECK_NE(0u, reader->BytesRemaining());
- if (current_type_field_length_ == 0) {
- // A new frame is coming.
- current_type_field_length_ = reader->PeekVarInt62Length();
- QUICHE_DCHECK_NE(0u, current_type_field_length_);
- if (current_type_field_length_ > reader->BytesRemaining()) {
- // Buffer a new type field.
- remaining_type_field_length_ = current_type_field_length_;
- BufferFrameType(reader);
- return true;
- }
- // The reader has all type data needed, so no need to buffer.
- bool success = reader->ReadVarInt62(&current_frame_type_);
- QUICHE_DCHECK(success);
- } else {
- // Buffer the existing type field.
- BufferFrameType(reader);
- // The frame is still not buffered completely.
- if (remaining_type_field_length_ != 0) {
- return true;
- }
- QuicDataReader type_reader(type_buffer_.data(), current_type_field_length_);
- bool success = type_reader.ReadVarInt62(&current_frame_type_);
- QUICHE_DCHECK(success);
- }
-
- // https://tools.ietf.org/html/draft-ietf-quic-http-31#section-7.2.8
- // specifies that the following frames are treated as errors.
- if (current_frame_type_ ==
- static_cast<uint64_t>(http2::Http2FrameType::PRIORITY) ||
- current_frame_type_ ==
- static_cast<uint64_t>(http2::Http2FrameType::PING) ||
- current_frame_type_ ==
- static_cast<uint64_t>(http2::Http2FrameType::WINDOW_UPDATE) ||
- current_frame_type_ ==
- static_cast<uint64_t>(http2::Http2FrameType::CONTINUATION)) {
- RaiseError(QUIC_HTTP_RECEIVE_SPDY_FRAME,
- absl::StrCat("HTTP/2 frame received in a HTTP/3 connection: ",
- current_frame_type_));
- return false;
- }
-
- if (current_frame_type_ ==
- static_cast<uint64_t>(HttpFrameType::CANCEL_PUSH)) {
- RaiseError(QUIC_HTTP_FRAME_ERROR, "CANCEL_PUSH frame received.");
- return false;
- }
- if (current_frame_type_ ==
- static_cast<uint64_t>(HttpFrameType::PUSH_PROMISE)) {
- RaiseError(QUIC_HTTP_FRAME_ERROR, "PUSH_PROMISE frame received.");
- return false;
- }
-
- state_ = STATE_READING_FRAME_LENGTH;
- return true;
-}
-
-bool HttpDecoder::ReadFrameLength(QuicDataReader* reader) {
- QUICHE_DCHECK_NE(0u, reader->BytesRemaining());
- if (current_length_field_length_ == 0) {
- // A new frame is coming.
- current_length_field_length_ = reader->PeekVarInt62Length();
- QUICHE_DCHECK_NE(0u, current_length_field_length_);
- if (current_length_field_length_ > reader->BytesRemaining()) {
- // Buffer a new length field.
- remaining_length_field_length_ = current_length_field_length_;
- BufferFrameLength(reader);
- return true;
- }
- // The reader has all length data needed, so no need to buffer.
- bool success = reader->ReadVarInt62(&current_frame_length_);
- QUICHE_DCHECK(success);
- } else {
- // Buffer the existing length field.
- BufferFrameLength(reader);
- // The frame is still not buffered completely.
- if (remaining_length_field_length_ != 0) {
- return true;
- }
- QuicDataReader length_reader(length_buffer_.data(),
- current_length_field_length_);
- bool success = length_reader.ReadVarInt62(&current_frame_length_);
- QUICHE_DCHECK(success);
- }
-
- // WEBTRANSPORT_STREAM frames are indefinitely long, and thus require
- // special handling; the number after the frame type is actually the
- // WebTransport session ID, and not the length.
- if (allow_web_transport_stream_ &&
- current_frame_type_ ==
- static_cast<uint64_t>(HttpFrameType::WEBTRANSPORT_STREAM)) {
- visitor_->OnWebTransportStreamFrameType(
- current_length_field_length_ + current_type_field_length_,
- current_frame_length_);
- state_ = STATE_PARSING_NO_LONGER_POSSIBLE;
- return false;
- }
-
- if (IsFrameBuffered() &&
- current_frame_length_ > MaxFrameLength(current_frame_type_)) {
- RaiseError(QUIC_HTTP_FRAME_TOO_LARGE, "Frame is too large.");
- return false;
- }
-
- // Calling the following visitor methods does not require parsing of any
- // frame payload.
- bool continue_processing = true;
- const QuicByteCount header_length =
- current_length_field_length_ + current_type_field_length_;
-
- switch (current_frame_type_) {
- case static_cast<uint64_t>(HttpFrameType::DATA):
- continue_processing =
- visitor_->OnDataFrameStart(header_length, current_frame_length_);
- break;
- case static_cast<uint64_t>(HttpFrameType::HEADERS):
- continue_processing =
- visitor_->OnHeadersFrameStart(header_length, current_frame_length_);
- break;
- case static_cast<uint64_t>(HttpFrameType::CANCEL_PUSH):
- QUICHE_NOTREACHED();
- break;
- case static_cast<uint64_t>(HttpFrameType::SETTINGS):
- continue_processing = visitor_->OnSettingsFrameStart(header_length);
- break;
- case static_cast<uint64_t>(HttpFrameType::PUSH_PROMISE):
- QUICHE_NOTREACHED();
- break;
- case static_cast<uint64_t>(HttpFrameType::GOAWAY):
- break;
- case static_cast<uint64_t>(HttpFrameType::MAX_PUSH_ID):
- break;
- case static_cast<uint64_t>(HttpFrameType::PRIORITY_UPDATE_REQUEST_STREAM):
- continue_processing = visitor_->OnPriorityUpdateFrameStart(header_length);
- break;
- case static_cast<uint64_t>(HttpFrameType::ACCEPT_CH):
- continue_processing = visitor_->OnAcceptChFrameStart(header_length);
- break;
- default:
- continue_processing = visitor_->OnUnknownFrameStart(
- current_frame_type_, header_length, current_frame_length_);
- break;
- }
-
- remaining_frame_length_ = current_frame_length_;
-
- if (IsFrameBuffered()) {
- state_ = STATE_BUFFER_OR_PARSE_PAYLOAD;
- return continue_processing;
- }
-
- state_ = (remaining_frame_length_ == 0) ? STATE_FINISH_PARSING
- : STATE_READING_FRAME_PAYLOAD;
- return continue_processing;
-}
-
-bool HttpDecoder::IsFrameBuffered() {
- switch (current_frame_type_) {
- case static_cast<uint64_t>(HttpFrameType::SETTINGS):
- return true;
- case static_cast<uint64_t>(HttpFrameType::GOAWAY):
- return true;
- case static_cast<uint64_t>(HttpFrameType::MAX_PUSH_ID):
- return true;
- case static_cast<uint64_t>(HttpFrameType::PRIORITY_UPDATE_REQUEST_STREAM):
- return true;
- case static_cast<uint64_t>(HttpFrameType::ACCEPT_CH):
- return true;
- }
-
- // Other defined frame types as well as unknown frames are not buffered.
- return false;
-}
-
-bool HttpDecoder::ReadFramePayload(QuicDataReader* reader) {
- QUICHE_DCHECK(!IsFrameBuffered());
- QUICHE_DCHECK_NE(0u, reader->BytesRemaining());
- QUICHE_DCHECK_NE(0u, remaining_frame_length_);
-
- bool continue_processing = true;
-
- switch (current_frame_type_) {
- case static_cast<uint64_t>(HttpFrameType::DATA): {
- QuicByteCount bytes_to_read = std::min<QuicByteCount>(
- remaining_frame_length_, reader->BytesRemaining());
- absl::string_view payload;
- bool success = reader->ReadStringPiece(&payload, bytes_to_read);
- QUICHE_DCHECK(success);
- QUICHE_DCHECK(!payload.empty());
- continue_processing = visitor_->OnDataFramePayload(payload);
- remaining_frame_length_ -= payload.length();
- break;
- }
- case static_cast<uint64_t>(HttpFrameType::HEADERS): {
- QuicByteCount bytes_to_read = std::min<QuicByteCount>(
- remaining_frame_length_, reader->BytesRemaining());
- absl::string_view payload;
- bool success = reader->ReadStringPiece(&payload, bytes_to_read);
- QUICHE_DCHECK(success);
- QUICHE_DCHECK(!payload.empty());
- continue_processing = visitor_->OnHeadersFramePayload(payload);
- remaining_frame_length_ -= payload.length();
- break;
- }
- case static_cast<uint64_t>(HttpFrameType::CANCEL_PUSH): {
- QUICHE_NOTREACHED();
- break;
- }
- case static_cast<uint64_t>(HttpFrameType::SETTINGS): {
- QUICHE_NOTREACHED();
- break;
- }
- case static_cast<uint64_t>(HttpFrameType::PUSH_PROMISE): {
- QUICHE_NOTREACHED();
- break;
- }
- case static_cast<uint64_t>(HttpFrameType::GOAWAY): {
- QUICHE_NOTREACHED();
- break;
- }
- case static_cast<uint64_t>(HttpFrameType::MAX_PUSH_ID): {
- QUICHE_NOTREACHED();
- break;
- }
- case static_cast<uint64_t>(HttpFrameType::PRIORITY_UPDATE_REQUEST_STREAM): {
- QUICHE_NOTREACHED();
- break;
- }
- case static_cast<uint64_t>(HttpFrameType::ACCEPT_CH): {
- QUICHE_NOTREACHED();
- break;
- }
- default: {
- continue_processing = HandleUnknownFramePayload(reader);
- break;
- }
- }
-
- if (remaining_frame_length_ == 0) {
- state_ = STATE_FINISH_PARSING;
- }
-
- return continue_processing;
-}
-
-bool HttpDecoder::FinishParsing() {
- QUICHE_DCHECK(!IsFrameBuffered());
- QUICHE_DCHECK_EQ(0u, remaining_frame_length_);
-
- bool continue_processing = true;
-
- switch (current_frame_type_) {
- case static_cast<uint64_t>(HttpFrameType::DATA): {
- continue_processing = visitor_->OnDataFrameEnd();
- break;
- }
- case static_cast<uint64_t>(HttpFrameType::HEADERS): {
- continue_processing = visitor_->OnHeadersFrameEnd();
- break;
- }
- case static_cast<uint64_t>(HttpFrameType::CANCEL_PUSH): {
- QUICHE_NOTREACHED();
- break;
- }
- case static_cast<uint64_t>(HttpFrameType::SETTINGS): {
- QUICHE_NOTREACHED();
- break;
- }
- case static_cast<uint64_t>(HttpFrameType::PUSH_PROMISE): {
- QUICHE_NOTREACHED();
- break;
- }
- case static_cast<uint64_t>(HttpFrameType::GOAWAY): {
- QUICHE_NOTREACHED();
- break;
- }
- case static_cast<uint64_t>(HttpFrameType::MAX_PUSH_ID): {
- QUICHE_NOTREACHED();
- break;
- }
- case static_cast<uint64_t>(HttpFrameType::PRIORITY_UPDATE_REQUEST_STREAM): {
- QUICHE_NOTREACHED();
- break;
- }
- case static_cast<uint64_t>(HttpFrameType::ACCEPT_CH): {
- QUICHE_NOTREACHED();
- break;
- }
- default:
- continue_processing = visitor_->OnUnknownFrameEnd();
- }
-
- ResetForNextFrame();
- return continue_processing;
-}
-
-void HttpDecoder::ResetForNextFrame() {
- current_length_field_length_ = 0;
- current_type_field_length_ = 0;
- state_ = STATE_READING_FRAME_TYPE;
-}
-
-bool HttpDecoder::HandleUnknownFramePayload(QuicDataReader* reader) {
- QuicByteCount bytes_to_read = std::min<QuicByteCount>(
- remaining_frame_length_, reader->BytesRemaining());
- absl::string_view payload;
- bool success = reader->ReadStringPiece(&payload, bytes_to_read);
- QUICHE_DCHECK(success);
- QUICHE_DCHECK(!payload.empty());
- remaining_frame_length_ -= payload.length();
- return visitor_->OnUnknownFramePayload(payload);
-}
-
-bool HttpDecoder::BufferOrParsePayload(QuicDataReader* reader) {
- QUICHE_DCHECK(IsFrameBuffered());
- QUICHE_DCHECK_EQ(current_frame_length_,
- buffer_.size() + remaining_frame_length_);
-
- if (buffer_.empty() && reader->BytesRemaining() >= current_frame_length_) {
- // |*reader| contains entire payload, which might be empty.
- remaining_frame_length_ = 0;
- QuicDataReader current_payload_reader(reader->PeekRemainingPayload().data(),
- current_frame_length_);
- bool continue_processing = ParseEntirePayload(&current_payload_reader);
-
- reader->Seek(current_frame_length_);
- ResetForNextFrame();
- return continue_processing;
- }
-
- // Buffer as much of the payload as |*reader| contains.
- QuicByteCount bytes_to_read = std::min<QuicByteCount>(
- remaining_frame_length_, reader->BytesRemaining());
- absl::StrAppend(&buffer_, reader->PeekRemainingPayload().substr(
- /* pos = */ 0, bytes_to_read));
- reader->Seek(bytes_to_read);
- remaining_frame_length_ -= bytes_to_read;
-
- QUICHE_DCHECK_EQ(current_frame_length_,
- buffer_.size() + remaining_frame_length_);
-
- if (remaining_frame_length_ > 0) {
- QUICHE_DCHECK(reader->IsDoneReading());
- return false;
- }
-
- QuicDataReader buffer_reader(buffer_);
- bool continue_processing = ParseEntirePayload(&buffer_reader);
- buffer_.clear();
-
- ResetForNextFrame();
- return continue_processing;
-}
-
-bool HttpDecoder::ParseEntirePayload(QuicDataReader* reader) {
- QUICHE_DCHECK(IsFrameBuffered());
- QUICHE_DCHECK_EQ(current_frame_length_, reader->BytesRemaining());
- QUICHE_DCHECK_EQ(0u, remaining_frame_length_);
-
- switch (current_frame_type_) {
- case static_cast<uint64_t>(HttpFrameType::CANCEL_PUSH): {
- QUICHE_NOTREACHED();
- return false;
- }
- case static_cast<uint64_t>(HttpFrameType::SETTINGS): {
- SettingsFrame frame;
- if (!ParseSettingsFrame(reader, &frame)) {
- return false;
- }
- return visitor_->OnSettingsFrame(frame);
- }
- case static_cast<uint64_t>(HttpFrameType::GOAWAY): {
- GoAwayFrame frame;
- if (!reader->ReadVarInt62(&frame.id)) {
- RaiseError(QUIC_HTTP_FRAME_ERROR, "Unable to read GOAWAY ID.");
- return false;
- }
- if (!reader->IsDoneReading()) {
- RaiseError(QUIC_HTTP_FRAME_ERROR, "Superfluous data in GOAWAY frame.");
- return false;
- }
- return visitor_->OnGoAwayFrame(frame);
- }
- case static_cast<uint64_t>(HttpFrameType::MAX_PUSH_ID): {
- MaxPushIdFrame frame;
- if (!reader->ReadVarInt62(&frame.push_id)) {
- RaiseError(QUIC_HTTP_FRAME_ERROR,
- "Unable to read MAX_PUSH_ID push_id.");
- return false;
- }
- if (!reader->IsDoneReading()) {
- RaiseError(QUIC_HTTP_FRAME_ERROR,
- "Superfluous data in MAX_PUSH_ID frame.");
- return false;
- }
- return visitor_->OnMaxPushIdFrame(frame);
- }
- case static_cast<uint64_t>(HttpFrameType::PRIORITY_UPDATE_REQUEST_STREAM): {
- PriorityUpdateFrame frame;
- if (!ParsePriorityUpdateFrame(reader, &frame)) {
- return false;
- }
- return visitor_->OnPriorityUpdateFrame(frame);
- }
- case static_cast<uint64_t>(HttpFrameType::ACCEPT_CH): {
- AcceptChFrame frame;
- if (!ParseAcceptChFrame(reader, &frame)) {
- return false;
- }
- return visitor_->OnAcceptChFrame(frame);
- }
- default:
- // Only above frame types are parsed by ParseEntirePayload().
- QUICHE_NOTREACHED();
- return false;
- }
-}
-
-void HttpDecoder::BufferFrameLength(QuicDataReader* reader) {
- QuicByteCount bytes_to_read = std::min<QuicByteCount>(
- remaining_length_field_length_, reader->BytesRemaining());
- bool success =
- reader->ReadBytes(length_buffer_.data() + current_length_field_length_ -
- remaining_length_field_length_,
- bytes_to_read);
- QUICHE_DCHECK(success);
- remaining_length_field_length_ -= bytes_to_read;
-}
-
-void HttpDecoder::BufferFrameType(QuicDataReader* reader) {
- QuicByteCount bytes_to_read = std::min<QuicByteCount>(
- remaining_type_field_length_, reader->BytesRemaining());
- bool success =
- reader->ReadBytes(type_buffer_.data() + current_type_field_length_ -
- remaining_type_field_length_,
- bytes_to_read);
- QUICHE_DCHECK(success);
- remaining_type_field_length_ -= bytes_to_read;
-}
-
-void HttpDecoder::RaiseError(QuicErrorCode error, std::string error_detail) {
- state_ = STATE_ERROR;
- error_ = error;
- error_detail_ = std::move(error_detail);
- visitor_->OnError(this);
-}
-
-bool HttpDecoder::ParseSettingsFrame(QuicDataReader* reader,
- SettingsFrame* frame) {
- while (!reader->IsDoneReading()) {
- uint64_t id;
- if (!reader->ReadVarInt62(&id)) {
- RaiseError(QUIC_HTTP_FRAME_ERROR, "Unable to read setting identifier.");
- return false;
- }
- uint64_t content;
- if (!reader->ReadVarInt62(&content)) {
- RaiseError(QUIC_HTTP_FRAME_ERROR, "Unable to read setting value.");
- return false;
- }
- auto result = frame->values.insert({id, content});
- if (!result.second) {
- RaiseError(QUIC_HTTP_DUPLICATE_SETTING_IDENTIFIER,
- "Duplicate setting identifier.");
- return false;
- }
- }
- return true;
-}
-
-bool HttpDecoder::ParsePriorityUpdateFrame(QuicDataReader* reader,
- PriorityUpdateFrame* frame) {
- frame->prioritized_element_type = REQUEST_STREAM;
-
- if (!reader->ReadVarInt62(&frame->prioritized_element_id)) {
- RaiseError(QUIC_HTTP_FRAME_ERROR, "Unable to read prioritized element id.");
- return false;
- }
-
- absl::string_view priority_field_value = reader->ReadRemainingPayload();
- frame->priority_field_value =
- std::string(priority_field_value.data(), priority_field_value.size());
-
- return true;
-}
-
-bool HttpDecoder::ParseAcceptChFrame(QuicDataReader* reader,
- AcceptChFrame* frame) {
- absl::string_view origin;
- absl::string_view value;
- while (!reader->IsDoneReading()) {
- if (!reader->ReadStringPieceVarInt62(&origin)) {
- RaiseError(QUIC_HTTP_FRAME_ERROR, "Unable to read ACCEPT_CH origin.");
- return false;
- }
- if (!reader->ReadStringPieceVarInt62(&value)) {
- RaiseError(QUIC_HTTP_FRAME_ERROR, "Unable to read ACCEPT_CH value.");
- return false;
- }
- // Copy data.
- frame->entries.push_back({std::string(origin.data(), origin.size()),
- std::string(value.data(), value.size())});
- }
- return true;
-}
-
-QuicByteCount HttpDecoder::MaxFrameLength(uint64_t frame_type) {
- QUICHE_DCHECK(IsFrameBuffered());
-
- switch (frame_type) {
- case static_cast<uint64_t>(HttpFrameType::SETTINGS):
- return kPayloadLengthLimit;
- case static_cast<uint64_t>(HttpFrameType::GOAWAY):
- return VARIABLE_LENGTH_INTEGER_LENGTH_8;
- case static_cast<uint64_t>(HttpFrameType::MAX_PUSH_ID):
- return VARIABLE_LENGTH_INTEGER_LENGTH_8;
- case static_cast<uint64_t>(HttpFrameType::PRIORITY_UPDATE_REQUEST_STREAM):
- return kPayloadLengthLimit;
- case static_cast<uint64_t>(HttpFrameType::ACCEPT_CH):
- return kPayloadLengthLimit;
- default:
- QUICHE_NOTREACHED();
- return 0;
- }
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/http/http_decoder.h b/chromium/net/third_party/quiche/src/quic/core/http/http_decoder.h
deleted file mode 100644
index 118fbcf59f5..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/http/http_decoder.h
+++ /dev/null
@@ -1,278 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_HTTP_HTTP_DECODER_H_
-#define QUICHE_QUIC_CORE_HTTP_HTTP_DECODER_H_
-
-#include <cstdint>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/http/http_frames.h"
-#include "quic/core/quic_error_codes.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-namespace test {
-
-class HttpDecoderPeer;
-
-} // namespace test
-
-class QuicDataReader;
-
-// A class for decoding the HTTP frames that are exchanged in an HTTP over QUIC
-// session.
-class QUIC_EXPORT_PRIVATE HttpDecoder {
- public:
- struct QUIC_EXPORT_PRIVATE Options {
- // Indicates that WEBTRANSPORT_STREAM should be parsed.
- bool allow_web_transport_stream = false;
- };
-
- class QUIC_EXPORT_PRIVATE Visitor {
- public:
- virtual ~Visitor() {}
-
- // Called if an error is detected.
- virtual void OnError(HttpDecoder* decoder) = 0;
-
- // All the following methods return true to continue decoding,
- // and false to pause it.
- // On*FrameStart() methods are called after the frame header is completely
- // 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;
-
- // Called when a GOAWAY frame has been successfully parsed.
- virtual bool OnGoAwayFrame(const GoAwayFrame& frame) = 0;
-
- // Called when a SETTINGS frame has been received.
- virtual bool OnSettingsFrameStart(QuicByteCount header_length) = 0;
-
- // Called when a SETTINGS frame has been successfully parsed.
- virtual bool OnSettingsFrame(const SettingsFrame& frame) = 0;
-
- // Called when a DATA frame has been received.
- // |header_length| and |payload_length| are the length of DATA frame header
- // and payload, respectively.
- virtual bool OnDataFrameStart(QuicByteCount header_length,
- QuicByteCount payload_length) = 0;
- // Called when part of the payload of a DATA frame has been read. May be
- // called multiple times for a single frame. |payload| is guaranteed to be
- // non-empty.
- virtual bool OnDataFramePayload(absl::string_view payload) = 0;
- // Called when a DATA frame has been completely processed.
- virtual bool OnDataFrameEnd() = 0;
-
- // Called when a HEADERS frame has been received.
- // |header_length| and |payload_length| are the length of HEADERS frame
- // header and payload, respectively.
- virtual bool OnHeadersFrameStart(QuicByteCount header_length,
- QuicByteCount payload_length) = 0;
- // Called when part of the payload of a HEADERS frame has been read. May be
- // called multiple times for a single frame. |payload| is guaranteed to be
- // non-empty.
- virtual bool OnHeadersFramePayload(absl::string_view payload) = 0;
- // Called when a HEADERS frame has been completely processed.
- virtual bool OnHeadersFrameEnd() = 0;
-
- // Called when a PRIORITY_UPDATE frame has been received.
- // |header_length| contains PRIORITY_UPDATE frame length and payload length.
- virtual bool OnPriorityUpdateFrameStart(QuicByteCount header_length) = 0;
-
- // Called when a PRIORITY_UPDATE frame has been successfully parsed.
- virtual bool OnPriorityUpdateFrame(const PriorityUpdateFrame& frame) = 0;
-
- // Called when an ACCEPT_CH frame has been received.
- // |header_length| contains ACCEPT_CH frame length and payload length.
- virtual bool OnAcceptChFrameStart(QuicByteCount header_length) = 0;
-
- // Called when an ACCEPT_CH frame has been successfully parsed.
- virtual bool OnAcceptChFrame(const AcceptChFrame& frame) = 0;
-
- // Called when a WEBTRANSPORT_STREAM frame type and the session ID varint
- // immediately following it has been received. Any further parsing should
- // be done by the stream itself, and not the parser. Note that this does not
- // return bool, because WEBTRANSPORT_STREAM always causes the parsing
- // process to cease.
- virtual void OnWebTransportStreamFrameType(
- QuicByteCount header_length,
- WebTransportSessionId session_id) = 0;
-
- // Called when a frame of unknown type |frame_type| has been received.
- // Frame type might be reserved, Visitor must make sure to ignore.
- // |header_length| and |payload_length| are the length of the frame header
- // and payload, respectively.
- virtual bool OnUnknownFrameStart(uint64_t frame_type,
- QuicByteCount header_length,
- QuicByteCount payload_length) = 0;
- // Called when part of the payload of the unknown frame has been read. May
- // be called multiple times for a single frame. |payload| is guaranteed to
- // be non-empty.
- virtual bool OnUnknownFramePayload(absl::string_view payload) = 0;
- // Called when the unknown frame has been completely processed.
- virtual bool OnUnknownFrameEnd() = 0;
- };
-
- // |visitor| must be non-null, and must outlive HttpDecoder.
- explicit HttpDecoder(Visitor* visitor);
- explicit HttpDecoder(Visitor* visitor, Options options);
-
- ~HttpDecoder();
-
- // Processes the input and invokes the appropriate visitor methods, until a
- // visitor method returns false or an error occurs. Returns the number of
- // bytes processed. Does not process any input if called after an error.
- // Paused processing can be resumed by calling ProcessInput() again with the
- // unprocessed portion of data. Must not be called after an error has
- // occurred.
- QuicByteCount ProcessInput(const char* data, QuicByteCount len);
-
- // Decode settings frame from |data|.
- // Upon successful decoding, |frame| will be populated, and returns true.
- // This method is not used for regular processing of incoming data.
- static bool DecodeSettings(const char* data,
- QuicByteCount len,
- SettingsFrame* frame);
-
- // Returns an error code other than QUIC_NO_ERROR if and only if
- // Visitor::OnError() has been called.
- QuicErrorCode error() const { return error_; }
-
- const std::string& error_detail() const { return error_detail_; }
-
- // Returns true if input data processed so far ends on a frame boundary.
- bool AtFrameBoundary() const { return state_ == STATE_READING_FRAME_TYPE; }
-
- private:
- friend test::HttpDecoderPeer;
-
- // Represents the current state of the parsing state machine.
- enum HttpDecoderState {
- STATE_READING_FRAME_LENGTH,
- STATE_READING_FRAME_TYPE,
-
- // States used for buffered frame types
- STATE_BUFFER_OR_PARSE_PAYLOAD,
-
- // States used for non-buffered frame types
- STATE_READING_FRAME_PAYLOAD,
- STATE_FINISH_PARSING,
-
- STATE_PARSING_NO_LONGER_POSSIBLE,
- STATE_ERROR
- };
-
- // Reads the type of a frame from |reader|. Sets error_ and error_detail_
- // if there are any errors. Also calls OnDataFrameStart() or
- // OnHeadersFrameStart() for appropriate frame types. Returns whether the
- // processing should continue.
- bool ReadFrameType(QuicDataReader* reader);
-
- // Reads the length of a frame from |reader|. Sets error_ and error_detail_
- // if there are any errors. Returns whether processing should continue.
- bool ReadFrameLength(QuicDataReader* reader);
-
- // Returns whether the current frame is of a buffered type.
- // The payload of buffered frames is buffered by HttpDecoder, and parsed by
- // HttpDecoder after the entire frame has been received. (Copying to the
- // buffer is skipped if the ProcessInput() call covers the entire payload.)
- // Frames that are not buffered have every payload fragment synchronously
- // passed to the Visitor without buffering.
- bool IsFrameBuffered();
-
- // For buffered frame types, calls BufferOrParsePayload(). For other frame
- // types, reads the payload of the current frame from |reader| and calls
- // visitor methods. Returns whether processing should continue.
- bool ReadFramePayload(QuicDataReader* reader);
-
- // For buffered frame types, this method is only called if frame payload is
- // empty, and it calls BufferOrParsePayload(). For other frame types, this
- // method directly calls visitor methods to signal that frame had been
- // received completely. Returns whether processing should continue.
- bool FinishParsing();
-
- // Reset internal fields to prepare for reading next frame.
- void ResetForNextFrame();
-
- // Read payload of unknown frame from |reader| and call
- // Visitor::OnUnknownFramePayload(). Returns true decoding should continue,
- // false if it should be paused.
- bool HandleUnknownFramePayload(QuicDataReader* reader);
-
- // Buffers any remaining frame payload from |*reader| into |buffer_| if
- // necessary. Parses the frame payload if complete. Parses out of |*reader|
- // without unnecessary copy if |*reader| contains entire payload.
- // Returns whether processing should continue.
- // Must only be called when current frame type is buffered.
- bool BufferOrParsePayload(QuicDataReader* reader);
-
- // Parses the entire payload of certain kinds of frames that are parsed in a
- // single pass. |reader| must have at least |current_frame_length_| bytes.
- // Returns whether processing should continue.
- // Must only be called when current frame type is buffered.
- bool ParseEntirePayload(QuicDataReader* reader);
-
- // Buffers any remaining frame length field from |reader| into
- // |length_buffer_|.
- void BufferFrameLength(QuicDataReader* reader);
-
- // Buffers any remaining frame type field from |reader| into |type_buffer_|.
- void BufferFrameType(QuicDataReader* reader);
-
- // Sets |error_| and |error_detail_| accordingly.
- void RaiseError(QuicErrorCode error, std::string error_detail);
-
- // Parses the payload of a SETTINGS frame from |reader| into |frame|.
- bool ParseSettingsFrame(QuicDataReader* reader, SettingsFrame* frame);
-
- // Parses the payload of a PRIORITY_UPDATE frame (draft-02, type 0xf0700)
- // from |reader| into |frame|.
- bool ParsePriorityUpdateFrame(QuicDataReader* reader,
- PriorityUpdateFrame* frame);
-
- // Parses the payload of an ACCEPT_CH frame from |reader| into |frame|.
- bool ParseAcceptChFrame(QuicDataReader* reader, AcceptChFrame* frame);
-
- // Returns the max frame size of a given |frame_type|.
- QuicByteCount MaxFrameLength(uint64_t frame_type);
-
- // Visitor to invoke when messages are parsed.
- Visitor* const visitor_; // Unowned.
- // Whether WEBTRANSPORT_STREAM should be parsed.
- bool allow_web_transport_stream_;
- // Current state of the parsing.
- HttpDecoderState state_;
- // Type of the frame currently being parsed.
- uint64_t current_frame_type_;
- // Size of the frame's length field.
- QuicByteCount current_length_field_length_;
- // Remaining length that's needed for the frame's length field.
- QuicByteCount remaining_length_field_length_;
- // Length of the payload of the frame currently being parsed.
- QuicByteCount current_frame_length_;
- // Remaining payload bytes to be parsed.
- QuicByteCount remaining_frame_length_;
- // Length of the frame's type field.
- QuicByteCount current_type_field_length_;
- // Remaining length that's needed for the frame's type field.
- QuicByteCount remaining_type_field_length_;
- // Last error.
- QuicErrorCode error_;
- // The issue which caused |error_|
- std::string error_detail_;
- // Remaining unparsed data.
- std::string buffer_;
- // Remaining unparsed length field data.
- std::array<char, sizeof(uint64_t)> length_buffer_;
- // Remaining unparsed type field data.
- std::array<char, sizeof(uint64_t)> type_buffer_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_HTTP_HTTP_DECODER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/http/http_decoder_test.cc b/chromium/net/third_party/quiche/src/quic/core/http/http_decoder_test.cc
deleted file mode 100644
index 95d5913896b..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/http/http_decoder_test.cc
+++ /dev/null
@@ -1,1136 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/http/http_decoder.h"
-
-#include <memory>
-#include <utility>
-
-#include "absl/base/macros.h"
-#include "absl/strings/escaping.h"
-#include "absl/strings/str_cat.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/http/http_encoder.h"
-#include "quic/core/http/http_frames.h"
-#include "quic/core/quic_data_writer.h"
-#include "quic/core/quic_versions.h"
-#include "quic/platform/api/quic_expect_bug.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/quic_test_utils.h"
-
-using ::testing::_;
-using ::testing::AnyNumber;
-using ::testing::Eq;
-using ::testing::InSequence;
-using ::testing::Return;
-
-namespace quic {
-namespace test {
-
-class HttpDecoderPeer {
- public:
- static uint64_t current_frame_type(HttpDecoder* decoder) {
- return decoder->current_frame_type_;
- }
-};
-
-namespace {
-
-class MockHttpDecoderVisitor : public HttpDecoder::Visitor {
- public:
- ~MockHttpDecoderVisitor() override = default;
-
- // Called if an error is detected.
- MOCK_METHOD(void, OnError, (HttpDecoder*), (override));
-
- MOCK_METHOD(bool,
- OnMaxPushIdFrame,
- (const MaxPushIdFrame& frame),
- (override));
- MOCK_METHOD(bool, OnGoAwayFrame, (const GoAwayFrame& frame), (override));
- MOCK_METHOD(bool,
- OnSettingsFrameStart,
- (QuicByteCount header_length),
- (override));
- MOCK_METHOD(bool, OnSettingsFrame, (const SettingsFrame& frame), (override));
-
- MOCK_METHOD(bool,
- OnDataFrameStart,
- (QuicByteCount header_length, QuicByteCount payload_length),
- (override));
- MOCK_METHOD(bool,
- OnDataFramePayload,
- (absl::string_view payload),
- (override));
- MOCK_METHOD(bool, OnDataFrameEnd, (), (override));
-
- MOCK_METHOD(bool,
- OnHeadersFrameStart,
- (QuicByteCount header_length, QuicByteCount payload_length),
- (override));
- MOCK_METHOD(bool,
- OnHeadersFramePayload,
- (absl::string_view payload),
- (override));
- MOCK_METHOD(bool, OnHeadersFrameEnd, (), (override));
-
- MOCK_METHOD(bool,
- OnPriorityUpdateFrameStart,
- (QuicByteCount header_length),
- (override));
- MOCK_METHOD(bool,
- OnPriorityUpdateFrame,
- (const PriorityUpdateFrame& frame),
- (override));
-
- MOCK_METHOD(bool,
- OnAcceptChFrameStart,
- (QuicByteCount header_length),
- (override));
- MOCK_METHOD(bool, OnAcceptChFrame, (const AcceptChFrame& frame), (override));
- MOCK_METHOD(void,
- OnWebTransportStreamFrameType,
- (QuicByteCount header_length, WebTransportSessionId session_id),
- (override));
-
- MOCK_METHOD(bool,
- OnUnknownFrameStart,
- (uint64_t frame_type,
- QuicByteCount header_length,
- QuicByteCount payload_length),
- (override));
- MOCK_METHOD(bool,
- OnUnknownFramePayload,
- (absl::string_view payload),
- (override));
- MOCK_METHOD(bool, OnUnknownFrameEnd, (), (override));
-};
-
-class HttpDecoderTest : public QuicTest {
- public:
- HttpDecoderTest() : decoder_(&visitor_) {
- 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));
- ON_CALL(visitor_, OnDataFrameStart(_, _)).WillByDefault(Return(true));
- ON_CALL(visitor_, OnDataFramePayload(_)).WillByDefault(Return(true));
- ON_CALL(visitor_, OnDataFrameEnd()).WillByDefault(Return(true));
- ON_CALL(visitor_, OnHeadersFrameStart(_, _)).WillByDefault(Return(true));
- ON_CALL(visitor_, OnHeadersFramePayload(_)).WillByDefault(Return(true));
- ON_CALL(visitor_, OnHeadersFrameEnd()).WillByDefault(Return(true));
- ON_CALL(visitor_, OnPriorityUpdateFrameStart(_))
- .WillByDefault(Return(true));
- ON_CALL(visitor_, OnPriorityUpdateFrame(_)).WillByDefault(Return(true));
- ON_CALL(visitor_, OnAcceptChFrameStart(_)).WillByDefault(Return(true));
- ON_CALL(visitor_, OnAcceptChFrame(_)).WillByDefault(Return(true));
- ON_CALL(visitor_, OnUnknownFrameStart(_, _, _)).WillByDefault(Return(true));
- ON_CALL(visitor_, OnUnknownFramePayload(_)).WillByDefault(Return(true));
- ON_CALL(visitor_, OnUnknownFrameEnd()).WillByDefault(Return(true));
- }
- ~HttpDecoderTest() override = default;
-
- uint64_t current_frame_type() {
- return HttpDecoderPeer::current_frame_type(&decoder_);
- }
-
- // Process |input| in a single call to HttpDecoder::ProcessInput().
- QuicByteCount ProcessInput(absl::string_view input) {
- return decoder_.ProcessInput(input.data(), input.size());
- }
-
- // Feed |input| to |decoder_| one character at a time,
- // verifying that each character gets processed.
- void ProcessInputCharByChar(absl::string_view input) {
- for (char c : input) {
- EXPECT_EQ(1u, decoder_.ProcessInput(&c, 1));
- }
- }
-
- // Append garbage to |input|, then process it in a single call to
- // HttpDecoder::ProcessInput(). Verify that garbage is not read.
- QuicByteCount ProcessInputWithGarbageAppended(absl::string_view input) {
- std::string input_with_garbage_appended = absl::StrCat(input, "blahblah");
- QuicByteCount processed_bytes = ProcessInput(input_with_garbage_appended);
-
- // Guaranteed by HttpDecoder::ProcessInput() contract.
- QUICHE_DCHECK_LE(processed_bytes, input_with_garbage_appended.size());
-
- // Caller should set up visitor to pause decoding
- // before HttpDecoder would read garbage.
- EXPECT_LE(processed_bytes, input.size());
-
- return processed_bytes;
- }
-
- testing::StrictMock<MockHttpDecoderVisitor> visitor_;
- HttpDecoder decoder_;
-};
-
-TEST_F(HttpDecoderTest, InitialState) {
- EXPECT_THAT(decoder_.error(), IsQuicNoError());
- EXPECT_EQ("", decoder_.error_detail());
-}
-
-TEST_F(HttpDecoderTest, UnknownFrame) {
- std::unique_ptr<char[]> input;
-
- const QuicByteCount payload_lengths[] = {0, 14, 100};
- const uint64_t frame_types[] = {
- 0x21, 0x40, 0x5f, 0x7e, 0x9d, // some reserved frame types
- 0x6f, 0x14 // some unknown, not reserved frame types
- };
-
- for (auto payload_length : payload_lengths) {
- std::string data(payload_length, 'a');
-
- for (auto frame_type : frame_types) {
- const QuicByteCount total_length =
- QuicDataWriter::GetVarInt62Len(frame_type) +
- QuicDataWriter::GetVarInt62Len(payload_length) + payload_length;
- input = std::make_unique<char[]>(total_length);
-
- QuicDataWriter writer(total_length, input.get());
- writer.WriteVarInt62(frame_type);
- writer.WriteVarInt62(payload_length);
- const QuicByteCount header_length = writer.length();
- if (payload_length > 0) {
- writer.WriteStringPiece(data);
- }
-
- EXPECT_CALL(visitor_, OnUnknownFrameStart(frame_type, header_length,
- payload_length));
- if (payload_length > 0) {
- EXPECT_CALL(visitor_, OnUnknownFramePayload(Eq(data)));
- }
- EXPECT_CALL(visitor_, OnUnknownFrameEnd());
-
- EXPECT_EQ(total_length, decoder_.ProcessInput(input.get(), total_length));
-
- EXPECT_THAT(decoder_.error(), IsQuicNoError());
- ASSERT_EQ("", decoder_.error_detail());
- EXPECT_EQ(frame_type, current_frame_type());
- }
- }
-}
-
-TEST_F(HttpDecoderTest, CancelPush) {
- InSequence s;
- std::string input = absl::HexStringToBytes(
- "03" // type (CANCEL_PUSH)
- "01" // length
- "01"); // Push Id
-
- EXPECT_CALL(visitor_, OnError(&decoder_));
- EXPECT_EQ(1u, ProcessInput(input));
- EXPECT_THAT(decoder_.error(), IsError(QUIC_HTTP_FRAME_ERROR));
- EXPECT_EQ("CANCEL_PUSH frame received.", decoder_.error_detail());
-}
-
-TEST_F(HttpDecoderTest, PushPromiseFrame) {
- InSequence s;
- std::string input =
- absl::StrCat(absl::HexStringToBytes("05" // type (PUSH PROMISE)
- "08" // length
- "1f"), // push id 31
- "Headers"); // headers
-
- EXPECT_CALL(visitor_, OnError(&decoder_));
- EXPECT_EQ(1u, ProcessInput(input));
- EXPECT_THAT(decoder_.error(), IsError(QUIC_HTTP_FRAME_ERROR));
- EXPECT_EQ("PUSH_PROMISE frame received.", decoder_.error_detail());
-}
-
-TEST_F(HttpDecoderTest, MaxPushId) {
- InSequence s;
- std::string input = absl::HexStringToBytes(
- "0D" // type (MAX_PUSH_ID)
- "01" // length
- "01"); // Push Id
-
- // Visitor pauses processing.
- EXPECT_CALL(visitor_, OnMaxPushIdFrame(MaxPushIdFrame({1})))
- .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_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})));
- ProcessInputCharByChar(input);
- EXPECT_THAT(decoder_.error(), IsQuicNoError());
- EXPECT_EQ("", decoder_.error_detail());
-}
-
-TEST_F(HttpDecoderTest, SettingsFrame) {
- InSequence s;
- std::string input = absl::HexStringToBytes(
- "04" // type (SETTINGS)
- "07" // length
- "01" // identifier (SETTINGS_QPACK_MAX_TABLE_CAPACITY)
- "02" // content
- "06" // identifier (SETTINGS_MAX_HEADER_LIST_SIZE)
- "05" // content
- "4100" // identifier, encoded on 2 bytes (0x40), value is 256 (0x100)
- "04"); // content
-
- SettingsFrame frame;
- frame.values[1] = 2;
- frame.values[6] = 5;
- frame.values[256] = 4;
-
- // Visitor pauses processing.
- absl::string_view remaining_input(input);
- EXPECT_CALL(visitor_, OnSettingsFrameStart(2)).WillOnce(Return(false));
- QuicByteCount processed_bytes =
- ProcessInputWithGarbageAppended(remaining_input);
- EXPECT_EQ(2u, processed_bytes);
- remaining_input = remaining_input.substr(processed_bytes);
-
- EXPECT_CALL(visitor_, OnSettingsFrame(frame)).WillOnce(Return(false));
- processed_bytes = ProcessInputWithGarbageAppended(remaining_input);
- EXPECT_EQ(remaining_input.size(), processed_bytes);
- EXPECT_THAT(decoder_.error(), IsQuicNoError());
- EXPECT_EQ("", decoder_.error_detail());
-
- // Process the full frame.
- EXPECT_CALL(visitor_, OnSettingsFrameStart(2));
- EXPECT_CALL(visitor_, OnSettingsFrame(frame));
- EXPECT_EQ(input.size(), ProcessInput(input));
- EXPECT_THAT(decoder_.error(), IsQuicNoError());
- EXPECT_EQ("", decoder_.error_detail());
-
- // Process the frame incrementally.
- EXPECT_CALL(visitor_, OnSettingsFrameStart(2));
- EXPECT_CALL(visitor_, OnSettingsFrame(frame));
- ProcessInputCharByChar(input);
- EXPECT_THAT(decoder_.error(), IsQuicNoError());
- EXPECT_EQ("", decoder_.error_detail());
-}
-
-TEST_F(HttpDecoderTest, CorruptSettingsFrame) {
- const char* const kPayload =
- "\x42\x11" // two-byte id
- "\x80\x22\x33\x44" // four-byte value
- "\x58\x39" // two-byte id
- "\xf0\x22\x33\x44\x55\x66\x77\x88"; // eight-byte value
- struct {
- size_t payload_length;
- const char* const error_message;
- } kTestData[] = {
- {1, "Unable to read setting identifier."},
- {5, "Unable to read setting value."},
- {7, "Unable to read setting identifier."},
- {12, "Unable to read setting value."},
- };
-
- for (const auto& test_data : kTestData) {
- std::string input;
- input.push_back(4u); // type SETTINGS
- input.push_back(test_data.payload_length);
- const size_t header_length = input.size();
- input.append(kPayload, test_data.payload_length);
-
- HttpDecoder decoder(&visitor_);
- EXPECT_CALL(visitor_, OnSettingsFrameStart(header_length));
- EXPECT_CALL(visitor_, OnError(&decoder));
-
- QuicByteCount processed_bytes =
- decoder.ProcessInput(input.data(), input.size());
- EXPECT_EQ(input.size(), processed_bytes);
- EXPECT_THAT(decoder.error(), IsError(QUIC_HTTP_FRAME_ERROR));
- EXPECT_EQ(test_data.error_message, decoder.error_detail());
- }
-}
-
-TEST_F(HttpDecoderTest, DuplicateSettingsIdentifier) {
- std::string input = absl::HexStringToBytes(
- "04" // type (SETTINGS)
- "04" // length
- "01" // identifier
- "01" // content
- "01" // identifier
- "02"); // content
-
- EXPECT_CALL(visitor_, OnSettingsFrameStart(2));
- EXPECT_CALL(visitor_, OnError(&decoder_));
-
- EXPECT_EQ(input.size(), ProcessInput(input));
-
- EXPECT_THAT(decoder_.error(),
- IsError(QUIC_HTTP_DUPLICATE_SETTING_IDENTIFIER));
- EXPECT_EQ("Duplicate setting identifier.", decoder_.error_detail());
-}
-
-TEST_F(HttpDecoderTest, DataFrame) {
- InSequence s;
- std::string input = absl::StrCat(absl::HexStringToBytes("00" // type (DATA)
- "05"), // length
- "Data!"); // data
-
- // Visitor pauses processing.
- EXPECT_CALL(visitor_, OnDataFrameStart(2, 5)).WillOnce(Return(false));
- absl::string_view remaining_input(input);
- QuicByteCount processed_bytes =
- ProcessInputWithGarbageAppended(remaining_input);
- EXPECT_EQ(2u, processed_bytes);
- remaining_input = remaining_input.substr(processed_bytes);
-
- EXPECT_CALL(visitor_, OnDataFramePayload(absl::string_view("Data!")))
- .WillOnce(Return(false));
- processed_bytes = ProcessInputWithGarbageAppended(remaining_input);
- EXPECT_EQ(remaining_input.size(), processed_bytes);
-
- EXPECT_CALL(visitor_, OnDataFrameEnd()).WillOnce(Return(false));
- EXPECT_EQ(0u, ProcessInputWithGarbageAppended(""));
- EXPECT_THAT(decoder_.error(), IsQuicNoError());
- EXPECT_EQ("", decoder_.error_detail());
-
- // Process the full frame.
- EXPECT_CALL(visitor_, OnDataFrameStart(2, 5));
- EXPECT_CALL(visitor_, OnDataFramePayload(absl::string_view("Data!")));
- EXPECT_CALL(visitor_, OnDataFrameEnd());
- EXPECT_EQ(input.size(), ProcessInput(input));
- EXPECT_THAT(decoder_.error(), IsQuicNoError());
- EXPECT_EQ("", decoder_.error_detail());
-
- // Process the frame incrementally.
- EXPECT_CALL(visitor_, OnDataFrameStart(2, 5));
- EXPECT_CALL(visitor_, OnDataFramePayload(absl::string_view("D")));
- EXPECT_CALL(visitor_, OnDataFramePayload(absl::string_view("a")));
- EXPECT_CALL(visitor_, OnDataFramePayload(absl::string_view("t")));
- EXPECT_CALL(visitor_, OnDataFramePayload(absl::string_view("a")));
- EXPECT_CALL(visitor_, OnDataFramePayload(absl::string_view("!")));
- EXPECT_CALL(visitor_, OnDataFrameEnd());
- ProcessInputCharByChar(input);
- EXPECT_THAT(decoder_.error(), IsQuicNoError());
- EXPECT_EQ("", decoder_.error_detail());
-}
-
-TEST_F(HttpDecoderTest, FrameHeaderPartialDelivery) {
- InSequence s;
- // A large input that will occupy more than 1 byte in the length field.
- std::string input(2048, 'x');
- QuicBuffer header = HttpEncoder::SerializeDataFrameHeader(
- input.length(), SimpleBufferAllocator::Get());
- // Partially send only 1 byte of the header to process.
- EXPECT_EQ(1u, decoder_.ProcessInput(header.data(), 1));
- EXPECT_THAT(decoder_.error(), IsQuicNoError());
- EXPECT_EQ("", decoder_.error_detail());
-
- // Send the rest of the header.
- EXPECT_CALL(visitor_, OnDataFrameStart(3, input.length()));
- EXPECT_EQ(header.size() - 1,
- decoder_.ProcessInput(header.data() + 1, header.size() - 1));
- EXPECT_THAT(decoder_.error(), IsQuicNoError());
- EXPECT_EQ("", decoder_.error_detail());
-
- // Send data.
- EXPECT_CALL(visitor_, OnDataFramePayload(absl::string_view(input)));
- EXPECT_CALL(visitor_, OnDataFrameEnd());
- EXPECT_EQ(2048u, decoder_.ProcessInput(input.data(), 2048));
- EXPECT_THAT(decoder_.error(), IsQuicNoError());
- EXPECT_EQ("", decoder_.error_detail());
-}
-
-TEST_F(HttpDecoderTest, PartialDeliveryOfLargeFrameType) {
- // Use a reserved type that takes four bytes as a varint.
- const uint64_t frame_type = 0x1f * 0x222 + 0x21;
- const QuicByteCount payload_length = 0;
- const QuicByteCount header_length =
- QuicDataWriter::GetVarInt62Len(frame_type) +
- QuicDataWriter::GetVarInt62Len(payload_length);
-
- auto input = std::make_unique<char[]>(header_length);
- QuicDataWriter writer(header_length, input.get());
- writer.WriteVarInt62(frame_type);
- writer.WriteVarInt62(payload_length);
-
- EXPECT_CALL(visitor_,
- OnUnknownFrameStart(frame_type, header_length, payload_length));
- EXPECT_CALL(visitor_, OnUnknownFrameEnd());
-
- auto raw_input = input.get();
- for (uint64_t i = 0; i < header_length; ++i) {
- char c = raw_input[i];
- EXPECT_EQ(1u, decoder_.ProcessInput(&c, 1));
- }
-
- EXPECT_THAT(decoder_.error(), IsQuicNoError());
- EXPECT_EQ("", decoder_.error_detail());
- EXPECT_EQ(frame_type, current_frame_type());
-}
-
-TEST_F(HttpDecoderTest, GoAway) {
- InSequence s;
- std::string input = absl::HexStringToBytes(
- "07" // type (GOAWAY)
- "01" // length
- "01"); // ID
-
- // Visitor pauses processing.
- EXPECT_CALL(visitor_, OnGoAwayFrame(GoAwayFrame({1})))
- .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_, OnGoAwayFrame(GoAwayFrame({1})));
- EXPECT_EQ(input.size(), ProcessInput(input));
- EXPECT_THAT(decoder_.error(), IsQuicNoError());
- EXPECT_EQ("", decoder_.error_detail());
-
- // Process the frame incrementally.
- EXPECT_CALL(visitor_, OnGoAwayFrame(GoAwayFrame({1})));
- ProcessInputCharByChar(input);
- EXPECT_THAT(decoder_.error(), IsQuicNoError());
- EXPECT_EQ("", decoder_.error_detail());
-}
-
-TEST_F(HttpDecoderTest, HeadersFrame) {
- InSequence s;
- std::string input =
- absl::StrCat(absl::HexStringToBytes("01" // type (HEADERS)
- "07"), // length
- "Headers"); // headers
-
- // Visitor pauses processing.
- EXPECT_CALL(visitor_, OnHeadersFrameStart(2, 7)).WillOnce(Return(false));
- absl::string_view remaining_input(input);
- QuicByteCount processed_bytes =
- ProcessInputWithGarbageAppended(remaining_input);
- EXPECT_EQ(2u, processed_bytes);
- remaining_input = remaining_input.substr(processed_bytes);
-
- EXPECT_CALL(visitor_, OnHeadersFramePayload(absl::string_view("Headers")))
- .WillOnce(Return(false));
- processed_bytes = ProcessInputWithGarbageAppended(remaining_input);
- EXPECT_EQ(remaining_input.size(), processed_bytes);
-
- EXPECT_CALL(visitor_, OnHeadersFrameEnd()).WillOnce(Return(false));
- EXPECT_EQ(0u, ProcessInputWithGarbageAppended(""));
- EXPECT_THAT(decoder_.error(), IsQuicNoError());
- EXPECT_EQ("", decoder_.error_detail());
-
- // Process the full frame.
- EXPECT_CALL(visitor_, OnHeadersFrameStart(2, 7));
- EXPECT_CALL(visitor_, OnHeadersFramePayload(absl::string_view("Headers")));
- EXPECT_CALL(visitor_, OnHeadersFrameEnd());
- EXPECT_EQ(input.size(), ProcessInput(input));
- EXPECT_THAT(decoder_.error(), IsQuicNoError());
- EXPECT_EQ("", decoder_.error_detail());
-
- // Process the frame incrementally.
- EXPECT_CALL(visitor_, OnHeadersFrameStart(2, 7));
- EXPECT_CALL(visitor_, OnHeadersFramePayload(absl::string_view("H")));
- EXPECT_CALL(visitor_, OnHeadersFramePayload(absl::string_view("e")));
- EXPECT_CALL(visitor_, OnHeadersFramePayload(absl::string_view("a")));
- EXPECT_CALL(visitor_, OnHeadersFramePayload(absl::string_view("d")));
- EXPECT_CALL(visitor_, OnHeadersFramePayload(absl::string_view("e")));
- EXPECT_CALL(visitor_, OnHeadersFramePayload(absl::string_view("r")));
- EXPECT_CALL(visitor_, OnHeadersFramePayload(absl::string_view("s")));
- EXPECT_CALL(visitor_, OnHeadersFrameEnd());
- ProcessInputCharByChar(input);
- EXPECT_THAT(decoder_.error(), IsQuicNoError());
- EXPECT_EQ("", decoder_.error_detail());
-}
-
-TEST_F(HttpDecoderTest, EmptyDataFrame) {
- InSequence s;
- std::string input = absl::HexStringToBytes(
- "00" // type (DATA)
- "00"); // length
-
- // Visitor pauses processing.
- EXPECT_CALL(visitor_, OnDataFrameStart(2, 0)).WillOnce(Return(false));
- EXPECT_EQ(input.size(), ProcessInputWithGarbageAppended(input));
-
- EXPECT_CALL(visitor_, OnDataFrameEnd()).WillOnce(Return(false));
- EXPECT_EQ(0u, ProcessInputWithGarbageAppended(""));
- EXPECT_THAT(decoder_.error(), IsQuicNoError());
- EXPECT_EQ("", decoder_.error_detail());
-
- // Process the full frame.
- EXPECT_CALL(visitor_, OnDataFrameStart(2, 0));
- EXPECT_CALL(visitor_, OnDataFrameEnd());
- EXPECT_EQ(input.size(), ProcessInput(input));
- EXPECT_THAT(decoder_.error(), IsQuicNoError());
- EXPECT_EQ("", decoder_.error_detail());
-
- // Process the frame incrementally.
- EXPECT_CALL(visitor_, OnDataFrameStart(2, 0));
- EXPECT_CALL(visitor_, OnDataFrameEnd());
- ProcessInputCharByChar(input);
- EXPECT_THAT(decoder_.error(), IsQuicNoError());
- EXPECT_EQ("", decoder_.error_detail());
-}
-
-TEST_F(HttpDecoderTest, EmptyHeadersFrame) {
- InSequence s;
- std::string input = absl::HexStringToBytes(
- "01" // type (HEADERS)
- "00"); // length
-
- // Visitor pauses processing.
- EXPECT_CALL(visitor_, OnHeadersFrameStart(2, 0)).WillOnce(Return(false));
- EXPECT_EQ(input.size(), ProcessInputWithGarbageAppended(input));
-
- EXPECT_CALL(visitor_, OnHeadersFrameEnd()).WillOnce(Return(false));
- EXPECT_EQ(0u, ProcessInputWithGarbageAppended(""));
- EXPECT_THAT(decoder_.error(), IsQuicNoError());
- EXPECT_EQ("", decoder_.error_detail());
-
- // Process the full frame.
- EXPECT_CALL(visitor_, OnHeadersFrameStart(2, 0));
- EXPECT_CALL(visitor_, OnHeadersFrameEnd());
- EXPECT_EQ(input.size(), ProcessInput(input));
- EXPECT_THAT(decoder_.error(), IsQuicNoError());
- EXPECT_EQ("", decoder_.error_detail());
-
- // Process the frame incrementally.
- EXPECT_CALL(visitor_, OnHeadersFrameStart(2, 0));
- EXPECT_CALL(visitor_, OnHeadersFrameEnd());
- ProcessInputCharByChar(input);
- EXPECT_THAT(decoder_.error(), IsQuicNoError());
- EXPECT_EQ("", decoder_.error_detail());
-}
-
-TEST_F(HttpDecoderTest, GoawayWithOverlyLargePayload) {
- std::string input = absl::HexStringToBytes(
- "07" // type (GOAWAY)
- "10"); // length exceeding the maximum possible length for GOAWAY frame
- // Process all data at once.
- EXPECT_CALL(visitor_, OnError(&decoder_));
- EXPECT_EQ(2u, ProcessInput(input));
- EXPECT_THAT(decoder_.error(), IsError(QUIC_HTTP_FRAME_TOO_LARGE));
- EXPECT_EQ("Frame is too large.", decoder_.error_detail());
-}
-
-TEST_F(HttpDecoderTest, MaxPushIdWithOverlyLargePayload) {
- std::string input = absl::HexStringToBytes(
- "0d" // type (MAX_PUSH_ID)
- "10"); // length exceeding the maximum possible length for MAX_PUSH_ID
- // frame
- // Process all data at once.
- EXPECT_CALL(visitor_, OnError(&decoder_));
- EXPECT_EQ(2u, ProcessInput(input));
- EXPECT_THAT(decoder_.error(), IsError(QUIC_HTTP_FRAME_TOO_LARGE));
- EXPECT_EQ("Frame is too large.", decoder_.error_detail());
-}
-
-TEST_F(HttpDecoderTest, FrameWithOverlyLargePayload) {
- // Regression test for b/193919867: Ensure that reading frames with incredibly
- // large payload lengths does not lead to allocating unbounded memory.
- constexpr size_t max_input_length =
- /*max frame type varint length*/ sizeof(uint64_t) +
- /*max frame length varint length*/ sizeof(uint64_t) +
- /*one byte of payload*/ sizeof(uint8_t);
- char input[max_input_length];
- for (uint64_t frame_type = 0; frame_type < 1025; frame_type++) {
- ::testing::NiceMock<MockHttpDecoderVisitor> visitor;
- HttpDecoder decoder(&visitor);
- QuicDataWriter writer(max_input_length, input);
- ASSERT_TRUE(writer.WriteVarInt62(frame_type)); // frame type.
- ASSERT_TRUE(writer.WriteVarInt62(kVarInt62MaxValue)); // frame length.
- ASSERT_TRUE(writer.WriteUInt8(0x00)); // one byte of payload.
- EXPECT_NE(decoder.ProcessInput(input, writer.length()), 0u) << frame_type;
- }
-}
-
-TEST_F(HttpDecoderTest, MalformedSettingsFrame) {
- char input[30];
- QuicDataWriter writer(30, input);
- // Write type SETTINGS.
- writer.WriteUInt8(0x04);
- // Write length.
- writer.WriteVarInt62(2048 * 1024);
-
- writer.WriteStringPiece("Malformed payload");
- EXPECT_CALL(visitor_, OnError(&decoder_));
- EXPECT_EQ(5u, decoder_.ProcessInput(input, ABSL_ARRAYSIZE(input)));
- EXPECT_THAT(decoder_.error(), IsError(QUIC_HTTP_FRAME_TOO_LARGE));
- EXPECT_EQ("Frame is too large.", decoder_.error_detail());
-}
-
-TEST_F(HttpDecoderTest, Http2Frame) {
- std::string input = absl::HexStringToBytes(
- "06" // PING in HTTP/2 but not supported in HTTP/3.
- "05" // length
- "15"); // random payload
-
- // Process the full frame.
- EXPECT_CALL(visitor_, OnError(&decoder_));
- EXPECT_EQ(1u, ProcessInput(input));
- EXPECT_THAT(decoder_.error(), IsError(QUIC_HTTP_RECEIVE_SPDY_FRAME));
- EXPECT_EQ("HTTP/2 frame received in a HTTP/3 connection: 6",
- decoder_.error_detail());
-}
-
-TEST_F(HttpDecoderTest, HeadersPausedThenData) {
- InSequence s;
- std::string input =
- absl::StrCat(absl::HexStringToBytes("01" // type (HEADERS)
- "07"), // length
- "Headers", // headers
- absl::HexStringToBytes("00" // type (DATA)
- "05"), // length
- "Data!"); // data
-
- // Visitor pauses processing, maybe because header decompression is blocked.
- EXPECT_CALL(visitor_, OnHeadersFrameStart(2, 7));
- EXPECT_CALL(visitor_, OnHeadersFramePayload(absl::string_view("Headers")));
- EXPECT_CALL(visitor_, OnHeadersFrameEnd()).WillOnce(Return(false));
- absl::string_view remaining_input(input);
- QuicByteCount processed_bytes =
- ProcessInputWithGarbageAppended(remaining_input);
- EXPECT_EQ(9u, processed_bytes);
- remaining_input = remaining_input.substr(processed_bytes);
-
- // Process DATA frame.
- EXPECT_CALL(visitor_, OnDataFrameStart(2, 5));
- EXPECT_CALL(visitor_, OnDataFramePayload(absl::string_view("Data!")));
- EXPECT_CALL(visitor_, OnDataFrameEnd());
-
- processed_bytes = ProcessInput(remaining_input);
- EXPECT_EQ(remaining_input.size(), processed_bytes);
-
- EXPECT_THAT(decoder_.error(), IsQuicNoError());
- EXPECT_EQ("", decoder_.error_detail());
-}
-
-TEST_F(HttpDecoderTest, CorruptFrame) {
- InSequence s;
-
- struct {
- const char* const input;
- const char* const error_message;
- } kTestData[] = {{"\x0D" // type (MAX_PUSH_ID)
- "\x01" // length
- "\x40", // first byte of two-byte varint push id
- "Unable to read MAX_PUSH_ID push_id."},
- {"\x0D" // type (MAX_PUSH_ID)
- "\x04" // length
- "\x05" // valid push id
- "foo", // superfluous data
- "Superfluous data in MAX_PUSH_ID frame."},
- {"\x07" // type (GOAWAY)
- "\x01" // length
- "\x40", // first byte of two-byte varint stream id
- "Unable to read GOAWAY ID."},
- {"\x07" // type (GOAWAY)
- "\x04" // length
- "\x05" // valid stream id
- "foo", // superfluous data
- "Superfluous data in GOAWAY frame."},
- {"\x40\x89" // type (ACCEPT_CH)
- "\x01" // length
- "\x40", // first byte of two-byte varint origin length
- "Unable to read ACCEPT_CH origin."},
- {"\x40\x89" // type (ACCEPT_CH)
- "\x01" // length
- "\x05", // valid origin length but no origin string
- "Unable to read ACCEPT_CH origin."},
- {"\x40\x89" // type (ACCEPT_CH)
- "\x04" // length
- "\x05" // valid origin length
- "foo", // payload ends before origin ends
- "Unable to read ACCEPT_CH origin."},
- {"\x40\x89" // type (ACCEPT_CH)
- "\x04" // length
- "\x03" // valid origin length
- "foo", // payload ends at end of origin: no value
- "Unable to read ACCEPT_CH value."},
- {"\x40\x89" // type (ACCEPT_CH)
- "\x05" // length
- "\x03" // valid origin length
- "foo" // payload ends at end of origin: no value
- "\x40", // first byte of two-byte varint value length
- "Unable to read ACCEPT_CH value."},
- {"\x40\x89" // type (ACCEPT_CH)
- "\x08" // length
- "\x03" // valid origin length
- "foo" // origin
- "\x05" // valid value length
- "bar", // payload ends before value ends
- "Unable to read ACCEPT_CH value."}};
-
- for (const auto& test_data : kTestData) {
- {
- HttpDecoder decoder(&visitor_);
- EXPECT_CALL(visitor_, OnAcceptChFrameStart(_)).Times(AnyNumber());
- EXPECT_CALL(visitor_, OnError(&decoder));
-
- absl::string_view input(test_data.input);
- decoder.ProcessInput(input.data(), input.size());
- EXPECT_THAT(decoder.error(), IsError(QUIC_HTTP_FRAME_ERROR));
- EXPECT_EQ(test_data.error_message, decoder.error_detail());
- }
- {
- HttpDecoder decoder(&visitor_);
- EXPECT_CALL(visitor_, OnAcceptChFrameStart(_)).Times(AnyNumber());
- EXPECT_CALL(visitor_, OnError(&decoder));
-
- absl::string_view input(test_data.input);
- for (auto c : input) {
- decoder.ProcessInput(&c, 1);
- }
- EXPECT_THAT(decoder.error(), IsError(QUIC_HTTP_FRAME_ERROR));
- EXPECT_EQ(test_data.error_message, decoder.error_detail());
- }
- }
-}
-
-TEST_F(HttpDecoderTest, EmptySettingsFrame) {
- std::string input = absl::HexStringToBytes(
- "04" // type (SETTINGS)
- "00"); // frame length
-
- EXPECT_CALL(visitor_, OnSettingsFrameStart(2));
-
- SettingsFrame empty_frame;
- EXPECT_CALL(visitor_, OnSettingsFrame(empty_frame));
-
- EXPECT_EQ(input.size(), ProcessInput(input));
- EXPECT_THAT(decoder_.error(), IsQuicNoError());
- EXPECT_EQ("", decoder_.error_detail());
-}
-
-TEST_F(HttpDecoderTest, EmptyGoAwayFrame) {
- std::string input = absl::HexStringToBytes(
- "07" // type (GOAWAY)
- "00"); // frame length
-
- EXPECT_CALL(visitor_, OnError(&decoder_));
- EXPECT_EQ(input.size(), ProcessInput(input));
- EXPECT_THAT(decoder_.error(), IsError(QUIC_HTTP_FRAME_ERROR));
- EXPECT_EQ("Unable to read GOAWAY ID.", decoder_.error_detail());
-}
-
-TEST_F(HttpDecoderTest, EmptyMaxPushIdFrame) {
- std::string input = absl::HexStringToBytes(
- "0d" // type (MAX_PUSH_ID)
- "00"); // frame length
-
- EXPECT_CALL(visitor_, OnError(&decoder_));
- EXPECT_EQ(input.size(), ProcessInput(input));
- EXPECT_THAT(decoder_.error(), IsError(QUIC_HTTP_FRAME_ERROR));
- EXPECT_EQ("Unable to read MAX_PUSH_ID push_id.", decoder_.error_detail());
-}
-
-TEST_F(HttpDecoderTest, LargeStreamIdInGoAway) {
- GoAwayFrame frame;
- frame.id = 1ull << 60;
- std::unique_ptr<char[]> buffer;
- uint64_t length = HttpEncoder::SerializeGoAwayFrame(frame, &buffer);
- EXPECT_CALL(visitor_, OnGoAwayFrame(frame));
- EXPECT_GT(length, 0u);
- EXPECT_EQ(length, decoder_.ProcessInput(buffer.get(), length));
- EXPECT_THAT(decoder_.error(), IsQuicNoError());
- EXPECT_EQ("", decoder_.error_detail());
-}
-
-// Old PRIORITY_UPDATE frame is parsed as unknown frame.
-TEST_F(HttpDecoderTest, ObsoletePriorityUpdateFrame) {
- const QuicByteCount header_length = 2;
- const QuicByteCount payload_length = 3;
- InSequence s;
- std::string input = absl::HexStringToBytes(
- "0f" // type (obsolete PRIORITY_UPDATE)
- "03" // length
- "666f6f"); // payload "foo"
-
- // Process frame as a whole.
- EXPECT_CALL(visitor_,
- OnUnknownFrameStart(0x0f, header_length, payload_length));
- EXPECT_CALL(visitor_, OnUnknownFramePayload(Eq("foo")));
- EXPECT_CALL(visitor_, OnUnknownFrameEnd()).WillOnce(Return(false));
-
- EXPECT_EQ(header_length + payload_length,
- ProcessInputWithGarbageAppended(input));
- EXPECT_THAT(decoder_.error(), IsQuicNoError());
- EXPECT_EQ("", decoder_.error_detail());
-
- // Process frame byte by byte.
- EXPECT_CALL(visitor_,
- OnUnknownFrameStart(0x0f, header_length, payload_length));
- EXPECT_CALL(visitor_, OnUnknownFramePayload(Eq("f")));
- EXPECT_CALL(visitor_, OnUnknownFramePayload(Eq("o")));
- EXPECT_CALL(visitor_, OnUnknownFramePayload(Eq("o")));
- EXPECT_CALL(visitor_, OnUnknownFrameEnd());
-
- ProcessInputCharByChar(input);
- EXPECT_THAT(decoder_.error(), IsQuicNoError());
- EXPECT_EQ("", decoder_.error_detail());
-}
-
-TEST_F(HttpDecoderTest, PriorityUpdateFrame) {
- InSequence s;
- std::string input1 = absl::HexStringToBytes(
- "800f0700" // type (PRIORITY_UPDATE)
- "01" // length
- "03"); // prioritized element id
-
- PriorityUpdateFrame priority_update1;
- priority_update1.prioritized_element_type = REQUEST_STREAM;
- priority_update1.prioritized_element_id = 0x03;
-
- // Visitor pauses processing.
- EXPECT_CALL(visitor_, OnPriorityUpdateFrameStart(5)).WillOnce(Return(false));
- absl::string_view remaining_input(input1);
- QuicByteCount processed_bytes =
- ProcessInputWithGarbageAppended(remaining_input);
- EXPECT_EQ(5u, processed_bytes);
- remaining_input = remaining_input.substr(processed_bytes);
-
- EXPECT_CALL(visitor_, OnPriorityUpdateFrame(priority_update1))
- .WillOnce(Return(false));
- processed_bytes = ProcessInputWithGarbageAppended(remaining_input);
- EXPECT_EQ(remaining_input.size(), processed_bytes);
- EXPECT_THAT(decoder_.error(), IsQuicNoError());
- EXPECT_EQ("", decoder_.error_detail());
-
- // Process the full frame.
- EXPECT_CALL(visitor_, OnPriorityUpdateFrameStart(5));
- EXPECT_CALL(visitor_, OnPriorityUpdateFrame(priority_update1));
- EXPECT_EQ(input1.size(), ProcessInput(input1));
- EXPECT_THAT(decoder_.error(), IsQuicNoError());
- EXPECT_EQ("", decoder_.error_detail());
-
- // Process the frame incrementally.
- EXPECT_CALL(visitor_, OnPriorityUpdateFrameStart(5));
- EXPECT_CALL(visitor_, OnPriorityUpdateFrame(priority_update1));
- ProcessInputCharByChar(input1);
- EXPECT_THAT(decoder_.error(), IsQuicNoError());
- EXPECT_EQ("", decoder_.error_detail());
-
- std::string input2 = absl::HexStringToBytes(
- "800f0700" // type (PRIORITY_UPDATE)
- "04" // length
- "05" // prioritized element id
- "666f6f"); // priority field value: "foo"
-
- PriorityUpdateFrame priority_update2;
- priority_update2.prioritized_element_type = REQUEST_STREAM;
- priority_update2.prioritized_element_id = 0x05;
- priority_update2.priority_field_value = "foo";
-
- // Visitor pauses processing.
- EXPECT_CALL(visitor_, OnPriorityUpdateFrameStart(5)).WillOnce(Return(false));
- remaining_input = input2;
- processed_bytes = ProcessInputWithGarbageAppended(remaining_input);
- EXPECT_EQ(5u, processed_bytes);
- remaining_input = remaining_input.substr(processed_bytes);
-
- EXPECT_CALL(visitor_, OnPriorityUpdateFrame(priority_update2))
- .WillOnce(Return(false));
- processed_bytes = ProcessInputWithGarbageAppended(remaining_input);
- EXPECT_EQ(remaining_input.size(), processed_bytes);
- EXPECT_THAT(decoder_.error(), IsQuicNoError());
- EXPECT_EQ("", decoder_.error_detail());
-
- // Process the full frame.
- EXPECT_CALL(visitor_, OnPriorityUpdateFrameStart(5));
- EXPECT_CALL(visitor_, OnPriorityUpdateFrame(priority_update2));
- EXPECT_EQ(input2.size(), ProcessInput(input2));
- EXPECT_THAT(decoder_.error(), IsQuicNoError());
- EXPECT_EQ("", decoder_.error_detail());
-
- // Process the frame incrementally.
- EXPECT_CALL(visitor_, OnPriorityUpdateFrameStart(5));
- EXPECT_CALL(visitor_, OnPriorityUpdateFrame(priority_update2));
- ProcessInputCharByChar(input2);
- EXPECT_THAT(decoder_.error(), IsQuicNoError());
- EXPECT_EQ("", decoder_.error_detail());
-}
-
-TEST_F(HttpDecoderTest, CorruptPriorityUpdateFrame) {
- std::string payload =
- absl::HexStringToBytes("4005"); // prioritized element id
- struct {
- size_t payload_length;
- const char* const error_message;
- } kTestData[] = {
- {0, "Unable to read prioritized element id."},
- {1, "Unable to read prioritized element id."},
- };
-
- for (const auto& test_data : kTestData) {
- std::string input =
- absl::HexStringToBytes("800f0700"); // type PRIORITY_UPDATE
- input.push_back(test_data.payload_length);
- size_t header_length = input.size();
- input.append(payload.data(), test_data.payload_length);
-
- HttpDecoder decoder(&visitor_);
- EXPECT_CALL(visitor_, OnPriorityUpdateFrameStart(header_length));
- EXPECT_CALL(visitor_, OnError(&decoder));
-
- QuicByteCount processed_bytes =
- decoder.ProcessInput(input.data(), input.size());
- EXPECT_EQ(input.size(), processed_bytes);
- EXPECT_THAT(decoder.error(), IsError(QUIC_HTTP_FRAME_ERROR));
- EXPECT_EQ(test_data.error_message, decoder.error_detail());
- }
-}
-
-TEST_F(HttpDecoderTest, AcceptChFrame) {
- InSequence s;
- std::string input1 = absl::HexStringToBytes(
- "4089" // type (ACCEPT_CH)
- "00"); // length
-
- AcceptChFrame accept_ch1;
-
- // Visitor pauses processing.
- EXPECT_CALL(visitor_, OnAcceptChFrameStart(3)).WillOnce(Return(false));
- absl::string_view remaining_input(input1);
- QuicByteCount processed_bytes =
- ProcessInputWithGarbageAppended(remaining_input);
- EXPECT_EQ(3u, processed_bytes);
- remaining_input = remaining_input.substr(processed_bytes);
-
- EXPECT_CALL(visitor_, OnAcceptChFrame(accept_ch1)).WillOnce(Return(false));
- processed_bytes = ProcessInputWithGarbageAppended(remaining_input);
- EXPECT_EQ(remaining_input.size(), processed_bytes);
- EXPECT_THAT(decoder_.error(), IsQuicNoError());
- EXPECT_EQ("", decoder_.error_detail());
-
- // Process the full frame.
- EXPECT_CALL(visitor_, OnAcceptChFrameStart(3));
- EXPECT_CALL(visitor_, OnAcceptChFrame(accept_ch1));
- EXPECT_EQ(input1.size(), ProcessInput(input1));
- EXPECT_THAT(decoder_.error(), IsQuicNoError());
- EXPECT_EQ("", decoder_.error_detail());
-
- // Process the frame incrementally.
- EXPECT_CALL(visitor_, OnAcceptChFrameStart(3));
- EXPECT_CALL(visitor_, OnAcceptChFrame(accept_ch1));
- ProcessInputCharByChar(input1);
- EXPECT_THAT(decoder_.error(), IsQuicNoError());
- EXPECT_EQ("", decoder_.error_detail());
-
- std::string input2 = absl::HexStringToBytes(
- "4089" // type (ACCEPT_CH)
- "08" // length
- "03" // length of origin
- "666f6f" // origin "foo"
- "03" // length of value
- "626172"); // value "bar"
-
- AcceptChFrame accept_ch2;
- accept_ch2.entries.push_back({"foo", "bar"});
-
- // Visitor pauses processing.
- EXPECT_CALL(visitor_, OnAcceptChFrameStart(3)).WillOnce(Return(false));
- remaining_input = input2;
- processed_bytes = ProcessInputWithGarbageAppended(remaining_input);
- EXPECT_EQ(3u, processed_bytes);
- remaining_input = remaining_input.substr(processed_bytes);
-
- EXPECT_CALL(visitor_, OnAcceptChFrame(accept_ch2)).WillOnce(Return(false));
- processed_bytes = ProcessInputWithGarbageAppended(remaining_input);
- EXPECT_EQ(remaining_input.size(), processed_bytes);
- EXPECT_THAT(decoder_.error(), IsQuicNoError());
- EXPECT_EQ("", decoder_.error_detail());
-
- // Process the full frame.
- EXPECT_CALL(visitor_, OnAcceptChFrameStart(3));
- EXPECT_CALL(visitor_, OnAcceptChFrame(accept_ch2));
- EXPECT_EQ(input2.size(), ProcessInput(input2));
- EXPECT_THAT(decoder_.error(), IsQuicNoError());
- EXPECT_EQ("", decoder_.error_detail());
-
- // Process the frame incrementally.
- EXPECT_CALL(visitor_, OnAcceptChFrameStart(3));
- EXPECT_CALL(visitor_, OnAcceptChFrame(accept_ch2));
- ProcessInputCharByChar(input2);
- EXPECT_THAT(decoder_.error(), IsQuicNoError());
- EXPECT_EQ("", decoder_.error_detail());
-}
-
-TEST_F(HttpDecoderTest, WebTransportStreamDisabled) {
- InSequence s;
-
- // Unknown frame of type 0x41 and length 0x104.
- std::string input = absl::HexStringToBytes("40414104");
- EXPECT_CALL(visitor_, OnUnknownFrameStart(0x41, input.size(), 0x104));
- EXPECT_EQ(ProcessInput(input), input.size());
-}
-
-TEST(HttpDecoderTestNoFixture, WebTransportStream) {
- HttpDecoder::Options options;
- options.allow_web_transport_stream = true;
- testing::StrictMock<MockHttpDecoderVisitor> visitor;
- HttpDecoder decoder(&visitor, options);
-
- // WebTransport stream for session ID 0x104, with four bytes of extra data.
- std::string input = absl::HexStringToBytes("40414104ffffffff");
- EXPECT_CALL(visitor, OnWebTransportStreamFrameType(4, 0x104));
- QuicByteCount bytes = decoder.ProcessInput(input.data(), input.size());
- EXPECT_EQ(bytes, 4u);
-}
-
-TEST(HttpDecoderTestNoFixture, WebTransportStreamError) {
- HttpDecoder::Options options;
- options.allow_web_transport_stream = true;
- testing::StrictMock<MockHttpDecoderVisitor> visitor;
- HttpDecoder decoder(&visitor, options);
-
- std::string input = absl::HexStringToBytes("404100");
- 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");
-}
-
-TEST_F(HttpDecoderTest, DecodeSettings) {
- std::string input = absl::HexStringToBytes(
- "04" // type (SETTINGS)
- "07" // length
- "01" // identifier (SETTINGS_QPACK_MAX_TABLE_CAPACITY)
- "02" // content
- "06" // identifier (SETTINGS_MAX_HEADER_LIST_SIZE)
- "05" // content
- "4100" // identifier, encoded on 2 bytes (0x40), value is 256 (0x100)
- "04"); // content
-
- SettingsFrame frame;
- frame.values[1] = 2;
- frame.values[6] = 5;
- frame.values[256] = 4;
-
- SettingsFrame out;
- EXPECT_TRUE(HttpDecoder::DecodeSettings(input.data(), input.size(), &out));
- EXPECT_EQ(frame, out);
-
- // non-settings frame.
- input = absl::HexStringToBytes(
- "0D" // type (MAX_PUSH_ID)
- "01" // length
- "01"); // Push Id
-
- EXPECT_FALSE(HttpDecoder::DecodeSettings(input.data(), input.size(), &out));
-
- // Corrupt SETTINGS.
- input = absl::HexStringToBytes(
- "04" // type (SETTINGS)
- "01" // length
- "42"); // First byte of setting identifier, indicating a 2-byte varint62.
-
- EXPECT_FALSE(HttpDecoder::DecodeSettings(input.data(), input.size(), &out));
-}
-
-} // namespace
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/http/http_encoder.cc b/chromium/net/third_party/quiche/src/quic/core/http/http_encoder.cc
deleted file mode 100644
index 25f6200e59b..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/http/http_encoder.cc
+++ /dev/null
@@ -1,279 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/http/http_encoder.h"
-#include <cstdint>
-#include <memory>
-
-#include "quic/core/crypto/quic_random.h"
-#include "quic/core/quic_data_writer.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_flag_utils.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-namespace {
-
-bool WriteFrameHeader(QuicByteCount length,
- HttpFrameType type,
- QuicDataWriter* writer) {
- return writer->WriteVarInt62(static_cast<uint64_t>(type)) &&
- writer->WriteVarInt62(length);
-}
-
-QuicByteCount GetTotalLength(QuicByteCount payload_length, HttpFrameType type) {
- return QuicDataWriter::GetVarInt62Len(payload_length) +
- QuicDataWriter::GetVarInt62Len(static_cast<uint64_t>(type)) +
- payload_length;
-}
-
-} // namespace
-
-// static
-QuicByteCount HttpEncoder::GetDataFrameHeaderLength(
- QuicByteCount payload_length) {
- QUICHE_DCHECK_NE(0u, payload_length);
- return QuicDataWriter::GetVarInt62Len(payload_length) +
- QuicDataWriter::GetVarInt62Len(
- static_cast<uint64_t>(HttpFrameType::DATA));
-}
-
-// static
-QuicBuffer HttpEncoder::SerializeDataFrameHeader(
- QuicByteCount payload_length,
- QuicBufferAllocator* allocator) {
- QUICHE_DCHECK_NE(0u, payload_length);
- QuicByteCount header_length = GetDataFrameHeaderLength(payload_length);
-
- QuicBuffer header(allocator, header_length);
- QuicDataWriter writer(header.size(), header.data());
-
- if (WriteFrameHeader(payload_length, HttpFrameType::DATA, &writer)) {
- return header;
- }
- QUIC_DLOG(ERROR)
- << "Http encoder failed when attempting to serialize data frame header.";
- return QuicBuffer();
-}
-
-// static
-QuicByteCount HttpEncoder::SerializeHeadersFrameHeader(
- QuicByteCount payload_length,
- std::unique_ptr<char[]>* output) {
- QUICHE_DCHECK_NE(0u, payload_length);
- QuicByteCount header_length =
- QuicDataWriter::GetVarInt62Len(payload_length) +
- QuicDataWriter::GetVarInt62Len(
- static_cast<uint64_t>(HttpFrameType::HEADERS));
-
- output->reset(new char[header_length]);
- QuicDataWriter writer(header_length, output->get());
-
- if (WriteFrameHeader(payload_length, HttpFrameType::HEADERS, &writer)) {
- return header_length;
- }
- QUIC_DLOG(ERROR)
- << "Http encoder failed when attempting to serialize headers "
- "frame header.";
- return 0;
-}
-
-// static
-QuicByteCount HttpEncoder::SerializeSettingsFrame(
- const SettingsFrame& settings,
- std::unique_ptr<char[]>* output) {
- QuicByteCount payload_length = 0;
- std::vector<std::pair<uint64_t, uint64_t>> ordered_settings{
- settings.values.begin(), settings.values.end()};
- std::sort(ordered_settings.begin(), ordered_settings.end());
- // Calculate the payload length.
- for (const auto& p : ordered_settings) {
- payload_length += QuicDataWriter::GetVarInt62Len(p.first);
- payload_length += QuicDataWriter::GetVarInt62Len(p.second);
- }
-
- QuicByteCount total_length =
- GetTotalLength(payload_length, HttpFrameType::SETTINGS);
-
- output->reset(new char[total_length]);
- QuicDataWriter writer(total_length, output->get());
-
- if (!WriteFrameHeader(payload_length, HttpFrameType::SETTINGS, &writer)) {
- QUIC_DLOG(ERROR) << "Http encoder failed when attempting to serialize "
- "settings frame header.";
- return 0;
- }
-
- for (const auto& p : ordered_settings) {
- if (!writer.WriteVarInt62(p.first) || !writer.WriteVarInt62(p.second)) {
- QUIC_DLOG(ERROR) << "Http encoder failed when attempting to serialize "
- "settings frame payload.";
- return 0;
- }
- }
-
- return total_length;
-}
-
-// static
-QuicByteCount HttpEncoder::SerializeGoAwayFrame(
- const GoAwayFrame& goaway,
- std::unique_ptr<char[]>* output) {
- QuicByteCount payload_length = QuicDataWriter::GetVarInt62Len(goaway.id);
- QuicByteCount total_length =
- GetTotalLength(payload_length, HttpFrameType::GOAWAY);
-
- output->reset(new char[total_length]);
- QuicDataWriter writer(total_length, output->get());
-
- if (WriteFrameHeader(payload_length, HttpFrameType::GOAWAY, &writer) &&
- writer.WriteVarInt62(goaway.id)) {
- return total_length;
- }
- QUIC_DLOG(ERROR)
- << "Http encoder failed when attempting to serialize goaway frame.";
- return 0;
-}
-
-// static
-QuicByteCount HttpEncoder::SerializePriorityUpdateFrame(
- const PriorityUpdateFrame& priority_update,
- std::unique_ptr<char[]>* output) {
- if (priority_update.prioritized_element_type != REQUEST_STREAM) {
- QUIC_BUG(quic_bug_10402_1)
- << "PRIORITY_UPDATE for push streams not implemented";
- return 0;
- }
-
- QuicByteCount payload_length =
- QuicDataWriter::GetVarInt62Len(priority_update.prioritized_element_id) +
- priority_update.priority_field_value.size();
- QuicByteCount total_length = GetTotalLength(
- payload_length, HttpFrameType::PRIORITY_UPDATE_REQUEST_STREAM);
-
- output->reset(new char[total_length]);
- QuicDataWriter writer(total_length, output->get());
-
- if (WriteFrameHeader(payload_length,
- HttpFrameType::PRIORITY_UPDATE_REQUEST_STREAM,
- &writer) &&
- writer.WriteVarInt62(priority_update.prioritized_element_id) &&
- writer.WriteBytes(priority_update.priority_field_value.data(),
- priority_update.priority_field_value.size())) {
- return total_length;
- }
-
- QUIC_DLOG(ERROR) << "Http encoder failed when attempting to serialize "
- "PRIORITY_UPDATE frame.";
- return 0;
-}
-
-// static
-QuicByteCount HttpEncoder::SerializeAcceptChFrame(
- const AcceptChFrame& accept_ch,
- std::unique_ptr<char[]>* output) {
- QuicByteCount payload_length = 0;
- for (const auto& entry : accept_ch.entries) {
- payload_length += QuicDataWriter::GetVarInt62Len(entry.origin.size());
- payload_length += entry.origin.size();
- payload_length += QuicDataWriter::GetVarInt62Len(entry.value.size());
- payload_length += entry.value.size();
- }
-
- QuicByteCount total_length =
- GetTotalLength(payload_length, HttpFrameType::ACCEPT_CH);
-
- output->reset(new char[total_length]);
- QuicDataWriter writer(total_length, output->get());
-
- if (!WriteFrameHeader(payload_length, HttpFrameType::ACCEPT_CH, &writer)) {
- QUIC_DLOG(ERROR)
- << "Http encoder failed to serialize ACCEPT_CH frame header.";
- return 0;
- }
-
- for (const auto& entry : accept_ch.entries) {
- if (!writer.WriteStringPieceVarInt62(entry.origin) ||
- !writer.WriteStringPieceVarInt62(entry.value)) {
- QUIC_DLOG(ERROR)
- << "Http encoder failed to serialize ACCEPT_CH frame payload.";
- return 0;
- }
- }
-
- return total_length;
-}
-
-// static
-QuicByteCount HttpEncoder::SerializeGreasingFrame(
- std::unique_ptr<char[]>* output) {
- uint64_t frame_type;
- QuicByteCount payload_length;
- std::string payload;
- if (!GetQuicFlag(FLAGS_quic_enable_http3_grease_randomness)) {
- frame_type = 0x40;
- payload_length = 1;
- payload = "a";
- } else {
- uint32_t result;
- QuicRandom::GetInstance()->RandBytes(&result, sizeof(result));
- frame_type = 0x1fULL * static_cast<uint64_t>(result) + 0x21ULL;
-
- // The payload length is random but within [0, 3];
- payload_length = result % 4;
-
- if (payload_length > 0) {
- std::unique_ptr<char[]> buffer(new char[payload_length]);
- QuicRandom::GetInstance()->RandBytes(buffer.get(), payload_length);
- payload = std::string(buffer.get(), payload_length);
- }
- }
- QuicByteCount total_length = QuicDataWriter::GetVarInt62Len(frame_type) +
- QuicDataWriter::GetVarInt62Len(payload_length) +
- payload_length;
-
- output->reset(new char[total_length]);
- QuicDataWriter writer(total_length, output->get());
-
- bool success =
- writer.WriteVarInt62(frame_type) && writer.WriteVarInt62(payload_length);
-
- if (payload_length > 0) {
- success &= writer.WriteBytes(payload.data(), payload_length);
- }
-
- if (success) {
- return total_length;
- }
-
- QUIC_DLOG(ERROR) << "Http encoder failed when attempting to serialize "
- "greasing frame.";
- return 0;
-}
-
-QuicByteCount HttpEncoder::SerializeWebTransportStreamFrameHeader(
- WebTransportSessionId session_id,
- std::unique_ptr<char[]>* output) {
- uint64_t stream_type =
- static_cast<uint64_t>(HttpFrameType::WEBTRANSPORT_STREAM);
- QuicByteCount header_length = QuicDataWriter::GetVarInt62Len(stream_type) +
- QuicDataWriter::GetVarInt62Len(session_id);
-
- *output = std::make_unique<char[]>(header_length);
- QuicDataWriter writer(header_length, output->get());
- bool success =
- writer.WriteVarInt62(stream_type) && writer.WriteVarInt62(session_id);
- if (success && writer.remaining() == 0) {
- return header_length;
- }
-
- QUIC_DLOG(ERROR) << "Http encoder failed when attempting to serialize "
- "WEBTRANSPORT_STREAM frame header.";
- return 0;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/http/http_encoder.h b/chromium/net/third_party/quiche/src/quic/core/http/http_encoder.h
deleted file mode 100644
index 585e739ef53..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/http/http_encoder.h
+++ /dev/null
@@ -1,73 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_HTTP_HTTP_ENCODER_H_
-#define QUICHE_QUIC_CORE_HTTP_HTTP_ENCODER_H_
-
-#include <memory>
-#include "quic/core/http/http_frames.h"
-#include "quic/core/quic_buffer_allocator.h"
-#include "quic/core/quic_error_codes.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-class QuicDataWriter;
-
-// A class for encoding the HTTP frames that are exchanged in an HTTP over QUIC
-// session.
-class QUIC_EXPORT_PRIVATE HttpEncoder {
- public:
- HttpEncoder() = delete;
-
- // Returns the length of the header for a DATA frame.
- static QuicByteCount GetDataFrameHeaderLength(QuicByteCount payload_length);
-
- // Serializes a DATA frame header into a QuicBuffer; returns said QuicBuffer
- // on success, empty buffer otherwise.
- static QuicBuffer SerializeDataFrameHeader(QuicByteCount payload_length,
- QuicBufferAllocator* allocator);
-
- // Serializes a HEADERS frame header into a new buffer stored in |output|.
- // Returns the length of the buffer on success, or 0 otherwise.
- static QuicByteCount SerializeHeadersFrameHeader(
- QuicByteCount payload_length,
- std::unique_ptr<char[]>* output);
-
- // Serializes a SETTINGS frame into a new buffer stored in |output|.
- // Returns the length of the buffer on success, or 0 otherwise.
- static QuicByteCount SerializeSettingsFrame(const SettingsFrame& settings,
- std::unique_ptr<char[]>* output);
-
- // Serializes a GOAWAY frame into a new buffer stored in |output|.
- // Returns the length of the buffer on success, or 0 otherwise.
- static QuicByteCount SerializeGoAwayFrame(const GoAwayFrame& goaway,
- std::unique_ptr<char[]>* output);
-
- // Serializes a PRIORITY_UPDATE frame into a new buffer stored in |output|.
- // Returns the length of the buffer on success, or 0 otherwise.
- static QuicByteCount SerializePriorityUpdateFrame(
- const PriorityUpdateFrame& priority_update,
- std::unique_ptr<char[]>* output);
-
- // Serializes an ACCEPT_CH frame into a new buffer stored in |output|.
- // Returns the length of the buffer on success, or 0 otherwise.
- static QuicByteCount SerializeAcceptChFrame(const AcceptChFrame& accept_ch,
- std::unique_ptr<char[]>* output);
-
- // Serializes a frame with reserved frame type specified in
- // https://tools.ietf.org/html/draft-ietf-quic-http-25#section-7.2.9.
- static QuicByteCount SerializeGreasingFrame(std::unique_ptr<char[]>* output);
-
- // Serializes a WEBTRANSPORT_STREAM frame header as specified in
- // https://www.ietf.org/archive/id/draft-ietf-webtrans-http3-00.html#name-client-initiated-bidirectio
- static QuicByteCount SerializeWebTransportStreamFrameHeader(
- WebTransportSessionId session_id,
- std::unique_ptr<char[]>* output);
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_HTTP_HTTP_ENCODER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/http/http_encoder_test.cc b/chromium/net/third_party/quiche/src/quic/core/http/http_encoder_test.cc
deleted file mode 100644
index c2b0f36946e..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/http/http_encoder_test.cc
+++ /dev/null
@@ -1,142 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/http/http_encoder.h"
-
-#include "absl/base/macros.h"
-#include "quic/core/quic_simple_buffer_allocator.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/quic_test_utils.h"
-#include "common/test_tools/quiche_test_utils.h"
-
-namespace quic {
-namespace test {
-
-TEST(HttpEncoderTest, SerializeDataFrameHeader) {
- QuicBuffer buffer = HttpEncoder::SerializeDataFrameHeader(
- /* payload_length = */ 5, SimpleBufferAllocator::Get());
- char output[] = {// type (DATA)
- 0x00,
- // length
- 0x05};
- EXPECT_EQ(ABSL_ARRAYSIZE(output), buffer.size());
- quiche::test::CompareCharArraysWithHexError(
- "DATA", buffer.data(), buffer.size(), output, ABSL_ARRAYSIZE(output));
-}
-
-TEST(HttpEncoderTest, SerializeHeadersFrameHeader) {
- std::unique_ptr<char[]> buffer;
- uint64_t length = HttpEncoder::SerializeHeadersFrameHeader(
- /* payload_length = */ 7, &buffer);
- char output[] = {// type (HEADERS)
- 0x01,
- // length
- 0x07};
- EXPECT_EQ(ABSL_ARRAYSIZE(output), length);
- quiche::test::CompareCharArraysWithHexError("HEADERS", buffer.get(), length,
- output, ABSL_ARRAYSIZE(output));
-}
-
-TEST(HttpEncoderTest, SerializeSettingsFrame) {
- SettingsFrame settings;
- settings.values[1] = 2;
- settings.values[6] = 5;
- settings.values[256] = 4;
- char output[] = {// type (SETTINGS)
- 0x04,
- // length
- 0x07,
- // identifier (SETTINGS_QPACK_MAX_TABLE_CAPACITY)
- 0x01,
- // content
- 0x02,
- // identifier (SETTINGS_MAX_HEADER_LIST_SIZE)
- 0x06,
- // content
- 0x05,
- // identifier (256 in variable length integer)
- 0x40 + 0x01, 0x00,
- // content
- 0x04};
- std::unique_ptr<char[]> buffer;
- uint64_t length = HttpEncoder::SerializeSettingsFrame(settings, &buffer);
- EXPECT_EQ(ABSL_ARRAYSIZE(output), length);
- quiche::test::CompareCharArraysWithHexError("SETTINGS", buffer.get(), length,
- output, ABSL_ARRAYSIZE(output));
-}
-
-TEST(HttpEncoderTest, SerializeGoAwayFrame) {
- GoAwayFrame goaway;
- goaway.id = 0x1;
- char output[] = {// type (GOAWAY)
- 0x07,
- // length
- 0x1,
- // ID
- 0x01};
- std::unique_ptr<char[]> buffer;
- uint64_t length = HttpEncoder::SerializeGoAwayFrame(goaway, &buffer);
- EXPECT_EQ(ABSL_ARRAYSIZE(output), length);
- quiche::test::CompareCharArraysWithHexError("GOAWAY", buffer.get(), length,
- output, ABSL_ARRAYSIZE(output));
-}
-
-TEST(HttpEncoderTest, SerializePriorityUpdateFrame) {
- PriorityUpdateFrame priority_update1;
- priority_update1.prioritized_element_type = REQUEST_STREAM;
- priority_update1.prioritized_element_id = 0x03;
- uint8_t output1[] = {0x80, 0x0f, 0x07, 0x00, // type (PRIORITY_UPDATE)
- 0x01, // length
- 0x03}; // prioritized element id
-
- std::unique_ptr<char[]> buffer;
- uint64_t length =
- HttpEncoder::SerializePriorityUpdateFrame(priority_update1, &buffer);
- EXPECT_EQ(ABSL_ARRAYSIZE(output1), length);
- quiche::test::CompareCharArraysWithHexError(
- "PRIORITY_UPDATE", buffer.get(), length, reinterpret_cast<char*>(output1),
- ABSL_ARRAYSIZE(output1));
-}
-
-TEST(HttpEncoderTest, SerializeAcceptChFrame) {
- AcceptChFrame accept_ch;
- uint8_t output1[] = {0x40, 0x89, // type (ACCEPT_CH)
- 0x00}; // length
-
- std::unique_ptr<char[]> buffer;
- uint64_t length = HttpEncoder::SerializeAcceptChFrame(accept_ch, &buffer);
- EXPECT_EQ(ABSL_ARRAYSIZE(output1), length);
- quiche::test::CompareCharArraysWithHexError("ACCEPT_CH", buffer.get(), length,
- reinterpret_cast<char*>(output1),
- ABSL_ARRAYSIZE(output1));
-
- accept_ch.entries.push_back({"foo", "bar"});
- uint8_t output2[] = {0x40, 0x89, // type (ACCEPT_CH)
- 0x08, // payload length
- 0x03, 0x66, 0x6f, 0x6f, // length of "foo"; "foo"
- 0x03, 0x62, 0x61, 0x72}; // length of "bar"; "bar"
-
- length = HttpEncoder::SerializeAcceptChFrame(accept_ch, &buffer);
- EXPECT_EQ(ABSL_ARRAYSIZE(output2), length);
- quiche::test::CompareCharArraysWithHexError("ACCEPT_CH", buffer.get(), length,
- reinterpret_cast<char*>(output2),
- ABSL_ARRAYSIZE(output2));
-}
-
-TEST(HttpEncoderTest, SerializeWebTransportStreamFrameHeader) {
- WebTransportSessionId session_id = 0x17;
- char output[] = {0x40, 0x41, // type (WEBTRANSPORT_STREAM)
- 0x17}; // session ID
-
- std::unique_ptr<char[]> buffer;
- uint64_t length =
- HttpEncoder::SerializeWebTransportStreamFrameHeader(session_id, &buffer);
- EXPECT_EQ(sizeof(output), length);
- quiche::test::CompareCharArraysWithHexError(
- "WEBTRANSPORT_STREAM", buffer.get(), length, output, sizeof(output));
-}
-
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/http/http_frames.h b/chromium/net/third_party/quiche/src/quic/core/http/http_frames.h
deleted file mode 100644
index 6a00ad7bb53..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/http/http_frames.h
+++ /dev/null
@@ -1,187 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_HTTP_HTTP_FRAMES_H_
-#define QUICHE_QUIC_CORE_HTTP_HTTP_FRAMES_H_
-
-#include <algorithm>
-#include <cstdint>
-#include <map>
-#include <ostream>
-#include <sstream>
-
-#include "absl/container/flat_hash_map.h"
-#include "absl/strings/str_cat.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/http/http_constants.h"
-#include "quic/core/quic_types.h"
-#include "spdy/core/spdy_protocol.h"
-
-namespace quic {
-
-// TODO(b/171463363): Remove.
-using PushId = uint64_t;
-
-enum class HttpFrameType {
- DATA = 0x0,
- HEADERS = 0x1,
- CANCEL_PUSH = 0X3,
- SETTINGS = 0x4,
- PUSH_PROMISE = 0x5,
- GOAWAY = 0x7,
- MAX_PUSH_ID = 0xD,
- // https://tools.ietf.org/html/draft-davidben-http-client-hint-reliability-02
- ACCEPT_CH = 0x89,
- // https://tools.ietf.org/html/draft-ietf-httpbis-priority-03
- PRIORITY_UPDATE_REQUEST_STREAM = 0xF0700,
- // https://www.ietf.org/archive/id/draft-ietf-webtrans-http3-00.html
- WEBTRANSPORT_STREAM = 0x41,
-};
-
-// 7.2.1. DATA
-//
-// DATA frames (type=0x0) convey arbitrary, variable-length sequences of
-// octets associated with an HTTP request or response payload.
-struct QUIC_EXPORT_PRIVATE DataFrame {
- absl::string_view data;
-};
-
-// 7.2.2. HEADERS
-//
-// The HEADERS frame (type=0x1) is used to carry a header block,
-// compressed using QPACK.
-struct QUIC_EXPORT_PRIVATE HeadersFrame {
- absl::string_view headers;
-};
-
-// 7.2.4. SETTINGS
-//
-// The SETTINGS frame (type=0x4) conveys configuration parameters that
-// affect how endpoints communicate, such as preferences and constraints
-// on peer behavior
-
-using SettingsMap = absl::flat_hash_map<uint64_t, uint64_t>;
-
-struct QUIC_EXPORT_PRIVATE SettingsFrame {
- SettingsMap values;
-
- bool operator==(const SettingsFrame& rhs) const {
- return values == rhs.values;
- }
-
- std::string ToString() const {
- std::string s;
- for (auto it : values) {
- std::string setting = absl::StrCat(
- H3SettingsToString(
- static_cast<Http3AndQpackSettingsIdentifiers>(it.first)),
- " = ", it.second, "; ");
- absl::StrAppend(&s, setting);
- }
- return s;
- }
- friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
- const SettingsFrame& s) {
- os << s.ToString();
- return os;
- }
-};
-
-// 7.2.6. GOAWAY
-//
-// The GOAWAY frame (type=0x7) is used to initiate shutdown of a connection by
-// either endpoint.
-struct QUIC_EXPORT_PRIVATE GoAwayFrame {
- // When sent from server to client, |id| is a stream ID that should refer to
- // a client-initiated bidirectional stream.
- // When sent from client to server, |id| is a push ID.
- uint64_t id;
-
- 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.
-// Frame type 0xf0700 (called PRIORITY_UPDATE_REQUEST_STREAM in the
-// implementation) is used for for request streams.
-// Frame type 0xf0701 is used for push streams and is not implemented.
-
-// Length of a priority frame's first byte.
-const QuicByteCount kPriorityFirstByteLength = 1;
-
-enum PrioritizedElementType : uint8_t {
- REQUEST_STREAM = 0x00,
- PUSH_STREAM = 0x80,
-};
-
-struct QUIC_EXPORT_PRIVATE PriorityUpdateFrame {
- PrioritizedElementType prioritized_element_type = REQUEST_STREAM;
- uint64_t prioritized_element_id = 0;
- std::string priority_field_value;
-
- bool operator==(const PriorityUpdateFrame& rhs) const {
- return std::tie(prioritized_element_type, prioritized_element_id,
- priority_field_value) ==
- std::tie(rhs.prioritized_element_type, rhs.prioritized_element_id,
- rhs.priority_field_value);
- }
- std::string ToString() const {
- return absl::StrCat("Priority Frame : {prioritized_element_type: ",
- static_cast<int>(prioritized_element_type),
- ", prioritized_element_id: ", prioritized_element_id,
- ", priority_field_value: ", priority_field_value, "}");
- }
-
- friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
- std::ostream& os,
- const PriorityUpdateFrame& s) {
- os << s.ToString();
- return os;
- }
-};
-
-// ACCEPT_CH
-// https://tools.ietf.org/html/draft-davidben-http-client-hint-reliability-02
-//
-struct QUIC_EXPORT_PRIVATE AcceptChFrame {
- std::vector<spdy::AcceptChOriginValuePair> entries;
-
- bool operator==(const AcceptChFrame& rhs) const {
- return entries.size() == rhs.entries.size() &&
- std::equal(entries.begin(), entries.end(), rhs.entries.begin());
- }
-
- std::string ToString() const {
- std::stringstream s;
- s << *this;
- return s.str();
- }
-
- friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
- std::ostream& os,
- const AcceptChFrame& frame) {
- os << "ACCEPT_CH frame with " << frame.entries.size() << " entries: ";
- for (auto& entry : frame.entries) {
- os << "origin: " << entry.origin << "; value: " << entry.value;
- }
- return os;
- }
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_HTTP_HTTP_FRAMES_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/http/http_frames_test.cc b/chromium/net/third_party/quiche/src/quic/core/http/http_frames_test.cc
deleted file mode 100644
index 24fd5780af8..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/http/http_frames_test.cc
+++ /dev/null
@@ -1,105 +0,0 @@
-// Copyright (c) 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/http/http_frames.h"
-
-#include <sstream>
-
-#include "quic/core/http/http_constants.h"
-#include "quic/platform/api/quic_test.h"
-
-namespace quic {
-namespace test {
-
-TEST(HttpFramesTest, SettingsFrame) {
- SettingsFrame a;
- EXPECT_TRUE(a == a);
- EXPECT_EQ("", a.ToString());
-
- SettingsFrame b;
- b.values[SETTINGS_QPACK_MAX_TABLE_CAPACITY] = 1;
- EXPECT_FALSE(a == b);
- EXPECT_TRUE(b == b);
-
- a.values[SETTINGS_QPACK_MAX_TABLE_CAPACITY] = 2;
- EXPECT_FALSE(a == b);
- a.values[SETTINGS_QPACK_MAX_TABLE_CAPACITY] = 1;
- EXPECT_TRUE(a == b);
-
- EXPECT_EQ("SETTINGS_QPACK_MAX_TABLE_CAPACITY = 1; ", b.ToString());
- std::stringstream s;
- s << b;
- EXPECT_EQ("SETTINGS_QPACK_MAX_TABLE_CAPACITY = 1; ", s.str());
-}
-
-TEST(HttpFramesTest, GoAwayFrame) {
- GoAwayFrame a{1};
- EXPECT_TRUE(a == a);
-
- GoAwayFrame b{2};
- EXPECT_FALSE(a == b);
-
- b.id = 1;
- 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);
- PriorityUpdateFrame b{REQUEST_STREAM, 4, ""};
- EXPECT_FALSE(a == b);
- a.prioritized_element_id = 4;
- EXPECT_TRUE(a == b);
-
- a.prioritized_element_type = PUSH_STREAM;
- EXPECT_FALSE(a == b);
- b.prioritized_element_type = PUSH_STREAM;
- EXPECT_TRUE(a == b);
-
- a.priority_field_value = "foo";
- EXPECT_FALSE(a == b);
-
- EXPECT_EQ(
- "Priority Frame : {prioritized_element_type: 128, "
- "prioritized_element_id: 4, priority_field_value: foo}",
- a.ToString());
- std::stringstream s;
- s << a;
- EXPECT_EQ(
- "Priority Frame : {prioritized_element_type: 128, "
- "prioritized_element_id: 4, priority_field_value: foo}",
- s.str());
-}
-
-TEST(HttpFramesTest, AcceptChFrame) {
- AcceptChFrame a;
- EXPECT_TRUE(a == a);
- EXPECT_EQ("ACCEPT_CH frame with 0 entries: ", a.ToString());
-
- AcceptChFrame b{{{"foo", "bar"}}};
- EXPECT_FALSE(a == b);
-
- a.entries.push_back({"foo", "bar"});
- EXPECT_TRUE(a == b);
-
- EXPECT_EQ("ACCEPT_CH frame with 1 entries: origin: foo; value: bar",
- a.ToString());
- std::stringstream s;
- s << a;
- EXPECT_EQ("ACCEPT_CH frame with 1 entries: origin: foo; value: bar", s.str());
-}
-
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/http/quic_client_promised_info.cc b/chromium/net/third_party/quiche/src/quic/core/http/quic_client_promised_info.cc
deleted file mode 100644
index 1c951ba108b..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/http/quic_client_promised_info.cc
+++ /dev/null
@@ -1,147 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/http/quic_client_promised_info.h"
-
-#include <string>
-#include <utility>
-
-#include "quic/core/http/spdy_server_push_utils.h"
-#include "quic/platform/api/quic_logging.h"
-#include "spdy/core/spdy_protocol.h"
-
-using spdy::SpdyHeaderBlock;
-
-namespace quic {
-
-QuicClientPromisedInfo::QuicClientPromisedInfo(
- QuicSpdyClientSessionBase* session,
- QuicStreamId id,
- std::string url)
- : session_(session),
- id_(id),
- url_(std::move(url)),
- client_request_delegate_(nullptr) {}
-
-QuicClientPromisedInfo::~QuicClientPromisedInfo() {
- if (cleanup_alarm_ != nullptr) {
- cleanup_alarm_->PermanentCancel();
- }
-}
-
-void QuicClientPromisedInfo::CleanupAlarm::OnAlarm() {
- QUIC_DVLOG(1) << "self GC alarm for stream " << promised_->id_;
- promised_->session()->OnPushStreamTimedOut(promised_->id_);
- promised_->Reset(QUIC_PUSH_STREAM_TIMED_OUT);
-}
-
-void QuicClientPromisedInfo::Init() {
- cleanup_alarm_.reset(session_->connection()->alarm_factory()->CreateAlarm(
- new QuicClientPromisedInfo::CleanupAlarm(this)));
- cleanup_alarm_->Set(
- session_->connection()->helper()->GetClock()->ApproximateNow() +
- QuicTime::Delta::FromSeconds(kPushPromiseTimeoutSecs));
-}
-
-bool QuicClientPromisedInfo::OnPromiseHeaders(const SpdyHeaderBlock& headers) {
- // RFC7540, Section 8.2, requests MUST be safe [RFC7231], Section
- // 4.2.1. GET and HEAD are the methods that are safe and required.
- SpdyHeaderBlock::const_iterator it = headers.find(spdy::kHttp2MethodHeader);
- if (it == headers.end()) {
- QUIC_DVLOG(1) << "Promise for stream " << id_ << " has no method";
- Reset(QUIC_INVALID_PROMISE_METHOD);
- return false;
- }
- if (!(it->second == "GET" || it->second == "HEAD")) {
- QUIC_DVLOG(1) << "Promise for stream " << id_ << " has invalid method "
- << it->second;
- Reset(QUIC_INVALID_PROMISE_METHOD);
- return false;
- }
- if (!SpdyServerPushUtils::PromisedUrlIsValid(headers)) {
- QUIC_DVLOG(1) << "Promise for stream " << id_ << " has invalid URL "
- << url_;
- Reset(QUIC_INVALID_PROMISE_URL);
- return false;
- }
- if (!session_->IsAuthorized(
- SpdyServerPushUtils::GetPromisedHostNameFromHeaders(headers))) {
- Reset(QUIC_UNAUTHORIZED_PROMISE_URL);
- return false;
- }
- request_headers_ = headers.Clone();
- return true;
-}
-
-void QuicClientPromisedInfo::OnResponseHeaders(const SpdyHeaderBlock& headers) {
- response_headers_ = std::make_unique<SpdyHeaderBlock>(headers.Clone());
- if (client_request_delegate_) {
- // We already have a client request waiting.
- FinalValidation();
- }
-}
-
-void QuicClientPromisedInfo::Reset(QuicRstStreamErrorCode error_code) {
- QuicClientPushPromiseIndex::Delegate* delegate = client_request_delegate_;
- session_->ResetPromised(id_, error_code);
- session_->DeletePromised(this);
- if (delegate) {
- delegate->OnRendezvousResult(nullptr);
- }
-}
-
-QuicAsyncStatus QuicClientPromisedInfo::FinalValidation() {
- if (!client_request_delegate_->CheckVary(
- client_request_headers_, request_headers_, *response_headers_)) {
- Reset(QUIC_PROMISE_VARY_MISMATCH);
- return QUIC_FAILURE;
- }
- QuicSpdyStream* stream = session_->GetPromisedStream(id_);
- if (!stream) {
- // This shouldn't be possible, as |ClientRequest| guards against
- // closed stream for the synchronous case. And in the
- // asynchronous case, a RST can only be caught by |OnAlarm()|.
- QUIC_BUG(quic_bug_10378_1) << "missing promised stream" << id_;
- }
- QuicClientPushPromiseIndex::Delegate* delegate = client_request_delegate_;
- session_->DeletePromised(this);
- // Stream can start draining now
- if (delegate) {
- delegate->OnRendezvousResult(stream);
- }
- return QUIC_SUCCESS;
-}
-
-QuicAsyncStatus QuicClientPromisedInfo::HandleClientRequest(
- const SpdyHeaderBlock& request_headers,
- QuicClientPushPromiseIndex::Delegate* delegate) {
- if (session_->IsClosedStream(id_)) {
- // There was a RST on the response stream.
- session_->DeletePromised(this);
- return QUIC_FAILURE;
- }
-
- if (is_validating()) {
- // The push promise has already been matched to another request though
- // pending for validation. Returns QUIC_FAILURE to the caller as it couldn't
- // match a new request any more. This will not affect the validation of the
- // other request.
- return QUIC_FAILURE;
- }
-
- client_request_delegate_ = delegate;
- client_request_headers_ = request_headers.Clone();
- if (response_headers_ == nullptr) {
- return QUIC_PENDING;
- }
- return FinalValidation();
-}
-
-void QuicClientPromisedInfo::Cancel() {
- // Don't fire OnRendezvousResult() for client initiated cancel.
- client_request_delegate_ = nullptr;
- Reset(QUIC_STREAM_CANCELLED);
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/http/quic_client_promised_info.h b/chromium/net/third_party/quiche/src/quic/core/http/quic_client_promised_info.h
deleted file mode 100644
index ec071f09c3f..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/http/quic_client_promised_info.h
+++ /dev/null
@@ -1,115 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_HTTP_QUIC_CLIENT_PROMISED_INFO_H_
-#define QUICHE_QUIC_CORE_HTTP_QUIC_CLIENT_PROMISED_INFO_H_
-
-#include <cstddef>
-#include <string>
-
-#include "quic/core/http/quic_client_push_promise_index.h"
-#include "quic/core/http/quic_spdy_client_session_base.h"
-#include "quic/core/http/quic_spdy_stream.h"
-#include "quic/core/quic_alarm.h"
-#include "quic/core/quic_packets.h"
-#include "quic/platform/api/quic_export.h"
-#include "spdy/core/spdy_framer.h"
-
-namespace quic {
-
-namespace test {
-class QuicClientPromisedInfoPeer;
-} // namespace test
-
-// QuicClientPromisedInfo tracks the client state of a server push
-// stream from the time a PUSH_PROMISE is received until rendezvous
-// between the promised response and the corresponding client request
-// is complete.
-class QUIC_EXPORT_PRIVATE QuicClientPromisedInfo
- : public QuicClientPushPromiseIndex::TryHandle {
- public:
- // Interface to QuicSpdyClientStream
- QuicClientPromisedInfo(QuicSpdyClientSessionBase* session,
- QuicStreamId id,
- std::string url);
- QuicClientPromisedInfo(const QuicClientPromisedInfo&) = delete;
- QuicClientPromisedInfo& operator=(const QuicClientPromisedInfo&) = delete;
- virtual ~QuicClientPromisedInfo();
-
- void Init();
-
- // Validate promise headers etc. Returns true if headers are valid.
- bool OnPromiseHeaders(const spdy::SpdyHeaderBlock& headers);
-
- // Store response, possibly proceed with final validation.
- void OnResponseHeaders(const spdy::SpdyHeaderBlock& headers);
-
- // Rendezvous between this promised stream and a client request that
- // has a matching URL.
- virtual QuicAsyncStatus HandleClientRequest(
- const spdy::SpdyHeaderBlock& headers,
- QuicClientPushPromiseIndex::Delegate* delegate);
-
- void Cancel() override;
-
- void Reset(QuicRstStreamErrorCode error_code);
-
- // Client requests are initially associated to promises by matching
- // URL in the client request against the URL in the promise headers,
- // uing the |promised_by_url| map. The push can be cross-origin, so
- // the client should validate that the session is authoritative for
- // the promised URL. If not, it should call |RejectUnauthorized|.
- QuicSpdyClientSessionBase* session() { return session_; }
-
- // If the promised response contains Vary header, then the fields
- // specified by Vary must match between the client request header
- // and the promise headers (see https://crbug.com//554220). Vary
- // validation requires the response headers (for the actual Vary
- // field list), the promise headers (taking the role of the "cached"
- // request), and the client request headers.
- spdy::SpdyHeaderBlock* request_headers() { return &request_headers_; }
-
- spdy::SpdyHeaderBlock* response_headers() { return response_headers_.get(); }
-
- // After validation, client will use this to access the pushed stream.
-
- QuicStreamId id() const { return id_; }
-
- const std::string url() const { return url_; }
-
- // Return true if there's a request pending matching this push promise.
- bool is_validating() const { return client_request_delegate_ != nullptr; }
-
- private:
- friend class test::QuicClientPromisedInfoPeer;
-
- class QUIC_EXPORT_PRIVATE CleanupAlarm
- : public QuicAlarm::DelegateWithoutContext {
- public:
- explicit CleanupAlarm(QuicClientPromisedInfo* promised)
- : promised_(promised) {}
-
- void OnAlarm() override;
-
- QuicClientPromisedInfo* promised_;
- };
-
- QuicAsyncStatus FinalValidation();
-
- QuicSpdyClientSessionBase* session_;
- QuicStreamId id_;
- std::string url_;
- spdy::SpdyHeaderBlock request_headers_;
- std::unique_ptr<spdy::SpdyHeaderBlock> response_headers_;
- spdy::SpdyHeaderBlock client_request_headers_;
- QuicClientPushPromiseIndex::Delegate* client_request_delegate_;
-
- // The promise will commit suicide eventually if it is not claimed by a GET
- // first.
- std::unique_ptr<QuicAlarm> cleanup_alarm_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_HTTP_QUIC_CLIENT_PROMISED_INFO_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/http/quic_client_promised_info_test.cc b/chromium/net/third_party/quiche/src/quic/core/http/quic_client_promised_info_test.cc
deleted file mode 100644
index 2f2b2a4125b..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/http/quic_client_promised_info_test.cc
+++ /dev/null
@@ -1,356 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/http/quic_client_promised_info.h"
-
-#include <memory>
-#include <string>
-#include <utility>
-
-#include "quic/core/crypto/null_encrypter.h"
-#include "quic/core/http/quic_spdy_client_session.h"
-#include "quic/core/http/spdy_server_push_utils.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/platform/api/quic_socket_address.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/crypto_test_utils.h"
-#include "quic/test_tools/quic_client_promised_info_peer.h"
-#include "quic/test_tools/quic_spdy_session_peer.h"
-#include "quic/test_tools/quic_test_utils.h"
-
-using spdy::SpdyHeaderBlock;
-using testing::_;
-using testing::StrictMock;
-
-namespace quic {
-namespace test {
-namespace {
-
-class MockQuicSpdyClientSession : public QuicSpdyClientSession {
- public:
- explicit MockQuicSpdyClientSession(
- const ParsedQuicVersionVector& supported_versions,
- QuicConnection* connection,
- QuicClientPushPromiseIndex* push_promise_index)
- : QuicSpdyClientSession(DefaultQuicConfig(),
- supported_versions,
- connection,
- QuicServerId("example.com", 443, false),
- &crypto_config_,
- push_promise_index),
- crypto_config_(crypto_test_utils::ProofVerifierForTesting()),
- authorized_(true) {}
- MockQuicSpdyClientSession(const MockQuicSpdyClientSession&) = delete;
- MockQuicSpdyClientSession& operator=(const MockQuicSpdyClientSession&) =
- delete;
- ~MockQuicSpdyClientSession() override {}
-
- bool IsAuthorized(const std::string& /*authority*/) override {
- return authorized_;
- }
-
- void set_authorized(bool authorized) { authorized_ = authorized; }
-
- MOCK_METHOD(bool,
- WriteControlFrame,
- (const QuicFrame& frame, TransmissionType type),
- (override));
-
- private:
- QuicCryptoClientConfig crypto_config_;
-
- bool authorized_;
-};
-
-class QuicClientPromisedInfoTest : public QuicTest {
- public:
- class StreamVisitor;
-
- QuicClientPromisedInfoTest()
- : connection_(new StrictMock<MockQuicConnection>(&helper_,
- &alarm_factory_,
- Perspective::IS_CLIENT)),
- session_(connection_->supported_versions(),
- connection_,
- &push_promise_index_),
- body_("hello world"),
- promise_id_(
- QuicUtils::GetInvalidStreamId(connection_->transport_version())) {
- connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
- connection_->SetEncrypter(
- ENCRYPTION_FORWARD_SECURE,
- std::make_unique<NullEncrypter>(connection_->perspective()));
- session_.Initialize();
-
- headers_[":status"] = "200";
- headers_["content-length"] = "11";
-
- stream_ = std::make_unique<QuicSpdyClientStream>(
- GetNthClientInitiatedBidirectionalStreamId(
- connection_->transport_version(), 0),
- &session_, BIDIRECTIONAL);
- stream_visitor_ = std::make_unique<StreamVisitor>();
- stream_->set_visitor(stream_visitor_.get());
-
- push_promise_[":path"] = "/bar";
- push_promise_[":authority"] = "www.google.com";
- push_promise_[":method"] = "GET";
- push_promise_[":scheme"] = "https";
-
- promise_url_ =
- SpdyServerPushUtils::GetPromisedUrlFromHeaders(push_promise_);
-
- client_request_ = push_promise_.Clone();
- promise_id_ = GetNthServerInitiatedUnidirectionalStreamId(
- connection_->transport_version(), 0);
- }
-
- class StreamVisitor : public QuicSpdyClientStream::Visitor {
- void OnClose(QuicSpdyStream* stream) override {
- QUIC_DVLOG(1) << "stream " << stream->id();
- }
- };
-
- void ReceivePromise(QuicStreamId id) {
- auto headers = AsHeaderList(push_promise_);
- stream_->OnPromiseHeaderList(id, headers.uncompressed_header_bytes(),
- headers);
- }
-
- MockQuicConnectionHelper helper_;
- MockAlarmFactory alarm_factory_;
- StrictMock<MockQuicConnection>* connection_;
- QuicClientPushPromiseIndex push_promise_index_;
-
- MockQuicSpdyClientSession session_;
- std::unique_ptr<QuicSpdyClientStream> stream_;
- std::unique_ptr<StreamVisitor> stream_visitor_;
- std::unique_ptr<QuicSpdyClientStream> promised_stream_;
- SpdyHeaderBlock headers_;
- std::string body_;
- SpdyHeaderBlock push_promise_;
- QuicStreamId promise_id_;
- std::string promise_url_;
- SpdyHeaderBlock client_request_;
-};
-
-TEST_F(QuicClientPromisedInfoTest, PushPromise) {
- ReceivePromise(promise_id_);
-
- // Verify that the promise is in the unclaimed streams map.
- EXPECT_NE(session_.GetPromisedById(promise_id_), nullptr);
-}
-
-TEST_F(QuicClientPromisedInfoTest, PushPromiseCleanupAlarm) {
- ReceivePromise(promise_id_);
-
- // Verify that the promise is in the unclaimed streams map.
- QuicClientPromisedInfo* promised = session_.GetPromisedById(promise_id_);
- ASSERT_NE(promised, nullptr);
-
- // Fire the alarm that will cancel the promised stream.
- EXPECT_CALL(session_, WriteControlFrame(_, _));
- EXPECT_CALL(*connection_,
- OnStreamReset(promise_id_, QUIC_PUSH_STREAM_TIMED_OUT));
- alarm_factory_.FireAlarm(QuicClientPromisedInfoPeer::GetAlarm(promised));
-
- // Verify that the promise is gone after the alarm fires.
- EXPECT_EQ(session_.GetPromisedById(promise_id_), nullptr);
- EXPECT_EQ(session_.GetPromisedByUrl(promise_url_), nullptr);
-}
-
-TEST_F(QuicClientPromisedInfoTest, PushPromiseInvalidMethod) {
- // Promise with an unsafe method
- push_promise_[":method"] = "PUT";
-
- EXPECT_CALL(session_, WriteControlFrame(_, _));
- EXPECT_CALL(*connection_,
- OnStreamReset(promise_id_, QUIC_INVALID_PROMISE_METHOD));
- ReceivePromise(promise_id_);
-
- // Verify that the promise headers were ignored
- EXPECT_EQ(session_.GetPromisedById(promise_id_), nullptr);
- EXPECT_EQ(session_.GetPromisedByUrl(promise_url_), nullptr);
-}
-
-TEST_F(QuicClientPromisedInfoTest, PushPromiseMissingMethod) {
- // Promise with a missing method
- push_promise_.erase(":method");
-
- EXPECT_CALL(session_, WriteControlFrame(_, _));
- EXPECT_CALL(*connection_,
- OnStreamReset(promise_id_, QUIC_INVALID_PROMISE_METHOD));
- ReceivePromise(promise_id_);
-
- // Verify that the promise headers were ignored
- EXPECT_EQ(session_.GetPromisedById(promise_id_), nullptr);
- EXPECT_EQ(session_.GetPromisedByUrl(promise_url_), nullptr);
-}
-
-TEST_F(QuicClientPromisedInfoTest, PushPromiseInvalidUrl) {
- // Remove required header field to make URL invalid
- push_promise_.erase(":authority");
-
- EXPECT_CALL(session_, WriteControlFrame(_, _));
- EXPECT_CALL(*connection_,
- OnStreamReset(promise_id_, QUIC_INVALID_PROMISE_URL));
- ReceivePromise(promise_id_);
-
- // Verify that the promise headers were ignored
- EXPECT_EQ(session_.GetPromisedById(promise_id_), nullptr);
- EXPECT_EQ(session_.GetPromisedByUrl(promise_url_), nullptr);
-}
-
-TEST_F(QuicClientPromisedInfoTest, PushPromiseUnauthorizedUrl) {
- session_.set_authorized(false);
-
- EXPECT_CALL(session_, WriteControlFrame(_, _));
- EXPECT_CALL(*connection_,
- OnStreamReset(promise_id_, QUIC_UNAUTHORIZED_PROMISE_URL));
-
- ReceivePromise(promise_id_);
-
- QuicClientPromisedInfo* promised = session_.GetPromisedById(promise_id_);
- ASSERT_EQ(promised, nullptr);
-}
-
-TEST_F(QuicClientPromisedInfoTest, PushPromiseMismatch) {
- ReceivePromise(promise_id_);
-
- QuicClientPromisedInfo* promised = session_.GetPromisedById(promise_id_);
- ASSERT_NE(promised, nullptr);
-
- // Need to send the promised response headers and initiate the
- // rendezvous for secondary validation to proceed.
- QuicSpdyClientStream* promise_stream = static_cast<QuicSpdyClientStream*>(
- session_.GetOrCreateStream(promise_id_));
- auto headers = AsHeaderList(headers_);
- promise_stream->OnStreamHeaderList(false, headers.uncompressed_header_bytes(),
- headers);
-
- TestPushPromiseDelegate delegate(/*match=*/false);
- EXPECT_CALL(session_, WriteControlFrame(_, _));
- EXPECT_CALL(*connection_,
- OnStreamReset(promise_id_, QUIC_PROMISE_VARY_MISMATCH));
-
- promised->HandleClientRequest(client_request_, &delegate);
-}
-
-TEST_F(QuicClientPromisedInfoTest, PushPromiseVaryWaits) {
- ReceivePromise(promise_id_);
-
- QuicClientPromisedInfo* promised = session_.GetPromisedById(promise_id_);
- EXPECT_FALSE(promised->is_validating());
- ASSERT_NE(promised, nullptr);
-
- // Now initiate rendezvous.
- TestPushPromiseDelegate delegate(/*match=*/true);
- promised->HandleClientRequest(client_request_, &delegate);
- EXPECT_TRUE(promised->is_validating());
-
- // Promise is still there, waiting for response.
- EXPECT_NE(session_.GetPromisedById(promise_id_), nullptr);
-
- // Send Response, should trigger promise validation and complete rendezvous
- QuicSpdyClientStream* promise_stream = static_cast<QuicSpdyClientStream*>(
- session_.GetOrCreateStream(promise_id_));
- ASSERT_NE(promise_stream, nullptr);
- auto headers = AsHeaderList(headers_);
- promise_stream->OnStreamHeaderList(false, headers.uncompressed_header_bytes(),
- headers);
-
- // Promise is gone
- EXPECT_EQ(session_.GetPromisedById(promise_id_), nullptr);
-}
-
-TEST_F(QuicClientPromisedInfoTest, PushPromiseVaryNoWait) {
- ReceivePromise(promise_id_);
-
- QuicClientPromisedInfo* promised = session_.GetPromisedById(promise_id_);
- ASSERT_NE(promised, nullptr);
-
- QuicSpdyClientStream* promise_stream = static_cast<QuicSpdyClientStream*>(
- session_.GetOrCreateStream(promise_id_));
- ASSERT_NE(promise_stream, nullptr);
-
- // Send Response, should trigger promise validation and complete rendezvous
- auto headers = AsHeaderList(headers_);
- promise_stream->OnStreamHeaderList(false, headers.uncompressed_header_bytes(),
- headers);
-
- // Now initiate rendezvous.
- TestPushPromiseDelegate delegate(/*match=*/true);
- promised->HandleClientRequest(client_request_, &delegate);
-
- // Promise is gone
- EXPECT_EQ(session_.GetPromisedById(promise_id_), nullptr);
- // Have a push stream
- EXPECT_TRUE(delegate.rendezvous_fired());
-
- EXPECT_NE(delegate.rendezvous_stream(), nullptr);
-}
-
-TEST_F(QuicClientPromisedInfoTest, PushPromiseWaitCancels) {
- ReceivePromise(promise_id_);
-
- QuicClientPromisedInfo* promised = session_.GetPromisedById(promise_id_);
- ASSERT_NE(promised, nullptr);
-
- // Now initiate rendezvous.
- TestPushPromiseDelegate delegate(/*match=*/true);
- promised->HandleClientRequest(client_request_, &delegate);
-
- // Promise is still there, waiting for response.
- EXPECT_NE(session_.GetPromisedById(promise_id_), nullptr);
-
- // Create response stream, but no data yet.
- session_.GetOrCreateStream(promise_id_);
-
- // Cancel the promised stream.
- EXPECT_CALL(session_, WriteControlFrame(_, _));
- EXPECT_CALL(*connection_, OnStreamReset(promise_id_, QUIC_STREAM_CANCELLED));
- promised->Cancel();
-
- // Promise is gone
- EXPECT_EQ(session_.GetPromisedById(promise_id_), nullptr);
-}
-
-TEST_F(QuicClientPromisedInfoTest, PushPromiseDataClosed) {
- ReceivePromise(promise_id_);
-
- QuicClientPromisedInfo* promised = session_.GetPromisedById(promise_id_);
- ASSERT_NE(promised, nullptr);
-
- QuicSpdyClientStream* promise_stream = static_cast<QuicSpdyClientStream*>(
- session_.GetOrCreateStream(promise_id_));
- ASSERT_NE(promise_stream, nullptr);
-
- // Send response, rendezvous will be able to finish synchronously.
- auto headers = AsHeaderList(headers_);
- promise_stream->OnStreamHeaderList(false, headers.uncompressed_header_bytes(),
- headers);
-
- EXPECT_CALL(session_, WriteControlFrame(_, _));
- EXPECT_CALL(*connection_,
- OnStreamReset(promise_id_, QUIC_STREAM_PEER_GOING_AWAY));
- session_.ResetStream(promise_id_, QUIC_STREAM_PEER_GOING_AWAY);
-
- // Now initiate rendezvous.
- TestPushPromiseDelegate delegate(/*match=*/true);
- EXPECT_EQ(promised->HandleClientRequest(client_request_, &delegate),
- QUIC_FAILURE);
-
- // Got an indication of the stream failure, client should retry
- // request.
- EXPECT_FALSE(delegate.rendezvous_fired());
- EXPECT_EQ(delegate.rendezvous_stream(), nullptr);
-
- // Promise is gone
- EXPECT_EQ(session_.GetPromisedById(promise_id_), nullptr);
-}
-
-} // namespace
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/http/quic_client_push_promise_index.cc b/chromium/net/third_party/quiche/src/quic/core/http/quic_client_push_promise_index.cc
deleted file mode 100644
index 79e4f31c863..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/http/quic_client_push_promise_index.cc
+++ /dev/null
@@ -1,48 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/http/quic_client_push_promise_index.h"
-
-#include <string>
-
-#include "quic/core/http/quic_client_promised_info.h"
-#include "quic/core/http/spdy_server_push_utils.h"
-
-using spdy::SpdyHeaderBlock;
-
-namespace quic {
-
-QuicClientPushPromiseIndex::QuicClientPushPromiseIndex() {}
-
-QuicClientPushPromiseIndex::~QuicClientPushPromiseIndex() {}
-
-QuicClientPushPromiseIndex::TryHandle::~TryHandle() {}
-
-QuicClientPromisedInfo* QuicClientPushPromiseIndex::GetPromised(
- const std::string& url) {
- auto it = promised_by_url_.find(url);
- if (it == promised_by_url_.end()) {
- return nullptr;
- }
- return it->second;
-}
-
-QuicAsyncStatus QuicClientPushPromiseIndex::Try(
- const spdy::SpdyHeaderBlock& request,
- QuicClientPushPromiseIndex::Delegate* delegate,
- TryHandle** handle) {
- std::string url(SpdyServerPushUtils::GetPromisedUrlFromHeaders(request));
- auto it = promised_by_url_.find(url);
- if (it != promised_by_url_.end()) {
- QuicClientPromisedInfo* promised = it->second;
- QuicAsyncStatus rv = promised->HandleClientRequest(request, delegate);
- if (rv == QUIC_PENDING) {
- *handle = promised;
- }
- return rv;
- }
- return QUIC_FAILURE;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/http/quic_client_push_promise_index.h b/chromium/net/third_party/quiche/src/quic/core/http/quic_client_push_promise_index.h
deleted file mode 100644
index de070e6ef5e..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/http/quic_client_push_promise_index.h
+++ /dev/null
@@ -1,99 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_HTTP_QUIC_CLIENT_PUSH_PROMISE_INDEX_H_
-#define QUICHE_QUIC_CORE_HTTP_QUIC_CLIENT_PUSH_PROMISE_INDEX_H_
-
-#include <string>
-
-#include "quic/core/http/quic_spdy_client_session_base.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// QuicClientPushPromiseIndex is the interface to support rendezvous
-// between client requests and resources delivered via server push.
-// The same index can be shared across multiple sessions (e.g. for the
-// same browser users profile), since cross-origin pushes are allowed
-// (subject to authority constraints).
-
-class QUIC_EXPORT_PRIVATE QuicClientPushPromiseIndex {
- public:
- // Delegate is used to complete the rendezvous that began with
- // |Try()|.
- class QUIC_EXPORT_PRIVATE Delegate {
- public:
- virtual ~Delegate() {}
-
- // The primary lookup matched request with push promise by URL. A
- // secondary match is necessary to ensure Vary (RFC 2616, 14.14)
- // is honored. If Vary is not present, return true. If Vary is
- // present, return whether designated header fields of
- // |promise_request| and |client_request| match.
- virtual bool CheckVary(const spdy::SpdyHeaderBlock& client_request,
- const spdy::SpdyHeaderBlock& promise_request,
- const spdy::SpdyHeaderBlock& promise_response) = 0;
-
- // On rendezvous success, provides the promised |stream|. Callee
- // does not inherit ownership of |stream|. On rendezvous failure,
- // |stream| is |nullptr| and the client should retry the request.
- // Rendezvous can fail due to promise validation failure or RST on
- // promised stream. |url| will have been removed from the index
- // before |OnRendezvousResult()| is invoked, so a recursive call to
- // |Try()| will return |QUIC_FAILURE|, which may be convenient for
- // retry purposes.
- virtual void OnRendezvousResult(QuicSpdyStream* stream) = 0;
- };
-
- class QUIC_EXPORT_PRIVATE TryHandle {
- public:
- // Cancel the request.
- virtual void Cancel() = 0;
-
- protected:
- TryHandle() {}
- TryHandle(const TryHandle&) = delete;
- TryHandle& operator=(const TryHandle&) = delete;
- ~TryHandle();
- };
-
- QuicClientPushPromiseIndex();
- QuicClientPushPromiseIndex(const QuicClientPushPromiseIndex&) = delete;
- QuicClientPushPromiseIndex& operator=(const QuicClientPushPromiseIndex&) =
- delete;
- virtual ~QuicClientPushPromiseIndex();
-
- // Called by client code, used to enforce affinity between requests
- // for promised streams and the session the promise came from.
- QuicClientPromisedInfo* GetPromised(const std::string& url);
-
- // Called by client code, to initiate rendezvous between a request
- // and a server push stream. If |request|'s url is in the index,
- // rendezvous will be attempted and may complete immediately or
- // asynchronously. If the matching promise and response headers
- // have already arrived, the delegate's methods will fire
- // recursively from within |Try()|. Returns |QUIC_SUCCESS| if the
- // rendezvous was a success. Returns |QUIC_FAILURE| if there was no
- // matching promise, or if there was but the rendezvous has failed.
- // Returns QUIC_PENDING if a matching promise was found, but the
- // rendezvous needs to complete asynchronously because the promised
- // response headers are not yet available. If result is
- // QUIC_PENDING, then |*handle| will set so that the caller may
- // cancel the request if need be. The caller does not inherit
- // ownership of |*handle|, and it ceases to be valid if the caller
- // invokes |handle->Cancel()| or if |delegate->OnReponse()| fires.
- QuicAsyncStatus Try(const spdy::SpdyHeaderBlock& request,
- Delegate* delegate,
- TryHandle** handle);
-
- QuicPromisedByUrlMap* promised_by_url() { return &promised_by_url_; }
-
- private:
- QuicPromisedByUrlMap promised_by_url_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_HTTP_QUIC_CLIENT_PUSH_PROMISE_INDEX_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/http/quic_client_push_promise_index_test.cc b/chromium/net/third_party/quiche/src/quic/core/http/quic_client_push_promise_index_test.cc
deleted file mode 100644
index 03f4eb7183a..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/http/quic_client_push_promise_index_test.cc
+++ /dev/null
@@ -1,113 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/http/quic_client_push_promise_index.h"
-
-#include <string>
-
-#include "quic/core/http/quic_spdy_client_session.h"
-#include "quic/core/http/spdy_server_push_utils.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/crypto_test_utils.h"
-#include "quic/test_tools/mock_quic_client_promised_info.h"
-#include "quic/test_tools/quic_spdy_session_peer.h"
-#include "quic/test_tools/quic_test_utils.h"
-
-using testing::_;
-using testing::Return;
-using testing::StrictMock;
-
-namespace quic {
-namespace test {
-namespace {
-
-class MockQuicSpdyClientSession : public QuicSpdyClientSession {
- public:
- explicit MockQuicSpdyClientSession(
- const ParsedQuicVersionVector& supported_versions,
- QuicConnection* connection,
- QuicClientPushPromiseIndex* push_promise_index)
- : QuicSpdyClientSession(DefaultQuicConfig(),
- supported_versions,
- connection,
- QuicServerId("example.com", 443, false),
- &crypto_config_,
- push_promise_index),
- crypto_config_(crypto_test_utils::ProofVerifierForTesting()) {}
- MockQuicSpdyClientSession(const MockQuicSpdyClientSession&) = delete;
- MockQuicSpdyClientSession& operator=(const MockQuicSpdyClientSession&) =
- delete;
- ~MockQuicSpdyClientSession() override {}
-
- private:
- QuicCryptoClientConfig crypto_config_;
-};
-
-class QuicClientPushPromiseIndexTest : public QuicTest {
- public:
- QuicClientPushPromiseIndexTest()
- : connection_(new StrictMock<MockQuicConnection>(&helper_,
- &alarm_factory_,
- Perspective::IS_CLIENT)),
- session_(connection_->supported_versions(), connection_, &index_),
- promised_(&session_,
- GetNthServerInitiatedUnidirectionalStreamId(
- connection_->transport_version(),
- 0),
- url_) {
- request_[":path"] = "/bar";
- request_[":authority"] = "www.google.com";
- request_[":method"] = "GET";
- request_[":scheme"] = "https";
- url_ = SpdyServerPushUtils::GetPromisedUrlFromHeaders(request_);
- }
-
- MockQuicConnectionHelper helper_;
- MockAlarmFactory alarm_factory_;
- StrictMock<MockQuicConnection>* connection_;
- MockQuicSpdyClientSession session_;
- QuicClientPushPromiseIndex index_;
- spdy::SpdyHeaderBlock request_;
- std::string url_;
- MockQuicClientPromisedInfo promised_;
- QuicClientPushPromiseIndex::TryHandle* handle_;
-};
-
-TEST_F(QuicClientPushPromiseIndexTest, TryRequestSuccess) {
- (*index_.promised_by_url())[url_] = &promised_;
- EXPECT_CALL(promised_, HandleClientRequest(_, _))
- .WillOnce(Return(QUIC_SUCCESS));
- EXPECT_EQ(index_.Try(request_, nullptr, &handle_), QUIC_SUCCESS);
-}
-
-TEST_F(QuicClientPushPromiseIndexTest, TryRequestPending) {
- (*index_.promised_by_url())[url_] = &promised_;
- EXPECT_CALL(promised_, HandleClientRequest(_, _))
- .WillOnce(Return(QUIC_PENDING));
- EXPECT_EQ(index_.Try(request_, nullptr, &handle_), QUIC_PENDING);
-}
-
-TEST_F(QuicClientPushPromiseIndexTest, TryRequestFailure) {
- (*index_.promised_by_url())[url_] = &promised_;
- EXPECT_CALL(promised_, HandleClientRequest(_, _))
- .WillOnce(Return(QUIC_FAILURE));
- EXPECT_EQ(index_.Try(request_, nullptr, &handle_), QUIC_FAILURE);
-}
-
-TEST_F(QuicClientPushPromiseIndexTest, TryNoPromise) {
- EXPECT_EQ(index_.Try(request_, nullptr, &handle_), QUIC_FAILURE);
-}
-
-TEST_F(QuicClientPushPromiseIndexTest, GetNoPromise) {
- EXPECT_EQ(index_.GetPromised(url_), nullptr);
-}
-
-TEST_F(QuicClientPushPromiseIndexTest, GetPromise) {
- (*index_.promised_by_url())[url_] = &promised_;
- EXPECT_EQ(index_.GetPromised(url_), &promised_);
-}
-
-} // namespace
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/http/quic_header_list.cc b/chromium/net/third_party/quiche/src/quic/core/http/quic_header_list.cc
deleted file mode 100644
index 7ac768dcc05..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/http/quic_header_list.cc
+++ /dev/null
@@ -1,75 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/http/quic_header_list.h"
-
-#include <limits>
-#include <string>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/qpack/qpack_header_table.h"
-#include "quic/core/quic_packets.h"
-#include "quic/platform/api/quic_flags.h"
-
-namespace quic {
-
-QuicHeaderList::QuicHeaderList()
- : max_header_list_size_(std::numeric_limits<size_t>::max()),
- current_header_list_size_(0),
- uncompressed_header_bytes_(0),
- compressed_header_bytes_(0) {}
-
-QuicHeaderList::QuicHeaderList(QuicHeaderList&& other) = default;
-
-QuicHeaderList::QuicHeaderList(const QuicHeaderList& other) = default;
-
-QuicHeaderList& QuicHeaderList::operator=(const QuicHeaderList& other) =
- default;
-
-QuicHeaderList& QuicHeaderList::operator=(QuicHeaderList&& other) = default;
-
-QuicHeaderList::~QuicHeaderList() {}
-
-void QuicHeaderList::OnHeaderBlockStart() {
- QUIC_BUG_IF(quic_bug_12518_1, current_header_list_size_ != 0)
- << "OnHeaderBlockStart called more than once!";
-}
-
-void QuicHeaderList::OnHeader(absl::string_view name, absl::string_view value) {
- // Avoid infinite buffering of headers. No longer store headers
- // once the current headers are over the limit.
- if (current_header_list_size_ < max_header_list_size_) {
- current_header_list_size_ += name.size();
- current_header_list_size_ += value.size();
- current_header_list_size_ += kQpackEntrySizeOverhead;
- header_list_.emplace_back(std::string(name), std::string(value));
- }
-}
-
-void QuicHeaderList::OnHeaderBlockEnd(size_t uncompressed_header_bytes,
- size_t compressed_header_bytes) {
- uncompressed_header_bytes_ = uncompressed_header_bytes;
- compressed_header_bytes_ = compressed_header_bytes;
- if (current_header_list_size_ > max_header_list_size_) {
- Clear();
- }
-}
-
-void QuicHeaderList::Clear() {
- header_list_.clear();
- current_header_list_size_ = 0;
- uncompressed_header_bytes_ = 0;
- compressed_header_bytes_ = 0;
-}
-
-std::string QuicHeaderList::DebugString() const {
- std::string s = "{ ";
- for (const auto& p : *this) {
- s.append(p.first + "=" + p.second + ", ");
- }
- s.append("}");
- return s;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/http/quic_header_list.h b/chromium/net/third_party/quiche/src/quic/core/http/quic_header_list.h
deleted file mode 100644
index 01c861d5905..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/http/quic_header_list.h
+++ /dev/null
@@ -1,89 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_HTTP_QUIC_HEADER_LIST_H_
-#define QUICHE_QUIC_CORE_HTTP_QUIC_HEADER_LIST_H_
-
-#include <algorithm>
-#include <functional>
-#include <string>
-#include <utility>
-
-#include "absl/strings/string_view.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_export.h"
-#include "common/quiche_circular_deque.h"
-#include "spdy/core/spdy_header_block.h"
-#include "spdy/core/spdy_headers_handler_interface.h"
-
-namespace quic {
-
-// A simple class that accumulates header pairs
-class QUIC_EXPORT_PRIVATE QuicHeaderList
- : public spdy::SpdyHeadersHandlerInterface {
- public:
- using ListType =
- quiche::QuicheCircularDeque<std::pair<std::string, std::string>>;
- using value_type = ListType::value_type;
- using const_iterator = ListType::const_iterator;
-
- QuicHeaderList();
- QuicHeaderList(QuicHeaderList&& other);
- QuicHeaderList(const QuicHeaderList& other);
- QuicHeaderList& operator=(QuicHeaderList&& other);
- QuicHeaderList& operator=(const QuicHeaderList& other);
- ~QuicHeaderList() override;
-
- // From SpdyHeadersHandlerInteface.
- void OnHeaderBlockStart() override;
- void OnHeader(absl::string_view name, absl::string_view value) override;
- void OnHeaderBlockEnd(size_t uncompressed_header_bytes,
- size_t compressed_header_bytes) override;
-
- void Clear();
-
- const_iterator begin() const { return header_list_.begin(); }
- const_iterator end() const { return header_list_.end(); }
-
- bool empty() const { return header_list_.empty(); }
- size_t uncompressed_header_bytes() const {
- return uncompressed_header_bytes_;
- }
- size_t compressed_header_bytes() const { return compressed_header_bytes_; }
-
- // Deprecated. TODO(b/145909215): remove.
- void set_max_header_list_size(size_t max_header_list_size) {
- max_header_list_size_ = max_header_list_size;
- }
-
- std::string DebugString() const;
-
- private:
- quiche::QuicheCircularDeque<std::pair<std::string, std::string>> header_list_;
-
- // The limit on the size of the header list (defined by spec as name + value +
- // overhead for each header field). Headers over this limit will not be
- // buffered, and the list will be cleared upon OnHeaderBlockEnd.
- size_t max_header_list_size_;
-
- // Defined per the spec as the size of all header fields with an additional
- // overhead for each field.
- size_t current_header_list_size_;
-
- // TODO(dahollings) Are these fields necessary?
- size_t uncompressed_header_bytes_;
- size_t compressed_header_bytes_;
-};
-
-inline bool operator==(const QuicHeaderList& l1, const QuicHeaderList& l2) {
- auto pred = [](const std::pair<std::string, std::string>& p1,
- const std::pair<std::string, std::string>& p2) {
- return p1.first == p2.first && p1.second == p2.second;
- };
- return std::equal(l1.begin(), l1.end(), l2.begin(), pred);
-}
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_HTTP_QUIC_HEADER_LIST_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/http/quic_header_list_test.cc b/chromium/net/third_party/quiche/src/quic/core/http/quic_header_list_test.cc
deleted file mode 100644
index edd52dd91ae..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/http/quic_header_list_test.cc
+++ /dev/null
@@ -1,86 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/http/quic_header_list.h"
-
-#include <string>
-
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_test.h"
-
-using ::testing::ElementsAre;
-using ::testing::Pair;
-
-namespace quic {
-
-class QuicHeaderListTest : public QuicTest {};
-
-// This test verifies that QuicHeaderList accumulates header pairs in order.
-TEST_F(QuicHeaderListTest, OnHeader) {
- QuicHeaderList headers;
- headers.OnHeader("foo", "bar");
- headers.OnHeader("april", "fools");
- headers.OnHeader("beep", "");
-
- EXPECT_THAT(headers, ElementsAre(Pair("foo", "bar"), Pair("april", "fools"),
- Pair("beep", "")));
-}
-
-TEST_F(QuicHeaderListTest, DebugString) {
- QuicHeaderList headers;
- headers.OnHeader("foo", "bar");
- headers.OnHeader("april", "fools");
- headers.OnHeader("beep", "");
-
- EXPECT_EQ("{ foo=bar, april=fools, beep=, }", headers.DebugString());
-}
-
-TEST_F(QuicHeaderListTest, TooLarge) {
- const size_t kMaxHeaderListSize = 256;
-
- QuicHeaderList headers;
- headers.set_max_header_list_size(kMaxHeaderListSize);
- std::string key = "key";
- std::string value(kMaxHeaderListSize, '1');
- // Send a header that exceeds max_header_list_size.
- headers.OnHeader(key, value);
- // Send a second header exceeding max_header_list_size.
- headers.OnHeader(key + "2", value);
- // We should not allocate more memory after exceeding max_header_list_size.
- EXPECT_LT(headers.DebugString().size(), 2 * value.size());
- size_t total_bytes = 2 * (key.size() + value.size()) + 1;
- headers.OnHeaderBlockEnd(total_bytes, total_bytes);
-
- EXPECT_TRUE(headers.empty());
- EXPECT_EQ("{ }", headers.DebugString());
-}
-
-TEST_F(QuicHeaderListTest, NotTooLarge) {
- QuicHeaderList headers;
- headers.set_max_header_list_size(1 << 20);
- std::string key = "key";
- std::string value(1 << 18, '1');
- headers.OnHeader(key, value);
- size_t total_bytes = key.size() + value.size();
- headers.OnHeaderBlockEnd(total_bytes, total_bytes);
- EXPECT_FALSE(headers.empty());
-}
-
-// This test verifies that QuicHeaderList is copyable and assignable.
-TEST_F(QuicHeaderListTest, IsCopyableAndAssignable) {
- QuicHeaderList headers;
- headers.OnHeader("foo", "bar");
- headers.OnHeader("april", "fools");
- headers.OnHeader("beep", "");
-
- QuicHeaderList headers2(headers);
- QuicHeaderList headers3 = headers;
-
- EXPECT_THAT(headers2, ElementsAre(Pair("foo", "bar"), Pair("april", "fools"),
- Pair("beep", "")));
- EXPECT_THAT(headers3, ElementsAre(Pair("foo", "bar"), Pair("april", "fools"),
- Pair("beep", "")));
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/http/quic_headers_stream.cc b/chromium/net/third_party/quiche/src/quic/core/http/quic_headers_stream.cc
deleted file mode 100644
index 2b9f485a436..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/http/quic_headers_stream.cc
+++ /dev/null
@@ -1,164 +0,0 @@
-// Copyright 2013 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 "quic/core/http/quic_headers_stream.h"
-
-#include "absl/base/macros.h"
-#include "quic/core/http/quic_spdy_session.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_flag_utils.h"
-#include "quic/platform/api/quic_flags.h"
-
-namespace quic {
-
-QuicHeadersStream::CompressedHeaderInfo::CompressedHeaderInfo(
- QuicStreamOffset headers_stream_offset,
- QuicStreamOffset full_length,
- QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener)
- : headers_stream_offset(headers_stream_offset),
- full_length(full_length),
- unacked_length(full_length),
- ack_listener(std::move(ack_listener)) {}
-
-QuicHeadersStream::CompressedHeaderInfo::CompressedHeaderInfo(
- const CompressedHeaderInfo& other) = default;
-
-QuicHeadersStream::CompressedHeaderInfo::~CompressedHeaderInfo() {}
-
-QuicHeadersStream::QuicHeadersStream(QuicSpdySession* session)
- : QuicStream(QuicUtils::GetHeadersStreamId(session->transport_version()),
- session,
- /*is_static=*/true,
- BIDIRECTIONAL),
- spdy_session_(session) {
- // The headers stream is exempt from connection level flow control.
- DisableConnectionFlowControlForThisStream();
-}
-
-QuicHeadersStream::~QuicHeadersStream() {}
-
-void QuicHeadersStream::OnDataAvailable() {
- struct iovec iov;
- while (sequencer()->GetReadableRegion(&iov)) {
- if (spdy_session_->ProcessHeaderData(iov) != iov.iov_len) {
- // Error processing data.
- return;
- }
- sequencer()->MarkConsumed(iov.iov_len);
- MaybeReleaseSequencerBuffer();
- }
-}
-
-void QuicHeadersStream::MaybeReleaseSequencerBuffer() {
- if (spdy_session_->ShouldReleaseHeadersStreamSequencerBuffer()) {
- sequencer()->ReleaseBufferIfEmpty();
- }
-}
-
-bool QuicHeadersStream::OnStreamFrameAcked(QuicStreamOffset offset,
- QuicByteCount data_length,
- bool fin_acked,
- QuicTime::Delta ack_delay_time,
- QuicTime receive_timestamp,
- QuicByteCount* newly_acked_length) {
- QuicIntervalSet<QuicStreamOffset> newly_acked(offset, offset + data_length);
- newly_acked.Difference(bytes_acked());
- for (const auto& acked : newly_acked) {
- QuicStreamOffset acked_offset = acked.min();
- QuicByteCount acked_length = acked.max() - acked.min();
- for (CompressedHeaderInfo& header : unacked_headers_) {
- if (acked_offset < header.headers_stream_offset) {
- // This header frame offset belongs to headers with smaller offset, stop
- // processing.
- break;
- }
-
- if (acked_offset >= header.headers_stream_offset + header.full_length) {
- // This header frame belongs to headers with larger offset.
- continue;
- }
-
- QuicByteCount header_offset = acked_offset - header.headers_stream_offset;
- QuicByteCount header_length =
- std::min(acked_length, header.full_length - header_offset);
-
- if (header.unacked_length < header_length) {
- QUIC_BUG(quic_bug_10416_1)
- << "Unsent stream data is acked. unacked_length: "
- << header.unacked_length << " acked_length: " << header_length;
- OnUnrecoverableError(QUIC_INTERNAL_ERROR,
- "Unsent stream data is acked");
- return false;
- }
- if (header.ack_listener != nullptr && header_length > 0) {
- header.ack_listener->OnPacketAcked(header_length, ack_delay_time);
- }
- header.unacked_length -= header_length;
- acked_offset += header_length;
- acked_length -= header_length;
- }
- }
- // Remove headers which are fully acked. Please note, header frames can be
- // acked out of order, but unacked_headers_ is cleaned up in order.
- while (!unacked_headers_.empty() &&
- unacked_headers_.front().unacked_length == 0) {
- unacked_headers_.pop_front();
- }
- return QuicStream::OnStreamFrameAcked(offset, data_length, fin_acked,
- ack_delay_time, receive_timestamp,
- newly_acked_length);
-}
-
-void QuicHeadersStream::OnStreamFrameRetransmitted(QuicStreamOffset offset,
- QuicByteCount data_length,
- bool /*fin_retransmitted*/) {
- QuicStream::OnStreamFrameRetransmitted(offset, data_length, false);
- for (CompressedHeaderInfo& header : unacked_headers_) {
- if (offset < header.headers_stream_offset) {
- // This header frame offset belongs to headers with smaller offset, stop
- // processing.
- break;
- }
-
- if (offset >= header.headers_stream_offset + header.full_length) {
- // This header frame belongs to headers with larger offset.
- continue;
- }
-
- QuicByteCount header_offset = offset - header.headers_stream_offset;
- QuicByteCount retransmitted_length =
- std::min(data_length, header.full_length - header_offset);
- if (header.ack_listener != nullptr && retransmitted_length > 0) {
- header.ack_listener->OnPacketRetransmitted(retransmitted_length);
- }
- offset += retransmitted_length;
- data_length -= retransmitted_length;
- }
-}
-
-void QuicHeadersStream::OnDataBuffered(
- QuicStreamOffset offset,
- QuicByteCount data_length,
- const QuicReferenceCountedPointer<QuicAckListenerInterface>& ack_listener) {
- // Populate unacked_headers_.
- if (!unacked_headers_.empty() &&
- (offset == unacked_headers_.back().headers_stream_offset +
- unacked_headers_.back().full_length) &&
- ack_listener == unacked_headers_.back().ack_listener) {
- // Try to combine with latest inserted entry if they belong to the same
- // header (i.e., having contiguous offset and the same ack listener).
- unacked_headers_.back().full_length += data_length;
- unacked_headers_.back().unacked_length += data_length;
- } else {
- unacked_headers_.push_back(
- CompressedHeaderInfo(offset, data_length, ack_listener));
- }
-}
-
-void QuicHeadersStream::OnStreamReset(const QuicRstStreamFrame& /*frame*/) {
- stream_delegate()->OnStreamError(QUIC_INVALID_STREAM_ID,
- "Attempt to reset headers stream");
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/http/quic_headers_stream.h b/chromium/net/third_party/quiche/src/quic/core/http/quic_headers_stream.h
deleted file mode 100644
index 153575be1de..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/http/quic_headers_stream.h
+++ /dev/null
@@ -1,99 +0,0 @@
-// Copyright 2013 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_HTTP_QUIC_HEADERS_STREAM_H_
-#define QUICHE_QUIC_CORE_HTTP_QUIC_HEADERS_STREAM_H_
-
-#include <cstddef>
-#include <memory>
-
-#include "quic/core/http/quic_header_list.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_stream.h"
-#include "quic/platform/api/quic_containers.h"
-#include "quic/platform/api/quic_export.h"
-#include "spdy/core/spdy_framer.h"
-
-namespace quic {
-
-class QuicSpdySession;
-
-namespace test {
-class QuicHeadersStreamPeer;
-} // namespace test
-
-// Headers in QUIC are sent as HTTP/2 HEADERS or PUSH_PROMISE frames over a
-// reserved stream with the id 3. Each endpoint (client and server) will
-// allocate an instance of QuicHeadersStream to send and receive headers.
-class QUIC_EXPORT_PRIVATE QuicHeadersStream : public QuicStream {
- public:
- explicit QuicHeadersStream(QuicSpdySession* session);
- QuicHeadersStream(const QuicHeadersStream&) = delete;
- QuicHeadersStream& operator=(const QuicHeadersStream&) = delete;
- ~QuicHeadersStream() override;
-
- // QuicStream implementation
- void OnDataAvailable() override;
-
- // Release underlying buffer if allowed.
- void MaybeReleaseSequencerBuffer();
-
- bool OnStreamFrameAcked(QuicStreamOffset offset,
- QuicByteCount data_length,
- bool fin_acked,
- QuicTime::Delta ack_delay_time,
- QuicTime receive_timestamp,
- QuicByteCount* newly_acked_length) override;
-
- void OnStreamFrameRetransmitted(QuicStreamOffset offset,
- QuicByteCount data_length,
- bool fin_retransmitted) override;
-
- void OnStreamReset(const QuicRstStreamFrame& frame) override;
-
- private:
- friend class test::QuicHeadersStreamPeer;
-
- // CompressedHeaderInfo includes simple information of a header, including
- // offset in headers stream, unacked length and ack listener of this header.
- struct QUIC_EXPORT_PRIVATE CompressedHeaderInfo {
- CompressedHeaderInfo(
- QuicStreamOffset headers_stream_offset,
- QuicStreamOffset full_length,
- QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener);
- CompressedHeaderInfo(const CompressedHeaderInfo& other);
- ~CompressedHeaderInfo();
-
- // Offset the header was sent on the headers stream.
- QuicStreamOffset headers_stream_offset;
- // The full length of the header.
- QuicByteCount full_length;
- // The remaining bytes to be acked.
- QuicByteCount unacked_length;
- // Ack listener of this header, and it is notified once any of the bytes has
- // been acked or retransmitted.
- QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener;
- };
-
- // Returns true if the session is still connected.
- bool IsConnected();
-
- // Override to store mapping from offset, length to ack_listener. This
- // ack_listener is notified once data within [offset, offset + length] is
- // acked or retransmitted.
- void OnDataBuffered(
- QuicStreamOffset offset,
- QuicByteCount data_length,
- const QuicReferenceCountedPointer<QuicAckListenerInterface>& ack_listener)
- override;
-
- QuicSpdySession* spdy_session_;
-
- // Headers that have not been fully acked.
- quiche::QuicheCircularDeque<CompressedHeaderInfo> unacked_headers_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_HTTP_QUIC_HEADERS_STREAM_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/http/quic_headers_stream_test.cc b/chromium/net/third_party/quiche/src/quic/core/http/quic_headers_stream_test.cc
deleted file mode 100644
index 3a44f79a1d1..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/http/quic_headers_stream_test.cc
+++ /dev/null
@@ -1,953 +0,0 @@
-// Copyright 2013 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 "quic/core/http/quic_headers_stream.h"
-
-#include <cstdint>
-#include <ostream>
-#include <string>
-#include <tuple>
-#include <utility>
-#include <vector>
-
-#include "absl/strings/str_cat.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/crypto/null_encrypter.h"
-#include "quic/core/http/spdy_utils.h"
-#include "quic/core/quic_data_writer.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_expect_bug.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/quic_connection_peer.h"
-#include "quic/test_tools/quic_spdy_session_peer.h"
-#include "quic/test_tools/quic_stream_peer.h"
-#include "quic/test_tools/quic_test_utils.h"
-#include "common/quiche_endian.h"
-#include "spdy/core/http2_frame_decoder_adapter.h"
-#include "spdy/core/recording_headers_handler.h"
-#include "spdy/core/spdy_alt_svc_wire_format.h"
-#include "spdy/core/spdy_protocol.h"
-#include "spdy/core/spdy_test_utils.h"
-
-using spdy::ERROR_CODE_PROTOCOL_ERROR;
-using spdy::RecordingHeadersHandler;
-using spdy::SETTINGS_ENABLE_PUSH;
-using spdy::SETTINGS_HEADER_TABLE_SIZE;
-using spdy::SETTINGS_INITIAL_WINDOW_SIZE;
-using spdy::SETTINGS_MAX_CONCURRENT_STREAMS;
-using spdy::SETTINGS_MAX_FRAME_SIZE;
-using spdy::Spdy3PriorityToHttp2Weight;
-using spdy::SpdyAltSvcWireFormat;
-using spdy::SpdyDataIR;
-using spdy::SpdyErrorCode;
-using spdy::SpdyFramer;
-using spdy::SpdyFramerVisitorInterface;
-using spdy::SpdyGoAwayIR;
-using spdy::SpdyHeaderBlock;
-using spdy::SpdyHeadersHandlerInterface;
-using spdy::SpdyHeadersIR;
-using spdy::SpdyPingId;
-using spdy::SpdyPingIR;
-using spdy::SpdyPriority;
-using spdy::SpdyPriorityIR;
-using spdy::SpdyPushPromiseIR;
-using spdy::SpdyRstStreamIR;
-using spdy::SpdySerializedFrame;
-using spdy::SpdySettingsId;
-using spdy::SpdySettingsIR;
-using spdy::SpdyStreamId;
-using spdy::SpdyWindowUpdateIR;
-using testing::_;
-using testing::AnyNumber;
-using testing::AtLeast;
-using testing::InSequence;
-using testing::Invoke;
-using testing::Return;
-using testing::StrictMock;
-using testing::WithArgs;
-
-namespace quic {
-namespace test {
-namespace {
-
-class MockVisitor : public SpdyFramerVisitorInterface {
- public:
- MOCK_METHOD(void,
- OnError,
- (http2::Http2DecoderAdapter::SpdyFramerError error,
- std::string detailed_error),
- (override));
- MOCK_METHOD(void,
- OnDataFrameHeader,
- (SpdyStreamId stream_id, size_t length, bool fin),
- (override));
- MOCK_METHOD(void,
- OnStreamFrameData,
- (SpdyStreamId stream_id, const char*, size_t len),
- (override));
- MOCK_METHOD(void, OnStreamEnd, (SpdyStreamId stream_id), (override));
- MOCK_METHOD(void,
- OnStreamPadding,
- (SpdyStreamId stream_id, size_t len),
- (override));
- MOCK_METHOD(SpdyHeadersHandlerInterface*,
- OnHeaderFrameStart,
- (SpdyStreamId stream_id),
- (override));
- MOCK_METHOD(void, OnHeaderFrameEnd, (SpdyStreamId stream_id), (override));
- MOCK_METHOD(void,
- OnRstStream,
- (SpdyStreamId stream_id, SpdyErrorCode error_code),
- (override));
- MOCK_METHOD(void, OnSettings, (), (override));
- MOCK_METHOD(void, OnSetting, (SpdySettingsId id, uint32_t value), (override));
- MOCK_METHOD(void, OnSettingsAck, (), (override));
- MOCK_METHOD(void, OnSettingsEnd, (), (override));
- MOCK_METHOD(void, OnPing, (SpdyPingId unique_id, bool is_ack), (override));
- MOCK_METHOD(void,
- OnGoAway,
- (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),
- (override));
- MOCK_METHOD(void,
- OnWindowUpdate,
- (SpdyStreamId stream_id, int delta_window_size),
- (override));
- MOCK_METHOD(void,
- OnPushPromise,
- (SpdyStreamId stream_id,
- SpdyStreamId promised_stream_id,
- bool end),
- (override));
- MOCK_METHOD(void,
- OnContinuation,
- (SpdyStreamId stream_id, bool end),
- (override));
- MOCK_METHOD(
- void,
- OnAltSvc,
- (SpdyStreamId stream_id,
- absl::string_view origin,
- const SpdyAltSvcWireFormat::AlternativeServiceVector& altsvc_vector),
- (override));
- MOCK_METHOD(void,
- OnPriority,
- (SpdyStreamId stream_id,
- SpdyStreamId parent_stream_id,
- int weight,
- bool exclusive),
- (override));
- MOCK_METHOD(void,
- OnPriorityUpdate,
- (SpdyStreamId prioritized_stream_id,
- absl::string_view priority_field_value),
- (override));
- MOCK_METHOD(bool,
- OnUnknownFrame,
- (SpdyStreamId stream_id, uint8_t frame_type),
- (override));
-};
-
-struct TestParams {
- TestParams(const ParsedQuicVersion& version, Perspective perspective)
- : version(version), perspective(perspective) {
- QUIC_LOG(INFO) << "TestParams: " << *this;
- }
-
- TestParams(const TestParams& other)
- : version(other.version), perspective(other.perspective) {}
-
- friend std::ostream& operator<<(std::ostream& os, const TestParams& tp) {
- os << "{ version: " << ParsedQuicVersionToString(tp.version)
- << ", perspective: "
- << (tp.perspective == Perspective::IS_CLIENT ? "client" : "server")
- << "}";
- return os;
- }
-
- ParsedQuicVersion version;
- Perspective perspective;
-};
-
-// Used by ::testing::PrintToStringParamName().
-std::string PrintToString(const TestParams& tp) {
- return absl::StrCat(
- ParsedQuicVersionToString(tp.version), "_",
- (tp.perspective == Perspective::IS_CLIENT ? "client" : "server"));
-}
-
-std::vector<TestParams> GetTestParams() {
- std::vector<TestParams> params;
- ParsedQuicVersionVector all_supported_versions = AllSupportedVersions();
- for (size_t i = 0; i < all_supported_versions.size(); ++i) {
- if (VersionUsesHttp3(all_supported_versions[i].transport_version)) {
- continue;
- }
- for (Perspective p : {Perspective::IS_SERVER, Perspective::IS_CLIENT}) {
- params.emplace_back(all_supported_versions[i], p);
- }
- }
- return params;
-}
-
-class QuicHeadersStreamTest : public QuicTestWithParam<TestParams> {
- public:
- QuicHeadersStreamTest()
- : connection_(new StrictMock<MockQuicConnection>(&helper_,
- &alarm_factory_,
- perspective(),
- GetVersion())),
- session_(connection_),
- body_("hello world"),
- stream_frame_(
- QuicUtils::GetHeadersStreamId(connection_->transport_version()),
- /*fin=*/false,
- /*offset=*/0,
- ""),
- next_promised_stream_id_(2) {
- QuicSpdySessionPeer::SetMaxInboundHeaderListSize(&session_, 256 * 1024);
- EXPECT_CALL(session_, OnCongestionWindowChange(_)).Times(AnyNumber());
- session_.Initialize();
- connection_->SetEncrypter(
- quic::ENCRYPTION_FORWARD_SECURE,
- std::make_unique<quic::NullEncrypter>(connection_->perspective()));
- headers_stream_ = QuicSpdySessionPeer::GetHeadersStream(&session_);
- headers_[":status"] = "200 Ok";
- headers_["content-length"] = "11";
- framer_ = std::unique_ptr<SpdyFramer>(
- new SpdyFramer(SpdyFramer::ENABLE_COMPRESSION));
- deframer_ = std::unique_ptr<http2::Http2DecoderAdapter>(
- new http2::Http2DecoderAdapter());
- deframer_->set_visitor(&visitor_);
- EXPECT_EQ(transport_version(), session_.transport_version());
- EXPECT_TRUE(headers_stream_ != nullptr);
- connection_->AdvanceTime(QuicTime::Delta::FromMilliseconds(1));
- client_id_1_ = GetNthClientInitiatedBidirectionalStreamId(
- connection_->transport_version(), 0);
- client_id_2_ = GetNthClientInitiatedBidirectionalStreamId(
- connection_->transport_version(), 1);
- client_id_3_ = GetNthClientInitiatedBidirectionalStreamId(
- connection_->transport_version(), 2);
- next_stream_id_ =
- QuicUtils::StreamIdDelta(connection_->transport_version());
- }
-
- QuicStreamId GetNthClientInitiatedId(int n) {
- return GetNthClientInitiatedBidirectionalStreamId(
- connection_->transport_version(), n);
- }
-
- QuicConsumedData SaveIov(size_t write_length) {
- char* buf = new char[write_length];
- QuicDataWriter writer(write_length, buf, quiche::NETWORK_BYTE_ORDER);
- headers_stream_->WriteStreamData(headers_stream_->stream_bytes_written(),
- write_length, &writer);
- saved_data_.append(buf, write_length);
- delete[] buf;
- return QuicConsumedData(write_length, false);
- }
-
- void SavePayload(const char* data, size_t len) {
- saved_payloads_.append(data, len);
- }
-
- bool SaveHeaderData(const char* data, int len) {
- saved_header_data_.append(data, len);
- return true;
- }
-
- void SaveHeaderDataStringPiece(absl::string_view data) {
- saved_header_data_.append(data.data(), data.length());
- }
-
- void SavePromiseHeaderList(QuicStreamId /* stream_id */,
- QuicStreamId /* promised_stream_id */,
- size_t size,
- const QuicHeaderList& header_list) {
- SaveToHandler(size, header_list);
- }
-
- void SaveHeaderList(QuicStreamId /* stream_id */,
- bool /* fin */,
- size_t size,
- const QuicHeaderList& header_list) {
- SaveToHandler(size, header_list);
- }
-
- void SaveToHandler(size_t size, const QuicHeaderList& header_list) {
- headers_handler_ = std::make_unique<RecordingHeadersHandler>();
- headers_handler_->OnHeaderBlockStart();
- for (const auto& p : header_list) {
- headers_handler_->OnHeader(p.first, p.second);
- }
- headers_handler_->OnHeaderBlockEnd(size, size);
- }
-
- void WriteAndExpectRequestHeaders(QuicStreamId stream_id,
- bool fin,
- SpdyPriority priority) {
- WriteHeadersAndCheckData(stream_id, fin, priority, true /*is_request*/);
- }
-
- void WriteAndExpectResponseHeaders(QuicStreamId stream_id, bool fin) {
- WriteHeadersAndCheckData(stream_id, fin, 0, false /*is_request*/);
- }
-
- void WriteHeadersAndCheckData(QuicStreamId stream_id,
- bool fin,
- SpdyPriority priority,
- bool is_request) {
- // Write the headers and capture the outgoing data
- EXPECT_CALL(session_, WritevData(QuicUtils::GetHeadersStreamId(
- connection_->transport_version()),
- _, _, NO_FIN, _, _))
- .WillOnce(WithArgs<1>(Invoke(this, &QuicHeadersStreamTest::SaveIov)));
- QuicSpdySessionPeer::WriteHeadersOnHeadersStream(
- &session_, stream_id, headers_.Clone(), fin,
- spdy::SpdyStreamPrecedence(priority), nullptr);
-
- // 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));
- } else {
- EXPECT_CALL(visitor_,
- OnHeaders(stream_id, !kHasPriority,
- /*weight=*/0,
- /*parent_stream_id=*/0,
- /*exclusive=*/false, fin, kFrameComplete));
- }
- headers_handler_ = std::make_unique<RecordingHeadersHandler>();
- EXPECT_CALL(visitor_, OnHeaderFrameStart(stream_id))
- .WillOnce(Return(headers_handler_.get()));
- EXPECT_CALL(visitor_, OnHeaderFrameEnd(stream_id)).Times(1);
- if (fin) {
- EXPECT_CALL(visitor_, OnStreamEnd(stream_id));
- }
- deframer_->ProcessInput(saved_data_.data(), saved_data_.length());
- EXPECT_FALSE(deframer_->HasError())
- << http2::Http2DecoderAdapter::SpdyFramerErrorToString(
- deframer_->spdy_framer_error());
-
- CheckHeaders();
- saved_data_.clear();
- }
-
- void CheckHeaders() {
- ASSERT_TRUE(headers_handler_);
- EXPECT_EQ(headers_, headers_handler_->decoded_block());
- headers_handler_.reset();
- }
-
- Perspective perspective() const { return GetParam().perspective; }
-
- QuicTransportVersion transport_version() const {
- return GetParam().version.transport_version;
- }
-
- ParsedQuicVersionVector GetVersion() {
- ParsedQuicVersionVector versions;
- versions.push_back(GetParam().version);
- return versions;
- }
-
- void TearDownLocalConnectionState() {
- QuicConnectionPeer::TearDownLocalConnectionState(connection_);
- }
-
- QuicStreamId NextPromisedStreamId() {
- return next_promised_stream_id_ += next_stream_id_;
- }
-
- static constexpr bool kFrameComplete = true;
- static constexpr bool kHasPriority = true;
-
- MockQuicConnectionHelper helper_;
- MockAlarmFactory alarm_factory_;
- StrictMock<MockQuicConnection>* connection_;
- StrictMock<MockQuicSpdySession> session_;
- QuicHeadersStream* headers_stream_;
- SpdyHeaderBlock headers_;
- std::unique_ptr<RecordingHeadersHandler> headers_handler_;
- std::string body_;
- std::string saved_data_;
- std::string saved_header_data_;
- std::string saved_payloads_;
- std::unique_ptr<SpdyFramer> framer_;
- std::unique_ptr<http2::Http2DecoderAdapter> deframer_;
- StrictMock<MockVisitor> visitor_;
- QuicStreamFrame stream_frame_;
- QuicStreamId next_promised_stream_id_;
- QuicStreamId client_id_1_;
- QuicStreamId client_id_2_;
- QuicStreamId client_id_3_;
- QuicStreamId next_stream_id_;
-};
-
-// Run all tests with each version and perspective (client or server).
-INSTANTIATE_TEST_SUITE_P(Tests,
- QuicHeadersStreamTest,
- ::testing::ValuesIn(GetTestParams()),
- ::testing::PrintToStringParamName());
-
-TEST_P(QuicHeadersStreamTest, StreamId) {
- EXPECT_EQ(QuicUtils::GetHeadersStreamId(connection_->transport_version()),
- headers_stream_->id());
-}
-
-TEST_P(QuicHeadersStreamTest, WriteHeaders) {
- for (QuicStreamId stream_id = client_id_1_; stream_id < client_id_3_;
- stream_id += next_stream_id_) {
- for (bool fin : {false, true}) {
- if (perspective() == Perspective::IS_SERVER) {
- WriteAndExpectResponseHeaders(stream_id, fin);
- } else {
- for (SpdyPriority priority = 0; priority < 7; ++priority) {
- // TODO(rch): implement priorities correctly.
- WriteAndExpectRequestHeaders(stream_id, fin, 0);
- }
- }
- }
- }
-}
-
-TEST_P(QuicHeadersStreamTest, WritePushPromises) {
- for (QuicStreamId stream_id = client_id_1_; stream_id < client_id_3_;
- stream_id += next_stream_id_) {
- QuicStreamId promised_stream_id = NextPromisedStreamId();
- if (perspective() == Perspective::IS_SERVER) {
- // Write the headers and capture the outgoing data
- EXPECT_CALL(session_, WritevData(QuicUtils::GetHeadersStreamId(
- connection_->transport_version()),
- _, _, NO_FIN, _, _))
- .WillOnce(WithArgs<1>(Invoke(this, &QuicHeadersStreamTest::SaveIov)));
- session_.WritePushPromise(stream_id, promised_stream_id,
- headers_.Clone());
-
- // Parse the outgoing data and check that it matches was was written.
- EXPECT_CALL(visitor_,
- OnPushPromise(stream_id, promised_stream_id, kFrameComplete));
- headers_handler_ = std::make_unique<RecordingHeadersHandler>();
- EXPECT_CALL(visitor_, OnHeaderFrameStart(stream_id))
- .WillOnce(Return(headers_handler_.get()));
- EXPECT_CALL(visitor_, OnHeaderFrameEnd(stream_id)).Times(1);
- deframer_->ProcessInput(saved_data_.data(), saved_data_.length());
- EXPECT_FALSE(deframer_->HasError())
- << http2::Http2DecoderAdapter::SpdyFramerErrorToString(
- deframer_->spdy_framer_error());
- CheckHeaders();
- saved_data_.clear();
- } else {
- EXPECT_QUIC_BUG(session_.WritePushPromise(stream_id, promised_stream_id,
- headers_.Clone()),
- "Client shouldn't send PUSH_PROMISE");
- }
- }
-}
-
-TEST_P(QuicHeadersStreamTest, ProcessRawData) {
- for (QuicStreamId stream_id = client_id_1_; stream_id < client_id_3_;
- stream_id += next_stream_id_) {
- for (bool fin : {false, true}) {
- for (SpdyPriority priority = 0; priority < 7; ++priority) {
- // Replace with "WriteHeadersAndSaveData"
- SpdySerializedFrame frame;
- if (perspective() == Perspective::IS_SERVER) {
- SpdyHeadersIR headers_frame(stream_id, headers_.Clone());
- headers_frame.set_fin(fin);
- headers_frame.set_has_priority(true);
- headers_frame.set_weight(Spdy3PriorityToHttp2Weight(0));
- frame = framer_->SerializeFrame(headers_frame);
- EXPECT_CALL(session_, OnStreamHeadersPriority(
- stream_id, spdy::SpdyStreamPrecedence(0)));
- } else {
- SpdyHeadersIR headers_frame(stream_id, headers_.Clone());
- headers_frame.set_fin(fin);
- frame = framer_->SerializeFrame(headers_frame);
- }
- EXPECT_CALL(session_,
- OnStreamHeaderList(stream_id, fin, frame.size(), _))
- .WillOnce(Invoke(this, &QuicHeadersStreamTest::SaveHeaderList));
- stream_frame_.data_buffer = frame.data();
- stream_frame_.data_length = frame.size();
- headers_stream_->OnStreamFrame(stream_frame_);
- stream_frame_.offset += frame.size();
- CheckHeaders();
- }
- }
- }
-}
-
-TEST_P(QuicHeadersStreamTest, ProcessPushPromise) {
- if (perspective() == Perspective::IS_SERVER) {
- return;
- }
- for (QuicStreamId stream_id = client_id_1_; stream_id < client_id_3_;
- stream_id += next_stream_id_) {
- QuicStreamId promised_stream_id = NextPromisedStreamId();
- SpdyPushPromiseIR push_promise(stream_id, promised_stream_id,
- headers_.Clone());
- SpdySerializedFrame frame(framer_->SerializeFrame(push_promise));
- bool connection_closed = false;
- if (perspective() == Perspective::IS_SERVER) {
- EXPECT_CALL(*connection_,
- CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA,
- "PUSH_PROMISE not supported.", _))
- .WillRepeatedly(InvokeWithoutArgs(
- this, &QuicHeadersStreamTest::TearDownLocalConnectionState));
- } else {
- ON_CALL(*connection_, CloseConnection(_, _, _))
- .WillByDefault(testing::Assign(&connection_closed, true));
- EXPECT_CALL(session_, OnPromiseHeaderList(stream_id, promised_stream_id,
- frame.size(), _))
- .WillOnce(
- Invoke(this, &QuicHeadersStreamTest::SavePromiseHeaderList));
- }
- stream_frame_.data_buffer = frame.data();
- stream_frame_.data_length = frame.size();
- headers_stream_->OnStreamFrame(stream_frame_);
- if (perspective() == Perspective::IS_CLIENT) {
- stream_frame_.offset += frame.size();
- // CheckHeaders crashes if the connection is closed so this ensures we
- // fail the test instead of crashing.
- ASSERT_FALSE(connection_closed);
- CheckHeaders();
- }
- }
-}
-
-TEST_P(QuicHeadersStreamTest, ProcessPriorityFrame) {
- QuicStreamId parent_stream_id = 0;
- for (SpdyPriority priority = 0; priority < 7; ++priority) {
- for (QuicStreamId stream_id = client_id_1_; stream_id < client_id_3_;
- stream_id += next_stream_id_) {
- int weight = Spdy3PriorityToHttp2Weight(priority);
- SpdyPriorityIR priority_frame(stream_id, parent_stream_id, weight, true);
- SpdySerializedFrame frame(framer_->SerializeFrame(priority_frame));
- parent_stream_id = stream_id;
- if (perspective() == Perspective::IS_CLIENT) {
- EXPECT_CALL(*connection_,
- CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA,
- "Server must not send PRIORITY frames.", _))
- .WillRepeatedly(InvokeWithoutArgs(
- this, &QuicHeadersStreamTest::TearDownLocalConnectionState));
- } else {
- EXPECT_CALL(
- session_,
- OnPriorityFrame(stream_id, spdy::SpdyStreamPrecedence(priority)))
- .Times(1);
- }
- stream_frame_.data_buffer = frame.data();
- stream_frame_.data_length = frame.size();
- headers_stream_->OnStreamFrame(stream_frame_);
- stream_frame_.offset += frame.size();
- }
- }
-}
-
-TEST_P(QuicHeadersStreamTest, ProcessPushPromiseDisabledSetting) {
- if (perspective() != Perspective::IS_CLIENT) {
- return;
- }
-
- session_.OnConfigNegotiated();
- SpdySettingsIR data;
- // Respect supported settings frames SETTINGS_ENABLE_PUSH.
- data.AddSetting(SETTINGS_ENABLE_PUSH, 0);
- SpdySerializedFrame frame(framer_->SerializeFrame(data));
- stream_frame_.data_buffer = frame.data();
- stream_frame_.data_length = frame.size();
- EXPECT_CALL(
- *connection_,
- CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA,
- "Unsupported field of HTTP/2 SETTINGS frame: 2", _));
- headers_stream_->OnStreamFrame(stream_frame_);
-}
-
-TEST_P(QuicHeadersStreamTest, ProcessLargeRawData) {
- // We want to create a frame that is more than the SPDY Framer's max control
- // frame size, which is 16K, but less than the HPACK decoders max decode
- // buffer size, which is 32K.
- headers_["key0"] = std::string(1 << 13, '.');
- headers_["key1"] = std::string(1 << 13, '.');
- headers_["key2"] = std::string(1 << 13, '.');
- for (QuicStreamId stream_id = client_id_1_; stream_id < client_id_3_;
- stream_id += next_stream_id_) {
- for (bool fin : {false, true}) {
- for (SpdyPriority priority = 0; priority < 7; ++priority) {
- // Replace with "WriteHeadersAndSaveData"
- SpdySerializedFrame frame;
- if (perspective() == Perspective::IS_SERVER) {
- SpdyHeadersIR headers_frame(stream_id, headers_.Clone());
- headers_frame.set_fin(fin);
- headers_frame.set_has_priority(true);
- headers_frame.set_weight(Spdy3PriorityToHttp2Weight(0));
- frame = framer_->SerializeFrame(headers_frame);
- EXPECT_CALL(session_, OnStreamHeadersPriority(
- stream_id, spdy::SpdyStreamPrecedence(0)));
- } else {
- SpdyHeadersIR headers_frame(stream_id, headers_.Clone());
- headers_frame.set_fin(fin);
- frame = framer_->SerializeFrame(headers_frame);
- }
- EXPECT_CALL(session_,
- OnStreamHeaderList(stream_id, fin, frame.size(), _))
- .WillOnce(Invoke(this, &QuicHeadersStreamTest::SaveHeaderList));
- stream_frame_.data_buffer = frame.data();
- stream_frame_.data_length = frame.size();
- headers_stream_->OnStreamFrame(stream_frame_);
- stream_frame_.offset += frame.size();
- CheckHeaders();
- }
- }
- }
-}
-
-TEST_P(QuicHeadersStreamTest, ProcessBadData) {
- const char kBadData[] = "blah blah blah";
- EXPECT_CALL(*connection_,
- CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA, _, _))
- .Times(::testing::AnyNumber());
- stream_frame_.data_buffer = kBadData;
- stream_frame_.data_length = strlen(kBadData);
- headers_stream_->OnStreamFrame(stream_frame_);
-}
-
-TEST_P(QuicHeadersStreamTest, ProcessSpdyDataFrame) {
- SpdyDataIR data(/* stream_id = */ 2, "ping");
- SpdySerializedFrame frame(framer_->SerializeFrame(data));
-
- EXPECT_CALL(*connection_, CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA,
- "SPDY DATA frame received.", _))
- .WillOnce(InvokeWithoutArgs(
- this, &QuicHeadersStreamTest::TearDownLocalConnectionState));
- stream_frame_.data_buffer = frame.data();
- stream_frame_.data_length = frame.size();
- headers_stream_->OnStreamFrame(stream_frame_);
-}
-
-TEST_P(QuicHeadersStreamTest, ProcessSpdyRstStreamFrame) {
- SpdyRstStreamIR data(/* stream_id = */ 2, ERROR_CODE_PROTOCOL_ERROR);
- SpdySerializedFrame frame(framer_->SerializeFrame(data));
- EXPECT_CALL(*connection_,
- CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA,
- "SPDY RST_STREAM frame received.", _))
- .WillOnce(InvokeWithoutArgs(
- this, &QuicHeadersStreamTest::TearDownLocalConnectionState));
- stream_frame_.data_buffer = frame.data();
- stream_frame_.data_length = frame.size();
- headers_stream_->OnStreamFrame(stream_frame_);
-}
-
-TEST_P(QuicHeadersStreamTest, RespectHttp2SettingsFrameSupportedFields) {
- const uint32_t kTestHeaderTableSize = 1000;
- SpdySettingsIR data;
- // Respect supported settings frames SETTINGS_HEADER_TABLE_SIZE,
- // SETTINGS_MAX_HEADER_LIST_SIZE.
- data.AddSetting(SETTINGS_HEADER_TABLE_SIZE, kTestHeaderTableSize);
- data.AddSetting(spdy::SETTINGS_MAX_HEADER_LIST_SIZE, 2000);
- SpdySerializedFrame frame(framer_->SerializeFrame(data));
- stream_frame_.data_buffer = frame.data();
- stream_frame_.data_length = frame.size();
- headers_stream_->OnStreamFrame(stream_frame_);
- EXPECT_EQ(kTestHeaderTableSize, QuicSpdySessionPeer::GetSpdyFramer(&session_)
- ->header_encoder_table_size());
-}
-
-TEST_P(QuicHeadersStreamTest, RespectHttp2SettingsFrameUnsupportedFields) {
- SpdySettingsIR data;
- // Does not support SETTINGS_MAX_CONCURRENT_STREAMS,
- // SETTINGS_INITIAL_WINDOW_SIZE, SETTINGS_ENABLE_PUSH and
- // SETTINGS_MAX_FRAME_SIZE.
- data.AddSetting(SETTINGS_MAX_CONCURRENT_STREAMS, 100);
- data.AddSetting(SETTINGS_INITIAL_WINDOW_SIZE, 100);
- data.AddSetting(SETTINGS_ENABLE_PUSH, 1);
- data.AddSetting(SETTINGS_MAX_FRAME_SIZE, 1250);
- SpdySerializedFrame frame(framer_->SerializeFrame(data));
- EXPECT_CALL(*connection_,
- CloseConnection(
- QUIC_INVALID_HEADERS_STREAM_DATA,
- absl::StrCat("Unsupported field of HTTP/2 SETTINGS frame: ",
- SETTINGS_MAX_CONCURRENT_STREAMS),
- _));
- EXPECT_CALL(*connection_,
- CloseConnection(
- QUIC_INVALID_HEADERS_STREAM_DATA,
- absl::StrCat("Unsupported field of HTTP/2 SETTINGS frame: ",
- SETTINGS_INITIAL_WINDOW_SIZE),
- _));
- if (session_.perspective() == Perspective::IS_CLIENT) {
- EXPECT_CALL(*connection_,
- CloseConnection(
- QUIC_INVALID_HEADERS_STREAM_DATA,
- absl::StrCat("Unsupported field of HTTP/2 SETTINGS frame: ",
- SETTINGS_ENABLE_PUSH),
- _));
- }
- EXPECT_CALL(*connection_,
- CloseConnection(
- QUIC_INVALID_HEADERS_STREAM_DATA,
- absl::StrCat("Unsupported field of HTTP/2 SETTINGS frame: ",
- SETTINGS_MAX_FRAME_SIZE),
- _));
- stream_frame_.data_buffer = frame.data();
- stream_frame_.data_length = frame.size();
- headers_stream_->OnStreamFrame(stream_frame_);
-}
-
-TEST_P(QuicHeadersStreamTest, ProcessSpdyPingFrame) {
- SpdyPingIR data(1);
- SpdySerializedFrame frame(framer_->SerializeFrame(data));
- EXPECT_CALL(*connection_, CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA,
- "SPDY PING frame received.", _))
- .WillOnce(InvokeWithoutArgs(
- this, &QuicHeadersStreamTest::TearDownLocalConnectionState));
- stream_frame_.data_buffer = frame.data();
- stream_frame_.data_length = frame.size();
- headers_stream_->OnStreamFrame(stream_frame_);
-}
-
-TEST_P(QuicHeadersStreamTest, ProcessSpdyGoAwayFrame) {
- SpdyGoAwayIR data(/* last_good_stream_id = */ 1, ERROR_CODE_PROTOCOL_ERROR,
- "go away");
- SpdySerializedFrame frame(framer_->SerializeFrame(data));
- EXPECT_CALL(*connection_, CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA,
- "SPDY GOAWAY frame received.", _))
- .WillOnce(InvokeWithoutArgs(
- this, &QuicHeadersStreamTest::TearDownLocalConnectionState));
- stream_frame_.data_buffer = frame.data();
- stream_frame_.data_length = frame.size();
- headers_stream_->OnStreamFrame(stream_frame_);
-}
-
-TEST_P(QuicHeadersStreamTest, ProcessSpdyWindowUpdateFrame) {
- SpdyWindowUpdateIR data(/* stream_id = */ 1, /* delta = */ 1);
- SpdySerializedFrame frame(framer_->SerializeFrame(data));
- EXPECT_CALL(*connection_,
- CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA,
- "SPDY WINDOW_UPDATE frame received.", _))
- .WillOnce(InvokeWithoutArgs(
- this, &QuicHeadersStreamTest::TearDownLocalConnectionState));
- stream_frame_.data_buffer = frame.data();
- stream_frame_.data_length = frame.size();
- headers_stream_->OnStreamFrame(stream_frame_);
-}
-
-TEST_P(QuicHeadersStreamTest, NoConnectionLevelFlowControl) {
- EXPECT_FALSE(QuicStreamPeer::StreamContributesToConnectionFlowControl(
- headers_stream_));
-}
-
-TEST_P(QuicHeadersStreamTest, AckSentData) {
- EXPECT_CALL(session_, WritevData(QuicUtils::GetHeadersStreamId(
- connection_->transport_version()),
- _, _, NO_FIN, _, _))
- .WillRepeatedly(Invoke(&session_, &MockQuicSpdySession::ConsumeData));
- InSequence s;
- QuicReferenceCountedPointer<MockAckListener> ack_listener1(
- new MockAckListener());
- QuicReferenceCountedPointer<MockAckListener> ack_listener2(
- new MockAckListener());
- QuicReferenceCountedPointer<MockAckListener> ack_listener3(
- new MockAckListener());
-
- // Packet 1.
- headers_stream_->WriteOrBufferData("Header5", false, ack_listener1);
- headers_stream_->WriteOrBufferData("Header5", false, ack_listener1);
- headers_stream_->WriteOrBufferData("Header7", false, ack_listener2);
-
- // Packet 2.
- headers_stream_->WriteOrBufferData("Header9", false, ack_listener3);
- headers_stream_->WriteOrBufferData("Header7", false, ack_listener2);
-
- // Packet 3.
- headers_stream_->WriteOrBufferData("Header9", false, ack_listener3);
-
- // Packet 2 gets retransmitted.
- EXPECT_CALL(*ack_listener3, OnPacketRetransmitted(7)).Times(1);
- EXPECT_CALL(*ack_listener2, OnPacketRetransmitted(7)).Times(1);
- headers_stream_->OnStreamFrameRetransmitted(21, 7, false);
- headers_stream_->OnStreamFrameRetransmitted(28, 7, false);
-
- // Packets are acked in order: 2, 3, 1.
- QuicByteCount newly_acked_length = 0;
- EXPECT_CALL(*ack_listener3, OnPacketAcked(7, _));
- EXPECT_CALL(*ack_listener2, OnPacketAcked(7, _));
- EXPECT_TRUE(headers_stream_->OnStreamFrameAcked(
- 21, 7, false, QuicTime::Delta::Zero(), QuicTime::Zero(),
- &newly_acked_length));
- EXPECT_EQ(7u, newly_acked_length);
- EXPECT_TRUE(headers_stream_->OnStreamFrameAcked(
- 28, 7, false, QuicTime::Delta::Zero(), QuicTime::Zero(),
- &newly_acked_length));
- EXPECT_EQ(7u, newly_acked_length);
-
- EXPECT_CALL(*ack_listener3, OnPacketAcked(7, _));
- EXPECT_TRUE(headers_stream_->OnStreamFrameAcked(
- 35, 7, false, QuicTime::Delta::Zero(), QuicTime::Zero(),
- &newly_acked_length));
- EXPECT_EQ(7u, newly_acked_length);
-
- EXPECT_CALL(*ack_listener1, OnPacketAcked(7, _));
- EXPECT_CALL(*ack_listener1, OnPacketAcked(7, _));
- EXPECT_TRUE(headers_stream_->OnStreamFrameAcked(
- 0, 7, false, QuicTime::Delta::Zero(), QuicTime::Zero(),
- &newly_acked_length));
- EXPECT_EQ(7u, newly_acked_length);
- EXPECT_TRUE(headers_stream_->OnStreamFrameAcked(
- 7, 7, false, QuicTime::Delta::Zero(), QuicTime::Zero(),
- &newly_acked_length));
- EXPECT_EQ(7u, newly_acked_length);
- // Unsent data is acked.
- EXPECT_CALL(*ack_listener2, OnPacketAcked(7, _));
- EXPECT_TRUE(headers_stream_->OnStreamFrameAcked(
- 14, 10, false, QuicTime::Delta::Zero(), QuicTime::Zero(),
- &newly_acked_length));
- EXPECT_EQ(7u, newly_acked_length);
-}
-
-TEST_P(QuicHeadersStreamTest, FrameContainsMultipleHeaders) {
- // In this test, a stream frame can contain multiple headers.
- EXPECT_CALL(session_, WritevData(QuicUtils::GetHeadersStreamId(
- connection_->transport_version()),
- _, _, NO_FIN, _, _))
- .WillRepeatedly(Invoke(&session_, &MockQuicSpdySession::ConsumeData));
- InSequence s;
- QuicReferenceCountedPointer<MockAckListener> ack_listener1(
- new MockAckListener());
- QuicReferenceCountedPointer<MockAckListener> ack_listener2(
- new MockAckListener());
- QuicReferenceCountedPointer<MockAckListener> ack_listener3(
- new MockAckListener());
-
- headers_stream_->WriteOrBufferData("Header5", false, ack_listener1);
- headers_stream_->WriteOrBufferData("Header5", false, ack_listener1);
- headers_stream_->WriteOrBufferData("Header7", false, ack_listener2);
- headers_stream_->WriteOrBufferData("Header9", false, ack_listener3);
- headers_stream_->WriteOrBufferData("Header7", false, ack_listener2);
- headers_stream_->WriteOrBufferData("Header9", false, ack_listener3);
-
- // Frame 1 is retransmitted.
- EXPECT_CALL(*ack_listener1, OnPacketRetransmitted(14));
- EXPECT_CALL(*ack_listener2, OnPacketRetransmitted(3));
- headers_stream_->OnStreamFrameRetransmitted(0, 17, false);
-
- // Frames are acked in order: 2, 3, 1.
- QuicByteCount newly_acked_length = 0;
- EXPECT_CALL(*ack_listener2, OnPacketAcked(4, _));
- EXPECT_CALL(*ack_listener3, OnPacketAcked(7, _));
- EXPECT_CALL(*ack_listener2, OnPacketAcked(2, _));
- EXPECT_TRUE(headers_stream_->OnStreamFrameAcked(
- 17, 13, false, QuicTime::Delta::Zero(), QuicTime::Zero(),
- &newly_acked_length));
- EXPECT_EQ(13u, newly_acked_length);
-
- EXPECT_CALL(*ack_listener2, OnPacketAcked(5, _));
- EXPECT_CALL(*ack_listener3, OnPacketAcked(7, _));
- EXPECT_TRUE(headers_stream_->OnStreamFrameAcked(
- 30, 12, false, QuicTime::Delta::Zero(), QuicTime::Zero(),
- &newly_acked_length));
- EXPECT_EQ(12u, newly_acked_length);
-
- EXPECT_CALL(*ack_listener1, OnPacketAcked(14, _));
- EXPECT_CALL(*ack_listener2, OnPacketAcked(3, _));
- EXPECT_TRUE(headers_stream_->OnStreamFrameAcked(
- 0, 17, false, QuicTime::Delta::Zero(), QuicTime::Zero(),
- &newly_acked_length));
- EXPECT_EQ(17u, newly_acked_length);
-}
-
-TEST_P(QuicHeadersStreamTest, HeadersGetAckedMultipleTimes) {
- EXPECT_CALL(session_, WritevData(QuicUtils::GetHeadersStreamId(
- connection_->transport_version()),
- _, _, NO_FIN, _, _))
- .WillRepeatedly(Invoke(&session_, &MockQuicSpdySession::ConsumeData));
- InSequence s;
- QuicReferenceCountedPointer<MockAckListener> ack_listener1(
- new MockAckListener());
- QuicReferenceCountedPointer<MockAckListener> ack_listener2(
- new MockAckListener());
- QuicReferenceCountedPointer<MockAckListener> ack_listener3(
- new MockAckListener());
-
- // Send [0, 42).
- headers_stream_->WriteOrBufferData("Header5", false, ack_listener1);
- headers_stream_->WriteOrBufferData("Header5", false, ack_listener1);
- headers_stream_->WriteOrBufferData("Header7", false, ack_listener2);
- headers_stream_->WriteOrBufferData("Header9", false, ack_listener3);
- headers_stream_->WriteOrBufferData("Header7", false, ack_listener2);
- headers_stream_->WriteOrBufferData("Header9", false, ack_listener3);
-
- // Ack [15, 20), [5, 25), [10, 17), [0, 12) and [22, 42).
- QuicByteCount newly_acked_length = 0;
- EXPECT_CALL(*ack_listener2, OnPacketAcked(5, _));
- EXPECT_TRUE(headers_stream_->OnStreamFrameAcked(
- 15, 5, false, QuicTime::Delta::Zero(), QuicTime::Zero(),
- &newly_acked_length));
- EXPECT_EQ(5u, newly_acked_length);
-
- EXPECT_CALL(*ack_listener1, OnPacketAcked(9, _));
- EXPECT_CALL(*ack_listener2, OnPacketAcked(1, _));
- EXPECT_CALL(*ack_listener2, OnPacketAcked(1, _));
- EXPECT_CALL(*ack_listener3, OnPacketAcked(4, _));
- EXPECT_TRUE(headers_stream_->OnStreamFrameAcked(
- 5, 20, false, QuicTime::Delta::Zero(), QuicTime::Zero(),
- &newly_acked_length));
- EXPECT_EQ(15u, newly_acked_length);
-
- // Duplicate ack.
- EXPECT_FALSE(headers_stream_->OnStreamFrameAcked(
- 10, 7, false, QuicTime::Delta::Zero(), QuicTime::Zero(),
- &newly_acked_length));
- EXPECT_EQ(0u, newly_acked_length);
-
- EXPECT_CALL(*ack_listener1, OnPacketAcked(5, _));
- EXPECT_TRUE(headers_stream_->OnStreamFrameAcked(
- 0, 12, false, QuicTime::Delta::Zero(), QuicTime::Zero(),
- &newly_acked_length));
- EXPECT_EQ(5u, newly_acked_length);
-
- EXPECT_CALL(*ack_listener3, OnPacketAcked(3, _));
- EXPECT_CALL(*ack_listener2, OnPacketAcked(7, _));
- EXPECT_CALL(*ack_listener3, OnPacketAcked(7, _));
- EXPECT_TRUE(headers_stream_->OnStreamFrameAcked(
- 22, 20, false, QuicTime::Delta::Zero(), QuicTime::Zero(),
- &newly_acked_length));
- EXPECT_EQ(17u, newly_acked_length);
-}
-
-TEST_P(QuicHeadersStreamTest, CloseOnPushPromiseToServer) {
- if (perspective() == Perspective::IS_CLIENT) {
- return;
- }
- QuicStreamId promised_id = 1;
- SpdyPushPromiseIR push_promise(client_id_1_, promised_id, headers_.Clone());
- SpdySerializedFrame frame = framer_->SerializeFrame(push_promise);
- stream_frame_.data_buffer = frame.data();
- stream_frame_.data_length = frame.size();
- EXPECT_CALL(session_, OnStreamHeaderList(_, _, _, _));
- // TODO(lassey): Check for HTTP_WRONG_STREAM error code.
- EXPECT_CALL(*connection_, CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA,
- "PUSH_PROMISE not supported.", _));
- headers_stream_->OnStreamFrame(stream_frame_);
-}
-
-} // namespace
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/http/quic_receive_control_stream.cc b/chromium/net/third_party/quiche/src/quic/core/http/quic_receive_control_stream.cc
deleted file mode 100644
index 3c6546fb8f3..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/http/quic_receive_control_stream.cc
+++ /dev/null
@@ -1,269 +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 "quic/core/http/quic_receive_control_stream.h"
-
-#include <utility>
-
-#include "absl/strings/numbers.h"
-#include "absl/strings/str_split.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/http/http_constants.h"
-#include "quic/core/http/http_decoder.h"
-#include "quic/core/http/quic_spdy_session.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_flag_utils.h"
-#include "quic/platform/api/quic_flags.h"
-#include "common/quiche_text_utils.h"
-
-namespace quic {
-
-QuicReceiveControlStream::QuicReceiveControlStream(
- PendingStream* pending,
- QuicSpdySession* spdy_session)
- : QuicStream(pending,
- spdy_session,
- /*is_static=*/true),
- settings_frame_received_(false),
- decoder_(this),
- spdy_session_(spdy_session) {
- sequencer()->set_level_triggered(true);
-}
-
-QuicReceiveControlStream::~QuicReceiveControlStream() {}
-
-void QuicReceiveControlStream::OnStreamReset(
- const QuicRstStreamFrame& /*frame*/) {
- stream_delegate()->OnStreamError(
- QUIC_HTTP_CLOSED_CRITICAL_STREAM,
- "RESET_STREAM received for receive control stream");
-}
-
-void QuicReceiveControlStream::OnDataAvailable() {
- iovec iov;
- while (!reading_stopped() && decoder_.error() == QUIC_NO_ERROR &&
- sequencer()->GetReadableRegion(&iov)) {
- QUICHE_DCHECK(!sequencer()->IsClosed());
-
- QuicByteCount processed_bytes = decoder_.ProcessInput(
- reinterpret_cast<const char*>(iov.iov_base), iov.iov_len);
- sequencer()->MarkConsumed(processed_bytes);
-
- if (!session()->connection()->connected()) {
- return;
- }
-
- // The only reason QuicReceiveControlStream pauses HttpDecoder is an error,
- // in which case the connection would have already been closed.
- QUICHE_DCHECK_EQ(iov.iov_len, processed_bytes);
- }
-}
-
-void QuicReceiveControlStream::OnError(HttpDecoder* decoder) {
- stream_delegate()->OnStreamError(decoder->error(), decoder->error_detail());
-}
-
-bool QuicReceiveControlStream::OnMaxPushIdFrame(const MaxPushIdFrame& frame) {
- 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::OnGoAwayFrame(const GoAwayFrame& frame) {
- if (spdy_session()->debug_visitor()) {
- spdy_session()->debug_visitor()->OnGoAwayFrameReceived(frame);
- }
-
- if (!ValidateFrameType(HttpFrameType::GOAWAY)) {
- return false;
- }
-
- spdy_session()->OnHttp3GoAway(frame.id);
- return true;
-}
-
-bool QuicReceiveControlStream::OnSettingsFrameStart(
- QuicByteCount /*header_length*/) {
- return ValidateFrameType(HttpFrameType::SETTINGS);
-}
-
-bool QuicReceiveControlStream::OnSettingsFrame(const SettingsFrame& frame) {
- QUIC_DVLOG(1) << "Control Stream " << id()
- << " received settings frame: " << frame;
- return spdy_session_->OnSettingsFrame(frame);
-}
-
-bool QuicReceiveControlStream::OnDataFrameStart(QuicByteCount /*header_length*/,
- QuicByteCount
- /*payload_length*/) {
- return ValidateFrameType(HttpFrameType::DATA);
-}
-
-bool QuicReceiveControlStream::OnDataFramePayload(
- absl::string_view /*payload*/) {
- QUICHE_NOTREACHED();
- return false;
-}
-
-bool QuicReceiveControlStream::OnDataFrameEnd() {
- QUICHE_NOTREACHED();
- return false;
-}
-
-bool QuicReceiveControlStream::OnHeadersFrameStart(
- QuicByteCount /*header_length*/,
- QuicByteCount
- /*payload_length*/) {
- return ValidateFrameType(HttpFrameType::HEADERS);
-}
-
-bool QuicReceiveControlStream::OnHeadersFramePayload(
- absl::string_view /*payload*/) {
- QUICHE_NOTREACHED();
- return false;
-}
-
-bool QuicReceiveControlStream::OnHeadersFrameEnd() {
- QUICHE_NOTREACHED();
- return false;
-}
-
-bool QuicReceiveControlStream::OnPriorityUpdateFrameStart(
- QuicByteCount /*header_length*/) {
- return ValidateFrameType(HttpFrameType::PRIORITY_UPDATE_REQUEST_STREAM);
-}
-
-bool QuicReceiveControlStream::OnPriorityUpdateFrame(
- const PriorityUpdateFrame& frame) {
- if (spdy_session()->debug_visitor()) {
- spdy_session()->debug_visitor()->OnPriorityUpdateFrameReceived(frame);
- }
-
- // TODO(b/147306124): Use a proper structured headers parser instead.
- for (absl::string_view key_value :
- absl::StrSplit(frame.priority_field_value, ',')) {
- std::vector<absl::string_view> key_and_value =
- absl::StrSplit(key_value, '=');
- if (key_and_value.size() != 2) {
- continue;
- }
-
- absl::string_view key = key_and_value[0];
- quiche::QuicheTextUtils::RemoveLeadingAndTrailingWhitespace(&key);
- if (key != "u") {
- continue;
- }
-
- absl::string_view value = key_and_value[1];
- int urgency;
- if (!absl::SimpleAtoi(value, &urgency) || urgency < 0 || urgency > 7) {
- stream_delegate()->OnStreamError(
- QUIC_INVALID_PRIORITY_UPDATE,
- "Invalid value for PRIORITY_UPDATE urgency parameter.");
- return false;
- }
-
- if (frame.prioritized_element_type == REQUEST_STREAM) {
- return spdy_session_->OnPriorityUpdateForRequestStream(
- frame.prioritized_element_id, urgency);
- } else {
- return spdy_session_->OnPriorityUpdateForPushStream(
- frame.prioritized_element_id, urgency);
- }
- }
-
- // Ignore frame if no urgency parameter can be parsed.
- return true;
-}
-
-bool QuicReceiveControlStream::OnAcceptChFrameStart(
- QuicByteCount /* header_length */) {
- return ValidateFrameType(HttpFrameType::ACCEPT_CH);
-}
-
-bool QuicReceiveControlStream::OnAcceptChFrame(const AcceptChFrame& frame) {
- QUICHE_DCHECK_EQ(Perspective::IS_CLIENT, spdy_session()->perspective());
-
- if (spdy_session()->debug_visitor()) {
- spdy_session()->debug_visitor()->OnAcceptChFrameReceived(frame);
- }
-
- spdy_session()->OnAcceptChFrame(frame);
- return true;
-}
-
-void QuicReceiveControlStream::OnWebTransportStreamFrameType(
- QuicByteCount /*header_length*/,
- WebTransportSessionId /*session_id*/) {
- QUIC_BUG(WEBTRANSPORT_STREAM on Control Stream)
- << "Parsed WEBTRANSPORT_STREAM on a control stream.";
-}
-
-bool QuicReceiveControlStream::OnUnknownFrameStart(
- uint64_t frame_type,
- QuicByteCount /*header_length*/,
- QuicByteCount payload_length) {
- if (spdy_session()->debug_visitor()) {
- spdy_session()->debug_visitor()->OnUnknownFrameReceived(id(), frame_type,
- payload_length);
- }
-
- return ValidateFrameType(static_cast<HttpFrameType>(frame_type));
-}
-
-bool QuicReceiveControlStream::OnUnknownFramePayload(
- absl::string_view /*payload*/) {
- // Ignore unknown frame types.
- return true;
-}
-
-bool QuicReceiveControlStream::OnUnknownFrameEnd() {
- // Ignore unknown frame types.
- return true;
-}
-
-bool QuicReceiveControlStream::ValidateFrameType(HttpFrameType frame_type) {
- // Certain frame types are forbidden.
- if (frame_type == HttpFrameType::DATA ||
- frame_type == HttpFrameType::HEADERS ||
- (spdy_session()->perspective() == Perspective::IS_CLIENT &&
- frame_type == HttpFrameType::MAX_PUSH_ID) ||
- (spdy_session()->perspective() == Perspective::IS_SERVER &&
- frame_type == HttpFrameType::ACCEPT_CH)) {
- stream_delegate()->OnStreamError(
- QUIC_HTTP_FRAME_UNEXPECTED_ON_CONTROL_STREAM,
- absl::StrCat("Invalid frame type ", static_cast<int>(frame_type),
- " received on control stream."));
- return false;
- }
-
- if (settings_frame_received_) {
- if (frame_type == HttpFrameType::SETTINGS) {
- // SETTINGS frame may only be the first frame on the control stream.
- stream_delegate()->OnStreamError(
- QUIC_HTTP_INVALID_FRAME_SEQUENCE_ON_CONTROL_STREAM,
- "SETTINGS frame can only be received once.");
- return false;
- }
- return true;
- }
-
- if (frame_type == HttpFrameType::SETTINGS) {
- settings_frame_received_ = true;
- return true;
- }
- stream_delegate()->OnStreamError(
- QUIC_HTTP_MISSING_SETTINGS_FRAME,
- absl::StrCat("First frame received on control stream is type ",
- static_cast<int>(frame_type), ", but it must be SETTINGS."));
- return false;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/http/quic_receive_control_stream.h b/chromium/net/third_party/quiche/src/quic/core/http/quic_receive_control_stream.h
deleted file mode 100644
index 3c61d3cb621..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/http/quic_receive_control_stream.h
+++ /dev/null
@@ -1,79 +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_CORE_HTTP_QUIC_RECEIVE_CONTROL_STREAM_H_
-#define QUICHE_QUIC_CORE_HTTP_QUIC_RECEIVE_CONTROL_STREAM_H_
-
-#include "quic/core/http/http_decoder.h"
-#include "quic/core/quic_stream.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-class QuicSpdySession;
-
-// 3.2.1 Control Stream.
-// The receive control stream is peer initiated and is read only.
-class QUIC_EXPORT_PRIVATE QuicReceiveControlStream
- : public QuicStream,
- public HttpDecoder::Visitor {
- public:
- explicit QuicReceiveControlStream(PendingStream* pending,
- QuicSpdySession* spdy_session);
- QuicReceiveControlStream(const QuicReceiveControlStream&) = delete;
- QuicReceiveControlStream& operator=(const QuicReceiveControlStream&) = delete;
- ~QuicReceiveControlStream() override;
-
- // Overriding QuicStream::OnStreamReset to make sure control stream is never
- // closed before connection.
- void OnStreamReset(const QuicRstStreamFrame& frame) override;
-
- // Implementation of QuicStream.
- void OnDataAvailable() override;
-
- // HttpDecoder::Visitor implementation.
- void OnError(HttpDecoder* decoder) override;
- bool OnMaxPushIdFrame(const MaxPushIdFrame& frame) override;
- bool OnGoAwayFrame(const GoAwayFrame& frame) override;
- bool OnSettingsFrameStart(QuicByteCount header_length) override;
- bool OnSettingsFrame(const SettingsFrame& frame) override;
- bool OnDataFrameStart(QuicByteCount header_length,
- QuicByteCount payload_length) override;
- bool OnDataFramePayload(absl::string_view payload) override;
- bool OnDataFrameEnd() override;
- bool OnHeadersFrameStart(QuicByteCount header_length,
- QuicByteCount payload_length) override;
- bool OnHeadersFramePayload(absl::string_view payload) override;
- bool OnHeadersFrameEnd() override;
- bool OnPriorityUpdateFrameStart(QuicByteCount header_length) override;
- bool OnPriorityUpdateFrame(const PriorityUpdateFrame& frame) override;
- bool OnAcceptChFrameStart(QuicByteCount header_length) override;
- bool OnAcceptChFrame(const AcceptChFrame& frame) override;
- void OnWebTransportStreamFrameType(QuicByteCount header_length,
- WebTransportSessionId session_id) override;
- bool OnUnknownFrameStart(uint64_t frame_type,
- QuicByteCount header_length,
- QuicByteCount payload_length) override;
- bool OnUnknownFramePayload(absl::string_view payload) override;
- bool OnUnknownFrameEnd() override;
-
- QuicSpdySession* spdy_session() { return spdy_session_; }
-
- private:
- // Called when a frame of allowed type is received. Returns true if the frame
- // is allowed in this position. Returns false and resets the stream
- // otherwise.
- bool ValidateFrameType(HttpFrameType frame_type);
-
- // False until a SETTINGS frame is received.
- bool settings_frame_received_;
-
- HttpDecoder decoder_;
- QuicSpdySession* const spdy_session_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_HTTP_QUIC_RECEIVE_CONTROL_STREAM_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/http/quic_receive_control_stream_test.cc b/chromium/net/third_party/quiche/src/quic/core/http/quic_receive_control_stream_test.cc
deleted file mode 100644
index ae7a0d818cc..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/http/quic_receive_control_stream_test.cc
+++ /dev/null
@@ -1,483 +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 "quic/core/http/quic_receive_control_stream.h"
-
-#include "absl/memory/memory.h"
-#include "absl/strings/escaping.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/http/http_constants.h"
-#include "quic/core/qpack/qpack_header_table.h"
-#include "quic/core/quic_simple_buffer_allocator.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_utils.h"
-#include "quic/test_tools/qpack/qpack_encoder_peer.h"
-#include "quic/test_tools/quic_spdy_session_peer.h"
-#include "quic/test_tools/quic_stream_peer.h"
-#include "quic/test_tools/quic_test_utils.h"
-
-namespace quic {
-
-class QpackEncoder;
-
-namespace test {
-
-namespace {
-using ::testing::_;
-using ::testing::AnyNumber;
-using ::testing::StrictMock;
-
-struct TestParams {
- TestParams(const ParsedQuicVersion& version, Perspective perspective)
- : version(version), perspective(perspective) {
- QUIC_LOG(INFO) << "TestParams: " << *this;
- }
-
- TestParams(const TestParams& other)
- : version(other.version), perspective(other.perspective) {}
-
- friend std::ostream& operator<<(std::ostream& os, const TestParams& tp) {
- os << "{ version: " << ParsedQuicVersionToString(tp.version)
- << ", perspective: "
- << (tp.perspective == Perspective::IS_CLIENT ? "client" : "server")
- << "}";
- return os;
- }
-
- ParsedQuicVersion version;
- Perspective perspective;
-};
-
-// Used by ::testing::PrintToStringParamName().
-std::string PrintToString(const TestParams& tp) {
- return absl::StrCat(
- ParsedQuicVersionToString(tp.version), "_",
- (tp.perspective == Perspective::IS_CLIENT ? "client" : "server"));
-}
-
-std::vector<TestParams> GetTestParams() {
- std::vector<TestParams> params;
- ParsedQuicVersionVector all_supported_versions = AllSupportedVersions();
- for (const auto& version : AllSupportedVersions()) {
- if (!VersionUsesHttp3(version.transport_version)) {
- continue;
- }
- for (Perspective p : {Perspective::IS_SERVER, Perspective::IS_CLIENT}) {
- params.emplace_back(version, p);
- }
- }
- return params;
-}
-
-class TestStream : public QuicSpdyStream {
- public:
- TestStream(QuicStreamId id, QuicSpdySession* session)
- : QuicSpdyStream(id, session, BIDIRECTIONAL) {}
- ~TestStream() override = default;
-
- void OnBodyAvailable() override {}
-};
-
-class QuicReceiveControlStreamTest : public QuicTestWithParam<TestParams> {
- public:
- QuicReceiveControlStreamTest()
- : connection_(new StrictMock<MockQuicConnection>(
- &helper_,
- &alarm_factory_,
- perspective(),
- SupportedVersions(GetParam().version))),
- session_(connection_) {
- EXPECT_CALL(session_, OnCongestionWindowChange(_)).Times(AnyNumber());
- session_.Initialize();
- QuicStreamId id = perspective() == Perspective::IS_SERVER
- ? GetNthClientInitiatedUnidirectionalStreamId(
- session_.transport_version(), 3)
- : GetNthServerInitiatedUnidirectionalStreamId(
- session_.transport_version(), 3);
- char type[] = {kControlStream};
-
- QuicStreamFrame data1(id, false, 0, absl::string_view(type, 1));
- session_.OnStreamFrame(data1);
-
- receive_control_stream_ =
- QuicSpdySessionPeer::GetReceiveControlStream(&session_);
-
- stream_ = new TestStream(GetNthClientInitiatedBidirectionalStreamId(
- GetParam().version.transport_version, 0),
- &session_);
- session_.ActivateStream(absl::WrapUnique(stream_));
- }
-
- Perspective perspective() const { return GetParam().perspective; }
-
- std::string EncodeSettings(const SettingsFrame& settings) {
- std::unique_ptr<char[]> buffer;
- QuicByteCount settings_frame_length =
- HttpEncoder::SerializeSettingsFrame(settings, &buffer);
- return std::string(buffer.get(), settings_frame_length);
- }
-
- std::string SerializePriorityUpdateFrame(
- const PriorityUpdateFrame& priority_update) {
- std::unique_ptr<char[]> priority_buffer;
- QuicByteCount priority_frame_length =
- HttpEncoder::SerializePriorityUpdateFrame(priority_update,
- &priority_buffer);
- return std::string(priority_buffer.get(), priority_frame_length);
- }
-
- QuicStreamOffset NumBytesConsumed() {
- return QuicStreamPeer::sequencer(receive_control_stream_)
- ->NumBytesConsumed();
- }
-
- MockQuicConnectionHelper helper_;
- MockAlarmFactory alarm_factory_;
- StrictMock<MockQuicConnection>* connection_;
- StrictMock<MockQuicSpdySession> session_;
- QuicReceiveControlStream* receive_control_stream_;
- TestStream* stream_;
-};
-
-INSTANTIATE_TEST_SUITE_P(Tests,
- QuicReceiveControlStreamTest,
- ::testing::ValuesIn(GetTestParams()),
- ::testing::PrintToStringParamName());
-
-TEST_P(QuicReceiveControlStreamTest, ResetControlStream) {
- EXPECT_TRUE(receive_control_stream_->is_static());
- QuicRstStreamFrame rst_frame(kInvalidControlFrameId,
- receive_control_stream_->id(),
- QUIC_STREAM_CANCELLED, 1234);
- EXPECT_CALL(*connection_,
- CloseConnection(QUIC_HTTP_CLOSED_CRITICAL_STREAM, _, _));
- receive_control_stream_->OnStreamReset(rst_frame);
-}
-
-TEST_P(QuicReceiveControlStreamTest, ReceiveSettings) {
- SettingsFrame settings;
- settings.values[10] = 2;
- settings.values[SETTINGS_MAX_FIELD_SECTION_SIZE] = 5;
- settings.values[SETTINGS_QPACK_BLOCKED_STREAMS] = 12;
- settings.values[SETTINGS_QPACK_MAX_TABLE_CAPACITY] = 37;
- std::string data = EncodeSettings(settings);
- QuicStreamFrame frame(receive_control_stream_->id(), false, 1, data);
-
- QpackEncoder* qpack_encoder = session_.qpack_encoder();
- QpackEncoderHeaderTable* header_table =
- QpackEncoderPeer::header_table(qpack_encoder);
- EXPECT_EQ(std::numeric_limits<size_t>::max(),
- session_.max_outbound_header_list_size());
- EXPECT_EQ(0u, QpackEncoderPeer::maximum_blocked_streams(qpack_encoder));
- EXPECT_EQ(0u, header_table->maximum_dynamic_table_capacity());
-
- receive_control_stream_->OnStreamFrame(frame);
-
- EXPECT_EQ(5u, session_.max_outbound_header_list_size());
- EXPECT_EQ(12u, QpackEncoderPeer::maximum_blocked_streams(qpack_encoder));
- EXPECT_EQ(37u, header_table->maximum_dynamic_table_capacity());
-}
-
-// Regression test for https://crbug.com/982648.
-// QuicReceiveControlStream::OnDataAvailable() must stop processing input as
-// soon as OnSettingsFrameStart() is called by HttpDecoder for the second frame.
-TEST_P(QuicReceiveControlStreamTest, ReceiveSettingsTwice) {
- SettingsFrame settings;
- // Reserved identifiers, must be ignored.
- settings.values[0x21] = 100;
- settings.values[0x40] = 200;
-
- std::string settings_frame = EncodeSettings(settings);
-
- QuicStreamOffset offset = 1;
- EXPECT_EQ(offset, NumBytesConsumed());
-
- // Receive first SETTINGS frame.
- receive_control_stream_->OnStreamFrame(
- QuicStreamFrame(receive_control_stream_->id(), /* fin = */ false, offset,
- settings_frame));
- offset += settings_frame.length();
-
- // First SETTINGS frame is consumed.
- EXPECT_EQ(offset, NumBytesConsumed());
-
- // Second SETTINGS frame causes the connection to be closed.
- EXPECT_CALL(
- *connection_,
- CloseConnection(QUIC_HTTP_INVALID_FRAME_SEQUENCE_ON_CONTROL_STREAM,
- "SETTINGS frame can only be received once.", _))
- .WillOnce(
- Invoke(connection_, &MockQuicConnection::ReallyCloseConnection));
- EXPECT_CALL(*connection_, SendConnectionClosePacket(_, _, _));
- EXPECT_CALL(session_, OnConnectionClosed(_, _));
-
- // Receive second SETTINGS frame.
- receive_control_stream_->OnStreamFrame(
- QuicStreamFrame(receive_control_stream_->id(), /* fin = */ false, offset,
- settings_frame));
-
- // Frame header of second SETTINGS frame is consumed, but not frame payload.
- QuicByteCount settings_frame_header_length = 2;
- EXPECT_EQ(offset + settings_frame_header_length, NumBytesConsumed());
-}
-
-TEST_P(QuicReceiveControlStreamTest, ReceiveSettingsFragments) {
- SettingsFrame settings;
- settings.values[10] = 2;
- settings.values[SETTINGS_MAX_FIELD_SECTION_SIZE] = 5;
- std::string data = EncodeSettings(settings);
- std::string data1 = data.substr(0, 1);
- std::string data2 = data.substr(1, data.length() - 1);
-
- QuicStreamFrame frame(receive_control_stream_->id(), false, 1, data1);
- QuicStreamFrame frame2(receive_control_stream_->id(), false, 2, data2);
- EXPECT_NE(5u, session_.max_outbound_header_list_size());
- receive_control_stream_->OnStreamFrame(frame);
- receive_control_stream_->OnStreamFrame(frame2);
- EXPECT_EQ(5u, session_.max_outbound_header_list_size());
-}
-
-TEST_P(QuicReceiveControlStreamTest, ReceiveWrongFrame) {
- // DATA frame header without payload.
- QuicBuffer data = HttpEncoder::SerializeDataFrameHeader(
- /* payload_length = */ 2, SimpleBufferAllocator::Get());
-
- QuicStreamFrame frame(receive_control_stream_->id(), false, 1,
- data.AsStringView());
- EXPECT_CALL(
- *connection_,
- CloseConnection(QUIC_HTTP_FRAME_UNEXPECTED_ON_CONTROL_STREAM, _, _));
- receive_control_stream_->OnStreamFrame(frame);
-}
-
-TEST_P(QuicReceiveControlStreamTest,
- ReceivePriorityUpdateFrameBeforeSettingsFrame) {
- std::string serialized_frame = SerializePriorityUpdateFrame({});
- QuicStreamFrame data(receive_control_stream_->id(), /* fin = */ false,
- /* offset = */ 1, serialized_frame);
-
- EXPECT_CALL(*connection_,
- CloseConnection(QUIC_HTTP_MISSING_SETTINGS_FRAME,
- "First frame received on control stream is type "
- "984832, but it must be SETTINGS.",
- _))
- .WillOnce(
- Invoke(connection_, &MockQuicConnection::ReallyCloseConnection));
- EXPECT_CALL(*connection_, SendConnectionClosePacket(_, _, _));
- EXPECT_CALL(session_, OnConnectionClosed(_, _));
-
- receive_control_stream_->OnStreamFrame(data);
-}
-
-TEST_P(QuicReceiveControlStreamTest, ReceiveGoAwayFrame) {
- StrictMock<MockHttp3DebugVisitor> debug_visitor;
- session_.set_debug_visitor(&debug_visitor);
-
- QuicStreamOffset offset = 1;
-
- // Receive SETTINGS frame.
- SettingsFrame settings;
- std::string settings_frame = EncodeSettings(settings);
- EXPECT_CALL(debug_visitor, OnSettingsFrameReceived(settings));
- receive_control_stream_->OnStreamFrame(
- QuicStreamFrame(receive_control_stream_->id(), /* fin = */ false, offset,
- settings_frame));
- offset += settings_frame.length();
-
- GoAwayFrame goaway{/* id = */ 0};
-
- std::unique_ptr<char[]> buffer;
- QuicByteCount header_length =
- HttpEncoder::SerializeGoAwayFrame(goaway, &buffer);
- std::string data = std::string(buffer.get(), header_length);
-
- QuicStreamFrame frame(receive_control_stream_->id(), false, offset, data);
- EXPECT_FALSE(session_.goaway_received());
-
- EXPECT_CALL(debug_visitor, OnGoAwayFrameReceived(goaway));
-
- receive_control_stream_->OnStreamFrame(frame);
- EXPECT_TRUE(session_.goaway_received());
-}
-
-TEST_P(QuicReceiveControlStreamTest, PushPromiseOnControlStreamShouldClose) {
- std::string push_promise_frame = absl::HexStringToBytes(
- "05" // PUSH_PROMISE
- "01" // length
- "00"); // push ID
- QuicStreamFrame frame(receive_control_stream_->id(), false, 1,
- push_promise_frame);
- EXPECT_CALL(*connection_, CloseConnection(QUIC_HTTP_FRAME_ERROR, _, _))
- .WillOnce(
- Invoke(connection_, &MockQuicConnection::ReallyCloseConnection));
- EXPECT_CALL(*connection_, SendConnectionClosePacket(_, _, _));
- EXPECT_CALL(session_, OnConnectionClosed(_, _));
- receive_control_stream_->OnStreamFrame(frame);
-}
-
-// Regression test for b/137554973: unknown frames should be consumed.
-TEST_P(QuicReceiveControlStreamTest, ConsumeUnknownFrame) {
- EXPECT_EQ(1u, NumBytesConsumed());
-
- QuicStreamOffset offset = 1;
-
- // Receive SETTINGS frame.
- std::string settings_frame = EncodeSettings({});
- receive_control_stream_->OnStreamFrame(
- QuicStreamFrame(receive_control_stream_->id(), /* fin = */ false, offset,
- settings_frame));
- offset += settings_frame.length();
-
- // SETTINGS frame is consumed.
- EXPECT_EQ(offset, NumBytesConsumed());
-
- // Receive unknown frame.
- std::string unknown_frame = absl::HexStringToBytes(
- "21" // reserved frame type
- "03" // payload length
- "666f6f"); // payload "foo"
-
- receive_control_stream_->OnStreamFrame(QuicStreamFrame(
- receive_control_stream_->id(), /* fin = */ false, offset, unknown_frame));
- offset += unknown_frame.size();
-
- // Unknown frame is consumed.
- EXPECT_EQ(offset, NumBytesConsumed());
-}
-
-TEST_P(QuicReceiveControlStreamTest, ReceiveUnknownFrame) {
- StrictMock<MockHttp3DebugVisitor> debug_visitor;
- session_.set_debug_visitor(&debug_visitor);
-
- const QuicStreamId id = receive_control_stream_->id();
- QuicStreamOffset offset = 1;
-
- // Receive SETTINGS frame.
- SettingsFrame settings;
- std::string settings_frame = EncodeSettings(settings);
- EXPECT_CALL(debug_visitor, OnSettingsFrameReceived(settings));
- receive_control_stream_->OnStreamFrame(
- QuicStreamFrame(id, /* fin = */ false, offset, settings_frame));
- offset += settings_frame.length();
-
- // Receive unknown frame.
- std::string unknown_frame = absl::HexStringToBytes(
- "21" // reserved frame type
- "03" // payload length
- "666f6f"); // payload "foo"
-
- EXPECT_CALL(debug_visitor, OnUnknownFrameReceived(id, /* frame_type = */ 0x21,
- /* payload_length = */ 3));
- receive_control_stream_->OnStreamFrame(
- QuicStreamFrame(id, /* fin = */ false, offset, unknown_frame));
-}
-
-TEST_P(QuicReceiveControlStreamTest, CancelPushFrameBeforeSettings) {
- std::string cancel_push_frame = absl::HexStringToBytes(
- "03" // type CANCEL_PUSH
- "01" // payload length
- "01"); // push ID
-
- EXPECT_CALL(*connection_, CloseConnection(QUIC_HTTP_FRAME_ERROR,
- "CANCEL_PUSH frame received.", _))
- .WillOnce(
- Invoke(connection_, &MockQuicConnection::ReallyCloseConnection));
- EXPECT_CALL(*connection_, SendConnectionClosePacket(_, _, _));
- EXPECT_CALL(session_, OnConnectionClosed(_, _));
-
- receive_control_stream_->OnStreamFrame(
- QuicStreamFrame(receive_control_stream_->id(), /* fin = */ false,
- /* offset = */ 1, cancel_push_frame));
-}
-
-TEST_P(QuicReceiveControlStreamTest, AcceptChFrameBeforeSettings) {
- std::string accept_ch_frame = absl::HexStringToBytes(
- "4089" // type (ACCEPT_CH)
- "00"); // length
-
- if (perspective() == Perspective::IS_SERVER) {
- EXPECT_CALL(*connection_,
- CloseConnection(
- QUIC_HTTP_FRAME_UNEXPECTED_ON_CONTROL_STREAM,
- "Invalid frame type 137 received on control stream.", _))
- .WillOnce(
- Invoke(connection_, &MockQuicConnection::ReallyCloseConnection));
- } else {
- EXPECT_CALL(*connection_,
- CloseConnection(QUIC_HTTP_MISSING_SETTINGS_FRAME,
- "First frame received on control stream is "
- "type 137, but it must be SETTINGS.",
- _))
- .WillOnce(
- Invoke(connection_, &MockQuicConnection::ReallyCloseConnection));
- }
- EXPECT_CALL(*connection_, SendConnectionClosePacket(_, _, _));
- EXPECT_CALL(session_, OnConnectionClosed(_, _));
-
- receive_control_stream_->OnStreamFrame(
- QuicStreamFrame(receive_control_stream_->id(), /* fin = */ false,
- /* offset = */ 1, accept_ch_frame));
-}
-
-TEST_P(QuicReceiveControlStreamTest, ReceiveAcceptChFrame) {
- StrictMock<MockHttp3DebugVisitor> debug_visitor;
- session_.set_debug_visitor(&debug_visitor);
-
- const QuicStreamId id = receive_control_stream_->id();
- QuicStreamOffset offset = 1;
-
- // Receive SETTINGS frame.
- SettingsFrame settings;
- std::string settings_frame = EncodeSettings(settings);
- EXPECT_CALL(debug_visitor, OnSettingsFrameReceived(settings));
- receive_control_stream_->OnStreamFrame(
- QuicStreamFrame(id, /* fin = */ false, offset, settings_frame));
- offset += settings_frame.length();
-
- // Receive ACCEPT_CH frame.
- std::string accept_ch_frame = absl::HexStringToBytes(
- "4089" // type (ACCEPT_CH)
- "00"); // length
-
- if (perspective() == Perspective::IS_CLIENT) {
- EXPECT_CALL(debug_visitor, OnAcceptChFrameReceived(_));
- } else {
- EXPECT_CALL(*connection_,
- CloseConnection(
- QUIC_HTTP_FRAME_UNEXPECTED_ON_CONTROL_STREAM,
- "Invalid frame type 137 received on control stream.", _))
- .WillOnce(
- Invoke(connection_, &MockQuicConnection::ReallyCloseConnection));
- EXPECT_CALL(*connection_, SendConnectionClosePacket(_, _, _));
- EXPECT_CALL(session_, OnConnectionClosed(_, _));
- }
-
- receive_control_stream_->OnStreamFrame(
- QuicStreamFrame(id, /* fin = */ false, offset, accept_ch_frame));
-}
-
-TEST_P(QuicReceiveControlStreamTest, UnknownFrameBeforeSettings) {
- std::string unknown_frame = absl::HexStringToBytes(
- "21" // reserved frame type
- "03" // payload length
- "666f6f"); // payload "foo"
-
- EXPECT_CALL(*connection_,
- CloseConnection(QUIC_HTTP_MISSING_SETTINGS_FRAME,
- "First frame received on control stream is type "
- "33, but it must be SETTINGS.",
- _))
- .WillOnce(
- Invoke(connection_, &MockQuicConnection::ReallyCloseConnection));
- EXPECT_CALL(*connection_, SendConnectionClosePacket(_, _, _));
- EXPECT_CALL(session_, OnConnectionClosed(_, _));
-
- receive_control_stream_->OnStreamFrame(
- QuicStreamFrame(receive_control_stream_->id(), /* fin = */ false,
- /* offset = */ 1, unknown_frame));
-}
-
-} // namespace
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/http/quic_send_control_stream.cc b/chromium/net/third_party/quiche/src/quic/core/http/quic_send_control_stream.cc
deleted file mode 100644
index 92831f2d14d..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/http/quic_send_control_stream.cc
+++ /dev/null
@@ -1,124 +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 "quic/core/http/quic_send_control_stream.h"
-#include <cstdint>
-#include <memory>
-
-#include "absl/base/macros.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/crypto/quic_random.h"
-#include "quic/core/http/http_constants.h"
-#include "quic/core/http/quic_spdy_session.h"
-#include "quic/core/quic_session.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-QuicSendControlStream::QuicSendControlStream(QuicStreamId id,
- QuicSpdySession* spdy_session,
- const SettingsFrame& settings)
- : QuicStream(id, spdy_session, /*is_static = */ true, WRITE_UNIDIRECTIONAL),
- settings_sent_(false),
- settings_(settings),
- spdy_session_(spdy_session) {}
-
-void QuicSendControlStream::OnStreamReset(const QuicRstStreamFrame& /*frame*/) {
- QUIC_BUG(quic_bug_10382_1)
- << "OnStreamReset() called for write unidirectional stream.";
-}
-
-bool QuicSendControlStream::OnStopSending(QuicResetStreamError /* code */) {
- stream_delegate()->OnStreamError(
- QUIC_HTTP_CLOSED_CRITICAL_STREAM,
- "STOP_SENDING received for send control stream");
- return false;
-}
-
-void QuicSendControlStream::MaybeSendSettingsFrame() {
- if (settings_sent_) {
- return;
- }
-
- QuicConnection::ScopedPacketFlusher flusher(session()->connection());
- // Send the stream type on so the peer knows about this stream.
- char data[sizeof(kControlStream)];
- QuicDataWriter writer(ABSL_ARRAYSIZE(data), data);
- writer.WriteVarInt62(kControlStream);
- WriteOrBufferData(absl::string_view(writer.data(), writer.length()), false,
- nullptr);
-
- SettingsFrame settings = settings_;
- // https://tools.ietf.org/html/draft-ietf-quic-http-25#section-7.2.4.1
- // specifies that setting identifiers of 0x1f * N + 0x21 are reserved and
- // greasing should be attempted.
- if (!GetQuicFlag(FLAGS_quic_enable_http3_grease_randomness)) {
- settings.values[0x40] = 20;
- } else {
- uint32_t result;
- QuicRandom::GetInstance()->RandBytes(&result, sizeof(result));
- uint64_t setting_id = 0x1fULL * static_cast<uint64_t>(result) + 0x21ULL;
- QuicRandom::GetInstance()->RandBytes(&result, sizeof(result));
- settings.values[setting_id] = result;
- }
-
- std::unique_ptr<char[]> buffer;
- QuicByteCount frame_length =
- HttpEncoder::SerializeSettingsFrame(settings, &buffer);
- QUIC_DVLOG(1) << "Control stream " << id() << " is writing settings frame "
- << settings;
- if (spdy_session_->debug_visitor()) {
- spdy_session_->debug_visitor()->OnSettingsFrameSent(settings);
- }
- WriteOrBufferData(absl::string_view(buffer.get(), frame_length),
- /*fin = */ false, nullptr);
- settings_sent_ = true;
-
- // https://tools.ietf.org/html/draft-ietf-quic-http-25#section-7.2.9
- // specifies that a reserved frame type has no semantic meaning and should be
- // discarded. A greasing frame is added here.
- std::unique_ptr<char[]> grease;
- QuicByteCount grease_length = HttpEncoder::SerializeGreasingFrame(&grease);
- WriteOrBufferData(absl::string_view(grease.get(), grease_length),
- /*fin = */ false, nullptr);
-}
-
-void QuicSendControlStream::WritePriorityUpdate(
- const PriorityUpdateFrame& priority_update) {
- QuicConnection::ScopedPacketFlusher flusher(session()->connection());
- MaybeSendSettingsFrame();
-
- if (spdy_session_->debug_visitor()) {
- spdy_session_->debug_visitor()->OnPriorityUpdateFrameSent(priority_update);
- }
-
- std::unique_ptr<char[]> buffer;
- QuicByteCount frame_length =
- HttpEncoder::SerializePriorityUpdateFrame(priority_update, &buffer);
- QUIC_DVLOG(1) << "Control Stream " << id() << " is writing "
- << priority_update;
- WriteOrBufferData(absl::string_view(buffer.get(), frame_length), false,
- nullptr);
-}
-
-void QuicSendControlStream::SendGoAway(QuicStreamId id) {
- QuicConnection::ScopedPacketFlusher flusher(session()->connection());
- MaybeSendSettingsFrame();
-
- GoAwayFrame frame;
- frame.id = id;
- if (spdy_session_->debug_visitor()) {
- spdy_session_->debug_visitor()->OnGoAwayFrameSent(id);
- }
-
- std::unique_ptr<char[]> buffer;
- QuicByteCount frame_length =
- HttpEncoder::SerializeGoAwayFrame(frame, &buffer);
- WriteOrBufferData(absl::string_view(buffer.get(), frame_length), false,
- nullptr);
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/http/quic_send_control_stream.h b/chromium/net/third_party/quiche/src/quic/core/http/quic_send_control_stream.h
deleted file mode 100644
index d376a63c48b..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/http/quic_send_control_stream.h
+++ /dev/null
@@ -1,64 +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_CORE_HTTP_QUIC_SEND_CONTROL_STREAM_H_
-#define QUICHE_QUIC_CORE_HTTP_QUIC_SEND_CONTROL_STREAM_H_
-
-#include "quic/core/http/http_encoder.h"
-#include "quic/core/quic_stream.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_export.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-class QuicSpdySession;
-
-// 6.2.1 Control Stream.
-// The send control stream is self initiated and is write only.
-class QUIC_EXPORT_PRIVATE QuicSendControlStream : public QuicStream {
- public:
- // |session| can't be nullptr, and the ownership is not passed. The stream can
- // only be accessed through the session.
- QuicSendControlStream(QuicStreamId id,
- QuicSpdySession* session,
- const SettingsFrame& settings);
- QuicSendControlStream(const QuicSendControlStream&) = delete;
- QuicSendControlStream& operator=(const QuicSendControlStream&) = delete;
- ~QuicSendControlStream() override = default;
-
- // Overriding QuicStream::OnStopSending() to make sure control stream is never
- // closed before connection.
- void OnStreamReset(const QuicRstStreamFrame& frame) override;
- bool OnStopSending(QuicResetStreamError code) override;
-
- // Send SETTINGS frame if it hasn't been sent yet. Settings frame must be the
- // first frame sent on this stream.
- void MaybeSendSettingsFrame();
-
- // Send a PRIORITY_UPDATE frame on this stream, and a SETTINGS frame
- // beforehand if one has not been already sent.
- void WritePriorityUpdate(const PriorityUpdateFrame& priority_update);
-
- // Send a GOAWAY frame on this stream, and a SETTINGS frame beforehand if one
- // has not been already sent.
- void SendGoAway(QuicStreamId id);
-
- // The send control stream is write unidirectional, so this method should
- // never be called.
- void OnDataAvailable() override { QUIC_NOTREACHED(); }
-
- private:
- // Track if a settings frame is already sent.
- bool settings_sent_;
-
- // SETTINGS values to send.
- const SettingsFrame settings_;
-
- QuicSpdySession* const spdy_session_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_HTTP_QUIC_SEND_CONTROL_STREAM_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/http/quic_send_control_stream_test.cc b/chromium/net/third_party/quiche/src/quic/core/http/quic_send_control_stream_test.cc
deleted file mode 100644
index fa1e584d402..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/http/quic_send_control_stream_test.cc
+++ /dev/null
@@ -1,300 +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 "quic/core/http/quic_send_control_stream.h"
-
-#include <utility>
-
-#include "absl/strings/escaping.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/crypto/null_encrypter.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/test_tools/quic_config_peer.h"
-#include "quic/test_tools/quic_spdy_session_peer.h"
-#include "quic/test_tools/quic_test_utils.h"
-#include "common/test_tools/quiche_test_utils.h"
-
-namespace quic {
-namespace test {
-
-namespace {
-
-using ::testing::_;
-using ::testing::AnyNumber;
-using ::testing::Invoke;
-using ::testing::StrictMock;
-
-struct TestParams {
- TestParams(const ParsedQuicVersion& version, Perspective perspective)
- : version(version), perspective(perspective) {
- QUIC_LOG(INFO) << "TestParams: " << *this;
- }
-
- TestParams(const TestParams& other)
- : version(other.version), perspective(other.perspective) {}
-
- friend std::ostream& operator<<(std::ostream& os, const TestParams& tp) {
- os << "{ version: " << ParsedQuicVersionToString(tp.version)
- << ", perspective: "
- << (tp.perspective == Perspective::IS_CLIENT ? "client" : "server")
- << "}";
- return os;
- }
-
- ParsedQuicVersion version;
- Perspective perspective;
-};
-
-// Used by ::testing::PrintToStringParamName().
-std::string PrintToString(const TestParams& tp) {
- return absl::StrCat(
- ParsedQuicVersionToString(tp.version), "_",
- (tp.perspective == Perspective::IS_CLIENT ? "client" : "server"));
-}
-
-std::vector<TestParams> GetTestParams() {
- std::vector<TestParams> params;
- ParsedQuicVersionVector all_supported_versions = AllSupportedVersions();
- for (const auto& version : AllSupportedVersions()) {
- if (!VersionUsesHttp3(version.transport_version)) {
- continue;
- }
- for (Perspective p : {Perspective::IS_SERVER, Perspective::IS_CLIENT}) {
- params.emplace_back(version, p);
- }
- }
- return params;
-}
-
-class QuicSendControlStreamTest : public QuicTestWithParam<TestParams> {
- public:
- QuicSendControlStreamTest()
- : connection_(new StrictMock<MockQuicConnection>(
- &helper_, &alarm_factory_, perspective(),
- SupportedVersions(GetParam().version))),
- session_(connection_) {
- ON_CALL(session_, WritevData(_, _, _, _, _, _))
- .WillByDefault(Invoke(&session_, &MockQuicSpdySession::ConsumeData));
- }
-
- void Initialize() {
- EXPECT_CALL(session_, OnCongestionWindowChange(_)).Times(AnyNumber());
- session_.Initialize();
- connection_->SetEncrypter(
- ENCRYPTION_FORWARD_SECURE,
- std::make_unique<NullEncrypter>(connection_->perspective()));
- send_control_stream_ = QuicSpdySessionPeer::GetSendControlStream(&session_);
- QuicConfigPeer::SetReceivedInitialSessionFlowControlWindow(
- session_.config(), kMinimumFlowControlSendWindow);
- QuicConfigPeer::SetReceivedInitialMaxStreamDataBytesUnidirectional(
- session_.config(), kMinimumFlowControlSendWindow);
- QuicConfigPeer::SetReceivedMaxUnidirectionalStreams(session_.config(), 3);
- session_.OnConfigNegotiated();
- }
-
- Perspective perspective() const { return GetParam().perspective; }
-
- MockQuicConnectionHelper helper_;
- MockAlarmFactory alarm_factory_;
- StrictMock<MockQuicConnection>* connection_;
- StrictMock<MockQuicSpdySession> session_;
- QuicSendControlStream* send_control_stream_;
-};
-
-INSTANTIATE_TEST_SUITE_P(Tests, QuicSendControlStreamTest,
- ::testing::ValuesIn(GetTestParams()),
- ::testing::PrintToStringParamName());
-
-TEST_P(QuicSendControlStreamTest, WriteSettings) {
- SetQuicFlag(FLAGS_quic_enable_http3_grease_randomness, false);
- session_.set_qpack_maximum_dynamic_table_capacity(255);
- session_.set_qpack_maximum_blocked_streams(16);
- session_.set_max_inbound_header_list_size(1024);
-
- Initialize();
- testing::InSequence s;
-
- std::string expected_write_data = absl::HexStringToBytes(
- "00" // stream type: control stream
- "04" // frame type: SETTINGS frame
- "0b" // frame length
- "01" // SETTINGS_QPACK_MAX_TABLE_CAPACITY
- "40ff" // 255
- "06" // SETTINGS_MAX_HEADER_LIST_SIZE
- "4400" // 1024
- "07" // SETTINGS_QPACK_BLOCKED_STREAMS
- "10" // 16
- "4040" // 0x40 as the reserved settings id
- "14" // 20
- "4040" // 0x40 as the reserved frame type
- "01" // 1 byte frame length
- "61"); // payload "a"
- if ((!GetQuicReloadableFlag(quic_verify_request_headers_2) ||
- perspective() == Perspective::IS_CLIENT) &&
- QuicSpdySessionPeer::LocalHttpDatagramSupport(&session_) ==
- HttpDatagramSupport::kDraft00And04) {
- expected_write_data = absl::HexStringToBytes(
- "00" // stream type: control stream
- "04" // frame type: SETTINGS frame
- "0e" // frame length
- "01" // SETTINGS_QPACK_MAX_TABLE_CAPACITY
- "40ff" // 255
- "06" // SETTINGS_MAX_HEADER_LIST_SIZE
- "4400" // 1024
- "07" // SETTINGS_QPACK_BLOCKED_STREAMS
- "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
- "01" // 1 byte frame length
- "61"); // payload "a"
- }
- if (GetQuicReloadableFlag(quic_verify_request_headers_2) &&
- perspective() == Perspective::IS_SERVER &&
- QuicSpdySessionPeer::LocalHttpDatagramSupport(&session_) ==
- HttpDatagramSupport::kNone) {
- expected_write_data = absl::HexStringToBytes(
- "00" // stream type: control stream
- "04" // frame type: SETTINGS frame
- "0d" // frame length
- "01" // SETTINGS_QPACK_MAX_TABLE_CAPACITY
- "40ff" // 255
- "06" // SETTINGS_MAX_HEADER_LIST_SIZE
- "4400" // 1024
- "07" // SETTINGS_QPACK_BLOCKED_STREAMS
- "10" // 16
- "08" // SETTINGS_ENABLE_CONNECT_PROTOCOL
- "01" // 1
- "4040" // 0x40 as the reserved settings id
- "14" // 20
- "4040" // 0x40 as the reserved frame type
- "01" // 1 byte frame length
- "61"); // payload "a"
- }
- if (GetQuicReloadableFlag(quic_verify_request_headers_2) &&
- perspective() == Perspective::IS_SERVER &&
- QuicSpdySessionPeer::LocalHttpDatagramSupport(&session_) !=
- HttpDatagramSupport::kNone) {
- expected_write_data = absl::HexStringToBytes(
- "00" // stream type: control stream
- "04" // frame type: SETTINGS frame
- "11" // frame length
- "01" // SETTINGS_QPACK_MAX_TABLE_CAPACITY
- "40ff" // 255
- "06" // SETTINGS_MAX_HEADER_LIST_SIZE
- "4400" // 1024
- "07" // SETTINGS_QPACK_BLOCKED_STREAMS
- "10" // 16
- "08" // SETTINGS_ENABLE_CONNECT_PROTOCOL
- "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
- "01" // 1 byte frame length
- "61"); // payload "a"
- }
-
- auto buffer = std::make_unique<char[]>(expected_write_data.size());
- QuicDataWriter writer(expected_write_data.size(), buffer.get());
-
- // A lambda to save and consume stream data when QuicSession::WritevData() is
- // called.
- auto save_write_data =
- [&writer, this](QuicStreamId /*id*/, size_t write_length,
- QuicStreamOffset offset, StreamSendingState /*state*/,
- TransmissionType /*type*/,
- absl::optional<EncryptionLevel> /*level*/) {
- send_control_stream_->WriteStreamData(offset, write_length, &writer);
- return QuicConsumedData(/* bytes_consumed = */ write_length,
- /* fin_consumed = */ false);
- };
-
- EXPECT_CALL(session_, WritevData(send_control_stream_->id(), 1, _, _, _, _))
- .WillOnce(Invoke(save_write_data));
- EXPECT_CALL(session_, WritevData(send_control_stream_->id(),
- expected_write_data.size() - 5, _, _, _, _))
- .WillOnce(Invoke(save_write_data));
- EXPECT_CALL(session_, WritevData(send_control_stream_->id(), 4, _, _, _, _))
- .WillOnce(Invoke(save_write_data));
-
- send_control_stream_->MaybeSendSettingsFrame();
- quiche::test::CompareCharArraysWithHexError(
- "settings", writer.data(), writer.length(), expected_write_data.data(),
- expected_write_data.length());
-}
-
-TEST_P(QuicSendControlStreamTest, WriteSettingsOnlyOnce) {
- Initialize();
- testing::InSequence s;
-
- EXPECT_CALL(session_, WritevData(send_control_stream_->id(), 1, _, _, _, _));
- EXPECT_CALL(session_, WritevData(send_control_stream_->id(), _, _, _, _, _))
- .Times(2);
- send_control_stream_->MaybeSendSettingsFrame();
-
- // No data should be written the second time MaybeSendSettingsFrame() is
- // called.
- send_control_stream_->MaybeSendSettingsFrame();
-}
-
-// Send stream type and SETTINGS frame if WritePriorityUpdate() is called first.
-TEST_P(QuicSendControlStreamTest, WritePriorityBeforeSettings) {
- Initialize();
- testing::InSequence s;
-
- // The first write will trigger the control stream to write stream type, a
- // SETTINGS frame, and a greased frame before the PRIORITY_UPDATE frame.
- EXPECT_CALL(session_, WritevData(send_control_stream_->id(), _, _, _, _, _))
- .Times(4);
- PriorityUpdateFrame frame;
- send_control_stream_->WritePriorityUpdate(frame);
-
- EXPECT_CALL(session_, WritevData(send_control_stream_->id(), _, _, _, _, _));
- send_control_stream_->WritePriorityUpdate(frame);
-}
-
-TEST_P(QuicSendControlStreamTest, CloseControlStream) {
- Initialize();
- EXPECT_CALL(*connection_,
- CloseConnection(QUIC_HTTP_CLOSED_CRITICAL_STREAM, _, _));
- send_control_stream_->OnStopSending(
- QuicResetStreamError::FromInternal(QUIC_STREAM_CANCELLED));
-}
-
-TEST_P(QuicSendControlStreamTest, ReceiveDataOnSendControlStream) {
- Initialize();
- QuicStreamFrame frame(send_control_stream_->id(), false, 0, "test");
- EXPECT_CALL(
- *connection_,
- CloseConnection(QUIC_DATA_RECEIVED_ON_WRITE_UNIDIRECTIONAL_STREAM, _, _));
- send_control_stream_->OnStreamFrame(frame);
-}
-
-TEST_P(QuicSendControlStreamTest, SendGoAway) {
- Initialize();
-
- StrictMock<MockHttp3DebugVisitor> debug_visitor;
- session_.set_debug_visitor(&debug_visitor);
-
- QuicStreamId stream_id = 4;
-
- EXPECT_CALL(session_, WritevData(send_control_stream_->id(), _, _, _, _, _))
- .Times(AnyNumber());
- EXPECT_CALL(debug_visitor, OnSettingsFrameSent(_));
- EXPECT_CALL(debug_visitor, OnGoAwayFrameSent(stream_id));
-
- send_control_stream_->SendGoAway(stream_id);
-}
-
-} // namespace
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/http/quic_server_initiated_spdy_stream.cc b/chromium/net/third_party/quiche/src/quic/core/http/quic_server_initiated_spdy_stream.cc
deleted file mode 100644
index 37a53898d01..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/http/quic_server_initiated_spdy_stream.cc
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright 2021 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 "quic/core/http/quic_server_initiated_spdy_stream.h"
-#include "quic/core/quic_error_codes.h"
-
-namespace quic {
-
-void QuicServerInitiatedSpdyStream::OnBodyAvailable() {
- QUIC_BUG(Body received in QuicServerInitiatedSpdyStream)
- << "Received body data in QuicServerInitiatedSpdyStream.";
- OnUnrecoverableError(
- QUIC_INTERNAL_ERROR,
- "Received HTTP/3 body data in a server-initiated bidirectional stream");
-}
-
-size_t QuicServerInitiatedSpdyStream::WriteHeaders(
- spdy::SpdyHeaderBlock /*header_block*/,
- bool /*fin*/,
- QuicReferenceCountedPointer<QuicAckListenerInterface> /*ack_listener*/) {
- QUIC_BUG(Writing headers in QuicServerInitiatedSpdyStream)
- << "Attempting to write headers in QuicServerInitiatedSpdyStream";
- OnUnrecoverableError(QUIC_INTERNAL_ERROR,
- "Attempted to send HTTP/3 headers in a server-initiated "
- "bidirectional stream");
- return 0;
-}
-
-void QuicServerInitiatedSpdyStream::OnInitialHeadersComplete(
- bool /*fin*/,
- size_t /*frame_len*/,
- const QuicHeaderList& /*header_list*/) {
- QUIC_PEER_BUG(Reading headers in QuicServerInitiatedSpdyStream)
- << "Attempting to receive headers in QuicServerInitiatedSpdyStream";
-
- OnUnrecoverableError(IETF_QUIC_PROTOCOL_VIOLATION,
- "Received HTTP/3 headers in a server-initiated "
- "bidirectional stream without an extension setting "
- "explicitly allowing those");
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/http/quic_server_initiated_spdy_stream.h b/chromium/net/third_party/quiche/src/quic/core/http/quic_server_initiated_spdy_stream.h
deleted file mode 100644
index a13dc65cd13..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/http/quic_server_initiated_spdy_stream.h
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright 2021 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_HTTP_QUIC_SERVER_INITIATED_SPDY_STREAM_H_
-#define QUICHE_QUIC_CORE_HTTP_QUIC_SERVER_INITIATED_SPDY_STREAM_H_
-
-#include "quic/core/http/quic_spdy_stream.h"
-
-namespace quic {
-
-// QuicServerInitiatedSpdyStream is a subclass of QuicSpdyStream meant to handle
-// WebTransport traffic on server-initiated bidirectional streams. Receiving or
-// sending any other traffic on this stream will result in a CONNECTION_CLOSE.
-class QUIC_EXPORT_PRIVATE QuicServerInitiatedSpdyStream
- : public QuicSpdyStream {
- public:
- using QuicSpdyStream::QuicSpdyStream;
-
- void OnBodyAvailable() override;
- size_t WriteHeaders(spdy::SpdyHeaderBlock header_block,
- bool fin,
- QuicReferenceCountedPointer<QuicAckListenerInterface>
- ack_listener) override;
- void OnInitialHeadersComplete(bool fin,
- size_t frame_len,
- const QuicHeaderList& header_list) override;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_HTTP_QUIC_SERVER_INITIATED_SPDY_STREAM_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/http/quic_server_session_base.cc b/chromium/net/third_party/quiche/src/quic/core/http/quic_server_session_base.cc
deleted file mode 100644
index 8edcb6932b7..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/http/quic_server_session_base.cc
+++ /dev/null
@@ -1,409 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/http/quic_server_session_base.h"
-
-#include <string>
-
-#include "quic/core/proto/cached_network_parameters_proto.h"
-#include "quic/core/quic_connection.h"
-#include "quic/core/quic_stream.h"
-#include "quic/core/quic_tag.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_flag_utils.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-QuicServerSessionBase::QuicServerSessionBase(
- const QuicConfig& config,
- const ParsedQuicVersionVector& supported_versions,
- QuicConnection* connection,
- Visitor* visitor,
- QuicCryptoServerStreamBase::Helper* helper,
- const QuicCryptoServerConfig* crypto_config,
- QuicCompressedCertsCache* compressed_certs_cache)
- : QuicSpdySession(connection, visitor, config, supported_versions),
- crypto_config_(crypto_config),
- compressed_certs_cache_(compressed_certs_cache),
- helper_(helper),
- bandwidth_resumption_enabled_(false),
- bandwidth_estimate_sent_to_client_(QuicBandwidth::Zero()),
- last_scup_time_(QuicTime::Zero()) {}
-
-QuicServerSessionBase::~QuicServerSessionBase() {}
-
-void QuicServerSessionBase::Initialize() {
- crypto_stream_ =
- CreateQuicCryptoServerStream(crypto_config_, compressed_certs_cache_);
- QuicSpdySession::Initialize();
- SendSettingsToCryptoStream();
-}
-
-void QuicServerSessionBase::OnConfigNegotiated() {
- QuicSpdySession::OnConfigNegotiated();
-
- if (!config()->HasReceivedConnectionOptions()) {
- return;
- }
-
- const CachedNetworkParameters* cached_network_params =
- crypto_stream_->PreviousCachedNetworkParams();
-
- // Set the initial rtt from cached_network_params.min_rtt_ms, which comes from
- // a validated address token. This will override the initial rtt that may have
- // been set by the transport parameters.
- if (add_cached_network_parameters_to_address_token() && 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 (ContainsQuicTag(config()->ReceivedConnectionOptions(), kTRTT)) {
- QUIC_DLOG(INFO)
- << "Server: Setting initial rtt to "
- << cached_network_params->min_rtt_ms()
- << "ms which is received from a validated address token";
- connection()->sent_packet_manager().SetInitialRtt(
- QuicTime::Delta::FromMilliseconds(
- cached_network_params->min_rtt_ms()));
- }
- } else {
- QUIC_CODE_COUNT(quic_server_received_network_params_at_different_region);
- }
- }
-
- // Enable bandwidth resumption if peer sent correct connection options.
- const bool last_bandwidth_resumption =
- ContainsQuicTag(config()->ReceivedConnectionOptions(), kBWRE);
- const bool max_bandwidth_resumption =
- ContainsQuicTag(config()->ReceivedConnectionOptions(), kBWMX);
- bandwidth_resumption_enabled_ =
- last_bandwidth_resumption || max_bandwidth_resumption;
-
- // If the client has provided a bandwidth estimate from the same serving
- // region as this server, then decide whether to use the data for bandwidth
- // resumption.
- if (cached_network_params != nullptr &&
- cached_network_params->serving_region() == serving_region_) {
- if (!add_cached_network_parameters_to_address_token() ||
- !version().UsesTls()) {
- // Log the received connection parameters, regardless of how they
- // get used for bandwidth resumption.
- connection()->OnReceiveConnectionState(*cached_network_params);
- }
-
- if (bandwidth_resumption_enabled_) {
- // Only do bandwidth resumption if estimate is recent enough.
- const uint64_t seconds_since_estimate =
- connection()->clock()->WallNow().ToUNIXSeconds() -
- cached_network_params->timestamp();
- if (seconds_since_estimate <= kNumSecondsPerHour) {
- connection()->ResumeConnectionState(*cached_network_params,
- max_bandwidth_resumption);
- }
- }
- }
-}
-
-void QuicServerSessionBase::OnConnectionClosed(
- const QuicConnectionCloseFrame& frame,
- ConnectionCloseSource source) {
- QuicSession::OnConnectionClosed(frame, source);
- // In the unlikely event we get a connection close while doing an asynchronous
- // crypto event, make sure we cancel the callback.
- if (crypto_stream_ != nullptr) {
- crypto_stream_->CancelOutstandingCallbacks();
- }
-}
-
-void QuicServerSessionBase::OnCongestionWindowChange(QuicTime now) {
- if (!bandwidth_resumption_enabled_) {
- return;
- }
- // Only send updates when the application has no data to write.
- if (HasDataToWrite()) {
- return;
- }
-
- // If not enough time has passed since the last time we sent an update to the
- // client, or not enough packets have been sent, then return early.
- const QuicSentPacketManager& sent_packet_manager =
- connection()->sent_packet_manager();
- int64_t srtt_ms =
- sent_packet_manager.GetRttStats()->smoothed_rtt().ToMilliseconds();
- int64_t now_ms = (now - last_scup_time_).ToMilliseconds();
- int64_t packets_since_last_scup = 0;
- const QuicPacketNumber largest_sent_packet =
- connection()->sent_packet_manager().GetLargestSentPacket();
- if (largest_sent_packet.IsInitialized()) {
- packets_since_last_scup =
- last_scup_packet_number_.IsInitialized()
- ? largest_sent_packet - last_scup_packet_number_
- : largest_sent_packet.ToUint64();
- }
- if (now_ms < (kMinIntervalBetweenServerConfigUpdatesRTTs * srtt_ms) ||
- now_ms < kMinIntervalBetweenServerConfigUpdatesMs ||
- packets_since_last_scup < kMinPacketsBetweenServerConfigUpdates) {
- return;
- }
-
- // If the bandwidth recorder does not have a valid estimate, return early.
- const QuicSustainedBandwidthRecorder* bandwidth_recorder =
- sent_packet_manager.SustainedBandwidthRecorder();
- if (bandwidth_recorder == nullptr || !bandwidth_recorder->HasEstimate()) {
- return;
- }
-
- // The bandwidth recorder has recorded at least one sustained bandwidth
- // estimate. Check that it's substantially different from the last one that
- // we sent to the client, and if so, send the new one.
- QuicBandwidth new_bandwidth_estimate =
- bandwidth_recorder->BandwidthEstimate();
-
- int64_t bandwidth_delta =
- std::abs(new_bandwidth_estimate.ToBitsPerSecond() -
- bandwidth_estimate_sent_to_client_.ToBitsPerSecond());
-
- // Define "substantial" difference as a 50% increase or decrease from the
- // last estimate.
- bool substantial_difference =
- bandwidth_delta >
- 0.5 * bandwidth_estimate_sent_to_client_.ToBitsPerSecond();
- if (!substantial_difference) {
- return;
- }
-
- if (add_cached_network_parameters_to_address_token()) {
- if (version().UsesTls()) {
- if (version().HasIetfQuicFrames() && MaybeSendAddressToken()) {
- bandwidth_estimate_sent_to_client_ = new_bandwidth_estimate;
- }
- } else {
- absl::optional<CachedNetworkParameters> cached_network_params =
- GenerateCachedNetworkParameters();
-
- if (cached_network_params.has_value()) {
- bandwidth_estimate_sent_to_client_ = new_bandwidth_estimate;
- QUIC_DVLOG(1) << "Server: sending new bandwidth estimate (KBytes/s): "
- << bandwidth_estimate_sent_to_client_.ToKBytesPerSecond();
-
- QUICHE_DCHECK_EQ(
- BandwidthToCachedParameterBytesPerSecond(
- bandwidth_estimate_sent_to_client_),
- cached_network_params->bandwidth_estimate_bytes_per_second());
-
- crypto_stream_->SendServerConfigUpdate(&cached_network_params.value());
-
- connection()->OnSendConnectionState(*cached_network_params);
- }
- }
- } else {
- bandwidth_estimate_sent_to_client_ = new_bandwidth_estimate;
- QUIC_DVLOG(1) << "Server: sending new bandwidth estimate (KBytes/s): "
- << bandwidth_estimate_sent_to_client_.ToKBytesPerSecond();
-
- // Include max bandwidth in the update.
- QuicBandwidth max_bandwidth_estimate =
- bandwidth_recorder->MaxBandwidthEstimate();
- int32_t max_bandwidth_timestamp =
- bandwidth_recorder->MaxBandwidthTimestamp();
-
- // Fill the proto before passing it to the crypto stream to send.
- const int32_t bw_estimate_bytes_per_second =
- BandwidthToCachedParameterBytesPerSecond(
- bandwidth_estimate_sent_to_client_);
- const int32_t max_bw_estimate_bytes_per_second =
- BandwidthToCachedParameterBytesPerSecond(max_bandwidth_estimate);
- 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;
-
- CachedNetworkParameters cached_network_params;
- 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(
- max_bandwidth_timestamp);
- cached_network_params.set_min_rtt_ms(
- sent_packet_manager.GetRttStats()->min_rtt().ToMilliseconds());
- cached_network_params.set_previous_connection_state(
- bandwidth_recorder->EstimateRecordedDuringSlowStart()
- ? CachedNetworkParameters::SLOW_START
- : CachedNetworkParameters::CONGESTION_AVOIDANCE);
- cached_network_params.set_timestamp(
- connection()->clock()->WallNow().ToUNIXSeconds());
- if (!serving_region_.empty()) {
- cached_network_params.set_serving_region(serving_region_);
- }
-
- crypto_stream_->SendServerConfigUpdate(&cached_network_params);
-
- connection()->OnSendConnectionState(cached_network_params);
- }
-
- last_scup_time_ = now;
- last_scup_packet_number_ =
- connection()->sent_packet_manager().GetLargestSentPacket();
-}
-
-bool QuicServerSessionBase::ShouldCreateIncomingStream(QuicStreamId id) {
- if (!connection()->connected()) {
- QUIC_BUG(quic_bug_10393_2)
- << "ShouldCreateIncomingStream called when disconnected";
- return false;
- }
-
- if (QuicUtils::IsServerInitiatedStreamId(transport_version(), id)) {
- QUIC_BUG(quic_bug_10393_3)
- << "ShouldCreateIncomingStream called with server initiated "
- "stream ID.";
- return false;
- }
-
- if (QuicUtils::IsServerInitiatedStreamId(transport_version(), id)) {
- QUIC_DLOG(INFO) << "Invalid incoming even stream_id:" << id;
- connection()->CloseConnection(
- QUIC_INVALID_STREAM_ID, "Client created even numbered stream",
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
- return false;
- }
- return true;
-}
-
-bool QuicServerSessionBase::ShouldCreateOutgoingBidirectionalStream() {
- if (!connection()->connected()) {
- QUIC_BUG(quic_bug_12513_2)
- << "ShouldCreateOutgoingBidirectionalStream called when disconnected";
- return false;
- }
- if (!crypto_stream_->encryption_established()) {
- QUIC_BUG(quic_bug_10393_4)
- << "Encryption not established so no outgoing stream created.";
- return false;
- }
-
- return CanOpenNextOutgoingBidirectionalStream();
-}
-
-bool QuicServerSessionBase::ShouldCreateOutgoingUnidirectionalStream() {
- if (!connection()->connected()) {
- QUIC_BUG(quic_bug_12513_3)
- << "ShouldCreateOutgoingUnidirectionalStream called when disconnected";
- return false;
- }
- if (!crypto_stream_->encryption_established()) {
- QUIC_BUG(quic_bug_10393_5)
- << "Encryption not established so no outgoing stream created.";
- return false;
- }
-
- return CanOpenNextOutgoingUnidirectionalStream();
-}
-
-QuicCryptoServerStreamBase* QuicServerSessionBase::GetMutableCryptoStream() {
- return crypto_stream_.get();
-}
-
-const QuicCryptoServerStreamBase* QuicServerSessionBase::GetCryptoStream()
- const {
- return crypto_stream_.get();
-}
-
-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()));
-}
-
-void QuicServerSessionBase::SendSettingsToCryptoStream() {
- if (!version().UsesTls()) {
- return;
- }
- std::unique_ptr<char[]> buffer;
- QuicByteCount buffer_size =
- HttpEncoder::SerializeSettingsFrame(settings(), &buffer);
-
- std::unique_ptr<ApplicationState> serialized_settings =
- std::make_unique<ApplicationState>(buffer.get(),
- buffer.get() + buffer_size);
- GetMutableCryptoStream()->SetServerApplicationStateForResumption(
- std::move(serialized_settings));
-}
-
-QuicSSLConfig QuicServerSessionBase::GetSSLConfig() const {
- QUICHE_DCHECK(crypto_config_ && crypto_config_->proof_source());
-
- QuicSSLConfig ssl_config = QuicSpdySession::GetSSLConfig();
-
- ssl_config.disable_ticket_support =
- GetQuicFlag(FLAGS_quic_disable_server_tls_resumption);
-
- if (!crypto_config_ || !crypto_config_->proof_source()) {
- return ssl_config;
- }
-
- absl::InlinedVector<uint16_t, 8> signature_algorithms =
- crypto_config_->proof_source()->SupportedTlsSignatureAlgorithms();
- if (!signature_algorithms.empty()) {
- ssl_config.signing_algorithm_prefs = std::move(signature_algorithms);
- }
-
- return ssl_config;
-}
-
-absl::optional<CachedNetworkParameters>
-QuicServerSessionBase::GenerateCachedNetworkParameters() const {
- QUICHE_DCHECK(add_cached_network_parameters_to_address_token());
- const QuicSentPacketManager& sent_packet_manager =
- connection()->sent_packet_manager();
- const QuicSustainedBandwidthRecorder* bandwidth_recorder =
- sent_packet_manager.SustainedBandwidthRecorder();
-
- CachedNetworkParameters cached_network_params;
- cached_network_params.set_timestamp(
- connection()->clock()->WallNow().ToUNIXSeconds());
-
- if (!sent_packet_manager.GetRttStats()->min_rtt().IsZero()) {
- cached_network_params.set_min_rtt_ms(
- 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 (!serving_region_.empty()) {
- cached_network_params.set_serving_region(serving_region_);
- }
-
- return cached_network_params;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/http/quic_server_session_base.h b/chromium/net/third_party/quiche/src/quic/core/http/quic_server_session_base.h
deleted file mode 100644
index 5903de65a1a..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/http/quic_server_session_base.h
+++ /dev/null
@@ -1,149 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// A server specific QuicSession subclass.
-
-#ifndef QUICHE_QUIC_CORE_HTTP_QUIC_SERVER_SESSION_BASE_H_
-#define QUICHE_QUIC_CORE_HTTP_QUIC_SERVER_SESSION_BASE_H_
-
-#include <cstdint>
-#include <memory>
-#include <set>
-#include <string>
-#include <vector>
-
-#include "quic/core/crypto/quic_compressed_certs_cache.h"
-#include "quic/core/http/quic_spdy_session.h"
-#include "quic/core/quic_crypto_server_stream_base.h"
-#include "quic/core/quic_packets.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-class QuicConfig;
-class QuicConnection;
-class QuicCryptoServerConfig;
-
-namespace test {
-class QuicServerSessionBasePeer;
-class QuicSimpleServerSessionPeer;
-} // namespace test
-
-class QUIC_EXPORT_PRIVATE QuicServerSessionBase : public QuicSpdySession {
- public:
- // Does not take ownership of |connection|. |crypto_config| must outlive the
- // session. |helper| must outlive any created crypto streams.
- QuicServerSessionBase(const QuicConfig& config,
- const ParsedQuicVersionVector& supported_versions,
- QuicConnection* connection,
- QuicSession::Visitor* visitor,
- QuicCryptoServerStreamBase::Helper* helper,
- const QuicCryptoServerConfig* crypto_config,
- QuicCompressedCertsCache* compressed_certs_cache);
- QuicServerSessionBase(const QuicServerSessionBase&) = delete;
- QuicServerSessionBase& operator=(const QuicServerSessionBase&) = delete;
-
- // Override the base class to cancel any ongoing asychronous crypto.
- void OnConnectionClosed(const QuicConnectionCloseFrame& frame,
- ConnectionCloseSource source) override;
-
- // Sends a server config update to the client, containing new bandwidth
- // estimate.
- void OnCongestionWindowChange(QuicTime now) override;
-
- ~QuicServerSessionBase() override;
-
- void Initialize() override;
-
- const QuicCryptoServerStreamBase* crypto_stream() const {
- return crypto_stream_.get();
- }
-
- // Override base class to process bandwidth related config received from
- // client.
- void OnConfigNegotiated() override;
-
- void set_serving_region(const std::string& serving_region) {
- serving_region_ = serving_region;
- }
-
- QuicSSLConfig GetSSLConfig() const override;
-
- protected:
- // QuicSession methods(override them with return type of QuicSpdyStream*):
- QuicCryptoServerStreamBase* GetMutableCryptoStream() override;
-
- const QuicCryptoServerStreamBase* GetCryptoStream() const override;
-
- absl::optional<CachedNetworkParameters> GenerateCachedNetworkParameters()
- const override;
-
- // If an outgoing stream can be created, return true.
- // Return false when connection is closed or forward secure encryption hasn't
- // established yet or number of server initiated streams already reaches the
- // upper limit.
- bool ShouldCreateOutgoingBidirectionalStream() override;
- bool ShouldCreateOutgoingUnidirectionalStream() override;
-
- // If we should create an incoming stream, returns true. Otherwise
- // does error handling, including communicating the error to the client and
- // possibly closing the connection, and returns false.
- bool ShouldCreateIncomingStream(QuicStreamId id) override;
-
- virtual std::unique_ptr<QuicCryptoServerStreamBase>
- CreateQuicCryptoServerStream(
- const QuicCryptoServerConfig* crypto_config,
- QuicCompressedCertsCache* compressed_certs_cache) = 0;
-
- const QuicCryptoServerConfig* crypto_config() { return crypto_config_; }
-
- QuicCryptoServerStreamBase::Helper* stream_helper() { return helper_; }
-
- private:
- friend class test::QuicServerSessionBasePeer;
- friend class test::QuicSimpleServerSessionPeer;
-
- // Informs the QuicCryptoStream of the SETTINGS that will be used on this
- // connection, so that the server crypto stream knows whether to accept 0-RTT
- // data.
- void SendSettingsToCryptoStream();
-
- const QuicCryptoServerConfig* crypto_config_;
-
- // The cache which contains most recently compressed certs.
- // Owned by QuicDispatcher.
- QuicCompressedCertsCache* compressed_certs_cache_;
-
- std::unique_ptr<QuicCryptoServerStreamBase> crypto_stream_;
-
- // Pointer to the helper used to create crypto server streams. Must outlive
- // streams created via CreateQuicCryptoServerStream.
- QuicCryptoServerStreamBase::Helper* helper_;
-
- // Whether bandwidth resumption is enabled for this connection.
- bool bandwidth_resumption_enabled_;
-
- // 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.
- std::string serving_region_;
-
- // Time at which we send the last SCUP to the client.
- QuicTime last_scup_time_;
-
- // Number of packets sent to the peer, at the time we last sent a SCUP.
- QuicPacketNumber last_scup_packet_number_;
-
- // Converts QuicBandwidth to an int32 bytes/second that can be
- // stored in CachedNetworkParameters. TODO(jokulik): This function
- // should go away once we fix http://b//27897982
- int32_t BandwidthToCachedParameterBytesPerSecond(
- const QuicBandwidth& bandwidth) const;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_HTTP_QUIC_SERVER_SESSION_BASE_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/http/quic_server_session_base_test.cc b/chromium/net/third_party/quiche/src/quic/core/http/quic_server_session_base_test.cc
deleted file mode 100644
index 2d144d2465c..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/http/quic_server_session_base_test.cc
+++ /dev/null
@@ -1,814 +0,0 @@
-// Copyright 2013 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 "quic/core/http/quic_server_session_base.h"
-
-#include <cstdint>
-#include <memory>
-#include <string>
-#include <utility>
-
-#include "absl/memory/memory.h"
-#include "quic/core/crypto/null_encrypter.h"
-#include "quic/core/crypto/quic_crypto_server_config.h"
-#include "quic/core/crypto/quic_random.h"
-#include "quic/core/proto/cached_network_parameters_proto.h"
-#include "quic/core/quic_connection.h"
-#include "quic/core/quic_crypto_server_stream.h"
-#include "quic/core/quic_crypto_server_stream_base.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_utils.h"
-#include "quic/core/tls_server_handshaker.h"
-#include "quic/platform/api/quic_expect_bug.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_socket_address.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/crypto_test_utils.h"
-#include "quic/test_tools/fake_proof_source.h"
-#include "quic/test_tools/mock_quic_session_visitor.h"
-#include "quic/test_tools/quic_config_peer.h"
-#include "quic/test_tools/quic_connection_peer.h"
-#include "quic/test_tools/quic_crypto_server_config_peer.h"
-#include "quic/test_tools/quic_sent_packet_manager_peer.h"
-#include "quic/test_tools/quic_server_session_base_peer.h"
-#include "quic/test_tools/quic_session_peer.h"
-#include "quic/test_tools/quic_spdy_session_peer.h"
-#include "quic/test_tools/quic_stream_id_manager_peer.h"
-#include "quic/test_tools/quic_stream_peer.h"
-#include "quic/test_tools/quic_sustained_bandwidth_recorder_peer.h"
-#include "quic/test_tools/quic_test_utils.h"
-#include "quic/tools/quic_memory_cache_backend.h"
-#include "quic/tools/quic_simple_server_stream.h"
-
-using testing::_;
-using testing::StrictMock;
-
-using testing::AtLeast;
-
-namespace quic {
-namespace test {
-namespace {
-
-// Data to be sent on a request stream. In Google QUIC, this is interpreted as
-// DATA payload (there is no framing on request streams). In IETF QUIC, this is
-// interpreted as HEADERS frame (type 0x1) with payload length 122 ('z'). Since
-// no payload is included, QPACK decoder will not be invoked.
-const char* const kStreamData = "\1z";
-
-class TestServerSession : public QuicServerSessionBase {
- public:
- TestServerSession(const QuicConfig& config,
- QuicConnection* connection,
- QuicSession::Visitor* visitor,
- QuicCryptoServerStreamBase::Helper* helper,
- const QuicCryptoServerConfig* crypto_config,
- QuicCompressedCertsCache* compressed_certs_cache,
- QuicSimpleServerBackend* quic_simple_server_backend)
- : QuicServerSessionBase(config,
- CurrentSupportedVersions(),
- connection,
- visitor,
- helper,
- crypto_config,
- compressed_certs_cache),
- quic_simple_server_backend_(quic_simple_server_backend) {}
-
- ~TestServerSession() override { DeleteConnection(); }
-
- MOCK_METHOD(bool,
- WriteControlFrame,
- (const QuicFrame& frame, TransmissionType type),
- (override));
-
- protected:
- QuicSpdyStream* CreateIncomingStream(QuicStreamId id) override {
- if (!ShouldCreateIncomingStream(id)) {
- return nullptr;
- }
- QuicSpdyStream* stream = new QuicSimpleServerStream(
- id, this, BIDIRECTIONAL, quic_simple_server_backend_);
- ActivateStream(absl::WrapUnique(stream));
- return stream;
- }
-
- QuicSpdyStream* CreateIncomingStream(PendingStream* pending) override {
- QuicSpdyStream* stream =
- new QuicSimpleServerStream(pending, this, quic_simple_server_backend_);
- ActivateStream(absl::WrapUnique(stream));
- return stream;
- }
-
- QuicSpdyStream* CreateOutgoingBidirectionalStream() override {
- QUICHE_DCHECK(false);
- return nullptr;
- }
-
- QuicSpdyStream* CreateOutgoingUnidirectionalStream() override {
- if (!ShouldCreateOutgoingUnidirectionalStream()) {
- return nullptr;
- }
-
- QuicSpdyStream* stream = new QuicSimpleServerStream(
- GetNextOutgoingUnidirectionalStreamId(), this, WRITE_UNIDIRECTIONAL,
- quic_simple_server_backend_);
- ActivateStream(absl::WrapUnique(stream));
- return stream;
- }
-
- std::unique_ptr<QuicCryptoServerStreamBase> CreateQuicCryptoServerStream(
- const QuicCryptoServerConfig* crypto_config,
- QuicCompressedCertsCache* compressed_certs_cache) override {
- return CreateCryptoServerStream(crypto_config, compressed_certs_cache, this,
- stream_helper());
- }
-
- private:
- QuicSimpleServerBackend*
- quic_simple_server_backend_; // Owned by QuicServerSessionBaseTest
-};
-
-const size_t kMaxStreamsForTest = 10;
-
-class QuicServerSessionBaseTest : public QuicTestWithParam<ParsedQuicVersion> {
- protected:
- QuicServerSessionBaseTest()
- : QuicServerSessionBaseTest(crypto_test_utils::ProofSourceForTesting()) {}
-
- explicit QuicServerSessionBaseTest(std::unique_ptr<ProofSource> proof_source)
- : crypto_config_(QuicCryptoServerConfig::TESTING,
- QuicRandom::GetInstance(),
- std::move(proof_source),
- KeyExchangeSource::Default()),
- compressed_certs_cache_(
- QuicCompressedCertsCache::kQuicCompressedCertsCacheSize) {
- config_.SetMaxBidirectionalStreamsToSend(kMaxStreamsForTest);
- config_.SetMaxUnidirectionalStreamsToSend(kMaxStreamsForTest);
- QuicConfigPeer::SetReceivedMaxBidirectionalStreams(&config_,
- kMaxStreamsForTest);
- QuicConfigPeer::SetReceivedMaxUnidirectionalStreams(&config_,
- kMaxStreamsForTest);
- config_.SetInitialStreamFlowControlWindowToSend(
- kInitialStreamFlowControlWindowForTest);
- config_.SetInitialSessionFlowControlWindowToSend(
- kInitialSessionFlowControlWindowForTest);
-
- ParsedQuicVersionVector supported_versions = SupportedVersions(version());
- connection_ = new StrictMock<MockQuicConnection>(
- &helper_, &alarm_factory_, Perspective::IS_SERVER, supported_versions);
- connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
- connection_->SetEncrypter(
- ENCRYPTION_FORWARD_SECURE,
- std::make_unique<NullEncrypter>(connection_->perspective()));
- session_ = std::make_unique<TestServerSession>(
- config_, connection_, &owner_, &stream_helper_, &crypto_config_,
- &compressed_certs_cache_, &memory_cache_backend_);
- MockClock clock;
- handshake_message_ = crypto_config_.AddDefaultConfig(
- QuicRandom::GetInstance(), &clock,
- QuicCryptoServerConfig::ConfigOptions());
- session_->Initialize();
- QuicConfigPeer::SetReceivedInitialSessionFlowControlWindow(
- session_->config(), kMinimumFlowControlSendWindow);
- session_->OnConfigNegotiated();
- if (version().SupportsAntiAmplificationLimit()) {
- QuicConnectionPeer::SetAddressValidated(connection_);
- }
- }
-
- QuicStreamId GetNthClientInitiatedBidirectionalId(int n) {
- return GetNthClientInitiatedBidirectionalStreamId(transport_version(), n);
- }
-
- QuicStreamId GetNthServerInitiatedUnidirectionalId(int n) {
- return quic::test::GetNthServerInitiatedUnidirectionalStreamId(
- transport_version(), n);
- }
-
- ParsedQuicVersion version() const { return GetParam(); }
-
- QuicTransportVersion transport_version() const {
- return version().transport_version;
- }
-
- // Create and inject a STOP_SENDING frame. In GOOGLE QUIC, receiving a
- // RST_STREAM frame causes a two-way close. For IETF QUIC, RST_STREAM causes a
- // one-way close. This method can be used to inject a STOP_SENDING, which
- // would cause a close in the opposite direction. This allows tests to do the
- // extra work to get a two-way (full) close where desired. Also sets up
- // expects needed to ensure that the STOP_SENDING worked as expected.
- void InjectStopSendingFrame(QuicStreamId stream_id) {
- if (!VersionHasIetfQuicFrames(transport_version())) {
- // Only needed for version 99/IETF QUIC. Noop otherwise.
- return;
- }
- QuicStopSendingFrame stop_sending(kInvalidControlFrameId, stream_id,
- QUIC_ERROR_PROCESSING_STREAM);
- EXPECT_CALL(owner_, OnStopSendingReceived(_)).Times(1);
- // Expect the RESET_STREAM that is generated in response to receiving a
- // STOP_SENDING.
- EXPECT_CALL(*session_, WriteControlFrame(_, _));
- EXPECT_CALL(*connection_,
- OnStreamReset(stream_id, QUIC_ERROR_PROCESSING_STREAM));
- session_->OnStopSendingFrame(stop_sending);
- }
-
- StrictMock<MockQuicSessionVisitor> owner_;
- StrictMock<MockQuicCryptoServerStreamHelper> stream_helper_;
- MockQuicConnectionHelper helper_;
- MockAlarmFactory alarm_factory_;
- StrictMock<MockQuicConnection>* connection_;
- QuicConfig config_;
- QuicCryptoServerConfig crypto_config_;
- QuicCompressedCertsCache compressed_certs_cache_;
- QuicMemoryCacheBackend memory_cache_backend_;
- std::unique_ptr<TestServerSession> session_;
- std::unique_ptr<CryptoHandshakeMessage> handshake_message_;
-};
-
-// Compares CachedNetworkParameters.
-MATCHER_P(EqualsProto, network_params, "") {
- CachedNetworkParameters reference(network_params);
- return (arg->bandwidth_estimate_bytes_per_second() ==
- reference.bandwidth_estimate_bytes_per_second() &&
- arg->bandwidth_estimate_bytes_per_second() ==
- reference.bandwidth_estimate_bytes_per_second() &&
- arg->max_bandwidth_estimate_bytes_per_second() ==
- reference.max_bandwidth_estimate_bytes_per_second() &&
- arg->max_bandwidth_timestamp_seconds() ==
- reference.max_bandwidth_timestamp_seconds() &&
- arg->min_rtt_ms() == reference.min_rtt_ms() &&
- arg->previous_connection_state() ==
- reference.previous_connection_state());
-}
-
-INSTANTIATE_TEST_SUITE_P(Tests,
- QuicServerSessionBaseTest,
- ::testing::ValuesIn(AllSupportedVersions()),
- ::testing::PrintToStringParamName());
-
-TEST_P(QuicServerSessionBaseTest, CloseStreamDueToReset) {
- // Send some data open a stream, then reset it.
- QuicStreamFrame data1(GetNthClientInitiatedBidirectionalId(0), false, 0,
- kStreamData);
- session_->OnStreamFrame(data1);
- EXPECT_EQ(1u, QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()));
-
- // Send a reset (and expect the peer to send a RST in response).
- QuicRstStreamFrame rst1(kInvalidControlFrameId,
- GetNthClientInitiatedBidirectionalId(0),
- QUIC_ERROR_PROCESSING_STREAM, 0);
- EXPECT_CALL(owner_, OnRstStreamReceived(_)).Times(1);
- if (!VersionHasIetfQuicFrames(transport_version())) {
- // For non-version 99, the RESET_STREAM will do the full close.
- // Set up expects accordingly.
- EXPECT_CALL(*session_, WriteControlFrame(_, _));
- EXPECT_CALL(*connection_,
- OnStreamReset(GetNthClientInitiatedBidirectionalId(0),
- QUIC_RST_ACKNOWLEDGEMENT));
- }
- session_->OnRstStream(rst1);
-
- // For version-99 will create and receive a stop-sending, completing
- // the full-close expected by this test.
- InjectStopSendingFrame(GetNthClientInitiatedBidirectionalId(0));
-
- EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()));
- // Send the same two bytes of payload in a new packet.
- session_->OnStreamFrame(data1);
-
- // The stream should not be re-opened.
- EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()));
- EXPECT_TRUE(connection_->connected());
-}
-
-TEST_P(QuicServerSessionBaseTest, NeverOpenStreamDueToReset) {
- // Send a reset (and expect the peer to send a RST in response).
- QuicRstStreamFrame rst1(kInvalidControlFrameId,
- GetNthClientInitiatedBidirectionalId(0),
- QUIC_ERROR_PROCESSING_STREAM, 0);
- EXPECT_CALL(owner_, OnRstStreamReceived(_)).Times(1);
- if (!VersionHasIetfQuicFrames(transport_version())) {
- // For non-version 99, the RESET_STREAM will do the full close.
- // Set up expects accordingly.
- EXPECT_CALL(*session_, WriteControlFrame(_, _));
- EXPECT_CALL(*connection_,
- OnStreamReset(GetNthClientInitiatedBidirectionalId(0),
- QUIC_RST_ACKNOWLEDGEMENT));
- }
- session_->OnRstStream(rst1);
-
- // For version-99 will create and receive a stop-sending, completing
- // the full-close expected by this test.
- InjectStopSendingFrame(GetNthClientInitiatedBidirectionalId(0));
-
- EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()));
-
- QuicStreamFrame data1(GetNthClientInitiatedBidirectionalId(0), false, 0,
- kStreamData);
- session_->OnStreamFrame(data1);
-
- // The stream should never be opened, now that the reset is received.
- EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()));
- EXPECT_TRUE(connection_->connected());
-}
-
-TEST_P(QuicServerSessionBaseTest, AcceptClosedStream) {
- // Send some data to open two streams.
- QuicStreamFrame frame1(GetNthClientInitiatedBidirectionalId(0), false, 0,
- kStreamData);
- QuicStreamFrame frame2(GetNthClientInitiatedBidirectionalId(1), false, 0,
- kStreamData);
- session_->OnStreamFrame(frame1);
- session_->OnStreamFrame(frame2);
- EXPECT_EQ(2u, QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()));
-
- // Send a reset (and expect the peer to send a RST in response).
- QuicRstStreamFrame rst(kInvalidControlFrameId,
- GetNthClientInitiatedBidirectionalId(0),
- QUIC_ERROR_PROCESSING_STREAM, 0);
- EXPECT_CALL(owner_, OnRstStreamReceived(_)).Times(1);
- if (!VersionHasIetfQuicFrames(transport_version())) {
- // For non-version 99, the RESET_STREAM will do the full close.
- // Set up expects accordingly.
- EXPECT_CALL(*session_, WriteControlFrame(_, _));
- EXPECT_CALL(*connection_,
- OnStreamReset(GetNthClientInitiatedBidirectionalId(0),
- QUIC_RST_ACKNOWLEDGEMENT));
- }
- session_->OnRstStream(rst);
-
- // For version-99 will create and receive a stop-sending, completing
- // the full-close expected by this test.
- InjectStopSendingFrame(GetNthClientInitiatedBidirectionalId(0));
-
- // If we were tracking, we'd probably want to reject this because it's data
- // past the reset point of stream 3. As it's a closed stream we just drop the
- // data on the floor, but accept the packet because it has data for stream 5.
- QuicStreamFrame frame3(GetNthClientInitiatedBidirectionalId(0), false, 2,
- kStreamData);
- QuicStreamFrame frame4(GetNthClientInitiatedBidirectionalId(1), false, 2,
- kStreamData);
- session_->OnStreamFrame(frame3);
- session_->OnStreamFrame(frame4);
- // The stream should never be opened, now that the reset is received.
- EXPECT_EQ(1u, QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()));
- EXPECT_TRUE(connection_->connected());
-}
-
-TEST_P(QuicServerSessionBaseTest, MaxOpenStreams) {
- // Test that the server refuses if a client attempts to open too many data
- // streams. For versions other than version 99, the server accepts slightly
- // more than the negotiated stream limit to deal with rare cases where a
- // client FIN/RST is lost.
- connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
- session_->OnConfigNegotiated();
- if (!VersionHasIetfQuicFrames(transport_version())) {
- // The slightly increased stream limit is set during config negotiation. It
- // is either an increase of 10 over negotiated limit, or a fixed percentage
- // scaling, whichever is larger. Test both before continuing.
- EXPECT_LT(kMaxStreamsMultiplier * kMaxStreamsForTest,
- kMaxStreamsForTest + kMaxStreamsMinimumIncrement);
- EXPECT_EQ(kMaxStreamsForTest + kMaxStreamsMinimumIncrement,
- session_->max_open_incoming_bidirectional_streams());
- }
- EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()));
- QuicStreamId stream_id = GetNthClientInitiatedBidirectionalId(0);
- // Open the max configured number of streams, should be no problem.
- for (size_t i = 0; i < kMaxStreamsForTest; ++i) {
- EXPECT_TRUE(QuicServerSessionBasePeer::GetOrCreateStream(session_.get(),
- stream_id));
- stream_id += QuicUtils::StreamIdDelta(transport_version());
- }
-
- if (!VersionHasIetfQuicFrames(transport_version())) {
- // Open more streams: server should accept slightly more than the limit.
- // Excess streams are for non-version-99 only.
- for (size_t i = 0; i < kMaxStreamsMinimumIncrement; ++i) {
- EXPECT_TRUE(QuicServerSessionBasePeer::GetOrCreateStream(session_.get(),
- stream_id));
- stream_id += QuicUtils::StreamIdDelta(transport_version());
- }
- }
- // Now violate the server's internal stream limit.
- stream_id += QuicUtils::StreamIdDelta(transport_version());
-
- if (!VersionHasIetfQuicFrames(transport_version())) {
- // For non-version 99, QUIC responds to an attempt to exceed the stream
- // limit by resetting the stream.
- EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
- EXPECT_CALL(*session_, WriteControlFrame(_, _));
- EXPECT_CALL(*connection_, OnStreamReset(stream_id, QUIC_REFUSED_STREAM));
- } else {
- // In version 99 QUIC responds to an attempt to exceed the stream limit by
- // closing the connection.
- EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(1);
- }
- // Even if the connection remains open, the stream creation should fail.
- EXPECT_FALSE(
- QuicServerSessionBasePeer::GetOrCreateStream(session_.get(), stream_id));
-}
-
-TEST_P(QuicServerSessionBaseTest, MaxAvailableBidirectionalStreams) {
- // Test that the server closes the connection if a client makes too many data
- // streams available. The server accepts slightly more than the negotiated
- // stream limit to deal with rare cases where a client FIN/RST is lost.
- connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
- session_->OnConfigNegotiated();
- const size_t kAvailableStreamLimit =
- session_->MaxAvailableBidirectionalStreams();
-
- EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()));
- EXPECT_TRUE(QuicServerSessionBasePeer::GetOrCreateStream(
- session_.get(), GetNthClientInitiatedBidirectionalId(0)));
-
- // Establish available streams up to the server's limit.
- QuicStreamId next_id = QuicUtils::StreamIdDelta(transport_version());
- const int kLimitingStreamId =
- GetNthClientInitiatedBidirectionalId(kAvailableStreamLimit + 1);
- if (!VersionHasIetfQuicFrames(transport_version())) {
- // This exceeds the stream limit. In versions other than 99
- // this is allowed. Version 99 hews to the IETF spec and does
- // not allow it.
- EXPECT_TRUE(QuicServerSessionBasePeer::GetOrCreateStream(
- session_.get(), kLimitingStreamId));
- // A further available stream will result in connection close.
- EXPECT_CALL(*connection_,
- CloseConnection(QUIC_TOO_MANY_AVAILABLE_STREAMS, _, _));
- } else {
- // A further available stream will result in connection close.
- EXPECT_CALL(*connection_, CloseConnection(QUIC_INVALID_STREAM_ID, _, _));
- }
-
- // This forces stream kLimitingStreamId + 2 to become available, which
- // violates the quota.
- EXPECT_FALSE(QuicServerSessionBasePeer::GetOrCreateStream(
- session_.get(), kLimitingStreamId + 2 * next_id));
-}
-
-TEST_P(QuicServerSessionBaseTest, GetEvenIncomingError) {
- // Incoming streams on the server session must be odd.
- const QuicErrorCode expected_error =
- VersionHasIetfQuicFrames(transport_version())
- ? QUIC_HTTP_STREAM_WRONG_DIRECTION
- : QUIC_INVALID_STREAM_ID;
- EXPECT_CALL(*connection_, CloseConnection(expected_error, _, _));
- EXPECT_EQ(nullptr, QuicServerSessionBasePeer::GetOrCreateStream(
- session_.get(),
- session_->next_outgoing_unidirectional_stream_id()));
-}
-
-TEST_P(QuicServerSessionBaseTest, GetStreamDisconnected) {
- // EXPECT_QUIC_BUG tests are expensive so only run one instance of them.
- if (version() != AllSupportedVersions()[0]) {
- return;
- }
-
- // Don't create new streams if the connection is disconnected.
- QuicConnectionPeer::TearDownLocalConnectionState(connection_);
- EXPECT_QUIC_BUG(QuicServerSessionBasePeer::GetOrCreateStream(
- session_.get(), GetNthClientInitiatedBidirectionalId(0)),
- "ShouldCreateIncomingStream called when disconnected");
-}
-
-class MockQuicCryptoServerStream : public QuicCryptoServerStream {
- public:
- explicit MockQuicCryptoServerStream(
- const QuicCryptoServerConfig* crypto_config,
- QuicCompressedCertsCache* compressed_certs_cache,
- QuicServerSessionBase* session,
- QuicCryptoServerStreamBase::Helper* helper)
- : QuicCryptoServerStream(crypto_config,
- compressed_certs_cache,
- session,
- helper) {}
- MockQuicCryptoServerStream(const MockQuicCryptoServerStream&) = delete;
- MockQuicCryptoServerStream& operator=(const MockQuicCryptoServerStream&) =
- delete;
- ~MockQuicCryptoServerStream() override {}
-
- MOCK_METHOD(void,
- SendServerConfigUpdate,
- (const CachedNetworkParameters*),
- (override));
-};
-
-class MockTlsServerHandshaker : public TlsServerHandshaker {
- public:
- explicit MockTlsServerHandshaker(QuicServerSessionBase* session,
- const QuicCryptoServerConfig* crypto_config)
- : TlsServerHandshaker(session, crypto_config) {}
- MockTlsServerHandshaker(const MockTlsServerHandshaker&) = delete;
- MockTlsServerHandshaker& operator=(const MockTlsServerHandshaker&) = delete;
- ~MockTlsServerHandshaker() override {}
-
- MOCK_METHOD(void, SendServerConfigUpdate, (const CachedNetworkParameters*),
- (override));
-
- MOCK_METHOD(std::string, GetAddressToken, (const CachedNetworkParameters*),
- (const, override));
-};
-
-TEST_P(QuicServerSessionBaseTest, BandwidthEstimates) {
- if (version().UsesTls() && !version().HasIetfQuicFrames()) {
- // Skip the Txxx versions.
- return;
- }
-
- // Test that bandwidth estimate updates are sent to the client, only when
- // bandwidth resumption is enabled, the bandwidth estimate has changed
- // sufficiently, enough time has passed,
- // and we don't have any other data to write.
-
- // Client has sent kBWRE connection option to trigger bandwidth resumption.
- QuicTagVector copt;
- copt.push_back(kBWRE);
- QuicConfigPeer::SetReceivedConnectionOptions(session_->config(), copt);
- connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
- session_->OnConfigNegotiated();
- EXPECT_TRUE(
- QuicServerSessionBasePeer::IsBandwidthResumptionEnabled(session_.get()));
-
- int32_t bandwidth_estimate_kbytes_per_second = 123;
- int32_t max_bandwidth_estimate_kbytes_per_second = 134;
- int32_t max_bandwidth_estimate_timestamp = 1122334455;
- const std::string serving_region = "not a real region";
- session_->set_serving_region(serving_region);
-
- if (!VersionUsesHttp3(transport_version())) {
- session_->UnregisterStreamPriority(
- QuicUtils::GetHeadersStreamId(transport_version()),
- /*is_static=*/true);
- }
- QuicServerSessionBasePeer::SetCryptoStream(session_.get(), nullptr);
- MockQuicCryptoServerStream* quic_crypto_stream = nullptr;
- MockTlsServerHandshaker* tls_server_stream = nullptr;
- if (version().handshake_protocol == PROTOCOL_QUIC_CRYPTO) {
- quic_crypto_stream = new MockQuicCryptoServerStream(
- &crypto_config_, &compressed_certs_cache_, session_.get(),
- &stream_helper_);
- QuicServerSessionBasePeer::SetCryptoStream(session_.get(),
- quic_crypto_stream);
- } else {
- tls_server_stream =
- new MockTlsServerHandshaker(session_.get(), &crypto_config_);
- QuicServerSessionBasePeer::SetCryptoStream(session_.get(),
- tls_server_stream);
- }
- if (!VersionUsesHttp3(transport_version())) {
- session_->RegisterStreamPriority(
- QuicUtils::GetHeadersStreamId(transport_version()),
- /*is_static=*/true,
- spdy::SpdyStreamPrecedence(QuicStream::kDefaultPriority));
- }
-
- // Set some initial bandwidth values.
- QuicSentPacketManager* sent_packet_manager =
- QuicConnectionPeer::GetSentPacketManager(session_->connection());
- QuicSustainedBandwidthRecorder& bandwidth_recorder =
- QuicSentPacketManagerPeer::GetBandwidthRecorder(sent_packet_manager);
- // Seed an rtt measurement equal to the initial default rtt.
- RttStats* rtt_stats =
- const_cast<RttStats*>(sent_packet_manager->GetRttStats());
- rtt_stats->UpdateRtt(rtt_stats->initial_rtt(), QuicTime::Delta::Zero(),
- QuicTime::Zero());
- QuicSustainedBandwidthRecorderPeer::SetBandwidthEstimate(
- &bandwidth_recorder, bandwidth_estimate_kbytes_per_second);
- QuicSustainedBandwidthRecorderPeer::SetMaxBandwidthEstimate(
- &bandwidth_recorder, max_bandwidth_estimate_kbytes_per_second,
- max_bandwidth_estimate_timestamp);
- // Queue up some pending data.
- if (!VersionUsesHttp3(transport_version())) {
- session_->MarkConnectionLevelWriteBlocked(
- QuicUtils::GetHeadersStreamId(transport_version()));
- } else {
- session_->MarkConnectionLevelWriteBlocked(
- QuicUtils::GetFirstUnidirectionalStreamId(transport_version(),
- Perspective::IS_SERVER));
- }
- EXPECT_TRUE(session_->HasDataToWrite());
-
- // There will be no update sent yet - not enough time has passed.
- QuicTime now = QuicTime::Zero();
- session_->OnCongestionWindowChange(now);
-
- // Bandwidth estimate has now changed sufficiently but not enough time has
- // passed to send a Server Config Update.
- bandwidth_estimate_kbytes_per_second =
- bandwidth_estimate_kbytes_per_second * 1.6;
- session_->OnCongestionWindowChange(now);
-
- // Bandwidth estimate has now changed sufficiently and enough time has passed,
- // but not enough packets have been sent.
- int64_t srtt_ms =
- sent_packet_manager->GetRttStats()->smoothed_rtt().ToMilliseconds();
- now = now + QuicTime::Delta::FromMilliseconds(
- kMinIntervalBetweenServerConfigUpdatesRTTs * srtt_ms);
- session_->OnCongestionWindowChange(now);
-
- // The connection no longer has pending data to be written.
- session_->OnCanWrite();
- EXPECT_FALSE(session_->HasDataToWrite());
- session_->OnCongestionWindowChange(now);
-
- // Bandwidth estimate has now changed sufficiently, enough time has passed,
- // and enough packets have been sent.
- SerializedPacket packet(
- QuicPacketNumber(1) + kMinPacketsBetweenServerConfigUpdates,
- PACKET_4BYTE_PACKET_NUMBER, nullptr, 1000, false, false);
- 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);
- } else if (!GetQuicReloadableFlag(
- quic_add_cached_network_parameters_to_address_token2)) {
- EXPECT_CALL(*tls_server_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);
- session_->OnCongestionWindowChange(now);
-}
-
-TEST_P(QuicServerSessionBaseTest, BandwidthResumptionExperiment) {
- if (version().UsesTls()) {
- if (!version().HasIetfQuicFrames()) {
- // Skip the Txxx versions.
- return;
- }
- // Avoid a QUIC_BUG in QuicSession::OnConfigNegotiated.
- connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
- }
-
- // Test that if a client provides a CachedNetworkParameters with the same
- // serving region as the current server, and which was made within an hour of
- // now, that this data is passed down to the send algorithm.
-
- // Client has sent kBWRE connection option to trigger bandwidth resumption.
- QuicTagVector copt;
- copt.push_back(kBWRE);
- QuicConfigPeer::SetReceivedConnectionOptions(session_->config(), copt);
-
- const std::string kTestServingRegion = "a serving region";
- session_->set_serving_region(kTestServingRegion);
-
- // Set the time to be one hour + one second from the 0 baseline.
- connection_->AdvanceTime(
- QuicTime::Delta::FromSeconds(kNumSecondsPerHour + 1));
-
- QuicCryptoServerStreamBase* crypto_stream =
- static_cast<QuicCryptoServerStreamBase*>(
- QuicSessionPeer::GetMutableCryptoStream(session_.get()));
-
- // No effect if no CachedNetworkParameters provided.
- EXPECT_CALL(*connection_, ResumeConnectionState(_, _)).Times(0);
- session_->OnConfigNegotiated();
-
- // No effect if CachedNetworkParameters provided, but different serving
- // regions.
- CachedNetworkParameters cached_network_params;
- cached_network_params.set_bandwidth_estimate_bytes_per_second(1);
- cached_network_params.set_serving_region("different serving region");
- crypto_stream->SetPreviousCachedNetworkParams(cached_network_params);
- EXPECT_CALL(*connection_, ResumeConnectionState(_, _)).Times(0);
- session_->OnConfigNegotiated();
-
- // Same serving region, but timestamp is too old, should have no effect.
- cached_network_params.set_serving_region(kTestServingRegion);
- cached_network_params.set_timestamp(0);
- crypto_stream->SetPreviousCachedNetworkParams(cached_network_params);
- EXPECT_CALL(*connection_, ResumeConnectionState(_, _)).Times(0);
- session_->OnConfigNegotiated();
-
- // Same serving region, and timestamp is recent: estimate is stored.
- cached_network_params.set_timestamp(
- connection_->clock()->WallNow().ToUNIXSeconds());
- crypto_stream->SetPreviousCachedNetworkParams(cached_network_params);
- EXPECT_CALL(*connection_, ResumeConnectionState(_, _)).Times(1);
- session_->OnConfigNegotiated();
-}
-
-TEST_P(QuicServerSessionBaseTest, BandwidthMaxEnablesResumption) {
- EXPECT_FALSE(
- QuicServerSessionBasePeer::IsBandwidthResumptionEnabled(session_.get()));
-
- // Client has sent kBWMX connection option to trigger bandwidth resumption.
- QuicTagVector copt;
- copt.push_back(kBWMX);
- QuicConfigPeer::SetReceivedConnectionOptions(session_->config(), copt);
- connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
- session_->OnConfigNegotiated();
- EXPECT_TRUE(
- QuicServerSessionBasePeer::IsBandwidthResumptionEnabled(session_.get()));
-}
-
-TEST_P(QuicServerSessionBaseTest, NoBandwidthResumptionByDefault) {
- EXPECT_FALSE(
- QuicServerSessionBasePeer::IsBandwidthResumptionEnabled(session_.get()));
- connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
- session_->OnConfigNegotiated();
- EXPECT_FALSE(
- QuicServerSessionBasePeer::IsBandwidthResumptionEnabled(session_.get()));
-}
-
-// Tests which check the lifetime management of data members of
-// QuicCryptoServerStream objects when async GetProof is in use.
-class StreamMemberLifetimeTest : public QuicServerSessionBaseTest {
- public:
- StreamMemberLifetimeTest()
- : QuicServerSessionBaseTest(
- std::unique_ptr<FakeProofSource>(new FakeProofSource())),
- crypto_config_peer_(&crypto_config_) {
- GetFakeProofSource()->Activate();
- }
-
- FakeProofSource* GetFakeProofSource() const {
- return static_cast<FakeProofSource*>(crypto_config_peer_.GetProofSource());
- }
-
- private:
- QuicCryptoServerConfigPeer crypto_config_peer_;
-};
-
-INSTANTIATE_TEST_SUITE_P(StreamMemberLifetimeTests,
- StreamMemberLifetimeTest,
- ::testing::ValuesIn(AllSupportedVersions()),
- ::testing::PrintToStringParamName());
-
-// Trigger an operation which causes an async invocation of
-// ProofSource::GetProof. Delay the completion of the operation until after the
-// stream has been destroyed, and verify that there are no memory bugs.
-TEST_P(StreamMemberLifetimeTest, Basic) {
- if (version().handshake_protocol == PROTOCOL_TLS1_3) {
- // This test depends on the QUIC crypto protocol, so it is disabled for the
- // TLS handshake.
- // TODO(nharper): Fix this test so it doesn't rely on QUIC crypto.
- return;
- }
-
- const QuicClock* clock = helper_.GetClock();
- CryptoHandshakeMessage chlo = crypto_test_utils::GenerateDefaultInchoateCHLO(
- clock, transport_version(), &crypto_config_);
- chlo.SetVector(kCOPT, QuicTagVector{kREJ});
- std::vector<ParsedQuicVersion> packet_version_list = {version()};
- std::unique_ptr<QuicEncryptedPacket> packet(ConstructEncryptedPacket(
- TestConnectionId(1), EmptyQuicConnectionId(), true, false, 1,
- std::string(chlo.GetSerialized().AsStringPiece()), CONNECTION_ID_PRESENT,
- CONNECTION_ID_ABSENT, PACKET_4BYTE_PACKET_NUMBER, &packet_version_list));
-
- EXPECT_CALL(stream_helper_, CanAcceptClientHello(_, _, _, _, _))
- .WillOnce(testing::Return(true));
-
- // Set the current packet
- QuicConnectionPeer::SetCurrentPacket(session_->connection(),
- packet->AsStringPiece());
-
- // Yes, this is horrible. But it's the easiest way to trigger the behavior we
- // need to exercise.
- QuicCryptoServerStreamBase* crypto_stream =
- const_cast<QuicCryptoServerStreamBase*>(session_->crypto_stream());
-
- // Feed the CHLO into the crypto stream, which will trigger a call to
- // ProofSource::GetProof
- crypto_test_utils::SendHandshakeMessageToStream(crypto_stream, chlo,
- Perspective::IS_CLIENT);
- ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 1);
-
- // Destroy the stream
- session_.reset();
-
- // Allow the async ProofSource::GetProof call to complete. Verify (under
- // memory access checkers) that this does not result in accesses to any
- // freed memory from the session or its subobjects.
- GetFakeProofSource()->InvokePendingCallback(0);
-}
-
-} // namespace
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_client_session.cc b/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_client_session.cc
deleted file mode 100644
index 898398f59e3..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_client_session.cc
+++ /dev/null
@@ -1,223 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/http/quic_spdy_client_session.h"
-
-#include <string>
-#include <utility>
-
-#include "absl/memory/memory.h"
-#include "quic/core/crypto/crypto_protocol.h"
-#include "quic/core/http/quic_server_initiated_spdy_stream.h"
-#include "quic/core/http/quic_spdy_client_stream.h"
-#include "quic/core/http/spdy_utils.h"
-#include "quic/core/quic_server_id.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_flag_utils.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-QuicSpdyClientSession::QuicSpdyClientSession(
- const QuicConfig& config,
- const ParsedQuicVersionVector& supported_versions,
- QuicConnection* connection,
- const QuicServerId& server_id,
- QuicCryptoClientConfig* crypto_config,
- QuicClientPushPromiseIndex* push_promise_index)
- : QuicSpdyClientSessionBase(connection,
- push_promise_index,
- config,
- supported_versions),
- server_id_(server_id),
- crypto_config_(crypto_config),
- respect_goaway_(true) {}
-
-QuicSpdyClientSession::~QuicSpdyClientSession() = default;
-
-void QuicSpdyClientSession::Initialize() {
- crypto_stream_ = CreateQuicCryptoStream();
- if (config()->HasClientRequestedIndependentOption(kQLVE,
- Perspective::IS_CLIENT)) {
- connection()->EnableLegacyVersionEncapsulation(server_id_.host());
- }
- QuicSpdyClientSessionBase::Initialize();
-}
-
-void QuicSpdyClientSession::OnProofValid(
- const QuicCryptoClientConfig::CachedState& /*cached*/) {}
-
-void QuicSpdyClientSession::OnProofVerifyDetailsAvailable(
- const ProofVerifyDetails& /*verify_details*/) {}
-
-bool QuicSpdyClientSession::ShouldCreateOutgoingBidirectionalStream() {
- if (!crypto_stream_->encryption_established()) {
- QUIC_DLOG(INFO) << "Encryption not active so no outgoing stream created.";
- return false;
- }
- if (goaway_received() && respect_goaway_) {
- QUIC_DLOG(INFO) << "Failed to create a new outgoing stream. "
- << "Already received goaway.";
- return false;
- }
- return CanOpenNextOutgoingBidirectionalStream();
-}
-
-bool QuicSpdyClientSession::ShouldCreateOutgoingUnidirectionalStream() {
- QUIC_BUG(quic_bug_10396_1)
- << "Try to create outgoing unidirectional client data streams";
- return false;
-}
-
-QuicSpdyClientStream*
-QuicSpdyClientSession::CreateOutgoingBidirectionalStream() {
- if (!ShouldCreateOutgoingBidirectionalStream()) {
- return nullptr;
- }
- std::unique_ptr<QuicSpdyClientStream> stream = CreateClientStream();
- QuicSpdyClientStream* stream_ptr = stream.get();
- ActivateStream(std::move(stream));
- return stream_ptr;
-}
-
-QuicSpdyClientStream*
-QuicSpdyClientSession::CreateOutgoingUnidirectionalStream() {
- QUIC_BUG(quic_bug_10396_2)
- << "Try to create outgoing unidirectional client data streams";
- return nullptr;
-}
-
-std::unique_ptr<QuicSpdyClientStream>
-QuicSpdyClientSession::CreateClientStream() {
- return std::make_unique<QuicSpdyClientStream>(
- GetNextOutgoingBidirectionalStreamId(), this, BIDIRECTIONAL);
-}
-
-QuicCryptoClientStreamBase* QuicSpdyClientSession::GetMutableCryptoStream() {
- return crypto_stream_.get();
-}
-
-const QuicCryptoClientStreamBase* QuicSpdyClientSession::GetCryptoStream()
- const {
- return crypto_stream_.get();
-}
-
-bool QuicSpdyClientSession::IsKnownServerAddress(
- const QuicSocketAddress& address) const {
- return std::find(known_server_addresses_.cbegin(),
- known_server_addresses_.cend(),
- address) != known_server_addresses_.cend();
-}
-
-void QuicSpdyClientSession::AddKnownServerAddress(
- const QuicSocketAddress& address) {
- known_server_addresses_.push_back(address);
-}
-
-void QuicSpdyClientSession::CryptoConnect() {
- QUICHE_DCHECK(flow_controller());
- crypto_stream_->CryptoConnect();
-}
-
-int QuicSpdyClientSession::GetNumSentClientHellos() const {
- return crypto_stream_->num_sent_client_hellos();
-}
-
-bool QuicSpdyClientSession::IsResumption() const {
- return crypto_stream_->IsResumption();
-}
-
-bool QuicSpdyClientSession::EarlyDataAccepted() const {
- return crypto_stream_->EarlyDataAccepted();
-}
-
-bool QuicSpdyClientSession::ReceivedInchoateReject() const {
- return crypto_stream_->ReceivedInchoateReject();
-}
-
-int QuicSpdyClientSession::GetNumReceivedServerConfigUpdates() const {
- return crypto_stream_->num_scup_messages_received();
-}
-
-bool QuicSpdyClientSession::ShouldCreateIncomingStream(QuicStreamId id) {
- if (!connection()->connected()) {
- QUIC_BUG(quic_bug_10396_3)
- << "ShouldCreateIncomingStream called when disconnected";
- return false;
- }
- if (goaway_received() && respect_goaway_) {
- QUIC_DLOG(INFO) << "Failed to create a new outgoing stream. "
- << "Already received goaway.";
- return false;
- }
-
- if (QuicUtils::IsClientInitiatedStreamId(transport_version(), id)) {
- QUIC_BUG(quic_bug_10396_4)
- << "ShouldCreateIncomingStream called with client initiated "
- "stream ID.";
- return false;
- }
-
- if (QuicUtils::IsClientInitiatedStreamId(transport_version(), id)) {
- QUIC_LOG(WARNING) << "Received invalid push stream id " << id;
- connection()->CloseConnection(
- QUIC_INVALID_STREAM_ID,
- "Server created non write unidirectional stream",
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
- return false;
- }
-
- if (VersionHasIetfQuicFrames(transport_version()) &&
- QuicUtils::IsBidirectionalStreamId(id, version()) &&
- !WillNegotiateWebTransport()) {
- connection()->CloseConnection(
- QUIC_HTTP_SERVER_INITIATED_BIDIRECTIONAL_STREAM,
- "Server created bidirectional stream.",
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
- return false;
- }
-
- return true;
-}
-
-QuicSpdyStream* QuicSpdyClientSession::CreateIncomingStream(
- PendingStream* pending) {
- QuicSpdyStream* stream = new QuicSpdyClientStream(pending, this);
- ActivateStream(absl::WrapUnique(stream));
- return stream;
-}
-
-QuicSpdyStream* QuicSpdyClientSession::CreateIncomingStream(QuicStreamId id) {
- if (!ShouldCreateIncomingStream(id)) {
- return nullptr;
- }
- QuicSpdyStream* stream;
- if (version().UsesHttp3() &&
- QuicUtils::IsBidirectionalStreamId(id, version())) {
- QUIC_BUG_IF(QuicServerInitiatedSpdyStream but no WebTransport support,
- !WillNegotiateWebTransport())
- << "QuicServerInitiatedSpdyStream created but no WebTransport support";
- stream = new QuicServerInitiatedSpdyStream(id, this, BIDIRECTIONAL);
- } else {
- stream = new QuicSpdyClientStream(id, this, READ_UNIDIRECTIONAL);
- }
- ActivateStream(absl::WrapUnique(stream));
- return stream;
-}
-
-std::unique_ptr<QuicCryptoClientStreamBase>
-QuicSpdyClientSession::CreateQuicCryptoStream() {
- return std::make_unique<QuicCryptoClientStream>(
- server_id_, this,
- crypto_config_->proof_verifier()->CreateDefaultContext(), crypto_config_,
- this, /*has_application_state = */ version().UsesHttp3());
-}
-
-bool QuicSpdyClientSession::IsAuthorized(const std::string& /*authority*/) {
- return true;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_client_session.h b/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_client_session.h
deleted file mode 100644
index 42471b181d8..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_client_session.h
+++ /dev/null
@@ -1,127 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// A client specific QuicSession subclass.
-
-#ifndef QUICHE_QUIC_CORE_HTTP_QUIC_SPDY_CLIENT_SESSION_H_
-#define QUICHE_QUIC_CORE_HTTP_QUIC_SPDY_CLIENT_SESSION_H_
-
-#include <memory>
-#include <string>
-
-#include "quic/core/http/quic_spdy_client_session_base.h"
-#include "quic/core/http/quic_spdy_client_stream.h"
-#include "quic/core/quic_crypto_client_stream.h"
-#include "quic/core/quic_packets.h"
-
-namespace quic {
-
-class QuicConnection;
-class QuicServerId;
-
-class QUIC_EXPORT_PRIVATE QuicSpdyClientSession
- : public QuicSpdyClientSessionBase {
- public:
- // Takes ownership of |connection|. Caller retains ownership of
- // |promised_by_url|.
- QuicSpdyClientSession(const QuicConfig& config,
- const ParsedQuicVersionVector& supported_versions,
- QuicConnection* connection,
- const QuicServerId& server_id,
- QuicCryptoClientConfig* crypto_config,
- QuicClientPushPromiseIndex* push_promise_index);
- QuicSpdyClientSession(const QuicSpdyClientSession&) = delete;
- QuicSpdyClientSession& operator=(const QuicSpdyClientSession&) = delete;
- ~QuicSpdyClientSession() override;
- // Set up the QuicSpdyClientSession. Must be called prior to use.
- void Initialize() override;
-
- // QuicSession methods:
- QuicSpdyClientStream* CreateOutgoingBidirectionalStream() override;
- QuicSpdyClientStream* CreateOutgoingUnidirectionalStream() override;
- QuicCryptoClientStreamBase* GetMutableCryptoStream() override;
- const QuicCryptoClientStreamBase* GetCryptoStream() const override;
- bool IsKnownServerAddress(const QuicSocketAddress& address) const override;
-
- void AddKnownServerAddress(const QuicSocketAddress& address);
-
- bool IsAuthorized(const std::string& authority) override;
-
- // QuicSpdyClientSessionBase methods:
- void OnProofValid(const QuicCryptoClientConfig::CachedState& cached) override;
- void OnProofVerifyDetailsAvailable(
- const ProofVerifyDetails& verify_details) override;
-
- // Performs a crypto handshake with the server.
- virtual void CryptoConnect();
-
- // Returns the number of client hello messages that have been sent on the
- // crypto stream. If the handshake has completed then this is one greater
- // than the number of round-trips needed for the handshake.
- int GetNumSentClientHellos() const;
-
- // Return true if the handshake performed is a TLS resumption.
- // Always return false for QUIC Crypto.
- bool IsResumption() const;
-
- // Returns true if early data (0-RTT data) was sent and the server accepted
- // it.
- bool EarlyDataAccepted() const;
-
- // Returns true if the handshake was delayed one round trip by the server
- // because the server wanted proof the client controls its source address
- // before progressing further. In Google QUIC, this would be due to an
- // inchoate REJ in the QUIC Crypto handshake; in IETF QUIC this would be due
- // to a Retry packet.
- // TODO(nharper): Consider a better name for this method.
- bool ReceivedInchoateReject() const;
-
- int GetNumReceivedServerConfigUpdates() const;
-
- using QuicSession::CanOpenNextOutgoingBidirectionalStream;
-
- void set_respect_goaway(bool respect_goaway) {
- respect_goaway_ = respect_goaway;
- }
-
- protected:
- // QuicSession methods:
- QuicSpdyStream* CreateIncomingStream(QuicStreamId id) override;
- QuicSpdyStream* CreateIncomingStream(PendingStream* pending) override;
- // If an outgoing stream can be created, return true.
- bool ShouldCreateOutgoingBidirectionalStream() override;
- bool ShouldCreateOutgoingUnidirectionalStream() override;
-
- // If an incoming stream can be created, return true.
- // TODO(fayang): move this up to QuicSpdyClientSessionBase.
- bool ShouldCreateIncomingStream(QuicStreamId id) override;
-
- // Create the crypto stream. Called by Initialize().
- virtual std::unique_ptr<QuicCryptoClientStreamBase> CreateQuicCryptoStream();
-
- // Unlike CreateOutgoingBidirectionalStream, which applies a bunch of
- // sanity checks, this simply returns a new QuicSpdyClientStream. This may be
- // used by subclasses which want to use a subclass of QuicSpdyClientStream for
- // streams but wish to use the sanity checks in
- // CreateOutgoingBidirectionalStream.
- virtual std::unique_ptr<QuicSpdyClientStream> CreateClientStream();
-
- const QuicServerId& server_id() const { return server_id_; }
- QuicCryptoClientConfig* crypto_config() { return crypto_config_; }
-
- private:
- std::unique_ptr<QuicCryptoClientStreamBase> crypto_stream_;
- QuicServerId server_id_;
- QuicCryptoClientConfig* crypto_config_;
- // Server addresses that are known to the client.
- std::vector<QuicSocketAddress> known_server_addresses_;
-
- // If this is set to false, the client will ignore server GOAWAYs and allow
- // the creation of streams regardless of the high chance they will fail.
- bool respect_goaway_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_HTTP_QUIC_SPDY_CLIENT_SESSION_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_client_session_base.cc b/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_client_session_base.cc
deleted file mode 100644
index 56a976442c9..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_client_session_base.cc
+++ /dev/null
@@ -1,278 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/http/quic_spdy_client_session_base.h"
-
-#include <string>
-
-#include "quic/core/http/quic_client_promised_info.h"
-#include "quic/core/http/spdy_server_push_utils.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-
-using spdy::SpdyHeaderBlock;
-
-namespace quic {
-
-QuicSpdyClientSessionBase::QuicSpdyClientSessionBase(
- QuicConnection* connection,
- QuicClientPushPromiseIndex* push_promise_index,
- const QuicConfig& config,
- const ParsedQuicVersionVector& supported_versions)
- : QuicSpdySession(connection, nullptr, config, supported_versions),
- push_promise_index_(push_promise_index),
- largest_promised_stream_id_(
- QuicUtils::GetInvalidStreamId(connection->transport_version())) {}
-
-QuicSpdyClientSessionBase::~QuicSpdyClientSessionBase() {
- // all promised streams for this session
- for (auto& it : promised_by_id_) {
- QUIC_DVLOG(1) << "erase stream " << it.first << " url " << it.second->url();
- push_promise_index_->promised_by_url()->erase(it.second->url());
- }
- DeleteConnection();
-}
-
-void QuicSpdyClientSessionBase::OnConfigNegotiated() {
- QuicSpdySession::OnConfigNegotiated();
-}
-
-void QuicSpdyClientSessionBase::OnInitialHeadersComplete(
- QuicStreamId stream_id,
- const SpdyHeaderBlock& response_headers) {
- // Note that the strong ordering of the headers stream means that
- // QuicSpdyClientStream::OnPromiseHeadersComplete must have already
- // been called (on the associated stream) if this is a promised
- // stream. However, this stream may not have existed at this time,
- // hence the need to query the session.
- QuicClientPromisedInfo* promised = GetPromisedById(stream_id);
- if (!promised)
- return;
-
- promised->OnResponseHeaders(response_headers);
-}
-
-void QuicSpdyClientSessionBase::OnPromiseHeaderList(
- QuicStreamId stream_id,
- QuicStreamId promised_stream_id,
- size_t frame_len,
- const QuicHeaderList& header_list) {
- if (IsStaticStream(stream_id)) {
- connection()->CloseConnection(
- QUIC_INVALID_HEADERS_STREAM_DATA, "stream is static",
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
- return;
- }
- // In HTTP3, push promises are received on individual streams, so they could
- // be arrive out of order.
- if (!VersionUsesHttp3(transport_version()) &&
- promised_stream_id !=
- QuicUtils::GetInvalidStreamId(transport_version()) &&
- largest_promised_stream_id_ !=
- QuicUtils::GetInvalidStreamId(transport_version()) &&
- promised_stream_id <= largest_promised_stream_id_) {
- connection()->CloseConnection(
- QUIC_INVALID_STREAM_ID,
- "Received push stream id lesser or equal to the"
- " last accepted before",
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
- return;
- }
- if (!IsIncomingStream(promised_stream_id)) {
- connection()->CloseConnection(
- QUIC_INVALID_STREAM_ID, "Received push stream id for outgoing stream.",
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
- return;
- }
-
- if (VersionUsesHttp3(transport_version()) &&
- !CanCreatePushStreamWithId(promised_stream_id)) {
- connection()->CloseConnection(
- QUIC_INVALID_STREAM_ID,
- "Received push stream id higher than MAX_PUSH_ID.",
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
- return;
- }
- largest_promised_stream_id_ = promised_stream_id;
-
- QuicSpdyStream* stream = GetOrCreateSpdyDataStream(stream_id);
- if (!stream) {
- // It's quite possible to receive headers after a stream has been reset.
- return;
- }
- stream->OnPromiseHeaderList(promised_stream_id, frame_len, header_list);
-}
-
-bool QuicSpdyClientSessionBase::HandlePromised(QuicStreamId /* associated_id */,
- QuicStreamId promised_id,
- const SpdyHeaderBlock& headers) {
- // TODO(b/136295430): Do not treat |promised_id| as a stream ID when using
- // IETF QUIC.
- // Due to pathalogical packet re-ordering, it is possible that
- // frames for the promised stream have already arrived, and the
- // promised stream could be active or closed.
- if (IsClosedStream(promised_id)) {
- // There was a RST on the data stream already, perhaps
- // QUIC_REFUSED_STREAM?
- QUIC_DVLOG(1) << "Promise ignored for stream " << promised_id
- << " that is already closed";
- return false;
- }
-
- if (push_promise_index_->promised_by_url()->size() >= get_max_promises()) {
- QUIC_DVLOG(1) << "Too many promises, rejecting promise for stream "
- << promised_id;
- ResetPromised(promised_id, QUIC_REFUSED_STREAM);
- return false;
- }
-
- const std::string url =
- SpdyServerPushUtils::GetPromisedUrlFromHeaders(headers);
- QuicClientPromisedInfo* old_promised = GetPromisedByUrl(url);
- if (old_promised) {
- QUIC_DVLOG(1) << "Promise for stream " << promised_id
- << " is duplicate URL " << url
- << " of previous promise for stream " << old_promised->id();
- ResetPromised(promised_id, QUIC_DUPLICATE_PROMISE_URL);
- return false;
- }
-
- if (GetPromisedById(promised_id)) {
- // OnPromiseHeadersComplete() would have closed the connection if
- // promised id is a duplicate.
- QUIC_BUG(quic_bug_10412_1) << "Duplicate promise for id " << promised_id;
- return false;
- }
-
- QuicClientPromisedInfo* promised =
- new QuicClientPromisedInfo(this, promised_id, url);
- std::unique_ptr<QuicClientPromisedInfo> promised_owner(promised);
- promised->Init();
- QUIC_DVLOG(1) << "stream " << promised_id << " emplace url " << url;
- (*push_promise_index_->promised_by_url())[url] = promised;
- promised_by_id_[promised_id] = std::move(promised_owner);
- bool result = promised->OnPromiseHeaders(headers);
- if (result) {
- QUICHE_DCHECK(promised_by_id_.find(promised_id) != promised_by_id_.end());
- }
- return result;
-}
-
-QuicClientPromisedInfo* QuicSpdyClientSessionBase::GetPromisedByUrl(
- const std::string& url) {
- auto it = push_promise_index_->promised_by_url()->find(url);
- if (it != push_promise_index_->promised_by_url()->end()) {
- return it->second;
- }
- return nullptr;
-}
-
-QuicClientPromisedInfo* QuicSpdyClientSessionBase::GetPromisedById(
- const QuicStreamId id) {
- auto it = promised_by_id_.find(id);
- if (it != promised_by_id_.end()) {
- return it->second.get();
- }
- return nullptr;
-}
-
-QuicSpdyStream* QuicSpdyClientSessionBase::GetPromisedStream(
- const QuicStreamId id) {
- QuicStream* stream = GetActiveStream(id);
- if (stream != nullptr) {
- return static_cast<QuicSpdyStream*>(stream);
- }
- return nullptr;
-}
-
-void QuicSpdyClientSessionBase::DeletePromised(
- QuicClientPromisedInfo* promised) {
- push_promise_index_->promised_by_url()->erase(promised->url());
- // Since promised_by_id_ contains the unique_ptr, this will destroy
- // promised.
- // ToDo: Consider implementing logic to send a new MAX_PUSH_ID frame to allow
- // another stream to be promised.
- promised_by_id_.erase(promised->id());
- if (!VersionUsesHttp3(transport_version())) {
- headers_stream()->MaybeReleaseSequencerBuffer();
- }
-}
-
-void QuicSpdyClientSessionBase::OnPushStreamTimedOut(
- QuicStreamId /*stream_id*/) {}
-
-void QuicSpdyClientSessionBase::ResetPromised(
- QuicStreamId id,
- QuicRstStreamErrorCode error_code) {
- QUICHE_DCHECK(QuicUtils::IsServerInitiatedStreamId(transport_version(), id));
- ResetStream(id, error_code);
- if (!IsOpenStream(id) && !IsClosedStream(id)) {
- MaybeIncreaseLargestPeerStreamId(id);
- }
-}
-
-void QuicSpdyClientSessionBase::OnStreamClosed(QuicStreamId stream_id) {
- QuicSpdySession::OnStreamClosed(stream_id);
- if (!VersionUsesHttp3(transport_version())) {
- headers_stream()->MaybeReleaseSequencerBuffer();
- }
-}
-
-bool QuicSpdyClientSessionBase::ShouldReleaseHeadersStreamSequencerBuffer() {
- return !HasActiveRequestStreams() && promised_by_id_.empty();
-}
-
-bool QuicSpdyClientSessionBase::ShouldKeepConnectionAlive() const {
- return QuicSpdySession::ShouldKeepConnectionAlive() ||
- num_outgoing_draining_streams() > 0;
-}
-
-bool QuicSpdyClientSessionBase::OnSettingsFrame(const SettingsFrame& frame) {
- if (!was_zero_rtt_rejected()) {
- if (max_outbound_header_list_size() != std::numeric_limits<size_t>::max() &&
- frame.values.find(SETTINGS_MAX_FIELD_SECTION_SIZE) ==
- frame.values.end()) {
- CloseConnectionWithDetails(
- QUIC_HTTP_ZERO_RTT_RESUMPTION_SETTINGS_MISMATCH,
- "Server accepted 0-RTT but omitted non-default "
- "SETTINGS_MAX_FIELD_SECTION_SIZE");
- return false;
- }
-
- if (qpack_encoder()->maximum_blocked_streams() != 0 &&
- frame.values.find(SETTINGS_QPACK_BLOCKED_STREAMS) ==
- frame.values.end()) {
- CloseConnectionWithDetails(
- QUIC_HTTP_ZERO_RTT_RESUMPTION_SETTINGS_MISMATCH,
- "Server accepted 0-RTT but omitted non-default "
- "SETTINGS_QPACK_BLOCKED_STREAMS");
- return false;
- }
-
- if (qpack_encoder()->MaximumDynamicTableCapacity() != 0 &&
- frame.values.find(SETTINGS_QPACK_MAX_TABLE_CAPACITY) ==
- frame.values.end()) {
- CloseConnectionWithDetails(
- QUIC_HTTP_ZERO_RTT_RESUMPTION_SETTINGS_MISMATCH,
- "Server accepted 0-RTT but omitted non-default "
- "SETTINGS_QPACK_MAX_TABLE_CAPACITY");
- return false;
- }
- }
-
- if (!QuicSpdySession::OnSettingsFrame(frame)) {
- return false;
- }
- std::unique_ptr<char[]> buffer;
- QuicByteCount frame_length =
- HttpEncoder::SerializeSettingsFrame(frame, &buffer);
- auto serialized_data = std::make_unique<ApplicationState>(
- buffer.get(), buffer.get() + frame_length);
- GetMutableCryptoStream()->SetServerApplicationStateForResumption(
- std::move(serialized_data));
- return true;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_client_session_base.h b/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_client_session_base.h
deleted file mode 100644
index 71236bf8d46..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_client_session_base.h
+++ /dev/null
@@ -1,146 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_HTTP_QUIC_SPDY_CLIENT_SESSION_BASE_H_
-#define QUICHE_QUIC_CORE_HTTP_QUIC_SPDY_CLIENT_SESSION_BASE_H_
-
-#include <string>
-
-#include "absl/container/flat_hash_map.h"
-#include "quic/core/http/quic_spdy_session.h"
-#include "quic/core/quic_crypto_client_stream.h"
-#include "quic/platform/api/quic_containers.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-class QuicClientPromisedInfo;
-class QuicClientPushPromiseIndex;
-class QuicSpdyClientStream;
-
-// For client/http layer code. Lookup promised streams based on
-// matching promised request url. The same map can be shared across
-// multiple sessions, since cross-origin pushes are allowed (subject
-// to authority constraints). Clients should use this map to enforce
-// session affinity for requests corresponding to cross-origin push
-// promised streams.
-using QuicPromisedByUrlMap =
- absl::flat_hash_map<std::string, QuicClientPromisedInfo*>;
-
-// The maximum time a promises stream can be reserved without being
-// claimed by a client request.
-const int64_t kPushPromiseTimeoutSecs = 60;
-
-// Base class for all client-specific QuicSession subclasses.
-class QUIC_EXPORT_PRIVATE QuicSpdyClientSessionBase
- : public QuicSpdySession,
- public QuicCryptoClientStream::ProofHandler {
- public:
- // Takes ownership of |connection|. Caller retains ownership of
- // |promised_by_url|.
- QuicSpdyClientSessionBase(QuicConnection* connection,
- QuicClientPushPromiseIndex* push_promise_index,
- const QuicConfig& config,
- const ParsedQuicVersionVector& supported_versions);
- QuicSpdyClientSessionBase(const QuicSpdyClientSessionBase&) = delete;
- QuicSpdyClientSessionBase& operator=(const QuicSpdyClientSessionBase&) =
- delete;
-
- ~QuicSpdyClientSessionBase() override;
-
- void OnConfigNegotiated() override;
-
- // Called by |headers_stream_| when push promise headers have been
- // completely received.
- void OnPromiseHeaderList(QuicStreamId stream_id,
- QuicStreamId promised_stream_id,
- size_t frame_len,
- const QuicHeaderList& header_list) override;
-
- // Called by |QuicSpdyClientStream| on receipt of response headers,
- // needed to detect promised server push streams, as part of
- // client-request to push-stream rendezvous.
- void OnInitialHeadersComplete(QuicStreamId stream_id,
- const spdy::SpdyHeaderBlock& response_headers);
-
- // Called by |QuicSpdyClientStream| on receipt of PUSH_PROMISE, does
- // some session level validation and creates the
- // |QuicClientPromisedInfo| inserting into maps by (promised) id and
- // url. Returns true if a new push promise is accepted. Resets the promised
- // stream and returns false otherwise.
- virtual bool HandlePromised(QuicStreamId associated_id,
- QuicStreamId promised_id,
- const spdy::SpdyHeaderBlock& headers);
-
- // For cross-origin server push, this should verify the server is
- // authoritative per [RFC2818], Section 3. Roughly, subjectAltName
- // list in the certificate should contain a matching DNS name, or IP
- // address. |hostname| is derived from the ":authority" header field of
- // the PUSH_PROMISE frame, port if present there will be dropped.
- virtual bool IsAuthorized(const std::string& hostname) = 0;
-
- // Session retains ownership.
- QuicClientPromisedInfo* GetPromisedByUrl(const std::string& url);
- // Session retains ownership.
- QuicClientPromisedInfo* GetPromisedById(const QuicStreamId id);
-
- //
- QuicSpdyStream* GetPromisedStream(const QuicStreamId id);
-
- // Removes |promised| from the maps by url.
- void ErasePromisedByUrl(QuicClientPromisedInfo* promised);
-
- // Removes |promised| from the maps by url and id and destroys
- // promised.
- virtual void DeletePromised(QuicClientPromisedInfo* promised);
-
- virtual void OnPushStreamTimedOut(QuicStreamId stream_id);
-
- // Sends Rst for the stream, and makes sure that future calls to
- // IsClosedStream(id) return true, which ensures that any subsequent
- // frames related to this stream will be ignored (modulo flow
- // control accounting).
- void ResetPromised(QuicStreamId id, QuicRstStreamErrorCode error_code);
-
- // Release headers stream's sequencer buffer if it's empty.
- void OnStreamClosed(QuicStreamId stream_id) override;
-
- // Returns true if there are no active requests and no promised streams.
- bool ShouldReleaseHeadersStreamSequencerBuffer() override;
-
- // Override to wait for all received responses to be consumed by application.
- bool ShouldKeepConnectionAlive() const override;
-
- size_t get_max_promises() const {
- return max_open_incoming_unidirectional_streams() *
- kMaxPromisedStreamsMultiplier;
- }
-
- QuicClientPushPromiseIndex* push_promise_index() {
- return push_promise_index_;
- }
-
- // Override to serialize the settings and pass it down to the handshaker.
- bool OnSettingsFrame(const SettingsFrame& frame) override;
-
- private:
- // For QuicSpdyClientStream to detect that a response corresponds to a
- // promise.
- using QuicPromisedByIdMap =
- absl::flat_hash_map<QuicStreamId,
- std::unique_ptr<QuicClientPromisedInfo>>;
-
- // As per rfc7540, section 10.5: track promise streams in "reserved
- // (remote)". The primary key is URL from the promise request
- // headers. The promised stream id is a secondary key used to get
- // promise info when the response headers of the promised stream
- // arrive.
- QuicClientPushPromiseIndex* push_promise_index_;
- QuicPromisedByIdMap promised_by_id_;
- QuicStreamId largest_promised_stream_id_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_HTTP_QUIC_SPDY_CLIENT_SESSION_BASE_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_client_session_test.cc b/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_client_session_test.cc
deleted file mode 100644
index 2a620469b5a..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_client_session_test.cc
+++ /dev/null
@@ -1,1345 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/http/quic_spdy_client_session.h"
-
-#include <memory>
-#include <string>
-#include <utility>
-#include <vector>
-
-#include "absl/base/macros.h"
-#include "absl/memory/memory.h"
-#include "absl/strings/str_cat.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/crypto/null_decrypter.h"
-#include "quic/core/crypto/null_encrypter.h"
-#include "quic/core/http/http_constants.h"
-#include "quic/core/http/http_frames.h"
-#include "quic/core/http/quic_spdy_client_stream.h"
-#include "quic/core/http/spdy_server_push_utils.h"
-#include "quic/core/quic_constants.h"
-#include "quic/core/quic_error_codes.h"
-#include "quic/core/quic_utils.h"
-#include "quic/core/quic_versions.h"
-#include "quic/core/tls_client_handshaker.h"
-#include "quic/platform/api/quic_expect_bug.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_socket_address.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/crypto_test_utils.h"
-#include "quic/test_tools/mock_quic_spdy_client_stream.h"
-#include "quic/test_tools/quic_config_peer.h"
-#include "quic/test_tools/quic_connection_peer.h"
-#include "quic/test_tools/quic_framer_peer.h"
-#include "quic/test_tools/quic_packet_creator_peer.h"
-#include "quic/test_tools/quic_session_peer.h"
-#include "quic/test_tools/quic_spdy_session_peer.h"
-#include "quic/test_tools/quic_stream_peer.h"
-#include "quic/test_tools/quic_test_utils.h"
-#include "quic/test_tools/simple_session_cache.h"
-
-using spdy::SpdyHeaderBlock;
-using ::testing::_;
-using ::testing::AnyNumber;
-using ::testing::AtLeast;
-using ::testing::AtMost;
-using ::testing::Invoke;
-using ::testing::StrictMock;
-using ::testing::Truly;
-
-namespace quic {
-namespace test {
-namespace {
-
-const char kServerHostname[] = "test.example.com";
-const uint16_t kPort = 443;
-
-class TestQuicSpdyClientSession : public QuicSpdyClientSession {
- public:
- explicit TestQuicSpdyClientSession(
- const QuicConfig& config,
- const ParsedQuicVersionVector& supported_versions,
- QuicConnection* connection,
- const QuicServerId& server_id,
- QuicCryptoClientConfig* crypto_config,
- QuicClientPushPromiseIndex* push_promise_index)
- : QuicSpdyClientSession(config,
- supported_versions,
- connection,
- server_id,
- crypto_config,
- push_promise_index) {}
-
- std::unique_ptr<QuicSpdyClientStream> CreateClientStream() override {
- return std::make_unique<MockQuicSpdyClientStream>(
- GetNextOutgoingBidirectionalStreamId(), this, BIDIRECTIONAL);
- }
-
- MockQuicSpdyClientStream* CreateIncomingStream(QuicStreamId id) override {
- if (!ShouldCreateIncomingStream(id)) {
- return nullptr;
- }
- MockQuicSpdyClientStream* stream =
- new MockQuicSpdyClientStream(id, this, READ_UNIDIRECTIONAL);
- ActivateStream(absl::WrapUnique(stream));
- return stream;
- }
-};
-
-class QuicSpdyClientSessionTest : public QuicTestWithParam<ParsedQuicVersion> {
- protected:
- QuicSpdyClientSessionTest()
- : promised_stream_id_(
- QuicUtils::GetInvalidStreamId(GetParam().transport_version)),
- associated_stream_id_(
- QuicUtils::GetInvalidStreamId(GetParam().transport_version)) {
- auto client_cache = std::make_unique<test::SimpleSessionCache>();
- client_session_cache_ = client_cache.get();
- client_crypto_config_ = std::make_unique<QuicCryptoClientConfig>(
- crypto_test_utils::ProofVerifierForTesting(), std::move(client_cache));
- server_crypto_config_ = crypto_test_utils::CryptoServerConfigForTesting();
- Initialize();
- // Advance the time, because timers do not like uninitialized times.
- connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
- }
-
- ~QuicSpdyClientSessionTest() override {
- // Session must be destroyed before promised_by_url_
- session_.reset(nullptr);
- }
-
- void Initialize() {
- session_.reset();
- connection_ = new ::testing::NiceMock<PacketSavingConnection>(
- &helper_, &alarm_factory_, Perspective::IS_CLIENT,
- SupportedVersions(GetParam()));
- session_ = std::make_unique<TestQuicSpdyClientSession>(
- DefaultQuicConfig(), SupportedVersions(GetParam()), connection_,
- QuicServerId(kServerHostname, kPort, false),
- client_crypto_config_.get(), &push_promise_index_);
- session_->Initialize();
- connection_->SetEncrypter(
- ENCRYPTION_FORWARD_SECURE,
- std::make_unique<NullEncrypter>(connection_->perspective()));
- crypto_stream_ = static_cast<QuicCryptoClientStream*>(
- session_->GetMutableCryptoStream());
- push_promise_[":path"] = "/bar";
- push_promise_[":authority"] = "www.google.com";
- push_promise_[":method"] = "GET";
- push_promise_[":scheme"] = "https";
- promise_url_ =
- SpdyServerPushUtils::GetPromisedUrlFromHeaders(push_promise_);
- promised_stream_id_ = GetNthServerInitiatedUnidirectionalStreamId(
- connection_->transport_version(), 0);
- associated_stream_id_ = GetNthClientInitiatedBidirectionalStreamId(
- connection_->transport_version(), 0);
- }
-
- // The function ensures that A) the MAX_STREAMS frames get properly deleted
- // (since the test uses a 'did we leak memory' check ... if we just lose the
- // frame, the test fails) and B) returns true (instead of the default, false)
- // which ensures that the rest of the system thinks that the frame actually
- // was transmitted.
- bool ClearMaxStreamsControlFrame(const QuicFrame& frame) {
- if (frame.type == MAX_STREAMS_FRAME) {
- DeleteFrame(&const_cast<QuicFrame&>(frame));
- return true;
- }
- return false;
- }
-
- public:
- bool ClearStreamsBlockedControlFrame(const QuicFrame& frame) {
- if (frame.type == STREAMS_BLOCKED_FRAME) {
- DeleteFrame(&const_cast<QuicFrame&>(frame));
- return true;
- }
- return false;
- }
-
- protected:
- void CompleteCryptoHandshake() {
- CompleteCryptoHandshake(kDefaultMaxStreamsPerConnection);
- }
-
- void CompleteCryptoHandshake(uint32_t server_max_incoming_streams) {
- if (VersionHasIetfQuicFrames(connection_->transport_version())) {
- EXPECT_CALL(*connection_, SendControlFrame(_))
- .Times(::testing::AnyNumber())
- .WillRepeatedly(Invoke(
- this, &QuicSpdyClientSessionTest::ClearMaxStreamsControlFrame));
- }
- session_->CryptoConnect();
- QuicConfig config = DefaultQuicConfig();
- if (VersionHasIetfQuicFrames(connection_->transport_version())) {
- config.SetMaxUnidirectionalStreamsToSend(server_max_incoming_streams);
- config.SetMaxBidirectionalStreamsToSend(server_max_incoming_streams);
- } else {
- config.SetMaxBidirectionalStreamsToSend(server_max_incoming_streams);
- }
- crypto_test_utils::HandshakeWithFakeServer(
- &config, server_crypto_config_.get(), &helper_, &alarm_factory_,
- connection_, crypto_stream_, AlpnForVersion(connection_->version()));
- }
-
- void CreateConnection() {
- connection_ = new ::testing::NiceMock<PacketSavingConnection>(
- &helper_, &alarm_factory_, Perspective::IS_CLIENT,
- SupportedVersions(GetParam()));
- // Advance the time, because timers do not like uninitialized times.
- connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
- session_ = std::make_unique<TestQuicSpdyClientSession>(
- DefaultQuicConfig(), SupportedVersions(GetParam()), connection_,
- QuicServerId(kServerHostname, kPort, false),
- client_crypto_config_.get(), &push_promise_index_);
- session_->Initialize();
- crypto_stream_ = static_cast<QuicCryptoClientStream*>(
- session_->GetMutableCryptoStream());
- }
-
- void CompleteFirstConnection() {
- CompleteCryptoHandshake();
- EXPECT_FALSE(session_->GetCryptoStream()->IsResumption());
- if (session_->version().UsesHttp3()) {
- SettingsFrame settings;
- settings.values[SETTINGS_QPACK_MAX_TABLE_CAPACITY] = 2;
- settings.values[SETTINGS_MAX_FIELD_SECTION_SIZE] = 5;
- settings.values[256] = 4; // unknown setting
- session_->OnSettingsFrame(settings);
- }
- }
-
- // Owned by |session_|.
- QuicCryptoClientStream* crypto_stream_;
- std::unique_ptr<QuicCryptoServerConfig> server_crypto_config_;
- std::unique_ptr<QuicCryptoClientConfig> client_crypto_config_;
- MockQuicConnectionHelper helper_;
- MockAlarmFactory alarm_factory_;
- ::testing::NiceMock<PacketSavingConnection>* connection_;
- std::unique_ptr<TestQuicSpdyClientSession> session_;
- QuicClientPushPromiseIndex push_promise_index_;
- SpdyHeaderBlock push_promise_;
- std::string promise_url_;
- QuicStreamId promised_stream_id_;
- QuicStreamId associated_stream_id_;
- test::SimpleSessionCache* client_session_cache_;
-};
-
-std::string ParamNameFormatter(
- const testing::TestParamInfo<QuicSpdyClientSessionTest::ParamType>& info) {
- return ParsedQuicVersionToString(info.param);
-}
-
-INSTANTIATE_TEST_SUITE_P(Tests,
- QuicSpdyClientSessionTest,
- ::testing::ValuesIn(AllSupportedVersions()),
- ParamNameFormatter);
-
-TEST_P(QuicSpdyClientSessionTest, CryptoConnect) {
- CompleteCryptoHandshake();
-}
-
-TEST_P(QuicSpdyClientSessionTest, NoEncryptionAfterInitialEncryption) {
- if (GetParam().handshake_protocol == PROTOCOL_TLS1_3) {
- // This test relies on resumption and is QUIC crypto specific, so it is
- // disabled for TLS.
- return;
- }
- // Complete a handshake in order to prime the crypto config for 0-RTT.
- CompleteCryptoHandshake();
-
- // Now create a second session using the same crypto config.
- Initialize();
-
- // Starting the handshake should move immediately to encryption
- // established and will allow streams to be created.
- session_->CryptoConnect();
- EXPECT_TRUE(session_->IsEncryptionEstablished());
- QuicSpdyClientStream* stream = session_->CreateOutgoingBidirectionalStream();
- ASSERT_TRUE(stream != nullptr);
- EXPECT_FALSE(QuicUtils::IsCryptoStreamId(connection_->transport_version(),
- stream->id()));
-
- // Process an "inchoate" REJ from the server which will cause
- // an inchoate CHLO to be sent and will leave the encryption level
- // at NONE.
- CryptoHandshakeMessage rej;
- crypto_test_utils::FillInDummyReject(&rej);
- EXPECT_TRUE(session_->IsEncryptionEstablished());
- crypto_test_utils::SendHandshakeMessageToStream(
- session_->GetMutableCryptoStream(), rej, Perspective::IS_CLIENT);
- EXPECT_FALSE(session_->IsEncryptionEstablished());
- EXPECT_EQ(ENCRYPTION_INITIAL,
- QuicPacketCreatorPeer::GetEncryptionLevel(
- QuicConnectionPeer::GetPacketCreator(connection_)));
- // Verify that no new streams may be created.
- EXPECT_TRUE(session_->CreateOutgoingBidirectionalStream() == nullptr);
- // Verify that no data may be send on existing streams.
- char data[] = "hello world";
- QuicConsumedData consumed =
- session_->WritevData(stream->id(), ABSL_ARRAYSIZE(data), 0, NO_FIN,
- NOT_RETRANSMISSION, ENCRYPTION_INITIAL);
- EXPECT_EQ(0u, consumed.bytes_consumed);
- EXPECT_FALSE(consumed.fin_consumed);
-}
-
-TEST_P(QuicSpdyClientSessionTest, MaxNumStreamsWithNoFinOrRst) {
- uint32_t kServerMaxIncomingStreams = 1;
- CompleteCryptoHandshake(kServerMaxIncomingStreams);
-
- QuicSpdyClientStream* stream = session_->CreateOutgoingBidirectionalStream();
- ASSERT_TRUE(stream);
- EXPECT_FALSE(session_->CreateOutgoingBidirectionalStream());
-
- // Close the stream, but without having received a FIN or a RST_STREAM
- // or MAX_STREAMS (IETF QUIC) and check that a new one can not be created.
- session_->ResetStream(stream->id(), QUIC_STREAM_CANCELLED);
- EXPECT_EQ(1u, QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()));
-
- stream = session_->CreateOutgoingBidirectionalStream();
- EXPECT_FALSE(stream);
-}
-
-TEST_P(QuicSpdyClientSessionTest, MaxNumStreamsWithRst) {
- uint32_t kServerMaxIncomingStreams = 1;
- CompleteCryptoHandshake(kServerMaxIncomingStreams);
-
- QuicSpdyClientStream* stream = session_->CreateOutgoingBidirectionalStream();
- ASSERT_NE(nullptr, stream);
- EXPECT_EQ(nullptr, session_->CreateOutgoingBidirectionalStream());
-
- // Close the stream and receive an RST frame to remove the unfinished stream
- session_->ResetStream(stream->id(), QUIC_STREAM_CANCELLED);
- session_->OnRstStream(QuicRstStreamFrame(kInvalidControlFrameId, stream->id(),
- QUIC_RST_ACKNOWLEDGEMENT, 0));
- // Check that a new one can be created.
- EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()));
- if (VersionHasIetfQuicFrames(GetParam().transport_version)) {
- // In IETF QUIC the stream limit increases only if we get a MAX_STREAMS
- // frame; pretend we got one.
-
- QuicMaxStreamsFrame frame(0, 2,
- /*unidirectional=*/false);
- session_->OnMaxStreamsFrame(frame);
- }
- stream = session_->CreateOutgoingBidirectionalStream();
- EXPECT_NE(nullptr, stream);
- if (VersionHasIetfQuicFrames(GetParam().transport_version)) {
- // Ensure that we have 2 total streams, 1 open and 1 closed.
- QuicStreamCount expected_stream_count = 2;
- EXPECT_EQ(expected_stream_count,
- QuicSessionPeer::ietf_bidirectional_stream_id_manager(&*session_)
- ->outgoing_stream_count());
- }
-}
-
-TEST_P(QuicSpdyClientSessionTest, ResetAndTrailers) {
- // Tests the situation in which the client sends a RST at the same time that
- // the server sends trailing headers (trailers). Receipt of the trailers by
- // the client should result in all outstanding stream state being tidied up
- // (including flow control, and number of available outgoing streams).
- uint32_t kServerMaxIncomingStreams = 1;
- CompleteCryptoHandshake(kServerMaxIncomingStreams);
-
- QuicSpdyClientStream* stream = session_->CreateOutgoingBidirectionalStream();
- ASSERT_NE(nullptr, stream);
-
- if (VersionHasIetfQuicFrames(GetParam().transport_version)) {
- // For IETF QUIC, trying to open a stream and failing due to lack
- // of stream ids will result in a STREAMS_BLOCKED. Make
- // sure we get one. Also clear out the frame because if it's
- // left sitting, the later SendRstStream will not actually
- // transmit the RST_STREAM because the connection will be in write-blocked
- // state. This means that the SendControlFrame that is expected w.r.t. the
- // RST_STREAM, below, will not be satisfied.
- EXPECT_CALL(*connection_, SendControlFrame(_))
- .WillOnce(Invoke(
- this, &QuicSpdyClientSessionTest::ClearStreamsBlockedControlFrame));
- }
-
- EXPECT_EQ(nullptr, session_->CreateOutgoingBidirectionalStream());
-
- QuicStreamId stream_id = stream->id();
-
- EXPECT_CALL(*connection_, SendControlFrame(_))
- .Times(AtLeast(1))
- .WillRepeatedly(Invoke(&ClearControlFrame));
- EXPECT_CALL(*connection_, OnStreamReset(_, _)).Times(1);
- session_->ResetStream(stream_id, QUIC_STREAM_PEER_GOING_AWAY);
-
- // A new stream cannot be created as the reset stream still counts as an open
- // outgoing stream until closed by the server.
- EXPECT_EQ(1u, QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()));
- stream = session_->CreateOutgoingBidirectionalStream();
- EXPECT_EQ(nullptr, stream);
-
- // The stream receives trailers with final byte offset: this is one of three
- // ways that a peer can signal the end of a stream (the others being RST,
- // stream data + FIN).
- QuicHeaderList trailers;
- trailers.OnHeaderBlockStart();
- trailers.OnHeader(kFinalOffsetHeaderKey, "0");
- trailers.OnHeaderBlockEnd(0, 0);
- session_->OnStreamHeaderList(stream_id, /*fin=*/false, 0, trailers);
-
- // The stream is now complete from the client's perspective, and it should
- // be able to create a new outgoing stream.
- EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()));
- if (VersionHasIetfQuicFrames(GetParam().transport_version)) {
- QuicMaxStreamsFrame frame(0, 2,
- /*unidirectional=*/false);
-
- session_->OnMaxStreamsFrame(frame);
- }
- stream = session_->CreateOutgoingBidirectionalStream();
- EXPECT_NE(nullptr, stream);
- if (VersionHasIetfQuicFrames(GetParam().transport_version)) {
- // Ensure that we have 2 open streams.
- QuicStreamCount expected_stream_count = 2;
- EXPECT_EQ(expected_stream_count,
- QuicSessionPeer::ietf_bidirectional_stream_id_manager(&*session_)
- ->outgoing_stream_count());
- }
-}
-
-TEST_P(QuicSpdyClientSessionTest, ReceivedMalformedTrailersAfterSendingRst) {
- // Tests the situation where the client has sent a RST to the server, and has
- // received trailing headers with a malformed final byte offset value.
- CompleteCryptoHandshake();
-
- QuicSpdyClientStream* stream = session_->CreateOutgoingBidirectionalStream();
- ASSERT_NE(nullptr, stream);
-
- // Send the RST, which results in the stream being closed locally (but some
- // state remains while the client waits for a response from the server).
- QuicStreamId stream_id = stream->id();
- EXPECT_CALL(*connection_, SendControlFrame(_))
- .Times(AtLeast(1))
- .WillRepeatedly(Invoke(&ClearControlFrame));
- EXPECT_CALL(*connection_, OnStreamReset(_, _)).Times(1);
- session_->ResetStream(stream_id, QUIC_STREAM_PEER_GOING_AWAY);
-
- // The stream receives trailers with final byte offset, but the header value
- // is non-numeric and should be treated as malformed.
- QuicHeaderList trailers;
- trailers.OnHeaderBlockStart();
- trailers.OnHeader(kFinalOffsetHeaderKey, "invalid non-numeric value");
- trailers.OnHeaderBlockEnd(0, 0);
-
- EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(1);
- session_->OnStreamHeaderList(stream_id, /*fin=*/false, 0, trailers);
-}
-
-TEST_P(QuicSpdyClientSessionTest, OnStreamHeaderListWithStaticStream) {
- // Test situation where OnStreamHeaderList is called by stream with static id.
- CompleteCryptoHandshake();
-
- QuicHeaderList trailers;
- trailers.OnHeaderBlockStart();
- trailers.OnHeader(kFinalOffsetHeaderKey, "0");
- trailers.OnHeaderBlockEnd(0, 0);
-
- // Initialize H/3 control stream.
- QuicStreamId id;
- if (VersionUsesHttp3(connection_->transport_version())) {
- id = GetNthServerInitiatedUnidirectionalStreamId(
- connection_->transport_version(), 3);
- char type[] = {0x00};
-
- QuicStreamFrame data1(id, false, 0, absl::string_view(type, 1));
- session_->OnStreamFrame(data1);
- } else {
- id = QuicUtils::GetHeadersStreamId(connection_->transport_version());
- }
-
- EXPECT_CALL(*connection_, CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA,
- "stream is static", _))
- .Times(1);
- session_->OnStreamHeaderList(id,
- /*fin=*/false, 0, trailers);
-}
-
-TEST_P(QuicSpdyClientSessionTest, OnPromiseHeaderListWithStaticStream) {
- // Test situation where OnPromiseHeaderList is called by stream with static
- // id.
- CompleteCryptoHandshake();
-
- QuicHeaderList trailers;
- trailers.OnHeaderBlockStart();
- trailers.OnHeader(kFinalOffsetHeaderKey, "0");
- trailers.OnHeaderBlockEnd(0, 0);
-
- // Initialize H/3 control stream.
- QuicStreamId id;
- if (VersionUsesHttp3(connection_->transport_version())) {
- id = GetNthServerInitiatedUnidirectionalStreamId(
- connection_->transport_version(), 3);
- char type[] = {0x00};
-
- QuicStreamFrame data1(id, false, 0, absl::string_view(type, 1));
- session_->OnStreamFrame(data1);
- } else {
- id = QuicUtils::GetHeadersStreamId(connection_->transport_version());
- }
- EXPECT_CALL(*connection_, CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA,
- "stream is static", _))
- .Times(1);
- session_->OnPromiseHeaderList(id, promised_stream_id_, 0, trailers);
-}
-
-TEST_P(QuicSpdyClientSessionTest, GoAwayReceived) {
- if (VersionHasIetfQuicFrames(connection_->transport_version())) {
- return;
- }
- CompleteCryptoHandshake();
-
- // After receiving a GoAway, I should no longer be able to create outgoing
- // streams.
- session_->connection()->OnGoAwayFrame(QuicGoAwayFrame(
- kInvalidControlFrameId, QUIC_PEER_GOING_AWAY, 1u, "Going away."));
- EXPECT_EQ(nullptr, session_->CreateOutgoingBidirectionalStream());
-}
-
-static bool CheckForDecryptionError(QuicFramer* framer) {
- return framer->error() == QUIC_DECRYPTION_FAILURE;
-}
-
-// Various sorts of invalid packets that should not cause a connection
-// to be closed.
-TEST_P(QuicSpdyClientSessionTest, InvalidPacketReceived) {
- QuicSocketAddress server_address(TestPeerIPAddress(), kTestPort);
- QuicSocketAddress client_address(TestPeerIPAddress(), kTestPort);
-
- EXPECT_CALL(*connection_, ProcessUdpPacket(server_address, client_address, _))
- .WillRepeatedly(Invoke(static_cast<MockQuicConnection*>(connection_),
- &MockQuicConnection::ReallyProcessUdpPacket));
- EXPECT_CALL(*connection_, OnCanWrite()).Times(AnyNumber());
- EXPECT_CALL(*connection_, OnError(_)).Times(1);
-
- // Verify that empty packets don't close the connection.
- QuicReceivedPacket zero_length_packet(nullptr, 0, QuicTime::Zero(), false);
- EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
- session_->ProcessUdpPacket(client_address, server_address,
- zero_length_packet);
-
- // Verifiy that small, invalid packets don't close the connection.
- char buf[2] = {0x00, 0x01};
- QuicConnectionId connection_id = session_->connection()->connection_id();
- QuicReceivedPacket valid_packet(buf, 2, QuicTime::Zero(), false);
- // Close connection shouldn't be called.
- EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
- EXPECT_CALL(*connection_, OnError(_)).Times(AtMost(1));
- session_->ProcessUdpPacket(client_address, server_address, valid_packet);
-
- // Verify that a non-decryptable packet doesn't close the connection.
- QuicFramerPeer::SetLastSerializedServerConnectionId(
- QuicConnectionPeer::GetFramer(connection_), connection_id);
- ParsedQuicVersionVector versions = SupportedVersions(GetParam());
- QuicConnectionId destination_connection_id = EmptyQuicConnectionId();
- QuicConnectionId source_connection_id = connection_id;
- std::unique_ptr<QuicEncryptedPacket> packet(ConstructEncryptedPacket(
- destination_connection_id, source_connection_id, false, false, 100,
- "data", true, CONNECTION_ID_ABSENT, CONNECTION_ID_ABSENT,
- PACKET_4BYTE_PACKET_NUMBER, &versions, Perspective::IS_SERVER));
- std::unique_ptr<QuicReceivedPacket> received(
- ConstructReceivedPacket(*packet, QuicTime::Zero()));
- // Change the last byte of the encrypted data.
- *(const_cast<char*>(received->data() + received->length() - 1)) += 1;
- EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
- EXPECT_CALL(*connection_, OnError(Truly(CheckForDecryptionError))).Times(1);
- session_->ProcessUdpPacket(client_address, server_address, *received);
-}
-
-// A packet with invalid framing should cause a connection to be closed.
-TEST_P(QuicSpdyClientSessionTest, InvalidFramedPacketReceived) {
- const ParsedQuicVersion version = GetParam();
- QuicSocketAddress server_address(TestPeerIPAddress(), kTestPort);
- QuicSocketAddress client_address(TestPeerIPAddress(), kTestPort);
- if (version.KnowsWhichDecrypterToUse()) {
- connection_->InstallDecrypter(
- ENCRYPTION_FORWARD_SECURE,
- std::make_unique<NullDecrypter>(Perspective::IS_CLIENT));
- } else {
- connection_->SetDecrypter(
- ENCRYPTION_FORWARD_SECURE,
- std::make_unique<NullDecrypter>(Perspective::IS_CLIENT));
- }
-
- EXPECT_CALL(*connection_, ProcessUdpPacket(server_address, client_address, _))
- .WillRepeatedly(Invoke(static_cast<MockQuicConnection*>(connection_),
- &MockQuicConnection::ReallyProcessUdpPacket));
- EXPECT_CALL(*connection_, OnError(_)).Times(1);
-
- // Verify that a decryptable packet with bad frames does close the connection.
- QuicConnectionId destination_connection_id =
- session_->connection()->connection_id();
- QuicConnectionId source_connection_id = EmptyQuicConnectionId();
- QuicFramerPeer::SetLastSerializedServerConnectionId(
- QuicConnectionPeer::GetFramer(connection_), destination_connection_id);
- bool version_flag = false;
- QuicConnectionIdIncluded scid_included = CONNECTION_ID_ABSENT;
- if (version.HasIetfInvariantHeader()) {
- version_flag = true;
- source_connection_id = destination_connection_id;
- scid_included = CONNECTION_ID_PRESENT;
- }
- std::unique_ptr<QuicEncryptedPacket> packet(ConstructMisFramedEncryptedPacket(
- destination_connection_id, source_connection_id, version_flag, false, 100,
- "data", CONNECTION_ID_ABSENT, scid_included, PACKET_4BYTE_PACKET_NUMBER,
- version, Perspective::IS_SERVER));
- std::unique_ptr<QuicReceivedPacket> received(
- ConstructReceivedPacket(*packet, QuicTime::Zero()));
- EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(1);
- session_->ProcessUdpPacket(client_address, server_address, *received);
-}
-
-TEST_P(QuicSpdyClientSessionTest, PushPromiseOnPromiseHeaders) {
- if (VersionHasIetfQuicFrames(connection_->transport_version())) {
- return;
- }
-
- // Initialize crypto before the client session will create a stream.
- CompleteCryptoHandshake();
-
- MockQuicSpdyClientStream* stream = static_cast<MockQuicSpdyClientStream*>(
- session_->CreateOutgoingBidirectionalStream());
-
- EXPECT_CALL(*stream, OnPromiseHeaderList(_, _, _));
- session_->OnPromiseHeaderList(associated_stream_id_, promised_stream_id_, 0,
- QuicHeaderList());
-}
-
-TEST_P(QuicSpdyClientSessionTest, PushPromiseStreamIdTooHigh) {
- if (VersionHasIetfQuicFrames(connection_->transport_version())) {
- return;
- }
-
- // Initialize crypto before the client session will create a stream.
- CompleteCryptoHandshake();
- QuicStreamId stream_id =
- QuicSessionPeer::GetNextOutgoingBidirectionalStreamId(session_.get());
- QuicSessionPeer::ActivateStream(
- session_.get(), std::make_unique<QuicSpdyClientStream>(
- stream_id, session_.get(), BIDIRECTIONAL));
-
- QuicHeaderList headers;
- headers.OnHeaderBlockStart();
- headers.OnHeader(":path", "/bar");
- headers.OnHeader(":authority", "www.google.com");
- headers.OnHeader(":method", "GET");
- headers.OnHeader(":scheme", "https");
- headers.OnHeaderBlockEnd(0, 0);
-
- const QuicStreamId promise_id = GetNthServerInitiatedUnidirectionalStreamId(
- connection_->transport_version(), 11);
- session_->OnPromiseHeaderList(stream_id, promise_id, 0, headers);
-}
-
-TEST_P(QuicSpdyClientSessionTest, PushPromiseOnPromiseHeadersAlreadyClosed) {
- // Initialize crypto before the client session will create a stream.
- CompleteCryptoHandshake();
-
- session_->CreateOutgoingBidirectionalStream();
-
- EXPECT_CALL(*connection_, SendControlFrame(_));
- EXPECT_CALL(*connection_,
- OnStreamReset(promised_stream_id_, QUIC_REFUSED_STREAM));
- session_->ResetPromised(promised_stream_id_, QUIC_REFUSED_STREAM);
-
- session_->OnPromiseHeaderList(associated_stream_id_, promised_stream_id_, 0,
- QuicHeaderList());
-}
-
-TEST_P(QuicSpdyClientSessionTest, PushPromiseOutOfOrder) {
- if (VersionHasIetfQuicFrames(connection_->transport_version())) {
- return;
- }
-
- // Initialize crypto before the client session will create a stream.
- CompleteCryptoHandshake();
-
- MockQuicSpdyClientStream* stream = static_cast<MockQuicSpdyClientStream*>(
- session_->CreateOutgoingBidirectionalStream());
-
- EXPECT_CALL(*stream, OnPromiseHeaderList(promised_stream_id_, _, _));
- session_->OnPromiseHeaderList(associated_stream_id_, promised_stream_id_, 0,
- QuicHeaderList());
- associated_stream_id_ +=
- QuicUtils::StreamIdDelta(connection_->transport_version());
- if (!VersionUsesHttp3(session_->transport_version())) {
- EXPECT_CALL(*connection_,
- CloseConnection(QUIC_INVALID_STREAM_ID,
- "Received push stream id lesser or equal to the"
- " last accepted before",
- _));
- }
- session_->OnPromiseHeaderList(associated_stream_id_, promised_stream_id_, 0,
- QuicHeaderList());
-}
-
-TEST_P(QuicSpdyClientSessionTest, PushPromiseOutgoingStreamId) {
- // Initialize crypto before the client session will create a stream.
- CompleteCryptoHandshake();
-
- MockQuicSpdyClientStream* stream = static_cast<MockQuicSpdyClientStream*>(
- session_->CreateOutgoingBidirectionalStream());
-
- // Promise an illegal (outgoing) stream id.
- promised_stream_id_ = GetNthClientInitiatedBidirectionalStreamId(
- connection_->transport_version(), 0);
- EXPECT_CALL(
- *connection_,
- CloseConnection(QUIC_INVALID_STREAM_ID,
- "Received push stream id for outgoing stream.", _));
-
- session_->OnPromiseHeaderList(stream->id(), promised_stream_id_, 0,
- QuicHeaderList());
-}
-
-TEST_P(QuicSpdyClientSessionTest, PushPromiseHandlePromise) {
- // Initialize crypto before the client session will create a stream.
- CompleteCryptoHandshake();
-
- session_->CreateOutgoingBidirectionalStream();
-
- EXPECT_TRUE(session_->HandlePromised(associated_stream_id_,
- promised_stream_id_, push_promise_));
-
- EXPECT_NE(session_->GetPromisedById(promised_stream_id_), nullptr);
- EXPECT_NE(session_->GetPromisedByUrl(promise_url_), nullptr);
-}
-
-TEST_P(QuicSpdyClientSessionTest, PushPromiseAlreadyClosed) {
- // Initialize crypto before the client session will create a stream.
- CompleteCryptoHandshake();
-
- session_->CreateOutgoingBidirectionalStream();
- session_->GetOrCreateStream(promised_stream_id_);
-
- EXPECT_CALL(*connection_, SendControlFrame(_));
- EXPECT_CALL(*connection_,
- OnStreamReset(promised_stream_id_, QUIC_REFUSED_STREAM));
-
- session_->ResetPromised(promised_stream_id_, QUIC_REFUSED_STREAM);
- SpdyHeaderBlock promise_headers;
- EXPECT_FALSE(session_->HandlePromised(associated_stream_id_,
- promised_stream_id_, promise_headers));
-
- // Verify that the promise was not created.
- EXPECT_EQ(session_->GetPromisedById(promised_stream_id_), nullptr);
- EXPECT_EQ(session_->GetPromisedByUrl(promise_url_), nullptr);
-}
-
-TEST_P(QuicSpdyClientSessionTest, PushPromiseDuplicateUrl) {
- // Initialize crypto before the client session will create a stream.
- CompleteCryptoHandshake();
-
- session_->CreateOutgoingBidirectionalStream();
-
- EXPECT_TRUE(session_->HandlePromised(associated_stream_id_,
- promised_stream_id_, push_promise_));
-
- EXPECT_NE(session_->GetPromisedById(promised_stream_id_), nullptr);
- EXPECT_NE(session_->GetPromisedByUrl(promise_url_), nullptr);
-
- promised_stream_id_ +=
- QuicUtils::StreamIdDelta(connection_->transport_version());
- EXPECT_CALL(*connection_, SendControlFrame(_));
- EXPECT_CALL(*connection_,
- OnStreamReset(promised_stream_id_, QUIC_DUPLICATE_PROMISE_URL));
-
- EXPECT_FALSE(session_->HandlePromised(associated_stream_id_,
- promised_stream_id_, push_promise_));
-
- // Verify that the promise was not created.
- EXPECT_EQ(session_->GetPromisedById(promised_stream_id_), nullptr);
-}
-
-TEST_P(QuicSpdyClientSessionTest, ReceivingPromiseEnhanceYourCalm) {
- CompleteCryptoHandshake();
- for (size_t i = 0u; i < session_->get_max_promises(); i++) {
- push_promise_[":path"] = absl::StrCat("/bar", i);
-
- QuicStreamId id =
- promised_stream_id_ +
- i * QuicUtils::StreamIdDelta(connection_->transport_version());
-
- EXPECT_TRUE(
- session_->HandlePromised(associated_stream_id_, id, push_promise_));
-
- // Verify that the promise is in the unclaimed streams map.
- std::string promise_url(
- SpdyServerPushUtils::GetPromisedUrlFromHeaders(push_promise_));
- EXPECT_NE(session_->GetPromisedByUrl(promise_url), nullptr);
- EXPECT_NE(session_->GetPromisedById(id), nullptr);
- }
-
- // One more promise, this should be refused.
- int i = session_->get_max_promises();
- push_promise_[":path"] = absl::StrCat("/bar", i);
-
- QuicStreamId id =
- promised_stream_id_ +
- i * QuicUtils::StreamIdDelta(connection_->transport_version());
- EXPECT_CALL(*connection_, SendControlFrame(_));
- EXPECT_CALL(*connection_, OnStreamReset(id, QUIC_REFUSED_STREAM));
- EXPECT_FALSE(
- session_->HandlePromised(associated_stream_id_, id, push_promise_));
-
- // Verify that the promise was not created.
- std::string promise_url(
- SpdyServerPushUtils::GetPromisedUrlFromHeaders(push_promise_));
- EXPECT_EQ(session_->GetPromisedById(id), nullptr);
- EXPECT_EQ(session_->GetPromisedByUrl(promise_url), nullptr);
-}
-
-TEST_P(QuicSpdyClientSessionTest, IsClosedTrueAfterResetPromisedAlreadyOpen) {
- // Initialize crypto before the client session will create a stream.
- CompleteCryptoHandshake();
-
- session_->GetOrCreateStream(promised_stream_id_);
- EXPECT_CALL(*connection_, SendControlFrame(_));
- EXPECT_CALL(*connection_,
- OnStreamReset(promised_stream_id_, QUIC_REFUSED_STREAM));
- session_->ResetPromised(promised_stream_id_, QUIC_REFUSED_STREAM);
- EXPECT_TRUE(session_->IsClosedStream(promised_stream_id_));
-}
-
-TEST_P(QuicSpdyClientSessionTest, IsClosedTrueAfterResetPromisedNonexistant) {
- // Initialize crypto before the client session will create a stream.
- CompleteCryptoHandshake();
-
- EXPECT_CALL(*connection_, SendControlFrame(_));
- EXPECT_CALL(*connection_,
- OnStreamReset(promised_stream_id_, QUIC_REFUSED_STREAM));
- session_->ResetPromised(promised_stream_id_, QUIC_REFUSED_STREAM);
- EXPECT_TRUE(session_->IsClosedStream(promised_stream_id_));
-}
-
-TEST_P(QuicSpdyClientSessionTest, OnInitialHeadersCompleteIsPush) {
- // Initialize crypto before the client session will create a stream.
- CompleteCryptoHandshake();
- session_->GetOrCreateStream(promised_stream_id_);
- EXPECT_TRUE(session_->HandlePromised(associated_stream_id_,
- promised_stream_id_, push_promise_));
- EXPECT_NE(session_->GetPromisedById(promised_stream_id_), nullptr);
- EXPECT_NE(session_->GetPromisedStream(promised_stream_id_), nullptr);
- EXPECT_NE(session_->GetPromisedByUrl(promise_url_), nullptr);
-
- session_->OnInitialHeadersComplete(promised_stream_id_, SpdyHeaderBlock());
-}
-
-TEST_P(QuicSpdyClientSessionTest, OnInitialHeadersCompleteIsNotPush) {
- // Initialize crypto before the client session will create a stream.
- CompleteCryptoHandshake();
- session_->CreateOutgoingBidirectionalStream();
- session_->OnInitialHeadersComplete(promised_stream_id_, SpdyHeaderBlock());
-}
-
-TEST_P(QuicSpdyClientSessionTest, DeletePromised) {
- // Initialize crypto before the client session will create a stream.
- CompleteCryptoHandshake();
- session_->GetOrCreateStream(promised_stream_id_);
- EXPECT_TRUE(session_->HandlePromised(associated_stream_id_,
- promised_stream_id_, push_promise_));
- QuicClientPromisedInfo* promised =
- session_->GetPromisedById(promised_stream_id_);
- EXPECT_NE(promised, nullptr);
- EXPECT_NE(session_->GetPromisedStream(promised_stream_id_), nullptr);
- EXPECT_NE(session_->GetPromisedByUrl(promise_url_), nullptr);
-
- session_->DeletePromised(promised);
- EXPECT_EQ(session_->GetPromisedById(promised_stream_id_), nullptr);
- EXPECT_EQ(session_->GetPromisedByUrl(promise_url_), nullptr);
-}
-
-TEST_P(QuicSpdyClientSessionTest, ResetPromised) {
- // Initialize crypto before the client session will create a stream.
- CompleteCryptoHandshake();
- session_->GetOrCreateStream(promised_stream_id_);
- EXPECT_TRUE(session_->HandlePromised(associated_stream_id_,
- promised_stream_id_, push_promise_));
- EXPECT_CALL(*connection_, SendControlFrame(_));
- EXPECT_CALL(*connection_,
- OnStreamReset(promised_stream_id_, QUIC_STREAM_PEER_GOING_AWAY));
- session_->ResetStream(promised_stream_id_, QUIC_STREAM_PEER_GOING_AWAY);
- QuicClientPromisedInfo* promised =
- session_->GetPromisedById(promised_stream_id_);
- EXPECT_NE(promised, nullptr);
- EXPECT_NE(session_->GetPromisedByUrl(promise_url_), nullptr);
- EXPECT_EQ(session_->GetPromisedStream(promised_stream_id_), nullptr);
-}
-
-TEST_P(QuicSpdyClientSessionTest, PushPromiseInvalidMethod) {
- // Initialize crypto before the client session will create a stream.
- CompleteCryptoHandshake();
-
- session_->CreateOutgoingBidirectionalStream();
-
- EXPECT_CALL(*connection_, SendControlFrame(_));
- EXPECT_CALL(*connection_,
- OnStreamReset(promised_stream_id_, QUIC_INVALID_PROMISE_METHOD));
-
- push_promise_[":method"] = "POST";
- EXPECT_FALSE(session_->HandlePromised(associated_stream_id_,
- promised_stream_id_, push_promise_));
-
- EXPECT_EQ(session_->GetPromisedById(promised_stream_id_), nullptr);
- EXPECT_EQ(session_->GetPromisedByUrl(promise_url_), nullptr);
-}
-
-TEST_P(QuicSpdyClientSessionTest, PushPromiseInvalidHost) {
- // Initialize crypto before the client session will create a stream.
- CompleteCryptoHandshake();
-
- session_->CreateOutgoingBidirectionalStream();
-
- EXPECT_CALL(*connection_, SendControlFrame(_));
- EXPECT_CALL(*connection_,
- OnStreamReset(promised_stream_id_, QUIC_INVALID_PROMISE_URL));
-
- push_promise_[":authority"] = "";
- EXPECT_FALSE(session_->HandlePromised(associated_stream_id_,
- promised_stream_id_, push_promise_));
-
- EXPECT_EQ(session_->GetPromisedById(promised_stream_id_), nullptr);
- EXPECT_EQ(session_->GetPromisedByUrl(promise_url_), nullptr);
-}
-
-TEST_P(QuicSpdyClientSessionTest,
- TryToCreateServerInitiatedBidirectionalStream) {
- if (VersionHasIetfQuicFrames(connection_->transport_version())) {
- EXPECT_CALL(
- *connection_,
- CloseConnection(QUIC_HTTP_SERVER_INITIATED_BIDIRECTIONAL_STREAM, _, _));
- } else {
- EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
- }
- session_->GetOrCreateStream(GetNthServerInitiatedBidirectionalStreamId(
- connection_->transport_version(), 0));
-}
-
-TEST_P(QuicSpdyClientSessionTest, TooManyPushPromises) {
- if (VersionHasIetfQuicFrames(connection_->transport_version())) {
- return;
- }
-
- // Initialize crypto before the client session will create a stream.
- CompleteCryptoHandshake();
- QuicStreamId stream_id =
- QuicSessionPeer::GetNextOutgoingBidirectionalStreamId(session_.get());
- QuicSessionPeer::ActivateStream(
- session_.get(), std::make_unique<QuicSpdyClientStream>(
- stream_id, session_.get(), BIDIRECTIONAL));
-
- EXPECT_CALL(*connection_, OnStreamReset(_, QUIC_REFUSED_STREAM));
-
- for (size_t promise_count = 0; promise_count <= session_->get_max_promises();
- promise_count++) {
- auto promise_id = GetNthServerInitiatedUnidirectionalStreamId(
- connection_->transport_version(), promise_count);
- auto headers = QuicHeaderList();
- headers.OnHeaderBlockStart();
- headers.OnHeader(":path", absl::StrCat("/", promise_count));
- headers.OnHeader(":authority", "www.google.com");
- headers.OnHeader(":method", "GET");
- headers.OnHeader(":scheme", "https");
- headers.OnHeaderBlockEnd(0, 0);
- session_->OnPromiseHeaderList(stream_id, promise_id, 0, headers);
- }
-}
-
-// Test that upon receiving HTTP/3 SETTINGS, the settings are serialized and
-// stored into client session cache.
-TEST_P(QuicSpdyClientSessionTest, OnSettingsFrame) {
- // This feature is HTTP/3 only
- if (!VersionUsesHttp3(session_->transport_version())) {
- return;
- }
- CompleteCryptoHandshake();
- SettingsFrame settings;
- settings.values[SETTINGS_QPACK_MAX_TABLE_CAPACITY] = 2;
- settings.values[SETTINGS_MAX_FIELD_SECTION_SIZE] = 5;
- settings.values[256] = 4; // unknown setting
- char application_state[] = {// type (SETTINGS)
- 0x04,
- // length
- 0x07,
- // identifier (SETTINGS_QPACK_MAX_TABLE_CAPACITY)
- 0x01,
- // content
- 0x02,
- // identifier (SETTINGS_MAX_FIELD_SECTION_SIZE)
- 0x06,
- // content
- 0x05,
- // identifier (256 in variable length integer)
- 0x40 + 0x01, 0x00,
- // content
- 0x04};
- ApplicationState expected(std::begin(application_state),
- std::end(application_state));
- session_->OnSettingsFrame(settings);
- EXPECT_EQ(expected, *client_session_cache_
- ->Lookup(QuicServerId(kServerHostname, kPort, false),
- session_->GetClock()->WallNow(), nullptr)
- ->application_state);
-}
-
-TEST_P(QuicSpdyClientSessionTest, IetfZeroRttSetup) {
- // This feature is TLS-only.
- if (session_->version().UsesQuicCrypto()) {
- return;
- }
-
- CompleteFirstConnection();
-
- CreateConnection();
- // Session configs should be in initial state.
- if (session_->version().UsesHttp3()) {
- EXPECT_EQ(0u, session_->flow_controller()->send_window_offset());
- EXPECT_EQ(std::numeric_limits<size_t>::max(),
- session_->max_outbound_header_list_size());
- } else {
- EXPECT_EQ(kMinimumFlowControlSendWindow,
- session_->flow_controller()->send_window_offset());
- }
- session_->CryptoConnect();
- EXPECT_TRUE(session_->IsEncryptionEstablished());
- EXPECT_EQ(ENCRYPTION_ZERO_RTT, session_->connection()->encryption_level());
-
- // The client session should have a basic setup ready before the handshake
- // succeeds.
- EXPECT_EQ(kInitialSessionFlowControlWindowForTest,
- session_->flow_controller()->send_window_offset());
- if (session_->version().UsesHttp3()) {
- auto* id_manager = QuicSessionPeer::ietf_streamid_manager(session_.get());
- EXPECT_EQ(kDefaultMaxStreamsPerConnection,
- id_manager->max_outgoing_bidirectional_streams());
- EXPECT_EQ(
- kDefaultMaxStreamsPerConnection + kHttp3StaticUnidirectionalStreamCount,
- id_manager->max_outgoing_unidirectional_streams());
- auto* control_stream =
- QuicSpdySessionPeer::GetSendControlStream(session_.get());
- EXPECT_EQ(kInitialStreamFlowControlWindowForTest,
- QuicStreamPeer::SendWindowOffset(control_stream));
- EXPECT_EQ(5u, session_->max_outbound_header_list_size());
- } else {
- auto* id_manager = QuicSessionPeer::GetStreamIdManager(session_.get());
- EXPECT_EQ(kDefaultMaxStreamsPerConnection,
- id_manager->max_open_outgoing_streams());
- }
-
- // Complete the handshake with a different config.
- QuicConfig config = DefaultQuicConfig();
- config.SetInitialMaxStreamDataBytesUnidirectionalToSend(
- kInitialStreamFlowControlWindowForTest + 1);
- config.SetInitialSessionFlowControlWindowToSend(
- kInitialSessionFlowControlWindowForTest + 1);
- config.SetMaxBidirectionalStreamsToSend(kDefaultMaxStreamsPerConnection + 1);
- config.SetMaxUnidirectionalStreamsToSend(kDefaultMaxStreamsPerConnection + 1);
- crypto_test_utils::HandshakeWithFakeServer(
- &config, server_crypto_config_.get(), &helper_, &alarm_factory_,
- connection_, crypto_stream_, AlpnForVersion(connection_->version()));
-
- EXPECT_TRUE(session_->GetCryptoStream()->IsResumption());
- EXPECT_EQ(kInitialSessionFlowControlWindowForTest + 1,
- session_->flow_controller()->send_window_offset());
- if (session_->version().UsesHttp3()) {
- auto* id_manager = QuicSessionPeer::ietf_streamid_manager(session_.get());
- auto* control_stream =
- QuicSpdySessionPeer::GetSendControlStream(session_.get());
- EXPECT_EQ(kDefaultMaxStreamsPerConnection + 1,
- id_manager->max_outgoing_bidirectional_streams());
- EXPECT_EQ(kDefaultMaxStreamsPerConnection +
- kHttp3StaticUnidirectionalStreamCount + 1,
- id_manager->max_outgoing_unidirectional_streams());
- EXPECT_EQ(kInitialStreamFlowControlWindowForTest + 1,
- QuicStreamPeer::SendWindowOffset(control_stream));
- } else {
- auto* id_manager = QuicSessionPeer::GetStreamIdManager(session_.get());
- EXPECT_EQ(kDefaultMaxStreamsPerConnection + 1,
- id_manager->max_open_outgoing_streams());
- }
-
- EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
- // Let the session receive a new SETTINGS frame to complete the second
- // connection.
- if (session_->version().UsesHttp3()) {
- SettingsFrame settings;
- settings.values[SETTINGS_QPACK_MAX_TABLE_CAPACITY] = 2;
- settings.values[SETTINGS_MAX_FIELD_SECTION_SIZE] = 5;
- settings.values[256] = 4; // unknown setting
- session_->OnSettingsFrame(settings);
- }
-}
-
-// Regression test for b/159168475
-TEST_P(QuicSpdyClientSessionTest, RetransmitDataOnZeroRttReject) {
- // This feature is TLS-only.
- if (session_->version().UsesQuicCrypto()) {
- return;
- }
-
- CompleteFirstConnection();
-
- // Create a second connection, but disable 0-RTT on the server.
- CreateConnection();
- ON_CALL(*connection_, OnCanWrite())
- .WillByDefault(
- testing::Invoke(connection_, &MockQuicConnection::ReallyOnCanWrite));
- EXPECT_CALL(*connection_, OnCanWrite()).Times(0);
-
- QuicConfig config = DefaultQuicConfig();
- config.SetMaxUnidirectionalStreamsToSend(kDefaultMaxStreamsPerConnection);
- config.SetMaxBidirectionalStreamsToSend(kDefaultMaxStreamsPerConnection);
- SSL_CTX_set_early_data_enabled(server_crypto_config_->ssl_ctx(), false);
-
- // Packets will be written: CHLO, HTTP/3 SETTINGS (H/3 only), and request
- // data.
- EXPECT_CALL(*connection_,
- OnPacketSent(ENCRYPTION_INITIAL, NOT_RETRANSMISSION));
- EXPECT_CALL(*connection_,
- OnPacketSent(ENCRYPTION_ZERO_RTT, NOT_RETRANSMISSION))
- .Times(session_->version().UsesHttp3() ? 2 : 1);
- session_->CryptoConnect();
- EXPECT_TRUE(session_->IsEncryptionEstablished());
- EXPECT_EQ(ENCRYPTION_ZERO_RTT, session_->connection()->encryption_level());
- QuicSpdyClientStream* stream = session_->CreateOutgoingBidirectionalStream();
- ASSERT_TRUE(stream);
- stream->WriteOrBufferData("hello", true, nullptr);
-
- // When handshake is done, the client sends 2 packet: HANDSHAKE FINISHED, and
- // coalesced retransmission of HTTP/3 SETTINGS and request data.
- EXPECT_CALL(*connection_,
- OnPacketSent(ENCRYPTION_HANDSHAKE, NOT_RETRANSMISSION));
- // TODO(b/158027651): change transmission type to ALL_ZERO_RTT_RETRANSMISSION.
- EXPECT_CALL(*connection_,
- OnPacketSent(ENCRYPTION_FORWARD_SECURE, LOSS_RETRANSMISSION));
- crypto_test_utils::HandshakeWithFakeServer(
- &config, server_crypto_config_.get(), &helper_, &alarm_factory_,
- connection_, crypto_stream_, AlpnForVersion(connection_->version()));
- EXPECT_TRUE(session_->GetCryptoStream()->IsResumption());
-}
-
-// When IETF QUIC 0-RTT is rejected, a server-sent fresh transport params is
-// available. If the new transport params reduces stream/flow control limit to
-// lower than what the client has already used, connection will be closed.
-TEST_P(QuicSpdyClientSessionTest, ZeroRttRejectReducesStreamLimitTooMuch) {
- // This feature is TLS-only.
- if (session_->version().UsesQuicCrypto()) {
- return;
- }
-
- CompleteFirstConnection();
-
- // Create a second connection, but disable 0-RTT on the server.
- CreateConnection();
- QuicConfig config = DefaultQuicConfig();
- // Server doesn't allow any bidirectional streams.
- config.SetMaxBidirectionalStreamsToSend(0);
- SSL_CTX_set_early_data_enabled(server_crypto_config_->ssl_ctx(), false);
- session_->CryptoConnect();
- EXPECT_TRUE(session_->IsEncryptionEstablished());
- QuicSpdyClientStream* stream = session_->CreateOutgoingBidirectionalStream();
- ASSERT_TRUE(stream);
-
- if (session_->version().UsesHttp3()) {
- EXPECT_CALL(
- *connection_,
- CloseConnection(
- QUIC_ZERO_RTT_UNRETRANSMITTABLE,
- "Server rejected 0-RTT, aborting because new bidirectional initial "
- "stream limit 0 is less than current open streams: 1",
- _))
- .WillOnce(testing::Invoke(connection_,
- &MockQuicConnection::ReallyCloseConnection));
- } else {
- EXPECT_CALL(
- *connection_,
- CloseConnection(QUIC_INTERNAL_ERROR,
- "Server rejected 0-RTT, aborting because new stream "
- "limit 0 is less than current open streams: 1",
- _))
- .WillOnce(testing::Invoke(connection_,
- &MockQuicConnection::ReallyCloseConnection));
- }
- EXPECT_CALL(*connection_, CloseConnection(QUIC_HANDSHAKE_FAILED, _, _));
-
- crypto_test_utils::HandshakeWithFakeServer(
- &config, server_crypto_config_.get(), &helper_, &alarm_factory_,
- connection_, crypto_stream_, AlpnForVersion(connection_->version()));
-}
-
-TEST_P(QuicSpdyClientSessionTest,
- ZeroRttRejectReducesStreamFlowControlTooMuch) {
- // This feature is TLS-only.
- if (session_->version().UsesQuicCrypto()) {
- return;
- }
-
- CompleteFirstConnection();
-
- // Create a second connection, but disable 0-RTT on the server.
- CreateConnection();
- QuicConfig config = DefaultQuicConfig();
- // Server doesn't allow any outgoing streams.
- config.SetInitialMaxStreamDataBytesIncomingBidirectionalToSend(2);
- config.SetInitialMaxStreamDataBytesUnidirectionalToSend(1);
- SSL_CTX_set_early_data_enabled(server_crypto_config_->ssl_ctx(), false);
- session_->CryptoConnect();
- EXPECT_TRUE(session_->IsEncryptionEstablished());
- QuicSpdyClientStream* stream = session_->CreateOutgoingBidirectionalStream();
- ASSERT_TRUE(stream);
- // Let the stream write more than 1 byte of data.
- stream->WriteOrBufferData("hello", true, nullptr);
-
- if (session_->version().UsesHttp3()) {
- // Both control stream and the request stream will report errors.
- // Open question: should both streams be closed with the same error code?
- EXPECT_CALL(*connection_, CloseConnection(_, _, _))
- .WillOnce(testing::Invoke(connection_,
- &MockQuicConnection::ReallyCloseConnection));
- EXPECT_CALL(*connection_,
- CloseConnection(QUIC_ZERO_RTT_UNRETRANSMITTABLE, _, _))
- .WillOnce(testing::Invoke(connection_,
- &MockQuicConnection::ReallyCloseConnection))
- .RetiresOnSaturation();
- } else {
- EXPECT_CALL(*connection_,
- CloseConnection(
- QUIC_ZERO_RTT_UNRETRANSMITTABLE,
- "Server rejected 0-RTT, aborting because new stream max "
- "data 2 for stream 3 is less than currently used: 5",
- _))
- .Times(1)
- .WillOnce(testing::Invoke(connection_,
- &MockQuicConnection::ReallyCloseConnection));
- }
- EXPECT_CALL(*connection_, CloseConnection(QUIC_HANDSHAKE_FAILED, _, _));
-
- crypto_test_utils::HandshakeWithFakeServer(
- &config, server_crypto_config_.get(), &helper_, &alarm_factory_,
- connection_, crypto_stream_, AlpnForVersion(connection_->version()));
-}
-
-TEST_P(QuicSpdyClientSessionTest,
- ZeroRttRejectReducesSessionFlowControlTooMuch) {
- // This feature is TLS-only.
- if (session_->version().UsesQuicCrypto()) {
- return;
- }
-
- CompleteFirstConnection();
-
- // Create a second connection, but disable 0-RTT on the server.
- CreateConnection();
- QuicConfig config = DefaultQuicConfig();
- // Server doesn't allow minimum data in session.
- config.SetInitialSessionFlowControlWindowToSend(
- kMinimumFlowControlSendWindow);
- SSL_CTX_set_early_data_enabled(server_crypto_config_->ssl_ctx(), false);
- session_->CryptoConnect();
- EXPECT_TRUE(session_->IsEncryptionEstablished());
- QuicSpdyClientStream* stream = session_->CreateOutgoingBidirectionalStream();
- ASSERT_TRUE(stream);
- std::string data_to_send(kMinimumFlowControlSendWindow + 1, 'x');
- // Let the stream write some data.
- stream->WriteOrBufferData(data_to_send, true, nullptr);
-
- EXPECT_CALL(*connection_,
- CloseConnection(QUIC_ZERO_RTT_UNRETRANSMITTABLE, _, _))
- .WillOnce(testing::Invoke(connection_,
- &MockQuicConnection::ReallyCloseConnection));
- EXPECT_CALL(*connection_, CloseConnection(QUIC_HANDSHAKE_FAILED, _, _));
-
- crypto_test_utils::HandshakeWithFakeServer(
- &config, server_crypto_config_.get(), &helper_, &alarm_factory_,
- connection_, crypto_stream_, AlpnForVersion(connection_->version()));
-}
-
-TEST_P(QuicSpdyClientSessionTest, BadSettingsInZeroRttResumption) {
- if (!session_->version().UsesHttp3()) {
- return;
- }
-
- CompleteFirstConnection();
-
- CreateConnection();
- CompleteCryptoHandshake();
- EXPECT_TRUE(session_->GetCryptoStream()->EarlyDataAccepted());
-
- EXPECT_CALL(
- *connection_,
- CloseConnection(QUIC_HTTP_ZERO_RTT_RESUMPTION_SETTINGS_MISMATCH, _, _))
- .WillOnce(testing::Invoke(connection_,
- &MockQuicConnection::ReallyCloseConnection));
- // Let the session receive a different SETTINGS frame.
- SettingsFrame settings;
- settings.values[SETTINGS_QPACK_MAX_TABLE_CAPACITY] = 1;
- settings.values[SETTINGS_MAX_FIELD_SECTION_SIZE] = 5;
- settings.values[256] = 4; // unknown setting
- session_->OnSettingsFrame(settings);
-}
-
-TEST_P(QuicSpdyClientSessionTest, BadSettingsInZeroRttRejection) {
- if (!session_->version().UsesHttp3()) {
- return;
- }
-
- CompleteFirstConnection();
-
- CreateConnection();
- SSL_CTX_set_early_data_enabled(server_crypto_config_->ssl_ctx(), false);
- session_->CryptoConnect();
- EXPECT_TRUE(session_->IsEncryptionEstablished());
- QuicConfig config = DefaultQuicConfig();
- crypto_test_utils::HandshakeWithFakeServer(
- &config, server_crypto_config_.get(), &helper_, &alarm_factory_,
- connection_, crypto_stream_, AlpnForVersion(connection_->version()));
- EXPECT_FALSE(session_->GetCryptoStream()->EarlyDataAccepted());
-
- EXPECT_CALL(
- *connection_,
- CloseConnection(QUIC_HTTP_ZERO_RTT_REJECTION_SETTINGS_MISMATCH, _, _))
- .WillOnce(testing::Invoke(connection_,
- &MockQuicConnection::ReallyCloseConnection));
- // Let the session receive a different SETTINGS frame.
- SettingsFrame settings;
- settings.values[SETTINGS_QPACK_MAX_TABLE_CAPACITY] = 2;
- // setting on SETTINGS_MAX_FIELD_SECTION_SIZE is reduced.
- settings.values[SETTINGS_MAX_FIELD_SECTION_SIZE] = 4;
- settings.values[256] = 4; // unknown setting
- session_->OnSettingsFrame(settings);
-}
-
-TEST_P(QuicSpdyClientSessionTest, ServerAcceptsZeroRttButOmitSetting) {
- if (!session_->version().UsesHttp3()) {
- return;
- }
-
- CompleteFirstConnection();
-
- CreateConnection();
- CompleteCryptoHandshake();
- EXPECT_TRUE(session_->GetMutableCryptoStream()->EarlyDataAccepted());
-
- EXPECT_CALL(
- *connection_,
- CloseConnection(QUIC_HTTP_ZERO_RTT_RESUMPTION_SETTINGS_MISMATCH, _, _))
- .WillOnce(testing::Invoke(connection_,
- &MockQuicConnection::ReallyCloseConnection));
- // Let the session receive a different SETTINGS frame.
- SettingsFrame settings;
- settings.values[SETTINGS_QPACK_MAX_TABLE_CAPACITY] = 1;
- // Intentionally omit SETTINGS_MAX_FIELD_SECTION_SIZE which was previously
- // sent with a non-zero value.
- settings.values[256] = 4; // unknown setting
- session_->OnSettingsFrame(settings);
-}
-
-} // namespace
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_client_stream.cc b/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_client_stream.cc
deleted file mode 100644
index 2491900c80d..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_client_stream.cc
+++ /dev/null
@@ -1,219 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/http/quic_spdy_client_stream.h"
-
-#include <utility>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/http/quic_client_promised_info.h"
-#include "quic/core/http/quic_spdy_client_session.h"
-#include "quic/core/http/spdy_utils.h"
-#include "quic/core/http/web_transport_http3.h"
-#include "quic/core/quic_alarm.h"
-#include "quic/platform/api/quic_logging.h"
-#include "common/quiche_text_utils.h"
-#include "spdy/core/spdy_protocol.h"
-
-using spdy::SpdyHeaderBlock;
-
-namespace quic {
-
-QuicSpdyClientStream::QuicSpdyClientStream(QuicStreamId id,
- QuicSpdyClientSession* session,
- StreamType type)
- : QuicSpdyStream(id, session, type),
- content_length_(-1),
- response_code_(0),
- header_bytes_read_(0),
- header_bytes_written_(0),
- session_(session),
- has_preliminary_headers_(false) {}
-
-QuicSpdyClientStream::QuicSpdyClientStream(PendingStream* pending,
- QuicSpdyClientSession* session)
- : QuicSpdyStream(pending, session),
- content_length_(-1),
- response_code_(0),
- header_bytes_read_(0),
- header_bytes_written_(0),
- session_(session),
- has_preliminary_headers_(false) {}
-
-QuicSpdyClientStream::~QuicSpdyClientStream() = default;
-
-void QuicSpdyClientStream::OnInitialHeadersComplete(
- bool fin,
- size_t frame_len,
- const QuicHeaderList& header_list) {
- QuicSpdyStream::OnInitialHeadersComplete(fin, frame_len, header_list);
-
- QUICHE_DCHECK(headers_decompressed());
- header_bytes_read_ += frame_len;
- if (rst_sent()) {
- // QuicSpdyStream::OnInitialHeadersComplete already rejected invalid
- // response header.
- return;
- }
-
- if (!SpdyUtils::CopyAndValidateHeaders(header_list, &content_length_,
- &response_headers_)) {
- QUIC_DLOG(ERROR) << "Failed to parse header list: "
- << header_list.DebugString() << " on stream " << id();
- Reset(QUIC_BAD_APPLICATION_PAYLOAD);
- return;
- }
-
- if (web_transport() != nullptr) {
- web_transport()->HeadersReceived(response_headers_);
- if (!web_transport()->ready()) {
- // The request was rejected by WebTransport, typically due to not having a
- // 2xx status. The reason we're using Reset() here rather than closing
- // cleanly is that even if the server attempts to send us any form of body
- // with a 4xx request, we've already set up the capsule parser, and we
- // don't have any way to process anything from the response body in
- // question.
- Reset(QUIC_STREAM_CANCELLED);
- return;
- }
- }
-
- if (!ParseHeaderStatusCode(response_headers_, &response_code_)) {
- QUIC_DLOG(ERROR) << "Received invalid response code: "
- << response_headers_[":status"].as_string()
- << " on stream " << id();
- Reset(QUIC_BAD_APPLICATION_PAYLOAD);
- return;
- }
-
- if (response_code_ == 101) {
- // 101 "Switching Protocols" is forbidden in HTTP/3 as per the
- // "HTTP Upgrade" section of draft-ietf-quic-http.
- QUIC_DLOG(ERROR) << "Received forbidden 101 response code"
- << " on stream " << id();
- Reset(QUIC_BAD_APPLICATION_PAYLOAD);
- return;
- }
-
- if (response_code_ >= 100 && response_code_ < 200) {
- // These are Informational 1xx headers, not the actual response headers.
- QUIC_DLOG(INFO) << "Received informational response code: "
- << response_headers_[":status"].as_string() << " on stream "
- << id();
- set_headers_decompressed(false);
- if (response_code_ == 100 && !has_preliminary_headers_) {
- // This is 100 Continue, save it to enable "Expect: 100-continue".
- has_preliminary_headers_ = true;
- preliminary_headers_ = std::move(response_headers_);
- } else {
- response_headers_.clear();
- }
- }
-
- ConsumeHeaderList();
- QUIC_DVLOG(1) << "headers complete for stream " << id();
-
- session_->OnInitialHeadersComplete(id(), response_headers_);
-}
-
-void QuicSpdyClientStream::OnTrailingHeadersComplete(
- bool fin,
- size_t frame_len,
- const QuicHeaderList& header_list) {
- QuicSpdyStream::OnTrailingHeadersComplete(fin, frame_len, header_list);
- MarkTrailersConsumed();
-}
-
-void QuicSpdyClientStream::OnPromiseHeaderList(
- QuicStreamId promised_id,
- size_t frame_len,
- const QuicHeaderList& header_list) {
- header_bytes_read_ += frame_len;
- int64_t content_length = -1;
- SpdyHeaderBlock promise_headers;
- if (!SpdyUtils::CopyAndValidateHeaders(header_list, &content_length,
- &promise_headers)) {
- QUIC_DLOG(ERROR) << "Failed to parse promise headers: "
- << header_list.DebugString();
- Reset(QUIC_BAD_APPLICATION_PAYLOAD);
- return;
- }
-
- session_->HandlePromised(id(), promised_id, promise_headers);
- if (visitor() != nullptr) {
- visitor()->OnPromiseHeadersComplete(promised_id, frame_len);
- }
-}
-
-void QuicSpdyClientStream::OnBodyAvailable() {
- // For push streams, visitor will not be set until the rendezvous
- // between server promise and client request is complete.
- if (visitor() == nullptr)
- return;
-
- while (HasBytesToRead()) {
- struct iovec iov;
- if (GetReadableRegions(&iov, 1) == 0) {
- // No more data to read.
- break;
- }
- QUIC_DVLOG(1) << "Client processed " << iov.iov_len << " bytes for stream "
- << id();
- data_.append(static_cast<char*>(iov.iov_base), iov.iov_len);
-
- if (content_length_ >= 0 &&
- data_.size() > static_cast<uint64_t>(content_length_)) {
- QUIC_DLOG(ERROR) << "Invalid content length (" << content_length_
- << ") with data of size " << data_.size();
- Reset(QUIC_BAD_APPLICATION_PAYLOAD);
- return;
- }
- MarkConsumed(iov.iov_len);
- }
- if (sequencer()->IsClosed()) {
- OnFinRead();
- } else {
- sequencer()->SetUnblocked();
- }
-}
-
-size_t QuicSpdyClientStream::SendRequest(SpdyHeaderBlock headers,
- absl::string_view body,
- bool fin) {
- QuicConnection::ScopedPacketFlusher flusher(session_->connection());
- bool send_fin_with_headers = fin && body.empty();
- size_t bytes_sent = body.size();
- header_bytes_written_ =
- WriteHeaders(std::move(headers), send_fin_with_headers, nullptr);
- bytes_sent += header_bytes_written_;
-
- if (!body.empty()) {
- WriteOrBufferBody(body, fin);
- }
-
- return bytes_sent;
-}
-
-bool QuicSpdyClientStream::AreHeadersValid(
- const QuicHeaderList& header_list) const {
- if (!GetQuicReloadableFlag(quic_verify_request_headers_2)) {
- return true;
- }
- if (!QuicSpdyStream::AreHeadersValid(header_list)) {
- return false;
- }
- // Verify the presence of :status header.
- bool saw_status = false;
- for (const std::pair<std::string, std::string>& pair : header_list) {
- if (pair.first == ":status") {
- saw_status = true;
- } else if (absl::StrContains(pair.first, ":")) {
- QUIC_DLOG(ERROR) << "Unexpected ':' in header " << pair.first << ".";
- return false;
- }
- }
- return saw_status;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_client_stream.h b/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_client_stream.h
deleted file mode 100644
index 7d420f521e0..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_client_stream.h
+++ /dev/null
@@ -1,102 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_HTTP_QUIC_SPDY_CLIENT_STREAM_H_
-#define QUICHE_QUIC_CORE_HTTP_QUIC_SPDY_CLIENT_STREAM_H_
-
-#include <cstddef>
-#include <string>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/http/quic_spdy_stream.h"
-#include "quic/core/quic_packets.h"
-#include "spdy/core/spdy_framer.h"
-
-namespace quic {
-
-class QuicSpdyClientSession;
-
-// All this does right now is send an SPDY request, and aggregate the
-// SPDY response.
-class QUIC_EXPORT_PRIVATE QuicSpdyClientStream : public QuicSpdyStream {
- public:
- QuicSpdyClientStream(QuicStreamId id,
- QuicSpdyClientSession* session,
- StreamType type);
- QuicSpdyClientStream(PendingStream* pending,
- QuicSpdyClientSession* spdy_session);
- QuicSpdyClientStream(const QuicSpdyClientStream&) = delete;
- QuicSpdyClientStream& operator=(const QuicSpdyClientStream&) = delete;
- ~QuicSpdyClientStream() override;
-
- // Override the base class to parse and store headers.
- void OnInitialHeadersComplete(bool fin,
- size_t frame_len,
- const QuicHeaderList& header_list) override;
-
- // Override the base class to parse and store trailers.
- void OnTrailingHeadersComplete(bool fin,
- size_t frame_len,
- const QuicHeaderList& header_list) override;
-
- // Override the base class to handle creation of the push stream.
- void OnPromiseHeaderList(QuicStreamId promised_id,
- size_t frame_len,
- const QuicHeaderList& header_list) override;
-
- // QuicStream implementation called by the session when there's data for us.
- void OnBodyAvailable() override;
-
- // Serializes the headers and body, sends it to the server, and
- // returns the number of bytes sent.
- size_t SendRequest(spdy::SpdyHeaderBlock headers,
- absl::string_view body,
- bool fin);
-
- // Returns the response data.
- const std::string& data() { return data_; }
-
- // Returns whatever headers have been received for this stream.
- const spdy::SpdyHeaderBlock& response_headers() { return response_headers_; }
-
- const spdy::SpdyHeaderBlock& preliminary_headers() {
- return preliminary_headers_;
- }
-
- size_t header_bytes_read() const { return header_bytes_read_; }
-
- size_t header_bytes_written() const { return header_bytes_written_; }
-
- int response_code() const { return response_code_; }
-
- // While the server's SetPriority shouldn't be called externally, the creator
- // of client-side streams should be able to set the priority.
- using QuicSpdyStream::SetPriority;
-
- protected:
- bool AreHeadersValid(const QuicHeaderList& header_list) const override;
-
- private:
- // The parsed headers received from the server.
- spdy::SpdyHeaderBlock response_headers_;
-
- // The parsed content-length, or -1 if none is specified.
- int64_t content_length_;
- int response_code_;
- std::string data_;
- size_t header_bytes_read_;
- size_t header_bytes_written_;
-
- QuicSpdyClientSession* session_;
-
- // These preliminary headers are used for the 100 Continue headers
- // that may arrive before the response headers when the request has
- // Expect: 100-continue.
- bool has_preliminary_headers_;
- spdy::SpdyHeaderBlock preliminary_headers_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_HTTP_QUIC_SPDY_CLIENT_STREAM_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_client_stream_test.cc b/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_client_stream_test.cc
deleted file mode 100644
index 32a0c0c3876..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_client_stream_test.cc
+++ /dev/null
@@ -1,324 +0,0 @@
-// Copyright 2013 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 "quic/core/http/quic_spdy_client_stream.h"
-
-#include <memory>
-#include <string>
-#include <utility>
-
-#include "absl/strings/str_cat.h"
-#include "quic/core/crypto/null_encrypter.h"
-#include "quic/core/http/quic_spdy_client_session.h"
-#include "quic/core/http/spdy_utils.h"
-#include "quic/core/quic_simple_buffer_allocator.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/platform/api/quic_socket_address.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/crypto_test_utils.h"
-#include "quic/test_tools/quic_spdy_session_peer.h"
-#include "quic/test_tools/quic_test_utils.h"
-
-using spdy::SpdyHeaderBlock;
-using testing::_;
-using testing::StrictMock;
-
-namespace quic {
-namespace test {
-
-namespace {
-
-class MockQuicSpdyClientSession : public QuicSpdyClientSession {
- public:
- explicit MockQuicSpdyClientSession(
- const ParsedQuicVersionVector& supported_versions,
- QuicConnection* connection,
- QuicClientPushPromiseIndex* push_promise_index)
- : QuicSpdyClientSession(DefaultQuicConfig(),
- supported_versions,
- connection,
- QuicServerId("example.com", 443, false),
- &crypto_config_,
- push_promise_index),
- crypto_config_(crypto_test_utils::ProofVerifierForTesting()) {}
- MockQuicSpdyClientSession(const MockQuicSpdyClientSession&) = delete;
- MockQuicSpdyClientSession& operator=(const MockQuicSpdyClientSession&) =
- delete;
- ~MockQuicSpdyClientSession() override = default;
-
- MOCK_METHOD(bool,
- WriteControlFrame,
- (const QuicFrame& frame, TransmissionType type),
- (override));
-
- using QuicSession::ActivateStream;
-
- private:
- QuicCryptoClientConfig crypto_config_;
-};
-
-class QuicSpdyClientStreamTest : public QuicTestWithParam<ParsedQuicVersion> {
- public:
- class StreamVisitor;
-
- QuicSpdyClientStreamTest()
- : connection_(
- new StrictMock<MockQuicConnection>(&helper_,
- &alarm_factory_,
- Perspective::IS_CLIENT,
- SupportedVersions(GetParam()))),
- session_(connection_->supported_versions(),
- connection_,
- &push_promise_index_),
- body_("hello world") {
- session_.Initialize();
- connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
- connection_->SetEncrypter(
- ENCRYPTION_FORWARD_SECURE,
- std::make_unique<NullEncrypter>(connection_->perspective()));
- headers_[":status"] = "200";
- headers_["content-length"] = "11";
-
- auto stream = std::make_unique<QuicSpdyClientStream>(
- GetNthClientInitiatedBidirectionalStreamId(
- connection_->transport_version(), 0),
- &session_, BIDIRECTIONAL);
- stream_ = stream.get();
- session_.ActivateStream(std::move(stream));
-
- stream_visitor_ = std::make_unique<StreamVisitor>();
- stream_->set_visitor(stream_visitor_.get());
- }
-
- class StreamVisitor : public QuicSpdyClientStream::Visitor {
- void OnClose(QuicSpdyStream* stream) override {
- QUIC_DVLOG(1) << "stream " << stream->id();
- }
- };
-
- MockQuicConnectionHelper helper_;
- MockAlarmFactory alarm_factory_;
- StrictMock<MockQuicConnection>* connection_;
- QuicClientPushPromiseIndex push_promise_index_;
-
- MockQuicSpdyClientSession session_;
- QuicSpdyClientStream* stream_;
- std::unique_ptr<StreamVisitor> stream_visitor_;
- SpdyHeaderBlock headers_;
- std::string body_;
-};
-
-INSTANTIATE_TEST_SUITE_P(Tests,
- QuicSpdyClientStreamTest,
- ::testing::ValuesIn(AllSupportedVersions()),
- ::testing::PrintToStringParamName());
-
-TEST_P(QuicSpdyClientStreamTest, TestReceivingIllegalResponseStatusCode) {
- headers_[":status"] = "200 ok";
-
- EXPECT_CALL(session_, WriteControlFrame(_, _));
- EXPECT_CALL(*connection_,
- OnStreamReset(stream_->id(), QUIC_BAD_APPLICATION_PAYLOAD));
- auto headers = AsHeaderList(headers_);
- stream_->OnStreamHeaderList(false, headers.uncompressed_header_bytes(),
- headers);
- EXPECT_THAT(stream_->stream_error(),
- IsStreamError(QUIC_BAD_APPLICATION_PAYLOAD));
-}
-
-TEST_P(QuicSpdyClientStreamTest, InvalidResponseHeader) {
- SetQuicReloadableFlag(quic_verify_request_headers_2, true);
- SetQuicReloadableFlag(quic_act_upon_invalid_header, true);
- auto headers = AsHeaderList(std::vector<std::pair<std::string, std::string>>{
- {":status", "200"}, {":path", "/foo"}});
- EXPECT_CALL(*connection_,
- OnStreamReset(stream_->id(), QUIC_BAD_APPLICATION_PAYLOAD));
- stream_->OnStreamHeaderList(false, headers.uncompressed_header_bytes(),
- headers);
- EXPECT_THAT(stream_->stream_error(),
- IsStreamError(QUIC_BAD_APPLICATION_PAYLOAD));
-}
-
-TEST_P(QuicSpdyClientStreamTest, MissingStatusCode) {
- SetQuicReloadableFlag(quic_verify_request_headers_2, true);
- SetQuicReloadableFlag(quic_act_upon_invalid_header, true);
- auto headers = AsHeaderList(
- std::vector<std::pair<std::string, std::string>>{{"key", "value"}});
- EXPECT_CALL(*connection_,
- OnStreamReset(stream_->id(), QUIC_BAD_APPLICATION_PAYLOAD));
- stream_->OnStreamHeaderList(false, headers.uncompressed_header_bytes(),
- headers);
- EXPECT_THAT(stream_->stream_error(),
- IsStreamError(QUIC_BAD_APPLICATION_PAYLOAD));
-}
-
-TEST_P(QuicSpdyClientStreamTest, TestFraming) {
- auto headers = AsHeaderList(headers_);
- stream_->OnStreamHeaderList(false, headers.uncompressed_header_bytes(),
- headers);
- QuicBuffer header = HttpEncoder::SerializeDataFrameHeader(
- body_.length(), SimpleBufferAllocator::Get());
- std::string data = VersionUsesHttp3(connection_->transport_version())
- ? absl::StrCat(header.AsStringView(), body_)
- : body_;
- stream_->OnStreamFrame(
- QuicStreamFrame(stream_->id(), /*fin=*/false, /*offset=*/0, data));
- EXPECT_EQ("200", stream_->response_headers().find(":status")->second);
- EXPECT_EQ(200, stream_->response_code());
- EXPECT_EQ(body_, stream_->data());
-}
-
-TEST_P(QuicSpdyClientStreamTest, Test100ContinueBeforeSuccessful) {
- // First send 100 Continue.
- headers_[":status"] = "100";
- auto headers = AsHeaderList(headers_);
- stream_->OnStreamHeaderList(false, headers.uncompressed_header_bytes(),
- headers);
- EXPECT_EQ("100", stream_->preliminary_headers().find(":status")->second);
- EXPECT_EQ(0u, stream_->response_headers().size());
- EXPECT_EQ(100, stream_->response_code());
- EXPECT_EQ("", stream_->data());
- // Then send 200 OK.
- headers_[":status"] = "200";
- headers = AsHeaderList(headers_);
- stream_->OnStreamHeaderList(false, headers.uncompressed_header_bytes(),
- headers);
- QuicBuffer header = HttpEncoder::SerializeDataFrameHeader(
- body_.length(), SimpleBufferAllocator::Get());
- std::string data = VersionUsesHttp3(connection_->transport_version())
- ? absl::StrCat(header.AsStringView(), body_)
- : body_;
- stream_->OnStreamFrame(
- QuicStreamFrame(stream_->id(), /*fin=*/false, /*offset=*/0, data));
- // Make sure the 200 response got parsed correctly.
- EXPECT_EQ("200", stream_->response_headers().find(":status")->second);
- EXPECT_EQ(200, stream_->response_code());
- EXPECT_EQ(body_, stream_->data());
- // Make sure the 100 response is still available.
- EXPECT_EQ("100", stream_->preliminary_headers().find(":status")->second);
-}
-
-TEST_P(QuicSpdyClientStreamTest, TestUnknownInformationalBeforeSuccessful) {
- // First send 199, an unknown Informational (1XX).
- headers_[":status"] = "199";
- auto headers = AsHeaderList(headers_);
- stream_->OnStreamHeaderList(false, headers.uncompressed_header_bytes(),
- headers);
- EXPECT_EQ(0u, stream_->response_headers().size());
- EXPECT_EQ(199, stream_->response_code());
- EXPECT_EQ("", stream_->data());
- // Then send 200 OK.
- headers_[":status"] = "200";
- headers = AsHeaderList(headers_);
- stream_->OnStreamHeaderList(false, headers.uncompressed_header_bytes(),
- headers);
- QuicBuffer header = HttpEncoder::SerializeDataFrameHeader(
- body_.length(), SimpleBufferAllocator::Get());
- std::string data = VersionUsesHttp3(connection_->transport_version())
- ? absl::StrCat(header.AsStringView(), body_)
- : body_;
- stream_->OnStreamFrame(
- QuicStreamFrame(stream_->id(), /*fin=*/false, /*offset=*/0, data));
- // Make sure the 200 response got parsed correctly.
- EXPECT_EQ("200", stream_->response_headers().find(":status")->second);
- EXPECT_EQ(200, stream_->response_code());
- EXPECT_EQ(body_, stream_->data());
-}
-
-TEST_P(QuicSpdyClientStreamTest, TestReceiving101) {
- // 101 "Switching Protocols" is forbidden in HTTP/3 as per the
- // "HTTP Upgrade" section of draft-ietf-quic-http.
- headers_[":status"] = "101";
- EXPECT_CALL(session_, WriteControlFrame(_, _));
- EXPECT_CALL(*connection_,
- OnStreamReset(stream_->id(), QUIC_BAD_APPLICATION_PAYLOAD));
- auto headers = AsHeaderList(headers_);
- stream_->OnStreamHeaderList(false, headers.uncompressed_header_bytes(),
- headers);
- EXPECT_THAT(stream_->stream_error(),
- IsStreamError(QUIC_BAD_APPLICATION_PAYLOAD));
-}
-
-TEST_P(QuicSpdyClientStreamTest, TestFramingOnePacket) {
- auto headers = AsHeaderList(headers_);
- stream_->OnStreamHeaderList(false, headers.uncompressed_header_bytes(),
- headers);
- QuicBuffer header = HttpEncoder::SerializeDataFrameHeader(
- body_.length(), SimpleBufferAllocator::Get());
- std::string data = VersionUsesHttp3(connection_->transport_version())
- ? absl::StrCat(header.AsStringView(), body_)
- : body_;
- stream_->OnStreamFrame(
- QuicStreamFrame(stream_->id(), /*fin=*/false, /*offset=*/0, data));
- EXPECT_EQ("200", stream_->response_headers().find(":status")->second);
- EXPECT_EQ(200, stream_->response_code());
- EXPECT_EQ(body_, stream_->data());
-}
-
-TEST_P(QuicSpdyClientStreamTest,
- QUIC_TEST_DISABLED_IN_CHROME(TestFramingExtraData)) {
- std::string large_body = "hello world!!!!!!";
-
- auto headers = AsHeaderList(headers_);
- stream_->OnStreamHeaderList(false, headers.uncompressed_header_bytes(),
- headers);
- // The headers should parse successfully.
- EXPECT_THAT(stream_->stream_error(), IsQuicStreamNoError());
- EXPECT_EQ("200", stream_->response_headers().find(":status")->second);
- EXPECT_EQ(200, stream_->response_code());
- QuicBuffer header = HttpEncoder::SerializeDataFrameHeader(
- large_body.length(), SimpleBufferAllocator::Get());
- std::string data = VersionUsesHttp3(connection_->transport_version())
- ? absl::StrCat(header.AsStringView(), large_body)
- : large_body;
- EXPECT_CALL(session_, WriteControlFrame(_, _));
- EXPECT_CALL(*connection_,
- OnStreamReset(stream_->id(), QUIC_BAD_APPLICATION_PAYLOAD));
-
- stream_->OnStreamFrame(
- QuicStreamFrame(stream_->id(), /*fin=*/false, /*offset=*/0, data));
-
- EXPECT_NE(QUIC_STREAM_NO_ERROR, stream_->stream_error());
-}
-
-// Test that receiving trailing headers (on the headers stream), containing a
-// final offset, results in the stream being closed at that byte offset.
-TEST_P(QuicSpdyClientStreamTest, ReceivingTrailers) {
- // There is no kFinalOffsetHeaderKey if trailers are sent on the
- // request/response stream.
- if (VersionUsesHttp3(connection_->transport_version())) {
- return;
- }
-
- // Send headers as usual.
- auto headers = AsHeaderList(headers_);
- stream_->OnStreamHeaderList(false, headers.uncompressed_header_bytes(),
- headers);
-
- // Send trailers before sending the body. Even though a FIN has been received
- // the stream should not be closed, as it does not yet have all the data bytes
- // promised by the final offset field.
- SpdyHeaderBlock trailer_block;
- trailer_block["trailer key"] = "trailer value";
- trailer_block[kFinalOffsetHeaderKey] = absl::StrCat(body_.size());
- auto trailers = AsHeaderList(trailer_block);
- stream_->OnStreamHeaderList(true, trailers.uncompressed_header_bytes(),
- trailers);
-
- // Now send the body, which should close the stream as the FIN has been
- // received, as well as all data.
- QuicBuffer header = HttpEncoder::SerializeDataFrameHeader(
- body_.length(), SimpleBufferAllocator::Get());
- std::string data = VersionUsesHttp3(connection_->transport_version())
- ? absl::StrCat(header.AsStringView(), body_)
- : body_;
- stream_->OnStreamFrame(
- QuicStreamFrame(stream_->id(), /*fin=*/false, /*offset=*/0, data));
- EXPECT_TRUE(stream_->reading_stopped());
-}
-
-} // namespace
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_server_stream_base.cc b/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_server_stream_base.cc
deleted file mode 100644
index 8b57fb67230..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_server_stream_base.cc
+++ /dev/null
@@ -1,134 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/http/quic_spdy_server_stream_base.h"
-
-#include "absl/strings/string_view.h"
-#include "quic/core/http/quic_spdy_session.h"
-#include "quic/core/quic_error_codes.h"
-#include "quic/platform/api/quic_flag_utils.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-#include "common/quiche_text_utils.h"
-
-namespace quic {
-
-QuicSpdyServerStreamBase::QuicSpdyServerStreamBase(QuicStreamId id,
- QuicSpdySession* session,
- StreamType type)
- : QuicSpdyStream(id, session, type) {}
-
-QuicSpdyServerStreamBase::QuicSpdyServerStreamBase(PendingStream* pending,
- QuicSpdySession* session)
- : QuicSpdyStream(pending, session) {}
-
-void QuicSpdyServerStreamBase::CloseWriteSide() {
- if (!fin_received() && !rst_received() && sequencer()->ignore_read_data() &&
- !rst_sent()) {
- // Early cancel the stream if it has stopped reading before receiving FIN
- // or RST.
- QUICHE_DCHECK(fin_sent() || !session()->connection()->connected());
- // Tell the peer to stop sending further data.
- QUIC_DVLOG(1) << " Server: Send QUIC_STREAM_NO_ERROR on stream " << id();
- MaybeSendStopSending(QUIC_STREAM_NO_ERROR);
- }
-
- QuicSpdyStream::CloseWriteSide();
-}
-
-void QuicSpdyServerStreamBase::StopReading() {
- if (!fin_received() && !rst_received() && write_side_closed() &&
- !rst_sent()) {
- QUICHE_DCHECK(fin_sent());
- // Tell the peer to stop sending further data.
- QUIC_DVLOG(1) << " Server: Send QUIC_STREAM_NO_ERROR on stream " << id();
- MaybeSendStopSending(QUIC_STREAM_NO_ERROR);
- }
- QuicSpdyStream::StopReading();
-}
-
-bool QuicSpdyServerStreamBase::AreHeadersValid(
- const QuicHeaderList& header_list) const {
- if (!GetQuicReloadableFlag(quic_verify_request_headers_2)) {
- return true;
- }
- QUIC_RELOADABLE_FLAG_COUNT_N(quic_verify_request_headers_2, 2, 3);
- if (!QuicSpdyStream::AreHeadersValid(header_list)) {
- return false;
- }
-
- bool saw_connect = false;
- bool saw_protocol = false;
- bool saw_path = false;
- bool saw_scheme = false;
- bool saw_method = false;
- bool saw_authority = false;
- bool is_extended_connect = false;
- // Check if it is missing any required headers and if there is any disallowed
- // ones.
- for (const std::pair<std::string, std::string>& pair : header_list) {
- if (pair.first == ":method") {
- saw_method = true;
- if (pair.second == "CONNECT") {
- saw_connect = true;
- if (saw_protocol) {
- is_extended_connect = true;
- }
- }
- } else if (pair.first == ":protocol") {
- saw_protocol = true;
- if (saw_connect) {
- is_extended_connect = true;
- }
- } else if (pair.first == ":scheme") {
- saw_scheme = true;
- } else if (pair.first == ":path") {
- saw_path = true;
- } else if (pair.first == ":authority") {
- saw_authority = true;
- } else if (absl::StrContains(pair.first, ":")) {
- QUIC_DLOG(ERROR) << "Unexpected ':' in header " << pair.first << ".";
- return false;
- }
- if (is_extended_connect) {
- if (!spdy_session()->allow_extended_connect()) {
- QUIC_DLOG(ERROR)
- << "Received extended-CONNECT request while it is disabled.";
- return false;
- }
- } else if (saw_method && !saw_connect) {
- if (saw_protocol) {
- QUIC_DLOG(ERROR) << "Receive non-CONNECT request with :protocol.";
- return false;
- }
- }
- }
-
- if (is_extended_connect) {
- if (saw_scheme && saw_path && saw_authority) {
- // Saw all the required pseudo headers.
- return true;
- }
- QUIC_DLOG(ERROR) << "Missing required pseudo headers for extended-CONNECT.";
- return false;
- }
- // This is a vanilla CONNECT or non-CONNECT request.
- if (saw_connect) {
- // Check vanilla CONNECT.
- if (saw_path || saw_scheme) {
- QUIC_DLOG(ERROR)
- << "Received invalid CONNECT request with disallowed pseudo header.";
- return false;
- }
- return true;
- }
- // Check non-CONNECT request.
- if (saw_method && saw_authority && saw_path && saw_scheme) {
- return true;
- }
- QUIC_LOG(ERROR) << "Missing required pseudo headers.";
- return false;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_server_stream_base.h b/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_server_stream_base.h
deleted file mode 100644
index d10a6d49420..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_server_stream_base.h
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_HTTP_QUIC_SPDY_SERVER_STREAM_BASE_H_
-#define QUICHE_QUIC_CORE_HTTP_QUIC_SPDY_SERVER_STREAM_BASE_H_
-
-#include "quic/core/http/quic_spdy_stream.h"
-
-namespace quic {
-
-class QUIC_NO_EXPORT QuicSpdyServerStreamBase : public QuicSpdyStream {
- public:
- QuicSpdyServerStreamBase(QuicStreamId id,
- QuicSpdySession* session,
- StreamType type);
- QuicSpdyServerStreamBase(PendingStream* pending, QuicSpdySession* session);
- QuicSpdyServerStreamBase(const QuicSpdyServerStreamBase&) = delete;
- QuicSpdyServerStreamBase& operator=(const QuicSpdyServerStreamBase&) = delete;
-
- // Override the base class to send QUIC_STREAM_NO_ERROR to the peer
- // when the stream has not received all the data.
- void CloseWriteSide() override;
- void StopReading() override;
-
- protected:
- bool AreHeadersValid(const QuicHeaderList& header_list) const override;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_HTTP_QUIC_SPDY_SERVER_STREAM_BASE_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_server_stream_base_test.cc b/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_server_stream_base_test.cc
deleted file mode 100644
index ae227812cf2..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_server_stream_base_test.cc
+++ /dev/null
@@ -1,339 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/http/quic_spdy_server_stream_base.h"
-
-#include "absl/memory/memory.h"
-#include "quic/core/crypto/null_encrypter.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/qpack/qpack_encoder_test_utils.h"
-#include "quic/test_tools/quic_spdy_session_peer.h"
-#include "quic/test_tools/quic_stream_peer.h"
-#include "quic/test_tools/quic_test_utils.h"
-
-using testing::_;
-
-namespace quic {
-namespace test {
-namespace {
-
-class TestQuicSpdyServerStream : public QuicSpdyServerStreamBase {
- public:
- TestQuicSpdyServerStream(QuicStreamId id, QuicSpdySession* session,
- StreamType type)
- : QuicSpdyServerStreamBase(id, session, type) {}
-
- void OnBodyAvailable() override {}
-};
-
-class QuicSpdyServerStreamBaseTest : public QuicTest {
- protected:
- QuicSpdyServerStreamBaseTest()
- : session_(new MockQuicConnection(&helper_, &alarm_factory_,
- Perspective::IS_SERVER)) {
- session_.Initialize();
- session_.connection()->SetEncrypter(
- ENCRYPTION_FORWARD_SECURE,
- std::make_unique<NullEncrypter>(session_.perspective()));
- stream_ =
- new TestQuicSpdyServerStream(GetNthClientInitiatedBidirectionalStreamId(
- session_.transport_version(), 0),
- &session_, BIDIRECTIONAL);
- session_.ActivateStream(absl::WrapUnique(stream_));
- helper_.AdvanceTime(QuicTime::Delta::FromSeconds(1));
- }
-
- QuicSpdyServerStreamBase* stream_ = nullptr;
- MockQuicConnectionHelper helper_;
- MockAlarmFactory alarm_factory_;
- MockQuicSpdySession session_;
-};
-
-TEST_F(QuicSpdyServerStreamBaseTest,
- SendQuicRstStreamNoErrorWithEarlyResponse) {
- stream_->StopReading();
-
- if (session_.version().UsesHttp3()) {
- EXPECT_CALL(session_,
- MaybeSendStopSendingFrame(_, QuicResetStreamError::FromInternal(
- QUIC_STREAM_NO_ERROR)))
- .Times(1);
- } else {
- EXPECT_CALL(
- session_,
- MaybeSendRstStreamFrame(
- _, QuicResetStreamError::FromInternal(QUIC_STREAM_NO_ERROR), _))
- .Times(1);
- }
- QuicStreamPeer::SetFinSent(stream_);
- stream_->CloseWriteSide();
-}
-
-TEST_F(QuicSpdyServerStreamBaseTest,
- DoNotSendQuicRstStreamNoErrorWithRstReceived) {
- EXPECT_FALSE(stream_->reading_stopped());
-
- EXPECT_CALL(session_,
- MaybeSendRstStreamFrame(
- _,
- QuicResetStreamError::FromInternal(
- VersionHasIetfQuicFrames(session_.transport_version())
- ? QUIC_STREAM_CANCELLED
- : QUIC_RST_ACKNOWLEDGEMENT),
- _))
- .Times(1);
- QuicRstStreamFrame rst_frame(kInvalidControlFrameId, stream_->id(),
- QUIC_STREAM_CANCELLED, 1234);
- stream_->OnStreamReset(rst_frame);
- if (VersionHasIetfQuicFrames(session_.transport_version())) {
- // Create and inject a STOP SENDING frame to complete the close
- // of the stream. This is only needed for version 99/IETF QUIC.
- QuicStopSendingFrame stop_sending(kInvalidControlFrameId, stream_->id(),
- QUIC_STREAM_CANCELLED);
- session_.OnStopSendingFrame(stop_sending);
- }
-
- EXPECT_TRUE(stream_->reading_stopped());
- EXPECT_TRUE(stream_->write_side_closed());
-}
-
-TEST_F(QuicSpdyServerStreamBaseTest, AllowExtendedConnect) {
- QuicHeaderList header_list;
- header_list.OnHeaderBlockStart();
- header_list.OnHeader(":authority", "www.google.com:4433");
- header_list.OnHeader(":method", "CONNECT");
- header_list.OnHeader(":protocol", "webtransport");
- header_list.OnHeader(":path", "/path");
- header_list.OnHeader(":scheme", "http");
- header_list.OnHeaderBlockEnd(128, 128);
- stream_->OnStreamHeaderList(/*fin=*/false, 0, header_list);
- EXPECT_EQ(GetQuicReloadableFlag(quic_verify_request_headers_2) &&
- GetQuicReloadableFlag(quic_act_upon_invalid_header) &&
- !session_.allow_extended_connect(),
- stream_->rst_sent());
-}
-
-TEST_F(QuicSpdyServerStreamBaseTest, AllowExtendedConnectProtocolFirst) {
- QuicHeaderList header_list;
- header_list.OnHeaderBlockStart();
- header_list.OnHeader(":protocol", "webtransport");
- header_list.OnHeader(":authority", "www.google.com:4433");
- header_list.OnHeader(":method", "CONNECT");
- header_list.OnHeader(":path", "/path");
- header_list.OnHeader(":scheme", "http");
- header_list.OnHeaderBlockEnd(128, 128);
- stream_->OnStreamHeaderList(/*fin=*/false, 0, header_list);
- EXPECT_EQ(GetQuicReloadableFlag(quic_verify_request_headers_2) &&
- GetQuicReloadableFlag(quic_act_upon_invalid_header) &&
- !session_.allow_extended_connect(),
- stream_->rst_sent());
-}
-
-TEST_F(QuicSpdyServerStreamBaseTest, InvalidExtendedConnect) {
- if (!session_.version().UsesHttp3()) {
- return;
- }
- SetQuicReloadableFlag(quic_verify_request_headers_2, true);
- SetQuicReloadableFlag(quic_act_upon_invalid_header, true);
- QuicHeaderList header_list;
- header_list.OnHeaderBlockStart();
- header_list.OnHeader(":authority", "www.google.com:4433");
- header_list.OnHeader(":method", "CONNECT");
- header_list.OnHeader(":protocol", "webtransport");
- header_list.OnHeader(":scheme", "http");
- header_list.OnHeaderBlockEnd(128, 128);
-
- EXPECT_CALL(
- session_,
- MaybeSendRstStreamFrame(
- _, QuicResetStreamError::FromInternal(QUIC_BAD_APPLICATION_PAYLOAD),
- _));
- stream_->OnStreamHeaderList(/*fin=*/false, 0, header_list);
- EXPECT_TRUE(stream_->rst_sent());
-}
-
-TEST_F(QuicSpdyServerStreamBaseTest, VanillaConnectAllowed) {
- 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, 0, header_list);
- EXPECT_FALSE(stream_->rst_sent());
-}
-
-TEST_F(QuicSpdyServerStreamBaseTest, InvalidVanillaConnect) {
- SetQuicReloadableFlag(quic_verify_request_headers_2, true);
- SetQuicReloadableFlag(quic_act_upon_invalid_header, true);
- QuicHeaderList header_list;
- header_list.OnHeaderBlockStart();
- header_list.OnHeader(":authority", "www.google.com:4433");
- header_list.OnHeader(":method", "CONNECT");
- header_list.OnHeader(":scheme", "http");
- header_list.OnHeaderBlockEnd(128, 128);
-
- EXPECT_CALL(
- session_,
- MaybeSendRstStreamFrame(
- _, QuicResetStreamError::FromInternal(QUIC_BAD_APPLICATION_PAYLOAD),
- _));
- stream_->OnStreamHeaderList(/*fin=*/false, 0, header_list);
- EXPECT_TRUE(stream_->rst_sent());
-}
-
-TEST_F(QuicSpdyServerStreamBaseTest, InvalidNonConnectWithProtocol) {
- SetQuicReloadableFlag(quic_verify_request_headers_2, true);
- SetQuicReloadableFlag(quic_act_upon_invalid_header, true);
- QuicHeaderList header_list;
- header_list.OnHeaderBlockStart();
- header_list.OnHeader(":authority", "www.google.com:4433");
- header_list.OnHeader(":method", "GET");
- header_list.OnHeader(":scheme", "http");
- header_list.OnHeader(":path", "/path");
- header_list.OnHeader(":protocol", "webtransport");
- header_list.OnHeaderBlockEnd(128, 128);
-
- EXPECT_CALL(
- session_,
- MaybeSendRstStreamFrame(
- _, QuicResetStreamError::FromInternal(QUIC_BAD_APPLICATION_PAYLOAD),
- _));
- stream_->OnStreamHeaderList(/*fin=*/false, 0, header_list);
- EXPECT_TRUE(stream_->rst_sent());
-}
-
-TEST_F(QuicSpdyServerStreamBaseTest, InvalidRequestWithoutScheme) {
- SetQuicReloadableFlag(quic_verify_request_headers_2, true);
- SetQuicReloadableFlag(quic_act_upon_invalid_header, true);
- // A request without :scheme should be rejected.
- QuicHeaderList header_list;
- header_list.OnHeaderBlockStart();
- header_list.OnHeader(":authority", "www.google.com:4433");
- header_list.OnHeader(":method", "GET");
- header_list.OnHeader(":path", "/path");
- header_list.OnHeaderBlockEnd(128, 128);
-
- EXPECT_CALL(
- session_,
- MaybeSendRstStreamFrame(
- _, QuicResetStreamError::FromInternal(QUIC_BAD_APPLICATION_PAYLOAD),
- _));
- stream_->OnStreamHeaderList(/*fin=*/false, 0, header_list);
- EXPECT_TRUE(stream_->rst_sent());
-}
-
-TEST_F(QuicSpdyServerStreamBaseTest, InvalidRequestWithoutAuthority) {
- SetQuicReloadableFlag(quic_verify_request_headers_2, true);
- SetQuicReloadableFlag(quic_act_upon_invalid_header, true);
- // A request without :authority should be rejected.
- QuicHeaderList header_list;
- header_list.OnHeaderBlockStart();
- header_list.OnHeader(":scheme", "http");
- header_list.OnHeader(":method", "GET");
- header_list.OnHeader(":path", "/path");
- header_list.OnHeaderBlockEnd(128, 128);
-
- EXPECT_CALL(
- session_,
- MaybeSendRstStreamFrame(
- _, QuicResetStreamError::FromInternal(QUIC_BAD_APPLICATION_PAYLOAD),
- _));
- stream_->OnStreamHeaderList(/*fin=*/false, 0, header_list);
- EXPECT_TRUE(stream_->rst_sent());
-}
-
-TEST_F(QuicSpdyServerStreamBaseTest, InvalidRequestWithoutMethod) {
- SetQuicReloadableFlag(quic_verify_request_headers_2, true);
- SetQuicReloadableFlag(quic_act_upon_invalid_header, true);
- // A request without :method should be rejected.
- QuicHeaderList header_list;
- header_list.OnHeaderBlockStart();
- header_list.OnHeader(":authority", "www.google.com:4433");
- header_list.OnHeader(":scheme", "http");
- header_list.OnHeader(":path", "/path");
- header_list.OnHeaderBlockEnd(128, 128);
-
- EXPECT_CALL(
- session_,
- MaybeSendRstStreamFrame(
- _, QuicResetStreamError::FromInternal(QUIC_BAD_APPLICATION_PAYLOAD),
- _));
- stream_->OnStreamHeaderList(/*fin=*/false, 0, header_list);
- EXPECT_TRUE(stream_->rst_sent());
-}
-
-TEST_F(QuicSpdyServerStreamBaseTest, InvalidRequestWithoutPath) {
- SetQuicReloadableFlag(quic_verify_request_headers_2, true);
- SetQuicReloadableFlag(quic_act_upon_invalid_header, true);
- // A request without :path should be rejected.
- QuicHeaderList header_list;
- header_list.OnHeaderBlockStart();
- header_list.OnHeader(":authority", "www.google.com:4433");
- header_list.OnHeader(":scheme", "http");
- header_list.OnHeader(":method", "POST");
- header_list.OnHeaderBlockEnd(128, 128);
-
- EXPECT_CALL(
- session_,
- MaybeSendRstStreamFrame(
- _, QuicResetStreamError::FromInternal(QUIC_BAD_APPLICATION_PAYLOAD),
- _));
- stream_->OnStreamHeaderList(/*fin=*/false, 0, header_list);
- EXPECT_TRUE(stream_->rst_sent());
-}
-
-TEST_F(QuicSpdyServerStreamBaseTest, InvalidRequestHeader) {
- SetQuicReloadableFlag(quic_verify_request_headers_2, true);
- SetQuicReloadableFlag(quic_act_upon_invalid_header, true);
- // A request without :path should be rejected.
- QuicHeaderList header_list;
- header_list.OnHeaderBlockStart();
- header_list.OnHeader(":authority", "www.google.com:4433");
- header_list.OnHeader(":scheme", "http");
- header_list.OnHeader(":method", "POST");
- header_list.OnHeader("invalid:header", "value");
- header_list.OnHeaderBlockEnd(128, 128);
-
- EXPECT_CALL(
- session_,
- MaybeSendRstStreamFrame(
- _, QuicResetStreamError::FromInternal(QUIC_BAD_APPLICATION_PAYLOAD),
- _));
- stream_->OnStreamHeaderList(/*fin=*/false, 0, header_list);
- EXPECT_TRUE(stream_->rst_sent());
-}
-
-TEST_F(QuicSpdyServerStreamBaseTest, EmptyHeaders) {
- SetQuicReloadableFlag(quic_verify_request_headers_2, true);
- SetQuicReloadableFlag(quic_act_upon_invalid_header, true);
- spdy::SpdyHeaderBlock empty_header;
- quic::test::NoopQpackStreamSenderDelegate encoder_stream_sender_delegate;
- quic::test::NoopDecoderStreamErrorDelegate decoder_stream_error_delegate;
- auto qpack_encoder =
- std::make_unique<quic::QpackEncoder>(&decoder_stream_error_delegate);
- qpack_encoder->set_qpack_stream_sender_delegate(
- &encoder_stream_sender_delegate);
- std::string payload =
- qpack_encoder->EncodeHeaderList(stream_->id(), empty_header, nullptr);
- std::unique_ptr<char[]> headers_buffer;
- quic::QuicByteCount headers_frame_header_length =
- quic::HttpEncoder::SerializeHeadersFrameHeader(payload.length(),
- &headers_buffer);
- absl::string_view headers_frame_header(headers_buffer.get(),
- headers_frame_header_length);
-
- EXPECT_CALL(
- session_,
- MaybeSendRstStreamFrame(
- _, QuicResetStreamError::FromInternal(QUIC_BAD_APPLICATION_PAYLOAD),
- _));
- stream_->OnStreamFrame(QuicStreamFrame(
- stream_->id(), true, 0, absl::StrCat(headers_frame_header, payload)));
- EXPECT_TRUE(stream_->rst_sent());
-}
-
-} // namespace
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_session.cc b/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_session.cc
deleted file mode 100644
index cfc47296417..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_session.cc
+++ /dev/null
@@ -1,1943 +0,0 @@
-// Copyright (c) 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/http/quic_spdy_session.h"
-
-#include <algorithm>
-#include <cstdint>
-#include <limits>
-#include <memory>
-#include <string>
-#include <utility>
-
-#include "absl/base/attributes.h"
-#include "absl/strings/numbers.h"
-#include "absl/strings/str_cat.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/http/http_constants.h"
-#include "quic/core/http/http_decoder.h"
-#include "quic/core/http/http_frames.h"
-#include "quic/core/http/quic_headers_stream.h"
-#include "quic/core/http/web_transport_http3.h"
-#include "quic/core/quic_error_codes.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_utils.h"
-#include "quic/core/quic_versions.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_exported_stats.h"
-#include "quic/platform/api/quic_flag_utils.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/platform/api/quic_stack_trace.h"
-#include "spdy/core/http2_frame_decoder_adapter.h"
-
-using http2::Http2DecoderAdapter;
-using spdy::Http2WeightToSpdy3Priority;
-using spdy::Spdy3PriorityToHttp2Weight;
-using spdy::SpdyErrorCode;
-using spdy::SpdyFramer;
-using spdy::SpdyFramerDebugVisitorInterface;
-using spdy::SpdyFramerVisitorInterface;
-using spdy::SpdyFrameType;
-using spdy::SpdyHeaderBlock;
-using spdy::SpdyHeadersHandlerInterface;
-using spdy::SpdyHeadersIR;
-using spdy::SpdyPingId;
-using spdy::SpdyPriority;
-using spdy::SpdyPriorityIR;
-using spdy::SpdyPushPromiseIR;
-using spdy::SpdySerializedFrame;
-using spdy::SpdySettingsId;
-using spdy::SpdyStreamId;
-
-namespace quic {
-
-ABSL_CONST_INIT const size_t kMaxUnassociatedWebTransportStreams = 24;
-
-namespace {
-
-#define ENDPOINT \
- (perspective() == Perspective::IS_SERVER ? "Server: " : "Client: ")
-
-// Class to forward ACCEPT_CH frame to QuicSpdySession,
-// and ignore every other frame.
-class AlpsFrameDecoder : public HttpDecoder::Visitor {
- public:
- explicit AlpsFrameDecoder(QuicSpdySession* session) : session_(session) {}
- ~AlpsFrameDecoder() override = default;
-
- // HttpDecoder::Visitor implementation.
- void OnError(HttpDecoder* /*decoder*/) override {}
- bool OnMaxPushIdFrame(const MaxPushIdFrame& /*frame*/) override {
- error_detail_ = "MAX_PUSH_ID frame forbidden";
- return false;
- }
- bool OnGoAwayFrame(const GoAwayFrame& /*frame*/) override {
- error_detail_ = "GOAWAY frame forbidden";
- return false;
- }
- bool OnSettingsFrameStart(QuicByteCount /*header_length*/) override {
- return true;
- }
- bool OnSettingsFrame(const SettingsFrame& frame) override {
- if (settings_frame_received_via_alps_) {
- error_detail_ = "multiple SETTINGS frames";
- return false;
- }
-
- settings_frame_received_via_alps_ = true;
-
- error_detail_ = session_->OnSettingsFrameViaAlps(frame);
- return !error_detail_;
- }
- bool OnDataFrameStart(QuicByteCount /*header_length*/, QuicByteCount
- /*payload_length*/) override {
- error_detail_ = "DATA frame forbidden";
- return false;
- }
- bool OnDataFramePayload(absl::string_view /*payload*/) override {
- QUICHE_NOTREACHED();
- return false;
- }
- bool OnDataFrameEnd() override {
- QUICHE_NOTREACHED();
- return false;
- }
- bool OnHeadersFrameStart(QuicByteCount /*header_length*/,
- QuicByteCount /*payload_length*/) override {
- error_detail_ = "HEADERS frame forbidden";
- return false;
- }
- bool OnHeadersFramePayload(absl::string_view /*payload*/) override {
- QUICHE_NOTREACHED();
- return false;
- }
- bool OnHeadersFrameEnd() override {
- QUICHE_NOTREACHED();
- return false;
- }
- bool OnPriorityUpdateFrameStart(QuicByteCount /*header_length*/) override {
- error_detail_ = "PRIORITY_UPDATE frame forbidden";
- return false;
- }
- bool OnPriorityUpdateFrame(const PriorityUpdateFrame& /*frame*/) override {
- QUICHE_NOTREACHED();
- return false;
- }
- bool OnAcceptChFrameStart(QuicByteCount /*header_length*/) override {
- return true;
- }
- bool OnAcceptChFrame(const AcceptChFrame& frame) override {
- session_->OnAcceptChFrameReceivedViaAlps(frame);
- return true;
- }
- void OnWebTransportStreamFrameType(
- QuicByteCount /*header_length*/,
- WebTransportSessionId /*session_id*/) override {
- QUICHE_NOTREACHED();
- }
- bool OnUnknownFrameStart(uint64_t /*frame_type*/,
- QuicByteCount
- /*header_length*/,
- QuicByteCount /*payload_length*/) override {
- return true;
- }
- bool OnUnknownFramePayload(absl::string_view /*payload*/) override {
- return true;
- }
- bool OnUnknownFrameEnd() override { return true; }
-
- const absl::optional<std::string>& error_detail() const {
- return error_detail_;
- }
-
- private:
- QuicSpdySession* const session_;
- absl::optional<std::string> error_detail_;
-
- // True if SETTINGS frame has been received via ALPS.
- bool settings_frame_received_via_alps_ = false;
-};
-
-} // namespace
-
-// A SpdyFramerVisitor that passes HEADERS frames to the QuicSpdyStream, and
-// closes the connection if any unexpected frames are received.
-class QuicSpdySession::SpdyFramerVisitor
- : public SpdyFramerVisitorInterface,
- public SpdyFramerDebugVisitorInterface {
- public:
- explicit SpdyFramerVisitor(QuicSpdySession* session) : session_(session) {}
- SpdyFramerVisitor(const SpdyFramerVisitor&) = delete;
- SpdyFramerVisitor& operator=(const SpdyFramerVisitor&) = delete;
-
- SpdyHeadersHandlerInterface* OnHeaderFrameStart(
- SpdyStreamId /* stream_id */) override {
- QUICHE_DCHECK(!VersionUsesHttp3(session_->transport_version()));
- return &header_list_;
- }
-
- void OnHeaderFrameEnd(SpdyStreamId /* stream_id */) override {
- QUICHE_DCHECK(!VersionUsesHttp3(session_->transport_version()));
-
- LogHeaderCompressionRatioHistogram(
- /* using_qpack = */ false,
- /* is_sent = */ false, header_list_.compressed_header_bytes(),
- header_list_.uncompressed_header_bytes());
-
- if (session_->IsConnected()) {
- session_->OnHeaderList(header_list_);
- }
- header_list_.Clear();
- }
-
- void OnStreamFrameData(SpdyStreamId /*stream_id*/, const char* /*data*/,
- size_t /*len*/) override {
- QUICHE_DCHECK(!VersionUsesHttp3(session_->transport_version()));
- CloseConnection("SPDY DATA frame received.",
- QUIC_INVALID_HEADERS_STREAM_DATA);
- }
-
- void OnStreamEnd(SpdyStreamId /*stream_id*/) override {
- // The framer invokes OnStreamEnd after processing a frame that had the fin
- // bit set.
- }
-
- void OnStreamPadding(SpdyStreamId /*stream_id*/, size_t /*len*/) override {
- CloseConnection("SPDY frame padding received.",
- QUIC_INVALID_HEADERS_STREAM_DATA);
- }
-
- void OnError(Http2DecoderAdapter::SpdyFramerError error,
- std::string detailed_error) override {
- QuicErrorCode code;
- switch (error) {
- case Http2DecoderAdapter::SpdyFramerError::SPDY_HPACK_INDEX_VARINT_ERROR:
- code = QUIC_HPACK_INDEX_VARINT_ERROR;
- break;
- case Http2DecoderAdapter::SpdyFramerError::
- SPDY_HPACK_NAME_LENGTH_VARINT_ERROR:
- code = QUIC_HPACK_NAME_LENGTH_VARINT_ERROR;
- break;
- case Http2DecoderAdapter::SpdyFramerError::
- SPDY_HPACK_VALUE_LENGTH_VARINT_ERROR:
- code = QUIC_HPACK_VALUE_LENGTH_VARINT_ERROR;
- break;
- case Http2DecoderAdapter::SpdyFramerError::SPDY_HPACK_NAME_TOO_LONG:
- code = QUIC_HPACK_NAME_TOO_LONG;
- break;
- case Http2DecoderAdapter::SpdyFramerError::SPDY_HPACK_VALUE_TOO_LONG:
- code = QUIC_HPACK_VALUE_TOO_LONG;
- break;
- case Http2DecoderAdapter::SpdyFramerError::SPDY_HPACK_NAME_HUFFMAN_ERROR:
- code = QUIC_HPACK_NAME_HUFFMAN_ERROR;
- break;
- case Http2DecoderAdapter::SpdyFramerError::SPDY_HPACK_VALUE_HUFFMAN_ERROR:
- code = QUIC_HPACK_VALUE_HUFFMAN_ERROR;
- break;
- case Http2DecoderAdapter::SpdyFramerError::
- SPDY_HPACK_MISSING_DYNAMIC_TABLE_SIZE_UPDATE:
- code = QUIC_HPACK_MISSING_DYNAMIC_TABLE_SIZE_UPDATE;
- break;
- case Http2DecoderAdapter::SpdyFramerError::SPDY_HPACK_INVALID_INDEX:
- code = QUIC_HPACK_INVALID_INDEX;
- break;
- case Http2DecoderAdapter::SpdyFramerError::SPDY_HPACK_INVALID_NAME_INDEX:
- code = QUIC_HPACK_INVALID_NAME_INDEX;
- break;
- case Http2DecoderAdapter::SpdyFramerError::
- SPDY_HPACK_DYNAMIC_TABLE_SIZE_UPDATE_NOT_ALLOWED:
- code = QUIC_HPACK_DYNAMIC_TABLE_SIZE_UPDATE_NOT_ALLOWED;
- break;
- case Http2DecoderAdapter::SpdyFramerError::
- SPDY_HPACK_INITIAL_DYNAMIC_TABLE_SIZE_UPDATE_IS_ABOVE_LOW_WATER_MARK:
- code = QUIC_HPACK_INITIAL_TABLE_SIZE_UPDATE_IS_ABOVE_LOW_WATER_MARK;
- break;
- case Http2DecoderAdapter::SpdyFramerError::
- SPDY_HPACK_DYNAMIC_TABLE_SIZE_UPDATE_IS_ABOVE_ACKNOWLEDGED_SETTING:
- code = QUIC_HPACK_TABLE_SIZE_UPDATE_IS_ABOVE_ACKNOWLEDGED_SETTING;
- break;
- case Http2DecoderAdapter::SpdyFramerError::SPDY_HPACK_TRUNCATED_BLOCK:
- code = QUIC_HPACK_TRUNCATED_BLOCK;
- break;
- case Http2DecoderAdapter::SpdyFramerError::SPDY_HPACK_FRAGMENT_TOO_LONG:
- code = QUIC_HPACK_FRAGMENT_TOO_LONG;
- break;
- case Http2DecoderAdapter::SpdyFramerError::
- SPDY_HPACK_COMPRESSED_HEADER_SIZE_EXCEEDS_LIMIT:
- code = QUIC_HPACK_COMPRESSED_HEADER_SIZE_EXCEEDS_LIMIT;
- break;
- case Http2DecoderAdapter::SpdyFramerError::SPDY_DECOMPRESS_FAILURE:
- code = QUIC_HEADERS_STREAM_DATA_DECOMPRESS_FAILURE;
- break;
- default:
- code = QUIC_INVALID_HEADERS_STREAM_DATA;
- }
- CloseConnection(
- absl::StrCat("SPDY framing error: ", detailed_error,
- Http2DecoderAdapter::SpdyFramerErrorToString(error)),
- code);
- }
-
- void OnDataFrameHeader(SpdyStreamId /*stream_id*/, size_t /*length*/,
- bool /*fin*/) override {
- QUICHE_DCHECK(!VersionUsesHttp3(session_->transport_version()));
- CloseConnection("SPDY DATA frame received.",
- QUIC_INVALID_HEADERS_STREAM_DATA);
- }
-
- void OnRstStream(SpdyStreamId /*stream_id*/,
- SpdyErrorCode /*error_code*/) override {
- CloseConnection("SPDY RST_STREAM frame received.",
- QUIC_INVALID_HEADERS_STREAM_DATA);
- }
-
- void OnSetting(SpdySettingsId id, uint32_t value) override {
- QUICHE_DCHECK(!VersionUsesHttp3(session_->transport_version()));
- session_->OnSetting(id, value);
- }
-
- void OnSettingsEnd() override {
- QUICHE_DCHECK(!VersionUsesHttp3(session_->transport_version()));
- }
-
- void OnPing(SpdyPingId /*unique_id*/, bool /*is_ack*/) override {
- CloseConnection("SPDY PING frame received.",
- QUIC_INVALID_HEADERS_STREAM_DATA);
- }
-
- void OnGoAway(SpdyStreamId /*last_accepted_stream_id*/,
- SpdyErrorCode /*error_code*/) override {
- CloseConnection("SPDY GOAWAY frame received.",
- QUIC_INVALID_HEADERS_STREAM_DATA);
- }
-
- void OnHeaders(SpdyStreamId stream_id, bool has_priority, int weight,
- SpdyStreamId /* parent_stream_id */, bool /* exclusive */,
- bool fin, bool /*end*/) override {
- if (!session_->IsConnected()) {
- return;
- }
-
- if (VersionUsesHttp3(session_->transport_version())) {
- CloseConnection("HEADERS frame not allowed on headers stream.",
- QUIC_INVALID_HEADERS_STREAM_DATA);
- return;
- }
-
- QUIC_BUG_IF(quic_bug_12477_1,
- session_->destruction_indicator() != 123456789)
- << "QuicSpdyStream use after free. "
- << session_->destruction_indicator() << QuicStackTrace();
-
- SpdyPriority priority =
- has_priority ? Http2WeightToSpdy3Priority(weight) : 0;
- session_->OnHeaders(stream_id, has_priority,
- spdy::SpdyStreamPrecedence(priority), fin);
- }
-
- void OnWindowUpdate(SpdyStreamId /*stream_id*/,
- int /*delta_window_size*/) override {
- CloseConnection("SPDY WINDOW_UPDATE frame received.",
- QUIC_INVALID_HEADERS_STREAM_DATA);
- }
-
- void OnPushPromise(SpdyStreamId stream_id, SpdyStreamId promised_stream_id,
- bool /*end*/) override {
- QUICHE_DCHECK(!VersionUsesHttp3(session_->transport_version()));
- if (session_->perspective() != Perspective::IS_CLIENT) {
- CloseConnection("PUSH_PROMISE not supported.",
- QUIC_INVALID_HEADERS_STREAM_DATA);
- return;
- }
- if (!session_->IsConnected()) {
- return;
- }
- session_->OnPushPromise(stream_id, promised_stream_id);
- }
-
- void OnContinuation(SpdyStreamId /*stream_id*/, bool /*end*/) override {}
-
- void OnPriority(SpdyStreamId stream_id, SpdyStreamId /* parent_id */,
- int weight, bool /* exclusive */) override {
- QUICHE_DCHECK(!VersionUsesHttp3(session_->transport_version()));
- if (!session_->IsConnected()) {
- return;
- }
- SpdyPriority priority = Http2WeightToSpdy3Priority(weight);
- session_->OnPriority(stream_id, spdy::SpdyStreamPrecedence(priority));
- }
-
- void OnPriorityUpdate(SpdyStreamId /*prioritized_stream_id*/,
- absl::string_view /*priority_field_value*/) override {
- // TODO(b/171470299): Parse and call
- // QuicSpdySession::OnPriorityUpdateForRequestStream().
- }
-
- bool OnUnknownFrame(SpdyStreamId /*stream_id*/,
- uint8_t /*frame_type*/) override {
- CloseConnection("Unknown frame type received.",
- QUIC_INVALID_HEADERS_STREAM_DATA);
- return false;
- }
-
- // SpdyFramerDebugVisitorInterface implementation
- void OnSendCompressedFrame(SpdyStreamId /*stream_id*/, SpdyFrameType /*type*/,
- size_t payload_len, size_t frame_len) override {
- if (payload_len == 0) {
- QUIC_BUG(quic_bug_10360_1) << "Zero payload length.";
- return;
- }
- int compression_pct = 100 - (100 * frame_len) / payload_len;
- QUIC_DVLOG(1) << "Net.QuicHpackCompressionPercentage: " << compression_pct;
- }
-
- void OnReceiveCompressedFrame(SpdyStreamId /*stream_id*/,
- SpdyFrameType /*type*/,
- size_t frame_len) override {
- if (session_->IsConnected()) {
- session_->OnCompressedFrameSize(frame_len);
- }
- }
-
- void set_max_header_list_size(size_t max_header_list_size) {
- header_list_.set_max_header_list_size(max_header_list_size);
- }
-
- private:
- void CloseConnection(const std::string& details, QuicErrorCode code) {
- if (session_->IsConnected()) {
- session_->CloseConnectionWithDetails(code, details);
- }
- }
-
- QuicSpdySession* session_;
- QuicHeaderList header_list_;
-};
-
-Http3DebugVisitor::Http3DebugVisitor() {}
-
-Http3DebugVisitor::~Http3DebugVisitor() {}
-
-// Expected unidirectional static streams Requirement can be found at
-// https://tools.ietf.org/html/draft-ietf-quic-http-22#section-6.2.
-QuicSpdySession::QuicSpdySession(
- QuicConnection* connection, QuicSession::Visitor* visitor,
- const QuicConfig& config, const ParsedQuicVersionVector& supported_versions)
- : QuicSession(connection, visitor, config, supported_versions,
- /*num_expected_unidirectional_static_streams = */
- VersionUsesHttp3(connection->transport_version())
- ? static_cast<QuicStreamCount>(
- kHttp3StaticUnidirectionalStreamCount)
- : 0u,
- std::make_unique<DatagramObserver>(this)),
- send_control_stream_(nullptr),
- receive_control_stream_(nullptr),
- qpack_encoder_receive_stream_(nullptr),
- qpack_decoder_receive_stream_(nullptr),
- qpack_encoder_send_stream_(nullptr),
- qpack_decoder_send_stream_(nullptr),
- qpack_maximum_dynamic_table_capacity_(
- kDefaultQpackMaxDynamicTableCapacity),
- qpack_maximum_blocked_streams_(kDefaultMaximumBlockedStreams),
- max_inbound_header_list_size_(kDefaultMaxUncompressedHeaderSize),
- max_outbound_header_list_size_(std::numeric_limits<size_t>::max()),
- stream_id_(
- QuicUtils::GetInvalidStreamId(connection->transport_version())),
- promised_stream_id_(
- QuicUtils::GetInvalidStreamId(connection->transport_version())),
- frame_len_(0),
- fin_(false),
- spdy_framer_(SpdyFramer::ENABLE_COMPRESSION),
- spdy_framer_visitor_(new SpdyFramerVisitor(this)),
- debug_visitor_(nullptr),
- destruction_indicator_(123456789),
- allow_extended_connect_(
- GetQuicReloadableFlag(quic_verify_request_headers_2) &&
- perspective() == Perspective::IS_SERVER &&
- VersionUsesHttp3(transport_version())) {
- h2_deframer_.set_visitor(spdy_framer_visitor_.get());
- h2_deframer_.set_debug_visitor(spdy_framer_visitor_.get());
- spdy_framer_.set_debug_visitor(spdy_framer_visitor_.get());
-}
-
-QuicSpdySession::~QuicSpdySession() {
- QUIC_BUG_IF(quic_bug_12477_2, destruction_indicator_ != 123456789)
- << "QuicSpdySession use after free. " << destruction_indicator_
- << QuicStackTrace();
- destruction_indicator_ = 987654321;
-}
-
-void QuicSpdySession::Initialize() {
- QuicSession::Initialize();
-
- FillSettingsFrame();
- if (!VersionUsesHttp3(transport_version())) {
- if (perspective() == Perspective::IS_SERVER) {
- set_largest_peer_created_stream_id(
- QuicUtils::GetHeadersStreamId(transport_version()));
- } else {
- QuicStreamId headers_stream_id = GetNextOutgoingBidirectionalStreamId();
- QUICHE_DCHECK_EQ(headers_stream_id,
- QuicUtils::GetHeadersStreamId(transport_version()));
- }
- auto headers_stream = std::make_unique<QuicHeadersStream>((this));
- QUICHE_DCHECK_EQ(QuicUtils::GetHeadersStreamId(transport_version()),
- headers_stream->id());
-
- headers_stream_ = headers_stream.get();
- ActivateStream(std::move(headers_stream));
- } else {
- qpack_encoder_ = std::make_unique<QpackEncoder>(this);
- qpack_decoder_ =
- std::make_unique<QpackDecoder>(qpack_maximum_dynamic_table_capacity_,
- qpack_maximum_blocked_streams_, this);
- MaybeInitializeHttp3UnidirectionalStreams();
- }
-
- spdy_framer_visitor_->set_max_header_list_size(max_inbound_header_list_size_);
-
- // Limit HPACK buffering to 2x header list size limit.
- h2_deframer_.GetHpackDecoder()->set_max_decode_buffer_size_bytes(
- 2 * max_inbound_header_list_size_);
-}
-
-void QuicSpdySession::FillSettingsFrame() {
- settings_.values[SETTINGS_QPACK_MAX_TABLE_CAPACITY] =
- qpack_maximum_dynamic_table_capacity_;
- settings_.values[SETTINGS_QPACK_BLOCKED_STREAMS] =
- qpack_maximum_blocked_streams_;
- settings_.values[SETTINGS_MAX_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;
- }
- }
- if (WillNegotiateWebTransport()) {
- settings_.values[SETTINGS_WEBTRANS_DRAFT00] = 1;
- }
- if (allow_extended_connect()) {
- QUIC_RELOADABLE_FLAG_COUNT_N(quic_verify_request_headers_2, 1, 3);
- settings_.values[SETTINGS_ENABLE_CONNECT_PROTOCOL] = 1;
- }
-}
-
-void QuicSpdySession::OnDecoderStreamError(QuicErrorCode error_code,
- absl::string_view error_message) {
- QUICHE_DCHECK(VersionUsesHttp3(transport_version()));
-
- CloseConnectionWithDetails(
- error_code, absl::StrCat("Decoder stream error: ", error_message));
-}
-
-void QuicSpdySession::OnEncoderStreamError(QuicErrorCode error_code,
- absl::string_view error_message) {
- QUICHE_DCHECK(VersionUsesHttp3(transport_version()));
-
- CloseConnectionWithDetails(
- error_code, absl::StrCat("Encoder stream error: ", error_message));
-}
-
-void QuicSpdySession::OnStreamHeadersPriority(
- QuicStreamId stream_id, const spdy::SpdyStreamPrecedence& precedence) {
- QuicSpdyStream* stream = GetOrCreateSpdyDataStream(stream_id);
- if (!stream) {
- // It's quite possible to receive headers after a stream has been reset.
- return;
- }
- stream->OnStreamHeadersPriority(precedence);
-}
-
-void QuicSpdySession::OnStreamHeaderList(QuicStreamId stream_id, bool fin,
- size_t frame_len,
- const QuicHeaderList& header_list) {
- if (IsStaticStream(stream_id)) {
- connection()->CloseConnection(
- QUIC_INVALID_HEADERS_STREAM_DATA, "stream is static",
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
- return;
- }
- QuicSpdyStream* stream = GetOrCreateSpdyDataStream(stream_id);
- if (stream == nullptr) {
- // The stream no longer exists, but trailing headers may contain the final
- // byte offset necessary for flow control and open stream accounting.
- size_t final_byte_offset = 0;
- for (const auto& header : header_list) {
- const std::string& header_key = header.first;
- const std::string& header_value = header.second;
- if (header_key == kFinalOffsetHeaderKey) {
- if (!absl::SimpleAtoi(header_value, &final_byte_offset)) {
- connection()->CloseConnection(
- QUIC_INVALID_HEADERS_STREAM_DATA,
- "Trailers are malformed (no final offset)",
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
- return;
- }
- QUIC_DVLOG(1) << ENDPOINT
- << "Received final byte offset in trailers for stream "
- << stream_id << ", which no longer exists.";
- OnFinalByteOffsetReceived(stream_id, final_byte_offset);
- }
- }
-
- // It's quite possible to receive headers after a stream has been reset.
- return;
- }
- stream->OnStreamHeaderList(fin, frame_len, header_list);
-}
-
-void QuicSpdySession::OnPriorityFrame(
- QuicStreamId stream_id, const spdy::SpdyStreamPrecedence& precedence) {
- QuicSpdyStream* stream = GetOrCreateSpdyDataStream(stream_id);
- if (!stream) {
- // It's quite possible to receive a PRIORITY frame after a stream has been
- // reset.
- return;
- }
- stream->OnPriorityFrame(precedence);
-}
-
-bool QuicSpdySession::OnPriorityUpdateForRequestStream(QuicStreamId stream_id,
- int urgency) {
- if (perspective() == Perspective::IS_CLIENT ||
- !QuicUtils::IsBidirectionalStreamId(stream_id, version()) ||
- !QuicUtils::IsClientInitiatedStreamId(transport_version(), stream_id)) {
- return true;
- }
-
- QuicStreamCount advertised_max_incoming_bidirectional_streams =
- GetAdvertisedMaxIncomingBidirectionalStreams();
- if (advertised_max_incoming_bidirectional_streams == 0 ||
- stream_id > QuicUtils::GetFirstBidirectionalStreamId(
- transport_version(), Perspective::IS_CLIENT) +
- QuicUtils::StreamIdDelta(transport_version()) *
- (advertised_max_incoming_bidirectional_streams - 1)) {
- connection()->CloseConnection(
- QUIC_INVALID_STREAM_ID,
- "PRIORITY_UPDATE frame received for invalid stream.",
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
- return false;
- }
-
- if (MaybeSetStreamPriority(stream_id, spdy::SpdyStreamPrecedence(urgency))) {
- return true;
- }
-
- if (IsClosedStream(stream_id)) {
- return true;
- }
-
- buffered_stream_priorities_[stream_id] = urgency;
-
- if (buffered_stream_priorities_.size() >
- 10 * max_open_incoming_bidirectional_streams()) {
- // This should never happen, because |buffered_stream_priorities_| should
- // only contain entries for streams that are allowed to be open by the peer
- // but have not been opened yet.
- std::string error_message =
- absl::StrCat("Too many stream priority values buffered: ",
- buffered_stream_priorities_.size(),
- ", which should not exceed the incoming stream limit of ",
- max_open_incoming_bidirectional_streams());
- QUIC_BUG(quic_bug_10360_2) << error_message;
- connection()->CloseConnection(
- QUIC_INTERNAL_ERROR, error_message,
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
- return false;
- }
-
- return true;
-}
-
-bool QuicSpdySession::OnPriorityUpdateForPushStream(QuicStreamId /*push_id*/,
- int /*urgency*/) {
- // TODO(b/147306124): Implement PRIORITY_UPDATE frames for pushed streams.
- return true;
-}
-
-size_t QuicSpdySession::ProcessHeaderData(const struct iovec& iov) {
- QUIC_BUG_IF(quic_bug_12477_4, destruction_indicator_ != 123456789)
- << "QuicSpdyStream use after free. " << destruction_indicator_
- << QuicStackTrace();
- return h2_deframer_.ProcessInput(static_cast<char*>(iov.iov_base),
- iov.iov_len);
-}
-
-size_t QuicSpdySession::WriteHeadersOnHeadersStream(
- QuicStreamId id, SpdyHeaderBlock headers, bool fin,
- const spdy::SpdyStreamPrecedence& precedence,
- QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener) {
- QUICHE_DCHECK(!VersionUsesHttp3(transport_version()));
-
- return WriteHeadersOnHeadersStreamImpl(
- id, std::move(headers), fin,
- /* parent_stream_id = */ 0,
- Spdy3PriorityToHttp2Weight(precedence.spdy3_priority()),
- /* exclusive = */ false, std::move(ack_listener));
-}
-
-size_t QuicSpdySession::WritePriority(QuicStreamId id,
- QuicStreamId parent_stream_id, int weight,
- bool exclusive) {
- QUICHE_DCHECK(!VersionUsesHttp3(transport_version()));
- SpdyPriorityIR priority_frame(id, parent_stream_id, weight, exclusive);
- SpdySerializedFrame frame(spdy_framer_.SerializeFrame(priority_frame));
- headers_stream()->WriteOrBufferData(
- absl::string_view(frame.data(), frame.size()), false, nullptr);
- return frame.size();
-}
-
-void QuicSpdySession::WriteHttp3PriorityUpdate(
- const PriorityUpdateFrame& priority_update) {
- QUICHE_DCHECK(VersionUsesHttp3(transport_version()));
-
- send_control_stream_->WritePriorityUpdate(priority_update);
-}
-
-void QuicSpdySession::OnHttp3GoAway(uint64_t id) {
- QUIC_BUG_IF(quic_bug_12477_5, !version().UsesHttp3())
- << "HTTP/3 GOAWAY received on version " << version();
-
- if (last_received_http3_goaway_id_.has_value() &&
- id > last_received_http3_goaway_id_.value()) {
- CloseConnectionWithDetails(
- QUIC_HTTP_GOAWAY_ID_LARGER_THAN_PREVIOUS,
- absl::StrCat("GOAWAY received with ID ", id,
- " greater than previously received ID ",
- last_received_http3_goaway_id_.value()));
- return;
- }
- last_received_http3_goaway_id_ = id;
-
- if (perspective() == Perspective::IS_SERVER) {
- // TODO(b/151749109): Cancel server pushes with push ID larger than |id|.
- return;
- }
-
- // QuicStreamId is uint32_t. Casting to this narrower type is well-defined
- // and preserves the lower 32 bits. Both IsBidirectionalStreamId() and
- // IsIncomingStream() give correct results, because their return value is
- // determined by the least significant two bits.
- QuicStreamId stream_id = static_cast<QuicStreamId>(id);
- if (!QuicUtils::IsBidirectionalStreamId(stream_id, version()) ||
- IsIncomingStream(stream_id)) {
- CloseConnectionWithDetails(QUIC_HTTP_GOAWAY_INVALID_STREAM_ID,
- "GOAWAY with invalid stream ID");
- return;
- }
-
- // TODO(b/161252736): Cancel client requests with ID larger than |id|.
- // If |id| is larger than numeric_limits<QuicStreamId>::max(), then use
- // max() instead of downcast value.
-}
-
-bool QuicSpdySession::OnStreamsBlockedFrame(
- const QuicStreamsBlockedFrame& frame) {
- if (!QuicSession::OnStreamsBlockedFrame(frame)) {
- return false;
- }
-
- // The peer asked for stream space more than this implementation has. Send
- // goaway.
- if (perspective() == Perspective::IS_SERVER &&
- frame.stream_count >= QuicUtils::GetMaxStreamCount()) {
- QUICHE_DCHECK_EQ(frame.stream_count, QuicUtils::GetMaxStreamCount());
- SendHttp3GoAway(QUIC_PEER_GOING_AWAY, "stream count too large");
- }
- return true;
-}
-
-void QuicSpdySession::SendHttp3GoAway(QuicErrorCode error_code,
- const std::string& reason) {
- QUICHE_DCHECK(VersionUsesHttp3(transport_version()));
- if (!IsEncryptionEstablished()) {
- QUIC_CODE_COUNT(quic_h3_goaway_before_encryption_established);
- connection()->CloseConnection(
- error_code, reason,
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
- return;
- }
- QuicStreamId stream_id;
-
- stream_id = QuicUtils::GetMaxClientInitiatedBidirectionalStreamId(
- transport_version());
- if (last_sent_http3_goaway_id_.has_value()) {
- if (last_sent_http3_goaway_id_.value() == stream_id) {
- // Do not send GOAWAY twice.
- return;
- }
- if (last_sent_http3_goaway_id_.value() < stream_id) {
- // A previous GOAWAY frame was sent with smaller stream ID. This is not
- // possible, because the only time a GOAWAY frame with non-maximal
- // stream ID is sent is right before closing connection.
- QUIC_BUG(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;
- }
- }
-
- send_control_stream_->SendGoAway(stream_id);
- last_sent_http3_goaway_id_ = stream_id;
-}
-
-void QuicSpdySession::WritePushPromise(QuicStreamId original_stream_id,
- QuicStreamId promised_stream_id,
- SpdyHeaderBlock headers) {
- if (perspective() == Perspective::IS_CLIENT) {
- QUIC_BUG(quic_bug_10360_4) << "Client shouldn't send PUSH_PROMISE";
- return;
- }
-
- if (VersionUsesHttp3(transport_version())) {
- QUIC_BUG(quic_bug_12477_6)
- << "Support for server push over HTTP/3 has been removed.";
- return;
- }
-
- SpdyPushPromiseIR push_promise(original_stream_id, promised_stream_id,
- std::move(headers));
- // PUSH_PROMISE must not be the last frame sent out, at least followed by
- // response headers.
- push_promise.set_fin(false);
-
- SpdySerializedFrame frame(spdy_framer_.SerializeFrame(push_promise));
- headers_stream()->WriteOrBufferData(
- absl::string_view(frame.data(), frame.size()), false, nullptr);
-}
-
-void QuicSpdySession::SendInitialData() {
- if (!VersionUsesHttp3(transport_version())) {
- return;
- }
- QuicConnection::ScopedPacketFlusher flusher(connection());
- send_control_stream_->MaybeSendSettingsFrame();
-}
-
-QpackEncoder* QuicSpdySession::qpack_encoder() {
- QUICHE_DCHECK(VersionUsesHttp3(transport_version()));
-
- return qpack_encoder_.get();
-}
-
-QpackDecoder* QuicSpdySession::qpack_decoder() {
- QUICHE_DCHECK(VersionUsesHttp3(transport_version()));
-
- return qpack_decoder_.get();
-}
-
-void QuicSpdySession::OnStreamCreated(QuicSpdyStream* stream) {
- auto it = buffered_stream_priorities_.find(stream->id());
- if (it == buffered_stream_priorities_.end()) {
- return;
- }
-
- stream->SetPriority(spdy::SpdyStreamPrecedence(it->second));
- buffered_stream_priorities_.erase(it);
-}
-
-QuicSpdyStream* QuicSpdySession::GetOrCreateSpdyDataStream(
- const QuicStreamId stream_id) {
- QuicStream* stream = GetOrCreateStream(stream_id);
- if (stream && stream->is_static()) {
- QUIC_BUG(quic_bug_10360_5)
- << "GetOrCreateSpdyDataStream returns static stream " << stream_id
- << " in version " << transport_version() << "\n"
- << QuicStackTrace();
- connection()->CloseConnection(
- QUIC_INVALID_STREAM_ID,
- absl::StrCat("stream ", stream_id, " is static"),
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
- return nullptr;
- }
- return static_cast<QuicSpdyStream*>(stream);
-}
-
-void QuicSpdySession::OnNewEncryptionKeyAvailable(
- EncryptionLevel level, std::unique_ptr<QuicEncrypter> encrypter) {
- QuicSession::OnNewEncryptionKeyAvailable(level, std::move(encrypter));
- if (IsEncryptionEstablished()) {
- // Send H3 SETTINGs once encryption is established.
- SendInitialData();
- }
-}
-
-bool QuicSpdySession::ShouldNegotiateWebTransport() { return false; }
-
-bool QuicSpdySession::ShouldNegotiateDatagramContexts() { return false; }
-
-bool QuicSpdySession::ShouldValidateWebTransportVersion() const { return true; }
-
-bool QuicSpdySession::WillNegotiateWebTransport() {
- return LocalHttpDatagramSupport() != HttpDatagramSupport::kNone &&
- version().UsesHttp3() && ShouldNegotiateWebTransport();
-}
-
-// True if there are open HTTP requests.
-bool QuicSpdySession::ShouldKeepConnectionAlive() const {
- QUICHE_DCHECK(VersionUsesHttp3(transport_version()) ||
- 0u == pending_streams_size());
- return GetNumActiveStreams() + pending_streams_size() > 0;
-}
-
-bool QuicSpdySession::UsesPendingStreamForFrame(QuicFrameType type,
- QuicStreamId stream_id) const {
- // Pending streams can only be used to handle unidirectional stream with
- // STREAM & RESET_STREAM frames in IETF QUIC.
- return VersionUsesHttp3(transport_version()) &&
- (type == STREAM_FRAME || type == RST_STREAM_FRAME) &&
- QuicUtils::GetStreamType(stream_id, perspective(),
- IsIncomingStream(stream_id),
- version()) == READ_UNIDIRECTIONAL;
-}
-
-size_t QuicSpdySession::WriteHeadersOnHeadersStreamImpl(
- QuicStreamId id, spdy::SpdyHeaderBlock headers, bool fin,
- QuicStreamId parent_stream_id, int weight, bool exclusive,
- QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener) {
- QUICHE_DCHECK(!VersionUsesHttp3(transport_version()));
-
- const QuicByteCount uncompressed_size = headers.TotalBytesUsed();
- SpdyHeadersIR headers_frame(id, std::move(headers));
- headers_frame.set_fin(fin);
- if (perspective() == Perspective::IS_CLIENT) {
- headers_frame.set_has_priority(true);
- headers_frame.set_parent_stream_id(parent_stream_id);
- headers_frame.set_weight(weight);
- headers_frame.set_exclusive(exclusive);
- }
- SpdySerializedFrame frame(spdy_framer_.SerializeFrame(headers_frame));
- headers_stream()->WriteOrBufferData(
- absl::string_view(frame.data(), frame.size()), false,
- std::move(ack_listener));
-
- // Calculate compressed header block size without framing overhead.
- QuicByteCount compressed_size = frame.size();
- compressed_size -= spdy::kFrameHeaderSize;
- if (perspective() == Perspective::IS_CLIENT) {
- // Exclusive bit and Stream Dependency are four bytes, weight is one more.
- compressed_size -= 5;
- }
-
- LogHeaderCompressionRatioHistogram(
- /* using_qpack = */ false,
- /* is_sent = */ true, compressed_size, uncompressed_size);
-
- return frame.size();
-}
-
-void QuicSpdySession::OnPromiseHeaderList(
- QuicStreamId /*stream_id*/, QuicStreamId /*promised_stream_id*/,
- size_t /*frame_len*/, const QuicHeaderList& /*header_list*/) {
- std::string error =
- "OnPromiseHeaderList should be overridden in client code.";
- QUIC_BUG(quic_bug_10360_6) << error;
- connection()->CloseConnection(QUIC_INTERNAL_ERROR, error,
- ConnectionCloseBehavior::SILENT_CLOSE);
-}
-
-bool QuicSpdySession::ResumeApplicationState(ApplicationState* cached_state) {
- QUICHE_DCHECK_EQ(perspective(), Perspective::IS_CLIENT);
- QUICHE_DCHECK(VersionUsesHttp3(transport_version()));
-
- SettingsFrame out;
- if (!HttpDecoder::DecodeSettings(
- reinterpret_cast<char*>(cached_state->data()), cached_state->size(),
- &out)) {
- return false;
- }
-
- if (debug_visitor_ != nullptr) {
- debug_visitor_->OnSettingsFrameResumed(out);
- }
- QUICHE_DCHECK(streams_waiting_for_settings_.empty());
- for (const auto& setting : out.values) {
- OnSetting(setting.first, setting.second);
- }
- return true;
-}
-
-absl::optional<std::string> QuicSpdySession::OnAlpsData(
- const uint8_t* alps_data, size_t alps_length) {
- AlpsFrameDecoder alps_frame_decoder(this);
- HttpDecoder decoder(&alps_frame_decoder);
- decoder.ProcessInput(reinterpret_cast<const char*>(alps_data), alps_length);
- if (alps_frame_decoder.error_detail()) {
- return alps_frame_decoder.error_detail();
- }
-
- if (decoder.error() != QUIC_NO_ERROR) {
- return decoder.error_detail();
- }
-
- if (!decoder.AtFrameBoundary()) {
- return "incomplete HTTP/3 frame";
- }
-
- return absl::nullopt;
-}
-
-void QuicSpdySession::OnAcceptChFrameReceivedViaAlps(
- const AcceptChFrame& frame) {
- if (debug_visitor_) {
- debug_visitor_->OnAcceptChFrameReceivedViaAlps(frame);
- }
-}
-
-bool QuicSpdySession::OnSettingsFrame(const SettingsFrame& frame) {
- QUICHE_DCHECK(VersionUsesHttp3(transport_version()));
- if (debug_visitor_ != nullptr) {
- debug_visitor_->OnSettingsFrameReceived(frame);
- }
- for (const auto& setting : frame.values) {
- if (!OnSetting(setting.first, setting.second)) {
- return false;
- }
- }
- for (QuicStreamId stream_id : streams_waiting_for_settings_) {
- QUICHE_DCHECK(ShouldBufferRequestsUntilSettings());
- QuicSpdyStream* stream = GetOrCreateSpdyDataStream(stream_id);
- if (stream == nullptr) {
- // The stream may no longer exist, since it is possible for a stream to
- // get reset while waiting for the SETTINGS frame.
- continue;
- }
- stream->OnDataAvailable();
- }
- streams_waiting_for_settings_.clear();
- return true;
-}
-
-absl::optional<std::string> QuicSpdySession::OnSettingsFrameViaAlps(
- const SettingsFrame& frame) {
- QUICHE_DCHECK(VersionUsesHttp3(transport_version()));
-
- if (debug_visitor_ != nullptr) {
- debug_visitor_->OnSettingsFrameReceivedViaAlps(frame);
- }
- for (const auto& setting : frame.values) {
- if (!OnSetting(setting.first, setting.second)) {
- // Do not bother adding the setting identifier or value to the error
- // message, because OnSetting() already closed the connection, therefore
- // the error message will be ignored.
- return "error parsing setting";
- }
- }
- return absl::nullopt;
-}
-
-bool QuicSpdySession::VerifySettingIsZeroOrOne(uint64_t id, uint64_t value) {
- if (value == 0 || value == 1) {
- return true;
- }
- std::string error_details = absl::StrCat(
- "Received ",
- H3SettingsToString(static_cast<Http3AndQpackSettingsIdentifiers>(id)),
- " with invalid value ", value);
- QUIC_PEER_BUG(bad received setting) << ENDPOINT << error_details;
- CloseConnectionWithDetails(QUIC_HTTP_INVALID_SETTING_VALUE, error_details);
- return false;
-}
-
-bool QuicSpdySession::OnSetting(uint64_t id, uint64_t value) {
- any_settings_received_ = true;
-
- if (VersionUsesHttp3(transport_version())) {
- // SETTINGS frame received on the control stream.
- switch (id) {
- case SETTINGS_QPACK_MAX_TABLE_CAPACITY: {
- QUIC_DVLOG(1)
- << ENDPOINT
- << "SETTINGS_QPACK_MAX_TABLE_CAPACITY received with value "
- << value;
- // Communicate |value| to encoder, because it is used for encoding
- // Required Insert Count.
- if (!qpack_encoder_->SetMaximumDynamicTableCapacity(value)) {
- CloseConnectionWithDetails(
- was_zero_rtt_rejected()
- ? QUIC_HTTP_ZERO_RTT_REJECTION_SETTINGS_MISMATCH
- : QUIC_HTTP_ZERO_RTT_RESUMPTION_SETTINGS_MISMATCH,
- absl::StrCat(was_zero_rtt_rejected()
- ? "Server rejected 0-RTT, aborting because "
- : "",
- "Server sent an SETTINGS_QPACK_MAX_TABLE_CAPACITY: ",
- value, " while current value is: ",
- qpack_encoder_->MaximumDynamicTableCapacity()));
- return false;
- }
- // However, limit the dynamic table capacity to
- // |qpack_maximum_dynamic_table_capacity_|.
- qpack_encoder_->SetDynamicTableCapacity(
- std::min(value, qpack_maximum_dynamic_table_capacity_));
- break;
- }
- case SETTINGS_MAX_FIELD_SECTION_SIZE:
- QUIC_DVLOG(1) << ENDPOINT
- << "SETTINGS_MAX_FIELD_SECTION_SIZE received with value "
- << value;
- if (max_outbound_header_list_size_ !=
- std::numeric_limits<size_t>::max() &&
- max_outbound_header_list_size_ > value) {
- CloseConnectionWithDetails(
- was_zero_rtt_rejected()
- ? QUIC_HTTP_ZERO_RTT_REJECTION_SETTINGS_MISMATCH
- : QUIC_HTTP_ZERO_RTT_RESUMPTION_SETTINGS_MISMATCH,
- absl::StrCat(was_zero_rtt_rejected()
- ? "Server rejected 0-RTT, aborting because "
- : "",
- "Server sent an SETTINGS_MAX_FIELD_SECTION_SIZE: ",
- value, " which reduces current value: ",
- max_outbound_header_list_size_));
- return false;
- }
- max_outbound_header_list_size_ = value;
- break;
- case SETTINGS_QPACK_BLOCKED_STREAMS: {
- QUIC_DVLOG(1) << ENDPOINT
- << "SETTINGS_QPACK_BLOCKED_STREAMS received with value "
- << value;
- if (!qpack_encoder_->SetMaximumBlockedStreams(value)) {
- CloseConnectionWithDetails(
- was_zero_rtt_rejected()
- ? QUIC_HTTP_ZERO_RTT_REJECTION_SETTINGS_MISMATCH
- : QUIC_HTTP_ZERO_RTT_RESUMPTION_SETTINGS_MISMATCH,
- absl::StrCat(was_zero_rtt_rejected()
- ? "Server rejected 0-RTT, aborting because "
- : "",
- "Server sent an SETTINGS_QPACK_BLOCKED_STREAMS: ",
- value, " which reduces current value: ",
- qpack_encoder_->maximum_blocked_streams()));
- return false;
- }
- break;
- }
- case SETTINGS_ENABLE_CONNECT_PROTOCOL: {
- QUIC_DVLOG(1) << ENDPOINT
- << "SETTINGS_ENABLE_CONNECT_PROTOCOL received with value "
- << value;
- if (!VerifySettingIsZeroOrOne(id, value)) {
- return false;
- }
- if (perspective() == Perspective::IS_CLIENT) {
- allow_extended_connect_ = value != 0;
- }
- break;
- }
- case spdy::SETTINGS_ENABLE_PUSH:
- ABSL_FALLTHROUGH_INTENDED;
- case spdy::SETTINGS_MAX_CONCURRENT_STREAMS:
- ABSL_FALLTHROUGH_INTENDED;
- case spdy::SETTINGS_INITIAL_WINDOW_SIZE:
- ABSL_FALLTHROUGH_INTENDED;
- case spdy::SETTINGS_MAX_FRAME_SIZE:
- CloseConnectionWithDetails(
- QUIC_HTTP_RECEIVE_SPDY_SETTING,
- absl::StrCat("received HTTP/2 specific setting in HTTP/3 session: ",
- id));
- return false;
- case SETTINGS_H3_DATAGRAM_DRAFT00: {
- HttpDatagramSupport local_http_datagram_support =
- LocalHttpDatagramSupport();
- if (local_http_datagram_support != HttpDatagramSupport::kDraft00 &&
- local_http_datagram_support != HttpDatagramSupport::kDraft00And04) {
- break;
- }
- QUIC_DVLOG(1) << ENDPOINT
- << "SETTINGS_H3_DATAGRAM_DRAFT00 received with value "
- << value;
- if (!version().UsesHttp3()) {
- break;
- }
- 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;
- }
- break;
- }
- case SETTINGS_H3_DATAGRAM_DRAFT04: {
- HttpDatagramSupport local_http_datagram_support =
- LocalHttpDatagramSupport();
- if (local_http_datagram_support != HttpDatagramSupport::kDraft04 &&
- local_http_datagram_support != HttpDatagramSupport::kDraft00And04) {
- break;
- }
- QUIC_DVLOG(1) << ENDPOINT
- << "SETTINGS_H3_DATAGRAM_DRAFT04 received with value "
- << value;
- if (!version().UsesHttp3()) {
- break;
- }
- if (!VerifySettingIsZeroOrOne(id, value)) {
- return false;
- }
- if (value) {
- http_datagram_support_ = HttpDatagramSupport::kDraft04;
- }
- break;
- }
- case SETTINGS_WEBTRANS_DRAFT00:
- if (!WillNegotiateWebTransport()) {
- break;
- }
- QUIC_DVLOG(1) << ENDPOINT
- << "SETTINGS_ENABLE_WEBTRANSPORT received with value "
- << value;
- if (!VerifySettingIsZeroOrOne(id, value)) {
- return false;
- }
- peer_supports_webtransport_ = (value == 1);
- if (perspective() == Perspective::IS_CLIENT && value == 1) {
- allow_extended_connect_ = true;
- }
- break;
- default:
- QUIC_DVLOG(1) << ENDPOINT << "Unknown setting identifier " << id
- << " received with value " << value;
- // Ignore unknown settings.
- break;
- }
- return true;
- }
-
- // SETTINGS frame received on the headers stream.
- switch (id) {
- case spdy::SETTINGS_HEADER_TABLE_SIZE:
- QUIC_DVLOG(1) << ENDPOINT
- << "SETTINGS_HEADER_TABLE_SIZE received with value "
- << value;
- spdy_framer_.UpdateHeaderEncoderTableSize(value);
- break;
- case spdy::SETTINGS_ENABLE_PUSH:
- if (perspective() == Perspective::IS_SERVER) {
- // See rfc7540, Section 6.5.2.
- if (value > 1) {
- QUIC_DLOG(ERROR) << ENDPOINT << "Invalid value " << value
- << " received for SETTINGS_ENABLE_PUSH.";
- if (IsConnected()) {
- CloseConnectionWithDetails(
- QUIC_INVALID_HEADERS_STREAM_DATA,
- absl::StrCat("Invalid value for SETTINGS_ENABLE_PUSH: ",
- value));
- }
- return true;
- }
- QUIC_DVLOG(1) << ENDPOINT << "SETTINGS_ENABLE_PUSH received with value "
- << value << ", ignoring.";
- break;
- } else {
- QUIC_DLOG(ERROR)
- << ENDPOINT
- << "Invalid SETTINGS_ENABLE_PUSH received by client with value "
- << value;
- if (IsConnected()) {
- CloseConnectionWithDetails(
- QUIC_INVALID_HEADERS_STREAM_DATA,
- absl::StrCat("Unsupported field of HTTP/2 SETTINGS frame: ", id));
- }
- }
- break;
- case spdy::SETTINGS_MAX_HEADER_LIST_SIZE:
- QUIC_DVLOG(1) << ENDPOINT
- << "SETTINGS_MAX_HEADER_LIST_SIZE received with value "
- << value;
- max_outbound_header_list_size_ = value;
- break;
- default:
- QUIC_DLOG(ERROR) << ENDPOINT << "Unknown setting identifier " << id
- << " received with value " << value;
- if (IsConnected()) {
- CloseConnectionWithDetails(
- QUIC_INVALID_HEADERS_STREAM_DATA,
- absl::StrCat("Unsupported field of HTTP/2 SETTINGS frame: ", id));
- }
- }
- return true;
-}
-
-bool QuicSpdySession::ShouldReleaseHeadersStreamSequencerBuffer() {
- return false;
-}
-
-void QuicSpdySession::OnHeaders(SpdyStreamId stream_id, bool has_priority,
- const spdy::SpdyStreamPrecedence& precedence,
- bool fin) {
- if (has_priority) {
- if (perspective() == Perspective::IS_CLIENT) {
- CloseConnectionWithDetails(QUIC_INVALID_HEADERS_STREAM_DATA,
- "Server must not send priorities.");
- return;
- }
- OnStreamHeadersPriority(stream_id, precedence);
- } else {
- if (perspective() == Perspective::IS_SERVER) {
- CloseConnectionWithDetails(QUIC_INVALID_HEADERS_STREAM_DATA,
- "Client must send priorities.");
- return;
- }
- }
- QUICHE_DCHECK_EQ(QuicUtils::GetInvalidStreamId(transport_version()),
- stream_id_);
- QUICHE_DCHECK_EQ(QuicUtils::GetInvalidStreamId(transport_version()),
- promised_stream_id_);
- stream_id_ = stream_id;
- fin_ = fin;
-}
-
-void QuicSpdySession::OnPushPromise(SpdyStreamId stream_id,
- SpdyStreamId promised_stream_id) {
- QUICHE_DCHECK_EQ(QuicUtils::GetInvalidStreamId(transport_version()),
- stream_id_);
- QUICHE_DCHECK_EQ(QuicUtils::GetInvalidStreamId(transport_version()),
- promised_stream_id_);
- stream_id_ = stream_id;
- promised_stream_id_ = promised_stream_id;
-}
-
-// TODO (wangyix): Why is SpdyStreamId used instead of QuicStreamId?
-// This occurs in many places in this file.
-void QuicSpdySession::OnPriority(SpdyStreamId stream_id,
- const spdy::SpdyStreamPrecedence& precedence) {
- if (perspective() == Perspective::IS_CLIENT) {
- CloseConnectionWithDetails(QUIC_INVALID_HEADERS_STREAM_DATA,
- "Server must not send PRIORITY frames.");
- return;
- }
- OnPriorityFrame(stream_id, precedence);
-}
-
-void QuicSpdySession::OnHeaderList(const QuicHeaderList& header_list) {
- QUIC_DVLOG(1) << ENDPOINT << "Received header list for stream " << stream_id_
- << ": " << header_list.DebugString();
- // This code path is only executed for push promise in IETF QUIC.
- if (VersionUsesHttp3(transport_version())) {
- QUICHE_DCHECK(promised_stream_id_ !=
- QuicUtils::GetInvalidStreamId(transport_version()));
- }
- if (promised_stream_id_ ==
- QuicUtils::GetInvalidStreamId(transport_version())) {
- OnStreamHeaderList(stream_id_, fin_, frame_len_, header_list);
- } else {
- OnPromiseHeaderList(stream_id_, promised_stream_id_, frame_len_,
- header_list);
- }
- // Reset state for the next frame.
- promised_stream_id_ = QuicUtils::GetInvalidStreamId(transport_version());
- stream_id_ = QuicUtils::GetInvalidStreamId(transport_version());
- fin_ = false;
- frame_len_ = 0;
-}
-
-void QuicSpdySession::OnCompressedFrameSize(size_t frame_len) {
- frame_len_ += frame_len;
-}
-
-void QuicSpdySession::CloseConnectionWithDetails(QuicErrorCode error,
- const std::string& details) {
- connection()->CloseConnection(
- error, details, ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
-}
-
-bool QuicSpdySession::HasActiveRequestStreams() const {
- return GetNumActiveStreams() + num_draining_streams() > 0;
-}
-
-QuicStream* QuicSpdySession::ProcessPendingStream(PendingStream* pending) {
- QUICHE_DCHECK(VersionUsesHttp3(transport_version()));
- QUICHE_DCHECK(connection()->connected());
- struct iovec iov;
- if (!pending->sequencer()->GetReadableRegion(&iov)) {
- // The first byte hasn't been received yet.
- return nullptr;
- }
-
- QuicDataReader reader(static_cast<char*>(iov.iov_base), iov.iov_len);
- uint8_t stream_type_length = reader.PeekVarInt62Length();
- uint64_t stream_type = 0;
- if (!reader.ReadVarInt62(&stream_type)) {
- if (pending->sequencer()->NumBytesBuffered() ==
- pending->sequencer()->close_offset()) {
- // Stream received FIN but there are not enough bytes for stream type.
- // Mark all bytes consumed in order to close stream.
- pending->MarkConsumed(pending->sequencer()->close_offset());
- }
- return nullptr;
- }
- pending->MarkConsumed(stream_type_length);
-
- switch (stream_type) {
- case kControlStream: { // HTTP/3 control stream.
- if (receive_control_stream_) {
- CloseConnectionOnDuplicateHttp3UnidirectionalStreams("Control");
- return nullptr;
- }
- auto receive_stream =
- std::make_unique<QuicReceiveControlStream>(pending, this);
- receive_control_stream_ = receive_stream.get();
- ActivateStream(std::move(receive_stream));
- QUIC_DVLOG(1) << ENDPOINT << "Receive Control stream is created";
- if (debug_visitor_ != nullptr) {
- debug_visitor_->OnPeerControlStreamCreated(
- receive_control_stream_->id());
- }
- return receive_control_stream_;
- }
- case kServerPushStream: { // Push Stream.
- CloseConnectionWithDetails(QUIC_HTTP_RECEIVE_SERVER_PUSH,
- "Received server push stream");
- return nullptr;
- }
- case kQpackEncoderStream: { // QPACK encoder stream.
- if (qpack_encoder_receive_stream_) {
- CloseConnectionOnDuplicateHttp3UnidirectionalStreams("QPACK encoder");
- return nullptr;
- }
- auto encoder_receive = std::make_unique<QpackReceiveStream>(
- pending, this, qpack_decoder_->encoder_stream_receiver());
- qpack_encoder_receive_stream_ = encoder_receive.get();
- ActivateStream(std::move(encoder_receive));
- QUIC_DVLOG(1) << ENDPOINT << "Receive QPACK Encoder stream is created";
- if (debug_visitor_ != nullptr) {
- debug_visitor_->OnPeerQpackEncoderStreamCreated(
- qpack_encoder_receive_stream_->id());
- }
- return qpack_encoder_receive_stream_;
- }
- case kQpackDecoderStream: { // QPACK decoder stream.
- if (qpack_decoder_receive_stream_) {
- CloseConnectionOnDuplicateHttp3UnidirectionalStreams("QPACK decoder");
- return nullptr;
- }
- auto decoder_receive = std::make_unique<QpackReceiveStream>(
- pending, this, qpack_encoder_->decoder_stream_receiver());
- qpack_decoder_receive_stream_ = decoder_receive.get();
- ActivateStream(std::move(decoder_receive));
- QUIC_DVLOG(1) << ENDPOINT << "Receive QPACK Decoder stream is created";
- if (debug_visitor_ != nullptr) {
- debug_visitor_->OnPeerQpackDecoderStreamCreated(
- qpack_decoder_receive_stream_->id());
- }
- return qpack_decoder_receive_stream_;
- }
- case kWebTransportUnidirectionalStream: {
- // Note that this checks whether WebTransport is enabled on the receiver
- // side, as we may receive WebTransport streams before peer's SETTINGS are
- // received.
- // TODO(b/184156476): consider whether this means we should drop buffered
- // streams if we don't receive indication of WebTransport support.
- if (!WillNegotiateWebTransport()) {
- // Treat as unknown stream type.
- break;
- }
- QUIC_DVLOG(1) << ENDPOINT << "Created an incoming WebTransport stream "
- << pending->id();
- auto stream_owned =
- std::make_unique<WebTransportHttp3UnidirectionalStream>(pending,
- this);
- WebTransportHttp3UnidirectionalStream* stream = stream_owned.get();
- ActivateStream(std::move(stream_owned));
- return stream;
- }
- default:
- break;
- }
- MaybeSendStopSendingFrame(
- pending->id(),
- QuicResetStreamError::FromInternal(QUIC_STREAM_STREAM_CREATION_ERROR));
- pending->StopReading();
- return nullptr;
-}
-
-void QuicSpdySession::MaybeInitializeHttp3UnidirectionalStreams() {
- QUICHE_DCHECK(VersionUsesHttp3(transport_version()));
- if (!send_control_stream_ && CanOpenNextOutgoingUnidirectionalStream()) {
- auto send_control = std::make_unique<QuicSendControlStream>(
- GetNextOutgoingUnidirectionalStreamId(), this, settings_);
- send_control_stream_ = send_control.get();
- ActivateStream(std::move(send_control));
- if (debug_visitor_) {
- debug_visitor_->OnControlStreamCreated(send_control_stream_->id());
- }
- }
-
- if (!qpack_decoder_send_stream_ &&
- CanOpenNextOutgoingUnidirectionalStream()) {
- auto decoder_send = std::make_unique<QpackSendStream>(
- GetNextOutgoingUnidirectionalStreamId(), this, kQpackDecoderStream);
- qpack_decoder_send_stream_ = decoder_send.get();
- ActivateStream(std::move(decoder_send));
- qpack_decoder_->set_qpack_stream_sender_delegate(
- qpack_decoder_send_stream_);
- if (debug_visitor_) {
- debug_visitor_->OnQpackDecoderStreamCreated(
- qpack_decoder_send_stream_->id());
- }
- }
-
- if (!qpack_encoder_send_stream_ &&
- CanOpenNextOutgoingUnidirectionalStream()) {
- auto encoder_send = std::make_unique<QpackSendStream>(
- GetNextOutgoingUnidirectionalStreamId(), this, kQpackEncoderStream);
- qpack_encoder_send_stream_ = encoder_send.get();
- ActivateStream(std::move(encoder_send));
- qpack_encoder_->set_qpack_stream_sender_delegate(
- qpack_encoder_send_stream_);
- if (debug_visitor_) {
- debug_visitor_->OnQpackEncoderStreamCreated(
- qpack_encoder_send_stream_->id());
- }
- }
-}
-
-void QuicSpdySession::BeforeConnectionCloseSent() {
- if (!VersionUsesHttp3(transport_version()) || !IsEncryptionEstablished()) {
- return;
- }
-
- QUICHE_DCHECK_EQ(perspective(), Perspective::IS_SERVER);
-
- QuicStreamId stream_id =
- GetLargestPeerCreatedStreamId(/*unidirectional = */ false);
-
- if (stream_id == QuicUtils::GetInvalidStreamId(transport_version())) {
- // No client-initiated bidirectional streams received yet.
- // Send 0 to let client know that all requests can be retried.
- stream_id = 0;
- } else {
- // Tell client that streams starting with the next after the largest
- // received one can be retried.
- stream_id += QuicUtils::StreamIdDelta(transport_version());
- }
- if (last_sent_http3_goaway_id_.has_value() &&
- last_sent_http3_goaway_id_.value() <= stream_id) {
- // 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.
- return;
- }
-
- send_control_stream_->SendGoAway(stream_id);
- last_sent_http3_goaway_id_ = stream_id;
-}
-
-void QuicSpdySession::OnCanCreateNewOutgoingStream(bool unidirectional) {
- if (unidirectional && VersionUsesHttp3(transport_version())) {
- MaybeInitializeHttp3UnidirectionalStreams();
- }
-}
-
-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()
- : transport_goaway_received();
-}
-
-bool QuicSpdySession::goaway_sent() const {
- return VersionUsesHttp3(transport_version())
- ? last_sent_http3_goaway_id_.has_value()
- : transport_goaway_sent();
-}
-
-bool QuicSpdySession::CanCreatePushStreamWithId(PushId /* push_id */) {
- // TODO(b/171463363): Remove this method.
- QUICHE_DCHECK(VersionUsesHttp3(transport_version()));
-
- return false;
-}
-
-void QuicSpdySession::CloseConnectionOnDuplicateHttp3UnidirectionalStreams(
- absl::string_view type) {
- QUIC_PEER_BUG(quic_peer_bug_10360_9) << absl::StrCat(
- "Received a duplicate ", type, " stream: Closing connection.");
- CloseConnectionWithDetails(QUIC_HTTP_DUPLICATE_UNIDIRECTIONAL_STREAM,
- absl::StrCat(type, " stream is received twice."));
-}
-
-// static
-void QuicSpdySession::LogHeaderCompressionRatioHistogram(
- bool using_qpack, bool is_sent, QuicByteCount compressed,
- QuicByteCount uncompressed) {
- if (compressed <= 0 || uncompressed <= 0) {
- return;
- }
-
- int ratio = 100 * (compressed) / (uncompressed);
- if (ratio < 1) {
- ratio = 1;
- } else if (ratio > 200) {
- ratio = 200;
- }
-
- // Note that when using histogram macros in Chromium, the histogram name must
- // be the same across calls for any given call site.
- if (using_qpack) {
- if (is_sent) {
- QUIC_HISTOGRAM_COUNTS("QuicSession.HeaderCompressionRatioQpackSent",
- ratio, 1, 200, 200,
- "Header compression ratio as percentage for sent "
- "headers using QPACK.");
- } else {
- QUIC_HISTOGRAM_COUNTS("QuicSession.HeaderCompressionRatioQpackReceived",
- ratio, 1, 200, 200,
- "Header compression ratio as percentage for "
- "received headers using QPACK.");
- }
- } else {
- if (is_sent) {
- QUIC_HISTOGRAM_COUNTS("QuicSession.HeaderCompressionRatioHpackSent",
- ratio, 1, 200, 200,
- "Header compression ratio as percentage for sent "
- "headers using HPACK.");
- } else {
- QUIC_HISTOGRAM_COUNTS("QuicSession.HeaderCompressionRatioHpackReceived",
- ratio, 1, 200, 200,
- "Header compression ratio as percentage for "
- "received headers using HPACK.");
- }
- }
-}
-
-MessageStatus QuicSpdySession::SendHttp3Datagram(
- QuicDatagramStreamId stream_id,
- absl::optional<QuicDatagramContextId> context_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;
- }
- size_t slice_length =
- QuicDataWriter::GetVarInt62Len(stream_id_to_write) + payload.length();
- if (context_id.has_value()) {
- slice_length += QuicDataWriter::GetVarInt62Len(context_id.value());
- }
- QuicBuffer buffer(connection()->helper()->GetStreamSendBufferAllocator(),
- slice_length);
- QuicDataWriter writer(slice_length, buffer.data());
- if (!writer.WriteVarInt62(stream_id_to_write)) {
- QUIC_BUG(h3 datagram stream ID write fail)
- << "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";
- return MESSAGE_STATUS_INTERNAL_ERROR;
- }
-
- QuicMemSlice slice(std::move(buffer));
- return datagram_queue()->SendOrQueueDatagram(std::move(slice));
-}
-
-void QuicSpdySession::SetMaxDatagramTimeInQueueForStreamId(
- QuicStreamId /*stream_id*/, QuicTime::Delta max_time_in_queue) {
- // TODO(b/184598230): implement this in a way that works for multiple sessions
- // on a same connection.
- 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()) {
- QUIC_DLOG(INFO) << "Ignoring unexpected received HTTP/3 datagram";
- return;
- }
- QuicDataReader reader(message);
- uint64_t stream_id64;
- if (!reader.ReadVarInt62(&stream_id64)) {
- 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;
- return;
- }
- 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.
- return;
- }
- stream->OnDatagramReceived(&reader);
-}
-
-bool QuicSpdySession::SupportsWebTransport() {
- return WillNegotiateWebTransport() && SupportsH3Datagram() &&
- peer_supports_webtransport_ &&
- (!GetQuicReloadableFlag(quic_verify_request_headers_2) ||
- allow_extended_connect_);
-}
-
-bool QuicSpdySession::SupportsH3Datagram() const {
- return http_datagram_support_ != HttpDatagramSupport::kNone;
-}
-
-WebTransportHttp3* QuicSpdySession::GetWebTransportSession(
- WebTransportSessionId id) {
- if (!SupportsWebTransport()) {
- return nullptr;
- }
- if (!IsValidWebTransportSessionId(id, version())) {
- return nullptr;
- }
- QuicSpdyStream* connect_stream = GetOrCreateSpdyDataStream(id);
- if (connect_stream == nullptr) {
- return nullptr;
- }
- return connect_stream->web_transport();
-}
-
-bool QuicSpdySession::ShouldProcessIncomingRequests() {
- if (!ShouldBufferRequestsUntilSettings()) {
- return true;
- }
-
- return any_settings_received_;
-}
-
-void QuicSpdySession::OnStreamWaitingForClientSettings(QuicStreamId id) {
- QUICHE_DCHECK(ShouldBufferRequestsUntilSettings());
- QUICHE_DCHECK(QuicUtils::IsBidirectionalStreamId(id, version()));
- streams_waiting_for_settings_.insert(id);
-}
-
-void QuicSpdySession::AssociateIncomingWebTransportStreamWithSession(
- WebTransportSessionId session_id, QuicStreamId stream_id) {
- if (QuicUtils::IsOutgoingStreamId(version(), stream_id, perspective())) {
- QUIC_BUG(AssociateIncomingWebTransportStreamWithSession got outgoing stream)
- << ENDPOINT
- << "AssociateIncomingWebTransportStreamWithSession() got an outgoing "
- "stream ID: "
- << stream_id;
- return;
- }
- WebTransportHttp3* session = GetWebTransportSession(session_id);
- if (session != nullptr) {
- QUIC_DVLOG(1) << ENDPOINT
- << "Successfully associated incoming WebTransport stream "
- << stream_id << " with session ID " << session_id;
-
- session->AssociateStream(stream_id);
- return;
- }
- // Evict the oldest streams until we are under the limit.
- while (buffered_streams_.size() >= kMaxUnassociatedWebTransportStreams) {
- QUIC_DVLOG(1) << ENDPOINT << "Removing stream "
- << buffered_streams_.front().stream_id
- << " from buffered streams as the queue is full.";
- ResetStream(buffered_streams_.front().stream_id,
- QUIC_STREAM_WEBTRANSPORT_BUFFERED_STREAMS_LIMIT_EXCEEDED);
- buffered_streams_.pop_front();
- }
- QUIC_DVLOG(1) << ENDPOINT << "Received a WebTransport stream " << stream_id
- << " for session ID " << session_id
- << " but cannot associate it; buffering instead.";
- buffered_streams_.push_back(
- BufferedWebTransportStream{session_id, stream_id});
-}
-
-void QuicSpdySession::ProcessBufferedWebTransportStreamsForSession(
- WebTransportHttp3* session) {
- const WebTransportSessionId session_id = session->id();
- QUIC_DVLOG(1) << "Processing buffered WebTransport streams for "
- << session_id;
- auto it = buffered_streams_.begin();
- while (it != buffered_streams_.end()) {
- if (it->session_id == session_id) {
- QUIC_DVLOG(1) << "Unbuffered and associated WebTransport stream "
- << it->stream_id << " with session " << it->session_id;
- session->AssociateStream(it->stream_id);
- it = buffered_streams_.erase(it);
- } else {
- it++;
- }
- }
-}
-
-WebTransportHttp3UnidirectionalStream*
-QuicSpdySession::CreateOutgoingUnidirectionalWebTransportStream(
- WebTransportHttp3* session) {
- if (!CanOpenNextOutgoingUnidirectionalStream()) {
- return nullptr;
- }
-
- QuicStreamId stream_id = GetNextOutgoingUnidirectionalStreamId();
- auto stream_owned = std::make_unique<WebTransportHttp3UnidirectionalStream>(
- stream_id, this, session->id());
- WebTransportHttp3UnidirectionalStream* stream = stream_owned.get();
- ActivateStream(std::move(stream_owned));
- stream->WritePreamble();
- session->AssociateStream(stream_id);
- return stream;
-}
-
-QuicSpdyStream* QuicSpdySession::CreateOutgoingBidirectionalWebTransportStream(
- WebTransportHttp3* session) {
- QuicSpdyStream* stream = CreateOutgoingBidirectionalStream();
- if (stream == nullptr) {
- return nullptr;
- }
- QuicStreamId stream_id = stream->id();
- stream->ConvertToWebTransportDataStream(session->id());
- if (stream->web_transport_stream() == nullptr) {
- // An error in ConvertToWebTransportDataStream() would result in
- // CONNECTION_CLOSE, thus we don't need to do anything here.
- return nullptr;
- }
- session->AssociateStream(stream_id);
- return stream;
-}
-
-void QuicSpdySession::OnDatagramProcessed(
- absl::optional<MessageStatus> /*status*/) {
- // TODO(b/184598230): make this work with multiple datagram flows.
-}
-
-void QuicSpdySession::DatagramObserver::OnDatagramProcessed(
- absl::optional<MessageStatus> status) {
- session_->OnDatagramProcessed(status);
-}
-
-HttpDatagramSupport QuicSpdySession::LocalHttpDatagramSupport() {
- return HttpDatagramSupport::kNone;
-}
-
-std::string HttpDatagramSupportToString(
- HttpDatagramSupport http_datagram_support) {
- switch (http_datagram_support) {
- case HttpDatagramSupport::kNone:
- return "None";
- case HttpDatagramSupport::kDraft00:
- return "Draft00";
- case HttpDatagramSupport::kDraft04:
- return "Draft04";
- case HttpDatagramSupport::kDraft00And04:
- return "Draft00And04";
- }
- return absl::StrCat("Unknown(", static_cast<int>(http_datagram_support), ")");
-}
-
-std::ostream& operator<<(std::ostream& os,
- const HttpDatagramSupport& http_datagram_support) {
- os << HttpDatagramSupportToString(http_datagram_support);
- return os;
-}
-
-// Must not be called after Initialize().
-void QuicSpdySession::set_allow_extended_connect(bool allow_extended_connect) {
- QUIC_BUG_IF(extended connect wrong version,
- !GetQuicReloadableFlag(quic_verify_request_headers_2) ||
- !VersionUsesHttp3(transport_version()))
- << "Try to enable/disable extended CONNECT in Google QUIC";
- QUIC_BUG_IF(extended connect on client,
- !GetQuicReloadableFlag(quic_verify_request_headers_2) ||
- perspective() == Perspective::IS_CLIENT)
- << "Enabling/disabling extended CONNECT on the client side has no effect";
- if (ShouldNegotiateWebTransport()) {
- QUIC_BUG_IF(disable extended connect, !allow_extended_connect)
- << "Disabling extended CONNECT with web transport enabled has no "
- "effect.";
- return;
- }
- allow_extended_connect_ = allow_extended_connect;
-}
-
-#undef ENDPOINT // undef for jumbo builds
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_session.h b/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_session.h
deleted file mode 100644
index 50603de7d5a..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_session.h
+++ /dev/null
@@ -1,710 +0,0 @@
-// Copyright (c) 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_HTTP_QUIC_SPDY_SESSION_H_
-#define QUICHE_QUIC_CORE_HTTP_QUIC_SPDY_SESSION_H_
-
-#include <cstddef>
-#include <cstdint>
-#include <list>
-#include <memory>
-#include <string>
-
-#include "absl/container/flat_hash_map.h"
-#include "absl/container/flat_hash_set.h"
-#include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
-#include "quic/core/http/http_frames.h"
-#include "quic/core/http/quic_header_list.h"
-#include "quic/core/http/quic_headers_stream.h"
-#include "quic/core/http/quic_receive_control_stream.h"
-#include "quic/core/http/quic_send_control_stream.h"
-#include "quic/core/http/quic_spdy_stream.h"
-#include "quic/core/qpack/qpack_decoder.h"
-#include "quic/core/qpack/qpack_decoder_stream_sender.h"
-#include "quic/core/qpack/qpack_encoder.h"
-#include "quic/core/qpack/qpack_encoder_stream_sender.h"
-#include "quic/core/qpack/qpack_receive_stream.h"
-#include "quic/core/qpack/qpack_send_stream.h"
-#include "quic/core/quic_session.h"
-#include "quic/core/quic_time.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_versions.h"
-#include "quic/platform/api/quic_containers.h"
-#include "quic/platform/api/quic_export.h"
-#include "common/quiche_circular_deque.h"
-#include "spdy/core/http2_frame_decoder_adapter.h"
-
-namespace quic {
-
-namespace test {
-class QuicSpdySessionPeer;
-} // namespace test
-
-class WebTransportHttp3UnidirectionalStream;
-
-QUIC_EXPORT_PRIVATE extern const size_t kMaxUnassociatedWebTransportStreams;
-
-class QUIC_EXPORT_PRIVATE Http3DebugVisitor {
- public:
- Http3DebugVisitor();
- Http3DebugVisitor(const Http3DebugVisitor&) = delete;
- Http3DebugVisitor& operator=(const Http3DebugVisitor&) = delete;
-
- virtual ~Http3DebugVisitor();
-
- // TODO(https://crbug.com/1062700): Remove default implementation of all
- // methods after Chrome's QuicHttp3Logger has overrides. This is to make sure
- // QUICHE merge is not blocked on having to add those overrides, they can
- // happen asynchronously.
-
- // Creation of unidirectional streams.
-
- // Called when locally-initiated control stream is created.
- virtual void OnControlStreamCreated(QuicStreamId /*stream_id*/) {}
- // Called when locally-initiated QPACK encoder stream is created.
- virtual void OnQpackEncoderStreamCreated(QuicStreamId /*stream_id*/) {}
- // Called when locally-initiated QPACK decoder stream is created.
- virtual void OnQpackDecoderStreamCreated(QuicStreamId /*stream_id*/) {}
- // Called when peer's control stream type is received.
- virtual void OnPeerControlStreamCreated(QuicStreamId /*stream_id*/) = 0;
- // Called when peer's QPACK encoder stream type is received.
- virtual void OnPeerQpackEncoderStreamCreated(QuicStreamId /*stream_id*/) = 0;
- // Called when peer's QPACK decoder stream type is received.
- virtual void OnPeerQpackDecoderStreamCreated(QuicStreamId /*stream_id*/) = 0;
-
- // Incoming HTTP/3 frames in ALPS TLS extension.
- virtual void OnSettingsFrameReceivedViaAlps(const SettingsFrame& /*frame*/) {}
- virtual void OnAcceptChFrameReceivedViaAlps(const AcceptChFrame& /*frame*/) {}
-
- // 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*/) {}
-
- // Incoming HTTP/3 frames on request or push streams.
- virtual void OnDataFrameReceived(QuicStreamId /*stream_id*/,
- QuicByteCount /*payload_length*/) {}
- virtual void OnHeadersFrameReceived(
- QuicStreamId /*stream_id*/, QuicByteCount /*compressed_headers_length*/) {
- }
- virtual void OnHeadersDecoded(QuicStreamId /*stream_id*/,
- QuicHeaderList /*headers*/) {}
-
- // Incoming HTTP/3 frames of unknown type on any stream.
- virtual void OnUnknownFrameReceived(QuicStreamId /*stream_id*/,
- uint64_t /*frame_type*/,
- QuicByteCount /*payload_length*/) {}
-
- // Outgoing HTTP/3 frames on the control stream.
- virtual void OnSettingsFrameSent(const SettingsFrame& /*frame*/) = 0;
- virtual void OnGoAwayFrameSent(QuicStreamId /*stream_id*/) {}
- // TODO(b/171463363): Remove.
- virtual void OnMaxPushIdFrameSent(const MaxPushIdFrame& /*frame*/) {}
- virtual void OnPriorityUpdateFrameSent(const PriorityUpdateFrame& /*frame*/) {
- }
-
- // Outgoing HTTP/3 frames on request or push streams.
- virtual void OnDataFrameSent(QuicStreamId /*stream_id*/,
- QuicByteCount /*payload_length*/) {}
- virtual void OnHeadersFrameSent(
- QuicStreamId /*stream_id*/,
- const spdy::SpdyHeaderBlock& /*header_block*/) {}
-
- // 0-RTT related events.
- virtual void OnSettingsFrameResumed(const SettingsFrame& /*frame*/) {}
-};
-
-// 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.
-};
-
-QUIC_EXPORT_PRIVATE std::string HttpDatagramSupportToString(
- HttpDatagramSupport http_datagram_support);
-QUIC_EXPORT_PRIVATE std::ostream& operator<<(
- std::ostream& os, const HttpDatagramSupport& http_datagram_support);
-
-// A QUIC session for HTTP.
-class QUIC_EXPORT_PRIVATE QuicSpdySession
- : public QuicSession,
- public QpackEncoder::DecoderStreamErrorDelegate,
- public QpackDecoder::EncoderStreamErrorDelegate {
- public:
- // Does not take ownership of |connection| or |visitor|.
- QuicSpdySession(QuicConnection* connection, QuicSession::Visitor* visitor,
- const QuicConfig& config,
- const ParsedQuicVersionVector& supported_versions);
- QuicSpdySession(const QuicSpdySession&) = delete;
- QuicSpdySession& operator=(const QuicSpdySession&) = delete;
-
- ~QuicSpdySession() override;
-
- void Initialize() override;
-
- // QpackEncoder::DecoderStreamErrorDelegate implementation.
- void OnDecoderStreamError(QuicErrorCode error_code,
- absl::string_view error_message) override;
-
- // QpackDecoder::EncoderStreamErrorDelegate implementation.
- void OnEncoderStreamError(QuicErrorCode error_code,
- absl::string_view error_message) override;
-
- // Called by |headers_stream_| when headers with a priority have been
- // received for a stream. This method will only be called for server streams.
- virtual void OnStreamHeadersPriority(
- QuicStreamId stream_id, const spdy::SpdyStreamPrecedence& precedence);
-
- // Called by |headers_stream_| when headers have been completely received
- // for a stream. |fin| will be true if the fin flag was set in the headers
- // frame.
- virtual void OnStreamHeaderList(QuicStreamId stream_id, bool fin,
- size_t frame_len,
- const QuicHeaderList& header_list);
-
- // Called by |headers_stream_| when push promise headers have been
- // completely received. |fin| will be true if the fin flag was set
- // in the headers.
- virtual void OnPromiseHeaderList(QuicStreamId stream_id,
- QuicStreamId promised_stream_id,
- size_t frame_len,
- const QuicHeaderList& header_list);
-
- // Called by |headers_stream_| when a PRIORITY frame has been received for a
- // stream. This method will only be called for server streams.
- virtual void OnPriorityFrame(QuicStreamId stream_id,
- const spdy::SpdyStreamPrecedence& precedence);
-
- // Called when an HTTP/3 PRIORITY_UPDATE frame has been received for a request
- // stream. Returns false and closes connection if |stream_id| is invalid.
- bool OnPriorityUpdateForRequestStream(QuicStreamId stream_id, int urgency);
-
- // Called when an HTTP/3 PRIORITY_UPDATE frame has been received for a push
- // stream. Returns false and closes connection if |push_id| is invalid.
- bool OnPriorityUpdateForPushStream(QuicStreamId push_id, int urgency);
-
- // Called when an HTTP/3 ACCEPT_CH frame has been received.
- // This method will only be called for client sessions.
- virtual void OnAcceptChFrame(const AcceptChFrame& /*frame*/) {}
-
- // Sends contents of |iov| to h2_deframer_, returns number of bytes processed.
- size_t ProcessHeaderData(const struct iovec& iov);
-
- // Writes |headers| for the stream |id| to the dedicated headers stream.
- // If |fin| is true, then no more data will be sent for the stream |id|.
- // If provided, |ack_notifier_delegate| will be registered to be notified when
- // we have seen ACKs for all packets resulting from this call.
- virtual size_t WriteHeadersOnHeadersStream(
- QuicStreamId id, spdy::SpdyHeaderBlock headers, bool fin,
- const spdy::SpdyStreamPrecedence& precedence,
- QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener);
-
- // Writes an HTTP/2 PRIORITY frame the to peer. Returns the size in bytes of
- // the resulting PRIORITY frame.
- size_t WritePriority(QuicStreamId id, QuicStreamId parent_stream_id,
- int weight, bool exclusive);
-
- // Writes an HTTP/3 PRIORITY_UPDATE frame to the peer.
- void WriteHttp3PriorityUpdate(const PriorityUpdateFrame& priority_update);
-
- // Process received HTTP/3 GOAWAY frame. When sent from server to client,
- // |id| is a stream ID. When sent from client to server, |id| is a push ID.
- virtual void OnHttp3GoAway(uint64_t id);
-
- // Send GOAWAY if the peer is blocked on the implementation max.
- bool OnStreamsBlockedFrame(const QuicStreamsBlockedFrame& frame) override;
-
- // Write GOAWAY frame with maximum stream ID on the control stream. Called to
- // initite graceful connection shutdown. Do not use smaller stream ID, in
- // case client does not implement retry on GOAWAY. Do not send GOAWAY if one
- // has already been sent. Send connection close with |error_code| and |reason|
- // before encryption gets established.
- void SendHttp3GoAway(QuicErrorCode error_code, const std::string& reason);
-
- // Write |headers| for |promised_stream_id| on |original_stream_id| in a
- // PUSH_PROMISE frame to peer.
- virtual void WritePushPromise(QuicStreamId original_stream_id,
- QuicStreamId promised_stream_id,
- spdy::SpdyHeaderBlock headers);
-
- QpackEncoder* qpack_encoder();
- QpackDecoder* qpack_decoder();
- QuicHeadersStream* headers_stream() { return headers_stream_; }
-
- const QuicHeadersStream* headers_stream() const { return headers_stream_; }
-
- // Called when the control stream receives HTTP/3 SETTINGS.
- // Returns false in case of 0-RTT if received settings are incompatible with
- // cached values, true otherwise.
- virtual bool OnSettingsFrame(const SettingsFrame& frame);
-
- // Called when an HTTP/3 SETTINGS frame is received via ALPS.
- // Returns an error message if an error has occurred, or nullopt otherwise.
- // May or may not close the connection on error.
- absl::optional<std::string> OnSettingsFrameViaAlps(
- const SettingsFrame& frame);
-
- // Called when a setting is parsed from a SETTINGS frame received on the
- // control stream or from cached application state.
- // Returns true on success.
- // Returns false if received setting is incompatible with cached value (in
- // case of 0-RTT) or with previously received value (in case of ALPS).
- // Also closes the connection on error.
- bool OnSetting(uint64_t id, uint64_t value);
-
- // Return true if this session wants to release headers stream's buffer
- // aggressively.
- virtual bool ShouldReleaseHeadersStreamSequencerBuffer();
-
- void CloseConnectionWithDetails(QuicErrorCode error,
- const std::string& details);
-
- // Must not be called after Initialize().
- // TODO(bnc): Move to constructor argument.
- void set_qpack_maximum_dynamic_table_capacity(
- uint64_t qpack_maximum_dynamic_table_capacity) {
- qpack_maximum_dynamic_table_capacity_ =
- qpack_maximum_dynamic_table_capacity;
- }
-
- // Must not be called after Initialize().
- // TODO(bnc): Move to constructor argument.
- void set_qpack_maximum_blocked_streams(
- uint64_t qpack_maximum_blocked_streams) {
- qpack_maximum_blocked_streams_ = qpack_maximum_blocked_streams;
- }
-
- // Should only be used by IETF QUIC server side.
- // Must not be called after Initialize().
- // TODO(bnc): Move to constructor argument.
- void set_max_inbound_header_list_size(size_t max_inbound_header_list_size) {
- max_inbound_header_list_size_ = max_inbound_header_list_size;
- }
-
- // Must not be called after Initialize().
- void set_allow_extended_connect(bool allow_extended_connect);
-
- size_t max_outbound_header_list_size() const {
- return max_outbound_header_list_size_;
- }
-
- size_t max_inbound_header_list_size() const {
- return max_inbound_header_list_size_;
- }
-
- bool allow_extended_connect() const { return allow_extended_connect_; }
-
- // Returns true if the session has active request streams.
- bool HasActiveRequestStreams() const;
-
- // Called when the size of the compressed frame payload is available.
- void OnCompressedFrameSize(size_t frame_len);
-
- // Called when a PUSH_PROMISE frame has been received.
- // TODO(b/171463363): Remove.
- void OnPushPromise(spdy::SpdyStreamId stream_id,
- spdy::SpdyStreamId promised_stream_id);
-
- // Called when the complete list of headers is available.
- void OnHeaderList(const QuicHeaderList& header_list);
-
- QuicStreamId promised_stream_id() const { return promised_stream_id_; }
-
- // Initialze HTTP/3 unidirectional streams if |unidirectional| is true and
- // 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);
-
- // TODO(b/171463363): Remove.
- // Returns false.
- bool CanCreatePushStreamWithId(PushId push_id);
-
- int32_t destruction_indicator() const { return destruction_indicator_; }
-
- void set_debug_visitor(Http3DebugVisitor* debug_visitor) {
- debug_visitor_ = debug_visitor;
- }
-
- Http3DebugVisitor* debug_visitor() { return debug_visitor_; }
-
- // When using Google QUIC, return whether a transport layer GOAWAY frame has
- // been received or sent.
- // When using IETF QUIC, return whether an HTTP/3 GOAWAY frame has been
- // received or sent.
- bool goaway_received() const;
- bool goaway_sent() const;
-
- // Log header compression ratio histogram.
- // |using_qpack| is true for QPACK, false for HPACK.
- // |is_sent| is true for sent headers, false for received ones.
- // Ratio is recorded as percentage. Smaller value means more efficient
- // compression. Compressed size might be larger than uncompressed size, but
- // recorded ratio is trunckated at 200%.
- // Uncompressed size can be zero for an empty header list, and compressed size
- // can be zero for an empty header list when using HPACK. (QPACK always emits
- // a header block prefix of at least two bytes.) This method records nothing
- // if either |compressed| or |uncompressed| is not positive.
- // In order for measurements for different protocol to be comparable, the
- // caller must ensure that uncompressed size is the total length of header
- // names and values without any overhead.
- static void LogHeaderCompressionRatioHistogram(bool using_qpack, bool is_sent,
- QuicByteCount compressed,
- QuicByteCount uncompressed);
-
- // True if any dynamic table entries have been referenced from either a sent
- // or received header block. Used for stats.
- bool dynamic_table_entry_referenced() const {
- return (qpack_encoder_ &&
- qpack_encoder_->dynamic_table_entry_referenced()) ||
- (qpack_decoder_ && qpack_decoder_->dynamic_table_entry_referenced());
- }
-
- void OnStreamCreated(QuicSpdyStream* stream);
-
- // Decode SETTINGS from |cached_state| and apply it to the session.
- bool ResumeApplicationState(ApplicationState* cached_state) override;
-
- absl::optional<std::string> OnAlpsData(const uint8_t* alps_data,
- size_t alps_length) override;
-
- // Called when ACCEPT_CH frame is parsed out of data received in TLS ALPS
- // extension.
- virtual void OnAcceptChFrameReceivedViaAlps(const AcceptChFrame& /*frame*/);
-
- // Whether HTTP datagrams are supported on this session and which draft is in
- // use, based on received SETTINGS.
- HttpDatagramSupport http_datagram_support() const {
- return http_datagram_support_;
- }
-
- // This must not be used except by QuicSpdyStream::SendHttp3Datagram.
- MessageStatus SendHttp3Datagram(
- QuicDatagramStreamId stream_id,
- absl::optional<QuicDatagramContextId> context_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;
-
- // Indicates whether the HTTP/3 session supports WebTransport.
- bool SupportsWebTransport();
-
- // Indicates whether both the peer and us support HTTP/3 Datagrams.
- bool SupportsH3Datagram() const;
-
- // Indicates whether the HTTP/3 session will indicate WebTransport support to
- // the peer.
- bool WillNegotiateWebTransport();
-
- // Returns a WebTransport session by its session ID. Returns nullptr if no
- // session is associated with the given ID.
- WebTransportHttp3* GetWebTransportSession(WebTransportSessionId id);
-
- // If true, no data on bidirectional streams will be processed by the server
- // until the SETTINGS are received. Only works for HTTP/3.
- bool ShouldBufferRequestsUntilSettings() {
- return version().UsesHttp3() && perspective() == Perspective::IS_SERVER &&
- LocalHttpDatagramSupport() != HttpDatagramSupport::kNone;
- }
-
- // Returns if the incoming bidirectional streams should process data. This is
- // usually true, but in certain cases we would want to wait until the settings
- // are received.
- bool ShouldProcessIncomingRequests();
-
- void OnStreamWaitingForClientSettings(QuicStreamId id);
-
- // Links the specified stream with a WebTransport session. If the session is
- // not present, it is buffered until a corresponding stream is found.
- void AssociateIncomingWebTransportStreamWithSession(
- WebTransportSessionId session_id, QuicStreamId stream_id);
-
- void ProcessBufferedWebTransportStreamsForSession(WebTransportHttp3* session);
-
- bool CanOpenOutgoingUnidirectionalWebTransportStream(
- WebTransportSessionId /*id*/) {
- return CanOpenNextOutgoingUnidirectionalStream();
- }
- bool CanOpenOutgoingBidirectionalWebTransportStream(
- WebTransportSessionId /*id*/) {
- return CanOpenNextOutgoingBidirectionalStream();
- }
-
- // Creates an outgoing unidirectional WebTransport stream. Returns nullptr if
- // the stream cannot be created due to flow control or some other reason.
- WebTransportHttp3UnidirectionalStream*
- CreateOutgoingUnidirectionalWebTransportStream(WebTransportHttp3* session);
-
- // Creates an outgoing bidirectional WebTransport stream. Returns nullptr if
- // the stream cannot be created due to flow control or some other reason.
- QuicSpdyStream* CreateOutgoingBidirectionalWebTransportStream(
- WebTransportHttp3* session);
-
- 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.
- virtual bool ShouldValidateWebTransportVersion() const;
-
- protected:
- // Override CreateIncomingStream(), CreateOutgoingBidirectionalStream() and
- // CreateOutgoingUnidirectionalStream() with QuicSpdyStream return type to
- // make sure that all data streams are QuicSpdyStreams.
- QuicSpdyStream* CreateIncomingStream(QuicStreamId id) override = 0;
- QuicSpdyStream* CreateIncomingStream(PendingStream* pending) override = 0;
- virtual QuicSpdyStream* CreateOutgoingBidirectionalStream() = 0;
- virtual QuicSpdyStream* CreateOutgoingUnidirectionalStream() = 0;
-
- // If an incoming stream can be created, return true.
- virtual bool ShouldCreateIncomingStream(QuicStreamId id) = 0;
-
- // If an outgoing bidirectional/unidirectional stream can be created, return
- // true.
- virtual bool ShouldCreateOutgoingBidirectionalStream() = 0;
- virtual bool ShouldCreateOutgoingUnidirectionalStream() = 0;
-
- // Indicates whether the underlying backend can accept and process
- // WebTransport sessions over HTTP/3.
- virtual bool ShouldNegotiateWebTransport();
-
- // Returns true if there are open HTTP requests.
- bool ShouldKeepConnectionAlive() const override;
-
- // Overridden to buffer incoming unidirectional streams for version 99.
- bool UsesPendingStreamForFrame(QuicFrameType type,
- QuicStreamId stream_id) const override;
-
- // Processes incoming unidirectional streams; parses the stream type, and
- // creates a new stream of the corresponding type. Returns the pointer to the
- // newly created stream, or nullptr if the stream type is not yet available.
- QuicStream* ProcessPendingStream(PendingStream* pending) override;
-
- size_t WriteHeadersOnHeadersStreamImpl(
- QuicStreamId id, spdy::SpdyHeaderBlock headers, bool fin,
- QuicStreamId parent_stream_id, int weight, bool exclusive,
- QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener);
-
- void OnNewEncryptionKeyAvailable(
- EncryptionLevel level, std::unique_ptr<QuicEncrypter> encrypter) override;
-
- // Sets the maximum size of the header compression table spdy_framer_ is
- // willing to use to encode header blocks.
- void UpdateHeaderEncoderTableSize(uint32_t value);
-
- bool IsConnected() { return connection()->connected(); }
-
- const QuicReceiveControlStream* receive_control_stream() const {
- return receive_control_stream_;
- }
-
- const SettingsFrame& settings() const { return settings_; }
-
- // Initializes HTTP/3 unidirectional streams if not yet initialzed.
- virtual void MaybeInitializeHttp3UnidirectionalStreams();
-
- // QuicConnectionVisitorInterface method.
- void BeforeConnectionCloseSent() override;
-
- // Called whenever a datagram is dequeued or dropped from datagram_queue().
- virtual void OnDatagramProcessed(absl::optional<MessageStatus> status);
-
- // Returns which version of the HTTP/3 datagram extension we should advertise
- // in settings and accept remote settings for.
- virtual HttpDatagramSupport LocalHttpDatagramSupport();
-
- private:
- friend class test::QuicSpdySessionPeer;
-
- class SpdyFramerVisitor;
-
- // Proxies OnDatagramProcessed() calls to the session.
- class QUIC_EXPORT_PRIVATE DatagramObserver
- : public QuicDatagramQueue::Observer {
- public:
- explicit DatagramObserver(QuicSpdySession* session) : session_(session) {}
- void OnDatagramProcessed(absl::optional<MessageStatus> status) override;
-
- private:
- QuicSpdySession* session_; // not owned
- };
-
- struct QUIC_EXPORT_PRIVATE BufferedWebTransportStream {
- WebTransportSessionId session_id;
- QuicStreamId stream_id;
- };
-
- // The following methods are called by the SimpleVisitor.
-
- // Called when a HEADERS frame has been received.
- void OnHeaders(spdy::SpdyStreamId stream_id, bool has_priority,
- const spdy::SpdyStreamPrecedence& precedence, bool fin);
-
- // Called when a PRIORITY frame has been received.
- void OnPriority(spdy::SpdyStreamId stream_id,
- const spdy::SpdyStreamPrecedence& precedence);
-
- 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);
-
- std::unique_ptr<QpackEncoder> qpack_encoder_;
- std::unique_ptr<QpackDecoder> qpack_decoder_;
-
- // Pointer to the header stream in stream_map_.
- QuicHeadersStream* headers_stream_;
-
- // HTTP/3 control streams. They are owned by QuicSession inside
- // stream map, and can be accessed by those unowned pointers below.
- QuicSendControlStream* send_control_stream_;
- QuicReceiveControlStream* receive_control_stream_;
-
- // Pointers to HTTP/3 QPACK streams in stream map.
- QpackReceiveStream* qpack_encoder_receive_stream_;
- QpackReceiveStream* qpack_decoder_receive_stream_;
- QpackSendStream* qpack_encoder_send_stream_;
- QpackSendStream* qpack_decoder_send_stream_;
-
- SettingsFrame settings_;
-
- // Maximum dynamic table capacity as defined at
- // https://quicwg.org/base-drafts/draft-ietf-quic-qpack.html#maximum-dynamic-table-capacity
- // for the decoding context. Value will be sent via
- // SETTINGS_QPACK_MAX_TABLE_CAPACITY.
- // |qpack_maximum_dynamic_table_capacity_| also serves as an upper bound for
- // the dynamic table capacity of the encoding context, to limit memory usage
- // if a larger SETTINGS_QPACK_MAX_TABLE_CAPACITY value is received.
- uint64_t qpack_maximum_dynamic_table_capacity_;
-
- // Maximum number of blocked streams as defined at
- // https://quicwg.org/base-drafts/draft-ietf-quic-qpack.html#blocked-streams
- // for the decoding context. Value will be sent via
- // SETTINGS_QPACK_BLOCKED_STREAMS.
- uint64_t qpack_maximum_blocked_streams_;
-
- // The maximum size of a header block that will be accepted from the peer,
- // defined per spec as key + value + overhead per field (uncompressed).
- // Value will be sent via SETTINGS_MAX_HEADER_LIST_SIZE.
- size_t max_inbound_header_list_size_;
-
- // The maximum size of a header block that can be sent to the peer. This field
- // is informed and set by the peer via SETTINGS frame.
- // TODO(b/148616439): Honor this field when sending headers.
- size_t max_outbound_header_list_size_;
-
- // Data about the stream whose headers are being processed.
- QuicStreamId stream_id_;
- QuicStreamId promised_stream_id_;
- size_t frame_len_;
- bool fin_;
-
- spdy::SpdyFramer spdy_framer_;
- 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_;
-
- // Priority values received in PRIORITY_UPDATE frames for streams that are not
- // open yet.
- absl::flat_hash_map<QuicStreamId, int> buffered_stream_priorities_;
-
- // An integer used for live check. The indicator is assigned a value in
- // constructor. As long as it is not the assigned value, that would indicate
- // an use-after-free.
- int32_t destruction_indicator_;
-
- // The identifier in the most recently received GOAWAY frame. Unset if no
- // GOAWAY frame has been received yet.
- absl::optional<uint64_t> last_received_http3_goaway_id_;
- // The identifier in the most recently sent GOAWAY frame. Unset if no GOAWAY
- // frame has been sent yet.
- absl::optional<uint64_t> last_sent_http3_goaway_id_;
-
- // Whether both this endpoint and our peer support HTTP datagrams and which
- // draft is in use for this session.
- HttpDatagramSupport http_datagram_support_ = HttpDatagramSupport::kNone;
-
- // 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;
-
- // If ShouldBufferRequestsUntilSettings() is true, all streams that are
- // blocked by that are tracked here.
- absl::flat_hash_set<QuicStreamId> streams_waiting_for_settings_;
-
- // WebTransport streams that do not have a session associated with them.
- // Limited to kMaxUnassociatedWebTransportStreams; when the list is full,
- // oldest streams are evicated first.
- std::list<BufferedWebTransportStream> buffered_streams_;
-
- // On the server side, if true, advertise and accept extended CONNECT method.
- // On the client side, true if the peer advertised extended CONNECT.
- bool allow_extended_connect_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_HTTP_QUIC_SPDY_SESSION_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_session_test.cc b/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_session_test.cc
deleted file mode 100644
index 45506211f9d..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_session_test.cc
+++ /dev/null
@@ -1,3824 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/http/quic_spdy_session.h"
-
-#include <cstdint>
-#include <limits>
-#include <set>
-#include <string>
-#include <utility>
-
-#include "absl/base/macros.h"
-#include "absl/memory/memory.h"
-#include "absl/strings/escaping.h"
-#include "absl/strings/str_cat.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/crypto/crypto_protocol.h"
-#include "quic/core/crypto/null_encrypter.h"
-#include "quic/core/frames/quic_stream_frame.h"
-#include "quic/core/frames/quic_streams_blocked_frame.h"
-#include "quic/core/http/http_constants.h"
-#include "quic/core/http/http_encoder.h"
-#include "quic/core/http/quic_header_list.h"
-#include "quic/core/http/web_transport_http3.h"
-#include "quic/core/qpack/qpack_header_table.h"
-#include "quic/core/quic_config.h"
-#include "quic/core/quic_crypto_stream.h"
-#include "quic/core/quic_data_writer.h"
-#include "quic/core/quic_error_codes.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_stream.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_utils.h"
-#include "quic/core/quic_versions.h"
-#include "quic/platform/api/quic_expect_bug.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/qpack/qpack_encoder_peer.h"
-#include "quic/test_tools/qpack/qpack_test_utils.h"
-#include "quic/test_tools/quic_config_peer.h"
-#include "quic/test_tools/quic_connection_peer.h"
-#include "quic/test_tools/quic_flow_controller_peer.h"
-#include "quic/test_tools/quic_session_peer.h"
-#include "quic/test_tools/quic_spdy_session_peer.h"
-#include "quic/test_tools/quic_stream_peer.h"
-#include "quic/test_tools/quic_stream_send_buffer_peer.h"
-#include "quic/test_tools/quic_test_utils.h"
-#include "common/quiche_endian.h"
-#include "common/test_tools/quiche_test_utils.h"
-#include "spdy/core/spdy_framer.h"
-
-using spdy::kV3HighestPriority;
-using spdy::Spdy3PriorityToHttp2Weight;
-using spdy::SpdyFramer;
-using spdy::SpdyHeaderBlock;
-using spdy::SpdyPriority;
-using spdy::SpdyPriorityIR;
-using spdy::SpdySerializedFrame;
-using ::testing::_;
-using ::testing::AnyNumber;
-using ::testing::AtLeast;
-using ::testing::ElementsAre;
-using ::testing::InSequence;
-using ::testing::Invoke;
-using ::testing::Return;
-using ::testing::StrictMock;
-
-namespace quic {
-namespace test {
-namespace {
-
-bool VerifyAndClearStopSendingFrame(const QuicFrame& frame) {
- EXPECT_EQ(STOP_SENDING_FRAME, frame.type);
- return ClearControlFrame(frame);
-}
-
-class TestCryptoStream : public QuicCryptoStream, public QuicCryptoHandshaker {
- public:
- explicit TestCryptoStream(QuicSession* session)
- : QuicCryptoStream(session),
- QuicCryptoHandshaker(this, session),
- encryption_established_(false),
- one_rtt_keys_available_(false),
- params_(new QuicCryptoNegotiatedParameters) {
- // Simulate a negotiated cipher_suite with a fake value.
- params_->cipher_suite = 1;
- }
-
- void EstablishZeroRttEncryption() {
- encryption_established_ = true;
- session()->connection()->SetEncrypter(
- ENCRYPTION_ZERO_RTT,
- std::make_unique<NullEncrypter>(session()->perspective()));
- }
-
- void OnHandshakeMessage(const CryptoHandshakeMessage& /*message*/) override {
- encryption_established_ = true;
- one_rtt_keys_available_ = true;
- QuicErrorCode error;
- std::string error_details;
- session()->config()->SetInitialStreamFlowControlWindowToSend(
- kInitialStreamFlowControlWindowForTest);
- session()->config()->SetInitialSessionFlowControlWindowToSend(
- kInitialSessionFlowControlWindowForTest);
- if (session()->version().UsesTls()) {
- if (session()->perspective() == Perspective::IS_CLIENT) {
- session()->config()->SetOriginalConnectionIdToSend(
- session()->connection()->connection_id());
- session()->config()->SetInitialSourceConnectionIdToSend(
- session()->connection()->connection_id());
- } else {
- session()->config()->SetInitialSourceConnectionIdToSend(
- session()->connection()->client_connection_id());
- }
- TransportParameters transport_parameters;
- EXPECT_TRUE(
- session()->config()->FillTransportParameters(&transport_parameters));
- error = session()->config()->ProcessTransportParameters(
- transport_parameters, /* is_resumption = */ false, &error_details);
- } else {
- CryptoHandshakeMessage msg;
- session()->config()->ToHandshakeMessage(&msg, transport_version());
- error =
- session()->config()->ProcessPeerHello(msg, CLIENT, &error_details);
- }
- EXPECT_THAT(error, IsQuicNoError());
- session()->OnNewEncryptionKeyAvailable(
- ENCRYPTION_FORWARD_SECURE,
- std::make_unique<NullEncrypter>(session()->perspective()));
- session()->OnConfigNegotiated();
- if (session()->connection()->version().handshake_protocol ==
- PROTOCOL_TLS1_3) {
- session()->OnTlsHandshakeComplete();
- } else {
- session()->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
- }
- session()->DiscardOldEncryptionKey(ENCRYPTION_INITIAL);
- }
-
- // QuicCryptoStream implementation
- ssl_early_data_reason_t EarlyDataReason() const override {
- return ssl_early_data_unknown;
- }
- bool encryption_established() const override {
- return encryption_established_;
- }
- bool one_rtt_keys_available() const override {
- return one_rtt_keys_available_;
- }
- HandshakeState GetHandshakeState() const override {
- return one_rtt_keys_available() ? HANDSHAKE_COMPLETE : HANDSHAKE_START;
- }
- void SetServerApplicationStateForResumption(
- std::unique_ptr<ApplicationState> /*application_state*/) override {}
- std::unique_ptr<QuicDecrypter> AdvanceKeysAndCreateCurrentOneRttDecrypter()
- override {
- return nullptr;
- }
- std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() override {
- return nullptr;
- }
- const QuicCryptoNegotiatedParameters& crypto_negotiated_params()
- const override {
- return *params_;
- }
- CryptoMessageParser* crypto_message_parser() override {
- return QuicCryptoHandshaker::crypto_message_parser();
- }
- void OnPacketDecrypted(EncryptionLevel /*level*/) override {}
- void OnOneRttPacketAcknowledged() override {}
- void OnHandshakePacketSent() override {}
- void OnHandshakeDoneReceived() override {}
- void OnNewTokenReceived(absl::string_view /*token*/) override {}
- std::string GetAddressToken(
- const CachedNetworkParameters* /*cached_network_params*/) const override {
- return "";
- }
- bool ValidateAddressToken(absl::string_view /*token*/) const override {
- return true;
- }
- const CachedNetworkParameters* PreviousCachedNetworkParams() const override {
- return nullptr;
- }
- void SetPreviousCachedNetworkParams(
- CachedNetworkParameters /*cached_network_params*/) override {}
-
- MOCK_METHOD(void, OnCanWrite, (), (override));
-
- bool HasPendingCryptoRetransmission() const override { return false; }
-
- MOCK_METHOD(bool, HasPendingRetransmission, (), (const, override));
-
- void OnConnectionClosed(QuicErrorCode /*error*/,
- ConnectionCloseSource /*source*/) override {}
- SSL* GetSsl() const override { return nullptr; }
-
- bool ExportKeyingMaterial(absl::string_view /*label*/,
- absl::string_view /*context*/,
- size_t /*result_len*/,
- std::string* /*result*/) override {
- return false;
- }
-
- private:
- using QuicCryptoStream::session;
-
- bool encryption_established_;
- bool one_rtt_keys_available_;
- QuicReferenceCountedPointer<QuicCryptoNegotiatedParameters> params_;
-};
-
-class TestHeadersStream : public QuicHeadersStream {
- public:
- explicit TestHeadersStream(QuicSpdySession* session)
- : QuicHeadersStream(session) {}
-
- MOCK_METHOD(void, OnCanWrite, (), (override));
-};
-
-class TestStream : public QuicSpdyStream {
- public:
- TestStream(QuicStreamId id, QuicSpdySession* session, StreamType type)
- : QuicSpdyStream(id, session, type) {}
-
- TestStream(PendingStream* pending, QuicSpdySession* session)
- : QuicSpdyStream(pending, session) {}
-
- using QuicStream::CloseWriteSide;
-
- void OnBodyAvailable() override {}
-
- MOCK_METHOD(void, OnCanWrite, (), (override));
- MOCK_METHOD(bool, RetransmitStreamData,
- (QuicStreamOffset, QuicByteCount, bool, TransmissionType),
- (override));
-
- MOCK_METHOD(bool, HasPendingRetransmission, (), (const, override));
-
- protected:
- bool AreHeadersValid(const QuicHeaderList& /*header_list*/) const override {
- return true;
- }
-};
-
-class TestSession : public QuicSpdySession {
- public:
- explicit TestSession(QuicConnection* connection)
- : QuicSpdySession(connection, nullptr, DefaultQuicConfig(),
- CurrentSupportedVersions()),
- crypto_stream_(this),
- writev_consumes_all_data_(false) {
- this->connection()->SetEncrypter(
- ENCRYPTION_FORWARD_SECURE,
- std::make_unique<NullEncrypter>(connection->perspective()));
- if (this->connection()->version().SupportsAntiAmplificationLimit()) {
- QuicConnectionPeer::SetAddressValidated(this->connection());
- }
- }
-
- ~TestSession() override { DeleteConnection(); }
-
- TestCryptoStream* GetMutableCryptoStream() override {
- return &crypto_stream_;
- }
-
- const TestCryptoStream* GetCryptoStream() const override {
- return &crypto_stream_;
- }
-
- TestStream* CreateOutgoingBidirectionalStream() override {
- TestStream* stream = new TestStream(GetNextOutgoingBidirectionalStreamId(),
- this, BIDIRECTIONAL);
- ActivateStream(absl::WrapUnique(stream));
- return stream;
- }
-
- TestStream* CreateOutgoingUnidirectionalStream() override {
- TestStream* stream = new TestStream(GetNextOutgoingUnidirectionalStreamId(),
- this, WRITE_UNIDIRECTIONAL);
- ActivateStream(absl::WrapUnique(stream));
- return stream;
- }
-
- TestStream* CreateIncomingStream(QuicStreamId id) override {
- // Enforce the limit on the number of open streams.
- if (!VersionHasIetfQuicFrames(connection()->transport_version()) &&
- stream_id_manager().num_open_incoming_streams() + 1 >
- max_open_incoming_bidirectional_streams()) {
- connection()->CloseConnection(
- QUIC_TOO_MANY_OPEN_STREAMS, "Too many streams!",
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
- return nullptr;
- } else {
- TestStream* stream = new TestStream(
- id, this,
- DetermineStreamType(id, connection()->version(), perspective(),
- /*is_incoming=*/true, BIDIRECTIONAL));
- ActivateStream(absl::WrapUnique(stream));
- return stream;
- }
- }
-
- TestStream* CreateIncomingStream(PendingStream* pending) override {
- TestStream* stream = new TestStream(pending, this);
- ActivateStream(absl::WrapUnique(stream));
- return stream;
- }
-
- bool ShouldCreateIncomingStream(QuicStreamId /*id*/) override { return true; }
-
- bool ShouldCreateOutgoingBidirectionalStream() override { return true; }
- bool ShouldCreateOutgoingUnidirectionalStream() override { return true; }
-
- bool IsClosedStream(QuicStreamId id) {
- return QuicSession::IsClosedStream(id);
- }
-
- QuicStream* GetOrCreateStream(QuicStreamId stream_id) {
- return QuicSpdySession::GetOrCreateStream(stream_id);
- }
-
- QuicConsumedData WritevData(QuicStreamId id, size_t write_length,
- QuicStreamOffset offset, StreamSendingState state,
- TransmissionType type,
- EncryptionLevel level) override {
- bool fin = state != NO_FIN;
- QuicConsumedData consumed(write_length, fin);
- if (!writev_consumes_all_data_) {
- consumed =
- QuicSession::WritevData(id, write_length, offset, state, type, level);
- }
- QuicSessionPeer::GetWriteBlockedStreams(this)->UpdateBytesForStream(
- id, consumed.bytes_consumed);
- return consumed;
- }
-
- void set_writev_consumes_all_data(bool val) {
- writev_consumes_all_data_ = val;
- }
-
- QuicConsumedData SendStreamData(QuicStream* stream) {
- struct iovec iov;
- if (!QuicUtils::IsCryptoStreamId(connection()->transport_version(),
- stream->id()) &&
- connection()->encryption_level() != ENCRYPTION_FORWARD_SECURE) {
- this->connection()->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
- }
- MakeIOVector("not empty", &iov);
- QuicStreamPeer::SendBuffer(stream).SaveStreamData(&iov, 1, 0, 9);
- QuicConsumedData consumed =
- WritevData(stream->id(), 9, 0, FIN, NOT_RETRANSMISSION,
- GetEncryptionLevelToSendApplicationData());
- QuicStreamPeer::SendBuffer(stream).OnStreamDataConsumed(
- consumed.bytes_consumed);
- return consumed;
- }
-
- QuicConsumedData SendLargeFakeData(QuicStream* stream, int bytes) {
- QUICHE_DCHECK(writev_consumes_all_data_);
- return WritevData(stream->id(), bytes, 0, FIN, NOT_RETRANSMISSION,
- GetEncryptionLevelToSendApplicationData());
- }
-
- bool ShouldNegotiateWebTransport() override { return supports_webtransport_; }
- void set_supports_webtransport(bool value) { supports_webtransport_ = value; }
-
- HttpDatagramSupport LocalHttpDatagramSupport() override {
- return local_http_datagram_support_;
- }
- void set_local_http_datagram_support(HttpDatagramSupport value) {
- local_http_datagram_support_ = value;
- }
-
- MOCK_METHOD(void, OnAcceptChFrame, (const AcceptChFrame&), (override));
-
- using QuicSession::closed_streams;
- using QuicSession::ShouldKeepConnectionAlive;
- using QuicSpdySession::ProcessPendingStream;
- using QuicSpdySession::UsesPendingStreamForFrame;
-
- private:
- StrictMock<TestCryptoStream> crypto_stream_;
-
- bool writev_consumes_all_data_;
- bool supports_webtransport_ = false;
- HttpDatagramSupport local_http_datagram_support_ = HttpDatagramSupport::kNone;
-};
-
-class QuicSpdySessionTestBase : public QuicTestWithParam<ParsedQuicVersion> {
- public:
- bool ClearMaxStreamsControlFrame(const QuicFrame& frame) {
- if (frame.type == MAX_STREAMS_FRAME) {
- DeleteFrame(&const_cast<QuicFrame&>(frame));
- return true;
- }
- return false;
- }
-
- protected:
- explicit QuicSpdySessionTestBase(Perspective perspective,
- bool allow_extended_connect)
- : connection_(new StrictMock<MockQuicConnection>(
- &helper_, &alarm_factory_, perspective,
- SupportedVersions(GetParam()))),
- session_(connection_) {
- if (perspective == Perspective::IS_SERVER &&
- VersionUsesHttp3(transport_version()) &&
- GetQuicReloadableFlag(quic_verify_request_headers_2)) {
- session_.set_allow_extended_connect(allow_extended_connect);
- }
- session_.Initialize();
- session_.config()->SetInitialStreamFlowControlWindowToSend(
- kInitialStreamFlowControlWindowForTest);
- session_.config()->SetInitialSessionFlowControlWindowToSend(
- kInitialSessionFlowControlWindowForTest);
- if (VersionUsesHttp3(transport_version())) {
- QuicConfigPeer::SetReceivedMaxUnidirectionalStreams(
- session_.config(), kHttp3StaticUnidirectionalStreamCount);
- }
- QuicConfigPeer::SetReceivedInitialSessionFlowControlWindow(
- session_.config(), kMinimumFlowControlSendWindow);
- QuicConfigPeer::SetReceivedInitialMaxStreamDataBytesUnidirectional(
- session_.config(), kMinimumFlowControlSendWindow);
- QuicConfigPeer::SetReceivedInitialMaxStreamDataBytesIncomingBidirectional(
- session_.config(), kMinimumFlowControlSendWindow);
- QuicConfigPeer::SetReceivedInitialMaxStreamDataBytesOutgoingBidirectional(
- session_.config(), kMinimumFlowControlSendWindow);
- session_.OnConfigNegotiated();
- connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
- TestCryptoStream* crypto_stream = session_.GetMutableCryptoStream();
- EXPECT_CALL(*crypto_stream, HasPendingRetransmission())
- .Times(testing::AnyNumber());
- writer_ = static_cast<MockPacketWriter*>(
- QuicConnectionPeer::GetWriter(session_.connection()));
- }
-
- void CheckClosedStreams() {
- QuicStreamId first_stream_id = QuicUtils::GetFirstBidirectionalStreamId(
- transport_version(), Perspective::IS_CLIENT);
- if (!QuicVersionUsesCryptoFrames(transport_version())) {
- first_stream_id = QuicUtils::GetCryptoStreamId(transport_version());
- }
- for (QuicStreamId i = first_stream_id; i < 100; i++) {
- if (closed_streams_.find(i) == closed_streams_.end()) {
- EXPECT_FALSE(session_.IsClosedStream(i)) << " stream id: " << i;
- } else {
- EXPECT_TRUE(session_.IsClosedStream(i)) << " stream id: " << i;
- }
- }
- }
-
- void CloseStream(QuicStreamId id) {
- if (!VersionHasIetfQuicFrames(transport_version())) {
- EXPECT_CALL(*connection_, SendControlFrame(_))
- .WillOnce(Invoke(&ClearControlFrame));
- } else {
- // IETF QUIC has two frames, RST_STREAM and STOP_SENDING
- EXPECT_CALL(*connection_, SendControlFrame(_))
- .Times(2)
- .WillRepeatedly(Invoke(&ClearControlFrame));
- }
- EXPECT_CALL(*connection_, OnStreamReset(id, _));
-
- // QPACK streams might write data upon stream reset. Let the test session
- // handle the data.
- session_.set_writev_consumes_all_data(true);
-
- session_.ResetStream(id, QUIC_STREAM_CANCELLED);
- closed_streams_.insert(id);
- }
-
- ParsedQuicVersion version() const { return connection_->version(); }
-
- QuicTransportVersion transport_version() const {
- return connection_->transport_version();
- }
-
- QuicStreamId GetNthClientInitiatedBidirectionalId(int n) {
- return GetNthClientInitiatedBidirectionalStreamId(transport_version(), n);
- }
-
- QuicStreamId GetNthServerInitiatedBidirectionalId(int n) {
- return GetNthServerInitiatedBidirectionalStreamId(transport_version(), n);
- }
-
- QuicStreamId IdDelta() {
- return QuicUtils::StreamIdDelta(transport_version());
- }
-
- std::string EncodeSettings(const SettingsFrame& settings) {
- std::unique_ptr<char[]> buffer;
- auto header_length = HttpEncoder::SerializeSettingsFrame(settings, &buffer);
- return std::string(buffer.get(), header_length);
- }
-
- std::string SerializePriorityUpdateFrame(
- const PriorityUpdateFrame& priority_update) {
- std::unique_ptr<char[]> priority_buffer;
- QuicByteCount priority_frame_length =
- HttpEncoder::SerializePriorityUpdateFrame(priority_update,
- &priority_buffer);
- 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
- // GetFirst... because the test that relies on this method
- // needs to do the stream count where #1 is 0/1/2/3, and not
- // take into account that stream 0 is special.
- QuicStreamId id =
- ((stream_count - 1) * QuicUtils::StreamIdDelta(transport_version()));
- if (!bidirectional) {
- id |= 0x2;
- }
- if (perspective == Perspective::IS_SERVER) {
- id |= 0x1;
- }
- return id;
- }
-
- void CompleteHandshake() {
- if (VersionHasIetfQuicFrames(transport_version())) {
- EXPECT_CALL(*writer_, WritePacket(_, _, _, _, _))
- .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 0)));
- }
- if (connection_->version().UsesTls() &&
- connection_->perspective() == Perspective::IS_SERVER) {
- // HANDSHAKE_DONE frame.
- EXPECT_CALL(*connection_, SendControlFrame(_))
- .WillOnce(Invoke(&ClearControlFrame));
- }
-
- CryptoHandshakeMessage message;
- session_.GetMutableCryptoStream()->OnHandshakeMessage(message);
- testing::Mock::VerifyAndClearExpectations(writer_);
- testing::Mock::VerifyAndClearExpectations(connection_);
- }
-
- void ReceiveWebTransportSettings() {
- SettingsFrame settings;
- settings.values[SETTINGS_H3_DATAGRAM_DRAFT04] = 1;
- settings.values[SETTINGS_WEBTRANS_DRAFT00] = 1;
- settings.values[SETTINGS_ENABLE_CONNECT_PROTOCOL] = 1;
- std::string data =
- std::string(1, kControlStream) + EncodeSettings(settings);
- QuicStreamId control_stream_id =
- session_.perspective() == Perspective::IS_SERVER
- ? GetNthClientInitiatedUnidirectionalStreamId(transport_version(),
- 3)
- : GetNthServerInitiatedUnidirectionalStreamId(transport_version(),
- 3);
- QuicStreamFrame frame(control_stream_id, /*fin=*/false, /*offset=*/0, data);
- session_.OnStreamFrame(frame);
- }
-
- void ReceiveWebTransportSession(WebTransportSessionId session_id) {
- QuicStreamFrame frame(session_id, /*fin=*/false, /*offset=*/0,
- absl::string_view());
- session_.OnStreamFrame(frame);
- QuicSpdyStream* stream =
- static_cast<QuicSpdyStream*>(session_.GetOrCreateStream(session_id));
- QuicHeaderList headers;
- 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");
- }
- 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);
- spdy::SpdyHeaderBlock header_block;
- web_transport->HeadersReceived(header_block);
- }
-
- void ReceiveWebTransportUnidirectionalStream(WebTransportSessionId session_id,
- QuicStreamId stream_id) {
- char buffer[256];
- QuicDataWriter data_writer(sizeof(buffer), buffer);
- ASSERT_TRUE(data_writer.WriteVarInt62(kWebTransportUnidirectionalStream));
- ASSERT_TRUE(data_writer.WriteVarInt62(session_id));
- ASSERT_TRUE(data_writer.WriteStringPiece("test data"));
- std::string data(buffer, data_writer.length());
- QuicStreamFrame frame(stream_id, /*fin=*/false, /*offset=*/0, data);
- session_.OnStreamFrame(frame);
- }
-
- void TestHttpDatagramSetting(HttpDatagramSupport local_support,
- HttpDatagramSupport remote_support,
- HttpDatagramSupport expected_support,
- bool expected_datagram_supported);
-
- MockQuicConnectionHelper helper_;
- MockAlarmFactory alarm_factory_;
- StrictMock<MockQuicConnection>* connection_;
- TestSession session_;
- std::set<QuicStreamId> closed_streams_;
- MockPacketWriter* writer_;
-};
-
-class QuicSpdySessionTestServer : public QuicSpdySessionTestBase {
- protected:
- QuicSpdySessionTestServer()
- : QuicSpdySessionTestBase(Perspective::IS_SERVER, true) {}
-};
-
-INSTANTIATE_TEST_SUITE_P(Tests, QuicSpdySessionTestServer,
- ::testing::ValuesIn(AllSupportedVersions()),
- ::testing::PrintToStringParamName());
-
-TEST_P(QuicSpdySessionTestServer, UsesPendingStreamsForFrame) {
- if (!VersionUsesHttp3(transport_version())) {
- return;
- }
- EXPECT_TRUE(session_.UsesPendingStreamForFrame(
- STREAM_FRAME, QuicUtils::GetFirstUnidirectionalStreamId(
- transport_version(), Perspective::IS_CLIENT)));
- EXPECT_TRUE(session_.UsesPendingStreamForFrame(
- RST_STREAM_FRAME, QuicUtils::GetFirstUnidirectionalStreamId(
- transport_version(), Perspective::IS_CLIENT)));
- EXPECT_FALSE(session_.UsesPendingStreamForFrame(
- RST_STREAM_FRAME, QuicUtils::GetFirstUnidirectionalStreamId(
- transport_version(), Perspective::IS_SERVER)));
- EXPECT_FALSE(session_.UsesPendingStreamForFrame(
- STOP_SENDING_FRAME, QuicUtils::GetFirstUnidirectionalStreamId(
- transport_version(), Perspective::IS_CLIENT)));
- EXPECT_FALSE(session_.UsesPendingStreamForFrame(
- RST_STREAM_FRAME, QuicUtils::GetFirstBidirectionalStreamId(
- transport_version(), Perspective::IS_CLIENT)));
-}
-
-TEST_P(QuicSpdySessionTestServer, PeerAddress) {
- EXPECT_EQ(QuicSocketAddress(QuicIpAddress::Loopback4(), kTestPort),
- session_.peer_address());
-}
-
-TEST_P(QuicSpdySessionTestServer, SelfAddress) {
- EXPECT_TRUE(session_.self_address().IsInitialized());
-}
-
-TEST_P(QuicSpdySessionTestServer, OneRttKeysAvailable) {
- EXPECT_FALSE(session_.OneRttKeysAvailable());
- CompleteHandshake();
- EXPECT_TRUE(session_.OneRttKeysAvailable());
-}
-
-TEST_P(QuicSpdySessionTestServer, IsClosedStreamDefault) {
- // Ensure that no streams are initially closed.
- QuicStreamId first_stream_id = QuicUtils::GetFirstBidirectionalStreamId(
- transport_version(), Perspective::IS_CLIENT);
- if (!QuicVersionUsesCryptoFrames(transport_version())) {
- first_stream_id = QuicUtils::GetCryptoStreamId(transport_version());
- }
- for (QuicStreamId i = first_stream_id; i < 100; i++) {
- EXPECT_FALSE(session_.IsClosedStream(i)) << "stream id: " << i;
- }
-}
-
-TEST_P(QuicSpdySessionTestServer, AvailableStreams) {
- ASSERT_TRUE(session_.GetOrCreateStream(
- GetNthClientInitiatedBidirectionalId(2)) != nullptr);
- // Both client initiated streams with smaller stream IDs are available.
- EXPECT_TRUE(QuicSessionPeer::IsStreamAvailable(
- &session_, GetNthClientInitiatedBidirectionalId(0)));
- EXPECT_TRUE(QuicSessionPeer::IsStreamAvailable(
- &session_, GetNthClientInitiatedBidirectionalId(1)));
- ASSERT_TRUE(session_.GetOrCreateStream(
- GetNthClientInitiatedBidirectionalId(1)) != nullptr);
- ASSERT_TRUE(session_.GetOrCreateStream(
- GetNthClientInitiatedBidirectionalId(0)) != nullptr);
-}
-
-TEST_P(QuicSpdySessionTestServer, IsClosedStreamLocallyCreated) {
- CompleteHandshake();
- TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
- EXPECT_EQ(GetNthServerInitiatedBidirectionalId(0), stream2->id());
- QuicSpdyStream* stream4 = session_.CreateOutgoingBidirectionalStream();
- EXPECT_EQ(GetNthServerInitiatedBidirectionalId(1), stream4->id());
-
- CheckClosedStreams();
- CloseStream(GetNthServerInitiatedBidirectionalId(0));
- CheckClosedStreams();
- CloseStream(GetNthServerInitiatedBidirectionalId(1));
- CheckClosedStreams();
-}
-
-TEST_P(QuicSpdySessionTestServer, IsClosedStreamPeerCreated) {
- CompleteHandshake();
- QuicStreamId stream_id1 = GetNthClientInitiatedBidirectionalId(0);
- QuicStreamId stream_id2 = GetNthClientInitiatedBidirectionalId(1);
- session_.GetOrCreateStream(stream_id1);
- session_.GetOrCreateStream(stream_id2);
-
- CheckClosedStreams();
- CloseStream(stream_id1);
- CheckClosedStreams();
- CloseStream(stream_id2);
- // Create a stream, and make another available.
- QuicStream* stream3 = session_.GetOrCreateStream(stream_id2 + 4);
- CheckClosedStreams();
- // Close one, but make sure the other is still not closed
- CloseStream(stream3->id());
- CheckClosedStreams();
-}
-
-TEST_P(QuicSpdySessionTestServer, MaximumAvailableOpenedStreams) {
- if (VersionHasIetfQuicFrames(transport_version())) {
- // For IETF QUIC, we should be able to obtain the max allowed
- // stream ID, the next ID should fail. Since the actual limit
- // is not the number of open streams, we allocate the max and the max+2.
- // Get the max allowed stream ID, this should succeed.
- QuicStreamId stream_id = StreamCountToId(
- QuicSessionPeer::ietf_streamid_manager(&session_)
- ->max_incoming_bidirectional_streams(),
- Perspective::IS_CLIENT, // Client initates stream, allocs stream id.
- /*bidirectional=*/true);
- EXPECT_NE(nullptr, session_.GetOrCreateStream(stream_id));
- stream_id =
- StreamCountToId(QuicSessionPeer::ietf_streamid_manager(&session_)
- ->max_incoming_unidirectional_streams(),
- Perspective::IS_CLIENT,
- /*bidirectional=*/false);
- EXPECT_NE(nullptr, session_.GetOrCreateStream(stream_id));
- EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(2);
- // Get the (max allowed stream ID)++. These should all fail.
- stream_id =
- StreamCountToId(QuicSessionPeer::ietf_streamid_manager(&session_)
- ->max_incoming_bidirectional_streams() +
- 1,
- Perspective::IS_CLIENT,
- /*bidirectional=*/true);
- EXPECT_EQ(nullptr, session_.GetOrCreateStream(stream_id));
-
- stream_id =
- StreamCountToId(QuicSessionPeer::ietf_streamid_manager(&session_)
- ->max_incoming_unidirectional_streams() +
- 1,
- Perspective::IS_CLIENT,
- /*bidirectional=*/false);
- EXPECT_EQ(nullptr, session_.GetOrCreateStream(stream_id));
- } else {
- QuicStreamId stream_id = GetNthClientInitiatedBidirectionalId(0);
- session_.GetOrCreateStream(stream_id);
- EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
- EXPECT_NE(
- nullptr,
- session_.GetOrCreateStream(
- stream_id +
- IdDelta() *
- (session_.max_open_incoming_bidirectional_streams() - 1)));
- }
-}
-
-TEST_P(QuicSpdySessionTestServer, TooManyAvailableStreams) {
- QuicStreamId stream_id1 = GetNthClientInitiatedBidirectionalId(0);
- QuicStreamId stream_id2;
- EXPECT_NE(nullptr, session_.GetOrCreateStream(stream_id1));
- // A stream ID which is too large to create.
- stream_id2 = GetNthClientInitiatedBidirectionalId(
- 2 * session_.MaxAvailableBidirectionalStreams() + 4);
- if (VersionHasIetfQuicFrames(transport_version())) {
- EXPECT_CALL(*connection_, CloseConnection(QUIC_INVALID_STREAM_ID, _, _));
- } else {
- EXPECT_CALL(*connection_,
- CloseConnection(QUIC_TOO_MANY_AVAILABLE_STREAMS, _, _));
- }
- EXPECT_EQ(nullptr, session_.GetOrCreateStream(stream_id2));
-}
-
-TEST_P(QuicSpdySessionTestServer, ManyAvailableStreams) {
- // When max_open_streams_ is 200, should be able to create 200 streams
- // out-of-order, that is, creating the one with the largest stream ID first.
- if (VersionHasIetfQuicFrames(transport_version())) {
- QuicSessionPeer::SetMaxOpenIncomingBidirectionalStreams(&session_, 200);
- } else {
- QuicSessionPeer::SetMaxOpenIncomingStreams(&session_, 200);
- }
- QuicStreamId stream_id = GetNthClientInitiatedBidirectionalId(0);
- // Create one stream.
- session_.GetOrCreateStream(stream_id);
- EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
- // Stream count is 200, GetNth... starts counting at 0, so the 200'th stream
- // is 199. BUT actually we need to do 198 because the crypto stream (Stream
- // ID 0) has not been registered, but GetNth... assumes that it has.
- EXPECT_NE(nullptr, session_.GetOrCreateStream(
- GetNthClientInitiatedBidirectionalId(198)));
-}
-
-TEST_P(QuicSpdySessionTestServer,
- DebugDFatalIfMarkingClosedStreamWriteBlocked) {
- CompleteHandshake();
- EXPECT_CALL(*writer_, WritePacket(_, _, _, _, _))
- .WillRepeatedly(Return(WriteResult(WRITE_STATUS_OK, 0)));
-
- TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
- QuicStreamId closed_stream_id = stream2->id();
- // Close the stream.
- EXPECT_CALL(*connection_, SendControlFrame(_));
- EXPECT_CALL(*connection_, OnStreamReset(closed_stream_id, _));
- stream2->Reset(QUIC_BAD_APPLICATION_PAYLOAD);
- std::string msg =
- absl::StrCat("Marking unknown stream ", closed_stream_id, " blocked.");
- EXPECT_QUIC_BUG(session_.MarkConnectionLevelWriteBlocked(closed_stream_id),
- msg);
-}
-
-TEST_P(QuicSpdySessionTestServer, OnCanWrite) {
- CompleteHandshake();
- session_.set_writev_consumes_all_data(true);
- TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
- TestStream* stream4 = session_.CreateOutgoingBidirectionalStream();
- TestStream* stream6 = session_.CreateOutgoingBidirectionalStream();
-
- session_.MarkConnectionLevelWriteBlocked(stream2->id());
- session_.MarkConnectionLevelWriteBlocked(stream6->id());
- session_.MarkConnectionLevelWriteBlocked(stream4->id());
-
- InSequence s;
-
- // Reregister, to test the loop limit.
- EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
- session_.SendStreamData(stream2);
- session_.MarkConnectionLevelWriteBlocked(stream2->id());
- }));
- // 2 will get called a second time as it didn't finish its block
- EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
- session_.SendStreamData(stream2);
- }));
- EXPECT_CALL(*stream6, OnCanWrite()).WillOnce(Invoke([this, stream6]() {
- session_.SendStreamData(stream6);
- }));
- // 4 will not get called, as we exceeded the loop limit.
- session_.OnCanWrite();
- EXPECT_TRUE(session_.WillingAndAbleToWrite());
-}
-
-TEST_P(QuicSpdySessionTestServer, TooLargeStreamBlocked) {
- // STREAMS_BLOCKED frame is IETF QUIC only.
- if (!VersionUsesHttp3(transport_version())) {
- return;
- }
-
- CompleteHandshake();
- StrictMock<MockHttp3DebugVisitor> debug_visitor;
- session_.set_debug_visitor(&debug_visitor);
-
- // Simualte the situation where the incoming stream count is at its limit and
- // the peer is blocked.
- QuicSessionPeer::SetMaxOpenIncomingBidirectionalStreams(
- static_cast<QuicSession*>(&session_), QuicUtils::GetMaxStreamCount());
- QuicStreamsBlockedFrame frame;
- frame.stream_count = QuicUtils::GetMaxStreamCount();
- EXPECT_CALL(*writer_, WritePacket(_, _, _, _, _))
- .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 0)));
- EXPECT_CALL(debug_visitor, OnGoAwayFrameSent(_));
- session_.OnStreamsBlockedFrame(frame);
-}
-
-TEST_P(QuicSpdySessionTestServer, TestBatchedWrites) {
- session_.set_writev_consumes_all_data(true);
- TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
- TestStream* stream4 = session_.CreateOutgoingBidirectionalStream();
- TestStream* stream6 = session_.CreateOutgoingBidirectionalStream();
-
- session_.set_writev_consumes_all_data(true);
- session_.MarkConnectionLevelWriteBlocked(stream2->id());
- session_.MarkConnectionLevelWriteBlocked(stream4->id());
-
- // With two sessions blocked, we should get two write calls. They should both
- // go to the first stream as it will only write 6k and mark itself blocked
- // again.
- InSequence s;
- EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
- session_.SendLargeFakeData(stream2, 6000);
- session_.MarkConnectionLevelWriteBlocked(stream2->id());
- }));
- EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
- session_.SendLargeFakeData(stream2, 6000);
- session_.MarkConnectionLevelWriteBlocked(stream2->id());
- }));
- session_.OnCanWrite();
-
- // We should get one more call for stream2, at which point it has used its
- // write quota and we move over to stream 4.
- EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
- session_.SendLargeFakeData(stream2, 6000);
- session_.MarkConnectionLevelWriteBlocked(stream2->id());
- }));
- EXPECT_CALL(*stream4, OnCanWrite()).WillOnce(Invoke([this, stream4]() {
- session_.SendLargeFakeData(stream4, 6000);
- session_.MarkConnectionLevelWriteBlocked(stream4->id());
- }));
- session_.OnCanWrite();
-
- // Now let stream 4 do the 2nd of its 3 writes, but add a block for a high
- // priority stream 6. 4 should be preempted. 6 will write but *not* block so
- // will cede back to 4.
- stream6->SetPriority(spdy::SpdyStreamPrecedence(kV3HighestPriority));
- EXPECT_CALL(*stream4, OnCanWrite())
- .WillOnce(Invoke([this, stream4, stream6]() {
- session_.SendLargeFakeData(stream4, 6000);
- session_.MarkConnectionLevelWriteBlocked(stream4->id());
- session_.MarkConnectionLevelWriteBlocked(stream6->id());
- }));
- EXPECT_CALL(*stream6, OnCanWrite())
- .WillOnce(Invoke([this, stream4, stream6]() {
- session_.SendStreamData(stream6);
- session_.SendLargeFakeData(stream4, 6000);
- }));
- session_.OnCanWrite();
-
- // Stream4 alread did 6k worth of writes, so after doing another 12k it should
- // cede and 2 should resume.
- EXPECT_CALL(*stream4, OnCanWrite()).WillOnce(Invoke([this, stream4]() {
- session_.SendLargeFakeData(stream4, 12000);
- session_.MarkConnectionLevelWriteBlocked(stream4->id());
- }));
- EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
- session_.SendLargeFakeData(stream2, 6000);
- session_.MarkConnectionLevelWriteBlocked(stream2->id());
- }));
- session_.OnCanWrite();
-}
-
-TEST_P(QuicSpdySessionTestServer, OnCanWriteBundlesStreams) {
- // Encryption needs to be established before data can be sent.
- CompleteHandshake();
-
- // Drive congestion control manually.
- MockSendAlgorithm* send_algorithm = new StrictMock<MockSendAlgorithm>;
- QuicConnectionPeer::SetSendAlgorithm(session_.connection(), send_algorithm);
-
- TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
- TestStream* stream4 = session_.CreateOutgoingBidirectionalStream();
- TestStream* stream6 = session_.CreateOutgoingBidirectionalStream();
-
- session_.MarkConnectionLevelWriteBlocked(stream2->id());
- session_.MarkConnectionLevelWriteBlocked(stream6->id());
- session_.MarkConnectionLevelWriteBlocked(stream4->id());
-
- EXPECT_CALL(*send_algorithm, CanSend(_)).WillRepeatedly(Return(true));
- EXPECT_CALL(*send_algorithm, GetCongestionWindow())
- .WillRepeatedly(Return(kMaxOutgoingPacketSize * 10));
- EXPECT_CALL(*send_algorithm, InRecovery()).WillRepeatedly(Return(false));
- EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
- session_.SendStreamData(stream2);
- }));
- EXPECT_CALL(*stream4, OnCanWrite()).WillOnce(Invoke([this, stream4]() {
- session_.SendStreamData(stream4);
- }));
- EXPECT_CALL(*stream6, OnCanWrite()).WillOnce(Invoke([this, stream6]() {
- session_.SendStreamData(stream6);
- }));
-
- // Expect that we only send one packet, the writes from different streams
- // should be bundled together.
- EXPECT_CALL(*writer_, WritePacket(_, _, _, _, _))
- .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 0)));
- EXPECT_CALL(*send_algorithm, OnPacketSent(_, _, _, _, _));
- EXPECT_CALL(*send_algorithm, OnApplicationLimited(_));
- session_.OnCanWrite();
- EXPECT_FALSE(session_.WillingAndAbleToWrite());
-}
-
-TEST_P(QuicSpdySessionTestServer, OnCanWriteCongestionControlBlocks) {
- CompleteHandshake();
- session_.set_writev_consumes_all_data(true);
- InSequence s;
-
- // Drive congestion control manually.
- MockSendAlgorithm* send_algorithm = new StrictMock<MockSendAlgorithm>;
- QuicConnectionPeer::SetSendAlgorithm(session_.connection(), send_algorithm);
-
- TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
- TestStream* stream4 = session_.CreateOutgoingBidirectionalStream();
- TestStream* stream6 = session_.CreateOutgoingBidirectionalStream();
-
- session_.MarkConnectionLevelWriteBlocked(stream2->id());
- session_.MarkConnectionLevelWriteBlocked(stream6->id());
- session_.MarkConnectionLevelWriteBlocked(stream4->id());
-
- EXPECT_CALL(*send_algorithm, CanSend(_)).WillOnce(Return(true));
- EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
- session_.SendStreamData(stream2);
- }));
- EXPECT_CALL(*send_algorithm, GetCongestionWindow()).Times(AnyNumber());
- EXPECT_CALL(*send_algorithm, CanSend(_)).WillOnce(Return(true));
- EXPECT_CALL(*stream6, OnCanWrite()).WillOnce(Invoke([this, stream6]() {
- session_.SendStreamData(stream6);
- }));
- EXPECT_CALL(*send_algorithm, CanSend(_)).WillOnce(Return(false));
- // stream4->OnCanWrite is not called.
-
- session_.OnCanWrite();
- EXPECT_TRUE(session_.WillingAndAbleToWrite());
-
- // Still congestion-control blocked.
- EXPECT_CALL(*send_algorithm, CanSend(_)).WillOnce(Return(false));
- session_.OnCanWrite();
- EXPECT_TRUE(session_.WillingAndAbleToWrite());
-
- // stream4->OnCanWrite is called once the connection stops being
- // congestion-control blocked.
- EXPECT_CALL(*send_algorithm, CanSend(_)).WillOnce(Return(true));
- EXPECT_CALL(*stream4, OnCanWrite()).WillOnce(Invoke([this, stream4]() {
- session_.SendStreamData(stream4);
- }));
- EXPECT_CALL(*send_algorithm, OnApplicationLimited(_));
- session_.OnCanWrite();
- EXPECT_FALSE(session_.WillingAndAbleToWrite());
-}
-
-TEST_P(QuicSpdySessionTestServer, OnCanWriteWriterBlocks) {
- CompleteHandshake();
- // Drive congestion control manually in order to ensure that
- // application-limited signaling is handled correctly.
- MockSendAlgorithm* send_algorithm = new StrictMock<MockSendAlgorithm>;
- QuicConnectionPeer::SetSendAlgorithm(session_.connection(), send_algorithm);
- EXPECT_CALL(*send_algorithm, CanSend(_)).WillRepeatedly(Return(true));
-
- // Drive packet writer manually.
- EXPECT_CALL(*writer_, IsWriteBlocked()).WillRepeatedly(Return(true));
- EXPECT_CALL(*writer_, WritePacket(_, _, _, _, _)).Times(0);
-
- TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
-
- session_.MarkConnectionLevelWriteBlocked(stream2->id());
-
- EXPECT_CALL(*stream2, OnCanWrite()).Times(0);
- EXPECT_CALL(*send_algorithm, OnApplicationLimited(_)).Times(0);
-
- session_.OnCanWrite();
- EXPECT_TRUE(session_.WillingAndAbleToWrite());
-}
-
-TEST_P(QuicSpdySessionTestServer, BufferedHandshake) {
- // This tests prioritization of the crypto stream when flow control limits are
- // reached. When CRYPTO frames are in use, there is no flow control for the
- // crypto handshake, so this test is irrelevant.
- if (QuicVersionUsesCryptoFrames(transport_version())) {
- return;
- }
- session_.set_writev_consumes_all_data(true);
- EXPECT_FALSE(session_.HasPendingHandshake()); // Default value.
-
- // Test that blocking other streams does not change our status.
- TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
- session_.MarkConnectionLevelWriteBlocked(stream2->id());
- EXPECT_FALSE(session_.HasPendingHandshake());
-
- TestStream* stream3 = session_.CreateOutgoingBidirectionalStream();
- session_.MarkConnectionLevelWriteBlocked(stream3->id());
- EXPECT_FALSE(session_.HasPendingHandshake());
-
- // Blocking (due to buffering of) the Crypto stream is detected.
- session_.MarkConnectionLevelWriteBlocked(
- QuicUtils::GetCryptoStreamId(transport_version()));
- EXPECT_TRUE(session_.HasPendingHandshake());
-
- TestStream* stream4 = session_.CreateOutgoingBidirectionalStream();
- session_.MarkConnectionLevelWriteBlocked(stream4->id());
- EXPECT_TRUE(session_.HasPendingHandshake());
-
- InSequence s;
- // Force most streams to re-register, which is common scenario when we block
- // the Crypto stream, and only the crypto stream can "really" write.
-
- // Due to prioritization, we *should* be asked to write the crypto stream
- // first.
- // Don't re-register the crypto stream (which signals complete writing).
- TestCryptoStream* crypto_stream = session_.GetMutableCryptoStream();
- EXPECT_CALL(*crypto_stream, OnCanWrite());
-
- EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
- session_.SendStreamData(stream2);
- }));
- EXPECT_CALL(*stream3, OnCanWrite()).WillOnce(Invoke([this, stream3]() {
- session_.SendStreamData(stream3);
- }));
- EXPECT_CALL(*stream4, OnCanWrite()).WillOnce(Invoke([this, stream4]() {
- session_.SendStreamData(stream4);
- session_.MarkConnectionLevelWriteBlocked(stream4->id());
- }));
-
- session_.OnCanWrite();
- EXPECT_TRUE(session_.WillingAndAbleToWrite());
- EXPECT_FALSE(session_.HasPendingHandshake()); // Crypto stream wrote.
-}
-
-TEST_P(QuicSpdySessionTestServer, OnCanWriteWithClosedStream) {
- CompleteHandshake();
- session_.set_writev_consumes_all_data(true);
- TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
- TestStream* stream4 = session_.CreateOutgoingBidirectionalStream();
- TestStream* stream6 = session_.CreateOutgoingBidirectionalStream();
-
- session_.MarkConnectionLevelWriteBlocked(stream2->id());
- session_.MarkConnectionLevelWriteBlocked(stream6->id());
- session_.MarkConnectionLevelWriteBlocked(stream4->id());
- CloseStream(stream6->id());
-
- InSequence s;
- EXPECT_CALL(*connection_, SendControlFrame(_))
- .WillRepeatedly(Invoke(&ClearControlFrame));
- EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
- session_.SendStreamData(stream2);
- }));
- EXPECT_CALL(*stream4, OnCanWrite()).WillOnce(Invoke([this, stream4]() {
- session_.SendStreamData(stream4);
- }));
- session_.OnCanWrite();
- EXPECT_FALSE(session_.WillingAndAbleToWrite());
-}
-
-TEST_P(QuicSpdySessionTestServer,
- OnCanWriteLimitsNumWritesIfFlowControlBlocked) {
- CompleteHandshake();
- // Drive congestion control manually in order to ensure that
- // application-limited signaling is handled correctly.
- MockSendAlgorithm* send_algorithm = new StrictMock<MockSendAlgorithm>;
- QuicConnectionPeer::SetSendAlgorithm(session_.connection(), send_algorithm);
- EXPECT_CALL(*send_algorithm, CanSend(_)).WillRepeatedly(Return(true));
-
- // Ensure connection level flow control blockage.
- QuicFlowControllerPeer::SetSendWindowOffset(session_.flow_controller(), 0);
- EXPECT_TRUE(session_.flow_controller()->IsBlocked());
- EXPECT_TRUE(session_.IsConnectionFlowControlBlocked());
- EXPECT_FALSE(session_.IsStreamFlowControlBlocked());
-
- // Mark the crypto and headers streams as write blocked, we expect them to be
- // allowed to write later.
- if (!QuicVersionUsesCryptoFrames(transport_version())) {
- session_.MarkConnectionLevelWriteBlocked(
- QuicUtils::GetCryptoStreamId(transport_version()));
- }
-
- // Create a data stream, and although it is write blocked we never expect it
- // to be allowed to write as we are connection level flow control blocked.
- TestStream* stream = session_.CreateOutgoingBidirectionalStream();
- session_.MarkConnectionLevelWriteBlocked(stream->id());
- EXPECT_CALL(*stream, OnCanWrite()).Times(0);
-
- // The crypto and headers streams should be called even though we are
- // connection flow control blocked.
- if (!QuicVersionUsesCryptoFrames(transport_version())) {
- TestCryptoStream* crypto_stream = session_.GetMutableCryptoStream();
- EXPECT_CALL(*crypto_stream, OnCanWrite());
- }
-
- if (!VersionUsesHttp3(transport_version())) {
- TestHeadersStream* headers_stream;
- QuicSpdySessionPeer::SetHeadersStream(&session_, nullptr);
- headers_stream = new TestHeadersStream(&session_);
- QuicSpdySessionPeer::SetHeadersStream(&session_, headers_stream);
- session_.MarkConnectionLevelWriteBlocked(
- QuicUtils::GetHeadersStreamId(transport_version()));
- EXPECT_CALL(*headers_stream, OnCanWrite());
- }
-
- // After the crypto and header streams perform a write, the connection will be
- // blocked by the flow control, hence it should become application-limited.
- EXPECT_CALL(*send_algorithm, OnApplicationLimited(_));
-
- session_.OnCanWrite();
- EXPECT_FALSE(session_.WillingAndAbleToWrite());
-}
-
-TEST_P(QuicSpdySessionTestServer, SendGoAway) {
- CompleteHandshake();
- if (VersionHasIetfQuicFrames(transport_version())) {
- // HTTP/3 GOAWAY has different semantic and thus has its own test.
- return;
- }
- connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
- EXPECT_CALL(*writer_, WritePacket(_, _, _, _, _))
- .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 0)));
-
- EXPECT_CALL(*connection_, SendControlFrame(_))
- .WillOnce(
- Invoke(connection_, &MockQuicConnection::ReallySendControlFrame));
- session_.SendGoAway(QUIC_PEER_GOING_AWAY, "Going Away.");
- EXPECT_TRUE(session_.goaway_sent());
-
- const QuicStreamId kTestStreamId = 5u;
- EXPECT_CALL(*connection_, SendControlFrame(_)).Times(0);
- EXPECT_CALL(*connection_,
- OnStreamReset(kTestStreamId, QUIC_STREAM_PEER_GOING_AWAY))
- .Times(0);
- EXPECT_TRUE(session_.GetOrCreateStream(kTestStreamId));
-}
-
-TEST_P(QuicSpdySessionTestServer, SendGoAwayWithoutEncryption) {
- if (VersionHasIetfQuicFrames(transport_version())) {
- // HTTP/3 GOAWAY has different semantic and thus has its own test.
- return;
- }
- EXPECT_CALL(
- *connection_,
- CloseConnection(QUIC_PEER_GOING_AWAY, "Going Away.",
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET));
- EXPECT_CALL(*connection_, SendControlFrame(_)).Times(0);
- session_.SendGoAway(QUIC_PEER_GOING_AWAY, "Going Away.");
- EXPECT_FALSE(session_.goaway_sent());
-}
-
-TEST_P(QuicSpdySessionTestServer, SendHttp3GoAway) {
- if (!VersionUsesHttp3(transport_version())) {
- return;
- }
-
- CompleteHandshake();
- StrictMock<MockHttp3DebugVisitor> debug_visitor;
- session_.set_debug_visitor(&debug_visitor);
-
- EXPECT_CALL(*writer_, WritePacket(_, _, _, _, _))
- .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 0)));
- // Send max stream id (currently 32 bits).
- EXPECT_CALL(debug_visitor, OnGoAwayFrameSent(/* stream_id = */ 0xfffffffc));
- session_.SendHttp3GoAway(QUIC_PEER_GOING_AWAY, "Goaway");
- EXPECT_TRUE(session_.goaway_sent());
-
- // New incoming stream is not reset.
- const QuicStreamId kTestStreamId =
- GetNthClientInitiatedBidirectionalStreamId(transport_version(), 0);
- EXPECT_CALL(*connection_, OnStreamReset(kTestStreamId, _)).Times(0);
- EXPECT_TRUE(session_.GetOrCreateStream(kTestStreamId));
-
- // No more GOAWAY frames are sent because they could not convey new
- // information to the client.
- session_.SendHttp3GoAway(QUIC_PEER_GOING_AWAY, "Goaway");
-}
-
-TEST_P(QuicSpdySessionTestServer, SendHttp3GoAwayWithoutEncryption) {
- if (!VersionUsesHttp3(transport_version())) {
- return;
- }
- EXPECT_CALL(
- *connection_,
- CloseConnection(QUIC_PEER_GOING_AWAY, "Goaway",
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET));
- session_.SendHttp3GoAway(QUIC_PEER_GOING_AWAY, "Goaway");
- EXPECT_FALSE(session_.goaway_sent());
-}
-
-TEST_P(QuicSpdySessionTestServer, SendHttp3GoAwayAfterStreamIsCreated) {
- if (!VersionUsesHttp3(transport_version())) {
- return;
- }
-
- CompleteHandshake();
- StrictMock<MockHttp3DebugVisitor> debug_visitor;
- session_.set_debug_visitor(&debug_visitor);
-
- const QuicStreamId kTestStreamId =
- GetNthClientInitiatedBidirectionalStreamId(transport_version(), 0);
- EXPECT_TRUE(session_.GetOrCreateStream(kTestStreamId));
-
- EXPECT_CALL(*writer_, WritePacket(_, _, _, _, _))
- .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 0)));
- // Send max stream id (currently 32 bits).
- EXPECT_CALL(debug_visitor, OnGoAwayFrameSent(/* stream_id = */ 0xfffffffc));
- session_.SendHttp3GoAway(QUIC_PEER_GOING_AWAY, "Goaway");
- EXPECT_TRUE(session_.goaway_sent());
-
- // No more GOAWAY frames are sent because they could not convey new
- // information to the client.
- session_.SendHttp3GoAway(QUIC_PEER_GOING_AWAY, "Goaway");
-}
-
-TEST_P(QuicSpdySessionTestServer, DoNotSendGoAwayTwice) {
- CompleteHandshake();
- if (VersionHasIetfQuicFrames(transport_version())) {
- // HTTP/3 GOAWAY doesn't have such restriction.
- return;
- }
- EXPECT_CALL(*connection_, SendControlFrame(_))
- .WillOnce(Invoke(&ClearControlFrame));
- session_.SendGoAway(QUIC_PEER_GOING_AWAY, "Going Away.");
- EXPECT_TRUE(session_.goaway_sent());
- session_.SendGoAway(QUIC_PEER_GOING_AWAY, "Going Away.");
-}
-
-TEST_P(QuicSpdySessionTestServer, InvalidGoAway) {
- if (VersionHasIetfQuicFrames(transport_version())) {
- // HTTP/3 GOAWAY has different semantics and thus has its own test.
- return;
- }
- QuicGoAwayFrame go_away(kInvalidControlFrameId, QUIC_PEER_GOING_AWAY,
- session_.next_outgoing_bidirectional_stream_id(), "");
- session_.OnGoAway(go_away);
-}
-
-TEST_P(QuicSpdySessionTestServer, Http3GoAwayLargerIdThanBefore) {
- if (!VersionUsesHttp3(transport_version())) {
- return;
- }
-
- EXPECT_FALSE(session_.goaway_received());
- PushId push_id1 = 0;
- session_.OnHttp3GoAway(push_id1);
- EXPECT_TRUE(session_.goaway_received());
-
- EXPECT_CALL(
- *connection_,
- CloseConnection(
- 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);
-}
-
-// Test that server session will send a connectivity probe in response to a
-// connectivity probe on the same path.
-TEST_P(QuicSpdySessionTestServer, ServerReplyToConnecitivityProbe) {
- if (VersionHasIetfQuicFrames(transport_version()) &&
- connection_->send_path_response()) {
- return;
- }
- connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
- QuicSocketAddress old_peer_address =
- QuicSocketAddress(QuicIpAddress::Loopback4(), kTestPort);
- EXPECT_EQ(old_peer_address, session_.peer_address());
-
- QuicSocketAddress new_peer_address =
- QuicSocketAddress(QuicIpAddress::Loopback4(), kTestPort + 1);
-
- if (connection_->send_path_response()) {
- EXPECT_CALL(*connection_,
- SendConnectivityProbingPacket(nullptr, new_peer_address));
- } else {
- EXPECT_CALL(*connection_,
- SendConnectivityProbingResponsePacket(new_peer_address));
- }
-
- if (VersionHasIetfQuicFrames(transport_version())) {
- // Need to explicitly do this to emulate the reception of a PathChallenge,
- // which stores its payload for use in generating the response.
- connection_->OnPathChallengeFrame(
- QuicPathChallengeFrame(0, {{0, 1, 2, 3, 4, 5, 6, 7}}));
- }
- session_.OnPacketReceived(session_.self_address(), new_peer_address,
- /*is_connectivity_probe=*/true);
- EXPECT_EQ(old_peer_address, session_.peer_address());
-}
-
-TEST_P(QuicSpdySessionTestServer, IncreasedTimeoutAfterCryptoHandshake) {
- EXPECT_EQ(kInitialIdleTimeoutSecs + 3,
- QuicConnectionPeer::GetNetworkTimeout(connection_).ToSeconds());
- CompleteHandshake();
- EXPECT_EQ(kMaximumIdleTimeoutSecs + 3,
- QuicConnectionPeer::GetNetworkTimeout(connection_).ToSeconds());
-}
-
-TEST_P(QuicSpdySessionTestServer, RstStreamBeforeHeadersDecompressed) {
- CompleteHandshake();
- // Send two bytes of payload.
- QuicStreamFrame data1(GetNthClientInitiatedBidirectionalId(0), false, 0,
- absl::string_view("HT"));
- session_.OnStreamFrame(data1);
- EXPECT_EQ(1u, QuicSessionPeer::GetNumOpenDynamicStreams(&session_));
-
- if (!VersionHasIetfQuicFrames(transport_version())) {
- // For version99, OnStreamReset gets called because of the STOP_SENDING,
- // below. EXPECT the call there.
- EXPECT_CALL(*connection_,
- OnStreamReset(GetNthClientInitiatedBidirectionalId(0), _));
- }
-
- // In HTTP/3, Qpack stream will send data on stream reset and cause packet to
- // be flushed.
- if (VersionUsesHttp3(transport_version())) {
- EXPECT_CALL(*writer_, WritePacket(_, _, _, _, _))
- .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 0)));
- }
- EXPECT_CALL(*connection_, SendControlFrame(_));
- QuicRstStreamFrame rst1(kInvalidControlFrameId,
- GetNthClientInitiatedBidirectionalId(0),
- QUIC_ERROR_PROCESSING_STREAM, 0);
- session_.OnRstStream(rst1);
-
- // Create and inject a STOP_SENDING frame. In GOOGLE QUIC, receiving a
- // RST_STREAM frame causes a two-way close. For IETF QUIC, RST_STREAM causes a
- // one-way close.
- if (VersionHasIetfQuicFrames(transport_version())) {
- // Only needed for version 99/IETF QUIC.
- QuicStopSendingFrame stop_sending(kInvalidControlFrameId,
- GetNthClientInitiatedBidirectionalId(0),
- QUIC_ERROR_PROCESSING_STREAM);
- // Expect the RESET_STREAM that is generated in response to receiving a
- // STOP_SENDING.
- EXPECT_CALL(*connection_,
- OnStreamReset(GetNthClientInitiatedBidirectionalId(0),
- QUIC_ERROR_PROCESSING_STREAM));
- session_.OnStopSendingFrame(stop_sending);
- }
-
- EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(&session_));
- // Connection should remain alive.
- EXPECT_TRUE(connection_->connected());
-}
-
-TEST_P(QuicSpdySessionTestServer, OnStreamFrameFinStaticStreamId) {
- QuicStreamId id;
- // Initialize HTTP/3 control stream.
- if (VersionUsesHttp3(transport_version())) {
- id = GetNthClientInitiatedUnidirectionalStreamId(transport_version(), 3);
- char type[] = {kControlStream};
-
- QuicStreamFrame data1(id, false, 0, absl::string_view(type, 1));
- session_.OnStreamFrame(data1);
- } else {
- id = QuicUtils::GetHeadersStreamId(transport_version());
- }
-
- // Send two bytes of payload.
- QuicStreamFrame data1(id, true, 0, absl::string_view("HT"));
- EXPECT_CALL(*connection_,
- CloseConnection(
- QUIC_INVALID_STREAM_ID, "Attempt to close a static stream",
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET));
- session_.OnStreamFrame(data1);
-}
-
-TEST_P(QuicSpdySessionTestServer, OnRstStreamStaticStreamId) {
- QuicStreamId id;
- QuicErrorCode expected_error;
- std::string error_message;
- // Initialize HTTP/3 control stream.
- if (VersionUsesHttp3(transport_version())) {
- id = GetNthClientInitiatedUnidirectionalStreamId(transport_version(), 3);
- char type[] = {kControlStream};
-
- QuicStreamFrame data1(id, false, 0, absl::string_view(type, 1));
- session_.OnStreamFrame(data1);
- expected_error = QUIC_HTTP_CLOSED_CRITICAL_STREAM;
- error_message = "RESET_STREAM received for receive control stream";
- } else {
- id = QuicUtils::GetHeadersStreamId(transport_version());
- expected_error = QUIC_INVALID_STREAM_ID;
- error_message = "Attempt to reset headers stream";
- }
-
- // Send two bytes of payload.
- QuicRstStreamFrame rst1(kInvalidControlFrameId, id,
- QUIC_ERROR_PROCESSING_STREAM, 0);
- EXPECT_CALL(
- *connection_,
- CloseConnection(expected_error, error_message,
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET));
- session_.OnRstStream(rst1);
-}
-
-TEST_P(QuicSpdySessionTestServer, OnStreamFrameInvalidStreamId) {
- // Send two bytes of payload.
- QuicStreamFrame data1(QuicUtils::GetInvalidStreamId(transport_version()),
- true, 0, absl::string_view("HT"));
- EXPECT_CALL(*connection_,
- CloseConnection(
- QUIC_INVALID_STREAM_ID, "Received data for an invalid stream",
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET));
- session_.OnStreamFrame(data1);
-}
-
-TEST_P(QuicSpdySessionTestServer, OnRstStreamInvalidStreamId) {
- // Send two bytes of payload.
- QuicRstStreamFrame rst1(kInvalidControlFrameId,
- QuicUtils::GetInvalidStreamId(transport_version()),
- QUIC_ERROR_PROCESSING_STREAM, 0);
- EXPECT_CALL(*connection_,
- CloseConnection(
- QUIC_INVALID_STREAM_ID, "Received data for an invalid stream",
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET));
- session_.OnRstStream(rst1);
-}
-
-TEST_P(QuicSpdySessionTestServer, HandshakeUnblocksFlowControlBlockedStream) {
- if (connection_->version().handshake_protocol == PROTOCOL_TLS1_3) {
- // This test requires Google QUIC crypto because it assumes streams start
- // off unblocked.
- return;
- }
- // Test that if a stream is flow control blocked, then on receipt of the SHLO
- // containing a suitable send window offset, the stream becomes unblocked.
-
- // Ensure that Writev consumes all the data it is given (simulate no socket
- // blocking).
- session_.GetMutableCryptoStream()->EstablishZeroRttEncryption();
- session_.set_writev_consumes_all_data(true);
-
- // Create a stream, and send enough data to make it flow control blocked.
- TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
- std::string body(kMinimumFlowControlSendWindow, '.');
- EXPECT_FALSE(stream2->IsFlowControlBlocked());
- EXPECT_FALSE(session_.IsConnectionFlowControlBlocked());
- EXPECT_FALSE(session_.IsStreamFlowControlBlocked());
- EXPECT_CALL(*connection_, SendControlFrame(_)).Times(AtLeast(1));
- stream2->WriteOrBufferBody(body, false);
- EXPECT_TRUE(stream2->IsFlowControlBlocked());
- EXPECT_TRUE(session_.IsConnectionFlowControlBlocked());
- EXPECT_TRUE(session_.IsStreamFlowControlBlocked());
-
- // Now complete the crypto handshake, resulting in an increased flow control
- // send window.
- CompleteHandshake();
- EXPECT_TRUE(QuicSessionPeer::IsStreamWriteBlocked(&session_, stream2->id()));
- // Stream is now unblocked.
- EXPECT_FALSE(stream2->IsFlowControlBlocked());
- EXPECT_FALSE(session_.IsConnectionFlowControlBlocked());
- EXPECT_FALSE(session_.IsStreamFlowControlBlocked());
-}
-
-#if !defined(OS_IOS)
-// This test is failing flakily for iOS bots.
-// http://crbug.com/425050
-// NOTE: It's not possible to use the standard MAYBE_ convention to disable
-// this test on iOS because when this test gets instantiated it ends up with
-// various names that are dependent on the parameters passed.
-TEST_P(QuicSpdySessionTestServer,
- HandshakeUnblocksFlowControlBlockedHeadersStream) {
- // This test depends on stream-level flow control for the crypto stream, which
- // doesn't exist when CRYPTO frames are used.
- if (QuicVersionUsesCryptoFrames(transport_version())) {
- return;
- }
-
- // This test depends on the headers stream, which does not exist when QPACK is
- // used.
- if (VersionUsesHttp3(transport_version())) {
- return;
- }
-
- // Test that if the header stream is flow control blocked, then if the SHLO
- // contains a larger send window offset, the stream becomes unblocked.
- session_.GetMutableCryptoStream()->EstablishZeroRttEncryption();
- session_.set_writev_consumes_all_data(true);
- TestCryptoStream* crypto_stream = session_.GetMutableCryptoStream();
- EXPECT_FALSE(crypto_stream->IsFlowControlBlocked());
- EXPECT_FALSE(session_.IsConnectionFlowControlBlocked());
- EXPECT_FALSE(session_.IsStreamFlowControlBlocked());
- QuicHeadersStream* headers_stream =
- QuicSpdySessionPeer::GetHeadersStream(&session_);
- EXPECT_FALSE(headers_stream->IsFlowControlBlocked());
- EXPECT_FALSE(session_.IsConnectionFlowControlBlocked());
- EXPECT_FALSE(session_.IsStreamFlowControlBlocked());
- QuicStreamId stream_id = 5;
- // Write until the header stream is flow control blocked.
- EXPECT_CALL(*connection_, SendControlFrame(_))
- .WillOnce(Invoke(&ClearControlFrame));
- SpdyHeaderBlock headers;
- SimpleRandom random;
- while (!headers_stream->IsFlowControlBlocked() && stream_id < 2000) {
- EXPECT_FALSE(session_.IsConnectionFlowControlBlocked());
- EXPECT_FALSE(session_.IsStreamFlowControlBlocked());
- headers["header"] = absl::StrCat(random.RandUint64(), random.RandUint64(),
- random.RandUint64());
- session_.WriteHeadersOnHeadersStream(stream_id, headers.Clone(), true,
- spdy::SpdyStreamPrecedence(0),
- nullptr);
- stream_id += IdDelta();
- }
- // Write once more to ensure that the headers stream has buffered data. The
- // random headers may have exactly filled the flow control window.
- session_.WriteHeadersOnHeadersStream(stream_id, std::move(headers), true,
- spdy::SpdyStreamPrecedence(0), nullptr);
- EXPECT_TRUE(headers_stream->HasBufferedData());
-
- EXPECT_TRUE(headers_stream->IsFlowControlBlocked());
- EXPECT_FALSE(crypto_stream->IsFlowControlBlocked());
- EXPECT_FALSE(session_.IsConnectionFlowControlBlocked());
- EXPECT_TRUE(session_.IsStreamFlowControlBlocked());
- EXPECT_FALSE(session_.HasDataToWrite());
-
- // Now complete the crypto handshake, resulting in an increased flow control
- // send window.
- CompleteHandshake();
-
- // Stream is now unblocked and will no longer have buffered data.
- EXPECT_FALSE(headers_stream->IsFlowControlBlocked());
- EXPECT_FALSE(session_.IsConnectionFlowControlBlocked());
- EXPECT_FALSE(session_.IsStreamFlowControlBlocked());
- EXPECT_TRUE(headers_stream->HasBufferedData());
- EXPECT_TRUE(QuicSessionPeer::IsStreamWriteBlocked(
- &session_, QuicUtils::GetHeadersStreamId(transport_version())));
-}
-#endif // !defined(OS_IOS)
-
-TEST_P(QuicSpdySessionTestServer,
- ConnectionFlowControlAccountingRstOutOfOrder) {
- EXPECT_CALL(*connection_, SendControlFrame(_))
- .WillRepeatedly(Invoke(&ClearControlFrame));
- CompleteHandshake();
- // Test that when we receive an out of order stream RST we correctly adjust
- // our connection level flow control receive window.
- // On close, the stream should mark as consumed all bytes between the highest
- // byte consumed so far and the final byte offset from the RST frame.
- TestStream* stream = session_.CreateOutgoingBidirectionalStream();
-
- const QuicStreamOffset kByteOffset =
- 1 + kInitialSessionFlowControlWindowForTest / 2;
-
- if (!VersionHasIetfQuicFrames(transport_version())) {
- // For version99 the call to OnStreamReset happens as a result of receiving
- // the STOP_SENDING, so set up the EXPECT there.
- EXPECT_CALL(*connection_, OnStreamReset(stream->id(), _));
- EXPECT_CALL(*connection_, SendControlFrame(_));
- } else {
- EXPECT_CALL(*writer_, WritePacket(_, _, _, _, _))
- .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 0)));
- }
- QuicRstStreamFrame rst_frame(kInvalidControlFrameId, stream->id(),
- QUIC_STREAM_CANCELLED, kByteOffset);
- session_.OnRstStream(rst_frame);
- // Create and inject a STOP_SENDING frame. In GOOGLE QUIC, receiving a
- // RST_STREAM frame causes a two-way close. For IETF QUIC, RST_STREAM causes a
- // one-way close.
- if (VersionHasIetfQuicFrames(transport_version())) {
- // Only needed for version 99/IETF QUIC.
- QuicStopSendingFrame stop_sending(kInvalidControlFrameId, stream->id(),
- QUIC_STREAM_CANCELLED);
- // Expect the RESET_STREAM that is generated in response to receiving a
- // STOP_SENDING.
- EXPECT_CALL(*connection_,
- OnStreamReset(stream->id(), QUIC_STREAM_CANCELLED));
- EXPECT_CALL(*connection_, SendControlFrame(_));
- session_.OnStopSendingFrame(stop_sending);
- }
-
- EXPECT_EQ(kByteOffset, session_.flow_controller()->bytes_consumed());
-}
-
-TEST_P(QuicSpdySessionTestServer, InvalidStreamFlowControlWindowInHandshake) {
- if (GetParam().handshake_protocol == PROTOCOL_TLS1_3) {
- // IETF Quic doesn't require a minimum flow control window.
- return;
- }
- // Test that receipt of an invalid (< default) stream flow control window from
- // the peer results in the connection being torn down.
- const uint32_t kInvalidWindow = kMinimumFlowControlSendWindow - 1;
- QuicConfigPeer::SetReceivedInitialStreamFlowControlWindow(session_.config(),
- kInvalidWindow);
-
- EXPECT_CALL(*connection_,
- CloseConnection(QUIC_FLOW_CONTROL_INVALID_WINDOW, _, _));
- session_.OnConfigNegotiated();
-}
-
-TEST_P(QuicSpdySessionTestServer, TooLowUnidirectionalStreamLimitHttp3) {
- if (!VersionUsesHttp3(transport_version())) {
- return;
- }
- session_.GetMutableCryptoStream()->EstablishZeroRttEncryption();
- QuicConfigPeer::SetReceivedMaxUnidirectionalStreams(session_.config(), 2u);
- connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
-
- EXPECT_CALL(
- *connection_,
- CloseConnection(
- _, "new unidirectional limit 2 decreases the current limit: 3", _));
- session_.OnConfigNegotiated();
-}
-
-// Test negotiation of custom server initial flow control window.
-TEST_P(QuicSpdySessionTestServer, CustomFlowControlWindow) {
- QuicTagVector copt;
- copt.push_back(kIFW7);
- QuicConfigPeer::SetReceivedConnectionOptions(session_.config(), copt);
- connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
- session_.OnConfigNegotiated();
- EXPECT_EQ(192 * 1024u, QuicFlowControllerPeer::ReceiveWindowSize(
- session_.flow_controller()));
-}
-
-TEST_P(QuicSpdySessionTestServer, WindowUpdateUnblocksHeadersStream) {
- if (VersionUsesHttp3(transport_version())) {
- // The test relies on headers stream, which no longer exists in IETF QUIC.
- return;
- }
-
- // Test that a flow control blocked headers stream gets unblocked on recipt of
- // a WINDOW_UPDATE frame.
-
- // Set the headers stream to be flow control blocked.
- QuicHeadersStream* headers_stream =
- QuicSpdySessionPeer::GetHeadersStream(&session_);
- QuicStreamPeer::SetSendWindowOffset(headers_stream, 0);
- EXPECT_TRUE(headers_stream->IsFlowControlBlocked());
- EXPECT_FALSE(session_.IsConnectionFlowControlBlocked());
- EXPECT_TRUE(session_.IsStreamFlowControlBlocked());
-
- // Unblock the headers stream by supplying a WINDOW_UPDATE.
- QuicWindowUpdateFrame window_update_frame(kInvalidControlFrameId,
- headers_stream->id(),
- 2 * kMinimumFlowControlSendWindow);
- session_.OnWindowUpdateFrame(window_update_frame);
- EXPECT_FALSE(headers_stream->IsFlowControlBlocked());
- EXPECT_FALSE(session_.IsConnectionFlowControlBlocked());
- EXPECT_FALSE(session_.IsStreamFlowControlBlocked());
-}
-
-TEST_P(QuicSpdySessionTestServer,
- TooManyUnfinishedStreamsCauseServerRejectStream) {
- // If a buggy/malicious peer creates too many streams that are not ended
- // with a FIN or RST then we send an RST to refuse streams for versions other
- // than version 99. In version 99 the connection gets closed.
- CompleteHandshake();
- const QuicStreamId kMaxStreams = 5;
- if (VersionHasIetfQuicFrames(transport_version())) {
- QuicSessionPeer::SetMaxOpenIncomingBidirectionalStreams(&session_,
- kMaxStreams);
- } else {
- QuicSessionPeer::SetMaxOpenIncomingStreams(&session_, kMaxStreams);
- }
- // GetNth assumes that both the crypto and header streams have been
- // open, but the stream id manager, using GetFirstBidirectional... only
- // assumes that the crypto stream is open. This means that GetNth...(0)
- // Will return stream ID == 8 (with id ==0 for crypto and id==4 for headers).
- // It also means that GetNth(kMax..=5) returns 28 (streams 0/1/2/3/4 are ids
- // 8, 12, 16, 20, 24, respectively, so stream#5 is stream id 28).
- // However, the stream ID manager does not assume stream 4 is for headers.
- // The ID manager would assume that stream#5 is streamid 24.
- // In order to make this all work out properly, kFinalStreamId will
- // be set to GetNth...(kMaxStreams-1)... but only for IETF QUIC
- const QuicStreamId kFirstStreamId = GetNthClientInitiatedBidirectionalId(0);
- const QuicStreamId kFinalStreamId =
- GetNthClientInitiatedBidirectionalId(kMaxStreams);
- // Create kMaxStreams data streams, and close them all without receiving a
- // FIN or a RST_STREAM from the client.
- const QuicStreamId kNextId = QuicUtils::StreamIdDelta(transport_version());
- for (QuicStreamId i = kFirstStreamId; i < kFinalStreamId; i += kNextId) {
- QuicStreamFrame data1(i, false, 0, absl::string_view("HT"));
- session_.OnStreamFrame(data1);
- CloseStream(i);
- }
- // Try and open a stream that exceeds the limit.
- if (!VersionHasIetfQuicFrames(transport_version())) {
- // On versions other than 99, opening such a stream results in a
- // RST_STREAM.
- EXPECT_CALL(*connection_, SendControlFrame(_)).Times(1);
- EXPECT_CALL(*connection_,
- OnStreamReset(kFinalStreamId, QUIC_REFUSED_STREAM))
- .Times(1);
- } else {
- // On version 99 opening such a stream results in a connection close.
- EXPECT_CALL(
- *connection_,
- CloseConnection(QUIC_INVALID_STREAM_ID,
- testing::MatchesRegex(
- "Stream id \\d+ would exceed stream count limit 5"),
- _));
- }
- // Create one more data streams to exceed limit of open stream.
- QuicStreamFrame data1(kFinalStreamId, false, 0, absl::string_view("HT"));
- session_.OnStreamFrame(data1);
-}
-
-TEST_P(QuicSpdySessionTestServer, DrainingStreamsDoNotCountAsOpened) {
- // Verify that a draining stream (which has received a FIN but not consumed
- // it) does not count against the open quota (because it is closed from the
- // protocol point of view).
- CompleteHandshake();
- if (VersionHasIetfQuicFrames(transport_version())) {
- // Simulate receiving a config. so that MAX_STREAMS/etc frames may
- // be transmitted
- QuicSessionPeer::set_is_configured(&session_, true);
- // Version 99 will result in a MAX_STREAMS frame as streams are consumed
- // (via the OnStreamFrame call) and then released (via
- // StreamDraining). Eventually this node will believe that the peer is
- // running low on available stream ids and then send a MAX_STREAMS frame,
- // caught by this EXPECT_CALL.
- EXPECT_CALL(*connection_, SendControlFrame(_)).Times(1);
- } else {
- EXPECT_CALL(*connection_, SendControlFrame(_)).Times(0);
- }
- EXPECT_CALL(*connection_, OnStreamReset(_, QUIC_REFUSED_STREAM)).Times(0);
- const QuicStreamId kMaxStreams = 5;
- if (VersionHasIetfQuicFrames(transport_version())) {
- QuicSessionPeer::SetMaxOpenIncomingBidirectionalStreams(&session_,
- kMaxStreams);
- } else {
- QuicSessionPeer::SetMaxOpenIncomingStreams(&session_, kMaxStreams);
- }
-
- // Create kMaxStreams + 1 data streams, and mark them draining.
- const QuicStreamId kFirstStreamId = GetNthClientInitiatedBidirectionalId(0);
- const QuicStreamId kFinalStreamId =
- GetNthClientInitiatedBidirectionalId(kMaxStreams + 1);
- for (QuicStreamId i = kFirstStreamId; i < kFinalStreamId; i += IdDelta()) {
- QuicStreamFrame data1(i, true, 0, absl::string_view("HT"));
- session_.OnStreamFrame(data1);
- EXPECT_EQ(1u, QuicSessionPeer::GetNumOpenDynamicStreams(&session_));
- session_.StreamDraining(i, /*unidirectional=*/false);
- EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(&session_));
- }
-}
-
-// TODO(b/171463363): Remove.
-TEST_P(QuicSpdySessionTestServer, ReduceMaxPushId) {
- 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()
- : QuicSpdySessionTestBase(Perspective::IS_CLIENT, false) {}
-};
-
-INSTANTIATE_TEST_SUITE_P(Tests, QuicSpdySessionTestClient,
- ::testing::ValuesIn(AllSupportedVersions()),
- ::testing::PrintToStringParamName());
-
-TEST_P(QuicSpdySessionTestClient, UsesPendingStreamsForFrame) {
- if (!VersionUsesHttp3(transport_version())) {
- return;
- }
- EXPECT_TRUE(session_.UsesPendingStreamForFrame(
- STREAM_FRAME, QuicUtils::GetFirstUnidirectionalStreamId(
- transport_version(), Perspective::IS_SERVER)));
- EXPECT_TRUE(session_.UsesPendingStreamForFrame(
- RST_STREAM_FRAME, QuicUtils::GetFirstUnidirectionalStreamId(
- transport_version(), Perspective::IS_SERVER)));
- EXPECT_FALSE(session_.UsesPendingStreamForFrame(
- RST_STREAM_FRAME, QuicUtils::GetFirstUnidirectionalStreamId(
- transport_version(), Perspective::IS_CLIENT)));
- EXPECT_FALSE(session_.UsesPendingStreamForFrame(
- STOP_SENDING_FRAME, QuicUtils::GetFirstUnidirectionalStreamId(
- transport_version(), Perspective::IS_SERVER)));
- EXPECT_FALSE(session_.UsesPendingStreamForFrame(
- RST_STREAM_FRAME, QuicUtils::GetFirstBidirectionalStreamId(
- transport_version(), Perspective::IS_SERVER)));
-}
-
-// Regression test for crbug.com/977581.
-TEST_P(QuicSpdySessionTestClient, BadStreamFramePendingStream) {
- if (!VersionUsesHttp3(transport_version())) {
- return;
- }
-
- EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(&session_));
- QuicStreamId stream_id1 =
- GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 0);
- // A bad stream frame with no data and no fin.
- QuicStreamFrame data1(stream_id1, false, 0, 0);
- session_.OnStreamFrame(data1);
-}
-
-TEST_P(QuicSpdySessionTestClient, PendingStreamKeepsConnectionAlive) {
- if (!VersionUsesHttp3(transport_version())) {
- return;
- }
-
- QuicStreamId stream_id = QuicUtils::GetFirstUnidirectionalStreamId(
- transport_version(), Perspective::IS_SERVER);
-
- QuicStreamFrame frame(stream_id, false, 1, "test");
- EXPECT_FALSE(session_.ShouldKeepConnectionAlive());
- session_.OnStreamFrame(frame);
- EXPECT_TRUE(QuicSessionPeer::GetPendingStream(&session_, stream_id));
- EXPECT_TRUE(session_.ShouldKeepConnectionAlive());
-}
-
-TEST_P(QuicSpdySessionTestClient, AvailableStreamsClient) {
- ASSERT_TRUE(session_.GetOrCreateStream(
- GetNthServerInitiatedBidirectionalId(2)) != nullptr);
- // Both server initiated streams with smaller stream IDs should be available.
- EXPECT_TRUE(QuicSessionPeer::IsStreamAvailable(
- &session_, GetNthServerInitiatedBidirectionalId(0)));
- EXPECT_TRUE(QuicSessionPeer::IsStreamAvailable(
- &session_, GetNthServerInitiatedBidirectionalId(1)));
- ASSERT_TRUE(session_.GetOrCreateStream(
- GetNthServerInitiatedBidirectionalId(0)) != nullptr);
- ASSERT_TRUE(session_.GetOrCreateStream(
- GetNthServerInitiatedBidirectionalId(1)) != nullptr);
- // And client initiated stream ID should be not available.
- EXPECT_FALSE(QuicSessionPeer::IsStreamAvailable(
- &session_, GetNthClientInitiatedBidirectionalId(0)));
-}
-
-// Regression test for b/130740258 and https://crbug.com/971779.
-// If headers that are too large or empty are received (these cases are handled
-// the same way, as QuicHeaderList clears itself when headers exceed the limit),
-// then the stream is reset. No more frames must be sent in this case.
-TEST_P(QuicSpdySessionTestClient, TooLargeHeadersMustNotCauseWriteAfterReset) {
- // In IETF QUIC, HEADERS do not carry FIN flag, and OnStreamHeaderList() is
- // never called after an error, including too large headers.
- if (VersionUsesHttp3(transport_version())) {
- return;
- }
- CompleteHandshake();
- TestStream* stream = session_.CreateOutgoingBidirectionalStream();
-
- EXPECT_CALL(*writer_, WritePacket(_, _, _, _, _))
- .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 0)));
- // Write headers with FIN set to close write side of stream.
- // Header block does not matter.
- stream->WriteHeaders(SpdyHeaderBlock(), /* fin = */ true, nullptr);
-
- // Receive headers that are too large or empty, with FIN set.
- // This causes the stream to be reset. No frames must be written after this.
- QuicHeaderList headers;
- EXPECT_CALL(*connection_, SendControlFrame(_));
- EXPECT_CALL(*connection_,
- OnStreamReset(stream->id(), QUIC_HEADERS_TOO_LARGE));
- stream->OnStreamHeaderList(/* fin = */ true,
- headers.uncompressed_header_bytes(), headers);
-}
-
-TEST_P(QuicSpdySessionTestClient, RecordFinAfterReadSideClosed) {
- // Verify that an incoming FIN is recorded in a stream object even if the read
- // side has been closed. This prevents an entry from being made in
- // locally_closed_streams_highest_offset_ (which will never be deleted).
- CompleteHandshake();
- TestStream* stream = session_.CreateOutgoingBidirectionalStream();
- QuicStreamId stream_id = stream->id();
-
- // Close the read side manually.
- QuicStreamPeer::CloseReadSide(stream);
-
- // Receive a stream data frame with FIN.
- QuicStreamFrame frame(stream_id, true, 0, absl::string_view());
- session_.OnStreamFrame(frame);
- EXPECT_TRUE(stream->fin_received());
-
- // Reset stream locally.
- EXPECT_CALL(*connection_, SendControlFrame(_));
- EXPECT_CALL(*connection_, OnStreamReset(stream->id(), _));
- stream->Reset(QUIC_STREAM_CANCELLED);
- EXPECT_TRUE(QuicStreamPeer::read_side_closed(stream));
-
- EXPECT_TRUE(connection_->connected());
- EXPECT_TRUE(QuicSessionPeer::IsStreamClosed(&session_, stream_id));
- EXPECT_FALSE(QuicSessionPeer::IsStreamCreated(&session_, stream_id));
-
- // The stream is not waiting for the arrival of the peer's final offset as it
- // was received with the FIN earlier.
- EXPECT_EQ(
- 0u,
- QuicSessionPeer::GetLocallyClosedStreamsHighestOffset(&session_).size());
-}
-
-TEST_P(QuicSpdySessionTestClient, WritePriority) {
- if (VersionUsesHttp3(transport_version())) {
- // IETF QUIC currently doesn't support PRIORITY.
- return;
- }
- CompleteHandshake();
-
- TestHeadersStream* headers_stream;
- QuicSpdySessionPeer::SetHeadersStream(&session_, nullptr);
- headers_stream = new TestHeadersStream(&session_);
- QuicSpdySessionPeer::SetHeadersStream(&session_, headers_stream);
-
- // Make packet writer blocked so |headers_stream| will buffer its write data.
- EXPECT_CALL(*writer_, IsWriteBlocked()).WillRepeatedly(Return(true));
-
- const QuicStreamId id = 4;
- const QuicStreamId parent_stream_id = 9;
- const SpdyPriority priority = kV3HighestPriority;
- const bool exclusive = true;
- session_.WritePriority(id, parent_stream_id,
- Spdy3PriorityToHttp2Weight(priority), exclusive);
-
- QuicStreamSendBuffer& send_buffer =
- QuicStreamPeer::SendBuffer(headers_stream);
- ASSERT_EQ(1u, send_buffer.size());
-
- SpdyPriorityIR priority_frame(
- id, parent_stream_id, Spdy3PriorityToHttp2Weight(priority), exclusive);
- SpdyFramer spdy_framer(SpdyFramer::ENABLE_COMPRESSION);
- SpdySerializedFrame frame = spdy_framer.SerializeFrame(priority_frame);
-
- const QuicMemSlice& slice =
- QuicStreamSendBufferPeer::CurrentWriteSlice(&send_buffer)->slice;
- EXPECT_EQ(absl::string_view(frame.data(), frame.size()),
- absl::string_view(slice.data(), slice.length()));
-}
-
-TEST_P(QuicSpdySessionTestClient, Http3ServerPush) {
- if (!VersionUsesHttp3(transport_version())) {
- return;
- }
-
- EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(&session_));
-
- // Push unidirectional stream is type 0x01.
- std::string frame_type1 = absl::HexStringToBytes("01");
- QuicStreamId stream_id1 =
- GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 0);
- EXPECT_CALL(*connection_,
- CloseConnection(QUIC_HTTP_RECEIVE_SERVER_PUSH, _, _))
- .Times(1);
- session_.OnStreamFrame(QuicStreamFrame(stream_id1, /* fin = */ false,
- /* offset = */ 0, frame_type1));
-}
-
-TEST_P(QuicSpdySessionTestClient, Http3ServerPushOutofOrderFrame) {
- if (!VersionUsesHttp3(transport_version())) {
- return;
- }
-
- EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(&session_));
-
- // Push unidirectional stream is type 0x01.
- std::string frame_type = absl::HexStringToBytes("01");
- // The first field of a push stream is the Push ID.
- std::string push_id = absl::HexStringToBytes("4000");
-
- QuicStreamId stream_id =
- GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 0);
-
- QuicStreamFrame data1(stream_id,
- /* fin = */ false, /* offset = */ 0, frame_type);
- QuicStreamFrame data2(stream_id,
- /* fin = */ false, /* offset = */ frame_type.size(),
- push_id);
-
- // Receiving some stream data without stream type does not open the stream.
- session_.OnStreamFrame(data2);
- EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(&session_));
- EXPECT_CALL(*connection_,
- CloseConnection(QUIC_HTTP_RECEIVE_SERVER_PUSH, _, _))
- .Times(1);
- session_.OnStreamFrame(data1);
-}
-
-TEST_P(QuicSpdySessionTestServer, OnStreamFrameLost) {
- CompleteHandshake();
- InSequence s;
-
- // Drive congestion control manually.
- MockSendAlgorithm* send_algorithm = new StrictMock<MockSendAlgorithm>;
- QuicConnectionPeer::SetSendAlgorithm(session_.connection(), send_algorithm);
-
- TestCryptoStream* crypto_stream = session_.GetMutableCryptoStream();
- TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
- TestStream* stream4 = session_.CreateOutgoingBidirectionalStream();
-
- QuicStreamFrame frame2(stream2->id(), false, 0, 9);
- QuicStreamFrame frame3(stream4->id(), false, 0, 9);
-
- // Lost data on cryption stream, streams 2 and 4.
- EXPECT_CALL(*stream4, HasPendingRetransmission()).WillOnce(Return(true));
- if (!QuicVersionUsesCryptoFrames(transport_version())) {
- EXPECT_CALL(*crypto_stream, HasPendingRetransmission())
- .WillOnce(Return(true));
- }
- EXPECT_CALL(*stream2, HasPendingRetransmission()).WillOnce(Return(true));
- session_.OnFrameLost(QuicFrame(frame3));
- if (!QuicVersionUsesCryptoFrames(transport_version())) {
- QuicStreamFrame frame1(QuicUtils::GetCryptoStreamId(transport_version()),
- false, 0, 1300);
- session_.OnFrameLost(QuicFrame(frame1));
- } else {
- QuicCryptoFrame crypto_frame(ENCRYPTION_INITIAL, 0, 1300);
- session_.OnFrameLost(QuicFrame(&crypto_frame));
- }
- session_.OnFrameLost(QuicFrame(frame2));
- EXPECT_TRUE(session_.WillingAndAbleToWrite());
-
- // Mark streams 2 and 4 write blocked.
- session_.MarkConnectionLevelWriteBlocked(stream2->id());
- session_.MarkConnectionLevelWriteBlocked(stream4->id());
-
- // Lost data is retransmitted before new data, and retransmissions for crypto
- // stream go first.
- // Do not check congestion window when crypto stream has lost data.
- EXPECT_CALL(*send_algorithm, CanSend(_)).Times(0);
- if (!QuicVersionUsesCryptoFrames(transport_version())) {
- EXPECT_CALL(*crypto_stream, OnCanWrite());
- EXPECT_CALL(*crypto_stream, HasPendingRetransmission())
- .WillOnce(Return(false));
- }
- // Check congestion window for non crypto streams.
- EXPECT_CALL(*send_algorithm, CanSend(_)).WillOnce(Return(true));
- EXPECT_CALL(*stream4, OnCanWrite());
- EXPECT_CALL(*stream4, HasPendingRetransmission()).WillOnce(Return(false));
- // Connection is blocked.
- EXPECT_CALL(*send_algorithm, CanSend(_)).WillRepeatedly(Return(false));
-
- session_.OnCanWrite();
- EXPECT_TRUE(session_.WillingAndAbleToWrite());
-
- // Unblock connection.
- // Stream 2 retransmits lost data.
- EXPECT_CALL(*send_algorithm, CanSend(_)).WillOnce(Return(true));
- EXPECT_CALL(*stream2, OnCanWrite());
- EXPECT_CALL(*stream2, HasPendingRetransmission()).WillOnce(Return(false));
- EXPECT_CALL(*send_algorithm, CanSend(_)).WillOnce(Return(true));
- // Stream 2 sends new data.
- EXPECT_CALL(*stream2, OnCanWrite());
- EXPECT_CALL(*send_algorithm, CanSend(_)).WillOnce(Return(true));
- EXPECT_CALL(*stream4, OnCanWrite());
- EXPECT_CALL(*send_algorithm, OnApplicationLimited(_));
-
- session_.OnCanWrite();
- EXPECT_FALSE(session_.WillingAndAbleToWrite());
-}
-
-TEST_P(QuicSpdySessionTestServer, DonotRetransmitDataOfClosedStreams) {
- // Resetting a stream will send a QPACK Stream Cancellation instruction on the
- // decoder stream. For simplicity, ignore writes on this stream.
- CompleteHandshake();
- NoopQpackStreamSenderDelegate qpack_stream_sender_delegate;
- if (VersionUsesHttp3(transport_version())) {
- session_.qpack_decoder()->set_qpack_stream_sender_delegate(
- &qpack_stream_sender_delegate);
- }
-
- InSequence s;
-
- TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
- TestStream* stream4 = session_.CreateOutgoingBidirectionalStream();
- TestStream* stream6 = session_.CreateOutgoingBidirectionalStream();
-
- QuicStreamFrame frame1(stream2->id(), false, 0, 9);
- QuicStreamFrame frame2(stream4->id(), false, 0, 9);
- QuicStreamFrame frame3(stream6->id(), false, 0, 9);
-
- EXPECT_CALL(*stream6, HasPendingRetransmission()).WillOnce(Return(true));
- EXPECT_CALL(*stream4, HasPendingRetransmission()).WillOnce(Return(true));
- EXPECT_CALL(*stream2, HasPendingRetransmission()).WillOnce(Return(true));
- session_.OnFrameLost(QuicFrame(frame3));
- session_.OnFrameLost(QuicFrame(frame2));
- session_.OnFrameLost(QuicFrame(frame1));
-
- session_.MarkConnectionLevelWriteBlocked(stream2->id());
- session_.MarkConnectionLevelWriteBlocked(stream4->id());
- session_.MarkConnectionLevelWriteBlocked(stream6->id());
-
- // Reset stream 4 locally.
- EXPECT_CALL(*connection_, SendControlFrame(_));
- EXPECT_CALL(*connection_, OnStreamReset(stream4->id(), _));
- stream4->Reset(QUIC_STREAM_CANCELLED);
-
- // Verify stream 4 is removed from streams with lost data list.
- EXPECT_CALL(*stream6, OnCanWrite());
- EXPECT_CALL(*stream6, HasPendingRetransmission()).WillOnce(Return(false));
- EXPECT_CALL(*stream2, OnCanWrite());
- EXPECT_CALL(*stream2, HasPendingRetransmission()).WillOnce(Return(false));
- EXPECT_CALL(*connection_, SendControlFrame(_))
- .WillRepeatedly(Invoke(&ClearControlFrame));
- EXPECT_CALL(*stream2, OnCanWrite());
- EXPECT_CALL(*stream6, OnCanWrite());
- session_.OnCanWrite();
-}
-
-TEST_P(QuicSpdySessionTestServer, RetransmitFrames) {
- CompleteHandshake();
- MockSendAlgorithm* send_algorithm = new StrictMock<MockSendAlgorithm>;
- QuicConnectionPeer::SetSendAlgorithm(session_.connection(), send_algorithm);
- InSequence s;
-
- TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
- TestStream* stream4 = session_.CreateOutgoingBidirectionalStream();
- TestStream* stream6 = session_.CreateOutgoingBidirectionalStream();
- EXPECT_CALL(*connection_, SendControlFrame(_))
- .WillOnce(Invoke(&ClearControlFrame));
- session_.SendWindowUpdate(stream2->id(), 9);
-
- QuicStreamFrame frame1(stream2->id(), false, 0, 9);
- QuicStreamFrame frame2(stream4->id(), false, 0, 9);
- QuicStreamFrame frame3(stream6->id(), false, 0, 9);
- QuicWindowUpdateFrame window_update(1, stream2->id(), 9);
- QuicFrames frames;
- frames.push_back(QuicFrame(frame1));
- frames.push_back(QuicFrame(&window_update));
- frames.push_back(QuicFrame(frame2));
- frames.push_back(QuicFrame(frame3));
- EXPECT_FALSE(session_.WillingAndAbleToWrite());
-
- EXPECT_CALL(*stream2, RetransmitStreamData(_, _, _, _))
- .WillOnce(Return(true));
- EXPECT_CALL(*connection_, SendControlFrame(_))
- .WillOnce(Invoke(&ClearControlFrame));
- EXPECT_CALL(*stream4, RetransmitStreamData(_, _, _, _))
- .WillOnce(Return(true));
- EXPECT_CALL(*stream6, RetransmitStreamData(_, _, _, _))
- .WillOnce(Return(true));
- EXPECT_CALL(*send_algorithm, OnApplicationLimited(_));
- session_.RetransmitFrames(frames, TLP_RETRANSMISSION);
-}
-
-TEST_P(QuicSpdySessionTestServer, OnPriorityFrame) {
- QuicStreamId stream_id = GetNthClientInitiatedBidirectionalId(0);
- TestStream* stream = session_.CreateIncomingStream(stream_id);
- session_.OnPriorityFrame(stream_id,
- spdy::SpdyStreamPrecedence(kV3HighestPriority));
- EXPECT_EQ(spdy::SpdyStreamPrecedence(kV3HighestPriority),
- stream->precedence());
-}
-
-TEST_P(QuicSpdySessionTestServer, OnPriorityUpdateFrame) {
- if (!VersionUsesHttp3(transport_version())) {
- return;
- }
-
- StrictMock<MockHttp3DebugVisitor> debug_visitor;
- session_.set_debug_visitor(&debug_visitor);
-
- // Create control stream.
- QuicStreamId receive_control_stream_id =
- GetNthClientInitiatedUnidirectionalStreamId(transport_version(), 3);
- char type[] = {kControlStream};
- absl::string_view stream_type(type, 1);
- QuicStreamOffset offset = 0;
- QuicStreamFrame data1(receive_control_stream_id, false, offset, stream_type);
- offset += stream_type.length();
- EXPECT_CALL(debug_visitor,
- OnPeerControlStreamCreated(receive_control_stream_id));
- session_.OnStreamFrame(data1);
- EXPECT_EQ(receive_control_stream_id,
- QuicSpdySessionPeer::GetReceiveControlStream(&session_)->id());
-
- // Send SETTINGS frame.
- std::string serialized_settings = EncodeSettings({});
- QuicStreamFrame data2(receive_control_stream_id, false, offset,
- serialized_settings);
- offset += serialized_settings.length();
- EXPECT_CALL(debug_visitor, OnSettingsFrameReceived(_));
- session_.OnStreamFrame(data2);
-
- // PRIORITY_UPDATE frame for first request stream.
- const QuicStreamId stream_id1 = GetNthClientInitiatedBidirectionalId(0);
- struct PriorityUpdateFrame priority_update1;
- priority_update1.prioritized_element_type = REQUEST_STREAM;
- priority_update1.prioritized_element_id = stream_id1;
- priority_update1.priority_field_value = "u=2";
- std::string serialized_priority_update1 =
- SerializePriorityUpdateFrame(priority_update1);
- QuicStreamFrame data3(receive_control_stream_id,
- /* fin = */ false, offset, serialized_priority_update1);
- offset += serialized_priority_update1.size();
-
- // PRIORITY_UPDATE frame arrives after stream creation.
- TestStream* stream1 = session_.CreateIncomingStream(stream_id1);
- EXPECT_EQ(QuicStream::kDefaultUrgency,
- stream1->precedence().spdy3_priority());
- EXPECT_CALL(debug_visitor, OnPriorityUpdateFrameReceived(priority_update1));
- session_.OnStreamFrame(data3);
- EXPECT_EQ(2u, stream1->precedence().spdy3_priority());
-
- // PRIORITY_UPDATE frame for second request stream.
- const QuicStreamId stream_id2 = GetNthClientInitiatedBidirectionalId(1);
- struct PriorityUpdateFrame priority_update2;
- priority_update2.prioritized_element_type = REQUEST_STREAM;
- priority_update2.prioritized_element_id = stream_id2;
- priority_update2.priority_field_value = "u=2";
- std::string serialized_priority_update2 =
- SerializePriorityUpdateFrame(priority_update2);
- QuicStreamFrame stream_frame3(receive_control_stream_id,
- /* fin = */ false, offset,
- serialized_priority_update2);
-
- // PRIORITY_UPDATE frame arrives before stream creation,
- // priority value is buffered.
- EXPECT_CALL(debug_visitor, OnPriorityUpdateFrameReceived(priority_update2));
- session_.OnStreamFrame(stream_frame3);
- // Priority is applied upon stream construction.
- TestStream* stream2 = session_.CreateIncomingStream(stream_id2);
- EXPECT_EQ(2u, stream2->precedence().spdy3_priority());
-}
-
-TEST_P(QuicSpdySessionTestServer, SimplePendingStreamType) {
- if (!VersionUsesHttp3(transport_version())) {
- return;
- }
- CompleteHandshake();
- char input[] = {0x04, // type
- 'a', 'b', 'c'}; // data
- absl::string_view payload(input, ABSL_ARRAYSIZE(input));
-
- // This is a server test with a client-initiated unidirectional stream.
- QuicStreamId stream_id = QuicUtils::GetFirstUnidirectionalStreamId(
- transport_version(), Perspective::IS_CLIENT);
-
- for (bool fin : {true, false}) {
- QuicStreamFrame frame(stream_id, fin, /* offset = */ 0, payload);
-
- // A STOP_SENDING frame is sent in response to the unknown stream type.
- EXPECT_CALL(*connection_, SendControlFrame(_))
- .WillOnce(Invoke([stream_id](const QuicFrame& frame) {
- EXPECT_EQ(STOP_SENDING_FRAME, frame.type);
-
- QuicStopSendingFrame* stop_sending = frame.stop_sending_frame;
- EXPECT_EQ(stream_id, stop_sending->stream_id);
- EXPECT_EQ(QUIC_STREAM_STREAM_CREATION_ERROR,
- stop_sending->error_code);
- EXPECT_EQ(
- static_cast<uint64_t>(QuicHttp3ErrorCode::STREAM_CREATION_ERROR),
- stop_sending->ietf_error_code);
-
- return ClearControlFrame(frame);
- }));
- session_.OnStreamFrame(frame);
-
- PendingStream* pending =
- QuicSessionPeer::GetPendingStream(&session_, stream_id);
- if (fin) {
- // Stream is closed if FIN is received.
- EXPECT_FALSE(pending);
- } else {
- ASSERT_TRUE(pending);
- // The pending stream must ignore read data.
- EXPECT_TRUE(pending->sequencer()->ignore_read_data());
- }
-
- stream_id += QuicUtils::StreamIdDelta(transport_version());
- }
-}
-
-TEST_P(QuicSpdySessionTestServer, SimplePendingStreamTypeOutOfOrderDelivery) {
- if (!VersionUsesHttp3(transport_version())) {
- return;
- }
- CompleteHandshake();
- char input[] = {0x04, // type
- 'a', 'b', 'c'}; // data
- absl::string_view payload(input, ABSL_ARRAYSIZE(input));
-
- // This is a server test with a client-initiated unidirectional stream.
- QuicStreamId stream_id = QuicUtils::GetFirstUnidirectionalStreamId(
- transport_version(), Perspective::IS_CLIENT);
-
- for (bool fin : {true, false}) {
- QuicStreamFrame frame1(stream_id, /* fin = */ false, /* offset = */ 0,
- payload.substr(0, 1));
- QuicStreamFrame frame2(stream_id, fin, /* offset = */ 1, payload.substr(1));
-
- // Deliver frames out of order.
- session_.OnStreamFrame(frame2);
- // A STOP_SENDING frame is sent in response to the unknown stream type.
- EXPECT_CALL(*connection_, SendControlFrame(_))
- .WillOnce(Invoke(&VerifyAndClearStopSendingFrame));
- session_.OnStreamFrame(frame1);
-
- PendingStream* pending =
- QuicSessionPeer::GetPendingStream(&session_, stream_id);
- if (fin) {
- // Stream is closed if FIN is received.
- EXPECT_FALSE(pending);
- } else {
- ASSERT_TRUE(pending);
- // The pending stream must ignore read data.
- EXPECT_TRUE(pending->sequencer()->ignore_read_data());
- }
-
- stream_id += QuicUtils::StreamIdDelta(transport_version());
- }
-}
-
-TEST_P(QuicSpdySessionTestServer,
- MultipleBytesPendingStreamTypeOutOfOrderDelivery) {
- if (!VersionUsesHttp3(transport_version())) {
- return;
- }
- CompleteHandshake();
- char input[] = {0x41, 0x00, // type (256)
- 'a', 'b', 'c'}; // data
- absl::string_view payload(input, ABSL_ARRAYSIZE(input));
-
- // This is a server test with a client-initiated unidirectional stream.
- QuicStreamId stream_id = QuicUtils::GetFirstUnidirectionalStreamId(
- transport_version(), Perspective::IS_CLIENT);
-
- for (bool fin : {true, false}) {
- QuicStreamFrame frame1(stream_id, /* fin = */ false, /* offset = */ 0,
- payload.substr(0, 1));
- QuicStreamFrame frame2(stream_id, /* fin = */ false, /* offset = */ 1,
- payload.substr(1, 1));
- QuicStreamFrame frame3(stream_id, fin, /* offset = */ 2, payload.substr(2));
-
- // Deliver frames out of order.
- session_.OnStreamFrame(frame3);
- // The first byte does not contain the entire type varint.
- session_.OnStreamFrame(frame1);
- // A STOP_SENDING frame is sent in response to the unknown stream type.
- EXPECT_CALL(*connection_, SendControlFrame(_))
- .WillOnce(Invoke(&VerifyAndClearStopSendingFrame));
- session_.OnStreamFrame(frame2);
-
- PendingStream* pending =
- QuicSessionPeer::GetPendingStream(&session_, stream_id);
- if (fin) {
- // Stream is closed if FIN is received.
- EXPECT_FALSE(pending);
- } else {
- ASSERT_TRUE(pending);
- // The pending stream must ignore read data.
- EXPECT_TRUE(pending->sequencer()->ignore_read_data());
- }
-
- stream_id += QuicUtils::StreamIdDelta(transport_version());
- }
-}
-
-TEST_P(QuicSpdySessionTestServer, ReceiveControlStream) {
- if (!VersionUsesHttp3(transport_version())) {
- return;
- }
-
- CompleteHandshake();
- StrictMock<MockHttp3DebugVisitor> debug_visitor;
- session_.set_debug_visitor(&debug_visitor);
-
- // Use an arbitrary stream id.
- QuicStreamId stream_id =
- GetNthClientInitiatedUnidirectionalStreamId(transport_version(), 3);
- char type[] = {kControlStream};
-
- QuicStreamFrame data1(stream_id, false, 0, absl::string_view(type, 1));
- EXPECT_CALL(debug_visitor, OnPeerControlStreamCreated(stream_id));
- session_.OnStreamFrame(data1);
- EXPECT_EQ(stream_id,
- QuicSpdySessionPeer::GetReceiveControlStream(&session_)->id());
-
- SettingsFrame settings;
- settings.values[SETTINGS_QPACK_MAX_TABLE_CAPACITY] = 512;
- settings.values[SETTINGS_MAX_FIELD_SECTION_SIZE] = 5;
- settings.values[SETTINGS_QPACK_BLOCKED_STREAMS] = 42;
- std::string data = EncodeSettings(settings);
- QuicStreamFrame frame(stream_id, false, 1, absl::string_view(data));
-
- QpackEncoder* qpack_encoder = session_.qpack_encoder();
- QpackEncoderHeaderTable* header_table =
- QpackEncoderPeer::header_table(qpack_encoder);
-
- EXPECT_NE(512u, header_table->maximum_dynamic_table_capacity());
- EXPECT_NE(5u, session_.max_outbound_header_list_size());
- EXPECT_NE(42u, QpackEncoderPeer::maximum_blocked_streams(qpack_encoder));
-
- EXPECT_CALL(debug_visitor, OnSettingsFrameReceived(settings));
- session_.OnStreamFrame(frame);
-
- EXPECT_EQ(512u, header_table->maximum_dynamic_table_capacity());
- EXPECT_EQ(5u, session_.max_outbound_header_list_size());
- EXPECT_EQ(42u, QpackEncoderPeer::maximum_blocked_streams(qpack_encoder));
-}
-
-TEST_P(QuicSpdySessionTestServer, ReceiveControlStreamOutOfOrderDelivery) {
- if (!VersionUsesHttp3(transport_version())) {
- return;
- }
- // Use an arbitrary stream id.
- QuicStreamId stream_id =
- GetNthClientInitiatedUnidirectionalStreamId(transport_version(), 3);
- char type[] = {kControlStream};
- SettingsFrame settings;
- settings.values[10] = 2;
- settings.values[SETTINGS_MAX_FIELD_SECTION_SIZE] = 5;
- std::string data = EncodeSettings(settings);
-
- QuicStreamFrame data1(stream_id, false, 1, absl::string_view(data));
- QuicStreamFrame data2(stream_id, false, 0, absl::string_view(type, 1));
-
- session_.OnStreamFrame(data1);
- EXPECT_NE(5u, session_.max_outbound_header_list_size());
- session_.OnStreamFrame(data2);
- EXPECT_EQ(5u, session_.max_outbound_header_list_size());
-}
-
-// Regression test for https://crbug.com/1009551.
-TEST_P(QuicSpdySessionTestServer, StreamClosedWhileHeaderDecodingBlocked) {
- if (!VersionUsesHttp3(transport_version())) {
- return;
- }
- CompleteHandshake();
- session_.qpack_decoder()->OnSetDynamicTableCapacity(1024);
-
- QuicStreamId stream_id = GetNthClientInitiatedBidirectionalId(0);
- TestStream* stream = session_.CreateIncomingStream(stream_id);
-
- // HEADERS frame referencing first dynamic table entry.
- std::string headers_payload = absl::HexStringToBytes("020080");
- std::unique_ptr<char[]> headers_buffer;
- QuicByteCount headers_frame_header_length =
- HttpEncoder::SerializeHeadersFrameHeader(headers_payload.length(),
- &headers_buffer);
- absl::string_view headers_frame_header(headers_buffer.get(),
- headers_frame_header_length);
- std::string headers = absl::StrCat(headers_frame_header, headers_payload);
- stream->OnStreamFrame(QuicStreamFrame(stream_id, false, 0, headers));
-
- // Decoding is blocked because dynamic table entry has not been received yet.
- EXPECT_FALSE(stream->headers_decompressed());
-
- // Stream is closed and destroyed.
- CloseStream(stream_id);
- session_.CleanUpClosedStreams();
-
- // Dynamic table entry arrived on the decoder stream.
- // The destroyed stream object must not be referenced.
- session_.qpack_decoder()->OnInsertWithoutNameReference("foo", "bar");
-}
-
-// Regression test for https://crbug.com/1011294.
-TEST_P(QuicSpdySessionTestServer, SessionDestroyedWhileHeaderDecodingBlocked) {
- if (!VersionUsesHttp3(transport_version())) {
- return;
- }
-
- session_.qpack_decoder()->OnSetDynamicTableCapacity(1024);
-
- QuicStreamId stream_id = GetNthClientInitiatedBidirectionalId(0);
- TestStream* stream = session_.CreateIncomingStream(stream_id);
-
- // HEADERS frame referencing first dynamic table entry.
- std::string headers_payload = absl::HexStringToBytes("020080");
- std::unique_ptr<char[]> headers_buffer;
- QuicByteCount headers_frame_header_length =
- HttpEncoder::SerializeHeadersFrameHeader(headers_payload.length(),
- &headers_buffer);
- absl::string_view headers_frame_header(headers_buffer.get(),
- headers_frame_header_length);
- std::string headers = absl::StrCat(headers_frame_header, headers_payload);
- stream->OnStreamFrame(QuicStreamFrame(stream_id, false, 0, headers));
-
- // Decoding is blocked because dynamic table entry has not been received yet.
- EXPECT_FALSE(stream->headers_decompressed());
-
- // |session_| gets destoyed. That destroys QpackDecoder, a member of
- // QuicSpdySession (derived class), which destroys QpackDecoderHeaderTable.
- // Then |*stream|, owned by QuicSession (base class) get destroyed, which
- // destroys QpackProgessiveDecoder, a registered Observer of
- // QpackDecoderHeaderTable. This must not cause a crash.
-}
-
-TEST_P(QuicSpdySessionTestClient, ResetAfterInvalidIncomingStreamType) {
- if (!VersionUsesHttp3(transport_version())) {
- return;
- }
- CompleteHandshake();
-
- const QuicStreamId stream_id =
- GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 0);
- ASSERT_TRUE(session_.UsesPendingStreamForFrame(STREAM_FRAME, stream_id));
-
- // Payload consists of two bytes. The first byte is an unknown unidirectional
- // stream type. The second one would be the type of a push stream, but it
- // must not be interpreted as stream type.
- std::string payload = absl::HexStringToBytes("3f01");
- QuicStreamFrame frame(stream_id, /* fin = */ false, /* offset = */ 0,
- payload);
-
- // A STOP_SENDING frame is sent in response to the unknown stream type.
- EXPECT_CALL(*connection_, SendControlFrame(_))
- .WillOnce(Invoke(&VerifyAndClearStopSendingFrame));
- session_.OnStreamFrame(frame);
-
- // There are no active streams.
- EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(&session_));
-
- // The pending stream is still around, because it did not receive a FIN.
- PendingStream* pending =
- QuicSessionPeer::GetPendingStream(&session_, stream_id);
- ASSERT_TRUE(pending);
-
- // The pending stream must ignore read data.
- EXPECT_TRUE(pending->sequencer()->ignore_read_data());
-
- // If the stream frame is received again, it should be ignored.
- session_.OnStreamFrame(frame);
-
- // Receive RESET_STREAM.
- QuicRstStreamFrame rst_frame(kInvalidControlFrameId, stream_id,
- QUIC_STREAM_CANCELLED,
- /* bytes_written = */ payload.size());
-
- session_.OnRstStream(rst_frame);
-
- // The stream is closed.
- EXPECT_FALSE(QuicSessionPeer::GetPendingStream(&session_, stream_id));
-}
-
-TEST_P(QuicSpdySessionTestClient, FinAfterInvalidIncomingStreamType) {
- if (!VersionUsesHttp3(transport_version())) {
- return;
- }
- CompleteHandshake();
-
- const QuicStreamId stream_id =
- GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 0);
- ASSERT_TRUE(session_.UsesPendingStreamForFrame(STREAM_FRAME, stream_id));
-
- // Payload consists of two bytes. The first byte is an unknown unidirectional
- // stream type. The second one would be the type of a push stream, but it
- // must not be interpreted as stream type.
- std::string payload = absl::HexStringToBytes("3f01");
- QuicStreamFrame frame(stream_id, /* fin = */ false, /* offset = */ 0,
- payload);
-
- // A STOP_SENDING frame is sent in response to the unknown stream type.
- EXPECT_CALL(*connection_, SendControlFrame(_))
- .WillOnce(Invoke(&VerifyAndClearStopSendingFrame));
- session_.OnStreamFrame(frame);
-
- // The pending stream is still around, because it did not receive a FIN.
- PendingStream* pending =
- QuicSessionPeer::GetPendingStream(&session_, stream_id);
- EXPECT_TRUE(pending);
-
- // The pending stream must ignore read data.
- EXPECT_TRUE(pending->sequencer()->ignore_read_data());
-
- // If the stream frame is received again, it should be ignored.
- session_.OnStreamFrame(frame);
-
- // Receive FIN.
- session_.OnStreamFrame(QuicStreamFrame(stream_id, /* fin = */ true,
- /* offset = */ payload.size(), ""));
-
- EXPECT_FALSE(QuicSessionPeer::GetPendingStream(&session_, stream_id));
-}
-
-TEST_P(QuicSpdySessionTestClient, ResetInMiddleOfStreamType) {
- if (!VersionUsesHttp3(transport_version())) {
- return;
- }
-
- const QuicStreamId stream_id =
- GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 0);
- ASSERT_TRUE(session_.UsesPendingStreamForFrame(STREAM_FRAME, stream_id));
-
- // Payload is the first byte of a two byte varint encoding.
- std::string payload = absl::HexStringToBytes("40");
- QuicStreamFrame frame(stream_id, /* fin = */ false, /* offset = */ 0,
- payload);
-
- session_.OnStreamFrame(frame);
- EXPECT_TRUE(QuicSessionPeer::GetPendingStream(&session_, stream_id));
-
- // Receive RESET_STREAM.
- QuicRstStreamFrame rst_frame(kInvalidControlFrameId, stream_id,
- QUIC_STREAM_CANCELLED,
- /* bytes_written = */ payload.size());
-
- session_.OnRstStream(rst_frame);
-
- // The stream is closed.
- EXPECT_FALSE(QuicSessionPeer::GetPendingStream(&session_, stream_id));
-}
-
-TEST_P(QuicSpdySessionTestClient, FinInMiddleOfStreamType) {
- if (!VersionUsesHttp3(transport_version())) {
- return;
- }
-
- const QuicStreamId stream_id =
- GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 0);
- ASSERT_TRUE(session_.UsesPendingStreamForFrame(STREAM_FRAME, stream_id));
-
- // Payload is the first byte of a two byte varint encoding with a FIN.
- std::string payload = absl::HexStringToBytes("40");
- QuicStreamFrame frame(stream_id, /* fin = */ true, /* offset = */ 0, payload);
-
- session_.OnStreamFrame(frame);
- EXPECT_FALSE(QuicSessionPeer::GetPendingStream(&session_, stream_id));
-}
-
-TEST_P(QuicSpdySessionTestClient, DuplicateHttp3UnidirectionalStreams) {
- if (!VersionUsesHttp3(transport_version())) {
- return;
- }
-
- StrictMock<MockHttp3DebugVisitor> debug_visitor;
- session_.set_debug_visitor(&debug_visitor);
-
- QuicStreamId id1 =
- GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 0);
- char type1[] = {kControlStream};
-
- QuicStreamFrame data1(id1, false, 0, absl::string_view(type1, 1));
- EXPECT_CALL(debug_visitor, OnPeerControlStreamCreated(id1));
- session_.OnStreamFrame(data1);
- QuicStreamId id2 =
- GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 1);
- QuicStreamFrame data2(id2, false, 0, 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),
- "Received a duplicate Control stream: Closing connection.");
-
- QuicStreamId id3 =
- GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 2);
- char type2[]{kQpackEncoderStream};
-
- QuicStreamFrame data3(id3, false, 0, absl::string_view(type2, 1));
- EXPECT_CALL(debug_visitor, OnPeerQpackEncoderStreamCreated(id3));
- session_.OnStreamFrame(data3);
-
- QuicStreamId id4 =
- GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 3);
- QuicStreamFrame data4(id4, false, 0, 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),
- "Received a duplicate QPACK encoder stream: Closing connection.");
-
- QuicStreamId id5 =
- GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 4);
- char type3[]{kQpackDecoderStream};
-
- QuicStreamFrame data5(id5, false, 0, absl::string_view(type3, 1));
- EXPECT_CALL(debug_visitor, OnPeerQpackDecoderStreamCreated(id5));
- session_.OnStreamFrame(data5);
-
- QuicStreamId id6 =
- GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 5);
- QuicStreamFrame data6(id6, false, 0, 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),
- "Received a duplicate QPACK decoder stream: Closing connection.");
-}
-
-TEST_P(QuicSpdySessionTestClient, EncoderStreamError) {
- if (!VersionUsesHttp3(transport_version())) {
- return;
- }
-
- std::string data = absl::HexStringToBytes(
- "02" // Encoder stream.
- "00"); // Duplicate entry 0, but no entries exist.
-
- QuicStreamId stream_id =
- GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 0);
-
- QuicStreamFrame frame(stream_id, /* fin = */ false, /* offset = */ 0, data);
-
- EXPECT_CALL(*connection_,
- CloseConnection(
- QUIC_QPACK_ENCODER_STREAM_DUPLICATE_INVALID_RELATIVE_INDEX,
- "Encoder stream error: Invalid relative index.", _));
- session_.OnStreamFrame(frame);
-}
-
-TEST_P(QuicSpdySessionTestClient, DecoderStreamError) {
- if (!VersionUsesHttp3(transport_version())) {
- return;
- }
-
- std::string data = absl::HexStringToBytes(
- "03" // Decoder stream.
- "00"); // Insert Count Increment with forbidden increment value of zero.
-
- QuicStreamId stream_id =
- GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 0);
-
- QuicStreamFrame frame(stream_id, /* fin = */ false, /* offset = */ 0, data);
-
- EXPECT_CALL(
- *connection_,
- CloseConnection(QUIC_QPACK_DECODER_STREAM_INVALID_ZERO_INCREMENT,
- "Decoder stream error: Invalid increment value 0.", _));
- session_.OnStreamFrame(frame);
-}
-
-TEST_P(QuicSpdySessionTestClient, InvalidHttp3GoAway) {
- if (!VersionUsesHttp3(transport_version())) {
- return;
- }
- EXPECT_CALL(*connection_,
- CloseConnection(QUIC_HTTP_GOAWAY_INVALID_STREAM_ID,
- "GOAWAY with invalid stream ID", _));
- QuicStreamId stream_id =
- GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 0);
- session_.OnHttp3GoAway(stream_id);
-}
-
-TEST_P(QuicSpdySessionTestClient, Http3GoAwayLargerIdThanBefore) {
- if (!VersionUsesHttp3(transport_version())) {
- return;
- }
-
- EXPECT_FALSE(session_.goaway_received());
- QuicStreamId stream_id1 =
- GetNthClientInitiatedBidirectionalStreamId(transport_version(), 0);
- session_.OnHttp3GoAway(stream_id1);
- EXPECT_TRUE(session_.goaway_received());
-
- EXPECT_CALL(
- *connection_,
- CloseConnection(
- QUIC_HTTP_GOAWAY_ID_LARGER_THAN_PREVIOUS,
- "GOAWAY received with ID 4 greater than previously received ID 0",
- _));
- QuicStreamId stream_id2 =
- GetNthClientInitiatedBidirectionalStreamId(transport_version(), 1);
- session_.OnHttp3GoAway(stream_id2);
-}
-
-TEST_P(QuicSpdySessionTestClient, CloseConnectionOnCancelPush) {
- if (!VersionUsesHttp3(transport_version())) {
- return;
- }
-
- StrictMock<MockHttp3DebugVisitor> debug_visitor;
- session_.set_debug_visitor(&debug_visitor);
-
- // Create control stream.
- QuicStreamId receive_control_stream_id =
- GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 3);
- char type[] = {kControlStream};
- absl::string_view stream_type(type, 1);
- QuicStreamOffset offset = 0;
- QuicStreamFrame data1(receive_control_stream_id, /* fin = */ false, offset,
- stream_type);
- offset += stream_type.length();
- EXPECT_CALL(debug_visitor,
- OnPeerControlStreamCreated(receive_control_stream_id));
- session_.OnStreamFrame(data1);
- EXPECT_EQ(receive_control_stream_id,
- QuicSpdySessionPeer::GetReceiveControlStream(&session_)->id());
-
- // First frame has to be SETTINGS.
- std::string serialized_settings = EncodeSettings({});
- QuicStreamFrame data2(receive_control_stream_id, /* fin = */ false, offset,
- serialized_settings);
- offset += serialized_settings.length();
- EXPECT_CALL(debug_visitor, OnSettingsFrameReceived(_));
- session_.OnStreamFrame(data2);
-
- std::string cancel_push_frame = absl::HexStringToBytes(
- "03" // CANCEL_PUSH
- "01" // length
- "00"); // push ID
- QuicStreamFrame data3(receive_control_stream_id, /* fin = */ false, offset,
- cancel_push_frame);
- EXPECT_CALL(*connection_, CloseConnection(QUIC_HTTP_FRAME_ERROR,
- "CANCEL_PUSH frame received.", _))
- .WillOnce(
- Invoke(connection_, &MockQuicConnection::ReallyCloseConnection));
- EXPECT_CALL(*connection_,
- SendConnectionClosePacket(QUIC_HTTP_FRAME_ERROR, _,
- "CANCEL_PUSH frame received."));
- session_.OnStreamFrame(data3);
-}
-
-TEST_P(QuicSpdySessionTestServer, OnSetting) {
- CompleteHandshake();
- if (VersionUsesHttp3(transport_version())) {
- EXPECT_EQ(std::numeric_limits<size_t>::max(),
- session_.max_outbound_header_list_size());
- session_.OnSetting(SETTINGS_MAX_FIELD_SECTION_SIZE, 5);
- EXPECT_EQ(5u, session_.max_outbound_header_list_size());
-
- EXPECT_CALL(*writer_, WritePacket(_, _, _, _, _))
- .WillRepeatedly(Return(WriteResult(WRITE_STATUS_OK, 0)));
- QpackEncoder* qpack_encoder = session_.qpack_encoder();
- EXPECT_EQ(0u, QpackEncoderPeer::maximum_blocked_streams(qpack_encoder));
- session_.OnSetting(SETTINGS_QPACK_BLOCKED_STREAMS, 12);
- EXPECT_EQ(12u, QpackEncoderPeer::maximum_blocked_streams(qpack_encoder));
-
- QpackEncoderHeaderTable* header_table =
- QpackEncoderPeer::header_table(qpack_encoder);
- EXPECT_EQ(0u, header_table->maximum_dynamic_table_capacity());
- session_.OnSetting(SETTINGS_QPACK_MAX_TABLE_CAPACITY, 37);
- EXPECT_EQ(37u, header_table->maximum_dynamic_table_capacity());
-
- return;
- }
-
- EXPECT_EQ(std::numeric_limits<size_t>::max(),
- session_.max_outbound_header_list_size());
- session_.OnSetting(SETTINGS_MAX_FIELD_SECTION_SIZE, 5);
- EXPECT_EQ(5u, session_.max_outbound_header_list_size());
-
- spdy::HpackEncoder* hpack_encoder =
- QuicSpdySessionPeer::GetSpdyFramer(&session_)->GetHpackEncoder();
- EXPECT_EQ(4096u, hpack_encoder->CurrentHeaderTableSizeSetting());
- session_.OnSetting(spdy::SETTINGS_HEADER_TABLE_SIZE, 59);
- EXPECT_EQ(59u, hpack_encoder->CurrentHeaderTableSizeSetting());
-}
-
-TEST_P(QuicSpdySessionTestServer, FineGrainedHpackErrorCodes) {
- if (VersionUsesHttp3(transport_version())) {
- // HPACK is not used in HTTP/3.
- return;
- }
-
- QuicStreamId request_stream_id = 5;
- session_.CreateIncomingStream(request_stream_id);
-
- // Index 126 does not exist (static table has 61 entries and dynamic table is
- // empty).
- std::string headers_frame = absl::HexStringToBytes(
- "000006" // length
- "01" // type
- "24" // flags: PRIORITY | END_HEADERS
- "00000005" // stream_id
- "00000000" // stream dependency
- "10" // weight
- "fe"); // payload: reference to index 126.
- QuicStreamId headers_stream_id =
- QuicUtils::GetHeadersStreamId(transport_version());
- QuicStreamFrame data(headers_stream_id, false, 0, headers_frame);
-
- EXPECT_CALL(
- *connection_,
- CloseConnection(QUIC_HPACK_INVALID_INDEX,
- "SPDY framing error: HPACK_INVALID_INDEX",
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET));
- session_.OnStreamFrame(data);
-}
-
-TEST_P(QuicSpdySessionTestServer, PeerClosesCriticalReceiveStream) {
- if (!VersionUsesHttp3(transport_version())) {
- return;
- }
-
- struct {
- char type;
- const char* error_details;
- } kTestData[] = {
- {kControlStream, "RESET_STREAM received for receive control stream"},
- {kQpackEncoderStream, "RESET_STREAM received for QPACK receive stream"},
- {kQpackDecoderStream, "RESET_STREAM received for QPACK receive stream"},
- };
- for (size_t i = 0; i < ABSL_ARRAYSIZE(kTestData); ++i) {
- QuicStreamId stream_id =
- GetNthClientInitiatedUnidirectionalStreamId(transport_version(), i + 1);
- const QuicByteCount data_length = 1;
- QuicStreamFrame data(stream_id, false, 0,
- absl::string_view(&kTestData[i].type, data_length));
- session_.OnStreamFrame(data);
-
- EXPECT_CALL(*connection_, CloseConnection(QUIC_HTTP_CLOSED_CRITICAL_STREAM,
- kTestData[i].error_details, _));
-
- QuicRstStreamFrame rst(kInvalidControlFrameId, stream_id,
- QUIC_STREAM_CANCELLED, data_length);
- session_.OnRstStream(rst);
- }
-}
-
-TEST_P(QuicSpdySessionTestServer,
- H3ControlStreamsLimitedByConnectionFlowControl) {
- if (!VersionUsesHttp3(transport_version())) {
- return;
- }
- // Ensure connection level flow control blockage.
- QuicFlowControllerPeer::SetSendWindowOffset(session_.flow_controller(), 0);
- EXPECT_TRUE(session_.IsConnectionFlowControlBlocked());
-
- QuicSendControlStream* send_control_stream =
- QuicSpdySessionPeer::GetSendControlStream(&session_);
- // Mark send_control stream write blocked.
- session_.MarkConnectionLevelWriteBlocked(send_control_stream->id());
- EXPECT_FALSE(session_.WillingAndAbleToWrite());
-}
-
-TEST_P(QuicSpdySessionTestServer, PeerClosesCriticalSendStream) {
- if (!VersionUsesHttp3(transport_version())) {
- return;
- }
-
- QuicSendControlStream* control_stream =
- QuicSpdySessionPeer::GetSendControlStream(&session_);
- ASSERT_TRUE(control_stream);
-
- QuicStopSendingFrame stop_sending_control_stream(
- kInvalidControlFrameId, control_stream->id(), QUIC_STREAM_CANCELLED);
- EXPECT_CALL(
- *connection_,
- CloseConnection(QUIC_HTTP_CLOSED_CRITICAL_STREAM,
- "STOP_SENDING received for send control stream", _));
- session_.OnStopSendingFrame(stop_sending_control_stream);
-
- QpackSendStream* decoder_stream =
- QuicSpdySessionPeer::GetQpackDecoderSendStream(&session_);
- ASSERT_TRUE(decoder_stream);
-
- QuicStopSendingFrame stop_sending_decoder_stream(
- kInvalidControlFrameId, decoder_stream->id(), QUIC_STREAM_CANCELLED);
- EXPECT_CALL(
- *connection_,
- CloseConnection(QUIC_HTTP_CLOSED_CRITICAL_STREAM,
- "STOP_SENDING received for QPACK send stream", _));
- session_.OnStopSendingFrame(stop_sending_decoder_stream);
-
- QpackSendStream* encoder_stream =
- QuicSpdySessionPeer::GetQpackEncoderSendStream(&session_);
- ASSERT_TRUE(encoder_stream);
-
- QuicStopSendingFrame stop_sending_encoder_stream(
- kInvalidControlFrameId, encoder_stream->id(), QUIC_STREAM_CANCELLED);
- EXPECT_CALL(
- *connection_,
- CloseConnection(QUIC_HTTP_CLOSED_CRITICAL_STREAM,
- "STOP_SENDING received for QPACK send stream", _));
- session_.OnStopSendingFrame(stop_sending_encoder_stream);
-}
-
-TEST_P(QuicSpdySessionTestServer, CloseConnectionOnCancelPush) {
- if (!VersionUsesHttp3(transport_version())) {
- return;
- }
-
- StrictMock<MockHttp3DebugVisitor> debug_visitor;
- session_.set_debug_visitor(&debug_visitor);
-
- // Create control stream.
- QuicStreamId receive_control_stream_id =
- GetNthClientInitiatedUnidirectionalStreamId(transport_version(), 3);
- char type[] = {kControlStream};
- absl::string_view stream_type(type, 1);
- QuicStreamOffset offset = 0;
- QuicStreamFrame data1(receive_control_stream_id, /* fin = */ false, offset,
- stream_type);
- offset += stream_type.length();
- EXPECT_CALL(debug_visitor,
- OnPeerControlStreamCreated(receive_control_stream_id));
- session_.OnStreamFrame(data1);
- EXPECT_EQ(receive_control_stream_id,
- QuicSpdySessionPeer::GetReceiveControlStream(&session_)->id());
-
- // First frame has to be SETTINGS.
- std::string serialized_settings = EncodeSettings({});
- QuicStreamFrame data2(receive_control_stream_id, /* fin = */ false, offset,
- serialized_settings);
- offset += serialized_settings.length();
- EXPECT_CALL(debug_visitor, OnSettingsFrameReceived(_));
- session_.OnStreamFrame(data2);
-
- std::string cancel_push_frame = absl::HexStringToBytes(
- "03" // CANCEL_PUSH
- "01" // length
- "00"); // push ID
- QuicStreamFrame data3(receive_control_stream_id, /* fin = */ false, offset,
- cancel_push_frame);
- EXPECT_CALL(*connection_, CloseConnection(QUIC_HTTP_FRAME_ERROR,
- "CANCEL_PUSH frame received.", _))
- .WillOnce(
- Invoke(connection_, &MockQuicConnection::ReallyCloseConnection));
- EXPECT_CALL(*connection_,
- SendConnectionClosePacket(QUIC_HTTP_FRAME_ERROR, _,
- "CANCEL_PUSH frame received."));
- session_.OnStreamFrame(data3);
-}
-
-TEST_P(QuicSpdySessionTestServer, Http3GoAwayWhenClosingConnection) {
- if (!VersionUsesHttp3(transport_version())) {
- return;
- }
-
- StrictMock<MockHttp3DebugVisitor> debug_visitor;
- session_.set_debug_visitor(&debug_visitor);
-
- EXPECT_CALL(debug_visitor, OnSettingsFrameSent(_));
- CompleteHandshake();
-
- QuicStreamId stream_id = GetNthClientInitiatedBidirectionalId(0);
-
- // Create stream by receiving some data (CreateIncomingStream() would not
- // update the session's largest peer created stream ID).
- const size_t headers_payload_length = 10;
- std::unique_ptr<char[]> headers_buffer;
- QuicByteCount headers_frame_header_length =
- HttpEncoder::SerializeHeadersFrameHeader(headers_payload_length,
- &headers_buffer);
- absl::string_view headers_frame_header(headers_buffer.get(),
- headers_frame_header_length);
- EXPECT_CALL(debug_visitor,
- OnHeadersFrameReceived(stream_id, headers_payload_length));
- session_.OnStreamFrame(
- QuicStreamFrame(stream_id, false, 0, headers_frame_header));
-
- EXPECT_EQ(stream_id, QuicSessionPeer::GetLargestPeerCreatedStreamId(
- &session_, /*unidirectional = */ false));
-
- // Stream with stream_id is already received and potentially processed,
- // therefore a GOAWAY frame is sent with the next stream ID.
- EXPECT_CALL(debug_visitor,
- OnGoAwayFrameSent(stream_id +
- QuicUtils::StreamIdDelta(transport_version())));
-
- // Close connection.
- EXPECT_CALL(*writer_, WritePacket(_, _, _, _, _))
- .WillRepeatedly(Return(WriteResult(WRITE_STATUS_OK, 0)));
- EXPECT_CALL(*connection_, CloseConnection(QUIC_NO_ERROR, _, _))
- .WillOnce(
- Invoke(connection_, &MockQuicConnection::ReallyCloseConnection));
- EXPECT_CALL(*connection_, SendConnectionClosePacket(QUIC_NO_ERROR, _, _))
- .WillOnce(Invoke(connection_,
- &MockQuicConnection::ReallySendConnectionClosePacket));
- connection_->CloseConnection(
- QUIC_NO_ERROR, "closing connection",
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
-}
-
-TEST_P(QuicSpdySessionTestClient, DoNotSendInitialMaxPushIdIfNotSet) {
- if (!VersionUsesHttp3(transport_version())) {
- return;
- }
-
- StrictMock<MockHttp3DebugVisitor> debug_visitor;
- session_.set_debug_visitor(&debug_visitor);
-
- InSequence s;
- EXPECT_CALL(debug_visitor, OnSettingsFrameSent(_));
-
- CompleteHandshake();
-}
-
-TEST_P(QuicSpdySessionTestClient, ReceiveSpdySettingInHttp3) {
- if (!VersionUsesHttp3(transport_version())) {
- return;
- }
-
- SettingsFrame frame;
- frame.values[SETTINGS_MAX_FIELD_SECTION_SIZE] = 5;
- // https://datatracker.ietf.org/doc/html/draft-ietf-quic-http-30#section-7.2.4.1
- // specifies the presence of HTTP/2 setting as error.
- frame.values[spdy::SETTINGS_INITIAL_WINDOW_SIZE] = 100;
-
- CompleteHandshake();
-
- EXPECT_CALL(*connection_,
- CloseConnection(QUIC_HTTP_RECEIVE_SPDY_SETTING, _, _));
- session_.OnSettingsFrame(frame);
-}
-
-TEST_P(QuicSpdySessionTestClient, ReceiveAcceptChFrame) {
- if (!VersionUsesHttp3(transport_version())) {
- return;
- }
-
- StrictMock<MockHttp3DebugVisitor> debug_visitor;
- session_.set_debug_visitor(&debug_visitor);
-
- // Create control stream.
- QuicStreamId receive_control_stream_id =
- GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 3);
- char type[] = {kControlStream};
- absl::string_view stream_type(type, 1);
- QuicStreamOffset offset = 0;
- QuicStreamFrame data1(receive_control_stream_id, /* fin = */ false, offset,
- stream_type);
- offset += stream_type.length();
- EXPECT_CALL(debug_visitor,
- OnPeerControlStreamCreated(receive_control_stream_id));
-
- session_.OnStreamFrame(data1);
- EXPECT_EQ(receive_control_stream_id,
- QuicSpdySessionPeer::GetReceiveControlStream(&session_)->id());
-
- // First frame has to be SETTINGS.
- std::string serialized_settings = EncodeSettings({});
- QuicStreamFrame data2(receive_control_stream_id, /* fin = */ false, offset,
- serialized_settings);
- offset += serialized_settings.length();
- EXPECT_CALL(debug_visitor, OnSettingsFrameReceived(_));
-
- session_.OnStreamFrame(data2);
-
- // Receive ACCEPT_CH frame.
- AcceptChFrame accept_ch;
- accept_ch.entries.push_back({"foo", "bar"});
- std::unique_ptr<char[]> buffer;
- auto frame_length = HttpEncoder::SerializeAcceptChFrame(accept_ch, &buffer);
- QuicStreamFrame data3(receive_control_stream_id, /* fin = */ false, offset,
- absl::string_view(buffer.get(), frame_length));
-
- EXPECT_CALL(debug_visitor, OnAcceptChFrameReceived(accept_ch));
- EXPECT_CALL(session_, OnAcceptChFrame(accept_ch));
-
- session_.OnStreamFrame(data3);
-}
-
-TEST_P(QuicSpdySessionTestClient, AcceptChViaAlps) {
- if (!VersionUsesHttp3(transport_version())) {
- return;
- }
-
- StrictMock<MockHttp3DebugVisitor> debug_visitor;
- session_.set_debug_visitor(&debug_visitor);
-
- std::string serialized_accept_ch_frame = absl::HexStringToBytes(
- "4089" // type (ACCEPT_CH)
- "08" // length
- "03" // length of origin
- "666f6f" // origin "foo"
- "03" // length of value
- "626172"); // value "bar"
-
- AcceptChFrame expected_accept_ch_frame{{{"foo", "bar"}}};
- EXPECT_CALL(debug_visitor,
- OnAcceptChFrameReceivedViaAlps(expected_accept_ch_frame));
-
- auto error = session_.OnAlpsData(
- reinterpret_cast<const uint8_t*>(serialized_accept_ch_frame.data()),
- serialized_accept_ch_frame.size());
- EXPECT_FALSE(error);
-}
-
-TEST_P(QuicSpdySessionTestClient, AlpsForbiddenFrame) {
- if (!VersionUsesHttp3(transport_version())) {
- return;
- }
-
- std::string forbidden_frame = absl::HexStringToBytes(
- "00" // type (DATA)
- "03" // length
- "66666f"); // "foo"
-
- auto error = session_.OnAlpsData(
- reinterpret_cast<const uint8_t*>(forbidden_frame.data()),
- forbidden_frame.size());
- ASSERT_TRUE(error);
- EXPECT_EQ("DATA frame forbidden", error.value());
-}
-
-TEST_P(QuicSpdySessionTestClient, AlpsIncompleteFrame) {
- if (!VersionUsesHttp3(transport_version())) {
- return;
- }
-
- std::string incomplete_frame = absl::HexStringToBytes(
- "04" // type (SETTINGS)
- "03"); // non-zero length but empty payload
-
- auto error = session_.OnAlpsData(
- reinterpret_cast<const uint8_t*>(incomplete_frame.data()),
- incomplete_frame.size());
- ASSERT_TRUE(error);
- EXPECT_EQ("incomplete HTTP/3 frame", error.value());
-}
-
-// After receiving a SETTINGS frame via ALPS,
-// another SETTINGS frame is still allowed on control frame.
-TEST_P(QuicSpdySessionTestClient, SettingsViaAlpsThenOnControlStream) {
- if (!VersionUsesHttp3(transport_version())) {
- return;
- }
-
- QpackEncoder* qpack_encoder = session_.qpack_encoder();
- EXPECT_EQ(0u, qpack_encoder->MaximumDynamicTableCapacity());
- EXPECT_EQ(0u, qpack_encoder->maximum_blocked_streams());
-
- StrictMock<MockHttp3DebugVisitor> debug_visitor;
- session_.set_debug_visitor(&debug_visitor);
-
- std::string serialized_settings_frame1 = absl::HexStringToBytes(
- "04" // type (SETTINGS)
- "05" // length
- "01" // SETTINGS_QPACK_MAX_TABLE_CAPACITY
- "4400" // 0x0400 = 1024
- "07" // SETTINGS_QPACK_BLOCKED_STREAMS
- "20"); // 0x20 = 32
-
- SettingsFrame expected_settings_frame1{
- {{SETTINGS_QPACK_MAX_TABLE_CAPACITY, 1024},
- {SETTINGS_QPACK_BLOCKED_STREAMS, 32}}};
- EXPECT_CALL(debug_visitor,
- OnSettingsFrameReceivedViaAlps(expected_settings_frame1));
-
- auto error = session_.OnAlpsData(
- reinterpret_cast<const uint8_t*>(serialized_settings_frame1.data()),
- serialized_settings_frame1.size());
- EXPECT_FALSE(error);
-
- EXPECT_EQ(1024u, qpack_encoder->MaximumDynamicTableCapacity());
- EXPECT_EQ(32u, qpack_encoder->maximum_blocked_streams());
-
- const QuicStreamId control_stream_id =
- GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 0);
- EXPECT_CALL(debug_visitor, OnPeerControlStreamCreated(control_stream_id));
-
- std::string stream_type = absl::HexStringToBytes("00");
- session_.OnStreamFrame(QuicStreamFrame(control_stream_id, /* fin = */ false,
- /* offset = */ 0, stream_type));
-
- // SETTINGS_QPACK_MAX_TABLE_CAPACITY, if advertised again, MUST have identical
- // value.
- // SETTINGS_QPACK_BLOCKED_STREAMS is a limit. Limits MUST NOT be reduced, but
- // increasing is okay.
- SettingsFrame expected_settings_frame2{
- {{SETTINGS_QPACK_MAX_TABLE_CAPACITY, 1024},
- {SETTINGS_QPACK_BLOCKED_STREAMS, 48}}};
- EXPECT_CALL(debug_visitor, OnSettingsFrameReceived(expected_settings_frame2));
- std::string serialized_settings_frame2 = absl::HexStringToBytes(
- "04" // type (SETTINGS)
- "05" // length
- "01" // SETTINGS_QPACK_MAX_TABLE_CAPACITY
- "4400" // 0x0400 = 1024
- "07" // SETTINGS_QPACK_BLOCKED_STREAMS
- "30"); // 0x30 = 48
- session_.OnStreamFrame(QuicStreamFrame(control_stream_id, /* fin = */ false,
- /* offset = */ stream_type.length(),
- serialized_settings_frame2));
-
- EXPECT_EQ(1024u, qpack_encoder->MaximumDynamicTableCapacity());
- EXPECT_EQ(48u, qpack_encoder->maximum_blocked_streams());
-}
-
-// A SETTINGS frame received via ALPS and another one on the control stream
-// cannot have conflicting values.
-TEST_P(QuicSpdySessionTestClient,
- SettingsViaAlpsConflictsSettingsViaControlStream) {
- if (!VersionUsesHttp3(transport_version())) {
- return;
- }
-
- QpackEncoder* qpack_encoder = session_.qpack_encoder();
- EXPECT_EQ(0u, qpack_encoder->MaximumDynamicTableCapacity());
-
- std::string serialized_settings_frame1 = absl::HexStringToBytes(
- "04" // type (SETTINGS)
- "03" // length
- "01" // SETTINGS_QPACK_MAX_TABLE_CAPACITY
- "4400"); // 0x0400 = 1024
-
- auto error = session_.OnAlpsData(
- reinterpret_cast<const uint8_t*>(serialized_settings_frame1.data()),
- serialized_settings_frame1.size());
- EXPECT_FALSE(error);
-
- EXPECT_EQ(1024u, qpack_encoder->MaximumDynamicTableCapacity());
-
- const QuicStreamId control_stream_id =
- GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 0);
-
- std::string stream_type = absl::HexStringToBytes("00");
- session_.OnStreamFrame(QuicStreamFrame(control_stream_id, /* fin = */ false,
- /* offset = */ 0, stream_type));
-
- EXPECT_CALL(
- *connection_,
- CloseConnection(QUIC_HTTP_ZERO_RTT_RESUMPTION_SETTINGS_MISMATCH,
- "Server sent an SETTINGS_QPACK_MAX_TABLE_CAPACITY: "
- "32 while current value is: 1024",
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET));
- std::string serialized_settings_frame2 = absl::HexStringToBytes(
- "04" // type (SETTINGS)
- "02" // length
- "01" // SETTINGS_QPACK_MAX_TABLE_CAPACITY
- "20"); // 0x20 = 32
- session_.OnStreamFrame(QuicStreamFrame(control_stream_id, /* fin = */ false,
- /* offset = */ stream_type.length(),
- serialized_settings_frame2));
-}
-
-TEST_P(QuicSpdySessionTestClient, AlpsTwoSettingsFrame) {
- if (!VersionUsesHttp3(transport_version())) {
- return;
- }
-
- std::string banned_frame = absl::HexStringToBytes(
- "04" // type (SETTINGS)
- "00" // length
- "04" // type (SETTINGS)
- "00"); // length
-
- auto error =
- session_.OnAlpsData(reinterpret_cast<const uint8_t*>(banned_frame.data()),
- banned_frame.size());
- ASSERT_TRUE(error);
- EXPECT_EQ("multiple SETTINGS frames", error.value());
-}
-
-void QuicSpdySessionTestBase::TestHttpDatagramSetting(
- HttpDatagramSupport local_support, HttpDatagramSupport remote_support,
- HttpDatagramSupport expected_support, bool expected_datagram_supported) {
- if (!version().UsesHttp3()) {
- return;
- }
- session_.set_local_http_datagram_support(local_support);
- // HTTP/3 datagrams aren't supported before SETTINGS are received.
- EXPECT_FALSE(session_.SupportsH3Datagram());
- EXPECT_EQ(session_.http_datagram_support(), HttpDatagramSupport::kNone);
- // Receive SETTINGS.
- SettingsFrame settings;
- 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;
- settings.values[SETTINGS_H3_DATAGRAM_DRAFT04] = 1;
- break;
- }
- std::string data = std::string(1, kControlStream) + EncodeSettings(settings);
- QuicStreamId stream_id =
- GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 3);
- QuicStreamFrame frame(stream_id, /*fin=*/false, /*offset=*/0, data);
- StrictMock<MockHttp3DebugVisitor> debug_visitor;
- session_.set_debug_visitor(&debug_visitor);
- EXPECT_CALL(debug_visitor, OnPeerControlStreamCreated(stream_id));
- EXPECT_CALL(debug_visitor, OnSettingsFrameReceived(settings));
- session_.OnStreamFrame(frame);
- EXPECT_EQ(session_.http_datagram_support(), expected_support);
- EXPECT_EQ(session_.SupportsH3Datagram(), expected_datagram_supported);
-}
-
-TEST_P(QuicSpdySessionTestClient, HttpDatagramSettingLocal00Remote00) {
- TestHttpDatagramSetting(
- /*local_support=*/HttpDatagramSupport::kDraft00,
- /*remote_support=*/HttpDatagramSupport::kDraft00,
- /*expected_support=*/HttpDatagramSupport::kDraft00,
- /*expected_datagram_supported=*/true);
-}
-
-TEST_P(QuicSpdySessionTestClient, HttpDatagramSettingLocal00Remote04) {
- TestHttpDatagramSetting(
- /*local_support=*/HttpDatagramSupport::kDraft00,
- /*remote_support=*/HttpDatagramSupport::kDraft04,
- /*expected_support=*/HttpDatagramSupport::kNone,
- /*expected_datagram_supported=*/false);
-}
-
-TEST_P(QuicSpdySessionTestClient, HttpDatagramSettingLocal00Remote00And04) {
- TestHttpDatagramSetting(
- /*local_support=*/HttpDatagramSupport::kDraft00,
- /*remote_support=*/HttpDatagramSupport::kDraft00And04,
- /*expected_support=*/HttpDatagramSupport::kDraft00,
- /*expected_datagram_supported=*/true);
-}
-
-TEST_P(QuicSpdySessionTestClient, HttpDatagramSettingLocal04Remote00) {
- TestHttpDatagramSetting(
- /*local_support=*/HttpDatagramSupport::kDraft04,
- /*remote_support=*/HttpDatagramSupport::kDraft00,
- /*expected_support=*/HttpDatagramSupport::kNone,
- /*expected_datagram_supported=*/false);
-}
-
-TEST_P(QuicSpdySessionTestClient, HttpDatagramSettingLocal04Remote04) {
- TestHttpDatagramSetting(
- /*local_support=*/HttpDatagramSupport::kDraft04,
- /*remote_support=*/HttpDatagramSupport::kDraft04,
- /*expected_support=*/HttpDatagramSupport::kDraft04,
- /*expected_datagram_supported=*/true);
-}
-
-TEST_P(QuicSpdySessionTestClient, HttpDatagramSettingLocal04Remote00And04) {
- TestHttpDatagramSetting(
- /*local_support=*/HttpDatagramSupport::kDraft04,
- /*remote_support=*/HttpDatagramSupport::kDraft00And04,
- /*expected_support=*/HttpDatagramSupport::kDraft04,
- /*expected_datagram_supported=*/true);
-}
-
-TEST_P(QuicSpdySessionTestClient, HttpDatagramSettingLocal00And04Remote00) {
- TestHttpDatagramSetting(
- /*local_support=*/HttpDatagramSupport::kDraft00And04,
- /*remote_support=*/HttpDatagramSupport::kDraft00,
- /*expected_support=*/HttpDatagramSupport::kDraft00,
- /*expected_datagram_supported=*/true);
-}
-
-TEST_P(QuicSpdySessionTestClient, HttpDatagramSettingLocal00And04Remote04) {
- TestHttpDatagramSetting(
- /*local_support=*/HttpDatagramSupport::kDraft00And04,
- /*remote_support=*/HttpDatagramSupport::kDraft04,
- /*expected_support=*/HttpDatagramSupport::kDraft04,
- /*expected_datagram_supported=*/true);
-}
-
-TEST_P(QuicSpdySessionTestClient,
- HttpDatagramSettingLocal00And04Remote00And04) {
- TestHttpDatagramSetting(
- /*local_support=*/HttpDatagramSupport::kDraft00And04,
- /*remote_support=*/HttpDatagramSupport::kDraft00And04,
- /*expected_support=*/HttpDatagramSupport::kDraft04,
- /*expected_datagram_supported=*/true);
-}
-
-TEST_P(QuicSpdySessionTestClient, WebTransportSetting) {
- if (!version().UsesHttp3()) {
- return;
- }
- session_.set_local_http_datagram_support(HttpDatagramSupport::kDraft00And04);
- session_.set_supports_webtransport(true);
-
- EXPECT_FALSE(session_.SupportsWebTransport());
-
- StrictMock<MockHttp3DebugVisitor> debug_visitor;
- // Note that this does not actually fill out correct settings because the
- // settings are filled in at the construction time.
- EXPECT_CALL(debug_visitor, OnSettingsFrameSent(_));
- session_.set_debug_visitor(&debug_visitor);
- CompleteHandshake();
-
- EXPECT_CALL(debug_visitor, OnPeerControlStreamCreated(_));
- EXPECT_CALL(debug_visitor, OnSettingsFrameReceived(_));
- ReceiveWebTransportSettings();
- EXPECT_TRUE(session_.ShouldProcessIncomingRequests());
- EXPECT_TRUE(session_.SupportsWebTransport());
-}
-
-TEST_P(QuicSpdySessionTestClient, WebTransportSettingSetToZero) {
- if (!version().UsesHttp3()) {
- return;
- }
- session_.set_local_http_datagram_support(HttpDatagramSupport::kDraft00And04);
- session_.set_supports_webtransport(true);
-
- EXPECT_FALSE(session_.SupportsWebTransport());
-
- StrictMock<MockHttp3DebugVisitor> debug_visitor;
- // Note that this does not actually fill out correct settings because the
- // settings are filled in at the construction time.
- EXPECT_CALL(debug_visitor, OnSettingsFrameSent(_));
- session_.set_debug_visitor(&debug_visitor);
- CompleteHandshake();
-
- SettingsFrame server_settings;
- server_settings.values[SETTINGS_H3_DATAGRAM_DRAFT04] = 1;
- server_settings.values[SETTINGS_WEBTRANS_DRAFT00] = 0;
- std::string data =
- std::string(1, kControlStream) + EncodeSettings(server_settings);
- QuicStreamId stream_id =
- GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 3);
- QuicStreamFrame frame(stream_id, /*fin=*/false, /*offset=*/0, data);
- EXPECT_CALL(debug_visitor, OnPeerControlStreamCreated(stream_id));
- EXPECT_CALL(debug_visitor, OnSettingsFrameReceived(server_settings));
- session_.OnStreamFrame(frame);
- EXPECT_FALSE(session_.SupportsWebTransport());
-}
-
-TEST_P(QuicSpdySessionTestServer, WebTransportSetting) {
- if (!version().UsesHttp3()) {
- return;
- }
- session_.set_local_http_datagram_support(HttpDatagramSupport::kDraft00And04);
- session_.set_supports_webtransport(true);
-
- EXPECT_FALSE(session_.SupportsWebTransport());
- EXPECT_FALSE(session_.ShouldProcessIncomingRequests());
-
- CompleteHandshake();
-
- ReceiveWebTransportSettings();
- EXPECT_TRUE(session_.SupportsWebTransport());
- EXPECT_TRUE(session_.ShouldProcessIncomingRequests());
-}
-
-TEST_P(QuicSpdySessionTestServer, BufferingIncomingStreams) {
- if (!version().UsesHttp3()) {
- return;
- }
- session_.set_local_http_datagram_support(HttpDatagramSupport::kDraft00And04);
- session_.set_supports_webtransport(true);
-
- CompleteHandshake();
- QuicStreamId session_id =
- GetNthClientInitiatedBidirectionalStreamId(transport_version(), 1);
-
- QuicStreamId data_stream_id =
- GetNthClientInitiatedUnidirectionalStreamId(transport_version(), 4);
- ReceiveWebTransportUnidirectionalStream(session_id, data_stream_id);
-
- ReceiveWebTransportSettings();
-
- ReceiveWebTransportSession(session_id);
- WebTransportHttp3* web_transport =
- session_.GetWebTransportSession(session_id);
- ASSERT_TRUE(web_transport != nullptr);
-
- EXPECT_EQ(web_transport->NumberOfAssociatedStreams(), 1u);
-
- EXPECT_CALL(*connection_, SendControlFrame(_))
- .WillRepeatedly(Invoke(&ClearControlFrame));
- EXPECT_CALL(*connection_, OnStreamReset(session_id, _));
- EXPECT_CALL(
- *connection_,
- OnStreamReset(data_stream_id, QUIC_STREAM_WEBTRANSPORT_SESSION_GONE));
- session_.ResetStream(session_id, QUIC_STREAM_INTERNAL_ERROR);
-}
-
-TEST_P(QuicSpdySessionTestServer, BufferingIncomingStreamsLimit) {
- if (!version().UsesHttp3()) {
- return;
- }
- session_.set_local_http_datagram_support(HttpDatagramSupport::kDraft00And04);
- session_.set_supports_webtransport(true);
-
- CompleteHandshake();
- QuicStreamId session_id =
- GetNthClientInitiatedBidirectionalStreamId(transport_version(), 1);
-
- const int streams_to_send = kMaxUnassociatedWebTransportStreams + 4;
- EXPECT_CALL(*connection_, SendControlFrame(_))
- .WillRepeatedly(Invoke(&ClearControlFrame));
- EXPECT_CALL(*connection_,
- OnStreamReset(
- _, QUIC_STREAM_WEBTRANSPORT_BUFFERED_STREAMS_LIMIT_EXCEEDED))
- .Times(4);
- for (int i = 0; i < streams_to_send; i++) {
- QuicStreamId data_stream_id =
- GetNthClientInitiatedUnidirectionalStreamId(transport_version(), 4 + i);
- ReceiveWebTransportUnidirectionalStream(session_id, data_stream_id);
- }
-
- ReceiveWebTransportSettings();
-
- ReceiveWebTransportSession(session_id);
- WebTransportHttp3* web_transport =
- session_.GetWebTransportSession(session_id);
- ASSERT_TRUE(web_transport != nullptr);
-
- EXPECT_EQ(web_transport->NumberOfAssociatedStreams(),
- kMaxUnassociatedWebTransportStreams);
-
- EXPECT_CALL(*connection_, SendControlFrame(_))
- .WillRepeatedly(Invoke(&ClearControlFrame));
- EXPECT_CALL(*connection_, OnStreamReset(_, _))
- .Times(kMaxUnassociatedWebTransportStreams + 1);
- session_.ResetStream(session_id, QUIC_STREAM_INTERNAL_ERROR);
-}
-
-TEST_P(QuicSpdySessionTestServer, ResetOutgoingWebTransportStreams) {
- if (!version().UsesHttp3()) {
- return;
- }
- session_.set_local_http_datagram_support(HttpDatagramSupport::kDraft00And04);
- session_.set_supports_webtransport(true);
-
- CompleteHandshake();
- QuicStreamId session_id =
- GetNthClientInitiatedBidirectionalStreamId(transport_version(), 1);
-
- ReceiveWebTransportSettings();
- ReceiveWebTransportSession(session_id);
- WebTransportHttp3* web_transport =
- session_.GetWebTransportSession(session_id);
- ASSERT_TRUE(web_transport != nullptr);
-
- session_.set_writev_consumes_all_data(true);
- EXPECT_TRUE(web_transport->CanOpenNextOutgoingUnidirectionalStream());
- EXPECT_EQ(web_transport->NumberOfAssociatedStreams(), 0u);
- WebTransportStream* stream =
- web_transport->OpenOutgoingUnidirectionalStream();
- EXPECT_EQ(web_transport->NumberOfAssociatedStreams(), 1u);
- ASSERT_TRUE(stream != nullptr);
- QuicStreamId stream_id = stream->GetStreamId();
-
- EXPECT_CALL(*connection_, SendControlFrame(_))
- .WillRepeatedly(Invoke(&ClearControlFrame));
- EXPECT_CALL(*connection_, OnStreamReset(session_id, _));
- EXPECT_CALL(*connection_,
- OnStreamReset(stream_id, QUIC_STREAM_WEBTRANSPORT_SESSION_GONE));
- session_.ResetStream(session_id, QUIC_STREAM_INTERNAL_ERROR);
- EXPECT_EQ(web_transport->NumberOfAssociatedStreams(), 0u);
-}
-
-TEST_P(QuicSpdySessionTestClient, WebTransportWithoutExtendedConnect) {
- if (!version().UsesHttp3()) {
- return;
- }
- SetQuicReloadableFlag(quic_verify_request_headers_2, true);
- SetQuicReloadableFlag(quic_act_upon_invalid_header, true);
- session_.set_local_http_datagram_support(HttpDatagramSupport::kDraft00And04);
- session_.set_supports_webtransport(true);
-
- EXPECT_FALSE(session_.SupportsWebTransport());
- CompleteHandshake();
-
- SettingsFrame settings;
- settings.values[SETTINGS_H3_DATAGRAM_DRAFT04] = 1;
- settings.values[SETTINGS_WEBTRANS_DRAFT00] = 1;
- // No SETTINGS_ENABLE_CONNECT_PROTOCOL here.
- std::string data = std::string(1, kControlStream) + EncodeSettings(settings);
- QuicStreamId control_stream_id =
- session_.perspective() == Perspective::IS_SERVER
- ? GetNthClientInitiatedUnidirectionalStreamId(transport_version(), 3)
- : GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 3);
- QuicStreamFrame frame(control_stream_id, /*fin=*/false, /*offset=*/0, data);
- session_.OnStreamFrame(frame);
-
- EXPECT_TRUE(session_.SupportsWebTransport());
-}
-
-class QuicSpdySessionTestServerNoExtendedConnect
- : public QuicSpdySessionTestBase {
- public:
- QuicSpdySessionTestServerNoExtendedConnect()
- : QuicSpdySessionTestBase(Perspective::IS_SERVER, false) {}
-};
-
-INSTANTIATE_TEST_SUITE_P(Tests, QuicSpdySessionTestServerNoExtendedConnect,
- ::testing::ValuesIn(AllSupportedVersions()),
- ::testing::PrintToStringParamName());
-
-// Tests that receiving SETTINGS_ENABLE_CONNECT_PROTOCOL = 1 doesn't enable
-// server session to support extended CONNECT.
-TEST_P(QuicSpdySessionTestServerNoExtendedConnect,
- WebTransportSettingNoEffect) {
- if (!version().UsesHttp3()) {
- return;
- }
-
- EXPECT_FALSE(session_.SupportsWebTransport());
- EXPECT_TRUE(session_.ShouldProcessIncomingRequests());
-
- CompleteHandshake();
-
- ReceiveWebTransportSettings();
- EXPECT_FALSE(session_.allow_extended_connect());
- EXPECT_FALSE(session_.SupportsWebTransport());
- EXPECT_TRUE(session_.ShouldProcessIncomingRequests());
-}
-
-TEST_P(QuicSpdySessionTestServerNoExtendedConnect, BadExtendedConnectSetting) {
- if (!version().UsesHttp3()) {
- return;
- }
- SetQuicReloadableFlag(quic_verify_request_headers_2, true);
- SetQuicReloadableFlag(quic_act_upon_invalid_header, true);
-
- EXPECT_FALSE(session_.SupportsWebTransport());
- EXPECT_TRUE(session_.ShouldProcessIncomingRequests());
-
- CompleteHandshake();
-
- // ENABLE_CONNECT_PROTOCOL setting value has to be 1 or 0;
- SettingsFrame settings;
- settings.values[SETTINGS_ENABLE_CONNECT_PROTOCOL] = 2;
- std::string data = std::string(1, kControlStream) + EncodeSettings(settings);
- QuicStreamId control_stream_id =
- session_.perspective() == Perspective::IS_SERVER
- ? 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),
- "Received SETTINGS_ENABLE_CONNECT_PROTOCOL with invalid value");
-}
-
-} // namespace
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_stream.cc b/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_stream.cc
deleted file mode 100644
index 5317137d7e0..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_stream.cc
+++ /dev/null
@@ -1,1939 +0,0 @@
-// Copyright 2013 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 "quic/core/http/quic_spdy_stream.h"
-
-#include <limits>
-#include <memory>
-#include <string>
-#include <utility>
-
-#include "absl/base/macros.h"
-#include "absl/strings/numbers.h"
-#include "absl/strings/str_cat.h"
-#include "absl/strings/string_view.h"
-#include "http2/http2_constants.h"
-#include "quic/core/http/capsule.h"
-#include "quic/core/http/http_constants.h"
-#include "quic/core/http/http_decoder.h"
-#include "quic/core/http/http_frames.h"
-#include "quic/core/http/quic_spdy_session.h"
-#include "quic/core/http/spdy_utils.h"
-#include "quic/core/http/web_transport_http3.h"
-#include "quic/core/qpack/qpack_decoder.h"
-#include "quic/core/qpack/qpack_encoder.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_utils.h"
-#include "quic/core/quic_versions.h"
-#include "quic/core/quic_write_blocked_list.h"
-#include "quic/core/web_transport_interface.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_flag_utils.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/platform/api/quic_mem_slice_storage.h"
-#include "common/quiche_text_utils.h"
-#include "spdy/core/spdy_protocol.h"
-
-using spdy::SpdyHeaderBlock;
-using spdy::SpdyPriority;
-
-namespace quic {
-
-// Visitor of HttpDecoder that passes data frame to QuicSpdyStream and closes
-// the connection on unexpected frames.
-class QuicSpdyStream::HttpDecoderVisitor : public HttpDecoder::Visitor {
- public:
- explicit HttpDecoderVisitor(QuicSpdyStream* stream) : stream_(stream) {}
- HttpDecoderVisitor(const HttpDecoderVisitor&) = delete;
- HttpDecoderVisitor& operator=(const HttpDecoderVisitor&) = delete;
-
- void OnError(HttpDecoder* decoder) override {
- stream_->OnUnrecoverableError(decoder->error(), decoder->error_detail());
- }
-
- bool OnMaxPushIdFrame(const MaxPushIdFrame& /*frame*/) override {
- CloseConnectionOnWrongFrame("Max Push Id");
- return false;
- }
-
- bool OnGoAwayFrame(const GoAwayFrame& /*frame*/) override {
- CloseConnectionOnWrongFrame("Goaway");
- return false;
- }
-
- bool OnSettingsFrameStart(QuicByteCount /*header_length*/) override {
- CloseConnectionOnWrongFrame("Settings");
- return false;
- }
-
- bool OnSettingsFrame(const SettingsFrame& /*frame*/) override {
- CloseConnectionOnWrongFrame("Settings");
- return false;
- }
-
- bool OnDataFrameStart(QuicByteCount header_length,
- QuicByteCount payload_length) override {
- return stream_->OnDataFrameStart(header_length, payload_length);
- }
-
- bool OnDataFramePayload(absl::string_view payload) override {
- QUICHE_DCHECK(!payload.empty());
- return stream_->OnDataFramePayload(payload);
- }
-
- bool OnDataFrameEnd() override { return stream_->OnDataFrameEnd(); }
-
- bool OnHeadersFrameStart(QuicByteCount header_length,
- QuicByteCount payload_length) override {
- if (!VersionUsesHttp3(stream_->transport_version())) {
- CloseConnectionOnWrongFrame("Headers");
- return false;
- }
- return stream_->OnHeadersFrameStart(header_length, payload_length);
- }
-
- bool OnHeadersFramePayload(absl::string_view payload) override {
- QUICHE_DCHECK(!payload.empty());
- if (!VersionUsesHttp3(stream_->transport_version())) {
- CloseConnectionOnWrongFrame("Headers");
- return false;
- }
- return stream_->OnHeadersFramePayload(payload);
- }
-
- bool OnHeadersFrameEnd() override {
- if (!VersionUsesHttp3(stream_->transport_version())) {
- CloseConnectionOnWrongFrame("Headers");
- return false;
- }
- return stream_->OnHeadersFrameEnd();
- }
-
- bool OnPriorityUpdateFrameStart(QuicByteCount /*header_length*/) override {
- CloseConnectionOnWrongFrame("Priority update");
- return false;
- }
-
- bool OnPriorityUpdateFrame(const PriorityUpdateFrame& /*frame*/) override {
- CloseConnectionOnWrongFrame("Priority update");
- return false;
- }
-
- bool OnAcceptChFrameStart(QuicByteCount /*header_length*/) override {
- CloseConnectionOnWrongFrame("ACCEPT_CH");
- return false;
- }
-
- bool OnAcceptChFrame(const AcceptChFrame& /*frame*/) override {
- CloseConnectionOnWrongFrame("ACCEPT_CH");
- return false;
- }
-
- void OnWebTransportStreamFrameType(
- QuicByteCount header_length, WebTransportSessionId session_id) override {
- stream_->OnWebTransportStreamFrameType(header_length, session_id);
- }
-
- bool OnUnknownFrameStart(uint64_t frame_type, QuicByteCount header_length,
- QuicByteCount payload_length) override {
- return stream_->OnUnknownFrameStart(frame_type, header_length,
- payload_length);
- }
-
- bool OnUnknownFramePayload(absl::string_view payload) override {
- return stream_->OnUnknownFramePayload(payload);
- }
-
- bool OnUnknownFrameEnd() override { return stream_->OnUnknownFrameEnd(); }
-
- private:
- void CloseConnectionOnWrongFrame(absl::string_view frame_type) {
- stream_->OnUnrecoverableError(
- QUIC_HTTP_FRAME_UNEXPECTED_ON_SPDY_STREAM,
- absl::StrCat(frame_type, " frame received on data stream"));
- }
-
- QuicSpdyStream* stream_;
-};
-
-#define ENDPOINT \
- (session()->perspective() == Perspective::IS_SERVER ? "Server: " \
- : "Client:" \
- " ")
-
-namespace {
-HttpDecoder::Options HttpDecoderOptionsForBidiStream(
- QuicSpdySession* spdy_session) {
- HttpDecoder::Options options;
- options.allow_web_transport_stream =
- spdy_session->WillNegotiateWebTransport();
- return options;
-}
-} // namespace
-
-QuicSpdyStream::QuicSpdyStream(QuicStreamId id, QuicSpdySession* spdy_session,
- StreamType type)
- : QuicStream(id, spdy_session, /*is_static=*/false, type),
- spdy_session_(spdy_session),
- on_body_available_called_because_sequencer_is_closed_(false),
- visitor_(nullptr),
- blocked_on_decoding_headers_(false),
- headers_decompressed_(false),
- header_list_size_limit_exceeded_(false),
- headers_payload_length_(0),
- trailers_decompressed_(false),
- trailers_consumed_(false),
- qpack_decoded_headers_accumulator_reset_reason_(
- QpackDecodedHeadersAccumulatorResetReason::kUnSet),
- http_decoder_visitor_(std::make_unique<HttpDecoderVisitor>(this)),
- decoder_(http_decoder_visitor_.get(),
- HttpDecoderOptionsForBidiStream(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) {
- QUICHE_DCHECK_EQ(session()->connection(), spdy_session->connection());
- QUICHE_DCHECK_EQ(transport_version(), spdy_session->transport_version());
- QUICHE_DCHECK(!QuicUtils::IsCryptoStreamId(transport_version(), id));
- QUICHE_DCHECK_EQ(0u, sequencer()->NumBytesConsumed());
- // If headers are sent on the headers stream, then do not receive any
- // callbacks from the sequencer until headers are complete.
- if (!VersionUsesHttp3(transport_version())) {
- sequencer()->SetBlockedUntilFlush();
- }
-
- if (VersionUsesHttp3(transport_version())) {
- sequencer()->set_level_triggered(true);
- }
-
- spdy_session_->OnStreamCreated(this);
-}
-
-QuicSpdyStream::QuicSpdyStream(PendingStream* pending,
- QuicSpdySession* spdy_session)
- : QuicStream(pending, spdy_session, /*is_static=*/false),
- spdy_session_(spdy_session),
- on_body_available_called_because_sequencer_is_closed_(false),
- visitor_(nullptr),
- blocked_on_decoding_headers_(false),
- headers_decompressed_(false),
- header_list_size_limit_exceeded_(false),
- headers_payload_length_(0),
- trailers_decompressed_(false),
- trailers_consumed_(false),
- qpack_decoded_headers_accumulator_reset_reason_(
- QpackDecodedHeadersAccumulatorResetReason::kUnSet),
- http_decoder_visitor_(std::make_unique<HttpDecoderVisitor>(this)),
- decoder_(http_decoder_visitor_.get()),
- sequencer_offset_(sequencer()->NumBytesConsumed()),
- is_decoder_processing_input_(false),
- ack_listener_(nullptr),
- 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()));
- // If headers are sent on the headers stream, then do not receive any
- // callbacks from the sequencer until headers are complete.
- if (!VersionUsesHttp3(transport_version())) {
- sequencer()->SetBlockedUntilFlush();
- }
-
- if (VersionUsesHttp3(transport_version())) {
- sequencer()->set_level_triggered(true);
- }
-
- spdy_session_->OnStreamCreated(this);
-}
-
-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,
- QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener) {
- if (!AssertNotWebTransportDataStream("writing headers")) {
- return 0;
- }
-
- QuicConnection::ScopedPacketFlusher flusher(spdy_session_->connection());
- // Send stream type for server push stream
- if (VersionUsesHttp3(transport_version()) && type() == WRITE_UNIDIRECTIONAL &&
- send_buffer().stream_offset() == 0) {
- char data[sizeof(kServerPushStream)];
- QuicDataWriter writer(ABSL_ARRAYSIZE(data), data);
- writer.WriteVarInt62(kServerPushStream);
-
- // Similar to frame headers, stream type byte shouldn't be exposed to upper
- // layer applications.
- unacked_frame_headers_offsets_.Add(0, writer.length());
-
- QUIC_LOG(INFO) << ENDPOINT << "Stream " << id()
- << " is writing type as server push";
- WriteOrBufferData(absl::string_view(writer.data(), writer.length()), false,
- nullptr);
- }
-
- 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";
- }
-
- size_t bytes_written =
- WriteHeadersImpl(std::move(header_block), fin, std::move(ack_listener));
- if (!VersionUsesHttp3(transport_version()) && fin) {
- // If HEADERS are sent on the headers stream, then |fin_sent_| needs to be
- // set and write side needs to be closed without actually sending a FIN on
- // this stream.
- // TODO(rch): Add test to ensure fin_sent_ is set whenever a fin is sent.
- SetFinSent();
- CloseWriteSide();
- }
-
- 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());
- }
-
- return bytes_written;
-}
-
-void QuicSpdyStream::WriteOrBufferBody(absl::string_view data, bool fin) {
- if (!AssertNotWebTransportDataStream("writing body data")) {
- return;
- }
- if (!VersionUsesHttp3(transport_version()) || data.length() == 0) {
- WriteOrBufferData(data, fin, nullptr);
- return;
- }
- QuicConnection::ScopedPacketFlusher flusher(spdy_session_->connection());
-
- if (spdy_session_->debug_visitor()) {
- spdy_session_->debug_visitor()->OnDataFrameSent(id(), data.length());
- }
-
- const bool success =
- WriteDataFrameHeader(data.length(), /*force_write=*/true);
- QUICHE_DCHECK(success);
-
- // Write body.
- QUIC_DLOG(INFO) << ENDPOINT << "Stream " << id()
- << " is writing DATA frame payload of length "
- << data.length() << " with fin " << fin;
- WriteOrBufferData(data, fin, nullptr);
-}
-
-size_t QuicSpdyStream::WriteTrailers(
- SpdyHeaderBlock trailer_block,
- QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener) {
- if (fin_sent()) {
- QUIC_BUG(quic_bug_10410_1)
- << "Trailers cannot be sent after a FIN, on stream " << id();
- return 0;
- }
-
- if (!VersionUsesHttp3(transport_version())) {
- // The header block must contain the final offset for this stream, as the
- // trailers may be processed out of order at the peer.
- const QuicStreamOffset final_offset =
- stream_bytes_written() + BufferedDataBytes();
- QUIC_DLOG(INFO) << ENDPOINT << "Inserting trailer: ("
- << kFinalOffsetHeaderKey << ", " << final_offset << ")";
- trailer_block.insert(
- std::make_pair(kFinalOffsetHeaderKey, absl::StrCat(final_offset)));
- }
-
- // Write the trailing headers with a FIN, and close stream for writing:
- // trailers are the last thing to be sent on a stream.
- const bool kFin = true;
- size_t bytes_written =
- WriteHeadersImpl(std::move(trailer_block), kFin, std::move(ack_listener));
-
- // If trailers are sent on the headers stream, then |fin_sent_| needs to be
- // set without actually sending a FIN on this stream.
- if (!VersionUsesHttp3(transport_version())) {
- SetFinSent();
-
- // Also, write side of this stream needs to be closed. However, only do
- // this if there is no more buffered data, otherwise it will never be sent.
- if (BufferedDataBytes() == 0) {
- CloseWriteSide();
- }
- }
-
- return bytes_written;
-}
-
-QuicConsumedData QuicSpdyStream::WritevBody(const struct iovec* iov, int count,
- bool fin) {
- QuicMemSliceStorage storage(
- iov, count,
- session()->connection()->helper()->GetStreamSendBufferAllocator(),
- GetQuicFlag(FLAGS_quic_send_buffer_max_data_slice_size));
- return WriteBodySlices(storage.ToSpan(), fin);
-}
-
-bool QuicSpdyStream::WriteDataFrameHeader(QuicByteCount data_length,
- bool force_write) {
- QUICHE_DCHECK(VersionUsesHttp3(transport_version()));
- QUICHE_DCHECK_GT(data_length, 0u);
- QuicBuffer header = HttpEncoder::SerializeDataFrameHeader(
- data_length,
- spdy_session_->connection()->helper()->GetStreamSendBufferAllocator());
- const bool can_write = CanWriteNewDataAfterData(header.size());
- if (!can_write && !force_write) {
- return false;
- }
-
- if (spdy_session_->debug_visitor()) {
- spdy_session_->debug_visitor()->OnDataFrameSent(id(), data_length);
- }
-
- unacked_frame_headers_offsets_.Add(
- send_buffer().stream_offset(),
- send_buffer().stream_offset() + header.size());
- QUIC_DLOG(INFO) << ENDPOINT << "Stream " << id()
- << " is writing DATA frame header of length "
- << header.size();
- if (can_write) {
- // Save one copy and allocation if send buffer can accomodate the header.
- QuicMemSlice header_slice(std::move(header));
- WriteMemSlices(absl::MakeSpan(&header_slice, 1), false);
- } else {
- QUICHE_DCHECK(force_write);
- WriteOrBufferData(header.AsStringView(), false, nullptr);
- }
- return true;
-}
-
-QuicConsumedData QuicSpdyStream::WriteBodySlices(
- absl::Span<QuicMemSlice> slices, bool fin) {
- if (!VersionUsesHttp3(transport_version()) || slices.empty()) {
- return WriteMemSlices(slices, fin);
- }
-
- QuicConnection::ScopedPacketFlusher flusher(spdy_session_->connection());
- const QuicByteCount data_size = MemSliceSpanTotalSize(slices);
- if (!WriteDataFrameHeader(data_size, /*force_write=*/false)) {
- return {0, false};
- }
-
- QUIC_DLOG(INFO) << ENDPOINT << "Stream " << id()
- << " is writing DATA frame payload of length " << data_size;
- return WriteMemSlices(slices, fin);
-}
-
-size_t QuicSpdyStream::Readv(const struct iovec* iov, size_t iov_len) {
- QUICHE_DCHECK(FinishedReadingHeaders());
- if (!VersionUsesHttp3(transport_version())) {
- return sequencer()->Readv(iov, iov_len);
- }
- size_t bytes_read = 0;
- sequencer()->MarkConsumed(body_manager_.ReadBody(iov, iov_len, &bytes_read));
-
- return bytes_read;
-}
-
-int QuicSpdyStream::GetReadableRegions(iovec* iov, size_t iov_len) const {
- QUICHE_DCHECK(FinishedReadingHeaders());
- if (!VersionUsesHttp3(transport_version())) {
- return sequencer()->GetReadableRegions(iov, iov_len);
- }
- return body_manager_.PeekBody(iov, iov_len);
-}
-
-void QuicSpdyStream::MarkConsumed(size_t num_bytes) {
- QUICHE_DCHECK(FinishedReadingHeaders());
- if (!VersionUsesHttp3(transport_version())) {
- sequencer()->MarkConsumed(num_bytes);
- return;
- }
-
- sequencer()->MarkConsumed(body_manager_.OnBodyConsumed(num_bytes));
-}
-
-bool QuicSpdyStream::IsDoneReading() const {
- bool done_reading_headers = FinishedReadingHeaders();
- bool done_reading_body = sequencer()->IsClosed();
- bool done_reading_trailers = FinishedReadingTrailers();
- return done_reading_headers && done_reading_body && done_reading_trailers;
-}
-
-bool QuicSpdyStream::HasBytesToRead() const {
- if (!VersionUsesHttp3(transport_version())) {
- return sequencer()->HasBytesToRead();
- }
- return body_manager_.HasBytesToRead();
-}
-
-void QuicSpdyStream::MarkTrailersConsumed() { trailers_consumed_ = true; }
-
-uint64_t QuicSpdyStream::total_body_bytes_read() const {
- if (VersionUsesHttp3(transport_version())) {
- return body_manager_.total_body_bytes_received();
- }
- return sequencer()->NumBytesConsumed();
-}
-
-void QuicSpdyStream::ConsumeHeaderList() {
- header_list_.Clear();
-
- if (!FinishedReadingHeaders()) {
- return;
- }
-
- if (!VersionUsesHttp3(transport_version())) {
- sequencer()->SetUnblocked();
- return;
- }
-
- if (body_manager_.HasBytesToRead()) {
- HandleBodyAvailable();
- return;
- }
-
- if (sequencer()->IsClosed() &&
- !on_body_available_called_because_sequencer_is_closed_) {
- on_body_available_called_because_sequencer_is_closed_ = true;
- HandleBodyAvailable();
- }
-}
-
-void QuicSpdyStream::OnStreamHeadersPriority(
- const spdy::SpdyStreamPrecedence& precedence) {
- QUICHE_DCHECK_EQ(Perspective::IS_SERVER,
- session()->connection()->perspective());
- SetPriority(precedence);
-}
-
-void QuicSpdyStream::OnStreamHeaderList(bool fin, size_t frame_len,
- const QuicHeaderList& header_list) {
- if (!spdy_session()->user_agent_id().has_value()) {
- std::string uaid;
- for (const auto& kv : header_list) {
- if (quiche::QuicheTextUtils::ToLower(kv.first) == kUserAgentHeaderName) {
- uaid = kv.second;
- break;
- }
- }
- spdy_session()->SetUserAgentId(std::move(uaid));
- }
-
- // TODO(b/134706391): remove |fin| argument.
- // When using Google QUIC, an empty header list indicates that the size limit
- // has been exceeded.
- // When using IETF QUIC, there is an explicit signal from
- // QpackDecodedHeadersAccumulator.
- if ((VersionUsesHttp3(transport_version()) &&
- header_list_size_limit_exceeded_) ||
- (!VersionUsesHttp3(transport_version()) && header_list.empty())) {
- OnHeadersTooLarge();
- if (IsDoneReading()) {
- return;
- }
- }
- if (!headers_decompressed_) {
- OnInitialHeadersComplete(fin, frame_len, header_list);
- } else {
- OnTrailingHeadersComplete(fin, frame_len, header_list);
- }
-}
-
-void QuicSpdyStream::OnHeadersDecoded(QuicHeaderList headers,
- bool header_list_size_limit_exceeded) {
- header_list_size_limit_exceeded_ = header_list_size_limit_exceeded;
- qpack_decoded_headers_accumulator_.reset();
- qpack_decoded_headers_accumulator_reset_reason_ =
- QpackDecodedHeadersAccumulatorResetReason::kResetInOnHeadersDecoded;
-
- QuicSpdySession::LogHeaderCompressionRatioHistogram(
- /* using_qpack = */ true,
- /* is_sent = */ false, headers.compressed_header_bytes(),
- headers.uncompressed_header_bytes());
-
- const QuicStreamId promised_stream_id = spdy_session()->promised_stream_id();
- Http3DebugVisitor* const debug_visitor = spdy_session()->debug_visitor();
- if (promised_stream_id ==
- QuicUtils::GetInvalidStreamId(transport_version())) {
- if (debug_visitor) {
- debug_visitor->OnHeadersDecoded(id(), headers);
- }
-
- OnStreamHeaderList(/* fin = */ false, headers_payload_length_, headers);
- } else {
- spdy_session_->OnHeaderList(headers);
- }
-
- if (blocked_on_decoding_headers_) {
- blocked_on_decoding_headers_ = false;
- // Continue decoding HTTP/3 frames.
- OnDataAvailable();
- }
-}
-
-void QuicSpdyStream::OnHeaderDecodingError(QuicErrorCode error_code,
- absl::string_view error_message) {
- qpack_decoded_headers_accumulator_.reset();
- qpack_decoded_headers_accumulator_reset_reason_ =
- QpackDecodedHeadersAccumulatorResetReason::kResetInOnHeaderDecodingError;
-
- std::string connection_close_error_message = absl::StrCat(
- "Error decoding ", headers_decompressed_ ? "trailers" : "headers",
- " on stream ", id(), ": ", error_message);
- OnUnrecoverableError(error_code, connection_close_error_message);
-}
-
-void QuicSpdyStream::MaybeSendPriorityUpdateFrame() {
- if (!VersionUsesHttp3(transport_version()) ||
- session()->perspective() != Perspective::IS_CLIENT) {
- return;
- }
-
- // Value between 0 and 7, inclusive. Lower value means higher priority.
- int urgency = precedence().spdy3_priority();
- if (last_sent_urgency_ == urgency) {
- return;
- }
- last_sent_urgency_ = urgency;
-
- PriorityUpdateFrame priority_update;
- priority_update.prioritized_element_type = REQUEST_STREAM;
- priority_update.prioritized_element_id = id();
- priority_update.priority_field_value = absl::StrCat("u=", urgency);
- spdy_session_->WriteHttp3PriorityUpdate(priority_update);
-}
-
-void QuicSpdyStream::OnHeadersTooLarge() { Reset(QUIC_HEADERS_TOO_LARGE); }
-
-void QuicSpdyStream::OnInitialHeadersComplete(
- bool fin, size_t /*frame_len*/, const QuicHeaderList& header_list) {
- // TODO(b/134706391): remove |fin| argument.
- headers_decompressed_ = true;
- header_list_ = header_list;
- bool header_too_large = VersionUsesHttp3(transport_version())
- ? header_list_size_limit_exceeded_
- : header_list.empty();
- // Validate request headers if it did not exceed size limit. If it did,
- // OnHeadersTooLarge() should have already handled it previously.
- if (!header_too_large && !AreHeadersValid(header_list)) {
- QUIC_CODE_COUNT_N(quic_validate_request_header, 1, 2);
- if (GetQuicReloadableFlag(quic_act_upon_invalid_header)) {
- QUIC_RELOADABLE_FLAG_COUNT(quic_act_upon_invalid_header);
- OnInvalidHeaders();
- return;
- }
- }
- QUIC_CODE_COUNT_N(quic_validate_request_header, 2, 2);
-
- 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())) {
- if (fin) {
- OnStreamFrame(QuicStreamFrame(id(), /* fin = */ true,
- highest_received_byte_offset(),
- absl::string_view()));
- }
- return;
- }
-
- if (fin && !rst_sent()) {
- OnStreamFrame(
- QuicStreamFrame(id(), fin, /* offset = */ 0, absl::string_view()));
- }
- if (FinishedReadingHeaders()) {
- sequencer()->SetUnblocked();
- }
-}
-
-void QuicSpdyStream::OnPromiseHeaderList(
- QuicStreamId /* promised_id */, size_t /* frame_len */,
- const QuicHeaderList& /*header_list */) {
- // To be overridden in QuicSpdyClientStream. Not supported on
- // server side.
- stream_delegate()->OnStreamError(QUIC_INVALID_HEADERS_STREAM_DATA,
- "Promise headers received by server");
-}
-
-void QuicSpdyStream::OnTrailingHeadersComplete(
- bool fin, size_t /*frame_len*/, const QuicHeaderList& header_list) {
- // TODO(b/134706391): remove |fin| argument.
- QUICHE_DCHECK(!trailers_decompressed_);
- if (!VersionUsesHttp3(transport_version()) && fin_received()) {
- QUIC_DLOG(INFO) << ENDPOINT
- << "Received Trailers after FIN, on stream: " << id();
- stream_delegate()->OnStreamError(QUIC_INVALID_HEADERS_STREAM_DATA,
- "Trailers after fin");
- return;
- }
-
- if (!VersionUsesHttp3(transport_version()) && !fin) {
- QUIC_DLOG(INFO) << ENDPOINT
- << "Trailers must have FIN set, on stream: " << id();
- stream_delegate()->OnStreamError(QUIC_INVALID_HEADERS_STREAM_DATA,
- "Fin missing from trailers");
- return;
- }
-
- size_t final_byte_offset = 0;
- const bool expect_final_byte_offset = !VersionUsesHttp3(transport_version());
- if (!SpdyUtils::CopyAndValidateTrailers(header_list, expect_final_byte_offset,
- &final_byte_offset,
- &received_trailers_)) {
- QUIC_DLOG(ERROR) << ENDPOINT << "Trailers for stream " << id()
- << " are malformed.";
- stream_delegate()->OnStreamError(QUIC_INVALID_HEADERS_STREAM_DATA,
- "Trailers are malformed");
- return;
- }
- trailers_decompressed_ = true;
- if (fin) {
- const QuicStreamOffset offset = VersionUsesHttp3(transport_version())
- ? highest_received_byte_offset()
- : final_byte_offset;
- OnStreamFrame(QuicStreamFrame(id(), fin, offset, absl::string_view()));
- }
-}
-
-void QuicSpdyStream::OnPriorityFrame(
- const spdy::SpdyStreamPrecedence& precedence) {
- QUICHE_DCHECK_EQ(Perspective::IS_SERVER,
- session()->connection()->perspective());
- SetPriority(precedence);
-}
-
-void QuicSpdyStream::OnStreamReset(const QuicRstStreamFrame& frame) {
- if (web_transport_data_ != nullptr) {
- WebTransportStreamVisitor* webtransport_visitor =
- web_transport_data_->adapter.visitor();
- if (webtransport_visitor != nullptr) {
- webtransport_visitor->OnResetStreamReceived(
- Http3ErrorToWebTransportOrDefault(frame.ietf_error_code));
- }
- QuicStream::OnStreamReset(frame);
- return;
- }
-
- // TODO(bnc): Merge the two blocks below when both
- // quic_abort_qpack_on_stream_reset and quic_fix_on_stream_reset are
- // deprecated.
- if (frame.error_code != QUIC_STREAM_NO_ERROR) {
- if (VersionUsesHttp3(transport_version()) && !fin_received() &&
- spdy_session_->qpack_decoder()) {
- QUIC_CODE_COUNT_N(quic_abort_qpack_on_stream_reset, 1, 2);
- spdy_session_->qpack_decoder()->OnStreamReset(id());
- if (GetQuicReloadableFlag(quic_abort_qpack_on_stream_reset)) {
- QUIC_RELOADABLE_FLAG_COUNT_N(quic_abort_qpack_on_stream_reset, 1, 2);
- qpack_decoded_headers_accumulator_.reset();
- qpack_decoded_headers_accumulator_reset_reason_ =
- QpackDecodedHeadersAccumulatorResetReason::kResetInOnStreamReset1;
- }
- }
-
- QuicStream::OnStreamReset(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;
- }
-
- QuicStream::OnStreamReset(frame);
- return;
- }
-
- QUIC_DVLOG(1) << ENDPOINT
- << "Received QUIC_STREAM_NO_ERROR, not discarding response";
- set_rst_received(true);
- MaybeIncreaseHighestReceivedOffset(frame.byte_offset);
- set_stream_error(frame.error());
- CloseWriteSide();
-}
-
-void QuicSpdyStream::ResetWithError(QuicResetStreamError error) {
- if (VersionUsesHttp3(transport_version()) && !fin_received() &&
- spdy_session_->qpack_decoder() && web_transport_data_ == nullptr) {
- QUIC_CODE_COUNT_N(quic_abort_qpack_on_stream_reset, 2, 2);
- spdy_session_->qpack_decoder()->OnStreamReset(id());
- if (GetQuicReloadableFlag(quic_abort_qpack_on_stream_reset)) {
- QUIC_RELOADABLE_FLAG_COUNT_N(quic_abort_qpack_on_stream_reset, 2, 2);
- qpack_decoded_headers_accumulator_.reset();
- qpack_decoded_headers_accumulator_reset_reason_ =
- QpackDecodedHeadersAccumulatorResetReason::kResetInResetWithError;
- }
- }
-
- QuicStream::ResetWithError(error);
-}
-
-bool QuicSpdyStream::OnStopSending(QuicResetStreamError error) {
- if (web_transport_data_ != nullptr) {
- WebTransportStreamVisitor* visitor = web_transport_data_->adapter.visitor();
- if (visitor != nullptr) {
- visitor->OnStopSendingReceived(
- Http3ErrorToWebTransportOrDefault(error.ietf_application_code()));
- }
- }
-
- return QuicStream::OnStopSending(error);
-}
-
-void QuicSpdyStream::OnWriteSideInDataRecvdState() {
- if (web_transport_data_ != nullptr) {
- WebTransportStreamVisitor* visitor = web_transport_data_->adapter.visitor();
- if (visitor != nullptr) {
- visitor->OnWriteSideInDataRecvdState();
- }
- }
-
- QuicStream::OnWriteSideInDataRecvdState();
-}
-
-void QuicSpdyStream::OnDataAvailable() {
- if (!VersionUsesHttp3(transport_version())) {
- // Sequencer must be blocked until headers are consumed.
- QUICHE_DCHECK(FinishedReadingHeaders());
- }
-
- if (!VersionUsesHttp3(transport_version())) {
- HandleBodyAvailable();
- return;
- }
-
- if (web_transport_data_ != nullptr) {
- web_transport_data_->adapter.OnDataAvailable();
- return;
- }
-
- if (!spdy_session()->ShouldProcessIncomingRequests()) {
- spdy_session()->OnStreamWaitingForClientSettings(id());
- return;
- }
-
- if (is_decoder_processing_input_) {
- // Let the outermost nested OnDataAvailable() call do the work.
- return;
- }
-
- if (blocked_on_decoding_headers_) {
- return;
- }
-
- iovec iov;
- while (session()->connection()->connected() && !reading_stopped() &&
- decoder_.error() == QUIC_NO_ERROR) {
- QUICHE_DCHECK_GE(sequencer_offset_, sequencer()->NumBytesConsumed());
- if (!sequencer()->PeekRegion(sequencer_offset_, &iov)) {
- break;
- }
-
- QUICHE_DCHECK(!sequencer()->IsClosed());
- is_decoder_processing_input_ = true;
- QuicByteCount processed_bytes = decoder_.ProcessInput(
- reinterpret_cast<const char*>(iov.iov_base), iov.iov_len);
- is_decoder_processing_input_ = false;
- sequencer_offset_ += processed_bytes;
- if (blocked_on_decoding_headers_) {
- return;
- }
- if (web_transport_data_ != nullptr) {
- return;
- }
- }
-
- // Do not call HandleBodyAvailable() until headers are consumed.
- if (!FinishedReadingHeaders()) {
- return;
- }
-
- if (body_manager_.HasBytesToRead()) {
- HandleBodyAvailable();
- return;
- }
-
- if (sequencer()->IsClosed() &&
- !on_body_available_called_because_sequencer_is_closed_) {
- on_body_available_called_because_sequencer_is_closed_ = true;
- HandleBodyAvailable();
- }
-}
-
-void QuicSpdyStream::OnClose() {
- QuicStream::OnClose();
-
- qpack_decoded_headers_accumulator_.reset();
- qpack_decoded_headers_accumulator_reset_reason_ =
- QpackDecodedHeadersAccumulatorResetReason::kResetInOnClose;
-
- if (visitor_) {
- Visitor* visitor = visitor_;
- // Calling Visitor::OnClose() may result the destruction of the visitor,
- // so we need to ensure we don't call it again.
- visitor_ = nullptr;
- visitor->OnClose(this);
- }
-
- if (datagram_flow_id_.has_value()) {
- spdy_session_->UnregisterHttp3DatagramFlowId(datagram_flow_id_.value());
- }
-
- if (web_transport_ != nullptr) {
- web_transport_->OnConnectStreamClosing();
- }
- if (web_transport_data_ != nullptr) {
- WebTransportHttp3* web_transport =
- spdy_session_->GetWebTransportSession(web_transport_data_->session_id);
- if (web_transport == nullptr) {
- // Since there is no guaranteed destruction order for streams, the session
- // could be already removed from the stream map by the time we reach here.
- QUIC_DLOG(WARNING) << ENDPOINT << "WebTransport stream " << id()
- << " attempted to notify parent session "
- << web_transport_data_->session_id
- << ", but the session could not be found.";
- return;
- }
- web_transport->OnStreamClosed(id());
- }
-}
-
-void QuicSpdyStream::OnCanWrite() {
- QuicStream::OnCanWrite();
-
- // Trailers (and hence a FIN) may have been sent ahead of queued body bytes.
- if (!HasBufferedData() && fin_sent()) {
- CloseWriteSide();
- }
-}
-
-bool QuicSpdyStream::FinishedReadingHeaders() const {
- return headers_decompressed_ && header_list_.empty();
-}
-
-// static
-bool QuicSpdyStream::ParseHeaderStatusCode(const SpdyHeaderBlock& header,
- int* status_code) {
- SpdyHeaderBlock::const_iterator it = header.find(spdy::kHttp2StatusHeader);
- if (it == header.end()) {
- return false;
- }
- const absl::string_view status(it->second);
- if (status.size() != 3) {
- return false;
- }
- // First character must be an integer in range [1,5].
- if (status[0] < '1' || status[0] > '5') {
- return false;
- }
- // The remaining two characters must be integers.
- if (!isdigit(status[1]) || !isdigit(status[2])) {
- return false;
- }
- return absl::SimpleAtoi(status, status_code);
-}
-
-bool QuicSpdyStream::FinishedReadingTrailers() const {
- // If no further trailing headers are expected, and the decompressed trailers
- // (if any) have been consumed, then reading of trailers is finished.
- if (!fin_received()) {
- return false;
- } else if (!trailers_decompressed_) {
- return true;
- } else {
- return trailers_consumed_;
- }
-}
-
-bool QuicSpdyStream::OnDataFrameStart(QuicByteCount header_length,
- QuicByteCount payload_length) {
- QUICHE_DCHECK(VersionUsesHttp3(transport_version()));
-
- if (spdy_session_->debug_visitor()) {
- spdy_session_->debug_visitor()->OnDataFrameReceived(id(), payload_length);
- }
-
- if (!headers_decompressed_ || trailers_decompressed_) {
- stream_delegate()->OnStreamError(
- QUIC_HTTP_INVALID_FRAME_SEQUENCE_ON_SPDY_STREAM,
- "Unexpected DATA frame received.");
- return false;
- }
-
- sequencer()->MarkConsumed(body_manager_.OnNonBody(header_length));
-
- return true;
-}
-
-bool QuicSpdyStream::OnDataFramePayload(absl::string_view payload) {
- QUICHE_DCHECK(VersionUsesHttp3(transport_version()));
-
- body_manager_.OnBody(payload);
-
- return true;
-}
-
-bool QuicSpdyStream::OnDataFrameEnd() {
- QUICHE_DCHECK(VersionUsesHttp3(transport_version()));
-
- QUIC_DVLOG(1) << ENDPOINT
- << "Reaches the end of a data frame. Total bytes received are "
- << body_manager_.total_body_bytes_received();
- return true;
-}
-
-bool QuicSpdyStream::OnStreamFrameAcked(QuicStreamOffset offset,
- QuicByteCount data_length,
- bool fin_acked,
- QuicTime::Delta ack_delay_time,
- QuicTime receive_timestamp,
- QuicByteCount* newly_acked_length) {
- const bool new_data_acked = QuicStream::OnStreamFrameAcked(
- offset, data_length, fin_acked, ack_delay_time, receive_timestamp,
- newly_acked_length);
-
- const QuicByteCount newly_acked_header_length =
- GetNumFrameHeadersInInterval(offset, data_length);
- QUICHE_DCHECK_LE(newly_acked_header_length, *newly_acked_length);
- unacked_frame_headers_offsets_.Difference(offset, offset + data_length);
- if (ack_listener_ != nullptr && new_data_acked) {
- ack_listener_->OnPacketAcked(
- *newly_acked_length - newly_acked_header_length, ack_delay_time);
- }
- return new_data_acked;
-}
-
-void QuicSpdyStream::OnStreamFrameRetransmitted(QuicStreamOffset offset,
- QuicByteCount data_length,
- bool fin_retransmitted) {
- QuicStream::OnStreamFrameRetransmitted(offset, data_length,
- fin_retransmitted);
-
- const QuicByteCount retransmitted_header_length =
- GetNumFrameHeadersInInterval(offset, data_length);
- QUICHE_DCHECK_LE(retransmitted_header_length, data_length);
-
- if (ack_listener_ != nullptr) {
- ack_listener_->OnPacketRetransmitted(data_length -
- retransmitted_header_length);
- }
-}
-
-QuicByteCount QuicSpdyStream::GetNumFrameHeadersInInterval(
- QuicStreamOffset offset, QuicByteCount data_length) const {
- QuicByteCount header_acked_length = 0;
- QuicIntervalSet<QuicStreamOffset> newly_acked(offset, offset + data_length);
- newly_acked.Intersection(unacked_frame_headers_offsets_);
- for (const auto& interval : newly_acked) {
- header_acked_length += interval.Length();
- }
- return header_acked_length;
-}
-
-bool QuicSpdyStream::OnHeadersFrameStart(QuicByteCount header_length,
- QuicByteCount payload_length) {
- QUICHE_DCHECK(VersionUsesHttp3(transport_version()));
- QUICHE_DCHECK(!qpack_decoded_headers_accumulator_);
-
- if (spdy_session_->debug_visitor()) {
- spdy_session_->debug_visitor()->OnHeadersFrameReceived(id(),
- payload_length);
- }
-
- headers_payload_length_ = payload_length;
-
- if (trailers_decompressed_) {
- stream_delegate()->OnStreamError(
- QUIC_HTTP_INVALID_FRAME_SEQUENCE_ON_SPDY_STREAM,
- "HEADERS frame received after trailing HEADERS.");
- return false;
- }
-
- sequencer()->MarkConsumed(body_manager_.OnNonBody(header_length));
-
- qpack_decoded_headers_accumulator_ =
- std::make_unique<QpackDecodedHeadersAccumulator>(
- id(), spdy_session_->qpack_decoder(), this,
- spdy_session_->max_inbound_header_list_size());
-
- return true;
-}
-
-bool QuicSpdyStream::OnHeadersFramePayload(absl::string_view payload) {
- QUICHE_DCHECK(VersionUsesHttp3(transport_version()));
-
- if (!qpack_decoded_headers_accumulator_) {
- QUIC_BUG(b215142466_OnHeadersFramePayload)
- << static_cast<int>(qpack_decoded_headers_accumulator_reset_reason_);
- OnHeaderDecodingError(QUIC_INTERNAL_ERROR,
- "qpack_decoded_headers_accumulator_ is nullptr");
- return false;
- }
-
- qpack_decoded_headers_accumulator_->Decode(payload);
-
- // |qpack_decoded_headers_accumulator_| is reset if an error is detected.
- if (!qpack_decoded_headers_accumulator_) {
- return false;
- }
-
- sequencer()->MarkConsumed(body_manager_.OnNonBody(payload.size()));
- return true;
-}
-
-bool QuicSpdyStream::OnHeadersFrameEnd() {
- QUICHE_DCHECK(VersionUsesHttp3(transport_version()));
-
- if (!qpack_decoded_headers_accumulator_) {
- QUIC_BUG(b215142466_OnHeadersFrameEnd)
- << static_cast<int>(qpack_decoded_headers_accumulator_reset_reason_);
- OnHeaderDecodingError(QUIC_INTERNAL_ERROR,
- "qpack_decoded_headers_accumulator_ is nullptr");
- return false;
- }
-
- qpack_decoded_headers_accumulator_->EndHeaderBlock();
-
- // If decoding is complete or an error is detected, then
- // |qpack_decoded_headers_accumulator_| is already reset.
- if (qpack_decoded_headers_accumulator_) {
- blocked_on_decoding_headers_ = true;
- return false;
- }
-
- return !sequencer()->IsClosed() && !reading_stopped();
-}
-
-void QuicSpdyStream::OnWebTransportStreamFrameType(
- QuicByteCount header_length, WebTransportSessionId session_id) {
- QUIC_DVLOG(1) << ENDPOINT << " Received WEBTRANSPORT_STREAM on stream "
- << id() << " for session " << session_id;
- sequencer()->MarkConsumed(header_length);
-
- if (headers_payload_length_ > 0 || headers_decompressed_) {
- QUIC_PEER_BUG(WEBTRANSPORT_STREAM received on HTTP request)
- << ENDPOINT << "Stream " << id()
- << " tried to convert to WebTransport, but it already "
- "has HTTP data on it";
- Reset(QUIC_STREAM_FRAME_UNEXPECTED);
- }
- if (QuicUtils::IsOutgoingStreamId(spdy_session_->version(), id(),
- spdy_session_->perspective())) {
- QUIC_PEER_BUG(WEBTRANSPORT_STREAM received on outgoing request)
- << ENDPOINT << "Stream " << id()
- << " tried to convert to WebTransport, but only the "
- "initiator of the stream can do it.";
- Reset(QUIC_STREAM_FRAME_UNEXPECTED);
- }
-
- QUICHE_DCHECK(web_transport_ == nullptr);
- web_transport_data_ =
- std::make_unique<WebTransportDataStream>(this, session_id);
- spdy_session_->AssociateIncomingWebTransportStreamWithSession(session_id,
- id());
-}
-
-bool QuicSpdyStream::OnUnknownFrameStart(uint64_t frame_type,
- QuicByteCount header_length,
- QuicByteCount payload_length) {
- if (spdy_session_->debug_visitor()) {
- spdy_session_->debug_visitor()->OnUnknownFrameReceived(id(), frame_type,
- payload_length);
- }
-
- // Ignore unknown frames, but consume frame header.
- QUIC_DVLOG(1) << ENDPOINT << "Discarding " << header_length
- << " byte long frame header of frame of unknown type "
- << frame_type << ".";
- sequencer()->MarkConsumed(body_manager_.OnNonBody(header_length));
- return true;
-}
-
-bool QuicSpdyStream::OnUnknownFramePayload(absl::string_view payload) {
- // Ignore unknown frames, but consume frame payload.
- QUIC_DVLOG(1) << ENDPOINT << "Discarding " << payload.size()
- << " bytes of payload of frame of unknown type.";
- sequencer()->MarkConsumed(body_manager_.OnNonBody(payload.size()));
- return true;
-}
-
-bool QuicSpdyStream::OnUnknownFrameEnd() { return true; }
-
-size_t QuicSpdyStream::WriteHeadersImpl(
- spdy::SpdyHeaderBlock header_block, bool fin,
- QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener) {
- if (!VersionUsesHttp3(transport_version())) {
- return spdy_session_->WriteHeadersOnHeadersStream(
- id(), std::move(header_block), fin, precedence(),
- std::move(ack_listener));
- }
-
- // Encode header list.
- QuicByteCount encoder_stream_sent_byte_count;
- std::string encoded_headers =
- spdy_session_->qpack_encoder()->EncodeHeaderList(
- id(), header_block, &encoder_stream_sent_byte_count);
-
- if (spdy_session_->debug_visitor()) {
- spdy_session_->debug_visitor()->OnHeadersFrameSent(id(), header_block);
- }
-
- // Write HEADERS frame.
- std::unique_ptr<char[]> headers_frame_header;
- const size_t headers_frame_header_length =
- HttpEncoder::SerializeHeadersFrameHeader(encoded_headers.size(),
- &headers_frame_header);
- unacked_frame_headers_offsets_.Add(
- send_buffer().stream_offset(),
- send_buffer().stream_offset() + headers_frame_header_length);
-
- QUIC_DLOG(INFO) << ENDPOINT << "Stream " << id()
- << " is writing HEADERS frame header of length "
- << headers_frame_header_length;
- WriteOrBufferData(absl::string_view(headers_frame_header.get(),
- headers_frame_header_length),
- /* fin = */ false, /* ack_listener = */ nullptr);
-
- QUIC_DLOG(INFO) << ENDPOINT << "Stream " << id()
- << " is writing HEADERS frame payload of length "
- << encoded_headers.length() << " with fin " << fin;
- WriteOrBufferData(encoded_headers, fin, nullptr);
-
- QuicSpdySession::LogHeaderCompressionRatioHistogram(
- /* using_qpack = */ true,
- /* is_sent = */ true,
- encoded_headers.size() + encoder_stream_sent_byte_count,
- header_block.TotalBytesUsed());
-
- return encoded_headers.size();
-}
-
-bool QuicSpdyStream::CanWriteNewBodyData(QuicByteCount write_size) const {
- QUICHE_DCHECK_NE(0u, write_size);
- if (!VersionUsesHttp3(transport_version())) {
- return CanWriteNewData();
- }
-
- return CanWriteNewDataAfterData(
- HttpEncoder::GetDataFrameHeaderLength(write_size));
-}
-
-void QuicSpdyStream::MaybeProcessReceivedWebTransportHeaders() {
- if (!spdy_session_->SupportsWebTransport()) {
- return;
- }
- if (session()->perspective() != Perspective::IS_SERVER) {
- return;
- }
- QUICHE_DCHECK(IsValidWebTransportSessionId(id(), version()));
-
- 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()) {
- return;
- }
- method = header_value;
- }
- if (header_name == ":protocol") {
- if (!protocol.empty() || header_value.empty()) {
- return;
- }
- 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;
- }
- if (header_name == "sec-webtransport-http3-draft02") {
- if (header_value != "1") {
- QUIC_DLOG(ERROR) << ENDPOINT
- << "Rejecting WebTransport due to invalid value of "
- "Sec-Webtransport-Http3-Draft02 header";
- return;
- }
- version_indicated = true;
- }
- }
-
- if (method != "CONNECT" || protocol != "webtransport") {
- 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());
-}
-
-void QuicSpdyStream::MaybeProcessSentWebTransportHeaders(
- spdy::SpdyHeaderBlock& headers) {
- if (!spdy_session_->SupportsWebTransport()) {
- return;
- }
- if (session()->perspective() != Perspective::IS_CLIENT) {
- return;
- }
- QUICHE_DCHECK(IsValidWebTransportSessionId(id(), version()));
-
- const auto method_it = headers.find(":method");
- const auto protocol_it = headers.find(":protocol");
- if (method_it == headers.end() || protocol_it == headers.end()) {
- return;
- }
- if (method_it->second != "CONNECT" && protocol_it->second != "webtransport") {
- return;
- }
-
- if (spdy_session_->http_datagram_support() == HttpDatagramSupport::kDraft00) {
- headers["datagram-flow-id"] = absl::StrCat(id());
- } else {
- headers["sec-webtransport-http3-draft02"] = "1";
- }
-
- web_transport_ = std::make_unique<WebTransportHttp3>(
- spdy_session_, this, id(),
- spdy_session_->ShouldNegotiateDatagramContexts());
-}
-
-void QuicSpdyStream::OnCanWriteNewData() {
- if (web_transport_data_ != nullptr) {
- web_transport_data_->adapter.OnCanWriteNewData();
- }
-}
-
-bool QuicSpdyStream::AssertNotWebTransportDataStream(
- absl::string_view operation) {
- if (web_transport_data_ != nullptr) {
- QUIC_BUG(Invalid operation on WebTransport stream)
- << "Attempted to " << operation << " on WebTransport data stream "
- << id() << " associated with session "
- << web_transport_data_->session_id;
- OnUnrecoverableError(QUIC_INTERNAL_ERROR,
- absl::StrCat("Attempted to ", operation,
- " on WebTransport data stream"));
- return false;
- }
- return true;
-}
-
-void QuicSpdyStream::ConvertToWebTransportDataStream(
- WebTransportSessionId session_id) {
- if (send_buffer().stream_offset() != 0) {
- QUIC_BUG(Sending WEBTRANSPORT_STREAM when data already sent)
- << "Attempted to send a WEBTRANSPORT_STREAM frame when other data has "
- "already been sent on the stream.";
- OnUnrecoverableError(QUIC_INTERNAL_ERROR,
- "Attempted to send a WEBTRANSPORT_STREAM frame when "
- "other data has already been sent on the stream.");
- return;
- }
-
- std::unique_ptr<char[]> header;
- QuicByteCount header_size =
- HttpEncoder::SerializeWebTransportStreamFrameHeader(session_id, &header);
- if (header_size == 0) {
- QUIC_BUG(Failed to serialize WEBTRANSPORT_STREAM)
- << "Failed to serialize a WEBTRANSPORT_STREAM frame.";
- OnUnrecoverableError(QUIC_INTERNAL_ERROR,
- "Failed to serialize a WEBTRANSPORT_STREAM frame.");
- return;
- }
-
- WriteOrBufferData(absl::string_view(header.get(), header_size), /*fin=*/false,
- nullptr);
- web_transport_data_ =
- std::make_unique<WebTransportDataStream>(this, session_id);
- QUIC_DVLOG(1) << ENDPOINT << "Successfully opened WebTransport data stream "
- << id() << " for session " << session_id;
-}
-
-QuicSpdyStream::WebTransportDataStream::WebTransportDataStream(
- QuicSpdyStream* stream, WebTransportSessionId session_id)
- : 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_;
- }
- visitor->OnHttp3Datagram(id(), context_id, payload);
-}
-
-bool QuicSpdyStream::OnCapsule(const Capsule& capsule) {
- QUIC_DLOG(INFO) << ENDPOINT << "Stream " << id() << " received capsule "
- << capsule;
- if (!headers_decompressed_) {
- QUIC_PEER_BUG(capsule before headers)
- << ENDPOINT << "Stream " << id() << " received capsule " << capsule
- << " before headers";
- return false;
- }
- if (web_transport_ != nullptr && web_transport_->close_received()) {
- QUIC_PEER_BUG(capsule after close)
- << ENDPOINT << "Stream " << id() << " received capsule " << capsule
- << " after CLOSE_WEBTRANSPORT_SESSION.";
- return false;
- }
- 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
- << " for a non-WebTransport stream.";
- return false;
- }
- web_transport_->OnCloseReceived(
- capsule.close_web_transport_session_capsule().error_code,
- capsule.close_web_transport_session_capsule().error_message);
- } break;
- }
- return true;
-}
-
-void QuicSpdyStream::OnCapsuleParseFailure(const std::string& error_message) {
- QUIC_DLOG(ERROR) << ENDPOINT << "Capsule parse failure: " << error_message;
- Reset(QUIC_BAD_APPLICATION_PAYLOAD);
-}
-
-void QuicSpdyStream::WriteCapsule(const Capsule& capsule, bool fin) {
- QUIC_DLOG(INFO) << ENDPOINT << "Stream " << id() << " sending capsule "
- << capsule;
- QuicBuffer serialized_capsule = SerializeCapsule(
- capsule,
- spdy_session_->connection()->helper()->GetStreamSendBufferAllocator());
- QUICHE_DCHECK_GT(serialized_capsule.size(), 0u);
- WriteOrBufferBody(serialized_capsule.AsStringView(), /*fin=*/fin);
-}
-
-void QuicSpdyStream::WriteGreaseCapsule() {
- // GREASE capsulde IDs have a form of 41 * N + 23.
- QuicRandom* random = spdy_session_->connection()->random_generator();
- uint64_t type = random->InsecureRandUint64() >> 4;
- type = (type / 41) * 41 + 23;
- QUICHE_DCHECK_EQ((type - 23) % 41, 0u);
-
- constexpr size_t kMaxLength = 64;
- size_t length = random->InsecureRandUint64() % kMaxLength;
- std::string bytes(length, '\0');
- random->InsecureRandBytes(&bytes[0], bytes.size());
- Capsule capsule = Capsule::Unknown(type, bytes);
- 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));
-}
-
-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,
- 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");
- 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();
- 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();
- }
- }
-}
-
-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 "
- << id();
- datagram_no_context_visitor_ = nullptr;
- }
- if (spdy_session_->http_datagram_support() == HttpDatagramSupport::kDraft04 &&
- context_id.has_value()) {
- WriteCapsule(Capsule::CloseDatagramContext(context_id.value()));
- }
-}
-
-void QuicSpdyStream::MoveHttp3DatagramContextIdRegistration(
- absl::optional<QuicDatagramContextId> context_id,
- 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;
-}
-
-void QuicSpdyStream::SetMaxDatagramTimeInQueue(
- QuicTime::Delta max_time_in_queue) {
- 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);
-}
-
-QuicByteCount QuicSpdyStream::GetMaxDatagramSize(
- absl::optional<QuicDatagramContextId> context_id) 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:
- prefix_size =
- QuicDataWriter::GetVarInt62Len(id() / kHttpDatagramStreamIdDivisor);
- break;
- case HttpDatagramSupport::kNone:
- case HttpDatagramSupport::kDraft00And04:
- QUIC_BUG(GetMaxDatagramSize called with no datagram support)
- << "GetMaxDatagramSize() called when no HTTP/3 datagram support has "
- "been negotiated. Support value: "
- << spdy_session_->http_datagram_support();
- break;
- }
- // If the logic above fails, use the largest possible value as the safe one.
- if (prefix_size == 0) {
- 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.";
- 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();
- return;
- }
- while (body_manager_.HasBytesToRead()) {
- iovec iov;
- int num_iov = GetReadableRegions(&iov, /*iov_len=*/1);
- if (num_iov == 0) {
- break;
- }
- if (!capsule_parser_->IngestCapsuleFragment(absl::string_view(
- reinterpret_cast<const char*>(iov.iov_base), iov.iov_len))) {
- break;
- }
- MarkConsumed(iov.iov_len);
- }
- // If we received a FIN, make sure that there isn't a partial capsule buffered
- // in the capsule parser.
- if (sequencer()->IsClosed()) {
- capsule_parser_->ErrorIfThereIsRemainingBufferedData();
- if (web_transport_ != nullptr) {
- web_transport_->OnConnectStreamFinReceived();
- }
- OnFinRead();
- }
-}
-
-namespace {
-// Return true if |c| is not allowed in an HTTP/3 wire-encoded header and
-// pseudo-header names according to
-// https://datatracker.ietf.org/doc/html/draft-ietf-quic-http#section-4.1.1 and
-// https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-semantics-19#section-5.6.2
-constexpr bool isInvalidHeaderNameCharacter(unsigned char c) {
- if (c == '!' || c == '|' || c == '~' || c == '*' || c == '+' || c == '-' ||
- c == '.' ||
- // #, $, %, &, '
- (c >= '#' && c <= '\'') ||
- // [0-9], :
- (c >= '0' && c <= ':') ||
- // ^, _, `, [a-z]
- (c >= '^' && c <= 'z')) {
- return false;
- }
- return true;
-}
-} // namespace
-
-bool QuicSpdyStream::AreHeadersValid(const QuicHeaderList& header_list) const {
- QUICHE_DCHECK(GetQuicReloadableFlag(quic_verify_request_headers_2));
- for (const std::pair<std::string, std::string>& pair : header_list) {
- const std::string& name = pair.first;
- if (std::any_of(name.begin(), name.end(), isInvalidHeaderNameCharacter)) {
- QUIC_DLOG(ERROR) << "Invalid request header " << name;
- return false;
- }
- if (http2::GetInvalidHttp2HeaderSet().contains(name)) {
- QUIC_DLOG(ERROR) << name << " header is not allowed";
- return false;
- }
- }
- return true;
-}
-
-void QuicSpdyStream::OnInvalidHeaders() { Reset(QUIC_BAD_APPLICATION_PAYLOAD); }
-
-#undef ENDPOINT // undef for jumbo builds
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_stream.h b/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_stream.h
deleted file mode 100644
index 14ac2f2f585..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_stream.h
+++ /dev/null
@@ -1,534 +0,0 @@
-// Copyright 2013 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.
-
-// The base class for streams which deliver data to/from an application.
-// In each direction, the data on such a stream first contains compressed
-// headers then body data.
-
-#ifndef QUICHE_QUIC_CORE_HTTP_QUIC_SPDY_STREAM_H_
-#define QUICHE_QUIC_CORE_HTTP_QUIC_SPDY_STREAM_H_
-
-#include <sys/types.h>
-
-#include <cstddef>
-#include <list>
-#include <memory>
-#include <string>
-
-#include "absl/base/attributes.h"
-#include "absl/strings/string_view.h"
-#include "absl/types/span.h"
-#include "quic/core/http/capsule.h"
-#include "quic/core/http/http_decoder.h"
-#include "quic/core/http/http_encoder.h"
-#include "quic/core/http/quic_header_list.h"
-#include "quic/core/http/quic_spdy_stream_body_manager.h"
-#include "quic/core/http/web_transport_stream_adapter.h"
-#include "quic/core/qpack/qpack_decoded_headers_accumulator.h"
-#include "quic/core/quic_error_codes.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_stream.h"
-#include "quic/core/quic_stream_sequencer.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/web_transport_interface.h"
-#include "quic/platform/api/quic_export.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_socket_address.h"
-#include "spdy/core/spdy_framer.h"
-#include "spdy/core/spdy_header_block.h"
-
-namespace quic {
-
-namespace test {
-class QuicSpdyStreamPeer;
-class QuicStreamPeer;
-} // namespace test
-
-class QuicSpdySession;
-class WebTransportHttp3;
-
-// A QUIC stream that can send and receive HTTP2 (SPDY) headers.
-class QUIC_EXPORT_PRIVATE QuicSpdyStream
- : public QuicStream,
- public CapsuleParser::Visitor,
- public QpackDecodedHeadersAccumulator::Visitor {
- public:
- // Visitor receives callbacks from the stream.
- class QUIC_EXPORT_PRIVATE Visitor {
- public:
- Visitor() {}
- Visitor(const Visitor&) = delete;
- Visitor& operator=(const Visitor&) = delete;
-
- // Called when the stream is closed.
- virtual void OnClose(QuicSpdyStream* stream) = 0;
-
- // Allows subclasses to override and do work.
- virtual void OnPromiseHeadersComplete(QuicStreamId /*promised_id*/,
- size_t /*frame_len*/) {}
-
- protected:
- virtual ~Visitor() {}
- };
-
- QuicSpdyStream(QuicStreamId id, QuicSpdySession* spdy_session,
- StreamType type);
- QuicSpdyStream(PendingStream* pending, QuicSpdySession* spdy_session);
- QuicSpdyStream(const QuicSpdyStream&) = delete;
- QuicSpdyStream& operator=(const QuicSpdyStream&) = delete;
- ~QuicSpdyStream() override;
-
- // QuicStream implementation
- void OnClose() override;
-
- // Override to maybe close the write side after writing.
- void OnCanWrite() override;
-
- // Called by the session when headers with a priority have been received
- // for this stream. This method will only be called for server streams.
- virtual void OnStreamHeadersPriority(
- const spdy::SpdyStreamPrecedence& precedence);
-
- // Called by the session when decompressed headers have been completely
- // delivered to this stream. If |fin| is true, then this stream
- // should be closed; no more data will be sent by the peer.
- virtual void OnStreamHeaderList(bool fin, size_t frame_len,
- const QuicHeaderList& header_list);
-
- // Called by the session when decompressed push promise headers have
- // been completely delivered to this stream.
- virtual void OnPromiseHeaderList(QuicStreamId promised_id, size_t frame_len,
- const QuicHeaderList& header_list);
-
- // Called by the session when a PRIORITY frame has been been received for this
- // stream. This method will only be called for server streams.
- void OnPriorityFrame(const spdy::SpdyStreamPrecedence& precedence);
-
- // Override the base class to not discard response when receiving
- // QUIC_STREAM_NO_ERROR.
- void OnStreamReset(const QuicRstStreamFrame& frame) override;
- void ResetWithError(QuicResetStreamError error) override;
- bool OnStopSending(QuicResetStreamError error) override;
-
- // Called by the sequencer when new data is available. Decodes the data and
- // calls OnBodyAvailable() to pass to the upper layer.
- void OnDataAvailable() override;
-
- // Called in OnDataAvailable() after it finishes the decoding job.
- virtual void OnBodyAvailable() = 0;
-
- // Writes the headers contained in |header_block| on the dedicated headers
- // stream or on this stream, depending on VersionUsesHttp3(). Returns the
- // number of bytes sent, including data sent on the encoder stream when using
- // QPACK.
- virtual size_t WriteHeaders(
- spdy::SpdyHeaderBlock header_block, bool fin,
- QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener);
-
- // Sends |data| to the peer, or buffers if it can't be sent immediately.
- 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
- // always have the FIN flag set. Returns the number of bytes sent, including
- // data sent on the encoder stream when using QPACK.
- virtual size_t WriteTrailers(
- spdy::SpdyHeaderBlock trailer_block,
- QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener);
-
- // Override to report newly acked bytes via ack_listener_.
- bool OnStreamFrameAcked(QuicStreamOffset offset, QuicByteCount data_length,
- bool fin_acked, QuicTime::Delta ack_delay_time,
- QuicTime receive_timestamp,
- QuicByteCount* newly_acked_length) override;
-
- // Override to report bytes retransmitted via ack_listener_.
- void OnStreamFrameRetransmitted(QuicStreamOffset offset,
- QuicByteCount data_length,
- bool fin_retransmitted) override;
-
- // Does the same thing as WriteOrBufferBody except this method takes iovec
- // as the data input. Right now it only calls WritevData.
- QuicConsumedData WritevBody(const struct iovec* iov, int count, bool fin);
-
- // Does the same thing as WriteOrBufferBody except this method takes
- // memslicespan as the data input. Right now it only calls WriteMemSlices.
- QuicConsumedData WriteBodySlices(absl::Span<QuicMemSlice> slices, bool fin);
-
- // Marks the trailers as consumed. This applies to the case where this object
- // receives headers and trailers as QuicHeaderLists via calls to
- // OnStreamHeaderList(). Trailer data will be consumed from the sequencer only
- // once all body data has been consumed.
- void MarkTrailersConsumed();
-
- // Clears |header_list_|.
- void ConsumeHeaderList();
-
- // This block of functions wraps the sequencer's functions of the same
- // name. These methods return uncompressed data until that has
- // been fully processed. Then they simply delegate to the sequencer.
- virtual size_t Readv(const struct iovec* iov, size_t iov_len);
- virtual int GetReadableRegions(iovec* iov, size_t iov_len) const;
- void MarkConsumed(size_t num_bytes);
-
- // Returns true if header contains a valid 3-digit status and parse the status
- // code to |status_code|.
- static bool ParseHeaderStatusCode(const spdy::SpdyHeaderBlock& header,
- int* status_code);
-
- // Returns true when all data from the peer has been read and consumed,
- // including the fin.
- bool IsDoneReading() const;
- bool HasBytesToRead() const;
-
- void set_visitor(Visitor* visitor) { visitor_ = visitor; }
-
- bool headers_decompressed() const { return headers_decompressed_; }
-
- // Returns total amount of body bytes that have been read.
- uint64_t total_body_bytes_read() const;
-
- const QuicHeaderList& header_list() const { return header_list_; }
-
- bool trailers_decompressed() const { return trailers_decompressed_; }
-
- // Returns whatever trailers have been received for this stream.
- const spdy::SpdyHeaderBlock& received_trailers() const {
- return received_trailers_;
- }
-
- // Returns true if headers have been fully read and consumed.
- bool FinishedReadingHeaders() const;
-
- // Returns true if FIN has been received and either trailers have been fully
- // read and consumed or there are no trailers.
- bool FinishedReadingTrailers() const;
-
- // Returns true if the sequencer has delivered the FIN, and no more body bytes
- // will be available.
- bool IsSequencerClosed() { return sequencer()->IsClosed(); }
-
- // QpackDecodedHeadersAccumulator::Visitor implementation.
- void OnHeadersDecoded(QuicHeaderList headers,
- bool header_list_size_limit_exceeded) override;
- void OnHeaderDecodingError(QuicErrorCode error_code,
- absl::string_view error_message) override;
-
- QuicSpdySession* spdy_session() const { return spdy_session_; }
-
- // Send PRIORITY_UPDATE frame and update |last_sent_urgency_| if
- // |last_sent_urgency_| is different from current priority.
- void MaybeSendPriorityUpdateFrame() override;
-
- // Returns the WebTransport session owned by this stream, if one exists.
- WebTransportHttp3* web_transport() { return web_transport_.get(); }
-
- // Returns the WebTransport data stream associated with this QUIC stream, or
- // null if this is not a WebTransport data stream.
- WebTransportStream* web_transport_stream() {
- if (web_transport_data_ == nullptr) {
- return nullptr;
- }
- return &web_transport_data_->adapter;
- }
-
- // Sends a WEBTRANSPORT_STREAM frame and sets up the appropriate metadata.
- void ConvertToWebTransportDataStream(WebTransportSessionId session_id);
-
- void OnCanWriteNewData() override;
-
- // If this stream is a WebTransport data stream, closes the connection with an
- // error, and returns false.
- bool AssertNotWebTransportDataStream(absl::string_view operation);
-
- // Indicates whether a call to WriteBodySlices will be successful and not
- // rejected due to buffer being full. |write_size| must be non-zero.
- bool CanWriteNewBodyData(QuicByteCount write_size) const;
-
- // From CapsuleParser::Visitor.
- 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);
-
- 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;
- };
-
- 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 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);
-
- // 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;
-
- // Writes |capsule| onto the DATA stream.
- void WriteCapsule(const Capsule& capsule, bool fin = false);
-
- void WriteGreaseCapsule();
-
- protected:
- // Called when the received headers are too large. By default this will
- // reset the stream.
- virtual void OnHeadersTooLarge();
-
- virtual void OnInitialHeadersComplete(bool fin, size_t frame_len,
- const QuicHeaderList& header_list);
- virtual void OnTrailingHeadersComplete(bool fin, size_t frame_len,
- const QuicHeaderList& header_list);
- virtual size_t WriteHeadersImpl(
- spdy::SpdyHeaderBlock header_block, bool fin,
- QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener);
-
- Visitor* visitor() { return visitor_; }
-
- void set_headers_decompressed(bool val) { headers_decompressed_ = val; }
-
- void set_ack_listener(
- QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener) {
- ack_listener_ = std::move(ack_listener);
- }
-
- void OnWriteSideInDataRecvdState() override;
-
- virtual bool AreHeadersValid(const QuicHeaderList& header_list) const;
-
- // Reset stream upon invalid request headers.
- virtual void OnInvalidHeaders();
-
- private:
- friend class test::QuicSpdyStreamPeer;
- friend class test::QuicStreamPeer;
- friend class QuicStreamUtils;
- class HttpDecoderVisitor;
-
- struct QUIC_EXPORT_PRIVATE WebTransportDataStream {
- WebTransportDataStream(QuicSpdyStream* stream,
- WebTransportSessionId session_id);
-
- WebTransportSessionId session_id;
- WebTransportStreamAdapter adapter;
- };
-
- // Reason codes for `qpack_decoded_headers_accumulator_` being nullptr.
- enum class QpackDecodedHeadersAccumulatorResetReason {
- // `qpack_decoded_headers_accumulator_` was default constructed to nullptr.
- kUnSet = 0,
- // `qpack_decoded_headers_accumulator_` was reset in the corresponding
- // method.
- kResetInOnHeadersDecoded = 1,
- kResetInOnHeaderDecodingError = 2,
- kResetInOnStreamReset1 = 3,
- kResetInOnStreamReset2 = 4,
- kResetInResetWithError = 5,
- kResetInOnClose = 6,
- };
-
- // Called by HttpDecoderVisitor.
- bool OnDataFrameStart(QuicByteCount header_length,
- QuicByteCount payload_length);
- bool OnDataFramePayload(absl::string_view payload);
- bool OnDataFrameEnd();
- bool OnHeadersFrameStart(QuicByteCount header_length,
- QuicByteCount payload_length);
- bool OnHeadersFramePayload(absl::string_view payload);
- bool OnHeadersFrameEnd();
- void OnWebTransportStreamFrameType(QuicByteCount header_length,
- WebTransportSessionId session_id);
- bool OnUnknownFrameStart(uint64_t frame_type, QuicByteCount header_length,
- QuicByteCount payload_length);
- bool OnUnknownFramePayload(absl::string_view payload);
- bool OnUnknownFrameEnd();
-
- // Given the interval marked by [|offset|, |offset| + |data_length|), return
- // the number of frame header bytes contained in it.
- QuicByteCount GetNumFrameHeadersInInterval(QuicStreamOffset offset,
- QuicByteCount data_length) const;
-
- void MaybeProcessSentWebTransportHeaders(spdy::SpdyHeaderBlock& headers);
- void MaybeProcessReceivedWebTransportHeaders();
-
- // Writes HTTP/3 DATA frame header. If |force_write| is true, use
- // WriteOrBufferData if send buffer cannot accomodate the header + data.
- ABSL_MUST_USE_RESULT bool WriteDataFrameHeader(QuicByteCount data_length,
- bool force_write);
-
- // Simply calls OnBodyAvailable() unless capsules are in use, in which case
- // pass the capsule fragments to the capsule manager.
- 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;
-
- QuicSpdySession* spdy_session_;
-
- bool on_body_available_called_because_sequencer_is_closed_;
-
- Visitor* visitor_;
-
- // True if read side processing is blocked while waiting for callback from
- // QPACK decoder.
- bool blocked_on_decoding_headers_;
- // True if the headers have been completely decompressed.
- bool headers_decompressed_;
- // True if uncompressed headers or trailers exceed maximum allowed size
- // advertised to peer via SETTINGS_MAX_HEADER_LIST_SIZE.
- bool header_list_size_limit_exceeded_;
- // Contains a copy of the decompressed header (name, value) pairs until they
- // are consumed via Readv.
- QuicHeaderList header_list_;
- // Length of most recently received HEADERS frame payload.
- QuicByteCount headers_payload_length_;
-
- // True if the trailers have been completely decompressed.
- bool trailers_decompressed_;
- // True if the trailers have been consumed.
- bool trailers_consumed_;
-
- // The parsed trailers received from the peer.
- spdy::SpdyHeaderBlock received_trailers_;
-
- // Headers accumulator for decoding HEADERS frame payload.
- std::unique_ptr<QpackDecodedHeadersAccumulator>
- qpack_decoded_headers_accumulator_;
- // Reason for `qpack_decoded_headers_accumulator_` being nullptr.
- QpackDecodedHeadersAccumulatorResetReason
- qpack_decoded_headers_accumulator_reset_reason_;
- // Visitor of the HttpDecoder.
- std::unique_ptr<HttpDecoderVisitor> http_decoder_visitor_;
- // HttpDecoder for processing raw incoming stream frames.
- HttpDecoder decoder_;
- // Object that manages references to DATA frame payload fragments buffered by
- // the sequencer and calculates how much data should be marked consumed with
- // the sequencer each time new stream data is processed.
- QuicSpdyStreamBodyManager body_manager_;
-
- std::unique_ptr<CapsuleParser> capsule_parser_;
-
- // Sequencer offset keeping track of how much data HttpDecoder has processed.
- // Initial value is zero for fresh streams, or sequencer()->NumBytesConsumed()
- // at time of construction if a PendingStream is converted to account for the
- // length of the unidirectional stream type at the beginning of the stream.
- QuicStreamOffset sequencer_offset_;
-
- // True when inside an HttpDecoder::ProcessInput() call.
- // Used for detecting reentrancy.
- bool is_decoder_processing_input_;
-
- // Ack listener of this stream, and it is notified when any of written bytes
- // are acked or retransmitted.
- QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener_;
-
- // Offset of unacked frame headers.
- QuicIntervalSet<QuicStreamOffset> unacked_frame_headers_offsets_;
-
- // Urgency value sent in the last PRIORITY_UPDATE frame, or default urgency
- // defined by the spec if no PRIORITY_UPDATE frame has been sent.
- int last_sent_urgency_;
-
- // If this stream is a WebTransport extended CONNECT stream, contains the
- // WebTransport session associated with this stream.
- std::unique_ptr<WebTransportHttp3> web_transport_;
-
- // If this stream is a WebTransport data stream, |web_transport_data_|
- // contains all of the associated metadata.
- 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;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_HTTP_QUIC_SPDY_STREAM_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_stream_body_manager.cc b/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_stream_body_manager.cc
deleted file mode 100644
index 2ae24d472b7..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_stream_body_manager.cc
+++ /dev/null
@@ -1,140 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/http/quic_spdy_stream_body_manager.h"
-
-#include <algorithm>
-
-#include "absl/strings/string_view.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-QuicSpdyStreamBodyManager::QuicSpdyStreamBodyManager()
- : total_body_bytes_received_(0) {}
-
-size_t QuicSpdyStreamBodyManager::OnNonBody(QuicByteCount length) {
- QUICHE_DCHECK_NE(0u, length);
-
- if (fragments_.empty()) {
- // Non-body bytes can be consumed immediately, because all previously
- // received body bytes have been read.
- return length;
- }
-
- // Non-body bytes will be consumed after last body fragment is read.
- fragments_.back().trailing_non_body_byte_count += length;
- return 0;
-}
-
-void QuicSpdyStreamBodyManager::OnBody(absl::string_view body) {
- QUICHE_DCHECK(!body.empty());
-
- fragments_.push_back({body, 0});
- total_body_bytes_received_ += body.length();
-}
-
-size_t QuicSpdyStreamBodyManager::OnBodyConsumed(size_t num_bytes) {
- QuicByteCount bytes_to_consume = 0;
- size_t remaining_bytes = num_bytes;
-
- while (remaining_bytes > 0) {
- if (fragments_.empty()) {
- QUIC_BUG(quic_bug_10394_1) << "Not enough available body to consume.";
- return 0;
- }
-
- Fragment& fragment = fragments_.front();
- const absl::string_view body = fragment.body;
-
- if (body.length() > remaining_bytes) {
- // Consume leading |remaining_bytes| bytes of body.
- bytes_to_consume += remaining_bytes;
- fragment.body = body.substr(remaining_bytes);
- return bytes_to_consume;
- }
-
- // Consume entire fragment and the following
- // |trailing_non_body_byte_count| bytes.
- remaining_bytes -= body.length();
- bytes_to_consume += body.length() + fragment.trailing_non_body_byte_count;
- fragments_.pop_front();
- }
-
- return bytes_to_consume;
-}
-
-int QuicSpdyStreamBodyManager::PeekBody(iovec* iov, size_t iov_len) const {
- QUICHE_DCHECK(iov);
- QUICHE_DCHECK_GT(iov_len, 0u);
-
- // TODO(bnc): Is this really necessary?
- if (fragments_.empty()) {
- iov[0].iov_base = nullptr;
- iov[0].iov_len = 0;
- return 0;
- }
-
- size_t iov_filled = 0;
- while (iov_filled < fragments_.size() && iov_filled < iov_len) {
- absl::string_view body = fragments_[iov_filled].body;
- iov[iov_filled].iov_base = const_cast<char*>(body.data());
- iov[iov_filled].iov_len = body.size();
- iov_filled++;
- }
-
- return iov_filled;
-}
-
-size_t QuicSpdyStreamBodyManager::ReadBody(const struct iovec* iov,
- size_t iov_len,
- size_t* total_bytes_read) {
- *total_bytes_read = 0;
- QuicByteCount bytes_to_consume = 0;
-
- // The index of iovec to write to.
- size_t index = 0;
- // Address to write to within current iovec.
- char* dest = reinterpret_cast<char*>(iov[index].iov_base);
- // Remaining space in current iovec.
- size_t dest_remaining = iov[index].iov_len;
-
- while (!fragments_.empty()) {
- Fragment& fragment = fragments_.front();
- const absl::string_view body = fragment.body;
-
- const size_t bytes_to_copy =
- std::min<size_t>(body.length(), dest_remaining);
- memcpy(dest, body.data(), bytes_to_copy);
- bytes_to_consume += bytes_to_copy;
- *total_bytes_read += bytes_to_copy;
-
- if (bytes_to_copy == body.length()) {
- // Entire fragment read.
- bytes_to_consume += fragment.trailing_non_body_byte_count;
- fragments_.pop_front();
- } else {
- // Consume leading |bytes_to_copy| bytes of body.
- fragment.body = body.substr(bytes_to_copy);
- }
-
- if (bytes_to_copy == dest_remaining) {
- // Current iovec full.
- ++index;
- if (index == iov_len) {
- break;
- }
- dest = reinterpret_cast<char*>(iov[index].iov_base);
- dest_remaining = iov[index].iov_len;
- } else {
- // Advance destination parameters within this iovec.
- dest += bytes_to_copy;
- dest_remaining -= bytes_to_copy;
- }
- }
-
- return bytes_to_consume;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_stream_body_manager.h b/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_stream_body_manager.h
deleted file mode 100644
index f34801a383c..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_stream_body_manager.h
+++ /dev/null
@@ -1,94 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_HTTP_QUIC_SPDY_STREAM_BODY_MANAGER_H_
-#define QUICHE_QUIC_CORE_HTTP_QUIC_SPDY_STREAM_BODY_MANAGER_H_
-
-#include "absl/base/attributes.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_constants.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_export.h"
-#include "quic/platform/api/quic_iovec.h"
-#include "common/quiche_circular_deque.h"
-
-namespace quic {
-
-// All data that a request stream receives falls into one of two categories:
-// * "body", that is, DATA frame payload, which the QuicStreamSequencer must
-// buffer until it is read;
-// * everything else, which QuicSpdyStream immediately processes and thus could
-// be marked as consumed with QuicStreamSequencer, unless there is some piece
-// of body received prior that still needs to be buffered.
-// QuicSpdyStreamBodyManager does two things: it keeps references to body
-// fragments (owned by QuicStreamSequencer) and offers methods to read them; and
-// it calculates the total number of bytes (including non-body bytes) the caller
-// needs to mark consumed (with QuicStreamSequencer) when non-body bytes are
-// received or when body is consumed.
-class QUIC_EXPORT_PRIVATE QuicSpdyStreamBodyManager {
- public:
- QuicSpdyStreamBodyManager();
- ~QuicSpdyStreamBodyManager() = default;
-
- // One of the following two methods must be called every time data is received
- // on the request stream.
-
- // Called when data that could immediately be marked consumed with the
- // sequencer (provided that all previous body fragments are consumed) is
- // received. |length| must be positive. Returns number of bytes the caller
- // must mark consumed, which might be zero.
- ABSL_MUST_USE_RESULT size_t OnNonBody(QuicByteCount length);
-
- // Called when body is received. |body| is added to |fragments_|. The data
- // pointed to by |body| must be kept alive until an OnBodyConsumed() or
- // ReadBody() call consumes it. |body| must not be empty.
- void OnBody(absl::string_view body);
-
- // Internally marks |num_bytes| of body consumed. |num_bytes| might be zero.
- // Returns the number of bytes that the caller should mark consumed with the
- // sequencer, which is the sum of |num_bytes| for body, and the number of any
- // interleaving or immediately trailing non-body bytes.
- ABSL_MUST_USE_RESULT size_t OnBodyConsumed(size_t num_bytes);
-
- // Set up to |iov_len| elements of iov[] to point to available bodies: each
- // iov[i].iov_base will point to a body fragment, and iov[i].iov_len will be
- // set to its length. No data is copied, no data is consumed. Returns the
- // number of iov set.
- int PeekBody(iovec* iov, size_t iov_len) const;
-
- // Copies data from available bodies into at most |iov_len| elements of iov[].
- // Internally consumes copied body bytes as well as all interleaving and
- // immediately trailing non-body bytes. |iov.iov_base| and |iov.iov_len| are
- // preassigned and will not be changed. Returns the total number of bytes the
- // caller shall mark consumed. Sets |*total_bytes_read| to the total number
- // of body bytes read.
- ABSL_MUST_USE_RESULT size_t ReadBody(const struct iovec* iov,
- size_t iov_len,
- size_t* total_bytes_read);
-
- bool HasBytesToRead() const { return !fragments_.empty(); }
-
- uint64_t total_body_bytes_received() const {
- return total_body_bytes_received_;
- }
-
- private:
- // A Fragment instance represents a body fragment with a count of bytes
- // received afterwards but before the next body fragment that can be marked
- // consumed as soon as all of the body fragment is read.
- struct QUIC_EXPORT_PRIVATE Fragment {
- // |body| must not be empty.
- absl::string_view body;
- // Might be zero.
- QuicByteCount trailing_non_body_byte_count;
- };
- // Queue of body fragments and trailing non-body byte counts.
- quiche::QuicheCircularDeque<Fragment> fragments_;
- // Total body bytes received.
- QuicByteCount total_body_bytes_received_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_HTTP_QUIC_SPDY_STREAM_BODY_MANAGER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_stream_body_manager_test.cc b/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_stream_body_manager_test.cc
deleted file mode 100644
index 90e50d4813c..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_stream_body_manager_test.cc
+++ /dev/null
@@ -1,286 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/http/quic_spdy_stream_body_manager.h"
-
-#include <algorithm>
-#include <numeric>
-#include <string>
-
-#include "absl/base/macros.h"
-#include "absl/strings/string_view.h"
-#include "quic/platform/api/quic_expect_bug.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/platform/api/quic_test.h"
-
-namespace quic {
-
-namespace test {
-
-namespace {
-
-class QuicSpdyStreamBodyManagerTest : public QuicTest {
- protected:
- QuicSpdyStreamBodyManager body_manager_;
-};
-
-TEST_F(QuicSpdyStreamBodyManagerTest, HasBytesToRead) {
- EXPECT_FALSE(body_manager_.HasBytesToRead());
- EXPECT_EQ(0u, body_manager_.total_body_bytes_received());
-
- const QuicByteCount header_length = 3;
- EXPECT_EQ(header_length, body_manager_.OnNonBody(header_length));
-
- EXPECT_FALSE(body_manager_.HasBytesToRead());
- EXPECT_EQ(0u, body_manager_.total_body_bytes_received());
-
- std::string body(1024, 'a');
- body_manager_.OnBody(body);
-
- EXPECT_TRUE(body_manager_.HasBytesToRead());
- EXPECT_EQ(1024u, body_manager_.total_body_bytes_received());
-}
-
-TEST_F(QuicSpdyStreamBodyManagerTest, ConsumeMoreThanAvailable) {
- std::string body(1024, 'a');
- body_manager_.OnBody(body);
- size_t bytes_to_consume = 0;
- EXPECT_QUIC_BUG(bytes_to_consume = body_manager_.OnBodyConsumed(2048),
- "Not enough available body to consume.");
- EXPECT_EQ(0u, bytes_to_consume);
-}
-
-TEST_F(QuicSpdyStreamBodyManagerTest, OnBodyConsumed) {
- struct {
- std::vector<QuicByteCount> frame_header_lengths;
- std::vector<const char*> frame_payloads;
- std::vector<QuicByteCount> body_bytes_to_read;
- std::vector<QuicByteCount> expected_return_values;
- } const kOnBodyConsumedTestData[] = {
- // One frame consumed in one call.
- {{2}, {"foobar"}, {6}, {6}},
- // Two frames consumed in one call.
- {{3, 5}, {"foobar", "baz"}, {9}, {14}},
- // One frame consumed in two calls.
- {{2}, {"foobar"}, {4, 2}, {4, 2}},
- // Two frames consumed in two calls matching frame boundaries.
- {{3, 5}, {"foobar", "baz"}, {6, 3}, {11, 3}},
- // Two frames consumed in two calls,
- // the first call only consuming part of the first frame.
- {{3, 5}, {"foobar", "baz"}, {5, 4}, {5, 9}},
- // Two frames consumed in two calls,
- // the first call consuming the entire first frame and part of the second.
- {{3, 5}, {"foobar", "baz"}, {7, 2}, {12, 2}},
- };
-
- for (size_t test_case_index = 0;
- test_case_index < ABSL_ARRAYSIZE(kOnBodyConsumedTestData);
- ++test_case_index) {
- const std::vector<QuicByteCount>& frame_header_lengths =
- kOnBodyConsumedTestData[test_case_index].frame_header_lengths;
- const std::vector<const char*>& frame_payloads =
- kOnBodyConsumedTestData[test_case_index].frame_payloads;
- const std::vector<QuicByteCount>& body_bytes_to_read =
- kOnBodyConsumedTestData[test_case_index].body_bytes_to_read;
- const std::vector<QuicByteCount>& expected_return_values =
- kOnBodyConsumedTestData[test_case_index].expected_return_values;
-
- for (size_t frame_index = 0; frame_index < frame_header_lengths.size();
- ++frame_index) {
- // Frame header of first frame can immediately be consumed, but not the
- // other frames. Each test case start with an empty
- // QuicSpdyStreamBodyManager.
- EXPECT_EQ(frame_index == 0 ? frame_header_lengths[frame_index] : 0u,
- body_manager_.OnNonBody(frame_header_lengths[frame_index]));
- body_manager_.OnBody(frame_payloads[frame_index]);
- }
-
- for (size_t call_index = 0; call_index < body_bytes_to_read.size();
- ++call_index) {
- EXPECT_EQ(expected_return_values[call_index],
- body_manager_.OnBodyConsumed(body_bytes_to_read[call_index]));
- }
-
- EXPECT_FALSE(body_manager_.HasBytesToRead());
- }
-}
-
-TEST_F(QuicSpdyStreamBodyManagerTest, PeekBody) {
- struct {
- std::vector<QuicByteCount> frame_header_lengths;
- std::vector<const char*> frame_payloads;
- size_t iov_len;
- } const kPeekBodyTestData[] = {
- // No frames, more iovecs than frames.
- {{}, {}, 1},
- // One frame, same number of iovecs.
- {{3}, {"foobar"}, 1},
- // One frame, more iovecs than frames.
- {{3}, {"foobar"}, 2},
- // Two frames, fewer iovecs than frames.
- {{3, 5}, {"foobar", "baz"}, 1},
- // Two frames, same number of iovecs.
- {{3, 5}, {"foobar", "baz"}, 2},
- // Two frames, more iovecs than frames.
- {{3, 5}, {"foobar", "baz"}, 3},
- };
-
- for (size_t test_case_index = 0;
- test_case_index < ABSL_ARRAYSIZE(kPeekBodyTestData); ++test_case_index) {
- const std::vector<QuicByteCount>& frame_header_lengths =
- kPeekBodyTestData[test_case_index].frame_header_lengths;
- const std::vector<const char*>& frame_payloads =
- kPeekBodyTestData[test_case_index].frame_payloads;
- size_t iov_len = kPeekBodyTestData[test_case_index].iov_len;
-
- QuicSpdyStreamBodyManager body_manager;
-
- for (size_t frame_index = 0; frame_index < frame_header_lengths.size();
- ++frame_index) {
- // Frame header of first frame can immediately be consumed, but not the
- // other frames. Each test case uses a new QuicSpdyStreamBodyManager
- // instance.
- EXPECT_EQ(frame_index == 0 ? frame_header_lengths[frame_index] : 0u,
- body_manager.OnNonBody(frame_header_lengths[frame_index]));
- body_manager.OnBody(frame_payloads[frame_index]);
- }
-
- std::vector<iovec> iovecs;
- iovecs.resize(iov_len);
- size_t iovs_filled = std::min(frame_payloads.size(), iov_len);
- ASSERT_EQ(iovs_filled,
- static_cast<size_t>(body_manager.PeekBody(&iovecs[0], iov_len)));
- for (size_t iovec_index = 0; iovec_index < iovs_filled; ++iovec_index) {
- EXPECT_EQ(frame_payloads[iovec_index],
- absl::string_view(
- static_cast<const char*>(iovecs[iovec_index].iov_base),
- iovecs[iovec_index].iov_len));
- }
- }
-}
-
-TEST_F(QuicSpdyStreamBodyManagerTest, ReadBody) {
- struct {
- std::vector<QuicByteCount> frame_header_lengths;
- std::vector<const char*> frame_payloads;
- std::vector<std::vector<QuicByteCount>> iov_lengths;
- std::vector<QuicByteCount> expected_total_bytes_read;
- std::vector<QuicByteCount> expected_return_values;
- } const kReadBodyTestData[] = {
- // One frame, one read with smaller iovec.
- {{4}, {"foo"}, {{2}}, {2}, {2}},
- // One frame, one read with same size iovec.
- {{4}, {"foo"}, {{3}}, {3}, {3}},
- // One frame, one read with larger iovec.
- {{4}, {"foo"}, {{5}}, {3}, {3}},
- // One frame, one read with two iovecs, smaller total size.
- {{4}, {"foobar"}, {{2, 3}}, {5}, {5}},
- // One frame, one read with two iovecs, same total size.
- {{4}, {"foobar"}, {{2, 4}}, {6}, {6}},
- // One frame, one read with two iovecs, larger total size in last iovec.
- {{4}, {"foobar"}, {{2, 6}}, {6}, {6}},
- // One frame, one read with extra iovecs, body ends at iovec boundary.
- {{4}, {"foobar"}, {{2, 4, 4, 3}}, {6}, {6}},
- // One frame, one read with extra iovecs, body ends not at iovec boundary.
- {{4}, {"foobar"}, {{2, 7, 4, 3}}, {6}, {6}},
- // One frame, two reads with two iovecs each, smaller total size.
- {{4}, {"foobarbaz"}, {{2, 1}, {3, 2}}, {3, 5}, {3, 5}},
- // One frame, two reads with two iovecs each, same total size.
- {{4}, {"foobarbaz"}, {{2, 1}, {4, 2}}, {3, 6}, {3, 6}},
- // One frame, two reads with two iovecs each, larger total size.
- {{4}, {"foobarbaz"}, {{2, 1}, {4, 10}}, {3, 6}, {3, 6}},
- // Two frames, one read with smaller iovec.
- {{4, 3}, {"foobar", "baz"}, {{8}}, {8}, {11}},
- // Two frames, one read with same size iovec.
- {{4, 3}, {"foobar", "baz"}, {{9}}, {9}, {12}},
- // Two frames, one read with larger iovec.
- {{4, 3}, {"foobar", "baz"}, {{10}}, {9}, {12}},
- // Two frames, one read with two iovecs, smaller total size.
- {{4, 3}, {"foobar", "baz"}, {{4, 3}}, {7}, {10}},
- // Two frames, one read with two iovecs, same total size.
- {{4, 3}, {"foobar", "baz"}, {{4, 5}}, {9}, {12}},
- // Two frames, one read with two iovecs, larger total size in last iovec.
- {{4, 3}, {"foobar", "baz"}, {{4, 6}}, {9}, {12}},
- // Two frames, one read with extra iovecs, body ends at iovec boundary.
- {{4, 3}, {"foobar", "baz"}, {{4, 6, 4, 3}}, {9}, {12}},
- // Two frames, one read with extra iovecs, body ends not at iovec
- // boundary.
- {{4, 3}, {"foobar", "baz"}, {{4, 7, 4, 3}}, {9}, {12}},
- // Two frames, two reads with two iovecs each, reads end on frame
- // boundary.
- {{4, 3}, {"foobar", "baz"}, {{2, 4}, {2, 1}}, {6, 3}, {9, 3}},
- // Three frames, three reads, extra iovecs, no iovec ends on frame
- // boundary.
- {{4, 3, 6},
- {"foobar", "bazquux", "qux"},
- {{4, 3}, {2, 3}, {5, 3}},
- {7, 5, 4},
- {10, 5, 10}},
- };
-
- for (size_t test_case_index = 0;
- test_case_index < ABSL_ARRAYSIZE(kReadBodyTestData); ++test_case_index) {
- const std::vector<QuicByteCount>& frame_header_lengths =
- kReadBodyTestData[test_case_index].frame_header_lengths;
- const std::vector<const char*>& frame_payloads =
- kReadBodyTestData[test_case_index].frame_payloads;
- const std::vector<std::vector<QuicByteCount>>& iov_lengths =
- kReadBodyTestData[test_case_index].iov_lengths;
- const std::vector<QuicByteCount>& expected_total_bytes_read =
- kReadBodyTestData[test_case_index].expected_total_bytes_read;
- const std::vector<QuicByteCount>& expected_return_values =
- kReadBodyTestData[test_case_index].expected_return_values;
-
- QuicSpdyStreamBodyManager body_manager;
-
- std::string received_body;
-
- for (size_t frame_index = 0; frame_index < frame_header_lengths.size();
- ++frame_index) {
- // Frame header of first frame can immediately be consumed, but not the
- // other frames. Each test case uses a new QuicSpdyStreamBodyManager
- // instance.
- EXPECT_EQ(frame_index == 0 ? frame_header_lengths[frame_index] : 0u,
- body_manager.OnNonBody(frame_header_lengths[frame_index]));
- body_manager.OnBody(frame_payloads[frame_index]);
- received_body.append(frame_payloads[frame_index]);
- }
-
- std::string read_body;
-
- for (size_t call_index = 0; call_index < iov_lengths.size(); ++call_index) {
- // Allocate single buffer for iovecs.
- size_t total_iov_length = std::accumulate(iov_lengths[call_index].begin(),
- iov_lengths[call_index].end(),
- static_cast<size_t>(0));
- std::string buffer(total_iov_length, 'z');
-
- // Construct iovecs pointing to contiguous areas in the buffer.
- std::vector<iovec> iovecs;
- size_t offset = 0;
- for (size_t iov_length : iov_lengths[call_index]) {
- QUICHE_CHECK(offset + iov_length <= buffer.size());
- iovecs.push_back({&buffer[offset], iov_length});
- offset += iov_length;
- }
-
- // Make sure |total_bytes_read| differs from |expected_total_bytes_read|.
- size_t total_bytes_read = expected_total_bytes_read[call_index] + 12;
- EXPECT_EQ(
- expected_return_values[call_index],
- body_manager.ReadBody(&iovecs[0], iovecs.size(), &total_bytes_read));
- read_body.append(buffer.substr(0, total_bytes_read));
- }
-
- EXPECT_EQ(received_body.substr(0, read_body.size()), read_body);
- EXPECT_EQ(read_body.size() < received_body.size(),
- body_manager.HasBytesToRead());
- }
-}
-
-} // anonymous namespace
-
-} // namespace test
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_stream_test.cc b/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_stream_test.cc
deleted file mode 100644
index c8146e1c5a1..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_stream_test.cc
+++ /dev/null
@@ -1,3454 +0,0 @@
-// Copyright 2013 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 "quic/core/http/quic_spdy_stream.h"
-
-#include <cstring>
-#include <memory>
-#include <string>
-#include <utility>
-
-#include "absl/base/macros.h"
-#include "absl/memory/memory.h"
-#include "absl/strings/escaping.h"
-#include "absl/strings/str_cat.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/crypto/null_encrypter.h"
-#include "quic/core/http/http_encoder.h"
-#include "quic/core/http/quic_spdy_session.h"
-#include "quic/core/http/spdy_utils.h"
-#include "quic/core/http/web_transport_http3.h"
-#include "quic/core/quic_connection.h"
-#include "quic/core/quic_simple_buffer_allocator.h"
-#include "quic/core/quic_stream_sequencer_buffer.h"
-#include "quic/core/quic_utils.h"
-#include "quic/core/quic_versions.h"
-#include "quic/core/quic_write_blocked_list.h"
-#include "quic/platform/api/quic_expect_bug.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/qpack/qpack_test_utils.h"
-#include "quic/test_tools/quic_config_peer.h"
-#include "quic/test_tools/quic_connection_peer.h"
-#include "quic/test_tools/quic_flow_controller_peer.h"
-#include "quic/test_tools/quic_session_peer.h"
-#include "quic/test_tools/quic_spdy_session_peer.h"
-#include "quic/test_tools/quic_spdy_stream_peer.h"
-#include "quic/test_tools/quic_stream_peer.h"
-#include "quic/test_tools/quic_test_utils.h"
-
-using spdy::kV3HighestPriority;
-using spdy::kV3LowestPriority;
-using spdy::SpdyHeaderBlock;
-using spdy::SpdyPriority;
-using testing::_;
-using testing::AnyNumber;
-using testing::AtLeast;
-using testing::DoAll;
-using testing::ElementsAre;
-using testing::Invoke;
-using testing::InvokeWithoutArgs;
-using testing::MatchesRegex;
-using testing::Pair;
-using testing::Return;
-using testing::SaveArg;
-using testing::StrictMock;
-
-namespace quic {
-namespace test {
-namespace {
-
-const bool kShouldProcessData = true;
-const char kDataFramePayload[] = "some data";
-
-class TestCryptoStream : public QuicCryptoStream, public QuicCryptoHandshaker {
- public:
- explicit TestCryptoStream(QuicSession* session)
- : QuicCryptoStream(session),
- QuicCryptoHandshaker(this, session),
- encryption_established_(false),
- one_rtt_keys_available_(false),
- params_(new QuicCryptoNegotiatedParameters) {
- // Simulate a negotiated cipher_suite with a fake value.
- params_->cipher_suite = 1;
- }
-
- void OnHandshakeMessage(const CryptoHandshakeMessage& /*message*/) override {
- encryption_established_ = true;
- one_rtt_keys_available_ = true;
- QuicErrorCode error;
- std::string error_details;
- session()->config()->SetInitialStreamFlowControlWindowToSend(
- kInitialStreamFlowControlWindowForTest);
- session()->config()->SetInitialSessionFlowControlWindowToSend(
- kInitialSessionFlowControlWindowForTest);
- if (session()->version().UsesTls()) {
- if (session()->perspective() == Perspective::IS_CLIENT) {
- session()->config()->SetOriginalConnectionIdToSend(
- session()->connection()->connection_id());
- session()->config()->SetInitialSourceConnectionIdToSend(
- session()->connection()->connection_id());
- } else {
- session()->config()->SetInitialSourceConnectionIdToSend(
- session()->connection()->client_connection_id());
- }
- TransportParameters transport_parameters;
- EXPECT_TRUE(
- session()->config()->FillTransportParameters(&transport_parameters));
- error = session()->config()->ProcessTransportParameters(
- transport_parameters, /* is_resumption = */ false, &error_details);
- } else {
- CryptoHandshakeMessage msg;
- session()->config()->ToHandshakeMessage(&msg, transport_version());
- error =
- session()->config()->ProcessPeerHello(msg, CLIENT, &error_details);
- }
- EXPECT_THAT(error, IsQuicNoError());
- session()->OnNewEncryptionKeyAvailable(
- ENCRYPTION_FORWARD_SECURE,
- std::make_unique<NullEncrypter>(session()->perspective()));
- session()->OnConfigNegotiated();
- if (session()->version().UsesTls()) {
- session()->OnTlsHandshakeComplete();
- } else {
- session()->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
- }
- if (session()->version().UsesTls()) {
- // HANDSHAKE_DONE frame.
- EXPECT_CALL(*this, HasPendingRetransmission());
- }
- session()->DiscardOldEncryptionKey(ENCRYPTION_INITIAL);
- }
-
- // QuicCryptoStream implementation
- ssl_early_data_reason_t EarlyDataReason() const override {
- return ssl_early_data_unknown;
- }
- bool encryption_established() const override {
- return encryption_established_;
- }
- bool one_rtt_keys_available() const override {
- return one_rtt_keys_available_;
- }
- HandshakeState GetHandshakeState() const override {
- return one_rtt_keys_available() ? HANDSHAKE_COMPLETE : HANDSHAKE_START;
- }
- void SetServerApplicationStateForResumption(
- std::unique_ptr<ApplicationState> /*application_state*/) override {}
- std::unique_ptr<QuicDecrypter> AdvanceKeysAndCreateCurrentOneRttDecrypter()
- override {
- return nullptr;
- }
- std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() override {
- return nullptr;
- }
- const QuicCryptoNegotiatedParameters& crypto_negotiated_params()
- const override {
- return *params_;
- }
- CryptoMessageParser* crypto_message_parser() override {
- return QuicCryptoHandshaker::crypto_message_parser();
- }
- void OnPacketDecrypted(EncryptionLevel /*level*/) override {}
- void OnOneRttPacketAcknowledged() override {}
- void OnHandshakePacketSent() override {}
- void OnConnectionClosed(QuicErrorCode /*error*/,
- ConnectionCloseSource /*source*/) override {}
- void OnHandshakeDoneReceived() override {}
- void OnNewTokenReceived(absl::string_view /*token*/) override {}
- std::string GetAddressToken(
- const CachedNetworkParameters* /*cached_network_parameters*/)
- const override {
- return "";
- }
- bool ValidateAddressToken(absl::string_view /*token*/) const override {
- return true;
- }
- const CachedNetworkParameters* PreviousCachedNetworkParams() const override {
- return nullptr;
- }
- void SetPreviousCachedNetworkParams(
- CachedNetworkParameters /*cached_network_params*/) override {}
-
- MOCK_METHOD(void, OnCanWrite, (), (override));
-
- bool HasPendingCryptoRetransmission() const override { return false; }
-
- MOCK_METHOD(bool, HasPendingRetransmission, (), (const, override));
-
- bool ExportKeyingMaterial(absl::string_view /*label*/,
- absl::string_view /*context*/,
- size_t /*result_len*/,
- std::string* /*result*/) override {
- return false;
- }
-
- SSL* GetSsl() const override { return nullptr; }
-
- private:
- using QuicCryptoStream::session;
-
- bool encryption_established_;
- bool one_rtt_keys_available_;
- QuicReferenceCountedPointer<QuicCryptoNegotiatedParameters> params_;
-};
-
-class TestStream : public QuicSpdyStream {
- public:
- TestStream(QuicStreamId id, QuicSpdySession* session,
- bool should_process_data)
- : QuicSpdyStream(id, session, BIDIRECTIONAL),
- should_process_data_(should_process_data),
- headers_payload_length_(0) {}
- ~TestStream() override = default;
-
- using QuicSpdyStream::set_ack_listener;
- using QuicStream::CloseWriteSide;
- using QuicStream::WriteOrBufferData;
-
- void OnBodyAvailable() override {
- if (!should_process_data_) {
- return;
- }
- char buffer[2048];
- struct iovec vec;
- vec.iov_base = buffer;
- vec.iov_len = ABSL_ARRAYSIZE(buffer);
- size_t bytes_read = Readv(&vec, 1);
- data_ += std::string(buffer, bytes_read);
- }
-
- MOCK_METHOD(void, WriteHeadersMock, (bool fin), ());
-
- size_t WriteHeadersImpl(spdy::SpdyHeaderBlock header_block, bool fin,
- QuicReferenceCountedPointer<QuicAckListenerInterface>
- /*ack_listener*/) override {
- saved_headers_ = std::move(header_block);
- WriteHeadersMock(fin);
- if (VersionUsesHttp3(transport_version())) {
- // In this case, call QuicSpdyStream::WriteHeadersImpl() that does the
- // actual work of closing the stream.
- return QuicSpdyStream::WriteHeadersImpl(saved_headers_.Clone(), fin,
- nullptr);
- }
- return 0;
- }
-
- const std::string& data() const { return data_; }
- const spdy::SpdyHeaderBlock& saved_headers() const { return saved_headers_; }
-
- // Expose protected accessor.
- const QuicStreamSequencer* sequencer() const {
- return QuicStream::sequencer();
- }
-
- void OnStreamHeaderList(bool fin, size_t frame_len,
- const QuicHeaderList& header_list) override {
- headers_payload_length_ = frame_len;
- QuicSpdyStream::OnStreamHeaderList(fin, frame_len, header_list);
- }
-
- size_t headers_payload_length() const { return headers_payload_length_; }
-
- bool AreHeadersValid(const QuicHeaderList& header_list) const override {
- return !GetQuicReloadableFlag(quic_verify_request_headers_2) ||
- QuicSpdyStream::AreHeadersValid(header_list);
- }
-
- private:
- bool should_process_data_;
- spdy::SpdyHeaderBlock saved_headers_;
- std::string data_;
- size_t headers_payload_length_;
-};
-
-class TestSession : public MockQuicSpdySession {
- public:
- explicit TestSession(QuicConnection* connection)
- : MockQuicSpdySession(connection, /*create_mock_crypto_stream=*/false),
- crypto_stream_(this) {}
-
- TestCryptoStream* GetMutableCryptoStream() override {
- return &crypto_stream_;
- }
-
- const TestCryptoStream* GetCryptoStream() const override {
- return &crypto_stream_;
- }
-
- bool ShouldNegotiateWebTransport() override { return enable_webtransport_; }
- void EnableWebTransport() { enable_webtransport_ = true; }
-
- HttpDatagramSupport LocalHttpDatagramSupport() override {
- return local_http_datagram_support_;
- }
- void set_local_http_datagram_support(HttpDatagramSupport value) {
- local_http_datagram_support_ = value;
- }
-
- private:
- bool enable_webtransport_ = false;
- HttpDatagramSupport local_http_datagram_support_ = HttpDatagramSupport::kNone;
- StrictMock<TestCryptoStream> crypto_stream_;
-};
-
-class TestMockUpdateStreamSession : public MockQuicSpdySession {
- public:
- explicit TestMockUpdateStreamSession(QuicConnection* connection)
- : MockQuicSpdySession(connection),
- expected_precedence_(
- spdy::SpdyStreamPrecedence(QuicStream::kDefaultPriority)) {}
-
- void UpdateStreamPriority(
- QuicStreamId id, const spdy::SpdyStreamPrecedence& precedence) override {
- EXPECT_EQ(id, expected_stream_->id());
- EXPECT_EQ(expected_precedence_, precedence);
- EXPECT_EQ(expected_precedence_, expected_stream_->precedence());
- }
-
- void SetExpectedStream(QuicSpdyStream* stream) { expected_stream_ = stream; }
- void SetExpectedPriority(const spdy::SpdyStreamPrecedence& precedence) {
- expected_precedence_ = precedence;
- }
-
- private:
- QuicSpdyStream* expected_stream_;
- spdy::SpdyStreamPrecedence expected_precedence_;
-};
-
-class QuicSpdyStreamTest : public QuicTestWithParam<ParsedQuicVersion> {
- protected:
- QuicSpdyStreamTest() {
- headers_[":host"] = "www.google.com";
- headers_[":path"] = "/index.hml";
- headers_[":scheme"] = "https";
- headers_["cookie"] =
- "__utma=208381060.1228362404.1372200928.1372200928.1372200928.1; "
- "__utmc=160408618; "
- "GX=DQAAAOEAAACWJYdewdE9rIrW6qw3PtVi2-d729qaa-74KqOsM1NVQblK4VhX"
- "hoALMsy6HOdDad2Sz0flUByv7etmo3mLMidGrBoljqO9hSVA40SLqpG_iuKKSHX"
- "RW3Np4bq0F0SDGDNsW0DSmTS9ufMRrlpARJDS7qAI6M3bghqJp4eABKZiRqebHT"
- "pMU-RXvTI5D5oCF1vYxYofH_l1Kviuiy3oQ1kS1enqWgbhJ2t61_SNdv-1XJIS0"
- "O3YeHLmVCs62O6zp89QwakfAWK9d3IDQvVSJzCQsvxvNIvaZFa567MawWlXg0Rh"
- "1zFMi5vzcns38-8_Sns; "
- "GA=v*2%2Fmem*57968640*47239936%2Fmem*57968640*47114716%2Fno-nm-"
- "yj*15%2Fno-cc-yj*5%2Fpc-ch*133685%2Fpc-s-cr*133947%2Fpc-s-t*1339"
- "47%2Fno-nm-yj*4%2Fno-cc-yj*1%2Fceft-as*1%2Fceft-nqas*0%2Fad-ra-c"
- "v_p%2Fad-nr-cv_p-f*1%2Fad-v-cv_p*859%2Fad-ns-cv_p-f*1%2Ffn-v-ad%"
- "2Fpc-t*250%2Fpc-cm*461%2Fpc-s-cr*722%2Fpc-s-t*722%2Fau_p*4"
- "SICAID=AJKiYcHdKgxum7KMXG0ei2t1-W4OD1uW-ecNsCqC0wDuAXiDGIcT_HA2o1"
- "3Rs1UKCuBAF9g8rWNOFbxt8PSNSHFuIhOo2t6bJAVpCsMU5Laa6lewuTMYI8MzdQP"
- "ARHKyW-koxuhMZHUnGBJAM1gJODe0cATO_KGoX4pbbFxxJ5IicRxOrWK_5rU3cdy6"
- "edlR9FsEdH6iujMcHkbE5l18ehJDwTWmBKBzVD87naobhMMrF6VvnDGxQVGp9Ir_b"
- "Rgj3RWUoPumQVCxtSOBdX0GlJOEcDTNCzQIm9BSfetog_eP_TfYubKudt5eMsXmN6"
- "QnyXHeGeK2UINUzJ-D30AFcpqYgH9_1BvYSpi7fc7_ydBU8TaD8ZRxvtnzXqj0RfG"
- "tuHghmv3aD-uzSYJ75XDdzKdizZ86IG6Fbn1XFhYZM-fbHhm3mVEXnyRW4ZuNOLFk"
- "Fas6LMcVC6Q8QLlHYbXBpdNFuGbuZGUnav5C-2I_-46lL0NGg3GewxGKGHvHEfoyn"
- "EFFlEYHsBQ98rXImL8ySDycdLEFvBPdtctPmWCfTxwmoSMLHU2SCVDhbqMWU5b0yr"
- "JBCScs_ejbKaqBDoB7ZGxTvqlrB__2ZmnHHjCr8RgMRtKNtIeuZAo ";
- }
-
- ~QuicSpdyStreamTest() override = default;
-
- // Return QPACK-encoded header block without using the dynamic table.
- std::string EncodeQpackHeaders(
- std::vector<std::pair<absl::string_view, absl::string_view>> headers) {
- SpdyHeaderBlock header_block;
- for (const auto& header_field : headers) {
- header_block.AppendValueOrAddHeader(header_field.first,
- header_field.second);
- }
-
- return EncodeQpackHeaders(header_block);
- }
-
- // Return QPACK-encoded header block without using the dynamic table.
- std::string EncodeQpackHeaders(const SpdyHeaderBlock& header) {
- NoopQpackStreamSenderDelegate encoder_stream_sender_delegate;
- auto qpack_encoder = std::make_unique<QpackEncoder>(session_.get());
- qpack_encoder->set_qpack_stream_sender_delegate(
- &encoder_stream_sender_delegate);
- // QpackEncoder does not use the dynamic table by default,
- // therefore the value of |stream_id| does not matter.
- return qpack_encoder->EncodeHeaderList(/* stream_id = */ 0, header,
- nullptr);
- }
-
- void Initialize(bool stream_should_process_data) {
- InitializeWithPerspective(stream_should_process_data,
- Perspective::IS_SERVER);
- }
-
- void InitializeWithPerspective(bool stream_should_process_data,
- Perspective perspective) {
- connection_ = new StrictMock<MockQuicConnection>(
- &helper_, &alarm_factory_, perspective, SupportedVersions(GetParam()));
- session_ = std::make_unique<StrictMock<TestSession>>(connection_);
- EXPECT_CALL(*session_, OnCongestionWindowChange(_)).Times(AnyNumber());
- session_->Initialize();
- if (connection_->version().SupportsAntiAmplificationLimit()) {
- QuicConnectionPeer::SetAddressValidated(connection_);
- }
- connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
- ON_CALL(*session_, WritevData(_, _, _, _, _, _))
- .WillByDefault(
- Invoke(session_.get(), &MockQuicSpdySession::ConsumeData));
-
- stream_ =
- new StrictMock<TestStream>(GetNthClientInitiatedBidirectionalId(0),
- session_.get(), stream_should_process_data);
- session_->ActivateStream(absl::WrapUnique(stream_));
- stream2_ =
- new StrictMock<TestStream>(GetNthClientInitiatedBidirectionalId(1),
- session_.get(), stream_should_process_data);
- session_->ActivateStream(absl::WrapUnique(stream2_));
- QuicConfigPeer::SetReceivedInitialSessionFlowControlWindow(
- session_->config(), kMinimumFlowControlSendWindow);
- QuicConfigPeer::SetReceivedInitialMaxStreamDataBytesUnidirectional(
- session_->config(), kMinimumFlowControlSendWindow);
- QuicConfigPeer::SetReceivedInitialMaxStreamDataBytesIncomingBidirectional(
- session_->config(), kMinimumFlowControlSendWindow);
- QuicConfigPeer::SetReceivedInitialMaxStreamDataBytesOutgoingBidirectional(
- session_->config(), kMinimumFlowControlSendWindow);
- QuicConfigPeer::SetReceivedMaxUnidirectionalStreams(session_->config(), 10);
- session_->OnConfigNegotiated();
- if (UsesHttp3()) {
- // The control stream will write the stream type, a greased frame, and
- // SETTINGS frame.
- int num_control_stream_writes = 3;
- auto send_control_stream =
- QuicSpdySessionPeer::GetSendControlStream(session_.get());
- EXPECT_CALL(*session_,
- WritevData(send_control_stream->id(), _, _, _, _, _))
- .Times(num_control_stream_writes);
- }
- TestCryptoStream* crypto_stream = session_->GetMutableCryptoStream();
- EXPECT_CALL(*crypto_stream, HasPendingRetransmission()).Times(AnyNumber());
-
- if (connection_->version().UsesTls() &&
- session_->perspective() == Perspective::IS_SERVER) {
- // HANDSHAKE_DONE frame.
- EXPECT_CALL(*connection_, SendControlFrame(_))
- .WillOnce(Invoke(&ClearControlFrame));
- }
- CryptoHandshakeMessage message;
- session_->GetMutableCryptoStream()->OnHandshakeMessage(message);
- }
-
- QuicHeaderList ProcessHeaders(bool fin, const SpdyHeaderBlock& headers) {
- QuicHeaderList h = AsHeaderList(headers);
- stream_->OnStreamHeaderList(fin, h.uncompressed_header_bytes(), h);
- return h;
- }
-
- QuicStreamId GetNthClientInitiatedBidirectionalId(int n) {
- return GetNthClientInitiatedBidirectionalStreamId(
- connection_->transport_version(), n);
- }
-
- bool UsesHttp3() const {
- return VersionUsesHttp3(GetParam().transport_version);
- }
-
- // Construct HEADERS frame with QPACK-encoded |headers| without using the
- // dynamic table.
- std::string HeadersFrame(
- std::vector<std::pair<absl::string_view, absl::string_view>> headers) {
- return HeadersFrame(EncodeQpackHeaders(headers));
- }
-
- // Construct HEADERS frame with QPACK-encoded |headers| without using the
- // dynamic table.
- std::string HeadersFrame(const SpdyHeaderBlock& headers) {
- return HeadersFrame(EncodeQpackHeaders(headers));
- }
-
- // Construct HEADERS frame with given payload.
- std::string HeadersFrame(absl::string_view payload) {
- std::unique_ptr<char[]> headers_buffer;
- QuicByteCount headers_frame_header_length =
- HttpEncoder::SerializeHeadersFrameHeader(payload.length(),
- &headers_buffer);
- absl::string_view headers_frame_header(headers_buffer.get(),
- headers_frame_header_length);
- return absl::StrCat(headers_frame_header, payload);
- }
-
- std::string DataFrame(absl::string_view payload) {
- QuicBuffer header = HttpEncoder::SerializeDataFrameHeader(
- payload.length(), SimpleBufferAllocator::Get());
- return absl::StrCat(header.AsStringView(), payload);
- }
-
- std::string UnknownFrame(uint64_t frame_type, absl::string_view payload) {
- std::string frame;
- const size_t length = QuicDataWriter::GetVarInt62Len(frame_type) +
- QuicDataWriter::GetVarInt62Len(payload.size()) +
- payload.size();
- frame.resize(length);
-
- QuicDataWriter writer(length, const_cast<char*>(frame.data()));
- writer.WriteVarInt62(frame_type);
- writer.WriteStringPieceVarInt62(payload);
- // Even though integers can be encoded with different lengths,
- // QuicDataWriter is expected to produce an encoding in Write*() of length
- // promised in GetVarInt62Len().
- QUICHE_DCHECK_EQ(length, writer.length());
-
- return frame;
- }
-
- MockQuicConnectionHelper helper_;
- MockAlarmFactory alarm_factory_;
- MockQuicConnection* connection_;
- std::unique_ptr<TestSession> session_;
-
- // Owned by the |session_|.
- TestStream* stream_;
- TestStream* stream2_;
-
- SpdyHeaderBlock headers_;
-};
-
-INSTANTIATE_TEST_SUITE_P(Tests, QuicSpdyStreamTest,
- ::testing::ValuesIn(AllSupportedVersions()),
- ::testing::PrintToStringParamName());
-
-TEST_P(QuicSpdyStreamTest, ProcessHeaderList) {
- Initialize(kShouldProcessData);
-
- stream_->OnStreamHeadersPriority(
- spdy::SpdyStreamPrecedence(kV3HighestPriority));
- ProcessHeaders(false, headers_);
- EXPECT_EQ("", stream_->data());
- EXPECT_FALSE(stream_->header_list().empty());
- EXPECT_FALSE(stream_->IsDoneReading());
-}
-
-TEST_P(QuicSpdyStreamTest, ProcessTooLargeHeaderList) {
- Initialize(kShouldProcessData);
-
- if (!UsesHttp3()) {
- QuicHeaderList headers;
- stream_->OnStreamHeadersPriority(
- spdy::SpdyStreamPrecedence(kV3HighestPriority));
-
- EXPECT_CALL(
- *session_,
- MaybeSendRstStreamFrame(
- stream_->id(),
- QuicResetStreamError::FromInternal(QUIC_HEADERS_TOO_LARGE), 0));
- stream_->OnStreamHeaderList(false, 1 << 20, headers);
-
- EXPECT_THAT(stream_->stream_error(), IsStreamError(QUIC_HEADERS_TOO_LARGE));
-
- return;
- }
-
- // Header list size includes 32 bytes for overhead per header field.
- session_->set_max_inbound_header_list_size(40);
- std::string headers =
- HeadersFrame({std::make_pair("foo", "too long headers")});
-
- QuicStreamFrame frame(stream_->id(), false, 0, headers);
-
- EXPECT_CALL(*session_, MaybeSendStopSendingFrame(
- stream_->id(), QuicResetStreamError::FromInternal(
- QUIC_HEADERS_TOO_LARGE)));
- EXPECT_CALL(
- *session_,
- MaybeSendRstStreamFrame(
- stream_->id(),
- QuicResetStreamError::FromInternal(QUIC_HEADERS_TOO_LARGE), 0));
-
- auto qpack_decoder_stream =
- QuicSpdySessionPeer::GetQpackDecoderSendStream(session_.get());
- // Stream type and stream cancellation.
- EXPECT_CALL(*session_,
- WritevData(qpack_decoder_stream->id(), _, _, NO_FIN, _, _))
- .Times(2);
-
- stream_->OnStreamFrame(frame);
- EXPECT_THAT(stream_->stream_error(), IsStreamError(QUIC_HEADERS_TOO_LARGE));
-}
-
-TEST_P(QuicSpdyStreamTest, QpackProcessLargeHeaderListDiscountOverhead) {
- if (!UsesHttp3()) {
- return;
- }
- // Setting this flag to false causes no per-entry overhead to be included
- // in the header size.
- SetQuicFlag(FLAGS_quic_header_size_limit_includes_overhead, false);
- Initialize(kShouldProcessData);
- session_->set_max_inbound_header_list_size(40);
- std::string headers =
- HeadersFrame({std::make_pair("foo", "too long headers")});
-
- QuicStreamFrame frame(stream_->id(), false, 0, headers);
- stream_->OnStreamFrame(frame);
- EXPECT_THAT(stream_->stream_error(), IsStreamError(QUIC_STREAM_NO_ERROR));
-}
-
-TEST_P(QuicSpdyStreamTest, ProcessHeaderListWithFin) {
- Initialize(kShouldProcessData);
-
- size_t total_bytes = 0;
- QuicHeaderList headers;
- for (auto p : headers_) {
- headers.OnHeader(p.first, p.second);
- total_bytes += p.first.size() + p.second.size();
- }
- stream_->OnStreamHeadersPriority(
- spdy::SpdyStreamPrecedence(kV3HighestPriority));
- stream_->OnStreamHeaderList(true, total_bytes, headers);
- EXPECT_EQ("", stream_->data());
- EXPECT_FALSE(stream_->header_list().empty());
- EXPECT_FALSE(stream_->IsDoneReading());
- EXPECT_TRUE(stream_->HasReceivedFinalOffset());
-}
-
-// A valid status code should be 3-digit integer. The first digit should be in
-// the range of [1, 5]. All the others are invalid.
-TEST_P(QuicSpdyStreamTest, ParseHeaderStatusCode) {
- Initialize(kShouldProcessData);
- int status_code = 0;
-
- // Valid status codes.
- headers_[":status"] = "404";
- EXPECT_TRUE(stream_->ParseHeaderStatusCode(headers_, &status_code));
- EXPECT_EQ(404, status_code);
-
- headers_[":status"] = "100";
- EXPECT_TRUE(stream_->ParseHeaderStatusCode(headers_, &status_code));
- EXPECT_EQ(100, status_code);
-
- headers_[":status"] = "599";
- EXPECT_TRUE(stream_->ParseHeaderStatusCode(headers_, &status_code));
- EXPECT_EQ(599, status_code);
-
- // Invalid status codes.
- headers_[":status"] = "010";
- EXPECT_FALSE(stream_->ParseHeaderStatusCode(headers_, &status_code));
-
- headers_[":status"] = "600";
- EXPECT_FALSE(stream_->ParseHeaderStatusCode(headers_, &status_code));
-
- headers_[":status"] = "200 ok";
- EXPECT_FALSE(stream_->ParseHeaderStatusCode(headers_, &status_code));
-
- headers_[":status"] = "2000";
- EXPECT_FALSE(stream_->ParseHeaderStatusCode(headers_, &status_code));
-
- headers_[":status"] = "+200";
- EXPECT_FALSE(stream_->ParseHeaderStatusCode(headers_, &status_code));
-
- headers_[":status"] = "+20";
- EXPECT_FALSE(stream_->ParseHeaderStatusCode(headers_, &status_code));
-
- headers_[":status"] = "-10";
- EXPECT_FALSE(stream_->ParseHeaderStatusCode(headers_, &status_code));
-
- headers_[":status"] = "-100";
- EXPECT_FALSE(stream_->ParseHeaderStatusCode(headers_, &status_code));
-
- // Leading or trailing spaces are also invalid.
- headers_[":status"] = " 200";
- EXPECT_FALSE(stream_->ParseHeaderStatusCode(headers_, &status_code));
-
- headers_[":status"] = "200 ";
- EXPECT_FALSE(stream_->ParseHeaderStatusCode(headers_, &status_code));
-
- headers_[":status"] = " 200 ";
- EXPECT_FALSE(stream_->ParseHeaderStatusCode(headers_, &status_code));
-
- headers_[":status"] = " ";
- EXPECT_FALSE(stream_->ParseHeaderStatusCode(headers_, &status_code));
-}
-
-TEST_P(QuicSpdyStreamTest, MarkHeadersConsumed) {
- Initialize(kShouldProcessData);
-
- std::string body = "this is the body";
- QuicHeaderList headers = ProcessHeaders(false, headers_);
- EXPECT_EQ(headers, stream_->header_list());
-
- stream_->ConsumeHeaderList();
- EXPECT_EQ(QuicHeaderList(), stream_->header_list());
-}
-
-TEST_P(QuicSpdyStreamTest, ProcessWrongFramesOnSpdyStream) {
- if (!UsesHttp3()) {
- return;
- }
-
- Initialize(kShouldProcessData);
- testing::InSequence s;
- connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
- GoAwayFrame goaway;
- goaway.id = 0x1;
- std::unique_ptr<char[]> buffer;
- QuicByteCount header_length =
- HttpEncoder::SerializeGoAwayFrame(goaway, &buffer);
- std::string data = std::string(buffer.get(), header_length);
-
- EXPECT_EQ("", stream_->data());
- QuicHeaderList headers = ProcessHeaders(false, headers_);
- EXPECT_EQ(headers, stream_->header_list());
- stream_->ConsumeHeaderList();
- QuicStreamFrame frame(GetNthClientInitiatedBidirectionalId(0), false, 0,
- absl::string_view(data));
-
- EXPECT_CALL(*connection_,
- CloseConnection(QUIC_HTTP_FRAME_UNEXPECTED_ON_SPDY_STREAM, _, _))
- .WillOnce(
- (Invoke([this](QuicErrorCode error, const std::string& error_details,
- ConnectionCloseBehavior connection_close_behavior) {
- connection_->ReallyCloseConnection(error, error_details,
- connection_close_behavior);
- })));
- EXPECT_CALL(*connection_, SendConnectionClosePacket(_, _, _));
- EXPECT_CALL(*session_, OnConnectionClosed(_, _))
- .WillOnce(Invoke([this](const QuicConnectionCloseFrame& frame,
- ConnectionCloseSource source) {
- session_->ReallyOnConnectionClosed(frame, source);
- }));
- EXPECT_CALL(*session_, MaybeSendRstStreamFrame(_, _, _)).Times(2);
-
- stream_->OnStreamFrame(frame);
-}
-
-TEST_P(QuicSpdyStreamTest, Http3FrameError) {
- if (!UsesHttp3()) {
- return;
- }
-
- Initialize(kShouldProcessData);
-
- // PUSH_PROMISE frame with empty payload is considered invalid.
- std::string invalid_http3_frame = absl::HexStringToBytes("0500");
- QuicStreamFrame stream_frame(stream_->id(), /* fin = */ false,
- /* offset = */ 0, invalid_http3_frame);
-
- EXPECT_CALL(*connection_, CloseConnection(QUIC_HTTP_FRAME_ERROR, _, _));
- stream_->OnStreamFrame(stream_frame);
-}
-
-TEST_P(QuicSpdyStreamTest, UnexpectedHttp3Frame) {
- if (!UsesHttp3()) {
- return;
- }
-
- Initialize(kShouldProcessData);
-
- // SETTINGS frame with empty payload.
- std::string settings = absl::HexStringToBytes("0400");
- QuicStreamFrame stream_frame(stream_->id(), /* fin = */ false,
- /* offset = */ 0, settings);
-
- EXPECT_CALL(*connection_,
- CloseConnection(QUIC_HTTP_FRAME_UNEXPECTED_ON_SPDY_STREAM, _, _));
- stream_->OnStreamFrame(stream_frame);
-}
-
-TEST_P(QuicSpdyStreamTest, ProcessHeadersAndBody) {
- Initialize(kShouldProcessData);
-
- std::string body = "this is the body";
- std::string data = UsesHttp3() ? DataFrame(body) : body;
-
- EXPECT_EQ("", stream_->data());
- QuicHeaderList headers = ProcessHeaders(false, headers_);
- EXPECT_EQ(headers, stream_->header_list());
- stream_->ConsumeHeaderList();
- QuicStreamFrame frame(GetNthClientInitiatedBidirectionalId(0), false, 0,
- absl::string_view(data));
- stream_->OnStreamFrame(frame);
- EXPECT_EQ(QuicHeaderList(), stream_->header_list());
- EXPECT_EQ(body, stream_->data());
-}
-
-TEST_P(QuicSpdyStreamTest, ProcessHeadersAndBodyFragments) {
- std::string body = "this is the body";
- std::string data = UsesHttp3() ? DataFrame(body) : body;
-
- for (size_t fragment_size = 1; fragment_size < data.size(); ++fragment_size) {
- Initialize(kShouldProcessData);
- QuicHeaderList headers = ProcessHeaders(false, headers_);
- ASSERT_EQ(headers, stream_->header_list());
- stream_->ConsumeHeaderList();
- for (size_t offset = 0; offset < data.size(); offset += fragment_size) {
- size_t remaining_data = data.size() - offset;
- absl::string_view fragment(data.data() + offset,
- std::min(fragment_size, remaining_data));
- QuicStreamFrame frame(GetNthClientInitiatedBidirectionalId(0), false,
- offset, absl::string_view(fragment));
- stream_->OnStreamFrame(frame);
- }
- ASSERT_EQ(body, stream_->data()) << "fragment_size: " << fragment_size;
- }
-}
-
-TEST_P(QuicSpdyStreamTest, ProcessHeadersAndBodyFragmentsSplit) {
- std::string body = "this is the body";
- std::string data = UsesHttp3() ? DataFrame(body) : body;
-
- for (size_t split_point = 1; split_point < data.size() - 1; ++split_point) {
- Initialize(kShouldProcessData);
- QuicHeaderList headers = ProcessHeaders(false, headers_);
- ASSERT_EQ(headers, stream_->header_list());
- stream_->ConsumeHeaderList();
-
- absl::string_view fragment1(data.data(), split_point);
- QuicStreamFrame frame1(GetNthClientInitiatedBidirectionalId(0), false, 0,
- absl::string_view(fragment1));
- stream_->OnStreamFrame(frame1);
-
- absl::string_view fragment2(data.data() + split_point,
- data.size() - split_point);
- QuicStreamFrame frame2(GetNthClientInitiatedBidirectionalId(0), false,
- split_point, absl::string_view(fragment2));
- stream_->OnStreamFrame(frame2);
-
- ASSERT_EQ(body, stream_->data()) << "split_point: " << split_point;
- }
-}
-
-TEST_P(QuicSpdyStreamTest, ProcessHeadersAndBodyReadv) {
- Initialize(!kShouldProcessData);
-
- std::string body = "this is the body";
- std::string data = UsesHttp3() ? DataFrame(body) : body;
-
- ProcessHeaders(false, headers_);
- QuicStreamFrame frame(GetNthClientInitiatedBidirectionalId(0), false, 0,
- absl::string_view(data));
- stream_->OnStreamFrame(frame);
- stream_->ConsumeHeaderList();
-
- char buffer[2048];
- ASSERT_LT(data.length(), ABSL_ARRAYSIZE(buffer));
- struct iovec vec;
- vec.iov_base = buffer;
- vec.iov_len = ABSL_ARRAYSIZE(buffer);
-
- size_t bytes_read = stream_->Readv(&vec, 1);
- QuicStreamPeer::CloseReadSide(stream_);
- EXPECT_EQ(body.length(), bytes_read);
- EXPECT_EQ(body, std::string(buffer, bytes_read));
-}
-
-TEST_P(QuicSpdyStreamTest, ProcessHeadersAndLargeBodySmallReadv) {
- Initialize(kShouldProcessData);
- std::string body(12 * 1024, 'a');
- std::string data = UsesHttp3() ? DataFrame(body) : body;
-
- ProcessHeaders(false, headers_);
- QuicStreamFrame frame(GetNthClientInitiatedBidirectionalId(0), false, 0,
- absl::string_view(data));
- stream_->OnStreamFrame(frame);
- stream_->ConsumeHeaderList();
- char buffer[2048];
- char buffer2[2048];
- struct iovec vec[2];
- vec[0].iov_base = buffer;
- vec[0].iov_len = ABSL_ARRAYSIZE(buffer);
- vec[1].iov_base = buffer2;
- vec[1].iov_len = ABSL_ARRAYSIZE(buffer2);
- size_t bytes_read = stream_->Readv(vec, 2);
- EXPECT_EQ(2048u * 2, bytes_read);
- EXPECT_EQ(body.substr(0, 2048), std::string(buffer, 2048));
- EXPECT_EQ(body.substr(2048, 2048), std::string(buffer2, 2048));
-}
-
-TEST_P(QuicSpdyStreamTest, ProcessHeadersAndBodyMarkConsumed) {
- Initialize(!kShouldProcessData);
-
- std::string body = "this is the body";
- std::string data = UsesHttp3() ? DataFrame(body) : body;
-
- ProcessHeaders(false, headers_);
- QuicStreamFrame frame(GetNthClientInitiatedBidirectionalId(0), false, 0,
- absl::string_view(data));
- stream_->OnStreamFrame(frame);
- stream_->ConsumeHeaderList();
-
- struct iovec vec;
-
- EXPECT_EQ(1, stream_->GetReadableRegions(&vec, 1));
- EXPECT_EQ(body.length(), vec.iov_len);
- EXPECT_EQ(body, std::string(static_cast<char*>(vec.iov_base), vec.iov_len));
-
- stream_->MarkConsumed(body.length());
- EXPECT_EQ(data.length(), QuicStreamPeer::bytes_consumed(stream_));
-}
-
-TEST_P(QuicSpdyStreamTest, ProcessHeadersAndConsumeMultipleBody) {
- Initialize(!kShouldProcessData);
- std::string body1 = "this is body 1";
- std::string data1 = UsesHttp3() ? DataFrame(body1) : body1;
- std::string body2 = "body 2";
- std::string data2 = UsesHttp3() ? DataFrame(body2) : body2;
-
- ProcessHeaders(false, headers_);
- QuicStreamFrame frame1(GetNthClientInitiatedBidirectionalId(0), false, 0,
- absl::string_view(data1));
- QuicStreamFrame frame2(GetNthClientInitiatedBidirectionalId(0), false,
- data1.length(), absl::string_view(data2));
- stream_->OnStreamFrame(frame1);
- stream_->OnStreamFrame(frame2);
- stream_->ConsumeHeaderList();
-
- stream_->MarkConsumed(body1.length() + body2.length());
- EXPECT_EQ(data1.length() + data2.length(),
- QuicStreamPeer::bytes_consumed(stream_));
-}
-
-TEST_P(QuicSpdyStreamTest, ProcessHeadersAndBodyIncrementalReadv) {
- Initialize(!kShouldProcessData);
-
- std::string body = "this is the body";
- std::string data = UsesHttp3() ? DataFrame(body) : body;
-
- ProcessHeaders(false, headers_);
- QuicStreamFrame frame(GetNthClientInitiatedBidirectionalId(0), false, 0,
- absl::string_view(data));
- stream_->OnStreamFrame(frame);
- stream_->ConsumeHeaderList();
-
- char buffer[1];
- struct iovec vec;
- vec.iov_base = buffer;
- vec.iov_len = ABSL_ARRAYSIZE(buffer);
-
- for (size_t i = 0; i < body.length(); ++i) {
- size_t bytes_read = stream_->Readv(&vec, 1);
- ASSERT_EQ(1u, bytes_read);
- EXPECT_EQ(body.data()[i], buffer[0]);
- }
-}
-
-TEST_P(QuicSpdyStreamTest, ProcessHeadersUsingReadvWithMultipleIovecs) {
- Initialize(!kShouldProcessData);
-
- std::string body = "this is the body";
- std::string data = UsesHttp3() ? DataFrame(body) : body;
-
- ProcessHeaders(false, headers_);
- QuicStreamFrame frame(GetNthClientInitiatedBidirectionalId(0), false, 0,
- absl::string_view(data));
- stream_->OnStreamFrame(frame);
- stream_->ConsumeHeaderList();
-
- char buffer1[1];
- char buffer2[1];
- struct iovec vec[2];
- vec[0].iov_base = buffer1;
- vec[0].iov_len = ABSL_ARRAYSIZE(buffer1);
- vec[1].iov_base = buffer2;
- vec[1].iov_len = ABSL_ARRAYSIZE(buffer2);
-
- for (size_t i = 0; i < body.length(); i += 2) {
- size_t bytes_read = stream_->Readv(vec, 2);
- ASSERT_EQ(2u, bytes_read) << i;
- ASSERT_EQ(body.data()[i], buffer1[0]) << i;
- ASSERT_EQ(body.data()[i + 1], buffer2[0]) << i;
- }
-}
-
-// Tests that we send a BLOCKED frame to the peer when we attempt to write, but
-// are flow control blocked.
-TEST_P(QuicSpdyStreamTest, StreamFlowControlBlocked) {
- Initialize(kShouldProcessData);
- testing::InSequence seq;
-
- // Set a small flow control limit.
- const uint64_t kWindow = 36;
- QuicStreamPeer::SetSendWindowOffset(stream_, kWindow);
- EXPECT_EQ(kWindow, QuicStreamPeer::SendWindowOffset(stream_));
-
- // Try to send more data than the flow control limit allows.
- const uint64_t kOverflow = 15;
- std::string body(kWindow + kOverflow, 'a');
-
- const uint64_t kHeaderLength = UsesHttp3() ? 2 : 0;
- if (UsesHttp3()) {
- EXPECT_CALL(*session_, WritevData(_, kHeaderLength, _, NO_FIN, _, _));
- }
- EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
- .WillOnce(Return(QuicConsumedData(kWindow - kHeaderLength, true)));
- EXPECT_CALL(*session_, SendBlocked(_));
- EXPECT_CALL(*connection_, SendControlFrame(_));
- stream_->WriteOrBufferBody(body, false);
-
- // Should have sent as much as possible, resulting in no send window left.
- EXPECT_EQ(0u, QuicStreamPeer::SendWindowSize(stream_));
-
- // And we should have queued the overflowed data.
- EXPECT_EQ(kOverflow + kHeaderLength, stream_->BufferedDataBytes());
-}
-
-// The flow control receive window decreases whenever we add new bytes to the
-// sequencer, whether they are consumed immediately or buffered. However we only
-// send WINDOW_UPDATE frames based on increasing number of bytes consumed.
-TEST_P(QuicSpdyStreamTest, StreamFlowControlNoWindowUpdateIfNotConsumed) {
- // Don't process data - it will be buffered instead.
- Initialize(!kShouldProcessData);
-
- // Expect no WINDOW_UPDATE frames to be sent.
- EXPECT_CALL(*session_, SendWindowUpdate(_, _)).Times(0);
-
- // Set a small flow control receive window.
- const uint64_t kWindow = 36;
- QuicStreamPeer::SetReceiveWindowOffset(stream_, kWindow);
- QuicStreamPeer::SetMaxReceiveWindow(stream_, kWindow);
-
- // Stream receives enough data to fill a fraction of the receive window.
- std::string body(kWindow / 3, 'a');
- QuicByteCount header_length = 0;
- std::string data;
-
- if (UsesHttp3()) {
- QuicBuffer header = HttpEncoder::SerializeDataFrameHeader(
- body.length(), SimpleBufferAllocator::Get());
- data = absl::StrCat(header.AsStringView(), body);
- header_length = header.size();
- } else {
- data = body;
- }
-
- ProcessHeaders(false, headers_);
-
- QuicStreamFrame frame1(GetNthClientInitiatedBidirectionalId(0), false, 0,
- absl::string_view(data));
- stream_->OnStreamFrame(frame1);
- EXPECT_EQ(kWindow - (kWindow / 3) - header_length,
- QuicStreamPeer::ReceiveWindowSize(stream_));
-
- // Now receive another frame which results in the receive window being over
- // half full. This should all be buffered, decreasing the receive window but
- // not sending WINDOW_UPDATE.
- QuicStreamFrame frame2(GetNthClientInitiatedBidirectionalId(0), false,
- kWindow / 3 + header_length, absl::string_view(data));
- stream_->OnStreamFrame(frame2);
- EXPECT_EQ(kWindow - (2 * kWindow / 3) - 2 * header_length,
- QuicStreamPeer::ReceiveWindowSize(stream_));
-}
-
-// Tests that on receipt of data, the stream updates its receive window offset
-// appropriately, and sends WINDOW_UPDATE frames when its receive window drops
-// too low.
-TEST_P(QuicSpdyStreamTest, StreamFlowControlWindowUpdate) {
- Initialize(kShouldProcessData);
-
- // Set a small flow control limit.
- const uint64_t kWindow = 36;
- QuicStreamPeer::SetReceiveWindowOffset(stream_, kWindow);
- QuicStreamPeer::SetMaxReceiveWindow(stream_, kWindow);
-
- // Stream receives enough data to fill a fraction of the receive window.
- std::string body(kWindow / 3, 'a');
- QuicByteCount header_length = 0;
- std::string data;
-
- if (UsesHttp3()) {
- QuicBuffer header = HttpEncoder::SerializeDataFrameHeader(
- body.length(), SimpleBufferAllocator::Get());
- data = absl::StrCat(header.AsStringView(), body);
- header_length = header.size();
- } else {
- data = body;
- }
-
- ProcessHeaders(false, headers_);
- stream_->ConsumeHeaderList();
-
- QuicStreamFrame frame1(GetNthClientInitiatedBidirectionalId(0), false, 0,
- absl::string_view(data));
- stream_->OnStreamFrame(frame1);
- EXPECT_EQ(kWindow - (kWindow / 3) - header_length,
- QuicStreamPeer::ReceiveWindowSize(stream_));
-
- // Now receive another frame which results in the receive window being over
- // half full. This will trigger the stream to increase its receive window
- // offset and send a WINDOW_UPDATE. The result will be again an available
- // window of kWindow bytes.
- QuicStreamFrame frame2(GetNthClientInitiatedBidirectionalId(0), false,
- kWindow / 3 + header_length, absl::string_view(data));
- EXPECT_CALL(*session_, SendWindowUpdate(_, _));
- EXPECT_CALL(*connection_, SendControlFrame(_));
- stream_->OnStreamFrame(frame2);
- EXPECT_EQ(kWindow, QuicStreamPeer::ReceiveWindowSize(stream_));
-}
-
-// Tests that on receipt of data, the connection updates its receive window
-// offset appropriately, and sends WINDOW_UPDATE frames when its receive window
-// drops too low.
-TEST_P(QuicSpdyStreamTest, ConnectionFlowControlWindowUpdate) {
- Initialize(kShouldProcessData);
-
- // Set a small flow control limit for streams and connection.
- const uint64_t kWindow = 36;
- QuicStreamPeer::SetReceiveWindowOffset(stream_, kWindow);
- QuicStreamPeer::SetMaxReceiveWindow(stream_, kWindow);
- QuicStreamPeer::SetReceiveWindowOffset(stream2_, kWindow);
- QuicStreamPeer::SetMaxReceiveWindow(stream2_, kWindow);
- QuicFlowControllerPeer::SetReceiveWindowOffset(session_->flow_controller(),
- kWindow);
- QuicFlowControllerPeer::SetMaxReceiveWindow(session_->flow_controller(),
- kWindow);
-
- // Supply headers to both streams so that they are happy to receive data.
- auto headers = AsHeaderList(headers_);
- stream_->OnStreamHeaderList(false, headers.uncompressed_header_bytes(),
- headers);
- stream_->ConsumeHeaderList();
- stream2_->OnStreamHeaderList(false, headers.uncompressed_header_bytes(),
- headers);
- stream2_->ConsumeHeaderList();
-
- // Each stream gets a quarter window of data. This should not trigger a
- // WINDOW_UPDATE for either stream, nor for the connection.
- QuicByteCount header_length = 0;
- std::string body;
- std::string data;
- std::string data2;
- std::string body2(1, 'a');
-
- if (UsesHttp3()) {
- body = std::string(kWindow / 4 - 2, 'a');
- QuicBuffer header = HttpEncoder::SerializeDataFrameHeader(
- body.length(), SimpleBufferAllocator::Get());
- data = absl::StrCat(header.AsStringView(), body);
- header_length = header.size();
- QuicBuffer header2 = HttpEncoder::SerializeDataFrameHeader(
- body.length(), SimpleBufferAllocator::Get());
- data2 = absl::StrCat(header2.AsStringView(), body2);
- } else {
- body = std::string(kWindow / 4, 'a');
- data = body;
- data2 = body2;
- }
-
- QuicStreamFrame frame1(GetNthClientInitiatedBidirectionalId(0), false, 0,
- absl::string_view(data));
- stream_->OnStreamFrame(frame1);
- QuicStreamFrame frame2(GetNthClientInitiatedBidirectionalId(1), false, 0,
- absl::string_view(data));
- stream2_->OnStreamFrame(frame2);
-
- // Now receive a further single byte on one stream - again this does not
- // trigger a stream WINDOW_UPDATE, but now the connection flow control window
- // is over half full and thus a connection WINDOW_UPDATE is sent.
- EXPECT_CALL(*session_, SendWindowUpdate(_, _));
- EXPECT_CALL(*connection_, SendControlFrame(_));
- QuicStreamFrame frame3(GetNthClientInitiatedBidirectionalId(0), false,
- body.length() + header_length,
- absl::string_view(data2));
- stream_->OnStreamFrame(frame3);
-}
-
-// Tests that on if the peer sends too much data (i.e. violates the flow control
-// protocol), then we terminate the connection.
-TEST_P(QuicSpdyStreamTest, StreamFlowControlViolation) {
- // Stream should not process data, so that data gets buffered in the
- // sequencer, triggering flow control limits.
- Initialize(!kShouldProcessData);
-
- // Set a small flow control limit.
- const uint64_t kWindow = 50;
- QuicStreamPeer::SetReceiveWindowOffset(stream_, kWindow);
-
- ProcessHeaders(false, headers_);
-
- // Receive data to overflow the window, violating flow control.
- std::string body(kWindow + 1, 'a');
- std::string data = UsesHttp3() ? DataFrame(body) : body;
- QuicStreamFrame frame(GetNthClientInitiatedBidirectionalId(0), false, 0,
- absl::string_view(data));
- EXPECT_CALL(*connection_,
- CloseConnection(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA, _, _));
- stream_->OnStreamFrame(frame);
-}
-
-TEST_P(QuicSpdyStreamTest, TestHandlingQuicRstStreamNoError) {
- Initialize(kShouldProcessData);
- ProcessHeaders(false, headers_);
-
- EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _)).Times(AnyNumber());
-
- stream_->OnStreamReset(QuicRstStreamFrame(
- kInvalidControlFrameId, stream_->id(), QUIC_STREAM_NO_ERROR, 0));
-
- if (GetQuicReloadableFlag(quic_fix_on_stream_reset) && UsesHttp3()) {
- // RESET_STREAM should close the read side but not the write side.
- EXPECT_TRUE(stream_->read_side_closed());
- EXPECT_FALSE(stream_->write_side_closed());
- } else {
- EXPECT_TRUE(stream_->write_side_closed());
- EXPECT_FALSE(stream_->reading_stopped());
- }
-}
-
-// Tests that on if the peer sends too much data (i.e. violates the flow control
-// protocol), at the connection level (rather than the stream level) then we
-// terminate the connection.
-TEST_P(QuicSpdyStreamTest, ConnectionFlowControlViolation) {
- // Stream should not process data, so that data gets buffered in the
- // sequencer, triggering flow control limits.
- Initialize(!kShouldProcessData);
-
- // Set a small flow control window on streams, and connection.
- const uint64_t kStreamWindow = 50;
- const uint64_t kConnectionWindow = 10;
- QuicStreamPeer::SetReceiveWindowOffset(stream_, kStreamWindow);
- QuicFlowControllerPeer::SetReceiveWindowOffset(session_->flow_controller(),
- kConnectionWindow);
-
- ProcessHeaders(false, headers_);
-
- // Send enough data to overflow the connection level flow control window.
- std::string body(kConnectionWindow + 1, 'a');
- std::string data = UsesHttp3() ? DataFrame(body) : body;
-
- EXPECT_LT(data.size(), kStreamWindow);
- QuicStreamFrame frame(GetNthClientInitiatedBidirectionalId(0), false, 0,
- absl::string_view(data));
-
- EXPECT_CALL(*connection_,
- CloseConnection(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA, _, _));
- stream_->OnStreamFrame(frame);
-}
-
-// An attempt to write a FIN with no data should not be flow control blocked,
-// even if the send window is 0.
-TEST_P(QuicSpdyStreamTest, StreamFlowControlFinNotBlocked) {
- Initialize(kShouldProcessData);
-
- // Set a flow control limit of zero.
- QuicStreamPeer::SetReceiveWindowOffset(stream_, 0);
-
- // Send a frame with a FIN but no data. This should not be blocked.
- std::string body = "";
- bool fin = true;
-
- EXPECT_CALL(*session_, SendBlocked(GetNthClientInitiatedBidirectionalId(0)))
- .Times(0);
- EXPECT_CALL(*session_, WritevData(_, 0, _, FIN, _, _));
-
- stream_->WriteOrBufferBody(body, fin);
-}
-
-// Test that receiving trailing headers from the peer via OnStreamHeaderList()
-// works, and can be read from the stream and consumed.
-TEST_P(QuicSpdyStreamTest, ReceivingTrailersViaHeaderList) {
- Initialize(kShouldProcessData);
-
- // Receive initial headers.
- size_t total_bytes = 0;
- QuicHeaderList headers;
- for (const auto& p : headers_) {
- headers.OnHeader(p.first, p.second);
- total_bytes += p.first.size() + p.second.size();
- }
-
- stream_->OnStreamHeadersPriority(
- spdy::SpdyStreamPrecedence(kV3HighestPriority));
- stream_->OnStreamHeaderList(/*fin=*/false, total_bytes, headers);
- stream_->ConsumeHeaderList();
-
- // Receive trailing headers.
- SpdyHeaderBlock trailers_block;
- trailers_block["key1"] = "value1";
- trailers_block["key2"] = "value2";
- trailers_block["key3"] = "value3";
- SpdyHeaderBlock trailers_block_with_final_offset = trailers_block.Clone();
- if (!UsesHttp3()) {
- // :final-offset pseudo-header is only added if trailers are sent
- // on the headers stream.
- trailers_block_with_final_offset[kFinalOffsetHeaderKey] = "0";
- }
- total_bytes = 0;
- QuicHeaderList trailers;
- for (const auto& p : trailers_block_with_final_offset) {
- trailers.OnHeader(p.first, p.second);
- total_bytes += p.first.size() + p.second.size();
- }
- stream_->OnStreamHeaderList(/*fin=*/true, total_bytes, trailers);
-
- // The trailers should be decompressed, and readable from the stream.
- EXPECT_TRUE(stream_->trailers_decompressed());
- EXPECT_EQ(trailers_block, stream_->received_trailers());
-
- // IsDoneReading() returns false until trailers marked consumed.
- EXPECT_FALSE(stream_->IsDoneReading());
- stream_->MarkTrailersConsumed();
- EXPECT_TRUE(stream_->IsDoneReading());
-}
-
-// Test that when receiving trailing headers with an offset before response
-// body, stream is closed at the right offset.
-TEST_P(QuicSpdyStreamTest, ReceivingTrailersWithOffset) {
- // kFinalOffsetHeaderKey is not used when HEADERS are sent on the
- // request/response stream.
- if (UsesHttp3()) {
- return;
- }
-
- Initialize(kShouldProcessData);
-
- // Receive initial headers.
- QuicHeaderList headers = ProcessHeaders(false, headers_);
- stream_->ConsumeHeaderList();
-
- const std::string body = "this is the body";
- std::string data = UsesHttp3() ? DataFrame(body) : body;
-
- // Receive trailing headers.
- SpdyHeaderBlock trailers_block;
- trailers_block["key1"] = "value1";
- trailers_block["key2"] = "value2";
- trailers_block["key3"] = "value3";
- trailers_block[kFinalOffsetHeaderKey] = absl::StrCat(data.size());
-
- QuicHeaderList trailers = ProcessHeaders(true, trailers_block);
-
- // The trailers should be decompressed, and readable from the stream.
- EXPECT_TRUE(stream_->trailers_decompressed());
-
- // The final offset trailer will be consumed by QUIC.
- trailers_block.erase(kFinalOffsetHeaderKey);
- EXPECT_EQ(trailers_block, stream_->received_trailers());
-
- // Consuming the trailers erases them from the stream.
- stream_->MarkTrailersConsumed();
- EXPECT_TRUE(stream_->FinishedReadingTrailers());
-
- EXPECT_FALSE(stream_->IsDoneReading());
- // Receive and consume body.
- QuicStreamFrame frame(GetNthClientInitiatedBidirectionalId(0), /*fin=*/false,
- 0, data);
- stream_->OnStreamFrame(frame);
- EXPECT_EQ(body, stream_->data());
- EXPECT_TRUE(stream_->IsDoneReading());
-}
-
-// Test that receiving trailers without a final offset field is an error.
-TEST_P(QuicSpdyStreamTest, ReceivingTrailersWithoutOffset) {
- // kFinalOffsetHeaderKey is not used when HEADERS are sent on the
- // request/response stream.
- if (UsesHttp3()) {
- return;
- }
-
- Initialize(kShouldProcessData);
-
- // Receive initial headers.
- ProcessHeaders(false, headers_);
- stream_->ConsumeHeaderList();
-
- // Receive trailing headers, without kFinalOffsetHeaderKey.
- SpdyHeaderBlock trailers_block;
- trailers_block["key1"] = "value1";
- trailers_block["key2"] = "value2";
- trailers_block["key3"] = "value3";
- auto trailers = AsHeaderList(trailers_block);
-
- // Verify that the trailers block didn't contain a final offset.
- EXPECT_EQ("", trailers_block[kFinalOffsetHeaderKey].as_string());
-
- // Receipt of the malformed trailers will close the connection.
- EXPECT_CALL(*connection_,
- CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA, _, _))
- .Times(1);
- stream_->OnStreamHeaderList(/*fin=*/true,
- trailers.uncompressed_header_bytes(), trailers);
-}
-
-// Test that received Trailers must always have the FIN set.
-TEST_P(QuicSpdyStreamTest, ReceivingTrailersWithoutFin) {
- // In IETF QUIC, there is no such thing as FIN flag on HTTP/3 frames like the
- // HEADERS frame.
- if (UsesHttp3()) {
- return;
- }
-
- Initialize(kShouldProcessData);
-
- // Receive initial headers.
- auto headers = AsHeaderList(headers_);
- stream_->OnStreamHeaderList(/*fin=*/false,
- headers.uncompressed_header_bytes(), headers);
- stream_->ConsumeHeaderList();
-
- // Receive trailing headers with FIN deliberately set to false.
- SpdyHeaderBlock trailers_block;
- trailers_block["foo"] = "bar";
- auto trailers = AsHeaderList(trailers_block);
-
- EXPECT_CALL(*connection_,
- CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA, _, _))
- .Times(1);
- stream_->OnStreamHeaderList(/*fin=*/false,
- trailers.uncompressed_header_bytes(), trailers);
-}
-
-TEST_P(QuicSpdyStreamTest, ReceivingTrailersAfterHeadersWithFin) {
- // If headers are received with a FIN, no trailers should then arrive.
- Initialize(kShouldProcessData);
-
- // If HEADERS frames are sent on the request/response stream, then the
- // sequencer will signal an error if any stream data arrives after a FIN,
- // so QuicSpdyStream does not need to.
- if (UsesHttp3()) {
- return;
- }
-
- // Receive initial headers with FIN set.
- ProcessHeaders(true, headers_);
- stream_->ConsumeHeaderList();
-
- // Receive trailing headers after FIN already received.
- SpdyHeaderBlock trailers_block;
- trailers_block["foo"] = "bar";
- EXPECT_CALL(*connection_,
- CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA, _, _))
- .Times(1);
- ProcessHeaders(true, trailers_block);
-}
-
-// If body data are received with a FIN, no trailers should then arrive.
-TEST_P(QuicSpdyStreamTest, ReceivingTrailersAfterBodyWithFin) {
- // If HEADERS frames are sent on the request/response stream,
- // then the sequencer will block them from reaching QuicSpdyStream
- // after the stream is closed.
- if (UsesHttp3()) {
- return;
- }
-
- Initialize(kShouldProcessData);
-
- // Receive initial headers without FIN set.
- ProcessHeaders(false, headers_);
- stream_->ConsumeHeaderList();
-
- // Receive body data, with FIN.
- QuicStreamFrame frame(GetNthClientInitiatedBidirectionalId(0), /*fin=*/true,
- 0, "body");
- stream_->OnStreamFrame(frame);
-
- // Receive trailing headers after FIN already received.
- SpdyHeaderBlock trailers_block;
- trailers_block["foo"] = "bar";
- EXPECT_CALL(*connection_,
- CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA, _, _))
- .Times(1);
- ProcessHeaders(true, trailers_block);
-}
-
-TEST_P(QuicSpdyStreamTest, ClosingStreamWithNoTrailers) {
- // Verify that a stream receiving headers, body, and no trailers is correctly
- // marked as done reading on consumption of headers and body.
- Initialize(kShouldProcessData);
-
- // Receive and consume initial headers with FIN not set.
- auto h = AsHeaderList(headers_);
- stream_->OnStreamHeaderList(/*fin=*/false, h.uncompressed_header_bytes(), h);
- stream_->ConsumeHeaderList();
-
- // Receive and consume body with FIN set, and no trailers.
- std::string body(1024, 'x');
- std::string data = UsesHttp3() ? DataFrame(body) : body;
-
- QuicStreamFrame frame(GetNthClientInitiatedBidirectionalId(0), /*fin=*/true,
- 0, data);
- stream_->OnStreamFrame(frame);
-
- EXPECT_TRUE(stream_->IsDoneReading());
-}
-
-// Test that writing trailers will send a FIN, as Trailers are the last thing to
-// be sent on a stream.
-TEST_P(QuicSpdyStreamTest, WritingTrailersSendsAFin) {
- Initialize(kShouldProcessData);
-
- if (UsesHttp3()) {
- // In this case, TestStream::WriteHeadersImpl() does not prevent writes.
- // Four writes on the request stream: HEADERS frame header and payload both
- // for headers and trailers.
- EXPECT_CALL(*session_, WritevData(stream_->id(), _, _, _, _, _)).Times(4);
- }
-
- // Write the initial headers, without a FIN.
- EXPECT_CALL(*stream_, WriteHeadersMock(false));
- stream_->WriteHeaders(SpdyHeaderBlock(), /*fin=*/false, nullptr);
-
- // Writing trailers implicitly sends a FIN.
- SpdyHeaderBlock trailers;
- trailers["trailer key"] = "trailer value";
- EXPECT_CALL(*stream_, WriteHeadersMock(true));
- stream_->WriteTrailers(std::move(trailers), nullptr);
- EXPECT_TRUE(stream_->fin_sent());
-}
-
-TEST_P(QuicSpdyStreamTest, DoNotSendPriorityUpdateWithDefaultUrgency) {
- if (!UsesHttp3()) {
- return;
- }
-
- InitializeWithPerspective(kShouldProcessData, Perspective::IS_CLIENT);
- StrictMock<MockHttp3DebugVisitor> debug_visitor;
- session_->set_debug_visitor(&debug_visitor);
-
- // Four writes on the request stream: HEADERS frame header and payload both
- // for headers and trailers.
- EXPECT_CALL(*session_, WritevData(stream_->id(), _, _, _, _, _)).Times(4);
-
- // No PRIORITY_UPDATE frames on the control stream,
- // because the stream has default priority.
- auto send_control_stream =
- QuicSpdySessionPeer::GetSendControlStream(session_.get());
- EXPECT_CALL(*session_, WritevData(send_control_stream->id(), _, _, _, _, _))
- .Times(0);
-
- // Write the initial headers, without a FIN.
- EXPECT_CALL(*stream_, WriteHeadersMock(false));
- EXPECT_CALL(debug_visitor, OnHeadersFrameSent(stream_->id(), _));
- stream_->WriteHeaders(SpdyHeaderBlock(), /*fin=*/false, nullptr);
-
- // Writing trailers implicitly sends a FIN.
- SpdyHeaderBlock trailers;
- trailers["trailer key"] = "trailer value";
- EXPECT_CALL(*stream_, WriteHeadersMock(true));
- EXPECT_CALL(debug_visitor, OnHeadersFrameSent(stream_->id(), _));
- stream_->WriteTrailers(std::move(trailers), nullptr);
- EXPECT_TRUE(stream_->fin_sent());
-}
-
-TEST_P(QuicSpdyStreamTest, ChangePriority) {
- if (!UsesHttp3()) {
- return;
- }
-
- InitializeWithPerspective(kShouldProcessData, Perspective::IS_CLIENT);
- StrictMock<MockHttp3DebugVisitor> debug_visitor;
- session_->set_debug_visitor(&debug_visitor);
-
- // Two writes on the request stream: HEADERS frame header and payload.
- EXPECT_CALL(*session_, WritevData(stream_->id(), _, _, _, _, _)).Times(2);
- EXPECT_CALL(*stream_, WriteHeadersMock(false));
- EXPECT_CALL(debug_visitor, OnHeadersFrameSent(stream_->id(), _));
- stream_->WriteHeaders(SpdyHeaderBlock(), /*fin=*/false, nullptr);
-
- // PRIORITY_UPDATE frame on the control stream.
- auto send_control_stream =
- QuicSpdySessionPeer::GetSendControlStream(session_.get());
- EXPECT_CALL(*session_, WritevData(send_control_stream->id(), _, _, _, _, _));
- PriorityUpdateFrame priority_update;
- priority_update.prioritized_element_id = 0;
- priority_update.priority_field_value = "u=0";
- EXPECT_CALL(debug_visitor, OnPriorityUpdateFrameSent(priority_update));
- stream_->SetPriority(spdy::SpdyStreamPrecedence(kV3HighestPriority));
-}
-
-TEST_P(QuicSpdyStreamTest, ChangePriorityBeforeWritingHeaders) {
- if (!UsesHttp3()) {
- return;
- }
-
- InitializeWithPerspective(kShouldProcessData, Perspective::IS_CLIENT);
-
- // PRIORITY_UPDATE frame sent on the control stream as soon as SetPriority()
- // is called, before HEADERS frame is sent.
- auto send_control_stream =
- QuicSpdySessionPeer::GetSendControlStream(session_.get());
- EXPECT_CALL(*session_, WritevData(send_control_stream->id(), _, _, _, _, _));
-
- stream_->SetPriority(spdy::SpdyStreamPrecedence(kV3HighestPriority));
- testing::Mock::VerifyAndClearExpectations(session_.get());
-
- // Two writes on the request stream: HEADERS frame header and payload.
- // PRIORITY_UPDATE frame is not sent this time, because one is already sent.
- EXPECT_CALL(*session_, WritevData(stream_->id(), _, _, _, _, _)).Times(2);
- EXPECT_CALL(*stream_, WriteHeadersMock(true));
- stream_->WriteHeaders(SpdyHeaderBlock(), /*fin=*/true, nullptr);
-}
-
-// Test that when writing trailers, the trailers that are actually sent to the
-// peer contain the final offset field indicating last byte of data.
-TEST_P(QuicSpdyStreamTest, WritingTrailersFinalOffset) {
- Initialize(kShouldProcessData);
-
- if (UsesHttp3()) {
- // In this case, TestStream::WriteHeadersImpl() does not prevent writes.
- // HEADERS frame header and payload on the request stream.
- EXPECT_CALL(*session_, WritevData(stream_->id(), _, _, _, _, _)).Times(2);
- }
-
- // Write the initial headers.
- EXPECT_CALL(*stream_, WriteHeadersMock(false));
- stream_->WriteHeaders(SpdyHeaderBlock(), /*fin=*/false, nullptr);
-
- // Write non-zero body data to force a non-zero final offset.
- EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _)).Times(AtLeast(1));
- std::string body(1024, 'x'); // 1 kB
- QuicByteCount header_length = 0;
- if (UsesHttp3()) {
- header_length = HttpEncoder::SerializeDataFrameHeader(
- body.length(), SimpleBufferAllocator::Get())
- .size();
- }
-
- stream_->WriteOrBufferBody(body, false);
-
- // The final offset field in the trailing headers is populated with the
- // number of body bytes written (including queued bytes).
- SpdyHeaderBlock trailers;
- trailers["trailer key"] = "trailer value";
-
- SpdyHeaderBlock expected_trailers(trailers.Clone());
- // :final-offset pseudo-header is only added if trailers are sent
- // on the headers stream.
- if (!UsesHttp3()) {
- expected_trailers[kFinalOffsetHeaderKey] =
- absl::StrCat(body.length() + header_length);
- }
-
- EXPECT_CALL(*stream_, WriteHeadersMock(true));
- stream_->WriteTrailers(std::move(trailers), nullptr);
- EXPECT_EQ(expected_trailers, stream_->saved_headers());
-}
-
-// Test that if trailers are written after all other data has been written
-// (headers and body), that this closes the stream for writing.
-TEST_P(QuicSpdyStreamTest, WritingTrailersClosesWriteSide) {
- Initialize(kShouldProcessData);
-
- // Expect data being written on the stream. In addition to that, headers are
- // also written on the stream in case of IETF QUIC.
- EXPECT_CALL(*session_, WritevData(stream_->id(), _, _, _, _, _))
- .Times(AtLeast(1));
-
- // Write the initial headers.
- EXPECT_CALL(*stream_, WriteHeadersMock(false));
- stream_->WriteHeaders(SpdyHeaderBlock(), /*fin=*/false, nullptr);
-
- // Write non-zero body data.
- const int kBodySize = 1 * 1024; // 1 kB
- stream_->WriteOrBufferBody(std::string(kBodySize, 'x'), false);
- EXPECT_EQ(0u, stream_->BufferedDataBytes());
-
- // Headers and body have been fully written, there is no queued data. Writing
- // trailers marks the end of this stream, and thus the write side is closed.
- EXPECT_CALL(*stream_, WriteHeadersMock(true));
- stream_->WriteTrailers(SpdyHeaderBlock(), nullptr);
- EXPECT_TRUE(stream_->write_side_closed());
-}
-
-// Test that the stream is not closed for writing when trailers are sent while
-// there are still body bytes queued.
-TEST_P(QuicSpdyStreamTest, WritingTrailersWithQueuedBytes) {
- // This test exercises sending trailers on the headers stream while data is
- // still queued on the response/request stream. In IETF QUIC, data and
- // trailers are sent on the same stream, so this test does not apply.
- if (UsesHttp3()) {
- return;
- }
-
- testing::InSequence seq;
- Initialize(kShouldProcessData);
-
- // Write the initial headers.
- EXPECT_CALL(*stream_, WriteHeadersMock(false));
- stream_->WriteHeaders(SpdyHeaderBlock(), /*fin=*/false, nullptr);
-
- // Write non-zero body data, but only consume partially, ensuring queueing.
- const int kBodySize = 1 * 1024; // 1 kB
- if (UsesHttp3()) {
- EXPECT_CALL(*session_, WritevData(_, 3, _, NO_FIN, _, _));
- }
- EXPECT_CALL(*session_, WritevData(_, kBodySize, _, NO_FIN, _, _))
- .WillOnce(Return(QuicConsumedData(kBodySize - 1, false)));
- stream_->WriteOrBufferBody(std::string(kBodySize, 'x'), false);
- EXPECT_EQ(1u, stream_->BufferedDataBytes());
-
- // Writing trailers will send a FIN, but not close the write side of the
- // stream as there are queued bytes.
- EXPECT_CALL(*stream_, WriteHeadersMock(true));
- stream_->WriteTrailers(SpdyHeaderBlock(), nullptr);
- EXPECT_TRUE(stream_->fin_sent());
- EXPECT_FALSE(stream_->write_side_closed());
-
- // Writing the queued bytes will close the write side of the stream.
- EXPECT_CALL(*session_, WritevData(_, 1, _, NO_FIN, _, _));
- stream_->OnCanWrite();
- EXPECT_TRUE(stream_->write_side_closed());
-}
-
-// Test that it is not possible to write Trailers after a FIN has been sent.
-TEST_P(QuicSpdyStreamTest, WritingTrailersAfterFIN) {
- // In IETF QUIC, there is no such thing as FIN flag on HTTP/3 frames like the
- // HEADERS frame.
- if (UsesHttp3()) {
- return;
- }
-
- Initialize(kShouldProcessData);
-
- // Write the initial headers, with a FIN.
- EXPECT_CALL(*stream_, WriteHeadersMock(true));
- stream_->WriteHeaders(SpdyHeaderBlock(), /*fin=*/true, nullptr);
- EXPECT_TRUE(stream_->fin_sent());
-
- // Writing Trailers should fail, as the FIN has already been sent.
- // populated with the number of body bytes written.
- EXPECT_QUIC_BUG(stream_->WriteTrailers(SpdyHeaderBlock(), nullptr),
- "Trailers cannot be sent after a FIN");
-}
-
-TEST_P(QuicSpdyStreamTest, HeaderStreamNotiferCorrespondingSpdyStream) {
- // There is no headers stream if QPACK is used.
- if (UsesHttp3()) {
- return;
- }
-
- const char kHeader1[] = "Header1";
- const char kHeader2[] = "Header2";
- const char kBody1[] = "Test1";
- const char kBody2[] = "Test2";
-
- Initialize(kShouldProcessData);
- EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _)).Times(AtLeast(1));
- testing::InSequence s;
- QuicReferenceCountedPointer<MockAckListener> ack_listener1(
- new MockAckListener());
- QuicReferenceCountedPointer<MockAckListener> ack_listener2(
- new MockAckListener());
- stream_->set_ack_listener(ack_listener1);
- stream2_->set_ack_listener(ack_listener2);
-
- session_->headers_stream()->WriteOrBufferData(kHeader1, false, ack_listener1);
- stream_->WriteOrBufferBody(kBody1, true);
-
- session_->headers_stream()->WriteOrBufferData(kHeader2, false, ack_listener2);
- stream2_->WriteOrBufferBody(kBody2, false);
-
- QuicStreamFrame frame1(
- QuicUtils::GetHeadersStreamId(connection_->transport_version()), false, 0,
- kHeader1);
-
- std::string data1 = UsesHttp3() ? DataFrame(kBody1) : kBody1;
- QuicStreamFrame frame2(stream_->id(), true, 0, data1);
- QuicStreamFrame frame3(
- QuicUtils::GetHeadersStreamId(connection_->transport_version()), false, 7,
- kHeader2);
- std::string data2 = UsesHttp3() ? DataFrame(kBody2) : kBody2;
- QuicStreamFrame frame4(stream2_->id(), false, 0, data2);
-
- EXPECT_CALL(*ack_listener1, OnPacketRetransmitted(7));
- session_->OnStreamFrameRetransmitted(frame1);
-
- EXPECT_CALL(*ack_listener1, OnPacketAcked(7, _));
- EXPECT_TRUE(session_->OnFrameAcked(QuicFrame(frame1), QuicTime::Delta::Zero(),
- QuicTime::Zero()));
- EXPECT_CALL(*ack_listener1, OnPacketAcked(5, _));
- EXPECT_TRUE(session_->OnFrameAcked(QuicFrame(frame2), QuicTime::Delta::Zero(),
- QuicTime::Zero()));
- EXPECT_CALL(*ack_listener2, OnPacketAcked(7, _));
- EXPECT_TRUE(session_->OnFrameAcked(QuicFrame(frame3), QuicTime::Delta::Zero(),
- QuicTime::Zero()));
- EXPECT_CALL(*ack_listener2, OnPacketAcked(5, _));
- EXPECT_TRUE(session_->OnFrameAcked(QuicFrame(frame4), QuicTime::Delta::Zero(),
- QuicTime::Zero()));
-}
-
-TEST_P(QuicSpdyStreamTest, OnPriorityFrame) {
- Initialize(kShouldProcessData);
- stream_->OnPriorityFrame(spdy::SpdyStreamPrecedence(kV3HighestPriority));
- EXPECT_EQ(spdy::SpdyStreamPrecedence(kV3HighestPriority),
- stream_->precedence());
-}
-
-TEST_P(QuicSpdyStreamTest, OnPriorityFrameAfterSendingData) {
- Initialize(kShouldProcessData);
- testing::InSequence seq;
-
- if (UsesHttp3()) {
- EXPECT_CALL(*session_, WritevData(_, 2, _, NO_FIN, _, _));
- }
- EXPECT_CALL(*session_, WritevData(_, 4, _, FIN, _, _));
- stream_->WriteOrBufferBody("data", true);
- stream_->OnPriorityFrame(spdy::SpdyStreamPrecedence(kV3HighestPriority));
- EXPECT_EQ(spdy::SpdyStreamPrecedence(kV3HighestPriority),
- stream_->precedence());
-}
-
-TEST_P(QuicSpdyStreamTest, SetPriorityBeforeUpdateStreamPriority) {
- MockQuicConnection* connection = new StrictMock<MockQuicConnection>(
- &helper_, &alarm_factory_, Perspective::IS_SERVER,
- SupportedVersions(GetParam()));
- std::unique_ptr<TestMockUpdateStreamSession> session(
- new StrictMock<TestMockUpdateStreamSession>(connection));
- auto stream =
- new StrictMock<TestStream>(GetNthClientInitiatedBidirectionalStreamId(
- session->transport_version(), 0),
- session.get(),
- /*should_process_data=*/true);
- session->ActivateStream(absl::WrapUnique(stream));
-
- // QuicSpdyStream::SetPriority() should eventually call UpdateStreamPriority()
- // on the session. Make sure stream->priority() returns the updated priority
- // if called within UpdateStreamPriority(). This expectation is enforced in
- // TestMockUpdateStreamSession::UpdateStreamPriority().
- session->SetExpectedStream(stream);
- session->SetExpectedPriority(spdy::SpdyStreamPrecedence(kV3HighestPriority));
- stream->SetPriority(spdy::SpdyStreamPrecedence(kV3HighestPriority));
-
- session->SetExpectedPriority(spdy::SpdyStreamPrecedence(kV3LowestPriority));
- stream->SetPriority(spdy::SpdyStreamPrecedence(kV3LowestPriority));
-}
-
-TEST_P(QuicSpdyStreamTest, StreamWaitsForAcks) {
- Initialize(kShouldProcessData);
- QuicReferenceCountedPointer<MockAckListener> mock_ack_listener(
- new StrictMock<MockAckListener>);
- stream_->set_ack_listener(mock_ack_listener);
- EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _)).Times(AtLeast(1));
- // Stream is not waiting for acks initially.
- EXPECT_FALSE(stream_->IsWaitingForAcks());
- EXPECT_EQ(0u, QuicStreamPeer::SendBuffer(stream_).size());
-
- // Send kData1.
- stream_->WriteOrBufferData("FooAndBar", false, nullptr);
- EXPECT_EQ(1u, QuicStreamPeer::SendBuffer(stream_).size());
- EXPECT_TRUE(stream_->IsWaitingForAcks());
- EXPECT_CALL(*mock_ack_listener, OnPacketAcked(9, _));
- QuicByteCount newly_acked_length = 0;
- EXPECT_TRUE(stream_->OnStreamFrameAcked(0, 9, false, QuicTime::Delta::Zero(),
- QuicTime::Zero(),
- &newly_acked_length));
- // Stream is not waiting for acks as all sent data is acked.
- EXPECT_FALSE(stream_->IsWaitingForAcks());
- EXPECT_EQ(0u, QuicStreamPeer::SendBuffer(stream_).size());
-
- // Send kData2.
- stream_->WriteOrBufferData("FooAndBar", false, nullptr);
- EXPECT_TRUE(stream_->IsWaitingForAcks());
- EXPECT_EQ(1u, QuicStreamPeer::SendBuffer(stream_).size());
- // Send FIN.
- stream_->WriteOrBufferData("", true, nullptr);
- // Fin only frame is not stored in send buffer.
- EXPECT_EQ(1u, QuicStreamPeer::SendBuffer(stream_).size());
-
- // kData2 is retransmitted.
- EXPECT_CALL(*mock_ack_listener, OnPacketRetransmitted(9));
- stream_->OnStreamFrameRetransmitted(9, 9, false);
-
- // kData2 is acked.
- EXPECT_CALL(*mock_ack_listener, OnPacketAcked(9, _));
- EXPECT_TRUE(stream_->OnStreamFrameAcked(9, 9, false, QuicTime::Delta::Zero(),
- QuicTime::Zero(),
- &newly_acked_length));
- // Stream is waiting for acks as FIN is not acked.
- EXPECT_TRUE(stream_->IsWaitingForAcks());
- EXPECT_EQ(0u, QuicStreamPeer::SendBuffer(stream_).size());
-
- // FIN is acked.
- EXPECT_CALL(*mock_ack_listener, OnPacketAcked(0, _));
- EXPECT_TRUE(stream_->OnStreamFrameAcked(18, 0, true, QuicTime::Delta::Zero(),
- QuicTime::Zero(),
- &newly_acked_length));
- EXPECT_FALSE(stream_->IsWaitingForAcks());
- EXPECT_EQ(0u, QuicStreamPeer::SendBuffer(stream_).size());
-}
-
-TEST_P(QuicSpdyStreamTest, StreamDataGetAckedMultipleTimes) {
- Initialize(kShouldProcessData);
- QuicReferenceCountedPointer<MockAckListener> mock_ack_listener(
- new StrictMock<MockAckListener>);
- stream_->set_ack_listener(mock_ack_listener);
- EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _)).Times(AtLeast(1));
- // Send [0, 27) and fin.
- stream_->WriteOrBufferData("FooAndBar", false, nullptr);
- stream_->WriteOrBufferData("FooAndBar", false, nullptr);
- stream_->WriteOrBufferData("FooAndBar", true, nullptr);
-
- // Ack [0, 9), [5, 22) and [18, 26)
- // Verify [0, 9) 9 bytes are acked.
- QuicByteCount newly_acked_length = 0;
- EXPECT_CALL(*mock_ack_listener, OnPacketAcked(9, _));
- EXPECT_TRUE(stream_->OnStreamFrameAcked(0, 9, false, QuicTime::Delta::Zero(),
- QuicTime::Zero(),
- &newly_acked_length));
- EXPECT_EQ(2u, QuicStreamPeer::SendBuffer(stream_).size());
- // Verify [9, 22) 13 bytes are acked.
- EXPECT_CALL(*mock_ack_listener, OnPacketAcked(13, _));
- EXPECT_TRUE(stream_->OnStreamFrameAcked(5, 17, false, QuicTime::Delta::Zero(),
- QuicTime::Zero(),
- &newly_acked_length));
- EXPECT_EQ(1u, QuicStreamPeer::SendBuffer(stream_).size());
- // Verify [22, 26) 4 bytes are acked.
- EXPECT_CALL(*mock_ack_listener, OnPacketAcked(4, _));
- EXPECT_TRUE(stream_->OnStreamFrameAcked(18, 8, false, QuicTime::Delta::Zero(),
- QuicTime::Zero(),
- &newly_acked_length));
- EXPECT_EQ(1u, QuicStreamPeer::SendBuffer(stream_).size());
- EXPECT_TRUE(stream_->IsWaitingForAcks());
-
- // Ack [0, 27).
- // Verify [26, 27) 1 byte is acked.
- EXPECT_CALL(*mock_ack_listener, OnPacketAcked(1, _));
- EXPECT_TRUE(stream_->OnStreamFrameAcked(26, 1, false, QuicTime::Delta::Zero(),
- QuicTime::Zero(),
- &newly_acked_length));
- EXPECT_EQ(0u, QuicStreamPeer::SendBuffer(stream_).size());
- EXPECT_TRUE(stream_->IsWaitingForAcks());
-
- // Ack Fin. Verify OnPacketAcked is called.
- EXPECT_CALL(*mock_ack_listener, OnPacketAcked(0, _));
- EXPECT_TRUE(stream_->OnStreamFrameAcked(27, 0, true, QuicTime::Delta::Zero(),
- QuicTime::Zero(),
- &newly_acked_length));
- EXPECT_EQ(0u, QuicStreamPeer::SendBuffer(stream_).size());
- EXPECT_FALSE(stream_->IsWaitingForAcks());
-
- // Ack [10, 27) and fin.
- // No new data is acked, verify OnPacketAcked is not called.
- EXPECT_CALL(*mock_ack_listener, OnPacketAcked(_, _)).Times(0);
- EXPECT_FALSE(
- stream_->OnStreamFrameAcked(10, 17, true, QuicTime::Delta::Zero(),
- QuicTime::Zero(), &newly_acked_length));
- EXPECT_EQ(0u, QuicStreamPeer::SendBuffer(stream_).size());
- EXPECT_FALSE(stream_->IsWaitingForAcks());
-}
-
-// HTTP/3 only.
-TEST_P(QuicSpdyStreamTest, HeadersAckNotReportedWriteOrBufferBody) {
- if (!UsesHttp3()) {
- return;
- }
-
- Initialize(kShouldProcessData);
- QuicReferenceCountedPointer<MockAckListener> mock_ack_listener(
- new StrictMock<MockAckListener>);
- stream_->set_ack_listener(mock_ack_listener);
- std::string body = "Test1";
- std::string body2(100, 'x');
-
- EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _)).Times(AtLeast(1));
- stream_->WriteOrBufferBody(body, false);
- stream_->WriteOrBufferBody(body2, true);
-
- QuicBuffer header = HttpEncoder::SerializeDataFrameHeader(
- body.length(), SimpleBufferAllocator::Get());
- QuicBuffer header2 = HttpEncoder::SerializeDataFrameHeader(
- body2.length(), SimpleBufferAllocator::Get());
-
- EXPECT_CALL(*mock_ack_listener, OnPacketAcked(body.length(), _));
- QuicStreamFrame frame(stream_->id(), false, 0,
- absl::StrCat(header.AsStringView(), body));
- EXPECT_TRUE(session_->OnFrameAcked(QuicFrame(frame), QuicTime::Delta::Zero(),
- QuicTime::Zero()));
-
- EXPECT_CALL(*mock_ack_listener, OnPacketAcked(0, _));
- QuicStreamFrame frame2(stream_->id(), false, header.size() + body.length(),
- header2.AsStringView());
- EXPECT_TRUE(session_->OnFrameAcked(QuicFrame(frame2), QuicTime::Delta::Zero(),
- QuicTime::Zero()));
-
- EXPECT_CALL(*mock_ack_listener, OnPacketAcked(body2.length(), _));
- QuicStreamFrame frame3(stream_->id(), true,
- header.size() + body.length() + header2.size(), body2);
- EXPECT_TRUE(session_->OnFrameAcked(QuicFrame(frame3), QuicTime::Delta::Zero(),
- QuicTime::Zero()));
-
- EXPECT_TRUE(
- QuicSpdyStreamPeer::unacked_frame_headers_offsets(stream_).Empty());
-}
-
-// HTTP/3 only.
-TEST_P(QuicSpdyStreamTest, HeadersAckNotReportedWriteBodySlices) {
- if (!UsesHttp3()) {
- return;
- }
-
- Initialize(kShouldProcessData);
- QuicReferenceCountedPointer<MockAckListener> mock_ack_listener(
- new StrictMock<MockAckListener>);
- stream_->set_ack_listener(mock_ack_listener);
- std::string body1 = "Test1";
- std::string body2(100, 'x');
- struct iovec body1_iov = {const_cast<char*>(body1.data()), body1.length()};
- struct iovec body2_iov = {const_cast<char*>(body2.data()), body2.length()};
- QuicMemSliceStorage storage(&body1_iov, 1,
- helper_.GetStreamSendBufferAllocator(), 1024);
- QuicMemSliceStorage storage2(&body2_iov, 1,
- helper_.GetStreamSendBufferAllocator(), 1024);
- EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _)).Times(AtLeast(1));
- stream_->WriteBodySlices(storage.ToSpan(), false);
- stream_->WriteBodySlices(storage2.ToSpan(), true);
-
- std::string data1 = DataFrame(body1);
- std::string data2 = DataFrame(body2);
-
- EXPECT_CALL(*mock_ack_listener,
- OnPacketAcked(body1.length() + body2.length(), _));
- QuicStreamFrame frame(stream_->id(), true, 0, data1 + data2);
- EXPECT_TRUE(session_->OnFrameAcked(QuicFrame(frame), QuicTime::Delta::Zero(),
- QuicTime::Zero()));
-
- EXPECT_TRUE(
- QuicSpdyStreamPeer::unacked_frame_headers_offsets(stream_).Empty());
-}
-
-// HTTP/3 only.
-TEST_P(QuicSpdyStreamTest, HeaderBytesNotReportedOnRetransmission) {
- if (!UsesHttp3()) {
- return;
- }
-
- Initialize(kShouldProcessData);
- QuicReferenceCountedPointer<MockAckListener> mock_ack_listener(
- new StrictMock<MockAckListener>);
- stream_->set_ack_listener(mock_ack_listener);
- std::string body1 = "Test1";
- std::string body2(100, 'x');
-
- EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _)).Times(AtLeast(1));
- stream_->WriteOrBufferBody(body1, false);
- stream_->WriteOrBufferBody(body2, true);
-
- std::string data1 = DataFrame(body1);
- std::string data2 = DataFrame(body2);
-
- EXPECT_CALL(*mock_ack_listener, OnPacketRetransmitted(body1.length()));
- QuicStreamFrame frame(stream_->id(), false, 0, data1);
- session_->OnStreamFrameRetransmitted(frame);
-
- EXPECT_CALL(*mock_ack_listener, OnPacketRetransmitted(body2.length()));
- QuicStreamFrame frame2(stream_->id(), true, data1.length(), data2);
- session_->OnStreamFrameRetransmitted(frame2);
-
- EXPECT_FALSE(
- QuicSpdyStreamPeer::unacked_frame_headers_offsets(stream_).Empty());
-}
-
-TEST_P(QuicSpdyStreamTest, HeadersFrameOnRequestStream) {
- if (!UsesHttp3()) {
- return;
- }
-
- Initialize(kShouldProcessData);
-
- std::string headers = HeadersFrame({std::make_pair("foo", "bar")});
- std::string data = DataFrame(kDataFramePayload);
- std::string trailers =
- HeadersFrame({std::make_pair("custom-key", "custom-value")});
-
- std::string stream_frame_payload = absl::StrCat(headers, data, trailers);
- QuicStreamFrame frame(stream_->id(), false, 0, stream_frame_payload);
- stream_->OnStreamFrame(frame);
-
- EXPECT_THAT(stream_->header_list(), ElementsAre(Pair("foo", "bar")));
-
- // QuicSpdyStream only calls OnBodyAvailable()
- // after the header list has been consumed.
- EXPECT_EQ("", stream_->data());
- stream_->ConsumeHeaderList();
- EXPECT_EQ(kDataFramePayload, stream_->data());
-
- EXPECT_THAT(stream_->received_trailers(),
- ElementsAre(Pair("custom-key", "custom-value")));
-}
-
-TEST_P(QuicSpdyStreamTest, ProcessBodyAfterTrailers) {
- if (!UsesHttp3()) {
- return;
- }
-
- Initialize(!kShouldProcessData);
-
- std::string headers = HeadersFrame({std::make_pair("foo", "bar")});
- std::string data = DataFrame(kDataFramePayload);
-
- // A header block that will take more than one block of sequencer buffer.
- // This ensures that when the trailers are consumed, some buffer buckets will
- // be freed.
- SpdyHeaderBlock trailers_block;
- trailers_block["key1"] = std::string(10000, 'x');
- std::string trailers = HeadersFrame(trailers_block);
-
- // Feed all three HTTP/3 frames in a single stream frame.
- std::string stream_frame_payload = absl::StrCat(headers, data, trailers);
- QuicStreamFrame frame(stream_->id(), false, 0, stream_frame_payload);
- stream_->OnStreamFrame(frame);
-
- stream_->ConsumeHeaderList();
- stream_->MarkTrailersConsumed();
-
- EXPECT_TRUE(stream_->trailers_decompressed());
- EXPECT_EQ(trailers_block, stream_->received_trailers());
-
- EXPECT_TRUE(stream_->HasBytesToRead());
-
- // Consume data.
- char buffer[2048];
- struct iovec vec;
- vec.iov_base = buffer;
- vec.iov_len = ABSL_ARRAYSIZE(buffer);
- size_t bytes_read = stream_->Readv(&vec, 1);
- EXPECT_EQ(kDataFramePayload, absl::string_view(buffer, bytes_read));
-
- EXPECT_FALSE(stream_->HasBytesToRead());
-}
-
-// The test stream will receive a stream frame containing malformed headers and
-// normal body. Make sure the http decoder stops processing body after the
-// connection shuts down.
-TEST_P(QuicSpdyStreamTest, MalformedHeadersStopHttpDecoder) {
- if (!UsesHttp3()) {
- return;
- }
-
- Initialize(kShouldProcessData);
- testing::InSequence s;
- connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
-
- // Random bad headers.
- std::string headers =
- HeadersFrame(absl::HexStringToBytes("00002a94e7036261"));
- std::string data = DataFrame(kDataFramePayload);
-
- std::string stream_frame_payload = absl::StrCat(headers, data);
- QuicStreamFrame frame(stream_->id(), false, 0, stream_frame_payload);
-
- EXPECT_CALL(
- *connection_,
- CloseConnection(QUIC_QPACK_DECOMPRESSION_FAILED,
- MatchesRegex("Error decoding headers on stream \\d+: "
- "Incomplete header block."),
- _))
- .WillOnce(
- (Invoke([this](QuicErrorCode error, const std::string& error_details,
- ConnectionCloseBehavior connection_close_behavior) {
- connection_->ReallyCloseConnection(error, error_details,
- connection_close_behavior);
- })));
- EXPECT_CALL(*connection_, SendConnectionClosePacket(_, _, _));
- EXPECT_CALL(*session_, OnConnectionClosed(_, _))
- .WillOnce(Invoke([this](const QuicConnectionCloseFrame& frame,
- ConnectionCloseSource source) {
- session_->ReallyOnConnectionClosed(frame, source);
- }));
- EXPECT_CALL(*session_, MaybeSendRstStreamFrame(_, _, _)).Times(2);
- stream_->OnStreamFrame(frame);
-}
-
-// Regression test for https://crbug.com/1027895: a HEADERS frame triggers an
-// error in QuicSpdyStream::OnHeadersFramePayload(). This closes the
-// connection, freeing the buffer of QuicStreamSequencer. Therefore
-// QuicStreamSequencer::MarkConsumed() must not be called from
-// QuicSpdyStream::OnHeadersFramePayload().
-TEST_P(QuicSpdyStreamTest, DoNotMarkConsumedAfterQpackDecodingError) {
- if (!UsesHttp3()) {
- return;
- }
-
- Initialize(kShouldProcessData);
- connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
-
- {
- testing::InSequence s;
- EXPECT_CALL(
- *connection_,
- CloseConnection(QUIC_QPACK_DECOMPRESSION_FAILED,
- MatchesRegex("Error decoding headers on stream \\d+: "
- "Invalid relative index."),
- _))
- .WillOnce((
- Invoke([this](QuicErrorCode error, const std::string& error_details,
- ConnectionCloseBehavior connection_close_behavior) {
- connection_->ReallyCloseConnection(error, error_details,
- connection_close_behavior);
- })));
- EXPECT_CALL(*connection_, SendConnectionClosePacket(_, _, _));
- EXPECT_CALL(*session_, OnConnectionClosed(_, _))
- .WillOnce(Invoke([this](const QuicConnectionCloseFrame& frame,
- ConnectionCloseSource source) {
- session_->ReallyOnConnectionClosed(frame, source);
- }));
- }
- EXPECT_CALL(*session_, MaybeSendRstStreamFrame(stream_->id(), _, _));
- EXPECT_CALL(*session_, MaybeSendRstStreamFrame(stream2_->id(), _, _));
-
- // Invalid headers: Required Insert Count is zero, but the header block
- // contains a dynamic table reference.
- std::string headers = HeadersFrame(absl::HexStringToBytes("000080"));
- QuicStreamFrame frame(stream_->id(), false, 0, headers);
- stream_->OnStreamFrame(frame);
-}
-
-TEST_P(QuicSpdyStreamTest, ImmediateHeaderDecodingWithDynamicTableEntries) {
- if (!UsesHttp3()) {
- return;
- }
-
- Initialize(kShouldProcessData);
- testing::InSequence s;
- session_->qpack_decoder()->OnSetDynamicTableCapacity(1024);
- StrictMock<MockHttp3DebugVisitor> debug_visitor;
- session_->set_debug_visitor(&debug_visitor);
-
- auto decoder_send_stream =
- QuicSpdySessionPeer::GetQpackDecoderSendStream(session_.get());
-
- // Deliver dynamic table entry to decoder.
- session_->qpack_decoder()->OnInsertWithoutNameReference("foo", "bar");
-
- // HEADERS frame referencing first dynamic table entry.
- std::string encoded_headers = absl::HexStringToBytes("020080");
- std::string headers = HeadersFrame(encoded_headers);
- EXPECT_CALL(debug_visitor,
- OnHeadersFrameReceived(stream_->id(), encoded_headers.length()));
- // Decoder stream type.
- EXPECT_CALL(*session_,
- WritevData(decoder_send_stream->id(), /* write_length = */ 1,
- /* offset = */ 0, _, _, _));
- // Header acknowledgement.
- EXPECT_CALL(*session_,
- WritevData(decoder_send_stream->id(), /* write_length = */ 1,
- /* offset = */ 1, _, _, _));
- EXPECT_CALL(debug_visitor, OnHeadersDecoded(stream_->id(), _));
- stream_->OnStreamFrame(QuicStreamFrame(stream_->id(), false, 0, headers));
-
- // Headers can be decoded immediately.
- EXPECT_TRUE(stream_->headers_decompressed());
-
- // Verify headers.
- EXPECT_THAT(stream_->header_list(), ElementsAre(Pair("foo", "bar")));
- stream_->ConsumeHeaderList();
-
- // DATA frame.
- std::string data = DataFrame(kDataFramePayload);
- EXPECT_CALL(debug_visitor,
- OnDataFrameReceived(stream_->id(), strlen(kDataFramePayload)));
- stream_->OnStreamFrame(QuicStreamFrame(stream_->id(), false, /* offset = */
- headers.length(), data));
- EXPECT_EQ(kDataFramePayload, stream_->data());
-
- // Deliver second dynamic table entry to decoder.
- session_->qpack_decoder()->OnInsertWithoutNameReference("trailing", "foobar");
-
- // Trailing HEADERS frame referencing second dynamic table entry.
- std::string encoded_trailers = absl::HexStringToBytes("030080");
- std::string trailers = HeadersFrame(encoded_trailers);
- EXPECT_CALL(debug_visitor,
- OnHeadersFrameReceived(stream_->id(), encoded_trailers.length()));
- // Header acknowledgement.
- EXPECT_CALL(*session_, WritevData(decoder_send_stream->id(), _, _, _, _, _));
- EXPECT_CALL(debug_visitor, OnHeadersDecoded(stream_->id(), _));
- stream_->OnStreamFrame(QuicStreamFrame(stream_->id(), true, /* offset = */
- headers.length() + data.length(),
- trailers));
-
- // Trailers can be decoded immediately.
- EXPECT_TRUE(stream_->trailers_decompressed());
-
- // Verify trailers.
- EXPECT_THAT(stream_->received_trailers(),
- ElementsAre(Pair("trailing", "foobar")));
- stream_->MarkTrailersConsumed();
-}
-
-TEST_P(QuicSpdyStreamTest, BlockedHeaderDecoding) {
- if (!UsesHttp3()) {
- return;
- }
-
- Initialize(kShouldProcessData);
- testing::InSequence s;
- session_->qpack_decoder()->OnSetDynamicTableCapacity(1024);
- StrictMock<MockHttp3DebugVisitor> debug_visitor;
- session_->set_debug_visitor(&debug_visitor);
-
- // HEADERS frame referencing first dynamic table entry.
- std::string encoded_headers = absl::HexStringToBytes("020080");
- std::string headers = HeadersFrame(encoded_headers);
- EXPECT_CALL(debug_visitor,
- OnHeadersFrameReceived(stream_->id(), encoded_headers.length()));
- stream_->OnStreamFrame(QuicStreamFrame(stream_->id(), false, 0, headers));
-
- // Decoding is blocked because dynamic table entry has not been received yet.
- EXPECT_FALSE(stream_->headers_decompressed());
-
- auto decoder_send_stream =
- QuicSpdySessionPeer::GetQpackDecoderSendStream(session_.get());
-
- // Decoder stream type.
- EXPECT_CALL(*session_,
- WritevData(decoder_send_stream->id(), /* write_length = */ 1,
- /* offset = */ 0, _, _, _));
- // Header acknowledgement.
- EXPECT_CALL(*session_,
- WritevData(decoder_send_stream->id(), /* write_length = */ 1,
- /* offset = */ 1, _, _, _));
- EXPECT_CALL(debug_visitor, OnHeadersDecoded(stream_->id(), _));
- // Deliver dynamic table entry to decoder.
- session_->qpack_decoder()->OnInsertWithoutNameReference("foo", "bar");
- EXPECT_TRUE(stream_->headers_decompressed());
-
- // Verify headers.
- EXPECT_THAT(stream_->header_list(), ElementsAre(Pair("foo", "bar")));
- stream_->ConsumeHeaderList();
-
- // DATA frame.
- std::string data = DataFrame(kDataFramePayload);
- EXPECT_CALL(debug_visitor,
- OnDataFrameReceived(stream_->id(), strlen(kDataFramePayload)));
- stream_->OnStreamFrame(QuicStreamFrame(stream_->id(), false, /* offset = */
- headers.length(), data));
- EXPECT_EQ(kDataFramePayload, stream_->data());
-
- // Trailing HEADERS frame referencing second dynamic table entry.
- std::string encoded_trailers = absl::HexStringToBytes("030080");
- std::string trailers = HeadersFrame(encoded_trailers);
- EXPECT_CALL(debug_visitor,
- OnHeadersFrameReceived(stream_->id(), encoded_trailers.length()));
- stream_->OnStreamFrame(QuicStreamFrame(stream_->id(), true, /* offset = */
- headers.length() + data.length(),
- trailers));
-
- // Decoding is blocked because dynamic table entry has not been received yet.
- EXPECT_FALSE(stream_->trailers_decompressed());
-
- // Header acknowledgement.
- EXPECT_CALL(*session_, WritevData(decoder_send_stream->id(), _, _, _, _, _));
- EXPECT_CALL(debug_visitor, OnHeadersDecoded(stream_->id(), _));
- // Deliver second dynamic table entry to decoder.
- session_->qpack_decoder()->OnInsertWithoutNameReference("trailing", "foobar");
- EXPECT_TRUE(stream_->trailers_decompressed());
-
- // Verify trailers.
- EXPECT_THAT(stream_->received_trailers(),
- ElementsAre(Pair("trailing", "foobar")));
- stream_->MarkTrailersConsumed();
-}
-
-TEST_P(QuicSpdyStreamTest, AsyncErrorDecodingHeaders) {
- if (!UsesHttp3()) {
- return;
- }
-
- Initialize(kShouldProcessData);
- session_->qpack_decoder()->OnSetDynamicTableCapacity(1024);
-
- // HEADERS frame only referencing entry with absolute index 0 but with
- // Required Insert Count = 2, which is incorrect.
- std::string headers = HeadersFrame(absl::HexStringToBytes("030081"));
- stream_->OnStreamFrame(QuicStreamFrame(stream_->id(), false, 0, headers));
-
- // Even though entire header block is received and every referenced entry is
- // available, decoding is blocked until insert count reaches the Required
- // Insert Count value advertised in the header block prefix.
- EXPECT_FALSE(stream_->headers_decompressed());
-
- EXPECT_CALL(
- *connection_,
- CloseConnection(QUIC_QPACK_DECOMPRESSION_FAILED,
- MatchesRegex("Error decoding headers on stream \\d+: "
- "Required Insert Count too large."),
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET));
-
- // Deliver two dynamic table entries to decoder
- // to trigger decoding of header block.
- session_->qpack_decoder()->OnInsertWithoutNameReference("foo", "bar");
- session_->qpack_decoder()->OnInsertWithoutNameReference("foo", "bar");
-}
-
-// Regression test for https://crbug.com/1024263 and for
-// https://crbug.com/1025209#c11.
-TEST_P(QuicSpdyStreamTest, BlockedHeaderDecodingUnblockedWithBufferedError) {
- if (!UsesHttp3()) {
- return;
- }
-
- Initialize(kShouldProcessData);
- session_->qpack_decoder()->OnSetDynamicTableCapacity(1024);
-
- // Relative index 2 is invalid because it is larger than or equal to the Base.
- std::string headers = HeadersFrame(absl::HexStringToBytes("020082"));
- stream_->OnStreamFrame(QuicStreamFrame(stream_->id(), false, 0, headers));
-
- // Decoding is blocked.
- EXPECT_FALSE(stream_->headers_decompressed());
-
- EXPECT_CALL(
- *connection_,
- CloseConnection(QUIC_QPACK_DECOMPRESSION_FAILED,
- MatchesRegex("Error decoding headers on stream \\d+: "
- "Invalid relative index."),
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET));
-
- // Deliver one dynamic table entry to decoder
- // to trigger decoding of header block.
- session_->qpack_decoder()->OnInsertWithoutNameReference("foo", "bar");
-}
-
-TEST_P(QuicSpdyStreamTest, AsyncErrorDecodingTrailers) {
- if (!UsesHttp3()) {
- return;
- }
-
- Initialize(kShouldProcessData);
- testing::InSequence s;
- session_->qpack_decoder()->OnSetDynamicTableCapacity(1024);
-
- // HEADERS frame referencing first dynamic table entry.
- std::string headers = HeadersFrame(absl::HexStringToBytes("020080"));
- stream_->OnStreamFrame(QuicStreamFrame(stream_->id(), false, 0, headers));
-
- // Decoding is blocked because dynamic table entry has not been received yet.
- EXPECT_FALSE(stream_->headers_decompressed());
-
- auto decoder_send_stream =
- QuicSpdySessionPeer::GetQpackDecoderSendStream(session_.get());
-
- // Decoder stream type.
- EXPECT_CALL(*session_,
- WritevData(decoder_send_stream->id(), /* write_length = */ 1,
- /* offset = */ 0, _, _, _));
- // Header acknowledgement.
- EXPECT_CALL(*session_,
- WritevData(decoder_send_stream->id(), /* write_length = */ 1,
- /* offset = */ 1, _, _, _));
- // Deliver dynamic table entry to decoder.
- session_->qpack_decoder()->OnInsertWithoutNameReference("foo", "bar");
- EXPECT_TRUE(stream_->headers_decompressed());
-
- // Verify headers.
- EXPECT_THAT(stream_->header_list(), ElementsAre(Pair("foo", "bar")));
- stream_->ConsumeHeaderList();
-
- // DATA frame.
- std::string data = DataFrame(kDataFramePayload);
- stream_->OnStreamFrame(QuicStreamFrame(stream_->id(), false, /* offset = */
- headers.length(), data));
- EXPECT_EQ(kDataFramePayload, stream_->data());
-
- // Trailing HEADERS frame only referencing entry with absolute index 0 but
- // with Required Insert Count = 2, which is incorrect.
- std::string trailers = HeadersFrame(absl::HexStringToBytes("030081"));
- stream_->OnStreamFrame(QuicStreamFrame(stream_->id(), true, /* offset = */
- headers.length() + data.length(),
- trailers));
-
- // Even though entire header block is received and every referenced entry is
- // available, decoding is blocked until insert count reaches the Required
- // Insert Count value advertised in the header block prefix.
- EXPECT_FALSE(stream_->trailers_decompressed());
-
- EXPECT_CALL(
- *connection_,
- CloseConnection(QUIC_QPACK_DECOMPRESSION_FAILED,
- MatchesRegex("Error decoding trailers on stream \\d+: "
- "Required Insert Count too large."),
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET));
-
- // Deliver second dynamic table entry to decoder
- // to trigger decoding of trailing header block.
- session_->qpack_decoder()->OnInsertWithoutNameReference("trailing", "foobar");
-}
-
-// Regression test for b/132603592: QPACK decoding unblocked after stream is
-// closed.
-TEST_P(QuicSpdyStreamTest, HeaderDecodingUnblockedAfterStreamClosed) {
- if (!UsesHttp3()) {
- return;
- }
-
- Initialize(kShouldProcessData);
- testing::InSequence s;
- session_->qpack_decoder()->OnSetDynamicTableCapacity(1024);
- StrictMock<MockHttp3DebugVisitor> debug_visitor;
- session_->set_debug_visitor(&debug_visitor);
-
- // HEADERS frame referencing first dynamic table entry.
- std::string encoded_headers = absl::HexStringToBytes("020080");
- std::string headers = HeadersFrame(encoded_headers);
- EXPECT_CALL(debug_visitor,
- OnHeadersFrameReceived(stream_->id(), encoded_headers.length()));
- stream_->OnStreamFrame(QuicStreamFrame(stream_->id(), false, 0, headers));
-
- // Decoding is blocked because dynamic table entry has not been received yet.
- EXPECT_FALSE(stream_->headers_decompressed());
-
- // Decoder stream type and stream cancellation instruction.
- auto decoder_send_stream =
- QuicSpdySessionPeer::GetQpackDecoderSendStream(session_.get());
- EXPECT_CALL(*session_,
- WritevData(decoder_send_stream->id(), /* write_length = */ 1,
- /* offset = */ 0, _, _, _));
- EXPECT_CALL(*session_,
- WritevData(decoder_send_stream->id(), /* write_length = */ 1,
- /* offset = */ 1, _, _, _));
-
- // Reset stream by this endpoint, for example, due to stream cancellation.
- EXPECT_CALL(*session_, MaybeSendStopSendingFrame(
- stream_->id(), QuicResetStreamError::FromInternal(
- QUIC_STREAM_CANCELLED)));
- EXPECT_CALL(
- *session_,
- MaybeSendRstStreamFrame(
- stream_->id(),
- QuicResetStreamError::FromInternal(QUIC_STREAM_CANCELLED), _));
- stream_->Reset(QUIC_STREAM_CANCELLED);
-
- // Deliver dynamic table entry to decoder.
- session_->qpack_decoder()->OnInsertWithoutNameReference("foo", "bar");
-
- EXPECT_FALSE(stream_->headers_decompressed());
-}
-
-TEST_P(QuicSpdyStreamTest, HeaderDecodingUnblockedAfterResetReceived) {
- if (!UsesHttp3()) {
- return;
- }
-
- Initialize(kShouldProcessData);
- testing::InSequence s;
- session_->qpack_decoder()->OnSetDynamicTableCapacity(1024);
- StrictMock<MockHttp3DebugVisitor> debug_visitor;
- session_->set_debug_visitor(&debug_visitor);
-
- // HEADERS frame referencing first dynamic table entry.
- std::string encoded_headers = absl::HexStringToBytes("020080");
- std::string headers = HeadersFrame(encoded_headers);
- EXPECT_CALL(debug_visitor,
- OnHeadersFrameReceived(stream_->id(), encoded_headers.length()));
- stream_->OnStreamFrame(QuicStreamFrame(stream_->id(), false, 0, headers));
-
- // Decoding is blocked because dynamic table entry has not been received yet.
- EXPECT_FALSE(stream_->headers_decompressed());
-
- // Decoder stream type and stream cancellation instruction.
- auto decoder_send_stream =
- QuicSpdySessionPeer::GetQpackDecoderSendStream(session_.get());
- EXPECT_CALL(*session_,
- WritevData(decoder_send_stream->id(), /* write_length = */ 1,
- /* offset = */ 0, _, _, _));
- EXPECT_CALL(*session_,
- WritevData(decoder_send_stream->id(), /* write_length = */ 1,
- /* offset = */ 1, _, _, _));
-
- // OnStreamReset() is called when RESET_STREAM frame is received from peer.
- stream_->OnStreamReset(QuicRstStreamFrame(
- kInvalidControlFrameId, stream_->id(), QUIC_STREAM_CANCELLED, 0));
-
- if (!GetQuicReloadableFlag(quic_abort_qpack_on_stream_reset)) {
- // Header acknowledgement.
- EXPECT_CALL(*session_,
- WritevData(decoder_send_stream->id(), /* write_length = */ 1,
- /* offset = */ 2, _, _, _));
- EXPECT_CALL(debug_visitor, OnHeadersDecoded(stream_->id(), _));
- }
-
- // Deliver dynamic table entry to decoder.
- session_->qpack_decoder()->OnInsertWithoutNameReference("foo", "bar");
-
- if (GetQuicReloadableFlag(quic_abort_qpack_on_stream_reset)) {
- EXPECT_FALSE(stream_->headers_decompressed());
- } else {
- // Verify headers.
- EXPECT_TRUE(stream_->headers_decompressed());
- EXPECT_THAT(stream_->header_list(), ElementsAre(Pair("foo", "bar")));
- }
-}
-
-class QuicSpdyStreamIncrementalConsumptionTest : public QuicSpdyStreamTest {
- protected:
- QuicSpdyStreamIncrementalConsumptionTest() : offset_(0), consumed_bytes_(0) {}
- ~QuicSpdyStreamIncrementalConsumptionTest() override = default;
-
- // Create QuicStreamFrame with |payload|
- // and pass it to stream_->OnStreamFrame().
- void OnStreamFrame(absl::string_view payload) {
- QuicStreamFrame frame(stream_->id(), /* fin = */ false, offset_, payload);
- stream_->OnStreamFrame(frame);
- offset_ += payload.size();
- }
-
- // Return number of bytes marked consumed with sequencer
- // since last NewlyConsumedBytes() call.
- QuicStreamOffset NewlyConsumedBytes() {
- QuicStreamOffset previously_consumed_bytes = consumed_bytes_;
- consumed_bytes_ = stream_->sequencer()->NumBytesConsumed();
- return consumed_bytes_ - previously_consumed_bytes;
- }
-
- // Read |size| bytes from the stream.
- std::string ReadFromStream(QuicByteCount size) {
- std::string buffer;
- buffer.resize(size);
-
- struct iovec vec;
- vec.iov_base = const_cast<char*>(buffer.data());
- vec.iov_len = size;
-
- size_t bytes_read = stream_->Readv(&vec, 1);
- EXPECT_EQ(bytes_read, size);
-
- return buffer;
- }
-
- private:
- QuicStreamOffset offset_;
- QuicStreamOffset consumed_bytes_;
-};
-
-INSTANTIATE_TEST_SUITE_P(Tests, QuicSpdyStreamIncrementalConsumptionTest,
- ::testing::ValuesIn(AllSupportedVersions()),
- ::testing::PrintToStringParamName());
-
-// Test that stream bytes are consumed (by calling
-// sequencer()->MarkConsumed()) incrementally, as soon as possible.
-TEST_P(QuicSpdyStreamIncrementalConsumptionTest, OnlyKnownFrames) {
- if (!UsesHttp3()) {
- return;
- }
-
- Initialize(!kShouldProcessData);
-
- std::string headers = HeadersFrame({std::make_pair("foo", "bar")});
-
- // All HEADERS frame bytes are consumed even if the frame is not received
- // completely.
- OnStreamFrame(absl::string_view(headers).substr(0, headers.size() - 1));
- EXPECT_EQ(headers.size() - 1, NewlyConsumedBytes());
-
- // The rest of the HEADERS frame is also consumed immediately.
- OnStreamFrame(absl::string_view(headers).substr(headers.size() - 1));
- EXPECT_EQ(1u, NewlyConsumedBytes());
-
- // Verify headers.
- EXPECT_THAT(stream_->header_list(), ElementsAre(Pair("foo", "bar")));
- stream_->ConsumeHeaderList();
-
- // DATA frame.
- absl::string_view data_payload(kDataFramePayload);
- std::string data_frame = DataFrame(data_payload);
- QuicByteCount data_frame_header_length =
- data_frame.size() - data_payload.size();
-
- // DATA frame header is consumed.
- // DATA frame payload is not consumed because payload has to be buffered.
- OnStreamFrame(data_frame);
- EXPECT_EQ(data_frame_header_length, NewlyConsumedBytes());
-
- // Consume all but last byte of data.
- EXPECT_EQ(data_payload.substr(0, data_payload.size() - 1),
- ReadFromStream(data_payload.size() - 1));
- EXPECT_EQ(data_payload.size() - 1, NewlyConsumedBytes());
-
- std::string trailers =
- HeadersFrame({std::make_pair("custom-key", "custom-value")});
-
- // No bytes are consumed, because last byte of DATA payload is still buffered.
- OnStreamFrame(absl::string_view(trailers).substr(0, trailers.size() - 1));
- EXPECT_EQ(0u, NewlyConsumedBytes());
-
- // Reading last byte of DATA payload triggers consumption of all data received
- // so far, even though last HEADERS frame has not been received completely.
- EXPECT_EQ(data_payload.substr(data_payload.size() - 1), ReadFromStream(1));
- EXPECT_EQ(1 + trailers.size() - 1, NewlyConsumedBytes());
-
- // Last byte of trailers is immediately consumed.
- OnStreamFrame(absl::string_view(trailers).substr(trailers.size() - 1));
- EXPECT_EQ(1u, NewlyConsumedBytes());
-
- // Verify trailers.
- EXPECT_THAT(stream_->received_trailers(),
- ElementsAre(Pair("custom-key", "custom-value")));
-}
-
-TEST_P(QuicSpdyStreamIncrementalConsumptionTest, ReceiveUnknownFrame) {
- if (!UsesHttp3()) {
- return;
- }
-
- Initialize(kShouldProcessData);
- StrictMock<MockHttp3DebugVisitor> debug_visitor;
- session_->set_debug_visitor(&debug_visitor);
-
- EXPECT_CALL(debug_visitor,
- OnUnknownFrameReceived(stream_->id(), /* frame_type = */ 0x21,
- /* payload_length = */ 3));
- std::string unknown_frame = UnknownFrame(0x21, "foo");
- OnStreamFrame(unknown_frame);
-}
-
-TEST_P(QuicSpdyStreamIncrementalConsumptionTest, UnknownFramesInterleaved) {
- if (!UsesHttp3()) {
- return;
- }
-
- Initialize(!kShouldProcessData);
-
- // Unknown frame of reserved type before HEADERS is consumed immediately.
- std::string unknown_frame1 = UnknownFrame(0x21, "foo");
- OnStreamFrame(unknown_frame1);
- EXPECT_EQ(unknown_frame1.size(), NewlyConsumedBytes());
-
- std::string headers = HeadersFrame({std::make_pair("foo", "bar")});
-
- // All HEADERS frame bytes are consumed even if the frame is not received
- // completely.
- OnStreamFrame(absl::string_view(headers).substr(0, headers.size() - 1));
- EXPECT_EQ(headers.size() - 1, NewlyConsumedBytes());
-
- // The rest of the HEADERS frame is also consumed immediately.
- OnStreamFrame(absl::string_view(headers).substr(headers.size() - 1));
- EXPECT_EQ(1u, NewlyConsumedBytes());
-
- // Verify headers.
- EXPECT_THAT(stream_->header_list(), ElementsAre(Pair("foo", "bar")));
- stream_->ConsumeHeaderList();
-
- // Frame of unknown, not reserved type between HEADERS and DATA is consumed
- // immediately.
- std::string unknown_frame2 = UnknownFrame(0x3a, "");
- OnStreamFrame(unknown_frame2);
- EXPECT_EQ(unknown_frame2.size(), NewlyConsumedBytes());
-
- // DATA frame.
- absl::string_view data_payload(kDataFramePayload);
- std::string data_frame = DataFrame(data_payload);
- QuicByteCount data_frame_header_length =
- data_frame.size() - data_payload.size();
-
- // DATA frame header is consumed.
- // DATA frame payload is not consumed because payload has to be buffered.
- OnStreamFrame(data_frame);
- EXPECT_EQ(data_frame_header_length, NewlyConsumedBytes());
-
- // Frame of unknown, not reserved type is not consumed because DATA payload is
- // still buffered.
- std::string unknown_frame3 = UnknownFrame(0x39, "bar");
- OnStreamFrame(unknown_frame3);
- EXPECT_EQ(0u, NewlyConsumedBytes());
-
- // Consume all but last byte of data.
- EXPECT_EQ(data_payload.substr(0, data_payload.size() - 1),
- ReadFromStream(data_payload.size() - 1));
- EXPECT_EQ(data_payload.size() - 1, NewlyConsumedBytes());
-
- std::string trailers =
- HeadersFrame({std::make_pair("custom-key", "custom-value")});
-
- // No bytes are consumed, because last byte of DATA payload is still buffered.
- OnStreamFrame(absl::string_view(trailers).substr(0, trailers.size() - 1));
- EXPECT_EQ(0u, NewlyConsumedBytes());
-
- // Reading last byte of DATA payload triggers consumption of all data received
- // so far, even though last HEADERS frame has not been received completely.
- EXPECT_EQ(data_payload.substr(data_payload.size() - 1), ReadFromStream(1));
- EXPECT_EQ(1 + unknown_frame3.size() + trailers.size() - 1,
- NewlyConsumedBytes());
-
- // Last byte of trailers is immediately consumed.
- OnStreamFrame(absl::string_view(trailers).substr(trailers.size() - 1));
- EXPECT_EQ(1u, NewlyConsumedBytes());
-
- // Verify trailers.
- EXPECT_THAT(stream_->received_trailers(),
- ElementsAre(Pair("custom-key", "custom-value")));
-
- // Unknown frame of reserved type after trailers is consumed immediately.
- std::string unknown_frame4 = UnknownFrame(0x40, "");
- OnStreamFrame(unknown_frame4);
- EXPECT_EQ(unknown_frame4.size(), NewlyConsumedBytes());
-}
-
-// Close connection if a DATA frame is received before a HEADERS frame.
-TEST_P(QuicSpdyStreamTest, DataBeforeHeaders) {
- if (!UsesHttp3()) {
- return;
- }
-
- Initialize(kShouldProcessData);
-
- // Closing the connection is mocked out in tests. Instead, simply stop
- // reading data at the stream level to prevent QuicSpdyStream from blowing up.
- EXPECT_CALL(
- *connection_,
- CloseConnection(QUIC_HTTP_INVALID_FRAME_SEQUENCE_ON_SPDY_STREAM,
- "Unexpected DATA frame received.",
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET))
- .WillOnce(InvokeWithoutArgs([this]() { stream_->StopReading(); }));
-
- std::string data = DataFrame(kDataFramePayload);
- stream_->OnStreamFrame(QuicStreamFrame(stream_->id(), false, 0, data));
-}
-
-// Close connection if a HEADERS frame is received after the trailing HEADERS.
-TEST_P(QuicSpdyStreamTest, TrailersAfterTrailers) {
- if (!UsesHttp3()) {
- return;
- }
-
- Initialize(kShouldProcessData);
-
- // Receive and consume headers.
- std::string headers = HeadersFrame({std::make_pair("foo", "bar")});
- QuicStreamOffset offset = 0;
- stream_->OnStreamFrame(
- QuicStreamFrame(stream_->id(), false, offset, headers));
- offset += headers.size();
-
- EXPECT_THAT(stream_->header_list(), ElementsAre(Pair("foo", "bar")));
- stream_->ConsumeHeaderList();
-
- // Receive data. It is consumed by TestStream.
- std::string data = DataFrame(kDataFramePayload);
- stream_->OnStreamFrame(QuicStreamFrame(stream_->id(), false, offset, data));
- offset += data.size();
-
- EXPECT_EQ(kDataFramePayload, stream_->data());
-
- // Receive and consume trailers.
- std::string trailers1 =
- HeadersFrame({std::make_pair("custom-key", "custom-value")});
- stream_->OnStreamFrame(
- QuicStreamFrame(stream_->id(), false, offset, trailers1));
- offset += trailers1.size();
-
- EXPECT_TRUE(stream_->trailers_decompressed());
- EXPECT_THAT(stream_->received_trailers(),
- ElementsAre(Pair("custom-key", "custom-value")));
-
- // Closing the connection is mocked out in tests. Instead, simply stop
- // reading data at the stream level to prevent QuicSpdyStream from blowing up.
- EXPECT_CALL(
- *connection_,
- CloseConnection(QUIC_HTTP_INVALID_FRAME_SEQUENCE_ON_SPDY_STREAM,
- "HEADERS frame received after trailing HEADERS.",
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET))
- .WillOnce(InvokeWithoutArgs([this]() { stream_->StopReading(); }));
-
- // Receive another HEADERS frame, with no header fields.
- std::string trailers2 = HeadersFrame(SpdyHeaderBlock());
- stream_->OnStreamFrame(
- QuicStreamFrame(stream_->id(), false, offset, trailers2));
-}
-
-// Regression test for https://crbug.com/978733.
-// Close connection if a DATA frame is received after the trailing HEADERS.
-TEST_P(QuicSpdyStreamTest, DataAfterTrailers) {
- if (!UsesHttp3()) {
- return;
- }
-
- Initialize(kShouldProcessData);
-
- // Receive and consume headers.
- std::string headers = HeadersFrame({std::make_pair("foo", "bar")});
- QuicStreamOffset offset = 0;
- stream_->OnStreamFrame(
- QuicStreamFrame(stream_->id(), false, offset, headers));
- offset += headers.size();
-
- EXPECT_THAT(stream_->header_list(), ElementsAre(Pair("foo", "bar")));
- stream_->ConsumeHeaderList();
-
- // Receive data. It is consumed by TestStream.
- std::string data1 = DataFrame(kDataFramePayload);
- stream_->OnStreamFrame(QuicStreamFrame(stream_->id(), false, offset, data1));
- offset += data1.size();
- EXPECT_EQ(kDataFramePayload, stream_->data());
-
- // Receive trailers, with single header field "custom-key: custom-value".
- std::string trailers =
- HeadersFrame({std::make_pair("custom-key", "custom-value")});
- stream_->OnStreamFrame(
- QuicStreamFrame(stream_->id(), false, offset, trailers));
- offset += trailers.size();
-
- EXPECT_THAT(stream_->received_trailers(),
- ElementsAre(Pair("custom-key", "custom-value")));
-
- // Closing the connection is mocked out in tests. Instead, simply stop
- // reading data at the stream level to prevent QuicSpdyStream from blowing up.
- EXPECT_CALL(
- *connection_,
- CloseConnection(QUIC_HTTP_INVALID_FRAME_SEQUENCE_ON_SPDY_STREAM,
- "Unexpected DATA frame received.",
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET))
- .WillOnce(InvokeWithoutArgs([this]() { stream_->StopReading(); }));
-
- // Receive more data.
- std::string data2 = DataFrame("This payload should not be proccessed.");
- stream_->OnStreamFrame(QuicStreamFrame(stream_->id(), false, offset, data2));
-}
-
-// SETTINGS frames are invalid on bidirectional streams. If one is received,
-// the connection is closed. No more data should be processed.
-TEST_P(QuicSpdyStreamTest, StopProcessingIfConnectionClosed) {
- if (!UsesHttp3()) {
- return;
- }
-
- Initialize(kShouldProcessData);
-
- // SETTINGS frame with empty payload.
- std::string settings = absl::HexStringToBytes("0400");
-
- // HEADERS frame.
- // Since it arrives after a SETTINGS frame, it should never be read.
- std::string headers = HeadersFrame({std::make_pair("foo", "bar")});
-
- // Combine the two frames to make sure they are processed in a single
- // QuicSpdyStream::OnDataAvailable() call.
- std::string frames = absl::StrCat(settings, headers);
-
- EXPECT_EQ(0u, stream_->sequencer()->NumBytesConsumed());
-
- EXPECT_CALL(*connection_,
- CloseConnection(QUIC_HTTP_FRAME_UNEXPECTED_ON_SPDY_STREAM, _, _))
- .WillOnce(
- Invoke(connection_, &MockQuicConnection::ReallyCloseConnection));
- EXPECT_CALL(*connection_, SendConnectionClosePacket(_, _, _));
- EXPECT_CALL(*session_, OnConnectionClosed(_, _));
-
- stream_->OnStreamFrame(QuicStreamFrame(stream_->id(), /* fin = */ false,
- /* offset = */ 0, frames));
-
- EXPECT_EQ(0u, stream_->sequencer()->NumBytesConsumed());
-}
-
-// Stream Cancellation instruction is sent on QPACK decoder stream
-// when stream is reset.
-TEST_P(QuicSpdyStreamTest, StreamCancellationWhenStreamReset) {
- if (!UsesHttp3()) {
- return;
- }
-
- Initialize(kShouldProcessData);
-
- auto qpack_decoder_stream =
- QuicSpdySessionPeer::GetQpackDecoderSendStream(session_.get());
- // Stream type.
- EXPECT_CALL(*session_,
- WritevData(qpack_decoder_stream->id(), /* write_length = */ 1,
- /* offset = */ 0, _, _, _));
- // Stream cancellation.
- EXPECT_CALL(*session_,
- WritevData(qpack_decoder_stream->id(), /* write_length = */ 1,
- /* offset = */ 1, _, _, _));
- EXPECT_CALL(*session_, MaybeSendStopSendingFrame(
- stream_->id(), QuicResetStreamError::FromInternal(
- QUIC_STREAM_CANCELLED)));
- EXPECT_CALL(
- *session_,
- MaybeSendRstStreamFrame(
- stream_->id(),
- QuicResetStreamError::FromInternal(QUIC_STREAM_CANCELLED), _));
-
- stream_->Reset(QUIC_STREAM_CANCELLED);
-}
-
-// Stream Cancellation instruction is sent on QPACK decoder stream
-// when RESET_STREAM frame is received.
-TEST_P(QuicSpdyStreamTest, StreamCancellationOnResetReceived) {
- if (!UsesHttp3()) {
- return;
- }
-
- Initialize(kShouldProcessData);
-
- auto qpack_decoder_stream =
- QuicSpdySessionPeer::GetQpackDecoderSendStream(session_.get());
- // Stream type.
- EXPECT_CALL(*session_,
- WritevData(qpack_decoder_stream->id(), /* write_length = */ 1,
- /* offset = */ 0, _, _, _));
- // Stream cancellation.
- EXPECT_CALL(*session_,
- WritevData(qpack_decoder_stream->id(), /* write_length = */ 1,
- /* offset = */ 1, _, _, _));
-
- stream_->OnStreamReset(QuicRstStreamFrame(
- kInvalidControlFrameId, stream_->id(), QUIC_STREAM_CANCELLED, 0));
-}
-
-TEST_P(QuicSpdyStreamTest, WriteHeadersReturnValue) {
- if (!UsesHttp3()) {
- return;
- }
-
- Initialize(kShouldProcessData);
- testing::InSequence s;
-
- // Enable QPACK dynamic table.
- session_->OnSetting(SETTINGS_QPACK_MAX_TABLE_CAPACITY, 1024);
- session_->OnSetting(SETTINGS_QPACK_BLOCKED_STREAMS, 1);
-
- EXPECT_CALL(*stream_, WriteHeadersMock(true));
-
- QpackSendStream* encoder_stream =
- QuicSpdySessionPeer::GetQpackEncoderSendStream(session_.get());
- EXPECT_CALL(*session_, WritevData(encoder_stream->id(), _, _, _, _, _))
- .Times(AnyNumber());
-
- // HEADERS frame header.
- EXPECT_CALL(*session_,
- WritevData(stream_->id(), _, /* offset = */ 0, _, _, _));
- // HEADERS frame payload.
- size_t headers_frame_payload_length = 0;
- EXPECT_CALL(*session_, WritevData(stream_->id(), _, _, _, _, _))
- .WillOnce(
- DoAll(SaveArg<1>(&headers_frame_payload_length),
- Invoke(session_.get(), &MockQuicSpdySession::ConsumeData)));
-
- SpdyHeaderBlock request_headers;
- request_headers["foo"] = "bar";
- size_t write_headers_return_value =
- stream_->WriteHeaders(std::move(request_headers), /*fin=*/true, nullptr);
- EXPECT_TRUE(stream_->fin_sent());
-
- EXPECT_EQ(headers_frame_payload_length, write_headers_return_value);
-}
-
-// Regression test for https://crbug.com/1177662.
-// RESET_STREAM with QUIC_STREAM_NO_ERROR should not be treated in a special
-// way: it should close the read side but not the write side.
-TEST_P(QuicSpdyStreamTest, TwoResetStreamFrames) {
- if (!UsesHttp3()) {
- return;
- }
-
- Initialize(kShouldProcessData);
-
- EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _)).Times(AnyNumber());
-
- QuicRstStreamFrame rst_frame1(kInvalidControlFrameId, stream_->id(),
- QUIC_STREAM_CANCELLED, /* bytes_written = */ 0);
- stream_->OnStreamReset(rst_frame1);
- EXPECT_TRUE(stream_->read_side_closed());
- EXPECT_FALSE(stream_->write_side_closed());
-
- QuicRstStreamFrame rst_frame2(kInvalidControlFrameId, stream_->id(),
- QUIC_STREAM_NO_ERROR, /* bytes_written = */ 0);
- if (GetQuicReloadableFlag(quic_fix_on_stream_reset)) {
- stream_->OnStreamReset(rst_frame2);
- EXPECT_TRUE(stream_->read_side_closed());
- EXPECT_FALSE(stream_->write_side_closed());
- } else {
- EXPECT_CALL(
- *session_,
- MaybeSendRstStreamFrame(
- stream_->id(),
- QuicResetStreamError::FromInternal(QUIC_RST_ACKNOWLEDGEMENT), _));
- EXPECT_QUIC_BUG(
- stream_->OnStreamReset(rst_frame2),
- "The stream should've already sent RST in response to STOP_SENDING");
- }
-}
-
-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_->EnableWebTransport();
- session_->OnSetting(SETTINGS_ENABLE_CONNECT_PROTOCOL, 1);
- QuicSpdySessionPeer::EnableWebTransport(session_.get());
- QuicSpdySessionPeer::SetHttpDatagramSupport(session_.get(),
- HttpDatagramSupport::kDraft04);
-
- EXPECT_CALL(*stream_, WriteHeadersMock(false));
- EXPECT_CALL(*session_, WritevData(stream_->id(), _, _, _, _, _))
- .Times(AnyNumber());
-
- spdy::SpdyHeaderBlock headers;
- headers[":method"] = "CONNECT";
- headers[":protocol"] = "webtransport";
- 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, ProcessIncomingWebTransportHeadersDatagramDraft04) {
- if (!UsesHttp3()) {
- return;
- }
-
- Initialize(kShouldProcessData);
- session_->set_local_http_datagram_support(HttpDatagramSupport::kDraft00And04);
- session_->EnableWebTransport();
- QuicSpdySessionPeer::EnableWebTransport(session_.get());
- QuicSpdySessionPeer::SetHttpDatagramSupport(session_.get(),
- HttpDatagramSupport::kDraft04);
-
- headers_[":method"] = "CONNECT";
- headers_[":protocol"] = "webtransport";
- headers_["sec-webtransport-http3-draft02"] = "1";
-
- 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());
- ASSERT_TRUE(stream_->web_transport() != nullptr);
- 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) {
- 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);
- QuicSpdySessionPeer::SetHttpDatagramSupport(session_.get(),
- HttpDatagramSupport::kDraft00);
- 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);
- 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)}));
- // 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[2], datagram.size() - 2)}));
- // 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());
-}
-
-TEST_P(QuicSpdyStreamTest, SendHttp3Datagram) {
- if (!UsesHttp3()) {
- return;
- }
- Initialize(kShouldProcessData);
- session_->set_local_http_datagram_support(HttpDatagramSupport::kDraft00And04);
- QuicSpdySessionPeer::SetHttpDatagramSupport(session_.get(),
- HttpDatagramSupport::kDraft04);
- absl::optional<QuicDatagramContextId> context_id;
- std::string h3_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),
- MESSAGE_STATUS_SUCCESS);
-}
-
-TEST_P(QuicSpdyStreamTest, GetMaxDatagramSize) {
- if (!UsesHttp3()) {
- return;
- }
- Initialize(kShouldProcessData);
- session_->set_local_http_datagram_support(HttpDatagramSupport::kDraft00And04);
- 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);
-}
-
-TEST_P(QuicSpdyStreamTest,
- QUIC_TEST_DISABLED_IN_CHROME(HeadersAccumulatorNullptr)) {
- if (!UsesHttp3()) {
- return;
- }
-
- Initialize(kShouldProcessData);
-
- // Creates QpackDecodedHeadersAccumulator in
- // `qpack_decoded_headers_accumulator_`.
- std::string headers = HeadersFrame({std::make_pair("foo", "bar")});
- stream_->OnStreamFrame(QuicStreamFrame(stream_->id(), false, 0, headers));
-
- // Resets `qpack_decoded_headers_accumulator_`.
- stream_->OnHeadersDecoded({}, false);
-
- // 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);
-}
-
-} // namespace
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/http/spdy_server_push_utils.cc b/chromium/net/third_party/quiche/src/quic/core/http/spdy_server_push_utils.cc
deleted file mode 100644
index eb818101ff5..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/http/spdy_server_push_utils.cc
+++ /dev/null
@@ -1,215 +0,0 @@
-// Copyright (c) 2013 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 "quic/core/http/spdy_server_push_utils.h"
-
-#include "absl/strings/string_view.h"
-#include "url/gurl.h"
-
-using spdy::SpdyHeaderBlock;
-
-namespace quic {
-
-// static
-std::string SpdyServerPushUtils::GetPromisedUrlFromHeaders(
- const SpdyHeaderBlock& headers) {
- // RFC 7540, Section 8.1.2.3: All HTTP/2 requests MUST include exactly
- // one valid value for the ":method", ":scheme", and ":path" pseudo-header
- // fields, unless it is a CONNECT request.
-
- // RFC 7540, Section 8.2.1: The header fields in PUSH_PROMISE and any
- // subsequent CONTINUATION frames MUST be a valid and complete set of request
- // header fields (Section 8.1.2.3). The server MUST include a method in the
- // ":method" pseudo-header field that is safe and cacheable.
- //
- // RFC 7231, Section 4.2.1: Of the request methods defined by this
- // specification, the GET, HEAD, OPTIONS, and TRACE methods are defined to be
- // safe.
- //
- // RFC 7231, Section 4.2.1: ... this specification defines GET, HEAD, and
- // POST as cacheable, ...
- //
- // So the only methods allowed in a PUSH_PROMISE are GET and HEAD.
- SpdyHeaderBlock::const_iterator it = headers.find(":method");
- if (it == headers.end() || (it->second != "GET" && it->second != "HEAD")) {
- return std::string();
- }
-
- it = headers.find(":scheme");
- if (it == headers.end() || it->second.empty()) {
- return std::string();
- }
- absl::string_view scheme = it->second;
-
- // RFC 7540, Section 8.2: The server MUST include a value in the
- // ":authority" pseudo-header field for which the server is authoritative
- // (see Section 10.1).
- it = headers.find(":authority");
- if (it == headers.end() || it->second.empty()) {
- return std::string();
- }
- absl::string_view authority = it->second;
-
- // RFC 7540, Section 8.1.2.3 requires that the ":path" pseudo-header MUST
- // NOT be empty for "http" or "https" URIs;
- //
- // However, to ensure the scheme is consistently canonicalized, that check
- // is deferred to implementations in QuicUrlUtils::GetPushPromiseUrl().
- it = headers.find(":path");
- if (it == headers.end()) {
- return std::string();
- }
- absl::string_view path = it->second;
-
- return GetPushPromiseUrl(scheme, authority, path);
-}
-
-// static
-std::string SpdyServerPushUtils::GetPromisedHostNameFromHeaders(
- const SpdyHeaderBlock& headers) {
- // TODO(fayang): Consider just checking out the value of the ":authority" key
- // in headers.
- return GURL(GetPromisedUrlFromHeaders(headers)).host();
-}
-
-// static
-bool SpdyServerPushUtils::PromisedUrlIsValid(const SpdyHeaderBlock& headers) {
- std::string url(GetPromisedUrlFromHeaders(headers));
- return !url.empty() && GURL(url).is_valid();
-}
-
-// static
-std::string SpdyServerPushUtils::GetPushPromiseUrl(absl::string_view scheme,
- absl::string_view authority,
- absl::string_view path) {
- // RFC 7540, Section 8.1.2.3: The ":path" pseudo-header field includes the
- // path and query parts of the target URI (the "path-absolute" production
- // and optionally a '?' character followed by the "query" production (see
- // Sections 3.3 and 3.4 of RFC3986). A request in asterisk form includes the
- // value '*' for the ":path" pseudo-header field.
- //
- // This pseudo-header field MUST NOT be empty for "http" or "https" URIs;
- // "http" or "https" URIs that do not contain a path MUST include a value of
- // '/'. The exception to this rule is an OPTIONS request for an "http" or
- // "https" URI that does not include a path component; these MUST include a
- // ":path" pseudo-header with a value of '*' (see RFC7230, Section 5.3.4).
- //
- // In addition to the above restriction from RFC 7540, note that RFC3986
- // defines the "path-absolute" construction as starting with "/" but not "//".
- //
- // RFC 7540, Section 8.2.1: The header fields in PUSH_PROMISE and any
- // subsequent CONTINUATION frames MUST be a valid and complete set of request
- // header fields (Section 8.1.2.3). The server MUST include a method in the
- // ":method" pseudo-header field that is safe and cacheable.
- //
- // RFC 7231, Section 4.2.1:
- // ... this specification defines GET, HEAD, and POST as cacheable, ...
- //
- // Since the OPTIONS method is not cacheable, it cannot be the method of a
- // PUSH_PROMISE. Therefore, the exception mentioned in RFC 7540, Section
- // 8.1.2.3 about OPTIONS requests does not apply here (i.e. ":path" cannot be
- // "*").
- if (path.empty() || path[0] != '/' || (path.size() >= 2 && path[1] == '/')) {
- return std::string();
- }
-
- // Validate the scheme; this is to ensure a scheme of "foo://bar" is not
- // parsed as a URL of "foo://bar://baz" when combined with a host of "baz".
- std::string canonical_scheme;
- url::StdStringCanonOutput canon_scheme_output(&canonical_scheme);
- url::Component canon_component;
- url::Component scheme_component(0, scheme.size());
-
- if (!url::CanonicalizeScheme(scheme.data(), scheme_component,
- &canon_scheme_output, &canon_component) ||
- !canon_component.is_nonempty() || canon_component.begin != 0) {
- return std::string();
- }
- canonical_scheme.resize(canon_component.len + 1);
-
- // Validate the authority; this is to ensure an authority such as
- // "host/path" is not accepted, as when combined with a scheme like
- // "http://", could result in a URL of "http://host/path".
- url::Component auth_component(0, authority.size());
- url::Component username_component;
- url::Component password_component;
- url::Component host_component;
- url::Component port_component;
-
- url::ParseAuthority(authority.data(), auth_component, &username_component,
- &password_component, &host_component, &port_component);
-
- // RFC 7540, Section 8.1.2.3: The authority MUST NOT include the deprecated
- // "userinfo" subcomponent for "http" or "https" schemed URIs.
- //
- // Note: Although |canonical_scheme| has not yet been checked for that, as
- // it is performed later in processing, only "http" and "https" schemed
- // URIs are supported for PUSH.
- if (username_component.is_valid() || password_component.is_valid()) {
- return std::string();
- }
-
- // Failed parsing or no host present. ParseAuthority() will ensure that
- // host_component + port_component cover the entire string, if
- // username_component and password_component are not present.
- if (!host_component.is_nonempty()) {
- return std::string();
- }
-
- // Validate the port (if present; it's optional).
- int parsed_port_number = url::PORT_INVALID;
- if (port_component.is_nonempty()) {
- parsed_port_number = url::ParsePort(authority.data(), port_component);
- if (parsed_port_number < 0 && parsed_port_number != url::PORT_UNSPECIFIED) {
- return std::string();
- }
- }
-
- // Validate the host by attempting to canonicalize it. Invalid characters
- // will result in a canonicalization failure (e.g. '/')
- std::string canon_host;
- url::StdStringCanonOutput canon_host_output(&canon_host);
- canon_component.reset();
- if (!url::CanonicalizeHost(authority.data(), host_component,
- &canon_host_output, &canon_component) ||
- !canon_component.is_nonempty() || canon_component.begin != 0) {
- return std::string();
- }
-
- // At this point, "authority" has been validated to either be of the form
- // 'host:port' or 'host', with 'host' being a valid domain or IP address,
- // and 'port' (if present), being a valid port. Attempt to construct a
- // URL of just the (scheme, host, port), which should be safe and will not
- // result in ambiguous parsing.
- //
- // This also enforces that all PUSHed URLs are either HTTP or HTTPS-schemed
- // URIs, consistent with the other restrictions enforced above.
- //
- // Note: url::CanonicalizeScheme() will have added the ':' to
- // |canonical_scheme|.
- GURL origin_url(canonical_scheme + "//" + std::string(authority));
- if (!origin_url.is_valid() || !origin_url.SchemeIsHTTPOrHTTPS() ||
- // The following checks are merely defense in depth.
- origin_url.has_username() || origin_url.has_password() ||
- (origin_url.has_path() && origin_url.path_piece() != "/") ||
- origin_url.has_query() || origin_url.has_ref()) {
- return std::string();
- }
-
- // Attempt to parse the path.
- std::string spec = origin_url.GetWithEmptyPath().spec();
- spec.pop_back(); // Remove the '/', as ":path" must contain it.
- spec.append(std::string(path));
-
- // Attempt to parse the full URL, with the path as well. Ensure there is no
- // fragment to the query.
- GURL full_url(spec);
- if (!full_url.is_valid() || full_url.has_ref()) {
- return std::string();
- }
-
- return full_url.spec();
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/http/spdy_server_push_utils.h b/chromium/net/third_party/quiche/src/quic/core/http/spdy_server_push_utils.h
deleted file mode 100644
index 63cfb886e47..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/http/spdy_server_push_utils.h
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright (c) 2013 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_HTTP_SPDY_SERVER_PUSH_UTILS_H_
-#define QUICHE_QUIC_CORE_HTTP_SPDY_SERVER_PUSH_UTILS_H_
-
-#include "absl/strings/string_view.h"
-#include "quic/platform/api/quic_export.h"
-#include "spdy/core/spdy_header_block.h"
-
-namespace quic {
-
-class QUIC_EXPORT_PRIVATE SpdyServerPushUtils {
- public:
- SpdyServerPushUtils() = delete;
-
- // Returns a canonicalized URL composed from the :scheme, :authority, and
- // :path headers of a PUSH_PROMISE. Returns empty string if the headers do not
- // conform to HTTP/2 spec or if the ":method" header contains a forbidden
- // method for PUSH_PROMISE.
- static std::string GetPromisedUrlFromHeaders(
- const spdy::SpdyHeaderBlock& headers);
-
- // Returns hostname, or empty string if missing.
- static std::string GetPromisedHostNameFromHeaders(
- const spdy::SpdyHeaderBlock& headers);
-
- // Returns true if result of |GetPromisedUrlFromHeaders()| is non-empty
- // and is a well-formed URL.
- static bool PromisedUrlIsValid(const spdy::SpdyHeaderBlock& headers);
-
- // Returns a canonical, valid URL for a PUSH_PROMISE with the specified
- // ":scheme", ":authority", and ":path" header fields, or an empty
- // string if the resulting URL is not valid or supported.
- static std::string GetPushPromiseUrl(absl::string_view scheme,
- absl::string_view authority,
- absl::string_view path);
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_HTTP_SPDY_SERVER_PUSH_UTILS_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/http/spdy_server_push_utils_test.cc b/chromium/net/third_party/quiche/src/quic/core/http/spdy_server_push_utils_test.cc
deleted file mode 100644
index df1659d683c..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/http/spdy_server_push_utils_test.cc
+++ /dev/null
@@ -1,217 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/http/spdy_server_push_utils.h"
-
-#include <memory>
-#include <string>
-
-#include "absl/base/macros.h"
-#include "quic/platform/api/quic_test.h"
-
-using spdy::SpdyHeaderBlock;
-
-namespace quic {
-namespace test {
-
-using GetPromisedUrlFromHeaders = QuicTest;
-
-TEST_F(GetPromisedUrlFromHeaders, Basic) {
- SpdyHeaderBlock headers;
- headers[":method"] = "GET";
- EXPECT_EQ(SpdyServerPushUtils::GetPromisedUrlFromHeaders(headers), "");
- headers[":scheme"] = "https";
- EXPECT_EQ(SpdyServerPushUtils::GetPromisedUrlFromHeaders(headers), "");
- headers[":authority"] = "www.google.com";
- EXPECT_EQ(SpdyServerPushUtils::GetPromisedUrlFromHeaders(headers), "");
- headers[":path"] = "/index.html";
- EXPECT_EQ(SpdyServerPushUtils::GetPromisedUrlFromHeaders(headers),
- "https://www.google.com/index.html");
- headers["key1"] = "value1";
- headers["key2"] = "value2";
- EXPECT_EQ(SpdyServerPushUtils::GetPromisedUrlFromHeaders(headers),
- "https://www.google.com/index.html");
-}
-
-TEST_F(GetPromisedUrlFromHeaders, Connect) {
- SpdyHeaderBlock headers;
- headers[":method"] = "CONNECT";
- EXPECT_EQ(SpdyServerPushUtils::GetPromisedUrlFromHeaders(headers), "");
- headers[":authority"] = "www.google.com";
- EXPECT_EQ(SpdyServerPushUtils::GetPromisedUrlFromHeaders(headers), "");
- headers[":scheme"] = "https";
- EXPECT_EQ(SpdyServerPushUtils::GetPromisedUrlFromHeaders(headers), "");
- headers[":path"] = "https";
- EXPECT_EQ(SpdyServerPushUtils::GetPromisedUrlFromHeaders(headers), "");
-}
-
-TEST_F(GetPromisedUrlFromHeaders, InvalidUserinfo) {
- SpdyHeaderBlock headers;
- headers[":method"] = "GET";
- headers[":authority"] = "user@www.google.com";
- headers[":scheme"] = "https";
- headers[":path"] = "/";
- EXPECT_EQ(SpdyServerPushUtils::GetPromisedUrlFromHeaders(headers), "");
-}
-
-TEST_F(GetPromisedUrlFromHeaders, InvalidPath) {
- SpdyHeaderBlock headers;
- headers[":method"] = "GET";
- headers[":authority"] = "www.google.com";
- headers[":scheme"] = "https";
- headers[":path"] = "";
- EXPECT_EQ(SpdyServerPushUtils::GetPromisedUrlFromHeaders(headers), "");
-}
-
-using GetPromisedHostNameFromHeaders = QuicTest;
-
-TEST_F(GetPromisedHostNameFromHeaders, NormalUsage) {
- SpdyHeaderBlock headers;
- headers[":method"] = "GET";
- EXPECT_EQ(SpdyServerPushUtils::GetPromisedHostNameFromHeaders(headers), "");
- headers[":scheme"] = "https";
- EXPECT_EQ(SpdyServerPushUtils::GetPromisedHostNameFromHeaders(headers), "");
- headers[":authority"] = "www.google.com";
- EXPECT_EQ(SpdyServerPushUtils::GetPromisedHostNameFromHeaders(headers), "");
- headers[":path"] = "/index.html";
- EXPECT_EQ(SpdyServerPushUtils::GetPromisedHostNameFromHeaders(headers),
- "www.google.com");
- headers["key1"] = "value1";
- headers["key2"] = "value2";
- EXPECT_EQ(SpdyServerPushUtils::GetPromisedHostNameFromHeaders(headers),
- "www.google.com");
- headers[":authority"] = "www.google.com:6666";
- EXPECT_EQ(SpdyServerPushUtils::GetPromisedHostNameFromHeaders(headers),
- "www.google.com");
- headers[":authority"] = "192.168.1.1";
- EXPECT_EQ(SpdyServerPushUtils::GetPromisedHostNameFromHeaders(headers),
- "192.168.1.1");
- headers[":authority"] = "192.168.1.1:6666";
- EXPECT_EQ(SpdyServerPushUtils::GetPromisedHostNameFromHeaders(headers),
- "192.168.1.1");
-}
-
-using PushPromiseUrlTest = QuicTest;
-
-TEST_F(PushPromiseUrlTest, GetPushPromiseUrl) {
- // Test rejection of various inputs.
- EXPECT_EQ("", SpdyServerPushUtils::GetPushPromiseUrl("file", "localhost",
- "/etc/password"));
- EXPECT_EQ("", SpdyServerPushUtils::GetPushPromiseUrl(
- "file", "", "/C:/Windows/System32/Config/"));
- EXPECT_EQ("", SpdyServerPushUtils::GetPushPromiseUrl(
- "", "https://www.google.com", "/"));
-
- EXPECT_EQ("", SpdyServerPushUtils::GetPushPromiseUrl("https://www.google.com",
- "www.google.com", "/"));
- EXPECT_EQ("", SpdyServerPushUtils::GetPushPromiseUrl("https://",
- "www.google.com", "/"));
- EXPECT_EQ("", SpdyServerPushUtils::GetPushPromiseUrl("https", "", "/"));
- EXPECT_EQ("", SpdyServerPushUtils::GetPushPromiseUrl("https", "",
- "www.google.com/"));
- EXPECT_EQ("", SpdyServerPushUtils::GetPushPromiseUrl("https",
- "www.google.com/", "/"));
- EXPECT_EQ("", SpdyServerPushUtils::GetPushPromiseUrl("https",
- "www.google.com", ""));
- EXPECT_EQ("", SpdyServerPushUtils::GetPushPromiseUrl("https", "www.google",
- ".com/"));
-
- // Test acception/rejection of various input combinations.
- // |input_headers| is an array of pairs. The first value of each pair is a
- // string that will be used as one of the inputs of GetPushPromiseUrl(). The
- // second value of each pair is a bitfield where the lowest 3 bits indicate
- // for which headers that string is valid (in a PUSH_PROMISE). For example,
- // the string "http" would be valid for both the ":scheme" and ":authority"
- // headers, so the bitfield paired with it is set to SCHEME | AUTH.
- const unsigned char SCHEME = (1u << 0);
- const unsigned char AUTH = (1u << 1);
- const unsigned char PATH = (1u << 2);
- const std::pair<const char*, unsigned char> input_headers[] = {
- {"http", SCHEME | AUTH},
- {"https", SCHEME | AUTH},
- {"hTtP", SCHEME | AUTH},
- {"HTTPS", SCHEME | AUTH},
- {"www.google.com", AUTH},
- {"90af90e0", AUTH},
- {"12foo%20-bar:00001233", AUTH},
- {"GOO\u200b\u2060\ufeffgoo", AUTH},
- {"192.168.0.5", AUTH},
- {"[::ffff:192.168.0.1.]", AUTH},
- {"http:", AUTH},
- {"bife l", AUTH},
- {"/", PATH},
- {"/foo/bar/baz", PATH},
- {"/%20-2DVdkj.cie/foe_.iif/", PATH},
- {"http://", 0},
- {":443", 0},
- {":80/eddd", 0},
- {"google.com:-0", 0},
- {"google.com:65536", 0},
- {"http://google.com", 0},
- {"http://google.com:39", 0},
- {"//google.com/foo", 0},
- {".com/", 0},
- {"http://www.google.com/", 0},
- {"http://foo:439", 0},
- {"[::ffff:192.168", 0},
- {"]/", 0},
- {"//", 0}};
- for (size_t i = 0; i < ABSL_ARRAYSIZE(input_headers); ++i) {
- bool should_accept = (input_headers[i].second & SCHEME);
- for (size_t j = 0; j < ABSL_ARRAYSIZE(input_headers); ++j) {
- bool should_accept_2 = should_accept && (input_headers[j].second & AUTH);
- for (size_t k = 0; k < ABSL_ARRAYSIZE(input_headers); ++k) {
- // |should_accept_3| indicates whether or not GetPushPromiseUrl() is
- // expected to accept this input combination.
- bool should_accept_3 =
- should_accept_2 && (input_headers[k].second & PATH);
-
- std::string url = SpdyServerPushUtils::GetPushPromiseUrl(
- input_headers[i].first, input_headers[j].first,
- input_headers[k].first);
-
- ::testing::AssertionResult result = ::testing::AssertionSuccess();
- if (url.empty() == should_accept_3) {
- result = ::testing::AssertionFailure()
- << "GetPushPromiseUrl() accepted/rejected the inputs when "
- "it shouldn't have."
- << std::endl
- << " scheme: " << input_headers[i].first << std::endl
- << " authority: " << input_headers[j].first << std::endl
- << " path: " << input_headers[k].first << std::endl
- << "Output: " << url << std::endl;
- }
- ASSERT_TRUE(result);
- }
- }
- }
-
- // Test canonicalization of various valid inputs.
- EXPECT_EQ("http://www.google.com/", SpdyServerPushUtils::GetPushPromiseUrl(
- "http", "www.google.com", "/"));
- EXPECT_EQ("https://www.goo-gle.com/fOOo/baRR",
- SpdyServerPushUtils::GetPushPromiseUrl("hTtPs", "wWw.gOo-gLE.cOm",
- "/fOOo/baRR"));
- EXPECT_EQ("https://www.goo-gle.com:3278/pAth/To/reSOurce",
- SpdyServerPushUtils::GetPushPromiseUrl(
- "hTtPs", "Www.gOo-Gle.Com:000003278", "/pAth/To/reSOurce"));
- EXPECT_EQ("https://foo%20bar/foo/bar/baz",
- SpdyServerPushUtils::GetPushPromiseUrl("https", "foo bar",
- "/foo/bar/baz"));
- EXPECT_EQ("http://foo.com:70/e/", SpdyServerPushUtils::GetPushPromiseUrl(
- "http", "foo.com:0000070", "/e/"));
- EXPECT_EQ("http://192.168.0.1:70/e/",
- SpdyServerPushUtils::GetPushPromiseUrl(
- "http", "0300.0250.00.01:0070", "/e/"));
- EXPECT_EQ("http://192.168.0.1/e/", SpdyServerPushUtils::GetPushPromiseUrl(
- "http", "0xC0a80001", "/e/"));
- EXPECT_EQ("http://[::c0a8:1]/", SpdyServerPushUtils::GetPushPromiseUrl(
- "http", "[::192.168.0.1]", "/"));
- EXPECT_EQ("https://[::ffff:c0a8:1]/",
- SpdyServerPushUtils::GetPushPromiseUrl(
- "https", "[::ffff:0xC0.0Xa8.0x0.0x1]", "/"));
-}
-
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/http/spdy_utils.cc b/chromium/net/third_party/quiche/src/quic/core/http/spdy_utils.cc
deleted file mode 100644
index 5b744077402..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/http/spdy_utils.cc
+++ /dev/null
@@ -1,217 +0,0 @@
-// Copyright (c) 2013 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 "quic/core/http/spdy_utils.h"
-
-#include <memory>
-#include <string>
-#include <vector>
-
-#include "absl/strings/numbers.h"
-#include "absl/strings/str_cat.h"
-#include "absl/strings/str_split.h"
-#include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
-#include "quic/core/quic_versions.h"
-#include "quic/platform/api/quic_flag_utils.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-#include "common/quiche_text_utils.h"
-#include "spdy/core/spdy_protocol.h"
-
-using spdy::SpdyHeaderBlock;
-
-namespace quic {
-
-// static
-bool SpdyUtils::ExtractContentLengthFromHeaders(int64_t* content_length,
- SpdyHeaderBlock* headers) {
- auto it = headers->find("content-length");
- if (it == headers->end()) {
- return false;
- } else {
- // Check whether multiple values are consistent.
- absl::string_view content_length_header = it->second;
- std::vector<absl::string_view> values =
- absl::StrSplit(content_length_header, '\0');
- for (const absl::string_view& value : values) {
- uint64_t new_value;
- if (!absl::SimpleAtoi(value, &new_value) ||
- !quiche::QuicheTextUtils::IsAllDigits(value)) {
- QUIC_DLOG(ERROR)
- << "Content length was either unparseable or negative.";
- return false;
- }
- if (*content_length < 0) {
- *content_length = new_value;
- continue;
- }
- if (new_value != static_cast<uint64_t>(*content_length)) {
- QUIC_DLOG(ERROR)
- << "Parsed content length " << new_value << " is "
- << "inconsistent with previously detected content length "
- << *content_length;
- return false;
- }
- }
- return true;
- }
-}
-
-bool SpdyUtils::CopyAndValidateHeaders(const QuicHeaderList& header_list,
- int64_t* content_length,
- SpdyHeaderBlock* headers) {
- for (const auto& p : header_list) {
- const std::string& name = p.first;
- if (name.empty()) {
- QUIC_DLOG(ERROR) << "Header name must not be empty.";
- return false;
- }
-
- if (quiche::QuicheTextUtils::ContainsUpperCase(name)) {
- QUIC_DLOG(ERROR) << "Malformed header: Header name " << name
- << " contains upper-case characters.";
- return false;
- }
-
- headers->AppendValueOrAddHeader(name, p.second);
- }
-
- if (headers->contains("content-length") &&
- !ExtractContentLengthFromHeaders(content_length, headers)) {
- return false;
- }
-
- QUIC_DVLOG(1) << "Successfully parsed headers: " << headers->DebugString();
- return true;
-}
-
-bool SpdyUtils::CopyAndValidateTrailers(const QuicHeaderList& header_list,
- bool expect_final_byte_offset,
- size_t* final_byte_offset,
- SpdyHeaderBlock* trailers) {
- bool found_final_byte_offset = false;
- for (const auto& p : header_list) {
- const std::string& name = p.first;
-
- // Pull out the final offset pseudo header which indicates the number of
- // response body bytes expected.
- if (expect_final_byte_offset && !found_final_byte_offset &&
- name == kFinalOffsetHeaderKey &&
- absl::SimpleAtoi(p.second, final_byte_offset)) {
- found_final_byte_offset = true;
- continue;
- }
-
- if (name.empty() || name[0] == ':') {
- QUIC_DLOG(ERROR)
- << "Trailers must not be empty, and must not contain pseudo-"
- << "headers. Found: '" << name << "'";
- return false;
- }
-
- if (quiche::QuicheTextUtils::ContainsUpperCase(name)) {
- QUIC_DLOG(ERROR) << "Malformed header: Header name " << name
- << " contains upper-case characters.";
- return false;
- }
-
- trailers->AppendValueOrAddHeader(name, p.second);
- }
-
- if (expect_final_byte_offset && !found_final_byte_offset) {
- QUIC_DLOG(ERROR) << "Required key '" << kFinalOffsetHeaderKey
- << "' not present";
- return false;
- }
-
- // TODO(rjshade): Check for other forbidden keys, following the HTTP/2 spec.
-
- QUIC_DVLOG(1) << "Successfully parsed Trailers: " << trailers->DebugString();
- return true;
-}
-
-// static
-// TODO(danzh): Move it to quic/tools/ and switch to use GURL.
-bool SpdyUtils::PopulateHeaderBlockFromUrl(const std::string url,
- SpdyHeaderBlock* headers) {
- (*headers)[":method"] = "GET";
- size_t pos = url.find("://");
- if (pos == std::string::npos) {
- return false;
- }
- (*headers)[":scheme"] = url.substr(0, pos);
- size_t start = pos + 3;
- pos = url.find('/', start);
- if (pos == std::string::npos) {
- (*headers)[":authority"] = url.substr(start);
- (*headers)[":path"] = "/";
- return true;
- }
- (*headers)[":authority"] = url.substr(start, pos - start);
- (*headers)[":path"] = url.substr(pos);
- return true;
-}
-
-// 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,
- const ParsedQuicVersionVector& supported_versions) {
- for (const ParsedQuicVersion& version : supported_versions) {
- if (version.AlpnDeferToRFCv1()) {
- // Versions with share an ALPN with v1 are currently unable to be
- // advertised with Alt-Svc.
- continue;
- }
- if (AlpnForVersion(version) == alternative_service_entry.protocol_id) {
- return version;
- }
- }
-
- return ParsedQuicVersion::Unsupported();
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/http/spdy_utils.h b/chromium/net/third_party/quiche/src/quic/core/http/spdy_utils.h
deleted file mode 100644
index 85099ab15e7..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/http/spdy_utils.h
+++ /dev/null
@@ -1,77 +0,0 @@
-// Copyright (c) 2013 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_HTTP_SPDY_UTILS_H_
-#define QUICHE_QUIC_CORE_HTTP_SPDY_UTILS_H_
-
-#include <cstddef>
-#include <cstdint>
-#include <string>
-
-#include "absl/types/optional.h"
-#include "quic/core/http/http_constants.h"
-#include "quic/core/http/quic_header_list.h"
-#include "quic/core/quic_packets.h"
-#include "quic/platform/api/quic_export.h"
-#include "spdy/core/spdy_alt_svc_wire_format.h"
-#include "spdy/core/spdy_header_block.h"
-
-namespace quic {
-
-class QUIC_EXPORT_PRIVATE SpdyUtils {
- public:
- SpdyUtils() = delete;
-
- // Populate |content length| with the value of the content-length header.
- // Returns true on success, false if parsing fails or content-length header is
- // missing.
- static bool ExtractContentLengthFromHeaders(int64_t* content_length,
- spdy::SpdyHeaderBlock* headers);
-
- // Copies a list of headers to a SpdyHeaderBlock.
- static bool CopyAndValidateHeaders(const QuicHeaderList& header_list,
- int64_t* content_length,
- spdy::SpdyHeaderBlock* headers);
-
- // Copies a list of headers to a SpdyHeaderBlock.
- // If |expect_final_byte_offset| is true, requires exactly one header field
- // with key kFinalOffsetHeaderKey and an integer value.
- // If |expect_final_byte_offset| is false, no kFinalOffsetHeaderKey may be
- // present.
- // Returns true if parsing is successful. Returns false if the presence of
- // kFinalOffsetHeaderKey does not match the value of
- // |expect_final_byte_offset|, the kFinalOffsetHeaderKey value cannot be
- // parsed, any other pseudo-header is present, an empty header key is present,
- // or a header key contains an uppercase character.
- static bool CopyAndValidateTrailers(const QuicHeaderList& header_list,
- bool expect_final_byte_offset,
- size_t* final_byte_offset,
- spdy::SpdyHeaderBlock* trailers);
-
- // Populates the fields of |headers| to make a GET request of |url|,
- // which must be fully-qualified.
- 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.
- static ParsedQuicVersion ExtractQuicVersionFromAltSvcEntry(
- const spdy::SpdyAltSvcWireFormat::AlternativeService&
- alternative_service_entry,
- const ParsedQuicVersionVector& supported_versions);
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_HTTP_SPDY_UTILS_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/http/spdy_utils_test.cc b/chromium/net/third_party/quiche/src/quic/core/http/spdy_utils_test.cc
deleted file mode 100644
index 85c5ceccd57..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/http/spdy_utils_test.cc
+++ /dev/null
@@ -1,442 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/http/spdy_utils.h"
-
-#include <memory>
-#include <string>
-
-#include "absl/base/macros.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_versions.h"
-#include "quic/platform/api/quic_test.h"
-
-using spdy::SpdyHeaderBlock;
-using testing::Pair;
-using testing::UnorderedElementsAre;
-
-namespace quic {
-namespace test {
-namespace {
-
-const bool kExpectFinalByteOffset = true;
-const bool kDoNotExpectFinalByteOffset = false;
-
-static std::unique_ptr<QuicHeaderList> FromList(
- const QuicHeaderList::ListType& src) {
- std::unique_ptr<QuicHeaderList> headers(new QuicHeaderList);
- headers->OnHeaderBlockStart();
- for (const auto& p : src) {
- headers->OnHeader(p.first, p.second);
- }
- headers->OnHeaderBlockEnd(0, 0);
- 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;
-
-TEST_F(CopyAndValidateHeaders, NormalUsage) {
- auto headers = FromList({// All cookie crumbs are joined.
- {"cookie", " part 1"},
- {"cookie", "part 2 "},
- {"cookie", "part3"},
-
- // Already-delimited headers are passed through.
- {"passed-through", std::string("foo\0baz", 7)},
-
- // Other headers are joined on \0.
- {"joined", "value 1"},
- {"joined", "value 2"},
-
- // Empty headers remain empty.
- {"empty", ""},
-
- // Joined empty headers work as expected.
- {"empty-joined", ""},
- {"empty-joined", "foo"},
- {"empty-joined", ""},
- {"empty-joined", ""},
-
- // Non-continguous cookie crumb.
- {"cookie", " fin!"}});
-
- int64_t content_length = -1;
- SpdyHeaderBlock block;
- ASSERT_TRUE(
- SpdyUtils::CopyAndValidateHeaders(*headers, &content_length, &block));
- EXPECT_THAT(block,
- UnorderedElementsAre(
- Pair("cookie", " part 1; part 2 ; part3; fin!"),
- Pair("passed-through", absl::string_view("foo\0baz", 7)),
- Pair("joined", absl::string_view("value 1\0value 2", 15)),
- Pair("empty", ""),
- Pair("empty-joined", absl::string_view("\0foo\0\0", 6))));
- EXPECT_EQ(-1, content_length);
-}
-
-TEST_F(CopyAndValidateHeaders, EmptyName) {
- auto headers = FromList({{"foo", "foovalue"}, {"", "barvalue"}, {"baz", ""}});
- int64_t content_length = -1;
- SpdyHeaderBlock block;
- ASSERT_FALSE(
- SpdyUtils::CopyAndValidateHeaders(*headers, &content_length, &block));
-}
-
-TEST_F(CopyAndValidateHeaders, UpperCaseName) {
- auto headers =
- FromList({{"foo", "foovalue"}, {"bar", "barvalue"}, {"bAz", ""}});
- int64_t content_length = -1;
- SpdyHeaderBlock block;
- ASSERT_FALSE(
- SpdyUtils::CopyAndValidateHeaders(*headers, &content_length, &block));
-}
-
-TEST_F(CopyAndValidateHeaders, MultipleContentLengths) {
- auto headers = FromList({{"content-length", "9"},
- {"foo", "foovalue"},
- {"content-length", "9"},
- {"bar", "barvalue"},
- {"baz", ""}});
- int64_t content_length = -1;
- SpdyHeaderBlock block;
- ASSERT_TRUE(
- SpdyUtils::CopyAndValidateHeaders(*headers, &content_length, &block));
- EXPECT_THAT(block, UnorderedElementsAre(
- Pair("foo", "foovalue"), Pair("bar", "barvalue"),
- Pair("content-length", absl::string_view("9\09", 3)),
- Pair("baz", "")));
- EXPECT_EQ(9, content_length);
-}
-
-TEST_F(CopyAndValidateHeaders, InconsistentContentLengths) {
- auto headers = FromList({{"content-length", "9"},
- {"foo", "foovalue"},
- {"content-length", "8"},
- {"bar", "barvalue"},
- {"baz", ""}});
- int64_t content_length = -1;
- SpdyHeaderBlock block;
- ASSERT_FALSE(
- SpdyUtils::CopyAndValidateHeaders(*headers, &content_length, &block));
-}
-
-TEST_F(CopyAndValidateHeaders, LargeContentLength) {
- auto headers = FromList({{"content-length", "9000000000"},
- {"foo", "foovalue"},
- {"bar", "barvalue"},
- {"baz", ""}});
- int64_t content_length = -1;
- SpdyHeaderBlock block;
- ASSERT_TRUE(
- SpdyUtils::CopyAndValidateHeaders(*headers, &content_length, &block));
- EXPECT_THAT(block,
- UnorderedElementsAre(
- Pair("foo", "foovalue"), Pair("bar", "barvalue"),
- Pair("content-length", absl::string_view("9000000000")),
- Pair("baz", "")));
- EXPECT_EQ(9000000000, content_length);
-}
-
-TEST_F(CopyAndValidateHeaders, NonDigitContentLength) {
- // Section 3.3.2 of RFC 7230 defines content-length as being only digits.
- // Number parsers might accept symbols like a leading plus; test that this
- // fails to parse.
- auto headers = FromList({{"content-length", "+123"},
- {"foo", "foovalue"},
- {"bar", "barvalue"},
- {"baz", ""}});
- int64_t content_length = -1;
- SpdyHeaderBlock block;
- EXPECT_FALSE(
- SpdyUtils::CopyAndValidateHeaders(*headers, &content_length, &block));
-}
-
-TEST_F(CopyAndValidateHeaders, MultipleValues) {
- auto headers = FromList({{"foo", "foovalue"},
- {"bar", "barvalue"},
- {"baz", ""},
- {"foo", "boo"},
- {"baz", "buzz"}});
- int64_t content_length = -1;
- SpdyHeaderBlock block;
- ASSERT_TRUE(
- SpdyUtils::CopyAndValidateHeaders(*headers, &content_length, &block));
- EXPECT_THAT(block, UnorderedElementsAre(
- Pair("foo", absl::string_view("foovalue\0boo", 12)),
- Pair("bar", "barvalue"),
- Pair("baz", absl::string_view("\0buzz", 5))));
- EXPECT_EQ(-1, content_length);
-}
-
-TEST_F(CopyAndValidateHeaders, MoreThanTwoValues) {
- auto headers = FromList({{"set-cookie", "value1"},
- {"set-cookie", "value2"},
- {"set-cookie", "value3"}});
- int64_t content_length = -1;
- SpdyHeaderBlock block;
- ASSERT_TRUE(
- SpdyUtils::CopyAndValidateHeaders(*headers, &content_length, &block));
- EXPECT_THAT(block, UnorderedElementsAre(Pair(
- "set-cookie",
- absl::string_view("value1\0value2\0value3", 20))));
- EXPECT_EQ(-1, content_length);
-}
-
-TEST_F(CopyAndValidateHeaders, Cookie) {
- auto headers = FromList({{"foo", "foovalue"},
- {"bar", "barvalue"},
- {"cookie", "value1"},
- {"baz", ""}});
- int64_t content_length = -1;
- SpdyHeaderBlock block;
- ASSERT_TRUE(
- SpdyUtils::CopyAndValidateHeaders(*headers, &content_length, &block));
- EXPECT_THAT(block, UnorderedElementsAre(
- Pair("foo", "foovalue"), Pair("bar", "barvalue"),
- Pair("cookie", "value1"), Pair("baz", "")));
- EXPECT_EQ(-1, content_length);
-}
-
-TEST_F(CopyAndValidateHeaders, MultipleCookies) {
- auto headers = FromList({{"foo", "foovalue"},
- {"bar", "barvalue"},
- {"cookie", "value1"},
- {"baz", ""},
- {"cookie", "value2"}});
- int64_t content_length = -1;
- SpdyHeaderBlock block;
- ASSERT_TRUE(
- SpdyUtils::CopyAndValidateHeaders(*headers, &content_length, &block));
- EXPECT_THAT(block, UnorderedElementsAre(
- Pair("foo", "foovalue"), Pair("bar", "barvalue"),
- Pair("cookie", "value1; value2"), Pair("baz", "")));
- EXPECT_EQ(-1, content_length);
-}
-
-using CopyAndValidateTrailers = QuicTest;
-
-TEST_F(CopyAndValidateTrailers, SimplestValidList) {
- // Verify that the simplest trailers are valid: just a final byte offset that
- // gets parsed successfully.
- auto trailers = FromList({{kFinalOffsetHeaderKey, "1234"}});
- size_t final_byte_offset = 0;
- SpdyHeaderBlock block;
- EXPECT_TRUE(SpdyUtils::CopyAndValidateTrailers(
- *trailers, kExpectFinalByteOffset, &final_byte_offset, &block));
- EXPECT_EQ(1234u, final_byte_offset);
-}
-
-TEST_F(CopyAndValidateTrailers, EmptyTrailerListWithFinalByteOffsetExpected) {
- // An empty trailer list will fail as expected key kFinalOffsetHeaderKey is
- // not present.
- QuicHeaderList trailers;
- size_t final_byte_offset = 0;
- SpdyHeaderBlock block;
- EXPECT_FALSE(SpdyUtils::CopyAndValidateTrailers(
- trailers, kExpectFinalByteOffset, &final_byte_offset, &block));
-}
-
-TEST_F(CopyAndValidateTrailers,
- EmptyTrailerListWithFinalByteOffsetNotExpected) {
- // An empty trailer list will pass successfully if kFinalOffsetHeaderKey is
- // not expected.
- QuicHeaderList trailers;
- size_t final_byte_offset = 0;
- SpdyHeaderBlock block;
- EXPECT_TRUE(SpdyUtils::CopyAndValidateTrailers(
- trailers, kDoNotExpectFinalByteOffset, &final_byte_offset, &block));
- EXPECT_TRUE(block.empty());
-}
-
-TEST_F(CopyAndValidateTrailers, FinalByteOffsetExpectedButNotPresent) {
- // Validation fails if expected kFinalOffsetHeaderKey is not present, even if
- // the rest of the header block is valid.
- auto trailers = FromList({{"key", "value"}});
- size_t final_byte_offset = 0;
- SpdyHeaderBlock block;
- EXPECT_FALSE(SpdyUtils::CopyAndValidateTrailers(
- *trailers, kExpectFinalByteOffset, &final_byte_offset, &block));
-}
-
-TEST_F(CopyAndValidateTrailers, FinalByteOffsetNotExpectedButPresent) {
- // Validation fails if kFinalOffsetHeaderKey is present but should not be,
- // even if the rest of the header block is valid.
- auto trailers = FromList({{"key", "value"}, {kFinalOffsetHeaderKey, "1234"}});
- size_t final_byte_offset = 0;
- SpdyHeaderBlock block;
- EXPECT_FALSE(SpdyUtils::CopyAndValidateTrailers(
- *trailers, kDoNotExpectFinalByteOffset, &final_byte_offset, &block));
-}
-
-TEST_F(CopyAndValidateTrailers, FinalByteOffsetNotExpectedAndNotPresent) {
- // Validation succeeds if kFinalOffsetHeaderKey is not expected and not
- // present.
- auto trailers = FromList({{"key", "value"}});
- size_t final_byte_offset = 0;
- SpdyHeaderBlock block;
- EXPECT_TRUE(SpdyUtils::CopyAndValidateTrailers(
- *trailers, kDoNotExpectFinalByteOffset, &final_byte_offset, &block));
- EXPECT_THAT(block, UnorderedElementsAre(Pair("key", "value")));
-}
-
-TEST_F(CopyAndValidateTrailers, EmptyName) {
- // Trailer validation will fail with an empty header key, in an otherwise
- // valid block of trailers.
- auto trailers = FromList({{"", "value"}, {kFinalOffsetHeaderKey, "1234"}});
- size_t final_byte_offset = 0;
- SpdyHeaderBlock block;
- EXPECT_FALSE(SpdyUtils::CopyAndValidateTrailers(
- *trailers, kExpectFinalByteOffset, &final_byte_offset, &block));
-}
-
-TEST_F(CopyAndValidateTrailers, PseudoHeaderInTrailers) {
- // Pseudo headers are illegal in trailers.
- auto trailers =
- FromList({{":pseudo_key", "value"}, {kFinalOffsetHeaderKey, "1234"}});
- size_t final_byte_offset = 0;
- SpdyHeaderBlock block;
- EXPECT_FALSE(SpdyUtils::CopyAndValidateTrailers(
- *trailers, kExpectFinalByteOffset, &final_byte_offset, &block));
-}
-
-TEST_F(CopyAndValidateTrailers, DuplicateTrailers) {
- // Duplicate trailers are allowed, and their values are concatenated into a
- // single string delimted with '\0'. Some of the duplicate headers
- // deliberately have an empty value.
- auto trailers = FromList({{"key", "value0"},
- {"key", "value1"},
- {"key", ""},
- {"key", ""},
- {"key", "value2"},
- {"key", ""},
- {kFinalOffsetHeaderKey, "1234"},
- {"other_key", "value"},
- {"key", "non_contiguous_duplicate"}});
- size_t final_byte_offset = 0;
- SpdyHeaderBlock block;
- EXPECT_TRUE(SpdyUtils::CopyAndValidateTrailers(
- *trailers, kExpectFinalByteOffset, &final_byte_offset, &block));
- EXPECT_THAT(
- block,
- UnorderedElementsAre(
- Pair("key",
- absl::string_view(
- "value0\0value1\0\0\0value2\0\0non_contiguous_duplicate",
- 48)),
- Pair("other_key", "value")));
-}
-
-TEST_F(CopyAndValidateTrailers, DuplicateCookies) {
- // Duplicate cookie headers in trailers should be concatenated into a single
- // "; " delimted string.
- auto headers = FromList({{"cookie", " part 1"},
- {"cookie", "part 2 "},
- {"cookie", "part3"},
- {"key", "value"},
- {kFinalOffsetHeaderKey, "1234"},
- {"cookie", " non_contiguous_cookie!"}});
-
- size_t final_byte_offset = 0;
- SpdyHeaderBlock block;
- EXPECT_TRUE(SpdyUtils::CopyAndValidateTrailers(
- *headers, kExpectFinalByteOffset, &final_byte_offset, &block));
- EXPECT_THAT(
- block,
- UnorderedElementsAre(
- Pair("cookie", " part 1; part 2 ; part3; non_contiguous_cookie!"),
- Pair("key", "value")));
-}
-
-using PopulateHeaderBlockFromUrl = QuicTest;
-
-TEST_F(PopulateHeaderBlockFromUrl, NormalUsage) {
- std::string url = "https://www.google.com/index.html";
- SpdyHeaderBlock headers;
- EXPECT_TRUE(SpdyUtils::PopulateHeaderBlockFromUrl(url, &headers));
- EXPECT_EQ("https", headers[":scheme"].as_string());
- EXPECT_EQ("www.google.com", headers[":authority"].as_string());
- EXPECT_EQ("/index.html", headers[":path"].as_string());
-}
-
-TEST_F(PopulateHeaderBlockFromUrl, UrlWithNoPath) {
- std::string url = "https://www.google.com";
- SpdyHeaderBlock headers;
- EXPECT_TRUE(SpdyUtils::PopulateHeaderBlockFromUrl(url, &headers));
- EXPECT_EQ("https", headers[":scheme"].as_string());
- EXPECT_EQ("www.google.com", headers[":authority"].as_string());
- EXPECT_EQ("/", headers[":path"].as_string());
-}
-
-TEST_F(PopulateHeaderBlockFromUrl, Failure) {
- SpdyHeaderBlock headers;
- EXPECT_FALSE(SpdyUtils::PopulateHeaderBlockFromUrl("/", &headers));
- EXPECT_FALSE(SpdyUtils::PopulateHeaderBlockFromUrl("/index.html", &headers));
- EXPECT_FALSE(
- 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) {
- ParsedQuicVersionVector supported_versions = AllSupportedVersions();
- spdy::SpdyAltSvcWireFormat::AlternativeService entry;
- for (const ParsedQuicVersion& version : supported_versions) {
- entry.protocol_id = AlpnForVersion(version);
- ParsedQuicVersion expected_version = version;
- // Versions with share an ALPN with v1 are currently unable to be
- // advertised with Alt-Svc.
- if (entry.protocol_id == AlpnForVersion(ParsedQuicVersion::RFCv1()) &&
- version != ParsedQuicVersion::RFCv1()) {
- expected_version = ParsedQuicVersion::RFCv1();
- }
- EXPECT_EQ(expected_version, SpdyUtils::ExtractQuicVersionFromAltSvcEntry(
- entry, supported_versions))
- << "version: " << version;
- }
-}
-
-TEST_F(ExtractQuicVersionFromAltSvcEntry, UnsupportedVersion) {
- spdy::SpdyAltSvcWireFormat::AlternativeService entry;
- entry.protocol_id = "quic";
- EXPECT_EQ(ParsedQuicVersion::Unsupported(),
- SpdyUtils::ExtractQuicVersionFromAltSvcEntry(
- entry, AllSupportedVersions()));
-}
-
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/http/web_transport_http3.cc b/chromium/net/third_party/quiche/src/quic/core/http/web_transport_http3.cc
deleted file mode 100644
index c2d02f0cf67..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/http/web_transport_http3.cc
+++ /dev/null
@@ -1,545 +0,0 @@
-// Copyright 2021 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 "quic/core/http/web_transport_http3.h"
-
-#include <limits>
-#include <memory>
-
-#include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
-#include "quic/core/http/capsule.h"
-#include "quic/core/http/quic_spdy_session.h"
-#include "quic/core/http/quic_spdy_stream.h"
-#include "quic/core/quic_data_reader.h"
-#include "quic/core/quic_data_writer.h"
-#include "quic/core/quic_error_codes.h"
-#include "quic/core/quic_stream.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_utils.h"
-#include "quic/core/quic_versions.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "common/platform/api/quiche_logging.h"
-
-#define ENDPOINT \
- (session_->perspective() == Perspective::IS_SERVER ? "Server: " : "Client: ")
-
-namespace quic {
-
-namespace {
-class QUIC_NO_EXPORT NoopWebTransportVisitor : public WebTransportVisitor {
- void OnSessionReady(const spdy::SpdyHeaderBlock&) override {}
- void OnSessionClosed(WebTransportSessionError /*error_code*/,
- const std::string& /*error_message*/) override {}
- void OnIncomingBidirectionalStreamAvailable() override {}
- void OnIncomingUnidirectionalStreamAvailable() override {}
- void OnDatagramReceived(absl::string_view /*datagram*/) override {}
- void OnCanCreateNewOutgoingBidirectionalStream() override {}
- void OnCanCreateNewOutgoingUnidirectionalStream() override {}
-};
-} // namespace
-
-WebTransportHttp3::WebTransportHttp3(QuicSpdySession* session,
- QuicSpdyStream* connect_stream,
- WebTransportSessionId id,
- bool attempt_to_use_datagram_contexts)
- : session_(session),
- connect_stream_(connect_stream),
- id_(id),
- visitor_(std::make_unique<NoopWebTransportVisitor>()) {
- 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();
- }
- }
-}
-
-void WebTransportHttp3::AssociateStream(QuicStreamId stream_id) {
- streams_.insert(stream_id);
-
- ParsedQuicVersion version = session_->version();
- if (QuicUtils::IsOutgoingStreamId(version, stream_id,
- session_->perspective())) {
- return;
- }
- if (QuicUtils::IsBidirectionalStreamId(stream_id, version)) {
- incoming_bidirectional_streams_.push_back(stream_id);
- visitor_->OnIncomingBidirectionalStreamAvailable();
- } else {
- incoming_unidirectional_streams_.push_back(stream_id);
- visitor_->OnIncomingUnidirectionalStreamAvailable();
- }
-}
-
-void WebTransportHttp3::OnConnectStreamClosing() {
- // Copy the stream list before iterating over it, as calls to ResetStream()
- // can potentially mutate the |session_| list.
- std::vector<QuicStreamId> streams(streams_.begin(), streams_.end());
- streams_.clear();
- 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();
-
- MaybeNotifyClose();
-}
-
-void WebTransportHttp3::CloseSession(WebTransportSessionError error_code,
- absl::string_view error_message) {
- if (close_sent_) {
- QUIC_BUG(WebTransportHttp3 close sent twice)
- << "Calling WebTransportHttp3::CloseSession() more than once is not "
- "allowed.";
- return;
- }
- close_sent_ = true;
-
- // There can be a race between us trying to send our close and peer sending
- // one. If we received a close, however, we cannot send ours since we already
- // closed the stream in response.
- if (close_received_) {
- QUIC_DLOG(INFO) << "Not sending CLOSE_WEBTRANSPORT_SESSION as we've "
- "already sent one from peer.";
- return;
- }
-
- error_code_ = error_code;
- error_message_ = std::string(error_message);
- QuicConnection::ScopedPacketFlusher flusher(
- connect_stream_->spdy_session()->connection());
- connect_stream_->WriteCapsule(
- Capsule::CloseWebTransportSession(error_code, error_message),
- /*fin=*/true);
-}
-
-void WebTransportHttp3::OnCloseReceived(WebTransportSessionError error_code,
- absl::string_view error_message) {
- if (close_received_) {
- QUIC_BUG(WebTransportHttp3 notified of close received twice)
- << "WebTransportHttp3::OnCloseReceived() may be only called once.";
- }
- close_received_ = true;
-
- // If the peer has sent a close after we sent our own, keep the local error.
- if (close_sent_) {
- QUIC_DLOG(INFO) << "Ignoring received CLOSE_WEBTRANSPORT_SESSION as we've "
- "already sent our own.";
- return;
- }
-
- error_code_ = error_code;
- error_message_ = std::string(error_message);
- connect_stream_->WriteOrBufferBody("", /*fin=*/true);
- MaybeNotifyClose();
-}
-
-void WebTransportHttp3::OnConnectStreamFinReceived() {
- // If we already received a CLOSE_WEBTRANSPORT_SESSION capsule, we don't need
- // to do anything about receiving a FIN, since we already sent one in
- // response.
- if (close_received_) {
- return;
- }
- close_received_ = true;
- if (close_sent_) {
- QUIC_DLOG(INFO) << "Ignoring received FIN as we've already sent our close.";
- return;
- }
-
- connect_stream_->WriteOrBufferBody("", /*fin=*/true);
- MaybeNotifyClose();
-}
-
-void WebTransportHttp3::CloseSessionWithFinOnlyForTests() {
- QUICHE_DCHECK(!close_sent_);
- close_sent_ = true;
- if (close_received_) {
- return;
- }
-
- connect_stream_->WriteOrBufferBody("", /*fin=*/true);
-}
-
-void WebTransportHttp3::HeadersReceived(const spdy::SpdyHeaderBlock& headers) {
- if (session_->perspective() == Perspective::IS_CLIENT) {
- int status_code;
- if (!QuicSpdyStream::ParseHeaderStatusCode(headers, &status_code)) {
- QUIC_DVLOG(1) << ENDPOINT
- << "Received WebTransport headers from server without "
- "a valid status code, rejecting.";
- rejection_reason_ = WebTransportHttp3RejectionReason::kNoStatusCode;
- return;
- }
- bool valid_status = status_code >= 200 && status_code <= 299;
- if (!valid_status) {
- QUIC_DVLOG(1) << ENDPOINT
- << "Received WebTransport headers from server with "
- "status code "
- << status_code << ", rejecting.";
- rejection_reason_ = WebTransportHttp3RejectionReason::kWrongStatusCode;
- 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");
- if (draft_version_it == headers.end()) {
- QUIC_DVLOG(1) << ENDPOINT
- << "Received WebTransport headers from server without "
- "a draft version, rejecting.";
- rejection_reason_ =
- WebTransportHttp3RejectionReason::kMissingDraftVersion;
- return;
- }
- if (draft_version_it->second != "draft02") {
- QUIC_DVLOG(1) << ENDPOINT
- << "Received WebTransport headers from server with "
- "an unknown draft version ("
- << draft_version_it->second << "), rejecting.";
- rejection_reason_ =
- WebTransportHttp3RejectionReason::kUnsupportedDraftVersion;
- return;
- }
- }
- }
-
- QUIC_DVLOG(1) << ENDPOINT << "WebTransport session " << id_ << " ready.";
- ready_ = true;
- visitor_->OnSessionReady(headers);
- session_->ProcessBufferedWebTransportStreamsForSession(this);
-}
-
-WebTransportStream* WebTransportHttp3::AcceptIncomingBidirectionalStream() {
- while (!incoming_bidirectional_streams_.empty()) {
- QuicStreamId id = incoming_bidirectional_streams_.front();
- incoming_bidirectional_streams_.pop_front();
- QuicSpdyStream* stream = session_->GetOrCreateSpdyDataStream(id);
- if (stream == nullptr) {
- // Skip the streams that were reset in between the time they were
- // receieved and the time the client has polled for them.
- continue;
- }
- return stream->web_transport_stream();
- }
- return nullptr;
-}
-
-WebTransportStream* WebTransportHttp3::AcceptIncomingUnidirectionalStream() {
- while (!incoming_unidirectional_streams_.empty()) {
- QuicStreamId id = incoming_unidirectional_streams_.front();
- incoming_unidirectional_streams_.pop_front();
- QuicStream* stream = session_->GetOrCreateStream(id);
- if (stream == nullptr) {
- // Skip the streams that were reset in between the time they were
- // receieved and the time the client has polled for them.
- continue;
- }
- return static_cast<WebTransportHttp3UnidirectionalStream*>(stream)
- ->interface();
- }
- return nullptr;
-}
-
-bool WebTransportHttp3::CanOpenNextOutgoingBidirectionalStream() {
- return session_->CanOpenOutgoingBidirectionalWebTransportStream(id_);
-}
-bool WebTransportHttp3::CanOpenNextOutgoingUnidirectionalStream() {
- return session_->CanOpenOutgoingUnidirectionalWebTransportStream(id_);
-}
-WebTransportStream* WebTransportHttp3::OpenOutgoingBidirectionalStream() {
- QuicSpdyStream* stream =
- session_->CreateOutgoingBidirectionalWebTransportStream(this);
- if (stream == nullptr) {
- // If stream cannot be created due to flow control or other errors, return
- // nullptr.
- return nullptr;
- }
- return stream->web_transport_stream();
-}
-
-WebTransportStream* WebTransportHttp3::OpenOutgoingUnidirectionalStream() {
- WebTransportHttp3UnidirectionalStream* stream =
- session_->CreateOutgoingUnidirectionalWebTransportStream(this);
- if (stream == nullptr) {
- // If stream cannot be created due to flow control, return nullptr.
- return nullptr;
- }
- return stream->interface();
-}
-
-MessageStatus WebTransportHttp3::SendOrQueueDatagram(QuicMemSlice datagram) {
- return connect_stream_->SendHttp3Datagram(
- context_id_, absl::string_view(datagram.data(), datagram.length()));
-}
-
-QuicByteCount WebTransportHttp3::GetMaxDatagramSize() const {
- return connect_stream_->GetMaxDatagramSize(context_id_);
-}
-
-void WebTransportHttp3::SetDatagramMaxTimeInQueue(
- QuicTime::Delta max_time_in_queue) {
- connect_stream_->SetMaxDatagramTimeInQueue(max_time_in_queue);
-}
-
-void WebTransportHttp3::OnHttp3Datagram(
- QuicStreamId stream_id, absl::optional<QuicDatagramContextId> context_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;
- }
- close_notified_ = true;
- visitor_->OnSessionClosed(error_code_, error_message_);
-}
-
-WebTransportHttp3UnidirectionalStream::WebTransportHttp3UnidirectionalStream(
- PendingStream* pending, QuicSpdySession* session)
- : QuicStream(pending, session, /*is_static=*/false),
- session_(session),
- adapter_(session, this, sequencer()),
- needs_to_send_preamble_(false) {}
-
-WebTransportHttp3UnidirectionalStream::WebTransportHttp3UnidirectionalStream(
- QuicStreamId id, QuicSpdySession* session, WebTransportSessionId session_id)
- : QuicStream(id, session, /*is_static=*/false, WRITE_UNIDIRECTIONAL),
- session_(session),
- adapter_(session, this, sequencer()),
- session_id_(session_id),
- needs_to_send_preamble_(true) {}
-
-void WebTransportHttp3UnidirectionalStream::WritePreamble() {
- if (!needs_to_send_preamble_ || !session_id_.has_value()) {
- QUIC_BUG(WebTransportHttp3UnidirectionalStream duplicate preamble)
- << ENDPOINT << "Sending preamble on stream ID " << id()
- << " at the wrong time.";
- OnUnrecoverableError(QUIC_INTERNAL_ERROR,
- "Attempting to send a WebTransport unidirectional "
- "stream preamble at the wrong time.");
- return;
- }
-
- QuicConnection::ScopedPacketFlusher flusher(session_->connection());
- char buffer[sizeof(uint64_t) * 2]; // varint62, varint62
- QuicDataWriter writer(sizeof(buffer), buffer);
- bool success = true;
- success = success && writer.WriteVarInt62(kWebTransportUnidirectionalStream);
- success = success && writer.WriteVarInt62(*session_id_);
- QUICHE_DCHECK(success);
- WriteOrBufferData(absl::string_view(buffer, writer.length()), /*fin=*/false,
- /*ack_listener=*/nullptr);
- QUIC_DVLOG(1) << ENDPOINT << "Sent stream type and session ID ("
- << *session_id_ << ") on WebTransport stream " << id();
- needs_to_send_preamble_ = false;
-}
-
-bool WebTransportHttp3UnidirectionalStream::ReadSessionId() {
- iovec iov;
- if (!sequencer()->GetReadableRegion(&iov)) {
- return false;
- }
- QuicDataReader reader(static_cast<const char*>(iov.iov_base), iov.iov_len);
- WebTransportSessionId session_id;
- uint8_t session_id_length = reader.PeekVarInt62Length();
- if (!reader.ReadVarInt62(&session_id)) {
- // 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()) {
- QUIC_DLOG(WARNING)
- << ENDPOINT << "Failed to associate WebTransport stream " << id()
- << " with a session because the stream ended prematurely.";
- sequencer()->MarkConsumed(sequencer()->NumBytesBuffered());
- }
- return false;
- }
- sequencer()->MarkConsumed(session_id_length);
- session_id_ = session_id;
- session_->AssociateIncomingWebTransportStreamWithSession(session_id, id());
- return true;
-}
-
-void WebTransportHttp3UnidirectionalStream::OnDataAvailable() {
- if (!session_id_.has_value()) {
- if (!ReadSessionId()) {
- return;
- }
- }
-
- adapter_.OnDataAvailable();
-}
-
-void WebTransportHttp3UnidirectionalStream::OnCanWriteNewData() {
- adapter_.OnCanWriteNewData();
-}
-
-void WebTransportHttp3UnidirectionalStream::OnClose() {
- QuicStream::OnClose();
-
- if (!session_id_.has_value()) {
- return;
- }
- WebTransportHttp3* session = session_->GetWebTransportSession(*session_id_);
- if (session == nullptr) {
- QUIC_DLOG(WARNING) << ENDPOINT << "WebTransport stream " << id()
- << " attempted to notify parent session " << *session_id_
- << ", but the session could not be found.";
- return;
- }
- session->OnStreamClosed(id());
-}
-
-void WebTransportHttp3UnidirectionalStream::OnStreamReset(
- const QuicRstStreamFrame& frame) {
- if (adapter_.visitor() != nullptr) {
- adapter_.visitor()->OnResetStreamReceived(
- Http3ErrorToWebTransportOrDefault(frame.ietf_error_code));
- }
- QuicStream::OnStreamReset(frame);
-}
-bool WebTransportHttp3UnidirectionalStream::OnStopSending(
- QuicResetStreamError error) {
- if (adapter_.visitor() != nullptr) {
- adapter_.visitor()->OnStopSendingReceived(
- Http3ErrorToWebTransportOrDefault(error.ietf_application_code()));
- }
- return QuicStream::OnStopSending(error);
-}
-void WebTransportHttp3UnidirectionalStream::OnWriteSideInDataRecvdState() {
- if (adapter_.visitor() != nullptr) {
- adapter_.visitor()->OnWriteSideInDataRecvdState();
- }
-
- QuicStream::OnWriteSideInDataRecvdState();
-}
-
-namespace {
-constexpr uint64_t kWebTransportMappedErrorCodeFirst = 0x52e4a40fa8db;
-constexpr uint64_t kWebTransportMappedErrorCodeLast = 0x52e4a40fa9e2;
-constexpr WebTransportStreamError kDefaultWebTransportError = 0;
-} // namespace
-
-absl::optional<WebTransportStreamError> Http3ErrorToWebTransport(
- uint64_t http3_error_code) {
- // Ensure the code is within the valid range.
- if (http3_error_code < kWebTransportMappedErrorCodeFirst ||
- http3_error_code > kWebTransportMappedErrorCodeLast) {
- return absl::nullopt;
- }
- // Exclude GREASE codepoints.
- if ((http3_error_code - 0x21) % 0x1f == 0) {
- return absl::nullopt;
- }
-
- uint64_t shifted = http3_error_code - kWebTransportMappedErrorCodeFirst;
- uint64_t result = shifted - shifted / 0x1f;
- QUICHE_DCHECK_LE(result, std::numeric_limits<uint8_t>::max());
- return result;
-}
-
-WebTransportStreamError Http3ErrorToWebTransportOrDefault(
- uint64_t http3_error_code) {
- absl::optional<WebTransportStreamError> result =
- Http3ErrorToWebTransport(http3_error_code);
- return result.has_value() ? *result : kDefaultWebTransportError;
-}
-
-uint64_t WebTransportErrorToHttp3(
- WebTransportStreamError webtransport_error_code) {
- return kWebTransportMappedErrorCodeFirst + webtransport_error_code +
- webtransport_error_code / 0x1e;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/http/web_transport_http3.h b/chromium/net/third_party/quiche/src/quic/core/http/web_transport_http3.h
deleted file mode 100644
index 542b9418a73..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/http/web_transport_http3.h
+++ /dev/null
@@ -1,197 +0,0 @@
-// Copyright 2021 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_HTTP_WEB_TRANSPORT_HTTP3_H_
-#define QUICHE_QUIC_CORE_HTTP_WEB_TRANSPORT_HTTP3_H_
-
-#include <memory>
-
-#include "absl/base/attributes.h"
-#include "absl/container/flat_hash_set.h"
-#include "absl/types/optional.h"
-#include "quic/core/http/quic_spdy_session.h"
-#include "quic/core/http/web_transport_stream_adapter.h"
-#include "quic/core/quic_error_codes.h"
-#include "quic/core/quic_stream.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/web_transport_interface.h"
-#include "spdy/core/spdy_header_block.h"
-
-namespace quic {
-
-class QuicSpdySession;
-class QuicSpdyStream;
-
-enum class WebTransportHttp3RejectionReason {
- kNone,
- kNoStatusCode,
- kWrongStatusCode,
- kMissingDraftVersion,
- kUnsupportedDraftVersion,
-};
-
-// A session of WebTransport over HTTP/3. The session is owned by
-// QuicSpdyStream object for the CONNECT stream that established it.
-//
-// WebTransport over HTTP/3 specification:
-// <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);
-
- void HeadersReceived(const spdy::SpdyHeaderBlock& headers);
- void SetVisitor(std::unique_ptr<WebTransportVisitor> visitor) {
- visitor_ = std::move(visitor);
- }
-
- 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); }
- void OnConnectStreamClosing();
-
- size_t NumberOfAssociatedStreams() { return streams_.size(); }
-
- void CloseSession(WebTransportSessionError error_code,
- absl::string_view error_message) override;
- void OnCloseReceived(WebTransportSessionError error_code,
- absl::string_view error_message);
- void OnConnectStreamFinReceived();
-
- // It is legal for WebTransport to be closed without a
- // CLOSE_WEBTRANSPORT_SESSION capsule. We always send a capsule, but we still
- // need to ensure we handle this case correctly.
- void CloseSessionWithFinOnlyForTests();
-
- // Return the earliest incoming stream that has been received by the session
- // but has not been accepted. Returns nullptr if there are no incoming
- // streams.
- WebTransportStream* AcceptIncomingBidirectionalStream() override;
- WebTransportStream* AcceptIncomingUnidirectionalStream() override;
-
- bool CanOpenNextOutgoingBidirectionalStream() override;
- bool CanOpenNextOutgoingUnidirectionalStream() override;
- WebTransportStream* OpenOutgoingBidirectionalStream() override;
- WebTransportStream* OpenOutgoingUnidirectionalStream() override;
-
- MessageStatus SendOrQueueDatagram(QuicMemSlice datagram) override;
- QuicByteCount GetMaxDatagramSize() const override;
- void SetDatagramMaxTimeInQueue(QuicTime::Delta max_time_in_queue) override;
-
- // 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_;
- }
-
- private:
- // Notifies the visitor that the connection has been closed. Ensures that the
- // visitor is only ever called once.
- void MaybeNotifyClose();
-
- 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_;
- quiche::QuicheCircularDeque<QuicStreamId> incoming_unidirectional_streams_;
-
- bool close_sent_ = false;
- bool close_received_ = false;
- bool close_notified_ = false;
-
- WebTransportHttp3RejectionReason rejection_reason_ =
- WebTransportHttp3RejectionReason::kNone;
- // Those are set to default values, which are used if the session is not
- // closed cleanly using an appropriate capsule.
- WebTransportSessionError error_code_ = 0;
- std::string error_message_ = "";
-};
-
-class QUIC_EXPORT_PRIVATE WebTransportHttp3UnidirectionalStream
- : public QuicStream {
- public:
- // Incoming stream.
- WebTransportHttp3UnidirectionalStream(PendingStream* pending,
- QuicSpdySession* session);
- // Outgoing stream.
- WebTransportHttp3UnidirectionalStream(QuicStreamId id,
- QuicSpdySession* session,
- WebTransportSessionId session_id);
-
- // Sends the stream type and the session ID on the stream.
- void WritePreamble();
-
- // Implementation of QuicStream.
- void OnDataAvailable() override;
- void OnCanWriteNewData() override;
- void OnClose() override;
- void OnStreamReset(const QuicRstStreamFrame& frame) override;
- bool OnStopSending(QuicResetStreamError error) override;
- void OnWriteSideInDataRecvdState() override;
-
- WebTransportStream* interface() { return &adapter_; }
- void SetUnblocked() { sequencer()->SetUnblocked(); }
-
- private:
- QuicSpdySession* session_;
- WebTransportStreamAdapter adapter_;
- absl::optional<WebTransportSessionId> session_id_;
- bool needs_to_send_preamble_;
-
- bool ReadSessionId();
- // Closes the stream if all of the data has been received.
- void MaybeCloseIncompleteStream();
-};
-
-// Remaps HTTP/3 error code into a WebTransport error code. Returns nullopt if
-// the provided code is outside of valid range.
-QUIC_EXPORT_PRIVATE absl::optional<WebTransportStreamError>
-Http3ErrorToWebTransport(uint64_t http3_error_code);
-
-// Same as above, but returns default error value (zero) when none could be
-// mapped.
-QUIC_EXPORT_PRIVATE WebTransportStreamError
-Http3ErrorToWebTransportOrDefault(uint64_t http3_error_code);
-
-// Remaps WebTransport error code into an HTTP/3 error code.
-QUIC_EXPORT_PRIVATE uint64_t
-WebTransportErrorToHttp3(WebTransportStreamError webtransport_error_code);
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_HTTP_WEB_TRANSPORT_HTTP3_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/http/web_transport_http3_test.cc b/chromium/net/third_party/quiche/src/quic/core/http/web_transport_http3_test.cc
deleted file mode 100644
index 0cf5b946200..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/http/web_transport_http3_test.cc
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright 2021 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 "quic/core/http/web_transport_http3.h"
-
-#include <cstdint>
-#include <limits>
-
-#include "absl/types/optional.h"
-#include "quic/platform/api/quic_test.h"
-
-namespace quic {
-namespace {
-
-using ::testing::Optional;
-
-TEST(WebTransportHttp3Test, ErrorCodesToHttp3) {
- EXPECT_EQ(0x52e4a40fa8dbu, WebTransportErrorToHttp3(0x00));
- EXPECT_EQ(0x52e4a40fa9e2u, WebTransportErrorToHttp3(0xff));
-
- EXPECT_EQ(0x52e4a40fa8f7u, WebTransportErrorToHttp3(0x1c));
- EXPECT_EQ(0x52e4a40fa8f8u, WebTransportErrorToHttp3(0x1d));
- // 0x52e4a40fa8f9 is a GREASE codepoint
- EXPECT_EQ(0x52e4a40fa8fau, WebTransportErrorToHttp3(0x1e));
-}
-
-TEST(WebTransportHttp3Test, ErrorCodesToWebTransport) {
- EXPECT_THAT(Http3ErrorToWebTransport(0x52e4a40fa8db), Optional(0x00));
- EXPECT_THAT(Http3ErrorToWebTransport(0x52e4a40fa9e2), Optional(0xff));
-
- EXPECT_THAT(Http3ErrorToWebTransport(0x52e4a40fa8f7), Optional(0x1cu));
- EXPECT_THAT(Http3ErrorToWebTransport(0x52e4a40fa8f8), Optional(0x1du));
- EXPECT_THAT(Http3ErrorToWebTransport(0x52e4a40fa8f9), absl::nullopt);
- EXPECT_THAT(Http3ErrorToWebTransport(0x52e4a40fa8fa), Optional(0x1eu));
-
- EXPECT_EQ(Http3ErrorToWebTransport(0), absl::nullopt);
- EXPECT_EQ(Http3ErrorToWebTransport(std::numeric_limits<uint64_t>::max()),
- absl::nullopt);
-}
-
-TEST(WebTransportHttp3Test, ErrorCodeRoundTrip) {
- for (int error = 0; error < 256; error++) {
- uint64_t http_error = WebTransportErrorToHttp3(error);
- absl::optional<WebTransportStreamError> mapped_back =
- quic::Http3ErrorToWebTransport(http_error);
- EXPECT_THAT(mapped_back, Optional(error));
- }
-}
-
-} // namespace
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/http/web_transport_stream_adapter.cc b/chromium/net/third_party/quiche/src/quic/core/http/web_transport_stream_adapter.cc
deleted file mode 100644
index bea13770756..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/http/web_transport_stream_adapter.cc
+++ /dev/null
@@ -1,127 +0,0 @@
-// Copyright 2021 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 "quic/core/http/web_transport_stream_adapter.h"
-
-#include "quic/core/http/web_transport_http3.h"
-#include "quic/core/quic_error_codes.h"
-
-namespace quic {
-
-WebTransportStreamAdapter::WebTransportStreamAdapter(
- QuicSession* session,
- QuicStream* stream,
- QuicStreamSequencer* sequencer)
- : session_(session), stream_(stream), sequencer_(sequencer) {}
-
-WebTransportStream::ReadResult WebTransportStreamAdapter::Read(
- char* buffer,
- size_t buffer_size) {
- iovec iov;
- iov.iov_base = buffer;
- iov.iov_len = buffer_size;
- const size_t result = sequencer_->Readv(&iov, 1);
- if (!fin_read_ && sequencer_->IsClosed()) {
- fin_read_ = true;
- stream_->OnFinRead();
- }
- return ReadResult{result, sequencer_->IsClosed()};
-}
-
-WebTransportStream::ReadResult WebTransportStreamAdapter::Read(
- std::string* output) {
- const size_t old_size = output->size();
- const size_t bytes_to_read = ReadableBytes();
- output->resize(old_size + bytes_to_read);
- ReadResult result = Read(&(*output)[old_size], bytes_to_read);
- QUICHE_DCHECK_EQ(bytes_to_read, result.bytes_read);
- output->resize(old_size + result.bytes_read);
- return result;
-}
-
-bool WebTransportStreamAdapter::Write(absl::string_view data) {
- if (!CanWrite()) {
- return false;
- }
-
- QuicMemSlice memslice(QuicBuffer::Copy(
- session_->connection()->helper()->GetStreamSendBufferAllocator(), data));
- QuicConsumedData consumed =
- stream_->WriteMemSlices(absl::MakeSpan(&memslice, 1), /*fin=*/false);
-
- if (consumed.bytes_consumed == data.size()) {
- return true;
- }
- if (consumed.bytes_consumed == 0) {
- return false;
- }
- // WebTransportStream::Write() is an all-or-nothing write API. To achieve
- // that property, it relies on WriteMemSlices() being an all-or-nothing API.
- // If WriteMemSlices() fails to provide that guarantee, we have no way to
- // communicate a partial write to the caller, and thus it's safer to just
- // close the connection.
- QUIC_BUG(WebTransportStreamAdapter partial write)
- << "WriteMemSlices() unexpectedly partially consumed the input "
- "data, provided: "
- << data.size() << ", written: " << consumed.bytes_consumed;
- stream_->OnUnrecoverableError(
- QUIC_INTERNAL_ERROR,
- "WriteMemSlices() unexpectedly partially consumed the input data");
- return false;
-}
-
-bool WebTransportStreamAdapter::SendFin() {
- if (!CanWrite()) {
- return false;
- }
-
- QuicMemSlice empty;
- QuicConsumedData consumed =
- stream_->WriteMemSlices(absl::MakeSpan(&empty, 1), /*fin=*/true);
- QUICHE_DCHECK_EQ(consumed.bytes_consumed, 0u);
- return consumed.fin_consumed;
-}
-
-bool WebTransportStreamAdapter::CanWrite() const {
- return stream_->CanWriteNewData() && !stream_->write_side_closed();
-}
-
-size_t WebTransportStreamAdapter::ReadableBytes() const {
- return sequencer_->ReadableBytes();
-}
-
-void WebTransportStreamAdapter::OnDataAvailable() {
- if (visitor_ == nullptr) {
- return;
- }
- const bool fin_readable = sequencer_->IsClosed() && !fin_read_;
- if (ReadableBytes() == 0 && !fin_readable) {
- return;
- }
- visitor_->OnCanRead();
-}
-
-void WebTransportStreamAdapter::OnCanWriteNewData() {
- // Ensure the origin check has been completed, as the stream can be notified
- // about being writable before that.
- if (!CanWrite()) {
- return;
- }
- if (visitor_ != nullptr) {
- visitor_->OnCanWrite();
- }
-}
-
-void WebTransportStreamAdapter::ResetWithUserCode(
- WebTransportStreamError error) {
- stream_->ResetWriteSide(QuicResetStreamError(
- QUIC_STREAM_CANCELLED, WebTransportErrorToHttp3(error)));
-}
-
-void WebTransportStreamAdapter::SendStopSending(WebTransportStreamError error) {
- stream_->SendStopSending(QuicResetStreamError(
- QUIC_STREAM_CANCELLED, WebTransportErrorToHttp3(error)));
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/http/web_transport_stream_adapter.h b/chromium/net/third_party/quiche/src/quic/core/http/web_transport_stream_adapter.h
deleted file mode 100644
index a761f6fac03..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/http/web_transport_stream_adapter.h
+++ /dev/null
@@ -1,66 +0,0 @@
-// Copyright 2021 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_WEB_TRANSPORT_STREAM_ADAPTER_H_
-#define QUICHE_QUIC_CORE_WEB_TRANSPORT_STREAM_ADAPTER_H_
-
-#include "quic/core/quic_session.h"
-#include "quic/core/quic_stream.h"
-#include "quic/core/quic_stream_sequencer.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/web_transport_interface.h"
-
-namespace quic {
-
-// Converts WebTransportStream API calls into QuicStream API calls. The users
-// of this class can either subclass it, or wrap around it.
-class QUIC_EXPORT_PRIVATE WebTransportStreamAdapter
- : public WebTransportStream {
- public:
- WebTransportStreamAdapter(QuicSession* session,
- QuicStream* stream,
- QuicStreamSequencer* sequencer);
-
- // WebTransportStream implementation.
- ABSL_MUST_USE_RESULT ReadResult Read(char* buffer,
- size_t buffer_size) override;
- ABSL_MUST_USE_RESULT ReadResult Read(std::string* output) override;
- ABSL_MUST_USE_RESULT bool Write(absl::string_view data) override;
- ABSL_MUST_USE_RESULT bool SendFin() override;
- bool CanWrite() const override;
- size_t ReadableBytes() const override;
- void SetVisitor(std::unique_ptr<WebTransportStreamVisitor> visitor) override {
- visitor_ = std::move(visitor);
- }
- QuicStreamId GetStreamId() const override { return stream_->id(); }
-
- void ResetWithUserCode(WebTransportStreamError error) override;
- void ResetDueToInternalError() override {
- stream_->Reset(QUIC_STREAM_INTERNAL_ERROR);
- }
- void SendStopSending(WebTransportStreamError error) override;
- void MaybeResetDueToStreamObjectGone() override {
- if (stream_->write_side_closed() && stream_->read_side_closed()) {
- return;
- }
- stream_->Reset(QUIC_STREAM_CANCELLED);
- }
-
- WebTransportStreamVisitor* visitor() override { return visitor_.get(); }
-
- // Calls that need to be passed from the corresponding QuicStream methods.
- void OnDataAvailable();
- void OnCanWriteNewData();
-
- private:
- QuicSession* session_; // Unowned.
- QuicStream* stream_; // Unowned.
- QuicStreamSequencer* sequencer_; // Unowned.
- std::unique_ptr<WebTransportStreamVisitor> visitor_;
- bool fin_read_ = false;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_WEB_TRANSPORT_STREAM_ADAPTER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/legacy_quic_stream_id_manager.cc b/chromium/net/third_party/quiche/src/quic/core/legacy_quic_stream_id_manager.cc
deleted file mode 100644
index 19128abf2ca..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/legacy_quic_stream_id_manager.cc
+++ /dev/null
@@ -1,142 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-#include "quic/core/legacy_quic_stream_id_manager.h"
-
-#include "quic/core/quic_session.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_utils.h"
-#include "quic/core/quic_versions.h"
-
-namespace quic {
-
-LegacyQuicStreamIdManager::LegacyQuicStreamIdManager(
- Perspective perspective,
- QuicTransportVersion transport_version,
- size_t max_open_outgoing_streams,
- size_t max_open_incoming_streams)
- : perspective_(perspective),
- transport_version_(transport_version),
- max_open_outgoing_streams_(max_open_outgoing_streams),
- max_open_incoming_streams_(max_open_incoming_streams),
- next_outgoing_stream_id_(
- QuicUtils::GetFirstBidirectionalStreamId(transport_version_,
- perspective_)),
- largest_peer_created_stream_id_(
- perspective_ == Perspective::IS_SERVER
- ? (QuicVersionUsesCryptoFrames(transport_version_)
- ? QuicUtils::GetInvalidStreamId(transport_version_)
- : QuicUtils::GetCryptoStreamId(transport_version_))
- : QuicUtils::GetInvalidStreamId(transport_version_)),
- num_open_incoming_streams_(0),
- num_open_outgoing_streams_(0) {}
-
-LegacyQuicStreamIdManager::~LegacyQuicStreamIdManager() {}
-
-bool LegacyQuicStreamIdManager::CanOpenNextOutgoingStream() const {
- QUICHE_DCHECK_LE(num_open_outgoing_streams_, max_open_outgoing_streams_);
- QUIC_DLOG_IF(INFO, num_open_outgoing_streams_ == max_open_outgoing_streams_)
- << "Failed to create a new outgoing stream. "
- << "Already " << num_open_outgoing_streams_ << " open.";
- return num_open_outgoing_streams_ < max_open_outgoing_streams_;
-}
-
-bool LegacyQuicStreamIdManager::CanOpenIncomingStream() const {
- return num_open_incoming_streams_ < max_open_incoming_streams_;
-}
-
-bool LegacyQuicStreamIdManager::MaybeIncreaseLargestPeerStreamId(
- const QuicStreamId stream_id) {
- available_streams_.erase(stream_id);
-
- if (largest_peer_created_stream_id_ !=
- QuicUtils::GetInvalidStreamId(transport_version_) &&
- stream_id <= largest_peer_created_stream_id_) {
- return true;
- }
-
- // Check if the new number of available streams would cause the number of
- // available streams to exceed the limit. Note that the peer can create
- // only alternately-numbered streams.
- size_t additional_available_streams =
- (stream_id - largest_peer_created_stream_id_) / 2 - 1;
- if (largest_peer_created_stream_id_ ==
- QuicUtils::GetInvalidStreamId(transport_version_)) {
- additional_available_streams = (stream_id + 1) / 2 - 1;
- }
- size_t new_num_available_streams =
- GetNumAvailableStreams() + additional_available_streams;
- if (new_num_available_streams > MaxAvailableStreams()) {
- QUIC_DLOG(INFO) << perspective_
- << "Failed to create a new incoming stream with id:"
- << stream_id << ". There are already "
- << GetNumAvailableStreams()
- << " streams available, which would become "
- << new_num_available_streams << ", which exceeds the limit "
- << MaxAvailableStreams() << ".";
- return false;
- }
- QuicStreamId first_available_stream = largest_peer_created_stream_id_ + 2;
- if (largest_peer_created_stream_id_ ==
- QuicUtils::GetInvalidStreamId(transport_version_)) {
- first_available_stream = QuicUtils::GetFirstBidirectionalStreamId(
- transport_version_, QuicUtils::InvertPerspective(perspective_));
- }
- for (QuicStreamId id = first_available_stream; id < stream_id; id += 2) {
- available_streams_.insert(id);
- }
- largest_peer_created_stream_id_ = stream_id;
-
- return true;
-}
-
-QuicStreamId LegacyQuicStreamIdManager::GetNextOutgoingStreamId() {
- QuicStreamId id = next_outgoing_stream_id_;
- next_outgoing_stream_id_ += 2;
- return id;
-}
-
-void LegacyQuicStreamIdManager::ActivateStream(bool is_incoming) {
- if (is_incoming) {
- ++num_open_incoming_streams_;
- return;
- }
- ++num_open_outgoing_streams_;
-}
-
-void LegacyQuicStreamIdManager::OnStreamClosed(bool is_incoming) {
- if (is_incoming) {
- QUIC_BUG_IF(quic_bug_12720_1, num_open_incoming_streams_ == 0);
- --num_open_incoming_streams_;
- return;
- }
- QUIC_BUG_IF(quic_bug_12720_2, num_open_outgoing_streams_ == 0);
- --num_open_outgoing_streams_;
-}
-
-bool LegacyQuicStreamIdManager::IsAvailableStream(QuicStreamId id) const {
- if (!IsIncomingStream(id)) {
- // Stream IDs under next_ougoing_stream_id_ are either open or previously
- // open but now closed.
- return id >= next_outgoing_stream_id_;
- }
- // For peer created streams, we also need to consider available streams.
- return largest_peer_created_stream_id_ ==
- QuicUtils::GetInvalidStreamId(transport_version_) ||
- id > largest_peer_created_stream_id_ ||
- available_streams_.contains(id);
-}
-
-bool LegacyQuicStreamIdManager::IsIncomingStream(QuicStreamId id) const {
- return id % 2 != next_outgoing_stream_id_ % 2;
-}
-
-size_t LegacyQuicStreamIdManager::GetNumAvailableStreams() const {
- return available_streams_.size();
-}
-
-size_t LegacyQuicStreamIdManager::MaxAvailableStreams() const {
- return max_open_incoming_streams_ * kMaxAvailableStreamsMultiplier;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/legacy_quic_stream_id_manager.h b/chromium/net/third_party/quiche/src/quic/core/legacy_quic_stream_id_manager.h
deleted file mode 100644
index 728d288e8af..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/legacy_quic_stream_id_manager.h
+++ /dev/null
@@ -1,128 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-#ifndef QUICHE_QUIC_CORE_LEGACY_QUIC_STREAM_ID_MANAGER_H_
-#define QUICHE_QUIC_CORE_LEGACY_QUIC_STREAM_ID_MANAGER_H_
-
-#include "absl/container/flat_hash_set.h"
-#include "quic/core/quic_stream_id_manager.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_versions.h"
-
-namespace quic {
-
-namespace test {
-class QuicSessionPeer;
-} // namespace test
-
-class QuicSession;
-
-// Manages Google QUIC stream IDs. This manager is responsible for two
-// questions: 1) can next outgoing stream ID be allocated (if yes, what is the
-// next outgoing stream ID) and 2) can a new incoming stream be opened.
-class QUIC_EXPORT_PRIVATE LegacyQuicStreamIdManager {
- public:
- LegacyQuicStreamIdManager(Perspective perspective,
- QuicTransportVersion transport_version,
- size_t max_open_outgoing_streams,
- size_t max_open_incoming_streams);
-
- ~LegacyQuicStreamIdManager();
-
- // Returns true if the next outgoing stream ID can be allocated.
- bool CanOpenNextOutgoingStream() const;
-
- // Returns true if a new incoming stream can be opened.
- bool CanOpenIncomingStream() const;
-
- // Returns false when increasing the largest created stream id to |id| would
- // violate the limit, so the connection should be closed.
- bool MaybeIncreaseLargestPeerStreamId(const QuicStreamId id);
-
- // Returns true if |id| is still available.
- bool IsAvailableStream(QuicStreamId id) const;
-
- // Returns the stream ID for a new outgoing stream, and increments the
- // underlying counter.
- QuicStreamId GetNextOutgoingStreamId();
-
- // Called when a new stream is open.
- void ActivateStream(bool is_incoming);
-
- // Called when a stream ID is closed.
- void OnStreamClosed(bool is_incoming);
-
- // Return true if |id| is peer initiated.
- bool IsIncomingStream(QuicStreamId id) const;
-
- size_t MaxAvailableStreams() const;
-
- void set_max_open_incoming_streams(size_t max_open_incoming_streams) {
- max_open_incoming_streams_ = max_open_incoming_streams;
- }
-
- void set_max_open_outgoing_streams(size_t max_open_outgoing_streams) {
- max_open_outgoing_streams_ = max_open_outgoing_streams;
- }
-
- void set_largest_peer_created_stream_id(
- QuicStreamId largest_peer_created_stream_id) {
- largest_peer_created_stream_id_ = largest_peer_created_stream_id;
- }
-
- size_t max_open_incoming_streams() const {
- return max_open_incoming_streams_;
- }
-
- size_t max_open_outgoing_streams() const {
- return max_open_outgoing_streams_;
- }
-
- QuicStreamId next_outgoing_stream_id() const {
- return next_outgoing_stream_id_;
- }
-
- QuicStreamId largest_peer_created_stream_id() const {
- return largest_peer_created_stream_id_;
- }
-
- size_t GetNumAvailableStreams() const;
-
- size_t num_open_incoming_streams() const {
- return num_open_incoming_streams_;
- }
- size_t num_open_outgoing_streams() const {
- return num_open_outgoing_streams_;
- }
-
- private:
- friend class test::QuicSessionPeer;
-
- const Perspective perspective_;
- const QuicTransportVersion transport_version_;
-
- // The maximum number of outgoing streams this connection can open.
- size_t max_open_outgoing_streams_;
-
- // The maximum number of incoming streams this connection will allow.
- size_t max_open_incoming_streams_;
-
- // The ID to use for the next outgoing stream.
- QuicStreamId next_outgoing_stream_id_;
-
- // Set of stream ids that are less than the largest stream id that has been
- // received, but are nonetheless available to be created.
- absl::flat_hash_set<QuicStreamId> available_streams_;
-
- QuicStreamId largest_peer_created_stream_id_;
-
- // A counter for peer initiated open streams.
- size_t num_open_incoming_streams_;
-
- // A counter for self initiated open streams.
- size_t num_open_outgoing_streams_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_LEGACY_QUIC_STREAM_ID_MANAGER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/legacy_quic_stream_id_manager_test.cc b/chromium/net/third_party/quiche/src/quic/core/legacy_quic_stream_id_manager_test.cc
deleted file mode 100644
index a91a2f0e6eb..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/legacy_quic_stream_id_manager_test.cc
+++ /dev/null
@@ -1,180 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/legacy_quic_stream_id_manager.h"
-
-#include <utility>
-
-#include "absl/strings/str_cat.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_utils.h"
-#include "quic/core/quic_versions.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/quic_session_peer.h"
-#include "quic/test_tools/quic_test_utils.h"
-
-namespace quic {
-namespace test {
-namespace {
-
-using testing::_;
-using testing::StrictMock;
-
-struct TestParams {
- TestParams(ParsedQuicVersion version, Perspective perspective)
- : version(version), perspective(perspective) {}
-
- ParsedQuicVersion version;
- Perspective perspective;
-};
-
-// Used by ::testing::PrintToStringParamName().
-std::string PrintToString(const TestParams& p) {
- return absl::StrCat(
- ParsedQuicVersionToString(p.version),
- (p.perspective == Perspective::IS_CLIENT ? "Client" : "Server"));
-}
-
-std::vector<TestParams> GetTestParams() {
- std::vector<TestParams> params;
- for (ParsedQuicVersion version : AllSupportedVersions()) {
- for (auto perspective : {Perspective::IS_CLIENT, Perspective::IS_SERVER}) {
- // LegacyQuicStreamIdManager is only used when IETF QUIC frames are not
- // presented.
- if (!VersionHasIetfQuicFrames(version.transport_version)) {
- params.push_back(TestParams(version, perspective));
- }
- }
- }
- return params;
-}
-
-class LegacyQuicStreamIdManagerTest : public QuicTestWithParam<TestParams> {
- public:
- LegacyQuicStreamIdManagerTest()
- : manager_(GetParam().perspective,
- GetParam().version.transport_version,
- kDefaultMaxStreamsPerConnection,
- kDefaultMaxStreamsPerConnection) {}
-
- protected:
- QuicStreamId GetNthPeerInitiatedId(int n) {
- if (GetParam().perspective == Perspective::IS_SERVER) {
- return QuicUtils::GetFirstBidirectionalStreamId(
- GetParam().version.transport_version, Perspective::IS_CLIENT) +
- 2 * n;
- } else {
- return 2 + 2 * n;
- }
- }
-
- LegacyQuicStreamIdManager manager_;
-};
-
-INSTANTIATE_TEST_SUITE_P(Tests,
- LegacyQuicStreamIdManagerTest,
- ::testing::ValuesIn(GetTestParams()),
- ::testing::PrintToStringParamName());
-
-TEST_P(LegacyQuicStreamIdManagerTest, CanOpenNextOutgoingStream) {
- for (size_t i = 0; i < manager_.max_open_outgoing_streams() - 1; ++i) {
- manager_.ActivateStream(/*is_incoming=*/false);
- }
- EXPECT_TRUE(manager_.CanOpenNextOutgoingStream());
- manager_.ActivateStream(/*is_incoming=*/false);
- EXPECT_FALSE(manager_.CanOpenNextOutgoingStream());
-}
-
-TEST_P(LegacyQuicStreamIdManagerTest, CanOpenIncomingStream) {
- for (size_t i = 0; i < manager_.max_open_incoming_streams() - 1; ++i) {
- manager_.ActivateStream(/*is_incoming=*/true);
- }
- EXPECT_TRUE(manager_.CanOpenIncomingStream());
- manager_.ActivateStream(/*is_incoming=*/true);
- EXPECT_FALSE(manager_.CanOpenIncomingStream());
-}
-
-TEST_P(LegacyQuicStreamIdManagerTest, AvailableStreams) {
- ASSERT_TRUE(
- manager_.MaybeIncreaseLargestPeerStreamId(GetNthPeerInitiatedId(3)));
- EXPECT_TRUE(manager_.IsAvailableStream(GetNthPeerInitiatedId(1)));
- EXPECT_TRUE(manager_.IsAvailableStream(GetNthPeerInitiatedId(2)));
- ASSERT_TRUE(
- manager_.MaybeIncreaseLargestPeerStreamId(GetNthPeerInitiatedId(2)));
- ASSERT_TRUE(
- manager_.MaybeIncreaseLargestPeerStreamId(GetNthPeerInitiatedId(1)));
-}
-
-TEST_P(LegacyQuicStreamIdManagerTest, MaxAvailableStreams) {
- // Test that the server closes the connection if a client makes too many data
- // streams available. The server accepts slightly more than the negotiated
- // stream limit to deal with rare cases where a client FIN/RST is lost.
- const size_t kMaxStreamsForTest = 10;
- const size_t kAvailableStreamLimit = manager_.MaxAvailableStreams();
- EXPECT_EQ(
- manager_.max_open_incoming_streams() * kMaxAvailableStreamsMultiplier,
- manager_.MaxAvailableStreams());
- // The protocol specification requires that there can be at least 10 times
- // as many available streams as the connection's maximum open streams.
- EXPECT_LE(10 * kMaxStreamsForTest, kAvailableStreamLimit);
-
- EXPECT_TRUE(
- manager_.MaybeIncreaseLargestPeerStreamId(GetNthPeerInitiatedId(0)));
-
- // Establish available streams up to the server's limit.
- const int kLimitingStreamId =
- GetNthPeerInitiatedId(kAvailableStreamLimit + 1);
- // This exceeds the stream limit. In versions other than 99
- // this is allowed. Version 99 hews to the IETF spec and does
- // not allow it.
- EXPECT_TRUE(manager_.MaybeIncreaseLargestPeerStreamId(kLimitingStreamId));
-
- // This forces stream kLimitingStreamId + 2 to become available, which
- // violates the quota.
- EXPECT_FALSE(
- manager_.MaybeIncreaseLargestPeerStreamId(kLimitingStreamId + 2 * 2));
-}
-
-TEST_P(LegacyQuicStreamIdManagerTest, MaximumAvailableOpenedStreams) {
- QuicStreamId stream_id = GetNthPeerInitiatedId(0);
- EXPECT_TRUE(manager_.MaybeIncreaseLargestPeerStreamId(stream_id));
-
- EXPECT_TRUE(manager_.MaybeIncreaseLargestPeerStreamId(
- stream_id + 2 * (manager_.max_open_incoming_streams() - 1)));
-}
-
-TEST_P(LegacyQuicStreamIdManagerTest, TooManyAvailableStreams) {
- QuicStreamId stream_id = GetNthPeerInitiatedId(0);
- EXPECT_TRUE(manager_.MaybeIncreaseLargestPeerStreamId(stream_id));
-
- // A stream ID which is too large to create.
- QuicStreamId stream_id2 =
- GetNthPeerInitiatedId(2 * manager_.MaxAvailableStreams() + 4);
- EXPECT_FALSE(manager_.MaybeIncreaseLargestPeerStreamId(stream_id2));
-}
-
-TEST_P(LegacyQuicStreamIdManagerTest, ManyAvailableStreams) {
- // When max_open_streams_ is 200, should be able to create 200 streams
- // out-of-order, that is, creating the one with the largest stream ID first.
- manager_.set_max_open_incoming_streams(200);
- QuicStreamId stream_id = GetNthPeerInitiatedId(0);
- EXPECT_TRUE(manager_.MaybeIncreaseLargestPeerStreamId(stream_id));
-
- // Create the largest stream ID of a threatened total of 200 streams.
- // GetNth... starts at 0, so for 200 streams, get the 199th.
- EXPECT_TRUE(
- manager_.MaybeIncreaseLargestPeerStreamId(GetNthPeerInitiatedId(199)));
-}
-
-TEST_P(LegacyQuicStreamIdManagerTest,
- TestMaxIncomingAndOutgoingStreamsAllowed) {
- EXPECT_EQ(manager_.max_open_incoming_streams(),
- kDefaultMaxStreamsPerConnection);
- EXPECT_EQ(manager_.max_open_outgoing_streams(),
- kDefaultMaxStreamsPerConnection);
-}
-
-} // namespace
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/packet_number_indexed_queue.h b/chromium/net/third_party/quiche/src/quic/core/packet_number_indexed_queue.h
deleted file mode 100644
index 8e80c7de4b7..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/packet_number_indexed_queue.h
+++ /dev/null
@@ -1,252 +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_CORE_PACKET_NUMBER_INDEXED_QUEUE_H_
-#define QUICHE_QUIC_CORE_PACKET_NUMBER_INDEXED_QUEUE_H_
-
-#include "quic/core/quic_constants.h"
-#include "quic/core/quic_packet_number.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "common/quiche_circular_deque.h"
-
-namespace quic {
-
-// PacketNumberIndexedQueue is a queue of mostly continuous numbered entries
-// which supports the following operations:
-// - adding elements to the end of the queue, or at some point past the end
-// - removing elements in any order
-// - retrieving elements
-// If all elements are inserted in order, all of the operations above are
-// amortized O(1) time.
-//
-// Internally, the data structure is a deque where each element is marked as
-// present or not. The deque starts at the lowest present index. Whenever an
-// element is removed, it's marked as not present, and the front of the deque is
-// cleared of elements that are not present.
-//
-// The tail of the queue is not cleared due to the assumption of entries being
-// inserted in order, though removing all elements of the queue will return it
-// to its initial state.
-//
-// Note that this data structure is inherently hazardous, since an addition of
-// just two entries will cause it to consume all of the memory available.
-// Because of that, it is not a general-purpose container and should not be used
-// as one.
-// TODO(wub): Update the comments when deprecating
-// --quic_bw_sampler_remove_packets_once_per_congestion_event.
-template <typename T>
-class QUIC_NO_EXPORT PacketNumberIndexedQueue {
- public:
- PacketNumberIndexedQueue() : number_of_present_entries_(0) {}
-
- // Retrieve the entry associated with the packet number. Returns the pointer
- // to the entry in case of success, or nullptr if the entry does not exist.
- T* GetEntry(QuicPacketNumber packet_number);
- const T* GetEntry(QuicPacketNumber packet_number) const;
-
- // Inserts data associated |packet_number| into (or past) the end of the
- // queue, filling up the missing intermediate entries as necessary. Returns
- // true if the element has been inserted successfully, false if it was already
- // in the queue or inserted out of order.
- template <typename... Args>
- bool Emplace(QuicPacketNumber packet_number, Args&&... args);
-
- // Removes data associated with |packet_number| and frees the slots in the
- // queue as necessary.
- bool Remove(QuicPacketNumber packet_number);
-
- // Same as above, but if an entry is present in the queue, also call f(entry)
- // before removing it.
- template <typename Function>
- bool Remove(QuicPacketNumber packet_number, Function f);
-
- // Remove up to, but not including |packet_number|.
- // Unused slots in the front are also removed, which means when the function
- // returns, |first_packet()| can be larger than |packet_number|.
- void RemoveUpTo(QuicPacketNumber packet_number);
-
- bool IsEmpty() const { return number_of_present_entries_ == 0; }
-
- // Returns the number of entries in the queue.
- size_t number_of_present_entries() const {
- return number_of_present_entries_;
- }
-
- // Returns the number of entries allocated in the underlying deque. This is
- // proportional to the memory usage of the queue.
- size_t entry_slots_used() const { return entries_.size(); }
-
- // Packet number of the first entry in the queue.
- QuicPacketNumber first_packet() const { return first_packet_; }
-
- // Packet number of the last entry ever inserted in the queue. Note that the
- // entry in question may have already been removed. Zero if the queue is
- // empty.
- QuicPacketNumber last_packet() const {
- if (IsEmpty()) {
- return QuicPacketNumber();
- }
- return first_packet_ + entries_.size() - 1;
- }
-
- private:
- // Wrapper around T used to mark whether the entry is actually in the map.
- struct QUIC_NO_EXPORT EntryWrapper : T {
- // NOTE(wub): When quic_bw_sampler_remove_packets_once_per_congestion_event
- // is enabled, |present| is false if and only if this is a placeholder entry
- // for holes in the parent's |entries|.
- bool present;
-
- EntryWrapper() : present(false) {}
-
- template <typename... Args>
- explicit EntryWrapper(Args&&... args)
- : T(std::forward<Args>(args)...), present(true) {}
- };
-
- // Cleans up unused slots in the front after removing an element.
- void Cleanup();
-
- const EntryWrapper* GetEntryWrapper(QuicPacketNumber offset) const;
- EntryWrapper* GetEntryWrapper(QuicPacketNumber offset) {
- const auto* const_this = this;
- return const_cast<EntryWrapper*>(const_this->GetEntryWrapper(offset));
- }
-
- quiche::QuicheCircularDeque<EntryWrapper> entries_;
- // NOTE(wub): When --quic_bw_sampler_remove_packets_once_per_congestion_event
- // is enabled, |number_of_present_entries_| only represents number of holes,
- // which does not include number of acked or lost packets.
- size_t number_of_present_entries_;
- QuicPacketNumber first_packet_;
-};
-
-template <typename T>
-T* PacketNumberIndexedQueue<T>::GetEntry(QuicPacketNumber packet_number) {
- EntryWrapper* entry = GetEntryWrapper(packet_number);
- if (entry == nullptr) {
- return nullptr;
- }
- return entry;
-}
-
-template <typename T>
-const T* PacketNumberIndexedQueue<T>::GetEntry(
- QuicPacketNumber packet_number) const {
- const EntryWrapper* entry = GetEntryWrapper(packet_number);
- if (entry == nullptr) {
- return nullptr;
- }
- return entry;
-}
-
-template <typename T>
-template <typename... Args>
-bool PacketNumberIndexedQueue<T>::Emplace(QuicPacketNumber packet_number,
- Args&&... args) {
- if (!packet_number.IsInitialized()) {
- QUIC_BUG(quic_bug_10359_1)
- << "Try to insert an uninitialized packet number";
- return false;
- }
-
- if (IsEmpty()) {
- QUICHE_DCHECK(entries_.empty());
- QUICHE_DCHECK(!first_packet_.IsInitialized());
-
- entries_.emplace_back(std::forward<Args>(args)...);
- number_of_present_entries_ = 1;
- first_packet_ = packet_number;
- return true;
- }
-
- // Do not allow insertion out-of-order.
- if (packet_number <= last_packet()) {
- return false;
- }
-
- // Handle potentially missing elements.
- size_t offset = packet_number - first_packet_;
- if (offset > entries_.size()) {
- entries_.resize(offset);
- }
-
- number_of_present_entries_++;
- entries_.emplace_back(std::forward<Args>(args)...);
- QUICHE_DCHECK_EQ(packet_number, last_packet());
- return true;
-}
-
-template <typename T>
-bool PacketNumberIndexedQueue<T>::Remove(QuicPacketNumber packet_number) {
- return Remove(packet_number, [](const T&) {});
-}
-
-template <typename T>
-template <typename Function>
-bool PacketNumberIndexedQueue<T>::Remove(QuicPacketNumber packet_number,
- Function f) {
- EntryWrapper* entry = GetEntryWrapper(packet_number);
- if (entry == nullptr) {
- return false;
- }
- f(*static_cast<const T*>(entry));
- entry->present = false;
- number_of_present_entries_--;
-
- if (packet_number == first_packet()) {
- Cleanup();
- }
- return true;
-}
-
-template <typename T>
-void PacketNumberIndexedQueue<T>::RemoveUpTo(QuicPacketNumber packet_number) {
- while (!entries_.empty() && first_packet_.IsInitialized() &&
- first_packet_ < packet_number) {
- if (entries_.front().present) {
- number_of_present_entries_--;
- }
- entries_.pop_front();
- first_packet_++;
- }
- Cleanup();
-}
-
-template <typename T>
-void PacketNumberIndexedQueue<T>::Cleanup() {
- while (!entries_.empty() && !entries_.front().present) {
- entries_.pop_front();
- first_packet_++;
- }
- if (entries_.empty()) {
- first_packet_.Clear();
- }
-}
-
-template <typename T>
-auto PacketNumberIndexedQueue<T>::GetEntryWrapper(
- QuicPacketNumber packet_number) const -> const EntryWrapper* {
- if (!packet_number.IsInitialized() || IsEmpty() ||
- packet_number < first_packet_) {
- return nullptr;
- }
-
- uint64_t offset = packet_number - first_packet_;
- if (offset >= entries_.size()) {
- return nullptr;
- }
-
- const EntryWrapper* entry = &entries_[offset];
- if (!entry->present) {
- return nullptr;
- }
-
- return entry;
-}
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_PACKET_NUMBER_INDEXED_QUEUE_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/packet_number_indexed_queue_test.cc b/chromium/net/third_party/quiche/src/quic/core/packet_number_indexed_queue_test.cc
deleted file mode 100644
index cd41f9edd00..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/packet_number_indexed_queue_test.cc
+++ /dev/null
@@ -1,205 +0,0 @@
-// Copyright (c) 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/packet_number_indexed_queue.h"
-
-#include <limits>
-#include <map>
-#include <string>
-
-#include "quic/core/quic_packet_number.h"
-#include "quic/platform/api/quic_test.h"
-
-namespace quic {
-namespace {
-
-class PacketNumberIndexedQueueTest : public QuicTest {
- public:
- PacketNumberIndexedQueueTest() {}
-
- protected:
- PacketNumberIndexedQueue<std::string> queue_;
-};
-
-TEST_F(PacketNumberIndexedQueueTest, InitialState) {
- EXPECT_TRUE(queue_.IsEmpty());
- EXPECT_FALSE(queue_.first_packet().IsInitialized());
- EXPECT_FALSE(queue_.last_packet().IsInitialized());
- EXPECT_EQ(0u, queue_.number_of_present_entries());
- EXPECT_EQ(0u, queue_.entry_slots_used());
-}
-
-TEST_F(PacketNumberIndexedQueueTest, InsertingContinuousElements) {
- ASSERT_TRUE(queue_.Emplace(QuicPacketNumber(1001), "one"));
- EXPECT_EQ("one", *queue_.GetEntry(QuicPacketNumber(1001)));
-
- ASSERT_TRUE(queue_.Emplace(QuicPacketNumber(1002), "two"));
- EXPECT_EQ("two", *queue_.GetEntry(QuicPacketNumber(1002)));
-
- EXPECT_FALSE(queue_.IsEmpty());
- EXPECT_EQ(QuicPacketNumber(1001u), queue_.first_packet());
- EXPECT_EQ(QuicPacketNumber(1002u), queue_.last_packet());
- EXPECT_EQ(2u, queue_.number_of_present_entries());
- EXPECT_EQ(2u, queue_.entry_slots_used());
-}
-
-TEST_F(PacketNumberIndexedQueueTest, InsertingOutOfOrder) {
- queue_.Emplace(QuicPacketNumber(1001), "one");
-
- ASSERT_TRUE(queue_.Emplace(QuicPacketNumber(1003), "three"));
- EXPECT_EQ(nullptr, queue_.GetEntry(QuicPacketNumber(1002)));
- EXPECT_EQ("three", *queue_.GetEntry(QuicPacketNumber(1003)));
-
- EXPECT_EQ(QuicPacketNumber(1001u), queue_.first_packet());
- EXPECT_EQ(QuicPacketNumber(1003u), queue_.last_packet());
- EXPECT_EQ(2u, queue_.number_of_present_entries());
- EXPECT_EQ(3u, queue_.entry_slots_used());
-
- ASSERT_FALSE(queue_.Emplace(QuicPacketNumber(1002), "two"));
-}
-
-TEST_F(PacketNumberIndexedQueueTest, InsertingIntoPast) {
- queue_.Emplace(QuicPacketNumber(1001), "one");
- EXPECT_FALSE(queue_.Emplace(QuicPacketNumber(1000), "zero"));
-}
-
-TEST_F(PacketNumberIndexedQueueTest, InsertingDuplicate) {
- queue_.Emplace(QuicPacketNumber(1001), "one");
- EXPECT_FALSE(queue_.Emplace(QuicPacketNumber(1001), "one"));
-}
-
-TEST_F(PacketNumberIndexedQueueTest, RemoveInTheMiddle) {
- queue_.Emplace(QuicPacketNumber(1001), "one");
- queue_.Emplace(QuicPacketNumber(1002), "two");
- queue_.Emplace(QuicPacketNumber(1003), "three");
-
- ASSERT_TRUE(queue_.Remove(QuicPacketNumber(1002)));
- EXPECT_EQ(nullptr, queue_.GetEntry(QuicPacketNumber(1002)));
-
- EXPECT_EQ(QuicPacketNumber(1001u), queue_.first_packet());
- EXPECT_EQ(QuicPacketNumber(1003u), queue_.last_packet());
- EXPECT_EQ(2u, queue_.number_of_present_entries());
- EXPECT_EQ(3u, queue_.entry_slots_used());
-
- EXPECT_FALSE(queue_.Emplace(QuicPacketNumber(1002), "two"));
- EXPECT_TRUE(queue_.Emplace(QuicPacketNumber(1004), "four"));
-}
-
-TEST_F(PacketNumberIndexedQueueTest, RemoveAtImmediateEdges) {
- queue_.Emplace(QuicPacketNumber(1001), "one");
- queue_.Emplace(QuicPacketNumber(1002), "two");
- queue_.Emplace(QuicPacketNumber(1003), "three");
- ASSERT_TRUE(queue_.Remove(QuicPacketNumber(1001)));
- EXPECT_EQ(nullptr, queue_.GetEntry(QuicPacketNumber(1001)));
- ASSERT_TRUE(queue_.Remove(QuicPacketNumber(1003)));
- EXPECT_EQ(nullptr, queue_.GetEntry(QuicPacketNumber(1003)));
-
- EXPECT_EQ(QuicPacketNumber(1002u), queue_.first_packet());
- EXPECT_EQ(QuicPacketNumber(1003u), queue_.last_packet());
- EXPECT_EQ(1u, queue_.number_of_present_entries());
- EXPECT_EQ(2u, queue_.entry_slots_used());
-
- EXPECT_TRUE(queue_.Emplace(QuicPacketNumber(1004), "four"));
-}
-
-TEST_F(PacketNumberIndexedQueueTest, RemoveAtDistantFront) {
- queue_.Emplace(QuicPacketNumber(1001), "one");
- queue_.Emplace(QuicPacketNumber(1002), "one (kinda)");
- queue_.Emplace(QuicPacketNumber(2001), "two");
-
- EXPECT_EQ(QuicPacketNumber(1001u), queue_.first_packet());
- EXPECT_EQ(QuicPacketNumber(2001u), queue_.last_packet());
- EXPECT_EQ(3u, queue_.number_of_present_entries());
- EXPECT_EQ(1001u, queue_.entry_slots_used());
-
- ASSERT_TRUE(queue_.Remove(QuicPacketNumber(1002)));
- EXPECT_EQ(QuicPacketNumber(1001u), queue_.first_packet());
- EXPECT_EQ(QuicPacketNumber(2001u), queue_.last_packet());
- EXPECT_EQ(2u, queue_.number_of_present_entries());
- EXPECT_EQ(1001u, queue_.entry_slots_used());
-
- ASSERT_TRUE(queue_.Remove(QuicPacketNumber(1001)));
- EXPECT_EQ(QuicPacketNumber(2001u), queue_.first_packet());
- EXPECT_EQ(QuicPacketNumber(2001u), queue_.last_packet());
- EXPECT_EQ(1u, queue_.number_of_present_entries());
- EXPECT_EQ(1u, queue_.entry_slots_used());
-}
-
-TEST_F(PacketNumberIndexedQueueTest, RemoveAtDistantBack) {
- queue_.Emplace(QuicPacketNumber(1001), "one");
- queue_.Emplace(QuicPacketNumber(2001), "two");
-
- EXPECT_EQ(QuicPacketNumber(1001u), queue_.first_packet());
- EXPECT_EQ(QuicPacketNumber(2001u), queue_.last_packet());
-
- ASSERT_TRUE(queue_.Remove(QuicPacketNumber(2001)));
- EXPECT_EQ(QuicPacketNumber(1001u), queue_.first_packet());
- EXPECT_EQ(QuicPacketNumber(2001u), queue_.last_packet());
-}
-
-TEST_F(PacketNumberIndexedQueueTest, ClearAndRepopulate) {
- queue_.Emplace(QuicPacketNumber(1001), "one");
- queue_.Emplace(QuicPacketNumber(2001), "two");
-
- ASSERT_TRUE(queue_.Remove(QuicPacketNumber(1001)));
- ASSERT_TRUE(queue_.Remove(QuicPacketNumber(2001)));
- EXPECT_TRUE(queue_.IsEmpty());
- EXPECT_FALSE(queue_.first_packet().IsInitialized());
- EXPECT_FALSE(queue_.last_packet().IsInitialized());
-
- EXPECT_TRUE(queue_.Emplace(QuicPacketNumber(101), "one"));
- EXPECT_TRUE(queue_.Emplace(QuicPacketNumber(201), "two"));
- EXPECT_EQ(QuicPacketNumber(101u), queue_.first_packet());
- EXPECT_EQ(QuicPacketNumber(201u), queue_.last_packet());
-}
-
-TEST_F(PacketNumberIndexedQueueTest, FailToRemoveElementsThatNeverExisted) {
- ASSERT_FALSE(queue_.Remove(QuicPacketNumber(1000)));
- queue_.Emplace(QuicPacketNumber(1001), "one");
- ASSERT_FALSE(queue_.Remove(QuicPacketNumber(1000)));
- ASSERT_FALSE(queue_.Remove(QuicPacketNumber(1002)));
-}
-
-TEST_F(PacketNumberIndexedQueueTest, FailToRemoveElementsTwice) {
- queue_.Emplace(QuicPacketNumber(1001), "one");
- ASSERT_TRUE(queue_.Remove(QuicPacketNumber(1001)));
- ASSERT_FALSE(queue_.Remove(QuicPacketNumber(1001)));
- ASSERT_FALSE(queue_.Remove(QuicPacketNumber(1001)));
-}
-
-TEST_F(PacketNumberIndexedQueueTest, RemoveUpTo) {
- queue_.Emplace(QuicPacketNumber(1001), "one");
- queue_.Emplace(QuicPacketNumber(2001), "two");
- EXPECT_EQ(QuicPacketNumber(1001u), queue_.first_packet());
- EXPECT_EQ(2u, queue_.number_of_present_entries());
-
- queue_.RemoveUpTo(QuicPacketNumber(1001));
- EXPECT_EQ(QuicPacketNumber(1001u), queue_.first_packet());
- EXPECT_EQ(2u, queue_.number_of_present_entries());
-
- // Remove up to 1100, since [1100, 2001) are !present, they should be cleaned
- // up from the front.
- queue_.RemoveUpTo(QuicPacketNumber(1100));
- EXPECT_EQ(QuicPacketNumber(2001u), queue_.first_packet());
- EXPECT_EQ(1u, queue_.number_of_present_entries());
-
- queue_.RemoveUpTo(QuicPacketNumber(2001));
- EXPECT_EQ(QuicPacketNumber(2001u), queue_.first_packet());
- EXPECT_EQ(1u, queue_.number_of_present_entries());
-
- queue_.RemoveUpTo(QuicPacketNumber(2002));
- EXPECT_FALSE(queue_.first_packet().IsInitialized());
- EXPECT_EQ(0u, queue_.number_of_present_entries());
-}
-
-TEST_F(PacketNumberIndexedQueueTest, ConstGetter) {
- queue_.Emplace(QuicPacketNumber(1001), "one");
- const auto& const_queue = queue_;
-
- EXPECT_EQ("one", *const_queue.GetEntry(QuicPacketNumber(1001)));
- EXPECT_EQ(nullptr, const_queue.GetEntry(QuicPacketNumber(1002)));
-}
-
-} // namespace
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/proto/cached_network_parameters.proto b/chromium/net/third_party/quiche/src/quic/core/proto/cached_network_parameters.proto
deleted file mode 100644
index d609be9b0d1..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/proto/cached_network_parameters.proto
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-syntax = "proto2";
-
-option optimize_for = LITE_RUNTIME;
-
-package quic;
-
-// CachedNetworkParameters contains data that can be used to choose appropriate
-// connection parameters (initial RTT, initial CWND, etc.) in new connections.
-// Next id: 8
-message CachedNetworkParameters {
- // Describes the state of the connection during which the supplied network
- // parameters were calculated.
- enum PreviousConnectionState {
- SLOW_START = 0;
- CONGESTION_AVOIDANCE = 1;
- }
-
- // serving_region is used to decide whether or not the bandwidth estimate and
- // min RTT are reasonable and if they should be used.
- // For example a group of geographically close servers may share the same
- // serving_region string if they are expected to have similar network
- // performance.
- optional string serving_region = 1;
- // The server can supply a bandwidth estimate (in bytes/s) which it may re-use
- // on receipt of a source-address token with this field set.
- optional int32 bandwidth_estimate_bytes_per_second = 2;
- // The maximum bandwidth seen to the client, not necessarily the latest.
- optional int32 max_bandwidth_estimate_bytes_per_second = 5;
- // Timestamp (seconds since UNIX epoch) that indicates when the max bandwidth
- // was seen by the server.
- optional int64 max_bandwidth_timestamp_seconds = 6;
- // The min RTT seen on a previous connection can be used by the server to
- // inform initial connection parameters for new connections.
- optional int32 min_rtt_ms = 3;
- // Encodes the PreviousConnectionState enum.
- optional int32 previous_connection_state = 4;
- // UNIX timestamp when this bandwidth estimate was created.
- optional int64 timestamp = 7;
-};
diff --git a/chromium/net/third_party/quiche/src/quic/core/proto/cached_network_parameters_proto.h b/chromium/net/third_party/quiche/src/quic/core/proto/cached_network_parameters_proto.h
deleted file mode 100644
index 5714801b460..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/proto/cached_network_parameters_proto.h
+++ /dev/null
@@ -1,15 +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_CORE_PROTO_CACHED_NETWORK_PARAMETERS_PROTO_H_
-#define QUICHE_QUIC_CORE_PROTO_CACHED_NETWORK_PARAMETERS_PROTO_H_
-
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Weverything"
-
-#include "quic/core/proto/cached_network_parameters.pb.h"
-
-#pragma clang diagnostic pop
-
-#endif // QUICHE_QUIC_CORE_PROTO_CACHED_NETWORK_PARAMETERS_PROTO_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/proto/crypto_server_config.proto b/chromium/net/third_party/quiche/src/quic/core/proto/crypto_server_config.proto
deleted file mode 100644
index bb447dcc4b6..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/proto/crypto_server_config.proto
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-syntax = "proto2";
-
-option optimize_for = LITE_RUNTIME;
-
-package quic;
-
-// QuicServerConfigProtobuf contains QUIC server config block and the private
-// keys needed to prove ownership.
-message QuicServerConfigProtobuf {
- // config is a serialised config in QUIC wire format.
- required bytes config = 1;
-
- // PrivateKey contains a QUIC tag of a key exchange algorithm and a
- // serialised private key for that algorithm. The format of the serialised
- // private key is specific to the algorithm in question.
- message PrivateKey {
- required uint32 tag = 1;
- required bytes private_key = 2;
- }
- repeated PrivateKey key = 2;
-
- // primary_time contains a UNIX epoch seconds value that indicates when this
- // config should become primary.
- optional int64 primary_time = 3;
-
- // Relative priority of this config vs other configs with the same
- // primary time. For use as a secondary sort key when selecting the
- // primary config.
- optional uint64 priority = 4;
-};
diff --git a/chromium/net/third_party/quiche/src/quic/core/proto/crypto_server_config_proto.h b/chromium/net/third_party/quiche/src/quic/core/proto/crypto_server_config_proto.h
deleted file mode 100644
index 908a289f1de..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/proto/crypto_server_config_proto.h
+++ /dev/null
@@ -1,15 +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_CORE_PROTO_CRYPTO_SERVER_CONFIG_PROTO_H_
-#define QUICHE_QUIC_CORE_PROTO_CRYPTO_SERVER_CONFIG_PROTO_H_
-
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Weverything"
-
-#include "quic/core/proto/crypto_server_config.pb.h"
-
-#pragma clang diagnostic pop
-
-#endif // QUICHE_QUIC_CORE_PROTO_CRYPTO_SERVER_CONFIG_PROTO_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/proto/source_address_token.proto b/chromium/net/third_party/quiche/src/quic/core/proto/source_address_token.proto
deleted file mode 100644
index df12fa5c7c8..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/proto/source_address_token.proto
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-syntax = "proto2";
-
-option optimize_for = LITE_RUNTIME;
-
-import "quic/core/proto/cached_network_parameters.proto";
-
-package quic;
-
-// A SourceAddressToken is serialised, encrypted and sent to clients so that
-// they can prove ownership of an IP address.
-message SourceAddressToken {
- // ip contains either 4 (IPv4) or 16 (IPv6) bytes of IP address in network
- // byte order.
- required bytes ip = 1;
- // timestamp contains a UNIX timestamp value of the time when the token was
- // created.
- required int64 timestamp = 2;
- // The server can provide estimated network parameters to be used for
- // initial parameter selection in future connections.
- optional CachedNetworkParameters cached_network_parameters = 3;
-};
-
-// SourceAddressTokens are simply lists of SourceAddressToken messages.
-message SourceAddressTokens {
- // This field has id 4 to avoid ambiguity between the serialized form of
- // SourceAddressToken vs SourceAddressTokens.
- repeated SourceAddressToken tokens = 4;
-};
diff --git a/chromium/net/third_party/quiche/src/quic/core/proto/source_address_token_proto.h b/chromium/net/third_party/quiche/src/quic/core/proto/source_address_token_proto.h
deleted file mode 100644
index a63bd89febf..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/proto/source_address_token_proto.h
+++ /dev/null
@@ -1,15 +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_CORE_PROTO_SOURCE_ADDRESS_TOKEN_PROTO_H_
-#define QUICHE_QUIC_CORE_PROTO_SOURCE_ADDRESS_TOKEN_PROTO_H_
-
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Weverything"
-
-#include "quic/core/proto/source_address_token.pb.h"
-
-#pragma clang diagnostic pop
-
-#endif // QUICHE_QUIC_CORE_PROTO_SOURCE_ADDRESS_TOKEN_PROTO_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_blocking_manager.cc b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_blocking_manager.cc
deleted file mode 100644
index 3b03710b3c3..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_blocking_manager.cc
+++ /dev/null
@@ -1,159 +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 "quic/core/qpack/qpack_blocking_manager.h"
-
-#include <limits>
-#include <utility>
-
-namespace quic {
-
-QpackBlockingManager::QpackBlockingManager() : known_received_count_(0) {}
-
-bool QpackBlockingManager::OnHeaderAcknowledgement(QuicStreamId stream_id) {
- auto it = header_blocks_.find(stream_id);
- if (it == header_blocks_.end()) {
- return false;
- }
-
- QUICHE_DCHECK(!it->second.empty());
-
- const IndexSet& indices = it->second.front();
- QUICHE_DCHECK(!indices.empty());
-
- const uint64_t required_index_count = RequiredInsertCount(indices);
- if (known_received_count_ < required_index_count) {
- known_received_count_ = required_index_count;
- }
-
- DecreaseReferenceCounts(indices);
-
- it->second.pop_front();
- if (it->second.empty()) {
- header_blocks_.erase(it);
- }
-
- return true;
-}
-
-void QpackBlockingManager::OnStreamCancellation(QuicStreamId stream_id) {
- auto it = header_blocks_.find(stream_id);
- if (it == header_blocks_.end()) {
- return;
- }
-
- for (const IndexSet& indices : it->second) {
- DecreaseReferenceCounts(indices);
- }
-
- header_blocks_.erase(it);
-}
-
-bool QpackBlockingManager::OnInsertCountIncrement(uint64_t increment) {
- if (increment >
- std::numeric_limits<uint64_t>::max() - known_received_count_) {
- return false;
- }
-
- known_received_count_ += increment;
- return true;
-}
-
-void QpackBlockingManager::OnHeaderBlockSent(QuicStreamId stream_id,
- IndexSet indices) {
- QUICHE_DCHECK(!indices.empty());
-
- IncreaseReferenceCounts(indices);
- header_blocks_[stream_id].push_back(std::move(indices));
-}
-
-bool QpackBlockingManager::blocking_allowed_on_stream(
- QuicStreamId stream_id,
- uint64_t maximum_blocked_streams) const {
- // This should be the most common case: the limit is larger than the number of
- // streams that have unacknowledged header blocks (regardless of whether they
- // are blocked or not) plus one for stream |stream_id|.
- if (header_blocks_.size() + 1 <= maximum_blocked_streams) {
- return true;
- }
-
- // This should be another common case: no blocked stream allowed.
- if (maximum_blocked_streams == 0) {
- return false;
- }
-
- uint64_t blocked_stream_count = 0;
- for (const auto& header_blocks_for_stream : header_blocks_) {
- for (const IndexSet& indices : header_blocks_for_stream.second) {
- if (RequiredInsertCount(indices) > known_received_count_) {
- if (header_blocks_for_stream.first == stream_id) {
- // Sending blocking references is allowed if stream |stream_id| is
- // already blocked.
- return true;
- }
- ++blocked_stream_count;
- // If stream |stream_id| is already blocked, then it is not counted yet,
- // therefore the number of blocked streams is at least
- // |blocked_stream_count + 1|, which cannot be more than
- // |maximum_blocked_streams| by API contract.
- // If stream |stream_id| is not blocked, then blocking will increase the
- // blocked stream count to at least |blocked_stream_count + 1|. If that
- // is larger than |maximum_blocked_streams|, then blocking is not
- // allowed on stream |stream_id|.
- if (blocked_stream_count + 1 > maximum_blocked_streams) {
- return false;
- }
- break;
- }
- }
- }
-
- // Stream |stream_id| is not blocked.
- // If there are no blocked streams, then
- // |blocked_stream_count + 1 <= maximum_blocked_streams| because
- // |maximum_blocked_streams| is larger than zero.
- // If there are are blocked streams, then
- // |blocked_stream_count + 1 <= maximum_blocked_streams| otherwise the method
- // would have returned false when |blocked_stream_count| was incremented.
- // Therefore blocking on |stream_id| is allowed.
- return true;
-}
-
-uint64_t QpackBlockingManager::smallest_blocking_index() const {
- return entry_reference_counts_.empty()
- ? std::numeric_limits<uint64_t>::max()
- : entry_reference_counts_.begin()->first;
-}
-
-// static
-uint64_t QpackBlockingManager::RequiredInsertCount(const IndexSet& indices) {
- return *indices.rbegin() + 1;
-}
-
-void QpackBlockingManager::IncreaseReferenceCounts(const IndexSet& indices) {
- for (const uint64_t index : indices) {
- auto it = entry_reference_counts_.lower_bound(index);
- if (it != entry_reference_counts_.end() && it->first == index) {
- ++it->second;
- } else {
- entry_reference_counts_.insert(it, {index, 1});
- }
- }
-}
-
-void QpackBlockingManager::DecreaseReferenceCounts(const IndexSet& indices) {
- for (const uint64_t index : indices) {
- auto it = entry_reference_counts_.find(index);
- QUICHE_DCHECK(it != entry_reference_counts_.end());
- QUICHE_DCHECK_NE(0u, it->second);
-
- if (it->second == 1) {
- entry_reference_counts_.erase(it);
- } else {
- --it->second;
- }
- }
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_blocking_manager.h b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_blocking_manager.h
deleted file mode 100644
index 4188350e463..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_blocking_manager.h
+++ /dev/null
@@ -1,99 +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_CORE_QPACK_QPACK_BLOCKING_MANAGER_H_
-#define QUICHE_QUIC_CORE_QPACK_QPACK_BLOCKING_MANAGER_H_
-
-#include <cstdint>
-#include <map>
-#include <set>
-
-#include "absl/container/flat_hash_map.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_containers.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-namespace test {
-
-class QpackBlockingManagerPeer;
-
-} // namespace test
-
-// Class to keep track of blocked streams and blocking dynamic table entries:
-// https://quicwg.org/base-drafts/draft-ietf-quic-qpack.html#blocked-decoding
-// https://quicwg.org/base-drafts/draft-ietf-quic-qpack.html#blocked-insertion
-class QUIC_EXPORT_PRIVATE QpackBlockingManager {
- public:
- using IndexSet = std::multiset<uint64_t>;
-
- QpackBlockingManager();
-
- // Called when a Header Acknowledgement instruction is received on the decoder
- // stream. Returns false if there are no outstanding header blocks to be
- // acknowledged on |stream_id|.
- bool OnHeaderAcknowledgement(QuicStreamId stream_id);
-
- // Called when a Stream Cancellation instruction is received on the decoder
- // stream.
- void OnStreamCancellation(QuicStreamId stream_id);
-
- // Called when an Insert Count Increment instruction is received on the
- // decoder stream. Returns true if Known Received Count is successfully
- // updated. Returns false on overflow.
- bool OnInsertCountIncrement(uint64_t increment);
-
- // Called when sending a header block containing references to dynamic table
- // entries with |indices|. |indices| must not be empty.
- void OnHeaderBlockSent(QuicStreamId stream_id, IndexSet indices);
-
- // Returns true if sending blocking references on stream |stream_id| would not
- // increase the total number of blocked streams above
- // |maximum_blocked_streams|. Note that if |stream_id| is already blocked
- // then it is always allowed to send more blocking references on it.
- // Behavior is undefined if |maximum_blocked_streams| is smaller than number
- // of currently blocked streams.
- bool blocking_allowed_on_stream(QuicStreamId stream_id,
- uint64_t maximum_blocked_streams) const;
-
- // Returns the index of the blocking entry with the smallest index,
- // or std::numeric_limits<uint64_t>::max() if there are no blocking entries.
- uint64_t smallest_blocking_index() const;
-
- // Returns the Known Received Count as defined at
- // https://quicwg.org/base-drafts/draft-ietf-quic-qpack.html#known-received-count.
- uint64_t known_received_count() const { return known_received_count_; }
-
- // Required Insert Count for set of indices.
- static uint64_t RequiredInsertCount(const IndexSet& indices);
-
- private:
- friend test::QpackBlockingManagerPeer;
-
- // A stream typically has only one header block, except for the rare cases of
- // 1xx responses, trailers, or push promises. Even if there are multiple
- // header blocks sent on a single stream, they might not be blocked at the
- // same time. Use std::list instead of quiche::QuicheCircularDeque because it
- // has lower memory footprint when holding few elements.
- using HeaderBlocksForStream = std::list<IndexSet>;
- using HeaderBlocks = absl::flat_hash_map<QuicStreamId, HeaderBlocksForStream>;
-
- // Increase or decrease the reference count for each index in |indices|.
- void IncreaseReferenceCounts(const IndexSet& indices);
- void DecreaseReferenceCounts(const IndexSet& indices);
-
- // Multiset of indices in each header block for each stream.
- // Must not contain a stream id with an empty queue.
- HeaderBlocks header_blocks_;
-
- // Number of references in |header_blocks_| for each entry index.
- std::map<uint64_t, uint64_t> entry_reference_counts_;
-
- uint64_t known_received_count_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_QPACK_QPACK_BLOCKING_MANAGER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_blocking_manager_test.cc b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_blocking_manager_test.cc
deleted file mode 100644
index 4bc8419e0b3..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_blocking_manager_test.cc
+++ /dev/null
@@ -1,319 +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 "quic/core/qpack/qpack_blocking_manager.h"
-
-#include <limits>
-
-#include "quic/platform/api/quic_test.h"
-
-namespace quic {
-namespace test {
-
-class QpackBlockingManagerPeer {
- public:
- static bool stream_is_blocked(const QpackBlockingManager* manager,
- QuicStreamId stream_id) {
- for (const auto& header_blocks_for_stream : manager->header_blocks_) {
- if (header_blocks_for_stream.first != stream_id) {
- continue;
- }
- for (const auto& indices : header_blocks_for_stream.second) {
- if (QpackBlockingManager::RequiredInsertCount(indices) >
- manager->known_received_count_) {
- return true;
- }
- }
- }
-
- return false;
- }
-};
-
-namespace {
-
-class QpackBlockingManagerTest : public QuicTest {
- protected:
- QpackBlockingManagerTest() = default;
- ~QpackBlockingManagerTest() override = default;
-
- bool stream_is_blocked(QuicStreamId stream_id) const {
- return QpackBlockingManagerPeer::stream_is_blocked(&manager_, stream_id);
- }
-
- QpackBlockingManager manager_;
-};
-
-TEST_F(QpackBlockingManagerTest, Empty) {
- EXPECT_EQ(0u, manager_.known_received_count());
- EXPECT_EQ(std::numeric_limits<uint64_t>::max(),
- manager_.smallest_blocking_index());
-
- EXPECT_FALSE(manager_.OnHeaderAcknowledgement(0));
- EXPECT_FALSE(manager_.OnHeaderAcknowledgement(1));
-}
-
-TEST_F(QpackBlockingManagerTest, NotBlockedByInsertCountIncrement) {
- EXPECT_TRUE(manager_.OnInsertCountIncrement(2));
-
- // Stream 0 is not blocked, because it only references entries that are
- // already acknowledged by an Insert Count Increment instruction.
- manager_.OnHeaderBlockSent(0, {1, 0});
- EXPECT_FALSE(stream_is_blocked(0));
-}
-
-TEST_F(QpackBlockingManagerTest, UnblockedByInsertCountIncrement) {
- manager_.OnHeaderBlockSent(0, {1, 0});
- EXPECT_TRUE(stream_is_blocked(0));
-
- EXPECT_TRUE(manager_.OnInsertCountIncrement(2));
- EXPECT_FALSE(stream_is_blocked(0));
-}
-
-TEST_F(QpackBlockingManagerTest, NotBlockedByHeaderAcknowledgement) {
- manager_.OnHeaderBlockSent(0, {2, 1, 1});
- EXPECT_TRUE(stream_is_blocked(0));
-
- EXPECT_TRUE(manager_.OnHeaderAcknowledgement(0));
- EXPECT_FALSE(stream_is_blocked(0));
-
- // Stream 1 is not blocked, because it only references entries that are
- // already acknowledged by a Header Acknowledgement instruction.
- manager_.OnHeaderBlockSent(1, {2, 2});
- EXPECT_FALSE(stream_is_blocked(1));
-}
-
-TEST_F(QpackBlockingManagerTest, UnblockedByHeaderAcknowledgement) {
- manager_.OnHeaderBlockSent(0, {2, 1, 1});
- manager_.OnHeaderBlockSent(1, {2, 2});
- EXPECT_TRUE(stream_is_blocked(0));
- EXPECT_TRUE(stream_is_blocked(1));
-
- EXPECT_TRUE(manager_.OnHeaderAcknowledgement(0));
- EXPECT_FALSE(stream_is_blocked(0));
- EXPECT_FALSE(stream_is_blocked(1));
-}
-
-TEST_F(QpackBlockingManagerTest, KnownReceivedCount) {
- EXPECT_EQ(0u, manager_.known_received_count());
-
- // Sending a header block does not change Known Received Count.
- manager_.OnHeaderBlockSent(0, {0});
- EXPECT_EQ(0u, manager_.known_received_count());
-
- manager_.OnHeaderBlockSent(1, {1});
- EXPECT_EQ(0u, manager_.known_received_count());
-
- // Header Acknowledgement might increase Known Received Count.
- EXPECT_TRUE(manager_.OnHeaderAcknowledgement(0));
- EXPECT_EQ(1u, manager_.known_received_count());
-
- manager_.OnHeaderBlockSent(2, {5});
- EXPECT_EQ(1u, manager_.known_received_count());
-
- EXPECT_TRUE(manager_.OnHeaderAcknowledgement(1));
- EXPECT_EQ(2u, manager_.known_received_count());
-
- // Insert Count Increment increases Known Received Count.
- EXPECT_TRUE(manager_.OnInsertCountIncrement(2));
- EXPECT_EQ(4u, manager_.known_received_count());
-
- EXPECT_TRUE(manager_.OnHeaderAcknowledgement(2));
- EXPECT_EQ(6u, manager_.known_received_count());
-
- // Stream Cancellation does not change Known Received Count.
- manager_.OnStreamCancellation(0);
- EXPECT_EQ(6u, manager_.known_received_count());
-
- // Header Acknowledgement of a block with smaller Required Insert Count does
- // not increase Known Received Count.
- manager_.OnHeaderBlockSent(0, {3});
- EXPECT_EQ(6u, manager_.known_received_count());
-
- EXPECT_TRUE(manager_.OnHeaderAcknowledgement(0));
- EXPECT_EQ(6u, manager_.known_received_count());
-
- // Header Acknowledgement of a block with equal Required Insert Count does not
- // increase Known Received Count.
- manager_.OnHeaderBlockSent(1, {5});
- EXPECT_EQ(6u, manager_.known_received_count());
-
- EXPECT_TRUE(manager_.OnHeaderAcknowledgement(1));
- EXPECT_EQ(6u, manager_.known_received_count());
-}
-
-TEST_F(QpackBlockingManagerTest, SmallestBlockingIndex) {
- EXPECT_EQ(std::numeric_limits<uint64_t>::max(),
- manager_.smallest_blocking_index());
-
- manager_.OnHeaderBlockSent(0, {0});
- EXPECT_EQ(0u, manager_.smallest_blocking_index());
-
- manager_.OnHeaderBlockSent(1, {2});
- EXPECT_EQ(0u, manager_.smallest_blocking_index());
-
- EXPECT_TRUE(manager_.OnHeaderAcknowledgement(0));
- EXPECT_EQ(2u, manager_.smallest_blocking_index());
-
- manager_.OnHeaderBlockSent(1, {1});
- EXPECT_EQ(1u, manager_.smallest_blocking_index());
-
- EXPECT_TRUE(manager_.OnHeaderAcknowledgement(1));
- EXPECT_EQ(1u, manager_.smallest_blocking_index());
-
- // Insert Count Increment does not change smallest blocking index.
- EXPECT_TRUE(manager_.OnInsertCountIncrement(2));
- EXPECT_EQ(1u, manager_.smallest_blocking_index());
-
- manager_.OnStreamCancellation(1);
- EXPECT_EQ(std::numeric_limits<uint64_t>::max(),
- manager_.smallest_blocking_index());
-}
-
-TEST_F(QpackBlockingManagerTest, HeaderAcknowledgementsOnSingleStream) {
- EXPECT_EQ(0u, manager_.known_received_count());
- EXPECT_EQ(std::numeric_limits<uint64_t>::max(),
- manager_.smallest_blocking_index());
-
- manager_.OnHeaderBlockSent(0, {2, 1, 1});
- EXPECT_EQ(0u, manager_.known_received_count());
- EXPECT_TRUE(stream_is_blocked(0));
- EXPECT_EQ(1u, manager_.smallest_blocking_index());
-
- manager_.OnHeaderBlockSent(0, {1, 0});
- EXPECT_EQ(0u, manager_.known_received_count());
- EXPECT_TRUE(stream_is_blocked(0));
- EXPECT_EQ(0u, manager_.smallest_blocking_index());
-
- EXPECT_TRUE(manager_.OnHeaderAcknowledgement(0));
- EXPECT_EQ(3u, manager_.known_received_count());
- EXPECT_FALSE(stream_is_blocked(0));
- EXPECT_EQ(0u, manager_.smallest_blocking_index());
-
- manager_.OnHeaderBlockSent(0, {3});
- EXPECT_EQ(3u, manager_.known_received_count());
- EXPECT_TRUE(stream_is_blocked(0));
- EXPECT_EQ(0u, manager_.smallest_blocking_index());
-
- EXPECT_TRUE(manager_.OnHeaderAcknowledgement(0));
- EXPECT_EQ(3u, manager_.known_received_count());
- EXPECT_TRUE(stream_is_blocked(0));
- EXPECT_EQ(3u, manager_.smallest_blocking_index());
-
- EXPECT_TRUE(manager_.OnHeaderAcknowledgement(0));
- EXPECT_EQ(4u, manager_.known_received_count());
- EXPECT_FALSE(stream_is_blocked(0));
- EXPECT_EQ(std::numeric_limits<uint64_t>::max(),
- manager_.smallest_blocking_index());
-
- EXPECT_FALSE(manager_.OnHeaderAcknowledgement(0));
-}
-
-TEST_F(QpackBlockingManagerTest, CancelStream) {
- manager_.OnHeaderBlockSent(0, {3});
- EXPECT_TRUE(stream_is_blocked(0));
- EXPECT_EQ(3u, manager_.smallest_blocking_index());
-
- manager_.OnHeaderBlockSent(0, {2});
- EXPECT_TRUE(stream_is_blocked(0));
- EXPECT_EQ(2u, manager_.smallest_blocking_index());
-
- manager_.OnHeaderBlockSent(1, {4});
- EXPECT_TRUE(stream_is_blocked(0));
- EXPECT_TRUE(stream_is_blocked(1));
- EXPECT_EQ(2u, manager_.smallest_blocking_index());
-
- manager_.OnStreamCancellation(0);
- EXPECT_FALSE(stream_is_blocked(0));
- EXPECT_TRUE(stream_is_blocked(1));
- EXPECT_EQ(4u, manager_.smallest_blocking_index());
-
- manager_.OnStreamCancellation(1);
- EXPECT_FALSE(stream_is_blocked(0));
- EXPECT_FALSE(stream_is_blocked(1));
- EXPECT_EQ(std::numeric_limits<uint64_t>::max(),
- manager_.smallest_blocking_index());
-}
-
-TEST_F(QpackBlockingManagerTest, BlockingAllowedOnStream) {
- const QuicStreamId kStreamId1 = 1;
- const QuicStreamId kStreamId2 = 2;
- const QuicStreamId kStreamId3 = 3;
-
- // No stream can block if limit is 0.
- EXPECT_FALSE(manager_.blocking_allowed_on_stream(kStreamId1, 0));
- EXPECT_FALSE(manager_.blocking_allowed_on_stream(kStreamId2, 0));
-
- // Either stream can block if limit is larger.
- EXPECT_TRUE(manager_.blocking_allowed_on_stream(kStreamId1, 1));
- EXPECT_TRUE(manager_.blocking_allowed_on_stream(kStreamId2, 1));
-
- // Doubly block first stream.
- manager_.OnHeaderBlockSent(kStreamId1, {0});
- manager_.OnHeaderBlockSent(kStreamId1, {1});
-
- // First stream is already blocked so it can carry more blocking references.
- EXPECT_TRUE(manager_.blocking_allowed_on_stream(kStreamId1, 1));
- // Second stream is not allowed to block if limit is already reached.
- EXPECT_FALSE(manager_.blocking_allowed_on_stream(kStreamId2, 1));
-
- // Either stream can block if limit is larger than number of blocked streams.
- EXPECT_TRUE(manager_.blocking_allowed_on_stream(kStreamId1, 2));
- EXPECT_TRUE(manager_.blocking_allowed_on_stream(kStreamId2, 2));
-
- // Block second stream.
- manager_.OnHeaderBlockSent(kStreamId2, {2});
-
- // Streams are already blocked so either can carry more blocking references.
- EXPECT_TRUE(manager_.blocking_allowed_on_stream(kStreamId1, 2));
- EXPECT_TRUE(manager_.blocking_allowed_on_stream(kStreamId2, 2));
-
- // Third, unblocked stream is not allowed to block unless limit is strictly
- // larger than number of blocked streams.
- EXPECT_FALSE(manager_.blocking_allowed_on_stream(kStreamId3, 2));
- EXPECT_TRUE(manager_.blocking_allowed_on_stream(kStreamId3, 3));
-
- // Acknowledge decoding of first header block on first stream.
- // Stream is still blocked on its second header block.
- manager_.OnHeaderAcknowledgement(kStreamId1);
-
- EXPECT_TRUE(manager_.blocking_allowed_on_stream(kStreamId1, 2));
- EXPECT_TRUE(manager_.blocking_allowed_on_stream(kStreamId2, 2));
-
- // Acknowledge decoding of second header block on first stream.
- // This unblocks the stream.
- manager_.OnHeaderAcknowledgement(kStreamId1);
-
- // First stream is not allowed to block if limit is already reached.
- EXPECT_FALSE(manager_.blocking_allowed_on_stream(kStreamId1, 1));
- // Second stream is already blocked so it can carry more blocking references.
- EXPECT_TRUE(manager_.blocking_allowed_on_stream(kStreamId2, 1));
-
- // Either stream can block if limit is larger than number of blocked streams.
- EXPECT_TRUE(manager_.blocking_allowed_on_stream(kStreamId1, 2));
- EXPECT_TRUE(manager_.blocking_allowed_on_stream(kStreamId2, 2));
-
- // Unblock second stream.
- manager_.OnHeaderAcknowledgement(kStreamId2);
-
- // No stream can block if limit is 0.
- EXPECT_FALSE(manager_.blocking_allowed_on_stream(kStreamId1, 0));
- EXPECT_FALSE(manager_.blocking_allowed_on_stream(kStreamId2, 0));
-
- // Either stream can block if limit is larger.
- EXPECT_TRUE(manager_.blocking_allowed_on_stream(kStreamId1, 1));
- EXPECT_TRUE(manager_.blocking_allowed_on_stream(kStreamId2, 1));
-}
-
-TEST_F(QpackBlockingManagerTest, InsertCountIncrementOverflow) {
- EXPECT_TRUE(manager_.OnInsertCountIncrement(10));
- EXPECT_EQ(10u, manager_.known_received_count());
-
- EXPECT_FALSE(manager_.OnInsertCountIncrement(
- std::numeric_limits<uint64_t>::max() - 5));
-}
-
-} // namespace
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_decoded_headers_accumulator.cc b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_decoded_headers_accumulator.cc
deleted file mode 100644
index 934cc5f0d4d..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_decoded_headers_accumulator.cc
+++ /dev/null
@@ -1,101 +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 "quic/core/qpack/qpack_decoded_headers_accumulator.h"
-
-#include "absl/strings/string_view.h"
-#include "quic/core/qpack/qpack_decoder.h"
-#include "quic/core/qpack/qpack_header_table.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-
-namespace quic {
-
-QpackDecodedHeadersAccumulator::QpackDecodedHeadersAccumulator(
- QuicStreamId id,
- QpackDecoder* qpack_decoder,
- Visitor* visitor,
- size_t max_header_list_size)
- : decoder_(qpack_decoder->CreateProgressiveDecoder(id, this)),
- visitor_(visitor),
- max_header_list_size_(max_header_list_size),
- uncompressed_header_bytes_including_overhead_(0),
- uncompressed_header_bytes_without_overhead_(0),
- compressed_header_bytes_(0),
- header_list_size_limit_exceeded_(false),
- headers_decoded_(false),
- error_detected_(false) {
- quic_header_list_.OnHeaderBlockStart();
-}
-
-void QpackDecodedHeadersAccumulator::OnHeaderDecoded(absl::string_view name,
- absl::string_view value) {
- QUICHE_DCHECK(!error_detected_);
-
- uncompressed_header_bytes_without_overhead_ += name.size() + value.size();
-
- if (header_list_size_limit_exceeded_) {
- return;
- }
-
- uncompressed_header_bytes_including_overhead_ +=
- name.size() + value.size() + kQpackEntrySizeOverhead;
-
- const size_t uncompressed_header_bytes =
- GetQuicFlag(FLAGS_quic_header_size_limit_includes_overhead)
- ? uncompressed_header_bytes_including_overhead_
- : uncompressed_header_bytes_without_overhead_;
- if (uncompressed_header_bytes > max_header_list_size_) {
- header_list_size_limit_exceeded_ = true;
- quic_header_list_.Clear();
- } else {
- quic_header_list_.OnHeader(name, value);
- }
-}
-
-void QpackDecodedHeadersAccumulator::OnDecodingCompleted() {
- QUICHE_DCHECK(!headers_decoded_);
- QUICHE_DCHECK(!error_detected_);
-
- headers_decoded_ = true;
-
- quic_header_list_.OnHeaderBlockEnd(
- uncompressed_header_bytes_without_overhead_, compressed_header_bytes_);
-
- // Might destroy |this|.
- visitor_->OnHeadersDecoded(std::move(quic_header_list_),
- header_list_size_limit_exceeded_);
-}
-
-void QpackDecodedHeadersAccumulator::OnDecodingErrorDetected(
- QuicErrorCode error_code, absl::string_view error_message) {
- QUICHE_DCHECK(!error_detected_);
- QUICHE_DCHECK(!headers_decoded_);
-
- error_detected_ = true;
- // Might destroy |this|.
- visitor_->OnHeaderDecodingError(error_code, error_message);
-}
-
-void QpackDecodedHeadersAccumulator::Decode(absl::string_view data) {
- QUICHE_DCHECK(!error_detected_);
-
- compressed_header_bytes_ += data.size();
- // Might destroy |this|.
- decoder_->Decode(data);
-}
-
-void QpackDecodedHeadersAccumulator::EndHeaderBlock() {
- QUICHE_DCHECK(!error_detected_);
- QUICHE_DCHECK(!headers_decoded_);
-
- if (!decoder_) {
- QUIC_BUG(b215142466_EndHeaderBlock);
- return;
- }
-
- // Might destroy |this|.
- decoder_->EndHeaderBlock();
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_decoded_headers_accumulator.h b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_decoded_headers_accumulator.h
deleted file mode 100644
index 57d1839d904..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_decoded_headers_accumulator.h
+++ /dev/null
@@ -1,106 +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_CORE_QPACK_QPACK_DECODED_HEADERS_ACCUMULATOR_H_
-#define QUICHE_QUIC_CORE_QPACK_QPACK_DECODED_HEADERS_ACCUMULATOR_H_
-
-#include <cstddef>
-#include <string>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/http/quic_header_list.h"
-#include "quic/core/qpack/qpack_progressive_decoder.h"
-#include "quic/core/quic_error_codes.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-class QpackDecoder;
-
-// A class that creates and owns a QpackProgressiveDecoder instance, accumulates
-// decoded headers in a QuicHeaderList, and keeps track of uncompressed and
-// compressed size so that it can be passed to
-// QuicHeaderList::OnHeaderBlockEnd().
-class QUIC_EXPORT_PRIVATE QpackDecodedHeadersAccumulator
- : public QpackProgressiveDecoder::HeadersHandlerInterface {
- public:
- // Visitor interface to signal success or error.
- // Exactly one method will be called.
- // Methods may be called synchronously from Decode() and EndHeaderBlock(),
- // or asynchronously.
- // Method implementations are allowed to destroy |this|.
- class QUIC_EXPORT_PRIVATE Visitor {
- public:
- virtual ~Visitor() = default;
-
- // Called when headers are successfully decoded. If the uncompressed header
- // list size including an overhead for each header field exceeds the limit
- // specified via |max_header_list_size| in QpackDecodedHeadersAccumulator
- // constructor, then |header_list_size_limit_exceeded| will be true, and
- // |headers| will be empty but will still have the correct compressed and
- // uncompressed size
- // information.
- virtual void OnHeadersDecoded(QuicHeaderList headers,
- bool header_list_size_limit_exceeded) = 0;
-
- // Called when an error has occurred.
- virtual void OnHeaderDecodingError(QuicErrorCode error_code,
- absl::string_view error_message) = 0;
- };
-
- QpackDecodedHeadersAccumulator(QuicStreamId id,
- QpackDecoder* qpack_decoder,
- Visitor* visitor,
- size_t max_header_list_size);
- virtual ~QpackDecodedHeadersAccumulator() = default;
-
- // QpackProgressiveDecoder::HeadersHandlerInterface implementation.
- // These methods should only be called by |decoder_|.
- void OnHeaderDecoded(absl::string_view name,
- absl::string_view value) override;
- void OnDecodingCompleted() override;
- void OnDecodingErrorDetected(QuicErrorCode error_code,
- absl::string_view error_message) override;
-
- // Decode payload data.
- // Must not be called if an error has been detected.
- // Must not be called after EndHeaderBlock().
- void Decode(absl::string_view data);
-
- // Signal end of HEADERS frame.
- // Must not be called if an error has been detected.
- // Must not be called more that once.
- void EndHeaderBlock();
-
- private:
- std::unique_ptr<QpackProgressiveDecoder> decoder_;
- Visitor* visitor_;
- // Maximum header list size including overhead.
- size_t max_header_list_size_;
- // Uncompressed header list size including overhead, for enforcing the limit.
- size_t uncompressed_header_bytes_including_overhead_;
- QuicHeaderList quic_header_list_;
- // Uncompressed header list size with overhead,
- // for passing in to QuicHeaderList::OnHeaderBlockEnd().
- size_t uncompressed_header_bytes_without_overhead_;
- // Compressed header list size
- // for passing in to QuicHeaderList::OnHeaderBlockEnd().
- size_t compressed_header_bytes_;
-
- // True if the header size limit has been exceeded.
- // Input data is still fed to QpackProgressiveDecoder.
- bool header_list_size_limit_exceeded_;
-
- // The following two members are only used for QUICHE_DCHECKs.
-
- // True if headers have been completedly and successfully decoded.
- bool headers_decoded_;
- // True if an error has been detected during decoding.
- bool error_detected_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_QPACK_QPACK_DECODED_HEADERS_ACCUMULATOR_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_decoded_headers_accumulator_test.cc b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_decoded_headers_accumulator_test.cc
deleted file mode 100644
index 0aa08a05d5c..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_decoded_headers_accumulator_test.cc
+++ /dev/null
@@ -1,253 +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 "quic/core/qpack/qpack_decoded_headers_accumulator.h"
-
-#include <cstring>
-
-#include "absl/strings/escaping.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/qpack/qpack_decoder.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/qpack/qpack_decoder_test_utils.h"
-#include "quic/test_tools/qpack/qpack_test_utils.h"
-
-using ::testing::_;
-using ::testing::ElementsAre;
-using ::testing::Eq;
-using ::testing::Pair;
-using ::testing::SaveArg;
-using ::testing::StrictMock;
-
-namespace quic {
-namespace test {
-namespace {
-
-// Arbitrary stream ID used for testing.
-QuicStreamId kTestStreamId = 1;
-
-// Limit on header list size.
-const size_t kMaxHeaderListSize = 100;
-
-// Maximum dynamic table capacity.
-const size_t kMaxDynamicTableCapacity = 100;
-
-// Maximum number of blocked streams.
-const uint64_t kMaximumBlockedStreams = 1;
-
-// Header Acknowledgement decoder stream instruction with stream_id = 1.
-const char* const kHeaderAcknowledgement = "\x81";
-
-class MockVisitor : public QpackDecodedHeadersAccumulator::Visitor {
- public:
- ~MockVisitor() override = default;
- MOCK_METHOD(void,
- OnHeadersDecoded,
- (QuicHeaderList headers, bool header_list_size_limit_exceeded),
- (override));
- MOCK_METHOD(void, OnHeaderDecodingError,
- (QuicErrorCode error_code, absl::string_view error_message),
- (override));
-};
-
-} // anonymous namespace
-
-class QpackDecodedHeadersAccumulatorTest : public QuicTest {
- protected:
- QpackDecodedHeadersAccumulatorTest()
- : qpack_decoder_(kMaxDynamicTableCapacity,
- kMaximumBlockedStreams,
- &encoder_stream_error_delegate_),
- accumulator_(kTestStreamId,
- &qpack_decoder_,
- &visitor_,
- kMaxHeaderListSize) {
- qpack_decoder_.set_qpack_stream_sender_delegate(
- &decoder_stream_sender_delegate_);
- }
-
- NoopEncoderStreamErrorDelegate encoder_stream_error_delegate_;
- StrictMock<MockQpackStreamSenderDelegate> decoder_stream_sender_delegate_;
- QpackDecoder qpack_decoder_;
- StrictMock<MockVisitor> visitor_;
- QpackDecodedHeadersAccumulator accumulator_;
-};
-
-// HEADERS frame payload must have a complete Header Block Prefix.
-TEST_F(QpackDecodedHeadersAccumulatorTest, EmptyPayload) {
- EXPECT_CALL(visitor_,
- OnHeaderDecodingError(QUIC_QPACK_DECOMPRESSION_FAILED,
- Eq("Incomplete header data prefix.")));
- accumulator_.EndHeaderBlock();
-}
-
-// HEADERS frame payload must have a complete Header Block Prefix.
-TEST_F(QpackDecodedHeadersAccumulatorTest, TruncatedHeaderBlockPrefix) {
- accumulator_.Decode(absl::HexStringToBytes("00"));
-
- EXPECT_CALL(visitor_,
- OnHeaderDecodingError(QUIC_QPACK_DECOMPRESSION_FAILED,
- Eq("Incomplete header data prefix.")));
- accumulator_.EndHeaderBlock();
-}
-
-TEST_F(QpackDecodedHeadersAccumulatorTest, EmptyHeaderList) {
- std::string encoded_data(absl::HexStringToBytes("0000"));
- accumulator_.Decode(encoded_data);
-
- QuicHeaderList header_list;
- EXPECT_CALL(visitor_, OnHeadersDecoded(_, false))
- .WillOnce(SaveArg<0>(&header_list));
- accumulator_.EndHeaderBlock();
-
- EXPECT_EQ(0u, header_list.uncompressed_header_bytes());
- EXPECT_EQ(encoded_data.size(), header_list.compressed_header_bytes());
- EXPECT_TRUE(header_list.empty());
-}
-
-// This payload is the prefix of a valid payload, but EndHeaderBlock() is called
-// before it can be completely decoded.
-TEST_F(QpackDecodedHeadersAccumulatorTest, TruncatedPayload) {
- accumulator_.Decode(absl::HexStringToBytes("00002366"));
-
- EXPECT_CALL(visitor_, OnHeaderDecodingError(QUIC_QPACK_DECOMPRESSION_FAILED,
- Eq("Incomplete header block.")));
- accumulator_.EndHeaderBlock();
-}
-
-// This payload is invalid because it refers to a non-existing static entry.
-TEST_F(QpackDecodedHeadersAccumulatorTest, InvalidPayload) {
- EXPECT_CALL(visitor_,
- OnHeaderDecodingError(QUIC_QPACK_DECOMPRESSION_FAILED,
- Eq("Static table entry not found.")));
- accumulator_.Decode(absl::HexStringToBytes("0000ff23ff24"));
-}
-
-TEST_F(QpackDecodedHeadersAccumulatorTest, Success) {
- std::string encoded_data(absl::HexStringToBytes("000023666f6f03626172"));
- accumulator_.Decode(encoded_data);
-
- QuicHeaderList header_list;
- EXPECT_CALL(visitor_, OnHeadersDecoded(_, false))
- .WillOnce(SaveArg<0>(&header_list));
- accumulator_.EndHeaderBlock();
-
- EXPECT_THAT(header_list, ElementsAre(Pair("foo", "bar")));
- EXPECT_EQ(strlen("foo") + strlen("bar"),
- header_list.uncompressed_header_bytes());
- EXPECT_EQ(encoded_data.size(), header_list.compressed_header_bytes());
-}
-
-// Test that Decode() calls are not ignored after header list limit is exceeded,
-// otherwise decoding could fail with "incomplete header block" error.
-TEST_F(QpackDecodedHeadersAccumulatorTest, ExceedLimitThenSplitInstruction) {
- // Total length of header list exceeds kMaxHeaderListSize.
- accumulator_.Decode(absl::HexStringToBytes(
- "0000" // header block prefix
- "26666f6f626172" // header key: "foobar"
- "7d61616161616161616161616161616161616161" // header value: 'a' 125 times
- "616161616161616161616161616161616161616161616161616161616161616161616161"
- "616161616161616161616161616161616161616161616161616161616161616161616161"
- "61616161616161616161616161616161616161616161616161616161616161616161"
- "ff")); // first byte of a two-byte long Indexed Header Field instruction
- accumulator_.Decode(absl::HexStringToBytes(
- "0f" // second byte of a two-byte long Indexed Header Field instruction
- ));
-
- EXPECT_CALL(visitor_, OnHeadersDecoded(_, true));
- accumulator_.EndHeaderBlock();
-}
-
-// Test that header list limit enforcement works with blocked encoding.
-TEST_F(QpackDecodedHeadersAccumulatorTest, ExceedLimitBlocked) {
- // Total length of header list exceeds kMaxHeaderListSize.
- accumulator_.Decode(absl::HexStringToBytes(
- "0200" // header block prefix
- "80" // reference to dynamic table entry not yet received
- "26666f6f626172" // header key: "foobar"
- "7d61616161616161616161616161616161616161" // header value: 'a' 125 times
- "616161616161616161616161616161616161616161616161616161616161616161616161"
- "616161616161616161616161616161616161616161616161616161616161616161616161"
- "61616161616161616161616161616161616161616161616161616161616161616161"));
- accumulator_.EndHeaderBlock();
-
- // Set dynamic table capacity.
- qpack_decoder_.OnSetDynamicTableCapacity(kMaxDynamicTableCapacity);
- // Adding dynamic table entry unblocks decoding.
- EXPECT_CALL(decoder_stream_sender_delegate_,
- WriteStreamData(Eq(kHeaderAcknowledgement)));
-
- EXPECT_CALL(visitor_, OnHeadersDecoded(_, true));
- qpack_decoder_.OnInsertWithoutNameReference("foo", "bar");
-}
-
-TEST_F(QpackDecodedHeadersAccumulatorTest, BlockedDecoding) {
- // Reference to dynamic table entry not yet received.
- std::string encoded_data(absl::HexStringToBytes("020080"));
- accumulator_.Decode(encoded_data);
- accumulator_.EndHeaderBlock();
-
- // Set dynamic table capacity.
- qpack_decoder_.OnSetDynamicTableCapacity(kMaxDynamicTableCapacity);
- // Adding dynamic table entry unblocks decoding.
- EXPECT_CALL(decoder_stream_sender_delegate_,
- WriteStreamData(Eq(kHeaderAcknowledgement)));
-
- QuicHeaderList header_list;
- EXPECT_CALL(visitor_, OnHeadersDecoded(_, false))
- .WillOnce(SaveArg<0>(&header_list));
- qpack_decoder_.OnInsertWithoutNameReference("foo", "bar");
-
- EXPECT_THAT(header_list, ElementsAre(Pair("foo", "bar")));
- EXPECT_EQ(strlen("foo") + strlen("bar"),
- header_list.uncompressed_header_bytes());
- EXPECT_EQ(encoded_data.size(), header_list.compressed_header_bytes());
-}
-
-TEST_F(QpackDecodedHeadersAccumulatorTest,
- BlockedDecodingUnblockedBeforeEndOfHeaderBlock) {
- // Reference to dynamic table entry not yet received.
- accumulator_.Decode(absl::HexStringToBytes("020080"));
-
- // Set dynamic table capacity.
- qpack_decoder_.OnSetDynamicTableCapacity(kMaxDynamicTableCapacity);
- // Adding dynamic table entry unblocks decoding.
- qpack_decoder_.OnInsertWithoutNameReference("foo", "bar");
-
- // Rest of header block: same entry again.
- EXPECT_CALL(decoder_stream_sender_delegate_,
- WriteStreamData(Eq(kHeaderAcknowledgement)));
- accumulator_.Decode(absl::HexStringToBytes("80"));
-
- QuicHeaderList header_list;
- EXPECT_CALL(visitor_, OnHeadersDecoded(_, false))
- .WillOnce(SaveArg<0>(&header_list));
- accumulator_.EndHeaderBlock();
-
- EXPECT_THAT(header_list, ElementsAre(Pair("foo", "bar"), Pair("foo", "bar")));
-}
-
-// Regression test for https://crbug.com/1024263.
-TEST_F(QpackDecodedHeadersAccumulatorTest,
- BlockedDecodingUnblockedAndErrorBeforeEndOfHeaderBlock) {
- // Required Insert Count higher than number of entries causes decoding to be
- // blocked.
- accumulator_.Decode(absl::HexStringToBytes("0200"));
- // Indexed Header Field instruction addressing dynamic table entry with
- // relative index 0, absolute index 0.
- accumulator_.Decode(absl::HexStringToBytes("80"));
- // Relative index larger than or equal to Base is invalid.
- accumulator_.Decode(absl::HexStringToBytes("81"));
-
- // Set dynamic table capacity.
- qpack_decoder_.OnSetDynamicTableCapacity(kMaxDynamicTableCapacity);
-
- // Adding dynamic table entry unblocks decoding. Error is detected.
- EXPECT_CALL(visitor_, OnHeaderDecodingError(QUIC_QPACK_DECOMPRESSION_FAILED,
- Eq("Invalid relative index.")));
- qpack_decoder_.OnInsertWithoutNameReference("foo", "bar");
-}
-
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_decoder.cc b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_decoder.cc
deleted file mode 100644
index b9926167126..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_decoder.cc
+++ /dev/null
@@ -1,171 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/qpack/qpack_decoder.h"
-
-#include <utility>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/qpack/qpack_index_conversions.h"
-#include "quic/platform/api/quic_flag_utils.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-QpackDecoder::QpackDecoder(
- uint64_t maximum_dynamic_table_capacity,
- uint64_t maximum_blocked_streams,
- EncoderStreamErrorDelegate* encoder_stream_error_delegate)
- : encoder_stream_error_delegate_(encoder_stream_error_delegate),
- encoder_stream_receiver_(this),
- maximum_blocked_streams_(maximum_blocked_streams),
- known_received_count_(0) {
- QUICHE_DCHECK(encoder_stream_error_delegate_);
-
- header_table_.SetMaximumDynamicTableCapacity(maximum_dynamic_table_capacity);
-}
-
-QpackDecoder::~QpackDecoder() {}
-
-void QpackDecoder::OnStreamReset(QuicStreamId stream_id) {
- if (header_table_.maximum_dynamic_table_capacity() > 0) {
- decoder_stream_sender_.SendStreamCancellation(stream_id);
- decoder_stream_sender_.Flush();
- }
-}
-
-bool QpackDecoder::OnStreamBlocked(QuicStreamId stream_id) {
- auto result = blocked_streams_.insert(stream_id);
- QUICHE_DCHECK(result.second);
- return blocked_streams_.size() <= maximum_blocked_streams_;
-}
-
-void QpackDecoder::OnStreamUnblocked(QuicStreamId stream_id) {
- size_t result = blocked_streams_.erase(stream_id);
- QUICHE_DCHECK_EQ(1u, result);
-}
-
-void QpackDecoder::OnDecodingCompleted(QuicStreamId stream_id,
- uint64_t required_insert_count) {
- if (required_insert_count > 0) {
- decoder_stream_sender_.SendHeaderAcknowledgement(stream_id);
-
- if (known_received_count_ < required_insert_count) {
- known_received_count_ = required_insert_count;
- }
- }
-
- // Send an Insert Count Increment instruction if not all dynamic table entries
- // have been acknowledged yet. This is necessary for efficient compression in
- // case the encoder chooses not to reference unacknowledged dynamic table
- // entries, otherwise inserted entries would never be acknowledged.
- if (known_received_count_ < header_table_.inserted_entry_count()) {
- decoder_stream_sender_.SendInsertCountIncrement(
- header_table_.inserted_entry_count() - known_received_count_);
- known_received_count_ = header_table_.inserted_entry_count();
- }
-
- decoder_stream_sender_.Flush();
-}
-
-void QpackDecoder::OnInsertWithNameReference(bool is_static,
- uint64_t name_index,
- absl::string_view value) {
- if (is_static) {
- auto entry = header_table_.LookupEntry(/* is_static = */ true, name_index);
- if (!entry) {
- OnErrorDetected(QUIC_QPACK_ENCODER_STREAM_INVALID_STATIC_ENTRY,
- "Invalid static table entry.");
- return;
- }
-
- if (!header_table_.EntryFitsDynamicTableCapacity(entry->name(), value)) {
- OnErrorDetected(QUIC_QPACK_ENCODER_STREAM_ERROR_INSERTING_STATIC,
- "Error inserting entry with name reference.");
- return;
- }
- header_table_.InsertEntry(entry->name(), value);
- return;
- }
-
- uint64_t absolute_index;
- if (!QpackEncoderStreamRelativeIndexToAbsoluteIndex(
- name_index, header_table_.inserted_entry_count(), &absolute_index)) {
- OnErrorDetected(QUIC_QPACK_ENCODER_STREAM_INSERTION_INVALID_RELATIVE_INDEX,
- "Invalid relative index.");
- return;
- }
-
- const QpackEntry* entry =
- header_table_.LookupEntry(/* is_static = */ false, absolute_index);
- if (!entry) {
- OnErrorDetected(QUIC_QPACK_ENCODER_STREAM_INSERTION_DYNAMIC_ENTRY_NOT_FOUND,
- "Dynamic table entry not found.");
- return;
- }
- if (!header_table_.EntryFitsDynamicTableCapacity(entry->name(), value)) {
- OnErrorDetected(QUIC_QPACK_ENCODER_STREAM_ERROR_INSERTING_DYNAMIC,
- "Error inserting entry with name reference.");
- return;
- }
- header_table_.InsertEntry(entry->name(), value);
-}
-
-void QpackDecoder::OnInsertWithoutNameReference(absl::string_view name,
- absl::string_view value) {
- if (!header_table_.EntryFitsDynamicTableCapacity(name, value)) {
- OnErrorDetected(QUIC_QPACK_ENCODER_STREAM_ERROR_INSERTING_LITERAL,
- "Error inserting literal entry.");
- return;
- }
- header_table_.InsertEntry(name, value);
-}
-
-void QpackDecoder::OnDuplicate(uint64_t index) {
- uint64_t absolute_index;
- if (!QpackEncoderStreamRelativeIndexToAbsoluteIndex(
- index, header_table_.inserted_entry_count(), &absolute_index)) {
- OnErrorDetected(QUIC_QPACK_ENCODER_STREAM_DUPLICATE_INVALID_RELATIVE_INDEX,
- "Invalid relative index.");
- return;
- }
-
- const QpackEntry* entry =
- header_table_.LookupEntry(/* is_static = */ false, absolute_index);
- if (!entry) {
- OnErrorDetected(QUIC_QPACK_ENCODER_STREAM_DUPLICATE_DYNAMIC_ENTRY_NOT_FOUND,
- "Dynamic table entry not found.");
- return;
- }
- if (!header_table_.EntryFitsDynamicTableCapacity(entry->name(),
- entry->value())) {
- // This is impossible since entry was retrieved from the dynamic table.
- OnErrorDetected(QUIC_INTERNAL_ERROR, "Error inserting duplicate entry.");
- return;
- }
- header_table_.InsertEntry(entry->name(), entry->value());
-}
-
-void QpackDecoder::OnSetDynamicTableCapacity(uint64_t capacity) {
- if (!header_table_.SetDynamicTableCapacity(capacity)) {
- OnErrorDetected(QUIC_QPACK_ENCODER_STREAM_SET_DYNAMIC_TABLE_CAPACITY,
- "Error updating dynamic table capacity.");
- }
-}
-
-void QpackDecoder::OnErrorDetected(QuicErrorCode error_code,
- absl::string_view error_message) {
- encoder_stream_error_delegate_->OnEncoderStreamError(error_code,
- error_message);
-}
-
-std::unique_ptr<QpackProgressiveDecoder> QpackDecoder::CreateProgressiveDecoder(
- QuicStreamId stream_id,
- QpackProgressiveDecoder::HeadersHandlerInterface* handler) {
- return std::make_unique<QpackProgressiveDecoder>(stream_id, this, this,
- &header_table_, handler);
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_decoder.h b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_decoder.h
deleted file mode 100644
index b947ce3cf0e..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_decoder.h
+++ /dev/null
@@ -1,128 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QPACK_QPACK_DECODER_H_
-#define QUICHE_QUIC_CORE_QPACK_QPACK_DECODER_H_
-
-#include <cstdint>
-#include <memory>
-#include <set>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/qpack/qpack_decoder_stream_sender.h"
-#include "quic/core/qpack/qpack_encoder_stream_receiver.h"
-#include "quic/core/qpack/qpack_header_table.h"
-#include "quic/core/qpack/qpack_progressive_decoder.h"
-#include "quic/core/quic_error_codes.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// QPACK decoder class. Exactly one instance should exist per QUIC connection.
-// This class vends a new QpackProgressiveDecoder instance for each new header
-// list to be encoded.
-// QpackProgressiveDecoder detects and signals errors with header blocks, which
-// are stream errors.
-// The only input of QpackDecoder is the encoder stream. Any error QpackDecoder
-// signals is an encoder stream error, which is fatal to the connection.
-class QUIC_EXPORT_PRIVATE QpackDecoder
- : public QpackEncoderStreamReceiver::Delegate,
- public QpackProgressiveDecoder::BlockedStreamLimitEnforcer,
- public QpackProgressiveDecoder::DecodingCompletedVisitor {
- public:
- // Interface for receiving notification that an error has occurred on the
- // encoder stream. This MUST be treated as a connection error of type
- // HTTP_QPACK_ENCODER_STREAM_ERROR.
- class QUIC_EXPORT_PRIVATE EncoderStreamErrorDelegate {
- public:
- virtual ~EncoderStreamErrorDelegate() {}
-
- virtual void OnEncoderStreamError(QuicErrorCode error_code,
- absl::string_view error_message) = 0;
- };
-
- QpackDecoder(uint64_t maximum_dynamic_table_capacity,
- uint64_t maximum_blocked_streams,
- EncoderStreamErrorDelegate* encoder_stream_error_delegate);
- ~QpackDecoder() override;
-
- // Signal to the peer's encoder that a stream is reset. This lets the peer's
- // encoder know that no more header blocks will be processed on this stream,
- // therefore references to dynamic table entries shall not prevent their
- // eviction.
- // This method should be called regardless of whether a header block is being
- // decoded on that stream, because a header block might be in flight from the
- // peer.
- // This method should be called every time a request or push stream is reset
- // for any reason: for example, client cancels request, or a decoding error
- // occurs and HeadersHandlerInterface::OnDecodingErrorDetected() is called.
- // This method should also be called if the stream is reset by the peer,
- // because the peer's encoder can only evict entries referenced by header
- // blocks once it receives acknowledgement from this endpoint that the stream
- // is reset.
- // However, this method should not be called if the stream is closed normally
- // using the FIN bit.
- void OnStreamReset(QuicStreamId stream_id);
-
- // QpackProgressiveDecoder::BlockedStreamLimitEnforcer implementation.
- bool OnStreamBlocked(QuicStreamId stream_id) override;
- void OnStreamUnblocked(QuicStreamId stream_id) override;
-
- // QpackProgressiveDecoder::DecodingCompletedVisitor implementation.
- void OnDecodingCompleted(QuicStreamId stream_id,
- uint64_t required_insert_count) override;
-
- // Factory method to create a QpackProgressiveDecoder for decoding a header
- // block. |handler| must remain valid until the returned
- // QpackProgressiveDecoder instance is destroyed or the decoder calls
- // |handler->OnHeaderBlockEnd()|.
- std::unique_ptr<QpackProgressiveDecoder> CreateProgressiveDecoder(
- QuicStreamId stream_id,
- QpackProgressiveDecoder::HeadersHandlerInterface* handler);
-
- // QpackEncoderStreamReceiver::Delegate implementation
- void OnInsertWithNameReference(bool is_static,
- uint64_t name_index,
- absl::string_view value) override;
- void OnInsertWithoutNameReference(absl::string_view name,
- absl::string_view value) override;
- void OnDuplicate(uint64_t index) override;
- void OnSetDynamicTableCapacity(uint64_t capacity) override;
- void OnErrorDetected(QuicErrorCode error_code,
- absl::string_view error_message) override;
-
- // delegate must be set if dynamic table capacity is not zero.
- void set_qpack_stream_sender_delegate(QpackStreamSenderDelegate* delegate) {
- decoder_stream_sender_.set_qpack_stream_sender_delegate(delegate);
- }
-
- QpackStreamReceiver* encoder_stream_receiver() {
- return &encoder_stream_receiver_;
- }
-
- // True if any dynamic table entries have been referenced from a header block.
- bool dynamic_table_entry_referenced() const {
- return header_table_.dynamic_table_entry_referenced();
- }
-
- private:
- EncoderStreamErrorDelegate* const encoder_stream_error_delegate_;
- QpackEncoderStreamReceiver encoder_stream_receiver_;
- QpackDecoderStreamSender decoder_stream_sender_;
- QpackDecoderHeaderTable header_table_;
- std::set<QuicStreamId> blocked_streams_;
- const uint64_t maximum_blocked_streams_;
-
- // Known Received Count is the number of insertions the encoder has received
- // acknowledgement for (through Header Acknowledgement and Insert Count
- // Increment instructions). The encoder must keep track of it in order to be
- // able to send Insert Count Increment instructions. See
- // https://quicwg.org/base-drafts/draft-ietf-quic-qpack.html#known-received-count.
- uint64_t known_received_count_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_QPACK_QPACK_DECODER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_decoder_stream_receiver.cc b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_decoder_stream_receiver.cc
deleted file mode 100644
index aed660ef4d3..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_decoder_stream_receiver.cc
+++ /dev/null
@@ -1,62 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/qpack/qpack_decoder_stream_receiver.h"
-
-#include "absl/strings/string_view.h"
-#include "http2/decoder/decode_buffer.h"
-#include "http2/decoder/decode_status.h"
-#include "quic/core/qpack/qpack_instructions.h"
-
-namespace quic {
-
-QpackDecoderStreamReceiver::QpackDecoderStreamReceiver(Delegate* delegate)
- : instruction_decoder_(QpackDecoderStreamLanguage(), this),
- delegate_(delegate),
- error_detected_(false) {
- QUICHE_DCHECK(delegate_);
-}
-
-void QpackDecoderStreamReceiver::Decode(absl::string_view data) {
- if (data.empty() || error_detected_) {
- return;
- }
-
- instruction_decoder_.Decode(data);
-}
-
-bool QpackDecoderStreamReceiver::OnInstructionDecoded(
- const QpackInstruction* instruction) {
- if (instruction == InsertCountIncrementInstruction()) {
- delegate_->OnInsertCountIncrement(instruction_decoder_.varint());
- return true;
- }
-
- if (instruction == HeaderAcknowledgementInstruction()) {
- delegate_->OnHeaderAcknowledgement(instruction_decoder_.varint());
- return true;
- }
-
- QUICHE_DCHECK_EQ(instruction, StreamCancellationInstruction());
- delegate_->OnStreamCancellation(instruction_decoder_.varint());
- return true;
-}
-
-void QpackDecoderStreamReceiver::OnInstructionDecodingError(
- QpackInstructionDecoder::ErrorCode error_code,
- absl::string_view error_message) {
- QUICHE_DCHECK(!error_detected_);
-
- error_detected_ = true;
-
- // There is no string literals on the decoder stream,
- // the only possible error is INTEGER_TOO_LARGE.
- QuicErrorCode quic_error_code =
- (error_code == QpackInstructionDecoder::ErrorCode::INTEGER_TOO_LARGE)
- ? QUIC_QPACK_DECODER_STREAM_INTEGER_TOO_LARGE
- : QUIC_INTERNAL_ERROR;
- delegate_->OnErrorDetected(quic_error_code, error_message);
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_decoder_stream_receiver.h b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_decoder_stream_receiver.h
deleted file mode 100644
index 026c7b96892..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_decoder_stream_receiver.h
+++ /dev/null
@@ -1,69 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QPACK_QPACK_DECODER_STREAM_RECEIVER_H_
-#define QUICHE_QUIC_CORE_QPACK_QPACK_DECODER_STREAM_RECEIVER_H_
-
-#include <cstdint>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/qpack/qpack_instruction_decoder.h"
-#include "quic/core/qpack/qpack_stream_receiver.h"
-#include "quic/core/quic_error_codes.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// This class decodes data received on the decoder stream,
-// and passes it along to its Delegate.
-class QUIC_EXPORT_PRIVATE QpackDecoderStreamReceiver
- : public QpackInstructionDecoder::Delegate,
- public QpackStreamReceiver {
- public:
- // An interface for handling instructions decoded from the decoder stream, see
- // https://quicwg.org/base-drafts/draft-ietf-quic-qpack.html#rfc.section.5.3
- class QUIC_EXPORT_PRIVATE Delegate {
- public:
- virtual ~Delegate() = default;
-
- // 5.3.1 Insert Count Increment
- virtual void OnInsertCountIncrement(uint64_t increment) = 0;
- // 5.3.2 Header Acknowledgement
- virtual void OnHeaderAcknowledgement(QuicStreamId stream_id) = 0;
- // 5.3.3 Stream Cancellation
- virtual void OnStreamCancellation(QuicStreamId stream_id) = 0;
- // Decoding error
- virtual void OnErrorDetected(QuicErrorCode error_code,
- absl::string_view error_message) = 0;
- };
-
- explicit QpackDecoderStreamReceiver(Delegate* delegate);
- QpackDecoderStreamReceiver() = delete;
- QpackDecoderStreamReceiver(const QpackDecoderStreamReceiver&) = delete;
- QpackDecoderStreamReceiver& operator=(const QpackDecoderStreamReceiver&) =
- delete;
-
- // Implements QpackStreamReceiver::Decode().
- // Decode data and call appropriate Delegate method after each decoded
- // instruction. Once an error occurs, Delegate::OnErrorDetected() is called,
- // and all further data is ignored.
- void Decode(absl::string_view data) override;
-
- // QpackInstructionDecoder::Delegate implementation.
- bool OnInstructionDecoded(const QpackInstruction* instruction) override;
- void OnInstructionDecodingError(QpackInstructionDecoder::ErrorCode error_code,
- absl::string_view error_message) override;
-
- private:
- QpackInstructionDecoder instruction_decoder_;
- Delegate* const delegate_;
-
- // True if a decoding error has been detected.
- bool error_detected_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_QPACK_QPACK_DECODER_STREAM_RECEIVER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_decoder_stream_receiver_test.cc b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_decoder_stream_receiver_test.cc
deleted file mode 100644
index 0a76a17450f..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_decoder_stream_receiver_test.cc
+++ /dev/null
@@ -1,102 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/qpack/qpack_decoder_stream_receiver.h"
-
-#include "absl/strings/escaping.h"
-#include "absl/strings/string_view.h"
-#include "quic/platform/api/quic_test.h"
-
-using testing::Eq;
-using testing::StrictMock;
-
-namespace quic {
-namespace test {
-namespace {
-
-class MockDelegate : public QpackDecoderStreamReceiver::Delegate {
- public:
- ~MockDelegate() override = default;
-
- MOCK_METHOD(void, OnInsertCountIncrement, (uint64_t increment), (override));
- MOCK_METHOD(void,
- OnHeaderAcknowledgement,
- (QuicStreamId stream_id),
- (override));
- MOCK_METHOD(void, OnStreamCancellation, (QuicStreamId stream_id), (override));
- MOCK_METHOD(void,
- OnErrorDetected,
- (QuicErrorCode error_code, absl::string_view error_message),
- (override));
-};
-
-class QpackDecoderStreamReceiverTest : public QuicTest {
- protected:
- QpackDecoderStreamReceiverTest() : stream_(&delegate_) {}
- ~QpackDecoderStreamReceiverTest() override = default;
-
- QpackDecoderStreamReceiver stream_;
- StrictMock<MockDelegate> delegate_;
-};
-
-TEST_F(QpackDecoderStreamReceiverTest, InsertCountIncrement) {
- EXPECT_CALL(delegate_, OnInsertCountIncrement(0));
- stream_.Decode(absl::HexStringToBytes("00"));
-
- EXPECT_CALL(delegate_, OnInsertCountIncrement(10));
- stream_.Decode(absl::HexStringToBytes("0a"));
-
- EXPECT_CALL(delegate_, OnInsertCountIncrement(63));
- stream_.Decode(absl::HexStringToBytes("3f00"));
-
- EXPECT_CALL(delegate_, OnInsertCountIncrement(200));
- stream_.Decode(absl::HexStringToBytes("3f8901"));
-
- EXPECT_CALL(delegate_,
- OnErrorDetected(QUIC_QPACK_DECODER_STREAM_INTEGER_TOO_LARGE,
- Eq("Encoded integer too large.")));
- stream_.Decode(absl::HexStringToBytes("3fffffffffffffffffffff"));
-}
-
-TEST_F(QpackDecoderStreamReceiverTest, HeaderAcknowledgement) {
- EXPECT_CALL(delegate_, OnHeaderAcknowledgement(0));
- stream_.Decode(absl::HexStringToBytes("80"));
-
- EXPECT_CALL(delegate_, OnHeaderAcknowledgement(37));
- stream_.Decode(absl::HexStringToBytes("a5"));
-
- EXPECT_CALL(delegate_, OnHeaderAcknowledgement(127));
- stream_.Decode(absl::HexStringToBytes("ff00"));
-
- EXPECT_CALL(delegate_, OnHeaderAcknowledgement(503));
- stream_.Decode(absl::HexStringToBytes("fff802"));
-
- EXPECT_CALL(delegate_,
- OnErrorDetected(QUIC_QPACK_DECODER_STREAM_INTEGER_TOO_LARGE,
- Eq("Encoded integer too large.")));
- stream_.Decode(absl::HexStringToBytes("ffffffffffffffffffffff"));
-}
-
-TEST_F(QpackDecoderStreamReceiverTest, StreamCancellation) {
- EXPECT_CALL(delegate_, OnStreamCancellation(0));
- stream_.Decode(absl::HexStringToBytes("40"));
-
- EXPECT_CALL(delegate_, OnStreamCancellation(19));
- stream_.Decode(absl::HexStringToBytes("53"));
-
- EXPECT_CALL(delegate_, OnStreamCancellation(63));
- stream_.Decode(absl::HexStringToBytes("7f00"));
-
- EXPECT_CALL(delegate_, OnStreamCancellation(110));
- stream_.Decode(absl::HexStringToBytes("7f2f"));
-
- EXPECT_CALL(delegate_,
- OnErrorDetected(QUIC_QPACK_DECODER_STREAM_INTEGER_TOO_LARGE,
- Eq("Encoded integer too large.")));
- stream_.Decode(absl::HexStringToBytes("7fffffffffffffffffffff"));
-}
-
-} // namespace
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_decoder_stream_sender.cc b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_decoder_stream_sender.cc
deleted file mode 100644
index 9e2488d3a72..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_decoder_stream_sender.cc
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/qpack/qpack_decoder_stream_sender.h"
-
-#include <cstddef>
-#include <limits>
-#include <string>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/qpack/qpack_instructions.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-QpackDecoderStreamSender::QpackDecoderStreamSender() : delegate_(nullptr) {}
-
-void QpackDecoderStreamSender::SendInsertCountIncrement(uint64_t increment) {
- instruction_encoder_.Encode(
- QpackInstructionWithValues::InsertCountIncrement(increment), &buffer_);
-}
-
-void QpackDecoderStreamSender::SendHeaderAcknowledgement(
- QuicStreamId stream_id) {
- instruction_encoder_.Encode(
- QpackInstructionWithValues::HeaderAcknowledgement(stream_id), &buffer_);
-}
-
-void QpackDecoderStreamSender::SendStreamCancellation(QuicStreamId stream_id) {
- instruction_encoder_.Encode(
- QpackInstructionWithValues::StreamCancellation(stream_id), &buffer_);
-}
-
-void QpackDecoderStreamSender::Flush() {
- if (buffer_.empty()) {
- return;
- }
-
- delegate_->WriteStreamData(buffer_);
- buffer_.clear();
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_decoder_stream_sender.h b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_decoder_stream_sender.h
deleted file mode 100644
index c554651f6d7..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_decoder_stream_sender.h
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QPACK_QPACK_DECODER_STREAM_SENDER_H_
-#define QUICHE_QUIC_CORE_QPACK_QPACK_DECODER_STREAM_SENDER_H_
-
-#include <cstdint>
-
-#include "quic/core/qpack/qpack_instruction_encoder.h"
-#include "quic/core/qpack/qpack_stream_sender_delegate.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// This class serializes instructions for transmission on the decoder stream.
-// Serialized instructions are buffered until Flush() is called.
-class QUIC_EXPORT_PRIVATE QpackDecoderStreamSender {
- public:
- QpackDecoderStreamSender();
- QpackDecoderStreamSender(const QpackDecoderStreamSender&) = delete;
- QpackDecoderStreamSender& operator=(const QpackDecoderStreamSender&) = delete;
-
- // Methods for serializing and buffering instructions, see
- // https://quicwg.org/base-drafts/draft-ietf-quic-qpack.html#rfc.section.5.3
-
- // 5.3.1 Insert Count Increment
- void SendInsertCountIncrement(uint64_t increment);
- // 5.3.2 Header Acknowledgement
- void SendHeaderAcknowledgement(QuicStreamId stream_id);
- // 5.3.3 Stream Cancellation
- void SendStreamCancellation(QuicStreamId stream_id);
-
- // Writes all buffered instructions on the decoder stream.
- void Flush();
-
- // delegate must be set if dynamic table capacity is not zero.
- void set_qpack_stream_sender_delegate(QpackStreamSenderDelegate* delegate) {
- delegate_ = delegate;
- }
-
- private:
- QpackStreamSenderDelegate* delegate_;
- QpackInstructionEncoder instruction_encoder_;
- std::string buffer_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_QPACK_QPACK_DECODER_STREAM_SENDER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_decoder_stream_sender_test.cc b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_decoder_stream_sender_test.cc
deleted file mode 100644
index 708e7a3d3f1..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_decoder_stream_sender_test.cc
+++ /dev/null
@@ -1,101 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/qpack/qpack_decoder_stream_sender.h"
-
-#include "absl/strings/escaping.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/qpack/qpack_test_utils.h"
-
-using ::testing::Eq;
-using ::testing::StrictMock;
-
-namespace quic {
-namespace test {
-namespace {
-
-class QpackDecoderStreamSenderTest : public QuicTest {
- protected:
- QpackDecoderStreamSenderTest() {
- stream_.set_qpack_stream_sender_delegate(&delegate_);
- }
- ~QpackDecoderStreamSenderTest() override = default;
-
- StrictMock<MockQpackStreamSenderDelegate> delegate_;
- QpackDecoderStreamSender stream_;
-};
-
-TEST_F(QpackDecoderStreamSenderTest, InsertCountIncrement) {
- EXPECT_CALL(delegate_, WriteStreamData(Eq(absl::HexStringToBytes("00"))));
- stream_.SendInsertCountIncrement(0);
- stream_.Flush();
-
- EXPECT_CALL(delegate_, WriteStreamData(Eq(absl::HexStringToBytes("0a"))));
- stream_.SendInsertCountIncrement(10);
- stream_.Flush();
-
- EXPECT_CALL(delegate_, WriteStreamData(Eq(absl::HexStringToBytes("3f00"))));
- stream_.SendInsertCountIncrement(63);
- stream_.Flush();
-
- EXPECT_CALL(delegate_, WriteStreamData(Eq(absl::HexStringToBytes("3f8901"))));
- stream_.SendInsertCountIncrement(200);
- stream_.Flush();
-}
-
-TEST_F(QpackDecoderStreamSenderTest, HeaderAcknowledgement) {
- EXPECT_CALL(delegate_, WriteStreamData(Eq(absl::HexStringToBytes("80"))));
- stream_.SendHeaderAcknowledgement(0);
- stream_.Flush();
-
- EXPECT_CALL(delegate_, WriteStreamData(Eq(absl::HexStringToBytes("a5"))));
- stream_.SendHeaderAcknowledgement(37);
- stream_.Flush();
-
- EXPECT_CALL(delegate_, WriteStreamData(Eq(absl::HexStringToBytes("ff00"))));
- stream_.SendHeaderAcknowledgement(127);
- stream_.Flush();
-
- EXPECT_CALL(delegate_, WriteStreamData(Eq(absl::HexStringToBytes("fff802"))));
- stream_.SendHeaderAcknowledgement(503);
- stream_.Flush();
-}
-
-TEST_F(QpackDecoderStreamSenderTest, StreamCancellation) {
- EXPECT_CALL(delegate_, WriteStreamData(Eq(absl::HexStringToBytes("40"))));
- stream_.SendStreamCancellation(0);
- stream_.Flush();
-
- EXPECT_CALL(delegate_, WriteStreamData(Eq(absl::HexStringToBytes("53"))));
- stream_.SendStreamCancellation(19);
- stream_.Flush();
-
- EXPECT_CALL(delegate_, WriteStreamData(Eq(absl::HexStringToBytes("7f00"))));
- stream_.SendStreamCancellation(63);
- stream_.Flush();
-
- EXPECT_CALL(delegate_, WriteStreamData(Eq(absl::HexStringToBytes("7f2f"))));
- stream_.SendStreamCancellation(110);
- stream_.Flush();
-}
-
-TEST_F(QpackDecoderStreamSenderTest, Coalesce) {
- stream_.SendInsertCountIncrement(10);
- stream_.SendHeaderAcknowledgement(37);
- stream_.SendStreamCancellation(0);
-
- EXPECT_CALL(delegate_, WriteStreamData(Eq(absl::HexStringToBytes("0aa540"))));
- stream_.Flush();
-
- stream_.SendInsertCountIncrement(63);
- stream_.SendStreamCancellation(110);
-
- EXPECT_CALL(delegate_,
- WriteStreamData(Eq(absl::HexStringToBytes("3f007f2f"))));
- stream_.Flush();
-}
-
-} // namespace
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_decoder_test.cc b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_decoder_test.cc
deleted file mode 100644
index fe45397adf9..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_decoder_test.cc
+++ /dev/null
@@ -1,984 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/qpack/qpack_decoder.h"
-
-#include <algorithm>
-
-#include "absl/strings/escaping.h"
-#include "absl/strings/string_view.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/qpack/qpack_decoder_test_utils.h"
-#include "quic/test_tools/qpack/qpack_test_utils.h"
-#include "spdy/core/spdy_header_block.h"
-
-using ::testing::_;
-using ::testing::Eq;
-using ::testing::Invoke;
-using ::testing::Mock;
-using ::testing::Sequence;
-using ::testing::StrictMock;
-using ::testing::Values;
-
-namespace quic {
-namespace test {
-namespace {
-
-// Header Acknowledgement decoder stream instruction with stream_id = 1.
-const char* const kHeaderAcknowledgement = "\x81";
-
-const uint64_t kMaximumDynamicTableCapacity = 1024;
-const uint64_t kMaximumBlockedStreams = 1;
-
-class QpackDecoderTest : public QuicTestWithParam<FragmentMode> {
- protected:
- QpackDecoderTest()
- : qpack_decoder_(kMaximumDynamicTableCapacity,
- kMaximumBlockedStreams,
- &encoder_stream_error_delegate_),
- fragment_mode_(GetParam()) {
- qpack_decoder_.set_qpack_stream_sender_delegate(
- &decoder_stream_sender_delegate_);
- }
-
- ~QpackDecoderTest() override = default;
-
- void SetUp() override {
- // Destroy QpackProgressiveDecoder on error to test that it does not crash.
- // See https://crbug.com/1025209.
- ON_CALL(handler_, OnDecodingErrorDetected(_, _))
- .WillByDefault(Invoke([this](QuicErrorCode /* error_code */,
- absl::string_view /* error_message */) {
- progressive_decoder_.reset();
- }));
- }
-
- void DecodeEncoderStreamData(absl::string_view data) {
- qpack_decoder_.encoder_stream_receiver()->Decode(data);
- }
-
- std::unique_ptr<QpackProgressiveDecoder> CreateProgressiveDecoder(
- QuicStreamId stream_id) {
- return qpack_decoder_.CreateProgressiveDecoder(stream_id, &handler_);
- }
-
- // Set up |progressive_decoder_|.
- void StartDecoding() {
- progressive_decoder_ = CreateProgressiveDecoder(/* stream_id = */ 1);
- }
-
- // Pass header block data to QpackProgressiveDecoder::Decode()
- // in fragments dictated by |fragment_mode_|.
- void DecodeData(absl::string_view data) {
- auto fragment_size_generator =
- FragmentModeToFragmentSizeGenerator(fragment_mode_);
- while (progressive_decoder_ && !data.empty()) {
- size_t fragment_size = std::min(fragment_size_generator(), data.size());
- progressive_decoder_->Decode(data.substr(0, fragment_size));
- data = data.substr(fragment_size);
- }
- }
-
- // Signal end of header block to QpackProgressiveDecoder.
- void EndDecoding() {
- if (progressive_decoder_) {
- progressive_decoder_->EndHeaderBlock();
- }
- // If no error was detected, |*progressive_decoder_| is kept alive so that
- // it can handle callbacks later in case of blocked decoding.
- }
-
- // Decode an entire header block.
- void DecodeHeaderBlock(absl::string_view data) {
- StartDecoding();
- DecodeData(data);
- EndDecoding();
- }
-
- StrictMock<MockEncoderStreamErrorDelegate> encoder_stream_error_delegate_;
- StrictMock<MockQpackStreamSenderDelegate> decoder_stream_sender_delegate_;
- StrictMock<MockHeadersHandler> handler_;
-
- private:
- QpackDecoder qpack_decoder_;
- const FragmentMode fragment_mode_;
- std::unique_ptr<QpackProgressiveDecoder> progressive_decoder_;
-};
-
-INSTANTIATE_TEST_SUITE_P(All,
- QpackDecoderTest,
- Values(FragmentMode::kSingleChunk,
- FragmentMode::kOctetByOctet));
-
-TEST_P(QpackDecoderTest, NoPrefix) {
- EXPECT_CALL(handler_,
- OnDecodingErrorDetected(QUIC_QPACK_DECOMPRESSION_FAILED,
- Eq("Incomplete header data prefix.")));
-
- // Header Data Prefix is at least two bytes long.
- DecodeHeaderBlock(absl::HexStringToBytes("00"));
-}
-
-// Regression test for https://1025209: QpackProgressiveDecoder must not crash
-// in Decode() if it is destroyed by handler_.OnDecodingErrorDetected().
-TEST_P(QpackDecoderTest, InvalidPrefix) {
- StartDecoding();
-
- EXPECT_CALL(handler_,
- OnDecodingErrorDetected(QUIC_QPACK_DECOMPRESSION_FAILED,
- Eq("Encoded integer too large.")));
-
- // Encoded Required Insert Count in Header Data Prefix is too large.
- DecodeData(absl::HexStringToBytes("ffffffffffffffffffffffffffff"));
-}
-
-TEST_P(QpackDecoderTest, EmptyHeaderBlock) {
- EXPECT_CALL(handler_, OnDecodingCompleted());
-
- DecodeHeaderBlock(absl::HexStringToBytes("0000"));
-}
-
-TEST_P(QpackDecoderTest, LiteralEntryEmptyName) {
- EXPECT_CALL(handler_, OnHeaderDecoded(Eq(""), Eq("foo")));
- EXPECT_CALL(handler_, OnDecodingCompleted());
-
- DecodeHeaderBlock(absl::HexStringToBytes("00002003666f6f"));
-}
-
-TEST_P(QpackDecoderTest, LiteralEntryEmptyValue) {
- EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("")));
- EXPECT_CALL(handler_, OnDecodingCompleted());
-
- DecodeHeaderBlock(absl::HexStringToBytes("000023666f6f00"));
-}
-
-TEST_P(QpackDecoderTest, LiteralEntryEmptyNameAndValue) {
- EXPECT_CALL(handler_, OnHeaderDecoded(Eq(""), Eq("")));
- EXPECT_CALL(handler_, OnDecodingCompleted());
-
- DecodeHeaderBlock(absl::HexStringToBytes("00002000"));
-}
-
-TEST_P(QpackDecoderTest, SimpleLiteralEntry) {
- EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("bar")));
- EXPECT_CALL(handler_, OnDecodingCompleted());
-
- DecodeHeaderBlock(absl::HexStringToBytes("000023666f6f03626172"));
-}
-
-TEST_P(QpackDecoderTest, MultipleLiteralEntries) {
- EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("bar")));
- std::string str(127, 'a');
- EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foobaar"), absl::string_view(str)));
- EXPECT_CALL(handler_, OnDecodingCompleted());
-
- DecodeHeaderBlock(absl::HexStringToBytes(
- "0000" // prefix
- "23666f6f03626172" // foo: bar
- "2700666f6f62616172" // 7 octet long header name, the smallest number
- // that does not fit on a 3-bit prefix.
- "7f0061616161616161" // 127 octet long header value, the smallest number
- "616161616161616161" // that does not fit on a 7-bit prefix.
- "6161616161616161616161616161616161616161616161616161616161616161616161"
- "6161616161616161616161616161616161616161616161616161616161616161616161"
- "6161616161616161616161616161616161616161616161616161616161616161616161"
- "616161616161"));
-}
-
-// Name Length value is too large for varint decoder to decode.
-TEST_P(QpackDecoderTest, NameLenTooLargeForVarintDecoder) {
- EXPECT_CALL(handler_,
- OnDecodingErrorDetected(QUIC_QPACK_DECOMPRESSION_FAILED,
- Eq("Encoded integer too large.")));
-
- DecodeHeaderBlock(absl::HexStringToBytes("000027ffffffffffffffffffff"));
-}
-
-// Name Length value can be decoded by varint decoder but exceeds 1 MB limit.
-TEST_P(QpackDecoderTest, NameLenExceedsLimit) {
- EXPECT_CALL(handler_,
- OnDecodingErrorDetected(QUIC_QPACK_DECOMPRESSION_FAILED,
- Eq("String literal too long.")));
-
- DecodeHeaderBlock(absl::HexStringToBytes("000027ffff7f"));
-}
-
-// Value Length value is too large for varint decoder to decode.
-TEST_P(QpackDecoderTest, ValueLenTooLargeForVarintDecoder) {
- EXPECT_CALL(handler_,
- OnDecodingErrorDetected(QUIC_QPACK_DECOMPRESSION_FAILED,
- Eq("Encoded integer too large.")));
-
- DecodeHeaderBlock(
- absl::HexStringToBytes("000023666f6f7fffffffffffffffffffff"));
-}
-
-// Value Length value can be decoded by varint decoder but exceeds 1 MB limit.
-TEST_P(QpackDecoderTest, ValueLenExceedsLimit) {
- EXPECT_CALL(handler_,
- OnDecodingErrorDetected(QUIC_QPACK_DECOMPRESSION_FAILED,
- Eq("String literal too long.")));
-
- DecodeHeaderBlock(absl::HexStringToBytes("000023666f6f7fffff7f"));
-}
-
-TEST_P(QpackDecoderTest, LineFeedInValue) {
- EXPECT_CALL(handler_,
- OnDecodingErrorDetected(QUIC_INVALID_CHARACTER_IN_FIELD_VALUE,
- "Invalid character in field value."));
-
- DecodeHeaderBlock(absl::HexStringToBytes("000023666f6f0462610a72"));
-}
-
-TEST_P(QpackDecoderTest, IncompleteHeaderBlock) {
- EXPECT_CALL(handler_,
- OnDecodingErrorDetected(QUIC_QPACK_DECOMPRESSION_FAILED,
- Eq("Incomplete header block.")));
-
- DecodeHeaderBlock(absl::HexStringToBytes("00002366"));
-}
-
-TEST_P(QpackDecoderTest, HuffmanSimple) {
- EXPECT_CALL(handler_, OnHeaderDecoded(Eq("custom-key"), Eq("custom-value")));
- EXPECT_CALL(handler_, OnDecodingCompleted());
-
- DecodeHeaderBlock(
- absl::HexStringToBytes("00002f0125a849e95ba97d7f8925a849e95bb8e8b4bf"));
-}
-
-TEST_P(QpackDecoderTest, AlternatingHuffmanNonHuffman) {
- EXPECT_CALL(handler_, OnHeaderDecoded(Eq("custom-key"), Eq("custom-value")))
- .Times(4);
- EXPECT_CALL(handler_, OnDecodingCompleted());
-
- DecodeHeaderBlock(absl::HexStringToBytes(
- "0000" // Prefix.
- "2f0125a849e95ba97d7f" // Huffman-encoded name.
- "8925a849e95bb8e8b4bf" // Huffman-encoded value.
- "2703637573746f6d2d6b6579" // Non-Huffman encoded name.
- "0c637573746f6d2d76616c7565" // Non-Huffman encoded value.
- "2f0125a849e95ba97d7f" // Huffman-encoded name.
- "0c637573746f6d2d76616c7565" // Non-Huffman encoded value.
- "2703637573746f6d2d6b6579" // Non-Huffman encoded name.
- "8925a849e95bb8e8b4bf")); // Huffman-encoded value.
-}
-
-TEST_P(QpackDecoderTest, HuffmanNameDoesNotHaveEOSPrefix) {
- EXPECT_CALL(handler_,
- OnDecodingErrorDetected(QUIC_QPACK_DECOMPRESSION_FAILED,
- Eq("Error in Huffman-encoded string.")));
-
- // 'y' ends in 0b0 on the most significant bit of the last byte.
- // The remaining 7 bits must be a prefix of EOS, which is all 1s.
- DecodeHeaderBlock(
- absl::HexStringToBytes("00002f0125a849e95ba97d7e8925a849e95bb8e8b4bf"));
-}
-
-TEST_P(QpackDecoderTest, HuffmanValueDoesNotHaveEOSPrefix) {
- EXPECT_CALL(handler_,
- OnDecodingErrorDetected(QUIC_QPACK_DECOMPRESSION_FAILED,
- Eq("Error in Huffman-encoded string.")));
-
- // 'e' ends in 0b101, taking up the 3 most significant bits of the last byte.
- // The remaining 5 bits must be a prefix of EOS, which is all 1s.
- DecodeHeaderBlock(
- absl::HexStringToBytes("00002f0125a849e95ba97d7f8925a849e95bb8e8b4be"));
-}
-
-TEST_P(QpackDecoderTest, HuffmanNameEOSPrefixTooLong) {
- EXPECT_CALL(handler_,
- OnDecodingErrorDetected(QUIC_QPACK_DECOMPRESSION_FAILED,
- Eq("Error in Huffman-encoded string.")));
-
- // The trailing EOS prefix must be at most 7 bits long. Appending one octet
- // with value 0xff is invalid, even though 0b111111111111111 (15 bits) is a
- // prefix of EOS.
- DecodeHeaderBlock(
- absl::HexStringToBytes("00002f0225a849e95ba97d7fff8925a849e95bb8e8b4bf"));
-}
-
-TEST_P(QpackDecoderTest, HuffmanValueEOSPrefixTooLong) {
- EXPECT_CALL(handler_,
- OnDecodingErrorDetected(QUIC_QPACK_DECOMPRESSION_FAILED,
- Eq("Error in Huffman-encoded string.")));
-
- // The trailing EOS prefix must be at most 7 bits long. Appending one octet
- // with value 0xff is invalid, even though 0b1111111111111 (13 bits) is a
- // prefix of EOS.
- DecodeHeaderBlock(
- absl::HexStringToBytes("00002f0125a849e95ba97d7f8a25a849e95bb8e8b4bfff"));
-}
-
-TEST_P(QpackDecoderTest, StaticTable) {
- // A header name that has multiple entries with different values.
- EXPECT_CALL(handler_, OnHeaderDecoded(Eq(":method"), Eq("GET")));
- EXPECT_CALL(handler_, OnHeaderDecoded(Eq(":method"), Eq("POST")));
- EXPECT_CALL(handler_, OnHeaderDecoded(Eq(":method"), Eq("TRACE")));
-
- // A header name that has a single entry with non-empty value.
- EXPECT_CALL(handler_,
- OnHeaderDecoded(Eq("accept-encoding"), Eq("gzip, deflate, br")));
- EXPECT_CALL(handler_, OnHeaderDecoded(Eq("accept-encoding"), Eq("compress")));
- EXPECT_CALL(handler_, OnHeaderDecoded(Eq("accept-encoding"), Eq("")));
-
- // A header name that has a single entry with empty value.
- EXPECT_CALL(handler_, OnHeaderDecoded(Eq("location"), Eq("")));
- EXPECT_CALL(handler_, OnHeaderDecoded(Eq("location"), Eq("foo")));
-
- EXPECT_CALL(handler_, OnDecodingCompleted());
-
- DecodeHeaderBlock(absl::HexStringToBytes(
- "0000d1dfccd45f108621e9aec2a11f5c8294e75f000554524143455f1000"));
-}
-
-TEST_P(QpackDecoderTest, TooHighStaticTableIndex) {
- // This is the last entry in the static table with index 98.
- EXPECT_CALL(handler_,
- OnHeaderDecoded(Eq("x-frame-options"), Eq("sameorigin")));
-
- // Addressing entry 99 should trigger an error.
- EXPECT_CALL(handler_,
- OnDecodingErrorDetected(QUIC_QPACK_DECOMPRESSION_FAILED,
- Eq("Static table entry not found.")));
-
- DecodeHeaderBlock(absl::HexStringToBytes("0000ff23ff24"));
-}
-
-TEST_P(QpackDecoderTest, DynamicTable) {
- DecodeEncoderStreamData(absl::HexStringToBytes(
- "3fe107" // Set dynamic table capacity to 1024.
- "6294e703626172" // Add literal entry with name "foo" and value "bar".
- "80035a5a5a" // Add entry with name of dynamic table entry index 0
- // (relative index) and value "ZZZ".
- "cf8294e7" // Add entry with name of static table entry index 15
- // and value "foo".
- "01")); // Duplicate entry with relative index 1.
-
- // Now there are four entries in the dynamic table.
- // Entry 0: "foo", "bar"
- // Entry 1: "foo", "ZZZ"
- // Entry 2: ":method", "foo"
- // Entry 3: "foo", "ZZZ"
-
- // Use a Sequence to test that mock methods are called in order.
- Sequence s;
-
- EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("bar"))).InSequence(s);
- EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("ZZZ"))).InSequence(s);
- EXPECT_CALL(handler_, OnHeaderDecoded(Eq(":method"), Eq("foo")))
- .InSequence(s);
- EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("ZZZ"))).InSequence(s);
- EXPECT_CALL(handler_, OnHeaderDecoded(Eq(":method"), Eq("ZZ"))).InSequence(s);
- EXPECT_CALL(decoder_stream_sender_delegate_,
- WriteStreamData(Eq(kHeaderAcknowledgement)))
- .InSequence(s);
- EXPECT_CALL(handler_, OnDecodingCompleted()).InSequence(s);
-
- DecodeHeaderBlock(absl::HexStringToBytes(
- "0500" // Required Insert Count 4 and Delta Base 0.
- // Base is 4 + 0 = 4.
- "83" // Dynamic table entry with relative index 3, absolute index 0.
- "82" // Dynamic table entry with relative index 2, absolute index 1.
- "81" // Dynamic table entry with relative index 1, absolute index 2.
- "80" // Dynamic table entry with relative index 0, absolute index 3.
- "41025a5a")); // Name of entry 1 (relative index) from dynamic table,
- // with value "ZZ".
-
- EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("bar"))).InSequence(s);
- EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("ZZZ"))).InSequence(s);
- EXPECT_CALL(handler_, OnHeaderDecoded(Eq(":method"), Eq("foo")))
- .InSequence(s);
- EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("ZZZ"))).InSequence(s);
- EXPECT_CALL(handler_, OnHeaderDecoded(Eq(":method"), Eq("ZZ"))).InSequence(s);
- EXPECT_CALL(decoder_stream_sender_delegate_,
- WriteStreamData(Eq(kHeaderAcknowledgement)))
- .InSequence(s);
- EXPECT_CALL(handler_, OnDecodingCompleted()).InSequence(s);
-
- DecodeHeaderBlock(absl::HexStringToBytes(
- "0502" // Required Insert Count 4 and Delta Base 2.
- // Base is 4 + 2 = 6.
- "85" // Dynamic table entry with relative index 5, absolute index 0.
- "84" // Dynamic table entry with relative index 4, absolute index 1.
- "83" // Dynamic table entry with relative index 3, absolute index 2.
- "82" // Dynamic table entry with relative index 2, absolute index 3.
- "43025a5a")); // Name of entry 3 (relative index) from dynamic table,
- // with value "ZZ".
-
- EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("bar"))).InSequence(s);
- EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("ZZZ"))).InSequence(s);
- EXPECT_CALL(handler_, OnHeaderDecoded(Eq(":method"), Eq("foo")))
- .InSequence(s);
- EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("ZZZ"))).InSequence(s);
- EXPECT_CALL(handler_, OnHeaderDecoded(Eq(":method"), Eq("ZZ"))).InSequence(s);
- EXPECT_CALL(decoder_stream_sender_delegate_,
- WriteStreamData(Eq(kHeaderAcknowledgement)))
- .InSequence(s);
- EXPECT_CALL(handler_, OnDecodingCompleted()).InSequence(s);
-
- DecodeHeaderBlock(absl::HexStringToBytes(
- "0582" // Required Insert Count 4 and Delta Base 2 with sign bit set.
- // Base is 4 - 2 - 1 = 1.
- "80" // Dynamic table entry with relative index 0, absolute index 0.
- "10" // Dynamic table entry with post-base index 0, absolute index 1.
- "11" // Dynamic table entry with post-base index 1, absolute index 2.
- "12" // Dynamic table entry with post-base index 2, absolute index 3.
- "01025a5a")); // Name of entry 1 (post-base index) from dynamic table,
- // with value "ZZ".
-}
-
-TEST_P(QpackDecoderTest, DecreasingDynamicTableCapacityEvictsEntries) {
- // Set dynamic table capacity to 1024.
- DecodeEncoderStreamData(absl::HexStringToBytes("3fe107"));
- // Add literal entry with name "foo" and value "bar".
- DecodeEncoderStreamData(absl::HexStringToBytes("6294e703626172"));
-
- EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("bar")));
- EXPECT_CALL(handler_, OnDecodingCompleted());
- EXPECT_CALL(decoder_stream_sender_delegate_,
- WriteStreamData(Eq(kHeaderAcknowledgement)));
-
- DecodeHeaderBlock(absl::HexStringToBytes(
- "0200" // Required Insert Count 1 and Delta Base 0.
- // Base is 1 + 0 = 1.
- "80")); // Dynamic table entry with relative index 0, absolute index 0.
-
- // Change dynamic table capacity to 32 bytes, smaller than the entry.
- // This must cause the entry to be evicted.
- DecodeEncoderStreamData(absl::HexStringToBytes("3f01"));
-
- EXPECT_CALL(handler_, OnDecodingErrorDetected(
- QUIC_QPACK_DECOMPRESSION_FAILED,
- Eq("Dynamic table entry already evicted.")));
-
- DecodeHeaderBlock(absl::HexStringToBytes(
- "0200" // Required Insert Count 1 and Delta Base 0.
- // Base is 1 + 0 = 1.
- "80")); // Dynamic table entry with relative index 0, absolute index 0.
-}
-
-TEST_P(QpackDecoderTest, EncoderStreamErrorEntryTooLarge) {
- EXPECT_CALL(
- encoder_stream_error_delegate_,
- OnEncoderStreamError(QUIC_QPACK_ENCODER_STREAM_ERROR_INSERTING_LITERAL,
- Eq("Error inserting literal entry.")));
-
- // Set dynamic table capacity to 34.
- DecodeEncoderStreamData(absl::HexStringToBytes("3f03"));
- // Add literal entry with name "foo" and value "bar", size is 32 + 3 + 3 = 38.
- DecodeEncoderStreamData(absl::HexStringToBytes("6294e703626172"));
-}
-
-TEST_P(QpackDecoderTest, EncoderStreamErrorInvalidStaticTableEntry) {
- EXPECT_CALL(
- encoder_stream_error_delegate_,
- OnEncoderStreamError(QUIC_QPACK_ENCODER_STREAM_INVALID_STATIC_ENTRY,
- Eq("Invalid static table entry.")));
-
- // Address invalid static table entry index 99.
- DecodeEncoderStreamData(absl::HexStringToBytes("ff2400"));
-}
-
-TEST_P(QpackDecoderTest, EncoderStreamErrorInvalidDynamicTableEntry) {
- EXPECT_CALL(encoder_stream_error_delegate_,
- OnEncoderStreamError(
- QUIC_QPACK_ENCODER_STREAM_INSERTION_INVALID_RELATIVE_INDEX,
- Eq("Invalid relative index.")));
-
- DecodeEncoderStreamData(absl::HexStringToBytes(
- "3fe107" // Set dynamic table capacity to 1024.
- "6294e703626172" // Add literal entry with name "foo" and value "bar".
- "8100")); // Address dynamic table entry with relative index 1. Such
- // entry does not exist. The most recently added and only
- // dynamic table entry has relative index 0.
-}
-
-TEST_P(QpackDecoderTest, EncoderStreamErrorDuplicateInvalidEntry) {
- EXPECT_CALL(encoder_stream_error_delegate_,
- OnEncoderStreamError(
- QUIC_QPACK_ENCODER_STREAM_DUPLICATE_INVALID_RELATIVE_INDEX,
- Eq("Invalid relative index.")));
-
- DecodeEncoderStreamData(absl::HexStringToBytes(
- "3fe107" // Set dynamic table capacity to 1024.
- "6294e703626172" // Add literal entry with name "foo" and value "bar".
- "01")); // Duplicate dynamic table entry with relative index 1. Such
- // entry does not exist. The most recently added and only
- // dynamic table entry has relative index 0.
-}
-
-TEST_P(QpackDecoderTest, EncoderStreamErrorTooLargeInteger) {
- EXPECT_CALL(encoder_stream_error_delegate_,
- OnEncoderStreamError(QUIC_QPACK_ENCODER_STREAM_INTEGER_TOO_LARGE,
- Eq("Encoded integer too large.")));
-
- DecodeEncoderStreamData(absl::HexStringToBytes("3fffffffffffffffffffff"));
-}
-
-TEST_P(QpackDecoderTest, InvalidDynamicEntryWhenBaseIsZero) {
- EXPECT_CALL(handler_, OnDecodingErrorDetected(QUIC_QPACK_DECOMPRESSION_FAILED,
- Eq("Invalid relative index.")));
-
- // Set dynamic table capacity to 1024.
- DecodeEncoderStreamData(absl::HexStringToBytes("3fe107"));
- // Add literal entry with name "foo" and value "bar".
- DecodeEncoderStreamData(absl::HexStringToBytes("6294e703626172"));
-
- DecodeHeaderBlock(absl::HexStringToBytes(
- "0280" // Required Insert Count is 1. Base 1 - 1 - 0 = 0 is explicitly
- // permitted by the spec.
- "80")); // However, addressing entry with relative index 0 would point to
- // absolute index -1, which is invalid.
-}
-
-TEST_P(QpackDecoderTest, InvalidNegativeBase) {
- EXPECT_CALL(handler_, OnDecodingErrorDetected(QUIC_QPACK_DECOMPRESSION_FAILED,
- Eq("Error calculating Base.")));
-
- // Required Insert Count 1, Delta Base 1 with sign bit set, Base would
- // be 1 - 1 - 1 = -1, but it is not allowed to be negative.
- DecodeHeaderBlock(absl::HexStringToBytes("0281"));
-}
-
-TEST_P(QpackDecoderTest, InvalidDynamicEntryByRelativeIndex) {
- // Set dynamic table capacity to 1024.
- DecodeEncoderStreamData(absl::HexStringToBytes("3fe107"));
- // Add literal entry with name "foo" and value "bar".
- DecodeEncoderStreamData(absl::HexStringToBytes("6294e703626172"));
-
- EXPECT_CALL(handler_, OnDecodingErrorDetected(QUIC_QPACK_DECOMPRESSION_FAILED,
- Eq("Invalid relative index.")));
-
- DecodeHeaderBlock(absl::HexStringToBytes(
- "0200" // Required Insert Count 1 and Delta Base 0.
- // Base is 1 + 0 = 1.
- "81")); // Indexed Header Field instruction addressing relative index 1.
- // This is absolute index -1, which is invalid.
-
- EXPECT_CALL(handler_, OnDecodingErrorDetected(QUIC_QPACK_DECOMPRESSION_FAILED,
- Eq("Invalid relative index.")));
-
- DecodeHeaderBlock(absl::HexStringToBytes(
- "0200" // Required Insert Count 1 and Delta Base 0.
- // Base is 1 + 0 = 1.
- "4100")); // Literal Header Field with Name Reference instruction
- // addressing relative index 1. This is absolute index -1,
- // which is invalid.
-}
-
-TEST_P(QpackDecoderTest, EvictedDynamicTableEntry) {
- // Update dynamic table capacity to 128.
- DecodeEncoderStreamData(absl::HexStringToBytes("3f61"));
-
- // Add literal entry with name "foo" and value "bar", size 32 + 3 + 3 = 38.
- // This fits in the table three times.
- DecodeEncoderStreamData(absl::HexStringToBytes("6294e703626172"));
- // Duplicate entry four times. This evicts the first two instances.
- DecodeEncoderStreamData(absl::HexStringToBytes("00000000"));
-
- EXPECT_CALL(handler_, OnDecodingErrorDetected(
- QUIC_QPACK_DECOMPRESSION_FAILED,
- Eq("Dynamic table entry already evicted.")));
-
- DecodeHeaderBlock(absl::HexStringToBytes(
- "0500" // Required Insert Count 4 and Delta Base 0.
- // Base is 4 + 0 = 4.
- "82")); // Indexed Header Field instruction addressing relative index 2.
- // This is absolute index 1. Such entry does not exist.
-
- EXPECT_CALL(handler_, OnDecodingErrorDetected(
- QUIC_QPACK_DECOMPRESSION_FAILED,
- Eq("Dynamic table entry already evicted.")));
-
- DecodeHeaderBlock(absl::HexStringToBytes(
- "0500" // Required Insert Count 4 and Delta Base 0.
- // Base is 4 + 0 = 4.
- "4200")); // Literal Header Field with Name Reference instruction
- // addressing relative index 2. This is absolute index 1. Such
- // entry does not exist.
-
- EXPECT_CALL(handler_, OnDecodingErrorDetected(
- QUIC_QPACK_DECOMPRESSION_FAILED,
- Eq("Dynamic table entry already evicted.")));
-
- DecodeHeaderBlock(absl::HexStringToBytes(
- "0380" // Required Insert Count 2 and Delta Base 0 with sign bit set.
- // Base is 2 - 0 - 1 = 1
- "10")); // Indexed Header Field instruction addressing dynamic table
- // entry with post-base index 0, absolute index 1. Such entry
- // does not exist.
-
- EXPECT_CALL(handler_, OnDecodingErrorDetected(
- QUIC_QPACK_DECOMPRESSION_FAILED,
- Eq("Dynamic table entry already evicted.")));
-
- DecodeHeaderBlock(absl::HexStringToBytes(
- "0380" // Required Insert Count 2 and Delta Base 0 with sign bit set.
- // Base is 2 - 0 - 1 = 1
- "0000")); // Literal Header Field With Name Reference instruction
- // addressing dynamic table entry with post-base index 0,
- // absolute index 1. Such entry does not exist.
-}
-
-TEST_P(QpackDecoderTest, TableCapacityMustNotExceedMaximum) {
- EXPECT_CALL(
- encoder_stream_error_delegate_,
- OnEncoderStreamError(QUIC_QPACK_ENCODER_STREAM_SET_DYNAMIC_TABLE_CAPACITY,
- Eq("Error updating dynamic table capacity.")));
-
- // Try to update dynamic table capacity to 2048, which exceeds the maximum.
- DecodeEncoderStreamData(absl::HexStringToBytes("3fe10f"));
-}
-
-TEST_P(QpackDecoderTest, SetDynamicTableCapacity) {
- // Update dynamic table capacity to 128, which does not exceed the maximum.
- DecodeEncoderStreamData(absl::HexStringToBytes("3f61"));
-}
-
-TEST_P(QpackDecoderTest, InvalidEncodedRequiredInsertCount) {
- // Maximum dynamic table capacity is 1024.
- // MaxEntries is 1024 / 32 = 32.
- // Required Insert Count is decoded modulo 2 * MaxEntries, that is, modulo 64.
- // A value of 1 cannot be encoded as 65 even though it has the same remainder.
- EXPECT_CALL(handler_, OnDecodingErrorDetected(
- QUIC_QPACK_DECOMPRESSION_FAILED,
- Eq("Error decoding Required Insert Count.")));
- DecodeHeaderBlock(absl::HexStringToBytes("4100"));
-}
-
-// Regression test for https://crbug.com/970218: Decoder must stop processing
-// after a Header Block Prefix with an invalid Encoded Required Insert Count.
-TEST_P(QpackDecoderTest, DataAfterInvalidEncodedRequiredInsertCount) {
- EXPECT_CALL(handler_, OnDecodingErrorDetected(
- QUIC_QPACK_DECOMPRESSION_FAILED,
- Eq("Error decoding Required Insert Count.")));
- // Header Block Prefix followed by some extra data.
- DecodeHeaderBlock(absl::HexStringToBytes("410000"));
-}
-
-TEST_P(QpackDecoderTest, WrappedRequiredInsertCount) {
- // Maximum dynamic table capacity is 1024.
- // MaxEntries is 1024 / 32 = 32.
-
- // Set dynamic table capacity to 1024.
- DecodeEncoderStreamData(absl::HexStringToBytes("3fe107"));
- // Add literal entry with name "foo" and a 600 byte long value. This will fit
- // in the dynamic table once but not twice.
- DecodeEncoderStreamData(
- absl::HexStringToBytes("6294e7" // Name "foo".
- "7fd903")); // Value length 600.
- std::string header_value(600, 'Z');
- DecodeEncoderStreamData(header_value);
-
- // Duplicate most recent entry 200 times.
- DecodeEncoderStreamData(std::string(200, '\x00'));
-
- // Now there is only one entry in the dynamic table, with absolute index 200.
-
- EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq(header_value)));
- EXPECT_CALL(handler_, OnDecodingCompleted());
- EXPECT_CALL(decoder_stream_sender_delegate_,
- WriteStreamData(Eq(kHeaderAcknowledgement)));
-
- // Send header block with Required Insert Count = 201.
- DecodeHeaderBlock(absl::HexStringToBytes(
- "0a00" // Encoded Required Insert Count 10, Required Insert Count 201,
- // Delta Base 0, Base 201.
- "80")); // Emit dynamic table entry with relative index 0.
-}
-
-TEST_P(QpackDecoderTest, NonZeroRequiredInsertCountButNoDynamicEntries) {
- // Set dynamic table capacity to 1024.
- DecodeEncoderStreamData(absl::HexStringToBytes("3fe107"));
- // Add literal entry with name "foo" and value "bar".
- DecodeEncoderStreamData(absl::HexStringToBytes("6294e703626172"));
-
- EXPECT_CALL(handler_, OnHeaderDecoded(Eq(":method"), Eq("GET")));
- EXPECT_CALL(handler_,
- OnDecodingErrorDetected(QUIC_QPACK_DECOMPRESSION_FAILED,
- Eq("Required Insert Count too large.")));
-
- DecodeHeaderBlock(absl::HexStringToBytes(
- "0200" // Required Insert Count is 1.
- "d1")); // But the only instruction references the static table.
-}
-
-TEST_P(QpackDecoderTest, AddressEntryNotAllowedByRequiredInsertCount) {
- // Set dynamic table capacity to 1024.
- DecodeEncoderStreamData(absl::HexStringToBytes("3fe107"));
- // Add literal entry with name "foo" and value "bar".
- DecodeEncoderStreamData(absl::HexStringToBytes("6294e703626172"));
-
- EXPECT_CALL(
- handler_,
- OnDecodingErrorDetected(
- QUIC_QPACK_DECOMPRESSION_FAILED,
- Eq("Absolute Index must be smaller than Required Insert Count.")));
-
- DecodeHeaderBlock(absl::HexStringToBytes(
- "0201" // Required Insert Count 1 and Delta Base 1.
- // Base is 1 + 1 = 2.
- "80")); // Indexed Header Field instruction addressing dynamic table
- // entry with relative index 0, absolute index 1. This is not
- // allowed by Required Insert Count.
-
- EXPECT_CALL(
- handler_,
- OnDecodingErrorDetected(
- QUIC_QPACK_DECOMPRESSION_FAILED,
- Eq("Absolute Index must be smaller than Required Insert Count.")));
-
- DecodeHeaderBlock(absl::HexStringToBytes(
- "0201" // Required Insert Count 1 and Delta Base 1.
- // Base is 1 + 1 = 2.
- "4000")); // Literal Header Field with Name Reference instruction
- // addressing dynamic table entry with relative index 0,
- // absolute index 1. This is not allowed by Required Index
- // Count.
-
- EXPECT_CALL(
- handler_,
- OnDecodingErrorDetected(
- QUIC_QPACK_DECOMPRESSION_FAILED,
- Eq("Absolute Index must be smaller than Required Insert Count.")));
-
- DecodeHeaderBlock(absl::HexStringToBytes(
- "0200" // Required Insert Count 1 and Delta Base 0.
- // Base is 1 + 0 = 1.
- "10")); // Indexed Header Field with Post-Base Index instruction
- // addressing dynamic table entry with post-base index 0,
- // absolute index 1. This is not allowed by Required Insert
- // Count.
-
- EXPECT_CALL(
- handler_,
- OnDecodingErrorDetected(
- QUIC_QPACK_DECOMPRESSION_FAILED,
- Eq("Absolute Index must be smaller than Required Insert Count.")));
-
- DecodeHeaderBlock(absl::HexStringToBytes(
- "0200" // Required Insert Count 1 and Delta Base 0.
- // Base is 1 + 0 = 1.
- "0000")); // Literal Header Field with Post-Base Name Reference
- // instruction addressing dynamic table entry with post-base
- // index 0, absolute index 1. This is not allowed by Required
- // Index Count.
-}
-
-TEST_P(QpackDecoderTest, PromisedRequiredInsertCountLargerThanActual) {
- // Set dynamic table capacity to 1024.
- DecodeEncoderStreamData(absl::HexStringToBytes("3fe107"));
- // Add literal entry with name "foo" and value "bar".
- DecodeEncoderStreamData(absl::HexStringToBytes("6294e703626172"));
- // Duplicate entry twice so that decoding of header blocks with Required
- // Insert Count not exceeding 3 is not blocked.
- DecodeEncoderStreamData(absl::HexStringToBytes("00"));
- DecodeEncoderStreamData(absl::HexStringToBytes("00"));
-
- EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("bar")));
- EXPECT_CALL(handler_,
- OnDecodingErrorDetected(QUIC_QPACK_DECOMPRESSION_FAILED,
- Eq("Required Insert Count too large.")));
-
- DecodeHeaderBlock(absl::HexStringToBytes(
- "0300" // Required Insert Count 2 and Delta Base 0.
- // Base is 2 + 0 = 2.
- "81")); // Indexed Header Field instruction addressing dynamic table
- // entry with relative index 1, absolute index 0. Header block
- // requires insert count of 1, even though Required Insert Count
- // is 2.
-
- EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("")));
- EXPECT_CALL(handler_,
- OnDecodingErrorDetected(QUIC_QPACK_DECOMPRESSION_FAILED,
- Eq("Required Insert Count too large.")));
-
- DecodeHeaderBlock(absl::HexStringToBytes(
- "0300" // Required Insert Count 2 and Delta Base 0.
- // Base is 2 + 0 = 2.
- "4100")); // Literal Header Field with Name Reference instruction
- // addressing dynamic table entry with relative index 1,
- // absolute index 0. Header block requires insert count of 1,
- // even though Required Insert Count is 2.
-
- EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("bar")));
- EXPECT_CALL(handler_,
- OnDecodingErrorDetected(QUIC_QPACK_DECOMPRESSION_FAILED,
- Eq("Required Insert Count too large.")));
-
- DecodeHeaderBlock(absl::HexStringToBytes(
- "0481" // Required Insert Count 3 and Delta Base 1 with sign bit set.
- // Base is 3 - 1 - 1 = 1.
- "10")); // Indexed Header Field with Post-Base Index instruction
- // addressing dynamic table entry with post-base index 0,
- // absolute index 1. Header block requires insert count of 2,
- // even though Required Insert Count is 3.
-
- EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("")));
- EXPECT_CALL(handler_,
- OnDecodingErrorDetected(QUIC_QPACK_DECOMPRESSION_FAILED,
- Eq("Required Insert Count too large.")));
-
- DecodeHeaderBlock(absl::HexStringToBytes(
- "0481" // Required Insert Count 3 and Delta Base 1 with sign bit set.
- // Base is 3 - 1 - 1 = 1.
- "0000")); // Literal Header Field with Post-Base Name Reference
- // instruction addressing dynamic table entry with post-base
- // index 0, absolute index 1. Header block requires insert
- // count of 2, even though Required Insert Count is 3.
-}
-
-TEST_P(QpackDecoderTest, BlockedDecoding) {
- DecodeHeaderBlock(absl::HexStringToBytes(
- "0200" // Required Insert Count 1 and Delta Base 0.
- // Base is 1 + 0 = 1.
- "80")); // Indexed Header Field instruction addressing dynamic table
- // entry with relative index 0, absolute index 0.
-
- EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("bar")));
- EXPECT_CALL(handler_, OnDecodingCompleted());
- EXPECT_CALL(decoder_stream_sender_delegate_,
- WriteStreamData(Eq(kHeaderAcknowledgement)));
-
- // Set dynamic table capacity to 1024.
- DecodeEncoderStreamData(absl::HexStringToBytes("3fe107"));
- // Add literal entry with name "foo" and value "bar".
- DecodeEncoderStreamData(absl::HexStringToBytes("6294e703626172"));
-}
-
-TEST_P(QpackDecoderTest, BlockedDecodingUnblockedBeforeEndOfHeaderBlock) {
- StartDecoding();
- DecodeData(absl::HexStringToBytes(
- "0200" // Required Insert Count 1 and Delta Base 0.
- // Base is 1 + 0 = 1.
- "80" // Indexed Header Field instruction addressing dynamic table
- // entry with relative index 0, absolute index 0.
- "d1")); // Static table entry with index 17.
-
- // Set dynamic table capacity to 1024.
- DecodeEncoderStreamData(absl::HexStringToBytes("3fe107"));
-
- // Add literal entry with name "foo" and value "bar". Decoding is now
- // unblocked because dynamic table Insert Count reached the Required Insert
- // Count of the header block. |handler_| methods are called immediately for
- // the already consumed part of the header block.
- EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("bar")));
- EXPECT_CALL(handler_, OnHeaderDecoded(Eq(":method"), Eq("GET")));
- DecodeEncoderStreamData(absl::HexStringToBytes("6294e703626172"));
- Mock::VerifyAndClearExpectations(&handler_);
-
- // Rest of header block is processed by QpackProgressiveDecoder
- // in the unblocked state.
- EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("bar")));
- EXPECT_CALL(handler_, OnHeaderDecoded(Eq(":scheme"), Eq("https")));
- DecodeData(absl::HexStringToBytes(
- "80" // Indexed Header Field instruction addressing dynamic table
- // entry with relative index 0, absolute index 0.
- "d7")); // Static table entry with index 23.
- Mock::VerifyAndClearExpectations(&handler_);
-
- EXPECT_CALL(handler_, OnDecodingCompleted());
- EXPECT_CALL(decoder_stream_sender_delegate_,
- WriteStreamData(Eq(kHeaderAcknowledgement)));
- EndDecoding();
-}
-
-// Regression test for https://crbug.com/1024263.
-TEST_P(QpackDecoderTest,
- BlockedDecodingUnblockedAndErrorBeforeEndOfHeaderBlock) {
- StartDecoding();
- DecodeData(absl::HexStringToBytes(
- "0200" // Required Insert Count 1 and Delta Base 0.
- // Base is 1 + 0 = 1.
- "80" // Indexed Header Field instruction addressing dynamic table
- // entry with relative index 0, absolute index 0.
- "81")); // Relative index 1 is equal to Base, therefore invalid.
-
- // Set dynamic table capacity to 1024.
- DecodeEncoderStreamData(absl::HexStringToBytes("3fe107"));
-
- // Add literal entry with name "foo" and value "bar". Decoding is now
- // unblocked because dynamic table Insert Count reached the Required Insert
- // Count of the header block. |handler_| methods are called immediately for
- // the already consumed part of the header block.
- EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("bar")));
- EXPECT_CALL(handler_, OnDecodingErrorDetected(QUIC_QPACK_DECOMPRESSION_FAILED,
- Eq("Invalid relative index.")));
- DecodeEncoderStreamData(absl::HexStringToBytes("6294e703626172"));
-}
-
-// Make sure that Required Insert Count is compared to Insert Count,
-// not size of dynamic table.
-TEST_P(QpackDecoderTest, BlockedDecodingAndEvictedEntries) {
- // Update dynamic table capacity to 128.
- // At most three non-empty entries fit in the dynamic table.
- DecodeEncoderStreamData(absl::HexStringToBytes("3f61"));
-
- DecodeHeaderBlock(absl::HexStringToBytes(
- "0700" // Required Insert Count 6 and Delta Base 0.
- // Base is 6 + 0 = 6.
- "80")); // Indexed Header Field instruction addressing dynamic table
- // entry with relative index 0, absolute index 5.
-
- // Add literal entry with name "foo" and value "bar".
- DecodeEncoderStreamData(absl::HexStringToBytes("6294e703626172"));
-
- // Duplicate entry four times. This evicts the first two instances.
- DecodeEncoderStreamData(absl::HexStringToBytes("00000000"));
-
- EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("baz")));
- EXPECT_CALL(handler_, OnDecodingCompleted());
- EXPECT_CALL(decoder_stream_sender_delegate_,
- WriteStreamData(Eq(kHeaderAcknowledgement)));
-
- // Add literal entry with name "foo" and value "bar".
- // Insert Count is now 6, reaching Required Insert Count of the header block.
- DecodeEncoderStreamData(absl::HexStringToBytes("6294e70362617a"));
-}
-
-TEST_P(QpackDecoderTest, TooManyBlockedStreams) {
- // Required Insert Count 1 and Delta Base 0.
- // Without any dynamic table entries received, decoding is blocked.
- std::string data = absl::HexStringToBytes("0200");
-
- auto progressive_decoder1 = CreateProgressiveDecoder(/* stream_id = */ 1);
- progressive_decoder1->Decode(data);
-
- EXPECT_CALL(handler_,
- OnDecodingErrorDetected(
- QUIC_QPACK_DECOMPRESSION_FAILED,
- Eq("Limit on number of blocked streams exceeded.")));
-
- auto progressive_decoder2 = CreateProgressiveDecoder(/* stream_id = */ 2);
- progressive_decoder2->Decode(data);
-}
-
-TEST_P(QpackDecoderTest, InsertCountIncrement) {
- DecodeEncoderStreamData(absl::HexStringToBytes(
- "3fe107" // Set dynamic table capacity to 1024.
- "6294e703626172" // Add literal entry with name "foo" and value "bar".
- "00")); // Duplicate entry.
-
- EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("bar")));
- EXPECT_CALL(handler_, OnDecodingCompleted());
-
- // Decoder received two insertions, but Header Acknowledgement only increases
- // Known Insert Count to one. Decoder should send an Insert Count Increment
- // instruction with increment of one to update Known Insert Count to two.
- EXPECT_CALL(decoder_stream_sender_delegate_,
- WriteStreamData(Eq(absl::HexStringToBytes(
- "81" // Header Acknowledgement on stream 1
- "01")))); // Insert Count Increment with increment of one
-
- DecodeHeaderBlock(absl::HexStringToBytes(
- "0200" // Required Insert Count 1 and Delta Base 0.
- // Base is 1 + 0 = 1.
- "80")); // Dynamic table entry with relative index 0, absolute index 0.
-}
-
-} // namespace
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_encoder.cc b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_encoder.cc
deleted file mode 100644
index 974f7b2274f..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_encoder.cc
+++ /dev/null
@@ -1,467 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/qpack/qpack_encoder.h"
-
-#include <algorithm>
-#include <utility>
-
-#include "absl/strings/str_cat.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/qpack/qpack_index_conversions.h"
-#include "quic/core/qpack/qpack_instruction_encoder.h"
-#include "quic/core/qpack/qpack_required_insert_count.h"
-#include "quic/core/qpack/value_splitting_header_list.h"
-#include "quic/platform/api/quic_flag_utils.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-namespace {
-
-// Fraction to calculate draining index. The oldest |kDrainingFraction| entries
-// will not be referenced in header blocks. A new entry (duplicate or literal
-// with name reference) will be added to the dynamic table instead. This allows
-// the number of references to the draining entry to go to zero faster, so that
-// it can be evicted. See
-// https://quicwg.org/base-drafts/draft-ietf-quic-qpack.html#avoiding-blocked-insertions.
-// TODO(bnc): Fine tune.
-const float kDrainingFraction = 0.25;
-
-} // anonymous namespace
-
-QpackEncoder::QpackEncoder(
- DecoderStreamErrorDelegate* decoder_stream_error_delegate)
- : decoder_stream_error_delegate_(decoder_stream_error_delegate),
- decoder_stream_receiver_(this),
- maximum_blocked_streams_(0),
- header_list_count_(0) {
- QUICHE_DCHECK(decoder_stream_error_delegate_);
-}
-
-QpackEncoder::~QpackEncoder() {}
-
-// static
-QpackEncoder::Representation QpackEncoder::EncodeIndexedHeaderField(
- bool is_static,
- uint64_t index,
- QpackBlockingManager::IndexSet* referred_indices) {
- // Add |index| to |*referred_indices| only if entry is in the dynamic table.
- if (!is_static) {
- referred_indices->insert(index);
- }
- return Representation::IndexedHeaderField(is_static, index);
-}
-
-// static
-QpackEncoder::Representation
-QpackEncoder::EncodeLiteralHeaderFieldWithNameReference(
- bool is_static,
- uint64_t index,
- absl::string_view value,
- QpackBlockingManager::IndexSet* referred_indices) {
- // Add |index| to |*referred_indices| only if entry is in the dynamic table.
- if (!is_static) {
- referred_indices->insert(index);
- }
- return Representation::LiteralHeaderFieldNameReference(is_static, index,
- value);
-}
-
-// static
-QpackEncoder::Representation QpackEncoder::EncodeLiteralHeaderField(
- absl::string_view name,
- absl::string_view value) {
- return Representation::LiteralHeaderField(name, value);
-}
-
-QpackEncoder::Representations QpackEncoder::FirstPassEncode(
- QuicStreamId stream_id,
- const spdy::Http2HeaderBlock& header_list,
- QpackBlockingManager::IndexSet* referred_indices,
- QuicByteCount* encoder_stream_sent_byte_count) {
- // If previous instructions are buffered in |encoder_stream_sender_|,
- // do not count them towards the current header block.
- const QuicByteCount initial_encoder_stream_buffered_byte_count =
- encoder_stream_sender_.BufferedByteCount();
-
- bool can_write_to_encoder_stream = true;
- if (GetQuicReloadableFlag(quic_limit_encoder_stream_buffering)) {
- QUIC_RELOADABLE_FLAG_COUNT(quic_limit_encoder_stream_buffering);
- can_write_to_encoder_stream = encoder_stream_sender_.CanWrite();
- }
-
- Representations representations;
- representations.reserve(header_list.size());
-
- // The index of the oldest entry that must not be evicted.
- uint64_t smallest_blocking_index =
- blocking_manager_.smallest_blocking_index();
- // Entries with index larger than or equal to |known_received_count| are
- // blocking.
- const uint64_t known_received_count =
- blocking_manager_.known_received_count();
- // Only entries with index greater than or equal to |draining_index| are
- // allowed to be referenced.
- const uint64_t draining_index =
- header_table_.draining_index(kDrainingFraction);
- // Blocking references are allowed if the number of blocked streams is less
- // than the limit.
- const bool blocking_allowed = blocking_manager_.blocking_allowed_on_stream(
- stream_id, maximum_blocked_streams_);
-
- // Track events for histograms.
- bool dynamic_table_insertion_blocked = false;
- bool blocked_stream_limit_exhausted = false;
-
- for (const auto& header : ValueSplittingHeaderList(&header_list)) {
- // These strings are owned by |header_list|.
- absl::string_view name = header.first;
- absl::string_view value = header.second;
-
- bool is_static;
- uint64_t index;
-
- auto match_type =
- header_table_.FindHeaderField(name, value, &is_static, &index);
-
- switch (match_type) {
- case QpackEncoderHeaderTable::MatchType::kNameAndValue:
- if (is_static) {
- // Refer to entry directly.
- representations.push_back(
- EncodeIndexedHeaderField(is_static, index, referred_indices));
-
- break;
- }
-
- if (index >= draining_index) {
- // If allowed, refer to entry directly.
- if (!blocking_allowed && index >= known_received_count) {
- blocked_stream_limit_exhausted = true;
- } else {
- representations.push_back(
- EncodeIndexedHeaderField(is_static, index, referred_indices));
- smallest_blocking_index = std::min(smallest_blocking_index, index);
- header_table_.set_dynamic_table_entry_referenced();
-
- break;
- }
- } else {
- // Entry is draining, needs to be duplicated.
- if (!blocking_allowed) {
- blocked_stream_limit_exhausted = true;
- } else if (QpackEntry::Size(name, value) >
- header_table_.MaxInsertSizeWithoutEvictingGivenEntry(
- std::min(smallest_blocking_index, index))) {
- dynamic_table_insertion_blocked = true;
- } else {
- if (can_write_to_encoder_stream) {
- // If allowed, duplicate entry and refer to it.
- encoder_stream_sender_.SendDuplicate(
- QpackAbsoluteIndexToEncoderStreamRelativeIndex(
- index, header_table_.inserted_entry_count()));
- uint64_t new_index = header_table_.InsertEntry(name, value);
- representations.push_back(EncodeIndexedHeaderField(
- is_static, new_index, referred_indices));
- smallest_blocking_index =
- std::min(smallest_blocking_index, index);
- header_table_.set_dynamic_table_entry_referenced();
-
- break;
- }
- }
- }
-
- // Encode entry as string literals.
- // TODO(b/112770235): Use already acknowledged entry with lower index if
- // exists.
- // TODO(b/112770235): Use static entry name with literal value if
- // dynamic entry exists but cannot be used.
- representations.push_back(EncodeLiteralHeaderField(name, value));
-
- break;
-
- case QpackEncoderHeaderTable::MatchType::kName:
- if (is_static) {
- if (blocking_allowed &&
- QpackEntry::Size(name, value) <=
- header_table_.MaxInsertSizeWithoutEvictingGivenEntry(
- smallest_blocking_index)) {
- // If allowed, insert entry into dynamic table and refer to it.
- if (can_write_to_encoder_stream) {
- encoder_stream_sender_.SendInsertWithNameReference(is_static,
- index, value);
- uint64_t new_index = header_table_.InsertEntry(name, value);
- representations.push_back(EncodeIndexedHeaderField(
- /* is_static = */ false, new_index, referred_indices));
- smallest_blocking_index =
- std::min<uint64_t>(smallest_blocking_index, new_index);
-
- break;
- }
- }
-
- // Emit literal field with name reference.
- representations.push_back(EncodeLiteralHeaderFieldWithNameReference(
- is_static, index, value, referred_indices));
-
- break;
- }
-
- if (!blocking_allowed) {
- blocked_stream_limit_exhausted = true;
- } else if (QpackEntry::Size(name, value) >
- header_table_.MaxInsertSizeWithoutEvictingGivenEntry(
- std::min(smallest_blocking_index, index))) {
- dynamic_table_insertion_blocked = true;
- } else {
- // If allowed, insert entry with name reference and refer to it.
- if (can_write_to_encoder_stream) {
- encoder_stream_sender_.SendInsertWithNameReference(
- is_static,
- QpackAbsoluteIndexToEncoderStreamRelativeIndex(
- index, header_table_.inserted_entry_count()),
- value);
- uint64_t new_index = header_table_.InsertEntry(name, value);
- representations.push_back(EncodeIndexedHeaderField(
- is_static, new_index, referred_indices));
- smallest_blocking_index = std::min(smallest_blocking_index, index);
- header_table_.set_dynamic_table_entry_referenced();
-
- break;
- }
- }
-
- if ((blocking_allowed || index < known_received_count) &&
- index >= draining_index) {
- // If allowed, refer to entry name directly, with literal value.
- representations.push_back(EncodeLiteralHeaderFieldWithNameReference(
- is_static, index, value, referred_indices));
- smallest_blocking_index = std::min(smallest_blocking_index, index);
- header_table_.set_dynamic_table_entry_referenced();
-
- break;
- }
-
- // Encode entry as string literals.
- // TODO(b/112770235): Use already acknowledged entry with lower index if
- // exists.
- // TODO(b/112770235): Use static entry name with literal value if
- // dynamic entry exists but cannot be used.
- representations.push_back(EncodeLiteralHeaderField(name, value));
-
- break;
-
- case QpackEncoderHeaderTable::MatchType::kNoMatch:
- // If allowed, insert entry and refer to it.
- if (!blocking_allowed) {
- blocked_stream_limit_exhausted = true;
- } else if (QpackEntry::Size(name, value) >
- header_table_.MaxInsertSizeWithoutEvictingGivenEntry(
- smallest_blocking_index)) {
- dynamic_table_insertion_blocked = true;
- } else {
- if (can_write_to_encoder_stream) {
- encoder_stream_sender_.SendInsertWithoutNameReference(name, value);
- uint64_t new_index = header_table_.InsertEntry(name, value);
- representations.push_back(EncodeIndexedHeaderField(
- /* is_static = */ false, new_index, referred_indices));
- smallest_blocking_index =
- std::min<uint64_t>(smallest_blocking_index, new_index);
-
- break;
- }
- }
-
- // Encode entry as string literals.
- // TODO(b/112770235): Consider also adding to dynamic table to improve
- // compression ratio for subsequent header blocks with peers that do not
- // allow any blocked streams.
- representations.push_back(EncodeLiteralHeaderField(name, value));
-
- break;
- }
- }
-
- const QuicByteCount encoder_stream_buffered_byte_count =
- encoder_stream_sender_.BufferedByteCount();
- QUICHE_DCHECK_GE(encoder_stream_buffered_byte_count,
- initial_encoder_stream_buffered_byte_count);
-
- if (encoder_stream_sent_byte_count) {
- *encoder_stream_sent_byte_count =
- encoder_stream_buffered_byte_count -
- initial_encoder_stream_buffered_byte_count;
- }
- if (can_write_to_encoder_stream) {
- encoder_stream_sender_.Flush();
- } else {
- QUICHE_DCHECK_EQ(encoder_stream_buffered_byte_count,
- initial_encoder_stream_buffered_byte_count);
- }
-
- ++header_list_count_;
-
- if (dynamic_table_insertion_blocked) {
- QUIC_HISTOGRAM_COUNTS(
- "QuicSession.Qpack.HeaderListCountWhenInsertionBlocked",
- header_list_count_, /* min = */ 1, /* max = */ 1000,
- /* bucket_count = */ 50,
- "The ordinality of a header list within a connection during the "
- "encoding of which at least one dynamic table insertion was "
- "blocked.");
- } else {
- QUIC_HISTOGRAM_COUNTS(
- "QuicSession.Qpack.HeaderListCountWhenInsertionNotBlocked",
- header_list_count_, /* min = */ 1, /* max = */ 1000,
- /* bucket_count = */ 50,
- "The ordinality of a header list within a connection during the "
- "encoding of which no dynamic table insertion was blocked.");
- }
-
- if (blocked_stream_limit_exhausted) {
- QUIC_HISTOGRAM_COUNTS(
- "QuicSession.Qpack.HeaderListCountWhenBlockedStreamLimited",
- header_list_count_, /* min = */ 1, /* max = */ 1000,
- /* bucket_count = */ 50,
- "The ordinality of a header list within a connection during the "
- "encoding of which unacknowledged dynamic table entries could not be "
- "referenced due to the limit on the number of blocked streams.");
- } else {
- QUIC_HISTOGRAM_COUNTS(
- "QuicSession.Qpack.HeaderListCountWhenNotBlockedStreamLimited",
- header_list_count_, /* min = */ 1, /* max = */ 1000,
- /* bucket_count = */ 50,
- "The ordinality of a header list within a connection during the "
- "encoding of which the limit on the number of blocked streams did "
- "not "
- "prevent referencing unacknowledged dynamic table entries.");
- }
-
- return representations;
-}
-
-std::string QpackEncoder::SecondPassEncode(
- QpackEncoder::Representations representations,
- uint64_t required_insert_count) const {
- QpackInstructionEncoder instruction_encoder;
- std::string encoded_headers;
-
- // Header block prefix.
- instruction_encoder.Encode(
- Representation::Prefix(QpackEncodeRequiredInsertCount(
- required_insert_count, header_table_.max_entries())),
- &encoded_headers);
-
- const uint64_t base = required_insert_count;
-
- for (auto& representation : representations) {
- // Dynamic table references must be transformed from absolute to relative
- // indices.
- if ((representation.instruction() == QpackIndexedHeaderFieldInstruction() ||
- representation.instruction() ==
- QpackLiteralHeaderFieldNameReferenceInstruction()) &&
- !representation.s_bit()) {
- representation.set_varint(QpackAbsoluteIndexToRequestStreamRelativeIndex(
- representation.varint(), base));
- }
- instruction_encoder.Encode(representation, &encoded_headers);
- }
-
- return encoded_headers;
-}
-
-std::string QpackEncoder::EncodeHeaderList(
- QuicStreamId stream_id,
- const spdy::Http2HeaderBlock& header_list,
- QuicByteCount* encoder_stream_sent_byte_count) {
- // Keep track of all dynamic table indices that this header block refers to so
- // that it can be passed to QpackBlockingManager.
- QpackBlockingManager::IndexSet referred_indices;
-
- // First pass: encode into |representations|.
- Representations representations =
- FirstPassEncode(stream_id, header_list, &referred_indices,
- encoder_stream_sent_byte_count);
-
- const uint64_t required_insert_count =
- referred_indices.empty()
- ? 0
- : QpackBlockingManager::RequiredInsertCount(referred_indices);
- if (!referred_indices.empty()) {
- blocking_manager_.OnHeaderBlockSent(stream_id, std::move(referred_indices));
- }
-
- // Second pass.
- return SecondPassEncode(std::move(representations), required_insert_count);
-}
-
-bool QpackEncoder::SetMaximumDynamicTableCapacity(
- uint64_t maximum_dynamic_table_capacity) {
- return header_table_.SetMaximumDynamicTableCapacity(
- maximum_dynamic_table_capacity);
-}
-
-void QpackEncoder::SetDynamicTableCapacity(uint64_t dynamic_table_capacity) {
- encoder_stream_sender_.SendSetDynamicTableCapacity(dynamic_table_capacity);
- // Do not flush encoder stream. This write can safely be delayed until more
- // instructions are written.
-
- bool success = header_table_.SetDynamicTableCapacity(dynamic_table_capacity);
- QUICHE_DCHECK(success);
-}
-
-bool QpackEncoder::SetMaximumBlockedStreams(uint64_t maximum_blocked_streams) {
- if (maximum_blocked_streams < maximum_blocked_streams_) {
- return false;
- }
- maximum_blocked_streams_ = maximum_blocked_streams;
- return true;
-}
-
-void QpackEncoder::OnInsertCountIncrement(uint64_t increment) {
- if (increment == 0) {
- OnErrorDetected(QUIC_QPACK_DECODER_STREAM_INVALID_ZERO_INCREMENT,
- "Invalid increment value 0.");
- return;
- }
-
- if (!blocking_manager_.OnInsertCountIncrement(increment)) {
- OnErrorDetected(QUIC_QPACK_DECODER_STREAM_INCREMENT_OVERFLOW,
- "Insert Count Increment instruction causes overflow.");
- }
-
- if (blocking_manager_.known_received_count() >
- header_table_.inserted_entry_count()) {
- OnErrorDetected(QUIC_QPACK_DECODER_STREAM_IMPOSSIBLE_INSERT_COUNT,
- absl::StrCat("Increment value ", increment,
- " raises known received count to ",
- blocking_manager_.known_received_count(),
- " exceeding inserted entry count ",
- header_table_.inserted_entry_count()));
- }
-}
-
-void QpackEncoder::OnHeaderAcknowledgement(QuicStreamId stream_id) {
- if (!blocking_manager_.OnHeaderAcknowledgement(stream_id)) {
- OnErrorDetected(
- QUIC_QPACK_DECODER_STREAM_INCORRECT_ACKNOWLEDGEMENT,
- absl::StrCat("Header Acknowledgement received for stream ", stream_id,
- " with no outstanding header blocks."));
- }
-}
-
-void QpackEncoder::OnStreamCancellation(QuicStreamId stream_id) {
- blocking_manager_.OnStreamCancellation(stream_id);
-}
-
-void QpackEncoder::OnErrorDetected(QuicErrorCode error_code,
- absl::string_view error_message) {
- decoder_stream_error_delegate_->OnDecoderStreamError(error_code,
- error_message);
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_encoder.h b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_encoder.h
deleted file mode 100644
index c3d77fea061..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_encoder.h
+++ /dev/null
@@ -1,164 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QPACK_QPACK_ENCODER_H_
-#define QUICHE_QUIC_CORE_QPACK_QPACK_ENCODER_H_
-
-#include <cstdint>
-#include <memory>
-#include <string>
-#include <vector>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/qpack/qpack_blocking_manager.h"
-#include "quic/core/qpack/qpack_decoder_stream_receiver.h"
-#include "quic/core/qpack/qpack_encoder_stream_sender.h"
-#include "quic/core/qpack/qpack_header_table.h"
-#include "quic/core/qpack/qpack_instructions.h"
-#include "quic/core/quic_error_codes.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_export.h"
-#include "quic/platform/api/quic_exported_stats.h"
-#include "spdy/core/spdy_header_block.h"
-
-namespace quic {
-
-namespace test {
-
-class QpackEncoderPeer;
-
-} // namespace test
-
-// QPACK encoder class. Exactly one instance should exist per QUIC connection.
-class QUIC_EXPORT_PRIVATE QpackEncoder
- : public QpackDecoderStreamReceiver::Delegate {
- public:
- // Interface for receiving notification that an error has occurred on the
- // decoder stream. This MUST be treated as a connection error of type
- // HTTP_QPACK_DECODER_STREAM_ERROR.
- class QUIC_EXPORT_PRIVATE DecoderStreamErrorDelegate {
- public:
- virtual ~DecoderStreamErrorDelegate() {}
-
- virtual void OnDecoderStreamError(QuicErrorCode error_code,
- absl::string_view error_message) = 0;
- };
-
- QpackEncoder(DecoderStreamErrorDelegate* decoder_stream_error_delegate);
- ~QpackEncoder() override;
-
- // Encode a header list. If |encoder_stream_sent_byte_count| is not null,
- // |*encoder_stream_sent_byte_count| will be set to the number of bytes sent
- // on the encoder stream to insert dynamic table entries.
- std::string EncodeHeaderList(QuicStreamId stream_id,
- const spdy::Http2HeaderBlock& header_list,
- QuicByteCount* encoder_stream_sent_byte_count);
-
- // Set maximum dynamic table capacity to |maximum_dynamic_table_capacity|,
- // measured in bytes. Called when SETTINGS_QPACK_MAX_TABLE_CAPACITY is
- // received. Encoder needs to know this value so that it can calculate
- // MaxEntries, used as a modulus to encode Required Insert Count.
- // Returns true if |maximum_dynamic_table_capacity| is set for the first time
- // or if it doesn't change current value. The setting is not changed when
- // returning false.
- bool SetMaximumDynamicTableCapacity(uint64_t maximum_dynamic_table_capacity);
-
- // Set dynamic table capacity to |dynamic_table_capacity|.
- // |dynamic_table_capacity| must not exceed maximum dynamic table capacity.
- // Also sends Set Dynamic Table Capacity instruction on encoder stream.
- void SetDynamicTableCapacity(uint64_t dynamic_table_capacity);
-
- // Set maximum number of blocked streams.
- // Called when SETTINGS_QPACK_BLOCKED_STREAMS is received.
- // Returns true if |maximum_blocked_streams| doesn't decrease current value.
- // The setting is not changed when returning false.
- bool SetMaximumBlockedStreams(uint64_t maximum_blocked_streams);
-
- // QpackDecoderStreamReceiver::Delegate implementation
- void OnInsertCountIncrement(uint64_t increment) override;
- void OnHeaderAcknowledgement(QuicStreamId stream_id) override;
- void OnStreamCancellation(QuicStreamId stream_id) override;
- void OnErrorDetected(QuicErrorCode error_code,
- absl::string_view error_message) override;
-
- // delegate must be set if dynamic table capacity is not zero.
- void set_qpack_stream_sender_delegate(QpackStreamSenderDelegate* delegate) {
- encoder_stream_sender_.set_qpack_stream_sender_delegate(delegate);
- }
-
- QpackStreamReceiver* decoder_stream_receiver() {
- return &decoder_stream_receiver_;
- }
-
- // True if any dynamic table entries have been referenced from a header block.
- bool dynamic_table_entry_referenced() const {
- return header_table_.dynamic_table_entry_referenced();
- }
-
- uint64_t maximum_blocked_streams() const { return maximum_blocked_streams_; }
-
- uint64_t MaximumDynamicTableCapacity() const {
- return header_table_.maximum_dynamic_table_capacity();
- }
-
- private:
- friend class test::QpackEncoderPeer;
-
- using Representation = QpackInstructionWithValues;
- using Representations = std::vector<Representation>;
-
- // Generate indexed header field representation
- // and optionally update |*referred_indices|.
- static Representation EncodeIndexedHeaderField(
- bool is_static,
- uint64_t index,
- QpackBlockingManager::IndexSet* referred_indices);
-
- // Generate literal header field with name reference representation
- // and optionally update |*referred_indices|.
- static Representation EncodeLiteralHeaderFieldWithNameReference(
- bool is_static,
- uint64_t index,
- absl::string_view value,
- QpackBlockingManager::IndexSet* referred_indices);
-
- // Generate literal header field representation.
- static Representation EncodeLiteralHeaderField(absl::string_view name,
- absl::string_view value);
-
- // Performs first pass of two-pass encoding: represent each header field in
- // |*header_list| as a reference to an existing entry, the name of an existing
- // entry with a literal value, or a literal name and value pair. Sends
- // necessary instructions on the encoder stream coalesced in a single write.
- // Records absolute indices of referred dynamic table entries in
- // |*referred_indices|. If |encoder_stream_sent_byte_count| is not null, then
- // sets |*encoder_stream_sent_byte_count| to the number of bytes sent on the
- // encoder stream to insert dynamic table entries. Returns list of header
- // field representations, with all dynamic table entries referred to with
- // absolute indices. Returned representation objects may have
- // absl::string_views pointing to strings owned by |*header_list|.
- Representations FirstPassEncode(
- QuicStreamId stream_id,
- const spdy::Http2HeaderBlock& header_list,
- QpackBlockingManager::IndexSet* referred_indices,
- QuicByteCount* encoder_stream_sent_byte_count);
-
- // Performs second pass of two-pass encoding: serializes representations
- // generated in first pass, transforming absolute indices of dynamic table
- // entries to relative indices.
- std::string SecondPassEncode(Representations representations,
- uint64_t required_insert_count) const;
-
- DecoderStreamErrorDelegate* const decoder_stream_error_delegate_;
- QpackDecoderStreamReceiver decoder_stream_receiver_;
- QpackEncoderStreamSender encoder_stream_sender_;
- QpackEncoderHeaderTable header_table_;
- uint64_t maximum_blocked_streams_;
- QpackBlockingManager blocking_manager_;
- int header_list_count_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_QPACK_QPACK_ENCODER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_encoder_stream_receiver.cc b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_encoder_stream_receiver.cc
deleted file mode 100644
index bf71faf5def..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_encoder_stream_receiver.cc
+++ /dev/null
@@ -1,80 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/qpack/qpack_encoder_stream_receiver.h"
-
-#include "absl/strings/string_view.h"
-#include "http2/decoder/decode_buffer.h"
-#include "http2/decoder/decode_status.h"
-#include "quic/core/qpack/qpack_instructions.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-QpackEncoderStreamReceiver::QpackEncoderStreamReceiver(Delegate* delegate)
- : instruction_decoder_(QpackEncoderStreamLanguage(), this),
- delegate_(delegate),
- error_detected_(false) {
- QUICHE_DCHECK(delegate_);
-}
-
-void QpackEncoderStreamReceiver::Decode(absl::string_view data) {
- if (data.empty() || error_detected_) {
- return;
- }
-
- instruction_decoder_.Decode(data);
-}
-
-bool QpackEncoderStreamReceiver::OnInstructionDecoded(
- const QpackInstruction* instruction) {
- if (instruction == InsertWithNameReferenceInstruction()) {
- delegate_->OnInsertWithNameReference(instruction_decoder_.s_bit(),
- instruction_decoder_.varint(),
- instruction_decoder_.value());
- return true;
- }
-
- if (instruction == InsertWithoutNameReferenceInstruction()) {
- delegate_->OnInsertWithoutNameReference(instruction_decoder_.name(),
- instruction_decoder_.value());
- return true;
- }
-
- if (instruction == DuplicateInstruction()) {
- delegate_->OnDuplicate(instruction_decoder_.varint());
- return true;
- }
-
- QUICHE_DCHECK_EQ(instruction, SetDynamicTableCapacityInstruction());
- delegate_->OnSetDynamicTableCapacity(instruction_decoder_.varint());
- return true;
-}
-
-void QpackEncoderStreamReceiver::OnInstructionDecodingError(
- QpackInstructionDecoder::ErrorCode error_code,
- absl::string_view error_message) {
- QUICHE_DCHECK(!error_detected_);
-
- error_detected_ = true;
-
- QuicErrorCode quic_error_code;
- switch (error_code) {
- case QpackInstructionDecoder::ErrorCode::INTEGER_TOO_LARGE:
- quic_error_code = QUIC_QPACK_ENCODER_STREAM_INTEGER_TOO_LARGE;
- break;
- case QpackInstructionDecoder::ErrorCode::STRING_LITERAL_TOO_LONG:
- quic_error_code = QUIC_QPACK_ENCODER_STREAM_STRING_LITERAL_TOO_LONG;
- break;
- case QpackInstructionDecoder::ErrorCode::HUFFMAN_ENCODING_ERROR:
- quic_error_code = QUIC_QPACK_ENCODER_STREAM_HUFFMAN_ENCODING_ERROR;
- break;
- default:
- quic_error_code = QUIC_INTERNAL_ERROR;
- }
-
- delegate_->OnErrorDetected(quic_error_code, error_message);
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_encoder_stream_receiver.h b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_encoder_stream_receiver.h
deleted file mode 100644
index b3e43cf94f7..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_encoder_stream_receiver.h
+++ /dev/null
@@ -1,74 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QPACK_QPACK_ENCODER_STREAM_RECEIVER_H_
-#define QUICHE_QUIC_CORE_QPACK_QPACK_ENCODER_STREAM_RECEIVER_H_
-
-#include <cstdint>
-#include <string>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/qpack/qpack_instruction_decoder.h"
-#include "quic/core/qpack/qpack_stream_receiver.h"
-#include "quic/core/quic_error_codes.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// This class decodes data received on the encoder stream.
-class QUIC_EXPORT_PRIVATE QpackEncoderStreamReceiver
- : public QpackInstructionDecoder::Delegate,
- public QpackStreamReceiver {
- public:
- // An interface for handling instructions decoded from the encoder stream, see
- // https://quicwg.org/base-drafts/draft-ietf-quic-qpack.html#rfc.section.5.2
- class QUIC_EXPORT_PRIVATE Delegate {
- public:
- virtual ~Delegate() = default;
-
- // 5.2.1. Insert With Name Reference
- virtual void OnInsertWithNameReference(bool is_static,
- uint64_t name_index,
- absl::string_view value) = 0;
- // 5.2.2. Insert Without Name Reference
- virtual void OnInsertWithoutNameReference(absl::string_view name,
- absl::string_view value) = 0;
- // 5.2.3. Duplicate
- virtual void OnDuplicate(uint64_t index) = 0;
- // 5.2.4. Set Dynamic Table Capacity
- virtual void OnSetDynamicTableCapacity(uint64_t capacity) = 0;
- // Decoding error
- virtual void OnErrorDetected(QuicErrorCode error_code,
- absl::string_view error_message) = 0;
- };
-
- explicit QpackEncoderStreamReceiver(Delegate* delegate);
- QpackEncoderStreamReceiver() = delete;
- QpackEncoderStreamReceiver(const QpackEncoderStreamReceiver&) = delete;
- QpackEncoderStreamReceiver& operator=(const QpackEncoderStreamReceiver&) =
- delete;
- ~QpackEncoderStreamReceiver() override = default;
-
- // Implements QpackStreamReceiver::Decode().
- // Decode data and call appropriate Delegate method after each decoded
- // instruction. Once an error occurs, Delegate::OnErrorDetected() is called,
- // and all further data is ignored.
- void Decode(absl::string_view data) override;
-
- // QpackInstructionDecoder::Delegate implementation.
- bool OnInstructionDecoded(const QpackInstruction* instruction) override;
- void OnInstructionDecodingError(QpackInstructionDecoder::ErrorCode error_code,
- absl::string_view error_message) override;
-
- private:
- QpackInstructionDecoder instruction_decoder_;
- Delegate* const delegate_;
-
- // True if a decoding error has been detected.
- bool error_detected_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_QPACK_QPACK_ENCODER_STREAM_RECEIVER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_encoder_stream_receiver_test.cc b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_encoder_stream_receiver_test.cc
deleted file mode 100644
index 2fa440b51b4..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_encoder_stream_receiver_test.cc
+++ /dev/null
@@ -1,197 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/qpack/qpack_encoder_stream_receiver.h"
-
-#include "absl/strings/escaping.h"
-#include "absl/strings/string_view.h"
-#include "quic/platform/api/quic_test.h"
-
-using testing::Eq;
-using testing::StrictMock;
-
-namespace quic {
-namespace test {
-namespace {
-
-class MockDelegate : public QpackEncoderStreamReceiver::Delegate {
- public:
- ~MockDelegate() override = default;
-
- MOCK_METHOD(void,
- OnInsertWithNameReference,
- (bool is_static, uint64_t name_index, absl::string_view value),
- (override));
- MOCK_METHOD(void,
- OnInsertWithoutNameReference,
- (absl::string_view name, absl::string_view value),
- (override));
- MOCK_METHOD(void, OnDuplicate, (uint64_t index), (override));
- MOCK_METHOD(void, OnSetDynamicTableCapacity, (uint64_t capacity), (override));
- MOCK_METHOD(void,
- OnErrorDetected,
- (QuicErrorCode error_code, absl::string_view error_message),
- (override));
-};
-
-class QpackEncoderStreamReceiverTest : public QuicTest {
- protected:
- QpackEncoderStreamReceiverTest() : stream_(&delegate_) {}
- ~QpackEncoderStreamReceiverTest() override = default;
-
- void Decode(absl::string_view data) { stream_.Decode(data); }
- StrictMock<MockDelegate>* delegate() { return &delegate_; }
-
- private:
- QpackEncoderStreamReceiver stream_;
- StrictMock<MockDelegate> delegate_;
-};
-
-TEST_F(QpackEncoderStreamReceiverTest, InsertWithNameReference) {
- // Static, index fits in prefix, empty value.
- EXPECT_CALL(*delegate(), OnInsertWithNameReference(true, 5, Eq("")));
- // Static, index fits in prefix, Huffman encoded value.
- EXPECT_CALL(*delegate(), OnInsertWithNameReference(true, 2, Eq("foo")));
- // Not static, index does not fit in prefix, not Huffman encoded value.
- EXPECT_CALL(*delegate(), OnInsertWithNameReference(false, 137, Eq("bar")));
- // Value length does not fit in prefix.
- // 'Z' would be Huffman encoded to 8 bits, so no Huffman encoding is used.
- EXPECT_CALL(*delegate(),
- OnInsertWithNameReference(false, 42, Eq(std::string(127, 'Z'))));
-
- Decode(absl::HexStringToBytes(
- "c500"
- "c28294e7"
- "bf4a03626172"
- "aa7f005a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a"
- "5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a"
- "5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a"
- "5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a"));
-}
-
-TEST_F(QpackEncoderStreamReceiverTest, InsertWithNameReferenceIndexTooLarge) {
- EXPECT_CALL(*delegate(),
- OnErrorDetected(QUIC_QPACK_ENCODER_STREAM_INTEGER_TOO_LARGE,
- Eq("Encoded integer too large.")));
-
- Decode(absl::HexStringToBytes("bfffffffffffffffffffffff"));
-}
-
-TEST_F(QpackEncoderStreamReceiverTest, InsertWithNameReferenceValueTooLong) {
- EXPECT_CALL(*delegate(),
- OnErrorDetected(QUIC_QPACK_ENCODER_STREAM_INTEGER_TOO_LARGE,
- Eq("Encoded integer too large.")));
-
- Decode(absl::HexStringToBytes("c57fffffffffffffffffffff"));
-}
-
-TEST_F(QpackEncoderStreamReceiverTest, InsertWithoutNameReference) {
- // Empty name and value.
- EXPECT_CALL(*delegate(), OnInsertWithoutNameReference(Eq(""), Eq("")));
- // Huffman encoded short strings.
- EXPECT_CALL(*delegate(), OnInsertWithoutNameReference(Eq("bar"), Eq("bar")));
- // Not Huffman encoded short strings.
- EXPECT_CALL(*delegate(), OnInsertWithoutNameReference(Eq("foo"), Eq("foo")));
- // Not Huffman encoded long strings; length does not fit on prefix.
- // 'Z' would be Huffman encoded to 8 bits, so no Huffman encoding is used.
- EXPECT_CALL(*delegate(),
- OnInsertWithoutNameReference(Eq(std::string(31, 'Z')),
- Eq(std::string(127, 'Z'))));
-
- Decode(absl::HexStringToBytes(
- "4000"
- "4362617203626172"
- "6294e78294e7"
- "5f005a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a7f005a"
- "5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a"
- "5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a"
- "5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a"
- "5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a"));
-}
-
-// Name Length value is too large for varint decoder to decode.
-TEST_F(QpackEncoderStreamReceiverTest,
- InsertWithoutNameReferenceNameTooLongForVarintDecoder) {
- EXPECT_CALL(*delegate(),
- OnErrorDetected(QUIC_QPACK_ENCODER_STREAM_INTEGER_TOO_LARGE,
- Eq("Encoded integer too large.")));
-
- Decode(absl::HexStringToBytes("5fffffffffffffffffffff"));
-}
-
-// Name Length value can be decoded by varint decoder but exceeds 1 MB limit.
-TEST_F(QpackEncoderStreamReceiverTest,
- InsertWithoutNameReferenceNameExceedsLimit) {
- EXPECT_CALL(*delegate(),
- OnErrorDetected(QUIC_QPACK_ENCODER_STREAM_STRING_LITERAL_TOO_LONG,
- Eq("String literal too long.")));
-
- Decode(absl::HexStringToBytes("5fffff7f"));
-}
-
-// Value Length value is too large for varint decoder to decode.
-TEST_F(QpackEncoderStreamReceiverTest,
- InsertWithoutNameReferenceValueTooLongForVarintDecoder) {
- EXPECT_CALL(*delegate(),
- OnErrorDetected(QUIC_QPACK_ENCODER_STREAM_INTEGER_TOO_LARGE,
- Eq("Encoded integer too large.")));
-
- Decode(absl::HexStringToBytes("436261727fffffffffffffffffffff"));
-}
-
-// Value Length value can be decoded by varint decoder but exceeds 1 MB limit.
-TEST_F(QpackEncoderStreamReceiverTest,
- InsertWithoutNameReferenceValueExceedsLimit) {
- EXPECT_CALL(*delegate(),
- OnErrorDetected(QUIC_QPACK_ENCODER_STREAM_STRING_LITERAL_TOO_LONG,
- Eq("String literal too long.")));
-
- Decode(absl::HexStringToBytes("436261727fffff7f"));
-}
-
-TEST_F(QpackEncoderStreamReceiverTest, Duplicate) {
- // Small index fits in prefix.
- EXPECT_CALL(*delegate(), OnDuplicate(17));
- // Large index requires two extension bytes.
- EXPECT_CALL(*delegate(), OnDuplicate(500));
-
- Decode(absl::HexStringToBytes("111fd503"));
-}
-
-TEST_F(QpackEncoderStreamReceiverTest, DuplicateIndexTooLarge) {
- EXPECT_CALL(*delegate(),
- OnErrorDetected(QUIC_QPACK_ENCODER_STREAM_INTEGER_TOO_LARGE,
- Eq("Encoded integer too large.")));
-
- Decode(absl::HexStringToBytes("1fffffffffffffffffffff"));
-}
-
-TEST_F(QpackEncoderStreamReceiverTest, SetDynamicTableCapacity) {
- // Small capacity fits in prefix.
- EXPECT_CALL(*delegate(), OnSetDynamicTableCapacity(17));
- // Large capacity requires two extension bytes.
- EXPECT_CALL(*delegate(), OnSetDynamicTableCapacity(500));
-
- Decode(absl::HexStringToBytes("313fd503"));
-}
-
-TEST_F(QpackEncoderStreamReceiverTest, SetDynamicTableCapacityTooLarge) {
- EXPECT_CALL(*delegate(),
- OnErrorDetected(QUIC_QPACK_ENCODER_STREAM_INTEGER_TOO_LARGE,
- Eq("Encoded integer too large.")));
-
- Decode(absl::HexStringToBytes("3fffffffffffffffffffff"));
-}
-
-TEST_F(QpackEncoderStreamReceiverTest, InvalidHuffmanEncoding) {
- EXPECT_CALL(*delegate(),
- OnErrorDetected(QUIC_QPACK_ENCODER_STREAM_HUFFMAN_ENCODING_ERROR,
- Eq("Error in Huffman-encoded string.")));
-
- Decode(absl::HexStringToBytes("c281ff"));
-}
-
-} // namespace
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_encoder_stream_sender.cc b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_encoder_stream_sender.cc
deleted file mode 100644
index 8b6f887cf3c..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_encoder_stream_sender.cc
+++ /dev/null
@@ -1,69 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/qpack/qpack_encoder_stream_sender.h"
-
-#include <cstddef>
-#include <limits>
-#include <string>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/qpack/qpack_instructions.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-namespace {
-
-// If QUIC stream bufferes more that this number of bytes,
-// CanWrite() will return false.
-constexpr uint64_t kMaxBytesBufferedByStream = 64 * 1024;
-
-} // anonymous namespace
-
-QpackEncoderStreamSender::QpackEncoderStreamSender() : delegate_(nullptr) {}
-
-void QpackEncoderStreamSender::SendInsertWithNameReference(
- bool is_static,
- uint64_t name_index,
- absl::string_view value) {
- instruction_encoder_.Encode(
- QpackInstructionWithValues::InsertWithNameReference(is_static, name_index,
- value),
- &buffer_);
-}
-
-void QpackEncoderStreamSender::SendInsertWithoutNameReference(
- absl::string_view name,
- absl::string_view value) {
- instruction_encoder_.Encode(
- QpackInstructionWithValues::InsertWithoutNameReference(name, value),
- &buffer_);
-}
-
-void QpackEncoderStreamSender::SendDuplicate(uint64_t index) {
- instruction_encoder_.Encode(QpackInstructionWithValues::Duplicate(index),
- &buffer_);
-}
-
-void QpackEncoderStreamSender::SendSetDynamicTableCapacity(uint64_t capacity) {
- instruction_encoder_.Encode(
- QpackInstructionWithValues::SetDynamicTableCapacity(capacity), &buffer_);
-}
-
-bool QpackEncoderStreamSender::CanWrite() const {
- return delegate_ && delegate_->NumBytesBuffered() + buffer_.size() <=
- kMaxBytesBufferedByStream;
-}
-
-void QpackEncoderStreamSender::Flush() {
- if (buffer_.empty()) {
- return;
- }
-
- delegate_->WriteStreamData(buffer_);
- buffer_.clear();
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_encoder_stream_sender.h b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_encoder_stream_sender.h
deleted file mode 100644
index d8c64306a78..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_encoder_stream_sender.h
+++ /dev/null
@@ -1,69 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QPACK_QPACK_ENCODER_STREAM_SENDER_H_
-#define QUICHE_QUIC_CORE_QPACK_QPACK_ENCODER_STREAM_SENDER_H_
-
-#include <cstdint>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/qpack/qpack_instruction_encoder.h"
-#include "quic/core/qpack/qpack_stream_sender_delegate.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// This class serializes instructions for transmission on the encoder stream.
-// Serialized instructions are buffered until Flush() is called.
-class QUIC_EXPORT_PRIVATE QpackEncoderStreamSender {
- public:
- QpackEncoderStreamSender();
- QpackEncoderStreamSender(const QpackEncoderStreamSender&) = delete;
- QpackEncoderStreamSender& operator=(const QpackEncoderStreamSender&) = delete;
-
- // Methods for serializing and buffering instructions, see
- // https://quicwg.org/base-drafts/draft-ietf-quic-qpack.html#rfc.section.5.2
-
- // 5.2.1. Insert With Name Reference
- void SendInsertWithNameReference(bool is_static,
- uint64_t name_index,
- absl::string_view value);
- // 5.2.2. Insert Without Name Reference
- void SendInsertWithoutNameReference(absl::string_view name,
- absl::string_view value);
- // 5.2.3. Duplicate
- void SendDuplicate(uint64_t index);
- // 5.2.4. Set Dynamic Table Capacity
- void SendSetDynamicTableCapacity(uint64_t capacity);
-
- // Returns number of bytes buffered by this object.
- // There is no limit on how much data this object is willing to buffer.
- QuicByteCount BufferedByteCount() const { return buffer_.size(); }
-
- // Returns whether writing to the encoder stream is allowed. Writing is
- // disallowed if the amount of data buffered by the underlying stream exceeds
- // a hardcoded limit, in order to limit memory consumption in case the encoder
- // stream is blocked. CanWrite() returning true does not mean that the
- // encoder stream is not blocked, it just means the blocked data does not
- // exceed the threshold.
- bool CanWrite() const;
-
- // Writes all buffered instructions on the encoder stream.
- void Flush();
-
- // delegate must be set if dynamic table capacity is not zero.
- void set_qpack_stream_sender_delegate(QpackStreamSenderDelegate* delegate) {
- delegate_ = delegate;
- }
-
- private:
- QpackStreamSenderDelegate* delegate_;
- QpackInstructionEncoder instruction_encoder_;
- std::string buffer_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_QPACK_QPACK_ENCODER_STREAM_SENDER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_encoder_stream_sender_test.cc b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_encoder_stream_sender_test.cc
deleted file mode 100644
index 98e3e23030f..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_encoder_stream_sender_test.cc
+++ /dev/null
@@ -1,179 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/qpack/qpack_encoder_stream_sender.h"
-
-#include "absl/strings/escaping.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/qpack/qpack_test_utils.h"
-
-using ::testing::Eq;
-using ::testing::StrictMock;
-
-namespace quic {
-namespace test {
-namespace {
-
-class QpackEncoderStreamSenderTest : public QuicTest {
- protected:
- QpackEncoderStreamSenderTest() {
- stream_.set_qpack_stream_sender_delegate(&delegate_);
- }
- ~QpackEncoderStreamSenderTest() override = default;
-
- StrictMock<MockQpackStreamSenderDelegate> delegate_;
- QpackEncoderStreamSender stream_;
-};
-
-TEST_F(QpackEncoderStreamSenderTest, InsertWithNameReference) {
- EXPECT_EQ(0u, stream_.BufferedByteCount());
-
- // Static, index fits in prefix, empty value.
- std::string expected_encoded_data = absl::HexStringToBytes("c500");
- EXPECT_CALL(delegate_, WriteStreamData(Eq(expected_encoded_data)));
- stream_.SendInsertWithNameReference(true, 5, "");
- EXPECT_EQ(expected_encoded_data.size(), stream_.BufferedByteCount());
- stream_.Flush();
-
- // Static, index fits in prefix, Huffman encoded value.
- expected_encoded_data = absl::HexStringToBytes("c28294e7");
- EXPECT_CALL(delegate_, WriteStreamData(Eq(expected_encoded_data)));
- stream_.SendInsertWithNameReference(true, 2, "foo");
- EXPECT_EQ(expected_encoded_data.size(), stream_.BufferedByteCount());
- stream_.Flush();
-
- // Not static, index does not fit in prefix, not Huffman encoded value.
- expected_encoded_data = absl::HexStringToBytes("bf4a03626172");
- EXPECT_CALL(delegate_, WriteStreamData(Eq(expected_encoded_data)));
- stream_.SendInsertWithNameReference(false, 137, "bar");
- EXPECT_EQ(expected_encoded_data.size(), stream_.BufferedByteCount());
- stream_.Flush();
-
- // Value length does not fit in prefix.
- // 'Z' would be Huffman encoded to 8 bits, so no Huffman encoding is used.
- expected_encoded_data = absl::HexStringToBytes(
- "aa7f005a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a"
- "5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a"
- "5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a"
- "5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a");
- EXPECT_CALL(delegate_, WriteStreamData(Eq(expected_encoded_data)));
- stream_.SendInsertWithNameReference(false, 42, std::string(127, 'Z'));
- EXPECT_EQ(expected_encoded_data.size(), stream_.BufferedByteCount());
- stream_.Flush();
-}
-
-TEST_F(QpackEncoderStreamSenderTest, InsertWithoutNameReference) {
- EXPECT_EQ(0u, stream_.BufferedByteCount());
-
- // Empty name and value.
- std::string expected_encoded_data = absl::HexStringToBytes("4000");
- EXPECT_CALL(delegate_, WriteStreamData(Eq(expected_encoded_data)));
- stream_.SendInsertWithoutNameReference("", "");
- EXPECT_EQ(expected_encoded_data.size(), stream_.BufferedByteCount());
- stream_.Flush();
-
- // Huffman encoded short strings.
- expected_encoded_data = absl::HexStringToBytes("6294e78294e7");
- EXPECT_CALL(delegate_, WriteStreamData(Eq(expected_encoded_data)));
- stream_.SendInsertWithoutNameReference("foo", "foo");
- EXPECT_EQ(expected_encoded_data.size(), stream_.BufferedByteCount());
- stream_.Flush();
-
- // Not Huffman encoded short strings.
- expected_encoded_data = absl::HexStringToBytes("4362617203626172");
- EXPECT_CALL(delegate_, WriteStreamData(Eq(expected_encoded_data)));
- stream_.SendInsertWithoutNameReference("bar", "bar");
- EXPECT_EQ(expected_encoded_data.size(), stream_.BufferedByteCount());
- stream_.Flush();
-
- // Not Huffman encoded long strings; length does not fit on prefix.
- // 'Z' would be Huffman encoded to 8 bits, so no Huffman encoding is used.
- expected_encoded_data = absl::HexStringToBytes(
- "5f005a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a7f"
- "005a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a"
- "5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a"
- "5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a"
- "5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a");
- EXPECT_CALL(delegate_, WriteStreamData(Eq(expected_encoded_data)));
- stream_.SendInsertWithoutNameReference(std::string(31, 'Z'),
- std::string(127, 'Z'));
- EXPECT_EQ(expected_encoded_data.size(), stream_.BufferedByteCount());
- stream_.Flush();
-}
-
-TEST_F(QpackEncoderStreamSenderTest, Duplicate) {
- EXPECT_EQ(0u, stream_.BufferedByteCount());
-
- // Small index fits in prefix.
- std::string expected_encoded_data = absl::HexStringToBytes("11");
- EXPECT_CALL(delegate_, WriteStreamData(Eq(expected_encoded_data)));
- stream_.SendDuplicate(17);
- EXPECT_EQ(expected_encoded_data.size(), stream_.BufferedByteCount());
- stream_.Flush();
-
- // Large index requires two extension bytes.
- expected_encoded_data = absl::HexStringToBytes("1fd503");
- EXPECT_CALL(delegate_, WriteStreamData(Eq(expected_encoded_data)));
- stream_.SendDuplicate(500);
- EXPECT_EQ(expected_encoded_data.size(), stream_.BufferedByteCount());
- stream_.Flush();
-}
-
-TEST_F(QpackEncoderStreamSenderTest, SetDynamicTableCapacity) {
- EXPECT_EQ(0u, stream_.BufferedByteCount());
-
- // Small capacity fits in prefix.
- std::string expected_encoded_data = absl::HexStringToBytes("31");
- EXPECT_CALL(delegate_, WriteStreamData(Eq(expected_encoded_data)));
- stream_.SendSetDynamicTableCapacity(17);
- EXPECT_EQ(expected_encoded_data.size(), stream_.BufferedByteCount());
- stream_.Flush();
- EXPECT_EQ(0u, stream_.BufferedByteCount());
-
- // Large capacity requires two extension bytes.
- expected_encoded_data = absl::HexStringToBytes("3fd503");
- EXPECT_CALL(delegate_, WriteStreamData(Eq(expected_encoded_data)));
- stream_.SendSetDynamicTableCapacity(500);
- EXPECT_EQ(expected_encoded_data.size(), stream_.BufferedByteCount());
- stream_.Flush();
- EXPECT_EQ(0u, stream_.BufferedByteCount());
-}
-
-// No writes should happen until Flush is called.
-TEST_F(QpackEncoderStreamSenderTest, Coalesce) {
- // Insert entry with static name reference, empty value.
- stream_.SendInsertWithNameReference(true, 5, "");
-
- // Insert entry with static name reference, Huffman encoded value.
- stream_.SendInsertWithNameReference(true, 2, "foo");
-
- // Insert literal entry, Huffman encoded short strings.
- stream_.SendInsertWithoutNameReference("foo", "foo");
-
- // Duplicate entry.
- stream_.SendDuplicate(17);
-
- std::string expected_encoded_data = absl::HexStringToBytes(
- "c500" // Insert entry with static name reference.
- "c28294e7" // Insert entry with static name reference.
- "6294e78294e7" // Insert literal entry.
- "11"); // Duplicate entry.
-
- EXPECT_CALL(delegate_, WriteStreamData(Eq(expected_encoded_data)));
- EXPECT_EQ(expected_encoded_data.size(), stream_.BufferedByteCount());
- stream_.Flush();
- EXPECT_EQ(0u, stream_.BufferedByteCount());
-}
-
-// No writes should happen if QpackEncoderStreamSender::Flush() is called
-// when the buffer is empty.
-TEST_F(QpackEncoderStreamSenderTest, FlushEmpty) {
- EXPECT_EQ(0u, stream_.BufferedByteCount());
- stream_.Flush();
- EXPECT_EQ(0u, stream_.BufferedByteCount());
-}
-
-} // namespace
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_encoder_test.cc b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_encoder_test.cc
deleted file mode 100644
index 30f578e9378..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_encoder_test.cc
+++ /dev/null
@@ -1,632 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/qpack/qpack_encoder.h"
-
-#include <limits>
-#include <string>
-
-#include "absl/strings/escaping.h"
-#include "absl/strings/str_cat.h"
-#include "absl/strings/string_view.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/qpack/qpack_encoder_peer.h"
-#include "quic/test_tools/qpack/qpack_encoder_test_utils.h"
-#include "quic/test_tools/qpack/qpack_test_utils.h"
-
-using ::testing::_;
-using ::testing::Eq;
-using ::testing::Return;
-using ::testing::StrictMock;
-
-namespace quic {
-namespace test {
-namespace {
-
-// A number larger than kMaxBytesBufferedByStream in
-// qpack_encoder_stream_sender.cc. Returning this value from NumBytesBuffered()
-// will instruct QpackEncoder not to generate any instructions for the encoder
-// stream.
-constexpr uint64_t kTooManyBytesBuffered = 1024 * 1024;
-
-class QpackEncoderTest : public QuicTest {
- protected:
- QpackEncoderTest()
- : encoder_(&decoder_stream_error_delegate_),
- encoder_stream_sent_byte_count_(0) {
- encoder_.set_qpack_stream_sender_delegate(&encoder_stream_sender_delegate_);
- encoder_.SetMaximumBlockedStreams(1);
- }
-
- ~QpackEncoderTest() override = default;
-
- std::string Encode(const spdy::Http2HeaderBlock& header_list) {
- return encoder_.EncodeHeaderList(/* stream_id = */ 1, header_list,
- &encoder_stream_sent_byte_count_);
- }
-
- StrictMock<MockDecoderStreamErrorDelegate> decoder_stream_error_delegate_;
- StrictMock<MockQpackStreamSenderDelegate> encoder_stream_sender_delegate_;
- QpackEncoder encoder_;
- QuicByteCount encoder_stream_sent_byte_count_;
-};
-
-TEST_F(QpackEncoderTest, Empty) {
- EXPECT_CALL(encoder_stream_sender_delegate_, NumBytesBuffered())
- .WillRepeatedly(Return(0));
- spdy::Http2HeaderBlock header_list;
- std::string output = Encode(header_list);
-
- EXPECT_EQ(absl::HexStringToBytes("0000"), output);
-}
-
-TEST_F(QpackEncoderTest, EmptyName) {
- EXPECT_CALL(encoder_stream_sender_delegate_, NumBytesBuffered())
- .WillRepeatedly(Return(0));
- spdy::Http2HeaderBlock header_list;
- header_list[""] = "foo";
- std::string output = Encode(header_list);
-
- EXPECT_EQ(absl::HexStringToBytes("0000208294e7"), output);
-}
-
-TEST_F(QpackEncoderTest, EmptyValue) {
- EXPECT_CALL(encoder_stream_sender_delegate_, NumBytesBuffered())
- .WillRepeatedly(Return(0));
- spdy::Http2HeaderBlock header_list;
- header_list["foo"] = "";
- std::string output = Encode(header_list);
-
- EXPECT_EQ(absl::HexStringToBytes("00002a94e700"), output);
-}
-
-TEST_F(QpackEncoderTest, EmptyNameAndValue) {
- EXPECT_CALL(encoder_stream_sender_delegate_, NumBytesBuffered())
- .WillRepeatedly(Return(0));
- spdy::Http2HeaderBlock header_list;
- header_list[""] = "";
- std::string output = Encode(header_list);
-
- EXPECT_EQ(absl::HexStringToBytes("00002000"), output);
-}
-
-TEST_F(QpackEncoderTest, Simple) {
- EXPECT_CALL(encoder_stream_sender_delegate_, NumBytesBuffered())
- .WillRepeatedly(Return(0));
- spdy::Http2HeaderBlock header_list;
- header_list["foo"] = "bar";
- std::string output = Encode(header_list);
-
- EXPECT_EQ(absl::HexStringToBytes("00002a94e703626172"), output);
-}
-
-TEST_F(QpackEncoderTest, Multiple) {
- EXPECT_CALL(encoder_stream_sender_delegate_, NumBytesBuffered())
- .WillRepeatedly(Return(0));
- spdy::Http2HeaderBlock header_list;
- header_list["foo"] = "bar";
- // 'Z' would be Huffman encoded to 8 bits, so no Huffman encoding is used.
- header_list["ZZZZZZZ"] = std::string(127, 'Z');
- std::string output = Encode(header_list);
-
- EXPECT_EQ(
- absl::HexStringToBytes(
- "0000" // prefix
- "2a94e703626172" // foo: bar
- "27005a5a5a5a5a5a5a" // 7 octet long header name, the smallest number
- // that does not fit on a 3-bit prefix.
- "7f005a5a5a5a5a5a5a" // 127 octet long header value, the smallest
- "5a5a5a5a5a5a5a5a5a" // number that does not fit on a 7-bit prefix.
- "5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a"
- "5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a"
- "5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a"
- "5a5a5a5a5a5a5a5a5a"),
- output);
-}
-
-TEST_F(QpackEncoderTest, StaticTable) {
- EXPECT_CALL(encoder_stream_sender_delegate_, NumBytesBuffered())
- .WillRepeatedly(Return(0));
- {
- spdy::Http2HeaderBlock header_list;
- header_list[":method"] = "GET";
- header_list["accept-encoding"] = "gzip, deflate, br";
- header_list["location"] = "";
-
- std::string output = Encode(header_list);
- EXPECT_EQ(absl::HexStringToBytes("0000d1dfcc"), output);
- }
- {
- spdy::Http2HeaderBlock header_list;
- header_list[":method"] = "POST";
- header_list["accept-encoding"] = "compress";
- header_list["location"] = "foo";
-
- std::string output = Encode(header_list);
- EXPECT_EQ(absl::HexStringToBytes("0000d45f108621e9aec2a11f5c8294e7"),
- output);
- }
- {
- spdy::Http2HeaderBlock header_list;
- header_list[":method"] = "TRACE";
- header_list["accept-encoding"] = "";
-
- std::string output = Encode(header_list);
- EXPECT_EQ(absl::HexStringToBytes("00005f000554524143455f1000"), output);
- }
-}
-
-TEST_F(QpackEncoderTest, DecoderStreamError) {
- EXPECT_CALL(decoder_stream_error_delegate_,
- OnDecoderStreamError(QUIC_QPACK_DECODER_STREAM_INTEGER_TOO_LARGE,
- Eq("Encoded integer too large.")));
-
- QpackEncoder encoder(&decoder_stream_error_delegate_);
- encoder.set_qpack_stream_sender_delegate(&encoder_stream_sender_delegate_);
- encoder.decoder_stream_receiver()->Decode(
- absl::HexStringToBytes("ffffffffffffffffffffff"));
-}
-
-TEST_F(QpackEncoderTest, SplitAlongNullCharacter) {
- EXPECT_CALL(encoder_stream_sender_delegate_, NumBytesBuffered())
- .WillRepeatedly(Return(0));
- spdy::Http2HeaderBlock header_list;
- header_list["foo"] = absl::string_view("bar\0bar\0baz", 11);
- std::string output = Encode(header_list);
-
- EXPECT_EQ(absl::HexStringToBytes("0000" // prefix
- "2a94e703626172" // foo: bar
- "2a94e703626172" // foo: bar
- "2a94e70362617a" // foo: baz
- ),
- output);
-}
-
-TEST_F(QpackEncoderTest, ZeroInsertCountIncrement) {
- // Encoder receives insert count increment with forbidden value 0.
- EXPECT_CALL(
- decoder_stream_error_delegate_,
- OnDecoderStreamError(QUIC_QPACK_DECODER_STREAM_INVALID_ZERO_INCREMENT,
- Eq("Invalid increment value 0.")));
- encoder_.OnInsertCountIncrement(0);
-}
-
-TEST_F(QpackEncoderTest, TooLargeInsertCountIncrement) {
- // Encoder receives insert count increment with value that increases Known
- // Received Count to a value (one) which is larger than the number of dynamic
- // table insertions sent (zero).
- EXPECT_CALL(
- decoder_stream_error_delegate_,
- OnDecoderStreamError(QUIC_QPACK_DECODER_STREAM_IMPOSSIBLE_INSERT_COUNT,
- Eq("Increment value 1 raises known received count "
- "to 1 exceeding inserted entry count 0")));
- encoder_.OnInsertCountIncrement(1);
-}
-
-// Regression test for https://crbug.com/1014372.
-TEST_F(QpackEncoderTest, InsertCountIncrementOverflow) {
- QpackEncoderHeaderTable* header_table =
- QpackEncoderPeer::header_table(&encoder_);
-
- // Set dynamic table capacity large enough to hold one entry.
- header_table->SetMaximumDynamicTableCapacity(4096);
- header_table->SetDynamicTableCapacity(4096);
- // Insert one entry into the header table.
- header_table->InsertEntry("foo", "bar");
-
- // Receive Insert Count Increment instruction with increment value 1.
- encoder_.OnInsertCountIncrement(1);
-
- // Receive Insert Count Increment instruction that overflows the known
- // received count. This must result in an error instead of a crash.
- EXPECT_CALL(decoder_stream_error_delegate_,
- OnDecoderStreamError(
- QUIC_QPACK_DECODER_STREAM_INCREMENT_OVERFLOW,
- Eq("Insert Count Increment instruction causes overflow.")));
- encoder_.OnInsertCountIncrement(std::numeric_limits<uint64_t>::max());
-}
-
-TEST_F(QpackEncoderTest, InvalidHeaderAcknowledgement) {
- // Encoder receives header acknowledgement for a stream on which no header
- // block with dynamic table entries was ever sent.
- EXPECT_CALL(
- decoder_stream_error_delegate_,
- OnDecoderStreamError(QUIC_QPACK_DECODER_STREAM_INCORRECT_ACKNOWLEDGEMENT,
- Eq("Header Acknowledgement received for stream 0 "
- "with no outstanding header blocks.")));
- encoder_.OnHeaderAcknowledgement(/* stream_id = */ 0);
-}
-
-TEST_F(QpackEncoderTest, DynamicTable) {
- EXPECT_CALL(encoder_stream_sender_delegate_, NumBytesBuffered())
- .WillRepeatedly(Return(0));
- encoder_.SetMaximumBlockedStreams(1);
- encoder_.SetMaximumDynamicTableCapacity(4096);
- encoder_.SetDynamicTableCapacity(4096);
-
- spdy::Http2HeaderBlock header_list;
- header_list["foo"] = "bar";
- header_list.AppendValueOrAddHeader("foo",
- "baz"); // name matches dynamic entry
- header_list["cookie"] = "baz"; // name matches static entry
-
- // Set Dynamic Table Capacity instruction.
- std::string set_dyanamic_table_capacity = absl::HexStringToBytes("3fe11f");
- // Insert three entries into the dynamic table.
- std::string insert_entries = absl::HexStringToBytes(
- "62" // insert without name reference
- "94e7" // Huffman-encoded name "foo"
- "03626172" // value "bar"
- "80" // insert with name reference, dynamic index 0
- "0362617a" // value "baz"
- "c5" // insert with name reference, static index 5
- "0362617a"); // value "baz"
- EXPECT_CALL(encoder_stream_sender_delegate_,
- WriteStreamData(Eq(
- absl::StrCat(set_dyanamic_table_capacity, insert_entries))));
-
- EXPECT_EQ(absl::HexStringToBytes(
- "0400" // prefix
- "828180"), // dynamic entries with relative index 0, 1, and 2
- Encode(header_list));
-
- EXPECT_EQ(insert_entries.size(), encoder_stream_sent_byte_count_);
-}
-
-// There is no room in the dynamic table after inserting the first entry.
-TEST_F(QpackEncoderTest, SmallDynamicTable) {
- EXPECT_CALL(encoder_stream_sender_delegate_, NumBytesBuffered())
- .WillRepeatedly(Return(0));
- encoder_.SetMaximumBlockedStreams(1);
- encoder_.SetMaximumDynamicTableCapacity(QpackEntry::Size("foo", "bar"));
- encoder_.SetDynamicTableCapacity(QpackEntry::Size("foo", "bar"));
-
- spdy::Http2HeaderBlock header_list;
- header_list["foo"] = "bar";
- header_list.AppendValueOrAddHeader("foo",
- "baz"); // name matches dynamic entry
- header_list["cookie"] = "baz"; // name matches static entry
- header_list["bar"] = "baz"; // no match
-
- // Set Dynamic Table Capacity instruction.
- std::string set_dyanamic_table_capacity = absl::HexStringToBytes("3f07");
- // Insert one entry into the dynamic table.
- std::string insert_entry = absl::HexStringToBytes(
- "62" // insert without name reference
- "94e7" // Huffman-encoded name "foo"
- "03626172"); // value "bar"
- EXPECT_CALL(encoder_stream_sender_delegate_,
- WriteStreamData(
- Eq(absl::StrCat(set_dyanamic_table_capacity, insert_entry))));
-
- EXPECT_EQ(absl::HexStringToBytes("0200" // prefix
- "80" // dynamic entry 0
- "40" // reference to dynamic entry 0 name
- "0362617a" // with literal value "baz"
- "55" // reference to static entry 5 name
- "0362617a" // with literal value "baz"
- "23626172" // literal name "bar"
- "0362617a"), // with literal value "baz"
- Encode(header_list));
-
- EXPECT_EQ(insert_entry.size(), encoder_stream_sent_byte_count_);
-}
-
-TEST_F(QpackEncoderTest, BlockedStream) {
- EXPECT_CALL(encoder_stream_sender_delegate_, NumBytesBuffered())
- .WillRepeatedly(Return(0));
- encoder_.SetMaximumBlockedStreams(1);
- encoder_.SetMaximumDynamicTableCapacity(4096);
- encoder_.SetDynamicTableCapacity(4096);
-
- spdy::Http2HeaderBlock header_list1;
- header_list1["foo"] = "bar";
-
- // Set Dynamic Table Capacity instruction.
- std::string set_dyanamic_table_capacity = absl::HexStringToBytes("3fe11f");
- // Insert one entry into the dynamic table.
- std::string insert_entry1 = absl::HexStringToBytes(
- "62" // insert without name reference
- "94e7" // Huffman-encoded name "foo"
- "03626172"); // value "bar"
- EXPECT_CALL(encoder_stream_sender_delegate_,
- WriteStreamData(Eq(
- absl::StrCat(set_dyanamic_table_capacity, insert_entry1))));
-
- EXPECT_EQ(absl::HexStringToBytes("0200" // prefix
- "80"), // dynamic entry 0
- encoder_.EncodeHeaderList(/* stream_id = */ 1, header_list1,
- &encoder_stream_sent_byte_count_));
- EXPECT_EQ(insert_entry1.size(), encoder_stream_sent_byte_count_);
-
- // Stream 1 is blocked. Stream 2 is not allowed to block.
- spdy::Http2HeaderBlock header_list2;
- header_list2["foo"] = "bar"; // name and value match dynamic entry
- header_list2.AppendValueOrAddHeader("foo",
- "baz"); // name matches dynamic entry
- header_list2["cookie"] = "baz"; // name matches static entry
- header_list2["bar"] = "baz"; // no match
-
- EXPECT_EQ(absl::HexStringToBytes("0000" // prefix
- "2a94e7" // literal name "foo"
- "03626172" // with literal value "bar"
- "2a94e7" // literal name "foo"
- "0362617a" // with literal value "baz"
- "55" // name of static entry 5
- "0362617a" // with literal value "baz"
- "23626172" // literal name "bar"
- "0362617a"), // with literal value "baz"
- encoder_.EncodeHeaderList(/* stream_id = */ 2, header_list2,
- &encoder_stream_sent_byte_count_));
- EXPECT_EQ(0u, encoder_stream_sent_byte_count_);
-
- // Peer acknowledges receipt of one dynamic table entry.
- // Stream 1 is no longer blocked.
- encoder_.OnInsertCountIncrement(1);
-
- // Insert three entries into the dynamic table.
- std::string insert_entries = absl::HexStringToBytes(
- "80" // insert with name reference, dynamic index 0
- "0362617a" // value "baz"
- "c5" // insert with name reference, static index 5
- "0362617a" // value "baz"
- "43" // insert without name reference
- "626172" // name "bar"
- "0362617a"); // value "baz"
- EXPECT_CALL(encoder_stream_sender_delegate_,
- WriteStreamData(Eq(insert_entries)));
-
- EXPECT_EQ(absl::HexStringToBytes("0500" // prefix
- "83828180"), // dynamic entries
- encoder_.EncodeHeaderList(/* stream_id = */ 3, header_list2,
- &encoder_stream_sent_byte_count_));
- EXPECT_EQ(insert_entries.size(), encoder_stream_sent_byte_count_);
-
- // Stream 3 is blocked. Stream 4 is not allowed to block, but it can
- // reference already acknowledged dynamic entry 0.
- EXPECT_EQ(absl::HexStringToBytes("0200" // prefix
- "80" // dynamic entry 0
- "2a94e7" // literal name "foo"
- "0362617a" // with literal value "baz"
- "2c21cfd4c5" // literal name "cookie"
- "0362617a" // with literal value "baz"
- "23626172" // literal name "bar"
- "0362617a"), // with literal value "baz"
- encoder_.EncodeHeaderList(/* stream_id = */ 4, header_list2,
- &encoder_stream_sent_byte_count_));
- EXPECT_EQ(0u, encoder_stream_sent_byte_count_);
-
- // Peer acknowledges receipt of two more dynamic table entries.
- // Stream 3 is still blocked.
- encoder_.OnInsertCountIncrement(2);
-
- // Stream 5 is not allowed to block, but it can reference already acknowledged
- // dynamic entries 0, 1, and 2.
- EXPECT_EQ(absl::HexStringToBytes("0400" // prefix
- "828180" // dynamic entries
- "23626172" // literal name "bar"
- "0362617a"), // with literal value "baz"
- encoder_.EncodeHeaderList(/* stream_id = */ 5, header_list2,
- &encoder_stream_sent_byte_count_));
- EXPECT_EQ(0u, encoder_stream_sent_byte_count_);
-
- // Peer acknowledges decoding header block on stream 3.
- // Stream 3 is not blocked any longer.
- encoder_.OnHeaderAcknowledgement(3);
-
- EXPECT_EQ(absl::HexStringToBytes("0500" // prefix
- "83828180"), // dynamic entries
- encoder_.EncodeHeaderList(/* stream_id = */ 6, header_list2,
- &encoder_stream_sent_byte_count_));
- EXPECT_EQ(0u, encoder_stream_sent_byte_count_);
-}
-
-TEST_F(QpackEncoderTest, Draining) {
- EXPECT_CALL(encoder_stream_sender_delegate_, NumBytesBuffered())
- .WillRepeatedly(Return(0));
- spdy::Http2HeaderBlock header_list1;
- header_list1["one"] = "foo";
- header_list1["two"] = "foo";
- header_list1["three"] = "foo";
- header_list1["four"] = "foo";
- header_list1["five"] = "foo";
- header_list1["six"] = "foo";
- header_list1["seven"] = "foo";
- header_list1["eight"] = "foo";
- header_list1["nine"] = "foo";
- header_list1["ten"] = "foo";
-
- // Make just enough room in the dynamic table for the header list plus the
- // first entry duplicated. This will ensure that the oldest entries are
- // draining.
- uint64_t maximum_dynamic_table_capacity = 0;
- for (const auto& header_field : header_list1) {
- maximum_dynamic_table_capacity +=
- QpackEntry::Size(header_field.first, header_field.second);
- }
- maximum_dynamic_table_capacity += QpackEntry::Size("one", "foo");
- encoder_.SetMaximumDynamicTableCapacity(maximum_dynamic_table_capacity);
- encoder_.SetDynamicTableCapacity(maximum_dynamic_table_capacity);
-
- // Set Dynamic Table Capacity instruction and insert ten entries into the
- // dynamic table.
- EXPECT_CALL(encoder_stream_sender_delegate_, WriteStreamData(_));
-
- EXPECT_EQ(absl::HexStringToBytes("0b00" // prefix
- "89888786858483828180"), // dynamic entries
- Encode(header_list1));
-
- // Entry is identical to oldest one, which is draining. It will be
- // duplicated and referenced.
- spdy::Http2HeaderBlock header_list2;
- header_list2["one"] = "foo";
-
- // Duplicate oldest entry.
- EXPECT_CALL(encoder_stream_sender_delegate_,
- WriteStreamData(Eq(absl::HexStringToBytes("09"))));
-
- EXPECT_EQ(absl::HexStringToBytes("0c00" // prefix
- "80"), // most recent dynamic table entry
- Encode(header_list2));
-
- spdy::Http2HeaderBlock header_list3;
- // Entry is identical to second oldest one, which is draining. There is no
- // room to duplicate, it will be encoded with string literals.
- header_list3.AppendValueOrAddHeader("two", "foo");
- // Entry has name identical to second oldest one, which is draining. There is
- // no room to insert new entry, it will be encoded with string literals.
- header_list3.AppendValueOrAddHeader("two", "bar");
-
- EXPECT_EQ(absl::HexStringToBytes("0000" // prefix
- "2374776f" // literal name "two"
- "8294e7" // literal value "foo"
- "2374776f" // literal name "two"
- "03626172"), // literal value "bar"
- Encode(header_list3));
-}
-
-TEST_F(QpackEncoderTest, DynamicTableCapacityLessThanMaximum) {
- encoder_.SetMaximumDynamicTableCapacity(1024);
- encoder_.SetDynamicTableCapacity(30);
-
- QpackEncoderHeaderTable* header_table =
- QpackEncoderPeer::header_table(&encoder_);
-
- EXPECT_EQ(1024u, header_table->maximum_dynamic_table_capacity());
- EXPECT_EQ(30u, header_table->dynamic_table_capacity());
-}
-
-TEST_F(QpackEncoderTest, EncoderStreamWritesDisallowedThenAllowed) {
- if (!GetQuicReloadableFlag(quic_limit_encoder_stream_buffering)) {
- return;
- }
-
- EXPECT_CALL(encoder_stream_sender_delegate_, NumBytesBuffered())
- .WillRepeatedly(Return(kTooManyBytesBuffered));
- encoder_.SetMaximumBlockedStreams(1);
- encoder_.SetMaximumDynamicTableCapacity(4096);
- encoder_.SetDynamicTableCapacity(4096);
-
- spdy::Http2HeaderBlock header_list1;
- header_list1["foo"] = "bar";
- header_list1.AppendValueOrAddHeader("foo", "baz");
- header_list1["cookie"] = "baz"; // name matches static entry
-
- // Encoder is not allowed to write on the encoder stream.
- // No Set Dynamic Table Capacity or Insert instructions are sent.
- // Headers are encoded as string literals.
- EXPECT_EQ(absl::HexStringToBytes("0000" // prefix
- "2a94e7" // literal name "foo"
- "03626172" // with literal value "bar"
- "2a94e7" // literal name "foo"
- "0362617a" // with literal value "baz"
- "55" // name of static entry 5
- "0362617a"), // with literal value "baz"
- Encode(header_list1));
-
- EXPECT_EQ(0u, encoder_stream_sent_byte_count_);
-
- // If number of bytes buffered by encoder stream goes under the threshold,
- // then QpackEncoder will resume emitting encoder stream instructions.
- ::testing::Mock::VerifyAndClearExpectations(&encoder_stream_sender_delegate_);
- EXPECT_CALL(encoder_stream_sender_delegate_, NumBytesBuffered())
- .WillRepeatedly(Return(0));
-
- spdy::Http2HeaderBlock header_list2;
- header_list2["foo"] = "bar";
- header_list2.AppendValueOrAddHeader("foo",
- "baz"); // name matches dynamic entry
- header_list2["cookie"] = "baz"; // name matches static entry
-
- // Set Dynamic Table Capacity instruction.
- std::string set_dyanamic_table_capacity = absl::HexStringToBytes("3fe11f");
- // Insert three entries into the dynamic table.
- std::string insert_entries = absl::HexStringToBytes(
- "62" // insert without name reference
- "94e7" // Huffman-encoded name "foo"
- "03626172" // value "bar"
- "80" // insert with name reference, dynamic index 0
- "0362617a" // value "baz"
- "c5" // insert with name reference, static index 5
- "0362617a"); // value "baz"
- EXPECT_CALL(encoder_stream_sender_delegate_,
- WriteStreamData(Eq(
- absl::StrCat(set_dyanamic_table_capacity, insert_entries))));
-
- EXPECT_EQ(absl::HexStringToBytes(
- "0400" // prefix
- "828180"), // dynamic entries with relative index 0, 1, and 2
- Encode(header_list2));
-
- EXPECT_EQ(insert_entries.size(), encoder_stream_sent_byte_count_);
-}
-
-TEST_F(QpackEncoderTest, EncoderStreamWritesAllowedThenDisallowed) {
- if (!GetQuicReloadableFlag(quic_limit_encoder_stream_buffering)) {
- return;
- }
-
- EXPECT_CALL(encoder_stream_sender_delegate_, NumBytesBuffered())
- .WillRepeatedly(Return(0));
- encoder_.SetMaximumBlockedStreams(1);
- encoder_.SetMaximumDynamicTableCapacity(4096);
- encoder_.SetDynamicTableCapacity(4096);
-
- spdy::Http2HeaderBlock header_list1;
- header_list1["foo"] = "bar";
- header_list1.AppendValueOrAddHeader("foo",
- "baz"); // name matches dynamic entry
- header_list1["cookie"] = "baz"; // name matches static entry
-
- // Set Dynamic Table Capacity instruction.
- std::string set_dyanamic_table_capacity = absl::HexStringToBytes("3fe11f");
- // Insert three entries into the dynamic table.
- std::string insert_entries = absl::HexStringToBytes(
- "62" // insert without name reference
- "94e7" // Huffman-encoded name "foo"
- "03626172" // value "bar"
- "80" // insert with name reference, dynamic index 0
- "0362617a" // value "baz"
- "c5" // insert with name reference, static index 5
- "0362617a"); // value "baz"
- EXPECT_CALL(encoder_stream_sender_delegate_,
- WriteStreamData(Eq(
- absl::StrCat(set_dyanamic_table_capacity, insert_entries))));
-
- EXPECT_EQ(absl::HexStringToBytes(
- "0400" // prefix
- "828180"), // dynamic entries with relative index 0, 1, and 2
- Encode(header_list1));
-
- EXPECT_EQ(insert_entries.size(), encoder_stream_sent_byte_count_);
-
- // If number of bytes buffered by encoder stream goes over the threshold,
- // then QpackEncoder will stop emitting encoder stream instructions.
- ::testing::Mock::VerifyAndClearExpectations(&encoder_stream_sender_delegate_);
- EXPECT_CALL(encoder_stream_sender_delegate_, NumBytesBuffered())
- .WillRepeatedly(Return(kTooManyBytesBuffered));
-
- spdy::Http2HeaderBlock header_list2;
- header_list2["foo"] = "bar"; // matches previously inserted dynamic entry
- header_list2["bar"] = "baz";
- header_list2["cookie"] = "baz"; // name matches static entry
-
- // Encoder is not allowed to write on the encoder stream.
- // No Set Dynamic Table Capacity or Insert instructions are sent.
- // Headers are encoded as string literals.
- EXPECT_EQ(
- absl::HexStringToBytes("0400" // prefix
- "82" // dynamic entry with relative index 0
- "23626172" // literal name "bar"
- "0362617a" // with literal value "baz"
- "80"), // dynamic entry with relative index 2
- Encode(header_list2));
-
- EXPECT_EQ(0u, encoder_stream_sent_byte_count_);
-}
-
-} // namespace
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_header_table.cc b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_header_table.cc
deleted file mode 100644
index 660727231d6..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_header_table.cc
+++ /dev/null
@@ -1,240 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/qpack/qpack_header_table.h"
-
-#include "absl/strings/string_view.h"
-#include "quic/core/qpack/qpack_static_table.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-QpackEncoderHeaderTable::QpackEncoderHeaderTable()
- : static_index_(ObtainQpackStaticTable().GetStaticIndex()),
- static_name_index_(ObtainQpackStaticTable().GetStaticNameIndex()) {}
-
-uint64_t QpackEncoderHeaderTable::InsertEntry(absl::string_view name,
- absl::string_view value) {
- const uint64_t index =
- QpackHeaderTableBase<QpackEncoderDynamicTable>::InsertEntry(name, value);
-
- // Make name and value point to the new entry.
- name = dynamic_entries().back().name();
- value = dynamic_entries().back().value();
-
- auto index_result = dynamic_index_.insert(
- std::make_pair(QpackLookupEntry{name, value}, index));
- if (!index_result.second) {
- // An entry with the same name and value already exists. It needs to be
- // replaced, because |dynamic_index_| tracks the most recent entry for a
- // given name and value.
- QUICHE_DCHECK_GT(index, index_result.first->second);
- dynamic_index_.erase(index_result.first);
- auto result = dynamic_index_.insert(
- std::make_pair(QpackLookupEntry{name, value}, index));
- QUICHE_CHECK(result.second);
- }
-
- auto name_result = dynamic_name_index_.insert({name, index});
- if (!name_result.second) {
- // An entry with the same name already exists. It needs to be replaced,
- // because |dynamic_name_index_| tracks the most recent entry for a given
- // name.
- QUICHE_DCHECK_GT(index, name_result.first->second);
- dynamic_name_index_.erase(name_result.first);
- auto result = dynamic_name_index_.insert({name, index});
- QUICHE_CHECK(result.second);
- }
-
- return index;
-}
-
-QpackEncoderHeaderTable::MatchType QpackEncoderHeaderTable::FindHeaderField(
- absl::string_view name,
- absl::string_view value,
- bool* is_static,
- uint64_t* index) const {
- QpackLookupEntry query{name, value};
-
- // Look for exact match in static table.
- auto index_it = static_index_.find(query);
- if (index_it != static_index_.end()) {
- *index = index_it->second;
- *is_static = true;
- return MatchType::kNameAndValue;
- }
-
- // Look for exact match in dynamic table.
- index_it = dynamic_index_.find(query);
- if (index_it != dynamic_index_.end()) {
- *index = index_it->second;
- *is_static = false;
- return MatchType::kNameAndValue;
- }
-
- // Look for name match in static table.
- auto name_index_it = static_name_index_.find(name);
- if (name_index_it != static_name_index_.end()) {
- *index = name_index_it->second;
- *is_static = true;
- return MatchType::kName;
- }
-
- // Look for name match in dynamic table.
- name_index_it = dynamic_name_index_.find(name);
- if (name_index_it != dynamic_name_index_.end()) {
- *index = name_index_it->second;
- *is_static = false;
- return MatchType::kName;
- }
-
- return MatchType::kNoMatch;
-}
-
-uint64_t QpackEncoderHeaderTable::MaxInsertSizeWithoutEvictingGivenEntry(
- uint64_t index) const {
- QUICHE_DCHECK_LE(dropped_entry_count(), index);
-
- if (index > inserted_entry_count()) {
- // All entries are allowed to be evicted.
- return dynamic_table_capacity();
- }
-
- // Initialize to current available capacity.
- uint64_t max_insert_size = dynamic_table_capacity() - dynamic_table_size();
-
- uint64_t entry_index = dropped_entry_count();
- for (const auto& entry : dynamic_entries()) {
- if (entry_index >= index) {
- break;
- }
- ++entry_index;
- max_insert_size += entry.Size();
- }
-
- return max_insert_size;
-}
-
-uint64_t QpackEncoderHeaderTable::draining_index(
- float draining_fraction) const {
- QUICHE_DCHECK_LE(0.0, draining_fraction);
- QUICHE_DCHECK_LE(draining_fraction, 1.0);
-
- const uint64_t required_space = draining_fraction * dynamic_table_capacity();
- uint64_t space_above_draining_index =
- dynamic_table_capacity() - dynamic_table_size();
-
- if (dynamic_entries().empty() ||
- space_above_draining_index >= required_space) {
- return dropped_entry_count();
- }
-
- auto it = dynamic_entries().begin();
- uint64_t entry_index = dropped_entry_count();
- while (space_above_draining_index < required_space) {
- space_above_draining_index += it->Size();
- ++it;
- ++entry_index;
- if (it == dynamic_entries().end()) {
- return inserted_entry_count();
- }
- }
-
- return entry_index;
-}
-
-void QpackEncoderHeaderTable::RemoveEntryFromEnd() {
- const QpackEntry* const entry = &dynamic_entries().front();
- const uint64_t index = dropped_entry_count();
-
- auto index_it = dynamic_index_.find({entry->name(), entry->value()});
- // Remove |dynamic_index_| entry only if it points to the same
- // QpackEntry in dynamic_entries().
- if (index_it != dynamic_index_.end() && index_it->second == index) {
- dynamic_index_.erase(index_it);
- }
-
- auto name_it = dynamic_name_index_.find(entry->name());
- // Remove |dynamic_name_index_| entry only if it points to the same
- // QpackEntry in dynamic_entries().
- if (name_it != dynamic_name_index_.end() && name_it->second == index) {
- dynamic_name_index_.erase(name_it);
- }
-
- QpackHeaderTableBase<QpackEncoderDynamicTable>::RemoveEntryFromEnd();
-}
-
-QpackDecoderHeaderTable::QpackDecoderHeaderTable()
- : static_entries_(ObtainQpackStaticTable().GetStaticEntries()) {}
-
-QpackDecoderHeaderTable::~QpackDecoderHeaderTable() {
- for (auto& entry : observers_) {
- entry.second->Cancel();
- }
-}
-
-uint64_t QpackDecoderHeaderTable::InsertEntry(absl::string_view name,
- absl::string_view value) {
- const uint64_t index =
- QpackHeaderTableBase<QpackDecoderDynamicTable>::InsertEntry(name, value);
-
- // Notify and deregister observers whose threshold is met, if any.
- while (!observers_.empty()) {
- auto it = observers_.begin();
- if (it->first > inserted_entry_count()) {
- break;
- }
- Observer* observer = it->second;
- observers_.erase(it);
- observer->OnInsertCountReachedThreshold();
- }
-
- return index;
-}
-
-const QpackEntry* QpackDecoderHeaderTable::LookupEntry(bool is_static,
- uint64_t index) const {
- if (is_static) {
- if (index >= static_entries_.size()) {
- return nullptr;
- }
-
- return &static_entries_[index];
- }
-
- if (index < dropped_entry_count()) {
- return nullptr;
- }
-
- index -= dropped_entry_count();
-
- if (index >= dynamic_entries().size()) {
- return nullptr;
- }
-
- return &dynamic_entries()[index];
-}
-
-void QpackDecoderHeaderTable::RegisterObserver(uint64_t required_insert_count,
- Observer* observer) {
- QUICHE_DCHECK_GT(required_insert_count, 0u);
- observers_.insert({required_insert_count, observer});
-}
-
-void QpackDecoderHeaderTable::UnregisterObserver(uint64_t required_insert_count,
- Observer* observer) {
- auto it = observers_.lower_bound(required_insert_count);
- while (it != observers_.end() && it->first == required_insert_count) {
- if (it->second == observer) {
- observers_.erase(it);
- return;
- }
- ++it;
- }
-
- // |observer| must have been registered.
- QUIC_NOTREACHED();
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_header_table.h b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_header_table.h
deleted file mode 100644
index 7193d102294..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_header_table.h
+++ /dev/null
@@ -1,346 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QPACK_QPACK_HEADER_TABLE_H_
-#define QUICHE_QUIC_CORE_QPACK_QPACK_HEADER_TABLE_H_
-
-#include <cstdint>
-#include <deque>
-
-#include "absl/strings/string_view.h"
-#include "quic/platform/api/quic_export.h"
-#include "common/quiche_circular_deque.h"
-#include "spdy/core/hpack/hpack_entry.h"
-#include "spdy/core/hpack/hpack_header_table.h"
-
-namespace quic {
-
-using QpackEntry = spdy::HpackEntry;
-using QpackLookupEntry = spdy::HpackLookupEntry;
-constexpr size_t kQpackEntrySizeOverhead = spdy::kHpackEntrySizeOverhead;
-
-// Encoder needs pointer stability for |dynamic_index_| and
-// |dynamic_name_index_|. However, it does not need random access.
-// TODO(b/182349990): Change to a more memory efficient container.
-using QpackEncoderDynamicTable = std::deque<QpackEntry>;
-
-// Decoder needs random access for LookupEntry().
-// However, it does not need pointer stability.
-using QpackDecoderDynamicTable = quiche::QuicheCircularDeque<QpackEntry>;
-
-// This is a base class for encoder and decoder classes that manage the QPACK
-// static and dynamic tables. For dynamic entries, it only has a concept of
-// absolute indices. The caller needs to perform the necessary transformations
-// to and from relative indices and post-base indices.
-template <typename DynamicEntryTable>
-class QUIC_EXPORT_PRIVATE QpackHeaderTableBase {
- public:
- QpackHeaderTableBase();
- QpackHeaderTableBase(const QpackHeaderTableBase&) = delete;
- QpackHeaderTableBase& operator=(const QpackHeaderTableBase&) = delete;
-
- virtual ~QpackHeaderTableBase() = default;
-
- // Returns whether an entry with |name| and |value| has a size (including
- // overhead) that is smaller than or equal to the capacity of the dynamic
- // table.
- bool EntryFitsDynamicTableCapacity(absl::string_view name,
- absl::string_view value) const;
-
- // Inserts (name, value) into the dynamic table. Entry must not be larger
- // than the capacity of the dynamic table. May evict entries. |name| and
- // |value| are copied first, therefore it is safe for them to point to an
- // entry in the dynamic table, even if it is about to be evicted, or even if
- // the underlying container might move entries around when resizing for
- // insertion.
- // Returns the absolute index of the inserted dynamic table entry.
- virtual uint64_t InsertEntry(absl::string_view name, absl::string_view value);
-
- // Change dynamic table capacity to |capacity|. Returns true on success.
- // Returns false is |capacity| exceeds maximum dynamic table capacity.
- bool SetDynamicTableCapacity(uint64_t capacity);
-
- // Set |maximum_dynamic_table_capacity_|. The initial value is zero. The
- // final value is determined by the decoder and is sent to the encoder as
- // SETTINGS_HEADER_TABLE_SIZE. Therefore in the decoding context the final
- // value can be set upon connection establishment, whereas in the encoding
- // context it can be set when the SETTINGS frame is received.
- // This method must only be called at most once.
- // Returns true if |maximum_dynamic_table_capacity| is set for the first time
- // or if it doesn't change current value. The setting is not changed when
- // returning false.
- bool SetMaximumDynamicTableCapacity(uint64_t maximum_dynamic_table_capacity);
-
- uint64_t dynamic_table_size() const { return dynamic_table_size_; }
- uint64_t dynamic_table_capacity() const { return dynamic_table_capacity_; }
- uint64_t maximum_dynamic_table_capacity() const {
- return maximum_dynamic_table_capacity_;
- }
- uint64_t max_entries() const { return max_entries_; }
-
- // The number of entries inserted to the dynamic table (including ones that
- // were dropped since). Used for relative indexing on the encoder stream.
- uint64_t inserted_entry_count() const {
- return dynamic_entries_.size() + dropped_entry_count_;
- }
-
- // The number of entries dropped from the dynamic table.
- uint64_t dropped_entry_count() const { return dropped_entry_count_; }
-
- void set_dynamic_table_entry_referenced() {
- dynamic_table_entry_referenced_ = true;
- }
- bool dynamic_table_entry_referenced() const {
- return dynamic_table_entry_referenced_;
- }
-
- protected:
- // Removes a single entry from the end of the dynamic table, updates
- // |dynamic_table_size_| and |dropped_entry_count_|.
- virtual void RemoveEntryFromEnd();
-
- const DynamicEntryTable& dynamic_entries() const { return dynamic_entries_; }
-
- private:
- // Evict entries from the dynamic table until table size is less than or equal
- // to |capacity|.
- void EvictDownToCapacity(uint64_t capacity);
-
- // Dynamic Table entries.
- DynamicEntryTable dynamic_entries_;
-
- // Size of the dynamic table. This is the sum of the size of its entries.
- uint64_t dynamic_table_size_;
-
- // Dynamic Table Capacity is the maximum allowed value of
- // |dynamic_table_size_|. Entries are evicted if necessary before inserting a
- // new entry to ensure that dynamic table size never exceeds capacity.
- // Initial value is |maximum_dynamic_table_capacity_|. Capacity can be
- // changed by the encoder, as long as it does not exceed
- // |maximum_dynamic_table_capacity_|.
- uint64_t dynamic_table_capacity_;
-
- // Maximum allowed value of |dynamic_table_capacity|. The initial value is
- // zero. Can be changed by SetMaximumDynamicTableCapacity().
- uint64_t maximum_dynamic_table_capacity_;
-
- // MaxEntries, see Section 3.2.2. Calculated based on
- // |maximum_dynamic_table_capacity_|. Used on request streams to encode and
- // decode Required Insert Count.
- uint64_t max_entries_;
-
- // The number of entries dropped from the dynamic table.
- uint64_t dropped_entry_count_;
-
- // True if any dynamic table entries have been referenced from a header block.
- // Set directly by the encoder or decoder. Used for stats.
- bool dynamic_table_entry_referenced_;
-};
-
-template <typename DynamicEntryTable>
-QpackHeaderTableBase<DynamicEntryTable>::QpackHeaderTableBase()
- : dynamic_table_size_(0),
- dynamic_table_capacity_(0),
- maximum_dynamic_table_capacity_(0),
- max_entries_(0),
- dropped_entry_count_(0),
- dynamic_table_entry_referenced_(false) {}
-
-template <typename DynamicEntryTable>
-bool QpackHeaderTableBase<DynamicEntryTable>::EntryFitsDynamicTableCapacity(
- absl::string_view name,
- absl::string_view value) const {
- return QpackEntry::Size(name, value) <= dynamic_table_capacity_;
-}
-
-template <typename DynamicEntryTable>
-uint64_t QpackHeaderTableBase<DynamicEntryTable>::InsertEntry(
- absl::string_view name,
- absl::string_view value) {
- QUICHE_DCHECK(EntryFitsDynamicTableCapacity(name, value));
-
- const uint64_t index = dropped_entry_count_ + dynamic_entries_.size();
-
- // Copy name and value before modifying the container, because evicting
- // entries or even inserting a new one might invalidate |name| or |value| if
- // they point to an entry.
- QpackEntry new_entry((std::string(name)), (std::string(value)));
- const size_t entry_size = new_entry.Size();
-
- EvictDownToCapacity(dynamic_table_capacity_ - entry_size);
-
- dynamic_table_size_ += entry_size;
- dynamic_entries_.push_back(std::move(new_entry));
-
- return index;
-}
-
-template <typename DynamicEntryTable>
-bool QpackHeaderTableBase<DynamicEntryTable>::SetDynamicTableCapacity(
- uint64_t capacity) {
- if (capacity > maximum_dynamic_table_capacity_) {
- return false;
- }
-
- dynamic_table_capacity_ = capacity;
- EvictDownToCapacity(capacity);
-
- QUICHE_DCHECK_LE(dynamic_table_size_, dynamic_table_capacity_);
-
- return true;
-}
-
-template <typename DynamicEntryTable>
-bool QpackHeaderTableBase<DynamicEntryTable>::SetMaximumDynamicTableCapacity(
- uint64_t maximum_dynamic_table_capacity) {
- if (maximum_dynamic_table_capacity_ == 0) {
- maximum_dynamic_table_capacity_ = maximum_dynamic_table_capacity;
- max_entries_ = maximum_dynamic_table_capacity / 32;
- return true;
- }
- // If the value is already set, it should not be changed.
- return maximum_dynamic_table_capacity == maximum_dynamic_table_capacity_;
-}
-
-template <typename DynamicEntryTable>
-void QpackHeaderTableBase<DynamicEntryTable>::RemoveEntryFromEnd() {
- const uint64_t entry_size = dynamic_entries_.front().Size();
- QUICHE_DCHECK_GE(dynamic_table_size_, entry_size);
- dynamic_table_size_ -= entry_size;
-
- dynamic_entries_.pop_front();
- ++dropped_entry_count_;
-}
-
-template <typename DynamicEntryTable>
-void QpackHeaderTableBase<DynamicEntryTable>::EvictDownToCapacity(
- uint64_t capacity) {
- while (dynamic_table_size_ > capacity) {
- QUICHE_DCHECK(!dynamic_entries_.empty());
- RemoveEntryFromEnd();
- }
-}
-
-class QUIC_EXPORT_PRIVATE QpackEncoderHeaderTable
- : public QpackHeaderTableBase<QpackEncoderDynamicTable> {
- public:
- // Result of header table lookup.
- enum class MatchType { kNameAndValue, kName, kNoMatch };
-
- QpackEncoderHeaderTable();
- ~QpackEncoderHeaderTable() override = default;
-
- uint64_t InsertEntry(absl::string_view name,
- absl::string_view value) override;
-
- // Returns the absolute index of an entry with matching name and value if such
- // exists, otherwise one with matching name is such exists. |index| is zero
- // based for both the static and the dynamic table.
- MatchType FindHeaderField(absl::string_view name,
- absl::string_view value,
- bool* is_static,
- uint64_t* index) const;
-
- // Returns the size of the largest entry that could be inserted into the
- // dynamic table without evicting entry |index|. |index| might be larger than
- // inserted_entry_count(), in which case the capacity of the table is
- // returned. |index| must not be smaller than dropped_entry_count().
- uint64_t MaxInsertSizeWithoutEvictingGivenEntry(uint64_t index) const;
-
- // Returns the draining index described at
- // https://quicwg.org/base-drafts/draft-ietf-quic-qpack.html#avoiding-blocked-insertions.
- // Entries with an index larger than or equal to the draining index take up
- // approximately |1.0 - draining_fraction| of dynamic table capacity. The
- // remaining capacity is taken up by draining entries and unused space.
- // The returned index might not be the index of a valid entry.
- uint64_t draining_index(float draining_fraction) const;
-
- protected:
- void RemoveEntryFromEnd() override;
-
- private:
- using NameValueToEntryMap = spdy::HpackHeaderTable::NameValueToEntryMap;
- using NameToEntryMap = spdy::HpackHeaderTable::NameToEntryMap;
-
- // Static Table
-
- // |static_index_| and |static_name_index_| are owned by QpackStaticTable
- // singleton.
-
- // Tracks the unique static entry for a given header name and value.
- const NameValueToEntryMap& static_index_;
-
- // Tracks the first static entry for a given header name.
- const NameToEntryMap& static_name_index_;
-
- // Dynamic Table
-
- // An unordered set of QpackEntry pointers with a comparison operator that
- // only cares about name and value. This allows fast lookup of the most
- // recently inserted dynamic entry for a given header name and value pair.
- // Entries point to entries owned by |QpackHeaderTableBase::dynamic_entries_|.
- NameValueToEntryMap dynamic_index_;
-
- // An unordered map of QpackEntry pointers keyed off header name. This allows
- // fast lookup of the most recently inserted dynamic entry for a given header
- // name. Entries point to entries owned by
- // |QpackHeaderTableBase::dynamic_entries_|.
- NameToEntryMap dynamic_name_index_;
-};
-
-class QUIC_EXPORT_PRIVATE QpackDecoderHeaderTable
- : public QpackHeaderTableBase<QpackDecoderDynamicTable> {
- public:
- // Observer interface for dynamic table insertion.
- class QUIC_EXPORT_PRIVATE Observer {
- public:
- virtual ~Observer() = default;
-
- // Called when inserted_entry_count() reaches the threshold the Observer was
- // registered with. After this call the Observer automatically gets
- // deregistered.
- virtual void OnInsertCountReachedThreshold() = 0;
-
- // Called when QpackDecoderHeaderTable is destroyed to let the Observer know
- // that it must not call UnregisterObserver().
- virtual void Cancel() = 0;
- };
-
- QpackDecoderHeaderTable();
- ~QpackDecoderHeaderTable() override;
-
- uint64_t InsertEntry(absl::string_view name,
- absl::string_view value) override;
-
- // Returns the entry at absolute index |index| from the static or dynamic
- // table according to |is_static|. |index| is zero based for both the static
- // and the dynamic table. The returned pointer is valid until the entry is
- // evicted, even if other entries are inserted into the dynamic table.
- // Returns nullptr if entry does not exist.
- const QpackEntry* LookupEntry(bool is_static, uint64_t index) const;
-
- // Register an observer to be notified when inserted_entry_count() reaches
- // |required_insert_count|. After the notification, |observer| automatically
- // gets unregistered. Each observer must only be registered at most once.
- void RegisterObserver(uint64_t required_insert_count, Observer* observer);
-
- // Unregister previously registered observer. Must be called with the same
- // |required_insert_count| value that |observer| was registered with. Must be
- // called before an observer still waiting for notification is destroyed,
- // unless QpackDecoderHeaderTable already called Observer::Cancel(), in which
- // case this method must not be called.
- void UnregisterObserver(uint64_t required_insert_count, Observer* observer);
-
- private:
- // Static Table entries. Owned by QpackStaticTable singleton.
- using StaticEntryTable = spdy::HpackHeaderTable::StaticEntryTable;
- const StaticEntryTable& static_entries_;
-
- // Observers waiting to be notified, sorted by required insert count.
- std::multimap<uint64_t, Observer*> observers_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_QPACK_QPACK_HEADER_TABLE_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_header_table_test.cc b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_header_table_test.cc
deleted file mode 100644
index 4a1e39c2325..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_header_table_test.cc
+++ /dev/null
@@ -1,655 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/qpack/qpack_header_table.h"
-
-#include <utility>
-
-#include "absl/base/macros.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/qpack/qpack_static_table.h"
-#include "quic/platform/api/quic_test.h"
-#include "spdy/core/hpack/hpack_entry.h"
-
-using ::testing::Mock;
-using ::testing::StrictMock;
-
-namespace quic {
-namespace test {
-namespace {
-
-const uint64_t kMaximumDynamicTableCapacityForTesting = 1024 * 1024;
-
-template <typename T>
-class QpackHeaderTableTest : public QuicTest {
- protected:
- ~QpackHeaderTableTest() override = default;
-
- void SetUp() override {
- ASSERT_TRUE(table_.SetMaximumDynamicTableCapacity(
- kMaximumDynamicTableCapacityForTesting));
- ASSERT_TRUE(
- table_.SetDynamicTableCapacity(kMaximumDynamicTableCapacityForTesting));
- }
-
- bool EntryFitsDynamicTableCapacity(absl::string_view name,
- absl::string_view value) const {
- return table_.EntryFitsDynamicTableCapacity(name, value);
- }
-
- void InsertEntry(absl::string_view name, absl::string_view value) {
- table_.InsertEntry(name, value);
- }
-
- bool SetDynamicTableCapacity(uint64_t capacity) {
- return table_.SetDynamicTableCapacity(capacity);
- }
-
- uint64_t max_entries() const { return table_.max_entries(); }
- uint64_t inserted_entry_count() const {
- return table_.inserted_entry_count();
- }
- uint64_t dropped_entry_count() const { return table_.dropped_entry_count(); }
-
- T table_;
-};
-
-using MyTypes =
- ::testing::Types<QpackEncoderHeaderTable, QpackDecoderHeaderTable>;
-TYPED_TEST_SUITE(QpackHeaderTableTest, MyTypes);
-
-// MaxEntries is determined by maximum dynamic table capacity,
-// which is set at construction time.
-TYPED_TEST(QpackHeaderTableTest, MaxEntries) {
- TypeParam table1;
- table1.SetMaximumDynamicTableCapacity(1024);
- EXPECT_EQ(32u, table1.max_entries());
-
- TypeParam table2;
- table2.SetMaximumDynamicTableCapacity(500);
- EXPECT_EQ(15u, table2.max_entries());
-}
-
-TYPED_TEST(QpackHeaderTableTest, SetDynamicTableCapacity) {
- // Dynamic table capacity does not affect MaxEntries.
- EXPECT_TRUE(this->SetDynamicTableCapacity(1024));
- EXPECT_EQ(32u * 1024, this->max_entries());
-
- EXPECT_TRUE(this->SetDynamicTableCapacity(500));
- EXPECT_EQ(32u * 1024, this->max_entries());
-
- // Dynamic table capacity cannot exceed maximum dynamic table capacity.
- EXPECT_FALSE(this->SetDynamicTableCapacity(
- 2 * kMaximumDynamicTableCapacityForTesting));
-}
-
-TYPED_TEST(QpackHeaderTableTest, EntryFitsDynamicTableCapacity) {
- EXPECT_TRUE(this->SetDynamicTableCapacity(39));
-
- EXPECT_TRUE(this->EntryFitsDynamicTableCapacity("foo", "bar"));
- EXPECT_TRUE(this->EntryFitsDynamicTableCapacity("foo", "bar2"));
- EXPECT_FALSE(this->EntryFitsDynamicTableCapacity("foo", "bar12"));
-}
-
-class QpackEncoderHeaderTableTest
- : public QpackHeaderTableTest<QpackEncoderHeaderTable> {
- protected:
- ~QpackEncoderHeaderTableTest() override = default;
-
- void ExpectMatch(absl::string_view name,
- absl::string_view value,
- QpackEncoderHeaderTable::MatchType expected_match_type,
- bool expected_is_static,
- uint64_t expected_index) const {
- // Initialize outparams to a value different from the expected to ensure
- // that FindHeaderField() sets them.
- bool is_static = !expected_is_static;
- uint64_t index = expected_index + 1;
-
- QpackEncoderHeaderTable::MatchType matchtype =
- table_.FindHeaderField(name, value, &is_static, &index);
-
- EXPECT_EQ(expected_match_type, matchtype) << name << ": " << value;
- EXPECT_EQ(expected_is_static, is_static) << name << ": " << value;
- EXPECT_EQ(expected_index, index) << name << ": " << value;
- }
-
- void ExpectNoMatch(absl::string_view name, absl::string_view value) const {
- bool is_static = false;
- uint64_t index = 0;
-
- QpackEncoderHeaderTable::MatchType matchtype =
- table_.FindHeaderField(name, value, &is_static, &index);
-
- EXPECT_EQ(QpackEncoderHeaderTable::MatchType::kNoMatch, matchtype)
- << name << ": " << value;
- }
-
- uint64_t MaxInsertSizeWithoutEvictingGivenEntry(uint64_t index) const {
- return table_.MaxInsertSizeWithoutEvictingGivenEntry(index);
- }
-
- uint64_t draining_index(float draining_fraction) const {
- return table_.draining_index(draining_fraction);
- }
-};
-
-TEST_F(QpackEncoderHeaderTableTest, FindStaticHeaderField) {
- // A header name that has multiple entries with different values.
- ExpectMatch(":method", "GET",
- QpackEncoderHeaderTable::MatchType::kNameAndValue, true, 17u);
-
- ExpectMatch(":method", "POST",
- QpackEncoderHeaderTable::MatchType::kNameAndValue, true, 20u);
-
- ExpectMatch(":method", "TRACE", QpackEncoderHeaderTable::MatchType::kName,
- true, 15u);
-
- // A header name that has a single entry with non-empty value.
- ExpectMatch("accept-encoding", "gzip, deflate, br",
- QpackEncoderHeaderTable::MatchType::kNameAndValue, true, 31u);
-
- ExpectMatch("accept-encoding", "compress",
- QpackEncoderHeaderTable::MatchType::kName, true, 31u);
-
- ExpectMatch("accept-encoding", "", QpackEncoderHeaderTable::MatchType::kName,
- true, 31u);
-
- // A header name that has a single entry with empty value.
- ExpectMatch("location", "", QpackEncoderHeaderTable::MatchType::kNameAndValue,
- true, 12u);
-
- ExpectMatch("location", "foo", QpackEncoderHeaderTable::MatchType::kName,
- true, 12u);
-
- // No matching header name.
- ExpectNoMatch("foo", "");
- ExpectNoMatch("foo", "bar");
-}
-
-TEST_F(QpackEncoderHeaderTableTest, FindDynamicHeaderField) {
- // Dynamic table is initially entry.
- ExpectNoMatch("foo", "bar");
- ExpectNoMatch("foo", "baz");
-
- // Insert one entry.
- InsertEntry("foo", "bar");
-
- // Match name and value.
- ExpectMatch("foo", "bar", QpackEncoderHeaderTable::MatchType::kNameAndValue,
- false, 0u);
-
- // Match name only.
- ExpectMatch("foo", "baz", QpackEncoderHeaderTable::MatchType::kName, false,
- 0u);
-
- // Insert an identical entry. FindHeaderField() should return the index of
- // the most recently inserted matching entry.
- InsertEntry("foo", "bar");
-
- // Match name and value.
- ExpectMatch("foo", "bar", QpackEncoderHeaderTable::MatchType::kNameAndValue,
- false, 1u);
-
- // Match name only.
- ExpectMatch("foo", "baz", QpackEncoderHeaderTable::MatchType::kName, false,
- 1u);
-}
-
-TEST_F(QpackEncoderHeaderTableTest, FindHeaderFieldPrefersStaticTable) {
- // Insert an entry to the dynamic table that exists in the static table.
- InsertEntry(":method", "GET");
-
- // FindHeaderField() prefers static table if both have name-and-value match.
- ExpectMatch(":method", "GET",
- QpackEncoderHeaderTable::MatchType::kNameAndValue, true, 17u);
-
- // FindHeaderField() prefers static table if both have name match but no value
- // match, and prefers the first entry with matching name.
- ExpectMatch(":method", "TRACE", QpackEncoderHeaderTable::MatchType::kName,
- true, 15u);
-
- // Add new entry to the dynamic table.
- InsertEntry(":method", "TRACE");
-
- // FindHeaderField prefers name-and-value match in dynamic table over name
- // only match in static table.
- ExpectMatch(":method", "TRACE",
- QpackEncoderHeaderTable::MatchType::kNameAndValue, false, 1u);
-}
-
-TEST_F(QpackEncoderHeaderTableTest, EvictByInsertion) {
- EXPECT_TRUE(SetDynamicTableCapacity(40));
-
- // Entry size is 3 + 3 + 32 = 38.
- InsertEntry("foo", "bar");
- EXPECT_EQ(1u, inserted_entry_count());
- EXPECT_EQ(0u, dropped_entry_count());
-
- ExpectMatch("foo", "bar", QpackEncoderHeaderTable::MatchType::kNameAndValue,
- /* expected_is_static = */ false, 0u);
-
- // Inserting second entry evicts the first one.
- InsertEntry("baz", "qux");
- EXPECT_EQ(2u, inserted_entry_count());
- EXPECT_EQ(1u, dropped_entry_count());
-
- ExpectNoMatch("foo", "bar");
- ExpectMatch("baz", "qux", QpackEncoderHeaderTable::MatchType::kNameAndValue,
- /* expected_is_static = */ false, 1u);
-}
-
-TEST_F(QpackEncoderHeaderTableTest, EvictByUpdateTableSize) {
- // Entry size is 3 + 3 + 32 = 38.
- InsertEntry("foo", "bar");
- InsertEntry("baz", "qux");
- EXPECT_EQ(2u, inserted_entry_count());
- EXPECT_EQ(0u, dropped_entry_count());
-
- ExpectMatch("foo", "bar", QpackEncoderHeaderTable::MatchType::kNameAndValue,
- /* expected_is_static = */ false, 0u);
- ExpectMatch("baz", "qux", QpackEncoderHeaderTable::MatchType::kNameAndValue,
- /* expected_is_static = */ false, 1u);
-
- EXPECT_TRUE(SetDynamicTableCapacity(40));
- EXPECT_EQ(2u, inserted_entry_count());
- EXPECT_EQ(1u, dropped_entry_count());
-
- ExpectNoMatch("foo", "bar");
- ExpectMatch("baz", "qux", QpackEncoderHeaderTable::MatchType::kNameAndValue,
- /* expected_is_static = */ false, 1u);
-
- EXPECT_TRUE(SetDynamicTableCapacity(20));
- EXPECT_EQ(2u, inserted_entry_count());
- EXPECT_EQ(2u, dropped_entry_count());
-
- ExpectNoMatch("foo", "bar");
- ExpectNoMatch("baz", "qux");
-}
-
-TEST_F(QpackEncoderHeaderTableTest, EvictOldestOfIdentical) {
- EXPECT_TRUE(SetDynamicTableCapacity(80));
-
- // Entry size is 3 + 3 + 32 = 38.
- // Insert same entry twice.
- InsertEntry("foo", "bar");
- InsertEntry("foo", "bar");
- EXPECT_EQ(2u, inserted_entry_count());
- EXPECT_EQ(0u, dropped_entry_count());
-
- // Find most recently inserted entry.
- ExpectMatch("foo", "bar", QpackEncoderHeaderTable::MatchType::kNameAndValue,
- /* expected_is_static = */ false, 1u);
-
- // Inserting third entry evicts the first one, not the second.
- InsertEntry("baz", "qux");
- EXPECT_EQ(3u, inserted_entry_count());
- EXPECT_EQ(1u, dropped_entry_count());
-
- ExpectMatch("foo", "bar", QpackEncoderHeaderTable::MatchType::kNameAndValue,
- /* expected_is_static = */ false, 1u);
- ExpectMatch("baz", "qux", QpackEncoderHeaderTable::MatchType::kNameAndValue,
- /* expected_is_static = */ false, 2u);
-}
-
-TEST_F(QpackEncoderHeaderTableTest, EvictOldestOfSameName) {
- EXPECT_TRUE(SetDynamicTableCapacity(80));
-
- // Entry size is 3 + 3 + 32 = 38.
- // Insert two entries with same name but different values.
- InsertEntry("foo", "bar");
- InsertEntry("foo", "baz");
- EXPECT_EQ(2u, inserted_entry_count());
- EXPECT_EQ(0u, dropped_entry_count());
-
- // Find most recently inserted entry with matching name.
- ExpectMatch("foo", "foo", QpackEncoderHeaderTable::MatchType::kName,
- /* expected_is_static = */ false, 1u);
-
- // Inserting third entry evicts the first one, not the second.
- InsertEntry("baz", "qux");
- EXPECT_EQ(3u, inserted_entry_count());
- EXPECT_EQ(1u, dropped_entry_count());
-
- ExpectMatch("foo", "foo", QpackEncoderHeaderTable::MatchType::kName,
- /* expected_is_static = */ false, 1u);
- ExpectMatch("baz", "qux", QpackEncoderHeaderTable::MatchType::kNameAndValue,
- /* expected_is_static = */ false, 2u);
-}
-
-// Returns the size of the largest entry that could be inserted into the
-// dynamic table without evicting entry |index|.
-TEST_F(QpackEncoderHeaderTableTest, MaxInsertSizeWithoutEvictingGivenEntry) {
- const uint64_t dynamic_table_capacity = 100;
- EXPECT_TRUE(SetDynamicTableCapacity(dynamic_table_capacity));
-
- // Empty table can take an entry up to its capacity.
- EXPECT_EQ(dynamic_table_capacity, MaxInsertSizeWithoutEvictingGivenEntry(0));
-
- const uint64_t entry_size1 = QpackEntry::Size("foo", "bar");
- InsertEntry("foo", "bar");
- EXPECT_EQ(dynamic_table_capacity - entry_size1,
- MaxInsertSizeWithoutEvictingGivenEntry(0));
- // Table can take an entry up to its capacity if all entries are allowed to be
- // evicted.
- EXPECT_EQ(dynamic_table_capacity, MaxInsertSizeWithoutEvictingGivenEntry(1));
-
- const uint64_t entry_size2 = QpackEntry::Size("baz", "foobar");
- InsertEntry("baz", "foobar");
- // Table can take an entry up to its capacity if all entries are allowed to be
- // evicted.
- EXPECT_EQ(dynamic_table_capacity, MaxInsertSizeWithoutEvictingGivenEntry(2));
- // Second entry must stay.
- EXPECT_EQ(dynamic_table_capacity - entry_size2,
- MaxInsertSizeWithoutEvictingGivenEntry(1));
- // First and second entry must stay.
- EXPECT_EQ(dynamic_table_capacity - entry_size2 - entry_size1,
- MaxInsertSizeWithoutEvictingGivenEntry(0));
-
- // Third entry evicts first one.
- const uint64_t entry_size3 = QpackEntry::Size("last", "entry");
- InsertEntry("last", "entry");
- EXPECT_EQ(1u, dropped_entry_count());
- // Table can take an entry up to its capacity if all entries are allowed to be
- // evicted.
- EXPECT_EQ(dynamic_table_capacity, MaxInsertSizeWithoutEvictingGivenEntry(3));
- // Third entry must stay.
- EXPECT_EQ(dynamic_table_capacity - entry_size3,
- MaxInsertSizeWithoutEvictingGivenEntry(2));
- // Second and third entry must stay.
- EXPECT_EQ(dynamic_table_capacity - entry_size3 - entry_size2,
- MaxInsertSizeWithoutEvictingGivenEntry(1));
-}
-
-TEST_F(QpackEncoderHeaderTableTest, DrainingIndex) {
- EXPECT_TRUE(SetDynamicTableCapacity(4 * QpackEntry::Size("foo", "bar")));
-
- // Empty table: no draining entry.
- EXPECT_EQ(0u, draining_index(0.0));
- EXPECT_EQ(0u, draining_index(1.0));
-
- // Table with one entry.
- InsertEntry("foo", "bar");
- // Any entry can be referenced if none of the table is draining.
- EXPECT_EQ(0u, draining_index(0.0));
- // No entry can be referenced if all of the table is draining.
- EXPECT_EQ(1u, draining_index(1.0));
-
- // Table with two entries is at half capacity.
- InsertEntry("foo", "bar");
- // Any entry can be referenced if at most half of the table is draining,
- // because current entries only take up half of total capacity.
- EXPECT_EQ(0u, draining_index(0.0));
- EXPECT_EQ(0u, draining_index(0.5));
- // No entry can be referenced if all of the table is draining.
- EXPECT_EQ(2u, draining_index(1.0));
-
- // Table with four entries is full.
- InsertEntry("foo", "bar");
- InsertEntry("foo", "bar");
- // Any entry can be referenced if none of the table is draining.
- EXPECT_EQ(0u, draining_index(0.0));
- // In a full table with identically sized entries, |draining_fraction| of all
- // entries are draining.
- EXPECT_EQ(2u, draining_index(0.5));
- // No entry can be referenced if all of the table is draining.
- EXPECT_EQ(4u, draining_index(1.0));
-}
-
-class MockObserver : public QpackDecoderHeaderTable::Observer {
- public:
- ~MockObserver() override = default;
-
- MOCK_METHOD(void, OnInsertCountReachedThreshold, (), (override));
- MOCK_METHOD(void, Cancel, (), (override));
-};
-
-class QpackDecoderHeaderTableTest
- : public QpackHeaderTableTest<QpackDecoderHeaderTable> {
- protected:
- ~QpackDecoderHeaderTableTest() override = default;
-
- void ExpectEntryAtIndex(bool is_static,
- uint64_t index,
- absl::string_view expected_name,
- absl::string_view expected_value) const {
- const auto* entry = table_.LookupEntry(is_static, index);
- ASSERT_TRUE(entry);
- EXPECT_EQ(expected_name, entry->name());
- EXPECT_EQ(expected_value, entry->value());
- }
-
- void ExpectNoEntryAtIndex(bool is_static, uint64_t index) const {
- EXPECT_FALSE(table_.LookupEntry(is_static, index));
- }
-
- void RegisterObserver(uint64_t required_insert_count,
- QpackDecoderHeaderTable::Observer* observer) {
- table_.RegisterObserver(required_insert_count, observer);
- }
-
- void UnregisterObserver(uint64_t required_insert_count,
- QpackDecoderHeaderTable::Observer* observer) {
- table_.UnregisterObserver(required_insert_count, observer);
- }
-};
-
-TEST_F(QpackDecoderHeaderTableTest, LookupStaticEntry) {
- ExpectEntryAtIndex(/* is_static = */ true, 0, ":authority", "");
-
- ExpectEntryAtIndex(/* is_static = */ true, 1, ":path", "/");
-
- // 98 is the last entry.
- ExpectEntryAtIndex(/* is_static = */ true, 98, "x-frame-options",
- "sameorigin");
-
- ASSERT_EQ(99u, QpackStaticTableVector().size());
- ExpectNoEntryAtIndex(/* is_static = */ true, 99);
-}
-
-TEST_F(QpackDecoderHeaderTableTest, InsertAndLookupDynamicEntry) {
- // Dynamic table is initially entry.
- ExpectNoEntryAtIndex(/* is_static = */ false, 0);
- ExpectNoEntryAtIndex(/* is_static = */ false, 1);
- ExpectNoEntryAtIndex(/* is_static = */ false, 2);
- ExpectNoEntryAtIndex(/* is_static = */ false, 3);
-
- // Insert one entry.
- InsertEntry("foo", "bar");
-
- ExpectEntryAtIndex(/* is_static = */ false, 0, "foo", "bar");
-
- ExpectNoEntryAtIndex(/* is_static = */ false, 1);
- ExpectNoEntryAtIndex(/* is_static = */ false, 2);
- ExpectNoEntryAtIndex(/* is_static = */ false, 3);
-
- // Insert a different entry.
- InsertEntry("baz", "bing");
-
- ExpectEntryAtIndex(/* is_static = */ false, 0, "foo", "bar");
-
- ExpectEntryAtIndex(/* is_static = */ false, 1, "baz", "bing");
-
- ExpectNoEntryAtIndex(/* is_static = */ false, 2);
- ExpectNoEntryAtIndex(/* is_static = */ false, 3);
-
- // Insert an entry identical to the most recently inserted one.
- InsertEntry("baz", "bing");
-
- ExpectEntryAtIndex(/* is_static = */ false, 0, "foo", "bar");
-
- ExpectEntryAtIndex(/* is_static = */ false, 1, "baz", "bing");
-
- ExpectEntryAtIndex(/* is_static = */ false, 2, "baz", "bing");
-
- ExpectNoEntryAtIndex(/* is_static = */ false, 3);
-}
-
-TEST_F(QpackDecoderHeaderTableTest, EvictByInsertion) {
- EXPECT_TRUE(SetDynamicTableCapacity(40));
-
- // Entry size is 3 + 3 + 32 = 38.
- InsertEntry("foo", "bar");
- EXPECT_EQ(1u, inserted_entry_count());
- EXPECT_EQ(0u, dropped_entry_count());
-
- ExpectEntryAtIndex(/* is_static = */ false, 0u, "foo", "bar");
-
- // Inserting second entry evicts the first one.
- InsertEntry("baz", "qux");
- EXPECT_EQ(2u, inserted_entry_count());
- EXPECT_EQ(1u, dropped_entry_count());
-
- ExpectNoEntryAtIndex(/* is_static = */ false, 0u);
- ExpectEntryAtIndex(/* is_static = */ false, 1u, "baz", "qux");
-}
-
-TEST_F(QpackDecoderHeaderTableTest, EvictByUpdateTableSize) {
- ExpectNoEntryAtIndex(/* is_static = */ false, 0u);
- ExpectNoEntryAtIndex(/* is_static = */ false, 1u);
-
- // Entry size is 3 + 3 + 32 = 38.
- InsertEntry("foo", "bar");
- InsertEntry("baz", "qux");
- EXPECT_EQ(2u, inserted_entry_count());
- EXPECT_EQ(0u, dropped_entry_count());
-
- ExpectEntryAtIndex(/* is_static = */ false, 0u, "foo", "bar");
- ExpectEntryAtIndex(/* is_static = */ false, 1u, "baz", "qux");
-
- EXPECT_TRUE(SetDynamicTableCapacity(40));
- EXPECT_EQ(2u, inserted_entry_count());
- EXPECT_EQ(1u, dropped_entry_count());
-
- ExpectNoEntryAtIndex(/* is_static = */ false, 0u);
- ExpectEntryAtIndex(/* is_static = */ false, 1u, "baz", "qux");
-
- EXPECT_TRUE(SetDynamicTableCapacity(20));
- EXPECT_EQ(2u, inserted_entry_count());
- EXPECT_EQ(2u, dropped_entry_count());
-
- ExpectNoEntryAtIndex(/* is_static = */ false, 0u);
- ExpectNoEntryAtIndex(/* is_static = */ false, 1u);
-}
-
-TEST_F(QpackDecoderHeaderTableTest, EvictOldestOfIdentical) {
- EXPECT_TRUE(SetDynamicTableCapacity(80));
-
- // Entry size is 3 + 3 + 32 = 38.
- // Insert same entry twice.
- InsertEntry("foo", "bar");
- InsertEntry("foo", "bar");
- EXPECT_EQ(2u, inserted_entry_count());
- EXPECT_EQ(0u, dropped_entry_count());
-
- ExpectEntryAtIndex(/* is_static = */ false, 0u, "foo", "bar");
- ExpectEntryAtIndex(/* is_static = */ false, 1u, "foo", "bar");
- ExpectNoEntryAtIndex(/* is_static = */ false, 2u);
-
- // Inserting third entry evicts the first one, not the second.
- InsertEntry("baz", "qux");
- EXPECT_EQ(3u, inserted_entry_count());
- EXPECT_EQ(1u, dropped_entry_count());
-
- ExpectNoEntryAtIndex(/* is_static = */ false, 0u);
- ExpectEntryAtIndex(/* is_static = */ false, 1u, "foo", "bar");
- ExpectEntryAtIndex(/* is_static = */ false, 2u, "baz", "qux");
-}
-
-TEST_F(QpackDecoderHeaderTableTest, EvictOldestOfSameName) {
- EXPECT_TRUE(SetDynamicTableCapacity(80));
-
- // Entry size is 3 + 3 + 32 = 38.
- // Insert two entries with same name but different values.
- InsertEntry("foo", "bar");
- InsertEntry("foo", "baz");
- EXPECT_EQ(2u, inserted_entry_count());
- EXPECT_EQ(0u, dropped_entry_count());
-
- ExpectEntryAtIndex(/* is_static = */ false, 0u, "foo", "bar");
- ExpectEntryAtIndex(/* is_static = */ false, 1u, "foo", "baz");
- ExpectNoEntryAtIndex(/* is_static = */ false, 2u);
-
- // Inserting third entry evicts the first one, not the second.
- InsertEntry("baz", "qux");
- EXPECT_EQ(3u, inserted_entry_count());
- EXPECT_EQ(1u, dropped_entry_count());
-
- ExpectNoEntryAtIndex(/* is_static = */ false, 0u);
- ExpectEntryAtIndex(/* is_static = */ false, 1u, "foo", "baz");
- ExpectEntryAtIndex(/* is_static = */ false, 2u, "baz", "qux");
-}
-
-TEST_F(QpackDecoderHeaderTableTest, RegisterObserver) {
- StrictMock<MockObserver> observer1;
- RegisterObserver(1, &observer1);
- EXPECT_CALL(observer1, OnInsertCountReachedThreshold);
- InsertEntry("foo", "bar");
- EXPECT_EQ(1u, inserted_entry_count());
- Mock::VerifyAndClearExpectations(&observer1);
-
- // Registration order does not matter.
- StrictMock<MockObserver> observer2;
- StrictMock<MockObserver> observer3;
- RegisterObserver(3, &observer3);
- RegisterObserver(2, &observer2);
-
- EXPECT_CALL(observer2, OnInsertCountReachedThreshold);
- InsertEntry("foo", "bar");
- EXPECT_EQ(2u, inserted_entry_count());
- Mock::VerifyAndClearExpectations(&observer3);
-
- EXPECT_CALL(observer3, OnInsertCountReachedThreshold);
- InsertEntry("foo", "bar");
- EXPECT_EQ(3u, inserted_entry_count());
- Mock::VerifyAndClearExpectations(&observer2);
-
- // Multiple observers with identical |required_insert_count| should all be
- // notified.
- StrictMock<MockObserver> observer4;
- StrictMock<MockObserver> observer5;
- RegisterObserver(4, &observer4);
- RegisterObserver(4, &observer5);
-
- EXPECT_CALL(observer4, OnInsertCountReachedThreshold);
- EXPECT_CALL(observer5, OnInsertCountReachedThreshold);
- InsertEntry("foo", "bar");
- EXPECT_EQ(4u, inserted_entry_count());
- Mock::VerifyAndClearExpectations(&observer4);
- Mock::VerifyAndClearExpectations(&observer5);
-}
-
-TEST_F(QpackDecoderHeaderTableTest, UnregisterObserver) {
- StrictMock<MockObserver> observer1;
- StrictMock<MockObserver> observer2;
- StrictMock<MockObserver> observer3;
- StrictMock<MockObserver> observer4;
- RegisterObserver(1, &observer1);
- RegisterObserver(2, &observer2);
- RegisterObserver(2, &observer3);
- RegisterObserver(3, &observer4);
-
- UnregisterObserver(2, &observer3);
-
- EXPECT_CALL(observer1, OnInsertCountReachedThreshold);
- EXPECT_CALL(observer2, OnInsertCountReachedThreshold);
- EXPECT_CALL(observer4, OnInsertCountReachedThreshold);
- InsertEntry("foo", "bar");
- InsertEntry("foo", "bar");
- InsertEntry("foo", "bar");
- EXPECT_EQ(3u, inserted_entry_count());
-}
-
-TEST_F(QpackDecoderHeaderTableTest, Cancel) {
- StrictMock<MockObserver> observer;
- auto table = std::make_unique<QpackDecoderHeaderTable>();
- table->RegisterObserver(1, &observer);
-
- EXPECT_CALL(observer, Cancel);
- table.reset();
-}
-
-} // namespace
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_index_conversions.cc b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_index_conversions.cc
deleted file mode 100644
index 66f2ea32e87..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_index_conversions.cc
+++ /dev/null
@@ -1,62 +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 "quic/core/qpack/qpack_index_conversions.h"
-
-#include <limits>
-
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-uint64_t QpackAbsoluteIndexToEncoderStreamRelativeIndex(
- uint64_t absolute_index,
- uint64_t inserted_entry_count) {
- QUICHE_DCHECK_LT(absolute_index, inserted_entry_count);
-
- return inserted_entry_count - absolute_index - 1;
-}
-
-uint64_t QpackAbsoluteIndexToRequestStreamRelativeIndex(uint64_t absolute_index,
- uint64_t base) {
- QUICHE_DCHECK_LT(absolute_index, base);
-
- return base - absolute_index - 1;
-}
-
-bool QpackEncoderStreamRelativeIndexToAbsoluteIndex(
- uint64_t relative_index,
- uint64_t inserted_entry_count,
- uint64_t* absolute_index) {
- if (relative_index >= inserted_entry_count) {
- return false;
- }
-
- *absolute_index = inserted_entry_count - relative_index - 1;
- return true;
-}
-
-bool QpackRequestStreamRelativeIndexToAbsoluteIndex(uint64_t relative_index,
- uint64_t base,
- uint64_t* absolute_index) {
- if (relative_index >= base) {
- return false;
- }
-
- *absolute_index = base - relative_index - 1;
- return true;
-}
-
-bool QpackPostBaseIndexToAbsoluteIndex(uint64_t post_base_index,
- uint64_t base,
- uint64_t* absolute_index) {
- if (post_base_index >= std::numeric_limits<uint64_t>::max() - base) {
- return false;
- }
-
- *absolute_index = base + post_base_index;
- return true;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_index_conversions.h b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_index_conversions.h
deleted file mode 100644
index 101858a69c7..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_index_conversions.h
+++ /dev/null
@@ -1,59 +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.
-
-// Utility methods to convert between absolute indexing (used in the dynamic
-// table), relative indexing used on the encoder stream, and relative indexing
-// and post-base indexing used on request streams (in header blocks). See:
-// https://quicwg.org/base-drafts/draft-ietf-quic-qpack.html#indexing
-// https://quicwg.org/base-drafts/draft-ietf-quic-qpack.html#relative-indexing
-// https://quicwg.org/base-drafts/draft-ietf-quic-qpack.html#post-base
-
-#ifndef QUICHE_QUIC_CORE_QPACK_QPACK_INDEX_CONVERSIONS_H_
-#define QUICHE_QUIC_CORE_QPACK_QPACK_INDEX_CONVERSIONS_H_
-
-#include <cstdint>
-
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// Conversion functions used in the encoder do not check for overflow/underflow.
-// Since the maximum index is limited by maximum dynamic table capacity
-// (represented on uint64_t) divided by minimum header field size (defined to be
-// 32 bytes), overflow is not possible. The caller is responsible for providing
-// input that does not underflow.
-
-QUIC_EXPORT_PRIVATE uint64_t
-QpackAbsoluteIndexToEncoderStreamRelativeIndex(uint64_t absolute_index,
- uint64_t inserted_entry_count);
-
-QUIC_EXPORT_PRIVATE uint64_t
-QpackAbsoluteIndexToRequestStreamRelativeIndex(uint64_t absolute_index,
- uint64_t base);
-
-// Conversion functions used in the decoder operate on input received from the
-// network. These functions return false on overflow or underflow.
-
-QUIC_EXPORT_PRIVATE bool QpackEncoderStreamRelativeIndexToAbsoluteIndex(
- uint64_t relative_index,
- uint64_t inserted_entry_count,
- uint64_t* absolute_index);
-
-// On success, |*absolute_index| is guaranteed to be strictly less than
-// std::numeric_limits<uint64_t>::max().
-QUIC_EXPORT_PRIVATE bool QpackRequestStreamRelativeIndexToAbsoluteIndex(
- uint64_t relative_index,
- uint64_t base,
- uint64_t* absolute_index);
-
-// On success, |*absolute_index| is guaranteed to be strictly less than
-// std::numeric_limits<uint64_t>::max().
-QUIC_EXPORT_PRIVATE bool QpackPostBaseIndexToAbsoluteIndex(
- uint64_t post_base_index,
- uint64_t base,
- uint64_t* absolute_index);
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_QPACK_QPACK_INDEX_CONVERSIONS_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_index_conversions_test.cc b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_index_conversions_test.cc
deleted file mode 100644
index 335adc42fca..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_index_conversions_test.cc
+++ /dev/null
@@ -1,99 +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 "quic/core/qpack/qpack_index_conversions.h"
-
-#include "quic/platform/api/quic_test.h"
-
-namespace quic {
-namespace test {
-namespace {
-
-struct {
- uint64_t relative_index;
- uint64_t inserted_entry_count;
- uint64_t expected_absolute_index;
-} kEncoderStreamRelativeIndexTestData[] = {{0, 1, 0}, {0, 2, 1}, {1, 2, 0},
- {0, 10, 9}, {5, 10, 4}, {9, 10, 0}};
-
-TEST(QpackIndexConversions, EncoderStreamRelativeIndex) {
- for (const auto& test_data : kEncoderStreamRelativeIndexTestData) {
- uint64_t absolute_index = 42;
- EXPECT_TRUE(QpackEncoderStreamRelativeIndexToAbsoluteIndex(
- test_data.relative_index, test_data.inserted_entry_count,
- &absolute_index));
- EXPECT_EQ(test_data.expected_absolute_index, absolute_index);
-
- EXPECT_EQ(test_data.relative_index,
- QpackAbsoluteIndexToEncoderStreamRelativeIndex(
- absolute_index, test_data.inserted_entry_count));
- }
-}
-
-struct {
- uint64_t relative_index;
- uint64_t base;
- uint64_t expected_absolute_index;
-} kRequestStreamRelativeIndexTestData[] = {{0, 1, 0}, {0, 2, 1}, {1, 2, 0},
- {0, 10, 9}, {5, 10, 4}, {9, 10, 0}};
-
-TEST(QpackIndexConversions, RequestStreamRelativeIndex) {
- for (const auto& test_data : kRequestStreamRelativeIndexTestData) {
- uint64_t absolute_index = 42;
- EXPECT_TRUE(QpackRequestStreamRelativeIndexToAbsoluteIndex(
- test_data.relative_index, test_data.base, &absolute_index));
- EXPECT_EQ(test_data.expected_absolute_index, absolute_index);
-
- EXPECT_EQ(test_data.relative_index,
- QpackAbsoluteIndexToRequestStreamRelativeIndex(absolute_index,
- test_data.base));
- }
-}
-
-struct {
- uint64_t post_base_index;
- uint64_t base;
- uint64_t expected_absolute_index;
-} kPostBaseIndexTestData[] = {{0, 1, 1}, {1, 0, 1}, {2, 0, 2},
- {1, 1, 2}, {0, 2, 2}, {1, 2, 3}};
-
-TEST(QpackIndexConversions, PostBaseIndex) {
- for (const auto& test_data : kPostBaseIndexTestData) {
- uint64_t absolute_index = 42;
- EXPECT_TRUE(QpackPostBaseIndexToAbsoluteIndex(
- test_data.post_base_index, test_data.base, &absolute_index));
- EXPECT_EQ(test_data.expected_absolute_index, absolute_index);
- }
-}
-
-TEST(QpackIndexConversions, EncoderStreamRelativeIndexUnderflow) {
- uint64_t absolute_index;
- EXPECT_FALSE(QpackEncoderStreamRelativeIndexToAbsoluteIndex(
- /* relative_index = */ 10,
- /* inserted_entry_count = */ 10, &absolute_index));
- EXPECT_FALSE(QpackEncoderStreamRelativeIndexToAbsoluteIndex(
- /* relative_index = */ 12,
- /* inserted_entry_count = */ 10, &absolute_index));
-}
-
-TEST(QpackIndexConversions, RequestStreamRelativeIndexUnderflow) {
- uint64_t absolute_index;
- EXPECT_FALSE(QpackRequestStreamRelativeIndexToAbsoluteIndex(
- /* relative_index = */ 10,
- /* base = */ 10, &absolute_index));
- EXPECT_FALSE(QpackRequestStreamRelativeIndexToAbsoluteIndex(
- /* relative_index = */ 12,
- /* base = */ 10, &absolute_index));
-}
-
-TEST(QpackIndexConversions, QpackPostBaseIndexToAbsoluteIndexOverflow) {
- uint64_t absolute_index;
- EXPECT_FALSE(QpackPostBaseIndexToAbsoluteIndex(
- /* post_base_index = */ 20,
- /* base = */ std::numeric_limits<uint64_t>::max() - 10, &absolute_index));
-}
-
-} // namespace
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_instruction_decoder.cc b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_instruction_decoder.cc
deleted file mode 100644
index acd52c2ce33..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_instruction_decoder.cc
+++ /dev/null
@@ -1,332 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/qpack/qpack_instruction_decoder.h"
-
-#include <algorithm>
-#include <utility>
-
-#include "absl/strings/string_view.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-namespace {
-
-// Maximum length of header name and header value. This limits the amount of
-// memory the peer can make the decoder allocate when sending string literals.
-const size_t kStringLiteralLengthLimit = 1024 * 1024;
-
-} // namespace
-
-QpackInstructionDecoder::QpackInstructionDecoder(const QpackLanguage* language,
- Delegate* delegate)
- : language_(language),
- delegate_(delegate),
- s_bit_(false),
- varint_(0),
- varint2_(0),
- is_huffman_encoded_(false),
- string_length_(0),
- error_detected_(false),
- state_(State::kStartInstruction) {}
-
-bool QpackInstructionDecoder::Decode(absl::string_view data) {
- QUICHE_DCHECK(!data.empty());
- QUICHE_DCHECK(!error_detected_);
-
- while (true) {
- bool success = true;
- size_t bytes_consumed = 0;
-
- switch (state_) {
- case State::kStartInstruction:
- success = DoStartInstruction(data);
- break;
- case State::kStartField:
- success = DoStartField();
- break;
- case State::kReadBit:
- success = DoReadBit(data);
- break;
- case State::kVarintStart:
- success = DoVarintStart(data, &bytes_consumed);
- break;
- case State::kVarintResume:
- success = DoVarintResume(data, &bytes_consumed);
- break;
- case State::kVarintDone:
- success = DoVarintDone();
- break;
- case State::kReadString:
- success = DoReadString(data, &bytes_consumed);
- break;
- case State::kReadStringDone:
- success = DoReadStringDone();
- break;
- }
-
- if (!success) {
- return false;
- }
-
- // |success| must be false if an error is detected.
- QUICHE_DCHECK(!error_detected_);
-
- QUICHE_DCHECK_LE(bytes_consumed, data.size());
-
- data = absl::string_view(data.data() + bytes_consumed,
- data.size() - bytes_consumed);
-
- // Stop processing if no more data but next state would require it.
- if (data.empty() && (state_ != State::kStartField) &&
- (state_ != State::kVarintDone) && (state_ != State::kReadStringDone)) {
- return true;
- }
- }
-}
-
-bool QpackInstructionDecoder::AtInstructionBoundary() const {
- return state_ == State::kStartInstruction;
-}
-
-bool QpackInstructionDecoder::DoStartInstruction(absl::string_view data) {
- QUICHE_DCHECK(!data.empty());
-
- instruction_ = LookupOpcode(data[0]);
- field_ = instruction_->fields.begin();
-
- state_ = State::kStartField;
- return true;
-}
-
-bool QpackInstructionDecoder::DoStartField() {
- if (field_ == instruction_->fields.end()) {
- // Completed decoding this instruction.
-
- if (!delegate_->OnInstructionDecoded(instruction_)) {
- return false;
- }
-
- state_ = State::kStartInstruction;
- return true;
- }
-
- switch (field_->type) {
- case QpackInstructionFieldType::kSbit:
- case QpackInstructionFieldType::kName:
- case QpackInstructionFieldType::kValue:
- state_ = State::kReadBit;
- return true;
- case QpackInstructionFieldType::kVarint:
- case QpackInstructionFieldType::kVarint2:
- state_ = State::kVarintStart;
- return true;
- default:
- QUIC_BUG(quic_bug_10767_1) << "Invalid field type.";
- return false;
- }
-}
-
-bool QpackInstructionDecoder::DoReadBit(absl::string_view data) {
- QUICHE_DCHECK(!data.empty());
-
- switch (field_->type) {
- case QpackInstructionFieldType::kSbit: {
- const uint8_t bitmask = field_->param;
- s_bit_ = (data[0] & bitmask) == bitmask;
-
- ++field_;
- state_ = State::kStartField;
-
- return true;
- }
- case QpackInstructionFieldType::kName:
- case QpackInstructionFieldType::kValue: {
- const uint8_t prefix_length = field_->param;
- QUICHE_DCHECK_GE(7, prefix_length);
- const uint8_t bitmask = 1 << prefix_length;
- is_huffman_encoded_ = (data[0] & bitmask) == bitmask;
-
- state_ = State::kVarintStart;
-
- return true;
- }
- default:
- QUIC_BUG(quic_bug_10767_2) << "Invalid field type.";
- return false;
- }
-}
-
-bool QpackInstructionDecoder::DoVarintStart(absl::string_view data,
- size_t* bytes_consumed) {
- QUICHE_DCHECK(!data.empty());
- QUICHE_DCHECK(field_->type == QpackInstructionFieldType::kVarint ||
- field_->type == QpackInstructionFieldType::kVarint2 ||
- field_->type == QpackInstructionFieldType::kName ||
- field_->type == QpackInstructionFieldType::kValue);
-
- http2::DecodeBuffer buffer(data.data() + 1, data.size() - 1);
- http2::DecodeStatus status =
- varint_decoder_.Start(data[0], field_->param, &buffer);
-
- *bytes_consumed = 1 + buffer.Offset();
- switch (status) {
- case http2::DecodeStatus::kDecodeDone:
- state_ = State::kVarintDone;
- return true;
- case http2::DecodeStatus::kDecodeInProgress:
- state_ = State::kVarintResume;
- return true;
- case http2::DecodeStatus::kDecodeError:
- OnError(ErrorCode::INTEGER_TOO_LARGE, "Encoded integer too large.");
- return false;
- default:
- QUIC_BUG(quic_bug_10767_3) << "Unknown decode status " << status;
- return false;
- }
-}
-
-bool QpackInstructionDecoder::DoVarintResume(absl::string_view data,
- size_t* bytes_consumed) {
- QUICHE_DCHECK(!data.empty());
- QUICHE_DCHECK(field_->type == QpackInstructionFieldType::kVarint ||
- field_->type == QpackInstructionFieldType::kVarint2 ||
- field_->type == QpackInstructionFieldType::kName ||
- field_->type == QpackInstructionFieldType::kValue);
-
- http2::DecodeBuffer buffer(data);
- http2::DecodeStatus status = varint_decoder_.Resume(&buffer);
-
- *bytes_consumed = buffer.Offset();
- switch (status) {
- case http2::DecodeStatus::kDecodeDone:
- state_ = State::kVarintDone;
- return true;
- case http2::DecodeStatus::kDecodeInProgress:
- QUICHE_DCHECK_EQ(*bytes_consumed, data.size());
- QUICHE_DCHECK(buffer.Empty());
- return true;
- case http2::DecodeStatus::kDecodeError:
- OnError(ErrorCode::INTEGER_TOO_LARGE, "Encoded integer too large.");
- return false;
- default:
- QUIC_BUG(quic_bug_10767_4) << "Unknown decode status " << status;
- return false;
- }
-}
-
-bool QpackInstructionDecoder::DoVarintDone() {
- QUICHE_DCHECK(field_->type == QpackInstructionFieldType::kVarint ||
- field_->type == QpackInstructionFieldType::kVarint2 ||
- field_->type == QpackInstructionFieldType::kName ||
- field_->type == QpackInstructionFieldType::kValue);
-
- if (field_->type == QpackInstructionFieldType::kVarint) {
- varint_ = varint_decoder_.value();
-
- ++field_;
- state_ = State::kStartField;
- return true;
- }
-
- if (field_->type == QpackInstructionFieldType::kVarint2) {
- varint2_ = varint_decoder_.value();
-
- ++field_;
- state_ = State::kStartField;
- return true;
- }
-
- string_length_ = varint_decoder_.value();
- if (string_length_ > kStringLiteralLengthLimit) {
- OnError(ErrorCode::STRING_LITERAL_TOO_LONG, "String literal too long.");
- return false;
- }
-
- std::string* const string =
- (field_->type == QpackInstructionFieldType::kName) ? &name_ : &value_;
- string->clear();
-
- if (string_length_ == 0) {
- ++field_;
- state_ = State::kStartField;
- return true;
- }
-
- string->reserve(string_length_);
-
- state_ = State::kReadString;
- return true;
-}
-
-bool QpackInstructionDecoder::DoReadString(absl::string_view data,
- size_t* bytes_consumed) {
- QUICHE_DCHECK(!data.empty());
- QUICHE_DCHECK(field_->type == QpackInstructionFieldType::kName ||
- field_->type == QpackInstructionFieldType::kValue);
-
- std::string* const string =
- (field_->type == QpackInstructionFieldType::kName) ? &name_ : &value_;
- QUICHE_DCHECK_LT(string->size(), string_length_);
-
- *bytes_consumed = std::min(string_length_ - string->size(), data.size());
- string->append(data.data(), *bytes_consumed);
-
- QUICHE_DCHECK_LE(string->size(), string_length_);
- if (string->size() == string_length_) {
- state_ = State::kReadStringDone;
- }
- return true;
-}
-
-bool QpackInstructionDecoder::DoReadStringDone() {
- QUICHE_DCHECK(field_->type == QpackInstructionFieldType::kName ||
- field_->type == QpackInstructionFieldType::kValue);
-
- std::string* const string =
- (field_->type == QpackInstructionFieldType::kName) ? &name_ : &value_;
- QUICHE_DCHECK_EQ(string->size(), string_length_);
-
- if (is_huffman_encoded_) {
- huffman_decoder_.Reset();
- // HpackHuffmanDecoder::Decode() cannot perform in-place decoding.
- std::string decoded_value;
- huffman_decoder_.Decode(*string, &decoded_value);
- if (!huffman_decoder_.InputProperlyTerminated()) {
- OnError(ErrorCode::HUFFMAN_ENCODING_ERROR,
- "Error in Huffman-encoded string.");
- return false;
- }
- *string = std::move(decoded_value);
- }
-
- ++field_;
- state_ = State::kStartField;
- return true;
-}
-
-const QpackInstruction* QpackInstructionDecoder::LookupOpcode(
- uint8_t byte) const {
- for (const auto* instruction : *language_) {
- if ((byte & instruction->opcode.mask) == instruction->opcode.value) {
- return instruction;
- }
- }
- // |language_| should be defined such that instruction opcodes cover every
- // possible input.
- QUICHE_DCHECK(false);
- return nullptr;
-}
-
-void QpackInstructionDecoder::OnError(ErrorCode error_code,
- absl::string_view error_message) {
- QUICHE_DCHECK(!error_detected_);
-
- error_detected_ = true;
- delegate_->OnInstructionDecodingError(error_code, error_message);
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_instruction_decoder.h b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_instruction_decoder.h
deleted file mode 100644
index fc9b96eca16..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_instruction_decoder.h
+++ /dev/null
@@ -1,161 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QPACK_QPACK_INSTRUCTION_DECODER_H_
-#define QUICHE_QUIC_CORE_QPACK_QPACK_INSTRUCTION_DECODER_H_
-
-#include <cstddef>
-#include <cstdint>
-#include <string>
-
-#include "absl/strings/string_view.h"
-#include "http2/hpack/huffman/hpack_huffman_decoder.h"
-#include "http2/hpack/varint/hpack_varint_decoder.h"
-#include "quic/core/qpack/qpack_instructions.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// Generic instruction decoder class. Takes a QpackLanguage that describes a
-// language, that is, a set of instruction opcodes together with a list of
-// fields that follow each instruction.
-class QUIC_EXPORT_PRIVATE QpackInstructionDecoder {
- public:
- enum class ErrorCode {
- INTEGER_TOO_LARGE,
- STRING_LITERAL_TOO_LONG,
- HUFFMAN_ENCODING_ERROR,
- };
-
- // Delegate is notified each time an instruction is decoded or when an error
- // occurs.
- class QUIC_EXPORT_PRIVATE Delegate {
- public:
- virtual ~Delegate() = default;
-
- // Called when an instruction (including all its fields) is decoded.
- // |instruction| points to an entry in |language|.
- // Returns true if decoded fields are valid.
- // Returns false otherwise, in which case QpackInstructionDecoder stops
- // decoding: Delegate methods will not be called, and Decode() must not be
- // called. Implementations are allowed to destroy the
- // QpackInstructionDecoder instance synchronously if OnInstructionDecoded()
- // returns false.
- virtual bool OnInstructionDecoded(const QpackInstruction* instruction) = 0;
-
- // Called by QpackInstructionDecoder if an error has occurred.
- // No more data is processed afterwards.
- // Implementations are allowed to destroy the QpackInstructionDecoder
- // instance synchronously.
- virtual void OnInstructionDecodingError(
- ErrorCode error_code,
- absl::string_view error_message) = 0;
- };
-
- // Both |*language| and |*delegate| must outlive this object.
- QpackInstructionDecoder(const QpackLanguage* language, Delegate* delegate);
- QpackInstructionDecoder() = delete;
- QpackInstructionDecoder(const QpackInstructionDecoder&) = delete;
- QpackInstructionDecoder& operator=(const QpackInstructionDecoder&) = delete;
-
- // Provide a data fragment to decode. Must not be called after an error has
- // occurred. Must not be called with empty |data|. Return true on success,
- // false on error (in which case Delegate::OnInstructionDecodingError() is
- // called synchronously).
- bool Decode(absl::string_view data);
-
- // Returns true if no decoding has taken place yet or if the last instruction
- // has been entirely parsed.
- bool AtInstructionBoundary() const;
-
- // Accessors for decoded values. Should only be called for fields that are
- // part of the most recently decoded instruction, and only after |this| calls
- // Delegate::OnInstructionDecoded() but before Decode() is called again.
- bool s_bit() const { return s_bit_; }
- uint64_t varint() const { return varint_; }
- uint64_t varint2() const { return varint2_; }
- const std::string& name() const { return name_; }
- const std::string& value() const { return value_; }
-
- private:
- enum class State {
- // Identify instruction.
- kStartInstruction,
- // Start decoding next field.
- kStartField,
- // Read a single bit.
- kReadBit,
- // Start reading integer.
- kVarintStart,
- // Resume reading integer.
- kVarintResume,
- // Done reading integer.
- kVarintDone,
- // Read string.
- kReadString,
- // Done reading string.
- kReadStringDone
- };
-
- // One method for each state. They each return true on success, false on
- // error (in which case |this| might already be destroyed). Some take input
- // data and set |*bytes_consumed| to the number of octets processed. Some
- // take input data but do not consume any bytes. Some do not take any
- // arguments because they only change internal state.
- bool DoStartInstruction(absl::string_view data);
- bool DoStartField();
- bool DoReadBit(absl::string_view data);
- bool DoVarintStart(absl::string_view data, size_t* bytes_consumed);
- bool DoVarintResume(absl::string_view data, size_t* bytes_consumed);
- bool DoVarintDone();
- bool DoReadString(absl::string_view data, size_t* bytes_consumed);
- bool DoReadStringDone();
-
- // Identify instruction based on opcode encoded in |byte|.
- // Returns a pointer to an element of |*language_|.
- const QpackInstruction* LookupOpcode(uint8_t byte) const;
-
- // Stops decoding and calls Delegate::OnInstructionDecodingError().
- void OnError(ErrorCode error_code, absl::string_view error_message);
-
- // Describes the language used for decoding.
- const QpackLanguage* const language_;
-
- // The Delegate to notify of decoded instructions and errors.
- Delegate* const delegate_;
-
- // Storage for decoded field values.
- bool s_bit_;
- uint64_t varint_;
- uint64_t varint2_;
- std::string name_;
- std::string value_;
- // Whether the currently decoded header name or value is Huffman encoded.
- bool is_huffman_encoded_;
- // Length of string being read into |name_| or |value_|.
- size_t string_length_;
-
- // Decoder instance for decoding integers.
- http2::HpackVarintDecoder varint_decoder_;
-
- // Decoder instance for decoding Huffman encoded strings.
- http2::HpackHuffmanDecoder huffman_decoder_;
-
- // True if a decoding error has been detected by QpackInstructionDecoder.
- // Only used in QUICHE_DCHECKs.
- bool error_detected_;
-
- // Decoding state.
- State state_;
-
- // Instruction currently being decoded.
- const QpackInstruction* instruction_;
-
- // Field currently being decoded.
- QpackInstructionFields::const_iterator field_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_QPACK_QPACK_INSTRUCTION_DECODER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_instruction_decoder_test.cc b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_instruction_decoder_test.cc
deleted file mode 100644
index b10c1b42d86..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_instruction_decoder_test.cc
+++ /dev/null
@@ -1,226 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/qpack/qpack_instruction_decoder.h"
-
-#include <algorithm>
-
-#include "absl/strings/escaping.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/qpack/qpack_instructions.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/qpack/qpack_test_utils.h"
-
-using ::testing::_;
-using ::testing::Eq;
-using ::testing::Expectation;
-using ::testing::InvokeWithoutArgs;
-using ::testing::Return;
-using ::testing::StrictMock;
-using ::testing::Values;
-
-namespace quic {
-namespace test {
-namespace {
-
-// This instruction has three fields: an S bit and two varints.
-const QpackInstruction* TestInstruction1() {
- static const QpackInstruction* const instruction =
- new QpackInstruction{QpackInstructionOpcode{0x00, 0x80},
- {{QpackInstructionFieldType::kSbit, 0x40},
- {QpackInstructionFieldType::kVarint, 6},
- {QpackInstructionFieldType::kVarint2, 8}}};
- return instruction;
-}
-
-// This instruction has two fields: a header name with a 6-bit prefix, and a
-// header value with a 7-bit prefix, both preceded by a Huffman bit.
-const QpackInstruction* TestInstruction2() {
- static const QpackInstruction* const instruction =
- new QpackInstruction{QpackInstructionOpcode{0x80, 0x80},
- {{QpackInstructionFieldType::kName, 6},
- {QpackInstructionFieldType::kValue, 7}}};
- return instruction;
-}
-
-const QpackLanguage* TestLanguage() {
- static const QpackLanguage* const language =
- new QpackLanguage{TestInstruction1(), TestInstruction2()};
- return language;
-}
-
-class MockDelegate : public QpackInstructionDecoder::Delegate {
- public:
- MockDelegate() {
- ON_CALL(*this, OnInstructionDecoded(_)).WillByDefault(Return(true));
- }
-
- MockDelegate(const MockDelegate&) = delete;
- MockDelegate& operator=(const MockDelegate&) = delete;
- ~MockDelegate() override = default;
-
- MOCK_METHOD(bool,
- OnInstructionDecoded,
- (const QpackInstruction*),
- (override));
- MOCK_METHOD(void,
- OnInstructionDecodingError,
- (QpackInstructionDecoder::ErrorCode error_code,
- absl::string_view error_message),
- (override));
-};
-
-class QpackInstructionDecoderTest : public QuicTestWithParam<FragmentMode> {
- protected:
- QpackInstructionDecoderTest()
- : decoder_(std::make_unique<QpackInstructionDecoder>(TestLanguage(),
- &delegate_)),
- fragment_mode_(GetParam()) {}
- ~QpackInstructionDecoderTest() override = default;
-
- void SetUp() override {
- // Destroy QpackInstructionDecoder on error to test that it does not crash.
- // See https://crbug.com/1025209.
- ON_CALL(delegate_, OnInstructionDecodingError(_, _))
- .WillByDefault(InvokeWithoutArgs([this]() { decoder_.reset(); }));
- }
-
- // Decode one full instruction with fragment sizes dictated by
- // |fragment_mode_|.
- // Assumes that |data| is a single complete instruction, and accordingly
- // verifies that AtInstructionBoundary() returns true before and after the
- // instruction, and returns false while decoding is in progress.
- // Assumes that delegate methods destroy |decoder_| if they return false.
- void DecodeInstruction(absl::string_view data) {
- EXPECT_TRUE(decoder_->AtInstructionBoundary());
-
- FragmentSizeGenerator fragment_size_generator =
- FragmentModeToFragmentSizeGenerator(fragment_mode_);
-
- while (!data.empty()) {
- size_t fragment_size = std::min(fragment_size_generator(), data.size());
- bool success = decoder_->Decode(data.substr(0, fragment_size));
- if (!decoder_) {
- EXPECT_FALSE(success);
- return;
- }
- EXPECT_TRUE(success);
- data = data.substr(fragment_size);
- if (!data.empty()) {
- EXPECT_FALSE(decoder_->AtInstructionBoundary());
- }
- }
-
- EXPECT_TRUE(decoder_->AtInstructionBoundary());
- }
-
- StrictMock<MockDelegate> delegate_;
- std::unique_ptr<QpackInstructionDecoder> decoder_;
-
- private:
- const FragmentMode fragment_mode_;
-};
-
-INSTANTIATE_TEST_SUITE_P(All,
- QpackInstructionDecoderTest,
- Values(FragmentMode::kSingleChunk,
- FragmentMode::kOctetByOctet));
-
-TEST_P(QpackInstructionDecoderTest, SBitAndVarint2) {
- EXPECT_CALL(delegate_, OnInstructionDecoded(TestInstruction1()));
- DecodeInstruction(absl::HexStringToBytes("7f01ff65"));
-
- EXPECT_TRUE(decoder_->s_bit());
- EXPECT_EQ(64u, decoder_->varint());
- EXPECT_EQ(356u, decoder_->varint2());
-
- EXPECT_CALL(delegate_, OnInstructionDecoded(TestInstruction1()));
- DecodeInstruction(absl::HexStringToBytes("05c8"));
-
- EXPECT_FALSE(decoder_->s_bit());
- EXPECT_EQ(5u, decoder_->varint());
- EXPECT_EQ(200u, decoder_->varint2());
-}
-
-TEST_P(QpackInstructionDecoderTest, NameAndValue) {
- EXPECT_CALL(delegate_, OnInstructionDecoded(TestInstruction2()));
- DecodeInstruction(absl::HexStringToBytes("83666f6f03626172"));
-
- EXPECT_EQ("foo", decoder_->name());
- EXPECT_EQ("bar", decoder_->value());
-
- EXPECT_CALL(delegate_, OnInstructionDecoded(TestInstruction2()));
- DecodeInstruction(absl::HexStringToBytes("8000"));
-
- EXPECT_EQ("", decoder_->name());
- EXPECT_EQ("", decoder_->value());
-
- EXPECT_CALL(delegate_, OnInstructionDecoded(TestInstruction2()));
- DecodeInstruction(absl::HexStringToBytes("c294e7838c767f"));
-
- EXPECT_EQ("foo", decoder_->name());
- EXPECT_EQ("bar", decoder_->value());
-}
-
-TEST_P(QpackInstructionDecoderTest, InvalidHuffmanEncoding) {
- EXPECT_CALL(delegate_,
- OnInstructionDecodingError(
- QpackInstructionDecoder::ErrorCode::HUFFMAN_ENCODING_ERROR,
- Eq("Error in Huffman-encoded string.")));
- DecodeInstruction(absl::HexStringToBytes("c1ff"));
-}
-
-TEST_P(QpackInstructionDecoderTest, InvalidVarintEncoding) {
- EXPECT_CALL(delegate_,
- OnInstructionDecodingError(
- QpackInstructionDecoder::ErrorCode::INTEGER_TOO_LARGE,
- Eq("Encoded integer too large.")));
- DecodeInstruction(absl::HexStringToBytes("ffffffffffffffffffffff"));
-}
-
-TEST_P(QpackInstructionDecoderTest, StringLiteralTooLong) {
- EXPECT_CALL(delegate_,
- OnInstructionDecodingError(
- QpackInstructionDecoder::ErrorCode::STRING_LITERAL_TOO_LONG,
- Eq("String literal too long.")));
- DecodeInstruction(absl::HexStringToBytes("bfffff7f"));
-}
-
-TEST_P(QpackInstructionDecoderTest, DelegateSignalsError) {
- // First instruction is valid.
- Expectation first_call =
- EXPECT_CALL(delegate_, OnInstructionDecoded(TestInstruction1()))
- .WillOnce(InvokeWithoutArgs([this]() -> bool {
- EXPECT_EQ(1u, decoder_->varint());
- return true;
- }));
-
- // Second instruction is invalid. Decoding must halt.
- EXPECT_CALL(delegate_, OnInstructionDecoded(TestInstruction1()))
- .After(first_call)
- .WillOnce(InvokeWithoutArgs([this]() -> bool {
- EXPECT_EQ(2u, decoder_->varint());
- return false;
- }));
-
- EXPECT_FALSE(
- decoder_->Decode(absl::HexStringToBytes("01000200030004000500")));
-}
-
-// QpackInstructionDecoder must not crash if it is destroyed from a
-// Delegate::OnInstructionDecoded() call as long as it returns false.
-TEST_P(QpackInstructionDecoderTest, DelegateSignalsErrorAndDestroysDecoder) {
- EXPECT_CALL(delegate_, OnInstructionDecoded(TestInstruction1()))
- .WillOnce(InvokeWithoutArgs([this]() -> bool {
- EXPECT_EQ(1u, decoder_->varint());
- decoder_.reset();
- return false;
- }));
- DecodeInstruction(absl::HexStringToBytes("0100"));
-}
-
-} // namespace
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_instruction_encoder.cc b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_instruction_encoder.cc
deleted file mode 100644
index 527c43c82db..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_instruction_encoder.cc
+++ /dev/null
@@ -1,177 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/qpack/qpack_instruction_encoder.h"
-
-#include <limits>
-
-#include "absl/strings/str_cat.h"
-#include "absl/strings/string_view.h"
-#include "http2/hpack/huffman/hpack_huffman_encoder.h"
-#include "http2/hpack/varint/hpack_varint_encoder.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-QpackInstructionEncoder::QpackInstructionEncoder()
- : use_huffman_(false),
- string_length_(0),
- byte_(0),
- state_(State::kOpcode),
- instruction_(nullptr) {}
-
-void QpackInstructionEncoder::Encode(
- const QpackInstructionWithValues& instruction_with_values,
- std::string* output) {
- QUICHE_DCHECK(instruction_with_values.instruction());
-
- state_ = State::kOpcode;
- instruction_ = instruction_with_values.instruction();
- field_ = instruction_->fields.begin();
-
- // Field list must not be empty.
- QUICHE_DCHECK(field_ != instruction_->fields.end());
-
- do {
- switch (state_) {
- case State::kOpcode:
- DoOpcode();
- break;
- case State::kStartField:
- DoStartField();
- break;
- case State::kSbit:
- DoSBit(instruction_with_values.s_bit());
- break;
- case State::kVarintEncode:
- DoVarintEncode(instruction_with_values.varint(),
- instruction_with_values.varint2(), output);
- break;
- case State::kStartString:
- DoStartString(instruction_with_values.name(),
- instruction_with_values.value());
- break;
- case State::kWriteString:
- DoWriteString(instruction_with_values.name(),
- instruction_with_values.value(), output);
- break;
- }
- } while (field_ != instruction_->fields.end());
-
- QUICHE_DCHECK(state_ == State::kStartField);
-}
-
-void QpackInstructionEncoder::DoOpcode() {
- QUICHE_DCHECK_EQ(0u, byte_);
-
- byte_ = instruction_->opcode.value;
-
- state_ = State::kStartField;
-}
-
-void QpackInstructionEncoder::DoStartField() {
- switch (field_->type) {
- case QpackInstructionFieldType::kSbit:
- state_ = State::kSbit;
- return;
- case QpackInstructionFieldType::kVarint:
- case QpackInstructionFieldType::kVarint2:
- state_ = State::kVarintEncode;
- return;
- case QpackInstructionFieldType::kName:
- case QpackInstructionFieldType::kValue:
- state_ = State::kStartString;
- return;
- }
-}
-
-void QpackInstructionEncoder::DoSBit(bool s_bit) {
- QUICHE_DCHECK(field_->type == QpackInstructionFieldType::kSbit);
-
- if (s_bit) {
- QUICHE_DCHECK_EQ(0, byte_ & field_->param);
-
- byte_ |= field_->param;
- }
-
- ++field_;
- state_ = State::kStartField;
-}
-
-void QpackInstructionEncoder::DoVarintEncode(uint64_t varint,
- uint64_t varint2,
- std::string* output) {
- QUICHE_DCHECK(field_->type == QpackInstructionFieldType::kVarint ||
- field_->type == QpackInstructionFieldType::kVarint2 ||
- field_->type == QpackInstructionFieldType::kName ||
- field_->type == QpackInstructionFieldType::kValue);
- uint64_t integer_to_encode;
- switch (field_->type) {
- case QpackInstructionFieldType::kVarint:
- integer_to_encode = varint;
- break;
- case QpackInstructionFieldType::kVarint2:
- integer_to_encode = varint2;
- break;
- default:
- integer_to_encode = string_length_;
- break;
- }
-
- http2::HpackVarintEncoder::Encode(byte_, field_->param, integer_to_encode,
- output);
- byte_ = 0;
-
- if (field_->type == QpackInstructionFieldType::kVarint ||
- field_->type == QpackInstructionFieldType::kVarint2) {
- ++field_;
- state_ = State::kStartField;
- return;
- }
-
- state_ = State::kWriteString;
-}
-
-void QpackInstructionEncoder::DoStartString(absl::string_view name,
- absl::string_view value) {
- QUICHE_DCHECK(field_->type == QpackInstructionFieldType::kName ||
- field_->type == QpackInstructionFieldType::kValue);
-
- absl::string_view string_to_write =
- (field_->type == QpackInstructionFieldType::kName) ? name : value;
- string_length_ = string_to_write.size();
-
- size_t encoded_size = http2::HuffmanSize(string_to_write);
- use_huffman_ = encoded_size < string_length_;
-
- if (use_huffman_) {
- QUICHE_DCHECK_EQ(0, byte_ & (1 << field_->param));
- byte_ |= (1 << field_->param);
-
- string_length_ = encoded_size;
- }
-
- state_ = State::kVarintEncode;
-}
-
-void QpackInstructionEncoder::DoWriteString(absl::string_view name,
- absl::string_view value,
- std::string* output) {
- QUICHE_DCHECK(field_->type == QpackInstructionFieldType::kName ||
- field_->type == QpackInstructionFieldType::kValue);
-
- absl::string_view string_to_write =
- (field_->type == QpackInstructionFieldType::kName) ? name : value;
- if (use_huffman_) {
- http2::HuffmanEncodeFast(string_to_write, string_length_, output);
- } else {
- absl::StrAppend(output, string_to_write);
- }
-
- ++field_;
- state_ = State::kStartField;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_instruction_encoder.h b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_instruction_encoder.h
deleted file mode 100644
index 66a76eaded9..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_instruction_encoder.h
+++ /dev/null
@@ -1,84 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QPACK_QPACK_INSTRUCTION_ENCODER_H_
-#define QUICHE_QUIC_CORE_QPACK_QPACK_INSTRUCTION_ENCODER_H_
-
-#include <cstdint>
-#include <string>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/qpack/qpack_instructions.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// Generic instruction encoder class. Takes a QpackLanguage that describes a
-// language, that is, a set of instruction opcodes together with a list of
-// fields that follow each instruction.
-class QUIC_EXPORT_PRIVATE QpackInstructionEncoder {
- public:
- QpackInstructionEncoder();
- QpackInstructionEncoder(const QpackInstructionEncoder&) = delete;
- QpackInstructionEncoder& operator=(const QpackInstructionEncoder&) = delete;
-
- // Append encoded instruction to |output|.
- void Encode(const QpackInstructionWithValues& instruction_with_values,
- std::string* output);
-
- private:
- enum class State {
- // Write instruction opcode to |byte_|.
- kOpcode,
- // Select state based on type of current field.
- kStartField,
- // Write static bit to |byte_|.
- kSbit,
- // Encode an integer (|varint_| or |varint2_| or string length) with a
- // prefix, using |byte_| for the high bits.
- kVarintEncode,
- // Determine if Huffman encoding should be used for the header name or
- // value, set |use_huffman_| and |string_length_| appropriately, write the
- // Huffman bit to |byte_|.
- kStartString,
- // Write header name or value, performing Huffman encoding if |use_huffman_|
- // is true.
- kWriteString
- };
-
- // One method for each state. Some append encoded bytes to |output|.
- // Some only change internal state.
- void DoOpcode();
- void DoStartField();
- void DoSBit(bool s_bit);
- void DoVarintEncode(uint64_t varint, uint64_t varint2, std::string* output);
- void DoStartString(absl::string_view name, absl::string_view value);
- void DoWriteString(absl::string_view name,
- absl::string_view value,
- std::string* output);
-
- // True if name or value should be Huffman encoded.
- bool use_huffman_;
-
- // Length of name or value string to be written.
- // If |use_huffman_| is true, length is after Huffman encoding.
- size_t string_length_;
-
- // Storage for a single byte that contains multiple fields, that is, multiple
- // states are writing it.
- uint8_t byte_;
-
- // Encoding state.
- State state_;
-
- // Instruction currently being decoded.
- const QpackInstruction* instruction_;
-
- // Field currently being decoded.
- QpackInstructionFields::const_iterator field_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_QPACK_QPACK_INSTRUCTION_ENCODER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_instruction_encoder_test.cc b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_instruction_encoder_test.cc
deleted file mode 100644
index c84634b1321..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_instruction_encoder_test.cc
+++ /dev/null
@@ -1,204 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/qpack/qpack_instruction_encoder.h"
-
-#include "absl/strings/escaping.h"
-#include "absl/strings/string_view.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/platform/api/quic_test.h"
-
-namespace quic {
-namespace test {
-
-class QpackInstructionWithValuesPeer {
- public:
- static QpackInstructionWithValues CreateQpackInstructionWithValues(
- const QpackInstruction* instruction) {
- QpackInstructionWithValues instruction_with_values;
- instruction_with_values.instruction_ = instruction;
- return instruction_with_values;
- }
-
- static void set_s_bit(QpackInstructionWithValues* instruction_with_values,
- bool s_bit) {
- instruction_with_values->s_bit_ = s_bit;
- }
-
- static void set_varint(QpackInstructionWithValues* instruction_with_values,
- uint64_t varint) {
- instruction_with_values->varint_ = varint;
- }
-
- static void set_varint2(QpackInstructionWithValues* instruction_with_values,
- uint64_t varint2) {
- instruction_with_values->varint2_ = varint2;
- }
-
- static void set_name(QpackInstructionWithValues* instruction_with_values,
- absl::string_view name) {
- instruction_with_values->name_ = name;
- }
-
- static void set_value(QpackInstructionWithValues* instruction_with_values,
- absl::string_view value) {
- instruction_with_values->value_ = value;
- }
-};
-
-namespace {
-
-class QpackInstructionEncoderTest : public QuicTest {
- protected:
- QpackInstructionEncoderTest() : verified_position_(0) {}
- ~QpackInstructionEncoderTest() override = default;
-
- // Append encoded |instruction| to |output_|.
- void EncodeInstruction(
- const QpackInstructionWithValues& instruction_with_values) {
- encoder_.Encode(instruction_with_values, &output_);
- }
-
- // Compare substring appended to |output_| since last EncodedSegmentMatches()
- // call against hex-encoded argument.
- bool EncodedSegmentMatches(absl::string_view hex_encoded_expected_substring) {
- auto recently_encoded =
- absl::string_view(output_).substr(verified_position_);
- auto expected = absl::HexStringToBytes(hex_encoded_expected_substring);
- verified_position_ = output_.size();
- return recently_encoded == expected;
- }
-
- private:
- QpackInstructionEncoder encoder_;
- std::string output_;
- std::string::size_type verified_position_;
-};
-
-TEST_F(QpackInstructionEncoderTest, Varint) {
- const QpackInstruction instruction{QpackInstructionOpcode{0x00, 0x80},
- {{QpackInstructionFieldType::kVarint, 7}}};
-
- auto instruction_with_values =
- QpackInstructionWithValuesPeer::CreateQpackInstructionWithValues(
- &instruction);
- QpackInstructionWithValuesPeer::set_varint(&instruction_with_values, 5);
- EncodeInstruction(instruction_with_values);
- EXPECT_TRUE(EncodedSegmentMatches("05"));
-
- QpackInstructionWithValuesPeer::set_varint(&instruction_with_values, 127);
- EncodeInstruction(instruction_with_values);
- EXPECT_TRUE(EncodedSegmentMatches("7f00"));
-}
-
-TEST_F(QpackInstructionEncoderTest, SBitAndTwoVarint2) {
- const QpackInstruction instruction{
- QpackInstructionOpcode{0x80, 0xc0},
- {{QpackInstructionFieldType::kSbit, 0x20},
- {QpackInstructionFieldType::kVarint, 5},
- {QpackInstructionFieldType::kVarint2, 8}}};
-
- auto instruction_with_values =
- QpackInstructionWithValuesPeer::CreateQpackInstructionWithValues(
- &instruction);
- QpackInstructionWithValuesPeer::set_s_bit(&instruction_with_values, true);
- QpackInstructionWithValuesPeer::set_varint(&instruction_with_values, 5);
- QpackInstructionWithValuesPeer::set_varint2(&instruction_with_values, 200);
- EncodeInstruction(instruction_with_values);
- EXPECT_TRUE(EncodedSegmentMatches("a5c8"));
-
- QpackInstructionWithValuesPeer::set_s_bit(&instruction_with_values, false);
- QpackInstructionWithValuesPeer::set_varint(&instruction_with_values, 31);
- QpackInstructionWithValuesPeer::set_varint2(&instruction_with_values, 356);
- EncodeInstruction(instruction_with_values);
- EXPECT_TRUE(EncodedSegmentMatches("9f00ff65"));
-}
-
-TEST_F(QpackInstructionEncoderTest, SBitAndVarintAndValue) {
- const QpackInstruction instruction{QpackInstructionOpcode{0xc0, 0xc0},
- {{QpackInstructionFieldType::kSbit, 0x20},
- {QpackInstructionFieldType::kVarint, 5},
- {QpackInstructionFieldType::kValue, 7}}};
-
- auto instruction_with_values =
- QpackInstructionWithValuesPeer::CreateQpackInstructionWithValues(
- &instruction);
- QpackInstructionWithValuesPeer::set_s_bit(&instruction_with_values, true);
- QpackInstructionWithValuesPeer::set_varint(&instruction_with_values, 100);
- QpackInstructionWithValuesPeer::set_value(&instruction_with_values, "foo");
- EncodeInstruction(instruction_with_values);
- EXPECT_TRUE(EncodedSegmentMatches("ff458294e7"));
-
- QpackInstructionWithValuesPeer::set_s_bit(&instruction_with_values, false);
- QpackInstructionWithValuesPeer::set_varint(&instruction_with_values, 3);
- QpackInstructionWithValuesPeer::set_value(&instruction_with_values, "bar");
- EncodeInstruction(instruction_with_values);
- EXPECT_TRUE(EncodedSegmentMatches("c303626172"));
-}
-
-TEST_F(QpackInstructionEncoderTest, Name) {
- const QpackInstruction instruction{QpackInstructionOpcode{0xe0, 0xe0},
- {{QpackInstructionFieldType::kName, 4}}};
-
- auto instruction_with_values =
- QpackInstructionWithValuesPeer::CreateQpackInstructionWithValues(
- &instruction);
- QpackInstructionWithValuesPeer::set_name(&instruction_with_values, "");
- EncodeInstruction(instruction_with_values);
- EXPECT_TRUE(EncodedSegmentMatches("e0"));
-
- QpackInstructionWithValuesPeer::set_name(&instruction_with_values, "foo");
- EncodeInstruction(instruction_with_values);
- EXPECT_TRUE(EncodedSegmentMatches("f294e7"));
-
- QpackInstructionWithValuesPeer::set_name(&instruction_with_values, "bar");
- EncodeInstruction(instruction_with_values);
- EXPECT_TRUE(EncodedSegmentMatches("e3626172"));
-}
-
-TEST_F(QpackInstructionEncoderTest, Value) {
- const QpackInstruction instruction{QpackInstructionOpcode{0xf0, 0xf0},
- {{QpackInstructionFieldType::kValue, 3}}};
-
- auto instruction_with_values =
- QpackInstructionWithValuesPeer::CreateQpackInstructionWithValues(
- &instruction);
- QpackInstructionWithValuesPeer::set_value(&instruction_with_values, "");
- EncodeInstruction(instruction_with_values);
- EXPECT_TRUE(EncodedSegmentMatches("f0"));
-
- QpackInstructionWithValuesPeer::set_value(&instruction_with_values, "foo");
- EncodeInstruction(instruction_with_values);
- EXPECT_TRUE(EncodedSegmentMatches("fa94e7"));
-
- QpackInstructionWithValuesPeer::set_value(&instruction_with_values, "bar");
- EncodeInstruction(instruction_with_values);
- EXPECT_TRUE(EncodedSegmentMatches("f3626172"));
-}
-
-TEST_F(QpackInstructionEncoderTest, SBitAndNameAndValue) {
- const QpackInstruction instruction{QpackInstructionOpcode{0xf0, 0xf0},
- {{QpackInstructionFieldType::kSbit, 0x08},
- {QpackInstructionFieldType::kName, 2},
- {QpackInstructionFieldType::kValue, 7}}};
-
- auto instruction_with_values =
- QpackInstructionWithValuesPeer::CreateQpackInstructionWithValues(
- &instruction);
- QpackInstructionWithValuesPeer::set_s_bit(&instruction_with_values, false);
- QpackInstructionWithValuesPeer::set_name(&instruction_with_values, "");
- QpackInstructionWithValuesPeer::set_value(&instruction_with_values, "");
- EncodeInstruction(instruction_with_values);
- EXPECT_TRUE(EncodedSegmentMatches("f000"));
-
- QpackInstructionWithValuesPeer::set_s_bit(&instruction_with_values, true);
- QpackInstructionWithValuesPeer::set_name(&instruction_with_values, "foo");
- QpackInstructionWithValuesPeer::set_value(&instruction_with_values, "bar");
- EncodeInstruction(instruction_with_values);
- EXPECT_TRUE(EncodedSegmentMatches("fe94e703626172"));
-}
-
-} // namespace
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_instructions.cc b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_instructions.cc
deleted file mode 100644
index 7f95762431e..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_instructions.cc
+++ /dev/null
@@ -1,333 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/qpack/qpack_instructions.h"
-
-#include <limits>
-
-#include "absl/strings/string_view.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-namespace {
-
-// Validate that
-// * in each instruction, the bits of |value| that are zero in |mask| are zero;
-// * every byte matches exactly one opcode.
-void ValidateLangague(const QpackLanguage* language) {
-#ifndef NDEBUG
- for (const auto* instruction : *language) {
- QUICHE_DCHECK_EQ(0, instruction->opcode.value & ~instruction->opcode.mask);
- }
-
- for (uint8_t byte = 0; byte < std::numeric_limits<uint8_t>::max(); ++byte) {
- size_t match_count = 0;
- for (const auto* instruction : *language) {
- if ((byte & instruction->opcode.mask) == instruction->opcode.value) {
- ++match_count;
- }
- }
- QUICHE_DCHECK_EQ(1u, match_count) << static_cast<int>(byte);
- }
-#else
- (void)language;
-#endif
-}
-
-} // namespace
-
-bool operator==(const QpackInstructionOpcode& a,
- const QpackInstructionOpcode& b) {
- return std::tie(a.value, a.mask) == std::tie(b.value, b.mask);
-}
-
-const QpackInstruction* InsertWithNameReferenceInstruction() {
- static const QpackInstructionOpcode* const opcode =
- new QpackInstructionOpcode{0b10000000, 0b10000000};
- static const QpackInstruction* const instruction =
- new QpackInstruction{*opcode,
- {{QpackInstructionFieldType::kSbit, 0b01000000},
- {QpackInstructionFieldType::kVarint, 6},
- {QpackInstructionFieldType::kValue, 7}}};
- return instruction;
-}
-
-const QpackInstruction* InsertWithoutNameReferenceInstruction() {
- static const QpackInstructionOpcode* const opcode =
- new QpackInstructionOpcode{0b01000000, 0b11000000};
- static const QpackInstruction* const instruction =
- new QpackInstruction{*opcode,
- {{QpackInstructionFieldType::kName, 5},
- {QpackInstructionFieldType::kValue, 7}}};
- return instruction;
-}
-
-const QpackInstruction* DuplicateInstruction() {
- static const QpackInstructionOpcode* const opcode =
- new QpackInstructionOpcode{0b00000000, 0b11100000};
- static const QpackInstruction* const instruction =
- new QpackInstruction{*opcode, {{QpackInstructionFieldType::kVarint, 5}}};
- return instruction;
-}
-
-const QpackInstruction* SetDynamicTableCapacityInstruction() {
- static const QpackInstructionOpcode* const opcode =
- new QpackInstructionOpcode{0b00100000, 0b11100000};
- static const QpackInstruction* const instruction =
- new QpackInstruction{*opcode, {{QpackInstructionFieldType::kVarint, 5}}};
- return instruction;
-}
-
-const QpackLanguage* QpackEncoderStreamLanguage() {
- static const QpackLanguage* const language = new QpackLanguage{
- InsertWithNameReferenceInstruction(),
- InsertWithoutNameReferenceInstruction(), DuplicateInstruction(),
- SetDynamicTableCapacityInstruction()};
- ValidateLangague(language);
- return language;
-}
-
-const QpackInstruction* InsertCountIncrementInstruction() {
- static const QpackInstructionOpcode* const opcode =
- new QpackInstructionOpcode{0b00000000, 0b11000000};
- static const QpackInstruction* const instruction =
- new QpackInstruction{*opcode, {{QpackInstructionFieldType::kVarint, 6}}};
- return instruction;
-}
-
-const QpackInstruction* HeaderAcknowledgementInstruction() {
- static const QpackInstructionOpcode* const opcode =
- new QpackInstructionOpcode{0b10000000, 0b10000000};
- static const QpackInstruction* const instruction =
- new QpackInstruction{*opcode, {{QpackInstructionFieldType::kVarint, 7}}};
- return instruction;
-}
-
-const QpackInstruction* StreamCancellationInstruction() {
- static const QpackInstructionOpcode* const opcode =
- new QpackInstructionOpcode{0b01000000, 0b11000000};
- static const QpackInstruction* const instruction =
- new QpackInstruction{*opcode, {{QpackInstructionFieldType::kVarint, 6}}};
- return instruction;
-}
-
-const QpackLanguage* QpackDecoderStreamLanguage() {
- static const QpackLanguage* const language = new QpackLanguage{
- InsertCountIncrementInstruction(), HeaderAcknowledgementInstruction(),
- StreamCancellationInstruction()};
- ValidateLangague(language);
- return language;
-}
-
-const QpackInstruction* QpackPrefixInstruction() {
- // This opcode matches every input.
- static const QpackInstructionOpcode* const opcode =
- new QpackInstructionOpcode{0b00000000, 0b00000000};
- static const QpackInstruction* const instruction =
- new QpackInstruction{*opcode,
- {{QpackInstructionFieldType::kVarint, 8},
- {QpackInstructionFieldType::kSbit, 0b10000000},
- {QpackInstructionFieldType::kVarint2, 7}}};
- return instruction;
-}
-
-const QpackLanguage* QpackPrefixLanguage() {
- static const QpackLanguage* const language =
- new QpackLanguage{QpackPrefixInstruction()};
- ValidateLangague(language);
- return language;
-}
-
-const QpackInstruction* QpackIndexedHeaderFieldInstruction() {
- static const QpackInstructionOpcode* const opcode =
- new QpackInstructionOpcode{0b10000000, 0b10000000};
- static const QpackInstruction* const instruction =
- new QpackInstruction{*opcode,
- {{QpackInstructionFieldType::kSbit, 0b01000000},
- {QpackInstructionFieldType::kVarint, 6}}};
- return instruction;
-}
-
-const QpackInstruction* QpackIndexedHeaderFieldPostBaseInstruction() {
- static const QpackInstructionOpcode* const opcode =
- new QpackInstructionOpcode{0b00010000, 0b11110000};
- static const QpackInstruction* const instruction =
- new QpackInstruction{*opcode, {{QpackInstructionFieldType::kVarint, 4}}};
- return instruction;
-}
-
-const QpackInstruction* QpackLiteralHeaderFieldNameReferenceInstruction() {
- static const QpackInstructionOpcode* const opcode =
- new QpackInstructionOpcode{0b01000000, 0b11000000};
- static const QpackInstruction* const instruction =
- new QpackInstruction{*opcode,
- {{QpackInstructionFieldType::kSbit, 0b00010000},
- {QpackInstructionFieldType::kVarint, 4},
- {QpackInstructionFieldType::kValue, 7}}};
- return instruction;
-}
-
-const QpackInstruction* QpackLiteralHeaderFieldPostBaseInstruction() {
- static const QpackInstructionOpcode* const opcode =
- new QpackInstructionOpcode{0b00000000, 0b11110000};
- static const QpackInstruction* const instruction =
- new QpackInstruction{*opcode,
- {{QpackInstructionFieldType::kVarint, 3},
- {QpackInstructionFieldType::kValue, 7}}};
- return instruction;
-}
-
-const QpackInstruction* QpackLiteralHeaderFieldInstruction() {
- static const QpackInstructionOpcode* const opcode =
- new QpackInstructionOpcode{0b00100000, 0b11100000};
- static const QpackInstruction* const instruction =
- new QpackInstruction{*opcode,
- {{QpackInstructionFieldType::kName, 3},
- {QpackInstructionFieldType::kValue, 7}}};
- return instruction;
-}
-
-const QpackLanguage* QpackRequestStreamLanguage() {
- static const QpackLanguage* const language =
- new QpackLanguage{QpackIndexedHeaderFieldInstruction(),
- QpackIndexedHeaderFieldPostBaseInstruction(),
- QpackLiteralHeaderFieldNameReferenceInstruction(),
- QpackLiteralHeaderFieldPostBaseInstruction(),
- QpackLiteralHeaderFieldInstruction()};
- ValidateLangague(language);
- return language;
-}
-
-// static
-QpackInstructionWithValues QpackInstructionWithValues::InsertWithNameReference(
- bool is_static,
- uint64_t name_index,
- absl::string_view value) {
- QpackInstructionWithValues instruction_with_values;
- instruction_with_values.instruction_ = InsertWithNameReferenceInstruction();
- instruction_with_values.s_bit_ = is_static;
- instruction_with_values.varint_ = name_index;
- instruction_with_values.value_ = value;
-
- return instruction_with_values;
-}
-
-// static
-QpackInstructionWithValues
-QpackInstructionWithValues::InsertWithoutNameReference(
- absl::string_view name,
- absl::string_view value) {
- QpackInstructionWithValues instruction_with_values;
- instruction_with_values.instruction_ =
- InsertWithoutNameReferenceInstruction();
- instruction_with_values.name_ = name;
- instruction_with_values.value_ = value;
-
- return instruction_with_values;
-}
-
-// static
-QpackInstructionWithValues QpackInstructionWithValues::Duplicate(
- uint64_t index) {
- QpackInstructionWithValues instruction_with_values;
- instruction_with_values.instruction_ = DuplicateInstruction();
- instruction_with_values.varint_ = index;
-
- return instruction_with_values;
-}
-
-// static
-QpackInstructionWithValues QpackInstructionWithValues::SetDynamicTableCapacity(
- uint64_t capacity) {
- QpackInstructionWithValues instruction_with_values;
- instruction_with_values.instruction_ = SetDynamicTableCapacityInstruction();
- instruction_with_values.varint_ = capacity;
-
- return instruction_with_values;
-}
-
-// static
-QpackInstructionWithValues QpackInstructionWithValues::InsertCountIncrement(
- uint64_t increment) {
- QpackInstructionWithValues instruction_with_values;
- instruction_with_values.instruction_ = InsertCountIncrementInstruction();
- instruction_with_values.varint_ = increment;
-
- return instruction_with_values;
-}
-
-// static
-QpackInstructionWithValues QpackInstructionWithValues::HeaderAcknowledgement(
- uint64_t stream_id) {
- QpackInstructionWithValues instruction_with_values;
- instruction_with_values.instruction_ = HeaderAcknowledgementInstruction();
- instruction_with_values.varint_ = stream_id;
-
- return instruction_with_values;
-}
-
-// static
-QpackInstructionWithValues QpackInstructionWithValues::StreamCancellation(
- uint64_t stream_id) {
- QpackInstructionWithValues instruction_with_values;
- instruction_with_values.instruction_ = StreamCancellationInstruction();
- instruction_with_values.varint_ = stream_id;
-
- return instruction_with_values;
-}
-
-// static
-QpackInstructionWithValues QpackInstructionWithValues::Prefix(
- uint64_t required_insert_count) {
- QpackInstructionWithValues instruction_with_values;
- instruction_with_values.instruction_ = QpackPrefixInstruction();
- instruction_with_values.varint_ = required_insert_count;
- instruction_with_values.varint2_ = 0; // Delta Base.
- instruction_with_values.s_bit_ = false; // Delta Base sign.
-
- return instruction_with_values;
-}
-
-// static
-QpackInstructionWithValues QpackInstructionWithValues::IndexedHeaderField(
- bool is_static,
- uint64_t index) {
- QpackInstructionWithValues instruction_with_values;
- instruction_with_values.instruction_ = QpackIndexedHeaderFieldInstruction();
- instruction_with_values.s_bit_ = is_static;
- instruction_with_values.varint_ = index;
-
- return instruction_with_values;
-}
-
-// static
-QpackInstructionWithValues
-QpackInstructionWithValues::LiteralHeaderFieldNameReference(
- bool is_static,
- uint64_t index,
- absl::string_view value) {
- QpackInstructionWithValues instruction_with_values;
- instruction_with_values.instruction_ =
- QpackLiteralHeaderFieldNameReferenceInstruction();
- instruction_with_values.s_bit_ = is_static;
- instruction_with_values.varint_ = index;
- instruction_with_values.value_ = value;
-
- return instruction_with_values;
-}
-
-// static
-QpackInstructionWithValues QpackInstructionWithValues::LiteralHeaderField(
- absl::string_view name,
- absl::string_view value) {
- QpackInstructionWithValues instruction_with_values;
- instruction_with_values.instruction_ = QpackLiteralHeaderFieldInstruction();
- instruction_with_values.name_ = name;
- instruction_with_values.value_ = value;
-
- return instruction_with_values;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_instructions.h b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_instructions.h
deleted file mode 100644
index 56613de370e..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_instructions.h
+++ /dev/null
@@ -1,207 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QPACK_QPACK_INSTRUCTIONS_H_
-#define QUICHE_QUIC_CORE_QPACK_QPACK_INSTRUCTIONS_H_
-
-#include <cstdint>
-#include <string>
-#include <tuple>
-#include <vector>
-
-#include "absl/strings/string_view.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-namespace test {
-class QpackInstructionWithValuesPeer;
-} // namespace test
-
-// Each instruction is identified with an opcode in the first byte.
-// |mask| determines which bits are part of the opcode.
-// |value| is the value of these bits. (Other bits in value must be zero.)
-struct QUIC_EXPORT_PRIVATE QpackInstructionOpcode {
- uint8_t value;
- uint8_t mask;
-};
-
-bool operator==(const QpackInstructionOpcode& a,
- const QpackInstructionOpcode& b);
-
-// Possible types of an instruction field. Decoding a static bit does not
-// consume the current byte. Decoding an integer or a length-prefixed string
-// literal consumes all bytes containing the field value.
-enum class QpackInstructionFieldType {
- // A single bit indicating whether the index refers to the static table, or
- // indicating the sign of Delta Base. Called "S" bit because both "static"
- // and "sign" start with the letter "S".
- kSbit,
- // An integer encoded with variable length encoding. This could be an index,
- // stream ID, maximum size, or Encoded Required Insert Count.
- kVarint,
- // A second integer encoded with variable length encoding. This could be
- // Delta Base.
- kVarint2,
- // A header name or header value encoded as:
- // a bit indicating whether it is Huffman encoded;
- // the encoded length of the string;
- // the header name or value optionally Huffman encoded.
- kName,
- kValue
-};
-
-// Each instruction field has a type and a parameter.
-// The meaning of the parameter depends on the field type.
-struct QUIC_EXPORT_PRIVATE QpackInstructionField {
- QpackInstructionFieldType type;
- // For a kSbit field, |param| is a mask with exactly one bit set.
- // For kVarint fields, |param| is the prefix length of the integer encoding.
- // For kName and kValue fields, |param| is the prefix length of the length of
- // the string, and the bit immediately preceding the prefix is interpreted as
- // the Huffman bit.
- uint8_t param;
-};
-
-using QpackInstructionFields = std::vector<QpackInstructionField>;
-
-// A QPACK instruction consists of an opcode identifying the instruction,
-// followed by a non-empty list of fields. The last field must be integer or
-// string literal type to guarantee that all bytes of the instruction are
-// consumed.
-struct QUIC_EXPORT_PRIVATE QpackInstruction {
- QpackInstruction(const QpackInstruction&) = delete;
- const QpackInstruction& operator=(const QpackInstruction&) = delete;
-
- QpackInstructionOpcode opcode;
- QpackInstructionFields fields;
-};
-
-// A language is a collection of instructions. The order does not matter.
-// Every possible input must match exactly one instruction.
-using QpackLanguage = std::vector<const QpackInstruction*>;
-
-// Wire format defined in
-// https://quicwg.org/base-drafts/draft-ietf-quic-qpack.html#rfc.section.5
-
-// 5.2 Encoder stream instructions
-
-// 5.2.1 Insert With Name Reference
-const QpackInstruction* InsertWithNameReferenceInstruction();
-
-// 5.2.2 Insert Without Name Reference
-const QpackInstruction* InsertWithoutNameReferenceInstruction();
-
-// 5.2.3 Duplicate
-const QpackInstruction* DuplicateInstruction();
-
-// 5.2.4 Dynamic Table Size Update
-const QpackInstruction* SetDynamicTableCapacityInstruction();
-
-// Encoder stream language.
-const QpackLanguage* QpackEncoderStreamLanguage();
-
-// 5.3 Decoder stream instructions
-
-// 5.3.1 Insert Count Increment
-const QpackInstruction* InsertCountIncrementInstruction();
-
-// 5.3.2 Header Acknowledgement
-const QpackInstruction* HeaderAcknowledgementInstruction();
-
-// 5.3.3 Stream Cancellation
-const QpackInstruction* StreamCancellationInstruction();
-
-// Decoder stream language.
-const QpackLanguage* QpackDecoderStreamLanguage();
-
-// 5.4.1. Header data prefix instructions
-
-const QpackInstruction* QpackPrefixInstruction();
-
-const QpackLanguage* QpackPrefixLanguage();
-
-// 5.4.2. Request and push stream instructions
-
-// 5.4.2.1. Indexed Header Field
-const QpackInstruction* QpackIndexedHeaderFieldInstruction();
-
-// 5.4.2.2. Indexed Header Field With Post-Base Index
-const QpackInstruction* QpackIndexedHeaderFieldPostBaseInstruction();
-
-// 5.4.2.3. Literal Header Field With Name Reference
-const QpackInstruction* QpackLiteralHeaderFieldNameReferenceInstruction();
-
-// 5.4.2.4. Literal Header Field With Post-Base Name Reference
-const QpackInstruction* QpackLiteralHeaderFieldPostBaseInstruction();
-
-// 5.4.2.5. Literal Header Field Without Name Reference
-const QpackInstruction* QpackLiteralHeaderFieldInstruction();
-
-// Request and push stream language.
-const QpackLanguage* QpackRequestStreamLanguage();
-
-// Storage for instruction and field values to be encoded.
-// This class can only be instantiated using factory methods that take exactly
-// the arguments that the corresponding instruction needs.
-class QUIC_EXPORT_PRIVATE QpackInstructionWithValues {
- public:
- // 5.2 Encoder stream instructions
- static QpackInstructionWithValues InsertWithNameReference(
- bool is_static,
- uint64_t name_index,
- absl::string_view value);
- static QpackInstructionWithValues InsertWithoutNameReference(
- absl::string_view name,
- absl::string_view value);
- static QpackInstructionWithValues Duplicate(uint64_t index);
- static QpackInstructionWithValues SetDynamicTableCapacity(uint64_t capacity);
-
- // 5.3 Decoder stream instructions
- static QpackInstructionWithValues InsertCountIncrement(uint64_t increment);
- static QpackInstructionWithValues HeaderAcknowledgement(uint64_t stream_id);
- static QpackInstructionWithValues StreamCancellation(uint64_t stream_id);
-
- // 5.4.1. Header data prefix. Delta Base is hardcoded to be zero.
- static QpackInstructionWithValues Prefix(uint64_t required_insert_count);
-
- // 5.4.2. Request and push stream instructions
- static QpackInstructionWithValues IndexedHeaderField(bool is_static,
- uint64_t index);
- static QpackInstructionWithValues LiteralHeaderFieldNameReference(
- bool is_static,
- uint64_t index,
- absl::string_view value);
- static QpackInstructionWithValues LiteralHeaderField(absl::string_view name,
- absl::string_view value);
-
- const QpackInstruction* instruction() const { return instruction_; }
- bool s_bit() const { return s_bit_; }
- uint64_t varint() const { return varint_; }
- uint64_t varint2() const { return varint2_; }
- absl::string_view name() const { return name_; }
- absl::string_view value() const { return value_; }
-
- // Used by QpackEncoder, because in the first pass it stores absolute indices,
- // which are converted into relative indices in the second pass after base is
- // determined.
- void set_varint(uint64_t varint) { varint_ = varint; }
-
- private:
- friend test::QpackInstructionWithValuesPeer;
-
- QpackInstructionWithValues() = default;
-
- // |*instruction| is not owned.
- const QpackInstruction* instruction_ = nullptr;
- bool s_bit_ = false;
- uint64_t varint_ = 0;
- uint64_t varint2_ = 0;
- absl::string_view name_;
- absl::string_view value_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_QPACK_QPACK_INSTRUCTIONS_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_offline_decoder_bin.cc b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_offline_decoder_bin.cc
deleted file mode 100644
index 20f7a62731b..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_offline_decoder_bin.cc
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <cstddef>
-#include <iostream>
-
-#include "absl/strings/string_view.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/test_tools/qpack/qpack_offline_decoder.h"
-#include "common/platform/api/quiche_command_line_flags.h"
-
-int main(int argc, char* argv[]) {
- const char* usage =
- "Usage: qpack_offline_decoder input_filename expected_headers_filename "
- "....";
- std::vector<std::string> args =
- quiche::QuicheParseCommandLineFlags(usage, argc, argv);
-
- if (args.size() < 2 || args.size() % 2 != 0) {
- quiche::QuichePrintCommandLineFlagHelp(usage);
- return 1;
- }
-
- size_t i;
- size_t success_count = 0;
- for (i = 0; 2 * i < args.size(); ++i) {
- const absl::string_view input_filename(args[2 * i]);
- const absl::string_view expected_headers_filename(args[2 * i + 1]);
-
- // Every file represents a different connection,
- // therefore every file needs a fresh decoding context.
- quic::QpackOfflineDecoder decoder;
- if (decoder.DecodeAndVerifyOfflineData(input_filename,
- expected_headers_filename)) {
- ++success_count;
- }
- }
-
- std::cout << "Processed " << i << " pairs of input files, " << success_count
- << " passed, " << (i - success_count) << " failed." << std::endl;
-
- // Return success if all input files pass.
- return (success_count == i) ? 0 : 1;
-}
diff --git a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_progressive_decoder.cc b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_progressive_decoder.cc
deleted file mode 100644
index 12ad7f6206a..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_progressive_decoder.cc
+++ /dev/null
@@ -1,428 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/qpack/qpack_progressive_decoder.h"
-
-#include <algorithm>
-#include <limits>
-#include <utility>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/qpack/qpack_index_conversions.h"
-#include "quic/core/qpack/qpack_instructions.h"
-#include "quic/core/qpack/qpack_required_insert_count.h"
-#include "quic/platform/api/quic_flag_utils.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-namespace {
-
-// The value argument passed to OnHeaderDecoded() is from an entry in the static
-// table.
-constexpr bool kValueFromStaticTable = true;
-
-} // anonymous namespace
-
-QpackProgressiveDecoder::QpackProgressiveDecoder(
- QuicStreamId stream_id, BlockedStreamLimitEnforcer* enforcer,
- DecodingCompletedVisitor* visitor, QpackDecoderHeaderTable* header_table,
- HeadersHandlerInterface* handler)
- : stream_id_(stream_id),
- prefix_decoder_(std::make_unique<QpackInstructionDecoder>(
- QpackPrefixLanguage(), this)),
- instruction_decoder_(QpackRequestStreamLanguage(), this),
- enforcer_(enforcer),
- visitor_(visitor),
- header_table_(header_table),
- handler_(handler),
- required_insert_count_(0),
- base_(0),
- required_insert_count_so_far_(0),
- prefix_decoded_(false),
- blocked_(false),
- decoding_(true),
- error_detected_(false),
- cancelled_(false) {}
-
-QpackProgressiveDecoder::~QpackProgressiveDecoder() {
- if (blocked_ && !cancelled_) {
- header_table_->UnregisterObserver(required_insert_count_, this);
- }
-}
-
-void QpackProgressiveDecoder::Decode(absl::string_view data) {
- QUICHE_DCHECK(decoding_);
-
- if (data.empty() || error_detected_) {
- return;
- }
-
- // Decode prefix byte by byte until the first (and only) instruction is
- // decoded.
- while (!prefix_decoded_) {
- QUICHE_DCHECK(!blocked_);
-
- if (!prefix_decoder_->Decode(data.substr(0, 1))) {
- return;
- }
-
- // |prefix_decoder_->Decode()| must return false if an error is detected.
- QUICHE_DCHECK(!error_detected_);
-
- data = data.substr(1);
- if (data.empty()) {
- return;
- }
- }
-
- if (blocked_) {
- buffer_.append(data.data(), data.size());
- } else {
- QUICHE_DCHECK(buffer_.empty());
-
- instruction_decoder_.Decode(data);
- }
-}
-
-void QpackProgressiveDecoder::EndHeaderBlock() {
- QUICHE_DCHECK(decoding_);
- decoding_ = false;
-
- if (!blocked_) {
- FinishDecoding();
- }
-}
-
-bool QpackProgressiveDecoder::OnInstructionDecoded(
- const QpackInstruction* instruction) {
- if (instruction == QpackPrefixInstruction()) {
- return DoPrefixInstruction();
- }
-
- QUICHE_DCHECK(prefix_decoded_);
- QUICHE_DCHECK_LE(required_insert_count_,
- header_table_->inserted_entry_count());
-
- if (instruction == QpackIndexedHeaderFieldInstruction()) {
- return DoIndexedHeaderFieldInstruction();
- }
- if (instruction == QpackIndexedHeaderFieldPostBaseInstruction()) {
- return DoIndexedHeaderFieldPostBaseInstruction();
- }
- if (instruction == QpackLiteralHeaderFieldNameReferenceInstruction()) {
- return DoLiteralHeaderFieldNameReferenceInstruction();
- }
- if (instruction == QpackLiteralHeaderFieldPostBaseInstruction()) {
- return DoLiteralHeaderFieldPostBaseInstruction();
- }
- QUICHE_DCHECK_EQ(instruction, QpackLiteralHeaderFieldInstruction());
- return DoLiteralHeaderFieldInstruction();
-}
-
-void QpackProgressiveDecoder::OnInstructionDecodingError(
- QpackInstructionDecoder::ErrorCode /* error_code */,
- absl::string_view error_message) {
- // Ignore |error_code| and always use QUIC_QPACK_DECOMPRESSION_FAILED to avoid
- // having to define a new QuicErrorCode for every instruction decoder error.
- OnError(QUIC_QPACK_DECOMPRESSION_FAILED, error_message);
-}
-
-void QpackProgressiveDecoder::OnInsertCountReachedThreshold() {
- QUICHE_DCHECK(blocked_);
-
- // Clear |blocked_| before calling instruction_decoder_.Decode() below,
- // because that might destroy |this| and ~QpackProgressiveDecoder() needs to
- // know not to call UnregisterObserver().
- blocked_ = false;
- enforcer_->OnStreamUnblocked(stream_id_);
-
- if (!buffer_.empty()) {
- std::string buffer(std::move(buffer_));
- buffer_.clear();
- if (!instruction_decoder_.Decode(buffer)) {
- // |this| might be destroyed.
- return;
- }
- }
-
- if (!decoding_) {
- FinishDecoding();
- }
-}
-
-void QpackProgressiveDecoder::Cancel() {
- cancelled_ = true;
-}
-
-bool QpackProgressiveDecoder::DoIndexedHeaderFieldInstruction() {
- if (!instruction_decoder_.s_bit()) {
- uint64_t absolute_index;
- if (!QpackRequestStreamRelativeIndexToAbsoluteIndex(
- instruction_decoder_.varint(), base_, &absolute_index)) {
- OnError(QUIC_QPACK_DECOMPRESSION_FAILED, "Invalid relative index.");
- return false;
- }
-
- if (absolute_index >= required_insert_count_) {
- OnError(QUIC_QPACK_DECOMPRESSION_FAILED,
- "Absolute Index must be smaller than Required Insert Count.");
- return false;
- }
-
- QUICHE_DCHECK_LT(absolute_index, std::numeric_limits<uint64_t>::max());
- required_insert_count_so_far_ =
- std::max(required_insert_count_so_far_, absolute_index + 1);
-
- auto entry =
- header_table_->LookupEntry(/* is_static = */ false, absolute_index);
- if (!entry) {
- OnError(QUIC_QPACK_DECOMPRESSION_FAILED,
- "Dynamic table entry already evicted.");
- return false;
- }
-
- header_table_->set_dynamic_table_entry_referenced();
- return OnHeaderDecoded(!kValueFromStaticTable, entry->name(),
- entry->value());
- }
-
- auto entry = header_table_->LookupEntry(/* is_static = */ true,
- instruction_decoder_.varint());
- if (!entry) {
- OnError(QUIC_QPACK_DECOMPRESSION_FAILED, "Static table entry not found.");
- return false;
- }
-
- return OnHeaderDecoded(kValueFromStaticTable, entry->name(), entry->value());
-}
-
-bool QpackProgressiveDecoder::DoIndexedHeaderFieldPostBaseInstruction() {
- uint64_t absolute_index;
- if (!QpackPostBaseIndexToAbsoluteIndex(instruction_decoder_.varint(), base_,
- &absolute_index)) {
- OnError(QUIC_QPACK_DECOMPRESSION_FAILED, "Invalid post-base index.");
- return false;
- }
-
- if (absolute_index >= required_insert_count_) {
- OnError(QUIC_QPACK_DECOMPRESSION_FAILED,
- "Absolute Index must be smaller than Required Insert Count.");
- return false;
- }
-
- QUICHE_DCHECK_LT(absolute_index, std::numeric_limits<uint64_t>::max());
- required_insert_count_so_far_ =
- std::max(required_insert_count_so_far_, absolute_index + 1);
-
- auto entry =
- header_table_->LookupEntry(/* is_static = */ false, absolute_index);
- if (!entry) {
- OnError(QUIC_QPACK_DECOMPRESSION_FAILED,
- "Dynamic table entry already evicted.");
- return false;
- }
-
- header_table_->set_dynamic_table_entry_referenced();
- return OnHeaderDecoded(!kValueFromStaticTable, entry->name(), entry->value());
-}
-
-bool QpackProgressiveDecoder::DoLiteralHeaderFieldNameReferenceInstruction() {
- if (!instruction_decoder_.s_bit()) {
- uint64_t absolute_index;
- if (!QpackRequestStreamRelativeIndexToAbsoluteIndex(
- instruction_decoder_.varint(), base_, &absolute_index)) {
- OnError(QUIC_QPACK_DECOMPRESSION_FAILED, "Invalid relative index.");
- return false;
- }
-
- if (absolute_index >= required_insert_count_) {
- OnError(QUIC_QPACK_DECOMPRESSION_FAILED,
- "Absolute Index must be smaller than Required Insert Count.");
- return false;
- }
-
- QUICHE_DCHECK_LT(absolute_index, std::numeric_limits<uint64_t>::max());
- required_insert_count_so_far_ =
- std::max(required_insert_count_so_far_, absolute_index + 1);
-
- auto entry =
- header_table_->LookupEntry(/* is_static = */ false, absolute_index);
- if (!entry) {
- OnError(QUIC_QPACK_DECOMPRESSION_FAILED,
- "Dynamic table entry already evicted.");
- return false;
- }
-
- header_table_->set_dynamic_table_entry_referenced();
- return OnHeaderDecoded(!kValueFromStaticTable, entry->name(),
- instruction_decoder_.value());
- }
-
- auto entry = header_table_->LookupEntry(/* is_static = */ true,
- instruction_decoder_.varint());
- if (!entry) {
- OnError(QUIC_QPACK_DECOMPRESSION_FAILED, "Static table entry not found.");
- return false;
- }
-
- return OnHeaderDecoded(kValueFromStaticTable, entry->name(),
- instruction_decoder_.value());
-}
-
-bool QpackProgressiveDecoder::DoLiteralHeaderFieldPostBaseInstruction() {
- uint64_t absolute_index;
- if (!QpackPostBaseIndexToAbsoluteIndex(instruction_decoder_.varint(), base_,
- &absolute_index)) {
- OnError(QUIC_QPACK_DECOMPRESSION_FAILED, "Invalid post-base index.");
- return false;
- }
-
- if (absolute_index >= required_insert_count_) {
- OnError(QUIC_QPACK_DECOMPRESSION_FAILED,
- "Absolute Index must be smaller than Required Insert Count.");
- return false;
- }
-
- QUICHE_DCHECK_LT(absolute_index, std::numeric_limits<uint64_t>::max());
- required_insert_count_so_far_ =
- std::max(required_insert_count_so_far_, absolute_index + 1);
-
- auto entry =
- header_table_->LookupEntry(/* is_static = */ false, absolute_index);
- if (!entry) {
- OnError(QUIC_QPACK_DECOMPRESSION_FAILED,
- "Dynamic table entry already evicted.");
- return false;
- }
-
- header_table_->set_dynamic_table_entry_referenced();
- return OnHeaderDecoded(!kValueFromStaticTable, entry->name(),
- instruction_decoder_.value());
-}
-
-bool QpackProgressiveDecoder::DoLiteralHeaderFieldInstruction() {
- return OnHeaderDecoded(!kValueFromStaticTable, instruction_decoder_.name(),
- instruction_decoder_.value());
-}
-
-bool QpackProgressiveDecoder::DoPrefixInstruction() {
- QUICHE_DCHECK(!prefix_decoded_);
-
- if (!QpackDecodeRequiredInsertCount(
- prefix_decoder_->varint(), header_table_->max_entries(),
- header_table_->inserted_entry_count(), &required_insert_count_)) {
- OnError(QUIC_QPACK_DECOMPRESSION_FAILED,
- "Error decoding Required Insert Count.");
- return false;
- }
-
- const bool sign = prefix_decoder_->s_bit();
- const uint64_t delta_base = prefix_decoder_->varint2();
- if (!DeltaBaseToBase(sign, delta_base, &base_)) {
- OnError(QUIC_QPACK_DECOMPRESSION_FAILED, "Error calculating Base.");
- return false;
- }
-
- prefix_decoded_ = true;
-
- if (required_insert_count_ > header_table_->inserted_entry_count()) {
- if (!enforcer_->OnStreamBlocked(stream_id_)) {
- OnError(QUIC_QPACK_DECOMPRESSION_FAILED,
- "Limit on number of blocked streams exceeded.");
- return false;
- }
- blocked_ = true;
- header_table_->RegisterObserver(required_insert_count_, this);
- }
-
- return true;
-}
-
-bool QpackProgressiveDecoder::OnHeaderDecoded(bool value_from_static_table,
- absl::string_view name,
- absl::string_view value) {
- // Skip test for static table entries as they are all known to be valid.
- if (!value_from_static_table) {
- // According to Section 10.3 of
- // https://quicwg.org/base-drafts/draft-ietf-quic-http.html,
- // "[...] HTTP/3 can transport field values that are not valid. While most
- // values that can be encoded will not alter field parsing, carriage return
- // (CR, ASCII 0x0d), line feed (LF, ASCII 0x0a), and the zero character
- // (NUL, ASCII 0x00) might be exploited by an attacker if they are
- // translated verbatim. Any request or response that contains a character
- // not permitted in a field value MUST be treated as malformed [...]"
- for (const auto c : value) {
- if (c == '\0' || c == '\n' || c == '\r') {
- OnError(QUIC_INVALID_CHARACTER_IN_FIELD_VALUE,
- "Invalid character in field value.");
- return false;
- }
- }
- }
-
- handler_->OnHeaderDecoded(name, value);
- return true;
-}
-
-void QpackProgressiveDecoder::FinishDecoding() {
- QUICHE_DCHECK(buffer_.empty());
- QUICHE_DCHECK(!blocked_);
- QUICHE_DCHECK(!decoding_);
-
- if (error_detected_) {
- return;
- }
-
- if (!instruction_decoder_.AtInstructionBoundary()) {
- OnError(QUIC_QPACK_DECOMPRESSION_FAILED, "Incomplete header block.");
- return;
- }
-
- if (!prefix_decoded_) {
- OnError(QUIC_QPACK_DECOMPRESSION_FAILED, "Incomplete header data prefix.");
- return;
- }
-
- if (required_insert_count_ != required_insert_count_so_far_) {
- OnError(QUIC_QPACK_DECOMPRESSION_FAILED,
- "Required Insert Count too large.");
- return;
- }
-
- visitor_->OnDecodingCompleted(stream_id_, required_insert_count_);
- handler_->OnDecodingCompleted();
-}
-
-void QpackProgressiveDecoder::OnError(QuicErrorCode error_code,
- absl::string_view error_message) {
- QUICHE_DCHECK(!error_detected_);
-
- error_detected_ = true;
- // Might destroy |this|.
- handler_->OnDecodingErrorDetected(error_code, error_message);
-}
-
-bool QpackProgressiveDecoder::DeltaBaseToBase(bool sign,
- uint64_t delta_base,
- uint64_t* base) {
- if (sign) {
- if (delta_base == std::numeric_limits<uint64_t>::max() ||
- required_insert_count_ < delta_base + 1) {
- return false;
- }
- *base = required_insert_count_ - delta_base - 1;
- return true;
- }
-
- if (delta_base >
- std::numeric_limits<uint64_t>::max() - required_insert_count_) {
- return false;
- }
- *base = required_insert_count_ + delta_base;
- return true;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_progressive_decoder.h b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_progressive_decoder.h
deleted file mode 100644
index c234b313ce5..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_progressive_decoder.h
+++ /dev/null
@@ -1,183 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QPACK_QPACK_PROGRESSIVE_DECODER_H_
-#define QUICHE_QUIC_CORE_QPACK_QPACK_PROGRESSIVE_DECODER_H_
-
-#include <cstdint>
-#include <memory>
-#include <string>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/qpack/qpack_encoder_stream_receiver.h"
-#include "quic/core/qpack/qpack_header_table.h"
-#include "quic/core/qpack/qpack_instruction_decoder.h"
-#include "quic/core/quic_error_codes.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-class QpackDecoderHeaderTable;
-
-// Class to decode a single header block.
-class QUIC_EXPORT_PRIVATE QpackProgressiveDecoder
- : public QpackInstructionDecoder::Delegate,
- public QpackDecoderHeaderTable::Observer {
- public:
- // Interface for receiving decoded header block from the decoder.
- class QUIC_EXPORT_PRIVATE HeadersHandlerInterface {
- public:
- virtual ~HeadersHandlerInterface() {}
-
- // Called when a new header name-value pair is decoded. Multiple values for
- // a given name will be emitted as multiple calls to OnHeader.
- virtual void OnHeaderDecoded(absl::string_view name,
- absl::string_view value) = 0;
-
- // Called when the header block is completely decoded.
- // Indicates the total number of bytes in this block.
- // The decoder will not access the handler after this call.
- // Note that this method might not be called synchronously when the header
- // block is received on the wire, in case decoding is blocked on receiving
- // entries on the encoder stream.
- virtual void OnDecodingCompleted() = 0;
-
- // Called when a decoding error has occurred. No other methods will be
- // called afterwards. Implementations are allowed to destroy
- // the QpackProgressiveDecoder instance synchronously.
- virtual void OnDecodingErrorDetected(QuicErrorCode error_code,
- absl::string_view error_message) = 0;
- };
-
- // Interface for keeping track of blocked streams for the purpose of enforcing
- // the limit communicated to peer via QPACK_BLOCKED_STREAMS settings.
- class QUIC_EXPORT_PRIVATE BlockedStreamLimitEnforcer {
- public:
- virtual ~BlockedStreamLimitEnforcer() {}
-
- // Called when the stream becomes blocked. Returns true if allowed. Returns
- // false if limit is violated, in which case QpackProgressiveDecoder signals
- // an error.
- // Stream must not be already blocked.
- virtual bool OnStreamBlocked(QuicStreamId stream_id) = 0;
-
- // Called when the stream becomes unblocked.
- // Stream must be blocked.
- virtual void OnStreamUnblocked(QuicStreamId stream_id) = 0;
- };
-
- // Visitor to be notified when decoding is completed.
- class QUIC_EXPORT_PRIVATE DecodingCompletedVisitor {
- public:
- virtual ~DecodingCompletedVisitor() = default;
-
- // Called when decoding is completed, with Required Insert Count of the
- // decoded header block. Required Insert Count is defined at
- // https://quicwg.org/base-drafts/draft-ietf-quic-qpack.html#blocked-streams.
- virtual void OnDecodingCompleted(QuicStreamId stream_id,
- uint64_t required_insert_count) = 0;
- };
-
- QpackProgressiveDecoder() = delete;
- QpackProgressiveDecoder(QuicStreamId stream_id,
- BlockedStreamLimitEnforcer* enforcer,
- DecodingCompletedVisitor* visitor,
- QpackDecoderHeaderTable* header_table,
- HeadersHandlerInterface* handler);
- QpackProgressiveDecoder(const QpackProgressiveDecoder&) = delete;
- QpackProgressiveDecoder& operator=(const QpackProgressiveDecoder&) = delete;
- ~QpackProgressiveDecoder() override;
-
- // Provide a data fragment to decode.
- void Decode(absl::string_view data);
-
- // Signal that the entire header block has been received and passed in
- // through Decode(). No methods must be called afterwards.
- void EndHeaderBlock();
-
- // QpackInstructionDecoder::Delegate implementation.
- bool OnInstructionDecoded(const QpackInstruction* instruction) override;
- void OnInstructionDecodingError(QpackInstructionDecoder::ErrorCode error_code,
- absl::string_view error_message) override;
-
- // QpackDecoderHeaderTable::Observer implementation.
- void OnInsertCountReachedThreshold() override;
- void Cancel() override;
-
- private:
- bool DoIndexedHeaderFieldInstruction();
- bool DoIndexedHeaderFieldPostBaseInstruction();
- bool DoLiteralHeaderFieldNameReferenceInstruction();
- bool DoLiteralHeaderFieldPostBaseInstruction();
- bool DoLiteralHeaderFieldInstruction();
- bool DoPrefixInstruction();
-
- // Called when an entry is decoded. Performs validation and calls
- // HeadersHandlerInterface::OnHeaderDecoded() or OnError() as needed. Returns
- // true if header value is valid, false otherwise. Skips validation if
- // |value_from_static_table| is true, because static table entries are always
- // valid.
- bool OnHeaderDecoded(bool value_from_static_table, absl::string_view name,
- absl::string_view value);
-
- // Called as soon as EndHeaderBlock() is called and decoding is not blocked.
- void FinishDecoding();
-
- // Called on error.
- void OnError(QuicErrorCode error_code, absl::string_view error_message);
-
- // Calculates Base from |required_insert_count_|, which must be set before
- // calling this method, and sign bit and Delta Base in the Header Data Prefix,
- // which are passed in as arguments. Returns true on success, false on
- // failure due to overflow/underflow.
- bool DeltaBaseToBase(bool sign, uint64_t delta_base, uint64_t* base);
-
- const QuicStreamId stream_id_;
-
- // |prefix_decoder_| only decodes a handful of bytes then it can be
- // destroyed to conserve memory. |instruction_decoder_|, on the other hand,
- // is used until the entire header block is decoded.
- std::unique_ptr<QpackInstructionDecoder> prefix_decoder_;
- QpackInstructionDecoder instruction_decoder_;
-
- BlockedStreamLimitEnforcer* const enforcer_;
- DecodingCompletedVisitor* const visitor_;
- QpackDecoderHeaderTable* const header_table_;
- HeadersHandlerInterface* const handler_;
-
- // Required Insert Count and Base are decoded from the Header Data Prefix.
- uint64_t required_insert_count_;
- uint64_t base_;
-
- // Required Insert Count is one larger than the largest absolute index of all
- // referenced dynamic table entries, or zero if no dynamic table entries are
- // referenced. |required_insert_count_so_far_| starts out as zero and keeps
- // track of the Required Insert Count based on entries decoded so far.
- // After decoding is completed, it is compared to |required_insert_count_|.
- uint64_t required_insert_count_so_far_;
-
- // False until prefix is fully read and decoded.
- bool prefix_decoded_;
-
- // True if waiting for dynamic table entries to arrive.
- bool blocked_;
-
- // Buffer the entire header block after the prefix while decoding is blocked.
- std::string buffer_;
-
- // True until EndHeaderBlock() is called.
- bool decoding_;
-
- // True if a decoding error has been detected.
- bool error_detected_;
-
- // True if QpackDecoderHeaderTable has been destroyed
- // while decoding is still blocked.
- bool cancelled_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_QPACK_QPACK_PROGRESSIVE_DECODER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_receive_stream.cc b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_receive_stream.cc
deleted file mode 100644
index 1f75919d8f8..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_receive_stream.cc
+++ /dev/null
@@ -1,33 +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 "quic/core/qpack/qpack_receive_stream.h"
-
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_session.h"
-
-namespace quic {
-QpackReceiveStream::QpackReceiveStream(PendingStream* pending,
- QuicSession* session,
- QpackStreamReceiver* receiver)
- : QuicStream(pending, session, /*is_static=*/true), receiver_(receiver) {}
-
-void QpackReceiveStream::OnStreamReset(const QuicRstStreamFrame& /*frame*/) {
- stream_delegate()->OnStreamError(
- QUIC_HTTP_CLOSED_CRITICAL_STREAM,
- "RESET_STREAM received for QPACK receive stream");
-}
-
-void QpackReceiveStream::OnDataAvailable() {
- iovec iov;
- while (!reading_stopped() && sequencer()->GetReadableRegion(&iov)) {
- QUICHE_DCHECK(!sequencer()->IsClosed());
-
- receiver_->Decode(absl::string_view(
- reinterpret_cast<const char*>(iov.iov_base), iov.iov_len));
- sequencer()->MarkConsumed(iov.iov_len);
- }
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_receive_stream.h b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_receive_stream.h
deleted file mode 100644
index 6c04b942e5d..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_receive_stream.h
+++ /dev/null
@@ -1,42 +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_CORE_QPACK_QPACK_RECEIVE_STREAM_H_
-#define QUICHE_QUIC_CORE_QPACK_QPACK_RECEIVE_STREAM_H_
-
-#include "quic/core/qpack/qpack_stream_receiver.h"
-#include "quic/core/quic_stream.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-class QuicSession;
-
-// QPACK 4.2.1 Encoder and Decoder Streams.
-// The QPACK receive stream is peer initiated and is read only.
-class QUIC_EXPORT_PRIVATE QpackReceiveStream : public QuicStream {
- public:
- // Construct receive stream from pending stream, the |pending| object needs
- // to be deleted after the construction.
- QpackReceiveStream(PendingStream* pending,
- QuicSession* session,
- QpackStreamReceiver* receiver);
- QpackReceiveStream(const QpackReceiveStream&) = delete;
- QpackReceiveStream& operator=(const QpackReceiveStream&) = delete;
- ~QpackReceiveStream() override = default;
-
- // Overriding QuicStream::OnStreamReset to make sure QPACK stream is never
- // closed before connection.
- void OnStreamReset(const QuicRstStreamFrame& frame) override;
-
- // Implementation of QuicStream.
- void OnDataAvailable() override;
-
- private:
- QpackStreamReceiver* receiver_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_QPACK_QPACK_RECEIVE_STREAM_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_receive_stream_test.cc b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_receive_stream_test.cc
deleted file mode 100644
index cc0e2513956..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_receive_stream_test.cc
+++ /dev/null
@@ -1,98 +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 "quic/core/qpack/qpack_receive_stream.h"
-
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/quic_spdy_session_peer.h"
-#include "quic/test_tools/quic_test_utils.h"
-
-namespace quic {
-namespace test {
-
-namespace {
-using ::testing::_;
-using ::testing::AnyNumber;
-using ::testing::StrictMock;
-
-struct TestParams {
- TestParams(const ParsedQuicVersion& version, Perspective perspective)
- : version(version), perspective(perspective) {
- QUIC_LOG(INFO) << "TestParams: version: "
- << ParsedQuicVersionToString(version)
- << ", perspective: " << perspective;
- }
-
- TestParams(const TestParams& other)
- : version(other.version), perspective(other.perspective) {}
-
- ParsedQuicVersion version;
- Perspective perspective;
-};
-
-std::vector<TestParams> GetTestParams() {
- std::vector<TestParams> params;
- ParsedQuicVersionVector all_supported_versions = AllSupportedVersions();
- for (const auto& version : AllSupportedVersions()) {
- if (!VersionUsesHttp3(version.transport_version)) {
- continue;
- }
- for (Perspective p : {Perspective::IS_SERVER, Perspective::IS_CLIENT}) {
- params.emplace_back(version, p);
- }
- }
- return params;
-}
-
-class QpackReceiveStreamTest : public QuicTestWithParam<TestParams> {
- public:
- QpackReceiveStreamTest()
- : connection_(new StrictMock<MockQuicConnection>(
- &helper_,
- &alarm_factory_,
- perspective(),
- SupportedVersions(GetParam().version))),
- session_(connection_) {
- EXPECT_CALL(session_, OnCongestionWindowChange(_)).Times(AnyNumber());
- session_.Initialize();
- QuicStreamId id = perspective() == Perspective::IS_SERVER
- ? GetNthClientInitiatedUnidirectionalStreamId(
- session_.transport_version(), 3)
- : GetNthServerInitiatedUnidirectionalStreamId(
- session_.transport_version(), 3);
- char type[] = {0x03};
- QuicStreamFrame data1(id, false, 0, absl::string_view(type, 1));
- session_.OnStreamFrame(data1);
- qpack_receive_stream_ =
- QuicSpdySessionPeer::GetQpackDecoderReceiveStream(&session_);
- }
-
- Perspective perspective() const { return GetParam().perspective; }
-
- MockQuicConnectionHelper helper_;
- MockAlarmFactory alarm_factory_;
- StrictMock<MockQuicConnection>* connection_;
- StrictMock<MockQuicSpdySession> session_;
- QpackReceiveStream* qpack_receive_stream_;
-};
-
-INSTANTIATE_TEST_SUITE_P(Tests,
- QpackReceiveStreamTest,
- ::testing::ValuesIn(GetTestParams()));
-
-TEST_P(QpackReceiveStreamTest, ResetQpackReceiveStream) {
- EXPECT_TRUE(qpack_receive_stream_->is_static());
- QuicRstStreamFrame rst_frame(kInvalidControlFrameId,
- qpack_receive_stream_->id(),
- QUIC_STREAM_CANCELLED, 1234);
- EXPECT_CALL(*connection_,
- CloseConnection(QUIC_HTTP_CLOSED_CRITICAL_STREAM, _, _));
- qpack_receive_stream_->OnStreamReset(rst_frame);
-}
-
-} // namespace
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_required_insert_count.cc b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_required_insert_count.cc
deleted file mode 100644
index 6e17b24d577..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_required_insert_count.cc
+++ /dev/null
@@ -1,71 +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 "quic/core/qpack/qpack_required_insert_count.h"
-
-#include <limits>
-
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-uint64_t QpackEncodeRequiredInsertCount(uint64_t required_insert_count,
- uint64_t max_entries) {
- if (required_insert_count == 0) {
- return 0;
- }
-
- return required_insert_count % (2 * max_entries) + 1;
-}
-
-bool QpackDecodeRequiredInsertCount(uint64_t encoded_required_insert_count,
- uint64_t max_entries,
- uint64_t total_number_of_inserts,
- uint64_t* required_insert_count) {
- if (encoded_required_insert_count == 0) {
- *required_insert_count = 0;
- return true;
- }
-
- // |max_entries| is calculated by dividing an unsigned 64-bit integer by 32,
- // precluding all calculations in this method from overflowing.
- QUICHE_DCHECK_LE(max_entries, std::numeric_limits<uint64_t>::max() / 32);
-
- if (encoded_required_insert_count > 2 * max_entries) {
- return false;
- }
-
- *required_insert_count = encoded_required_insert_count - 1;
- QUICHE_DCHECK_LT(*required_insert_count,
- std::numeric_limits<uint64_t>::max() / 16);
-
- uint64_t current_wrapped = total_number_of_inserts % (2 * max_entries);
- QUICHE_DCHECK_LT(current_wrapped, std::numeric_limits<uint64_t>::max() / 16);
-
- if (current_wrapped >= *required_insert_count + max_entries) {
- // Required Insert Count wrapped around 1 extra time.
- *required_insert_count += 2 * max_entries;
- } else if (current_wrapped + max_entries < *required_insert_count) {
- // Decoder wrapped around 1 extra time.
- current_wrapped += 2 * max_entries;
- }
-
- if (*required_insert_count >
- std::numeric_limits<uint64_t>::max() - total_number_of_inserts) {
- return false;
- }
-
- *required_insert_count += total_number_of_inserts;
-
- // Prevent underflow, also disallow invalid value 0 for Required Insert Count.
- if (current_wrapped >= *required_insert_count) {
- return false;
- }
-
- *required_insert_count -= current_wrapped;
-
- return true;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_required_insert_count.h b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_required_insert_count.h
deleted file mode 100644
index 60b1f83370b..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_required_insert_count.h
+++ /dev/null
@@ -1,33 +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_CORE_QPACK_REQUIRED_INSERT_COUNT_H_
-#define QUICHE_QUIC_CORE_QPACK_REQUIRED_INSERT_COUNT_H_
-
-#include <cstdint>
-
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// Calculate Encoded Required Insert Count from Required Insert Count and
-// MaxEntries according to
-// https://quicwg.org/base-drafts/draft-ietf-quic-qpack.html#ric.
-QUIC_EXPORT_PRIVATE uint64_t
-QpackEncodeRequiredInsertCount(uint64_t required_insert_count,
- uint64_t max_entries);
-
-// Calculate Required Insert Count from Encoded Required Insert Count,
-// MaxEntries, and total number of dynamic table insertions according to
-// https://quicwg.org/base-drafts/draft-ietf-quic-qpack.html#ric. Returns true
-// on success, false on invalid input or overflow/underflow.
-QUIC_EXPORT_PRIVATE bool QpackDecodeRequiredInsertCount(
- uint64_t encoded_required_insert_count,
- uint64_t max_entries,
- uint64_t total_number_of_inserts,
- uint64_t* required_insert_count);
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_QPACK_REQUIRED_INSERT_COUNT_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_required_insert_count_test.cc b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_required_insert_count_test.cc
deleted file mode 100644
index 3fa71468931..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_required_insert_count_test.cc
+++ /dev/null
@@ -1,125 +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 "quic/core/qpack/qpack_required_insert_count.h"
-
-#include "absl/base/macros.h"
-#include "quic/platform/api/quic_test.h"
-
-namespace quic {
-namespace test {
-namespace {
-
-TEST(QpackRequiredInsertCountTest, QpackEncodeRequiredInsertCount) {
- EXPECT_EQ(0u, QpackEncodeRequiredInsertCount(0, 0));
- EXPECT_EQ(0u, QpackEncodeRequiredInsertCount(0, 8));
- EXPECT_EQ(0u, QpackEncodeRequiredInsertCount(0, 1024));
-
- EXPECT_EQ(2u, QpackEncodeRequiredInsertCount(1, 8));
- EXPECT_EQ(5u, QpackEncodeRequiredInsertCount(20, 8));
- EXPECT_EQ(7u, QpackEncodeRequiredInsertCount(106, 10));
-}
-
-// For testing valid decodings, the Encoded Required Insert Count is calculated
-// from Required Insert Count, so that there is an expected value to compare
-// the decoded value against, and so that intricate inequalities can be
-// documented.
-struct {
- uint64_t required_insert_count;
- uint64_t max_entries;
- uint64_t total_number_of_inserts;
-} kTestData[] = {
- // Maximum dynamic table capacity is zero.
- {0, 0, 0},
- // No dynamic entries in header.
- {0, 100, 0},
- {0, 100, 500},
- // Required Insert Count has not wrapped around yet, no entries evicted.
- {15, 100, 25},
- {20, 100, 10},
- // Required Insert Count has not wrapped around yet, some entries evicted.
- {90, 100, 110},
- // Required Insert Count has wrapped around.
- {234, 100, 180},
- // Required Insert Count has wrapped around many times.
- {5678, 100, 5701},
- // Lowest and highest possible Required Insert Count values
- // for given MaxEntries and total number of insertions.
- {401, 100, 500},
- {600, 100, 500}};
-
-TEST(QpackRequiredInsertCountTest, QpackDecodeRequiredInsertCount) {
- for (size_t i = 0; i < ABSL_ARRAYSIZE(kTestData); ++i) {
- const uint64_t required_insert_count = kTestData[i].required_insert_count;
- const uint64_t max_entries = kTestData[i].max_entries;
- const uint64_t total_number_of_inserts =
- kTestData[i].total_number_of_inserts;
-
- if (required_insert_count != 0) {
- // Dynamic entries cannot be referenced if dynamic table capacity is zero.
- ASSERT_LT(0u, max_entries) << i;
- // Entry |total_number_of_inserts - 1 - max_entries| and earlier entries
- // are evicted. Entry |required_insert_count - 1| is referenced. No
- // evicted entry can be referenced.
- ASSERT_LT(total_number_of_inserts, required_insert_count + max_entries)
- << i;
- // Entry |required_insert_count - 1 - max_entries| and earlier entries are
- // evicted, entry |total_number_of_inserts - 1| is the last acknowledged
- // entry. Every evicted entry must be acknowledged.
- ASSERT_LE(required_insert_count, total_number_of_inserts + max_entries)
- << i;
- }
-
- uint64_t encoded_required_insert_count =
- QpackEncodeRequiredInsertCount(required_insert_count, max_entries);
-
- // Initialize to a value different from the expected output to confirm that
- // QpackDecodeRequiredInsertCount() modifies the value of
- // |decoded_required_insert_count|.
- uint64_t decoded_required_insert_count = required_insert_count + 1;
- EXPECT_TRUE(QpackDecodeRequiredInsertCount(
- encoded_required_insert_count, max_entries, total_number_of_inserts,
- &decoded_required_insert_count))
- << i;
-
- EXPECT_EQ(decoded_required_insert_count, required_insert_count) << i;
- }
-}
-
-// Failures are tested with hardcoded values for encoded required insert count,
-// to provide test coverage for values that would never be produced by a well
-// behaved encoding function.
-struct {
- uint64_t encoded_required_insert_count;
- uint64_t max_entries;
- uint64_t total_number_of_inserts;
-} kInvalidTestData[] = {
- // Maximum dynamic table capacity is zero, yet header block
- // claims to have a reference to a dynamic table entry.
- {1, 0, 0},
- {9, 0, 0},
- // Examples from
- // https://github.com/quicwg/base-drafts/issues/2112#issue-389626872.
- {1, 10, 2},
- {18, 10, 2},
- // Encoded Required Insert Count value too small or too large
- // for given MaxEntries and total number of insertions.
- {400, 100, 500},
- {601, 100, 500}};
-
-TEST(QpackRequiredInsertCountTest, DecodeRequiredInsertCountError) {
- for (size_t i = 0; i < ABSL_ARRAYSIZE(kInvalidTestData); ++i) {
- uint64_t decoded_required_insert_count = 0;
- EXPECT_FALSE(QpackDecodeRequiredInsertCount(
- kInvalidTestData[i].encoded_required_insert_count,
- kInvalidTestData[i].max_entries,
- kInvalidTestData[i].total_number_of_inserts,
- &decoded_required_insert_count))
- << i;
- }
-}
-
-} // namespace
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_round_trip_test.cc b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_round_trip_test.cc
deleted file mode 100644
index 35530d01771..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_round_trip_test.cc
+++ /dev/null
@@ -1,137 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <string>
-#include <tuple>
-
-#include "absl/strings/string_view.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/qpack/qpack_decoder_test_utils.h"
-#include "quic/test_tools/qpack/qpack_encoder_test_utils.h"
-#include "quic/test_tools/qpack/qpack_test_utils.h"
-#include "spdy/core/spdy_header_block.h"
-
-using ::testing::Values;
-
-namespace quic {
-namespace test {
-namespace {
-
-class QpackRoundTripTest : public QuicTestWithParam<FragmentMode> {
- public:
- QpackRoundTripTest() = default;
- ~QpackRoundTripTest() override = default;
-
- spdy::Http2HeaderBlock EncodeThenDecode(
- const spdy::Http2HeaderBlock& header_list) {
- NoopDecoderStreamErrorDelegate decoder_stream_error_delegate;
- NoopQpackStreamSenderDelegate encoder_stream_sender_delegate;
- QpackEncoder encoder(&decoder_stream_error_delegate);
- encoder.set_qpack_stream_sender_delegate(&encoder_stream_sender_delegate);
- std::string encoded_header_block =
- encoder.EncodeHeaderList(/* stream_id = */ 1, header_list, nullptr);
-
- TestHeadersHandler handler;
- NoopEncoderStreamErrorDelegate encoder_stream_error_delegate;
- NoopQpackStreamSenderDelegate decoder_stream_sender_delegate;
- // TODO(b/112770235): Test dynamic table and blocked streams.
- QpackDecode(
- /* maximum_dynamic_table_capacity = */ 0,
- /* maximum_blocked_streams = */ 0, &encoder_stream_error_delegate,
- &decoder_stream_sender_delegate, &handler,
- FragmentModeToFragmentSizeGenerator(GetParam()), encoded_header_block);
-
- EXPECT_TRUE(handler.decoding_completed());
- EXPECT_FALSE(handler.decoding_error_detected());
-
- return handler.ReleaseHeaderList();
- }
-};
-
-INSTANTIATE_TEST_SUITE_P(All,
- QpackRoundTripTest,
- Values(FragmentMode::kSingleChunk,
- FragmentMode::kOctetByOctet));
-
-TEST_P(QpackRoundTripTest, Empty) {
- spdy::Http2HeaderBlock header_list;
- spdy::Http2HeaderBlock output = EncodeThenDecode(header_list);
- EXPECT_EQ(header_list, output);
-}
-
-TEST_P(QpackRoundTripTest, EmptyName) {
- spdy::Http2HeaderBlock header_list;
- header_list["foo"] = "bar";
- header_list[""] = "bar";
-
- spdy::Http2HeaderBlock output = EncodeThenDecode(header_list);
- EXPECT_EQ(header_list, output);
-}
-
-TEST_P(QpackRoundTripTest, EmptyValue) {
- spdy::Http2HeaderBlock header_list;
- header_list["foo"] = "";
- header_list[""] = "";
-
- spdy::Http2HeaderBlock output = EncodeThenDecode(header_list);
- EXPECT_EQ(header_list, output);
-}
-
-TEST_P(QpackRoundTripTest, MultipleWithLongEntries) {
- spdy::Http2HeaderBlock header_list;
- header_list["foo"] = "bar";
- header_list[":path"] = "/";
- header_list["foobaar"] = std::string(127, 'Z');
- header_list[std::string(1000, 'b')] = std::string(1000, 'c');
-
- spdy::Http2HeaderBlock output = EncodeThenDecode(header_list);
- EXPECT_EQ(header_list, output);
-}
-
-TEST_P(QpackRoundTripTest, StaticTable) {
- {
- spdy::Http2HeaderBlock header_list;
- header_list[":method"] = "GET";
- header_list["accept-encoding"] = "gzip, deflate";
- header_list["cache-control"] = "";
- header_list["foo"] = "bar";
- header_list[":path"] = "/";
-
- spdy::Http2HeaderBlock output = EncodeThenDecode(header_list);
- EXPECT_EQ(header_list, output);
- }
- {
- spdy::Http2HeaderBlock header_list;
- header_list[":method"] = "POST";
- header_list["accept-encoding"] = "brotli";
- header_list["cache-control"] = "foo";
- header_list["foo"] = "bar";
- header_list[":path"] = "/";
-
- spdy::Http2HeaderBlock output = EncodeThenDecode(header_list);
- EXPECT_EQ(header_list, output);
- }
- {
- spdy::Http2HeaderBlock header_list;
- header_list[":method"] = "CONNECT";
- header_list["accept-encoding"] = "";
- header_list["foo"] = "bar";
- header_list[":path"] = "/";
-
- spdy::Http2HeaderBlock output = EncodeThenDecode(header_list);
- EXPECT_EQ(header_list, output);
- }
-}
-
-TEST_P(QpackRoundTripTest, ValueHasNullCharacter) {
- spdy::Http2HeaderBlock header_list;
- header_list["foo"] = absl::string_view("bar\0bar\0baz", 11);
-
- spdy::Http2HeaderBlock output = EncodeThenDecode(header_list);
- EXPECT_EQ(header_list, output);
-}
-
-} // namespace
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_send_stream.cc b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_send_stream.cc
deleted file mode 100644
index 3e921d860f6..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_send_stream.cc
+++ /dev/null
@@ -1,52 +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 "quic/core/qpack/qpack_send_stream.h"
-
-#include "absl/base/macros.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_session.h"
-
-namespace quic {
-QpackSendStream::QpackSendStream(QuicStreamId id,
- QuicSession* session,
- uint64_t http3_stream_type)
- : QuicStream(id, session, /*is_static = */ true, WRITE_UNIDIRECTIONAL),
- http3_stream_type_(http3_stream_type),
- stream_type_sent_(false) {}
-
-void QpackSendStream::OnStreamReset(const QuicRstStreamFrame& /*frame*/) {
- QUIC_BUG(quic_bug_10805_1)
- << "OnStreamReset() called for write unidirectional stream.";
-}
-
-bool QpackSendStream::OnStopSending(QuicResetStreamError /* code */) {
- stream_delegate()->OnStreamError(
- QUIC_HTTP_CLOSED_CRITICAL_STREAM,
- "STOP_SENDING received for QPACK send stream");
- return false;
-}
-
-void QpackSendStream::WriteStreamData(absl::string_view data) {
- QuicConnection::ScopedPacketFlusher flusher(session()->connection());
- MaybeSendStreamType();
- WriteOrBufferData(data, false, nullptr);
-}
-
-uint64_t QpackSendStream::NumBytesBuffered() const {
- return QuicStream::BufferedDataBytes();
-}
-
-void QpackSendStream::MaybeSendStreamType() {
- if (!stream_type_sent_) {
- char type[sizeof(http3_stream_type_)];
- QuicDataWriter writer(ABSL_ARRAYSIZE(type), type);
- writer.WriteVarInt62(http3_stream_type_);
- WriteOrBufferData(absl::string_view(writer.data(), writer.length()), false,
- nullptr);
- stream_type_sent_ = true;
- }
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_send_stream.h b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_send_stream.h
deleted file mode 100644
index 72dc677ecc7..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_send_stream.h
+++ /dev/null
@@ -1,60 +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_CORE_QPACK_QPACK_SEND_STREAM_H_
-#define QUICHE_QUIC_CORE_QPACK_QPACK_SEND_STREAM_H_
-
-#include <cstdint>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/qpack/qpack_stream_sender_delegate.h"
-#include "quic/core/quic_stream.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-class QuicSession;
-
-// QPACK 4.2.1 Encoder and Decoder Streams.
-// The QPACK send stream is self initiated and is write only.
-class QUIC_EXPORT_PRIVATE QpackSendStream : public QuicStream,
- public QpackStreamSenderDelegate {
- public:
- // |session| can't be nullptr, and the ownership is not passed. |session| owns
- // this stream.
- QpackSendStream(QuicStreamId id,
- QuicSession* session,
- uint64_t http3_stream_type);
- QpackSendStream(const QpackSendStream&) = delete;
- QpackSendStream& operator=(const QpackSendStream&) = delete;
- ~QpackSendStream() override = default;
-
- // Overriding QuicStream::OnStopSending() to make sure QPACK stream is never
- // closed before connection.
- void OnStreamReset(const QuicRstStreamFrame& frame) override;
- bool OnStopSending(QuicResetStreamError code) override;
-
- // The send QPACK stream is write unidirectional, so this method
- // should never be called.
- void OnDataAvailable() override { QUIC_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.
- void WriteStreamData(absl::string_view data) override;
-
- // Return the number of bytes buffered due to underlying stream being blocked.
- uint64_t NumBytesBuffered() const override;
-
- // TODO(b/112770235): Remove this method once QuicStreamIdManager supports
- // creating HTTP/3 unidirectional streams dynamically.
- void MaybeSendStreamType();
-
- private:
- const uint64_t http3_stream_type_;
- bool stream_type_sent_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_QPACK_QPACK_SEND_STREAM_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_send_stream_test.cc b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_send_stream_test.cc
deleted file mode 100644
index 5a98951a630..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_send_stream_test.cc
+++ /dev/null
@@ -1,136 +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 "quic/core/qpack/qpack_send_stream.h"
-
-#include "absl/strings/str_cat.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/crypto/null_encrypter.h"
-#include "quic/core/http/http_constants.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/quic_config_peer.h"
-#include "quic/test_tools/quic_connection_peer.h"
-#include "quic/test_tools/quic_spdy_session_peer.h"
-#include "quic/test_tools/quic_test_utils.h"
-
-namespace quic {
-namespace test {
-
-namespace {
-using ::testing::_;
-using ::testing::AnyNumber;
-using ::testing::Invoke;
-using ::testing::StrictMock;
-
-struct TestParams {
- TestParams(const ParsedQuicVersion& version, Perspective perspective)
- : version(version), perspective(perspective) {
- QUIC_LOG(INFO) << "TestParams: version: "
- << ParsedQuicVersionToString(version)
- << ", perspective: " << perspective;
- }
-
- TestParams(const TestParams& other)
- : version(other.version), perspective(other.perspective) {}
-
- ParsedQuicVersion version;
- Perspective perspective;
-};
-
-// Used by ::testing::PrintToStringParamName().
-std::string PrintToString(const TestParams& tp) {
- return absl::StrCat(
- ParsedQuicVersionToString(tp.version), "_",
- (tp.perspective == Perspective::IS_CLIENT ? "client" : "server"));
-}
-
-std::vector<TestParams> GetTestParams() {
- std::vector<TestParams> params;
- ParsedQuicVersionVector all_supported_versions = AllSupportedVersions();
- for (const auto& version : AllSupportedVersions()) {
- if (!VersionUsesHttp3(version.transport_version)) {
- continue;
- }
- for (Perspective p : {Perspective::IS_SERVER, Perspective::IS_CLIENT}) {
- params.emplace_back(version, p);
- }
- }
- return params;
-}
-
-class QpackSendStreamTest : public QuicTestWithParam<TestParams> {
- public:
- QpackSendStreamTest()
- : connection_(new StrictMock<MockQuicConnection>(
- &helper_,
- &alarm_factory_,
- perspective(),
- SupportedVersions(GetParam().version))),
- session_(connection_) {
- EXPECT_CALL(session_, OnCongestionWindowChange(_)).Times(AnyNumber());
- session_.Initialize();
- connection_->SetEncrypter(
- ENCRYPTION_FORWARD_SECURE,
- std::make_unique<NullEncrypter>(connection_->perspective()));
- if (connection_->version().SupportsAntiAmplificationLimit()) {
- QuicConnectionPeer::SetAddressValidated(connection_);
- }
- QuicConfigPeer::SetReceivedInitialSessionFlowControlWindow(
- session_.config(), kMinimumFlowControlSendWindow);
- QuicConfigPeer::SetReceivedInitialMaxStreamDataBytesUnidirectional(
- session_.config(), kMinimumFlowControlSendWindow);
- QuicConfigPeer::SetReceivedMaxUnidirectionalStreams(session_.config(), 3);
- session_.OnConfigNegotiated();
-
- qpack_send_stream_ =
- QuicSpdySessionPeer::GetQpackDecoderSendStream(&session_);
-
- ON_CALL(session_, WritevData(_, _, _, _, _, _))
- .WillByDefault(Invoke(&session_, &MockQuicSpdySession::ConsumeData));
- }
-
- Perspective perspective() const { return GetParam().perspective; }
-
- MockQuicConnectionHelper helper_;
- MockAlarmFactory alarm_factory_;
- StrictMock<MockQuicConnection>* connection_;
- StrictMock<MockQuicSpdySession> session_;
- QpackSendStream* qpack_send_stream_;
-};
-
-INSTANTIATE_TEST_SUITE_P(Tests,
- QpackSendStreamTest,
- ::testing::ValuesIn(GetTestParams()),
- ::testing::PrintToStringParamName());
-
-TEST_P(QpackSendStreamTest, WriteStreamTypeOnlyFirstTime) {
- std::string data = "data";
- EXPECT_CALL(session_, WritevData(_, 1, _, _, _, _));
- EXPECT_CALL(session_, WritevData(_, data.length(), _, _, _, _));
- qpack_send_stream_->WriteStreamData(absl::string_view(data));
-
- EXPECT_CALL(session_, WritevData(_, data.length(), _, _, _, _));
- qpack_send_stream_->WriteStreamData(absl::string_view(data));
- EXPECT_CALL(session_, WritevData(_, _, _, _, _, _)).Times(0);
- qpack_send_stream_->MaybeSendStreamType();
-}
-
-TEST_P(QpackSendStreamTest, StopSendingQpackStream) {
- EXPECT_CALL(*connection_,
- CloseConnection(QUIC_HTTP_CLOSED_CRITICAL_STREAM, _, _));
- qpack_send_stream_->OnStopSending(
- QuicResetStreamError::FromInternal(QUIC_STREAM_CANCELLED));
-}
-
-TEST_P(QpackSendStreamTest, ReceiveDataOnSendStream) {
- QuicStreamFrame frame(qpack_send_stream_->id(), false, 0, "test");
- EXPECT_CALL(
- *connection_,
- CloseConnection(QUIC_DATA_RECEIVED_ON_WRITE_UNIDIRECTIONAL_STREAM, _, _));
- qpack_send_stream_->OnStreamFrame(frame);
-}
-
-} // namespace
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_static_table.cc b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_static_table.cc
deleted file mode 100644
index 869d09c2cf2..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_static_table.cc
+++ /dev/null
@@ -1,139 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/qpack/qpack_static_table.h"
-
-#include "absl/base/macros.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-// The "constructor" for a QpackStaticEntry that computes the lengths at
-// compile time.
-#define STATIC_ENTRY(name, value) \
- { name, ABSL_ARRAYSIZE(name) - 1, value, ABSL_ARRAYSIZE(value) - 1 }
-
-const std::vector<QpackStaticEntry>& QpackStaticTableVector() {
- static const auto* kQpackStaticTable = new std::vector<QpackStaticEntry>{
- STATIC_ENTRY(":authority", ""), // 0
- STATIC_ENTRY(":path", "/"), // 1
- STATIC_ENTRY("age", "0"), // 2
- STATIC_ENTRY("content-disposition", ""), // 3
- STATIC_ENTRY("content-length", "0"), // 4
- STATIC_ENTRY("cookie", ""), // 5
- STATIC_ENTRY("date", ""), // 6
- STATIC_ENTRY("etag", ""), // 7
- STATIC_ENTRY("if-modified-since", ""), // 8
- STATIC_ENTRY("if-none-match", ""), // 9
- STATIC_ENTRY("last-modified", ""), // 10
- STATIC_ENTRY("link", ""), // 11
- STATIC_ENTRY("location", ""), // 12
- STATIC_ENTRY("referer", ""), // 13
- STATIC_ENTRY("set-cookie", ""), // 14
- STATIC_ENTRY(":method", "CONNECT"), // 15
- STATIC_ENTRY(":method", "DELETE"), // 16
- STATIC_ENTRY(":method", "GET"), // 17
- STATIC_ENTRY(":method", "HEAD"), // 18
- STATIC_ENTRY(":method", "OPTIONS"), // 19
- STATIC_ENTRY(":method", "POST"), // 20
- STATIC_ENTRY(":method", "PUT"), // 21
- STATIC_ENTRY(":scheme", "http"), // 22
- STATIC_ENTRY(":scheme", "https"), // 23
- STATIC_ENTRY(":status", "103"), // 24
- STATIC_ENTRY(":status", "200"), // 25
- STATIC_ENTRY(":status", "304"), // 26
- STATIC_ENTRY(":status", "404"), // 27
- STATIC_ENTRY(":status", "503"), // 28
- STATIC_ENTRY("accept", "*/*"), // 29
- STATIC_ENTRY("accept", "application/dns-message"), // 30
- STATIC_ENTRY("accept-encoding", "gzip, deflate, br"), // 31
- STATIC_ENTRY("accept-ranges", "bytes"), // 32
- STATIC_ENTRY("access-control-allow-headers", "cache-control"), // 33
- STATIC_ENTRY("access-control-allow-headers", "content-type"), // 35
- STATIC_ENTRY("access-control-allow-origin", "*"), // 35
- STATIC_ENTRY("cache-control", "max-age=0"), // 36
- STATIC_ENTRY("cache-control", "max-age=2592000"), // 37
- STATIC_ENTRY("cache-control", "max-age=604800"), // 38
- STATIC_ENTRY("cache-control", "no-cache"), // 39
- STATIC_ENTRY("cache-control", "no-store"), // 40
- STATIC_ENTRY("cache-control", "public, max-age=31536000"), // 41
- STATIC_ENTRY("content-encoding", "br"), // 42
- STATIC_ENTRY("content-encoding", "gzip"), // 43
- STATIC_ENTRY("content-type", "application/dns-message"), // 44
- STATIC_ENTRY("content-type", "application/javascript"), // 45
- STATIC_ENTRY("content-type", "application/json"), // 46
- STATIC_ENTRY("content-type", "application/x-www-form-urlencoded"), // 47
- STATIC_ENTRY("content-type", "image/gif"), // 48
- STATIC_ENTRY("content-type", "image/jpeg"), // 49
- STATIC_ENTRY("content-type", "image/png"), // 50
- STATIC_ENTRY("content-type", "text/css"), // 51
- STATIC_ENTRY("content-type", "text/html; charset=utf-8"), // 52
- STATIC_ENTRY("content-type", "text/plain"), // 53
- STATIC_ENTRY("content-type", "text/plain;charset=utf-8"), // 54
- STATIC_ENTRY("range", "bytes=0-"), // 55
- STATIC_ENTRY("strict-transport-security", "max-age=31536000"), // 56
- STATIC_ENTRY("strict-transport-security",
- "max-age=31536000; includesubdomains"), // 57
- STATIC_ENTRY("strict-transport-security",
- "max-age=31536000; includesubdomains; preload"), // 58
- STATIC_ENTRY("vary", "accept-encoding"), // 59
- STATIC_ENTRY("vary", "origin"), // 60
- STATIC_ENTRY("x-content-type-options", "nosniff"), // 61
- STATIC_ENTRY("x-xss-protection", "1; mode=block"), // 62
- STATIC_ENTRY(":status", "100"), // 63
- STATIC_ENTRY(":status", "204"), // 64
- STATIC_ENTRY(":status", "206"), // 65
- STATIC_ENTRY(":status", "302"), // 66
- STATIC_ENTRY(":status", "400"), // 67
- STATIC_ENTRY(":status", "403"), // 68
- STATIC_ENTRY(":status", "421"), // 69
- STATIC_ENTRY(":status", "425"), // 70
- STATIC_ENTRY(":status", "500"), // 71
- STATIC_ENTRY("accept-language", ""), // 72
- STATIC_ENTRY("access-control-allow-credentials", "FALSE"), // 73
- STATIC_ENTRY("access-control-allow-credentials", "TRUE"), // 74
- STATIC_ENTRY("access-control-allow-headers", "*"), // 75
- STATIC_ENTRY("access-control-allow-methods", "get"), // 76
- STATIC_ENTRY("access-control-allow-methods", "get, post, options"), // 77
- STATIC_ENTRY("access-control-allow-methods", "options"), // 78
- STATIC_ENTRY("access-control-expose-headers", "content-length"), // 79
- STATIC_ENTRY("access-control-request-headers", "content-type"), // 80
- STATIC_ENTRY("access-control-request-method", "get"), // 81
- STATIC_ENTRY("access-control-request-method", "post"), // 82
- STATIC_ENTRY("alt-svc", "clear"), // 83
- STATIC_ENTRY("authorization", ""), // 84
- STATIC_ENTRY(
- "content-security-policy",
- "script-src 'none'; object-src 'none'; base-uri 'none'"), // 85
- STATIC_ENTRY("early-data", "1"), // 86
- STATIC_ENTRY("expect-ct", ""), // 87
- STATIC_ENTRY("forwarded", ""), // 88
- STATIC_ENTRY("if-range", ""), // 89
- STATIC_ENTRY("origin", ""), // 90
- STATIC_ENTRY("purpose", "prefetch"), // 91
- STATIC_ENTRY("server", ""), // 92
- STATIC_ENTRY("timing-allow-origin", "*"), // 93
- STATIC_ENTRY("upgrade-insecure-requests", "1"), // 94
- STATIC_ENTRY("user-agent", ""), // 95
- STATIC_ENTRY("x-forwarded-for", ""), // 96
- STATIC_ENTRY("x-frame-options", "deny"), // 97
- STATIC_ENTRY("x-frame-options", "sameorigin"), // 98
- };
- return *kQpackStaticTable;
-}
-
-#undef STATIC_ENTRY
-
-const QpackStaticTable& ObtainQpackStaticTable() {
- static const QpackStaticTable* const shared_static_table = []() {
- auto* table = new QpackStaticTable();
- table->Initialize(QpackStaticTableVector().data(),
- QpackStaticTableVector().size());
- QUICHE_CHECK(table->IsInitialized());
- return table;
- }();
- return *shared_static_table;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_static_table.h b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_static_table.h
deleted file mode 100644
index 7f03cf92448..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_static_table.h
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QPACK_QPACK_STATIC_TABLE_H_
-#define QUICHE_QUIC_CORE_QPACK_QPACK_STATIC_TABLE_H_
-
-#include <vector>
-
-#include "quic/platform/api/quic_export.h"
-#include "spdy/core/hpack/hpack_constants.h"
-#include "spdy/core/hpack/hpack_static_table.h"
-
-namespace quic {
-
-using QpackStaticEntry = spdy::HpackStaticEntry;
-using QpackStaticTable = spdy::HpackStaticTable;
-
-// QPACK static table defined at
-// https://quicwg.org/base-drafts/draft-ietf-quic-qpack.html#static-table.
-QUIC_EXPORT_PRIVATE const std::vector<QpackStaticEntry>&
-QpackStaticTableVector();
-
-// Returns a QpackStaticTable instance initialized with kQpackStaticTable.
-// The instance is read-only, has static lifetime, and is safe to share amoung
-// threads. This function is thread-safe.
-QUIC_EXPORT_PRIVATE const QpackStaticTable& ObtainQpackStaticTable();
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_QPACK_QPACK_STATIC_TABLE_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_static_table_test.cc b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_static_table_test.cc
deleted file mode 100644
index 53ab0f49a04..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_static_table_test.cc
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/qpack/qpack_static_table.h"
-
-#include <set>
-
-#include "absl/base/macros.h"
-#include "absl/strings/string_view.h"
-#include "quic/platform/api/quic_test.h"
-
-namespace quic {
-
-namespace test {
-
-namespace {
-
-// Check that an initialized instance has the right number of entries.
-TEST(QpackStaticTableTest, Initialize) {
- QpackStaticTable table;
- EXPECT_FALSE(table.IsInitialized());
-
- table.Initialize(QpackStaticTableVector().data(),
- QpackStaticTableVector().size());
- EXPECT_TRUE(table.IsInitialized());
-
- const auto& static_entries = table.GetStaticEntries();
- EXPECT_EQ(QpackStaticTableVector().size(), static_entries.size());
-
- const auto& static_index = table.GetStaticIndex();
- EXPECT_EQ(QpackStaticTableVector().size(), static_index.size());
-
- const auto& static_name_index = table.GetStaticNameIndex();
- // Count distinct names in static table.
- std::set<absl::string_view> names;
- for (const auto& entry : static_entries) {
- names.insert(entry.name());
- }
- EXPECT_EQ(names.size(), static_name_index.size());
-}
-
-// Test that ObtainQpackStaticTable returns the same instance every time.
-TEST(QpackStaticTableTest, IsSingleton) {
- const QpackStaticTable* static_table_one = &ObtainQpackStaticTable();
- const QpackStaticTable* static_table_two = &ObtainQpackStaticTable();
- EXPECT_EQ(static_table_one, static_table_two);
-}
-
-} // namespace
-
-} // namespace test
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_stream_receiver.h b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_stream_receiver.h
deleted file mode 100644
index a543496de0c..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_stream_receiver.h
+++ /dev/null
@@ -1,24 +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_CORE_QPACK_QPACK_STREAM_RECEIVER_H_
-#define QUICHE_QUIC_CORE_QPACK_QPACK_STREAM_RECEIVER_H_
-
-#include "absl/strings/string_view.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// This interface decodes QPACK data that are received on a QpackReceiveStream.
-class QUIC_EXPORT_PRIVATE QpackStreamReceiver {
- public:
- virtual ~QpackStreamReceiver() = default;
-
- // Decode data.
- virtual void Decode(absl::string_view data) = 0;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_QPACK_QPACK_STREAM_RECEIVER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_stream_sender_delegate.h b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_stream_sender_delegate.h
deleted file mode 100644
index 04f533d3084..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_stream_sender_delegate.h
+++ /dev/null
@@ -1,27 +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_CORE_QPACK_QPACK_STREAM_SENDER_DELEGATE_H_
-#define QUICHE_QUIC_CORE_QPACK_QPACK_STREAM_SENDER_DELEGATE_H_
-
-#include "absl/strings/string_view.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// This interface writes encoder/decoder data to peer.
-class QUIC_EXPORT_PRIVATE QpackStreamSenderDelegate {
- public:
- virtual ~QpackStreamSenderDelegate() = default;
-
- // Write data on the unidirectional stream.
- virtual void WriteStreamData(absl::string_view data) = 0;
-
- // Return the number of bytes buffered due to underlying stream being blocked.
- virtual uint64_t NumBytesBuffered() const = 0;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_QPACK_QPACK_STREAM_SENDER_DELEGATE_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/qpack/value_splitting_header_list.cc b/chromium/net/third_party/quiche/src/quic/core/qpack/value_splitting_header_list.cc
deleted file mode 100644
index 9d4231d0801..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/qpack/value_splitting_header_list.cc
+++ /dev/null
@@ -1,108 +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 "quic/core/qpack/value_splitting_header_list.h"
-
-#include "absl/strings/string_view.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-namespace {
-
-const char kCookieKey[] = "cookie";
-const char kCookieSeparator = ';';
-const char kOptionalSpaceAfterCookieSeparator = ' ';
-const char kNonCookieSeparator = '\0';
-
-} // namespace
-
-ValueSplittingHeaderList::const_iterator::const_iterator(
- const spdy::Http2HeaderBlock* header_list,
- spdy::Http2HeaderBlock::const_iterator header_list_iterator)
- : header_list_(header_list),
- header_list_iterator_(header_list_iterator),
- value_start_(0) {
- UpdateHeaderField();
-}
-
-bool ValueSplittingHeaderList::const_iterator::operator==(
- const const_iterator& other) const {
- return header_list_iterator_ == other.header_list_iterator_ &&
- value_start_ == other.value_start_;
-}
-
-bool ValueSplittingHeaderList::const_iterator::operator!=(
- const const_iterator& other) const {
- return !(*this == other);
-}
-
-const ValueSplittingHeaderList::const_iterator&
-ValueSplittingHeaderList::const_iterator::operator++() {
- if (value_end_ == absl::string_view::npos) {
- // This was the last frament within |*header_list_iterator_|,
- // move on to the next header element of |header_list_|.
- ++header_list_iterator_;
- value_start_ = 0;
- } else {
- // Find the next fragment within |*header_list_iterator_|.
- value_start_ = value_end_ + 1;
- }
- UpdateHeaderField();
-
- return *this;
-}
-
-const ValueSplittingHeaderList::value_type&
- ValueSplittingHeaderList::const_iterator::operator*() const {
- return header_field_;
-}
-const ValueSplittingHeaderList::value_type*
- ValueSplittingHeaderList::const_iterator::operator->() const {
- return &header_field_;
-}
-
-void ValueSplittingHeaderList::const_iterator::UpdateHeaderField() {
- QUICHE_DCHECK(value_start_ != absl::string_view::npos);
-
- if (header_list_iterator_ == header_list_->end()) {
- return;
- }
-
- const absl::string_view name = header_list_iterator_->first;
- const absl::string_view original_value = header_list_iterator_->second;
-
- if (name == kCookieKey) {
- value_end_ = original_value.find(kCookieSeparator, value_start_);
- } else {
- value_end_ = original_value.find(kNonCookieSeparator, value_start_);
- }
-
- const absl::string_view value =
- original_value.substr(value_start_, value_end_ - value_start_);
- header_field_ = std::make_pair(name, value);
-
- // Skip character after ';' separator if it is a space.
- if (name == kCookieKey && value_end_ != absl::string_view::npos &&
- value_end_ + 1 < original_value.size() &&
- original_value[value_end_ + 1] == kOptionalSpaceAfterCookieSeparator) {
- ++value_end_;
- }
-}
-
-ValueSplittingHeaderList::ValueSplittingHeaderList(
- const spdy::Http2HeaderBlock* header_list)
- : header_list_(header_list) {
- QUICHE_DCHECK(header_list_);
-}
-
-ValueSplittingHeaderList::const_iterator ValueSplittingHeaderList::begin()
- const {
- return const_iterator(header_list_, header_list_->begin());
-}
-
-ValueSplittingHeaderList::const_iterator ValueSplittingHeaderList::end() const {
- return const_iterator(header_list_, header_list_->end());
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/qpack/value_splitting_header_list.h b/chromium/net/third_party/quiche/src/quic/core/qpack/value_splitting_header_list.h
deleted file mode 100644
index 939a4cee56b..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/qpack/value_splitting_header_list.h
+++ /dev/null
@@ -1,62 +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_CORE_QPACK_VALUE_SPLITTING_HEADER_LIST_H_
-#define QUICHE_QUIC_CORE_QPACK_VALUE_SPLITTING_HEADER_LIST_H_
-
-#include "absl/strings/string_view.h"
-#include "quic/platform/api/quic_export.h"
-#include "spdy/core/spdy_header_block.h"
-
-namespace quic {
-
-// A wrapper class around Http2HeaderBlock that splits header values along ';'
-// separators (while also removing optional space following separator) for
-// cookies and along '\0' separators for other header fields.
-class QUIC_EXPORT_PRIVATE ValueSplittingHeaderList {
- public:
- using value_type = spdy::Http2HeaderBlock::value_type;
-
- class QUIC_EXPORT_PRIVATE const_iterator {
- public:
- // |header_list| must outlive this object.
- const_iterator(const spdy::Http2HeaderBlock* header_list,
- spdy::Http2HeaderBlock::const_iterator header_list_iterator);
- const_iterator(const const_iterator&) = default;
- const_iterator& operator=(const const_iterator&) = delete;
-
- bool operator==(const const_iterator& other) const;
- bool operator!=(const const_iterator& other) const;
-
- const const_iterator& operator++();
-
- const value_type& operator*() const;
- const value_type* operator->() const;
-
- private:
- // Find next separator; update |value_end_| and |header_field_|.
- void UpdateHeaderField();
-
- const spdy::Http2HeaderBlock* const header_list_;
- spdy::Http2HeaderBlock::const_iterator header_list_iterator_;
- absl::string_view::size_type value_start_;
- absl::string_view::size_type value_end_;
- value_type header_field_;
- };
-
- // |header_list| must outlive this object.
- explicit ValueSplittingHeaderList(const spdy::Http2HeaderBlock* header_list);
- ValueSplittingHeaderList(const ValueSplittingHeaderList&) = delete;
- ValueSplittingHeaderList& operator=(const ValueSplittingHeaderList&) = delete;
-
- const_iterator begin() const;
- const_iterator end() const;
-
- private:
- const spdy::Http2HeaderBlock* const header_list_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_QPACK_VALUE_SPLITTING_HEADER_LIST_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/qpack/value_splitting_header_list_test.cc b/chromium/net/third_party/quiche/src/quic/core/qpack/value_splitting_header_list_test.cc
deleted file mode 100644
index bc3072a049e..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/qpack/value_splitting_header_list_test.cc
+++ /dev/null
@@ -1,158 +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 "quic/core/qpack/value_splitting_header_list.h"
-
-#include "absl/base/macros.h"
-#include "absl/strings/string_view.h"
-#include "quic/platform/api/quic_test.h"
-
-namespace quic {
-namespace test {
-namespace {
-
-using ::testing::ElementsAre;
-using ::testing::Pair;
-
-TEST(ValueSplittingHeaderListTest, Comparison) {
- spdy::Http2HeaderBlock block;
- block["foo"] = absl::string_view("bar\0baz", 7);
- block["baz"] = "qux";
- block["cookie"] = "foo; bar";
-
- ValueSplittingHeaderList headers(&block);
- ValueSplittingHeaderList::const_iterator it1 = headers.begin();
- const int kEnd = 6;
- for (int i = 0; i < kEnd; ++i) {
- // Compare to begin().
- if (i == 0) {
- EXPECT_TRUE(it1 == headers.begin());
- EXPECT_TRUE(headers.begin() == it1);
- EXPECT_FALSE(it1 != headers.begin());
- EXPECT_FALSE(headers.begin() != it1);
- } else {
- EXPECT_FALSE(it1 == headers.begin());
- EXPECT_FALSE(headers.begin() == it1);
- EXPECT_TRUE(it1 != headers.begin());
- EXPECT_TRUE(headers.begin() != it1);
- }
-
- // Compare to end().
- if (i == kEnd - 1) {
- EXPECT_TRUE(it1 == headers.end());
- EXPECT_TRUE(headers.end() == it1);
- EXPECT_FALSE(it1 != headers.end());
- EXPECT_FALSE(headers.end() != it1);
- } else {
- EXPECT_FALSE(it1 == headers.end());
- EXPECT_FALSE(headers.end() == it1);
- EXPECT_TRUE(it1 != headers.end());
- EXPECT_TRUE(headers.end() != it1);
- }
-
- // Compare to another iterator walking through the container.
- ValueSplittingHeaderList::const_iterator it2 = headers.begin();
- for (int j = 0; j < kEnd; ++j) {
- if (i == j) {
- EXPECT_TRUE(it1 == it2);
- EXPECT_FALSE(it1 != it2);
- } else {
- EXPECT_FALSE(it1 == it2);
- EXPECT_TRUE(it1 != it2);
- }
- if (j < kEnd - 1) {
- ASSERT_NE(it2, headers.end());
- ++it2;
- }
- }
-
- if (i < kEnd - 1) {
- ASSERT_NE(it1, headers.end());
- ++it1;
- }
- }
-}
-
-TEST(ValueSplittingHeaderListTest, Empty) {
- spdy::Http2HeaderBlock block;
-
- ValueSplittingHeaderList headers(&block);
- EXPECT_THAT(headers, ElementsAre());
- EXPECT_EQ(headers.begin(), headers.end());
-}
-
-TEST(ValueSplittingHeaderListTest, Split) {
- struct {
- const char* name;
- absl::string_view value;
- std::vector<const char*> expected_values;
- } kTestData[]{
- // Empty value.
- {"foo", "", {""}},
- // Trivial case.
- {"foo", "bar", {"bar"}},
- // Simple split.
- {"foo", {"bar\0baz", 7}, {"bar", "baz"}},
- {"cookie", "foo;bar", {"foo", "bar"}},
- {"cookie", "foo; bar", {"foo", "bar"}},
- // Empty fragments with \0 separator.
- {"foo", {"\0", 1}, {"", ""}},
- {"bar", {"foo\0", 4}, {"foo", ""}},
- {"baz", {"\0bar", 4}, {"", "bar"}},
- {"qux", {"\0foobar\0", 8}, {"", "foobar", ""}},
- // Empty fragments with ";" separator.
- {"cookie", ";", {"", ""}},
- {"cookie", "foo;", {"foo", ""}},
- {"cookie", ";bar", {"", "bar"}},
- {"cookie", ";foobar;", {"", "foobar", ""}},
- // Empty fragments with "; " separator.
- {"cookie", "; ", {"", ""}},
- {"cookie", "foo; ", {"foo", ""}},
- {"cookie", "; bar", {"", "bar"}},
- {"cookie", "; foobar; ", {"", "foobar", ""}},
- };
-
- for (size_t i = 0; i < ABSL_ARRAYSIZE(kTestData); ++i) {
- spdy::Http2HeaderBlock block;
- block[kTestData[i].name] = kTestData[i].value;
-
- ValueSplittingHeaderList headers(&block);
- auto it = headers.begin();
- for (const char* expected_value : kTestData[i].expected_values) {
- ASSERT_NE(it, headers.end());
- EXPECT_EQ(it->first, kTestData[i].name);
- EXPECT_EQ(it->second, expected_value);
- ++it;
- }
- EXPECT_EQ(it, headers.end());
- }
-}
-
-TEST(ValueSplittingHeaderListTest, MultipleFields) {
- spdy::Http2HeaderBlock block;
- block["foo"] = absl::string_view("bar\0baz\0", 8);
- block["cookie"] = "foo; bar";
- block["bar"] = absl::string_view("qux\0foo", 7);
-
- ValueSplittingHeaderList headers(&block);
- EXPECT_THAT(headers, ElementsAre(Pair("foo", "bar"), Pair("foo", "baz"),
- Pair("foo", ""), Pair("cookie", "foo"),
- Pair("cookie", "bar"), Pair("bar", "qux"),
- Pair("bar", "foo")));
-}
-
-TEST(ValueSplittingHeaderListTest, CookieStartsWithSpace) {
- spdy::Http2HeaderBlock block;
- block["foo"] = "bar";
- block["cookie"] = " foo";
- block["bar"] = "baz";
-
- ValueSplittingHeaderList headers(&block);
- EXPECT_THAT(headers, ElementsAre(Pair("foo", "bar"), Pair("cookie", " foo"),
- Pair("bar", "baz")));
-}
-
-} // namespace
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_ack_listener_interface.cc b/chromium/net/third_party/quiche/src/quic/core/quic_ack_listener_interface.cc
deleted file mode 100644
index 4a8548174c4..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_ack_listener_interface.cc
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_ack_listener_interface.h"
-
-namespace quic {
-
-QuicAckListenerInterface::~QuicAckListenerInterface() {}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_ack_listener_interface.h b/chromium/net/third_party/quiche/src/quic/core/quic_ack_listener_interface.h
deleted file mode 100644
index abfb217b7ed..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_ack_listener_interface.h
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_ACK_LISTENER_INTERFACE_H_
-#define QUICHE_QUIC_CORE_QUIC_ACK_LISTENER_INTERFACE_H_
-
-#include "quic/core/quic_time.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_export.h"
-#include "quic/platform/api/quic_reference_counted.h"
-
-namespace quic {
-
-// Pure virtual class to listen for packet acknowledgements.
-class QUIC_EXPORT_PRIVATE QuicAckListenerInterface
- : public QuicReferenceCounted {
- public:
- QuicAckListenerInterface() {}
-
- // Called when a packet is acked. Called once per packet.
- // |acked_bytes| is the number of data bytes acked.
- virtual void OnPacketAcked(int acked_bytes,
- QuicTime::Delta ack_delay_time) = 0;
-
- // Called when a packet is retransmitted. Called once per packet.
- // |retransmitted_bytes| is the number of data bytes retransmitted.
- virtual void OnPacketRetransmitted(int retransmitted_bytes) = 0;
-
- protected:
- // Delegates are ref counted.
- ~QuicAckListenerInterface() override;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_QUIC_ACK_LISTENER_INTERFACE_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_alarm.cc b/chromium/net/third_party/quiche/src/quic/core/quic_alarm.cc
deleted file mode 100644
index 33b96ed652b..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_alarm.cc
+++ /dev/null
@@ -1,107 +0,0 @@
-// Copyright 2013 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 "quic/core/quic_alarm.h"
-
-#include <atomic>
-
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_flag_utils.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_stack_trace.h"
-
-namespace quic {
-
-QuicAlarm::QuicAlarm(QuicArenaScopedPtr<Delegate> delegate)
- : delegate_(std::move(delegate)), deadline_(QuicTime::Zero()) {}
-
-QuicAlarm::~QuicAlarm() {
- if (IsSet()) {
- QUIC_CODE_COUNT(quic_alarm_not_cancelled_in_dtor);
- }
-}
-
-void QuicAlarm::Set(QuicTime new_deadline) {
- QUICHE_DCHECK(!IsSet());
- QUICHE_DCHECK(new_deadline.IsInitialized());
-
- if (IsPermanentlyCancelled()) {
- QUIC_BUG(quic_alarm_illegal_set)
- << "Set called after alarm is permanently cancelled. new_deadline:"
- << new_deadline;
- return;
- }
-
- deadline_ = new_deadline;
- SetImpl();
-}
-
-void QuicAlarm::CancelInternal(bool permanent) {
- if (IsSet()) {
- deadline_ = QuicTime::Zero();
- CancelImpl();
- }
-
- if (permanent) {
- delegate_.reset();
- }
-}
-
-bool QuicAlarm::IsPermanentlyCancelled() const { return delegate_ == nullptr; }
-
-void QuicAlarm::Update(QuicTime new_deadline, QuicTime::Delta granularity) {
- if (IsPermanentlyCancelled()) {
- QUIC_BUG(quic_alarm_illegal_update)
- << "Update called after alarm is permanently cancelled. new_deadline:"
- << new_deadline << ", granularity:" << granularity;
- return;
- }
-
- if (!new_deadline.IsInitialized()) {
- Cancel();
- return;
- }
- if (std::abs((new_deadline - deadline_).ToMicroseconds()) <
- granularity.ToMicroseconds()) {
- return;
- }
- const bool was_set = IsSet();
- deadline_ = new_deadline;
- if (was_set) {
- UpdateImpl();
- } else {
- SetImpl();
- }
-}
-
-bool QuicAlarm::IsSet() const {
- return deadline_.IsInitialized();
-}
-
-void QuicAlarm::Fire() {
- if (!IsSet()) {
- return;
- }
-
- deadline_ = QuicTime::Zero();
- if (!IsPermanentlyCancelled()) {
- QuicConnectionContextSwitcher context_switcher(
- delegate_->GetConnectionContext());
- delegate_->OnAlarm();
- }
-}
-
-void QuicAlarm::UpdateImpl() {
- // CancelImpl and SetImpl take the new deadline by way of the deadline_
- // member, so save and restore deadline_ before canceling.
- const QuicTime new_deadline = deadline_;
-
- deadline_ = QuicTime::Zero();
- CancelImpl();
-
- deadline_ = new_deadline;
- SetImpl();
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_alarm.h b/chromium/net/third_party/quiche/src/quic/core/quic_alarm.h
deleted file mode 100644
index 26ebfe8ca4d..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_alarm.h
+++ /dev/null
@@ -1,125 +0,0 @@
-// Copyright 2013 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_ALARM_H_
-#define QUICHE_QUIC_CORE_QUIC_ALARM_H_
-
-#include "quic/core/quic_arena_scoped_ptr.h"
-#include "quic/core/quic_connection_context.h"
-#include "quic/core/quic_time.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// Abstract class which represents an alarm which will go off at a
-// scheduled time, and execute the |OnAlarm| method of the delegate.
-// An alarm may be cancelled, in which case it may or may not be
-// removed from the underlying scheduling system, but in either case
-// the task will not be executed.
-class QUIC_EXPORT_PRIVATE QuicAlarm {
- public:
- class QUIC_EXPORT_PRIVATE Delegate {
- public:
- virtual ~Delegate() {}
-
- // If the alarm belongs to a single QuicConnection, return the corresponding
- // QuicConnection.context_. Note the context_ is the first member of
- // QuicConnection, so it should outlive the delegate.
- // Otherwise return nullptr.
- // The OnAlarm function will be called under the connection context, if any.
- virtual QuicConnectionContext* GetConnectionContext() = 0;
-
- // Invoked when the alarm fires.
- virtual void OnAlarm() = 0;
- };
-
- // DelegateWithContext is a Delegate with a QuicConnectionContext* stored as a
- // member variable.
- class QUIC_EXPORT_PRIVATE DelegateWithContext : public Delegate {
- public:
- explicit DelegateWithContext(QuicConnectionContext* context)
- : context_(context) {}
- ~DelegateWithContext() override {}
- QuicConnectionContext* GetConnectionContext() override { return context_; }
-
- private:
- QuicConnectionContext* context_;
- };
-
- // DelegateWithoutContext is a Delegate that does not have a corresponding
- // context. Typically this means one object of the child class deals with many
- // connections.
- class QUIC_EXPORT_PRIVATE DelegateWithoutContext : public Delegate {
- public:
- ~DelegateWithoutContext() override {}
- QuicConnectionContext* GetConnectionContext() override { return nullptr; }
- };
-
- explicit QuicAlarm(QuicArenaScopedPtr<Delegate> delegate);
- QuicAlarm(const QuicAlarm&) = delete;
- QuicAlarm& operator=(const QuicAlarm&) = delete;
- virtual ~QuicAlarm();
-
- // Sets the alarm to fire at |deadline|. Must not be called while
- // the alarm is set. To reschedule an alarm, call Cancel() first,
- // then Set().
- void Set(QuicTime new_deadline);
-
- // Both PermanentCancel() and Cancel() can cancel the alarm. If permanent,
- // future calls to Set() and Update() will become no-op except emitting an
- // error log.
- //
- // Both may be called repeatedly. Does not guarantee that the underlying
- // scheduling system will remove the alarm's associated task, but guarantees
- // that the delegates OnAlarm method will not be called.
- void PermanentCancel() { CancelInternal(true); }
- void Cancel() { CancelInternal(false); }
-
- // Return true if PermanentCancel() has been called.
- bool IsPermanentlyCancelled() const;
-
- // Cancels and sets the alarm if the |deadline| is farther from the current
- // deadline than |granularity|, and otherwise does nothing. If |deadline| is
- // not initialized, the alarm is cancelled.
- void Update(QuicTime new_deadline, QuicTime::Delta granularity);
-
- // Returns true if |deadline_| has been set to a non-zero time.
- bool IsSet() const;
-
- QuicTime deadline() const { return deadline_; }
-
- protected:
- // Subclasses implement this method to perform the platform-specific
- // scheduling of the alarm. Is called from Set() or Fire(), after the
- // deadline has been updated.
- virtual void SetImpl() = 0;
-
- // Subclasses implement this method to perform the platform-specific
- // cancelation of the alarm.
- virtual void CancelImpl() = 0;
-
- // Subclasses implement this method to perform the platform-specific update of
- // the alarm if there exists a more optimal implementation than calling
- // CancelImpl() and SetImpl().
- virtual void UpdateImpl();
-
- // Called by subclasses when the alarm fires. Invokes the
- // delegates |OnAlarm| if a delegate is set, and if the deadline
- // has been exceeded. Implementations which do not remove the
- // alarm from the underlying scheduler on Cancel() may need to handle
- // the situation where the task executes before the deadline has been
- // reached, in which case they need to reschedule the task and must not
- // call invoke this method.
- void Fire();
-
- private:
- void CancelInternal(bool permanent);
-
- QuicArenaScopedPtr<Delegate> delegate_;
- QuicTime deadline_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_QUIC_ALARM_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_alarm_factory.h b/chromium/net/third_party/quiche/src/quic/core/quic_alarm_factory.h
deleted file mode 100644
index 57505ef6474..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_alarm_factory.h
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright (c) 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_ALARM_FACTORY_H_
-#define QUICHE_QUIC_CORE_QUIC_ALARM_FACTORY_H_
-
-#include "quic/core/quic_alarm.h"
-#include "quic/core/quic_one_block_arena.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// Creates platform-specific alarms used throughout QUIC.
-class QUIC_EXPORT_PRIVATE QuicAlarmFactory {
- public:
- virtual ~QuicAlarmFactory() {}
-
- // Creates a new platform-specific alarm which will be configured to notify
- // |delegate| when the alarm fires. Returns an alarm allocated on the heap.
- // Caller takes ownership of the new alarm, which will not yet be "set" to
- // fire.
- virtual QuicAlarm* CreateAlarm(QuicAlarm::Delegate* delegate) = 0;
-
- // Creates a new platform-specific alarm which will be configured to notify
- // |delegate| when the alarm fires. Caller takes ownership of the new alarm,
- // which will not yet be "set" to fire. If |arena| is null, then the alarm
- // will be created on the heap. Otherwise, it will be created in |arena|.
- virtual QuicArenaScopedPtr<QuicAlarm> CreateAlarm(
- QuicArenaScopedPtr<QuicAlarm::Delegate> delegate,
- QuicConnectionArena* arena) = 0;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_QUIC_ALARM_FACTORY_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_alarm_test.cc b/chromium/net/third_party/quiche/src/quic/core/quic_alarm_test.cc
deleted file mode 100644
index b27f96eed4d..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_alarm_test.cc
+++ /dev/null
@@ -1,261 +0,0 @@
-// Copyright 2013 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 "quic/core/quic_alarm.h"
-
-#include "quic/core/quic_connection_context.h"
-#include "quic/platform/api/quic_expect_bug.h"
-#include "quic/platform/api/quic_test.h"
-
-using testing::ElementsAre;
-using testing::Invoke;
-using testing::Return;
-
-namespace quic {
-namespace test {
-namespace {
-
-class TraceCollector : public QuicConnectionTracer {
- public:
- ~TraceCollector() override = default;
-
- void PrintLiteral(const char* literal) override { trace_.push_back(literal); }
-
- void PrintString(absl::string_view s) override {
- trace_.push_back(std::string(s));
- }
-
- const std::vector<std::string>& trace() const { return trace_; }
-
- private:
- std::vector<std::string> trace_;
-};
-
-class MockDelegate : public QuicAlarm::Delegate {
- public:
- MOCK_METHOD(QuicConnectionContext*, GetConnectionContext, (), (override));
- MOCK_METHOD(void, OnAlarm, (), (override));
-};
-
-class DestructiveDelegate : public QuicAlarm::DelegateWithoutContext {
- public:
- DestructiveDelegate() : alarm_(nullptr) {}
-
- void set_alarm(QuicAlarm* alarm) { alarm_ = alarm; }
-
- void OnAlarm() override {
- QUICHE_DCHECK(alarm_);
- delete alarm_;
- }
-
- private:
- QuicAlarm* alarm_;
-};
-
-class TestAlarm : public QuicAlarm {
- public:
- explicit TestAlarm(QuicAlarm::Delegate* delegate)
- : QuicAlarm(QuicArenaScopedPtr<QuicAlarm::Delegate>(delegate)) {}
-
- bool scheduled() const { return scheduled_; }
-
- void FireAlarm() {
- scheduled_ = false;
- Fire();
- }
-
- protected:
- void SetImpl() override {
- QUICHE_DCHECK(deadline().IsInitialized());
- scheduled_ = true;
- }
-
- void CancelImpl() override {
- QUICHE_DCHECK(!deadline().IsInitialized());
- scheduled_ = false;
- }
-
- private:
- bool scheduled_;
-};
-
-class DestructiveAlarm : public QuicAlarm {
- public:
- explicit DestructiveAlarm(DestructiveDelegate* delegate)
- : QuicAlarm(QuicArenaScopedPtr<DestructiveDelegate>(delegate)) {}
-
- void FireAlarm() { Fire(); }
-
- protected:
- void SetImpl() override {}
-
- void CancelImpl() override {}
-};
-
-class QuicAlarmTest : public QuicTest {
- public:
- QuicAlarmTest()
- : delegate_(new MockDelegate()),
- alarm_(delegate_),
- deadline_(QuicTime::Zero() + QuicTime::Delta::FromSeconds(7)),
- deadline2_(QuicTime::Zero() + QuicTime::Delta::FromSeconds(14)),
- new_deadline_(QuicTime::Zero()) {}
-
- void ResetAlarm() { alarm_.Set(new_deadline_); }
-
- MockDelegate* delegate_; // not owned
- TestAlarm alarm_;
- QuicTime deadline_;
- QuicTime deadline2_;
- QuicTime new_deadline_;
-};
-
-TEST_F(QuicAlarmTest, IsSet) {
- EXPECT_FALSE(alarm_.IsSet());
-}
-
-TEST_F(QuicAlarmTest, Set) {
- QuicTime deadline = QuicTime::Zero() + QuicTime::Delta::FromSeconds(7);
- alarm_.Set(deadline);
- EXPECT_TRUE(alarm_.IsSet());
- EXPECT_TRUE(alarm_.scheduled());
- EXPECT_EQ(deadline, alarm_.deadline());
-}
-
-TEST_F(QuicAlarmTest, Cancel) {
- QuicTime deadline = QuicTime::Zero() + QuicTime::Delta::FromSeconds(7);
- alarm_.Set(deadline);
- alarm_.Cancel();
- EXPECT_FALSE(alarm_.IsSet());
- EXPECT_FALSE(alarm_.scheduled());
- EXPECT_EQ(QuicTime::Zero(), alarm_.deadline());
-}
-
-TEST_F(QuicAlarmTest, PermanentCancel) {
- QuicTime deadline = QuicTime::Zero() + QuicTime::Delta::FromSeconds(7);
- alarm_.Set(deadline);
- alarm_.PermanentCancel();
- EXPECT_FALSE(alarm_.IsSet());
- EXPECT_FALSE(alarm_.scheduled());
- EXPECT_EQ(QuicTime::Zero(), alarm_.deadline());
-
- EXPECT_QUIC_BUG(alarm_.Set(deadline),
- "Set called after alarm is permanently cancelled");
- EXPECT_TRUE(alarm_.IsPermanentlyCancelled());
- EXPECT_FALSE(alarm_.IsSet());
- EXPECT_FALSE(alarm_.scheduled());
- EXPECT_EQ(QuicTime::Zero(), alarm_.deadline());
-
- EXPECT_QUIC_BUG(alarm_.Update(deadline, QuicTime::Delta::Zero()),
- "Update called after alarm is permanently cancelled");
- EXPECT_TRUE(alarm_.IsPermanentlyCancelled());
- EXPECT_FALSE(alarm_.IsSet());
- EXPECT_FALSE(alarm_.scheduled());
- EXPECT_EQ(QuicTime::Zero(), alarm_.deadline());
-}
-
-TEST_F(QuicAlarmTest, Update) {
- QuicTime deadline = QuicTime::Zero() + QuicTime::Delta::FromSeconds(7);
- alarm_.Set(deadline);
- QuicTime new_deadline = QuicTime::Zero() + QuicTime::Delta::FromSeconds(8);
- alarm_.Update(new_deadline, QuicTime::Delta::Zero());
- EXPECT_TRUE(alarm_.IsSet());
- EXPECT_TRUE(alarm_.scheduled());
- EXPECT_EQ(new_deadline, alarm_.deadline());
-}
-
-TEST_F(QuicAlarmTest, UpdateWithZero) {
- QuicTime deadline = QuicTime::Zero() + QuicTime::Delta::FromSeconds(7);
- alarm_.Set(deadline);
- alarm_.Update(QuicTime::Zero(), QuicTime::Delta::Zero());
- EXPECT_FALSE(alarm_.IsSet());
- EXPECT_FALSE(alarm_.scheduled());
- EXPECT_EQ(QuicTime::Zero(), alarm_.deadline());
-}
-
-TEST_F(QuicAlarmTest, Fire) {
- QuicTime deadline = QuicTime::Zero() + QuicTime::Delta::FromSeconds(7);
- alarm_.Set(deadline);
- EXPECT_CALL(*delegate_, OnAlarm());
- alarm_.FireAlarm();
- EXPECT_FALSE(alarm_.IsSet());
- EXPECT_FALSE(alarm_.scheduled());
- EXPECT_EQ(QuicTime::Zero(), alarm_.deadline());
-}
-
-TEST_F(QuicAlarmTest, FireAndResetViaSet) {
- alarm_.Set(deadline_);
- new_deadline_ = deadline2_;
- EXPECT_CALL(*delegate_, OnAlarm())
- .WillOnce(Invoke(this, &QuicAlarmTest::ResetAlarm));
- alarm_.FireAlarm();
- EXPECT_TRUE(alarm_.IsSet());
- EXPECT_TRUE(alarm_.scheduled());
- EXPECT_EQ(deadline2_, alarm_.deadline());
-}
-
-TEST_F(QuicAlarmTest, FireDestroysAlarm) {
- DestructiveDelegate* delegate(new DestructiveDelegate);
- DestructiveAlarm* alarm = new DestructiveAlarm(delegate);
- delegate->set_alarm(alarm);
- QuicTime deadline = QuicTime::Zero() + QuicTime::Delta::FromSeconds(7);
- alarm->Set(deadline);
- // This should not crash, even though it will destroy alarm.
- alarm->FireAlarm();
-}
-
-TEST_F(QuicAlarmTest, NullAlarmContext) {
- QuicTime deadline = QuicTime::Zero() + QuicTime::Delta::FromSeconds(7);
- alarm_.Set(deadline);
-
- EXPECT_CALL(*delegate_, GetConnectionContext()).WillOnce(Return(nullptr));
-
- EXPECT_CALL(*delegate_, OnAlarm()).WillOnce(Invoke([] {
- QUIC_TRACELITERAL("Alarm fired.");
- }));
- alarm_.FireAlarm();
-}
-
-TEST_F(QuicAlarmTest, AlarmContextWithNullTracer) {
- QuicConnectionContext context;
- ASSERT_EQ(context.tracer, nullptr);
-
- QuicTime deadline = QuicTime::Zero() + QuicTime::Delta::FromSeconds(7);
- alarm_.Set(deadline);
-
- EXPECT_CALL(*delegate_, GetConnectionContext()).WillOnce(Return(&context));
-
- EXPECT_CALL(*delegate_, OnAlarm()).WillOnce(Invoke([] {
- QUIC_TRACELITERAL("Alarm fired.");
- }));
- alarm_.FireAlarm();
-}
-
-TEST_F(QuicAlarmTest, AlarmContextWithTracer) {
- QuicConnectionContext context;
- std::unique_ptr<TraceCollector> tracer = std::make_unique<TraceCollector>();
- const TraceCollector& tracer_ref = *tracer;
- context.tracer = std::move(tracer);
-
- QuicTime deadline = QuicTime::Zero() + QuicTime::Delta::FromSeconds(7);
- alarm_.Set(deadline);
-
- EXPECT_CALL(*delegate_, GetConnectionContext()).WillOnce(Return(&context));
-
- EXPECT_CALL(*delegate_, OnAlarm()).WillOnce(Invoke([] {
- QUIC_TRACELITERAL("Alarm fired.");
- }));
-
- // Since |context| is not installed in the current thread, the messages before
- // and after FireAlarm() should not be collected by |tracer|.
- QUIC_TRACELITERAL("Should not be collected before alarm.");
- alarm_.FireAlarm();
- QUIC_TRACELITERAL("Should not be collected after alarm.");
-
- EXPECT_THAT(tracer_ref.trace(), ElementsAre("Alarm fired."));
-}
-
-} // namespace
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_arena_scoped_ptr.h b/chromium/net/third_party/quiche/src/quic/core/quic_arena_scoped_ptr.h
deleted file mode 100644
index 19b89a3ca27..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_arena_scoped_ptr.h
+++ /dev/null
@@ -1,208 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// unique_ptr-style pointer that stores values that may be from an arena. Takes
-// up the same storage as the platform's native pointer type. Takes ownership
-// of the value it's constructed with; if holding a value in an arena, and the
-// type has a non-trivial destructor, the arena must outlive the
-// QuicArenaScopedPtr. Does not support array overloads.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_ARENA_SCOPED_PTR_H_
-#define QUICHE_QUIC_CORE_QUIC_ARENA_SCOPED_PTR_H_
-
-#include <cstdint> // for uintptr_t
-
-#include "quic/platform/api/quic_export.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-template <typename T>
-class QUIC_NO_EXPORT QuicArenaScopedPtr {
- static_assert(alignof(T*) > 1,
- "QuicArenaScopedPtr can only store objects that are aligned to "
- "greater than 1 byte.");
-
- public:
- // Constructs an empty QuicArenaScopedPtr.
- QuicArenaScopedPtr();
-
- // Constructs a QuicArenaScopedPtr referencing the heap-allocated memory
- // provided.
- explicit QuicArenaScopedPtr(T* value);
-
- template <typename U>
- QuicArenaScopedPtr(QuicArenaScopedPtr<U>&& other); // NOLINT
- template <typename U>
- QuicArenaScopedPtr& operator=(QuicArenaScopedPtr<U>&& other);
- ~QuicArenaScopedPtr();
-
- // Returns a pointer to the value.
- T* get() const;
-
- // Returns a reference to the value.
- T& operator*() const;
-
- // Returns a pointer to the value.
- T* operator->() const;
-
- // Swaps the value of this pointer with |other|.
- void swap(QuicArenaScopedPtr& other);
-
- // Resets the held value to |value|.
- void reset(T* value = nullptr);
-
- // Returns true if |this| came from an arena. Primarily exposed for testing
- // and assertions.
- bool is_from_arena();
-
- private:
- // Friends with other derived types of QuicArenaScopedPtr, to support the
- // derived-types case.
- template <typename U>
- friend class QuicArenaScopedPtr;
- // Also befriend all known arenas, only to prevent misuse.
- template <uint32_t ArenaSize>
- friend class QuicOneBlockArena;
-
- // Tag to denote that a QuicArenaScopedPtr is being explicitly created by an
- // arena.
- enum class ConstructFrom { kHeap, kArena };
-
- // Constructs a QuicArenaScopedPtr with the given representation.
- QuicArenaScopedPtr(void* value, ConstructFrom from);
- QuicArenaScopedPtr(const QuicArenaScopedPtr&) = delete;
- QuicArenaScopedPtr& operator=(const QuicArenaScopedPtr&) = delete;
-
- // Low-order bits of value_ that determine if the pointer came from an arena.
- static const uintptr_t kFromArenaMask = 0x1;
-
- // Every platform we care about has at least 4B aligned integers, so store the
- // is_from_arena bit in the least significant bit.
- void* value_;
-};
-
-template <typename T>
-bool operator==(const QuicArenaScopedPtr<T>& left,
- const QuicArenaScopedPtr<T>& right) {
- return left.get() == right.get();
-}
-
-template <typename T>
-bool operator!=(const QuicArenaScopedPtr<T>& left,
- const QuicArenaScopedPtr<T>& right) {
- return left.get() != right.get();
-}
-
-template <typename T>
-bool operator==(std::nullptr_t, const QuicArenaScopedPtr<T>& right) {
- return nullptr == right.get();
-}
-
-template <typename T>
-bool operator!=(std::nullptr_t, const QuicArenaScopedPtr<T>& right) {
- return nullptr != right.get();
-}
-
-template <typename T>
-bool operator==(const QuicArenaScopedPtr<T>& left, std::nullptr_t) {
- return left.get() == nullptr;
-}
-
-template <typename T>
-bool operator!=(const QuicArenaScopedPtr<T>& left, std::nullptr_t) {
- return left.get() != nullptr;
-}
-
-template <typename T>
-QuicArenaScopedPtr<T>::QuicArenaScopedPtr() : value_(nullptr) {}
-
-template <typename T>
-QuicArenaScopedPtr<T>::QuicArenaScopedPtr(T* value)
- : QuicArenaScopedPtr(value, ConstructFrom::kHeap) {}
-
-template <typename T>
-template <typename U>
-QuicArenaScopedPtr<T>::QuicArenaScopedPtr(QuicArenaScopedPtr<U>&& other)
- : value_(other.value_) {
- static_assert(
- std::is_base_of<T, U>::value || std::is_same<T, U>::value,
- "Cannot construct QuicArenaScopedPtr; type is not derived or same.");
- other.value_ = nullptr;
-}
-
-template <typename T>
-template <typename U>
-QuicArenaScopedPtr<T>& QuicArenaScopedPtr<T>::operator=(
- QuicArenaScopedPtr<U>&& other) {
- static_assert(
- std::is_base_of<T, U>::value || std::is_same<T, U>::value,
- "Cannot assign QuicArenaScopedPtr; type is not derived or same.");
- swap(other);
- return *this;
-}
-
-template <typename T>
-QuicArenaScopedPtr<T>::~QuicArenaScopedPtr() {
- reset();
-}
-
-template <typename T>
-T* QuicArenaScopedPtr<T>::get() const {
- return reinterpret_cast<T*>(reinterpret_cast<uintptr_t>(value_) &
- ~kFromArenaMask);
-}
-
-template <typename T>
-T& QuicArenaScopedPtr<T>::operator*() const {
- return *get();
-}
-
-template <typename T>
-T* QuicArenaScopedPtr<T>::operator->() const {
- return get();
-}
-
-template <typename T>
-void QuicArenaScopedPtr<T>::swap(QuicArenaScopedPtr& other) {
- using std::swap;
- swap(value_, other.value_);
-}
-
-template <typename T>
-bool QuicArenaScopedPtr<T>::is_from_arena() {
- return (reinterpret_cast<uintptr_t>(value_) & kFromArenaMask) != 0;
-}
-
-template <typename T>
-void QuicArenaScopedPtr<T>::reset(T* value) {
- if (value_ != nullptr) {
- if (is_from_arena()) {
- // Manually invoke the destructor.
- get()->~T();
- } else {
- delete get();
- }
- }
- QUICHE_DCHECK_EQ(0u, reinterpret_cast<uintptr_t>(value) & kFromArenaMask);
- value_ = value;
-}
-
-template <typename T>
-QuicArenaScopedPtr<T>::QuicArenaScopedPtr(void* value, ConstructFrom from_arena)
- : value_(value) {
- QUICHE_DCHECK_EQ(0u, reinterpret_cast<uintptr_t>(value_) & kFromArenaMask);
- switch (from_arena) {
- case ConstructFrom::kHeap:
- break;
- case ConstructFrom::kArena:
- value_ = reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(value_) |
- QuicArenaScopedPtr<T>::kFromArenaMask);
- break;
- }
-}
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_QUIC_ARENA_SCOPED_PTR_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_arena_scoped_ptr_test.cc b/chromium/net/third_party/quiche/src/quic/core/quic_arena_scoped_ptr_test.cc
deleted file mode 100644
index 6388cf366da..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_arena_scoped_ptr_test.cc
+++ /dev/null
@@ -1,115 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_arena_scoped_ptr.h"
-
-#include "quic/core/quic_one_block_arena.h"
-#include "quic/platform/api/quic_test.h"
-
-namespace quic {
-namespace {
-
-enum class TestParam { kFromHeap, kFromArena };
-
-struct TestObject {
- explicit TestObject(uintptr_t value) : value(value) { buffer.resize(1024); }
- uintptr_t value;
-
- // Ensure that we have a non-trivial destructor that will leak memory if it's
- // not called.
- std::vector<char> buffer;
-};
-
-// Used by ::testing::PrintToStringParamName().
-std::string PrintToString(const TestParam& p) {
- switch (p) {
- case TestParam::kFromHeap:
- return "heap";
- case TestParam::kFromArena:
- return "arena";
- }
- QUICHE_DCHECK(false);
- return "?";
-}
-
-class QuicArenaScopedPtrParamTest : public QuicTestWithParam<TestParam> {
- protected:
- QuicArenaScopedPtr<TestObject> CreateObject(uintptr_t value) {
- QuicArenaScopedPtr<TestObject> ptr;
- switch (GetParam()) {
- case TestParam::kFromHeap:
- ptr = QuicArenaScopedPtr<TestObject>(new TestObject(value));
- QUICHE_CHECK(!ptr.is_from_arena());
- break;
- case TestParam::kFromArena:
- ptr = arena_.New<TestObject>(value);
- QUICHE_CHECK(ptr.is_from_arena());
- break;
- }
- return ptr;
- }
-
- private:
- QuicOneBlockArena<1024> arena_;
-};
-
-INSTANTIATE_TEST_SUITE_P(QuicArenaScopedPtrParamTest,
- QuicArenaScopedPtrParamTest,
- testing::Values(TestParam::kFromHeap,
- TestParam::kFromArena),
- ::testing::PrintToStringParamName());
-
-TEST_P(QuicArenaScopedPtrParamTest, NullObjects) {
- QuicArenaScopedPtr<TestObject> def;
- QuicArenaScopedPtr<TestObject> null(nullptr);
- EXPECT_EQ(def, null);
- EXPECT_EQ(def, nullptr);
- EXPECT_EQ(null, nullptr);
-}
-
-TEST_P(QuicArenaScopedPtrParamTest, FromArena) {
- QuicOneBlockArena<1024> arena_;
- EXPECT_TRUE(arena_.New<TestObject>(0).is_from_arena());
- EXPECT_FALSE(
- QuicArenaScopedPtr<TestObject>(new TestObject(0)).is_from_arena());
-}
-
-TEST_P(QuicArenaScopedPtrParamTest, Assign) {
- QuicArenaScopedPtr<TestObject> ptr = CreateObject(12345);
- ptr = CreateObject(54321);
- EXPECT_EQ(54321u, ptr->value);
-}
-
-TEST_P(QuicArenaScopedPtrParamTest, MoveConstruct) {
- QuicArenaScopedPtr<TestObject> ptr1 = CreateObject(12345);
- QuicArenaScopedPtr<TestObject> ptr2(std::move(ptr1));
- EXPECT_EQ(nullptr, ptr1);
- EXPECT_EQ(12345u, ptr2->value);
-}
-
-TEST_P(QuicArenaScopedPtrParamTest, Accessors) {
- QuicArenaScopedPtr<TestObject> ptr = CreateObject(12345);
- EXPECT_EQ(12345u, (*ptr).value);
- EXPECT_EQ(12345u, ptr->value);
- // We explicitly want to test that get() returns a valid pointer to the data,
- // but the call looks redundant.
- EXPECT_EQ(12345u, ptr.get()->value); // NOLINT
-}
-
-TEST_P(QuicArenaScopedPtrParamTest, Reset) {
- QuicArenaScopedPtr<TestObject> ptr = CreateObject(12345);
- ptr.reset(new TestObject(54321));
- EXPECT_EQ(54321u, ptr->value);
-}
-
-TEST_P(QuicArenaScopedPtrParamTest, Swap) {
- QuicArenaScopedPtr<TestObject> ptr1 = CreateObject(12345);
- QuicArenaScopedPtr<TestObject> ptr2 = CreateObject(54321);
- ptr1.swap(ptr2);
- EXPECT_EQ(12345u, ptr2->value);
- EXPECT_EQ(54321u, ptr1->value);
-}
-
-} // namespace
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_bandwidth.cc b/chromium/net/third_party/quiche/src/quic/core/quic_bandwidth.cc
deleted file mode 100644
index b4108bea510..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_bandwidth.cc
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_bandwidth.h"
-
-#include <cinttypes>
-#include <string>
-
-#include "absl/strings/str_format.h"
-#include "absl/strings/string_view.h"
-
-namespace quic {
-
-std::string QuicBandwidth::ToDebuggingValue() const {
- if (bits_per_second_ < 80000) {
- return absl::StrFormat("%d bits/s (%d bytes/s)", bits_per_second_,
- bits_per_second_ / 8);
- }
-
- double divisor;
- char unit;
- if (bits_per_second_ < 8 * 1000 * 1000) {
- divisor = 1e3;
- unit = 'k';
- } else if (bits_per_second_ < INT64_C(8) * 1000 * 1000 * 1000) {
- divisor = 1e6;
- unit = 'M';
- } else {
- divisor = 1e9;
- unit = 'G';
- }
-
- double bits_per_second_with_unit = bits_per_second_ / divisor;
- double bytes_per_second_with_unit = bits_per_second_with_unit / 8;
- return absl::StrFormat("%.2f %cbits/s (%.2f %cbytes/s)",
- bits_per_second_with_unit, unit,
- bytes_per_second_with_unit, unit);
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_bandwidth.h b/chromium/net/third_party/quiche/src/quic/core/quic_bandwidth.h
deleted file mode 100644
index 949c264e31e..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_bandwidth.h
+++ /dev/null
@@ -1,164 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// QuicBandwidth represents a bandwidth, stored in bits per second resolution.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_BANDWIDTH_H_
-#define QUICHE_QUIC_CORE_QUIC_BANDWIDTH_H_
-
-#include <cmath>
-#include <cstdint>
-#include <limits>
-#include <ostream>
-#include <string>
-
-#include "quic/core/quic_constants.h"
-#include "quic/core/quic_time.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_export.h"
-#include "quic/platform/api/quic_flag_utils.h"
-
-namespace quic {
-
-class QUIC_EXPORT_PRIVATE QuicBandwidth {
- public:
- // Creates a new QuicBandwidth with an internal value of 0.
- static constexpr QuicBandwidth Zero() { return QuicBandwidth(0); }
-
- // Creates a new QuicBandwidth with an internal value of INT64_MAX.
- static constexpr QuicBandwidth Infinite() {
- return QuicBandwidth(std::numeric_limits<int64_t>::max());
- }
-
- // Create a new QuicBandwidth holding the bits per second.
- static constexpr QuicBandwidth FromBitsPerSecond(int64_t bits_per_second) {
- return QuicBandwidth(bits_per_second);
- }
-
- // Create a new QuicBandwidth holding the kilo bits per second.
- static constexpr QuicBandwidth FromKBitsPerSecond(int64_t k_bits_per_second) {
- return QuicBandwidth(k_bits_per_second * 1000);
- }
-
- // Create a new QuicBandwidth holding the bytes per second.
- static constexpr QuicBandwidth FromBytesPerSecond(int64_t bytes_per_second) {
- return QuicBandwidth(bytes_per_second * 8);
- }
-
- // Create a new QuicBandwidth holding the kilo bytes per second.
- static constexpr QuicBandwidth FromKBytesPerSecond(
- int64_t k_bytes_per_second) {
- return QuicBandwidth(k_bytes_per_second * 8000);
- }
-
- // Create a new QuicBandwidth based on the bytes per the elapsed delta.
- static inline QuicBandwidth FromBytesAndTimeDelta(QuicByteCount bytes,
- QuicTime::Delta delta) {
- if (bytes == 0) {
- return QuicBandwidth(0);
- }
-
- // 1 bit is 1000000 micro bits.
- int64_t num_micro_bits = 8 * bytes * kNumMicrosPerSecond;
- if (num_micro_bits < delta.ToMicroseconds()) {
- return QuicBandwidth(1);
- }
-
- return QuicBandwidth(num_micro_bits / delta.ToMicroseconds());
- }
-
- inline int64_t ToBitsPerSecond() const { return bits_per_second_; }
-
- inline int64_t ToKBitsPerSecond() const { return bits_per_second_ / 1000; }
-
- inline int64_t ToBytesPerSecond() const { return bits_per_second_ / 8; }
-
- inline int64_t ToKBytesPerSecond() const { return bits_per_second_ / 8000; }
-
- inline QuicByteCount ToBytesPerPeriod(QuicTime::Delta time_period) const {
- return bits_per_second_ * time_period.ToMicroseconds() / 8 /
- kNumMicrosPerSecond;
- }
-
- inline int64_t ToKBytesPerPeriod(QuicTime::Delta time_period) const {
- return bits_per_second_ * time_period.ToMicroseconds() / 8000 /
- kNumMicrosPerSecond;
- }
-
- inline bool IsZero() const { return bits_per_second_ == 0; }
- inline bool IsInfinite() const {
- return bits_per_second_ == Infinite().ToBitsPerSecond();
- }
-
- inline QuicTime::Delta TransferTime(QuicByteCount bytes) const {
- if (bits_per_second_ == 0) {
- return QuicTime::Delta::Zero();
- }
- return QuicTime::Delta::FromMicroseconds(bytes * 8 * kNumMicrosPerSecond /
- bits_per_second_);
- }
-
- std::string ToDebuggingValue() const;
-
- private:
- explicit constexpr QuicBandwidth(int64_t bits_per_second)
- : bits_per_second_(bits_per_second >= 0 ? bits_per_second : 0) {}
-
- int64_t bits_per_second_;
-
- friend QuicBandwidth operator+(QuicBandwidth lhs, QuicBandwidth rhs);
- friend QuicBandwidth operator-(QuicBandwidth lhs, QuicBandwidth rhs);
- friend QuicBandwidth operator*(QuicBandwidth lhs, float factor);
-};
-
-// Non-member relational operators for QuicBandwidth.
-inline bool operator==(QuicBandwidth lhs, QuicBandwidth rhs) {
- return lhs.ToBitsPerSecond() == rhs.ToBitsPerSecond();
-}
-inline bool operator!=(QuicBandwidth lhs, QuicBandwidth rhs) {
- return !(lhs == rhs);
-}
-inline bool operator<(QuicBandwidth lhs, QuicBandwidth rhs) {
- return lhs.ToBitsPerSecond() < rhs.ToBitsPerSecond();
-}
-inline bool operator>(QuicBandwidth lhs, QuicBandwidth rhs) {
- return rhs < lhs;
-}
-inline bool operator<=(QuicBandwidth lhs, QuicBandwidth rhs) {
- return !(rhs < lhs);
-}
-inline bool operator>=(QuicBandwidth lhs, QuicBandwidth rhs) {
- return !(lhs < rhs);
-}
-
-// Non-member arithmetic operators for QuicBandwidth.
-inline QuicBandwidth operator+(QuicBandwidth lhs, QuicBandwidth rhs) {
- return QuicBandwidth(lhs.bits_per_second_ + rhs.bits_per_second_);
-}
-inline QuicBandwidth operator-(QuicBandwidth lhs, QuicBandwidth rhs) {
- return QuicBandwidth(lhs.bits_per_second_ - rhs.bits_per_second_);
-}
-inline QuicBandwidth operator*(QuicBandwidth lhs, float rhs) {
- return QuicBandwidth(
- static_cast<int64_t>(std::llround(lhs.bits_per_second_ * rhs)));
-}
-inline QuicBandwidth operator*(float lhs, QuicBandwidth rhs) {
- return rhs * lhs;
-}
-inline QuicByteCount operator*(QuicBandwidth lhs, QuicTime::Delta rhs) {
- return lhs.ToBytesPerPeriod(rhs);
-}
-inline QuicByteCount operator*(QuicTime::Delta lhs, QuicBandwidth rhs) {
- return rhs * lhs;
-}
-
-// Override stream output operator for gtest.
-inline std::ostream& operator<<(std::ostream& output,
- const QuicBandwidth bandwidth) {
- output << bandwidth.ToDebuggingValue();
- return output;
-}
-
-} // namespace quic
-#endif // QUICHE_QUIC_CORE_QUIC_BANDWIDTH_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_bandwidth_test.cc b/chromium/net/third_party/quiche/src/quic/core/quic_bandwidth_test.cc
deleted file mode 100644
index 7811b47e445..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_bandwidth_test.cc
+++ /dev/null
@@ -1,151 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_bandwidth.h"
-
-#include <limits>
-
-#include "quic/core/quic_time.h"
-#include "quic/platform/api/quic_test.h"
-
-namespace quic {
-namespace test {
-
-class QuicBandwidthTest : public QuicTest {};
-
-TEST_F(QuicBandwidthTest, FromTo) {
- EXPECT_EQ(QuicBandwidth::FromKBitsPerSecond(1),
- QuicBandwidth::FromBitsPerSecond(1000));
- EXPECT_EQ(QuicBandwidth::FromKBytesPerSecond(1),
- QuicBandwidth::FromBytesPerSecond(1000));
- EXPECT_EQ(QuicBandwidth::FromBitsPerSecond(8000),
- QuicBandwidth::FromBytesPerSecond(1000));
- EXPECT_EQ(QuicBandwidth::FromKBitsPerSecond(8),
- QuicBandwidth::FromKBytesPerSecond(1));
-
- EXPECT_EQ(0, QuicBandwidth::Zero().ToBitsPerSecond());
- EXPECT_EQ(0, QuicBandwidth::Zero().ToKBitsPerSecond());
- EXPECT_EQ(0, QuicBandwidth::Zero().ToBytesPerSecond());
- EXPECT_EQ(0, QuicBandwidth::Zero().ToKBytesPerSecond());
-
- EXPECT_EQ(1, QuicBandwidth::FromBitsPerSecond(1000).ToKBitsPerSecond());
- EXPECT_EQ(1000, QuicBandwidth::FromKBitsPerSecond(1).ToBitsPerSecond());
- EXPECT_EQ(1, QuicBandwidth::FromBytesPerSecond(1000).ToKBytesPerSecond());
- EXPECT_EQ(1000, QuicBandwidth::FromKBytesPerSecond(1).ToBytesPerSecond());
-}
-
-TEST_F(QuicBandwidthTest, Add) {
- QuicBandwidth bandwidht_1 = QuicBandwidth::FromKBitsPerSecond(1);
- QuicBandwidth bandwidht_2 = QuicBandwidth::FromKBytesPerSecond(1);
-
- EXPECT_EQ(9000, (bandwidht_1 + bandwidht_2).ToBitsPerSecond());
- EXPECT_EQ(9000, (bandwidht_2 + bandwidht_1).ToBitsPerSecond());
-}
-
-TEST_F(QuicBandwidthTest, Subtract) {
- QuicBandwidth bandwidht_1 = QuicBandwidth::FromKBitsPerSecond(1);
- QuicBandwidth bandwidht_2 = QuicBandwidth::FromKBytesPerSecond(1);
-
- EXPECT_EQ(7000, (bandwidht_2 - bandwidht_1).ToBitsPerSecond());
-}
-
-TEST_F(QuicBandwidthTest, TimeDelta) {
- EXPECT_EQ(QuicBandwidth::FromKBytesPerSecond(1000),
- QuicBandwidth::FromBytesAndTimeDelta(
- 1000, QuicTime::Delta::FromMilliseconds(1)));
-
- EXPECT_EQ(QuicBandwidth::FromKBytesPerSecond(10),
- QuicBandwidth::FromBytesAndTimeDelta(
- 1000, QuicTime::Delta::FromMilliseconds(100)));
-
- EXPECT_EQ(QuicBandwidth::Zero(), QuicBandwidth::FromBytesAndTimeDelta(
- 0, QuicTime::Delta::FromSeconds(9)));
-
- EXPECT_EQ(
- QuicBandwidth::FromBitsPerSecond(1),
- QuicBandwidth::FromBytesAndTimeDelta(1, QuicTime::Delta::FromSeconds(9)));
-}
-
-TEST_F(QuicBandwidthTest, Scale) {
- EXPECT_EQ(QuicBandwidth::FromKBytesPerSecond(500),
- QuicBandwidth::FromKBytesPerSecond(1000) * 0.5f);
- EXPECT_EQ(QuicBandwidth::FromKBytesPerSecond(750),
- 0.75f * QuicBandwidth::FromKBytesPerSecond(1000));
- EXPECT_EQ(QuicBandwidth::FromKBytesPerSecond(1250),
- QuicBandwidth::FromKBytesPerSecond(1000) * 1.25f);
-
- // Ensure we are rounding correctly within a 1bps level of precision.
- EXPECT_EQ(QuicBandwidth::FromBitsPerSecond(5),
- QuicBandwidth::FromBitsPerSecond(9) * 0.5f);
- EXPECT_EQ(QuicBandwidth::FromBitsPerSecond(2),
- QuicBandwidth::FromBitsPerSecond(12) * 0.2f);
-}
-
-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)));
-
- // 1599 * 1001 = 1600599 bits/ms = 200.074875 bytes/s.
- EXPECT_EQ(200u, QuicBandwidth::FromBitsPerSecond(1599).ToBytesPerPeriod(
- QuicTime::Delta::FromMilliseconds(1001)));
-
- EXPECT_EQ(200u, QuicBandwidth::FromBitsPerSecond(1599).ToKBytesPerPeriod(
- QuicTime::Delta::FromSeconds(1001)));
-}
-
-TEST_F(QuicBandwidthTest, TransferTime) {
- EXPECT_EQ(QuicTime::Delta::FromSeconds(1),
- QuicBandwidth::FromKBytesPerSecond(1).TransferTime(1000));
- EXPECT_EQ(QuicTime::Delta::Zero(), QuicBandwidth::Zero().TransferTime(1000));
-}
-
-TEST_F(QuicBandwidthTest, RelOps) {
- const QuicBandwidth b1 = QuicBandwidth::FromKBitsPerSecond(1);
- const QuicBandwidth b2 = QuicBandwidth::FromKBytesPerSecond(2);
- EXPECT_EQ(b1, b1);
- EXPECT_NE(b1, b2);
- EXPECT_LT(b1, b2);
- EXPECT_GT(b2, b1);
- EXPECT_LE(b1, b1);
- EXPECT_LE(b1, b2);
- EXPECT_GE(b1, b1);
- EXPECT_GE(b2, b1);
-}
-
-TEST_F(QuicBandwidthTest, DebuggingValue) {
- EXPECT_EQ("128 bits/s (16 bytes/s)",
- QuicBandwidth::FromBytesPerSecond(16).ToDebuggingValue());
- EXPECT_EQ("4096 bits/s (512 bytes/s)",
- QuicBandwidth::FromBytesPerSecond(512).ToDebuggingValue());
-
- QuicBandwidth bandwidth = QuicBandwidth::FromBytesPerSecond(1000 * 50);
- EXPECT_EQ("400.00 kbits/s (50.00 kbytes/s)", bandwidth.ToDebuggingValue());
-
- bandwidth = bandwidth * 1000;
- EXPECT_EQ("400.00 Mbits/s (50.00 Mbytes/s)", bandwidth.ToDebuggingValue());
-
- bandwidth = bandwidth * 1000;
- EXPECT_EQ("400.00 Gbits/s (50.00 Gbytes/s)", bandwidth.ToDebuggingValue());
-}
-
-TEST_F(QuicBandwidthTest, SpecialValues) {
- EXPECT_EQ(0, QuicBandwidth::Zero().ToBitsPerSecond());
- EXPECT_EQ(std::numeric_limits<int64_t>::max(),
- QuicBandwidth::Infinite().ToBitsPerSecond());
-
- EXPECT_TRUE(QuicBandwidth::Zero().IsZero());
- EXPECT_FALSE(QuicBandwidth::Zero().IsInfinite());
-
- EXPECT_TRUE(QuicBandwidth::Infinite().IsInfinite());
- EXPECT_FALSE(QuicBandwidth::Infinite().IsZero());
-}
-
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_blocked_writer_interface.h b/chromium/net/third_party/quiche/src/quic/core/quic_blocked_writer_interface.h
deleted file mode 100644
index b441d926c3f..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_blocked_writer_interface.h
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// This is an interface for all objects that want to be notified that
-// the underlying UDP socket is available for writing (not write blocked
-// anymore).
-
-#ifndef QUICHE_QUIC_CORE_QUIC_BLOCKED_WRITER_INTERFACE_H_
-#define QUICHE_QUIC_CORE_QUIC_BLOCKED_WRITER_INTERFACE_H_
-
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-class QUIC_EXPORT_PRIVATE QuicBlockedWriterInterface {
- public:
- virtual ~QuicBlockedWriterInterface() {}
-
- // Called by the PacketWriter when the underlying socket becomes writable
- // so that the BlockedWriter can go ahead and try writing.
- virtual void OnBlockedWriterCanWrite() = 0;
-
- virtual bool IsWriterBlocked() const = 0;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_QUIC_BLOCKED_WRITER_INTERFACE_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_buffer_allocator.cc b/chromium/net/third_party/quiche/src/quic/core/quic_buffer_allocator.cc
deleted file mode 100644
index 41491d97c72..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_buffer_allocator.cc
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_buffer_allocator.h"
-
-namespace quic {
-
-QuicBufferAllocator::~QuicBufferAllocator() = default;
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_buffer_allocator.h b/chromium/net/third_party/quiche/src/quic/core/quic_buffer_allocator.h
deleted file mode 100644
index d3905e70064..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_buffer_allocator.h
+++ /dev/null
@@ -1,114 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_BUFFER_ALLOCATOR_H_
-#define QUICHE_QUIC_CORE_QUIC_BUFFER_ALLOCATOR_H_
-
-#include <stddef.h>
-
-#include <memory>
-
-#include "absl/strings/string_view.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// Abstract base class for classes which allocate and delete buffers.
-class QUIC_EXPORT_PRIVATE QuicBufferAllocator {
- public:
- virtual ~QuicBufferAllocator();
-
- // Returns or allocates a new buffer of |size|. Never returns null.
- virtual char* New(size_t size) = 0;
-
- // Returns or allocates a new buffer of |size| if |flag_enable| is true.
- // Otherwise, returns a buffer that is compatible with this class directly
- // with operator new. Never returns null.
- virtual char* New(size_t size, bool flag_enable) = 0;
-
- // Releases a buffer.
- virtual void Delete(char* buffer) = 0;
-
- // Marks the allocator as being idle. Serves as a hint to notify the allocator
- // that it should release any resources it's still holding on to.
- virtual void MarkAllocatorIdle() {}
-};
-
-// A deleter that can be used to manage ownership of buffers allocated via
-// QuicBufferAllocator through std::unique_ptr.
-class QUIC_EXPORT_PRIVATE QuicBufferDeleter {
- public:
- explicit QuicBufferDeleter(QuicBufferAllocator* allocator)
- : allocator_(allocator) {}
-
- QuicBufferAllocator* allocator() { return allocator_; }
- void operator()(char* buffer) { allocator_->Delete(buffer); }
-
- private:
- QuicBufferAllocator* allocator_;
-};
-
-using QuicUniqueBufferPtr = std::unique_ptr<char[], QuicBufferDeleter>;
-
-inline QuicUniqueBufferPtr MakeUniqueBuffer(QuicBufferAllocator* allocator,
- size_t size) {
- return QuicUniqueBufferPtr(allocator->New(size),
- QuicBufferDeleter(allocator));
-}
-
-// QuicUniqueBufferPtr with a length attached to it. Similar to QuicMemSlice,
-// except unlike QuicMemSlice, QuicBuffer is mutable and is not
-// platform-specific. Also unlike QuicMemSlice, QuicBuffer can be empty.
-class QUIC_EXPORT_PRIVATE QuicBuffer {
- public:
- QuicBuffer() : buffer_(nullptr, QuicBufferDeleter(nullptr)), size_(0) {}
- QuicBuffer(QuicBufferAllocator* allocator, size_t size)
- : buffer_(MakeUniqueBuffer(allocator, size)), size_(size) {}
-
- // Make sure the move constructor zeroes out the size field.
- QuicBuffer(QuicBuffer&& other)
- : buffer_(std::move(other.buffer_)), size_(other.size_) {
- other.buffer_ = nullptr;
- other.size_ = 0;
- }
- QuicBuffer& operator=(QuicBuffer&& other) {
- buffer_ = std::move(other.buffer_);
- size_ = other.size_;
-
- other.buffer_ = nullptr;
- other.size_ = 0;
- return *this;
- }
-
- // Convenience method to initialize a QuicBuffer by copying from an existing
- // one.
- static QuicBuffer Copy(QuicBufferAllocator* allocator,
- absl::string_view data) {
- QuicBuffer result(allocator, data.size());
- memcpy(result.data(), data.data(), data.size());
- return result;
- }
-
- const char* data() const { return buffer_.get(); }
- char* data() { return buffer_.get(); }
- size_t size() const { return size_; }
- bool empty() const { return size_ == 0; }
- absl::string_view AsStringView() const {
- return absl::string_view(data(), size());
- }
-
- // Releases the ownership of the underlying buffer.
- QuicUniqueBufferPtr Release() {
- size_ = 0;
- return std::move(buffer_);
- }
-
- private:
- QuicUniqueBufferPtr buffer_;
- size_t size_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_QUIC_BUFFER_ALLOCATOR_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_buffered_packet_store.cc b/chromium/net/third_party/quiche/src/quic/core/quic_buffered_packet_store.cc
deleted file mode 100644
index f597ce07131..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_buffered_packet_store.cc
+++ /dev/null
@@ -1,283 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_buffered_packet_store.h"
-
-#include <string>
-
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_flags.h"
-
-namespace quic {
-
-using BufferedPacket = QuicBufferedPacketStore::BufferedPacket;
-using BufferedPacketList = QuicBufferedPacketStore::BufferedPacketList;
-using EnqueuePacketResult = QuicBufferedPacketStore::EnqueuePacketResult;
-
-// Max number of connections this store can keep track.
-static const size_t kDefaultMaxConnectionsInStore = 100;
-// Up to half of the capacity can be used for storing non-CHLO packets.
-static const size_t kMaxConnectionsWithoutCHLO =
- kDefaultMaxConnectionsInStore / 2;
-
-namespace {
-
-// This alarm removes expired entries in map each time this alarm fires.
-class ConnectionExpireAlarm : public QuicAlarm::DelegateWithoutContext {
- public:
- explicit ConnectionExpireAlarm(QuicBufferedPacketStore* store)
- : connection_store_(store) {}
-
- void OnAlarm() override { connection_store_->OnExpirationTimeout(); }
-
- ConnectionExpireAlarm(const ConnectionExpireAlarm&) = delete;
- ConnectionExpireAlarm& operator=(const ConnectionExpireAlarm&) = delete;
-
- private:
- QuicBufferedPacketStore* connection_store_;
-};
-
-} // namespace
-
-BufferedPacket::BufferedPacket(std::unique_ptr<QuicReceivedPacket> packet,
- QuicSocketAddress self_address,
- QuicSocketAddress peer_address)
- : packet(std::move(packet)),
- self_address(self_address),
- peer_address(peer_address) {}
-
-BufferedPacket::BufferedPacket(BufferedPacket&& other) = default;
-
-BufferedPacket& BufferedPacket::operator=(BufferedPacket&& other) = default;
-
-BufferedPacket::~BufferedPacket() {}
-
-BufferedPacketList::BufferedPacketList()
- : creation_time(QuicTime::Zero()),
- ietf_quic(false),
- version(ParsedQuicVersion::Unsupported()) {}
-
-BufferedPacketList::BufferedPacketList(BufferedPacketList&& other) = default;
-
-BufferedPacketList& BufferedPacketList::operator=(BufferedPacketList&& other) =
- default;
-
-BufferedPacketList::~BufferedPacketList() {}
-
-QuicBufferedPacketStore::QuicBufferedPacketStore(
- VisitorInterface* visitor,
- const QuicClock* clock,
- QuicAlarmFactory* alarm_factory)
- : connection_life_span_(
- QuicTime::Delta::FromSeconds(kInitialIdleTimeoutSecs)),
- visitor_(visitor),
- clock_(clock),
- expiration_alarm_(
- alarm_factory->CreateAlarm(new ConnectionExpireAlarm(this))) {}
-
-QuicBufferedPacketStore::~QuicBufferedPacketStore() {
- if (expiration_alarm_ != nullptr) {
- expiration_alarm_->PermanentCancel();
- }
-}
-
-EnqueuePacketResult QuicBufferedPacketStore::EnqueuePacket(
- QuicConnectionId connection_id, bool ietf_quic,
- const QuicReceivedPacket& packet, QuicSocketAddress self_address,
- QuicSocketAddress peer_address, const ParsedQuicVersion& version,
- absl::optional<ParsedClientHello> parsed_chlo) {
- const bool is_chlo = parsed_chlo.has_value();
- QUIC_BUG_IF(quic_bug_12410_1, !GetQuicFlag(FLAGS_quic_allow_chlo_buffering))
- << "Shouldn't buffer packets if disabled via flag.";
- QUIC_BUG_IF(quic_bug_12410_2,
- is_chlo && connections_with_chlo_.contains(connection_id))
- << "Shouldn't buffer duplicated CHLO on connection " << connection_id;
- QUIC_BUG_IF(quic_bug_12410_4, is_chlo && !version.IsKnown())
- << "Should have version for CHLO packet.";
-
- const bool is_first_packet = !undecryptable_packets_.contains(connection_id);
- if (is_first_packet) {
- if (ShouldNotBufferPacket(is_chlo)) {
- // Drop the packet if the upper limit of undecryptable packets has been
- // reached or the whole capacity of the store has been reached.
- return TOO_MANY_CONNECTIONS;
- }
- undecryptable_packets_.emplace(
- std::make_pair(connection_id, BufferedPacketList()));
- undecryptable_packets_.back().second.ietf_quic = ietf_quic;
- undecryptable_packets_.back().second.version = version;
- }
- QUICHE_CHECK(undecryptable_packets_.contains(connection_id));
- BufferedPacketList& queue =
- undecryptable_packets_.find(connection_id)->second;
-
- if (!is_chlo) {
- // If current packet is not CHLO, it might not be buffered because store
- // only buffers certain number of undecryptable packets per connection.
- size_t num_non_chlo_packets = connections_with_chlo_.contains(connection_id)
- ? (queue.buffered_packets.size() - 1)
- : queue.buffered_packets.size();
- if (num_non_chlo_packets >= kDefaultMaxUndecryptablePackets) {
- // If there are kMaxBufferedPacketsPerConnection packets buffered up for
- // this connection, drop the current packet.
- return TOO_MANY_PACKETS;
- }
- }
-
- if (queue.buffered_packets.empty()) {
- // If this is the first packet arrived on a new connection, initialize the
- // creation time.
- queue.creation_time = clock_->ApproximateNow();
- }
-
- BufferedPacket new_entry(std::unique_ptr<QuicReceivedPacket>(packet.Clone()),
- self_address, peer_address);
- if (is_chlo) {
- // Add CHLO to the beginning of buffered packets so that it can be delivered
- // first later.
- queue.buffered_packets.push_front(std::move(new_entry));
- queue.parsed_chlo = std::move(parsed_chlo);
- connections_with_chlo_[connection_id] = false; // Dummy value.
- // Set the version of buffered packets of this connection on CHLO.
- queue.version = version;
- } else {
- // Buffer non-CHLO packets in arrival order.
- queue.buffered_packets.push_back(std::move(new_entry));
-
- // Attempt to parse multi-packet TLS CHLOs.
- if (is_first_packet) {
- queue.tls_chlo_extractor.IngestPacket(version, packet);
- // Since this is the first packet and it's not a CHLO, the
- // TlsChloExtractor should not have the entire CHLO.
- QUIC_BUG_IF(quic_bug_12410_5,
- queue.tls_chlo_extractor.HasParsedFullChlo())
- << "First packet in list should not contain full CHLO";
- }
- // TODO(b/154857081) Reorder CHLO packets ahead of other ones.
- }
-
- MaybeSetExpirationAlarm();
- return SUCCESS;
-}
-
-bool QuicBufferedPacketStore::HasBufferedPackets(
- QuicConnectionId connection_id) const {
- return undecryptable_packets_.contains(connection_id);
-}
-
-bool QuicBufferedPacketStore::HasChlosBuffered() const {
- return !connections_with_chlo_.empty();
-}
-
-BufferedPacketList QuicBufferedPacketStore::DeliverPackets(
- QuicConnectionId connection_id) {
- BufferedPacketList packets_to_deliver;
- auto it = undecryptable_packets_.find(connection_id);
- if (it != undecryptable_packets_.end()) {
- packets_to_deliver = std::move(it->second);
- undecryptable_packets_.erase(connection_id);
- }
- return packets_to_deliver;
-}
-
-void QuicBufferedPacketStore::DiscardPackets(QuicConnectionId connection_id) {
- undecryptable_packets_.erase(connection_id);
- connections_with_chlo_.erase(connection_id);
-}
-
-void QuicBufferedPacketStore::DiscardAllPackets() {
- undecryptable_packets_.clear();
- connections_with_chlo_.clear();
- expiration_alarm_->Cancel();
-}
-
-void QuicBufferedPacketStore::OnExpirationTimeout() {
- QuicTime expiration_time = clock_->ApproximateNow() - connection_life_span_;
- while (!undecryptable_packets_.empty()) {
- auto& entry = undecryptable_packets_.front();
- if (entry.second.creation_time > expiration_time) {
- break;
- }
- QuicConnectionId connection_id = entry.first;
- visitor_->OnExpiredPackets(connection_id, std::move(entry.second));
- undecryptable_packets_.pop_front();
- connections_with_chlo_.erase(connection_id);
- }
- if (!undecryptable_packets_.empty()) {
- MaybeSetExpirationAlarm();
- }
-}
-
-void QuicBufferedPacketStore::MaybeSetExpirationAlarm() {
- if (!expiration_alarm_->IsSet()) {
- expiration_alarm_->Set(clock_->ApproximateNow() + connection_life_span_);
- }
-}
-
-bool QuicBufferedPacketStore::ShouldNotBufferPacket(bool is_chlo) {
- bool is_store_full =
- undecryptable_packets_.size() >= kDefaultMaxConnectionsInStore;
-
- if (is_chlo) {
- return is_store_full;
- }
-
- size_t num_connections_without_chlo =
- undecryptable_packets_.size() - connections_with_chlo_.size();
- bool reach_non_chlo_limit =
- num_connections_without_chlo >= kMaxConnectionsWithoutCHLO;
-
- return is_store_full || reach_non_chlo_limit;
-}
-
-BufferedPacketList QuicBufferedPacketStore::DeliverPacketsForNextConnection(
- QuicConnectionId* connection_id) {
- if (connections_with_chlo_.empty()) {
- // Returns empty list if no CHLO has been buffered.
- return BufferedPacketList();
- }
- *connection_id = connections_with_chlo_.front().first;
- connections_with_chlo_.pop_front();
-
- BufferedPacketList packets = DeliverPackets(*connection_id);
- QUICHE_DCHECK(!packets.buffered_packets.empty() &&
- packets.parsed_chlo.has_value())
- << "Try to deliver connectons without CHLO. # packets:"
- << packets.buffered_packets.size()
- << ", has_parsed_chlo:" << packets.parsed_chlo.has_value();
- return packets;
-}
-
-bool QuicBufferedPacketStore::HasChloForConnection(
- QuicConnectionId connection_id) {
- return connections_with_chlo_.contains(connection_id);
-}
-
-bool QuicBufferedPacketStore::IngestPacketForTlsChloExtraction(
- const QuicConnectionId& connection_id, const ParsedQuicVersion& version,
- const QuicReceivedPacket& packet, std::vector<std::string>* out_alpns,
- std::string* out_sni, bool* out_resumption_attempted,
- bool* out_early_data_attempted) {
- QUICHE_DCHECK_NE(out_alpns, nullptr);
- QUICHE_DCHECK_NE(out_sni, nullptr);
- QUICHE_DCHECK_EQ(version.handshake_protocol, PROTOCOL_TLS1_3);
- auto it = undecryptable_packets_.find(connection_id);
- if (it == undecryptable_packets_.end()) {
- QUIC_BUG(quic_bug_10838_1)
- << "Cannot ingest packet for unknown connection ID " << connection_id;
- return false;
- }
- it->second.tls_chlo_extractor.IngestPacket(version, packet);
- if (!it->second.tls_chlo_extractor.HasParsedFullChlo()) {
- return false;
- }
- const TlsChloExtractor& tls_chlo_extractor = it->second.tls_chlo_extractor;
- *out_alpns = tls_chlo_extractor.alpns();
- *out_sni = tls_chlo_extractor.server_name();
- *out_resumption_attempted = tls_chlo_extractor.resumption_attempted();
- *out_early_data_attempted = tls_chlo_extractor.early_data_attempted();
- return true;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_buffered_packet_store.h b/chromium/net/third_party/quiche/src/quic/core/quic_buffered_packet_store.h
deleted file mode 100644
index 9607054bd38..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_buffered_packet_store.h
+++ /dev/null
@@ -1,194 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_BUFFERED_PACKET_STORE_H_
-#define QUICHE_QUIC_CORE_QUIC_BUFFERED_PACKET_STORE_H_
-
-#include <list>
-#include <string>
-
-#include "quic/core/quic_alarm.h"
-#include "quic/core/quic_alarm_factory.h"
-#include "quic/core/quic_clock.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_time.h"
-#include "quic/core/tls_chlo_extractor.h"
-#include "quic/platform/api/quic_export.h"
-#include "quic/platform/api/quic_socket_address.h"
-#include "common/quiche_linked_hash_map.h"
-
-namespace quic {
-
-namespace test {
-class QuicBufferedPacketStorePeer;
-} // namespace test
-
-// This class buffers packets for each connection until either
-// 1) They are requested to be delivered via
-// DeliverPacket()/DeliverPacketsForNextConnection(), or
-// 2) They expire after exceeding their lifetime in the store.
-//
-// It can only buffer packets on certain number of connections. It has two pools
-// of connections: connections with CHLO buffered and those without CHLO. The
-// latter has its own upper limit along with the max number of connections this
-// store can hold. The former pool can grow till this store is full.
-class QUIC_NO_EXPORT QuicBufferedPacketStore {
- public:
- enum EnqueuePacketResult {
- SUCCESS = 0,
- TOO_MANY_PACKETS, // Too many packets stored up for a certain connection.
- TOO_MANY_CONNECTIONS // Too many connections stored up in the store.
- };
-
- struct QUIC_NO_EXPORT BufferedPacket {
- BufferedPacket(std::unique_ptr<QuicReceivedPacket> packet,
- QuicSocketAddress self_address,
- QuicSocketAddress peer_address);
- BufferedPacket(BufferedPacket&& other);
-
- BufferedPacket& operator=(BufferedPacket&& other);
-
- ~BufferedPacket();
-
- std::unique_ptr<QuicReceivedPacket> packet;
- QuicSocketAddress self_address;
- QuicSocketAddress peer_address;
- };
-
- // A queue of BufferedPackets for a connection.
- struct QUIC_NO_EXPORT BufferedPacketList {
- BufferedPacketList();
- BufferedPacketList(BufferedPacketList&& other);
-
- BufferedPacketList& operator=(BufferedPacketList&& other);
-
- ~BufferedPacketList();
-
- std::list<BufferedPacket> buffered_packets;
- QuicTime creation_time;
- // |parsed_chlo| is set iff the entire CHLO has been received.
- absl::optional<ParsedClientHello> parsed_chlo;
- // Indicating whether this is an IETF QUIC connection.
- bool ietf_quic;
- // If buffered_packets contains the CHLO, it is the version of the CHLO.
- // Otherwise, it is the version of the first packet in |buffered_packets|.
- ParsedQuicVersion version;
- TlsChloExtractor tls_chlo_extractor;
- };
-
- using BufferedPacketMap = quiche::QuicheLinkedHashMap<QuicConnectionId,
- BufferedPacketList,
- QuicConnectionIdHash>;
-
- class QUIC_NO_EXPORT VisitorInterface {
- public:
- virtual ~VisitorInterface() {}
-
- // Called for each expired connection when alarm fires.
- virtual void OnExpiredPackets(QuicConnectionId connection_id,
- BufferedPacketList early_arrived_packets) = 0;
- };
-
- QuicBufferedPacketStore(VisitorInterface* visitor, const QuicClock* clock,
- QuicAlarmFactory* alarm_factory);
-
- QuicBufferedPacketStore(const QuicBufferedPacketStore&) = delete;
-
- ~QuicBufferedPacketStore();
-
- QuicBufferedPacketStore& operator=(const QuicBufferedPacketStore&) = delete;
-
- // Adds a copy of packet into the packet queue for given connection. If the
- // packet is the last one of the CHLO, |parsed_chlo| will contain a parsed
- // version of the CHLO.
- EnqueuePacketResult EnqueuePacket(
- QuicConnectionId connection_id, bool ietf_quic,
- const QuicReceivedPacket& packet, QuicSocketAddress self_address,
- QuicSocketAddress peer_address, const ParsedQuicVersion& version,
- absl::optional<ParsedClientHello> parsed_chlo);
-
- // Returns true if there are any packets buffered for |connection_id|.
- bool HasBufferedPackets(QuicConnectionId connection_id) const;
-
- // Ingests this packet into the corresponding TlsChloExtractor. This should
- // only be called when HasBufferedPackets(connection_id) is true.
- // Returns whether we've now parsed a full multi-packet TLS CHLO.
- // When this returns true, |out_alpns| is populated with the list of ALPNs
- // extracted from the CHLO. |out_sni| is populated with the SNI tag in CHLO.
- // |out_resumption_attempted| is populated if the CHLO has the
- // 'pre_shared_key' TLS extension. |out_early_data_attempted| is populated if
- // the CHLO has the 'early_data' TLS extension.
- bool IngestPacketForTlsChloExtraction(const QuicConnectionId& connection_id,
- const ParsedQuicVersion& version,
- const QuicReceivedPacket& packet,
- std::vector<std::string>* out_alpns,
- std::string* out_sni,
- bool* out_resumption_attempted,
- bool* out_early_data_attempted);
-
- // Returns the list of buffered packets for |connection_id| and removes them
- // from the store. Returns an empty list if no early arrived packets for this
- // connection are present.
- BufferedPacketList DeliverPackets(QuicConnectionId connection_id);
-
- // Discards packets buffered for |connection_id|, if any.
- void DiscardPackets(QuicConnectionId connection_id);
-
- // Discards all the packets.
- void DiscardAllPackets();
-
- // Examines how long packets have been buffered in the store for each
- // connection. If they stay too long, removes them for new coming packets and
- // calls |visitor_|'s OnPotentialConnectionExpire().
- // Resets the alarm at the end.
- void OnExpirationTimeout();
-
- // Delivers buffered packets for next connection with CHLO to open.
- // Return connection id for next connection in |connection_id|
- // and all buffered packets including CHLO.
- // The returned list should at least has one packet(CHLO) if
- // store does have any connection to open. If no connection in the store has
- // received CHLO yet, empty list will be returned.
- BufferedPacketList DeliverPacketsForNextConnection(
- QuicConnectionId* connection_id);
-
- // Is given connection already buffered in the store?
- bool HasChloForConnection(QuicConnectionId connection_id);
-
- // Is there any CHLO buffered in the store?
- bool HasChlosBuffered() const;
-
- private:
- friend class test::QuicBufferedPacketStorePeer;
-
- // Set expiration alarm if it hasn't been set.
- void MaybeSetExpirationAlarm();
-
- // Return true if add an extra packet will go beyond allowed max connection
- // limit. The limit for non-CHLO packet and CHLO packet is different.
- bool ShouldNotBufferPacket(bool is_chlo);
-
- // A map to store packet queues with creation time for each connection.
- BufferedPacketMap undecryptable_packets_;
-
- // The max time the packets of a connection can be buffer in the store.
- const QuicTime::Delta connection_life_span_;
-
- VisitorInterface* visitor_; // Unowned.
-
- const QuicClock* clock_; // Unowned.
-
- // This alarm fires every |connection_life_span_| to clean up
- // packets staying in the store for too long.
- std::unique_ptr<QuicAlarm> expiration_alarm_;
-
- // Keeps track of connection with CHLO buffered up already and the order they
- // arrive.
- quiche::QuicheLinkedHashMap<QuicConnectionId, bool, QuicConnectionIdHash>
- connections_with_chlo_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_QUIC_BUFFERED_PACKET_STORE_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_buffered_packet_store_test.cc b/chromium/net/third_party/quiche/src/quic/core/quic_buffered_packet_store_test.cc
deleted file mode 100644
index 7e51751e4f5..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_buffered_packet_store_test.cc
+++ /dev/null
@@ -1,452 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_buffered_packet_store.h"
-
-#include <list>
-#include <string>
-
-#include "quic/core/quic_versions.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/mock_clock.h"
-#include "quic/test_tools/quic_buffered_packet_store_peer.h"
-#include "quic/test_tools/quic_test_utils.h"
-
-namespace quic {
-static const size_t kDefaultMaxConnectionsInStore = 100;
-static const size_t kMaxConnectionsWithoutCHLO =
- kDefaultMaxConnectionsInStore / 2;
-
-namespace test {
-namespace {
-
-const absl::optional<ParsedClientHello> kNoParsedChlo;
-const absl::optional<ParsedClientHello> kDefaultParsedChlo =
- absl::make_optional<ParsedClientHello>();
-
-using BufferedPacket = QuicBufferedPacketStore::BufferedPacket;
-using BufferedPacketList = QuicBufferedPacketStore::BufferedPacketList;
-using EnqueuePacketResult = QuicBufferedPacketStore::EnqueuePacketResult;
-class QuicBufferedPacketStoreVisitor
- : public QuicBufferedPacketStore::VisitorInterface {
- public:
- QuicBufferedPacketStoreVisitor() {}
-
- ~QuicBufferedPacketStoreVisitor() override {}
-
- void OnExpiredPackets(QuicConnectionId /*connection_id*/,
- BufferedPacketList early_arrived_packets) override {
- last_expired_packet_queue_ = std::move(early_arrived_packets);
- }
-
- // The packets queue for most recently expirect connection.
- BufferedPacketList last_expired_packet_queue_;
-};
-
-class QuicBufferedPacketStoreTest : public QuicTest {
- public:
- QuicBufferedPacketStoreTest()
- : store_(&visitor_, &clock_, &alarm_factory_),
- self_address_(QuicIpAddress::Any6(), 65535),
- peer_address_(QuicIpAddress::Any6(), 65535),
- packet_content_("some encrypted content"),
- packet_time_(QuicTime::Zero() + QuicTime::Delta::FromMicroseconds(42)),
- packet_(packet_content_.data(), packet_content_.size(), packet_time_),
- invalid_version_(UnsupportedQuicVersion()),
- valid_version_(CurrentSupportedVersions().front()) {}
-
- protected:
- QuicBufferedPacketStoreVisitor visitor_;
- MockClock clock_;
- MockAlarmFactory alarm_factory_;
- QuicBufferedPacketStore store_;
- QuicSocketAddress self_address_;
- QuicSocketAddress peer_address_;
- std::string packet_content_;
- QuicTime packet_time_;
- QuicReceivedPacket packet_;
- const ParsedQuicVersion invalid_version_;
- const ParsedQuicVersion valid_version_;
-};
-
-TEST_F(QuicBufferedPacketStoreTest, SimpleEnqueueAndDeliverPacket) {
- QuicConnectionId connection_id = TestConnectionId(1);
- store_.EnqueuePacket(connection_id, false, packet_, self_address_,
- peer_address_, invalid_version_, kNoParsedChlo);
- EXPECT_TRUE(store_.HasBufferedPackets(connection_id));
- auto packets = store_.DeliverPackets(connection_id);
- const std::list<BufferedPacket>& queue = packets.buffered_packets;
- ASSERT_EQ(1u, queue.size());
- ASSERT_FALSE(packets.parsed_chlo.has_value());
- // There is no valid version because CHLO has not arrived.
- EXPECT_EQ(invalid_version_, packets.version);
- // Check content of the only packet in the queue.
- EXPECT_EQ(packet_content_, queue.front().packet->AsStringPiece());
- EXPECT_EQ(packet_time_, queue.front().packet->receipt_time());
- EXPECT_EQ(peer_address_, queue.front().peer_address);
- EXPECT_EQ(self_address_, queue.front().self_address);
- // No more packets on connection 1 should remain in the store.
- EXPECT_TRUE(store_.DeliverPackets(connection_id).buffered_packets.empty());
- EXPECT_FALSE(store_.HasBufferedPackets(connection_id));
-}
-
-TEST_F(QuicBufferedPacketStoreTest, DifferentPacketAddressOnOneConnection) {
- QuicSocketAddress addr_with_new_port(QuicIpAddress::Any4(), 256);
- QuicConnectionId connection_id = TestConnectionId(1);
- store_.EnqueuePacket(connection_id, false, packet_, self_address_,
- peer_address_, invalid_version_, kNoParsedChlo);
- store_.EnqueuePacket(connection_id, false, packet_, self_address_,
- addr_with_new_port, invalid_version_, kNoParsedChlo);
- std::list<BufferedPacket> queue =
- store_.DeliverPackets(connection_id).buffered_packets;
- ASSERT_EQ(2u, queue.size());
- // The address migration path should be preserved.
- EXPECT_EQ(peer_address_, queue.front().peer_address);
- EXPECT_EQ(addr_with_new_port, queue.back().peer_address);
-}
-
-TEST_F(QuicBufferedPacketStoreTest,
- EnqueueAndDeliverMultiplePacketsOnMultipleConnections) {
- size_t num_connections = 10;
- for (uint64_t conn_id = 1; conn_id <= num_connections; ++conn_id) {
- QuicConnectionId connection_id = TestConnectionId(conn_id);
- store_.EnqueuePacket(connection_id, false, packet_, self_address_,
- peer_address_, invalid_version_, kNoParsedChlo);
- store_.EnqueuePacket(connection_id, false, packet_, self_address_,
- peer_address_, invalid_version_, kNoParsedChlo);
- }
-
- // Deliver packets in reversed order.
- for (uint64_t conn_id = num_connections; conn_id > 0; --conn_id) {
- QuicConnectionId connection_id = TestConnectionId(conn_id);
- std::list<BufferedPacket> queue =
- store_.DeliverPackets(connection_id).buffered_packets;
- ASSERT_EQ(2u, queue.size());
- }
-}
-
-TEST_F(QuicBufferedPacketStoreTest,
- FailToBufferTooManyPacketsOnExistingConnection) {
- // Tests that for one connection, only limited number of packets can be
- // buffered.
- size_t num_packets = kDefaultMaxUndecryptablePackets + 1;
- QuicConnectionId connection_id = TestConnectionId(1);
- // Arrived CHLO packet shouldn't affect how many non-CHLO pacekts store can
- // keep.
- EXPECT_EQ(
- QuicBufferedPacketStore::SUCCESS,
- store_.EnqueuePacket(connection_id, false, packet_, self_address_,
- peer_address_, valid_version_, kDefaultParsedChlo));
- for (size_t i = 1; i <= num_packets; ++i) {
- // Only first |kDefaultMaxUndecryptablePackets packets| will be buffered.
- EnqueuePacketResult result =
- store_.EnqueuePacket(connection_id, false, packet_, self_address_,
- peer_address_, invalid_version_, kNoParsedChlo);
- if (i <= kDefaultMaxUndecryptablePackets) {
- EXPECT_EQ(EnqueuePacketResult::SUCCESS, result);
- } else {
- EXPECT_EQ(EnqueuePacketResult::TOO_MANY_PACKETS, result);
- }
- }
-
- // Only first |kDefaultMaxUndecryptablePackets| non-CHLO packets and CHLO are
- // buffered.
- EXPECT_EQ(kDefaultMaxUndecryptablePackets + 1,
- store_.DeliverPackets(connection_id).buffered_packets.size());
-}
-
-TEST_F(QuicBufferedPacketStoreTest, ReachNonChloConnectionUpperLimit) {
- // Tests that store can only keep early arrived packets for limited number of
- // connections.
- const size_t kNumConnections = kMaxConnectionsWithoutCHLO + 1;
- for (uint64_t conn_id = 1; conn_id <= kNumConnections; ++conn_id) {
- QuicConnectionId connection_id = TestConnectionId(conn_id);
- EnqueuePacketResult result =
- store_.EnqueuePacket(connection_id, false, packet_, self_address_,
- peer_address_, invalid_version_, kNoParsedChlo);
- if (conn_id <= kMaxConnectionsWithoutCHLO) {
- EXPECT_EQ(EnqueuePacketResult::SUCCESS, result);
- } else {
- EXPECT_EQ(EnqueuePacketResult::TOO_MANY_CONNECTIONS, result);
- }
- }
- // Store only keeps early arrived packets upto |kNumConnections| connections.
- for (uint64_t conn_id = 1; conn_id <= kNumConnections; ++conn_id) {
- QuicConnectionId connection_id = TestConnectionId(conn_id);
- std::list<BufferedPacket> queue =
- store_.DeliverPackets(connection_id).buffered_packets;
- if (conn_id <= kMaxConnectionsWithoutCHLO) {
- EXPECT_EQ(1u, queue.size());
- } else {
- EXPECT_EQ(0u, queue.size());
- }
- }
-}
-
-TEST_F(QuicBufferedPacketStoreTest,
- FullStoreFailToBufferDataPacketOnNewConnection) {
- // Send enough CHLOs so that store gets full before number of connections
- // without CHLO reaches its upper limit.
- size_t num_chlos =
- kDefaultMaxConnectionsInStore - kMaxConnectionsWithoutCHLO + 1;
- for (uint64_t conn_id = 1; conn_id <= num_chlos; ++conn_id) {
- EXPECT_EQ(EnqueuePacketResult::SUCCESS,
- store_.EnqueuePacket(TestConnectionId(conn_id), false, packet_,
- self_address_, peer_address_, valid_version_,
- kDefaultParsedChlo));
- }
-
- // Send data packets on another |kMaxConnectionsWithoutCHLO| connections.
- // Store should only be able to buffer till it's full.
- for (uint64_t conn_id = num_chlos + 1;
- conn_id <= (kDefaultMaxConnectionsInStore + 1); ++conn_id) {
- QuicConnectionId connection_id = TestConnectionId(conn_id);
- EnqueuePacketResult result =
- store_.EnqueuePacket(connection_id, false, packet_, self_address_,
- peer_address_, valid_version_, kDefaultParsedChlo);
- if (conn_id <= kDefaultMaxConnectionsInStore) {
- EXPECT_EQ(EnqueuePacketResult::SUCCESS, result);
- } else {
- EXPECT_EQ(EnqueuePacketResult::TOO_MANY_CONNECTIONS, result);
- }
- }
-}
-
-TEST_F(QuicBufferedPacketStoreTest, EnqueueChloOnTooManyDifferentConnections) {
- // Buffer data packets on different connections upto limit.
- for (uint64_t conn_id = 1; conn_id <= kMaxConnectionsWithoutCHLO; ++conn_id) {
- QuicConnectionId connection_id = TestConnectionId(conn_id);
- EXPECT_EQ(
- EnqueuePacketResult::SUCCESS,
- store_.EnqueuePacket(connection_id, false, packet_, self_address_,
- peer_address_, invalid_version_, kNoParsedChlo));
- }
-
- // Buffer CHLOs on other connections till store is full.
- for (size_t i = kMaxConnectionsWithoutCHLO + 1;
- i <= kDefaultMaxConnectionsInStore + 1; ++i) {
- QuicConnectionId connection_id = TestConnectionId(i);
- EnqueuePacketResult rs =
- store_.EnqueuePacket(connection_id, false, packet_, self_address_,
- peer_address_, valid_version_, kDefaultParsedChlo);
- if (i <= kDefaultMaxConnectionsInStore) {
- EXPECT_EQ(EnqueuePacketResult::SUCCESS, rs);
- EXPECT_TRUE(store_.HasChloForConnection(connection_id));
- } else {
- // Last CHLO can't be buffered because store is full.
- EXPECT_EQ(EnqueuePacketResult::TOO_MANY_CONNECTIONS, rs);
- EXPECT_FALSE(store_.HasChloForConnection(connection_id));
- }
- }
-
- // But buffering a CHLO belonging to a connection already has data packet
- // buffered in the store should success. This is the connection should be
- // delivered at last.
- EXPECT_EQ(
- EnqueuePacketResult::SUCCESS,
- store_.EnqueuePacket(
- /*connection_id=*/TestConnectionId(1), false, packet_, self_address_,
- peer_address_, valid_version_, kDefaultParsedChlo));
- EXPECT_TRUE(store_.HasChloForConnection(
- /*connection_id=*/TestConnectionId(1)));
-
- QuicConnectionId delivered_conn_id;
- for (size_t i = 0;
- i < kDefaultMaxConnectionsInStore - kMaxConnectionsWithoutCHLO + 1;
- ++i) {
- if (i < kDefaultMaxConnectionsInStore - kMaxConnectionsWithoutCHLO) {
- // Only CHLO is buffered.
- EXPECT_EQ(1u, store_.DeliverPacketsForNextConnection(&delivered_conn_id)
- .buffered_packets.size());
- EXPECT_EQ(TestConnectionId(i + kMaxConnectionsWithoutCHLO + 1),
- delivered_conn_id);
- } else {
- EXPECT_EQ(2u, store_.DeliverPacketsForNextConnection(&delivered_conn_id)
- .buffered_packets.size());
- EXPECT_EQ(TestConnectionId(1u), delivered_conn_id);
- }
- }
- EXPECT_FALSE(store_.HasChlosBuffered());
-}
-
-// Tests that store expires long-staying connections appropriately for
-// connections both with and without CHLOs.
-TEST_F(QuicBufferedPacketStoreTest, PacketQueueExpiredBeforeDelivery) {
- QuicConnectionId connection_id = TestConnectionId(1);
- store_.EnqueuePacket(connection_id, false, packet_, self_address_,
- peer_address_, invalid_version_, kNoParsedChlo);
- EXPECT_EQ(
- EnqueuePacketResult::SUCCESS,
- store_.EnqueuePacket(connection_id, false, packet_, self_address_,
- peer_address_, valid_version_, kDefaultParsedChlo));
- QuicConnectionId connection_id2 = TestConnectionId(2);
- EXPECT_EQ(
- EnqueuePacketResult::SUCCESS,
- store_.EnqueuePacket(connection_id2, false, packet_, self_address_,
- peer_address_, invalid_version_, kNoParsedChlo));
-
- // CHLO on connection 3 arrives 1ms later.
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(1));
- QuicConnectionId connection_id3 = TestConnectionId(3);
- // Use different client address to differetiate packets from different
- // connections.
- QuicSocketAddress another_client_address(QuicIpAddress::Any4(), 255);
- store_.EnqueuePacket(connection_id3, false, packet_, self_address_,
- another_client_address, valid_version_,
- kDefaultParsedChlo);
-
- // Advance clock to the time when connection 1 and 2 expires.
- clock_.AdvanceTime(
- QuicBufferedPacketStorePeer::expiration_alarm(&store_)->deadline() -
- clock_.ApproximateNow());
- ASSERT_GE(clock_.ApproximateNow(),
- QuicBufferedPacketStorePeer::expiration_alarm(&store_)->deadline());
- // Fire alarm to remove long-staying connection 1 and 2 packets.
- alarm_factory_.FireAlarm(
- QuicBufferedPacketStorePeer::expiration_alarm(&store_));
- EXPECT_EQ(1u, visitor_.last_expired_packet_queue_.buffered_packets.size());
- EXPECT_FALSE(store_.HasBufferedPackets(connection_id));
- EXPECT_FALSE(store_.HasBufferedPackets(connection_id2));
-
- // Try to deliver packets, but packet queue has been removed so no
- // packets can be returned.
- ASSERT_EQ(0u, store_.DeliverPackets(connection_id).buffered_packets.size());
- ASSERT_EQ(0u, store_.DeliverPackets(connection_id2).buffered_packets.size());
- QuicConnectionId delivered_conn_id;
- auto queue = store_.DeliverPacketsForNextConnection(&delivered_conn_id)
- .buffered_packets;
- // Connection 3 is the next to be delivered as connection 1 already expired.
- EXPECT_EQ(connection_id3, delivered_conn_id);
- ASSERT_EQ(1u, queue.size());
- // Packets in connection 3 should use another peer address.
- EXPECT_EQ(another_client_address, queue.front().peer_address);
-
- // Test the alarm is reset by enqueueing 2 packets for 4th connection and wait
- // for them to expire.
- QuicConnectionId connection_id4 = TestConnectionId(4);
- store_.EnqueuePacket(connection_id4, false, packet_, self_address_,
- peer_address_, invalid_version_, kNoParsedChlo);
- store_.EnqueuePacket(connection_id4, false, packet_, self_address_,
- peer_address_, invalid_version_, kNoParsedChlo);
- clock_.AdvanceTime(
- QuicBufferedPacketStorePeer::expiration_alarm(&store_)->deadline() -
- clock_.ApproximateNow());
- alarm_factory_.FireAlarm(
- QuicBufferedPacketStorePeer::expiration_alarm(&store_));
- // |last_expired_packet_queue_| should be updated.
- EXPECT_EQ(2u, visitor_.last_expired_packet_queue_.buffered_packets.size());
-}
-
-TEST_F(QuicBufferedPacketStoreTest, SimpleDiscardPackets) {
- QuicConnectionId connection_id = TestConnectionId(1);
-
- // Enqueue some packets
- store_.EnqueuePacket(connection_id, false, packet_, self_address_,
- peer_address_, invalid_version_, kNoParsedChlo);
- store_.EnqueuePacket(connection_id, false, packet_, self_address_,
- peer_address_, invalid_version_, kNoParsedChlo);
- EXPECT_TRUE(store_.HasBufferedPackets(connection_id));
- EXPECT_FALSE(store_.HasChlosBuffered());
-
- // Dicard the packets
- store_.DiscardPackets(connection_id);
-
- // No packets on connection 1 should remain in the store
- EXPECT_TRUE(store_.DeliverPackets(connection_id).buffered_packets.empty());
- EXPECT_FALSE(store_.HasBufferedPackets(connection_id));
- EXPECT_FALSE(store_.HasChlosBuffered());
-
- // Check idempotency
- store_.DiscardPackets(connection_id);
- EXPECT_TRUE(store_.DeliverPackets(connection_id).buffered_packets.empty());
- EXPECT_FALSE(store_.HasBufferedPackets(connection_id));
- EXPECT_FALSE(store_.HasChlosBuffered());
-}
-
-TEST_F(QuicBufferedPacketStoreTest, DiscardWithCHLOs) {
- QuicConnectionId connection_id = TestConnectionId(1);
-
- // Enqueue some packets, which include a CHLO
- store_.EnqueuePacket(connection_id, false, packet_, self_address_,
- peer_address_, invalid_version_, kNoParsedChlo);
- store_.EnqueuePacket(connection_id, false, packet_, self_address_,
- peer_address_, valid_version_, kDefaultParsedChlo);
- store_.EnqueuePacket(connection_id, false, packet_, self_address_,
- peer_address_, invalid_version_, kNoParsedChlo);
- EXPECT_TRUE(store_.HasBufferedPackets(connection_id));
- EXPECT_TRUE(store_.HasChlosBuffered());
-
- // Dicard the packets
- store_.DiscardPackets(connection_id);
-
- // No packets on connection 1 should remain in the store
- EXPECT_TRUE(store_.DeliverPackets(connection_id).buffered_packets.empty());
- EXPECT_FALSE(store_.HasBufferedPackets(connection_id));
- EXPECT_FALSE(store_.HasChlosBuffered());
-
- // Check idempotency
- store_.DiscardPackets(connection_id);
- EXPECT_TRUE(store_.DeliverPackets(connection_id).buffered_packets.empty());
- EXPECT_FALSE(store_.HasBufferedPackets(connection_id));
- EXPECT_FALSE(store_.HasChlosBuffered());
-}
-
-TEST_F(QuicBufferedPacketStoreTest, MultipleDiscardPackets) {
- QuicConnectionId connection_id_1 = TestConnectionId(1);
- QuicConnectionId connection_id_2 = TestConnectionId(2);
-
- // Enqueue some packets for two connection IDs
- store_.EnqueuePacket(connection_id_1, false, packet_, self_address_,
- peer_address_, invalid_version_, kNoParsedChlo);
- store_.EnqueuePacket(connection_id_1, false, packet_, self_address_,
- peer_address_, invalid_version_, kNoParsedChlo);
-
- ParsedClientHello parsed_chlo;
- parsed_chlo.alpns.push_back("h3");
- parsed_chlo.sni = TestHostname();
- store_.EnqueuePacket(connection_id_2, false, packet_, self_address_,
- peer_address_, valid_version_, parsed_chlo);
- EXPECT_TRUE(store_.HasBufferedPackets(connection_id_1));
- EXPECT_TRUE(store_.HasBufferedPackets(connection_id_2));
- EXPECT_TRUE(store_.HasChlosBuffered());
-
- // Discard the packets for connection 1
- store_.DiscardPackets(connection_id_1);
-
- // No packets on connection 1 should remain in the store
- EXPECT_TRUE(store_.DeliverPackets(connection_id_1).buffered_packets.empty());
- EXPECT_FALSE(store_.HasBufferedPackets(connection_id_1));
- EXPECT_TRUE(store_.HasChlosBuffered());
-
- // Packets on connection 2 should remain
- EXPECT_TRUE(store_.HasBufferedPackets(connection_id_2));
- auto packets = store_.DeliverPackets(connection_id_2);
- EXPECT_EQ(1u, packets.buffered_packets.size());
- ASSERT_EQ(1u, packets.parsed_chlo->alpns.size());
- EXPECT_EQ("h3", packets.parsed_chlo->alpns[0]);
- EXPECT_EQ(TestHostname(), packets.parsed_chlo->sni);
- // Since connection_id_2's chlo arrives, verify version is set.
- EXPECT_EQ(valid_version_, packets.version);
- EXPECT_TRUE(store_.HasChlosBuffered());
-
- // Discard the packets for connection 2
- store_.DiscardPackets(connection_id_2);
- EXPECT_FALSE(store_.HasChlosBuffered());
-}
-
-TEST_F(QuicBufferedPacketStoreTest, DiscardPacketsEmpty) {
- // Check that DiscardPackets on an unknown connection ID is safe and does
- // nothing.
- QuicConnectionId connection_id = TestConnectionId(11235);
- EXPECT_FALSE(store_.HasBufferedPackets(connection_id));
- EXPECT_FALSE(store_.HasChlosBuffered());
- store_.DiscardPackets(connection_id);
- EXPECT_FALSE(store_.HasBufferedPackets(connection_id));
- EXPECT_FALSE(store_.HasChlosBuffered());
-}
-
-} // namespace
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_chaos_protector.cc b/chromium/net/third_party/quiche/src/quic/core/quic_chaos_protector.cc
deleted file mode 100644
index e21d26ca353..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_chaos_protector.cc
+++ /dev/null
@@ -1,232 +0,0 @@
-// Copyright (c) 2021 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 "quic/core/quic_chaos_protector.h"
-
-#include <algorithm>
-#include <cstddef>
-#include <cstdint>
-#include <limits>
-#include <memory>
-
-#include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
-#include "quic/core/crypto/quic_random.h"
-#include "quic/core/frames/quic_crypto_frame.h"
-#include "quic/core/frames/quic_frame.h"
-#include "quic/core/frames/quic_padding_frame.h"
-#include "quic/core/frames/quic_ping_frame.h"
-#include "quic/core/quic_data_reader.h"
-#include "quic/core/quic_data_writer.h"
-#include "quic/core/quic_framer.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_stream_frame_data_producer.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "common/platform/api/quiche_logging.h"
-
-namespace quic {
-
-QuicChaosProtector::QuicChaosProtector(const QuicCryptoFrame& crypto_frame,
- int num_padding_bytes,
- size_t packet_size,
- QuicFramer* framer,
- QuicRandom* random)
- : packet_size_(packet_size),
- crypto_data_length_(crypto_frame.data_length),
- crypto_buffer_offset_(crypto_frame.offset),
- level_(crypto_frame.level),
- remaining_padding_bytes_(num_padding_bytes),
- framer_(framer),
- random_(random) {
- QUICHE_DCHECK_NE(framer_, nullptr);
- QUICHE_DCHECK_NE(framer_->data_producer(), nullptr);
- QUICHE_DCHECK_NE(random_, nullptr);
-}
-
-QuicChaosProtector::~QuicChaosProtector() {
- DeleteFrames(&frames_);
-}
-
-absl::optional<size_t> QuicChaosProtector::BuildDataPacket(
- const QuicPacketHeader& header,
- char* buffer) {
- if (!CopyCryptoDataToLocalBuffer()) {
- return absl::nullopt;
- }
- SplitCryptoFrame();
- AddPingFrames();
- SpreadPadding();
- ReorderFrames();
- return BuildPacket(header, buffer);
-}
-
-WriteStreamDataResult QuicChaosProtector::WriteStreamData(
- QuicStreamId id,
- QuicStreamOffset offset,
- QuicByteCount data_length,
- QuicDataWriter* /*writer*/) {
- QUIC_BUG(chaos stream) << "This should never be called; id " << id
- << " offset " << offset << " data_length "
- << data_length;
- return STREAM_MISSING;
-}
-
-bool QuicChaosProtector::WriteCryptoData(EncryptionLevel level,
- QuicStreamOffset offset,
- QuicByteCount data_length,
- QuicDataWriter* writer) {
- if (level != level_) {
- QUIC_BUG(chaos bad level) << "Unexpected " << level << " != " << level_;
- return false;
- }
- // This is `offset + data_length > buffer_offset_ + buffer_length_`
- // but with integer overflow protection.
- if (offset < crypto_buffer_offset_ || data_length > crypto_data_length_ ||
- offset - crypto_buffer_offset_ > crypto_data_length_ - data_length) {
- QUIC_BUG(chaos bad lengths)
- << "Unexpected buffer_offset_ " << crypto_buffer_offset_ << " offset "
- << offset << " buffer_length_ " << crypto_data_length_
- << " data_length " << data_length;
- return false;
- }
- writer->WriteBytes(&crypto_data_buffer_[offset - crypto_buffer_offset_],
- data_length);
- return true;
-}
-
-bool QuicChaosProtector::CopyCryptoDataToLocalBuffer() {
- crypto_frame_buffer_ = std::make_unique<char[]>(packet_size_);
- frames_.push_back(QuicFrame(
- new QuicCryptoFrame(level_, crypto_buffer_offset_, crypto_data_length_)));
- // We use |framer_| to serialize the CRYPTO frame in order to extract its
- // data from the crypto data producer. This ensures that we reuse the
- // usual serialization code path, but has the downside that we then need to
- // parse the offset and length in order to skip over those fields.
- QuicDataWriter writer(packet_size_, crypto_frame_buffer_.get());
- if (!framer_->AppendCryptoFrame(*frames_.front().crypto_frame, &writer)) {
- QUIC_BUG(chaos write crypto data);
- return false;
- }
- QuicDataReader reader(crypto_frame_buffer_.get(), writer.length());
- uint64_t parsed_offset, parsed_length;
- if (!reader.ReadVarInt62(&parsed_offset) ||
- !reader.ReadVarInt62(&parsed_length)) {
- QUIC_BUG(chaos parse crypto frame);
- return false;
- }
-
- absl::string_view crypto_data = reader.ReadRemainingPayload();
- crypto_data_buffer_ = crypto_data.data();
-
- QUICHE_DCHECK_EQ(parsed_offset, crypto_buffer_offset_);
- QUICHE_DCHECK_EQ(parsed_length, crypto_data_length_);
- QUICHE_DCHECK_EQ(parsed_length, crypto_data.length());
-
- return true;
-}
-
-void QuicChaosProtector::SplitCryptoFrame() {
- const int max_overhead_of_adding_a_crypto_frame =
- static_cast<int>(QuicFramer::GetMinCryptoFrameSize(
- crypto_buffer_offset_ + crypto_data_length_, crypto_data_length_));
- // Pick a random number of CRYPTO frames to add.
- constexpr uint64_t kMaxAddedCryptoFrames = 10;
- const uint64_t num_added_crypto_frames =
- random_->InsecureRandUint64() % (kMaxAddedCryptoFrames + 1);
- for (uint64_t i = 0; i < num_added_crypto_frames; i++) {
- if (remaining_padding_bytes_ < max_overhead_of_adding_a_crypto_frame) {
- break;
- }
- // Pick a random frame and split it by shrinking the picked frame and
- // moving the second half of its data to a new frame that is then appended
- // to |frames|.
- size_t frame_to_split_index =
- random_->InsecureRandUint64() % frames_.size();
- QuicCryptoFrame* frame_to_split =
- frames_[frame_to_split_index].crypto_frame;
- if (frame_to_split->data_length <= 1) {
- continue;
- }
- const int frame_to_split_old_overhead =
- static_cast<int>(QuicFramer::GetMinCryptoFrameSize(
- frame_to_split->offset, frame_to_split->data_length));
- const QuicPacketLength frame_to_split_new_data_length =
- 1 + (random_->InsecureRandUint64() % (frame_to_split->data_length - 1));
- const QuicPacketLength new_frame_data_length =
- frame_to_split->data_length - frame_to_split_new_data_length;
- const QuicStreamOffset new_frame_offset =
- frame_to_split->offset + frame_to_split_new_data_length;
- frame_to_split->data_length -= new_frame_data_length;
- frames_.push_back(QuicFrame(
- new QuicCryptoFrame(level_, new_frame_offset, new_frame_data_length)));
- const int frame_to_split_new_overhead =
- static_cast<int>(QuicFramer::GetMinCryptoFrameSize(
- frame_to_split->offset, frame_to_split->data_length));
- const int new_frame_overhead =
- static_cast<int>(QuicFramer::GetMinCryptoFrameSize(
- new_frame_offset, new_frame_data_length));
- QUICHE_DCHECK_LE(frame_to_split_new_overhead, frame_to_split_old_overhead);
- // Readjust padding based on increased overhead.
- remaining_padding_bytes_ -= new_frame_overhead;
- remaining_padding_bytes_ -= frame_to_split_new_overhead;
- remaining_padding_bytes_ += frame_to_split_old_overhead;
- }
-}
-
-void QuicChaosProtector::AddPingFrames() {
- if (remaining_padding_bytes_ == 0) {
- return;
- }
- constexpr uint64_t kMaxAddedPingFrames = 10;
- const uint64_t num_ping_frames =
- random_->InsecureRandUint64() %
- std::min<uint64_t>(kMaxAddedPingFrames, remaining_padding_bytes_);
- for (uint64_t i = 0; i < num_ping_frames; i++) {
- frames_.push_back(QuicFrame(QuicPingFrame()));
- }
- remaining_padding_bytes_ -= static_cast<int>(num_ping_frames);
-}
-
-void QuicChaosProtector::ReorderFrames() {
- // Walk the array backwards and swap each frame with a random earlier one.
- for (size_t i = frames_.size() - 1; i > 0; i--) {
- std::swap(frames_[i], frames_[random_->InsecureRandUint64() % (i + 1)]);
- }
-}
-
-void QuicChaosProtector::SpreadPadding() {
- for (auto it = frames_.begin(); it != frames_.end(); ++it) {
- const int padding_bytes_in_this_frame =
- random_->InsecureRandUint64() % (remaining_padding_bytes_ + 1);
- if (padding_bytes_in_this_frame <= 0) {
- continue;
- }
- it = frames_.insert(
- it, QuicFrame(QuicPaddingFrame(padding_bytes_in_this_frame)));
- ++it; // Skip over the padding frame we just added.
- remaining_padding_bytes_ -= padding_bytes_in_this_frame;
- }
- if (remaining_padding_bytes_ > 0) {
- frames_.push_back(QuicFrame(QuicPaddingFrame(remaining_padding_bytes_)));
- }
-}
-
-absl::optional<size_t> QuicChaosProtector::BuildPacket(
- const QuicPacketHeader& header,
- char* buffer) {
- QuicStreamFrameDataProducer* original_data_producer =
- framer_->data_producer();
- framer_->set_data_producer(this);
-
- size_t length =
- framer_->BuildDataPacket(header, frames_, buffer, packet_size_, level_);
-
- framer_->set_data_producer(original_data_producer);
- if (length == 0) {
- return absl::nullopt;
- }
- return length;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_chaos_protector.h b/chromium/net/third_party/quiche/src/quic/core/quic_chaos_protector.h
deleted file mode 100644
index 6bcd42087e7..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_chaos_protector.h
+++ /dev/null
@@ -1,99 +0,0 @@
-// Copyright (c) 2021 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_CHAOS_PROTECTOR_H_
-#define QUICHE_QUIC_CORE_QUIC_CHAOS_PROTECTOR_H_
-
-#include <cstddef>
-#include <memory>
-
-#include "absl/types/optional.h"
-#include "quic/core/crypto/quic_random.h"
-#include "quic/core/frames/quic_crypto_frame.h"
-#include "quic/core/frames/quic_frame.h"
-#include "quic/core/quic_data_writer.h"
-#include "quic/core/quic_framer.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_stream_frame_data_producer.h"
-#include "quic/core/quic_types.h"
-
-namespace quic {
-
-namespace test {
-class QuicChaosProtectorTest;
-}
-
-// QuicChaosProtector will take a crypto frame and an amount of padding and
-// build a data packet that will parse to something equivalent.
-class QUIC_EXPORT_PRIVATE QuicChaosProtector
- : public QuicStreamFrameDataProducer {
- public:
- // |framer| and |random| must be valid for the lifetime of QuicChaosProtector.
- explicit QuicChaosProtector(const QuicCryptoFrame& crypto_frame,
- int num_padding_bytes,
- size_t packet_size,
- QuicFramer* framer,
- QuicRandom* random);
-
- ~QuicChaosProtector() override;
-
- QuicChaosProtector(const QuicChaosProtector&) = delete;
- QuicChaosProtector(QuicChaosProtector&&) = delete;
- QuicChaosProtector& operator=(const QuicChaosProtector&) = delete;
- QuicChaosProtector& operator=(QuicChaosProtector&&) = delete;
-
- // Attempts to build a data packet with chaos protection. If an error occurs,
- // then absl::nullopt is returned. Otherwise returns the serialized length.
- absl::optional<size_t> BuildDataPacket(const QuicPacketHeader& header,
- char* buffer);
-
- // From QuicStreamFrameDataProducer.
- WriteStreamDataResult WriteStreamData(QuicStreamId id,
- QuicStreamOffset offset,
- QuicByteCount data_length,
- QuicDataWriter* /*writer*/) override;
- bool WriteCryptoData(EncryptionLevel level,
- QuicStreamOffset offset,
- QuicByteCount data_length,
- QuicDataWriter* writer) override;
-
- private:
- friend class test::QuicChaosProtectorTest;
-
- // Allocate the crypto data buffer, create the CRYPTO frame and write the
- // crypto data to our buffer.
- bool CopyCryptoDataToLocalBuffer();
-
- // Split the CRYPTO frame in |frames_| into one or more CRYPTO frames that
- // collectively represent the same data. Adjusts padding to compensate.
- void SplitCryptoFrame();
-
- // Add a random number of PING frames to |frames_| and adjust padding.
- void AddPingFrames();
-
- // Randomly reorder |frames_|.
- void ReorderFrames();
-
- // Add PADDING frames randomly between all other frames.
- void SpreadPadding();
-
- // Serialize |frames_| using |framer_|.
- absl::optional<size_t> BuildPacket(const QuicPacketHeader& header,
- char* buffer);
-
- size_t packet_size_;
- std::unique_ptr<char[]> crypto_frame_buffer_;
- const char* crypto_data_buffer_ = nullptr;
- QuicByteCount crypto_data_length_;
- QuicStreamOffset crypto_buffer_offset_;
- EncryptionLevel level_;
- int remaining_padding_bytes_;
- QuicFrames frames_; // Inner frames owned, will be deleted by destructor.
- QuicFramer* framer_; // Unowned.
- QuicRandom* random_; // Unowned.
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_QUIC_CHAOS_PROTECTOR_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_chaos_protector_test.cc b/chromium/net/third_party/quiche/src/quic/core/quic_chaos_protector_test.cc
deleted file mode 100644
index 675e00fa160..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_chaos_protector_test.cc
+++ /dev/null
@@ -1,230 +0,0 @@
-// Copyright (c) 2021 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 "quic/core/quic_chaos_protector.h"
-
-#include <cstddef>
-#include <memory>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/frames/quic_crypto_frame.h"
-#include "quic/core/quic_connection_id.h"
-#include "quic/core/quic_framer.h"
-#include "quic/core/quic_packet_number.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_stream_frame_data_producer.h"
-#include "quic/core/quic_time.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_versions.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/mock_random.h"
-#include "quic/test_tools/quic_test_utils.h"
-#include "quic/test_tools/simple_quic_framer.h"
-
-namespace quic {
-namespace test {
-
-class QuicChaosProtectorTest : public QuicTestWithParam<ParsedQuicVersion>,
- public QuicStreamFrameDataProducer {
- public:
- QuicChaosProtectorTest()
- : version_(GetParam()),
- framer_({version_}, QuicTime::Zero(), Perspective::IS_CLIENT,
- kQuicDefaultConnectionIdLength),
- validation_framer_({version_}),
- random_(/*base=*/3),
- level_(ENCRYPTION_INITIAL),
- crypto_offset_(0),
- crypto_data_length_(100),
- crypto_frame_(level_, crypto_offset_, crypto_data_length_),
- num_padding_bytes_(50),
- packet_size_(1000),
- packet_buffer_(std::make_unique<char[]>(packet_size_)) {
- ReCreateChaosProtector();
- }
-
- void ReCreateChaosProtector() {
- chaos_protector_ = std::make_unique<QuicChaosProtector>(
- crypto_frame_, num_padding_bytes_, packet_size_,
- SetupHeaderAndFramers(), &random_);
- }
-
- // From QuicStreamFrameDataProducer.
- WriteStreamDataResult WriteStreamData(QuicStreamId /*id*/,
- QuicStreamOffset /*offset*/,
- QuicByteCount /*data_length*/,
- QuicDataWriter* /*writer*/) override {
- ADD_FAILURE() << "This should never be called";
- return STREAM_MISSING;
- }
-
- // From QuicStreamFrameDataProducer.
- bool WriteCryptoData(EncryptionLevel level,
- QuicStreamOffset offset,
- QuicByteCount data_length,
- QuicDataWriter* writer) override {
- EXPECT_EQ(level, level);
- EXPECT_EQ(offset, crypto_offset_);
- EXPECT_EQ(data_length, crypto_data_length_);
- for (QuicByteCount i = 0; i < data_length; i++) {
- EXPECT_TRUE(writer->WriteUInt8(static_cast<uint8_t>(i & 0xFF)));
- }
- return true;
- }
-
- protected:
- QuicFramer* SetupHeaderAndFramers() {
- // Setup header.
- header_.destination_connection_id = TestConnectionId();
- header_.destination_connection_id_included = CONNECTION_ID_PRESENT;
- header_.source_connection_id = EmptyQuicConnectionId();
- header_.source_connection_id_included = CONNECTION_ID_PRESENT;
- header_.reset_flag = false;
- header_.version_flag = true;
- header_.has_possible_stateless_reset_token = false;
- header_.packet_number_length = PACKET_4BYTE_PACKET_NUMBER;
- header_.version = version_;
- header_.packet_number = QuicPacketNumber(1);
- header_.form = IETF_QUIC_LONG_HEADER_PACKET;
- header_.long_packet_type = INITIAL;
- header_.retry_token_length_length = VARIABLE_LENGTH_INTEGER_LENGTH_1;
- header_.length_length = kQuicDefaultLongHeaderLengthLength;
- // Setup validation framer.
- validation_framer_.framer()->SetInitialObfuscators(
- header_.destination_connection_id);
- // Setup framer.
- framer_.SetInitialObfuscators(header_.destination_connection_id);
- framer_.set_data_producer(this);
- return &framer_;
- }
-
- void BuildEncryptAndParse() {
- absl::optional<size_t> length =
- chaos_protector_->BuildDataPacket(header_, packet_buffer_.get());
- ASSERT_TRUE(length.has_value());
- ASSERT_GT(length.value(), 0u);
- size_t encrypted_length = framer_.EncryptInPlace(
- level_, header_.packet_number,
- GetStartOfEncryptedData(framer_.transport_version(), header_),
- length.value(), packet_size_, packet_buffer_.get());
- ASSERT_GT(encrypted_length, 0u);
- ASSERT_TRUE(validation_framer_.ProcessPacket(QuicEncryptedPacket(
- absl::string_view(packet_buffer_.get(), encrypted_length))));
- }
-
- void ResetOffset(QuicStreamOffset offset) {
- crypto_offset_ = offset;
- crypto_frame_.offset = offset;
- ReCreateChaosProtector();
- }
-
- void ResetLength(QuicByteCount length) {
- crypto_data_length_ = length;
- crypto_frame_.data_length = length;
- ReCreateChaosProtector();
- }
-
- ParsedQuicVersion version_;
- QuicPacketHeader header_;
- QuicFramer framer_;
- SimpleQuicFramer validation_framer_;
- MockRandom random_;
- EncryptionLevel level_;
- QuicStreamOffset crypto_offset_;
- QuicByteCount crypto_data_length_;
- QuicCryptoFrame crypto_frame_;
- int num_padding_bytes_;
- size_t packet_size_;
- std::unique_ptr<char[]> packet_buffer_;
- std::unique_ptr<QuicChaosProtector> chaos_protector_;
-};
-
-namespace {
-
-ParsedQuicVersionVector TestVersions() {
- ParsedQuicVersionVector versions;
- for (const ParsedQuicVersion& version : AllSupportedVersions()) {
- if (version.UsesCryptoFrames()) {
- versions.push_back(version);
- }
- }
- return versions;
-}
-
-INSTANTIATE_TEST_SUITE_P(QuicChaosProtectorTests,
- QuicChaosProtectorTest,
- ::testing::ValuesIn(TestVersions()),
- ::testing::PrintToStringParamName());
-
-TEST_P(QuicChaosProtectorTest, Main) {
- BuildEncryptAndParse();
- ASSERT_EQ(validation_framer_.crypto_frames().size(), 4u);
- EXPECT_EQ(validation_framer_.crypto_frames()[0]->offset, 0u);
- EXPECT_EQ(validation_framer_.crypto_frames()[0]->data_length, 1u);
- ASSERT_EQ(validation_framer_.ping_frames().size(), 3u);
- ASSERT_EQ(validation_framer_.padding_frames().size(), 7u);
- EXPECT_EQ(validation_framer_.padding_frames()[0].num_padding_bytes, 3);
-}
-
-TEST_P(QuicChaosProtectorTest, DifferentRandom) {
- random_.ResetBase(4);
- BuildEncryptAndParse();
- ASSERT_EQ(validation_framer_.crypto_frames().size(), 4u);
- ASSERT_EQ(validation_framer_.ping_frames().size(), 4u);
- ASSERT_EQ(validation_framer_.padding_frames().size(), 8u);
-}
-
-TEST_P(QuicChaosProtectorTest, RandomnessZero) {
- random_.ResetBase(0);
- BuildEncryptAndParse();
- ASSERT_EQ(validation_framer_.crypto_frames().size(), 1u);
- EXPECT_EQ(validation_framer_.crypto_frames()[0]->offset, crypto_offset_);
- EXPECT_EQ(validation_framer_.crypto_frames()[0]->data_length,
- crypto_data_length_);
- ASSERT_EQ(validation_framer_.ping_frames().size(), 0u);
- ASSERT_EQ(validation_framer_.padding_frames().size(), 1u);
-}
-
-TEST_P(QuicChaosProtectorTest, Offset) {
- ResetOffset(123);
- BuildEncryptAndParse();
- ASSERT_EQ(validation_framer_.crypto_frames().size(), 4u);
- EXPECT_EQ(validation_framer_.crypto_frames()[0]->offset, crypto_offset_);
- EXPECT_EQ(validation_framer_.crypto_frames()[0]->data_length, 1u);
- ASSERT_EQ(validation_framer_.ping_frames().size(), 3u);
- ASSERT_EQ(validation_framer_.padding_frames().size(), 7u);
- EXPECT_EQ(validation_framer_.padding_frames()[0].num_padding_bytes, 3);
-}
-
-TEST_P(QuicChaosProtectorTest, OffsetAndRandomnessZero) {
- ResetOffset(123);
- random_.ResetBase(0);
- BuildEncryptAndParse();
- ASSERT_EQ(validation_framer_.crypto_frames().size(), 1u);
- EXPECT_EQ(validation_framer_.crypto_frames()[0]->offset, crypto_offset_);
- EXPECT_EQ(validation_framer_.crypto_frames()[0]->data_length,
- crypto_data_length_);
- ASSERT_EQ(validation_framer_.ping_frames().size(), 0u);
- ASSERT_EQ(validation_framer_.padding_frames().size(), 1u);
-}
-
-TEST_P(QuicChaosProtectorTest, ZeroRemainingBytesAfterSplit) {
- QuicPacketLength new_length = 63;
- num_padding_bytes_ = QuicFramer::GetMinCryptoFrameSize(
- crypto_frame_.offset + new_length, new_length);
- ResetLength(new_length);
- BuildEncryptAndParse();
-
- ASSERT_EQ(validation_framer_.crypto_frames().size(), 2u);
- EXPECT_EQ(validation_framer_.crypto_frames()[0]->offset, crypto_offset_);
- EXPECT_EQ(validation_framer_.crypto_frames()[0]->data_length, 4);
- EXPECT_EQ(validation_framer_.crypto_frames()[1]->offset, crypto_offset_ + 4);
- EXPECT_EQ(validation_framer_.crypto_frames()[1]->data_length,
- crypto_data_length_ - 4);
- ASSERT_EQ(validation_framer_.ping_frames().size(), 0u);
-}
-
-} // namespace
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_clock.cc b/chromium/net/third_party/quiche/src/quic/core/quic_clock.cc
deleted file mode 100644
index 4d865b5b30d..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_clock.cc
+++ /dev/null
@@ -1,70 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_clock.h"
-
-#include <limits>
-
-#include "quic/platform/api/quic_logging.h"
-
-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);
- }
-
- // ..........................
- // | | |
- // unix epoch |walltime| WallNow()
- // ..........................
- // | | |
- // clock epoch | Now()
- // result
- //
- // result = Now() - (WallNow() - walltime)
- return Now() - QuicTime::Delta::FromMicroseconds(
- WallNow()
- .Subtract(QuicTime::Delta::FromMicroseconds(
- walltime.ToUNIXMicroseconds()))
- .ToUNIXMicroseconds());
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_clock.h b/chromium/net/third_party/quiche/src/quic/core/quic_clock.h
deleted file mode 100644
index 6164cafaa5a..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_clock.h
+++ /dev/null
@@ -1,72 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_CLOCK_H_
-#define QUICHE_QUIC_CORE_QUIC_CLOCK_H_
-
-#include "quic/core/quic_time.h"
-#include "quic/platform/api/quic_export.h"
-
-/* API_DESCRIPTION
- QuicClock is used by QUIC core to get current time. Its instance is created by
- applications and passed into QuicDispatcher and QuicConnectionHelperInterface.
- API-DESCRIPTION */
-
-namespace quic {
-
-// Interface for retrieving the current time.
-class QUIC_EXPORT_PRIVATE QuicClock {
- public:
- QuicClock();
- virtual ~QuicClock();
-
- 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;
-
- // Returns the current time as a QuicTime object.
- // Note: this use significant resources please use only if needed.
- virtual QuicTime Now() const = 0;
-
- // WallNow returns the current wall-time - a time that is consistent across
- // different clocks.
- virtual QuicWallTime WallNow() const = 0;
-
- // Converts |walltime| to a QuicTime relative to this clock's epoch.
- virtual QuicTime ConvertWallTimeToQuicTime(
- const QuicWallTime& walltime) const;
-
- protected:
- // Creates a new QuicTime using |time_us| as the internal value.
- 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
-
-#endif // QUICHE_QUIC_CORE_QUIC_CLOCK_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_coalesced_packet.cc b/chromium/net/third_party/quiche/src/quic/core/quic_coalesced_packet.cc
deleted file mode 100644
index 52673b61d5e..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_coalesced_packet.cc
+++ /dev/null
@@ -1,185 +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 "quic/core/quic_coalesced_packet.h"
-
-#include "absl/memory/memory.h"
-#include "absl/strings/str_cat.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-
-namespace quic {
-
-QuicCoalescedPacket::QuicCoalescedPacket()
- : length_(0), max_packet_length_(0) {}
-
-QuicCoalescedPacket::~QuicCoalescedPacket() {
- Clear();
-}
-
-bool QuicCoalescedPacket::MaybeCoalescePacket(
- const SerializedPacket& packet,
- const QuicSocketAddress& self_address,
- const QuicSocketAddress& peer_address,
- QuicBufferAllocator* allocator,
- QuicPacketLength current_max_packet_length) {
- if (packet.encrypted_length == 0) {
- QUIC_BUG(quic_bug_10611_1) << "Trying to coalesce an empty packet";
- return true;
- }
- if (length_ == 0) {
-#ifndef NDEBUG
- for (const auto& buffer : encrypted_buffers_) {
- QUICHE_DCHECK(buffer.empty());
- }
-#endif
- QUICHE_DCHECK(initial_packet_ == nullptr);
- // This is the first packet, set max_packet_length and self/peer
- // addresses.
- max_packet_length_ = current_max_packet_length;
- self_address_ = self_address;
- peer_address_ = peer_address;
- } else {
- if (self_address_ != self_address || peer_address_ != peer_address) {
- // Do not coalesce packet with different self/peer addresses.
- QUIC_DLOG(INFO)
- << "Cannot coalesce packet because self/peer address changed";
- return false;
- }
- if (max_packet_length_ != current_max_packet_length) {
- QUIC_BUG(quic_bug_10611_2)
- << "Max packet length changes in the middle of the write path";
- return false;
- }
- if (ContainsPacketOfEncryptionLevel(packet.encryption_level)) {
- // Do not coalesce packets of the same encryption level.
- return false;
- }
- }
-
- if (length_ + packet.encrypted_length > max_packet_length_) {
- // Packet does not fit.
- return false;
- }
- QUIC_DVLOG(1) << "Successfully coalesced packet: encryption_level: "
- << packet.encryption_level
- << ", encrypted_length: " << packet.encrypted_length
- << ", current length: " << length_
- << ", max_packet_length: " << max_packet_length_;
- if (length_ > 0) {
- QUIC_CODE_COUNT(QUIC_SUCCESSFULLY_COALESCED_MULTIPLE_PACKETS);
- }
- length_ += packet.encrypted_length;
- transmission_types_[packet.encryption_level] = packet.transmission_type;
- if (packet.encryption_level == ENCRYPTION_INITIAL) {
- // Save a copy of ENCRYPTION_INITIAL packet (excluding encrypted buffer, as
- // the packet will be re-serialized later).
- initial_packet_ = absl::WrapUnique<SerializedPacket>(
- CopySerializedPacket(packet, allocator, /*copy_buffer=*/false));
- return true;
- }
- // Copy encrypted buffer of packets with other encryption levels.
- encrypted_buffers_[packet.encryption_level] =
- std::string(packet.encrypted_buffer, packet.encrypted_length);
- return true;
-}
-
-void QuicCoalescedPacket::Clear() {
- self_address_ = QuicSocketAddress();
- peer_address_ = QuicSocketAddress();
- length_ = 0;
- max_packet_length_ = 0;
- for (auto& packet : encrypted_buffers_) {
- packet.clear();
- }
- for (size_t i = ENCRYPTION_INITIAL; i < NUM_ENCRYPTION_LEVELS; ++i) {
- transmission_types_[i] = NOT_RETRANSMISSION;
- }
- initial_packet_ = nullptr;
-}
-
-void QuicCoalescedPacket::NeuterInitialPacket() {
- if (initial_packet_ == nullptr) {
- return;
- }
- if (length_ < initial_packet_->encrypted_length) {
- QUIC_BUG(quic_bug_10611_3)
- << "length_: " << length_ << ", is less than initial packet length: "
- << initial_packet_->encrypted_length;
- Clear();
- return;
- }
- length_ -= initial_packet_->encrypted_length;
- if (length_ == 0) {
- Clear();
- return;
- }
- transmission_types_[ENCRYPTION_INITIAL] = NOT_RETRANSMISSION;
- initial_packet_ = nullptr;
-}
-
-bool QuicCoalescedPacket::CopyEncryptedBuffers(char* buffer,
- size_t buffer_len,
- size_t* length_copied) const {
- *length_copied = 0;
- for (const auto& packet : encrypted_buffers_) {
- if (packet.empty()) {
- continue;
- }
- if (packet.length() > buffer_len) {
- return false;
- }
- memcpy(buffer, packet.data(), packet.length());
- buffer += packet.length();
- buffer_len -= packet.length();
- *length_copied += packet.length();
- }
- return true;
-}
-
-bool QuicCoalescedPacket::ContainsPacketOfEncryptionLevel(
- EncryptionLevel level) const {
- return !encrypted_buffers_[level].empty() ||
- (level == ENCRYPTION_INITIAL && initial_packet_ != nullptr);
-}
-
-TransmissionType QuicCoalescedPacket::TransmissionTypeOfPacket(
- EncryptionLevel level) const {
- if (!ContainsPacketOfEncryptionLevel(level)) {
- QUIC_BUG(quic_bug_10611_4)
- << "Coalesced packet does not contain packet of encryption level: "
- << EncryptionLevelToString(level);
- return NOT_RETRANSMISSION;
- }
- return transmission_types_[level];
-}
-
-size_t QuicCoalescedPacket::NumberOfPackets() const {
- size_t num_of_packets = 0;
- for (int8_t i = ENCRYPTION_INITIAL; i < NUM_ENCRYPTION_LEVELS; ++i) {
- if (ContainsPacketOfEncryptionLevel(static_cast<EncryptionLevel>(i))) {
- ++num_of_packets;
- }
- }
- return num_of_packets;
-}
-
-std::string QuicCoalescedPacket::ToString(size_t serialized_length) const {
- // Total length and padding size.
- std::string info = absl::StrCat(
- "total_length: ", serialized_length,
- " padding_size: ", serialized_length - length_, " packets: {");
- // Packets' encryption levels.
- bool first_packet = true;
- for (int8_t i = ENCRYPTION_INITIAL; i < NUM_ENCRYPTION_LEVELS; ++i) {
- if (ContainsPacketOfEncryptionLevel(static_cast<EncryptionLevel>(i))) {
- absl::StrAppend(&info, first_packet ? "" : ", ",
- EncryptionLevelToString(static_cast<EncryptionLevel>(i)));
- first_packet = false;
- }
- }
- absl::StrAppend(&info, "}");
- return info;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_coalesced_packet.h b/chromium/net/third_party/quiche/src/quic/core/quic_coalesced_packet.h
deleted file mode 100644
index e8bc2c3eb0b..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_coalesced_packet.h
+++ /dev/null
@@ -1,89 +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_CORE_QUIC_COALESCED_PACKET_H_
-#define QUICHE_QUIC_CORE_QUIC_COALESCED_PACKET_H_
-
-#include "quic/core/quic_packets.h"
-
-namespace quic {
-
-// QuicCoalescedPacket is used to buffer multiple packets which can be coalesced
-// into the same UDP datagram.
-class QUIC_EXPORT_PRIVATE QuicCoalescedPacket {
- public:
- QuicCoalescedPacket();
- ~QuicCoalescedPacket();
-
- // Returns true if |packet| is successfully coalesced with existing packets.
- // Returns false otherwise.
- bool MaybeCoalescePacket(const SerializedPacket& packet,
- const QuicSocketAddress& self_address,
- const QuicSocketAddress& peer_address,
- QuicBufferAllocator* allocator,
- QuicPacketLength current_max_packet_length);
-
- // Clears this coalesced packet.
- void Clear();
-
- // Clears all state associated with initial_packet_.
- void NeuterInitialPacket();
-
- // Copies encrypted_buffers_ to |buffer| and sets |length_copied| to the
- // copied amount. Returns false if copy fails (i.e., |buffer_len| is not
- // enough).
- bool CopyEncryptedBuffers(char* buffer,
- size_t buffer_len,
- size_t* length_copied) const;
-
- std::string ToString(size_t serialized_length) const;
-
- // Returns true if this coalesced packet contains packet of |level|.
- bool ContainsPacketOfEncryptionLevel(EncryptionLevel level) const;
-
- // Returns transmission type of packet of |level|. This should only be called
- // when this coalesced packet contains packet of |level|.
- TransmissionType TransmissionTypeOfPacket(EncryptionLevel level) const;
-
- // Returns number of packets contained in this coalesced packet.
- size_t NumberOfPackets() const;
-
- const SerializedPacket* initial_packet() const {
- return initial_packet_.get();
- }
-
- const QuicSocketAddress& self_address() const { return self_address_; }
-
- const QuicSocketAddress& peer_address() const { return peer_address_; }
-
- QuicPacketLength length() const { return length_; }
-
- QuicPacketLength max_packet_length() const { return max_packet_length_; }
-
- private:
- // self/peer addresses are set when trying to coalesce the first packet.
- // Packets with different self/peer addresses cannot be coalesced.
- QuicSocketAddress self_address_;
- QuicSocketAddress peer_address_;
- // Length of this coalesced packet.
- QuicPacketLength length_;
- // Max packet length. Do not try to coalesce packet when max packet length
- // changes (e.g., with MTU discovery).
- QuicPacketLength max_packet_length_;
- // Copies of packets' encrypted buffers according to different encryption
- // levels.
- std::string encrypted_buffers_[NUM_ENCRYPTION_LEVELS];
- // Recorded transmission type according to different encryption levels.
- TransmissionType transmission_types_[NUM_ENCRYPTION_LEVELS];
-
- // A copy of ENCRYPTION_INITIAL packet if this coalesced packet contains one.
- // Null otherwise. Please note, the encrypted_buffer field is not copied. The
- // frames are copied to allow it be re-serialized when this coalesced packet
- // gets sent.
- std::unique_ptr<SerializedPacket> initial_packet_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_QUIC_COALESCED_PACKET_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_coalesced_packet_test.cc b/chromium/net/third_party/quiche/src/quic/core/quic_coalesced_packet_test.cc
deleted file mode 100644
index 34f6da30890..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_coalesced_packet_test.cc
+++ /dev/null
@@ -1,213 +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 "quic/core/quic_coalesced_packet.h"
-
-#include "quic/platform/api/quic_expect_bug.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/quic_test_utils.h"
-#include "common/test_tools/quiche_test_utils.h"
-
-namespace quic {
-namespace test {
-namespace {
-
-TEST(QuicCoalescedPacketTest, MaybeCoalescePacket) {
- QuicCoalescedPacket coalesced;
- EXPECT_EQ("total_length: 0 padding_size: 0 packets: {}",
- coalesced.ToString(0));
- SimpleBufferAllocator allocator;
- EXPECT_EQ(0u, coalesced.length());
- EXPECT_EQ(0u, coalesced.NumberOfPackets());
- char buffer[1000];
- QuicSocketAddress self_address(QuicIpAddress::Loopback4(), 1);
- QuicSocketAddress peer_address(QuicIpAddress::Loopback4(), 2);
- SerializedPacket packet1(QuicPacketNumber(1), PACKET_4BYTE_PACKET_NUMBER,
- buffer, 500, false, false);
- packet1.transmission_type = PTO_RETRANSMISSION;
- QuicAckFrame ack_frame(InitAckFrame(1));
- packet1.nonretransmittable_frames.push_back(QuicFrame(&ack_frame));
- packet1.retransmittable_frames.push_back(
- QuicFrame(QuicStreamFrame(1, true, 0, 100)));
- ASSERT_TRUE(coalesced.MaybeCoalescePacket(packet1, self_address, peer_address,
- &allocator, 1500));
- EXPECT_EQ(PTO_RETRANSMISSION,
- coalesced.TransmissionTypeOfPacket(ENCRYPTION_INITIAL));
- EXPECT_EQ(1500u, coalesced.max_packet_length());
- EXPECT_EQ(500u, coalesced.length());
- EXPECT_EQ(1u, coalesced.NumberOfPackets());
- EXPECT_EQ(
- "total_length: 1500 padding_size: 1000 packets: {ENCRYPTION_INITIAL}",
- coalesced.ToString(1500));
-
- // Cannot coalesce packet of the same encryption level.
- SerializedPacket packet2(QuicPacketNumber(2), PACKET_4BYTE_PACKET_NUMBER,
- buffer, 500, false, false);
- EXPECT_FALSE(coalesced.MaybeCoalescePacket(packet2, self_address,
- peer_address, &allocator, 1500));
-
- SerializedPacket packet3(QuicPacketNumber(3), PACKET_4BYTE_PACKET_NUMBER,
- buffer, 500, false, false);
- packet3.nonretransmittable_frames.push_back(QuicFrame(QuicPaddingFrame(100)));
- packet3.encryption_level = ENCRYPTION_ZERO_RTT;
- packet3.transmission_type = LOSS_RETRANSMISSION;
- ASSERT_TRUE(coalesced.MaybeCoalescePacket(packet3, self_address, peer_address,
- &allocator, 1500));
- EXPECT_EQ(1500u, coalesced.max_packet_length());
- EXPECT_EQ(1000u, coalesced.length());
- EXPECT_EQ(2u, coalesced.NumberOfPackets());
- EXPECT_EQ(LOSS_RETRANSMISSION,
- coalesced.TransmissionTypeOfPacket(ENCRYPTION_ZERO_RTT));
- EXPECT_EQ(
- "total_length: 1500 padding_size: 500 packets: {ENCRYPTION_INITIAL, "
- "ENCRYPTION_ZERO_RTT}",
- coalesced.ToString(1500));
-
- SerializedPacket packet4(QuicPacketNumber(4), PACKET_4BYTE_PACKET_NUMBER,
- buffer, 500, false, false);
- packet4.encryption_level = ENCRYPTION_FORWARD_SECURE;
- // Cannot coalesce packet of changed self/peer address.
- EXPECT_FALSE(coalesced.MaybeCoalescePacket(
- packet4, QuicSocketAddress(QuicIpAddress::Loopback4(), 3), peer_address,
- &allocator, 1500));
-
- // Packet does not fit.
- SerializedPacket packet5(QuicPacketNumber(5), PACKET_4BYTE_PACKET_NUMBER,
- buffer, 501, false, false);
- packet5.encryption_level = ENCRYPTION_FORWARD_SECURE;
- EXPECT_FALSE(coalesced.MaybeCoalescePacket(packet5, self_address,
- peer_address, &allocator, 1500));
- EXPECT_EQ(1500u, coalesced.max_packet_length());
- EXPECT_EQ(1000u, coalesced.length());
- EXPECT_EQ(2u, coalesced.NumberOfPackets());
-
- // Max packet number length changed.
- SerializedPacket packet6(QuicPacketNumber(6), PACKET_4BYTE_PACKET_NUMBER,
- buffer, 100, false, false);
- packet6.encryption_level = ENCRYPTION_FORWARD_SECURE;
- EXPECT_QUIC_BUG(coalesced.MaybeCoalescePacket(packet6, self_address,
- peer_address, &allocator, 1000),
- "Max packet length changes in the middle of the write path");
- EXPECT_EQ(1500u, coalesced.max_packet_length());
- EXPECT_EQ(1000u, coalesced.length());
- EXPECT_EQ(2u, coalesced.NumberOfPackets());
-}
-
-TEST(QuicCoalescedPacketTest, CopyEncryptedBuffers) {
- QuicCoalescedPacket coalesced;
- SimpleBufferAllocator allocator;
- QuicSocketAddress self_address(QuicIpAddress::Loopback4(), 1);
- QuicSocketAddress peer_address(QuicIpAddress::Loopback4(), 2);
- std::string buffer(500, 'a');
- std::string buffer2(500, 'b');
- SerializedPacket packet1(QuicPacketNumber(1), PACKET_4BYTE_PACKET_NUMBER,
- buffer.data(), 500,
- /*has_ack=*/false, /*has_stop_waiting=*/false);
- packet1.encryption_level = ENCRYPTION_ZERO_RTT;
- SerializedPacket packet2(QuicPacketNumber(2), PACKET_4BYTE_PACKET_NUMBER,
- buffer2.data(), 500,
- /*has_ack=*/false, /*has_stop_waiting=*/false);
- packet2.encryption_level = ENCRYPTION_FORWARD_SECURE;
-
- ASSERT_TRUE(coalesced.MaybeCoalescePacket(packet1, self_address, peer_address,
- &allocator, 1500));
- ASSERT_TRUE(coalesced.MaybeCoalescePacket(packet2, self_address, peer_address,
- &allocator, 1500));
- EXPECT_EQ(1000u, coalesced.length());
-
- char copy_buffer[1000];
- size_t length_copied = 0;
- EXPECT_FALSE(
- coalesced.CopyEncryptedBuffers(copy_buffer, 900, &length_copied));
- ASSERT_TRUE(
- coalesced.CopyEncryptedBuffers(copy_buffer, 1000, &length_copied));
- EXPECT_EQ(1000u, length_copied);
- char expected[1000];
- memset(expected, 'a', 500);
- memset(expected + 500, 'b', 500);
- quiche::test::CompareCharArraysWithHexError("copied buffers", copy_buffer,
- length_copied, expected, 1000);
-}
-
-TEST(QuicCoalescedPacketTest, NeuterInitialPacket) {
- QuicCoalescedPacket coalesced;
- EXPECT_EQ("total_length: 0 padding_size: 0 packets: {}",
- coalesced.ToString(0));
- // Noop when neutering initial packet on a empty coalescer.
- coalesced.NeuterInitialPacket();
- EXPECT_EQ("total_length: 0 padding_size: 0 packets: {}",
- coalesced.ToString(0));
-
- SimpleBufferAllocator allocator;
- EXPECT_EQ(0u, coalesced.length());
- char buffer[1000];
- QuicSocketAddress self_address(QuicIpAddress::Loopback4(), 1);
- QuicSocketAddress peer_address(QuicIpAddress::Loopback4(), 2);
- SerializedPacket packet1(QuicPacketNumber(1), PACKET_4BYTE_PACKET_NUMBER,
- buffer, 500, false, false);
- packet1.transmission_type = PTO_RETRANSMISSION;
- QuicAckFrame ack_frame(InitAckFrame(1));
- packet1.nonretransmittable_frames.push_back(QuicFrame(&ack_frame));
- packet1.retransmittable_frames.push_back(
- QuicFrame(QuicStreamFrame(1, true, 0, 100)));
- ASSERT_TRUE(coalesced.MaybeCoalescePacket(packet1, self_address, peer_address,
- &allocator, 1500));
- EXPECT_EQ(PTO_RETRANSMISSION,
- coalesced.TransmissionTypeOfPacket(ENCRYPTION_INITIAL));
- EXPECT_EQ(1500u, coalesced.max_packet_length());
- EXPECT_EQ(500u, coalesced.length());
- EXPECT_EQ(
- "total_length: 1500 padding_size: 1000 packets: {ENCRYPTION_INITIAL}",
- coalesced.ToString(1500));
- // Neuter initial packet.
- coalesced.NeuterInitialPacket();
- EXPECT_EQ(0u, coalesced.max_packet_length());
- EXPECT_EQ(0u, coalesced.length());
- EXPECT_EQ("total_length: 0 padding_size: 0 packets: {}",
- coalesced.ToString(0));
-
- // Coalesce initial packet again.
- ASSERT_TRUE(coalesced.MaybeCoalescePacket(packet1, self_address, peer_address,
- &allocator, 1500));
-
- SerializedPacket packet2(QuicPacketNumber(3), PACKET_4BYTE_PACKET_NUMBER,
- buffer, 500, false, false);
- packet2.nonretransmittable_frames.push_back(QuicFrame(QuicPaddingFrame(100)));
- packet2.encryption_level = ENCRYPTION_ZERO_RTT;
- packet2.transmission_type = LOSS_RETRANSMISSION;
- ASSERT_TRUE(coalesced.MaybeCoalescePacket(packet2, self_address, peer_address,
- &allocator, 1500));
- EXPECT_EQ(1500u, coalesced.max_packet_length());
- EXPECT_EQ(1000u, coalesced.length());
- EXPECT_EQ(LOSS_RETRANSMISSION,
- coalesced.TransmissionTypeOfPacket(ENCRYPTION_ZERO_RTT));
- EXPECT_EQ(
- "total_length: 1500 padding_size: 500 packets: {ENCRYPTION_INITIAL, "
- "ENCRYPTION_ZERO_RTT}",
- coalesced.ToString(1500));
-
- // Neuter initial packet.
- coalesced.NeuterInitialPacket();
- EXPECT_EQ(1500u, coalesced.max_packet_length());
- EXPECT_EQ(500u, coalesced.length());
- EXPECT_EQ(
- "total_length: 1500 padding_size: 1000 packets: {ENCRYPTION_ZERO_RTT}",
- coalesced.ToString(1500));
-
- SerializedPacket packet3(QuicPacketNumber(5), PACKET_4BYTE_PACKET_NUMBER,
- buffer, 501, false, false);
- packet3.encryption_level = ENCRYPTION_FORWARD_SECURE;
- EXPECT_TRUE(coalesced.MaybeCoalescePacket(packet3, self_address, peer_address,
- &allocator, 1500));
- EXPECT_EQ(1500u, coalesced.max_packet_length());
- EXPECT_EQ(1001u, coalesced.length());
- // Neuter initial packet.
- coalesced.NeuterInitialPacket();
- EXPECT_EQ(1500u, coalesced.max_packet_length());
- EXPECT_EQ(1001u, coalesced.length());
-}
-
-} // namespace
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_config.cc b/chromium/net/third_party/quiche/src/quic/core/quic_config.cc
deleted file mode 100644
index 8313ef76fbd..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_config.cc
+++ /dev/null
@@ -1,1424 +0,0 @@
-// Copyright (c) 2013 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 "quic/core/quic_config.h"
-
-#include <algorithm>
-#include <cstring>
-#include <limits>
-#include <string>
-#include <utility>
-
-#include "absl/base/attributes.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/crypto/crypto_handshake_message.h"
-#include "quic/core/crypto/crypto_protocol.h"
-#include "quic/core/quic_connection_id.h"
-#include "quic/core/quic_constants.h"
-#include "quic/core/quic_socket_address_coder.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_flag_utils.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/platform/api/quic_socket_address.h"
-
-namespace quic {
-
-// Reads the value corresponding to |name_| from |msg| into |out|. If the
-// |name_| is absent in |msg| and |presence| is set to OPTIONAL |out| is set
-// to |default_value|.
-QuicErrorCode ReadUint32(const CryptoHandshakeMessage& msg,
- QuicTag tag,
- QuicConfigPresence presence,
- uint32_t default_value,
- uint32_t* out,
- std::string* error_details) {
- QUICHE_DCHECK(error_details != nullptr);
- QuicErrorCode error = msg.GetUint32(tag, out);
- switch (error) {
- case QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND:
- if (presence == PRESENCE_REQUIRED) {
- *error_details = "Missing " + QuicTagToString(tag);
- break;
- }
- error = QUIC_NO_ERROR;
- *out = default_value;
- break;
- case QUIC_NO_ERROR:
- break;
- default:
- *error_details = "Bad " + QuicTagToString(tag);
- break;
- }
- return error;
-}
-
-QuicConfigValue::QuicConfigValue(QuicTag tag, QuicConfigPresence presence)
- : tag_(tag), presence_(presence) {}
-QuicConfigValue::~QuicConfigValue() {}
-
-QuicFixedUint32::QuicFixedUint32(QuicTag tag, QuicConfigPresence presence)
- : QuicConfigValue(tag, presence),
- has_send_value_(false),
- has_receive_value_(false) {}
-QuicFixedUint32::~QuicFixedUint32() {}
-
-bool QuicFixedUint32::HasSendValue() const {
- return has_send_value_;
-}
-
-uint32_t QuicFixedUint32::GetSendValue() const {
- QUIC_BUG_IF(quic_bug_12743_1, !has_send_value_)
- << "No send value to get for tag:" << QuicTagToString(tag_);
- return send_value_;
-}
-
-void QuicFixedUint32::SetSendValue(uint32_t value) {
- has_send_value_ = true;
- send_value_ = value;
-}
-
-bool QuicFixedUint32::HasReceivedValue() const {
- return has_receive_value_;
-}
-
-uint32_t QuicFixedUint32::GetReceivedValue() const {
- QUIC_BUG_IF(quic_bug_12743_2, !has_receive_value_)
- << "No receive value to get for tag:" << QuicTagToString(tag_);
- return receive_value_;
-}
-
-void QuicFixedUint32::SetReceivedValue(uint32_t value) {
- has_receive_value_ = true;
- receive_value_ = value;
-}
-
-void QuicFixedUint32::ToHandshakeMessage(CryptoHandshakeMessage* out) const {
- if (tag_ == 0) {
- QUIC_BUG(quic_bug_12743_3)
- << "This parameter does not support writing to CryptoHandshakeMessage";
- return;
- }
- if (has_send_value_) {
- out->SetValue(tag_, send_value_);
- }
-}
-
-QuicErrorCode QuicFixedUint32::ProcessPeerHello(
- const CryptoHandshakeMessage& peer_hello,
- HelloType /*hello_type*/,
- std::string* error_details) {
- QUICHE_DCHECK(error_details != nullptr);
- if (tag_ == 0) {
- *error_details =
- "This parameter does not support reading from CryptoHandshakeMessage";
- QUIC_BUG(quic_bug_10575_1) << *error_details;
- return QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND;
- }
- QuicErrorCode error = peer_hello.GetUint32(tag_, &receive_value_);
- switch (error) {
- case QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND:
- if (presence_ == PRESENCE_OPTIONAL) {
- return QUIC_NO_ERROR;
- }
- *error_details = "Missing " + QuicTagToString(tag_);
- break;
- case QUIC_NO_ERROR:
- has_receive_value_ = true;
- break;
- default:
- *error_details = "Bad " + QuicTagToString(tag_);
- break;
- }
- return error;
-}
-
-QuicFixedUint62::QuicFixedUint62(QuicTag name, QuicConfigPresence presence)
- : QuicConfigValue(name, presence),
- has_send_value_(false),
- has_receive_value_(false) {}
-
-QuicFixedUint62::~QuicFixedUint62() {}
-
-bool QuicFixedUint62::HasSendValue() const {
- return has_send_value_;
-}
-
-uint64_t QuicFixedUint62::GetSendValue() const {
- if (!has_send_value_) {
- QUIC_BUG(quic_bug_10575_2)
- << "No send value to get for tag:" << QuicTagToString(tag_);
- return 0;
- }
- return send_value_;
-}
-
-void QuicFixedUint62::SetSendValue(uint64_t value) {
- if (value > kVarInt62MaxValue) {
- QUIC_BUG(quic_bug_10575_3) << "QuicFixedUint62 invalid value " << value;
- value = kVarInt62MaxValue;
- }
- has_send_value_ = true;
- send_value_ = value;
-}
-
-bool QuicFixedUint62::HasReceivedValue() const {
- return has_receive_value_;
-}
-
-uint64_t QuicFixedUint62::GetReceivedValue() const {
- if (!has_receive_value_) {
- QUIC_BUG(quic_bug_10575_4)
- << "No receive value to get for tag:" << QuicTagToString(tag_);
- return 0;
- }
- return receive_value_;
-}
-
-void QuicFixedUint62::SetReceivedValue(uint64_t value) {
- has_receive_value_ = true;
- receive_value_ = value;
-}
-
-void QuicFixedUint62::ToHandshakeMessage(CryptoHandshakeMessage* out) const {
- if (!has_send_value_) {
- return;
- }
- uint32_t send_value32;
- if (send_value_ > std::numeric_limits<uint32_t>::max()) {
- QUIC_BUG(quic_bug_10575_5) << "Attempting to send " << send_value_
- << " for tag:" << QuicTagToString(tag_);
- send_value32 = std::numeric_limits<uint32_t>::max();
- } else {
- send_value32 = static_cast<uint32_t>(send_value_);
- }
- out->SetValue(tag_, send_value32);
-}
-
-QuicErrorCode QuicFixedUint62::ProcessPeerHello(
- const CryptoHandshakeMessage& peer_hello,
- HelloType /*hello_type*/,
- std::string* error_details) {
- QUICHE_DCHECK(error_details != nullptr);
- uint32_t receive_value32;
- QuicErrorCode error = peer_hello.GetUint32(tag_, &receive_value32);
- // GetUint32 is guaranteed to always initialize receive_value32.
- receive_value_ = receive_value32;
- switch (error) {
- case QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND:
- if (presence_ == PRESENCE_OPTIONAL) {
- return QUIC_NO_ERROR;
- }
- *error_details = "Missing " + QuicTagToString(tag_);
- break;
- case QUIC_NO_ERROR:
- has_receive_value_ = true;
- break;
- default:
- *error_details = "Bad " + QuicTagToString(tag_);
- break;
- }
- return error;
-}
-
-QuicFixedStatelessResetToken::QuicFixedStatelessResetToken(
- QuicTag tag,
- QuicConfigPresence presence)
- : QuicConfigValue(tag, presence),
- has_send_value_(false),
- has_receive_value_(false) {}
-QuicFixedStatelessResetToken::~QuicFixedStatelessResetToken() {}
-
-bool QuicFixedStatelessResetToken::HasSendValue() const {
- return has_send_value_;
-}
-
-const StatelessResetToken& QuicFixedStatelessResetToken::GetSendValue() const {
- QUIC_BUG_IF(quic_bug_12743_4, !has_send_value_)
- << "No send value to get for tag:" << QuicTagToString(tag_);
- return send_value_;
-}
-
-void QuicFixedStatelessResetToken::SetSendValue(
- const StatelessResetToken& value) {
- has_send_value_ = true;
- send_value_ = value;
-}
-
-bool QuicFixedStatelessResetToken::HasReceivedValue() const {
- return has_receive_value_;
-}
-
-const StatelessResetToken& QuicFixedStatelessResetToken::GetReceivedValue()
- const {
- QUIC_BUG_IF(quic_bug_12743_5, !has_receive_value_)
- << "No receive value to get for tag:" << QuicTagToString(tag_);
- return receive_value_;
-}
-
-void QuicFixedStatelessResetToken::SetReceivedValue(
- const StatelessResetToken& value) {
- has_receive_value_ = true;
- receive_value_ = value;
-}
-
-void QuicFixedStatelessResetToken::ToHandshakeMessage(
- CryptoHandshakeMessage* out) const {
- if (has_send_value_) {
- out->SetValue(tag_, send_value_);
- }
-}
-
-QuicErrorCode QuicFixedStatelessResetToken::ProcessPeerHello(
- const CryptoHandshakeMessage& peer_hello,
- HelloType /*hello_type*/,
- std::string* error_details) {
- QUICHE_DCHECK(error_details != nullptr);
- QuicErrorCode error =
- peer_hello.GetStatelessResetToken(tag_, &receive_value_);
- switch (error) {
- case QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND:
- if (presence_ == PRESENCE_OPTIONAL) {
- return QUIC_NO_ERROR;
- }
- *error_details = "Missing " + QuicTagToString(tag_);
- break;
- case QUIC_NO_ERROR:
- has_receive_value_ = true;
- break;
- default:
- *error_details = "Bad " + QuicTagToString(tag_);
- break;
- }
- return error;
-}
-
-QuicFixedTagVector::QuicFixedTagVector(QuicTag name,
- QuicConfigPresence presence)
- : QuicConfigValue(name, presence),
- has_send_values_(false),
- has_receive_values_(false) {}
-
-QuicFixedTagVector::QuicFixedTagVector(const QuicFixedTagVector& other) =
- default;
-
-QuicFixedTagVector::~QuicFixedTagVector() {}
-
-bool QuicFixedTagVector::HasSendValues() const {
- return has_send_values_;
-}
-
-const QuicTagVector& QuicFixedTagVector::GetSendValues() const {
- QUIC_BUG_IF(quic_bug_12743_6, !has_send_values_)
- << "No send values to get for tag:" << QuicTagToString(tag_);
- return send_values_;
-}
-
-void QuicFixedTagVector::SetSendValues(const QuicTagVector& values) {
- has_send_values_ = true;
- send_values_ = values;
-}
-
-bool QuicFixedTagVector::HasReceivedValues() const {
- return has_receive_values_;
-}
-
-const QuicTagVector& QuicFixedTagVector::GetReceivedValues() const {
- QUIC_BUG_IF(quic_bug_12743_7, !has_receive_values_)
- << "No receive value to get for tag:" << QuicTagToString(tag_);
- return receive_values_;
-}
-
-void QuicFixedTagVector::SetReceivedValues(const QuicTagVector& values) {
- has_receive_values_ = true;
- receive_values_ = values;
-}
-
-void QuicFixedTagVector::ToHandshakeMessage(CryptoHandshakeMessage* out) const {
- if (has_send_values_) {
- out->SetVector(tag_, send_values_);
- }
-}
-
-QuicErrorCode QuicFixedTagVector::ProcessPeerHello(
- const CryptoHandshakeMessage& peer_hello,
- HelloType /*hello_type*/,
- std::string* error_details) {
- QUICHE_DCHECK(error_details != nullptr);
- QuicTagVector values;
- QuicErrorCode error = peer_hello.GetTaglist(tag_, &values);
- switch (error) {
- case QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND:
- if (presence_ == PRESENCE_OPTIONAL) {
- return QUIC_NO_ERROR;
- }
- *error_details = "Missing " + QuicTagToString(tag_);
- break;
- case QUIC_NO_ERROR:
- QUIC_DVLOG(1) << "Received Connection Option tags from receiver.";
- has_receive_values_ = true;
- receive_values_.insert(receive_values_.end(), values.begin(),
- values.end());
- break;
- default:
- *error_details = "Bad " + QuicTagToString(tag_);
- break;
- }
- return error;
-}
-
-QuicFixedSocketAddress::QuicFixedSocketAddress(QuicTag tag,
- QuicConfigPresence presence)
- : QuicConfigValue(tag, presence),
- has_send_value_(false),
- has_receive_value_(false) {}
-
-QuicFixedSocketAddress::~QuicFixedSocketAddress() {}
-
-bool QuicFixedSocketAddress::HasSendValue() const {
- return has_send_value_;
-}
-
-const QuicSocketAddress& QuicFixedSocketAddress::GetSendValue() const {
- QUIC_BUG_IF(quic_bug_12743_8, !has_send_value_)
- << "No send value to get for tag:" << QuicTagToString(tag_);
- return send_value_;
-}
-
-void QuicFixedSocketAddress::SetSendValue(const QuicSocketAddress& value) {
- has_send_value_ = true;
- send_value_ = value;
-}
-
-bool QuicFixedSocketAddress::HasReceivedValue() const {
- return has_receive_value_;
-}
-
-const QuicSocketAddress& QuicFixedSocketAddress::GetReceivedValue() const {
- QUIC_BUG_IF(quic_bug_12743_9, !has_receive_value_)
- << "No receive value to get for tag:" << QuicTagToString(tag_);
- return receive_value_;
-}
-
-void QuicFixedSocketAddress::SetReceivedValue(const QuicSocketAddress& value) {
- has_receive_value_ = true;
- receive_value_ = value;
-}
-
-void QuicFixedSocketAddress::ToHandshakeMessage(
- CryptoHandshakeMessage* out) const {
- if (has_send_value_) {
- QuicSocketAddressCoder address_coder(send_value_);
- out->SetStringPiece(tag_, address_coder.Encode());
- }
-}
-
-QuicErrorCode QuicFixedSocketAddress::ProcessPeerHello(
- const CryptoHandshakeMessage& peer_hello,
- HelloType /*hello_type*/,
- std::string* error_details) {
- absl::string_view address;
- if (!peer_hello.GetStringPiece(tag_, &address)) {
- if (presence_ == PRESENCE_REQUIRED) {
- *error_details = "Missing " + QuicTagToString(tag_);
- return QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND;
- }
- } else {
- QuicSocketAddressCoder address_coder;
- if (address_coder.Decode(address.data(), address.length())) {
- SetReceivedValue(
- QuicSocketAddress(address_coder.ip(), address_coder.port()));
- }
- }
- return QUIC_NO_ERROR;
-}
-
-QuicConfig::QuicConfig()
- : negotiated_(false),
- max_time_before_crypto_handshake_(QuicTime::Delta::Zero()),
- max_idle_time_before_crypto_handshake_(QuicTime::Delta::Zero()),
- max_undecryptable_packets_(0),
- connection_options_(kCOPT, PRESENCE_OPTIONAL),
- client_connection_options_(kCLOP, PRESENCE_OPTIONAL),
- max_idle_timeout_to_send_(QuicTime::Delta::Infinite()),
- max_bidirectional_streams_(kMIBS, PRESENCE_REQUIRED),
- max_unidirectional_streams_(kMIUS, PRESENCE_OPTIONAL),
- bytes_for_connection_id_(kTCID, PRESENCE_OPTIONAL),
- initial_round_trip_time_us_(kIRTT, PRESENCE_OPTIONAL),
- initial_max_stream_data_bytes_incoming_bidirectional_(0,
- PRESENCE_OPTIONAL),
- initial_max_stream_data_bytes_outgoing_bidirectional_(0,
- PRESENCE_OPTIONAL),
- initial_max_stream_data_bytes_unidirectional_(0, PRESENCE_OPTIONAL),
- initial_stream_flow_control_window_bytes_(kSFCW, PRESENCE_OPTIONAL),
- initial_session_flow_control_window_bytes_(kCFCW, PRESENCE_OPTIONAL),
- connection_migration_disabled_(kNCMR, PRESENCE_OPTIONAL),
- alternate_server_address_ipv6_(kASAD, PRESENCE_OPTIONAL),
- alternate_server_address_ipv4_(kASAD, PRESENCE_OPTIONAL),
- stateless_reset_token_(kSRST, PRESENCE_OPTIONAL),
- max_ack_delay_ms_(kMAD, PRESENCE_OPTIONAL),
- min_ack_delay_ms_(0, PRESENCE_OPTIONAL),
- ack_delay_exponent_(kADE, PRESENCE_OPTIONAL),
- max_udp_payload_size_(0, PRESENCE_OPTIONAL),
- max_datagram_frame_size_(0, PRESENCE_OPTIONAL),
- active_connection_id_limit_(0, PRESENCE_OPTIONAL) {
- SetDefaults();
-}
-
-QuicConfig::QuicConfig(const QuicConfig& other) = default;
-
-QuicConfig::~QuicConfig() {}
-
-bool QuicConfig::SetInitialReceivedConnectionOptions(
- const QuicTagVector& tags) {
- if (HasReceivedConnectionOptions()) {
- // If we have already received connection options (via handshake or due to
- // a previous call), don't re-initialize.
- return false;
- }
- connection_options_.SetReceivedValues(tags);
- return true;
-}
-
-void QuicConfig::SetConnectionOptionsToSend(
- const QuicTagVector& connection_options) {
- connection_options_.SetSendValues(connection_options);
-}
-
-bool QuicConfig::HasReceivedConnectionOptions() const {
- return connection_options_.HasReceivedValues();
-}
-
-const QuicTagVector& QuicConfig::ReceivedConnectionOptions() const {
- return connection_options_.GetReceivedValues();
-}
-
-bool QuicConfig::HasSendConnectionOptions() const {
- return connection_options_.HasSendValues();
-}
-
-const QuicTagVector& QuicConfig::SendConnectionOptions() const {
- return connection_options_.GetSendValues();
-}
-
-bool QuicConfig::HasClientSentConnectionOption(QuicTag tag,
- Perspective perspective) const {
- if (perspective == Perspective::IS_SERVER) {
- if (HasReceivedConnectionOptions() &&
- ContainsQuicTag(ReceivedConnectionOptions(), tag)) {
- return true;
- }
- } else if (HasSendConnectionOptions() &&
- ContainsQuicTag(SendConnectionOptions(), tag)) {
- return true;
- }
- return false;
-}
-
-void QuicConfig::SetClientConnectionOptions(
- const QuicTagVector& client_connection_options) {
- client_connection_options_.SetSendValues(client_connection_options);
-}
-
-bool QuicConfig::HasClientRequestedIndependentOption(
- QuicTag tag,
- Perspective perspective) const {
- if (perspective == Perspective::IS_SERVER) {
- return (HasReceivedConnectionOptions() &&
- ContainsQuicTag(ReceivedConnectionOptions(), tag));
- }
-
- return (client_connection_options_.HasSendValues() &&
- ContainsQuicTag(client_connection_options_.GetSendValues(), tag));
-}
-
-const QuicTagVector& QuicConfig::ClientRequestedIndependentOptions(
- Perspective perspective) const {
- static const QuicTagVector* no_options = new QuicTagVector;
- if (perspective == Perspective::IS_SERVER) {
- return HasReceivedConnectionOptions() ? ReceivedConnectionOptions()
- : *no_options;
- }
-
- return client_connection_options_.HasSendValues()
- ? client_connection_options_.GetSendValues()
- : *no_options;
-}
-
-void QuicConfig::SetIdleNetworkTimeout(QuicTime::Delta idle_network_timeout) {
- if (idle_network_timeout.ToMicroseconds() <= 0) {
- QUIC_BUG(quic_bug_10575_6)
- << "Invalid idle network timeout " << idle_network_timeout;
- return;
- }
- max_idle_timeout_to_send_ = idle_network_timeout;
-}
-
-QuicTime::Delta QuicConfig::IdleNetworkTimeout() const {
- // TODO(b/152032210) add a QUIC_BUG to ensure that is not called before we've
- // received the peer's values. This is true in production code but not in all
- // of our tests that use a fake QuicConfig.
- if (!received_max_idle_timeout_.has_value()) {
- return max_idle_timeout_to_send_;
- }
- return received_max_idle_timeout_.value();
-}
-
-void QuicConfig::SetMaxBidirectionalStreamsToSend(uint32_t max_streams) {
- max_bidirectional_streams_.SetSendValue(max_streams);
-}
-
-uint32_t QuicConfig::GetMaxBidirectionalStreamsToSend() const {
- return max_bidirectional_streams_.GetSendValue();
-}
-
-bool QuicConfig::HasReceivedMaxBidirectionalStreams() const {
- return max_bidirectional_streams_.HasReceivedValue();
-}
-
-uint32_t QuicConfig::ReceivedMaxBidirectionalStreams() const {
- return max_bidirectional_streams_.GetReceivedValue();
-}
-
-void QuicConfig::SetMaxUnidirectionalStreamsToSend(uint32_t max_streams) {
- max_unidirectional_streams_.SetSendValue(max_streams);
-}
-
-uint32_t QuicConfig::GetMaxUnidirectionalStreamsToSend() const {
- return max_unidirectional_streams_.GetSendValue();
-}
-
-bool QuicConfig::HasReceivedMaxUnidirectionalStreams() const {
- return max_unidirectional_streams_.HasReceivedValue();
-}
-
-uint32_t QuicConfig::ReceivedMaxUnidirectionalStreams() const {
- return max_unidirectional_streams_.GetReceivedValue();
-}
-
-void QuicConfig::SetMaxAckDelayToSendMs(uint32_t max_ack_delay_ms) {
- max_ack_delay_ms_.SetSendValue(max_ack_delay_ms);
-}
-
-uint32_t QuicConfig::GetMaxAckDelayToSendMs() const {
- return max_ack_delay_ms_.GetSendValue();
-}
-
-bool QuicConfig::HasReceivedMaxAckDelayMs() const {
- return max_ack_delay_ms_.HasReceivedValue();
-}
-
-uint32_t QuicConfig::ReceivedMaxAckDelayMs() const {
- return max_ack_delay_ms_.GetReceivedValue();
-}
-
-void QuicConfig::SetMinAckDelayMs(uint32_t min_ack_delay_ms) {
- min_ack_delay_ms_.SetSendValue(min_ack_delay_ms);
-}
-
-uint32_t QuicConfig::GetMinAckDelayToSendMs() const {
- return min_ack_delay_ms_.GetSendValue();
-}
-
-bool QuicConfig::HasReceivedMinAckDelayMs() const {
- return min_ack_delay_ms_.HasReceivedValue();
-}
-
-uint32_t QuicConfig::ReceivedMinAckDelayMs() const {
- return min_ack_delay_ms_.GetReceivedValue();
-}
-
-void QuicConfig::SetAckDelayExponentToSend(uint32_t exponent) {
- ack_delay_exponent_.SetSendValue(exponent);
-}
-
-uint32_t QuicConfig::GetAckDelayExponentToSend() const {
- return ack_delay_exponent_.GetSendValue();
-}
-
-bool QuicConfig::HasReceivedAckDelayExponent() const {
- return ack_delay_exponent_.HasReceivedValue();
-}
-
-uint32_t QuicConfig::ReceivedAckDelayExponent() const {
- return ack_delay_exponent_.GetReceivedValue();
-}
-
-void QuicConfig::SetMaxPacketSizeToSend(uint64_t max_udp_payload_size) {
- max_udp_payload_size_.SetSendValue(max_udp_payload_size);
-}
-
-uint64_t QuicConfig::GetMaxPacketSizeToSend() const {
- return max_udp_payload_size_.GetSendValue();
-}
-
-bool QuicConfig::HasReceivedMaxPacketSize() const {
- return max_udp_payload_size_.HasReceivedValue();
-}
-
-uint64_t QuicConfig::ReceivedMaxPacketSize() const {
- return max_udp_payload_size_.GetReceivedValue();
-}
-
-void QuicConfig::SetMaxDatagramFrameSizeToSend(
- uint64_t max_datagram_frame_size) {
- max_datagram_frame_size_.SetSendValue(max_datagram_frame_size);
-}
-
-uint64_t QuicConfig::GetMaxDatagramFrameSizeToSend() const {
- return max_datagram_frame_size_.GetSendValue();
-}
-
-bool QuicConfig::HasReceivedMaxDatagramFrameSize() const {
- return max_datagram_frame_size_.HasReceivedValue();
-}
-
-uint64_t QuicConfig::ReceivedMaxDatagramFrameSize() const {
- return max_datagram_frame_size_.GetReceivedValue();
-}
-
-void QuicConfig::SetActiveConnectionIdLimitToSend(
- uint64_t active_connection_id_limit) {
- active_connection_id_limit_.SetSendValue(active_connection_id_limit);
-}
-
-uint64_t QuicConfig::GetActiveConnectionIdLimitToSend() const {
- return active_connection_id_limit_.GetSendValue();
-}
-
-bool QuicConfig::HasReceivedActiveConnectionIdLimit() const {
- return active_connection_id_limit_.HasReceivedValue();
-}
-
-uint64_t QuicConfig::ReceivedActiveConnectionIdLimit() const {
- return active_connection_id_limit_.GetReceivedValue();
-}
-
-bool QuicConfig::HasSetBytesForConnectionIdToSend() const {
- return bytes_for_connection_id_.HasSendValue();
-}
-
-void QuicConfig::SetBytesForConnectionIdToSend(uint32_t bytes) {
- bytes_for_connection_id_.SetSendValue(bytes);
-}
-
-bool QuicConfig::HasReceivedBytesForConnectionId() const {
- return bytes_for_connection_id_.HasReceivedValue();
-}
-
-uint32_t QuicConfig::ReceivedBytesForConnectionId() const {
- return bytes_for_connection_id_.GetReceivedValue();
-}
-
-void QuicConfig::SetInitialRoundTripTimeUsToSend(uint64_t rtt) {
- initial_round_trip_time_us_.SetSendValue(rtt);
-}
-
-bool QuicConfig::HasReceivedInitialRoundTripTimeUs() const {
- return initial_round_trip_time_us_.HasReceivedValue();
-}
-
-uint64_t QuicConfig::ReceivedInitialRoundTripTimeUs() const {
- return initial_round_trip_time_us_.GetReceivedValue();
-}
-
-bool QuicConfig::HasInitialRoundTripTimeUsToSend() const {
- return initial_round_trip_time_us_.HasSendValue();
-}
-
-uint64_t QuicConfig::GetInitialRoundTripTimeUsToSend() const {
- return initial_round_trip_time_us_.GetSendValue();
-}
-
-void QuicConfig::SetInitialStreamFlowControlWindowToSend(
- uint64_t window_bytes) {
- if (window_bytes < kMinimumFlowControlSendWindow) {
- QUIC_BUG(quic_bug_10575_7)
- << "Initial stream flow control receive window (" << window_bytes
- << ") cannot be set lower than minimum ("
- << kMinimumFlowControlSendWindow << ").";
- window_bytes = kMinimumFlowControlSendWindow;
- }
- initial_stream_flow_control_window_bytes_.SetSendValue(window_bytes);
-}
-
-uint64_t QuicConfig::GetInitialStreamFlowControlWindowToSend() const {
- return initial_stream_flow_control_window_bytes_.GetSendValue();
-}
-
-bool QuicConfig::HasReceivedInitialStreamFlowControlWindowBytes() const {
- return initial_stream_flow_control_window_bytes_.HasReceivedValue();
-}
-
-uint64_t QuicConfig::ReceivedInitialStreamFlowControlWindowBytes() const {
- return initial_stream_flow_control_window_bytes_.GetReceivedValue();
-}
-
-void QuicConfig::SetInitialMaxStreamDataBytesIncomingBidirectionalToSend(
- uint64_t window_bytes) {
- initial_max_stream_data_bytes_incoming_bidirectional_.SetSendValue(
- window_bytes);
-}
-
-uint64_t QuicConfig::GetInitialMaxStreamDataBytesIncomingBidirectionalToSend()
- const {
- if (initial_max_stream_data_bytes_incoming_bidirectional_.HasSendValue()) {
- return initial_max_stream_data_bytes_incoming_bidirectional_.GetSendValue();
- }
- return initial_stream_flow_control_window_bytes_.GetSendValue();
-}
-
-bool QuicConfig::HasReceivedInitialMaxStreamDataBytesIncomingBidirectional()
- const {
- return initial_max_stream_data_bytes_incoming_bidirectional_
- .HasReceivedValue();
-}
-
-uint64_t QuicConfig::ReceivedInitialMaxStreamDataBytesIncomingBidirectional()
- const {
- return initial_max_stream_data_bytes_incoming_bidirectional_
- .GetReceivedValue();
-}
-
-void QuicConfig::SetInitialMaxStreamDataBytesOutgoingBidirectionalToSend(
- uint64_t window_bytes) {
- initial_max_stream_data_bytes_outgoing_bidirectional_.SetSendValue(
- window_bytes);
-}
-
-uint64_t QuicConfig::GetInitialMaxStreamDataBytesOutgoingBidirectionalToSend()
- const {
- if (initial_max_stream_data_bytes_outgoing_bidirectional_.HasSendValue()) {
- return initial_max_stream_data_bytes_outgoing_bidirectional_.GetSendValue();
- }
- return initial_stream_flow_control_window_bytes_.GetSendValue();
-}
-
-bool QuicConfig::HasReceivedInitialMaxStreamDataBytesOutgoingBidirectional()
- const {
- return initial_max_stream_data_bytes_outgoing_bidirectional_
- .HasReceivedValue();
-}
-
-uint64_t QuicConfig::ReceivedInitialMaxStreamDataBytesOutgoingBidirectional()
- const {
- return initial_max_stream_data_bytes_outgoing_bidirectional_
- .GetReceivedValue();
-}
-
-void QuicConfig::SetInitialMaxStreamDataBytesUnidirectionalToSend(
- uint64_t window_bytes) {
- initial_max_stream_data_bytes_unidirectional_.SetSendValue(window_bytes);
-}
-
-uint64_t QuicConfig::GetInitialMaxStreamDataBytesUnidirectionalToSend() const {
- if (initial_max_stream_data_bytes_unidirectional_.HasSendValue()) {
- return initial_max_stream_data_bytes_unidirectional_.GetSendValue();
- }
- return initial_stream_flow_control_window_bytes_.GetSendValue();
-}
-
-bool QuicConfig::HasReceivedInitialMaxStreamDataBytesUnidirectional() const {
- return initial_max_stream_data_bytes_unidirectional_.HasReceivedValue();
-}
-
-uint64_t QuicConfig::ReceivedInitialMaxStreamDataBytesUnidirectional() const {
- return initial_max_stream_data_bytes_unidirectional_.GetReceivedValue();
-}
-
-void QuicConfig::SetInitialSessionFlowControlWindowToSend(
- uint64_t window_bytes) {
- if (window_bytes < kMinimumFlowControlSendWindow) {
- QUIC_BUG(quic_bug_10575_8)
- << "Initial session flow control receive window (" << window_bytes
- << ") cannot be set lower than default ("
- << kMinimumFlowControlSendWindow << ").";
- window_bytes = kMinimumFlowControlSendWindow;
- }
- initial_session_flow_control_window_bytes_.SetSendValue(window_bytes);
-}
-
-uint64_t QuicConfig::GetInitialSessionFlowControlWindowToSend() const {
- return initial_session_flow_control_window_bytes_.GetSendValue();
-}
-
-bool QuicConfig::HasReceivedInitialSessionFlowControlWindowBytes() const {
- return initial_session_flow_control_window_bytes_.HasReceivedValue();
-}
-
-uint64_t QuicConfig::ReceivedInitialSessionFlowControlWindowBytes() const {
- return initial_session_flow_control_window_bytes_.GetReceivedValue();
-}
-
-void QuicConfig::SetDisableConnectionMigration() {
- connection_migration_disabled_.SetSendValue(1);
-}
-
-bool QuicConfig::DisableConnectionMigration() const {
- return connection_migration_disabled_.HasReceivedValue();
-}
-
-void QuicConfig::SetIPv6AlternateServerAddressToSend(
- const QuicSocketAddress& alternate_server_address_ipv6) {
- if (!alternate_server_address_ipv6.host().IsIPv6()) {
- QUIC_BUG(quic_bug_10575_9)
- << "Cannot use SetIPv6AlternateServerAddressToSend with "
- << alternate_server_address_ipv6;
- return;
- }
- alternate_server_address_ipv6_.SetSendValue(alternate_server_address_ipv6);
-}
-
-void QuicConfig::SetIPv6AlternateServerAddressToSend(
- const QuicSocketAddress& alternate_server_address_ipv6,
- const QuicConnectionId& connection_id,
- const StatelessResetToken& stateless_reset_token) {
- if (!alternate_server_address_ipv6.host().IsIPv6()) {
- QUIC_BUG(quic_bug_10575_10)
- << "Cannot use SetIPv6AlternateServerAddressToSend with "
- << alternate_server_address_ipv6;
- return;
- }
- alternate_server_address_ipv6_.SetSendValue(alternate_server_address_ipv6);
- preferred_address_connection_id_and_token_ =
- std::make_pair(connection_id, stateless_reset_token);
-}
-
-bool QuicConfig::HasReceivedIPv6AlternateServerAddress() const {
- return alternate_server_address_ipv6_.HasReceivedValue();
-}
-
-const QuicSocketAddress& QuicConfig::ReceivedIPv6AlternateServerAddress()
- const {
- return alternate_server_address_ipv6_.GetReceivedValue();
-}
-
-void QuicConfig::SetIPv4AlternateServerAddressToSend(
- const QuicSocketAddress& alternate_server_address_ipv4) {
- if (!alternate_server_address_ipv4.host().IsIPv4()) {
- QUIC_BUG(quic_bug_10575_11)
- << "Cannot use SetIPv4AlternateServerAddressToSend with "
- << alternate_server_address_ipv4;
- return;
- }
- alternate_server_address_ipv4_.SetSendValue(alternate_server_address_ipv4);
-}
-
-void QuicConfig::SetIPv4AlternateServerAddressToSend(
- const QuicSocketAddress& alternate_server_address_ipv4,
- const QuicConnectionId& connection_id,
- const StatelessResetToken& stateless_reset_token) {
- if (!alternate_server_address_ipv4.host().IsIPv4()) {
- QUIC_BUG(quic_bug_10575_12)
- << "Cannot use SetIPv4AlternateServerAddressToSend with "
- << alternate_server_address_ipv4;
- return;
- }
- alternate_server_address_ipv4_.SetSendValue(alternate_server_address_ipv4);
- preferred_address_connection_id_and_token_ =
- std::make_pair(connection_id, stateless_reset_token);
-}
-
-bool QuicConfig::HasReceivedIPv4AlternateServerAddress() const {
- return alternate_server_address_ipv4_.HasReceivedValue();
-}
-
-const QuicSocketAddress& QuicConfig::ReceivedIPv4AlternateServerAddress()
- const {
- return alternate_server_address_ipv4_.GetReceivedValue();
-}
-
-bool QuicConfig::HasReceivedPreferredAddressConnectionIdAndToken() const {
- return (HasReceivedIPv6AlternateServerAddress() ||
- HasReceivedIPv4AlternateServerAddress()) &&
- preferred_address_connection_id_and_token_.has_value();
-}
-
-const std::pair<QuicConnectionId, StatelessResetToken>&
-QuicConfig::ReceivedPreferredAddressConnectionIdAndToken() const {
- QUICHE_DCHECK(HasReceivedPreferredAddressConnectionIdAndToken());
- return *preferred_address_connection_id_and_token_;
-}
-
-void QuicConfig::SetOriginalConnectionIdToSend(
- const QuicConnectionId& original_destination_connection_id) {
- original_destination_connection_id_to_send_ =
- original_destination_connection_id;
-}
-
-bool QuicConfig::HasReceivedOriginalConnectionId() const {
- return received_original_destination_connection_id_.has_value();
-}
-
-QuicConnectionId QuicConfig::ReceivedOriginalConnectionId() const {
- if (!HasReceivedOriginalConnectionId()) {
- QUIC_BUG(quic_bug_10575_13) << "No received original connection ID";
- return EmptyQuicConnectionId();
- }
- return received_original_destination_connection_id_.value();
-}
-
-void QuicConfig::SetInitialSourceConnectionIdToSend(
- const QuicConnectionId& initial_source_connection_id) {
- initial_source_connection_id_to_send_ = initial_source_connection_id;
-}
-
-bool QuicConfig::HasReceivedInitialSourceConnectionId() const {
- return received_initial_source_connection_id_.has_value();
-}
-
-QuicConnectionId QuicConfig::ReceivedInitialSourceConnectionId() const {
- if (!HasReceivedInitialSourceConnectionId()) {
- QUIC_BUG(quic_bug_10575_14) << "No received initial source connection ID";
- return EmptyQuicConnectionId();
- }
- return received_initial_source_connection_id_.value();
-}
-
-void QuicConfig::SetRetrySourceConnectionIdToSend(
- const QuicConnectionId& retry_source_connection_id) {
- retry_source_connection_id_to_send_ = retry_source_connection_id;
-}
-
-bool QuicConfig::HasReceivedRetrySourceConnectionId() const {
- return received_retry_source_connection_id_.has_value();
-}
-
-QuicConnectionId QuicConfig::ReceivedRetrySourceConnectionId() const {
- if (!HasReceivedRetrySourceConnectionId()) {
- QUIC_BUG(quic_bug_10575_15) << "No received retry source connection ID";
- return EmptyQuicConnectionId();
- }
- return received_retry_source_connection_id_.value();
-}
-
-void QuicConfig::SetStatelessResetTokenToSend(
- const StatelessResetToken& stateless_reset_token) {
- stateless_reset_token_.SetSendValue(stateless_reset_token);
-}
-
-bool QuicConfig::HasReceivedStatelessResetToken() const {
- return stateless_reset_token_.HasReceivedValue();
-}
-
-const StatelessResetToken& QuicConfig::ReceivedStatelessResetToken() const {
- return stateless_reset_token_.GetReceivedValue();
-}
-
-bool QuicConfig::negotiated() const {
- return negotiated_;
-}
-
-void QuicConfig::SetCreateSessionTagIndicators(QuicTagVector tags) {
- create_session_tag_indicators_ = std::move(tags);
-}
-
-const QuicTagVector& QuicConfig::create_session_tag_indicators() const {
- return create_session_tag_indicators_;
-}
-
-void QuicConfig::SetDefaults() {
- SetIdleNetworkTimeout(QuicTime::Delta::FromSeconds(kMaximumIdleTimeoutSecs));
- SetMaxBidirectionalStreamsToSend(kDefaultMaxStreamsPerConnection);
- SetMaxUnidirectionalStreamsToSend(kDefaultMaxStreamsPerConnection);
- max_time_before_crypto_handshake_ =
- QuicTime::Delta::FromSeconds(kMaxTimeForCryptoHandshakeSecs);
- max_idle_time_before_crypto_handshake_ =
- QuicTime::Delta::FromSeconds(kInitialIdleTimeoutSecs);
- max_undecryptable_packets_ = kDefaultMaxUndecryptablePackets;
-
- SetInitialStreamFlowControlWindowToSend(kMinimumFlowControlSendWindow);
- SetInitialSessionFlowControlWindowToSend(kMinimumFlowControlSendWindow);
- SetMaxAckDelayToSendMs(kDefaultDelayedAckTimeMs);
- SetAckDelayExponentToSend(kDefaultAckDelayExponent);
- SetMaxPacketSizeToSend(kMaxIncomingPacketSize);
- SetMaxDatagramFrameSizeToSend(kMaxAcceptedDatagramFrameSize);
-}
-
-void QuicConfig::ToHandshakeMessage(
- CryptoHandshakeMessage* out,
- QuicTransportVersion transport_version) const {
- // Idle timeout has custom rules that are different from other values.
- // We configure ourselves with the minumum value between the one sent and
- // the one received. Additionally, when QUIC_CRYPTO is used, the server
- // MUST send an idle timeout no greater than the idle timeout it received
- // from the client. We therefore send the received value if it is lower.
- QuicFixedUint32 max_idle_timeout_seconds(kICSL, PRESENCE_REQUIRED);
- uint32_t max_idle_timeout_to_send_seconds =
- max_idle_timeout_to_send_.ToSeconds();
- if (received_max_idle_timeout_.has_value() &&
- received_max_idle_timeout_->ToSeconds() <
- max_idle_timeout_to_send_seconds) {
- max_idle_timeout_to_send_seconds = received_max_idle_timeout_->ToSeconds();
- }
- max_idle_timeout_seconds.SetSendValue(max_idle_timeout_to_send_seconds);
- max_idle_timeout_seconds.ToHandshakeMessage(out);
-
- // Do not need a version check here, max...bi... will encode
- // as "MIDS" -- the max initial dynamic streams tag -- if
- // doing some version other than IETF QUIC.
- max_bidirectional_streams_.ToHandshakeMessage(out);
- if (VersionHasIetfQuicFrames(transport_version)) {
- max_unidirectional_streams_.ToHandshakeMessage(out);
- ack_delay_exponent_.ToHandshakeMessage(out);
- }
- if (max_ack_delay_ms_.GetSendValue() != kDefaultDelayedAckTimeMs) {
- // Only send max ack delay if it is using a non-default value, because
- // the default value is used by QuicSentPacketManager if it is not
- // sent during the handshake, and we want to save bytes.
- max_ack_delay_ms_.ToHandshakeMessage(out);
- }
- bytes_for_connection_id_.ToHandshakeMessage(out);
- initial_round_trip_time_us_.ToHandshakeMessage(out);
- initial_stream_flow_control_window_bytes_.ToHandshakeMessage(out);
- initial_session_flow_control_window_bytes_.ToHandshakeMessage(out);
- connection_migration_disabled_.ToHandshakeMessage(out);
- connection_options_.ToHandshakeMessage(out);
- if (alternate_server_address_ipv6_.HasSendValue()) {
- alternate_server_address_ipv6_.ToHandshakeMessage(out);
- } else {
- alternate_server_address_ipv4_.ToHandshakeMessage(out);
- }
- stateless_reset_token_.ToHandshakeMessage(out);
-}
-
-QuicErrorCode QuicConfig::ProcessPeerHello(
- const CryptoHandshakeMessage& peer_hello,
- HelloType hello_type,
- std::string* error_details) {
- QUICHE_DCHECK(error_details != nullptr);
-
- QuicErrorCode error = QUIC_NO_ERROR;
- if (error == QUIC_NO_ERROR) {
- // Idle timeout has custom rules that are different from other values.
- // We configure ourselves with the minumum value between the one sent and
- // the one received. Additionally, when QUIC_CRYPTO is used, the server
- // MUST send an idle timeout no greater than the idle timeout it received
- // from the client.
- QuicFixedUint32 max_idle_timeout_seconds(kICSL, PRESENCE_REQUIRED);
- error = max_idle_timeout_seconds.ProcessPeerHello(peer_hello, hello_type,
- error_details);
- if (error == QUIC_NO_ERROR) {
- if (max_idle_timeout_seconds.GetReceivedValue() >
- max_idle_timeout_to_send_.ToSeconds()) {
- // The received value is higher than ours, ignore it if from the client
- // and raise an error if from the server.
- if (hello_type == SERVER) {
- error = QUIC_INVALID_NEGOTIATED_VALUE;
- *error_details =
- "Invalid value received for " + QuicTagToString(kICSL);
- }
- } else {
- received_max_idle_timeout_ = QuicTime::Delta::FromSeconds(
- max_idle_timeout_seconds.GetReceivedValue());
- }
- }
- }
- if (error == QUIC_NO_ERROR) {
- error = max_bidirectional_streams_.ProcessPeerHello(peer_hello, hello_type,
- error_details);
- }
- if (error == QUIC_NO_ERROR) {
- error = max_unidirectional_streams_.ProcessPeerHello(peer_hello, hello_type,
- error_details);
- }
- if (error == QUIC_NO_ERROR) {
- error = bytes_for_connection_id_.ProcessPeerHello(peer_hello, hello_type,
- error_details);
- }
- if (error == QUIC_NO_ERROR) {
- error = initial_round_trip_time_us_.ProcessPeerHello(peer_hello, hello_type,
- error_details);
- }
- if (error == QUIC_NO_ERROR) {
- error = initial_stream_flow_control_window_bytes_.ProcessPeerHello(
- peer_hello, hello_type, error_details);
- }
- if (error == QUIC_NO_ERROR) {
- error = initial_session_flow_control_window_bytes_.ProcessPeerHello(
- peer_hello, hello_type, error_details);
- }
- if (error == QUIC_NO_ERROR) {
- error = connection_migration_disabled_.ProcessPeerHello(
- peer_hello, hello_type, error_details);
- }
- if (error == QUIC_NO_ERROR) {
- error = connection_options_.ProcessPeerHello(peer_hello, hello_type,
- error_details);
- }
- if (error == QUIC_NO_ERROR) {
- QuicFixedSocketAddress alternate_server_address(kASAD, PRESENCE_OPTIONAL);
- error = alternate_server_address.ProcessPeerHello(peer_hello, hello_type,
- error_details);
- if (error == QUIC_NO_ERROR && alternate_server_address.HasReceivedValue()) {
- const QuicSocketAddress& received_address =
- alternate_server_address.GetReceivedValue();
- if (received_address.host().IsIPv6()) {
- alternate_server_address_ipv6_.SetReceivedValue(received_address);
- } else if (received_address.host().IsIPv4()) {
- alternate_server_address_ipv4_.SetReceivedValue(received_address);
- }
- }
- }
- if (error == QUIC_NO_ERROR) {
- error = stateless_reset_token_.ProcessPeerHello(peer_hello, hello_type,
- error_details);
- }
-
- if (error == QUIC_NO_ERROR) {
- error = max_ack_delay_ms_.ProcessPeerHello(peer_hello, hello_type,
- error_details);
- }
- if (error == QUIC_NO_ERROR) {
- error = ack_delay_exponent_.ProcessPeerHello(peer_hello, hello_type,
- error_details);
- }
- if (error == QUIC_NO_ERROR) {
- negotiated_ = true;
- }
- return error;
-}
-
-bool QuicConfig::FillTransportParameters(TransportParameters* params) const {
- if (original_destination_connection_id_to_send_.has_value()) {
- params->original_destination_connection_id =
- original_destination_connection_id_to_send_.value();
- }
-
- params->max_idle_timeout_ms.set_value(
- max_idle_timeout_to_send_.ToMilliseconds());
-
- if (stateless_reset_token_.HasSendValue()) {
- StatelessResetToken stateless_reset_token =
- stateless_reset_token_.GetSendValue();
- params->stateless_reset_token.assign(
- reinterpret_cast<const char*>(&stateless_reset_token),
- reinterpret_cast<const char*>(&stateless_reset_token) +
- sizeof(stateless_reset_token));
- }
-
- params->max_udp_payload_size.set_value(GetMaxPacketSizeToSend());
- params->max_datagram_frame_size.set_value(GetMaxDatagramFrameSizeToSend());
- params->initial_max_data.set_value(
- GetInitialSessionFlowControlWindowToSend());
- // The max stream data bidirectional transport parameters can be either local
- // or remote. A stream is local iff it is initiated by the endpoint that sent
- // the transport parameter (see the Transport Parameter Definitions section of
- // draft-ietf-quic-transport). In this function we are sending transport
- // parameters, so a local stream is one we initiated, which means an outgoing
- // stream.
- params->initial_max_stream_data_bidi_local.set_value(
- GetInitialMaxStreamDataBytesOutgoingBidirectionalToSend());
- params->initial_max_stream_data_bidi_remote.set_value(
- GetInitialMaxStreamDataBytesIncomingBidirectionalToSend());
- params->initial_max_stream_data_uni.set_value(
- GetInitialMaxStreamDataBytesUnidirectionalToSend());
- params->initial_max_streams_bidi.set_value(
- GetMaxBidirectionalStreamsToSend());
- params->initial_max_streams_uni.set_value(
- GetMaxUnidirectionalStreamsToSend());
- params->max_ack_delay.set_value(GetMaxAckDelayToSendMs());
- if (min_ack_delay_ms_.HasSendValue()) {
- params->min_ack_delay_us.set_value(min_ack_delay_ms_.GetSendValue() *
- kNumMicrosPerMilli);
- }
- params->ack_delay_exponent.set_value(GetAckDelayExponentToSend());
- params->disable_active_migration =
- connection_migration_disabled_.HasSendValue() &&
- connection_migration_disabled_.GetSendValue() != 0;
-
- if (alternate_server_address_ipv6_.HasSendValue() ||
- alternate_server_address_ipv4_.HasSendValue()) {
- TransportParameters::PreferredAddress preferred_address;
- if (alternate_server_address_ipv6_.HasSendValue()) {
- preferred_address.ipv6_socket_address =
- alternate_server_address_ipv6_.GetSendValue();
- }
- if (alternate_server_address_ipv4_.HasSendValue()) {
- preferred_address.ipv4_socket_address =
- alternate_server_address_ipv4_.GetSendValue();
- }
- if (preferred_address_connection_id_and_token_) {
- preferred_address.connection_id =
- preferred_address_connection_id_and_token_->first;
- auto* begin = reinterpret_cast<const char*>(
- &preferred_address_connection_id_and_token_->second);
- auto* end =
- begin + sizeof(preferred_address_connection_id_and_token_->second);
- preferred_address.stateless_reset_token.assign(begin, end);
- }
- params->preferred_address =
- std::make_unique<TransportParameters::PreferredAddress>(
- preferred_address);
- }
-
- if (active_connection_id_limit_.HasSendValue()) {
- params->active_connection_id_limit.set_value(
- active_connection_id_limit_.GetSendValue());
- }
-
- if (initial_source_connection_id_to_send_.has_value()) {
- params->initial_source_connection_id =
- initial_source_connection_id_to_send_.value();
- }
-
- if (retry_source_connection_id_to_send_.has_value()) {
- params->retry_source_connection_id =
- retry_source_connection_id_to_send_.value();
- }
-
- if (initial_round_trip_time_us_.HasSendValue()) {
- params->initial_round_trip_time_us.set_value(
- initial_round_trip_time_us_.GetSendValue());
- }
- if (connection_options_.HasSendValues() &&
- !connection_options_.GetSendValues().empty()) {
- params->google_connection_options = connection_options_.GetSendValues();
- }
-
- params->custom_parameters = custom_transport_parameters_to_send_;
-
- return true;
-}
-
-QuicErrorCode QuicConfig::ProcessTransportParameters(
- const TransportParameters& params,
- bool is_resumption,
- std::string* error_details) {
- if (!is_resumption && params.original_destination_connection_id.has_value()) {
- received_original_destination_connection_id_ =
- params.original_destination_connection_id.value();
- }
-
- if (params.max_idle_timeout_ms.value() > 0 &&
- params.max_idle_timeout_ms.value() <
- static_cast<uint64_t>(max_idle_timeout_to_send_.ToMilliseconds())) {
- // An idle timeout of zero indicates it is disabled.
- // We also ignore values higher than ours which will cause us to use the
- // smallest value between ours and our peer's.
- received_max_idle_timeout_ =
- QuicTime::Delta::FromMilliseconds(params.max_idle_timeout_ms.value());
- }
-
- if (!is_resumption && !params.stateless_reset_token.empty()) {
- StatelessResetToken stateless_reset_token;
- if (params.stateless_reset_token.size() != sizeof(stateless_reset_token)) {
- QUIC_BUG(quic_bug_10575_16) << "Bad stateless reset token length "
- << params.stateless_reset_token.size();
- *error_details = "Bad stateless reset token length";
- return QUIC_INTERNAL_ERROR;
- }
- memcpy(&stateless_reset_token, params.stateless_reset_token.data(),
- params.stateless_reset_token.size());
- stateless_reset_token_.SetReceivedValue(stateless_reset_token);
- }
-
- if (params.max_udp_payload_size.IsValid()) {
- max_udp_payload_size_.SetReceivedValue(params.max_udp_payload_size.value());
- }
-
- if (params.max_datagram_frame_size.IsValid()) {
- max_datagram_frame_size_.SetReceivedValue(
- params.max_datagram_frame_size.value());
- }
-
- initial_session_flow_control_window_bytes_.SetReceivedValue(
- params.initial_max_data.value());
-
- // IETF QUIC specifies stream IDs and stream counts as 62-bit integers but
- // our implementation uses uint32_t to represent them to save memory.
- max_bidirectional_streams_.SetReceivedValue(
- std::min<uint64_t>(params.initial_max_streams_bidi.value(),
- std::numeric_limits<uint32_t>::max()));
- max_unidirectional_streams_.SetReceivedValue(
- std::min<uint64_t>(params.initial_max_streams_uni.value(),
- std::numeric_limits<uint32_t>::max()));
-
- // The max stream data bidirectional transport parameters can be either local
- // or remote. A stream is local iff it is initiated by the endpoint that sent
- // the transport parameter (see the Transport Parameter Definitions section of
- // draft-ietf-quic-transport). However in this function we are processing
- // received transport parameters, so a local stream is one initiated by our
- // peer, which means an incoming stream.
- initial_max_stream_data_bytes_incoming_bidirectional_.SetReceivedValue(
- params.initial_max_stream_data_bidi_local.value());
- initial_max_stream_data_bytes_outgoing_bidirectional_.SetReceivedValue(
- params.initial_max_stream_data_bidi_remote.value());
- initial_max_stream_data_bytes_unidirectional_.SetReceivedValue(
- params.initial_max_stream_data_uni.value());
-
- if (!is_resumption) {
- max_ack_delay_ms_.SetReceivedValue(params.max_ack_delay.value());
- if (params.ack_delay_exponent.IsValid()) {
- ack_delay_exponent_.SetReceivedValue(params.ack_delay_exponent.value());
- }
- if (params.preferred_address != nullptr) {
- if (params.preferred_address->ipv6_socket_address.port() != 0) {
- alternate_server_address_ipv6_.SetReceivedValue(
- params.preferred_address->ipv6_socket_address);
- }
- if (params.preferred_address->ipv4_socket_address.port() != 0) {
- alternate_server_address_ipv4_.SetReceivedValue(
- params.preferred_address->ipv4_socket_address);
- }
- // TODO(haoyuewang) Treat 0 length connection ID sent in preferred_address
- // as a connection error of type TRANSPORT_PARAMETER_ERROR when server
- // fully supports it.
- if (!params.preferred_address->connection_id.IsEmpty()) {
- preferred_address_connection_id_and_token_ = std::make_pair(
- params.preferred_address->connection_id,
- *reinterpret_cast<const StatelessResetToken*>(
- &params.preferred_address->stateless_reset_token.front()));
- }
- }
- if (params.min_ack_delay_us.value() != 0) {
- if (params.min_ack_delay_us.value() >
- params.max_ack_delay.value() * kNumMicrosPerMilli) {
- *error_details = "MinAckDelay is greater than MaxAckDelay.";
- return IETF_QUIC_PROTOCOL_VIOLATION;
- }
- min_ack_delay_ms_.SetReceivedValue(params.min_ack_delay_us.value() /
- kNumMicrosPerMilli);
- }
- }
-
- if (params.disable_active_migration) {
- connection_migration_disabled_.SetReceivedValue(1u);
- }
-
- active_connection_id_limit_.SetReceivedValue(
- params.active_connection_id_limit.value());
-
- if (!is_resumption) {
- if (params.initial_source_connection_id.has_value()) {
- received_initial_source_connection_id_ =
- params.initial_source_connection_id.value();
- }
- if (params.retry_source_connection_id.has_value()) {
- received_retry_source_connection_id_ =
- params.retry_source_connection_id.value();
- }
- }
-
- if (params.initial_round_trip_time_us.value() > 0) {
- initial_round_trip_time_us_.SetReceivedValue(
- params.initial_round_trip_time_us.value());
- }
- if (params.google_connection_options.has_value()) {
- connection_options_.SetReceivedValues(
- params.google_connection_options.value());
- }
-
- received_custom_transport_parameters_ = params.custom_parameters;
-
- if (!is_resumption) {
- negotiated_ = true;
- }
- *error_details = "";
- return QUIC_NO_ERROR;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_config.h b/chromium/net/third_party/quiche/src/quic/core/quic_config.h
deleted file mode 100644
index cb8b4ecdf1e..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_config.h
+++ /dev/null
@@ -1,665 +0,0 @@
-// Copyright (c) 2013 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_CONFIG_H_
-#define QUICHE_QUIC_CORE_QUIC_CONFIG_H_
-
-#include <cstddef>
-#include <cstdint>
-#include <string>
-
-#include "absl/types/optional.h"
-#include "quic/core/crypto/transport_parameters.h"
-#include "quic/core/quic_connection_id.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_time.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-namespace test {
-class QuicConfigPeer;
-} // namespace test
-
-class CryptoHandshakeMessage;
-
-// Describes whether or not a given QuicTag is required or optional in the
-// handshake message.
-enum QuicConfigPresence : uint8_t {
- // This negotiable value can be absent from the handshake message. Default
- // value is selected as the negotiated value in such a case.
- PRESENCE_OPTIONAL,
- // This negotiable value is required in the handshake message otherwise the
- // Process*Hello function returns an error.
- PRESENCE_REQUIRED,
-};
-
-// Whether the CryptoHandshakeMessage is from the client or server.
-enum HelloType {
- CLIENT,
- SERVER,
-};
-
-// An abstract base class that stores a value that can be sent in CHLO/SHLO
-// message. These values can be OPTIONAL or REQUIRED, depending on |presence_|.
-class QUIC_EXPORT_PRIVATE QuicConfigValue {
- public:
- QuicConfigValue(QuicTag tag, QuicConfigPresence presence);
- virtual ~QuicConfigValue();
-
- // Serialises tag name and value(s) to |out|.
- virtual void ToHandshakeMessage(CryptoHandshakeMessage* out) const = 0;
-
- // Selects a mutually acceptable value from those offered in |peer_hello|
- // and those defined in the subclass.
- virtual QuicErrorCode ProcessPeerHello(
- const CryptoHandshakeMessage& peer_hello,
- HelloType hello_type,
- std::string* error_details) = 0;
-
- protected:
- const QuicTag tag_;
- const QuicConfigPresence presence_;
-};
-
-// Stores uint32_t from CHLO or SHLO messages that are not negotiated.
-class QUIC_EXPORT_PRIVATE QuicFixedUint32 : public QuicConfigValue {
- public:
- QuicFixedUint32(QuicTag tag, QuicConfigPresence presence);
- ~QuicFixedUint32() override;
-
- bool HasSendValue() const;
-
- uint32_t GetSendValue() const;
-
- void SetSendValue(uint32_t value);
-
- bool HasReceivedValue() const;
-
- uint32_t GetReceivedValue() const;
-
- void SetReceivedValue(uint32_t value);
-
- // If has_send_value is true, serialises |tag_| and |send_value_| to |out|.
- void ToHandshakeMessage(CryptoHandshakeMessage* out) const override;
-
- // Sets |value_| to the corresponding value from |peer_hello_| if it exists.
- QuicErrorCode ProcessPeerHello(const CryptoHandshakeMessage& peer_hello,
- HelloType hello_type,
- std::string* error_details) override;
-
- private:
- bool has_send_value_;
- bool has_receive_value_;
- uint32_t send_value_;
- uint32_t receive_value_;
-};
-
-// Stores 62bit numbers from handshake messages that unilaterally shared by each
-// endpoint. IMPORTANT: these are serialized as 32-bit unsigned integers when
-// using QUIC_CRYPTO versions and CryptoHandshakeMessage.
-class QUIC_EXPORT_PRIVATE QuicFixedUint62 : public QuicConfigValue {
- public:
- QuicFixedUint62(QuicTag name, QuicConfigPresence presence);
- ~QuicFixedUint62() override;
-
- bool HasSendValue() const;
-
- uint64_t GetSendValue() const;
-
- void SetSendValue(uint64_t value);
-
- bool HasReceivedValue() const;
-
- uint64_t GetReceivedValue() const;
-
- void SetReceivedValue(uint64_t value);
-
- // If has_send_value is true, serialises |tag_| and |send_value_| to |out|.
- // IMPORTANT: this method serializes |send_value_| as an unsigned 32bit
- // integer.
- void ToHandshakeMessage(CryptoHandshakeMessage* out) const override;
-
- // Sets |value_| to the corresponding value from |peer_hello_| if it exists.
- QuicErrorCode ProcessPeerHello(const CryptoHandshakeMessage& peer_hello,
- HelloType hello_type,
- std::string* error_details) override;
-
- private:
- bool has_send_value_;
- bool has_receive_value_;
- uint64_t send_value_;
- uint64_t receive_value_;
-};
-
-// Stores StatelessResetToken from CHLO or SHLO messages that are not
-// negotiated.
-class QUIC_EXPORT_PRIVATE QuicFixedStatelessResetToken
- : public QuicConfigValue {
- public:
- QuicFixedStatelessResetToken(QuicTag tag, QuicConfigPresence presence);
- ~QuicFixedStatelessResetToken() override;
-
- bool HasSendValue() const;
-
- const StatelessResetToken& GetSendValue() const;
-
- void SetSendValue(const StatelessResetToken& value);
-
- bool HasReceivedValue() const;
-
- const StatelessResetToken& GetReceivedValue() const;
-
- void SetReceivedValue(const StatelessResetToken& value);
-
- // If has_send_value is true, serialises |tag_| and |send_value_| to |out|.
- void ToHandshakeMessage(CryptoHandshakeMessage* out) const override;
-
- // Sets |value_| to the corresponding value from |peer_hello_| if it exists.
- QuicErrorCode ProcessPeerHello(const CryptoHandshakeMessage& peer_hello,
- HelloType hello_type,
- std::string* error_details) override;
-
- private:
- bool has_send_value_;
- bool has_receive_value_;
- StatelessResetToken send_value_;
- StatelessResetToken receive_value_;
-};
-
-// Stores tag from CHLO or SHLO messages that are not negotiated.
-class QUIC_EXPORT_PRIVATE QuicFixedTagVector : public QuicConfigValue {
- public:
- QuicFixedTagVector(QuicTag name, QuicConfigPresence presence);
- QuicFixedTagVector(const QuicFixedTagVector& other);
- ~QuicFixedTagVector() override;
-
- bool HasSendValues() const;
-
- const QuicTagVector& GetSendValues() const;
-
- void SetSendValues(const QuicTagVector& values);
-
- bool HasReceivedValues() const;
-
- const QuicTagVector& GetReceivedValues() const;
-
- void SetReceivedValues(const QuicTagVector& values);
-
- // If has_send_value is true, serialises |tag_vector_| and |send_value_| to
- // |out|.
- void ToHandshakeMessage(CryptoHandshakeMessage* out) const override;
-
- // Sets |receive_values_| to the corresponding value from |client_hello_| if
- // it exists.
- QuicErrorCode ProcessPeerHello(const CryptoHandshakeMessage& peer_hello,
- HelloType hello_type,
- std::string* error_details) override;
-
- private:
- bool has_send_values_;
- bool has_receive_values_;
- QuicTagVector send_values_;
- QuicTagVector receive_values_;
-};
-
-// Stores QuicSocketAddress from CHLO or SHLO messages that are not negotiated.
-class QUIC_EXPORT_PRIVATE QuicFixedSocketAddress : public QuicConfigValue {
- public:
- QuicFixedSocketAddress(QuicTag tag, QuicConfigPresence presence);
- ~QuicFixedSocketAddress() override;
-
- bool HasSendValue() const;
-
- const QuicSocketAddress& GetSendValue() const;
-
- void SetSendValue(const QuicSocketAddress& value);
-
- bool HasReceivedValue() const;
-
- const QuicSocketAddress& GetReceivedValue() const;
-
- void SetReceivedValue(const QuicSocketAddress& value);
-
- void ToHandshakeMessage(CryptoHandshakeMessage* out) const override;
-
- QuicErrorCode ProcessPeerHello(const CryptoHandshakeMessage& peer_hello,
- HelloType hello_type,
- std::string* error_details) override;
-
- private:
- bool has_send_value_;
- bool has_receive_value_;
- QuicSocketAddress send_value_;
- QuicSocketAddress receive_value_;
-};
-
-// QuicConfig contains non-crypto configuration options that are negotiated in
-// the crypto handshake.
-class QUIC_EXPORT_PRIVATE QuicConfig {
- public:
- QuicConfig();
- QuicConfig(const QuicConfig& other);
- ~QuicConfig();
-
- void SetConnectionOptionsToSend(const QuicTagVector& connection_options);
-
- bool HasReceivedConnectionOptions() const;
-
- // Sets initial received connection options. All received connection options
- // will be initialized with these fields. Initial received options may only be
- // set once per config, prior to the setting of any other options. If options
- // have already been set (either by previous calls or via handshake), this
- // function does nothing and returns false.
- bool SetInitialReceivedConnectionOptions(const QuicTagVector& tags);
-
- const QuicTagVector& ReceivedConnectionOptions() const;
-
- bool HasSendConnectionOptions() const;
-
- const QuicTagVector& SendConnectionOptions() const;
-
- // Returns true if the client is sending or the server has received a
- // connection option.
- // TODO(ianswett): Rename to HasClientRequestedSharedOption
- bool HasClientSentConnectionOption(QuicTag tag,
- Perspective perspective) const;
-
- void SetClientConnectionOptions(
- const QuicTagVector& client_connection_options);
-
- // Returns true if the client has requested the specified connection option.
- // Checks the client connection options if the |perspective| is client and
- // connection options if the |perspective| is the server.
- bool HasClientRequestedIndependentOption(QuicTag tag,
- Perspective perspective) const;
-
- const QuicTagVector& ClientRequestedIndependentOptions(
- Perspective perspective) const;
-
- void SetIdleNetworkTimeout(QuicTime::Delta idle_network_timeout);
-
- QuicTime::Delta IdleNetworkTimeout() const;
-
- // Sets the max bidirectional stream count that this endpoint supports.
- void SetMaxBidirectionalStreamsToSend(uint32_t max_streams);
- uint32_t GetMaxBidirectionalStreamsToSend() const;
-
- bool HasReceivedMaxBidirectionalStreams() const;
- // Gets the max bidirectional stream limit imposed by the peer.
- uint32_t ReceivedMaxBidirectionalStreams() const;
-
- // Sets the max unidirectional stream count that this endpoint supports.
- void SetMaxUnidirectionalStreamsToSend(uint32_t max_streams);
- uint32_t GetMaxUnidirectionalStreamsToSend() const;
-
- bool HasReceivedMaxUnidirectionalStreams() const;
- // Gets the max unidirectional stream limit imposed by the peer.
- uint32_t ReceivedMaxUnidirectionalStreams() const;
-
- void set_max_time_before_crypto_handshake(
- QuicTime::Delta max_time_before_crypto_handshake) {
- max_time_before_crypto_handshake_ = max_time_before_crypto_handshake;
- }
-
- QuicTime::Delta max_time_before_crypto_handshake() const {
- return max_time_before_crypto_handshake_;
- }
-
- void set_max_idle_time_before_crypto_handshake(
- QuicTime::Delta max_idle_time_before_crypto_handshake) {
- max_idle_time_before_crypto_handshake_ =
- max_idle_time_before_crypto_handshake;
- }
-
- QuicTime::Delta max_idle_time_before_crypto_handshake() const {
- return max_idle_time_before_crypto_handshake_;
- }
-
- void set_max_undecryptable_packets(size_t max_undecryptable_packets) {
- max_undecryptable_packets_ = max_undecryptable_packets;
- }
-
- size_t max_undecryptable_packets() const {
- return max_undecryptable_packets_;
- }
-
- // Peer's connection id length, in bytes. Only used in Q043 and Q046.
- bool HasSetBytesForConnectionIdToSend() const;
- void SetBytesForConnectionIdToSend(uint32_t bytes);
- bool HasReceivedBytesForConnectionId() const;
- uint32_t ReceivedBytesForConnectionId() const;
-
- // Estimated initial round trip time in us.
- void SetInitialRoundTripTimeUsToSend(uint64_t rtt_us);
- bool HasReceivedInitialRoundTripTimeUs() const;
- uint64_t ReceivedInitialRoundTripTimeUs() const;
- bool HasInitialRoundTripTimeUsToSend() const;
- uint64_t GetInitialRoundTripTimeUsToSend() const;
-
- // Sets an initial stream flow control window size to transmit to the peer.
- void SetInitialStreamFlowControlWindowToSend(uint64_t window_bytes);
- uint64_t GetInitialStreamFlowControlWindowToSend() const;
- bool HasReceivedInitialStreamFlowControlWindowBytes() const;
- uint64_t ReceivedInitialStreamFlowControlWindowBytes() const;
-
- // Specifies the initial flow control window (max stream data) for
- // incoming bidirectional streams. Incoming means streams initiated by our
- // peer. If not set, GetInitialMaxStreamDataBytesIncomingBidirectionalToSend
- // returns the value passed to SetInitialStreamFlowControlWindowToSend.
- void SetInitialMaxStreamDataBytesIncomingBidirectionalToSend(
- uint64_t window_bytes);
- uint64_t GetInitialMaxStreamDataBytesIncomingBidirectionalToSend() const;
- bool HasReceivedInitialMaxStreamDataBytesIncomingBidirectional() const;
- uint64_t ReceivedInitialMaxStreamDataBytesIncomingBidirectional() const;
-
- // Specifies the initial flow control window (max stream data) for
- // outgoing bidirectional streams. Outgoing means streams initiated by us.
- // If not set, GetInitialMaxStreamDataBytesOutgoingBidirectionalToSend
- // returns the value passed to SetInitialStreamFlowControlWindowToSend.
- void SetInitialMaxStreamDataBytesOutgoingBidirectionalToSend(
- uint64_t window_bytes);
- uint64_t GetInitialMaxStreamDataBytesOutgoingBidirectionalToSend() const;
- bool HasReceivedInitialMaxStreamDataBytesOutgoingBidirectional() const;
- uint64_t ReceivedInitialMaxStreamDataBytesOutgoingBidirectional() const;
-
- // Specifies the initial flow control window (max stream data) for
- // unidirectional streams. If not set,
- // GetInitialMaxStreamDataBytesUnidirectionalToSend returns the value passed
- // to SetInitialStreamFlowControlWindowToSend.
- void SetInitialMaxStreamDataBytesUnidirectionalToSend(uint64_t window_bytes);
- uint64_t GetInitialMaxStreamDataBytesUnidirectionalToSend() const;
- bool HasReceivedInitialMaxStreamDataBytesUnidirectional() const;
- uint64_t ReceivedInitialMaxStreamDataBytesUnidirectional() const;
-
- // Sets an initial session flow control window size to transmit to the peer.
- void SetInitialSessionFlowControlWindowToSend(uint64_t window_bytes);
- uint64_t GetInitialSessionFlowControlWindowToSend() const;
- bool HasReceivedInitialSessionFlowControlWindowBytes() const;
- uint64_t ReceivedInitialSessionFlowControlWindowBytes() const;
-
- // Disable connection migration.
- void SetDisableConnectionMigration();
- bool DisableConnectionMigration() const;
-
- // IPv6 alternate server address.
- void SetIPv6AlternateServerAddressToSend(
- const QuicSocketAddress& alternate_server_address_ipv6);
- void SetIPv6AlternateServerAddressToSend(
- const QuicSocketAddress& alternate_server_address_ipv6,
- const QuicConnectionId& connection_id,
- const StatelessResetToken& stateless_reset_token);
- bool HasReceivedIPv6AlternateServerAddress() const;
- const QuicSocketAddress& ReceivedIPv6AlternateServerAddress() const;
-
- // IPv4 alternate server address.
- void SetIPv4AlternateServerAddressToSend(
- const QuicSocketAddress& alternate_server_address_ipv4);
- void SetIPv4AlternateServerAddressToSend(
- const QuicSocketAddress& alternate_server_address_ipv4,
- const QuicConnectionId& connection_id,
- const StatelessResetToken& stateless_reset_token);
- bool HasReceivedIPv4AlternateServerAddress() const;
- const QuicSocketAddress& ReceivedIPv4AlternateServerAddress() const;
-
- // Preferred Address Connection ID and Token.
- bool HasReceivedPreferredAddressConnectionIdAndToken() const;
- const std::pair<QuicConnectionId, StatelessResetToken>&
- ReceivedPreferredAddressConnectionIdAndToken() const;
-
- // Original destination connection ID.
- void SetOriginalConnectionIdToSend(
- const QuicConnectionId& original_destination_connection_id);
- bool HasReceivedOriginalConnectionId() const;
- QuicConnectionId ReceivedOriginalConnectionId() const;
-
- // Stateless reset token.
- void SetStatelessResetTokenToSend(
- const StatelessResetToken& stateless_reset_token);
- bool HasReceivedStatelessResetToken() const;
- const StatelessResetToken& ReceivedStatelessResetToken() const;
-
- // Manage the IETF QUIC Max ACK Delay transport parameter.
- // The sent value is the delay that this node uses
- // (QuicSentPacketManager::local_max_ack_delay_).
- // The received delay is the value received from
- // the peer (QuicSentPacketManager::peer_max_ack_delay_).
- void SetMaxAckDelayToSendMs(uint32_t max_ack_delay_ms);
- uint32_t GetMaxAckDelayToSendMs() const;
- bool HasReceivedMaxAckDelayMs() const;
- uint32_t ReceivedMaxAckDelayMs() const;
-
- // Manage the IETF QUIC extension Min Ack Delay transport parameter.
- // An endpoint uses min_ack_delay to advsertise its support for
- // AckFrequencyFrame sent by peer.
- void SetMinAckDelayMs(uint32_t min_ack_delay_ms);
- uint32_t GetMinAckDelayToSendMs() const;
- bool HasReceivedMinAckDelayMs() const;
- uint32_t ReceivedMinAckDelayMs() const;
-
- void SetAckDelayExponentToSend(uint32_t exponent);
- uint32_t GetAckDelayExponentToSend() const;
- bool HasReceivedAckDelayExponent() const;
- uint32_t ReceivedAckDelayExponent() const;
-
- // IETF QUIC max_udp_payload_size transport parameter.
- void SetMaxPacketSizeToSend(uint64_t max_udp_payload_size);
- uint64_t GetMaxPacketSizeToSend() const;
- bool HasReceivedMaxPacketSize() const;
- uint64_t ReceivedMaxPacketSize() const;
-
- // IETF QUIC max_datagram_frame_size transport parameter.
- void SetMaxDatagramFrameSizeToSend(uint64_t max_datagram_frame_size);
- uint64_t GetMaxDatagramFrameSizeToSend() const;
- bool HasReceivedMaxDatagramFrameSize() const;
- uint64_t ReceivedMaxDatagramFrameSize() const;
-
- // IETF QUIC active_connection_id_limit transport parameter.
- void SetActiveConnectionIdLimitToSend(uint64_t active_connection_id_limit);
- uint64_t GetActiveConnectionIdLimitToSend() const;
- bool HasReceivedActiveConnectionIdLimit() const;
- uint64_t ReceivedActiveConnectionIdLimit() const;
-
- // Initial source connection ID.
- void SetInitialSourceConnectionIdToSend(
- const QuicConnectionId& initial_source_connection_id);
- bool HasReceivedInitialSourceConnectionId() const;
- QuicConnectionId ReceivedInitialSourceConnectionId() const;
-
- // Retry source connection ID.
- void SetRetrySourceConnectionIdToSend(
- const QuicConnectionId& retry_source_connection_id);
- bool HasReceivedRetrySourceConnectionId() const;
- QuicConnectionId ReceivedRetrySourceConnectionId() const;
-
- bool negotiated() const;
-
- void SetCreateSessionTagIndicators(QuicTagVector tags);
-
- const QuicTagVector& create_session_tag_indicators() const;
-
- // ToHandshakeMessage serialises the settings in this object as a series of
- // tags /value pairs and adds them to |out|.
- void ToHandshakeMessage(CryptoHandshakeMessage* out,
- QuicTransportVersion transport_version) const;
-
- // Calls ProcessPeerHello on each negotiable parameter. On failure returns
- // the corresponding QuicErrorCode and sets detailed error in |error_details|.
- QuicErrorCode ProcessPeerHello(const CryptoHandshakeMessage& peer_hello,
- HelloType hello_type,
- std::string* error_details);
-
- // FillTransportParameters writes the values to send for ICSL, MIDS, CFCW, and
- // SFCW to |*params|, returning true if the values could be written and false
- // if something prevents them from being written (e.g. a value is too large).
- bool FillTransportParameters(TransportParameters* params) const;
-
- // ProcessTransportParameters reads from |params| which were received from a
- // peer. If |is_resumption|, some configs will not be processed.
- // On failure, it returns a QuicErrorCode and puts a detailed error in
- // |*error_details|.
- QuicErrorCode ProcessTransportParameters(const TransportParameters& params,
- bool is_resumption,
- std::string* error_details);
-
- TransportParameters::ParameterMap& custom_transport_parameters_to_send() {
- return custom_transport_parameters_to_send_;
- }
- const TransportParameters::ParameterMap&
- received_custom_transport_parameters() const {
- return received_custom_transport_parameters_;
- }
-
- private:
- friend class test::QuicConfigPeer;
-
- // SetDefaults sets the members to sensible, default values.
- void SetDefaults();
-
- // Whether we've received the peer's config.
- bool negotiated_;
-
- // Configurations options that are not negotiated.
- // Maximum time the session can be alive before crypto handshake is finished.
- QuicTime::Delta max_time_before_crypto_handshake_;
- // Maximum idle time before the crypto handshake has completed.
- QuicTime::Delta max_idle_time_before_crypto_handshake_;
- // Maximum number of undecryptable packets stored before CHLO/SHLO.
- size_t max_undecryptable_packets_;
-
- // Connection options which affect the server side. May also affect the
- // client side in cases when identical behavior is desirable.
- QuicFixedTagVector connection_options_;
- // Connection options which only affect the client side.
- QuicFixedTagVector client_connection_options_;
- // Maximum idle network timeout.
- // Uses the max_idle_timeout transport parameter in IETF QUIC.
- // Note that received_max_idle_timeout_ is only populated if we receive the
- // peer's value, which isn't guaranteed in IETF QUIC as sending is optional.
- QuicTime::Delta max_idle_timeout_to_send_;
- absl::optional<QuicTime::Delta> received_max_idle_timeout_;
- // Maximum number of dynamic streams that a Google QUIC connection
- // can support or the maximum number of bidirectional streams that
- // an IETF QUIC connection can support.
- // The SendValue is the limit on peer-created streams that this endpoint is
- // advertising.
- // The ReceivedValue is the limit on locally-created streams that
- // the peer advertised.
- // Uses the initial_max_streams_bidi transport parameter in IETF QUIC.
- QuicFixedUint32 max_bidirectional_streams_;
- // Maximum number of unidirectional streams that the connection can
- // support.
- // The SendValue is the limit on peer-created streams that this endpoint is
- // advertising.
- // The ReceivedValue is the limit on locally-created streams that the peer
- // advertised.
- // Uses the initial_max_streams_uni transport parameter in IETF QUIC.
- QuicFixedUint32 max_unidirectional_streams_;
- // The number of bytes required for the connection ID. This is only used in
- // the legacy header format used only by Q043 at this point.
- QuicFixedUint32 bytes_for_connection_id_;
- // Initial round trip time estimate in microseconds.
- QuicFixedUint62 initial_round_trip_time_us_;
-
- // Initial IETF QUIC stream flow control receive windows in bytes.
- // Incoming bidirectional streams.
- // Uses the initial_max_stream_data_bidi_{local,remote} transport parameter
- // in IETF QUIC, depending on whether we're sending or receiving.
- QuicFixedUint62 initial_max_stream_data_bytes_incoming_bidirectional_;
- // Outgoing bidirectional streams.
- // Uses the initial_max_stream_data_bidi_{local,remote} transport parameter
- // in IETF QUIC, depending on whether we're sending or receiving.
- QuicFixedUint62 initial_max_stream_data_bytes_outgoing_bidirectional_;
- // Unidirectional streams.
- // Uses the initial_max_stream_data_uni transport parameter in IETF QUIC.
- QuicFixedUint62 initial_max_stream_data_bytes_unidirectional_;
-
- // Initial Google QUIC stream flow control receive window in bytes.
- QuicFixedUint62 initial_stream_flow_control_window_bytes_;
-
- // Initial session flow control receive window in bytes.
- // Uses the initial_max_data transport parameter in IETF QUIC.
- QuicFixedUint62 initial_session_flow_control_window_bytes_;
-
- // Whether active connection migration is allowed.
- // Uses the disable_active_migration transport parameter in IETF QUIC.
- QuicFixedUint32 connection_migration_disabled_;
-
- // Alternate server addresses the client could connect to.
- // Uses the preferred_address transport parameter in IETF QUIC.
- // Note that when QUIC_CRYPTO is in use, only one of the addresses is sent.
- QuicFixedSocketAddress alternate_server_address_ipv6_;
- QuicFixedSocketAddress alternate_server_address_ipv4_;
- // Connection Id data to send from the server or receive at the client as part
- // of the preferred address transport parameter.
- absl::optional<std::pair<QuicConnectionId, StatelessResetToken>>
- preferred_address_connection_id_and_token_;
-
- // Stateless reset token used in IETF public reset packet.
- // Uses the stateless_reset_token transport parameter in IETF QUIC.
- QuicFixedStatelessResetToken stateless_reset_token_;
-
- // List of QuicTags whose presence immediately causes the session to
- // be created. This allows for CHLOs that are larger than a single
- // packet to be processed.
- QuicTagVector create_session_tag_indicators_;
-
- // Maximum ack delay. The sent value is the value used on this node.
- // The received value is the value received from the peer and used by
- // the peer.
- // Uses the max_ack_delay transport parameter in IETF QUIC.
- QuicFixedUint32 max_ack_delay_ms_;
-
- // Minimum ack delay. Used to enable sender control of max_ack_delay.
- // Uses the min_ack_delay transport parameter in IETF QUIC extension.
- QuicFixedUint32 min_ack_delay_ms_;
-
- // The sent exponent is the exponent that this node uses when serializing an
- // ACK frame (and the peer should use when deserializing the frame);
- // the received exponent is the value the peer uses to serialize frames and
- // this node uses to deserialize them.
- // Uses the ack_delay_exponent transport parameter in IETF QUIC.
- QuicFixedUint32 ack_delay_exponent_;
-
- // Maximum packet size in bytes.
- // Uses the max_udp_payload_size transport parameter in IETF QUIC.
- QuicFixedUint62 max_udp_payload_size_;
-
- // Maximum DATAGRAM/MESSAGE frame size in bytes.
- // Uses the max_datagram_frame_size transport parameter in IETF QUIC.
- QuicFixedUint62 max_datagram_frame_size_;
-
- // Maximum number of connection IDs from the peer.
- // Uses the active_connection_id_limit transport parameter in IETF QUIC.
- QuicFixedUint62 active_connection_id_limit_;
-
- // The value of the Destination Connection ID field from the first
- // Initial packet sent by the client.
- // Uses the original_destination_connection_id transport parameter in
- // IETF QUIC.
- absl::optional<QuicConnectionId> original_destination_connection_id_to_send_;
- absl::optional<QuicConnectionId> received_original_destination_connection_id_;
-
- // The value that the endpoint included in the Source Connection ID field of
- // the first Initial packet it sent.
- // Uses the initial_source_connection_id transport parameter in IETF QUIC.
- absl::optional<QuicConnectionId> initial_source_connection_id_to_send_;
- absl::optional<QuicConnectionId> received_initial_source_connection_id_;
-
- // The value that the server included in the Source Connection ID field of a
- // Retry packet it sent.
- // Uses the retry_source_connection_id transport parameter in IETF QUIC.
- absl::optional<QuicConnectionId> retry_source_connection_id_to_send_;
- absl::optional<QuicConnectionId> received_retry_source_connection_id_;
-
- // Custom transport parameters that can be sent and received in the TLS
- // handshake.
- TransportParameters::ParameterMap custom_transport_parameters_to_send_;
- TransportParameters::ParameterMap received_custom_transport_parameters_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_QUIC_CONFIG_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_config_test.cc b/chromium/net/third_party/quiche/src/quic/core/quic_config_test.cc
deleted file mode 100644
index e53d429030e..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_config_test.cc
+++ /dev/null
@@ -1,727 +0,0 @@
-// Copyright (c) 2013 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 "quic/core/quic_config.h"
-
-#include <memory>
-#include <string>
-
-#include "quic/core/crypto/crypto_handshake_message.h"
-#include "quic/core/crypto/crypto_protocol.h"
-#include "quic/core/crypto/transport_parameters.h"
-#include "quic/core/quic_constants.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_time.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_expect_bug.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/quic_config_peer.h"
-#include "quic/test_tools/quic_test_utils.h"
-
-namespace quic {
-namespace test {
-namespace {
-
-class QuicConfigTest : public QuicTestWithParam<ParsedQuicVersion> {
- public:
- QuicConfigTest() : version_(GetParam()) {}
-
- protected:
- ParsedQuicVersion version_;
- QuicConfig config_;
-};
-
-// Run all tests with all versions of QUIC.
-INSTANTIATE_TEST_SUITE_P(QuicConfigTests,
- QuicConfigTest,
- ::testing::ValuesIn(AllSupportedVersions()),
- ::testing::PrintToStringParamName());
-
-TEST_P(QuicConfigTest, SetDefaults) {
- EXPECT_EQ(kMinimumFlowControlSendWindow,
- config_.GetInitialStreamFlowControlWindowToSend());
- EXPECT_EQ(kMinimumFlowControlSendWindow,
- config_.GetInitialMaxStreamDataBytesIncomingBidirectionalToSend());
- EXPECT_EQ(kMinimumFlowControlSendWindow,
- config_.GetInitialMaxStreamDataBytesOutgoingBidirectionalToSend());
- EXPECT_EQ(kMinimumFlowControlSendWindow,
- config_.GetInitialMaxStreamDataBytesUnidirectionalToSend());
- EXPECT_FALSE(config_.HasReceivedInitialStreamFlowControlWindowBytes());
- EXPECT_FALSE(
- config_.HasReceivedInitialMaxStreamDataBytesIncomingBidirectional());
- EXPECT_FALSE(
- config_.HasReceivedInitialMaxStreamDataBytesOutgoingBidirectional());
- EXPECT_FALSE(config_.HasReceivedInitialMaxStreamDataBytesUnidirectional());
- EXPECT_EQ(kMaxIncomingPacketSize, config_.GetMaxPacketSizeToSend());
- EXPECT_FALSE(config_.HasReceivedMaxPacketSize());
-}
-
-TEST_P(QuicConfigTest, AutoSetIetfFlowControl) {
- EXPECT_EQ(kMinimumFlowControlSendWindow,
- config_.GetInitialStreamFlowControlWindowToSend());
- EXPECT_EQ(kMinimumFlowControlSendWindow,
- config_.GetInitialMaxStreamDataBytesIncomingBidirectionalToSend());
- EXPECT_EQ(kMinimumFlowControlSendWindow,
- config_.GetInitialMaxStreamDataBytesOutgoingBidirectionalToSend());
- EXPECT_EQ(kMinimumFlowControlSendWindow,
- config_.GetInitialMaxStreamDataBytesUnidirectionalToSend());
- static const uint32_t kTestWindowSize = 1234567;
- config_.SetInitialStreamFlowControlWindowToSend(kTestWindowSize);
- EXPECT_EQ(kTestWindowSize, config_.GetInitialStreamFlowControlWindowToSend());
- EXPECT_EQ(kTestWindowSize,
- config_.GetInitialMaxStreamDataBytesIncomingBidirectionalToSend());
- EXPECT_EQ(kTestWindowSize,
- config_.GetInitialMaxStreamDataBytesOutgoingBidirectionalToSend());
- EXPECT_EQ(kTestWindowSize,
- config_.GetInitialMaxStreamDataBytesUnidirectionalToSend());
- static const uint32_t kTestWindowSizeTwo = 2345678;
- config_.SetInitialMaxStreamDataBytesIncomingBidirectionalToSend(
- kTestWindowSizeTwo);
- EXPECT_EQ(kTestWindowSize, config_.GetInitialStreamFlowControlWindowToSend());
- EXPECT_EQ(kTestWindowSizeTwo,
- config_.GetInitialMaxStreamDataBytesIncomingBidirectionalToSend());
- EXPECT_EQ(kTestWindowSize,
- config_.GetInitialMaxStreamDataBytesOutgoingBidirectionalToSend());
- EXPECT_EQ(kTestWindowSize,
- config_.GetInitialMaxStreamDataBytesUnidirectionalToSend());
-}
-
-TEST_P(QuicConfigTest, ToHandshakeMessage) {
- if (version_.UsesTls()) {
- // CryptoHandshakeMessage is only used for QUIC_CRYPTO.
- return;
- }
- config_.SetInitialStreamFlowControlWindowToSend(
- kInitialStreamFlowControlWindowForTest);
- config_.SetInitialSessionFlowControlWindowToSend(
- kInitialSessionFlowControlWindowForTest);
- config_.SetIdleNetworkTimeout(QuicTime::Delta::FromSeconds(5));
- CryptoHandshakeMessage msg;
- config_.ToHandshakeMessage(&msg, version_.transport_version);
-
- uint32_t value;
- QuicErrorCode error = msg.GetUint32(kICSL, &value);
- EXPECT_THAT(error, IsQuicNoError());
- EXPECT_EQ(5u, value);
-
- error = msg.GetUint32(kSFCW, &value);
- EXPECT_THAT(error, IsQuicNoError());
- EXPECT_EQ(kInitialStreamFlowControlWindowForTest, value);
-
- error = msg.GetUint32(kCFCW, &value);
- EXPECT_THAT(error, IsQuicNoError());
- EXPECT_EQ(kInitialSessionFlowControlWindowForTest, value);
-}
-
-TEST_P(QuicConfigTest, ProcessClientHello) {
- if (version_.UsesTls()) {
- // CryptoHandshakeMessage is only used for QUIC_CRYPTO.
- return;
- }
- const uint32_t kTestMaxAckDelayMs =
- static_cast<uint32_t>(kDefaultDelayedAckTimeMs + 1);
- QuicConfig client_config;
- QuicTagVector cgst;
- cgst.push_back(kQBIC);
- client_config.SetIdleNetworkTimeout(
- QuicTime::Delta::FromSeconds(2 * kMaximumIdleTimeoutSecs));
- client_config.SetInitialRoundTripTimeUsToSend(10 * kNumMicrosPerMilli);
- client_config.SetInitialStreamFlowControlWindowToSend(
- 2 * kInitialStreamFlowControlWindowForTest);
- client_config.SetInitialSessionFlowControlWindowToSend(
- 2 * kInitialSessionFlowControlWindowForTest);
- QuicTagVector copt;
- copt.push_back(kTBBR);
- client_config.SetConnectionOptionsToSend(copt);
- client_config.SetMaxAckDelayToSendMs(kTestMaxAckDelayMs);
- CryptoHandshakeMessage msg;
- client_config.ToHandshakeMessage(&msg, version_.transport_version);
-
- std::string error_details;
- QuicTagVector initial_received_options;
- initial_received_options.push_back(kIW50);
- EXPECT_TRUE(
- config_.SetInitialReceivedConnectionOptions(initial_received_options));
- EXPECT_FALSE(
- config_.SetInitialReceivedConnectionOptions(initial_received_options))
- << "You can only set initial options once.";
- const QuicErrorCode error =
- config_.ProcessPeerHello(msg, CLIENT, &error_details);
- EXPECT_FALSE(
- config_.SetInitialReceivedConnectionOptions(initial_received_options))
- << "You cannot set initial options after the hello.";
- EXPECT_THAT(error, IsQuicNoError());
- EXPECT_TRUE(config_.negotiated());
- EXPECT_EQ(QuicTime::Delta::FromSeconds(kMaximumIdleTimeoutSecs),
- config_.IdleNetworkTimeout());
- EXPECT_EQ(10 * kNumMicrosPerMilli, config_.ReceivedInitialRoundTripTimeUs());
- EXPECT_TRUE(config_.HasReceivedConnectionOptions());
- EXPECT_EQ(2u, config_.ReceivedConnectionOptions().size());
- EXPECT_EQ(config_.ReceivedConnectionOptions()[0], kIW50);
- EXPECT_EQ(config_.ReceivedConnectionOptions()[1], kTBBR);
- EXPECT_EQ(config_.ReceivedInitialStreamFlowControlWindowBytes(),
- 2 * kInitialStreamFlowControlWindowForTest);
- EXPECT_EQ(config_.ReceivedInitialSessionFlowControlWindowBytes(),
- 2 * kInitialSessionFlowControlWindowForTest);
- EXPECT_TRUE(config_.HasReceivedMaxAckDelayMs());
- EXPECT_EQ(kTestMaxAckDelayMs, config_.ReceivedMaxAckDelayMs());
-
- // IETF QUIC stream limits should not be received in QUIC crypto messages.
- EXPECT_FALSE(
- config_.HasReceivedInitialMaxStreamDataBytesIncomingBidirectional());
- EXPECT_FALSE(
- config_.HasReceivedInitialMaxStreamDataBytesOutgoingBidirectional());
- EXPECT_FALSE(config_.HasReceivedInitialMaxStreamDataBytesUnidirectional());
-}
-
-TEST_P(QuicConfigTest, ProcessServerHello) {
- if (version_.UsesTls()) {
- // CryptoHandshakeMessage is only used for QUIC_CRYPTO.
- return;
- }
- QuicIpAddress host;
- host.FromString("127.0.3.1");
- const QuicSocketAddress kTestServerAddress = QuicSocketAddress(host, 1234);
- const StatelessResetToken kTestStatelessResetToken{
- 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
- 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f};
- const uint32_t kTestMaxAckDelayMs =
- static_cast<uint32_t>(kDefaultDelayedAckTimeMs + 1);
- QuicConfig server_config;
- QuicTagVector cgst;
- cgst.push_back(kQBIC);
- server_config.SetIdleNetworkTimeout(
- QuicTime::Delta::FromSeconds(kMaximumIdleTimeoutSecs / 2));
- server_config.SetInitialRoundTripTimeUsToSend(10 * kNumMicrosPerMilli);
- server_config.SetInitialStreamFlowControlWindowToSend(
- 2 * kInitialStreamFlowControlWindowForTest);
- server_config.SetInitialSessionFlowControlWindowToSend(
- 2 * kInitialSessionFlowControlWindowForTest);
- server_config.SetIPv4AlternateServerAddressToSend(kTestServerAddress);
- server_config.SetStatelessResetTokenToSend(kTestStatelessResetToken);
- server_config.SetMaxAckDelayToSendMs(kTestMaxAckDelayMs);
- CryptoHandshakeMessage msg;
- server_config.ToHandshakeMessage(&msg, version_.transport_version);
- std::string error_details;
- const QuicErrorCode error =
- config_.ProcessPeerHello(msg, SERVER, &error_details);
- EXPECT_THAT(error, IsQuicNoError());
- EXPECT_TRUE(config_.negotiated());
- EXPECT_EQ(QuicTime::Delta::FromSeconds(kMaximumIdleTimeoutSecs / 2),
- config_.IdleNetworkTimeout());
- EXPECT_EQ(10 * kNumMicrosPerMilli, config_.ReceivedInitialRoundTripTimeUs());
- EXPECT_EQ(config_.ReceivedInitialStreamFlowControlWindowBytes(),
- 2 * kInitialStreamFlowControlWindowForTest);
- EXPECT_EQ(config_.ReceivedInitialSessionFlowControlWindowBytes(),
- 2 * kInitialSessionFlowControlWindowForTest);
- EXPECT_TRUE(config_.HasReceivedIPv4AlternateServerAddress());
- EXPECT_EQ(kTestServerAddress, config_.ReceivedIPv4AlternateServerAddress());
- EXPECT_FALSE(config_.HasReceivedIPv6AlternateServerAddress());
- EXPECT_TRUE(config_.HasReceivedStatelessResetToken());
- EXPECT_EQ(kTestStatelessResetToken, config_.ReceivedStatelessResetToken());
- EXPECT_TRUE(config_.HasReceivedMaxAckDelayMs());
- EXPECT_EQ(kTestMaxAckDelayMs, config_.ReceivedMaxAckDelayMs());
-
- // IETF QUIC stream limits should not be received in QUIC crypto messages.
- EXPECT_FALSE(
- config_.HasReceivedInitialMaxStreamDataBytesIncomingBidirectional());
- EXPECT_FALSE(
- config_.HasReceivedInitialMaxStreamDataBytesOutgoingBidirectional());
- EXPECT_FALSE(config_.HasReceivedInitialMaxStreamDataBytesUnidirectional());
-}
-
-TEST_P(QuicConfigTest, MissingOptionalValuesInCHLO) {
- if (version_.UsesTls()) {
- // CryptoHandshakeMessage is only used for QUIC_CRYPTO.
- return;
- }
- CryptoHandshakeMessage msg;
- msg.SetValue(kICSL, 1);
-
- // Set all REQUIRED tags.
- msg.SetValue(kICSL, 1);
- msg.SetValue(kMIBS, 1);
-
- // No error, as rest are optional.
- std::string error_details;
- const QuicErrorCode error =
- config_.ProcessPeerHello(msg, CLIENT, &error_details);
- EXPECT_THAT(error, IsQuicNoError());
- EXPECT_TRUE(config_.negotiated());
-}
-
-TEST_P(QuicConfigTest, MissingOptionalValuesInSHLO) {
- if (version_.UsesTls()) {
- // CryptoHandshakeMessage is only used for QUIC_CRYPTO.
- return;
- }
- CryptoHandshakeMessage msg;
-
- // Set all REQUIRED tags.
- msg.SetValue(kICSL, 1);
- msg.SetValue(kMIBS, 1);
-
- // No error, as rest are optional.
- std::string error_details;
- const QuicErrorCode error =
- config_.ProcessPeerHello(msg, SERVER, &error_details);
- EXPECT_THAT(error, IsQuicNoError());
- EXPECT_TRUE(config_.negotiated());
-}
-
-TEST_P(QuicConfigTest, MissingValueInCHLO) {
- if (version_.UsesTls()) {
- // CryptoHandshakeMessage is only used for QUIC_CRYPTO.
- return;
- }
- // Server receives CHLO with missing kICSL.
- CryptoHandshakeMessage msg;
- std::string error_details;
- const QuicErrorCode error =
- config_.ProcessPeerHello(msg, CLIENT, &error_details);
- EXPECT_THAT(error, IsError(QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND));
-}
-
-TEST_P(QuicConfigTest, MissingValueInSHLO) {
- if (version_.UsesTls()) {
- // CryptoHandshakeMessage is only used for QUIC_CRYPTO.
- return;
- }
- // Client receives SHLO with missing kICSL.
- CryptoHandshakeMessage msg;
- std::string error_details;
- const QuicErrorCode error =
- config_.ProcessPeerHello(msg, SERVER, &error_details);
- EXPECT_THAT(error, IsError(QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND));
-}
-
-TEST_P(QuicConfigTest, OutOfBoundSHLO) {
- if (version_.UsesTls()) {
- // CryptoHandshakeMessage is only used for QUIC_CRYPTO.
- return;
- }
- QuicConfig server_config;
- server_config.SetIdleNetworkTimeout(
- QuicTime::Delta::FromSeconds(2 * kMaximumIdleTimeoutSecs));
-
- CryptoHandshakeMessage msg;
- server_config.ToHandshakeMessage(&msg, version_.transport_version);
- std::string error_details;
- const QuicErrorCode error =
- config_.ProcessPeerHello(msg, SERVER, &error_details);
- EXPECT_THAT(error, IsError(QUIC_INVALID_NEGOTIATED_VALUE));
-}
-
-TEST_P(QuicConfigTest, InvalidFlowControlWindow) {
- // QuicConfig should not accept an invalid flow control window to send to the
- // peer: the receive window must be at least the default of 16 Kb.
- QuicConfig config;
- const uint64_t kInvalidWindow = kMinimumFlowControlSendWindow - 1;
- EXPECT_QUIC_BUG(
- config.SetInitialStreamFlowControlWindowToSend(kInvalidWindow),
- "Initial stream flow control receive window");
-
- EXPECT_EQ(kMinimumFlowControlSendWindow,
- config.GetInitialStreamFlowControlWindowToSend());
-}
-
-TEST_P(QuicConfigTest, HasClientSentConnectionOption) {
- if (version_.UsesTls()) {
- // CryptoHandshakeMessage is only used for QUIC_CRYPTO.
- return;
- }
- QuicConfig client_config;
- QuicTagVector copt;
- copt.push_back(kTBBR);
- client_config.SetConnectionOptionsToSend(copt);
- EXPECT_TRUE(client_config.HasClientSentConnectionOption(
- kTBBR, Perspective::IS_CLIENT));
-
- CryptoHandshakeMessage msg;
- client_config.ToHandshakeMessage(&msg, version_.transport_version);
-
- std::string error_details;
- const QuicErrorCode error =
- config_.ProcessPeerHello(msg, CLIENT, &error_details);
- EXPECT_THAT(error, IsQuicNoError());
- EXPECT_TRUE(config_.negotiated());
-
- EXPECT_TRUE(config_.HasReceivedConnectionOptions());
- EXPECT_EQ(1u, config_.ReceivedConnectionOptions().size());
- EXPECT_TRUE(
- config_.HasClientSentConnectionOption(kTBBR, Perspective::IS_SERVER));
-}
-
-TEST_P(QuicConfigTest, DontSendClientConnectionOptions) {
- if (version_.UsesTls()) {
- // CryptoHandshakeMessage is only used for QUIC_CRYPTO.
- return;
- }
- QuicConfig client_config;
- QuicTagVector copt;
- copt.push_back(kTBBR);
- client_config.SetClientConnectionOptions(copt);
-
- CryptoHandshakeMessage msg;
- client_config.ToHandshakeMessage(&msg, version_.transport_version);
-
- std::string error_details;
- const QuicErrorCode error =
- config_.ProcessPeerHello(msg, CLIENT, &error_details);
- EXPECT_THAT(error, IsQuicNoError());
- EXPECT_TRUE(config_.negotiated());
-
- EXPECT_FALSE(config_.HasReceivedConnectionOptions());
-}
-
-TEST_P(QuicConfigTest, HasClientRequestedIndependentOption) {
- if (version_.UsesTls()) {
- // CryptoHandshakeMessage is only used for QUIC_CRYPTO.
- return;
- }
- QuicConfig client_config;
- QuicTagVector client_opt;
- client_opt.push_back(kRENO);
- QuicTagVector copt;
- copt.push_back(kTBBR);
- client_config.SetClientConnectionOptions(client_opt);
- client_config.SetConnectionOptionsToSend(copt);
- EXPECT_TRUE(client_config.HasClientSentConnectionOption(
- kTBBR, Perspective::IS_CLIENT));
- EXPECT_TRUE(client_config.HasClientRequestedIndependentOption(
- kRENO, Perspective::IS_CLIENT));
- EXPECT_FALSE(client_config.HasClientRequestedIndependentOption(
- kTBBR, Perspective::IS_CLIENT));
-
- CryptoHandshakeMessage msg;
- client_config.ToHandshakeMessage(&msg, version_.transport_version);
-
- std::string error_details;
- const QuicErrorCode error =
- config_.ProcessPeerHello(msg, CLIENT, &error_details);
- EXPECT_THAT(error, IsQuicNoError());
- EXPECT_TRUE(config_.negotiated());
-
- EXPECT_TRUE(config_.HasReceivedConnectionOptions());
- EXPECT_EQ(1u, config_.ReceivedConnectionOptions().size());
- EXPECT_FALSE(config_.HasClientRequestedIndependentOption(
- kRENO, Perspective::IS_SERVER));
- EXPECT_TRUE(config_.HasClientRequestedIndependentOption(
- kTBBR, Perspective::IS_SERVER));
-}
-
-TEST_P(QuicConfigTest, IncomingLargeIdleTimeoutTransportParameter) {
- if (!version_.UsesTls()) {
- // TransportParameters are only used for QUIC+TLS.
- return;
- }
- // Configure our idle timeout to 60s, then receive 120s from peer.
- // Since the received value is above ours, we should then use ours.
- config_.SetIdleNetworkTimeout(quic::QuicTime::Delta::FromSeconds(60));
- TransportParameters params;
- params.max_idle_timeout_ms.set_value(120000);
-
- std::string error_details = "foobar";
- EXPECT_THAT(config_.ProcessTransportParameters(
- params, /* is_resumption = */ false, &error_details),
- IsQuicNoError());
- EXPECT_EQ("", error_details);
- EXPECT_EQ(quic::QuicTime::Delta::FromSeconds(60),
- config_.IdleNetworkTimeout());
-}
-
-TEST_P(QuicConfigTest, ReceivedInvalidMinAckDelayInTransportParameter) {
- if (!version_.UsesTls()) {
- // TransportParameters are only used for QUIC+TLS.
- return;
- }
- TransportParameters params;
-
- params.max_ack_delay.set_value(25 /*ms*/);
- params.min_ack_delay_us.set_value(25 * kNumMicrosPerMilli + 1);
- std::string error_details = "foobar";
- EXPECT_THAT(config_.ProcessTransportParameters(
- params, /* is_resumption = */ false, &error_details),
- IsError(IETF_QUIC_PROTOCOL_VIOLATION));
- EXPECT_EQ("MinAckDelay is greater than MaxAckDelay.", error_details);
-
- params.max_ack_delay.set_value(25 /*ms*/);
- params.min_ack_delay_us.set_value(25 * kNumMicrosPerMilli);
- EXPECT_THAT(config_.ProcessTransportParameters(
- params, /* is_resumption = */ false, &error_details),
- IsQuicNoError());
- EXPECT_TRUE(error_details.empty());
-}
-
-TEST_P(QuicConfigTest, FillTransportParams) {
- if (!version_.UsesTls()) {
- // TransportParameters are only used for QUIC+TLS.
- return;
- }
- config_.SetInitialMaxStreamDataBytesIncomingBidirectionalToSend(
- 2 * kMinimumFlowControlSendWindow);
- config_.SetInitialMaxStreamDataBytesOutgoingBidirectionalToSend(
- 3 * kMinimumFlowControlSendWindow);
- config_.SetInitialMaxStreamDataBytesUnidirectionalToSend(
- 4 * kMinimumFlowControlSendWindow);
- config_.SetMaxPacketSizeToSend(kMaxPacketSizeForTest);
- config_.SetMaxDatagramFrameSizeToSend(kMaxDatagramFrameSizeForTest);
- config_.SetActiveConnectionIdLimitToSend(kActiveConnectionIdLimitForTest);
-
- config_.SetOriginalConnectionIdToSend(TestConnectionId(0x1111));
- config_.SetInitialSourceConnectionIdToSend(TestConnectionId(0x2222));
- config_.SetRetrySourceConnectionIdToSend(TestConnectionId(0x3333));
- config_.SetMinAckDelayMs(kDefaultMinAckDelayTimeMs);
-
- QuicIpAddress host;
- host.FromString("127.0.3.1");
- QuicSocketAddress kTestServerAddress = QuicSocketAddress(host, 1234);
- QuicConnectionId new_connection_id = TestConnectionId(5);
- StatelessResetToken new_stateless_reset_token =
- QuicUtils::GenerateStatelessResetToken(new_connection_id);
- config_.SetIPv4AlternateServerAddressToSend(
- kTestServerAddress, new_connection_id, new_stateless_reset_token);
-
- TransportParameters params;
- config_.FillTransportParameters(&params);
-
- EXPECT_EQ(2 * kMinimumFlowControlSendWindow,
- params.initial_max_stream_data_bidi_remote.value());
- EXPECT_EQ(3 * kMinimumFlowControlSendWindow,
- params.initial_max_stream_data_bidi_local.value());
- EXPECT_EQ(4 * kMinimumFlowControlSendWindow,
- params.initial_max_stream_data_uni.value());
-
- EXPECT_EQ(static_cast<uint64_t>(kMaximumIdleTimeoutSecs * 1000),
- params.max_idle_timeout_ms.value());
-
- EXPECT_EQ(kMaxPacketSizeForTest, params.max_udp_payload_size.value());
- EXPECT_EQ(kMaxDatagramFrameSizeForTest,
- params.max_datagram_frame_size.value());
- EXPECT_EQ(kActiveConnectionIdLimitForTest,
- params.active_connection_id_limit.value());
-
- ASSERT_TRUE(params.original_destination_connection_id.has_value());
- EXPECT_EQ(TestConnectionId(0x1111),
- params.original_destination_connection_id.value());
- ASSERT_TRUE(params.initial_source_connection_id.has_value());
- EXPECT_EQ(TestConnectionId(0x2222),
- params.initial_source_connection_id.value());
- ASSERT_TRUE(params.retry_source_connection_id.has_value());
- EXPECT_EQ(TestConnectionId(0x3333),
- params.retry_source_connection_id.value());
-
- EXPECT_EQ(
- static_cast<uint64_t>(kDefaultMinAckDelayTimeMs) * kNumMicrosPerMilli,
- params.min_ack_delay_us.value());
-
- EXPECT_EQ(params.preferred_address->ipv4_socket_address, kTestServerAddress);
- EXPECT_EQ(*reinterpret_cast<StatelessResetToken*>(
- &params.preferred_address->stateless_reset_token.front()),
- new_stateless_reset_token);
-}
-
-TEST_P(QuicConfigTest, ProcessTransportParametersServer) {
- if (!version_.UsesTls()) {
- // TransportParameters are only used for QUIC+TLS.
- return;
- }
- TransportParameters params;
-
- params.initial_max_stream_data_bidi_local.set_value(
- 2 * kMinimumFlowControlSendWindow);
- params.initial_max_stream_data_bidi_remote.set_value(
- 3 * kMinimumFlowControlSendWindow);
- params.initial_max_stream_data_uni.set_value(4 *
- kMinimumFlowControlSendWindow);
- params.max_udp_payload_size.set_value(kMaxPacketSizeForTest);
- params.max_datagram_frame_size.set_value(kMaxDatagramFrameSizeForTest);
- params.initial_max_streams_bidi.set_value(kDefaultMaxStreamsPerConnection);
- params.stateless_reset_token = CreateStatelessResetTokenForTest();
- params.max_ack_delay.set_value(kMaxAckDelayForTest);
- params.min_ack_delay_us.set_value(kMinAckDelayUsForTest);
- params.ack_delay_exponent.set_value(kAckDelayExponentForTest);
- params.active_connection_id_limit.set_value(kActiveConnectionIdLimitForTest);
- params.original_destination_connection_id = TestConnectionId(0x1111);
- params.initial_source_connection_id = TestConnectionId(0x2222);
- params.retry_source_connection_id = TestConnectionId(0x3333);
-
- std::string error_details;
- EXPECT_THAT(config_.ProcessTransportParameters(
- params, /* is_resumption = */ true, &error_details),
- IsQuicNoError())
- << error_details;
-
- EXPECT_FALSE(config_.negotiated());
-
- ASSERT_TRUE(
- config_.HasReceivedInitialMaxStreamDataBytesIncomingBidirectional());
- EXPECT_EQ(2 * kMinimumFlowControlSendWindow,
- config_.ReceivedInitialMaxStreamDataBytesIncomingBidirectional());
-
- ASSERT_TRUE(
- config_.HasReceivedInitialMaxStreamDataBytesOutgoingBidirectional());
- EXPECT_EQ(3 * kMinimumFlowControlSendWindow,
- config_.ReceivedInitialMaxStreamDataBytesOutgoingBidirectional());
-
- ASSERT_TRUE(config_.HasReceivedInitialMaxStreamDataBytesUnidirectional());
- EXPECT_EQ(4 * kMinimumFlowControlSendWindow,
- config_.ReceivedInitialMaxStreamDataBytesUnidirectional());
-
- ASSERT_TRUE(config_.HasReceivedMaxPacketSize());
- EXPECT_EQ(kMaxPacketSizeForTest, config_.ReceivedMaxPacketSize());
-
- ASSERT_TRUE(config_.HasReceivedMaxDatagramFrameSize());
- EXPECT_EQ(kMaxDatagramFrameSizeForTest,
- config_.ReceivedMaxDatagramFrameSize());
-
- ASSERT_TRUE(config_.HasReceivedMaxBidirectionalStreams());
- EXPECT_EQ(kDefaultMaxStreamsPerConnection,
- config_.ReceivedMaxBidirectionalStreams());
-
- EXPECT_FALSE(config_.DisableConnectionMigration());
-
- // The following config shouldn't be processed because of resumption.
- EXPECT_FALSE(config_.HasReceivedStatelessResetToken());
- EXPECT_FALSE(config_.HasReceivedMaxAckDelayMs());
- EXPECT_FALSE(config_.HasReceivedAckDelayExponent());
- EXPECT_FALSE(config_.HasReceivedMinAckDelayMs());
- EXPECT_FALSE(config_.HasReceivedOriginalConnectionId());
- EXPECT_FALSE(config_.HasReceivedInitialSourceConnectionId());
- EXPECT_FALSE(config_.HasReceivedRetrySourceConnectionId());
-
- // Let the config process another slightly tweaked transport paramters.
- // Note that the values for flow control and stream limit cannot be smaller
- // than before. This rule is enforced in QuicSession::OnConfigNegotiated().
- params.initial_max_stream_data_bidi_local.set_value(
- 2 * kMinimumFlowControlSendWindow + 1);
- params.initial_max_stream_data_bidi_remote.set_value(
- 4 * kMinimumFlowControlSendWindow);
- params.initial_max_stream_data_uni.set_value(5 *
- kMinimumFlowControlSendWindow);
- params.max_udp_payload_size.set_value(2 * kMaxPacketSizeForTest);
- params.max_datagram_frame_size.set_value(2 * kMaxDatagramFrameSizeForTest);
- params.initial_max_streams_bidi.set_value(2 *
- kDefaultMaxStreamsPerConnection);
- params.disable_active_migration = true;
-
- EXPECT_THAT(config_.ProcessTransportParameters(
- params, /* is_resumption = */ false, &error_details),
- IsQuicNoError())
- << error_details;
-
- EXPECT_TRUE(config_.negotiated());
-
- ASSERT_TRUE(
- config_.HasReceivedInitialMaxStreamDataBytesIncomingBidirectional());
- EXPECT_EQ(2 * kMinimumFlowControlSendWindow + 1,
- config_.ReceivedInitialMaxStreamDataBytesIncomingBidirectional());
-
- ASSERT_TRUE(
- config_.HasReceivedInitialMaxStreamDataBytesOutgoingBidirectional());
- EXPECT_EQ(4 * kMinimumFlowControlSendWindow,
- config_.ReceivedInitialMaxStreamDataBytesOutgoingBidirectional());
-
- ASSERT_TRUE(config_.HasReceivedInitialMaxStreamDataBytesUnidirectional());
- EXPECT_EQ(5 * kMinimumFlowControlSendWindow,
- config_.ReceivedInitialMaxStreamDataBytesUnidirectional());
-
- ASSERT_TRUE(config_.HasReceivedMaxPacketSize());
- EXPECT_EQ(2 * kMaxPacketSizeForTest, config_.ReceivedMaxPacketSize());
-
- ASSERT_TRUE(config_.HasReceivedMaxDatagramFrameSize());
- EXPECT_EQ(2 * kMaxDatagramFrameSizeForTest,
- config_.ReceivedMaxDatagramFrameSize());
-
- ASSERT_TRUE(config_.HasReceivedMaxBidirectionalStreams());
- EXPECT_EQ(2 * kDefaultMaxStreamsPerConnection,
- config_.ReceivedMaxBidirectionalStreams());
-
- EXPECT_TRUE(config_.DisableConnectionMigration());
-
- ASSERT_TRUE(config_.HasReceivedStatelessResetToken());
-
- ASSERT_TRUE(config_.HasReceivedMaxAckDelayMs());
- EXPECT_EQ(config_.ReceivedMaxAckDelayMs(), kMaxAckDelayForTest);
-
- ASSERT_TRUE(config_.HasReceivedMinAckDelayMs());
- EXPECT_EQ(config_.ReceivedMinAckDelayMs(),
- kMinAckDelayUsForTest / kNumMicrosPerMilli);
-
- ASSERT_TRUE(config_.HasReceivedAckDelayExponent());
- EXPECT_EQ(config_.ReceivedAckDelayExponent(), kAckDelayExponentForTest);
-
- ASSERT_TRUE(config_.HasReceivedActiveConnectionIdLimit());
- EXPECT_EQ(config_.ReceivedActiveConnectionIdLimit(),
- kActiveConnectionIdLimitForTest);
-
- ASSERT_TRUE(config_.HasReceivedOriginalConnectionId());
- EXPECT_EQ(config_.ReceivedOriginalConnectionId(), TestConnectionId(0x1111));
- ASSERT_TRUE(config_.HasReceivedInitialSourceConnectionId());
- EXPECT_EQ(config_.ReceivedInitialSourceConnectionId(),
- TestConnectionId(0x2222));
- ASSERT_TRUE(config_.HasReceivedRetrySourceConnectionId());
- EXPECT_EQ(config_.ReceivedRetrySourceConnectionId(),
- TestConnectionId(0x3333));
-}
-
-TEST_P(QuicConfigTest, DisableMigrationTransportParameter) {
- if (!version_.UsesTls()) {
- // TransportParameters are only used for QUIC+TLS.
- return;
- }
- TransportParameters params;
- params.disable_active_migration = true;
- std::string error_details;
- EXPECT_THAT(config_.ProcessTransportParameters(
- params, /* is_resumption = */ false, &error_details),
- IsQuicNoError());
- EXPECT_TRUE(config_.DisableConnectionMigration());
-}
-
-TEST_P(QuicConfigTest, SendPreferredIPv4Address) {
- if (!version_.UsesTls()) {
- // TransportParameters are only used for QUIC+TLS.
- return;
- }
-
- EXPECT_FALSE(config_.HasReceivedPreferredAddressConnectionIdAndToken());
-
- TransportParameters params;
- QuicIpAddress host;
- host.FromString("::ffff:192.0.2.128");
- QuicSocketAddress kTestServerAddress = QuicSocketAddress(host, 1234);
- QuicConnectionId new_connection_id = TestConnectionId(5);
- StatelessResetToken new_stateless_reset_token =
- QuicUtils::GenerateStatelessResetToken(new_connection_id);
- auto preferred_address =
- std::make_unique<TransportParameters::PreferredAddress>();
- preferred_address->ipv6_socket_address = kTestServerAddress;
- preferred_address->connection_id = new_connection_id;
- preferred_address->stateless_reset_token.assign(
- reinterpret_cast<const char*>(&new_stateless_reset_token),
- reinterpret_cast<const char*>(&new_stateless_reset_token) +
- sizeof(new_stateless_reset_token));
- params.preferred_address = std::move(preferred_address);
-
- std::string error_details;
- EXPECT_THAT(config_.ProcessTransportParameters(
- params, /* is_resumption = */ false, &error_details),
- IsQuicNoError());
-
- EXPECT_TRUE(config_.HasReceivedIPv6AlternateServerAddress());
- EXPECT_EQ(config_.ReceivedIPv6AlternateServerAddress(), kTestServerAddress);
- EXPECT_TRUE(config_.HasReceivedPreferredAddressConnectionIdAndToken());
- const std::pair<QuicConnectionId, StatelessResetToken>&
- preferred_address_connection_id_and_token =
- config_.ReceivedPreferredAddressConnectionIdAndToken();
- EXPECT_EQ(preferred_address_connection_id_and_token.first, new_connection_id);
- EXPECT_EQ(preferred_address_connection_id_and_token.second,
- new_stateless_reset_token);
-}
-
-} // namespace
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_connection.cc b/chromium/net/third_party/quiche/src/quic/core/quic_connection.cc
deleted file mode 100644
index 2fe7af38717..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_connection.cc
+++ /dev/null
@@ -1,7123 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_connection.h"
-
-#include <string.h>
-#include <sys/types.h>
-
-#include <algorithm>
-#include <iterator>
-#include <limits>
-#include <memory>
-#include <optional>
-#include <set>
-#include <string>
-#include <utility>
-
-#include "absl/strings/escaping.h"
-#include "absl/strings/str_cat.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/congestion_control/rtt_stats.h"
-#include "quic/core/congestion_control/send_algorithm_interface.h"
-#include "quic/core/crypto/crypto_protocol.h"
-#include "quic/core/crypto/crypto_utils.h"
-#include "quic/core/crypto/quic_decrypter.h"
-#include "quic/core/crypto/quic_encrypter.h"
-#include "quic/core/proto/cached_network_parameters_proto.h"
-#include "quic/core/quic_bandwidth.h"
-#include "quic/core/quic_config.h"
-#include "quic/core/quic_connection_id.h"
-#include "quic/core/quic_constants.h"
-#include "quic/core/quic_error_codes.h"
-#include "quic/core/quic_legacy_version_encapsulator.h"
-#include "quic/core/quic_packet_creator.h"
-#include "quic/core/quic_packet_writer.h"
-#include "quic/core/quic_path_validator.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_client_stats.h"
-#include "quic/platform/api/quic_error_code_wrappers.h"
-#include "quic/platform/api/quic_exported_stats.h"
-#include "quic/platform/api/quic_flag_utils.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_hostname_utils.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/platform/api/quic_server_stats.h"
-#include "quic/platform/api/quic_socket_address.h"
-#include "common/platform/api/quiche_flag_utils.h"
-#include "common/quiche_text_utils.h"
-
-namespace quic {
-
-class QuicDecrypter;
-class QuicEncrypter;
-
-namespace {
-
-// Maximum number of consecutive sent nonretransmittable packets.
-const QuicPacketCount kMaxConsecutiveNonRetransmittablePackets = 19;
-
-// The minimum release time into future in ms.
-const int kMinReleaseTimeIntoFutureMs = 1;
-
-// Base class of all alarms owned by a QuicConnection.
-class QuicConnectionAlarmDelegate : public QuicAlarm::Delegate {
- public:
- explicit QuicConnectionAlarmDelegate(QuicConnection* connection)
- : connection_(connection) {}
- QuicConnectionAlarmDelegate(const QuicConnectionAlarmDelegate&) = delete;
- QuicConnectionAlarmDelegate& operator=(const QuicConnectionAlarmDelegate&) =
- delete;
-
- QuicConnectionContext* GetConnectionContext() override {
- return (connection_ == nullptr) ? nullptr : connection_->context();
- }
-
- protected:
- QuicConnection* connection_;
-};
-
-// An alarm that is scheduled to send an ack if a timeout occurs.
-class AckAlarmDelegate : public QuicConnectionAlarmDelegate {
- public:
- using QuicConnectionAlarmDelegate::QuicConnectionAlarmDelegate;
-
- void OnAlarm() override {
- QUICHE_DCHECK(connection_->ack_frame_updated());
- QUICHE_DCHECK(connection_->connected());
- QuicConnection::ScopedPacketFlusher flusher(connection_);
- if (connection_->SupportsMultiplePacketNumberSpaces()) {
- connection_->SendAllPendingAcks();
- } else {
- connection_->SendAck();
- }
- }
-};
-
-// This alarm will be scheduled any time a data-bearing packet is sent out.
-// When the alarm goes off, the connection checks to see if the oldest packets
-// have been acked, and retransmit them if they have not.
-class RetransmissionAlarmDelegate : public QuicConnectionAlarmDelegate {
- public:
- using QuicConnectionAlarmDelegate::QuicConnectionAlarmDelegate;
-
- void OnAlarm() override {
- QUICHE_DCHECK(connection_->connected());
- connection_->OnRetransmissionTimeout();
- }
-};
-
-// An alarm that is scheduled when the SentPacketManager requires a delay
-// before sending packets and fires when the packet may be sent.
-class SendAlarmDelegate : public QuicConnectionAlarmDelegate {
- public:
- using QuicConnectionAlarmDelegate::QuicConnectionAlarmDelegate;
-
- void OnAlarm() override {
- QUICHE_DCHECK(connection_->connected());
- connection_->WriteIfNotBlocked();
- }
-};
-
-class PingAlarmDelegate : public QuicConnectionAlarmDelegate {
- public:
- using QuicConnectionAlarmDelegate::QuicConnectionAlarmDelegate;
-
- void OnAlarm() override {
- QUICHE_DCHECK(connection_->connected());
- connection_->OnPingTimeout();
- }
-};
-
-class MtuDiscoveryAlarmDelegate : public QuicConnectionAlarmDelegate {
- public:
- using QuicConnectionAlarmDelegate::QuicConnectionAlarmDelegate;
-
- void OnAlarm() override {
- QUICHE_DCHECK(connection_->connected());
- connection_->DiscoverMtu();
- }
-};
-
-class ProcessUndecryptablePacketsAlarmDelegate
- : public QuicConnectionAlarmDelegate {
- public:
- using QuicConnectionAlarmDelegate::QuicConnectionAlarmDelegate;
-
- void OnAlarm() override {
- QUICHE_DCHECK(connection_->connected());
- QuicConnection::ScopedPacketFlusher flusher(connection_);
- connection_->MaybeProcessUndecryptablePackets();
- }
-};
-
-class DiscardPreviousOneRttKeysAlarmDelegate
- : public QuicConnectionAlarmDelegate {
- public:
- using QuicConnectionAlarmDelegate::QuicConnectionAlarmDelegate;
-
- void OnAlarm() override {
- QUICHE_DCHECK(connection_->connected());
- connection_->DiscardPreviousOneRttKeys();
- }
-};
-
-class DiscardZeroRttDecryptionKeysAlarmDelegate
- : public QuicConnectionAlarmDelegate {
- public:
- using QuicConnectionAlarmDelegate::QuicConnectionAlarmDelegate;
-
- void OnAlarm() override {
- QUICHE_DCHECK(connection_->connected());
- QUIC_DLOG(INFO) << "0-RTT discard alarm fired";
- connection_->RemoveDecrypter(ENCRYPTION_ZERO_RTT);
- }
-};
-
-// When the clearer goes out of scope, the coalesced packet gets cleared.
-class ScopedCoalescedPacketClearer {
- public:
- explicit ScopedCoalescedPacketClearer(QuicCoalescedPacket* coalesced)
- : coalesced_(coalesced) {}
- ~ScopedCoalescedPacketClearer() { coalesced_->Clear(); }
-
- private:
- QuicCoalescedPacket* coalesced_; // Unowned.
-};
-
-// Whether this incoming packet is allowed to replace our connection ID.
-bool PacketCanReplaceServerConnectionId(const QuicPacketHeader& header,
- Perspective perspective) {
- return perspective == Perspective::IS_CLIENT &&
- header.form == IETF_QUIC_LONG_HEADER_PACKET &&
- header.version.IsKnown() &&
- header.version.AllowsVariableLengthConnectionIds() &&
- (header.long_packet_type == INITIAL ||
- header.long_packet_type == RETRY);
-}
-
-CongestionControlType GetDefaultCongestionControlType() {
- if (GetQuicReloadableFlag(quic_default_to_bbr_v2)) {
- return kBBRv2;
- }
-
- if (GetQuicReloadableFlag(quic_default_to_bbr)) {
- return kBBR;
- }
-
- return kCubicBytes;
-}
-
-} // namespace
-
-#define ENDPOINT \
- (perspective_ == Perspective::IS_SERVER ? "Server: " : "Client: ")
-
-QuicConnection::QuicConnection(
- QuicConnectionId server_connection_id,
- QuicSocketAddress initial_self_address,
- QuicSocketAddress initial_peer_address,
- QuicConnectionHelperInterface* helper, QuicAlarmFactory* alarm_factory,
- QuicPacketWriter* writer, bool owns_writer, Perspective perspective,
- const ParsedQuicVersionVector& supported_versions)
- : framer_(supported_versions, helper->GetClock()->ApproximateNow(),
- perspective, server_connection_id.length()),
- current_packet_content_(NO_FRAMES_RECEIVED),
- is_current_packet_connectivity_probing_(false),
- has_path_challenge_in_current_packet_(false),
- current_effective_peer_migration_type_(NO_CHANGE),
- helper_(helper),
- alarm_factory_(alarm_factory),
- per_packet_options_(nullptr),
- writer_(writer),
- owns_writer_(owns_writer),
- encryption_level_(ENCRYPTION_INITIAL),
- clock_(helper->GetClock()),
- random_generator_(helper->GetRandomGenerator()),
- client_connection_id_is_set_(false),
- direct_peer_address_(initial_peer_address),
- default_path_(initial_self_address, QuicSocketAddress(),
- /*client_connection_id=*/EmptyQuicConnectionId(),
- server_connection_id,
- /*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)),
- idle_timeout_connection_close_behavior_(
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET),
- num_rtos_for_blackhole_detection_(0),
- uber_received_packet_manager_(&stats_),
- stop_waiting_count_(0),
- pending_retransmission_alarm_(false),
- defer_send_in_response_to_packets_(false),
- ping_timeout_(QuicTime::Delta::FromSeconds(kPingTimeoutSecs)),
- initial_retransmittable_on_wire_timeout_(QuicTime::Delta::Infinite()),
- consecutive_retransmittable_on_wire_ping_count_(0),
- retransmittable_on_wire_ping_count_(0),
- arena_(),
- ack_alarm_(alarm_factory_->CreateAlarm(arena_.New<AckAlarmDelegate>(this),
- &arena_)),
- retransmission_alarm_(alarm_factory_->CreateAlarm(
- arena_.New<RetransmissionAlarmDelegate>(this), &arena_)),
- send_alarm_(alarm_factory_->CreateAlarm(
- arena_.New<SendAlarmDelegate>(this), &arena_)),
- ping_alarm_(alarm_factory_->CreateAlarm(
- arena_.New<PingAlarmDelegate>(this), &arena_)),
- mtu_discovery_alarm_(alarm_factory_->CreateAlarm(
- arena_.New<MtuDiscoveryAlarmDelegate>(this), &arena_)),
- process_undecryptable_packets_alarm_(alarm_factory_->CreateAlarm(
- arena_.New<ProcessUndecryptablePacketsAlarmDelegate>(this), &arena_)),
- discard_previous_one_rtt_keys_alarm_(alarm_factory_->CreateAlarm(
- arena_.New<DiscardPreviousOneRttKeysAlarmDelegate>(this), &arena_)),
- discard_zero_rtt_decryption_keys_alarm_(alarm_factory_->CreateAlarm(
- arena_.New<DiscardZeroRttDecryptionKeysAlarmDelegate>(this),
- &arena_)),
- visitor_(nullptr),
- debug_visitor_(nullptr),
- packet_creator_(server_connection_id, &framer_, random_generator_, this),
- last_received_packet_info_(clock_->ApproximateNow()),
- sent_packet_manager_(perspective, clock_, random_generator_, &stats_,
- GetDefaultCongestionControlType()),
- version_negotiated_(false),
- perspective_(perspective),
- connected_(true),
- can_truncate_connection_ids_(perspective == Perspective::IS_SERVER),
- mtu_probe_count_(0),
- previous_validated_mtu_(0),
- peer_max_packet_size_(kDefaultMaxPacketSizeTransportParam),
- largest_received_packet_size_(0),
- write_error_occurred_(false),
- no_stop_waiting_frames_(version().HasIetfInvariantHeader()),
- consecutive_num_packets_with_no_retransmittable_frames_(0),
- 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),
- supports_release_time_(false),
- release_time_into_future_(QuicTime::Delta::Zero()),
- blackhole_detector_(this, &arena_, alarm_factory_, &context_),
- idle_network_detector_(this, clock_->ApproximateNow(), &arena_,
- alarm_factory_, &context_),
- path_validator_(alarm_factory_, &arena_, this, random_generator_,
- &context_),
- most_recent_frame_type_(NUM_FRAME_TYPES) {
- QUICHE_DCHECK(perspective_ == Perspective::IS_CLIENT ||
- default_path_.self_address.IsInitialized());
-
- QUIC_DLOG(INFO) << ENDPOINT << "Created connection with server connection ID "
- << server_connection_id
- << " and version: " << ParsedQuicVersionToString(version());
-
- QUIC_BUG_IF(quic_bug_12714_2, !QuicUtils::IsConnectionIdValidForVersion(
- server_connection_id, transport_version()))
- << "QuicConnection: attempted to use server connection ID "
- << server_connection_id << " which is invalid with version " << version();
- framer_.set_visitor(this);
- stats_.connection_creation_time = clock_->ApproximateNow();
- // TODO(ianswett): Supply the NetworkChangeVisitor as a constructor argument
- // and make it required non-null, because it's always used.
- sent_packet_manager_.SetNetworkChangeVisitor(this);
- if (GetQuicRestartFlag(quic_offload_pacing_to_usps2)) {
- sent_packet_manager_.SetPacingAlarmGranularity(QuicTime::Delta::Zero());
- release_time_into_future_ =
- QuicTime::Delta::FromMilliseconds(kMinReleaseTimeIntoFutureMs);
- }
- // Allow the packet writer to potentially reduce the packet size to a value
- // even smaller than kDefaultMaxPacketSize.
- SetMaxPacketLength(perspective_ == Perspective::IS_SERVER
- ? kDefaultServerMaxPacketSize
- : kDefaultMaxPacketSize);
- uber_received_packet_manager_.set_max_ack_ranges(255);
- MaybeEnableMultiplePacketNumberSpacesSupport();
- QUICHE_DCHECK(perspective_ == Perspective::IS_CLIENT ||
- supported_versions.size() == 1);
- InstallInitialCrypters(default_path_.server_connection_id);
-
- // On the server side, version negotiation has been done by the dispatcher,
- // and the server connection is created with the right version.
- if (perspective_ == Perspective::IS_SERVER) {
- SetVersionNegotiated();
- }
- if (default_enable_5rto_blackhole_detection_) {
- num_rtos_for_blackhole_detection_ = 5;
- if (GetQuicReloadableFlag(quic_disable_server_blackhole_detection) &&
- perspective_ == Perspective::IS_SERVER) {
- QUIC_RELOADABLE_FLAG_COUNT(quic_disable_server_blackhole_detection);
- blackhole_detection_disabled_ = true;
- }
- }
- packet_creator_.SetDefaultPeerAddress(initial_peer_address);
-}
-
-void QuicConnection::InstallInitialCrypters(QuicConnectionId connection_id) {
- CrypterPair crypters;
- CryptoUtils::CreateInitialObfuscators(perspective_, version(), connection_id,
- &crypters);
- SetEncrypter(ENCRYPTION_INITIAL, std::move(crypters.encrypter));
- if (version().KnowsWhichDecrypterToUse()) {
- InstallDecrypter(ENCRYPTION_INITIAL, std::move(crypters.decrypter));
- } else {
- SetDecrypter(ENCRYPTION_INITIAL, std::move(crypters.decrypter));
- }
-}
-
-QuicConnection::~QuicConnection() {
- QUICHE_DCHECK_GE(stats_.max_egress_mtu, long_term_mtu_);
- if (owns_writer_) {
- delete writer_;
- }
- ClearQueuedPackets();
- if (stats_
- .num_tls_server_zero_rtt_packets_received_after_discarding_decrypter >
- 0) {
- QUIC_CODE_COUNT_N(
- quic_server_received_tls_zero_rtt_packet_after_discarding_decrypter, 2,
- 3);
- } else {
- QUIC_CODE_COUNT_N(
- quic_server_received_tls_zero_rtt_packet_after_discarding_decrypter, 3,
- 3);
- }
-}
-
-void QuicConnection::ClearQueuedPackets() {
- buffered_packets_.clear();
-}
-
-bool QuicConnection::ValidateConfigConnectionIds(const QuicConfig& config) {
- QUICHE_DCHECK(config.negotiated());
- if (!version().UsesTls()) {
- // QUIC+TLS is required to transmit connection ID transport parameters.
- return true;
- }
- // This function validates connection IDs as defined in IETF draft-28 and
- // later.
-
- // Validate initial_source_connection_id.
- QuicConnectionId expected_initial_source_connection_id;
- if (perspective_ == Perspective::IS_CLIENT) {
- expected_initial_source_connection_id = default_path_.server_connection_id;
- } else {
- expected_initial_source_connection_id = default_path_.client_connection_id;
- }
- if (!config.HasReceivedInitialSourceConnectionId() ||
- config.ReceivedInitialSourceConnectionId() !=
- expected_initial_source_connection_id) {
- std::string received_value;
- if (config.HasReceivedInitialSourceConnectionId()) {
- received_value = config.ReceivedInitialSourceConnectionId().ToString();
- } else {
- received_value = "none";
- }
- std::string error_details =
- absl::StrCat("Bad initial_source_connection_id: expected ",
- expected_initial_source_connection_id.ToString(),
- ", received ", received_value);
- CloseConnection(IETF_QUIC_PROTOCOL_VIOLATION, error_details,
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
- return false;
- }
- if (perspective_ == Perspective::IS_CLIENT) {
- // Validate original_destination_connection_id.
- if (!config.HasReceivedOriginalConnectionId() ||
- config.ReceivedOriginalConnectionId() !=
- GetOriginalDestinationConnectionId()) {
- std::string received_value;
- if (config.HasReceivedOriginalConnectionId()) {
- received_value = config.ReceivedOriginalConnectionId().ToString();
- } else {
- received_value = "none";
- }
- std::string error_details =
- absl::StrCat("Bad original_destination_connection_id: expected ",
- GetOriginalDestinationConnectionId().ToString(),
- ", received ", received_value);
- CloseConnection(IETF_QUIC_PROTOCOL_VIOLATION, error_details,
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
- return false;
- }
- // Validate retry_source_connection_id.
- if (retry_source_connection_id_.has_value()) {
- // We received a RETRY packet, validate that the retry source
- // connection ID from the config matches the one from the RETRY.
- if (!config.HasReceivedRetrySourceConnectionId() ||
- config.ReceivedRetrySourceConnectionId() !=
- retry_source_connection_id_.value()) {
- std::string received_value;
- if (config.HasReceivedRetrySourceConnectionId()) {
- received_value = config.ReceivedRetrySourceConnectionId().ToString();
- } else {
- received_value = "none";
- }
- std::string error_details =
- absl::StrCat("Bad retry_source_connection_id: expected ",
- retry_source_connection_id_.value().ToString(),
- ", received ", received_value);
- CloseConnection(IETF_QUIC_PROTOCOL_VIOLATION, error_details,
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
- return false;
- }
- } else {
- // We did not receive a RETRY packet, make sure we did not receive the
- // retry_source_connection_id transport parameter.
- if (config.HasReceivedRetrySourceConnectionId()) {
- std::string error_details = absl::StrCat(
- "Bad retry_source_connection_id: did not receive RETRY but "
- "received ",
- config.ReceivedRetrySourceConnectionId().ToString());
- CloseConnection(IETF_QUIC_PROTOCOL_VIOLATION, error_details,
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
- return false;
- }
- }
- }
- return true;
-}
-
-void QuicConnection::SetFromConfig(const QuicConfig& config) {
- if (config.negotiated()) {
- // Handshake complete, set handshake timeout to Infinite.
- SetNetworkTimeouts(QuicTime::Delta::Infinite(),
- config.IdleNetworkTimeout());
- idle_timeout_connection_close_behavior_ =
- ConnectionCloseBehavior::SILENT_CLOSE;
- if (perspective_ == Perspective::IS_SERVER) {
- idle_timeout_connection_close_behavior_ = ConnectionCloseBehavior::
- SILENT_CLOSE_WITH_CONNECTION_CLOSE_PACKET_SERIALIZED;
- }
- if (config.HasClientRequestedIndependentOption(kNSLC, perspective_)) {
- idle_timeout_connection_close_behavior_ =
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET;
- }
- if (!ValidateConfigConnectionIds(config)) {
- return;
- }
- support_key_update_for_connection_ = version().UsesTls();
- framer_.SetKeyUpdateSupportForConnection(
- support_key_update_for_connection_);
- } else {
- SetNetworkTimeouts(config.max_time_before_crypto_handshake(),
- config.max_idle_time_before_crypto_handshake());
- if (config.HasClientRequestedIndependentOption(kNCHP, perspective_)) {
- packet_creator_.set_chaos_protection_enabled(false);
- }
- }
-
- if (version().HasIetfQuicFrames() &&
- config.HasReceivedPreferredAddressConnectionIdAndToken()) {
- QuicNewConnectionIdFrame frame;
- std::tie(frame.connection_id, frame.stateless_reset_token) =
- config.ReceivedPreferredAddressConnectionIdAndToken();
- frame.sequence_number = 1u;
- frame.retire_prior_to = 0u;
- OnNewConnectionIdFrameInner(frame);
- }
-
- sent_packet_manager_.SetFromConfig(config);
- if (perspective_ == Perspective::IS_SERVER &&
- config.HasClientSentConnectionOption(kAFF2, perspective_)) {
- send_ack_frequency_on_handshake_completion_ = true;
- }
- if (config.HasReceivedBytesForConnectionId() &&
- can_truncate_connection_ids_) {
- packet_creator_.SetServerConnectionIdLength(
- config.ReceivedBytesForConnectionId());
- }
- max_undecryptable_packets_ = config.max_undecryptable_packets();
-
- if (!GetQuicReloadableFlag(quic_enable_mtu_discovery_at_server)) {
- if (config.HasClientRequestedIndependentOption(kMTUH, perspective_)) {
- SetMtuDiscoveryTarget(kMtuDiscoveryTargetPacketSizeHigh);
- }
- }
- if (config.HasClientRequestedIndependentOption(kMTUL, perspective_)) {
- SetMtuDiscoveryTarget(kMtuDiscoveryTargetPacketSizeLow);
- }
- if (default_enable_5rto_blackhole_detection_) {
- if (config.HasClientRequestedIndependentOption(kCBHD, perspective_)) {
- QUIC_CODE_COUNT(quic_client_only_blackhole_detection);
- blackhole_detection_disabled_ = true;
- }
- if (config.HasClientSentConnectionOption(kNBHD, perspective_)) {
- blackhole_detection_disabled_ = true;
- }
- if (config.HasClientSentConnectionOption(k2RTO, perspective_)) {
- QUIC_CODE_COUNT(quic_2rto_blackhole_detection);
- num_rtos_for_blackhole_detection_ = 2;
- }
- if (config.HasClientSentConnectionOption(k3RTO, perspective_)) {
- QUIC_CODE_COUNT(quic_3rto_blackhole_detection);
- num_rtos_for_blackhole_detection_ = 3;
- }
- if (config.HasClientSentConnectionOption(k4RTO, perspective_)) {
- QUIC_CODE_COUNT(quic_4rto_blackhole_detection);
- num_rtos_for_blackhole_detection_ = 4;
- }
- if (config.HasClientSentConnectionOption(k6RTO, perspective_)) {
- QUIC_CODE_COUNT(quic_6rto_blackhole_detection);
- num_rtos_for_blackhole_detection_ = 6;
- }
- }
-
- if (config.HasClientRequestedIndependentOption(kFIDT, perspective_)) {
- idle_network_detector_.enable_shorter_idle_timeout_on_sent_packet();
- }
- if (config.HasClientRequestedIndependentOption(k3AFF, perspective_)) {
- anti_amplification_factor_ = 3;
- }
- if (config.HasClientRequestedIndependentOption(k10AF, perspective_)) {
- anti_amplification_factor_ = 10;
- }
-
- if (GetQuicReloadableFlag(quic_enable_server_on_wire_ping) &&
- perspective_ == Perspective::IS_SERVER &&
- config.HasClientSentConnectionOption(kSRWP, perspective_)) {
- QUIC_RELOADABLE_FLAG_COUNT(quic_enable_server_on_wire_ping);
- set_initial_retransmittable_on_wire_timeout(
- QuicTime::Delta::FromMilliseconds(200));
- }
-
- if (debug_visitor_ != nullptr) {
- debug_visitor_->OnSetFromConfig(config);
- }
- uber_received_packet_manager_.SetFromConfig(config, perspective_);
- 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(kNSTP, perspective_)) {
- no_stop_waiting_frames_ = true;
- }
- if (config.HasReceivedStatelessResetToken()) {
- default_path_.stateless_reset_token = config.ReceivedStatelessResetToken();
- }
- if (config.HasReceivedAckDelayExponent()) {
- framer_.set_peer_ack_delay_exponent(config.ReceivedAckDelayExponent());
- }
- if (config.HasClientSentConnectionOption(kEACK, perspective_)) {
- bundle_retransmittable_with_pto_ack_ = true;
- }
- if (config.HasClientSentConnectionOption(kDFER, perspective_)) {
- defer_send_in_response_to_packets_ = false;
- }
- const bool remove_connection_migration_connection_option =
- GetQuicReloadableFlag(quic_remove_connection_migration_connection_option);
- if (remove_connection_migration_connection_option) {
- QUIC_RELOADABLE_FLAG_COUNT(
- quic_remove_connection_migration_connection_option);
- }
- if (framer_.version().HasIetfQuicFrames() && use_path_validator_ &&
- 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
- // and connection option on both client and server sides has the advantage of:
- // 1) Less chance of skew in using new connection ID or not between client
- // and server in unit tests with random flag combinations.
- // 2) Client side's rollout can be protected by the same connection option.
- connection_migration_use_new_cid_ =
- validate_client_addresses_ &&
- GetQuicReloadableFlag(quic_connection_migration_use_new_cid_v2);
- if (config.HasReceivedMaxPacketSize()) {
- peer_max_packet_size_ = config.ReceivedMaxPacketSize();
- MaybeUpdatePacketCreatorMaxPacketLengthAndPadding();
- }
- if (config.HasReceivedMaxDatagramFrameSize()) {
- packet_creator_.SetMaxDatagramFrameSize(
- config.ReceivedMaxDatagramFrameSize());
- }
-
- supports_release_time_ =
- writer_ != nullptr && writer_->SupportsReleaseTime() &&
- !config.HasClientSentConnectionOption(kNPCO, perspective_);
-
- if (supports_release_time_) {
- UpdateReleaseTimeIntoFuture();
- }
-}
-
-void QuicConnection::EnableLegacyVersionEncapsulation(
- const std::string& server_name) {
- if (perspective_ != Perspective::IS_CLIENT) {
- QUIC_BUG(quic_bug_10511_1)
- << "Cannot enable Legacy Version Encapsulation on the server";
- return;
- }
- if (legacy_version_encapsulation_enabled_) {
- QUIC_BUG(quic_bug_10511_2)
- << "Do not call EnableLegacyVersionEncapsulation twice";
- return;
- }
- if (!QuicHostnameUtils::IsValidSNI(server_name)) {
- // Legacy Version Encapsulation is only used when SNI is transmitted.
- QUIC_DLOG(INFO)
- << "Refusing to use Legacy Version Encapsulation with invalid SNI \""
- << server_name << "\"";
- return;
- }
- QUIC_DLOG(INFO) << "Enabling Legacy Version Encapsulation with SNI \""
- << server_name << "\"";
- legacy_version_encapsulation_enabled_ = true;
- legacy_version_encapsulation_sni_ = server_name;
-}
-
-bool QuicConnection::MaybeTestLiveness() {
- QUICHE_DCHECK_EQ(perspective_, Perspective::IS_CLIENT);
- if (encryption_level_ != ENCRYPTION_FORWARD_SECURE) {
- return false;
- }
- const QuicTime idle_network_deadline =
- idle_network_detector_.GetIdleNetworkDeadline();
- if (!idle_network_deadline.IsInitialized()) {
- return false;
- }
- const QuicTime now = clock_->ApproximateNow();
- if (now > idle_network_deadline) {
- QUIC_DLOG(WARNING) << "Idle network deadline has passed";
- return false;
- }
- const QuicTime::Delta timeout = idle_network_deadline - now;
- if (2 * timeout > idle_network_detector_.idle_network_timeout()) {
- // Do not test liveness if timeout is > half timeout. This is used to
- // prevent an infinite loop for short idle timeout.
- return false;
- }
- if (!sent_packet_manager_.IsLessThanThreePTOs(timeout)) {
- return false;
- }
- SendConnectivityProbingPacket(writer_, peer_address());
- return true;
-}
-
-void QuicConnection::ApplyConnectionOptions(
- const QuicTagVector& connection_options) {
- sent_packet_manager_.ApplyConnectionOptions(connection_options);
-}
-
-void QuicConnection::OnSendConnectionState(
- const CachedNetworkParameters& cached_network_params) {
- if (debug_visitor_ != nullptr) {
- debug_visitor_->OnSendConnectionState(cached_network_params);
- }
-}
-
-void QuicConnection::OnReceiveConnectionState(
- const CachedNetworkParameters& cached_network_params) {
- if (debug_visitor_ != nullptr) {
- debug_visitor_->OnReceiveConnectionState(cached_network_params);
- }
-}
-
-void QuicConnection::ResumeConnectionState(
- const CachedNetworkParameters& cached_network_params,
- bool max_bandwidth_resumption) {
- sent_packet_manager_.ResumeConnectionState(cached_network_params,
- max_bandwidth_resumption);
-}
-
-void QuicConnection::SetMaxPacingRate(QuicBandwidth max_pacing_rate) {
- sent_packet_manager_.SetMaxPacingRate(max_pacing_rate);
-}
-
-void QuicConnection::AdjustNetworkParameters(
- const SendAlgorithmInterface::NetworkParams& params) {
- sent_packet_manager_.AdjustNetworkParameters(params);
-}
-
-void QuicConnection::SetLossDetectionTuner(
- std::unique_ptr<LossDetectionTunerInterface> tuner) {
- sent_packet_manager_.SetLossDetectionTuner(std::move(tuner));
-}
-
-void QuicConnection::OnConfigNegotiated() {
- sent_packet_manager_.OnConfigNegotiated();
-
- if (GetQuicReloadableFlag(quic_enable_mtu_discovery_at_server) &&
- perspective_ == Perspective::IS_SERVER) {
- QUIC_RELOADABLE_FLAG_COUNT(quic_enable_mtu_discovery_at_server);
- SetMtuDiscoveryTarget(kMtuDiscoveryTargetPacketSizeHigh);
- }
-}
-
-QuicBandwidth QuicConnection::MaxPacingRate() const {
- return sent_packet_manager_.MaxPacingRate();
-}
-
-bool QuicConnection::SelectMutualVersion(
- const ParsedQuicVersionVector& available_versions) {
- // Try to find the highest mutual version by iterating over supported
- // versions, starting with the highest, and breaking out of the loop once we
- // find a matching version in the provided available_versions vector.
- const ParsedQuicVersionVector& supported_versions =
- framer_.supported_versions();
- for (size_t i = 0; i < supported_versions.size(); ++i) {
- const ParsedQuicVersion& version = supported_versions[i];
- if (std::find(available_versions.begin(), available_versions.end(),
- version) != available_versions.end()) {
- framer_.set_version(version);
- return true;
- }
- }
-
- return false;
-}
-
-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) {
- return;
- }
- CloseConnection(framer->error(), framer->detailed_error(),
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
-}
-
-void QuicConnection::OnPacket() {
- last_packet_decrypted_ = false;
-}
-
-void QuicConnection::OnPublicResetPacket(const QuicPublicResetPacket& packet) {
- // Check that any public reset packet with a different connection ID that was
- // routed to this QuicConnection has been redirected before control reaches
- // here. (Check for a bug regression.)
- QUICHE_DCHECK_EQ(default_path_.server_connection_id, packet.connection_id);
- QUICHE_DCHECK_EQ(perspective_, Perspective::IS_CLIENT);
- QUICHE_DCHECK(!version().HasIetfInvariantHeader());
- if (debug_visitor_ != nullptr) {
- debug_visitor_->OnPublicResetPacket(packet);
- }
- std::string error_details = "Received public reset.";
- if (perspective_ == Perspective::IS_CLIENT && !packet.endpoint_id.empty()) {
- absl::StrAppend(&error_details, " From ", packet.endpoint_id, ".");
- }
- QUIC_DLOG(INFO) << ENDPOINT << error_details;
- QUIC_CODE_COUNT(quic_tear_down_local_connection_on_public_reset);
- TearDownLocalConnectionState(QUIC_PUBLIC_RESET, NO_IETF_QUIC_ERROR,
- error_details, ConnectionCloseSource::FROM_PEER);
-}
-
-bool QuicConnection::OnProtocolVersionMismatch(
- ParsedQuicVersion received_version) {
- QUIC_DLOG(INFO) << ENDPOINT << "Received packet with mismatched version "
- << ParsedQuicVersionToString(received_version);
- if (perspective_ == Perspective::IS_CLIENT) {
- const std::string error_details = "Protocol version mismatch.";
- QUIC_BUG(quic_bug_10511_3) << ENDPOINT << error_details;
- CloseConnection(QUIC_INTERNAL_ERROR, error_details,
- ConnectionCloseBehavior::SILENT_CLOSE);
- }
-
- // Server drops old packets that were sent by the client before the version
- // was negotiated.
- return false;
-}
-
-// Handles version negotiation for client connection.
-void QuicConnection::OnVersionNegotiationPacket(
- const QuicVersionNegotiationPacket& packet) {
- // Check that any public reset packet with a different connection ID that was
- // routed to this QuicConnection has been redirected before control reaches
- // here. (Check for a bug regression.)
- QUICHE_DCHECK_EQ(default_path_.server_connection_id, packet.connection_id);
- if (perspective_ == Perspective::IS_SERVER) {
- const std::string error_details =
- "Server received version negotiation packet.";
- QUIC_BUG(quic_bug_10511_4) << error_details;
- QUIC_CODE_COUNT(quic_tear_down_local_connection_on_version_negotiation);
- CloseConnection(QUIC_INTERNAL_ERROR, error_details,
- ConnectionCloseBehavior::SILENT_CLOSE);
- return;
- }
- if (debug_visitor_ != nullptr) {
- debug_visitor_->OnVersionNegotiationPacket(packet);
- }
-
- if (version_negotiated_) {
- // Possibly a duplicate version negotiation packet.
- return;
- }
-
- if (std::find(packet.versions.begin(), packet.versions.end(), version()) !=
- packet.versions.end()) {
- const std::string error_details = absl::StrCat(
- "Server already supports client's version ",
- ParsedQuicVersionToString(version()),
- " and should have accepted the connection instead of sending {",
- ParsedQuicVersionVectorToString(packet.versions), "}.");
- QUIC_DLOG(WARNING) << error_details;
- CloseConnection(QUIC_INVALID_VERSION_NEGOTIATION_PACKET, error_details,
- ConnectionCloseBehavior::SILENT_CLOSE);
- return;
- }
-
- server_supported_versions_ = packet.versions;
- CloseConnection(
- QUIC_INVALID_VERSION,
- absl::StrCat(
- "Client may support one of the versions in the server's list, but "
- "it's going to close the connection anyway. Supported versions: {",
- ParsedQuicVersionVectorToString(framer_.supported_versions()),
- "}, peer supported versions: {",
- ParsedQuicVersionVectorToString(packet.versions), "}"),
- ConnectionCloseBehavior::SILENT_CLOSE);
-}
-
-// Handles retry for client connection.
-void QuicConnection::OnRetryPacket(QuicConnectionId original_connection_id,
- QuicConnectionId new_connection_id,
- absl::string_view retry_token,
- absl::string_view retry_integrity_tag,
- absl::string_view retry_without_tag) {
- QUICHE_DCHECK_EQ(Perspective::IS_CLIENT, perspective_);
- if (version().UsesTls()) {
- if (!CryptoUtils::ValidateRetryIntegrityTag(
- version(), default_path_.server_connection_id, retry_without_tag,
- retry_integrity_tag)) {
- QUIC_DLOG(ERROR) << "Ignoring RETRY with invalid integrity tag";
- return;
- }
- } else {
- if (original_connection_id != default_path_.server_connection_id) {
- QUIC_DLOG(ERROR) << "Ignoring RETRY with original connection ID "
- << original_connection_id << " not matching expected "
- << default_path_.server_connection_id << " token "
- << absl::BytesToHexString(retry_token);
- return;
- }
- }
- framer_.set_drop_incoming_retry_packets(true);
- stats_.retry_packet_processed = true;
- QUIC_DLOG(INFO) << "Received RETRY, replacing connection ID "
- << default_path_.server_connection_id << " with "
- << new_connection_id << ", received token "
- << absl::BytesToHexString(retry_token);
- if (!original_destination_connection_id_.has_value()) {
- original_destination_connection_id_ = default_path_.server_connection_id;
- }
- QUICHE_DCHECK(!retry_source_connection_id_.has_value())
- << retry_source_connection_id_.value();
- retry_source_connection_id_ = new_connection_id;
- ReplaceInitialServerConnectionId(new_connection_id);
- packet_creator_.SetRetryToken(retry_token);
-
- // Reinstall initial crypters because the connection ID changed.
- InstallInitialCrypters(default_path_.server_connection_id);
-
- sent_packet_manager_.MarkInitialPacketsForRetransmission();
-}
-
-void QuicConnection::SetOriginalDestinationConnectionId(
- const QuicConnectionId& original_destination_connection_id) {
- QUIC_DLOG(INFO) << "Setting original_destination_connection_id to "
- << original_destination_connection_id
- << " on connection with server_connection_id "
- << default_path_.server_connection_id;
- QUICHE_DCHECK_NE(original_destination_connection_id,
- default_path_.server_connection_id);
- InstallInitialCrypters(original_destination_connection_id);
- QUICHE_DCHECK(!original_destination_connection_id_.has_value())
- << original_destination_connection_id_.value();
- original_destination_connection_id_ = original_destination_connection_id;
- original_destination_connection_id_replacement_ =
- default_path_.server_connection_id;
-}
-
-QuicConnectionId QuicConnection::GetOriginalDestinationConnectionId() {
- if (original_destination_connection_id_.has_value()) {
- return original_destination_connection_id_.value();
- }
- return default_path_.server_connection_id;
-}
-
-bool QuicConnection::ValidateServerConnectionId(
- const QuicPacketHeader& header) const {
- if (perspective_ == Perspective::IS_CLIENT &&
- header.form == IETF_QUIC_SHORT_HEADER_PACKET) {
- return true;
- }
-
- QuicConnectionId server_connection_id =
- GetServerConnectionIdAsRecipient(header, perspective_);
-
- if (server_connection_id == default_path_.server_connection_id ||
- server_connection_id == original_destination_connection_id_) {
- return true;
- }
-
- if (PacketCanReplaceServerConnectionId(header, perspective_)) {
- QUIC_DLOG(INFO) << ENDPOINT << "Accepting packet with new connection ID "
- << server_connection_id << " instead of "
- << default_path_.server_connection_id;
- return true;
- }
-
- if (connection_migration_use_new_cid_ &&
- perspective_ == Perspective::IS_SERVER &&
- self_issued_cid_manager_ != nullptr &&
- self_issued_cid_manager_->IsConnectionIdInUse(server_connection_id)) {
- return true;
- }
-
- return false;
-}
-
-bool QuicConnection::OnUnauthenticatedPublicHeader(
- const QuicPacketHeader& header) {
- last_packet_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_ ==
- *original_destination_connection_id_) {
- last_packet_destination_connection_id_ =
- original_destination_connection_id_replacement_;
- }
-
- // As soon as we receive an initial we start ignoring subsequent retries.
- if (header.version_flag && header.long_packet_type == INITIAL) {
- framer_.set_drop_incoming_retry_packets(true);
- }
-
- if (!ValidateServerConnectionId(header)) {
- ++stats_.packets_dropped;
- QuicConnectionId server_connection_id =
- GetServerConnectionIdAsRecipient(header, perspective_);
- QUIC_DLOG(INFO) << ENDPOINT
- << "Ignoring packet from unexpected server connection ID "
- << server_connection_id << " instead of "
- << default_path_.server_connection_id;
- if (debug_visitor_ != nullptr) {
- debug_visitor_->OnIncorrectConnectionId(server_connection_id);
- }
- // If this is a server, the dispatcher routes each packet to the
- // QuicConnection responsible for the packet's connection ID. So if control
- // arrives here and this is a server, the dispatcher must be malfunctioning.
- QUICHE_DCHECK_NE(Perspective::IS_SERVER, perspective_);
- return false;
- }
-
- if (!version().SupportsClientConnectionIds()) {
- return true;
- }
-
- if (perspective_ == Perspective::IS_SERVER &&
- header.form == IETF_QUIC_SHORT_HEADER_PACKET) {
- return true;
- }
-
- QuicConnectionId client_connection_id =
- GetClientConnectionIdAsRecipient(header, perspective_);
-
- if (client_connection_id == default_path_.client_connection_id) {
- return true;
- }
-
- if (!client_connection_id_is_set_ && perspective_ == Perspective::IS_SERVER) {
- QUIC_DLOG(INFO) << ENDPOINT
- << "Setting client connection ID from first packet to "
- << client_connection_id;
- set_client_connection_id(client_connection_id);
- return true;
- }
-
- if (connection_migration_use_new_cid_ &&
- perspective_ == Perspective::IS_CLIENT &&
- self_issued_cid_manager_ != nullptr &&
- self_issued_cid_manager_->IsConnectionIdInUse(client_connection_id)) {
- return true;
- }
-
- ++stats_.packets_dropped;
- QUIC_DLOG(INFO) << ENDPOINT
- << "Ignoring packet from unexpected client connection ID "
- << client_connection_id << " instead of "
- << default_path_.client_connection_id;
- return false;
-}
-
-bool QuicConnection::OnUnauthenticatedHeader(const QuicPacketHeader& header) {
- if (debug_visitor_ != nullptr) {
- debug_visitor_->OnUnauthenticatedHeader(header);
- }
-
- // Sanity check on the server connection ID in header.
- QUICHE_DCHECK(ValidateServerConnectionId(header));
-
- if (packet_creator_.HasPendingFrames()) {
- // Incoming packets may change a queued ACK frame.
- const std::string error_details =
- "Pending frames must be serialized before incoming packets are "
- "processed.";
- QUIC_BUG(quic_pending_frames_not_serialized)
- << error_details << ", received header: " << header;
- CloseConnection(QUIC_INTERNAL_ERROR, error_details,
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
- return false;
- }
-
- return true;
-}
-
-void QuicConnection::OnSuccessfulVersionNegotiation() {
- visitor_->OnSuccessfulVersionNegotiation(version());
- if (debug_visitor_ != nullptr) {
- debug_visitor_->OnSuccessfulVersionNegotiation(version());
- }
-}
-
-void QuicConnection::OnSuccessfulMigration(bool is_port_change) {
- QUICHE_DCHECK_EQ(perspective_, Perspective::IS_CLIENT);
- if (IsPathDegrading()) {
- // If path was previously degrading, and migration is successful after
- // probing, restart the path degrading and blackhole detection.
- OnForwardProgressMade();
- }
- if (IsAlternativePath(default_path_.self_address,
- default_path_.peer_address)) {
- // Reset alternative path state even if it is still under validation.
- alternative_path_.Clear();
- }
- // TODO(b/159074035): notify SentPacketManger with RTT sample from probing.
- if (version().HasIetfQuicFrames() && !is_port_change) {
- sent_packet_manager_.OnConnectionMigration(/*reset_send_algorithm=*/true);
- }
-}
-
-void QuicConnection::OnTransportParametersSent(
- const TransportParameters& transport_parameters) const {
- if (debug_visitor_ != nullptr) {
- debug_visitor_->OnTransportParametersSent(transport_parameters);
- }
-}
-
-void QuicConnection::OnTransportParametersReceived(
- const TransportParameters& transport_parameters) const {
- if (debug_visitor_ != nullptr) {
- debug_visitor_->OnTransportParametersReceived(transport_parameters);
- }
-}
-
-void QuicConnection::OnTransportParametersResumed(
- const TransportParameters& transport_parameters) const {
- if (debug_visitor_ != nullptr) {
- debug_visitor_->OnTransportParametersResumed(transport_parameters);
- }
-}
-
-bool QuicConnection::HasPendingAcks() const {
- return ack_alarm_->IsSet();
-}
-
-void QuicConnection::OnUserAgentIdKnown(const std::string& /*user_agent_id*/) {
- sent_packet_manager_.OnUserAgentIdKnown();
-}
-
-void QuicConnection::OnDecryptedPacket(size_t /*length*/,
- EncryptionLevel level) {
- last_decrypted_packet_level_ = level;
- last_packet_decrypted_ = true;
- if (level == ENCRYPTION_FORWARD_SECURE &&
- !have_decrypted_first_one_rtt_packet_) {
- have_decrypted_first_one_rtt_packet_ = true;
- if (version().UsesTls() && perspective_ == Perspective::IS_SERVER) {
- // Servers MAY temporarily retain 0-RTT keys to allow decrypting reordered
- // packets without requiring their contents to be retransmitted with 1-RTT
- // keys. After receiving a 1-RTT packet, servers MUST discard 0-RTT keys
- // within a short time; the RECOMMENDED time period is three times the
- // Probe Timeout.
- // https://quicwg.org/base-drafts/draft-ietf-quic-tls.html#name-discarding-0-rtt-keys
- discard_zero_rtt_decryption_keys_alarm_->Set(
- clock_->ApproximateNow() + sent_packet_manager_.GetPtoDelay() * 3);
- }
- }
- if (EnforceAntiAmplificationLimit() && !IsHandshakeConfirmed() &&
- (last_decrypted_packet_level_ == ENCRYPTION_HANDSHAKE ||
- last_decrypted_packet_level_ == ENCRYPTION_FORWARD_SECURE)) {
- // Address is validated by successfully processing a HANDSHAKE or 1-RTT
- // packet.
- default_path_.validated = true;
- stats_.address_validated_via_decrypting_packet = true;
- }
- idle_network_detector_.OnPacketReceived(
- last_received_packet_info_.receipt_time);
-
- visitor_->OnPacketDecrypted(level);
-}
-
-QuicSocketAddress QuicConnection::GetEffectivePeerAddressFromCurrentPacket()
- const {
- // By default, the connection is not proxied, and the effective peer address
- // is the packet's source address, i.e. the direct peer address.
- return last_received_packet_info_.source_address;
-}
-
-bool QuicConnection::OnPacketHeader(const QuicPacketHeader& header) {
- if (debug_visitor_ != nullptr) {
- debug_visitor_->OnPacketHeader(header, clock_->ApproximateNow(),
- last_decrypted_packet_level_);
- }
-
- // Will be decremented below if we fall through to return true.
- ++stats_.packets_dropped;
-
- if (!ProcessValidatedPacket(header)) {
- return false;
- }
-
- // 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;
- current_effective_peer_migration_type_ = NO_CHANGE;
-
- if (perspective_ == Perspective::IS_CLIENT) {
- if (!GetLargestReceivedPacket().IsInitialized() ||
- header.packet_number > GetLargestReceivedPacket()) {
- // Update direct_peer_address_ and default path peer_address immediately
- // for client connections.
- // TODO(fayang): only change peer addresses in application data packet
- // number space.
- UpdatePeerAddress(last_received_packet_info_.source_address);
- default_path_.peer_address = GetEffectivePeerAddressFromCurrentPacket();
- }
- } else {
- // At server, remember the address change type of effective_peer_address
- // in current_effective_peer_migration_type_. But this variable alone
- // doesn't necessarily starts a migration. A migration will be started
- // later, once the current packet is confirmed to meet the following
- // conditions:
- // 1) current_effective_peer_migration_type_ is not NO_CHANGE.
- // 2) The current packet is not a connectivity probing.
- // 3) The current packet is not reordered, i.e. its packet number is the
- // largest of this connection so far.
- // Once the above conditions are confirmed, a new migration will start
- // even if there is an active migration underway.
- current_effective_peer_migration_type_ =
- QuicUtils::DetermineAddressChangeType(
- default_path_.peer_address,
- GetEffectivePeerAddressFromCurrentPacket());
-
- if (connection_migration_use_new_cid_) {
- auto effective_peer_address = GetEffectivePeerAddressFromCurrentPacket();
- // Since server does not send new connection ID to client before handshake
- // completion and source connection ID is omitted in short header packet,
- // the server_connection_id on PathState on the server side does not
- // affect the packets server writes after handshake completion. On the
- // other hand, it is still desirable to have the "correct" server
- // 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.
- if (IsDefaultPath(last_received_packet_info_.destination_address,
- effective_peer_address)) {
- default_path_.server_connection_id =
- last_packet_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_;
- }
- }
-
- if (last_packet_destination_connection_id_ !=
- default_path_.server_connection_id &&
- (!original_destination_connection_id_.has_value() ||
- last_packet_destination_connection_id_ !=
- *original_destination_connection_id_)) {
- QUIC_CODE_COUNT(quic_connection_id_change);
- }
-
- QUIC_DLOG_IF(INFO, current_effective_peer_migration_type_ != NO_CHANGE)
- << ENDPOINT << "Effective peer's ip:port changed from "
- << default_path_.peer_address.ToString() << " to "
- << GetEffectivePeerAddressFromCurrentPacket().ToString()
- << ", active_effective_peer_migration_type is "
- << active_effective_peer_migration_type_;
- }
-
- --stats_.packets_dropped;
- QUIC_DVLOG(1) << ENDPOINT << "Received packet header: " << header;
- last_header_ = header;
- if (!stats_.first_decrypted_packet.IsInitialized()) {
- stats_.first_decrypted_packet = last_header_.packet_number;
- }
-
- // Record packet receipt to populate ack info before processing stream
- // frames, since the processing may result in sending a bundled ack.
- QuicTime receipt_time = idle_network_detector_.time_of_last_received_packet();
- if (reset_per_packet_state_for_undecryptable_packets_ &&
- SupportsMultiplePacketNumberSpaces()) {
- QUIC_RELOADABLE_FLAG_COUNT_N(
- quic_reset_per_packet_state_for_undecryptable_packets, 2, 2);
- receipt_time = last_received_packet_info_.receipt_time;
- }
- uber_received_packet_manager_.RecordPacketReceived(
- last_decrypted_packet_level_, last_header_, receipt_time);
- if (EnforceAntiAmplificationLimit() && !IsHandshakeConfirmed() &&
- !header.retry_token.empty() &&
- visitor_->ValidateToken(header.retry_token)) {
- QUIC_DLOG(INFO) << ENDPOINT << "Address validated via token.";
- QUIC_CODE_COUNT(quic_address_validated_via_token);
- default_path_.validated = true;
- stats_.address_validated_via_token = true;
- }
- QUICHE_DCHECK(connected_);
- return true;
-}
-
-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_;
-
- // Since a stream frame was received, this is not a connectivity probe.
- // A probe only contains a PING and full padding.
- if (!UpdatePacketContent(STREAM_FRAME)) {
- return false;
- }
-
- if (debug_visitor_ != nullptr) {
- debug_visitor_->OnStreamFrame(frame);
- }
- if (!QuicUtils::IsCryptoStreamId(transport_version(), frame.stream_id) &&
- last_decrypted_packet_level_ == ENCRYPTION_INITIAL) {
- if (MaybeConsiderAsMemoryCorruption(frame)) {
- CloseConnection(QUIC_MAYBE_CORRUPTED_MEMORY,
- "Received crypto frame on non crypto stream.",
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
- return false;
- }
-
- QUIC_PEER_BUG(quic_peer_bug_10511_6)
- << ENDPOINT << "Received an unencrypted data frame: closing connection"
- << " packet_number:" << last_header_.packet_number
- << " stream_id:" << frame.stream_id
- << " received_packets:" << ack_frame();
- CloseConnection(QUIC_UNENCRYPTED_STREAM_DATA,
- "Unencrypted stream data seen.",
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
- return false;
- }
- // TODO(fayang): Consider moving UpdatePacketContent and
- // MaybeUpdateAckTimeout to a stand-alone function instead of calling them for
- // all frames.
- MaybeUpdateAckTimeout();
- visitor_->OnStreamFrame(frame);
- stats_.stream_bytes_received += frame.data_length;
- 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_;
-
- // Since a CRYPTO frame was received, this is not a connectivity probe.
- // A probe only contains a PING and full padding.
- if (!UpdatePacketContent(CRYPTO_FRAME)) {
- return false;
- }
-
- if (debug_visitor_ != nullptr) {
- debug_visitor_->OnCryptoFrame(frame);
- }
- MaybeUpdateAckTimeout();
- visitor_->OnCryptoFrame(frame);
- return connected_;
-}
-
-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_;
-
- if (processing_ack_frame_) {
- CloseConnection(QUIC_INVALID_ACK_DATA,
- "Received a new ack while processing an ack frame.",
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
- return false;
- }
-
- // Since an ack frame was received, this is not a connectivity probe.
- // A probe only contains a PING and full padding.
- if (!UpdatePacketContent(ACK_FRAME)) {
- return false;
- }
-
- QUIC_DVLOG(1) << ENDPOINT
- << "OnAckFrameStart, largest_acked: " << largest_acked;
-
- if (GetLargestReceivedPacketWithAck().IsInitialized() &&
- last_header_.packet_number <= GetLargestReceivedPacketWithAck()) {
- QUIC_DLOG(INFO) << ENDPOINT << "Received an old ack frame: ignoring";
- return true;
- }
-
- if (!sent_packet_manager_.GetLargestSentPacket().IsInitialized() ||
- largest_acked > sent_packet_manager_.GetLargestSentPacket()) {
- QUIC_DLOG(WARNING) << ENDPOINT
- << "Peer's observed unsent packet:" << largest_acked
- << " vs " << sent_packet_manager_.GetLargestSentPacket()
- << ". SupportsMultiplePacketNumberSpaces():"
- << SupportsMultiplePacketNumberSpaces()
- << ", last_decrypted_packet_level_:"
- << last_decrypted_packet_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);
- return false;
- }
- processing_ack_frame_ = true;
- sent_packet_manager_.OnAckFrameStart(
- largest_acked, ack_delay_time,
- idle_network_detector_.time_of_last_received_packet());
- return true;
-}
-
-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_;
- QUIC_DVLOG(1) << ENDPOINT << "OnAckRange: [" << start << ", " << end << ")";
-
- if (GetLargestReceivedPacketWithAck().IsInitialized() &&
- last_header_.packet_number <= GetLargestReceivedPacketWithAck()) {
- QUIC_DLOG(INFO) << ENDPOINT << "Received an old ack frame: ignoring";
- return true;
- }
-
- sent_packet_manager_.OnAckRange(start, end);
- return true;
-}
-
-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_;
- QUIC_DVLOG(1) << ENDPOINT << "OnAckTimestamp: [" << packet_number << ", "
- << timestamp.ToDebuggingValue() << ")";
-
- if (GetLargestReceivedPacketWithAck().IsInitialized() &&
- last_header_.packet_number <= GetLargestReceivedPacketWithAck()) {
- QUIC_DLOG(INFO) << ENDPOINT << "Received an old ack frame: ignoring";
- return true;
- }
-
- sent_packet_manager_.OnAckTimestamp(packet_number, timestamp);
- return true;
-}
-
-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_;
- QUIC_DVLOG(1) << ENDPOINT << "OnAckFrameEnd, start: " << start;
-
- if (GetLargestReceivedPacketWithAck().IsInitialized() &&
- last_header_.packet_number <= GetLargestReceivedPacketWithAck()) {
- QUIC_DLOG(INFO) << ENDPOINT << "Received an old ack frame: ignoring";
- return true;
- }
- const bool one_rtt_packet_was_acked =
- sent_packet_manager_.one_rtt_packet_acked();
- const bool zero_rtt_packet_was_acked =
- 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_);
- 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
- // number space), and this would cause the connection to be closed.
- QUIC_DLOG(ERROR) << ENDPOINT
- << "Error occurred when processing an ACK frame: "
- << QuicUtils::AckResultToString(ack_result);
- return false;
- }
- if (SupportsMultiplePacketNumberSpaces() && !one_rtt_packet_was_acked &&
- sent_packet_manager_.one_rtt_packet_acked()) {
- visitor_->OnOneRttPacketAcknowledged();
- }
- if (debug_visitor_ != nullptr && version().UsesTls() &&
- !zero_rtt_packet_was_acked &&
- sent_packet_manager_.zero_rtt_packet_acked()) {
- debug_visitor_->OnZeroRttPacketAcked();
- }
- // Cancel the send alarm because new packets likely have been acked, which
- // may change the congestion window and/or pacing rate. Canceling the alarm
- // causes CanWrite to recalculate the next send time.
- if (send_alarm_->IsSet()) {
- send_alarm_->Cancel();
- }
- if (supports_release_time_) {
- // Update pace time into future because smoothed RTT is likely updated.
- UpdateReleaseTimeIntoFuture();
- }
- SetLargestReceivedPacketWithAck(last_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.
- // If the incoming ack's packets set expresses received packets: peer is still
- // acking packets which we never care about.
- // Send an ack to raise the high water mark.
- const bool send_stop_waiting =
- no_stop_waiting_frames_ ? false : GetLeastUnacked() > start;
- PostProcessAfterAckFrame(send_stop_waiting,
- ack_result == PACKETS_NEWLY_ACKED);
- processing_ack_frame_ = false;
- return connected_;
-}
-
-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_;
-
- // Since a stop waiting frame was received, this is not a connectivity probe.
- // A probe only contains a PING and full padding.
- if (!UpdatePacketContent(STOP_WAITING_FRAME)) {
- return false;
- }
-
- if (no_stop_waiting_frames_) {
- return true;
- }
- if (largest_seen_packet_with_stop_waiting_.IsInitialized() &&
- last_header_.packet_number <= largest_seen_packet_with_stop_waiting_) {
- QUIC_DLOG(INFO) << ENDPOINT
- << "Received an old stop waiting frame: ignoring";
- return true;
- }
-
- const char* error = ValidateStopWaitingFrame(frame);
- if (error != nullptr) {
- CloseConnection(QUIC_INVALID_STOP_WAITING_DATA, error,
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
- return false;
- }
-
- if (debug_visitor_ != nullptr) {
- debug_visitor_->OnStopWaitingFrame(frame);
- }
-
- largest_seen_packet_with_stop_waiting_ = last_header_.packet_number;
- uber_received_packet_manager_.DontWaitForPacketsBefore(
- last_decrypted_packet_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_;
- if (!UpdatePacketContent(PADDING_FRAME)) {
- return false;
- }
-
- if (debug_visitor_ != nullptr) {
- debug_visitor_->OnPaddingFrame(frame);
- }
- return true;
-}
-
-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_;
- if (!UpdatePacketContent(PING_FRAME)) {
- return false;
- }
-
- if (debug_visitor_ != nullptr) {
- QuicTime::Delta ping_received_delay = QuicTime::Delta::Zero();
- const QuicTime now = clock_->ApproximateNow();
- if (now > stats_.connection_creation_time) {
- ping_received_delay = now - stats_.connection_creation_time;
- }
- debug_visitor_->OnPingFrame(frame, ping_received_delay);
- }
- MaybeUpdateAckTimeout();
- return true;
-}
-
-const char* QuicConnection::ValidateStopWaitingFrame(
- const QuicStopWaitingFrame& stop_waiting) {
- const QuicPacketNumber peer_least_packet_awaiting_ack =
- uber_received_packet_manager_.peer_least_packet_awaiting_ack();
- if (peer_least_packet_awaiting_ack.IsInitialized() &&
- stop_waiting.least_unacked < peer_least_packet_awaiting_ack) {
- QUIC_DLOG(ERROR) << ENDPOINT << "Peer's sent low least_unacked: "
- << stop_waiting.least_unacked << " vs "
- << peer_least_packet_awaiting_ack;
- // We never process old ack frames, so this number should only increase.
- return "Least unacked too small.";
- }
-
- if (stop_waiting.least_unacked > last_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;
- return "Least unacked too large.";
- }
-
- return nullptr;
-}
-
-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_;
-
- // Since a reset stream frame was received, this is not a connectivity probe.
- // A probe only contains a PING and full padding.
- if (!UpdatePacketContent(RST_STREAM_FRAME)) {
- return false;
- }
-
- if (debug_visitor_ != nullptr) {
- debug_visitor_->OnRstStreamFrame(frame);
- }
- QUIC_DLOG(INFO) << ENDPOINT
- << "RST_STREAM_FRAME received for stream: " << frame.stream_id
- << " with error: "
- << QuicRstStreamErrorCodeToString(frame.error_code);
- MaybeUpdateAckTimeout();
- visitor_->OnRstStream(frame);
- return connected_;
-}
-
-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_;
-
- // Since a reset stream frame was received, this is not a connectivity probe.
- // A probe only contains a PING and full padding.
- if (!UpdatePacketContent(STOP_SENDING_FRAME)) {
- return false;
- }
-
- if (debug_visitor_ != nullptr) {
- debug_visitor_->OnStopSendingFrame(frame);
- }
-
- QUIC_DLOG(INFO) << ENDPOINT << "STOP_SENDING frame received for stream: "
- << frame.stream_id
- << " with error: " << frame.ietf_error_code;
- MaybeUpdateAckTimeout();
- visitor_->OnStopSendingFrame(frame);
- return connected_;
-}
-
-class ReversePathValidationContext : public QuicPathValidationContext {
- public:
- ReversePathValidationContext(const QuicSocketAddress& self_address,
- const QuicSocketAddress& peer_address,
- const QuicSocketAddress& effective_peer_address,
- QuicConnection* connection)
- : QuicPathValidationContext(self_address,
- peer_address,
- effective_peer_address),
- connection_(connection) {}
-
- QuicPacketWriter* WriterToUse() override { return connection_->writer(); }
-
- private:
- QuicConnection* connection_;
-};
-
-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_;
- if (has_path_challenge_in_current_packet_) {
- QUICHE_DCHECK(send_path_response_);
- QUIC_RELOADABLE_FLAG_COUNT_N(quic_send_path_response2, 2, 5);
- // Only respond to the 1st PATH_CHALLENGE in the packet.
- return true;
- }
- 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.
- if (!OnPathChallengeFrameInternal(frame)) {
- return false;
- }
- }
- return connected_;
-}
-
-bool QuicConnection::OnPathChallengeFrameInternal(
- const QuicPathChallengeFrame& frame) {
- should_proactively_validate_peer_address_on_path_challenge_ = false;
- // UpdatePacketContent() may start reverse path validation.
- if (!UpdatePacketContent(PATH_CHALLENGE_FRAME)) {
- return false;
- }
- if (debug_visitor_ != nullptr) {
- debug_visitor_->OnPathChallengeFrame(frame);
- }
-
- const QuicSocketAddress current_effective_peer_address =
- GetEffectivePeerAddressFromCurrentPacket();
- QuicConnectionId client_cid, server_cid;
- FindOnPathConnectionIds(last_received_packet_info_.destination_address,
- current_effective_peer_address, &client_cid,
- &server_cid);
- QuicPacketCreator::ScopedPeerAddressContext context(
- &packet_creator_, last_received_packet_info_.source_address, client_cid,
- server_cid, connection_migration_use_new_cid_);
- if (should_proactively_validate_peer_address_on_path_challenge_) {
- // Conditions to proactively validate peer address:
- // The perspective is server
- // The PATH_CHALLENGE is received on an unvalidated alternative path.
- // The connection isn't validating migrated peer address, which is of
- // higher prority.
- QUIC_DVLOG(1) << "Proactively validate the effective peer address "
- << current_effective_peer_address;
- QUIC_CODE_COUNT_N(quic_kick_off_client_address_validation, 2, 6);
- ValidatePath(std::make_unique<ReversePathValidationContext>(
- default_path_.self_address,
- last_received_packet_info_.source_address,
- current_effective_peer_address, this),
- std::make_unique<ReversePathValidationResultDelegate>(
- this, peer_address()));
- }
- if (!send_path_response_) {
- // Save the path challenge's payload, for later use in generating the
- // response.
- received_path_challenge_payloads_.push_back(frame.data_buffer);
-
- MaybeUpdateAckTimeout();
- return true;
- }
- QUIC_RELOADABLE_FLAG_COUNT_N(quic_send_path_response2, 3, 5);
- has_path_challenge_in_current_packet_ = true;
- MaybeUpdateAckTimeout();
- // Queue or send PATH_RESPONSE. Send PATH_RESPONSE to the source address of
- // the current incoming packet, even if it's not the default path or the
- // alternative path.
- if (!SendPathResponse(frame.data_buffer,
- last_received_packet_info_.source_address,
- current_effective_peer_address)) {
- QUIC_CODE_COUNT(quic_failed_to_send_path_response);
- }
- // TODO(b/150095588): change the stats to
- // num_valid_path_challenge_received.
- ++stats_.num_connectivity_probing_received;
-
- // SendPathResponse() might cause connection to be closed.
- return connected_;
-}
-
-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_;
- if (!UpdatePacketContent(PATH_RESPONSE_FRAME)) {
- return false;
- }
- if (debug_visitor_ != nullptr) {
- debug_visitor_->OnPathResponseFrame(frame);
- }
- MaybeUpdateAckTimeout();
- if (use_path_validator_) {
- QUIC_RELOADABLE_FLAG_COUNT_N(quic_pass_path_response_to_validator, 1, 4);
- path_validator_.OnPathResponse(
- frame.data_buffer, last_received_packet_info_.destination_address);
- } else {
- if (!transmitted_connectivity_probe_payload_ ||
- *transmitted_connectivity_probe_payload_ != frame.data_buffer) {
- // Is not for the probe we sent, ignore it.
- return true;
- }
- // Have received the matching PATH RESPONSE, saved payload no longer valid.
- transmitted_connectivity_probe_payload_ = nullptr;
- }
- return connected_;
-}
-
-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_;
-
- // Since a connection close frame was received, this is not a connectivity
- // probe. A probe only contains a PING and full padding.
- if (!UpdatePacketContent(CONNECTION_CLOSE_FRAME)) {
- return false;
- }
-
- if (debug_visitor_ != nullptr) {
- debug_visitor_->OnConnectionCloseFrame(frame);
- }
- switch (frame.close_type) {
- case GOOGLE_QUIC_CONNECTION_CLOSE:
- QUIC_DLOG(INFO) << ENDPOINT << "Received ConnectionClose for connection: "
- << connection_id() << ", with error: "
- << QuicErrorCodeToString(frame.quic_error_code) << " ("
- << frame.error_details << ")";
- break;
- case IETF_QUIC_TRANSPORT_CONNECTION_CLOSE:
- QUIC_DLOG(INFO) << ENDPOINT
- << "Received Transport ConnectionClose for connection: "
- << connection_id() << ", with error: "
- << QuicErrorCodeToString(frame.quic_error_code) << " ("
- << frame.error_details << ")"
- << ", transport error code: "
- << QuicIetfTransportErrorCodeString(
- static_cast<QuicIetfTransportErrorCodes>(
- frame.wire_error_code))
- << ", error frame type: "
- << frame.transport_close_frame_type;
- break;
- case IETF_QUIC_APPLICATION_CONNECTION_CLOSE:
- QUIC_DLOG(INFO) << ENDPOINT
- << "Received Application ConnectionClose for connection: "
- << connection_id() << ", with error: "
- << QuicErrorCodeToString(frame.quic_error_code) << " ("
- << frame.error_details << ")"
- << ", application error code: " << frame.wire_error_code;
- break;
- }
-
- 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_;
- }
- TearDownLocalConnectionState(frame, ConnectionCloseSource::FROM_PEER);
- return connected_;
-}
-
-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_;
- if (!UpdatePacketContent(MAX_STREAMS_FRAME)) {
- return false;
- }
-
- if (debug_visitor_ != nullptr) {
- debug_visitor_->OnMaxStreamsFrame(frame);
- }
- MaybeUpdateAckTimeout();
- return visitor_->OnMaxStreamsFrame(frame) && connected_;
-}
-
-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_;
- if (!UpdatePacketContent(STREAMS_BLOCKED_FRAME)) {
- return false;
- }
-
- if (debug_visitor_ != nullptr) {
- debug_visitor_->OnStreamsBlockedFrame(frame);
- }
- MaybeUpdateAckTimeout();
- return visitor_->OnStreamsBlockedFrame(frame) && connected_;
-}
-
-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_;
-
- // Since a go away frame was received, this is not a connectivity probe.
- // A probe only contains a PING and full padding.
- if (!UpdatePacketContent(GOAWAY_FRAME)) {
- return false;
- }
-
- if (debug_visitor_ != nullptr) {
- debug_visitor_->OnGoAwayFrame(frame);
- }
- QUIC_DLOG(INFO) << ENDPOINT << "GOAWAY_FRAME received with last good stream: "
- << frame.last_good_stream_id
- << " and error: " << QuicErrorCodeToString(frame.error_code)
- << " and reason: " << frame.reason_phrase;
- MaybeUpdateAckTimeout();
- visitor_->OnGoAway(frame);
- return connected_;
-}
-
-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_;
-
- // Since a window update frame was received, this is not a connectivity probe.
- // A probe only contains a PING and full padding.
- if (!UpdatePacketContent(WINDOW_UPDATE_FRAME)) {
- return false;
- }
-
- if (debug_visitor_ != nullptr) {
- debug_visitor_->OnWindowUpdateFrame(
- frame, idle_network_detector_.time_of_last_received_packet());
- }
- QUIC_DVLOG(1) << ENDPOINT << "WINDOW_UPDATE_FRAME received " << frame;
- MaybeUpdateAckTimeout();
- visitor_->OnWindowUpdateFrame(frame);
- return connected_;
-}
-
-void QuicConnection::OnClientConnectionIdAvailable() {
- QUICHE_DCHECK(perspective_ == Perspective::IS_SERVER);
- if (!peer_issued_cid_manager_->HasUnusedConnectionId()) {
- return;
- }
- if (default_path_.client_connection_id.IsEmpty()) {
- // Count client connection ID patched onto the default path.
- QUIC_RELOADABLE_FLAG_COUNT_N(quic_connection_migration_use_new_cid_v2, 3,
- 6);
- const QuicConnectionIdData* unused_cid_data =
- peer_issued_cid_manager_->ConsumeOneUnusedConnectionId();
- QUIC_DVLOG(1) << ENDPOINT << "Patch connection ID "
- << unused_cid_data->connection_id << " to default path";
- default_path_.client_connection_id = unused_cid_data->connection_id;
- default_path_.stateless_reset_token =
- unused_cid_data->stateless_reset_token;
- QUICHE_DCHECK(!packet_creator_.HasPendingFrames());
- QUICHE_DCHECK(packet_creator_.GetDestinationConnectionId().IsEmpty());
- packet_creator_.SetClientConnectionId(default_path_.client_connection_id);
- return;
- }
- if (alternative_path_.peer_address.IsInitialized() &&
- alternative_path_.client_connection_id.IsEmpty()) {
- // Count client connection ID patched onto the alternative path.
- QUIC_RELOADABLE_FLAG_COUNT_N(quic_connection_migration_use_new_cid_v2, 4,
- 6);
- const QuicConnectionIdData* unused_cid_data =
- peer_issued_cid_manager_->ConsumeOneUnusedConnectionId();
- QUIC_DVLOG(1) << ENDPOINT << "Patch connection ID "
- << unused_cid_data->connection_id << " to alternative path";
- alternative_path_.client_connection_id = unused_cid_data->connection_id;
- alternative_path_.stateless_reset_token =
- unused_cid_data->stateless_reset_token;
- }
-}
-
-bool QuicConnection::ShouldSetRetransmissionAlarmOnPacketSent(
- bool in_flight, EncryptionLevel level) const {
- 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) {
- CloseConnection(
- IETF_QUIC_PROTOCOL_VIOLATION,
- "Receives NEW_CONNECTION_ID while peer uses zero length connection ID",
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
- return false;
- }
- std::string error_detail;
- QuicErrorCode error =
- peer_issued_cid_manager_->OnNewConnectionIdFrame(frame, &error_detail);
- if (error != QUIC_NO_ERROR) {
- CloseConnection(error, error_detail,
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
- return false;
- }
- if (perspective_ == Perspective::IS_SERVER) {
- OnClientConnectionIdAvailable();
- }
- MaybeUpdateAckTimeout();
- return true;
-}
-
-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_;
- if (!UpdatePacketContent(NEW_CONNECTION_ID_FRAME)) {
- return false;
- }
-
- if (debug_visitor_ != nullptr) {
- debug_visitor_->OnNewConnectionIdFrame(frame);
- }
- return OnNewConnectionIdFrameInner(frame);
-}
-
-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_;
- if (!UpdatePacketContent(RETIRE_CONNECTION_ID_FRAME)) {
- return false;
- }
-
- if (debug_visitor_ != nullptr) {
- debug_visitor_->OnRetireConnectionIdFrame(frame);
- }
- if (!connection_migration_use_new_cid_) {
- // Do not respond to RetireConnectionId frame.
- return true;
- }
- if (self_issued_cid_manager_ == nullptr) {
- CloseConnection(
- IETF_QUIC_PROTOCOL_VIOLATION,
- "Receives RETIRE_CONNECTION_ID while new connection ID is never issued",
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
- return false;
- }
- std::string error_detail;
- QuicErrorCode error = self_issued_cid_manager_->OnRetireConnectionIdFrame(
- frame, sent_packet_manager_.GetPtoDelay(), &error_detail);
- if (error != QUIC_NO_ERROR) {
- CloseConnection(error, error_detail,
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
- return false;
- }
- // Count successfully received RETIRE_CONNECTION_ID frames.
- QUIC_RELOADABLE_FLAG_COUNT_N(quic_connection_migration_use_new_cid_v2, 5, 6);
- MaybeUpdateAckTimeout();
- return true;
-}
-
-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_;
- if (!UpdatePacketContent(NEW_TOKEN_FRAME)) {
- return false;
- }
-
- if (debug_visitor_ != nullptr) {
- debug_visitor_->OnNewTokenFrame(frame);
- }
- if (perspective_ == Perspective::IS_SERVER) {
- CloseConnection(QUIC_INVALID_NEW_TOKEN, "Server received new token frame.",
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
- return false;
- }
- // NEW_TOKEN frame should insitgate ACKs.
- MaybeUpdateAckTimeout();
- visitor_->OnNewTokenReceived(frame.token);
- return true;
-}
-
-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_;
-
- // Since a message frame was received, this is not a connectivity probe.
- // A probe only contains a PING and full padding.
- if (!UpdatePacketContent(MESSAGE_FRAME)) {
- return false;
- }
-
- if (debug_visitor_ != nullptr) {
- debug_visitor_->OnMessageFrame(frame);
- }
- MaybeUpdateAckTimeout();
- visitor_->OnMessageReceived(
- absl::string_view(frame.data, frame.message_length));
- return connected_;
-}
-
-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_;
- if (!version().UsesTls()) {
- CloseConnection(IETF_QUIC_PROTOCOL_VIOLATION,
- "Handshake done frame is unsupported",
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
- return false;
- }
-
- if (perspective_ == Perspective::IS_SERVER) {
- CloseConnection(IETF_QUIC_PROTOCOL_VIOLATION,
- "Server received handshake done frame.",
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
- return false;
- }
-
- // Since a handshake done frame was received, this is not a connectivity
- // probe. A probe only contains a PING and full padding.
- if (!UpdatePacketContent(HANDSHAKE_DONE_FRAME)) {
- return false;
- }
-
- if (debug_visitor_ != nullptr) {
- debug_visitor_->OnHandshakeDoneFrame(frame);
- }
- MaybeUpdateAckTimeout();
- visitor_->OnHandshakeDoneReceived();
- return connected_;
-}
-
-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_;
- if (debug_visitor_ != nullptr) {
- debug_visitor_->OnAckFrequencyFrame(frame);
- }
- if (!UpdatePacketContent(ACK_FREQUENCY_FRAME)) {
- return false;
- }
-
- if (!can_receive_ack_frequency_frame_) {
- QUIC_LOG_EVERY_N_SEC(ERROR, 120) << "Get unexpected AckFrequencyFrame.";
- return false;
- }
- if (auto packet_number_space =
- QuicUtils::GetPacketNumberSpace(last_decrypted_packet_level_) ==
- APPLICATION_DATA) {
- uber_received_packet_manager_.OnAckFrequencyFrame(frame);
- } else {
- QUIC_LOG_EVERY_N_SEC(ERROR, 120)
- << "Get AckFrequencyFrame in packet number space "
- << packet_number_space;
- }
- MaybeUpdateAckTimeout();
- return true;
-}
-
-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_;
-
- // Since a blocked frame was received, this is not a connectivity probe.
- // A probe only contains a PING and full padding.
- if (!UpdatePacketContent(BLOCKED_FRAME)) {
- return false;
- }
-
- if (debug_visitor_ != nullptr) {
- debug_visitor_->OnBlockedFrame(frame);
- }
- QUIC_DLOG(INFO) << ENDPOINT
- << "BLOCKED_FRAME received for stream: " << frame.stream_id;
- MaybeUpdateAckTimeout();
- visitor_->OnBlockedFrame(frame);
- stats_.blocked_frames_received++;
- return connected_;
-}
-
-void QuicConnection::OnPacketComplete() {
- // Don't do anything if this packet closed the connection.
- if (!connected_) {
- ClearLastFrames();
- return;
- }
-
- if (IsCurrentPacketConnectivityProbing()) {
- QUICHE_DCHECK(!version().HasIetfQuicFrames());
- ++stats_.num_connectivity_probing_received;
- }
-
- QUIC_DVLOG(1) << ENDPOINT << "Got"
- << (SupportsMultiplePacketNumberSpaces()
- ? (" " + EncryptionLevelToString(
- last_decrypted_packet_level_))
- : "")
- << " packet " << last_header_.packet_number << " for "
- << GetServerConnectionIdAsRecipient(last_header_, perspective_);
-
- QUIC_DLOG_IF(INFO, current_packet_content_ == SECOND_FRAME_IS_PADDING)
- << ENDPOINT << "Received a padded PING packet. is_probing: "
- << IsCurrentPacketConnectivityProbing();
-
- MaybeRespondToConnectivityProbingOrMigration();
-
- current_effective_peer_migration_type_ = NO_CHANGE;
-
- // For IETF QUIC, it is guaranteed that TLS will give connection the
- // corresponding write key before read key. In other words, connection should
- // never process a packet while an ACK for it cannot be encrypted.
- if (!should_last_packet_instigate_acks_) {
- uber_received_packet_manager_.MaybeUpdateAckTimeout(
- should_last_packet_instigate_acks_, last_decrypted_packet_level_,
- last_header_.packet_number, clock_->ApproximateNow(),
- sent_packet_manager_.GetRttStats());
- }
-
- ClearLastFrames();
- CloseIfTooManyOutstandingSentPackets();
-}
-
-void QuicConnection::MaybeRespondToConnectivityProbingOrMigration() {
- if (version().HasIetfQuicFrames()) {
- if (send_path_response_) {
- return;
- }
- if (perspective_ == Perspective::IS_CLIENT) {
- // This node is a client, notify that a speculative connectivity probing
- // packet has been received anyway.
- visitor_->OnPacketReceived(last_received_packet_info_.destination_address,
- last_received_packet_info_.source_address,
- /*is_connectivity_probe=*/false);
- return;
- }
- if (!received_path_challenge_payloads_.empty()) {
- if (current_effective_peer_migration_type_ != NO_CHANGE) {
- // TODO(b/150095588): change the stats to
- // num_valid_path_challenge_received.
- ++stats_.num_connectivity_probing_received;
- }
- // If the packet contains PATH CHALLENGE, send appropriate RESPONSE.
- // There was at least one PATH CHALLENGE in the received packet,
- // Generate the required PATH RESPONSE.
- SendGenericPathProbePacket(nullptr,
- last_received_packet_info_.source_address,
- /* is_response=*/true);
- return;
- }
- } else {
- if (IsCurrentPacketConnectivityProbing()) {
- visitor_->OnPacketReceived(last_received_packet_info_.destination_address,
- last_received_packet_info_.source_address,
- /*is_connectivity_probe=*/true);
- return;
- }
- if (perspective_ == Perspective::IS_CLIENT) {
- // This node is a client, notify that a speculative connectivity probing
- // packet has been received anyway.
- QUIC_DVLOG(1)
- << ENDPOINT
- << "Received a speculative connectivity probing packet for "
- << GetServerConnectionIdAsRecipient(last_header_, perspective_)
- << " from ip:port: "
- << last_received_packet_info_.source_address.ToString()
- << " to ip:port: "
- << last_received_packet_info_.destination_address.ToString();
- visitor_->OnPacketReceived(last_received_packet_info_.destination_address,
- last_received_packet_info_.source_address,
- /*is_connectivity_probe=*/false);
- return;
- }
- }
-}
-
-bool QuicConnection::IsValidStatelessResetToken(
- const StatelessResetToken& token) const {
- QUICHE_DCHECK_EQ(perspective_, Perspective::IS_CLIENT);
- return default_path_.stateless_reset_token.has_value() &&
- QuicUtils::AreStatelessResetTokensEqual(
- token, *default_path_.stateless_reset_token);
-}
-
-void QuicConnection::OnAuthenticatedIetfStatelessResetPacket(
- const QuicIetfStatelessResetPacket& /*packet*/) {
- // TODO(fayang): Add OnAuthenticatedIetfStatelessResetPacket to
- // debug_visitor_.
- QUICHE_DCHECK(version().HasIetfInvariantHeader());
- QUICHE_DCHECK_EQ(perspective_, Perspective::IS_CLIENT);
-
- if (use_path_validator_) {
- QUIC_RELOADABLE_FLAG_COUNT_N(quic_pass_path_response_to_validator, 4, 4);
- if (!IsDefaultPath(last_received_packet_info_.destination_address,
- last_received_packet_info_.source_address)) {
- // This packet is received on a probing path. Do not close connection.
- if (IsAlternativePath(last_received_packet_info_.destination_address,
- GetEffectivePeerAddressFromCurrentPacket())) {
- QUIC_BUG_IF(quic_bug_12714_18, alternative_path_.validated)
- << "STATELESS_RESET received on alternate path after it's "
- "validated.";
- path_validator_.CancelPathValidation();
- } else {
- QUIC_BUG(quic_bug_10511_17)
- << "Received Stateless Reset on unknown socket.";
- }
- return;
- }
- } else if (!visitor_->ValidateStatelessReset(
- last_received_packet_info_.destination_address,
- last_received_packet_info_.source_address)) {
- // This packet is received on a probing path. Do not close connection.
- return;
- }
-
- const std::string error_details = "Received stateless reset.";
- QUIC_CODE_COUNT(quic_tear_down_local_connection_on_stateless_reset);
- TearDownLocalConnectionState(QUIC_PUBLIC_RESET, NO_IETF_QUIC_ERROR,
- error_details, ConnectionCloseSource::FROM_PEER);
-}
-
-void QuicConnection::OnKeyUpdate(KeyUpdateReason reason) {
- QUICHE_DCHECK(support_key_update_for_connection_);
- QUIC_DLOG(INFO) << ENDPOINT << "Key phase updated for " << reason;
-
- lowest_packet_sent_in_current_key_phase_.Clear();
- stats_.key_update_count++;
-
- // If another key update triggers while the previous
- // discard_previous_one_rtt_keys_alarm_ hasn't fired yet, cancel it since the
- // old keys would already be discarded.
- discard_previous_one_rtt_keys_alarm_->Cancel();
-
- visitor_->OnKeyUpdate(reason);
-}
-
-void QuicConnection::OnDecryptedFirstPacketInKeyPhase() {
- QUIC_DLOG(INFO) << ENDPOINT << "OnDecryptedFirstPacketInKeyPhase";
- // An endpoint SHOULD retain old read keys for no more than three times the
- // PTO after having received a packet protected using the new keys. After this
- // period, old read keys and their corresponding secrets SHOULD be discarded.
- //
- // Note that this will cause an unnecessary
- // discard_previous_one_rtt_keys_alarm_ on the first packet in the 1RTT
- // encryption level, but this is harmless.
- discard_previous_one_rtt_keys_alarm_->Set(
- clock_->ApproximateNow() + sent_packet_manager_.GetPtoDelay() * 3);
-}
-
-std::unique_ptr<QuicDecrypter>
-QuicConnection::AdvanceKeysAndCreateCurrentOneRttDecrypter() {
- QUIC_DLOG(INFO) << ENDPOINT << "AdvanceKeysAndCreateCurrentOneRttDecrypter";
- return visitor_->AdvanceKeysAndCreateCurrentOneRttDecrypter();
-}
-
-std::unique_ptr<QuicEncrypter> QuicConnection::CreateCurrentOneRttEncrypter() {
- QUIC_DLOG(INFO) << ENDPOINT << "CreateCurrentOneRttEncrypter";
- return visitor_->CreateCurrentOneRttEncrypter();
-}
-
-void QuicConnection::ClearLastFrames() {
- should_last_packet_instigate_acks_ = false;
-}
-
-void QuicConnection::CloseIfTooManyOutstandingSentPackets() {
- // This occurs if we don't discard old packets we've seen fast enough. It's
- // possible largest observed is less than leaset unacked.
- const bool should_close =
- sent_packet_manager_.GetLargestSentPacket().IsInitialized() &&
- sent_packet_manager_.GetLargestSentPacket() >
- sent_packet_manager_.GetLeastUnacked() + max_tracked_packets_;
-
- if (should_close) {
- CloseConnection(
- QUIC_TOO_MANY_OUTSTANDING_SENT_PACKETS,
- absl::StrCat("More than ", max_tracked_packets_,
- " outstanding, least_unacked: ",
- sent_packet_manager_.GetLeastUnacked().ToUint64(),
- ", packets_processed: ", stats_.packets_processed,
- ", last_decrypted_packet_level: ",
- EncryptionLevelToString(last_decrypted_packet_level_)),
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
- }
-}
-
-const QuicFrame QuicConnection::GetUpdatedAckFrame() {
- QUICHE_DCHECK(!uber_received_packet_manager_.IsAckFrameEmpty(
- QuicUtils::GetPacketNumberSpace(encryption_level_)))
- << "Try to retrieve an empty ACK frame";
- return uber_received_packet_manager_.GetUpdatedAckFrame(
- QuicUtils::GetPacketNumberSpace(encryption_level_),
- clock_->ApproximateNow());
-}
-
-void QuicConnection::PopulateStopWaitingFrame(
- QuicStopWaitingFrame* stop_waiting) {
- stop_waiting->least_unacked = GetLeastUnacked();
-}
-
-QuicPacketNumber QuicConnection::GetLeastUnacked() const {
- return sent_packet_manager_.GetLeastUnacked();
-}
-
-bool QuicConnection::HandleWriteBlocked() {
- if (!writer_->IsWriteBlocked()) {
- return false;
- }
-
- visitor_->OnWriteBlocked();
- return true;
-}
-
-void QuicConnection::MaybeSendInResponseToPacket() {
- if (!connected_) {
- return;
- }
-
- // If the writer is blocked, don't attempt to send packets now or in the send
- // alarm. When the writer unblocks, OnCanWrite() will be called for this
- // connection to send.
- if (HandleWriteBlocked()) {
- return;
- }
-
- // Now that we have received an ack, we might be able to send packets which
- // are queued locally, or drain streams which are blocked.
- if (defer_send_in_response_to_packets_) {
- send_alarm_->Update(clock_->ApproximateNow(), QuicTime::Delta::Zero());
- } else {
- WriteIfNotBlocked();
- }
-}
-
-void QuicConnection::MaybeActivateLegacyVersionEncapsulation() {
- if (!legacy_version_encapsulation_enabled_) {
- return;
- }
- QUICHE_DCHECK(!legacy_version_encapsulation_in_progress_);
- QUIC_BUG_IF(quic_bug_12714_19, !packet_creator_.CanSetMaxPacketLength())
- << "Cannot activate Legacy Version Encapsulation mid-packet";
- QUIC_BUG_IF(quic_bug_12714_20, coalesced_packet_.length() != 0u)
- << "Cannot activate Legacy Version Encapsulation mid-coalesced-packet";
- legacy_version_encapsulation_in_progress_ = true;
- MaybeUpdatePacketCreatorMaxPacketLengthAndPadding();
-}
-void QuicConnection::MaybeDisactivateLegacyVersionEncapsulation() {
- if (!legacy_version_encapsulation_in_progress_) {
- return;
- }
- // Flush any remaining packet before disactivating encapsulation.
- packet_creator_.FlushCurrentPacket();
- QUICHE_DCHECK(legacy_version_encapsulation_enabled_);
- legacy_version_encapsulation_in_progress_ = false;
- MaybeUpdatePacketCreatorMaxPacketLengthAndPadding();
-}
-
-size_t QuicConnection::SendCryptoData(EncryptionLevel level,
- size_t write_length,
- QuicStreamOffset offset) {
- if (write_length == 0) {
- QUIC_BUG(quic_bug_10511_18) << "Attempt to send empty crypto frame";
- return 0;
- }
- if (level == ENCRYPTION_INITIAL) {
- MaybeActivateLegacyVersionEncapsulation();
- }
- size_t consumed_length;
- {
- ScopedPacketFlusher flusher(this);
- consumed_length =
- packet_creator_.ConsumeCryptoData(level, write_length, offset);
- } // Added scope ensures packets are flushed before continuing.
- MaybeDisactivateLegacyVersionEncapsulation();
- return consumed_length;
-}
-
-QuicConsumedData QuicConnection::SendStreamData(QuicStreamId id,
- size_t write_length,
- QuicStreamOffset offset,
- StreamSendingState state) {
- if (state == NO_FIN && write_length == 0) {
- QUIC_BUG(quic_bug_10511_19) << "Attempt to send empty stream frame";
- return QuicConsumedData(0, false);
- }
-
- if (packet_creator_.encryption_level() == ENCRYPTION_INITIAL &&
- QuicUtils::IsCryptoStreamId(transport_version(), id)) {
- MaybeActivateLegacyVersionEncapsulation();
- }
- if (perspective_ == Perspective::IS_SERVER &&
- version().CanSendCoalescedPackets() && !IsHandshakeConfirmed()) {
- if (in_on_retransmission_time_out_ &&
- coalesced_packet_.NumberOfPackets() == 0u) {
- // PTO fires while handshake is not confirmed. Do not preempt handshake
- // data with stream data.
- QUIC_CODE_COUNT(quic_try_to_send_half_rtt_data_when_pto_fires);
- return QuicConsumedData(0, false);
- }
- if (coalesced_packet_.ContainsPacketOfEncryptionLevel(ENCRYPTION_INITIAL) &&
- coalesced_packet_.NumberOfPackets() == 1u) {
- // Handshake is not confirmed yet, if there is only an initial packet in
- // the coalescer, try to bundle an ENCRYPTION_HANDSHAKE packet before
- // sending stream data.
- sent_packet_manager_.RetransmitDataOfSpaceIfAny(HANDSHAKE_DATA);
- }
- }
- QuicConsumedData consumed_data(0, false);
- {
- // Opportunistically bundle an ack with every outgoing packet.
- // Particularly, we want to bundle with handshake packets since we don't
- // know which decrypter will be used on an ack packet following a handshake
- // packet (a handshake packet from client to server could result in a REJ or
- // a SHLO from the server, leading to two different decrypters at the
- // server.)
- ScopedPacketFlusher flusher(this);
- consumed_data =
- packet_creator_.ConsumeData(id, write_length, offset, state);
- } // Added scope ensures packets are flushed before continuing.
- MaybeDisactivateLegacyVersionEncapsulation();
- return consumed_data;
-}
-
-bool QuicConnection::SendControlFrame(const QuicFrame& frame) {
- if (SupportsMultiplePacketNumberSpaces() &&
- (encryption_level_ == ENCRYPTION_INITIAL ||
- encryption_level_ == ENCRYPTION_HANDSHAKE) &&
- frame.type != PING_FRAME) {
- // Allow PING frame to be sent without APPLICATION key. For example, when
- // anti-amplification limit is used, client needs to send something to avoid
- // handshake deadlock.
- QUIC_DVLOG(1) << ENDPOINT << "Failed to send control frame: " << frame
- << " at encryption level: " << encryption_level_;
- return false;
- }
- ScopedPacketFlusher flusher(this);
- const bool consumed =
- packet_creator_.ConsumeRetransmittableControlFrame(frame);
- if (!consumed) {
- QUIC_DVLOG(1) << ENDPOINT << "Failed to send control frame: " << frame;
- return false;
- }
- if (frame.type == PING_FRAME) {
- // Flush PING frame immediately.
- packet_creator_.FlushCurrentPacket();
- stats_.ping_frames_sent++;
- if (debug_visitor_ != nullptr) {
- debug_visitor_->OnPingSent();
- }
- }
- if (frame.type == BLOCKED_FRAME) {
- stats_.blocked_frames_sent++;
- }
- return true;
-}
-
-void QuicConnection::OnStreamReset(QuicStreamId id,
- QuicRstStreamErrorCode error) {
- if (error == QUIC_STREAM_NO_ERROR) {
- // All data for streams which are reset with QUIC_STREAM_NO_ERROR must
- // be received by the peer.
- return;
- }
- // Flush stream frames of reset stream.
- if (packet_creator_.HasPendingStreamFramesOfStream(id)) {
- ScopedPacketFlusher flusher(this);
- packet_creator_.FlushCurrentPacket();
- }
- // TODO(ianswett): Consider checking for 3 RTOs when the last stream is
- // cancelled as well.
-}
-
-const QuicConnectionStats& QuicConnection::GetStats() {
- const RttStats* rtt_stats = sent_packet_manager_.GetRttStats();
-
- // Update rtt and estimated bandwidth.
- QuicTime::Delta min_rtt = rtt_stats->min_rtt();
- if (min_rtt.IsZero()) {
- // If min RTT has not been set, use initial RTT instead.
- min_rtt = rtt_stats->initial_rtt();
- }
- stats_.min_rtt_us = min_rtt.ToMicroseconds();
-
- QuicTime::Delta srtt = rtt_stats->SmoothedOrInitialRtt();
- stats_.srtt_us = srtt.ToMicroseconds();
-
- stats_.estimated_bandwidth = sent_packet_manager_.BandwidthEstimate();
- sent_packet_manager_.GetSendAlgorithm()->PopulateConnectionStats(&stats_);
- stats_.egress_mtu = long_term_mtu_;
- stats_.ingress_mtu = largest_received_packet_size_;
- return stats_;
-}
-
-void QuicConnection::OnCoalescedPacket(const QuicEncryptedPacket& packet) {
- QueueCoalescedPacket(packet);
-}
-
-void QuicConnection::OnUndecryptablePacket(const QuicEncryptedPacket& packet,
- EncryptionLevel decryption_level,
- bool has_decryption_key) {
- QUIC_DVLOG(1) << ENDPOINT << "Received undecryptable packet of length "
- << packet.length() << " with"
- << (has_decryption_key ? "" : "out") << " key at level "
- << decryption_level
- << " while connection is at encryption level "
- << encryption_level_;
- QUICHE_DCHECK(EncryptionLevelIsValid(decryption_level));
- if (encryption_level_ != ENCRYPTION_FORWARD_SECURE) {
- ++stats_.undecryptable_packets_received_before_handshake_complete;
- }
-
- const bool should_enqueue =
- ShouldEnqueueUnDecryptablePacket(decryption_level, has_decryption_key);
- if (should_enqueue) {
- QueueUndecryptablePacket(packet, decryption_level);
- }
-
- if (debug_visitor_ != nullptr) {
- debug_visitor_->OnUndecryptablePacket(decryption_level,
- /*dropped=*/!should_enqueue);
- }
-
- if (has_decryption_key) {
- stats_.num_failed_authentication_packets_received++;
- if (version().UsesTls()) {
- // Should always be non-null if has_decryption_key is true.
- QUICHE_DCHECK(framer_.GetDecrypter(decryption_level));
- const QuicPacketCount integrity_limit =
- framer_.GetDecrypter(decryption_level)->GetIntegrityLimit();
- QUIC_DVLOG(2) << ENDPOINT << "Checking AEAD integrity limits:"
- << " num_failed_authentication_packets_received="
- << stats_.num_failed_authentication_packets_received
- << " integrity_limit=" << integrity_limit;
- if (stats_.num_failed_authentication_packets_received >=
- integrity_limit) {
- const std::string error_details = absl::StrCat(
- "decrypter integrity limit reached:"
- " num_failed_authentication_packets_received=",
- stats_.num_failed_authentication_packets_received,
- " integrity_limit=", integrity_limit);
- CloseConnection(QUIC_AEAD_LIMIT_REACHED, error_details,
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
- }
- }
- }
-
- if (version().UsesTls() && perspective_ == Perspective::IS_SERVER &&
- decryption_level == ENCRYPTION_ZERO_RTT && !has_decryption_key &&
- had_zero_rtt_decrypter_) {
- QUIC_CODE_COUNT_N(
- quic_server_received_tls_zero_rtt_packet_after_discarding_decrypter, 1,
- 3);
- stats_
- .num_tls_server_zero_rtt_packets_received_after_discarding_decrypter++;
- }
-}
-
-bool QuicConnection::ShouldEnqueueUnDecryptablePacket(
- EncryptionLevel decryption_level, bool has_decryption_key) const {
- if (has_decryption_key) {
- // We already have the key for this decryption level, therefore no
- // future keys will allow it be decrypted.
- return false;
- }
- if (IsHandshakeComplete()) {
- // We do not expect to install any further keys.
- return false;
- }
- if (undecryptable_packets_.size() >= max_undecryptable_packets_) {
- // We do not queue more than max_undecryptable_packets_ packets.
- return false;
- }
- if (version().KnowsWhichDecrypterToUse() &&
- decryption_level == ENCRYPTION_INITIAL) {
- // When the corresponding decryption key is not available, all
- // non-Initial packets should be buffered until the handshake is complete.
- return false;
- }
- if (perspective_ == Perspective::IS_CLIENT && version().UsesTls() &&
- decryption_level == ENCRYPTION_ZERO_RTT) {
- // Only clients send Zero RTT packets in IETF QUIC.
- QUIC_PEER_BUG(quic_peer_bug_client_received_zero_rtt)
- << "Client received a Zero RTT packet, not buffering.";
- return false;
- }
- return true;
-}
-
-std::string QuicConnection::UndecryptablePacketsInfo() const {
- std::string info = absl::StrCat(
- "num_undecryptable_packets: ", undecryptable_packets_.size(), " {");
- for (const auto& packet : undecryptable_packets_) {
- absl::StrAppend(&info, "[",
- EncryptionLevelToString(packet.encryption_level), ", ",
- packet.packet->length(), "]");
- }
- absl::StrAppend(&info, "}");
- return info;
-}
-
-void QuicConnection::MaybeUpdatePacketCreatorMaxPacketLengthAndPadding() {
- QuicByteCount max_packet_length = GetLimitedMaxPacketSize(long_term_mtu_);
- if (legacy_version_encapsulation_in_progress_) {
- QUICHE_DCHECK(legacy_version_encapsulation_enabled_);
- const QuicByteCount minimum_overhead =
- QuicLegacyVersionEncapsulator::GetMinimumOverhead(
- legacy_version_encapsulation_sni_);
- if (max_packet_length < minimum_overhead) {
- QUIC_BUG(quic_bug_10511_20)
- << "Cannot apply Legacy Version Encapsulation overhead because "
- << "max_packet_length " << max_packet_length << " < minimum_overhead "
- << minimum_overhead;
- legacy_version_encapsulation_in_progress_ = false;
- legacy_version_encapsulation_enabled_ = false;
- MaybeUpdatePacketCreatorMaxPacketLengthAndPadding();
- return;
- }
- max_packet_length -= minimum_overhead;
- }
- packet_creator_.SetMaxPacketLength(max_packet_length);
-}
-
-void QuicConnection::ProcessUdpPacket(const QuicSocketAddress& self_address,
- const QuicSocketAddress& peer_address,
- const QuicReceivedPacket& packet) {
- if (!connected_) {
- return;
- }
- QUIC_DVLOG(2) << ENDPOINT << "Received encrypted " << packet.length()
- << " bytes:" << std::endl
- << quiche::QuicheTextUtils::HexDump(
- absl::string_view(packet.data(), packet.length()));
- QUIC_BUG_IF(quic_bug_12714_21, current_packet_data_ != nullptr)
- << "ProcessUdpPacket must not be called while processing a packet.";
- 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();
- current_packet_data_ = packet.data();
-
- if (!default_path_.self_address.IsInitialized()) {
- default_path_.self_address = last_received_packet_info_.destination_address;
- }
-
- if (!direct_peer_address_.IsInitialized()) {
- UpdatePeerAddress(last_received_packet_info_.source_address);
- }
-
- if (!default_path_.peer_address.IsInitialized()) {
- const QuicSocketAddress effective_peer_addr =
- GetEffectivePeerAddressFromCurrentPacket();
-
- // The default path peer_address must be initialized at the beginning of the
- // first packet processed(here). If effective_peer_addr is uninitialized,
- // just set effective_peer_address_ to the direct peer address.
- default_path_.peer_address = effective_peer_addr.IsInitialized()
- ? effective_peer_addr
- : direct_peer_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);
- last_received_packet_info_.received_bytes_counted = true;
- default_path_.bytes_received_before_address_validation += last_size_;
- }
-
- // Ensure the time coming from the packet reader is within 2 minutes of now.
- if (std::abs((packet.receipt_time() - clock_->ApproximateNow()).ToSeconds()) >
- 2 * 60) {
- QUIC_BUG(quic_bug_10511_21)
- << "Packet receipt time:" << packet.receipt_time().ToDebuggingValue()
- << " too far from current time:"
- << clock_->ApproximateNow().ToDebuggingValue();
- }
- QUIC_DVLOG(1) << ENDPOINT << "time of last received packet: "
- << packet.receipt_time().ToDebuggingValue() << " from peer "
- << last_received_packet_info_.source_address;
-
- ScopedPacketFlusher flusher(this);
- if (!framer_.ProcessPacket(packet)) {
- // If we are unable to decrypt this packet, it might be
- // because the CHLO or SHLO packet was lost.
- QUIC_DVLOG(1) << ENDPOINT
- << "Unable to process packet. Last packet processed: "
- << last_header_.packet_number;
- current_packet_data_ = nullptr;
- is_current_packet_connectivity_probing_ = false;
-
- MaybeProcessCoalescedPackets();
- return;
- }
-
- ++stats_.packets_processed;
-
- QUIC_DLOG_IF(INFO, active_effective_peer_migration_type_ != NO_CHANGE)
- << "sent_packet_manager_.GetLargestObserved() = "
- << sent_packet_manager_.GetLargestObserved()
- << ", highest_packet_sent_before_effective_peer_migration_ = "
- << highest_packet_sent_before_effective_peer_migration_;
- if (!validate_client_addresses_ &&
- active_effective_peer_migration_type_ != NO_CHANGE &&
- sent_packet_manager_.GetLargestObserved().IsInitialized() &&
- (!highest_packet_sent_before_effective_peer_migration_.IsInitialized() ||
- sent_packet_manager_.GetLargestObserved() >
- highest_packet_sent_before_effective_peer_migration_)) {
- if (perspective_ == Perspective::IS_SERVER) {
- OnEffectivePeerMigrationValidated();
- }
- }
-
- if (!MaybeProcessCoalescedPackets()) {
- MaybeProcessUndecryptablePackets();
- MaybeSendInResponseToPacket();
- }
- SetPingAlarm();
- RetirePeerIssuedConnectionIdsNoLongerOnPath();
- current_packet_data_ = nullptr;
- is_current_packet_connectivity_probing_ = false;
-}
-
-void QuicConnection::OnBlockedWriterCanWrite() {
- writer_->SetWritable();
- OnCanWrite();
-}
-
-void QuicConnection::OnCanWrite() {
- if (!connected_) {
- return;
- }
- if (writer_->IsWriteBlocked()) {
- const std::string error_details =
- "Writer is blocked while calling OnCanWrite.";
- QUIC_BUG(quic_bug_10511_22) << ENDPOINT << error_details;
- CloseConnection(QUIC_INTERNAL_ERROR, error_details,
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
- return;
- }
-
- ScopedPacketFlusher flusher(this);
-
- WriteQueuedPackets();
- const QuicTime ack_timeout =
- uber_received_packet_manager_.GetEarliestAckTimeout();
- if (ack_timeout.IsInitialized() && ack_timeout <= clock_->ApproximateNow()) {
- // Send an ACK now because either 1) we were write blocked when we last
- // tried to send an ACK, or 2) both ack alarm and send alarm were set to
- // go off together.
- if (SupportsMultiplePacketNumberSpaces()) {
- SendAllPendingAcks();
- } else {
- SendAck();
- }
- }
-
- // Sending queued packets may have caused the socket to become write blocked,
- // or the congestion manager to prohibit sending.
- if (!CanWrite(HAS_RETRANSMITTABLE_DATA)) {
- return;
- }
-
- // Tell the session it can write.
- visitor_->OnCanWrite();
-
- // After the visitor writes, it may have caused the socket to become write
- // blocked or the congestion manager to prohibit sending, so check again.
- if (visitor_->WillingAndAbleToWrite() && !send_alarm_->IsSet() &&
- CanWrite(HAS_RETRANSMITTABLE_DATA)) {
- // We're not write blocked, but some data wasn't written. Register for
- // 'immediate' resumption so we'll keep writing after other connections.
- send_alarm_->Set(clock_->ApproximateNow());
- }
-}
-
-void QuicConnection::WriteIfNotBlocked() {
- if (framer().is_processing_packet()) {
- QUIC_BUG(connection_write_mid_packet_processing)
- << ENDPOINT << "Tried to write in mid of packet processing";
- return;
- }
- if (!HandleWriteBlocked()) {
- OnCanWrite();
- }
-}
-
-void QuicConnection::MaybeClearQueuedPacketsOnPathChange() {
- if (connection_migration_use_new_cid_ &&
- peer_issued_cid_manager_ != nullptr && HasQueuedPackets()) {
- // Discard packets serialized with the connection ID on the old code path.
- // It is possible to clear queued packets only if connection ID changes.
- // However, the case where connection ID is unchanged and queued packets are
- // non-empty is quite rare.
- ClearQueuedPackets();
- }
-}
-
-void QuicConnection::ReplaceInitialServerConnectionId(
- const QuicConnectionId& new_server_connection_id) {
- QUICHE_DCHECK(perspective_ == Perspective::IS_CLIENT);
- if (version().HasIetfQuicFrames()) {
- if (new_server_connection_id.IsEmpty()) {
- peer_issued_cid_manager_ = nullptr;
- } else {
- if (peer_issued_cid_manager_ != nullptr) {
- QUIC_BUG_IF(quic_bug_12714_22,
- !peer_issued_cid_manager_->IsConnectionIdActive(
- default_path_.server_connection_id))
- << "Connection ID replaced header is no longer active. old id: "
- << default_path_.server_connection_id
- << " new_id: " << new_server_connection_id;
- peer_issued_cid_manager_->ReplaceConnectionId(
- default_path_.server_connection_id, new_server_connection_id);
- } else {
- peer_issued_cid_manager_ =
- std::make_unique<QuicPeerIssuedConnectionIdManager>(
- kMinNumOfActiveConnectionIds, new_server_connection_id, clock_,
- alarm_factory_, this, context());
- }
- }
- }
- default_path_.server_connection_id = new_server_connection_id;
- packet_creator_.SetServerConnectionId(default_path_.server_connection_id);
-}
-
-void QuicConnection::FindMatchingOrNewClientConnectionIdOrToken(
- const PathState& default_path, const PathState& alternative_path,
- const QuicConnectionId& server_connection_id,
- QuicConnectionId* client_connection_id,
- absl::optional<StatelessResetToken>* stateless_reset_token) {
- QUICHE_DCHECK(perspective_ == Perspective::IS_SERVER);
- if (peer_issued_cid_manager_ == nullptr ||
- server_connection_id == default_path.server_connection_id) {
- *client_connection_id = default_path.client_connection_id;
- *stateless_reset_token = default_path.stateless_reset_token;
- return;
- }
- if (server_connection_id == alternative_path_.server_connection_id) {
- *client_connection_id = alternative_path.client_connection_id;
- *stateless_reset_token = alternative_path.stateless_reset_token;
- return;
- }
- if (!connection_migration_use_new_cid_) {
- QUIC_BUG(quic_bug_46004) << "Cannot find matching connection ID.";
- return;
- }
- auto* connection_id_data =
- peer_issued_cid_manager_->ConsumeOneUnusedConnectionId();
- if (connection_id_data == nullptr) {
- return;
- }
- *client_connection_id = connection_id_data->connection_id;
- *stateless_reset_token = connection_id_data->stateless_reset_token;
-}
-
-bool QuicConnection::FindOnPathConnectionIds(
- const QuicSocketAddress& self_address,
- const QuicSocketAddress& peer_address,
- QuicConnectionId* client_connection_id,
- QuicConnectionId* server_connection_id) const {
- if (IsDefaultPath(self_address, peer_address)) {
- *client_connection_id = default_path_.client_connection_id,
- *server_connection_id = default_path_.server_connection_id;
- return true;
- }
- if (IsAlternativePath(self_address, peer_address)) {
- *client_connection_id = alternative_path_.client_connection_id,
- *server_connection_id = alternative_path_.server_connection_id;
- return true;
- }
- return false;
-}
-
-void QuicConnection::SetDefaultPathState(PathState new_path_state) {
- default_path_ = std::move(new_path_state);
- if (connection_migration_use_new_cid_) {
- packet_creator_.SetClientConnectionId(default_path_.client_connection_id);
- packet_creator_.SetServerConnectionId(default_path_.server_connection_id);
- }
-}
-
-bool QuicConnection::ProcessValidatedPacket(const QuicPacketHeader& header) {
- if (perspective_ == Perspective::IS_CLIENT && version().HasIetfQuicFrames() &&
- direct_peer_address_.IsInitialized() &&
- last_received_packet_info_.source_address.IsInitialized() &&
- direct_peer_address_ != last_received_packet_info_.source_address &&
- !visitor_->IsKnownServerAddress(
- last_received_packet_info_.source_address)) {
- // TODO(haoyuewang) Revisit this when preferred_address transport parameter
- // is used on the client side.
- // Discard packets received from unseen server addresses.
- return false;
- }
-
- if (perspective_ == Perspective::IS_SERVER &&
- default_path_.self_address.IsInitialized() &&
- last_received_packet_info_.destination_address.IsInitialized() &&
- default_path_.self_address !=
- last_received_packet_info_.destination_address) {
- // Allow change between pure IPv4 and equivalent mapped IPv4 address.
- if (default_path_.self_address.port() !=
- last_received_packet_info_.destination_address.port() ||
- default_path_.self_address.host().Normalized() !=
- last_received_packet_info_.destination_address.host()
- .Normalized()) {
- if (!visitor_->AllowSelfAddressChange()) {
- CloseConnection(
- QUIC_ERROR_MIGRATING_ADDRESS,
- "Self address migration is not supported at the server.",
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
- return false;
- }
- }
- default_path_.self_address = last_received_packet_info_.destination_address;
- }
-
- if (PacketCanReplaceServerConnectionId(header, perspective_) &&
- default_path_.server_connection_id != header.source_connection_id) {
- QUICHE_DCHECK_EQ(header.long_packet_type, INITIAL);
- if (server_connection_id_replaced_by_initial_) {
- QUIC_DLOG(ERROR) << ENDPOINT << "Refusing to replace connection ID "
- << default_path_.server_connection_id << " with "
- << header.source_connection_id;
- return false;
- }
- server_connection_id_replaced_by_initial_ = true;
- QUIC_DLOG(INFO) << ENDPOINT << "Replacing connection ID "
- << default_path_.server_connection_id << " with "
- << header.source_connection_id;
- if (!original_destination_connection_id_.has_value()) {
- original_destination_connection_id_ = default_path_.server_connection_id;
- }
- ReplaceInitialServerConnectionId(header.source_connection_id);
- }
-
- if (!ValidateReceivedPacketNumber(header.packet_number)) {
- return false;
- }
-
- if (!version_negotiated_) {
- if (perspective_ == Perspective::IS_CLIENT) {
- QUICHE_DCHECK(!header.version_flag || header.form != GOOGLE_QUIC_PACKET);
- if (!version().HasIetfInvariantHeader()) {
- // If the client gets a packet without the version flag from the server
- // it should stop sending version since the version negotiation is done.
- // IETF QUIC stops sending version once encryption level switches to
- // forward secure.
- packet_creator_.StopSendingVersion();
- }
- version_negotiated_ = true;
- OnSuccessfulVersionNegotiation();
- }
- }
-
- if (last_size_ > largest_received_packet_size_) {
- largest_received_packet_size_ = last_size_;
- }
-
- if (perspective_ == Perspective::IS_SERVER &&
- encryption_level_ == ENCRYPTION_INITIAL &&
- last_size_ > packet_creator_.max_packet_length()) {
- if (GetQuicFlag(FLAGS_quic_use_lower_server_response_mtu_for_test)) {
- SetMaxPacketLength(std::min(last_size_, QuicByteCount(1250)));
- } else {
- SetMaxPacketLength(last_size_);
- }
- }
- return true;
-}
-
-bool QuicConnection::ValidateReceivedPacketNumber(
- QuicPacketNumber packet_number) {
- // 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)) {
- QUIC_DLOG(INFO) << ENDPOINT << "Packet " << packet_number
- << " no longer being waited for at level "
- << static_cast<int>(last_decrypted_packet_level_)
- << ". Discarding.";
- if (debug_visitor_ != nullptr) {
- debug_visitor_->OnDuplicatePacket(packet_number);
- }
- return false;
- }
-
- return true;
-}
-
-void QuicConnection::WriteQueuedPackets() {
- QUICHE_DCHECK(!writer_->IsWriteBlocked());
-
- QUIC_CLIENT_HISTOGRAM_COUNTS("QuicSession.NumQueuedPacketsBeforeWrite",
- buffered_packets_.size(), 1, 1000, 50, "");
-
- while (!buffered_packets_.empty()) {
- if (HandleWriteBlocked()) {
- break;
- }
- 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_);
- QUIC_DVLOG(1) << ENDPOINT << "Sending buffered packet, result: " << result;
- if (IsMsgTooBig(result) &&
- packet.encrypted_buffer.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.
- mtu_discoverer_.Disable();
- mtu_discovery_alarm_->Cancel();
- buffered_packets_.pop_front();
- continue;
- }
- if (IsWriteError(result.status)) {
- OnWriteError(result.error_code);
- break;
- }
- if (result.status == WRITE_STATUS_OK ||
- result.status == WRITE_STATUS_BLOCKED_DATA_BUFFERED) {
- buffered_packets_.pop_front();
- }
- if (IsWriteBlockedStatus(result.status)) {
- visitor_->OnWriteBlocked();
- break;
- }
- }
-}
-
-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()) {
- debug_visitor_->OnZeroRttRejected(reject_reason);
- }
-}
-
-void QuicConnection::NeuterUnencryptedPackets() {
- sent_packet_manager_.NeuterUnencryptedPackets();
- // This may have changed the retransmission timer, so re-arm it.
- SetRetransmissionAlarm();
- if (default_enable_5rto_blackhole_detection_) {
- QUIC_RELOADABLE_FLAG_COUNT_N(quic_default_enable_5rto_blackhole_detection2,
- 1, 3);
- // Consider this as forward progress since this is called when initial key
- // gets discarded (or previous unencrypted data is not needed anymore).
- OnForwardProgressMade();
- }
- if (SupportsMultiplePacketNumberSpaces()) {
- // Stop sending ack of initial packet number space.
- uber_received_packet_manager_.ResetAckStates(ENCRYPTION_INITIAL);
- // Re-arm ack alarm.
- ack_alarm_->Update(uber_received_packet_manager_.GetEarliestAckTimeout(),
- kAlarmGranularity);
- }
-}
-
-bool QuicConnection::ShouldGeneratePacket(
- HasRetransmittableData retransmittable,
- IsHandshake handshake) {
- QUICHE_DCHECK(handshake != IS_HANDSHAKE ||
- QuicVersionUsesCryptoFrames(transport_version()))
- << ENDPOINT
- << "Handshake in STREAM frames should not check ShouldGeneratePacket";
- if (peer_issued_cid_manager_ != nullptr &&
- packet_creator_.GetDestinationConnectionId().IsEmpty()) {
- QUICHE_DCHECK(version().HasIetfQuicFrames());
- QUIC_CODE_COUNT(quic_generate_packet_blocked_by_no_connection_id);
- QUIC_BUG_IF(quic_bug_90265_1, perspective_ == Perspective::IS_CLIENT);
- QUIC_DLOG(INFO) << ENDPOINT
- << "There is no destination connection ID available to "
- "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);
- }
- // This is checking on the alternative path with a different peer address. The
- // self address and the writer used are the same as the default path. In the
- // case of different self address and writer, writing packet would use a
- // differnt code path without checking the states of the default writer.
- return connected_ && !HandleWriteBlocked();
-}
-
-const QuicFrames QuicConnection::MaybeBundleAckOpportunistically() {
- if (!ack_frequency_sent_ && sent_packet_manager_.CanSendAckFrequency()) {
- if (packet_creator_.NextSendingPacketNumber() >=
- FirstSendingPacketNumber() + kMinReceivedBeforeAckDecimation) {
- QUIC_RELOADABLE_FLAG_COUNT_N(quic_can_send_ack_frequency, 3, 3);
- ack_frequency_sent_ = true;
- auto frame = sent_packet_manager_.GetUpdatedAckFrequencyFrame();
- visitor_->SendAckFrequency(frame);
- }
- }
-
- QuicFrames frames;
- const bool has_pending_ack =
- uber_received_packet_manager_
- .GetAckTimeout(QuicUtils::GetPacketNumberSpace(encryption_level_))
- .IsInitialized();
- if (!has_pending_ack && stop_waiting_count_ <= 1) {
- // No need to send an ACK.
- return frames;
- }
- ResetAckStates();
-
- QUIC_DVLOG(1) << ENDPOINT << "Bundle an ACK opportunistically";
- QuicFrame updated_ack_frame = GetUpdatedAckFrame();
- QUIC_BUG_IF(quic_bug_12714_23, updated_ack_frame.ack_frame->packets.Empty())
- << ENDPOINT << "Attempted to opportunistically bundle an empty "
- << encryption_level_ << " ACK, " << (has_pending_ack ? "" : "!")
- << "has_pending_ack, stop_waiting_count_ " << stop_waiting_count_;
- frames.push_back(updated_ack_frame);
-
- if (!no_stop_waiting_frames_) {
- QuicStopWaitingFrame stop_waiting;
- PopulateStopWaitingFrame(&stop_waiting);
- frames.push_back(QuicFrame(stop_waiting));
- }
- return frames;
-}
-
-bool QuicConnection::CanWrite(HasRetransmittableData retransmittable) {
- if (!connected_) {
- return false;
- }
-
- if (version().CanSendCoalescedPackets() &&
- framer_.HasEncrypterOfEncryptionLevel(ENCRYPTION_INITIAL) &&
- framer_.is_processing_packet()) {
- // While we still have initial keys, suppress sending in mid of packet
- // processing.
- // TODO(fayang): always suppress sending while in the mid of packet
- // processing.
- QUIC_DVLOG(1) << ENDPOINT
- << "Suppress sending in the mid of packet processing";
- return false;
- }
-
- if (fill_coalesced_packet_) {
- // Try to coalesce packet, only allow to write when creator is on soft max
- // packet length. Given the next created packet is going to fill current
- // coalesced packet, do not check amplification factor.
- return packet_creator_.HasSoftMaxPacketLength();
- }
-
- const bool donot_check_amplification_limit_with_pending_timer_credit =
- GetQuicReloadableFlag(
- quic_donot_check_amplification_limit_with_pending_timer_credit);
-
- if (!donot_check_amplification_limit_with_pending_timer_credit &&
- LimitedByAmplificationFactor()) {
- // Server is constrained by the amplification restriction.
- QUIC_CODE_COUNT(quic_throttled_by_amplification_limit);
- QUIC_DVLOG(1) << ENDPOINT
- << "Constrained by amplification restriction to peer address "
- << default_path_.peer_address << " bytes received "
- << default_path_.bytes_received_before_address_validation
- << ", bytes sent"
- << default_path_.bytes_sent_before_address_validation;
- ++stats_.num_amplification_throttling;
- return false;
- }
-
- if (sent_packet_manager_.pending_timer_transmission_count() > 0) {
- // Allow sending if there are pending tokens, which occurs when:
- // 1) firing PTO,
- // 2) bundling CRYPTO data with ACKs,
- // 3) coalescing CRYPTO data of higher space.
- return true;
- }
-
- if (donot_check_amplification_limit_with_pending_timer_credit) {
- QUIC_RELOADABLE_FLAG_COUNT(
- quic_donot_check_amplification_limit_with_pending_timer_credit);
- if (LimitedByAmplificationFactor()) {
- // Server is constrained by the amplification restriction.
- QUIC_CODE_COUNT(quic_throttled_by_amplification_limit);
- QUIC_DVLOG(1)
- << ENDPOINT
- << "Constrained by amplification restriction to peer address "
- << default_path_.peer_address << " bytes received "
- << default_path_.bytes_received_before_address_validation
- << ", bytes sent"
- << default_path_.bytes_sent_before_address_validation;
- ++stats_.num_amplification_throttling;
- return false;
- }
- }
-
- if (HandleWriteBlocked()) {
- return false;
- }
-
- // Allow acks and probing frames to be sent immediately.
- if (retransmittable == NO_RETRANSMITTABLE_DATA) {
- return true;
- }
- // If the send alarm is set, wait for it to fire.
- if (send_alarm_->IsSet()) {
- return false;
- }
-
- QuicTime now = clock_->Now();
- QuicTime::Delta delay = sent_packet_manager_.TimeUntilSend(now);
- if (delay.IsInfinite()) {
- send_alarm_->Cancel();
- return false;
- }
-
- // Scheduler requires a delay.
- if (!delay.IsZero()) {
- if (delay <= release_time_into_future_) {
- // Required delay is within pace time into future, send now.
- return true;
- }
- // Cannot send packet now because delay is too far in the future.
- send_alarm_->Update(now + delay, kAlarmGranularity);
- QUIC_DVLOG(1) << ENDPOINT << "Delaying sending " << delay.ToMilliseconds()
- << "ms";
- return false;
- }
- return true;
-}
-
-QuicTime QuicConnection::CalculatePacketSentTime() {
- const QuicTime now = clock_->Now();
- if (!supports_release_time_ || per_packet_options_ == nullptr) {
- // Don't change the release delay.
- return now;
- }
-
- auto next_release_time_result = sent_packet_manager_.GetNextReleaseTime();
-
- // Release before |now| is impossible.
- QuicTime next_release_time =
- std::max(now, next_release_time_result.release_time);
- per_packet_options_->release_time_delay = next_release_time - now;
- per_packet_options_->allow_burst = next_release_time_result.allow_burst;
- return next_release_time;
-}
-
-bool QuicConnection::WritePacket(SerializedPacket* packet) {
- if (sent_packet_manager_.GetLargestSentPacket().IsInitialized() &&
- packet->packet_number < sent_packet_manager_.GetLargestSentPacket()) {
- QUIC_BUG(quic_bug_10511_23)
- << "Attempt to write packet:" << packet->packet_number
- << " after:" << sent_packet_manager_.GetLargestSentPacket();
- CloseConnection(QUIC_INTERNAL_ERROR, "Packet written out of order.",
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
- return true;
- }
- const bool is_mtu_discovery = QuicUtils::ContainsFrameType(
- packet->nonretransmittable_frames, MTU_DISCOVERY_FRAME);
- const SerializedPacketFate fate = packet->fate;
- // Termination packets are encrypted and saved, so don't exit early.
- QuicErrorCode error_code = QUIC_NO_ERROR;
- const bool is_termination_packet = IsTerminationPacket(*packet, &error_code);
- QuicPacketNumber packet_number = packet->packet_number;
- QuicPacketLength encrypted_length = packet->encrypted_length;
- // Termination packets are eventually owned by TimeWaitListManager.
- // Others are deleted at the end of this call.
- if (is_termination_packet) {
- if (termination_packets_ == nullptr) {
- termination_packets_.reset(
- new std::vector<std::unique_ptr<QuicEncryptedPacket>>);
- }
- // Copy the buffer so it's owned in the future.
- char* buffer_copy = CopyBuffer(*packet);
- termination_packets_->emplace_back(
- new QuicEncryptedPacket(buffer_copy, encrypted_length, true));
- if (error_code == QUIC_SILENT_IDLE_TIMEOUT) {
- QUICHE_DCHECK_EQ(Perspective::IS_SERVER, perspective_);
- // TODO(fayang): populate histogram indicating the time elapsed from this
- // connection gets closed to following client packets get received.
- QUIC_DVLOG(1) << ENDPOINT
- << "Added silent connection close to termination packets, "
- "num of termination packets: "
- << termination_packets_->size();
- return true;
- }
- }
-
- QUICHE_DCHECK_LE(encrypted_length, kMaxOutgoingPacketSize);
- QUICHE_DCHECK(is_mtu_discovery ||
- encrypted_length <= packet_creator_.max_packet_length())
- << " encrypted_length=" << encrypted_length
- << " > packet_creator max_packet_length="
- << packet_creator_.max_packet_length();
- QUIC_DVLOG(1) << ENDPOINT << "Sending packet " << packet_number << " : "
- << (IsRetransmittable(*packet) == HAS_RETRANSMITTABLE_DATA
- ? "data bearing "
- : " ack or probing only ")
- << ", encryption level: " << packet->encryption_level
- << ", encrypted length:" << encrypted_length
- << ", fate: " << fate << " to peer " << packet->peer_address;
- QUIC_DVLOG(2) << ENDPOINT << packet->encryption_level << " packet number "
- << packet_number << " of length " << encrypted_length << ": "
- << std::endl
- << quiche::QuicheTextUtils::HexDump(absl::string_view(
- packet->encrypted_buffer, encrypted_length));
-
- // Measure the RTT from before the write begins to avoid underestimating the
- // min_rtt_, especially in cases where the thread blocks or gets swapped out
- // during the WritePacket below.
- QuicTime packet_send_time = CalculatePacketSentTime();
- WriteResult result(WRITE_STATUS_OK, encrypted_length);
- QuicSocketAddress send_to_address =
- (send_path_response_) ? packet->peer_address : peer_address();
- // Self address is always the default self address on this code path.
- bool send_on_current_path = send_to_address == peer_address();
- switch (fate) {
- case DISCARD:
- ++stats_.packets_discarded;
- return true;
- case COALESCE:
- QUIC_BUG_IF(quic_bug_12714_24,
- !version().CanSendCoalescedPackets() || coalescing_done_);
- if (!coalesced_packet_.MaybeCoalescePacket(
- *packet, self_address(), send_to_address,
- helper_->GetStreamSendBufferAllocator(),
- packet_creator_.max_packet_length())) {
- // Failed to coalesce packet, flush current coalesced packet.
- if (!FlushCoalescedPacket()) {
- // Failed to flush coalesced packet, write error has been handled.
- return false;
- }
- if (!coalesced_packet_.MaybeCoalescePacket(
- *packet, self_address(), send_to_address,
- helper_->GetStreamSendBufferAllocator(),
- packet_creator_.max_packet_length())) {
- // Failed to coalesce packet even it is the only packet, raise a write
- // error.
- QUIC_DLOG(ERROR) << ENDPOINT << "Failed to coalesce packet";
- result.error_code = WRITE_STATUS_FAILED_TO_COALESCE_PACKET;
- break;
- }
- }
- if (coalesced_packet_.length() < coalesced_packet_.max_packet_length()) {
- QUIC_DVLOG(1) << ENDPOINT << "Trying to set soft max packet length to "
- << coalesced_packet_.max_packet_length() -
- coalesced_packet_.length();
- packet_creator_.SetSoftMaxPacketLength(
- coalesced_packet_.max_packet_length() - coalesced_packet_.length());
- }
- break;
- case BUFFER:
- QUIC_DVLOG(1) << ENDPOINT << "Adding packet: " << packet->packet_number
- << " to buffered packets";
- buffered_packets_.emplace_back(*packet, self_address(), send_to_address);
- break;
- case SEND_TO_WRITER:
- // Stop using coalescer from now on.
- coalescing_done_ = true;
- // At this point, packet->release_encrypted_buffer is either nullptr,
- // meaning |packet->encrypted_buffer| is a stack buffer, or not-nullptr,
- /// meaning it's a writer-allocated buffer. Note that connectivity probing
- // packets do not use this function, so setting release_encrypted_buffer
- // to nullptr will not cause probing packets to be leaked.
- //
- // writer_->WritePacket transfers buffer ownership back to the writer.
- packet->release_encrypted_buffer = nullptr;
- result = writer_->WritePacket(packet->encrypted_buffer, encrypted_length,
- self_address().host(), send_to_address,
- per_packet_options_);
- // This is a work around for an issue with linux UDP GSO batch writers.
- // When sending a GSO packet with 2 segments, if the first segment is
- // larger than the path MTU, instead of EMSGSIZE, the linux kernel returns
- // EINVAL, which translates to WRITE_STATUS_ERROR and causes conneciton to
- // be closed. By manually flush the writer here, the MTU probe is sent in
- // a normal(non-GSO) packet, so the kernel can return EMSGSIZE and we will
- // not close the connection.
- if (is_mtu_discovery && writer_->IsBatchMode()) {
- result = writer_->Flush();
- }
- break;
- case LEGACY_VERSION_ENCAPSULATE: {
- QUICHE_DCHECK(!is_mtu_discovery);
- QUICHE_DCHECK_EQ(perspective_, Perspective::IS_CLIENT);
- QUICHE_DCHECK_EQ(packet->encryption_level, ENCRYPTION_INITIAL);
- QUICHE_DCHECK(legacy_version_encapsulation_enabled_);
- QUICHE_DCHECK(legacy_version_encapsulation_in_progress_);
- QuicPacketLength encapsulated_length =
- QuicLegacyVersionEncapsulator::Encapsulate(
- legacy_version_encapsulation_sni_,
- absl::string_view(packet->encrypted_buffer,
- packet->encrypted_length),
- default_path_.server_connection_id, framer_.creation_time(),
- GetLimitedMaxPacketSize(long_term_mtu_),
- const_cast<char*>(packet->encrypted_buffer));
- if (encapsulated_length != 0) {
- stats_.sent_legacy_version_encapsulated_packets++;
- packet->encrypted_length = encapsulated_length;
- encrypted_length = encapsulated_length;
- QUIC_DVLOG(2)
- << ENDPOINT
- << "Successfully performed Legacy Version Encapsulation on "
- << packet->encryption_level << " packet number " << packet_number
- << " of length " << encrypted_length << ": " << std::endl
- << quiche::QuicheTextUtils::HexDump(absl::string_view(
- packet->encrypted_buffer, encrypted_length));
- } else {
- QUIC_BUG(quic_bug_10511_24)
- << ENDPOINT << "Failed to perform Legacy Version Encapsulation on "
- << packet->encryption_level << " packet number " << packet_number
- << " of length " << encrypted_length;
- }
- if (!buffered_packets_.empty() || HandleWriteBlocked()) {
- // Buffer the packet.
- buffered_packets_.emplace_back(*packet, self_address(),
- send_to_address);
- } else { // Send the packet to the writer.
- // writer_->WritePacket transfers buffer ownership back to the writer.
- packet->release_encrypted_buffer = nullptr;
- result = writer_->WritePacket(packet->encrypted_buffer,
- encrypted_length, self_address().host(),
- send_to_address, per_packet_options_);
- }
- } break;
- default:
- QUICHE_DCHECK(false);
- break;
- }
-
- QUIC_HISTOGRAM_ENUM(
- "QuicConnection.WritePacketStatus", result.status,
- WRITE_STATUS_NUM_VALUES,
- "Status code returned by writer_->WritePacket() in QuicConnection.");
-
- if (IsWriteBlockedStatus(result.status)) {
- // Ensure the writer is still write blocked, otherwise QUIC may continue
- // trying to write when it will not be able to.
- QUICHE_DCHECK(writer_->IsWriteBlocked());
- visitor_->OnWriteBlocked();
- // If the socket buffers the data, then the packet should not
- // be queued and sent again, which would result in an unnecessary
- // duplicate packet being sent. The helper must call OnCanWrite
- // when the write completes, and OnWriteError if an error occurs.
- if (result.status != WRITE_STATUS_BLOCKED_DATA_BUFFERED) {
- QUIC_DVLOG(1) << ENDPOINT << "Adding packet: " << packet->packet_number
- << " to buffered packets";
- buffered_packets_.emplace_back(*packet, self_address(), send_to_address);
- }
- }
-
- // In some cases, an MTU probe can cause EMSGSIZE. This indicates that the
- // MTU discovery is permanently unsuccessful.
- if (IsMsgTooBig(result)) {
- if (is_mtu_discovery) {
- // 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.
- QUIC_DVLOG(1) << ENDPOINT
- << " MTU probe packet too big, size:" << encrypted_length
- << ", long_term_mtu_:" << long_term_mtu_;
- mtu_discoverer_.Disable();
- mtu_discovery_alarm_->Cancel();
- // The write failed, but the writer is not blocked, so return true.
- return true;
- }
- if (use_path_validator_ && !send_on_current_path) {
- QUIC_RELOADABLE_FLAG_COUNT_N(quic_pass_path_response_to_validator, 2, 4);
- // Only handle MSG_TOO_BIG as error on current path.
- return true;
- }
- }
-
- if (IsWriteError(result.status)) {
- QUIC_LOG_FIRST_N(ERROR, 10)
- << ENDPOINT << "Failed writing packet " << packet_number << " of "
- << encrypted_length << " bytes from " << self_address().host() << " to "
- << send_to_address << ", with error code " << result.error_code
- << ". long_term_mtu_:" << long_term_mtu_
- << ", previous_validated_mtu_:" << previous_validated_mtu_
- << ", max_packet_length():" << max_packet_length()
- << ", is_mtu_discovery:" << is_mtu_discovery;
- if (MaybeRevertToPreviousMtu()) {
- return true;
- }
-
- OnWriteError(result.error_code);
- return false;
- }
-
- if (result.status == WRITE_STATUS_OK) {
- // packet_send_time is the ideal send time, if allow_burst is true, writer
- // may have sent it earlier than that.
- packet_send_time = packet_send_time + result.send_time_offset;
- }
-
- if (IsRetransmittable(*packet) == HAS_RETRANSMITTABLE_DATA &&
- !is_termination_packet) {
- // Start blackhole/path degrading detections if the sent packet is not
- // termination packet and contains retransmittable data.
- // Do not restart detection if detection is in progress indicating no
- // forward progress has been made since last event (i.e., packet was sent
- // or new packets were acknowledged).
- if (!blackhole_detector_.IsDetectionInProgress()) {
- // Try to start detections if no detection in progress. This could
- // because either both detections are inactive when sending last packet
- // or this connection just gets out of quiescence.
- blackhole_detector_.RestartDetection(GetPathDegradingDeadline(),
- GetNetworkBlackholeDeadline(),
- GetPathMtuReductionDeadline());
- }
- idle_network_detector_.OnPacketSent(packet_send_time,
- sent_packet_manager_.GetPtoDelay());
- }
-
- MaybeSetMtuAlarm(packet_number);
- QUIC_DVLOG(1) << ENDPOINT << "time we began writing last sent packet: "
- << packet_send_time.ToDebuggingValue();
-
- if (!count_bytes_on_alternative_path_separately_) {
- 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);
- }
- }
-
- // Do not measure rtt of this packet if it's not sent on current path.
- QUIC_DLOG_IF(INFO, !send_on_current_path)
- << ENDPOINT << " Sent packet " << packet->packet_number
- << " on a different path with remote address " << send_to_address
- << " while current path has peer address " << peer_address();
- const bool in_flight = sent_packet_manager_.OnPacketSent(
- packet, packet_send_time, packet->transmission_type,
- IsRetransmittable(*packet), /*measure_rtt=*/send_on_current_path);
- QUIC_BUG_IF(quic_bug_12714_25,
- perspective_ == Perspective::IS_SERVER &&
- default_enable_5rto_blackhole_detection_ &&
- blackhole_detector_.IsDetectionInProgress() &&
- !sent_packet_manager_.HasInFlightPackets())
- << ENDPOINT
- << "Trying to start blackhole detection without no bytes in flight";
-
- if (debug_visitor_ != nullptr) {
- if (sent_packet_manager_.unacked_packets().empty()) {
- QUIC_BUG(quic_bug_10511_25)
- << "Unacked map is empty right after packet is sent";
- } else {
- debug_visitor_->OnPacketSent(
- packet->packet_number, packet->encrypted_length,
- packet->has_crypto_handshake, packet->transmission_type,
- packet->encryption_level,
- sent_packet_manager_.unacked_packets()
- .rbegin()
- ->retransmittable_frames,
- packet->nonretransmittable_frames, packet_send_time);
- }
- }
- if (packet->encryption_level == ENCRYPTION_HANDSHAKE) {
- handshake_packet_sent_ = true;
- }
-
- if (packet->encryption_level == ENCRYPTION_FORWARD_SECURE) {
- if (!lowest_packet_sent_in_current_key_phase_.IsInitialized()) {
- QUIC_DLOG(INFO) << ENDPOINT
- << "lowest_packet_sent_in_current_key_phase_ = "
- << packet_number;
- lowest_packet_sent_in_current_key_phase_ = packet_number;
- }
- if (!is_termination_packet &&
- MaybeHandleAeadConfidentialityLimits(*packet)) {
- return true;
- }
- }
- if (ShouldSetRetransmissionAlarmOnPacketSent(in_flight,
- packet->encryption_level)) {
- SetRetransmissionAlarm();
- }
- SetPingAlarm();
- RetirePeerIssuedConnectionIdsNoLongerOnPath();
-
- // The packet number length must be updated after OnPacketSent, because it
- // may change the packet number length in packet.
- packet_creator_.UpdatePacketNumberLength(
- sent_packet_manager_.GetLeastPacketAwaitedByPeer(encryption_level_),
- sent_packet_manager_.EstimateMaxPacketsInFlight(max_packet_length()));
-
- stats_.bytes_sent += result.bytes_written;
- ++stats_.packets_sent;
- if (packet->transmission_type != NOT_RETRANSMISSION) {
- stats_.bytes_retransmitted += result.bytes_written;
- ++stats_.packets_retransmitted;
- }
-
- return true;
-}
-
-bool QuicConnection::MaybeHandleAeadConfidentialityLimits(
- const SerializedPacket& packet) {
- if (!version().UsesTls()) {
- return false;
- }
-
- if (packet.encryption_level != ENCRYPTION_FORWARD_SECURE) {
- QUIC_BUG(quic_bug_12714_26)
- << "MaybeHandleAeadConfidentialityLimits called on non 1-RTT packet";
- return false;
- }
- if (!lowest_packet_sent_in_current_key_phase_.IsInitialized()) {
- QUIC_BUG(quic_bug_10511_26)
- << "lowest_packet_sent_in_current_key_phase_ must be initialized "
- "before calling MaybeHandleAeadConfidentialityLimits";
- return false;
- }
-
- // Calculate the number of packets encrypted from the packet number, which is
- // simpler than keeping another counter. The packet number space may be
- // sparse, so this might overcount, but doing a key update earlier than
- // necessary would only improve security and has negligible cost.
- if (packet.packet_number < lowest_packet_sent_in_current_key_phase_) {
- const std::string error_details =
- absl::StrCat("packet_number(", packet.packet_number.ToString(),
- ") < lowest_packet_sent_in_current_key_phase_ (",
- lowest_packet_sent_in_current_key_phase_.ToString(), ")");
- QUIC_BUG(quic_bug_10511_27) << error_details;
- CloseConnection(QUIC_INTERNAL_ERROR, error_details,
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
- return true;
- }
- const QuicPacketCount num_packets_encrypted_in_current_key_phase =
- packet.packet_number - lowest_packet_sent_in_current_key_phase_ + 1;
-
- const QuicPacketCount confidentiality_limit =
- framer_.GetOneRttEncrypterConfidentialityLimit();
-
- // Attempt to initiate a key update before reaching the AEAD
- // confidentiality limit when the number of packets sent in the current
- // key phase gets within |kKeyUpdateConfidentialityLimitOffset| packets of
- // the limit, unless overridden by
- // FLAGS_quic_key_update_confidentiality_limit.
- constexpr QuicPacketCount kKeyUpdateConfidentialityLimitOffset = 1000;
- QuicPacketCount key_update_limit = 0;
- if (confidentiality_limit > kKeyUpdateConfidentialityLimitOffset) {
- key_update_limit =
- confidentiality_limit - kKeyUpdateConfidentialityLimitOffset;
- }
- const QuicPacketCount key_update_limit_override =
- GetQuicFlag(FLAGS_quic_key_update_confidentiality_limit);
- if (key_update_limit_override) {
- key_update_limit = key_update_limit_override;
- }
-
- QUIC_DVLOG(2) << ENDPOINT << "Checking AEAD confidentiality limits: "
- << "num_packets_encrypted_in_current_key_phase="
- << num_packets_encrypted_in_current_key_phase
- << " key_update_limit=" << key_update_limit
- << " confidentiality_limit=" << confidentiality_limit
- << " IsKeyUpdateAllowed()=" << IsKeyUpdateAllowed();
-
- if (num_packets_encrypted_in_current_key_phase >= confidentiality_limit) {
- // Reached the confidentiality limit without initiating a key update,
- // must close the connection.
- const std::string error_details = absl::StrCat(
- "encrypter confidentiality limit reached: "
- "num_packets_encrypted_in_current_key_phase=",
- num_packets_encrypted_in_current_key_phase,
- " key_update_limit=", key_update_limit,
- " confidentiality_limit=", confidentiality_limit,
- " IsKeyUpdateAllowed()=", IsKeyUpdateAllowed());
- CloseConnection(QUIC_AEAD_LIMIT_REACHED, error_details,
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
- return true;
- }
-
- if (IsKeyUpdateAllowed() &&
- num_packets_encrypted_in_current_key_phase >= key_update_limit) {
- // Approaching the confidentiality limit, initiate key update so that
- // the next set of keys will be ready for the next packet before the
- // limit is reached.
- KeyUpdateReason reason = KeyUpdateReason::kLocalAeadConfidentialityLimit;
- if (key_update_limit_override) {
- QUIC_DLOG(INFO) << ENDPOINT
- << "reached FLAGS_quic_key_update_confidentiality_limit, "
- "initiating key update: "
- << "num_packets_encrypted_in_current_key_phase="
- << num_packets_encrypted_in_current_key_phase
- << " key_update_limit=" << key_update_limit
- << " confidentiality_limit=" << confidentiality_limit;
- reason = KeyUpdateReason::kLocalKeyUpdateLimitOverride;
- } else {
- QUIC_DLOG(INFO) << ENDPOINT
- << "approaching AEAD confidentiality limit, "
- "initiating key update: "
- << "num_packets_encrypted_in_current_key_phase="
- << num_packets_encrypted_in_current_key_phase
- << " key_update_limit=" << key_update_limit
- << " confidentiality_limit=" << confidentiality_limit;
- }
- InitiateKeyUpdate(reason);
- }
-
- return false;
-}
-
-void QuicConnection::FlushPackets() {
- if (!connected_) {
- return;
- }
-
- if (!writer_->IsBatchMode()) {
- return;
- }
-
- if (HandleWriteBlocked()) {
- QUIC_DLOG(INFO) << ENDPOINT << "FlushPackets called while blocked.";
- return;
- }
-
- WriteResult result = writer_->Flush();
-
- QUIC_HISTOGRAM_ENUM("QuicConnection.FlushPacketStatus", result.status,
- WRITE_STATUS_NUM_VALUES,
- "Status code returned by writer_->Flush() in "
- "QuicConnection::FlushPackets.");
-
- if (HandleWriteBlocked()) {
- QUICHE_DCHECK_EQ(WRITE_STATUS_BLOCKED, result.status)
- << "Unexpected flush result:" << result;
- QUIC_DLOG(INFO) << ENDPOINT << "Write blocked in FlushPackets.";
- return;
- }
-
- if (IsWriteError(result.status) && !MaybeRevertToPreviousMtu()) {
- OnWriteError(result.error_code);
- }
-}
-
-bool QuicConnection::IsMsgTooBig(const WriteResult& result) {
- return (result.status == WRITE_STATUS_MSG_TOO_BIG) ||
- (IsWriteError(result.status) && result.error_code == QUIC_EMSGSIZE);
-}
-
-bool QuicConnection::ShouldDiscardPacket(EncryptionLevel encryption_level) {
- if (!connected_) {
- QUIC_DLOG(INFO) << ENDPOINT
- << "Not sending packet as connection is disconnected.";
- return true;
- }
-
- if (encryption_level_ == ENCRYPTION_FORWARD_SECURE &&
- encryption_level == ENCRYPTION_INITIAL) {
- // Drop packets that are NULL encrypted since the peer won't accept them
- // anymore.
- QUIC_DLOG(INFO) << ENDPOINT
- << "Dropping NULL encrypted packet since the connection is "
- "forward secure.";
- return true;
- }
-
- return false;
-}
-
-QuicTime QuicConnection::GetPathMtuReductionDeadline() const {
- if (previous_validated_mtu_ == 0) {
- return QuicTime::Zero();
- }
- QuicTime::Delta delay = sent_packet_manager_.GetMtuReductionDelay(
- num_rtos_for_blackhole_detection_);
- if (delay.IsZero()) {
- return QuicTime::Zero();
- }
- return clock_->ApproximateNow() + delay;
-}
-
-bool QuicConnection::MaybeRevertToPreviousMtu() {
- if (previous_validated_mtu_ == 0) {
- return false;
- }
-
- SetMaxPacketLength(previous_validated_mtu_);
- mtu_discoverer_.Disable();
- mtu_discovery_alarm_->Cancel();
- previous_validated_mtu_ = 0;
- return true;
-}
-
-void QuicConnection::OnWriteError(int error_code) {
- if (write_error_occurred_) {
- // A write error already occurred. The connection is being closed.
- return;
- }
- write_error_occurred_ = true;
-
- const std::string error_details = absl::StrCat(
- "Write failed with error: ", error_code, " (", strerror(error_code), ")");
- QUIC_LOG_FIRST_N(ERROR, 2) << ENDPOINT << error_details;
- switch (error_code) {
- case QUIC_EMSGSIZE:
- CloseConnection(QUIC_PACKET_WRITE_ERROR, error_details,
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
- break;
- default:
- // We can't send an error as the socket is presumably borked.
- if (version().HasIetfInvariantHeader()) {
- QUIC_CODE_COUNT(quic_tear_down_local_connection_on_write_error_ietf);
- } else {
- QUIC_CODE_COUNT(
- quic_tear_down_local_connection_on_write_error_non_ietf);
- }
- CloseConnection(QUIC_PACKET_WRITE_ERROR, error_details,
- ConnectionCloseBehavior::SILENT_CLOSE);
- }
-}
-
-QuicPacketBuffer QuicConnection::GetPacketBuffer() {
- if (version().CanSendCoalescedPackets() && !coalescing_done_) {
- // Do not use writer's packet buffer for coalesced packets which may
- // contain multiple QUIC packets.
- return {nullptr, nullptr};
- }
- return writer_->GetNextWriteLocation(self_address().host(), peer_address());
-}
-
-void QuicConnection::OnSerializedPacket(SerializedPacket serialized_packet) {
- if (serialized_packet.encrypted_buffer == nullptr) {
- // We failed to serialize the packet, so close the connection.
- // Specify that the close is silent, that no packet be sent, so no infinite
- // loop here.
- // TODO(ianswett): This is actually an internal error, not an
- // encryption failure.
- if (version().HasIetfInvariantHeader()) {
- QUIC_CODE_COUNT(
- quic_tear_down_local_connection_on_serialized_packet_ietf);
- } else {
- QUIC_CODE_COUNT(
- quic_tear_down_local_connection_on_serialized_packet_non_ietf);
- }
- CloseConnection(QUIC_ENCRYPTION_FAILURE,
- "Serialized packet does not have an encrypted buffer.",
- ConnectionCloseBehavior::SILENT_CLOSE);
- return;
- }
-
- if (serialized_packet.retransmittable_frames.empty()) {
- // Increment consecutive_num_packets_with_no_retransmittable_frames_ if
- // this packet is a new transmission with no retransmittable frames.
- ++consecutive_num_packets_with_no_retransmittable_frames_;
- } else {
- consecutive_num_packets_with_no_retransmittable_frames_ = 0;
- }
- SendOrQueuePacket(std::move(serialized_packet));
-}
-
-void QuicConnection::OnUnrecoverableError(QuicErrorCode error,
- const std::string& error_details) {
- // The packet creator or generator encountered an unrecoverable error: tear
- // down local connection state immediately.
- if (version().HasIetfInvariantHeader()) {
- QUIC_CODE_COUNT(
- quic_tear_down_local_connection_on_unrecoverable_error_ietf);
- } else {
- QUIC_CODE_COUNT(
- quic_tear_down_local_connection_on_unrecoverable_error_non_ietf);
- }
- CloseConnection(error, error_details, ConnectionCloseBehavior::SILENT_CLOSE);
-}
-
-void QuicConnection::OnCongestionChange() {
- visitor_->OnCongestionWindowChange(clock_->ApproximateNow());
-
- // Uses the connection's smoothed RTT. If zero, uses initial_rtt.
- QuicTime::Delta rtt = sent_packet_manager_.GetRttStats()->smoothed_rtt();
- if (rtt.IsZero()) {
- rtt = sent_packet_manager_.GetRttStats()->initial_rtt();
- }
-
- if (debug_visitor_ != nullptr) {
- debug_visitor_->OnRttChanged(rtt);
- }
-}
-
-void QuicConnection::OnPathMtuIncreased(QuicPacketLength packet_size) {
- if (packet_size > max_packet_length()) {
- previous_validated_mtu_ = max_packet_length();
- SetMaxPacketLength(packet_size);
- mtu_discoverer_.OnMaxPacketLengthUpdated(previous_validated_mtu_,
- max_packet_length());
- }
-}
-
-std::unique_ptr<QuicSelfIssuedConnectionIdManager>
-QuicConnection::MakeSelfIssuedConnectionIdManager() {
- QUICHE_DCHECK((perspective_ == Perspective::IS_CLIENT &&
- !default_path_.client_connection_id.IsEmpty()) ||
- (perspective_ == Perspective::IS_SERVER &&
- !default_path_.server_connection_id.IsEmpty()));
- return std::make_unique<QuicSelfIssuedConnectionIdManager>(
- kMinNumOfActiveConnectionIds,
- perspective_ == Perspective::IS_CLIENT
- ? default_path_.client_connection_id
- : default_path_.server_connection_id,
- clock_, alarm_factory_, this, context());
-}
-
-void QuicConnection::MaybeSendConnectionIdToClient() {
- if (perspective_ == Perspective::IS_CLIENT) {
- return;
- }
- QUICHE_DCHECK(self_issued_cid_manager_ != nullptr);
- self_issued_cid_manager_->MaybeSendNewConnectionIds();
-}
-
-void QuicConnection::OnHandshakeComplete() {
- sent_packet_manager_.SetHandshakeConfirmed();
- if (connection_migration_use_new_cid_ &&
- perspective_ == Perspective::IS_SERVER &&
- self_issued_cid_manager_ != nullptr) {
- self_issued_cid_manager_->MaybeSendNewConnectionIds();
- }
- if (send_ack_frequency_on_handshake_completion_ &&
- sent_packet_manager_.CanSendAckFrequency()) {
- QUIC_RELOADABLE_FLAG_COUNT_N(quic_can_send_ack_frequency, 2, 3);
- auto ack_frequency_frame =
- sent_packet_manager_.GetUpdatedAckFrequencyFrame();
- // This AckFrequencyFrame is meant to only update the max_ack_delay. Set
- // packet tolerance to the default value for now.
- ack_frequency_frame.packet_tolerance =
- kDefaultRetransmittablePacketsBeforeAck;
- visitor_->SendAckFrequency(ack_frequency_frame);
- if (!connected_) {
- return;
- }
- }
- // This may have changed the retransmission timer, so re-arm it.
- SetRetransmissionAlarm();
- if (default_enable_5rto_blackhole_detection_) {
- QUIC_RELOADABLE_FLAG_COUNT_N(quic_default_enable_5rto_blackhole_detection2,
- 2, 3);
- OnForwardProgressMade();
- }
- if (!SupportsMultiplePacketNumberSpaces()) {
- // The client should immediately ack the SHLO to confirm the handshake is
- // complete with the server.
- if (perspective_ == Perspective::IS_CLIENT && ack_frame_updated()) {
- ack_alarm_->Update(clock_->ApproximateNow(), QuicTime::Delta::Zero());
- }
- return;
- }
- // Stop sending ack of handshake packet number space.
- uber_received_packet_manager_.ResetAckStates(ENCRYPTION_HANDSHAKE);
- // Re-arm ack alarm.
- ack_alarm_->Update(uber_received_packet_manager_.GetEarliestAckTimeout(),
- kAlarmGranularity);
-}
-
-void QuicConnection::SendOrQueuePacket(SerializedPacket packet) {
- // The caller of this function is responsible for checking CanWrite().
- WritePacket(&packet);
-}
-
-void QuicConnection::OnPingTimeout() {
- if (retransmission_alarm_->IsSet() ||
- !visitor_->ShouldKeepConnectionAlive()) {
- return;
- }
- SendPingAtLevel(framer().GetEncryptionLevelToSendApplicationData());
-}
-
-void QuicConnection::SendAck() {
- QUICHE_DCHECK(!SupportsMultiplePacketNumberSpaces());
- QUIC_DVLOG(1) << ENDPOINT << "Sending an ACK proactively";
- QuicFrames frames;
- frames.push_back(GetUpdatedAckFrame());
- if (!no_stop_waiting_frames_) {
- QuicStopWaitingFrame stop_waiting;
- PopulateStopWaitingFrame(&stop_waiting);
- frames.push_back(QuicFrame(stop_waiting));
- }
- if (!packet_creator_.FlushAckFrame(frames)) {
- return;
- }
- ResetAckStates();
- if (!ShouldBundleRetransmittableFrameWithAck()) {
- return;
- }
- consecutive_num_packets_with_no_retransmittable_frames_ = 0;
- if (packet_creator_.HasPendingRetransmittableFrames() ||
- visitor_->WillingAndAbleToWrite()) {
- // There are pending retransmittable frames.
- return;
- }
-
- visitor_->OnAckNeedsRetransmittableFrame();
-}
-
-void QuicConnection::OnRetransmissionTimeout() {
- ScopedRetransmissionTimeoutIndicator indicator(this);
-#ifndef NDEBUG
- if (sent_packet_manager_.unacked_packets().empty()) {
- QUICHE_DCHECK(sent_packet_manager_.handshake_mode_disabled());
- QUICHE_DCHECK(!IsHandshakeComplete());
- }
-#endif
- if (!connected_) {
- return;
- }
-
- QuicPacketNumber previous_created_packet_number =
- 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.
- const QuicPacketCount num_packet_numbers_to_skip = 1;
- packet_creator_.SkipNPacketNumbers(
- num_packet_numbers_to_skip,
- sent_packet_manager_.GetLeastPacketAwaitedByPeer(encryption_level_),
- sent_packet_manager_.EstimateMaxPacketsInFlight(max_packet_length()));
- previous_created_packet_number += num_packet_numbers_to_skip;
- if (debug_visitor_ != nullptr) {
- debug_visitor_->OnNPacketNumbersSkipped(num_packet_numbers_to_skip,
- clock_->Now());
- }
- }
- if (default_enable_5rto_blackhole_detection_ &&
- !sent_packet_manager_.HasInFlightPackets() &&
- blackhole_detector_.IsDetectionInProgress()) {
- // Stop detection in quiescence.
- QUICHE_DCHECK_EQ(QuicSentPacketManager::LOSS_MODE, retransmission_mode);
- blackhole_detector_.StopDetection(/*permanent=*/false);
- }
- WriteIfNotBlocked();
-
- // A write failure can result in the connection being closed, don't attempt to
- // write further packets, or to set alarms.
- 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();
- }
-
- if (packet_creator_.packet_number() == previous_created_packet_number &&
- (retransmission_mode == QuicSentPacketManager::TLP_MODE ||
- retransmission_mode == QuicSentPacketManager::RTO_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.
- QUIC_DLOG(INFO) << ENDPOINT
- << "No packet gets sent when timer fires in mode "
- << retransmission_mode << ", send PING";
- QUICHE_DCHECK_LT(0u,
- sent_packet_manager_.pending_timer_transmission_count());
- if (SupportsMultiplePacketNumberSpaces()) {
- // Based on https://datatracker.ietf.org/doc/html/rfc9002#appendix-A.9
- PacketNumberSpace packet_number_space;
- if (sent_packet_manager_
- .GetEarliestPacketSentTimeForPto(&packet_number_space)
- .IsInitialized()) {
- SendPingAtLevel(QuicUtils::GetEncryptionLevel(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
- QUICHE_DCHECK_EQ(Perspective::IS_CLIENT, perspective_);
- if (framer_.HasEncrypterOfEncryptionLevel(ENCRYPTION_HANDSHAKE)) {
- SendPingAtLevel(ENCRYPTION_HANDSHAKE);
- } else if (framer_.HasEncrypterOfEncryptionLevel(ENCRYPTION_INITIAL)) {
- SendPingAtLevel(ENCRYPTION_INITIAL);
- } else {
- QUIC_BUG(quic_bug_no_pto) << "PTO fired but nothing was sent.";
- }
- }
- } else {
- SendPingAtLevel(encryption_level_);
- }
- }
- 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).
- QUIC_BUG_IF(
- quic_bug_12714_27,
- packet_creator_.packet_number() == previous_created_packet_number &&
- (!visitor_->WillingAndAbleToWrite() ||
- sent_packet_manager_.pending_timer_transmission_count() == 0u))
- << "retransmission_mode: " << retransmission_mode
- << ", packet_number: " << packet_creator_.packet_number()
- << ", session has data to write: " << visitor_->WillingAndAbleToWrite()
- << ", writer is blocked: " << writer_->IsWriteBlocked()
- << ", pending_timer_transmission_count: "
- << sent_packet_manager_.pending_timer_transmission_count();
- }
-
- // Ensure the retransmission alarm is always set if there are unacked packets
- // and nothing waiting to be sent.
- // This happens if the loss algorithm invokes a timer based loss, but the
- // packet doesn't need to be retransmitted.
- if (!HasQueuedData() && !retransmission_alarm_->IsSet()) {
- SetRetransmissionAlarm();
- }
-}
-
-void QuicConnection::SetEncrypter(EncryptionLevel level,
- std::unique_ptr<QuicEncrypter> encrypter) {
- packet_creator_.SetEncrypter(level, std::move(encrypter));
-}
-
-void QuicConnection::RemoveEncrypter(EncryptionLevel level) {
- framer_.RemoveEncrypter(level);
-}
-
-void QuicConnection::SetDiversificationNonce(
- const DiversificationNonce& nonce) {
- QUICHE_DCHECK_EQ(Perspective::IS_SERVER, perspective_);
- packet_creator_.SetDiversificationNonce(nonce);
-}
-
-void QuicConnection::SetDefaultEncryptionLevel(EncryptionLevel level) {
- QUIC_DVLOG(1) << ENDPOINT << "Setting default encryption level from "
- << encryption_level_ << " to " << level;
- const bool changing_level = level != encryption_level_;
- if (changing_level && packet_creator_.HasPendingFrames()) {
- // Flush all queued frames when encryption level changes.
- ScopedPacketFlusher flusher(this);
- packet_creator_.FlushCurrentPacket();
- }
- encryption_level_ = level;
- packet_creator_.set_encryption_level(level);
- QUIC_BUG_IF(quic_bug_12714_28, !framer_.HasEncrypterOfEncryptionLevel(level))
- << ENDPOINT << "Trying to set encryption level to "
- << EncryptionLevelToString(level) << " while the key is missing";
-
- if (!changing_level) {
- return;
- }
- // The least packet awaited by the peer depends on the encryption level so
- // we recalculate it here.
- packet_creator_.UpdatePacketNumberLength(
- sent_packet_manager_.GetLeastPacketAwaitedByPeer(encryption_level_),
- sent_packet_manager_.EstimateMaxPacketsInFlight(max_packet_length()));
-}
-
-void QuicConnection::SetDecrypter(EncryptionLevel level,
- std::unique_ptr<QuicDecrypter> decrypter) {
- framer_.SetDecrypter(level, std::move(decrypter));
-
- if (!undecryptable_packets_.empty() &&
- !process_undecryptable_packets_alarm_->IsSet()) {
- process_undecryptable_packets_alarm_->Set(clock_->ApproximateNow());
- }
-}
-
-void QuicConnection::SetAlternativeDecrypter(
- EncryptionLevel level,
- std::unique_ptr<QuicDecrypter> decrypter,
- bool latch_once_used) {
- framer_.SetAlternativeDecrypter(level, std::move(decrypter), latch_once_used);
-
- if (!undecryptable_packets_.empty() &&
- !process_undecryptable_packets_alarm_->IsSet()) {
- process_undecryptable_packets_alarm_->Set(clock_->ApproximateNow());
- }
-}
-
-void QuicConnection::InstallDecrypter(
- EncryptionLevel level,
- std::unique_ptr<QuicDecrypter> decrypter) {
- if (level == ENCRYPTION_ZERO_RTT) {
- had_zero_rtt_decrypter_ = true;
- }
- framer_.InstallDecrypter(level, std::move(decrypter));
- if (!undecryptable_packets_.empty() &&
- !process_undecryptable_packets_alarm_->IsSet()) {
- process_undecryptable_packets_alarm_->Set(clock_->ApproximateNow());
- }
-}
-
-void QuicConnection::RemoveDecrypter(EncryptionLevel level) {
- framer_.RemoveDecrypter(level);
-}
-
-void QuicConnection::DiscardPreviousOneRttKeys() {
- framer_.DiscardPreviousOneRttKeys();
-}
-
-bool QuicConnection::IsKeyUpdateAllowed() const {
- return support_key_update_for_connection_ &&
- GetLargestAckedPacket().IsInitialized() &&
- lowest_packet_sent_in_current_key_phase_.IsInitialized() &&
- GetLargestAckedPacket() >= lowest_packet_sent_in_current_key_phase_;
-}
-
-bool QuicConnection::HaveSentPacketsInCurrentKeyPhaseButNoneAcked() const {
- return lowest_packet_sent_in_current_key_phase_.IsInitialized() &&
- (!GetLargestAckedPacket().IsInitialized() ||
- GetLargestAckedPacket() < lowest_packet_sent_in_current_key_phase_);
-}
-
-QuicPacketCount QuicConnection::PotentialPeerKeyUpdateAttemptCount() const {
- return framer_.PotentialPeerKeyUpdateAttemptCount();
-}
-
-bool QuicConnection::InitiateKeyUpdate(KeyUpdateReason reason) {
- QUIC_DLOG(INFO) << ENDPOINT << "InitiateKeyUpdate";
- if (!IsKeyUpdateAllowed()) {
- QUIC_BUG(quic_bug_10511_28) << "key update not allowed";
- return false;
- }
- return framer_.DoKeyUpdate(reason);
-}
-
-const QuicDecrypter* QuicConnection::decrypter() const {
- return framer_.decrypter();
-}
-
-const QuicDecrypter* QuicConnection::alternative_decrypter() const {
- return framer_.alternative_decrypter();
-}
-
-void QuicConnection::QueueUndecryptablePacket(
- const QuicEncryptedPacket& packet,
- EncryptionLevel decryption_level) {
- for (const auto& saved_packet : undecryptable_packets_) {
- if (packet.data() == saved_packet.packet->data() &&
- packet.length() == saved_packet.packet->length()) {
- QUIC_DVLOG(1) << ENDPOINT << "Not queueing known undecryptable packet";
- return;
- }
- }
- QUIC_DVLOG(1) << ENDPOINT << "Queueing undecryptable packet.";
- undecryptable_packets_.emplace_back(packet, decryption_level,
- last_received_packet_info_);
- if (perspective_ == Perspective::IS_CLIENT) {
- if (!retransmission_alarm_->IsSet() ||
- GetRetransmissionDeadline() < retransmission_alarm_->deadline()) {
- // Re-arm PTO only if we can make it sooner to speed up recovery.
- SetRetransmissionAlarm();
- }
- }
-}
-
-void QuicConnection::MaybeProcessUndecryptablePackets() {
- process_undecryptable_packets_alarm_->Cancel();
-
- if (undecryptable_packets_.empty() ||
- encryption_level_ == ENCRYPTION_INITIAL) {
- return;
- }
-
- auto iter = undecryptable_packets_.begin();
- while (connected_ && iter != undecryptable_packets_.end()) {
- // Making sure there is no pending frames when processing next undecrypted
- // packet because the queued ack frame may change.
- packet_creator_.FlushCurrentPacket();
- if (!connected_) {
- return;
- }
- UndecryptablePacket* undecryptable_packet = &*iter;
- QUIC_DVLOG(1) << ENDPOINT << "Attempting to process undecryptable packet";
- if (debug_visitor_ != nullptr) {
- debug_visitor_->OnAttemptingToProcessUndecryptablePacket(
- undecryptable_packet->encryption_level);
- }
- bool processed = false;
- if (reset_per_packet_state_for_undecryptable_packets_) {
- QUIC_RELOADABLE_FLAG_COUNT_N(
- quic_reset_per_packet_state_for_undecryptable_packets, 1, 2);
- last_received_packet_info_ = undecryptable_packet->packet_info;
- last_size_ = undecryptable_packet->packet->length();
- current_packet_data_ = undecryptable_packet->packet->data();
- processed = framer_.ProcessPacket(*undecryptable_packet->packet);
- current_packet_data_ = nullptr;
- } else {
- processed = framer_.ProcessPacket(*undecryptable_packet->packet);
- }
- if (processed) {
- QUIC_DVLOG(1) << ENDPOINT << "Processed undecryptable packet!";
- iter = undecryptable_packets_.erase(iter);
- ++stats_.packets_processed;
- continue;
- }
- const bool has_decryption_key = version().KnowsWhichDecrypterToUse() &&
- framer_.HasDecrypterOfEncryptionLevel(
- undecryptable_packet->encryption_level);
- if (framer_.error() == QUIC_DECRYPTION_FAILURE &&
- ShouldEnqueueUnDecryptablePacket(undecryptable_packet->encryption_level,
- has_decryption_key)) {
- QUIC_DVLOG(1)
- << ENDPOINT
- << "Need to attempt to process this undecryptable packet later";
- ++iter;
- continue;
- }
- iter = undecryptable_packets_.erase(iter);
- }
-
- // Once handshake is complete, there will be no new keys installed and hence
- // any undecryptable packets will never be able to be decrypted.
- bool clear_undecryptable_packets =
- encryption_level_ == ENCRYPTION_FORWARD_SECURE;
- if (GetQuicReloadableFlag(
- quic_clear_undecryptable_packets_on_handshake_complete)) {
- QUIC_RELOADABLE_FLAG_COUNT(
- quic_clear_undecryptable_packets_on_handshake_complete);
- clear_undecryptable_packets = IsHandshakeComplete();
- }
- if (clear_undecryptable_packets) {
- if (debug_visitor_ != nullptr) {
- for (const auto& undecryptable_packet : undecryptable_packets_) {
- debug_visitor_->OnUndecryptablePacket(
- undecryptable_packet.encryption_level, /*dropped=*/true);
- }
- }
- undecryptable_packets_.clear();
- }
- if (perspective_ == Perspective::IS_CLIENT) {
- 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();
- }
- }
-}
-
-void QuicConnection::QueueCoalescedPacket(const QuicEncryptedPacket& packet) {
- QUIC_DVLOG(1) << ENDPOINT << "Queueing coalesced packet.";
- received_coalesced_packets_.push_back(packet.Clone());
- ++stats_.num_coalesced_packets_received;
-}
-
-bool QuicConnection::MaybeProcessCoalescedPackets() {
- bool processed = false;
- while (connected_ && !received_coalesced_packets_.empty()) {
- // Making sure there are no pending frames when processing the next
- // coalesced packet because the queued ack frame may change.
- packet_creator_.FlushCurrentPacket();
- if (!connected_) {
- return processed;
- }
-
- std::unique_ptr<QuicEncryptedPacket> packet =
- std::move(received_coalesced_packets_.front());
- received_coalesced_packets_.pop_front();
-
- QUIC_DVLOG(1) << ENDPOINT << "Processing coalesced packet";
- if (framer_.ProcessPacket(*packet)) {
- processed = true;
- ++stats_.num_coalesced_packets_processed;
- } else {
- // If we are unable to decrypt this packet, it might be
- // because the CHLO or SHLO packet was lost.
- }
- }
- if (processed) {
- MaybeProcessUndecryptablePackets();
- MaybeSendInResponseToPacket();
- }
- return processed;
-}
-
-void QuicConnection::CloseConnection(
- QuicErrorCode error,
- const std::string& details,
- ConnectionCloseBehavior connection_close_behavior) {
- CloseConnection(error, NO_IETF_QUIC_ERROR, details,
- connection_close_behavior);
-}
-
-void QuicConnection::CloseConnection(
- QuicErrorCode error,
- QuicIetfTransportErrorCodes ietf_error,
- const std::string& error_details,
- ConnectionCloseBehavior connection_close_behavior) {
- QUICHE_DCHECK(!error_details.empty());
- if (!connected_) {
- QUIC_DLOG(INFO) << "Connection is already closed.";
- return;
- }
-
- if (ietf_error != NO_IETF_QUIC_ERROR) {
- QUIC_DLOG(INFO) << ENDPOINT << "Closing connection: " << connection_id()
- << ", with wire error: " << ietf_error
- << ", error: " << QuicErrorCodeToString(error)
- << ", and details: " << error_details;
- } else {
- QUIC_DLOG(INFO) << ENDPOINT << "Closing connection: " << connection_id()
- << ", with error: " << QuicErrorCodeToString(error) << " ("
- << error << "), and details: " << error_details;
- }
-
- if (connection_close_behavior != ConnectionCloseBehavior::SILENT_CLOSE) {
- SendConnectionClosePacket(error, ietf_error, error_details);
- }
-
- TearDownLocalConnectionState(error, ietf_error, error_details,
- ConnectionCloseSource::FROM_SELF);
-}
-
-void QuicConnection::SendConnectionClosePacket(
- QuicErrorCode error,
- QuicIetfTransportErrorCodes ietf_error,
- const std::string& details) {
- // Always use the current path to send CONNECTION_CLOSE.
- QuicPacketCreator::ScopedPeerAddressContext context(
- &packet_creator_, peer_address(), default_path_.client_connection_id,
- default_path_.server_connection_id, connection_migration_use_new_cid_);
- if (!SupportsMultiplePacketNumberSpaces()) {
- QUIC_DLOG(INFO) << ENDPOINT << "Sending connection close packet.";
- ScopedEncryptionLevelContext context(this,
- GetConnectionCloseEncryptionLevel());
- if (version().CanSendCoalescedPackets()) {
- coalesced_packet_.Clear();
- }
- ClearQueuedPackets();
- // If there was a packet write error, write the smallest close possible.
- ScopedPacketFlusher flusher(this);
- // Always bundle an ACK with connection close for debugging purpose.
- bool send_ack = error != QUIC_PACKET_WRITE_ERROR &&
- !uber_received_packet_manager_.IsAckFrameEmpty(
- QuicUtils::GetPacketNumberSpace(encryption_level_));
- if (GetQuicReloadableFlag(quic_single_ack_in_packet2)) {
- QUIC_RELOADABLE_FLAG_COUNT_N(quic_single_ack_in_packet2, 1, 2);
- send_ack = !packet_creator_.has_ack() && send_ack;
- }
- if (send_ack) {
- SendAck();
- }
- QuicConnectionCloseFrame* frame;
-
- frame = new QuicConnectionCloseFrame(transport_version(), error, ietf_error,
- details,
- framer_.current_received_frame_type());
- packet_creator_.ConsumeRetransmittableControlFrame(QuicFrame(frame));
- packet_creator_.FlushCurrentPacket();
- if (version().CanSendCoalescedPackets()) {
- FlushCoalescedPacket();
- }
- ClearQueuedPackets();
- return;
- }
- ScopedPacketFlusher flusher(this);
-
- // Now that the connection is being closed, discard any unsent packets
- // so the only packets to be sent will be connection close packets.
- if (version().CanSendCoalescedPackets()) {
- coalesced_packet_.Clear();
- }
- ClearQueuedPackets();
-
- for (EncryptionLevel level :
- {ENCRYPTION_INITIAL, ENCRYPTION_HANDSHAKE, ENCRYPTION_ZERO_RTT,
- ENCRYPTION_FORWARD_SECURE}) {
- if (!framer_.HasEncrypterOfEncryptionLevel(level)) {
- continue;
- }
- QUIC_DLOG(INFO) << ENDPOINT
- << "Sending connection close packet at level: " << level;
- ScopedEncryptionLevelContext context(this, level);
- // Bundle an ACK of the corresponding packet number space for debugging
- // purpose.
- bool send_ack = error != QUIC_PACKET_WRITE_ERROR &&
- !uber_received_packet_manager_.IsAckFrameEmpty(
- QuicUtils::GetPacketNumberSpace(encryption_level_));
- if (GetQuicReloadableFlag(quic_single_ack_in_packet2)) {
- QUIC_RELOADABLE_FLAG_COUNT_N(quic_single_ack_in_packet2, 2, 2);
- send_ack = !packet_creator_.has_ack() && send_ack;
- }
- if (send_ack) {
- QuicFrames frames;
- frames.push_back(GetUpdatedAckFrame());
- packet_creator_.FlushAckFrame(frames);
- }
-
- if (level == ENCRYPTION_FORWARD_SECURE &&
- perspective_ == Perspective::IS_SERVER) {
- visitor_->BeforeConnectionCloseSent();
- }
-
- auto* frame = new QuicConnectionCloseFrame(
- transport_version(), error, ietf_error, details,
- framer_.current_received_frame_type());
- packet_creator_.ConsumeRetransmittableControlFrame(QuicFrame(frame));
- packet_creator_.FlushCurrentPacket();
- }
- if (version().CanSendCoalescedPackets()) {
- FlushCoalescedPacket();
- }
- // Since the connection is closing, if the connection close packets were not
- // sent, then they should be discarded.
- ClearQueuedPackets();
-}
-
-void QuicConnection::TearDownLocalConnectionState(
- QuicErrorCode error,
- QuicIetfTransportErrorCodes ietf_error,
- const std::string& error_details,
- ConnectionCloseSource source) {
- QuicConnectionCloseFrame frame(transport_version(), error, ietf_error,
- error_details,
- framer_.current_received_frame_type());
- return TearDownLocalConnectionState(frame, source);
-}
-
-void QuicConnection::TearDownLocalConnectionState(
- const QuicConnectionCloseFrame& frame,
- ConnectionCloseSource source) {
- if (!connected_) {
- QUIC_DLOG(INFO) << "Connection is already closed.";
- return;
- }
-
- // If we are using a batch writer, flush packets queued in it, if any.
- FlushPackets();
- connected_ = false;
- QUICHE_DCHECK(visitor_ != nullptr);
- visitor_->OnConnectionClosed(frame, source);
- // LossDetectionTunerInterface::Finish() may be called from
- // sent_packet_manager_.OnConnectionClosed. Which may require the session to
- // finish its business first.
- sent_packet_manager_.OnConnectionClosed();
- if (debug_visitor_ != nullptr) {
- debug_visitor_->OnConnectionClosed(frame, source);
- }
- // Cancel the alarms so they don't trigger any action now that the
- // connection is closed.
- CancelAllAlarms();
- if (use_path_validator_) {
- QUIC_RELOADABLE_FLAG_COUNT_N(quic_pass_path_response_to_validator, 3, 4);
- CancelPathValidation();
- }
- peer_issued_cid_manager_.reset();
- self_issued_cid_manager_.reset();
-}
-
-void QuicConnection::CancelAllAlarms() {
- QUIC_DVLOG(1) << "Cancelling all QuicConnection alarms.";
-
- ack_alarm_->PermanentCancel();
- ping_alarm_->PermanentCancel();
- retransmission_alarm_->PermanentCancel();
- send_alarm_->PermanentCancel();
- mtu_discovery_alarm_->PermanentCancel();
- process_undecryptable_packets_alarm_->PermanentCancel();
- discard_previous_one_rtt_keys_alarm_->PermanentCancel();
- discard_zero_rtt_decryption_keys_alarm_->PermanentCancel();
- blackhole_detector_.StopDetection(/*permanent=*/true);
- idle_network_detector_.StopDetection();
-}
-
-QuicByteCount QuicConnection::max_packet_length() const {
- return packet_creator_.max_packet_length();
-}
-
-void QuicConnection::SetMaxPacketLength(QuicByteCount length) {
- long_term_mtu_ = length;
- stats_.max_egress_mtu = std::max(stats_.max_egress_mtu, long_term_mtu_);
- MaybeUpdatePacketCreatorMaxPacketLengthAndPadding();
-}
-
-bool QuicConnection::HasQueuedData() const {
- return packet_creator_.HasPendingFrames() || !buffered_packets_.empty();
-}
-
-void QuicConnection::SetNetworkTimeouts(QuicTime::Delta handshake_timeout,
- QuicTime::Delta idle_timeout) {
- QUIC_BUG_IF(quic_bug_12714_29, idle_timeout > handshake_timeout)
- << "idle_timeout:" << idle_timeout.ToMilliseconds()
- << " handshake_timeout:" << handshake_timeout.ToMilliseconds();
- // Adjust the idle timeout on client and server to prevent clients from
- // sending requests to servers which have already closed the connection.
- if (perspective_ == Perspective::IS_SERVER) {
- idle_timeout = idle_timeout + QuicTime::Delta::FromSeconds(3);
- } else if (idle_timeout > QuicTime::Delta::FromSeconds(1)) {
- idle_timeout = idle_timeout - QuicTime::Delta::FromSeconds(1);
- }
- idle_network_detector_.SetTimeouts(handshake_timeout, idle_timeout);
-}
-
-void QuicConnection::SetPingAlarm() {
- if (!connected_) {
- return;
- }
- 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.
- return;
- }
- if (!visitor_->ShouldKeepConnectionAlive()) {
- ping_alarm_->Cancel();
- // Don't send a ping unless the application (ie: HTTP/3) says to, usually
- // because it is expecting a response from the server.
- return;
- }
- if (initial_retransmittable_on_wire_timeout_.IsInfinite() ||
- sent_packet_manager_.HasInFlightPackets() ||
- retransmittable_on_wire_ping_count_ >
- 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_,
- QuicTime::Delta::FromSeconds(1));
- } else {
- // Servers do not send 15s PINGs.
- ping_alarm_->Cancel();
- }
- return;
- }
- QUICHE_DCHECK_LT(initial_retransmittable_on_wire_timeout_, ping_timeout_);
- QuicTime::Delta retransmittable_on_wire_timeout =
- initial_retransmittable_on_wire_timeout_;
- int max_aggressive_retransmittable_on_wire_ping_count =
- GetQuicFlag(FLAGS_quic_max_aggressive_retransmittable_on_wire_ping_count);
- QUICHE_DCHECK_LE(0, max_aggressive_retransmittable_on_wire_ping_count);
- if (consecutive_retransmittable_on_wire_ping_count_ >
- max_aggressive_retransmittable_on_wire_ping_count) {
- // Exponentially back off the timeout if the number of consecutive
- // retransmittable on wire pings has exceeds the allowance.
- int shift = consecutive_retransmittable_on_wire_ping_count_ -
- max_aggressive_retransmittable_on_wire_ping_count;
- retransmittable_on_wire_timeout =
- initial_retransmittable_on_wire_timeout_ * (1 << shift);
- }
- // If it's already set to an earlier time, then don't update it.
- if (ping_alarm_->IsSet() &&
- ping_alarm_->deadline() <
- clock_->ApproximateNow() + retransmittable_on_wire_timeout) {
- return;
- }
-
- if (retransmittable_on_wire_timeout < 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,
- kAlarmGranularity);
- if (max_aggressive_retransmittable_on_wire_ping_count != 0) {
- consecutive_retransmittable_on_wire_ping_count_++;
- }
- retransmittable_on_wire_ping_count_++;
- return;
- }
-
- ping_alarm_->Update(clock_->ApproximateNow() + ping_timeout_,
- kAlarmGranularity);
-}
-
-void QuicConnection::SetRetransmissionAlarm() {
- if (!connected_) {
- if (retransmission_alarm_->IsSet()) {
- QUIC_BUG(quic_bug_10511_29)
- << ENDPOINT << "Retransmission alarm is set while disconnected";
- retransmission_alarm_->Cancel();
- }
- return;
- }
- if (packet_creator_.PacketFlusherAttached()) {
- pending_retransmission_alarm_ = true;
- return;
- }
- if (LimitedByAmplificationFactor()) {
- // Do not set retransmission timer if connection is anti-amplification limit
- // throttled. Otherwise, nothing can be sent when timer fires.
- retransmission_alarm_->Cancel();
- return;
- }
-
- retransmission_alarm_->Update(GetRetransmissionDeadline(), kAlarmGranularity);
-}
-
-void QuicConnection::MaybeSetMtuAlarm(QuicPacketNumber sent_packet_number) {
- if (mtu_discovery_alarm_->IsSet() ||
- !mtu_discoverer_.ShouldProbeMtu(sent_packet_number)) {
- return;
- }
- mtu_discovery_alarm_->Set(clock_->ApproximateNow());
-}
-
-QuicConnection::ScopedPacketFlusher::ScopedPacketFlusher(
- QuicConnection* connection)
- : connection_(connection),
- flush_and_set_pending_retransmission_alarm_on_delete_(false),
- handshake_packet_sent_(connection != nullptr &&
- connection->handshake_packet_sent_) {
- if (connection_ == nullptr) {
- return;
- }
-
- if (!connection_->packet_creator_.PacketFlusherAttached()) {
- flush_and_set_pending_retransmission_alarm_on_delete_ = true;
- connection->packet_creator_.AttachPacketFlusher();
- }
-}
-
-QuicConnection::ScopedPacketFlusher::~ScopedPacketFlusher() {
- if (connection_ == nullptr || !connection_->connected()) {
- return;
- }
-
- if (flush_and_set_pending_retransmission_alarm_on_delete_) {
- const QuicTime ack_timeout =
- connection_->uber_received_packet_manager_.GetEarliestAckTimeout();
- if (ack_timeout.IsInitialized()) {
- if (ack_timeout <= connection_->clock_->ApproximateNow() &&
- !connection_->CanWrite(NO_RETRANSMITTABLE_DATA)) {
- // Cancel ACK alarm if connection is write blocked, and ACK will be
- // sent when connection gets unblocked.
- connection_->ack_alarm_->Cancel();
- } else if (!connection_->ack_alarm_->IsSet() ||
- connection_->ack_alarm_->deadline() > ack_timeout) {
- connection_->ack_alarm_->Update(ack_timeout, QuicTime::Delta::Zero());
- }
- }
- if (connection_->ack_alarm_->IsSet() &&
- connection_->ack_alarm_->deadline() <=
- connection_->clock_->ApproximateNow()) {
- // An ACK needs to be sent right now. This ACK did not get bundled
- // because either there was no data to write or packets were marked as
- // received after frames were queued in the generator.
- if (connection_->send_alarm_->IsSet() &&
- connection_->send_alarm_->deadline() <=
- connection_->clock_->ApproximateNow()) {
- // If send alarm will go off soon, let send alarm send the ACK.
- connection_->ack_alarm_->Cancel();
- } else if (connection_->SupportsMultiplePacketNumberSpaces()) {
- connection_->SendAllPendingAcks();
- } else {
- connection_->SendAck();
- }
- }
- connection_->packet_creator_.Flush();
- if (connection_->version().CanSendCoalescedPackets()) {
- connection_->MaybeCoalescePacketOfHigherSpace();
- connection_->FlushCoalescedPacket();
- }
- connection_->FlushPackets();
- if (!handshake_packet_sent_ && connection_->handshake_packet_sent_) {
- // This would cause INITIAL key to be dropped. Drop keys here to avoid
- // missing the write keys in the middle of writing.
- connection_->visitor_->OnHandshakePacketSent();
- }
- // Reset transmission type.
- connection_->SetTransmissionType(NOT_RETRANSMISSION);
-
- // Once all transmissions are done, check if there is any outstanding data
- // to send and notify the congestion controller if not.
- //
- // Note that this means that the application limited check will happen as
- // soon as the last flusher gets destroyed, which is typically after a
- // single stream write is finished. This means that if all the data from a
- // single write goes through the connection, the application-limited signal
- // will fire even if the caller does a write operation immediately after.
- // There are two important approaches to remedy this situation:
- // (1) Instantiate ScopedPacketFlusher before performing multiple subsequent
- // writes, thus deferring this check until all writes are done.
- // (2) Write data in chunks sufficiently large so that they cause the
- // connection to be limited by the congestion control. Typically, this
- // would mean writing chunks larger than the product of the current
- // pacing rate and the pacer granularity. So, for instance, if the
- // pacing rate of the connection is 1 Gbps, and the pacer granularity is
- // 1 ms, the caller should send at least 125k bytes in order to not
- // be marked as application-limited.
- connection_->CheckIfApplicationLimited();
-
- if (connection_->pending_retransmission_alarm_) {
- connection_->SetRetransmissionAlarm();
- connection_->pending_retransmission_alarm_ = false;
- }
- }
- QUICHE_DCHECK_EQ(flush_and_set_pending_retransmission_alarm_on_delete_,
- !connection_->packet_creator_.PacketFlusherAttached());
-}
-
-QuicConnection::ScopedEncryptionLevelContext::ScopedEncryptionLevelContext(
- QuicConnection* connection,
- EncryptionLevel encryption_level)
- : connection_(connection), latched_encryption_level_(ENCRYPTION_INITIAL) {
- if (connection_ == nullptr) {
- return;
- }
- latched_encryption_level_ = connection_->encryption_level_;
- connection_->SetDefaultEncryptionLevel(encryption_level);
-}
-
-QuicConnection::ScopedEncryptionLevelContext::~ScopedEncryptionLevelContext() {
- if (connection_ == nullptr || !connection_->connected_) {
- return;
- }
- connection_->SetDefaultEncryptionLevel(latched_encryption_level_);
-}
-
-QuicConnection::BufferedPacket::BufferedPacket(
- const SerializedPacket& packet,
- const QuicSocketAddress& self_address,
- const QuicSocketAddress& peer_address)
- : encrypted_buffer(CopyBuffer(packet), packet.encrypted_length),
- self_address(self_address),
- peer_address(peer_address) {}
-
-QuicConnection::BufferedPacket::BufferedPacket(
- char* encrypted_buffer,
- QuicPacketLength encrypted_length,
- const QuicSocketAddress& self_address,
- const QuicSocketAddress& peer_address)
- : encrypted_buffer(CopyBuffer(encrypted_buffer, encrypted_length),
- encrypted_length),
- self_address(self_address),
- peer_address(peer_address) {}
-
-QuicConnection::BufferedPacket::~BufferedPacket() {
- delete[] encrypted_buffer.data();
-}
-
-HasRetransmittableData QuicConnection::IsRetransmittable(
- const SerializedPacket& packet) {
- // Retransmitted packets retransmittable frames are owned by the unacked
- // packet map, but are not present in the serialized packet.
- if (packet.transmission_type != NOT_RETRANSMISSION ||
- !packet.retransmittable_frames.empty()) {
- return HAS_RETRANSMITTABLE_DATA;
- } else {
- return NO_RETRANSMITTABLE_DATA;
- }
-}
-
-bool QuicConnection::IsTerminationPacket(const SerializedPacket& packet,
- QuicErrorCode* error_code) {
- if (packet.retransmittable_frames.empty()) {
- return false;
- }
- for (const QuicFrame& frame : packet.retransmittable_frames) {
- if (frame.type == CONNECTION_CLOSE_FRAME) {
- *error_code = frame.connection_close_frame->quic_error_code;
- return true;
- }
- }
- return false;
-}
-
-void QuicConnection::SetMtuDiscoveryTarget(QuicByteCount target) {
- QUIC_DVLOG(2) << ENDPOINT << "SetMtuDiscoveryTarget: " << target;
- mtu_discoverer_.Disable();
- mtu_discoverer_.Enable(max_packet_length(), GetLimitedMaxPacketSize(target));
-}
-
-QuicByteCount QuicConnection::GetLimitedMaxPacketSize(
- QuicByteCount suggested_max_packet_size) {
- if (!peer_address().IsInitialized()) {
- QUIC_BUG(quic_bug_10511_30)
- << "Attempted to use a connection without a valid peer address";
- return suggested_max_packet_size;
- }
-
- const QuicByteCount writer_limit = writer_->GetMaxPacketSize(peer_address());
-
- QuicByteCount max_packet_size = suggested_max_packet_size;
- if (max_packet_size > writer_limit) {
- max_packet_size = writer_limit;
- }
- if (max_packet_size > peer_max_packet_size_) {
- max_packet_size = peer_max_packet_size_;
- }
- if (max_packet_size > kMaxOutgoingPacketSize) {
- max_packet_size = kMaxOutgoingPacketSize;
- }
- return max_packet_size;
-}
-
-void QuicConnection::SendMtuDiscoveryPacket(QuicByteCount target_mtu) {
- // Currently, this limit is ensured by the caller.
- QUICHE_DCHECK_EQ(target_mtu, GetLimitedMaxPacketSize(target_mtu));
-
- // Send the probe.
- packet_creator_.GenerateMtuDiscoveryPacket(target_mtu);
-}
-
-// TODO(zhongyi): change this method to generate a connectivity probing packet
-// and let the caller to call writer to write the packet and handle write
-// status.
-bool QuicConnection::SendConnectivityProbingPacket(
- QuicPacketWriter* probing_writer,
- const QuicSocketAddress& peer_address) {
- return SendGenericPathProbePacket(probing_writer, peer_address,
- /* is_response= */ false);
-}
-
-void QuicConnection::SendConnectivityProbingResponsePacket(
- const QuicSocketAddress& peer_address) {
- SendGenericPathProbePacket(nullptr, peer_address,
- /* is_response= */ true);
-}
-
-bool QuicConnection::SendGenericPathProbePacket(
- QuicPacketWriter* probing_writer,
- const QuicSocketAddress& peer_address,
- bool is_response) {
- QUICHE_DCHECK(peer_address.IsInitialized());
- if (!connected_) {
- QUIC_BUG(quic_bug_10511_31)
- << "Not sending connectivity probing packet as connection is "
- << "disconnected.";
- return false;
- }
- if (perspective_ == Perspective::IS_SERVER && probing_writer == nullptr) {
- // Server can use default packet writer to write packet.
- probing_writer = writer_;
- }
- QUICHE_DCHECK(probing_writer);
-
- if (probing_writer->IsWriteBlocked()) {
- QUIC_DLOG(INFO)
- << ENDPOINT
- << "Writer blocked when sending connectivity probing packet.";
- if (probing_writer == writer_) {
- // Visitor should not be write blocked if the probing writer is not the
- // default packet writer.
- visitor_->OnWriteBlocked();
- }
- return true;
- }
-
- QUIC_DLOG(INFO) << ENDPOINT
- << "Sending path probe packet for connection_id = "
- << default_path_.server_connection_id;
-
- std::unique_ptr<SerializedPacket> probing_packet;
- if (!version().HasIetfQuicFrames()) {
- // Non-IETF QUIC, generate a padded ping regardless of whether this is a
- // request or a response.
- probing_packet = packet_creator_.SerializeConnectivityProbingPacket();
- } else if (is_response) {
- QUICHE_DCHECK(!send_path_response_);
- // IETF QUIC path response.
- // Respond to path probe request using IETF QUIC PATH_RESPONSE frame.
- probing_packet =
- packet_creator_.SerializePathResponseConnectivityProbingPacket(
- received_path_challenge_payloads_,
- /*is_padded=*/false);
- received_path_challenge_payloads_.clear();
- } else {
- // IETF QUIC path challenge.
- // Send a path probe request using IETF QUIC PATH_CHALLENGE frame.
- transmitted_connectivity_probe_payload_ =
- std::make_unique<QuicPathFrameBuffer>();
- random_generator_->RandBytes(transmitted_connectivity_probe_payload_.get(),
- sizeof(QuicPathFrameBuffer));
- probing_packet =
- packet_creator_.SerializePathChallengeConnectivityProbingPacket(
- *transmitted_connectivity_probe_payload_);
- if (!probing_packet) {
- transmitted_connectivity_probe_payload_ = nullptr;
- }
- }
- QUICHE_DCHECK_EQ(IsRetransmittable(*probing_packet), NO_RETRANSMITTABLE_DATA);
- return WritePacketUsingWriter(std::move(probing_packet), probing_writer,
- self_address(), peer_address,
- /*measure_rtt=*/true);
-}
-
-bool QuicConnection::WritePacketUsingWriter(
- std::unique_ptr<SerializedPacket> packet,
- QuicPacketWriter* writer,
- const QuicSocketAddress& self_address,
- const QuicSocketAddress& peer_address,
- bool measure_rtt) {
- const QuicTime packet_send_time = clock_->Now();
- QUIC_DVLOG(2) << ENDPOINT
- << "Sending path probe packet for server connection ID "
- << default_path_.server_connection_id << std::endl
- << quiche::QuicheTextUtils::HexDump(absl::string_view(
- packet->encrypted_buffer, packet->encrypted_length));
- WriteResult result = writer->WritePacket(
- packet->encrypted_buffer, packet->encrypted_length, self_address.host(),
- peer_address, per_packet_options_);
-
- // If using a batch writer and the probing packet is buffered, flush it.
- if (writer->IsBatchMode() && result.status == WRITE_STATUS_OK &&
- result.bytes_written == 0) {
- result = writer->Flush();
- }
-
- if (IsWriteError(result.status)) {
- // Write error for any connectivity probe should not affect the connection
- // as it is sent on a different path.
- QUIC_DLOG(INFO) << ENDPOINT << "Write probing packet failed with error = "
- << result.error_code;
- return false;
- }
-
- // Send in currrent path. Call OnPacketSent regardless of the write result.
- sent_packet_manager_.OnPacketSent(packet.get(), packet_send_time,
- packet->transmission_type,
- NO_RETRANSMITTABLE_DATA, measure_rtt);
-
- if (debug_visitor_ != nullptr) {
- if (sent_packet_manager_.unacked_packets().empty()) {
- QUIC_BUG(quic_bug_10511_32)
- << "Unacked map is empty right after packet is sent";
- } else {
- debug_visitor_->OnPacketSent(
- packet->packet_number, packet->encrypted_length,
- packet->has_crypto_handshake, packet->transmission_type,
- packet->encryption_level,
- sent_packet_manager_.unacked_packets()
- .rbegin()
- ->retransmittable_frames,
- packet->nonretransmittable_frames, packet_send_time);
- }
- }
-
- if (IsWriteBlockedStatus(result.status)) {
- if (writer == writer_) {
- // Visitor should not be write blocked if the probing writer is not the
- // default packet writer.
- visitor_->OnWriteBlocked();
- }
- if (result.status == WRITE_STATUS_BLOCKED_DATA_BUFFERED) {
- QUIC_DLOG(INFO) << ENDPOINT << "Write probing packet blocked";
- }
- }
-
- return true;
-}
-
-void QuicConnection::DisableMtuDiscovery() {
- mtu_discoverer_.Disable();
- mtu_discovery_alarm_->Cancel();
-}
-
-void QuicConnection::DiscoverMtu() {
- QUICHE_DCHECK(!mtu_discovery_alarm_->IsSet());
-
- const QuicPacketNumber largest_sent_packet =
- sent_packet_manager_.GetLargestSentPacket();
- if (mtu_discoverer_.ShouldProbeMtu(largest_sent_packet)) {
- ++mtu_probe_count_;
- SendMtuDiscoveryPacket(
- mtu_discoverer_.GetUpdatedMtuProbeSize(largest_sent_packet));
- }
- QUICHE_DCHECK(!mtu_discovery_alarm_->IsSet());
-}
-
-void QuicConnection::OnEffectivePeerMigrationValidated() {
- if (active_effective_peer_migration_type_ == NO_CHANGE) {
- QUIC_BUG(quic_bug_10511_33) << "No migration underway.";
- return;
- }
- highest_packet_sent_before_effective_peer_migration_.Clear();
- const bool send_address_token =
- active_effective_peer_migration_type_ != PORT_CHANGE;
- active_effective_peer_migration_type_ = NO_CHANGE;
- ++stats_.num_validated_peer_migration;
- 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) {
- debug_visitor_->OnPeerMigrationValidated(
- now - stats_.handshake_completion_time);
- } else {
- QUIC_BUG(quic_bug_10511_34)
- << "Handshake completion time is larger than current time.";
- }
- }
-
- // Lift anti-amplification limit.
- default_path_.validated = true;
- alternative_path_.Clear();
- if (send_address_token) {
- visitor_->MaybeSendAddressToken();
- }
-}
-
-void QuicConnection::StartEffectivePeerMigration(AddressChangeType type) {
- // TODO(fayang): Currently, all peer address change type are allowed. Need to
- // add a method ShouldAllowPeerAddressChange(PeerAddressChangeType type) to
- // determine whether |type| is allowed.
- if (!validate_client_addresses_) {
- if (type == NO_CHANGE) {
- QUIC_BUG(quic_bug_10511_35)
- << "EffectivePeerMigration started without address change.";
- return;
- }
- QUIC_DLOG(INFO)
- << ENDPOINT << "Effective peer's ip:port changed from "
- << default_path_.peer_address.ToString() << " to "
- << GetEffectivePeerAddressFromCurrentPacket().ToString()
- << ", address change type is " << type
- << ", migrating connection without validating new client address.";
-
- highest_packet_sent_before_effective_peer_migration_ =
- sent_packet_manager_.GetLargestSentPacket();
- default_path_.peer_address = GetEffectivePeerAddressFromCurrentPacket();
- active_effective_peer_migration_type_ = type;
-
- OnConnectionMigration();
- 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)
- << "EffectivePeerMigration started without address change.";
- return;
- }
- if (GetQuicReloadableFlag(
- quic_flush_pending_frames_and_padding_bytes_on_migration)) {
- QUIC_RELOADABLE_FLAG_COUNT(
- quic_flush_pending_frames_and_padding_bytes_on_migration);
- // There could be pending NEW_TOKEN_FRAME triggered by non-probing
- // PATH_RESPONSE_FRAME in the same packet or pending padding bytes in the
- // packet creator.
- packet_creator_.FlushCurrentPacket();
- packet_creator_.SendRemainingPendingPadding();
- if (!connected_) {
- return;
- }
- } else {
- if (packet_creator_.HasPendingFrames()) {
- packet_creator_.FlushCurrentPacket();
- if (!connected_) {
- return;
- }
- }
- }
-
- // Action items:
- // 1. Switch congestion controller;
- // 2. Update default_path_ (addresses, validation and bytes accounting);
- // 3. Save previous default path if needed;
- // 4. Kick off reverse path validation if needed.
- // Items 1 and 2 are must-to-do. Items 3 and 4 depends on if the new address
- // is validated or not and which path the incoming packet is on.
-
- const QuicSocketAddress current_effective_peer_address =
- GetEffectivePeerAddressFromCurrentPacket();
- QUIC_DLOG(INFO) << ENDPOINT << "Effective peer's ip:port changed from "
- << default_path_.peer_address.ToString() << " to "
- << current_effective_peer_address.ToString()
- << ", address change type is " << type
- << ", migrating connection.";
-
- const QuicSocketAddress previous_direct_peer_address = direct_peer_address_;
- PathState previous_default_path = std::move(default_path_);
- active_effective_peer_migration_type_ = type;
- MaybeClearQueuedPacketsOnPathChange();
- OnConnectionMigration();
-
- // Update congestion controller if the address change type is not PORT_CHANGE.
- if (type == PORT_CHANGE) {
- QUICHE_DCHECK(previous_default_path.validated ||
- (alternative_path_.validated &&
- alternative_path_.send_algorithm != nullptr));
- // No need to store previous congestion controller because either the new
- // default path is validated or the alternative path is validated and
- // already has associated congestion controller.
- } else {
- previous_default_path.rtt_stats.emplace();
- previous_default_path.rtt_stats->CloneFrom(
- *sent_packet_manager_.GetRttStats());
- // If the new peer address share the same IP with the alternative path, the
- // connection should switch to the congestion controller of the alternative
- // path. Otherwise, the connection should use a brand new one.
- // In order to re-use existing code in sent_packet_manager_, reset
- // congestion controller to initial state first and then change to the one
- // on alternative path.
- // TODO(danzh) combine these two steps into one after deprecating gQUIC.
- previous_default_path.send_algorithm = OnPeerIpAddressChanged();
-
- if (alternative_path_.peer_address.host() ==
- current_effective_peer_address.host() &&
- alternative_path_.send_algorithm != nullptr) {
- // Update the default path with the congestion controller of the
- // alternative path.
- sent_packet_manager_.SetSendAlgorithm(
- alternative_path_.send_algorithm.release());
- sent_packet_manager_.SetRttStats(
- std::move(alternative_path_.rtt_stats).value());
- }
- }
- // Update to the new peer address.
- UpdatePeerAddress(last_received_packet_info_.source_address);
- // Update the default path.
- if (IsAlternativePath(last_received_packet_info_.destination_address,
- current_effective_peer_address)) {
- SetDefaultPathState(std::move(alternative_path_));
- } else {
- QuicConnectionId client_connection_id;
- 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));
- // The path is considered validated if its peer IP address matches any
- // validated path's peer IP address.
- default_path_.validated =
- (alternative_path_.peer_address.host() ==
- current_effective_peer_address.host() &&
- alternative_path_.validated) ||
- (previous_default_path.validated && type == PORT_CHANGE);
- }
- 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_;
- last_received_packet_info_.received_bytes_counted = true;
- }
-
- if (!previous_default_path.validated) {
- // If the old address is under validation, cancel and fail it. Failing to
- // validate the old path shouldn't take any effect.
- QUIC_DVLOG(1) << "Cancel validation of previous peer address change to "
- << previous_default_path.peer_address
- << " upon peer migration to " << default_path_.peer_address;
- path_validator_.CancelPathValidation();
- ++stats_.num_peer_migration_while_validating_default_path;
- }
-
- // Clear alternative path if the new default path shares the same IP as the
- // alternative path.
- if (alternative_path_.peer_address.host() ==
- default_path_.peer_address.host()) {
- alternative_path_.Clear();
- }
-
- if (default_path_.validated) {
- QUIC_DVLOG(1) << "Peer migrated to a validated address.";
- // No need to save previous default path, validate new peer address or
- // update bytes sent/received.
- if (!(previous_default_path.validated && type == PORT_CHANGE)) {
- // The alternative path was validated because of proactive reverse path
- // validation.
- ++stats_.num_peer_migration_to_proactively_validated_address;
- }
- OnEffectivePeerMigrationValidated();
- return;
- }
-
- // The new default address is not validated yet. Anti-amplification limit is
- // enforced.
- QUICHE_DCHECK(EnforceAntiAmplificationLimit());
- QUIC_DVLOG(1) << "Apply anti-amplification limit to effective peer address "
- << default_path_.peer_address << " with "
- << default_path_.bytes_sent_before_address_validation
- << " bytes sent and "
- << default_path_.bytes_received_before_address_validation
- << " bytes received.";
-
- QUICHE_DCHECK(!alternative_path_.peer_address.IsInitialized() ||
- alternative_path_.peer_address.host() !=
- default_path_.peer_address.host());
-
- // Save previous default path to the altenative path.
- if (previous_default_path.validated) {
- // The old path is a validated path which the connection might revert back
- // to later. Store it as the alternative path.
- alternative_path_ = std::move(previous_default_path);
- QUICHE_DCHECK(alternative_path_.send_algorithm != nullptr);
- }
-
- // If the new address is not validated and the connection is not already
- // validating that address, a new reverse path validation is needed.
- if (!path_validator_.IsValidatingPeerAddress(
- current_effective_peer_address)) {
- ++stats_.num_reverse_path_validtion_upon_migration;
- ValidatePath(std::make_unique<ReversePathValidationContext>(
- default_path_.self_address, peer_address(),
- default_path_.peer_address, this),
- std::make_unique<ReversePathValidationResultDelegate>(
- this, previous_direct_peer_address));
- } else {
- QUIC_DVLOG(1) << "Peer address " << default_path_.peer_address
- << " is already under validation, wait for result.";
- ++stats_.num_peer_migration_to_proactively_validated_address;
- }
-}
-
-void QuicConnection::OnConnectionMigration() {
- if (debug_visitor_ != nullptr) {
- const QuicTime now = clock_->ApproximateNow();
- if (now >= stats_.handshake_completion_time) {
- debug_visitor_->OnPeerAddressChange(
- active_effective_peer_migration_type_,
- now - stats_.handshake_completion_time);
- }
- }
- visitor_->OnConnectionMigration(active_effective_peer_migration_type_);
- if (active_effective_peer_migration_type_ != PORT_CHANGE &&
- active_effective_peer_migration_type_ != IPV4_SUBNET_CHANGE &&
- !validate_client_addresses_) {
- sent_packet_manager_.OnConnectionMigration(/*reset_send_algorithm=*/false);
- }
-}
-
-bool QuicConnection::IsCurrentPacketConnectivityProbing() const {
- return is_current_packet_connectivity_probing_;
-}
-
-bool QuicConnection::ack_frame_updated() const {
- return uber_received_packet_manager_.IsAckFrameUpdated();
-}
-
-absl::string_view QuicConnection::GetCurrentPacket() {
- if (current_packet_data_ == nullptr) {
- return absl::string_view();
- }
- return absl::string_view(current_packet_data_, last_size_);
-}
-
-bool QuicConnection::MaybeConsiderAsMemoryCorruption(
- const QuicStreamFrame& frame) {
- if (QuicUtils::IsCryptoStreamId(transport_version(), frame.stream_id) ||
- last_decrypted_packet_level_ != ENCRYPTION_INITIAL) {
- return false;
- }
-
- if (perspective_ == Perspective::IS_SERVER &&
- frame.data_length >= sizeof(kCHLO) &&
- strncmp(frame.data_buffer, reinterpret_cast<const char*>(&kCHLO),
- sizeof(kCHLO)) == 0) {
- return true;
- }
-
- if (perspective_ == Perspective::IS_CLIENT &&
- frame.data_length >= sizeof(kREJ) &&
- strncmp(frame.data_buffer, reinterpret_cast<const char*>(&kREJ),
- sizeof(kREJ)) == 0) {
- return true;
- }
-
- 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_) {
- return;
- }
-
- bool application_limited =
- buffered_packets_.empty() && !visitor_->WillingAndAbleToWrite();
-
- if (!application_limited) {
- 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;
- if (version().HasIetfQuicFrames()) {
- if (!QuicUtils::IsProbingFrame(type)) {
- MaybeStartIetfPeerMigration();
- return connected_;
- }
- QuicSocketAddress current_effective_peer_address =
- GetEffectivePeerAddressFromCurrentPacket();
- if (!count_bytes_on_alternative_path_separately_ ||
- 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,
- current_effective_peer_address)) {
- QUIC_DVLOG(1)
- << "The peer is probing a new path with effective peer address "
- << current_effective_peer_address << ", self address "
- << last_received_packet_info_.destination_address;
- if (!validate_client_addresses_) {
- QuicConnectionId client_cid;
- absl::optional<StatelessResetToken> stateless_reset_token;
- FindMatchingOrNewClientConnectionIdOrToken(
- default_path_, alternative_path_,
- last_packet_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);
- } 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
- // handshake gets comfirmed is meaningless because anyone can respond to
- // it. If the connection is validating the default path, this
- // alternative path is currently the only validated path which shouldn't
- // be overridden.
- QUIC_DVLOG(1) << "The connection hasn't finished handshake or is "
- "validating a recent peer address change.";
- QUIC_BUG_IF(quic_bug_12714_30,
- 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);
- // 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);
- should_proactively_validate_peer_address_on_path_challenge_ = true;
- }
- }
- MaybeUpdateBytesReceivedFromAlternativeAddress(last_size_);
- return connected_;
- }
- // Packet content is tracked to identify connectivity probe in non-IETF
- // version, where a connectivity probe is defined as
- // - a padded PING packet with peer address change received by server,
- // - a padded PING packet on new path received by client.
-
- if (current_packet_content_ == NOT_PADDED_PING) {
- // We have already learned the current packet is not a connectivity
- // probing packet. Peer migration should have already been started earlier
- // if needed.
- return connected_;
- }
-
- if (type == PING_FRAME) {
- if (current_packet_content_ == NO_FRAMES_RECEIVED) {
- current_packet_content_ = FIRST_FRAME_IS_PING;
- return connected_;
- }
- }
-
- // In Google QUIC, we look for a packet with just a PING and PADDING.
- // If the condition is met, mark things as connectivity-probing, causing
- // later processing to generate the correct response.
- if (type == PADDING_FRAME && current_packet_content_ == FIRST_FRAME_IS_PING) {
- current_packet_content_ = SECOND_FRAME_IS_PADDING;
- if (perspective_ == Perspective::IS_SERVER) {
- is_current_packet_connectivity_probing_ =
- current_effective_peer_migration_type_ != NO_CHANGE;
- QUIC_DLOG_IF(INFO, is_current_packet_connectivity_probing_)
- << ENDPOINT
- << "Detected connectivity probing packet. "
- "current_effective_peer_migration_type_:"
- << current_effective_peer_migration_type_;
- } else {
- is_current_packet_connectivity_probing_ =
- (last_received_packet_info_.source_address != peer_address()) ||
- (last_received_packet_info_.destination_address !=
- default_path_.self_address);
- QUIC_DLOG_IF(INFO, is_current_packet_connectivity_probing_)
- << ENDPOINT
- << "Detected connectivity probing packet. "
- "last_packet_source_address:"
- << last_received_packet_info_.source_address
- << ", peer_address_:" << peer_address()
- << ", last_packet_destination_address:"
- << last_received_packet_info_.destination_address
- << ", default path self_address :" << default_path_.self_address;
- }
- return connected_;
- }
-
- current_packet_content_ = NOT_PADDED_PING;
- if (GetLargestReceivedPacket().IsInitialized() &&
- last_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
- // confirmed not a connectivity probing packet.
- StartEffectivePeerMigration(current_effective_peer_migration_type_);
- }
- }
- current_effective_peer_migration_type_ = NO_CHANGE;
- return connected_;
-}
-
-void QuicConnection::MaybeStartIetfPeerMigration() {
- QUICHE_DCHECK(version().HasIetfQuicFrames());
- if (current_effective_peer_migration_type_ != NO_CHANGE &&
- !IsHandshakeConfirmed()) {
- QUIC_LOG_EVERY_N_SEC(INFO, 60)
- << ENDPOINT << "Effective peer's ip:port changed from "
- << default_path_.peer_address.ToString() << " to "
- << GetEffectivePeerAddressFromCurrentPacket().ToString()
- << " before handshake confirmed, "
- "current_effective_peer_migration_type_: "
- << current_effective_peer_migration_type_;
- // Peer migrated before handshake gets confirmed.
- CloseConnection((current_effective_peer_migration_type_ == PORT_CHANGE
- ? QUIC_PEER_PORT_CHANGE_HANDSHAKE_UNCONFIRMED
- : QUIC_CONNECTION_MIGRATION_HANDSHAKE_UNCONFIRMED),
- "Peer address changed before handshake is confirmed.",
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
- return;
- }
-
- if (GetLargestReceivedPacket().IsInitialized() &&
- last_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.
- // TODO(fayang): When multiple packet number spaces is supported, only
- // start peer migration for the application data.
- if (!validate_client_addresses_) {
- UpdatePeerAddress(last_received_packet_info_.source_address);
- }
- StartEffectivePeerMigration(current_effective_peer_migration_type_);
- } else {
- UpdatePeerAddress(last_received_packet_info_.source_address);
- }
- }
- current_effective_peer_migration_type_ = NO_CHANGE;
-}
-
-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_,
- SupportsMultiplePacketNumberSpaces()
- ? sent_packet_manager_.GetLargestPacketPeerKnowsIsAcked(
- last_decrypted_packet_level_)
- : sent_packet_manager_.largest_packet_peer_knows_is_acked());
- }
- // Always reset the retransmission alarm when an ack comes in, since we now
- // have a better estimate of the current rtt than when it was set.
- SetRetransmissionAlarm();
- if (acked_new_packet) {
- OnForwardProgressMade();
- } else if (default_enable_5rto_blackhole_detection_ &&
- !sent_packet_manager_.HasInFlightPackets() &&
- blackhole_detector_.IsDetectionInProgress()) {
- // In case no new packets get acknowledged, it is possible packets are
- // detected lost because of time based loss detection. Cancel blackhole
- // detection if there is no packets in flight.
- blackhole_detector_.StopDetection(/*permanent=*/false);
- }
-
- if (send_stop_waiting) {
- ++stop_waiting_count_;
- } else {
- stop_waiting_count_ = 0;
- }
-}
-
-void QuicConnection::SetSessionNotifier(
- SessionNotifierInterface* session_notifier) {
- sent_packet_manager_.SetSessionNotifier(session_notifier);
-}
-
-void QuicConnection::SetDataProducer(
- QuicStreamFrameDataProducer* data_producer) {
- framer_.set_data_producer(data_producer);
-}
-
-void QuicConnection::SetTransmissionType(TransmissionType type) {
- packet_creator_.SetTransmissionType(type);
-}
-
-void QuicConnection::UpdateReleaseTimeIntoFuture() {
- QUICHE_DCHECK(supports_release_time_);
-
- const QuicTime::Delta prior_max_release_time = release_time_into_future_;
- release_time_into_future_ = std::max(
- QuicTime::Delta::FromMilliseconds(kMinReleaseTimeIntoFutureMs),
- std::min(
- QuicTime::Delta::FromMilliseconds(
- GetQuicFlag(FLAGS_quic_max_pace_time_into_future_ms)),
- sent_packet_manager_.GetRttStats()->SmoothedOrInitialRtt() *
- GetQuicFlag(FLAGS_quic_pace_time_into_future_srtt_fraction)));
- QUIC_DVLOG(3) << "Updated max release time delay from "
- << prior_max_release_time << " to "
- << release_time_into_future_;
-}
-
-void QuicConnection::ResetAckStates() {
- ack_alarm_->Cancel();
- stop_waiting_count_ = 0;
- uber_received_packet_manager_.ResetAckStates(encryption_level_);
-}
-
-MessageStatus QuicConnection::SendMessage(QuicMessageId message_id,
- absl::Span<QuicMemSlice> message,
- bool flush) {
- if (!VersionSupportsMessageFrames(transport_version())) {
- QUIC_BUG(quic_bug_10511_38)
- << "MESSAGE frame is not supported for version " << transport_version();
- return MESSAGE_STATUS_UNSUPPORTED;
- }
- if (MemSliceSpanTotalSize(message) > GetCurrentLargestMessagePayload()) {
- return MESSAGE_STATUS_TOO_LARGE;
- }
- if (!connected_ || (!flush && !CanWrite(HAS_RETRANSMITTABLE_DATA))) {
- return MESSAGE_STATUS_BLOCKED;
- }
- ScopedPacketFlusher flusher(this);
- return packet_creator_.AddMessageFrame(message_id, message);
-}
-
-QuicPacketLength QuicConnection::GetCurrentLargestMessagePayload() const {
- return packet_creator_.GetCurrentLargestMessagePayload();
-}
-
-QuicPacketLength QuicConnection::GetGuaranteedLargestMessagePayload() const {
- return packet_creator_.GetGuaranteedLargestMessagePayload();
-}
-
-uint32_t QuicConnection::cipher_id() const {
- if (version().KnowsWhichDecrypterToUse()) {
- return framer_.GetDecrypter(last_decrypted_packet_level_)->cipher_id();
- }
- return framer_.decrypter()->cipher_id();
-}
-
-EncryptionLevel QuicConnection::GetConnectionCloseEncryptionLevel() const {
- if (perspective_ == Perspective::IS_CLIENT) {
- return encryption_level_;
- }
- if (IsHandshakeComplete()) {
- // A forward secure packet has been received.
- QUIC_BUG_IF(quic_bug_12714_31,
- encryption_level_ != ENCRYPTION_FORWARD_SECURE)
- << ENDPOINT << "Unexpected connection close encryption level "
- << encryption_level_;
- return ENCRYPTION_FORWARD_SECURE;
- }
- if (framer_.HasEncrypterOfEncryptionLevel(ENCRYPTION_ZERO_RTT)) {
- if (encryption_level_ != ENCRYPTION_ZERO_RTT) {
- if (version().HasIetfInvariantHeader()) {
- QUIC_CODE_COUNT(quic_wrong_encryption_level_connection_close_ietf);
- } else {
- QUIC_CODE_COUNT(quic_wrong_encryption_level_connection_close);
- }
- }
- return ENCRYPTION_ZERO_RTT;
- }
- return ENCRYPTION_INITIAL;
-}
-
-void QuicConnection::MaybeBundleCryptoDataWithAcks() {
- QUICHE_DCHECK(SupportsMultiplePacketNumberSpaces());
- if (IsHandshakeConfirmed()) {
- return;
- }
- PacketNumberSpace space = HANDSHAKE_DATA;
- if (perspective() == Perspective::IS_SERVER &&
- framer_.HasEncrypterOfEncryptionLevel(ENCRYPTION_INITIAL)) {
- // On the server side, sends INITIAL data with INITIAL ACK if initial key is
- // available.
- space = INITIAL_DATA;
- }
- const QuicTime ack_timeout =
- uber_received_packet_manager_.GetAckTimeout(space);
- if (!ack_timeout.IsInitialized() ||
- (ack_timeout > clock_->ApproximateNow() &&
- ack_timeout > uber_received_packet_manager_.GetEarliestAckTimeout())) {
- // No pending ACK of space.
- return;
- }
- if (coalesced_packet_.length() > 0) {
- // Do not bundle CRYPTO data if the ACK could be coalesced with other
- // packets.
- return;
- }
-
- if (!framer_.HasAnEncrypterForSpace(space)) {
- QUIC_BUG(quic_bug_10511_39)
- << ENDPOINT
- << "Try to bundle crypto with ACK with missing key of space "
- << PacketNumberSpaceToString(space);
- return;
- }
-
- sent_packet_manager_.RetransmitDataOfSpaceIfAny(space);
-}
-
-void QuicConnection::SendAllPendingAcks() {
- QUICHE_DCHECK(SupportsMultiplePacketNumberSpaces());
- QUIC_DVLOG(1) << ENDPOINT << "Trying to send all pending ACKs";
- ack_alarm_->Cancel();
- QuicTime earliest_ack_timeout =
- uber_received_packet_manager_.GetEarliestAckTimeout();
- QUIC_BUG_IF(quic_bug_12714_32, !earliest_ack_timeout.IsInitialized());
- MaybeBundleCryptoDataWithAcks();
- earliest_ack_timeout = uber_received_packet_manager_.GetEarliestAckTimeout();
- if (!earliest_ack_timeout.IsInitialized()) {
- return;
- }
- for (int8_t i = INITIAL_DATA; i <= APPLICATION_DATA; ++i) {
- const QuicTime ack_timeout = uber_received_packet_manager_.GetAckTimeout(
- static_cast<PacketNumberSpace>(i));
- if (!ack_timeout.IsInitialized()) {
- continue;
- }
- if (!framer_.HasAnEncrypterForSpace(static_cast<PacketNumberSpace>(i))) {
- // The key has been dropped.
- continue;
- }
- if (ack_timeout > clock_->ApproximateNow() &&
- ack_timeout > earliest_ack_timeout) {
- // Always send the earliest ACK to make forward progress in case alarm
- // fires early.
- continue;
- }
- QUIC_DVLOG(1) << ENDPOINT << "Sending ACK of packet number space "
- << PacketNumberSpaceToString(
- static_cast<PacketNumberSpace>(i));
- ScopedEncryptionLevelContext context(
- this, QuicUtils::GetEncryptionLevel(static_cast<PacketNumberSpace>(i)));
- QuicFrames frames;
- frames.push_back(uber_received_packet_manager_.GetUpdatedAckFrame(
- static_cast<PacketNumberSpace>(i), clock_->ApproximateNow()));
- const bool flushed = packet_creator_.FlushAckFrame(frames);
- if (!flushed) {
- // Connection is write blocked.
- QUIC_BUG_IF(quic_bug_12714_33,
- !writer_->IsWriteBlocked() && !LimitedByAmplificationFactor())
- << "Writer not blocked and not throttled by amplification factor, "
- "but ACK not flushed for packet space:"
- << i;
- break;
- }
- ResetAckStates();
- }
-
- const QuicTime timeout =
- uber_received_packet_manager_.GetEarliestAckTimeout();
- if (timeout.IsInitialized()) {
- // If there are ACKs pending, re-arm ack alarm.
- ack_alarm_->Update(timeout, kAlarmGranularity);
- }
- // Only try to bundle retransmittable data with ACK frame if default
- // encryption level is forward secure.
- if (encryption_level_ != ENCRYPTION_FORWARD_SECURE ||
- !ShouldBundleRetransmittableFrameWithAck()) {
- return;
- }
- consecutive_num_packets_with_no_retransmittable_frames_ = 0;
- if (packet_creator_.HasPendingRetransmittableFrames() ||
- visitor_->WillingAndAbleToWrite()) {
- // There are pending retransmittable frames.
- return;
- }
-
- visitor_->OnAckNeedsRetransmittableFrame();
-}
-
-bool QuicConnection::ShouldBundleRetransmittableFrameWithAck() const {
- if (consecutive_num_packets_with_no_retransmittable_frames_ >=
- max_consecutive_num_packets_with_no_retransmittable_frames_) {
- 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.
- return true;
- }
- return false;
-}
-
-void QuicConnection::MaybeCoalescePacketOfHigherSpace() {
- if (!connected() || !packet_creator_.HasSoftMaxPacketLength() ||
- fill_coalesced_packet_) {
- // Make sure MaybeCoalescePacketOfHigherSpace is not re-entrant.
- return;
- }
- // 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 (which includes the PTO
- // timeout) when receiving ACKs of those undecryptable packets. To mitigate
- // this, tries to coalesce a packet of higher encryption level.
- for (EncryptionLevel retransmission_level :
- {ENCRYPTION_INITIAL, ENCRYPTION_HANDSHAKE}) {
- // Coalesce HANDSHAKE with INITIAL retransmission, and coalesce 1-RTT with
- // HANDSHAKE retransmission.
- const EncryptionLevel coalesced_level =
- retransmission_level == ENCRYPTION_INITIAL ? ENCRYPTION_HANDSHAKE
- : ENCRYPTION_FORWARD_SECURE;
- if (coalesced_packet_.ContainsPacketOfEncryptionLevel(
- retransmission_level) &&
- coalesced_packet_.TransmissionTypeOfPacket(retransmission_level) !=
- NOT_RETRANSMISSION &&
- framer_.HasEncrypterOfEncryptionLevel(coalesced_level) &&
- !coalesced_packet_.ContainsPacketOfEncryptionLevel(coalesced_level)) {
- fill_coalesced_packet_ = true;
- sent_packet_manager_.RetransmitDataOfSpaceIfAny(
- QuicUtils::GetPacketNumberSpace(coalesced_level));
- fill_coalesced_packet_ = false;
- }
- }
-}
-
-bool QuicConnection::FlushCoalescedPacket() {
- ScopedCoalescedPacketClearer clearer(&coalesced_packet_);
- if (!connected_) {
- return false;
- }
- if (!version().CanSendCoalescedPackets()) {
- QUIC_BUG_IF(quic_bug_12714_34, coalesced_packet_.length() > 0);
- return true;
- }
- if (coalesced_packet_.ContainsPacketOfEncryptionLevel(ENCRYPTION_INITIAL) &&
- !framer_.HasEncrypterOfEncryptionLevel(ENCRYPTION_INITIAL)) {
- // Initial packet will be re-serialized. Neuter it in case initial key has
- // been dropped.
- QUIC_BUG(quic_bug_10511_40)
- << ENDPOINT
- << "Coalescer contains initial packet while initial key has "
- "been dropped.";
- coalesced_packet_.NeuterInitialPacket();
- }
- if (coalesced_packet_.length() == 0) {
- return true;
- }
-
- char buffer[kMaxOutgoingPacketSize];
- const size_t length = packet_creator_.SerializeCoalescedPacket(
- coalesced_packet_, buffer, coalesced_packet_.max_packet_length());
- if (length == 0) {
- return false;
- }
- if (debug_visitor_ != nullptr) {
- debug_visitor_->OnCoalescedPacketSent(coalesced_packet_, length);
- }
- QUIC_DVLOG(1) << ENDPOINT << "Sending coalesced packet "
- << coalesced_packet_.ToString(length);
-
- if (!buffered_packets_.empty() || HandleWriteBlocked()) {
- QUIC_DVLOG(1) << ENDPOINT
- << "Buffering coalesced packet of len: " << length;
- buffered_packets_.emplace_back(
- buffer, static_cast<QuicPacketLength>(length),
- coalesced_packet_.self_address(), coalesced_packet_.peer_address());
- return true;
- }
-
- WriteResult result = writer_->WritePacket(
- buffer, length, coalesced_packet_.self_address().host(),
- coalesced_packet_.peer_address(), per_packet_options_);
- if (IsWriteError(result.status)) {
- OnWriteError(result.error_code);
- return false;
- }
- if (IsWriteBlockedStatus(result.status)) {
- visitor_->OnWriteBlocked();
- if (result.status != WRITE_STATUS_BLOCKED_DATA_BUFFERED) {
- QUIC_DVLOG(1) << ENDPOINT
- << "Buffering coalesced packet of len: " << length;
- buffered_packets_.emplace_back(
- buffer, static_cast<QuicPacketLength>(length),
- coalesced_packet_.self_address(), coalesced_packet_.peer_address());
- }
- }
- // 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 (EnforceAntiAmplificationLimit()) {
- 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);
- }
- }
- stats_.bytes_sent += padding_size;
- if (coalesced_packet_.initial_packet() != nullptr &&
- coalesced_packet_.initial_packet()->transmission_type !=
- NOT_RETRANSMISSION) {
- stats_.bytes_retransmitted += padding_size;
- }
- }
- return true;
-}
-
-void QuicConnection::MaybeEnableMultiplePacketNumberSpacesSupport() {
- if (version().handshake_protocol != PROTOCOL_TLS1_3) {
- return;
- }
- QUIC_DVLOG(1) << ENDPOINT << "connection " << connection_id()
- << " supports multiple packet number spaces";
- framer_.EnableMultiplePacketNumberSpacesSupport();
- sent_packet_manager_.EnableMultiplePacketNumberSpacesSupport();
- uber_received_packet_manager_.EnableMultiplePacketNumberSpacesSupport(
- perspective_);
-}
-
-bool QuicConnection::SupportsMultiplePacketNumberSpaces() const {
- return sent_packet_manager_.supports_multiple_packet_number_spaces();
-}
-
-void QuicConnection::SetLargestReceivedPacketWithAck(
- QuicPacketNumber new_value) {
- if (SupportsMultiplePacketNumberSpaces()) {
- largest_seen_packets_with_ack_[QuicUtils::GetPacketNumberSpace(
- last_decrypted_packet_level_)] = new_value;
- } else {
- largest_seen_packet_with_ack_ = new_value;
- }
-}
-
-void QuicConnection::OnForwardProgressMade() {
- if (!connected_) {
- return;
- }
- if (is_path_degrading_) {
- visitor_->OnForwardProgressMadeAfterPathDegrading();
- is_path_degrading_ = false;
- }
- if (sent_packet_manager_.HasInFlightPackets()) {
- // Restart detections if forward progress has been made.
- blackhole_detector_.RestartDetection(GetPathDegradingDeadline(),
- GetNetworkBlackholeDeadline(),
- GetPathMtuReductionDeadline());
- } else {
- // Stop detections in quiecense.
- blackhole_detector_.StopDetection(/*permanent=*/false);
- }
- QUIC_BUG_IF(quic_bug_12714_35,
- perspective_ == Perspective::IS_SERVER &&
- default_enable_5rto_blackhole_detection_ &&
- blackhole_detector_.IsDetectionInProgress() &&
- !sent_packet_manager_.HasInFlightPackets())
- << ENDPOINT
- << "Trying to start blackhole detection without no bytes in flight";
-}
-
-QuicPacketNumber QuicConnection::GetLargestReceivedPacketWithAck() const {
- if (SupportsMultiplePacketNumberSpaces()) {
- return largest_seen_packets_with_ack_[QuicUtils::GetPacketNumberSpace(
- last_decrypted_packet_level_)];
- }
- return largest_seen_packet_with_ack_;
-}
-
-QuicPacketNumber QuicConnection::GetLargestAckedPacket() const {
- if (SupportsMultiplePacketNumberSpaces()) {
- return sent_packet_manager_.GetLargestAckedPacket(
- last_decrypted_packet_level_);
- }
- return sent_packet_manager_.GetLargestObserved();
-}
-
-QuicPacketNumber QuicConnection::GetLargestReceivedPacket() const {
- return uber_received_packet_manager_.GetLargestObserved(
- last_decrypted_packet_level_);
-}
-
-bool QuicConnection::EnforceAntiAmplificationLimit() const {
- return version().SupportsAntiAmplificationLimit() &&
- perspective_ == Perspective::IS_SERVER && !default_path_.validated;
-}
-
-// TODO(danzh) Pass in path object or its reference of some sort to use this
-// method to check anti-amplification limit on non-default path.
-bool QuicConnection::LimitedByAmplificationFactor() const {
- return EnforceAntiAmplificationLimit() &&
- default_path_.bytes_sent_before_address_validation >=
- anti_amplification_factor_ *
- default_path_.bytes_received_before_address_validation;
-}
-
-SerializedPacketFate QuicConnection::GetSerializedPacketFate(
- bool is_mtu_discovery,
- EncryptionLevel encryption_level) {
- if (ShouldDiscardPacket(encryption_level)) {
- return DISCARD;
- }
- if (legacy_version_encapsulation_in_progress_) {
- QUICHE_DCHECK(!is_mtu_discovery);
- return LEGACY_VERSION_ENCAPSULATE;
- }
- if (version().CanSendCoalescedPackets() && !coalescing_done_ &&
- !is_mtu_discovery) {
- if (!IsHandshakeConfirmed()) {
- // Before receiving ACK for any 1-RTT packets, always try to coalesce
- // packet (except MTU discovery packet).
- return COALESCE;
- }
- if (coalesced_packet_.length() > 0) {
- // If the coalescer is not empty, let this packet go through coalescer
- // to avoid potential out of order sending.
- return COALESCE;
- }
- }
- if (!buffered_packets_.empty() || HandleWriteBlocked()) {
- return BUFFER;
- }
- return SEND_TO_WRITER;
-}
-
-bool QuicConnection::IsHandshakeComplete() const {
- return visitor_->GetHandshakeState() >= HANDSHAKE_COMPLETE;
-}
-
-bool QuicConnection::IsHandshakeConfirmed() const {
- QUICHE_DCHECK_EQ(PROTOCOL_TLS1_3, version().handshake_protocol);
- return visitor_->GetHandshakeState() == HANDSHAKE_CONFIRMED;
-}
-
-size_t QuicConnection::min_received_before_ack_decimation() const {
- return uber_received_packet_manager_.min_received_before_ack_decimation();
-}
-
-void QuicConnection::set_min_received_before_ack_decimation(size_t new_value) {
- uber_received_packet_manager_.set_min_received_before_ack_decimation(
- new_value);
-}
-
-const QuicAckFrame& QuicConnection::ack_frame() const {
- if (SupportsMultiplePacketNumberSpaces()) {
- return uber_received_packet_manager_.GetAckFrame(
- QuicUtils::GetPacketNumberSpace(last_decrypted_packet_level_));
- }
- return uber_received_packet_manager_.ack_frame();
-}
-
-void QuicConnection::set_client_connection_id(
- QuicConnectionId client_connection_id) {
- if (!version().SupportsClientConnectionIds()) {
- QUIC_BUG_IF(quic_bug_12714_36, !client_connection_id.IsEmpty())
- << ENDPOINT << "Attempted to use client connection ID "
- << client_connection_id << " with unsupported version " << version();
- return;
- }
- default_path_.client_connection_id = client_connection_id;
-
- client_connection_id_is_set_ = true;
- if (version().HasIetfQuicFrames() && !client_connection_id.IsEmpty()) {
- if (perspective_ == Perspective::IS_SERVER) {
- QUICHE_DCHECK(peer_issued_cid_manager_ == nullptr);
- peer_issued_cid_manager_ =
- std::make_unique<QuicPeerIssuedConnectionIdManager>(
- kMinNumOfActiveConnectionIds, client_connection_id, clock_,
- alarm_factory_, this, context());
- } else {
- // Note in Chromium client, set_client_connection_id is not called and
- // thus self_issued_cid_manager_ should be null.
- self_issued_cid_manager_ = MakeSelfIssuedConnectionIdManager();
- }
- }
- QUIC_DLOG(INFO) << ENDPOINT << "setting client connection ID to "
- << default_path_.client_connection_id
- << " for connection with server connection ID "
- << default_path_.server_connection_id;
- packet_creator_.SetClientConnectionId(default_path_.client_connection_id);
- framer_.SetExpectedClientConnectionIdLength(
- default_path_.client_connection_id.length());
-}
-
-void QuicConnection::OnPathDegradingDetected() {
- is_path_degrading_ = true;
- visitor_->OnPathDegrading();
-}
-
-void QuicConnection::OnBlackholeDetected() {
- if (default_enable_5rto_blackhole_detection_ &&
- !sent_packet_manager_.HasInFlightPackets()) {
- QUIC_BUG(quic_bug_10511_41)
- << ENDPOINT
- << "Blackhole detected, but there is no bytes in flight, version: "
- << version();
- // Do not close connection if there is no bytes in flight.
- return;
- }
- CloseConnection(QUIC_TOO_MANY_RTOS, "Network blackhole detected",
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
-}
-
-void QuicConnection::OnPathMtuReductionDetected() {
- MaybeRevertToPreviousMtu();
-}
-
-void QuicConnection::OnHandshakeTimeout() {
- const QuicTime::Delta duration =
- clock_->ApproximateNow() - stats_.connection_creation_time;
- std::string error_details = absl::StrCat(
- "Handshake timeout expired after ", duration.ToDebuggingValue(),
- ". Timeout:",
- idle_network_detector_.handshake_timeout().ToDebuggingValue());
- if (perspective() == Perspective::IS_CLIENT && version().UsesTls()) {
- absl::StrAppend(&error_details, UndecryptablePacketsInfo());
- }
- QUIC_DVLOG(1) << ENDPOINT << error_details;
- CloseConnection(QUIC_HANDSHAKE_TIMEOUT, error_details,
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
-}
-
-void QuicConnection::OnIdleNetworkDetected() {
- const QuicTime::Delta duration =
- clock_->ApproximateNow() -
- idle_network_detector_.last_network_activity_time();
- std::string error_details = absl::StrCat(
- "No recent network activity after ", duration.ToDebuggingValue(),
- ". Timeout:",
- idle_network_detector_.idle_network_timeout().ToDebuggingValue());
- if (perspective() == Perspective::IS_CLIENT && version().UsesTls() &&
- !IsHandshakeComplete()) {
- absl::StrAppend(&error_details, UndecryptablePacketsInfo());
- }
- 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) &&
- !has_consecutive_pto) {
- // Include stream information in error detail if there are open streams.
- QUIC_RELOADABLE_FLAG_COUNT(quic_add_stream_info_to_idle_close_detail);
- absl::StrAppend(&error_details, ", ",
- visitor_->GetStreamsInfoForLogging());
- }
- CloseConnection(QUIC_NETWORK_IDLE_TIMEOUT, error_details,
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
- return;
- }
- QuicErrorCode error_code = QUIC_NETWORK_IDLE_TIMEOUT;
- if (idle_timeout_connection_close_behavior_ ==
- ConnectionCloseBehavior::
- SILENT_CLOSE_WITH_CONNECTION_CLOSE_PACKET_SERIALIZED) {
- error_code = QUIC_SILENT_IDLE_TIMEOUT;
- }
- CloseConnection(error_code, error_details,
- idle_timeout_connection_close_behavior_);
-}
-
-void QuicConnection::OnPeerIssuedConnectionIdRetired() {
- QUICHE_DCHECK(peer_issued_cid_manager_ != nullptr);
- QuicConnectionId* default_path_cid =
- perspective_ == Perspective::IS_CLIENT
- ? &default_path_.server_connection_id
- : &default_path_.client_connection_id;
- QuicConnectionId* alternative_path_cid =
- perspective_ == Perspective::IS_CLIENT
- ? &alternative_path_.server_connection_id
- : &alternative_path_.client_connection_id;
- bool default_path_and_alternative_path_use_the_same_peer_connection_id =
- *default_path_cid == *alternative_path_cid;
- if (!default_path_cid->IsEmpty() &&
- !peer_issued_cid_manager_->IsConnectionIdActive(*default_path_cid)) {
- *default_path_cid = QuicConnectionId();
- }
- // TODO(haoyuewang) Handle the change for default_path_ & alternatvie_path_
- // via the same helper function.
- if (default_path_cid->IsEmpty()) {
- // Try setting a new connection ID now such that subsequent
- // RetireConnectionId frames can be sent on the default path.
- const QuicConnectionIdData* unused_connection_id_data =
- peer_issued_cid_manager_->ConsumeOneUnusedConnectionId();
- if (unused_connection_id_data != nullptr) {
- *default_path_cid = unused_connection_id_data->connection_id;
- default_path_.stateless_reset_token =
- unused_connection_id_data->stateless_reset_token;
- if (perspective_ == Perspective::IS_CLIENT) {
- packet_creator_.SetServerConnectionId(
- unused_connection_id_data->connection_id);
- } else {
- packet_creator_.SetClientConnectionId(
- unused_connection_id_data->connection_id);
- }
- }
- }
- if (default_path_and_alternative_path_use_the_same_peer_connection_id) {
- *alternative_path_cid = *default_path_cid;
- alternative_path_.stateless_reset_token =
- default_path_.stateless_reset_token;
- } else if (!alternative_path_cid->IsEmpty() &&
- !peer_issued_cid_manager_->IsConnectionIdActive(
- *alternative_path_cid)) {
- *alternative_path_cid = EmptyQuicConnectionId();
- const QuicConnectionIdData* unused_connection_id_data =
- peer_issued_cid_manager_->ConsumeOneUnusedConnectionId();
- if (unused_connection_id_data != nullptr) {
- *alternative_path_cid = unused_connection_id_data->connection_id;
- alternative_path_.stateless_reset_token =
- unused_connection_id_data->stateless_reset_token;
- }
- }
-
- std::vector<uint64_t> retired_cid_sequence_numbers =
- peer_issued_cid_manager_->ConsumeToBeRetiredConnectionIdSequenceNumbers();
- QUICHE_DCHECK(!retired_cid_sequence_numbers.empty());
- for (const auto& sequence_number : retired_cid_sequence_numbers) {
- ++stats_.num_retire_connection_id_sent;
- visitor_->SendRetireConnectionId(sequence_number);
- }
-}
-
-bool QuicConnection::SendNewConnectionId(
- const QuicNewConnectionIdFrame& frame) {
- visitor_->SendNewConnectionId(frame);
- ++stats_.num_new_connection_id_sent;
- return connected_;
-}
-
-void QuicConnection::OnNewConnectionIdIssued(
- const QuicConnectionId& connection_id) {
- if (perspective_ == Perspective::IS_SERVER) {
- visitor_->OnServerConnectionIdIssued(connection_id);
- }
-}
-
-void QuicConnection::OnSelfIssuedConnectionIdRetired(
- const QuicConnectionId& connection_id) {
- if (perspective_ == Perspective::IS_SERVER) {
- visitor_->OnServerConnectionIdRetired(connection_id);
- }
-}
-
-void QuicConnection::MaybeUpdateAckTimeout() {
- if (should_last_packet_instigate_acks_) {
- return;
- }
- should_last_packet_instigate_acks_ = true;
- uber_received_packet_manager_.MaybeUpdateAckTimeout(
- /*should_last_packet_instigate_acks=*/true, last_decrypted_packet_level_,
- last_header_.packet_number, clock_->ApproximateNow(),
- sent_packet_manager_.GetRttStats());
-}
-
-QuicTime QuicConnection::GetPathDegradingDeadline() const {
- if (!ShouldDetectPathDegrading()) {
- return QuicTime::Zero();
- }
- return clock_->ApproximateNow() +
- sent_packet_manager_.GetPathDegradingDelay();
-}
-
-bool QuicConnection::ShouldDetectPathDegrading() const {
- if (!connected_) {
- return false;
- }
- // No path degrading detection before handshake completes.
- if (!idle_network_detector_.handshake_timeout().IsInfinite()) {
- return false;
- }
- return perspective_ == Perspective::IS_CLIENT && !is_path_degrading_;
-}
-
-QuicTime QuicConnection::GetNetworkBlackholeDeadline() const {
- if (!ShouldDetectBlackhole()) {
- return QuicTime::Zero();
- }
- QUICHE_DCHECK_LT(0u, num_rtos_for_blackhole_detection_);
- return clock_->ApproximateNow() +
- sent_packet_manager_.GetNetworkBlackholeDelay(
- num_rtos_for_blackhole_detection_);
-}
-
-bool QuicConnection::ShouldDetectBlackhole() const {
- if (!connected_ || blackhole_detection_disabled_) {
- return false;
- }
- // No blackhole detection before handshake completes.
- if (default_enable_5rto_blackhole_detection_) {
- QUIC_RELOADABLE_FLAG_COUNT_N(quic_default_enable_5rto_blackhole_detection2,
- 3, 3);
- return IsHandshakeComplete();
- }
-
- if (!idle_network_detector_.handshake_timeout().IsInfinite()) {
- return false;
- }
- return num_rtos_for_blackhole_detection_ > 0;
-}
-
-QuicTime QuicConnection::GetRetransmissionDeadline() const {
- if (perspective_ == Perspective::IS_CLIENT &&
- SupportsMultiplePacketNumberSpaces() && !IsHandshakeConfirmed() &&
- stats_.pto_count == 0 &&
- !framer_.HasDecrypterOfEncryptionLevel(ENCRYPTION_HANDSHAKE) &&
- !undecryptable_packets_.empty()) {
- // Retransmits ClientHello quickly when a Handshake or 1-RTT packet is
- // received prior to having Handshake keys. Adding kAlarmGranulary will
- // avoid spurious retransmissions in the case of small-scale reordering.
- return clock_->ApproximateNow() + kAlarmGranularity;
- }
- return sent_packet_manager_.GetRetransmissionTime();
-}
-
-bool QuicConnection::SendPathChallenge(
- const QuicPathFrameBuffer& data_buffer,
- const QuicSocketAddress& self_address,
- const QuicSocketAddress& peer_address,
- const QuicSocketAddress& effective_peer_address,
- QuicPacketWriter* writer) {
- if (!framer_.HasEncrypterOfEncryptionLevel(ENCRYPTION_FORWARD_SECURE)) {
- return connected_;
- }
- if (connection_migration_use_new_cid_) {
- {
- 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_;
- }
- if (writer == writer_) {
- ScopedPacketFlusher flusher(this);
- {
- // It's on current path, add the PATH_CHALLENGE the same way as other
- // frames.
- QuicPacketCreator::ScopedPeerAddressContext context(
- &packet_creator_, peer_address, /*update_connection_id=*/false);
- // This may cause connection to be closed.
- packet_creator_.AddPathChallengeFrame(data_buffer);
- }
- // Return outside of the scope so that the flush result can be reflected.
- return connected_;
- }
- 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 true;
-}
-
-QuicTime QuicConnection::GetRetryTimeout(
- const QuicSocketAddress& peer_address_to_use,
- QuicPacketWriter* writer_to_use) const {
- if (writer_to_use == writer_ && peer_address_to_use == peer_address()) {
- return clock_->ApproximateNow() + sent_packet_manager_.GetPtoDelay();
- }
- return clock_->ApproximateNow() +
- QuicTime::Delta::FromMilliseconds(3 * kInitialRttMs);
-}
-
-void QuicConnection::ValidatePath(
- std::unique_ptr<QuicPathValidationContext> context,
- std::unique_ptr<QuicPathValidator::ResultDelegate> result_delegate) {
- QUICHE_DCHECK(use_path_validator_);
- if (!connection_migration_use_new_cid_ &&
- perspective_ == Perspective::IS_CLIENT &&
- !IsDefaultPath(context->self_address(), context->peer_address())) {
- alternative_path_ = PathState(
- context->self_address(), context->peer_address(),
- default_path_.client_connection_id, default_path_.server_connection_id,
- default_path_.stateless_reset_token);
- }
- if (path_validator_.HasPendingPathValidation()) {
- // Cancel and fail any earlier validation.
- path_validator_.CancelPathValidation();
- }
- if (connection_migration_use_new_cid_ &&
- perspective_ == Perspective::IS_CLIENT &&
- !IsDefaultPath(context->self_address(), context->peer_address())) {
- if (self_issued_cid_manager_ != nullptr) {
- self_issued_cid_manager_->MaybeSendNewConnectionIds();
- if (!connected_) {
- return;
- }
- }
- if ((self_issued_cid_manager_ != nullptr &&
- !self_issued_cid_manager_->HasConnectionIdToConsume()) ||
- (peer_issued_cid_manager_ != nullptr &&
- !peer_issued_cid_manager_->HasUnusedConnectionId())) {
- QUIC_DVLOG(1) << "Client cannot start new path validation as there is no "
- "requried connection ID is available.";
- result_delegate->OnPathValidationFailure(std::move(context));
- return;
- }
- QuicConnectionId client_connection_id, server_connection_id;
- absl::optional<StatelessResetToken> stateless_reset_token;
- if (self_issued_cid_manager_ != nullptr) {
- client_connection_id =
- *self_issued_cid_manager_->ConsumeOneConnectionId();
- }
- if (peer_issued_cid_manager_ != nullptr) {
- const auto* connection_id_data =
- peer_issued_cid_manager_->ConsumeOneUnusedConnectionId();
- server_connection_id = connection_id_data->connection_id;
- stateless_reset_token = connection_id_data->stateless_reset_token;
- }
- alternative_path_ = PathState(context->self_address(),
- context->peer_address(), client_connection_id,
- server_connection_id, stateless_reset_token);
- }
- path_validator_.StartPathValidation(std::move(context),
- std::move(result_delegate));
-}
-
-bool QuicConnection::SendPathResponse(
- const QuicPathFrameBuffer& data_buffer,
- const QuicSocketAddress& peer_address_to_send,
- const QuicSocketAddress& effective_peer_address) {
- if (!framer_.HasEncrypterOfEncryptionLevel(ENCRYPTION_FORWARD_SECURE)) {
- return false;
- }
- QuicConnectionId client_cid, server_cid;
- if (connection_migration_use_new_cid_) {
- FindOnPathConnectionIds(last_received_packet_info_.destination_address,
- effective_peer_address, &client_cid, &server_cid);
- }
- // Send PATH_RESPONSE using the provided peer address. If the creator has been
- // using a different peer address, it will flush before and after serializing
- // the current PATH_RESPONSE.
- QuicPacketCreator::ScopedPeerAddressContext context(
- &packet_creator_, peer_address_to_send, client_cid, server_cid,
- connection_migration_use_new_cid_);
- QUIC_DVLOG(1) << ENDPOINT << "Send PATH_RESPONSE to " << peer_address_to_send;
- if (default_path_.self_address ==
- last_received_packet_info_.destination_address) {
- // The PATH_CHALLENGE is received on the default socket. Respond on the same
- // socket.
- return packet_creator_.AddPathResponseFrame(data_buffer);
- }
-
- QUICHE_DCHECK_EQ(Perspective::IS_CLIENT, perspective_);
- // This PATH_CHALLENGE is received on an alternative socket which should be
- // used to send PATH_RESPONSE.
- if (!path_validator_.HasPendingPathValidation() ||
- path_validator_.GetContext()->self_address() !=
- last_received_packet_info_.destination_address) {
- // Ignore this PATH_CHALLENGE if it's received from an uninteresting
- // socket.
- return true;
- }
- QuicPacketWriter* writer = path_validator_.GetContext()->WriterToUse();
-
- std::unique_ptr<SerializedPacket> probing_packet =
- packet_creator_.SerializePathResponseConnectivityProbingPacket(
- {data_buffer}, /*is_padded=*/true);
- QUICHE_DCHECK_EQ(IsRetransmittable(*probing_packet), NO_RETRANSMITTABLE_DATA);
- QUIC_DVLOG(1) << ENDPOINT
- << "Send PATH_RESPONSE from alternative socket with address "
- << last_received_packet_info_.destination_address;
- // Ignore the return value to treat write error on the alternative writer as
- // part of network error. If the writer becomes blocked, wait for the peer to
- // send another PATH_CHALLENGE.
- WritePacketUsingWriter(std::move(probing_packet), writer,
- last_received_packet_info_.destination_address,
- peer_address_to_send,
- /*measure_rtt=*/false);
- return true;
-}
-
-void QuicConnection::UpdatePeerAddress(QuicSocketAddress peer_address) {
- direct_peer_address_ = peer_address;
- packet_creator_.SetDefaultPeerAddress(peer_address);
-}
-
-void QuicConnection::SendPingAtLevel(EncryptionLevel level) {
- ScopedEncryptionLevelContext context(this, level);
- SendControlFrame(QuicFrame(QuicPingFrame()));
-}
-
-bool QuicConnection::HasPendingPathValidation() const {
- QUICHE_DCHECK(use_path_validator_);
- return path_validator_.HasPendingPathValidation();
-}
-
-QuicPathValidationContext* QuicConnection::GetPathValidationContext() const {
- QUICHE_DCHECK(use_path_validator_);
- return path_validator_.GetContext();
-}
-
-void QuicConnection::CancelPathValidation() {
- QUICHE_DCHECK(use_path_validator_);
- path_validator_.CancelPathValidation();
-}
-
-bool QuicConnection::UpdateConnectionIdsOnClientMigration(
- const QuicSocketAddress& self_address,
- const QuicSocketAddress& peer_address) {
- QUICHE_DCHECK(perspective_ == Perspective::IS_CLIENT);
- if (IsAlternativePath(self_address, peer_address)) {
- // Client migration is after path validation.
- default_path_.client_connection_id = alternative_path_.client_connection_id;
- default_path_.server_connection_id = alternative_path_.server_connection_id;
- default_path_.stateless_reset_token =
- alternative_path_.stateless_reset_token;
- return true;
- }
- // Client migration is without path validation.
- if (self_issued_cid_manager_ != nullptr) {
- self_issued_cid_manager_->MaybeSendNewConnectionIds();
- if (!connected_) {
- return false;
- }
- }
- if ((self_issued_cid_manager_ != nullptr &&
- !self_issued_cid_manager_->HasConnectionIdToConsume()) ||
- (peer_issued_cid_manager_ != nullptr &&
- !peer_issued_cid_manager_->HasUnusedConnectionId())) {
- return false;
- }
- if (self_issued_cid_manager_ != nullptr) {
- default_path_.client_connection_id =
- *self_issued_cid_manager_->ConsumeOneConnectionId();
- }
- if (peer_issued_cid_manager_ != nullptr) {
- const auto* connection_id_data =
- peer_issued_cid_manager_->ConsumeOneUnusedConnectionId();
- default_path_.server_connection_id = connection_id_data->connection_id;
- default_path_.stateless_reset_token =
- connection_id_data->stateless_reset_token;
- }
- return true;
-}
-
-void QuicConnection::RetirePeerIssuedConnectionIdsNoLongerOnPath() {
- if (!connection_migration_use_new_cid_ ||
- peer_issued_cid_manager_ == nullptr) {
- return;
- }
- if (perspective_ == Perspective::IS_CLIENT) {
- peer_issued_cid_manager_->MaybeRetireUnusedConnectionIds(
- {default_path_.server_connection_id,
- alternative_path_.server_connection_id});
- } else {
- peer_issued_cid_manager_->MaybeRetireUnusedConnectionIds(
- {default_path_.client_connection_id,
- alternative_path_.client_connection_id});
- }
-}
-
-void QuicConnection::RetirePeerIssuedConnectionIdsOnPathValidationFailure() {
- // The alarm to retire connection IDs no longer on paths is scheduled at the
- // end of writing and reading packet. On path validation failure, there could
- // be no packet to write or read. Hence the retirement alarm for the
- // connection ID associated with the failed path needs to be proactively
- // scheduled here.
- if (GetQuicReloadableFlag(
- quic_retire_cid_on_reverse_path_validation_failure) ||
- perspective_ == Perspective::IS_CLIENT) {
- QUIC_RELOADABLE_FLAG_COUNT(
- quic_retire_cid_on_reverse_path_validation_failure);
- RetirePeerIssuedConnectionIdsNoLongerOnPath();
- }
-}
-
-bool QuicConnection::MigratePath(const QuicSocketAddress& self_address,
- const QuicSocketAddress& peer_address,
- QuicPacketWriter* writer,
- bool owns_writer) {
- QUICHE_DCHECK(perspective_ == Perspective::IS_CLIENT);
- if (!connected_) {
- if (owns_writer) {
- delete writer;
- }
- return false;
- }
- QUICHE_DCHECK(!version().UsesHttp3() || IsHandshakeConfirmed());
-
- if (connection_migration_use_new_cid_) {
- if (!UpdateConnectionIdsOnClientMigration(self_address, peer_address)) {
- if (owns_writer) {
- delete writer;
- }
- return false;
- }
- if (packet_creator_.GetServerConnectionId().length() !=
- default_path_.server_connection_id.length()) {
- packet_creator_.FlushCurrentPacket();
- }
- packet_creator_.SetClientConnectionId(default_path_.client_connection_id);
- packet_creator_.SetServerConnectionId(default_path_.server_connection_id);
- }
-
- const auto self_address_change_type = QuicUtils::DetermineAddressChangeType(
- default_path_.self_address, self_address);
- const auto peer_address_change_type = QuicUtils::DetermineAddressChangeType(
- default_path_.peer_address, peer_address);
- QUICHE_DCHECK(self_address_change_type != NO_CHANGE ||
- peer_address_change_type != NO_CHANGE);
- const bool is_port_change = (self_address_change_type == PORT_CHANGE ||
- self_address_change_type == NO_CHANGE) &&
- (peer_address_change_type == PORT_CHANGE ||
- peer_address_change_type == NO_CHANGE);
- SetSelfAddress(self_address);
- UpdatePeerAddress(peer_address);
- SetQuicPacketWriter(writer, owns_writer);
- MaybeClearQueuedPacketsOnPathChange();
- OnSuccessfulMigration(is_port_change);
- return true;
-}
-
-void QuicConnection::OnPathValidationFailureAtClient() {
- if (connection_migration_use_new_cid_) {
- QUICHE_DCHECK(perspective_ == Perspective::IS_CLIENT);
- alternative_path_.Clear();
- }
- RetirePeerIssuedConnectionIdsOnPathValidationFailure();
-}
-
-QuicConnectionId QuicConnection::GetOneActiveServerConnectionId() const {
- if (perspective_ == Perspective::IS_CLIENT ||
- self_issued_cid_manager_ == nullptr) {
- return connection_id();
- }
- auto active_connection_ids = GetActiveServerConnectionIds();
- QUIC_BUG_IF(quic_bug_6944, active_connection_ids.empty());
- if (active_connection_ids.empty() ||
- std::find(active_connection_ids.begin(), active_connection_ids.end(),
- connection_id()) != active_connection_ids.end()) {
- return connection_id();
- }
- QUICHE_CODE_COUNT(connection_id_on_default_path_has_been_retired);
- auto active_connection_id =
- self_issued_cid_manager_->GetOneActiveConnectionId();
- return active_connection_id;
-}
-
-std::vector<QuicConnectionId> QuicConnection::GetActiveServerConnectionIds()
- const {
- if (self_issued_cid_manager_ == nullptr) {
- return {default_path_.server_connection_id};
- }
- QUICHE_DCHECK(version().HasIetfQuicFrames());
- return self_issued_cid_manager_->GetUnretiredConnectionIds();
-}
-
-void QuicConnection::CreateConnectionIdManager() {
- if (!version().HasIetfQuicFrames()) {
- return;
- }
-
- if (perspective_ == Perspective::IS_CLIENT) {
- if (!default_path_.server_connection_id.IsEmpty()) {
- peer_issued_cid_manager_ =
- std::make_unique<QuicPeerIssuedConnectionIdManager>(
- kMinNumOfActiveConnectionIds, default_path_.server_connection_id,
- clock_, alarm_factory_, this, context());
- }
- } else {
- if (!default_path_.server_connection_id.IsEmpty()) {
- self_issued_cid_manager_ = MakeSelfIssuedConnectionIdManager();
- }
- }
-}
-
-void QuicConnection::SetUnackedMapInitialCapacity() {
- sent_packet_manager_.ReserveUnackedPacketsInitialCapacity(
- GetUnackedMapInitialCapacity());
-}
-
-void QuicConnection::SetSourceAddressTokenToSend(absl::string_view token) {
- QUICHE_DCHECK_EQ(perspective_, Perspective::IS_CLIENT);
- if (!packet_creator_.HasRetryToken()) {
- // Ignore received tokens (via NEW_TOKEN frame) from previous connections
- // when a RETRY token has been received.
- packet_creator_.SetRetryToken(std::string(token.data(), token.length()));
- }
-}
-
-void QuicConnection::MaybeUpdateBytesSentToAlternativeAddress(
- const QuicSocketAddress& peer_address,
- QuicByteCount sent_packet_size) {
- if (!version().SupportsAntiAmplificationLimit() ||
- perspective_ != Perspective::IS_SERVER) {
- return;
- }
- QUICHE_DCHECK(!IsDefaultPath(default_path_.self_address, peer_address));
- if (!IsAlternativePath(default_path_.self_address, peer_address)) {
- QUIC_DLOG(INFO) << "Wrote to uninteresting peer address: " << peer_address
- << " default direct_peer_address_ " << direct_peer_address_
- << " alternative path peer address "
- << alternative_path_.peer_address;
- return;
- }
- if (alternative_path_.validated) {
- return;
- }
- if (alternative_path_.bytes_sent_before_address_validation >=
- anti_amplification_factor_ *
- alternative_path_.bytes_received_before_address_validation) {
- QUIC_LOG_FIRST_N(WARNING, 100)
- << "Server sent more data than allowed to unverified alternative "
- "peer address "
- << peer_address << " bytes sent "
- << alternative_path_.bytes_sent_before_address_validation
- << ", bytes received "
- << alternative_path_.bytes_received_before_address_validation;
- }
- alternative_path_.bytes_sent_before_address_validation += sent_packet_size;
-}
-
-void QuicConnection::MaybeUpdateBytesReceivedFromAlternativeAddress(
- QuicByteCount received_packet_size) {
- if (!version().SupportsAntiAmplificationLimit() ||
- perspective_ != Perspective::IS_SERVER ||
- !IsAlternativePath(last_received_packet_info_.destination_address,
- GetEffectivePeerAddressFromCurrentPacket()) ||
- last_received_packet_info_.received_bytes_counted) {
- return;
- }
- // Only update bytes received if this probing frame is received on the most
- // recent alternative path.
- QUICHE_DCHECK(!IsDefaultPath(last_received_packet_info_.destination_address,
- GetEffectivePeerAddressFromCurrentPacket()));
- if (!alternative_path_.validated) {
- alternative_path_.bytes_received_before_address_validation +=
- received_packet_size;
- }
- last_received_packet_info_.received_bytes_counted = true;
-}
-
-bool QuicConnection::IsDefaultPath(
- const QuicSocketAddress& self_address,
- const QuicSocketAddress& peer_address) const {
- return direct_peer_address_ == peer_address &&
- default_path_.self_address == self_address;
-}
-
-bool QuicConnection::IsAlternativePath(
- const QuicSocketAddress& self_address,
- const QuicSocketAddress& peer_address) const {
- return alternative_path_.peer_address == peer_address &&
- alternative_path_.self_address == self_address;
-}
-
-void QuicConnection::PathState::Clear() {
- self_address = QuicSocketAddress();
- peer_address = QuicSocketAddress();
- client_connection_id = {};
- server_connection_id = {};
- validated = false;
- bytes_received_before_address_validation = 0;
- bytes_sent_before_address_validation = 0;
- send_algorithm = nullptr;
- rtt_stats = absl::nullopt;
- stateless_reset_token.reset();
-}
-
-QuicConnection::PathState::PathState(PathState&& other) {
- *this = std::move(other);
-}
-
-QuicConnection::PathState& QuicConnection::PathState::operator=(
- QuicConnection::PathState&& other) {
- if (this != &other) {
- self_address = other.self_address;
- peer_address = other.peer_address;
- client_connection_id = other.client_connection_id;
- server_connection_id = other.server_connection_id;
- stateless_reset_token = other.stateless_reset_token;
- validated = other.validated;
- bytes_received_before_address_validation =
- other.bytes_received_before_address_validation;
- bytes_sent_before_address_validation =
- other.bytes_sent_before_address_validation;
- send_algorithm = std::move(other.send_algorithm);
- if (other.rtt_stats.has_value()) {
- rtt_stats.emplace();
- rtt_stats->CloneFrom(other.rtt_stats.value());
- } else {
- rtt_stats.reset();
- }
- other.Clear();
- }
- return *this;
-}
-
-bool QuicConnection::IsReceivedPeerAddressValidated() const {
- QuicSocketAddress current_effective_peer_address =
- GetEffectivePeerAddressFromCurrentPacket();
- QUICHE_DCHECK(current_effective_peer_address.IsInitialized());
- return (alternative_path_.peer_address.host() ==
- current_effective_peer_address.host() &&
- alternative_path_.validated) ||
- (default_path_.validated && default_path_.peer_address.host() ==
- current_effective_peer_address.host());
-}
-
-QuicConnection::ReversePathValidationResultDelegate::
- ReversePathValidationResultDelegate(
- QuicConnection* connection,
- const QuicSocketAddress& direct_peer_address)
- : QuicPathValidator::ResultDelegate(),
- connection_(connection),
- original_direct_peer_address_(direct_peer_address),
- peer_address_default_path_(connection->direct_peer_address_),
- peer_address_alternative_path_(
- connection_->alternative_path_.peer_address),
- active_effective_peer_migration_type_(
- connection_->active_effective_peer_migration_type_) {}
-
-void QuicConnection::ReversePathValidationResultDelegate::
- OnPathValidationSuccess(
- std::unique_ptr<QuicPathValidationContext> context) {
- QUIC_DLOG(INFO) << "Successfully validated new path " << *context;
- if (connection_->IsDefaultPath(context->self_address(),
- context->peer_address())) {
- QUIC_CODE_COUNT_N(quic_kick_off_client_address_validation, 3, 6);
- if (connection_->active_effective_peer_migration_type_ == NO_CHANGE) {
- connection_->quic_bug_10511_43_timestamp_ =
- connection_->clock_->WallNow();
- connection_->quic_bug_10511_43_error_detail_ = absl::StrCat(
- "Reverse path validation on default path from ",
- context->self_address().ToString(), " to ",
- context->peer_address().ToString(),
- " completed without active peer address change: current "
- "peer address on default path ",
- connection_->direct_peer_address_.ToString(),
- ", peer address on default path when the reverse path "
- "validation was kicked off ",
- peer_address_default_path_.ToString(),
- ", peer address on alternative path when the reverse "
- "path validation was kicked off ",
- peer_address_alternative_path_.ToString(),
- ", with active_effective_peer_migration_type_ = ",
- AddressChangeTypeToString(active_effective_peer_migration_type_),
- ". The last received packet number ",
- connection_->last_header_.packet_number.ToString(),
- " Connection is connected: ", connection_->connected_);
- QUIC_BUG(quic_bug_10511_43)
- << connection_->quic_bug_10511_43_error_detail_;
- }
- connection_->OnEffectivePeerMigrationValidated();
- } else {
- QUICHE_DCHECK(connection_->IsAlternativePath(
- context->self_address(), context->effective_peer_address()));
- QUIC_CODE_COUNT_N(quic_kick_off_client_address_validation, 4, 6);
- QUIC_DVLOG(1) << "Mark alternative peer address "
- << context->effective_peer_address() << " validated.";
- connection_->alternative_path_.validated = true;
- }
-}
-
-void QuicConnection::ReversePathValidationResultDelegate::
- OnPathValidationFailure(
- std::unique_ptr<QuicPathValidationContext> context) {
- if (!connection_->connected()) {
- return;
- }
- QUIC_DLOG(INFO) << "Fail to validate new path " << *context;
- if (connection_->IsDefaultPath(context->self_address(),
- context->peer_address())) {
- // Only act upon validation failure on the default path.
- QUIC_CODE_COUNT_N(quic_kick_off_client_address_validation, 5, 6);
- connection_->RestoreToLastValidatedPath(original_direct_peer_address_);
- } else if (connection_->IsAlternativePath(
- context->self_address(), context->effective_peer_address())) {
- QUIC_CODE_COUNT_N(quic_kick_off_client_address_validation, 6, 6);
- connection_->alternative_path_.Clear();
- }
- connection_->RetirePeerIssuedConnectionIdsOnPathValidationFailure();
-}
-
-QuicConnection::ScopedRetransmissionTimeoutIndicator::
- ScopedRetransmissionTimeoutIndicator(QuicConnection* connection)
- : connection_(connection) {
- QUICHE_DCHECK(!connection_->in_on_retransmission_time_out_)
- << "ScopedRetransmissionTimeoutIndicator is not supposed to be nested";
- connection_->in_on_retransmission_time_out_ = true;
-}
-
-QuicConnection::ScopedRetransmissionTimeoutIndicator::
- ~ScopedRetransmissionTimeoutIndicator() {
- QUICHE_DCHECK(connection_->in_on_retransmission_time_out_);
- connection_->in_on_retransmission_time_out_ = false;
-}
-
-void QuicConnection::RestoreToLastValidatedPath(
- QuicSocketAddress original_direct_peer_address) {
- QUIC_DLOG(INFO) << "Switch back to use the old peer address "
- << alternative_path_.peer_address;
- if (!alternative_path_.validated) {
- // If not validated by now, close connection silently so that the following
- // packets received will be rejected.
- CloseConnection(QUIC_INTERNAL_ERROR,
- "No validated peer address to use after reverse path "
- "validation failure.",
- ConnectionCloseBehavior::SILENT_CLOSE);
- return;
- }
- MaybeClearQueuedPacketsOnPathChange();
-
- // Revert congestion control context to old state.
- OnPeerIpAddressChanged();
-
- if (alternative_path_.send_algorithm != nullptr) {
- sent_packet_manager_.SetSendAlgorithm(
- alternative_path_.send_algorithm.release());
- sent_packet_manager_.SetRttStats(alternative_path_.rtt_stats.value());
- } else {
- QUIC_BUG(quic_bug_10511_42)
- << "Fail to store congestion controller before migration.";
- }
-
- UpdatePeerAddress(original_direct_peer_address);
- SetDefaultPathState(std::move(alternative_path_));
-
- active_effective_peer_migration_type_ = NO_CHANGE;
- ++stats_.num_invalid_peer_migration;
- // The reverse path validation failed because of alarm firing, flush all the
- // pending writes previously throttled by anti-amplification limit.
- WriteIfNotBlocked();
-}
-
-std::unique_ptr<SendAlgorithmInterface>
-QuicConnection::OnPeerIpAddressChanged() {
- QUICHE_DCHECK(validate_client_addresses_);
- std::unique_ptr<SendAlgorithmInterface> old_send_algorithm =
- sent_packet_manager_.OnConnectionMigration(
- /*reset_send_algorithm=*/true);
- // OnConnectionMigration() should have marked in-flight packets to be
- // retransmitted if there is any.
- QUICHE_DCHECK(!sent_packet_manager_.HasInFlightPackets());
- // OnConnectionMigration() may have changed the retransmission timer, so
- // re-arm it.
- SetRetransmissionAlarm();
- // Stop detections in quiecense.
- blackhole_detector_.StopDetection(/*permanent=*/false);
- return old_send_algorithm;
-}
-
-#undef ENDPOINT // undef for jumbo builds
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_connection.h b/chromium/net/third_party/quiche/src/quic/core/quic_connection.h
deleted file mode 100644
index 954eb6a6d0f..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_connection.h
+++ /dev/null
@@ -1,2297 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// The entity that handles framing writes for a Quic client or server.
-// Each QuicSession will have a connection associated with it.
-//
-// On the server side, the Dispatcher handles the raw reads, and hands off
-// packets via ProcessUdpPacket for framing and processing.
-//
-// On the client side, the Connection handles the raw reads, as well as the
-// processing.
-//
-// Note: this class is not thread-safe.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_CONNECTION_H_
-#define QUICHE_QUIC_CORE_QUIC_CONNECTION_H_
-
-#include <cstddef>
-#include <cstdint>
-#include <list>
-#include <map>
-#include <memory>
-#include <string>
-#include <vector>
-
-#include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
-#include "quic/core/crypto/quic_decrypter.h"
-#include "quic/core/crypto/quic_encrypter.h"
-#include "quic/core/crypto/transport_parameters.h"
-#include "quic/core/frames/quic_ack_frequency_frame.h"
-#include "quic/core/frames/quic_max_streams_frame.h"
-#include "quic/core/frames/quic_new_connection_id_frame.h"
-#include "quic/core/proto/cached_network_parameters_proto.h"
-#include "quic/core/quic_alarm.h"
-#include "quic/core/quic_alarm_factory.h"
-#include "quic/core/quic_blocked_writer_interface.h"
-#include "quic/core/quic_connection_context.h"
-#include "quic/core/quic_connection_id.h"
-#include "quic/core/quic_connection_id_manager.h"
-#include "quic/core/quic_connection_stats.h"
-#include "quic/core/quic_constants.h"
-#include "quic/core/quic_framer.h"
-#include "quic/core/quic_idle_network_detector.h"
-#include "quic/core/quic_mtu_discovery.h"
-#include "quic/core/quic_network_blackhole_detector.h"
-#include "quic/core/quic_one_block_arena.h"
-#include "quic/core/quic_packet_creator.h"
-#include "quic/core/quic_packet_writer.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_path_validator.h"
-#include "quic/core/quic_sent_packet_manager.h"
-#include "quic/core/quic_time.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/uber_received_packet_manager.h"
-#include "quic/platform/api/quic_containers.h"
-#include "quic/platform/api/quic_export.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_socket_address.h"
-#include "common/quiche_circular_deque.h"
-
-namespace quic {
-
-class QuicClock;
-class QuicConfig;
-class QuicConnection;
-class QuicRandom;
-
-namespace test {
-class QuicConnectionPeer;
-} // namespace test
-
-// Class that receives callbacks from the connection when frames are received
-// and when other interesting events happen.
-class QUIC_EXPORT_PRIVATE QuicConnectionVisitorInterface {
- public:
- virtual ~QuicConnectionVisitorInterface() {}
-
- // A simple visitor interface for dealing with a data frame.
- virtual void OnStreamFrame(const QuicStreamFrame& frame) = 0;
-
- // Called when a CRYPTO frame containing handshake data is received.
- virtual void OnCryptoFrame(const QuicCryptoFrame& frame) = 0;
-
- // The session should process the WINDOW_UPDATE frame, adjusting both stream
- // and connection level flow control windows.
- virtual void OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame) = 0;
-
- // A BLOCKED frame indicates the peer is flow control blocked
- // on a specified stream.
- virtual void OnBlockedFrame(const QuicBlockedFrame& frame) = 0;
-
- // Called when the stream is reset by the peer.
- virtual void OnRstStream(const QuicRstStreamFrame& frame) = 0;
-
- // Called when the connection is going away according to the peer.
- virtual void OnGoAway(const QuicGoAwayFrame& frame) = 0;
-
- // Called when |message| has been received.
- virtual void OnMessageReceived(absl::string_view message) = 0;
-
- // Called when a HANDSHAKE_DONE frame has been received.
- virtual void OnHandshakeDoneReceived() = 0;
-
- // Called when a NEW_TOKEN frame has been received.
- virtual void OnNewTokenReceived(absl::string_view token) = 0;
-
- // Called when a MAX_STREAMS frame has been received from the peer.
- virtual bool OnMaxStreamsFrame(const QuicMaxStreamsFrame& frame) = 0;
-
- // Called when a STREAMS_BLOCKED frame has been received from the peer.
- virtual bool OnStreamsBlockedFrame(const QuicStreamsBlockedFrame& frame) = 0;
-
- // Called when the connection is closed either locally by the framer, or
- // remotely by the peer.
- virtual void OnConnectionClosed(const QuicConnectionCloseFrame& frame,
- ConnectionCloseSource source) = 0;
-
- // Called when the connection failed to write because the socket was blocked.
- virtual void OnWriteBlocked() = 0;
-
- // Called once a specific QUIC version is agreed by both endpoints.
- virtual void OnSuccessfulVersionNegotiation(
- const ParsedQuicVersion& version) = 0;
-
- // Called when a packet has been received by the connection, after being
- // validated and parsed. Only called when the client receives a valid packet
- // or the server receives a connectivity probing packet.
- // |is_connectivity_probe| is true if the received packet is a connectivity
- // probe.
- virtual void OnPacketReceived(const QuicSocketAddress& self_address,
- const QuicSocketAddress& peer_address,
- bool is_connectivity_probe) = 0;
-
- // 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 stateless reset packet is received. Returns true if the
- // connection needs to be closed.
- virtual bool ValidateStatelessReset(
- const quic::QuicSocketAddress& self_address,
- const quic::QuicSocketAddress& peer_address) = 0;
-
- // Called when the connection experiences a change in congestion window.
- virtual void OnCongestionWindowChange(QuicTime now) = 0;
-
- // Called when the connection receives a packet from a migrated client.
- virtual void OnConnectionMigration(AddressChangeType type) = 0;
-
- // Called when the peer seems unreachable over the current path.
- virtual void OnPathDegrading() = 0;
-
- // Called when forward progress made after path degrading.
- virtual void OnForwardProgressMadeAfterPathDegrading() = 0;
-
- // Called when the connection sends ack after
- // max_consecutive_num_packets_with_no_retransmittable_frames_ consecutive not
- // retransmittable packets sent. To instigate an ack from peer, a
- // retransmittable frame needs to be added.
- virtual void OnAckNeedsRetransmittableFrame() = 0;
-
- // Called when an AckFrequency frame need to be sent.
- virtual void SendAckFrequency(const QuicAckFrequencyFrame& frame) = 0;
-
- // Called to send a NEW_CONNECTION_ID frame.
- virtual void SendNewConnectionId(const QuicNewConnectionIdFrame& frame) = 0;
-
- // Called to send a RETIRE_CONNECTION_ID frame.
- virtual void SendRetireConnectionId(uint64_t sequence_number) = 0;
-
- // Called when server starts to use a server issued connection ID.
- virtual void OnServerConnectionIdIssued(
- const QuicConnectionId& server_connection_id) = 0;
-
- // Called when server stops to use a server issued connection ID.
- virtual void OnServerConnectionIdRetired(
- const QuicConnectionId& server_connection_id) = 0;
-
- // Called to ask if the visitor wants to schedule write resumption as it both
- // has pending data to write, and is able to write (e.g. based on flow control
- // limits).
- // Writes may be pending because they were write-blocked, congestion-throttled
- // or yielded to other connections.
- virtual bool WillingAndAbleToWrite() const = 0;
-
- // Called to ask if the connection should be kept alive and prevented
- // from timing out, for example if there are outstanding application
- // transactions expecting a response.
- virtual bool ShouldKeepConnectionAlive() const = 0;
-
- // Called to retrieve streams information for logging purpose.
- virtual std::string GetStreamsInfoForLogging() const = 0;
-
- // Called when a self address change is observed. Returns true if self address
- // change is allowed.
- virtual bool AllowSelfAddressChange() const = 0;
-
- // Called to get current handshake state.
- virtual HandshakeState GetHandshakeState() const = 0;
-
- // Called when a STOP_SENDING frame has been received.
- virtual void OnStopSendingFrame(const QuicStopSendingFrame& frame) = 0;
-
- // Called when a packet of encryption |level| has been successfully decrypted.
- virtual void OnPacketDecrypted(EncryptionLevel level) = 0;
-
- // Called when a 1RTT packet has been acknowledged.
- virtual void OnOneRttPacketAcknowledged() = 0;
-
- // Called when a packet of ENCRYPTION_HANDSHAKE gets sent.
- virtual void OnHandshakePacketSent() = 0;
-
- // Called when a key update has occurred.
- virtual void OnKeyUpdate(KeyUpdateReason reason) = 0;
-
- // Called to generate a decrypter for the next key phase. Each call should
- // generate the key for phase n+1.
- virtual std::unique_ptr<QuicDecrypter>
- AdvanceKeysAndCreateCurrentOneRttDecrypter() = 0;
-
- // Called to generate an encrypter for the same key phase of the last
- // decrypter returned by AdvanceKeysAndCreateCurrentOneRttDecrypter().
- virtual std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() = 0;
-
- // Called when connection is being closed right before a CONNECTION_CLOSE
- // frame is serialized, but only on the server and only if forward secure
- // encryption has already been established.
- virtual void BeforeConnectionCloseSent() = 0;
-
- // Called by the server to validate |token| in received INITIAL packets.
- // Consider the client address gets validated (and therefore remove
- // amplification factor) once the |token| gets successfully validated.
- virtual bool ValidateToken(absl::string_view token) = 0;
-
- // Called by the server to send another token.
- // Return false if the crypto stream fail to generate one.
- virtual bool MaybeSendAddressToken() = 0;
-
- // Whether the server address is known to the connection.
- virtual bool IsKnownServerAddress(const QuicSocketAddress& address) const = 0;
-};
-
-// Interface which gets callbacks from the QuicConnection at interesting
-// points. Implementations must not mutate the state of the connection
-// as a result of these callbacks.
-class QUIC_EXPORT_PRIVATE QuicConnectionDebugVisitor
- : public QuicSentPacketManager::DebugDelegate {
- public:
- ~QuicConnectionDebugVisitor() override {}
-
- // Called when a packet has been sent.
- virtual void OnPacketSent(QuicPacketNumber /*packet_number*/,
- QuicPacketLength /*packet_length*/,
- bool /*has_crypto_handshake*/,
- TransmissionType /*transmission_type*/,
- EncryptionLevel /*encryption_level*/,
- const QuicFrames& /*retransmittable_frames*/,
- const QuicFrames& /*nonretransmittable_frames*/,
- QuicTime /*sent_time*/) {}
-
- // Called when a coalesced packet is successfully serialized.
- virtual void OnCoalescedPacketSent(
- const QuicCoalescedPacket& /*coalesced_packet*/, size_t /*length*/) {}
-
- // Called when a PING frame has been sent.
- virtual void OnPingSent() {}
-
- // Called when a packet has been received, but before it is
- // validated or parsed.
- virtual void OnPacketReceived(const QuicSocketAddress& /*self_address*/,
- const QuicSocketAddress& /*peer_address*/,
- const QuicEncryptedPacket& /*packet*/) {}
-
- // Called when the unauthenticated portion of the header has been parsed.
- virtual void OnUnauthenticatedHeader(const QuicPacketHeader& /*header*/) {}
-
- // Called when a packet is received with a connection id that does not
- // match the ID of this connection.
- virtual void OnIncorrectConnectionId(QuicConnectionId /*connection_id*/) {}
-
- // Called when an undecryptable packet has been received. If |dropped| is
- // true, the packet has been dropped. Otherwise, the packet will be queued and
- // connection will attempt to process it later.
- virtual void OnUndecryptablePacket(EncryptionLevel /*decryption_level*/,
- bool /*dropped*/) {}
-
- // Called when attempting to process a previously undecryptable packet.
- virtual void OnAttemptingToProcessUndecryptablePacket(
- EncryptionLevel /*decryption_level*/) {}
-
- // Called when a duplicate packet has been received.
- virtual void OnDuplicatePacket(QuicPacketNumber /*packet_number*/) {}
-
- // Called when the protocol version on the received packet doensn't match
- // current protocol version of the connection.
- virtual void OnProtocolVersionMismatch(ParsedQuicVersion /*version*/) {}
-
- // Called when the complete header of a packet has been parsed.
- virtual void OnPacketHeader(const QuicPacketHeader& /*header*/,
- QuicTime /*receive_time*/,
- EncryptionLevel /*level*/) {}
-
- // Called when a StreamFrame has been parsed.
- virtual void OnStreamFrame(const QuicStreamFrame& /*frame*/) {}
-
- // Called when a CRYPTO frame containing handshake data is received.
- virtual void OnCryptoFrame(const QuicCryptoFrame& /*frame*/) {}
-
- // Called when a StopWaitingFrame has been parsed.
- virtual void OnStopWaitingFrame(const QuicStopWaitingFrame& /*frame*/) {}
-
- // Called when a QuicPaddingFrame has been parsed.
- virtual void OnPaddingFrame(const QuicPaddingFrame& /*frame*/) {}
-
- // Called when a Ping has been parsed.
- virtual void OnPingFrame(const QuicPingFrame& /*frame*/,
- QuicTime::Delta /*ping_received_delay*/) {}
-
- // Called when a GoAway has been parsed.
- virtual void OnGoAwayFrame(const QuicGoAwayFrame& /*frame*/) {}
-
- // Called when a RstStreamFrame has been parsed.
- virtual void OnRstStreamFrame(const QuicRstStreamFrame& /*frame*/) {}
-
- // Called when a ConnectionCloseFrame has been parsed. All forms
- // of CONNECTION CLOSE are handled, Google QUIC, IETF QUIC
- // CONNECTION CLOSE/Transport and IETF QUIC CONNECTION CLOSE/Application
- virtual void OnConnectionCloseFrame(
- const QuicConnectionCloseFrame& /*frame*/) {}
-
- // Called when a WindowUpdate has been parsed.
- virtual void OnWindowUpdateFrame(const QuicWindowUpdateFrame& /*frame*/,
- const QuicTime& /*receive_time*/) {}
-
- // Called when a BlockedFrame has been parsed.
- virtual void OnBlockedFrame(const QuicBlockedFrame& /*frame*/) {}
-
- // Called when a NewConnectionIdFrame has been parsed.
- virtual void OnNewConnectionIdFrame(
- const QuicNewConnectionIdFrame& /*frame*/) {}
-
- // Called when a RetireConnectionIdFrame has been parsed.
- virtual void OnRetireConnectionIdFrame(
- const QuicRetireConnectionIdFrame& /*frame*/) {}
-
- // Called when a NewTokenFrame has been parsed.
- virtual void OnNewTokenFrame(const QuicNewTokenFrame& /*frame*/) {}
-
- // Called when a MessageFrame has been parsed.
- virtual void OnMessageFrame(const QuicMessageFrame& /*frame*/) {}
-
- // Called when a HandshakeDoneFrame has been parsed.
- virtual void OnHandshakeDoneFrame(const QuicHandshakeDoneFrame& /*frame*/) {}
-
- // Called when a public reset packet has been received.
- virtual void OnPublicResetPacket(const QuicPublicResetPacket& /*packet*/) {}
-
- // Called when a version negotiation packet has been received.
- virtual void OnVersionNegotiationPacket(
- const QuicVersionNegotiationPacket& /*packet*/) {}
-
- // Called when the connection is closed.
- virtual void OnConnectionClosed(const QuicConnectionCloseFrame& /*frame*/,
- ConnectionCloseSource /*source*/) {}
-
- // Called when the version negotiation is successful.
- virtual void OnSuccessfulVersionNegotiation(
- const ParsedQuicVersion& /*version*/) {}
-
- // Called when a CachedNetworkParameters is sent to the client.
- virtual void OnSendConnectionState(
- const CachedNetworkParameters& /*cached_network_params*/) {}
-
- // Called when a CachedNetworkParameters are received from the client.
- virtual void OnReceiveConnectionState(
- const CachedNetworkParameters& /*cached_network_params*/) {}
-
- // Called when the connection parameters are set from the supplied
- // |config|.
- virtual void OnSetFromConfig(const QuicConfig& /*config*/) {}
-
- // Called when RTT may have changed, including when an RTT is read from
- // the config.
- virtual void OnRttChanged(QuicTime::Delta /*rtt*/) const {}
-
- // Called when a StopSendingFrame has been parsed.
- virtual void OnStopSendingFrame(const QuicStopSendingFrame& /*frame*/) {}
-
- // Called when a PathChallengeFrame has been parsed.
- virtual void OnPathChallengeFrame(const QuicPathChallengeFrame& /*frame*/) {}
-
- // Called when a PathResponseFrame has been parsed.
- virtual void OnPathResponseFrame(const QuicPathResponseFrame& /*frame*/) {}
-
- // Called when a StreamsBlockedFrame has been parsed.
- virtual void OnStreamsBlockedFrame(const QuicStreamsBlockedFrame& /*frame*/) {
- }
-
- // Called when a MaxStreamsFrame has been parsed.
- virtual void OnMaxStreamsFrame(const QuicMaxStreamsFrame& /*frame*/) {}
-
- // Called when an AckFrequencyFrame has been parsed.
- virtual void OnAckFrequencyFrame(const QuicAckFrequencyFrame& /*frame*/) {}
-
- // Called when |count| packet numbers have been skipped.
- virtual void OnNPacketNumbersSkipped(QuicPacketCount /*count*/,
- QuicTime /*now*/) {}
-
- // Called for QUIC+TLS versions when we send transport parameters.
- virtual void OnTransportParametersSent(
- const TransportParameters& /*transport_parameters*/) {}
-
- // Called for QUIC+TLS versions when we receive transport parameters.
- virtual void OnTransportParametersReceived(
- const TransportParameters& /*transport_parameters*/) {}
-
- // Called for QUIC+TLS versions when we resume cached transport parameters for
- // 0-RTT.
- virtual void OnTransportParametersResumed(
- const TransportParameters& /*transport_parameters*/) {}
-
- // Called for QUIC+TLS versions when 0-RTT is rejected.
- virtual void OnZeroRttRejected(int /*reject_reason*/) {}
-
- // Called for QUIC+TLS versions when 0-RTT packet gets acked.
- virtual void OnZeroRttPacketAcked() {}
-
- // Called on peer address change.
- virtual void OnPeerAddressChange(AddressChangeType /*type*/,
- QuicTime::Delta /*connection_time*/) {}
-
- // Called after peer migration is validated.
- virtual void OnPeerMigrationValidated(QuicTime::Delta /*connection_time*/) {}
-};
-
-class QUIC_EXPORT_PRIVATE QuicConnectionHelperInterface {
- public:
- virtual ~QuicConnectionHelperInterface() {}
-
- // Returns a QuicClock to be used for all time related functions.
- virtual const QuicClock* GetClock() const = 0;
-
- // Returns a QuicRandom to be used for all random number related functions.
- virtual QuicRandom* GetRandomGenerator() = 0;
-
- // Returns a QuicBufferAllocator to be used for stream send buffers.
- virtual QuicBufferAllocator* GetStreamSendBufferAllocator() = 0;
-};
-
-class QUIC_EXPORT_PRIVATE QuicConnection
- : public QuicFramerVisitorInterface,
- public QuicBlockedWriterInterface,
- public QuicPacketCreator::DelegateInterface,
- public QuicSentPacketManager::NetworkChangeVisitor,
- public QuicNetworkBlackholeDetector::Delegate,
- public QuicIdleNetworkDetector::Delegate,
- public QuicPathValidator::SendDelegate,
- public QuicConnectionIdManagerVisitorInterface {
- public:
- // Constructs a new QuicConnection for |connection_id| and
- // |initial_peer_address| using |writer| to write packets. |owns_writer|
- // specifies whether the connection takes ownership of |writer|. |helper| must
- // outlive this connection.
- QuicConnection(QuicConnectionId server_connection_id,
- QuicSocketAddress initial_self_address,
- QuicSocketAddress initial_peer_address,
- QuicConnectionHelperInterface* helper,
- QuicAlarmFactory* alarm_factory,
- QuicPacketWriter* writer,
- bool owns_writer,
- Perspective perspective,
- const ParsedQuicVersionVector& supported_versions);
- QuicConnection(const QuicConnection&) = delete;
- QuicConnection& operator=(const QuicConnection&) = delete;
- ~QuicConnection() override;
-
- // Sets connection parameters from the supplied |config|.
- void SetFromConfig(const QuicConfig& config);
-
- // Apply |connection_options| for this connection. Unlike SetFromConfig, this
- // can happen at anytime in the life of a connection.
- // Note there is no guarantee that all options can be applied. Components will
- // only apply cherrypicked options that make sense at the time of the call.
- void ApplyConnectionOptions(const QuicTagVector& connection_options);
-
- // Called by the session when sending connection state to the client.
- virtual void OnSendConnectionState(
- const CachedNetworkParameters& cached_network_params);
-
- // Called by the session when receiving connection state from the client.
- virtual void OnReceiveConnectionState(
- const CachedNetworkParameters& cached_network_params);
-
- // Called by the Session when the client has provided CachedNetworkParameters.
- virtual void ResumeConnectionState(
- const CachedNetworkParameters& cached_network_params,
- bool max_bandwidth_resumption);
-
- // Called by the Session when a max pacing rate for the connection is needed.
- virtual void SetMaxPacingRate(QuicBandwidth max_pacing_rate);
-
- // Allows the client to adjust network parameters based on external
- // information.
- void AdjustNetworkParameters(
- const SendAlgorithmInterface::NetworkParams& params);
- void AdjustNetworkParameters(QuicBandwidth bandwidth,
- QuicTime::Delta rtt,
- bool allow_cwnd_to_decrease);
-
- // Install a loss detection tuner. Must be called before OnConfigNegotiated.
- void SetLossDetectionTuner(
- std::unique_ptr<LossDetectionTunerInterface> tuner);
- // Called by the session when session->is_configured() becomes true.
- void OnConfigNegotiated();
-
- // Returns the max pacing rate for the connection.
- virtual QuicBandwidth MaxPacingRate() const;
-
- // Sends crypto handshake messages of length |write_length| to the peer in as
- // few packets as possible. Returns the number of bytes consumed from the
- // data.
- virtual size_t SendCryptoData(EncryptionLevel level,
- size_t write_length,
- QuicStreamOffset offset);
-
- // Send the data of length |write_length| to the peer in as few packets as
- // possible. Returns the number of bytes consumed from data, and a boolean
- // indicating if the fin bit was consumed. This does not indicate the data
- // has been sent on the wire: it may have been turned into a packet and queued
- // if the socket was unexpectedly blocked.
- virtual QuicConsumedData SendStreamData(QuicStreamId id,
- size_t write_length,
- QuicStreamOffset offset,
- StreamSendingState state);
-
- // Send |frame| to the peer. Returns true if frame is consumed, false
- // otherwise.
- virtual bool SendControlFrame(const QuicFrame& frame);
-
- // Called when stream |id| is reset because of |error|.
- virtual void OnStreamReset(QuicStreamId id, QuicRstStreamErrorCode error);
-
- // Closes the connection.
- // |connection_close_behavior| determines whether or not a connection close
- // packet is sent to the peer.
- virtual void CloseConnection(
- QuicErrorCode error,
- const std::string& details,
- ConnectionCloseBehavior connection_close_behavior);
- // Closes the connection, specifying the wire error code |ietf_error|
- // explicitly.
- virtual void CloseConnection(
- QuicErrorCode error,
- QuicIetfTransportErrorCodes ietf_error,
- const std::string& details,
- ConnectionCloseBehavior connection_close_behavior);
-
- QuicConnectionStats& mutable_stats() { return stats_; }
-
- int retransmittable_on_wire_ping_count() const {
- return retransmittable_on_wire_ping_count_;
- }
-
- // Returns statistics tracked for this connection.
- const QuicConnectionStats& GetStats();
-
- // Processes an incoming UDP packet (consisting of a QuicEncryptedPacket) from
- // the peer.
- // In a client, the packet may be "stray" and have a different connection ID
- // than that of this connection.
- virtual void ProcessUdpPacket(const QuicSocketAddress& self_address,
- const QuicSocketAddress& peer_address,
- const QuicReceivedPacket& packet);
-
- // QuicBlockedWriterInterface
- // Called when the underlying connection becomes writable to allow queued
- // writes to happen.
- void OnBlockedWriterCanWrite() override;
-
- bool IsWriterBlocked() const override {
- return writer_ != nullptr && writer_->IsWriteBlocked();
- }
-
- // Called when the caller thinks it's worth a try to write.
- // TODO(fayang): consider unifying this with QuicSession::OnCanWrite.
- virtual void OnCanWrite();
-
- // Called when an error occurs while attempting to write a packet to the
- // network.
- void OnWriteError(int error_code);
-
- // Whether |result| represents a MSG TOO BIG write error.
- bool IsMsgTooBig(const WriteResult& result);
-
- // If the socket is not blocked, writes queued packets.
- void WriteIfNotBlocked();
-
- // Set the packet writer.
- void SetQuicPacketWriter(QuicPacketWriter* writer, bool owns_writer) {
- QUICHE_DCHECK(writer != nullptr);
- if (writer_ != nullptr && owns_writer_) {
- delete writer_;
- }
- writer_ = writer;
- owns_writer_ = owns_writer;
- }
-
- // Set self address.
- void SetSelfAddress(QuicSocketAddress address) {
- default_path_.self_address = address;
- }
-
- // The version of the protocol this connection is using.
- QuicTransportVersion transport_version() const {
- return framer_.transport_version();
- }
-
- ParsedQuicVersion version() const { return framer_.version(); }
-
- // The versions of the protocol that this connection supports.
- const ParsedQuicVersionVector& supported_versions() const {
- return framer_.supported_versions();
- }
-
- // Mark version negotiated for this connection. Once called, the connection
- // will ignore received version negotiation packets.
- void SetVersionNegotiated() {
- version_negotiated_ = true;
- if (perspective_ == Perspective::IS_SERVER) {
- framer_.InferPacketHeaderTypeFromVersion();
- }
- }
-
- // From QuicFramerVisitorInterface
- void OnError(QuicFramer* framer) override;
- bool OnProtocolVersionMismatch(ParsedQuicVersion received_version) override;
- void OnPacket() override;
- void OnPublicResetPacket(const QuicPublicResetPacket& packet) override;
- void OnVersionNegotiationPacket(
- const QuicVersionNegotiationPacket& packet) override;
- void OnRetryPacket(QuicConnectionId original_connection_id,
- QuicConnectionId new_connection_id,
- absl::string_view retry_token,
- absl::string_view retry_integrity_tag,
- absl::string_view retry_without_tag) override;
- bool OnUnauthenticatedPublicHeader(const QuicPacketHeader& header) override;
- bool OnUnauthenticatedHeader(const QuicPacketHeader& header) override;
- void OnDecryptedPacket(size_t length, EncryptionLevel level) override;
- bool OnPacketHeader(const QuicPacketHeader& header) override;
- void OnCoalescedPacket(const QuicEncryptedPacket& packet) override;
- void OnUndecryptablePacket(const QuicEncryptedPacket& packet,
- EncryptionLevel decryption_level,
- bool has_decryption_key) override;
- bool OnStreamFrame(const QuicStreamFrame& frame) override;
- bool OnCryptoFrame(const QuicCryptoFrame& frame) override;
- bool OnAckFrameStart(QuicPacketNumber largest_acked,
- QuicTime::Delta ack_delay_time) override;
- bool OnAckRange(QuicPacketNumber start, QuicPacketNumber end) override;
- bool OnAckTimestamp(QuicPacketNumber packet_number,
- QuicTime timestamp) override;
- bool OnAckFrameEnd(QuicPacketNumber start) override;
- bool OnStopWaitingFrame(const QuicStopWaitingFrame& frame) override;
- bool OnPaddingFrame(const QuicPaddingFrame& frame) override;
- bool OnPingFrame(const QuicPingFrame& frame) override;
- bool OnRstStreamFrame(const QuicRstStreamFrame& frame) override;
- bool OnConnectionCloseFrame(const QuicConnectionCloseFrame& frame) override;
- bool OnStopSendingFrame(const QuicStopSendingFrame& frame) override;
- bool OnPathChallengeFrame(const QuicPathChallengeFrame& frame) override;
- bool OnPathResponseFrame(const QuicPathResponseFrame& frame) override;
- bool OnGoAwayFrame(const QuicGoAwayFrame& frame) override;
- bool OnMaxStreamsFrame(const QuicMaxStreamsFrame& frame) override;
- bool OnStreamsBlockedFrame(const QuicStreamsBlockedFrame& frame) override;
- bool OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame) override;
- bool OnBlockedFrame(const QuicBlockedFrame& frame) override;
- bool OnNewConnectionIdFrame(const QuicNewConnectionIdFrame& frame) override;
- bool OnRetireConnectionIdFrame(
- const QuicRetireConnectionIdFrame& frame) override;
- bool OnNewTokenFrame(const QuicNewTokenFrame& frame) override;
- bool OnMessageFrame(const QuicMessageFrame& frame) override;
- bool OnHandshakeDoneFrame(const QuicHandshakeDoneFrame& frame) override;
- bool OnAckFrequencyFrame(const QuicAckFrequencyFrame& frame) override;
- void OnPacketComplete() override;
- bool IsValidStatelessResetToken(
- const StatelessResetToken& token) const override;
- void OnAuthenticatedIetfStatelessResetPacket(
- const QuicIetfStatelessResetPacket& packet) override;
- void OnKeyUpdate(KeyUpdateReason reason) override;
- void OnDecryptedFirstPacketInKeyPhase() override;
- std::unique_ptr<QuicDecrypter> AdvanceKeysAndCreateCurrentOneRttDecrypter()
- override;
- std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() override;
-
- // QuicPacketCreator::DelegateInterface
- bool ShouldGeneratePacket(HasRetransmittableData retransmittable,
- IsHandshake handshake) override;
- const QuicFrames MaybeBundleAckOpportunistically() override;
- QuicPacketBuffer GetPacketBuffer() override;
- void OnSerializedPacket(SerializedPacket packet) override;
- void OnUnrecoverableError(QuicErrorCode error,
- const std::string& error_details) override;
- SerializedPacketFate GetSerializedPacketFate(
- bool is_mtu_discovery,
- EncryptionLevel encryption_level) override;
-
- // QuicSentPacketManager::NetworkChangeVisitor
- void OnCongestionChange() override;
- void OnPathMtuIncreased(QuicPacketLength packet_size) override;
-
- // QuicNetworkBlackholeDetector::Delegate
- void OnPathDegradingDetected() override;
- void OnBlackholeDetected() override;
- void OnPathMtuReductionDetected() override;
-
- // QuicIdleNetworkDetector::Delegate
- void OnHandshakeTimeout() override;
- void OnIdleNetworkDetected() override;
-
- // QuicConnectionIdManagerVisitorInterface
- void OnPeerIssuedConnectionIdRetired() override;
- bool SendNewConnectionId(const QuicNewConnectionIdFrame& frame) override;
- void OnNewConnectionIdIssued(const QuicConnectionId& connection_id) override;
- void OnSelfIssuedConnectionIdRetired(
- const QuicConnectionId& connection_id) override;
-
- // Please note, this is not a const function. For logging purpose, please use
- // ack_frame().
- const QuicFrame GetUpdatedAckFrame();
-
- // Called to send a new connection ID to client if the # of connection ID has
- // not exceeded the active connection ID limits.
- void MaybeSendConnectionIdToClient();
-
- // Called when the handshake completes. On the client side, handshake
- // completes on receipt of SHLO. On the server side, handshake completes when
- // SHLO gets ACKed (or a forward secure packet gets decrypted successfully).
- // TODO(fayang): Add a guard that this only gets called once.
- void OnHandshakeComplete();
-
- // Accessors
- void set_visitor(QuicConnectionVisitorInterface* visitor) {
- visitor_ = visitor;
- }
- void set_debug_visitor(QuicConnectionDebugVisitor* debug_visitor) {
- debug_visitor_ = debug_visitor;
- sent_packet_manager_.SetDebugDelegate(debug_visitor);
- }
- // 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_; }
- // 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_;
- }
- // Used in Chromium, but not internally.
- void set_creator_debug_delegate(QuicPacketCreator::DebugDelegate* visitor) {
- packet_creator_.set_debug_delegate(visitor);
- }
- const QuicSocketAddress& self_address() const {
- return default_path_.self_address;
- }
- const QuicSocketAddress& peer_address() const { return direct_peer_address_; }
- const QuicSocketAddress& effective_peer_address() const {
- return default_path_.peer_address;
- }
-
- // Returns the server connection ID used on the default path.
- const QuicConnectionId& connection_id() const {
- return default_path_.server_connection_id;
- }
-
- const QuicConnectionId& client_connection_id() const {
- return default_path_.client_connection_id;
- }
- void set_client_connection_id(QuicConnectionId client_connection_id);
- const QuicClock* clock() const { return clock_; }
- QuicRandom* random_generator() const { return random_generator_; }
- QuicByteCount max_packet_length() const;
- void SetMaxPacketLength(QuicByteCount length);
-
- size_t mtu_probe_count() const { return mtu_probe_count_; }
-
- bool connected() const { return connected_; }
-
- // Must only be called on client connections.
- const ParsedQuicVersionVector& server_supported_versions() const {
- QUICHE_DCHECK_EQ(Perspective::IS_CLIENT, perspective_);
- return server_supported_versions_;
- }
-
- bool HasQueuedPackets() const { return !buffered_packets_.empty(); }
- // Testing only. TODO(ianswett): Use a peer instead.
- size_t NumQueuedPackets() const { return buffered_packets_.size(); }
-
- // Returns true if the connection has queued packets or frames.
- bool HasQueuedData() const;
-
- // Sets the handshake and idle state connection timeouts.
- void SetNetworkTimeouts(QuicTime::Delta handshake_timeout,
- QuicTime::Delta idle_timeout);
-
- // Called when the ping alarm fires. Causes a ping frame to be sent only
- // if the retransmission alarm is not running.
- void OnPingTimeout();
-
- // Sets up a packet with an QuicAckFrame and sends it out.
- void SendAck();
-
- // Called when an RTO fires. Resets the retransmission alarm if there are
- // remaining unacked packets.
- void OnRetransmissionTimeout();
-
- // Mark all sent 0-RTT encrypted packets for retransmission. Called when new
- // 0-RTT or 1-RTT key is available in gQUIC, or when 0-RTT is rejected in IETF
- // QUIC. |reject_reason| is used in TLS-QUIC to log why 0-RTT was rejected.
- void MarkZeroRttPacketsForRetransmission(int reject_reason);
-
- // Calls |sent_packet_manager_|'s NeuterUnencryptedPackets. Used when the
- // connection becomes forward secure and hasn't received acks for all packets.
- void NeuterUnencryptedPackets();
-
- // Changes the encrypter used for level |level| to |encrypter|.
- void SetEncrypter(EncryptionLevel level,
- std::unique_ptr<QuicEncrypter> encrypter);
-
- // Called to remove encrypter of encryption |level|.
- void RemoveEncrypter(EncryptionLevel level);
-
- // SetNonceForPublicHeader sets the nonce that will be transmitted in the
- // header of each packet encrypted at the initial encryption level decrypted.
- // This should only be called on the server side.
- void SetDiversificationNonce(const DiversificationNonce& nonce);
-
- // SetDefaultEncryptionLevel sets the encryption level that will be applied
- // to new packets.
- void SetDefaultEncryptionLevel(EncryptionLevel level);
-
- // SetDecrypter sets the primary decrypter, replacing any that already exists.
- // If an alternative decrypter is in place then the function QUICHE_DCHECKs.
- // This is intended for cases where one knows that future packets will be
- // using the new decrypter and the previous decrypter is now obsolete. |level|
- // indicates the encryption level of the new decrypter.
- void SetDecrypter(EncryptionLevel level,
- std::unique_ptr<QuicDecrypter> decrypter);
-
- // SetAlternativeDecrypter sets a decrypter that may be used to decrypt
- // future packets. |level| indicates the encryption level of the decrypter. If
- // |latch_once_used| is true, then the first time that the decrypter is
- // successful it will replace the primary decrypter. Otherwise both
- // decrypters will remain active and the primary decrypter will be the one
- // last used.
- void SetAlternativeDecrypter(EncryptionLevel level,
- std::unique_ptr<QuicDecrypter> decrypter,
- bool latch_once_used);
-
- void InstallDecrypter(EncryptionLevel level,
- std::unique_ptr<QuicDecrypter> decrypter);
- void RemoveDecrypter(EncryptionLevel level);
-
- // Discard keys for the previous key phase.
- void DiscardPreviousOneRttKeys();
-
- // Returns true if it is currently allowed to initiate a key update.
- bool IsKeyUpdateAllowed() const;
-
- // Returns true if packets have been sent in the current 1-RTT key phase but
- // none of these packets have been acked.
- bool HaveSentPacketsInCurrentKeyPhaseButNoneAcked() const;
-
- // Returns the count of packets received that appeared to attempt a key
- // update but failed decryption that have been received since the last
- // successfully decrypted packet.
- QuicPacketCount PotentialPeerKeyUpdateAttemptCount() const;
-
- // Increment the key phase. It is a bug to call this when IsKeyUpdateAllowed()
- // is false. Returns false on error.
- bool InitiateKeyUpdate(KeyUpdateReason reason);
-
- const QuicDecrypter* decrypter() const;
- const QuicDecrypter* alternative_decrypter() const;
-
- Perspective perspective() const { return perspective_; }
-
- // Allow easy overriding of truncated connection IDs.
- void set_can_truncate_connection_ids(bool can) {
- can_truncate_connection_ids_ = can;
- }
-
- // Returns the underlying sent packet manager.
- const QuicSentPacketManager& sent_packet_manager() const {
- return sent_packet_manager_;
- }
-
- // Returns the underlying sent packet manager.
- QuicSentPacketManager& sent_packet_manager() { return sent_packet_manager_; }
-
- UberReceivedPacketManager& received_packet_manager() {
- return uber_received_packet_manager_;
- }
-
- bool CanWrite(HasRetransmittableData retransmittable);
-
- // When the flusher is out of scope, only the outermost flusher will cause a
- // flush of the connection and set the retransmission alarm if there is one
- // pending. In addition, this flusher can be configured to ensure that an ACK
- // frame is included in the first packet created, if there's new ack
- // information to be sent.
- class QUIC_EXPORT_PRIVATE ScopedPacketFlusher {
- public:
- explicit ScopedPacketFlusher(QuicConnection* connection);
- ~ScopedPacketFlusher();
-
- private:
- QuicConnection* connection_;
- // If true, when this flusher goes out of scope, flush connection and set
- // retransmission alarm if there is one pending.
- bool flush_and_set_pending_retransmission_alarm_on_delete_;
- // Latched connection's handshake_packet_sent_ on creation of this flusher.
- const bool handshake_packet_sent_;
- };
-
- class QUIC_EXPORT_PRIVATE ScopedEncryptionLevelContext {
- public:
- ScopedEncryptionLevelContext(QuicConnection* connection,
- EncryptionLevel level);
- ~ScopedEncryptionLevelContext();
-
- private:
- QuicConnection* connection_;
- // Latched current write encryption level on creation of this context.
- EncryptionLevel latched_encryption_level_;
- };
-
- QuicPacketWriter* writer() { return writer_; }
- const QuicPacketWriter* writer() const { return writer_; }
-
- // Sends an MTU discovery packet of size |target_mtu|. If the packet is
- // acknowledged by the peer, the maximum packet size will be increased to
- // |target_mtu|.
- void SendMtuDiscoveryPacket(QuicByteCount target_mtu);
-
- // Sends a connectivity probing packet to |peer_address| with
- // |probing_writer|. If |probing_writer| is nullptr, will use default
- // packet writer to write the packet. Returns true if subsequent packets can
- // be written to the probing writer. If connection is V99, a padded IETF QUIC
- // PATH_CHALLENGE packet is transmitted; if not V99, a Google QUIC padded PING
- // packet is transmitted.
- virtual bool SendConnectivityProbingPacket(
- QuicPacketWriter* probing_writer,
- const QuicSocketAddress& peer_address);
-
- // Sends response to a connectivity probe. Sends either a Padded Ping
- // or an IETF PATH_RESPONSE based on the version of the connection.
- // Is the counterpart to SendConnectivityProbingPacket().
- // TODO(danzh): remove this method after deprecating
- // --gfe2_reloadable_flag_quic_send_path_response.
- virtual void SendConnectivityProbingResponsePacket(
- const QuicSocketAddress& peer_address);
-
- // Disable MTU discovery on this connection.
- void DisableMtuDiscovery();
-
- // Sends an MTU discovery packet and updates the MTU discovery alarm.
- void DiscoverMtu();
-
- // Sets the session notifier on the SentPacketManager.
- void SetSessionNotifier(SessionNotifierInterface* session_notifier);
-
- // Set data producer in framer.
- void SetDataProducer(QuicStreamFrameDataProducer* data_producer);
-
- // Set transmission type of next sending packets.
- void SetTransmissionType(TransmissionType type);
-
- // Tries to send |message| and returns the message status.
- // If |flush| is false, this will return a MESSAGE_STATUS_BLOCKED
- // when the connection is deemed unwritable.
- virtual MessageStatus SendMessage(QuicMessageId message_id,
- absl::Span<QuicMemSlice> message,
- bool flush);
-
- // Returns the largest payload that will fit into a single MESSAGE frame.
- // Because overhead can vary during a connection, this method should be
- // checked for every message.
- QuicPacketLength GetCurrentLargestMessagePayload() const;
- // Returns the largest payload that will fit into a single MESSAGE frame at
- // any point during the connection. This assumes the version and
- // connection ID lengths do not change.
- QuicPacketLength GetGuaranteedLargestMessagePayload() const;
-
- void SetUnackedMapInitialCapacity();
-
- virtual int GetUnackedMapInitialCapacity() const {
- return kDefaultUnackedPacketsInitialCapacity;
- }
-
- // Returns the id of the cipher last used for decrypting packets.
- uint32_t cipher_id() const;
-
- std::vector<std::unique_ptr<QuicEncryptedPacket>>* termination_packets() {
- return termination_packets_.get();
- }
-
- bool ack_frame_updated() const;
-
- QuicConnectionHelperInterface* helper() { return helper_; }
- const QuicConnectionHelperInterface* helper() const { return helper_; }
- QuicAlarmFactory* alarm_factory() { return alarm_factory_; }
-
- absl::string_view GetCurrentPacket();
-
- const QuicFramer& framer() const { return framer_; }
-
- const QuicPacketCreator& packet_creator() const { return packet_creator_; }
-
- EncryptionLevel encryption_level() const { return encryption_level_; }
- EncryptionLevel last_decrypted_level() const {
- return last_decrypted_packet_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.
- //
- // This setting should never be set to false in public facing endpoints. It
- // can only be set to false if there is some other mechanism of preventing
- // amplification attacks, such as ICE (plus its a non-standard quic).
- void set_fully_pad_crypto_handshake_packets(bool new_value) {
- packet_creator_.set_fully_pad_crypto_handshake_packets(new_value);
- }
-
- bool fully_pad_during_crypto_handshake() const {
- return packet_creator_.fully_pad_crypto_handshake_packets();
- }
-
- size_t min_received_before_ack_decimation() const;
- void set_min_received_before_ack_decimation(size_t new_value);
-
- // If |defer| is true, configures the connection to defer sending packets in
- // response to an ACK to the SendAlarm. If |defer| is false, packets may be
- // sent immediately after receiving an ACK.
- void set_defer_send_in_response_to_packets(bool defer) {
- defer_send_in_response_to_packets_ = defer;
- }
-
- // Sets the current per-packet options for the connection. The QuicConnection
- // does not take ownership of |options|; |options| must live for as long as
- // the QuicConnection is in use.
- void set_per_packet_options(PerPacketOptions* options) {
- per_packet_options_ = options;
- }
-
- bool IsPathDegrading() const { return is_path_degrading_; }
-
- // Attempts to process any queued undecryptable packets.
- void MaybeProcessUndecryptablePackets();
-
- // Queue a coalesced packet.
- void QueueCoalescedPacket(const QuicEncryptedPacket& packet);
-
- // Process previously queued coalesced packets. Returns true if any coalesced
- // packets have been successfully processed.
- bool MaybeProcessCoalescedPackets();
-
- enum PacketContent : uint8_t {
- NO_FRAMES_RECEIVED,
- // TODO(fkastenholz): Change name when we get rid of padded ping/
- // pre-version-99.
- // Also PATH CHALLENGE and PATH RESPONSE.
- FIRST_FRAME_IS_PING,
- SECOND_FRAME_IS_PADDING,
- NOT_PADDED_PING, // Set if the packet is not {PING, PADDING}.
- };
-
- // Whether the handshake completes from this connection's perspective.
- bool IsHandshakeComplete() const;
-
- // Whether peer completes handshake. Only used with TLS handshake.
- bool IsHandshakeConfirmed() const;
-
- // Returns the largest received packet number sent by peer.
- QuicPacketNumber GetLargestReceivedPacket() const;
-
- // Sets the original destination connection ID on the connection.
- // This is called by QuicDispatcher when it has replaced the connection ID.
- void SetOriginalDestinationConnectionId(
- const QuicConnectionId& original_destination_connection_id);
-
- // Returns the original destination connection ID used for this connection.
- QuicConnectionId GetOriginalDestinationConnectionId();
-
- // Called when ACK alarm goes off. Sends ACKs of those packet number spaces
- // which have expired ACK timeout. Only used when this connection supports
- // multiple packet number spaces.
- void SendAllPendingAcks();
-
- // Returns true if this connection supports multiple packet number spaces.
- bool SupportsMultiplePacketNumberSpaces() const;
-
- // For logging purpose.
- const QuicAckFrame& ack_frame() const;
-
- // Install encrypter and decrypter for ENCRYPTION_INITIAL using
- // |connection_id| as the first client-sent destination connection ID,
- // or the one sent after an IETF Retry.
- void InstallInitialCrypters(QuicConnectionId connection_id);
-
- // Called when version is considered negotiated.
- void OnSuccessfulVersionNegotiation();
-
- // Called when self migration succeeds after probing.
- void OnSuccessfulMigration(bool is_port_change);
-
- // Called for QUIC+TLS versions when we send transport parameters.
- void OnTransportParametersSent(
- const TransportParameters& transport_parameters) const;
-
- // Called for QUIC+TLS versions when we receive transport parameters.
- void OnTransportParametersReceived(
- const TransportParameters& transport_parameters) const;
-
- // Called for QUIC+TLS versions when we resume cached transport parameters for
- // 0-RTT.
- void OnTransportParametersResumed(
- const TransportParameters& transport_parameters) const;
-
- // Returns true if ack_alarm_ is set.
- bool HasPendingAcks() const;
-
- virtual void OnUserAgentIdKnown(const std::string& user_agent_id);
-
- // Enables Legacy Version Encapsulation using |server_name| as SNI.
- // Can only be set if this is a client connection.
- void EnableLegacyVersionEncapsulation(const std::string& server_name);
-
- bool send_path_response() const { return send_path_response_; }
-
- bool use_path_validator() const { return use_path_validator_; }
-
- // If now is close to idle timeout, returns true and sends a connectivity
- // probing packet to test the connection for liveness. Otherwise, returns
- // false.
- bool MaybeTestLiveness();
-
- // QuicPathValidator::SendDelegate
- // Send PATH_CHALLENGE using the given path information. If |writer| is the
- // default writer, PATH_CHALLENGE can be bundled with other frames, and the
- // containing packet can be buffered if the writer is blocked. Otherwise,
- // PATH_CHALLENGE will be written in an individual packet and it will be
- // dropped if write fails. |data_buffer| will be populated with the payload
- // for future validation.
- // Return false if the connection is closed thus the caller will not continue
- // the validation, otherwise return true.
- bool SendPathChallenge(const QuicPathFrameBuffer& data_buffer,
- const QuicSocketAddress& self_address,
- const QuicSocketAddress& peer_address,
- const QuicSocketAddress& effective_peer_address,
- QuicPacketWriter* writer) override;
- // If |writer| is the default writer and |peer_address| is the same as
- // peer_address(), return the PTO of this connection. Otherwise, return 3 *
- // kInitialRtt.
- QuicTime GetRetryTimeout(const QuicSocketAddress& peer_address_to_use,
- QuicPacketWriter* writer_to_use) const override;
-
- // Start vaildating the path defined by |context| asynchronously and call the
- // |result_delegate| after validation finishes. If the connection is
- // validating another path, cancel and fail that validation before starting
- // this one.
- void ValidatePath(
- std::unique_ptr<QuicPathValidationContext> context,
- std::unique_ptr<QuicPathValidator::ResultDelegate> result_delegate);
-
- bool can_receive_ack_frequency_frame() const {
- return can_receive_ack_frequency_frame_;
- }
-
- void set_can_receive_ack_frequency_frame() {
- can_receive_ack_frequency_frame_ = true;
- }
-
- bool is_processing_packet() const { return framer_.is_processing_packet(); }
-
- bool HasPendingPathValidation() const;
-
- QuicPathValidationContext* GetPathValidationContext() const;
-
- void CancelPathValidation();
-
- // Returns true if the migration succeeds, otherwise returns false (e.g., no
- // available CIDs, connection disconnected, etc).
- bool MigratePath(const QuicSocketAddress& self_address,
- const QuicSocketAddress& peer_address,
- QuicPacketWriter* writer,
- bool owns_writer);
-
- // Called to clear the alternative_path_ when path validation failed on the
- // client side.
- void OnPathValidationFailureAtClient();
-
- void SetSourceAddressTokenToSend(absl::string_view token);
-
- void SendPing() {
- SendPingAtLevel(framer().GetEncryptionLevelToSendApplicationData());
- }
-
- // Returns one server connection ID that associates the current session in the
- // session map.
- virtual QuicConnectionId GetOneActiveServerConnectionId() const;
-
- // Returns all server connection IDs that have not been removed from the
- // session map.
- virtual std::vector<QuicConnectionId> GetActiveServerConnectionIds() const;
-
- bool validate_client_address() const { return validate_client_addresses_; }
-
- bool connection_migration_use_new_cid() const {
- 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();
-
- QuicConnectionContext* context() { return &context_; }
- const QuicConnectionContext* context() const { return &context_; }
-
- void set_tracer(std::unique_ptr<QuicConnectionTracer> tracer) {
- context_.tracer.swap(tracer);
- }
-
- void set_bug_listener(std::unique_ptr<QuicBugListener> bug_listener) {
- context_.bug_listener.swap(bug_listener);
- }
-
- absl::optional<QuicWallTime> quic_bug_10511_43_timestamp() const {
- return quic_bug_10511_43_timestamp_;
- }
-
- const std::string& quic_bug_10511_43_error_detail() const {
- return quic_bug_10511_43_error_detail_;
- }
-
- protected:
- // Calls cancel() on all the alarms owned by this connection.
- void CancelAllAlarms();
-
- // Send a packet to the peer, and takes ownership of the packet if the packet
- // cannot be written immediately.
- virtual void SendOrQueuePacket(SerializedPacket packet);
-
- // Called after a packet is received from a new effective peer address and is
- // decrypted. Starts validation of effective peer's address change. Calls
- // OnConnectionMigration as soon as the address changed.
- void StartEffectivePeerMigration(AddressChangeType type);
-
- // Called when a effective peer address migration is validated.
- virtual void OnEffectivePeerMigrationValidated();
-
- // Get the effective peer address from the packet being processed. For proxied
- // connections, effective peer address is the address of the endpoint behind
- // the proxy. For non-proxied connections, effective peer address is the same
- // as peer address.
- //
- // Notes for implementations in subclasses:
- // - If the connection is not proxied, the overridden method should use the
- // base implementation:
- //
- // return QuicConnection::GetEffectivePeerAddressFromCurrentPacket();
- //
- // - If the connection is proxied, the overridden method may return either of
- // the following:
- // a) The address of the endpoint behind the proxy. The address is used to
- // drive effective peer migration.
- // b) An uninitialized address, meaning the effective peer address does not
- // change.
- virtual QuicSocketAddress GetEffectivePeerAddressFromCurrentPacket() const;
-
- // Selects and updates the version of the protocol being used by selecting a
- // version from |available_versions| which is also supported. Returns true if
- // such a version exists, false otherwise.
- bool SelectMutualVersion(const ParsedQuicVersionVector& available_versions);
-
- // Returns the current per-packet options for the connection.
- PerPacketOptions* per_packet_options() { return per_packet_options_; }
-
- AddressChangeType active_effective_peer_migration_type() const {
- return active_effective_peer_migration_type_;
- }
-
- // Sends a connection close packet to the peer and includes an ACK if the ACK
- // is not empty, the |error| is not PACKET_WRITE_ERROR, and it fits.
- // |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.
- virtual void SendConnectionClosePacket(QuicErrorCode error,
- QuicIetfTransportErrorCodes ietf_error,
- const std::string& details);
-
- // 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();
-
- // Return whether the packet being processed is a connectivity probing.
- // A packet is a connectivity probing if it is a padded ping packet with self
- // and/or peer address changes.
- bool IsCurrentPacketConnectivityProbing() const;
-
- // Return true iff the writer is blocked, if blocked, call
- // visitor_->OnWriteBlocked() to add the connection into the write blocked
- // list.
- bool HandleWriteBlocked();
-
- // Whether connection enforces anti-amplification limit.
- bool EnforceAntiAmplificationLimit() const;
-
- void AddBytesReceivedBeforeAddressValidation(size_t length) {
- default_path_.bytes_received_before_address_validation += length;
- }
-
- void set_validate_client_addresses(bool value) {
- validate_client_addresses_ = value;
- }
-
- private:
- friend class test::QuicConnectionPeer;
-
- struct QUIC_EXPORT_PRIVATE PendingPathChallenge {
- QuicPathFrameBuffer received_path_challenge;
- QuicSocketAddress peer_address;
- };
-
- struct QUIC_EXPORT_PRIVATE PathState {
- PathState() = default;
-
- PathState(const QuicSocketAddress& alternative_self_address,
- const QuicSocketAddress& alternative_peer_address,
- const QuicConnectionId& client_connection_id,
- const QuicConnectionId& server_connection_id,
- absl::optional<StatelessResetToken> stateless_reset_token)
- : self_address(alternative_self_address),
- peer_address(alternative_peer_address),
- client_connection_id(client_connection_id),
- server_connection_id(server_connection_id),
- stateless_reset_token(stateless_reset_token) {}
-
- PathState(PathState&& other);
-
- PathState& operator=(PathState&& other);
-
- // Reset all the members.
- void Clear();
-
- QuicSocketAddress self_address;
- // The actual peer address behind the proxy if there is any.
- QuicSocketAddress peer_address;
- QuicConnectionId client_connection_id;
- QuicConnectionId server_connection_id;
- absl::optional<StatelessResetToken> stateless_reset_token;
- // True if the peer address has been validated. Address is considered
- // validated when 1) an address token of the peer address is received and
- // validated, or 2) a HANDSHAKE packet has been successfully processed on
- // this path, or 3) a path validation on this path has succeeded.
- bool validated = false;
- // Used by the sever to apply anti-amplification limit after this path
- // becomes the default path if |peer_address| hasn't been validated.
- QuicByteCount bytes_received_before_address_validation = 0;
- QuicByteCount bytes_sent_before_address_validation = 0;
- // Points to the send algorithm on the old default path while connection is
- // validating migrated peer address. Nullptr otherwise.
- std::unique_ptr<SendAlgorithmInterface> send_algorithm;
- absl::optional<RttStats> rtt_stats;
- };
-
- using QueuedPacketList = std::list<SerializedPacket>;
-
- // BufferedPacket stores necessary information (encrypted buffer and self/peer
- // addresses) of those packets which are serialized but failed to send because
- // socket is blocked. From unacked packet map and send algorithm's
- // perspective, buffered packets are treated as sent.
- struct QUIC_EXPORT_PRIVATE BufferedPacket {
- BufferedPacket(const SerializedPacket& packet,
- const QuicSocketAddress& self_address,
- const QuicSocketAddress& peer_address);
- BufferedPacket(char* encrypted_buffer,
- QuicPacketLength encrypted_length,
- const QuicSocketAddress& self_address,
- const QuicSocketAddress& peer_address);
- BufferedPacket(const BufferedPacket& other) = delete;
- BufferedPacket(const BufferedPacket&& other) = delete;
-
- ~BufferedPacket();
-
- // encrypted_buffer is owned by buffered packet.
- absl::string_view encrypted_buffer;
- // 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.
- struct QUIC_EXPORT_PRIVATE ReceivedPacketInfo {
- explicit ReceivedPacketInfo(QuicTime receipt_time)
- : received_bytes_counted(false), receipt_time(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) {}
-
- bool received_bytes_counted;
- QuicSocketAddress destination_address;
- QuicSocketAddress source_address;
- QuicTime receipt_time;
- };
-
- // UndecrytablePacket comprises a undecryptable packet and related
- // information.
- struct QUIC_EXPORT_PRIVATE UndecryptablePacket {
- UndecryptablePacket(const QuicEncryptedPacket& packet,
- EncryptionLevel encryption_level,
- const ReceivedPacketInfo& packet_info)
- : packet(packet.Clone()),
- encryption_level(encryption_level),
- packet_info(packet_info) {}
-
- std::unique_ptr<QuicEncryptedPacket> packet;
- EncryptionLevel encryption_level;
- ReceivedPacketInfo packet_info;
- };
-
- // Handles the reverse path validation result depending on connection state:
- // whether the connection is validating a migrated peer address or is
- // validating an alternative path.
- class ReversePathValidationResultDelegate
- : public QuicPathValidator::ResultDelegate {
- public:
- ReversePathValidationResultDelegate(
- QuicConnection* connection,
- const QuicSocketAddress& direct_peer_address);
-
- void OnPathValidationSuccess(
- std::unique_ptr<QuicPathValidationContext> context) override;
-
- void OnPathValidationFailure(
- std::unique_ptr<QuicPathValidationContext> context) override;
-
- private:
- QuicConnection* connection_;
- QuicSocketAddress original_direct_peer_address_;
- // TODO(b/205023946) Debug-only fields, to be deprecated after the bug is
- // fixed.
- QuicSocketAddress peer_address_default_path_;
- QuicSocketAddress peer_address_alternative_path_;
- AddressChangeType active_effective_peer_migration_type_;
- };
-
- // A class which sets and clears in_on_retransmission_time_out_ when entering
- // and exiting OnRetransmissionTimeout, respectively.
- class QUIC_EXPORT_PRIVATE ScopedRetransmissionTimeoutIndicator {
- public:
- // |connection| must outlive this indicator.
- explicit ScopedRetransmissionTimeoutIndicator(QuicConnection* connection);
-
- ~ScopedRetransmissionTimeoutIndicator();
-
- private:
- QuicConnection* connection_; // Not owned.
- };
-
- // If peer uses non-empty connection ID, discards any buffered packets on path
- // change in IETF QUIC.
- void MaybeClearQueuedPacketsOnPathChange();
-
- // Notifies the visitor of the close and marks the connection as disconnected.
- // Does not send a connection close frame to the peer. It should only be
- // called by CloseConnection or OnConnectionCloseFrame, OnPublicResetPacket,
- // and OnAuthenticatedIetfStatelessResetPacket.
- // |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.
- void TearDownLocalConnectionState(QuicErrorCode error,
- QuicIetfTransportErrorCodes ietf_error,
- const std::string& details,
- ConnectionCloseSource source);
- void TearDownLocalConnectionState(const QuicConnectionCloseFrame& frame,
- ConnectionCloseSource source);
-
- // Replace server connection ID on the client side from retry packet or
- // initial packets with a different source connection ID.
- void ReplaceInitialServerConnectionId(
- const QuicConnectionId& new_server_connection_id);
-
- // Given the server_connection_id find if there is already a corresponding
- // client connection ID used on default/alternative path. If not, find if
- // there is an unused connection ID.
- void FindMatchingOrNewClientConnectionIdOrToken(
- const PathState& default_path, const PathState& alternative_path,
- const QuicConnectionId& server_connection_id,
- QuicConnectionId* client_connection_id,
- absl::optional<StatelessResetToken>* stateless_reset_token);
-
- // Returns true and sets connection IDs if (self_address, peer_address)
- // corresponds to either the default path or alternative path. Returns false
- // otherwise.
- bool FindOnPathConnectionIds(const QuicSocketAddress& self_address,
- const QuicSocketAddress& peer_address,
- QuicConnectionId* client_connection_id,
- QuicConnectionId* server_connection_id) const;
-
- // Set default_path_ to the new_path_state and update the connection IDs in
- // packet creator accordingly.
- void SetDefaultPathState(PathState new_path_state);
-
- // Returns true if header contains valid server connection ID.
- bool ValidateServerConnectionId(const QuicPacketHeader& header) const;
-
- // Update the connection IDs when client migrates with/without validation.
- // Returns false if required connection ID is not available.
- bool UpdateConnectionIdsOnClientMigration(
- const QuicSocketAddress& self_address,
- const QuicSocketAddress& peer_address);
-
- // Retire active peer issued connection IDs after they are no longer used on
- // any path.
- void RetirePeerIssuedConnectionIdsNoLongerOnPath();
-
- // When path validation fails, proactively retire peer issued connection IDs
- // no longer used on any path.
- void RetirePeerIssuedConnectionIdsOnPathValidationFailure();
-
- // Writes the given packet to socket, encrypted with packet's
- // encryption_level. Returns true on successful write, and false if the writer
- // was blocked and the write needs to be tried again. Notifies the
- // SentPacketManager when the write is successful and sets
- // retransmittable frames to nullptr.
- // Saves the connection close packet for later transmission, even if the
- // writer is write blocked.
- bool WritePacket(SerializedPacket* packet);
-
- // Enforce AEAD Confidentiality limits by iniating key update or closing
- // connection if too many packets have been encrypted with the current key.
- // Returns true if the connection was closed. Should not be called for
- // termination packets.
- bool MaybeHandleAeadConfidentialityLimits(const SerializedPacket& packet);
-
- // Flush packets buffered in the writer, if any.
- void FlushPackets();
-
- // Make sure a stop waiting we got from our peer is sane.
- // Returns nullptr if the frame is valid or an error string if it was invalid.
- const char* ValidateStopWaitingFrame(
- const QuicStopWaitingFrame& stop_waiting);
-
- // Sends a version negotiation packet to the peer.
- void SendVersionNegotiationPacket(bool ietf_quic, bool has_length_prefix);
-
- // Clears any accumulated frames from the last received packet.
- void ClearLastFrames();
-
- // Deletes and clears any queued packets.
- void ClearQueuedPackets();
-
- // Closes the connection if the sent packet manager is tracking too many
- // outstanding packets.
- void CloseIfTooManyOutstandingSentPackets();
-
- // Writes as many queued packets as possible. The connection must not be
- // blocked when this is called.
- void WriteQueuedPackets();
-
- // Queues |packet| in the hopes that it can be decrypted in the
- // future, when a new key is installed.
- void QueueUndecryptablePacket(const QuicEncryptedPacket& packet,
- EncryptionLevel decryption_level);
-
- // Sends any packets which are a response to the last packet, including both
- // acks and pending writes if an ack opened the congestion window.
- void MaybeSendInResponseToPacket();
-
- // Gets the least unacked packet number, which is the next packet number to be
- // sent if there are no outstanding packets.
- QuicPacketNumber GetLeastUnacked() const;
-
- // Sets the ping alarm to the appropriate value, if any.
- void SetPingAlarm();
-
- // Sets the retransmission alarm based on SentPacketManager.
- void SetRetransmissionAlarm();
-
- // Sets the MTU discovery alarm if necessary.
- // |sent_packet_number| is the recently sent packet number.
- void MaybeSetMtuAlarm(QuicPacketNumber sent_packet_number);
-
- HasRetransmittableData IsRetransmittable(const SerializedPacket& packet);
- bool IsTerminationPacket(const SerializedPacket& packet,
- QuicErrorCode* error_code);
-
- // Set the size of the packet we are targeting while doing path MTU discovery.
- void SetMtuDiscoveryTarget(QuicByteCount target);
-
- // Returns |suggested_max_packet_size| clamped to any limits set by the
- // underlying writer, connection, or protocol.
- QuicByteCount GetLimitedMaxPacketSize(
- QuicByteCount suggested_max_packet_size);
-
- // Do any work which logically would be done in OnPacket but can not be
- // safely done until the packet is validated. Returns true if packet can be
- // handled, false otherwise.
- bool ProcessValidatedPacket(const QuicPacketHeader& header);
-
- // Returns true if received |packet_number| can be processed. Please note,
- // this is called after packet got decrypted successfully.
- bool ValidateReceivedPacketNumber(QuicPacketNumber packet_number);
-
- // Consider receiving crypto frame on non crypto stream as memory corruption.
- bool MaybeConsiderAsMemoryCorruption(const QuicStreamFrame& frame);
-
- // Check if the connection has no outstanding data to send and notify
- // congestion controller if it is the case.
- void CheckIfApplicationLimited();
-
- // Sets |current_packet_content_| to |type| if applicable. And
- // starts effective peer migration if current packet is confirmed not a
- // connectivity probe and |current_effective_peer_migration_type_| indicates
- // effective peer address change.
- // Returns true if connection is still alive.
- ABSL_MUST_USE_RESULT bool UpdatePacketContent(QuicFrameType type);
-
- // Called when last received ack frame has been processed.
- // |send_stop_waiting| indicates whether a stop waiting needs to be sent.
- // |acked_new_packet| is true if a previously-unacked packet was acked.
- void PostProcessAfterAckFrame(bool send_stop_waiting, bool acked_new_packet);
-
- // Updates the release time into the future.
- void UpdateReleaseTimeIntoFuture();
-
- // Sends generic path probe packet to the peer. If we are not IETF QUIC, will
- // always send a padded ping, regardless of whether this is a request or not.
- // TODO(danzh): remove |is_response| after deprecating
- // --gfe2_reloadable_flag_quic_send_path_response.
- bool SendGenericPathProbePacket(QuicPacketWriter* probing_writer,
- const QuicSocketAddress& peer_address,
- bool is_response);
-
- // Called when an ACK is about to send. Resets ACK related internal states,
- // e.g., cancels ack_alarm_, resets
- // num_retransmittable_packets_received_since_last_ack_sent_ etc.
- void ResetAckStates();
-
- // Returns true if the ACK frame should be bundled with ACK-eliciting frame.
- bool ShouldBundleRetransmittableFrameWithAck() const;
-
- void PopulateStopWaitingFrame(QuicStopWaitingFrame* stop_waiting);
-
- // Enables multiple packet number spaces support based on handshake protocol
- // and flags.
- void MaybeEnableMultiplePacketNumberSpacesSupport();
-
- // Called to update ACK timeout when an retransmittable frame has been parsed.
- void MaybeUpdateAckTimeout();
-
- // Tries to fill coalesced packet with data of higher packet space.
- void MaybeCoalescePacketOfHigherSpace();
-
- // Serialize and send coalesced_packet. Returns false if serialization fails
- // or the write causes errors, otherwise, returns true.
- bool FlushCoalescedPacket();
-
- // Returns the encryption level the connection close packet should be sent at,
- // which is the highest encryption level that peer can guarantee to process.
- EncryptionLevel GetConnectionCloseEncryptionLevel() const;
-
- // Called after an ACK frame is successfully processed to update largest
- // received packet number which contains an ACK frame.
- void SetLargestReceivedPacketWithAck(QuicPacketNumber new_value);
-
- // Called when new packets have been acknowledged or old keys have been
- // discarded.
- void OnForwardProgressMade();
-
- // Returns largest received packet number which contains an ACK frame.
- QuicPacketNumber GetLargestReceivedPacketWithAck() const;
-
- // Returns the largest packet number that has been sent.
- QuicPacketNumber GetLargestSentPacket() const;
-
- // Returns the largest sent packet number that has been ACKed by peer.
- QuicPacketNumber GetLargestAckedPacket() const;
-
- // Whether connection is limited by amplification factor.
- bool LimitedByAmplificationFactor() const;
-
- // Called before sending a packet to get packet send time and to set the
- // release time delay in |per_packet_options_|. Return the time when the
- // packet is scheduled to be released(a.k.a send time), which is NOW + delay.
- // Returns Now() and does not update release time delay if
- // |supports_release_time_| is false.
- QuicTime CalculatePacketSentTime();
-
- // If we have a previously validate MTU value, e.g. due to a write error,
- // revert to it and disable MTU discovery.
- // Return true iff we reverted to a previously validate MTU.
- bool MaybeRevertToPreviousMtu();
-
- QuicTime GetPathMtuReductionDeadline() const;
-
- // Returns path degrading deadline. QuicTime::Zero() means no path degrading
- // detection is needed.
- QuicTime GetPathDegradingDeadline() const;
-
- // Returns true if path degrading should be detected.
- bool ShouldDetectPathDegrading() const;
-
- // Returns network blackhole deadline. QuicTime::Zero() means no blackhole
- // detection is needed.
- QuicTime GetNetworkBlackholeDeadline() const;
-
- // Returns true if network blackhole should be detected.
- bool ShouldDetectBlackhole() const;
-
- // Returns retransmission deadline.
- QuicTime GetRetransmissionDeadline() const;
-
- // Validate connection IDs used during the handshake. Closes the connection
- // on validation failure.
- bool ValidateConfigConnectionIds(const QuicConfig& config);
-
- // Called when ACK alarm goes off. Try to bundle crypto data with ACKs.
- void MaybeBundleCryptoDataWithAcks();
-
- // Returns true if an undecryptable packet of |decryption_level| should be
- // buffered (such that connection can try to decrypt it later).
- bool ShouldEnqueueUnDecryptablePacket(EncryptionLevel decryption_level,
- bool has_decryption_key) const;
-
- // Returns string which contains undecryptable packets information.
- std::string UndecryptablePacketsInfo() const;
-
- // Sets the max packet length on the packet creator if needed.
- void MaybeUpdatePacketCreatorMaxPacketLengthAndPadding();
-
- // Sets internal state to enable or disable Legacy Version Encapsulation.
- void MaybeActivateLegacyVersionEncapsulation();
- void MaybeDisactivateLegacyVersionEncapsulation();
-
- // For Google Quic, if the current packet is connectivity probing packet, call
- // session OnPacketReceived() which eventually sends connectivity probing
- // response on server side. And no-op on client side. And for both Google Quic
- // and IETF Quic, start migration if the current packet is a non-probing
- // packet.
- // TODO(danzh) rename to MaybeRespondToPeerMigration() when Google Quic is
- // deprecated.
- void MaybeRespondToConnectivityProbingOrMigration();
-
- // Called in IETF QUIC. Start peer migration if a non-probing frame is
- // received and the current packet number is largest received so far.
- void MaybeStartIetfPeerMigration();
-
- // Send PATH_RESPONSE to the given peer address.
- bool SendPathResponse(const QuicPathFrameBuffer& data_buffer,
- const QuicSocketAddress& peer_address_to_send,
- const QuicSocketAddress& effective_peer_address);
-
- // Update both connection's and packet creator's peer address.
- void UpdatePeerAddress(QuicSocketAddress peer_address);
-
- // Send PING at encryption level.
- void SendPingAtLevel(EncryptionLevel level);
-
- // Write the given packet with |self_address| and |peer_address| using
- // |writer|.
- bool WritePacketUsingWriter(std::unique_ptr<SerializedPacket> packet,
- QuicPacketWriter* writer,
- const QuicSocketAddress& self_address,
- const QuicSocketAddress& peer_address,
- bool measure_rtt);
-
- // Increment bytes sent/received on the alternative path if the current packet
- // is sent/received on that path.
- void MaybeUpdateBytesSentToAlternativeAddress(
- const QuicSocketAddress& peer_address,
- QuicByteCount sent_packet_size);
- void MaybeUpdateBytesReceivedFromAlternativeAddress(
- QuicByteCount received_packet_size);
-
- // TODO(danzh) pass in PathState of the incoming packet or the packet sent
- // once PathState is used in packet creator. Return true if the given self
- // address and peer address is the same as the self address and peer address
- // of the default path.
- bool IsDefaultPath(const QuicSocketAddress& self_address,
- const QuicSocketAddress& peer_address) const;
-
- // Return true if the |self_address| and |peer_address| is the same as the
- // self address and peer address of the alternative path.
- bool IsAlternativePath(const QuicSocketAddress& self_address,
- const QuicSocketAddress& peer_address) const;
-
- // Restore connection default path and congestion control state to the last
- // validated path and its state. Called after fail to validate peer address
- // upon detecting a peer migration.
- void RestoreToLastValidatedPath(
- QuicSocketAddress original_direct_peer_address);
-
- // Return true if the current incoming packet is from a peer address that is
- // validated.
- bool IsReceivedPeerAddressValidated() const;
-
- // Called after receiving PATH_CHALLENGE. Update packet content and
- // alternative path state if the current packet is from a non-default path.
- // Return true if framer should continue processing the packet.
- bool OnPathChallengeFrameInternal(const QuicPathChallengeFrame& frame);
-
- virtual std::unique_ptr<QuicSelfIssuedConnectionIdManager>
- MakeSelfIssuedConnectionIdManager();
-
- // Called on peer IP change or restoring to previous address to reset
- // congestion window, RTT stats, retransmission timer, etc. Only used in IETF
- // QUIC.
- std::unique_ptr<SendAlgorithmInterface> OnPeerIpAddressChanged();
-
- // Process NewConnectionIdFrame either sent from peer or synsthesized from
- // preferred_address transport parameter.
- bool OnNewConnectionIdFrameInner(const QuicNewConnectionIdFrame& frame);
-
- // Called to patch missing client connection ID on default/alternative paths
- // 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;
-
- QuicConnectionContext context_;
-
- QuicFramer framer_;
-
- // Contents received in the current packet, especially used to identify
- // whether the current packet is a padded PING packet.
- PacketContent current_packet_content_;
- // Set to true as soon as the packet currently being processed has been
- // detected as a connectivity probing.
- // Always false outside the context of ProcessUdpPacket().
- bool is_current_packet_connectivity_probing_;
-
- bool has_path_challenge_in_current_packet_;
-
- // Caches the current effective peer migration type if a effective peer
- // migration might be initiated. As soon as the current packet is confirmed
- // not a connectivity probe, effective peer migration will start.
- AddressChangeType current_effective_peer_migration_type_;
- QuicConnectionHelperInterface* helper_; // Not owned.
- QuicAlarmFactory* alarm_factory_; // Not owned.
- PerPacketOptions* per_packet_options_; // Not owned.
- QuicPacketWriter* writer_; // Owned or not depending on |owns_writer_|.
- bool owns_writer_;
- // Encryption level for new packets. Should only be changed via
- // SetDefaultEncryptionLevel().
- EncryptionLevel encryption_level_;
- const QuicClock* clock_;
- QuicRandom* random_generator_;
-
- // On the server, the connection ID is set when receiving the first packet.
- // This variable ensures we only set it this way once.
- bool client_connection_id_is_set_;
-
- // Whether we've already replaced our server connection ID due to receiving an
- // INITIAL packet with a different source connection ID. Only used on client.
- bool server_connection_id_replaced_by_initial_ = false;
- // Address on the last successfully processed packet received from the
- // direct peer.
-
- // Other than initialization, do not modify it directly, use
- // UpdatePeerAddress() instead.
- QuicSocketAddress direct_peer_address_;
- // The default path on which the endpoint sends non-probing packets.
- // The send algorithm and RTT stats of this path are stored in
- // |sent_packet_manager_| instead of in this object.
- PathState default_path_;
-
- // Records change type when the effective peer initiates migration to a new
- // address. Reset to NO_CHANGE after effective peer migration is validated.
- AddressChangeType active_effective_peer_migration_type_;
-
- // Records highest sent packet number when effective peer migration is
- // started.
- QuicPacketNumber highest_packet_sent_before_effective_peer_migration_;
-
- // True if Key Update is supported on this connection.
- bool support_key_update_for_connection_;
-
- // Tracks the lowest packet sent in the current key phase. Will be
- // uninitialized before the first one-RTT packet has been sent or after a
- // key update but before the first packet has been sent.
- QuicPacketNumber lowest_packet_sent_in_current_key_phase_;
-
- // 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
- // Largest sequence sent by the peer which had an ack frame (latest ack info).
- // Do not read or write directly, use GetLargestReceivedPacketWithAck() and
- // SetLargestReceivedPacketWithAck() instead.
- QuicPacketNumber largest_seen_packet_with_ack_;
- // Largest packet number sent by the peer which had an ACK frame per packet
- // number space. Only used when this connection supports multiple packet
- // number spaces.
- QuicPacketNumber largest_seen_packets_with_ack_[NUM_PACKET_NUMBER_SPACES];
-
- // Largest packet number sent by the peer which had a stop waiting frame.
- QuicPacketNumber largest_seen_packet_with_stop_waiting_;
-
- // Collection of packets which were received before encryption was
- // established, but which could not be decrypted. We buffer these on
- // the assumption that they could not be processed because they were
- // sent with the INITIAL encryption and the CHLO message was lost.
- std::deque<UndecryptablePacket> undecryptable_packets_;
-
- // Collection of coalesced packets which were received while processing
- // the current packet.
- quiche::QuicheCircularDeque<std::unique_ptr<QuicEncryptedPacket>>
- received_coalesced_packets_;
-
- // Maximum number of undecryptable packets the connection will store.
- size_t max_undecryptable_packets_;
-
- // Maximum number of tracked packets.
- QuicPacketCount max_tracked_packets_;
-
- // Contains the connection close packets if the connection has been closed.
- std::unique_ptr<std::vector<std::unique_ptr<QuicEncryptedPacket>>>
- termination_packets_;
-
- // Determines whether or not a connection close packet is sent to the peer
- // after idle timeout due to lack of network activity. During the handshake,
- // a connection close packet is sent, but not after.
- ConnectionCloseBehavior idle_timeout_connection_close_behavior_;
-
- // When > 0, close the QUIC connection after this number of RTOs.
- size_t num_rtos_for_blackhole_detection_;
-
- // Statistics for this session.
- QuicConnectionStats stats_;
-
- UberReceivedPacketManager uber_received_packet_manager_;
-
- // Indicates how many consecutive times an ack has arrived which indicates
- // the peer needs to stop waiting for some packets.
- // TODO(fayang): remove this when deprecating Q043.
- int stop_waiting_count_;
-
- // Indicates the retransmission alarm needs to be set.
- bool pending_retransmission_alarm_;
-
- // If true, defer sending data in response to received packets to the
- // SendAlarm.
- bool defer_send_in_response_to_packets_;
-
- // The timeout for PING.
- QuicTime::Delta ping_timeout_;
-
- // Initial timeout for how long the wire can have no retransmittable packets.
- QuicTime::Delta initial_retransmittable_on_wire_timeout_;
-
- // Indicates how many retransmittable-on-wire pings have been emitted without
- // receiving any new data in between.
- int consecutive_retransmittable_on_wire_ping_count_;
-
- // Indicates how many retransmittable-on-wire pings have been emitted.
- int retransmittable_on_wire_ping_count_;
-
- // Arena to store class implementations within the QuicConnection.
- QuicConnectionArena arena_;
-
- // An alarm that fires when an ACK should be sent to the peer.
- QuicArenaScopedPtr<QuicAlarm> ack_alarm_;
- // An alarm that fires when a packet needs to be retransmitted.
- QuicArenaScopedPtr<QuicAlarm> retransmission_alarm_;
- // 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_;
- // 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.
- QuicArenaScopedPtr<QuicAlarm> mtu_discovery_alarm_;
- // An alarm that fires to process undecryptable packets when new decyrption
- // keys are available.
- QuicArenaScopedPtr<QuicAlarm> process_undecryptable_packets_alarm_;
- // An alarm that fires to discard keys for the previous key phase some time
- // after a key update has completed.
- QuicArenaScopedPtr<QuicAlarm> discard_previous_one_rtt_keys_alarm_;
- // An alarm that fires to discard 0-RTT decryption keys some time after the
- // first 1-RTT packet has been decrypted. Only used on server connections with
- // TLS handshaker.
- QuicArenaScopedPtr<QuicAlarm> discard_zero_rtt_decryption_keys_alarm_;
- // Neither visitor is owned by this class.
- QuicConnectionVisitorInterface* visitor_;
- QuicConnectionDebugVisitor* debug_visitor_;
-
- QuicPacketCreator packet_creator_;
-
- // Information about the last received QUIC packet, which may not have been
- // successfully decrypted and processed.
- ReceivedPacketInfo last_received_packet_info_;
-
- // Sent packet manager which tracks the status of packets sent by this
- // connection and contains the send and receive algorithms to determine when
- // to send packets.
- QuicSentPacketManager sent_packet_manager_;
-
- // Indicates whether connection version has been negotiated.
- // Always true for server connections.
- bool version_negotiated_;
-
- // Tracks if the connection was created by the server or the client.
- Perspective perspective_;
-
- // True by default. False if we've received or sent an explicit connection
- // 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_;
-
- // If non-empty this contains the set of versions received in a
- // version negotiation packet.
- ParsedQuicVersionVector server_supported_versions_;
-
- // The number of MTU probes already sent.
- size_t mtu_probe_count_;
-
- // The value of |long_term_mtu_| prior to the last successful MTU increase.
- // 0 means either
- // - MTU discovery has never been enabled, or
- // - MTU discovery has been enabled, but the connection got a packet write
- // error with a new (successfully probed) MTU, so it reverted
- // |long_term_mtu_| to the value before the last increase.
- QuicPacketLength previous_validated_mtu_;
- // The value of the MTU regularly used by the connection. This is different
- // from the value returned by max_packet_size(), as max_packet_size() returns
- // the value of the MTU as currently used by the serializer, so if
- // serialization of an MTU probe is in progress, those two values will be
- // different.
- QuicByteCount long_term_mtu_;
-
- // The maximum UDP payload size that our peer has advertised support for.
- // Defaults to kDefaultMaxPacketSizeTransportParam until received from peer.
- QuicByteCount peer_max_packet_size_;
-
- // The size of the largest packet received from peer.
- QuicByteCount largest_received_packet_size_;
-
- // Indicates whether a write error is encountered currently. This is used to
- // avoid infinite write errors.
- bool write_error_occurred_;
-
- // Indicates not to send or process stop waiting frames.
- bool no_stop_waiting_frames_;
-
- // Consecutive number of sent packets which have no retransmittable frames.
- size_t consecutive_num_packets_with_no_retransmittable_frames_;
-
- // After this many packets sent without retransmittable frames, an artificial
- // retransmittable frame(a WINDOW_UPDATE) will be created to solicit an ack
- // 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.
- 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_;
-
- // True if the peer is unreachable on the current path.
- bool is_path_degrading_;
-
- // True if an ack frame is being processed.
- bool processing_ack_frame_;
-
- // True if the writer supports release timestamp.
- bool supports_release_time_;
-
- std::unique_ptr<QuicPeerIssuedConnectionIdManager> peer_issued_cid_manager_;
- std::unique_ptr<QuicSelfIssuedConnectionIdManager> self_issued_cid_manager_;
-
- // Time this connection can release packets into the future.
- QuicTime::Delta release_time_into_future_;
-
- // Payload of most recently transmitted IETF QUIC connectivity
- // probe packet (the PATH_CHALLENGE payload). This implementation transmits
- // only one PATH_CHALLENGE per connectivity probe, so only one
- // QuicPathFrameBuffer is needed.
- std::unique_ptr<QuicPathFrameBuffer> transmitted_connectivity_probe_payload_;
-
- // Payloads that were received in the most recent probe. This needs to be a
- // Deque because the peer might no be using this implementation, and others
- // might send a packet with more than one PATH_CHALLENGE, so all need to be
- // saved and responded to.
- // TODO(danzh) deprecate this field when deprecating
- // --quic_send_path_response.
- quiche::QuicheCircularDeque<QuicPathFrameBuffer>
- received_path_challenge_payloads_;
-
- // When we receive a RETRY packet or some INITIAL packets, we replace
- // |server_connection_id_| with the value from that packet and save off the
- // original value of |server_connection_id_| into
- // |original_destination_connection_id_| for validation.
- absl::optional<QuicConnectionId> original_destination_connection_id_;
-
- // The connection ID that replaces original_destination_connection_id_.
- QuicConnectionId original_destination_connection_id_replacement_;
-
- // After we receive a RETRY packet, |retry_source_connection_id_| contains
- // the source connection ID from that packet.
- absl::optional<QuicConnectionId> retry_source_connection_id_;
-
- // Used to store content of packets which cannot be sent because of write
- // blocked. Packets' encrypted buffers are copied and owned by
- // buffered_packets_. From unacked_packet_map (and congestion control)'s
- // perspective, those packets are considered sent.
- std::list<BufferedPacket> buffered_packets_;
-
- // Used to coalesce packets of different encryption level into the same UDP
- // datagram. Connection stops trying to coalesce packets if a forward secure
- // packet gets acknowledged.
- QuicCoalescedPacket coalesced_packet_;
-
- QuicConnectionMtuDiscoverer mtu_discoverer_;
-
- QuicNetworkBlackholeDetector blackhole_detector_;
-
- QuicIdleNetworkDetector idle_network_detector_;
-
- bool blackhole_detection_disabled_ = false;
-
- const bool default_enable_5rto_blackhole_detection_ =
- GetQuicReloadableFlag(quic_default_enable_5rto_blackhole_detection2);
-
- // Whether the Legacy Version Encapsulation feature is enabled.
- bool legacy_version_encapsulation_enabled_ = false;
- // Whether we are in the middle of sending a packet using Legacy Version
- // Encapsulation.
- bool legacy_version_encapsulation_in_progress_ = false;
- // SNI to send when using Legacy Version Encapsulation.
- std::string legacy_version_encapsulation_sni_;
- // True if next packet is intended to consume remaining space in the
- // coalescer.
- bool fill_coalesced_packet_ = false;
-
- size_t anti_amplification_factor_ =
- GetQuicFlag(FLAGS_quic_anti_amplification_factor);
-
- // latch --gfe2_reloadable_flag_quic_send_path_response.
- bool send_path_response_ = GetQuicReloadableFlag(quic_send_path_response2);
-
- bool use_path_validator_ =
- send_path_response_ &&
- GetQuicReloadableFlag(quic_pass_path_response_to_validator);
-
- // True if AckFrequencyFrame is supported.
- bool can_receive_ack_frequency_frame_ = false;
-
- // Indicate whether coalescing is done.
- bool coalescing_done_ = false;
-
- // Indicate whether any ENCRYPTION_HANDSHAKE packet has been sent.
- bool handshake_packet_sent_ = false;
-
- // Indicate whether to send an AckFrequencyFrame upon handshake completion.
- // The AckFrequencyFrame sent will updates client's max_ack_delay, which if
- // chosen properly can reduce the CPU and bandwidth usage for ACK frames.
- bool send_ack_frequency_on_handshake_completion_ = false;
-
- // Indicate whether AckFrequency frame has been sent.
- bool ack_frequency_sent_ = false;
-
- // True if a 0-RTT decrypter was or is installed at some point in the
- // connection's lifetime.
- bool had_zero_rtt_decrypter_ = false;
-
- // True after the first 1-RTT packet has successfully decrypted.
- bool have_decrypted_first_one_rtt_packet_ = false;
-
- // True if we are currently processing OnRetransmissionTimeout.
- bool in_on_retransmission_time_out_ = false;
-
- QuicPathValidator path_validator_;
-
- // Stores information of a path which maybe used as default path in the
- // future. On the client side, it gets created when the client starts
- // validating a new path and gets cleared once it becomes the default path or
- // the path validation fails or replaced by a newer path of interest. On the
- // server side, alternative_path gets created when server: 1) receives
- // PATH_CHALLENGE on non-default path, or 2) switches to a not yet validated
- // default path such that it needs to store the previous validated default
- // path.
- // Note that if alternative_path_ stores a validated path information (case
- // 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;
-
- // Indicates whether we should proactively validate peer address on a
- // PATH_CHALLENGE received.
- bool should_proactively_validate_peer_address_on_path_challenge_ = false;
-
- // Enable this via reloadable flag once this feature is complete.
- bool connection_migration_use_new_cid_ = false;
-
- const bool reset_per_packet_state_for_undecryptable_packets_ =
- GetQuicReloadableFlag(
- quic_reset_per_packet_state_for_undecryptable_packets);
-
- // 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_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_QUIC_CONNECTION_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_connection_context.cc b/chromium/net/third_party/quiche/src/quic/core/quic_connection_context.cc
deleted file mode 100644
index e77fc431289..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_connection_context.cc
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 2021 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 "quic/core/quic_connection_context.h"
-
-#include "common/platform/api/quiche_thread_local.h"
-
-namespace quic {
-namespace {
-DEFINE_QUICHE_THREAD_LOCAL_POINTER(CurrentContext, QuicConnectionContext);
-} // namespace
-
-// static
-QuicConnectionContext* QuicConnectionContext::Current() {
- return GET_QUICHE_THREAD_LOCAL_POINTER(CurrentContext);
-}
-
-QuicConnectionContextSwitcher::QuicConnectionContextSwitcher(
- QuicConnectionContext* new_context)
- : old_context_(QuicConnectionContext::Current()) {
- SET_QUICHE_THREAD_LOCAL_POINTER(CurrentContext, new_context);
- if (new_context && new_context->tracer) {
- new_context->tracer->Activate();
- }
-}
-
-QuicConnectionContextSwitcher::~QuicConnectionContextSwitcher() {
- QuicConnectionContext* current = QuicConnectionContext::Current();
- if (current && current->tracer) {
- current->tracer->Deactivate();
- }
- SET_QUICHE_THREAD_LOCAL_POINTER(CurrentContext, old_context_);
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_connection_context.h b/chromium/net/third_party/quiche/src/quic/core/quic_connection_context.h
deleted file mode 100644
index a1d76e334b9..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_connection_context.h
+++ /dev/null
@@ -1,133 +0,0 @@
-// Copyright 2021 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_CONNECTION_CONTEXT_H_
-#define QUICHE_QUIC_CORE_QUIC_CONNECTION_CONTEXT_H_
-
-#include "absl/strings/str_format.h"
-#include "absl/strings/string_view.h"
-#include "quic/platform/api/quic_export.h"
-#include "common/platform/api/quiche_logging.h"
-
-namespace quic {
-
-// QuicConnectionTracer is responsible for emit trace messages for a single
-// QuicConnection.
-// QuicConnectionTracer is part of the QuicConnectionContext.
-class QUIC_EXPORT_PRIVATE QuicConnectionTracer {
- public:
- virtual ~QuicConnectionTracer() = default;
-
- // Emit a trace message from a string literal. The trace may simply remember
- // the address of the literal in this function and read it at a later time.
- virtual void PrintLiteral(const char* literal) = 0;
-
- // Emit a trace message from a string_view. Unlike PrintLiteral, this function
- // will not read |s| after it returns.
- virtual void PrintString(absl::string_view s) = 0;
-
- // Emit a trace message from printf-style arguments.
- template <typename... Args>
- void Printf(const absl::FormatSpec<Args...>& format, const Args&... args) {
- std::string s = absl::StrFormat(format, args...);
- PrintString(s);
- }
-
- private:
- friend class QuicConnectionContextSwitcher;
-
- // Called by QuicConnectionContextSwitcher, when |this| becomes the current
- // thread's QUIC connection tracer.
- //
- // Activate/Deactivate are only called by QuicConnectionContextSwitcher's
- // constructor/destructor, they always come in pairs.
- virtual void Activate() {}
-
- // Called by QuicConnectionContextSwitcher, when |this| stops from being the
- // current thread's QUIC connection tracer.
- //
- // Activate/Deactivate are only called by QuicConnectionContextSwitcher's
- // constructor/destructor, they always come in pairs.
- virtual void Deactivate() {}
-};
-
-// QuicBugListener is a helper class for implementing QUIC_BUG. The QUIC_BUG
-// implementation can send the bug information into quic::CurrentBugListener().
-class QUIC_EXPORT_PRIVATE QuicBugListener {
- public:
- virtual ~QuicBugListener() = default;
- virtual void OnQuicBug(const char* bug_id, const char* file, int line,
- absl::string_view bug_message) = 0;
-};
-
-// QuicConnectionContext is a per-QuicConnection context that includes
-// facilities useable by any part of a QuicConnection. A QuicConnectionContext
-// is owned by a QuicConnection.
-//
-// The 'top-level' QuicConnection functions are responsible for maintaining the
-// thread-local QuicConnectionContext pointer, such that any function called by
-// them(directly or indirectly) can access the context.
-//
-// Like QuicConnection, all facilities in QuicConnectionContext are assumed to
-// be called from a single thread at a time, they are NOT thread-safe.
-struct QUIC_EXPORT_PRIVATE QuicConnectionContext final {
- // Get the context on the current executing thread. nullptr if the current
- // function is not called from a 'top-level' QuicConnection function.
- static QuicConnectionContext* Current();
-
- std::unique_ptr<QuicConnectionTracer> tracer;
- std::unique_ptr<QuicBugListener> bug_listener;
-};
-
-// QuicConnectionContextSwitcher is a RAII object used for maintaining the
-// thread-local QuicConnectionContext pointer.
-class QUIC_EXPORT_PRIVATE QuicConnectionContextSwitcher final {
- public:
- // The constructor switches from QuicConnectionContext::Current() to
- // |new_context|.
- explicit QuicConnectionContextSwitcher(QuicConnectionContext* new_context);
-
- // The destructor switches from QuicConnectionContext::Current() back to the
- // old context.
- ~QuicConnectionContextSwitcher();
-
- private:
- QuicConnectionContext* old_context_;
-};
-
-// Emit a trace message from a string literal to the current tracer(if any).
-inline void QUIC_TRACELITERAL(const char* literal) {
- QuicConnectionContext* current = QuicConnectionContext::Current();
- if (current && current->tracer) {
- current->tracer->PrintLiteral(literal);
- }
-}
-
-// Emit a trace message from a string_view to the current tracer(if any).
-inline void QUIC_TRACESTRING(absl::string_view s) {
- QuicConnectionContext* current = QuicConnectionContext::Current();
- if (current && current->tracer) {
- current->tracer->PrintString(s);
- }
-}
-
-// Emit a trace message from printf-style arguments to the current tracer(if
-// any).
-template <typename... Args>
-void QUIC_TRACEPRINTF(const absl::FormatSpec<Args...>& format,
- const Args&... args) {
- QuicConnectionContext* current = QuicConnectionContext::Current();
- if (current && current->tracer) {
- current->tracer->Printf(format, args...);
- }
-}
-
-inline QuicBugListener* CurrentBugListener() {
- QuicConnectionContext* current = QuicConnectionContext::Current();
- return (current != nullptr) ? current->bug_listener.get() : nullptr;
-}
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_QUIC_CONNECTION_CONTEXT_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_connection_context_test.cc b/chromium/net/third_party/quiche/src/quic/core/quic_connection_context_test.cc
deleted file mode 100644
index 0f5b2c481b6..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_connection_context_test.cc
+++ /dev/null
@@ -1,173 +0,0 @@
-// Copyright 2021 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 "quic/core/quic_connection_context.h"
-
-#include "quic/platform/api/quic_test.h"
-#include "quic/platform/api/quic_thread.h"
-
-using testing::ElementsAre;
-
-namespace quic {
-namespace {
-
-class TraceCollector : public QuicConnectionTracer {
- public:
- ~TraceCollector() override = default;
-
- void PrintLiteral(const char* literal) override { trace_.push_back(literal); }
-
- void PrintString(absl::string_view s) override {
- trace_.push_back(std::string(s));
- }
-
- const std::vector<std::string>& trace() const { return trace_; }
-
- private:
- std::vector<std::string> trace_;
-};
-
-struct FakeConnection {
- FakeConnection() { context.tracer = std::make_unique<TraceCollector>(); }
-
- const std::vector<std::string>& trace() const {
- return static_cast<const TraceCollector*>(context.tracer.get())->trace();
- }
-
- QuicConnectionContext context;
-};
-
-void SimpleSwitch() {
- FakeConnection connection;
-
- // These should be ignored since current context is nullptr.
- EXPECT_EQ(QuicConnectionContext::Current(), nullptr);
- QUIC_TRACELITERAL("before switch: literal");
- QUIC_TRACESTRING(std::string("before switch: string"));
- QUIC_TRACEPRINTF("%s: %s", "before switch", "printf");
-
- {
- QuicConnectionContextSwitcher switcher(&connection.context);
- QUIC_TRACELITERAL("literal");
- QUIC_TRACESTRING(std::string("string"));
- QUIC_TRACEPRINTF("%s", "printf");
- }
-
- EXPECT_EQ(QuicConnectionContext::Current(), nullptr);
- QUIC_TRACELITERAL("after switch: literal");
- QUIC_TRACESTRING(std::string("after switch: string"));
- QUIC_TRACEPRINTF("%s: %s", "after switch", "printf");
-
- EXPECT_THAT(connection.trace(), ElementsAre("literal", "string", "printf"));
-}
-
-void NestedSwitch() {
- FakeConnection outer, inner;
-
- {
- QuicConnectionContextSwitcher switcher(&outer.context);
- QUIC_TRACELITERAL("outer literal 0");
- QUIC_TRACESTRING(std::string("outer string 0"));
- QUIC_TRACEPRINTF("%s %s %d", "outer", "printf", 0);
-
- {
- QuicConnectionContextSwitcher switcher(&inner.context);
- QUIC_TRACELITERAL("inner literal");
- QUIC_TRACESTRING(std::string("inner string"));
- QUIC_TRACEPRINTF("%s %s", "inner", "printf");
- }
-
- QUIC_TRACELITERAL("outer literal 1");
- QUIC_TRACESTRING(std::string("outer string 1"));
- QUIC_TRACEPRINTF("%s %s %d", "outer", "printf", 1);
- }
-
- EXPECT_THAT(outer.trace(), ElementsAre("outer literal 0", "outer string 0",
- "outer printf 0", "outer literal 1",
- "outer string 1", "outer printf 1"));
-
- EXPECT_THAT(inner.trace(),
- ElementsAre("inner literal", "inner string", "inner printf"));
-}
-
-void AlternatingSwitch() {
- FakeConnection zero, one, two;
- for (int i = 0; i < 15; ++i) {
- FakeConnection* connection =
- ((i % 3) == 0) ? &zero : (((i % 3) == 1) ? &one : &two);
-
- QuicConnectionContextSwitcher switcher(&connection->context);
- QUIC_TRACEPRINTF("%d", i);
- }
-
- EXPECT_THAT(zero.trace(), ElementsAre("0", "3", "6", "9", "12"));
- EXPECT_THAT(one.trace(), ElementsAre("1", "4", "7", "10", "13"));
- EXPECT_THAT(two.trace(), ElementsAre("2", "5", "8", "11", "14"));
-}
-
-typedef void (*ThreadFunction)();
-
-template <ThreadFunction func>
-class TestThread : public QuicThread {
- public:
- TestThread() : QuicThread("TestThread") {}
- ~TestThread() override = default;
-
- protected:
- void Run() override { func(); }
-};
-
-template <ThreadFunction func>
-void RunInThreads(size_t n_threads) {
- using ThreadType = TestThread<func>;
- std::vector<ThreadType> threads(n_threads);
-
- for (ThreadType& t : threads) {
- t.Start();
- }
-
- for (ThreadType& t : threads) {
- t.Join();
- }
-}
-
-class QuicConnectionContextTest : public QuicTest {
- protected:
-};
-
-TEST_F(QuicConnectionContextTest, NullTracerOK) {
- FakeConnection connection;
- std::unique_ptr<QuicConnectionTracer> tracer;
-
- {
- QuicConnectionContextSwitcher switcher(&connection.context);
- QUIC_TRACELITERAL("msg 1 recorded");
- }
-
- connection.context.tracer.swap(tracer);
-
- {
- QuicConnectionContextSwitcher switcher(&connection.context);
- // Should be a no-op since connection.context.tracer is nullptr.
- QUIC_TRACELITERAL("msg 2 ignored");
- }
-
- EXPECT_THAT(static_cast<TraceCollector*>(tracer.get())->trace(),
- ElementsAre("msg 1 recorded"));
-}
-
-TEST_F(QuicConnectionContextTest, TestSimpleSwitch) {
- RunInThreads<SimpleSwitch>(10);
-}
-
-TEST_F(QuicConnectionContextTest, TestNestedSwitch) {
- RunInThreads<NestedSwitch>(10);
-}
-
-TEST_F(QuicConnectionContextTest, TestAlternatingSwitch) {
- RunInThreads<AlternatingSwitch>(10);
-}
-
-} // namespace
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_connection_id.cc b/chromium/net/third_party/quiche/src/quic/core/quic_connection_id.cc
deleted file mode 100644
index a8cb4c0f377..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_connection_id.cc
+++ /dev/null
@@ -1,182 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_connection_id.h"
-
-#include <cstddef>
-#include <cstdint>
-#include <cstring>
-#include <iomanip>
-#include <string>
-
-#include "absl/strings/escaping.h"
-#include "third_party/boringssl/src/include/openssl/siphash.h"
-#include "quic/core/crypto/quic_random.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_flag_utils.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-#include "common/quiche_endian.h"
-
-namespace quic {
-
-namespace {
-
-// QuicConnectionIdHasher can be used to generate a stable connection ID hash
-// function that will return the same value for two equal connection IDs for
-// the duration of process lifetime. It is meant to be used as input to data
-// structures that do not outlast process lifetime. A new key is generated once
-// per process to prevent attackers from crafting connection IDs in such a way
-// that they always land in the same hash bucket.
-class QuicConnectionIdHasher {
- public:
- inline QuicConnectionIdHasher()
- : QuicConnectionIdHasher(QuicRandom::GetInstance()) {}
-
- explicit inline QuicConnectionIdHasher(QuicRandom* random) {
- random->RandBytes(&sip_hash_key_, sizeof(sip_hash_key_));
- }
-
- inline size_t Hash(const char* input, size_t input_len) const {
- return static_cast<size_t>(SIPHASH_24(
- sip_hash_key_, reinterpret_cast<const uint8_t*>(input), input_len));
- }
-
- private:
- uint64_t sip_hash_key_[2];
-};
-
-} // namespace
-
-QuicConnectionId::QuicConnectionId() : QuicConnectionId(nullptr, 0) {
- static_assert(offsetof(QuicConnectionId, padding_) ==
- offsetof(QuicConnectionId, length_),
- "bad offset");
- static_assert(sizeof(QuicConnectionId) <= 16, "bad size");
-}
-
-QuicConnectionId::QuicConnectionId(const char* data, uint8_t length) {
- length_ = length;
- if (length_ == 0) {
- return;
- }
- if (length_ <= sizeof(data_short_)) {
- memcpy(data_short_, data, length_);
- return;
- }
- data_long_ = reinterpret_cast<char*>(malloc(length_));
- QUICHE_CHECK_NE(nullptr, data_long_);
- memcpy(data_long_, data, length_);
-}
-
-QuicConnectionId::~QuicConnectionId() {
- if (length_ > sizeof(data_short_)) {
- free(data_long_);
- data_long_ = nullptr;
- }
-}
-
-QuicConnectionId::QuicConnectionId(const QuicConnectionId& other)
- : QuicConnectionId(other.data(), other.length()) {}
-
-QuicConnectionId& QuicConnectionId::operator=(const QuicConnectionId& other) {
- set_length(other.length());
- memcpy(mutable_data(), other.data(), length_);
- return *this;
-}
-
-const char* QuicConnectionId::data() const {
- if (length_ <= sizeof(data_short_)) {
- return data_short_;
- }
- return data_long_;
-}
-
-char* QuicConnectionId::mutable_data() {
- if (length_ <= sizeof(data_short_)) {
- return data_short_;
- }
- return data_long_;
-}
-
-uint8_t QuicConnectionId::length() const {
- return length_;
-}
-
-void QuicConnectionId::set_length(uint8_t length) {
- char temporary_data[sizeof(data_short_)];
- if (length > sizeof(data_short_)) {
- if (length_ <= sizeof(data_short_)) {
- // Copy data from data_short_ to data_long_.
- memcpy(temporary_data, data_short_, length_);
- data_long_ = reinterpret_cast<char*>(malloc(length));
- QUICHE_CHECK_NE(nullptr, data_long_);
- memcpy(data_long_, temporary_data, length_);
- } else {
- // Resize data_long_.
- char* realloc_result =
- reinterpret_cast<char*>(realloc(data_long_, length));
- QUICHE_CHECK_NE(nullptr, realloc_result);
- data_long_ = realloc_result;
- }
- } else if (length_ > sizeof(data_short_)) {
- // Copy data from data_long_ to data_short_.
- memcpy(temporary_data, data_long_, length);
- free(data_long_);
- data_long_ = nullptr;
- memcpy(data_short_, temporary_data, length);
- }
- length_ = length;
-}
-
-bool QuicConnectionId::IsEmpty() const {
- return length_ == 0;
-}
-
-size_t QuicConnectionId::Hash() const {
- static const QuicConnectionIdHasher hasher = QuicConnectionIdHasher();
- return hasher.Hash(data(), length_);
-}
-
-std::string QuicConnectionId::ToString() const {
- if (IsEmpty()) {
- return std::string("0");
- }
- return absl::BytesToHexString(absl::string_view(data(), length_));
-}
-
-std::ostream& operator<<(std::ostream& os, const QuicConnectionId& v) {
- os << v.ToString();
- return os;
-}
-
-bool QuicConnectionId::operator==(const QuicConnectionId& v) const {
- return length_ == v.length_ && memcmp(data(), v.data(), length_) == 0;
-}
-
-bool QuicConnectionId::operator!=(const QuicConnectionId& v) const {
- return !(v == *this);
-}
-
-bool QuicConnectionId::operator<(const QuicConnectionId& v) const {
- if (length_ < v.length_) {
- return true;
- }
- if (length_ > v.length_) {
- return false;
- }
- return memcmp(data(), v.data(), length_) < 0;
-}
-
-QuicConnectionId EmptyQuicConnectionId() {
- return QuicConnectionId();
-}
-
-static_assert(kQuicDefaultConnectionIdLength == sizeof(uint64_t),
- "kQuicDefaultConnectionIdLength changed");
-static_assert(kQuicDefaultConnectionIdLength == PACKET_8BYTE_CONNECTION_ID,
- "kQuicDefaultConnectionIdLength changed");
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_connection_id.h b/chromium/net/third_party/quiche/src/quic/core/quic_connection_id.h
deleted file mode 100644
index a0669d7d642..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_connection_id.h
+++ /dev/null
@@ -1,141 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_CONNECTION_ID_H_
-#define QUICHE_QUIC_CORE_QUIC_CONNECTION_ID_H_
-
-#include <string>
-#include <vector>
-
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-enum QuicConnectionIdLength {
- PACKET_0BYTE_CONNECTION_ID = 0,
- PACKET_8BYTE_CONNECTION_ID = 8,
-};
-
-// This is a property of QUIC headers, it indicates whether the connection ID
-// should actually be sent over the wire (or was sent on received packets).
-enum QuicConnectionIdIncluded : uint8_t {
- CONNECTION_ID_PRESENT = 1,
- CONNECTION_ID_ABSENT = 2,
-};
-
-// Maximum connection ID length supported by versions that use the encoding from
-// draft-ietf-quic-invariants-06.
-const uint8_t kQuicMaxConnectionIdWithLengthPrefixLength = 20;
-
-// Maximum connection ID length supported by versions that use the encoding from
-// draft-ietf-quic-invariants-05.
-const uint8_t kQuicMaxConnectionId4BitLength = 18;
-
-// kQuicDefaultConnectionIdLength is the only supported length for QUIC
-// versions < v99, and is the default picked for all versions.
-const uint8_t kQuicDefaultConnectionIdLength = 8;
-
-// According to the IETF spec, the initial server connection ID generated by
-// the client must be at least this long.
-const uint8_t kQuicMinimumInitialConnectionIdLength = 8;
-
-class QUIC_EXPORT_PRIVATE QuicConnectionId {
- public:
- // Creates a connection ID of length zero.
- QuicConnectionId();
-
- // Creates a connection ID from network order bytes.
- QuicConnectionId(const char* data, uint8_t length);
-
- // Creates a connection ID from another connection ID.
- QuicConnectionId(const QuicConnectionId& other);
-
- // Assignment operator.
- QuicConnectionId& operator=(const QuicConnectionId& other);
-
- ~QuicConnectionId();
-
- // Returns the length of the connection ID, in bytes.
- uint8_t length() const;
-
- // Sets the length of the connection ID, in bytes.
- // WARNING: Calling set_length() can change the in-memory location of the
- // connection ID. Callers must therefore ensure they call data() or
- // mutable_data() after they call set_length().
- void set_length(uint8_t length);
-
- // Returns a pointer to the connection ID bytes, in network byte order.
- const char* data() const;
-
- // Returns a mutable pointer to the connection ID bytes,
- // in network byte order.
- char* mutable_data();
-
- // Returns whether the connection ID has length zero.
- bool IsEmpty() const;
-
- // Hash() is required to use connection IDs as keys in hash tables.
- // During the lifetime of a process, the output of Hash() is guaranteed to be
- // the same for connection IDs that are equal to one another. Note however
- // that this property is not guaranteed across process lifetimes. This makes
- // Hash() suitable for data structures such as hash tables but not for sending
- // a hash over the network.
- size_t Hash() const;
-
- // Generates an ASCII string that represents
- // the contents of the connection ID, or "0" if it is empty.
- std::string ToString() const;
-
- // operator<< allows easily logging connection IDs.
- friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
- std::ostream& os,
- const QuicConnectionId& v);
-
- bool operator==(const QuicConnectionId& v) const;
- bool operator!=(const QuicConnectionId& v) const;
- // operator< is required to use connection IDs as keys in hash tables.
- bool operator<(const QuicConnectionId& v) const;
-
- private:
- // The connection ID is represented in network byte order.
- union {
- // If the connection ID fits in |data_short_|, it is stored in the
- // first |length_| bytes of |data_short_|.
- // Otherwise it is stored in |data_long_| which is guaranteed to have a size
- // equal to |length_|.
- // A value of 11 was chosen because our commonly used connection ID length
- // is 8 and with the length, the class is padded to at least 12 bytes
- // anyway.
- struct {
- uint8_t padding_; // Match length_ field of the other union member.
- char data_short_[11];
- };
- struct {
- uint8_t length_; // length of the connection ID, in bytes.
- char* data_long_;
- };
- };
-};
-
-// Creates a connection ID of length zero, unless the restart flag
-// quic_connection_ids_network_byte_order is false in which case
-// it returns an 8-byte all-zeroes connection ID.
-QUIC_EXPORT_PRIVATE QuicConnectionId EmptyQuicConnectionId();
-
-// QuicConnectionIdHash can be passed as hash argument to hash tables.
-// During the lifetime of a process, the output of QuicConnectionIdHash is
-// guaranteed to be the same for connection IDs that are equal to one another.
-// Note however that this property is not guaranteed across process lifetimes.
-// This makes QuicConnectionIdHash suitable for data structures such as hash
-// tables but not for sending a hash over the network.
-class QUIC_EXPORT_PRIVATE QuicConnectionIdHash {
- public:
- size_t operator()(QuicConnectionId const& connection_id) const noexcept {
- return connection_id.Hash();
- }
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_QUIC_CONNECTION_ID_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_connection_id_manager.cc b/chromium/net/third_party/quiche/src/quic/core/quic_connection_id_manager.cc
deleted file mode 100644
index 1138a2ed5d4..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_connection_id_manager.cc
+++ /dev/null
@@ -1,460 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_connection_id_manager.h"
-
-#include <cstdio>
-
-#include "quic/core/quic_clock.h"
-#include "quic/core/quic_connection_id.h"
-#include "quic/core/quic_error_codes.h"
-#include "quic/core/quic_utils.h"
-#include "common/platform/api/quiche_logging.h"
-
-namespace quic {
-
-QuicConnectionIdData::QuicConnectionIdData(
- const QuicConnectionId& connection_id,
- uint64_t sequence_number,
- const StatelessResetToken& stateless_reset_token)
- : connection_id(connection_id),
- sequence_number(sequence_number),
- stateless_reset_token(stateless_reset_token) {}
-
-namespace {
-
-class RetirePeerIssuedConnectionIdAlarm
- : public QuicAlarm::DelegateWithContext {
- public:
- explicit RetirePeerIssuedConnectionIdAlarm(
- QuicConnectionIdManagerVisitorInterface* visitor,
- QuicConnectionContext* context)
- : QuicAlarm::DelegateWithContext(context), visitor_(visitor) {}
- RetirePeerIssuedConnectionIdAlarm(const RetirePeerIssuedConnectionIdAlarm&) =
- delete;
- RetirePeerIssuedConnectionIdAlarm& operator=(
- const RetirePeerIssuedConnectionIdAlarm&) = delete;
-
- void OnAlarm() override { visitor_->OnPeerIssuedConnectionIdRetired(); }
-
- private:
- QuicConnectionIdManagerVisitorInterface* visitor_;
-};
-
-std::vector<QuicConnectionIdData>::const_iterator FindConnectionIdData(
- const std::vector<QuicConnectionIdData>& cid_data_vector,
- const QuicConnectionId& cid) {
- return std::find_if(cid_data_vector.begin(), cid_data_vector.end(),
- [&cid](const QuicConnectionIdData& cid_data) {
- return cid == cid_data.connection_id;
- });
-}
-
-std::vector<QuicConnectionIdData>::iterator FindConnectionIdData(
- std::vector<QuicConnectionIdData>* cid_data_vector,
- const QuicConnectionId& cid) {
- return std::find_if(cid_data_vector->begin(), cid_data_vector->end(),
- [&cid](const QuicConnectionIdData& cid_data) {
- return cid == cid_data.connection_id;
- });
-}
-
-} // namespace
-
-QuicPeerIssuedConnectionIdManager::QuicPeerIssuedConnectionIdManager(
- size_t active_connection_id_limit,
- const QuicConnectionId& initial_peer_issued_connection_id,
- const QuicClock* clock, QuicAlarmFactory* alarm_factory,
- QuicConnectionIdManagerVisitorInterface* visitor,
- QuicConnectionContext* context)
- : active_connection_id_limit_(active_connection_id_limit),
- clock_(clock),
- retire_connection_id_alarm_(alarm_factory->CreateAlarm(
- new RetirePeerIssuedConnectionIdAlarm(visitor, context))) {
- QUICHE_DCHECK_GE(active_connection_id_limit_, 2u);
- QUICHE_DCHECK(!initial_peer_issued_connection_id.IsEmpty());
- active_connection_id_data_.emplace_back<const QuicConnectionId&, uint64_t,
- const StatelessResetToken&>(
- initial_peer_issued_connection_id,
- /*sequence_number=*/0u, {});
- recent_new_connection_id_sequence_numbers_.Add(0u, 1u);
-}
-
-QuicPeerIssuedConnectionIdManager::~QuicPeerIssuedConnectionIdManager() {
- retire_connection_id_alarm_->Cancel();
-}
-
-bool QuicPeerIssuedConnectionIdManager::IsConnectionIdNew(
- const QuicNewConnectionIdFrame& frame) {
- auto is_old_connection_id = [&frame](const QuicConnectionIdData& cid_data) {
- return cid_data.connection_id == frame.connection_id;
- };
- if (std::any_of(active_connection_id_data_.begin(),
- active_connection_id_data_.end(), is_old_connection_id)) {
- return false;
- }
- if (std::any_of(unused_connection_id_data_.begin(),
- unused_connection_id_data_.end(), is_old_connection_id)) {
- return false;
- }
- if (std::any_of(to_be_retired_connection_id_data_.begin(),
- to_be_retired_connection_id_data_.end(),
- is_old_connection_id)) {
- return false;
- }
- return true;
-}
-
-void QuicPeerIssuedConnectionIdManager::PrepareToRetireConnectionIdPriorTo(
- uint64_t retire_prior_to,
- std::vector<QuicConnectionIdData>* cid_data_vector) {
- auto it2 = cid_data_vector->begin();
- for (auto it = cid_data_vector->begin(); it != cid_data_vector->end(); ++it) {
- if (it->sequence_number >= retire_prior_to) {
- *it2++ = *it;
- } else {
- to_be_retired_connection_id_data_.push_back(*it);
- if (!retire_connection_id_alarm_->IsSet()) {
- retire_connection_id_alarm_->Set(clock_->ApproximateNow());
- }
- }
- }
- cid_data_vector->erase(it2, cid_data_vector->end());
-}
-
-QuicErrorCode QuicPeerIssuedConnectionIdManager::OnNewConnectionIdFrame(
- const QuicNewConnectionIdFrame& frame,
- std::string* error_detail) {
- if (recent_new_connection_id_sequence_numbers_.Contains(
- frame.sequence_number)) {
- // This frame has a recently seen sequence number. Ignore.
- return QUIC_NO_ERROR;
- }
- if (!IsConnectionIdNew(frame)) {
- *error_detail =
- "Received a NEW_CONNECTION_ID frame that reuses a previously seen Id.";
- return IETF_QUIC_PROTOCOL_VIOLATION;
- }
-
- recent_new_connection_id_sequence_numbers_.AddOptimizedForAppend(
- frame.sequence_number, frame.sequence_number + 1);
-
- if (recent_new_connection_id_sequence_numbers_.Size() >
- kMaxNumConnectionIdSequenceNumberIntervals) {
- *error_detail =
- "Too many disjoint connection Id sequence number intervals.";
- return IETF_QUIC_PROTOCOL_VIOLATION;
- }
-
- // QuicFramer::ProcessNewConnectionIdFrame guarantees that
- // frame.sequence_number >= frame.retire_prior_to, and hence there is no need
- // to check that.
- if (frame.sequence_number < max_new_connection_id_frame_retire_prior_to_) {
- // Later frames have asked for retirement of the current frame.
- to_be_retired_connection_id_data_.emplace_back(frame.connection_id,
- frame.sequence_number,
- frame.stateless_reset_token);
- if (!retire_connection_id_alarm_->IsSet()) {
- retire_connection_id_alarm_->Set(clock_->ApproximateNow());
- }
- return QUIC_NO_ERROR;
- }
- if (frame.retire_prior_to > max_new_connection_id_frame_retire_prior_to_) {
- max_new_connection_id_frame_retire_prior_to_ = frame.retire_prior_to;
- PrepareToRetireConnectionIdPriorTo(frame.retire_prior_to,
- &active_connection_id_data_);
- PrepareToRetireConnectionIdPriorTo(frame.retire_prior_to,
- &unused_connection_id_data_);
- }
-
- if (active_connection_id_data_.size() + unused_connection_id_data_.size() >=
- active_connection_id_limit_) {
- *error_detail = "Peer provides more connection IDs than the limit.";
- return QUIC_CONNECTION_ID_LIMIT_ERROR;
- }
-
- unused_connection_id_data_.emplace_back(
- frame.connection_id, frame.sequence_number, frame.stateless_reset_token);
- return QUIC_NO_ERROR;
-}
-
-const QuicConnectionIdData*
-QuicPeerIssuedConnectionIdManager::ConsumeOneUnusedConnectionId() {
- if (unused_connection_id_data_.empty()) {
- return nullptr;
- }
- active_connection_id_data_.push_back(unused_connection_id_data_.back());
- unused_connection_id_data_.pop_back();
- return &active_connection_id_data_.back();
-}
-
-void QuicPeerIssuedConnectionIdManager::PrepareToRetireActiveConnectionId(
- const QuicConnectionId& cid) {
- auto it = FindConnectionIdData(active_connection_id_data_, cid);
- if (it == active_connection_id_data_.end()) {
- // The cid has already been retired.
- return;
- }
- to_be_retired_connection_id_data_.push_back(*it);
- active_connection_id_data_.erase(it);
- if (!retire_connection_id_alarm_->IsSet()) {
- retire_connection_id_alarm_->Set(clock_->ApproximateNow());
- }
-}
-
-void QuicPeerIssuedConnectionIdManager::MaybeRetireUnusedConnectionIds(
- const std::vector<QuicConnectionId>& active_connection_ids_on_path) {
- std::vector<QuicConnectionId> cids_to_retire;
- for (const auto& cid_data : active_connection_id_data_) {
- if (std::find(active_connection_ids_on_path.begin(),
- active_connection_ids_on_path.end(),
- cid_data.connection_id) ==
- active_connection_ids_on_path.end()) {
- cids_to_retire.push_back(cid_data.connection_id);
- }
- }
- for (const auto& cid : cids_to_retire) {
- PrepareToRetireActiveConnectionId(cid);
- }
-}
-
-bool QuicPeerIssuedConnectionIdManager::IsConnectionIdActive(
- const QuicConnectionId& cid) const {
- return FindConnectionIdData(active_connection_id_data_, cid) !=
- active_connection_id_data_.end();
-}
-
-std::vector<uint64_t> QuicPeerIssuedConnectionIdManager::
- ConsumeToBeRetiredConnectionIdSequenceNumbers() {
- std::vector<uint64_t> result;
- for (auto const& cid_data : to_be_retired_connection_id_data_) {
- result.push_back(cid_data.sequence_number);
- }
- to_be_retired_connection_id_data_.clear();
- return result;
-}
-
-void QuicPeerIssuedConnectionIdManager::ReplaceConnectionId(
- const QuicConnectionId& old_connection_id,
- const QuicConnectionId& new_connection_id) {
- auto it1 =
- FindConnectionIdData(&active_connection_id_data_, old_connection_id);
- if (it1 != active_connection_id_data_.end()) {
- it1->connection_id = new_connection_id;
- return;
- }
- auto it2 = FindConnectionIdData(&to_be_retired_connection_id_data_,
- old_connection_id);
- if (it2 != to_be_retired_connection_id_data_.end()) {
- it2->connection_id = new_connection_id;
- }
-}
-
-namespace {
-
-class RetireSelfIssuedConnectionIdAlarmDelegate
- : public QuicAlarm::DelegateWithContext {
- public:
- explicit RetireSelfIssuedConnectionIdAlarmDelegate(
- QuicSelfIssuedConnectionIdManager* connection_id_manager,
- QuicConnectionContext* context)
- : QuicAlarm::DelegateWithContext(context),
- connection_id_manager_(connection_id_manager) {}
- RetireSelfIssuedConnectionIdAlarmDelegate(
- const RetireSelfIssuedConnectionIdAlarmDelegate&) = delete;
- RetireSelfIssuedConnectionIdAlarmDelegate& operator=(
- const RetireSelfIssuedConnectionIdAlarmDelegate&) = delete;
-
- void OnAlarm() override { connection_id_manager_->RetireConnectionId(); }
-
- private:
- QuicSelfIssuedConnectionIdManager* connection_id_manager_;
-};
-
-} // namespace
-
-QuicSelfIssuedConnectionIdManager::QuicSelfIssuedConnectionIdManager(
- size_t active_connection_id_limit,
- const QuicConnectionId& initial_connection_id, const QuicClock* clock,
- QuicAlarmFactory* alarm_factory,
- QuicConnectionIdManagerVisitorInterface* visitor,
- QuicConnectionContext* context)
- : active_connection_id_limit_(active_connection_id_limit),
- clock_(clock),
- visitor_(visitor),
- retire_connection_id_alarm_(alarm_factory->CreateAlarm(
- new RetireSelfIssuedConnectionIdAlarmDelegate(this, context))),
- last_connection_id_(initial_connection_id),
- next_connection_id_sequence_number_(1u),
- last_connection_id_consumed_by_self_sequence_number_(0u) {
- active_connection_ids_.emplace_back(initial_connection_id, 0u);
-}
-
-QuicSelfIssuedConnectionIdManager::~QuicSelfIssuedConnectionIdManager() {
- retire_connection_id_alarm_->Cancel();
-}
-
-QuicConnectionId QuicSelfIssuedConnectionIdManager::GenerateNewConnectionId(
- const QuicConnectionId& old_connection_id) const {
- return QuicUtils::CreateReplacementConnectionId(old_connection_id);
-}
-
-QuicNewConnectionIdFrame
-QuicSelfIssuedConnectionIdManager::IssueNewConnectionId() {
- QuicNewConnectionIdFrame frame;
- frame.connection_id = GenerateNewConnectionId(last_connection_id_);
- frame.sequence_number = next_connection_id_sequence_number_++;
- frame.stateless_reset_token =
- QuicUtils::GenerateStatelessResetToken(frame.connection_id);
- visitor_->OnNewConnectionIdIssued(frame.connection_id);
- active_connection_ids_.emplace_back(frame.connection_id,
- frame.sequence_number);
- frame.retire_prior_to = active_connection_ids_.front().second;
- last_connection_id_ = frame.connection_id;
- return frame;
-}
-
-QuicNewConnectionIdFrame
-QuicSelfIssuedConnectionIdManager::IssueNewConnectionIdForPreferredAddress() {
- QuicNewConnectionIdFrame frame = IssueNewConnectionId();
- QUICHE_DCHECK_EQ(frame.sequence_number, 1u);
- return frame;
-}
-
-QuicErrorCode QuicSelfIssuedConnectionIdManager::OnRetireConnectionIdFrame(
- const QuicRetireConnectionIdFrame& frame,
- QuicTime::Delta pto_delay,
- std::string* error_detail) {
- QUICHE_DCHECK(!active_connection_ids_.empty());
- if (frame.sequence_number > active_connection_ids_.back().second) {
- *error_detail = "To be retired connecton ID is never issued.";
- return IETF_QUIC_PROTOCOL_VIOLATION;
- }
-
- auto it =
- std::find_if(active_connection_ids_.begin(), active_connection_ids_.end(),
- [&frame](const std::pair<QuicConnectionId, uint64_t>& p) {
- return p.second == frame.sequence_number;
- });
- // The corresponding connection ID has been retired. Ignore.
- if (it == active_connection_ids_.end()) {
- return QUIC_NO_ERROR;
- }
-
- if (to_be_retired_connection_ids_.size() + active_connection_ids_.size() >=
- kMaxNumConnectonIdsInUse) {
- // Close connection if the number of connection IDs in use will exeed the
- // limit, i.e., peer retires connection ID too fast.
- *error_detail = "There are too many connection IDs in use.";
- return QUIC_TOO_MANY_CONNECTION_ID_WAITING_TO_RETIRE;
- }
-
- QuicTime retirement_time = clock_->ApproximateNow() + 3 * pto_delay;
- if (!to_be_retired_connection_ids_.empty()) {
- retirement_time =
- std::max(retirement_time, to_be_retired_connection_ids_.back().second);
- }
-
- to_be_retired_connection_ids_.emplace_back(it->first, retirement_time);
- if (!retire_connection_id_alarm_->IsSet()) {
- retire_connection_id_alarm_->Set(retirement_time);
- }
-
- active_connection_ids_.erase(it);
- MaybeSendNewConnectionIds();
-
- return QUIC_NO_ERROR;
-}
-
-std::vector<QuicConnectionId>
-QuicSelfIssuedConnectionIdManager::GetUnretiredConnectionIds() const {
- std::vector<QuicConnectionId> unretired_ids;
- for (const auto& cid_pair : to_be_retired_connection_ids_) {
- unretired_ids.push_back(cid_pair.first);
- }
- for (const auto& cid_pair : active_connection_ids_) {
- unretired_ids.push_back(cid_pair.first);
- }
- return unretired_ids;
-}
-
-QuicConnectionId QuicSelfIssuedConnectionIdManager::GetOneActiveConnectionId()
- const {
- QUICHE_DCHECK(!active_connection_ids_.empty());
- return active_connection_ids_.front().first;
-}
-
-void QuicSelfIssuedConnectionIdManager::RetireConnectionId() {
- if (to_be_retired_connection_ids_.empty()) {
- QUIC_BUG(quic_bug_12420_1)
- << "retire_connection_id_alarm fired but there is no connection ID "
- "to be retired.";
- return;
- }
- QuicTime now = clock_->ApproximateNow();
- auto it = to_be_retired_connection_ids_.begin();
- do {
- visitor_->OnSelfIssuedConnectionIdRetired(it->first);
- ++it;
- } while (it != to_be_retired_connection_ids_.end() && it->second <= now);
- to_be_retired_connection_ids_.erase(to_be_retired_connection_ids_.begin(),
- it);
- // Set the alarm again if there is another connection ID to be removed.
- if (!to_be_retired_connection_ids_.empty()) {
- retire_connection_id_alarm_->Set(
- to_be_retired_connection_ids_.front().second);
- }
-}
-
-void QuicSelfIssuedConnectionIdManager::MaybeSendNewConnectionIds() {
- while (active_connection_ids_.size() < active_connection_id_limit_) {
- QuicNewConnectionIdFrame frame = IssueNewConnectionId();
- if (!visitor_->SendNewConnectionId(frame)) {
- break;
- }
- }
-}
-
-bool QuicSelfIssuedConnectionIdManager::HasConnectionIdToConsume() const {
- for (const auto& active_cid_data : active_connection_ids_) {
- if (active_cid_data.second >
- last_connection_id_consumed_by_self_sequence_number_) {
- return true;
- }
- }
- return false;
-}
-
-absl::optional<QuicConnectionId>
-QuicSelfIssuedConnectionIdManager::ConsumeOneConnectionId() {
- for (const auto& active_cid_data : active_connection_ids_) {
- if (active_cid_data.second >
- last_connection_id_consumed_by_self_sequence_number_) {
- // Since connection IDs in active_connection_ids_ has monotonically
- // increasing sequence numbers, the returned connection ID has the
- // smallest sequence number among all unconsumed active connection IDs.
- last_connection_id_consumed_by_self_sequence_number_ =
- active_cid_data.second;
- return active_cid_data.first;
- }
- }
- return absl::nullopt;
-}
-
-bool QuicSelfIssuedConnectionIdManager::IsConnectionIdInUse(
- const QuicConnectionId& cid) const {
- for (const auto& active_cid_data : active_connection_ids_) {
- if (active_cid_data.first == cid) {
- return true;
- }
- }
- for (const auto& to_be_retired_cid_data : to_be_retired_connection_ids_) {
- if (to_be_retired_cid_data.first == cid) {
- return true;
- }
- }
- return false;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_connection_id_manager.h b/chromium/net/third_party/quiche/src/quic/core/quic_connection_id_manager.h
deleted file mode 100644
index e23668df2c9..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_connection_id_manager.h
+++ /dev/null
@@ -1,195 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// QuicPeerIssuedConnectionIdManager handles the states associated with receving
-// and retiring peer issued connection Ids.
-// QuicSelfIssuedConnectionIdManager handles the states associated with
-// connection Ids issued by the current end point.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_CONNECTION_ID_MANAGER_H_
-#define QUICHE_QUIC_CORE_QUIC_CONNECTION_ID_MANAGER_H_
-
-#include <cstddef>
-#include <memory>
-
-#include "absl/types/optional.h"
-#include "quic/core/frames/quic_new_connection_id_frame.h"
-#include "quic/core/frames/quic_retire_connection_id_frame.h"
-#include "quic/core/quic_alarm.h"
-#include "quic/core/quic_alarm_factory.h"
-#include "quic/core/quic_clock.h"
-#include "quic/core/quic_connection_id.h"
-#include "quic/core/quic_interval_set.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-namespace test {
-class QuicConnectionIdManagerPeer;
-} // namespace test
-
-struct QUIC_EXPORT_PRIVATE QuicConnectionIdData {
- QuicConnectionIdData(const QuicConnectionId& connection_id,
- uint64_t sequence_number,
- const StatelessResetToken& stateless_reset_token);
-
- QuicConnectionId connection_id;
- uint64_t sequence_number;
- StatelessResetToken stateless_reset_token;
-};
-
-// Used by QuicSelfIssuedConnectionIdManager
-// and QuicPeerIssuedConnectionIdManager.
-class QUIC_EXPORT_PRIVATE QuicConnectionIdManagerVisitorInterface {
- public:
- virtual ~QuicConnectionIdManagerVisitorInterface() = default;
- virtual void OnPeerIssuedConnectionIdRetired() = 0;
- virtual bool SendNewConnectionId(const QuicNewConnectionIdFrame& frame) = 0;
- virtual void OnNewConnectionIdIssued(
- const QuicConnectionId& connection_id) = 0;
- virtual void OnSelfIssuedConnectionIdRetired(
- const QuicConnectionId& connection_id) = 0;
-};
-
-class QUIC_EXPORT_PRIVATE QuicPeerIssuedConnectionIdManager {
- public:
- // QuicPeerIssuedConnectionIdManager should be instantiated only when a peer
- // issued-non empty connection ID is received.
- QuicPeerIssuedConnectionIdManager(
- size_t active_connection_id_limit,
- const QuicConnectionId& initial_peer_issued_connection_id,
- const QuicClock* clock, QuicAlarmFactory* alarm_factory,
- QuicConnectionIdManagerVisitorInterface* visitor,
- QuicConnectionContext* context);
-
- ~QuicPeerIssuedConnectionIdManager();
-
- QuicErrorCode OnNewConnectionIdFrame(const QuicNewConnectionIdFrame& frame,
- std::string* error_detail);
-
- bool HasUnusedConnectionId() const {
- return !unused_connection_id_data_.empty();
- }
-
- // Returns the data associated with an unused connection Id. After the call,
- // the Id is marked as used. Returns nullptr if there is no unused connection
- // Id.
- const QuicConnectionIdData* ConsumeOneUnusedConnectionId();
-
- // Add each active connection Id that is no longer on path to the pending
- // retirement connection Id list.
- void MaybeRetireUnusedConnectionIds(
- const std::vector<QuicConnectionId>& active_connection_ids_on_path);
-
- bool IsConnectionIdActive(const QuicConnectionId& cid) const;
-
- // Get the sequence numbers of all the connection Ids pending retirement when
- // it is safe to retires these Ids.
- std::vector<uint64_t> ConsumeToBeRetiredConnectionIdSequenceNumbers();
-
- // If old_connection_id is still tracked by QuicPeerIssuedConnectionIdManager,
- // replace it with new_connection_id. Otherwise, this is a no-op.
- void ReplaceConnectionId(const QuicConnectionId& old_connection_id,
- const QuicConnectionId& new_connection_id);
-
- private:
- friend class test::QuicConnectionIdManagerPeer;
-
- // Add the connection Id to the pending retirement connection Id list and
- // schedule an alarm if needed.
- void PrepareToRetireActiveConnectionId(const QuicConnectionId& cid);
-
- bool IsConnectionIdNew(const QuicNewConnectionIdFrame& frame);
-
- void PrepareToRetireConnectionIdPriorTo(
- uint64_t retire_prior_to,
- std::vector<QuicConnectionIdData>* cid_data_vector);
-
- size_t active_connection_id_limit_;
- const QuicClock* clock_;
- std::unique_ptr<QuicAlarm> retire_connection_id_alarm_;
- std::vector<QuicConnectionIdData> active_connection_id_data_;
- std::vector<QuicConnectionIdData> unused_connection_id_data_;
- std::vector<QuicConnectionIdData> to_be_retired_connection_id_data_;
- // Track sequence numbers of recent NEW_CONNECTION_ID frames received from
- // the peer.
- QuicIntervalSet<uint64_t> recent_new_connection_id_sequence_numbers_;
- uint64_t max_new_connection_id_frame_retire_prior_to_ = 0u;
-};
-
-class QUIC_EXPORT_PRIVATE QuicSelfIssuedConnectionIdManager {
- public:
- QuicSelfIssuedConnectionIdManager(
- size_t active_connection_id_limit,
- const QuicConnectionId& initial_connection_id, const QuicClock* clock,
- QuicAlarmFactory* alarm_factory,
- QuicConnectionIdManagerVisitorInterface* visitor,
- QuicConnectionContext* context);
-
- virtual ~QuicSelfIssuedConnectionIdManager();
-
- QuicNewConnectionIdFrame IssueNewConnectionIdForPreferredAddress();
-
- QuicErrorCode OnRetireConnectionIdFrame(
- const QuicRetireConnectionIdFrame& frame,
- QuicTime::Delta pto_delay,
- std::string* error_detail);
-
- std::vector<QuicConnectionId> GetUnretiredConnectionIds() const;
-
- QuicConnectionId GetOneActiveConnectionId() const;
-
- // Called when the retire_connection_id alarm_ fires. Removes the to be
- // retired connection ID locally.
- void RetireConnectionId();
-
- // Sends new connection IDs if more can be sent.
- void MaybeSendNewConnectionIds();
-
- // The two functions are called on the client side to associate a client
- // connection ID with a new probing/migration path when client uses
- // non-empty connection ID.
- bool HasConnectionIdToConsume() const;
- absl::optional<QuicConnectionId> ConsumeOneConnectionId();
-
- // Returns true if the given connection ID is issued by the
- // QuicSelfIssuedConnectionIdManager and not retired locally yet. Called to
- // tell if a received packet has a valid connection ID.
- bool IsConnectionIdInUse(const QuicConnectionId& cid) const;
-
- virtual QuicConnectionId GenerateNewConnectionId(
- const QuicConnectionId& old_connection_id) const;
-
- private:
- friend class test::QuicConnectionIdManagerPeer;
-
- QuicNewConnectionIdFrame IssueNewConnectionId();
-
- // This should be set to the min of:
- // (1) # of connection atcive IDs that peer can maintain.
- // (2) maximum # of active connection IDs self plans to issue.
- size_t active_connection_id_limit_;
- const QuicClock* clock_;
- QuicConnectionIdManagerVisitorInterface* visitor_;
- // This tracks connection IDs issued to the peer but not retired by the peer.
- // Each pair is a connection ID and its sequence number.
- std::vector<std::pair<QuicConnectionId, uint64_t>> active_connection_ids_;
- // This tracks connection IDs retired by the peer but has not been retired
- // locally. Each pair is a connection ID and the time by which it should be
- // retired.
- std::vector<std::pair<QuicConnectionId, QuicTime>>
- to_be_retired_connection_ids_;
- // An alarm that fires when a connection ID should be retired.
- std::unique_ptr<QuicAlarm> retire_connection_id_alarm_;
- // State of the last issued connection Id.
- QuicConnectionId last_connection_id_;
- uint64_t next_connection_id_sequence_number_;
- // The sequence number of last connection ID consumed.
- uint64_t last_connection_id_consumed_by_self_sequence_number_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_QUIC_CONNECTION_ID_MANAGER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_connection_id_manager_test.cc b/chromium/net/third_party/quiche/src/quic/core/quic_connection_id_manager_test.cc
deleted file mode 100644
index fdb73daa85b..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_connection_id_manager_test.cc
+++ /dev/null
@@ -1,964 +0,0 @@
-// Copyright 2013 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 "quic/core/quic_connection_id_manager.h"
-#include <cstddef>
-
-#include "quic/core/quic_connection_id.h"
-#include "quic/core/quic_error_codes.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/mock_clock.h"
-#include "quic/test_tools/quic_connection_id_manager_peer.h"
-#include "quic/test_tools/quic_test_utils.h"
-
-namespace quic {
-namespace {
-
-using ::quic::test::IsError;
-using ::quic::test::IsQuicNoError;
-using ::quic::test::QuicConnectionIdManagerPeer;
-using ::quic::test::TestConnectionId;
-using ::testing::_;
-using ::testing::ElementsAre;
-using ::testing::IsNull;
-using ::testing::Return;
-using ::testing::StrictMock;
-
-class TestPeerIssuedConnectionIdManagerVisitor
- : public QuicConnectionIdManagerVisitorInterface {
- public:
- void SetPeerIssuedConnectionIdManager(
- QuicPeerIssuedConnectionIdManager* peer_issued_connection_id_manager) {
- peer_issued_connection_id_manager_ = peer_issued_connection_id_manager;
- }
-
- void OnPeerIssuedConnectionIdRetired() override {
- // Replace current connection Id if it has been retired.
- if (!peer_issued_connection_id_manager_->IsConnectionIdActive(
- current_peer_issued_connection_id_)) {
- current_peer_issued_connection_id_ =
- peer_issued_connection_id_manager_->ConsumeOneUnusedConnectionId()
- ->connection_id;
- }
- // Retire all the to-be-retired connection Ids.
- most_recent_retired_connection_id_sequence_numbers_ =
- peer_issued_connection_id_manager_
- ->ConsumeToBeRetiredConnectionIdSequenceNumbers();
- }
-
- const std::vector<uint64_t>&
- most_recent_retired_connection_id_sequence_numbers() {
- return most_recent_retired_connection_id_sequence_numbers_;
- }
-
- void SetCurrentPeerConnectionId(QuicConnectionId cid) {
- current_peer_issued_connection_id_ = cid;
- }
-
- const QuicConnectionId& GetCurrentPeerConnectionId() {
- return current_peer_issued_connection_id_;
- }
-
- bool SendNewConnectionId(const QuicNewConnectionIdFrame& /*frame*/) override {
- return false;
- }
- void OnNewConnectionIdIssued(
- const QuicConnectionId& /*connection_id*/) override {}
- void OnSelfIssuedConnectionIdRetired(
- const QuicConnectionId& /*connection_id*/) override {}
-
- private:
- QuicPeerIssuedConnectionIdManager* peer_issued_connection_id_manager_ =
- nullptr;
- QuicConnectionId current_peer_issued_connection_id_;
- std::vector<uint64_t> most_recent_retired_connection_id_sequence_numbers_;
-};
-
-class QuicPeerIssuedConnectionIdManagerTest : public QuicTest {
- public:
- QuicPeerIssuedConnectionIdManagerTest()
- : peer_issued_cid_manager_(
- /*active_connection_id_limit=*/2, initial_connection_id_, &clock_,
- &alarm_factory_, &cid_manager_visitor_, /*context=*/nullptr) {
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
- cid_manager_visitor_.SetPeerIssuedConnectionIdManager(
- &peer_issued_cid_manager_);
- cid_manager_visitor_.SetCurrentPeerConnectionId(initial_connection_id_);
- retire_peer_issued_cid_alarm_ =
- QuicConnectionIdManagerPeer::GetRetirePeerIssuedConnectionIdAlarm(
- &peer_issued_cid_manager_);
- }
-
- protected:
- MockClock clock_;
- test::MockAlarmFactory alarm_factory_;
- TestPeerIssuedConnectionIdManagerVisitor cid_manager_visitor_;
- QuicConnectionId initial_connection_id_ = TestConnectionId(0);
- QuicPeerIssuedConnectionIdManager peer_issued_cid_manager_;
- QuicAlarm* retire_peer_issued_cid_alarm_ = nullptr;
- std::string error_details_;
-};
-
-TEST_F(QuicPeerIssuedConnectionIdManagerTest,
- ConnectionIdSequenceWhenMigrationSucceed) {
- {
- // Receives CID #1 from peer.
- QuicNewConnectionIdFrame frame;
- frame.connection_id = TestConnectionId(1);
- frame.sequence_number = 1u;
- frame.retire_prior_to = 0u;
- frame.stateless_reset_token =
- QuicUtils::GenerateStatelessResetToken(frame.connection_id);
- ASSERT_THAT(
- peer_issued_cid_manager_.OnNewConnectionIdFrame(frame, &error_details_),
- IsQuicNoError());
-
- // Start to use CID #1 for alternative path.
- const QuicConnectionIdData* aternative_connection_id_data =
- peer_issued_cid_manager_.ConsumeOneUnusedConnectionId();
- ASSERT_THAT(aternative_connection_id_data, testing::NotNull());
- EXPECT_EQ(aternative_connection_id_data->connection_id,
- TestConnectionId(1));
- EXPECT_EQ(aternative_connection_id_data->stateless_reset_token,
- frame.stateless_reset_token);
-
- // Connection migration succeed. Prepares to retire CID #0.
- peer_issued_cid_manager_.MaybeRetireUnusedConnectionIds(
- {TestConnectionId(1)});
- cid_manager_visitor_.SetCurrentPeerConnectionId(TestConnectionId(1));
- ASSERT_TRUE(retire_peer_issued_cid_alarm_->IsSet());
- alarm_factory_.FireAlarm(retire_peer_issued_cid_alarm_);
- EXPECT_THAT(cid_manager_visitor_
- .most_recent_retired_connection_id_sequence_numbers(),
- ElementsAre(0u));
- }
-
- {
- // Receives CID #2 from peer since CID #0 is retired.
- QuicNewConnectionIdFrame frame;
- frame.connection_id = TestConnectionId(2);
- frame.sequence_number = 2u;
- frame.retire_prior_to = 1u;
- frame.stateless_reset_token =
- QuicUtils::GenerateStatelessResetToken(frame.connection_id);
- ASSERT_THAT(
- peer_issued_cid_manager_.OnNewConnectionIdFrame(frame, &error_details_),
- IsQuicNoError());
- // Start to use CID #2 for alternative path.
- peer_issued_cid_manager_.ConsumeOneUnusedConnectionId();
- // Connection migration succeed. Prepares to retire CID #1.
- peer_issued_cid_manager_.MaybeRetireUnusedConnectionIds(
- {TestConnectionId(2)});
- cid_manager_visitor_.SetCurrentPeerConnectionId(TestConnectionId(2));
- ASSERT_TRUE(retire_peer_issued_cid_alarm_->IsSet());
- alarm_factory_.FireAlarm(retire_peer_issued_cid_alarm_);
- EXPECT_THAT(cid_manager_visitor_
- .most_recent_retired_connection_id_sequence_numbers(),
- ElementsAre(1u));
- }
-
- {
- // Receives CID #3 from peer since CID #1 is retired.
- QuicNewConnectionIdFrame frame;
- frame.connection_id = TestConnectionId(3);
- frame.sequence_number = 3u;
- frame.retire_prior_to = 2u;
- frame.stateless_reset_token =
- QuicUtils::GenerateStatelessResetToken(frame.connection_id);
- ASSERT_THAT(
- peer_issued_cid_manager_.OnNewConnectionIdFrame(frame, &error_details_),
- IsQuicNoError());
- // Start to use CID #3 for alternative path.
- peer_issued_cid_manager_.ConsumeOneUnusedConnectionId();
- // Connection migration succeed. Prepares to retire CID #2.
- peer_issued_cid_manager_.MaybeRetireUnusedConnectionIds(
- {TestConnectionId(3)});
- cid_manager_visitor_.SetCurrentPeerConnectionId(TestConnectionId(3));
- ASSERT_TRUE(retire_peer_issued_cid_alarm_->IsSet());
- alarm_factory_.FireAlarm(retire_peer_issued_cid_alarm_);
- EXPECT_THAT(cid_manager_visitor_
- .most_recent_retired_connection_id_sequence_numbers(),
- ElementsAre(2u));
- }
-
- {
- // Receives CID #4 from peer since CID #2 is retired.
- QuicNewConnectionIdFrame frame;
- frame.connection_id = TestConnectionId(4);
- frame.sequence_number = 4u;
- frame.retire_prior_to = 3u;
- frame.stateless_reset_token =
- QuicUtils::GenerateStatelessResetToken(frame.connection_id);
- ASSERT_THAT(
- peer_issued_cid_manager_.OnNewConnectionIdFrame(frame, &error_details_),
- IsQuicNoError());
- }
-}
-
-TEST_F(QuicPeerIssuedConnectionIdManagerTest,
- ConnectionIdSequenceWhenMigrationFail) {
- {
- // Receives CID #1 from peer.
- QuicNewConnectionIdFrame frame;
- frame.connection_id = TestConnectionId(1);
- frame.sequence_number = 1u;
- frame.retire_prior_to = 0u;
- frame.stateless_reset_token =
- QuicUtils::GenerateStatelessResetToken(frame.connection_id);
- ASSERT_THAT(
- peer_issued_cid_manager_.OnNewConnectionIdFrame(frame, &error_details_),
- IsQuicNoError());
- // Start to use CID #1 for alternative path.
- peer_issued_cid_manager_.ConsumeOneUnusedConnectionId();
- // Connection migration fails. Prepares to retire CID #1.
- peer_issued_cid_manager_.MaybeRetireUnusedConnectionIds(
- {initial_connection_id_});
- // Actually retires CID #1.
- ASSERT_TRUE(retire_peer_issued_cid_alarm_->IsSet());
- alarm_factory_.FireAlarm(retire_peer_issued_cid_alarm_);
- EXPECT_THAT(cid_manager_visitor_
- .most_recent_retired_connection_id_sequence_numbers(),
- ElementsAre(1u));
- }
-
- {
- // Receives CID #2 from peer since CID #1 is retired.
- QuicNewConnectionIdFrame frame;
- frame.connection_id = TestConnectionId(2);
- frame.sequence_number = 2u;
- frame.retire_prior_to = 0u;
- frame.stateless_reset_token =
- QuicUtils::GenerateStatelessResetToken(frame.connection_id);
- ASSERT_THAT(
- peer_issued_cid_manager_.OnNewConnectionIdFrame(frame, &error_details_),
- IsQuicNoError());
- // Start to use CID #2 for alternative path.
- peer_issued_cid_manager_.ConsumeOneUnusedConnectionId();
- // Connection migration fails again. Prepares to retire CID #2.
- peer_issued_cid_manager_.MaybeRetireUnusedConnectionIds(
- {initial_connection_id_});
- // Actually retires CID #2.
- ASSERT_TRUE(retire_peer_issued_cid_alarm_->IsSet());
- alarm_factory_.FireAlarm(retire_peer_issued_cid_alarm_);
- EXPECT_THAT(cid_manager_visitor_
- .most_recent_retired_connection_id_sequence_numbers(),
- ElementsAre(2u));
- }
-
- {
- // Receives CID #3 from peer since CID #2 is retired.
- QuicNewConnectionIdFrame frame;
- frame.connection_id = TestConnectionId(3);
- frame.sequence_number = 3u;
- frame.retire_prior_to = 0u;
- frame.stateless_reset_token =
- QuicUtils::GenerateStatelessResetToken(frame.connection_id);
- ASSERT_THAT(
- peer_issued_cid_manager_.OnNewConnectionIdFrame(frame, &error_details_),
- IsQuicNoError());
- // Start to use CID #3 for alternative path.
- peer_issued_cid_manager_.ConsumeOneUnusedConnectionId();
- // Connection migration succeed. Prepares to retire CID #0.
- peer_issued_cid_manager_.MaybeRetireUnusedConnectionIds(
- {TestConnectionId(3)});
- // After CID #3 is default (i.e., when there is no pending frame to write
- // associated with CID #0), #0 can actually be retired.
- cid_manager_visitor_.SetCurrentPeerConnectionId(TestConnectionId(3));
- ASSERT_TRUE(retire_peer_issued_cid_alarm_->IsSet());
- alarm_factory_.FireAlarm(retire_peer_issued_cid_alarm_);
- EXPECT_THAT(cid_manager_visitor_
- .most_recent_retired_connection_id_sequence_numbers(),
- ElementsAre(0u));
- }
-
- {
- // Receives CID #4 from peer since CID #0 is retired.
- QuicNewConnectionIdFrame frame;
- frame.connection_id = TestConnectionId(4);
- frame.sequence_number = 4u;
- frame.retire_prior_to = 3u;
- frame.stateless_reset_token =
- QuicUtils::GenerateStatelessResetToken(frame.connection_id);
- EXPECT_THAT(
- peer_issued_cid_manager_.OnNewConnectionIdFrame(frame, &error_details_),
- IsQuicNoError());
- EXPECT_FALSE(retire_peer_issued_cid_alarm_->IsSet());
- }
-}
-
-TEST_F(QuicPeerIssuedConnectionIdManagerTest,
- ReceivesNewConnectionIdOutOfOrder) {
- {
- // Receives new CID #1 that retires prior to #0.
- // Outcome: (active: #0 unused: #1)
- QuicNewConnectionIdFrame frame;
- frame.connection_id = TestConnectionId(1);
- frame.sequence_number = 1u;
- frame.retire_prior_to = 0u;
- frame.stateless_reset_token =
- QuicUtils::GenerateStatelessResetToken(frame.connection_id);
- ASSERT_THAT(
- peer_issued_cid_manager_.OnNewConnectionIdFrame(frame, &error_details_),
- IsQuicNoError());
- // Start to use CID #1 for alternative path.
- // Outcome: (active: #0 #1 unused: None)
- peer_issued_cid_manager_.ConsumeOneUnusedConnectionId();
- }
-
- {
- // Receives new CID #3 that retires prior to #2.
- // Outcome: (active: None unused: #3)
- QuicNewConnectionIdFrame frame;
- frame.connection_id = TestConnectionId(3);
- frame.sequence_number = 3u;
- frame.retire_prior_to = 2u;
- frame.stateless_reset_token =
- QuicUtils::GenerateStatelessResetToken(frame.connection_id);
- ASSERT_THAT(
- peer_issued_cid_manager_.OnNewConnectionIdFrame(frame, &error_details_),
- IsQuicNoError());
- }
-
- {
- // Receives new CID #2 that retires prior to #1.
- // Outcome: (active: None unused: #3, #2)
- QuicNewConnectionIdFrame frame;
- frame.connection_id = TestConnectionId(2);
- frame.sequence_number = 2u;
- frame.retire_prior_to = 1u;
- frame.stateless_reset_token =
- QuicUtils::GenerateStatelessResetToken(frame.connection_id);
- ASSERT_THAT(
- peer_issued_cid_manager_.OnNewConnectionIdFrame(frame, &error_details_),
- IsQuicNoError());
- }
-
- {
- EXPECT_FALSE(
- peer_issued_cid_manager_.IsConnectionIdActive(TestConnectionId(0)));
- EXPECT_FALSE(
- peer_issued_cid_manager_.IsConnectionIdActive(TestConnectionId(1)));
- // When there is no frame associated with #0 and #1 to write, replace the
- // in-use CID with an unused CID (#2) and retires #0 & #1.
- ASSERT_TRUE(retire_peer_issued_cid_alarm_->IsSet());
- alarm_factory_.FireAlarm(retire_peer_issued_cid_alarm_);
- EXPECT_THAT(cid_manager_visitor_
- .most_recent_retired_connection_id_sequence_numbers(),
- ElementsAre(0u, 1u));
- EXPECT_EQ(cid_manager_visitor_.GetCurrentPeerConnectionId(),
- TestConnectionId(2));
- // Get another unused CID for path validation.
- EXPECT_EQ(
- peer_issued_cid_manager_.ConsumeOneUnusedConnectionId()->connection_id,
- TestConnectionId(3));
- }
-}
-
-TEST_F(QuicPeerIssuedConnectionIdManagerTest,
- VisitedNewConnectionIdFrameIsIgnored) {
- // Receives new CID #1 that retires prior to #0.
- // Outcome: (active: #0 unused: #1)
- QuicNewConnectionIdFrame frame;
- frame.connection_id = TestConnectionId(1);
- frame.sequence_number = 1u;
- frame.retire_prior_to = 0u;
- frame.stateless_reset_token =
- QuicUtils::GenerateStatelessResetToken(frame.connection_id);
- ASSERT_THAT(
- peer_issued_cid_manager_.OnNewConnectionIdFrame(frame, &error_details_),
- IsQuicNoError());
- // Start to use CID #1 for alternative path.
- // Outcome: (active: #0 #1 unused: None)
- peer_issued_cid_manager_.ConsumeOneUnusedConnectionId();
- // Prepare to retire CID #1 as path validation fails.
- peer_issued_cid_manager_.MaybeRetireUnusedConnectionIds(
- {initial_connection_id_});
- // Actually retires CID #1.
- ASSERT_TRUE(retire_peer_issued_cid_alarm_->IsSet());
- alarm_factory_.FireAlarm(retire_peer_issued_cid_alarm_);
- EXPECT_THAT(
- cid_manager_visitor_.most_recent_retired_connection_id_sequence_numbers(),
- ElementsAre(1u));
- // Receives the same frame again. Should be a no-op.
- ASSERT_THAT(
- peer_issued_cid_manager_.OnNewConnectionIdFrame(frame, &error_details_),
- IsQuicNoError());
- EXPECT_THAT(peer_issued_cid_manager_.ConsumeOneUnusedConnectionId(),
- testing::IsNull());
-}
-
-TEST_F(QuicPeerIssuedConnectionIdManagerTest,
- ErrorWhenActiveConnectionIdLimitExceeded) {
- {
- // Receives new CID #1 that retires prior to #0.
- // Outcome: (active: #0 unused: #1)
- QuicNewConnectionIdFrame frame;
- frame.connection_id = TestConnectionId(1);
- frame.sequence_number = 1u;
- frame.retire_prior_to = 0u;
- frame.stateless_reset_token =
- QuicUtils::GenerateStatelessResetToken(frame.connection_id);
- ASSERT_THAT(
- peer_issued_cid_manager_.OnNewConnectionIdFrame(frame, &error_details_),
- IsQuicNoError());
- }
-
- {
- QuicNewConnectionIdFrame frame;
- frame.connection_id = TestConnectionId(2);
- frame.sequence_number = 2u;
- frame.retire_prior_to = 0u;
- frame.stateless_reset_token =
- QuicUtils::GenerateStatelessResetToken(frame.connection_id);
- ASSERT_THAT(
- peer_issued_cid_manager_.OnNewConnectionIdFrame(frame, &error_details_),
- IsError(QUIC_CONNECTION_ID_LIMIT_ERROR));
- }
-}
-
-TEST_F(QuicPeerIssuedConnectionIdManagerTest,
- ErrorWhenTheSameConnectionIdIsSeenWithDifferentSequenceNumbers) {
- {
- QuicNewConnectionIdFrame frame;
- frame.connection_id = TestConnectionId(1);
- frame.sequence_number = 1u;
- frame.retire_prior_to = 0u;
- frame.stateless_reset_token =
- QuicUtils::GenerateStatelessResetToken(frame.connection_id);
- ASSERT_THAT(
- peer_issued_cid_manager_.OnNewConnectionIdFrame(frame, &error_details_),
- IsQuicNoError());
- }
-
- {
- QuicNewConnectionIdFrame frame;
- frame.connection_id = TestConnectionId(1);
- frame.sequence_number = 2u;
- frame.retire_prior_to = 1u;
- frame.stateless_reset_token =
- QuicUtils::GenerateStatelessResetToken(TestConnectionId(2));
- ASSERT_THAT(
- peer_issued_cid_manager_.OnNewConnectionIdFrame(frame, &error_details_),
- IsError(IETF_QUIC_PROTOCOL_VIOLATION));
- }
-}
-
-TEST_F(QuicPeerIssuedConnectionIdManagerTest,
- NewConnectionIdFrameWithTheSameSequenceNumberIsIgnored) {
- {
- QuicNewConnectionIdFrame frame;
- frame.connection_id = TestConnectionId(1);
- frame.sequence_number = 1u;
- frame.retire_prior_to = 0u;
- frame.stateless_reset_token =
- QuicUtils::GenerateStatelessResetToken(frame.connection_id);
- ASSERT_THAT(
- peer_issued_cid_manager_.OnNewConnectionIdFrame(frame, &error_details_),
- IsQuicNoError());
- }
-
- {
- QuicNewConnectionIdFrame frame;
- frame.connection_id = TestConnectionId(2);
- frame.sequence_number = 1u;
- frame.retire_prior_to = 0u;
- frame.stateless_reset_token =
- QuicUtils::GenerateStatelessResetToken(TestConnectionId(2));
- EXPECT_THAT(
- peer_issued_cid_manager_.OnNewConnectionIdFrame(frame, &error_details_),
- IsQuicNoError());
- EXPECT_EQ(
- peer_issued_cid_manager_.ConsumeOneUnusedConnectionId()->connection_id,
- TestConnectionId(1));
- EXPECT_THAT(peer_issued_cid_manager_.ConsumeOneUnusedConnectionId(),
- IsNull());
- }
-}
-
-TEST_F(QuicPeerIssuedConnectionIdManagerTest,
- ErrorWhenThereAreTooManyGapsInIssuedConnectionIdSequenceNumbers) {
- // Add 20 intervals: [0, 1), [2, 3), ..., [38,39)
- for (int i = 2; i <= 38; i += 2) {
- QuicNewConnectionIdFrame frame;
- frame.connection_id = TestConnectionId(i);
- frame.sequence_number = i;
- frame.retire_prior_to = i;
- frame.stateless_reset_token =
- QuicUtils::GenerateStatelessResetToken(frame.connection_id);
- ASSERT_THAT(
- peer_issued_cid_manager_.OnNewConnectionIdFrame(frame, &error_details_),
- IsQuicNoError());
- }
-
- // Interval [40, 41) goes over the limit.
- QuicNewConnectionIdFrame frame;
- frame.connection_id = TestConnectionId(40);
- frame.sequence_number = 40u;
- frame.retire_prior_to = 40u;
- frame.stateless_reset_token =
- QuicUtils::GenerateStatelessResetToken(frame.connection_id);
- ASSERT_THAT(
- peer_issued_cid_manager_.OnNewConnectionIdFrame(frame, &error_details_),
- IsError(IETF_QUIC_PROTOCOL_VIOLATION));
-}
-
-TEST_F(QuicPeerIssuedConnectionIdManagerTest, ReplaceConnectionId) {
- ASSERT_TRUE(
- peer_issued_cid_manager_.IsConnectionIdActive(initial_connection_id_));
- peer_issued_cid_manager_.ReplaceConnectionId(initial_connection_id_,
- TestConnectionId(1));
- EXPECT_FALSE(
- peer_issued_cid_manager_.IsConnectionIdActive(initial_connection_id_));
- EXPECT_TRUE(
- peer_issued_cid_manager_.IsConnectionIdActive(TestConnectionId(1)));
-}
-
-class TestSelfIssuedConnectionIdManagerVisitor
- : public QuicConnectionIdManagerVisitorInterface {
- public:
- void OnPeerIssuedConnectionIdRetired() override {}
-
- MOCK_METHOD(bool,
- SendNewConnectionId,
- (const QuicNewConnectionIdFrame& frame),
- (override));
- MOCK_METHOD(void,
- OnNewConnectionIdIssued,
- (const QuicConnectionId& connection_id),
- (override));
- MOCK_METHOD(void,
- OnSelfIssuedConnectionIdRetired,
- (const QuicConnectionId& connection_id),
- (override));
-};
-
-class QuicSelfIssuedConnectionIdManagerTest : public QuicTest {
- public:
- QuicSelfIssuedConnectionIdManagerTest()
- : cid_manager_(/*active_connection_id_limit*/ 2, initial_connection_id_,
- &clock_, &alarm_factory_, &cid_manager_visitor_,
- /*context=*/nullptr) {
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
- retire_self_issued_cid_alarm_ =
- QuicConnectionIdManagerPeer::GetRetireSelfIssuedConnectionIdAlarm(
- &cid_manager_);
- }
-
- protected:
- MockClock clock_;
- test::MockAlarmFactory alarm_factory_;
- TestSelfIssuedConnectionIdManagerVisitor cid_manager_visitor_;
- QuicConnectionId initial_connection_id_ = TestConnectionId(0);
- StrictMock<QuicSelfIssuedConnectionIdManager> cid_manager_;
- QuicAlarm* retire_self_issued_cid_alarm_ = nullptr;
- std::string error_details_;
- QuicTime::Delta pto_delay_ = QuicTime::Delta::FromMilliseconds(10);
-};
-
-MATCHER_P3(ExpectedNewConnectionIdFrame,
- connection_id,
- sequence_number,
- retire_prior_to,
- "") {
- return (arg.connection_id == connection_id) &&
- (arg.sequence_number == sequence_number) &&
- (arg.retire_prior_to == retire_prior_to);
-}
-
-TEST_F(QuicSelfIssuedConnectionIdManagerTest,
- RetireSelfIssuedConnectionIdInOrder) {
- QuicConnectionId cid0 = initial_connection_id_;
- QuicConnectionId cid1 = cid_manager_.GenerateNewConnectionId(cid0);
- QuicConnectionId cid2 = cid_manager_.GenerateNewConnectionId(cid1);
- QuicConnectionId cid3 = cid_manager_.GenerateNewConnectionId(cid2);
- QuicConnectionId cid4 = cid_manager_.GenerateNewConnectionId(cid3);
- QuicConnectionId cid5 = cid_manager_.GenerateNewConnectionId(cid4);
-
- // Sends CID #1 to peer.
- EXPECT_CALL(cid_manager_visitor_, OnNewConnectionIdIssued(cid1));
- EXPECT_CALL(cid_manager_visitor_,
- SendNewConnectionId(ExpectedNewConnectionIdFrame(cid1, 1u, 0u)))
- .WillOnce(Return(true));
- cid_manager_.MaybeSendNewConnectionIds();
-
- {
- // Peer retires CID #0;
- // Sends CID #2 and asks peer to retire CIDs prior to #1.
- // Outcome: (#1, #2) are active.
- EXPECT_CALL(cid_manager_visitor_, OnNewConnectionIdIssued(cid2));
- EXPECT_CALL(cid_manager_visitor_,
- SendNewConnectionId(ExpectedNewConnectionIdFrame(cid2, 2u, 1u)))
- .WillOnce(Return(true));
- QuicRetireConnectionIdFrame retire_cid_frame;
- retire_cid_frame.sequence_number = 0u;
- ASSERT_THAT(cid_manager_.OnRetireConnectionIdFrame(
- retire_cid_frame, pto_delay_, &error_details_),
- IsQuicNoError());
- }
-
- {
- // Peer retires CID #1;
- // Sends CID #3 and asks peer to retire CIDs prior to #2.
- // Outcome: (#2, #3) are active.
- EXPECT_CALL(cid_manager_visitor_, OnNewConnectionIdIssued(cid3));
- EXPECT_CALL(cid_manager_visitor_,
- SendNewConnectionId(ExpectedNewConnectionIdFrame(cid3, 3u, 2u)))
- .WillOnce(Return(true));
- QuicRetireConnectionIdFrame retire_cid_frame;
- retire_cid_frame.sequence_number = 1u;
- ASSERT_THAT(cid_manager_.OnRetireConnectionIdFrame(
- retire_cid_frame, pto_delay_, &error_details_),
- IsQuicNoError());
- }
-
- {
- // Peer retires CID #2;
- // Sends CID #4 and asks peer to retire CIDs prior to #3.
- // Outcome: (#3, #4) are active.
- EXPECT_CALL(cid_manager_visitor_, OnNewConnectionIdIssued(cid4));
- EXPECT_CALL(cid_manager_visitor_,
- SendNewConnectionId(ExpectedNewConnectionIdFrame(cid4, 4u, 3u)))
- .WillOnce(Return(true));
- QuicRetireConnectionIdFrame retire_cid_frame;
- retire_cid_frame.sequence_number = 2u;
- ASSERT_THAT(cid_manager_.OnRetireConnectionIdFrame(
- retire_cid_frame, pto_delay_, &error_details_),
- IsQuicNoError());
- }
-
- {
- // Peer retires CID #3;
- // Sends CID #5 and asks peer to retire CIDs prior to #4.
- // Outcome: (#4, #5) are active.
- EXPECT_CALL(cid_manager_visitor_, OnNewConnectionIdIssued(cid5));
- EXPECT_CALL(cid_manager_visitor_,
- SendNewConnectionId(ExpectedNewConnectionIdFrame(cid5, 5u, 4u)))
- .WillOnce(Return(true));
- QuicRetireConnectionIdFrame retire_cid_frame;
- retire_cid_frame.sequence_number = 3u;
- ASSERT_THAT(cid_manager_.OnRetireConnectionIdFrame(
- retire_cid_frame, pto_delay_, &error_details_),
- IsQuicNoError());
- }
-}
-
-TEST_F(QuicSelfIssuedConnectionIdManagerTest,
- RetireSelfIssuedConnectionIdOutOfOrder) {
- QuicConnectionId cid0 = initial_connection_id_;
- QuicConnectionId cid1 = cid_manager_.GenerateNewConnectionId(cid0);
- QuicConnectionId cid2 = cid_manager_.GenerateNewConnectionId(cid1);
- QuicConnectionId cid3 = cid_manager_.GenerateNewConnectionId(cid2);
- QuicConnectionId cid4 = cid_manager_.GenerateNewConnectionId(cid3);
-
- // Sends CID #1 to peer.
- EXPECT_CALL(cid_manager_visitor_, OnNewConnectionIdIssued(cid1));
- EXPECT_CALL(cid_manager_visitor_,
- SendNewConnectionId(ExpectedNewConnectionIdFrame(cid1, 1u, 0u)))
- .WillOnce(Return(true));
- cid_manager_.MaybeSendNewConnectionIds();
-
- {
- // Peer retires CID #1;
- // Sends CID #2 and asks peer to retire CIDs prior to #0.
- // Outcome: (#0, #2) are active.
- EXPECT_CALL(cid_manager_visitor_, OnNewConnectionIdIssued(cid2));
- EXPECT_CALL(cid_manager_visitor_,
- SendNewConnectionId(ExpectedNewConnectionIdFrame(cid2, 2u, 0u)))
- .WillOnce(Return(true));
- QuicRetireConnectionIdFrame retire_cid_frame;
- retire_cid_frame.sequence_number = 1u;
- ASSERT_THAT(cid_manager_.OnRetireConnectionIdFrame(
- retire_cid_frame, pto_delay_, &error_details_),
- IsQuicNoError());
- }
-
- {
- // Peer retires CID #1 again. This is a no-op.
- QuicRetireConnectionIdFrame retire_cid_frame;
- retire_cid_frame.sequence_number = 1u;
- ASSERT_THAT(cid_manager_.OnRetireConnectionIdFrame(
- retire_cid_frame, pto_delay_, &error_details_),
- IsQuicNoError());
- }
-
- {
- // Peer retires CID #0;
- // Sends CID #3 and asks peer to retire CIDs prior to #2.
- // Outcome: (#2, #3) are active.
- EXPECT_CALL(cid_manager_visitor_, OnNewConnectionIdIssued(cid3));
- EXPECT_CALL(cid_manager_visitor_,
- SendNewConnectionId(ExpectedNewConnectionIdFrame(cid3, 3u, 2u)))
- .WillOnce(Return(true));
- QuicRetireConnectionIdFrame retire_cid_frame;
- retire_cid_frame.sequence_number = 0u;
- ASSERT_THAT(cid_manager_.OnRetireConnectionIdFrame(
- retire_cid_frame, pto_delay_, &error_details_),
- IsQuicNoError());
- }
-
- {
- // Peer retires CID #3;
- // Sends CID #4 and asks peer to retire CIDs prior to #2.
- // Outcome: (#2, #4) are active.
- EXPECT_CALL(cid_manager_visitor_, OnNewConnectionIdIssued(cid4));
- EXPECT_CALL(cid_manager_visitor_,
- SendNewConnectionId(ExpectedNewConnectionIdFrame(cid4, 4u, 2u)))
- .WillOnce(Return(true));
- QuicRetireConnectionIdFrame retire_cid_frame;
- retire_cid_frame.sequence_number = 3u;
- ASSERT_THAT(cid_manager_.OnRetireConnectionIdFrame(
- retire_cid_frame, pto_delay_, &error_details_),
- IsQuicNoError());
- }
-
- {
- // Peer retires CID #0 again. This is a no-op.
- QuicRetireConnectionIdFrame retire_cid_frame;
- retire_cid_frame.sequence_number = 0u;
- ASSERT_THAT(cid_manager_.OnRetireConnectionIdFrame(
- retire_cid_frame, pto_delay_, &error_details_),
- IsQuicNoError());
- }
-}
-
-TEST_F(QuicSelfIssuedConnectionIdManagerTest,
- ScheduleConnectionIdRetirementOneAtATime) {
- QuicConnectionId cid0 = initial_connection_id_;
- QuicConnectionId cid1 = cid_manager_.GenerateNewConnectionId(cid0);
- QuicConnectionId cid2 = cid_manager_.GenerateNewConnectionId(cid1);
- QuicConnectionId cid3 = cid_manager_.GenerateNewConnectionId(cid2);
- EXPECT_CALL(cid_manager_visitor_, OnNewConnectionIdIssued(_)).Times(3);
- EXPECT_CALL(cid_manager_visitor_, SendNewConnectionId(_))
- .Times(3)
- .WillRepeatedly(Return(true));
- QuicTime::Delta connection_id_expire_timeout = 3 * pto_delay_;
- QuicRetireConnectionIdFrame retire_cid_frame;
-
- // CID #1 is sent to peer.
- cid_manager_.MaybeSendNewConnectionIds();
-
- // CID #0's retirement is scheduled and CID #2 is sent to peer.
- retire_cid_frame.sequence_number = 0u;
- ASSERT_THAT(cid_manager_.OnRetireConnectionIdFrame(
- retire_cid_frame, pto_delay_, &error_details_),
- IsQuicNoError());
- // While CID #0's retirement is scheduled, it is not retired yet.
- EXPECT_THAT(cid_manager_.GetUnretiredConnectionIds(),
- ElementsAre(cid0, cid1, cid2));
- EXPECT_TRUE(retire_self_issued_cid_alarm_->IsSet());
- EXPECT_EQ(retire_self_issued_cid_alarm_->deadline(),
- clock_.ApproximateNow() + connection_id_expire_timeout);
-
- // CID #0 is actually retired.
- EXPECT_CALL(cid_manager_visitor_, OnSelfIssuedConnectionIdRetired(cid0));
- clock_.AdvanceTime(connection_id_expire_timeout);
- alarm_factory_.FireAlarm(retire_self_issued_cid_alarm_);
- EXPECT_THAT(cid_manager_.GetUnretiredConnectionIds(),
- ElementsAre(cid1, cid2));
- EXPECT_FALSE(retire_self_issued_cid_alarm_->IsSet());
-
- // CID #1's retirement is scheduled and CID #3 is sent to peer.
- retire_cid_frame.sequence_number = 1u;
- ASSERT_THAT(cid_manager_.OnRetireConnectionIdFrame(
- retire_cid_frame, pto_delay_, &error_details_),
- IsQuicNoError());
- // While CID #1's retirement is scheduled, it is not retired yet.
- EXPECT_THAT(cid_manager_.GetUnretiredConnectionIds(),
- ElementsAre(cid1, cid2, cid3));
- EXPECT_TRUE(retire_self_issued_cid_alarm_->IsSet());
- EXPECT_EQ(retire_self_issued_cid_alarm_->deadline(),
- clock_.ApproximateNow() + connection_id_expire_timeout);
-
- // CID #1 is actually retired.
- EXPECT_CALL(cid_manager_visitor_, OnSelfIssuedConnectionIdRetired(cid1));
- clock_.AdvanceTime(connection_id_expire_timeout);
- alarm_factory_.FireAlarm(retire_self_issued_cid_alarm_);
- EXPECT_THAT(cid_manager_.GetUnretiredConnectionIds(),
- ElementsAre(cid2, cid3));
- EXPECT_FALSE(retire_self_issued_cid_alarm_->IsSet());
-}
-
-TEST_F(QuicSelfIssuedConnectionIdManagerTest,
- ScheduleMultipleConnectionIdRetirement) {
- QuicConnectionId cid0 = initial_connection_id_;
- QuicConnectionId cid1 = cid_manager_.GenerateNewConnectionId(cid0);
- QuicConnectionId cid2 = cid_manager_.GenerateNewConnectionId(cid1);
- QuicConnectionId cid3 = cid_manager_.GenerateNewConnectionId(cid2);
- EXPECT_CALL(cid_manager_visitor_, OnNewConnectionIdIssued(_)).Times(3);
- EXPECT_CALL(cid_manager_visitor_, SendNewConnectionId(_))
- .Times(3)
- .WillRepeatedly(Return(true));
- QuicTime::Delta connection_id_expire_timeout = 3 * pto_delay_;
- QuicRetireConnectionIdFrame retire_cid_frame;
-
- // CID #1 is sent to peer.
- cid_manager_.MaybeSendNewConnectionIds();
-
- // CID #0's retirement is scheduled and CID #2 is sent to peer.
- retire_cid_frame.sequence_number = 0u;
- ASSERT_THAT(cid_manager_.OnRetireConnectionIdFrame(
- retire_cid_frame, pto_delay_, &error_details_),
- IsQuicNoError());
-
- clock_.AdvanceTime(connection_id_expire_timeout * 0.25);
-
- // CID #1's retirement is scheduled and CID #3 is sent to peer.
- retire_cid_frame.sequence_number = 1u;
- ASSERT_THAT(cid_manager_.OnRetireConnectionIdFrame(
- retire_cid_frame, pto_delay_, &error_details_),
- IsQuicNoError());
-
- // While CID #0, #1s retirement is scheduled, they are not retired yet.
- EXPECT_THAT(cid_manager_.GetUnretiredConnectionIds(),
- ElementsAre(cid0, cid1, cid2, cid3));
- EXPECT_TRUE(retire_self_issued_cid_alarm_->IsSet());
- EXPECT_EQ(retire_self_issued_cid_alarm_->deadline(),
- clock_.ApproximateNow() + connection_id_expire_timeout * 0.75);
-
- // CID #0 is actually retired.
- EXPECT_CALL(cid_manager_visitor_, OnSelfIssuedConnectionIdRetired(cid0));
- clock_.AdvanceTime(connection_id_expire_timeout * 0.75);
- alarm_factory_.FireAlarm(retire_self_issued_cid_alarm_);
- EXPECT_THAT(cid_manager_.GetUnretiredConnectionIds(),
- ElementsAre(cid1, cid2, cid3));
- EXPECT_TRUE(retire_self_issued_cid_alarm_->IsSet());
- EXPECT_EQ(retire_self_issued_cid_alarm_->deadline(),
- clock_.ApproximateNow() + connection_id_expire_timeout * 0.25);
-
- // CID #1 is actually retired.
- EXPECT_CALL(cid_manager_visitor_, OnSelfIssuedConnectionIdRetired(cid1));
- clock_.AdvanceTime(connection_id_expire_timeout * 0.25);
- alarm_factory_.FireAlarm(retire_self_issued_cid_alarm_);
- EXPECT_THAT(cid_manager_.GetUnretiredConnectionIds(),
- ElementsAre(cid2, cid3));
- EXPECT_FALSE(retire_self_issued_cid_alarm_->IsSet());
-}
-
-TEST_F(QuicSelfIssuedConnectionIdManagerTest,
- AllExpiredConnectionIdsAreRetiredInOneBatch) {
- QuicConnectionId cid0 = initial_connection_id_;
- QuicConnectionId cid1 = cid_manager_.GenerateNewConnectionId(cid0);
- QuicConnectionId cid2 = cid_manager_.GenerateNewConnectionId(cid1);
- QuicConnectionId cid3 = cid_manager_.GenerateNewConnectionId(cid2);
- QuicConnectionId cid;
- EXPECT_CALL(cid_manager_visitor_, OnNewConnectionIdIssued(_)).Times(3);
- EXPECT_CALL(cid_manager_visitor_, SendNewConnectionId(_))
- .Times(3)
- .WillRepeatedly(Return(true));
- QuicTime::Delta connection_id_expire_timeout = 3 * pto_delay_;
- QuicRetireConnectionIdFrame retire_cid_frame;
- EXPECT_TRUE(cid_manager_.IsConnectionIdInUse(cid0));
- EXPECT_FALSE(cid_manager_.HasConnectionIdToConsume());
- EXPECT_FALSE(cid_manager_.ConsumeOneConnectionId().has_value());
-
- // CID #1 is sent to peer.
- cid_manager_.MaybeSendNewConnectionIds();
- EXPECT_TRUE(cid_manager_.IsConnectionIdInUse(cid1));
- EXPECT_TRUE(cid_manager_.HasConnectionIdToConsume());
- cid = *cid_manager_.ConsumeOneConnectionId();
- EXPECT_EQ(cid1, cid);
- EXPECT_FALSE(cid_manager_.HasConnectionIdToConsume());
-
- // CID #0's retirement is scheduled and CID #2 is sent to peer.
- retire_cid_frame.sequence_number = 0u;
- cid_manager_.OnRetireConnectionIdFrame(retire_cid_frame, pto_delay_,
- &error_details_);
- EXPECT_TRUE(cid_manager_.IsConnectionIdInUse(cid0));
- EXPECT_TRUE(cid_manager_.IsConnectionIdInUse(cid1));
- EXPECT_TRUE(cid_manager_.IsConnectionIdInUse(cid2));
- EXPECT_TRUE(cid_manager_.HasConnectionIdToConsume());
- cid = *cid_manager_.ConsumeOneConnectionId();
- EXPECT_EQ(cid2, cid);
- EXPECT_FALSE(cid_manager_.HasConnectionIdToConsume());
-
- clock_.AdvanceTime(connection_id_expire_timeout * 0.1);
-
- // CID #1's retirement is scheduled and CID #3 is sent to peer.
- retire_cid_frame.sequence_number = 1u;
- cid_manager_.OnRetireConnectionIdFrame(retire_cid_frame, pto_delay_,
- &error_details_);
-
- {
- // CID #0 & #1 are retired in a single alarm fire.
- clock_.AdvanceTime(connection_id_expire_timeout);
- testing::InSequence s;
- EXPECT_CALL(cid_manager_visitor_, OnSelfIssuedConnectionIdRetired(cid0));
- EXPECT_CALL(cid_manager_visitor_, OnSelfIssuedConnectionIdRetired(cid1));
- alarm_factory_.FireAlarm(retire_self_issued_cid_alarm_);
- EXPECT_FALSE(cid_manager_.IsConnectionIdInUse(cid0));
- EXPECT_FALSE(cid_manager_.IsConnectionIdInUse(cid1));
- EXPECT_TRUE(cid_manager_.IsConnectionIdInUse(cid2));
- EXPECT_THAT(cid_manager_.GetUnretiredConnectionIds(),
- ElementsAre(cid2, cid3));
- EXPECT_FALSE(retire_self_issued_cid_alarm_->IsSet());
- }
-}
-
-TEST_F(QuicSelfIssuedConnectionIdManagerTest,
- ErrorWhenRetireConnectionIdNeverIssued) {
- QuicConnectionId cid0 = initial_connection_id_;
- QuicConnectionId cid1 = cid_manager_.GenerateNewConnectionId(cid0);
-
- // CID #1 is sent to peer.
- EXPECT_CALL(cid_manager_visitor_, OnNewConnectionIdIssued(_)).Times(1);
- EXPECT_CALL(cid_manager_visitor_, SendNewConnectionId(_))
- .WillOnce(Return(true));
- cid_manager_.MaybeSendNewConnectionIds();
-
- // CID #2 is never issued.
- QuicRetireConnectionIdFrame retire_cid_frame;
- retire_cid_frame.sequence_number = 2u;
- ASSERT_THAT(cid_manager_.OnRetireConnectionIdFrame(
- retire_cid_frame, pto_delay_, &error_details_),
- IsError(IETF_QUIC_PROTOCOL_VIOLATION));
-}
-
-TEST_F(QuicSelfIssuedConnectionIdManagerTest,
- ErrorWhenTooManyConnectionIdWaitingToBeRetired) {
- // CID #0 & #1 are issued.
- EXPECT_CALL(cid_manager_visitor_, OnNewConnectionIdIssued(_));
- EXPECT_CALL(cid_manager_visitor_, SendNewConnectionId(_))
- .WillOnce(Return(true));
- cid_manager_.MaybeSendNewConnectionIds();
-
- // Add 8 connection IDs to the to-be-retired list.
- QuicConnectionId last_connection_id =
- cid_manager_.GenerateNewConnectionId(initial_connection_id_);
- for (int i = 0; i < 8; ++i) {
- EXPECT_CALL(cid_manager_visitor_, OnNewConnectionIdIssued(_));
- EXPECT_CALL(cid_manager_visitor_, SendNewConnectionId(_));
- QuicRetireConnectionIdFrame retire_cid_frame;
- retire_cid_frame.sequence_number = i;
- ASSERT_THAT(cid_manager_.OnRetireConnectionIdFrame(
- retire_cid_frame, pto_delay_, &error_details_),
- IsQuicNoError());
- last_connection_id =
- cid_manager_.GenerateNewConnectionId(last_connection_id);
- }
- QuicRetireConnectionIdFrame retire_cid_frame;
- retire_cid_frame.sequence_number = 8u;
- // This would have push the number of to-be-retired connection IDs over its
- // limit.
- ASSERT_THAT(cid_manager_.OnRetireConnectionIdFrame(
- retire_cid_frame, pto_delay_, &error_details_),
- IsError(QUIC_TOO_MANY_CONNECTION_ID_WAITING_TO_RETIRE));
-}
-
-TEST_F(QuicSelfIssuedConnectionIdManagerTest,
- DoNotIssueConnectionIdVoluntarilyIfOneHasIssuedForPerferredAddress) {
- QuicConnectionId cid0 = initial_connection_id_;
- QuicConnectionId cid1 = cid_manager_.GenerateNewConnectionId(cid0);
- EXPECT_CALL(cid_manager_visitor_, OnNewConnectionIdIssued(cid1));
- ASSERT_THAT(cid_manager_.IssueNewConnectionIdForPreferredAddress(),
- ExpectedNewConnectionIdFrame(cid1, 1u, 0u));
- EXPECT_THAT(cid_manager_.GetUnretiredConnectionIds(),
- ElementsAre(cid0, cid1));
-
- EXPECT_CALL(cid_manager_visitor_, OnNewConnectionIdIssued(_)).Times(0);
- EXPECT_CALL(cid_manager_visitor_, SendNewConnectionId(_)).Times(0);
- cid_manager_.MaybeSendNewConnectionIds();
-}
-
-} // namespace
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_connection_id_test.cc b/chromium/net/third_party/quiche/src/quic/core/quic_connection_id_test.cc
deleted file mode 100644
index 3effb3483c1..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_connection_id_test.cc
+++ /dev/null
@@ -1,154 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_connection_id.h"
-
-#include <cstdint>
-#include <cstring>
-#include <string>
-
-#include "absl/base/macros.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/quic_test_utils.h"
-
-namespace quic {
-
-namespace {
-
-class QuicConnectionIdTest : public QuicTest {};
-
-TEST_F(QuicConnectionIdTest, Empty) {
- QuicConnectionId connection_id_empty = EmptyQuicConnectionId();
- EXPECT_TRUE(connection_id_empty.IsEmpty());
-}
-
-TEST_F(QuicConnectionIdTest, DefaultIsEmpty) {
- QuicConnectionId connection_id_empty = QuicConnectionId();
- EXPECT_TRUE(connection_id_empty.IsEmpty());
-}
-
-TEST_F(QuicConnectionIdTest, NotEmpty) {
- QuicConnectionId connection_id = test::TestConnectionId(1);
- EXPECT_FALSE(connection_id.IsEmpty());
-}
-
-TEST_F(QuicConnectionIdTest, ZeroIsNotEmpty) {
- QuicConnectionId connection_id = test::TestConnectionId(0);
- EXPECT_FALSE(connection_id.IsEmpty());
-}
-
-TEST_F(QuicConnectionIdTest, Data) {
- char connection_id_data[kQuicDefaultConnectionIdLength];
- memset(connection_id_data, 0x42, sizeof(connection_id_data));
- QuicConnectionId connection_id1 =
- QuicConnectionId(connection_id_data, sizeof(connection_id_data));
- QuicConnectionId connection_id2 =
- QuicConnectionId(connection_id_data, sizeof(connection_id_data));
- EXPECT_EQ(connection_id1, connection_id2);
- EXPECT_EQ(connection_id1.length(), kQuicDefaultConnectionIdLength);
- EXPECT_EQ(connection_id1.data(), connection_id1.mutable_data());
- EXPECT_EQ(0, memcmp(connection_id1.data(), connection_id2.data(),
- sizeof(connection_id_data)));
- EXPECT_EQ(0, memcmp(connection_id1.data(), connection_id_data,
- sizeof(connection_id_data)));
- connection_id2.mutable_data()[0] = 0x33;
- EXPECT_NE(connection_id1, connection_id2);
- static const uint8_t kNewLength = 4;
- connection_id2.set_length(kNewLength);
- EXPECT_EQ(kNewLength, connection_id2.length());
-}
-
-TEST_F(QuicConnectionIdTest, DoubleConvert) {
- QuicConnectionId connection_id64_1 = test::TestConnectionId(1);
- QuicConnectionId connection_id64_2 = test::TestConnectionId(42);
- QuicConnectionId connection_id64_3 =
- test::TestConnectionId(UINT64_C(0xfedcba9876543210));
- EXPECT_EQ(connection_id64_1,
- test::TestConnectionId(
- test::TestConnectionIdToUInt64(connection_id64_1)));
- EXPECT_EQ(connection_id64_2,
- test::TestConnectionId(
- test::TestConnectionIdToUInt64(connection_id64_2)));
- EXPECT_EQ(connection_id64_3,
- test::TestConnectionId(
- test::TestConnectionIdToUInt64(connection_id64_3)));
- EXPECT_NE(connection_id64_1, connection_id64_2);
- EXPECT_NE(connection_id64_1, connection_id64_3);
- EXPECT_NE(connection_id64_2, connection_id64_3);
-}
-
-TEST_F(QuicConnectionIdTest, Hash) {
- QuicConnectionId connection_id64_1 = test::TestConnectionId(1);
- QuicConnectionId connection_id64_1b = test::TestConnectionId(1);
- QuicConnectionId connection_id64_2 = test::TestConnectionId(42);
- QuicConnectionId connection_id64_3 =
- test::TestConnectionId(UINT64_C(0xfedcba9876543210));
- EXPECT_EQ(connection_id64_1.Hash(), connection_id64_1b.Hash());
- EXPECT_NE(connection_id64_1.Hash(), connection_id64_2.Hash());
- EXPECT_NE(connection_id64_1.Hash(), connection_id64_3.Hash());
- EXPECT_NE(connection_id64_2.Hash(), connection_id64_3.Hash());
-
- // Verify that any two all-zero connection IDs of different lengths never
- // have the same hash.
- const char connection_id_bytes[255] = {};
- for (uint8_t i = 0; i < sizeof(connection_id_bytes) - 1; ++i) {
- QuicConnectionId connection_id_i(connection_id_bytes, i);
- for (uint8_t j = i + 1; j < sizeof(connection_id_bytes); ++j) {
- QuicConnectionId connection_id_j(connection_id_bytes, j);
- EXPECT_NE(connection_id_i.Hash(), connection_id_j.Hash());
- }
- }
-}
-
-TEST_F(QuicConnectionIdTest, AssignAndCopy) {
- QuicConnectionId connection_id = test::TestConnectionId(1);
- QuicConnectionId connection_id2 = test::TestConnectionId(2);
- connection_id = connection_id2;
- EXPECT_EQ(connection_id, test::TestConnectionId(2));
- EXPECT_NE(connection_id, test::TestConnectionId(1));
- connection_id = QuicConnectionId(test::TestConnectionId(1));
- EXPECT_EQ(connection_id, test::TestConnectionId(1));
- EXPECT_NE(connection_id, test::TestConnectionId(2));
-}
-
-TEST_F(QuicConnectionIdTest, ChangeLength) {
- QuicConnectionId connection_id64_1 = test::TestConnectionId(1);
- QuicConnectionId connection_id64_2 = test::TestConnectionId(2);
- QuicConnectionId connection_id136_2 = test::TestConnectionId(2);
- connection_id136_2.set_length(17);
- memset(connection_id136_2.mutable_data() + 8, 0, 9);
- char connection_id136_2_bytes[17] = {0, 0, 0, 0, 0, 0, 0, 2, 0,
- 0, 0, 0, 0, 0, 0, 0, 0};
- QuicConnectionId connection_id136_2b(connection_id136_2_bytes,
- sizeof(connection_id136_2_bytes));
- EXPECT_EQ(connection_id136_2, connection_id136_2b);
- QuicConnectionId connection_id = connection_id64_1;
- connection_id.set_length(17);
- EXPECT_NE(connection_id64_1, connection_id);
- // Check resizing big to small.
- connection_id.set_length(8);
- EXPECT_EQ(connection_id64_1, connection_id);
- // Check resizing small to big.
- connection_id.set_length(17);
- memset(connection_id.mutable_data(), 0, connection_id.length());
- memcpy(connection_id.mutable_data(), connection_id64_2.data(),
- connection_id64_2.length());
- EXPECT_EQ(connection_id136_2, connection_id);
- EXPECT_EQ(connection_id136_2b, connection_id);
- QuicConnectionId connection_id120(connection_id136_2_bytes, 15);
- connection_id.set_length(15);
- EXPECT_EQ(connection_id120, connection_id);
- // Check resizing big to big.
- QuicConnectionId connection_id2 = connection_id120;
- connection_id2.set_length(17);
- connection_id2.mutable_data()[15] = 0;
- connection_id2.mutable_data()[16] = 0;
- EXPECT_EQ(connection_id136_2, connection_id2);
- EXPECT_EQ(connection_id136_2b, connection_id2);
-}
-
-} // namespace
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_connection_stats.cc b/chromium/net/third_party/quiche/src/quic/core/quic_connection_stats.cc
deleted file mode 100644
index fbaa20abd94..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_connection_stats.cc
+++ /dev/null
@@ -1,72 +0,0 @@
-// Copyright 2013 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 "quic/core/quic_connection_stats.h"
-
-namespace quic {
-
-std::ostream& operator<<(std::ostream& os, const QuicConnectionStats& s) {
- os << "{ bytes_sent: " << s.bytes_sent;
- os << " packets_sent: " << s.packets_sent;
- os << " stream_bytes_sent: " << s.stream_bytes_sent;
- os << " packets_discarded: " << s.packets_discarded;
- os << " bytes_received: " << s.bytes_received;
- os << " packets_received: " << s.packets_received;
- os << " packets_processed: " << s.packets_processed;
- os << " stream_bytes_received: " << s.stream_bytes_received;
- os << " bytes_retransmitted: " << s.bytes_retransmitted;
- os << " packets_retransmitted: " << s.packets_retransmitted;
- os << " bytes_spuriously_retransmitted: " << s.bytes_spuriously_retransmitted;
- os << " packets_spuriously_retransmitted: "
- << s.packets_spuriously_retransmitted;
- os << " packets_lost: " << s.packets_lost;
- os << " slowstart_packets_sent: " << s.slowstart_packets_sent;
- os << " slowstart_packets_lost: " << s.slowstart_packets_lost;
- os << " slowstart_bytes_lost: " << s.slowstart_bytes_lost;
- os << " packets_dropped: " << s.packets_dropped;
- os << " undecryptable_packets_received_before_handshake_complete: "
- << s.undecryptable_packets_received_before_handshake_complete;
- os << " crypto_retransmit_count: " << s.crypto_retransmit_count;
- os << " loss_timeout_count: " << s.loss_timeout_count;
- os << " tlp_count: " << s.tlp_count;
- os << " rto_count: " << s.rto_count;
- os << " pto_count: " << s.pto_count;
- os << " min_rtt_us: " << s.min_rtt_us;
- os << " srtt_us: " << s.srtt_us;
- os << " egress_mtu: " << s.egress_mtu;
- os << " max_egress_mtu: " << s.max_egress_mtu;
- os << " ingress_mtu: " << s.ingress_mtu;
- os << " estimated_bandwidth: " << s.estimated_bandwidth;
- os << " packets_reordered: " << s.packets_reordered;
- os << " max_sequence_reordering: " << s.max_sequence_reordering;
- os << " max_time_reordering_us: " << s.max_time_reordering_us;
- os << " tcp_loss_events: " << s.tcp_loss_events;
- os << " connection_creation_time: "
- << s.connection_creation_time.ToDebuggingValue();
- os << " blocked_frames_received: " << s.blocked_frames_received;
- os << " blocked_frames_sent: " << s.blocked_frames_sent;
- os << " num_connectivity_probing_received: "
- << s.num_connectivity_probing_received;
- os << " retry_packet_processed: "
- << (s.retry_packet_processed ? "yes" : "no");
- os << " num_coalesced_packets_received: " << s.num_coalesced_packets_received;
- os << " num_coalesced_packets_processed: "
- << s.num_coalesced_packets_processed;
- os << " num_ack_aggregation_epochs: " << s.num_ack_aggregation_epochs;
- os << " sent_legacy_version_encapsulated_packets: "
- << s.sent_legacy_version_encapsulated_packets;
- os << " key_update_count: " << s.key_update_count;
- os << " num_failed_authentication_packets_received: "
- << s.num_failed_authentication_packets_received;
- os << " num_tls_server_zero_rtt_packets_received_after_discarding_decrypter: "
- << s.num_tls_server_zero_rtt_packets_received_after_discarding_decrypter;
- os << " address_validated_via_decrypting_packet: "
- << s.address_validated_via_decrypting_packet;
- os << " address_validated_via_token: " << s.address_validated_via_token;
- os << " }";
-
- return os;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_connection_stats.h b/chromium/net/third_party/quiche/src/quic/core/quic_connection_stats.h
deleted file mode 100644
index 39fd5b087a6..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_connection_stats.h
+++ /dev/null
@@ -1,241 +0,0 @@
-// Copyright 2013 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_CONNECTION_STATS_H_
-#define QUICHE_QUIC_CORE_QUIC_CONNECTION_STATS_H_
-
-#include <cstdint>
-#include <ostream>
-
-#include "quic/core/quic_bandwidth.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_time.h"
-#include "quic/core/quic_time_accumulator.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// Structure to hold stats for a QuicConnection.
-struct QUIC_EXPORT_PRIVATE QuicConnectionStats {
- QUIC_EXPORT_PRIVATE friend std::ostream& operator<<(
- std::ostream& os,
- const QuicConnectionStats& s);
-
- QuicByteCount bytes_sent = 0; // Includes retransmissions.
- QuicPacketCount packets_sent = 0;
- // Non-retransmitted bytes sent in a stream frame.
- QuicByteCount stream_bytes_sent = 0;
- // Packets serialized and discarded before sending.
- QuicPacketCount packets_discarded = 0;
-
- // These include version negotiation and public reset packets, which do not
- // have packet numbers or frame data.
- QuicByteCount bytes_received = 0; // Includes duplicate data for a stream.
- // Includes packets which were not processable.
- QuicPacketCount packets_received = 0;
- // Excludes packets which were not processable.
- QuicPacketCount packets_processed = 0;
- QuicByteCount stream_bytes_received = 0; // Bytes received in a stream frame.
-
- QuicByteCount bytes_retransmitted = 0;
- QuicPacketCount packets_retransmitted = 0;
-
- QuicByteCount bytes_spuriously_retransmitted = 0;
- QuicPacketCount packets_spuriously_retransmitted = 0;
- // Number of packets abandoned as lost by the loss detection algorithm.
- QuicPacketCount packets_lost = 0;
- QuicPacketCount packet_spuriously_detected_lost = 0;
-
- // The sum of loss detection response times of all lost packets, in number of
- // round trips.
- // Given a packet detected as lost:
- // T(S) T(1Rtt) T(D)
- // |_________________________________|_______|
- // Where
- // T(S) is the time when the packet is sent.
- // T(1Rtt) is one rtt after T(S), using the rtt at the time of detection.
- // T(D) is the time of detection, i.e. when the packet is declared as lost.
- // The loss detection response time is defined as
- // (T(D) - T(S)) / (T(1Rtt) - T(S))
- //
- // The average loss detection response time is this number divided by
- // |packets_lost|. Smaller result means detection is faster.
- float total_loss_detection_response_time = 0.0;
-
- // Number of times this connection went through the slow start phase.
- uint32_t slowstart_count = 0;
- // Number of round trips spent in slow start.
- uint32_t slowstart_num_rtts = 0;
- // Number of packets sent in slow start.
- QuicPacketCount slowstart_packets_sent = 0;
- // Number of bytes sent in slow start.
- QuicByteCount slowstart_bytes_sent = 0;
- // Number of packets lost exiting slow start.
- QuicPacketCount slowstart_packets_lost = 0;
- // Number of bytes lost exiting slow start.
- QuicByteCount slowstart_bytes_lost = 0;
- // Time spent in slow start. Populated for BBRv1 and BBRv2.
- QuicTimeAccumulator slowstart_duration;
-
- // Number of PROBE_BW cycles. Populated for BBRv1 and BBRv2.
- uint32_t bbr_num_cycles = 0;
- // Number of PROBE_BW cycles shortened for reno coexistence. BBRv2 only.
- uint32_t bbr_num_short_cycles_for_reno_coexistence = 0;
- // Whether BBR exited STARTUP due to excessive loss. Populated for BBRv1 and
- // BBRv2.
- bool bbr_exit_startup_due_to_loss = false;
-
- QuicPacketCount packets_dropped = 0; // Duplicate or less than least unacked.
-
- // Packets that failed to decrypt when they were first received,
- // before the handshake was complete.
- QuicPacketCount undecryptable_packets_received_before_handshake_complete = 0;
-
- size_t crypto_retransmit_count = 0;
- // Count of times the loss detection alarm fired. At least one packet should
- // be lost when the alarm fires.
- size_t loss_timeout_count = 0;
- size_t tlp_count = 0;
- size_t rto_count = 0; // Count of times the rto timer fired.
- size_t pto_count = 0;
-
- int64_t min_rtt_us = 0; // Minimum RTT in microseconds.
- int64_t srtt_us = 0; // Smoothed RTT in microseconds.
- int64_t cwnd_bootstrapping_rtt_us = 0; // RTT used in cwnd_bootstrapping.
- // The connection's |long_term_mtu_| used for sending packets, populated by
- // QuicConnection::GetStats().
- QuicByteCount egress_mtu = 0;
- // The maximum |long_term_mtu_| the connection ever used.
- QuicByteCount max_egress_mtu = 0;
- // Size of the largest packet received from the peer, populated by
- // QuicConnection::GetStats().
- QuicByteCount ingress_mtu = 0;
- QuicBandwidth estimated_bandwidth = QuicBandwidth::Zero();
-
- // Reordering stats for received packets.
- // Number of packets received out of packet number order.
- QuicPacketCount packets_reordered = 0;
- // Maximum reordering observed in packet number space.
- QuicPacketCount max_sequence_reordering = 0;
- // Maximum reordering observed in microseconds
- int64_t max_time_reordering_us = 0;
-
- // Maximum sequence reordering observed from acked packets.
- QuicPacketCount sent_packets_max_sequence_reordering = 0;
- // Number of times that a packet is not detected as lost per reordering_shift,
- // but would have been if the reordering_shift increases by one.
- QuicPacketCount sent_packets_num_borderline_time_reorderings = 0;
-
- // The following stats are used only in TcpCubicSender.
- // The number of loss events from TCP's perspective. Each loss event includes
- // one or more lost packets.
- uint32_t tcp_loss_events = 0;
-
- // Creation time, as reported by the QuicClock.
- QuicTime connection_creation_time = QuicTime::Zero();
-
- // Handshake completion time.
- QuicTime handshake_completion_time = QuicTime::Zero();
-
- uint64_t blocked_frames_received = 0;
- uint64_t blocked_frames_sent = 0;
-
- // Number of connectivity probing packets received by this connection.
- uint64_t num_connectivity_probing_received = 0;
-
- // Whether a RETRY packet was successfully processed.
- bool retry_packet_processed = false;
-
- // Number of received coalesced packets.
- uint64_t num_coalesced_packets_received = 0;
- // Number of successfully processed coalesced packets.
- uint64_t num_coalesced_packets_processed = 0;
- // Number of ack aggregation epochs. For the same number of bytes acked, the
- // smaller this value, the more ack aggregation is going on.
- uint64_t num_ack_aggregation_epochs = 0;
-
- // Whether overshooting is detected (and pacing rate decreases) during start
- // up with network parameters adjusted.
- bool overshooting_detected_with_network_parameters_adjusted = false;
-
- // Whether there is any non app-limited bandwidth sample.
- bool has_non_app_limited_sample = false;
-
- // Packet number of first decrypted packet.
- QuicPacketNumber first_decrypted_packet;
-
- // Max consecutive retransmission timeout before making forward progress.
- size_t max_consecutive_rto_with_forward_progress = 0;
-
- // Number of sent packets that were encapsulated using Legacy Version
- // Encapsulation.
- QuicPacketCount sent_legacy_version_encapsulated_packets = 0;
-
- // Number of times when the connection tries to send data but gets throttled
- // by amplification factor.
- size_t num_amplification_throttling = 0;
-
- // Number of key phase updates that have occurred. In the case of a locally
- // initiated key update, this is incremented when the keys are updated, before
- // the peer has acknowledged the key update.
- uint32_t key_update_count = 0;
-
- // Counts the number of undecryptable packets received across all keys. Does
- // not include packets where a decryption key for that level was absent.
- QuicPacketCount num_failed_authentication_packets_received = 0;
-
- // Counts the number of QUIC+TLS 0-RTT packets received after 0-RTT decrypter
- // was discarded, only on server connections.
- QuicPacketCount
- num_tls_server_zero_rtt_packets_received_after_discarding_decrypter = 0;
-
- // True if address is validated via decrypting HANDSHAKE or 1-RTT packet.
- bool address_validated_via_decrypting_packet = false;
-
- // True if address is validated via validating token received in INITIAL
- // packet.
- bool address_validated_via_token = false;
-
- size_t ping_frames_sent = 0;
-
- // Number of detected peer address changes which changes to a peer address
- // validated by earlier path validation.
- size_t num_peer_migration_to_proactively_validated_address = 0;
- // Number of detected peer address changes which triggers reverse path
- // validation.
- size_t num_reverse_path_validtion_upon_migration = 0;
- // Number of detected peer migrations which either succeed reverse path
- // validation or no need to be validated.
- size_t num_validated_peer_migration = 0;
- // Number of detected peer migrations which triggered reverse path validation
- // and failed and fell back to the old path.
- size_t num_invalid_peer_migration = 0;
- // Number of detected peer migrations which triggered reverse path validation
- // which was canceled because the peer migrated again. Such migration is also
- // counted as invalid peer migration.
- size_t num_peer_migration_while_validating_default_path = 0;
- // Number of NEW_CONNECTION_ID frames sent.
- size_t num_new_connection_id_sent = 0;
- // Number of RETIRE_CONNECTION_ID frames sent.
- size_t num_retire_connection_id_sent = 0;
-
- struct QUIC_NO_EXPORT TlsServerOperationStats {
- bool success = false;
- // If the operation is performed asynchronously, how long did it take.
- // Zero() for synchronous operations.
- QuicTime::Delta async_latency = QuicTime::Delta::Zero();
- };
-
- // The TLS server op stats only have values when the corresponding operation
- // is performed by TlsServerHandshaker. If an operation is done within
- // BoringSSL, e.g. ticket decrypted without using
- // TlsServerHandshaker::SessionTicketOpen, it will not be recorded here.
- absl::optional<TlsServerOperationStats> tls_server_select_cert_stats;
- absl::optional<TlsServerOperationStats> tls_server_compute_signature_stats;
- absl::optional<TlsServerOperationStats> tls_server_decrypt_ticket_stats;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_QUIC_CONNECTION_STATS_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_connection_test.cc b/chromium/net/third_party/quiche/src/quic/core/quic_connection_test.cc
deleted file mode 100644
index fba066caf68..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_connection_test.cc
+++ /dev/null
@@ -1,15297 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_connection.h"
-
-#include <errno.h>
-
-#include <memory>
-#include <ostream>
-#include <string>
-#include <utility>
-
-#include "absl/base/macros.h"
-#include "absl/strings/str_cat.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/congestion_control/loss_detection_interface.h"
-#include "quic/core/congestion_control/send_algorithm_interface.h"
-#include "quic/core/crypto/null_decrypter.h"
-#include "quic/core/crypto/null_encrypter.h"
-#include "quic/core/crypto/quic_decrypter.h"
-#include "quic/core/crypto/quic_encrypter.h"
-#include "quic/core/frames/quic_connection_close_frame.h"
-#include "quic/core/frames/quic_new_connection_id_frame.h"
-#include "quic/core/frames/quic_path_response_frame.h"
-#include "quic/core/frames/quic_rst_stream_frame.h"
-#include "quic/core/quic_connection_id.h"
-#include "quic/core/quic_constants.h"
-#include "quic/core/quic_error_codes.h"
-#include "quic/core/quic_packet_creator.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_path_validator.h"
-#include "quic/core/quic_simple_buffer_allocator.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_utils.h"
-#include "quic/core/quic_versions.h"
-#include "quic/platform/api/quic_error_code_wrappers.h"
-#include "quic/platform/api/quic_expect_bug.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_ip_address.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/platform/api/quic_reference_counted.h"
-#include "quic/platform/api/quic_socket_address.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/mock_clock.h"
-#include "quic/test_tools/mock_random.h"
-#include "quic/test_tools/quic_config_peer.h"
-#include "quic/test_tools/quic_connection_peer.h"
-#include "quic/test_tools/quic_framer_peer.h"
-#include "quic/test_tools/quic_packet_creator_peer.h"
-#include "quic/test_tools/quic_path_validator_peer.h"
-#include "quic/test_tools/quic_sent_packet_manager_peer.h"
-#include "quic/test_tools/quic_test_utils.h"
-#include "quic/test_tools/simple_data_producer.h"
-#include "quic/test_tools/simple_session_notifier.h"
-
-using testing::_;
-using testing::AnyNumber;
-using testing::AtLeast;
-using testing::DoAll;
-using testing::ElementsAre;
-using testing::Ge;
-using testing::IgnoreResult;
-using testing::InSequence;
-using testing::Invoke;
-using testing::InvokeWithoutArgs;
-using testing::Lt;
-using testing::Ref;
-using testing::Return;
-using testing::SaveArg;
-using testing::SetArgPointee;
-using testing::StrictMock;
-
-namespace quic {
-namespace test {
-namespace {
-
-const char data1[] = "foo data";
-const char data2[] = "bar data";
-
-const bool kHasStopWaiting = true;
-
-const int kDefaultRetransmissionTimeMs = 500;
-
-DiversificationNonce kTestDiversificationNonce = {
- 'a', 'b', 'a', 'b', 'a', 'b', 'a', 'b', 'a', 'b', 'a',
- 'b', 'a', 'b', 'a', 'b', 'a', 'b', 'a', 'b', 'a', 'b',
- 'a', 'b', 'a', 'b', 'a', 'b', 'a', 'b', 'a', 'b',
-};
-
-const StatelessResetToken kTestStatelessResetToken{
- 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
- 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f};
-
-const QuicSocketAddress kPeerAddress =
- QuicSocketAddress(QuicIpAddress::Loopback6(),
- /*port=*/12345);
-const QuicSocketAddress kSelfAddress =
- QuicSocketAddress(QuicIpAddress::Loopback6(),
- /*port=*/443);
-
-QuicStreamId GetNthClientInitiatedStreamId(int n,
- QuicTransportVersion version) {
- return QuicUtils::GetFirstBidirectionalStreamId(version,
- Perspective::IS_CLIENT) +
- n * 2;
-}
-
-QuicLongHeaderType EncryptionlevelToLongHeaderType(EncryptionLevel level) {
- switch (level) {
- case ENCRYPTION_INITIAL:
- return INITIAL;
- case ENCRYPTION_HANDSHAKE:
- return HANDSHAKE;
- case ENCRYPTION_ZERO_RTT:
- return ZERO_RTT_PROTECTED;
- case ENCRYPTION_FORWARD_SECURE:
- QUICHE_DCHECK(false);
- return INVALID_PACKET_TYPE;
- default:
- QUICHE_DCHECK(false);
- return INVALID_PACKET_TYPE;
- }
-}
-
-// A NullEncrypterWithConfidentialityLimit is a NullEncrypter that allows
-// specifying the confidentiality limit on the maximum number of packets that
-// may be encrypted per key phase in TLS+QUIC.
-class NullEncrypterWithConfidentialityLimit : public NullEncrypter {
- public:
- NullEncrypterWithConfidentialityLimit(Perspective perspective,
- QuicPacketCount confidentiality_limit)
- : NullEncrypter(perspective),
- confidentiality_limit_(confidentiality_limit) {}
-
- QuicPacketCount GetConfidentialityLimit() const override {
- return confidentiality_limit_;
- }
-
- private:
- QuicPacketCount confidentiality_limit_;
-};
-
-class StrictTaggingDecrypterWithIntegrityLimit : public StrictTaggingDecrypter {
- public:
- StrictTaggingDecrypterWithIntegrityLimit(uint8_t tag,
- QuicPacketCount integrity_limit)
- : StrictTaggingDecrypter(tag), integrity_limit_(integrity_limit) {}
-
- QuicPacketCount GetIntegrityLimit() const override {
- return integrity_limit_;
- }
-
- private:
- QuicPacketCount integrity_limit_;
-};
-
-class TestConnectionHelper : public QuicConnectionHelperInterface {
- public:
- TestConnectionHelper(MockClock* clock, MockRandom* random_generator)
- : clock_(clock), random_generator_(random_generator) {
- clock_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
- }
- TestConnectionHelper(const TestConnectionHelper&) = delete;
- TestConnectionHelper& operator=(const TestConnectionHelper&) = delete;
-
- // QuicConnectionHelperInterface
- const QuicClock* GetClock() const override { return clock_; }
-
- QuicRandom* GetRandomGenerator() override { return random_generator_; }
-
- QuicBufferAllocator* GetStreamSendBufferAllocator() override {
- return &buffer_allocator_;
- }
-
- private:
- MockClock* clock_;
- MockRandom* random_generator_;
- SimpleBufferAllocator buffer_allocator_;
-};
-
-class TestConnection : public QuicConnection {
- public:
- TestConnection(QuicConnectionId connection_id,
- QuicSocketAddress initial_self_address,
- QuicSocketAddress initial_peer_address,
- TestConnectionHelper* helper, TestAlarmFactory* alarm_factory,
- TestPacketWriter* writer, Perspective perspective,
- ParsedQuicVersion version)
- : QuicConnection(connection_id, initial_self_address,
- initial_peer_address, helper, alarm_factory, writer,
- /* owns_writer= */ false, perspective,
- SupportedVersions(version)),
- notifier_(nullptr) {
- writer->set_perspective(perspective);
- SetEncrypter(ENCRYPTION_FORWARD_SECURE,
- std::make_unique<NullEncrypter>(perspective));
- SetDataProducer(&producer_);
- }
- TestConnection(const TestConnection&) = delete;
- TestConnection& operator=(const TestConnection&) = delete;
-
- void SetSendAlgorithm(SendAlgorithmInterface* send_algorithm) {
- QuicConnectionPeer::SetSendAlgorithm(this, send_algorithm);
- }
-
- void SetLossAlgorithm(LossDetectionInterface* loss_algorithm) {
- QuicConnectionPeer::SetLossAlgorithm(this, loss_algorithm);
- }
-
- void SendPacket(EncryptionLevel /*level*/, uint64_t packet_number,
- std::unique_ptr<QuicPacket> packet,
- HasRetransmittableData retransmittable, bool has_ack,
- bool has_pending_frames) {
- ScopedPacketFlusher flusher(this);
- char buffer[kMaxOutgoingPacketSize];
- size_t encrypted_length =
- QuicConnectionPeer::GetFramer(this)->EncryptPayload(
- ENCRYPTION_INITIAL, QuicPacketNumber(packet_number), *packet,
- buffer, kMaxOutgoingPacketSize);
- SerializedPacket serialized_packet(
- QuicPacketNumber(packet_number), PACKET_4BYTE_PACKET_NUMBER, buffer,
- encrypted_length, has_ack, has_pending_frames);
- serialized_packet.peer_address = kPeerAddress;
- if (retransmittable == HAS_RETRANSMITTABLE_DATA) {
- serialized_packet.retransmittable_frames.push_back(
- QuicFrame(QuicPingFrame()));
- }
- OnSerializedPacket(std::move(serialized_packet));
- }
-
- QuicConsumedData SaveAndSendStreamData(QuicStreamId id,
- const struct iovec* iov, int iov_count,
- size_t total_length,
- QuicStreamOffset offset,
- StreamSendingState state) {
- ScopedPacketFlusher flusher(this);
- producer_.SaveStreamData(id, iov, iov_count, 0u, total_length);
- if (notifier_ != nullptr) {
- return notifier_->WriteOrBufferData(id, total_length, state);
- }
- return QuicConnection::SendStreamData(id, total_length, offset, state);
- }
-
- QuicConsumedData SendStreamDataWithString(QuicStreamId id,
- absl::string_view data,
- QuicStreamOffset offset,
- StreamSendingState state) {
- ScopedPacketFlusher flusher(this);
- if (!QuicUtils::IsCryptoStreamId(transport_version(), id) &&
- this->encryption_level() == ENCRYPTION_INITIAL) {
- this->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
- if (perspective() == Perspective::IS_CLIENT && !IsHandshakeComplete()) {
- OnHandshakeComplete();
- }
- if (version().SupportsAntiAmplificationLimit()) {
- QuicConnectionPeer::SetAddressValidated(this);
- }
- }
- struct iovec iov;
- MakeIOVector(data, &iov);
- return SaveAndSendStreamData(id, &iov, 1, data.length(), offset, state);
- }
-
- QuicConsumedData SendApplicationDataAtLevel(EncryptionLevel encryption_level,
- QuicStreamId id,
- absl::string_view data,
- QuicStreamOffset offset,
- StreamSendingState state) {
- ScopedPacketFlusher flusher(this);
- QUICHE_DCHECK(encryption_level >= ENCRYPTION_ZERO_RTT);
- SetEncrypter(encryption_level, std::make_unique<TaggingEncrypter>(0x01));
- SetDefaultEncryptionLevel(encryption_level);
- struct iovec iov;
- MakeIOVector(data, &iov);
- return SaveAndSendStreamData(id, &iov, 1, data.length(), offset, state);
- }
-
- QuicConsumedData SendStreamData3() {
- return SendStreamDataWithString(
- GetNthClientInitiatedStreamId(1, transport_version()), "food", 0,
- NO_FIN);
- }
-
- QuicConsumedData SendStreamData5() {
- return SendStreamDataWithString(
- GetNthClientInitiatedStreamId(2, transport_version()), "food2", 0,
- NO_FIN);
- }
-
- // Ensures the connection can write stream data before writing.
- QuicConsumedData EnsureWritableAndSendStreamData5() {
- EXPECT_TRUE(CanWrite(HAS_RETRANSMITTABLE_DATA));
- return SendStreamData5();
- }
-
- // The crypto stream has special semantics so that it is not blocked by a
- // congestion window limitation, and also so that it gets put into a separate
- // packet (so that it is easier to reason about a crypto frame not being
- // split needlessly across packet boundaries). As a result, we have separate
- // tests for some cases for this stream.
- QuicConsumedData SendCryptoStreamData() {
- QuicStreamOffset offset = 0;
- absl::string_view data("chlo");
- if (!QuicVersionUsesCryptoFrames(transport_version())) {
- return SendCryptoDataWithString(data, offset);
- }
- producer_.SaveCryptoData(ENCRYPTION_INITIAL, offset, data);
- size_t bytes_written;
- if (notifier_) {
- bytes_written =
- notifier_->WriteCryptoData(ENCRYPTION_INITIAL, data.length(), offset);
- } else {
- bytes_written = QuicConnection::SendCryptoData(ENCRYPTION_INITIAL,
- data.length(), offset);
- }
- return QuicConsumedData(bytes_written, /*fin_consumed*/ false);
- }
-
- QuicConsumedData SendCryptoDataWithString(absl::string_view data,
- QuicStreamOffset offset) {
- return SendCryptoDataWithString(data, offset, ENCRYPTION_INITIAL);
- }
-
- QuicConsumedData SendCryptoDataWithString(absl::string_view data,
- QuicStreamOffset offset,
- EncryptionLevel encryption_level) {
- if (!QuicVersionUsesCryptoFrames(transport_version())) {
- return SendStreamDataWithString(
- QuicUtils::GetCryptoStreamId(transport_version()), data, offset,
- NO_FIN);
- }
- producer_.SaveCryptoData(encryption_level, offset, data);
- size_t bytes_written;
- if (notifier_) {
- bytes_written =
- notifier_->WriteCryptoData(encryption_level, data.length(), offset);
- } else {
- bytes_written = QuicConnection::SendCryptoData(encryption_level,
- data.length(), offset);
- }
- return QuicConsumedData(bytes_written, /*fin_consumed*/ false);
- }
-
- void set_version(ParsedQuicVersion version) {
- QuicConnectionPeer::GetFramer(this)->set_version(version);
- }
-
- void SetSupportedVersions(const ParsedQuicVersionVector& versions) {
- QuicConnectionPeer::GetFramer(this)->SetSupportedVersions(versions);
- writer()->SetSupportedVersions(versions);
- }
-
- // This should be called before setting customized encrypters/decrypters for
- // connection and peer creator.
- void set_perspective(Perspective perspective) {
- writer()->set_perspective(perspective);
- QuicConnectionPeer::ResetPeerIssuedConnectionIdManager(this);
- QuicConnectionPeer::SetPerspective(this, perspective);
- QuicSentPacketManagerPeer::SetPerspective(
- QuicConnectionPeer::GetSentPacketManager(this), perspective);
- QuicConnectionPeer::GetFramer(this)->SetInitialObfuscators(
- TestConnectionId());
- for (EncryptionLevel level : {ENCRYPTION_ZERO_RTT, ENCRYPTION_HANDSHAKE,
- ENCRYPTION_FORWARD_SECURE}) {
- if (QuicConnectionPeer::GetFramer(this)->HasEncrypterOfEncryptionLevel(
- level)) {
- SetEncrypter(level, std::make_unique<NullEncrypter>(perspective));
- }
- if (QuicConnectionPeer::GetFramer(this)->HasDecrypterOfEncryptionLevel(
- level)) {
- InstallDecrypter(level, std::make_unique<NullDecrypter>(perspective));
- }
- }
- }
-
- // Enable path MTU discovery. Assumes that the test is performed from the
- // server perspective and the higher value of MTU target is used.
- void EnablePathMtuDiscovery(MockSendAlgorithm* send_algorithm) {
- ASSERT_EQ(Perspective::IS_SERVER, perspective());
-
- if (GetQuicReloadableFlag(quic_enable_mtu_discovery_at_server)) {
- OnConfigNegotiated();
- } else {
- QuicConfig config;
- QuicTagVector connection_options;
- connection_options.push_back(kMTUH);
- config.SetInitialReceivedConnectionOptions(connection_options);
- EXPECT_CALL(*send_algorithm, SetFromConfig(_, _));
- SetFromConfig(config);
- }
-
- // Normally, the pacing would be disabled in the test, but calling
- // SetFromConfig enables it. Set nearly-infinite bandwidth to make the
- // pacing algorithm work.
- EXPECT_CALL(*send_algorithm, PacingRate(_))
- .WillRepeatedly(Return(QuicBandwidth::Infinite()));
- }
-
- TestAlarmFactory::TestAlarm* GetAckAlarm() {
- return reinterpret_cast<TestAlarmFactory::TestAlarm*>(
- QuicConnectionPeer::GetAckAlarm(this));
- }
-
- TestAlarmFactory::TestAlarm* GetPingAlarm() {
- return reinterpret_cast<TestAlarmFactory::TestAlarm*>(
- QuicConnectionPeer::GetPingAlarm(this));
- }
-
- TestAlarmFactory::TestAlarm* GetRetransmissionAlarm() {
- return reinterpret_cast<TestAlarmFactory::TestAlarm*>(
- QuicConnectionPeer::GetRetransmissionAlarm(this));
- }
-
- TestAlarmFactory::TestAlarm* GetSendAlarm() {
- return reinterpret_cast<TestAlarmFactory::TestAlarm*>(
- QuicConnectionPeer::GetSendAlarm(this));
- }
-
- TestAlarmFactory::TestAlarm* GetTimeoutAlarm() {
- return reinterpret_cast<TestAlarmFactory::TestAlarm*>(
- QuicConnectionPeer::GetIdleNetworkDetectorAlarm(this));
- }
-
- TestAlarmFactory::TestAlarm* GetMtuDiscoveryAlarm() {
- return reinterpret_cast<TestAlarmFactory::TestAlarm*>(
- QuicConnectionPeer::GetMtuDiscoveryAlarm(this));
- }
-
- TestAlarmFactory::TestAlarm* GetProcessUndecryptablePacketsAlarm() {
- return reinterpret_cast<TestAlarmFactory::TestAlarm*>(
- QuicConnectionPeer::GetProcessUndecryptablePacketsAlarm(this));
- }
-
- TestAlarmFactory::TestAlarm* GetDiscardPreviousOneRttKeysAlarm() {
- return reinterpret_cast<TestAlarmFactory::TestAlarm*>(
- QuicConnectionPeer::GetDiscardPreviousOneRttKeysAlarm(this));
- }
-
- TestAlarmFactory::TestAlarm* GetDiscardZeroRttDecryptionKeysAlarm() {
- return reinterpret_cast<TestAlarmFactory::TestAlarm*>(
- QuicConnectionPeer::GetDiscardZeroRttDecryptionKeysAlarm(this));
- }
-
- TestAlarmFactory::TestAlarm* GetBlackholeDetectorAlarm() {
- return reinterpret_cast<TestAlarmFactory::TestAlarm*>(
- QuicConnectionPeer::GetBlackholeDetectorAlarm(this));
- }
-
- TestAlarmFactory::TestAlarm* GetRetirePeerIssuedConnectionIdAlarm() {
- return reinterpret_cast<TestAlarmFactory::TestAlarm*>(
- QuicConnectionPeer::GetRetirePeerIssuedConnectionIdAlarm(this));
- }
-
- TestAlarmFactory::TestAlarm* GetRetireSelfIssuedConnectionIdAlarm() {
- return reinterpret_cast<TestAlarmFactory::TestAlarm*>(
- QuicConnectionPeer::GetRetireSelfIssuedConnectionIdAlarm(this));
- }
-
- void PathDegradingTimeout() {
- QUICHE_DCHECK(PathDegradingDetectionInProgress());
- GetBlackholeDetectorAlarm()->Fire();
- }
-
- bool PathDegradingDetectionInProgress() {
- return QuicConnectionPeer::GetPathDegradingDeadline(this).IsInitialized();
- }
-
- bool BlackholeDetectionInProgress() {
- return QuicConnectionPeer::GetBlackholeDetectionDeadline(this)
- .IsInitialized();
- }
-
- bool PathMtuReductionDetectionInProgress() {
- return QuicConnectionPeer::GetPathMtuReductionDetectionDeadline(this)
- .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();
- }
-
- void set_notifier(SimpleSessionNotifier* notifier) { notifier_ = notifier; }
-
- void ReturnEffectivePeerAddressForNextPacket(const QuicSocketAddress& addr) {
- next_effective_peer_addr_ = std::make_unique<QuicSocketAddress>(addr);
- }
-
- bool PtoEnabled() {
- if (QuicConnectionPeer::GetSentPacketManager(this)->pto_enabled()) {
- // PTO mode is default enabled for T099. And TLP/RTO related tests are
- // stale.
- QUICHE_DCHECK(PROTOCOL_TLS1_3 == version().handshake_protocol ||
- GetQuicReloadableFlag(quic_default_on_pto));
- return true;
- }
- return false;
- }
-
- void SendOrQueuePacket(SerializedPacket packet) override {
- QuicConnection::SendOrQueuePacket(std::move(packet));
- self_address_on_default_path_while_sending_packet_ = self_address();
- }
-
- QuicSocketAddress self_address_on_default_path_while_sending_packet() {
- return self_address_on_default_path_while_sending_packet_;
- }
-
- SimpleDataProducer* producer() { return &producer_; }
-
- 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:
- QuicSocketAddress GetEffectivePeerAddressFromCurrentPacket() const override {
- if (next_effective_peer_addr_) {
- return *std::move(next_effective_peer_addr_);
- }
- return QuicConnection::GetEffectivePeerAddressFromCurrentPacket();
- }
-
- private:
- TestPacketWriter* writer() {
- return static_cast<TestPacketWriter*>(QuicConnection::writer());
- }
-
- SimpleDataProducer producer_;
-
- SimpleSessionNotifier* notifier_;
-
- std::unique_ptr<QuicSocketAddress> next_effective_peer_addr_;
-
- QuicSocketAddress self_address_on_default_path_while_sending_packet_;
-};
-
-enum class AckResponse { kDefer, kImmediate };
-
-// Run tests with combinations of {ParsedQuicVersion, AckResponse}.
-struct TestParams {
- TestParams(ParsedQuicVersion version, AckResponse ack_response,
- bool no_stop_waiting)
- : version(version),
- ack_response(ack_response),
- no_stop_waiting(no_stop_waiting) {}
-
- ParsedQuicVersion version;
- AckResponse ack_response;
- bool no_stop_waiting;
-};
-
-// Used by ::testing::PrintToStringParamName().
-std::string PrintToString(const TestParams& p) {
- return absl::StrCat(
- ParsedQuicVersionToString(p.version), "_",
- (p.ack_response == AckResponse::kDefer ? "defer" : "immediate"), "_",
- (p.no_stop_waiting ? "No" : ""), "StopWaiting");
-}
-
-// Constructs various test permutations.
-std::vector<TestParams> GetTestParams() {
- QuicFlagSaver flags;
- std::vector<TestParams> params;
- ParsedQuicVersionVector all_supported_versions = AllSupportedVersions();
- for (size_t i = 0; i < all_supported_versions.size(); ++i) {
- for (AckResponse ack_response :
- {AckResponse::kDefer, AckResponse::kImmediate}) {
- params.push_back(
- TestParams(all_supported_versions[i], ack_response, true));
- if (!all_supported_versions[i].HasIetfInvariantHeader()) {
- params.push_back(
- TestParams(all_supported_versions[i], ack_response, false));
- }
- }
- }
- return params;
-}
-
-class QuicConnectionTest : public QuicTestWithParam<TestParams> {
- public:
- // For tests that do silent connection closes, no such packet is generated. In
- // order to verify the contents of the OnConnectionClosed upcall, EXPECTs
- // should invoke this method, saving the frame, and then the test can verify
- // the contents.
- void SaveConnectionCloseFrame(const QuicConnectionCloseFrame& frame,
- ConnectionCloseSource /*source*/) {
- saved_connection_close_frame_ = frame;
- connection_close_frame_count_++;
- }
-
- protected:
- QuicConnectionTest()
- : connection_id_(TestConnectionId()),
- framer_(SupportedVersions(version()), QuicTime::Zero(),
- Perspective::IS_CLIENT, connection_id_.length()),
- send_algorithm_(new StrictMock<MockSendAlgorithm>),
- loss_algorithm_(new MockLossAlgorithm()),
- helper_(new TestConnectionHelper(&clock_, &random_generator_)),
- alarm_factory_(new TestAlarmFactory()),
- peer_framer_(SupportedVersions(version()), QuicTime::Zero(),
- Perspective::IS_SERVER, connection_id_.length()),
- peer_creator_(connection_id_, &peer_framer_,
- /*delegate=*/nullptr),
- writer_(
- new TestPacketWriter(version(), &clock_, Perspective::IS_CLIENT)),
- connection_(connection_id_, kSelfAddress, kPeerAddress, helper_.get(),
- alarm_factory_.get(), writer_.get(), Perspective::IS_CLIENT,
- version()),
- creator_(QuicConnectionPeer::GetPacketCreator(&connection_)),
- manager_(QuicConnectionPeer::GetSentPacketManager(&connection_)),
- frame1_(0, false, 0, absl::string_view(data1)),
- frame2_(0, false, 3, absl::string_view(data2)),
- crypto_frame_(ENCRYPTION_INITIAL, 0, absl::string_view(data1)),
- packet_number_length_(PACKET_4BYTE_PACKET_NUMBER),
- connection_id_included_(CONNECTION_ID_PRESENT),
- notifier_(&connection_),
- connection_close_frame_count_(0) {
- QUIC_DVLOG(2) << "QuicConnectionTest(" << PrintToString(GetParam()) << ")";
- connection_.set_defer_send_in_response_to_packets(GetParam().ack_response ==
- AckResponse::kDefer);
- framer_.SetInitialObfuscators(TestConnectionId());
- connection_.InstallInitialCrypters(TestConnectionId());
- CrypterPair crypters;
- CryptoUtils::CreateInitialObfuscators(Perspective::IS_SERVER, version(),
- TestConnectionId(), &crypters);
- peer_creator_.SetEncrypter(ENCRYPTION_INITIAL,
- std::move(crypters.encrypter));
- if (version().KnowsWhichDecrypterToUse()) {
- peer_framer_.InstallDecrypter(ENCRYPTION_INITIAL,
- std::move(crypters.decrypter));
- } else {
- peer_framer_.SetDecrypter(ENCRYPTION_INITIAL,
- std::move(crypters.decrypter));
- }
- for (EncryptionLevel level :
- {ENCRYPTION_ZERO_RTT, ENCRYPTION_FORWARD_SECURE}) {
- peer_creator_.SetEncrypter(
- level, std::make_unique<NullEncrypter>(peer_framer_.perspective()));
- }
- QuicFramerPeer::SetLastSerializedServerConnectionId(
- QuicConnectionPeer::GetFramer(&connection_), connection_id_);
- QuicFramerPeer::SetLastWrittenPacketNumberLength(
- QuicConnectionPeer::GetFramer(&connection_), packet_number_length_);
- if (version().HasIetfInvariantHeader()) {
- EXPECT_TRUE(QuicConnectionPeer::GetNoStopWaitingFrames(&connection_));
- } else {
- QuicConnectionPeer::SetNoStopWaitingFrames(&connection_,
- GetParam().no_stop_waiting);
- }
- QuicStreamId stream_id;
- if (QuicVersionUsesCryptoFrames(version().transport_version)) {
- stream_id = QuicUtils::GetFirstBidirectionalStreamId(
- version().transport_version, Perspective::IS_CLIENT);
- } else {
- stream_id = QuicUtils::GetCryptoStreamId(version().transport_version);
- }
- frame1_.stream_id = stream_id;
- frame2_.stream_id = stream_id;
- connection_.set_visitor(&visitor_);
- connection_.SetSessionNotifier(&notifier_);
- connection_.set_notifier(&notifier_);
- connection_.SetSendAlgorithm(send_algorithm_);
- connection_.SetLossAlgorithm(loss_algorithm_.get());
- EXPECT_CALL(*send_algorithm_, CanSend(_)).WillRepeatedly(Return(true));
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
- .Times(AnyNumber());
- EXPECT_CALL(*send_algorithm_, OnPacketNeutered(_)).Times(AnyNumber());
- EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
- .WillRepeatedly(Return(kDefaultTCPMSS));
- EXPECT_CALL(*send_algorithm_, PacingRate(_))
- .WillRepeatedly(Return(QuicBandwidth::Zero()));
- EXPECT_CALL(*send_algorithm_, BandwidthEstimate())
- .Times(AnyNumber())
- .WillRepeatedly(Return(QuicBandwidth::Zero()));
- EXPECT_CALL(*send_algorithm_, PopulateConnectionStats(_))
- .Times(AnyNumber());
- EXPECT_CALL(*send_algorithm_, InSlowStart()).Times(AnyNumber());
- EXPECT_CALL(*send_algorithm_, InRecovery()).Times(AnyNumber());
- EXPECT_CALL(*send_algorithm_, GetCongestionControlType())
- .Times(AnyNumber());
- EXPECT_CALL(*send_algorithm_, OnApplicationLimited(_)).Times(AnyNumber());
- EXPECT_CALL(*send_algorithm_, GetCongestionControlType())
- .Times(AnyNumber());
- EXPECT_CALL(visitor_, WillingAndAbleToWrite()).Times(AnyNumber());
- EXPECT_CALL(visitor_, OnPacketDecrypted(_)).Times(AnyNumber());
- EXPECT_CALL(visitor_, OnCanWrite())
- .WillRepeatedly(Invoke(&notifier_, &SimpleSessionNotifier::OnCanWrite));
- EXPECT_CALL(visitor_, ShouldKeepConnectionAlive())
- .WillRepeatedly(Return(false));
- EXPECT_CALL(visitor_, OnCongestionWindowChange(_)).Times(AnyNumber());
- EXPECT_CALL(visitor_, OnPacketReceived(_, _, _)).Times(AnyNumber());
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_)).Times(AnyNumber());
- EXPECT_CALL(visitor_, OnOneRttPacketAcknowledged())
- .Times(testing::AtMost(1));
- EXPECT_CALL(*loss_algorithm_, GetLossTimeout())
- .WillRepeatedly(Return(QuicTime::Zero()));
- EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _))
- .Times(AnyNumber());
- EXPECT_CALL(visitor_, GetHandshakeState())
- .WillRepeatedly(Return(HANDSHAKE_START));
- if (connection_.version().KnowsWhichDecrypterToUse()) {
- connection_.InstallDecrypter(
- ENCRYPTION_FORWARD_SECURE,
- std::make_unique<NullDecrypter>(Perspective::IS_CLIENT));
- }
- peer_creator_.SetDefaultPeerAddress(kSelfAddress);
- }
-
- QuicConnectionTest(const QuicConnectionTest&) = delete;
- QuicConnectionTest& operator=(const QuicConnectionTest&) = delete;
-
- ParsedQuicVersion version() { return GetParam().version; }
-
- QuicStopWaitingFrame* stop_waiting() {
- QuicConnectionPeer::PopulateStopWaitingFrame(&connection_, &stop_waiting_);
- return &stop_waiting_;
- }
-
- QuicPacketNumber least_unacked() {
- if (writer_->stop_waiting_frames().empty()) {
- return QuicPacketNumber();
- }
- return writer_->stop_waiting_frames()[0].least_unacked;
- }
-
- void use_tagging_decrypter() { writer_->use_tagging_decrypter(); }
-
- void SetClientConnectionId(const QuicConnectionId& client_connection_id) {
- connection_.set_client_connection_id(client_connection_id);
- writer_->framer()->framer()->SetExpectedClientConnectionIdLength(
- client_connection_id.length());
- }
-
- void SetDecrypter(EncryptionLevel level,
- std::unique_ptr<QuicDecrypter> decrypter) {
- if (connection_.version().KnowsWhichDecrypterToUse()) {
- connection_.InstallDecrypter(level, std::move(decrypter));
- } else {
- connection_.SetDecrypter(level, std::move(decrypter));
- }
- }
-
- void ProcessPacket(uint64_t number) {
- EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
- ProcessDataPacket(number);
- if (connection_.GetSendAlarm()->IsSet()) {
- connection_.GetSendAlarm()->Fire();
- }
- }
-
- void ProcessReceivedPacket(const QuicSocketAddress& self_address,
- const QuicSocketAddress& peer_address,
- const QuicReceivedPacket& packet) {
- connection_.ProcessUdpPacket(self_address, peer_address, packet);
- if (connection_.GetSendAlarm()->IsSet()) {
- connection_.GetSendAlarm()->Fire();
- }
- }
-
- QuicFrame MakeCryptoFrame() const {
- if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
- return QuicFrame(new QuicCryptoFrame(crypto_frame_));
- }
- return QuicFrame(QuicStreamFrame(
- QuicUtils::GetCryptoStreamId(connection_.transport_version()), false,
- 0u, absl::string_view()));
- }
-
- void ProcessFramePacket(QuicFrame frame) {
- ProcessFramePacketWithAddresses(frame, kSelfAddress, kPeerAddress,
- ENCRYPTION_FORWARD_SECURE);
- }
-
- void ProcessFramePacketWithAddresses(QuicFrame frame,
- QuicSocketAddress self_address,
- QuicSocketAddress peer_address,
- EncryptionLevel level) {
- QuicFrames frames;
- frames.push_back(QuicFrame(frame));
- return ProcessFramesPacketWithAddresses(frames, self_address, peer_address,
- level);
- }
-
- std::unique_ptr<QuicReceivedPacket> ConstructPacket(QuicFrames frames,
- EncryptionLevel level,
- char* buffer,
- size_t buffer_len) {
- QUICHE_DCHECK(peer_framer_.HasEncrypterOfEncryptionLevel(level));
- peer_creator_.set_encryption_level(level);
- QuicPacketCreatorPeer::SetSendVersionInPacket(
- &peer_creator_,
- level < ENCRYPTION_FORWARD_SECURE &&
- connection_.perspective() == Perspective::IS_SERVER);
-
- SerializedPacket serialized_packet =
- QuicPacketCreatorPeer::SerializeAllFrames(&peer_creator_, frames,
- buffer, buffer_len);
- return std::make_unique<QuicReceivedPacket>(
- serialized_packet.encrypted_buffer, serialized_packet.encrypted_length,
- clock_.Now());
- }
-
- void ProcessFramesPacketWithAddresses(QuicFrames frames,
- QuicSocketAddress self_address,
- QuicSocketAddress peer_address,
- EncryptionLevel level) {
- char buffer[kMaxOutgoingPacketSize];
- connection_.ProcessUdpPacket(
- self_address, peer_address,
- *ConstructPacket(std::move(frames), level, buffer,
- kMaxOutgoingPacketSize));
- if (connection_.GetSendAlarm()->IsSet()) {
- connection_.GetSendAlarm()->Fire();
- }
- }
-
- // Bypassing the packet creator is unrealistic, but allows us to process
- // packets the QuicPacketCreator won't allow us to create.
- void ForceProcessFramePacket(QuicFrame frame) {
- QuicFrames frames;
- frames.push_back(QuicFrame(frame));
- bool send_version = connection_.perspective() == Perspective::IS_SERVER;
- if (connection_.version().KnowsWhichDecrypterToUse()) {
- send_version = true;
- }
- QuicPacketCreatorPeer::SetSendVersionInPacket(&peer_creator_, send_version);
- QuicPacketHeader header;
- QuicPacketCreatorPeer::FillPacketHeader(&peer_creator_, &header);
- char encrypted_buffer[kMaxOutgoingPacketSize];
- size_t length = peer_framer_.BuildDataPacket(
- header, frames, encrypted_buffer, kMaxOutgoingPacketSize,
- ENCRYPTION_INITIAL);
- QUICHE_DCHECK_GT(length, 0u);
-
- const size_t encrypted_length = peer_framer_.EncryptInPlace(
- ENCRYPTION_INITIAL, header.packet_number,
- GetStartOfEncryptedData(peer_framer_.version().transport_version,
- header),
- length, kMaxOutgoingPacketSize, encrypted_buffer);
- QUICHE_DCHECK_GT(encrypted_length, 0u);
-
- connection_.ProcessUdpPacket(
- kSelfAddress, kPeerAddress,
- QuicReceivedPacket(encrypted_buffer, encrypted_length, clock_.Now()));
- }
-
- size_t ProcessFramePacketAtLevel(uint64_t number, QuicFrame frame,
- EncryptionLevel level) {
- QuicFrames frames;
- frames.push_back(frame);
- return ProcessFramesPacketAtLevel(number, frames, level);
- }
-
- size_t ProcessFramesPacketAtLevel(uint64_t number, const QuicFrames& frames,
- EncryptionLevel level) {
- QuicPacketHeader header = ConstructPacketHeader(number, level);
- // Set the correct encryption level and encrypter on peer_creator and
- // peer_framer, respectively.
- peer_creator_.set_encryption_level(level);
- if (QuicPacketCreatorPeer::GetEncryptionLevel(&peer_creator_) >
- ENCRYPTION_INITIAL) {
- peer_framer_.SetEncrypter(
- QuicPacketCreatorPeer::GetEncryptionLevel(&peer_creator_),
- std::make_unique<TaggingEncrypter>(0x01));
- // Set the corresponding decrypter.
- if (connection_.version().KnowsWhichDecrypterToUse()) {
- connection_.InstallDecrypter(
- QuicPacketCreatorPeer::GetEncryptionLevel(&peer_creator_),
- std::make_unique<StrictTaggingDecrypter>(0x01));
- } else {
- connection_.SetDecrypter(
- QuicPacketCreatorPeer::GetEncryptionLevel(&peer_creator_),
- std::make_unique<StrictTaggingDecrypter>(0x01));
- }
- }
- std::unique_ptr<QuicPacket> packet(ConstructPacket(header, frames));
-
- char buffer[kMaxOutgoingPacketSize];
- size_t encrypted_length =
- peer_framer_.EncryptPayload(level, QuicPacketNumber(number), *packet,
- buffer, kMaxOutgoingPacketSize);
- connection_.ProcessUdpPacket(
- kSelfAddress, kPeerAddress,
- QuicReceivedPacket(buffer, encrypted_length, clock_.Now(), false));
- if (connection_.GetSendAlarm()->IsSet()) {
- connection_.GetSendAlarm()->Fire();
- }
- return encrypted_length;
- }
-
- struct PacketInfo {
- PacketInfo(uint64_t packet_number, QuicFrames frames, EncryptionLevel level)
- : packet_number(packet_number), frames(frames), level(level) {}
-
- uint64_t packet_number;
- QuicFrames frames;
- EncryptionLevel level;
- };
-
- size_t ProcessCoalescedPacket(std::vector<PacketInfo> packets) {
- char coalesced_buffer[kMaxOutgoingPacketSize];
- size_t coalesced_size = 0;
- bool contains_initial = false;
- for (const auto& packet : packets) {
- QuicPacketHeader header =
- ConstructPacketHeader(packet.packet_number, packet.level);
- // Set the correct encryption level and encrypter on peer_creator and
- // peer_framer, respectively.
- peer_creator_.set_encryption_level(packet.level);
- if (packet.level == ENCRYPTION_INITIAL) {
- contains_initial = true;
- }
- if (QuicPacketCreatorPeer::GetEncryptionLevel(&peer_creator_) >
- ENCRYPTION_INITIAL) {
- peer_framer_.SetEncrypter(
- QuicPacketCreatorPeer::GetEncryptionLevel(&peer_creator_),
- std::make_unique<TaggingEncrypter>(0x01));
- // Set the corresponding decrypter.
- if (connection_.version().KnowsWhichDecrypterToUse()) {
- connection_.InstallDecrypter(
- QuicPacketCreatorPeer::GetEncryptionLevel(&peer_creator_),
- std::make_unique<StrictTaggingDecrypter>(0x01));
- } else {
- connection_.SetDecrypter(
- QuicPacketCreatorPeer::GetEncryptionLevel(&peer_creator_),
- std::make_unique<StrictTaggingDecrypter>(0x01));
- }
- }
- std::unique_ptr<QuicPacket> constructed_packet(
- ConstructPacket(header, packet.frames));
-
- char buffer[kMaxOutgoingPacketSize];
- size_t encrypted_length = peer_framer_.EncryptPayload(
- packet.level, QuicPacketNumber(packet.packet_number),
- *constructed_packet, buffer, kMaxOutgoingPacketSize);
- QUICHE_DCHECK_LE(coalesced_size + encrypted_length,
- kMaxOutgoingPacketSize);
- memcpy(coalesced_buffer + coalesced_size, buffer, encrypted_length);
- coalesced_size += encrypted_length;
- }
- if (contains_initial) {
- // Padded coalesced packet to full if it contains initial packet.
- memset(coalesced_buffer + coalesced_size, '0',
- kMaxOutgoingPacketSize - coalesced_size);
- }
- connection_.ProcessUdpPacket(
- kSelfAddress, kPeerAddress,
- QuicReceivedPacket(coalesced_buffer, coalesced_size, clock_.Now(),
- false));
- if (connection_.GetSendAlarm()->IsSet()) {
- connection_.GetSendAlarm()->Fire();
- }
- return coalesced_size;
- }
-
- size_t ProcessDataPacket(uint64_t number) {
- return ProcessDataPacketAtLevel(number, false, ENCRYPTION_FORWARD_SECURE);
- }
-
- size_t ProcessDataPacket(QuicPacketNumber packet_number) {
- return ProcessDataPacketAtLevel(packet_number, false,
- ENCRYPTION_FORWARD_SECURE);
- }
-
- size_t ProcessDataPacketAtLevel(QuicPacketNumber packet_number,
- bool has_stop_waiting,
- EncryptionLevel level) {
- return ProcessDataPacketAtLevel(packet_number.ToUint64(), has_stop_waiting,
- level);
- }
-
- size_t ProcessCryptoPacketAtLevel(uint64_t number, EncryptionLevel level) {
- QuicPacketHeader header = ConstructPacketHeader(number, level);
- QuicFrames frames;
- if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
- frames.push_back(QuicFrame(&crypto_frame_));
- } else {
- frames.push_back(QuicFrame(frame1_));
- }
- if (level == ENCRYPTION_INITIAL) {
- frames.push_back(QuicFrame(QuicPaddingFrame(-1)));
- }
- std::unique_ptr<QuicPacket> packet = ConstructPacket(header, frames);
- char buffer[kMaxOutgoingPacketSize];
- peer_creator_.set_encryption_level(level);
- size_t encrypted_length =
- peer_framer_.EncryptPayload(level, QuicPacketNumber(number), *packet,
- buffer, kMaxOutgoingPacketSize);
- connection_.ProcessUdpPacket(
- kSelfAddress, kPeerAddress,
- QuicReceivedPacket(buffer, encrypted_length, clock_.Now(), false));
- if (connection_.GetSendAlarm()->IsSet()) {
- connection_.GetSendAlarm()->Fire();
- }
- return encrypted_length;
- }
-
- size_t ProcessDataPacketAtLevel(uint64_t number, bool has_stop_waiting,
- EncryptionLevel level) {
- std::unique_ptr<QuicPacket> packet(
- ConstructDataPacket(number, has_stop_waiting, level));
- char buffer[kMaxOutgoingPacketSize];
- peer_creator_.set_encryption_level(level);
- size_t encrypted_length =
- peer_framer_.EncryptPayload(level, QuicPacketNumber(number), *packet,
- buffer, kMaxOutgoingPacketSize);
- connection_.ProcessUdpPacket(
- kSelfAddress, kPeerAddress,
- QuicReceivedPacket(buffer, encrypted_length, clock_.Now(), false));
- if (connection_.GetSendAlarm()->IsSet()) {
- connection_.GetSendAlarm()->Fire();
- }
- return encrypted_length;
- }
-
- void ProcessClosePacket(uint64_t number) {
- std::unique_ptr<QuicPacket> packet(ConstructClosePacket(number));
- char buffer[kMaxOutgoingPacketSize];
- size_t encrypted_length = peer_framer_.EncryptPayload(
- ENCRYPTION_FORWARD_SECURE, QuicPacketNumber(number), *packet, buffer,
- kMaxOutgoingPacketSize);
- connection_.ProcessUdpPacket(
- kSelfAddress, kPeerAddress,
- QuicReceivedPacket(buffer, encrypted_length, QuicTime::Zero(), false));
- }
-
- QuicByteCount SendStreamDataToPeer(QuicStreamId id, absl::string_view data,
- QuicStreamOffset offset,
- StreamSendingState state,
- QuicPacketNumber* last_packet) {
- QuicByteCount packet_size;
- // Save the last packet's size.
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
- .Times(AnyNumber())
- .WillRepeatedly(SaveArg<3>(&packet_size));
- connection_.SendStreamDataWithString(id, data, offset, state);
- if (last_packet != nullptr) {
- *last_packet = creator_->packet_number();
- }
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
- .Times(AnyNumber());
- return packet_size;
- }
-
- void SendAckPacketToPeer() {
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
- {
- QuicConnection::ScopedPacketFlusher flusher(&connection_);
- connection_.SendAck();
- }
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
- .Times(AnyNumber());
- }
-
- void SendRstStream(QuicStreamId id, QuicRstStreamErrorCode error,
- QuicStreamOffset bytes_written) {
- notifier_.WriteOrBufferRstStream(id, error, bytes_written);
- connection_.OnStreamReset(id, error);
- }
-
- void SendPing() { notifier_.WriteOrBufferPing(); }
-
- MessageStatus SendMessage(absl::string_view message) {
- connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
- QuicMemSlice slice(QuicBuffer::Copy(
- connection_.helper()->GetStreamSendBufferAllocator(), message));
- return connection_.SendMessage(1, absl::MakeSpan(&slice, 1), false);
- }
-
- void ProcessAckPacket(uint64_t packet_number, QuicAckFrame* frame) {
- if (packet_number > 1) {
- QuicPacketCreatorPeer::SetPacketNumber(&peer_creator_, packet_number - 1);
- } else {
- QuicPacketCreatorPeer::ClearPacketNumber(&peer_creator_);
- }
- ProcessFramePacket(QuicFrame(frame));
- }
-
- void ProcessAckPacket(QuicAckFrame* frame) {
- ProcessFramePacket(QuicFrame(frame));
- }
-
- void ProcessStopWaitingPacket(QuicStopWaitingFrame frame) {
- ProcessFramePacket(QuicFrame(frame));
- }
-
- size_t ProcessStopWaitingPacketAtLevel(uint64_t number,
- QuicStopWaitingFrame frame,
- EncryptionLevel /*level*/) {
- return ProcessFramePacketAtLevel(number, QuicFrame(frame),
- ENCRYPTION_ZERO_RTT);
- }
-
- void ProcessGoAwayPacket(QuicGoAwayFrame* frame) {
- ProcessFramePacket(QuicFrame(frame));
- }
-
- bool IsMissing(uint64_t number) {
- return IsAwaitingPacket(connection_.ack_frame(), QuicPacketNumber(number),
- QuicPacketNumber());
- }
-
- std::unique_ptr<QuicPacket> ConstructPacket(const QuicPacketHeader& header,
- const QuicFrames& frames) {
- auto packet = BuildUnsizedDataPacket(&peer_framer_, header, frames);
- EXPECT_NE(nullptr, packet.get());
- return packet;
- }
-
- QuicPacketHeader ConstructPacketHeader(uint64_t number,
- EncryptionLevel level) {
- QuicPacketHeader header;
- if (peer_framer_.version().HasIetfInvariantHeader() &&
- level < ENCRYPTION_FORWARD_SECURE) {
- // Set long header type accordingly.
- header.version_flag = true;
- header.form = IETF_QUIC_LONG_HEADER_PACKET;
- header.long_packet_type = EncryptionlevelToLongHeaderType(level);
- if (QuicVersionHasLongHeaderLengths(
- peer_framer_.version().transport_version)) {
- header.length_length = VARIABLE_LENGTH_INTEGER_LENGTH_2;
- if (header.long_packet_type == INITIAL) {
- header.retry_token_length_length = VARIABLE_LENGTH_INTEGER_LENGTH_1;
- }
- }
- }
- // Set connection_id to peer's in memory representation as this data packet
- // is created by peer_framer.
- if (peer_framer_.perspective() == Perspective::IS_SERVER) {
- header.source_connection_id = connection_id_;
- header.source_connection_id_included = connection_id_included_;
- header.destination_connection_id_included = CONNECTION_ID_ABSENT;
- } else {
- header.destination_connection_id = connection_id_;
- header.destination_connection_id_included = connection_id_included_;
- }
- if (peer_framer_.version().HasIetfInvariantHeader() &&
- peer_framer_.perspective() == Perspective::IS_SERVER) {
- if (!connection_.client_connection_id().IsEmpty()) {
- header.destination_connection_id = connection_.client_connection_id();
- header.destination_connection_id_included = CONNECTION_ID_PRESENT;
- } else {
- header.destination_connection_id_included = CONNECTION_ID_ABSENT;
- }
- if (header.version_flag) {
- header.source_connection_id = connection_id_;
- header.source_connection_id_included = CONNECTION_ID_PRESENT;
- if (GetParam().version.handshake_protocol == PROTOCOL_QUIC_CRYPTO &&
- header.long_packet_type == ZERO_RTT_PROTECTED) {
- header.nonce = &kTestDiversificationNonce;
- }
- }
- }
- header.packet_number_length = packet_number_length_;
- header.packet_number = QuicPacketNumber(number);
- return header;
- }
-
- std::unique_ptr<QuicPacket> ConstructDataPacket(uint64_t number,
- bool has_stop_waiting,
- EncryptionLevel level) {
- QuicPacketHeader header = ConstructPacketHeader(number, level);
- QuicFrames frames;
- if (VersionHasIetfQuicFrames(version().transport_version) &&
- (level == ENCRYPTION_INITIAL || level == ENCRYPTION_HANDSHAKE)) {
- frames.push_back(QuicFrame(QuicPingFrame()));
- frames.push_back(QuicFrame(QuicPaddingFrame(100)));
- } else {
- frames.push_back(QuicFrame(frame1_));
- if (has_stop_waiting) {
- frames.push_back(QuicFrame(stop_waiting_));
- }
- }
- return ConstructPacket(header, frames);
- }
-
- std::unique_ptr<SerializedPacket> ConstructProbingPacket() {
- peer_creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
- if (VersionHasIetfQuicFrames(version().transport_version)) {
- QuicPathFrameBuffer payload = {
- {0xde, 0xad, 0xbe, 0xef, 0xba, 0xdc, 0x0f, 0xfe}};
- return QuicPacketCreatorPeer::
- SerializePathChallengeConnectivityProbingPacket(&peer_creator_,
- payload);
- }
- return QuicPacketCreatorPeer::SerializeConnectivityProbingPacket(
- &peer_creator_);
- }
-
- std::unique_ptr<QuicPacket> ConstructClosePacket(uint64_t number) {
- peer_creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
- QuicPacketHeader header;
- // Set connection_id to peer's in memory representation as this connection
- // close packet is created by peer_framer.
- if (peer_framer_.perspective() == Perspective::IS_SERVER) {
- header.source_connection_id = connection_id_;
- header.destination_connection_id_included = CONNECTION_ID_ABSENT;
- if (!peer_framer_.version().HasIetfInvariantHeader()) {
- header.source_connection_id_included = CONNECTION_ID_PRESENT;
- }
- } else {
- header.destination_connection_id = connection_id_;
- if (peer_framer_.version().HasIetfInvariantHeader()) {
- header.destination_connection_id_included = CONNECTION_ID_ABSENT;
- }
- }
-
- header.packet_number = QuicPacketNumber(number);
-
- QuicErrorCode kQuicErrorCode = QUIC_PEER_GOING_AWAY;
- QuicConnectionCloseFrame qccf(peer_framer_.transport_version(),
- kQuicErrorCode, NO_IETF_QUIC_ERROR, "",
- /*transport_close_frame_type=*/0);
- QuicFrames frames;
- frames.push_back(QuicFrame(&qccf));
- return ConstructPacket(header, frames);
- }
-
- QuicTime::Delta DefaultRetransmissionTime() {
- return QuicTime::Delta::FromMilliseconds(kDefaultRetransmissionTimeMs);
- }
-
- QuicTime::Delta DefaultDelayedAckTime() {
- return QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
- }
-
- const QuicStopWaitingFrame InitStopWaitingFrame(uint64_t least_unacked) {
- QuicStopWaitingFrame frame;
- frame.least_unacked = QuicPacketNumber(least_unacked);
- return frame;
- }
-
- // Construct a ack_frame that acks all packet numbers between 1 and
- // |largest_acked|, except |missing|.
- // REQUIRES: 1 <= |missing| < |largest_acked|
- QuicAckFrame ConstructAckFrame(uint64_t largest_acked, uint64_t missing) {
- return ConstructAckFrame(QuicPacketNumber(largest_acked),
- QuicPacketNumber(missing));
- }
-
- QuicAckFrame ConstructAckFrame(QuicPacketNumber largest_acked,
- QuicPacketNumber missing) {
- if (missing == QuicPacketNumber(1)) {
- return InitAckFrame({{missing + 1, largest_acked + 1}});
- }
- return InitAckFrame(
- {{QuicPacketNumber(1), missing}, {missing + 1, largest_acked + 1}});
- }
-
- // Undo nacking a packet within the frame.
- void AckPacket(QuicPacketNumber arrived, QuicAckFrame* frame) {
- EXPECT_FALSE(frame->packets.Contains(arrived));
- frame->packets.Add(arrived);
- }
-
- void TriggerConnectionClose() {
- // Send an erroneous packet to close the connection.
- EXPECT_CALL(visitor_,
- OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF))
- .WillOnce(Invoke(this, &QuicConnectionTest::SaveConnectionCloseFrame));
-
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- // Triggers a connection by receiving ACK of unsent packet.
- QuicAckFrame frame = InitAckFrame(10000);
- ProcessAckPacket(1, &frame);
- EXPECT_FALSE(QuicConnectionPeer::GetConnectionClosePacket(&connection_) ==
- nullptr);
- EXPECT_EQ(1, connection_close_frame_count_);
- EXPECT_THAT(saved_connection_close_frame_.quic_error_code,
- IsError(QUIC_INVALID_ACK_DATA));
- }
-
- void BlockOnNextWrite() {
- writer_->BlockOnNextWrite();
- EXPECT_CALL(visitor_, OnWriteBlocked()).Times(AtLeast(1));
- }
-
- void SimulateNextPacketTooLarge() { writer_->SimulateNextPacketTooLarge(); }
-
- void AlwaysGetPacketTooLarge() { writer_->AlwaysGetPacketTooLarge(); }
-
- void SetWritePauseTimeDelta(QuicTime::Delta delta) {
- writer_->SetWritePauseTimeDelta(delta);
- }
-
- void CongestionBlockWrites() {
- EXPECT_CALL(*send_algorithm_, CanSend(_))
- .WillRepeatedly(testing::Return(false));
- }
-
- void CongestionUnblockWrites() {
- EXPECT_CALL(*send_algorithm_, CanSend(_))
- .WillRepeatedly(testing::Return(true));
- }
-
- void set_perspective(Perspective perspective) {
- connection_.set_perspective(perspective);
- if (perspective == Perspective::IS_SERVER) {
- QuicConfig config;
- if (!GetQuicReloadableFlag(
- quic_remove_connection_migration_connection_option)) {
- QuicTagVector connection_options;
- connection_options.push_back(kRVCM);
- config.SetInitialReceivedConnectionOptions(connection_options);
- }
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
- connection_.SetFromConfig(config);
-
- connection_.set_can_truncate_connection_ids(true);
- QuicConnectionPeer::SetNegotiatedVersion(&connection_);
- connection_.OnSuccessfulVersionNegotiation();
- }
- QuicFramerPeer::SetPerspective(&peer_framer_,
- QuicUtils::InvertPerspective(perspective));
- peer_framer_.SetInitialObfuscators(TestConnectionId());
- for (EncryptionLevel level : {ENCRYPTION_ZERO_RTT, ENCRYPTION_HANDSHAKE,
- ENCRYPTION_FORWARD_SECURE}) {
- if (peer_framer_.HasEncrypterOfEncryptionLevel(level)) {
- peer_creator_.SetEncrypter(
- level, std::make_unique<NullEncrypter>(peer_framer_.perspective()));
- }
- }
- }
-
- void set_packets_between_probes_base(
- const QuicPacketCount packets_between_probes_base) {
- QuicConnectionPeer::ReInitializeMtuDiscoverer(
- &connection_, packets_between_probes_base,
- QuicPacketNumber(packets_between_probes_base));
- }
-
- bool IsDefaultTestConfiguration() {
- TestParams p = GetParam();
- return p.ack_response == AckResponse::kImmediate &&
- p.version == AllSupportedVersions()[0] && p.no_stop_waiting;
- }
-
- void TestConnectionCloseQuicErrorCode(QuicErrorCode expected_code) {
- // Not strictly needed for this test, but is commonly done.
- EXPECT_FALSE(QuicConnectionPeer::GetConnectionClosePacket(&connection_) ==
- nullptr);
- const std::vector<QuicConnectionCloseFrame>& connection_close_frames =
- writer_->connection_close_frames();
- ASSERT_EQ(1u, connection_close_frames.size());
-
- EXPECT_THAT(connection_close_frames[0].quic_error_code,
- IsError(expected_code));
-
- if (!VersionHasIetfQuicFrames(version().transport_version)) {
- EXPECT_THAT(connection_close_frames[0].wire_error_code,
- IsError(expected_code));
- EXPECT_EQ(GOOGLE_QUIC_CONNECTION_CLOSE,
- connection_close_frames[0].close_type);
- return;
- }
-
- QuicErrorCodeToIetfMapping mapping =
- QuicErrorCodeToTransportErrorCode(expected_code);
-
- if (mapping.is_transport_close) {
- // This Google QUIC Error Code maps to a transport close,
- EXPECT_EQ(IETF_QUIC_TRANSPORT_CONNECTION_CLOSE,
- connection_close_frames[0].close_type);
- } else {
- // This maps to an application close.
- EXPECT_EQ(IETF_QUIC_APPLICATION_CONNECTION_CLOSE,
- connection_close_frames[0].close_type);
- }
- EXPECT_EQ(mapping.error_code, connection_close_frames[0].wire_error_code);
- }
-
- void MtuDiscoveryTestInit() {
- set_perspective(Perspective::IS_SERVER);
- QuicPacketCreatorPeer::SetSendVersionInPacket(creator_, false);
- if (version().SupportsAntiAmplificationLimit()) {
- QuicConnectionPeer::SetAddressValidated(&connection_);
- }
- connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
- peer_creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
- // QuicFramer::GetMaxPlaintextSize uses the smallest max plaintext size
- // across all encrypters. The initial encrypter used with IETF QUIC has a
- // 16-byte overhead, while the NullEncrypter used throughout this test has a
- // 12-byte overhead. This test tests behavior that relies on computing the
- // packet size correctly, so by unsetting the initial encrypter, we avoid
- // having a mismatch between the overheads for the encrypters used. In
- // non-test scenarios all encrypters used for a given connection have the
- // same overhead, either 12 bytes for ones using Google QUIC crypto, or 16
- // bytes for ones using TLS.
- connection_.SetEncrypter(ENCRYPTION_INITIAL, nullptr);
- // Prevent packets from being coalesced.
- EXPECT_CALL(visitor_, GetHandshakeState())
- .WillRepeatedly(Return(HANDSHAKE_CONFIRMED));
- EXPECT_TRUE(connection_.connected());
- }
-
- void PathProbeTestInit(Perspective perspective,
- bool receive_new_server_connection_id = true) {
- set_perspective(perspective);
- connection_.CreateConnectionIdManager();
- EXPECT_EQ(connection_.perspective(), perspective);
- if (perspective == Perspective::IS_SERVER) {
- QuicPacketCreatorPeer::SetSendVersionInPacket(creator_, false);
- }
- connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
- peer_creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
- // Discard INITIAL key.
- connection_.RemoveEncrypter(ENCRYPTION_INITIAL);
- connection_.NeuterUnencryptedPackets();
- // Prevent packets from being coalesced.
- EXPECT_CALL(visitor_, GetHandshakeState())
- .WillRepeatedly(Return(HANDSHAKE_CONFIRMED));
- if (version().SupportsAntiAmplificationLimit() &&
- perspective == Perspective::IS_SERVER) {
- QuicConnectionPeer::SetAddressValidated(&connection_);
- }
- // Clear direct_peer_address.
- QuicConnectionPeer::SetDirectPeerAddress(&connection_, QuicSocketAddress());
- // Clear effective_peer_address, it is the same as direct_peer_address for
- // this test.
- QuicConnectionPeer::SetEffectivePeerAddress(&connection_,
- QuicSocketAddress());
- EXPECT_FALSE(connection_.effective_peer_address().IsInitialized());
-
- if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
- EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
- } else {
- EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber());
- }
- QuicPacketCreatorPeer::SetPacketNumber(&peer_creator_, 2);
- ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress,
- kPeerAddress, ENCRYPTION_FORWARD_SECURE);
- EXPECT_EQ(kPeerAddress, connection_.peer_address());
- EXPECT_EQ(kPeerAddress, connection_.effective_peer_address());
- if (perspective == Perspective::IS_CLIENT &&
- receive_new_server_connection_id && version().HasIetfQuicFrames()) {
- QuicNewConnectionIdFrame frame;
- frame.connection_id = TestConnectionId(1234);
- ASSERT_NE(frame.connection_id, connection_.connection_id());
- frame.stateless_reset_token =
- QuicUtils::GenerateStatelessResetToken(frame.connection_id);
- frame.retire_prior_to = 0u;
- frame.sequence_number = 1u;
- connection_.OnNewConnectionIdFrame(frame);
- }
- }
-
- void TestClientRetryHandling(bool invalid_retry_tag,
- bool missing_original_id_in_config,
- bool wrong_original_id_in_config,
- bool missing_retry_id_in_config,
- bool wrong_retry_id_in_config);
-
- void TestReplaceConnectionIdFromInitial();
-
- QuicConnectionId connection_id_;
- QuicFramer framer_;
-
- MockSendAlgorithm* send_algorithm_;
- std::unique_ptr<MockLossAlgorithm> loss_algorithm_;
- MockClock clock_;
- MockRandom random_generator_;
- SimpleBufferAllocator buffer_allocator_;
- std::unique_ptr<TestConnectionHelper> helper_;
- std::unique_ptr<TestAlarmFactory> alarm_factory_;
- QuicFramer peer_framer_;
- QuicPacketCreator peer_creator_;
- std::unique_ptr<TestPacketWriter> writer_;
- TestConnection connection_;
- QuicPacketCreator* creator_;
- QuicSentPacketManager* manager_;
- StrictMock<MockQuicConnectionVisitor> visitor_;
-
- QuicStreamFrame frame1_;
- QuicStreamFrame frame2_;
- QuicCryptoFrame crypto_frame_;
- QuicAckFrame ack_;
- QuicStopWaitingFrame stop_waiting_;
- QuicPacketNumberLength packet_number_length_;
- QuicConnectionIdIncluded connection_id_included_;
-
- SimpleSessionNotifier notifier_;
-
- QuicConnectionCloseFrame saved_connection_close_frame_;
- int connection_close_frame_count_;
-};
-
-// Run all end to end tests with all supported versions.
-INSTANTIATE_TEST_SUITE_P(QuicConnectionTests, QuicConnectionTest,
- ::testing::ValuesIn(GetTestParams()),
- ::testing::PrintToStringParamName());
-
-// These two tests ensure that the QuicErrorCode mapping works correctly.
-// Both tests expect to see a Google QUIC close if not running IETF QUIC.
-// If running IETF QUIC, the first will generate a transport connection
-// close, the second an application connection close.
-// The connection close codes for the two tests are manually chosen;
-// they are expected to always map to transport- and application-
-// closes, respectively. If that changes, new codes should be chosen.
-TEST_P(QuicConnectionTest, CloseErrorCodeTestTransport) {
- EXPECT_TRUE(connection_.connected());
- EXPECT_CALL(visitor_, OnConnectionClosed(_, _));
- connection_.CloseConnection(
- IETF_QUIC_PROTOCOL_VIOLATION, "Should be transport close",
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
- EXPECT_FALSE(connection_.connected());
- TestConnectionCloseQuicErrorCode(IETF_QUIC_PROTOCOL_VIOLATION);
-}
-
-// Test that the IETF QUIC Error code mapping function works
-// properly for application connection close codes.
-TEST_P(QuicConnectionTest, CloseErrorCodeTestApplication) {
- EXPECT_TRUE(connection_.connected());
- EXPECT_CALL(visitor_, OnConnectionClosed(_, _));
- connection_.CloseConnection(
- QUIC_HEADERS_STREAM_DATA_DECOMPRESS_FAILURE,
- "Should be application close",
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
- EXPECT_FALSE(connection_.connected());
- TestConnectionCloseQuicErrorCode(QUIC_HEADERS_STREAM_DATA_DECOMPRESS_FAILURE);
-}
-
-TEST_P(QuicConnectionTest, SelfAddressChangeAtClient) {
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-
- EXPECT_EQ(Perspective::IS_CLIENT, connection_.perspective());
- EXPECT_TRUE(connection_.connected());
-
- if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
- EXPECT_CALL(visitor_, OnCryptoFrame(_));
- } else {
- EXPECT_CALL(visitor_, OnStreamFrame(_));
- }
- ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress, kPeerAddress,
- ENCRYPTION_INITIAL);
- // Cause change in self_address.
- QuicIpAddress host;
- host.FromString("1.1.1.1");
- QuicSocketAddress self_address(host, 123);
- if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
- EXPECT_CALL(visitor_, OnCryptoFrame(_));
- } else {
- EXPECT_CALL(visitor_, OnStreamFrame(_));
- }
- ProcessFramePacketWithAddresses(MakeCryptoFrame(), self_address, kPeerAddress,
- ENCRYPTION_INITIAL);
- EXPECT_TRUE(connection_.connected());
-}
-
-TEST_P(QuicConnectionTest, SelfAddressChangeAtServer) {
- set_perspective(Perspective::IS_SERVER);
- QuicPacketCreatorPeer::SetSendVersionInPacket(creator_, false);
-
- EXPECT_EQ(Perspective::IS_SERVER, connection_.perspective());
- EXPECT_TRUE(connection_.connected());
-
- if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
- EXPECT_CALL(visitor_, OnCryptoFrame(_));
- } else {
- EXPECT_CALL(visitor_, OnStreamFrame(_));
- }
- ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress, kPeerAddress,
- ENCRYPTION_INITIAL);
- // Cause change in self_address.
- QuicIpAddress host;
- host.FromString("1.1.1.1");
- QuicSocketAddress self_address(host, 123);
- EXPECT_CALL(visitor_, AllowSelfAddressChange()).WillOnce(Return(false));
- if (version().handshake_protocol == PROTOCOL_TLS1_3) {
- EXPECT_CALL(visitor_, BeforeConnectionCloseSent());
- }
- EXPECT_CALL(visitor_, OnConnectionClosed(_, _));
- ProcessFramePacketWithAddresses(MakeCryptoFrame(), self_address, kPeerAddress,
- ENCRYPTION_INITIAL);
- EXPECT_FALSE(connection_.connected());
- TestConnectionCloseQuicErrorCode(QUIC_ERROR_MIGRATING_ADDRESS);
-}
-
-TEST_P(QuicConnectionTest, AllowSelfAddressChangeToMappedIpv4AddressAtServer) {
- set_perspective(Perspective::IS_SERVER);
- QuicPacketCreatorPeer::SetSendVersionInPacket(creator_, false);
-
- EXPECT_EQ(Perspective::IS_SERVER, connection_.perspective());
- EXPECT_TRUE(connection_.connected());
-
- if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
- EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(3);
- } else {
- EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(3);
- }
- QuicIpAddress host;
- host.FromString("1.1.1.1");
- QuicSocketAddress self_address1(host, 443);
- connection_.SetSelfAddress(self_address1);
- ProcessFramePacketWithAddresses(MakeCryptoFrame(), self_address1,
- kPeerAddress, ENCRYPTION_INITIAL);
- // Cause self_address change to mapped Ipv4 address.
- QuicIpAddress host2;
- host2.FromString(
- absl::StrCat("::ffff:", connection_.self_address().host().ToString()));
- QuicSocketAddress self_address2(host2, connection_.self_address().port());
- ProcessFramePacketWithAddresses(MakeCryptoFrame(), self_address2,
- kPeerAddress, ENCRYPTION_INITIAL);
- EXPECT_TRUE(connection_.connected());
- // self_address change back to Ipv4 address.
- ProcessFramePacketWithAddresses(MakeCryptoFrame(), self_address1,
- kPeerAddress, ENCRYPTION_INITIAL);
- EXPECT_TRUE(connection_.connected());
-}
-
-TEST_P(QuicConnectionTest, ClientAddressChangeAndPacketReordered) {
- set_perspective(Perspective::IS_SERVER);
- QuicPacketCreatorPeer::SetSendVersionInPacket(creator_, false);
- EXPECT_CALL(visitor_, GetHandshakeState())
- .WillRepeatedly(Return(HANDSHAKE_CONFIRMED));
-
- // Clear direct_peer_address.
- QuicConnectionPeer::SetDirectPeerAddress(&connection_, QuicSocketAddress());
- // Clear effective_peer_address, it is the same as direct_peer_address for
- // this test.
- QuicConnectionPeer::SetEffectivePeerAddress(&connection_,
- QuicSocketAddress());
-
- if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
- EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
- } else {
- EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber());
- }
- QuicPacketCreatorPeer::SetPacketNumber(&peer_creator_, 5);
- const QuicSocketAddress kNewPeerAddress =
- QuicSocketAddress(QuicIpAddress::Loopback6(),
- /*port=*/23456);
- ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress,
- kNewPeerAddress, ENCRYPTION_INITIAL);
- EXPECT_EQ(kNewPeerAddress, connection_.peer_address());
- EXPECT_EQ(kNewPeerAddress, connection_.effective_peer_address());
-
- // Decrease packet number to simulate out-of-order packets.
- QuicPacketCreatorPeer::SetPacketNumber(&peer_creator_, 4);
- // This is an old packet, do not migrate.
- EXPECT_CALL(visitor_, OnConnectionMigration(PORT_CHANGE)).Times(0);
- ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress, kPeerAddress,
- ENCRYPTION_INITIAL);
- EXPECT_EQ(kNewPeerAddress, connection_.peer_address());
- EXPECT_EQ(kNewPeerAddress, connection_.effective_peer_address());
-}
-
-TEST_P(QuicConnectionTest, PeerPortChangeAtServer) {
- set_perspective(Perspective::IS_SERVER);
- QuicPacketCreatorPeer::SetSendVersionInPacket(creator_, false);
- EXPECT_EQ(Perspective::IS_SERVER, connection_.perspective());
- connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
- // Prevent packets from being coalesced.
- EXPECT_CALL(visitor_, GetHandshakeState())
- .WillRepeatedly(Return(HANDSHAKE_CONFIRMED));
- if (version().SupportsAntiAmplificationLimit()) {
- QuicConnectionPeer::SetAddressValidated(&connection_);
- }
-
- // Clear direct_peer_address.
- QuicConnectionPeer::SetDirectPeerAddress(&connection_, QuicSocketAddress());
- // Clear effective_peer_address, it is the same as direct_peer_address for
- // this test.
- QuicConnectionPeer::SetEffectivePeerAddress(&connection_,
- QuicSocketAddress());
- EXPECT_FALSE(connection_.effective_peer_address().IsInitialized());
-
- RttStats* rtt_stats = const_cast<RttStats*>(manager_->GetRttStats());
- QuicTime::Delta default_init_rtt = rtt_stats->initial_rtt();
- 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());
-
- const QuicSocketAddress kNewPeerAddress =
- QuicSocketAddress(QuicIpAddress::Loopback6(), /*port=*/23456);
- EXPECT_CALL(visitor_, OnStreamFrame(_))
- .WillOnce(Invoke(
- [=]() { EXPECT_EQ(kPeerAddress, connection_.peer_address()); }))
- .WillOnce(Invoke(
- [=]() { EXPECT_EQ(kNewPeerAddress, connection_.peer_address()); }));
- QuicFrames frames;
- frames.push_back(QuicFrame(frame1_));
- ProcessFramesPacketWithAddresses(frames, kSelfAddress, kPeerAddress,
- ENCRYPTION_FORWARD_SECURE);
- EXPECT_EQ(kPeerAddress, connection_.peer_address());
- EXPECT_EQ(kPeerAddress, connection_.effective_peer_address());
-
- // Process another packet with a different peer address on server side will
- // start connection migration.
- EXPECT_CALL(visitor_, OnConnectionMigration(PORT_CHANGE)).Times(1);
- QuicFrames frames2;
- frames2.push_back(QuicFrame(frame2_));
- ProcessFramesPacketWithAddresses(frames2, kSelfAddress, kNewPeerAddress,
- ENCRYPTION_FORWARD_SECURE);
- EXPECT_EQ(kNewPeerAddress, connection_.peer_address());
- 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(manager_->GetSendAlgorithm(), send_algorithm_);
- if (connection_.validate_client_address()) {
- EXPECT_EQ(NO_CHANGE, connection_.active_effective_peer_migration_type());
- EXPECT_EQ(1u, connection_.GetStats().num_validated_peer_migration);
- }
-}
-
-TEST_P(QuicConnectionTest, PeerIpAddressChangeAtServer) {
- set_perspective(Perspective::IS_SERVER);
- if (!connection_.validate_client_address()) {
- return;
- }
- QuicPacketCreatorPeer::SetSendVersionInPacket(creator_, false);
- EXPECT_EQ(Perspective::IS_SERVER, connection_.perspective());
- connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
- // Discard INITIAL key.
- connection_.RemoveEncrypter(ENCRYPTION_INITIAL);
- connection_.NeuterUnencryptedPackets();
- // Prevent packets from being coalesced.
- EXPECT_CALL(visitor_, GetHandshakeState())
- .WillRepeatedly(Return(HANDSHAKE_CONFIRMED));
- QuicConnectionPeer::SetAddressValidated(&connection_);
- connection_.OnHandshakeComplete();
-
- // Enable 5 RTO
- QuicConfig config;
- QuicTagVector connection_options;
- connection_options.push_back(k5RTO);
- config.SetInitialReceivedConnectionOptions(connection_options);
- QuicConfigPeer::SetNegotiated(&config, true);
- QuicConfigPeer::SetReceivedOriginalConnectionId(&config,
- connection_.connection_id());
- QuicConfigPeer::SetReceivedInitialSourceConnectionId(&config,
- QuicConnectionId());
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
- connection_.SetFromConfig(config);
-
- // Clear direct_peer_address.
- QuicConnectionPeer::SetDirectPeerAddress(&connection_, QuicSocketAddress());
- // Clear effective_peer_address, it is the same as direct_peer_address for
- // this test.
- QuicConnectionPeer::SetEffectivePeerAddress(&connection_,
- QuicSocketAddress());
- EXPECT_FALSE(connection_.effective_peer_address().IsInitialized());
-
- const QuicSocketAddress kNewPeerAddress =
- QuicSocketAddress(QuicIpAddress::Loopback4(), /*port=*/23456);
- EXPECT_CALL(visitor_, OnStreamFrame(_))
- .WillOnce(Invoke(
- [=]() { EXPECT_EQ(kPeerAddress, connection_.peer_address()); }))
- .WillOnce(Invoke(
- [=]() { EXPECT_EQ(kNewPeerAddress, connection_.peer_address()); }));
- QuicFrames frames;
- frames.push_back(QuicFrame(frame1_));
- ProcessFramesPacketWithAddresses(frames, kSelfAddress, kPeerAddress,
- ENCRYPTION_FORWARD_SECURE);
- EXPECT_EQ(kPeerAddress, connection_.peer_address());
- EXPECT_EQ(kPeerAddress, connection_.effective_peer_address());
-
- // Send some data to make connection has packets in flight.
- connection_.SendStreamData3();
- EXPECT_EQ(1u, writer_->packets_write_attempts());
- EXPECT_TRUE(connection_.BlackholeDetectionInProgress());
- EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
-
- // Process another packet with a different peer address on server side will
- // start connection migration.
- EXPECT_CALL(visitor_, OnConnectionMigration(IPV6_TO_IPV4_CHANGE)).Times(1);
- // IETF QUIC send algorithm should be changed to a different object, so no
- // OnPacketSent() called on the old send algorithm.
- EXPECT_CALL(*send_algorithm_,
- OnPacketSent(_, _, _, _, NO_RETRANSMITTABLE_DATA))
- .Times(0);
- // Do not propagate OnCanWrite() to session notifier.
- EXPECT_CALL(visitor_, OnCanWrite()).Times(AtLeast(1u));
-
- QuicFrames frames2;
- frames2.push_back(QuicFrame(frame2_));
- ProcessFramesPacketWithAddresses(frames2, kSelfAddress, kNewPeerAddress,
- ENCRYPTION_FORWARD_SECURE);
- EXPECT_EQ(kNewPeerAddress, connection_.peer_address());
- EXPECT_EQ(kNewPeerAddress, connection_.effective_peer_address());
- EXPECT_EQ(IPV6_TO_IPV4_CHANGE,
- connection_.active_effective_peer_migration_type());
- EXPECT_FALSE(connection_.BlackholeDetectionInProgress());
- EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
-
- EXPECT_EQ(2u, writer_->packets_write_attempts());
- EXPECT_FALSE(writer_->path_challenge_frames().empty());
- QuicPathFrameBuffer payload =
- writer_->path_challenge_frames().front().data_buffer;
- EXPECT_NE(connection_.sent_packet_manager().GetSendAlgorithm(),
- send_algorithm_);
- // Switch to use the mock send algorithm.
- send_algorithm_ = new StrictMock<MockSendAlgorithm>();
- EXPECT_CALL(*send_algorithm_, CanSend(_)).WillRepeatedly(Return(true));
- EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
- .WillRepeatedly(Return(kDefaultTCPMSS));
- EXPECT_CALL(*send_algorithm_, OnApplicationLimited(_)).Times(AnyNumber());
- EXPECT_CALL(*send_algorithm_, BandwidthEstimate())
- .Times(AnyNumber())
- .WillRepeatedly(Return(QuicBandwidth::Zero()));
- EXPECT_CALL(*send_algorithm_, InSlowStart()).Times(AnyNumber());
- EXPECT_CALL(*send_algorithm_, InRecovery()).Times(AnyNumber());
- EXPECT_CALL(*send_algorithm_, PopulateConnectionStats(_)).Times(AnyNumber());
- connection_.SetSendAlgorithm(send_algorithm_);
-
- // PATH_CHALLENGE is expanded upto the max packet size which may exceeds the
- // anti-amplification limit.
- EXPECT_EQ(kNewPeerAddress, writer_->last_write_peer_address());
- EXPECT_EQ(kNewPeerAddress, connection_.peer_address());
- EXPECT_EQ(kNewPeerAddress, connection_.effective_peer_address());
- EXPECT_EQ(1u,
- connection_.GetStats().num_reverse_path_validtion_upon_migration);
-
- // Verify server is throttled by anti-amplification limit.
- connection_.SendCryptoDataWithString("foo", 0);
- EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
-
- // Receiving an ACK to the packet sent after changing peer address doesn't
- // finish migration validation.
- QuicAckFrame ack_frame = InitAckFrame(2);
- EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _));
- ProcessFramePacketWithAddresses(QuicFrame(&ack_frame), kSelfAddress,
- kNewPeerAddress, ENCRYPTION_FORWARD_SECURE);
- EXPECT_EQ(kNewPeerAddress, connection_.peer_address());
- EXPECT_EQ(kNewPeerAddress, connection_.effective_peer_address());
- EXPECT_EQ(IPV6_TO_IPV4_CHANGE,
- connection_.active_effective_peer_migration_type());
-
- // Receiving PATH_RESPONSE should lift the anti-amplification limit.
- QuicFrames frames3;
- frames3.push_back(QuicFrame(new QuicPathResponseFrame(99, payload)));
- EXPECT_CALL(visitor_, MaybeSendAddressToken());
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
- .Times(testing::AtLeast(1u));
- ProcessFramesPacketWithAddresses(frames3, kSelfAddress, kNewPeerAddress,
- ENCRYPTION_FORWARD_SECURE);
- EXPECT_EQ(NO_CHANGE, connection_.active_effective_peer_migration_type());
-
- // Verify the anti-amplification limit is lifted by sending a packet larger
- // than the anti-amplification limit.
- connection_.SendCryptoDataWithString(std::string(1200, 'a'), 0);
- EXPECT_EQ(1u, connection_.GetStats().num_validated_peer_migration);
-}
-
-TEST_P(QuicConnectionTest, PeerIpAddressChangeAtServerWithMissingConnectionId) {
- set_perspective(Perspective::IS_SERVER);
- if (!connection_.connection_migration_use_new_cid()) {
- return;
- }
- QuicPacketCreatorPeer::SetSendVersionInPacket(creator_, false);
- EXPECT_EQ(Perspective::IS_SERVER, connection_.perspective());
-
- QuicConnectionId client_cid0 = TestConnectionId(1);
- QuicConnectionId client_cid1 = TestConnectionId(3);
- QuicConnectionId server_cid1;
- SetClientConnectionId(client_cid0);
- connection_.CreateConnectionIdManager();
- connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
- // Prevent packets from being coalesced.
- EXPECT_CALL(visitor_, GetHandshakeState())
- .WillRepeatedly(Return(HANDSHAKE_CONFIRMED));
- QuicConnectionPeer::SetAddressValidated(&connection_);
-
- // Sends new server CID to client.
- EXPECT_CALL(visitor_, OnServerConnectionIdIssued(_))
- .WillOnce(
- Invoke([&](const QuicConnectionId& cid) { server_cid1 = cid; }));
- EXPECT_CALL(visitor_, SendNewConnectionId(_));
- connection_.OnHandshakeComplete();
-
- // Clear direct_peer_address.
- QuicConnectionPeer::SetDirectPeerAddress(&connection_, QuicSocketAddress());
- // Clear effective_peer_address, it is the same as direct_peer_address for
- // this test.
- QuicConnectionPeer::SetEffectivePeerAddress(&connection_,
- QuicSocketAddress());
- EXPECT_FALSE(connection_.effective_peer_address().IsInitialized());
-
- const QuicSocketAddress kNewPeerAddress =
- QuicSocketAddress(QuicIpAddress::Loopback4(), /*port=*/23456);
- EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(2);
- QuicFrames frames;
- frames.push_back(QuicFrame(frame1_));
- ProcessFramesPacketWithAddresses(frames, kSelfAddress, kPeerAddress,
- ENCRYPTION_FORWARD_SECURE);
- EXPECT_EQ(kPeerAddress, connection_.peer_address());
- EXPECT_EQ(kPeerAddress, connection_.effective_peer_address());
-
- // Send some data to make connection has packets in flight.
- connection_.SendStreamData3();
- EXPECT_EQ(1u, writer_->packets_write_attempts());
-
- // Process another packet with a different peer address on server side will
- // start connection migration.
- peer_creator_.SetServerConnectionId(server_cid1);
- EXPECT_CALL(visitor_, OnConnectionMigration(IPV6_TO_IPV4_CHANGE)).Times(1);
- // Do not propagate OnCanWrite() to session notifier.
- EXPECT_CALL(visitor_, OnCanWrite()).Times(AtLeast(1u));
-
- QuicFrames frames2;
- frames2.push_back(QuicFrame(frame2_));
- ProcessFramesPacketWithAddresses(frames2, kSelfAddress, kNewPeerAddress,
- ENCRYPTION_FORWARD_SECURE);
- EXPECT_EQ(kNewPeerAddress, connection_.peer_address());
- EXPECT_EQ(kNewPeerAddress, connection_.effective_peer_address());
-
- // Writing path response & reverse path challenge is blocked due to missing
- // client connection ID, i.e., packets_write_attempts is unchanged.
- EXPECT_EQ(1u, writer_->packets_write_attempts());
-
- // Receives new client CID from client would unblock write.
- 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);
- connection_.SendStreamData3();
-
- EXPECT_EQ(2u, writer_->packets_write_attempts());
-}
-
-TEST_P(QuicConnectionTest, EffectivePeerAddressChangeAtServer) {
- set_perspective(Perspective::IS_SERVER);
- QuicPacketCreatorPeer::SetSendVersionInPacket(creator_, false);
- EXPECT_EQ(Perspective::IS_SERVER, connection_.perspective());
- if (version().SupportsAntiAmplificationLimit()) {
- QuicConnectionPeer::SetAddressValidated(&connection_);
- }
- connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
- // Discard INITIAL key.
- connection_.RemoveEncrypter(ENCRYPTION_INITIAL);
- connection_.NeuterUnencryptedPackets();
- EXPECT_CALL(visitor_, GetHandshakeState())
- .WillRepeatedly(Return(HANDSHAKE_CONFIRMED));
-
- // Clear direct_peer_address.
- QuicConnectionPeer::SetDirectPeerAddress(&connection_, QuicSocketAddress());
- // Clear effective_peer_address, it is different from direct_peer_address for
- // this test.
- QuicConnectionPeer::SetEffectivePeerAddress(&connection_,
- QuicSocketAddress());
- const QuicSocketAddress kEffectivePeerAddress =
- QuicSocketAddress(QuicIpAddress::Loopback6(), /*port=*/43210);
- connection_.ReturnEffectivePeerAddressForNextPacket(kEffectivePeerAddress);
-
- if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
- EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
- } else {
- EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber());
- }
- ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress, kPeerAddress,
- ENCRYPTION_FORWARD_SECURE);
- EXPECT_EQ(kPeerAddress, connection_.peer_address());
- EXPECT_EQ(kEffectivePeerAddress, connection_.effective_peer_address());
-
- // Process another packet with the same direct peer address and different
- // effective peer address on server side will start connection migration.
- const QuicSocketAddress kNewEffectivePeerAddress =
- QuicSocketAddress(QuicIpAddress::Loopback6(), /*port=*/54321);
- connection_.ReturnEffectivePeerAddressForNextPacket(kNewEffectivePeerAddress);
- EXPECT_CALL(visitor_, OnConnectionMigration(PORT_CHANGE)).Times(1);
- ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress, kPeerAddress,
- ENCRYPTION_FORWARD_SECURE);
- EXPECT_EQ(kPeerAddress, connection_.peer_address());
- EXPECT_EQ(kNewEffectivePeerAddress, connection_.effective_peer_address());
- EXPECT_EQ(kPeerAddress, writer_->last_write_peer_address());
- if (connection_.validate_client_address()) {
- EXPECT_EQ(NO_CHANGE, connection_.active_effective_peer_migration_type());
- EXPECT_EQ(1u, connection_.GetStats().num_validated_peer_migration);
- }
-
- // Process another packet with a different direct peer address and the same
- // effective peer address on server side will not start connection migration.
- const QuicSocketAddress kNewPeerAddress =
- QuicSocketAddress(QuicIpAddress::Loopback6(), /*port=*/23456);
- connection_.ReturnEffectivePeerAddressForNextPacket(kNewEffectivePeerAddress);
- EXPECT_CALL(visitor_, OnConnectionMigration(PORT_CHANGE)).Times(0);
-
- if (!connection_.validate_client_address()) {
- // ack_frame is used to complete the migration started by the last packet,
- // we need to make sure a new migration does not start after the previous
- // one is completed.
- QuicAckFrame ack_frame = InitAckFrame(1);
- EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _));
- ProcessFramePacketWithAddresses(QuicFrame(&ack_frame), kSelfAddress,
- kNewPeerAddress, ENCRYPTION_FORWARD_SECURE);
- EXPECT_EQ(kNewPeerAddress, connection_.peer_address());
- EXPECT_EQ(kNewEffectivePeerAddress, connection_.effective_peer_address());
- EXPECT_EQ(NO_CHANGE, connection_.active_effective_peer_migration_type());
- }
-
- // Process another packet with different direct peer address and different
- // effective peer address on server side will start connection migration.
- const QuicSocketAddress kNewerEffectivePeerAddress =
- QuicSocketAddress(QuicIpAddress::Loopback6(), /*port=*/65432);
- const QuicSocketAddress kFinalPeerAddress =
- QuicSocketAddress(QuicIpAddress::Loopback6(), /*port=*/34567);
- connection_.ReturnEffectivePeerAddressForNextPacket(
- kNewerEffectivePeerAddress);
- EXPECT_CALL(visitor_, OnConnectionMigration(PORT_CHANGE)).Times(1);
- ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress,
- kFinalPeerAddress, ENCRYPTION_FORWARD_SECURE);
- EXPECT_EQ(kFinalPeerAddress, connection_.peer_address());
- EXPECT_EQ(kNewerEffectivePeerAddress, connection_.effective_peer_address());
- if (connection_.validate_client_address()) {
- EXPECT_EQ(NO_CHANGE, connection_.active_effective_peer_migration_type());
- EXPECT_EQ(send_algorithm_,
- connection_.sent_packet_manager().GetSendAlgorithm());
- EXPECT_EQ(2u, connection_.GetStats().num_validated_peer_migration);
- }
-
- // While the previous migration is ongoing, process another packet with the
- // same direct peer address and different effective peer address on server
- // side will start a new connection migration.
- const QuicSocketAddress kNewestEffectivePeerAddress =
- QuicSocketAddress(QuicIpAddress::Loopback4(), /*port=*/65430);
- connection_.ReturnEffectivePeerAddressForNextPacket(
- kNewestEffectivePeerAddress);
- EXPECT_CALL(visitor_, OnConnectionMigration(IPV6_TO_IPV4_CHANGE)).Times(1);
- if (!connection_.validate_client_address()) {
- EXPECT_CALL(*send_algorithm_, OnConnectionMigration()).Times(1);
- }
- ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress,
- kFinalPeerAddress, ENCRYPTION_FORWARD_SECURE);
- EXPECT_EQ(kFinalPeerAddress, connection_.peer_address());
- EXPECT_EQ(kNewestEffectivePeerAddress, connection_.effective_peer_address());
- EXPECT_EQ(IPV6_TO_IPV4_CHANGE,
- connection_.active_effective_peer_migration_type());
- if (connection_.validate_client_address()) {
- EXPECT_NE(send_algorithm_,
- connection_.sent_packet_manager().GetSendAlgorithm());
- EXPECT_EQ(kFinalPeerAddress, writer_->last_write_peer_address());
- EXPECT_FALSE(writer_->path_challenge_frames().empty());
- EXPECT_EQ(0u, connection_.GetStats()
- .num_peer_migration_while_validating_default_path);
- EXPECT_TRUE(connection_.HasPendingPathValidation());
- }
-}
-
-// Regression test for b/200020764.
-TEST_P(QuicConnectionTest, ConnectionMigrationWithPendingPaddingBytes) {
- // TODO(haoyuewang) Move these test setup code to a common member function.
- set_perspective(Perspective::IS_SERVER);
- if (!connection_.connection_migration_use_new_cid()) {
- return;
- }
- QuicPacketCreatorPeer::SetSendVersionInPacket(creator_, false);
- connection_.CreateConnectionIdManager();
- connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
- QuicConnectionPeer::SetPeerAddress(&connection_, kPeerAddress);
- QuicConnectionPeer::SetEffectivePeerAddress(&connection_, kPeerAddress);
- QuicConnectionPeer::SetAddressValidated(&connection_);
-
- // Sends new server CID to client.
- QuicConnectionId new_cid;
- EXPECT_CALL(visitor_, OnServerConnectionIdIssued(_))
- .WillOnce(Invoke([&](const QuicConnectionId& cid) { new_cid = cid; }));
- EXPECT_CALL(visitor_, SendNewConnectionId(_));
- // Discard INITIAL key.
- connection_.RemoveEncrypter(ENCRYPTION_INITIAL);
- connection_.NeuterUnencryptedPackets();
- connection_.OnHandshakeComplete();
- EXPECT_CALL(visitor_, GetHandshakeState())
- .WillRepeatedly(Return(HANDSHAKE_CONFIRMED));
-
- auto* packet_creator = QuicConnectionPeer::GetPacketCreator(&connection_);
- packet_creator->FlushCurrentPacket();
- packet_creator->AddPendingPadding(50u);
- const QuicSocketAddress kPeerAddress3 =
- QuicSocketAddress(QuicIpAddress::Loopback6(), /*port=*/56789);
- auto ack_frame = InitAckFrame(1);
- EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _));
- EXPECT_CALL(visitor_, OnConnectionMigration(PORT_CHANGE)).Times(1);
- ProcessFramesPacketWithAddresses({QuicFrame(&ack_frame)}, kSelfAddress,
- kPeerAddress3, ENCRYPTION_FORWARD_SECURE);
- if (GetQuicReloadableFlag(
- quic_flush_pending_frames_and_padding_bytes_on_migration)) {
- // Any pending frames/padding should be flushed before default_path_ is
- // temporarily reset.
- ASSERT_EQ(connection_.self_address_on_default_path_while_sending_packet()
- .host()
- .address_family(),
- IpAddressFamily::IP_V6);
- } else {
- ASSERT_EQ(connection_.self_address_on_default_path_while_sending_packet()
- .host()
- .address_family(),
- IpAddressFamily::IP_UNSPEC);
- }
-}
-
-// Regression test for b/196208556.
-TEST_P(QuicConnectionTest,
- ReversePathValidationResponseReceivedFromUnexpectedPeerAddress) {
- set_perspective(Perspective::IS_SERVER);
- if (!connection_.connection_migration_use_new_cid()) {
- return;
- }
- QuicPacketCreatorPeer::SetSendVersionInPacket(creator_, false);
- connection_.CreateConnectionIdManager();
- connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
- QuicConnectionPeer::SetPeerAddress(&connection_, kPeerAddress);
- QuicConnectionPeer::SetEffectivePeerAddress(&connection_, kPeerAddress);
- QuicConnectionPeer::SetAddressValidated(&connection_);
- EXPECT_EQ(kPeerAddress, connection_.peer_address());
- EXPECT_EQ(kPeerAddress, connection_.effective_peer_address());
-
- // Sends new server CID to client.
- QuicConnectionId new_cid;
- EXPECT_CALL(visitor_, OnServerConnectionIdIssued(_))
- .WillOnce(Invoke([&](const QuicConnectionId& cid) { new_cid = cid; }));
- EXPECT_CALL(visitor_, SendNewConnectionId(_));
- // Discard INITIAL key.
- connection_.RemoveEncrypter(ENCRYPTION_INITIAL);
- connection_.NeuterUnencryptedPackets();
- connection_.OnHandshakeComplete();
- EXPECT_CALL(visitor_, GetHandshakeState())
- .WillRepeatedly(Return(HANDSHAKE_CONFIRMED));
-
- // Process a non-probing packet to migrate to path 2 and kick off reverse path
- // validation.
- EXPECT_CALL(visitor_, OnConnectionMigration(IPV6_TO_IPV4_CHANGE)).Times(1);
- const QuicSocketAddress kPeerAddress2 =
- QuicSocketAddress(QuicIpAddress::Loopback4(), /*port=*/23456);
- peer_creator_.SetServerConnectionId(new_cid);
- ProcessFramesPacketWithAddresses({QuicFrame(QuicPingFrame())}, kSelfAddress,
- kPeerAddress2, ENCRYPTION_FORWARD_SECURE);
- EXPECT_FALSE(writer_->path_challenge_frames().empty());
- QuicPathFrameBuffer reverse_path_challenge_payload =
- writer_->path_challenge_frames().front().data_buffer;
-
- // Receiveds a packet from path 3 with PATH_RESPONSE frame intended to
- // validate path 2 and a non-probing frame.
- {
- QuicConnection::ScopedPacketFlusher flusher(&connection_);
- const QuicSocketAddress kPeerAddress3 =
- QuicSocketAddress(QuicIpAddress::Loopback6(), /*port=*/56789);
- auto ack_frame = InitAckFrame(1);
- EXPECT_CALL(visitor_, OnConnectionMigration(IPV4_TO_IPV6_CHANGE)).Times(1);
- EXPECT_CALL(visitor_, MaybeSendAddressToken()).WillOnce(Invoke([this]() {
- connection_.SendControlFrame(
- QuicFrame(new QuicNewTokenFrame(1, "new_token")));
- return true;
- }));
- ProcessFramesPacketWithAddresses({QuicFrame(new QuicPathResponseFrame(
- 0, reverse_path_challenge_payload)),
- QuicFrame(&ack_frame)},
- kSelfAddress, kPeerAddress3,
- ENCRYPTION_FORWARD_SECURE);
- }
-}
-
-TEST_P(QuicConnectionTest, ReversePathValidationFailureAtServer) {
- set_perspective(Perspective::IS_SERVER);
- if (!connection_.connection_migration_use_new_cid()) {
- return;
- }
- QuicPacketCreatorPeer::SetSendVersionInPacket(creator_, false);
- EXPECT_EQ(Perspective::IS_SERVER, connection_.perspective());
- SetClientConnectionId(TestConnectionId(1));
- connection_.CreateConnectionIdManager();
- connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
- // Discard INITIAL key.
- connection_.RemoveEncrypter(ENCRYPTION_INITIAL);
- connection_.NeuterUnencryptedPackets();
- // Prevent packets from being coalesced.
- EXPECT_CALL(visitor_, GetHandshakeState())
- .WillRepeatedly(Return(HANDSHAKE_CONFIRMED));
- QuicConnectionPeer::SetAddressValidated(&connection_);
-
- QuicConnectionId client_cid0 = connection_.client_connection_id();
- QuicConnectionId client_cid1 = TestConnectionId(2);
- QuicConnectionId server_cid0 = connection_.connection_id();
- 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_.OnHandshakeComplete();
- // 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);
-
- // Clear direct_peer_address.
- QuicConnectionPeer::SetDirectPeerAddress(&connection_, QuicSocketAddress());
- // Clear effective_peer_address, it is the same as direct_peer_address for
- // this test.
- QuicConnectionPeer::SetEffectivePeerAddress(&connection_,
- QuicSocketAddress());
- EXPECT_FALSE(connection_.effective_peer_address().IsInitialized());
-
- const QuicSocketAddress kNewPeerAddress =
- QuicSocketAddress(QuicIpAddress::Loopback4(), /*port=*/23456);
- EXPECT_CALL(visitor_, OnStreamFrame(_))
- .WillOnce(Invoke(
- [=]() { EXPECT_EQ(kPeerAddress, connection_.peer_address()); }))
- .WillOnce(Invoke(
- [=]() { EXPECT_EQ(kNewPeerAddress, connection_.peer_address()); }));
- QuicFrames frames;
- frames.push_back(QuicFrame(frame1_));
- ProcessFramesPacketWithAddresses(frames, kSelfAddress, kPeerAddress,
- ENCRYPTION_FORWARD_SECURE);
- EXPECT_EQ(kPeerAddress, connection_.peer_address());
- EXPECT_EQ(kPeerAddress, connection_.effective_peer_address());
-
- // Process another packet with a different peer address on server side will
- // start connection migration.
- EXPECT_CALL(visitor_, OnConnectionMigration(IPV6_TO_IPV4_CHANGE)).Times(1);
- // IETF QUIC send algorithm should be changed to a different object, so no
- // OnPacketSent() called on the old send algorithm.
- EXPECT_CALL(*send_algorithm_, OnConnectionMigration()).Times(0);
-
- QuicFrames frames2;
- frames2.push_back(QuicFrame(frame2_));
- QuicPaddingFrame padding;
- frames2.push_back(QuicFrame(padding));
- peer_creator_.SetServerConnectionId(server_cid1);
- ProcessFramesPacketWithAddresses(frames2, kSelfAddress, kNewPeerAddress,
- ENCRYPTION_FORWARD_SECURE);
- EXPECT_EQ(kNewPeerAddress, connection_.peer_address());
- EXPECT_EQ(kNewPeerAddress, connection_.effective_peer_address());
- EXPECT_EQ(IPV6_TO_IPV4_CHANGE,
- connection_.active_effective_peer_migration_type());
- EXPECT_LT(0u, writer_->packets_write_attempts());
- EXPECT_TRUE(connection_.HasPendingPathValidation());
- EXPECT_NE(connection_.sent_packet_manager().GetSendAlgorithm(),
- send_algorithm_);
- EXPECT_EQ(kNewPeerAddress, writer_->last_write_peer_address());
- EXPECT_EQ(kNewPeerAddress, connection_.peer_address());
- EXPECT_EQ(kNewPeerAddress, connection_.effective_peer_address());
- const auto* default_path = QuicConnectionPeer::GetDefaultPath(&connection_);
- const auto* alternative_path =
- QuicConnectionPeer::GetAlternativePath(&connection_);
- EXPECT_EQ(default_path->client_connection_id, client_cid1);
- EXPECT_EQ(default_path->server_connection_id, server_cid1);
- EXPECT_EQ(alternative_path->client_connection_id, client_cid0);
- EXPECT_EQ(alternative_path->server_connection_id, server_cid0);
- EXPECT_EQ(packet_creator->GetDestinationConnectionId(), client_cid1);
- EXPECT_EQ(packet_creator->GetSourceConnectionId(), server_cid1);
-
- for (size_t i = 0; i < QuicPathValidator::kMaxRetryTimes; ++i) {
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(3 * kInitialRttMs));
- static_cast<TestAlarmFactory::TestAlarm*>(
- QuicPathValidatorPeer::retry_timer(
- QuicConnectionPeer::path_validator(&connection_)))
- ->Fire();
- }
- EXPECT_EQ(IPV6_TO_IPV4_CHANGE,
- connection_.active_effective_peer_migration_type());
-
- // Make sure anti-amplification limit is not reached.
- ProcessFramesPacketWithAddresses(
- {QuicFrame(QuicPingFrame()), QuicFrame(QuicPaddingFrame())}, kSelfAddress,
- kNewPeerAddress, ENCRYPTION_FORWARD_SECURE);
- SendStreamDataToPeer(1, "foo", 0, NO_FIN, nullptr);
- EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
-
- // Advance the time so that the reverse path validation times out.
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(3 * kInitialRttMs));
- static_cast<TestAlarmFactory::TestAlarm*>(
- QuicPathValidatorPeer::retry_timer(
- QuicConnectionPeer::path_validator(&connection_)))
- ->Fire();
- EXPECT_EQ(NO_CHANGE, connection_.active_effective_peer_migration_type());
- EXPECT_EQ(kPeerAddress, connection_.peer_address());
- EXPECT_EQ(kPeerAddress, connection_.effective_peer_address());
- EXPECT_EQ(connection_.sent_packet_manager().GetSendAlgorithm(),
- send_algorithm_);
- EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
-
- // Verify that default_path_ is reverted and alternative_path_ is cleared.
- EXPECT_EQ(default_path->client_connection_id, client_cid0);
- EXPECT_EQ(default_path->server_connection_id, server_cid0);
- EXPECT_TRUE(alternative_path->server_connection_id.IsEmpty());
- EXPECT_FALSE(alternative_path->stateless_reset_token.has_value());
- auto* retire_peer_issued_cid_alarm =
- connection_.GetRetirePeerIssuedConnectionIdAlarm();
- ASSERT_TRUE(retire_peer_issued_cid_alarm->IsSet());
- EXPECT_CALL(visitor_, SendRetireConnectionId(/*sequence_number=*/1u));
- retire_peer_issued_cid_alarm->Fire();
- EXPECT_EQ(packet_creator->GetDestinationConnectionId(), client_cid0);
- EXPECT_EQ(packet_creator->GetSourceConnectionId(), server_cid0);
-}
-
-TEST_P(QuicConnectionTest, ReceivePathProbeWithNoAddressChangeAtServer) {
- PathProbeTestInit(Perspective::IS_SERVER);
-
- EXPECT_CALL(visitor_, OnConnectionMigration(PORT_CHANGE)).Times(0);
- EXPECT_CALL(visitor_, OnPacketReceived(_, _, false)).Times(0);
-
- // Process a padded PING packet with no peer address change on server side
- // will be ignored. But a PATH CHALLENGE packet with no peer address change
- // will be considered as path probing.
- std::unique_ptr<SerializedPacket> probing_packet = ConstructProbingPacket();
-
- std::unique_ptr<QuicReceivedPacket> received(ConstructReceivedPacket(
- QuicEncryptedPacket(probing_packet->encrypted_buffer,
- probing_packet->encrypted_length),
- clock_.Now()));
-
- uint64_t num_probing_received =
- connection_.GetStats().num_connectivity_probing_received;
- ProcessReceivedPacket(kSelfAddress, kPeerAddress, *received);
-
- EXPECT_EQ(num_probing_received + (GetParam().version.HasIetfQuicFrames() &&
- connection_.send_path_response()
- ? 1u
- : 0u),
- connection_.GetStats().num_connectivity_probing_received);
- EXPECT_EQ(kPeerAddress, connection_.peer_address());
- EXPECT_EQ(kPeerAddress, connection_.effective_peer_address());
-}
-
-// Regression test for b/150161358.
-TEST_P(QuicConnectionTest, BufferedMtuPacketTooBig) {
- EXPECT_CALL(visitor_, OnWriteBlocked()).Times(1);
- writer_->SetWriteBlocked();
-
- // Send a MTU packet while blocked. It should be buffered.
- connection_.SendMtuDiscoveryPacket(kMaxOutgoingPacketSize);
- EXPECT_EQ(1u, connection_.NumQueuedPackets());
- EXPECT_TRUE(writer_->IsWriteBlocked());
-
- writer_->AlwaysGetPacketTooLarge();
- writer_->SetWritable();
- connection_.OnCanWrite();
-}
-
-TEST_P(QuicConnectionTest, WriteOutOfOrderQueuedPackets) {
- // EXPECT_QUIC_BUG tests are expensive so only run one instance of them.
- if (!IsDefaultTestConfiguration()) {
- return;
- }
-
- set_perspective(Perspective::IS_CLIENT);
-
- BlockOnNextWrite();
-
- QuicStreamId stream_id = 2;
- connection_.SendStreamDataWithString(stream_id, "foo", 0, NO_FIN);
-
- EXPECT_EQ(1u, connection_.NumQueuedPackets());
-
- writer_->SetWritable();
- connection_.SendConnectivityProbingPacket(writer_.get(),
- connection_.peer_address());
- EXPECT_CALL(visitor_, OnConnectionClosed(_, _)).Times(0);
- connection_.OnCanWrite();
-}
-
-TEST_P(QuicConnectionTest, DiscardQueuedPacketsAfterConnectionClose) {
- // Regression test for b/74073386.
- {
- InSequence seq;
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
- .Times(AtLeast(1));
- EXPECT_CALL(visitor_, OnConnectionClosed(_, _)).Times(AtLeast(1));
- }
-
- set_perspective(Perspective::IS_CLIENT);
-
- writer_->SimulateNextPacketTooLarge();
-
- // This packet write should fail, which should cause the connection to close
- // after sending a connection close packet, then the failed packet should be
- // queued.
- connection_.SendStreamDataWithString(/*id=*/2, "foo", 0, NO_FIN);
-
- EXPECT_FALSE(connection_.connected());
- // No need to buffer packets.
- EXPECT_EQ(0u, connection_.NumQueuedPackets());
-
- EXPECT_EQ(0u, connection_.GetStats().packets_discarded);
- connection_.OnCanWrite();
- EXPECT_EQ(0u, connection_.GetStats().packets_discarded);
-}
-
-class TestQuicPathValidationContext : public QuicPathValidationContext {
- public:
- TestQuicPathValidationContext(const QuicSocketAddress& self_address,
- const QuicSocketAddress& peer_address,
-
- QuicPacketWriter* writer)
- : QuicPathValidationContext(self_address, peer_address),
- writer_(writer) {}
-
- QuicPacketWriter* WriterToUse() override { return writer_; }
-
- private:
- QuicPacketWriter* writer_;
-};
-
-class TestValidationResultDelegate : public QuicPathValidator::ResultDelegate {
- public:
- TestValidationResultDelegate(QuicConnection* connection,
- const QuicSocketAddress& expected_self_address,
- const QuicSocketAddress& expected_peer_address,
- bool* success)
- : QuicPathValidator::ResultDelegate(),
- connection_(connection),
- expected_self_address_(expected_self_address),
- expected_peer_address_(expected_peer_address),
- success_(success) {}
- void OnPathValidationSuccess(
- std::unique_ptr<QuicPathValidationContext> context) override {
- EXPECT_EQ(expected_self_address_, context->self_address());
- EXPECT_EQ(expected_peer_address_, context->peer_address());
- *success_ = true;
- }
-
- void OnPathValidationFailure(
- std::unique_ptr<QuicPathValidationContext> context) override {
- EXPECT_EQ(expected_self_address_, context->self_address());
- EXPECT_EQ(expected_peer_address_, context->peer_address());
- if (connection_->perspective() == Perspective::IS_CLIENT) {
- connection_->OnPathValidationFailureAtClient();
- }
- *success_ = false;
- }
-
- private:
- QuicConnection* connection_;
- QuicSocketAddress expected_self_address_;
- QuicSocketAddress expected_peer_address_;
- bool* success_;
-};
-
-// Receive a path probe request at the server side, i.e.,
-// in non-IETF version: receive a padded PING packet with a peer addess change;
-// in IETF version: receive a packet contains PATH CHALLENGE with peer address
-// change.
-TEST_P(QuicConnectionTest, ReceivePathProbingAtServer) {
- PathProbeTestInit(Perspective::IS_SERVER);
-
- EXPECT_CALL(visitor_, OnConnectionMigration(PORT_CHANGE)).Times(0);
- QuicPathFrameBuffer payload;
- if (!GetParam().version.HasIetfQuicFrames()) {
- EXPECT_CALL(visitor_,
- OnPacketReceived(_, _, /*is_connectivity_probe=*/true))
- .Times(1);
- } else {
- EXPECT_CALL(visitor_, OnPacketReceived(_, _, _)).Times(0);
- if (connection_.validate_client_address()) {
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
- .Times(AtLeast(1u))
- .WillOnce(Invoke([&]() {
- EXPECT_EQ(1u, writer_->path_challenge_frames().size());
- EXPECT_EQ(1u, writer_->path_response_frames().size());
- payload = writer_->path_challenge_frames().front().data_buffer;
- }));
- }
- }
- // Process a probing packet from a new peer address on server side
- // is effectively receiving a connectivity probing.
- const QuicSocketAddress kNewPeerAddress(QuicIpAddress::Loopback4(),
- /*port=*/23456);
-
- std::unique_ptr<SerializedPacket> probing_packet = ConstructProbingPacket();
- std::unique_ptr<QuicReceivedPacket> received(ConstructReceivedPacket(
- QuicEncryptedPacket(probing_packet->encrypted_buffer,
- probing_packet->encrypted_length),
- clock_.Now()));
- uint64_t num_probing_received =
- connection_.GetStats().num_connectivity_probing_received;
- ProcessReceivedPacket(kSelfAddress, kNewPeerAddress, *received);
-
- EXPECT_EQ(num_probing_received + 1,
- connection_.GetStats().num_connectivity_probing_received);
- EXPECT_EQ(kPeerAddress, connection_.peer_address());
- EXPECT_EQ(kPeerAddress, connection_.effective_peer_address());
- if (GetParam().version.HasIetfQuicFrames() &&
- connection_.use_path_validator() &&
- GetQuicReloadableFlag(quic_count_bytes_on_alternative_path_seperately)) {
- QuicByteCount bytes_sent =
- QuicConnectionPeer::BytesSentOnAlternativePath(&connection_);
- EXPECT_LT(0u, bytes_sent);
- EXPECT_EQ(received->length(),
- QuicConnectionPeer::BytesReceivedOnAlternativePath(&connection_));
-
- // Receiving one more probing packet should update the bytes count.
- probing_packet = ConstructProbingPacket();
- received.reset(ConstructReceivedPacket(
- QuicEncryptedPacket(probing_packet->encrypted_buffer,
- probing_packet->encrypted_length),
- clock_.Now()));
- ProcessReceivedPacket(kSelfAddress, kNewPeerAddress, *received);
-
- EXPECT_EQ(num_probing_received + 2,
- connection_.GetStats().num_connectivity_probing_received);
- EXPECT_EQ(2 * bytes_sent,
- QuicConnectionPeer::BytesSentOnAlternativePath(&connection_));
- EXPECT_EQ(2 * received->length(),
- QuicConnectionPeer::BytesReceivedOnAlternativePath(&connection_));
-
- bool success = false;
- if (!connection_.validate_client_address()) {
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
- .Times(AtLeast(1u))
- .WillOnce(Invoke([&]() {
- EXPECT_EQ(1u, writer_->path_challenge_frames().size());
- payload = writer_->path_challenge_frames().front().data_buffer;
- }));
-
- connection_.ValidatePath(
- std::make_unique<TestQuicPathValidationContext>(
- connection_.self_address(), kNewPeerAddress, writer_.get()),
- std::make_unique<TestValidationResultDelegate>(
- &connection_, connection_.self_address(), kNewPeerAddress,
- &success));
- }
- EXPECT_EQ((connection_.validate_client_address() ? 2 : 3) * bytes_sent,
- QuicConnectionPeer::BytesSentOnAlternativePath(&connection_));
- QuicFrames frames;
- frames.push_back(QuicFrame(new QuicPathResponseFrame(99, payload)));
- ProcessFramesPacketWithAddresses(frames, connection_.self_address(),
- kNewPeerAddress,
- ENCRYPTION_FORWARD_SECURE);
- EXPECT_LT(2 * received->length(),
- QuicConnectionPeer::BytesReceivedOnAlternativePath(&connection_));
- if (connection_.validate_client_address()) {
- EXPECT_TRUE(QuicConnectionPeer::IsAlternativePathValidated(&connection_));
- }
- // Receiving another probing packet from a newer address with a different
- // port shouldn't trigger another reverse path validation.
- QuicSocketAddress kNewerPeerAddress(QuicIpAddress::Loopback4(),
- /*port=*/34567);
- probing_packet = ConstructProbingPacket();
- received.reset(ConstructReceivedPacket(
- QuicEncryptedPacket(probing_packet->encrypted_buffer,
- probing_packet->encrypted_length),
- clock_.Now()));
- ProcessReceivedPacket(kSelfAddress, kNewerPeerAddress, *received);
- EXPECT_FALSE(connection_.HasPendingPathValidation());
- EXPECT_EQ(connection_.validate_client_address(),
- QuicConnectionPeer::IsAlternativePathValidated(&connection_));
- }
-
- // Process another packet with the old peer address on server side will not
- // start peer migration.
- EXPECT_CALL(visitor_, OnConnectionMigration(PORT_CHANGE)).Times(0);
- ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress, kPeerAddress,
- ENCRYPTION_INITIAL);
- EXPECT_EQ(kPeerAddress, connection_.peer_address());
- EXPECT_EQ(kPeerAddress, connection_.effective_peer_address());
-}
-
-// Receive a padded PING packet with a port change on server side.
-TEST_P(QuicConnectionTest, ReceivePaddedPingWithPortChangeAtServer) {
- set_perspective(Perspective::IS_SERVER);
- QuicPacketCreatorPeer::SetSendVersionInPacket(creator_, false);
- EXPECT_EQ(Perspective::IS_SERVER, connection_.perspective());
- if (version().SupportsAntiAmplificationLimit()) {
- QuicConnectionPeer::SetAddressValidated(&connection_);
- }
-
- // Clear direct_peer_address.
- QuicConnectionPeer::SetDirectPeerAddress(&connection_, QuicSocketAddress());
- // Clear effective_peer_address, it is the same as direct_peer_address for
- // this test.
- QuicConnectionPeer::SetEffectivePeerAddress(&connection_,
- QuicSocketAddress());
- EXPECT_FALSE(connection_.effective_peer_address().IsInitialized());
-
- if (GetParam().version.UsesCryptoFrames()) {
- EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
- } else {
- EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber());
- }
- ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress, kPeerAddress,
- ENCRYPTION_INITIAL);
- EXPECT_EQ(kPeerAddress, connection_.peer_address());
- EXPECT_EQ(kPeerAddress, connection_.effective_peer_address());
-
- if (GetParam().version.HasIetfQuicFrames()) {
- // In IETF version, a padded PING packet with port change is not taken as
- // connectivity probe.
- EXPECT_CALL(visitor_, GetHandshakeState())
- .WillRepeatedly(Return(HANDSHAKE_CONFIRMED));
- EXPECT_CALL(visitor_, OnConnectionMigration(PORT_CHANGE)).Times(1);
- EXPECT_CALL(visitor_, OnPacketReceived(_, _, _)).Times(0);
- } else {
- // In non-IETF version, process a padded PING packet from a new peer
- // address on server side is effectively receiving a connectivity probing.
- EXPECT_CALL(visitor_, OnConnectionMigration(PORT_CHANGE)).Times(0);
- EXPECT_CALL(visitor_,
- OnPacketReceived(_, _, /*is_connectivity_probe=*/true))
- .Times(1);
- }
- const QuicSocketAddress kNewPeerAddress =
- QuicSocketAddress(QuicIpAddress::Loopback6(), /*port=*/23456);
-
- QuicFrames frames;
- // Write a PING frame, which has no data payload.
- QuicPingFrame ping_frame;
- frames.push_back(QuicFrame(ping_frame));
-
- // Add padding to the rest of the packet.
- QuicPaddingFrame padding_frame;
- frames.push_back(QuicFrame(padding_frame));
-
- uint64_t num_probing_received =
- connection_.GetStats().num_connectivity_probing_received;
-
- ProcessFramesPacketWithAddresses(frames, kSelfAddress, kNewPeerAddress,
- ENCRYPTION_INITIAL);
-
- if (GetParam().version.HasIetfQuicFrames()) {
- // Padded PING with port changen is not considered as connectivity probe but
- // a PORT CHANGE.
- EXPECT_EQ(num_probing_received,
- connection_.GetStats().num_connectivity_probing_received);
- EXPECT_EQ(kNewPeerAddress, connection_.peer_address());
- EXPECT_EQ(kNewPeerAddress, connection_.effective_peer_address());
- } else {
- EXPECT_EQ(num_probing_received + 1,
- connection_.GetStats().num_connectivity_probing_received);
- EXPECT_EQ(kPeerAddress, connection_.peer_address());
- EXPECT_EQ(kPeerAddress, connection_.effective_peer_address());
- }
-
- if (GetParam().version.HasIetfQuicFrames()) {
- EXPECT_CALL(visitor_, OnConnectionMigration(PORT_CHANGE)).Times(1);
- }
- // Process another packet with the old peer address on server side. gQUIC
- // shouldn't regard this as a peer migration.
- ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress, kPeerAddress,
- ENCRYPTION_INITIAL);
- EXPECT_EQ(kPeerAddress, connection_.peer_address());
- EXPECT_EQ(kPeerAddress, connection_.effective_peer_address());
-}
-
-TEST_P(QuicConnectionTest, ReceiveReorderedPathProbingAtServer) {
- PathProbeTestInit(Perspective::IS_SERVER);
-
- // Decrease packet number to simulate out-of-order packets.
- QuicPacketCreatorPeer::SetPacketNumber(&peer_creator_, 4);
-
- EXPECT_CALL(visitor_, OnConnectionMigration(PORT_CHANGE)).Times(0);
- if (!GetParam().version.HasIetfQuicFrames()) {
- EXPECT_CALL(visitor_,
- OnPacketReceived(_, _, /*is_connectivity_probe=*/true))
- .Times(1);
- } else {
- EXPECT_CALL(visitor_, OnPacketReceived(_, _, _)).Times(0);
- }
-
- // Process a padded PING packet from a new peer address on server side
- // is effectively receiving a connectivity probing, even if a newer packet has
- // been received before this one.
- const QuicSocketAddress kNewPeerAddress =
- QuicSocketAddress(QuicIpAddress::Loopback6(), /*port=*/23456);
-
- std::unique_ptr<SerializedPacket> probing_packet = ConstructProbingPacket();
- std::unique_ptr<QuicReceivedPacket> received(ConstructReceivedPacket(
- QuicEncryptedPacket(probing_packet->encrypted_buffer,
- probing_packet->encrypted_length),
- clock_.Now()));
-
- uint64_t num_probing_received =
- connection_.GetStats().num_connectivity_probing_received;
- ProcessReceivedPacket(kSelfAddress, kNewPeerAddress, *received);
-
- EXPECT_EQ(num_probing_received + 1,
- connection_.GetStats().num_connectivity_probing_received);
- EXPECT_EQ(kPeerAddress, connection_.peer_address());
- EXPECT_EQ(kPeerAddress, connection_.effective_peer_address());
-}
-
-TEST_P(QuicConnectionTest, MigrateAfterProbingAtServer) {
- PathProbeTestInit(Perspective::IS_SERVER);
-
- EXPECT_CALL(visitor_, OnConnectionMigration(PORT_CHANGE)).Times(0);
- if (!GetParam().version.HasIetfQuicFrames()) {
- EXPECT_CALL(visitor_,
- OnPacketReceived(_, _, /*is_connectivity_probe=*/true))
- .Times(1);
- } else {
- EXPECT_CALL(visitor_, OnPacketReceived(_, _, _)).Times(0);
- }
-
- // Process a padded PING packet from a new peer address on server side
- // is effectively receiving a connectivity probing.
- const QuicSocketAddress kNewPeerAddress =
- QuicSocketAddress(QuicIpAddress::Loopback6(), /*port=*/23456);
-
- std::unique_ptr<SerializedPacket> probing_packet = ConstructProbingPacket();
- std::unique_ptr<QuicReceivedPacket> received(ConstructReceivedPacket(
- QuicEncryptedPacket(probing_packet->encrypted_buffer,
- probing_packet->encrypted_length),
- clock_.Now()));
- ProcessReceivedPacket(kSelfAddress, kNewPeerAddress, *received);
- EXPECT_EQ(kPeerAddress, connection_.peer_address());
- EXPECT_EQ(kPeerAddress, connection_.effective_peer_address());
-
- // Process another non-probing packet with the new peer address on server
- // side will start peer migration.
- EXPECT_CALL(visitor_, OnConnectionMigration(PORT_CHANGE)).Times(1);
-
- ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress,
- kNewPeerAddress, ENCRYPTION_INITIAL);
- EXPECT_EQ(kNewPeerAddress, connection_.peer_address());
- EXPECT_EQ(kNewPeerAddress, connection_.effective_peer_address());
-}
-
-TEST_P(QuicConnectionTest, ReceiveConnectivityProbingPacketAtClient) {
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- PathProbeTestInit(Perspective::IS_CLIENT);
-
- // Client takes all padded PING packet as speculative connectivity
- // probing packet, and reports to visitor.
- EXPECT_CALL(visitor_, OnConnectionMigration(PORT_CHANGE)).Times(0);
- if (!connection_.send_path_response()) {
- EXPECT_CALL(visitor_, OnPacketReceived(_, _, false)).Times(1);
- }
-
- std::unique_ptr<SerializedPacket> probing_packet = ConstructProbingPacket();
- std::unique_ptr<QuicReceivedPacket> received(ConstructReceivedPacket(
- QuicEncryptedPacket(probing_packet->encrypted_buffer,
- probing_packet->encrypted_length),
- clock_.Now()));
- uint64_t num_probing_received =
- connection_.GetStats().num_connectivity_probing_received;
- ProcessReceivedPacket(kSelfAddress, kPeerAddress, *received);
-
- EXPECT_EQ(num_probing_received + (GetParam().version.HasIetfQuicFrames() &&
- connection_.send_path_response()
- ? 1u
- : 0u),
- connection_.GetStats().num_connectivity_probing_received);
- EXPECT_EQ(kPeerAddress, connection_.peer_address());
- EXPECT_EQ(kPeerAddress, connection_.effective_peer_address());
-}
-
-TEST_P(QuicConnectionTest, ReceiveConnectivityProbingResponseAtClient) {
- // TODO(b/150095484): add test coverage for IETF to verify that client takes
- // PATH RESPONSE with peer address change as correct validation on the new
- // path.
- if (GetParam().version.HasIetfQuicFrames()) {
- return;
- }
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- PathProbeTestInit(Perspective::IS_CLIENT);
-
- // Process a padded PING packet with a different self address on client side
- // is effectively receiving a connectivity probing.
- EXPECT_CALL(visitor_, OnConnectionMigration(PORT_CHANGE)).Times(0);
- if (!GetParam().version.HasIetfQuicFrames()) {
- EXPECT_CALL(visitor_,
- OnPacketReceived(_, _, /*is_connectivity_probe=*/true))
- .Times(1);
- } else {
- EXPECT_CALL(visitor_, OnPacketReceived(_, _, _)).Times(0);
- }
-
- const QuicSocketAddress kNewSelfAddress =
- QuicSocketAddress(QuicIpAddress::Loopback6(), /*port=*/23456);
-
- std::unique_ptr<SerializedPacket> probing_packet = ConstructProbingPacket();
- std::unique_ptr<QuicReceivedPacket> received(ConstructReceivedPacket(
- QuicEncryptedPacket(probing_packet->encrypted_buffer,
- probing_packet->encrypted_length),
- clock_.Now()));
- uint64_t num_probing_received =
- connection_.GetStats().num_connectivity_probing_received;
- ProcessReceivedPacket(kNewSelfAddress, kPeerAddress, *received);
-
- EXPECT_EQ(num_probing_received + 1,
- connection_.GetStats().num_connectivity_probing_received);
- EXPECT_EQ(kPeerAddress, connection_.peer_address());
- EXPECT_EQ(kPeerAddress, connection_.effective_peer_address());
-}
-
-TEST_P(QuicConnectionTest, PeerAddressChangeAtClient) {
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- set_perspective(Perspective::IS_CLIENT);
- EXPECT_EQ(Perspective::IS_CLIENT, connection_.perspective());
-
- // Clear direct_peer_address.
- QuicConnectionPeer::SetDirectPeerAddress(&connection_, QuicSocketAddress());
- // Clear effective_peer_address, it is the same as direct_peer_address for
- // this test.
- QuicConnectionPeer::SetEffectivePeerAddress(&connection_,
- QuicSocketAddress());
- EXPECT_FALSE(connection_.effective_peer_address().IsInitialized());
-
- if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
- EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
- } else {
- EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber());
- }
- ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress, kPeerAddress,
- ENCRYPTION_INITIAL);
- EXPECT_EQ(kPeerAddress, connection_.peer_address());
- EXPECT_EQ(kPeerAddress, connection_.effective_peer_address());
-
- // Process another packet with a different peer address on client side will
- // only update peer address.
- const QuicSocketAddress kNewPeerAddress =
- QuicSocketAddress(QuicIpAddress::Loopback6(), /*port=*/23456);
- EXPECT_CALL(visitor_, OnConnectionMigration(PORT_CHANGE)).Times(0);
- ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress,
- kNewPeerAddress, ENCRYPTION_INITIAL);
- if (connection_.version().HasIetfQuicFrames()) {
- // IETF QUIC disallows server initiated address change.
- EXPECT_EQ(kPeerAddress, connection_.peer_address());
- EXPECT_EQ(kPeerAddress, connection_.effective_peer_address());
- } else {
- EXPECT_EQ(kNewPeerAddress, connection_.peer_address());
- EXPECT_EQ(kNewPeerAddress, connection_.effective_peer_address());
- }
-}
-
-TEST_P(QuicConnectionTest, MaxPacketSize) {
- EXPECT_EQ(Perspective::IS_CLIENT, connection_.perspective());
- EXPECT_EQ(1250u, connection_.max_packet_length());
-}
-
-TEST_P(QuicConnectionTest, PeerLowersMaxPacketSize) {
- EXPECT_EQ(Perspective::IS_CLIENT, connection_.perspective());
-
- // SetFromConfig is always called after construction from InitializeSession.
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
- constexpr uint32_t kTestMaxPacketSize = 1233u;
- QuicConfig config;
- QuicConfigPeer::SetReceivedMaxPacketSize(&config, kTestMaxPacketSize);
- connection_.SetFromConfig(config);
-
- EXPECT_EQ(kTestMaxPacketSize, connection_.max_packet_length());
-}
-
-TEST_P(QuicConnectionTest, PeerCannotRaiseMaxPacketSize) {
- EXPECT_EQ(Perspective::IS_CLIENT, connection_.perspective());
-
- // SetFromConfig is always called after construction from InitializeSession.
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
- constexpr uint32_t kTestMaxPacketSize = 1450u;
- QuicConfig config;
- QuicConfigPeer::SetReceivedMaxPacketSize(&config, kTestMaxPacketSize);
- connection_.SetFromConfig(config);
-
- EXPECT_EQ(kDefaultMaxPacketSize, connection_.max_packet_length());
-}
-
-TEST_P(QuicConnectionTest, SmallerServerMaxPacketSize) {
- TestConnection connection(TestConnectionId(), kSelfAddress, kPeerAddress,
- helper_.get(), alarm_factory_.get(), writer_.get(),
- Perspective::IS_SERVER, version());
- EXPECT_EQ(Perspective::IS_SERVER, connection.perspective());
- EXPECT_EQ(1000u, connection.max_packet_length());
-}
-
-TEST_P(QuicConnectionTest, LowerServerResponseMtuTest) {
- set_perspective(Perspective::IS_SERVER);
- connection_.SetMaxPacketLength(1000);
- EXPECT_EQ(1000u, connection_.max_packet_length());
-
- SetQuicFlag(FLAGS_quic_use_lower_server_response_mtu_for_test, true);
- EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(::testing::AtMost(1));
- EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(::testing::AtMost(1));
- ProcessCryptoPacketAtLevel(1, ENCRYPTION_INITIAL);
- EXPECT_EQ(1250u, connection_.max_packet_length());
-}
-
-TEST_P(QuicConnectionTest, IncreaseServerMaxPacketSize) {
- set_perspective(Perspective::IS_SERVER);
- connection_.SetMaxPacketLength(1000);
-
- QuicPacketHeader header;
- header.destination_connection_id = connection_id_;
- header.version_flag = true;
- header.packet_number = QuicPacketNumber(12);
-
- if (QuicVersionHasLongHeaderLengths(
- peer_framer_.version().transport_version)) {
- header.long_packet_type = INITIAL;
- header.retry_token_length_length = VARIABLE_LENGTH_INTEGER_LENGTH_1;
- header.length_length = VARIABLE_LENGTH_INTEGER_LENGTH_2;
- }
-
- QuicFrames frames;
- QuicPaddingFrame padding;
- if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
- frames.push_back(QuicFrame(&crypto_frame_));
- } else {
- frames.push_back(QuicFrame(frame1_));
- }
- frames.push_back(QuicFrame(padding));
- std::unique_ptr<QuicPacket> packet(ConstructPacket(header, frames));
- char buffer[kMaxOutgoingPacketSize];
- size_t encrypted_length =
- peer_framer_.EncryptPayload(ENCRYPTION_INITIAL, QuicPacketNumber(12),
- *packet, buffer, kMaxOutgoingPacketSize);
- EXPECT_EQ(kMaxOutgoingPacketSize, encrypted_length);
-
- framer_.set_version(version());
- if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
- EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(1);
- } else {
- EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
- }
- connection_.ProcessUdpPacket(
- kSelfAddress, kPeerAddress,
- QuicReceivedPacket(buffer, encrypted_length, QuicTime::Zero(), false));
-
- EXPECT_EQ(kMaxOutgoingPacketSize, connection_.max_packet_length());
-}
-
-TEST_P(QuicConnectionTest, IncreaseServerMaxPacketSizeWhileWriterLimited) {
- const QuicByteCount lower_max_packet_size = 1240;
- writer_->set_max_packet_size(lower_max_packet_size);
- set_perspective(Perspective::IS_SERVER);
- connection_.SetMaxPacketLength(1000);
- EXPECT_EQ(1000u, connection_.max_packet_length());
-
- QuicPacketHeader header;
- header.destination_connection_id = connection_id_;
- header.version_flag = true;
- header.packet_number = QuicPacketNumber(12);
-
- if (QuicVersionHasLongHeaderLengths(
- peer_framer_.version().transport_version)) {
- header.long_packet_type = INITIAL;
- header.retry_token_length_length = VARIABLE_LENGTH_INTEGER_LENGTH_1;
- header.length_length = VARIABLE_LENGTH_INTEGER_LENGTH_2;
- }
-
- QuicFrames frames;
- QuicPaddingFrame padding;
- if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
- frames.push_back(QuicFrame(&crypto_frame_));
- } else {
- frames.push_back(QuicFrame(frame1_));
- }
- frames.push_back(QuicFrame(padding));
- std::unique_ptr<QuicPacket> packet(ConstructPacket(header, frames));
- char buffer[kMaxOutgoingPacketSize];
- size_t encrypted_length =
- peer_framer_.EncryptPayload(ENCRYPTION_INITIAL, QuicPacketNumber(12),
- *packet, buffer, kMaxOutgoingPacketSize);
- EXPECT_EQ(kMaxOutgoingPacketSize, encrypted_length);
-
- framer_.set_version(version());
- if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
- EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(1);
- } else {
- EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
- }
- connection_.ProcessUdpPacket(
- kSelfAddress, kPeerAddress,
- QuicReceivedPacket(buffer, encrypted_length, QuicTime::Zero(), false));
-
- // Here, the limit imposed by the writer is lower than the size of the packet
- // received, so the writer max packet size is used.
- EXPECT_EQ(lower_max_packet_size, connection_.max_packet_length());
-}
-
-TEST_P(QuicConnectionTest, LimitMaxPacketSizeByWriter) {
- const QuicByteCount lower_max_packet_size = 1240;
- writer_->set_max_packet_size(lower_max_packet_size);
-
- static_assert(lower_max_packet_size < kDefaultMaxPacketSize,
- "Default maximum packet size is too low");
- connection_.SetMaxPacketLength(kDefaultMaxPacketSize);
-
- EXPECT_EQ(lower_max_packet_size, connection_.max_packet_length());
-}
-
-TEST_P(QuicConnectionTest, LimitMaxPacketSizeByWriterForNewConnection) {
- const QuicConnectionId connection_id = TestConnectionId(17);
- const QuicByteCount lower_max_packet_size = 1240;
- writer_->set_max_packet_size(lower_max_packet_size);
- TestConnection connection(connection_id, kSelfAddress, kPeerAddress,
- helper_.get(), alarm_factory_.get(), writer_.get(),
- Perspective::IS_CLIENT, version());
- EXPECT_EQ(Perspective::IS_CLIENT, connection.perspective());
- EXPECT_EQ(lower_max_packet_size, connection.max_packet_length());
-}
-
-TEST_P(QuicConnectionTest, PacketsInOrder) {
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-
- ProcessPacket(1);
- EXPECT_EQ(QuicPacketNumber(1u), LargestAcked(connection_.ack_frame()));
- EXPECT_EQ(1u, connection_.ack_frame().packets.NumIntervals());
-
- ProcessPacket(2);
- EXPECT_EQ(QuicPacketNumber(2u), LargestAcked(connection_.ack_frame()));
- EXPECT_EQ(1u, connection_.ack_frame().packets.NumIntervals());
-
- ProcessPacket(3);
- EXPECT_EQ(QuicPacketNumber(3u), LargestAcked(connection_.ack_frame()));
- EXPECT_EQ(1u, connection_.ack_frame().packets.NumIntervals());
-}
-
-TEST_P(QuicConnectionTest, PacketsOutOfOrder) {
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-
- ProcessPacket(3);
- EXPECT_EQ(QuicPacketNumber(3u), LargestAcked(connection_.ack_frame()));
- EXPECT_TRUE(IsMissing(2));
- EXPECT_TRUE(IsMissing(1));
-
- ProcessPacket(2);
- EXPECT_EQ(QuicPacketNumber(3u), LargestAcked(connection_.ack_frame()));
- EXPECT_FALSE(IsMissing(2));
- EXPECT_TRUE(IsMissing(1));
-
- ProcessPacket(1);
- EXPECT_EQ(QuicPacketNumber(3u), LargestAcked(connection_.ack_frame()));
- EXPECT_FALSE(IsMissing(2));
- EXPECT_FALSE(IsMissing(1));
-}
-
-TEST_P(QuicConnectionTest, DuplicatePacket) {
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-
- ProcessPacket(3);
- EXPECT_EQ(QuicPacketNumber(3u), LargestAcked(connection_.ack_frame()));
- EXPECT_TRUE(IsMissing(2));
- EXPECT_TRUE(IsMissing(1));
-
- // Send packet 3 again, but do not set the expectation that
- // the visitor OnStreamFrame() will be called.
- ProcessDataPacket(3);
- EXPECT_EQ(QuicPacketNumber(3u), LargestAcked(connection_.ack_frame()));
- EXPECT_TRUE(IsMissing(2));
- EXPECT_TRUE(IsMissing(1));
-}
-
-TEST_P(QuicConnectionTest, PacketsOutOfOrderWithAdditionsAndLeastAwaiting) {
- if (connection_.SupportsMultiplePacketNumberSpaces()) {
- return;
- }
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-
- ProcessPacket(3);
- EXPECT_EQ(QuicPacketNumber(3u), LargestAcked(connection_.ack_frame()));
- EXPECT_TRUE(IsMissing(2));
- EXPECT_TRUE(IsMissing(1));
-
- ProcessPacket(2);
- EXPECT_EQ(QuicPacketNumber(3u), LargestAcked(connection_.ack_frame()));
- EXPECT_TRUE(IsMissing(1));
-
- ProcessPacket(5);
- EXPECT_EQ(QuicPacketNumber(5u), LargestAcked(connection_.ack_frame()));
- EXPECT_TRUE(IsMissing(1));
- EXPECT_TRUE(IsMissing(4));
-
- // Pretend at this point the client has gotten acks for 2 and 3 and 1 is a
- // packet the peer will not retransmit. It indicates this by sending 'least
- // awaiting' is 4. The connection should then realize 1 will not be
- // retransmitted, and will remove it from the missing list.
- QuicAckFrame frame = InitAckFrame(1);
- EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _));
- ProcessAckPacket(6, &frame);
-
- // Force an ack to be sent.
- SendAckPacketToPeer();
- EXPECT_TRUE(IsMissing(4));
-}
-
-TEST_P(QuicConnectionTest, RejectUnencryptedStreamData) {
- // EXPECT_QUIC_BUG tests are expensive so only run one instance of them.
- if (!IsDefaultTestConfiguration() ||
- VersionHasIetfQuicFrames(version().transport_version)) {
- return;
- }
-
- // Process an unencrypted packet from the non-crypto stream.
- frame1_.stream_id = 3;
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- EXPECT_CALL(visitor_,
- OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF));
- EXPECT_QUIC_PEER_BUG(ProcessDataPacketAtLevel(1, false, ENCRYPTION_INITIAL),
- "");
- TestConnectionCloseQuicErrorCode(QUIC_UNENCRYPTED_STREAM_DATA);
-}
-
-TEST_P(QuicConnectionTest, OutOfOrderReceiptCausesAckSend) {
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-
- ProcessPacket(3);
- // Should not cause an ack.
- EXPECT_EQ(0u, writer_->packets_write_attempts());
-
- ProcessPacket(2);
- // Should ack immediately, since this fills the last hole.
- EXPECT_EQ(1u, writer_->packets_write_attempts());
-
- ProcessPacket(1);
- // Should ack immediately, since this fills the last hole.
- EXPECT_EQ(2u, writer_->packets_write_attempts());
-
- ProcessPacket(4);
- // Should not cause an ack.
- EXPECT_EQ(2u, writer_->packets_write_attempts());
-}
-
-TEST_P(QuicConnectionTest, OutOfOrderAckReceiptCausesNoAck) {
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-
- SendStreamDataToPeer(1, "foo", 0, NO_FIN, nullptr);
- SendStreamDataToPeer(1, "bar", 3, NO_FIN, nullptr);
- EXPECT_EQ(2u, writer_->packets_write_attempts());
-
- QuicAckFrame ack1 = InitAckFrame(1);
- QuicAckFrame ack2 = InitAckFrame(2);
- EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
- if (connection_.SupportsMultiplePacketNumberSpaces()) {
- EXPECT_CALL(visitor_, OnOneRttPacketAcknowledged()).Times(1);
- }
- ProcessAckPacket(2, &ack2);
- // Should ack immediately since we have missing packets.
- EXPECT_EQ(2u, writer_->packets_write_attempts());
-
- if (connection_.SupportsMultiplePacketNumberSpaces()) {
- EXPECT_CALL(visitor_, OnOneRttPacketAcknowledged()).Times(0);
- }
- ProcessAckPacket(1, &ack1);
- // Should not ack an ack filling a missing packet.
- EXPECT_EQ(2u, writer_->packets_write_attempts());
-}
-
-TEST_P(QuicConnectionTest, AckReceiptCausesAckSend) {
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- QuicPacketNumber original, second;
-
- QuicByteCount packet_size =
- SendStreamDataToPeer(3, "foo", 0, NO_FIN, &original); // 1st packet.
- SendStreamDataToPeer(3, "bar", 3, NO_FIN, &second); // 2nd packet.
-
- QuicAckFrame frame = InitAckFrame({{second, second + 1}});
- // First nack triggers early retransmit.
- LostPacketVector lost_packets;
- lost_packets.push_back(LostPacket(original, kMaxOutgoingPacketSize));
- EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _))
- .WillOnce(DoAll(SetArgPointee<5>(lost_packets),
- Return(LossDetectionInterface::DetectionStats())));
- EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
- QuicPacketNumber retransmission;
- // Packet 1 is short header for IETF QUIC because the encryption level
- // switched to ENCRYPTION_FORWARD_SECURE in SendStreamDataToPeer.
- EXPECT_CALL(*send_algorithm_,
- OnPacketSent(_, _, _,
- GetParam().version.HasIetfInvariantHeader()
- ? packet_size
- : packet_size - kQuicVersionSize,
- _))
- .WillOnce(SaveArg<2>(&retransmission));
-
- ProcessAckPacket(&frame);
-
- QuicAckFrame frame2 = ConstructAckFrame(retransmission, original);
- EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
- EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _));
- ProcessAckPacket(&frame2);
-
- // Now if the peer sends an ack which still reports the retransmitted packet
- // as missing, that will bundle an ack with data after two acks in a row
- // indicate the high water mark needs to be raised.
- EXPECT_CALL(*send_algorithm_,
- OnPacketSent(_, _, _, _, HAS_RETRANSMITTABLE_DATA));
- connection_.SendStreamDataWithString(3, "foo", 6, NO_FIN);
- // No ack sent.
- size_t padding_frame_count = writer_->padding_frames().size();
- EXPECT_EQ(padding_frame_count + 1u, writer_->frame_count());
- EXPECT_EQ(1u, writer_->stream_frames().size());
-
- // No more packet loss for the rest of the test.
- EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _))
- .Times(AnyNumber());
- ProcessAckPacket(&frame2);
- EXPECT_CALL(*send_algorithm_,
- OnPacketSent(_, _, _, _, HAS_RETRANSMITTABLE_DATA));
- connection_.SendStreamDataWithString(3, "foofoofoo", 9, NO_FIN);
- // Ack bundled.
- if (GetParam().no_stop_waiting) {
- // Do not ACK acks.
- EXPECT_EQ(1u, writer_->frame_count());
- } else {
- EXPECT_EQ(3u, writer_->frame_count());
- }
- EXPECT_EQ(1u, writer_->stream_frames().size());
- if (GetParam().no_stop_waiting) {
- EXPECT_TRUE(writer_->ack_frames().empty());
- } else {
- EXPECT_FALSE(writer_->ack_frames().empty());
- }
-
- // But an ack with no missing packets will not send an ack.
- AckPacket(original, &frame2);
- ProcessAckPacket(&frame2);
- ProcessAckPacket(&frame2);
-}
-
-TEST_P(QuicConnectionTest, AckFrequencyUpdatedFromAckFrequencyFrame) {
- if (!GetParam().version.HasIetfQuicFrames()) {
- return;
- }
- connection_.set_can_receive_ack_frequency_frame();
-
- // Expect 13 acks, every 3rd packet including the first packet with
- // AckFrequencyFrame.
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(13);
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-
- QuicAckFrequencyFrame ack_frequency_frame;
- ack_frequency_frame.packet_tolerance = 3;
- ProcessFramePacketAtLevel(1, QuicFrame(&ack_frequency_frame),
- ENCRYPTION_FORWARD_SECURE);
-
- EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(38);
- // Receives packets 2 - 39.
- for (size_t i = 2; i <= 39; ++i) {
- ProcessDataPacket(i);
- }
-}
-
-TEST_P(QuicConnectionTest, AckDecimationReducesAcks) {
- const size_t kMinRttMs = 40;
- RttStats* rtt_stats = const_cast<RttStats*>(manager_->GetRttStats());
- rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(kMinRttMs),
- QuicTime::Delta::Zero(), QuicTime::Zero());
- EXPECT_CALL(visitor_, OnAckNeedsRetransmittableFrame()).Times(AnyNumber());
-
- // Start ack decimation from 10th packet.
- connection_.set_min_received_before_ack_decimation(10);
-
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(30);
-
- // Expect 6 acks: 5 acks between packets 1-10, and ack at 20.
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(6);
- // Receives packets 1 - 29.
- for (size_t i = 1; i <= 29; ++i) {
- ProcessDataPacket(i);
- }
-
- // We now receive the 30th packet, and so we send an ack.
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
- ProcessDataPacket(30);
-}
-
-TEST_P(QuicConnectionTest, AckNeedsRetransmittableFrames) {
- connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(99);
-
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(19);
- // Receives packets 1 - 39.
- for (size_t i = 1; i <= 39; ++i) {
- ProcessDataPacket(i);
- }
- // Receiving Packet 40 causes 20th ack to send. Session is informed and adds
- // WINDOW_UPDATE.
- EXPECT_CALL(visitor_, OnAckNeedsRetransmittableFrame())
- .WillOnce(Invoke([this]() {
- connection_.SendControlFrame(
- QuicFrame(new QuicWindowUpdateFrame(1, 0, 0)));
- }));
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
- EXPECT_EQ(0u, writer_->window_update_frames().size());
- ProcessDataPacket(40);
- EXPECT_EQ(1u, writer_->window_update_frames().size());
-
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(9);
- // Receives packets 41 - 59.
- for (size_t i = 41; i <= 59; ++i) {
- ProcessDataPacket(i);
- }
- // Send a packet containing stream frame.
- SendStreamDataToPeer(
- QuicUtils::GetFirstBidirectionalStreamId(
- connection_.version().transport_version, Perspective::IS_CLIENT),
- "bar", 0, NO_FIN, nullptr);
-
- // Session will not be informed until receiving another 20 packets.
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(19);
- for (size_t i = 60; i <= 98; ++i) {
- ProcessDataPacket(i);
- EXPECT_EQ(0u, writer_->window_update_frames().size());
- }
- // Session does not add a retransmittable frame.
- EXPECT_CALL(visitor_, OnAckNeedsRetransmittableFrame())
- .WillOnce(Invoke([this]() {
- connection_.SendControlFrame(QuicFrame(QuicPingFrame(1)));
- }));
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
- EXPECT_EQ(0u, writer_->ping_frames().size());
- ProcessDataPacket(99);
- EXPECT_EQ(0u, writer_->window_update_frames().size());
- // A ping frame will be added.
- EXPECT_EQ(1u, writer_->ping_frames().size());
-}
-
-TEST_P(QuicConnectionTest, AckNeedsRetransmittableFramesAfterPto) {
- // Disable TLP so the RTO fires immediately.
- connection_.SetMaxTailLossProbes(0);
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
- QuicConfig config;
- QuicTagVector connection_options;
- connection_options.push_back(kEACK);
- config.SetConnectionOptionsToSend(connection_options);
- connection_.SetFromConfig(config);
-
- connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
- connection_.OnHandshakeComplete();
-
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(10);
-
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(4);
- // Receive packets 1 - 9.
- for (size_t i = 1; i <= 9; ++i) {
- ProcessDataPacket(i);
- }
-
- // Send a ping and fire the retransmission alarm.
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(2);
- SendPing();
- QuicTime retransmission_time =
- connection_.GetRetransmissionAlarm()->deadline();
- clock_.AdvanceTime(retransmission_time - clock_.Now());
- connection_.GetRetransmissionAlarm()->Fire();
- ASSERT_TRUE(manager_->GetConsecutiveRtoCount() > 0 ||
- manager_->GetConsecutivePtoCount() > 0);
-
- // Process a packet, which requests a retransmittable frame be bundled
- // with the ACK.
- EXPECT_CALL(visitor_, OnAckNeedsRetransmittableFrame())
- .WillOnce(Invoke([this]() {
- connection_.SendControlFrame(
- QuicFrame(new QuicWindowUpdateFrame(1, 0, 0)));
- }));
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
- ProcessDataPacket(11);
- EXPECT_EQ(1u, writer_->window_update_frames().size());
-}
-
-TEST_P(QuicConnectionTest, LeastUnackedLower) {
- if (GetParam().version.HasIetfInvariantHeader()) {
- return;
- }
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-
- SendStreamDataToPeer(1, "foo", 0, NO_FIN, nullptr);
- SendStreamDataToPeer(1, "bar", 3, NO_FIN, nullptr);
- SendStreamDataToPeer(1, "eep", 6, NO_FIN, nullptr);
-
- // Start out saying the least unacked is 2.
- QuicPacketCreatorPeer::SetPacketNumber(&peer_creator_, 5);
- ProcessStopWaitingPacket(InitStopWaitingFrame(2));
-
- // Change it to 1, but lower the packet number to fake out-of-order packets.
- // This should be fine.
- QuicPacketCreatorPeer::SetPacketNumber(&peer_creator_, 1);
- // The scheduler will not process out of order acks, but all packet processing
- // causes the connection to try to write.
- if (!GetParam().no_stop_waiting) {
- EXPECT_CALL(visitor_, OnCanWrite());
- }
- ProcessStopWaitingPacket(InitStopWaitingFrame(1));
-
- // Now claim it's one, but set the ordering so it was sent "after" the first
- // one. This should cause a connection error.
- QuicPacketCreatorPeer::SetPacketNumber(&peer_creator_, 7);
- if (!GetParam().no_stop_waiting) {
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
- .Times(AtLeast(1));
- EXPECT_CALL(visitor_,
- OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF))
- .Times(AtLeast(1));
- }
- ProcessStopWaitingPacket(InitStopWaitingFrame(1));
- if (!GetParam().no_stop_waiting) {
- TestConnectionCloseQuicErrorCode(QUIC_INVALID_STOP_WAITING_DATA);
- }
-}
-
-TEST_P(QuicConnectionTest, TooManySentPackets) {
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-
- QuicPacketCount max_tracked_packets = 50;
- QuicConnectionPeer::SetMaxTrackedPackets(&connection_, max_tracked_packets);
-
- const int num_packets = max_tracked_packets + 5;
-
- for (int i = 0; i < num_packets; ++i) {
- SendStreamDataToPeer(1, "foo", 3 * i, NO_FIN, nullptr);
- }
-
- EXPECT_CALL(visitor_,
- OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF));
-
- ProcessFramePacket(QuicFrame(QuicPingFrame()));
-
- TestConnectionCloseQuicErrorCode(QUIC_TOO_MANY_OUTSTANDING_SENT_PACKETS);
-}
-
-TEST_P(QuicConnectionTest, LargestObservedLower) {
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-
- SendStreamDataToPeer(1, "foo", 0, NO_FIN, nullptr);
- SendStreamDataToPeer(1, "bar", 3, NO_FIN, nullptr);
- SendStreamDataToPeer(1, "eep", 6, NO_FIN, nullptr);
- EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
-
- // Start out saying the largest observed is 2.
- QuicAckFrame frame1 = InitAckFrame(1);
- QuicAckFrame frame2 = InitAckFrame(2);
- ProcessAckPacket(&frame2);
-
- EXPECT_CALL(visitor_, OnCanWrite());
- ProcessAckPacket(&frame1);
-}
-
-TEST_P(QuicConnectionTest, AckUnsentData) {
- // Ack a packet which has not been sent.
- EXPECT_CALL(visitor_,
- OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF));
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AtLeast(1));
- QuicAckFrame frame = InitAckFrame(1);
- EXPECT_CALL(visitor_, OnCanWrite()).Times(0);
- ProcessAckPacket(&frame);
- TestConnectionCloseQuicErrorCode(QUIC_INVALID_ACK_DATA);
-}
-
-TEST_P(QuicConnectionTest, BasicSending) {
- if (connection_.SupportsMultiplePacketNumberSpaces()) {
- return;
- }
- const QuicConnectionStats& stats = connection_.GetStats();
- EXPECT_FALSE(stats.first_decrypted_packet.IsInitialized());
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
- ProcessDataPacket(1);
- EXPECT_EQ(QuicPacketNumber(1), stats.first_decrypted_packet);
- QuicPacketCreatorPeer::SetPacketNumber(&peer_creator_, 2);
- QuicPacketNumber last_packet;
- SendStreamDataToPeer(1, "foo", 0, NO_FIN, &last_packet); // Packet 1
- EXPECT_EQ(QuicPacketNumber(1u), last_packet);
- SendAckPacketToPeer(); // Packet 2
-
- if (GetParam().no_stop_waiting) {
- // Expect no stop waiting frame is sent.
- EXPECT_FALSE(least_unacked().IsInitialized());
- } else {
- EXPECT_EQ(QuicPacketNumber(1u), least_unacked());
- }
-
- SendAckPacketToPeer(); // Packet 3
- if (GetParam().no_stop_waiting) {
- // Expect no stop waiting frame is sent.
- EXPECT_FALSE(least_unacked().IsInitialized());
- } else {
- EXPECT_EQ(QuicPacketNumber(1u), least_unacked());
- }
-
- SendStreamDataToPeer(1, "bar", 3, NO_FIN, &last_packet); // Packet 4
- EXPECT_EQ(QuicPacketNumber(4u), last_packet);
- SendAckPacketToPeer(); // Packet 5
- if (GetParam().no_stop_waiting) {
- // Expect no stop waiting frame is sent.
- EXPECT_FALSE(least_unacked().IsInitialized());
- } else {
- EXPECT_EQ(QuicPacketNumber(1u), least_unacked());
- }
-
- EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
-
- // Peer acks up to packet 3.
- QuicAckFrame frame = InitAckFrame(3);
- ProcessAckPacket(&frame);
- SendAckPacketToPeer(); // Packet 6
-
- // As soon as we've acked one, we skip ack packets 2 and 3 and note lack of
- // ack for 4.
- if (GetParam().no_stop_waiting) {
- // Expect no stop waiting frame is sent.
- EXPECT_FALSE(least_unacked().IsInitialized());
- } else {
- EXPECT_EQ(QuicPacketNumber(4u), least_unacked());
- }
-
- EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
-
- // Peer acks up to packet 4, the last packet.
- QuicAckFrame frame2 = InitAckFrame(6);
- ProcessAckPacket(&frame2); // Acks don't instigate acks.
-
- // Verify that we did not send an ack.
- EXPECT_EQ(QuicPacketNumber(6u), writer_->header().packet_number);
-
- // So the last ack has not changed.
- if (GetParam().no_stop_waiting) {
- // Expect no stop waiting frame is sent.
- EXPECT_FALSE(least_unacked().IsInitialized());
- } else {
- EXPECT_EQ(QuicPacketNumber(4u), least_unacked());
- }
-
- // If we force an ack, we shouldn't change our retransmit state.
- SendAckPacketToPeer(); // Packet 7
- if (GetParam().no_stop_waiting) {
- // Expect no stop waiting frame is sent.
- EXPECT_FALSE(least_unacked().IsInitialized());
- } else {
- EXPECT_EQ(QuicPacketNumber(7u), least_unacked());
- }
-
- // But if we send more data it should.
- SendStreamDataToPeer(1, "eep", 6, NO_FIN, &last_packet); // Packet 8
- EXPECT_EQ(QuicPacketNumber(8u), last_packet);
- SendAckPacketToPeer(); // Packet 9
- if (GetParam().no_stop_waiting) {
- // Expect no stop waiting frame is sent.
- EXPECT_FALSE(least_unacked().IsInitialized());
- } else {
- EXPECT_EQ(QuicPacketNumber(7u), least_unacked());
- }
- EXPECT_EQ(QuicPacketNumber(1), stats.first_decrypted_packet);
-}
-
-// QuicConnection should record the packet sent-time prior to sending the
-// packet.
-TEST_P(QuicConnectionTest, RecordSentTimeBeforePacketSent) {
- // We're using a MockClock for the tests, so we have complete control over the
- // time.
- // Our recorded timestamp for the last packet sent time will be passed in to
- // the send_algorithm. Make sure that it is set to the correct value.
- QuicTime actual_recorded_send_time = QuicTime::Zero();
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
- .WillOnce(SaveArg<0>(&actual_recorded_send_time));
-
- // First send without any pause and check the result.
- QuicTime expected_recorded_send_time = clock_.Now();
- connection_.SendStreamDataWithString(1, "foo", 0, NO_FIN);
- EXPECT_EQ(expected_recorded_send_time, actual_recorded_send_time)
- << "Expected time = " << expected_recorded_send_time.ToDebuggingValue()
- << ". Actual time = " << actual_recorded_send_time.ToDebuggingValue();
-
- // Now pause during the write, and check the results.
- actual_recorded_send_time = QuicTime::Zero();
- const QuicTime::Delta write_pause_time_delta =
- QuicTime::Delta::FromMilliseconds(5000);
- SetWritePauseTimeDelta(write_pause_time_delta);
- expected_recorded_send_time = clock_.Now();
-
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
- .WillOnce(SaveArg<0>(&actual_recorded_send_time));
- connection_.SendStreamDataWithString(2, "baz", 0, NO_FIN);
- EXPECT_EQ(expected_recorded_send_time, actual_recorded_send_time)
- << "Expected time = " << expected_recorded_send_time.ToDebuggingValue()
- << ". Actual time = " << actual_recorded_send_time.ToDebuggingValue();
-}
-
-TEST_P(QuicConnectionTest, FramePacking) {
- // Send two stream frames in 1 packet by queueing them.
- connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
- {
- QuicConnection::ScopedPacketFlusher flusher(&connection_);
- connection_.SendStreamData3();
- connection_.SendStreamData5();
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
- }
- EXPECT_EQ(0u, connection_.NumQueuedPackets());
- EXPECT_FALSE(connection_.HasQueuedData());
-
- // Parse the last packet and ensure it's an ack and two stream frames from
- // two different streams.
- if (GetParam().no_stop_waiting) {
- EXPECT_EQ(2u, writer_->frame_count());
- EXPECT_TRUE(writer_->stop_waiting_frames().empty());
- } else {
- EXPECT_EQ(2u, writer_->frame_count());
- EXPECT_TRUE(writer_->stop_waiting_frames().empty());
- }
-
- EXPECT_TRUE(writer_->ack_frames().empty());
-
- ASSERT_EQ(2u, writer_->stream_frames().size());
- EXPECT_EQ(GetNthClientInitiatedStreamId(1, connection_.transport_version()),
- writer_->stream_frames()[0]->stream_id);
- EXPECT_EQ(GetNthClientInitiatedStreamId(2, connection_.transport_version()),
- writer_->stream_frames()[1]->stream_id);
-}
-
-TEST_P(QuicConnectionTest, FramePackingNonCryptoThenCrypto) {
- // Send two stream frames (one non-crypto, then one crypto) in 2 packets by
- // queueing them.
- connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
- {
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(2);
- QuicConnection::ScopedPacketFlusher flusher(&connection_);
- connection_.SendStreamData3();
- connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
- connection_.SendCryptoStreamData();
- connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
- }
- EXPECT_EQ(0u, connection_.NumQueuedPackets());
- EXPECT_FALSE(connection_.HasQueuedData());
-
- // Parse the last packet and ensure it contains a crypto stream frame.
- EXPECT_LE(2u, writer_->frame_count());
- ASSERT_LE(1u, writer_->padding_frames().size());
- if (!QuicVersionUsesCryptoFrames(connection_.transport_version())) {
- ASSERT_EQ(1u, writer_->stream_frames().size());
- EXPECT_EQ(QuicUtils::GetCryptoStreamId(connection_.transport_version()),
- writer_->stream_frames()[0]->stream_id);
- } else {
- EXPECT_LE(1u, writer_->crypto_frames().size());
- }
-}
-
-TEST_P(QuicConnectionTest, FramePackingCryptoThenNonCrypto) {
- // Send two stream frames (one crypto, then one non-crypto) in 2 packets by
- // queueing them.
- {
- connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(2);
- QuicConnection::ScopedPacketFlusher flusher(&connection_);
- connection_.SendCryptoStreamData();
- connection_.SendStreamData3();
- }
- EXPECT_EQ(0u, connection_.NumQueuedPackets());
- EXPECT_FALSE(connection_.HasQueuedData());
-
- // Parse the last packet and ensure it's the stream frame from stream 3.
- size_t padding_frame_count = writer_->padding_frames().size();
- EXPECT_EQ(padding_frame_count + 1u, writer_->frame_count());
- ASSERT_EQ(1u, writer_->stream_frames().size());
- EXPECT_EQ(GetNthClientInitiatedStreamId(1, connection_.transport_version()),
- writer_->stream_frames()[0]->stream_id);
-}
-
-TEST_P(QuicConnectionTest, FramePackingAckResponse) {
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- // Process a data packet to queue up a pending ack.
- if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
- EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(1);
- } else {
- EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
- }
- ProcessCryptoPacketAtLevel(1, ENCRYPTION_INITIAL);
-
- QuicPacketNumber last_packet;
- if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
- connection_.SendCryptoDataWithString("foo", 0);
- } else {
- SendStreamDataToPeer(
- QuicUtils::GetCryptoStreamId(connection_.transport_version()), "foo", 0,
- NO_FIN, &last_packet);
- }
- // Verify ack is bundled with outging packet.
- EXPECT_FALSE(writer_->ack_frames().empty());
-
- EXPECT_CALL(visitor_, OnCanWrite())
- .WillOnce(DoAll(IgnoreResult(InvokeWithoutArgs(
- &connection_, &TestConnection::SendStreamData3)),
- IgnoreResult(InvokeWithoutArgs(
- &connection_, &TestConnection::SendStreamData5))));
-
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
-
- // Process a data packet to cause the visitor's OnCanWrite to be invoked.
- EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
- peer_framer_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
- std::make_unique<TaggingEncrypter>(0x01));
- SetDecrypter(ENCRYPTION_FORWARD_SECURE,
- std::make_unique<StrictTaggingDecrypter>(0x01));
- ProcessDataPacket(2);
-
- EXPECT_EQ(0u, connection_.NumQueuedPackets());
- EXPECT_FALSE(connection_.HasQueuedData());
-
- // Parse the last packet and ensure it's an ack and two stream frames from
- // two different streams.
- if (GetParam().no_stop_waiting) {
- EXPECT_EQ(3u, writer_->frame_count());
- EXPECT_TRUE(writer_->stop_waiting_frames().empty());
- } else {
- EXPECT_EQ(4u, writer_->frame_count());
- EXPECT_FALSE(writer_->stop_waiting_frames().empty());
- }
- EXPECT_FALSE(writer_->ack_frames().empty());
- ASSERT_EQ(2u, writer_->stream_frames().size());
- EXPECT_EQ(GetNthClientInitiatedStreamId(1, connection_.transport_version()),
- writer_->stream_frames()[0]->stream_id);
- EXPECT_EQ(GetNthClientInitiatedStreamId(2, connection_.transport_version()),
- writer_->stream_frames()[1]->stream_id);
-}
-
-TEST_P(QuicConnectionTest, FramePackingSendv) {
- connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
- // Send data in 1 packet by writing multiple blocks in a single iovector
- // using writev.
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _));
-
- char data[] = "ABCDEF";
- struct iovec iov[2];
- iov[0].iov_base = data;
- iov[0].iov_len = 4;
- iov[1].iov_base = data + 4;
- iov[1].iov_len = 2;
- QuicStreamId stream_id = QuicUtils::GetFirstBidirectionalStreamId(
- connection_.transport_version(), Perspective::IS_CLIENT);
- connection_.SaveAndSendStreamData(stream_id, iov, 2, 6, 0, NO_FIN);
-
- EXPECT_EQ(0u, connection_.NumQueuedPackets());
- EXPECT_FALSE(connection_.HasQueuedData());
-
- // Parse the last packet and ensure multiple iovector blocks have
- // been packed into a single stream frame from one stream.
- EXPECT_EQ(1u, writer_->frame_count());
- EXPECT_EQ(1u, writer_->stream_frames().size());
- EXPECT_EQ(0u, writer_->padding_frames().size());
- QuicStreamFrame* frame = writer_->stream_frames()[0].get();
- EXPECT_EQ(stream_id, frame->stream_id);
- EXPECT_EQ("ABCDEF",
- absl::string_view(frame->data_buffer, frame->data_length));
-}
-
-TEST_P(QuicConnectionTest, FramePackingSendvQueued) {
- connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
- // Try to send two stream frames in 1 packet by using writev.
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _));
-
- BlockOnNextWrite();
- char data[] = "ABCDEF";
- struct iovec iov[2];
- iov[0].iov_base = data;
- iov[0].iov_len = 4;
- iov[1].iov_base = data + 4;
- iov[1].iov_len = 2;
- QuicStreamId stream_id = QuicUtils::GetFirstBidirectionalStreamId(
- connection_.transport_version(), Perspective::IS_CLIENT);
- connection_.SaveAndSendStreamData(stream_id, iov, 2, 6, 0, NO_FIN);
-
- EXPECT_EQ(1u, connection_.NumQueuedPackets());
- EXPECT_TRUE(connection_.HasQueuedData());
-
- // Unblock the writes and actually send.
- writer_->SetWritable();
- connection_.OnCanWrite();
- EXPECT_EQ(0u, connection_.NumQueuedPackets());
-
- // Parse the last packet and ensure it's one stream frame from one stream.
- EXPECT_EQ(1u, writer_->frame_count());
- EXPECT_EQ(1u, writer_->stream_frames().size());
- EXPECT_EQ(0u, writer_->padding_frames().size());
- EXPECT_EQ(stream_id, writer_->stream_frames()[0]->stream_id);
-}
-
-TEST_P(QuicConnectionTest, SendingZeroBytes) {
- connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
- // Send a zero byte write with a fin using writev.
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _));
- QuicStreamId stream_id = QuicUtils::GetFirstBidirectionalStreamId(
- connection_.transport_version(), Perspective::IS_CLIENT);
- connection_.SaveAndSendStreamData(stream_id, nullptr, 0, 0, 0, FIN);
-
- EXPECT_EQ(0u, connection_.NumQueuedPackets());
- EXPECT_FALSE(connection_.HasQueuedData());
-
- // Padding frames are added by v99 to ensure a minimum packet size.
- size_t extra_padding_frames = 0;
- if (GetParam().version.HasHeaderProtection()) {
- extra_padding_frames = 1;
- }
-
- // Parse the last packet and ensure it's one stream frame from one stream.
- EXPECT_EQ(1u + extra_padding_frames, writer_->frame_count());
- EXPECT_EQ(extra_padding_frames, writer_->padding_frames().size());
- ASSERT_EQ(1u, writer_->stream_frames().size());
- EXPECT_EQ(stream_id, writer_->stream_frames()[0]->stream_id);
- EXPECT_TRUE(writer_->stream_frames()[0]->fin);
-}
-
-TEST_P(QuicConnectionTest, LargeSendWithPendingAck) {
- connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
- EXPECT_CALL(visitor_, GetHandshakeState())
- .WillRepeatedly(Return(HANDSHAKE_CONFIRMED));
- // Set the ack alarm by processing a ping frame.
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-
- // Processs a PING frame.
- ProcessFramePacket(QuicFrame(QuicPingFrame()));
- // Ensure that this has caused the ACK alarm to be set.
- EXPECT_TRUE(connection_.HasPendingAcks());
-
- // Send data and ensure the ack is bundled.
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(9);
- size_t len = 10000;
- std::unique_ptr<char[]> data_array(new char[len]);
- memset(data_array.get(), '?', len);
- struct iovec iov;
- iov.iov_base = data_array.get();
- iov.iov_len = len;
- QuicConsumedData consumed = connection_.SaveAndSendStreamData(
- GetNthClientInitiatedStreamId(0, connection_.transport_version()), &iov,
- 1, len, 0, FIN);
- EXPECT_EQ(len, consumed.bytes_consumed);
- EXPECT_TRUE(consumed.fin_consumed);
- EXPECT_EQ(0u, connection_.NumQueuedPackets());
- EXPECT_FALSE(connection_.HasQueuedData());
-
- // Parse the last packet and ensure it's one stream frame with a fin.
- EXPECT_EQ(1u, writer_->frame_count());
- ASSERT_EQ(1u, writer_->stream_frames().size());
- EXPECT_EQ(GetNthClientInitiatedStreamId(0, connection_.transport_version()),
- writer_->stream_frames()[0]->stream_id);
- EXPECT_TRUE(writer_->stream_frames()[0]->fin);
- // Ensure the ack alarm was cancelled when the ack was sent.
- EXPECT_FALSE(connection_.HasPendingAcks());
-}
-
-TEST_P(QuicConnectionTest, OnCanWrite) {
- // Visitor's OnCanWrite will send data, but will have more pending writes.
- EXPECT_CALL(visitor_, OnCanWrite())
- .WillOnce(DoAll(IgnoreResult(InvokeWithoutArgs(
- &connection_, &TestConnection::SendStreamData3)),
- IgnoreResult(InvokeWithoutArgs(
- &connection_, &TestConnection::SendStreamData5))));
- {
- InSequence seq;
- EXPECT_CALL(visitor_, WillingAndAbleToWrite()).WillOnce(Return(true));
- EXPECT_CALL(visitor_, WillingAndAbleToWrite())
- .WillRepeatedly(Return(false));
- }
-
- EXPECT_CALL(*send_algorithm_, CanSend(_))
- .WillRepeatedly(testing::Return(true));
-
- connection_.OnCanWrite();
-
- // Parse the last packet and ensure it's the two stream frames from
- // two different streams.
- EXPECT_EQ(2u, writer_->frame_count());
- EXPECT_EQ(2u, writer_->stream_frames().size());
- EXPECT_EQ(GetNthClientInitiatedStreamId(1, connection_.transport_version()),
- writer_->stream_frames()[0]->stream_id);
- EXPECT_EQ(GetNthClientInitiatedStreamId(2, connection_.transport_version()),
- writer_->stream_frames()[1]->stream_id);
-}
-
-TEST_P(QuicConnectionTest, RetransmitOnNack) {
- QuicPacketNumber last_packet;
- SendStreamDataToPeer(3, "foo", 0, NO_FIN, &last_packet);
- SendStreamDataToPeer(3, "foos", 3, NO_FIN, &last_packet);
- SendStreamDataToPeer(3, "fooos", 7, NO_FIN, &last_packet);
-
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-
- // Don't lose a packet on an ack, and nothing is retransmitted.
- EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
- QuicAckFrame ack_one = InitAckFrame(1);
- ProcessAckPacket(&ack_one);
-
- // Lose a packet and ensure it triggers retransmission.
- QuicAckFrame nack_two = ConstructAckFrame(3, 2);
- LostPacketVector lost_packets;
- lost_packets.push_back(
- LostPacket(QuicPacketNumber(2), kMaxOutgoingPacketSize));
- EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _))
- .WillOnce(DoAll(SetArgPointee<5>(lost_packets),
- Return(LossDetectionInterface::DetectionStats())));
- EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
- EXPECT_FALSE(QuicPacketCreatorPeer::SendVersionInPacket(creator_));
- ProcessAckPacket(&nack_two);
-}
-
-TEST_P(QuicConnectionTest, DoNotSendQueuedPacketForResetStream) {
- // Block the connection to queue the packet.
- BlockOnNextWrite();
-
- QuicStreamId stream_id = 2;
- connection_.SendStreamDataWithString(stream_id, "foo", 0, NO_FIN);
-
- // Now that there is a queued packet, reset the stream.
- SendRstStream(stream_id, QUIC_ERROR_PROCESSING_STREAM, 3);
-
- // Unblock the connection and verify that only the RST_STREAM is sent.
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
- writer_->SetWritable();
- connection_.OnCanWrite();
- size_t padding_frame_count = writer_->padding_frames().size();
- EXPECT_EQ(padding_frame_count + 1u, writer_->frame_count());
- EXPECT_EQ(1u, writer_->rst_stream_frames().size());
-}
-
-TEST_P(QuicConnectionTest, SendQueuedPacketForQuicRstStreamNoError) {
- // Block the connection to queue the packet.
- BlockOnNextWrite();
-
- QuicStreamId stream_id = 2;
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
- connection_.SendStreamDataWithString(stream_id, "foo", 0, NO_FIN);
-
- // Now that there is a queued packet, reset the stream.
- SendRstStream(stream_id, QUIC_STREAM_NO_ERROR, 3);
-
- // Unblock the connection and verify that the RST_STREAM is sent and the data
- // packet is sent.
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AtLeast(1));
- writer_->SetWritable();
- connection_.OnCanWrite();
- size_t padding_frame_count = writer_->padding_frames().size();
- EXPECT_EQ(padding_frame_count + 1u, writer_->frame_count());
- EXPECT_EQ(1u, writer_->rst_stream_frames().size());
-}
-
-TEST_P(QuicConnectionTest, DoNotRetransmitForResetStreamOnNack) {
- QuicStreamId stream_id = 2;
- QuicPacketNumber last_packet;
- SendStreamDataToPeer(stream_id, "foo", 0, NO_FIN, &last_packet);
- SendStreamDataToPeer(stream_id, "foos", 3, NO_FIN, &last_packet);
- SendStreamDataToPeer(stream_id, "fooos", 7, NO_FIN, &last_packet);
-
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
- SendRstStream(stream_id, QUIC_ERROR_PROCESSING_STREAM, 12);
-
- // Lose a packet and ensure it does not trigger retransmission.
- QuicAckFrame nack_two = ConstructAckFrame(last_packet, last_packet - 1);
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _));
- EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
- ProcessAckPacket(&nack_two);
-}
-
-TEST_P(QuicConnectionTest, RetransmitForQuicRstStreamNoErrorOnNack) {
- QuicStreamId stream_id = 2;
- QuicPacketNumber last_packet;
- SendStreamDataToPeer(stream_id, "foo", 0, NO_FIN, &last_packet);
- SendStreamDataToPeer(stream_id, "foos", 3, NO_FIN, &last_packet);
- SendStreamDataToPeer(stream_id, "fooos", 7, NO_FIN, &last_packet);
-
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
- SendRstStream(stream_id, QUIC_STREAM_NO_ERROR, 12);
-
- // Lose a packet, ensure it triggers retransmission.
- QuicAckFrame nack_two = ConstructAckFrame(last_packet, last_packet - 1);
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- LostPacketVector lost_packets;
- lost_packets.push_back(LostPacket(last_packet - 1, kMaxOutgoingPacketSize));
- EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _))
- .WillOnce(DoAll(SetArgPointee<5>(lost_packets),
- Return(LossDetectionInterface::DetectionStats())));
- EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AtLeast(1));
- ProcessAckPacket(&nack_two);
-}
-
-TEST_P(QuicConnectionTest, DoNotRetransmitForResetStreamOnRTO) {
- QuicStreamId stream_id = 2;
- QuicPacketNumber last_packet;
- SendStreamDataToPeer(stream_id, "foo", 0, NO_FIN, &last_packet);
-
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
- SendRstStream(stream_id, QUIC_ERROR_PROCESSING_STREAM, 3);
-
- // Fire the RTO and verify that the RST_STREAM is resent, not stream data.
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(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());
- EXPECT_EQ(1u, writer_->rst_stream_frames().size());
- EXPECT_EQ(stream_id, writer_->rst_stream_frames().front().stream_id);
-}
-
-// Ensure that if the only data in flight is non-retransmittable, the
-// retransmission alarm is not set.
-TEST_P(QuicConnectionTest, CancelRetransmissionAlarmAfterResetStream) {
- QuicStreamId stream_id = 2;
- QuicPacketNumber last_data_packet;
- SendStreamDataToPeer(stream_id, "foo", 0, NO_FIN, &last_data_packet);
-
- // Cancel the stream.
- const QuicPacketNumber rst_packet = last_data_packet + 1;
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, rst_packet, _, _)).Times(1);
- SendRstStream(stream_id, QUIC_ERROR_PROCESSING_STREAM, 3);
-
- // Ack the RST_STREAM frame (since it's retransmittable), but not the data
- // packet, which is no longer retransmittable since the stream was cancelled.
- QuicAckFrame nack_stream_data =
- ConstructAckFrame(rst_packet, last_data_packet);
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
- ProcessAckPacket(&nack_stream_data);
-
- // Ensure that the data is still in flight, but the retransmission alarm is no
- // longer set.
- EXPECT_GT(manager_->GetBytesInFlight(), 0u);
- EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
-}
-
-TEST_P(QuicConnectionTest, RetransmitForQuicRstStreamNoErrorOnRTO) {
- connection_.SetMaxTailLossProbes(0);
-
- QuicStreamId stream_id = 2;
- QuicPacketNumber last_packet;
- SendStreamDataToPeer(stream_id, "foo", 0, NO_FIN, &last_packet);
-
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
- SendRstStream(stream_id, QUIC_STREAM_NO_ERROR, 3);
-
- // Fire the RTO and verify that the RST_STREAM is resent, the stream data
- // is sent.
- const size_t num_retransmissions =
- connection_.SupportsMultiplePacketNumberSpaces() ? 1 : 2;
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
- .Times(AtLeast(num_retransmissions));
- 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) {
- QuicStreamId stream_id = 2;
- QuicPacketNumber last_packet;
- SendStreamDataToPeer(stream_id, "foo", 0, NO_FIN, &last_packet);
- SendStreamDataToPeer(stream_id, "foos", 3, NO_FIN, &last_packet);
- BlockOnNextWrite();
- connection_.SendStreamDataWithString(stream_id, "fooos", 7, NO_FIN);
-
- // Lose a packet which will trigger a pending retransmission.
- QuicAckFrame ack = ConstructAckFrame(last_packet, last_packet - 1);
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _));
- EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
- ProcessAckPacket(&ack);
-
- SendRstStream(stream_id, QUIC_ERROR_PROCESSING_STREAM, 12);
-
- // Unblock the connection and verify that the RST_STREAM is sent but not the
- // second data packet nor a retransmit.
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
- writer_->SetWritable();
- connection_.OnCanWrite();
- size_t padding_frame_count = writer_->padding_frames().size();
- EXPECT_EQ(padding_frame_count + 1u, writer_->frame_count());
- ASSERT_EQ(1u, writer_->rst_stream_frames().size());
- EXPECT_EQ(stream_id, writer_->rst_stream_frames().front().stream_id);
-}
-
-TEST_P(QuicConnectionTest, SendPendingRetransmissionForQuicRstStreamNoError) {
- QuicStreamId stream_id = 2;
- QuicPacketNumber last_packet;
- SendStreamDataToPeer(stream_id, "foo", 0, NO_FIN, &last_packet);
- SendStreamDataToPeer(stream_id, "foos", 3, NO_FIN, &last_packet);
- BlockOnNextWrite();
- connection_.SendStreamDataWithString(stream_id, "fooos", 7, NO_FIN);
-
- // Lose a packet which will trigger a pending retransmission.
- QuicAckFrame ack = ConstructAckFrame(last_packet, last_packet - 1);
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- LostPacketVector lost_packets;
- lost_packets.push_back(LostPacket(last_packet - 1, kMaxOutgoingPacketSize));
- EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _))
- .WillOnce(DoAll(SetArgPointee<5>(lost_packets),
- Return(LossDetectionInterface::DetectionStats())));
- EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
- ProcessAckPacket(&ack);
-
- SendRstStream(stream_id, QUIC_STREAM_NO_ERROR, 12);
-
- // Unblock the connection and verify that the RST_STREAM is sent and the
- // second data packet or a retransmit is sent.
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AtLeast(2));
- writer_->SetWritable();
- connection_.OnCanWrite();
- // The RST_STREAM_FRAME is sent after queued packets and pending
- // retransmission.
- connection_.SendControlFrame(QuicFrame(
- new QuicRstStreamFrame(1, stream_id, QUIC_STREAM_NO_ERROR, 14)));
- size_t padding_frame_count = writer_->padding_frames().size();
- EXPECT_EQ(padding_frame_count + 1u, writer_->frame_count());
- EXPECT_EQ(1u, writer_->rst_stream_frames().size());
-}
-
-TEST_P(QuicConnectionTest, RetransmitAckedPacket) {
- QuicPacketNumber last_packet;
- SendStreamDataToPeer(1, "foo", 0, NO_FIN, &last_packet); // Packet 1
- SendStreamDataToPeer(1, "foos", 3, NO_FIN, &last_packet); // Packet 2
- SendStreamDataToPeer(1, "fooos", 7, NO_FIN, &last_packet); // Packet 3
-
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-
- // Instigate a loss with an ack.
- QuicAckFrame nack_two = ConstructAckFrame(3, 2);
- // The first nack should trigger a fast retransmission, but we'll be
- // write blocked, so the packet will be queued.
- BlockOnNextWrite();
-
- LostPacketVector lost_packets;
- lost_packets.push_back(
- LostPacket(QuicPacketNumber(2), kMaxOutgoingPacketSize));
- EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _))
- .WillOnce(DoAll(SetArgPointee<5>(lost_packets),
- Return(LossDetectionInterface::DetectionStats())));
- EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, QuicPacketNumber(4), _, _))
- .Times(1);
- ProcessAckPacket(&nack_two);
- EXPECT_EQ(1u, connection_.NumQueuedPackets());
-
- // Now, ack the previous transmission.
- EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _));
- EXPECT_CALL(*send_algorithm_, OnCongestionEvent(false, _, _, _, _));
- QuicAckFrame ack_all = InitAckFrame(3);
- ProcessAckPacket(&ack_all);
-
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, QuicPacketNumber(4), _, _))
- .Times(0);
-
- writer_->SetWritable();
- connection_.OnCanWrite();
-
- EXPECT_EQ(0u, connection_.NumQueuedPackets());
- // We do not store retransmittable frames of this retransmission.
- EXPECT_FALSE(QuicConnectionPeer::HasRetransmittableFrames(&connection_, 4));
-}
-
-TEST_P(QuicConnectionTest, RetransmitNackedLargestObserved) {
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- QuicPacketNumber original, second;
-
- QuicByteCount packet_size =
- SendStreamDataToPeer(3, "foo", 0, NO_FIN, &original); // 1st packet.
- SendStreamDataToPeer(3, "bar", 3, NO_FIN, &second); // 2nd packet.
-
- QuicAckFrame frame = InitAckFrame({{second, second + 1}});
- // The first nack should retransmit the largest observed packet.
- LostPacketVector lost_packets;
- lost_packets.push_back(LostPacket(original, kMaxOutgoingPacketSize));
- EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _))
- .WillOnce(DoAll(SetArgPointee<5>(lost_packets),
- Return(LossDetectionInterface::DetectionStats())));
- EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
- // Packet 1 is short header for IETF QUIC because the encryption level
- // switched to ENCRYPTION_FORWARD_SECURE in SendStreamDataToPeer.
- EXPECT_CALL(*send_algorithm_,
- OnPacketSent(_, _, _,
- GetParam().version.HasIetfInvariantHeader()
- ? packet_size
- : packet_size - kQuicVersionSize,
- _));
- 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);
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
- connection_.SendStreamDataWithString(1, "foo", 0, NO_FIN);
- EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
-
- writer_->SetWritable();
- connection_.OnCanWrite();
- EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
-}
-
-TEST_P(QuicConnectionTest, WriteBlockedThenSent) {
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
- BlockOnNextWrite();
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
- connection_.SendStreamDataWithString(1, "foo", 0, NO_FIN);
- EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
- EXPECT_EQ(1u, connection_.NumQueuedPackets());
-
- // The second packet should also be queued, in order to ensure packets are
- // never sent out of order.
- writer_->SetWritable();
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
- connection_.SendStreamDataWithString(1, "foo", 0, NO_FIN);
- EXPECT_EQ(2u, connection_.NumQueuedPackets());
-
- // Now both are sent in order when we unblock.
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
- connection_.OnCanWrite();
- EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
- EXPECT_EQ(0u, connection_.NumQueuedPackets());
-}
-
-TEST_P(QuicConnectionTest, RetransmitWriteBlockedAckedOriginalThenSent) {
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- connection_.SendStreamDataWithString(3, "foo", 0, NO_FIN);
- EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
-
- BlockOnNextWrite();
- writer_->set_is_write_blocked_data_buffered(true);
- // Simulate the retransmission alarm firing.
- clock_.AdvanceTime(DefaultRetransmissionTime());
- connection_.GetRetransmissionAlarm()->Fire();
-
- // Ack the sent packet before the callback returns, which happens in
- // rare circumstances with write blocked sockets.
- QuicAckFrame ack = InitAckFrame(1);
- EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
- ProcessAckPacket(&ack);
-
- writer_->SetWritable();
- connection_.OnCanWrite();
- EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
- uint64_t retransmission = connection_.SupportsMultiplePacketNumberSpaces() &&
- !GetQuicReloadableFlag(quic_default_on_pto)
- ? 3
- : 2;
- EXPECT_FALSE(QuicConnectionPeer::HasRetransmittableFrames(&connection_,
- retransmission));
-}
-
-TEST_P(QuicConnectionTest, AlarmsWhenWriteBlocked) {
- // Block the connection.
- BlockOnNextWrite();
- connection_.SendStreamDataWithString(3, "foo", 0, NO_FIN);
- EXPECT_EQ(1u, writer_->packets_write_attempts());
- EXPECT_TRUE(writer_->IsWriteBlocked());
-
- // Set the send alarm. Fire the alarm and ensure it doesn't attempt to write.
- connection_.GetSendAlarm()->Set(clock_.ApproximateNow());
- connection_.GetSendAlarm()->Fire();
- EXPECT_TRUE(writer_->IsWriteBlocked());
- EXPECT_EQ(1u, writer_->packets_write_attempts());
-}
-
-TEST_P(QuicConnectionTest, NoSendAlarmAfterProcessPacketWhenWriteBlocked) {
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-
- // Block the connection.
- BlockOnNextWrite();
- connection_.SendStreamDataWithString(3, "foo", 0, NO_FIN);
- EXPECT_TRUE(writer_->IsWriteBlocked());
- EXPECT_EQ(1u, connection_.NumQueuedPackets());
- EXPECT_FALSE(connection_.GetSendAlarm()->IsSet());
-
- EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
- // Process packet number 1. Can not call ProcessPacket or ProcessDataPacket
- // here, because they will fire the alarm after QuicConnection::ProcessPacket
- // is returned.
- const uint64_t received_packet_num = 1;
- const bool has_stop_waiting = false;
- const EncryptionLevel level = ENCRYPTION_FORWARD_SECURE;
- std::unique_ptr<QuicPacket> packet(
- ConstructDataPacket(received_packet_num, has_stop_waiting, level));
- char buffer[kMaxOutgoingPacketSize];
- size_t encrypted_length =
- peer_framer_.EncryptPayload(level, QuicPacketNumber(received_packet_num),
- *packet, buffer, kMaxOutgoingPacketSize);
- connection_.ProcessUdpPacket(
- kSelfAddress, kPeerAddress,
- QuicReceivedPacket(buffer, encrypted_length, clock_.Now(), false));
-
- EXPECT_TRUE(writer_->IsWriteBlocked());
- EXPECT_FALSE(connection_.GetSendAlarm()->IsSet());
-}
-
-TEST_P(QuicConnectionTest, AddToWriteBlockedListIfWriterBlockedWhenProcessing) {
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- SendStreamDataToPeer(1, "foo", 0, NO_FIN, nullptr);
-
- // Simulate the case where a shared writer gets blocked by another connection.
- writer_->SetWriteBlocked();
-
- // Process an ACK, make sure the connection calls visitor_->OnWriteBlocked().
- QuicAckFrame ack1 = InitAckFrame(1);
- EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _));
- EXPECT_CALL(visitor_, OnWriteBlocked()).Times(1);
- ProcessAckPacket(1, &ack1);
-}
-
-TEST_P(QuicConnectionTest, DoNotAddToWriteBlockedListAfterDisconnect) {
- writer_->SetBatchMode(true);
- EXPECT_TRUE(connection_.connected());
- // Have to explicitly grab the OnConnectionClosed frame and check
- // its parameters because this is a silent connection close and the
- // frame is not also transmitted to the peer.
- EXPECT_CALL(visitor_, OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF))
- .WillOnce(Invoke(this, &QuicConnectionTest::SaveConnectionCloseFrame));
-
- EXPECT_CALL(visitor_, OnWriteBlocked()).Times(0);
-
- {
- QuicConnection::ScopedPacketFlusher flusher(&connection_);
- connection_.CloseConnection(QUIC_PEER_GOING_AWAY, "no reason",
- ConnectionCloseBehavior::SILENT_CLOSE);
-
- EXPECT_FALSE(connection_.connected());
- writer_->SetWriteBlocked();
- }
- EXPECT_EQ(1, connection_close_frame_count_);
- EXPECT_THAT(saved_connection_close_frame_.quic_error_code,
- IsError(QUIC_PEER_GOING_AWAY));
-}
-
-TEST_P(QuicConnectionTest, AddToWriteBlockedListIfBlockedOnFlushPackets) {
- writer_->SetBatchMode(true);
- writer_->BlockOnNextFlush();
-
- EXPECT_CALL(visitor_, OnWriteBlocked()).Times(1);
- {
- QuicConnection::ScopedPacketFlusher flusher(&connection_);
- // flusher's destructor will call connection_.FlushPackets, which should add
- // the connection to the write blocked list.
- }
-}
-
-TEST_P(QuicConnectionTest, NoLimitPacketsPerNack) {
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- int offset = 0;
- // Send packets 1 to 15.
- for (int i = 0; i < 15; ++i) {
- SendStreamDataToPeer(1, "foo", offset, NO_FIN, nullptr);
- offset += 3;
- }
-
- // Ack 15, nack 1-14.
-
- QuicAckFrame nack =
- InitAckFrame({{QuicPacketNumber(15), QuicPacketNumber(16)}});
-
- // 14 packets have been NACK'd and lost.
- LostPacketVector lost_packets;
- for (int i = 1; i < 15; ++i) {
- lost_packets.push_back(
- LostPacket(QuicPacketNumber(i), kMaxOutgoingPacketSize));
- }
- EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _))
- .WillOnce(DoAll(SetArgPointee<5>(lost_packets),
- Return(LossDetectionInterface::DetectionStats())));
- EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
- ProcessAckPacket(&nack);
-}
-
-// Test sending multiple acks from the connection to the session.
-TEST_P(QuicConnectionTest, MultipleAcks) {
- if (connection_.SupportsMultiplePacketNumberSpaces()) {
- return;
- }
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
- ProcessDataPacket(1);
- QuicPacketCreatorPeer::SetPacketNumber(&peer_creator_, 2);
- QuicPacketNumber last_packet;
- SendStreamDataToPeer(1, "foo", 0, NO_FIN, &last_packet); // Packet 1
- EXPECT_EQ(QuicPacketNumber(1u), last_packet);
- SendStreamDataToPeer(3, "foo", 0, NO_FIN, &last_packet); // Packet 2
- EXPECT_EQ(QuicPacketNumber(2u), last_packet);
- SendAckPacketToPeer(); // Packet 3
- SendStreamDataToPeer(5, "foo", 0, NO_FIN, &last_packet); // Packet 4
- EXPECT_EQ(QuicPacketNumber(4u), last_packet);
- SendStreamDataToPeer(1, "foo", 3, NO_FIN, &last_packet); // Packet 5
- EXPECT_EQ(QuicPacketNumber(5u), last_packet);
- SendStreamDataToPeer(3, "foo", 3, NO_FIN, &last_packet); // Packet 6
- EXPECT_EQ(QuicPacketNumber(6u), last_packet);
-
- // Client will ack packets 1, 2, [!3], 4, 5.
- EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
- QuicAckFrame frame1 = ConstructAckFrame(5, 3);
- ProcessAckPacket(&frame1);
-
- // Now the client implicitly acks 3, and explicitly acks 6.
- EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
- QuicAckFrame frame2 = InitAckFrame(6);
- ProcessAckPacket(&frame2);
-}
-
-TEST_P(QuicConnectionTest, DontLatchUnackedPacket) {
- if (connection_.SupportsMultiplePacketNumberSpaces()) {
- return;
- }
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
- ProcessDataPacket(1);
- QuicPacketCreatorPeer::SetPacketNumber(&peer_creator_, 2);
- SendStreamDataToPeer(1, "foo", 0, NO_FIN, nullptr); // Packet 1;
- // From now on, we send acks, so the send algorithm won't mark them pending.
- SendAckPacketToPeer(); // Packet 2
-
- EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
- QuicAckFrame frame = InitAckFrame(1);
- ProcessAckPacket(&frame);
-
- // Verify that our internal state has least-unacked as 2, because we're still
- // waiting for a potential ack for 2.
-
- EXPECT_EQ(QuicPacketNumber(2u), stop_waiting()->least_unacked);
-
- EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
- frame = InitAckFrame(2);
- ProcessAckPacket(&frame);
- EXPECT_EQ(QuicPacketNumber(3u), stop_waiting()->least_unacked);
-
- // When we send an ack, we make sure our least-unacked makes sense. In this
- // case since we're not waiting on an ack for 2 and all packets are acked, we
- // set it to 3.
- SendAckPacketToPeer(); // Packet 3
- // Least_unacked remains at 3 until another ack is received.
- EXPECT_EQ(QuicPacketNumber(3u), stop_waiting()->least_unacked);
- if (GetParam().no_stop_waiting) {
- // Expect no stop waiting frame is sent.
- EXPECT_FALSE(least_unacked().IsInitialized());
- } else {
- // Check that the outgoing ack had its packet number as least_unacked.
- EXPECT_EQ(QuicPacketNumber(3u), least_unacked());
- }
-
- // Ack the ack, which updates the rtt and raises the least unacked.
- EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
- frame = InitAckFrame(3);
- ProcessAckPacket(&frame);
-
- SendStreamDataToPeer(1, "bar", 3, NO_FIN, nullptr); // Packet 4
- EXPECT_EQ(QuicPacketNumber(4u), stop_waiting()->least_unacked);
- SendAckPacketToPeer(); // Packet 5
- if (GetParam().no_stop_waiting) {
- // Expect no stop waiting frame is sent.
- EXPECT_FALSE(least_unacked().IsInitialized());
- } else {
- EXPECT_EQ(QuicPacketNumber(4u), least_unacked());
- }
-
- // Send two data packets at the end, and ensure if the last one is acked,
- // the least unacked is raised above the ack packets.
- SendStreamDataToPeer(1, "bar", 6, NO_FIN, nullptr); // Packet 6
- SendStreamDataToPeer(1, "bar", 9, NO_FIN, nullptr); // Packet 7
-
- EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
- frame = InitAckFrame({{QuicPacketNumber(1), QuicPacketNumber(5)},
- {QuicPacketNumber(7), QuicPacketNumber(8)}});
- ProcessAckPacket(&frame);
-
- 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
- // the end of the packet. We can test this to check which encrypter was used.
- connection_.SetEncrypter(ENCRYPTION_INITIAL,
- std::make_unique<TaggingEncrypter>(0x01));
-
- // Attempt to send a handshake message and have the socket block.
- EXPECT_CALL(*send_algorithm_, CanSend(_)).WillRepeatedly(Return(true));
- BlockOnNextWrite();
- connection_.SendCryptoDataWithString("foo", 0);
- // The packet should be serialized, but not queued.
- EXPECT_EQ(1u, connection_.NumQueuedPackets());
-
- // Switch to the new encrypter.
- connection_.SetEncrypter(ENCRYPTION_ZERO_RTT,
- std::make_unique<TaggingEncrypter>(0x02));
- connection_.SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
-
- // Now become writeable and flush the packets.
- writer_->SetWritable();
- EXPECT_CALL(visitor_, OnCanWrite());
- connection_.OnCanWrite();
- EXPECT_EQ(0u, connection_.NumQueuedPackets());
-
- // Verify that the handshake packet went out at the null encryption.
- EXPECT_EQ(0x01010101u, writer_->final_bytes_of_last_packet());
-}
-
-TEST_P(QuicConnectionTest,
- DropRetransmitsForNullEncryptedPacketAfterForwardSecure) {
- use_tagging_decrypter();
- connection_.SetEncrypter(ENCRYPTION_INITIAL,
- std::make_unique<TaggingEncrypter>(0x01));
- connection_.SendCryptoStreamData();
-
- // Simulate the retransmission alarm firing and the socket blocking.
- BlockOnNextWrite();
- clock_.AdvanceTime(DefaultRetransmissionTime());
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
- connection_.GetRetransmissionAlarm()->Fire();
- EXPECT_EQ(1u, connection_.NumQueuedPackets());
-
- // Go forward secure.
- connection_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
- std::make_unique<TaggingEncrypter>(0x02));
- connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
- notifier_.NeuterUnencryptedData();
- connection_.NeuterUnencryptedPackets();
- connection_.OnHandshakeComplete();
-
- EXPECT_EQ(QuicTime::Zero(), connection_.GetRetransmissionAlarm()->deadline());
- // Unblock the socket and ensure that no packets are sent.
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
- writer_->SetWritable();
- connection_.OnCanWrite();
-}
-
-TEST_P(QuicConnectionTest, RetransmitPacketsWithInitialEncryption) {
- use_tagging_decrypter();
- connection_.SetEncrypter(ENCRYPTION_INITIAL,
- std::make_unique<TaggingEncrypter>(0x01));
- connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
-
- connection_.SendCryptoDataWithString("foo", 0);
-
- connection_.SetEncrypter(ENCRYPTION_ZERO_RTT,
- std::make_unique<TaggingEncrypter>(0x02));
- connection_.SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
-
- SendStreamDataToPeer(2, "bar", 0, NO_FIN, nullptr);
- EXPECT_FALSE(notifier_.HasLostStreamData());
- connection_.MarkZeroRttPacketsForRetransmission(0);
- EXPECT_TRUE(notifier_.HasLostStreamData());
-}
-
-TEST_P(QuicConnectionTest, BufferNonDecryptablePackets) {
- if (connection_.SupportsMultiplePacketNumberSpaces()) {
- return;
- }
- // SetFromConfig is always called after construction from InitializeSession.
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
- QuicConfig config;
- connection_.SetFromConfig(config);
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- use_tagging_decrypter();
-
- const uint8_t tag = 0x07;
- peer_framer_.SetEncrypter(ENCRYPTION_ZERO_RTT,
- std::make_unique<TaggingEncrypter>(tag));
-
- // Process an encrypted packet which can not yet be decrypted which should
- // result in the packet being buffered.
- ProcessDataPacketAtLevel(1, !kHasStopWaiting, ENCRYPTION_ZERO_RTT);
-
- // Transition to the new encryption state and process another encrypted packet
- // which should result in the original packet being processed.
- SetDecrypter(ENCRYPTION_ZERO_RTT,
- std::make_unique<StrictTaggingDecrypter>(tag));
- connection_.SetEncrypter(ENCRYPTION_ZERO_RTT,
- std::make_unique<TaggingEncrypter>(tag));
- connection_.SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
- EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(2);
- ProcessDataPacketAtLevel(2, !kHasStopWaiting, ENCRYPTION_ZERO_RTT);
-
- // Finally, process a third packet and note that we do not reprocess the
- // buffered packet.
- EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
- 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;
- }
- // SetFromConfig is always called after construction from InitializeSession.
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
- QuicConfig config;
- config.set_max_undecryptable_packets(100);
- connection_.SetFromConfig(config);
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- use_tagging_decrypter();
-
- const uint8_t tag = 0x07;
- peer_framer_.SetEncrypter(ENCRYPTION_ZERO_RTT,
- std::make_unique<TaggingEncrypter>(tag));
-
- // Process an encrypted packet which can not yet be decrypted which should
- // result in the packet being buffered.
- for (uint64_t i = 1; i <= 100; ++i) {
- ProcessDataPacketAtLevel(i, !kHasStopWaiting, ENCRYPTION_ZERO_RTT);
- }
-
- // Transition to the new encryption state and process another encrypted packet
- // which should result in the original packets being processed.
- EXPECT_FALSE(connection_.GetProcessUndecryptablePacketsAlarm()->IsSet());
- SetDecrypter(ENCRYPTION_ZERO_RTT,
- std::make_unique<StrictTaggingDecrypter>(tag));
- EXPECT_TRUE(connection_.GetProcessUndecryptablePacketsAlarm()->IsSet());
- connection_.SetEncrypter(ENCRYPTION_ZERO_RTT,
- std::make_unique<TaggingEncrypter>(tag));
- connection_.SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
-
- EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(100);
- connection_.GetProcessUndecryptablePacketsAlarm()->Fire();
-
- // Finally, process a third packet and note that we do not reprocess the
- // buffered packet.
- EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
- ProcessDataPacketAtLevel(102, !kHasStopWaiting, ENCRYPTION_ZERO_RTT);
-}
-
-TEST_P(QuicConnectionTest, SetRTOAfterWritingToSocket) {
- BlockOnNextWrite();
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
- connection_.SendStreamDataWithString(1, "foo", 0, NO_FIN);
- EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
-
- // Test that RTO is started once we write to the socket.
- writer_->SetWritable();
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
- connection_.OnCanWrite();
- 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);
- EXPECT_EQ(1u, connection_.NumQueuedPackets());
-
- // Unblock the writes and actually send.
- writer_->SetWritable();
- connection_.OnCanWrite();
- EXPECT_EQ(0u, connection_.NumQueuedPackets());
-}
-
-TEST_P(QuicConnectionTest, InitialTimeout) {
- EXPECT_TRUE(connection_.connected());
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AnyNumber());
- EXPECT_FALSE(connection_.GetTimeoutAlarm()->IsSet());
-
- // SetFromConfig sets the initial timeouts before negotiation.
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
- QuicConfig config;
- connection_.SetFromConfig(config);
- // Subtract a second from the idle timeout on the client side.
- QuicTime default_timeout =
- clock_.ApproximateNow() +
- QuicTime::Delta::FromSeconds(kInitialIdleTimeoutSecs - 1);
- EXPECT_EQ(default_timeout, connection_.GetTimeoutAlarm()->deadline());
-
- EXPECT_CALL(visitor_,
- OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF));
- // Simulate the timeout alarm firing.
- clock_.AdvanceTime(QuicTime::Delta::FromSeconds(kInitialIdleTimeoutSecs - 1));
- connection_.GetTimeoutAlarm()->Fire();
-
- EXPECT_FALSE(connection_.GetTimeoutAlarm()->IsSet());
- EXPECT_FALSE(connection_.connected());
-
- EXPECT_FALSE(connection_.HasPendingAcks());
- EXPECT_FALSE(connection_.GetPingAlarm()->IsSet());
- EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
- EXPECT_FALSE(connection_.GetSendAlarm()->IsSet());
- EXPECT_FALSE(connection_.GetMtuDiscoveryAlarm()->IsSet());
- EXPECT_FALSE(connection_.GetProcessUndecryptablePacketsAlarm()->IsSet());
- TestConnectionCloseQuicErrorCode(QUIC_NETWORK_IDLE_TIMEOUT);
-}
-
-TEST_P(QuicConnectionTest, IdleTimeoutAfterFirstSentPacket) {
- EXPECT_TRUE(connection_.connected());
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AnyNumber());
- EXPECT_FALSE(connection_.GetTimeoutAlarm()->IsSet());
-
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
- QuicConfig config;
- connection_.SetFromConfig(config);
- EXPECT_TRUE(connection_.GetTimeoutAlarm()->IsSet());
- QuicTime initial_ddl =
- clock_.ApproximateNow() +
- QuicTime::Delta::FromSeconds(kInitialIdleTimeoutSecs - 1);
- EXPECT_EQ(initial_ddl, connection_.GetTimeoutAlarm()->deadline());
- EXPECT_TRUE(connection_.connected());
-
- // Advance the time and send the first packet to the peer.
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(20));
- QuicPacketNumber last_packet;
- SendStreamDataToPeer(1, "foo", 0, NO_FIN, &last_packet);
- EXPECT_EQ(QuicPacketNumber(1u), last_packet);
- // This will be the updated deadline for the connection to idle time out.
- QuicTime new_ddl = clock_.ApproximateNow() +
- QuicTime::Delta::FromSeconds(kInitialIdleTimeoutSecs - 1);
-
- // Simulate the timeout alarm firing, the connection should not be closed as
- // a new packet has been sent.
- EXPECT_CALL(visitor_, OnConnectionClosed(_, _)).Times(0);
- QuicTime::Delta delay = initial_ddl - clock_.ApproximateNow();
- clock_.AdvanceTime(delay);
- // Verify the timeout alarm deadline is updated.
- EXPECT_TRUE(connection_.connected());
- EXPECT_TRUE(connection_.GetTimeoutAlarm()->IsSet());
- EXPECT_EQ(new_ddl, connection_.GetTimeoutAlarm()->deadline());
-
- // Simulate the timeout alarm firing again, the connection now should be
- // closed.
- EXPECT_CALL(visitor_,
- OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF));
- clock_.AdvanceTime(new_ddl - clock_.ApproximateNow());
- connection_.GetTimeoutAlarm()->Fire();
- EXPECT_FALSE(connection_.GetTimeoutAlarm()->IsSet());
- EXPECT_FALSE(connection_.connected());
-
- EXPECT_FALSE(connection_.HasPendingAcks());
- EXPECT_FALSE(connection_.GetPingAlarm()->IsSet());
- EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
- EXPECT_FALSE(connection_.GetSendAlarm()->IsSet());
- EXPECT_FALSE(connection_.GetMtuDiscoveryAlarm()->IsSet());
- TestConnectionCloseQuicErrorCode(QUIC_NETWORK_IDLE_TIMEOUT);
-}
-
-TEST_P(QuicConnectionTest, IdleTimeoutAfterSendTwoPackets) {
- EXPECT_TRUE(connection_.connected());
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AnyNumber());
- EXPECT_FALSE(connection_.GetTimeoutAlarm()->IsSet());
-
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
- QuicConfig config;
- connection_.SetFromConfig(config);
- EXPECT_TRUE(connection_.GetTimeoutAlarm()->IsSet());
- QuicTime initial_ddl =
- clock_.ApproximateNow() +
- QuicTime::Delta::FromSeconds(kInitialIdleTimeoutSecs - 1);
- EXPECT_EQ(initial_ddl, connection_.GetTimeoutAlarm()->deadline());
- EXPECT_TRUE(connection_.connected());
-
- // Immediately send the first packet, this is a rare case but test code will
- // hit this issue often as MockClock used for tests doesn't move with code
- // execution until manually adjusted.
- QuicPacketNumber last_packet;
- SendStreamDataToPeer(1, "foo", 0, NO_FIN, &last_packet);
- EXPECT_EQ(QuicPacketNumber(1u), last_packet);
-
- // Advance the time and send the second packet to the peer.
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(20));
- SendStreamDataToPeer(1, "foo", 0, NO_FIN, &last_packet);
- EXPECT_EQ(QuicPacketNumber(2u), last_packet);
-
- // Simulate the timeout alarm firing, the connection will be closed.
- EXPECT_CALL(visitor_,
- OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF));
- clock_.AdvanceTime(initial_ddl - clock_.ApproximateNow());
- connection_.GetTimeoutAlarm()->Fire();
-
- EXPECT_FALSE(connection_.GetTimeoutAlarm()->IsSet());
- EXPECT_FALSE(connection_.connected());
-
- EXPECT_FALSE(connection_.HasPendingAcks());
- EXPECT_FALSE(connection_.GetPingAlarm()->IsSet());
- EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
- EXPECT_FALSE(connection_.GetSendAlarm()->IsSet());
- EXPECT_FALSE(connection_.GetMtuDiscoveryAlarm()->IsSet());
- TestConnectionCloseQuicErrorCode(QUIC_NETWORK_IDLE_TIMEOUT);
-}
-
-TEST_P(QuicConnectionTest, HandshakeTimeout) {
- // Use a shorter handshake timeout than idle timeout for this test.
- const QuicTime::Delta timeout = QuicTime::Delta::FromSeconds(5);
- connection_.SetNetworkTimeouts(timeout, timeout);
- EXPECT_TRUE(connection_.connected());
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AnyNumber());
-
- QuicTime handshake_timeout =
- clock_.ApproximateNow() + timeout - QuicTime::Delta::FromSeconds(1);
- EXPECT_EQ(handshake_timeout, connection_.GetTimeoutAlarm()->deadline());
- EXPECT_TRUE(connection_.connected());
-
- // Send and ack new data 3 seconds later to lengthen the idle timeout.
- SendStreamDataToPeer(
- GetNthClientInitiatedStreamId(0, connection_.transport_version()),
- "GET /", 0, FIN, nullptr);
- clock_.AdvanceTime(QuicTime::Delta::FromSeconds(3));
- QuicAckFrame frame = InitAckFrame(1);
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
- ProcessAckPacket(&frame);
-
- EXPECT_TRUE(connection_.GetTimeoutAlarm()->IsSet());
- EXPECT_TRUE(connection_.connected());
-
- clock_.AdvanceTime(timeout - QuicTime::Delta::FromSeconds(2));
-
- EXPECT_CALL(visitor_,
- OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF));
- // Simulate the timeout alarm firing.
- connection_.GetTimeoutAlarm()->Fire();
-
- EXPECT_FALSE(connection_.GetTimeoutAlarm()->IsSet());
- EXPECT_FALSE(connection_.connected());
-
- EXPECT_FALSE(connection_.HasPendingAcks());
- EXPECT_FALSE(connection_.GetPingAlarm()->IsSet());
- EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
- EXPECT_FALSE(connection_.GetSendAlarm()->IsSet());
- TestConnectionCloseQuicErrorCode(QUIC_HANDSHAKE_TIMEOUT);
-}
-
-TEST_P(QuicConnectionTest, PingAfterSend) {
- if (connection_.SupportsMultiplePacketNumberSpaces()) {
- return;
- }
- EXPECT_TRUE(connection_.connected());
- EXPECT_CALL(visitor_, ShouldKeepConnectionAlive())
- .WillRepeatedly(Return(true));
- EXPECT_FALSE(connection_.GetPingAlarm()->IsSet());
-
- // Advance to 5ms, and send a packet to the peer, which will set
- // the ping alarm.
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
- EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
- SendStreamDataToPeer(
- GetNthClientInitiatedStreamId(0, connection_.transport_version()),
- "GET /", 0, FIN, nullptr);
- EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
- EXPECT_EQ(QuicTime::Delta::FromSeconds(15),
- connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
-
- // Now recevie an ACK of the previous packet, which will move the
- // ping alarm forward.
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
- QuicAckFrame frame = InitAckFrame(1);
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
- ProcessAckPacket(&frame);
- EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
- // The ping timer is set slightly less than 15 seconds in the future, because
- // of the 1s ping timer alarm granularity.
- EXPECT_EQ(
- QuicTime::Delta::FromSeconds(15) - QuicTime::Delta::FromMilliseconds(5),
- connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
-
- writer_->Reset();
- clock_.AdvanceTime(QuicTime::Delta::FromSeconds(15));
- connection_.GetPingAlarm()->Fire();
- size_t padding_frame_count = writer_->padding_frames().size();
- EXPECT_EQ(padding_frame_count + 1u, writer_->frame_count());
- ASSERT_EQ(1u, writer_->ping_frames().size());
- writer_->Reset();
-
- EXPECT_CALL(visitor_, ShouldKeepConnectionAlive())
- .WillRepeatedly(Return(false));
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
- SendAckPacketToPeer();
-
- EXPECT_FALSE(connection_.GetPingAlarm()->IsSet());
-}
-
-TEST_P(QuicConnectionTest, ReducedPingTimeout) {
- if (connection_.SupportsMultiplePacketNumberSpaces()) {
- return;
- }
- EXPECT_TRUE(connection_.connected());
- EXPECT_CALL(visitor_, ShouldKeepConnectionAlive())
- .WillRepeatedly(Return(true));
- EXPECT_FALSE(connection_.GetPingAlarm()->IsSet());
-
- // Use a reduced ping timeout for this connection.
- connection_.set_ping_timeout(QuicTime::Delta::FromSeconds(10));
-
- // Advance to 5ms, and send a packet to the peer, which will set
- // the ping alarm.
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
- EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
- SendStreamDataToPeer(
- GetNthClientInitiatedStreamId(0, connection_.transport_version()),
- "GET /", 0, FIN, nullptr);
- EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
- EXPECT_EQ(QuicTime::Delta::FromSeconds(10),
- connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
-
- // Now recevie an ACK of the previous packet, which will move the
- // ping alarm forward.
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
- QuicAckFrame frame = InitAckFrame(1);
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
- ProcessAckPacket(&frame);
- EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
- // The ping timer is set slightly less than 10 seconds in the future, because
- // of the 1s ping timer alarm granularity.
- EXPECT_EQ(
- QuicTime::Delta::FromSeconds(10) - QuicTime::Delta::FromMilliseconds(5),
- connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
-
- writer_->Reset();
- clock_.AdvanceTime(QuicTime::Delta::FromSeconds(10));
- connection_.GetPingAlarm()->Fire();
- size_t padding_frame_count = writer_->padding_frames().size();
- EXPECT_EQ(padding_frame_count + 1u, writer_->frame_count());
- ASSERT_EQ(1u, writer_->ping_frames().size());
- writer_->Reset();
-
- EXPECT_CALL(visitor_, ShouldKeepConnectionAlive())
- .WillRepeatedly(Return(false));
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
- SendAckPacketToPeer();
-
- EXPECT_FALSE(connection_.GetPingAlarm()->IsSet());
-}
-
-// Tests whether sending an MTU discovery packet to peer successfully causes the
-// maximum packet size to increase.
-TEST_P(QuicConnectionTest, SendMtuDiscoveryPacket) {
- MtuDiscoveryTestInit();
-
- // Send an MTU probe.
- const size_t new_mtu = kDefaultMaxPacketSize + 100;
- QuicByteCount mtu_probe_size;
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
- .WillOnce(SaveArg<3>(&mtu_probe_size));
- connection_.SendMtuDiscoveryPacket(new_mtu);
- EXPECT_EQ(new_mtu, mtu_probe_size);
- EXPECT_EQ(QuicPacketNumber(1u), creator_->packet_number());
-
- // Send more than MTU worth of data. No acknowledgement was received so far,
- // so the MTU should be at its old value.
- const std::string data(kDefaultMaxPacketSize + 1, '.');
- QuicByteCount size_before_mtu_change;
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
- .Times(2)
- .WillOnce(SaveArg<3>(&size_before_mtu_change))
- .WillOnce(Return());
- connection_.SendStreamDataWithString(3, data, 0, FIN);
- EXPECT_EQ(QuicPacketNumber(3u), creator_->packet_number());
- EXPECT_EQ(kDefaultMaxPacketSize, size_before_mtu_change);
-
- // Acknowledge all packets so far.
- QuicAckFrame probe_ack = InitAckFrame(3);
- EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
- ProcessAckPacket(&probe_ack);
- EXPECT_EQ(new_mtu, connection_.max_packet_length());
-
- // Send the same data again. Check that it fits into a single packet now.
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
- connection_.SendStreamDataWithString(3, data, 0, FIN);
- EXPECT_EQ(QuicPacketNumber(4u), creator_->packet_number());
-}
-
-// Verifies that when a MTU probe packet is sent and buffered in a batch writer,
-// the writer is flushed immediately.
-TEST_P(QuicConnectionTest, BatchWriterFlushedAfterMtuDiscoveryPacket) {
- writer_->SetBatchMode(true);
- MtuDiscoveryTestInit();
-
- // Send an MTU probe.
- const size_t target_mtu = kDefaultMaxPacketSize + 100;
- QuicByteCount mtu_probe_size;
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
- .WillOnce(SaveArg<3>(&mtu_probe_size));
- const uint32_t prior_flush_attempts = writer_->flush_attempts();
- connection_.SendMtuDiscoveryPacket(target_mtu);
- EXPECT_EQ(target_mtu, mtu_probe_size);
- EXPECT_EQ(writer_->flush_attempts(), prior_flush_attempts + 1);
-}
-
-// Tests whether MTU discovery does not happen when it is not explicitly enabled
-// by the connection options.
-TEST_P(QuicConnectionTest, MtuDiscoveryDisabled) {
- MtuDiscoveryTestInit();
-
- const QuicPacketCount packets_between_probes_base = 10;
- set_packets_between_probes_base(packets_between_probes_base);
-
- const QuicPacketCount number_of_packets = packets_between_probes_base * 2;
- for (QuicPacketCount i = 0; i < number_of_packets; i++) {
- SendStreamDataToPeer(3, ".", i, NO_FIN, nullptr);
- EXPECT_FALSE(connection_.GetMtuDiscoveryAlarm()->IsSet());
- EXPECT_EQ(0u, connection_.mtu_probe_count());
- }
-}
-
-// Tests whether MTU discovery works when all probes are acknowledged on the
-// first try.
-TEST_P(QuicConnectionTest, MtuDiscoveryEnabled) {
- MtuDiscoveryTestInit();
-
- const QuicPacketCount packets_between_probes_base = 5;
- set_packets_between_probes_base(packets_between_probes_base);
-
- connection_.EnablePathMtuDiscovery(send_algorithm_);
-
- // Send enough packets so that the next one triggers path MTU discovery.
- for (QuicPacketCount i = 0; i < packets_between_probes_base - 1; i++) {
- SendStreamDataToPeer(3, ".", i, NO_FIN, nullptr);
- ASSERT_FALSE(connection_.GetMtuDiscoveryAlarm()->IsSet());
- }
-
- // Trigger the probe.
- SendStreamDataToPeer(3, "!", packets_between_probes_base - 1, NO_FIN,
- nullptr);
- ASSERT_TRUE(connection_.GetMtuDiscoveryAlarm()->IsSet());
- QuicByteCount probe_size;
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
- .WillOnce(SaveArg<3>(&probe_size));
- connection_.GetMtuDiscoveryAlarm()->Fire();
-
- EXPECT_THAT(probe_size, InRange(connection_.max_packet_length(),
- kMtuDiscoveryTargetPacketSizeHigh));
-
- const QuicPacketNumber probe_packet_number =
- FirstSendingPacketNumber() + packets_between_probes_base;
- ASSERT_EQ(probe_packet_number, creator_->packet_number());
-
- // Acknowledge all packets sent so far.
- QuicAckFrame probe_ack = InitAckFrame(probe_packet_number);
- EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _))
- .Times(AnyNumber());
- ProcessAckPacket(&probe_ack);
- EXPECT_EQ(probe_size, connection_.max_packet_length());
- EXPECT_EQ(0u, connection_.GetBytesInFlight());
-
- EXPECT_EQ(1u, connection_.mtu_probe_count());
-
- QuicStreamOffset stream_offset = packets_between_probes_base;
- QuicByteCount last_probe_size = 0;
- for (size_t num_probes = 1; num_probes < kMtuDiscoveryAttempts;
- ++num_probes) {
- // Send just enough packets without triggering the next probe.
- for (QuicPacketCount i = 0;
- i < (packets_between_probes_base << num_probes) - 1; ++i) {
- SendStreamDataToPeer(3, ".", stream_offset++, NO_FIN, nullptr);
- ASSERT_FALSE(connection_.GetMtuDiscoveryAlarm()->IsSet());
- }
-
- // Trigger the next probe.
- SendStreamDataToPeer(3, "!", stream_offset++, NO_FIN, nullptr);
- ASSERT_TRUE(connection_.GetMtuDiscoveryAlarm()->IsSet());
- QuicByteCount new_probe_size;
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
- .WillOnce(SaveArg<3>(&new_probe_size));
- connection_.GetMtuDiscoveryAlarm()->Fire();
- EXPECT_THAT(new_probe_size,
- InRange(probe_size, kMtuDiscoveryTargetPacketSizeHigh));
- EXPECT_EQ(num_probes + 1, connection_.mtu_probe_count());
-
- // Acknowledge all packets sent so far.
- QuicAckFrame probe_ack = InitAckFrame(creator_->packet_number());
- ProcessAckPacket(&probe_ack);
- EXPECT_EQ(new_probe_size, connection_.max_packet_length());
- EXPECT_EQ(0u, connection_.GetBytesInFlight());
-
- last_probe_size = probe_size;
- probe_size = new_probe_size;
- }
-
- // The last probe size should be equal to the target.
- EXPECT_EQ(probe_size, kMtuDiscoveryTargetPacketSizeHigh);
-
- writer_->SetShouldWriteFail();
-
- // Ignore PACKET_WRITE_ERROR once.
- SendStreamDataToPeer(3, "(", stream_offset++, NO_FIN, nullptr);
- EXPECT_EQ(last_probe_size, connection_.max_packet_length());
- EXPECT_TRUE(connection_.connected());
-
- // Close connection on another PACKET_WRITE_ERROR.
- EXPECT_CALL(visitor_, OnConnectionClosed(_, _))
- .WillOnce(Invoke(this, &QuicConnectionTest::SaveConnectionCloseFrame));
- SendStreamDataToPeer(3, ")", stream_offset++, NO_FIN, nullptr);
- EXPECT_EQ(last_probe_size, connection_.max_packet_length());
- EXPECT_FALSE(connection_.connected());
- EXPECT_THAT(saved_connection_close_frame_.quic_error_code,
- IsError(QUIC_PACKET_WRITE_ERROR));
-}
-
-// After a successful MTU probe, one and only one write error should be ignored
-// if it happened in QuicConnection::FlushPacket.
-TEST_P(QuicConnectionTest,
- MtuDiscoveryIgnoreOneWriteErrorInFlushAfterSuccessfulProbes) {
- MtuDiscoveryTestInit();
- writer_->SetBatchMode(true);
-
- const QuicPacketCount packets_between_probes_base = 5;
- set_packets_between_probes_base(packets_between_probes_base);
-
- connection_.EnablePathMtuDiscovery(send_algorithm_);
-
- const QuicByteCount original_max_packet_length =
- connection_.max_packet_length();
- // Send enough packets so that the next one triggers path MTU discovery.
- for (QuicPacketCount i = 0; i < packets_between_probes_base - 1; i++) {
- SendStreamDataToPeer(3, ".", i, NO_FIN, nullptr);
- ASSERT_FALSE(connection_.GetMtuDiscoveryAlarm()->IsSet());
- }
-
- // Trigger the probe.
- SendStreamDataToPeer(3, "!", packets_between_probes_base - 1, NO_FIN,
- nullptr);
- ASSERT_TRUE(connection_.GetMtuDiscoveryAlarm()->IsSet());
- QuicByteCount probe_size;
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
- .WillOnce(SaveArg<3>(&probe_size));
- connection_.GetMtuDiscoveryAlarm()->Fire();
-
- EXPECT_THAT(probe_size, InRange(connection_.max_packet_length(),
- kMtuDiscoveryTargetPacketSizeHigh));
-
- const QuicPacketNumber probe_packet_number =
- FirstSendingPacketNumber() + packets_between_probes_base;
- ASSERT_EQ(probe_packet_number, creator_->packet_number());
-
- // Acknowledge all packets sent so far.
- QuicAckFrame probe_ack = InitAckFrame(probe_packet_number);
- EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _))
- .Times(AnyNumber());
- ProcessAckPacket(&probe_ack);
- EXPECT_EQ(probe_size, connection_.max_packet_length());
- EXPECT_EQ(0u, connection_.GetBytesInFlight());
-
- EXPECT_EQ(1u, connection_.mtu_probe_count());
-
- writer_->SetShouldWriteFail();
-
- // Ignore PACKET_WRITE_ERROR once.
- {
- QuicConnection::ScopedPacketFlusher flusher(&connection_);
- // flusher's destructor will call connection_.FlushPackets, which should
- // get a WRITE_STATUS_ERROR from the writer and ignore it.
- }
- EXPECT_EQ(original_max_packet_length, connection_.max_packet_length());
- EXPECT_TRUE(connection_.connected());
-
- // Close connection on another PACKET_WRITE_ERROR.
- EXPECT_CALL(visitor_, OnConnectionClosed(_, _))
- .WillOnce(Invoke(this, &QuicConnectionTest::SaveConnectionCloseFrame));
- {
- QuicConnection::ScopedPacketFlusher flusher(&connection_);
- // flusher's destructor will call connection_.FlushPackets, which should
- // get a WRITE_STATUS_ERROR from the writer and ignore it.
- }
- EXPECT_EQ(original_max_packet_length, connection_.max_packet_length());
- EXPECT_FALSE(connection_.connected());
- EXPECT_THAT(saved_connection_close_frame_.quic_error_code,
- IsError(QUIC_PACKET_WRITE_ERROR));
-}
-
-// Simulate the case where the first attempt to send a probe is write blocked,
-// and after unblock, the second attempt returns a MSG_TOO_BIG error.
-TEST_P(QuicConnectionTest, MtuDiscoveryWriteBlocked) {
- MtuDiscoveryTestInit();
-
- const QuicPacketCount packets_between_probes_base = 5;
- set_packets_between_probes_base(packets_between_probes_base);
-
- connection_.EnablePathMtuDiscovery(send_algorithm_);
-
- // Send enough packets so that the next one triggers path MTU discovery.
- for (QuicPacketCount i = 0; i < packets_between_probes_base - 1; i++) {
- SendStreamDataToPeer(3, ".", i, NO_FIN, nullptr);
- ASSERT_FALSE(connection_.GetMtuDiscoveryAlarm()->IsSet());
- }
-
- QuicByteCount original_max_packet_length = connection_.max_packet_length();
-
- // Trigger the probe.
- SendStreamDataToPeer(3, "!", packets_between_probes_base - 1, NO_FIN,
- nullptr);
- ASSERT_TRUE(connection_.GetMtuDiscoveryAlarm()->IsSet());
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _));
- BlockOnNextWrite();
- EXPECT_EQ(0u, connection_.NumQueuedPackets());
- connection_.GetMtuDiscoveryAlarm()->Fire();
- EXPECT_EQ(1u, connection_.mtu_probe_count());
- EXPECT_EQ(1u, connection_.NumQueuedPackets());
- ASSERT_TRUE(connection_.connected());
-
- writer_->SetWritable();
- SimulateNextPacketTooLarge();
- connection_.OnCanWrite();
- EXPECT_EQ(0u, connection_.NumQueuedPackets());
- EXPECT_EQ(original_max_packet_length, connection_.max_packet_length());
- EXPECT_TRUE(connection_.connected());
-}
-
-// Tests whether MTU discovery works correctly when the probes never get
-// acknowledged.
-TEST_P(QuicConnectionTest, MtuDiscoveryFailed) {
- MtuDiscoveryTestInit();
-
- // Lower the number of probes between packets in order to make the test go
- // much faster.
- const QuicPacketCount packets_between_probes_base = 5;
- set_packets_between_probes_base(packets_between_probes_base);
-
- connection_.EnablePathMtuDiscovery(send_algorithm_);
-
- const QuicTime::Delta rtt = QuicTime::Delta::FromMilliseconds(100);
-
- EXPECT_EQ(packets_between_probes_base,
- QuicConnectionPeer::GetPacketsBetweenMtuProbes(&connection_));
-
- // This tests sends more packets than strictly necessary to make sure that if
- // the connection was to send more discovery packets than needed, those would
- // get caught as well.
- const QuicPacketCount number_of_packets =
- packets_between_probes_base * (1 << (kMtuDiscoveryAttempts + 1));
- std::vector<QuicPacketNumber> mtu_discovery_packets;
- // Called on many acks.
- EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _))
- .Times(AnyNumber());
- for (QuicPacketCount i = 0; i < number_of_packets; i++) {
- SendStreamDataToPeer(3, "!", i, NO_FIN, nullptr);
- clock_.AdvanceTime(rtt);
-
- // Receive an ACK, which marks all data packets as received, and all MTU
- // discovery packets as missing.
-
- QuicAckFrame ack;
-
- if (!mtu_discovery_packets.empty()) {
- QuicPacketNumber min_packet = *min_element(mtu_discovery_packets.begin(),
- mtu_discovery_packets.end());
- QuicPacketNumber max_packet = *max_element(mtu_discovery_packets.begin(),
- mtu_discovery_packets.end());
- ack.packets.AddRange(QuicPacketNumber(1), min_packet);
- ack.packets.AddRange(QuicPacketNumber(max_packet + 1),
- creator_->packet_number() + 1);
- ack.largest_acked = creator_->packet_number();
-
- } else {
- ack.packets.AddRange(QuicPacketNumber(1), creator_->packet_number() + 1);
- ack.largest_acked = creator_->packet_number();
- }
-
- ProcessAckPacket(&ack);
-
- // Trigger MTU probe if it would be scheduled now.
- if (!connection_.GetMtuDiscoveryAlarm()->IsSet()) {
- continue;
- }
-
- // Fire the alarm. The alarm should cause a packet to be sent.
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _));
- connection_.GetMtuDiscoveryAlarm()->Fire();
- // Record the packet number of the MTU discovery packet in order to
- // mark it as NACK'd.
- mtu_discovery_packets.push_back(creator_->packet_number());
- }
-
- // Ensure the number of packets between probes grows exponentially by checking
- // it against the closed-form expression for the packet number.
- ASSERT_EQ(kMtuDiscoveryAttempts, mtu_discovery_packets.size());
- for (uint64_t i = 0; i < kMtuDiscoveryAttempts; i++) {
- // 2^0 + 2^1 + 2^2 + ... + 2^n = 2^(n + 1) - 1
- const QuicPacketCount packets_between_probes =
- packets_between_probes_base * ((1 << (i + 1)) - 1);
- EXPECT_EQ(QuicPacketNumber(packets_between_probes + (i + 1)),
- mtu_discovery_packets[i]);
- }
-
- EXPECT_FALSE(connection_.GetMtuDiscoveryAlarm()->IsSet());
- EXPECT_EQ(kDefaultMaxPacketSize, connection_.max_packet_length());
- EXPECT_EQ(kMtuDiscoveryAttempts, connection_.mtu_probe_count());
-}
-
-// Probe 3 times, the first one succeeds, then fails, then succeeds again.
-TEST_P(QuicConnectionTest, MtuDiscoverySecondProbeFailed) {
- MtuDiscoveryTestInit();
-
- const QuicPacketCount packets_between_probes_base = 5;
- set_packets_between_probes_base(packets_between_probes_base);
-
- connection_.EnablePathMtuDiscovery(send_algorithm_);
-
- // Send enough packets so that the next one triggers path MTU discovery.
- QuicStreamOffset stream_offset = 0;
- for (QuicPacketCount i = 0; i < packets_between_probes_base - 1; i++) {
- SendStreamDataToPeer(3, ".", stream_offset++, NO_FIN, nullptr);
- ASSERT_FALSE(connection_.GetMtuDiscoveryAlarm()->IsSet());
- }
-
- // Trigger the probe.
- SendStreamDataToPeer(3, "!", packets_between_probes_base - 1, NO_FIN,
- nullptr);
- ASSERT_TRUE(connection_.GetMtuDiscoveryAlarm()->IsSet());
- QuicByteCount probe_size;
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
- .WillOnce(SaveArg<3>(&probe_size));
- connection_.GetMtuDiscoveryAlarm()->Fire();
- EXPECT_THAT(probe_size, InRange(connection_.max_packet_length(),
- kMtuDiscoveryTargetPacketSizeHigh));
-
- const QuicPacketNumber probe_packet_number =
- FirstSendingPacketNumber() + packets_between_probes_base;
- ASSERT_EQ(probe_packet_number, creator_->packet_number());
-
- // Acknowledge all packets sent so far.
- QuicAckFrame first_ack = InitAckFrame(probe_packet_number);
- EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _))
- .Times(AnyNumber());
- ProcessAckPacket(&first_ack);
- EXPECT_EQ(probe_size, connection_.max_packet_length());
- EXPECT_EQ(0u, connection_.GetBytesInFlight());
-
- EXPECT_EQ(1u, connection_.mtu_probe_count());
-
- // Send just enough packets without triggering the second probe.
- for (QuicPacketCount i = 0; i < (packets_between_probes_base << 1) - 1; ++i) {
- SendStreamDataToPeer(3, ".", stream_offset++, NO_FIN, nullptr);
- ASSERT_FALSE(connection_.GetMtuDiscoveryAlarm()->IsSet());
- }
-
- // Trigger the second probe.
- SendStreamDataToPeer(3, "!", stream_offset++, NO_FIN, nullptr);
- ASSERT_TRUE(connection_.GetMtuDiscoveryAlarm()->IsSet());
- QuicByteCount second_probe_size;
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
- .WillOnce(SaveArg<3>(&second_probe_size));
- connection_.GetMtuDiscoveryAlarm()->Fire();
- EXPECT_THAT(second_probe_size,
- InRange(probe_size, kMtuDiscoveryTargetPacketSizeHigh));
- EXPECT_EQ(2u, connection_.mtu_probe_count());
-
- // Acknowledge all packets sent so far, except the second probe.
- QuicPacketNumber second_probe_packet_number = creator_->packet_number();
- QuicAckFrame second_ack = InitAckFrame(second_probe_packet_number - 1);
- ProcessAckPacket(&first_ack);
- EXPECT_EQ(probe_size, connection_.max_packet_length());
-
- // Send just enough packets without triggering the third probe.
- for (QuicPacketCount i = 0; i < (packets_between_probes_base << 2) - 1; ++i) {
- SendStreamDataToPeer(3, "@", stream_offset++, NO_FIN, nullptr);
- ASSERT_FALSE(connection_.GetMtuDiscoveryAlarm()->IsSet());
- }
-
- // Trigger the third probe.
- SendStreamDataToPeer(3, "#", stream_offset++, NO_FIN, nullptr);
- ASSERT_TRUE(connection_.GetMtuDiscoveryAlarm()->IsSet());
- QuicByteCount third_probe_size;
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
- .WillOnce(SaveArg<3>(&third_probe_size));
- connection_.GetMtuDiscoveryAlarm()->Fire();
- EXPECT_THAT(third_probe_size, InRange(probe_size, second_probe_size));
- EXPECT_EQ(3u, connection_.mtu_probe_count());
-
- // Acknowledge all packets sent so far, except the second probe.
- QuicAckFrame third_ack =
- ConstructAckFrame(creator_->packet_number(), second_probe_packet_number);
- ProcessAckPacket(&third_ack);
- EXPECT_EQ(third_probe_size, connection_.max_packet_length());
-
- SendStreamDataToPeer(3, "$", stream_offset++, NO_FIN, nullptr);
- EXPECT_TRUE(connection_.PathMtuReductionDetectionInProgress());
-
- if (connection_.PathDegradingDetectionInProgress() &&
- QuicConnectionPeer::GetPathDegradingDeadline(&connection_) <
- QuicConnectionPeer::GetPathMtuReductionDetectionDeadline(
- &connection_)) {
- // Fire path degrading alarm first.
- connection_.PathDegradingTimeout();
- }
-
- // Verify the max packet size has not reduced.
- EXPECT_EQ(third_probe_size, connection_.max_packet_length());
-
- // Fire alarm to get path mtu reduction callback called.
- EXPECT_TRUE(connection_.PathMtuReductionDetectionInProgress());
- connection_.GetBlackholeDetectorAlarm()->Fire();
-
- // Verify the max packet size has reduced to the previous value.
- EXPECT_EQ(probe_size, connection_.max_packet_length());
-}
-
-// Tests whether MTU discovery works when the writer has a limit on how large a
-// packet can be.
-TEST_P(QuicConnectionTest, MtuDiscoveryWriterLimited) {
- MtuDiscoveryTestInit();
-
- const QuicByteCount mtu_limit = kMtuDiscoveryTargetPacketSizeHigh - 1;
- writer_->set_max_packet_size(mtu_limit);
-
- const QuicPacketCount packets_between_probes_base = 5;
- set_packets_between_probes_base(packets_between_probes_base);
-
- connection_.EnablePathMtuDiscovery(send_algorithm_);
-
- // Send enough packets so that the next one triggers path MTU discovery.
- for (QuicPacketCount i = 0; i < packets_between_probes_base - 1; i++) {
- SendStreamDataToPeer(3, ".", i, NO_FIN, nullptr);
- ASSERT_FALSE(connection_.GetMtuDiscoveryAlarm()->IsSet());
- }
-
- // Trigger the probe.
- SendStreamDataToPeer(3, "!", packets_between_probes_base - 1, NO_FIN,
- nullptr);
- ASSERT_TRUE(connection_.GetMtuDiscoveryAlarm()->IsSet());
- QuicByteCount probe_size;
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
- .WillOnce(SaveArg<3>(&probe_size));
- connection_.GetMtuDiscoveryAlarm()->Fire();
-
- EXPECT_THAT(probe_size, InRange(connection_.max_packet_length(), mtu_limit));
-
- const QuicPacketNumber probe_sequence_number =
- FirstSendingPacketNumber() + packets_between_probes_base;
- ASSERT_EQ(probe_sequence_number, creator_->packet_number());
-
- // Acknowledge all packets sent so far.
- QuicAckFrame probe_ack = InitAckFrame(probe_sequence_number);
- EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _))
- .Times(AnyNumber());
- ProcessAckPacket(&probe_ack);
- EXPECT_EQ(probe_size, connection_.max_packet_length());
- EXPECT_EQ(0u, connection_.GetBytesInFlight());
-
- EXPECT_EQ(1u, connection_.mtu_probe_count());
-
- QuicStreamOffset stream_offset = packets_between_probes_base;
- for (size_t num_probes = 1; num_probes < kMtuDiscoveryAttempts;
- ++num_probes) {
- // Send just enough packets without triggering the next probe.
- for (QuicPacketCount i = 0;
- i < (packets_between_probes_base << num_probes) - 1; ++i) {
- SendStreamDataToPeer(3, ".", stream_offset++, NO_FIN, nullptr);
- ASSERT_FALSE(connection_.GetMtuDiscoveryAlarm()->IsSet());
- }
-
- // Trigger the next probe.
- SendStreamDataToPeer(3, "!", stream_offset++, NO_FIN, nullptr);
- ASSERT_TRUE(connection_.GetMtuDiscoveryAlarm()->IsSet());
- QuicByteCount new_probe_size;
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
- .WillOnce(SaveArg<3>(&new_probe_size));
- connection_.GetMtuDiscoveryAlarm()->Fire();
- EXPECT_THAT(new_probe_size, InRange(probe_size, mtu_limit));
- EXPECT_EQ(num_probes + 1, connection_.mtu_probe_count());
-
- // Acknowledge all packets sent so far.
- QuicAckFrame probe_ack = InitAckFrame(creator_->packet_number());
- ProcessAckPacket(&probe_ack);
- EXPECT_EQ(new_probe_size, connection_.max_packet_length());
- EXPECT_EQ(0u, connection_.GetBytesInFlight());
-
- probe_size = new_probe_size;
- }
-
- // The last probe size should be equal to the target.
- EXPECT_EQ(probe_size, mtu_limit);
-}
-
-// Tests whether MTU discovery works when the writer returns an error despite
-// advertising higher packet length.
-TEST_P(QuicConnectionTest, MtuDiscoveryWriterFailed) {
- MtuDiscoveryTestInit();
-
- const QuicByteCount mtu_limit = kMtuDiscoveryTargetPacketSizeHigh - 1;
- const QuicByteCount initial_mtu = connection_.max_packet_length();
- EXPECT_LT(initial_mtu, mtu_limit);
- writer_->set_max_packet_size(mtu_limit);
-
- const QuicPacketCount packets_between_probes_base = 5;
- set_packets_between_probes_base(packets_between_probes_base);
-
- connection_.EnablePathMtuDiscovery(send_algorithm_);
-
- // Send enough packets so that the next one triggers path MTU discovery.
- for (QuicPacketCount i = 0; i < packets_between_probes_base - 1; i++) {
- SendStreamDataToPeer(3, ".", i, NO_FIN, nullptr);
- ASSERT_FALSE(connection_.GetMtuDiscoveryAlarm()->IsSet());
- }
-
- // Trigger the probe.
- SendStreamDataToPeer(3, "!", packets_between_probes_base - 1, NO_FIN,
- nullptr);
- ASSERT_TRUE(connection_.GetMtuDiscoveryAlarm()->IsSet());
- writer_->SimulateNextPacketTooLarge();
- connection_.GetMtuDiscoveryAlarm()->Fire();
- ASSERT_TRUE(connection_.connected());
-
- // Send more data.
- QuicPacketNumber probe_number = creator_->packet_number();
- QuicPacketCount extra_packets = packets_between_probes_base * 3;
- for (QuicPacketCount i = 0; i < extra_packets; i++) {
- connection_.EnsureWritableAndSendStreamData5();
- ASSERT_FALSE(connection_.GetMtuDiscoveryAlarm()->IsSet());
- }
-
- // Acknowledge all packets sent so far, except for the lost probe.
- QuicAckFrame probe_ack =
- ConstructAckFrame(creator_->packet_number(), probe_number);
- EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
- ProcessAckPacket(&probe_ack);
- EXPECT_EQ(initial_mtu, connection_.max_packet_length());
-
- // Send more packets, and ensure that none of them sets the alarm.
- for (QuicPacketCount i = 0; i < 4 * packets_between_probes_base; i++) {
- connection_.EnsureWritableAndSendStreamData5();
- ASSERT_FALSE(connection_.GetMtuDiscoveryAlarm()->IsSet());
- }
-
- EXPECT_EQ(initial_mtu, connection_.max_packet_length());
- EXPECT_EQ(1u, connection_.mtu_probe_count());
-}
-
-TEST_P(QuicConnectionTest, NoMtuDiscoveryAfterConnectionClosed) {
- MtuDiscoveryTestInit();
-
- const QuicPacketCount packets_between_probes_base = 10;
- set_packets_between_probes_base(packets_between_probes_base);
-
- connection_.EnablePathMtuDiscovery(send_algorithm_);
-
- // Send enough packets so that the next one triggers path MTU discovery.
- for (QuicPacketCount i = 0; i < packets_between_probes_base - 1; i++) {
- SendStreamDataToPeer(3, ".", i, NO_FIN, nullptr);
- ASSERT_FALSE(connection_.GetMtuDiscoveryAlarm()->IsSet());
- }
-
- SendStreamDataToPeer(3, "!", packets_between_probes_base - 1, NO_FIN,
- nullptr);
- EXPECT_TRUE(connection_.GetMtuDiscoveryAlarm()->IsSet());
-
- EXPECT_CALL(visitor_, OnConnectionClosed(_, _));
- connection_.CloseConnection(QUIC_PEER_GOING_AWAY, "no reason",
- ConnectionCloseBehavior::SILENT_CLOSE);
- EXPECT_FALSE(connection_.GetMtuDiscoveryAlarm()->IsSet());
-}
-
-TEST_P(QuicConnectionTest, TimeoutAfterSendDuringHandshake) {
- EXPECT_TRUE(connection_.connected());
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
- QuicConfig config;
- connection_.SetFromConfig(config);
-
- const QuicTime::Delta initial_idle_timeout =
- QuicTime::Delta::FromSeconds(kInitialIdleTimeoutSecs - 1);
- const QuicTime::Delta five_ms = QuicTime::Delta::FromMilliseconds(5);
- QuicTime default_timeout = clock_.ApproximateNow() + initial_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());
-
- // Now send more data. This will not move the timeout because
- // no data has been received since the previous write.
- clock_.AdvanceTime(five_ms);
- SendStreamDataToPeer(
- GetNthClientInitiatedStreamId(1, connection_.transport_version()), "foo",
- 3, FIN, nullptr);
- EXPECT_EQ(default_timeout + five_ms,
- connection_.GetTimeoutAlarm()->deadline());
-
- // The original alarm will fire. We should not time out because we had a
- // network event at t=5ms. The alarm will reregister.
- clock_.AdvanceTime(initial_idle_timeout - five_ms - five_ms);
- EXPECT_EQ(default_timeout, clock_.ApproximateNow());
- EXPECT_TRUE(connection_.GetTimeoutAlarm()->IsSet());
- EXPECT_TRUE(connection_.connected());
- EXPECT_EQ(default_timeout + five_ms,
- connection_.GetTimeoutAlarm()->deadline());
-
- // This time, we should time out.
- EXPECT_CALL(visitor_,
- OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF));
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AtLeast(1));
- clock_.AdvanceTime(five_ms);
- EXPECT_EQ(default_timeout + five_ms, clock_.ApproximateNow());
- connection_.GetTimeoutAlarm()->Fire();
- EXPECT_FALSE(connection_.GetTimeoutAlarm()->IsSet());
- EXPECT_FALSE(connection_.connected());
- 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.
- 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());
-
- if (connection_.version().UsesTls()) {
- QuicConfigPeer::SetReceivedOriginalConnectionId(
- &config, connection_.connection_id());
- QuicConfigPeer::SetReceivedInitialSourceConnectionId(
- &config, connection_.connection_id());
- }
- 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());
-
- // Now send more data. This will not move the timeout because
- // no data has been received since the previous write.
- clock_.AdvanceTime(five_ms);
- SendStreamDataToPeer(
- GetNthClientInitiatedStreamId(1, connection_.transport_version()), "foo",
- 3, FIN, nullptr);
- EXPECT_EQ(default_timeout + five_ms,
- connection_.GetTimeoutAlarm()->deadline());
-
- // The original alarm will fire. We should not time out because we had a
- // network event at t=5ms. The alarm will reregister.
- clock_.AdvanceTime(default_idle_timeout - five_ms - five_ms);
- EXPECT_EQ(default_timeout, clock_.ApproximateNow());
- EXPECT_TRUE(connection_.GetTimeoutAlarm()->IsSet());
- EXPECT_TRUE(connection_.connected());
- EXPECT_EQ(default_timeout + five_ms,
- connection_.GetTimeoutAlarm()->deadline());
-
- // This time, we should time out.
- // This results in a SILENT_CLOSE, so the writer will not be invoked
- // and will not save the frame. Grab the frame from OnConnectionClosed
- // directly.
- EXPECT_CALL(visitor_, OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF))
- .WillOnce(Invoke(this, &QuicConnectionTest::SaveConnectionCloseFrame));
-
- clock_.AdvanceTime(five_ms);
- EXPECT_EQ(default_timeout + five_ms, clock_.ApproximateNow());
- connection_.GetTimeoutAlarm()->Fire();
- EXPECT_FALSE(connection_.GetTimeoutAlarm()->IsSet());
- EXPECT_FALSE(connection_.connected());
- EXPECT_EQ(1, connection_close_frame_count_);
- EXPECT_THAT(saved_connection_close_frame_.quic_error_code,
- 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.
- 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());
-
- if (connection_.version().UsesTls()) {
- QuicConfigPeer::SetReceivedOriginalConnectionId(
- &config, connection_.connection_id());
- QuicConfigPeer::SetReceivedInitialSourceConnectionId(
- &config, connection_.connection_id());
- }
- 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());
-
- // Indicate streams are still open.
- EXPECT_CALL(visitor_, ShouldKeepConnectionAlive())
- .WillRepeatedly(Return(true));
- if (GetQuicReloadableFlag(quic_add_stream_info_to_idle_close_detail)) {
- EXPECT_CALL(visitor_, GetStreamsInfoForLogging()).WillOnce(Return(""));
- }
-
- // 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, TimeoutAfterReceive) {
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- EXPECT_TRUE(connection_.connected());
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
- QuicConfig config;
- connection_.SetFromConfig(config);
-
- const QuicTime::Delta initial_idle_timeout =
- QuicTime::Delta::FromSeconds(kInitialIdleTimeoutSecs - 1);
- const QuicTime::Delta five_ms = QuicTime::Delta::FromMilliseconds(5);
- QuicTime default_timeout = clock_.ApproximateNow() + initial_idle_timeout;
-
- connection_.SendStreamDataWithString(
- GetNthClientInitiatedStreamId(1, connection_.transport_version()), "foo",
- 0, NO_FIN);
- connection_.SendStreamDataWithString(
- GetNthClientInitiatedStreamId(1, connection_.transport_version()), "foo",
- 3, NO_FIN);
-
- EXPECT_EQ(default_timeout, connection_.GetTimeoutAlarm()->deadline());
- clock_.AdvanceTime(five_ms);
-
- // When we receive a packet, the timeout will change to 5ms +
- // kInitialIdleTimeoutSecs.
- QuicAckFrame ack = InitAckFrame(2);
- EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
- ProcessAckPacket(&ack);
-
- // The original alarm will fire. We should not time out because we had a
- // network event at t=5ms. The alarm will reregister.
- clock_.AdvanceTime(initial_idle_timeout - five_ms);
- EXPECT_EQ(default_timeout, clock_.ApproximateNow());
- EXPECT_TRUE(connection_.connected());
- EXPECT_TRUE(connection_.GetTimeoutAlarm()->IsSet());
- EXPECT_EQ(default_timeout + five_ms,
- connection_.GetTimeoutAlarm()->deadline());
-
- // This time, we should time out.
- EXPECT_CALL(visitor_,
- OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF));
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AtLeast(1));
- clock_.AdvanceTime(five_ms);
- EXPECT_EQ(default_timeout + five_ms, clock_.ApproximateNow());
- connection_.GetTimeoutAlarm()->Fire();
- EXPECT_FALSE(connection_.GetTimeoutAlarm()->IsSet());
- EXPECT_FALSE(connection_.connected());
- TestConnectionCloseQuicErrorCode(QUIC_NETWORK_IDLE_TIMEOUT);
-}
-
-TEST_P(QuicConnectionTest, TimeoutAfterReceiveNotSendWhenUnacked) {
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- EXPECT_TRUE(connection_.connected());
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
- QuicConfig config;
- connection_.SetFromConfig(config);
-
- const QuicTime::Delta initial_idle_timeout =
- QuicTime::Delta::FromSeconds(kInitialIdleTimeoutSecs - 1);
- connection_.SetNetworkTimeouts(
- QuicTime::Delta::Infinite(),
- initial_idle_timeout + QuicTime::Delta::FromSeconds(1));
- const QuicTime::Delta five_ms = QuicTime::Delta::FromMilliseconds(5);
- QuicTime default_timeout = clock_.ApproximateNow() + initial_idle_timeout;
-
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _));
- connection_.SendStreamDataWithString(
- GetNthClientInitiatedStreamId(1, connection_.transport_version()), "foo",
- 0, NO_FIN);
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _));
- connection_.SendStreamDataWithString(
- GetNthClientInitiatedStreamId(1, connection_.transport_version()), "foo",
- 3, NO_FIN);
-
- EXPECT_EQ(default_timeout, connection_.GetTimeoutAlarm()->deadline());
-
- clock_.AdvanceTime(five_ms);
-
- // When we receive a packet, the timeout will change to 5ms +
- // kInitialIdleTimeoutSecs.
- QuicAckFrame ack = InitAckFrame(2);
- EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
- ProcessAckPacket(&ack);
-
- // The original alarm will fire. We should not time out because we had a
- // network event at t=5ms. The alarm will reregister.
- clock_.AdvanceTime(initial_idle_timeout - five_ms);
- EXPECT_EQ(default_timeout, clock_.ApproximateNow());
- EXPECT_TRUE(connection_.connected());
- EXPECT_TRUE(connection_.GetTimeoutAlarm()->IsSet());
- EXPECT_EQ(default_timeout + five_ms,
- connection_.GetTimeoutAlarm()->deadline());
-
- // Now, send packets while advancing the time and verify that the connection
- // eventually times out.
- EXPECT_CALL(visitor_,
- OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF));
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AnyNumber());
- for (int i = 0; i < 100 && connection_.connected(); ++i) {
- QUIC_LOG(INFO) << "sending data packet";
- connection_.SendStreamDataWithString(
- GetNthClientInitiatedStreamId(1, connection_.transport_version()),
- "foo", 0, NO_FIN);
- connection_.GetTimeoutAlarm()->Fire();
- clock_.AdvanceTime(QuicTime::Delta::FromSeconds(1));
- }
- EXPECT_FALSE(connection_.connected());
- EXPECT_FALSE(connection_.GetTimeoutAlarm()->IsSet());
- 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);
- std::unique_ptr<QuicPacket> packet =
- ConstructDataPacket(1, !kHasStopWaiting, ENCRYPTION_INITIAL);
- QuicPacketCreatorPeer::SetPacketNumber(creator_, 1);
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _));
- connection_.SendPacket(ENCRYPTION_INITIAL, 1, std::move(packet),
- HAS_RETRANSMITTABLE_DATA, false, false);
- EXPECT_EQ(0u, connection_.NumQueuedPackets());
-}
-
-TEST_P(QuicConnectionTest, FailToSendFirstPacket) {
- // Test that the connection does not crash when it fails to send the first
- // packet at which point self_address_ might be uninitialized.
- QuicFramerPeer::SetPerspective(&peer_framer_, Perspective::IS_CLIENT);
- EXPECT_CALL(visitor_, OnConnectionClosed(_, _)).Times(1);
- std::unique_ptr<QuicPacket> packet =
- ConstructDataPacket(1, !kHasStopWaiting, ENCRYPTION_INITIAL);
- QuicPacketCreatorPeer::SetPacketNumber(creator_, 1);
- writer_->SetShouldWriteFail();
- connection_.SendPacket(ENCRYPTION_INITIAL, 1, std::move(packet),
- HAS_RETRANSMITTABLE_DATA, false, false);
-}
-
-TEST_P(QuicConnectionTest, SendSchedulerEAGAIN) {
- QuicFramerPeer::SetPerspective(&peer_framer_, Perspective::IS_CLIENT);
- std::unique_ptr<QuicPacket> packet =
- ConstructDataPacket(1, !kHasStopWaiting, ENCRYPTION_INITIAL);
- QuicPacketCreatorPeer::SetPacketNumber(creator_, 1);
- BlockOnNextWrite();
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, QuicPacketNumber(2u), _, _))
- .Times(0);
- connection_.SendPacket(ENCRYPTION_INITIAL, 1, std::move(packet),
- HAS_RETRANSMITTABLE_DATA, false, false);
- EXPECT_EQ(1u, connection_.NumQueuedPackets());
-}
-
-TEST_P(QuicConnectionTest, TestQueueLimitsOnSendStreamData) {
- // Queue the first packet.
- size_t payload_length = connection_.max_packet_length();
- EXPECT_CALL(*send_algorithm_, CanSend(_)).WillOnce(testing::Return(false));
- const std::string payload(payload_length, 'a');
- QuicStreamId first_bidi_stream_id(QuicUtils::GetFirstBidirectionalStreamId(
- connection_.version().transport_version, Perspective::IS_CLIENT));
- EXPECT_EQ(0u, connection_
- .SendStreamDataWithString(first_bidi_stream_id, payload, 0,
- NO_FIN)
- .bytes_consumed);
- EXPECT_EQ(0u, connection_.NumQueuedPackets());
-}
-
-TEST_P(QuicConnectionTest, SendingThreePackets) {
- // Make the payload twice the size of the packet, so 3 packets are written.
- size_t total_payload_length = 2 * connection_.max_packet_length();
- const std::string payload(total_payload_length, 'a');
- QuicStreamId first_bidi_stream_id(QuicUtils::GetFirstBidirectionalStreamId(
- connection_.version().transport_version, Perspective::IS_CLIENT));
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(3);
- EXPECT_EQ(payload.size(), connection_
- .SendStreamDataWithString(first_bidi_stream_id,
- payload, 0, NO_FIN)
- .bytes_consumed);
-}
-
-TEST_P(QuicConnectionTest, LoopThroughSendingPacketsWithTruncation) {
- set_perspective(Perspective::IS_SERVER);
- if (!GetParam().version.HasIetfInvariantHeader()) {
- // For IETF QUIC, encryption level will be switched to FORWARD_SECURE in
- // SendStreamDataWithString.
- QuicPacketCreatorPeer::SetSendVersionInPacket(creator_, false);
- }
- // Set up a larger payload than will fit in one packet.
- const std::string payload(connection_.max_packet_length(), 'a');
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _)).Times(AnyNumber());
-
- // Now send some packets with no truncation.
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(2);
- EXPECT_EQ(payload.size(),
- connection_.SendStreamDataWithString(3, payload, 0, NO_FIN)
- .bytes_consumed);
- // Track the size of the second packet here. The overhead will be the largest
- // we see in this test, due to the non-truncated connection id.
- size_t non_truncated_packet_size = writer_->last_packet_size();
-
- // Change to a 0 byte connection id.
- QuicConfig config;
- QuicConfigPeer::SetReceivedBytesForConnectionId(&config, 0);
- connection_.SetFromConfig(config);
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(2);
- EXPECT_EQ(payload.size(),
- connection_.SendStreamDataWithString(3, payload, 1350, NO_FIN)
- .bytes_consumed);
- if (connection_.version().HasIetfInvariantHeader()) {
- // Short header packets sent from server omit connection ID already, and
- // stream offset size increases from 0 to 2.
- EXPECT_EQ(non_truncated_packet_size, writer_->last_packet_size() - 2);
- } else {
- // Just like above, we save 8 bytes on payload, and 8 on truncation. -2
- // because stream offset size is 2 instead of 0.
- EXPECT_EQ(non_truncated_packet_size,
- writer_->last_packet_size() + 8 * 2 - 2);
- }
-}
-
-TEST_P(QuicConnectionTest, SendDelayedAck) {
- QuicTime ack_time = clock_.ApproximateNow() + DefaultDelayedAckTime();
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- EXPECT_FALSE(connection_.HasPendingAcks());
- const uint8_t tag = 0x07;
- SetDecrypter(ENCRYPTION_ZERO_RTT,
- std::make_unique<StrictTaggingDecrypter>(tag));
- peer_framer_.SetEncrypter(ENCRYPTION_ZERO_RTT,
- std::make_unique<TaggingEncrypter>(tag));
- // Process a packet from the non-crypto stream.
- frame1_.stream_id = 3;
-
- // The same as ProcessPacket(1) except that ENCRYPTION_ZERO_RTT is used
- // instead of ENCRYPTION_INITIAL.
- EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
- ProcessDataPacketAtLevel(1, !kHasStopWaiting, ENCRYPTION_ZERO_RTT);
-
- // Check if delayed ack timer is running for the expected interval.
- EXPECT_TRUE(connection_.HasPendingAcks());
- EXPECT_EQ(ack_time, connection_.GetAckAlarm()->deadline());
- // Simulate delayed ack alarm firing.
- clock_.AdvanceTime(DefaultDelayedAckTime());
- connection_.GetAckAlarm()->Fire();
- // Check that ack is sent and that delayed ack alarm is reset.
- size_t padding_frame_count = writer_->padding_frames().size();
- if (GetParam().no_stop_waiting) {
- EXPECT_EQ(padding_frame_count + 1u, writer_->frame_count());
- EXPECT_TRUE(writer_->stop_waiting_frames().empty());
- } else {
- EXPECT_EQ(padding_frame_count + 2u, writer_->frame_count());
- EXPECT_FALSE(writer_->stop_waiting_frames().empty());
- }
- EXPECT_FALSE(writer_->ack_frames().empty());
- EXPECT_FALSE(connection_.HasPendingAcks());
-}
-
-TEST_P(QuicConnectionTest, SendDelayedAckDecimation) {
- EXPECT_CALL(visitor_, OnAckNeedsRetransmittableFrame()).Times(AnyNumber());
-
- const size_t kMinRttMs = 40;
- RttStats* rtt_stats = const_cast<RttStats*>(manager_->GetRttStats());
- rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(kMinRttMs),
- QuicTime::Delta::Zero(), QuicTime::Zero());
- // The ack time should be based on min_rtt/4, since it's less than the
- // default delayed ack time.
- QuicTime ack_time = clock_.ApproximateNow() +
- QuicTime::Delta::FromMilliseconds(kMinRttMs / 4);
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- EXPECT_FALSE(connection_.HasPendingAcks());
- const uint8_t tag = 0x07;
- SetDecrypter(ENCRYPTION_ZERO_RTT,
- std::make_unique<StrictTaggingDecrypter>(tag));
- peer_framer_.SetEncrypter(ENCRYPTION_ZERO_RTT,
- std::make_unique<TaggingEncrypter>(tag));
- // Process a packet from the non-crypto stream.
- frame1_.stream_id = 3;
-
- // Process all the initial packets in order so there aren't missing packets.
- uint64_t kFirstDecimatedPacket = 101;
- for (unsigned int i = 0; i < kFirstDecimatedPacket - 1; ++i) {
- EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
- ProcessDataPacketAtLevel(1 + i, !kHasStopWaiting, ENCRYPTION_ZERO_RTT);
- }
- EXPECT_FALSE(connection_.HasPendingAcks());
- // The same as ProcessPacket(1) except that ENCRYPTION_ZERO_RTT is used
- // instead of ENCRYPTION_INITIAL.
- EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
- ProcessDataPacketAtLevel(kFirstDecimatedPacket, !kHasStopWaiting,
- ENCRYPTION_ZERO_RTT);
-
- // Check if delayed ack timer is running for the expected interval.
- EXPECT_TRUE(connection_.HasPendingAcks());
- EXPECT_EQ(ack_time, connection_.GetAckAlarm()->deadline());
-
- // The 10th received packet causes an ack to be sent.
- for (int i = 0; i < 9; ++i) {
- EXPECT_TRUE(connection_.HasPendingAcks());
- EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
- ProcessDataPacketAtLevel(kFirstDecimatedPacket + 1 + i, !kHasStopWaiting,
- ENCRYPTION_ZERO_RTT);
- }
- // Check that ack is sent and that delayed ack alarm is reset.
- size_t padding_frame_count = writer_->padding_frames().size();
- if (GetParam().no_stop_waiting) {
- EXPECT_EQ(padding_frame_count + 1u, writer_->frame_count());
- EXPECT_TRUE(writer_->stop_waiting_frames().empty());
- } else {
- EXPECT_EQ(padding_frame_count + 2u, writer_->frame_count());
- EXPECT_FALSE(writer_->stop_waiting_frames().empty());
- }
- EXPECT_FALSE(writer_->ack_frames().empty());
- EXPECT_FALSE(connection_.HasPendingAcks());
-}
-
-TEST_P(QuicConnectionTest, SendDelayedAckDecimationUnlimitedAggregation) {
- EXPECT_CALL(visitor_, OnAckNeedsRetransmittableFrame()).Times(AnyNumber());
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
- QuicConfig config;
- QuicTagVector connection_options;
- // No limit on the number of packets received before sending an ack.
- connection_options.push_back(kAKDU);
- config.SetConnectionOptionsToSend(connection_options);
- connection_.SetFromConfig(config);
-
- const size_t kMinRttMs = 40;
- RttStats* rtt_stats = const_cast<RttStats*>(manager_->GetRttStats());
- rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(kMinRttMs),
- QuicTime::Delta::Zero(), QuicTime::Zero());
- // The ack time should be based on min_rtt/4, since it's less than the
- // default delayed ack time.
- QuicTime ack_time = clock_.ApproximateNow() +
- QuicTime::Delta::FromMilliseconds(kMinRttMs / 4);
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- EXPECT_FALSE(connection_.HasPendingAcks());
- const uint8_t tag = 0x07;
- SetDecrypter(ENCRYPTION_ZERO_RTT,
- std::make_unique<StrictTaggingDecrypter>(tag));
- peer_framer_.SetEncrypter(ENCRYPTION_ZERO_RTT,
- std::make_unique<TaggingEncrypter>(tag));
- // Process a packet from the non-crypto stream.
- frame1_.stream_id = 3;
-
- // Process all the initial packets in order so there aren't missing packets.
- uint64_t kFirstDecimatedPacket = 101;
- for (unsigned int i = 0; i < kFirstDecimatedPacket - 1; ++i) {
- EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
- ProcessDataPacketAtLevel(1 + i, !kHasStopWaiting, ENCRYPTION_ZERO_RTT);
- }
- EXPECT_FALSE(connection_.HasPendingAcks());
- // The same as ProcessPacket(1) except that ENCRYPTION_ZERO_RTT is used
- // instead of ENCRYPTION_INITIAL.
- EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
- ProcessDataPacketAtLevel(kFirstDecimatedPacket, !kHasStopWaiting,
- ENCRYPTION_ZERO_RTT);
-
- // Check if delayed ack timer is running for the expected interval.
- EXPECT_TRUE(connection_.HasPendingAcks());
- EXPECT_EQ(ack_time, connection_.GetAckAlarm()->deadline());
-
- // 18 packets will not cause an ack to be sent. 19 will because when
- // stop waiting frames are in use, we ack every 20 packets no matter what.
- for (int i = 0; i < 18; ++i) {
- EXPECT_TRUE(connection_.HasPendingAcks());
- EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
- ProcessDataPacketAtLevel(kFirstDecimatedPacket + 1 + i, !kHasStopWaiting,
- ENCRYPTION_ZERO_RTT);
- }
- // The delayed ack timer should still be set to the expected deadline.
- EXPECT_TRUE(connection_.HasPendingAcks());
- EXPECT_EQ(ack_time, connection_.GetAckAlarm()->deadline());
-}
-
-TEST_P(QuicConnectionTest, SendDelayedAckDecimationEighthRtt) {
- EXPECT_CALL(visitor_, OnAckNeedsRetransmittableFrame()).Times(AnyNumber());
- QuicConnectionPeer::SetAckDecimationDelay(&connection_, 0.125);
-
- const size_t kMinRttMs = 40;
- RttStats* rtt_stats = const_cast<RttStats*>(manager_->GetRttStats());
- rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(kMinRttMs),
- QuicTime::Delta::Zero(), QuicTime::Zero());
- // The ack time should be based on min_rtt/8, since it's less than the
- // default delayed ack time.
- QuicTime ack_time = clock_.ApproximateNow() +
- QuicTime::Delta::FromMilliseconds(kMinRttMs / 8);
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- EXPECT_FALSE(connection_.HasPendingAcks());
- const uint8_t tag = 0x07;
- SetDecrypter(ENCRYPTION_ZERO_RTT,
- std::make_unique<StrictTaggingDecrypter>(tag));
- peer_framer_.SetEncrypter(ENCRYPTION_ZERO_RTT,
- std::make_unique<TaggingEncrypter>(tag));
- // Process a packet from the non-crypto stream.
- frame1_.stream_id = 3;
-
- // Process all the initial packets in order so there aren't missing packets.
- uint64_t kFirstDecimatedPacket = 101;
- for (unsigned int i = 0; i < kFirstDecimatedPacket - 1; ++i) {
- EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
- ProcessDataPacketAtLevel(1 + i, !kHasStopWaiting, ENCRYPTION_ZERO_RTT);
- }
- EXPECT_FALSE(connection_.HasPendingAcks());
- // The same as ProcessPacket(1) except that ENCRYPTION_ZERO_RTT is used
- // instead of ENCRYPTION_INITIAL.
- EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
- ProcessDataPacketAtLevel(kFirstDecimatedPacket, !kHasStopWaiting,
- ENCRYPTION_ZERO_RTT);
-
- // Check if delayed ack timer is running for the expected interval.
- EXPECT_TRUE(connection_.HasPendingAcks());
- EXPECT_EQ(ack_time, connection_.GetAckAlarm()->deadline());
-
- // The 10th received packet causes an ack to be sent.
- for (int i = 0; i < 9; ++i) {
- EXPECT_TRUE(connection_.HasPendingAcks());
- EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
- ProcessDataPacketAtLevel(kFirstDecimatedPacket + 1 + i, !kHasStopWaiting,
- ENCRYPTION_ZERO_RTT);
- }
- // Check that ack is sent and that delayed ack alarm is reset.
- size_t padding_frame_count = writer_->padding_frames().size();
- if (GetParam().no_stop_waiting) {
- EXPECT_EQ(padding_frame_count + 1u, writer_->frame_count());
- EXPECT_TRUE(writer_->stop_waiting_frames().empty());
- } else {
- EXPECT_EQ(padding_frame_count + 2u, writer_->frame_count());
- EXPECT_FALSE(writer_->stop_waiting_frames().empty());
- }
- EXPECT_FALSE(writer_->ack_frames().empty());
- EXPECT_FALSE(connection_.HasPendingAcks());
-}
-
-TEST_P(QuicConnectionTest, SendDelayedAckOnHandshakeConfirmed) {
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- ProcessPacket(1);
- // Check that ack is sent and that delayed ack alarm is set.
- EXPECT_TRUE(connection_.HasPendingAcks());
- QuicTime ack_time = clock_.ApproximateNow() + DefaultDelayedAckTime();
- EXPECT_EQ(ack_time, connection_.GetAckAlarm()->deadline());
-
- // Completing the handshake as the server does nothing.
- QuicConnectionPeer::SetPerspective(&connection_, Perspective::IS_SERVER);
- connection_.OnHandshakeComplete();
- EXPECT_TRUE(connection_.HasPendingAcks());
- EXPECT_EQ(ack_time, connection_.GetAckAlarm()->deadline());
-
- // Complete the handshake as the client decreases the delayed ack time to 0ms.
- QuicConnectionPeer::SetPerspective(&connection_, Perspective::IS_CLIENT);
- connection_.OnHandshakeComplete();
- EXPECT_TRUE(connection_.HasPendingAcks());
- if (connection_.SupportsMultiplePacketNumberSpaces()) {
- EXPECT_EQ(clock_.ApproximateNow() + DefaultDelayedAckTime(),
- connection_.GetAckAlarm()->deadline());
- } else {
- EXPECT_EQ(clock_.ApproximateNow(), connection_.GetAckAlarm()->deadline());
- }
-}
-
-TEST_P(QuicConnectionTest, SendDelayedAckOnSecondPacket) {
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- ProcessPacket(1);
- ProcessPacket(2);
- // Check that ack is sent and that delayed ack alarm is reset.
- size_t padding_frame_count = writer_->padding_frames().size();
- if (GetParam().no_stop_waiting) {
- EXPECT_EQ(padding_frame_count + 1u, writer_->frame_count());
- EXPECT_TRUE(writer_->stop_waiting_frames().empty());
- } else {
- EXPECT_EQ(padding_frame_count + 2u, writer_->frame_count());
- EXPECT_FALSE(writer_->stop_waiting_frames().empty());
- }
- EXPECT_FALSE(writer_->ack_frames().empty());
- EXPECT_FALSE(connection_.HasPendingAcks());
-}
-
-TEST_P(QuicConnectionTest, NoAckOnOldNacks) {
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
- ProcessPacket(2);
- size_t frames_per_ack = GetParam().no_stop_waiting ? 1 : 2;
-
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
- ProcessPacket(3);
- size_t padding_frame_count = writer_->padding_frames().size();
- EXPECT_EQ(padding_frame_count + frames_per_ack, writer_->frame_count());
- EXPECT_FALSE(writer_->ack_frames().empty());
- writer_->Reset();
-
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
- ProcessPacket(4);
- EXPECT_EQ(0u, writer_->frame_count());
-
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
- ProcessPacket(5);
- padding_frame_count = writer_->padding_frames().size();
- EXPECT_EQ(padding_frame_count + frames_per_ack, writer_->frame_count());
- EXPECT_FALSE(writer_->ack_frames().empty());
- writer_->Reset();
-
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
- // Now only set the timer on the 6th packet, instead of sending another ack.
- ProcessPacket(6);
- padding_frame_count = writer_->padding_frames().size();
- EXPECT_EQ(padding_frame_count, writer_->frame_count());
- EXPECT_TRUE(connection_.HasPendingAcks());
-}
-
-TEST_P(QuicConnectionTest, SendDelayedAckOnOutgoingPacket) {
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- EXPECT_CALL(visitor_, OnStreamFrame(_));
- peer_framer_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
- std::make_unique<TaggingEncrypter>(0x01));
- SetDecrypter(ENCRYPTION_FORWARD_SECURE,
- std::make_unique<StrictTaggingDecrypter>(0x01));
- ProcessDataPacket(1);
- connection_.SendStreamDataWithString(
- GetNthClientInitiatedStreamId(1, connection_.transport_version()), "foo",
- 0, NO_FIN);
- // Check that ack is bundled with outgoing data and that delayed ack
- // alarm is reset.
- if (GetParam().no_stop_waiting) {
- EXPECT_EQ(2u, writer_->frame_count());
- EXPECT_TRUE(writer_->stop_waiting_frames().empty());
- } else {
- EXPECT_EQ(3u, writer_->frame_count());
- EXPECT_FALSE(writer_->stop_waiting_frames().empty());
- }
- EXPECT_FALSE(writer_->ack_frames().empty());
- EXPECT_FALSE(connection_.HasPendingAcks());
-}
-
-TEST_P(QuicConnectionTest, SendDelayedAckOnOutgoingCryptoPacket) {
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
- EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(1);
- } else {
- EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
- }
- ProcessCryptoPacketAtLevel(1, ENCRYPTION_INITIAL);
- connection_.SendCryptoDataWithString("foo", 0);
- // Check that ack is bundled with outgoing crypto data.
- if (GetParam().no_stop_waiting) {
- EXPECT_EQ(3u, writer_->frame_count());
- EXPECT_TRUE(writer_->stop_waiting_frames().empty());
- } else {
- EXPECT_EQ(4u, writer_->frame_count());
- EXPECT_FALSE(writer_->stop_waiting_frames().empty());
- }
- EXPECT_FALSE(connection_.HasPendingAcks());
-}
-
-TEST_P(QuicConnectionTest, BlockAndBufferOnFirstCHLOPacketOfTwo) {
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- ProcessPacket(1);
- BlockOnNextWrite();
- writer_->set_is_write_blocked_data_buffered(true);
- if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
- } else {
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(2);
- }
- connection_.SendCryptoDataWithString("foo", 0);
- EXPECT_TRUE(writer_->IsWriteBlocked());
- EXPECT_FALSE(connection_.HasQueuedData());
- connection_.SendCryptoDataWithString("bar", 3);
- EXPECT_TRUE(writer_->IsWriteBlocked());
- if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
- // CRYPTO frames are not flushed when writer is blocked.
- EXPECT_FALSE(connection_.HasQueuedData());
- } else {
- EXPECT_TRUE(connection_.HasQueuedData());
- }
-}
-
-TEST_P(QuicConnectionTest, BundleAckForSecondCHLO) {
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- EXPECT_FALSE(connection_.HasPendingAcks());
- EXPECT_CALL(visitor_, OnCanWrite())
- .WillOnce(IgnoreResult(InvokeWithoutArgs(
- &connection_, &TestConnection::SendCryptoStreamData)));
- // Process a packet from the crypto stream, which is frame1_'s default.
- // Receiving the CHLO as packet 2 first will cause the connection to
- // immediately send an ack, due to the packet gap.
- if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
- EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(1);
- } else {
- EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
- }
- ProcessCryptoPacketAtLevel(2, ENCRYPTION_INITIAL);
- // Check that ack is sent and that delayed ack alarm is reset.
- if (GetParam().no_stop_waiting) {
- EXPECT_EQ(3u, writer_->frame_count());
- EXPECT_TRUE(writer_->stop_waiting_frames().empty());
- } else {
- EXPECT_EQ(4u, writer_->frame_count());
- EXPECT_FALSE(writer_->stop_waiting_frames().empty());
- }
- if (!QuicVersionUsesCryptoFrames(connection_.transport_version())) {
- EXPECT_EQ(1u, writer_->stream_frames().size());
- } else {
- EXPECT_EQ(1u, writer_->crypto_frames().size());
- }
- EXPECT_EQ(1u, writer_->padding_frames().size());
- ASSERT_FALSE(writer_->ack_frames().empty());
- EXPECT_EQ(QuicPacketNumber(2u), LargestAcked(writer_->ack_frames().front()));
- EXPECT_FALSE(connection_.HasPendingAcks());
-}
-
-TEST_P(QuicConnectionTest, BundleAckForSecondCHLOTwoPacketReject) {
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- EXPECT_FALSE(connection_.HasPendingAcks());
-
- // Process two packets from the crypto stream, which is frame1_'s default,
- // simulating a 2 packet reject.
- {
- if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
- EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(1);
- } else {
- EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
- }
- ProcessCryptoPacketAtLevel(1, ENCRYPTION_INITIAL);
- // Send the new CHLO when the REJ is processed.
- if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
- EXPECT_CALL(visitor_, OnCryptoFrame(_))
- .WillOnce(IgnoreResult(InvokeWithoutArgs(
- &connection_, &TestConnection::SendCryptoStreamData)));
- } else {
- EXPECT_CALL(visitor_, OnStreamFrame(_))
- .WillOnce(IgnoreResult(InvokeWithoutArgs(
- &connection_, &TestConnection::SendCryptoStreamData)));
- }
- ProcessCryptoPacketAtLevel(2, ENCRYPTION_INITIAL);
- }
- // Check that ack is sent and that delayed ack alarm is reset.
- if (GetParam().no_stop_waiting) {
- EXPECT_EQ(3u, writer_->frame_count());
- EXPECT_TRUE(writer_->stop_waiting_frames().empty());
- } else {
- EXPECT_EQ(4u, writer_->frame_count());
- EXPECT_FALSE(writer_->stop_waiting_frames().empty());
- }
- if (!QuicVersionUsesCryptoFrames(connection_.transport_version())) {
- EXPECT_EQ(1u, writer_->stream_frames().size());
- } else {
- EXPECT_EQ(1u, writer_->crypto_frames().size());
- }
- EXPECT_EQ(1u, writer_->padding_frames().size());
- ASSERT_FALSE(writer_->ack_frames().empty());
- EXPECT_EQ(QuicPacketNumber(2u), LargestAcked(writer_->ack_frames().front()));
- EXPECT_FALSE(connection_.HasPendingAcks());
-}
-
-TEST_P(QuicConnectionTest, BundleAckWithDataOnIncomingAck) {
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- connection_.SendStreamDataWithString(
- GetNthClientInitiatedStreamId(1, connection_.transport_version()), "foo",
- 0, NO_FIN);
- connection_.SendStreamDataWithString(
- GetNthClientInitiatedStreamId(1, connection_.transport_version()), "foo",
- 3, NO_FIN);
- // Ack the second packet, which will retransmit the first packet.
- QuicAckFrame ack = ConstructAckFrame(2, 1);
- LostPacketVector lost_packets;
- lost_packets.push_back(
- LostPacket(QuicPacketNumber(1), kMaxOutgoingPacketSize));
- EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _))
- .WillOnce(DoAll(SetArgPointee<5>(lost_packets),
- Return(LossDetectionInterface::DetectionStats())));
- EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
- ProcessAckPacket(&ack);
- size_t padding_frame_count = writer_->padding_frames().size();
- EXPECT_EQ(padding_frame_count + 1u, writer_->frame_count());
- EXPECT_EQ(1u, writer_->stream_frames().size());
- writer_->Reset();
-
- // Now ack the retransmission, which will both raise the high water mark
- // and see if there is more data to send.
- ack = ConstructAckFrame(3, 1);
- EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _));
- EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
- ProcessAckPacket(&ack);
-
- // Check that no packet is sent and the ack alarm isn't set.
- EXPECT_EQ(0u, writer_->frame_count());
- EXPECT_FALSE(connection_.HasPendingAcks());
- writer_->Reset();
-
- // Send the same ack, but send both data and an ack together.
- ack = ConstructAckFrame(3, 1);
- EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _));
- EXPECT_CALL(visitor_, OnCanWrite())
- .WillOnce(IgnoreResult(InvokeWithoutArgs(
- &connection_, &TestConnection::EnsureWritableAndSendStreamData5)));
- ProcessAckPacket(&ack);
-
- // Check that ack is bundled with outgoing data and the delayed ack
- // alarm is reset.
- if (GetParam().no_stop_waiting) {
- // Do not ACK acks.
- EXPECT_EQ(1u, writer_->frame_count());
- } else {
- EXPECT_EQ(3u, writer_->frame_count());
- EXPECT_FALSE(writer_->stop_waiting_frames().empty());
- }
- if (GetParam().no_stop_waiting) {
- EXPECT_TRUE(writer_->ack_frames().empty());
- } else {
- EXPECT_FALSE(writer_->ack_frames().empty());
- EXPECT_EQ(QuicPacketNumber(3u),
- LargestAcked(writer_->ack_frames().front()));
- }
- EXPECT_EQ(1u, writer_->stream_frames().size());
- EXPECT_FALSE(connection_.HasPendingAcks());
-}
-
-TEST_P(QuicConnectionTest, NoAckSentForClose) {
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- ProcessPacket(1);
- EXPECT_CALL(visitor_, OnConnectionClosed(_, ConnectionCloseSource::FROM_PEER))
- .WillOnce(Invoke(this, &QuicConnectionTest::SaveConnectionCloseFrame));
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
- ProcessClosePacket(2);
- EXPECT_EQ(1, connection_close_frame_count_);
- EXPECT_THAT(saved_connection_close_frame_.quic_error_code,
- IsError(QUIC_PEER_GOING_AWAY));
-}
-
-TEST_P(QuicConnectionTest, SendWhenDisconnected) {
- EXPECT_TRUE(connection_.connected());
- EXPECT_CALL(visitor_, OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF))
- .WillOnce(Invoke(this, &QuicConnectionTest::SaveConnectionCloseFrame));
- connection_.CloseConnection(QUIC_PEER_GOING_AWAY, "no reason",
- ConnectionCloseBehavior::SILENT_CLOSE);
- EXPECT_FALSE(connection_.connected());
- EXPECT_FALSE(connection_.CanWrite(HAS_RETRANSMITTABLE_DATA));
- EXPECT_EQ(DISCARD, connection_.GetSerializedPacketFate(
- /*is_mtu_discovery=*/false, ENCRYPTION_INITIAL));
-}
-
-TEST_P(QuicConnectionTest, SendConnectivityProbingWhenDisconnected) {
- // EXPECT_QUIC_BUG tests are expensive so only run one instance of them.
- if (!IsDefaultTestConfiguration()) {
- return;
- }
-
- EXPECT_TRUE(connection_.connected());
- EXPECT_CALL(visitor_, OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF))
- .WillOnce(Invoke(this, &QuicConnectionTest::SaveConnectionCloseFrame));
- connection_.CloseConnection(QUIC_PEER_GOING_AWAY, "no reason",
- ConnectionCloseBehavior::SILENT_CLOSE);
- EXPECT_FALSE(connection_.connected());
- EXPECT_FALSE(connection_.CanWrite(HAS_RETRANSMITTABLE_DATA));
-
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, QuicPacketNumber(1), _, _))
- .Times(0);
-
- EXPECT_QUIC_BUG(connection_.SendConnectivityProbingPacket(
- writer_.get(), connection_.peer_address()),
- "Not sending connectivity probing packet as connection is "
- "disconnected.");
- EXPECT_EQ(1, connection_close_frame_count_);
- EXPECT_THAT(saved_connection_close_frame_.quic_error_code,
- IsError(QUIC_PEER_GOING_AWAY));
-}
-
-TEST_P(QuicConnectionTest, WriteBlockedAfterClientSendsConnectivityProbe) {
- PathProbeTestInit(Perspective::IS_CLIENT);
- TestPacketWriter probing_writer(version(), &clock_, Perspective::IS_CLIENT);
- // Block next write so that sending connectivity probe will encounter a
- // blocked write when send a connectivity probe to the peer.
- probing_writer.BlockOnNextWrite();
- // Connection will not be marked as write blocked as connectivity probe only
- // affects the probing_writer which is not the default.
- EXPECT_CALL(visitor_, OnWriteBlocked()).Times(0);
-
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, QuicPacketNumber(1), _, _))
- .Times(1);
- connection_.SendConnectivityProbingPacket(&probing_writer,
- connection_.peer_address());
-}
-
-TEST_P(QuicConnectionTest, WriterBlockedAfterServerSendsConnectivityProbe) {
- PathProbeTestInit(Perspective::IS_SERVER);
- if (version().SupportsAntiAmplificationLimit()) {
- QuicConnectionPeer::SetAddressValidated(&connection_);
- }
-
- // Block next write so that sending connectivity probe will encounter a
- // blocked write when send a connectivity probe to the peer.
- writer_->BlockOnNextWrite();
- // Connection will be marked as write blocked as server uses the default
- // writer to send connectivity probes.
- EXPECT_CALL(visitor_, OnWriteBlocked()).Times(1);
-
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, QuicPacketNumber(1), _, _))
- .Times(1);
- if (connection_.send_path_response() &&
- VersionHasIetfQuicFrames(GetParam().version.transport_version)) {
- QuicPathFrameBuffer payload{
- {0xde, 0xad, 0xbe, 0xef, 0xba, 0xdc, 0x0f, 0xfe}};
- QuicConnection::ScopedPacketFlusher flusher(&connection_);
- connection_.SendPathChallenge(
- payload, connection_.self_address(), connection_.peer_address(),
- connection_.effective_peer_address(), writer_.get());
- } else {
- connection_.SendConnectivityProbingPacket(writer_.get(),
- connection_.peer_address());
- }
-}
-
-TEST_P(QuicConnectionTest, WriterErrorWhenClientSendsConnectivityProbe) {
- PathProbeTestInit(Perspective::IS_CLIENT);
- TestPacketWriter probing_writer(version(), &clock_, Perspective::IS_CLIENT);
- probing_writer.SetShouldWriteFail();
-
- // Connection should not be closed if a connectivity probe is failed to be
- // sent.
- EXPECT_CALL(visitor_, OnConnectionClosed(_, _)).Times(0);
-
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, QuicPacketNumber(1), _, _))
- .Times(0);
- connection_.SendConnectivityProbingPacket(&probing_writer,
- connection_.peer_address());
-}
-
-TEST_P(QuicConnectionTest, WriterErrorWhenServerSendsConnectivityProbe) {
- PathProbeTestInit(Perspective::IS_SERVER);
-
- writer_->SetShouldWriteFail();
- // Connection should not be closed if a connectivity probe is failed to be
- // sent.
- EXPECT_CALL(visitor_, OnConnectionClosed(_, _)).Times(0);
-
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, QuicPacketNumber(1), _, _))
- .Times(0);
- connection_.SendConnectivityProbingPacket(writer_.get(),
- connection_.peer_address());
-}
-
-TEST_P(QuicConnectionTest, PublicReset) {
- if (GetParam().version.HasIetfInvariantHeader()) {
- return;
- }
- QuicPublicResetPacket header;
- // Public reset packet in only built by server.
- header.connection_id = connection_id_;
- std::unique_ptr<QuicEncryptedPacket> packet(
- framer_.BuildPublicResetPacket(header));
- std::unique_ptr<QuicReceivedPacket> received(
- ConstructReceivedPacket(*packet, QuicTime::Zero()));
- EXPECT_CALL(visitor_, OnConnectionClosed(_, ConnectionCloseSource::FROM_PEER))
- .WillOnce(Invoke(this, &QuicConnectionTest::SaveConnectionCloseFrame));
- connection_.ProcessUdpPacket(kSelfAddress, kPeerAddress, *received);
- EXPECT_EQ(1, connection_close_frame_count_);
- EXPECT_THAT(saved_connection_close_frame_.quic_error_code,
- IsError(QUIC_PUBLIC_RESET));
-}
-
-TEST_P(QuicConnectionTest, IetfStatelessReset) {
- if (!GetParam().version.HasIetfInvariantHeader()) {
- return;
- }
- QuicConfig config;
- QuicConfigPeer::SetReceivedStatelessResetToken(&config,
- kTestStatelessResetToken);
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
- connection_.SetFromConfig(config);
- std::unique_ptr<QuicEncryptedPacket> packet(
- QuicFramer::BuildIetfStatelessResetPacket(connection_id_,
- /*received_packet_length=*/100,
- kTestStatelessResetToken));
- std::unique_ptr<QuicReceivedPacket> received(
- ConstructReceivedPacket(*packet, QuicTime::Zero()));
- if (!connection_.use_path_validator()) {
- EXPECT_CALL(visitor_, ValidateStatelessReset(_, _)).WillOnce(Return(true));
- }
- EXPECT_CALL(visitor_, OnConnectionClosed(_, ConnectionCloseSource::FROM_PEER))
- .WillOnce(Invoke(this, &QuicConnectionTest::SaveConnectionCloseFrame));
- connection_.ProcessUdpPacket(kSelfAddress, kPeerAddress, *received);
- EXPECT_EQ(1, connection_close_frame_count_);
- EXPECT_THAT(saved_connection_close_frame_.quic_error_code,
- IsError(QUIC_PUBLIC_RESET));
-}
-
-TEST_P(QuicConnectionTest, GoAway) {
- if (VersionHasIetfQuicFrames(GetParam().version.transport_version)) {
- // GoAway is not available in version 99.
- return;
- }
-
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-
- QuicGoAwayFrame* goaway = new QuicGoAwayFrame();
- goaway->last_good_stream_id = 1;
- goaway->error_code = QUIC_PEER_GOING_AWAY;
- goaway->reason_phrase = "Going away.";
- EXPECT_CALL(visitor_, OnGoAway(_));
- ProcessGoAwayPacket(goaway);
-}
-
-TEST_P(QuicConnectionTest, WindowUpdate) {
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-
- QuicWindowUpdateFrame* window_update = new QuicWindowUpdateFrame();
- window_update->stream_id = 3;
- window_update->max_data = 1234;
- EXPECT_CALL(visitor_, OnWindowUpdateFrame(_));
- ProcessFramePacket(QuicFrame(window_update));
-}
-
-TEST_P(QuicConnectionTest, Blocked) {
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-
- QuicBlockedFrame* blocked = new QuicBlockedFrame();
- blocked->stream_id = 3;
- EXPECT_CALL(visitor_, OnBlockedFrame(_));
- ProcessFramePacket(QuicFrame(blocked));
- EXPECT_EQ(1u, connection_.GetStats().blocked_frames_received);
- EXPECT_EQ(0u, connection_.GetStats().blocked_frames_sent);
-}
-
-TEST_P(QuicConnectionTest, ZeroBytePacket) {
- // Don't close the connection for zero byte packets.
- EXPECT_CALL(visitor_, OnConnectionClosed(_, _)).Times(0);
- QuicReceivedPacket encrypted(nullptr, 0, QuicTime::Zero());
- connection_.ProcessUdpPacket(kSelfAddress, kPeerAddress, encrypted);
-}
-
-TEST_P(QuicConnectionTest, MissingPacketsBeforeLeastUnacked) {
- if (GetParam().version.HasIetfInvariantHeader()) {
- return;
- }
- // Set the packet number of the ack packet to be least unacked (4).
- QuicPacketCreatorPeer::SetPacketNumber(&peer_creator_, 3);
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- ProcessStopWaitingPacket(InitStopWaitingFrame(4));
- EXPECT_FALSE(connection_.ack_frame().packets.Empty());
-}
-
-TEST_P(QuicConnectionTest, ClientHandlesVersionNegotiation) {
- // All supported versions except the one the connection supports.
- ParsedQuicVersionVector versions;
- for (auto version : AllSupportedVersions()) {
- if (version != connection_.version()) {
- versions.push_back(version);
- }
- }
-
- // Send a version negotiation packet.
- std::unique_ptr<QuicEncryptedPacket> encrypted(
- QuicFramer::BuildVersionNegotiationPacket(
- connection_id_, EmptyQuicConnectionId(),
- connection_.version().HasIetfInvariantHeader(),
- connection_.version().HasLengthPrefixedConnectionIds(), versions));
- std::unique_ptr<QuicReceivedPacket> received(
- ConstructReceivedPacket(*encrypted, QuicTime::Zero()));
- EXPECT_CALL(visitor_, OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF))
- .WillOnce(Invoke(this, &QuicConnectionTest::SaveConnectionCloseFrame));
- // Verify no connection close packet gets sent.
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
- connection_.ProcessUdpPacket(kSelfAddress, kPeerAddress, *received);
- EXPECT_FALSE(connection_.connected());
- EXPECT_EQ(1, connection_close_frame_count_);
- EXPECT_THAT(saved_connection_close_frame_.quic_error_code,
- IsError(QUIC_INVALID_VERSION));
-}
-
-TEST_P(QuicConnectionTest, BadVersionNegotiation) {
- // Send a version negotiation packet with the version the client started with.
- // It should be rejected.
- EXPECT_CALL(visitor_, OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF))
- .WillOnce(Invoke(this, &QuicConnectionTest::SaveConnectionCloseFrame));
- std::unique_ptr<QuicEncryptedPacket> encrypted(
- QuicFramer::BuildVersionNegotiationPacket(
- connection_id_, EmptyQuicConnectionId(),
- connection_.version().HasIetfInvariantHeader(),
- connection_.version().HasLengthPrefixedConnectionIds(),
- AllSupportedVersions()));
- std::unique_ptr<QuicReceivedPacket> received(
- ConstructReceivedPacket(*encrypted, QuicTime::Zero()));
- connection_.ProcessUdpPacket(kSelfAddress, kPeerAddress, *received);
- EXPECT_EQ(1, connection_close_frame_count_);
- EXPECT_THAT(saved_connection_close_frame_.quic_error_code,
- 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;
- if (peer_framer_.perspective() == Perspective::IS_SERVER) {
- header.source_connection_id = connection_id_;
- header.destination_connection_id_included = CONNECTION_ID_ABSENT;
- if (!peer_framer_.version().HasIetfInvariantHeader()) {
- header.source_connection_id_included = CONNECTION_ID_PRESENT;
- }
- } else {
- header.destination_connection_id = connection_id_;
- if (peer_framer_.version().HasIetfInvariantHeader()) {
- header.destination_connection_id_included = CONNECTION_ID_ABSENT;
- }
- }
- header.packet_number = QuicPacketNumber(1);
- header.version_flag = false;
-
- QuicErrorCode kQuicErrorCode = QUIC_PEER_GOING_AWAY;
- // This QuicConnectionCloseFrame will default to being for a Google QUIC
- // close. If doing IETF QUIC then set fields appropriately for CC/T or CC/A,
- // depending on the mapping.
- QuicConnectionCloseFrame qccf(peer_framer_.transport_version(),
- kQuicErrorCode, NO_IETF_QUIC_ERROR, "",
- /*transport_close_frame_type=*/0);
- QuicFrames frames;
- frames.push_back(QuicFrame(frame1_));
- frames.push_back(QuicFrame(&qccf));
- std::unique_ptr<QuicPacket> packet(ConstructPacket(header, frames));
- EXPECT_TRUE(nullptr != packet);
- char buffer[kMaxOutgoingPacketSize];
- size_t encrypted_length = peer_framer_.EncryptPayload(
- ENCRYPTION_FORWARD_SECURE, QuicPacketNumber(1), *packet, buffer,
- kMaxOutgoingPacketSize);
-
- EXPECT_CALL(visitor_, OnConnectionClosed(_, ConnectionCloseSource::FROM_PEER))
- .WillOnce(Invoke(this, &QuicConnectionTest::SaveConnectionCloseFrame));
- EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-
- connection_.ProcessUdpPacket(
- kSelfAddress, kPeerAddress,
- QuicReceivedPacket(buffer, encrypted_length, QuicTime::Zero(), false));
- EXPECT_EQ(1, connection_close_frame_count_);
- EXPECT_THAT(saved_connection_close_frame_.quic_error_code,
- IsError(QUIC_PEER_GOING_AWAY));
-}
-
-TEST_P(QuicConnectionTest, SelectMutualVersion) {
- connection_.SetSupportedVersions(AllSupportedVersions());
- // Set the connection to speak the lowest quic version.
- connection_.set_version(QuicVersionMin());
- EXPECT_EQ(QuicVersionMin(), connection_.version());
-
- // Pass in available versions which includes a higher mutually supported
- // version. The higher mutually supported version should be selected.
- ParsedQuicVersionVector supported_versions = AllSupportedVersions();
- EXPECT_TRUE(connection_.SelectMutualVersion(supported_versions));
- EXPECT_EQ(QuicVersionMax(), connection_.version());
-
- // Expect that the lowest version is selected.
- // Ensure the lowest supported version is less than the max, unless they're
- // the same.
- ParsedQuicVersionVector lowest_version_vector;
- lowest_version_vector.push_back(QuicVersionMin());
- EXPECT_TRUE(connection_.SelectMutualVersion(lowest_version_vector));
- EXPECT_EQ(QuicVersionMin(), connection_.version());
-
- // Shouldn't be able to find a mutually supported version.
- ParsedQuicVersionVector unsupported_version;
- unsupported_version.push_back(UnsupportedQuicVersion());
- EXPECT_FALSE(connection_.SelectMutualVersion(unsupported_version));
-}
-
-TEST_P(QuicConnectionTest, ConnectionCloseWhenWritable) {
- EXPECT_FALSE(writer_->IsWriteBlocked());
-
- // Send a packet.
- connection_.SendStreamDataWithString(1, "foo", 0, NO_FIN);
- EXPECT_EQ(0u, connection_.NumQueuedPackets());
- EXPECT_EQ(1u, writer_->packets_write_attempts());
-
- TriggerConnectionClose();
- EXPECT_LE(2u, writer_->packets_write_attempts());
-}
-
-TEST_P(QuicConnectionTest, ConnectionCloseGettingWriteBlocked) {
- BlockOnNextWrite();
- TriggerConnectionClose();
- EXPECT_EQ(1u, writer_->packets_write_attempts());
- EXPECT_TRUE(writer_->IsWriteBlocked());
-}
-
-TEST_P(QuicConnectionTest, ConnectionCloseWhenWriteBlocked) {
- BlockOnNextWrite();
- connection_.SendStreamDataWithString(1, "foo", 0, NO_FIN);
- EXPECT_EQ(1u, connection_.NumQueuedPackets());
- EXPECT_EQ(1u, writer_->packets_write_attempts());
- EXPECT_TRUE(writer_->IsWriteBlocked());
- TriggerConnectionClose();
- EXPECT_EQ(1u, writer_->packets_write_attempts());
-}
-
-TEST_P(QuicConnectionTest, OnPacketSentDebugVisitor) {
- PathProbeTestInit(Perspective::IS_CLIENT);
- MockQuicConnectionDebugVisitor debug_visitor;
- connection_.set_debug_visitor(&debug_visitor);
-
- EXPECT_CALL(debug_visitor, OnPacketSent(_, _, _, _, _, _, _, _)).Times(1);
- connection_.SendStreamDataWithString(1, "foo", 0, NO_FIN);
-
- EXPECT_CALL(debug_visitor, OnPacketSent(_, _, _, _, _, _, _, _)).Times(1);
- connection_.SendConnectivityProbingPacket(writer_.get(),
- connection_.peer_address());
-}
-
-TEST_P(QuicConnectionTest, OnPacketHeaderDebugVisitor) {
- QuicPacketHeader header;
- header.packet_number = QuicPacketNumber(1);
- if (GetParam().version.HasIetfInvariantHeader()) {
- header.form = IETF_QUIC_LONG_HEADER_PACKET;
- }
-
- MockQuicConnectionDebugVisitor debug_visitor;
- connection_.set_debug_visitor(&debug_visitor);
- EXPECT_CALL(debug_visitor, OnPacketHeader(Ref(header), _, _)).Times(1);
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_)).Times(1);
- EXPECT_CALL(debug_visitor, OnSuccessfulVersionNegotiation(_)).Times(1);
- connection_.OnPacketHeader(header);
-}
-
-TEST_P(QuicConnectionTest, Pacing) {
- TestConnection server(connection_id_, kPeerAddress, kSelfAddress,
- helper_.get(), alarm_factory_.get(), writer_.get(),
- Perspective::IS_SERVER, version());
- TestConnection client(connection_id_, kSelfAddress, kPeerAddress,
- helper_.get(), alarm_factory_.get(), writer_.get(),
- Perspective::IS_CLIENT, version());
- EXPECT_FALSE(QuicSentPacketManagerPeer::UsingPacing(
- static_cast<const QuicSentPacketManager*>(
- &client.sent_packet_manager())));
- EXPECT_FALSE(QuicSentPacketManagerPeer::UsingPacing(
- static_cast<const QuicSentPacketManager*>(
- &server.sent_packet_manager())));
-}
-
-TEST_P(QuicConnectionTest, WindowUpdateInstigateAcks) {
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-
- // Send a WINDOW_UPDATE frame.
- QuicWindowUpdateFrame* window_update = new QuicWindowUpdateFrame();
- window_update->stream_id = 3;
- window_update->max_data = 1234;
- EXPECT_CALL(visitor_, OnWindowUpdateFrame(_));
- ProcessFramePacket(QuicFrame(window_update));
-
- // Ensure that this has caused the ACK alarm to be set.
- EXPECT_TRUE(connection_.HasPendingAcks());
-}
-
-TEST_P(QuicConnectionTest, BlockedFrameInstigateAcks) {
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-
- // Send a BLOCKED frame.
- QuicBlockedFrame* blocked = new QuicBlockedFrame();
- blocked->stream_id = 3;
- EXPECT_CALL(visitor_, OnBlockedFrame(_));
- ProcessFramePacket(QuicFrame(blocked));
-
- // Ensure that this has caused the ACK alarm to be set.
- EXPECT_TRUE(connection_.HasPendingAcks());
-}
-
-TEST_P(QuicConnectionTest, ReevaluateTimeUntilSendOnAck) {
- // Enable pacing.
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
- QuicConfig config;
- connection_.SetFromConfig(config);
-
- // Send two packets. One packet is not sufficient because if it gets acked,
- // there will be no packets in flight after that and the pacer will always
- // allow the next packet in that situation.
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- EXPECT_CALL(*send_algorithm_, CanSend(_)).WillRepeatedly(Return(true));
- connection_.SendStreamDataWithString(
- GetNthClientInitiatedStreamId(1, connection_.transport_version()), "foo",
- 0, NO_FIN);
- connection_.SendStreamDataWithString(
- GetNthClientInitiatedStreamId(1, connection_.transport_version()), "bar",
- 3, NO_FIN);
- connection_.OnCanWrite();
-
- // Schedule the next packet for a few milliseconds in future.
- QuicSentPacketManagerPeer::DisablePacerBursts(manager_);
- QuicTime scheduled_pacing_time =
- clock_.Now() + QuicTime::Delta::FromMilliseconds(5);
- QuicSentPacketManagerPeer::SetNextPacedPacketTime(manager_,
- scheduled_pacing_time);
-
- // Send a packet and have it be blocked by congestion control.
- EXPECT_CALL(*send_algorithm_, CanSend(_)).WillRepeatedly(Return(false));
- connection_.SendStreamDataWithString(
- GetNthClientInitiatedStreamId(1, connection_.transport_version()), "baz",
- 6, NO_FIN);
- EXPECT_FALSE(connection_.GetSendAlarm()->IsSet());
-
- // Process an ack and the send alarm will be set to the new 5ms delay.
- QuicAckFrame ack = InitAckFrame(1);
- EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _));
- EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
- EXPECT_CALL(*send_algorithm_, CanSend(_)).WillRepeatedly(Return(true));
- ProcessAckPacket(&ack);
- size_t padding_frame_count = writer_->padding_frames().size();
- EXPECT_EQ(padding_frame_count + 1u, writer_->frame_count());
- EXPECT_EQ(1u, writer_->stream_frames().size());
- EXPECT_TRUE(connection_.GetSendAlarm()->IsSet());
- EXPECT_EQ(scheduled_pacing_time, connection_.GetSendAlarm()->deadline());
- writer_->Reset();
-}
-
-TEST_P(QuicConnectionTest, SendAcksImmediately) {
- if (connection_.SupportsMultiplePacketNumberSpaces()) {
- return;
- }
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
- ProcessDataPacket(1);
- CongestionBlockWrites();
- SendAckPacketToPeer();
-}
-
-TEST_P(QuicConnectionTest, SendPingImmediately) {
- MockQuicConnectionDebugVisitor debug_visitor;
- connection_.set_debug_visitor(&debug_visitor);
-
- CongestionBlockWrites();
- connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
- EXPECT_CALL(debug_visitor, OnPacketSent(_, _, _, _, _, _, _, _)).Times(1);
- EXPECT_CALL(debug_visitor, OnPingSent()).Times(1);
- connection_.SendControlFrame(QuicFrame(QuicPingFrame(1)));
- EXPECT_FALSE(connection_.HasQueuedData());
-}
-
-TEST_P(QuicConnectionTest, SendBlockedImmediately) {
- MockQuicConnectionDebugVisitor debug_visitor;
- connection_.set_debug_visitor(&debug_visitor);
-
- connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
- 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(new QuicBlockedFrame(1, 3)));
- EXPECT_EQ(1u, connection_.GetStats().blocked_frames_sent);
- EXPECT_FALSE(connection_.HasQueuedData());
-}
-
-TEST_P(QuicConnectionTest, FailedToSendBlockedFrames) {
- if (!connection_.SupportsMultiplePacketNumberSpaces()) {
- return;
- }
- MockQuicConnectionDebugVisitor debug_visitor;
- connection_.set_debug_visitor(&debug_visitor);
- QuicBlockedFrame blocked(1, 3);
-
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
- EXPECT_CALL(debug_visitor, OnPacketSent(_, _, _, _, _, _, _, _)).Times(0);
- EXPECT_EQ(0u, connection_.GetStats().blocked_frames_sent);
- connection_.SendControlFrame(QuicFrame(&blocked));
- EXPECT_EQ(0u, connection_.GetStats().blocked_frames_sent);
- EXPECT_FALSE(connection_.HasQueuedData());
-}
-
-TEST_P(QuicConnectionTest, SendingUnencryptedStreamDataFails) {
- // EXPECT_QUIC_BUG tests are expensive so only run one instance of them.
- if (!IsDefaultTestConfiguration()) {
- return;
- }
-
- EXPECT_CALL(visitor_, OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF))
- .WillOnce(Invoke(this, &QuicConnectionTest::SaveConnectionCloseFrame));
- struct iovec iov;
- MakeIOVector("", &iov);
- EXPECT_QUIC_BUG(connection_.SaveAndSendStreamData(3, &iov, 1, 0, 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));
-}
-
-TEST_P(QuicConnectionTest, SetRetransmissionAlarmForCryptoPacket) {
- EXPECT_TRUE(connection_.connected());
- EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
-
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
- connection_.SendCryptoStreamData();
-
- // Verify retransmission timer is correctly set after crypto packet has been
- // sent.
- EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
- QuicTime retransmission_time =
- QuicConnectionPeer::GetSentPacketManager(&connection_)
- ->GetRetransmissionTime();
- EXPECT_NE(retransmission_time, clock_.ApproximateNow());
- EXPECT_EQ(retransmission_time,
- connection_.GetRetransmissionAlarm()->deadline());
-
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
- connection_.GetRetransmissionAlarm()->Fire();
-}
-
-// Includes regression test for b/69979024.
-TEST_P(QuicConnectionTest, PathDegradingDetectionForNonCryptoPackets) {
- EXPECT_TRUE(connection_.connected());
- EXPECT_FALSE(connection_.PathDegradingDetectionInProgress());
- EXPECT_FALSE(connection_.IsPathDegrading());
-
- const char data[] = "data";
- size_t data_size = strlen(data);
- QuicStreamOffset offset = 0;
-
- for (int i = 0; i < 2; ++i) {
- // Send a packet. Now there's a retransmittable packet on the wire, so the
- // path degrading detection should be set.
- connection_.SendStreamDataWithString(
- GetNthClientInitiatedStreamId(1, connection_.transport_version()), data,
- offset, NO_FIN);
- offset += data_size;
- EXPECT_TRUE(connection_.PathDegradingDetectionInProgress());
- // Check the deadline of the path degrading detection.
- QuicTime::Delta delay =
- QuicConnectionPeer::GetSentPacketManager(&connection_)
- ->GetPathDegradingDelay();
- EXPECT_EQ(delay, connection_.GetBlackholeDetectorAlarm()->deadline() -
- clock_.ApproximateNow());
-
- // Send a second packet. The path degrading detection's deadline should
- // remain the same.
- // Regression test for b/69979024.
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
- QuicTime prev_deadline =
- connection_.GetBlackholeDetectorAlarm()->deadline();
- connection_.SendStreamDataWithString(
- GetNthClientInitiatedStreamId(1, connection_.transport_version()), data,
- offset, NO_FIN);
- offset += data_size;
- EXPECT_TRUE(connection_.PathDegradingDetectionInProgress());
- EXPECT_EQ(prev_deadline,
- connection_.GetBlackholeDetectorAlarm()->deadline());
-
- // Now receive an ACK of the first packet. This should advance the path
- // degrading detection's deadline since forward progress has been made.
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
- if (i == 0) {
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- }
- EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
- QuicAckFrame frame = InitAckFrame(
- {{QuicPacketNumber(1u + 2u * i), QuicPacketNumber(2u + 2u * i)}});
- ProcessAckPacket(&frame);
- EXPECT_TRUE(connection_.PathDegradingDetectionInProgress());
- // Check the deadline of the path degrading detection.
- delay = QuicConnectionPeer::GetSentPacketManager(&connection_)
- ->GetPathDegradingDelay();
- EXPECT_EQ(delay, connection_.GetBlackholeDetectorAlarm()->deadline() -
- clock_.ApproximateNow());
-
- if (i == 0) {
- // Now receive an ACK of the second packet. Since there are no more
- // retransmittable packets on the wire, this should cancel the path
- // degrading detection.
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
- EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
- frame = InitAckFrame({{QuicPacketNumber(2), QuicPacketNumber(3)}});
- ProcessAckPacket(&frame);
- EXPECT_FALSE(connection_.PathDegradingDetectionInProgress());
- } else {
- // Advance time to the path degrading alarm's deadline and simulate
- // firing the alarm.
- clock_.AdvanceTime(delay);
- EXPECT_CALL(visitor_, OnPathDegrading());
- connection_.PathDegradingTimeout();
- EXPECT_FALSE(connection_.PathDegradingDetectionInProgress());
- }
- }
- EXPECT_TRUE(connection_.IsPathDegrading());
-}
-
-TEST_P(QuicConnectionTest, RetransmittableOnWireSetsPingAlarm) {
- const QuicTime::Delta retransmittable_on_wire_timeout =
- QuicTime::Delta::FromMilliseconds(50);
- connection_.set_initial_retransmittable_on_wire_timeout(
- retransmittable_on_wire_timeout);
-
- EXPECT_TRUE(connection_.connected());
- EXPECT_CALL(visitor_, ShouldKeepConnectionAlive())
- .WillRepeatedly(Return(true));
-
- EXPECT_FALSE(connection_.PathDegradingDetectionInProgress());
- EXPECT_FALSE(connection_.IsPathDegrading());
- EXPECT_FALSE(connection_.GetPingAlarm()->IsSet());
-
- const char data[] = "data";
- size_t data_size = strlen(data);
- QuicStreamOffset offset = 0;
-
- // Send a packet.
- connection_.SendStreamDataWithString(1, data, offset, NO_FIN);
- offset += data_size;
- // Now there's a retransmittable packet on the wire, so the path degrading
- // alarm should be set.
- // The retransmittable-on-wire alarm should not be set.
- EXPECT_TRUE(connection_.PathDegradingDetectionInProgress());
- QuicTime::Delta delay = QuicConnectionPeer::GetSentPacketManager(&connection_)
- ->GetPathDegradingDelay();
- EXPECT_EQ(delay, connection_.GetBlackholeDetectorAlarm()->deadline() -
- clock_.ApproximateNow());
- ASSERT_TRUE(connection_.sent_packet_manager().HasInFlightPackets());
- // The ping alarm is set for the ping timeout, not the shorter
- // retransmittable_on_wire_timeout.
- EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
- QuicTime::Delta ping_delay = QuicTime::Delta::FromSeconds(kPingTimeoutSecs);
- EXPECT_EQ(ping_delay,
- connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
-
- // Now receive an ACK of the packet.
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
- QuicAckFrame frame =
- InitAckFrame({{QuicPacketNumber(1), QuicPacketNumber(2)}});
- ProcessAckPacket(&frame);
- // No more retransmittable packets on the wire, so the path degrading alarm
- // should be cancelled, and the ping alarm should be set to the
- // retransmittable_on_wire_timeout.
- EXPECT_FALSE(connection_.PathDegradingDetectionInProgress());
- EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
- EXPECT_EQ(retransmittable_on_wire_timeout,
- connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
-
- // Simulate firing the ping alarm and sending a PING.
- clock_.AdvanceTime(retransmittable_on_wire_timeout);
- connection_.GetPingAlarm()->Fire();
-
- // Now there's a retransmittable packet (PING) on the wire, so the path
- // degrading alarm should be set.
- EXPECT_TRUE(connection_.PathDegradingDetectionInProgress());
- delay = QuicConnectionPeer::GetSentPacketManager(&connection_)
- ->GetPathDegradingDelay();
- EXPECT_EQ(delay, connection_.GetBlackholeDetectorAlarm()->deadline() -
- clock_.ApproximateNow());
-}
-
-TEST_P(QuicConnectionTest, ServerRetransmittableOnWire) {
- set_perspective(Perspective::IS_SERVER);
- QuicPacketCreatorPeer::SetSendVersionInPacket(creator_, false);
- SetQuicReloadableFlag(quic_enable_server_on_wire_ping, true);
-
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
- QuicConfig config;
- QuicTagVector connection_options;
- connection_options.push_back(kSRWP);
- config.SetInitialReceivedConnectionOptions(connection_options);
- connection_.SetFromConfig(config);
-
- EXPECT_CALL(visitor_, ShouldKeepConnectionAlive())
- .WillRepeatedly(Return(true));
-
- ProcessPacket(1);
-
- ASSERT_TRUE(connection_.GetPingAlarm()->IsSet());
- QuicTime::Delta ping_delay = QuicTime::Delta::FromMilliseconds(200);
- EXPECT_EQ(ping_delay,
- connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
-
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
- connection_.SendStreamDataWithString(2, "foo", 0, NO_FIN);
- // Verify PING alarm gets cancelled.
- EXPECT_FALSE(connection_.GetPingAlarm()->IsSet());
-
- // Now receive an ACK of the packet.
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(100));
- EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
- QuicAckFrame frame =
- InitAckFrame({{QuicPacketNumber(1), QuicPacketNumber(2)}});
- ProcessAckPacket(2, &frame);
- // Verify PING alarm gets scheduled.
- ASSERT_TRUE(connection_.GetPingAlarm()->IsSet());
- EXPECT_EQ(ping_delay,
- connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
-}
-
-// This test verifies that the connection marks path as degrading and does not
-// spin timer to detect path degrading when a new packet is sent on the
-// degraded path.
-TEST_P(QuicConnectionTest, NoPathDegradingDetectionIfPathIsDegrading) {
- EXPECT_TRUE(connection_.connected());
- EXPECT_FALSE(connection_.PathDegradingDetectionInProgress());
- EXPECT_FALSE(connection_.IsPathDegrading());
-
- const char data[] = "data";
- size_t data_size = strlen(data);
- QuicStreamOffset offset = 0;
-
- // Send the first packet. Now there's a retransmittable packet on the wire, so
- // the path degrading alarm should be set.
- connection_.SendStreamDataWithString(1, data, offset, NO_FIN);
- offset += data_size;
- EXPECT_TRUE(connection_.PathDegradingDetectionInProgress());
- // Check the deadline of the path degrading detection.
- QuicTime::Delta delay = QuicConnectionPeer::GetSentPacketManager(&connection_)
- ->GetPathDegradingDelay();
- EXPECT_EQ(delay, connection_.GetBlackholeDetectorAlarm()->deadline() -
- clock_.ApproximateNow());
-
- // Send a second packet. The path degrading detection's deadline should remain
- // the same.
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
- QuicTime prev_deadline = connection_.GetBlackholeDetectorAlarm()->deadline();
- connection_.SendStreamDataWithString(1, data, offset, NO_FIN);
- offset += data_size;
- EXPECT_TRUE(connection_.PathDegradingDetectionInProgress());
- EXPECT_EQ(prev_deadline, connection_.GetBlackholeDetectorAlarm()->deadline());
-
- // Now receive an ACK of the first packet. This should advance the path
- // degrading detection's deadline since forward progress has been made.
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
- QuicAckFrame frame =
- InitAckFrame({{QuicPacketNumber(1u), QuicPacketNumber(2u)}});
- ProcessAckPacket(&frame);
- EXPECT_TRUE(connection_.PathDegradingDetectionInProgress());
- // Check the deadline of the path degrading alarm.
- delay = QuicConnectionPeer::GetSentPacketManager(&connection_)
- ->GetPathDegradingDelay();
- EXPECT_EQ(delay, connection_.GetBlackholeDetectorAlarm()->deadline() -
- clock_.ApproximateNow());
-
- // Advance time to the path degrading detection's deadline and simulate
- // firing the path degrading detection. This path will be considered as
- // degrading.
- clock_.AdvanceTime(delay);
- EXPECT_CALL(visitor_, OnPathDegrading()).Times(1);
- connection_.PathDegradingTimeout();
- EXPECT_FALSE(connection_.PathDegradingDetectionInProgress());
- EXPECT_TRUE(connection_.IsPathDegrading());
-
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
- EXPECT_FALSE(connection_.PathDegradingDetectionInProgress());
- // Send a third packet. The path degrading detection is no longer set but path
- // should still be marked as degrading.
- connection_.SendStreamDataWithString(1, data, offset, NO_FIN);
- offset += data_size;
- EXPECT_FALSE(connection_.PathDegradingDetectionInProgress());
- EXPECT_TRUE(connection_.IsPathDegrading());
-}
-
-// This test verifies that the connection unmarks path as degrarding and spins
-// the timer to detect future path degrading when forward progress is made
-// after path has been marked degrading.
-TEST_P(QuicConnectionTest, UnmarkPathDegradingOnForwardProgress) {
- EXPECT_TRUE(connection_.connected());
- EXPECT_FALSE(connection_.PathDegradingDetectionInProgress());
- EXPECT_FALSE(connection_.IsPathDegrading());
-
- const char data[] = "data";
- size_t data_size = strlen(data);
- QuicStreamOffset offset = 0;
-
- // Send the first packet. Now there's a retransmittable packet on the wire, so
- // the path degrading alarm should be set.
- connection_.SendStreamDataWithString(1, data, offset, NO_FIN);
- offset += data_size;
- EXPECT_TRUE(connection_.PathDegradingDetectionInProgress());
- // Check the deadline of the path degrading alarm.
- QuicTime::Delta delay = QuicConnectionPeer::GetSentPacketManager(&connection_)
- ->GetPathDegradingDelay();
- EXPECT_EQ(delay, connection_.GetBlackholeDetectorAlarm()->deadline() -
- clock_.ApproximateNow());
-
- // Send a second packet. The path degrading alarm's deadline should remain
- // the same.
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
- QuicTime prev_deadline = connection_.GetBlackholeDetectorAlarm()->deadline();
- connection_.SendStreamDataWithString(1, data, offset, NO_FIN);
- offset += data_size;
- EXPECT_TRUE(connection_.PathDegradingDetectionInProgress());
- EXPECT_EQ(prev_deadline, connection_.GetBlackholeDetectorAlarm()->deadline());
-
- // Now receive an ACK of the first packet. This should advance the path
- // degrading alarm's deadline since forward progress has been made.
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
- QuicAckFrame frame =
- InitAckFrame({{QuicPacketNumber(1u), QuicPacketNumber(2u)}});
- ProcessAckPacket(&frame);
- EXPECT_TRUE(connection_.PathDegradingDetectionInProgress());
- // Check the deadline of the path degrading alarm.
- delay = QuicConnectionPeer::GetSentPacketManager(&connection_)
- ->GetPathDegradingDelay();
- EXPECT_EQ(delay, connection_.GetBlackholeDetectorAlarm()->deadline() -
- clock_.ApproximateNow());
-
- // Advance time to the path degrading alarm's deadline and simulate
- // firing the alarm.
- clock_.AdvanceTime(delay);
- EXPECT_CALL(visitor_, OnPathDegrading()).Times(1);
- connection_.PathDegradingTimeout();
- EXPECT_FALSE(connection_.PathDegradingDetectionInProgress());
- EXPECT_TRUE(connection_.IsPathDegrading());
-
- // Send a third packet. The path degrading alarm is no longer set but path
- // should still be marked as degrading.
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
- EXPECT_FALSE(connection_.PathDegradingDetectionInProgress());
- connection_.SendStreamDataWithString(1, data, offset, NO_FIN);
- offset += data_size;
- EXPECT_FALSE(connection_.PathDegradingDetectionInProgress());
- EXPECT_TRUE(connection_.IsPathDegrading());
-
- // Now receive an ACK of the second packet. This should unmark the path as
- // degrading. And will set a timer to detect new path degrading.
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
- EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
- EXPECT_CALL(visitor_, OnForwardProgressMadeAfterPathDegrading()).Times(1);
- frame = InitAckFrame({{QuicPacketNumber(2), QuicPacketNumber(3)}});
- ProcessAckPacket(&frame);
- EXPECT_FALSE(connection_.IsPathDegrading());
- EXPECT_TRUE(connection_.PathDegradingDetectionInProgress());
-}
-
-TEST_P(QuicConnectionTest, NoPathDegradingOnServer) {
- if (connection_.SupportsMultiplePacketNumberSpaces()) {
- return;
- }
- set_perspective(Perspective::IS_SERVER);
- QuicPacketCreatorPeer::SetSendVersionInPacket(creator_, false);
-
- EXPECT_FALSE(connection_.IsPathDegrading());
- EXPECT_FALSE(connection_.PathDegradingDetectionInProgress());
-
- // Send data.
- const char data[] = "data";
- connection_.SendStreamDataWithString(1, data, 0, NO_FIN);
- EXPECT_FALSE(connection_.IsPathDegrading());
- EXPECT_FALSE(connection_.PathDegradingDetectionInProgress());
-
- // Ack data.
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
- EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
- QuicAckFrame frame =
- InitAckFrame({{QuicPacketNumber(1u), QuicPacketNumber(2u)}});
- ProcessAckPacket(&frame);
- EXPECT_FALSE(connection_.IsPathDegrading());
- EXPECT_FALSE(connection_.PathDegradingDetectionInProgress());
-}
-
-TEST_P(QuicConnectionTest, NoPathDegradingAfterSendingAck) {
- if (connection_.SupportsMultiplePacketNumberSpaces()) {
- return;
- }
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
- ProcessDataPacket(1);
- SendAckPacketToPeer();
- EXPECT_FALSE(connection_.sent_packet_manager().unacked_packets().empty());
- EXPECT_FALSE(connection_.sent_packet_manager().HasInFlightPackets());
- EXPECT_FALSE(connection_.IsPathDegrading());
- EXPECT_FALSE(connection_.PathDegradingDetectionInProgress());
-}
-
-TEST_P(QuicConnectionTest, MultipleCallsToCloseConnection) {
- // Verifies that multiple calls to CloseConnection do not
- // result in multiple attempts to close the connection - it will be marked as
- // disconnected after the first call.
- EXPECT_CALL(visitor_, OnConnectionClosed(_, _)).Times(1);
- connection_.CloseConnection(QUIC_NO_ERROR, "no reason",
- ConnectionCloseBehavior::SILENT_CLOSE);
- connection_.CloseConnection(QUIC_NO_ERROR, "no reason",
- ConnectionCloseBehavior::SILENT_CLOSE);
-}
-
-TEST_P(QuicConnectionTest, ServerReceivesChloOnNonCryptoStream) {
- set_perspective(Perspective::IS_SERVER);
- QuicPacketCreatorPeer::SetSendVersionInPacket(creator_, false);
-
- CryptoHandshakeMessage message;
- CryptoFramer framer;
- message.set_tag(kCHLO);
- std::unique_ptr<QuicData> data = framer.ConstructHandshakeMessage(message);
- frame1_.stream_id = 10;
- frame1_.data_buffer = data->data();
- frame1_.data_length = data->length();
-
- if (version().handshake_protocol == PROTOCOL_TLS1_3) {
- EXPECT_CALL(visitor_, BeforeConnectionCloseSent());
- }
- EXPECT_CALL(visitor_,
- OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF));
- ForceProcessFramePacket(QuicFrame(frame1_));
- if (VersionHasIetfQuicFrames(version().transport_version)) {
- // INITIAL packet should not contain STREAM frame.
- TestConnectionCloseQuicErrorCode(IETF_QUIC_PROTOCOL_VIOLATION);
- } else {
- TestConnectionCloseQuicErrorCode(QUIC_MAYBE_CORRUPTED_MEMORY);
- }
-}
-
-TEST_P(QuicConnectionTest, ClientReceivesRejOnNonCryptoStream) {
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-
- CryptoHandshakeMessage message;
- CryptoFramer framer;
- message.set_tag(kREJ);
- std::unique_ptr<QuicData> data = framer.ConstructHandshakeMessage(message);
- frame1_.stream_id = 10;
- frame1_.data_buffer = data->data();
- frame1_.data_length = data->length();
-
- EXPECT_CALL(visitor_,
- OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF));
- ForceProcessFramePacket(QuicFrame(frame1_));
- if (VersionHasIetfQuicFrames(version().transport_version)) {
- // INITIAL packet should not contain STREAM frame.
- TestConnectionCloseQuicErrorCode(IETF_QUIC_PROTOCOL_VIOLATION);
- } else {
- TestConnectionCloseQuicErrorCode(QUIC_MAYBE_CORRUPTED_MEMORY);
- }
-}
-
-TEST_P(QuicConnectionTest, CloseConnectionOnPacketTooLarge) {
- SimulateNextPacketTooLarge();
- // A connection close packet is sent
- EXPECT_CALL(visitor_, OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF))
- .Times(1);
- connection_.SendStreamDataWithString(3, "foo", 0, NO_FIN);
- TestConnectionCloseQuicErrorCode(QUIC_PACKET_WRITE_ERROR);
-}
-
-TEST_P(QuicConnectionTest, AlwaysGetPacketTooLarge) {
- // Test even we always get packet too large, we do not infinitely try to send
- // close packet.
- AlwaysGetPacketTooLarge();
- EXPECT_CALL(visitor_, OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF))
- .Times(1);
- connection_.SendStreamDataWithString(3, "foo", 0, NO_FIN);
- TestConnectionCloseQuicErrorCode(QUIC_PACKET_WRITE_ERROR);
-}
-
-TEST_P(QuicConnectionTest, CloseConnectionOnQueuedWriteError) {
- // Regression test for crbug.com/979507.
- //
- // If we get a write error when writing queued packets, we should attempt to
- // send a connection close packet, but if sending that fails, it shouldn't get
- // queued.
-
- // Queue a packet to write.
- BlockOnNextWrite();
- connection_.SendStreamDataWithString(3, "foo", 0, NO_FIN);
- EXPECT_EQ(1u, connection_.NumQueuedPackets());
-
- // Configure writer to always fail.
- AlwaysGetPacketTooLarge();
-
- // Expect that we attempt to close the connection exactly once.
- EXPECT_CALL(visitor_, OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF))
- .Times(1);
-
- // Unblock the writes and actually send.
- writer_->SetWritable();
- connection_.OnCanWrite();
- EXPECT_EQ(0u, connection_.NumQueuedPackets());
-
- TestConnectionCloseQuicErrorCode(QUIC_PACKET_WRITE_ERROR);
-}
-
-// Verify that if connection has no outstanding data, it notifies the send
-// algorithm after the write.
-TEST_P(QuicConnectionTest, SendDataAndBecomeApplicationLimited) {
- EXPECT_CALL(*send_algorithm_, OnApplicationLimited(_)).Times(1);
- {
- InSequence seq;
- EXPECT_CALL(visitor_, WillingAndAbleToWrite()).WillRepeatedly(Return(true));
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _));
- EXPECT_CALL(visitor_, WillingAndAbleToWrite())
- .WillRepeatedly(Return(false));
- }
-
- connection_.SendStreamData3();
-}
-
-// Verify that the connection does not become app-limited if there is
-// outstanding data to send after the write.
-TEST_P(QuicConnectionTest, NotBecomeApplicationLimitedIfMoreDataAvailable) {
- EXPECT_CALL(*send_algorithm_, OnApplicationLimited(_)).Times(0);
- {
- InSequence seq;
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _));
- EXPECT_CALL(visitor_, WillingAndAbleToWrite()).WillRepeatedly(Return(true));
- }
-
- connection_.SendStreamData3();
-}
-
-// Verify that the connection does not become app-limited after blocked write
-// even if there is outstanding data to send after the write.
-TEST_P(QuicConnectionTest, NotBecomeApplicationLimitedDueToWriteBlock) {
- EXPECT_CALL(*send_algorithm_, OnApplicationLimited(_)).Times(0);
- EXPECT_CALL(visitor_, WillingAndAbleToWrite()).WillRepeatedly(Return(true));
- BlockOnNextWrite();
-
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
- connection_.SendStreamData3();
-
- // Now unblock the writer, become congestion control blocked,
- // and ensure we become app-limited after writing.
- writer_->SetWritable();
- CongestionBlockWrites();
- EXPECT_CALL(visitor_, WillingAndAbleToWrite()).WillRepeatedly(Return(false));
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
- EXPECT_CALL(*send_algorithm_, OnApplicationLimited(_)).Times(1);
- 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.
- ProcessPacket(1);
- EXPECT_TRUE(connection_.HasPendingAcks());
- connection_.GetAckAlarm()->Fire();
- // Simulate data packet causes write error.
- EXPECT_CALL(visitor_, OnConnectionClosed(_, _));
- SimulateNextPacketTooLarge();
- connection_.SendStreamDataWithString(3, "foo", 0, NO_FIN);
- EXPECT_EQ(1u, writer_->connection_close_frames().size());
- // Ack frame is not bundled in connection close packet.
- EXPECT_TRUE(writer_->ack_frames().empty());
- if (writer_->padding_frames().empty()) {
- EXPECT_EQ(1u, writer_->frame_count());
- } else {
- EXPECT_EQ(2u, writer_->frame_count());
- }
-
- TestConnectionCloseQuicErrorCode(QUIC_PACKET_WRITE_ERROR);
-}
-
-TEST_P(QuicConnectionTest, CloseConnectionAllLevels) {
- if (!connection_.SupportsMultiplePacketNumberSpaces()) {
- return;
- }
-
- EXPECT_CALL(visitor_, OnConnectionClosed(_, _));
- const QuicErrorCode kQuicErrorCode = QUIC_INTERNAL_ERROR;
- connection_.CloseConnection(
- kQuicErrorCode, "Some random error message",
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
-
- EXPECT_EQ(2u, QuicConnectionPeer::GetNumEncryptionLevels(&connection_));
-
- TestConnectionCloseQuicErrorCode(kQuicErrorCode);
- EXPECT_EQ(1u, writer_->connection_close_frames().size());
-
- if (!connection_.version().CanSendCoalescedPackets()) {
- // Each connection close packet should be sent in distinct UDP packets.
- EXPECT_EQ(QuicConnectionPeer::GetNumEncryptionLevels(&connection_),
- writer_->connection_close_packets());
- EXPECT_EQ(QuicConnectionPeer::GetNumEncryptionLevels(&connection_),
- writer_->packets_write_attempts());
- return;
- }
-
- // A single UDP packet should be sent with multiple connection close packets
- // coalesced together.
- EXPECT_EQ(1u, writer_->packets_write_attempts());
-
- // Only the first packet has been processed yet.
- EXPECT_EQ(1u, writer_->connection_close_packets());
-
- // ProcessPacket resets the visitor and frees the coalesced packet.
- ASSERT_TRUE(writer_->coalesced_packet() != nullptr);
- auto packet = writer_->coalesced_packet()->Clone();
- writer_->framer()->ProcessPacket(*packet);
- EXPECT_EQ(1u, writer_->connection_close_packets());
- ASSERT_TRUE(writer_->coalesced_packet() == nullptr);
-}
-
-TEST_P(QuicConnectionTest, CloseConnectionOneLevel) {
- if (connection_.SupportsMultiplePacketNumberSpaces()) {
- return;
- }
-
- EXPECT_CALL(visitor_, OnConnectionClosed(_, _));
- const QuicErrorCode kQuicErrorCode = QUIC_INTERNAL_ERROR;
- connection_.CloseConnection(
- kQuicErrorCode, "Some random error message",
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
-
- EXPECT_EQ(2u, QuicConnectionPeer::GetNumEncryptionLevels(&connection_));
-
- TestConnectionCloseQuicErrorCode(kQuicErrorCode);
- EXPECT_EQ(1u, writer_->connection_close_frames().size());
- EXPECT_EQ(1u, writer_->connection_close_packets());
- EXPECT_EQ(1u, writer_->packets_write_attempts());
- ASSERT_TRUE(writer_->coalesced_packet() == nullptr);
-}
-
-TEST_P(QuicConnectionTest, DoNotPadServerInitialConnectionClose) {
- if (!connection_.SupportsMultiplePacketNumberSpaces()) {
- return;
- }
- set_perspective(Perspective::IS_SERVER);
-
- if (version().handshake_protocol == PROTOCOL_TLS1_3) {
- EXPECT_CALL(visitor_, BeforeConnectionCloseSent());
- }
- EXPECT_CALL(visitor_, OnConnectionClosed(_, _));
- const QuicErrorCode kQuicErrorCode = QUIC_INTERNAL_ERROR;
- connection_.CloseConnection(
- kQuicErrorCode, "Some random error message",
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
-
- EXPECT_EQ(2u, QuicConnectionPeer::GetNumEncryptionLevels(&connection_));
-
- TestConnectionCloseQuicErrorCode(kQuicErrorCode);
- EXPECT_EQ(1u, writer_->connection_close_frames().size());
- EXPECT_TRUE(writer_->padding_frames().empty());
- EXPECT_EQ(ENCRYPTION_INITIAL, writer_->framer()->last_decrypted_level());
-}
-
-// Regression test for b/63620844.
-TEST_P(QuicConnectionTest, FailedToWriteHandshakePacket) {
- SimulateNextPacketTooLarge();
- EXPECT_CALL(visitor_, OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF))
- .Times(1);
-
- connection_.SendCryptoStreamData();
- TestConnectionCloseQuicErrorCode(QUIC_PACKET_WRITE_ERROR);
-}
-
-TEST_P(QuicConnectionTest, MaxPacingRate) {
- EXPECT_EQ(0, connection_.MaxPacingRate().ToBytesPerSecond());
- connection_.SetMaxPacingRate(QuicBandwidth::FromBytesPerSecond(100));
- EXPECT_EQ(100, connection_.MaxPacingRate().ToBytesPerSecond());
-}
-
-TEST_P(QuicConnectionTest, ClientAlwaysSendConnectionId) {
- EXPECT_EQ(Perspective::IS_CLIENT, connection_.perspective());
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
- connection_.SendStreamDataWithString(3, "foo", 0, NO_FIN);
- EXPECT_EQ(CONNECTION_ID_PRESENT,
- writer_->last_packet_header().destination_connection_id_included);
-
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
- QuicConfig config;
- QuicConfigPeer::SetReceivedBytesForConnectionId(&config, 0);
- connection_.SetFromConfig(config);
-
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
- connection_.SendStreamDataWithString(3, "bar", 3, NO_FIN);
- // Verify connection id is still sent in the packet.
- EXPECT_EQ(CONNECTION_ID_PRESENT,
- 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);
- connection_.set_initial_retransmittable_on_wire_timeout(
- retransmittable_on_wire_timeout);
-
- EXPECT_TRUE(connection_.connected());
- EXPECT_CALL(visitor_, ShouldKeepConnectionAlive())
- .WillRepeatedly(Return(true));
-
- const char data[] = "data";
- size_t data_size = strlen(data);
- QuicStreamOffset offset = 0;
-
- // Advance 5ms, send a retransmittable packet to the peer.
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
- EXPECT_FALSE(connection_.GetPingAlarm()->IsSet());
- connection_.SendStreamDataWithString(1, data, offset, NO_FIN);
- offset += data_size;
- EXPECT_TRUE(connection_.sent_packet_manager().HasInFlightPackets());
- // The ping alarm is set for the ping timeout, not the shorter
- // retransmittable_on_wire_timeout.
- EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
- QuicTime::Delta ping_delay = QuicTime::Delta::FromSeconds(kPingTimeoutSecs);
- EXPECT_EQ(ping_delay,
- connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
-
- // Advance 5ms, send a second retransmittable packet to the peer.
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
- EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
- connection_.SendStreamDataWithString(1, data, offset, NO_FIN);
- offset += data_size;
- EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
-
- // Now receive an ACK of the first packet. This should not set the
- // retransmittable-on-wire alarm since packet 2 is still on the wire.
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
- QuicAckFrame frame =
- InitAckFrame({{QuicPacketNumber(1), QuicPacketNumber(2)}});
- ProcessAckPacket(&frame);
- EXPECT_TRUE(connection_.sent_packet_manager().HasInFlightPackets());
- // The ping alarm is set for the ping timeout, not the shorter
- // retransmittable_on_wire_timeout.
- EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
- // The ping alarm has a 1 second granularity, and the clock has been advanced
- // 10ms since it was originally set.
- EXPECT_EQ(ping_delay - QuicTime::Delta::FromMilliseconds(10),
- connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
-
- // Now receive an ACK of the second packet. This should set the
- // retransmittable-on-wire alarm now that no retransmittable packets are on
- // the wire.
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
- EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
- frame = InitAckFrame({{QuicPacketNumber(2), QuicPacketNumber(3)}});
- ProcessAckPacket(&frame);
- EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
- EXPECT_EQ(retransmittable_on_wire_timeout,
- connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
-
- // Now receive a duplicate ACK of the second packet. This should not update
- // the ping alarm.
- QuicTime prev_deadline = connection_.GetPingAlarm()->deadline();
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
- frame = InitAckFrame({{QuicPacketNumber(2), QuicPacketNumber(3)}});
- ProcessAckPacket(&frame);
- EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
- EXPECT_EQ(prev_deadline, connection_.GetPingAlarm()->deadline());
-
- // Now receive a non-ACK packet. This should not update the ping alarm.
- prev_deadline = connection_.GetPingAlarm()->deadline();
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
- ProcessPacket(4);
- EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
- EXPECT_EQ(prev_deadline, connection_.GetPingAlarm()->deadline());
-
- // Simulate the alarm firing and check that a PING is sent.
- connection_.GetPingAlarm()->Fire();
- size_t padding_frame_count = writer_->padding_frames().size();
- if (GetParam().no_stop_waiting) {
- EXPECT_EQ(padding_frame_count + 2u, writer_->frame_count());
- } else {
- EXPECT_EQ(padding_frame_count + 3u, writer_->frame_count());
- }
- ASSERT_EQ(1u, writer_->ping_frames().size());
-}
-
-TEST_P(QuicConnectionTest, NoPingIfRetransmittablePacketSent) {
- const QuicTime::Delta retransmittable_on_wire_timeout =
- QuicTime::Delta::FromMilliseconds(50);
- connection_.set_initial_retransmittable_on_wire_timeout(
- retransmittable_on_wire_timeout);
-
- EXPECT_TRUE(connection_.connected());
- EXPECT_CALL(visitor_, ShouldKeepConnectionAlive())
- .WillRepeatedly(Return(true));
-
- const char data[] = "data";
- size_t data_size = strlen(data);
- QuicStreamOffset offset = 0;
-
- // Advance 5ms, send a retransmittable packet to the peer.
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
- EXPECT_FALSE(connection_.GetPingAlarm()->IsSet());
- connection_.SendStreamDataWithString(1, data, offset, NO_FIN);
- offset += data_size;
- EXPECT_TRUE(connection_.sent_packet_manager().HasInFlightPackets());
- // The ping alarm is set for the ping timeout, not the shorter
- // retransmittable_on_wire_timeout.
- EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
- QuicTime::Delta ping_delay = QuicTime::Delta::FromSeconds(kPingTimeoutSecs);
- EXPECT_EQ(ping_delay,
- connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
-
- // Now receive an ACK of the first packet. This should set the
- // retransmittable-on-wire alarm now that no retransmittable packets are on
- // the wire.
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
- QuicAckFrame frame =
- InitAckFrame({{QuicPacketNumber(1), QuicPacketNumber(2)}});
- ProcessAckPacket(&frame);
- EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
- EXPECT_EQ(retransmittable_on_wire_timeout,
- connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
-
- // Before the alarm fires, send another retransmittable packet. This should
- // cancel the retransmittable-on-wire alarm since now there's a
- // retransmittable packet on the wire.
- connection_.SendStreamDataWithString(1, data, offset, NO_FIN);
- offset += data_size;
- EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
-
- // Now receive an ACK of the second packet. This should set the
- // retransmittable-on-wire alarm now that no retransmittable packets are on
- // the wire.
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
- EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
- frame = InitAckFrame({{QuicPacketNumber(2), QuicPacketNumber(3)}});
- ProcessAckPacket(&frame);
- EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
- EXPECT_EQ(retransmittable_on_wire_timeout,
- connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
-
- // Simulate the alarm firing and check that a PING is sent.
- writer_->Reset();
- connection_.GetPingAlarm()->Fire();
- size_t padding_frame_count = writer_->padding_frames().size();
- if (GetParam().no_stop_waiting) {
- // Do not ACK acks.
- EXPECT_EQ(padding_frame_count + 1u, writer_->frame_count());
- } else {
- EXPECT_EQ(padding_frame_count + 3u, writer_->frame_count());
- }
- ASSERT_EQ(1u, writer_->ping_frames().size());
-}
-
-// When there is no stream data received but are open streams, send the
-// first few consecutive pings with aggressive retransmittable-on-wire
-// timeout. Exponentially back off the retransmittable-on-wire ping timeout
-// afterwards until it exceeds the default ping timeout.
-TEST_P(QuicConnectionTest, BackOffRetransmittableOnWireTimeout) {
- int max_aggressive_retransmittable_on_wire_ping_count = 5;
- SetQuicFlag(FLAGS_quic_max_aggressive_retransmittable_on_wire_ping_count,
- max_aggressive_retransmittable_on_wire_ping_count);
- const QuicTime::Delta initial_retransmittable_on_wire_timeout =
- QuicTime::Delta::FromMilliseconds(200);
- connection_.set_initial_retransmittable_on_wire_timeout(
- initial_retransmittable_on_wire_timeout);
-
- EXPECT_TRUE(connection_.connected());
- EXPECT_CALL(visitor_, ShouldKeepConnectionAlive())
- .WillRepeatedly(Return(true));
-
- const char data[] = "data";
- // Advance 5ms, send a retransmittable data packet to the peer.
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
- EXPECT_FALSE(connection_.GetPingAlarm()->IsSet());
- connection_.SendStreamDataWithString(1, data, 0, NO_FIN);
- EXPECT_TRUE(connection_.sent_packet_manager().HasInFlightPackets());
- // The ping alarm is set for the ping timeout, not the shorter
- // retransmittable_on_wire_timeout.
- EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
- EXPECT_EQ(connection_.ping_timeout(),
- connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
-
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_)).Times(AnyNumber());
- EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _))
- .Times(AnyNumber());
-
- // Verify that the first few consecutive retransmittable on wire pings are
- // sent with aggressive timeout.
- for (int i = 0; i <= max_aggressive_retransmittable_on_wire_ping_count; i++) {
- // Receive an ACK of the previous packet. This should set the ping alarm
- // with the initial retransmittable-on-wire timeout.
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
- QuicPacketNumber ack_num = creator_->packet_number();
- QuicAckFrame frame = InitAckFrame(
- {{QuicPacketNumber(ack_num), QuicPacketNumber(ack_num + 1)}});
- ProcessAckPacket(&frame);
- EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
- EXPECT_EQ(initial_retransmittable_on_wire_timeout,
- connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
- // Simulate the alarm firing and check that a PING is sent.
- writer_->Reset();
- clock_.AdvanceTime(initial_retransmittable_on_wire_timeout);
- connection_.GetPingAlarm()->Fire();
- }
-
- QuicTime::Delta retransmittable_on_wire_timeout =
- initial_retransmittable_on_wire_timeout;
-
- // Verify subsequent pings are sent with timeout that is exponentially backed
- // off.
- while (retransmittable_on_wire_timeout * 2 < connection_.ping_timeout()) {
- // 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;
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
- QuicPacketNumber ack_num = creator_->packet_number();
- QuicAckFrame frame = InitAckFrame(
- {{QuicPacketNumber(ack_num), QuicPacketNumber(ack_num + 1)}});
- ProcessAckPacket(&frame);
- EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
- EXPECT_EQ(retransmittable_on_wire_timeout,
- connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
-
- // Simulate the alarm firing and check that a PING is sent.
- writer_->Reset();
- clock_.AdvanceTime(retransmittable_on_wire_timeout);
- connection_.GetPingAlarm()->Fire();
- }
-
- // The ping alarm is set with default ping timeout.
- EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
- EXPECT_EQ(connection_.ping_timeout(),
- connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
-
- // Receive an ACK for the previous PING. The ping alarm is set with an
- // earlier deadline.
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
- QuicPacketNumber ack_num = creator_->packet_number();
- QuicAckFrame frame = InitAckFrame(
- {{QuicPacketNumber(ack_num), QuicPacketNumber(ack_num + 1)}});
- ProcessAckPacket(&frame);
- EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
- EXPECT_EQ(connection_.ping_timeout() - QuicTime::Delta::FromMilliseconds(5),
- connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
-}
-
-// This test verify that the count of consecutive aggressive pings is reset
-// when new data is received. And it also verifies the connection resets
-// the exponential back-off of the retransmittable-on-wire ping timeout
-// after receiving new stream data.
-TEST_P(QuicConnectionTest, ResetBackOffRetransmitableOnWireTimeout) {
- int max_aggressive_retransmittable_on_wire_ping_count = 3;
- SetQuicFlag(FLAGS_quic_max_aggressive_retransmittable_on_wire_ping_count, 3);
- const QuicTime::Delta initial_retransmittable_on_wire_timeout =
- QuicTime::Delta::FromMilliseconds(200);
- connection_.set_initial_retransmittable_on_wire_timeout(
- initial_retransmittable_on_wire_timeout);
-
- EXPECT_TRUE(connection_.connected());
- EXPECT_CALL(visitor_, ShouldKeepConnectionAlive())
- .WillRepeatedly(Return(true));
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_)).Times(AnyNumber());
- EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _))
- .Times(AnyNumber());
-
- const char data[] = "data";
- // Advance 5ms, send a retransmittable data packet to the peer.
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
- EXPECT_FALSE(connection_.GetPingAlarm()->IsSet());
- connection_.SendStreamDataWithString(1, data, 0, NO_FIN);
- EXPECT_TRUE(connection_.sent_packet_manager().HasInFlightPackets());
- // The ping alarm is set for the ping timeout, not the shorter
- // retransmittable_on_wire_timeout.
- EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
- EXPECT_EQ(connection_.ping_timeout(),
- connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
-
- // Receive an ACK of the first packet. This should set the ping alarm with
- // initial retransmittable-on-wire timeout since there is no retransmittable
- // packet on the wire.
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
- QuicAckFrame frame =
- InitAckFrame({{QuicPacketNumber(1), QuicPacketNumber(2)}});
- ProcessAckPacket(&frame);
- EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
- EXPECT_EQ(initial_retransmittable_on_wire_timeout,
- connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
-
- // Simulate the alarm firing and check that a PING is sent.
- writer_->Reset();
- clock_.AdvanceTime(initial_retransmittable_on_wire_timeout);
- connection_.GetPingAlarm()->Fire();
-
- // Receive an ACK for the previous PING. Ping alarm will be set with
- // aggressive timeout.
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
- QuicPacketNumber ack_num = creator_->packet_number();
- frame = InitAckFrame(
- {{QuicPacketNumber(ack_num), QuicPacketNumber(ack_num + 1)}});
- ProcessAckPacket(&frame);
- EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
- EXPECT_EQ(initial_retransmittable_on_wire_timeout,
- connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
-
- // Process a data packet.
- EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
- ProcessDataPacket(peer_creator_.packet_number() + 1);
- QuicPacketCreatorPeer::SetPacketNumber(&peer_creator_,
- peer_creator_.packet_number() + 1);
- EXPECT_EQ(initial_retransmittable_on_wire_timeout,
- connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
-
- // Verify the count of consecutive aggressive pings is reset.
- for (int i = 0; i < max_aggressive_retransmittable_on_wire_ping_count; i++) {
- // Receive an ACK of the previous packet. This should set the ping alarm
- // with the initial retransmittable-on-wire timeout.
- QuicPacketNumber ack_num = creator_->packet_number();
- QuicAckFrame frame = InitAckFrame(
- {{QuicPacketNumber(ack_num), QuicPacketNumber(ack_num + 1)}});
- ProcessAckPacket(&frame);
- EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
- EXPECT_EQ(initial_retransmittable_on_wire_timeout,
- connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
- // Simulate the alarm firing and check that a PING is sent.
- writer_->Reset();
- clock_.AdvanceTime(initial_retransmittable_on_wire_timeout);
- connection_.GetPingAlarm()->Fire();
- // Advance 5ms to receive next packet.
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
- }
-
- // Receive another ACK for the previous PING. This should set the
- // ping alarm with backed off retransmittable-on-wire timeout.
- ack_num = creator_->packet_number();
- frame = InitAckFrame(
- {{QuicPacketNumber(ack_num), QuicPacketNumber(ack_num + 1)}});
- ProcessAckPacket(&frame);
- EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
- EXPECT_EQ(initial_retransmittable_on_wire_timeout * 2,
- connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
-
- writer_->Reset();
- clock_.AdvanceTime(2 * initial_retransmittable_on_wire_timeout);
- connection_.GetPingAlarm()->Fire();
-
- // Process another data packet and a new ACK packet. The ping alarm is set
- // with aggressive ping timeout again.
- EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
- ProcessDataPacket(peer_creator_.packet_number() + 1);
- QuicPacketCreatorPeer::SetPacketNumber(&peer_creator_,
- peer_creator_.packet_number() + 1);
- ack_num = creator_->packet_number();
- frame = InitAckFrame(
- {{QuicPacketNumber(ack_num), QuicPacketNumber(ack_num + 1)}});
- ProcessAckPacket(&frame);
- EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
- EXPECT_EQ(initial_retransmittable_on_wire_timeout,
- connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
-}
-
-// Make sure that we never send more retransmissible on the wire pings than
-// the limit in FLAGS_quic_max_retransmittable_on_wire_ping_count.
-TEST_P(QuicConnectionTest, RetransmittableOnWirePingLimit) {
- static constexpr int kMaxRetransmittableOnWirePingCount = 3;
- SetQuicFlag(FLAGS_quic_max_retransmittable_on_wire_ping_count,
- kMaxRetransmittableOnWirePingCount);
- static constexpr QuicTime::Delta initial_retransmittable_on_wire_timeout =
- QuicTime::Delta::FromMilliseconds(200);
- static constexpr QuicTime::Delta short_delay =
- QuicTime::Delta::FromMilliseconds(5);
- ASSERT_LT(short_delay * 10, initial_retransmittable_on_wire_timeout);
- connection_.set_initial_retransmittable_on_wire_timeout(
- initial_retransmittable_on_wire_timeout);
-
- EXPECT_TRUE(connection_.connected());
- EXPECT_CALL(visitor_, ShouldKeepConnectionAlive())
- .WillRepeatedly(Return(true));
-
- const char data[] = "data";
- // Advance 5ms, send a retransmittable data packet to the peer.
- clock_.AdvanceTime(short_delay);
- EXPECT_FALSE(connection_.GetPingAlarm()->IsSet());
- connection_.SendStreamDataWithString(1, data, 0, NO_FIN);
- EXPECT_TRUE(connection_.sent_packet_manager().HasInFlightPackets());
- // The ping alarm is set for the ping timeout, not the shorter
- // retransmittable_on_wire_timeout.
- EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
- EXPECT_EQ(connection_.ping_timeout(),
- connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
-
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_)).Times(AnyNumber());
- EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _))
- .Times(AnyNumber());
-
- // Verify that the first few consecutive retransmittable on wire pings are
- // sent with aggressive timeout.
- for (int i = 0; i <= kMaxRetransmittableOnWirePingCount; i++) {
- // Receive an ACK of the previous packet. This should set the ping alarm
- // with the initial retransmittable-on-wire timeout.
- clock_.AdvanceTime(short_delay);
- QuicPacketNumber ack_num = creator_->packet_number();
- QuicAckFrame frame = InitAckFrame(
- {{QuicPacketNumber(ack_num), QuicPacketNumber(ack_num + 1)}});
- ProcessAckPacket(&frame);
- EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
- EXPECT_EQ(initial_retransmittable_on_wire_timeout,
- connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
- // Simulate the alarm firing and check that a PING is sent.
- writer_->Reset();
- clock_.AdvanceTime(initial_retransmittable_on_wire_timeout);
- connection_.GetPingAlarm()->Fire();
- }
-
- // Receive an ACK of the previous packet. This should set the ping alarm
- // but this time with the default ping timeout.
- QuicPacketNumber ack_num = creator_->packet_number();
- QuicAckFrame frame = InitAckFrame(
- {{QuicPacketNumber(ack_num), QuicPacketNumber(ack_num + 1)}});
- ProcessAckPacket(&frame);
- EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
- EXPECT_EQ(connection_.ping_timeout(),
- connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
-}
-
-TEST_P(QuicConnectionTest, ValidStatelessResetToken) {
- const StatelessResetToken kTestToken{0, 1, 0, 1, 0, 1, 0, 1,
- 0, 1, 0, 1, 0, 1, 0, 1};
- const StatelessResetToken kWrongTestToken{0, 1, 0, 1, 0, 1, 0, 1,
- 0, 1, 0, 1, 0, 1, 0, 2};
- QuicConfig config;
- // No token has been received.
- EXPECT_FALSE(connection_.IsValidStatelessResetToken(kTestToken));
-
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _)).Times(2);
- // Token is different from received token.
- QuicConfigPeer::SetReceivedStatelessResetToken(&config, kTestToken);
- connection_.SetFromConfig(config);
- EXPECT_FALSE(connection_.IsValidStatelessResetToken(kWrongTestToken));
-
- QuicConfigPeer::SetReceivedStatelessResetToken(&config, kTestToken);
- connection_.SetFromConfig(config);
- EXPECT_TRUE(connection_.IsValidStatelessResetToken(kTestToken));
-}
-
-TEST_P(QuicConnectionTest, WriteBlockedWithInvalidAck) {
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- EXPECT_CALL(visitor_, OnConnectionClosed(_, _)).Times(0);
- BlockOnNextWrite();
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
- connection_.SendStreamDataWithString(5, "foo", 0, FIN);
- // This causes connection to be closed because packet 1 has not been sent yet.
- QuicAckFrame frame = InitAckFrame(1);
- EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _));
- ProcessAckPacket(1, &frame);
- EXPECT_EQ(0, connection_close_frame_count_);
-}
-
-TEST_P(QuicConnectionTest, SendMessage) {
- if (!VersionSupportsMessageFrames(connection_.transport_version())) {
- return;
- }
- if (connection_.version().UsesTls()) {
- QuicConfig config;
- QuicConfigPeer::SetReceivedMaxDatagramFrameSize(
- &config, kMaxAcceptedDatagramFrameSize);
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
- connection_.SetFromConfig(config);
- }
- std::string message(connection_.GetCurrentLargestMessagePayload() * 2, 'a');
- QuicMemSlice slice;
- {
- QuicConnection::ScopedPacketFlusher flusher(&connection_);
- connection_.SendStreamData3();
- // Send a message which cannot fit into current open packet, and 2 packets
- // get sent, one contains stream frame, and the other only contains the
- // message frame.
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(2);
- slice = MemSliceFromString(absl::string_view(
- message.data(), connection_.GetCurrentLargestMessagePayload()));
- EXPECT_EQ(MESSAGE_STATUS_SUCCESS,
- connection_.SendMessage(1, absl::MakeSpan(&slice, 1), false));
- }
- // Fail to send a message if connection is congestion control blocked.
- EXPECT_CALL(*send_algorithm_, CanSend(_)).WillOnce(Return(false));
- slice = MemSliceFromString("message");
- EXPECT_EQ(MESSAGE_STATUS_BLOCKED,
- connection_.SendMessage(2, absl::MakeSpan(&slice, 1), false));
-
- // Always fail to send a message which cannot fit into one packet.
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
- slice = MemSliceFromString(absl::string_view(
- message.data(), connection_.GetCurrentLargestMessagePayload() + 1));
- EXPECT_EQ(MESSAGE_STATUS_TOO_LARGE,
- connection_.SendMessage(3, absl::MakeSpan(&slice, 1), false));
-}
-
-TEST_P(QuicConnectionTest, GetCurrentLargestMessagePayload) {
- if (!connection_.version().SupportsMessageFrames()) {
- return;
- }
- // Force use of this encrypter to simplify test expectations by making sure
- // that the encryption overhead is constant across versions.
- connection_.SetEncrypter(ENCRYPTION_INITIAL,
- std::make_unique<TaggingEncrypter>(0x00));
- QuicPacketLength expected_largest_payload = 1219;
- if (connection_.version().SendsVariableLengthPacketNumberInLongHeader()) {
- expected_largest_payload += 3;
- }
- if (connection_.version().HasLongHeaderLengths()) {
- expected_largest_payload -= 2;
- }
- if (connection_.version().HasLengthPrefixedConnectionIds()) {
- expected_largest_payload -= 1;
- }
- if (connection_.version().UsesTls()) {
- // QUIC+TLS disallows DATAGRAM/MESSAGE frames before the handshake.
- EXPECT_EQ(connection_.GetCurrentLargestMessagePayload(), 0);
- QuicConfig config;
- QuicConfigPeer::SetReceivedMaxDatagramFrameSize(
- &config, kMaxAcceptedDatagramFrameSize);
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
- connection_.SetFromConfig(config);
- // Verify the value post-handshake.
- EXPECT_EQ(connection_.GetCurrentLargestMessagePayload(),
- expected_largest_payload);
- } else {
- EXPECT_EQ(connection_.GetCurrentLargestMessagePayload(),
- expected_largest_payload);
- }
-}
-
-TEST_P(QuicConnectionTest, GetGuaranteedLargestMessagePayload) {
- if (!connection_.version().SupportsMessageFrames()) {
- return;
- }
- // Force use of this encrypter to simplify test expectations by making sure
- // that the encryption overhead is constant across versions.
- connection_.SetEncrypter(ENCRYPTION_INITIAL,
- std::make_unique<TaggingEncrypter>(0x00));
- QuicPacketLength expected_largest_payload = 1219;
- if (connection_.version().HasLongHeaderLengths()) {
- expected_largest_payload -= 2;
- }
- if (connection_.version().HasLengthPrefixedConnectionIds()) {
- expected_largest_payload -= 1;
- }
- if (connection_.version().UsesTls()) {
- // QUIC+TLS disallows DATAGRAM/MESSAGE frames before the handshake.
- EXPECT_EQ(connection_.GetGuaranteedLargestMessagePayload(), 0);
- QuicConfig config;
- QuicConfigPeer::SetReceivedMaxDatagramFrameSize(
- &config, kMaxAcceptedDatagramFrameSize);
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
- connection_.SetFromConfig(config);
- // Verify the value post-handshake.
- EXPECT_EQ(connection_.GetGuaranteedLargestMessagePayload(),
- expected_largest_payload);
- } else {
- EXPECT_EQ(connection_.GetGuaranteedLargestMessagePayload(),
- expected_largest_payload);
- }
-}
-
-TEST_P(QuicConnectionTest, LimitedLargestMessagePayload) {
- if (!connection_.version().SupportsMessageFrames() ||
- !connection_.version().UsesTls()) {
- return;
- }
- constexpr QuicPacketLength kFrameSizeLimit = 1000;
- constexpr QuicPacketLength kPayloadSizeLimit =
- kFrameSizeLimit - kQuicFrameTypeSize;
- // QUIC+TLS disallows DATAGRAM/MESSAGE frames before the handshake.
- EXPECT_EQ(connection_.GetCurrentLargestMessagePayload(), 0);
- EXPECT_EQ(connection_.GetGuaranteedLargestMessagePayload(), 0);
- QuicConfig config;
- QuicConfigPeer::SetReceivedMaxDatagramFrameSize(&config, kFrameSizeLimit);
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
- connection_.SetFromConfig(config);
- // Verify the value post-handshake.
- EXPECT_EQ(connection_.GetCurrentLargestMessagePayload(), kPayloadSizeLimit);
- EXPECT_EQ(connection_.GetGuaranteedLargestMessagePayload(),
- kPayloadSizeLimit);
-}
-
-// Test to check that the path challenge/path response logic works
-// correctly. This test is only for version-99
-TEST_P(QuicConnectionTest, ServerResponseToPathChallenge) {
- if (!VersionHasIetfQuicFrames(connection_.version().transport_version)) {
- return;
- }
- PathProbeTestInit(Perspective::IS_SERVER);
- QuicConnectionPeer::SetAddressValidated(&connection_);
- // First check if the server can send probing packet.
- QuicPacketCreatorPeer::SetSendVersionInPacket(creator_, false);
-
- // Create and send the probe request (PATH_CHALLENGE frame).
- // SendConnectivityProbingPacket ends up calling
- // TestPacketWriter::WritePacket() which in turns receives and parses the
- // packet by calling framer_.ProcessPacket() -- which in turn calls
- // SimpleQuicFramer::OnPathChallengeFrame(). SimpleQuicFramer saves
- // the packet in writer_->path_challenge_frames()
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
- connection_.SendConnectivityProbingPacket(writer_.get(),
- connection_.peer_address());
- // Save the random contents of the challenge for later comparison to the
- // response.
- ASSERT_GE(writer_->path_challenge_frames().size(), 1u);
- QuicPathFrameBuffer challenge_data =
- writer_->path_challenge_frames().front().data_buffer;
-
- // Normally, QuicConnection::OnPathChallengeFrame and OnPaddingFrame would be
- // called and it will perform actions to ensure that the rest of the protocol
- // is performed.
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
- EXPECT_TRUE(connection_.OnPathChallengeFrame(
- writer_->path_challenge_frames().front()));
- EXPECT_TRUE(connection_.OnPaddingFrame(writer_->padding_frames().front()));
- if (!connection_.send_path_response()) {
- connection_.SendConnectivityProbingResponsePacket(
- connection_.peer_address());
- }
- creator_->FlushCurrentPacket();
-
- // The final check is to ensure that the random data in the response matches
- // the random data from the challenge.
- EXPECT_EQ(1u, writer_->path_response_frames().size());
- EXPECT_EQ(0, memcmp(&challenge_data,
- &(writer_->path_response_frames().front().data_buffer),
- sizeof(challenge_data)));
-}
-
-TEST_P(QuicConnectionTest, ClientResponseToPathChallengeOnDefaulSocket) {
- if (!VersionHasIetfQuicFrames(connection_.version().transport_version) ||
- !connection_.send_path_response()) {
- return;
- }
- PathProbeTestInit(Perspective::IS_CLIENT);
- // First check if the client can send probing packet.
- QuicPacketCreatorPeer::SetSendVersionInPacket(creator_, false);
-
- // Create and send the probe request (PATH_CHALLENGE frame).
- // SendConnectivityProbingPacket ends up calling
- // TestPacketWriter::WritePacket() which in turns receives and parses the
- // packet by calling framer_.ProcessPacket() -- which in turn calls
- // SimpleQuicFramer::OnPathChallengeFrame(). SimpleQuicFramer saves
- // the packet in writer_->path_challenge_frames()
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
- connection_.SendConnectivityProbingPacket(writer_.get(),
- connection_.peer_address());
- // Save the random contents of the challenge for later validation against the
- // response.
- ASSERT_GE(writer_->path_challenge_frames().size(), 1u);
- QuicPathFrameBuffer challenge_data =
- writer_->path_challenge_frames().front().data_buffer;
-
- // Normally, QuicConnection::OnPathChallengeFrame would be
- // called and it will perform actions to ensure that the rest of the protocol
- // is performed.
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
- EXPECT_TRUE(connection_.OnPathChallengeFrame(
- writer_->path_challenge_frames().front()));
- EXPECT_TRUE(connection_.OnPaddingFrame(writer_->padding_frames().front()));
- creator_->FlushCurrentPacket();
-
- // The final check is to ensure that the random data in the response matches
- // the random data from the challenge.
- EXPECT_EQ(1u, writer_->path_response_frames().size());
- EXPECT_EQ(0, memcmp(&challenge_data,
- &(writer_->path_response_frames().front().data_buffer),
- sizeof(challenge_data)));
-}
-
-TEST_P(QuicConnectionTest, ClientResponseToPathChallengeOnAlternativeSocket) {
- if (!VersionHasIetfQuicFrames(connection_.version().transport_version) ||
- !connection_.use_path_validator()) {
- return;
- }
- PathProbeTestInit(Perspective::IS_CLIENT);
- QuicPacketCreatorPeer::SetSendVersionInPacket(creator_, false);
-
- QuicSocketAddress kNewSelfAddress(QuicIpAddress::Loopback6(), /*port=*/23456);
- TestPacketWriter new_writer(version(), &clock_, Perspective::IS_CLIENT);
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
- .Times(AtLeast(1u))
- .WillOnce(Invoke([&]() {
- EXPECT_EQ(1u, new_writer.packets_write_attempts());
- EXPECT_EQ(1u, new_writer.path_challenge_frames().size());
- EXPECT_EQ(1u, new_writer.padding_frames().size());
- EXPECT_EQ(kNewSelfAddress.host(),
- new_writer.last_write_source_address());
- }));
- bool success = false;
- connection_.ValidatePath(
- std::make_unique<TestQuicPathValidationContext>(
- kNewSelfAddress, connection_.peer_address(), &new_writer),
- std::make_unique<TestValidationResultDelegate>(
- &connection_, kNewSelfAddress, connection_.peer_address(), &success));
-
- // Receiving a PATH_CHALLENGE on the alternative path. Response to this
- // PATH_CHALLENGE should be sent via the alternative writer.
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
- .Times(AtLeast(1u))
- .WillOnce(Invoke([&]() {
- EXPECT_EQ(2u, new_writer.packets_write_attempts());
- EXPECT_EQ(1u, new_writer.path_response_frames().size());
- EXPECT_EQ(1u, new_writer.padding_frames().size());
- EXPECT_EQ(kNewSelfAddress.host(),
- new_writer.last_write_source_address());
- }));
- std::unique_ptr<SerializedPacket> probing_packet = ConstructProbingPacket();
- std::unique_ptr<QuicReceivedPacket> received(ConstructReceivedPacket(
- QuicEncryptedPacket(probing_packet->encrypted_buffer,
- probing_packet->encrypted_length),
- clock_.Now()));
- ProcessReceivedPacket(kNewSelfAddress, kPeerAddress, *received);
-
- QuicSocketAddress kNewerSelfAddress(QuicIpAddress::Loopback6(),
- /*port=*/34567);
- // Receiving a PATH_CHALLENGE on an unknown socket should be ignored.
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0u);
- ProcessReceivedPacket(kNewerSelfAddress, kPeerAddress, *received);
-}
-
-TEST_P(QuicConnectionTest,
- RestartPathDegradingDetectionAfterMigrationWithProbe) {
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- PathProbeTestInit(Perspective::IS_CLIENT);
-
- // Send data and verify the path degrading detection is set.
- const char data[] = "data";
- size_t data_size = strlen(data);
- QuicStreamOffset offset = 0;
- connection_.SendStreamDataWithString(1, data, offset, NO_FIN);
- offset += data_size;
-
- // Verify the path degrading detection is in progress.
- EXPECT_TRUE(connection_.PathDegradingDetectionInProgress());
- EXPECT_FALSE(connection_.IsPathDegrading());
- QuicTime ddl = connection_.GetBlackholeDetectorAlarm()->deadline();
-
- // Simulate the firing of path degrading.
- clock_.AdvanceTime(ddl - clock_.ApproximateNow());
- EXPECT_CALL(visitor_, OnPathDegrading()).Times(1);
- connection_.PathDegradingTimeout();
- EXPECT_TRUE(connection_.IsPathDegrading());
- EXPECT_FALSE(connection_.PathDegradingDetectionInProgress());
-
- if (!GetParam().version.HasIetfQuicFrames()) {
- // Simulate path degrading handling by sending a probe on an alternet path.
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
- TestPacketWriter probing_writer(version(), &clock_, Perspective::IS_CLIENT);
- connection_.SendConnectivityProbingPacket(&probing_writer,
- connection_.peer_address());
- // Verify that path degrading detection is not reset.
- EXPECT_FALSE(connection_.PathDegradingDetectionInProgress());
-
- // Simulate successful path degrading handling by receiving probe response.
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(20));
-
- EXPECT_CALL(visitor_,
- OnPacketReceived(_, _, /*is_connectivity_probe=*/true))
- .Times(1);
- const QuicSocketAddress kNewSelfAddress =
- QuicSocketAddress(QuicIpAddress::Loopback6(), /*port=*/23456);
-
- std::unique_ptr<SerializedPacket> probing_packet = ConstructProbingPacket();
- std::unique_ptr<QuicReceivedPacket> received(ConstructReceivedPacket(
- QuicEncryptedPacket(probing_packet->encrypted_buffer,
- probing_packet->encrypted_length),
- clock_.Now()));
- uint64_t num_probing_received =
- connection_.GetStats().num_connectivity_probing_received;
- ProcessReceivedPacket(kNewSelfAddress, kPeerAddress, *received);
-
- EXPECT_EQ(num_probing_received + 1,
- connection_.GetStats().num_connectivity_probing_received);
- EXPECT_EQ(kPeerAddress, connection_.peer_address());
- EXPECT_EQ(kPeerAddress, connection_.effective_peer_address());
- EXPECT_TRUE(connection_.IsPathDegrading());
- }
-
- // Verify new path degrading detection is activated.
- EXPECT_CALL(visitor_, OnForwardProgressMadeAfterPathDegrading()).Times(1);
- connection_.OnSuccessfulMigration(/*is_port_change*/ true);
- EXPECT_FALSE(connection_.IsPathDegrading());
- EXPECT_TRUE(connection_.PathDegradingDetectionInProgress());
-}
-
-TEST_P(QuicConnectionTest, ClientsResetCwndAfterConnectionMigration) {
- if (!GetParam().version.HasIetfQuicFrames()) {
- return;
- }
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- PathProbeTestInit(Perspective::IS_CLIENT);
- EXPECT_EQ(kSelfAddress, connection_.self_address());
-
- RttStats* rtt_stats = const_cast<RttStats*>(manager_->GetRttStats());
- QuicTime::Delta default_init_rtt = rtt_stats->initial_rtt();
- 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());
- const SendAlgorithmInterface* send_algorithm = manager_->GetSendAlgorithm();
-
- // Migrate to a new address with different IP.
- const QuicSocketAddress kNewSelfAddress =
- QuicSocketAddress(QuicIpAddress::Loopback4(), /*port=*/23456);
- TestPacketWriter new_writer(version(), &clock_, Perspective::IS_CLIENT);
- 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_NE(send_algorithm, manager_->GetSendAlgorithm());
-}
-
-// Regression test for b/110259444
-TEST_P(QuicConnectionTest, DoNotScheduleSpuriousAckAlarm) {
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- EXPECT_CALL(visitor_, OnWriteBlocked()).Times(AtLeast(1));
- writer_->SetWriteBlocked();
-
- ProcessPacket(1);
- // Verify ack alarm is set.
- EXPECT_TRUE(connection_.HasPendingAcks());
- // Fire the ack alarm, verify no packet is sent because the writer is blocked.
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
- connection_.GetAckAlarm()->Fire();
-
- writer_->SetWritable();
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
- ProcessPacket(2);
- // Verify ack alarm is not set.
- EXPECT_FALSE(connection_.HasPendingAcks());
-}
-
-TEST_P(QuicConnectionTest, DisablePacingOffloadConnectionOptions) {
- EXPECT_FALSE(QuicConnectionPeer::SupportsReleaseTime(&connection_));
- writer_->set_supports_release_time(true);
- QuicConfig config;
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
- connection_.SetFromConfig(config);
- EXPECT_TRUE(QuicConnectionPeer::SupportsReleaseTime(&connection_));
-
- QuicTagVector connection_options;
- connection_options.push_back(kNPCO);
- config.SetConnectionOptionsToSend(connection_options);
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
- connection_.SetFromConfig(config);
- // Verify pacing offload is disabled.
- EXPECT_FALSE(QuicConnectionPeer::SupportsReleaseTime(&connection_));
-}
-
-// Regression test for b/110259444
-// Get a path response without having issued a path challenge...
-TEST_P(QuicConnectionTest, OrphanPathResponse) {
- QuicPathFrameBuffer data = {{0, 1, 2, 3, 4, 5, 6, 7}};
-
- QuicPathResponseFrame frame(99, data);
- EXPECT_TRUE(connection_.OnPathResponseFrame(frame));
- // If PATH_RESPONSE was accepted (payload matches the payload saved
- // in QuicConnection::transmitted_connectivity_probe_payload_) then
- // current_packet_content_ would be set to FIRST_FRAME_IS_PING.
- // Since this PATH_RESPONSE does not match, current_packet_content_
- // must not be FIRST_FRAME_IS_PING.
- EXPECT_NE(QuicConnection::FIRST_FRAME_IS_PING,
- QuicConnectionPeer::GetCurrentPacketContent(&connection_));
-}
-
-// Regression test for b/120791670
-TEST_P(QuicConnectionTest, StopProcessingGQuicPacketInIetfQuicConnection) {
- // This test mimics a problematic scenario where a QUIC connection using a
- // modern version received a Q043 packet and processed it incorrectly.
- // We can remove this test once Q043 is deprecated.
- if (!version().HasIetfInvariantHeader()) {
- return;
- }
- set_perspective(Perspective::IS_SERVER);
- if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
- EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(1);
- } else {
- EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
- }
- ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress, kPeerAddress,
- ENCRYPTION_INITIAL);
-
- // Let connection process a Google QUIC packet.
- peer_framer_.set_version_for_tests(ParsedQuicVersion::Q043());
- std::unique_ptr<QuicPacket> packet(
- ConstructDataPacket(2, !kHasStopWaiting, ENCRYPTION_INITIAL));
- char buffer[kMaxOutgoingPacketSize];
- size_t encrypted_length =
- peer_framer_.EncryptPayload(ENCRYPTION_INITIAL, QuicPacketNumber(2),
- *packet, buffer, kMaxOutgoingPacketSize);
- // Make sure no stream frame is processed.
- EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(0);
- connection_.ProcessUdpPacket(
- kSelfAddress, kPeerAddress,
- QuicReceivedPacket(buffer, encrypted_length, clock_.Now(), false));
-
- EXPECT_EQ(2u, connection_.GetStats().packets_received);
- EXPECT_EQ(1u, connection_.GetStats().packets_processed);
-}
-
-TEST_P(QuicConnectionTest, AcceptPacketNumberZero) {
- if (!VersionHasIetfQuicFrames(version().transport_version)) {
- return;
- }
- // Set first_sending_packet_number to be 0 to allow successfully processing
- // acks which ack packet number 0.
- QuicFramerPeer::SetFirstSendingPacketNumber(writer_->framer()->framer(), 0);
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-
- ProcessPacket(0);
- EXPECT_EQ(QuicPacketNumber(0), LargestAcked(connection_.ack_frame()));
- EXPECT_EQ(1u, connection_.ack_frame().packets.NumIntervals());
-
- ProcessPacket(1);
- EXPECT_EQ(QuicPacketNumber(1), LargestAcked(connection_.ack_frame()));
- EXPECT_EQ(1u, connection_.ack_frame().packets.NumIntervals());
-
- ProcessPacket(2);
- EXPECT_EQ(QuicPacketNumber(2), LargestAcked(connection_.ack_frame()));
- EXPECT_EQ(1u, connection_.ack_frame().packets.NumIntervals());
-}
-
-TEST_P(QuicConnectionTest, MultiplePacketNumberSpacesBasicSending) {
- if (!connection_.SupportsMultiplePacketNumberSpaces()) {
- return;
- }
- use_tagging_decrypter();
- connection_.SetEncrypter(ENCRYPTION_INITIAL,
- std::make_unique<TaggingEncrypter>(0x01));
-
- connection_.SendCryptoStreamData();
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _));
- EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
- QuicAckFrame frame1 = InitAckFrame(1);
- // Received ACK for packet 1.
- ProcessFramePacketAtLevel(30, QuicFrame(&frame1), ENCRYPTION_INITIAL);
-
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(4);
- connection_.SendApplicationDataAtLevel(ENCRYPTION_ZERO_RTT, 5, "data", 0,
- NO_FIN);
- connection_.SendApplicationDataAtLevel(ENCRYPTION_ZERO_RTT, 5, "data", 4,
- NO_FIN);
- connection_.SendApplicationDataAtLevel(ENCRYPTION_FORWARD_SECURE, 5, "data",
- 8, NO_FIN);
- connection_.SendApplicationDataAtLevel(ENCRYPTION_FORWARD_SECURE, 5, "data",
- 12, FIN);
- // Received ACK for packets 2, 4, 5.
- EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _));
- EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
- QuicAckFrame frame2 =
- InitAckFrame({{QuicPacketNumber(2), QuicPacketNumber(3)},
- {QuicPacketNumber(4), QuicPacketNumber(6)}});
- // Make sure although the same packet number is used, but they are in
- // different packet number spaces.
- ProcessFramePacketAtLevel(30, QuicFrame(&frame2), ENCRYPTION_FORWARD_SECURE);
-}
-
-TEST_P(QuicConnectionTest, PeerAcksPacketsInWrongPacketNumberSpace) {
- if (!connection_.SupportsMultiplePacketNumberSpaces()) {
- return;
- }
- use_tagging_decrypter();
- connection_.SetEncrypter(ENCRYPTION_INITIAL,
- std::make_unique<TaggingEncrypter>(0x01));
- connection_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
- std::make_unique<TaggingEncrypter>(0x01));
-
- connection_.SendCryptoStreamData();
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _));
- EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
- QuicAckFrame frame1 = InitAckFrame(1);
- // Received ACK for packet 1.
- ProcessFramePacketAtLevel(30, QuicFrame(&frame1), ENCRYPTION_INITIAL);
-
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(2);
- connection_.SendApplicationDataAtLevel(ENCRYPTION_ZERO_RTT, 5, "data", 0,
- NO_FIN);
- connection_.SendApplicationDataAtLevel(ENCRYPTION_ZERO_RTT, 5, "data", 4,
- NO_FIN);
-
- // Received ACK for packets 2 and 3 in wrong packet number space.
- QuicAckFrame invalid_ack =
- InitAckFrame({{QuicPacketNumber(2), QuicPacketNumber(4)}});
- EXPECT_CALL(visitor_,
- OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF));
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AtLeast(1));
- ProcessFramePacketAtLevel(300, QuicFrame(&invalid_ack), ENCRYPTION_INITIAL);
- TestConnectionCloseQuicErrorCode(QUIC_INVALID_ACK_DATA);
-}
-
-TEST_P(QuicConnectionTest, MultiplePacketNumberSpacesBasicReceiving) {
- if (!connection_.SupportsMultiplePacketNumberSpaces()) {
- return;
- }
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
- EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
- }
- EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber());
- use_tagging_decrypter();
- // Receives packet 1000 in initial data.
- ProcessCryptoPacketAtLevel(1000, ENCRYPTION_INITIAL);
- EXPECT_TRUE(connection_.HasPendingAcks());
- peer_framer_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
- std::make_unique<TaggingEncrypter>(0x02));
- SetDecrypter(ENCRYPTION_FORWARD_SECURE,
- std::make_unique<StrictTaggingDecrypter>(0x02));
- connection_.SetEncrypter(ENCRYPTION_INITIAL,
- std::make_unique<TaggingEncrypter>(0x02));
- // Receives packet 1000 in application data.
- ProcessDataPacketAtLevel(1000, false, ENCRYPTION_FORWARD_SECURE);
- EXPECT_TRUE(connection_.HasPendingAcks());
- connection_.SendApplicationDataAtLevel(ENCRYPTION_FORWARD_SECURE, 5, "data",
- 0, NO_FIN);
- // Verify application data ACK gets bundled with outgoing data.
- EXPECT_EQ(2u, writer_->frame_count());
- // Make sure ACK alarm is still set because initial data is not ACKed.
- EXPECT_TRUE(connection_.HasPendingAcks());
- // Receive packet 1001 in application data.
- ProcessDataPacketAtLevel(1001, false, ENCRYPTION_FORWARD_SECURE);
- clock_.AdvanceTime(DefaultRetransmissionTime());
- // Simulates ACK alarm fires and verify two ACKs are flushed.
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(2);
- connection_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
- std::make_unique<TaggingEncrypter>(0x02));
- connection_.GetAckAlarm()->Fire();
- EXPECT_FALSE(connection_.HasPendingAcks());
- // Receives more packets in application data.
- ProcessDataPacketAtLevel(1002, false, ENCRYPTION_FORWARD_SECURE);
- EXPECT_TRUE(connection_.HasPendingAcks());
-
- // Verify zero rtt and forward secure packets get acked in the same packet.
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
- ProcessDataPacket(1003);
- EXPECT_FALSE(connection_.HasPendingAcks());
-}
-
-TEST_P(QuicConnectionTest, CancelAckAlarmOnWriteBlocked) {
- if (!connection_.SupportsMultiplePacketNumberSpaces()) {
- return;
- }
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
- EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
- }
- EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber());
- use_tagging_decrypter();
- // Receives packet 1000 in initial data.
- ProcessCryptoPacketAtLevel(1000, ENCRYPTION_INITIAL);
- EXPECT_TRUE(connection_.HasPendingAcks());
- peer_framer_.SetEncrypter(ENCRYPTION_ZERO_RTT,
- std::make_unique<TaggingEncrypter>(0x02));
- SetDecrypter(ENCRYPTION_ZERO_RTT,
- std::make_unique<StrictTaggingDecrypter>(0x02));
- connection_.SetEncrypter(ENCRYPTION_INITIAL,
- std::make_unique<TaggingEncrypter>(0x02));
- // Receives packet 1000 in application data.
- ProcessDataPacketAtLevel(1000, false, ENCRYPTION_ZERO_RTT);
- EXPECT_TRUE(connection_.HasPendingAcks());
-
- writer_->SetWriteBlocked();
- EXPECT_CALL(visitor_, OnWriteBlocked()).Times(AnyNumber());
- // Simulates ACK alarm fires and verify no ACK is flushed because of write
- // blocked.
- clock_.AdvanceTime(DefaultDelayedAckTime());
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
- connection_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
- std::make_unique<TaggingEncrypter>(0x02));
- connection_.GetAckAlarm()->Fire();
- // Verify ACK alarm is not set.
- EXPECT_FALSE(connection_.HasPendingAcks());
-
- writer_->SetWritable();
- // Verify 2 ACKs are sent when connection gets unblocked.
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(2);
- connection_.OnCanWrite();
- EXPECT_FALSE(connection_.HasPendingAcks());
-}
-
-// Make sure a packet received with the right client connection ID is processed.
-TEST_P(QuicConnectionTest, ValidClientConnectionId) {
- if (!framer_.version().SupportsClientConnectionIds()) {
- return;
- }
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- SetClientConnectionId(TestConnectionId(0x33));
- QuicPacketHeader header = ConstructPacketHeader(1, ENCRYPTION_FORWARD_SECURE);
- header.destination_connection_id = TestConnectionId(0x33);
- header.destination_connection_id_included = CONNECTION_ID_PRESENT;
- header.source_connection_id_included = CONNECTION_ID_ABSENT;
- QuicFrames frames;
- QuicPingFrame ping_frame;
- QuicPaddingFrame padding_frame;
- frames.push_back(QuicFrame(ping_frame));
- frames.push_back(QuicFrame(padding_frame));
- std::unique_ptr<QuicPacket> packet =
- BuildUnsizedDataPacket(&peer_framer_, header, frames);
- char buffer[kMaxOutgoingPacketSize];
- size_t encrypted_length = peer_framer_.EncryptPayload(
- ENCRYPTION_FORWARD_SECURE, QuicPacketNumber(1), *packet, buffer,
- kMaxOutgoingPacketSize);
- QuicReceivedPacket received_packet(buffer, encrypted_length, clock_.Now(),
- false);
- EXPECT_EQ(0u, connection_.GetStats().packets_dropped);
- ProcessReceivedPacket(kSelfAddress, kPeerAddress, received_packet);
- EXPECT_EQ(0u, connection_.GetStats().packets_dropped);
-}
-
-// Make sure a packet received with a different client connection ID is dropped.
-TEST_P(QuicConnectionTest, InvalidClientConnectionId) {
- if (!framer_.version().SupportsClientConnectionIds()) {
- return;
- }
- SetClientConnectionId(TestConnectionId(0x33));
- QuicPacketHeader header = ConstructPacketHeader(1, ENCRYPTION_FORWARD_SECURE);
- header.destination_connection_id = TestConnectionId(0xbad);
- header.destination_connection_id_included = CONNECTION_ID_PRESENT;
- header.source_connection_id_included = CONNECTION_ID_ABSENT;
- QuicFrames frames;
- QuicPingFrame ping_frame;
- QuicPaddingFrame padding_frame;
- frames.push_back(QuicFrame(ping_frame));
- frames.push_back(QuicFrame(padding_frame));
- std::unique_ptr<QuicPacket> packet =
- BuildUnsizedDataPacket(&peer_framer_, header, frames);
- char buffer[kMaxOutgoingPacketSize];
- size_t encrypted_length = peer_framer_.EncryptPayload(
- ENCRYPTION_FORWARD_SECURE, QuicPacketNumber(1), *packet, buffer,
- kMaxOutgoingPacketSize);
- QuicReceivedPacket received_packet(buffer, encrypted_length, clock_.Now(),
- false);
- EXPECT_EQ(0u, connection_.GetStats().packets_dropped);
- ProcessReceivedPacket(kSelfAddress, kPeerAddress, received_packet);
- EXPECT_EQ(1u, connection_.GetStats().packets_dropped);
-}
-
-// Make sure the first packet received with a different client connection ID on
-// the server is processed and it changes the client connection ID.
-TEST_P(QuicConnectionTest, UpdateClientConnectionIdFromFirstPacket) {
- if (!framer_.version().SupportsClientConnectionIds()) {
- return;
- }
- set_perspective(Perspective::IS_SERVER);
- QuicPacketHeader header = ConstructPacketHeader(1, ENCRYPTION_INITIAL);
- header.source_connection_id = TestConnectionId(0x33);
- header.source_connection_id_included = CONNECTION_ID_PRESENT;
- QuicFrames frames;
- QuicPingFrame ping_frame;
- QuicPaddingFrame padding_frame;
- frames.push_back(QuicFrame(ping_frame));
- frames.push_back(QuicFrame(padding_frame));
- std::unique_ptr<QuicPacket> packet =
- BuildUnsizedDataPacket(&peer_framer_, header, frames);
- char buffer[kMaxOutgoingPacketSize];
- size_t encrypted_length =
- peer_framer_.EncryptPayload(ENCRYPTION_INITIAL, QuicPacketNumber(1),
- *packet, buffer, kMaxOutgoingPacketSize);
- QuicReceivedPacket received_packet(buffer, encrypted_length, clock_.Now(),
- false);
- EXPECT_EQ(0u, connection_.GetStats().packets_dropped);
- ProcessReceivedPacket(kSelfAddress, kPeerAddress, received_packet);
- EXPECT_EQ(0u, connection_.GetStats().packets_dropped);
- EXPECT_EQ(TestConnectionId(0x33), connection_.client_connection_id());
-}
-void QuicConnectionTest::TestReplaceConnectionIdFromInitial() {
- if (!framer_.version().AllowsVariableLengthConnectionIds()) {
- return;
- }
- // We start with a known connection ID.
- EXPECT_TRUE(connection_.connected());
- EXPECT_EQ(0u, connection_.GetStats().packets_dropped);
- EXPECT_NE(TestConnectionId(0x33), connection_.connection_id());
- // Receiving an initial can replace the connection ID once.
- {
- QuicPacketHeader header = ConstructPacketHeader(1, ENCRYPTION_INITIAL);
- header.source_connection_id = TestConnectionId(0x33);
- header.source_connection_id_included = CONNECTION_ID_PRESENT;
- QuicFrames frames;
- QuicPingFrame ping_frame;
- QuicPaddingFrame padding_frame;
- frames.push_back(QuicFrame(ping_frame));
- frames.push_back(QuicFrame(padding_frame));
- std::unique_ptr<QuicPacket> packet =
- BuildUnsizedDataPacket(&peer_framer_, header, frames);
- char buffer[kMaxOutgoingPacketSize];
- size_t encrypted_length =
- peer_framer_.EncryptPayload(ENCRYPTION_INITIAL, QuicPacketNumber(1),
- *packet, buffer, kMaxOutgoingPacketSize);
- QuicReceivedPacket received_packet(buffer, encrypted_length, clock_.Now(),
- false);
- ProcessReceivedPacket(kSelfAddress, kPeerAddress, received_packet);
- }
- EXPECT_TRUE(connection_.connected());
- EXPECT_EQ(0u, connection_.GetStats().packets_dropped);
- EXPECT_EQ(TestConnectionId(0x33), connection_.connection_id());
- // Trying to replace the connection ID a second time drops the packet.
- {
- QuicPacketHeader header = ConstructPacketHeader(2, ENCRYPTION_INITIAL);
- header.source_connection_id = TestConnectionId(0x66);
- header.source_connection_id_included = CONNECTION_ID_PRESENT;
- QuicFrames frames;
- QuicPingFrame ping_frame;
- QuicPaddingFrame padding_frame;
- frames.push_back(QuicFrame(ping_frame));
- frames.push_back(QuicFrame(padding_frame));
- std::unique_ptr<QuicPacket> packet =
- BuildUnsizedDataPacket(&peer_framer_, header, frames);
- char buffer[kMaxOutgoingPacketSize];
- size_t encrypted_length =
- peer_framer_.EncryptPayload(ENCRYPTION_INITIAL, QuicPacketNumber(2),
- *packet, buffer, kMaxOutgoingPacketSize);
- QuicReceivedPacket received_packet(buffer, encrypted_length, clock_.Now(),
- false);
- ProcessReceivedPacket(kSelfAddress, kPeerAddress, received_packet);
- }
- EXPECT_TRUE(connection_.connected());
- EXPECT_EQ(1u, connection_.GetStats().packets_dropped);
- EXPECT_EQ(TestConnectionId(0x33), connection_.connection_id());
-}
-
-TEST_P(QuicConnectionTest, ReplaceServerConnectionIdFromInitial) {
- TestReplaceConnectionIdFromInitial();
-}
-
-TEST_P(QuicConnectionTest, ReplaceServerConnectionIdFromRetryAndInitial) {
- // First make the connection process a RETRY and replace the server connection
- // ID a first time.
- TestClientRetryHandling(/*invalid_retry_tag=*/false,
- /*missing_original_id_in_config=*/false,
- /*wrong_original_id_in_config=*/false,
- /*missing_retry_id_in_config=*/false,
- /*wrong_retry_id_in_config=*/false);
- // Reset the test framer to use the right connection ID.
- peer_framer_.SetInitialObfuscators(connection_.connection_id());
- // Now process an INITIAL and replace the server connection ID a second time.
- TestReplaceConnectionIdFromInitial();
-}
-
-// Regression test for b/134416344.
-TEST_P(QuicConnectionTest, CheckConnectedBeforeFlush) {
- // This test mimics a scenario where a connection processes 2 packets and the
- // 2nd packet contains connection close frame. When the 2nd flusher goes out
- // of scope, a delayed ACK is pending, and ACK alarm should not be scheduled
- // because connection is disconnected.
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- EXPECT_CALL(visitor_, OnConnectionClosed(_, _));
- EXPECT_EQ(Perspective::IS_CLIENT, connection_.perspective());
- const QuicErrorCode kErrorCode = QUIC_INTERNAL_ERROR;
- std::unique_ptr<QuicConnectionCloseFrame> connection_close_frame(
- new QuicConnectionCloseFrame(connection_.transport_version(), kErrorCode,
- NO_IETF_QUIC_ERROR, "",
- /*transport_close_frame_type=*/0));
-
- // Received 2 packets.
- if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
- EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
- } else {
- EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber());
- }
- ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress, kPeerAddress,
- ENCRYPTION_INITIAL);
- EXPECT_TRUE(connection_.HasPendingAcks());
- ProcessFramePacketWithAddresses(QuicFrame(connection_close_frame.release()),
- kSelfAddress, kPeerAddress,
- ENCRYPTION_INITIAL);
- // Verify ack alarm is not set.
- EXPECT_FALSE(connection_.HasPendingAcks());
-}
-
-// Verify that a packet containing three coalesced packets is parsed correctly.
-TEST_P(QuicConnectionTest, CoalescedPacket) {
- if (!QuicVersionHasLongHeaderLengths(connection_.transport_version())) {
- // Coalesced packets can only be encoded using long header lengths.
- return;
- }
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- EXPECT_TRUE(connection_.connected());
- if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
- EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(3);
- } else {
- EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(3);
- }
-
- uint64_t packet_numbers[3] = {1, 2, 3};
- EncryptionLevel encryption_levels[3] = {
- ENCRYPTION_INITIAL, ENCRYPTION_INITIAL, ENCRYPTION_FORWARD_SECURE};
- char buffer[kMaxOutgoingPacketSize] = {};
- size_t total_encrypted_length = 0;
- for (int i = 0; i < 3; i++) {
- QuicPacketHeader header =
- ConstructPacketHeader(packet_numbers[i], encryption_levels[i]);
- QuicFrames frames;
- if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
- frames.push_back(QuicFrame(&crypto_frame_));
- } else {
- frames.push_back(QuicFrame(frame1_));
- }
- std::unique_ptr<QuicPacket> packet = ConstructPacket(header, frames);
- peer_creator_.set_encryption_level(encryption_levels[i]);
- size_t encrypted_length = peer_framer_.EncryptPayload(
- encryption_levels[i], QuicPacketNumber(packet_numbers[i]), *packet,
- buffer + total_encrypted_length,
- sizeof(buffer) - total_encrypted_length);
- EXPECT_GT(encrypted_length, 0u);
- total_encrypted_length += encrypted_length;
- }
- connection_.ProcessUdpPacket(
- kSelfAddress, kPeerAddress,
- QuicReceivedPacket(buffer, total_encrypted_length, clock_.Now(), false));
- if (connection_.GetSendAlarm()->IsSet()) {
- connection_.GetSendAlarm()->Fire();
- }
-
- EXPECT_TRUE(connection_.connected());
-}
-
-// Regression test for crbug.com/992831.
-TEST_P(QuicConnectionTest, CoalescedPacketThatSavesFrames) {
- if (!QuicVersionHasLongHeaderLengths(connection_.transport_version())) {
- // Coalesced packets can only be encoded using long header lengths.
- return;
- }
- if (connection_.SupportsMultiplePacketNumberSpaces()) {
- // TODO(b/129151114) Enable this test with multiple packet number spaces.
- return;
- }
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- EXPECT_TRUE(connection_.connected());
- if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
- EXPECT_CALL(visitor_, OnCryptoFrame(_))
- .Times(3)
- .WillRepeatedly([this](const QuicCryptoFrame& /*frame*/) {
- // QuicFrame takes ownership of the QuicBlockedFrame.
- connection_.SendControlFrame(QuicFrame(new QuicBlockedFrame(1, 3)));
- });
- } else {
- EXPECT_CALL(visitor_, OnStreamFrame(_))
- .Times(3)
- .WillRepeatedly([this](const QuicStreamFrame& /*frame*/) {
- // QuicFrame takes ownership of the QuicBlockedFrame.
- connection_.SendControlFrame(QuicFrame(new QuicBlockedFrame(1, 3)));
- });
- }
-
- uint64_t packet_numbers[3] = {1, 2, 3};
- EncryptionLevel encryption_levels[3] = {
- ENCRYPTION_INITIAL, ENCRYPTION_INITIAL, ENCRYPTION_FORWARD_SECURE};
- char buffer[kMaxOutgoingPacketSize] = {};
- size_t total_encrypted_length = 0;
- for (int i = 0; i < 3; i++) {
- QuicPacketHeader header =
- ConstructPacketHeader(packet_numbers[i], encryption_levels[i]);
- QuicFrames frames;
- if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
- frames.push_back(QuicFrame(&crypto_frame_));
- } else {
- frames.push_back(QuicFrame(frame1_));
- }
- std::unique_ptr<QuicPacket> packet = ConstructPacket(header, frames);
- peer_creator_.set_encryption_level(encryption_levels[i]);
- size_t encrypted_length = peer_framer_.EncryptPayload(
- encryption_levels[i], QuicPacketNumber(packet_numbers[i]), *packet,
- buffer + total_encrypted_length,
- sizeof(buffer) - total_encrypted_length);
- EXPECT_GT(encrypted_length, 0u);
- total_encrypted_length += encrypted_length;
- }
- connection_.ProcessUdpPacket(
- kSelfAddress, kPeerAddress,
- QuicReceivedPacket(buffer, total_encrypted_length, clock_.Now(), false));
- if (connection_.GetSendAlarm()->IsSet()) {
- connection_.GetSendAlarm()->Fire();
- }
-
- EXPECT_TRUE(connection_.connected());
-
- SendAckPacketToPeer();
-}
-
-// Regresstion test for b/138962304.
-TEST_P(QuicConnectionTest, RtoAndWriteBlocked) {
- EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
-
- QuicStreamId stream_id = 2;
- QuicPacketNumber last_data_packet;
- SendStreamDataToPeer(stream_id, "foo", 0, NO_FIN, &last_data_packet);
- EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
-
- // Writer gets blocked.
- writer_->SetWriteBlocked();
-
- // Cancel the stream.
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
- EXPECT_CALL(visitor_, OnWriteBlocked()).Times(AtLeast(1));
- EXPECT_CALL(visitor_, WillingAndAbleToWrite())
- .WillRepeatedly(
- Invoke(&notifier_, &SimpleSessionNotifier::WillingToWrite));
- SendRstStream(stream_id, QUIC_ERROR_PROCESSING_STREAM, 3);
-
- // Retransmission timer fires in RTO mode.
- connection_.GetRetransmissionAlarm()->Fire();
- // Verify no packets get flushed when writer is blocked.
- EXPECT_EQ(0u, connection_.NumQueuedPackets());
-}
-
-// Regresstion test for b/138962304.
-TEST_P(QuicConnectionTest, TlpAndWriteBlocked) {
- EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
- connection_.SetMaxTailLossProbes(1);
-
- QuicStreamId stream_id = 2;
- QuicPacketNumber last_data_packet;
- SendStreamDataToPeer(stream_id, "foo", 0, NO_FIN, &last_data_packet);
- SendStreamDataToPeer(4, "foo", 0, NO_FIN, &last_data_packet);
- EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
-
- // Writer gets blocked.
- writer_->SetWriteBlocked();
-
- // Cancel stream 2.
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
- EXPECT_CALL(visitor_, OnWriteBlocked()).Times(AtLeast(1));
- SendRstStream(stream_id, QUIC_ERROR_PROCESSING_STREAM, 3);
-
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
- // Retransmission timer fires in TLP mode.
- connection_.GetRetransmissionAlarm()->Fire();
- // Verify one packets is forced flushed when writer is blocked.
- 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;
- connection_options.push_back(k2PTO);
- config.SetConnectionOptionsToSend(connection_options);
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
- connection_.SetFromConfig(config);
- EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
-
- QuicStreamId stream_id = 2;
- QuicPacketNumber last_packet;
- SendStreamDataToPeer(stream_id, "foooooo", 0, NO_FIN, &last_packet);
- SendStreamDataToPeer(stream_id, "foooooo", 7, NO_FIN, &last_packet);
- EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
-
- // Reset stream.
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
- SendRstStream(stream_id, QUIC_ERROR_PROCESSING_STREAM, 3);
-
- // Fire the PTO and verify only the RST_STREAM is resent, not stream data.
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
- connection_.GetRetransmissionAlarm()->Fire();
- EXPECT_EQ(0u, writer_->stream_frames().size());
- EXPECT_EQ(1u, writer_->rst_stream_frames().size());
- EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
-}
-
-TEST_P(QuicConnectionTest, CloseConnectionAfter6ClientPTOs) {
- QuicConfig config;
- QuicTagVector connection_options;
- connection_options.push_back(k1PTO);
- connection_options.push_back(k6PTO);
- config.SetConnectionOptionsToSend(connection_options);
- QuicConfigPeer::SetNegotiated(&config, true);
- if (connection_.version().UsesTls()) {
- QuicConfigPeer::SetReceivedOriginalConnectionId(
- &config, connection_.connection_id());
- QuicConfigPeer::SetReceivedInitialSourceConnectionId(
- &config, connection_.connection_id());
- }
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
- connection_.SetFromConfig(config);
- if (GetQuicReloadableFlag(quic_default_enable_5rto_blackhole_detection2)) {
- EXPECT_CALL(visitor_, GetHandshakeState())
- .WillRepeatedly(Return(HANDSHAKE_CONFIRMED));
- }
- connection_.OnHandshakeComplete();
- EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
-
- // Send stream data.
- SendStreamDataToPeer(
- GetNthClientInitiatedStreamId(1, connection_.transport_version()), "foo",
- 0, FIN, nullptr);
-
- // Fire the retransmission alarm 5 times.
- for (int i = 0; i < 5; ++i) {
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
- connection_.GetRetransmissionAlarm()->Fire();
- EXPECT_TRUE(connection_.GetTimeoutAlarm()->IsSet());
- EXPECT_TRUE(connection_.connected());
- }
- 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.
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AtLeast(1));
- EXPECT_CALL(visitor_,
- OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF));
- ASSERT_TRUE(connection_.BlackholeDetectionInProgress());
- connection_.GetBlackholeDetectorAlarm()->Fire();
- EXPECT_FALSE(connection_.GetTimeoutAlarm()->IsSet());
- EXPECT_FALSE(connection_.connected());
- TestConnectionCloseQuicErrorCode(QUIC_TOO_MANY_RTOS);
-}
-
-TEST_P(QuicConnectionTest, CloseConnectionAfter7ClientPTOs) {
- QuicConfig config;
- QuicTagVector connection_options;
- connection_options.push_back(k2PTO);
- connection_options.push_back(k7PTO);
- config.SetConnectionOptionsToSend(connection_options);
- QuicConfigPeer::SetNegotiated(&config, true);
- if (connection_.version().UsesTls()) {
- QuicConfigPeer::SetReceivedOriginalConnectionId(
- &config, connection_.connection_id());
- QuicConfigPeer::SetReceivedInitialSourceConnectionId(
- &config, connection_.connection_id());
- }
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
- connection_.SetFromConfig(config);
- if (GetQuicReloadableFlag(quic_default_enable_5rto_blackhole_detection2)) {
- EXPECT_CALL(visitor_, GetHandshakeState())
- .WillRepeatedly(Return(HANDSHAKE_CONFIRMED));
- }
- connection_.OnHandshakeComplete();
- EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
-
- // Send stream data.
- SendStreamDataToPeer(
- GetNthClientInitiatedStreamId(1, connection_.transport_version()), "foo",
- 0, FIN, nullptr);
-
- // Fire the retransmission alarm 6 times.
- 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(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_,
- 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, CloseConnectionAfter8ClientPTOs) {
- QuicConfig config;
- QuicTagVector connection_options;
- connection_options.push_back(k2PTO);
- connection_options.push_back(k8PTO);
- QuicConfigPeer::SetNegotiated(&config, true);
- if (connection_.version().UsesTls()) {
- QuicConfigPeer::SetReceivedOriginalConnectionId(
- &config, connection_.connection_id());
- QuicConfigPeer::SetReceivedInitialSourceConnectionId(
- &config, connection_.connection_id());
- }
- config.SetConnectionOptionsToSend(connection_options);
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
- connection_.SetFromConfig(config);
- if (GetQuicReloadableFlag(quic_default_enable_5rto_blackhole_detection2)) {
- EXPECT_CALL(visitor_, GetHandshakeState())
- .WillRepeatedly(Return(HANDSHAKE_CONFIRMED));
- }
- connection_.OnHandshakeComplete();
- EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
-
- // Send stream data.
- SendStreamDataToPeer(
- GetNthClientInitiatedStreamId(1, connection_.transport_version()), "foo",
- 0, FIN, nullptr);
-
- // Fire the retransmission alarm 7 times.
- for (int i = 0; i < 7; ++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(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_,
- 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, DeprecateHandshakeMode) {
- if (!connection_.version().SupportsAntiAmplificationLimit()) {
- return;
- }
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
-
- // Send CHLO.
- connection_.SendCryptoStreamData();
- EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
-
- EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _));
- EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
- QuicAckFrame frame1 = InitAckFrame(1);
- // Received ACK for packet 1.
- ProcessFramePacketAtLevel(1, QuicFrame(&frame1), ENCRYPTION_INITIAL);
-
- // Verify retransmission alarm is still set because handshake is not
- // confirmed although there is nothing in flight.
- EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
- EXPECT_EQ(0u, connection_.GetStats().pto_count);
- EXPECT_EQ(0u, connection_.GetStats().crypto_retransmit_count);
-
- // PTO fires, verify a PING packet gets sent because there is no data to send.
- EXPECT_CALL(*send_algorithm_,
- OnPacketSent(_, _,
- GetQuicReloadableFlag(quic_default_on_pto)
- ? QuicPacketNumber(2)
- : QuicPacketNumber(3),
- _, _));
- connection_.GetRetransmissionAlarm()->Fire();
- EXPECT_EQ(1u, connection_.GetStats().pto_count);
- EXPECT_EQ(1u, connection_.GetStats().crypto_retransmit_count);
- EXPECT_EQ(1u, writer_->ping_frames().size());
-}
-
-TEST_P(QuicConnectionTest, AntiAmplificationLimit) {
- if (!connection_.version().SupportsAntiAmplificationLimit()) {
- return;
- }
- EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
-
- set_perspective(Perspective::IS_SERVER);
- // Verify no data can be sent at the beginning because bytes received is 0.
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
- connection_.SendCryptoDataWithString("foo", 0);
- EXPECT_FALSE(connection_.CanWrite(HAS_RETRANSMITTABLE_DATA));
- EXPECT_FALSE(connection_.CanWrite(NO_RETRANSMITTABLE_DATA));
- EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
-
- // Receives packet 1.
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
- ProcessCryptoPacketAtLevel(1, ENCRYPTION_INITIAL);
-
- const size_t anti_amplification_factor =
- GetQuicFlag(FLAGS_quic_anti_amplification_factor);
- // Verify now packets can be sent.
- for (size_t i = 1; i < anti_amplification_factor; ++i) {
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
- connection_.SendCryptoDataWithString("foo", i * 3);
- // Verify retransmission alarm is not set if throttled by anti-amplification
- // limit.
- EXPECT_EQ(i != anti_amplification_factor - 1,
- connection_.GetRetransmissionAlarm()->IsSet());
- }
- // Verify server is throttled by anti-amplification limit.
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
- connection_.SendCryptoDataWithString("foo", anti_amplification_factor * 3);
-
- // Receives packet 2.
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
- ProcessCryptoPacketAtLevel(2, ENCRYPTION_INITIAL);
- // Verify more packets can be sent.
- for (size_t i = anti_amplification_factor + 1;
- i < anti_amplification_factor * 2; ++i) {
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
- connection_.SendCryptoDataWithString("foo", i * 3);
- }
- // Verify server is throttled by anti-amplification limit.
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
- connection_.SendCryptoDataWithString("foo",
- 2 * anti_amplification_factor * 3);
-
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
- ProcessPacket(3);
- // Verify anti-amplification limit is gone after address validation.
- for (size_t i = 0; i < 100; ++i) {
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
- connection_.SendStreamDataWithString(3, "first", i * 0, NO_FIN);
- }
-}
-
-TEST_P(QuicConnectionTest, 3AntiAmplificationLimit) {
- if (!connection_.version().SupportsAntiAmplificationLimit()) {
- return;
- }
- EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
-
- set_perspective(Perspective::IS_SERVER);
- QuicConfig config;
- QuicTagVector connection_options;
- connection_options.push_back(k3AFF);
- config.SetInitialReceivedConnectionOptions(connection_options);
- if (connection_.version().UsesTls()) {
- QuicConfigPeer::SetReceivedOriginalConnectionId(
- &config, connection_.connection_id());
- QuicConfigPeer::SetReceivedInitialSourceConnectionId(&config,
- QuicConnectionId());
- }
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
- connection_.SetFromConfig(config);
-
- // Verify no data can be sent at the beginning because bytes received is 0.
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
- connection_.SendCryptoDataWithString("foo", 0);
- EXPECT_FALSE(connection_.CanWrite(HAS_RETRANSMITTABLE_DATA));
- EXPECT_FALSE(connection_.CanWrite(NO_RETRANSMITTABLE_DATA));
- EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
-
- // Receives packet 1.
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
- ProcessCryptoPacketAtLevel(1, ENCRYPTION_INITIAL);
-
- const size_t anti_amplification_factor = 3;
- // Verify now packets can be sent.
- for (size_t i = 1; i < anti_amplification_factor; ++i) {
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
- connection_.SendCryptoDataWithString("foo", i * 3);
- // Verify retransmission alarm is not set if throttled by anti-amplification
- // limit.
- EXPECT_EQ(i != anti_amplification_factor - 1,
- connection_.GetRetransmissionAlarm()->IsSet());
- }
- // Verify server is throttled by anti-amplification limit.
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
- connection_.SendCryptoDataWithString("foo", anti_amplification_factor * 3);
-
- // Receives packet 2.
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
- ProcessCryptoPacketAtLevel(2, ENCRYPTION_INITIAL);
- // Verify more packets can be sent.
- for (size_t i = anti_amplification_factor + 1;
- i < anti_amplification_factor * 2; ++i) {
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
- connection_.SendCryptoDataWithString("foo", i * 3);
- }
- // Verify server is throttled by anti-amplification limit.
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
- connection_.SendCryptoDataWithString("foo",
- 2 * anti_amplification_factor * 3);
-
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
- ProcessPacket(3);
- // Verify anti-amplification limit is gone after address validation.
- for (size_t i = 0; i < 100; ++i) {
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
- connection_.SendStreamDataWithString(3, "first", i * 0, NO_FIN);
- }
-}
-
-TEST_P(QuicConnectionTest, 10AntiAmplificationLimit) {
- if (!connection_.version().SupportsAntiAmplificationLimit()) {
- return;
- }
- EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
-
- set_perspective(Perspective::IS_SERVER);
- QuicConfig config;
- QuicTagVector connection_options;
- connection_options.push_back(k10AF);
- config.SetInitialReceivedConnectionOptions(connection_options);
- if (connection_.version().UsesTls()) {
- QuicConfigPeer::SetReceivedOriginalConnectionId(
- &config, connection_.connection_id());
- QuicConfigPeer::SetReceivedInitialSourceConnectionId(&config,
- QuicConnectionId());
- }
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
- connection_.SetFromConfig(config);
-
- // Verify no data can be sent at the beginning because bytes received is 0.
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
- connection_.SendCryptoDataWithString("foo", 0);
- EXPECT_FALSE(connection_.CanWrite(HAS_RETRANSMITTABLE_DATA));
- EXPECT_FALSE(connection_.CanWrite(NO_RETRANSMITTABLE_DATA));
- EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
-
- // Receives packet 1.
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
- ProcessCryptoPacketAtLevel(1, ENCRYPTION_INITIAL);
-
- const size_t anti_amplification_factor = 10;
- // Verify now packets can be sent.
- for (size_t i = 1; i < anti_amplification_factor; ++i) {
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
- connection_.SendCryptoDataWithString("foo", i * 3);
- // Verify retransmission alarm is not set if throttled by anti-amplification
- // limit.
- EXPECT_EQ(i != anti_amplification_factor - 1,
- connection_.GetRetransmissionAlarm()->IsSet());
- }
- // Verify server is throttled by anti-amplification limit.
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
- connection_.SendCryptoDataWithString("foo", anti_amplification_factor * 3);
-
- // Receives packet 2.
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
- ProcessCryptoPacketAtLevel(2, ENCRYPTION_INITIAL);
- // Verify more packets can be sent.
- for (size_t i = anti_amplification_factor + 1;
- i < anti_amplification_factor * 2; ++i) {
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
- connection_.SendCryptoDataWithString("foo", i * 3);
- }
- // Verify server is throttled by anti-amplification limit.
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
- connection_.SendCryptoDataWithString("foo",
- 2 * anti_amplification_factor * 3);
-
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
- ProcessPacket(3);
- // Verify anti-amplification limit is gone after address validation.
- for (size_t i = 0; i < 100; ++i) {
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
- connection_.SendStreamDataWithString(3, "first", i * 0, NO_FIN);
- }
-}
-
-TEST_P(QuicConnectionTest, AckPendingWithAmplificationLimited) {
- if (!connection_.version().SupportsAntiAmplificationLimit()) {
- return;
- }
- EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
- EXPECT_CALL(visitor_, OnHandshakePacketSent()).Times(AnyNumber());
- set_perspective(Perspective::IS_SERVER);
- use_tagging_decrypter();
- connection_.SetEncrypter(ENCRYPTION_INITIAL,
- std::make_unique<TaggingEncrypter>(0x01));
- connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
- // Receives packet 1.
- ProcessCryptoPacketAtLevel(1, ENCRYPTION_INITIAL);
- connection_.SetEncrypter(ENCRYPTION_HANDSHAKE,
- std::make_unique<TaggingEncrypter>(0x02));
- connection_.SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE);
- EXPECT_TRUE(connection_.HasPendingAcks());
- // Send response in different encryption level and cause amplification factor
- // throttled.
- size_t i = 0;
- while (connection_.CanWrite(HAS_RETRANSMITTABLE_DATA)) {
- connection_.SendCryptoDataWithString(std::string(1024, 'a'), i * 1024,
- ENCRYPTION_HANDSHAKE);
- ++i;
- }
- // Verify ACK is still pending.
- EXPECT_TRUE(connection_.HasPendingAcks());
-
- // Fire ACK alarm and verify ACK cannot be sent due to amplification factor.
- clock_.AdvanceTime(connection_.GetAckAlarm()->deadline() - clock_.Now());
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
- connection_.GetAckAlarm()->Fire();
- // Verify ACK alarm is cancelled.
- EXPECT_FALSE(connection_.HasPendingAcks());
-
- // Receives packet 2 and verify ACK gets flushed.
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
- ProcessCryptoPacketAtLevel(2, ENCRYPTION_INITIAL);
- EXPECT_FALSE(writer_->ack_frames().empty());
-}
-
-TEST_P(QuicConnectionTest, ConnectionCloseFrameType) {
- if (!VersionHasIetfQuicFrames(version().transport_version)) {
- // Test relevent only for IETF QUIC.
- return;
- }
- const QuicErrorCode kQuicErrorCode = IETF_QUIC_PROTOCOL_VIOLATION;
- // Use the (unknown) frame type of 9999 to avoid triggering any logic
- // which might be associated with the processing of a known frame type.
- const uint64_t kTransportCloseFrameType = 9999u;
- QuicFramerPeer::set_current_received_frame_type(
- QuicConnectionPeer::GetFramer(&connection_), kTransportCloseFrameType);
- // Do a transport connection close
- EXPECT_CALL(visitor_, OnConnectionClosed(_, _));
- connection_.CloseConnection(
- kQuicErrorCode, "Some random error message",
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
- const std::vector<QuicConnectionCloseFrame>& connection_close_frames =
- writer_->connection_close_frames();
- ASSERT_EQ(1u, connection_close_frames.size());
- EXPECT_EQ(IETF_QUIC_TRANSPORT_CONNECTION_CLOSE,
- connection_close_frames[0].close_type);
- EXPECT_EQ(kQuicErrorCode, connection_close_frames[0].quic_error_code);
- EXPECT_EQ(kTransportCloseFrameType,
- 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;
- connection_options.push_back(k1PTO);
- connection_options.push_back(kPTOS);
- config.SetConnectionOptionsToSend(connection_options);
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
- connection_.SetFromConfig(config);
- EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
-
- QuicStreamId stream_id = 2;
- QuicPacketNumber last_packet;
- SendStreamDataToPeer(stream_id, "foooooo", 0, NO_FIN, &last_packet);
- SendStreamDataToPeer(stream_id, "foooooo", 7, NO_FIN, &last_packet);
- EXPECT_EQ(QuicPacketNumber(2), last_packet);
- EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
-
- // Fire PTO and verify the PTO retransmission skips one packet number.
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
- connection_.GetRetransmissionAlarm()->Fire();
- EXPECT_EQ(1u, writer_->stream_frames().size());
- EXPECT_EQ(QuicPacketNumber(4), writer_->last_packet_header().packet_number);
- EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
-}
-
-TEST_P(QuicConnectionTest, SendCoalescedPackets) {
- if (!connection_.version().CanSendCoalescedPackets()) {
- return;
- }
- MockQuicConnectionDebugVisitor debug_visitor;
- connection_.set_debug_visitor(&debug_visitor);
- EXPECT_CALL(debug_visitor, OnPacketSent(_, _, _, _, _, _, _, _)).Times(3);
- EXPECT_CALL(debug_visitor, OnCoalescedPacketSent(_, _)).Times(1);
- EXPECT_CALL(visitor_, OnHandshakePacketSent()).Times(1);
- {
- QuicConnection::ScopedPacketFlusher flusher(&connection_);
- use_tagging_decrypter();
- 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);
- }
- // Verify all 3 packets are coalesced in the same UDP datagram.
- EXPECT_EQ(1u, writer_->packets_write_attempts());
- EXPECT_EQ(0x03030303u, writer_->final_bytes_of_last_packet());
- // Verify the packet is padded to full.
- EXPECT_EQ(connection_.max_packet_length(), writer_->last_packet_size());
-
- // Verify packet process.
- EXPECT_EQ(1u, writer_->crypto_frames().size());
- EXPECT_EQ(0u, writer_->stream_frames().size());
- // Verify there is coalesced packet.
- EXPECT_NE(nullptr, writer_->coalesced_packet());
-}
-
-TEST_P(QuicConnectionTest, LegacyVersionEncapsulation) {
- connection_.EnableLegacyVersionEncapsulation("test.example.org");
-
- MockQuicConnectionDebugVisitor debug_visitor;
- connection_.set_debug_visitor(&debug_visitor);
- EXPECT_CALL(debug_visitor, OnPacketSent(_, _, _, _, _, _, _, _)).Times(1);
-
- // Our TestPacketWriter normally parses the sent packet using the version
- // from the connection, so here we need to tell it to use the encapsulation
- // version, and reset the initial decrypter for that version.
- writer_->framer()->SetSupportedVersions(
- SupportedVersions(LegacyVersionForEncapsulation()));
- writer_->framer()->framer()->SetInitialObfuscators(
- connection_.connection_id());
-
- {
- QuicConnection::ScopedPacketFlusher flusher(&connection_);
- connection_.SendCryptoDataWithString("TEST_CRYPTO_DATA", /*offset=*/0);
- }
-
- EXPECT_EQ(1u, writer_->packets_write_attempts());
- // Verify that the packet is fully padded.
- EXPECT_EQ(connection_.max_packet_length(), writer_->last_packet_size());
-
- // Check that the connection stats show Legacy Version Encapsulation was used.
- EXPECT_GT(connection_.GetStats().sent_legacy_version_encapsulated_packets,
- 0u);
-
- // Verify that the sent packet was in fact encapsulated, and check header.
- const QuicPacketHeader& encapsulated_header = writer_->last_packet_header();
- EXPECT_TRUE(encapsulated_header.version_flag);
- EXPECT_EQ(encapsulated_header.version, LegacyVersionForEncapsulation());
- EXPECT_EQ(encapsulated_header.destination_connection_id,
- connection_.connection_id());
-
- // Encapsulated packet should contain a stream frame for the crypto stream,
- // optionally padding, and nothing else.
- EXPECT_EQ(0u, writer_->crypto_frames().size());
- EXPECT_EQ(1u, writer_->stream_frames().size());
- EXPECT_EQ(writer_->frame_count(), writer_->framer()->padding_frames().size() +
- writer_->stream_frames().size());
-}
-
-TEST_P(QuicConnectionTest, ClientReceivedHandshakeDone) {
- if (!connection_.version().UsesTls()) {
- return;
- }
- EXPECT_CALL(visitor_, OnHandshakeDoneReceived());
- QuicFrames frames;
- frames.push_back(QuicFrame(QuicHandshakeDoneFrame()));
- frames.push_back(QuicFrame(QuicPaddingFrame(-1)));
- ProcessFramesPacketAtLevel(1, frames, ENCRYPTION_FORWARD_SECURE);
-}
-
-TEST_P(QuicConnectionTest, ServerReceivedHandshakeDone) {
- if (!connection_.version().UsesTls()) {
- return;
- }
- set_perspective(Perspective::IS_SERVER);
- EXPECT_CALL(visitor_, OnHandshakeDoneReceived()).Times(0);
- if (version().handshake_protocol == PROTOCOL_TLS1_3) {
- EXPECT_CALL(visitor_, BeforeConnectionCloseSent());
- }
- EXPECT_CALL(visitor_, OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF))
- .WillOnce(Invoke(this, &QuicConnectionTest::SaveConnectionCloseFrame));
- QuicFrames frames;
- frames.push_back(QuicFrame(QuicHandshakeDoneFrame()));
- frames.push_back(QuicFrame(QuicPaddingFrame(-1)));
- ProcessFramesPacketAtLevel(1, frames, ENCRYPTION_FORWARD_SECURE);
- EXPECT_EQ(1, connection_close_frame_count_);
- EXPECT_THAT(saved_connection_close_frame_.quic_error_code,
- IsError(IETF_QUIC_PROTOCOL_VIOLATION));
-}
-
-TEST_P(QuicConnectionTest, MultiplePacketNumberSpacePto) {
- if (!connection_.SupportsMultiplePacketNumberSpaces()) {
- return;
- }
- use_tagging_decrypter();
- // Send handshake packet.
- connection_.SetEncrypter(ENCRYPTION_HANDSHAKE,
- std::make_unique<TaggingEncrypter>(0x02));
- connection_.SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE);
- EXPECT_CALL(visitor_, OnHandshakePacketSent()).Times(1);
- connection_.SendCryptoDataWithString("foo", 0, ENCRYPTION_HANDSHAKE);
- EXPECT_EQ(0x02020202u, writer_->final_bytes_of_last_packet());
-
- // Send application data.
- connection_.SendApplicationDataAtLevel(ENCRYPTION_FORWARD_SECURE, 5, "data",
- 0, NO_FIN);
- EXPECT_EQ(0x01010101u, writer_->final_bytes_of_last_packet());
- QuicTime retransmission_time =
- connection_.GetRetransmissionAlarm()->deadline();
- EXPECT_NE(QuicTime::Zero(), retransmission_time);
-
- // Retransmit handshake data.
- clock_.AdvanceTime(retransmission_time - clock_.Now());
- EXPECT_CALL(*send_algorithm_,
- OnPacketSent(_, _,
- GetQuicReloadableFlag(quic_default_on_pto)
- ? QuicPacketNumber(3)
- : QuicPacketNumber(4),
- _, _));
- connection_.GetRetransmissionAlarm()->Fire();
- // Verify 1-RTT packet gets coalesced with handshake retransmission.
- EXPECT_EQ(0x01010101u, writer_->final_bytes_of_last_packet());
-
- // Send application data.
- connection_.SendApplicationDataAtLevel(ENCRYPTION_FORWARD_SECURE, 5, "data",
- 4, NO_FIN);
- EXPECT_EQ(0x01010101u, writer_->final_bytes_of_last_packet());
- retransmission_time = connection_.GetRetransmissionAlarm()->deadline();
- EXPECT_NE(QuicTime::Zero(), retransmission_time);
-
- // Retransmit handshake data again.
- clock_.AdvanceTime(retransmission_time - clock_.Now());
- QuicPacketNumber handshake_retransmission =
- GetQuicReloadableFlag(quic_default_on_pto) ? QuicPacketNumber(5)
- : QuicPacketNumber(7);
- handshake_retransmission += 1;
- EXPECT_CALL(*send_algorithm_,
- OnPacketSent(_, _, handshake_retransmission + 1, _, _));
- EXPECT_CALL(*send_algorithm_,
- OnPacketSent(_, _, handshake_retransmission, _, _));
- connection_.GetRetransmissionAlarm()->Fire();
- // Verify 1-RTT packet gets coalesced with handshake retransmission.
- EXPECT_EQ(0x01010101u, writer_->final_bytes_of_last_packet());
-
- // Discard handshake key.
- connection_.OnHandshakeComplete();
- retransmission_time = connection_.GetRetransmissionAlarm()->deadline();
- EXPECT_NE(QuicTime::Zero(), retransmission_time);
-
- // Retransmit application data.
- clock_.AdvanceTime(retransmission_time - clock_.Now());
- QuicPacketNumber application_retransmission =
- GetQuicReloadableFlag(quic_default_on_pto) ? QuicPacketNumber(6)
- : QuicPacketNumber(9);
- application_retransmission += 2;
- EXPECT_CALL(*send_algorithm_,
- OnPacketSent(_, _, application_retransmission, _, _));
- connection_.GetRetransmissionAlarm()->Fire();
- EXPECT_EQ(0x01010101u, writer_->final_bytes_of_last_packet());
-}
-
-void QuicConnectionTest::TestClientRetryHandling(
- bool invalid_retry_tag, bool missing_original_id_in_config,
- bool wrong_original_id_in_config, bool missing_retry_id_in_config,
- bool wrong_retry_id_in_config) {
- if (invalid_retry_tag) {
- ASSERT_FALSE(missing_original_id_in_config);
- ASSERT_FALSE(wrong_original_id_in_config);
- ASSERT_FALSE(missing_retry_id_in_config);
- ASSERT_FALSE(wrong_retry_id_in_config);
- } else {
- ASSERT_FALSE(missing_original_id_in_config && wrong_original_id_in_config);
- ASSERT_FALSE(missing_retry_id_in_config && wrong_retry_id_in_config);
- }
- if (!version().UsesTls()) {
- return;
- }
-
- // These values come from draft-ietf-quic-v2 Appendix A.4.
- uint8_t retry_packet_rfcv2[] = {
- 0xcf, 0x70, 0x9a, 0x50, 0xc4, 0x00, 0x08, 0xf0, 0x67, 0xa5, 0x50, 0x2a,
- 0x42, 0x62, 0xb5, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x1d, 0xc7, 0x11, 0x30,
- 0xcd, 0x1e, 0xd3, 0x9d, 0x6e, 0xfc, 0xee, 0x5c, 0x85, 0x80, 0x65, 0x01};
- // These values come from RFC9001 Appendix A.4.
- uint8_t retry_packet_rfcv1[] = {
- 0xff, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0xf0, 0x67, 0xa5, 0x50, 0x2a,
- 0x42, 0x62, 0xb5, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x04, 0xa2, 0x65, 0xba,
- 0x2e, 0xff, 0x4d, 0x82, 0x90, 0x58, 0xfb, 0x3f, 0x0f, 0x24, 0x96, 0xba};
- uint8_t retry_packet29[] = {
- 0xff, 0xff, 0x00, 0x00, 0x1d, 0x00, 0x08, 0xf0, 0x67, 0xa5, 0x50, 0x2a,
- 0x42, 0x62, 0xb5, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0xd1, 0x69, 0x26, 0xd8,
- 0x1f, 0x6f, 0x9c, 0xa2, 0x95, 0x3a, 0x8a, 0xa4, 0x57, 0x5e, 0x1e, 0x49};
-
- uint8_t* retry_packet;
- size_t retry_packet_length;
- if (version() == ParsedQuicVersion::V2Draft01()) {
- retry_packet = retry_packet_rfcv2;
- retry_packet_length = ABSL_ARRAYSIZE(retry_packet_rfcv2);
- } else if (version() == ParsedQuicVersion::RFCv1()) {
- retry_packet = retry_packet_rfcv1;
- retry_packet_length = ABSL_ARRAYSIZE(retry_packet_rfcv1);
- } else if (version() == ParsedQuicVersion::Draft29()) {
- retry_packet = retry_packet29;
- retry_packet_length = ABSL_ARRAYSIZE(retry_packet29);
- } else {
- // TODO(dschinazi) generate retry packets for all versions once we have
- // server-side support for generating these programmatically.
- return;
- }
-
- uint8_t original_connection_id_bytes[] = {0x83, 0x94, 0xc8, 0xf0,
- 0x3e, 0x51, 0x57, 0x08};
- uint8_t new_connection_id_bytes[] = {0xf0, 0x67, 0xa5, 0x50,
- 0x2a, 0x42, 0x62, 0xb5};
- uint8_t retry_token_bytes[] = {0x74, 0x6f, 0x6b, 0x65, 0x6e};
-
- QuicConnectionId original_connection_id(
- reinterpret_cast<char*>(original_connection_id_bytes),
- ABSL_ARRAYSIZE(original_connection_id_bytes));
- QuicConnectionId new_connection_id(
- reinterpret_cast<char*>(new_connection_id_bytes),
- ABSL_ARRAYSIZE(new_connection_id_bytes));
-
- std::string retry_token(reinterpret_cast<char*>(retry_token_bytes),
- ABSL_ARRAYSIZE(retry_token_bytes));
-
- if (invalid_retry_tag) {
- // Flip the last bit of the retry packet to prevent the integrity tag
- // from validating correctly.
- retry_packet[retry_packet_length - 1] ^= 1;
- }
-
- QuicConnectionId config_original_connection_id = original_connection_id;
- if (wrong_original_id_in_config) {
- // Flip the first bit of the connection ID.
- ASSERT_FALSE(config_original_connection_id.IsEmpty());
- config_original_connection_id.mutable_data()[0] ^= 0x80;
- }
- QuicConnectionId config_retry_source_connection_id = new_connection_id;
- if (wrong_retry_id_in_config) {
- // Flip the first bit of the connection ID.
- ASSERT_FALSE(config_retry_source_connection_id.IsEmpty());
- config_retry_source_connection_id.mutable_data()[0] ^= 0x80;
- }
-
- // Make sure the connection uses the connection ID from the test vectors,
- QuicConnectionPeer::SetServerConnectionId(&connection_,
- original_connection_id);
- // Make sure our fake framer has the new post-retry INITIAL keys so that any
- // retransmission triggered by retry can be decrypted.
- writer_->framer()->framer()->SetInitialObfuscators(new_connection_id);
-
- // Process the RETRY packet.
- connection_.ProcessUdpPacket(
- kSelfAddress, kPeerAddress,
- QuicReceivedPacket(reinterpret_cast<char*>(retry_packet),
- retry_packet_length, clock_.Now()));
-
- if (invalid_retry_tag) {
- // Make sure we refuse to process a RETRY with invalid tag.
- EXPECT_FALSE(connection_.GetStats().retry_packet_processed);
- EXPECT_EQ(connection_.connection_id(), original_connection_id);
- EXPECT_TRUE(QuicPacketCreatorPeer::GetRetryToken(
- QuicConnectionPeer::GetPacketCreator(&connection_))
- .empty());
- return;
- }
-
- // Make sure we correctly parsed the RETRY.
- EXPECT_TRUE(connection_.GetStats().retry_packet_processed);
- EXPECT_EQ(connection_.connection_id(), new_connection_id);
- EXPECT_EQ(QuicPacketCreatorPeer::GetRetryToken(
- QuicConnectionPeer::GetPacketCreator(&connection_)),
- retry_token);
-
- // Test validating the original_connection_id from the config.
- QuicConfig received_config;
- QuicConfigPeer::SetNegotiated(&received_config, true);
- if (connection_.version().UsesTls()) {
- QuicConfigPeer::SetReceivedInitialSourceConnectionId(
- &received_config, connection_.connection_id());
- if (!missing_retry_id_in_config) {
- QuicConfigPeer::SetReceivedRetrySourceConnectionId(
- &received_config, config_retry_source_connection_id);
- }
- }
- if (!missing_original_id_in_config) {
- QuicConfigPeer::SetReceivedOriginalConnectionId(
- &received_config, config_original_connection_id);
- }
-
- if (missing_original_id_in_config || wrong_original_id_in_config ||
- missing_retry_id_in_config || wrong_retry_id_in_config) {
- EXPECT_CALL(visitor_,
- OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF))
- .Times(1);
- } else {
- EXPECT_CALL(visitor_,
- OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF))
- .Times(0);
- }
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _)).Times(AnyNumber());
- connection_.SetFromConfig(received_config);
- if (missing_original_id_in_config || wrong_original_id_in_config ||
- missing_retry_id_in_config || wrong_retry_id_in_config) {
- ASSERT_FALSE(connection_.connected());
- TestConnectionCloseQuicErrorCode(IETF_QUIC_PROTOCOL_VIOLATION);
- } else {
- EXPECT_TRUE(connection_.connected());
- }
-}
-
-TEST_P(QuicConnectionTest, ClientParsesRetry) {
- TestClientRetryHandling(/*invalid_retry_tag=*/false,
- /*missing_original_id_in_config=*/false,
- /*wrong_original_id_in_config=*/false,
- /*missing_retry_id_in_config=*/false,
- /*wrong_retry_id_in_config=*/false);
-}
-
-TEST_P(QuicConnectionTest, ClientParsesRetryInvalidTag) {
- TestClientRetryHandling(/*invalid_retry_tag=*/true,
- /*missing_original_id_in_config=*/false,
- /*wrong_original_id_in_config=*/false,
- /*missing_retry_id_in_config=*/false,
- /*wrong_retry_id_in_config=*/false);
-}
-
-TEST_P(QuicConnectionTest, ClientParsesRetryMissingOriginalId) {
- TestClientRetryHandling(/*invalid_retry_tag=*/false,
- /*missing_original_id_in_config=*/true,
- /*wrong_original_id_in_config=*/false,
- /*missing_retry_id_in_config=*/false,
- /*wrong_retry_id_in_config=*/false);
-}
-
-TEST_P(QuicConnectionTest, ClientParsesRetryWrongOriginalId) {
- TestClientRetryHandling(/*invalid_retry_tag=*/false,
- /*missing_original_id_in_config=*/false,
- /*wrong_original_id_in_config=*/true,
- /*missing_retry_id_in_config=*/false,
- /*wrong_retry_id_in_config=*/false);
-}
-
-TEST_P(QuicConnectionTest, ClientParsesRetryMissingRetryId) {
- if (!connection_.version().UsesTls()) {
- // Versions that do not authenticate connection IDs never send the
- // retry_source_connection_id transport parameter.
- return;
- }
- TestClientRetryHandling(/*invalid_retry_tag=*/false,
- /*missing_original_id_in_config=*/false,
- /*wrong_original_id_in_config=*/false,
- /*missing_retry_id_in_config=*/true,
- /*wrong_retry_id_in_config=*/false);
-}
-
-TEST_P(QuicConnectionTest, ClientParsesRetryWrongRetryId) {
- if (!connection_.version().UsesTls()) {
- // Versions that do not authenticate connection IDs never send the
- // retry_source_connection_id transport parameter.
- return;
- }
- TestClientRetryHandling(/*invalid_retry_tag=*/false,
- /*missing_original_id_in_config=*/false,
- /*wrong_original_id_in_config=*/false,
- /*missing_retry_id_in_config=*/false,
- /*wrong_retry_id_in_config=*/true);
-}
-
-TEST_P(QuicConnectionTest, ClientRetransmitsInitialPacketsOnRetry) {
- if (!connection_.version().HasIetfQuicFrames()) {
- // TestClientRetryHandling() currently only supports IETF draft versions.
- return;
- }
- connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
-
- connection_.SendCryptoStreamData();
-
- EXPECT_EQ(1u, writer_->packets_write_attempts());
- TestClientRetryHandling(/*invalid_retry_tag=*/false,
- /*missing_original_id_in_config=*/false,
- /*wrong_original_id_in_config=*/false,
- /*missing_retry_id_in_config=*/false,
- /*wrong_retry_id_in_config=*/false);
-
- // Verify that initial data is retransmitted immediately after receiving
- // RETRY.
- if (GetParam().ack_response == AckResponse::kImmediate) {
- EXPECT_EQ(2u, writer_->packets_write_attempts());
- EXPECT_EQ(1u, writer_->framer()->crypto_frames().size());
- }
-}
-
-TEST_P(QuicConnectionTest, NoInitialPacketsRetransmissionOnInvalidRetry) {
- if (!connection_.version().HasIetfQuicFrames()) {
- return;
- }
- connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
-
- connection_.SendCryptoStreamData();
-
- EXPECT_EQ(1u, writer_->packets_write_attempts());
- TestClientRetryHandling(/*invalid_retry_tag=*/true,
- /*missing_original_id_in_config=*/false,
- /*wrong_original_id_in_config=*/false,
- /*missing_retry_id_in_config=*/false,
- /*wrong_retry_id_in_config=*/false);
-
- EXPECT_EQ(1u, writer_->packets_write_attempts());
-}
-
-TEST_P(QuicConnectionTest, ClientReceivesOriginalConnectionIdWithoutRetry) {
- if (!connection_.version().UsesTls()) {
- // QUIC+TLS is required to transmit connection ID transport parameters.
- return;
- }
- if (connection_.version().UsesTls()) {
- // Versions that authenticate connection IDs always send the
- // original_destination_connection_id transport parameter.
- return;
- }
- // Make sure that receiving the original_destination_connection_id transport
- // parameter fails the handshake when no RETRY packet was received before it.
- QuicConfig received_config;
- QuicConfigPeer::SetNegotiated(&received_config, true);
- QuicConfigPeer::SetReceivedOriginalConnectionId(&received_config,
- TestConnectionId(0x12345));
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _)).Times(AnyNumber());
- EXPECT_CALL(visitor_, OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF))
- .Times(1);
- connection_.SetFromConfig(received_config);
- EXPECT_FALSE(connection_.connected());
- TestConnectionCloseQuicErrorCode(IETF_QUIC_PROTOCOL_VIOLATION);
-}
-
-TEST_P(QuicConnectionTest, ClientReceivesRetrySourceConnectionIdWithoutRetry) {
- if (!connection_.version().UsesTls()) {
- // Versions that do not authenticate connection IDs never send the
- // retry_source_connection_id transport parameter.
- return;
- }
- // Make sure that receiving the retry_source_connection_id transport parameter
- // fails the handshake when no RETRY packet was received before it.
- QuicConfig received_config;
- QuicConfigPeer::SetNegotiated(&received_config, true);
- QuicConfigPeer::SetReceivedRetrySourceConnectionId(&received_config,
- TestConnectionId(0x12345));
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _)).Times(AnyNumber());
- EXPECT_CALL(visitor_, OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF))
- .Times(1);
- connection_.SetFromConfig(received_config);
- EXPECT_FALSE(connection_.connected());
- TestConnectionCloseQuicErrorCode(IETF_QUIC_PROTOCOL_VIOLATION);
-}
-
-// Regression test for http://crbug/1047977
-TEST_P(QuicConnectionTest, MaxStreamsFrameCausesConnectionClose) {
- if (!VersionHasIetfQuicFrames(connection_.transport_version())) {
- return;
- }
- // Received frame causes connection close.
- EXPECT_CALL(visitor_, OnMaxStreamsFrame(_))
- .WillOnce(InvokeWithoutArgs([this]() {
- EXPECT_CALL(visitor_, OnConnectionClosed(_, _));
- connection_.CloseConnection(
- QUIC_TOO_MANY_BUFFERED_CONTROL_FRAMES, "error",
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
- return true;
- }));
- QuicFrames frames;
- frames.push_back(QuicFrame(QuicMaxStreamsFrame()));
- frames.push_back(QuicFrame(QuicPaddingFrame(-1)));
- ProcessFramesPacketAtLevel(1, frames, ENCRYPTION_FORWARD_SECURE);
-}
-
-TEST_P(QuicConnectionTest, StreamsBlockedFrameCausesConnectionClose) {
- if (!VersionHasIetfQuicFrames(connection_.transport_version())) {
- return;
- }
- // Received frame causes connection close.
- EXPECT_CALL(visitor_, OnStreamsBlockedFrame(_))
- .WillOnce(InvokeWithoutArgs([this]() {
- EXPECT_CALL(visitor_, OnConnectionClosed(_, _));
- connection_.CloseConnection(
- QUIC_TOO_MANY_BUFFERED_CONTROL_FRAMES, "error",
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
- return true;
- }));
- QuicFrames frames;
- frames.push_back(
- QuicFrame(QuicStreamsBlockedFrame(kInvalidControlFrameId, 10, false)));
- frames.push_back(QuicFrame(QuicPaddingFrame(-1)));
- ProcessFramesPacketAtLevel(1, frames, ENCRYPTION_FORWARD_SECURE);
-}
-
-TEST_P(QuicConnectionTest,
- BundleAckWithConnectionCloseMultiplePacketNumberSpace) {
- if (!connection_.SupportsMultiplePacketNumberSpaces()) {
- return;
- }
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
- EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber());
- // Receives packet 1000 in initial data.
- ProcessCryptoPacketAtLevel(1000, ENCRYPTION_INITIAL);
- // Receives packet 2000 in application data.
- ProcessDataPacketAtLevel(2000, false, ENCRYPTION_FORWARD_SECURE);
- EXPECT_CALL(visitor_, OnConnectionClosed(_, _));
- const QuicErrorCode kQuicErrorCode = QUIC_INTERNAL_ERROR;
- connection_.CloseConnection(
- kQuicErrorCode, "Some random error message",
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
-
- EXPECT_EQ(2u, QuicConnectionPeer::GetNumEncryptionLevels(&connection_));
-
- TestConnectionCloseQuicErrorCode(kQuicErrorCode);
- EXPECT_EQ(1u, writer_->connection_close_frames().size());
- // Verify ack is bundled.
- EXPECT_EQ(1u, writer_->ack_frames().size());
-
- if (!connection_.version().CanSendCoalescedPackets()) {
- // Each connection close packet should be sent in distinct UDP packets.
- EXPECT_EQ(QuicConnectionPeer::GetNumEncryptionLevels(&connection_),
- writer_->connection_close_packets());
- EXPECT_EQ(QuicConnectionPeer::GetNumEncryptionLevels(&connection_),
- writer_->packets_write_attempts());
- return;
- }
-
- // A single UDP packet should be sent with multiple connection close packets
- // coalesced together.
- EXPECT_EQ(1u, writer_->packets_write_attempts());
-
- // Only the first packet has been processed yet.
- EXPECT_EQ(1u, writer_->connection_close_packets());
-
- // ProcessPacket resets the visitor and frees the coalesced packet.
- ASSERT_TRUE(writer_->coalesced_packet() != nullptr);
- auto packet = writer_->coalesced_packet()->Clone();
- writer_->framer()->ProcessPacket(*packet);
- EXPECT_EQ(1u, writer_->connection_close_packets());
- EXPECT_EQ(1u, writer_->connection_close_frames().size());
- // Verify ack is bundled.
- EXPECT_EQ(1u, writer_->ack_frames().size());
- ASSERT_TRUE(writer_->coalesced_packet() == nullptr);
-}
-
-// Regression test for b/151220135.
-TEST_P(QuicConnectionTest, SendPingWhenSkipPacketNumberForPto) {
- if (!VersionSupportsMessageFrames(connection_.transport_version())) {
- return;
- }
- QuicConfig config;
- QuicTagVector connection_options;
- connection_options.push_back(kPTOS);
- connection_options.push_back(k1PTO);
- config.SetConnectionOptionsToSend(connection_options);
- if (connection_.version().UsesTls()) {
- QuicConfigPeer::SetReceivedMaxDatagramFrameSize(
- &config, kMaxAcceptedDatagramFrameSize);
- }
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
- connection_.SetFromConfig(config);
- connection_.OnHandshakeComplete();
- EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
-
- EXPECT_EQ(MESSAGE_STATUS_SUCCESS, SendMessage("message"));
- EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
-
- // PTO fires, verify a PING packet gets sent because there is no data to
- // send.
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, QuicPacketNumber(3), _, _));
- connection_.GetRetransmissionAlarm()->Fire();
- EXPECT_EQ(1u, connection_.GetStats().pto_count);
- EXPECT_EQ(0u, connection_.GetStats().crypto_retransmit_count);
- EXPECT_EQ(1u, writer_->ping_frames().size());
-}
-
-// Regression test for b/155757133
-TEST_P(QuicConnectionTest, DonotChangeQueuedAcks) {
- if (!connection_.SupportsMultiplePacketNumberSpaces()) {
- return;
- }
- const size_t kMinRttMs = 40;
- RttStats* rtt_stats = const_cast<RttStats*>(manager_->GetRttStats());
- rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(kMinRttMs),
- QuicTime::Delta::Zero(), QuicTime::Zero());
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _));
- connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
- // Discard INITIAL key.
- connection_.RemoveEncrypter(ENCRYPTION_INITIAL);
- connection_.NeuterUnencryptedPackets();
- EXPECT_CALL(visitor_, GetHandshakeState())
- .WillRepeatedly(Return(HANDSHAKE_COMPLETE));
-
- ProcessPacket(2);
- ProcessPacket(3);
- ProcessPacket(4);
- // Process a packet containing stream frame followed by ACK of packets 1.
- QuicFrames frames;
- frames.push_back(QuicFrame(QuicStreamFrame(
- QuicUtils::GetFirstBidirectionalStreamId(
- connection_.version().transport_version, Perspective::IS_CLIENT),
- false, 0u, absl::string_view())));
- QuicAckFrame ack_frame = InitAckFrame(1);
- frames.push_back(QuicFrame(&ack_frame));
- // Receiving stream frame causes something to send.
- EXPECT_CALL(visitor_, OnStreamFrame(_)).WillOnce(Invoke([this]() {
- connection_.SendControlFrame(QuicFrame(new QuicWindowUpdateFrame(1, 0, 0)));
- // Verify now the queued ACK contains packet number 2.
- EXPECT_TRUE(QuicPacketCreatorPeer::QueuedFrames(
- QuicConnectionPeer::GetPacketCreator(&connection_))[0]
- .ack_frame->packets.Contains(QuicPacketNumber(2)));
- }));
- ProcessFramesPacketAtLevel(9, frames, ENCRYPTION_FORWARD_SECURE);
- EXPECT_TRUE(writer_->ack_frames()[0].packets.Contains(QuicPacketNumber(2)));
-}
-
-TEST_P(QuicConnectionTest, DonotExtendIdleTimeOnUndecryptablePackets) {
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
- QuicConfig config;
- connection_.SetFromConfig(config);
- // Subtract a second from the idle timeout on the client side.
- QuicTime initial_deadline =
- clock_.ApproximateNow() +
- QuicTime::Delta::FromSeconds(kInitialIdleTimeoutSecs - 1);
- EXPECT_EQ(initial_deadline, connection_.GetTimeoutAlarm()->deadline());
-
- // Received an undecryptable packet.
- clock_.AdvanceTime(QuicTime::Delta::FromSeconds(1));
- const uint8_t tag = 0x07;
- peer_framer_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
- std::make_unique<TaggingEncrypter>(tag));
- ProcessDataPacketAtLevel(1, !kHasStopWaiting, ENCRYPTION_FORWARD_SECURE);
- // Verify deadline does not get extended.
- EXPECT_EQ(initial_deadline, connection_.GetTimeoutAlarm()->deadline());
- EXPECT_CALL(visitor_, OnConnectionClosed(_, _)).Times(1);
- QuicTime::Delta delay = initial_deadline - clock_.ApproximateNow();
- clock_.AdvanceTime(delay);
- connection_.GetTimeoutAlarm()->Fire();
- // Verify connection gets closed.
- EXPECT_FALSE(connection_.connected());
-}
-
-TEST_P(QuicConnectionTest, BundleAckWithImmediateResponse) {
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
-
- EXPECT_CALL(visitor_, OnStreamFrame(_)).WillOnce(Invoke([this]() {
- notifier_.WriteOrBufferWindowUpate(0, 0);
- }));
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
- ProcessDataPacket(1);
- // Verify ACK is bundled with WINDOW_UPDATE.
- EXPECT_FALSE(writer_->ack_frames().empty());
- EXPECT_FALSE(connection_.HasPendingAcks());
-}
-
-TEST_P(QuicConnectionTest, AckAlarmFiresEarly) {
- if (!connection_.SupportsMultiplePacketNumberSpaces()) {
- return;
- }
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
- EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
- }
- EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber());
- use_tagging_decrypter();
- // Receives packet 1000 in initial data.
- ProcessCryptoPacketAtLevel(1000, ENCRYPTION_INITIAL);
- EXPECT_TRUE(connection_.HasPendingAcks());
-
- peer_framer_.SetEncrypter(ENCRYPTION_ZERO_RTT,
- std::make_unique<TaggingEncrypter>(0x02));
- SetDecrypter(ENCRYPTION_ZERO_RTT,
- std::make_unique<StrictTaggingDecrypter>(0x02));
- connection_.SetEncrypter(ENCRYPTION_INITIAL,
- std::make_unique<TaggingEncrypter>(0x02));
- // Receives packet 1000 in application data.
- ProcessDataPacketAtLevel(1000, false, ENCRYPTION_ZERO_RTT);
- EXPECT_TRUE(connection_.HasPendingAcks());
- // Verify ACK deadline does not change.
- EXPECT_EQ(clock_.ApproximateNow() + kAlarmGranularity,
- connection_.GetAckAlarm()->deadline());
-
- // Ack alarm fires early.
- // Verify the earliest ACK is flushed.
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
- connection_.GetAckAlarm()->Fire();
- EXPECT_TRUE(connection_.HasPendingAcks());
- EXPECT_EQ(clock_.ApproximateNow() + DefaultDelayedAckTime(),
- connection_.GetAckAlarm()->deadline());
-}
-
-TEST_P(QuicConnectionTest, ClientOnlyBlackholeDetectionClient) {
- if (!GetQuicReloadableFlag(quic_default_enable_5rto_blackhole_detection2)) {
- return;
- }
- QuicConfig config;
- QuicTagVector connection_options;
- connection_options.push_back(kCBHD);
- config.SetConnectionOptionsToSend(connection_options);
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
- connection_.SetFromConfig(config);
- EXPECT_CALL(visitor_, GetHandshakeState())
- .WillRepeatedly(Return(HANDSHAKE_COMPLETE));
- EXPECT_FALSE(connection_.GetBlackholeDetectorAlarm()->IsSet());
- // Send stream data.
- SendStreamDataToPeer(
- GetNthClientInitiatedStreamId(1, connection_.transport_version()), "foo",
- 0, FIN, nullptr);
- // Verify blackhole detection is in progress.
- EXPECT_TRUE(connection_.GetBlackholeDetectorAlarm()->IsSet());
-}
-
-TEST_P(QuicConnectionTest, ClientOnlyBlackholeDetectionServer) {
- if (!GetQuicReloadableFlag(quic_default_enable_5rto_blackhole_detection2)) {
- return;
- }
- set_perspective(Perspective::IS_SERVER);
- QuicPacketCreatorPeer::SetSendVersionInPacket(creator_, false);
- if (version().SupportsAntiAmplificationLimit()) {
- QuicConnectionPeer::SetAddressValidated(&connection_);
- }
- QuicConfig config;
- QuicTagVector connection_options;
- connection_options.push_back(kCBHD);
- config.SetInitialReceivedConnectionOptions(connection_options);
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
- connection_.SetFromConfig(config);
- EXPECT_CALL(visitor_, GetHandshakeState())
- .WillRepeatedly(Return(HANDSHAKE_COMPLETE));
- EXPECT_FALSE(connection_.GetBlackholeDetectorAlarm()->IsSet());
- // Send stream data.
- SendStreamDataToPeer(
- GetNthClientInitiatedStreamId(1, connection_.transport_version()), "foo",
- 0, FIN, nullptr);
- // Verify blackhole detection is disabled.
- EXPECT_FALSE(connection_.GetBlackholeDetectorAlarm()->IsSet());
-}
-
-TEST_P(QuicConnectionTest, 2RtoBlackholeDetection) {
- if (!GetQuicReloadableFlag(quic_default_enable_5rto_blackhole_detection2)) {
- return;
- }
- QuicConfig config;
- QuicTagVector connection_options;
- connection_options.push_back(k2RTO);
- config.SetConnectionOptionsToSend(connection_options);
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
- connection_.SetFromConfig(config);
- const size_t kMinRttMs = 40;
- RttStats* rtt_stats = const_cast<RttStats*>(manager_->GetRttStats());
- rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(kMinRttMs),
- QuicTime::Delta::Zero(), QuicTime::Zero());
- EXPECT_CALL(visitor_, GetHandshakeState())
- .WillRepeatedly(Return(HANDSHAKE_COMPLETE));
- EXPECT_FALSE(connection_.GetBlackholeDetectorAlarm()->IsSet());
- // Send stream data.
- SendStreamDataToPeer(
- GetNthClientInitiatedStreamId(1, connection_.transport_version()), "foo",
- 0, FIN, nullptr);
- // Verify blackhole delay is expected.
- EXPECT_EQ(clock_.Now() +
- connection_.sent_packet_manager().GetNetworkBlackholeDelay(2),
- QuicConnectionPeer::GetBlackholeDetectionDeadline(&connection_));
-}
-
-TEST_P(QuicConnectionTest, 3RtoBlackholeDetection) {
- if (!GetQuicReloadableFlag(quic_default_enable_5rto_blackhole_detection2)) {
- return;
- }
- QuicConfig config;
- QuicTagVector connection_options;
- connection_options.push_back(k3RTO);
- config.SetConnectionOptionsToSend(connection_options);
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
- connection_.SetFromConfig(config);
- const size_t kMinRttMs = 40;
- RttStats* rtt_stats = const_cast<RttStats*>(manager_->GetRttStats());
- rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(kMinRttMs),
- QuicTime::Delta::Zero(), QuicTime::Zero());
- EXPECT_CALL(visitor_, GetHandshakeState())
- .WillRepeatedly(Return(HANDSHAKE_COMPLETE));
- EXPECT_FALSE(connection_.GetBlackholeDetectorAlarm()->IsSet());
- // Send stream data.
- SendStreamDataToPeer(
- GetNthClientInitiatedStreamId(1, connection_.transport_version()), "foo",
- 0, FIN, nullptr);
- // Verify blackhole delay is expected.
- EXPECT_EQ(clock_.Now() +
- connection_.sent_packet_manager().GetNetworkBlackholeDelay(3),
- QuicConnectionPeer::GetBlackholeDetectionDeadline(&connection_));
-}
-
-TEST_P(QuicConnectionTest, 4RtoBlackholeDetection) {
- if (!GetQuicReloadableFlag(quic_default_enable_5rto_blackhole_detection2)) {
- return;
- }
- QuicConfig config;
- QuicTagVector connection_options;
- connection_options.push_back(k4RTO);
- config.SetConnectionOptionsToSend(connection_options);
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
- connection_.SetFromConfig(config);
- const size_t kMinRttMs = 40;
- RttStats* rtt_stats = const_cast<RttStats*>(manager_->GetRttStats());
- rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(kMinRttMs),
- QuicTime::Delta::Zero(), QuicTime::Zero());
- EXPECT_CALL(visitor_, GetHandshakeState())
- .WillRepeatedly(Return(HANDSHAKE_COMPLETE));
- EXPECT_FALSE(connection_.GetBlackholeDetectorAlarm()->IsSet());
- // Send stream data.
- SendStreamDataToPeer(
- GetNthClientInitiatedStreamId(1, connection_.transport_version()), "foo",
- 0, FIN, nullptr);
- // Verify blackhole delay is expected.
- EXPECT_EQ(clock_.Now() +
- connection_.sent_packet_manager().GetNetworkBlackholeDelay(4),
- QuicConnectionPeer::GetBlackholeDetectionDeadline(&connection_));
-}
-
-TEST_P(QuicConnectionTest, 6RtoBlackholeDetection) {
- if (!GetQuicReloadableFlag(quic_default_enable_5rto_blackhole_detection2)) {
- return;
- }
- QuicConfig config;
- QuicTagVector connection_options;
- connection_options.push_back(k6RTO);
- config.SetConnectionOptionsToSend(connection_options);
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
- connection_.SetFromConfig(config);
- const size_t kMinRttMs = 40;
- RttStats* rtt_stats = const_cast<RttStats*>(manager_->GetRttStats());
- rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(kMinRttMs),
- QuicTime::Delta::Zero(), QuicTime::Zero());
- EXPECT_CALL(visitor_, GetHandshakeState())
- .WillRepeatedly(Return(HANDSHAKE_COMPLETE));
- EXPECT_FALSE(connection_.GetBlackholeDetectorAlarm()->IsSet());
- // Send stream data.
- SendStreamDataToPeer(
- GetNthClientInitiatedStreamId(1, connection_.transport_version()), "foo",
- 0, FIN, nullptr);
- // Verify blackhole delay is expected.
- EXPECT_EQ(clock_.Now() +
- connection_.sent_packet_manager().GetNetworkBlackholeDelay(6),
- QuicConnectionPeer::GetBlackholeDetectionDeadline(&connection_));
-}
-
-// Regresstion test for b/158491591.
-TEST_P(QuicConnectionTest, MadeForwardProgressOnDiscardingKeys) {
- if (!connection_.SupportsMultiplePacketNumberSpaces()) {
- return;
- }
- use_tagging_decrypter();
- // Send handshake packet.
- connection_.SetEncrypter(ENCRYPTION_HANDSHAKE,
- std::make_unique<TaggingEncrypter>(0x02));
- connection_.SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE);
- EXPECT_CALL(visitor_, OnHandshakePacketSent()).Times(1);
- QuicConfig config;
- QuicTagVector connection_options;
- connection_options.push_back(k5RTO);
- config.SetConnectionOptionsToSend(connection_options);
- QuicConfigPeer::SetNegotiated(&config, true);
- if (GetQuicReloadableFlag(quic_default_enable_5rto_blackhole_detection2)) {
- EXPECT_CALL(visitor_, GetHandshakeState())
- .WillRepeatedly(Return(HANDSHAKE_COMPLETE));
- }
- if (connection_.version().UsesTls()) {
- QuicConfigPeer::SetReceivedOriginalConnectionId(
- &config, connection_.connection_id());
- QuicConfigPeer::SetReceivedInitialSourceConnectionId(
- &config, connection_.connection_id());
- }
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
- connection_.SetFromConfig(config);
-
- connection_.SendCryptoDataWithString("foo", 0, ENCRYPTION_HANDSHAKE);
- EXPECT_TRUE(connection_.BlackholeDetectionInProgress());
- // Discard handshake keys.
- connection_.OnHandshakeComplete();
- if (GetQuicReloadableFlag(quic_default_enable_5rto_blackhole_detection2)) {
- // Verify blackhole detection stops.
- EXPECT_FALSE(connection_.BlackholeDetectionInProgress());
- } else {
- // Problematic: although there is nothing in flight, blackhole detection is
- // still in progress.
- EXPECT_TRUE(connection_.BlackholeDetectionInProgress());
- }
-}
-
-TEST_P(QuicConnectionTest, ProcessUndecryptablePacketsBasedOnEncryptionLevel) {
- if (!connection_.SupportsMultiplePacketNumberSpaces()) {
- return;
- }
- // SetFromConfig is always called after construction from InitializeSession.
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
- EXPECT_CALL(visitor_, OnHandshakePacketSent()).Times(AnyNumber());
- QuicConfig config;
- connection_.SetFromConfig(config);
- connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
- connection_.RemoveDecrypter(ENCRYPTION_FORWARD_SECURE);
- use_tagging_decrypter();
-
- peer_framer_.SetEncrypter(ENCRYPTION_HANDSHAKE,
- std::make_unique<TaggingEncrypter>(0x01));
- peer_framer_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
- std::make_unique<TaggingEncrypter>(0x02));
-
- for (uint64_t i = 1; i <= 3; ++i) {
- ProcessDataPacketAtLevel(i, !kHasStopWaiting, ENCRYPTION_HANDSHAKE);
- }
- ProcessDataPacketAtLevel(4, !kHasStopWaiting, ENCRYPTION_FORWARD_SECURE);
- for (uint64_t j = 5; j <= 7; ++j) {
- ProcessDataPacketAtLevel(j, !kHasStopWaiting, ENCRYPTION_HANDSHAKE);
- }
- EXPECT_EQ(7u, QuicConnectionPeer::NumUndecryptablePackets(&connection_));
- EXPECT_FALSE(connection_.GetProcessUndecryptablePacketsAlarm()->IsSet());
- SetDecrypter(ENCRYPTION_HANDSHAKE,
- std::make_unique<StrictTaggingDecrypter>(0x01));
- EXPECT_TRUE(connection_.GetProcessUndecryptablePacketsAlarm()->IsSet());
- connection_.SetEncrypter(ENCRYPTION_HANDSHAKE,
- std::make_unique<TaggingEncrypter>(0x01));
- connection_.SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE);
- // Verify all ENCRYPTION_HANDSHAKE packets get processed.
- if (!VersionHasIetfQuicFrames(version().transport_version)) {
- EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(6);
- }
- connection_.GetProcessUndecryptablePacketsAlarm()->Fire();
- EXPECT_EQ(1u, QuicConnectionPeer::NumUndecryptablePackets(&connection_));
-
- SetDecrypter(ENCRYPTION_FORWARD_SECURE,
- std::make_unique<StrictTaggingDecrypter>(0x02));
- EXPECT_TRUE(connection_.GetProcessUndecryptablePacketsAlarm()->IsSet());
- connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
- connection_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
- std::make_unique<TaggingEncrypter>(0x02));
- // Verify the 1-RTT packet gets processed.
- EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
- connection_.GetProcessUndecryptablePacketsAlarm()->Fire();
- EXPECT_EQ(0u, QuicConnectionPeer::NumUndecryptablePackets(&connection_));
-}
-
-TEST_P(QuicConnectionTest, ServerBundlesInitialDataWithInitialAck) {
- if (!connection_.SupportsMultiplePacketNumberSpaces()) {
- return;
- }
- set_perspective(Perspective::IS_SERVER);
- if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
- EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
- }
- EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber());
- use_tagging_decrypter();
- // Receives packet 1000 in initial data.
- ProcessCryptoPacketAtLevel(1000, ENCRYPTION_INITIAL);
- EXPECT_TRUE(connection_.HasPendingAcks());
-
- connection_.SetEncrypter(ENCRYPTION_INITIAL,
- std::make_unique<TaggingEncrypter>(0x01));
- connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
- connection_.SendCryptoDataWithString("foo", 0, ENCRYPTION_INITIAL);
- QuicTime expected_pto_time =
- connection_.sent_packet_manager().GetRetransmissionTime();
-
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
- connection_.SetEncrypter(ENCRYPTION_HANDSHAKE,
- std::make_unique<TaggingEncrypter>(0x02));
- connection_.SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE);
- EXPECT_CALL(visitor_, OnHandshakePacketSent()).Times(1);
- connection_.SendCryptoDataWithString("foo", 0, ENCRYPTION_HANDSHAKE);
- // Verify PTO time does not change.
- EXPECT_EQ(expected_pto_time,
- connection_.sent_packet_manager().GetRetransmissionTime());
-
- // Receives packet 1001 in initial data.
- ProcessCryptoPacketAtLevel(1001, ENCRYPTION_INITIAL);
- EXPECT_TRUE(connection_.HasPendingAcks());
- // Receives packet 1002 in initial data.
- ProcessCryptoPacketAtLevel(1002, ENCRYPTION_INITIAL);
- EXPECT_FALSE(writer_->ack_frames().empty());
- // Verify CRYPTO frame is bundled with INITIAL ACK.
- EXPECT_FALSE(writer_->crypto_frames().empty());
- // Verify PTO time changes.
- EXPECT_NE(expected_pto_time,
- connection_.sent_packet_manager().GetRetransmissionTime());
-}
-
-TEST_P(QuicConnectionTest, ClientBundlesHandshakeDataWithHandshakeAck) {
- if (!connection_.SupportsMultiplePacketNumberSpaces()) {
- return;
- }
- EXPECT_EQ(Perspective::IS_CLIENT, connection_.perspective());
- if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
- EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
- }
- EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber());
- use_tagging_decrypter();
- connection_.SetEncrypter(ENCRYPTION_HANDSHAKE,
- std::make_unique<TaggingEncrypter>(0x02));
- connection_.SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE);
- SetDecrypter(ENCRYPTION_HANDSHAKE,
- std::make_unique<StrictTaggingDecrypter>(0x02));
- peer_framer_.SetEncrypter(ENCRYPTION_HANDSHAKE,
- std::make_unique<TaggingEncrypter>(0x02));
- // Receives packet 1000 in handshake data.
- ProcessCryptoPacketAtLevel(1000, ENCRYPTION_HANDSHAKE);
- EXPECT_TRUE(connection_.HasPendingAcks());
- EXPECT_CALL(visitor_, OnHandshakePacketSent()).Times(1);
- connection_.SendCryptoDataWithString("foo", 0, ENCRYPTION_HANDSHAKE);
-
- // Receives packet 1001 in handshake data.
- ProcessCryptoPacketAtLevel(1001, ENCRYPTION_HANDSHAKE);
- EXPECT_TRUE(connection_.HasPendingAcks());
- // Receives packet 1002 in handshake data.
- ProcessCryptoPacketAtLevel(1002, ENCRYPTION_HANDSHAKE);
- EXPECT_FALSE(writer_->ack_frames().empty());
- // Verify CRYPTO frame is bundled with HANDSHAKE ACK.
- EXPECT_FALSE(writer_->crypto_frames().empty());
-}
-
-// Regresstion test for b/156232673.
-TEST_P(QuicConnectionTest, CoalescePacketOfLowerEncryptionLevel) {
- if (!connection_.version().CanSendCoalescedPackets()) {
- return;
- }
- EXPECT_CALL(visitor_, OnHandshakePacketSent()).Times(1);
- {
- QuicConnection::ScopedPacketFlusher flusher(&connection_);
- use_tagging_decrypter();
- connection_.SetEncrypter(ENCRYPTION_HANDSHAKE,
- std::make_unique<TaggingEncrypter>(0x01));
- connection_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
- std::make_unique<TaggingEncrypter>(0x02));
- connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
- SendStreamDataToPeer(2, std::string(1286, 'a'), 0, NO_FIN, nullptr);
- connection_.SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE);
- // Try to coalesce a HANDSHAKE packet after 1-RTT packet.
- // Verify soft max packet length gets resumed and handshake packet gets
- // successfully sent.
- connection_.SendCryptoDataWithString("a", 0, ENCRYPTION_HANDSHAKE);
- }
-}
-
-// Regression test for b/160790422.
-TEST_P(QuicConnectionTest, ServerRetransmitsHandshakeDataEarly) {
- if (!connection_.SupportsMultiplePacketNumberSpaces()) {
- return;
- }
- set_perspective(Perspective::IS_SERVER);
- if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
- EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
- }
- EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber());
- use_tagging_decrypter();
- // Receives packet 1000 in initial data.
- ProcessCryptoPacketAtLevel(1000, ENCRYPTION_INITIAL);
- EXPECT_TRUE(connection_.HasPendingAcks());
-
- connection_.SetEncrypter(ENCRYPTION_INITIAL,
- std::make_unique<TaggingEncrypter>(0x01));
- connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
- // Send INITIAL 1.
- connection_.SendCryptoDataWithString("foo", 0, ENCRYPTION_INITIAL);
- QuicTime expected_pto_time =
- connection_.sent_packet_manager().GetRetransmissionTime();
-
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
- connection_.SetEncrypter(ENCRYPTION_HANDSHAKE,
- std::make_unique<TaggingEncrypter>(0x02));
- connection_.SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE);
- EXPECT_CALL(visitor_, OnHandshakePacketSent()).Times(1);
- // Send HANDSHAKE 2 and 3.
- connection_.SendCryptoDataWithString("foo", 0, ENCRYPTION_HANDSHAKE);
- connection_.SendCryptoDataWithString("bar", 3, ENCRYPTION_HANDSHAKE);
- // Verify PTO time does not change.
- EXPECT_EQ(expected_pto_time,
- connection_.sent_packet_manager().GetRetransmissionTime());
-
- // Receives ACK for HANDSHAKE 2.
- QuicFrames frames;
- auto ack_frame = InitAckFrame({{QuicPacketNumber(2), QuicPacketNumber(3)}});
- frames.push_back(QuicFrame(&ack_frame));
- EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _));
- ProcessFramesPacketAtLevel(30, frames, ENCRYPTION_HANDSHAKE);
- // Discard INITIAL key.
- connection_.RemoveEncrypter(ENCRYPTION_INITIAL);
- connection_.NeuterUnencryptedPackets();
- // Receives PING from peer.
- frames.clear();
- frames.push_back(QuicFrame(QuicPingFrame()));
- frames.push_back(QuicFrame(QuicPaddingFrame(3)));
- ProcessFramesPacketAtLevel(31, frames, ENCRYPTION_HANDSHAKE);
- EXPECT_EQ(clock_.Now() + kAlarmGranularity,
- connection_.GetAckAlarm()->deadline());
- // Fire ACK alarm.
- clock_.AdvanceTime(kAlarmGranularity);
- connection_.GetAckAlarm()->Fire();
- EXPECT_FALSE(writer_->ack_frames().empty());
- // Verify handshake data gets retransmitted early.
- EXPECT_FALSE(writer_->crypto_frames().empty());
-}
-
-// Regression test for b/161228202
-TEST_P(QuicConnectionTest, InflatedRttSample) {
- if (!connection_.SupportsMultiplePacketNumberSpaces()) {
- return;
- }
- // 30ms RTT.
- const QuicTime::Delta kTestRTT = QuicTime::Delta::FromMilliseconds(30);
- set_perspective(Perspective::IS_SERVER);
- RttStats* rtt_stats = const_cast<RttStats*>(manager_->GetRttStats());
- use_tagging_decrypter();
- // Receives packet 1000 in initial data.
- if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
- EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
- }
- EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber());
- ProcessCryptoPacketAtLevel(1000, ENCRYPTION_INITIAL);
- EXPECT_TRUE(connection_.HasPendingAcks());
-
- connection_.SetEncrypter(ENCRYPTION_INITIAL,
- std::make_unique<TaggingEncrypter>(0x01));
- connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
- // Send INITIAL 1.
- std::string initial_crypto_data(512, 'a');
- connection_.SendCryptoDataWithString(initial_crypto_data, 0,
- ENCRYPTION_INITIAL);
- ASSERT_TRUE(connection_.sent_packet_manager()
- .GetRetransmissionTime()
- .IsInitialized());
- QuicTime::Delta pto_timeout =
- connection_.sent_packet_manager().GetRetransmissionTime() - clock_.Now();
- // Send Handshake 2.
- connection_.SetEncrypter(ENCRYPTION_HANDSHAKE,
- std::make_unique<TaggingEncrypter>(0x02));
- connection_.SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE);
- EXPECT_CALL(visitor_, OnHandshakePacketSent()).Times(1);
- std::string handshake_crypto_data(1024, 'a');
- connection_.SendCryptoDataWithString(handshake_crypto_data, 0,
- ENCRYPTION_HANDSHAKE);
-
- // INITIAL 1 gets lost and PTO fires.
- clock_.AdvanceTime(pto_timeout);
- connection_.GetRetransmissionAlarm()->Fire();
-
- clock_.AdvanceTime(kTestRTT);
- // Assume retransmitted INITIAL gets received.
- QuicFrames frames;
- QuicPacketNumber initial_retransmission =
- GetQuicReloadableFlag(quic_default_on_pto) ? QuicPacketNumber(3)
- : QuicPacketNumber(4);
- auto ack_frame =
- InitAckFrame({{initial_retransmission, initial_retransmission + 1}});
- frames.push_back(QuicFrame(&ack_frame));
- EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _))
- .Times(AnyNumber());
- ProcessFramesPacketAtLevel(1001, frames, ENCRYPTION_INITIAL);
- EXPECT_EQ(kTestRTT, rtt_stats->latest_rtt());
- // Because retransmitted INITIAL gets received so HANDSHAKE 2 gets processed.
- frames.clear();
- // HANDSHAKE 5 is also processed.
- QuicAckFrame ack_frame2 =
- InitAckFrame({{QuicPacketNumber(2), QuicPacketNumber(3)},
- {initial_retransmission + 1, initial_retransmission + 2}});
- ack_frame2.ack_delay_time = QuicTime::Delta::Zero();
- frames.push_back(QuicFrame(&ack_frame2));
- ProcessFramesPacketAtLevel(1, frames, ENCRYPTION_HANDSHAKE);
- // Verify RTT inflation gets mitigated.
- EXPECT_EQ(rtt_stats->latest_rtt(), kTestRTT);
-}
-
-// Regression test for b/161228202
-TEST_P(QuicConnectionTest, CoalscingPacketCausesInfiniteLoop) {
- if (!connection_.SupportsMultiplePacketNumberSpaces()) {
- return;
- }
- set_perspective(Perspective::IS_SERVER);
- use_tagging_decrypter();
- // Receives packet 1000 in initial data.
- if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
- EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
- }
- EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber());
-
- // Set anti amplification factor to 2, such that RetransmitDataOfSpaceIfAny
- // makes no forward progress and causes infinite loop.
- SetQuicFlag(FLAGS_quic_anti_amplification_factor, 2);
-
- ProcessCryptoPacketAtLevel(1000, ENCRYPTION_INITIAL);
- EXPECT_TRUE(connection_.HasPendingAcks());
-
- connection_.SetEncrypter(ENCRYPTION_INITIAL,
- std::make_unique<TaggingEncrypter>(0x01));
- connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
- // Send INITIAL 1.
- std::string initial_crypto_data(512, 'a');
- connection_.SendCryptoDataWithString(initial_crypto_data, 0,
- ENCRYPTION_INITIAL);
- ASSERT_TRUE(connection_.sent_packet_manager()
- .GetRetransmissionTime()
- .IsInitialized());
- QuicTime::Delta pto_timeout =
- connection_.sent_packet_manager().GetRetransmissionTime() - clock_.Now();
- // Send Handshake 2.
- connection_.SetEncrypter(ENCRYPTION_HANDSHAKE,
- std::make_unique<TaggingEncrypter>(0x02));
- connection_.SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE);
- // Verify HANDSHAKE packet is coalesced with INITIAL retransmission.
- EXPECT_CALL(visitor_, OnHandshakePacketSent()).Times(1);
- std::string handshake_crypto_data(1024, 'a');
- connection_.SendCryptoDataWithString(handshake_crypto_data, 0,
- ENCRYPTION_HANDSHAKE);
-
- // INITIAL 1 gets lost and PTO fires.
- clock_.AdvanceTime(pto_timeout);
- connection_.GetRetransmissionAlarm()->Fire();
-}
-
-TEST_P(QuicConnectionTest, ClientAckDelayForAsyncPacketProcessing) {
- if (!version().HasIetfQuicFrames()) {
- return;
- }
- // SetFromConfig is always called after construction from InitializeSession.
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
- EXPECT_CALL(visitor_, OnHandshakePacketSent()).Times(AnyNumber());
- QuicConfig config;
- connection_.SetFromConfig(config);
- connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
- use_tagging_decrypter();
- connection_.SetEncrypter(ENCRYPTION_INITIAL,
- std::make_unique<TaggingEncrypter>(0x01));
- peer_framer_.SetEncrypter(ENCRYPTION_HANDSHAKE,
- std::make_unique<TaggingEncrypter>(0x01));
- EXPECT_EQ(0u, QuicConnectionPeer::NumUndecryptablePackets(&connection_));
-
- // Received undecryptable HANDSHAKE 2.
- ProcessDataPacketAtLevel(2, !kHasStopWaiting, ENCRYPTION_HANDSHAKE);
- ASSERT_EQ(1u, QuicConnectionPeer::NumUndecryptablePackets(&connection_));
- // Received INITIAL 4 (which is retransmission of INITIAL 1) after 100ms.
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(100));
- ProcessDataPacketAtLevel(4, !kHasStopWaiting, ENCRYPTION_INITIAL);
- // Generate HANDSHAKE key.
- SetDecrypter(ENCRYPTION_HANDSHAKE,
- std::make_unique<StrictTaggingDecrypter>(0x01));
- EXPECT_TRUE(connection_.GetProcessUndecryptablePacketsAlarm()->IsSet());
- connection_.SetEncrypter(ENCRYPTION_HANDSHAKE,
- std::make_unique<TaggingEncrypter>(0x01));
- connection_.SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE);
- // Verify HANDSHAKE packet gets processed.
- connection_.GetProcessUndecryptablePacketsAlarm()->Fire();
- ASSERT_TRUE(connection_.HasPendingAcks());
- // Send ACKs.
- clock_.AdvanceTime(connection_.GetAckAlarm()->deadline() - clock_.Now());
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(2);
- connection_.GetAckAlarm()->Fire();
- ASSERT_FALSE(writer_->ack_frames().empty());
- // 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());
- if (GetQuicReloadableFlag(
- quic_reset_per_packet_state_for_undecryptable_packets)) {
- // Verify the ack_delay_time in the HANDSHAKE ACK frame includes the
- // buffering time.
- EXPECT_EQ(QuicTime::Delta::FromMilliseconds(101),
- writer_->ack_frames()[0].ack_delay_time);
- } else {
- // This ack_delay_time is wrong.
- EXPECT_EQ(QuicTime::Delta::FromMilliseconds(1),
- writer_->ack_frames()[0].ack_delay_time);
- }
- ASSERT_TRUE(writer_->coalesced_packet() == nullptr);
-}
-
-TEST_P(QuicConnectionTest, TestingLiveness) {
- const size_t kMinRttMs = 40;
- RttStats* rtt_stats = const_cast<RttStats*>(manager_->GetRttStats());
- rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(kMinRttMs),
- QuicTime::Delta::Zero(), QuicTime::Zero());
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
- QuicConfig config;
-
- CryptoHandshakeMessage msg;
- std::string error_details;
- QuicConfig client_config;
- client_config.SetInitialStreamFlowControlWindowToSend(
- kInitialStreamFlowControlWindowForTest);
- client_config.SetInitialSessionFlowControlWindowToSend(
- kInitialSessionFlowControlWindowForTest);
- client_config.SetIdleNetworkTimeout(QuicTime::Delta::FromSeconds(30));
- client_config.ToHandshakeMessage(&msg, connection_.transport_version());
- const QuicErrorCode error =
- config.ProcessPeerHello(msg, CLIENT, &error_details);
- EXPECT_THAT(error, IsQuicNoError());
-
- if (connection_.version().UsesTls()) {
- QuicConfigPeer::SetReceivedOriginalConnectionId(
- &config, connection_.connection_id());
- QuicConfigPeer::SetReceivedInitialSourceConnectionId(
- &config, connection_.connection_id());
- }
-
- connection_.SetFromConfig(config);
- connection_.OnHandshakeComplete();
- connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
- ASSERT_TRUE(connection_.GetTimeoutAlarm()->IsSet());
- EXPECT_FALSE(connection_.MaybeTestLiveness());
-
- QuicTime deadline = connection_.GetTimeoutAlarm()->deadline();
- 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());
-}
-
-TEST_P(QuicConnectionTest, SilentIdleTimeout) {
- set_perspective(Perspective::IS_SERVER);
- QuicPacketCreatorPeer::SetSendVersionInPacket(creator_, false);
- if (version().SupportsAntiAmplificationLimit()) {
- QuicConnectionPeer::SetAddressValidated(&connection_);
- }
-
- QuicConfig config;
- QuicConfigPeer::SetNegotiated(&config, true);
- if (connection_.version().UsesTls()) {
- QuicConfigPeer::SetReceivedOriginalConnectionId(
- &config, connection_.connection_id());
- QuicConfigPeer::SetReceivedInitialSourceConnectionId(&config,
- QuicConnectionId());
- }
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
- connection_.SetFromConfig(config);
-
- EXPECT_TRUE(connection_.connected());
- EXPECT_TRUE(connection_.GetTimeoutAlarm()->IsSet());
-
- if (version().handshake_protocol == PROTOCOL_TLS1_3) {
- EXPECT_CALL(visitor_, BeforeConnectionCloseSent());
- }
- EXPECT_CALL(visitor_,
- OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF));
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
- connection_.GetTimeoutAlarm()->Fire();
- // Verify the connection close packets get serialized and added to
- // termination packets list.
- EXPECT_NE(nullptr,
- QuicConnectionPeer::GetConnectionClosePacket(&connection_));
-}
-
-TEST_P(QuicConnectionTest, DonotSendPing) {
- connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
- connection_.OnHandshakeComplete();
- EXPECT_TRUE(connection_.connected());
- EXPECT_CALL(visitor_, ShouldKeepConnectionAlive())
- .WillRepeatedly(Return(true));
- EXPECT_FALSE(connection_.GetPingAlarm()->IsSet());
- EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
-
- SendStreamDataToPeer(
- GetNthClientInitiatedStreamId(0, connection_.transport_version()),
- "GET /", 0, FIN, nullptr);
- EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
- EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
- EXPECT_EQ(QuicTime::Delta::FromSeconds(15),
- connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
-
- // Now recevie an ACK and response of the previous packet, which will move the
- // ping alarm forward.
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
- QuicFrames frames;
- QuicAckFrame ack_frame = InitAckFrame(1);
- frames.push_back(QuicFrame(&ack_frame));
- frames.push_back(QuicFrame(QuicStreamFrame(
- GetNthClientInitiatedStreamId(0, connection_.transport_version()), true,
- 0u, absl::string_view())));
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
- EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
- ProcessFramesPacketAtLevel(1, frames, ENCRYPTION_FORWARD_SECURE);
- EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
- EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
- // The ping timer is set slightly less than 15 seconds in the future, because
- // of the 1s ping timer alarm granularity.
- EXPECT_EQ(
- QuicTime::Delta::FromSeconds(15) - QuicTime::Delta::FromMilliseconds(5),
- connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
-
- clock_.AdvanceTime(QuicTime::Delta::FromSeconds(15));
- // Suppose now ShouldKeepConnectionAlive returns false.
- EXPECT_CALL(visitor_, ShouldKeepConnectionAlive())
- .WillRepeatedly(Return(false));
- // Verify PING does not get sent.
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
- connection_.GetPingAlarm()->Fire();
-}
-
-// Regression test for b/159698337
-TEST_P(QuicConnectionTest, DuplicateAckCausesLostPackets) {
- if (!GetQuicReloadableFlag(quic_default_enable_5rto_blackhole_detection2)) {
- return;
- }
- // Finish handshake.
- connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
- notifier_.NeuterUnencryptedData();
- connection_.NeuterUnencryptedPackets();
- connection_.OnHandshakeComplete();
- EXPECT_CALL(visitor_, GetHandshakeState())
- .WillRepeatedly(Return(HANDSHAKE_COMPLETE));
-
- std::string data(1200, 'a');
- // Send data packets 1 - 5.
- for (size_t i = 0; i < 5; ++i) {
- SendStreamDataToPeer(
- GetNthClientInitiatedStreamId(1, connection_.transport_version()), data,
- i * 1200, i == 4 ? FIN : NO_FIN, nullptr);
- }
- ASSERT_TRUE(connection_.BlackholeDetectionInProgress());
-
- EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _)).Times(3);
-
- // ACK packet 5 and 1 and 2 are detected lost.
- QuicAckFrame frame =
- InitAckFrame({{QuicPacketNumber(5), QuicPacketNumber(6)}});
- LostPacketVector lost_packets;
- lost_packets.push_back(
- LostPacket(QuicPacketNumber(1), kMaxOutgoingPacketSize));
- lost_packets.push_back(
- LostPacket(QuicPacketNumber(2), kMaxOutgoingPacketSize));
- EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _))
- .Times(AnyNumber())
- .WillOnce(DoAll(SetArgPointee<5>(lost_packets),
- Return(LossDetectionInterface::DetectionStats())));
- ProcessAckPacket(1, &frame);
- EXPECT_TRUE(connection_.BlackholeDetectionInProgress());
- QuicAlarm* retransmission_alarm = connection_.GetRetransmissionAlarm();
- EXPECT_TRUE(retransmission_alarm->IsSet());
-
- // ACK packet 1 - 5 and 7.
- QuicAckFrame frame2 =
- InitAckFrame({{QuicPacketNumber(1), QuicPacketNumber(6)},
- {QuicPacketNumber(7), QuicPacketNumber(8)}});
- ProcessAckPacket(2, &frame2);
- EXPECT_TRUE(connection_.BlackholeDetectionInProgress());
-
- // ACK packet 7 again and assume packet 6 is detected lost.
- QuicAckFrame frame3 =
- InitAckFrame({{QuicPacketNumber(7), QuicPacketNumber(8)}});
- lost_packets.clear();
- lost_packets.push_back(
- LostPacket(QuicPacketNumber(6), kMaxOutgoingPacketSize));
- EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _))
- .Times(AnyNumber())
- .WillOnce(DoAll(SetArgPointee<5>(lost_packets),
- Return(LossDetectionInterface::DetectionStats())));
- ProcessAckPacket(3, &frame3);
- // Make sure loss detection is cancelled even there is no new acked packets.
- EXPECT_FALSE(connection_.BlackholeDetectionInProgress());
-}
-
-TEST_P(QuicConnectionTest, ShorterIdleTimeoutOnSentPackets) {
- EXPECT_TRUE(connection_.connected());
- RttStats* rtt_stats = const_cast<RttStats*>(manager_->GetRttStats());
- rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(100),
- QuicTime::Delta::Zero(), QuicTime::Zero());
-
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
- QuicConfig config;
- config.SetClientConnectionOptions(QuicTagVector{kFIDT});
- 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);
-
- ASSERT_TRUE(connection_.GetTimeoutAlarm()->IsSet());
- // Send a packet close to timeout.
- QuicTime::Delta timeout =
- connection_.GetTimeoutAlarm()->deadline() - clock_.Now();
- clock_.AdvanceTime(timeout - QuicTime::Delta::FromSeconds(1));
- // Send stream data.
- SendStreamDataToPeer(
- GetNthClientInitiatedStreamId(1, connection_.transport_version()), "foo",
- 0, FIN, nullptr);
- // Verify this sent packet does not extend idle timeout since 1s is > PTO
- // delay.
- ASSERT_TRUE(connection_.GetTimeoutAlarm()->IsSet());
- EXPECT_EQ(QuicTime::Delta::FromSeconds(1),
- connection_.GetTimeoutAlarm()->deadline() - clock_.Now());
-
- // Received an ACK 100ms later.
- clock_.AdvanceTime(timeout - QuicTime::Delta::FromMilliseconds(100));
- QuicAckFrame ack = InitAckFrame(1);
- EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
- ProcessAckPacket(1, &ack);
- // Verify idle timeout gets extended.
- EXPECT_EQ(clock_.Now() + timeout, connection_.GetTimeoutAlarm()->deadline());
-}
-
-// Regression test for b/166255274
-TEST_P(QuicConnectionTest,
- ReserializeInitialPacketInCoalescerAfterDiscardingInitialKey) {
- if (!connection_.version().CanSendCoalescedPackets()) {
- return;
- }
- use_tagging_decrypter();
- connection_.SetEncrypter(ENCRYPTION_INITIAL,
- std::make_unique<TaggingEncrypter>(0x01));
- connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
- EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(1);
- ProcessCryptoPacketAtLevel(1, ENCRYPTION_INITIAL);
- EXPECT_TRUE(connection_.HasPendingAcks());
- connection_.SetEncrypter(ENCRYPTION_HANDSHAKE,
- std::make_unique<TaggingEncrypter>(0x02));
- connection_.SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE);
- EXPECT_CALL(visitor_, OnHandshakePacketSent()).WillOnce(Invoke([this]() {
- connection_.RemoveEncrypter(ENCRYPTION_INITIAL);
- connection_.NeuterUnencryptedPackets();
- }));
- {
- QuicConnection::ScopedPacketFlusher flusher(&connection_);
- connection_.SendCryptoDataWithString("foo", 0, ENCRYPTION_HANDSHAKE);
- // Verify the packet is on hold.
- EXPECT_EQ(0u, writer_->packets_write_attempts());
- // Flush pending ACKs.
- connection_.GetAckAlarm()->Fire();
- }
- EXPECT_FALSE(connection_.packet_creator().HasPendingFrames());
- // The ACK frame is deleted along with initial_packet_ in coalescer. Sending
- // connection close would cause this (released) ACK frame be serialized (and
- // crashes).
- EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
- ProcessDataPacketAtLevel(1000, false, ENCRYPTION_FORWARD_SECURE);
- EXPECT_TRUE(connection_.connected());
-}
-
-TEST_P(QuicConnectionTest, PathValidationOnNewSocketSuccess) {
- if (!VersionHasIetfQuicFrames(connection_.version().transport_version) ||
- !connection_.use_path_validator()) {
- return;
- }
- PathProbeTestInit(Perspective::IS_CLIENT);
- const QuicSocketAddress kNewSelfAddress(QuicIpAddress::Any4(), 12345);
- EXPECT_NE(kNewSelfAddress, connection_.self_address());
- TestPacketWriter new_writer(version(), &clock_, Perspective::IS_CLIENT);
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
- .Times(AtLeast(1u))
- .WillOnce(Invoke([&]() {
- EXPECT_EQ(1u, new_writer.packets_write_attempts());
- EXPECT_EQ(1u, new_writer.path_challenge_frames().size());
- EXPECT_EQ(1u, new_writer.padding_frames().size());
- EXPECT_EQ(kNewSelfAddress.host(),
- new_writer.last_write_source_address());
- }));
- bool success = false;
- connection_.ValidatePath(
- std::make_unique<TestQuicPathValidationContext>(
- kNewSelfAddress, connection_.peer_address(), &new_writer),
- std::make_unique<TestValidationResultDelegate>(
- &connection_, kNewSelfAddress, connection_.peer_address(), &success));
- EXPECT_EQ(0u, writer_->packets_write_attempts());
-
- QuicFrames frames;
- frames.push_back(QuicFrame(new QuicPathResponseFrame(
- 99, new_writer.path_challenge_frames().front().data_buffer)));
- ProcessFramesPacketWithAddresses(frames, kNewSelfAddress, kPeerAddress,
- ENCRYPTION_FORWARD_SECURE);
- EXPECT_TRUE(success);
-}
-
-TEST_P(QuicConnectionTest, NewPathValidationCancelsPreviousOne) {
- if (!VersionHasIetfQuicFrames(connection_.version().transport_version) ||
- !connection_.use_path_validator()) {
- return;
- }
- PathProbeTestInit(Perspective::IS_CLIENT);
- const QuicSocketAddress kNewSelfAddress(QuicIpAddress::Any4(), 12345);
- EXPECT_NE(kNewSelfAddress, connection_.self_address());
- TestPacketWriter new_writer(version(), &clock_, Perspective::IS_CLIENT);
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
- .Times(AtLeast(1u))
- .WillOnce(Invoke([&]() {
- EXPECT_EQ(1u, new_writer.packets_write_attempts());
- EXPECT_EQ(1u, new_writer.path_challenge_frames().size());
- EXPECT_EQ(1u, new_writer.padding_frames().size());
- EXPECT_EQ(kNewSelfAddress.host(),
- new_writer.last_write_source_address());
- }));
- bool success = true;
- connection_.ValidatePath(
- std::make_unique<TestQuicPathValidationContext>(
- kNewSelfAddress, connection_.peer_address(), &new_writer),
- std::make_unique<TestValidationResultDelegate>(
- &connection_, kNewSelfAddress, connection_.peer_address(), &success));
- EXPECT_EQ(0u, writer_->packets_write_attempts());
-
- // Start another path validation request.
- const QuicSocketAddress kNewSelfAddress2(QuicIpAddress::Any4(), 12346);
- EXPECT_NE(kNewSelfAddress2, connection_.self_address());
- TestPacketWriter new_writer2(version(), &clock_, Perspective::IS_CLIENT);
- if (!connection_.connection_migration_use_new_cid()) {
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
- .Times(AtLeast(1u))
- .WillOnce(Invoke([&]() {
- EXPECT_EQ(1u, new_writer2.packets_write_attempts());
- EXPECT_EQ(1u, new_writer2.path_challenge_frames().size());
- EXPECT_EQ(1u, new_writer2.padding_frames().size());
- EXPECT_EQ(kNewSelfAddress2.host(),
- new_writer2.last_write_source_address());
- }));
- }
- bool success2 = false;
- connection_.ValidatePath(
- std::make_unique<TestQuicPathValidationContext>(
- kNewSelfAddress2, connection_.peer_address(), &new_writer2),
- std::make_unique<TestValidationResultDelegate>(
- &connection_, kNewSelfAddress2, connection_.peer_address(),
- &success2));
- EXPECT_FALSE(success);
- if (connection_.connection_migration_use_new_cid()) {
- // There is no pening path validation as there is no available connection
- // ID.
- EXPECT_FALSE(connection_.HasPendingPathValidation());
- } else {
- EXPECT_TRUE(connection_.HasPendingPathValidation());
- }
-}
-
-// Regression test for b/182571515.
-TEST_P(QuicConnectionTest, PathValidationRetry) {
- if (!VersionHasIetfQuicFrames(connection_.version().transport_version) ||
- !connection_.use_path_validator()) {
- return;
- }
- PathProbeTestInit(Perspective::IS_CLIENT);
-
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
- .Times(2u)
- .WillRepeatedly(Invoke([&]() {
- EXPECT_EQ(1u, writer_->path_challenge_frames().size());
- EXPECT_EQ(1u, writer_->padding_frames().size());
- }));
- bool success = true;
- connection_.ValidatePath(std::make_unique<TestQuicPathValidationContext>(
- connection_.self_address(),
- connection_.peer_address(), writer_.get()),
- std::make_unique<TestValidationResultDelegate>(
- &connection_, connection_.self_address(),
- connection_.peer_address(), &success));
- EXPECT_EQ(1u, writer_->packets_write_attempts());
- EXPECT_TRUE(connection_.HasPendingPathValidation());
-
- // Retry after time out.
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(3 * kInitialRttMs));
- static_cast<test::MockRandom*>(helper_->GetRandomGenerator())->ChangeValue();
- static_cast<TestAlarmFactory::TestAlarm*>(
- QuicPathValidatorPeer::retry_timer(
- QuicConnectionPeer::path_validator(&connection_)))
- ->Fire();
- EXPECT_EQ(2u, writer_->packets_write_attempts());
-}
-
-TEST_P(QuicConnectionTest, PathValidationReceivesStatelessReset) {
- if (!VersionHasIetfQuicFrames(connection_.version().transport_version) ||
- !connection_.use_path_validator()) {
- return;
- }
- PathProbeTestInit(Perspective::IS_CLIENT);
- QuicConfig config;
- QuicConfigPeer::SetReceivedStatelessResetToken(&config,
- kTestStatelessResetToken);
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
- connection_.SetFromConfig(config);
- const QuicSocketAddress kNewSelfAddress(QuicIpAddress::Any4(), 12345);
- EXPECT_NE(kNewSelfAddress, connection_.self_address());
- TestPacketWriter new_writer(version(), &clock_, Perspective::IS_CLIENT);
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
- .Times(AtLeast(1u))
- .WillOnce(Invoke([&]() {
- EXPECT_EQ(1u, new_writer.packets_write_attempts());
- EXPECT_EQ(1u, new_writer.path_challenge_frames().size());
- EXPECT_EQ(1u, new_writer.padding_frames().size());
- EXPECT_EQ(kNewSelfAddress.host(),
- new_writer.last_write_source_address());
- }));
- bool success = true;
- connection_.ValidatePath(
- std::make_unique<TestQuicPathValidationContext>(
- kNewSelfAddress, connection_.peer_address(), &new_writer),
- std::make_unique<TestValidationResultDelegate>(
- &connection_, kNewSelfAddress, connection_.peer_address(), &success));
- EXPECT_EQ(0u, writer_->packets_write_attempts());
- EXPECT_TRUE(connection_.HasPendingPathValidation());
-
- std::unique_ptr<QuicEncryptedPacket> packet(
- QuicFramer::BuildIetfStatelessResetPacket(connection_id_,
- /*received_packet_length=*/100,
- kTestStatelessResetToken));
- std::unique_ptr<QuicReceivedPacket> received(
- ConstructReceivedPacket(*packet, QuicTime::Zero()));
- EXPECT_CALL(visitor_, OnConnectionClosed(_, _)).Times(0);
- connection_.ProcessUdpPacket(kNewSelfAddress, kPeerAddress, *received);
- EXPECT_FALSE(connection_.HasPendingPathValidation());
- EXPECT_FALSE(success);
-}
-
-// Tests that PATH_CHALLENGE is dropped if it is sent via a blocked alternative
-// writer.
-TEST_P(QuicConnectionTest, SendPathChallengeUsingBlockedNewSocket) {
- if (!VersionHasIetfQuicFrames(connection_.version().transport_version) ||
- !connection_.connection_migration_use_new_cid()) {
- return;
- }
- PathProbeTestInit(Perspective::IS_CLIENT);
- const QuicSocketAddress kNewSelfAddress(QuicIpAddress::Any4(), 12345);
- EXPECT_NE(kNewSelfAddress, connection_.self_address());
- TestPacketWriter new_writer(version(), &clock_, Perspective::IS_CLIENT);
- new_writer.BlockOnNextWrite();
- EXPECT_CALL(visitor_, OnWriteBlocked()).Times(0);
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
- .Times(AtLeast(1))
- .WillOnce(Invoke([&]() {
- // Even though the socket is blocked, the PATH_CHALLENGE should still be
- // treated as sent.
- EXPECT_EQ(1u, new_writer.packets_write_attempts());
- EXPECT_EQ(1u, new_writer.path_challenge_frames().size());
- EXPECT_EQ(1u, new_writer.padding_frames().size());
- EXPECT_EQ(kNewSelfAddress.host(),
- new_writer.last_write_source_address());
- }));
- bool success = false;
- connection_.ValidatePath(
- std::make_unique<TestQuicPathValidationContext>(
- kNewSelfAddress, connection_.peer_address(), &new_writer),
- std::make_unique<TestValidationResultDelegate>(
- &connection_, kNewSelfAddress, connection_.peer_address(), &success));
- EXPECT_EQ(0u, writer_->packets_write_attempts());
-
- new_writer.SetWritable();
- // Write event on the default socket shouldn't make any difference.
- connection_.OnCanWrite();
- // A NEW_CONNECTION_ID frame is received in PathProbeTestInit and OnCanWrite
- // will write a acking packet.
- EXPECT_EQ(1u, writer_->packets_write_attempts());
- EXPECT_EQ(1u, new_writer.packets_write_attempts());
-}
-
-// Tests that PATH_CHALLENGE is dropped if it is sent via the default writer
-// and the writer is blocked.
-TEST_P(QuicConnectionTest, SendPathChallengeUsingBlockedDefaultSocket) {
- if (!VersionHasIetfQuicFrames(connection_.version().transport_version) ||
- !connection_.use_path_validator()) {
- return;
- }
- PathProbeTestInit(Perspective::IS_SERVER);
- const QuicSocketAddress kNewPeerAddress(QuicIpAddress::Any4(), 12345);
- writer_->BlockOnNextWrite();
- // 1st time is after writer returns WRITE_STATUS_BLOCKED. 2nd time is in
- // ShouldGeneratePacket().
- EXPECT_CALL(visitor_, OnWriteBlocked()).Times(AtLeast(2));
- QuicPathFrameBuffer path_challenge_payload{0, 1, 2, 3, 4, 5, 6, 7};
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
- .Times(AtLeast(1u))
- .WillOnce(Invoke([&]() {
- // This packet isn't sent actually, instead it is buffered in the
- // connection.
- EXPECT_EQ(1u, writer_->packets_write_attempts());
- if (connection_.validate_client_address()) {
- EXPECT_EQ(1u, writer_->path_response_frames().size());
- EXPECT_EQ(0,
- memcmp(&path_challenge_payload,
- &writer_->path_response_frames().front().data_buffer,
- sizeof(path_challenge_payload)));
- }
- EXPECT_EQ(1u, writer_->path_challenge_frames().size());
- EXPECT_EQ(1u, writer_->padding_frames().size());
- EXPECT_EQ(kNewPeerAddress, writer_->last_write_peer_address());
- }))
- .WillRepeatedly(Invoke([&]() {
- // Only one PATH_CHALLENGE should be sent out.
- EXPECT_EQ(0u, writer_->path_challenge_frames().size());
- }));
- bool success = false;
- if (connection_.validate_client_address()) {
- // Receiving a PATH_CHALLENGE from the new peer address should trigger
- // address validation.
- QuicFrames frames;
- frames.push_back(
- QuicFrame(new QuicPathChallengeFrame(0, path_challenge_payload)));
- ProcessFramesPacketWithAddresses(frames, kSelfAddress, kNewPeerAddress,
- ENCRYPTION_FORWARD_SECURE);
- } else {
- // Manually start to validate the new peer address.
- connection_.ValidatePath(
- std::make_unique<TestQuicPathValidationContext>(
- connection_.self_address(), kNewPeerAddress, writer_.get()),
- std::make_unique<TestValidationResultDelegate>(
- &connection_, connection_.self_address(), kNewPeerAddress,
- &success));
- }
- EXPECT_EQ(1u, writer_->packets_write_attempts());
-
- // Try again with the new socket blocked from the beginning. The 2nd
- // PATH_CHALLENGE shouldn't be serialized, but be dropped.
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(3 * kInitialRttMs));
- static_cast<test::MockRandom*>(helper_->GetRandomGenerator())->ChangeValue();
- static_cast<TestAlarmFactory::TestAlarm*>(
- QuicPathValidatorPeer::retry_timer(
- QuicConnectionPeer::path_validator(&connection_)))
- ->Fire();
-
- // No more write attempt should be made.
- EXPECT_EQ(1u, writer_->packets_write_attempts());
-
- writer_->SetWritable();
- // OnCanWrite() should actually write out the 1st PATH_CHALLENGE packet
- // buffered earlier, thus incrementing the write counter. It may also send
- // ACKs to previously received packets.
- connection_.OnCanWrite();
- EXPECT_LE(2u, writer_->packets_write_attempts());
-}
-
-// Tests that write error on the alternate socket should be ignored.
-TEST_P(QuicConnectionTest, SendPathChallengeFailOnNewSocket) {
- if (!VersionHasIetfQuicFrames(connection_.version().transport_version) ||
- !connection_.use_path_validator()) {
- return;
- }
- PathProbeTestInit(Perspective::IS_CLIENT);
- const QuicSocketAddress kNewSelfAddress(QuicIpAddress::Any4(), 12345);
- EXPECT_NE(kNewSelfAddress, connection_.self_address());
- TestPacketWriter new_writer(version(), &clock_, Perspective::IS_CLIENT);
- new_writer.SetShouldWriteFail();
- EXPECT_CALL(visitor_, OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF))
- .Times(0);
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0u);
-
- bool success = false;
- connection_.ValidatePath(
- std::make_unique<TestQuicPathValidationContext>(
- kNewSelfAddress, connection_.peer_address(), &new_writer),
- std::make_unique<TestValidationResultDelegate>(
- &connection_, kNewSelfAddress, connection_.peer_address(), &success));
- EXPECT_EQ(1u, new_writer.packets_write_attempts());
- EXPECT_EQ(1u, new_writer.path_challenge_frames().size());
- EXPECT_EQ(1u, new_writer.padding_frames().size());
- EXPECT_EQ(kNewSelfAddress.host(), new_writer.last_write_source_address());
-
- EXPECT_EQ(0u, writer_->packets_write_attempts());
- // Regardless of the write error, the connection should still be connected.
- EXPECT_TRUE(connection_.connected());
-}
-
-// Tests that write error while sending PATH_CHALLANGE from the default socket
-// should close the connection.
-TEST_P(QuicConnectionTest, SendPathChallengeFailOnDefaultPath) {
- if (!VersionHasIetfQuicFrames(connection_.version().transport_version) ||
- !connection_.use_path_validator()) {
- return;
- }
- PathProbeTestInit(Perspective::IS_CLIENT);
-
- writer_->SetShouldWriteFail();
- EXPECT_CALL(visitor_, OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF))
- .WillOnce(
- Invoke([](QuicConnectionCloseFrame frame, ConnectionCloseSource) {
- EXPECT_EQ(QUIC_PACKET_WRITE_ERROR, frame.quic_error_code);
- }));
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0u);
- {
- // Add a flusher to force flush, otherwise the frames will remain in the
- // packet creator.
- bool success = false;
- QuicConnection::ScopedPacketFlusher flusher(&connection_);
- connection_.ValidatePath(std::make_unique<TestQuicPathValidationContext>(
- connection_.self_address(),
- connection_.peer_address(), writer_.get()),
- std::make_unique<TestValidationResultDelegate>(
- &connection_, connection_.self_address(),
- connection_.peer_address(), &success));
- }
- EXPECT_EQ(1u, writer_->packets_write_attempts());
- EXPECT_EQ(1u, writer_->path_challenge_frames().size());
- EXPECT_EQ(1u, writer_->padding_frames().size());
- EXPECT_EQ(connection_.peer_address(), writer_->last_write_peer_address());
- EXPECT_FALSE(connection_.connected());
- // Closing connection should abandon ongoing path validation.
- EXPECT_FALSE(connection_.HasPendingPathValidation());
-}
-
-TEST_P(QuicConnectionTest, SendPathChallengeFailOnAlternativePeerAddress) {
- if (!VersionHasIetfQuicFrames(connection_.version().transport_version) ||
- !connection_.use_path_validator()) {
- return;
- }
- PathProbeTestInit(Perspective::IS_CLIENT);
-
- writer_->SetShouldWriteFail();
- const QuicSocketAddress kNewPeerAddress(QuicIpAddress::Any4(), 12345);
- EXPECT_CALL(visitor_, OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF))
- .WillOnce(
- Invoke([](QuicConnectionCloseFrame frame, ConnectionCloseSource) {
- EXPECT_EQ(QUIC_PACKET_WRITE_ERROR, frame.quic_error_code);
- }));
- // Sending PATH_CHALLENGE to trigger a flush write which will fail and close
- // the connection.
- bool success = false;
- connection_.ValidatePath(
- std::make_unique<TestQuicPathValidationContext>(
- connection_.self_address(), kNewPeerAddress, writer_.get()),
- std::make_unique<TestValidationResultDelegate>(
- &connection_, connection_.self_address(), kNewPeerAddress, &success));
-
- EXPECT_EQ(1u, writer_->packets_write_attempts());
- EXPECT_FALSE(connection_.HasPendingPathValidation());
- EXPECT_EQ(1u, writer_->path_challenge_frames().size());
- EXPECT_EQ(1u, writer_->padding_frames().size());
- EXPECT_EQ(kNewPeerAddress, writer_->last_write_peer_address());
- EXPECT_FALSE(connection_.connected());
-}
-
-TEST_P(QuicConnectionTest,
- SendPathChallengeFailPacketTooBigOnAlternativePeerAddress) {
- if (!VersionHasIetfQuicFrames(connection_.version().transport_version) ||
- !connection_.use_path_validator()) {
- return;
- }
- PathProbeTestInit(Perspective::IS_CLIENT);
- // Make sure there is no outstanding ACK_FRAME to write.
- connection_.OnCanWrite();
- uint32_t num_packets_write_attempts = writer_->packets_write_attempts();
-
- writer_->SetShouldWriteFail();
- writer_->SetWriteError(QUIC_EMSGSIZE);
- const QuicSocketAddress kNewPeerAddress(QuicIpAddress::Any4(), 12345);
- EXPECT_CALL(visitor_, OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF))
- .Times(0u);
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0u);
- // Sending PATH_CHALLENGE to trigger a flush write which will fail with
- // MSG_TOO_BIG.
- bool success = false;
- connection_.ValidatePath(
- std::make_unique<TestQuicPathValidationContext>(
- connection_.self_address(), kNewPeerAddress, writer_.get()),
- std::make_unique<TestValidationResultDelegate>(
- &connection_, connection_.self_address(), kNewPeerAddress, &success));
- EXPECT_TRUE(connection_.HasPendingPathValidation());
- // Connection shouldn't be closed.
- EXPECT_TRUE(connection_.connected());
- EXPECT_EQ(++num_packets_write_attempts, writer_->packets_write_attempts());
- EXPECT_EQ(1u, writer_->path_challenge_frames().size());
- EXPECT_EQ(1u, writer_->padding_frames().size());
- EXPECT_EQ(kNewPeerAddress, writer_->last_write_peer_address());
-}
-
-// Check that if there are two PATH_CHALLENGE frames in the packet, the latter
-// one is ignored.
-TEST_P(QuicConnectionTest, ReceiveMultiplePathChallenge) {
- if (!VersionHasIetfQuicFrames(connection_.version().transport_version)) {
- return;
- }
- PathProbeTestInit(Perspective::IS_SERVER);
-
- QuicPathFrameBuffer path_frame_buffer1{0, 1, 2, 3, 4, 5, 6, 7};
- QuicPathFrameBuffer path_frame_buffer2{8, 9, 10, 11, 12, 13, 14, 15};
- QuicFrames frames;
- frames.push_back(
- QuicFrame(new QuicPathChallengeFrame(0, path_frame_buffer1)));
- frames.push_back(
- QuicFrame(new QuicPathChallengeFrame(0, path_frame_buffer2)));
- const QuicSocketAddress kNewPeerAddress(QuicIpAddress::Loopback6(),
- /*port=*/23456);
-
- EXPECT_CALL(visitor_, OnConnectionMigration(PORT_CHANGE)).Times(0);
-
- // Expect 2 packets to be sent: the first are padded PATH_RESPONSE(s) to the
- // alternative peer address. The 2nd is a ACK-only packet to the original
- // peer address.
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
- .Times(2)
- .WillOnce(Invoke([=]() {
- EXPECT_EQ((connection_.send_path_response() ? 1u : 2u),
- writer_->path_response_frames().size());
- // The final check is to ensure that the random data in the response
- // matches the random data from the challenge.
- EXPECT_EQ(0,
- memcmp(path_frame_buffer1.data(),
- &(writer_->path_response_frames().front().data_buffer),
- sizeof(path_frame_buffer1)));
- if (!connection_.send_path_response()) {
- EXPECT_EQ(
- 0, memcmp(path_frame_buffer2.data(),
- &(writer_->path_response_frames().back().data_buffer),
- sizeof(path_frame_buffer2)));
- } else {
- EXPECT_EQ(1u, writer_->padding_frames().size());
- }
- EXPECT_EQ(kNewPeerAddress, writer_->last_write_peer_address());
- }))
- .WillOnce(Invoke([=]() {
- // The last write of ACK-only packet should still use the old peer
- // address.
- EXPECT_EQ(kPeerAddress, writer_->last_write_peer_address());
- }));
- ProcessFramesPacketWithAddresses(frames, kSelfAddress, kNewPeerAddress,
- ENCRYPTION_FORWARD_SECURE);
-}
-
-TEST_P(QuicConnectionTest, ReceiveStreamFrameBeforePathChallenge) {
- if (!VersionHasIetfQuicFrames(connection_.version().transport_version) ||
- !connection_.send_path_response()) {
- return;
- }
- PathProbeTestInit(Perspective::IS_SERVER);
-
- QuicFrames frames;
- frames.push_back(QuicFrame(frame1_));
- QuicPathFrameBuffer path_frame_buffer{0, 1, 2, 3, 4, 5, 6, 7};
- frames.push_back(QuicFrame(new QuicPathChallengeFrame(0, path_frame_buffer)));
- const QuicSocketAddress kNewPeerAddress(QuicIpAddress::Loopback4(),
- /*port=*/23456);
-
- EXPECT_CALL(visitor_, OnConnectionMigration(IPV6_TO_IPV4_CHANGE));
- EXPECT_CALL(*send_algorithm_, OnConnectionMigration())
- .Times(connection_.validate_client_address() ? 0u : 1u);
- EXPECT_CALL(visitor_, OnStreamFrame(_))
- .WillOnce(Invoke([=](const QuicStreamFrame& frame) {
- // Send some data on the stream. The STREAM_FRAME should be built into
- // one packet together with the latter PATH_RESPONSE and PATH_CHALLENGE.
- std::string data{"response body"};
- struct iovec iov;
- MakeIOVector(data, &iov);
- connection_.producer()->SaveStreamData(frame.stream_id, &iov, 1, 0u,
- data.length());
- return notifier_.WriteOrBufferData(frame.stream_id, data.length(),
- NO_FIN);
- }));
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
- .Times(connection_.validate_client_address() ? 0u : 1u);
- ProcessFramesPacketWithAddresses(frames, kSelfAddress, kNewPeerAddress,
- ENCRYPTION_FORWARD_SECURE);
-
- // Verify that this packet contains a STREAM_FRAME and a
- // PATH_RESPONSE_FRAME.
- EXPECT_EQ(1u, writer_->stream_frames().size());
- EXPECT_EQ(1u, writer_->path_response_frames().size());
- EXPECT_EQ(connection_.validate_client_address() ? 1u : 0u,
- writer_->path_challenge_frames().size());
- // The final check is to ensure that the random data in the response
- // matches the random data from the challenge.
- EXPECT_EQ(0, memcmp(path_frame_buffer.data(),
- &(writer_->path_response_frames().front().data_buffer),
- sizeof(path_frame_buffer)));
- EXPECT_EQ(connection_.validate_client_address() ? 1u : 0u,
- writer_->path_challenge_frames().size());
- EXPECT_EQ(1u, writer_->padding_frames().size());
- EXPECT_EQ(kNewPeerAddress, writer_->last_write_peer_address());
- if (connection_.validate_client_address()) {
- EXPECT_TRUE(connection_.HasPendingPathValidation());
- }
-}
-
-TEST_P(QuicConnectionTest, ReceiveStreamFrameFollowingPathChallenge) {
- if (!VersionHasIetfQuicFrames(connection_.version().transport_version) ||
- !connection_.send_path_response()) {
- return;
- }
- PathProbeTestInit(Perspective::IS_SERVER);
-
- QuicFrames frames;
- QuicPathFrameBuffer path_frame_buffer{0, 1, 2, 3, 4, 5, 6, 7};
- frames.push_back(QuicFrame(new QuicPathChallengeFrame(0, path_frame_buffer)));
- // PATH_RESPONSE should be flushed out before the rest packet is parsed.
- frames.push_back(QuicFrame(frame1_));
- const QuicSocketAddress kNewPeerAddress(QuicIpAddress::Loopback4(),
- /*port=*/23456);
- QuicByteCount received_packet_size;
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
- .Times(AtLeast(1u))
- .WillOnce(Invoke([=, &received_packet_size]() {
- // Verify that this packet contains a PATH_RESPONSE_FRAME.
- EXPECT_EQ(0u, writer_->stream_frames().size());
- EXPECT_EQ(1u, writer_->path_response_frames().size());
- // The final check is to ensure that the random data in the response
- // matches the random data from the challenge.
- EXPECT_EQ(0,
- memcmp(path_frame_buffer.data(),
- &(writer_->path_response_frames().front().data_buffer),
- sizeof(path_frame_buffer)));
- EXPECT_EQ(connection_.validate_client_address() ? 1u : 0u,
- writer_->path_challenge_frames().size());
- EXPECT_EQ(1u, writer_->padding_frames().size());
- EXPECT_EQ(kNewPeerAddress, writer_->last_write_peer_address());
- received_packet_size =
- QuicConnectionPeer::BytesReceivedOnAlternativePath(&connection_);
- }));
- EXPECT_CALL(visitor_, OnConnectionMigration(IPV6_TO_IPV4_CHANGE));
- EXPECT_CALL(*send_algorithm_, OnConnectionMigration())
- .Times(connection_.validate_client_address() ? 0u : 1u);
- EXPECT_CALL(visitor_, OnStreamFrame(_))
- .WillOnce(Invoke([=](const QuicStreamFrame& frame) {
- // Send some data on the stream. The STREAM_FRAME should be built into a
- // new packet but throttled by anti-amplifciation limit.
- std::string data{"response body"};
- struct iovec iov;
- MakeIOVector(data, &iov);
- connection_.producer()->SaveStreamData(frame.stream_id, &iov, 1, 0u,
- data.length());
- return notifier_.WriteOrBufferData(frame.stream_id, data.length(),
- NO_FIN);
- }));
-
- ProcessFramesPacketWithAddresses(frames, kSelfAddress, kNewPeerAddress,
- ENCRYPTION_FORWARD_SECURE);
- if (!connection_.validate_client_address()) {
- return;
- }
- EXPECT_TRUE(connection_.HasPendingPathValidation());
- EXPECT_EQ(0u,
- QuicConnectionPeer::BytesReceivedOnAlternativePath(&connection_));
- EXPECT_EQ(
- received_packet_size,
- QuicConnectionPeer::BytesReceivedBeforeAddressValidation(&connection_));
-}
-
-// Tests that a PATH_CHALLENGE is received in between other frames in an out of
-// order packet.
-TEST_P(QuicConnectionTest, PathChallengeWithDataInOutOfOrderPacket) {
- if (!VersionHasIetfQuicFrames(connection_.version().transport_version) ||
- !connection_.send_path_response()) {
- return;
- }
- PathProbeTestInit(Perspective::IS_SERVER);
-
- QuicFrames frames;
- frames.push_back(QuicFrame(frame1_));
- QuicPathFrameBuffer path_frame_buffer{0, 1, 2, 3, 4, 5, 6, 7};
- frames.push_back(QuicFrame(new QuicPathChallengeFrame(0, path_frame_buffer)));
- frames.push_back(QuicFrame(frame2_));
- const QuicSocketAddress kNewPeerAddress(QuicIpAddress::Loopback6(),
- /*port=*/23456);
-
- EXPECT_CALL(visitor_, OnConnectionMigration(PORT_CHANGE)).Times(0u);
- EXPECT_CALL(visitor_, OnStreamFrame(_))
- .Times(2)
- .WillRepeatedly(Invoke([=](const QuicStreamFrame& frame) {
- // Send some data on the stream. The STREAM_FRAME should be built into
- // one packet together with the latter PATH_RESPONSE.
- std::string data{"response body"};
- struct iovec iov;
- MakeIOVector(data, &iov);
- connection_.producer()->SaveStreamData(frame.stream_id, &iov, 1, 0u,
- data.length());
- return notifier_.WriteOrBufferData(frame.stream_id, data.length(),
- NO_FIN);
- }));
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
- .WillOnce(Invoke([=]() {
- // Verify that this packet contains a STREAM_FRAME and is sent to the
- // original peer address.
- EXPECT_EQ(1u, writer_->stream_frames().size());
- // No connection migration should happen because the packet is received
- // out of order.
- EXPECT_EQ(kPeerAddress, writer_->last_write_peer_address());
- }))
- .WillOnce(Invoke([=]() {
- EXPECT_EQ(1u, writer_->path_response_frames().size());
- // The final check is to ensure that the random data in the response
- // matches the random data from the challenge.
- EXPECT_EQ(0,
- memcmp(path_frame_buffer.data(),
- &(writer_->path_response_frames().front().data_buffer),
- sizeof(path_frame_buffer)));
- EXPECT_EQ(1u, writer_->padding_frames().size());
- // PATH_RESPONSE should be sent in another packet to a different peer
- // address.
- EXPECT_EQ(kNewPeerAddress, writer_->last_write_peer_address());
- }))
- .WillOnce(Invoke([=]() {
- // Verify that this packet contains a STREAM_FRAME and is sent to the
- // original peer address.
- EXPECT_EQ(1u, writer_->stream_frames().size());
- // No connection migration should happen because the packet is received
- // out of order.
- EXPECT_EQ(kPeerAddress, writer_->last_write_peer_address());
- }));
- // Lower the packet number so that receiving this packet shouldn't trigger
- // peer migration.
- QuicPacketCreatorPeer::SetPacketNumber(&peer_creator_, 1);
- ProcessFramesPacketWithAddresses(frames, kSelfAddress, kNewPeerAddress,
- ENCRYPTION_FORWARD_SECURE);
-}
-
-// Tests that a PATH_CHALLENGE is cached if its PATH_RESPONSE can't be sent.
-TEST_P(QuicConnectionTest, FailToWritePathResponse) {
- if (!VersionHasIetfQuicFrames(connection_.version().transport_version) ||
- !connection_.send_path_response()) {
- return;
- }
- PathProbeTestInit(Perspective::IS_SERVER);
-
- QuicFrames frames;
- QuicPathFrameBuffer path_frame_buffer{0, 1, 2, 3, 4, 5, 6, 7};
- frames.push_back(QuicFrame(new QuicPathChallengeFrame(0, path_frame_buffer)));
- const QuicSocketAddress kNewPeerAddress(QuicIpAddress::Loopback6(),
- /*port=*/23456);
-
- EXPECT_CALL(visitor_, OnConnectionMigration(PORT_CHANGE)).Times(0u);
- // Lower the packet number so that receiving this packet shouldn't trigger
- // peer migration.
- QuicPacketCreatorPeer::SetPacketNumber(&peer_creator_, 1);
- EXPECT_CALL(visitor_, OnWriteBlocked()).Times(AtLeast(1));
- writer_->SetWriteBlocked();
- ProcessFramesPacketWithAddresses(frames, kSelfAddress, kNewPeerAddress,
- ENCRYPTION_FORWARD_SECURE);
-}
-
-// Regression test for b/168101557.
-TEST_P(QuicConnectionTest, HandshakeDataDoesNotGetPtoed) {
- if (!connection_.SupportsMultiplePacketNumberSpaces()) {
- return;
- }
- set_perspective(Perspective::IS_SERVER);
- if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
- EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
- }
- EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber());
- use_tagging_decrypter();
- ProcessCryptoPacketAtLevel(1, ENCRYPTION_INITIAL);
- EXPECT_TRUE(connection_.HasPendingAcks());
-
- connection_.SetEncrypter(ENCRYPTION_INITIAL,
- std::make_unique<TaggingEncrypter>(0x01));
- connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
- // Send INITIAL 1.
- connection_.SendCryptoDataWithString("foo", 0, ENCRYPTION_INITIAL);
-
- connection_.SetEncrypter(ENCRYPTION_HANDSHAKE,
- std::make_unique<TaggingEncrypter>(0x02));
- connection_.SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE);
- SetDecrypter(ENCRYPTION_HANDSHAKE,
- std::make_unique<StrictTaggingDecrypter>(0x02));
- // Send HANDSHAKE packets.
- EXPECT_CALL(visitor_, OnHandshakePacketSent()).Times(1);
- connection_.SendCryptoDataWithString("foo", 0, ENCRYPTION_HANDSHAKE);
-
- connection_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
- std::make_unique<TaggingEncrypter>(0x03));
- connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
- // Send half RTT packet.
- connection_.SendStreamDataWithString(2, "foo", 0, NO_FIN);
-
- // Receives HANDSHAKE 1.
- peer_framer_.SetEncrypter(ENCRYPTION_HANDSHAKE,
- std::make_unique<TaggingEncrypter>(0x02));
- ProcessCryptoPacketAtLevel(1, ENCRYPTION_HANDSHAKE);
- // Discard INITIAL key.
- connection_.RemoveEncrypter(ENCRYPTION_INITIAL);
- connection_.NeuterUnencryptedPackets();
- // Verify there is pending ACK.
- ASSERT_TRUE(connection_.HasPendingAcks());
- // Set the send alarm.
- connection_.GetSendAlarm()->Set(clock_.ApproximateNow());
-
- // Fire ACK alarm.
- connection_.GetAckAlarm()->Fire();
- // Verify 1-RTT packet is coalesced with handshake packet.
- EXPECT_EQ(0x03030303u, writer_->final_bytes_of_last_packet());
- connection_.GetSendAlarm()->Fire();
-
- ASSERT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
- connection_.GetRetransmissionAlarm()->Fire();
- // Verify a handshake packet gets PTOed and 1-RTT packet gets coalesced.
- EXPECT_EQ(0x03030303u, writer_->final_bytes_of_last_packet());
-}
-
-// Regression test for b/168294218.
-TEST_P(QuicConnectionTest, CoalescerHandlesInitialKeyDiscard) {
- if (!connection_.version().CanSendCoalescedPackets()) {
- return;
- }
- SetQuicReloadableFlag(quic_discard_initial_packet_with_key_dropped, true);
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(2);
- EXPECT_CALL(visitor_, OnHandshakePacketSent()).WillOnce(Invoke([this]() {
- connection_.RemoveEncrypter(ENCRYPTION_INITIAL);
- connection_.NeuterUnencryptedPackets();
- }));
- EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
-
- EXPECT_EQ(0u, connection_.GetStats().packets_discarded);
- {
- QuicConnection::ScopedPacketFlusher flusher(&connection_);
- use_tagging_decrypter();
- ProcessCryptoPacketAtLevel(1000, ENCRYPTION_INITIAL);
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(1));
- connection_.SetEncrypter(ENCRYPTION_INITIAL,
- std::make_unique<TaggingEncrypter>(0x01));
- connection_.SetEncrypter(ENCRYPTION_HANDSHAKE,
- std::make_unique<TaggingEncrypter>(0x02));
- connection_.SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE);
- connection_.SendCryptoDataWithString(std::string(1200, 'a'), 0);
- // Verify this packet is on hold.
- EXPECT_EQ(0u, writer_->packets_write_attempts());
- }
- EXPECT_TRUE(connection_.connected());
-}
-
-// Regresstion test for b/168294218
-TEST_P(QuicConnectionTest, ZeroRttRejectionAndMissingInitialKeys) {
- if (!connection_.SupportsMultiplePacketNumberSpaces()) {
- return;
- }
- // Not defer send in response to packet.
- connection_.set_defer_send_in_response_to_packets(false);
- EXPECT_CALL(visitor_, OnHandshakePacketSent()).WillOnce(Invoke([this]() {
- connection_.RemoveEncrypter(ENCRYPTION_INITIAL);
- connection_.NeuterUnencryptedPackets();
- }));
- EXPECT_CALL(visitor_, OnCryptoFrame(_))
- .WillRepeatedly(Invoke([=](const QuicCryptoFrame& frame) {
- if (frame.level == ENCRYPTION_HANDSHAKE) {
- // 0-RTT gets rejected.
- connection_.MarkZeroRttPacketsForRetransmission(0);
- // Send Crypto data.
- connection_.SetEncrypter(ENCRYPTION_HANDSHAKE,
- std::make_unique<TaggingEncrypter>(0x03));
- connection_.SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE);
- connection_.SendCryptoDataWithString("foo", 0, ENCRYPTION_HANDSHAKE);
- connection_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
- std::make_unique<TaggingEncrypter>(0x04));
- connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
- // Advance INITIAL ack delay to trigger initial ACK to be sent AFTER
- // the retransmission of rejected 0-RTT packets while the HANDSHAKE
- // packet is still in the coalescer, such that the INITIAL key gets
- // dropped between SendAllPendingAcks and actually send the ack frame,
- // bummer.
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(1));
- }
- }));
- use_tagging_decrypter();
- connection_.SetEncrypter(ENCRYPTION_INITIAL,
- std::make_unique<TaggingEncrypter>(0x01));
- connection_.SendCryptoDataWithString("foo", 0, ENCRYPTION_INITIAL);
- // Send 0-RTT packet.
- connection_.SetEncrypter(ENCRYPTION_ZERO_RTT,
- std::make_unique<TaggingEncrypter>(0x02));
- connection_.SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
- connection_.SendStreamDataWithString(2, "foo", 0, NO_FIN);
-
- QuicAckFrame frame1 = InitAckFrame(1);
- // Received ACK for packet 1.
- EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _));
- ProcessFramePacketAtLevel(1, QuicFrame(&frame1), ENCRYPTION_INITIAL);
- EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
-
- // Fire retransmission alarm.
- connection_.GetRetransmissionAlarm()->Fire();
-
- QuicFrames frames1;
- frames1.push_back(QuicFrame(&crypto_frame_));
- QuicFrames frames2;
- QuicCryptoFrame crypto_frame(ENCRYPTION_HANDSHAKE, 0,
- absl::string_view(data1));
- frames2.push_back(QuicFrame(&crypto_frame));
- ProcessCoalescedPacket(
- {{2, frames1, ENCRYPTION_INITIAL}, {3, frames2, ENCRYPTION_HANDSHAKE}});
-}
-
-TEST_P(QuicConnectionTest, OnZeroRttPacketAcked) {
- if (!connection_.version().UsesTls()) {
- return;
- }
- MockQuicConnectionDebugVisitor debug_visitor;
- connection_.set_debug_visitor(&debug_visitor);
- use_tagging_decrypter();
- connection_.SetEncrypter(ENCRYPTION_INITIAL,
- std::make_unique<TaggingEncrypter>(0x01));
- connection_.SendCryptoStreamData();
- // Send 0-RTT packet.
- connection_.SetEncrypter(ENCRYPTION_ZERO_RTT,
- std::make_unique<TaggingEncrypter>(0x02));
- connection_.SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
- connection_.SendStreamDataWithString(2, "foo", 0, NO_FIN);
- connection_.SendStreamDataWithString(4, "bar", 0, NO_FIN);
- // Received ACK for packet 1, HANDSHAKE packet and 1-RTT ACK.
- EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _))
- .Times(AnyNumber());
- QuicFrames frames1;
- QuicAckFrame ack_frame1 = InitAckFrame(1);
- frames1.push_back(QuicFrame(&ack_frame1));
-
- QuicFrames frames2;
- QuicCryptoFrame crypto_frame(ENCRYPTION_HANDSHAKE, 0,
- absl::string_view(data1));
- frames2.push_back(QuicFrame(&crypto_frame));
- EXPECT_CALL(debug_visitor, OnZeroRttPacketAcked()).Times(0);
- EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(1);
- ProcessCoalescedPacket(
- {{1, frames1, ENCRYPTION_INITIAL}, {2, frames2, ENCRYPTION_HANDSHAKE}});
-
- QuicFrames frames3;
- QuicAckFrame ack_frame2 =
- InitAckFrame({{QuicPacketNumber(2), QuicPacketNumber(3)}});
- frames3.push_back(QuicFrame(&ack_frame2));
- EXPECT_CALL(debug_visitor, OnZeroRttPacketAcked()).Times(1);
- ProcessCoalescedPacket({{3, frames3, ENCRYPTION_FORWARD_SECURE}});
-
- QuicFrames frames4;
- QuicAckFrame ack_frame3 =
- InitAckFrame({{QuicPacketNumber(3), QuicPacketNumber(4)}});
- frames4.push_back(QuicFrame(&ack_frame3));
- EXPECT_CALL(debug_visitor, OnZeroRttPacketAcked()).Times(0);
- ProcessCoalescedPacket({{4, frames4, ENCRYPTION_FORWARD_SECURE}});
-}
-
-TEST_P(QuicConnectionTest, InitiateKeyUpdate) {
- if (!connection_.version().UsesTls()) {
- return;
- }
-
- TransportParameters params;
- QuicConfig config;
- std::string error_details;
- EXPECT_THAT(config.ProcessTransportParameters(
- params, /* is_resumption = */ false, &error_details),
- IsQuicNoError());
- QuicConfigPeer::SetNegotiated(&config, true);
- if (connection_.version().UsesTls()) {
- QuicConfigPeer::SetReceivedOriginalConnectionId(
- &config, connection_.connection_id());
- QuicConfigPeer::SetReceivedInitialSourceConnectionId(
- &config, connection_.connection_id());
- }
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
- connection_.SetFromConfig(config);
-
- EXPECT_FALSE(connection_.IsKeyUpdateAllowed());
-
- MockFramerVisitor peer_framer_visitor_;
- peer_framer_.set_visitor(&peer_framer_visitor_);
-
- use_tagging_decrypter();
-
- connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
- connection_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
- std::make_unique<TaggingEncrypter>(0x01));
- SetDecrypter(ENCRYPTION_FORWARD_SECURE,
- std::make_unique<StrictTaggingDecrypter>(0x01));
- EXPECT_CALL(visitor_, GetHandshakeState())
- .WillRepeatedly(Return(HANDSHAKE_CONFIRMED));
- connection_.OnHandshakeComplete();
-
- peer_framer_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
- std::make_unique<TaggingEncrypter>(0x01));
-
- // Key update should still not be allowed, since no packet has been acked
- // from the current key phase.
- EXPECT_FALSE(connection_.IsKeyUpdateAllowed());
- EXPECT_FALSE(connection_.HaveSentPacketsInCurrentKeyPhaseButNoneAcked());
-
- // Send packet 1.
- QuicPacketNumber last_packet;
- SendStreamDataToPeer(1, "foo", 0, NO_FIN, &last_packet);
- EXPECT_EQ(QuicPacketNumber(1u), last_packet);
-
- // Key update should still not be allowed, even though a packet was sent in
- // the current key phase it hasn't been acked yet.
- EXPECT_FALSE(connection_.IsKeyUpdateAllowed());
- EXPECT_TRUE(connection_.HaveSentPacketsInCurrentKeyPhaseButNoneAcked());
-
- EXPECT_FALSE(connection_.GetDiscardPreviousOneRttKeysAlarm()->IsSet());
- // Receive ack for packet 1.
- EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
- QuicAckFrame frame1 = InitAckFrame(1);
- ProcessAckPacket(&frame1);
-
- // OnDecryptedFirstPacketInKeyPhase is called even on the first key phase,
- // so discard_previous_keys_alarm_ should be set now.
- EXPECT_TRUE(connection_.GetDiscardPreviousOneRttKeysAlarm()->IsSet());
- EXPECT_FALSE(connection_.HaveSentPacketsInCurrentKeyPhaseButNoneAcked());
-
- // Key update should now be allowed.
- EXPECT_CALL(visitor_, AdvanceKeysAndCreateCurrentOneRttDecrypter())
- .WillOnce(
- []() { return std::make_unique<StrictTaggingDecrypter>(0x02); });
- EXPECT_CALL(visitor_, CreateCurrentOneRttEncrypter()).WillOnce([]() {
- return std::make_unique<TaggingEncrypter>(0x02);
- });
- EXPECT_CALL(visitor_, OnKeyUpdate(KeyUpdateReason::kLocalForTests));
- EXPECT_TRUE(connection_.InitiateKeyUpdate(KeyUpdateReason::kLocalForTests));
- // discard_previous_keys_alarm_ should not be set until a packet from the new
- // key phase has been received. (The alarm that was set above should be
- // cleared if it hasn't fired before the next key update happened.)
- EXPECT_FALSE(connection_.GetDiscardPreviousOneRttKeysAlarm()->IsSet());
- EXPECT_FALSE(connection_.HaveSentPacketsInCurrentKeyPhaseButNoneAcked());
-
- // Pretend that peer accepts the key update.
- EXPECT_CALL(peer_framer_visitor_,
- AdvanceKeysAndCreateCurrentOneRttDecrypter())
- .WillOnce(
- []() { return std::make_unique<StrictTaggingDecrypter>(0x02); });
- EXPECT_CALL(peer_framer_visitor_, CreateCurrentOneRttEncrypter())
- .WillOnce([]() { return std::make_unique<TaggingEncrypter>(0x02); });
- peer_framer_.SetKeyUpdateSupportForConnection(true);
- peer_framer_.DoKeyUpdate(KeyUpdateReason::kRemote);
-
- // Another key update should not be allowed yet.
- EXPECT_FALSE(connection_.IsKeyUpdateAllowed());
-
- // Send packet 2.
- SendStreamDataToPeer(2, "bar", 0, NO_FIN, &last_packet);
- EXPECT_EQ(QuicPacketNumber(2u), last_packet);
- EXPECT_TRUE(connection_.HaveSentPacketsInCurrentKeyPhaseButNoneAcked());
- // Receive ack for packet 2.
- EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
- QuicAckFrame frame2 = InitAckFrame(2);
- ProcessAckPacket(&frame2);
- EXPECT_TRUE(connection_.GetDiscardPreviousOneRttKeysAlarm()->IsSet());
- EXPECT_FALSE(connection_.HaveSentPacketsInCurrentKeyPhaseButNoneAcked());
-
- // Key update should be allowed again now that a packet has been acked from
- // the current key phase.
- EXPECT_CALL(visitor_, AdvanceKeysAndCreateCurrentOneRttDecrypter())
- .WillOnce(
- []() { return std::make_unique<StrictTaggingDecrypter>(0x03); });
- EXPECT_CALL(visitor_, CreateCurrentOneRttEncrypter()).WillOnce([]() {
- return std::make_unique<TaggingEncrypter>(0x03);
- });
- EXPECT_CALL(visitor_, OnKeyUpdate(KeyUpdateReason::kLocalForTests));
- EXPECT_TRUE(connection_.InitiateKeyUpdate(KeyUpdateReason::kLocalForTests));
-
- // Pretend that peer accepts the key update.
- EXPECT_CALL(peer_framer_visitor_,
- AdvanceKeysAndCreateCurrentOneRttDecrypter())
- .WillOnce(
- []() { return std::make_unique<StrictTaggingDecrypter>(0x03); });
- EXPECT_CALL(peer_framer_visitor_, CreateCurrentOneRttEncrypter())
- .WillOnce([]() { return std::make_unique<TaggingEncrypter>(0x03); });
- peer_framer_.DoKeyUpdate(KeyUpdateReason::kRemote);
-
- // Another key update should not be allowed yet.
- EXPECT_FALSE(connection_.IsKeyUpdateAllowed());
-
- // Send packet 3.
- SendStreamDataToPeer(3, "baz", 0, NO_FIN, &last_packet);
- EXPECT_EQ(QuicPacketNumber(3u), last_packet);
-
- // Another key update should not be allowed yet.
- EXPECT_FALSE(connection_.IsKeyUpdateAllowed());
- EXPECT_TRUE(connection_.HaveSentPacketsInCurrentKeyPhaseButNoneAcked());
-
- // Receive ack for packet 3.
- EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
- QuicAckFrame frame3 = InitAckFrame(3);
- ProcessAckPacket(&frame3);
- EXPECT_TRUE(connection_.GetDiscardPreviousOneRttKeysAlarm()->IsSet());
- EXPECT_FALSE(connection_.HaveSentPacketsInCurrentKeyPhaseButNoneAcked());
-
- // Key update should be allowed now.
- EXPECT_CALL(visitor_, AdvanceKeysAndCreateCurrentOneRttDecrypter())
- .WillOnce(
- []() { return std::make_unique<StrictTaggingDecrypter>(0x04); });
- EXPECT_CALL(visitor_, CreateCurrentOneRttEncrypter()).WillOnce([]() {
- return std::make_unique<TaggingEncrypter>(0x04);
- });
- EXPECT_CALL(visitor_, OnKeyUpdate(KeyUpdateReason::kLocalForTests));
- EXPECT_TRUE(connection_.InitiateKeyUpdate(KeyUpdateReason::kLocalForTests));
- EXPECT_FALSE(connection_.GetDiscardPreviousOneRttKeysAlarm()->IsSet());
- EXPECT_FALSE(connection_.HaveSentPacketsInCurrentKeyPhaseButNoneAcked());
-}
-
-TEST_P(QuicConnectionTest, InitiateKeyUpdateApproachingConfidentialityLimit) {
- if (!connection_.version().UsesTls()) {
- return;
- }
-
- SetQuicFlag(FLAGS_quic_key_update_confidentiality_limit, 3U);
-
- std::string error_details;
- TransportParameters params;
- // Key update is enabled.
- QuicConfig config;
- EXPECT_THAT(config.ProcessTransportParameters(
- params, /* is_resumption = */ false, &error_details),
- IsQuicNoError());
- QuicConfigPeer::SetNegotiated(&config, true);
- if (connection_.version().UsesTls()) {
- QuicConfigPeer::SetReceivedOriginalConnectionId(
- &config, connection_.connection_id());
- QuicConfigPeer::SetReceivedInitialSourceConnectionId(
- &config, connection_.connection_id());
- }
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
- connection_.SetFromConfig(config);
-
- MockFramerVisitor peer_framer_visitor_;
- peer_framer_.set_visitor(&peer_framer_visitor_);
-
- use_tagging_decrypter();
-
- uint8_t current_tag = 0x01;
-
- connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
- connection_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
- std::make_unique<TaggingEncrypter>(current_tag));
- SetDecrypter(ENCRYPTION_FORWARD_SECURE,
- std::make_unique<StrictTaggingDecrypter>(current_tag));
- EXPECT_CALL(visitor_, GetHandshakeState())
- .WillRepeatedly(Return(HANDSHAKE_CONFIRMED));
- connection_.OnHandshakeComplete();
-
- peer_framer_.SetKeyUpdateSupportForConnection(true);
- peer_framer_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
- std::make_unique<TaggingEncrypter>(current_tag));
-
- const QuicConnectionStats& stats = connection_.GetStats();
-
- for (int packet_num = 1; packet_num <= 8; ++packet_num) {
- if (packet_num == 3 || packet_num == 6) {
- current_tag++;
- EXPECT_CALL(visitor_, AdvanceKeysAndCreateCurrentOneRttDecrypter())
- .WillOnce([current_tag]() {
- return std::make_unique<StrictTaggingDecrypter>(current_tag);
- });
- EXPECT_CALL(visitor_, CreateCurrentOneRttEncrypter())
- .WillOnce([current_tag]() {
- return std::make_unique<TaggingEncrypter>(current_tag);
- });
- EXPECT_CALL(visitor_,
- OnKeyUpdate(KeyUpdateReason::kLocalKeyUpdateLimitOverride));
- }
- // Send packet.
- QuicPacketNumber last_packet;
- SendStreamDataToPeer(packet_num, "foo", 0, NO_FIN, &last_packet);
- EXPECT_EQ(QuicPacketNumber(packet_num), last_packet);
- if (packet_num >= 6) {
- EXPECT_EQ(2U, stats.key_update_count);
- } else if (packet_num >= 3) {
- EXPECT_EQ(1U, stats.key_update_count);
- } else {
- EXPECT_EQ(0U, stats.key_update_count);
- }
-
- if (packet_num == 4 || packet_num == 7) {
- // Pretend that peer accepts the key update.
- EXPECT_CALL(peer_framer_visitor_,
- AdvanceKeysAndCreateCurrentOneRttDecrypter())
- .WillOnce([current_tag]() {
- return std::make_unique<StrictTaggingDecrypter>(current_tag);
- });
- EXPECT_CALL(peer_framer_visitor_, CreateCurrentOneRttEncrypter())
- .WillOnce([current_tag]() {
- return std::make_unique<TaggingEncrypter>(current_tag);
- });
- peer_framer_.DoKeyUpdate(KeyUpdateReason::kRemote);
- }
- // Receive ack for packet.
- EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
- QuicAckFrame frame1 = InitAckFrame(packet_num);
- ProcessAckPacket(&frame1);
- }
-}
-
-TEST_P(QuicConnectionTest,
- CloseConnectionOnConfidentialityLimitKeyUpdateNotAllowed) {
- if (!connection_.version().UsesTls()) {
- return;
- }
-
- // Set key update confidentiality limit to 1 packet.
- SetQuicFlag(FLAGS_quic_key_update_confidentiality_limit, 1U);
- // Use confidentiality limit for connection close of 3 packets.
- constexpr size_t kConfidentialityLimit = 3U;
-
- std::string error_details;
- TransportParameters params;
- // Key update is enabled.
- QuicConfig config;
- EXPECT_THAT(config.ProcessTransportParameters(
- params, /* is_resumption = */ false, &error_details),
- IsQuicNoError());
- QuicConfigPeer::SetNegotiated(&config, true);
- if (connection_.version().UsesTls()) {
- QuicConfigPeer::SetReceivedOriginalConnectionId(
- &config, connection_.connection_id());
- QuicConfigPeer::SetReceivedInitialSourceConnectionId(
- &config, connection_.connection_id());
- }
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
- connection_.SetFromConfig(config);
-
- connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
- connection_.SetEncrypter(
- ENCRYPTION_FORWARD_SECURE,
- std::make_unique<NullEncrypterWithConfidentialityLimit>(
- Perspective::IS_CLIENT, kConfidentialityLimit));
- EXPECT_CALL(visitor_, GetHandshakeState())
- .WillRepeatedly(Return(HANDSHAKE_CONFIRMED));
- connection_.OnHandshakeComplete();
-
- QuicPacketNumber last_packet;
- // Send 3 packets without receiving acks for any of them. Key update will not
- // be allowed, so the confidentiality limit should be reached, forcing the
- // connection to be closed.
- SendStreamDataToPeer(1, "foo", 0, NO_FIN, &last_packet);
- EXPECT_TRUE(connection_.connected());
- SendStreamDataToPeer(2, "foo", 0, NO_FIN, &last_packet);
- EXPECT_TRUE(connection_.connected());
- EXPECT_CALL(visitor_, OnConnectionClosed(_, _));
- SendStreamDataToPeer(3, "foo", 0, NO_FIN, &last_packet);
- EXPECT_FALSE(connection_.connected());
- const QuicConnectionStats& stats = connection_.GetStats();
- EXPECT_EQ(0U, stats.key_update_count);
- TestConnectionCloseQuicErrorCode(QUIC_AEAD_LIMIT_REACHED);
-}
-
-TEST_P(QuicConnectionTest, CloseConnectionOnIntegrityLimitDuringHandshake) {
- if (!connection_.version().UsesTls()) {
- return;
- }
-
- constexpr uint8_t correct_tag = 0x01;
- constexpr uint8_t wrong_tag = 0xFE;
- constexpr QuicPacketCount kIntegrityLimit = 3;
-
- SetDecrypter(ENCRYPTION_HANDSHAKE,
- std::make_unique<StrictTaggingDecrypterWithIntegrityLimit>(
- correct_tag, kIntegrityLimit));
- connection_.SetEncrypter(ENCRYPTION_HANDSHAKE,
- std::make_unique<TaggingEncrypter>(correct_tag));
- connection_.SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE);
- peer_framer_.SetEncrypter(ENCRYPTION_HANDSHAKE,
- std::make_unique<TaggingEncrypter>(wrong_tag));
- for (uint64_t i = 1; i <= kIntegrityLimit; ++i) {
- EXPECT_TRUE(connection_.connected());
- if (i == kIntegrityLimit) {
- EXPECT_CALL(visitor_, OnConnectionClosed(_, _));
- EXPECT_CALL(visitor_, OnHandshakePacketSent()).Times(AnyNumber());
- }
- ProcessDataPacketAtLevel(i, !kHasStopWaiting, ENCRYPTION_HANDSHAKE);
- EXPECT_EQ(
- i, connection_.GetStats().num_failed_authentication_packets_received);
- }
- EXPECT_FALSE(connection_.connected());
- TestConnectionCloseQuicErrorCode(QUIC_AEAD_LIMIT_REACHED);
-}
-
-TEST_P(QuicConnectionTest, CloseConnectionOnIntegrityLimitAfterHandshake) {
- if (!connection_.version().UsesTls()) {
- return;
- }
-
- constexpr uint8_t correct_tag = 0x01;
- constexpr uint8_t wrong_tag = 0xFE;
- constexpr QuicPacketCount kIntegrityLimit = 3;
-
- use_tagging_decrypter();
- SetDecrypter(ENCRYPTION_FORWARD_SECURE,
- std::make_unique<StrictTaggingDecrypterWithIntegrityLimit>(
- correct_tag, kIntegrityLimit));
- connection_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
- std::make_unique<TaggingEncrypter>(correct_tag));
- connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
- EXPECT_CALL(visitor_, GetHandshakeState())
- .WillRepeatedly(Return(HANDSHAKE_CONFIRMED));
- connection_.OnHandshakeComplete();
- connection_.RemoveEncrypter(ENCRYPTION_INITIAL);
- peer_framer_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
- std::make_unique<TaggingEncrypter>(wrong_tag));
- for (uint64_t i = 1; i <= kIntegrityLimit; ++i) {
- EXPECT_TRUE(connection_.connected());
- if (i == kIntegrityLimit) {
- EXPECT_CALL(visitor_, OnConnectionClosed(_, _));
- }
- ProcessDataPacketAtLevel(i, !kHasStopWaiting, ENCRYPTION_FORWARD_SECURE);
- EXPECT_EQ(
- i, connection_.GetStats().num_failed_authentication_packets_received);
- }
- EXPECT_FALSE(connection_.connected());
- TestConnectionCloseQuicErrorCode(QUIC_AEAD_LIMIT_REACHED);
-}
-
-TEST_P(QuicConnectionTest,
- CloseConnectionOnIntegrityLimitAcrossEncryptionLevels) {
- if (!connection_.version().UsesTls()) {
- return;
- }
-
- constexpr uint8_t correct_tag = 0x01;
- constexpr uint8_t wrong_tag = 0xFE;
- constexpr QuicPacketCount kIntegrityLimit = 4;
-
- use_tagging_decrypter();
- SetDecrypter(ENCRYPTION_HANDSHAKE,
- std::make_unique<StrictTaggingDecrypterWithIntegrityLimit>(
- correct_tag, kIntegrityLimit));
- connection_.SetEncrypter(ENCRYPTION_HANDSHAKE,
- std::make_unique<TaggingEncrypter>(correct_tag));
- connection_.SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE);
- peer_framer_.SetEncrypter(ENCRYPTION_HANDSHAKE,
- std::make_unique<TaggingEncrypter>(wrong_tag));
- for (uint64_t i = 1; i <= 2; ++i) {
- EXPECT_TRUE(connection_.connected());
- ProcessDataPacketAtLevel(i, !kHasStopWaiting, ENCRYPTION_HANDSHAKE);
- EXPECT_EQ(
- i, connection_.GetStats().num_failed_authentication_packets_received);
- }
-
- SetDecrypter(ENCRYPTION_FORWARD_SECURE,
- std::make_unique<StrictTaggingDecrypterWithIntegrityLimit>(
- correct_tag, kIntegrityLimit));
- connection_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
- std::make_unique<TaggingEncrypter>(correct_tag));
- connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
- EXPECT_CALL(visitor_, GetHandshakeState())
- .WillRepeatedly(Return(HANDSHAKE_CONFIRMED));
- connection_.OnHandshakeComplete();
- connection_.RemoveEncrypter(ENCRYPTION_INITIAL);
- connection_.RemoveEncrypter(ENCRYPTION_HANDSHAKE);
- peer_framer_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
- std::make_unique<TaggingEncrypter>(wrong_tag));
- for (uint64_t i = 3; i <= kIntegrityLimit; ++i) {
- EXPECT_TRUE(connection_.connected());
- if (i == kIntegrityLimit) {
- EXPECT_CALL(visitor_, OnConnectionClosed(_, _));
- }
- ProcessDataPacketAtLevel(i, !kHasStopWaiting, ENCRYPTION_FORWARD_SECURE);
- EXPECT_EQ(
- i, connection_.GetStats().num_failed_authentication_packets_received);
- }
- EXPECT_FALSE(connection_.connected());
- TestConnectionCloseQuicErrorCode(QUIC_AEAD_LIMIT_REACHED);
-}
-
-TEST_P(QuicConnectionTest, IntegrityLimitDoesNotApplyWithoutDecryptionKey) {
- if (!connection_.version().UsesTls()) {
- return;
- }
-
- constexpr uint8_t correct_tag = 0x01;
- constexpr uint8_t wrong_tag = 0xFE;
- constexpr QuicPacketCount kIntegrityLimit = 3;
-
- use_tagging_decrypter();
- SetDecrypter(ENCRYPTION_HANDSHAKE,
- std::make_unique<StrictTaggingDecrypterWithIntegrityLimit>(
- correct_tag, kIntegrityLimit));
- connection_.SetEncrypter(ENCRYPTION_HANDSHAKE,
- std::make_unique<TaggingEncrypter>(correct_tag));
- connection_.SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE);
- connection_.RemoveDecrypter(ENCRYPTION_FORWARD_SECURE);
-
- peer_framer_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
- std::make_unique<TaggingEncrypter>(wrong_tag));
- for (uint64_t i = 1; i <= kIntegrityLimit * 2; ++i) {
- EXPECT_TRUE(connection_.connected());
- ProcessDataPacketAtLevel(i, !kHasStopWaiting, ENCRYPTION_FORWARD_SECURE);
- EXPECT_EQ(
- 0u, connection_.GetStats().num_failed_authentication_packets_received);
- }
- EXPECT_TRUE(connection_.connected());
-}
-
-TEST_P(QuicConnectionTest, CloseConnectionOnIntegrityLimitAcrossKeyPhases) {
- if (!connection_.version().UsesTls()) {
- return;
- }
-
- constexpr QuicPacketCount kIntegrityLimit = 4;
-
- TransportParameters params;
- QuicConfig config;
- std::string error_details;
- EXPECT_THAT(config.ProcessTransportParameters(
- params, /* is_resumption = */ false, &error_details),
- IsQuicNoError());
- QuicConfigPeer::SetNegotiated(&config, true);
- if (connection_.version().UsesTls()) {
- QuicConfigPeer::SetReceivedOriginalConnectionId(
- &config, connection_.connection_id());
- QuicConfigPeer::SetReceivedInitialSourceConnectionId(
- &config, connection_.connection_id());
- }
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
- connection_.SetFromConfig(config);
-
- MockFramerVisitor peer_framer_visitor_;
- peer_framer_.set_visitor(&peer_framer_visitor_);
-
- use_tagging_decrypter();
- connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
- connection_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
- std::make_unique<TaggingEncrypter>(0x01));
- SetDecrypter(ENCRYPTION_FORWARD_SECURE,
- std::make_unique<StrictTaggingDecrypterWithIntegrityLimit>(
- 0x01, kIntegrityLimit));
- EXPECT_CALL(visitor_, GetHandshakeState())
- .WillRepeatedly(Return(HANDSHAKE_CONFIRMED));
- connection_.OnHandshakeComplete();
- connection_.RemoveEncrypter(ENCRYPTION_INITIAL);
-
- peer_framer_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
- std::make_unique<TaggingEncrypter>(0xFF));
- for (uint64_t i = 1; i <= 2; ++i) {
- EXPECT_TRUE(connection_.connected());
- ProcessDataPacketAtLevel(i, !kHasStopWaiting, ENCRYPTION_FORWARD_SECURE);
- EXPECT_EQ(
- i, connection_.GetStats().num_failed_authentication_packets_received);
- }
-
- peer_framer_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
- std::make_unique<TaggingEncrypter>(0x01));
- // Send packet 1.
- QuicPacketNumber last_packet;
- SendStreamDataToPeer(1, "foo", 0, NO_FIN, &last_packet);
- EXPECT_EQ(QuicPacketNumber(1u), last_packet);
- // Receive ack for packet 1.
- EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
- QuicAckFrame frame1 = InitAckFrame(1);
- ProcessAckPacket(&frame1);
- // Key update should now be allowed, initiate it.
- EXPECT_CALL(visitor_, AdvanceKeysAndCreateCurrentOneRttDecrypter())
- .WillOnce([kIntegrityLimit]() {
- return std::make_unique<StrictTaggingDecrypterWithIntegrityLimit>(
- 0x02, kIntegrityLimit);
- });
- EXPECT_CALL(visitor_, CreateCurrentOneRttEncrypter()).WillOnce([]() {
- return std::make_unique<TaggingEncrypter>(0x02);
- });
- EXPECT_CALL(visitor_, OnKeyUpdate(KeyUpdateReason::kLocalForTests));
- EXPECT_TRUE(connection_.InitiateKeyUpdate(KeyUpdateReason::kLocalForTests));
-
- // Pretend that peer accepts the key update.
- EXPECT_CALL(peer_framer_visitor_,
- AdvanceKeysAndCreateCurrentOneRttDecrypter())
- .WillOnce(
- []() { return std::make_unique<StrictTaggingDecrypter>(0x02); });
- EXPECT_CALL(peer_framer_visitor_, CreateCurrentOneRttEncrypter())
- .WillOnce([]() { return std::make_unique<TaggingEncrypter>(0x02); });
- peer_framer_.SetKeyUpdateSupportForConnection(true);
- peer_framer_.DoKeyUpdate(KeyUpdateReason::kLocalForTests);
-
- // Send packet 2.
- SendStreamDataToPeer(2, "bar", 0, NO_FIN, &last_packet);
- EXPECT_EQ(QuicPacketNumber(2u), last_packet);
- // Receive ack for packet 2.
- EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
- QuicAckFrame frame2 = InitAckFrame(2);
- ProcessAckPacket(&frame2);
-
- EXPECT_EQ(2u,
- connection_.GetStats().num_failed_authentication_packets_received);
-
- // Do two more undecryptable packets. Integrity limit should be reached.
- peer_framer_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
- std::make_unique<TaggingEncrypter>(0xFF));
- for (uint64_t i = 3; i <= kIntegrityLimit; ++i) {
- EXPECT_TRUE(connection_.connected());
- if (i == kIntegrityLimit) {
- EXPECT_CALL(visitor_, OnConnectionClosed(_, _));
- }
- ProcessDataPacketAtLevel(i, !kHasStopWaiting, ENCRYPTION_FORWARD_SECURE);
- EXPECT_EQ(
- i, connection_.GetStats().num_failed_authentication_packets_received);
- }
- EXPECT_FALSE(connection_.connected());
- TestConnectionCloseQuicErrorCode(QUIC_AEAD_LIMIT_REACHED);
-}
-
-TEST_P(QuicConnectionTest, SendAckFrequencyFrame) {
- if (!version().HasIetfQuicFrames()) {
- return;
- }
- SetQuicReloadableFlag(quic_can_send_ack_frequency, true);
- set_perspective(Perspective::IS_SERVER);
- EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _))
- .Times(AnyNumber());
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AnyNumber());
-
- QuicConfig config;
- QuicConfigPeer::SetReceivedMinAckDelayMs(&config, /*min_ack_delay_ms=*/1);
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
- connection_.SetFromConfig(config);
- QuicConnectionPeer::SetAddressValidated(&connection_);
- connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
- peer_creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
-
- connection_.OnHandshakeComplete();
-
- writer_->SetWritable();
- QuicPacketCreatorPeer::SetPacketNumber(creator_, 99);
- // Send packet 100
- SendStreamDataToPeer(/*id=*/1, "foo", /*offset=*/0, NO_FIN, nullptr);
-
- QuicAckFrequencyFrame captured_frame;
- EXPECT_CALL(visitor_, SendAckFrequency(_))
- .WillOnce(Invoke([&captured_frame](const QuicAckFrequencyFrame& frame) {
- captured_frame = frame;
- }));
- // Send packet 101.
- SendStreamDataToPeer(/*id=*/1, "bar", /*offset=*/3, NO_FIN, nullptr);
-
- EXPECT_EQ(captured_frame.packet_tolerance, 10u);
- EXPECT_EQ(captured_frame.max_ack_delay,
- QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs));
-
- // Sending packet 102 does not trigger sending another AckFrequencyFrame.
- SendStreamDataToPeer(/*id=*/1, "baz", /*offset=*/6, NO_FIN, nullptr);
-}
-
-TEST_P(QuicConnectionTest, SendAckFrequencyFrameUponHandshakeCompletion) {
- if (!version().HasIetfQuicFrames()) {
- return;
- }
- SetQuicReloadableFlag(quic_can_send_ack_frequency, true);
- set_perspective(Perspective::IS_SERVER);
- EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _))
- .Times(AnyNumber());
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AnyNumber());
-
- QuicConfig config;
- QuicConfigPeer::SetReceivedMinAckDelayMs(&config, /*min_ack_delay_ms=*/1);
- QuicTagVector quic_tag_vector;
- // Enable sending AckFrequency upon handshake completion.
- quic_tag_vector.push_back(kAFF2);
- QuicConfigPeer::SetReceivedConnectionOptions(&config, quic_tag_vector);
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
- connection_.SetFromConfig(config);
- QuicConnectionPeer::SetAddressValidated(&connection_);
- connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
- peer_creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
-
- QuicAckFrequencyFrame captured_frame;
- EXPECT_CALL(visitor_, SendAckFrequency(_))
- .WillOnce(Invoke([&captured_frame](const QuicAckFrequencyFrame& frame) {
- captured_frame = frame;
- }));
-
- connection_.OnHandshakeComplete();
-
- EXPECT_EQ(captured_frame.packet_tolerance, 2u);
- EXPECT_EQ(captured_frame.max_ack_delay,
- QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs));
-}
-
-TEST_P(QuicConnectionTest, FastRecoveryOfLostServerHello) {
- if (!connection_.SupportsMultiplePacketNumberSpaces()) {
- return;
- }
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
- QuicConfig config;
- connection_.SetFromConfig(config);
-
- use_tagging_decrypter();
- connection_.SetEncrypter(ENCRYPTION_INITIAL,
- std::make_unique<TaggingEncrypter>(0x01));
- connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
- connection_.SendCryptoStreamData();
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(20));
-
- // Assume ServerHello gets lost.
- peer_framer_.SetEncrypter(ENCRYPTION_HANDSHAKE,
- std::make_unique<TaggingEncrypter>(0x02));
- ProcessCryptoPacketAtLevel(2, ENCRYPTION_HANDSHAKE);
- ASSERT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
- // Shorten PTO for fast recovery from lost ServerHello.
- EXPECT_EQ(clock_.ApproximateNow() + kAlarmGranularity,
- connection_.GetRetransmissionAlarm()->deadline());
-}
-
-TEST_P(QuicConnectionTest, ServerHelloGetsReordered) {
- if (!connection_.SupportsMultiplePacketNumberSpaces()) {
- return;
- }
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
- QuicConfig config;
- connection_.SetFromConfig(config);
- EXPECT_CALL(visitor_, OnCryptoFrame(_))
- .WillRepeatedly(Invoke([=](const QuicCryptoFrame& frame) {
- if (frame.level == ENCRYPTION_INITIAL) {
- // Install handshake read keys.
- SetDecrypter(ENCRYPTION_HANDSHAKE,
- std::make_unique<StrictTaggingDecrypter>(0x02));
- connection_.SetEncrypter(ENCRYPTION_HANDSHAKE,
- std::make_unique<TaggingEncrypter>(0x02));
- connection_.SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE);
- }
- }));
-
- use_tagging_decrypter();
- connection_.SetEncrypter(ENCRYPTION_INITIAL,
- std::make_unique<TaggingEncrypter>(0x01));
- connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
- connection_.SendCryptoStreamData();
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(20));
-
- // Assume ServerHello gets reordered.
- peer_framer_.SetEncrypter(ENCRYPTION_HANDSHAKE,
- std::make_unique<TaggingEncrypter>(0x02));
- ProcessCryptoPacketAtLevel(2, ENCRYPTION_HANDSHAKE);
- ProcessCryptoPacketAtLevel(1, ENCRYPTION_INITIAL);
- // Verify fast recovery is not enabled.
- EXPECT_EQ(connection_.sent_packet_manager().GetRetransmissionTime(),
- connection_.GetRetransmissionAlarm()->deadline());
-}
-
-TEST_P(QuicConnectionTest, MigratePath) {
- EXPECT_CALL(visitor_, GetHandshakeState())
- .Times(testing::AtMost(2))
- .WillRepeatedly(Return(HANDSHAKE_CONFIRMED));
- EXPECT_CALL(visitor_, OnPathDegrading());
- connection_.OnPathDegradingDetected();
- const QuicSocketAddress kNewSelfAddress(QuicIpAddress::Any4(), 12345);
- EXPECT_NE(kNewSelfAddress, connection_.self_address());
-
- // Buffer a packet.
- EXPECT_CALL(visitor_, OnWriteBlocked()).Times(1);
- writer_->SetWriteBlocked();
- connection_.SendMtuDiscoveryPacket(kMaxOutgoingPacketSize);
- EXPECT_EQ(1u, connection_.NumQueuedPackets());
-
- TestPacketWriter new_writer(version(), &clock_, Perspective::IS_CLIENT);
- EXPECT_CALL(visitor_, OnForwardProgressMadeAfterPathDegrading());
- connection_.MigratePath(kNewSelfAddress, connection_.peer_address(),
- &new_writer, /*owns_writer=*/false);
-
- EXPECT_EQ(kNewSelfAddress, connection_.self_address());
- EXPECT_EQ(&new_writer, QuicConnectionPeer::GetWriter(&connection_));
- EXPECT_FALSE(connection_.IsPathDegrading());
- // Buffered packet on the old path should be discarded.
- if (connection_.connection_migration_use_new_cid()) {
- EXPECT_EQ(0u, connection_.NumQueuedPackets());
- } else {
- EXPECT_EQ(1u, connection_.NumQueuedPackets());
- }
-}
-
-TEST_P(QuicConnectionTest, MigrateToNewPathDuringProbing) {
- if (!VersionHasIetfQuicFrames(connection_.version().transport_version) ||
- !connection_.use_path_validator()) {
- return;
- }
- PathProbeTestInit(Perspective::IS_CLIENT);
- const QuicSocketAddress kNewSelfAddress(QuicIpAddress::Any4(), 12345);
- EXPECT_NE(kNewSelfAddress, connection_.self_address());
- TestPacketWriter new_writer(version(), &clock_, Perspective::IS_CLIENT);
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _));
- bool success = false;
- connection_.ValidatePath(
- std::make_unique<TestQuicPathValidationContext>(
- kNewSelfAddress, connection_.peer_address(), &new_writer),
- std::make_unique<TestValidationResultDelegate>(
- &connection_, kNewSelfAddress, connection_.peer_address(), &success));
- EXPECT_TRUE(connection_.HasPendingPathValidation());
- EXPECT_TRUE(QuicConnectionPeer::IsAlternativePath(
- &connection_, kNewSelfAddress, connection_.peer_address()));
-
- connection_.MigratePath(kNewSelfAddress, connection_.peer_address(),
- &new_writer, /*owns_writer=*/false);
- EXPECT_EQ(kNewSelfAddress, connection_.self_address());
- EXPECT_TRUE(connection_.HasPendingPathValidation());
- EXPECT_FALSE(QuicConnectionPeer::IsAlternativePath(
- &connection_, kNewSelfAddress, connection_.peer_address()));
-}
-
-TEST_P(QuicConnectionTest, SingleAckInPacket) {
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- EXPECT_CALL(visitor_, OnConnectionClosed(_, _));
- connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
- connection_.RemoveEncrypter(ENCRYPTION_INITIAL);
- connection_.NeuterUnencryptedPackets();
- connection_.OnHandshakeComplete();
- EXPECT_CALL(visitor_, GetHandshakeState())
- .WillRepeatedly(Return(HANDSHAKE_COMPLETE));
-
- EXPECT_CALL(visitor_, OnStreamFrame(_)).WillOnce(Invoke([=]() {
- connection_.SendStreamData3();
- connection_.CloseConnection(
- QUIC_INTERNAL_ERROR, "error",
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
- }));
- QuicFrames frames;
- frames.push_back(QuicFrame(frame1_));
- ProcessFramesPacketWithAddresses(frames, kSelfAddress, kPeerAddress,
- ENCRYPTION_FORWARD_SECURE);
- ASSERT_FALSE(writer_->ack_frames().empty());
- if (GetQuicReloadableFlag(quic_single_ack_in_packet2)) {
- EXPECT_EQ(1u, writer_->ack_frames().size());
- } else {
- EXPECT_EQ(2u, writer_->ack_frames().size());
- }
-}
-
-TEST_P(QuicConnectionTest,
- ServerReceivedZeroRttPacketAfterOneRttPacketWithRetainedKey) {
- if (!connection_.version().UsesTls()) {
- return;
- }
-
- set_perspective(Perspective::IS_SERVER);
- SetDecrypter(ENCRYPTION_ZERO_RTT,
- std::make_unique<NullDecrypter>(Perspective::IS_SERVER));
-
- EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
- ProcessDataPacketAtLevel(1, !kHasStopWaiting, ENCRYPTION_ZERO_RTT);
-
- // Finish handshake.
- connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
- notifier_.NeuterUnencryptedData();
- connection_.NeuterUnencryptedPackets();
- connection_.OnHandshakeComplete();
- EXPECT_CALL(visitor_, GetHandshakeState())
- .WillRepeatedly(Return(HANDSHAKE_COMPLETE));
-
- EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
- ProcessDataPacketAtLevel(4, !kHasStopWaiting, ENCRYPTION_FORWARD_SECURE);
- EXPECT_TRUE(connection_.GetDiscardZeroRttDecryptionKeysAlarm()->IsSet());
-
- // 0-RTT packet received out of order should be decoded since the decrypter
- // is temporarily retained.
- EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
- ProcessDataPacketAtLevel(2, !kHasStopWaiting, ENCRYPTION_ZERO_RTT);
- EXPECT_EQ(
- 0u,
- connection_.GetStats()
- .num_tls_server_zero_rtt_packets_received_after_discarding_decrypter);
-
- // Simulate the timeout for discarding 0-RTT keys passing.
- connection_.GetDiscardZeroRttDecryptionKeysAlarm()->Fire();
-
- // Another 0-RTT packet received now should not be decoded.
- EXPECT_FALSE(connection_.GetDiscardZeroRttDecryptionKeysAlarm()->IsSet());
- EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(0);
- ProcessDataPacketAtLevel(3, !kHasStopWaiting, ENCRYPTION_ZERO_RTT);
- EXPECT_EQ(
- 1u,
- connection_.GetStats()
- .num_tls_server_zero_rtt_packets_received_after_discarding_decrypter);
-
- // The |discard_zero_rtt_decryption_keys_alarm_| should only be set on the
- // first 1-RTT packet received.
- EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
- ProcessDataPacketAtLevel(5, !kHasStopWaiting, ENCRYPTION_FORWARD_SECURE);
- EXPECT_FALSE(connection_.GetDiscardZeroRttDecryptionKeysAlarm()->IsSet());
-}
-
-TEST_P(QuicConnectionTest, NewTokenFrameInstigateAcks) {
- if (!version().HasIetfQuicFrames()) {
- return;
- }
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-
- QuicNewTokenFrame* new_token = new QuicNewTokenFrame();
- EXPECT_CALL(visitor_, OnNewTokenReceived(_));
- ProcessFramePacket(QuicFrame(new_token));
-
- // Ensure that this has caused the ACK alarm to be set.
- EXPECT_TRUE(connection_.HasPendingAcks());
-}
-
-TEST_P(QuicConnectionTest, ServerClosesConnectionOnNewTokenFrame) {
- if (!version().HasIetfQuicFrames()) {
- return;
- }
- set_perspective(Perspective::IS_SERVER);
- QuicNewTokenFrame* new_token = new QuicNewTokenFrame();
- EXPECT_CALL(visitor_, OnNewTokenReceived(_)).Times(0);
- EXPECT_CALL(visitor_, OnConnectionClosed(_, _));
- EXPECT_CALL(visitor_, BeforeConnectionCloseSent());
- ProcessFramePacket(QuicFrame(new_token));
- EXPECT_FALSE(connection_.connected());
-}
-
-TEST_P(QuicConnectionTest, OverrideRetryTokenWithRetryPacket) {
- if (!version().HasIetfQuicFrames()) {
- return;
- }
- std::string address_token = "TestAddressToken";
- connection_.SetSourceAddressTokenToSend(address_token);
- EXPECT_EQ(QuicPacketCreatorPeer::GetRetryToken(
- QuicConnectionPeer::GetPacketCreator(&connection_)),
- address_token);
- // Passes valid retry and verify token gets overridden.
- TestClientRetryHandling(/*invalid_retry_tag=*/false,
- /*missing_original_id_in_config=*/false,
- /*wrong_original_id_in_config=*/false,
- /*missing_retry_id_in_config=*/false,
- /*wrong_retry_id_in_config=*/false);
-}
-
-TEST_P(QuicConnectionTest, DonotOverrideRetryTokenWithAddressToken) {
- if (!version().HasIetfQuicFrames()) {
- return;
- }
- // Passes valid retry and verify token gets overridden.
- TestClientRetryHandling(/*invalid_retry_tag=*/false,
- /*missing_original_id_in_config=*/false,
- /*wrong_original_id_in_config=*/false,
- /*missing_retry_id_in_config=*/false,
- /*wrong_retry_id_in_config=*/false);
- std::string retry_token = QuicPacketCreatorPeer::GetRetryToken(
- QuicConnectionPeer::GetPacketCreator(&connection_));
-
- std::string address_token = "TestAddressToken";
- connection_.SetSourceAddressTokenToSend(address_token);
- EXPECT_EQ(QuicPacketCreatorPeer::GetRetryToken(
- QuicConnectionPeer::GetPacketCreator(&connection_)),
- retry_token);
-}
-
-TEST_P(QuicConnectionTest,
- ServerReceivedZeroRttWithHigherPacketNumberThanOneRtt) {
- if (!connection_.version().UsesTls()) {
- return;
- }
-
- // The code that checks for this error piggybacks on some book-keeping state
- // kept for key update, so enable key update for the test.
- std::string error_details;
- TransportParameters params;
- QuicConfig config;
- EXPECT_THAT(config.ProcessTransportParameters(
- params, /* is_resumption = */ false, &error_details),
- IsQuicNoError());
- QuicConfigPeer::SetNegotiated(&config, true);
- QuicConfigPeer::SetReceivedOriginalConnectionId(&config,
- connection_.connection_id());
- QuicConfigPeer::SetReceivedInitialSourceConnectionId(
- &config, connection_.connection_id());
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
- connection_.SetFromConfig(config);
-
- set_perspective(Perspective::IS_SERVER);
- SetDecrypter(ENCRYPTION_ZERO_RTT,
- std::make_unique<NullDecrypter>(Perspective::IS_SERVER));
-
- EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
- ProcessDataPacketAtLevel(1, !kHasStopWaiting, ENCRYPTION_ZERO_RTT);
-
- // Finish handshake.
- connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
- notifier_.NeuterUnencryptedData();
- connection_.NeuterUnencryptedPackets();
- connection_.OnHandshakeComplete();
- EXPECT_CALL(visitor_, GetHandshakeState())
- .WillRepeatedly(Return(HANDSHAKE_COMPLETE));
-
- // Decrypt a 1-RTT packet.
- EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
- ProcessDataPacketAtLevel(2, !kHasStopWaiting, ENCRYPTION_FORWARD_SECURE);
- EXPECT_TRUE(connection_.GetDiscardZeroRttDecryptionKeysAlarm()->IsSet());
-
- // 0-RTT packet with higher packet number than a 1-RTT packet is invalid and
- // should cause the connection to be closed.
- EXPECT_CALL(visitor_, BeforeConnectionCloseSent());
- EXPECT_CALL(visitor_, OnConnectionClosed(_, _));
- ProcessDataPacketAtLevel(3, !kHasStopWaiting, ENCRYPTION_ZERO_RTT);
- EXPECT_FALSE(connection_.connected());
- TestConnectionCloseQuicErrorCode(
- QUIC_INVALID_0RTT_PACKET_NUMBER_OUT_OF_ORDER);
-}
-
-// Regression test for b/177312785
-TEST_P(QuicConnectionTest, PeerMigrateBeforeHandshakeConfirm) {
- if (!VersionHasIetfQuicFrames(version().transport_version)) {
- return;
- }
- set_perspective(Perspective::IS_SERVER);
- QuicPacketCreatorPeer::SetSendVersionInPacket(creator_, false);
- EXPECT_EQ(Perspective::IS_SERVER, connection_.perspective());
- EXPECT_CALL(visitor_, GetHandshakeState())
- .WillRepeatedly(Return(HANDSHAKE_START));
-
- // Clear direct_peer_address.
- QuicConnectionPeer::SetDirectPeerAddress(&connection_, QuicSocketAddress());
- // Clear effective_peer_address, it is the same as direct_peer_address for
- // this test.
- QuicConnectionPeer::SetEffectivePeerAddress(&connection_,
- QuicSocketAddress());
- EXPECT_FALSE(connection_.effective_peer_address().IsInitialized());
-
- const QuicSocketAddress kNewPeerAddress =
- QuicSocketAddress(QuicIpAddress::Loopback6(), /*port=*/23456);
- EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
- ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress, kPeerAddress,
- ENCRYPTION_INITIAL);
- EXPECT_EQ(kPeerAddress, connection_.peer_address());
- EXPECT_EQ(kPeerAddress, connection_.effective_peer_address());
-
- // Process another packet with a different peer address on server side will
- // close connection.
- QuicAckFrame frame = InitAckFrame(1);
- EXPECT_CALL(visitor_, BeforeConnectionCloseSent());
- EXPECT_CALL(visitor_,
- OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF));
- EXPECT_CALL(visitor_, OnConnectionMigration(PORT_CHANGE)).Times(0u);
-
- EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _)).Times(0);
- ProcessFramePacketWithAddresses(QuicFrame(&frame), kSelfAddress,
- kNewPeerAddress, ENCRYPTION_INITIAL);
- EXPECT_FALSE(connection_.connected());
-}
-
-// Regresstion test for b/175685916
-TEST_P(QuicConnectionTest, TryToFlushAckWithAckQueued) {
- if (!version().HasIetfQuicFrames()) {
- return;
- }
- SetQuicReloadableFlag(quic_can_send_ack_frequency, true);
- SetQuicReloadableFlag(quic_single_ack_in_packet2, true);
- set_perspective(Perspective::IS_SERVER);
-
- QuicConfig config;
- QuicConfigPeer::SetReceivedMinAckDelayMs(&config, /*min_ack_delay_ms=*/1);
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
- connection_.SetFromConfig(config);
- connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
- connection_.OnHandshakeComplete();
- QuicPacketCreatorPeer::SetPacketNumber(creator_, 200);
-
- EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
- ProcessDataPacketAtLevel(1, !kHasStopWaiting, ENCRYPTION_FORWARD_SECURE);
- // Sending ACK_FREQUENCY bundles ACK. QuicConnectionPeer::SendPing
- // will try to bundle ACK but there is no pending ACK.
- EXPECT_CALL(visitor_, SendAckFrequency(_))
- .WillOnce(Invoke(&notifier_,
- &SimpleSessionNotifier::WriteOrBufferAckFrequency));
- QuicConnectionPeer::SendPing(&connection_);
-}
-
-TEST_P(QuicConnectionTest, PathChallengeBeforePeerIpAddressChangeAtServer) {
- set_perspective(Perspective::IS_SERVER);
- 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(new 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 another packet with a different peer address on server side will
- // start connection migration.
- EXPECT_CALL(visitor_, OnConnectionMigration(IPV6_TO_IPV4_CHANGE)).Times(1);
- EXPECT_CALL(visitor_, OnStreamFrame(_)).WillOnce(Invoke([=]() {
- EXPECT_EQ(kNewPeerAddress, connection_.peer_address());
- }));
- // IETF QUIC send algorithm should be changed to a different object, so no
- // OnPacketSent() called on the old send algorithm.
- EXPECT_CALL(*send_algorithm_,
- OnPacketSent(_, _, _, _, NO_RETRANSMITTABLE_DATA))
- .Times(0);
- QuicFrames frames2;
- frames2.push_back(QuicFrame(frame2_));
- ProcessFramesPacketWithAddresses(frames2, kSelfAddress, kNewPeerAddress,
- ENCRYPTION_FORWARD_SECURE);
- EXPECT_EQ(kNewPeerAddress, connection_.peer_address());
- EXPECT_EQ(kNewPeerAddress, connection_.effective_peer_address());
- EXPECT_EQ(IPV6_TO_IPV4_CHANGE,
- connection_.active_effective_peer_migration_type());
- EXPECT_TRUE(writer_->path_challenge_frames().empty());
- EXPECT_NE(connection_.sent_packet_manager().GetSendAlgorithm(),
- send_algorithm_);
- // Switch to use the mock send algorithm.
- send_algorithm_ = new StrictMock<MockSendAlgorithm>();
- EXPECT_CALL(*send_algorithm_, CanSend(_)).WillRepeatedly(Return(true));
- EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
- .WillRepeatedly(Return(kDefaultTCPMSS));
- EXPECT_CALL(*send_algorithm_, OnApplicationLimited(_)).Times(AnyNumber());
- EXPECT_CALL(*send_algorithm_, BandwidthEstimate())
- .Times(AnyNumber())
- .WillRepeatedly(Return(QuicBandwidth::Zero()));
- EXPECT_CALL(*send_algorithm_, InSlowStart()).Times(AnyNumber());
- EXPECT_CALL(*send_algorithm_, InRecovery()).Times(AnyNumber());
- EXPECT_CALL(*send_algorithm_, PopulateConnectionStats(_)).Times(AnyNumber());
- connection_.SetSendAlgorithm(send_algorithm_);
- EXPECT_EQ(default_path->client_connection_id, client_cid1);
- EXPECT_EQ(default_path->server_connection_id, server_cid1);
- // The previous default path is kept as alternative path before reverse path
- // validation finishes.
- EXPECT_EQ(alternative_path->client_connection_id, client_cid0);
- EXPECT_EQ(alternative_path->server_connection_id, server_cid0);
- EXPECT_EQ(packet_creator->GetDestinationConnectionId(), client_cid1);
- EXPECT_EQ(packet_creator->GetSourceConnectionId(), server_cid1);
-
- EXPECT_EQ(kNewPeerAddress, connection_.peer_address());
- EXPECT_EQ(kNewPeerAddress, connection_.effective_peer_address());
- EXPECT_EQ(IPV6_TO_IPV4_CHANGE,
- connection_.active_effective_peer_migration_type());
- EXPECT_EQ(1u, connection_.GetStats()
- .num_peer_migration_to_proactively_validated_address);
-
- // The PATH_CHALLENGE and PATH_RESPONSE is expanded upto the max packet size
- // which may exceeds the anti-amplification limit. Verify server is throttled
- // by anti-amplification limit.
- connection_.SendCryptoDataWithString("foo", 0);
- EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
-
- // Receiving PATH_RESPONSE should lift the anti-amplification limit.
- QuicFrames frames3;
- frames3.push_back(QuicFrame(new QuicPathResponseFrame(99, payload)));
- EXPECT_CALL(visitor_, MaybeSendAddressToken());
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
- .Times(testing::AtLeast(1u));
- ProcessFramesPacketWithAddresses(frames3, kSelfAddress, kNewPeerAddress,
- ENCRYPTION_FORWARD_SECURE);
- EXPECT_EQ(NO_CHANGE, connection_.active_effective_peer_migration_type());
- // Verify that alternative_path_ is cleared and the peer CID is retired.
- EXPECT_TRUE(alternative_path->client_connection_id.IsEmpty());
- EXPECT_TRUE(alternative_path->server_connection_id.IsEmpty());
- EXPECT_FALSE(alternative_path->stateless_reset_token.has_value());
- auto* retire_peer_issued_cid_alarm =
- connection_.GetRetirePeerIssuedConnectionIdAlarm();
- ASSERT_TRUE(retire_peer_issued_cid_alarm->IsSet());
- EXPECT_CALL(visitor_, SendRetireConnectionId(/*sequence_number=*/0u));
- retire_peer_issued_cid_alarm->Fire();
-
- // Verify the anti-amplification limit is lifted by sending a packet larger
- // than the anti-amplification limit.
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
- EXPECT_CALL(*send_algorithm_, PacingRate(_))
- .WillRepeatedly(Return(QuicBandwidth::Zero()));
- connection_.SendCryptoDataWithString(std::string(1200, 'a'), 0);
- EXPECT_EQ(1u, connection_.GetStats().num_validated_peer_migration);
-}
-
-TEST_P(QuicConnectionTest,
- PathValidationSucceedsBeforePeerIpAddressChangeAtServer) {
- set_perspective(Perspective::IS_SERVER);
- if (!connection_.connection_migration_use_new_cid()) {
- return;
- }
- PathProbeTestInit(Perspective::IS_SERVER);
- connection_.CreateConnectionIdManager();
-
- QuicConnectionId server_cid0 = connection_.connection_id();
- 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();
- auto* packet_creator = QuicConnectionPeer::GetPacketCreator(&connection_);
- ASSERT_EQ(packet_creator->GetSourceConnectionId(), server_cid0);
-
- // Receive probing packet with new peer address.
- peer_creator_.SetServerConnectionId(server_cid1);
- const QuicSocketAddress kNewPeerAddress(QuicIpAddress::Loopback4(),
- /*port=*/23456);
- QuicPathFrameBuffer payload;
- EXPECT_CALL(*send_algorithm_,
- OnPacketSent(_, _, _, _, NO_RETRANSMITTABLE_DATA))
- .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;
- }))
- .WillRepeatedly(Invoke([&]() {
- // Only start reverse path validation once.
- EXPECT_TRUE(writer_->path_challenge_frames().empty());
- }));
- QuicPathFrameBuffer path_challenge_payload{0, 1, 2, 3, 4, 5, 6, 7};
- QuicFrames frames1;
- frames1.push_back(
- QuicFrame(new QuicPathChallengeFrame(0, path_challenge_payload)));
- ProcessFramesPacketWithAddresses(frames1, kSelfAddress, kNewPeerAddress,
- ENCRYPTION_FORWARD_SECURE);
- EXPECT_TRUE(connection_.HasPendingPathValidation());
- const auto* default_path = QuicConnectionPeer::GetDefaultPath(&connection_);
- const auto* alternative_path =
- QuicConnectionPeer::GetAlternativePath(&connection_);
- EXPECT_EQ(default_path->server_connection_id, server_cid0);
- EXPECT_EQ(alternative_path->server_connection_id, server_cid1);
- EXPECT_EQ(packet_creator->GetSourceConnectionId(), server_cid0);
-
- // Receive PATH_RESPONSE should mark the new peer address validated.
- QuicFrames frames3;
- frames3.push_back(QuicFrame(new QuicPathResponseFrame(99, payload)));
- ProcessFramesPacketWithAddresses(frames3, kSelfAddress, kNewPeerAddress,
- ENCRYPTION_FORWARD_SECURE);
-
- // Process another packet with a newer peer address with the same port will
- // start connection migration.
- EXPECT_CALL(visitor_, OnConnectionMigration(IPV6_TO_IPV4_CHANGE)).Times(1);
- // IETF QUIC send algorithm should be changed to a different object, so no
- // OnPacketSent() called on the old send algorithm.
- EXPECT_CALL(*send_algorithm_,
- OnPacketSent(_, _, _, _, NO_RETRANSMITTABLE_DATA))
- .Times(0);
- const QuicSocketAddress kNewerPeerAddress(QuicIpAddress::Loopback4(),
- /*port=*/34567);
- EXPECT_CALL(visitor_, OnStreamFrame(_)).WillOnce(Invoke([=]() {
- EXPECT_EQ(kNewerPeerAddress, connection_.peer_address());
- }));
- EXPECT_CALL(visitor_, MaybeSendAddressToken());
- QuicFrames frames2;
- frames2.push_back(QuicFrame(frame2_));
- ProcessFramesPacketWithAddresses(frames2, kSelfAddress, kNewerPeerAddress,
- ENCRYPTION_FORWARD_SECURE);
- EXPECT_EQ(kNewerPeerAddress, connection_.peer_address());
- EXPECT_EQ(kNewerPeerAddress, connection_.effective_peer_address());
- // Since the newer address has the same IP as the previously validated probing
- // address. The peer migration becomes validated immediately.
- EXPECT_EQ(NO_CHANGE, connection_.active_effective_peer_migration_type());
- EXPECT_EQ(kNewerPeerAddress, writer_->last_write_peer_address());
- EXPECT_EQ(1u, connection_.GetStats()
- .num_peer_migration_to_proactively_validated_address);
- EXPECT_FALSE(connection_.HasPendingPathValidation());
- EXPECT_NE(connection_.sent_packet_manager().GetSendAlgorithm(),
- send_algorithm_);
-
- EXPECT_EQ(default_path->server_connection_id, server_cid1);
- EXPECT_EQ(packet_creator->GetSourceConnectionId(), server_cid1);
- // Verify that alternative_path_ is cleared.
- EXPECT_TRUE(alternative_path->server_connection_id.IsEmpty());
- EXPECT_FALSE(alternative_path->stateless_reset_token.has_value());
-
- // Switch to use the mock send algorithm.
- send_algorithm_ = new StrictMock<MockSendAlgorithm>();
- EXPECT_CALL(*send_algorithm_, CanSend(_)).WillRepeatedly(Return(true));
- EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
- .WillRepeatedly(Return(kDefaultTCPMSS));
- EXPECT_CALL(*send_algorithm_, OnApplicationLimited(_)).Times(AnyNumber());
- EXPECT_CALL(*send_algorithm_, BandwidthEstimate())
- .Times(AnyNumber())
- .WillRepeatedly(Return(QuicBandwidth::Zero()));
- EXPECT_CALL(*send_algorithm_, InSlowStart()).Times(AnyNumber());
- EXPECT_CALL(*send_algorithm_, InRecovery()).Times(AnyNumber());
- EXPECT_CALL(*send_algorithm_, PopulateConnectionStats(_)).Times(AnyNumber());
- connection_.SetSendAlgorithm(send_algorithm_);
-
- // Verify the server is not throttled by the anti-amplification limit by
- // sending a packet larger than the anti-amplification limit.
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _));
- connection_.SendCryptoDataWithString(std::string(1200, 'a'), 0);
- EXPECT_EQ(1u, connection_.GetStats().num_validated_peer_migration);
-}
-
-TEST_P(QuicConnectionTest,
- ProbedOnAnotherPathAfterPeerIpAddressChangeAtServer) {
- PathProbeTestInit(Perspective::IS_SERVER);
- if (!connection_.validate_client_address()) {
- return;
- }
-
- const QuicSocketAddress kNewPeerAddress(QuicIpAddress::Loopback4(),
- /*port=*/23456);
-
- // Process a packet with a new peer address will start connection migration.
- EXPECT_CALL(visitor_, OnConnectionMigration(IPV6_TO_IPV4_CHANGE)).Times(1);
- // IETF QUIC send algorithm should be changed to a different object, so no
- // OnPacketSent() called on the old send algorithm.
- EXPECT_CALL(*send_algorithm_,
- OnPacketSent(_, _, _, _, NO_RETRANSMITTABLE_DATA))
- .Times(0);
- EXPECT_CALL(visitor_, OnStreamFrame(_)).WillOnce(Invoke([=]() {
- EXPECT_EQ(kNewPeerAddress, connection_.peer_address());
- }));
- QuicFrames frames2;
- frames2.push_back(QuicFrame(frame2_));
- ProcessFramesPacketWithAddresses(frames2, kSelfAddress, kNewPeerAddress,
- ENCRYPTION_FORWARD_SECURE);
- EXPECT_TRUE(QuicConnectionPeer::IsAlternativePathValidated(&connection_));
- EXPECT_TRUE(connection_.HasPendingPathValidation());
-
- // Switch to use the mock send algorithm.
- send_algorithm_ = new StrictMock<MockSendAlgorithm>();
- EXPECT_CALL(*send_algorithm_, CanSend(_)).WillRepeatedly(Return(true));
- EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
- .WillRepeatedly(Return(kDefaultTCPMSS));
- EXPECT_CALL(*send_algorithm_, OnApplicationLimited(_)).Times(AnyNumber());
- EXPECT_CALL(*send_algorithm_, BandwidthEstimate())
- .Times(AnyNumber())
- .WillRepeatedly(Return(QuicBandwidth::Zero()));
- EXPECT_CALL(*send_algorithm_, InSlowStart()).Times(AnyNumber());
- EXPECT_CALL(*send_algorithm_, InRecovery()).Times(AnyNumber());
- EXPECT_CALL(*send_algorithm_, PopulateConnectionStats(_)).Times(AnyNumber());
- connection_.SetSendAlgorithm(send_algorithm_);
-
- // Receive probing packet with a newer peer address shouldn't override the
- // on-going path validation.
- const QuicSocketAddress kNewerPeerAddress(QuicIpAddress::Loopback4(),
- /*port=*/34567);
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
- .WillOnce(Invoke([&]() {
- EXPECT_EQ(kNewerPeerAddress, writer_->last_write_peer_address());
- EXPECT_FALSE(writer_->path_response_frames().empty());
- EXPECT_TRUE(writer_->path_challenge_frames().empty());
- }));
- QuicPathFrameBuffer path_challenge_payload{0, 1, 2, 3, 4, 5, 6, 7};
- QuicFrames frames1;
- frames1.push_back(
- QuicFrame(new QuicPathChallengeFrame(0, path_challenge_payload)));
- ProcessFramesPacketWithAddresses(frames1, kSelfAddress, kNewerPeerAddress,
- ENCRYPTION_FORWARD_SECURE);
- EXPECT_EQ(kNewPeerAddress, connection_.effective_peer_address());
- EXPECT_EQ(kNewPeerAddress, connection_.peer_address());
- EXPECT_TRUE(QuicConnectionPeer::IsAlternativePathValidated(&connection_));
- EXPECT_TRUE(connection_.HasPendingPathValidation());
-}
-
-TEST_P(QuicConnectionTest,
- PathValidationFailedOnClientDueToLackOfServerConnectionId) {
- if (!GetQuicReloadableFlag(
- quic_remove_connection_migration_connection_option)) {
- QuicConfig config;
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
- connection_.SetFromConfig(config);
- config.SetConnectionOptionsToSend({kRVCM});
- }
- if (!connection_.connection_migration_use_new_cid()) {
- return;
- }
- PathProbeTestInit(Perspective::IS_CLIENT,
- /*receive_new_server_connection_id=*/false);
-
- const QuicSocketAddress kNewSelfAddress(QuicIpAddress::Loopback4(),
- /*port=*/34567);
-
- bool success;
- connection_.ValidatePath(
- std::make_unique<TestQuicPathValidationContext>(
- kNewSelfAddress, connection_.peer_address(), writer_.get()),
- std::make_unique<TestValidationResultDelegate>(
- &connection_, kNewSelfAddress, connection_.peer_address(), &success));
-
- EXPECT_FALSE(success);
-}
-
-TEST_P(QuicConnectionTest,
- PathValidationFailedOnClientDueToLackOfClientConnectionIdTheSecondTime) {
- if (!GetQuicReloadableFlag(
- quic_remove_connection_migration_connection_option)) {
- QuicConfig config;
- config.SetConnectionOptionsToSend({kRVCM});
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
- connection_.SetFromConfig(config);
- }
- if (!connection_.connection_migration_use_new_cid()) {
- return;
- }
- PathProbeTestInit(Perspective::IS_CLIENT,
- /*receive_new_server_connection_id=*/false);
- SetClientConnectionId(TestConnectionId(1));
-
- // Make sure server connection ID is available for the 1st validation.
- QuicConnectionId server_cid0 = connection_.connection_id();
- QuicConnectionId server_cid1 = TestConnectionId(2);
- QuicConnectionId server_cid2 = TestConnectionId(4);
- QuicConnectionId client_cid1;
- QuicNewConnectionIdFrame frame1;
- frame1.connection_id = server_cid1;
- frame1.sequence_number = 1u;
- frame1.retire_prior_to = 0u;
- frame1.stateless_reset_token =
- QuicUtils::GenerateStatelessResetToken(frame1.connection_id);
- connection_.OnNewConnectionIdFrame(frame1);
- const auto* packet_creator =
- QuicConnectionPeer::GetPacketCreator(&connection_);
- ASSERT_EQ(packet_creator->GetDestinationConnectionId(), server_cid0);
-
- // Client will issue a new client connection ID to server.
- EXPECT_CALL(visitor_, SendNewConnectionId(_))
- .WillOnce(Invoke([&](const QuicNewConnectionIdFrame& frame) {
- client_cid1 = frame.connection_id;
- }));
-
- const QuicSocketAddress kSelfAddress1(QuicIpAddress::Any4(), 12345);
- ASSERT_NE(kSelfAddress1, connection_.self_address());
- bool success1;
- connection_.ValidatePath(
- std::make_unique<TestQuicPathValidationContext>(
- kSelfAddress1, connection_.peer_address(), writer_.get()),
- std::make_unique<TestValidationResultDelegate>(
- &connection_, kSelfAddress1, connection_.peer_address(), &success1));
-
- // Migrate upon 1st validation success.
- TestPacketWriter new_writer(version(), &clock_, Perspective::IS_CLIENT);
- ASSERT_TRUE(connection_.MigratePath(kSelfAddress1, connection_.peer_address(),
- &new_writer, /*owns_writer=*/false));
- QuicConnectionPeer::RetirePeerIssuedConnectionIdsNoLongerOnPath(&connection_);
- const auto* default_path = QuicConnectionPeer::GetDefaultPath(&connection_);
- EXPECT_EQ(default_path->client_connection_id, client_cid1);
- EXPECT_EQ(default_path->server_connection_id, server_cid1);
- EXPECT_EQ(default_path->stateless_reset_token, frame1.stateless_reset_token);
- const auto* alternative_path =
- QuicConnectionPeer::GetAlternativePath(&connection_);
- EXPECT_TRUE(alternative_path->client_connection_id.IsEmpty());
- EXPECT_TRUE(alternative_path->server_connection_id.IsEmpty());
- EXPECT_FALSE(alternative_path->stateless_reset_token.has_value());
- ASSERT_EQ(packet_creator->GetDestinationConnectionId(), server_cid1);
-
- // Client will retire server connection ID on old default_path.
- auto* retire_peer_issued_cid_alarm =
- connection_.GetRetirePeerIssuedConnectionIdAlarm();
- ASSERT_TRUE(retire_peer_issued_cid_alarm->IsSet());
- EXPECT_CALL(visitor_, SendRetireConnectionId(/*sequence_number=*/0u));
- retire_peer_issued_cid_alarm->Fire();
-
- // Another server connection ID is available to client.
- QuicNewConnectionIdFrame frame2;
- frame2.connection_id = server_cid2;
- frame2.sequence_number = 2u;
- frame2.retire_prior_to = 1u;
- frame2.stateless_reset_token =
- QuicUtils::GenerateStatelessResetToken(frame2.connection_id);
- connection_.OnNewConnectionIdFrame(frame2);
-
- const QuicSocketAddress kSelfAddress2(QuicIpAddress::Loopback4(),
- /*port=*/45678);
- bool success2;
- connection_.ValidatePath(
- std::make_unique<TestQuicPathValidationContext>(
- kSelfAddress2, connection_.peer_address(), writer_.get()),
- std::make_unique<TestValidationResultDelegate>(
- &connection_, kSelfAddress2, connection_.peer_address(), &success2));
- // Since server does not retire any client connection ID yet, 2nd validation
- // would fail due to lack of client connection ID.
- EXPECT_FALSE(success2);
-}
-
-TEST_P(QuicConnectionTest, ServerConnectionIdRetiredUponPathValidationFailure) {
- if (!GetQuicReloadableFlag(
- quic_remove_connection_migration_connection_option)) {
- QuicConfig config;
- config.SetConnectionOptionsToSend({kRVCM});
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
- connection_.SetFromConfig(config);
- }
- if (!connection_.connection_migration_use_new_cid()) {
- return;
- }
- PathProbeTestInit(Perspective::IS_CLIENT);
-
- // Make sure server connection ID is available for validation.
- QuicNewConnectionIdFrame frame;
- frame.connection_id = TestConnectionId(2);
- frame.sequence_number = 1u;
- frame.retire_prior_to = 0u;
- frame.stateless_reset_token =
- QuicUtils::GenerateStatelessResetToken(frame.connection_id);
- connection_.OnNewConnectionIdFrame(frame);
-
- const QuicSocketAddress kNewSelfAddress(QuicIpAddress::Loopback4(),
- /*port=*/34567);
- bool success;
- connection_.ValidatePath(
- std::make_unique<TestQuicPathValidationContext>(
- kNewSelfAddress, connection_.peer_address(), writer_.get()),
- std::make_unique<TestValidationResultDelegate>(
- &connection_, kNewSelfAddress, connection_.peer_address(), &success));
-
- auto* path_validator = QuicConnectionPeer::path_validator(&connection_);
- path_validator->CancelPathValidation();
- QuicConnectionPeer::RetirePeerIssuedConnectionIdsNoLongerOnPath(&connection_);
- EXPECT_FALSE(success);
- const auto* alternative_path =
- QuicConnectionPeer::GetAlternativePath(&connection_);
- EXPECT_TRUE(alternative_path->client_connection_id.IsEmpty());
- EXPECT_TRUE(alternative_path->server_connection_id.IsEmpty());
- EXPECT_FALSE(alternative_path->stateless_reset_token.has_value());
-
- // Client will retire server connection ID on alternative_path.
- auto* retire_peer_issued_cid_alarm =
- connection_.GetRetirePeerIssuedConnectionIdAlarm();
- ASSERT_TRUE(retire_peer_issued_cid_alarm->IsSet());
- EXPECT_CALL(visitor_, SendRetireConnectionId(/*sequence_number=*/1u));
- retire_peer_issued_cid_alarm->Fire();
-}
-
-TEST_P(QuicConnectionTest,
- MigratePathDirectlyFailedDueToLackOfServerConnectionId) {
- if (!GetQuicReloadableFlag(
- quic_remove_connection_migration_connection_option)) {
- QuicConfig config;
- config.SetConnectionOptionsToSend({kRVCM});
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
- connection_.SetFromConfig(config);
- }
- if (!connection_.connection_migration_use_new_cid()) {
- return;
- }
- PathProbeTestInit(Perspective::IS_CLIENT,
- /*receive_new_server_connection_id=*/false);
- const QuicSocketAddress kSelfAddress1(QuicIpAddress::Any4(), 12345);
- ASSERT_NE(kSelfAddress1, connection_.self_address());
-
- TestPacketWriter new_writer(version(), &clock_, Perspective::IS_CLIENT);
- ASSERT_FALSE(connection_.MigratePath(kSelfAddress1,
- connection_.peer_address(), &new_writer,
- /*owns_writer=*/false));
-}
-
-TEST_P(QuicConnectionTest,
- MigratePathDirectlyFailedDueToLackOfClientConnectionIdTheSecondTime) {
- if (!GetQuicReloadableFlag(
- quic_remove_connection_migration_connection_option)) {
- QuicConfig config;
- config.SetConnectionOptionsToSend({kRVCM});
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
- connection_.SetFromConfig(config);
- }
- if (!connection_.connection_migration_use_new_cid()) {
- return;
- }
- PathProbeTestInit(Perspective::IS_CLIENT,
- /*receive_new_server_connection_id=*/false);
- SetClientConnectionId(TestConnectionId(1));
-
- // Make sure server connection ID is available for the 1st migration.
- QuicNewConnectionIdFrame frame1;
- frame1.connection_id = TestConnectionId(2);
- frame1.sequence_number = 1u;
- frame1.retire_prior_to = 0u;
- frame1.stateless_reset_token =
- QuicUtils::GenerateStatelessResetToken(frame1.connection_id);
- connection_.OnNewConnectionIdFrame(frame1);
-
- // Client will issue a new client connection ID to server.
- QuicConnectionId new_client_connection_id;
- EXPECT_CALL(visitor_, SendNewConnectionId(_))
- .WillOnce(Invoke([&](const QuicNewConnectionIdFrame& frame) {
- new_client_connection_id = frame.connection_id;
- }));
-
- // 1st migration is successful.
- const QuicSocketAddress kSelfAddress1(QuicIpAddress::Any4(), 12345);
- ASSERT_NE(kSelfAddress1, connection_.self_address());
- TestPacketWriter new_writer(version(), &clock_, Perspective::IS_CLIENT);
- ASSERT_TRUE(connection_.MigratePath(kSelfAddress1, connection_.peer_address(),
- &new_writer,
- /*owns_writer=*/false));
- QuicConnectionPeer::RetirePeerIssuedConnectionIdsNoLongerOnPath(&connection_);
- const auto* default_path = QuicConnectionPeer::GetDefaultPath(&connection_);
- EXPECT_EQ(default_path->client_connection_id, new_client_connection_id);
- EXPECT_EQ(default_path->server_connection_id, frame1.connection_id);
- EXPECT_EQ(default_path->stateless_reset_token, frame1.stateless_reset_token);
-
- // Client will retire server connection ID on old default_path.
- auto* retire_peer_issued_cid_alarm =
- connection_.GetRetirePeerIssuedConnectionIdAlarm();
- ASSERT_TRUE(retire_peer_issued_cid_alarm->IsSet());
- EXPECT_CALL(visitor_, SendRetireConnectionId(/*sequence_number=*/0u));
- retire_peer_issued_cid_alarm->Fire();
-
- // Another server connection ID is available to client.
- QuicNewConnectionIdFrame frame2;
- frame2.connection_id = TestConnectionId(4);
- frame2.sequence_number = 2u;
- frame2.retire_prior_to = 1u;
- frame2.stateless_reset_token =
- QuicUtils::GenerateStatelessResetToken(frame2.connection_id);
- connection_.OnNewConnectionIdFrame(frame2);
-
- // Since server does not retire any client connection ID yet, 2nd migration
- // would fail due to lack of client connection ID.
- const QuicSocketAddress kSelfAddress2(QuicIpAddress::Loopback4(),
- /*port=*/45678);
- auto new_writer2 = std::make_unique<TestPacketWriter>(version(), &clock_,
- Perspective::IS_CLIENT);
- ASSERT_FALSE(connection_.MigratePath(
- kSelfAddress2, connection_.peer_address(), new_writer2.release(),
- /*owns_writer=*/true));
-}
-
-TEST_P(QuicConnectionTest,
- CloseConnectionAfterReceiveNewConnectionIdFromPeerUsingEmptyCID) {
- if (!version().HasIetfQuicFrames()) {
- return;
- }
- set_perspective(Perspective::IS_SERVER);
- ASSERT_TRUE(connection_.client_connection_id().IsEmpty());
-
- EXPECT_CALL(visitor_, BeforeConnectionCloseSent());
- EXPECT_CALL(visitor_, OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF))
- .WillOnce(Invoke(this, &QuicConnectionTest::SaveConnectionCloseFrame));
- QuicNewConnectionIdFrame frame;
- frame.sequence_number = 1u;
- frame.connection_id = TestConnectionId(1);
- frame.stateless_reset_token =
- QuicUtils::GenerateStatelessResetToken(frame.connection_id);
- frame.retire_prior_to = 0u;
-
- EXPECT_FALSE(connection_.OnNewConnectionIdFrame(frame));
-
- EXPECT_FALSE(connection_.connected());
- EXPECT_THAT(saved_connection_close_frame_.quic_error_code,
- IsError(IETF_QUIC_PROTOCOL_VIOLATION));
-}
-
-TEST_P(QuicConnectionTest, NewConnectionIdFrameResultsInError) {
- if (!version().HasIetfQuicFrames()) {
- return;
- }
- connection_.CreateConnectionIdManager();
- ASSERT_FALSE(connection_.connection_id().IsEmpty());
-
- EXPECT_CALL(visitor_, OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF))
- .WillOnce(Invoke(this, &QuicConnectionTest::SaveConnectionCloseFrame));
- QuicNewConnectionIdFrame frame;
- frame.sequence_number = 1u;
- frame.connection_id = connection_id_; // Reuses connection ID casuing error.
- frame.stateless_reset_token =
- QuicUtils::GenerateStatelessResetToken(frame.connection_id);
- frame.retire_prior_to = 0u;
-
- EXPECT_FALSE(connection_.OnNewConnectionIdFrame(frame));
-
- EXPECT_FALSE(connection_.connected());
- EXPECT_THAT(saved_connection_close_frame_.quic_error_code,
- IsError(IETF_QUIC_PROTOCOL_VIOLATION));
-}
-
-TEST_P(QuicConnectionTest,
- ClientRetirePeerIssuedConnectionIdTriggeredByNewConnectionIdFrame) {
- if (!version().HasIetfQuicFrames()) {
- return;
- }
- connection_.CreateConnectionIdManager();
-
- QuicNewConnectionIdFrame frame;
- frame.sequence_number = 1u;
- frame.connection_id = TestConnectionId(1);
- frame.stateless_reset_token =
- QuicUtils::GenerateStatelessResetToken(frame.connection_id);
- frame.retire_prior_to = 0u;
-
- EXPECT_TRUE(connection_.OnNewConnectionIdFrame(frame));
- auto* retire_peer_issued_cid_alarm =
- connection_.GetRetirePeerIssuedConnectionIdAlarm();
- ASSERT_FALSE(retire_peer_issued_cid_alarm->IsSet());
-
- frame.sequence_number = 2u;
- frame.connection_id = TestConnectionId(2);
- frame.stateless_reset_token =
- QuicUtils::GenerateStatelessResetToken(frame.connection_id);
- frame.retire_prior_to = 1u; // CID associated with #1 will be retired.
-
- EXPECT_TRUE(connection_.OnNewConnectionIdFrame(frame));
- ASSERT_TRUE(retire_peer_issued_cid_alarm->IsSet());
- EXPECT_EQ(connection_.connection_id(), connection_id_);
-
- EXPECT_CALL(visitor_, SendRetireConnectionId(/*sequence_number=*/0u));
- retire_peer_issued_cid_alarm->Fire();
- EXPECT_EQ(connection_.connection_id(), TestConnectionId(2));
- EXPECT_EQ(connection_.packet_creator().GetDestinationConnectionId(),
- TestConnectionId(2));
-}
-
-TEST_P(QuicConnectionTest,
- ServerRetirePeerIssuedConnectionIdTriggeredByNewConnectionIdFrame) {
- if (!version().HasIetfQuicFrames()) {
- return;
- }
- set_perspective(Perspective::IS_SERVER);
- SetClientConnectionId(TestConnectionId(0));
-
- QuicNewConnectionIdFrame frame;
- frame.sequence_number = 1u;
- frame.connection_id = TestConnectionId(1);
- frame.stateless_reset_token =
- QuicUtils::GenerateStatelessResetToken(frame.connection_id);
- frame.retire_prior_to = 0u;
-
- EXPECT_TRUE(connection_.OnNewConnectionIdFrame(frame));
- auto* retire_peer_issued_cid_alarm =
- connection_.GetRetirePeerIssuedConnectionIdAlarm();
- ASSERT_FALSE(retire_peer_issued_cid_alarm->IsSet());
-
- frame.sequence_number = 2u;
- frame.connection_id = TestConnectionId(2);
- frame.stateless_reset_token =
- QuicUtils::GenerateStatelessResetToken(frame.connection_id);
- frame.retire_prior_to = 1u; // CID associated with #1 will be retired.
-
- EXPECT_TRUE(connection_.OnNewConnectionIdFrame(frame));
- ASSERT_TRUE(retire_peer_issued_cid_alarm->IsSet());
- EXPECT_EQ(connection_.client_connection_id(), TestConnectionId(0));
-
- EXPECT_CALL(visitor_, SendRetireConnectionId(/*sequence_number=*/0u));
- retire_peer_issued_cid_alarm->Fire();
- EXPECT_EQ(connection_.client_connection_id(), TestConnectionId(2));
- EXPECT_EQ(connection_.packet_creator().GetDestinationConnectionId(),
- TestConnectionId(2));
-}
-
-TEST_P(
- QuicConnectionTest,
- ReplacePeerIssuedConnectionIdOnBothPathsTriggeredByNewConnectionIdFrame) {
- if (!version().HasIetfQuicFrames() || !connection_.use_path_validator() ||
- !connection_.count_bytes_on_alternative_path_separately()) {
- return;
- }
- PathProbeTestInit(Perspective::IS_SERVER);
- SetClientConnectionId(TestConnectionId(0));
-
- // Populate alternative_path_ with probing packet.
- std::unique_ptr<SerializedPacket> probing_packet = ConstructProbingPacket();
-
- std::unique_ptr<QuicReceivedPacket> received(ConstructReceivedPacket(
- QuicEncryptedPacket(probing_packet->encrypted_buffer,
- probing_packet->encrypted_length),
- clock_.Now()));
- QuicIpAddress new_host;
- new_host.FromString("1.1.1.1");
- ProcessReceivedPacket(kSelfAddress,
- QuicSocketAddress(new_host, /*port=*/23456), *received);
-
- EXPECT_EQ(
- TestConnectionId(0),
- QuicConnectionPeer::GetClientConnectionIdOnAlternativePath(&connection_));
-
- QuicNewConnectionIdFrame frame;
- frame.sequence_number = 1u;
- frame.connection_id = TestConnectionId(1);
- frame.stateless_reset_token =
- QuicUtils::GenerateStatelessResetToken(frame.connection_id);
- frame.retire_prior_to = 0u;
-
- EXPECT_TRUE(connection_.OnNewConnectionIdFrame(frame));
- auto* retire_peer_issued_cid_alarm =
- connection_.GetRetirePeerIssuedConnectionIdAlarm();
- ASSERT_FALSE(retire_peer_issued_cid_alarm->IsSet());
-
- frame.sequence_number = 2u;
- frame.connection_id = TestConnectionId(2);
- frame.stateless_reset_token =
- QuicUtils::GenerateStatelessResetToken(frame.connection_id);
- frame.retire_prior_to = 1u; // CID associated with #1 will be retired.
-
- EXPECT_TRUE(connection_.OnNewConnectionIdFrame(frame));
- ASSERT_TRUE(retire_peer_issued_cid_alarm->IsSet());
- EXPECT_EQ(connection_.client_connection_id(), TestConnectionId(0));
-
- EXPECT_CALL(visitor_, SendRetireConnectionId(/*sequence_number=*/0u));
- retire_peer_issued_cid_alarm->Fire();
- EXPECT_EQ(connection_.client_connection_id(), TestConnectionId(2));
- EXPECT_EQ(connection_.packet_creator().GetDestinationConnectionId(),
- TestConnectionId(2));
- // Clean up alternative path connection ID.
- EXPECT_EQ(
- TestConnectionId(2),
- QuicConnectionPeer::GetClientConnectionIdOnAlternativePath(&connection_));
-}
-
-TEST_P(QuicConnectionTest,
- CloseConnectionAfterReceiveRetireConnectionIdWhenNoCIDIssued) {
- if (!version().HasIetfQuicFrames() ||
- !connection_.connection_migration_use_new_cid()) {
- return;
- }
- set_perspective(Perspective::IS_SERVER);
-
- EXPECT_CALL(visitor_, BeforeConnectionCloseSent());
- EXPECT_CALL(visitor_, OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF))
- .WillOnce(Invoke(this, &QuicConnectionTest::SaveConnectionCloseFrame));
- QuicRetireConnectionIdFrame frame;
- frame.sequence_number = 1u;
-
- EXPECT_FALSE(connection_.OnRetireConnectionIdFrame(frame));
-
- EXPECT_FALSE(connection_.connected());
- EXPECT_THAT(saved_connection_close_frame_.quic_error_code,
- IsError(IETF_QUIC_PROTOCOL_VIOLATION));
-}
-
-TEST_P(QuicConnectionTest, RetireConnectionIdFrameResultsInError) {
- if (!version().HasIetfQuicFrames() ||
- !connection_.connection_migration_use_new_cid()) {
- return;
- }
- set_perspective(Perspective::IS_SERVER);
- connection_.CreateConnectionIdManager();
-
- EXPECT_CALL(visitor_, OnServerConnectionIdIssued(_));
- EXPECT_CALL(visitor_, SendNewConnectionId(_));
- connection_.MaybeSendConnectionIdToClient();
-
- EXPECT_CALL(visitor_, BeforeConnectionCloseSent());
- EXPECT_CALL(visitor_, OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF))
- .WillOnce(Invoke(this, &QuicConnectionTest::SaveConnectionCloseFrame));
- QuicRetireConnectionIdFrame frame;
- frame.sequence_number = 2u; // The corresponding ID is never issued.
-
- EXPECT_FALSE(connection_.OnRetireConnectionIdFrame(frame));
-
- EXPECT_FALSE(connection_.connected());
- EXPECT_THAT(saved_connection_close_frame_.quic_error_code,
- IsError(IETF_QUIC_PROTOCOL_VIOLATION));
-}
-
-TEST_P(QuicConnectionTest,
- ServerRetireSelfIssuedConnectionIdWithoutSendingNewConnectionIdBefore) {
- if (!version().HasIetfQuicFrames()) {
- return;
- }
- set_perspective(Perspective::IS_SERVER);
- connection_.CreateConnectionIdManager();
-
- auto* retire_self_issued_cid_alarm =
- connection_.GetRetireSelfIssuedConnectionIdAlarm();
- ASSERT_FALSE(retire_self_issued_cid_alarm->IsSet());
-
- QuicConnectionId cid0 = connection_id_;
- QuicRetireConnectionIdFrame frame;
- frame.sequence_number = 0u;
- if (connection_.connection_migration_use_new_cid()) {
- EXPECT_CALL(visitor_, OnServerConnectionIdIssued(_)).Times(2);
- EXPECT_CALL(visitor_, SendNewConnectionId(_)).Times(2);
- }
- EXPECT_TRUE(connection_.OnRetireConnectionIdFrame(frame));
-}
-
-TEST_P(QuicConnectionTest, ServerRetireSelfIssuedConnectionId) {
- if (!GetQuicReloadableFlag(
- quic_remove_connection_migration_connection_option)) {
- QuicConfig config;
- config.SetConnectionOptionsToSend({kRVCM});
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
- connection_.SetFromConfig(config);
- }
- if (!connection_.connection_migration_use_new_cid()) {
- return;
- }
- set_perspective(Perspective::IS_SERVER);
- connection_.CreateConnectionIdManager();
- QuicConnectionId recorded_cid;
- auto cid_recorder = [&recorded_cid](const QuicConnectionId& cid) {
- recorded_cid = cid;
- };
- QuicConnectionId cid0 = connection_id_;
- QuicConnectionId cid1;
- QuicConnectionId cid2;
- EXPECT_EQ(connection_.connection_id(), cid0);
- EXPECT_EQ(connection_.GetOneActiveServerConnectionId(), cid0);
-
- connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
- EXPECT_CALL(visitor_, OnServerConnectionIdIssued(_))
- .WillOnce(Invoke(cid_recorder));
- EXPECT_CALL(visitor_, SendNewConnectionId(_));
- connection_.MaybeSendConnectionIdToClient();
- cid1 = recorded_cid;
-
- auto* retire_self_issued_cid_alarm =
- connection_.GetRetireSelfIssuedConnectionIdAlarm();
- ASSERT_FALSE(retire_self_issued_cid_alarm->IsSet());
-
- // Generate three packets with different connection IDs that will arrive out
- // of order (2, 1, 3) later.
- char buffers[3][kMaxOutgoingPacketSize];
- // Destination connection ID of packet1 is cid0.
- auto packet1 =
- ConstructPacket({QuicFrame(QuicPingFrame())}, ENCRYPTION_FORWARD_SECURE,
- buffers[0], kMaxOutgoingPacketSize);
- peer_creator_.SetServerConnectionId(cid1);
- auto retire_cid_frame = std::make_unique<QuicRetireConnectionIdFrame>();
- retire_cid_frame->sequence_number = 0u;
- // Destination connection ID of packet2 is cid1.
- auto packet2 = ConstructPacket({QuicFrame(retire_cid_frame.release())},
- ENCRYPTION_FORWARD_SECURE, buffers[1],
- kMaxOutgoingPacketSize);
- // Destination connection ID of packet3 is cid1.
- auto packet3 =
- ConstructPacket({QuicFrame(QuicPingFrame())}, ENCRYPTION_FORWARD_SECURE,
- buffers[2], kMaxOutgoingPacketSize);
-
- // Packet2 with RetireConnectionId frame trigers sending NewConnectionId
- // immediately.
- EXPECT_CALL(visitor_, OnServerConnectionIdIssued(_))
- .WillOnce(Invoke(cid_recorder));
- EXPECT_CALL(visitor_, SendNewConnectionId(_));
- peer_creator_.SetServerConnectionId(cid1);
- connection_.ProcessUdpPacket(kSelfAddress, kPeerAddress, *packet2);
- cid2 = recorded_cid;
- // cid0 is not retired immediately.
- EXPECT_THAT(connection_.GetActiveServerConnectionIds(),
- ElementsAre(cid0, cid1, cid2));
- ASSERT_TRUE(retire_self_issued_cid_alarm->IsSet());
- EXPECT_EQ(connection_.connection_id(), cid1);
- EXPECT_TRUE(connection_.GetOneActiveServerConnectionId() == cid0 ||
- connection_.GetOneActiveServerConnectionId() == cid1 ||
- connection_.GetOneActiveServerConnectionId() == cid2);
-
- // Packet1 updates the connection ID on the default path but not the active
- // connection ID.
- connection_.ProcessUdpPacket(kSelfAddress, kPeerAddress, *packet1);
- EXPECT_EQ(connection_.connection_id(), cid0);
- EXPECT_TRUE(connection_.GetOneActiveServerConnectionId() == cid0 ||
- connection_.GetOneActiveServerConnectionId() == cid1 ||
- connection_.GetOneActiveServerConnectionId() == cid2);
-
- // cid0 is retired when the retire CID alarm fires.
- EXPECT_CALL(visitor_, OnServerConnectionIdRetired(cid0));
- retire_self_issued_cid_alarm->Fire();
- EXPECT_THAT(connection_.GetActiveServerConnectionIds(),
- ElementsAre(cid1, cid2));
- EXPECT_TRUE(connection_.GetOneActiveServerConnectionId() == cid1 ||
- connection_.GetOneActiveServerConnectionId() == cid2);
-
- // Packet3 updates the connection ID on the default path.
- connection_.ProcessUdpPacket(kSelfAddress, kPeerAddress, *packet3);
- EXPECT_EQ(connection_.connection_id(), cid1);
- EXPECT_TRUE(connection_.GetOneActiveServerConnectionId() == cid1 ||
- connection_.GetOneActiveServerConnectionId() == cid2);
-}
-
-TEST_P(QuicConnectionTest, PatchMissingClientConnectionIdOntoAlternativePath) {
- if (!version().HasIetfQuicFrames()) {
- return;
- }
- set_perspective(Perspective::IS_SERVER);
- connection_.CreateConnectionIdManager();
- connection_.set_client_connection_id(TestConnectionId(1));
-
- // Set up the state after path probing.
- const auto* default_path = QuicConnectionPeer::GetDefaultPath(&connection_);
- auto* alternative_path = QuicConnectionPeer::GetAlternativePath(&connection_);
- QuicIpAddress new_host;
- new_host.FromString("12.12.12.12");
- alternative_path->self_address = default_path->self_address;
- alternative_path->peer_address = QuicSocketAddress(new_host, 12345);
- alternative_path->server_connection_id = TestConnectionId(3);
- ASSERT_TRUE(alternative_path->client_connection_id.IsEmpty());
- ASSERT_FALSE(alternative_path->stateless_reset_token.has_value());
-
- QuicNewConnectionIdFrame frame;
- frame.sequence_number = 1u;
- frame.connection_id = TestConnectionId(5);
- frame.stateless_reset_token =
- QuicUtils::GenerateStatelessResetToken(frame.connection_id);
- frame.retire_prior_to = 0u;
- // New ID is patched onto the alternative path when the needed
- // NEW_CONNECTION_ID frame is received after PATH_CHALLENGE frame.
- connection_.OnNewConnectionIdFrame(frame);
-
- ASSERT_EQ(alternative_path->client_connection_id, frame.connection_id);
- ASSERT_EQ(alternative_path->stateless_reset_token,
- frame.stateless_reset_token);
-}
-
-TEST_P(QuicConnectionTest, PatchMissingClientConnectionIdOntoDefaultPath) {
- if (!version().HasIetfQuicFrames()) {
- return;
- }
- set_perspective(Perspective::IS_SERVER);
- connection_.CreateConnectionIdManager();
- connection_.set_client_connection_id(TestConnectionId(1));
-
- // Set up the state after peer migration without probing.
- auto* default_path = QuicConnectionPeer::GetDefaultPath(&connection_);
- auto* alternative_path = QuicConnectionPeer::GetAlternativePath(&connection_);
- auto* packet_creator = QuicConnectionPeer::GetPacketCreator(&connection_);
- *alternative_path = std::move(*default_path);
- QuicIpAddress new_host;
- new_host.FromString("12.12.12.12");
- default_path->self_address = default_path->self_address;
- default_path->peer_address = QuicSocketAddress(new_host, 12345);
- default_path->server_connection_id = TestConnectionId(3);
- packet_creator->SetDefaultPeerAddress(default_path->peer_address);
- packet_creator->SetServerConnectionId(default_path->server_connection_id);
- packet_creator->SetClientConnectionId(default_path->client_connection_id);
-
- ASSERT_FALSE(default_path->validated);
- ASSERT_TRUE(default_path->client_connection_id.IsEmpty());
- ASSERT_FALSE(default_path->stateless_reset_token.has_value());
-
- QuicNewConnectionIdFrame frame;
- frame.sequence_number = 1u;
- frame.connection_id = TestConnectionId(5);
- frame.stateless_reset_token =
- QuicUtils::GenerateStatelessResetToken(frame.connection_id);
- frame.retire_prior_to = 0u;
- // New ID is patched onto the default path when the needed
- // NEW_CONNECTION_ID frame is received after PATH_CHALLENGE frame.
- connection_.OnNewConnectionIdFrame(frame);
-
- ASSERT_EQ(default_path->client_connection_id, frame.connection_id);
- ASSERT_EQ(default_path->stateless_reset_token, frame.stateless_reset_token);
- ASSERT_EQ(packet_creator->GetDestinationConnectionId(), frame.connection_id);
-}
-
-TEST_P(QuicConnectionTest, ShouldGeneratePacketBlockedByMissingConnectionId) {
- if (!version().HasIetfQuicFrames()) {
- return;
- }
- set_perspective(Perspective::IS_SERVER);
- connection_.set_client_connection_id(TestConnectionId(1));
- connection_.CreateConnectionIdManager();
- if (version().SupportsAntiAmplificationLimit()) {
- QuicConnectionPeer::SetAddressValidated(&connection_);
- }
-
- ASSERT_TRUE(
- connection_.ShouldGeneratePacket(NO_RETRANSMITTABLE_DATA, NOT_HANDSHAKE));
-
- QuicPacketCreator* packet_creator =
- QuicConnectionPeer::GetPacketCreator(&connection_);
- QuicIpAddress peer_host1;
- peer_host1.FromString("12.12.12.12");
- QuicSocketAddress peer_address1(peer_host1, 1235);
-
- {
- // No connection ID is available as context is created without any.
- QuicPacketCreator::ScopedPeerAddressContext context(
- packet_creator, peer_address1, EmptyQuicConnectionId(),
- EmptyQuicConnectionId(),
- /*update_connection_id=*/true);
- ASSERT_FALSE(connection_.ShouldGeneratePacket(NO_RETRANSMITTABLE_DATA,
- NOT_HANDSHAKE));
- }
- ASSERT_TRUE(
- connection_.ShouldGeneratePacket(NO_RETRANSMITTABLE_DATA, NOT_HANDSHAKE));
-}
-
-// Regression test for b/182571515
-TEST_P(QuicConnectionTest, LostDataThenGetAcknowledged) {
- set_perspective(Perspective::IS_SERVER);
- if (!connection_.validate_client_address()) {
- return;
- }
-
- QuicPacketCreatorPeer::SetSendVersionInPacket(creator_, false);
- if (version().SupportsAntiAmplificationLimit()) {
- QuicConnectionPeer::SetAddressValidated(&connection_);
- }
- connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
- // Discard INITIAL key.
- connection_.RemoveEncrypter(ENCRYPTION_INITIAL);
- connection_.NeuterUnencryptedPackets();
- EXPECT_CALL(visitor_, GetHandshakeState())
- .WillRepeatedly(Return(HANDSHAKE_CONFIRMED));
-
- QuicPacketNumber last_packet;
- // Send packets 1 to 4.
- SendStreamDataToPeer(3, "foo", 0, NO_FIN, &last_packet); // Packet 1
- SendStreamDataToPeer(3, "foo", 3, NO_FIN, &last_packet); // Packet 2
- SendStreamDataToPeer(3, "foo", 6, NO_FIN, &last_packet); // Packet 3
- SendStreamDataToPeer(3, "foo", 9, NO_FIN, &last_packet); // Packet 4
-
- // Process a PING packet to set peer address.
- ProcessFramePacket(QuicFrame(QuicPingFrame()));
-
- // Process a packet containing a STREAM_FRAME and an ACK with changed peer
- // address.
- QuicFrames frames;
- frames.push_back(QuicFrame(frame1_));
- 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());
-}
-
-TEST_P(QuicConnectionTest, PtoSendStreamData) {
- if (!connection_.SupportsMultiplePacketNumberSpaces()) {
- return;
- }
- set_perspective(Perspective::IS_SERVER);
- if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
- EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
- }
- EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber());
- use_tagging_decrypter();
- ProcessCryptoPacketAtLevel(1, ENCRYPTION_INITIAL);
- EXPECT_TRUE(connection_.HasPendingAcks());
-
- connection_.SetEncrypter(ENCRYPTION_INITIAL,
- std::make_unique<TaggingEncrypter>(0x01));
- connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
- // Send INITIAL 1.
- connection_.SendCryptoDataWithString("foo", 0, ENCRYPTION_INITIAL);
-
- connection_.SetEncrypter(ENCRYPTION_HANDSHAKE,
- std::make_unique<TaggingEncrypter>(0x02));
- connection_.SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE);
- SetDecrypter(ENCRYPTION_HANDSHAKE,
- std::make_unique<StrictTaggingDecrypter>(0x02));
- // Send HANDSHAKE packets.
- EXPECT_CALL(visitor_, OnHandshakePacketSent()).Times(1);
- connection_.SendCryptoDataWithString("foo", 0, ENCRYPTION_HANDSHAKE);
-
- connection_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
- std::make_unique<TaggingEncrypter>(0x03));
- connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
-
- // Send half RTT packet with congestion control blocked.
- EXPECT_CALL(*send_algorithm_, CanSend(_)).WillRepeatedly(Return(false));
- connection_.SendStreamDataWithString(2, std::string(1500, 'a'), 0, NO_FIN);
-
- ASSERT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
- connection_.GetRetransmissionAlarm()->Fire();
- // Verify INITIAL and HANDSHAKE get retransmitted.
- EXPECT_EQ(0x02020202u, writer_->final_bytes_of_last_packet());
-}
-
-TEST_P(QuicConnectionTest, SendingZeroRttPacketsDoesNotPostponePTO) {
- if (!connection_.SupportsMultiplePacketNumberSpaces()) {
- return;
- }
- use_tagging_decrypter();
- connection_.SetEncrypter(ENCRYPTION_INITIAL,
- std::make_unique<TaggingEncrypter>(0x01));
- connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
- // Send CHLO.
- connection_.SendCryptoStreamData();
- ASSERT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
- // Install 0-RTT keys.
- connection_.SetEncrypter(ENCRYPTION_ZERO_RTT,
- std::make_unique<TaggingEncrypter>(0x02));
- connection_.SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
-
- // CHLO gets acknowledged after 10ms.
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
- QuicAckFrame frame1 = InitAckFrame(1);
- EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _));
- ProcessFramePacketAtLevel(1, QuicFrame(&frame1), ENCRYPTION_INITIAL);
- // Verify PTO is still armed since address validation is not finished yet.
- ASSERT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
- QuicTime pto_deadline = connection_.GetRetransmissionAlarm()->deadline();
-
- // Send 0-RTT packet.
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
- connection_.SetEncrypter(ENCRYPTION_ZERO_RTT,
- std::make_unique<TaggingEncrypter>(0x02));
- connection_.SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
- connection_.SendStreamDataWithString(2, "foo", 0, NO_FIN);
- ASSERT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
- // PTO deadline should be unchanged.
- EXPECT_EQ(pto_deadline, connection_.GetRetransmissionAlarm()->deadline());
-}
-
-TEST_P(QuicConnectionTest, QueueingUndecryptablePacketsDoesntPostponePTO) {
- if (!connection_.SupportsMultiplePacketNumberSpaces()) {
- return;
- }
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
- QuicConfig config;
- config.set_max_undecryptable_packets(3);
- connection_.SetFromConfig(config);
- use_tagging_decrypter();
- connection_.SetEncrypter(ENCRYPTION_INITIAL,
- std::make_unique<TaggingEncrypter>(0x01));
- connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
- connection_.RemoveDecrypter(ENCRYPTION_FORWARD_SECURE);
- // Send CHLO.
- connection_.SendCryptoStreamData();
-
- // Send 0-RTT packet.
- connection_.SetEncrypter(ENCRYPTION_ZERO_RTT,
- std::make_unique<TaggingEncrypter>(0x02));
- connection_.SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
- connection_.SendStreamDataWithString(2, "foo", 0, NO_FIN);
-
- // CHLO gets acknowledged after 10ms.
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
- QuicAckFrame frame1 = InitAckFrame(1);
- EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _));
- ProcessFramePacketAtLevel(1, QuicFrame(&frame1), ENCRYPTION_INITIAL);
- // Verify PTO is still armed since address validation is not finished yet.
- ASSERT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
- QuicTime pto_deadline = connection_.GetRetransmissionAlarm()->deadline();
-
- // Receive an undecryptable packets.
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
- peer_framer_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
- std::make_unique<TaggingEncrypter>(0xFF));
- ProcessDataPacketAtLevel(3, !kHasStopWaiting, ENCRYPTION_FORWARD_SECURE);
- // Verify PTO deadline is sooner.
- EXPECT_GT(pto_deadline, connection_.GetRetransmissionAlarm()->deadline());
- pto_deadline = connection_.GetRetransmissionAlarm()->deadline();
-
- // PTO fires.
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
- clock_.AdvanceTime(pto_deadline - clock_.ApproximateNow());
- connection_.GetRetransmissionAlarm()->Fire();
- // Verify PTO is still armed since address validation is not finished yet.
- ASSERT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
- pto_deadline = connection_.GetRetransmissionAlarm()->deadline();
-
- // Verify PTO deadline does not change.
- ProcessDataPacketAtLevel(4, !kHasStopWaiting, ENCRYPTION_FORWARD_SECURE);
- EXPECT_EQ(pto_deadline, connection_.GetRetransmissionAlarm()->deadline());
-}
-
-TEST_P(QuicConnectionTest, QueueUndecryptableHandshakePackets) {
- if (!connection_.SupportsMultiplePacketNumberSpaces()) {
- return;
- }
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
- QuicConfig config;
- config.set_max_undecryptable_packets(3);
- connection_.SetFromConfig(config);
- use_tagging_decrypter();
- connection_.SetEncrypter(ENCRYPTION_INITIAL,
- std::make_unique<TaggingEncrypter>(0x01));
- connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
- connection_.RemoveDecrypter(ENCRYPTION_HANDSHAKE);
- // Send CHLO.
- connection_.SendCryptoStreamData();
-
- // Send 0-RTT packet.
- connection_.SetEncrypter(ENCRYPTION_ZERO_RTT,
- std::make_unique<TaggingEncrypter>(0x02));
- connection_.SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
- connection_.SendStreamDataWithString(2, "foo", 0, NO_FIN);
- EXPECT_EQ(0u, QuicConnectionPeer::NumUndecryptablePackets(&connection_));
-
- // Receive an undecryptable handshake packet.
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
- peer_framer_.SetEncrypter(ENCRYPTION_HANDSHAKE,
- std::make_unique<TaggingEncrypter>(0xFF));
- ProcessDataPacketAtLevel(3, !kHasStopWaiting, ENCRYPTION_HANDSHAKE);
- // Verify this handshake packet gets queued.
- EXPECT_EQ(1u, QuicConnectionPeer::NumUndecryptablePackets(&connection_));
-}
-
-TEST_P(QuicConnectionTest, PingNotSentAt0RTTLevelWhenInitialAvailable) {
- if (!connection_.SupportsMultiplePacketNumberSpaces()) {
- return;
- }
- use_tagging_decrypter();
- connection_.SetEncrypter(ENCRYPTION_INITIAL,
- std::make_unique<TaggingEncrypter>(0x01));
- connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
- // Send CHLO.
- connection_.SendCryptoStreamData();
- // Send 0-RTT packet.
- connection_.SetEncrypter(ENCRYPTION_ZERO_RTT,
- std::make_unique<TaggingEncrypter>(0x02));
- connection_.SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
- connection_.SendStreamDataWithString(2, "foo", 0, NO_FIN);
-
- // CHLO gets acknowledged after 10ms.
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
- QuicAckFrame frame1 = InitAckFrame(1);
- EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _));
- ProcessFramePacketAtLevel(1, QuicFrame(&frame1), ENCRYPTION_INITIAL);
- // Verify PTO is still armed since address validation is not finished yet.
- ASSERT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
- QuicTime pto_deadline = connection_.GetRetransmissionAlarm()->deadline();
-
- // PTO fires.
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
- clock_.AdvanceTime(pto_deadline - clock_.ApproximateNow());
- connection_.GetRetransmissionAlarm()->Fire();
- // Verify the PING gets sent in ENCRYPTION_INITIAL.
- EXPECT_EQ(0x01010101u, writer_->final_bytes_of_last_packet());
-}
-
-TEST_P(QuicConnectionTest, AckElicitingFrames) {
- if (!GetQuicReloadableFlag(
- quic_remove_connection_migration_connection_option)) {
- QuicConfig config;
- config.SetConnectionOptionsToSend({kRVCM});
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
- connection_.SetFromConfig(config);
- }
- if (!version().HasIetfQuicFrames() ||
- !connection_.connection_migration_use_new_cid()) {
- return;
- }
- EXPECT_CALL(visitor_, SendNewConnectionId(_)).Times(2);
- EXPECT_CALL(visitor_, OnRstStream(_));
- EXPECT_CALL(visitor_, OnWindowUpdateFrame(_));
- EXPECT_CALL(visitor_, OnBlockedFrame(_));
- EXPECT_CALL(visitor_, OnHandshakeDoneReceived());
- EXPECT_CALL(visitor_, OnStreamFrame(_));
- EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _));
- EXPECT_CALL(visitor_, OnMaxStreamsFrame(_));
- EXPECT_CALL(visitor_, OnStreamsBlockedFrame(_));
- EXPECT_CALL(visitor_, OnStopSendingFrame(_));
- EXPECT_CALL(visitor_, OnMessageReceived(""));
- EXPECT_CALL(visitor_, OnNewTokenReceived(""));
-
- SetClientConnectionId(TestConnectionId(12));
- connection_.CreateConnectionIdManager();
- QuicConnectionPeer::GetSelfIssuedConnectionIdManager(&connection_)
- ->MaybeSendNewConnectionIds();
- connection_.set_can_receive_ack_frequency_frame();
-
- QuicAckFrame ack_frame = InitAckFrame(1);
- QuicRstStreamFrame rst_stream_frame;
- QuicWindowUpdateFrame window_update_frame;
- QuicPathChallengeFrame path_challenge_frame;
- QuicNewConnectionIdFrame new_connection_id_frame;
- QuicRetireConnectionIdFrame retire_connection_id_frame;
- retire_connection_id_frame.sequence_number = 1u;
- QuicStopSendingFrame stop_sending_frame;
- QuicPathResponseFrame path_response_frame;
- QuicMessageFrame message_frame;
- QuicNewTokenFrame new_token_frame;
- QuicAckFrequencyFrame ack_frequency_frame;
- QuicBlockedFrame blocked_frame;
- size_t packet_number = 1;
-
- connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
-
- for (uint8_t i = 0; i < NUM_FRAME_TYPES; ++i) {
- QuicFrameType frame_type = static_cast<QuicFrameType>(i);
- bool skipped = false;
- QuicFrame frame;
- QuicFrames frames;
- // Add some padding to fullfill the min size requirement of header
- // protection.
- frames.push_back(QuicFrame(QuicPaddingFrame(10)));
- switch (frame_type) {
- case PADDING_FRAME:
- frame = QuicFrame(QuicPaddingFrame(10));
- break;
- case MTU_DISCOVERY_FRAME:
- frame = QuicFrame(QuicMtuDiscoveryFrame());
- break;
- case PING_FRAME:
- frame = QuicFrame(QuicPingFrame());
- break;
- case MAX_STREAMS_FRAME:
- frame = QuicFrame(QuicMaxStreamsFrame());
- break;
- case STOP_WAITING_FRAME:
- // Not supported.
- skipped = true;
- break;
- case STREAMS_BLOCKED_FRAME:
- frame = QuicFrame(QuicStreamsBlockedFrame());
- break;
- case STREAM_FRAME:
- frame = QuicFrame(QuicStreamFrame());
- break;
- case HANDSHAKE_DONE_FRAME:
- frame = QuicFrame(QuicHandshakeDoneFrame());
- break;
- case ACK_FRAME:
- frame = QuicFrame(&ack_frame);
- break;
- case RST_STREAM_FRAME:
- frame = QuicFrame(&rst_stream_frame);
- break;
- case CONNECTION_CLOSE_FRAME:
- // Do not test connection close.
- skipped = true;
- break;
- case GOAWAY_FRAME:
- // Does not exist in IETF QUIC.
- skipped = true;
- break;
- case BLOCKED_FRAME:
- frame = QuicFrame(&blocked_frame);
- break;
- case WINDOW_UPDATE_FRAME:
- frame = QuicFrame(&window_update_frame);
- break;
- case PATH_CHALLENGE_FRAME:
- frame = QuicFrame(&path_challenge_frame);
- break;
- case STOP_SENDING_FRAME:
- frame = QuicFrame(&stop_sending_frame);
- break;
- case NEW_CONNECTION_ID_FRAME:
- frame = QuicFrame(&new_connection_id_frame);
- break;
- case RETIRE_CONNECTION_ID_FRAME:
- frame = QuicFrame(&retire_connection_id_frame);
- break;
- case PATH_RESPONSE_FRAME:
- frame = QuicFrame(&path_response_frame);
- break;
- case MESSAGE_FRAME:
- frame = QuicFrame(&message_frame);
- break;
- case CRYPTO_FRAME:
- // CRYPTO_FRAME is ack eliciting is covered by other tests.
- skipped = true;
- break;
- case NEW_TOKEN_FRAME:
- frame = QuicFrame(&new_token_frame);
- break;
- case ACK_FREQUENCY_FRAME:
- frame = QuicFrame(&ack_frequency_frame);
- break;
- case NUM_FRAME_TYPES:
- skipped = true;
- break;
- }
- if (skipped) {
- continue;
- }
- ASSERT_EQ(frame_type, frame.type);
- frames.push_back(frame);
- EXPECT_FALSE(connection_.HasPendingAcks());
- // Process frame.
- ProcessFramesPacketAtLevel(packet_number++, frames,
- ENCRYPTION_FORWARD_SECURE);
- if (QuicUtils::IsAckElicitingFrame(frame_type)) {
- ASSERT_TRUE(connection_.HasPendingAcks()) << frame;
- // Flush ACK.
- clock_.AdvanceTime(DefaultDelayedAckTime());
- connection_.GetAckAlarm()->Fire();
- }
- EXPECT_FALSE(connection_.HasPendingAcks());
- ASSERT_TRUE(connection_.connected());
- }
-}
-
-TEST_P(QuicConnectionTest, ReceivedChloAndAck) {
- if (!version().HasIetfQuicFrames()) {
- return;
- }
- set_perspective(Perspective::IS_SERVER);
- QuicFrames frames;
- QuicAckFrame ack_frame = InitAckFrame(1);
- frames.push_back(MakeCryptoFrame());
- frames.push_back(QuicFrame(&ack_frame));
-
- EXPECT_CALL(visitor_, OnCryptoFrame(_))
- .WillOnce(IgnoreResult(InvokeWithoutArgs(
- &connection_, &TestConnection::SendCryptoStreamData)));
- EXPECT_CALL(visitor_, BeforeConnectionCloseSent());
- EXPECT_CALL(visitor_, OnConnectionClosed(_, _));
- ProcessFramesPacketWithAddresses(frames, kSelfAddress, kPeerAddress,
- ENCRYPTION_INITIAL);
-}
-
-// Regression test for b/201643321.
-TEST_P(QuicConnectionTest, FailedToRetransmitShlo) {
- if (!version().HasIetfQuicFrames()) {
- return;
- }
- set_perspective(Perspective::IS_SERVER);
- EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
- EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber());
- use_tagging_decrypter();
- // Received INITIAL 1.
- ProcessCryptoPacketAtLevel(1, ENCRYPTION_INITIAL);
- EXPECT_TRUE(connection_.HasPendingAcks());
-
- peer_framer_.SetEncrypter(ENCRYPTION_ZERO_RTT,
- std::make_unique<TaggingEncrypter>(0x02));
-
- connection_.SetEncrypter(ENCRYPTION_INITIAL,
- std::make_unique<TaggingEncrypter>(0x01));
- connection_.SetEncrypter(ENCRYPTION_HANDSHAKE,
- std::make_unique<TaggingEncrypter>(0x03));
- SetDecrypter(ENCRYPTION_HANDSHAKE,
- std::make_unique<StrictTaggingDecrypter>(0x02));
- SetDecrypter(ENCRYPTION_ZERO_RTT,
- std::make_unique<StrictTaggingDecrypter>(0x02));
- connection_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
- std::make_unique<TaggingEncrypter>(0x04));
- // Received ENCRYPTION_ZERO_RTT 1.
- ProcessDataPacketAtLevel(1, !kHasStopWaiting, ENCRYPTION_ZERO_RTT);
- {
- QuicConnection::ScopedPacketFlusher flusher(&connection_);
- // Send INITIAL 1.
- connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
- connection_.SendCryptoDataWithString("foo", 0, ENCRYPTION_INITIAL);
- // Send HANDSHAKE 2.
- EXPECT_CALL(visitor_, OnHandshakePacketSent()).Times(1);
- connection_.SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE);
- connection_.SendCryptoDataWithString("foo", 0, ENCRYPTION_HANDSHAKE);
- connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
- // Send half RTT data to exhaust amplification credit.
- connection_.SendStreamDataWithString(0, std::string(100 * 1024, 'a'), 0,
- NO_FIN);
- }
- // Received INITIAL 2.
- ProcessCryptoPacketAtLevel(2, ENCRYPTION_INITIAL);
- ASSERT_TRUE(connection_.HasPendingAcks());
- // Verify ACK delay is 1ms.
- EXPECT_EQ(clock_.Now() + kAlarmGranularity,
- connection_.GetAckAlarm()->deadline());
- if (!GetQuicReloadableFlag(
- quic_donot_check_amplification_limit_with_pending_timer_credit)) {
- // ACK is not sent because of amplification limit throttled.
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
- } else {
- // ACK is not throttled by amplification limit, and SHLO is bundled. Also
- // HANDSHAKE packet gets coalesced.
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(2);
- }
- // ACK alarm fires.
- clock_.AdvanceTime(kAlarmGranularity);
- connection_.GetAckAlarm()->Fire();
- if (GetQuicReloadableFlag(
- quic_donot_check_amplification_limit_with_pending_timer_credit)) {
- // Verify HANDSHAKE packet is coalesced with INITIAL ACK + SHLO.
- EXPECT_EQ(0x03030303u, 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());
- EXPECT_EQ(1u, writer_->crypto_frames().size());
- // Process the coalesced HANDSHAKE packet.
- ASSERT_TRUE(writer_->coalesced_packet() != nullptr);
- auto packet = writer_->coalesced_packet()->Clone();
- writer_->framer()->ProcessPacket(*packet);
- EXPECT_EQ(0u, writer_->ack_frames().size());
- EXPECT_EQ(1u, writer_->crypto_frames().size());
- ASSERT_TRUE(writer_->coalesced_packet() == nullptr);
- }
-
- // Received INITIAL 3.
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AnyNumber());
- ProcessCryptoPacketAtLevel(3, ENCRYPTION_INITIAL);
- if (!GetQuicReloadableFlag(
- quic_donot_check_amplification_limit_with_pending_timer_credit)) {
- EXPECT_FALSE(connection_.HasPendingAcks());
- } else {
- EXPECT_TRUE(connection_.HasPendingAcks());
- }
-}
-
-} // namespace
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_constants.cc b/chromium/net/third_party/quiche/src/quic/core/quic_constants.cc
deleted file mode 100644
index 36ede3cef2c..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_constants.cc
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_constants.h"
-
-namespace quic {
-
-const char* const kFinalOffsetHeaderKey = ":final-offset";
-
-const char* const kEPIDGoogleFrontEnd = "GFE";
-const char* const kEPIDGoogleFrontEnd0 = "GFE0";
-
-QuicPacketNumber MaxRandomInitialPacketNumber() {
- static const QuicPacketNumber kMaxRandomInitialPacketNumber =
- QuicPacketNumber(0x7fffffff);
- return kMaxRandomInitialPacketNumber;
-}
-
-QuicPacketNumber FirstSendingPacketNumber() {
- static const QuicPacketNumber kFirstSendingPacketNumber = QuicPacketNumber(1);
- return kFirstSendingPacketNumber;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_constants.h b/chromium/net/third_party/quiche/src/quic/core/quic_constants.h
deleted file mode 100644
index c53459cf70d..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_constants.h
+++ /dev/null
@@ -1,310 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_CONSTANTS_H_
-#define QUICHE_QUIC_CORE_QUIC_CONSTANTS_H_
-
-#include <stddef.h>
-
-#include <cstdint>
-#include <limits>
-
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_export.h"
-
-// Definitions of constant values used throughout the QUIC code.
-
-namespace quic {
-
-// Simple time constants.
-const uint64_t kNumSecondsPerMinute = 60;
-const uint64_t kNumSecondsPerHour = kNumSecondsPerMinute * 60;
-const uint64_t kNumSecondsPerWeek = kNumSecondsPerHour * 24 * 7;
-const uint64_t kNumMillisPerSecond = 1000;
-const uint64_t kNumMicrosPerMilli = 1000;
-const uint64_t kNumMicrosPerSecond = kNumMicrosPerMilli * kNumMillisPerSecond;
-
-// Default number of connections for N-connection emulation.
-const uint32_t kDefaultNumConnections = 2;
-// Default initial maximum size in bytes of a QUIC packet.
-const QuicByteCount kDefaultMaxPacketSize = 1250;
-// Default initial maximum size in bytes of a QUIC packet for servers.
-const QuicByteCount kDefaultServerMaxPacketSize = 1000;
-// Maximum transmission unit on Ethernet.
-const QuicByteCount kEthernetMTU = 1500;
-// The maximum packet size of any QUIC packet over IPv6, based on ethernet's max
-// size, minus the IP and UDP headers. IPv6 has a 40 byte header, UDP adds an
-// additional 8 bytes. This is a total overhead of 48 bytes. Ethernet's
-// max packet size is 1500 bytes, 1500 - 48 = 1452.
-const QuicByteCount kMaxV6PacketSize = 1452;
-// The maximum packet size of any QUIC packet over IPv4.
-// 1500(Ethernet) - 20(IPv4 header) - 8(UDP header) = 1472.
-const QuicByteCount kMaxV4PacketSize = 1472;
-// The maximum incoming packet size allowed.
-const QuicByteCount kMaxIncomingPacketSize = kMaxV4PacketSize;
-// The maximum outgoing packet size allowed.
-const QuicByteCount kMaxOutgoingPacketSize = kMaxV6PacketSize;
-// ETH_MAX_MTU - MAX(sizeof(iphdr), sizeof(ip6_hdr)) - sizeof(udphdr).
-const QuicByteCount kMaxGsoPacketSize = 65535 - 40 - 8;
-// The maximal IETF DATAGRAM frame size we'll accept. Choosing 2^16 ensures
-// that it is greater than the biggest frame we could ever fit in a QUIC packet.
-const QuicByteCount kMaxAcceptedDatagramFrameSize = 65536;
-// Default value of the max_packet_size transport parameter if it is not
-// transmitted.
-const QuicByteCount kDefaultMaxPacketSizeTransportParam = 65527;
-// Default maximum packet size used in the Linux TCP implementation.
-// Used in QUIC for congestion window computations in bytes.
-const QuicByteCount kDefaultTCPMSS = 1460;
-const QuicByteCount kMaxSegmentSize = kDefaultTCPMSS;
-// The minimum size of a packet which can elicit a version negotiation packet,
-// as per section 8.1 of the QUIC spec.
-const QuicByteCount kMinPacketSizeForVersionNegotiation = 1200;
-
-// We match SPDY's use of 32 (since we'd compete with SPDY).
-const QuicPacketCount kInitialCongestionWindow = 32;
-
-// Do not allow initial congestion window to be greater than 200 packets.
-const QuicPacketCount kMaxInitialCongestionWindow = 200;
-
-// Do not allow initial congestion window to be smaller than 10 packets.
-const QuicPacketCount kMinInitialCongestionWindow = 10;
-
-// Minimum size of initial flow control window, for both stream and session.
-// This is only enforced when version.AllowsLowFlowControlLimits() is false.
-const QuicByteCount kMinimumFlowControlSendWindow = 16 * 1024; // 16 KB
-// Default size of initial flow control window, for both stream and session.
-const QuicByteCount kDefaultFlowControlSendWindow = 16 * 1024; // 16 KB
-
-// Maximum flow control receive window limits for connection and stream.
-const QuicByteCount kStreamReceiveWindowLimit = 16 * 1024 * 1024; // 16 MB
-const QuicByteCount kSessionReceiveWindowLimit = 24 * 1024 * 1024; // 24 MB
-
-// Minimum size of the CWND, in packets, when doing bandwidth resumption.
-const QuicPacketCount kMinCongestionWindowForBandwidthResumption = 10;
-
-// Default size of the socket receive buffer in bytes.
-const QuicByteCount kDefaultSocketReceiveBuffer = 1024 * 1024;
-
-// Don't allow a client to suggest an RTT shorter than 10ms.
-const uint32_t kMinInitialRoundTripTimeUs = 10 * kNumMicrosPerMilli;
-
-// Don't allow a client to suggest an RTT longer than 1 second.
-const uint32_t kMaxInitialRoundTripTimeUs = kNumMicrosPerSecond;
-
-// Maximum number of open streams per connection.
-const size_t kDefaultMaxStreamsPerConnection = 100;
-
-// Number of bytes reserved for public flags in the packet header.
-const size_t kPublicFlagsSize = 1;
-// Number of bytes reserved for version number in the packet header.
-const size_t kQuicVersionSize = 4;
-
-// Minimum number of active connection IDs that an end point can maintain.
-const uint32_t kMinNumOfActiveConnectionIds = 2;
-
-// Length of the retry integrity tag in bytes.
-// https://tools.ietf.org/html/draft-ietf-quic-transport-25#section-17.2.5
-const size_t kRetryIntegrityTagLength = 16;
-
-// By default, UnackedPacketsMap allocates buffer of 64 after the first packet
-// is added.
-const int kDefaultUnackedPacketsInitialCapacity = 64;
-
-// Signifies that the QuicPacket will contain version of the protocol.
-const bool kIncludeVersion = true;
-// Signifies that the QuicPacket will include a diversification nonce.
-const bool kIncludeDiversificationNonce = true;
-
-// Header key used to identify final offset on data stream when sending HTTP/2
-// trailing headers over QUIC.
-QUIC_EXPORT_PRIVATE extern const char* const kFinalOffsetHeaderKey;
-
-// Default maximum delayed ack time, in ms.
-// Uses a 25ms delayed ack timer. Helps with better signaling
-// in low-bandwidth (< ~384 kbps), where an ack is sent per packet.
-const int64_t kDefaultDelayedAckTimeMs = 25;
-
-// Default minimum delayed ack time, in ms (used only for sender control of ack
-// frequency).
-const uint32_t kDefaultMinAckDelayTimeMs = 5;
-
-// Default shift of the ACK delay in the IETF QUIC ACK frame.
-const uint32_t kDefaultAckDelayExponent = 3;
-
-// Minimum tail loss probe time in ms.
-static const int64_t kMinTailLossProbeTimeoutMs = 10;
-
-// The timeout before the handshake succeeds.
-const int64_t kInitialIdleTimeoutSecs = 5;
-// The maximum idle timeout that can be negotiated.
-const int64_t kMaximumIdleTimeoutSecs = 60 * 10; // 10 minutes.
-// The default timeout for a connection until the crypto handshake succeeds.
-const int64_t kMaxTimeForCryptoHandshakeSecs = 10; // 10 secs.
-
-// Default limit on the number of undecryptable packets the connection buffers
-// before the CHLO/SHLO arrive.
-const size_t kDefaultMaxUndecryptablePackets = 10;
-
-// Default ping timeout.
-const int64_t kPingTimeoutSecs = 15; // 15 secs.
-
-// Minimum number of RTTs between Server Config Updates (SCUP) sent to client.
-const int kMinIntervalBetweenServerConfigUpdatesRTTs = 10;
-
-// Minimum time between Server Config Updates (SCUP) sent to client.
-const int kMinIntervalBetweenServerConfigUpdatesMs = 1000;
-
-// Minimum number of packets between Server Config Updates (SCUP).
-const int kMinPacketsBetweenServerConfigUpdates = 100;
-
-// The number of open streams that a server will accept is set to be slightly
-// larger than the negotiated limit. Immediately closing the connection if the
-// client opens slightly too many streams is not ideal: the client may have sent
-// a FIN that was lost, and simultaneously opened a new stream. The number of
-// streams a server accepts is a fixed increment over the negotiated limit, or a
-// percentage increase, whichever is larger.
-const float kMaxStreamsMultiplier = 1.1f;
-const int kMaxStreamsMinimumIncrement = 10;
-
-// Available streams are ones with IDs less than the highest stream that has
-// been opened which have neither been opened or reset. The limit on the number
-// of available streams is 10 times the limit on the number of open streams.
-const int kMaxAvailableStreamsMultiplier = 10;
-
-// Track the number of promises that are not yet claimed by a
-// corresponding get. This must be smaller than
-// kMaxAvailableStreamsMultiplier, because RST on a promised stream my
-// create available streams entries.
-const int kMaxPromisedStreamsMultiplier = kMaxAvailableStreamsMultiplier - 1;
-
-// 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.
-static const int64_t kMinRetransmissionTimeMs = 200;
-// The delayed ack time must not be greater than half the min RTO.
-static_assert(kDefaultDelayedAckTimeMs <= kMinRetransmissionTimeMs / 2,
- "Delayed ack time must be less than or equal half the MinRTO");
-
-// We define an unsigned 16-bit floating point value, inspired by IEEE floats
-// (http://en.wikipedia.org/wiki/Half_precision_floating-point_format),
-// with 5-bit exponent (bias 1), 11-bit mantissa (effective 12 with hidden
-// bit) and denormals, but without signs, transfinites or fractions. Wire format
-// 16 bits (little-endian byte order) are split into exponent (high 5) and
-// mantissa (low 11) and decoded as:
-// uint64_t value;
-// if (exponent == 0) value = mantissa;
-// else value = (mantissa | 1 << 11) << (exponent - 1)
-const int kUFloat16ExponentBits = 5;
-const int kUFloat16MaxExponent = (1 << kUFloat16ExponentBits) - 2; // 30
-const int kUFloat16MantissaBits = 16 - kUFloat16ExponentBits; // 11
-const int kUFloat16MantissaEffectiveBits = kUFloat16MantissaBits + 1; // 12
-const uint64_t kUFloat16MaxValue = // 0x3FFC0000000
- ((UINT64_C(1) << kUFloat16MantissaEffectiveBits) - 1)
- << kUFloat16MaxExponent;
-
-// kDiversificationNonceSize is the size, in bytes, of the nonce that a server
-// may set in the packet header to ensure that its INITIAL keys are not
-// duplicated.
-const size_t kDiversificationNonceSize = 32;
-
-// The largest gap in packets we'll accept without closing the connection.
-// This will likely have to be tuned.
-const QuicPacketCount kMaxPacketGap = 5000;
-
-// The max number of sequence number intervals that
-// QuicPeerIssuedConnetionIdManager can maintain.
-const size_t kMaxNumConnectionIdSequenceNumberIntervals = 20;
-
-// The maximum number of random padding bytes to add.
-const QuicByteCount kMaxNumRandomPaddingBytes = 256;
-
-// The size of stream send buffer data slice size in bytes. A data slice is
-// piece of stream data stored in contiguous memory, and a stream frame can
-// contain data from multiple data slices.
-const QuicByteCount kQuicStreamSendBufferSliceSize = 4 * 1024;
-
-// For When using Random Initial Packet Numbers, they can start
-// anyplace in the range 1...((2^31)-1) or 0x7fffffff
-QUIC_EXPORT_PRIVATE QuicPacketNumber MaxRandomInitialPacketNumber();
-
-// Used to represent an invalid or no control frame id.
-const QuicControlFrameId kInvalidControlFrameId = 0;
-
-// The max length a stream can have.
-const QuicByteCount kMaxStreamLength = (UINT64_C(1) << 62) - 1;
-
-// The max value that can be encoded using IETF Var Ints.
-const uint64_t kMaxIetfVarInt = UINT64_C(0x3fffffffffffffff);
-
-// The maximum stream id value that is supported - (2^32)-1
-const QuicStreamId kMaxQuicStreamId = 0xffffffff;
-
-// The maximum value that can be stored in a 32-bit QuicStreamCount.
-const QuicStreamCount kMaxQuicStreamCount = 0xffffffff;
-
-// Number of bytes reserved for packet header type.
-const size_t kPacketHeaderTypeSize = 1;
-
-// Number of bytes reserved for connection ID length.
-const size_t kConnectionIdLengthSize = 1;
-
-// Minimum length of random bytes in IETF stateless reset packet.
-const size_t kMinRandomBytesLengthInStatelessReset = 24;
-
-// Maximum length allowed for the token in a NEW_TOKEN frame.
-const size_t kMaxNewTokenTokenLength = 0xffff;
-
-// Default initial rtt used before any samples are received.
-const int kInitialRttMs = 100;
-
-// Default threshold of packet reordering before a packet is declared lost.
-static const QuicPacketCount kDefaultPacketReorderingThreshold = 3;
-
-// Default fraction (1/4) of an RTT the algorithm waits before determining a
-// packet is lost due to early retransmission by time based loss detection.
-static const int kDefaultLossDelayShift = 2;
-
-// Default fraction (1/8) of an RTT when doing IETF loss detection.
-static const int kDefaultIetfLossDelayShift = 3;
-
-// Maximum number of retransmittable packets received before sending an ack.
-const QuicPacketCount kDefaultRetransmittablePacketsBeforeAck = 2;
-// Wait for up to 10 retransmittable packets before sending an ack.
-const QuicPacketCount kMaxRetransmittablePacketsBeforeAck = 10;
-// Minimum number of packets received before ack decimation is enabled.
-// This intends to avoid the beginning of slow start, when CWNDs may be
-// rapidly increasing.
-const QuicPacketCount kMinReceivedBeforeAckDecimation = 100;
-// One quarter RTT delay when doing ack decimation.
-const float kAckDecimationDelay = 0.25;
-
-// The default alarm granularity assumed by QUIC code.
-const QuicTime::Delta kAlarmGranularity = QuicTime::Delta::FromMilliseconds(1);
-
-// Maximum number of unretired connection IDs a connection can have.
-const size_t kMaxNumConnectonIdsInUse = 10u;
-
-// Packet number of first sending packet of a connection. Please note, this
-// cannot be used as first received packet because peer can choose its starting
-// packet number.
-QUIC_EXPORT_PRIVATE QuicPacketNumber FirstSendingPacketNumber();
-
-// Used by clients to tell if a public reset is sent from a Google frontend.
-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,
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_QUIC_CONSTANTS_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_control_frame_manager.cc b/chromium/net/third_party/quiche/src/quic/core/quic_control_frame_manager.cc
deleted file mode 100644
index 39e768c9ed5..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_control_frame_manager.cc
+++ /dev/null
@@ -1,363 +0,0 @@
-// Copyright (c) 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_control_frame_manager.h"
-
-#include <string>
-
-#include "absl/strings/str_cat.h"
-#include "quic/core/frames/quic_ack_frequency_frame.h"
-#include "quic/core/frames/quic_frame.h"
-#include "quic/core/frames/quic_new_connection_id_frame.h"
-#include "quic/core/frames/quic_retire_connection_id_frame.h"
-#include "quic/core/quic_constants.h"
-#include "quic/core/quic_session.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_flag_utils.h"
-
-namespace quic {
-
-namespace {
-
-// The maximum number of buffered control frames which are waiting to be ACKed
-// or sent for the first time.
-const size_t kMaxNumControlFrames = 1000;
-
-} // namespace
-
-QuicControlFrameManager::QuicControlFrameManager(QuicSession* session)
- : last_control_frame_id_(kInvalidControlFrameId),
- least_unacked_(1),
- least_unsent_(1),
- delegate_(session) {}
-
-QuicControlFrameManager::~QuicControlFrameManager() {
- while (!control_frames_.empty()) {
- DeleteFrame(&control_frames_.front());
- control_frames_.pop_front();
- }
-}
-
-void QuicControlFrameManager::WriteOrBufferQuicFrame(QuicFrame frame) {
- const bool had_buffered_frames = HasBufferedFrames();
- control_frames_.emplace_back(frame);
- if (control_frames_.size() > kMaxNumControlFrames) {
- delegate_->OnControlFrameManagerError(
- QUIC_TOO_MANY_BUFFERED_CONTROL_FRAMES,
- absl::StrCat("More than ", kMaxNumControlFrames,
- "buffered control frames, least_unacked: ", least_unacked_,
- ", least_unsent_: ", least_unsent_));
- return;
- }
- if (had_buffered_frames) {
- return;
- }
- WriteBufferedFrames();
-}
-
-void QuicControlFrameManager::WriteOrBufferRstStream(
- QuicStreamId id, QuicResetStreamError error,
- QuicStreamOffset bytes_written) {
- QUIC_DVLOG(1) << "Writing RST_STREAM_FRAME";
- WriteOrBufferQuicFrame((QuicFrame(new QuicRstStreamFrame(
- ++last_control_frame_id_, id, error, bytes_written))));
-}
-
-void QuicControlFrameManager::WriteOrBufferGoAway(
- QuicErrorCode error, QuicStreamId last_good_stream_id,
- const std::string& reason) {
- QUIC_DVLOG(1) << "Writing GOAWAY_FRAME";
- WriteOrBufferQuicFrame(QuicFrame(new QuicGoAwayFrame(
- ++last_control_frame_id_, error, last_good_stream_id, reason)));
-}
-
-void QuicControlFrameManager::WriteOrBufferWindowUpdate(
- QuicStreamId id, QuicStreamOffset byte_offset) {
- QUIC_DVLOG(1) << "Writing WINDOW_UPDATE_FRAME";
- WriteOrBufferQuicFrame(QuicFrame(
- new QuicWindowUpdateFrame(++last_control_frame_id_, id, byte_offset)));
-}
-
-void QuicControlFrameManager::WriteOrBufferBlocked(QuicStreamId id) {
- QUIC_DVLOG(1) << "Writing BLOCKED_FRAME";
- WriteOrBufferQuicFrame(
- QuicFrame(new QuicBlockedFrame(++last_control_frame_id_, id)));
-}
-
-void QuicControlFrameManager::WriteOrBufferStreamsBlocked(QuicStreamCount count,
- bool unidirectional) {
- QUIC_DVLOG(1) << "Writing STREAMS_BLOCKED Frame";
- QUIC_CODE_COUNT(quic_streams_blocked_transmits);
- WriteOrBufferQuicFrame(QuicFrame(QuicStreamsBlockedFrame(
- ++last_control_frame_id_, count, unidirectional)));
-}
-
-void QuicControlFrameManager::WriteOrBufferMaxStreams(QuicStreamCount count,
- bool unidirectional) {
- QUIC_DVLOG(1) << "Writing MAX_STREAMS Frame";
- QUIC_CODE_COUNT(quic_max_streams_transmits);
- WriteOrBufferQuicFrame(QuicFrame(
- QuicMaxStreamsFrame(++last_control_frame_id_, count, unidirectional)));
-}
-
-void QuicControlFrameManager::WriteOrBufferStopSending(
- QuicResetStreamError error, QuicStreamId stream_id) {
- QUIC_DVLOG(1) << "Writing STOP_SENDING_FRAME";
- WriteOrBufferQuicFrame(QuicFrame(
- new QuicStopSendingFrame(++last_control_frame_id_, stream_id, error)));
-}
-
-void QuicControlFrameManager::WriteOrBufferHandshakeDone() {
- QUIC_DVLOG(1) << "Writing HANDSHAKE_DONE";
- WriteOrBufferQuicFrame(
- QuicFrame(QuicHandshakeDoneFrame(++last_control_frame_id_)));
-}
-
-void QuicControlFrameManager::WriteOrBufferAckFrequency(
- const QuicAckFrequencyFrame& ack_frequency_frame) {
- QUIC_DVLOG(1) << "Writing ACK_FREQUENCY frame";
- QuicControlFrameId control_frame_id = ++last_control_frame_id_;
- // Using the control_frame_id for sequence_number here leaves gaps in
- // sequence_number.
- WriteOrBufferQuicFrame(
- QuicFrame(new QuicAckFrequencyFrame(control_frame_id,
- /*sequence_number=*/control_frame_id,
- ack_frequency_frame.packet_tolerance,
- ack_frequency_frame.max_ack_delay)));
-}
-
-void QuicControlFrameManager::WriteOrBufferNewConnectionId(
- const QuicConnectionId& connection_id, uint64_t sequence_number,
- uint64_t retire_prior_to,
- const StatelessResetToken& stateless_reset_token) {
- QUIC_DVLOG(1) << "Writing NEW_CONNECTION_ID frame";
- WriteOrBufferQuicFrame(QuicFrame(new QuicNewConnectionIdFrame(
- ++last_control_frame_id_, connection_id, sequence_number,
- stateless_reset_token, retire_prior_to)));
-}
-
-void QuicControlFrameManager::WriteOrBufferRetireConnectionId(
- uint64_t sequence_number) {
- QUIC_DVLOG(1) << "Writing RETIRE_CONNECTION_ID frame";
- WriteOrBufferQuicFrame(QuicFrame(new QuicRetireConnectionIdFrame(
- ++last_control_frame_id_, sequence_number)));
-}
-
-void QuicControlFrameManager::WriteOrBufferNewToken(absl::string_view token) {
- QUIC_DVLOG(1) << "Writing NEW_TOKEN frame";
- WriteOrBufferQuicFrame(
- QuicFrame(new QuicNewTokenFrame(++last_control_frame_id_, token)));
-}
-
-void QuicControlFrameManager::OnControlFrameSent(const QuicFrame& frame) {
- QuicControlFrameId id = GetControlFrameId(frame);
- if (id == kInvalidControlFrameId) {
- QUIC_BUG(quic_bug_12727_1)
- << "Send or retransmit a control frame with invalid control frame id";
- return;
- }
- if (frame.type == WINDOW_UPDATE_FRAME) {
- QuicStreamId stream_id = frame.window_update_frame->stream_id;
- if (window_update_frames_.contains(stream_id) &&
- id > window_update_frames_[stream_id]) {
- // Consider the older window update of the same stream as acked.
- OnControlFrameIdAcked(window_update_frames_[stream_id]);
- }
- window_update_frames_[stream_id] = id;
- }
- if (pending_retransmissions_.contains(id)) {
- // This is retransmitted control frame.
- pending_retransmissions_.erase(id);
- return;
- }
- if (id > least_unsent_) {
- QUIC_BUG(quic_bug_10517_1)
- << "Try to send control frames out of order, id: " << id
- << " least_unsent: " << least_unsent_;
- delegate_->OnControlFrameManagerError(
- QUIC_INTERNAL_ERROR, "Try to send control frames out of order");
- return;
- }
- ++least_unsent_;
-}
-
-bool QuicControlFrameManager::OnControlFrameAcked(const QuicFrame& frame) {
- QuicControlFrameId id = GetControlFrameId(frame);
- if (!OnControlFrameIdAcked(id)) {
- return false;
- }
- if (frame.type == WINDOW_UPDATE_FRAME) {
- QuicStreamId stream_id = frame.window_update_frame->stream_id;
- if (window_update_frames_.contains(stream_id) &&
- window_update_frames_[stream_id] == id) {
- window_update_frames_.erase(stream_id);
- }
- }
- return true;
-}
-
-void QuicControlFrameManager::OnControlFrameLost(const QuicFrame& frame) {
- QuicControlFrameId id = GetControlFrameId(frame);
- if (id == kInvalidControlFrameId) {
- // Frame does not have a valid control frame ID, ignore it.
- return;
- }
- if (id >= least_unsent_) {
- QUIC_BUG(quic_bug_10517_2) << "Try to mark unsent control frame as lost";
- delegate_->OnControlFrameManagerError(
- QUIC_INTERNAL_ERROR, "Try to mark unsent control frame as lost");
- return;
- }
- if (id < least_unacked_ ||
- GetControlFrameId(control_frames_.at(id - least_unacked_)) ==
- kInvalidControlFrameId) {
- // This frame has already been acked.
- return;
- }
- if (!pending_retransmissions_.contains(id)) {
- pending_retransmissions_[id] = true;
- QUIC_BUG_IF(quic_bug_12727_2,
- pending_retransmissions_.size() > control_frames_.size())
- << "least_unacked_: " << least_unacked_
- << ", least_unsent_: " << least_unsent_;
- }
-}
-
-bool QuicControlFrameManager::IsControlFrameOutstanding(
- const QuicFrame& frame) const {
- QuicControlFrameId id = GetControlFrameId(frame);
- if (id == kInvalidControlFrameId) {
- // Frame without a control frame ID should not be retransmitted.
- return false;
- }
- // Consider this frame is outstanding if it does not get acked.
- return id < least_unacked_ + control_frames_.size() && id >= least_unacked_ &&
- GetControlFrameId(control_frames_.at(id - least_unacked_)) !=
- kInvalidControlFrameId;
-}
-
-bool QuicControlFrameManager::HasPendingRetransmission() const {
- return !pending_retransmissions_.empty();
-}
-
-bool QuicControlFrameManager::WillingToWrite() const {
- return HasPendingRetransmission() || HasBufferedFrames();
-}
-
-QuicFrame QuicControlFrameManager::NextPendingRetransmission() const {
- QUIC_BUG_IF(quic_bug_12727_3, pending_retransmissions_.empty())
- << "Unexpected call to NextPendingRetransmission() with empty pending "
- << "retransmission list.";
- QuicControlFrameId id = pending_retransmissions_.begin()->first;
- return control_frames_.at(id - least_unacked_);
-}
-
-void QuicControlFrameManager::OnCanWrite() {
- if (HasPendingRetransmission()) {
- // Exit early to allow streams to write pending retransmissions if any.
- WritePendingRetransmission();
- return;
- }
- WriteBufferedFrames();
-}
-
-bool QuicControlFrameManager::RetransmitControlFrame(const QuicFrame& frame,
- TransmissionType type) {
- QUICHE_DCHECK(type == PTO_RETRANSMISSION || type == RTO_RETRANSMISSION ||
- type == TLP_RETRANSMISSION || type == PROBING_RETRANSMISSION);
- QuicControlFrameId id = GetControlFrameId(frame);
- if (id == kInvalidControlFrameId) {
- // Frame does not have a valid control frame ID, ignore it. Returns true
- // to allow writing following frames.
- return true;
- }
- if (id >= least_unsent_) {
- QUIC_BUG(quic_bug_10517_3) << "Try to retransmit unsent control frame";
- delegate_->OnControlFrameManagerError(
- QUIC_INTERNAL_ERROR, "Try to retransmit unsent control frame");
- return false;
- }
- if (id < least_unacked_ ||
- GetControlFrameId(control_frames_.at(id - least_unacked_)) ==
- kInvalidControlFrameId) {
- // This frame has already been acked.
- return true;
- }
- QuicFrame copy = CopyRetransmittableControlFrame(frame);
- QUIC_DVLOG(1) << "control frame manager is forced to retransmit frame: "
- << frame;
- if (delegate_->WriteControlFrame(copy, type)) {
- return true;
- }
- DeleteFrame(&copy);
- return false;
-}
-
-void QuicControlFrameManager::WriteBufferedFrames() {
- while (HasBufferedFrames()) {
- QuicFrame frame_to_send =
- control_frames_.at(least_unsent_ - least_unacked_);
- QuicFrame copy = CopyRetransmittableControlFrame(frame_to_send);
- if (!delegate_->WriteControlFrame(copy, NOT_RETRANSMISSION)) {
- // Connection is write blocked.
- DeleteFrame(&copy);
- break;
- }
- OnControlFrameSent(frame_to_send);
- }
-}
-
-void QuicControlFrameManager::WritePendingRetransmission() {
- while (HasPendingRetransmission()) {
- QuicFrame pending = NextPendingRetransmission();
- QuicFrame copy = CopyRetransmittableControlFrame(pending);
- if (!delegate_->WriteControlFrame(copy, LOSS_RETRANSMISSION)) {
- // Connection is write blocked.
- DeleteFrame(&copy);
- break;
- }
- OnControlFrameSent(pending);
- }
-}
-
-bool QuicControlFrameManager::OnControlFrameIdAcked(QuicControlFrameId id) {
- if (id == kInvalidControlFrameId) {
- // Frame does not have a valid control frame ID, ignore it.
- return false;
- }
- if (id >= least_unsent_) {
- QUIC_BUG(quic_bug_10517_4) << "Try to ack unsent control frame";
- delegate_->OnControlFrameManagerError(QUIC_INTERNAL_ERROR,
- "Try to ack unsent control frame");
- return false;
- }
- if (id < least_unacked_ ||
- GetControlFrameId(control_frames_.at(id - least_unacked_)) ==
- kInvalidControlFrameId) {
- // This frame has already been acked.
- return false;
- }
-
- // Set control frame ID of acked frames to 0.
- SetControlFrameId(kInvalidControlFrameId,
- &control_frames_.at(id - least_unacked_));
- // Remove acked control frames from pending retransmissions.
- pending_retransmissions_.erase(id);
- // Clean up control frames queue and increment least_unacked_.
- while (!control_frames_.empty() &&
- GetControlFrameId(control_frames_.front()) == kInvalidControlFrameId) {
- DeleteFrame(&control_frames_.front());
- control_frames_.pop_front();
- ++least_unacked_;
- }
- return true;
-}
-
-bool QuicControlFrameManager::HasBufferedFrames() const {
- return least_unsent_ < least_unacked_ + control_frames_.size();
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_control_frame_manager.h b/chromium/net/third_party/quiche/src/quic/core/quic_control_frame_manager.h
deleted file mode 100644
index e83fc3b1760..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_control_frame_manager.h
+++ /dev/null
@@ -1,192 +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_CORE_QUIC_CONTROL_FRAME_MANAGER_H_
-#define QUICHE_QUIC_CORE_QUIC_CONTROL_FRAME_MANAGER_H_
-
-#include <cstdint>
-#include <string>
-
-#include "absl/container/flat_hash_map.h"
-#include "quic/core/frames/quic_frame.h"
-#include "quic/core/quic_connection_id.h"
-#include "quic/core/quic_error_codes.h"
-#include "quic/core/quic_types.h"
-#include "common/quiche_circular_deque.h"
-#include "common/quiche_linked_hash_map.h"
-
-namespace quic {
-
-class QuicSession;
-
-namespace test {
-class QuicControlFrameManagerPeer;
-} // namespace test
-
-// Control frame manager contains a list of sent control frames with valid
-// control frame IDs. Control frames without valid control frame IDs include:
-// (1) non-retransmittable frames (e.g., ACK_FRAME, PADDING_FRAME,
-// STOP_WAITING_FRAME, etc.), (2) CONNECTION_CLOSE and IETF Quic
-// APPLICATION_CLOSE frames.
-// New control frames are added to the tail of the list when they are added to
-// the generator. Control frames are removed from the head of the list when they
-// get acked. Control frame manager also keeps track of lost control frames
-// which need to be retransmitted.
-class QUIC_EXPORT_PRIVATE QuicControlFrameManager {
- public:
- class QUIC_EXPORT_PRIVATE DelegateInterface {
- public:
- virtual ~DelegateInterface() = default;
-
- // Notifies the delegate of errors.
- virtual void OnControlFrameManagerError(QuicErrorCode error_code,
- std::string error_details) = 0;
-
- virtual bool WriteControlFrame(const QuicFrame& frame,
- TransmissionType type) = 0;
- };
-
- explicit QuicControlFrameManager(QuicSession* session);
- QuicControlFrameManager(const QuicControlFrameManager& other) = delete;
- QuicControlFrameManager(QuicControlFrameManager&& other) = delete;
- ~QuicControlFrameManager();
-
- // Tries to send a WINDOW_UPDATE_FRAME. Buffers the frame if it cannot be sent
- // immediately.
- void WriteOrBufferRstStream(QuicControlFrameId id, QuicResetStreamError error,
- QuicStreamOffset bytes_written);
-
- // Tries to send a GOAWAY_FRAME. Buffers the frame if it cannot be sent
- // immediately.
- void WriteOrBufferGoAway(QuicErrorCode error,
- QuicStreamId last_good_stream_id,
- const std::string& reason);
-
- // Tries to send a WINDOW_UPDATE_FRAME. Buffers the frame if it cannot be sent
- // immediately.
- void WriteOrBufferWindowUpdate(QuicStreamId id, QuicStreamOffset byte_offset);
-
- // Tries to send a BLOCKED_FRAME. Buffers the frame if it cannot be sent
- // immediately.
- void WriteOrBufferBlocked(QuicStreamId id);
-
- // Tries to send a STREAMS_BLOCKED Frame. Buffers the frame if it cannot be
- // sent immediately.
- void WriteOrBufferStreamsBlocked(QuicStreamCount count, bool unidirectional);
-
- // Tries to send a MAX_STREAMS Frame. Buffers the frame if it cannot be sent
- // immediately.
- void WriteOrBufferMaxStreams(QuicStreamCount count, bool unidirectional);
-
- // Tries to send an IETF-QUIC STOP_SENDING frame. The frame is buffered if it
- // can not be sent immediately.
- void WriteOrBufferStopSending(QuicResetStreamError error,
- QuicStreamId stream_id);
-
- // Tries to send an HANDSHAKE_DONE frame. The frame is buffered if it can not
- // be sent immediately.
- void WriteOrBufferHandshakeDone();
-
- // Tries to send an AckFrequencyFrame. The frame is buffered if it cannot be
- // sent immediately.
- void WriteOrBufferAckFrequency(
- const QuicAckFrequencyFrame& ack_frequency_frame);
-
- // Tries to send a NEW_CONNECTION_ID frame. The frame is buffered if it cannot
- // be sent immediately.
- void WriteOrBufferNewConnectionId(
- const QuicConnectionId& connection_id, uint64_t sequence_number,
- uint64_t retire_prior_to,
- const StatelessResetToken& stateless_reset_token);
-
- // Tries to send a RETIRE_CONNNECTION_ID frame. The frame is buffered if it
- // cannot be sent immediately.
- void WriteOrBufferRetireConnectionId(uint64_t sequence_number);
-
- // Tries to send a NEW_TOKEN frame. Buffers the frame if it cannot be sent
- // immediately.
- void WriteOrBufferNewToken(absl::string_view token);
-
- // Called when |frame| gets acked. Returns true if |frame| gets acked for the
- // first time, return false otherwise.
- bool OnControlFrameAcked(const QuicFrame& frame);
-
- // Called when |frame| is considered as lost.
- void OnControlFrameLost(const QuicFrame& frame);
-
- // Called by the session when the connection becomes writable.
- void OnCanWrite();
-
- // Retransmit |frame| if it is still outstanding. Returns false if the frame
- // does not get retransmitted because the connection is blocked. Otherwise,
- // returns true.
- bool RetransmitControlFrame(const QuicFrame& frame, TransmissionType type);
-
- // Returns true if |frame| is outstanding and waiting to be acked. Returns
- // false otherwise.
- bool IsControlFrameOutstanding(const QuicFrame& frame) const;
-
- // Returns true if there is any lost control frames waiting to be
- // retransmitted.
- bool HasPendingRetransmission() const;
-
- // Returns true if there are any lost or new control frames waiting to be
- // sent.
- bool WillingToWrite() const;
-
- private:
- friend class test::QuicControlFrameManagerPeer;
-
- // Tries to write buffered control frames to the peer.
- void WriteBufferedFrames();
-
- // Called when |frame| is sent for the first time or gets retransmitted.
- void OnControlFrameSent(const QuicFrame& frame);
-
- // Writes pending retransmissions if any.
- void WritePendingRetransmission();
-
- // Called when frame with |id| gets acked. Returns true if |id| gets acked for
- // the first time, return false otherwise.
- bool OnControlFrameIdAcked(QuicControlFrameId id);
-
- // Retrieves the next pending retransmission. This must only be called when
- // there are pending retransmissions.
- QuicFrame NextPendingRetransmission() const;
-
- // Returns true if there are buffered frames waiting to be sent for the first
- // time.
- bool HasBufferedFrames() const;
-
- // Writes or buffers a control frame. Frame is buffered if there already
- // are frames waiting to be sent. If no others waiting, will try to send the
- // frame.
- void WriteOrBufferQuicFrame(QuicFrame frame);
-
- quiche::QuicheCircularDeque<QuicFrame> control_frames_;
-
- // Id of latest saved control frame. 0 if no control frame has been saved.
- QuicControlFrameId last_control_frame_id_;
-
- // The control frame at the 0th index of control_frames_.
- QuicControlFrameId least_unacked_;
-
- // ID of the least unsent control frame.
- QuicControlFrameId least_unsent_;
-
- // TODO(fayang): switch to linked_hash_set when chromium supports it. The bool
- // is not used here.
- // Lost control frames waiting to be retransmitted.
- quiche::QuicheLinkedHashMap<QuicControlFrameId, bool>
- pending_retransmissions_;
-
- DelegateInterface* delegate_;
-
- // Last sent window update frame for each stream.
- absl::flat_hash_map<QuicStreamId, QuicControlFrameId> window_update_frames_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_QUIC_CONTROL_FRAME_MANAGER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_control_frame_manager_test.cc b/chromium/net/third_party/quiche/src/quic/core/quic_control_frame_manager_test.cc
deleted file mode 100644
index 6d208111a53..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_control_frame_manager_test.cc
+++ /dev/null
@@ -1,364 +0,0 @@
-// Copyright (c) 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_control_frame_manager.h"
-
-#include <utility>
-
-#include "quic/core/crypto/null_encrypter.h"
-#include "quic/core/frames/quic_ack_frequency_frame.h"
-#include "quic/core/frames/quic_retire_connection_id_frame.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_expect_bug.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/quic_test_utils.h"
-
-using testing::_;
-using testing::InSequence;
-using testing::Invoke;
-using testing::Return;
-using testing::StrictMock;
-
-namespace quic {
-namespace test {
-
-class QuicControlFrameManagerPeer {
- public:
- static size_t QueueSize(QuicControlFrameManager* manager) {
- return manager->control_frames_.size();
- }
-};
-
-namespace {
-
-const QuicStreamId kTestStreamId = 5;
-const QuicRstStreamErrorCode kTestStopSendingCode =
- QUIC_STREAM_ENCODER_STREAM_ERROR;
-
-class QuicControlFrameManagerTest : public QuicTest {
- public:
- bool SaveControlFrame(const QuicFrame& frame, TransmissionType /*type*/) {
- frame_ = frame;
- return true;
- }
-
- protected:
- // Pre-fills the control frame queue with the following frames:
- // ID Type
- // 1 RST_STREAM
- // 2 GO_AWAY
- // 3 WINDOW_UPDATE
- // 4 BLOCKED
- // 5 STOP_SENDING
- // This is verified. The tests then perform manipulations on these.
- void Initialize() {
- connection_ = new MockQuicConnection(&helper_, &alarm_factory_,
- Perspective::IS_SERVER);
- connection_->SetEncrypter(
- ENCRYPTION_FORWARD_SECURE,
- std::make_unique<NullEncrypter>(connection_->perspective()));
- session_ = std::make_unique<StrictMock<MockQuicSession>>(connection_);
- manager_ = std::make_unique<QuicControlFrameManager>(session_.get());
- EXPECT_EQ(0u, QuicControlFrameManagerPeer::QueueSize(manager_.get()));
- EXPECT_FALSE(manager_->HasPendingRetransmission());
- EXPECT_FALSE(manager_->WillingToWrite());
-
- EXPECT_CALL(*session_, WriteControlFrame(_, _)).WillOnce(Return(false));
- manager_->WriteOrBufferRstStream(
- kTestStreamId,
- QuicResetStreamError::FromInternal(QUIC_STREAM_CANCELLED), 0);
- manager_->WriteOrBufferGoAway(QUIC_PEER_GOING_AWAY, kTestStreamId,
- "Going away.");
- manager_->WriteOrBufferWindowUpdate(kTestStreamId, 100);
- manager_->WriteOrBufferBlocked(kTestStreamId);
- manager_->WriteOrBufferStopSending(
- QuicResetStreamError::FromInternal(kTestStopSendingCode),
- kTestStreamId);
- number_of_frames_ = 5u;
- EXPECT_EQ(number_of_frames_,
- QuicControlFrameManagerPeer::QueueSize(manager_.get()));
- EXPECT_TRUE(manager_->IsControlFrameOutstanding(QuicFrame(&rst_stream_)));
- EXPECT_TRUE(manager_->IsControlFrameOutstanding(QuicFrame(&goaway_)));
- EXPECT_TRUE(
- manager_->IsControlFrameOutstanding(QuicFrame(&window_update_)));
- EXPECT_TRUE(manager_->IsControlFrameOutstanding(QuicFrame(&blocked_)));
- EXPECT_TRUE(manager_->IsControlFrameOutstanding(QuicFrame(&stop_sending_)));
-
- EXPECT_FALSE(manager_->HasPendingRetransmission());
- EXPECT_TRUE(manager_->WillingToWrite());
- }
-
- QuicRstStreamFrame rst_stream_ = {1, kTestStreamId, QUIC_STREAM_CANCELLED, 0};
- QuicGoAwayFrame goaway_ = {2, QUIC_PEER_GOING_AWAY, kTestStreamId,
- "Going away."};
- QuicWindowUpdateFrame window_update_ = {3, kTestStreamId, 100};
- QuicBlockedFrame blocked_ = {4, kTestStreamId};
- QuicStopSendingFrame stop_sending_ = {5, kTestStreamId, kTestStopSendingCode};
- MockQuicConnectionHelper helper_;
- MockAlarmFactory alarm_factory_;
- MockQuicConnection* connection_;
- std::unique_ptr<StrictMock<MockQuicSession>> session_;
- std::unique_ptr<QuicControlFrameManager> manager_;
- QuicFrame frame_;
- size_t number_of_frames_;
-};
-
-TEST_F(QuicControlFrameManagerTest, OnControlFrameAcked) {
- Initialize();
- InSequence s;
- EXPECT_CALL(*session_, WriteControlFrame(_, _))
- .Times(3)
- .WillRepeatedly(Invoke(&ClearControlFrameWithTransmissionType));
- EXPECT_CALL(*session_, WriteControlFrame(_, _)).WillOnce(Return(false));
- // Send control frames 1, 2, 3.
- manager_->OnCanWrite();
- EXPECT_TRUE(manager_->IsControlFrameOutstanding(QuicFrame(&rst_stream_)));
- EXPECT_TRUE(manager_->IsControlFrameOutstanding(QuicFrame(&goaway_)));
- EXPECT_TRUE(manager_->IsControlFrameOutstanding(QuicFrame(&window_update_)));
- EXPECT_TRUE(manager_->IsControlFrameOutstanding(QuicFrame(&blocked_)));
- EXPECT_TRUE(manager_->IsControlFrameOutstanding(QuicFrame(&stop_sending_)));
-
- EXPECT_TRUE(manager_->OnControlFrameAcked(QuicFrame(&window_update_)));
- EXPECT_FALSE(manager_->IsControlFrameOutstanding(QuicFrame(&window_update_)));
- EXPECT_EQ(number_of_frames_,
- QuicControlFrameManagerPeer::QueueSize(manager_.get()));
-
- EXPECT_TRUE(manager_->OnControlFrameAcked(QuicFrame(&goaway_)));
- EXPECT_FALSE(manager_->IsControlFrameOutstanding(QuicFrame(&goaway_)));
- EXPECT_EQ(number_of_frames_,
- QuicControlFrameManagerPeer::QueueSize(manager_.get()));
- EXPECT_TRUE(manager_->OnControlFrameAcked(QuicFrame(&rst_stream_)));
- EXPECT_FALSE(manager_->IsControlFrameOutstanding(QuicFrame(&rst_stream_)));
- // Only after the first frame in the queue is acked do the frames get
- // removed ... now see that the length has been reduced by 3.
- EXPECT_EQ(number_of_frames_ - 3u,
- QuicControlFrameManagerPeer::QueueSize(manager_.get()));
- // Duplicate ack.
- EXPECT_FALSE(manager_->OnControlFrameAcked(QuicFrame(&goaway_)));
-
- EXPECT_FALSE(manager_->HasPendingRetransmission());
- EXPECT_TRUE(manager_->WillingToWrite());
-
- // Send control frames 4, 5.
- EXPECT_CALL(*session_, WriteControlFrame(_, _))
- .WillRepeatedly(Invoke(&ClearControlFrameWithTransmissionType));
- manager_->OnCanWrite();
- EXPECT_FALSE(manager_->WillingToWrite());
-}
-
-TEST_F(QuicControlFrameManagerTest, OnControlFrameLost) {
- Initialize();
- InSequence s;
- EXPECT_CALL(*session_, WriteControlFrame(_, _))
- .Times(3)
- .WillRepeatedly(Invoke(&ClearControlFrameWithTransmissionType));
- EXPECT_CALL(*session_, WriteControlFrame(_, _)).WillOnce(Return(false));
- // Send control frames 1, 2, 3.
- manager_->OnCanWrite();
-
- // Lost control frames 1, 2, 3.
- manager_->OnControlFrameLost(QuicFrame(&rst_stream_));
- manager_->OnControlFrameLost(QuicFrame(&goaway_));
- manager_->OnControlFrameLost(QuicFrame(&window_update_));
- EXPECT_TRUE(manager_->HasPendingRetransmission());
-
- // Ack control frame 2.
- manager_->OnControlFrameAcked(QuicFrame(&goaway_));
-
- // Retransmit control frames 1, 3.
- EXPECT_CALL(*session_, WriteControlFrame(_, _))
- .Times(2)
- .WillRepeatedly(Invoke(&ClearControlFrameWithTransmissionType));
- manager_->OnCanWrite();
- EXPECT_FALSE(manager_->HasPendingRetransmission());
- EXPECT_TRUE(manager_->WillingToWrite());
-
- // Send control frames 4, 5, and 6.
- EXPECT_CALL(*session_, WriteControlFrame(_, _))
- .Times(number_of_frames_ - 3u)
- .WillRepeatedly(Invoke(&ClearControlFrameWithTransmissionType));
- manager_->OnCanWrite();
- EXPECT_FALSE(manager_->WillingToWrite());
-}
-
-TEST_F(QuicControlFrameManagerTest, RetransmitControlFrame) {
- Initialize();
- InSequence s;
- // Send control frames 1, 2, 3, 4.
- EXPECT_CALL(*session_, WriteControlFrame(_, _))
- .Times(number_of_frames_)
- .WillRepeatedly(Invoke(&ClearControlFrameWithTransmissionType));
- manager_->OnCanWrite();
-
- // Ack control frame 2.
- manager_->OnControlFrameAcked(QuicFrame(&goaway_));
- // Do not retransmit an acked frame
- EXPECT_CALL(*session_, WriteControlFrame(_, _)).Times(0);
- EXPECT_TRUE(manager_->RetransmitControlFrame(QuicFrame(&goaway_),
- PTO_RETRANSMISSION));
-
- // Retransmit control frame 3.
- EXPECT_CALL(*session_, WriteControlFrame(_, _))
- .WillOnce(Invoke(&ClearControlFrameWithTransmissionType));
- EXPECT_TRUE(manager_->RetransmitControlFrame(QuicFrame(&window_update_),
- PTO_RETRANSMISSION));
-
- // Retransmit control frame 4, and connection is write blocked.
- EXPECT_CALL(*session_, WriteControlFrame(_, _)).WillOnce(Return(false));
- EXPECT_FALSE(manager_->RetransmitControlFrame(QuicFrame(&window_update_),
- PTO_RETRANSMISSION));
-}
-
-TEST_F(QuicControlFrameManagerTest, SendAndAckAckFrequencyFrame) {
- Initialize();
- InSequence s;
- // Send Non-AckFrequency frame 1-5.
- EXPECT_CALL(*session_, WriteControlFrame(_, _))
- .Times(5)
- .WillRepeatedly(Invoke(&ClearControlFrameWithTransmissionType));
- EXPECT_CALL(*session_, WriteControlFrame(_, _)).WillOnce(Return(false));
- manager_->OnCanWrite();
-
- // Send AckFrequencyFrame as frame 6.
- QuicAckFrequencyFrame frame_to_send;
- frame_to_send.packet_tolerance = 10;
- frame_to_send.max_ack_delay = QuicTime::Delta::FromMilliseconds(24);
- manager_->WriteOrBufferAckFrequency(frame_to_send);
- EXPECT_CALL(*session_, WriteControlFrame(_, _))
- .WillOnce(Invoke(&ClearControlFrameWithTransmissionType));
- manager_->OnCanWrite();
-
- // Ack AckFrequencyFrame.
- QuicAckFrequencyFrame expected_ack_frequency = {
- 6, 6, 10, QuicTime::Delta::FromMilliseconds(24)};
- EXPECT_TRUE(
- manager_->OnControlFrameAcked(QuicFrame(&expected_ack_frequency)));
-}
-
-TEST_F(QuicControlFrameManagerTest, NewAndRetireConnectionIdFrames) {
- Initialize();
- InSequence s;
-
- // Send other frames 1-5.
- EXPECT_CALL(*session_, WriteControlFrame(_, _))
- .Times(5)
- .WillRepeatedly(Invoke(&ClearControlFrameWithTransmissionType));
- manager_->OnCanWrite();
-
- EXPECT_CALL(*session_, WriteControlFrame(_, _)).WillOnce(Return(false));
- EXPECT_CALL(*session_, WriteControlFrame(_, _))
- .Times(2)
- .WillRepeatedly(Invoke(&ClearControlFrameWithTransmissionType));
- // Send NewConnectionIdFrame as frame 6.
- manager_->WriteOrBufferNewConnectionId(
- TestConnectionId(3), /*sequence_number=*/2, /*retire_prior_to=*/1,
- /*stateless_reset_token=*/
- {0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1});
- // Send RetireConnectionIdFrame as frame 7.
- manager_->WriteOrBufferRetireConnectionId(/*sequence_number=*/0);
- manager_->OnCanWrite();
-
- // Ack both frames.
- QuicNewConnectionIdFrame new_connection_id_frame;
- new_connection_id_frame.control_frame_id = 6;
- QuicRetireConnectionIdFrame retire_connection_id_frame;
- retire_connection_id_frame.control_frame_id = 7;
- EXPECT_TRUE(
- manager_->OnControlFrameAcked(QuicFrame(&new_connection_id_frame)));
- EXPECT_TRUE(
- manager_->OnControlFrameAcked(QuicFrame(&retire_connection_id_frame)));
-}
-
-TEST_F(QuicControlFrameManagerTest, DonotRetransmitOldWindowUpdates) {
- Initialize();
- // Send two more window updates of the same stream.
- manager_->WriteOrBufferWindowUpdate(kTestStreamId, 200);
- QuicWindowUpdateFrame window_update2(number_of_frames_ + 1, kTestStreamId,
- 200);
-
- manager_->WriteOrBufferWindowUpdate(kTestStreamId, 300);
- QuicWindowUpdateFrame window_update3(number_of_frames_ + 2, kTestStreamId,
- 300);
- InSequence s;
- // Flush all buffered control frames.
- EXPECT_CALL(*session_, WriteControlFrame(_, _))
- .WillRepeatedly(Invoke(&ClearControlFrameWithTransmissionType));
- manager_->OnCanWrite();
-
- // Mark all 3 window updates as lost.
- manager_->OnControlFrameLost(QuicFrame(&window_update_));
- manager_->OnControlFrameLost(QuicFrame(&window_update2));
- manager_->OnControlFrameLost(QuicFrame(&window_update3));
- EXPECT_TRUE(manager_->HasPendingRetransmission());
- EXPECT_TRUE(manager_->WillingToWrite());
-
- // Verify only the latest window update gets retransmitted.
- EXPECT_CALL(*session_, WriteControlFrame(_, _))
- .WillOnce(Invoke(this, &QuicControlFrameManagerTest::SaveControlFrame));
- manager_->OnCanWrite();
- EXPECT_EQ(number_of_frames_ + 2u,
- frame_.window_update_frame->control_frame_id);
- EXPECT_FALSE(manager_->HasPendingRetransmission());
- EXPECT_FALSE(manager_->WillingToWrite());
- DeleteFrame(&frame_);
-}
-
-TEST_F(QuicControlFrameManagerTest, RetransmitWindowUpdateOfDifferentStreams) {
- Initialize();
- // Send two more window updates of different streams.
- manager_->WriteOrBufferWindowUpdate(kTestStreamId + 2, 200);
- QuicWindowUpdateFrame window_update2(5, kTestStreamId + 2, 200);
-
- manager_->WriteOrBufferWindowUpdate(kTestStreamId + 4, 300);
- QuicWindowUpdateFrame window_update3(6, kTestStreamId + 4, 300);
- InSequence s;
- // Flush all buffered control frames.
- EXPECT_CALL(*session_, WriteControlFrame(_, _))
- .WillRepeatedly(Invoke(&ClearControlFrameWithTransmissionType));
- manager_->OnCanWrite();
-
- // Mark all 3 window updates as lost.
- manager_->OnControlFrameLost(QuicFrame(&window_update_));
- manager_->OnControlFrameLost(QuicFrame(&window_update2));
- manager_->OnControlFrameLost(QuicFrame(&window_update3));
- EXPECT_TRUE(manager_->HasPendingRetransmission());
- EXPECT_TRUE(manager_->WillingToWrite());
-
- // Verify all 3 window updates get retransmitted.
- EXPECT_CALL(*session_, WriteControlFrame(_, _))
- .Times(3)
- .WillRepeatedly(Invoke(&ClearControlFrameWithTransmissionType));
- manager_->OnCanWrite();
- EXPECT_FALSE(manager_->HasPendingRetransmission());
- EXPECT_FALSE(manager_->WillingToWrite());
-}
-
-TEST_F(QuicControlFrameManagerTest, TooManyBufferedControlFrames) {
- Initialize();
- EXPECT_CALL(*session_, WriteControlFrame(_, _))
- .Times(5)
- .WillRepeatedly(Invoke(&ClearControlFrameWithTransmissionType));
- // Flush buffered frames.
- manager_->OnCanWrite();
- // Write 995 control frames.
- EXPECT_CALL(*session_, WriteControlFrame(_, _)).WillOnce(Return(false));
- for (size_t i = 0; i < 995; ++i) {
- manager_->WriteOrBufferRstStream(
- kTestStreamId,
- QuicResetStreamError::FromInternal(QUIC_STREAM_CANCELLED), 0);
- }
- // Verify write one more control frame causes connection close.
- EXPECT_CALL(
- *connection_,
- CloseConnection(QUIC_TOO_MANY_BUFFERED_CONTROL_FRAMES, _,
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET));
- manager_->WriteOrBufferRstStream(
- kTestStreamId, QuicResetStreamError::FromInternal(QUIC_STREAM_CANCELLED),
- 0);
-}
-
-} // namespace
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_crypto_client_handshaker.cc b/chromium/net/third_party/quiche/src/quic/core/quic_crypto_client_handshaker.cc
deleted file mode 100644
index 872b050bf9c..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_crypto_client_handshaker.cc
+++ /dev/null
@@ -1,629 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_crypto_client_handshaker.h"
-
-#include <memory>
-#include <string>
-
-#include "absl/strings/str_cat.h"
-#include "quic/core/crypto/crypto_protocol.h"
-#include "quic/core/crypto/crypto_utils.h"
-#include "quic/core/quic_session.h"
-#include "quic/platform/api/quic_client_stats.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-QuicCryptoClientHandshaker::ProofVerifierCallbackImpl::
- ProofVerifierCallbackImpl(QuicCryptoClientHandshaker* parent)
- : parent_(parent) {}
-
-QuicCryptoClientHandshaker::ProofVerifierCallbackImpl::
- ~ProofVerifierCallbackImpl() {}
-
-void QuicCryptoClientHandshaker::ProofVerifierCallbackImpl::Run(
- bool ok,
- const std::string& error_details,
- std::unique_ptr<ProofVerifyDetails>* details) {
- if (parent_ == nullptr) {
- return;
- }
-
- parent_->verify_ok_ = ok;
- parent_->verify_error_details_ = error_details;
- parent_->verify_details_ = std::move(*details);
- parent_->proof_verify_callback_ = nullptr;
- parent_->DoHandshakeLoop(nullptr);
-
- // The ProofVerifier owns this object and will delete it when this method
- // returns.
-}
-
-void QuicCryptoClientHandshaker::ProofVerifierCallbackImpl::Cancel() {
- parent_ = nullptr;
-}
-
-QuicCryptoClientHandshaker::QuicCryptoClientHandshaker(
- const QuicServerId& server_id,
- QuicCryptoClientStream* stream,
- QuicSession* session,
- std::unique_ptr<ProofVerifyContext> verify_context,
- QuicCryptoClientConfig* crypto_config,
- QuicCryptoClientStream::ProofHandler* proof_handler)
- : QuicCryptoHandshaker(stream, session),
- stream_(stream),
- session_(session),
- delegate_(session),
- next_state_(STATE_IDLE),
- num_client_hellos_(0),
- crypto_config_(crypto_config),
- server_id_(server_id),
- generation_counter_(0),
- verify_context_(std::move(verify_context)),
- proof_verify_callback_(nullptr),
- proof_handler_(proof_handler),
- verify_ok_(false),
- proof_verify_start_time_(QuicTime::Zero()),
- num_scup_messages_received_(0),
- encryption_established_(false),
- one_rtt_keys_available_(false),
- crypto_negotiated_params_(new QuicCryptoNegotiatedParameters) {}
-
-QuicCryptoClientHandshaker::~QuicCryptoClientHandshaker() {
- if (proof_verify_callback_) {
- proof_verify_callback_->Cancel();
- }
-}
-
-void QuicCryptoClientHandshaker::OnHandshakeMessage(
- const CryptoHandshakeMessage& message) {
- QuicCryptoHandshaker::OnHandshakeMessage(message);
- if (message.tag() == kSCUP) {
- if (!one_rtt_keys_available()) {
- stream_->OnUnrecoverableError(
- QUIC_CRYPTO_UPDATE_BEFORE_HANDSHAKE_COMPLETE,
- "Early SCUP disallowed");
- return;
- }
-
- // |message| is an update from the server, so we treat it differently from a
- // handshake message.
- HandleServerConfigUpdateMessage(message);
- num_scup_messages_received_++;
- return;
- }
-
- // Do not process handshake messages after the handshake is confirmed.
- if (one_rtt_keys_available()) {
- stream_->OnUnrecoverableError(QUIC_CRYPTO_MESSAGE_AFTER_HANDSHAKE_COMPLETE,
- "Unexpected handshake message");
- return;
- }
-
- DoHandshakeLoop(&message);
-}
-
-bool QuicCryptoClientHandshaker::CryptoConnect() {
- next_state_ = STATE_INITIALIZE;
- DoHandshakeLoop(nullptr);
- return session()->connection()->connected();
-}
-
-int QuicCryptoClientHandshaker::num_sent_client_hellos() const {
- return num_client_hellos_;
-}
-
-bool QuicCryptoClientHandshaker::IsResumption() const {
- QUIC_BUG_IF(quic_bug_12522_1, !one_rtt_keys_available_);
- // While 0-RTT handshakes could be considered to be like resumption, QUIC
- // Crypto doesn't have the same notion of a resumption like TLS does.
- return false;
-}
-
-bool QuicCryptoClientHandshaker::EarlyDataAccepted() const {
- QUIC_BUG_IF(quic_bug_12522_2, !one_rtt_keys_available_);
- return num_client_hellos_ == 1;
-}
-
-ssl_early_data_reason_t QuicCryptoClientHandshaker::EarlyDataReason() const {
- return early_data_reason_;
-}
-
-bool QuicCryptoClientHandshaker::ReceivedInchoateReject() const {
- QUIC_BUG_IF(quic_bug_12522_3, !one_rtt_keys_available_);
- return num_client_hellos_ >= 3;
-}
-
-int QuicCryptoClientHandshaker::num_scup_messages_received() const {
- return num_scup_messages_received_;
-}
-
-std::string QuicCryptoClientHandshaker::chlo_hash() const {
- return chlo_hash_;
-}
-
-bool QuicCryptoClientHandshaker::encryption_established() const {
- return encryption_established_;
-}
-
-bool QuicCryptoClientHandshaker::one_rtt_keys_available() const {
- return one_rtt_keys_available_;
-}
-
-const QuicCryptoNegotiatedParameters&
-QuicCryptoClientHandshaker::crypto_negotiated_params() const {
- return *crypto_negotiated_params_;
-}
-
-CryptoMessageParser* QuicCryptoClientHandshaker::crypto_message_parser() {
- return QuicCryptoHandshaker::crypto_message_parser();
-}
-
-HandshakeState QuicCryptoClientHandshaker::GetHandshakeState() const {
- return one_rtt_keys_available() ? HANDSHAKE_COMPLETE : HANDSHAKE_START;
-}
-
-void QuicCryptoClientHandshaker::OnHandshakeDoneReceived() {
- QUICHE_DCHECK(false);
-}
-
-void QuicCryptoClientHandshaker::OnNewTokenReceived(
- absl::string_view /*token*/) {
- QUICHE_DCHECK(false);
-}
-
-size_t QuicCryptoClientHandshaker::BufferSizeLimitForLevel(
- EncryptionLevel level) const {
- return QuicCryptoHandshaker::BufferSizeLimitForLevel(level);
-}
-
-std::unique_ptr<QuicDecrypter>
-QuicCryptoClientHandshaker::AdvanceKeysAndCreateCurrentOneRttDecrypter() {
- // Key update is only defined in QUIC+TLS.
- QUICHE_DCHECK(false);
- return nullptr;
-}
-
-std::unique_ptr<QuicEncrypter>
-QuicCryptoClientHandshaker::CreateCurrentOneRttEncrypter() {
- // Key update is only defined in QUIC+TLS.
- QUICHE_DCHECK(false);
- return nullptr;
-}
-
-void QuicCryptoClientHandshaker::OnConnectionClosed(
- QuicErrorCode /*error*/,
- ConnectionCloseSource /*source*/) {
- next_state_ = STATE_CONNECTION_CLOSED;
-}
-
-void QuicCryptoClientHandshaker::HandleServerConfigUpdateMessage(
- const CryptoHandshakeMessage& server_config_update) {
- QUICHE_DCHECK(server_config_update.tag() == kSCUP);
- std::string error_details;
- QuicCryptoClientConfig::CachedState* cached =
- crypto_config_->LookupOrCreate(server_id_);
- QuicErrorCode error = crypto_config_->ProcessServerConfigUpdate(
- server_config_update, session()->connection()->clock()->WallNow(),
- session()->transport_version(), chlo_hash_, cached,
- crypto_negotiated_params_, &error_details);
-
- if (error != QUIC_NO_ERROR) {
- stream_->OnUnrecoverableError(
- error, "Server config update invalid: " + error_details);
- return;
- }
-
- QUICHE_DCHECK(one_rtt_keys_available());
- if (proof_verify_callback_) {
- proof_verify_callback_->Cancel();
- }
- next_state_ = STATE_INITIALIZE_SCUP;
- DoHandshakeLoop(nullptr);
-}
-
-void QuicCryptoClientHandshaker::DoHandshakeLoop(
- const CryptoHandshakeMessage* in) {
- QuicCryptoClientConfig::CachedState* cached =
- crypto_config_->LookupOrCreate(server_id_);
-
- QuicAsyncStatus rv = QUIC_SUCCESS;
- do {
- QUICHE_CHECK_NE(STATE_NONE, next_state_);
- const State state = next_state_;
- next_state_ = STATE_IDLE;
- rv = QUIC_SUCCESS;
- switch (state) {
- case STATE_INITIALIZE:
- DoInitialize(cached);
- break;
- case STATE_SEND_CHLO:
- DoSendCHLO(cached);
- return; // return waiting to hear from server.
- case STATE_RECV_REJ:
- DoReceiveREJ(in, cached);
- break;
- case STATE_VERIFY_PROOF:
- rv = DoVerifyProof(cached);
- break;
- case STATE_VERIFY_PROOF_COMPLETE:
- DoVerifyProofComplete(cached);
- break;
- case STATE_RECV_SHLO:
- DoReceiveSHLO(in, cached);
- break;
- case STATE_IDLE:
- // This means that the peer sent us a message that we weren't expecting.
- stream_->OnUnrecoverableError(QUIC_INVALID_CRYPTO_MESSAGE_TYPE,
- "Handshake in idle state");
- return;
- case STATE_INITIALIZE_SCUP:
- DoInitializeServerConfigUpdate(cached);
- break;
- case STATE_NONE:
- QUIC_NOTREACHED();
- return;
- case STATE_CONNECTION_CLOSED:
- rv = QUIC_FAILURE;
- return; // We are done.
- }
- } while (rv != QUIC_PENDING && next_state_ != STATE_NONE);
-}
-
-void QuicCryptoClientHandshaker::DoInitialize(
- QuicCryptoClientConfig::CachedState* cached) {
- if (!cached->IsEmpty() && !cached->signature().empty()) {
- // Note that we verify the proof even if the cached proof is valid.
- // This allows us to respond to CA trust changes or certificate
- // expiration because it may have been a while since we last verified
- // the proof.
- QUICHE_DCHECK(crypto_config_->proof_verifier());
- // Track proof verification time when cached server config is used.
- proof_verify_start_time_ = session()->connection()->clock()->Now();
- chlo_hash_ = cached->chlo_hash();
- // If the cached state needs to be verified, do it now.
- next_state_ = STATE_VERIFY_PROOF;
- } else {
- next_state_ = STATE_SEND_CHLO;
- }
-}
-
-void QuicCryptoClientHandshaker::DoSendCHLO(
- QuicCryptoClientConfig::CachedState* cached) {
- // Send the client hello in plaintext.
- session()->connection()->SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
- encryption_established_ = false;
- if (num_client_hellos_ >= QuicCryptoClientStream::kMaxClientHellos) {
- stream_->OnUnrecoverableError(
- QUIC_CRYPTO_TOO_MANY_REJECTS,
- absl::StrCat("More than ", QuicCryptoClientStream::kMaxClientHellos,
- " rejects"));
- return;
- }
- num_client_hellos_++;
-
- CryptoHandshakeMessage out;
- QUICHE_DCHECK(session() != nullptr);
- QUICHE_DCHECK(session()->config() != nullptr);
- // Send all the options, regardless of whether we're sending an
- // inchoate or subsequent hello.
- session()->config()->ToHandshakeMessage(&out, session()->transport_version());
-
- bool fill_inchoate_client_hello = false;
- if (!cached->IsComplete(session()->connection()->clock()->WallNow())) {
- early_data_reason_ = ssl_early_data_no_session_offered;
- fill_inchoate_client_hello = true;
- } else if (session()->config()->HasClientRequestedIndependentOption(
- kQNZ2, session()->perspective()) &&
- num_client_hellos_ == 1) {
- early_data_reason_ = ssl_early_data_disabled;
- fill_inchoate_client_hello = true;
- }
- if (fill_inchoate_client_hello) {
- crypto_config_->FillInchoateClientHello(
- server_id_, session()->supported_versions().front(), cached,
- session()->connection()->random_generator(),
- /* demand_x509_proof= */ true, crypto_negotiated_params_, &out);
- // Pad the inchoate client hello to fill up a packet.
- const QuicByteCount kFramingOverhead = 50; // A rough estimate.
- const QuicByteCount max_packet_size =
- session()->connection()->max_packet_length();
- if (max_packet_size <= kFramingOverhead) {
- QUIC_DLOG(DFATAL) << "max_packet_length (" << max_packet_size
- << ") has no room for framing overhead.";
- stream_->OnUnrecoverableError(QUIC_INTERNAL_ERROR,
- "max_packet_size too smalll");
- return;
- }
- if (kClientHelloMinimumSize > max_packet_size - kFramingOverhead) {
- QUIC_DLOG(DFATAL) << "Client hello won't fit in a single packet.";
- stream_->OnUnrecoverableError(QUIC_INTERNAL_ERROR, "CHLO too large");
- return;
- }
- next_state_ = STATE_RECV_REJ;
- chlo_hash_ = CryptoUtils::HashHandshakeMessage(out, Perspective::IS_CLIENT);
- session()->connection()->set_fully_pad_crypto_handshake_packets(
- crypto_config_->pad_inchoate_hello());
- SendHandshakeMessage(out, ENCRYPTION_INITIAL);
- return;
- }
-
- std::string error_details;
- QuicErrorCode error = crypto_config_->FillClientHello(
- server_id_, session()->connection()->connection_id(),
- session()->supported_versions().front(),
- session()->connection()->version(), cached,
- session()->connection()->clock()->WallNow(),
- session()->connection()->random_generator(), crypto_negotiated_params_,
- &out, &error_details);
- if (error != QUIC_NO_ERROR) {
- // Flush the cached config so that, if it's bad, the server has a
- // chance to send us another in the future.
- cached->InvalidateServerConfig();
- stream_->OnUnrecoverableError(error, error_details);
- return;
- }
- chlo_hash_ = CryptoUtils::HashHandshakeMessage(out, Perspective::IS_CLIENT);
- if (cached->proof_verify_details()) {
- proof_handler_->OnProofVerifyDetailsAvailable(
- *cached->proof_verify_details());
- }
- next_state_ = STATE_RECV_SHLO;
- session()->connection()->set_fully_pad_crypto_handshake_packets(
- crypto_config_->pad_full_hello());
- SendHandshakeMessage(out, ENCRYPTION_INITIAL);
- // Be prepared to decrypt with the new server write key.
- delegate_->OnNewEncryptionKeyAvailable(
- ENCRYPTION_ZERO_RTT,
- std::move(crypto_negotiated_params_->initial_crypters.encrypter));
- delegate_->OnNewDecryptionKeyAvailable(
- ENCRYPTION_ZERO_RTT,
- std::move(crypto_negotiated_params_->initial_crypters.decrypter),
- /*set_alternative_decrypter=*/true,
- /*latch_once_used=*/true);
- encryption_established_ = true;
- delegate_->SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
- if (early_data_reason_ == ssl_early_data_unknown && num_client_hellos_ > 1) {
- early_data_reason_ = ssl_early_data_peer_declined;
- }
-}
-
-void QuicCryptoClientHandshaker::DoReceiveREJ(
- const CryptoHandshakeMessage* in,
- QuicCryptoClientConfig::CachedState* cached) {
- // We sent a dummy CHLO because we didn't have enough information to
- // perform a handshake, or we sent a full hello that the server
- // rejected. Here we hope to have a REJ that contains the information
- // that we need.
- if (in->tag() != kREJ) {
- next_state_ = STATE_NONE;
- stream_->OnUnrecoverableError(QUIC_INVALID_CRYPTO_MESSAGE_TYPE,
- "Expected REJ");
- return;
- }
-
- QuicTagVector reject_reasons;
- static_assert(sizeof(QuicTag) == sizeof(uint32_t), "header out of sync");
- if (in->GetTaglist(kRREJ, &reject_reasons) == QUIC_NO_ERROR) {
- uint32_t packed_error = 0;
- for (size_t i = 0; i < reject_reasons.size(); ++i) {
- // HANDSHAKE_OK is 0 and don't report that as error.
- if (reject_reasons[i] == HANDSHAKE_OK || reject_reasons[i] >= 32) {
- continue;
- }
- HandshakeFailureReason reason =
- static_cast<HandshakeFailureReason>(reject_reasons[i]);
- packed_error |= 1 << (reason - 1);
- }
- QUIC_DVLOG(1) << "Reasons for rejection: " << packed_error;
- if (num_client_hellos_ == QuicCryptoClientStream::kMaxClientHellos) {
- QuicClientSparseHistogram("QuicClientHelloRejectReasons.TooMany",
- packed_error);
- }
- QuicClientSparseHistogram("QuicClientHelloRejectReasons.Secure",
- packed_error);
- }
-
- // Receipt of a REJ message means that the server received the CHLO
- // so we can cancel and retransmissions.
- delegate_->NeuterUnencryptedData();
-
- std::string error_details;
- QuicErrorCode error = crypto_config_->ProcessRejection(
- *in, session()->connection()->clock()->WallNow(),
- session()->transport_version(), chlo_hash_, cached,
- crypto_negotiated_params_, &error_details);
-
- if (error != QUIC_NO_ERROR) {
- next_state_ = STATE_NONE;
- stream_->OnUnrecoverableError(error, error_details);
- return;
- }
- if (!cached->proof_valid()) {
- if (!cached->signature().empty()) {
- // Note that we only verify the proof if the cached proof is not
- // valid. If the cached proof is valid here, someone else must have
- // just added the server config to the cache and verified the proof,
- // so we can assume no CA trust changes or certificate expiration
- // has happened since then.
- next_state_ = STATE_VERIFY_PROOF;
- return;
- }
- }
- next_state_ = STATE_SEND_CHLO;
-}
-
-QuicAsyncStatus QuicCryptoClientHandshaker::DoVerifyProof(
- QuicCryptoClientConfig::CachedState* cached) {
- ProofVerifier* verifier = crypto_config_->proof_verifier();
- QUICHE_DCHECK(verifier);
- next_state_ = STATE_VERIFY_PROOF_COMPLETE;
- generation_counter_ = cached->generation_counter();
-
- ProofVerifierCallbackImpl* proof_verify_callback =
- new ProofVerifierCallbackImpl(this);
-
- verify_ok_ = false;
-
- QuicAsyncStatus status = verifier->VerifyProof(
- server_id_.host(), server_id_.port(), cached->server_config(),
- session()->transport_version(), chlo_hash_, cached->certs(),
- cached->cert_sct(), cached->signature(), verify_context_.get(),
- &verify_error_details_, &verify_details_,
- std::unique_ptr<ProofVerifierCallback>(proof_verify_callback));
-
- switch (status) {
- case QUIC_PENDING:
- proof_verify_callback_ = proof_verify_callback;
- QUIC_DVLOG(1) << "Doing VerifyProof";
- break;
- case QUIC_FAILURE:
- break;
- case QUIC_SUCCESS:
- verify_ok_ = true;
- break;
- }
- return status;
-}
-
-void QuicCryptoClientHandshaker::DoVerifyProofComplete(
- QuicCryptoClientConfig::CachedState* cached) {
- if (proof_verify_start_time_.IsInitialized()) {
- QUIC_CLIENT_HISTOGRAM_TIMES(
- "QuicSession.VerifyProofTime.CachedServerConfig",
- (session()->connection()->clock()->Now() - proof_verify_start_time_),
- QuicTime::Delta::FromMilliseconds(1), QuicTime::Delta::FromSeconds(10),
- 50, "");
- }
- if (!verify_ok_) {
- if (verify_details_) {
- proof_handler_->OnProofVerifyDetailsAvailable(*verify_details_);
- }
- if (num_client_hellos_ == 0) {
- cached->Clear();
- next_state_ = STATE_INITIALIZE;
- return;
- }
- next_state_ = STATE_NONE;
- QUIC_CLIENT_HISTOGRAM_BOOL("QuicVerifyProofFailed.HandshakeConfirmed",
- one_rtt_keys_available(), "");
- stream_->OnUnrecoverableError(QUIC_PROOF_INVALID,
- "Proof invalid: " + verify_error_details_);
- return;
- }
-
- // Check if generation_counter has changed between STATE_VERIFY_PROOF and
- // STATE_VERIFY_PROOF_COMPLETE state changes.
- if (generation_counter_ != cached->generation_counter()) {
- next_state_ = STATE_VERIFY_PROOF;
- } else {
- SetCachedProofValid(cached);
- cached->SetProofVerifyDetails(verify_details_.release());
- if (!one_rtt_keys_available()) {
- next_state_ = STATE_SEND_CHLO;
- } else {
- next_state_ = STATE_NONE;
- }
- }
-}
-
-void QuicCryptoClientHandshaker::DoReceiveSHLO(
- const CryptoHandshakeMessage* in,
- QuicCryptoClientConfig::CachedState* cached) {
- next_state_ = STATE_NONE;
- // We sent a CHLO that we expected to be accepted and now we're
- // hoping for a SHLO from the server to confirm that. First check
- // to see whether the response was a reject, and if so, move on to
- // the reject-processing state.
- if (in->tag() == kREJ) {
- // A reject message must be sent in ENCRYPTION_INITIAL.
- if (session()->connection()->last_decrypted_level() != ENCRYPTION_INITIAL) {
- // The rejection was sent encrypted!
- stream_->OnUnrecoverableError(QUIC_CRYPTO_ENCRYPTION_LEVEL_INCORRECT,
- "encrypted REJ message");
- return;
- }
- next_state_ = STATE_RECV_REJ;
- return;
- }
-
- if (in->tag() != kSHLO) {
- stream_->OnUnrecoverableError(
- QUIC_INVALID_CRYPTO_MESSAGE_TYPE,
- absl::StrCat("Expected SHLO or REJ. Received: ",
- QuicTagToString(in->tag())));
- return;
- }
-
- if (session()->connection()->last_decrypted_level() == ENCRYPTION_INITIAL) {
- // The server hello was sent without encryption.
- stream_->OnUnrecoverableError(QUIC_CRYPTO_ENCRYPTION_LEVEL_INCORRECT,
- "unencrypted SHLO message");
- return;
- }
- if (num_client_hellos_ == 1) {
- early_data_reason_ = ssl_early_data_accepted;
- }
-
- std::string error_details;
- QuicErrorCode error = crypto_config_->ProcessServerHello(
- *in, session()->connection()->connection_id(),
- session()->connection()->version(),
- session()->connection()->server_supported_versions(), cached,
- crypto_negotiated_params_, &error_details);
-
- if (error != QUIC_NO_ERROR) {
- stream_->OnUnrecoverableError(error,
- "Server hello invalid: " + error_details);
- return;
- }
- error = session()->config()->ProcessPeerHello(*in, SERVER, &error_details);
- if (error != QUIC_NO_ERROR) {
- stream_->OnUnrecoverableError(error,
- "Server hello invalid: " + error_details);
- return;
- }
- session()->OnConfigNegotiated();
-
- CrypterPair* crypters = &crypto_negotiated_params_->forward_secure_crypters;
- // TODO(agl): we don't currently latch this decrypter because the idea
- // has been floated that the server shouldn't send packets encrypted
- // with the FORWARD_SECURE key until it receives a FORWARD_SECURE
- // packet from the client.
- delegate_->OnNewEncryptionKeyAvailable(ENCRYPTION_FORWARD_SECURE,
- std::move(crypters->encrypter));
- delegate_->OnNewDecryptionKeyAvailable(ENCRYPTION_FORWARD_SECURE,
- std::move(crypters->decrypter),
- /*set_alternative_decrypter=*/true,
- /*latch_once_used=*/false);
- one_rtt_keys_available_ = true;
- delegate_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
- delegate_->DiscardOldEncryptionKey(ENCRYPTION_INITIAL);
- delegate_->NeuterHandshakeData();
-}
-
-void QuicCryptoClientHandshaker::DoInitializeServerConfigUpdate(
- QuicCryptoClientConfig::CachedState* cached) {
- bool update_ignored = false;
- if (!cached->IsEmpty() && !cached->signature().empty()) {
- // Note that we verify the proof even if the cached proof is valid.
- QUICHE_DCHECK(crypto_config_->proof_verifier());
- next_state_ = STATE_VERIFY_PROOF;
- } else {
- update_ignored = true;
- next_state_ = STATE_NONE;
- }
- QUIC_CLIENT_HISTOGRAM_COUNTS("QuicNumServerConfig.UpdateMessagesIgnored",
- update_ignored, 1, 1000000, 50, "");
-}
-
-void QuicCryptoClientHandshaker::SetCachedProofValid(
- QuicCryptoClientConfig::CachedState* cached) {
- cached->SetProofValid();
- proof_handler_->OnProofValid(*cached);
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_crypto_client_handshaker.h b/chromium/net/third_party/quiche/src/quic/core/quic_crypto_client_handshaker.h
deleted file mode 100644
index c0c94b94cd8..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_crypto_client_handshaker.h
+++ /dev/null
@@ -1,211 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_CRYPTO_CLIENT_HANDSHAKER_H_
-#define QUICHE_QUIC_CORE_QUIC_CRYPTO_CLIENT_HANDSHAKER_H_
-
-#include <string>
-
-#include "quic/core/crypto/proof_verifier.h"
-#include "quic/core/crypto/quic_crypto_client_config.h"
-#include "quic/core/quic_crypto_client_stream.h"
-#include "quic/core/quic_server_id.h"
-#include "quic/platform/api/quic_export.h"
-#include "common/platform/api/quiche_logging.h"
-
-namespace quic {
-
-// An implementation of QuicCryptoClientStream::HandshakerInterface which uses
-// QUIC crypto as the crypto handshake protocol.
-class QUIC_EXPORT_PRIVATE QuicCryptoClientHandshaker
- : public QuicCryptoClientStream::HandshakerInterface,
- public QuicCryptoHandshaker {
- public:
- QuicCryptoClientHandshaker(
- const QuicServerId& server_id,
- QuicCryptoClientStream* stream,
- QuicSession* session,
- std::unique_ptr<ProofVerifyContext> verify_context,
- QuicCryptoClientConfig* crypto_config,
- QuicCryptoClientStream::ProofHandler* proof_handler);
- QuicCryptoClientHandshaker(const QuicCryptoClientHandshaker&) = delete;
- QuicCryptoClientHandshaker& operator=(const QuicCryptoClientHandshaker&) =
- delete;
-
- ~QuicCryptoClientHandshaker() override;
-
- // From QuicCryptoClientStream::HandshakerInterface
- bool CryptoConnect() override;
- int num_sent_client_hellos() const override;
- bool IsResumption() const override;
- bool EarlyDataAccepted() const override;
- ssl_early_data_reason_t EarlyDataReason() const override;
- bool ReceivedInchoateReject() const override;
- int num_scup_messages_received() const override;
- std::string chlo_hash() const override;
- bool encryption_established() const override;
- bool one_rtt_keys_available() const override;
- const QuicCryptoNegotiatedParameters& crypto_negotiated_params()
- const override;
- CryptoMessageParser* crypto_message_parser() override;
- HandshakeState GetHandshakeState() const override;
- size_t BufferSizeLimitForLevel(EncryptionLevel level) const override;
- std::unique_ptr<QuicDecrypter> AdvanceKeysAndCreateCurrentOneRttDecrypter()
- override;
- std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() override;
- void OnOneRttPacketAcknowledged() override {}
- void OnHandshakePacketSent() override {}
- void OnConnectionClosed(QuicErrorCode /*error*/,
- ConnectionCloseSource /*source*/) override;
- void OnHandshakeDoneReceived() override;
- void OnNewTokenReceived(absl::string_view token) override;
- void SetServerApplicationStateForResumption(
- std::unique_ptr<ApplicationState> /*application_state*/) override {
- QUICHE_NOTREACHED();
- }
- bool ExportKeyingMaterial(absl::string_view /*label*/,
- absl::string_view /*context*/,
- size_t /*result_len*/,
- std::string* /*result*/) override {
- QUICHE_NOTREACHED();
- return false;
- }
-
- // From QuicCryptoHandshaker
- void OnHandshakeMessage(const CryptoHandshakeMessage& message) override;
-
- protected:
- // Returns the QuicSession that this stream belongs to.
- QuicSession* session() const { return session_; }
-
- // Send either InchoateClientHello or ClientHello message to the server.
- void DoSendCHLO(QuicCryptoClientConfig::CachedState* cached);
-
- private:
- // ProofVerifierCallbackImpl is passed as the callback method to VerifyProof.
- // The ProofVerifier calls this class with the result of proof verification
- // when verification is performed asynchronously.
- class QUIC_EXPORT_PRIVATE ProofVerifierCallbackImpl
- : public ProofVerifierCallback {
- public:
- explicit ProofVerifierCallbackImpl(QuicCryptoClientHandshaker* parent);
- ~ProofVerifierCallbackImpl() override;
-
- // ProofVerifierCallback interface.
- void Run(bool ok,
- const std::string& error_details,
- std::unique_ptr<ProofVerifyDetails>* details) override;
-
- // Cancel causes any future callbacks to be ignored. It must be called on
- // the same thread as the callback will be made on.
- void Cancel();
-
- private:
- QuicCryptoClientHandshaker* parent_;
- };
-
- enum State {
- STATE_IDLE,
- STATE_INITIALIZE,
- STATE_SEND_CHLO,
- STATE_RECV_REJ,
- STATE_VERIFY_PROOF,
- STATE_VERIFY_PROOF_COMPLETE,
- STATE_RECV_SHLO,
- STATE_INITIALIZE_SCUP,
- STATE_NONE,
- STATE_CONNECTION_CLOSED,
- };
-
- // Handles new server config and optional source-address token provided by the
- // server during a connection.
- void HandleServerConfigUpdateMessage(
- const CryptoHandshakeMessage& server_config_update);
-
- // DoHandshakeLoop performs a step of the handshake state machine. Note that
- // |in| may be nullptr if the call did not result from a received message.
- void DoHandshakeLoop(const CryptoHandshakeMessage* in);
-
- // Start the handshake process.
- void DoInitialize(QuicCryptoClientConfig::CachedState* cached);
-
- // Process REJ message from the server.
- void DoReceiveREJ(const CryptoHandshakeMessage* in,
- QuicCryptoClientConfig::CachedState* cached);
-
- // Start the proof verification process. Returns the QuicAsyncStatus returned
- // by the ProofVerifier's VerifyProof.
- QuicAsyncStatus DoVerifyProof(QuicCryptoClientConfig::CachedState* cached);
-
- // If proof is valid then it sets the proof as valid (which persists the
- // server config). If not, it closes the connection.
- void DoVerifyProofComplete(QuicCryptoClientConfig::CachedState* cached);
-
- // Process SHLO message from the server.
- void DoReceiveSHLO(const CryptoHandshakeMessage* in,
- QuicCryptoClientConfig::CachedState* cached);
-
- // Start the proof verification if |server_id_| is https and |cached| has
- // signature.
- void DoInitializeServerConfigUpdate(
- QuicCryptoClientConfig::CachedState* cached);
-
- // Called to set the proof of |cached| valid. Also invokes the session's
- // OnProofValid() method.
- void SetCachedProofValid(QuicCryptoClientConfig::CachedState* cached);
-
- QuicCryptoClientStream* stream_;
-
- QuicSession* session_;
- HandshakerDelegateInterface* delegate_;
-
- State next_state_;
- // num_client_hellos_ contains the number of client hello messages that this
- // connection has sent.
- int num_client_hellos_;
-
- ssl_early_data_reason_t early_data_reason_ = ssl_early_data_unknown;
-
- QuicCryptoClientConfig* const crypto_config_;
-
- // SHA-256 hash of the most recently sent CHLO.
- std::string chlo_hash_;
-
- // Server's (hostname, port, is_https, privacy_mode) tuple.
- const QuicServerId server_id_;
-
- // Generation counter from QuicCryptoClientConfig's CachedState.
- uint64_t generation_counter_;
-
- // verify_context_ contains the context object that we pass to asynchronous
- // proof verifications.
- std::unique_ptr<ProofVerifyContext> verify_context_;
-
- // proof_verify_callback_ contains the callback object that we passed to an
- // asynchronous proof verification. The ProofVerifier owns this object.
- ProofVerifierCallbackImpl* proof_verify_callback_;
- // proof_handler_ contains the callback object used by a quic client
- // for proof verification. It is not owned by this class.
- QuicCryptoClientStream::ProofHandler* proof_handler_;
-
- // These members are used to store the result of an asynchronous proof
- // verification. These members must not be used after
- // STATE_VERIFY_PROOF_COMPLETE.
- bool verify_ok_;
- std::string verify_error_details_;
- std::unique_ptr<ProofVerifyDetails> verify_details_;
-
- QuicTime proof_verify_start_time_;
-
- int num_scup_messages_received_;
-
- bool encryption_established_;
- bool one_rtt_keys_available_;
- QuicReferenceCountedPointer<QuicCryptoNegotiatedParameters>
- crypto_negotiated_params_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_QUIC_CRYPTO_CLIENT_HANDSHAKER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_crypto_client_handshaker_test.cc b/chromium/net/third_party/quiche/src/quic/core/quic_crypto_client_handshaker_test.cc
deleted file mode 100644
index 120e5dae233..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_crypto_client_handshaker_test.cc
+++ /dev/null
@@ -1,238 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_crypto_client_handshaker.h"
-
-#include <utility>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/proto/crypto_server_config_proto.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/quic_test_utils.h"
-
-namespace quic {
-namespace {
-
-class TestProofHandler : public QuicCryptoClientStream::ProofHandler {
- public:
- ~TestProofHandler() override {}
- void OnProofValid(
- const QuicCryptoClientConfig::CachedState& /*cached*/) override {}
- void OnProofVerifyDetailsAvailable(
- const ProofVerifyDetails& /*verify_details*/) override {}
-};
-
-class InsecureProofVerifier : public ProofVerifier {
- public:
- InsecureProofVerifier() {}
- ~InsecureProofVerifier() override {}
-
- // ProofVerifier override.
- 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>* /*verify_details*/,
- std::unique_ptr<ProofVerifierCallback> /*callback*/) override {
- return QUIC_SUCCESS;
- }
-
- 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 {
- return QUIC_SUCCESS;
- }
-
- std::unique_ptr<ProofVerifyContext> CreateDefaultContext() override {
- return nullptr;
- }
-};
-
-class DummyProofSource : public ProofSource {
- public:
- DummyProofSource() {}
- ~DummyProofSource() override {}
-
- // ProofSource override.
- void GetProof(const QuicSocketAddress& server_address,
- const QuicSocketAddress& client_address,
- const std::string& hostname,
- const std::string& /*server_config*/,
- QuicTransportVersion /*transport_version*/,
- absl::string_view /*chlo_hash*/,
- std::unique_ptr<Callback> callback) override {
- bool cert_matched_sni;
- QuicReferenceCountedPointer<ProofSource::Chain> chain = GetCertChain(
- server_address, client_address, hostname, &cert_matched_sni);
- QuicCryptoProof proof;
- proof.signature = "Dummy signature";
- proof.leaf_cert_scts = "Dummy timestamp";
- proof.cert_matched_sni = cert_matched_sni;
- callback->Run(true, chain, proof, /*details=*/nullptr);
- }
-
- QuicReferenceCountedPointer<Chain> GetCertChain(
- const QuicSocketAddress& /*server_address*/,
- const QuicSocketAddress& /*client_address*/,
- const std::string& /*hostname*/, bool* /*cert_matched_sni*/) override {
- std::vector<std::string> certs;
- certs.push_back("Dummy cert");
- return QuicReferenceCountedPointer<ProofSource::Chain>(
- new ProofSource::Chain(certs));
- }
-
- void ComputeTlsSignature(
- const QuicSocketAddress& /*server_address*/,
- const QuicSocketAddress& /*client_address*/,
- const std::string& /*hostname*/,
- uint16_t /*signature_algorit*/,
- absl::string_view /*in*/,
- std::unique_ptr<SignatureCallback> callback) override {
- callback->Run(true, "Dummy signature", /*details=*/nullptr);
- }
-
- absl::InlinedVector<uint16_t, 8> SupportedTlsSignatureAlgorithms()
- const override {
- return {};
- }
-
- TicketCrypter* GetTicketCrypter() override { return nullptr; }
-};
-
-class Handshaker : public QuicCryptoClientHandshaker {
- public:
- Handshaker(const QuicServerId& server_id,
- QuicCryptoClientStream* stream,
- QuicSession* session,
- std::unique_ptr<ProofVerifyContext> verify_context,
- QuicCryptoClientConfig* crypto_config,
- QuicCryptoClientStream::ProofHandler* proof_handler)
- : QuicCryptoClientHandshaker(server_id,
- stream,
- session,
- std::move(verify_context),
- crypto_config,
- proof_handler) {}
-
- void DoSendCHLOTest(QuicCryptoClientConfig::CachedState* cached) {
- QuicCryptoClientHandshaker::DoSendCHLO(cached);
- }
-};
-
-class QuicCryptoClientHandshakerTest
- : public QuicTestWithParam<ParsedQuicVersion> {
- protected:
- QuicCryptoClientHandshakerTest()
- : version_(GetParam()),
- proof_handler_(),
- helper_(),
- alarm_factory_(),
- server_id_("host", 123),
- connection_(new test::MockQuicConnection(&helper_,
- &alarm_factory_,
- Perspective::IS_CLIENT,
- {version_})),
- session_(connection_, false),
- crypto_client_config_(std::make_unique<InsecureProofVerifier>()),
- client_stream_(
- new QuicCryptoClientStream(server_id_,
- &session_,
- nullptr,
- &crypto_client_config_,
- &proof_handler_,
- /*has_application_state = */ false)),
- handshaker_(server_id_,
- client_stream_,
- &session_,
- nullptr,
- &crypto_client_config_,
- &proof_handler_),
- state_() {
- // Session takes the ownership of the client stream! (but handshaker also
- // takes a reference to it, but doesn't take the ownership).
- session_.SetCryptoStream(client_stream_);
- session_.Initialize();
- }
-
- void InitializeServerParametersToEnableFullHello() {
- QuicCryptoServerConfig::ConfigOptions options;
- QuicServerConfigProtobuf config = QuicCryptoServerConfig::GenerateConfig(
- helper_.GetRandomGenerator(), helper_.GetClock(), options);
- state_.Initialize(
- config.config(), "sourcetoken", std::vector<std::string>{"Dummy cert"},
- "", "chlo_hash", "signature", helper_.GetClock()->WallNow(),
- helper_.GetClock()->WallNow().Add(QuicTime::Delta::FromSeconds(30)));
-
- state_.SetProofValid();
- }
-
- ParsedQuicVersion version_;
- TestProofHandler proof_handler_;
- test::MockQuicConnectionHelper helper_;
- test::MockAlarmFactory alarm_factory_;
- QuicServerId server_id_;
- // Session takes the ownership of the connection.
- test::MockQuicConnection* connection_;
- test::MockQuicSession session_;
- QuicCryptoClientConfig crypto_client_config_;
- QuicCryptoClientStream* client_stream_;
- Handshaker handshaker_;
- QuicCryptoClientConfig::CachedState state_;
-};
-
-INSTANTIATE_TEST_SUITE_P(
- QuicCryptoClientHandshakerTests,
- QuicCryptoClientHandshakerTest,
- ::testing::ValuesIn(AllSupportedVersionsWithQuicCrypto()),
- ::testing::PrintToStringParamName());
-
-TEST_P(QuicCryptoClientHandshakerTest, TestSendFullPaddingInInchoateHello) {
- handshaker_.DoSendCHLOTest(&state_);
-
- EXPECT_TRUE(connection_->fully_pad_during_crypto_handshake());
-}
-
-TEST_P(QuicCryptoClientHandshakerTest, TestDisabledPaddingInInchoateHello) {
- crypto_client_config_.set_pad_inchoate_hello(false);
- handshaker_.DoSendCHLOTest(&state_);
- EXPECT_FALSE(connection_->fully_pad_during_crypto_handshake());
-}
-
-TEST_P(QuicCryptoClientHandshakerTest,
- TestPaddingInFullHelloEvenIfInchoateDisabled) {
- // Disable inchoate, but full hello should still be padded.
- crypto_client_config_.set_pad_inchoate_hello(false);
-
- InitializeServerParametersToEnableFullHello();
-
- handshaker_.DoSendCHLOTest(&state_);
- EXPECT_TRUE(connection_->fully_pad_during_crypto_handshake());
-}
-
-TEST_P(QuicCryptoClientHandshakerTest, TestNoPaddingInFullHelloWhenDisabled) {
- crypto_client_config_.set_pad_full_hello(false);
-
- InitializeServerParametersToEnableFullHello();
-
- handshaker_.DoSendCHLOTest(&state_);
- EXPECT_FALSE(connection_->fully_pad_during_crypto_handshake());
-}
-
-} // namespace
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_crypto_client_stream.cc b/chromium/net/third_party/quiche/src/quic/core/quic_crypto_client_stream.cc
deleted file mode 100644
index 27a2a469ace..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_crypto_client_stream.cc
+++ /dev/null
@@ -1,169 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_crypto_client_stream.h"
-
-#include <memory>
-#include <string>
-#include <utility>
-
-#include "quic/core/crypto/crypto_protocol.h"
-#include "quic/core/crypto/crypto_utils.h"
-#include "quic/core/crypto/null_encrypter.h"
-#include "quic/core/crypto/quic_crypto_client_config.h"
-#include "quic/core/quic_crypto_client_handshaker.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_session.h"
-#include "quic/core/quic_utils.h"
-#include "quic/core/tls_client_handshaker.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-const int QuicCryptoClientStream::kMaxClientHellos;
-
-QuicCryptoClientStreamBase::QuicCryptoClientStreamBase(QuicSession* session)
- : QuicCryptoStream(session) {}
-
-QuicCryptoClientStream::QuicCryptoClientStream(
- const QuicServerId& server_id,
- QuicSession* session,
- std::unique_ptr<ProofVerifyContext> verify_context,
- QuicCryptoClientConfig* crypto_config,
- ProofHandler* proof_handler,
- bool has_application_state)
- : QuicCryptoClientStreamBase(session) {
- QUICHE_DCHECK_EQ(Perspective::IS_CLIENT,
- session->connection()->perspective());
- switch (session->connection()->version().handshake_protocol) {
- case PROTOCOL_QUIC_CRYPTO:
- handshaker_ = std::make_unique<QuicCryptoClientHandshaker>(
- server_id, this, session, std::move(verify_context), crypto_config,
- proof_handler);
- break;
- case PROTOCOL_TLS1_3: {
- auto handshaker = std::make_unique<TlsClientHandshaker>(
- server_id, this, session, std::move(verify_context), crypto_config,
- proof_handler, has_application_state);
- tls_handshaker_ = handshaker.get();
- handshaker_ = std::move(handshaker);
- break;
- }
- case PROTOCOL_UNSUPPORTED:
- QUIC_BUG(quic_bug_10296_1)
- << "Attempting to create QuicCryptoClientStream for unknown "
- "handshake protocol";
- }
-}
-
-QuicCryptoClientStream::~QuicCryptoClientStream() {}
-
-bool QuicCryptoClientStream::CryptoConnect() {
- return handshaker_->CryptoConnect();
-}
-
-int QuicCryptoClientStream::num_sent_client_hellos() const {
- return handshaker_->num_sent_client_hellos();
-}
-
-bool QuicCryptoClientStream::IsResumption() const {
- return handshaker_->IsResumption();
-}
-
-bool QuicCryptoClientStream::EarlyDataAccepted() const {
- return handshaker_->EarlyDataAccepted();
-}
-
-ssl_early_data_reason_t QuicCryptoClientStream::EarlyDataReason() const {
- return handshaker_->EarlyDataReason();
-}
-
-bool QuicCryptoClientStream::ReceivedInchoateReject() const {
- return handshaker_->ReceivedInchoateReject();
-}
-
-int QuicCryptoClientStream::num_scup_messages_received() const {
- return handshaker_->num_scup_messages_received();
-}
-
-bool QuicCryptoClientStream::encryption_established() const {
- return handshaker_->encryption_established();
-}
-
-bool QuicCryptoClientStream::one_rtt_keys_available() const {
- return handshaker_->one_rtt_keys_available();
-}
-
-const QuicCryptoNegotiatedParameters&
-QuicCryptoClientStream::crypto_negotiated_params() const {
- return handshaker_->crypto_negotiated_params();
-}
-
-CryptoMessageParser* QuicCryptoClientStream::crypto_message_parser() {
- return handshaker_->crypto_message_parser();
-}
-
-HandshakeState QuicCryptoClientStream::GetHandshakeState() const {
- return handshaker_->GetHandshakeState();
-}
-
-size_t QuicCryptoClientStream::BufferSizeLimitForLevel(
- EncryptionLevel level) const {
- return handshaker_->BufferSizeLimitForLevel(level);
-}
-
-std::unique_ptr<QuicDecrypter>
-QuicCryptoClientStream::AdvanceKeysAndCreateCurrentOneRttDecrypter() {
- return handshaker_->AdvanceKeysAndCreateCurrentOneRttDecrypter();
-}
-
-std::unique_ptr<QuicEncrypter>
-QuicCryptoClientStream::CreateCurrentOneRttEncrypter() {
- return handshaker_->CreateCurrentOneRttEncrypter();
-}
-
-bool QuicCryptoClientStream::ExportKeyingMaterial(absl::string_view label,
- absl::string_view context,
- size_t result_len,
- std::string* result) {
- return handshaker_->ExportKeyingMaterial(label, context, result_len, result);
-}
-
-std::string QuicCryptoClientStream::chlo_hash() const {
- return handshaker_->chlo_hash();
-}
-
-void QuicCryptoClientStream::OnOneRttPacketAcknowledged() {
- handshaker_->OnOneRttPacketAcknowledged();
-}
-
-void QuicCryptoClientStream::OnHandshakePacketSent() {
- handshaker_->OnHandshakePacketSent();
-}
-
-void QuicCryptoClientStream::OnConnectionClosed(QuicErrorCode error,
- ConnectionCloseSource source) {
- handshaker_->OnConnectionClosed(error, source);
-}
-
-void QuicCryptoClientStream::OnHandshakeDoneReceived() {
- handshaker_->OnHandshakeDoneReceived();
-}
-
-void QuicCryptoClientStream::OnNewTokenReceived(absl::string_view token) {
- handshaker_->OnNewTokenReceived(token);
-}
-
-void QuicCryptoClientStream::SetServerApplicationStateForResumption(
- std::unique_ptr<ApplicationState> application_state) {
- handshaker_->SetServerApplicationStateForResumption(
- std::move(application_state));
-}
-
-SSL* QuicCryptoClientStream::GetSsl() const {
- return tls_handshaker_ == nullptr ? nullptr : tls_handshaker_->ssl();
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_crypto_client_stream.h b/chromium/net/third_party/quiche/src/quic/core/quic_crypto_client_stream.h
deleted file mode 100644
index 34928b61f81..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_crypto_client_stream.h
+++ /dev/null
@@ -1,307 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_CRYPTO_CLIENT_STREAM_H_
-#define QUICHE_QUIC_CORE_QUIC_CRYPTO_CLIENT_STREAM_H_
-
-#include <cstdint>
-#include <memory>
-#include <string>
-
-#include "quic/core/crypto/proof_verifier.h"
-#include "quic/core/crypto/quic_crypto_client_config.h"
-#include "quic/core/proto/cached_network_parameters_proto.h"
-#include "quic/core/quic_config.h"
-#include "quic/core/quic_crypto_handshaker.h"
-#include "quic/core/quic_crypto_stream.h"
-#include "quic/core/quic_server_id.h"
-#include "quic/core/quic_session.h"
-#include "quic/core/quic_versions.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-namespace test {
-class QuicCryptoClientStreamPeer;
-} // namespace test
-
-class TlsClientHandshaker;
-
-class QUIC_EXPORT_PRIVATE QuicCryptoClientStreamBase : public QuicCryptoStream {
- public:
- explicit QuicCryptoClientStreamBase(QuicSession* session);
-
- ~QuicCryptoClientStreamBase() override {}
-
- // Performs a crypto handshake with the server. Returns true if the connection
- // is still connected.
- virtual bool CryptoConnect() = 0;
-
- // DEPRECATED: Use IsResumption, EarlyDataAccepted, and/or
- // ReceivedInchoateReject instead.
- //
- // num_sent_client_hellos returns the number of client hello messages that
- // have been sent. If the handshake has completed then this is one greater
- // than the number of round-trips needed for the handshake.
- virtual int num_sent_client_hellos() const = 0;
-
- // Returns true if the handshake performed was a resumption instead of a full
- // handshake. Resumption only makes sense for TLS handshakes - there is no
- // concept of resumption for QUIC crypto even though it supports a 0-RTT
- // handshake. This function only returns valid results once the handshake is
- // complete.
- virtual bool IsResumption() const = 0;
-
- // Returns true if early data (0-RTT) was accepted in the connection.
- virtual bool EarlyDataAccepted() const = 0;
-
- // Returns true if the client received an inchoate REJ during the handshake,
- // extending the handshake by one round trip. This only applies for QUIC
- // crypto handshakes. The equivalent feature in IETF QUIC is a Retry packet,
- // but that is handled at the connection layer instead of the crypto layer.
- virtual bool ReceivedInchoateReject() const = 0;
-
- // The number of server config update messages received by the
- // client. Does not count update messages that were received prior
- // to handshake confirmation.
- virtual int num_scup_messages_received() const = 0;
-
- bool ExportKeyingMaterial(absl::string_view /*label*/,
- absl::string_view /*context*/,
- size_t /*result_len*/,
- std::string* /*result*/) override {
- QUICHE_NOTREACHED();
- return false;
- }
-
- std::string GetAddressToken(
- const CachedNetworkParameters* /*cached_network_params*/) const override {
- QUICHE_DCHECK(false);
- return "";
- }
-
- bool ValidateAddressToken(absl::string_view /*token*/) const override {
- QUICHE_DCHECK(false);
- return false;
- }
-
- const CachedNetworkParameters* PreviousCachedNetworkParams() const override {
- QUICHE_DCHECK(false);
- return nullptr;
- }
-
- void SetPreviousCachedNetworkParams(
- CachedNetworkParameters /*cached_network_params*/) override {
- QUICHE_DCHECK(false);
- }
-};
-
-class QUIC_EXPORT_PRIVATE QuicCryptoClientStream
- : public QuicCryptoClientStreamBase {
- public:
- // kMaxClientHellos is the maximum number of times that we'll send a client
- // hello. The value 4 accounts for:
- // * One failure due to an incorrect or missing source-address token.
- // * One failure due the server's certificate chain being unavailible and
- // the server being unwilling to send it without a valid source-address
- // token.
- // * One failure due to the ServerConfig private key being located on a
- // remote oracle which has become unavailable, forcing the server to send
- // the client a fallback ServerConfig.
- static const int kMaxClientHellos = 4;
-
- // QuicCryptoClientStream creates a HandshakerInterface at construction time
- // based on the QuicTransportVersion of the connection. Different
- // HandshakerInterfaces provide implementations of different crypto handshake
- // protocols. Currently QUIC crypto is the only protocol implemented; a future
- // HandshakerInterface will use TLS as the handshake protocol.
- // QuicCryptoClientStream delegates all of its public methods to its
- // HandshakerInterface.
- //
- // This setup of the crypto stream delegating its implementation to the
- // handshaker results in the handshaker reading and writing bytes on the
- // crypto stream, instead of the handshaker passing the stream bytes to send.
- class QUIC_EXPORT_PRIVATE HandshakerInterface {
- public:
- virtual ~HandshakerInterface() {}
-
- // Performs a crypto handshake with the server. Returns true if the
- // connection is still connected.
- virtual bool CryptoConnect() = 0;
-
- // DEPRECATED: Use IsResumption, EarlyDataAccepted, and/or
- // ReceivedInchoateReject instead.
- //
- // num_sent_client_hellos returns the number of client hello messages that
- // have been sent. If the handshake has completed then this is one greater
- // than the number of round-trips needed for the handshake.
- virtual int num_sent_client_hellos() const = 0;
-
- // Returns true if the handshake performed was a resumption instead of a
- // full handshake. Resumption only makes sense for TLS handshakes - there is
- // no concept of resumption for QUIC crypto even though it supports a 0-RTT
- // handshake. This function only returns valid results once the handshake is
- // complete.
- virtual bool IsResumption() const = 0;
-
- // Returns true if early data (0-RTT) was accepted in the connection.
- virtual bool EarlyDataAccepted() const = 0;
-
- // Returns the ssl_early_data_reason_t describing why 0-RTT was accepted or
- // rejected.
- virtual ssl_early_data_reason_t EarlyDataReason() const = 0;
-
- // Returns true if the client received an inchoate REJ during the handshake,
- // extending the handshake by one round trip. This only applies for QUIC
- // crypto handshakes. The equivalent feature in IETF QUIC is a Retry packet,
- // but that is handled at the connection layer instead of the crypto layer.
- virtual bool ReceivedInchoateReject() const = 0;
-
- // The number of server config update messages received by the
- // client. Does not count update messages that were received prior
- // to handshake confirmation.
- virtual int num_scup_messages_received() const = 0;
-
- virtual std::string chlo_hash() const = 0;
-
- // Returns true once any encrypter (initial/0RTT or final/1RTT) has been set
- // for the connection.
- virtual bool encryption_established() const = 0;
-
- // Returns true once 1RTT keys are available.
- virtual bool one_rtt_keys_available() const = 0;
-
- // Returns the parameters negotiated in the crypto handshake.
- virtual const QuicCryptoNegotiatedParameters& crypto_negotiated_params()
- const = 0;
-
- // Used by QuicCryptoStream to parse data received on this stream.
- virtual CryptoMessageParser* crypto_message_parser() = 0;
-
- // Used by QuicCryptoStream to know how much unprocessed data can be
- // buffered at each encryption level.
- virtual size_t BufferSizeLimitForLevel(EncryptionLevel level) const = 0;
-
- // Called to generate a decrypter for the next key phase. Each call should
- // generate the key for phase n+1.
- virtual std::unique_ptr<QuicDecrypter>
- AdvanceKeysAndCreateCurrentOneRttDecrypter() = 0;
-
- // Called to generate an encrypter for the same key phase of the last
- // decrypter returned by AdvanceKeysAndCreateCurrentOneRttDecrypter().
- virtual std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() = 0;
-
- // Returns current handshake state.
- virtual HandshakeState GetHandshakeState() const = 0;
-
- // Called when a 1RTT packet has been acknowledged.
- virtual void OnOneRttPacketAcknowledged() = 0;
-
- // Called when a packet of ENCRYPTION_HANDSHAKE gets sent.
- virtual void OnHandshakePacketSent() = 0;
-
- // Called when connection gets closed.
- virtual void OnConnectionClosed(QuicErrorCode error,
- ConnectionCloseSource source) = 0;
-
- // Called when handshake done has been received.
- virtual void OnHandshakeDoneReceived() = 0;
-
- // Called when new token has been received.
- virtual void OnNewTokenReceived(absl::string_view token) = 0;
-
- // Called when application state is received.
- virtual void SetServerApplicationStateForResumption(
- std::unique_ptr<ApplicationState> application_state) = 0;
-
- // Called to obtain keying material export of length |result_len| with the
- // given |label| and |context|. Returns false on failure.
- virtual bool ExportKeyingMaterial(absl::string_view label,
- absl::string_view context,
- size_t result_len,
- std::string* result) = 0;
- };
-
- // ProofHandler is an interface that handles callbacks from the crypto
- // stream when the client has proof verification details of the server.
- class QUIC_EXPORT_PRIVATE ProofHandler {
- public:
- virtual ~ProofHandler() {}
-
- // Called when the proof in |cached| is marked valid. If this is a secure
- // QUIC session, then this will happen only after the proof verifier
- // completes.
- virtual void OnProofValid(
- const QuicCryptoClientConfig::CachedState& cached) = 0;
-
- // Called when proof verification details become available, either because
- // proof verification is complete, or when cached details are used. This
- // will only be called for secure QUIC connections.
- virtual void OnProofVerifyDetailsAvailable(
- const ProofVerifyDetails& verify_details) = 0;
- };
-
- QuicCryptoClientStream(const QuicServerId& server_id,
- QuicSession* session,
- std::unique_ptr<ProofVerifyContext> verify_context,
- QuicCryptoClientConfig* crypto_config,
- ProofHandler* proof_handler,
- bool has_application_state);
- QuicCryptoClientStream(const QuicCryptoClientStream&) = delete;
- QuicCryptoClientStream& operator=(const QuicCryptoClientStream&) = delete;
-
- ~QuicCryptoClientStream() override;
-
- // From QuicCryptoClientStreamBase
- bool CryptoConnect() override;
- int num_sent_client_hellos() const override;
- bool IsResumption() const override;
- bool EarlyDataAccepted() const override;
- ssl_early_data_reason_t EarlyDataReason() const override;
- bool ReceivedInchoateReject() const override;
-
- int num_scup_messages_received() const override;
-
- // From QuicCryptoStream
- bool encryption_established() const override;
- bool one_rtt_keys_available() const override;
- const QuicCryptoNegotiatedParameters& crypto_negotiated_params()
- const override;
- CryptoMessageParser* crypto_message_parser() override;
- void OnPacketDecrypted(EncryptionLevel /*level*/) override {}
- void OnOneRttPacketAcknowledged() override;
- void OnHandshakePacketSent() override;
- void OnConnectionClosed(QuicErrorCode error,
- ConnectionCloseSource source) override;
- void OnHandshakeDoneReceived() override;
- void OnNewTokenReceived(absl::string_view token) override;
- HandshakeState GetHandshakeState() const override;
- void SetServerApplicationStateForResumption(
- std::unique_ptr<ApplicationState> application_state) override;
- size_t BufferSizeLimitForLevel(EncryptionLevel level) const override;
- std::unique_ptr<QuicDecrypter> AdvanceKeysAndCreateCurrentOneRttDecrypter()
- override;
- std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() override;
- SSL* GetSsl() 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;
-
- protected:
- void set_handshaker(std::unique_ptr<HandshakerInterface> handshaker) {
- handshaker_ = std::move(handshaker);
- }
-
- private:
- friend class test::QuicCryptoClientStreamPeer;
- std::unique_ptr<HandshakerInterface> handshaker_;
- // Points to |handshaker_| if it uses TLS1.3. Otherwise, nullptr.
- // TODO(danzh) change the type of |handshaker_| to TlsClientHandshaker after
- // deprecating Google QUIC.
- TlsClientHandshaker* tls_handshaker_{nullptr};
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_QUIC_CRYPTO_CLIENT_STREAM_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_crypto_client_stream_test.cc b/chromium/net/third_party/quiche/src/quic/core/quic_crypto_client_stream_test.cc
deleted file mode 100644
index ac0a4fc6a9d..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_crypto_client_stream_test.cc
+++ /dev/null
@@ -1,371 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_crypto_client_stream.h"
-
-#include <memory>
-#include <string>
-#include <utility>
-
-#include "absl/base/macros.h"
-#include "quic/core/crypto/aes_128_gcm_12_encrypter.h"
-#include "quic/core/crypto/quic_decrypter.h"
-#include "quic/core/crypto/quic_encrypter.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_server_id.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/crypto_test_utils.h"
-#include "quic/test_tools/quic_stream_peer.h"
-#include "quic/test_tools/quic_stream_sequencer_peer.h"
-#include "quic/test_tools/quic_test_utils.h"
-#include "quic/test_tools/simple_quic_framer.h"
-#include "quic/test_tools/simple_session_cache.h"
-#include "common/test_tools/quiche_test_utils.h"
-
-using testing::_;
-
-namespace quic {
-namespace test {
-namespace {
-
-const char kServerHostname[] = "test.example.com";
-const uint16_t kServerPort = 443;
-
-// This test tests the client-side of the QUIC crypto handshake. It does not
-// test the TLS handshake - that is in tls_client_handshaker_test.cc.
-class QuicCryptoClientStreamTest : public QuicTest {
- public:
- QuicCryptoClientStreamTest()
- : supported_versions_(AllSupportedVersionsWithQuicCrypto()),
- server_id_(kServerHostname, kServerPort, false),
- crypto_config_(crypto_test_utils::ProofVerifierForTesting(),
- std::make_unique<test::SimpleSessionCache>()),
- server_crypto_config_(
- crypto_test_utils::CryptoServerConfigForTesting()) {
- CreateConnection();
- }
-
- void CreateSession() {
- session_ = std::make_unique<TestQuicSpdyClientSession>(
- connection_, DefaultQuicConfig(), supported_versions_, server_id_,
- &crypto_config_);
- EXPECT_CALL(*session_, GetAlpnsToOffer())
- .WillRepeatedly(testing::Return(std::vector<std::string>(
- {AlpnForVersion(connection_->version())})));
- }
-
- void CreateConnection() {
- connection_ =
- new PacketSavingConnection(&client_helper_, &alarm_factory_,
- Perspective::IS_CLIENT, supported_versions_);
- // Advance the time, because timers do not like uninitialized times.
- connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
- CreateSession();
- }
-
- void CompleteCryptoHandshake() {
- int proof_verify_details_calls = 1;
- if (stream()->handshake_protocol() != PROTOCOL_TLS1_3) {
- EXPECT_CALL(*session_, OnProofValid(testing::_))
- .Times(testing::AtLeast(1));
- proof_verify_details_calls = 0;
- }
- EXPECT_CALL(*session_, OnProofVerifyDetailsAvailable(testing::_))
- .Times(testing::AtLeast(proof_verify_details_calls));
- stream()->CryptoConnect();
- QuicConfig config;
- crypto_test_utils::HandshakeWithFakeServer(
- &config, server_crypto_config_.get(), &server_helper_, &alarm_factory_,
- connection_, stream(), AlpnForVersion(connection_->version()));
- }
-
- QuicCryptoClientStream* stream() {
- return session_->GetMutableCryptoStream();
- }
-
- MockQuicConnectionHelper server_helper_;
- MockQuicConnectionHelper client_helper_;
- MockAlarmFactory alarm_factory_;
- PacketSavingConnection* connection_;
- ParsedQuicVersionVector supported_versions_;
- std::unique_ptr<TestQuicSpdyClientSession> session_;
- QuicServerId server_id_;
- CryptoHandshakeMessage message_;
- QuicCryptoClientConfig crypto_config_;
- std::unique_ptr<QuicCryptoServerConfig> server_crypto_config_;
-};
-
-TEST_F(QuicCryptoClientStreamTest, NotInitiallyConected) {
- EXPECT_FALSE(stream()->encryption_established());
- EXPECT_FALSE(stream()->one_rtt_keys_available());
-}
-
-TEST_F(QuicCryptoClientStreamTest, ConnectedAfterSHLO) {
- CompleteCryptoHandshake();
- EXPECT_TRUE(stream()->encryption_established());
- EXPECT_TRUE(stream()->one_rtt_keys_available());
- EXPECT_FALSE(stream()->IsResumption());
- EXPECT_EQ(stream()->EarlyDataReason(), ssl_early_data_no_session_offered);
-}
-
-TEST_F(QuicCryptoClientStreamTest, MessageAfterHandshake) {
- CompleteCryptoHandshake();
-
- EXPECT_CALL(
- *connection_,
- CloseConnection(QUIC_CRYPTO_MESSAGE_AFTER_HANDSHAKE_COMPLETE, _, _));
- message_.set_tag(kCHLO);
- crypto_test_utils::SendHandshakeMessageToStream(stream(), message_,
- Perspective::IS_CLIENT);
-}
-
-TEST_F(QuicCryptoClientStreamTest, BadMessageType) {
- stream()->CryptoConnect();
-
- message_.set_tag(kCHLO);
-
- EXPECT_CALL(*connection_, CloseConnection(QUIC_INVALID_CRYPTO_MESSAGE_TYPE,
- "Expected REJ", _));
- crypto_test_utils::SendHandshakeMessageToStream(stream(), message_,
- Perspective::IS_CLIENT);
-}
-
-TEST_F(QuicCryptoClientStreamTest, NegotiatedParameters) {
- CompleteCryptoHandshake();
-
- const QuicConfig* config = session_->config();
- EXPECT_EQ(kMaximumIdleTimeoutSecs, config->IdleNetworkTimeout().ToSeconds());
-
- const QuicCryptoNegotiatedParameters& crypto_params(
- stream()->crypto_negotiated_params());
- EXPECT_EQ(crypto_config_.aead[0], crypto_params.aead);
- EXPECT_EQ(crypto_config_.kexs[0], crypto_params.key_exchange);
-}
-
-TEST_F(QuicCryptoClientStreamTest, ExpiredServerConfig) {
- // Seed the config with a cached server config.
- CompleteCryptoHandshake();
-
- // Recreate connection with the new config.
- CreateConnection();
-
- // Advance time 5 years to ensure that we pass the expiry time of the cached
- // server config.
- connection_->AdvanceTime(
- QuicTime::Delta::FromSeconds(60 * 60 * 24 * 365 * 5));
-
- EXPECT_CALL(*session_, OnProofValid(testing::_));
- stream()->CryptoConnect();
- // Check that a client hello was sent.
- ASSERT_EQ(1u, connection_->encrypted_packets_.size());
- EXPECT_EQ(ENCRYPTION_INITIAL, connection_->encryption_level());
-}
-
-TEST_F(QuicCryptoClientStreamTest, ClientTurnedOffZeroRtt) {
- // Seed the config with a cached server config.
- CompleteCryptoHandshake();
-
- // Recreate connection with the new config.
- CreateConnection();
-
- // Set connection option.
- QuicTagVector options;
- options.push_back(kQNZ2);
- session_->config()->SetClientConnectionOptions(options);
-
- CompleteCryptoHandshake();
- // Check that two client hellos were sent, one inchoate and one normal.
- EXPECT_EQ(2, stream()->num_sent_client_hellos());
- EXPECT_FALSE(stream()->EarlyDataAccepted());
- EXPECT_EQ(stream()->EarlyDataReason(), ssl_early_data_disabled);
-}
-
-TEST_F(QuicCryptoClientStreamTest, ClockSkew) {
- // Test that if the client's clock is skewed with respect to the server,
- // the handshake succeeds. In the past, the client would get the server
- // config, notice that it had already expired and then close the connection.
-
- // Advance time 5 years to ensure that we pass the expiry time in the server
- // config, but the TTL is used instead.
- connection_->AdvanceTime(
- QuicTime::Delta::FromSeconds(60 * 60 * 24 * 365 * 5));
-
- // The handshakes completes!
- CompleteCryptoHandshake();
-}
-
-TEST_F(QuicCryptoClientStreamTest, InvalidCachedServerConfig) {
- // Seed the config with a cached server config.
- CompleteCryptoHandshake();
-
- // Recreate connection with the new config.
- CreateConnection();
-
- QuicCryptoClientConfig::CachedState* state =
- crypto_config_.LookupOrCreate(server_id_);
-
- std::vector<std::string> certs = state->certs();
- std::string cert_sct = state->cert_sct();
- std::string signature = state->signature();
- std::string chlo_hash = state->chlo_hash();
- state->SetProof(certs, cert_sct, chlo_hash, signature + signature);
-
- EXPECT_CALL(*session_, OnProofVerifyDetailsAvailable(testing::_))
- .Times(testing::AnyNumber());
- stream()->CryptoConnect();
- // Check that a client hello was sent.
- ASSERT_EQ(1u, connection_->encrypted_packets_.size());
-}
-
-TEST_F(QuicCryptoClientStreamTest, ServerConfigUpdate) {
- // Test that the crypto client stream can receive server config updates after
- // the connection has been established.
- CompleteCryptoHandshake();
-
- QuicCryptoClientConfig::CachedState* state =
- crypto_config_.LookupOrCreate(server_id_);
-
- // Ensure cached STK is different to what we send in the handshake.
- EXPECT_NE("xstk", state->source_address_token());
-
- // Initialize using {...} syntax to avoid trailing \0 if converting from
- // string.
- unsigned char stk[] = {'x', 's', 't', 'k'};
-
- // Minimum SCFG that passes config validation checks.
- unsigned char scfg[] = {// SCFG
- 0x53, 0x43, 0x46, 0x47,
- // num entries
- 0x01, 0x00,
- // padding
- 0x00, 0x00,
- // EXPY
- 0x45, 0x58, 0x50, 0x59,
- // EXPY end offset
- 0x08, 0x00, 0x00, 0x00,
- // Value
- '1', '2', '3', '4', '5', '6', '7', '8'};
-
- CryptoHandshakeMessage server_config_update;
- server_config_update.set_tag(kSCUP);
- server_config_update.SetValue(kSourceAddressTokenTag, stk);
- server_config_update.SetValue(kSCFG, scfg);
- const uint64_t expiry_seconds = 60 * 60 * 24 * 2;
- server_config_update.SetValue(kSTTL, expiry_seconds);
-
- crypto_test_utils::SendHandshakeMessageToStream(
- stream(), server_config_update, Perspective::IS_SERVER);
-
- // Make sure that the STK and SCFG are cached correctly.
- EXPECT_EQ("xstk", state->source_address_token());
-
- const std::string& cached_scfg = state->server_config();
- quiche::test::CompareCharArraysWithHexError(
- "scfg", cached_scfg.data(), cached_scfg.length(),
- reinterpret_cast<char*>(scfg), ABSL_ARRAYSIZE(scfg));
-
- QuicStreamSequencer* sequencer = QuicStreamPeer::sequencer(stream());
- EXPECT_FALSE(QuicStreamSequencerPeer::IsUnderlyingBufferAllocated(sequencer));
-}
-
-TEST_F(QuicCryptoClientStreamTest, ServerConfigUpdateWithCert) {
- // Test that the crypto client stream can receive and use server config
- // updates with certificates after the connection has been established.
- CompleteCryptoHandshake();
-
- // Build a server config update message with certificates
- QuicCryptoServerConfig crypto_config(
- QuicCryptoServerConfig::TESTING, QuicRandom::GetInstance(),
- crypto_test_utils::ProofSourceForTesting(), KeyExchangeSource::Default());
- crypto_test_utils::SetupCryptoServerConfigForTest(
- connection_->clock(), QuicRandom::GetInstance(), &crypto_config);
- SourceAddressTokens tokens;
- QuicCompressedCertsCache cache(1);
- CachedNetworkParameters network_params;
- CryptoHandshakeMessage server_config_update;
-
- class Callback : public BuildServerConfigUpdateMessageResultCallback {
- public:
- Callback(bool* ok, CryptoHandshakeMessage* message)
- : ok_(ok), message_(message) {}
- void Run(bool ok, const CryptoHandshakeMessage& message) override {
- *ok_ = ok;
- *message_ = message;
- }
-
- private:
- bool* ok_;
- CryptoHandshakeMessage* message_;
- };
-
- // Note: relies on the callback being invoked synchronously
- bool ok = false;
- crypto_config.BuildServerConfigUpdateMessage(
- session_->transport_version(), stream()->chlo_hash(), tokens,
- QuicSocketAddress(QuicIpAddress::Loopback6(), 1234),
- QuicSocketAddress(QuicIpAddress::Loopback6(), 4321), connection_->clock(),
- QuicRandom::GetInstance(), &cache, stream()->crypto_negotiated_params(),
- &network_params,
- std::unique_ptr<BuildServerConfigUpdateMessageResultCallback>(
- new Callback(&ok, &server_config_update)));
- EXPECT_TRUE(ok);
-
- EXPECT_CALL(*session_, OnProofValid(testing::_));
- crypto_test_utils::SendHandshakeMessageToStream(
- stream(), server_config_update, Perspective::IS_SERVER);
-
- // Recreate connection with the new config and verify a 0-RTT attempt.
- CreateConnection();
-
- EXPECT_CALL(*session_, OnProofValid(testing::_));
- EXPECT_CALL(*session_, OnProofVerifyDetailsAvailable(testing::_))
- .Times(testing::AnyNumber());
- stream()->CryptoConnect();
- EXPECT_TRUE(session_->IsEncryptionEstablished());
-}
-
-TEST_F(QuicCryptoClientStreamTest, ServerConfigUpdateBeforeHandshake) {
- EXPECT_CALL(
- *connection_,
- CloseConnection(QUIC_CRYPTO_UPDATE_BEFORE_HANDSHAKE_COMPLETE, _, _));
- CryptoHandshakeMessage server_config_update;
- server_config_update.set_tag(kSCUP);
- crypto_test_utils::SendHandshakeMessageToStream(
- stream(), server_config_update, Perspective::IS_SERVER);
-}
-
-TEST_F(QuicCryptoClientStreamTest, PreferredVersion) {
- // This mimics the case where client receives version negotiation packet, such
- // that, the preferred version is different from the packets' version.
- connection_ = new PacketSavingConnection(
- &client_helper_, &alarm_factory_, Perspective::IS_CLIENT,
- ParsedVersionOfIndex(supported_versions_, 1));
- connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
-
- CreateSession();
- CompleteCryptoHandshake();
- // 2 CHLOs are sent.
- ASSERT_EQ(2u, session_->sent_crypto_handshake_messages().size());
- // Verify preferred version is the highest version that session supports, and
- // is different from connection's version.
- QuicVersionLabel client_version_label;
- EXPECT_THAT(session_->sent_crypto_handshake_messages()[0].GetVersionLabel(
- kVER, &client_version_label),
- IsQuicNoError());
- EXPECT_EQ(CreateQuicVersionLabel(supported_versions_[0]),
- client_version_label);
- EXPECT_THAT(session_->sent_crypto_handshake_messages()[1].GetVersionLabel(
- kVER, &client_version_label),
- IsQuicNoError());
- EXPECT_EQ(CreateQuicVersionLabel(supported_versions_[0]),
- client_version_label);
- EXPECT_NE(CreateQuicVersionLabel(connection_->version()),
- client_version_label);
-}
-
-} // namespace
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_crypto_handshaker.cc b/chromium/net/third_party/quiche/src/quic/core/quic_crypto_handshaker.cc
deleted file mode 100644
index 79142c4681e..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_crypto_handshaker.cc
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_crypto_handshaker.h"
-
-#include "quic/core/quic_session.h"
-
-namespace quic {
-
-#define ENDPOINT \
- (session()->perspective() == Perspective::IS_SERVER ? "Server: " : "Client: ")
-
-QuicCryptoHandshaker::QuicCryptoHandshaker(QuicCryptoStream* stream,
- QuicSession* session)
- : stream_(stream), session_(session), last_sent_handshake_message_tag_(0) {
- crypto_framer_.set_visitor(this);
-}
-
-QuicCryptoHandshaker::~QuicCryptoHandshaker() {}
-
-void QuicCryptoHandshaker::SendHandshakeMessage(
- const CryptoHandshakeMessage& message,
- EncryptionLevel level) {
- QUIC_DVLOG(1) << ENDPOINT << "Sending " << message.DebugString();
- session()->NeuterUnencryptedData();
- session()->OnCryptoHandshakeMessageSent(message);
- last_sent_handshake_message_tag_ = message.tag();
- const QuicData& data = message.GetSerialized();
- stream_->WriteCryptoData(level, data.AsStringPiece());
-}
-
-void QuicCryptoHandshaker::OnError(CryptoFramer* framer) {
- QUIC_DLOG(WARNING) << "Error processing crypto data: "
- << QuicErrorCodeToString(framer->error());
-}
-
-void QuicCryptoHandshaker::OnHandshakeMessage(
- const CryptoHandshakeMessage& message) {
- QUIC_DVLOG(1) << ENDPOINT << "Received " << message.DebugString();
- session()->OnCryptoHandshakeMessageReceived(message);
-}
-
-CryptoMessageParser* QuicCryptoHandshaker::crypto_message_parser() {
- return &crypto_framer_;
-}
-
-size_t QuicCryptoHandshaker::BufferSizeLimitForLevel(EncryptionLevel) const {
- return GetQuicFlag(FLAGS_quic_max_buffered_crypto_bytes);
-}
-
-#undef ENDPOINT // undef for jumbo builds
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_crypto_handshaker.h b/chromium/net/third_party/quiche/src/quic/core/quic_crypto_handshaker.h
deleted file mode 100644
index b5077d9566d..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_crypto_handshaker.h
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_CRYPTO_HANDSHAKER_H_
-#define QUICHE_QUIC_CORE_QUIC_CRYPTO_HANDSHAKER_H_
-
-#include "quic/core/quic_crypto_stream.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-class QUIC_EXPORT_PRIVATE QuicCryptoHandshaker
- : public CryptoFramerVisitorInterface {
- public:
- QuicCryptoHandshaker(QuicCryptoStream* stream, QuicSession* session);
- QuicCryptoHandshaker(const QuicCryptoHandshaker&) = delete;
- QuicCryptoHandshaker& operator=(const QuicCryptoHandshaker&) = delete;
-
- ~QuicCryptoHandshaker() override;
-
- // Sends |message| to the peer.
- // TODO(wtc): return a success/failure status.
- void SendHandshakeMessage(const CryptoHandshakeMessage& message,
- EncryptionLevel level);
-
- void OnError(CryptoFramer* framer) override;
- void OnHandshakeMessage(const CryptoHandshakeMessage& message) override;
-
- CryptoMessageParser* crypto_message_parser();
- size_t BufferSizeLimitForLevel(EncryptionLevel level) const;
-
- protected:
- QuicTag last_sent_handshake_message_tag() const {
- return last_sent_handshake_message_tag_;
- }
-
- private:
- QuicSession* session() { return session_; }
-
- QuicCryptoStream* stream_;
- QuicSession* session_;
-
- CryptoFramer crypto_framer_;
-
- // Records last sent crypto handshake message tag.
- QuicTag last_sent_handshake_message_tag_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_QUIC_CRYPTO_HANDSHAKER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_crypto_server_stream.cc b/chromium/net/third_party/quiche/src/quic/core/quic_crypto_server_stream.cc
deleted file mode 100644
index 55b7bf1a703..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_crypto_server_stream.cc
+++ /dev/null
@@ -1,529 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_crypto_server_stream.h"
-
-#include <memory>
-#include <string>
-
-#include "absl/base/macros.h"
-#include "absl/strings/string_view.h"
-#include "third_party/boringssl/src/include/openssl/sha.h"
-#include "quic/platform/api/quic_flag_utils.h"
-#include "quic/platform/api/quic_testvalue.h"
-#include "common/quiche_text_utils.h"
-
-namespace quic {
-
-class QuicCryptoServerStream::ProcessClientHelloCallback
- : public ProcessClientHelloResultCallback {
- public:
- ProcessClientHelloCallback(
- QuicCryptoServerStream* parent,
- const QuicReferenceCountedPointer<
- ValidateClientHelloResultCallback::Result>& result)
- : parent_(parent), result_(result) {}
-
- void Run(
- QuicErrorCode error,
- const std::string& error_details,
- std::unique_ptr<CryptoHandshakeMessage> message,
- std::unique_ptr<DiversificationNonce> diversification_nonce,
- std::unique_ptr<ProofSource::Details> proof_source_details) override {
- if (parent_ == nullptr) {
- return;
- }
-
- parent_->FinishProcessingHandshakeMessageAfterProcessClientHello(
- *result_, error, error_details, std::move(message),
- std::move(diversification_nonce), std::move(proof_source_details));
- }
-
- void Cancel() { parent_ = nullptr; }
-
- private:
- QuicCryptoServerStream* parent_;
- QuicReferenceCountedPointer<ValidateClientHelloResultCallback::Result>
- result_;
-};
-
-QuicCryptoServerStream::QuicCryptoServerStream(
- const QuicCryptoServerConfig* crypto_config,
- QuicCompressedCertsCache* compressed_certs_cache,
- QuicSession* session,
- QuicCryptoServerStreamBase::Helper* helper)
- : QuicCryptoServerStreamBase(session),
- QuicCryptoHandshaker(this, session),
- session_(session),
- delegate_(session),
- crypto_config_(crypto_config),
- compressed_certs_cache_(compressed_certs_cache),
- signed_config_(new QuicSignedServerConfig),
- helper_(helper),
- num_handshake_messages_(0),
- num_handshake_messages_with_server_nonces_(0),
- send_server_config_update_cb_(nullptr),
- num_server_config_update_messages_sent_(0),
- 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),
- crypto_negotiated_params_(new QuicCryptoNegotiatedParameters) {}
-
-QuicCryptoServerStream::~QuicCryptoServerStream() {
- CancelOutstandingCallbacks();
-}
-
-void QuicCryptoServerStream::CancelOutstandingCallbacks() {
- // Detach from the validation callback. Calling this multiple times is safe.
- if (validate_client_hello_cb_ != nullptr) {
- validate_client_hello_cb_->Cancel();
- validate_client_hello_cb_ = nullptr;
- }
- if (send_server_config_update_cb_ != nullptr) {
- 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;
- }
-}
-
-void QuicCryptoServerStream::OnHandshakeMessage(
- const CryptoHandshakeMessage& message) {
- QuicCryptoHandshaker::OnHandshakeMessage(message);
- ++num_handshake_messages_;
- chlo_packet_size_ = session()->connection()->GetCurrentPacket().length();
-
- // Do not process handshake messages after the handshake is confirmed.
- if (one_rtt_keys_available_) {
- OnUnrecoverableError(QUIC_CRYPTO_MESSAGE_AFTER_HANDSHAKE_COMPLETE,
- "Unexpected handshake message from client");
- return;
- }
-
- if (message.tag() != kCHLO) {
- OnUnrecoverableError(QUIC_INVALID_CRYPTO_MESSAGE_TYPE,
- "Handshake packet not CHLO");
- return;
- }
-
- if (validate_client_hello_cb_ != nullptr ||
- process_client_hello_cb_ != nullptr) {
- // 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.
- OnUnrecoverableError(QUIC_CRYPTO_MESSAGE_WHILE_VALIDATING_CLIENT_HELLO,
- "Unexpected handshake message while processing CHLO");
- return;
- }
-
- chlo_hash_ =
- CryptoUtils::HashHandshakeMessage(message, Perspective::IS_SERVER);
-
- std::unique_ptr<ValidateCallback> cb(new ValidateCallback(this));
- QUICHE_DCHECK(validate_client_hello_cb_ == nullptr);
- QUICHE_DCHECK(process_client_hello_cb_ == nullptr);
- validate_client_hello_cb_ = cb.get();
- crypto_config_->ValidateClientHello(
- message, GetClientAddress(), session()->connection()->self_address(),
- transport_version(), session()->connection()->clock(), signed_config_,
- std::move(cb));
-}
-
-void QuicCryptoServerStream::FinishProcessingHandshakeMessage(
- QuicReferenceCountedPointer<ValidateClientHelloResultCallback::Result>
- result,
- 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);
- validate_client_hello_cb_ = nullptr;
-
- std::unique_ptr<ProcessClientHelloCallback> cb(
- new ProcessClientHelloCallback(this, result));
- process_client_hello_cb_ = cb.get();
- ProcessClientHello(result, std::move(details), std::move(cb));
-}
-
-void QuicCryptoServerStream::
- FinishProcessingHandshakeMessageAfterProcessClientHello(
- const ValidateClientHelloResultCallback::Result& result,
- QuicErrorCode error,
- const std::string& error_details,
- std::unique_ptr<CryptoHandshakeMessage> reply,
- 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(validate_client_hello_cb_ == nullptr);
- process_client_hello_cb_ = nullptr;
- proof_source_details_ = std::move(proof_source_details);
-
- AdjustTestValue("quic::QuicCryptoServerStream::after_process_client_hello",
- session());
-
- if (noop_if_disconnected_after_process_chlo_) {
- QUIC_RELOADABLE_FLAG_COUNT(
- quic_crypto_noop_if_disconnected_after_process_chlo);
- if (!session()->connection()->connected()) {
- QUIC_CODE_COUNT(quic_crypto_disconnected_after_process_client_hello);
- QUIC_LOG_FIRST_N(INFO, 10)
- << "After processing CHLO, QUIC connection has been closed with code "
- << session()->error() << ", details: " << session()->error_details();
- return;
- }
- }
-
- const CryptoHandshakeMessage& message = result.client_hello;
- if (error != QUIC_NO_ERROR) {
- OnUnrecoverableError(error, error_details);
- return;
- }
-
- if (reply->tag() != kSHLO) {
- session()->connection()->set_fully_pad_crypto_handshake_packets(
- crypto_config_->pad_rej());
- // Send REJ in plaintext.
- SendHandshakeMessage(*reply, ENCRYPTION_INITIAL);
- return;
- }
-
- // If we are returning a SHLO then we accepted the handshake. Now
- // process the negotiated configuration options as part of the
- // session config.
- QuicConfig* config = session()->config();
- OverrideQuicConfigDefaults(config);
- std::string process_error_details;
- const QuicErrorCode process_error =
- config->ProcessPeerHello(message, CLIENT, &process_error_details);
- if (process_error != QUIC_NO_ERROR) {
- OnUnrecoverableError(process_error, process_error_details);
- return;
- }
-
- session()->OnConfigNegotiated();
-
- config->ToHandshakeMessage(reply.get(), session()->transport_version());
-
- // Receiving a full CHLO implies the client is prepared to decrypt with
- // the new server write key. We can start to encrypt with the new server
- // write key.
- //
- // NOTE: the SHLO will be encrypted with the new server write key.
- delegate_->OnNewEncryptionKeyAvailable(
- ENCRYPTION_ZERO_RTT,
- std::move(crypto_negotiated_params_->initial_crypters.encrypter));
- delegate_->OnNewDecryptionKeyAvailable(
- ENCRYPTION_ZERO_RTT,
- std::move(crypto_negotiated_params_->initial_crypters.decrypter),
- /*set_alternative_decrypter=*/false,
- /*latch_once_used=*/false);
- delegate_->SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
- delegate_->DiscardOldDecryptionKey(ENCRYPTION_INITIAL);
- session()->connection()->SetDiversificationNonce(*diversification_nonce);
-
- session()->connection()->set_fully_pad_crypto_handshake_packets(
- crypto_config_->pad_shlo());
- // Send SHLO in ENCRYPTION_ZERO_RTT.
- SendHandshakeMessage(*reply, ENCRYPTION_ZERO_RTT);
- delegate_->OnNewEncryptionKeyAvailable(
- ENCRYPTION_FORWARD_SECURE,
- std::move(crypto_negotiated_params_->forward_secure_crypters.encrypter));
- delegate_->OnNewDecryptionKeyAvailable(
- ENCRYPTION_FORWARD_SECURE,
- std::move(crypto_negotiated_params_->forward_secure_crypters.decrypter),
- /*set_alternative_decrypter=*/true,
- /*latch_once_used=*/false);
- encryption_established_ = true;
- one_rtt_keys_available_ = true;
- delegate_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
- delegate_->DiscardOldEncryptionKey(ENCRYPTION_INITIAL);
-}
-
-void QuicCryptoServerStream::SendServerConfigUpdate(
- const CachedNetworkParameters* cached_network_params) {
- if (!one_rtt_keys_available_) {
- return;
- }
-
- if (send_server_config_update_cb_ != nullptr) {
- QUIC_DVLOG(1)
- << "Skipped server config update since one is already in progress";
- return;
- }
-
- std::unique_ptr<SendServerConfigUpdateCallback> cb(
- new SendServerConfigUpdateCallback(this));
- send_server_config_update_cb_ = cb.get();
-
- crypto_config_->BuildServerConfigUpdateMessage(
- session()->transport_version(), chlo_hash_,
- previous_source_address_tokens_, session()->connection()->self_address(),
- GetClientAddress(), session()->connection()->clock(),
- session()->connection()->random_generator(), compressed_certs_cache_,
- *crypto_negotiated_params_, cached_network_params, std::move(cb));
-}
-
-QuicCryptoServerStream::SendServerConfigUpdateCallback::
- SendServerConfigUpdateCallback(QuicCryptoServerStream* parent)
- : parent_(parent) {}
-
-void QuicCryptoServerStream::SendServerConfigUpdateCallback::Cancel() {
- parent_ = nullptr;
-}
-
-// From BuildServerConfigUpdateMessageResultCallback
-void QuicCryptoServerStream::SendServerConfigUpdateCallback::Run(
- bool ok,
- const CryptoHandshakeMessage& message) {
- if (parent_ == nullptr) {
- return;
- }
- parent_->FinishSendServerConfigUpdate(ok, message);
-}
-
-void QuicCryptoServerStream::FinishSendServerConfigUpdate(
- bool ok,
- const CryptoHandshakeMessage& message) {
- // Clear the callback that got us here.
- QUICHE_DCHECK(send_server_config_update_cb_ != nullptr);
- send_server_config_update_cb_ = nullptr;
-
- if (!ok) {
- QUIC_DVLOG(1) << "Server: Failed to build server config update (SCUP)!";
- return;
- }
-
- QUIC_DVLOG(1) << "Server: Sending server config update: "
- << message.DebugString();
-
- // Send server config update in ENCRYPTION_FORWARD_SECURE.
- SendHandshakeMessage(message, ENCRYPTION_FORWARD_SECURE);
-
- ++num_server_config_update_messages_sent_;
-}
-
-bool QuicCryptoServerStream::IsZeroRtt() const {
- return num_handshake_messages_ == 1 &&
- num_handshake_messages_with_server_nonces_ == 0;
-}
-
-bool QuicCryptoServerStream::IsResumption() const {
- // QUIC Crypto doesn't have a non-0-RTT resumption mode.
- return IsZeroRtt();
-}
-
-int QuicCryptoServerStream::NumServerConfigUpdateMessagesSent() const {
- return num_server_config_update_messages_sent_;
-}
-
-const CachedNetworkParameters*
-QuicCryptoServerStream::PreviousCachedNetworkParams() const {
- return previous_cached_network_params_.get();
-}
-
-bool QuicCryptoServerStream::ResumptionAttempted() const {
- return zero_rtt_attempted_;
-}
-
-void QuicCryptoServerStream::SetPreviousCachedNetworkParams(
- CachedNetworkParameters cached_network_params) {
- previous_cached_network_params_.reset(
- new CachedNetworkParameters(cached_network_params));
-}
-
-void QuicCryptoServerStream::OnPacketDecrypted(EncryptionLevel level) {
- if (level == ENCRYPTION_FORWARD_SECURE) {
- one_rtt_packet_decrypted_ = true;
- delegate_->NeuterHandshakeData();
- }
-}
-
-void QuicCryptoServerStream::OnHandshakeDoneReceived() {
- QUICHE_DCHECK(false);
-}
-
-void QuicCryptoServerStream::OnNewTokenReceived(absl::string_view /*token*/) {
- QUICHE_DCHECK(false);
-}
-
-std::string QuicCryptoServerStream::GetAddressToken(
- const CachedNetworkParameters* /*cached_network_parameters*/) const {
- QUICHE_DCHECK(false);
- return "";
-}
-
-bool QuicCryptoServerStream::ValidateAddressToken(
- absl::string_view /*token*/) const {
- QUICHE_DCHECK(false);
- return false;
-}
-
-bool QuicCryptoServerStream::ShouldSendExpectCTHeader() const {
- return signed_config_->proof.send_expect_ct_header;
-}
-
-bool QuicCryptoServerStream::DidCertMatchSni() const {
- return signed_config_->proof.cert_matched_sni;
-}
-
-const ProofSource::Details* QuicCryptoServerStream::ProofSourceDetails() const {
- return proof_source_details_.get();
-}
-
-bool QuicCryptoServerStream::GetBase64SHA256ClientChannelID(
- std::string* output) const {
- if (!encryption_established() ||
- crypto_negotiated_params_->channel_id.empty()) {
- return false;
- }
-
- const std::string& channel_id(crypto_negotiated_params_->channel_id);
- uint8_t digest[SHA256_DIGEST_LENGTH];
- SHA256(reinterpret_cast<const uint8_t*>(channel_id.data()), channel_id.size(),
- digest);
-
- quiche::QuicheTextUtils::Base64Encode(digest, ABSL_ARRAYSIZE(digest), output);
- return true;
-}
-
-ssl_early_data_reason_t QuicCryptoServerStream::EarlyDataReason() const {
- if (IsZeroRtt()) {
- return ssl_early_data_accepted;
- }
- if (zero_rtt_attempted_) {
- return ssl_early_data_session_not_resumed;
- }
- return ssl_early_data_no_session_offered;
-}
-
-bool QuicCryptoServerStream::encryption_established() const {
- return encryption_established_;
-}
-
-bool QuicCryptoServerStream::one_rtt_keys_available() const {
- return one_rtt_keys_available_;
-}
-
-const QuicCryptoNegotiatedParameters&
-QuicCryptoServerStream::crypto_negotiated_params() const {
- return *crypto_negotiated_params_;
-}
-
-CryptoMessageParser* QuicCryptoServerStream::crypto_message_parser() {
- return QuicCryptoHandshaker::crypto_message_parser();
-}
-
-HandshakeState QuicCryptoServerStream::GetHandshakeState() const {
- return one_rtt_packet_decrypted_ ? HANDSHAKE_COMPLETE : HANDSHAKE_START;
-}
-
-void QuicCryptoServerStream::SetServerApplicationStateForResumption(
- std::unique_ptr<ApplicationState> /*state*/) {
- // QUIC Crypto doesn't need to remember any application state as part of doing
- // 0-RTT resumption, so this function is a no-op.
-}
-
-size_t QuicCryptoServerStream::BufferSizeLimitForLevel(
- EncryptionLevel level) const {
- return QuicCryptoHandshaker::BufferSizeLimitForLevel(level);
-}
-
-std::unique_ptr<QuicDecrypter>
-QuicCryptoServerStream::AdvanceKeysAndCreateCurrentOneRttDecrypter() {
- // Key update is only defined in QUIC+TLS.
- QUICHE_DCHECK(false);
- return nullptr;
-}
-
-std::unique_ptr<QuicEncrypter>
-QuicCryptoServerStream::CreateCurrentOneRttEncrypter() {
- // Key update is only defined in QUIC+TLS.
- QUICHE_DCHECK(false);
- return nullptr;
-}
-
-void QuicCryptoServerStream::ProcessClientHello(
- QuicReferenceCountedPointer<ValidateClientHelloResultCallback::Result>
- result,
- std::unique_ptr<ProofSource::Details> proof_source_details,
- std::unique_ptr<ProcessClientHelloResultCallback> done_cb) {
- proof_source_details_ = std::move(proof_source_details);
- const CryptoHandshakeMessage& message = result->client_hello;
- std::string error_details;
- if (!helper_->CanAcceptClientHello(
- message, GetClientAddress(), session()->connection()->peer_address(),
- session()->connection()->self_address(), &error_details)) {
- done_cb->Run(QUIC_HANDSHAKE_FAILED, error_details, nullptr, nullptr,
- nullptr);
- return;
- }
-
- absl::string_view user_agent_id;
- message.GetStringPiece(quic::kUAID, &user_agent_id);
- if (!session()->user_agent_id().has_value() && !user_agent_id.empty()) {
- session()->SetUserAgentId(std::string(user_agent_id));
- }
-
- if (!result->info.server_nonce.empty()) {
- ++num_handshake_messages_with_server_nonces_;
- }
-
- if (num_handshake_messages_ == 1) {
- // Client attempts zero RTT handshake by sending a non-inchoate CHLO.
- absl::string_view public_value;
- zero_rtt_attempted_ = message.GetStringPiece(kPUBS, &public_value);
- }
-
- // Store the bandwidth estimate from the client.
- if (result->cached_network_params.bandwidth_estimate_bytes_per_second() > 0) {
- previous_cached_network_params_.reset(
- new CachedNetworkParameters(result->cached_network_params));
- }
- previous_source_address_tokens_ = result->info.source_address_tokens;
-
- QuicConnection* connection = session()->connection();
- crypto_config_->ProcessClientHello(
- result, /*reject_only=*/false, connection->connection_id(),
- connection->self_address(), GetClientAddress(), connection->version(),
- session()->supported_versions(), connection->clock(),
- connection->random_generator(), compressed_certs_cache_,
- crypto_negotiated_params_, signed_config_,
- QuicCryptoStream::CryptoMessageFramingOverhead(
- transport_version(), connection->connection_id()),
- chlo_packet_size_, std::move(done_cb));
-}
-
-void QuicCryptoServerStream::OverrideQuicConfigDefaults(
- QuicConfig* /*config*/) {}
-
-QuicCryptoServerStream::ValidateCallback::ValidateCallback(
- QuicCryptoServerStream* parent)
- : parent_(parent) {}
-
-void QuicCryptoServerStream::ValidateCallback::Cancel() {
- parent_ = nullptr;
-}
-
-void QuicCryptoServerStream::ValidateCallback::Run(
- QuicReferenceCountedPointer<Result> result,
- std::unique_ptr<ProofSource::Details> details) {
- if (parent_ != nullptr) {
- parent_->FinishProcessingHandshakeMessage(std::move(result),
- std::move(details));
- }
-}
-
-const QuicSocketAddress QuicCryptoServerStream::GetClientAddress() {
- return session()->connection()->peer_address();
-}
-
-SSL* QuicCryptoServerStream::GetSsl() const { return nullptr; }
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_crypto_server_stream.h b/chromium/net/third_party/quiche/src/quic/core/quic_crypto_server_stream.h
deleted file mode 100644
index aca9e9a1170..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_crypto_server_stream.h
+++ /dev/null
@@ -1,265 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_CRYPTO_SERVER_STREAM_H_
-#define QUICHE_QUIC_CORE_QUIC_CRYPTO_SERVER_STREAM_H_
-
-#include <string>
-
-#include "quic/core/proto/cached_network_parameters_proto.h"
-#include "quic/core/proto/source_address_token_proto.h"
-#include "quic/core/quic_crypto_handshaker.h"
-#include "quic/core/quic_crypto_server_stream_base.h"
-#include "quic/core/quic_session.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-namespace test {
-class QuicCryptoServerStreamPeer;
-} // namespace test
-
-class QUIC_EXPORT_PRIVATE QuicCryptoServerStream
- : public QuicCryptoServerStreamBase,
- public QuicCryptoHandshaker {
- public:
- QuicCryptoServerStream(const QuicCryptoServerStream&) = delete;
- QuicCryptoServerStream& operator=(const QuicCryptoServerStream&) = delete;
-
- ~QuicCryptoServerStream() override;
-
- // From QuicCryptoServerStreamBase
- void CancelOutstandingCallbacks() override;
- bool GetBase64SHA256ClientChannelID(std::string* output) const override;
- void SendServerConfigUpdate(
- const CachedNetworkParameters* cached_network_params) override;
- bool IsZeroRtt() const override;
- bool IsResumption() const override;
- bool ResumptionAttempted() const override;
- int NumServerConfigUpdateMessagesSent() const override;
- const CachedNetworkParameters* PreviousCachedNetworkParams() const override;
- void SetPreviousCachedNetworkParams(
- CachedNetworkParameters cached_network_params) override;
- void OnPacketDecrypted(EncryptionLevel level) override;
- void OnOneRttPacketAcknowledged() override {}
- void OnHandshakePacketSent() override {}
- void OnConnectionClosed(QuicErrorCode /*error*/,
- ConnectionCloseSource /*source*/) override {}
- void OnHandshakeDoneReceived() override;
- void OnNewTokenReceived(absl::string_view token) override;
- std::string GetAddressToken(
- const CachedNetworkParameters* /*cached_network_params*/) const override;
- bool ValidateAddressToken(absl::string_view token) const override;
- bool ShouldSendExpectCTHeader() const override;
- bool DidCertMatchSni() const override;
- const ProofSource::Details* ProofSourceDetails() const override;
-
- // From QuicCryptoStream
- ssl_early_data_reason_t EarlyDataReason() const override;
- bool encryption_established() const override;
- bool one_rtt_keys_available() const override;
- const QuicCryptoNegotiatedParameters& crypto_negotiated_params()
- const override;
- CryptoMessageParser* crypto_message_parser() override;
- HandshakeState GetHandshakeState() const override;
- void SetServerApplicationStateForResumption(
- std::unique_ptr<ApplicationState> state) override;
- size_t BufferSizeLimitForLevel(EncryptionLevel level) const override;
- std::unique_ptr<QuicDecrypter> AdvanceKeysAndCreateCurrentOneRttDecrypter()
- override;
- std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() override;
- SSL* GetSsl() const override;
-
- // From QuicCryptoHandshaker
- void OnHandshakeMessage(const CryptoHandshakeMessage& message) override;
-
- protected:
- QUIC_EXPORT_PRIVATE friend std::unique_ptr<QuicCryptoServerStreamBase>
- CreateCryptoServerStream(const QuicCryptoServerConfig* crypto_config,
- QuicCompressedCertsCache* compressed_certs_cache,
- QuicSession* session,
- QuicCryptoServerStreamBase::Helper* helper);
-
- // |crypto_config| must outlive the stream.
- // |session| must outlive the stream.
- // |helper| must outlive the stream.
- QuicCryptoServerStream(const QuicCryptoServerConfig* crypto_config,
- QuicCompressedCertsCache* compressed_certs_cache,
- QuicSession* session,
- QuicCryptoServerStreamBase::Helper* helper);
-
- virtual void ProcessClientHello(
- QuicReferenceCountedPointer<ValidateClientHelloResultCallback::Result>
- result,
- std::unique_ptr<ProofSource::Details> proof_source_details,
- std::unique_ptr<ProcessClientHelloResultCallback> done_cb);
-
- // Hook that allows the server to set QuicConfig defaults just
- // before going through the parameter negotiation step.
- virtual void OverrideQuicConfigDefaults(QuicConfig* config);
-
- // Returns client address used to generate and validate source address token.
- virtual const QuicSocketAddress GetClientAddress();
-
- // Returns the QuicSession that this stream belongs to.
- QuicSession* session() const { return session_; }
-
- void set_encryption_established(bool encryption_established) {
- encryption_established_ = encryption_established;
- }
-
- void set_one_rtt_keys_available(bool one_rtt_keys_available) {
- one_rtt_keys_available_ = one_rtt_keys_available;
- }
-
- private:
- friend class test::QuicCryptoServerStreamPeer;
-
- class QUIC_EXPORT_PRIVATE ValidateCallback
- : public ValidateClientHelloResultCallback {
- public:
- explicit ValidateCallback(QuicCryptoServerStream* parent);
- ValidateCallback(const ValidateCallback&) = delete;
- ValidateCallback& operator=(const ValidateCallback&) = delete;
- // To allow the parent to detach itself from the callback before deletion.
- void Cancel();
-
- // From ValidateClientHelloResultCallback
- void Run(QuicReferenceCountedPointer<Result> result,
- std::unique_ptr<ProofSource::Details> details) override;
-
- private:
- QuicCryptoServerStream* parent_;
- };
-
- class SendServerConfigUpdateCallback
- : public BuildServerConfigUpdateMessageResultCallback {
- public:
- explicit SendServerConfigUpdateCallback(QuicCryptoServerStream* parent);
- SendServerConfigUpdateCallback(const SendServerConfigUpdateCallback&) =
- delete;
- void operator=(const SendServerConfigUpdateCallback&) = delete;
-
- // To allow the parent to detach itself from the callback before deletion.
- void Cancel();
-
- // From BuildServerConfigUpdateMessageResultCallback
- void Run(bool ok, const CryptoHandshakeMessage& message) override;
-
- private:
- QuicCryptoServerStream* parent_;
- };
-
- // Invoked by ValidateCallback::RunImpl once initial validation of
- // the client hello is complete. Finishes processing of the client
- // hello message and handles handshake success/failure.
- void FinishProcessingHandshakeMessage(
- QuicReferenceCountedPointer<ValidateClientHelloResultCallback::Result>
- result,
- std::unique_ptr<ProofSource::Details> details);
-
- class ProcessClientHelloCallback;
- friend class ProcessClientHelloCallback;
-
- // Portion of FinishProcessingHandshakeMessage which executes after
- // ProcessClientHello has been called.
- void FinishProcessingHandshakeMessageAfterProcessClientHello(
- const ValidateClientHelloResultCallback::Result& result,
- QuicErrorCode error,
- const std::string& error_details,
- std::unique_ptr<CryptoHandshakeMessage> reply,
- std::unique_ptr<DiversificationNonce> diversification_nonce,
- std::unique_ptr<ProofSource::Details> proof_source_details);
-
- // Invoked by SendServerConfigUpdateCallback::RunImpl once the proof has been
- // received. |ok| indicates whether or not the proof was successfully
- // acquired, and |message| holds the partially-constructed message from
- // SendServerConfigUpdate.
- void FinishSendServerConfigUpdate(bool ok,
- const CryptoHandshakeMessage& message);
-
- // Returns the QuicTransportVersion of the connection.
- QuicTransportVersion transport_version() const {
- return session_->transport_version();
- }
-
- QuicSession* session_;
- HandshakerDelegateInterface* delegate_;
-
- // crypto_config_ contains crypto parameters for the handshake.
- const QuicCryptoServerConfig* crypto_config_;
-
- // compressed_certs_cache_ contains a set of most recently compressed certs.
- // Owned by QuicDispatcher.
- QuicCompressedCertsCache* compressed_certs_cache_;
-
- // Server's certificate chain and signature of the server config, as provided
- // by ProofSource::GetProof.
- QuicReferenceCountedPointer<QuicSignedServerConfig> signed_config_;
-
- // Hash of the last received CHLO message which can be used for generating
- // server config update messages.
- std::string chlo_hash_;
-
- // Pointer to the helper for this crypto stream. Must outlive this stream.
- QuicCryptoServerStreamBase::Helper* helper_;
-
- // Number of handshake messages received by this stream.
- uint8_t num_handshake_messages_;
-
- // Number of handshake messages received by this stream that contain
- // server nonces (indicating that this is a non-zero-RTT handshake
- // attempt).
- uint8_t num_handshake_messages_with_server_nonces_;
-
- // Pointer to the active callback that will receive the result of
- // BuildServerConfigUpdateMessage and forward it to
- // FinishSendServerConfigUpdate. nullptr if no update message is currently
- // being built.
- SendServerConfigUpdateCallback* send_server_config_update_cb_;
-
- // Number of server config update (SCUP) messages sent by this stream.
- int num_server_config_update_messages_sent_;
-
- // If the client provides CachedNetworkParameters in the STK in the CHLO, then
- // store here, and send back in future STKs if we have no better bandwidth
- // estimate to send.
- std::unique_ptr<CachedNetworkParameters> previous_cached_network_params_;
-
- // Contains any source address tokens which were present in the CHLO.
- SourceAddressTokens previous_source_address_tokens_;
-
- // True if client attempts 0-rtt handshake (which can succeed or fail).
- bool zero_rtt_attempted_;
-
- // Size of the packet containing the most recently received CHLO.
- QuicByteCount chlo_packet_size_;
-
- // Pointer to the active callback that will receive the result of the client
- // hello validation request and forward it to FinishProcessingHandshakeMessage
- // for processing. nullptr if no handshake message is being validated. Note
- // that this field is mutually exclusive with process_client_hello_cb_.
- ValidateCallback* validate_client_hello_cb_;
-
- // Pointer to the active callback which will receive the results of
- // ProcessClientHello and forward it to
- // FinishProcessingHandshakeMessageAfterProcessClientHello. Note that this
- // field is mutually exclusive with validate_client_hello_cb_.
- ProcessClientHelloCallback* process_client_hello_cb_;
-
- // The ProofSource::Details from this connection.
- std::unique_ptr<ProofSource::Details> proof_source_details_;
-
- bool encryption_established_;
- bool one_rtt_keys_available_;
- bool one_rtt_packet_decrypted_;
- const bool noop_if_disconnected_after_process_chlo_ = GetQuicReloadableFlag(
- quic_crypto_noop_if_disconnected_after_process_chlo);
- QuicReferenceCountedPointer<QuicCryptoNegotiatedParameters>
- crypto_negotiated_params_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_QUIC_CRYPTO_SERVER_STREAM_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_crypto_server_stream_base.cc b/chromium/net/third_party/quiche/src/quic/core/quic_crypto_server_stream_base.cc
deleted file mode 100644
index 708b1750166..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_crypto_server_stream_base.cc
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_crypto_server_stream_base.h"
-
-#include <memory>
-#include <string>
-#include <utility>
-
-#include "quic/core/crypto/crypto_protocol.h"
-#include "quic/core/crypto/crypto_utils.h"
-#include "quic/core/crypto/quic_crypto_server_config.h"
-#include "quic/core/crypto/quic_random.h"
-#include "quic/core/proto/cached_network_parameters_proto.h"
-#include "quic/core/quic_config.h"
-#include "quic/core/quic_crypto_server_stream.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_session.h"
-#include "quic/core/tls_server_handshaker.h"
-#include "quic/platform/api/quic_flag_utils.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-QuicCryptoServerStreamBase::QuicCryptoServerStreamBase(QuicSession* session)
- : QuicCryptoStream(session) {}
-
-std::unique_ptr<QuicCryptoServerStreamBase> CreateCryptoServerStream(
- const QuicCryptoServerConfig* crypto_config,
- QuicCompressedCertsCache* compressed_certs_cache,
- QuicSession* session,
- QuicCryptoServerStreamBase::Helper* helper) {
- switch (session->connection()->version().handshake_protocol) {
- case PROTOCOL_QUIC_CRYPTO:
- return std::unique_ptr<QuicCryptoServerStream>(new QuicCryptoServerStream(
- crypto_config, compressed_certs_cache, session, helper));
- case PROTOCOL_TLS1_3:
- return std::unique_ptr<TlsServerHandshaker>(
- new TlsServerHandshaker(session, crypto_config));
- case PROTOCOL_UNSUPPORTED:
- break;
- }
- QUIC_BUG(quic_bug_10492_1)
- << "Unknown handshake protocol: "
- << static_cast<int>(session->connection()->version().handshake_protocol);
- return nullptr;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_crypto_server_stream_base.h b/chromium/net/third_party/quiche/src/quic/core/quic_crypto_server_stream_base.h
deleted file mode 100644
index 0a2a63eb07a..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_crypto_server_stream_base.h
+++ /dev/null
@@ -1,113 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_CRYPTO_SERVER_STREAM_BASE_H_
-#define QUICHE_QUIC_CORE_QUIC_CRYPTO_SERVER_STREAM_BASE_H_
-
-#include <cstdint>
-#include <memory>
-#include <string>
-
-#include "quic/core/crypto/crypto_handshake.h"
-#include "quic/core/crypto/quic_compressed_certs_cache.h"
-#include "quic/core/crypto/quic_crypto_server_config.h"
-#include "quic/core/quic_config.h"
-#include "quic/core/quic_crypto_handshaker.h"
-#include "quic/core/quic_crypto_stream.h"
-#include "quic/core/quic_session.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-class CachedNetworkParameters;
-class CryptoHandshakeMessage;
-class QuicCryptoServerConfig;
-class QuicCryptoServerStreamBase;
-
-// TODO(alyssar) see what can be moved out of QuicCryptoServerStream with
-// various code and test refactoring.
-class QUIC_EXPORT_PRIVATE QuicCryptoServerStreamBase : public QuicCryptoStream {
- public:
- explicit QuicCryptoServerStreamBase(QuicSession* session);
-
- class QUIC_EXPORT_PRIVATE Helper {
- public:
- virtual ~Helper() {}
-
- // Returns true if |message|, which was received on |self_address| is
- // acceptable according to the visitor's policy. Otherwise, returns false
- // and populates |error_details|.
- virtual bool CanAcceptClientHello(const CryptoHandshakeMessage& message,
- const QuicSocketAddress& client_address,
- const QuicSocketAddress& peer_address,
- const QuicSocketAddress& self_address,
- std::string* error_details) const = 0;
- };
-
- ~QuicCryptoServerStreamBase() override {}
-
- // Cancel any outstanding callbacks, such as asynchronous validation of client
- // hello.
- virtual void CancelOutstandingCallbacks() = 0;
-
- // GetBase64SHA256ClientChannelID sets |*output| to the base64 encoded,
- // SHA-256 hash of the client's ChannelID key and returns true, if the client
- // presented a ChannelID. Otherwise it returns false.
- virtual bool GetBase64SHA256ClientChannelID(std::string* output) const = 0;
-
- virtual int NumServerConfigUpdateMessagesSent() const = 0;
-
- // Sends the latest server config and source-address token to the client.
- virtual void SendServerConfigUpdate(
- const CachedNetworkParameters* cached_network_params) = 0;
-
- // Returns true if the connection was a successful 0-RTT resumption.
- virtual bool IsZeroRtt() const = 0;
-
- // Returns true if the connection was the result of a resumption handshake,
- // whether 0-RTT or not.
- virtual bool IsResumption() const = 0;
-
- // Returns true if the client attempted a resumption handshake, whether or not
- // the resumption actually occurred.
- virtual bool ResumptionAttempted() const = 0;
-
- // NOTE: Indicating that the Expect-CT header should be sent here presents
- // a layering violation to some extent. The Expect-CT header only applies to
- // HTTP connections, while this class can be used for non-HTTP applications.
- // However, it is exposed here because that is the only place where the
- // configuration for the certificate used in the connection is accessible.
- virtual bool ShouldSendExpectCTHeader() const = 0;
-
- // Return true if a cert was picked that matched the SNI hostname.
- virtual bool DidCertMatchSni() const = 0;
-
- // Returns the Details from the latest call to ProofSource::GetProof or
- // ProofSource::ComputeTlsSignature. Returns nullptr if no such call has been
- // made. The Details are owned by the QuicCryptoServerStreamBase and the
- // pointer is only valid while the owning object is still valid.
- virtual const ProofSource::Details* ProofSourceDetails() const = 0;
-
- bool ExportKeyingMaterial(absl::string_view /*label*/,
- absl::string_view /*context*/,
- size_t /*result_len*/,
- std::string* /*result*/) override {
- QUICHE_NOTREACHED();
- return false;
- }
-};
-
-// Creates an appropriate QuicCryptoServerStream for the provided parameters,
-// including the version used by |session|. |crypto_config|, |session|, and
-// |helper| must all outlive the stream. The caller takes ownership of the
-// returned object.
-QUIC_EXPORT_PRIVATE std::unique_ptr<QuicCryptoServerStreamBase>
-CreateCryptoServerStream(const QuicCryptoServerConfig* crypto_config,
- QuicCompressedCertsCache* compressed_certs_cache,
- QuicSession* session,
- QuicCryptoServerStreamBase::Helper* helper);
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_QUIC_CRYPTO_SERVER_STREAM_BASE_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_crypto_server_stream_test.cc b/chromium/net/third_party/quiche/src/quic/core/quic_crypto_server_stream_test.cc
deleted file mode 100644
index 4e07f34b616..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_crypto_server_stream_test.cc
+++ /dev/null
@@ -1,400 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_crypto_server_stream_base.h"
-
-#include <map>
-#include <memory>
-#include <utility>
-#include <vector>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/crypto/aes_128_gcm_12_encrypter.h"
-#include "quic/core/crypto/crypto_framer.h"
-#include "quic/core/crypto/crypto_handshake.h"
-#include "quic/core/crypto/crypto_protocol.h"
-#include "quic/core/crypto/crypto_utils.h"
-#include "quic/core/crypto/quic_crypto_server_config.h"
-#include "quic/core/crypto/quic_decrypter.h"
-#include "quic/core/crypto/quic_encrypter.h"
-#include "quic/core/crypto/quic_random.h"
-#include "quic/core/quic_crypto_client_stream.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_session.h"
-#include "quic/core/quic_utils.h"
-#include "quic/core/quic_versions.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/platform/api/quic_socket_address.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/crypto_test_utils.h"
-#include "quic/test_tools/failing_proof_source.h"
-#include "quic/test_tools/fake_proof_source.h"
-#include "quic/test_tools/quic_crypto_server_config_peer.h"
-#include "quic/test_tools/quic_test_utils.h"
-
-namespace quic {
-class QuicConnection;
-class QuicStream;
-} // namespace quic
-
-using testing::_;
-using testing::NiceMock;
-
-namespace quic {
-namespace test {
-
-namespace {
-
-const char kServerHostname[] = "test.example.com";
-const uint16_t kServerPort = 443;
-
-// This test tests the server-side of the QUIC crypto handshake. It does not
-// test the TLS handshake - that is in tls_server_handshaker_test.cc.
-class QuicCryptoServerStreamTest : public QuicTest {
- public:
- QuicCryptoServerStreamTest()
- : QuicCryptoServerStreamTest(crypto_test_utils::ProofSourceForTesting()) {
- }
-
- explicit QuicCryptoServerStreamTest(std::unique_ptr<ProofSource> proof_source)
- : server_crypto_config_(QuicCryptoServerConfig::TESTING,
- QuicRandom::GetInstance(),
- std::move(proof_source),
- KeyExchangeSource::Default()),
- server_compressed_certs_cache_(
- QuicCompressedCertsCache::kQuicCompressedCertsCacheSize),
- server_id_(kServerHostname, kServerPort, false),
- client_crypto_config_(crypto_test_utils::ProofVerifierForTesting()) {}
-
- void Initialize() { InitializeServer(); }
-
- ~QuicCryptoServerStreamTest() override {
- // Ensure that anything that might reference |helpers_| is destroyed before
- // |helpers_| is destroyed.
- server_session_.reset();
- client_session_.reset();
- helpers_.clear();
- alarm_factories_.clear();
- }
-
- // Initializes the crypto server stream state for testing. May be
- // called multiple times.
- void InitializeServer() {
- TestQuicSpdyServerSession* server_session = nullptr;
- helpers_.push_back(std::make_unique<NiceMock<MockQuicConnectionHelper>>());
- alarm_factories_.push_back(std::make_unique<MockAlarmFactory>());
- CreateServerSessionForTest(
- server_id_, QuicTime::Delta::FromSeconds(100000), supported_versions_,
- helpers_.back().get(), alarm_factories_.back().get(),
- &server_crypto_config_, &server_compressed_certs_cache_,
- &server_connection_, &server_session);
- QUICHE_CHECK(server_session);
- server_session_.reset(server_session);
- EXPECT_CALL(*server_session_->helper(), CanAcceptClientHello(_, _, _, _, _))
- .Times(testing::AnyNumber());
- EXPECT_CALL(*server_session_, SelectAlpn(_))
- .WillRepeatedly(
- [this](const std::vector<absl::string_view>& alpns) {
- return std::find(
- alpns.cbegin(), alpns.cend(),
- AlpnForVersion(server_session_->connection()->version()));
- });
- crypto_test_utils::SetupCryptoServerConfigForTest(
- server_connection_->clock(), server_connection_->random_generator(),
- &server_crypto_config_);
- }
-
- QuicCryptoServerStreamBase* server_stream() {
- return server_session_->GetMutableCryptoStream();
- }
-
- QuicCryptoClientStream* client_stream() {
- return client_session_->GetMutableCryptoStream();
- }
-
- // Initializes a fake client, and all its associated state, for
- // testing. May be called multiple times.
- void InitializeFakeClient() {
- TestQuicSpdyClientSession* client_session = nullptr;
- helpers_.push_back(std::make_unique<NiceMock<MockQuicConnectionHelper>>());
- alarm_factories_.push_back(std::make_unique<MockAlarmFactory>());
- CreateClientSessionForTest(
- server_id_, QuicTime::Delta::FromSeconds(100000), supported_versions_,
- helpers_.back().get(), alarm_factories_.back().get(),
- &client_crypto_config_, &client_connection_, &client_session);
- QUICHE_CHECK(client_session);
- client_session_.reset(client_session);
- }
-
- int CompleteCryptoHandshake() {
- QUICHE_CHECK(server_connection_);
- QUICHE_CHECK(server_session_ != nullptr);
-
- return crypto_test_utils::HandshakeWithFakeClient(
- helpers_.back().get(), alarm_factories_.back().get(),
- server_connection_, server_stream(), server_id_, client_options_,
- /*alpn=*/"");
- }
-
- // Performs a single round of handshake message-exchange between the
- // client and server.
- void AdvanceHandshakeWithFakeClient() {
- QUICHE_CHECK(server_connection_);
- QUICHE_CHECK(client_session_ != nullptr);
-
- EXPECT_CALL(*client_session_, OnProofValid(_)).Times(testing::AnyNumber());
- EXPECT_CALL(*client_session_, OnProofVerifyDetailsAvailable(_))
- .Times(testing::AnyNumber());
- EXPECT_CALL(*client_connection_, OnCanWrite()).Times(testing::AnyNumber());
- EXPECT_CALL(*server_connection_, OnCanWrite()).Times(testing::AnyNumber());
- client_stream()->CryptoConnect();
- crypto_test_utils::AdvanceHandshake(client_connection_, client_stream(), 0,
- server_connection_, server_stream(), 0);
- }
-
- protected:
- // Every connection gets its own MockQuicConnectionHelper and
- // MockAlarmFactory, tracked separately from the server and client state so
- // their lifetimes persist through the whole test.
- std::vector<std::unique_ptr<MockQuicConnectionHelper>> helpers_;
- std::vector<std::unique_ptr<MockAlarmFactory>> alarm_factories_;
-
- // Server state.
- PacketSavingConnection* server_connection_;
- std::unique_ptr<TestQuicSpdyServerSession> server_session_;
- QuicCryptoServerConfig server_crypto_config_;
- QuicCompressedCertsCache server_compressed_certs_cache_;
- QuicServerId server_id_;
-
- // Client state.
- PacketSavingConnection* client_connection_;
- QuicCryptoClientConfig client_crypto_config_;
- std::unique_ptr<TestQuicSpdyClientSession> client_session_;
-
- CryptoHandshakeMessage message_;
- crypto_test_utils::FakeClientOptions client_options_;
-
- // Which QUIC versions the client and server support.
- ParsedQuicVersionVector supported_versions_ =
- AllSupportedVersionsWithQuicCrypto();
-};
-
-TEST_F(QuicCryptoServerStreamTest, NotInitiallyConected) {
- Initialize();
- EXPECT_FALSE(server_stream()->encryption_established());
- EXPECT_FALSE(server_stream()->one_rtt_keys_available());
-}
-
-TEST_F(QuicCryptoServerStreamTest, ConnectedAfterCHLO) {
- // CompleteCryptoHandshake returns the number of client hellos sent. This
- // test should send:
- // * One to get a source-address token and certificates.
- // * One to complete the handshake.
- Initialize();
- EXPECT_EQ(2, CompleteCryptoHandshake());
- EXPECT_TRUE(server_stream()->encryption_established());
- EXPECT_TRUE(server_stream()->one_rtt_keys_available());
-}
-
-TEST_F(QuicCryptoServerStreamTest, ForwardSecureAfterCHLO) {
- Initialize();
- InitializeFakeClient();
-
- // Do a first handshake in order to prime the client config with the server's
- // information.
- AdvanceHandshakeWithFakeClient();
- EXPECT_FALSE(server_stream()->encryption_established());
- EXPECT_FALSE(server_stream()->one_rtt_keys_available());
-
- // Now do another handshake, with the blocking SHLO connection option.
- InitializeServer();
- InitializeFakeClient();
-
- AdvanceHandshakeWithFakeClient();
- EXPECT_TRUE(server_stream()->encryption_established());
- EXPECT_TRUE(server_stream()->one_rtt_keys_available());
- EXPECT_EQ(ENCRYPTION_FORWARD_SECURE,
- server_session_->connection()->encryption_level());
-}
-
-TEST_F(QuicCryptoServerStreamTest, ZeroRTT) {
- Initialize();
- InitializeFakeClient();
-
- // Do a first handshake in order to prime the client config with the server's
- // information.
- AdvanceHandshakeWithFakeClient();
- EXPECT_FALSE(server_stream()->ResumptionAttempted());
-
- // Now do another handshake, hopefully in 0-RTT.
- QUIC_LOG(INFO) << "Resetting for 0-RTT handshake attempt";
- InitializeFakeClient();
- InitializeServer();
-
- EXPECT_CALL(*client_session_, OnProofValid(_)).Times(testing::AnyNumber());
- EXPECT_CALL(*client_session_, OnProofVerifyDetailsAvailable(_))
- .Times(testing::AnyNumber());
- EXPECT_CALL(*client_connection_, OnCanWrite()).Times(testing::AnyNumber());
- client_stream()->CryptoConnect();
-
- EXPECT_CALL(*client_session_, OnProofValid(_)).Times(testing::AnyNumber());
- EXPECT_CALL(*client_session_, OnProofVerifyDetailsAvailable(_))
- .Times(testing::AnyNumber());
- EXPECT_CALL(*client_connection_, OnCanWrite()).Times(testing::AnyNumber());
- crypto_test_utils::CommunicateHandshakeMessages(
- client_connection_, client_stream(), server_connection_, server_stream());
-
- EXPECT_EQ(1, client_stream()->num_sent_client_hellos());
- EXPECT_TRUE(server_stream()->ResumptionAttempted());
-}
-
-TEST_F(QuicCryptoServerStreamTest, FailByPolicy) {
- Initialize();
- InitializeFakeClient();
-
- EXPECT_CALL(*server_session_->helper(), CanAcceptClientHello(_, _, _, _, _))
- .WillOnce(testing::Return(false));
- EXPECT_CALL(*server_connection_,
- CloseConnection(QUIC_HANDSHAKE_FAILED, _, _));
-
- AdvanceHandshakeWithFakeClient();
-}
-
-TEST_F(QuicCryptoServerStreamTest, MessageAfterHandshake) {
- Initialize();
- CompleteCryptoHandshake();
- EXPECT_CALL(
- *server_connection_,
- CloseConnection(QUIC_CRYPTO_MESSAGE_AFTER_HANDSHAKE_COMPLETE, _, _));
- message_.set_tag(kCHLO);
- crypto_test_utils::SendHandshakeMessageToStream(server_stream(), message_,
- Perspective::IS_CLIENT);
-}
-
-TEST_F(QuicCryptoServerStreamTest, BadMessageType) {
- Initialize();
-
- message_.set_tag(kSHLO);
- EXPECT_CALL(*server_connection_,
- CloseConnection(QUIC_INVALID_CRYPTO_MESSAGE_TYPE, _, _));
- crypto_test_utils::SendHandshakeMessageToStream(server_stream(), message_,
- Perspective::IS_SERVER);
-}
-
-TEST_F(QuicCryptoServerStreamTest, OnlySendSCUPAfterHandshakeComplete) {
- // An attempt to send a SCUP before completing handshake should fail.
- Initialize();
-
- server_stream()->SendServerConfigUpdate(nullptr);
- EXPECT_EQ(0, server_stream()->NumServerConfigUpdateMessagesSent());
-}
-
-TEST_F(QuicCryptoServerStreamTest, SendSCUPAfterHandshakeComplete) {
- Initialize();
-
- InitializeFakeClient();
-
- // Do a first handshake in order to prime the client config with the server's
- // information.
- AdvanceHandshakeWithFakeClient();
-
- // Now do another handshake, with the blocking SHLO connection option.
- InitializeServer();
- InitializeFakeClient();
- AdvanceHandshakeWithFakeClient();
-
- // Send a SCUP message and ensure that the client was able to verify it.
- EXPECT_CALL(*client_connection_, CloseConnection(_, _, _)).Times(0);
- server_stream()->SendServerConfigUpdate(nullptr);
- crypto_test_utils::AdvanceHandshake(client_connection_, client_stream(), 1,
- server_connection_, server_stream(), 1);
-
- EXPECT_EQ(1, server_stream()->NumServerConfigUpdateMessagesSent());
- EXPECT_EQ(1, client_stream()->num_scup_messages_received());
-}
-
-class QuicCryptoServerStreamTestWithFailingProofSource
- : public QuicCryptoServerStreamTest {
- public:
- QuicCryptoServerStreamTestWithFailingProofSource()
- : QuicCryptoServerStreamTest(
- std::unique_ptr<FailingProofSource>(new FailingProofSource)) {}
-};
-
-TEST_F(QuicCryptoServerStreamTestWithFailingProofSource, Test) {
- Initialize();
- InitializeFakeClient();
-
- EXPECT_CALL(*server_session_->helper(), CanAcceptClientHello(_, _, _, _, _))
- .WillOnce(testing::Return(true));
- EXPECT_CALL(*server_connection_,
- CloseConnection(QUIC_HANDSHAKE_FAILED, "Failed to get proof", _));
- // Regression test for b/31521252, in which a crash would happen here.
- AdvanceHandshakeWithFakeClient();
- EXPECT_FALSE(server_stream()->encryption_established());
- EXPECT_FALSE(server_stream()->one_rtt_keys_available());
-}
-
-class QuicCryptoServerStreamTestWithFakeProofSource
- : public QuicCryptoServerStreamTest {
- public:
- QuicCryptoServerStreamTestWithFakeProofSource()
- : QuicCryptoServerStreamTest(
- std::unique_ptr<FakeProofSource>(new FakeProofSource)),
- crypto_config_peer_(&server_crypto_config_) {}
-
- FakeProofSource* GetFakeProofSource() const {
- return static_cast<FakeProofSource*>(crypto_config_peer_.GetProofSource());
- }
-
- protected:
- QuicCryptoServerConfigPeer crypto_config_peer_;
-};
-
-// Regression test for b/35422225, in which multiple CHLOs arriving on the same
-// connection in close succession could cause a crash.
-TEST_F(QuicCryptoServerStreamTestWithFakeProofSource, MultipleChlo) {
- Initialize();
- GetFakeProofSource()->Activate();
- EXPECT_CALL(*server_session_->helper(), CanAcceptClientHello(_, _, _, _, _))
- .WillOnce(testing::Return(true));
-
- // The methods below use a PROTOCOL_QUIC_CRYPTO version so we pick the
- // first one from the list of supported versions.
- QuicTransportVersion transport_version = QUIC_VERSION_UNSUPPORTED;
- for (const ParsedQuicVersion& version : AllSupportedVersions()) {
- if (version.handshake_protocol == PROTOCOL_QUIC_CRYPTO) {
- transport_version = version.transport_version;
- break;
- }
- }
- ASSERT_NE(QUIC_VERSION_UNSUPPORTED, transport_version);
-
- // Create a minimal CHLO
- MockClock clock;
- CryptoHandshakeMessage chlo = crypto_test_utils::GenerateDefaultInchoateCHLO(
- &clock, transport_version, &server_crypto_config_);
-
- // Send in the CHLO, and check that a callback is now pending in the
- // ProofSource.
- crypto_test_utils::SendHandshakeMessageToStream(server_stream(), chlo,
- Perspective::IS_CLIENT);
- EXPECT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 1);
-
- // Send in a second CHLO while processing of the first is still pending.
- // Verify that the server closes the connection rather than crashing. Note
- // that the crash is a use-after-free, so it may only show up consistently in
- // ASAN tests.
- EXPECT_CALL(
- *server_connection_,
- CloseConnection(QUIC_CRYPTO_MESSAGE_WHILE_VALIDATING_CLIENT_HELLO,
- "Unexpected handshake message while processing CHLO", _));
- crypto_test_utils::SendHandshakeMessageToStream(server_stream(), chlo,
- Perspective::IS_CLIENT);
-}
-
-} // namespace
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_crypto_stream.cc b/chromium/net/third_party/quiche/src/quic/core/quic_crypto_stream.cc
deleted file mode 100644
index 99fb2cd22e1..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_crypto_stream.cc
+++ /dev/null
@@ -1,483 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_crypto_stream.h"
-
-#include <string>
-
-#include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
-#include "quic/core/crypto/crypto_handshake.h"
-#include "quic/core/crypto/crypto_utils.h"
-#include "quic/core/quic_connection.h"
-#include "quic/core/quic_session.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_flag_utils.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-#define ENDPOINT \
- (session()->perspective() == Perspective::IS_SERVER ? "Server: " \
- : "Client:" \
- " ")
-
-QuicCryptoStream::QuicCryptoStream(QuicSession* session)
- : QuicStream(
- QuicVersionUsesCryptoFrames(session->transport_version())
- ? QuicUtils::GetInvalidStreamId(session->transport_version())
- : QuicUtils::GetCryptoStreamId(session->transport_version()),
- session,
- /*is_static=*/true,
- QuicVersionUsesCryptoFrames(session->transport_version())
- ? CRYPTO
- : BIDIRECTIONAL),
- substreams_{{{this, ENCRYPTION_INITIAL},
- {this, ENCRYPTION_HANDSHAKE},
- {this, ENCRYPTION_ZERO_RTT},
- {this, ENCRYPTION_FORWARD_SECURE}}} {
- // The crypto stream is exempt from connection level flow control.
- DisableConnectionFlowControlForThisStream();
-}
-
-QuicCryptoStream::~QuicCryptoStream() {}
-
-// static
-QuicByteCount QuicCryptoStream::CryptoMessageFramingOverhead(
- QuicTransportVersion version,
- QuicConnectionId connection_id) {
- QUICHE_DCHECK(
- QuicUtils::IsConnectionIdValidForVersion(connection_id, version));
- QuicVariableLengthIntegerLength retry_token_length_length =
- VARIABLE_LENGTH_INTEGER_LENGTH_1;
- QuicVariableLengthIntegerLength length_length =
- VARIABLE_LENGTH_INTEGER_LENGTH_2;
- if (!QuicVersionHasLongHeaderLengths(version)) {
- retry_token_length_length = VARIABLE_LENGTH_INTEGER_LENGTH_0;
- length_length = VARIABLE_LENGTH_INTEGER_LENGTH_0;
- }
- return QuicPacketCreator::StreamFramePacketOverhead(
- version, static_cast<QuicConnectionIdLength>(connection_id.length()),
- PACKET_0BYTE_CONNECTION_ID,
- /*include_version=*/true,
- /*include_diversification_nonce=*/true,
- VersionHasIetfInvariantHeader(version) ? PACKET_4BYTE_PACKET_NUMBER
- : PACKET_1BYTE_PACKET_NUMBER,
- retry_token_length_length, length_length,
- /*offset=*/0);
-}
-
-void QuicCryptoStream::OnCryptoFrame(const QuicCryptoFrame& frame) {
- QUIC_BUG_IF(quic_bug_12573_1,
- !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);
- EncryptionLevel frame_level = level;
- if (substreams_[level].sequencer.NumBytesBuffered() >
- BufferSizeLimitForLevel(frame_level)) {
- OnUnrecoverableError(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA,
- "Too much crypto data received");
- }
-}
-
-void QuicCryptoStream::OnStreamFrame(const QuicStreamFrame& frame) {
- if (QuicVersionUsesCryptoFrames(session()->transport_version())) {
- QUIC_PEER_BUG(quic_peer_bug_12573_2)
- << "Crypto data received in stream frame instead of crypto frame";
- OnUnrecoverableError(QUIC_INVALID_STREAM_DATA, "Unexpected stream frame");
- }
- QuicStream::OnStreamFrame(frame);
-}
-
-void QuicCryptoStream::OnDataAvailable() {
- EncryptionLevel level = session()->connection()->last_decrypted_level();
- if (!QuicVersionUsesCryptoFrames(session()->transport_version())) {
- // Versions less than 47 only support QUIC crypto, which ignores the
- // EncryptionLevel passed into CryptoMessageParser::ProcessInput (and
- // OnDataAvailableInSequencer).
- OnDataAvailableInSequencer(sequencer(), level);
- return;
- }
- OnDataAvailableInSequencer(&substreams_[level].sequencer, level);
-}
-
-void QuicCryptoStream::OnDataAvailableInSequencer(
- QuicStreamSequencer* sequencer,
- EncryptionLevel level) {
- struct iovec iov;
- while (sequencer->GetReadableRegion(&iov)) {
- absl::string_view data(static_cast<char*>(iov.iov_base), iov.iov_len);
- if (!crypto_message_parser()->ProcessInput(data, level)) {
- OnUnrecoverableError(crypto_message_parser()->error(),
- crypto_message_parser()->error_detail());
- return;
- }
- sequencer->MarkConsumed(iov.iov_len);
- if (one_rtt_keys_available() &&
- crypto_message_parser()->InputBytesRemaining() == 0) {
- // If the handshake is complete and the current message has been fully
- // processed then no more handshake messages are likely to arrive soon
- // so release the memory in the stream sequencer.
- sequencer->ReleaseBufferIfEmpty();
- }
- }
-}
-
-void QuicCryptoStream::WriteCryptoData(EncryptionLevel level,
- absl::string_view data) {
- if (!QuicVersionUsesCryptoFrames(session()->transport_version())) {
- WriteOrBufferDataAtLevel(data, /*fin=*/false, level,
- /*ack_listener=*/nullptr);
- return;
- }
- if (data.empty()) {
- QUIC_BUG(quic_bug_10322_1) << "Empty crypto data being written";
- return;
- }
- const bool had_buffered_data = HasBufferedCryptoFrames();
- // Append |data| to the send buffer for this encryption level.
- struct iovec iov(QuicUtils::MakeIovec(data));
- QuicStreamSendBuffer* send_buffer = &substreams_[level].send_buffer;
- QuicStreamOffset offset = send_buffer->stream_offset();
- send_buffer->SaveStreamData(&iov, /*iov_count=*/1, /*iov_offset=*/0,
- data.length());
- 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,
- "Writing too much crypto handshake data");
- }
- if (had_buffered_data) {
- // Do not try to write if there is buffered data.
- return;
- }
-
- size_t bytes_consumed = stream_delegate()->SendCryptoData(
- level, data.length(), offset, NOT_RETRANSMISSION);
- send_buffer->OnStreamDataConsumed(bytes_consumed);
-}
-
-size_t QuicCryptoStream::BufferSizeLimitForLevel(EncryptionLevel) const {
- return GetQuicFlag(FLAGS_quic_max_buffered_crypto_bytes);
-}
-
-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)) {
- OnUnrecoverableError(QUIC_INTERNAL_ERROR,
- "Trying to ack unsent crypto data.");
- return false;
- }
- return newly_acked_length > 0;
-}
-
-void QuicCryptoStream::OnStreamReset(const QuicRstStreamFrame& /*frame*/) {
- stream_delegate()->OnStreamError(QUIC_INVALID_STREAM_ID,
- "Attempt to reset crypto stream");
-}
-
-void QuicCryptoStream::NeuterUnencryptedStreamData() {
- NeuterStreamDataOfEncryptionLevel(ENCRYPTION_INITIAL);
-}
-
-void QuicCryptoStream::NeuterStreamDataOfEncryptionLevel(
- EncryptionLevel level) {
- if (!QuicVersionUsesCryptoFrames(session()->transport_version())) {
- for (const auto& interval : bytes_consumed_[level]) {
- QuicByteCount newly_acked_length = 0;
- send_buffer().OnStreamDataAcked(
- interval.min(), interval.max() - interval.min(), &newly_acked_length);
- }
- return;
- }
- QuicStreamSendBuffer* send_buffer = &substreams_[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) {
- QuicByteCount newly_acked_length = 0;
- send_buffer->OnStreamDataAcked(
- interval.min(), interval.max() - interval.min(), &newly_acked_length);
- }
-}
-
-void QuicCryptoStream::OnStreamDataConsumed(QuicByteCount bytes_consumed) {
- if (QuicVersionUsesCryptoFrames(session()->transport_version())) {
- QUIC_BUG(quic_bug_10322_3)
- << "Stream data consumed when CRYPTO frames should be in use";
- }
- if (bytes_consumed > 0) {
- bytes_consumed_[session()->connection()->encryption_level()].Add(
- stream_bytes_written(), stream_bytes_written() + 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()) {
- return true;
- }
- }
- return false;
-}
-
-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;
- while (send_buffer->HasPendingRetransmission()) {
- auto pending = send_buffer->NextPendingRetransmission();
- size_t bytes_consumed = stream_delegate()->SendCryptoData(
- level, pending.length, pending.offset, HANDSHAKE_RETRANSMISSION);
- send_buffer->OnStreamDataRetransmitted(pending.offset, bytes_consumed);
- if (bytes_consumed < pending.length) {
- return;
- }
- }
- }
-}
-
-void QuicCryptoStream::WritePendingRetransmission() {
- while (HasPendingRetransmission()) {
- StreamPendingRetransmission pending =
- send_buffer().NextPendingRetransmission();
- QuicIntervalSet<QuicStreamOffset> retransmission(
- pending.offset, pending.offset + pending.length);
- EncryptionLevel retransmission_encryption_level = ENCRYPTION_INITIAL;
- // Determine the encryption level to write the retransmission
- // at. The retransmission should be written at the same encryption level
- // as the original transmission.
- for (size_t i = 0; i < NUM_ENCRYPTION_LEVELS; ++i) {
- if (retransmission.Intersects(bytes_consumed_[i])) {
- retransmission_encryption_level = static_cast<EncryptionLevel>(i);
- retransmission.Intersection(bytes_consumed_[i]);
- break;
- }
- }
- pending.offset = retransmission.begin()->min();
- pending.length =
- retransmission.begin()->max() - retransmission.begin()->min();
- QuicConsumedData consumed = RetransmitStreamDataAtLevel(
- pending.offset, pending.length, retransmission_encryption_level,
- HANDSHAKE_RETRANSMISSION);
- if (consumed.bytes_consumed < pending.length) {
- // The connection is write blocked.
- break;
- }
- }
-}
-
-bool QuicCryptoStream::RetransmitStreamData(QuicStreamOffset offset,
- QuicByteCount data_length,
- bool /*fin*/,
- TransmissionType type) {
- QUICHE_DCHECK(type == HANDSHAKE_RETRANSMISSION || type == PTO_RETRANSMISSION);
- QuicIntervalSet<QuicStreamOffset> retransmission(offset,
- offset + data_length);
- // Determine the encryption level to send data. This only needs to be once as
- // [offset, offset + data_length) is guaranteed to be in the same packet.
- EncryptionLevel send_encryption_level = ENCRYPTION_INITIAL;
- for (size_t i = 0; i < NUM_ENCRYPTION_LEVELS; ++i) {
- if (retransmission.Intersects(bytes_consumed_[i])) {
- send_encryption_level = static_cast<EncryptionLevel>(i);
- break;
- }
- }
- retransmission.Difference(bytes_acked());
- for (const auto& interval : retransmission) {
- QuicStreamOffset retransmission_offset = interval.min();
- QuicByteCount retransmission_length = interval.max() - interval.min();
- QuicConsumedData consumed = RetransmitStreamDataAtLevel(
- retransmission_offset, retransmission_length, send_encryption_level,
- type);
- if (consumed.bytes_consumed < retransmission_length) {
- // The connection is write blocked.
- return false;
- }
- }
-
- return true;
-}
-
-QuicConsumedData QuicCryptoStream::RetransmitStreamDataAtLevel(
- QuicStreamOffset retransmission_offset,
- QuicByteCount retransmission_length,
- EncryptionLevel encryption_level,
- TransmissionType type) {
- QUICHE_DCHECK(type == HANDSHAKE_RETRANSMISSION || type == PTO_RETRANSMISSION);
- const auto consumed = stream_delegate()->WritevData(
- id(), retransmission_length, retransmission_offset, NO_FIN, type,
- encryption_level);
- QUIC_DVLOG(1) << ENDPOINT << "stream " << id()
- << " is forced to retransmit stream data ["
- << retransmission_offset << ", "
- << retransmission_offset + retransmission_length
- << "), with encryption level: " << encryption_level
- << ", consumed: " << consumed;
- OnStreamFrameRetransmitted(retransmission_offset, consumed.bytes_consumed,
- consumed.fin_consumed);
-
- return consumed;
-}
-
-uint64_t QuicCryptoStream::crypto_bytes_read() const {
- if (!QuicVersionUsesCryptoFrames(session()->transport_version())) {
- return stream_bytes_read();
- }
- uint64_t bytes_read = 0;
- for (EncryptionLevel level : AllEncryptionLevels()) {
- bytes_read += substreams_[level].sequencer.NumBytesConsumed();
- }
- return bytes_read;
-}
-
-uint64_t QuicCryptoStream::BytesReadOnLevel(EncryptionLevel level) const {
- return substreams_[level].sequencer.NumBytesConsumed();
-}
-
-bool QuicCryptoStream::WriteCryptoFrame(EncryptionLevel level,
- QuicStreamOffset offset,
- QuicByteCount data_length,
- QuicDataWriter* writer) {
- 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);
-}
-
-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);
-}
-
-void QuicCryptoStream::RetransmitData(QuicCryptoFrame* crypto_frame,
- TransmissionType type) {
- QUIC_BUG_IF(quic_bug_12573_6,
- !QuicVersionUsesCryptoFrames(session()->transport_version()))
- << "Versions less than 47 don't retransmit CRYPTO frames";
- QuicIntervalSet<QuicStreamOffset> retransmission(
- crypto_frame->offset, crypto_frame->offset + crypto_frame->data_length);
- QuicStreamSendBuffer* send_buffer =
- &substreams_[crypto_frame->level].send_buffer;
- retransmission.Difference(send_buffer->bytes_acked());
- if (retransmission.Empty()) {
- return;
- }
- for (const auto& interval : retransmission) {
- size_t retransmission_offset = interval.min();
- size_t retransmission_length = interval.max() - interval.min();
- size_t bytes_consumed = stream_delegate()->SendCryptoData(
- crypto_frame->level, retransmission_length, retransmission_offset,
- type);
- send_buffer->OnStreamDataRetransmitted(retransmission_offset,
- bytes_consumed);
- if (bytes_consumed < retransmission_length) {
- break;
- }
- }
-}
-
-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;
- const size_t data_length =
- send_buffer->stream_offset() - send_buffer->stream_bytes_written();
- if (data_length == 0) {
- // No buffered data for this encryption level.
- continue;
- }
- size_t bytes_consumed = stream_delegate()->SendCryptoData(
- level, data_length, send_buffer->stream_bytes_written(),
- NOT_RETRANSMISSION);
- send_buffer->OnStreamDataConsumed(bytes_consumed);
- if (bytes_consumed < data_length) {
- // Connection is write blocked.
- break;
- }
- }
-}
-
-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;
- QUICHE_DCHECK_GE(send_buffer.stream_offset(),
- send_buffer.stream_bytes_written());
- if (send_buffer.stream_offset() > send_buffer.stream_bytes_written()) {
- return true;
- }
- }
- return false;
-}
-
-bool QuicCryptoStream::IsFrameOutstanding(EncryptionLevel level,
- size_t offset,
- size_t length) const {
- if (!QuicVersionUsesCryptoFrames(session()->transport_version())) {
- // This only happens if a client was originally configured for a version
- // greater than 45, but received a version negotiation packet and is
- // attempting to retransmit for a version less than 47. Outside of tests,
- // this is a misconfiguration of the client, and this connection will be
- // doomed. Return false here to avoid trying to retransmit CRYPTO frames on
- // the wrong transport version.
- return false;
- }
- return substreams_[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()) {
- return true;
- }
- }
- return false;
-}
-
-QuicCryptoStream::CryptoSubstream::CryptoSubstream(
- QuicCryptoStream* crypto_stream,
- EncryptionLevel)
- : sequencer(crypto_stream),
- send_buffer(crypto_stream->session()
- ->connection()
- ->helper()
- ->GetStreamSendBufferAllocator()) {}
-
-#undef ENDPOINT // undef for jumbo builds
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_crypto_stream.h b/chromium/net/third_party/quiche/src/quic/core/quic_crypto_stream.h
deleted file mode 100644
index 8197a5f4d75..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_crypto_stream.h
+++ /dev/null
@@ -1,273 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_CRYPTO_STREAM_H_
-#define QUICHE_QUIC_CORE_QUIC_CRYPTO_STREAM_H_
-
-#include <array>
-#include <cstddef>
-#include <string>
-
-#include "absl/strings/string_view.h"
-#include "third_party/boringssl/src/include/openssl/ssl.h"
-#include "quic/core/crypto/crypto_framer.h"
-#include "quic/core/crypto/crypto_utils.h"
-#include "quic/core/proto/cached_network_parameters_proto.h"
-#include "quic/core/quic_config.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_stream.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-class CachedNetworkParameters;
-class QuicSession;
-
-// Crypto handshake messages in QUIC take place over a reserved stream with the
-// id 1. Each endpoint (client and server) will allocate an instance of a
-// subclass of QuicCryptoStream to send and receive handshake messages. (In the
-// normal 1-RTT handshake, the client will send a client hello, CHLO, message.
-// The server will receive this message and respond with a server hello message,
-// SHLO. At this point both sides will have established a crypto context they
-// can use to send encrypted messages.
-//
-// For more details:
-// https://docs.google.com/document/d/1g5nIXAIkN_Y-7XJW5K45IblHd_L2f5LTaDUDwvZ5L6g/edit?usp=sharing
-class QUIC_EXPORT_PRIVATE QuicCryptoStream : public QuicStream {
- public:
- explicit QuicCryptoStream(QuicSession* session);
- QuicCryptoStream(const QuicCryptoStream&) = delete;
- QuicCryptoStream& operator=(const QuicCryptoStream&) = delete;
-
- ~QuicCryptoStream() override;
-
- // Returns the per-packet framing overhead associated with sending a
- // handshake message for |version|.
- static QuicByteCount CryptoMessageFramingOverhead(
- QuicTransportVersion version,
- QuicConnectionId connection_id);
-
- // QuicStream implementation
- void OnStreamFrame(const QuicStreamFrame& frame) override;
- void OnDataAvailable() override;
-
- // Called when a CRYPTO frame is received.
- void OnCryptoFrame(const QuicCryptoFrame& frame);
-
- // Called when a CRYPTO frame is ACKed.
- bool OnCryptoFrameAcked(const QuicCryptoFrame& frame,
- QuicTime::Delta ack_delay_time);
-
- void OnStreamReset(const QuicRstStreamFrame& frame) override;
-
- // Performs key extraction to derive a new secret of |result_len| bytes
- // dependent on |label|, |context|, and the stream's negotiated subkey secret.
- // Returns false if the handshake has not been confirmed or the parameters are
- // invalid (e.g. |label| contains null bytes); returns true on success. This
- // method is only supported for IETF QUIC and MUST NOT be called in gQUIC as
- // that'll trigger an assert in DEBUG build.
- virtual bool ExportKeyingMaterial(absl::string_view label,
- absl::string_view context,
- size_t result_len, std::string* result) = 0;
-
- // Writes |data| to the QuicStream at level |level|.
- virtual void WriteCryptoData(EncryptionLevel level, absl::string_view data);
-
- // Returns the ssl_early_data_reason_t describing why 0-RTT was accepted or
- // rejected. Note that the value returned by this function may vary during the
- // handshake. Once |one_rtt_keys_available| returns true, the value returned
- // by this function will not change for the rest of the lifetime of the
- // QuicCryptoStream.
- virtual ssl_early_data_reason_t EarlyDataReason() const = 0;
-
- // Returns true once an encrypter has been set for the connection.
- virtual bool encryption_established() const = 0;
-
- // Returns true once the crypto handshake has completed.
- virtual bool one_rtt_keys_available() const = 0;
-
- // Returns the parameters negotiated in the crypto handshake.
- virtual const QuicCryptoNegotiatedParameters& crypto_negotiated_params()
- const = 0;
-
- // Provides the message parser to use when data is received on this stream.
- virtual CryptoMessageParser* crypto_message_parser() = 0;
-
- // Called when a packet of encryption |level| has been successfully decrypted.
- virtual void OnPacketDecrypted(EncryptionLevel level) = 0;
-
- // Called when a 1RTT packet has been acknowledged.
- virtual void OnOneRttPacketAcknowledged() = 0;
-
- // Called when a packet of ENCRYPTION_HANDSHAKE gets sent.
- virtual void OnHandshakePacketSent() = 0;
-
- // Called when a handshake done frame has been received.
- virtual void OnHandshakeDoneReceived() = 0;
-
- // Called when a new token frame has been received.
- virtual void OnNewTokenReceived(absl::string_view token) = 0;
-
- // Called to get an address token.
- virtual std::string GetAddressToken(
- const CachedNetworkParameters* cached_network_params) const = 0;
-
- // Called to validate |token|.
- virtual bool ValidateAddressToken(absl::string_view token) const = 0;
-
- // Get the last CachedNetworkParameters received from a valid address token.
- virtual const CachedNetworkParameters* PreviousCachedNetworkParams()
- const = 0;
-
- // Set the CachedNetworkParameters that will be returned by
- // PreviousCachedNetworkParams.
- // TODO(wub): This function is test only, move it to a test only library.
- virtual void SetPreviousCachedNetworkParams(
- CachedNetworkParameters cached_network_params) = 0;
-
- // Returns current handshake state.
- virtual HandshakeState GetHandshakeState() const = 0;
-
- // Called to provide the server-side application state that must be checked
- // when performing a 0-RTT TLS resumption.
- //
- // On a client, this may be called at any time; 0-RTT tickets will not be
- // cached until this function is called. When a 0-RTT resumption is attempted,
- // QuicSession::SetApplicationState will be called with the state provided by
- // a call to this function on a previous connection.
- //
- // On a server, this function must be called before commencing the handshake,
- // otherwise 0-RTT tickets will not be issued. On subsequent connections,
- // 0-RTT will be rejected if the data passed into this function does not match
- // the data passed in on the connection where the 0-RTT ticket was issued.
- virtual void SetServerApplicationStateForResumption(
- std::unique_ptr<ApplicationState> state) = 0;
-
- // Returns the maximum number of bytes that can be buffered at a particular
- // encryption level |level|.
- virtual size_t BufferSizeLimitForLevel(EncryptionLevel level) const;
-
- // Called to generate a decrypter for the next key phase. Each call should
- // generate the key for phase n+1.
- virtual std::unique_ptr<QuicDecrypter>
- AdvanceKeysAndCreateCurrentOneRttDecrypter() = 0;
-
- // Called to generate an encrypter for the same key phase of the last
- // decrypter returned by AdvanceKeysAndCreateCurrentOneRttDecrypter().
- virtual std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() = 0;
-
- // Return the SSL struct object created by BoringSSL if the stream is using
- // TLS1.3. Otherwise, return nullptr.
- // This method is used in Envoy.
- virtual SSL* GetSsl() const = 0;
-
- // Called to cancel retransmission of unencrypted crypto stream data.
- void NeuterUnencryptedStreamData();
-
- // Called to cancel retransmission of data of encryption |level|.
- void NeuterStreamDataOfEncryptionLevel(EncryptionLevel level);
-
- // Override to record the encryption level of consumed data.
- void OnStreamDataConsumed(QuicByteCount bytes_consumed) override;
-
- // Returns whether there are any bytes pending retransmission in CRYPTO
- // frames.
- virtual bool HasPendingCryptoRetransmission() const;
-
- // Writes any pending CRYPTO frame retransmissions.
- void WritePendingCryptoRetransmission();
-
- // Override to retransmit lost crypto data with the appropriate encryption
- // level.
- void WritePendingRetransmission() override;
-
- // Override to send unacked crypto data with the appropriate encryption level.
- bool RetransmitStreamData(QuicStreamOffset offset,
- QuicByteCount data_length,
- bool fin,
- TransmissionType type) override;
-
- // Sends stream retransmission data at |encryption_level|.
- QuicConsumedData RetransmitStreamDataAtLevel(
- QuicStreamOffset retransmission_offset,
- QuicByteCount retransmission_length,
- EncryptionLevel encryption_level,
- TransmissionType type);
-
- // Returns the number of bytes of handshake data that have been received from
- // the peer in either CRYPTO or STREAM frames.
- uint64_t crypto_bytes_read() const;
-
- // Returns the number of bytes of handshake data that have been received from
- // the peer in CRYPTO frames at a particular encryption level.
- QuicByteCount BytesReadOnLevel(EncryptionLevel level) const;
-
- // Writes |data_length| of data of a crypto frame to |writer|. The data
- // written is from the send buffer for encryption level |level| and starts at
- // |offset|.
- bool WriteCryptoFrame(EncryptionLevel level,
- QuicStreamOffset offset,
- QuicByteCount data_length,
- QuicDataWriter* writer);
-
- // Called when data from a CRYPTO frame is considered lost. The lost data is
- // identified by the encryption level, offset, and length in |crypto_frame|.
- void OnCryptoFrameLost(QuicCryptoFrame* crypto_frame);
-
- // Called to retransmit any outstanding data in the range indicated by the
- // encryption level, offset, and length in |crypto_frame|.
- void RetransmitData(QuicCryptoFrame* crypto_frame, TransmissionType type);
-
- // Called to write buffered crypto frames.
- void WriteBufferedCryptoFrames();
-
- // Returns true if there is buffered crypto frames.
- bool HasBufferedCryptoFrames() const;
-
- // Returns true if any portion of the data at encryption level |level|
- // starting at |offset| for |length| bytes is outstanding.
- bool IsFrameOutstanding(EncryptionLevel level,
- size_t offset,
- size_t length) const;
-
- // Returns true if the crypto handshake is still waiting for acks of sent
- // data, and false if all data has been acked.
- bool IsWaitingForAcks() const;
-
- // Helper method for OnDataAvailable. Calls CryptoMessageParser::ProcessInput
- // with the data available in |sequencer| and |level|, and marks the data
- // passed to ProcessInput as consumed.
- virtual void OnDataAvailableInSequencer(QuicStreamSequencer* sequencer,
- EncryptionLevel level);
-
- QuicStreamSequencer* GetStreamSequencerForLevel(EncryptionLevel level) {
- return &substreams_[level].sequencer;
- }
-
- 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.
- struct QUIC_EXPORT_PRIVATE CryptoSubstream {
- CryptoSubstream(QuicCryptoStream* crypto_stream, EncryptionLevel);
-
- QuicStreamSequencer sequencer;
- QuicStreamSendBuffer send_buffer;
- };
-
- // Consumed data according to encryption levels.
- // TODO(fayang): This is not needed once switching from QUIC crypto to
- // TLS 1.3, which never encrypts crypto data.
- QuicIntervalSet<QuicStreamOffset> bytes_consumed_[NUM_ENCRYPTION_LEVELS];
-
- // Keeps state for data sent/received in CRYPTO frames at each encryption
- // level.
- std::array<CryptoSubstream, NUM_ENCRYPTION_LEVELS> substreams_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_QUIC_CRYPTO_STREAM_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_crypto_stream_test.cc b/chromium/net/third_party/quiche/src/quic/core/quic_crypto_stream_test.cc
deleted file mode 100644
index 2c9ec0db082..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_crypto_stream_test.cc
+++ /dev/null
@@ -1,724 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_crypto_stream.h"
-
-#include <cstdint>
-#include <memory>
-#include <string>
-#include <utility>
-#include <vector>
-
-#include "quic/core/crypto/crypto_handshake.h"
-#include "quic/core/crypto/crypto_protocol.h"
-#include "quic/core/crypto/null_encrypter.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_socket_address.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/crypto_test_utils.h"
-#include "quic/test_tools/quic_stream_peer.h"
-#include "quic/test_tools/quic_test_utils.h"
-
-using testing::_;
-using testing::InSequence;
-using testing::Invoke;
-using testing::InvokeWithoutArgs;
-using testing::Return;
-
-namespace quic {
-namespace test {
-namespace {
-
-class MockQuicCryptoStream : public QuicCryptoStream,
- public QuicCryptoHandshaker {
- public:
- explicit MockQuicCryptoStream(QuicSession* session)
- : QuicCryptoStream(session),
- QuicCryptoHandshaker(this, session),
- params_(new QuicCryptoNegotiatedParameters) {}
- MockQuicCryptoStream(const MockQuicCryptoStream&) = delete;
- MockQuicCryptoStream& operator=(const MockQuicCryptoStream&) = delete;
-
- void OnHandshakeMessage(const CryptoHandshakeMessage& message) override {
- messages_.push_back(message);
- }
-
- std::vector<CryptoHandshakeMessage>* messages() { return &messages_; }
-
- ssl_early_data_reason_t EarlyDataReason() const override {
- return ssl_early_data_unknown;
- }
- bool encryption_established() const override { return false; }
- bool one_rtt_keys_available() const override { return false; }
-
- const QuicCryptoNegotiatedParameters& crypto_negotiated_params()
- const override {
- return *params_;
- }
- CryptoMessageParser* crypto_message_parser() override {
- return QuicCryptoHandshaker::crypto_message_parser();
- }
- void OnPacketDecrypted(EncryptionLevel /*level*/) override {}
- void OnOneRttPacketAcknowledged() override {}
- void OnHandshakePacketSent() override {}
- void OnHandshakeDoneReceived() override {}
- void OnNewTokenReceived(absl::string_view /*token*/) override {}
- std::string GetAddressToken(
- const CachedNetworkParameters* /*cached_network_parameters*/)
- const override {
- return "";
- }
- bool ValidateAddressToken(absl::string_view /*token*/) const override {
- return true;
- }
- const CachedNetworkParameters* PreviousCachedNetworkParams() const override {
- return nullptr;
- }
- void SetPreviousCachedNetworkParams(
- CachedNetworkParameters /*cached_network_params*/) override {}
- HandshakeState GetHandshakeState() const override { return HANDSHAKE_START; }
- void SetServerApplicationStateForResumption(
- std::unique_ptr<ApplicationState> /*application_state*/) override {}
- std::unique_ptr<QuicDecrypter> AdvanceKeysAndCreateCurrentOneRttDecrypter()
- override {
- return nullptr;
- }
- std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() override {
- return nullptr;
- }
- bool ExportKeyingMaterial(absl::string_view /*label*/,
- absl::string_view /*context*/,
- size_t /*result_len*/,
- std::string* /*result*/) override {
- return false;
- }
- SSL* GetSsl() const override { return nullptr; }
-
- private:
- QuicReferenceCountedPointer<QuicCryptoNegotiatedParameters> params_;
- std::vector<CryptoHandshakeMessage> messages_;
-};
-
-class QuicCryptoStreamTest : public QuicTest {
- public:
- QuicCryptoStreamTest()
- : connection_(new MockQuicConnection(&helper_,
- &alarm_factory_,
- Perspective::IS_CLIENT)),
- session_(connection_, /*create_mock_crypto_stream=*/false) {
- stream_ = new MockQuicCryptoStream(&session_);
- session_.SetCryptoStream(stream_);
- session_.Initialize();
- message_.set_tag(kSHLO);
- message_.SetStringPiece(1, "abc");
- message_.SetStringPiece(2, "def");
- ConstructHandshakeMessage();
- }
- QuicCryptoStreamTest(const QuicCryptoStreamTest&) = delete;
- QuicCryptoStreamTest& operator=(const QuicCryptoStreamTest&) = delete;
-
- void ConstructHandshakeMessage() {
- CryptoFramer framer;
- message_data_ = framer.ConstructHandshakeMessage(message_);
- }
-
- protected:
- MockQuicConnectionHelper helper_;
- MockAlarmFactory alarm_factory_;
- MockQuicConnection* connection_;
- MockQuicSpdySession session_;
- MockQuicCryptoStream* stream_;
- CryptoHandshakeMessage message_;
- std::unique_ptr<QuicData> message_data_;
-};
-
-TEST_F(QuicCryptoStreamTest, NotInitiallyConected) {
- EXPECT_FALSE(stream_->encryption_established());
- EXPECT_FALSE(stream_->one_rtt_keys_available());
-}
-
-TEST_F(QuicCryptoStreamTest, ProcessRawData) {
- if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
- stream_->OnStreamFrame(QuicStreamFrame(
- QuicUtils::GetCryptoStreamId(connection_->transport_version()),
- /*fin=*/false,
- /*offset=*/0, message_data_->AsStringPiece()));
- } else {
- stream_->OnCryptoFrame(QuicCryptoFrame(ENCRYPTION_INITIAL, /*offset*/ 0,
- message_data_->AsStringPiece()));
- }
- ASSERT_EQ(1u, stream_->messages()->size());
- const CryptoHandshakeMessage& message = (*stream_->messages())[0];
- EXPECT_EQ(kSHLO, message.tag());
- EXPECT_EQ(2u, message.tag_value_map().size());
- EXPECT_EQ("abc", crypto_test_utils::GetValueForTag(message, 1));
- EXPECT_EQ("def", crypto_test_utils::GetValueForTag(message, 2));
-}
-
-TEST_F(QuicCryptoStreamTest, ProcessBadData) {
- std::string bad(message_data_->data(), message_data_->length());
- const int kFirstTagIndex = sizeof(uint32_t) + // message tag
- sizeof(uint16_t) + // number of tag-value pairs
- sizeof(uint16_t); // padding
- EXPECT_EQ(1, bad[kFirstTagIndex]);
- bad[kFirstTagIndex] = 0x7F; // out of order tag
-
- EXPECT_CALL(*connection_, CloseConnection(QUIC_CRYPTO_TAGS_OUT_OF_ORDER,
- testing::_, testing::_));
- if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
- stream_->OnStreamFrame(QuicStreamFrame(
- QuicUtils::GetCryptoStreamId(connection_->transport_version()),
- /*fin=*/false, /*offset=*/0, bad));
- } else {
- stream_->OnCryptoFrame(
- QuicCryptoFrame(ENCRYPTION_INITIAL, /*offset*/ 0, bad));
- }
-}
-
-TEST_F(QuicCryptoStreamTest, NoConnectionLevelFlowControl) {
- EXPECT_FALSE(
- QuicStreamPeer::StreamContributesToConnectionFlowControl(stream_));
-}
-
-TEST_F(QuicCryptoStreamTest, RetransmitCryptoData) {
- if (QuicVersionUsesCryptoFrames(connection_->transport_version())) {
- return;
- }
- InSequence s;
- // Send [0, 1350) in ENCRYPTION_INITIAL.
- EXPECT_EQ(ENCRYPTION_INITIAL, connection_->encryption_level());
- std::string data(1350, 'a');
- EXPECT_CALL(
- session_,
- WritevData(QuicUtils::GetCryptoStreamId(connection_->transport_version()),
- 1350, 0, _, _, _))
- .WillOnce(Invoke(&session_, &MockQuicSpdySession::ConsumeData));
- stream_->WriteOrBufferData(data, false, nullptr);
- // Send [1350, 2700) in ENCRYPTION_ZERO_RTT.
- connection_->SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
- EXPECT_EQ(ENCRYPTION_ZERO_RTT, connection_->encryption_level());
- EXPECT_CALL(
- session_,
- WritevData(QuicUtils::GetCryptoStreamId(connection_->transport_version()),
- 1350, 1350, _, _, _))
- .WillOnce(Invoke(&session_, &MockQuicSpdySession::ConsumeData));
- stream_->WriteOrBufferData(data, false, nullptr);
- connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
- EXPECT_EQ(ENCRYPTION_FORWARD_SECURE, connection_->encryption_level());
-
- // Lost [0, 1000).
- stream_->OnStreamFrameLost(0, 1000, false);
- EXPECT_TRUE(stream_->HasPendingRetransmission());
- // Lost [1200, 2000).
- stream_->OnStreamFrameLost(1200, 800, false);
- EXPECT_CALL(
- session_,
- WritevData(QuicUtils::GetCryptoStreamId(connection_->transport_version()),
- 1000, 0, _, _, _))
- .WillOnce(Invoke(&session_, &MockQuicSpdySession::ConsumeData));
- // Verify [1200, 2000) are sent in [1200, 1350) and [1350, 2000) because of
- // they are in different encryption levels.
- EXPECT_CALL(
- session_,
- WritevData(QuicUtils::GetCryptoStreamId(connection_->transport_version()),
- 150, 1200, _, _, _))
- .WillOnce(Invoke(&session_, &MockQuicSpdySession::ConsumeData));
- EXPECT_CALL(
- session_,
- WritevData(QuicUtils::GetCryptoStreamId(connection_->transport_version()),
- 650, 1350, _, _, _))
- .WillOnce(Invoke(&session_, &MockQuicSpdySession::ConsumeData));
- stream_->OnCanWrite();
- EXPECT_FALSE(stream_->HasPendingRetransmission());
- // Verify connection's encryption level has restored.
- EXPECT_EQ(ENCRYPTION_FORWARD_SECURE, connection_->encryption_level());
-}
-
-TEST_F(QuicCryptoStreamTest, RetransmitCryptoDataInCryptoFrames) {
- if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
- return;
- }
- EXPECT_CALL(*connection_, SendCryptoData(_, _, _)).Times(0);
- InSequence s;
- // Send [0, 1350) in ENCRYPTION_INITIAL.
- EXPECT_EQ(ENCRYPTION_INITIAL, connection_->encryption_level());
- std::string data(1350, 'a');
- EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_INITIAL, 1350, 0))
- .WillOnce(Invoke(connection_,
- &MockQuicConnection::QuicConnection_SendCryptoData));
- stream_->WriteCryptoData(ENCRYPTION_INITIAL, data);
- // Send [1350, 2700) in ENCRYPTION_ZERO_RTT.
- std::unique_ptr<NullEncrypter> encrypter =
- std::make_unique<NullEncrypter>(Perspective::IS_CLIENT);
- connection_->SetEncrypter(ENCRYPTION_ZERO_RTT, std::move(encrypter));
- connection_->SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
- EXPECT_EQ(ENCRYPTION_ZERO_RTT, connection_->encryption_level());
- EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_ZERO_RTT, 1350, 0))
- .WillOnce(Invoke(connection_,
- &MockQuicConnection::QuicConnection_SendCryptoData));
- stream_->WriteCryptoData(ENCRYPTION_ZERO_RTT, data);
- connection_->SetEncrypter(
- ENCRYPTION_FORWARD_SECURE,
- std::make_unique<NullEncrypter>(Perspective::IS_CLIENT));
- connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
- EXPECT_EQ(ENCRYPTION_FORWARD_SECURE, connection_->encryption_level());
-
- // Lost [0, 1000).
- QuicCryptoFrame lost_frame(ENCRYPTION_INITIAL, 0, 1000);
- stream_->OnCryptoFrameLost(&lost_frame);
- EXPECT_TRUE(stream_->HasPendingCryptoRetransmission());
- // Lost [1200, 2000).
- lost_frame = QuicCryptoFrame(ENCRYPTION_INITIAL, 1200, 150);
- stream_->OnCryptoFrameLost(&lost_frame);
- lost_frame = QuicCryptoFrame(ENCRYPTION_ZERO_RTT, 0, 650);
- stream_->OnCryptoFrameLost(&lost_frame);
- EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_INITIAL, 1000, 0))
- .WillOnce(Invoke(connection_,
- &MockQuicConnection::QuicConnection_SendCryptoData));
- // Verify [1200, 2000) are sent in [1200, 1350) and [1350, 2000) because of
- // they are in different encryption levels.
- EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_INITIAL, 150, 1200))
- .WillOnce(Invoke(connection_,
- &MockQuicConnection::QuicConnection_SendCryptoData));
- EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_ZERO_RTT, 650, 0))
- .WillOnce(Invoke(connection_,
- &MockQuicConnection::QuicConnection_SendCryptoData));
- stream_->WritePendingCryptoRetransmission();
- EXPECT_FALSE(stream_->HasPendingCryptoRetransmission());
- // Verify connection's encryption level has restored.
- EXPECT_EQ(ENCRYPTION_FORWARD_SECURE, connection_->encryption_level());
-}
-
-// Regression test for handling the missing ENCRYPTION_HANDSHAKE in
-// quic_crypto_stream.cc. This test is essentially the same as
-// RetransmitCryptoDataInCryptoFrames, except it uses ENCRYPTION_HANDSHAKE in
-// place of ENCRYPTION_ZERO_RTT.
-TEST_F(QuicCryptoStreamTest, RetransmitEncryptionHandshakeLevelCryptoFrames) {
- if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
- return;
- }
- EXPECT_CALL(*connection_, SendCryptoData(_, _, _)).Times(0);
- InSequence s;
- // Send [0, 1000) in ENCRYPTION_INITIAL.
- EXPECT_EQ(ENCRYPTION_INITIAL, connection_->encryption_level());
- std::string data(1000, 'a');
- EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_INITIAL, 1000, 0))
- .WillOnce(Invoke(connection_,
- &MockQuicConnection::QuicConnection_SendCryptoData));
- stream_->WriteCryptoData(ENCRYPTION_INITIAL, data);
- // Send [1000, 2000) in ENCRYPTION_HANDSHAKE.
- std::unique_ptr<NullEncrypter> encrypter =
- std::make_unique<NullEncrypter>(Perspective::IS_CLIENT);
- connection_->SetEncrypter(ENCRYPTION_HANDSHAKE, std::move(encrypter));
- connection_->SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE);
- EXPECT_EQ(ENCRYPTION_HANDSHAKE, connection_->encryption_level());
- EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_HANDSHAKE, 1000, 0))
- .WillOnce(Invoke(connection_,
- &MockQuicConnection::QuicConnection_SendCryptoData));
- stream_->WriteCryptoData(ENCRYPTION_HANDSHAKE, data);
- connection_->SetEncrypter(
- ENCRYPTION_FORWARD_SECURE,
- std::make_unique<NullEncrypter>(Perspective::IS_CLIENT));
- connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
- EXPECT_EQ(ENCRYPTION_FORWARD_SECURE, connection_->encryption_level());
-
- // Lost [1000, 1200).
- QuicCryptoFrame lost_frame(ENCRYPTION_HANDSHAKE, 0, 200);
- stream_->OnCryptoFrameLost(&lost_frame);
- EXPECT_TRUE(stream_->HasPendingCryptoRetransmission());
- // Verify [1000, 1200) is sent.
- EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_HANDSHAKE, 200, 0))
- .WillOnce(Invoke(connection_,
- &MockQuicConnection::QuicConnection_SendCryptoData));
- stream_->WritePendingCryptoRetransmission();
- EXPECT_FALSE(stream_->HasPendingCryptoRetransmission());
-}
-
-TEST_F(QuicCryptoStreamTest, NeuterUnencryptedStreamData) {
- if (QuicVersionUsesCryptoFrames(connection_->transport_version())) {
- return;
- }
- // Send [0, 1350) in ENCRYPTION_INITIAL.
- EXPECT_EQ(ENCRYPTION_INITIAL, connection_->encryption_level());
- std::string data(1350, 'a');
- EXPECT_CALL(
- session_,
- WritevData(QuicUtils::GetCryptoStreamId(connection_->transport_version()),
- 1350, 0, _, _, _))
- .WillOnce(Invoke(&session_, &MockQuicSpdySession::ConsumeData));
- stream_->WriteOrBufferData(data, false, nullptr);
- // Send [1350, 2700) in ENCRYPTION_ZERO_RTT.
- connection_->SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
- EXPECT_EQ(ENCRYPTION_ZERO_RTT, connection_->encryption_level());
- EXPECT_CALL(
- session_,
- WritevData(QuicUtils::GetCryptoStreamId(connection_->transport_version()),
- 1350, 1350, _, _, _))
- .WillOnce(Invoke(&session_, &MockQuicSpdySession::ConsumeData));
- stream_->WriteOrBufferData(data, false, nullptr);
-
- // Lost [0, 1350).
- stream_->OnStreamFrameLost(0, 1350, false);
- EXPECT_TRUE(stream_->HasPendingRetransmission());
- // Neuters [0, 1350).
- stream_->NeuterUnencryptedStreamData();
- EXPECT_FALSE(stream_->HasPendingRetransmission());
- // Lost [0, 1350) again.
- stream_->OnStreamFrameLost(0, 1350, false);
- EXPECT_FALSE(stream_->HasPendingRetransmission());
-
- // Lost [1350, 2000).
- stream_->OnStreamFrameLost(1350, 650, false);
- EXPECT_TRUE(stream_->HasPendingRetransmission());
- stream_->NeuterUnencryptedStreamData();
- EXPECT_TRUE(stream_->HasPendingRetransmission());
-}
-
-TEST_F(QuicCryptoStreamTest, NeuterUnencryptedCryptoData) {
- if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
- return;
- }
- // Send [0, 1350) in ENCRYPTION_INITIAL.
- EXPECT_EQ(ENCRYPTION_INITIAL, connection_->encryption_level());
- std::string data(1350, 'a');
- EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_INITIAL, 1350, 0))
- .WillOnce(Invoke(connection_,
- &MockQuicConnection::QuicConnection_SendCryptoData));
- stream_->WriteCryptoData(ENCRYPTION_INITIAL, data);
- // Send [1350, 2700) in ENCRYPTION_ZERO_RTT.
- connection_->SetEncrypter(
- ENCRYPTION_ZERO_RTT,
- std::make_unique<NullEncrypter>(Perspective::IS_CLIENT));
- connection_->SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
- std::unique_ptr<NullEncrypter> encrypter =
- std::make_unique<NullEncrypter>(Perspective::IS_CLIENT);
- connection_->SetEncrypter(ENCRYPTION_ZERO_RTT, std::move(encrypter));
- EXPECT_EQ(ENCRYPTION_ZERO_RTT, connection_->encryption_level());
- EXPECT_CALL(*connection_, SendCryptoData(_, _, _)).Times(0);
- EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_ZERO_RTT, 1350, 0))
- .WillOnce(Invoke(connection_,
- &MockQuicConnection::QuicConnection_SendCryptoData));
- stream_->WriteCryptoData(ENCRYPTION_ZERO_RTT, data);
-
- // Lost [0, 1350).
- QuicCryptoFrame lost_frame(ENCRYPTION_INITIAL, 0, 1350);
- stream_->OnCryptoFrameLost(&lost_frame);
- EXPECT_TRUE(stream_->HasPendingCryptoRetransmission());
- // Neuters [0, 1350).
- stream_->NeuterUnencryptedStreamData();
- EXPECT_FALSE(stream_->HasPendingCryptoRetransmission());
- // Lost [0, 1350) again.
- stream_->OnCryptoFrameLost(&lost_frame);
- EXPECT_FALSE(stream_->HasPendingCryptoRetransmission());
-
- // Lost [1350, 2000), which starts at offset 0 at the ENCRYPTION_ZERO_RTT
- // level.
- lost_frame = QuicCryptoFrame(ENCRYPTION_ZERO_RTT, 0, 650);
- stream_->OnCryptoFrameLost(&lost_frame);
- EXPECT_TRUE(stream_->HasPendingCryptoRetransmission());
- stream_->NeuterUnencryptedStreamData();
- EXPECT_TRUE(stream_->HasPendingCryptoRetransmission());
-}
-
-TEST_F(QuicCryptoStreamTest, RetransmitStreamData) {
- if (QuicVersionUsesCryptoFrames(connection_->transport_version())) {
- return;
- }
- InSequence s;
- // Send [0, 1350) in ENCRYPTION_INITIAL.
- EXPECT_EQ(ENCRYPTION_INITIAL, connection_->encryption_level());
- std::string data(1350, 'a');
- EXPECT_CALL(
- session_,
- WritevData(QuicUtils::GetCryptoStreamId(connection_->transport_version()),
- 1350, 0, _, _, _))
- .WillOnce(Invoke(&session_, &MockQuicSpdySession::ConsumeData));
- stream_->WriteOrBufferData(data, false, nullptr);
- // Send [1350, 2700) in ENCRYPTION_ZERO_RTT.
- connection_->SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
- EXPECT_EQ(ENCRYPTION_ZERO_RTT, connection_->encryption_level());
- EXPECT_CALL(
- session_,
- WritevData(QuicUtils::GetCryptoStreamId(connection_->transport_version()),
- 1350, 1350, _, _, _))
- .WillOnce(Invoke(&session_, &MockQuicSpdySession::ConsumeData));
- stream_->WriteOrBufferData(data, false, nullptr);
- connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
- EXPECT_EQ(ENCRYPTION_FORWARD_SECURE, connection_->encryption_level());
-
- // Ack [2000, 2500).
- QuicByteCount newly_acked_length = 0;
- stream_->OnStreamFrameAcked(2000, 500, false, QuicTime::Delta::Zero(),
- QuicTime::Zero(), &newly_acked_length);
- EXPECT_EQ(500u, newly_acked_length);
-
- // Force crypto stream to send [1350, 2700) and only [1350, 1500) is consumed.
- EXPECT_CALL(
- session_,
- WritevData(QuicUtils::GetCryptoStreamId(connection_->transport_version()),
- 650, 1350, _, _, _))
- .WillOnce(InvokeWithoutArgs([this]() {
- return session_.ConsumeData(
- QuicUtils::GetCryptoStreamId(connection_->transport_version()), 150,
- 1350, NO_FIN, HANDSHAKE_RETRANSMISSION, absl::nullopt);
- }));
-
- EXPECT_FALSE(stream_->RetransmitStreamData(1350, 1350, false,
- HANDSHAKE_RETRANSMISSION));
- // Verify connection's encryption level has restored.
- EXPECT_EQ(ENCRYPTION_FORWARD_SECURE, connection_->encryption_level());
-
- // Force session to send [1350, 1500) again and all data is consumed.
- EXPECT_CALL(
- session_,
- WritevData(QuicUtils::GetCryptoStreamId(connection_->transport_version()),
- 650, 1350, _, _, _))
- .WillOnce(Invoke(&session_, &MockQuicSpdySession::ConsumeData));
- EXPECT_CALL(
- session_,
- WritevData(QuicUtils::GetCryptoStreamId(connection_->transport_version()),
- 200, 2500, _, _, _))
- .WillOnce(Invoke(&session_, &MockQuicSpdySession::ConsumeData));
- EXPECT_TRUE(stream_->RetransmitStreamData(1350, 1350, false,
- HANDSHAKE_RETRANSMISSION));
- // Verify connection's encryption level has restored.
- EXPECT_EQ(ENCRYPTION_FORWARD_SECURE, connection_->encryption_level());
-
- EXPECT_CALL(session_, WritevData(_, _, _, _, _, _)).Times(0);
- // Force to send an empty frame.
- EXPECT_TRUE(
- stream_->RetransmitStreamData(0, 0, false, HANDSHAKE_RETRANSMISSION));
-}
-
-TEST_F(QuicCryptoStreamTest, RetransmitStreamDataWithCryptoFrames) {
- if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
- return;
- }
- InSequence s;
- // Send [0, 1350) in ENCRYPTION_INITIAL.
- EXPECT_EQ(ENCRYPTION_INITIAL, connection_->encryption_level());
- std::string data(1350, 'a');
- EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_INITIAL, 1350, 0))
- .WillOnce(Invoke(connection_,
- &MockQuicConnection::QuicConnection_SendCryptoData));
- stream_->WriteCryptoData(ENCRYPTION_INITIAL, data);
- // Send [1350, 2700) in ENCRYPTION_ZERO_RTT.
- std::unique_ptr<NullEncrypter> encrypter =
- std::make_unique<NullEncrypter>(Perspective::IS_CLIENT);
- connection_->SetEncrypter(ENCRYPTION_ZERO_RTT, std::move(encrypter));
- connection_->SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
- EXPECT_EQ(ENCRYPTION_ZERO_RTT, connection_->encryption_level());
- EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_ZERO_RTT, 1350, 0))
- .WillOnce(Invoke(connection_,
- &MockQuicConnection::QuicConnection_SendCryptoData));
- stream_->WriteCryptoData(ENCRYPTION_ZERO_RTT, data);
- connection_->SetEncrypter(
- ENCRYPTION_FORWARD_SECURE,
- std::make_unique<NullEncrypter>(Perspective::IS_CLIENT));
- connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
- EXPECT_EQ(ENCRYPTION_FORWARD_SECURE, connection_->encryption_level());
-
- // Ack [2000, 2500).
- QuicCryptoFrame acked_frame(ENCRYPTION_ZERO_RTT, 650, 500);
- EXPECT_TRUE(
- stream_->OnCryptoFrameAcked(acked_frame, QuicTime::Delta::Zero()));
-
- // Retransmit only [1350, 1500).
- EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_ZERO_RTT, 150, 0))
- .WillOnce(Invoke(connection_,
- &MockQuicConnection::QuicConnection_SendCryptoData));
- QuicCryptoFrame frame_to_retransmit(ENCRYPTION_ZERO_RTT, 0, 150);
- stream_->RetransmitData(&frame_to_retransmit, HANDSHAKE_RETRANSMISSION);
-
- // Verify connection's encryption level has restored.
- 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))
- .WillOnce(Invoke(connection_,
- &MockQuicConnection::QuicConnection_SendCryptoData));
- EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_ZERO_RTT, 200, 1150))
- .WillOnce(Invoke(connection_,
- &MockQuicConnection::QuicConnection_SendCryptoData));
- frame_to_retransmit = QuicCryptoFrame(ENCRYPTION_ZERO_RTT, 0, 1350);
- stream_->RetransmitData(&frame_to_retransmit, HANDSHAKE_RETRANSMISSION);
- // Verify connection's encryption level has restored.
- EXPECT_EQ(ENCRYPTION_FORWARD_SECURE, connection_->encryption_level());
-
- EXPECT_CALL(*connection_, SendCryptoData(_, _, _)).Times(0);
- // Force to send an empty frame.
- QuicCryptoFrame empty_frame(ENCRYPTION_FORWARD_SECURE, 0, 0);
- stream_->RetransmitData(&empty_frame, HANDSHAKE_RETRANSMISSION);
-}
-
-// Regression test for b/115926584.
-TEST_F(QuicCryptoStreamTest, HasUnackedCryptoData) {
- if (QuicVersionUsesCryptoFrames(connection_->transport_version())) {
- return;
- }
- std::string data(1350, 'a');
- EXPECT_CALL(
- session_,
- WritevData(QuicUtils::GetCryptoStreamId(connection_->transport_version()),
- 1350, 0, _, _, _))
- .WillOnce(testing::Return(QuicConsumedData(0, false)));
- stream_->WriteOrBufferData(data, false, nullptr);
- EXPECT_FALSE(stream_->IsWaitingForAcks());
- // Although there is no outstanding data, verify session has pending crypto
- // data.
- EXPECT_TRUE(session_.HasUnackedCryptoData());
-
- EXPECT_CALL(
- session_,
- WritevData(QuicUtils::GetCryptoStreamId(connection_->transport_version()),
- 1350, 0, _, _, _))
- .WillOnce(Invoke(&session_, &MockQuicSpdySession::ConsumeData));
- stream_->OnCanWrite();
- EXPECT_TRUE(stream_->IsWaitingForAcks());
- EXPECT_TRUE(session_.HasUnackedCryptoData());
-}
-
-TEST_F(QuicCryptoStreamTest, HasUnackedCryptoDataWithCryptoFrames) {
- if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
- return;
- }
- // Send [0, 1350) in ENCRYPTION_INITIAL.
- EXPECT_EQ(ENCRYPTION_INITIAL, connection_->encryption_level());
- std::string data(1350, 'a');
- EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_INITIAL, 1350, 0))
- .WillOnce(Invoke(connection_,
- &MockQuicConnection::QuicConnection_SendCryptoData));
- stream_->WriteCryptoData(ENCRYPTION_INITIAL, data);
- EXPECT_TRUE(stream_->IsWaitingForAcks());
- EXPECT_TRUE(session_.HasUnackedCryptoData());
-}
-
-// Regression test for bugfix of GetPacketHeaderSize.
-TEST_F(QuicCryptoStreamTest, CryptoMessageFramingOverhead) {
- for (const ParsedQuicVersion& version :
- AllSupportedVersionsWithQuicCrypto()) {
- SCOPED_TRACE(version);
- QuicByteCount expected_overhead = 48;
- if (version.HasIetfInvariantHeader()) {
- expected_overhead += 4;
- }
- if (version.HasLongHeaderLengths()) {
- expected_overhead += 3;
- }
- if (version.HasLengthPrefixedConnectionIds()) {
- expected_overhead += 1;
- }
- EXPECT_EQ(expected_overhead,
- QuicCryptoStream::CryptoMessageFramingOverhead(
- version.transport_version, TestConnectionId()));
- }
-}
-
-TEST_F(QuicCryptoStreamTest, WriteBufferedCryptoFrames) {
- if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
- return;
- }
- EXPECT_FALSE(stream_->HasBufferedCryptoFrames());
- InSequence s;
- // Send [0, 1350) in ENCRYPTION_INITIAL.
- EXPECT_EQ(ENCRYPTION_INITIAL, connection_->encryption_level());
- std::string data(1350, 'a');
- // Only consumed 1000 bytes.
- EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_INITIAL, 1350, 0))
- .WillOnce(Return(1000));
- stream_->WriteCryptoData(ENCRYPTION_INITIAL, data);
- EXPECT_TRUE(stream_->HasBufferedCryptoFrames());
-
- // Send [1350, 2700) in ENCRYPTION_ZERO_RTT and verify no write is attempted
- // because there is buffered data.
- EXPECT_CALL(*connection_, SendCryptoData(_, _, _)).Times(0);
- connection_->SetEncrypter(
- ENCRYPTION_ZERO_RTT,
- std::make_unique<NullEncrypter>(Perspective::IS_CLIENT));
- connection_->SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
- stream_->WriteCryptoData(ENCRYPTION_ZERO_RTT, data);
- EXPECT_EQ(ENCRYPTION_ZERO_RTT, connection_->encryption_level());
-
- EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_INITIAL, 350, 1000))
- .WillOnce(Return(350));
- // Partial write of ENCRYPTION_ZERO_RTT data.
- EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_ZERO_RTT, 1350, 0))
- .WillOnce(Return(1000));
- stream_->WriteBufferedCryptoFrames();
- EXPECT_TRUE(stream_->HasBufferedCryptoFrames());
- EXPECT_EQ(ENCRYPTION_ZERO_RTT, connection_->encryption_level());
-
- EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_ZERO_RTT, 350, 1000))
- .WillOnce(Return(350));
- stream_->WriteBufferedCryptoFrames();
- EXPECT_FALSE(stream_->HasBufferedCryptoFrames());
-}
-
-TEST_F(QuicCryptoStreamTest, LimitBufferedCryptoData) {
- if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
- return;
- }
-
- EXPECT_CALL(*connection_,
- CloseConnection(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA, _, _));
- std::string large_frame(2 * GetQuicFlag(FLAGS_quic_max_buffered_crypto_bytes),
- 'a');
-
- // Set offset to 1 so that we guarantee the data gets buffered instead of
- // immediately processed.
- QuicStreamOffset offset = 1;
- stream_->OnCryptoFrame(
- QuicCryptoFrame(ENCRYPTION_INITIAL, offset, large_frame));
-}
-
-TEST_F(QuicCryptoStreamTest, RetransmitCryptoFramesAndPartialWrite) {
- if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
- return;
- }
-
- EXPECT_CALL(*connection_, SendCryptoData(_, _, _)).Times(0);
- InSequence s;
- // Send [0, 1350) in ENCRYPTION_INITIAL.
- EXPECT_EQ(ENCRYPTION_INITIAL, connection_->encryption_level());
- std::string data(1350, 'a');
- EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_INITIAL, 1350, 0))
- .WillOnce(Invoke(connection_,
- &MockQuicConnection::QuicConnection_SendCryptoData));
- stream_->WriteCryptoData(ENCRYPTION_INITIAL, data);
-
- // Lost [0, 1000).
- QuicCryptoFrame lost_frame(ENCRYPTION_INITIAL, 0, 1000);
- stream_->OnCryptoFrameLost(&lost_frame);
- EXPECT_TRUE(stream_->HasPendingCryptoRetransmission());
- // Simulate connection is constrained by amplification restriction.
- EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_INITIAL, 1000, 0))
- .WillOnce(Return(0));
- stream_->WritePendingCryptoRetransmission();
- EXPECT_TRUE(stream_->HasPendingCryptoRetransmission());
- // Connection gets unblocked.
- EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_INITIAL, 1000, 0))
- .WillOnce(Invoke(connection_,
- &MockQuicConnection::QuicConnection_SendCryptoData));
- stream_->WritePendingCryptoRetransmission();
- EXPECT_FALSE(stream_->HasPendingCryptoRetransmission());
-}
-
-// Regression test for b/203199510
-TEST_F(QuicCryptoStreamTest, EmptyCryptoFrame) {
- if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
- return;
- }
- if (GetQuicReloadableFlag(quic_accept_empty_crypto_frame)) {
- EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
- } else {
- EXPECT_CALL(*connection_,
- CloseConnection(QUIC_EMPTY_STREAM_FRAME_NO_FIN, _, _));
- }
- QuicCryptoFrame empty_crypto_frame(ENCRYPTION_INITIAL, 0, nullptr, 0);
- stream_->OnCryptoFrame(empty_crypto_frame);
-}
-
-} // namespace
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_data_reader.cc b/chromium/net/third_party/quiche/src/quic/core/quic_data_reader.cc
deleted file mode 100644
index 7b605d36661..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_data_reader.cc
+++ /dev/null
@@ -1,176 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_data_reader.h"
-
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_flags.h"
-#include "common/quiche_endian.h"
-
-namespace quic {
-
-QuicDataReader::QuicDataReader(absl::string_view data)
- : quiche::QuicheDataReader(data) {}
-
-QuicDataReader::QuicDataReader(const char* data, const size_t len)
- : QuicDataReader(data, len, quiche::NETWORK_BYTE_ORDER) {}
-
-QuicDataReader::QuicDataReader(const char* data,
- const size_t len,
- quiche::Endianness endianness)
- : quiche::QuicheDataReader(data, len, endianness) {}
-
-bool QuicDataReader::ReadUFloat16(uint64_t* result) {
- uint16_t value;
- if (!ReadUInt16(&value)) {
- return false;
- }
-
- *result = value;
- if (*result < (1 << kUFloat16MantissaEffectiveBits)) {
- // Fast path: either the value is denormalized (no hidden bit), or
- // normalized (hidden bit set, exponent offset by one) with exponent zero.
- // Zero exponent offset by one sets the bit exactly where the hidden bit is.
- // So in both cases the value encodes itself.
- return true;
- }
-
- uint16_t exponent =
- value >> kUFloat16MantissaBits; // No sign extend on uint!
- // After the fast pass, the exponent is at least one (offset by one).
- // Un-offset the exponent.
- --exponent;
- QUICHE_DCHECK_GE(exponent, 1);
- QUICHE_DCHECK_LE(exponent, kUFloat16MaxExponent);
- // Here we need to clear the exponent and set the hidden bit. We have already
- // decremented the exponent, so when we subtract it, it leaves behind the
- // hidden bit.
- *result -= exponent << kUFloat16MantissaBits;
- *result <<= exponent;
- QUICHE_DCHECK_GE(*result,
- static_cast<uint64_t>(1 << kUFloat16MantissaEffectiveBits));
- QUICHE_DCHECK_LE(*result, kUFloat16MaxValue);
- return true;
-}
-
-bool QuicDataReader::ReadConnectionId(QuicConnectionId* connection_id,
- uint8_t length) {
- if (length == 0) {
- connection_id->set_length(0);
- return true;
- }
-
- if (BytesRemaining() < length) {
- return false;
- }
-
- connection_id->set_length(length);
- const bool ok =
- ReadBytes(connection_id->mutable_data(), connection_id->length());
- QUICHE_DCHECK(ok);
- return ok;
-}
-
-bool QuicDataReader::ReadLengthPrefixedConnectionId(
- QuicConnectionId* connection_id) {
- uint8_t connection_id_length;
- if (!ReadUInt8(&connection_id_length)) {
- return false;
- }
- return ReadConnectionId(connection_id, connection_id_length);
-}
-
-QuicVariableLengthIntegerLength QuicDataReader::PeekVarInt62Length() {
- QUICHE_DCHECK_EQ(endianness(), quiche::NETWORK_BYTE_ORDER);
- const unsigned char* next =
- reinterpret_cast<const unsigned char*>(data() + pos());
- if (BytesRemaining() == 0) {
- return VARIABLE_LENGTH_INTEGER_LENGTH_0;
- }
- return static_cast<QuicVariableLengthIntegerLength>(
- 1 << ((*next & 0b11000000) >> 6));
-}
-
-// Read an IETF/QUIC formatted 62-bit Variable Length Integer.
-//
-// Performance notes
-//
-// Measurements and experiments showed that unrolling the four cases
-// like this and dereferencing next_ as we do (*(next_+n) --- and then
-// doing a single pos_+=x at the end) gains about 10% over making a
-// loop and dereferencing next_ such as *(next_++)
-//
-// Using a register for pos_ was not helpful.
-//
-// Branches are ordered to increase the likelihood of the first being
-// taken.
-//
-// Low-level optimization is useful here because this function will be
-// called frequently, leading to outsize benefits.
-bool QuicDataReader::ReadVarInt62(uint64_t* result) {
- QUICHE_DCHECK_EQ(endianness(), quiche::NETWORK_BYTE_ORDER);
-
- size_t remaining = BytesRemaining();
- const unsigned char* next =
- reinterpret_cast<const unsigned char*>(data() + pos());
- if (remaining != 0) {
- switch (*next & 0xc0) {
- case 0xc0:
- // Leading 0b11...... is 8 byte encoding
- if (remaining >= 8) {
- *result = (static_cast<uint64_t>((*(next)) & 0x3f) << 56) +
- (static_cast<uint64_t>(*(next + 1)) << 48) +
- (static_cast<uint64_t>(*(next + 2)) << 40) +
- (static_cast<uint64_t>(*(next + 3)) << 32) +
- (static_cast<uint64_t>(*(next + 4)) << 24) +
- (static_cast<uint64_t>(*(next + 5)) << 16) +
- (static_cast<uint64_t>(*(next + 6)) << 8) +
- (static_cast<uint64_t>(*(next + 7)) << 0);
- AdvancePos(8);
- return true;
- }
- return false;
-
- case 0x80:
- // Leading 0b10...... is 4 byte encoding
- if (remaining >= 4) {
- *result = (((*(next)) & 0x3f) << 24) + (((*(next + 1)) << 16)) +
- (((*(next + 2)) << 8)) + (((*(next + 3)) << 0));
- AdvancePos(4);
- return true;
- }
- return false;
-
- case 0x40:
- // Leading 0b01...... is 2 byte encoding
- if (remaining >= 2) {
- *result = (((*(next)) & 0x3f) << 8) + (*(next + 1));
- AdvancePos(2);
- return true;
- }
- return false;
-
- case 0x00:
- // Leading 0b00...... is 1 byte encoding
- *result = (*next) & 0x3f;
- AdvancePos(1);
- return true;
- }
- }
- return false;
-}
-
-bool QuicDataReader::ReadStringPieceVarInt62(absl::string_view* result) {
- uint64_t result_length;
- if (!ReadVarInt62(&result_length)) {
- return false;
- }
- return ReadStringPiece(result, result_length);
-}
-
-#undef ENDPOINT // undef for jumbo builds
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_data_reader.h b/chromium/net/third_party/quiche/src/quic/core/quic_data_reader.h
deleted file mode 100644
index cca22410684..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_data_reader.h
+++ /dev/null
@@ -1,93 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_DATA_READER_H_
-#define QUICHE_QUIC_CORE_QUIC_DATA_READER_H_
-
-#include <cstddef>
-#include <cstdint>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_export.h"
-#include "common/quiche_data_reader.h"
-#include "common/quiche_endian.h"
-
-namespace quic {
-
-// Used for reading QUIC data. Though there isn't really anything terribly
-// QUIC-specific here, it's a helper class that's useful when doing QUIC
-// framing.
-//
-// To use, simply construct a QuicDataReader using the underlying buffer that
-// you'd like to read fields from, then call one of the Read*() methods to
-// actually do some reading.
-//
-// This class keeps an internal iterator to keep track of what's already been
-// read and each successive Read*() call automatically increments said iterator
-// on success. On failure, internal state of the QuicDataReader should not be
-// trusted and it is up to the caller to throw away the failed instance and
-// handle the error as appropriate. None of the Read*() methods should ever be
-// called after failure, as they will also fail immediately.
-class QUIC_EXPORT_PRIVATE QuicDataReader : public quiche::QuicheDataReader {
- public:
- // Constructs a reader using NETWORK_BYTE_ORDER endianness.
- // Caller must provide an underlying buffer to work on.
- explicit QuicDataReader(absl::string_view data);
- // Constructs a reader using NETWORK_BYTE_ORDER endianness.
- // Caller must provide an underlying buffer to work on.
- QuicDataReader(const char* data, const size_t len);
- // Constructs a reader using the specified endianness.
- // Caller must provide an underlying buffer to work on.
- QuicDataReader(const char* data,
- const size_t len,
- quiche::Endianness endianness);
- QuicDataReader(const QuicDataReader&) = delete;
- QuicDataReader& operator=(const QuicDataReader&) = delete;
-
- // Empty destructor.
- ~QuicDataReader() {}
-
- // Reads a 16-bit unsigned float into the given output parameter.
- // Forwards the internal iterator on success.
- // Returns true on success, false otherwise.
- bool ReadUFloat16(uint64_t* result);
-
- // Reads connection ID into the given output parameter.
- // Forwards the internal iterator on success.
- // Returns true on success, false otherwise.
- bool ReadConnectionId(QuicConnectionId* connection_id, uint8_t length);
-
- // Reads 8-bit connection ID length followed by connection ID of that length.
- // Forwards the internal iterator on success.
- // Returns true on success, false otherwise.
- bool ReadLengthPrefixedConnectionId(QuicConnectionId* connection_id);
-
- // Returns the length in bytes of a variable length integer based on the next
- // two bits available. Returns 1, 2, 4, or 8 on success, and 0 on failure.
- QuicVariableLengthIntegerLength PeekVarInt62Length();
-
- // Read an IETF-encoded Variable Length Integer and place the result
- // in |*result|.
- // Returns true if it works, false if not. The only error is that
- // there is not enough in the buffer to read the number.
- // If there is an error, |*result| is not altered.
- // Numbers are encoded per the rules in draft-ietf-quic-transport-10.txt
- // and that the integers in the range 0 ... (2^62)-1.
- bool ReadVarInt62(uint64_t* result);
-
- // Reads a string prefixed with a Variable Length integer length into the
- // given output parameter.
- //
- // NOTE: Does not copy but rather references strings in the underlying buffer.
- // This should be kept in mind when handling memory management!
- //
- // Forwards the internal iterator on success.
- // Returns true on success, false otherwise.
- bool ReadStringPieceVarInt62(absl::string_view* result);
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_QUIC_DATA_READER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_data_writer.cc b/chromium/net/third_party/quiche/src/quic/core/quic_data_writer.cc
deleted file mode 100644
index ee3c861ee8c..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_data_writer.cc
+++ /dev/null
@@ -1,260 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_data_writer.h"
-
-#include <algorithm>
-#include <limits>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/crypto/quic_random.h"
-#include "quic/core/quic_constants.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_flags.h"
-#include "common/quiche_endian.h"
-
-namespace quic {
-
-QuicDataWriter::QuicDataWriter(size_t size, char* buffer)
- : quiche::QuicheDataWriter(size, buffer) {}
-
-QuicDataWriter::QuicDataWriter(size_t size,
- char* buffer,
- quiche::Endianness endianness)
- : quiche::QuicheDataWriter(size, buffer, endianness) {}
-
-QuicDataWriter::~QuicDataWriter() {}
-
-bool QuicDataWriter::WriteUFloat16(uint64_t value) {
- uint16_t result;
- if (value < (UINT64_C(1) << kUFloat16MantissaEffectiveBits)) {
- // Fast path: either the value is denormalized, or has exponent zero.
- // Both cases are represented by the value itself.
- result = static_cast<uint16_t>(value);
- } else if (value >= kUFloat16MaxValue) {
- // Value is out of range; clamp it to the maximum representable.
- result = std::numeric_limits<uint16_t>::max();
- } else {
- // The highest bit is between position 13 and 42 (zero-based), which
- // corresponds to exponent 1-30. In the output, mantissa is from 0 to 10,
- // hidden bit is 11 and exponent is 11 to 15. Shift the highest bit to 11
- // and count the shifts.
- uint16_t exponent = 0;
- for (uint16_t offset = 16; offset > 0; offset /= 2) {
- // Right-shift the value until the highest bit is in position 11.
- // For offset of 16, 8, 4, 2 and 1 (binary search over 1-30),
- // shift if the bit is at or above 11 + offset.
- if (value >= (UINT64_C(1) << (kUFloat16MantissaBits + offset))) {
- exponent += offset;
- value >>= offset;
- }
- }
-
- QUICHE_DCHECK_GE(exponent, 1);
- QUICHE_DCHECK_LE(exponent, kUFloat16MaxExponent);
- QUICHE_DCHECK_GE(value, UINT64_C(1) << kUFloat16MantissaBits);
- QUICHE_DCHECK_LT(value, UINT64_C(1) << kUFloat16MantissaEffectiveBits);
-
- // Hidden bit (position 11) is set. We should remove it and increment the
- // exponent. Equivalently, we just add it to the exponent.
- // This hides the bit.
- result = static_cast<uint16_t>(value + (exponent << kUFloat16MantissaBits));
- }
-
- if (endianness() == quiche::NETWORK_BYTE_ORDER) {
- result = quiche::QuicheEndian::HostToNet16(result);
- }
- return WriteBytes(&result, sizeof(result));
-}
-
-bool QuicDataWriter::WriteConnectionId(QuicConnectionId connection_id) {
- if (connection_id.IsEmpty()) {
- return true;
- }
- return WriteBytes(connection_id.data(), connection_id.length());
-}
-
-bool QuicDataWriter::WriteLengthPrefixedConnectionId(
- QuicConnectionId connection_id) {
- return WriteUInt8(connection_id.length()) && WriteConnectionId(connection_id);
-}
-
-bool QuicDataWriter::WriteRandomBytes(QuicRandom* random, size_t length) {
- char* dest = BeginWrite(length);
- if (!dest) {
- return false;
- }
-
- random->RandBytes(dest, length);
- IncreaseLength(length);
- return true;
-}
-
-bool QuicDataWriter::WriteInsecureRandomBytes(QuicRandom* random,
- size_t length) {
- char* dest = BeginWrite(length);
- if (!dest) {
- return false;
- }
-
- random->InsecureRandBytes(dest, length);
- IncreaseLength(length);
- return true;
-}
-
-// Converts a uint64_t into an IETF/Quic formatted Variable Length
-// Integer. IETF Variable Length Integers have 62 significant bits, so
-// the value to write must be in the range of 0..(2^62)-1.
-//
-// Performance notes
-//
-// Measurements and experiments showed that unrolling the four cases
-// like this and dereferencing next_ as we do (*(next_+n)) gains about
-// 10% over making a loop and dereferencing it as *(next_++)
-//
-// Using a register for next didn't help.
-//
-// Branches are ordered to increase the likelihood of the first being
-// taken.
-//
-// Low-level optimization is useful here because this function will be
-// called frequently, leading to outsize benefits.
-bool QuicDataWriter::WriteVarInt62(uint64_t value) {
- QUICHE_DCHECK_EQ(endianness(), quiche::NETWORK_BYTE_ORDER);
-
- size_t remaining_bytes = remaining();
- char* next = buffer() + length();
-
- if ((value & kVarInt62ErrorMask) == 0) {
- // We know the high 2 bits are 0 so |value| is legal.
- // We can do the encoding.
- if ((value & kVarInt62Mask8Bytes) != 0) {
- // Someplace in the high-4 bytes is a 1-bit. Do an 8-byte
- // encoding.
- if (remaining_bytes >= 8) {
- *(next + 0) = ((value >> 56) & 0x3f) + 0xc0;
- *(next + 1) = (value >> 48) & 0xff;
- *(next + 2) = (value >> 40) & 0xff;
- *(next + 3) = (value >> 32) & 0xff;
- *(next + 4) = (value >> 24) & 0xff;
- *(next + 5) = (value >> 16) & 0xff;
- *(next + 6) = (value >> 8) & 0xff;
- *(next + 7) = value & 0xff;
- IncreaseLength(8);
- return true;
- }
- return false;
- }
- // The high-order-4 bytes are all 0, check for a 1, 2, or 4-byte
- // encoding
- if ((value & kVarInt62Mask4Bytes) != 0) {
- // The encoding will not fit into 2 bytes, Do a 4-byte
- // encoding.
- if (remaining_bytes >= 4) {
- *(next + 0) = ((value >> 24) & 0x3f) + 0x80;
- *(next + 1) = (value >> 16) & 0xff;
- *(next + 2) = (value >> 8) & 0xff;
- *(next + 3) = value & 0xff;
- IncreaseLength(4);
- return true;
- }
- return false;
- }
- // The high-order bits are all 0. Check to see if the number
- // can be encoded as one or two bytes. One byte encoding has
- // only 6 significant bits (bits 0xffffffff ffffffc0 are all 0).
- // Two byte encoding has more than 6, but 14 or less significant
- // bits (bits 0xffffffff ffffc000 are 0 and 0x00000000 00003fc0
- // are not 0)
- if ((value & kVarInt62Mask2Bytes) != 0) {
- // Do 2-byte encoding
- if (remaining_bytes >= 2) {
- *(next + 0) = ((value >> 8) & 0x3f) + 0x40;
- *(next + 1) = (value)&0xff;
- IncreaseLength(2);
- return true;
- }
- return false;
- }
- if (remaining_bytes >= 1) {
- // Do 1-byte encoding
- *next = (value & 0x3f);
- IncreaseLength(1);
- return true;
- }
- return false;
- }
- // Can not encode, high 2 bits not 0
- return false;
-}
-
-bool QuicDataWriter::WriteVarInt62(
- uint64_t value,
- QuicVariableLengthIntegerLength write_length) {
- QUICHE_DCHECK_EQ(endianness(), quiche::NETWORK_BYTE_ORDER);
-
- size_t remaining_bytes = remaining();
- if (remaining_bytes < write_length) {
- return false;
- }
-
- const QuicVariableLengthIntegerLength min_length = GetVarInt62Len(value);
- if (write_length < min_length) {
- QUIC_BUG(quic_bug_10347_1) << "Cannot write value " << value
- << " with write_length " << write_length;
- return false;
- }
- if (write_length == min_length) {
- return WriteVarInt62(value);
- }
-
- if (write_length == VARIABLE_LENGTH_INTEGER_LENGTH_2) {
- return WriteUInt8(0b01000000) && WriteUInt8(value);
- }
- if (write_length == VARIABLE_LENGTH_INTEGER_LENGTH_4) {
- return WriteUInt8(0b10000000) && WriteUInt8(0) && WriteUInt16(value);
- }
- if (write_length == VARIABLE_LENGTH_INTEGER_LENGTH_8) {
- return WriteUInt8(0b11000000) && WriteUInt8(0) && WriteUInt16(0) &&
- WriteUInt32(value);
- }
-
- QUIC_BUG(quic_bug_10347_2)
- << "Invalid write_length " << static_cast<int>(write_length);
- return false;
-}
-
-// static
-QuicVariableLengthIntegerLength QuicDataWriter::GetVarInt62Len(uint64_t value) {
- if ((value & kVarInt62ErrorMask) != 0) {
- QUIC_BUG(quic_bug_10347_3) << "Attempted to encode a value, " << value
- << ", that is too big for VarInt62";
- return VARIABLE_LENGTH_INTEGER_LENGTH_0;
- }
- if ((value & kVarInt62Mask8Bytes) != 0) {
- return VARIABLE_LENGTH_INTEGER_LENGTH_8;
- }
- if ((value & kVarInt62Mask4Bytes) != 0) {
- return VARIABLE_LENGTH_INTEGER_LENGTH_4;
- }
- if ((value & kVarInt62Mask2Bytes) != 0) {
- return VARIABLE_LENGTH_INTEGER_LENGTH_2;
- }
- return VARIABLE_LENGTH_INTEGER_LENGTH_1;
-}
-
-bool QuicDataWriter::WriteStringPieceVarInt62(
- const absl::string_view& string_piece) {
- if (!WriteVarInt62(string_piece.size())) {
- return false;
- }
- if (!string_piece.empty()) {
- if (!WriteBytes(string_piece.data(), string_piece.size())) {
- return false;
- }
- }
- return true;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_data_writer.h b/chromium/net/third_party/quiche/src/quic/core/quic_data_writer.h
deleted file mode 100644
index 2a23ce26eff..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_data_writer.h
+++ /dev/null
@@ -1,100 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_DATA_WRITER_H_
-#define QUICHE_QUIC_CORE_QUIC_DATA_WRITER_H_
-
-#include <cstddef>
-#include <cstdint>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_export.h"
-#include "common/quiche_data_writer.h"
-#include "common/quiche_endian.h"
-
-namespace quic {
-
-class QuicRandom;
-
-// Maximum value that can be properly encoded using VarInt62 coding.
-const uint64_t kVarInt62MaxValue = UINT64_C(0x3fffffffffffffff);
-
-// VarInt62 encoding masks
-// If a uint64_t anded with a mask is not 0 then the value is encoded
-// using that length (or is too big, in the case of kVarInt62ErrorMask).
-// Values must be checked in order (error, 8-, 4-, and then 2- bytes)
-// and if none are non-0, the value is encoded in 1 byte.
-const uint64_t kVarInt62ErrorMask = UINT64_C(0xc000000000000000);
-const uint64_t kVarInt62Mask8Bytes = UINT64_C(0x3fffffffc0000000);
-const uint64_t kVarInt62Mask4Bytes = UINT64_C(0x000000003fffc000);
-const uint64_t kVarInt62Mask2Bytes = UINT64_C(0x0000000000003fc0);
-
-// This class provides facilities for packing QUIC data.
-//
-// The QuicDataWriter supports appending primitive values (int, string, etc)
-// to a frame instance. The internal memory buffer is exposed as the "data"
-// of the QuicDataWriter.
-class QUIC_EXPORT_PRIVATE QuicDataWriter : public quiche::QuicheDataWriter {
- public:
- // Creates a QuicDataWriter where |buffer| is not owned
- // using NETWORK_BYTE_ORDER endianness.
- QuicDataWriter(size_t size, char* buffer);
- // Creates a QuicDataWriter where |buffer| is not owned
- // using the specified endianness.
- QuicDataWriter(size_t size, char* buffer, quiche::Endianness endianness);
- QuicDataWriter(const QuicDataWriter&) = delete;
- QuicDataWriter& operator=(const QuicDataWriter&) = delete;
-
- ~QuicDataWriter();
-
- // Methods for adding to the payload. These values are appended to the end
- // of the QuicDataWriter payload.
-
- // Write an unsigned-integer value per the IETF QUIC/Variable Length
- // Integer encoding rules (see draft-ietf-quic-transport-08.txt).
- // IETF Variable Length Integers have 62 significant bits, so the
- // value to write must be in the range of 0...(2^62)-1. Returns
- // false if the value is out of range or if there is no room in the
- // buffer.
- bool WriteVarInt62(uint64_t value);
-
- // Same as WriteVarInt62(uint64_t), but forces an encoding size to write to.
- // This is not as optimized as WriteVarInt62(uint64_t).
- // Returns false if the value does not fit in the specified write_length or if
- // there is no room in the buffer.
- bool WriteVarInt62(uint64_t value,
- QuicVariableLengthIntegerLength write_length);
-
- // Writes a string piece as a consecutive length/content pair. The
- // length is VarInt62 encoded.
- bool WriteStringPieceVarInt62(const absl::string_view& string_piece);
-
- // Utility function to return the number of bytes needed to encode
- // the given value using IETF VarInt62 encoding. Returns the number
- // of bytes required to encode the given integer or 0 if the value
- // is too large to encode.
- static QuicVariableLengthIntegerLength GetVarInt62Len(uint64_t value);
-
- // Write unsigned floating point corresponding to the value. Large values are
- // clamped to the maximum representable (kUFloat16MaxValue). Values that can
- // not be represented directly are rounded down.
- bool WriteUFloat16(uint64_t value);
- // Write connection ID to the payload.
- bool WriteConnectionId(QuicConnectionId connection_id);
-
- // Write 8-bit length followed by connection ID to the payload.
- bool WriteLengthPrefixedConnectionId(QuicConnectionId connection_id);
-
- // Write |length| random bytes generated by |random|.
- bool WriteRandomBytes(QuicRandom* random, size_t length);
-
- // Write |length| random bytes generated by |random|. This MUST NOT be used
- // for any application that requires cryptographically-secure randomness.
- bool WriteInsecureRandomBytes(QuicRandom* random, size_t length);
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_QUIC_DATA_WRITER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_data_writer_test.cc b/chromium/net/third_party/quiche/src/quic/core/quic_data_writer_test.cc
deleted file mode 100644
index cbe0351fbfc..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_data_writer_test.cc
+++ /dev/null
@@ -1,1281 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_data_writer.h"
-
-#include <cstdint>
-#include <cstring>
-
-#include "absl/base/macros.h"
-#include "absl/strings/str_cat.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_connection_id.h"
-#include "quic/core/quic_data_reader.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_expect_bug.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/quic_test_utils.h"
-#include "common/quiche_endian.h"
-#include "common/test_tools/quiche_test_utils.h"
-
-namespace quic {
-namespace test {
-namespace {
-
-char* AsChars(unsigned char* data) {
- return reinterpret_cast<char*>(data);
-}
-
-struct TestParams {
- explicit TestParams(quiche::Endianness endianness) : endianness(endianness) {}
-
- quiche::Endianness endianness;
-};
-
-// Used by ::testing::PrintToStringParamName().
-std::string PrintToString(const TestParams& p) {
- return absl::StrCat(
- (p.endianness == quiche::NETWORK_BYTE_ORDER ? "Network" : "Host"),
- "ByteOrder");
-}
-
-std::vector<TestParams> GetTestParams() {
- std::vector<TestParams> params;
- for (quiche::Endianness endianness :
- {quiche::NETWORK_BYTE_ORDER, quiche::HOST_BYTE_ORDER}) {
- params.push_back(TestParams(endianness));
- }
- return params;
-}
-
-class QuicDataWriterTest : public QuicTestWithParam<TestParams> {};
-
-INSTANTIATE_TEST_SUITE_P(QuicDataWriterTests,
- QuicDataWriterTest,
- ::testing::ValuesIn(GetTestParams()),
- ::testing::PrintToStringParamName());
-
-TEST_P(QuicDataWriterTest, SanityCheckUFloat16Consts) {
- // Check the arithmetic on the constants - otherwise the values below make
- // no sense.
- EXPECT_EQ(30, kUFloat16MaxExponent);
- EXPECT_EQ(11, kUFloat16MantissaBits);
- EXPECT_EQ(12, kUFloat16MantissaEffectiveBits);
- EXPECT_EQ(UINT64_C(0x3FFC0000000), kUFloat16MaxValue);
-}
-
-TEST_P(QuicDataWriterTest, WriteUFloat16) {
- struct TestCase {
- uint64_t decoded;
- uint16_t encoded;
- };
- TestCase test_cases[] = {
- // Small numbers represent themselves.
- {0, 0},
- {1, 1},
- {2, 2},
- {3, 3},
- {4, 4},
- {5, 5},
- {6, 6},
- {7, 7},
- {15, 15},
- {31, 31},
- {42, 42},
- {123, 123},
- {1234, 1234},
- // Check transition through 2^11.
- {2046, 2046},
- {2047, 2047},
- {2048, 2048},
- {2049, 2049},
- // Running out of mantissa at 2^12.
- {4094, 4094},
- {4095, 4095},
- {4096, 4096},
- {4097, 4096},
- {4098, 4097},
- {4099, 4097},
- {4100, 4098},
- {4101, 4098},
- // Check transition through 2^13.
- {8190, 6143},
- {8191, 6143},
- {8192, 6144},
- {8193, 6144},
- {8194, 6144},
- {8195, 6144},
- {8196, 6145},
- {8197, 6145},
- // Half-way through the exponents.
- {0x7FF8000, 0x87FF},
- {0x7FFFFFF, 0x87FF},
- {0x8000000, 0x8800},
- {0xFFF0000, 0x8FFF},
- {0xFFFFFFF, 0x8FFF},
- {0x10000000, 0x9000},
- // Transition into the largest exponent.
- {0x1FFFFFFFFFE, 0xF7FF},
- {0x1FFFFFFFFFF, 0xF7FF},
- {0x20000000000, 0xF800},
- {0x20000000001, 0xF800},
- {0x2003FFFFFFE, 0xF800},
- {0x2003FFFFFFF, 0xF800},
- {0x20040000000, 0xF801},
- {0x20040000001, 0xF801},
- // Transition into the max value and clamping.
- {0x3FF80000000, 0xFFFE},
- {0x3FFBFFFFFFF, 0xFFFE},
- {0x3FFC0000000, 0xFFFF},
- {0x3FFC0000001, 0xFFFF},
- {0x3FFFFFFFFFF, 0xFFFF},
- {0x40000000000, 0xFFFF},
- {0xFFFFFFFFFFFFFFFF, 0xFFFF},
- };
- int num_test_cases = sizeof(test_cases) / sizeof(test_cases[0]);
-
- for (int i = 0; i < num_test_cases; ++i) {
- char buffer[2];
- QuicDataWriter writer(2, buffer, GetParam().endianness);
- EXPECT_TRUE(writer.WriteUFloat16(test_cases[i].decoded));
- uint16_t result = *reinterpret_cast<uint16_t*>(writer.data());
- if (GetParam().endianness == quiche::NETWORK_BYTE_ORDER) {
- result = quiche::QuicheEndian::HostToNet16(result);
- }
- EXPECT_EQ(test_cases[i].encoded, result);
- }
-}
-
-TEST_P(QuicDataWriterTest, ReadUFloat16) {
- struct TestCase {
- uint64_t decoded;
- uint16_t encoded;
- };
- TestCase test_cases[] = {
- // There are fewer decoding test cases because encoding truncates, and
- // decoding returns the smallest expansion.
- // Small numbers represent themselves.
- {0, 0},
- {1, 1},
- {2, 2},
- {3, 3},
- {4, 4},
- {5, 5},
- {6, 6},
- {7, 7},
- {15, 15},
- {31, 31},
- {42, 42},
- {123, 123},
- {1234, 1234},
- // Check transition through 2^11.
- {2046, 2046},
- {2047, 2047},
- {2048, 2048},
- {2049, 2049},
- // Running out of mantissa at 2^12.
- {4094, 4094},
- {4095, 4095},
- {4096, 4096},
- {4098, 4097},
- {4100, 4098},
- // Check transition through 2^13.
- {8190, 6143},
- {8192, 6144},
- {8196, 6145},
- // Half-way through the exponents.
- {0x7FF8000, 0x87FF},
- {0x8000000, 0x8800},
- {0xFFF0000, 0x8FFF},
- {0x10000000, 0x9000},
- // Transition into the largest exponent.
- {0x1FFE0000000, 0xF7FF},
- {0x20000000000, 0xF800},
- {0x20040000000, 0xF801},
- // Transition into the max value.
- {0x3FF80000000, 0xFFFE},
- {0x3FFC0000000, 0xFFFF},
- };
- int num_test_cases = sizeof(test_cases) / sizeof(test_cases[0]);
-
- for (int i = 0; i < num_test_cases; ++i) {
- uint16_t encoded_ufloat = test_cases[i].encoded;
- if (GetParam().endianness == quiche::NETWORK_BYTE_ORDER) {
- encoded_ufloat = quiche::QuicheEndian::HostToNet16(encoded_ufloat);
- }
- QuicDataReader reader(reinterpret_cast<char*>(&encoded_ufloat), 2,
- GetParam().endianness);
- uint64_t value;
- EXPECT_TRUE(reader.ReadUFloat16(&value));
- EXPECT_EQ(test_cases[i].decoded, value);
- }
-}
-
-TEST_P(QuicDataWriterTest, RoundTripUFloat16) {
- // Just test all 16-bit encoded values. 0 and max already tested above.
- uint64_t previous_value = 0;
- for (uint16_t i = 1; i < 0xFFFF; ++i) {
- // Read the two bytes.
- uint16_t read_number = i;
- if (GetParam().endianness == quiche::NETWORK_BYTE_ORDER) {
- read_number = quiche::QuicheEndian::HostToNet16(read_number);
- }
- QuicDataReader reader(reinterpret_cast<char*>(&read_number), 2,
- GetParam().endianness);
- uint64_t value;
- // All values must be decodable.
- EXPECT_TRUE(reader.ReadUFloat16(&value));
- // Check that small numbers represent themselves
- if (i < 4097) {
- EXPECT_EQ(i, value);
- }
- // Check there's monotonic growth.
- EXPECT_LT(previous_value, value);
- // Check that precision is within 0.5% away from the denormals.
- if (i > 2000) {
- EXPECT_GT(previous_value * 1005, value * 1000);
- }
- // Check we're always within the promised range.
- EXPECT_LT(value, UINT64_C(0x3FFC0000000));
- previous_value = value;
- char buffer[6];
- QuicDataWriter writer(6, buffer, GetParam().endianness);
- EXPECT_TRUE(writer.WriteUFloat16(value - 1));
- EXPECT_TRUE(writer.WriteUFloat16(value));
- EXPECT_TRUE(writer.WriteUFloat16(value + 1));
- // Check minimal decoding (previous decoding has previous encoding).
- uint16_t encoded1 = *reinterpret_cast<uint16_t*>(writer.data());
- uint16_t encoded2 = *reinterpret_cast<uint16_t*>(writer.data() + 2);
- uint16_t encoded3 = *reinterpret_cast<uint16_t*>(writer.data() + 4);
- if (GetParam().endianness == quiche::NETWORK_BYTE_ORDER) {
- encoded1 = quiche::QuicheEndian::NetToHost16(encoded1);
- encoded2 = quiche::QuicheEndian::NetToHost16(encoded2);
- encoded3 = quiche::QuicheEndian::NetToHost16(encoded3);
- }
- EXPECT_EQ(i - 1, encoded1);
- // Check roundtrip.
- EXPECT_EQ(i, encoded2);
- // Check next decoding.
- EXPECT_EQ(i < 4096 ? i + 1 : i, encoded3);
- }
-}
-
-TEST_P(QuicDataWriterTest, WriteConnectionId) {
- QuicConnectionId connection_id =
- TestConnectionId(UINT64_C(0x0011223344556677));
- char big_endian[] = {
- 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
- };
- EXPECT_EQ(connection_id.length(), ABSL_ARRAYSIZE(big_endian));
- ASSERT_LE(connection_id.length(), 255);
- char buffer[255];
- QuicDataWriter writer(connection_id.length(), buffer, GetParam().endianness);
- EXPECT_TRUE(writer.WriteConnectionId(connection_id));
- quiche::test::CompareCharArraysWithHexError(
- "connection_id", buffer, connection_id.length(), big_endian,
- connection_id.length());
-
- QuicConnectionId read_connection_id;
- QuicDataReader reader(buffer, connection_id.length(), GetParam().endianness);
- EXPECT_TRUE(
- reader.ReadConnectionId(&read_connection_id, ABSL_ARRAYSIZE(big_endian)));
- EXPECT_EQ(connection_id, read_connection_id);
-}
-
-TEST_P(QuicDataWriterTest, LengthPrefixedConnectionId) {
- QuicConnectionId connection_id =
- TestConnectionId(UINT64_C(0x0011223344556677));
- char length_prefixed_connection_id[] = {
- 0x08, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
- };
- EXPECT_EQ(ABSL_ARRAYSIZE(length_prefixed_connection_id),
- kConnectionIdLengthSize + connection_id.length());
- char buffer[kConnectionIdLengthSize + 255] = {};
- QuicDataWriter writer(ABSL_ARRAYSIZE(buffer), buffer);
- EXPECT_TRUE(writer.WriteLengthPrefixedConnectionId(connection_id));
- quiche::test::CompareCharArraysWithHexError(
- "WriteLengthPrefixedConnectionId", buffer, writer.length(),
- length_prefixed_connection_id,
- ABSL_ARRAYSIZE(length_prefixed_connection_id));
-
- // Verify that writing length then connection ID produces the same output.
- memset(buffer, 0, ABSL_ARRAYSIZE(buffer));
- QuicDataWriter writer2(ABSL_ARRAYSIZE(buffer), buffer);
- EXPECT_TRUE(writer2.WriteUInt8(connection_id.length()));
- EXPECT_TRUE(writer2.WriteConnectionId(connection_id));
- quiche::test::CompareCharArraysWithHexError(
- "Write length then ConnectionId", buffer, writer2.length(),
- length_prefixed_connection_id,
- ABSL_ARRAYSIZE(length_prefixed_connection_id));
-
- QuicConnectionId read_connection_id;
- QuicDataReader reader(buffer, ABSL_ARRAYSIZE(buffer));
- EXPECT_TRUE(reader.ReadLengthPrefixedConnectionId(&read_connection_id));
- EXPECT_EQ(connection_id, read_connection_id);
-
- // Verify that reading length then connection ID produces the same output.
- uint8_t read_connection_id_length2 = 33;
- QuicConnectionId read_connection_id2;
- QuicDataReader reader2(buffer, ABSL_ARRAYSIZE(buffer));
- ASSERT_TRUE(reader2.ReadUInt8(&read_connection_id_length2));
- EXPECT_EQ(connection_id.length(), read_connection_id_length2);
- EXPECT_TRUE(reader2.ReadConnectionId(&read_connection_id2,
- read_connection_id_length2));
- EXPECT_EQ(connection_id, read_connection_id2);
-}
-
-TEST_P(QuicDataWriterTest, EmptyConnectionIds) {
- QuicConnectionId empty_connection_id = EmptyQuicConnectionId();
- char buffer[2];
- QuicDataWriter writer(ABSL_ARRAYSIZE(buffer), buffer, GetParam().endianness);
- EXPECT_TRUE(writer.WriteConnectionId(empty_connection_id));
- EXPECT_TRUE(writer.WriteUInt8(1));
- EXPECT_TRUE(writer.WriteConnectionId(empty_connection_id));
- EXPECT_TRUE(writer.WriteUInt8(2));
- EXPECT_TRUE(writer.WriteConnectionId(empty_connection_id));
- EXPECT_FALSE(writer.WriteUInt8(3));
-
- EXPECT_EQ(buffer[0], 1);
- EXPECT_EQ(buffer[1], 2);
-
- QuicConnectionId read_connection_id = TestConnectionId();
- uint8_t read_byte;
- QuicDataReader reader(buffer, ABSL_ARRAYSIZE(buffer), GetParam().endianness);
- EXPECT_TRUE(reader.ReadConnectionId(&read_connection_id, 0));
- EXPECT_EQ(read_connection_id, empty_connection_id);
- EXPECT_TRUE(reader.ReadUInt8(&read_byte));
- EXPECT_EQ(read_byte, 1);
- // Reset read_connection_id to something else to verify that
- // ReadConnectionId properly sets it back to empty.
- read_connection_id = TestConnectionId();
- EXPECT_TRUE(reader.ReadConnectionId(&read_connection_id, 0));
- EXPECT_EQ(read_connection_id, empty_connection_id);
- EXPECT_TRUE(reader.ReadUInt8(&read_byte));
- EXPECT_EQ(read_byte, 2);
- read_connection_id = TestConnectionId();
- EXPECT_TRUE(reader.ReadConnectionId(&read_connection_id, 0));
- EXPECT_EQ(read_connection_id, empty_connection_id);
- EXPECT_FALSE(reader.ReadUInt8(&read_byte));
-}
-
-TEST_P(QuicDataWriterTest, WriteTag) {
- char CHLO[] = {
- 'C',
- 'H',
- 'L',
- 'O',
- };
- const int kBufferLength = sizeof(QuicTag);
- char buffer[kBufferLength];
- QuicDataWriter writer(kBufferLength, buffer, GetParam().endianness);
- writer.WriteTag(kCHLO);
- quiche::test::CompareCharArraysWithHexError("CHLO", buffer, kBufferLength,
- CHLO, kBufferLength);
-
- QuicTag read_chlo;
- QuicDataReader reader(buffer, kBufferLength, GetParam().endianness);
- reader.ReadTag(&read_chlo);
- EXPECT_EQ(kCHLO, read_chlo);
-}
-
-TEST_P(QuicDataWriterTest, Write16BitUnsignedIntegers) {
- char little_endian16[] = {0x22, 0x11};
- char big_endian16[] = {0x11, 0x22};
- char buffer16[2];
- {
- uint16_t in_memory16 = 0x1122;
- QuicDataWriter writer(2, buffer16, GetParam().endianness);
- writer.WriteUInt16(in_memory16);
- quiche::test::CompareCharArraysWithHexError(
- "uint16_t", buffer16, 2,
- GetParam().endianness == quiche::NETWORK_BYTE_ORDER ? big_endian16
- : little_endian16,
- 2);
-
- uint16_t read_number16;
- QuicDataReader reader(buffer16, 2, GetParam().endianness);
- reader.ReadUInt16(&read_number16);
- EXPECT_EQ(in_memory16, read_number16);
- }
-
- {
- uint64_t in_memory16 = 0x0000000000001122;
- QuicDataWriter writer(2, buffer16, GetParam().endianness);
- writer.WriteBytesToUInt64(2, in_memory16);
- quiche::test::CompareCharArraysWithHexError(
- "uint16_t", buffer16, 2,
- GetParam().endianness == quiche::NETWORK_BYTE_ORDER ? big_endian16
- : little_endian16,
- 2);
-
- uint64_t read_number16;
- QuicDataReader reader(buffer16, 2, GetParam().endianness);
- reader.ReadBytesToUInt64(2, &read_number16);
- EXPECT_EQ(in_memory16, read_number16);
- }
-}
-
-TEST_P(QuicDataWriterTest, Write24BitUnsignedIntegers) {
- char little_endian24[] = {0x33, 0x22, 0x11};
- char big_endian24[] = {0x11, 0x22, 0x33};
- char buffer24[3];
- uint64_t in_memory24 = 0x0000000000112233;
- QuicDataWriter writer(3, buffer24, GetParam().endianness);
- writer.WriteBytesToUInt64(3, in_memory24);
- quiche::test::CompareCharArraysWithHexError(
- "uint24", buffer24, 3,
- GetParam().endianness == quiche::NETWORK_BYTE_ORDER ? big_endian24
- : little_endian24,
- 3);
-
- uint64_t read_number24;
- QuicDataReader reader(buffer24, 3, GetParam().endianness);
- reader.ReadBytesToUInt64(3, &read_number24);
- EXPECT_EQ(in_memory24, read_number24);
-}
-
-TEST_P(QuicDataWriterTest, Write32BitUnsignedIntegers) {
- char little_endian32[] = {0x44, 0x33, 0x22, 0x11};
- char big_endian32[] = {0x11, 0x22, 0x33, 0x44};
- char buffer32[4];
- {
- uint32_t in_memory32 = 0x11223344;
- QuicDataWriter writer(4, buffer32, GetParam().endianness);
- writer.WriteUInt32(in_memory32);
- quiche::test::CompareCharArraysWithHexError(
- "uint32_t", buffer32, 4,
- GetParam().endianness == quiche::NETWORK_BYTE_ORDER ? big_endian32
- : little_endian32,
- 4);
-
- uint32_t read_number32;
- QuicDataReader reader(buffer32, 4, GetParam().endianness);
- reader.ReadUInt32(&read_number32);
- EXPECT_EQ(in_memory32, read_number32);
- }
-
- {
- uint64_t in_memory32 = 0x11223344;
- QuicDataWriter writer(4, buffer32, GetParam().endianness);
- writer.WriteBytesToUInt64(4, in_memory32);
- quiche::test::CompareCharArraysWithHexError(
- "uint32_t", buffer32, 4,
- GetParam().endianness == quiche::NETWORK_BYTE_ORDER ? big_endian32
- : little_endian32,
- 4);
-
- uint64_t read_number32;
- QuicDataReader reader(buffer32, 4, GetParam().endianness);
- reader.ReadBytesToUInt64(4, &read_number32);
- EXPECT_EQ(in_memory32, read_number32);
- }
-}
-
-TEST_P(QuicDataWriterTest, Write40BitUnsignedIntegers) {
- uint64_t in_memory40 = 0x0000001122334455;
- char little_endian40[] = {0x55, 0x44, 0x33, 0x22, 0x11};
- char big_endian40[] = {0x11, 0x22, 0x33, 0x44, 0x55};
- char buffer40[5];
- QuicDataWriter writer(5, buffer40, GetParam().endianness);
- writer.WriteBytesToUInt64(5, in_memory40);
- quiche::test::CompareCharArraysWithHexError(
- "uint40", buffer40, 5,
- GetParam().endianness == quiche::NETWORK_BYTE_ORDER ? big_endian40
- : little_endian40,
- 5);
-
- uint64_t read_number40;
- QuicDataReader reader(buffer40, 5, GetParam().endianness);
- reader.ReadBytesToUInt64(5, &read_number40);
- EXPECT_EQ(in_memory40, read_number40);
-}
-
-TEST_P(QuicDataWriterTest, Write48BitUnsignedIntegers) {
- uint64_t in_memory48 = 0x0000112233445566;
- char little_endian48[] = {0x66, 0x55, 0x44, 0x33, 0x22, 0x11};
- char big_endian48[] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66};
- char buffer48[6];
- QuicDataWriter writer(6, buffer48, GetParam().endianness);
- writer.WriteBytesToUInt64(6, in_memory48);
- quiche::test::CompareCharArraysWithHexError(
- "uint48", buffer48, 6,
- GetParam().endianness == quiche::NETWORK_BYTE_ORDER ? big_endian48
- : little_endian48,
- 6);
-
- uint64_t read_number48;
- QuicDataReader reader(buffer48, 6, GetParam().endianness);
- reader.ReadBytesToUInt64(6., &read_number48);
- EXPECT_EQ(in_memory48, read_number48);
-}
-
-TEST_P(QuicDataWriterTest, Write56BitUnsignedIntegers) {
- uint64_t in_memory56 = 0x0011223344556677;
- char little_endian56[] = {0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11};
- char big_endian56[] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
- char buffer56[7];
- QuicDataWriter writer(7, buffer56, GetParam().endianness);
- writer.WriteBytesToUInt64(7, in_memory56);
- quiche::test::CompareCharArraysWithHexError(
- "uint56", buffer56, 7,
- GetParam().endianness == quiche::NETWORK_BYTE_ORDER ? big_endian56
- : little_endian56,
- 7);
-
- uint64_t read_number56;
- QuicDataReader reader(buffer56, 7, GetParam().endianness);
- reader.ReadBytesToUInt64(7, &read_number56);
- EXPECT_EQ(in_memory56, read_number56);
-}
-
-TEST_P(QuicDataWriterTest, Write64BitUnsignedIntegers) {
- uint64_t in_memory64 = 0x1122334455667788;
- unsigned char little_endian64[] = {0x88, 0x77, 0x66, 0x55,
- 0x44, 0x33, 0x22, 0x11};
- unsigned char big_endian64[] = {0x11, 0x22, 0x33, 0x44,
- 0x55, 0x66, 0x77, 0x88};
- char buffer64[8];
- QuicDataWriter writer(8, buffer64, GetParam().endianness);
- writer.WriteBytesToUInt64(8, in_memory64);
- quiche::test::CompareCharArraysWithHexError(
- "uint64_t", buffer64, 8,
- GetParam().endianness == quiche::NETWORK_BYTE_ORDER
- ? AsChars(big_endian64)
- : AsChars(little_endian64),
- 8);
-
- uint64_t read_number64;
- QuicDataReader reader(buffer64, 8, GetParam().endianness);
- reader.ReadBytesToUInt64(8, &read_number64);
- EXPECT_EQ(in_memory64, read_number64);
-
- QuicDataWriter writer2(8, buffer64, GetParam().endianness);
- writer2.WriteUInt64(in_memory64);
- quiche::test::CompareCharArraysWithHexError(
- "uint64_t", buffer64, 8,
- GetParam().endianness == quiche::NETWORK_BYTE_ORDER
- ? AsChars(big_endian64)
- : AsChars(little_endian64),
- 8);
- read_number64 = 0u;
- QuicDataReader reader2(buffer64, 8, GetParam().endianness);
- reader2.ReadUInt64(&read_number64);
- EXPECT_EQ(in_memory64, read_number64);
-}
-
-TEST_P(QuicDataWriterTest, WriteIntegers) {
- char buf[43];
- uint8_t i8 = 0x01;
- uint16_t i16 = 0x0123;
- uint32_t i32 = 0x01234567;
- uint64_t i64 = 0x0123456789ABCDEF;
- QuicDataWriter writer(46, buf, GetParam().endianness);
- for (size_t i = 0; i < 10; ++i) {
- switch (i) {
- case 0u:
- EXPECT_TRUE(writer.WriteBytesToUInt64(i, i64));
- break;
- case 1u:
- EXPECT_TRUE(writer.WriteUInt8(i8));
- EXPECT_TRUE(writer.WriteBytesToUInt64(i, i64));
- break;
- case 2u:
- EXPECT_TRUE(writer.WriteUInt16(i16));
- EXPECT_TRUE(writer.WriteBytesToUInt64(i, i64));
- break;
- case 3u:
- EXPECT_TRUE(writer.WriteBytesToUInt64(i, i64));
- break;
- case 4u:
- EXPECT_TRUE(writer.WriteUInt32(i32));
- EXPECT_TRUE(writer.WriteBytesToUInt64(i, i64));
- break;
- case 5u:
- case 6u:
- case 7u:
- case 8u:
- EXPECT_TRUE(writer.WriteBytesToUInt64(i, i64));
- break;
- default:
- EXPECT_FALSE(writer.WriteBytesToUInt64(i, i64));
- }
- }
-
- QuicDataReader reader(buf, 46, GetParam().endianness);
- for (size_t i = 0; i < 10; ++i) {
- uint8_t read8;
- uint16_t read16;
- uint32_t read32;
- uint64_t read64;
- switch (i) {
- case 0u:
- EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64));
- EXPECT_EQ(0u, read64);
- break;
- case 1u:
- EXPECT_TRUE(reader.ReadUInt8(&read8));
- EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64));
- EXPECT_EQ(i8, read8);
- EXPECT_EQ(0xEFu, read64);
- break;
- case 2u:
- EXPECT_TRUE(reader.ReadUInt16(&read16));
- EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64));
- EXPECT_EQ(i16, read16);
- EXPECT_EQ(0xCDEFu, read64);
- break;
- case 3u:
- EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64));
- EXPECT_EQ(0xABCDEFu, read64);
- break;
- case 4u:
- EXPECT_TRUE(reader.ReadUInt32(&read32));
- EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64));
- EXPECT_EQ(i32, read32);
- EXPECT_EQ(0x89ABCDEFu, read64);
- break;
- case 5u:
- EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64));
- EXPECT_EQ(0x6789ABCDEFu, read64);
- break;
- case 6u:
- EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64));
- EXPECT_EQ(0x456789ABCDEFu, read64);
- break;
- case 7u:
- EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64));
- EXPECT_EQ(0x23456789ABCDEFu, read64);
- break;
- case 8u:
- EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64));
- EXPECT_EQ(0x0123456789ABCDEFu, read64);
- break;
- default:
- EXPECT_FALSE(reader.ReadBytesToUInt64(i, &read64));
- }
- }
-}
-
-TEST_P(QuicDataWriterTest, WriteBytes) {
- char bytes[] = {0, 1, 2, 3, 4, 5, 6, 7, 8};
- char buf[ABSL_ARRAYSIZE(bytes)];
- QuicDataWriter writer(ABSL_ARRAYSIZE(buf), buf, GetParam().endianness);
- EXPECT_TRUE(writer.WriteBytes(bytes, ABSL_ARRAYSIZE(bytes)));
- for (unsigned int i = 0; i < ABSL_ARRAYSIZE(bytes); ++i) {
- EXPECT_EQ(bytes[i], buf[i]);
- }
-}
-
-const int kVarIntBufferLength = 1024;
-
-// Encodes and then decodes a specified value, checks that the
-// value that was encoded is the same as the decoded value, the length
-// is correct, and that after decoding, all data in the buffer has
-// been consumed..
-// Returns true if everything works, false if not.
-bool EncodeDecodeValue(uint64_t value_in, char* buffer, size_t size_of_buffer) {
- // Init the buffer to all 0, just for cleanliness. Makes for better
- // output if, in debugging, we need to dump out the buffer.
- memset(buffer, 0, size_of_buffer);
- // make a writer. Note that for IETF encoding
- // we do not care about endianness... It's always big-endian,
- // but the c'tor expects to be told what endianness is in force...
- QuicDataWriter writer(size_of_buffer, buffer,
- quiche::Endianness::NETWORK_BYTE_ORDER);
-
- // Try to write the value.
- if (writer.WriteVarInt62(value_in) != true) {
- return false;
- }
- // Look at the value we encoded. Determine how much should have been
- // used based on the value, and then check the state of the writer
- // to see that it matches.
- size_t expected_length = 0;
- if (value_in <= 0x3f) {
- expected_length = 1;
- } else if (value_in <= 0x3fff) {
- expected_length = 2;
- } else if (value_in <= 0x3fffffff) {
- expected_length = 4;
- } else {
- expected_length = 8;
- }
- if (writer.length() != expected_length) {
- return false;
- }
-
- // set up a reader, just the length we've used, no more, no less.
- QuicDataReader reader(buffer, expected_length,
- quiche::Endianness::NETWORK_BYTE_ORDER);
- uint64_t value_out;
-
- if (reader.ReadVarInt62(&value_out) == false) {
- return false;
- }
- if (value_in != value_out) {
- return false;
- }
- // We only write one value so there had better be nothing left to read
- return reader.IsDoneReading();
-}
-
-// Test that 8-byte-encoded Variable Length Integers are properly laid
-// out in the buffer.
-TEST_P(QuicDataWriterTest, VarInt8Layout) {
- char buffer[1024];
-
- // Check that the layout of bytes in the buffer is correct. Bytes
- // are always encoded big endian...
- memset(buffer, 0, sizeof(buffer));
- QuicDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
- quiche::Endianness::NETWORK_BYTE_ORDER);
- EXPECT_TRUE(writer.WriteVarInt62(UINT64_C(0x3142f3e4d5c6b7a8)));
- EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 0)),
- (0x31 + 0xc0)); // 0xc0 for encoding
- EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 1)), 0x42);
- EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 2)), 0xf3);
- EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 3)), 0xe4);
- EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 4)), 0xd5);
- EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 5)), 0xc6);
- EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 6)), 0xb7);
- EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 7)), 0xa8);
-}
-
-// Test that 4-byte-encoded Variable Length Integers are properly laid
-// out in the buffer.
-TEST_P(QuicDataWriterTest, VarInt4Layout) {
- char buffer[1024];
-
- // Check that the layout of bytes in the buffer is correct. Bytes
- // are always encoded big endian...
- memset(buffer, 0, sizeof(buffer));
- QuicDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
- quiche::Endianness::NETWORK_BYTE_ORDER);
- EXPECT_TRUE(writer.WriteVarInt62(0x3243f4e5));
- EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 0)),
- (0x32 + 0x80)); // 0x80 for encoding
- EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 1)), 0x43);
- EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 2)), 0xf4);
- EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 3)), 0xe5);
-}
-
-// Test that 2-byte-encoded Variable Length Integers are properly laid
-// out in the buffer.
-TEST_P(QuicDataWriterTest, VarInt2Layout) {
- char buffer[1024];
-
- // Check that the layout of bytes in the buffer is correct. Bytes
- // are always encoded big endian...
- memset(buffer, 0, sizeof(buffer));
- QuicDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
- quiche::Endianness::NETWORK_BYTE_ORDER);
- EXPECT_TRUE(writer.WriteVarInt62(0x3647));
- EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 0)),
- (0x36 + 0x40)); // 0x40 for encoding
- EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 1)), 0x47);
-}
-
-// Test that 1-byte-encoded Variable Length Integers are properly laid
-// out in the buffer.
-TEST_P(QuicDataWriterTest, VarInt1Layout) {
- char buffer[1024];
-
- // Check that the layout of bytes in the buffer
- // is correct. Bytes are always encoded big endian...
- memset(buffer, 0, sizeof(buffer));
- QuicDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
- quiche::Endianness::NETWORK_BYTE_ORDER);
- EXPECT_TRUE(writer.WriteVarInt62(0x3f));
- EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 0)), 0x3f);
-}
-
-// Test certain, targeted, values that are expected to succeed:
-// 0, 1,
-// 0x3e, 0x3f, 0x40, 0x41 (around the 1-2 byte transitions)
-// 0x3ffe, 0x3fff, 0x4000, 0x4001 (the 2-4 byte transition)
-// 0x3ffffffe, 0x3fffffff, 0x40000000, 0x40000001 (the 4-8 byte
-// transition)
-// 0x3ffffffffffffffe, 0x3fffffffffffffff, (the highest valid values)
-// 0xfe, 0xff, 0x100, 0x101,
-// 0xfffe, 0xffff, 0x10000, 0x10001,
-// 0xfffffe, 0xffffff, 0x1000000, 0x1000001,
-// 0xfffffffe, 0xffffffff, 0x100000000, 0x100000001,
-// 0xfffffffffe, 0xffffffffff, 0x10000000000, 0x10000000001,
-// 0xfffffffffffe, 0xffffffffffff, 0x1000000000000, 0x1000000000001,
-// 0xfffffffffffffe, 0xffffffffffffff, 0x100000000000000, 0x100000000000001,
-TEST_P(QuicDataWriterTest, VarIntGoodTargetedValues) {
- char buffer[kVarIntBufferLength];
- uint64_t passing_values[] = {
- 0,
- 1,
- 0x3e,
- 0x3f,
- 0x40,
- 0x41,
- 0x3ffe,
- 0x3fff,
- 0x4000,
- 0x4001,
- 0x3ffffffe,
- 0x3fffffff,
- 0x40000000,
- 0x40000001,
- 0x3ffffffffffffffe,
- 0x3fffffffffffffff,
- 0xfe,
- 0xff,
- 0x100,
- 0x101,
- 0xfffe,
- 0xffff,
- 0x10000,
- 0x10001,
- 0xfffffe,
- 0xffffff,
- 0x1000000,
- 0x1000001,
- 0xfffffffe,
- 0xffffffff,
- 0x100000000,
- 0x100000001,
- 0xfffffffffe,
- 0xffffffffff,
- 0x10000000000,
- 0x10000000001,
- 0xfffffffffffe,
- 0xffffffffffff,
- 0x1000000000000,
- 0x1000000000001,
- 0xfffffffffffffe,
- 0xffffffffffffff,
- 0x100000000000000,
- 0x100000000000001,
- };
- for (uint64_t test_val : passing_values) {
- EXPECT_TRUE(
- EncodeDecodeValue(test_val, static_cast<char*>(buffer), sizeof(buffer)))
- << " encode/decode of " << test_val << " failed";
- }
-}
-//
-// Test certain, targeted, values where failure is expected (the
-// values are invalid w.r.t. IETF VarInt encoding):
-// 0x4000000000000000, 0x4000000000000001, ( Just above max allowed value)
-// 0xfffffffffffffffe, 0xffffffffffffffff, (should fail)
-TEST_P(QuicDataWriterTest, VarIntBadTargetedValues) {
- char buffer[kVarIntBufferLength];
- uint64_t failing_values[] = {
- 0x4000000000000000,
- 0x4000000000000001,
- 0xfffffffffffffffe,
- 0xffffffffffffffff,
- };
- for (uint64_t test_val : failing_values) {
- EXPECT_FALSE(
- EncodeDecodeValue(test_val, static_cast<char*>(buffer), sizeof(buffer)))
- << " encode/decode of " << test_val << " succeeded, but was an "
- << "invalid value";
- }
-}
-
-// Following tests all try to fill the buffer with multiple values,
-// go one value more than the buffer can accommodate, then read
-// the successfully encoded values, and try to read the unsuccessfully
-// encoded value. The following is the number of values to encode.
-const int kMultiVarCount = 1000;
-
-// Test writing & reading multiple 8-byte-encoded varints
-TEST_P(QuicDataWriterTest, MultiVarInt8) {
- uint64_t test_val;
- char buffer[8 * kMultiVarCount];
- memset(buffer, 0, sizeof(buffer));
- QuicDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
- quiche::Endianness::NETWORK_BYTE_ORDER);
- // Put N values into the buffer. Adding i to the value ensures that
- // each value is different so we can detect if we overwrite values,
- // or read the same value over and over.
- for (int i = 0; i < kMultiVarCount; i++) {
- EXPECT_TRUE(writer.WriteVarInt62(UINT64_C(0x3142f3e4d5c6b7a8) + i));
- }
- EXPECT_EQ(writer.length(), 8u * kMultiVarCount);
-
- // N+1st should fail, the buffer is full.
- EXPECT_FALSE(writer.WriteVarInt62(UINT64_C(0x3142f3e4d5c6b7a8)));
-
- // Now we should be able to read out the N values that were
- // successfully encoded.
- QuicDataReader reader(buffer, sizeof(buffer),
- quiche::Endianness::NETWORK_BYTE_ORDER);
- for (int i = 0; i < kMultiVarCount; i++) {
- EXPECT_TRUE(reader.ReadVarInt62(&test_val));
- EXPECT_EQ(test_val, (UINT64_C(0x3142f3e4d5c6b7a8) + i));
- }
- // And the N+1st should fail.
- EXPECT_FALSE(reader.ReadVarInt62(&test_val));
-}
-
-// Test writing & reading multiple 4-byte-encoded varints
-TEST_P(QuicDataWriterTest, MultiVarInt4) {
- uint64_t test_val;
- char buffer[4 * kMultiVarCount];
- memset(buffer, 0, sizeof(buffer));
- QuicDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
- quiche::Endianness::NETWORK_BYTE_ORDER);
- // Put N values into the buffer. Adding i to the value ensures that
- // each value is different so we can detect if we overwrite values,
- // or read the same value over and over.
- for (int i = 0; i < kMultiVarCount; i++) {
- EXPECT_TRUE(writer.WriteVarInt62(UINT64_C(0x3142f3e4) + i));
- }
- EXPECT_EQ(writer.length(), 4u * kMultiVarCount);
-
- // N+1st should fail, the buffer is full.
- EXPECT_FALSE(writer.WriteVarInt62(UINT64_C(0x3142f3e4)));
-
- // Now we should be able to read out the N values that were
- // successfully encoded.
- QuicDataReader reader(buffer, sizeof(buffer),
- quiche::Endianness::NETWORK_BYTE_ORDER);
- for (int i = 0; i < kMultiVarCount; i++) {
- EXPECT_TRUE(reader.ReadVarInt62(&test_val));
- EXPECT_EQ(test_val, (UINT64_C(0x3142f3e4) + i));
- }
- // And the N+1st should fail.
- EXPECT_FALSE(reader.ReadVarInt62(&test_val));
-}
-
-// Test writing & reading multiple 2-byte-encoded varints
-TEST_P(QuicDataWriterTest, MultiVarInt2) {
- uint64_t test_val;
- char buffer[2 * kMultiVarCount];
- memset(buffer, 0, sizeof(buffer));
- QuicDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
- quiche::Endianness::NETWORK_BYTE_ORDER);
- // Put N values into the buffer. Adding i to the value ensures that
- // each value is different so we can detect if we overwrite values,
- // or read the same value over and over.
- for (int i = 0; i < kMultiVarCount; i++) {
- EXPECT_TRUE(writer.WriteVarInt62(UINT64_C(0x3142) + i));
- }
- EXPECT_EQ(writer.length(), 2u * kMultiVarCount);
-
- // N+1st should fail, the buffer is full.
- EXPECT_FALSE(writer.WriteVarInt62(UINT64_C(0x3142)));
-
- // Now we should be able to read out the N values that were
- // successfully encoded.
- QuicDataReader reader(buffer, sizeof(buffer),
- quiche::Endianness::NETWORK_BYTE_ORDER);
- for (int i = 0; i < kMultiVarCount; i++) {
- EXPECT_TRUE(reader.ReadVarInt62(&test_val));
- EXPECT_EQ(test_val, (UINT64_C(0x3142) + i));
- }
- // And the N+1st should fail.
- EXPECT_FALSE(reader.ReadVarInt62(&test_val));
-}
-
-// Test writing & reading multiple 1-byte-encoded varints
-TEST_P(QuicDataWriterTest, MultiVarInt1) {
- uint64_t test_val;
- char buffer[1 * kMultiVarCount];
- memset(buffer, 0, sizeof(buffer));
- QuicDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
- quiche::Endianness::NETWORK_BYTE_ORDER);
- // Put N values into the buffer. Adding i to the value ensures that
- // each value is different so we can detect if we overwrite values,
- // or read the same value over and over. &0xf ensures we do not
- // overflow the max value for single-byte encoding.
- for (int i = 0; i < kMultiVarCount; i++) {
- EXPECT_TRUE(writer.WriteVarInt62(UINT64_C(0x30) + (i & 0xf)));
- }
- EXPECT_EQ(writer.length(), 1u * kMultiVarCount);
-
- // N+1st should fail, the buffer is full.
- EXPECT_FALSE(writer.WriteVarInt62(UINT64_C(0x31)));
-
- // Now we should be able to read out the N values that were
- // successfully encoded.
- QuicDataReader reader(buffer, sizeof(buffer),
- quiche::Endianness::NETWORK_BYTE_ORDER);
- for (int i = 0; i < kMultiVarCount; i++) {
- EXPECT_TRUE(reader.ReadVarInt62(&test_val));
- EXPECT_EQ(test_val, (UINT64_C(0x30) + (i & 0xf)));
- }
- // And the N+1st should fail.
- EXPECT_FALSE(reader.ReadVarInt62(&test_val));
-}
-
-// Test writing varints with a forced length.
-TEST_P(QuicDataWriterTest, VarIntFixedLength) {
- char buffer[90];
- memset(buffer, 0, sizeof(buffer));
- QuicDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
- quiche::Endianness::NETWORK_BYTE_ORDER);
-
- writer.WriteVarInt62(1, VARIABLE_LENGTH_INTEGER_LENGTH_1);
- writer.WriteVarInt62(1, VARIABLE_LENGTH_INTEGER_LENGTH_2);
- writer.WriteVarInt62(1, VARIABLE_LENGTH_INTEGER_LENGTH_4);
- writer.WriteVarInt62(1, VARIABLE_LENGTH_INTEGER_LENGTH_8);
-
- writer.WriteVarInt62(63, VARIABLE_LENGTH_INTEGER_LENGTH_1);
- writer.WriteVarInt62(63, VARIABLE_LENGTH_INTEGER_LENGTH_2);
- writer.WriteVarInt62(63, VARIABLE_LENGTH_INTEGER_LENGTH_4);
- writer.WriteVarInt62(63, VARIABLE_LENGTH_INTEGER_LENGTH_8);
-
- writer.WriteVarInt62(64, VARIABLE_LENGTH_INTEGER_LENGTH_2);
- writer.WriteVarInt62(64, VARIABLE_LENGTH_INTEGER_LENGTH_4);
- writer.WriteVarInt62(64, VARIABLE_LENGTH_INTEGER_LENGTH_8);
-
- writer.WriteVarInt62(16383, VARIABLE_LENGTH_INTEGER_LENGTH_2);
- writer.WriteVarInt62(16383, VARIABLE_LENGTH_INTEGER_LENGTH_4);
- writer.WriteVarInt62(16383, VARIABLE_LENGTH_INTEGER_LENGTH_8);
-
- writer.WriteVarInt62(16384, VARIABLE_LENGTH_INTEGER_LENGTH_4);
- writer.WriteVarInt62(16384, VARIABLE_LENGTH_INTEGER_LENGTH_8);
-
- writer.WriteVarInt62(1073741823, VARIABLE_LENGTH_INTEGER_LENGTH_4);
- writer.WriteVarInt62(1073741823, VARIABLE_LENGTH_INTEGER_LENGTH_8);
-
- writer.WriteVarInt62(1073741824, VARIABLE_LENGTH_INTEGER_LENGTH_8);
-
- QuicDataReader reader(buffer, sizeof(buffer),
- quiche::Endianness::NETWORK_BYTE_ORDER);
-
- uint64_t test_val = 0;
- for (int i = 0; i < 4; ++i) {
- EXPECT_TRUE(reader.ReadVarInt62(&test_val));
- EXPECT_EQ(test_val, 1u);
- }
- for (int i = 0; i < 4; ++i) {
- EXPECT_TRUE(reader.ReadVarInt62(&test_val));
- EXPECT_EQ(test_val, 63u);
- }
-
- for (int i = 0; i < 3; ++i) {
- EXPECT_TRUE(reader.ReadVarInt62(&test_val));
- EXPECT_EQ(test_val, 64u);
- }
- for (int i = 0; i < 3; ++i) {
- EXPECT_TRUE(reader.ReadVarInt62(&test_val));
- EXPECT_EQ(test_val, 16383u);
- }
-
- for (int i = 0; i < 2; ++i) {
- EXPECT_TRUE(reader.ReadVarInt62(&test_val));
- EXPECT_EQ(test_val, 16384u);
- }
- for (int i = 0; i < 2; ++i) {
- EXPECT_TRUE(reader.ReadVarInt62(&test_val));
- EXPECT_EQ(test_val, 1073741823u);
- }
-
- EXPECT_TRUE(reader.ReadVarInt62(&test_val));
- EXPECT_EQ(test_val, 1073741824u);
-
- // We are at the end of the buffer so this should fail.
- EXPECT_FALSE(reader.ReadVarInt62(&test_val));
-}
-
-// Test encoding/decoding stream-id values.
-void EncodeDecodeStreamId(uint64_t value_in) {
- char buffer[1 * kMultiVarCount];
- memset(buffer, 0, sizeof(buffer));
-
- // Encode the given Stream ID.
- QuicDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
- quiche::Endianness::NETWORK_BYTE_ORDER);
- EXPECT_TRUE(writer.WriteVarInt62(value_in));
-
- QuicDataReader reader(buffer, sizeof(buffer),
- quiche::Endianness::NETWORK_BYTE_ORDER);
- QuicStreamId received_stream_id;
- uint64_t temp;
- EXPECT_TRUE(reader.ReadVarInt62(&temp));
- received_stream_id = static_cast<QuicStreamId>(temp);
- EXPECT_EQ(value_in, received_stream_id);
-}
-
-// Test writing & reading stream-ids of various value.
-TEST_P(QuicDataWriterTest, StreamId1) {
- // Check a 1-byte QuicStreamId, should work
- EncodeDecodeStreamId(UINT64_C(0x15));
-
- // Check a 2-byte QuicStream ID. It should work.
- EncodeDecodeStreamId(UINT64_C(0x1567));
-
- // Check a QuicStreamId that requires 4 bytes of encoding
- // This should work.
- EncodeDecodeStreamId(UINT64_C(0x34567890));
-
- // Check a QuicStreamId that requires 8 bytes of encoding
- // but whose value is in the acceptable range.
- // This should work.
- EncodeDecodeStreamId(UINT64_C(0xf4567890));
-}
-
-TEST_P(QuicDataWriterTest, WriteRandomBytes) {
- char buffer[20];
- char expected[20];
- for (size_t i = 0; i < 20; ++i) {
- expected[i] = 'r';
- }
- MockRandom random;
- QuicDataWriter writer(20, buffer, GetParam().endianness);
- EXPECT_FALSE(writer.WriteRandomBytes(&random, 30));
-
- EXPECT_TRUE(writer.WriteRandomBytes(&random, 20));
- quiche::test::CompareCharArraysWithHexError("random", buffer, 20, expected,
- 20);
-}
-
-TEST_P(QuicDataWriterTest, WriteInsecureRandomBytes) {
- char buffer[20];
- char expected[20];
- for (size_t i = 0; i < 20; ++i) {
- expected[i] = 'r';
- }
- MockRandom random;
- QuicDataWriter writer(20, buffer, GetParam().endianness);
- EXPECT_FALSE(writer.WriteInsecureRandomBytes(&random, 30));
-
- EXPECT_TRUE(writer.WriteInsecureRandomBytes(&random, 20));
- quiche::test::CompareCharArraysWithHexError("random", buffer, 20, expected,
- 20);
-}
-
-TEST_P(QuicDataWriterTest, PeekVarInt62Length) {
- // In range [0, 63], variable length should be 1 byte.
- char buffer[20];
- QuicDataWriter writer(20, buffer, quiche::NETWORK_BYTE_ORDER);
- EXPECT_TRUE(writer.WriteVarInt62(50));
- QuicDataReader reader(buffer, 20, quiche::NETWORK_BYTE_ORDER);
- EXPECT_EQ(1, reader.PeekVarInt62Length());
- // In range (63-16383], variable length should be 2 byte2.
- char buffer2[20];
- QuicDataWriter writer2(20, buffer2, quiche::NETWORK_BYTE_ORDER);
- EXPECT_TRUE(writer2.WriteVarInt62(100));
- QuicDataReader reader2(buffer2, 20, quiche::NETWORK_BYTE_ORDER);
- EXPECT_EQ(2, reader2.PeekVarInt62Length());
- // In range (16383, 1073741823], variable length should be 4 bytes.
- char buffer3[20];
- QuicDataWriter writer3(20, buffer3, quiche::NETWORK_BYTE_ORDER);
- EXPECT_TRUE(writer3.WriteVarInt62(20000));
- QuicDataReader reader3(buffer3, 20, quiche::NETWORK_BYTE_ORDER);
- EXPECT_EQ(4, reader3.PeekVarInt62Length());
- // In range (1073741823, 4611686018427387903], variable length should be 8
- // bytes.
- char buffer4[20];
- QuicDataWriter writer4(20, buffer4, quiche::NETWORK_BYTE_ORDER);
- EXPECT_TRUE(writer4.WriteVarInt62(2000000000));
- QuicDataReader reader4(buffer4, 20, quiche::NETWORK_BYTE_ORDER);
- EXPECT_EQ(8, reader4.PeekVarInt62Length());
-}
-
-TEST_P(QuicDataWriterTest, ValidStreamCount) {
- char buffer[1024];
- memset(buffer, 0, sizeof(buffer));
- QuicDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
- quiche::Endianness::NETWORK_BYTE_ORDER);
- QuicDataReader reader(buffer, sizeof(buffer));
- const QuicStreamCount write_stream_count = 0xffeeddcc;
- EXPECT_TRUE(writer.WriteVarInt62(write_stream_count));
- QuicStreamCount read_stream_count;
- uint64_t temp;
- EXPECT_TRUE(reader.ReadVarInt62(&temp));
- read_stream_count = static_cast<QuicStreamId>(temp);
- EXPECT_EQ(write_stream_count, read_stream_count);
-}
-
-TEST_P(QuicDataWriterTest, Seek) {
- char buffer[3] = {};
- QuicDataWriter writer(ABSL_ARRAYSIZE(buffer), buffer, GetParam().endianness);
- EXPECT_TRUE(writer.WriteUInt8(42));
- EXPECT_TRUE(writer.Seek(1));
- EXPECT_TRUE(writer.WriteUInt8(3));
-
- char expected[] = {42, 0, 3};
- for (size_t i = 0; i < ABSL_ARRAYSIZE(expected); ++i) {
- EXPECT_EQ(buffer[i], expected[i]);
- }
-}
-
-TEST_P(QuicDataWriterTest, SeekTooFarFails) {
- char buffer[20];
-
- // Check that one can seek to the end of the writer, but not past.
- {
- QuicDataWriter writer(ABSL_ARRAYSIZE(buffer), buffer,
- GetParam().endianness);
- EXPECT_TRUE(writer.Seek(20));
- EXPECT_FALSE(writer.Seek(1));
- }
-
- // Seeking several bytes past the end fails.
- {
- QuicDataWriter writer(ABSL_ARRAYSIZE(buffer), buffer,
- GetParam().endianness);
- EXPECT_FALSE(writer.Seek(100));
- }
-
- // Seeking so far that arithmetic overflow could occur also fails.
- {
- QuicDataWriter writer(ABSL_ARRAYSIZE(buffer), buffer,
- GetParam().endianness);
- EXPECT_TRUE(writer.Seek(10));
- EXPECT_FALSE(writer.Seek(std::numeric_limits<size_t>::max()));
- }
-}
-
-TEST_P(QuicDataWriterTest, PayloadReads) {
- char buffer[16] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
- char expected_first_read[4] = {1, 2, 3, 4};
- char expected_remaining[12] = {5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
- QuicDataReader reader(buffer, sizeof(buffer));
- char first_read_buffer[4] = {};
- EXPECT_TRUE(reader.ReadBytes(first_read_buffer, sizeof(first_read_buffer)));
- quiche::test::CompareCharArraysWithHexError(
- "first read", first_read_buffer, sizeof(first_read_buffer),
- expected_first_read, sizeof(expected_first_read));
- absl::string_view peeked_remaining_payload = reader.PeekRemainingPayload();
- quiche::test::CompareCharArraysWithHexError(
- "peeked_remaining_payload", peeked_remaining_payload.data(),
- peeked_remaining_payload.length(), expected_remaining,
- sizeof(expected_remaining));
- absl::string_view full_payload = reader.FullPayload();
- quiche::test::CompareCharArraysWithHexError(
- "full_payload", full_payload.data(), full_payload.length(), buffer,
- sizeof(buffer));
- absl::string_view read_remaining_payload = reader.ReadRemainingPayload();
- quiche::test::CompareCharArraysWithHexError(
- "read_remaining_payload", read_remaining_payload.data(),
- read_remaining_payload.length(), expected_remaining,
- sizeof(expected_remaining));
- EXPECT_TRUE(reader.IsDoneReading());
- absl::string_view full_payload2 = reader.FullPayload();
- quiche::test::CompareCharArraysWithHexError(
- "full_payload2", full_payload2.data(), full_payload2.length(), buffer,
- sizeof(buffer));
-}
-
-TEST_P(QuicDataWriterTest, StringPieceVarInt62) {
- char inner_buffer[16] = {1, 2, 3, 4, 5, 6, 7, 8,
- 9, 10, 11, 12, 13, 14, 15, 16};
- absl::string_view inner_payload_write(inner_buffer, sizeof(inner_buffer));
- char buffer[sizeof(inner_buffer) + sizeof(uint8_t)] = {};
- QuicDataWriter writer(sizeof(buffer), buffer);
- EXPECT_TRUE(writer.WriteStringPieceVarInt62(inner_payload_write));
- EXPECT_EQ(0u, writer.remaining());
- QuicDataReader reader(buffer, sizeof(buffer));
- absl::string_view inner_payload_read;
- EXPECT_TRUE(reader.ReadStringPieceVarInt62(&inner_payload_read));
- quiche::test::CompareCharArraysWithHexError(
- "inner_payload", inner_payload_write.data(), inner_payload_write.length(),
- inner_payload_read.data(), inner_payload_read.length());
-}
-
-} // namespace
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_datagram_queue.cc b/chromium/net/third_party/quiche/src/quic/core/quic_datagram_queue.cc
deleted file mode 100644
index ebd74836597..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_datagram_queue.cc
+++ /dev/null
@@ -1,100 +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 "quic/core/quic_datagram_queue.h"
-
-#include "absl/types/span.h"
-#include "quic/core/quic_constants.h"
-#include "quic/core/quic_session.h"
-#include "quic/core/quic_time.h"
-#include "quic/core/quic_types.h"
-
-namespace quic {
-
-
-constexpr float kExpiryInMinRtts = 1.25;
-constexpr float kMinPacingWindows = 4;
-
-QuicDatagramQueue::QuicDatagramQueue(QuicSession* session)
- : QuicDatagramQueue(session, nullptr) {}
-
-QuicDatagramQueue::QuicDatagramQueue(QuicSession* session,
- std::unique_ptr<Observer> observer)
- : session_(session),
- clock_(session->connection()->clock()),
- observer_(std::move(observer)) {}
-
-MessageStatus QuicDatagramQueue::SendOrQueueDatagram(QuicMemSlice datagram) {
- // If the queue is non-empty, always queue the daragram. This ensures that
- // the datagrams are sent in the same order that they were sent by the
- // application.
- if (queue_.empty()) {
- MessageResult result = session_->SendMessage(absl::MakeSpan(&datagram, 1));
- if (result.status != MESSAGE_STATUS_BLOCKED) {
- if (observer_) {
- observer_->OnDatagramProcessed(result.status);
- }
- return result.status;
- }
- }
-
- queue_.emplace_back(Datagram{std::move(datagram),
- clock_->ApproximateNow() + GetMaxTimeInQueue()});
- return MESSAGE_STATUS_BLOCKED;
-}
-
-absl::optional<MessageStatus> QuicDatagramQueue::TrySendingNextDatagram() {
- RemoveExpiredDatagrams();
- if (queue_.empty()) {
- return absl::nullopt;
- }
-
- MessageResult result =
- session_->SendMessage(absl::MakeSpan(&queue_.front().datagram, 1));
- if (result.status != MESSAGE_STATUS_BLOCKED) {
- queue_.pop_front();
- if (observer_) {
- observer_->OnDatagramProcessed(result.status);
- }
- }
- return result.status;
-}
-
-size_t QuicDatagramQueue::SendDatagrams() {
- size_t num_datagrams = 0;
- for (;;) {
- absl::optional<MessageStatus> status = TrySendingNextDatagram();
- if (!status.has_value()) {
- break;
- }
- if (*status == MESSAGE_STATUS_BLOCKED) {
- break;
- }
- num_datagrams++;
- }
- return num_datagrams;
-}
-
-QuicTime::Delta QuicDatagramQueue::GetMaxTimeInQueue() const {
- if (!max_time_in_queue_.IsZero()) {
- return max_time_in_queue_;
- }
-
- const QuicTime::Delta min_rtt =
- session_->connection()->sent_packet_manager().GetRttStats()->min_rtt();
- return std::max(kExpiryInMinRtts * min_rtt,
- kMinPacingWindows * kAlarmGranularity);
-}
-
-void QuicDatagramQueue::RemoveExpiredDatagrams() {
- QuicTime now = clock_->ApproximateNow();
- while (!queue_.empty() && queue_.front().expiry <= now) {
- queue_.pop_front();
- if (observer_) {
- observer_->OnDatagramProcessed(absl::nullopt);
- }
- }
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_datagram_queue.h b/chromium/net/third_party/quiche/src/quic/core/quic_datagram_queue.h
deleted file mode 100644
index 4d3aa2f17f3..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_datagram_queue.h
+++ /dev/null
@@ -1,89 +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_CORE_QUIC_DATAGRAM_QUEUE_H_
-#define QUICHE_QUIC_CORE_QUIC_DATAGRAM_QUEUE_H_
-
-#include <memory>
-
-#include "absl/types/optional.h"
-#include "quic/core/quic_time.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_mem_slice.h"
-#include "common/quiche_circular_deque.h"
-
-namespace quic {
-
-class QuicSession;
-
-// Provides a way to buffer QUIC datagrams (messages) in case they cannot
-// be sent due to congestion control. Datagrams are buffered for a limited
-// amount of time, and deleted after that time passes.
-class QUIC_EXPORT_PRIVATE QuicDatagramQueue {
- public:
- // An interface used to monitor events on the associated `QuicDatagramQueue`.
- class QUIC_EXPORT_PRIVATE Observer {
- public:
- virtual ~Observer() = default;
-
- // Called when a datagram in the associated queue is sent or discarded.
- // Identity information for the datagram is not given, because the sending
- // and discarding order is always first-in-first-out.
- // This function is called synchronously in `QuicDatagramQueue` methods.
- // `status` is nullopt when the datagram is dropped due to being in the
- // queue for too long.
- virtual void OnDatagramProcessed(absl::optional<MessageStatus> status) = 0;
- };
-
- // |session| is not owned and must outlive this object.
- explicit QuicDatagramQueue(QuicSession* session);
-
- // |session| is not owned and must outlive this object.
- QuicDatagramQueue(QuicSession* session, std::unique_ptr<Observer> observer);
-
- // Adds the datagram to the end of the queue. May send it immediately; if
- // not, MESSAGE_STATUS_BLOCKED is returned.
- MessageStatus SendOrQueueDatagram(QuicMemSlice datagram);
-
- // Attempts to send a single datagram from the queue. Returns the result of
- // SendMessage(), or nullopt if there were no unexpired datagrams to send.
- absl::optional<MessageStatus> TrySendingNextDatagram();
-
- // Sends all of the unexpired datagrams until either the connection becomes
- // write-blocked or the queue is empty. Returns the number of datagrams sent.
- size_t SendDatagrams();
-
- // Returns the amount of time a datagram is allowed to be in the queue before
- // it is dropped. If not set explicitly using SetMaxTimeInQueue(), an
- // RTT-based heuristic is used.
- QuicTime::Delta GetMaxTimeInQueue() const;
-
- void SetMaxTimeInQueue(QuicTime::Delta max_time_in_queue) {
- max_time_in_queue_ = max_time_in_queue;
- }
-
- size_t queue_size() { return queue_.size(); }
-
- bool empty() { return queue_.empty(); }
-
- private:
- struct QUIC_EXPORT_PRIVATE Datagram {
- QuicMemSlice datagram;
- QuicTime expiry;
- };
-
- // Removes expired datagrams from the front of the queue.
- void RemoveExpiredDatagrams();
-
- QuicSession* session_; // Not owned.
- const QuicClock* clock_;
-
- QuicTime::Delta max_time_in_queue_ = QuicTime::Delta::Zero();
- quiche::QuicheCircularDeque<Datagram> queue_;
- std::unique_ptr<Observer> observer_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_QUIC_DATAGRAM_QUEUE_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_datagram_queue_test.cc b/chromium/net/third_party/quiche/src/quic/core/quic_datagram_queue_test.cc
deleted file mode 100644
index 68a876b4cd0..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_datagram_queue_test.cc
+++ /dev/null
@@ -1,298 +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 "quic/core/quic_datagram_queue.h"
-
-#include <vector>
-
-#include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
-#include "quic/core/crypto/null_encrypter.h"
-#include "quic/core/quic_buffer_allocator.h"
-#include "quic/core/quic_time.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_mem_slice.h"
-#include "quic/platform/api/quic_reference_counted.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/quic_test_utils.h"
-
-namespace quic {
-namespace test {
-namespace {
-
-
-using testing::_;
-using testing::ElementsAre;
-using testing::Return;
-
-class EstablishedCryptoStream : public MockQuicCryptoStream {
- public:
- using MockQuicCryptoStream::MockQuicCryptoStream;
-
- bool encryption_established() const override { return true; }
-};
-
-class QuicDatagramQueueObserver final : public QuicDatagramQueue::Observer {
- public:
- class Context : public QuicReferenceCounted {
- public:
- std::vector<absl::optional<MessageStatus>> statuses;
- };
-
- QuicDatagramQueueObserver() : context_(new Context()) {}
- QuicDatagramQueueObserver(const QuicDatagramQueueObserver&) = delete;
- QuicDatagramQueueObserver& operator=(const QuicDatagramQueueObserver&) =
- delete;
-
- void OnDatagramProcessed(absl::optional<MessageStatus> status) override {
- context_->statuses.push_back(std::move(status));
- }
-
- const QuicReferenceCountedPointer<Context>& context() { return context_; }
-
- private:
- QuicReferenceCountedPointer<Context> context_;
-};
-
-class QuicDatagramQueueTestBase : public QuicTest {
- protected:
- QuicDatagramQueueTestBase()
- : connection_(new MockQuicConnection(&helper_,
- &alarm_factory_,
- Perspective::IS_CLIENT)),
- session_(connection_) {
- session_.SetCryptoStream(new EstablishedCryptoStream(&session_));
- connection_->SetEncrypter(
- ENCRYPTION_FORWARD_SECURE,
- std::make_unique<NullEncrypter>(connection_->perspective()));
- }
-
- ~QuicDatagramQueueTestBase() = default;
-
- QuicMemSlice CreateMemSlice(absl::string_view data) {
- QuicUniqueBufferPtr buffer =
- MakeUniqueBuffer(helper_.GetStreamSendBufferAllocator(), data.size());
- memcpy(buffer.get(), data.data(), data.size());
- return QuicMemSlice(std::move(buffer), data.size());
- }
-
- MockQuicConnectionHelper helper_;
- MockAlarmFactory alarm_factory_;
- MockQuicConnection* connection_; // Owned by |session_|.
- MockQuicSession session_;
-};
-
-class QuicDatagramQueueTest : public QuicDatagramQueueTestBase {
- public:
- QuicDatagramQueueTest() : queue_(&session_) {}
-
- protected:
- QuicDatagramQueue queue_;
-};
-
-TEST_F(QuicDatagramQueueTest, SendDatagramImmediately) {
- EXPECT_CALL(*connection_, SendMessage(_, _, _))
- .WillOnce(Return(MESSAGE_STATUS_SUCCESS));
- MessageStatus status = queue_.SendOrQueueDatagram(CreateMemSlice("test"));
- EXPECT_EQ(MESSAGE_STATUS_SUCCESS, status);
- EXPECT_EQ(0u, queue_.queue_size());
-}
-
-TEST_F(QuicDatagramQueueTest, SendDatagramAfterBuffering) {
- EXPECT_CALL(*connection_, SendMessage(_, _, _))
- .WillOnce(Return(MESSAGE_STATUS_BLOCKED));
- MessageStatus initial_status =
- queue_.SendOrQueueDatagram(CreateMemSlice("test"));
- EXPECT_EQ(MESSAGE_STATUS_BLOCKED, initial_status);
- EXPECT_EQ(1u, queue_.queue_size());
-
- // Verify getting write blocked does not remove the datagram from the queue.
- EXPECT_CALL(*connection_, SendMessage(_, _, _))
- .WillOnce(Return(MESSAGE_STATUS_BLOCKED));
- absl::optional<MessageStatus> status = queue_.TrySendingNextDatagram();
- ASSERT_TRUE(status.has_value());
- EXPECT_EQ(MESSAGE_STATUS_BLOCKED, *status);
- EXPECT_EQ(1u, queue_.queue_size());
-
- EXPECT_CALL(*connection_, SendMessage(_, _, _))
- .WillOnce(Return(MESSAGE_STATUS_SUCCESS));
- status = queue_.TrySendingNextDatagram();
- ASSERT_TRUE(status.has_value());
- EXPECT_EQ(MESSAGE_STATUS_SUCCESS, *status);
- EXPECT_EQ(0u, queue_.queue_size());
-}
-
-TEST_F(QuicDatagramQueueTest, EmptyBuffer) {
- absl::optional<MessageStatus> status = queue_.TrySendingNextDatagram();
- EXPECT_FALSE(status.has_value());
-
- size_t num_messages = queue_.SendDatagrams();
- EXPECT_EQ(0u, num_messages);
-}
-
-TEST_F(QuicDatagramQueueTest, MultipleDatagrams) {
- // Note that SendMessage() is called only once here, since all the remaining
- // messages are automatically queued due to the queue being non-empty.
- EXPECT_CALL(*connection_, SendMessage(_, _, _))
- .WillOnce(Return(MESSAGE_STATUS_BLOCKED));
- queue_.SendOrQueueDatagram(CreateMemSlice("a"));
- queue_.SendOrQueueDatagram(CreateMemSlice("b"));
- queue_.SendOrQueueDatagram(CreateMemSlice("c"));
- queue_.SendOrQueueDatagram(CreateMemSlice("d"));
- queue_.SendOrQueueDatagram(CreateMemSlice("e"));
-
- EXPECT_CALL(*connection_, SendMessage(_, _, _))
- .Times(5)
- .WillRepeatedly(Return(MESSAGE_STATUS_SUCCESS));
- size_t num_messages = queue_.SendDatagrams();
- EXPECT_EQ(5u, num_messages);
-}
-
-TEST_F(QuicDatagramQueueTest, DefaultMaxTimeInQueue) {
- EXPECT_EQ(QuicTime::Delta::Zero(),
- connection_->sent_packet_manager().GetRttStats()->min_rtt());
- EXPECT_EQ(QuicTime::Delta::FromMilliseconds(4), queue_.GetMaxTimeInQueue());
-
- RttStats* stats =
- const_cast<RttStats*>(connection_->sent_packet_manager().GetRttStats());
- stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(100),
- QuicTime::Delta::Zero(), helper_.GetClock()->Now());
- EXPECT_EQ(QuicTime::Delta::FromMilliseconds(125), queue_.GetMaxTimeInQueue());
-}
-
-TEST_F(QuicDatagramQueueTest, Expiry) {
- constexpr QuicTime::Delta expiry = QuicTime::Delta::FromMilliseconds(100);
- queue_.SetMaxTimeInQueue(expiry);
-
- EXPECT_CALL(*connection_, SendMessage(_, _, _))
- .WillOnce(Return(MESSAGE_STATUS_BLOCKED));
- queue_.SendOrQueueDatagram(CreateMemSlice("a"));
- helper_.AdvanceTime(0.6 * expiry);
- queue_.SendOrQueueDatagram(CreateMemSlice("b"));
- helper_.AdvanceTime(0.6 * expiry);
- queue_.SendOrQueueDatagram(CreateMemSlice("c"));
-
- std::vector<std::string> messages;
- EXPECT_CALL(*connection_, SendMessage(_, _, _))
- .WillRepeatedly([&messages](QuicMessageId /*id*/,
- absl::Span<QuicMemSlice> message,
- bool /*flush*/) {
- messages.push_back(std::string(message[0].AsStringView()));
- return MESSAGE_STATUS_SUCCESS;
- });
- EXPECT_EQ(2u, queue_.SendDatagrams());
- EXPECT_THAT(messages, ElementsAre("b", "c"));
-}
-
-TEST_F(QuicDatagramQueueTest, ExpireAll) {
- constexpr QuicTime::Delta expiry = QuicTime::Delta::FromMilliseconds(100);
- queue_.SetMaxTimeInQueue(expiry);
-
- EXPECT_CALL(*connection_, SendMessage(_, _, _))
- .WillOnce(Return(MESSAGE_STATUS_BLOCKED));
- queue_.SendOrQueueDatagram(CreateMemSlice("a"));
- queue_.SendOrQueueDatagram(CreateMemSlice("b"));
- queue_.SendOrQueueDatagram(CreateMemSlice("c"));
-
- helper_.AdvanceTime(100 * expiry);
- EXPECT_CALL(*connection_, SendMessage(_, _, _)).Times(0);
- EXPECT_EQ(0u, queue_.SendDatagrams());
-}
-
-class QuicDatagramQueueWithObserverTest : public QuicDatagramQueueTestBase {
- public:
- QuicDatagramQueueWithObserverTest()
- : observer_(std::make_unique<QuicDatagramQueueObserver>()),
- context_(observer_->context()),
- queue_(&session_, std::move(observer_)) {}
-
- protected:
- // This is moved out immediately.
- std::unique_ptr<QuicDatagramQueueObserver> observer_;
-
- QuicReferenceCountedPointer<QuicDatagramQueueObserver::Context> context_;
- QuicDatagramQueue queue_;
-};
-
-TEST_F(QuicDatagramQueueWithObserverTest, ObserveSuccessImmediately) {
- EXPECT_TRUE(context_->statuses.empty());
-
- EXPECT_CALL(*connection_, SendMessage(_, _, _))
- .WillOnce(Return(MESSAGE_STATUS_SUCCESS));
-
- EXPECT_EQ(MESSAGE_STATUS_SUCCESS,
- queue_.SendOrQueueDatagram(CreateMemSlice("a")));
-
- EXPECT_THAT(context_->statuses, ElementsAre(MESSAGE_STATUS_SUCCESS));
-}
-
-TEST_F(QuicDatagramQueueWithObserverTest, ObserveFailureImmediately) {
- EXPECT_TRUE(context_->statuses.empty());
-
- EXPECT_CALL(*connection_, SendMessage(_, _, _))
- .WillOnce(Return(MESSAGE_STATUS_TOO_LARGE));
-
- EXPECT_EQ(MESSAGE_STATUS_TOO_LARGE,
- queue_.SendOrQueueDatagram(CreateMemSlice("a")));
-
- EXPECT_THAT(context_->statuses, ElementsAre(MESSAGE_STATUS_TOO_LARGE));
-}
-
-TEST_F(QuicDatagramQueueWithObserverTest, BlockingShouldNotBeObserved) {
- EXPECT_TRUE(context_->statuses.empty());
-
- EXPECT_CALL(*connection_, SendMessage(_, _, _))
- .WillRepeatedly(Return(MESSAGE_STATUS_BLOCKED));
-
- EXPECT_EQ(MESSAGE_STATUS_BLOCKED,
- queue_.SendOrQueueDatagram(CreateMemSlice("a")));
- EXPECT_EQ(0u, queue_.SendDatagrams());
-
- EXPECT_TRUE(context_->statuses.empty());
-}
-
-TEST_F(QuicDatagramQueueWithObserverTest, ObserveSuccessAfterBuffering) {
- EXPECT_TRUE(context_->statuses.empty());
-
- EXPECT_CALL(*connection_, SendMessage(_, _, _))
- .WillOnce(Return(MESSAGE_STATUS_BLOCKED));
-
- EXPECT_EQ(MESSAGE_STATUS_BLOCKED,
- queue_.SendOrQueueDatagram(CreateMemSlice("a")));
-
- EXPECT_TRUE(context_->statuses.empty());
-
- EXPECT_CALL(*connection_, SendMessage(_, _, _))
- .WillOnce(Return(MESSAGE_STATUS_SUCCESS));
-
- EXPECT_EQ(1u, queue_.SendDatagrams());
- EXPECT_THAT(context_->statuses, ElementsAre(MESSAGE_STATUS_SUCCESS));
-}
-
-TEST_F(QuicDatagramQueueWithObserverTest, ObserveExpiry) {
- constexpr QuicTime::Delta expiry = QuicTime::Delta::FromMilliseconds(100);
- queue_.SetMaxTimeInQueue(expiry);
-
- EXPECT_TRUE(context_->statuses.empty());
-
- EXPECT_CALL(*connection_, SendMessage(_, _, _))
- .WillOnce(Return(MESSAGE_STATUS_BLOCKED));
-
- EXPECT_EQ(MESSAGE_STATUS_BLOCKED,
- queue_.SendOrQueueDatagram(CreateMemSlice("a")));
-
- EXPECT_TRUE(context_->statuses.empty());
-
- EXPECT_CALL(*connection_, SendMessage(_, _, _)).Times(0);
- helper_.AdvanceTime(100 * expiry);
-
- EXPECT_TRUE(context_->statuses.empty());
-
- EXPECT_EQ(0u, queue_.SendDatagrams());
- EXPECT_THAT(context_->statuses, ElementsAre(absl::nullopt));
-}
-
-} // namespace
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_default_packet_writer.cc b/chromium/net/third_party/quiche/src/quic/core/quic_default_packet_writer.cc
deleted file mode 100644
index e71169a6b57..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_default_packet_writer.cc
+++ /dev/null
@@ -1,71 +0,0 @@
-// Copyright 2013 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 "quic/core/quic_default_packet_writer.h"
-
-#include "quic/core/quic_udp_socket.h"
-
-namespace quic {
-
-QuicDefaultPacketWriter::QuicDefaultPacketWriter(int fd)
- : fd_(fd), write_blocked_(false) {}
-
-QuicDefaultPacketWriter::~QuicDefaultPacketWriter() = default;
-
-WriteResult QuicDefaultPacketWriter::WritePacket(
- const char* buffer,
- size_t buf_len,
- const QuicIpAddress& self_address,
- const QuicSocketAddress& peer_address,
- PerPacketOptions* options) {
- QUICHE_DCHECK(!write_blocked_);
- QUICHE_DCHECK(nullptr == options)
- << "QuicDefaultPacketWriter does not accept any options.";
- QuicUdpPacketInfo packet_info;
- packet_info.SetPeerAddress(peer_address);
- packet_info.SetSelfIp(self_address);
- WriteResult result =
- QuicUdpSocketApi().WritePacket(fd_, buffer, buf_len, packet_info);
- if (IsWriteBlockedStatus(result.status)) {
- write_blocked_ = true;
- }
- return result;
-}
-
-bool QuicDefaultPacketWriter::IsWriteBlocked() const {
- return write_blocked_;
-}
-
-void QuicDefaultPacketWriter::SetWritable() {
- write_blocked_ = false;
-}
-
-QuicByteCount QuicDefaultPacketWriter::GetMaxPacketSize(
- const QuicSocketAddress& /*peer_address*/) const {
- return kMaxOutgoingPacketSize;
-}
-
-bool QuicDefaultPacketWriter::SupportsReleaseTime() const {
- return false;
-}
-
-bool QuicDefaultPacketWriter::IsBatchMode() const {
- return false;
-}
-
-QuicPacketBuffer QuicDefaultPacketWriter::GetNextWriteLocation(
- const QuicIpAddress& /*self_address*/,
- const QuicSocketAddress& /*peer_address*/) {
- return {nullptr, nullptr};
-}
-
-WriteResult QuicDefaultPacketWriter::Flush() {
- return WriteResult(WRITE_STATUS_OK, 0);
-}
-
-void QuicDefaultPacketWriter::set_write_blocked(bool is_blocked) {
- write_blocked_ = is_blocked;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_default_packet_writer.h b/chromium/net/third_party/quiche/src/quic/core/quic_default_packet_writer.h
deleted file mode 100644
index df30f248f40..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_default_packet_writer.h
+++ /dev/null
@@ -1,56 +0,0 @@
-// Copyright 2013 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_DEFAULT_PACKET_WRITER_H_
-#define QUICHE_QUIC_CORE_QUIC_DEFAULT_PACKET_WRITER_H_
-
-#include <cstddef>
-
-#include "quic/core/quic_packet_writer.h"
-#include "quic/platform/api/quic_export.h"
-#include "quic/platform/api/quic_socket_address.h"
-
-namespace quic {
-
-struct WriteResult;
-
-// Default packet writer which wraps QuicSocketUtils WritePacket.
-class QUIC_EXPORT_PRIVATE QuicDefaultPacketWriter : public QuicPacketWriter {
- public:
- explicit QuicDefaultPacketWriter(int fd);
- QuicDefaultPacketWriter(const QuicDefaultPacketWriter&) = delete;
- QuicDefaultPacketWriter& operator=(const QuicDefaultPacketWriter&) = delete;
- ~QuicDefaultPacketWriter() override;
-
- // QuicPacketWriter
- WriteResult WritePacket(const char* buffer,
- size_t buf_len,
- const QuicIpAddress& self_address,
- const QuicSocketAddress& peer_address,
- PerPacketOptions* options) override;
- bool IsWriteBlocked() const override;
- void SetWritable() override;
- QuicByteCount GetMaxPacketSize(
- const QuicSocketAddress& peer_address) const override;
- bool SupportsReleaseTime() const override;
- bool IsBatchMode() const override;
- QuicPacketBuffer GetNextWriteLocation(
- const QuicIpAddress& self_address,
- const QuicSocketAddress& peer_address) override;
- WriteResult Flush() override;
-
- void set_fd(int fd) { fd_ = fd; }
-
- protected:
- void set_write_blocked(bool is_blocked);
- int fd() { return fd_; }
-
- private:
- int fd_;
- bool write_blocked_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_QUIC_DEFAULT_PACKET_WRITER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_dispatcher.cc b/chromium/net/third_party/quiche/src/quic/core/quic_dispatcher.cc
deleted file mode 100644
index 0da608c6900..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_dispatcher.cc
+++ /dev/null
@@ -1,1456 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_dispatcher.h"
-
-#include <memory>
-#include <string>
-#include <utility>
-
-#include "absl/container/flat_hash_set.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/chlo_extractor.h"
-#include "quic/core/crypto/crypto_protocol.h"
-#include "quic/core/crypto/quic_random.h"
-#include "quic/core/quic_connection_id.h"
-#include "quic/core/quic_error_codes.h"
-#include "quic/core/quic_session.h"
-#include "quic/core/quic_time_wait_list_manager.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_utils.h"
-#include "quic/core/quic_versions.h"
-#include "quic/core/tls_chlo_extractor.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_flag_utils.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/platform/api/quic_stack_trace.h"
-#include "common/quiche_text_utils.h"
-
-namespace quic {
-
-using BufferedPacket = QuicBufferedPacketStore::BufferedPacket;
-using BufferedPacketList = QuicBufferedPacketStore::BufferedPacketList;
-using EnqueuePacketResult = QuicBufferedPacketStore::EnqueuePacketResult;
-
-namespace {
-
-// Minimal INITIAL packet length sent by clients is 1200.
-const QuicPacketLength kMinClientInitialPacketLength = 1200;
-
-// An alarm that informs the QuicDispatcher to delete old sessions.
-class DeleteSessionsAlarm : public QuicAlarm::DelegateWithoutContext {
- public:
- explicit DeleteSessionsAlarm(QuicDispatcher* dispatcher)
- : dispatcher_(dispatcher) {}
- DeleteSessionsAlarm(const DeleteSessionsAlarm&) = delete;
- DeleteSessionsAlarm& operator=(const DeleteSessionsAlarm&) = delete;
-
- void OnAlarm() override { dispatcher_->DeleteSessions(); }
-
- private:
- // Not owned.
- QuicDispatcher* dispatcher_;
-};
-
-// An alarm that informs the QuicDispatcher to clear
-// recent_stateless_reset_addresses_.
-class ClearStatelessResetAddressesAlarm
- : public QuicAlarm::DelegateWithoutContext {
- public:
- explicit ClearStatelessResetAddressesAlarm(QuicDispatcher* dispatcher)
- : dispatcher_(dispatcher) {}
- ClearStatelessResetAddressesAlarm(const DeleteSessionsAlarm&) = delete;
- ClearStatelessResetAddressesAlarm& operator=(const DeleteSessionsAlarm&) =
- delete;
-
- void OnAlarm() override { dispatcher_->ClearStatelessResetAddresses(); }
-
- private:
- // Not owned.
- QuicDispatcher* dispatcher_;
-};
-
-// Collects packets serialized by a QuicPacketCreator in order
-// to be handed off to the time wait list manager.
-class PacketCollector : public QuicPacketCreator::DelegateInterface,
- public QuicStreamFrameDataProducer {
- public:
- explicit PacketCollector(QuicBufferAllocator* allocator)
- : send_buffer_(allocator) {}
- ~PacketCollector() override = default;
-
- // QuicPacketCreator::DelegateInterface methods:
- void OnSerializedPacket(SerializedPacket serialized_packet) override {
- // Make a copy of the serialized packet to send later.
- packets_.emplace_back(
- new QuicEncryptedPacket(CopyBuffer(serialized_packet),
- serialized_packet.encrypted_length, true));
- }
-
- QuicPacketBuffer GetPacketBuffer() override {
- // Let QuicPacketCreator to serialize packets on stack buffer.
- return {nullptr, nullptr};
- }
-
- void OnUnrecoverableError(QuicErrorCode /*error*/,
- const std::string& /*error_details*/) override {}
-
- bool ShouldGeneratePacket(HasRetransmittableData /*retransmittable*/,
- IsHandshake /*handshake*/) override {
- QUICHE_DCHECK(false);
- return true;
- }
-
- const QuicFrames MaybeBundleAckOpportunistically() override {
- QUICHE_DCHECK(false);
- return {};
- }
-
- SerializedPacketFate GetSerializedPacketFate(
- bool /*is_mtu_discovery*/,
- EncryptionLevel /*encryption_level*/) override {
- return SEND_TO_WRITER;
- }
-
- // QuicStreamFrameDataProducer
- WriteStreamDataResult WriteStreamData(QuicStreamId /*id*/,
- QuicStreamOffset offset,
- QuicByteCount data_length,
- QuicDataWriter* writer) override {
- if (send_buffer_.WriteStreamData(offset, data_length, writer)) {
- return WRITE_SUCCESS;
- }
- return WRITE_FAILED;
- }
- bool WriteCryptoData(EncryptionLevel /*level*/,
- QuicStreamOffset offset,
- QuicByteCount data_length,
- QuicDataWriter* writer) override {
- return send_buffer_.WriteStreamData(offset, data_length, writer);
- }
-
- std::vector<std::unique_ptr<QuicEncryptedPacket>>* packets() {
- return &packets_;
- }
-
- private:
- std::vector<std::unique_ptr<QuicEncryptedPacket>> packets_;
- // This is only needed until the packets are encrypted. Once packets are
- // encrypted, the stream data is no longer required.
- QuicStreamSendBuffer send_buffer_;
-};
-
-// Helper for statelessly closing connections by generating the
-// correct termination packets and adding the connection to the time wait
-// list manager.
-class StatelessConnectionTerminator {
- public:
- StatelessConnectionTerminator(QuicConnectionId server_connection_id,
- const ParsedQuicVersion version,
- QuicConnectionHelperInterface* helper,
- QuicTimeWaitListManager* time_wait_list_manager)
- : server_connection_id_(server_connection_id),
- framer_(ParsedQuicVersionVector{version},
- /*unused*/ QuicTime::Zero(),
- Perspective::IS_SERVER,
- /*unused*/ kQuicDefaultConnectionIdLength),
- collector_(helper->GetStreamSendBufferAllocator()),
- creator_(server_connection_id, &framer_, &collector_),
- time_wait_list_manager_(time_wait_list_manager) {
- framer_.set_data_producer(&collector_);
- framer_.SetInitialObfuscators(server_connection_id);
- }
-
- ~StatelessConnectionTerminator() {
- // Clear framer's producer.
- framer_.set_data_producer(nullptr);
- }
-
- // Generates a packet containing a CONNECTION_CLOSE frame specifying
- // |error_code| and |error_details| and add the connection to time wait.
- void CloseConnection(QuicErrorCode error_code,
- const std::string& error_details,
- bool ietf_quic,
- std::vector<QuicConnectionId> active_connection_ids) {
- SerializeConnectionClosePacket(error_code, error_details);
-
- time_wait_list_manager_->AddConnectionIdToTimeWait(
- QuicTimeWaitListManager::SEND_TERMINATION_PACKETS,
- TimeWaitConnectionInfo(ietf_quic, collector_.packets(),
- std::move(active_connection_ids),
- /*srtt=*/QuicTime::Delta::Zero()));
- }
-
- private:
- void SerializeConnectionClosePacket(QuicErrorCode error_code,
- const std::string& error_details) {
- QuicConnectionCloseFrame* frame =
- new QuicConnectionCloseFrame(framer_.transport_version(), error_code,
- NO_IETF_QUIC_ERROR, error_details,
- /*transport_close_frame_type=*/0);
-
- if (!creator_.AddFrame(QuicFrame(frame), NOT_RETRANSMISSION)) {
- QUIC_BUG(quic_bug_10287_1) << "Unable to add frame to an empty packet";
- delete frame;
- return;
- }
- creator_.FlushCurrentPacket();
- QUICHE_DCHECK_EQ(1u, collector_.packets()->size());
- }
-
- QuicConnectionId server_connection_id_;
- QuicFramer framer_;
- // Set as the visitor of |creator_| to collect any generated packets.
- PacketCollector collector_;
- QuicPacketCreator creator_;
- QuicTimeWaitListManager* time_wait_list_manager_;
-};
-
-// Class which extracts the ALPN and SNI from a QUIC_CRYPTO CHLO packet.
-class ChloAlpnSniExtractor : public ChloExtractor::Delegate {
- public:
- void OnChlo(QuicTransportVersion version,
- QuicConnectionId /*server_connection_id*/,
- const CryptoHandshakeMessage& chlo) override {
- absl::string_view alpn_value;
- if (chlo.GetStringPiece(kALPN, &alpn_value)) {
- alpn_ = std::string(alpn_value);
- }
- absl::string_view sni;
- if (chlo.GetStringPiece(quic::kSNI, &sni)) {
- sni_ = std::string(sni);
- }
- absl::string_view uaid_value;
- if (chlo.GetStringPiece(quic::kUAID, &uaid_value)) {
- uaid_ = std::string(uaid_value);
- }
- if (version == LegacyVersionForEncapsulation().transport_version) {
- absl::string_view qlve_value;
- if (chlo.GetStringPiece(kQLVE, &qlve_value)) {
- legacy_version_encapsulation_inner_packet_ = std::string(qlve_value);
- }
- }
- }
-
- std::string&& ConsumeAlpn() { return std::move(alpn_); }
-
- std::string&& ConsumeSni() { return std::move(sni_); }
-
- std::string&& ConsumeUaid() { return std::move(uaid_); }
-
- std::string&& ConsumeLegacyVersionEncapsulationInnerPacket() {
- return std::move(legacy_version_encapsulation_inner_packet_);
- }
-
- private:
- std::string alpn_;
- std::string sni_;
- std::string uaid_;
- std::string legacy_version_encapsulation_inner_packet_;
-};
-
-bool MaybeHandleLegacyVersionEncapsulation(
- QuicDispatcher* dispatcher,
- std::string legacy_version_encapsulation_inner_packet,
- const ReceivedPacketInfo& packet_info) {
- if (legacy_version_encapsulation_inner_packet.empty()) {
- // This CHLO did not contain the Legacy Version Encapsulation tag.
- return false;
- }
- PacketHeaderFormat format;
- QuicLongHeaderType long_packet_type;
- bool version_present;
- bool has_length_prefix;
- QuicVersionLabel version_label;
- ParsedQuicVersion parsed_version = ParsedQuicVersion::Unsupported();
- QuicConnectionId destination_connection_id, source_connection_id;
- absl::optional<absl::string_view> retry_token;
- std::string detailed_error;
- const QuicErrorCode error = QuicFramer::ParsePublicHeaderDispatcher(
- QuicEncryptedPacket(legacy_version_encapsulation_inner_packet.data(),
- legacy_version_encapsulation_inner_packet.length()),
- kQuicDefaultConnectionIdLength, &format, &long_packet_type,
- &version_present, &has_length_prefix, &version_label, &parsed_version,
- &destination_connection_id, &source_connection_id, &retry_token,
- &detailed_error);
- if (error != QUIC_NO_ERROR) {
- QUIC_DLOG(ERROR)
- << "Failed to parse Legacy Version Encapsulation inner packet:"
- << detailed_error;
- return false;
- }
- if (destination_connection_id != packet_info.destination_connection_id) {
- // We enforce that the inner and outer connection IDs match to make sure
- // this never impacts routing of packets.
- QUIC_DLOG(ERROR) << "Ignoring Legacy Version Encapsulation packet "
- "with mismatched connection ID "
- << destination_connection_id << " vs "
- << packet_info.destination_connection_id;
- return false;
- }
- if (legacy_version_encapsulation_inner_packet.length() >=
- packet_info.packet.length()) {
- QUIC_BUG(quic_bug_10287_2)
- << "Inner packet cannot be larger than outer "
- << legacy_version_encapsulation_inner_packet.length() << " vs "
- << packet_info.packet.length();
- return false;
- }
-
- QUIC_DVLOG(1) << "Extracted a Legacy Version Encapsulation "
- << legacy_version_encapsulation_inner_packet.length()
- << " byte packet of version " << parsed_version;
-
- // Append zeroes to the end of the packet. This will ensure that
- // we use the right number of bytes for calculating anti-amplification
- // limits. Note that this only works for long headers of versions that carry
- // long header lengths, since they'll ignore any trailing zeroes. We still
- // do this for all packets to ensure version negotiation works.
- legacy_version_encapsulation_inner_packet.append(
- packet_info.packet.length() -
- legacy_version_encapsulation_inner_packet.length(),
- 0x00);
-
- // Process the inner packet as if it had been received by itself.
- QuicReceivedPacket received_encapsulated_packet(
- legacy_version_encapsulation_inner_packet.data(),
- legacy_version_encapsulation_inner_packet.length(),
- packet_info.packet.receipt_time());
- dispatcher->ProcessPacket(packet_info.self_address, packet_info.peer_address,
- received_encapsulated_packet);
- QUIC_CODE_COUNT(quic_legacy_version_encapsulation_decapsulated);
- return true;
-}
-
-} // namespace
-
-QuicDispatcher::QuicDispatcher(
- 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)
- : config_(config),
- crypto_config_(crypto_config),
- compressed_certs_cache_(
- QuicCompressedCertsCache::kQuicCompressedCertsCacheSize),
- helper_(std::move(helper)),
- session_helper_(std::move(session_helper)),
- alarm_factory_(std::move(alarm_factory)),
- delete_sessions_alarm_(
- alarm_factory_->CreateAlarm(new DeleteSessionsAlarm(this))),
- buffered_packets_(this, helper_->GetClock(), alarm_factory_.get()),
- version_manager_(version_manager),
- last_error_(QUIC_NO_ERROR),
- new_sessions_allowed_per_event_loop_(0u),
- accept_new_connections_(true),
- allow_short_initial_server_connection_ids_(false),
- expected_server_connection_id_length_(
- expected_server_connection_id_length),
- clear_stateless_reset_addresses_alarm_(alarm_factory_->CreateAlarm(
- new ClearStatelessResetAddressesAlarm(this))),
- should_update_expected_server_connection_id_length_(false) {
- QUIC_BUG_IF(quic_bug_12724_1, GetSupportedVersions().empty())
- << "Trying to create dispatcher without any supported versions";
- QUIC_DLOG(INFO) << "Created QuicDispatcher with versions: "
- << ParsedQuicVersionVectorToString(GetSupportedVersions());
-}
-
-QuicDispatcher::~QuicDispatcher() {
- if (delete_sessions_alarm_ != nullptr) {
- delete_sessions_alarm_->PermanentCancel();
- }
- if (clear_stateless_reset_addresses_alarm_ != nullptr) {
- clear_stateless_reset_addresses_alarm_->PermanentCancel();
- }
- reference_counted_session_map_.clear();
- closed_session_list_.clear();
- num_sessions_in_session_map_ = 0;
-}
-
-void QuicDispatcher::InitializeWithWriter(QuicPacketWriter* writer) {
- QUICHE_DCHECK(writer_ == nullptr);
- writer_.reset(writer);
- time_wait_list_manager_.reset(CreateQuicTimeWaitListManager());
-}
-
-void QuicDispatcher::ProcessPacket(const QuicSocketAddress& self_address,
- const QuicSocketAddress& peer_address,
- const QuicReceivedPacket& packet) {
- QUIC_DVLOG(2) << "Dispatcher received encrypted " << packet.length()
- << " bytes:" << std::endl
- << quiche::QuicheTextUtils::HexDump(
- absl::string_view(packet.data(), packet.length()));
- ReceivedPacketInfo packet_info(self_address, peer_address, packet);
- std::string detailed_error;
- const QuicErrorCode error = QuicFramer::ParsePublicHeaderDispatcher(
- packet, expected_server_connection_id_length_, &packet_info.form,
- &packet_info.long_packet_type, &packet_info.version_flag,
- &packet_info.use_length_prefix, &packet_info.version_label,
- &packet_info.version, &packet_info.destination_connection_id,
- &packet_info.source_connection_id, &packet_info.retry_token,
- &detailed_error);
- if (error != QUIC_NO_ERROR) {
- // Packet has framing error.
- SetLastError(error);
- QUIC_DLOG(ERROR) << detailed_error;
- return;
- }
- if (packet_info.destination_connection_id.length() !=
- expected_server_connection_id_length_ &&
- !should_update_expected_server_connection_id_length_ &&
- packet_info.version.IsKnown() &&
- !packet_info.version.AllowsVariableLengthConnectionIds()) {
- SetLastError(QUIC_INVALID_PACKET_HEADER);
- QUIC_DLOG(ERROR) << "Invalid Connection Id Length";
- return;
- }
-
- if (packet_info.version_flag && IsSupportedVersion(packet_info.version)) {
- if (!QuicUtils::IsConnectionIdValidForVersion(
- packet_info.destination_connection_id,
- packet_info.version.transport_version)) {
- SetLastError(QUIC_INVALID_PACKET_HEADER);
- QUIC_DLOG(ERROR)
- << "Invalid destination connection ID length for version";
- return;
- }
- if (packet_info.version.SupportsClientConnectionIds() &&
- !QuicUtils::IsConnectionIdValidForVersion(
- packet_info.source_connection_id,
- packet_info.version.transport_version)) {
- SetLastError(QUIC_INVALID_PACKET_HEADER);
- QUIC_DLOG(ERROR) << "Invalid source connection ID length for version";
- return;
- }
- }
-
- if (should_update_expected_server_connection_id_length_) {
- expected_server_connection_id_length_ =
- packet_info.destination_connection_id.length();
- }
-
- if (MaybeDispatchPacket(packet_info)) {
- // Packet has been dropped or successfully dispatched, stop processing.
- return;
- }
- ProcessHeader(&packet_info);
-}
-
-QuicConnectionId QuicDispatcher::MaybeReplaceServerConnectionId(
- const QuicConnectionId& server_connection_id,
- const ParsedQuicVersion& version) const {
- const uint8_t server_connection_id_length = server_connection_id.length();
- if (server_connection_id_length == expected_server_connection_id_length_) {
- return server_connection_id;
- }
- QUICHE_DCHECK(version.AllowsVariableLengthConnectionIds());
- QuicConnectionId new_connection_id;
- if (server_connection_id_length < expected_server_connection_id_length_) {
- new_connection_id = ReplaceShortServerConnectionId(
- version, server_connection_id, expected_server_connection_id_length_);
- // Verify that ReplaceShortServerConnectionId is deterministic.
- QUICHE_DCHECK_EQ(
- new_connection_id,
- ReplaceShortServerConnectionId(version, server_connection_id,
- expected_server_connection_id_length_));
- } else {
- new_connection_id = ReplaceLongServerConnectionId(
- version, server_connection_id, expected_server_connection_id_length_);
- // Verify that ReplaceLongServerConnectionId is deterministic.
- QUICHE_DCHECK_EQ(
- new_connection_id,
- ReplaceLongServerConnectionId(version, server_connection_id,
- expected_server_connection_id_length_));
- }
- QUICHE_DCHECK_EQ(expected_server_connection_id_length_,
- new_connection_id.length());
-
- QUIC_DLOG(INFO) << "Replacing incoming connection ID " << server_connection_id
- << " with " << new_connection_id;
- return new_connection_id;
-}
-
-QuicConnectionId QuicDispatcher::ReplaceShortServerConnectionId(
- const ParsedQuicVersion& /*version*/,
- const QuicConnectionId& server_connection_id,
- uint8_t expected_server_connection_id_length) const {
- QUICHE_DCHECK_LT(server_connection_id.length(),
- expected_server_connection_id_length);
- return QuicUtils::CreateReplacementConnectionId(
- server_connection_id, expected_server_connection_id_length);
-}
-
-QuicConnectionId QuicDispatcher::ReplaceLongServerConnectionId(
- const ParsedQuicVersion& /*version*/,
- const QuicConnectionId& server_connection_id,
- uint8_t expected_server_connection_id_length) const {
- QUICHE_DCHECK_GT(server_connection_id.length(),
- expected_server_connection_id_length);
- return QuicUtils::CreateReplacementConnectionId(
- server_connection_id, expected_server_connection_id_length);
-}
-
-namespace {
-constexpr bool IsSourceUdpPortBlocked(uint16_t port) {
- // These UDP source ports have been observed in large scale denial of service
- // attacks and are not expected to ever carry user traffic, they are therefore
- // blocked as a safety measure. See draft-ietf-quic-applicability for details.
- constexpr uint16_t blocked_ports[] = {
- 0, // We cannot send to port 0 so drop that source port.
- 17, // Quote of the Day, can loop with QUIC.
- 19, // Chargen, can loop with QUIC.
- 53, // DNS, vulnerable to reflection attacks.
- 111, // Portmap.
- 123, // NTP, vulnerable to reflection attacks.
- 137, // NETBIOS Name Service,
- 128, // NETBIOS Datagram Service
- 161, // SNMP.
- 389, // CLDAP.
- 500, // IKE, can loop with QUIC.
- 1900, // SSDP, vulnerable to reflection attacks.
- 5353, // mDNS, 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)) {
- // Early-return to skip comparisons for the majority of traffic.
- return false;
- }
- for (size_t i = 0; i < num_blocked_ports; i++) {
- if (port == blocked_ports[i]) {
- return true;
- }
- }
- return false;
-}
-} // namespace
-
-bool QuicDispatcher::MaybeDispatchPacket(
- const ReceivedPacketInfo& packet_info) {
- if (IsSourceUdpPortBlocked(packet_info.peer_address.port())) {
- // Silently drop the received packet.
- QUIC_CODE_COUNT(quic_dropped_blocked_port);
- return true;
- }
-
- QuicConnectionId server_connection_id = packet_info.destination_connection_id;
-
- // The IETF spec requires the client to generate an initial server
- // connection ID that is at least 64 bits long. After that initial
- // connection ID, the dispatcher picks a new one of its expected length.
- // Therefore we should never receive a connection ID that is smaller
- // than 64 bits and smaller than what we expect. Unless the version is
- // unknown, in which case we allow short connection IDs for version
- // negotiation because that version could allow those.
- if (packet_info.version_flag && packet_info.version.IsKnown() &&
- server_connection_id.length() < kQuicMinimumInitialConnectionIdLength &&
- server_connection_id.length() < expected_server_connection_id_length_ &&
- !allow_short_initial_server_connection_ids_) {
- QUICHE_DCHECK(packet_info.version_flag);
- QUICHE_DCHECK(packet_info.version.AllowsVariableLengthConnectionIds());
- QUIC_DLOG(INFO) << "Packet with short destination connection ID "
- << server_connection_id << " expected "
- << static_cast<int>(expected_server_connection_id_length_);
- // Drop the packet silently.
- QUIC_CODE_COUNT(quic_dropped_invalid_small_initial_connection_id);
- return true;
- }
-
- if (packet_info.version_flag && packet_info.version.IsKnown() &&
- !QuicUtils::IsConnectionIdLengthValidForVersion(
- server_connection_id.length(),
- packet_info.version.transport_version)) {
- QUIC_DLOG(INFO) << "Packet with destination connection ID "
- << server_connection_id << " is invalid with version "
- << packet_info.version;
- // Drop the packet silently.
- QUIC_CODE_COUNT(quic_dropped_invalid_initial_connection_id);
- return true;
- }
-
- // Packets with connection IDs for active connections are processed
- // immediately.
- auto it = reference_counted_session_map_.find(server_connection_id);
- if (it != reference_counted_session_map_.end()) {
- QUICHE_DCHECK(!buffered_packets_.HasBufferedPackets(server_connection_id));
- if (packet_info.version_flag &&
- packet_info.version != it->second->version() &&
- packet_info.version == LegacyVersionForEncapsulation()) {
- // This packet is using the Legacy Version Encapsulation version but the
- // corresponding session isn't, attempt extraction of inner packet.
- ChloAlpnSniExtractor alpn_extractor;
- if (ChloExtractor::Extract(packet_info.packet, packet_info.version,
- config_->create_session_tag_indicators(),
- &alpn_extractor,
- server_connection_id.length())) {
- if (MaybeHandleLegacyVersionEncapsulation(
- this,
- alpn_extractor.ConsumeLegacyVersionEncapsulationInnerPacket(),
- packet_info)) {
- return true;
- }
- }
- }
- it->second->ProcessUdpPacket(packet_info.self_address,
- packet_info.peer_address, packet_info.packet);
- return true;
- }
- if (packet_info.version.IsKnown()) {
- // We did not find the connection ID, check if we've replaced it.
- // This is only performed for supported versions because packets with
- // unsupported versions can flow through this function in order to send
- // a version negotiation packet, but we know that their connection ID
- // did not get replaced since that is performed on connection creation,
- // and that only happens for known verions.
- QuicConnectionId replaced_connection_id = MaybeReplaceServerConnectionId(
- server_connection_id, packet_info.version);
- if (replaced_connection_id != server_connection_id) {
- // Search for the replacement.
- auto it2 = reference_counted_session_map_.find(replaced_connection_id);
- if (it2 != reference_counted_session_map_.end()) {
- QUICHE_DCHECK(
- !buffered_packets_.HasBufferedPackets(replaced_connection_id));
- it2->second->ProcessUdpPacket(packet_info.self_address,
- packet_info.peer_address,
- packet_info.packet);
- return true;
- }
- }
- }
-
- if (buffered_packets_.HasChloForConnection(server_connection_id)) {
- BufferEarlyPacket(packet_info);
- return true;
- }
-
- if (OnFailedToDispatchPacket(packet_info)) {
- return true;
- }
-
- if (time_wait_list_manager_->IsConnectionIdInTimeWait(server_connection_id)) {
- // This connection ID is already in time-wait state.
- time_wait_list_manager_->ProcessPacket(
- packet_info.self_address, packet_info.peer_address,
- packet_info.destination_connection_id, packet_info.form,
- packet_info.packet.length(), GetPerPacketContext());
- return true;
- }
-
- // The packet has an unknown connection ID.
- if (!accept_new_connections_ && packet_info.version_flag) {
- // If not accepting new connections, reject packets with version which can
- // potentially result in new connection creation. But if the packet doesn't
- // have version flag, leave it to ValidityChecks() to reset it.
- // By adding the connection to time wait list, following packets on this
- // connection will not reach ShouldAcceptNewConnections().
- StatelesslyTerminateConnection(
- packet_info.destination_connection_id, packet_info.form,
- packet_info.version_flag, packet_info.use_length_prefix,
- packet_info.version, QUIC_HANDSHAKE_FAILED,
- "Stop accepting new connections",
- quic::QuicTimeWaitListManager::SEND_STATELESS_RESET);
- // Time wait list will reject the packet correspondingly..
- time_wait_list_manager()->ProcessPacket(
- packet_info.self_address, packet_info.peer_address,
- packet_info.destination_connection_id, packet_info.form,
- packet_info.packet.length(), GetPerPacketContext());
- OnNewConnectionRejected();
- return true;
- }
-
- // Unless the packet provides a version, assume that we can continue
- // processing using our preferred version.
- if (packet_info.version_flag) {
- if (!IsSupportedVersion(packet_info.version)) {
- if (ShouldCreateSessionForUnknownVersion(packet_info.version_label)) {
- return false;
- }
- if (!crypto_config()->validate_chlo_size() ||
- packet_info.packet.length() >= kMinPacketSizeForVersionNegotiation) {
- // Since the version is not supported, send a version negotiation
- // packet and stop processing the current packet.
- QuicConnectionId client_connection_id =
- packet_info.source_connection_id;
- time_wait_list_manager()->SendVersionNegotiationPacket(
- server_connection_id, client_connection_id,
- packet_info.form != GOOGLE_QUIC_PACKET,
- packet_info.use_length_prefix, GetSupportedVersions(),
- packet_info.self_address, packet_info.peer_address,
- GetPerPacketContext());
- }
- return true;
- }
-
- if (crypto_config()->validate_chlo_size() &&
- packet_info.form == IETF_QUIC_LONG_HEADER_PACKET &&
- packet_info.long_packet_type == INITIAL &&
- packet_info.packet.length() < kMinClientInitialPacketLength) {
- QUIC_DVLOG(1) << "Dropping initial packet which is too short, length: "
- << packet_info.packet.length();
- QUIC_CODE_COUNT(quic_drop_small_initial_packets);
- return true;
- }
- }
-
- return false;
-}
-
-void QuicDispatcher::ProcessHeader(ReceivedPacketInfo* packet_info) {
- QuicConnectionId server_connection_id =
- packet_info->destination_connection_id;
- // Packet's connection ID is unknown. Apply the validity checks.
- QuicPacketFate fate = ValidityChecks(*packet_info);
-
- if (fate == kFateProcess) {
- absl::optional<ParsedClientHello> parsed_chlo =
- TryExtractChloOrBufferEarlyPacket(*packet_info);
- if (!parsed_chlo.has_value()) {
- // Client Hello incomplete. Packet has been buffered or (rarely) dropped.
- return;
- }
-
- // Client Hello fully received.
- fate = ValidityChecksOnFullChlo(*packet_info, *parsed_chlo);
-
- if (fate == kFateProcess) {
- QUICHE_DCHECK(
- parsed_chlo->legacy_version_encapsulation_inner_packet.empty() ||
- !packet_info->version.UsesTls());
- if (MaybeHandleLegacyVersionEncapsulation(
- this, parsed_chlo->legacy_version_encapsulation_inner_packet,
- *packet_info)) {
- return;
- }
-
- ProcessChlo(*std::move(parsed_chlo), packet_info);
- return;
- }
- }
-
- switch (fate) {
- case kFateProcess:
- // kFateProcess have been processed above.
- QUIC_BUG(quic_dispatcher_bad_packet_fate) << fate;
- break;
- case kFateTimeWait:
- // Add this connection_id to the time-wait state, to safely reject
- // future packets.
- QUIC_DLOG(INFO) << "Adding connection ID " << server_connection_id
- << " to time-wait list.";
- QUIC_CODE_COUNT(quic_reject_fate_time_wait);
- StatelesslyTerminateConnection(
- server_connection_id, packet_info->form, packet_info->version_flag,
- packet_info->use_length_prefix, packet_info->version,
- QUIC_HANDSHAKE_FAILED, "Reject connection",
- quic::QuicTimeWaitListManager::SEND_STATELESS_RESET);
-
- QUICHE_DCHECK(time_wait_list_manager_->IsConnectionIdInTimeWait(
- server_connection_id));
- time_wait_list_manager_->ProcessPacket(
- packet_info->self_address, packet_info->peer_address,
- server_connection_id, packet_info->form, packet_info->packet.length(),
- GetPerPacketContext());
-
- buffered_packets_.DiscardPackets(server_connection_id);
- break;
- case kFateDrop:
- break;
- }
-}
-
-absl::optional<ParsedClientHello>
-QuicDispatcher::TryExtractChloOrBufferEarlyPacket(
- const ReceivedPacketInfo& packet_info) {
- if (packet_info.version.UsesTls()) {
- bool has_full_tls_chlo = false;
- std::string sni;
- std::vector<std::string> alpns;
- bool resumption_attempted = false, early_data_attempted = false;
- if (buffered_packets_.HasBufferedPackets(
- packet_info.destination_connection_id)) {
- // If we already have buffered packets for this connection ID,
- // use the associated TlsChloExtractor to parse this packet.
- has_full_tls_chlo = buffered_packets_.IngestPacketForTlsChloExtraction(
- packet_info.destination_connection_id, packet_info.version,
- packet_info.packet, &alpns, &sni, &resumption_attempted,
- &early_data_attempted);
- } else {
- // If we do not have a BufferedPacketList for this connection ID,
- // create a single-use one to check whether this packet contains a
- // full single-packet CHLO.
- TlsChloExtractor tls_chlo_extractor;
- tls_chlo_extractor.IngestPacket(packet_info.version, packet_info.packet);
- if (tls_chlo_extractor.HasParsedFullChlo()) {
- // This packet contains a full single-packet CHLO.
- has_full_tls_chlo = true;
- alpns = tls_chlo_extractor.alpns();
- sni = tls_chlo_extractor.server_name();
- resumption_attempted = tls_chlo_extractor.resumption_attempted();
- early_data_attempted = tls_chlo_extractor.early_data_attempted();
- }
- }
- if (!has_full_tls_chlo) {
- // This packet does not contain a full CHLO. It could be a 0-RTT
- // packet that arrived before the CHLO (due to loss or reordering),
- // or it could be a fragment of a multi-packet CHLO.
- BufferEarlyPacket(packet_info);
- return absl::nullopt;
- }
-
- ParsedClientHello parsed_chlo;
- parsed_chlo.sni = std::move(sni);
- parsed_chlo.alpns = std::move(alpns);
- if (packet_info.retry_token.has_value()) {
- parsed_chlo.retry_token = std::string(*packet_info.retry_token);
- }
- parsed_chlo.resumption_attempted = resumption_attempted;
- parsed_chlo.early_data_attempted = early_data_attempted;
- return parsed_chlo;
- }
-
- ChloAlpnSniExtractor alpn_extractor;
- if (GetQuicFlag(FLAGS_quic_allow_chlo_buffering) &&
- !ChloExtractor::Extract(packet_info.packet, packet_info.version,
- config_->create_session_tag_indicators(),
- &alpn_extractor,
- packet_info.destination_connection_id.length())) {
- // Buffer non-CHLO packets.
- BufferEarlyPacket(packet_info);
- return absl::nullopt;
- }
-
- // We only apply this check for versions that do not use the IETF
- // invariant header because those versions are already checked in
- // QuicDispatcher::MaybeDispatchPacket.
- if (packet_info.version_flag &&
- !packet_info.version.HasIetfInvariantHeader() &&
- crypto_config()->validate_chlo_size() &&
- packet_info.packet.length() < kMinClientInitialPacketLength) {
- QUIC_DVLOG(1) << "Dropping CHLO packet which is too short, length: "
- << packet_info.packet.length();
- QUIC_CODE_COUNT(quic_drop_small_chlo_packets);
- return absl::nullopt;
- }
-
- ParsedClientHello parsed_chlo;
- parsed_chlo.legacy_version_encapsulation_inner_packet =
- alpn_extractor.ConsumeLegacyVersionEncapsulationInnerPacket();
- parsed_chlo.sni = alpn_extractor.ConsumeSni();
- parsed_chlo.uaid = alpn_extractor.ConsumeUaid();
- parsed_chlo.alpns = {alpn_extractor.ConsumeAlpn()};
- return parsed_chlo;
-}
-
-std::string QuicDispatcher::SelectAlpn(const std::vector<std::string>& alpns) {
- if (alpns.empty()) {
- return "";
- }
- if (alpns.size() > 1u) {
- const std::vector<std::string>& supported_alpns =
- version_manager_->GetSupportedAlpns();
- for (const std::string& alpn : alpns) {
- if (std::find(supported_alpns.begin(), supported_alpns.end(), alpn) !=
- supported_alpns.end()) {
- return alpn;
- }
- }
- }
- return alpns[0];
-}
-
-QuicDispatcher::QuicPacketFate QuicDispatcher::ValidityChecks(
- const ReceivedPacketInfo& packet_info) {
- if (!packet_info.version_flag) {
- QUIC_DLOG(INFO)
- << "Packet without version arrived for unknown connection ID "
- << packet_info.destination_connection_id;
- MaybeResetPacketsWithNoVersion(packet_info);
- return kFateDrop;
- }
-
- // Let the connection parse and validate packet number.
- return kFateProcess;
-}
-
-void QuicDispatcher::CleanUpSession(QuicConnectionId server_connection_id,
- QuicConnection* connection,
- QuicErrorCode /*error*/,
- const std::string& /*error_details*/,
- ConnectionCloseSource /*source*/) {
- write_blocked_list_.erase(connection);
- QuicTimeWaitListManager::TimeWaitAction action =
- QuicTimeWaitListManager::SEND_STATELESS_RESET;
- if (connection->termination_packets() != nullptr &&
- !connection->termination_packets()->empty()) {
- action = QuicTimeWaitListManager::SEND_CONNECTION_CLOSE_PACKETS;
- } else {
- if (!connection->IsHandshakeComplete()) {
- // TODO(fayang): Do not serialize connection close packet if the
- // connection is closed by the client.
- if (!connection->version().HasIetfInvariantHeader()) {
- QUIC_CODE_COUNT(gquic_add_to_time_wait_list_with_handshake_failed);
- } else {
- QUIC_CODE_COUNT(quic_v44_add_to_time_wait_list_with_handshake_failed);
- }
- // 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());
- terminator.CloseConnection(
- QUIC_HANDSHAKE_FAILED,
- "Connection is closed by server before handshake confirmed",
- connection->version().HasIetfInvariantHeader(),
- connection->GetActiveServerConnectionIds());
- return;
- }
- QUIC_CODE_COUNT(quic_v44_add_to_time_wait_list_with_stateless_reset);
- }
- time_wait_list_manager_->AddConnectionIdToTimeWait(
- action,
- TimeWaitConnectionInfo(
- connection->version().HasIetfInvariantHeader(),
- connection->termination_packets(),
- connection->GetActiveServerConnectionIds(),
- connection->sent_packet_manager().GetRttStats()->smoothed_rtt()));
-}
-
-void QuicDispatcher::StartAcceptingNewConnections() {
- accept_new_connections_ = true;
-}
-
-void QuicDispatcher::StopAcceptingNewConnections() {
- accept_new_connections_ = false;
- // No more CHLO will arrive and buffered CHLOs shouldn't be able to create
- // connections.
- buffered_packets_.DiscardAllPackets();
-}
-
-void QuicDispatcher::PerformActionOnActiveSessions(
- std::function<void(QuicSession*)> operation) const {
- absl::flat_hash_set<QuicSession*> visited_session;
- visited_session.reserve(reference_counted_session_map_.size());
- for (auto const& kv : reference_counted_session_map_) {
- QuicSession* session = kv.second.get();
- if (visited_session.insert(session).second) {
- operation(session);
- }
- }
-}
-
-// Get a snapshot of all sessions.
-std::vector<std::shared_ptr<QuicSession>> QuicDispatcher::GetSessionsSnapshot()
- const {
- std::vector<std::shared_ptr<QuicSession>> snapshot;
- snapshot.reserve(reference_counted_session_map_.size());
- absl::flat_hash_set<QuicSession*> visited_session;
- visited_session.reserve(reference_counted_session_map_.size());
- for (auto const& kv : reference_counted_session_map_) {
- QuicSession* session = kv.second.get();
- if (visited_session.insert(session).second) {
- snapshot.push_back(kv.second);
- }
- }
- return snapshot;
-}
-
-std::unique_ptr<QuicPerPacketContext> QuicDispatcher::GetPerPacketContext()
- const {
- return nullptr;
-}
-
-void QuicDispatcher::DeleteSessions() {
- if (!write_blocked_list_.empty()) {
- for (const auto& session : closed_session_list_) {
- if (write_blocked_list_.erase(session->connection()) != 0) {
- QUIC_BUG(quic_bug_12724_2)
- << "QuicConnection was in WriteBlockedList before destruction "
- << session->connection()->connection_id();
- }
- }
- }
- closed_session_list_.clear();
-}
-
-void QuicDispatcher::ClearStatelessResetAddresses() {
- recent_stateless_reset_addresses_.clear();
-}
-
-void QuicDispatcher::OnCanWrite() {
- // The socket is now writable.
- writer_->SetWritable();
-
- // Move every blocked writer in |write_blocked_list_| to a temporary list.
- const size_t num_blocked_writers_before = write_blocked_list_.size();
- WriteBlockedList temp_list;
- temp_list.swap(write_blocked_list_);
- QUICHE_DCHECK(write_blocked_list_.empty());
-
- // Give each blocked writer a chance to write what they indended to write.
- // If they are blocked again, they will call |OnWriteBlocked| to add
- // themselves back into |write_blocked_list_|.
- while (!temp_list.empty()) {
- QuicBlockedWriterInterface* blocked_writer = temp_list.begin()->first;
- temp_list.erase(temp_list.begin());
- blocked_writer->OnBlockedWriterCanWrite();
- }
- const size_t num_blocked_writers_after = write_blocked_list_.size();
- if (num_blocked_writers_after != 0) {
- if (num_blocked_writers_before == num_blocked_writers_after) {
- QUIC_CODE_COUNT(quic_zero_progress_on_can_write);
- } else {
- QUIC_CODE_COUNT(quic_blocked_again_on_can_write);
- }
- }
-}
-
-bool QuicDispatcher::HasPendingWrites() const {
- return !write_blocked_list_.empty();
-}
-
-void QuicDispatcher::Shutdown() {
- while (!reference_counted_session_map_.empty()) {
- QuicSession* session = reference_counted_session_map_.begin()->second.get();
- session->connection()->CloseConnection(
- QUIC_PEER_GOING_AWAY, "Server shutdown imminent",
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
- // Validate that the session removes itself from the session map on close.
- QUICHE_DCHECK(reference_counted_session_map_.empty() ||
- reference_counted_session_map_.begin()->second.get() !=
- session);
- }
- DeleteSessions();
-}
-
-void QuicDispatcher::OnConnectionClosed(QuicConnectionId server_connection_id,
- QuicErrorCode error,
- const std::string& error_details,
- ConnectionCloseSource source) {
- auto it = reference_counted_session_map_.find(server_connection_id);
- if (it == reference_counted_session_map_.end()) {
- QUIC_BUG(quic_bug_10287_3) << "ConnectionId " << server_connection_id
- << " does not exist in the session map. Error: "
- << QuicErrorCodeToString(error);
- QUIC_BUG(quic_bug_10287_4) << QuicStackTrace();
- return;
- }
-
- QUIC_DLOG_IF(INFO, error != QUIC_NO_ERROR)
- << "Closing connection (" << server_connection_id
- << ") due to error: " << QuicErrorCodeToString(error)
- << ", with details: " << error_details;
-
- QuicConnection* connection = it->second->connection();
- if (ShouldDestroySessionAsynchronously()) {
- // Set up alarm to fire immediately to bring destruction of this session
- // out of current call stack.
- if (closed_session_list_.empty()) {
- delete_sessions_alarm_->Update(helper()->GetClock()->ApproximateNow(),
- QuicTime::Delta::Zero());
- }
- closed_session_list_.push_back(std::move(it->second));
- }
- CleanUpSession(it->first, connection, error, error_details, source);
- for (const QuicConnectionId& cid :
- connection->GetActiveServerConnectionIds()) {
- reference_counted_session_map_.erase(cid);
- }
- --num_sessions_in_session_map_;
-}
-
-void QuicDispatcher::OnWriteBlocked(
- QuicBlockedWriterInterface* blocked_writer) {
- if (!blocked_writer->IsWriterBlocked()) {
- // It is a programming error if this ever happens. When we are sure it is
- // not happening, replace it with a QUICHE_DCHECK.
- QUIC_BUG(quic_bug_12724_4)
- << "Tried to add writer into blocked list when it shouldn't be added";
- // Return without adding the connection to the blocked list, to avoid
- // infinite loops in OnCanWrite.
- return;
- }
-
- write_blocked_list_.insert(std::make_pair(blocked_writer, true));
-}
-
-void QuicDispatcher::OnRstStreamReceived(const QuicRstStreamFrame& /*frame*/) {}
-
-void QuicDispatcher::OnStopSendingReceived(
- const QuicStopSendingFrame& /*frame*/) {}
-
-void QuicDispatcher::OnNewConnectionIdSent(
- const QuicConnectionId& server_connection_id,
- const QuicConnectionId& new_connection_id) {
- auto it = reference_counted_session_map_.find(server_connection_id);
- if (it == reference_counted_session_map_.end()) {
- QUIC_BUG(quic_bug_10287_7)
- << "Couldn't locate the session that issues the connection ID in "
- "reference_counted_session_map_. server_connection_id:"
- << server_connection_id << " new_connection_id: " << new_connection_id;
- return;
- }
- // Count new connection ID added to the dispatcher map.
- QUIC_RELOADABLE_FLAG_COUNT_N(quic_connection_migration_use_new_cid_v2, 6, 6);
- auto insertion_result = reference_counted_session_map_.insert(
- std::make_pair(new_connection_id, it->second));
- QUICHE_DCHECK(insertion_result.second);
-}
-
-void QuicDispatcher::OnConnectionIdRetired(
- const QuicConnectionId& server_connection_id) {
- reference_counted_session_map_.erase(server_connection_id);
-}
-
-void QuicDispatcher::OnConnectionAddedToTimeWaitList(
- QuicConnectionId server_connection_id) {
- QUIC_DLOG(INFO) << "Connection " << server_connection_id
- << " added to time wait list.";
-}
-
-void QuicDispatcher::StatelesslyTerminateConnection(
- QuicConnectionId server_connection_id,
- PacketHeaderFormat format,
- bool version_flag,
- bool use_length_prefix,
- ParsedQuicVersion version,
- QuicErrorCode error_code,
- const std::string& error_details,
- QuicTimeWaitListManager::TimeWaitAction action) {
- if (format != IETF_QUIC_LONG_HEADER_PACKET && !version_flag) {
- QUIC_DVLOG(1) << "Statelessly terminating " << server_connection_id
- << " based on a non-ietf-long packet, action:" << action
- << ", error_code:" << error_code
- << ", error_details:" << error_details;
- time_wait_list_manager_->AddConnectionIdToTimeWait(
- action, TimeWaitConnectionInfo(format != GOOGLE_QUIC_PACKET, nullptr,
- {server_connection_id}));
- return;
- }
-
- // If the version is known and supported by framer, send a connection close.
- if (IsSupportedVersion(version)) {
- QUIC_DVLOG(1)
- << "Statelessly terminating " << server_connection_id
- << " based on an ietf-long packet, which has a supported version:"
- << version << ", error_code:" << error_code
- << ", error_details:" << error_details;
-
- StatelessConnectionTerminator terminator(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,
- /*active_connection_ids=*/{server_connection_id});
- QUIC_CODE_COUNT(quic_dispatcher_generated_connection_close);
- QuicSession::RecordConnectionCloseAtServer(
- error_code, ConnectionCloseSource::FROM_SELF);
- return;
- }
-
- QUIC_DVLOG(1)
- << "Statelessly terminating " << server_connection_id
- << " based on an ietf-long packet, which has an unsupported version:"
- << version << ", error_code:" << error_code
- << ", error_details:" << error_details;
- // Version is unknown or unsupported by framer, send a version negotiation
- // with an empty version list, which can be understood by the client.
- std::vector<std::unique_ptr<QuicEncryptedPacket>> termination_packets;
- termination_packets.push_back(QuicFramer::BuildVersionNegotiationPacket(
- server_connection_id, EmptyQuicConnectionId(),
- /*ietf_quic=*/format != GOOGLE_QUIC_PACKET, use_length_prefix,
- /*versions=*/{}));
- time_wait_list_manager()->AddConnectionIdToTimeWait(
- QuicTimeWaitListManager::SEND_TERMINATION_PACKETS,
- TimeWaitConnectionInfo(/*ietf_quic=*/format != GOOGLE_QUIC_PACKET,
- &termination_packets, {server_connection_id}));
-}
-
-bool QuicDispatcher::ShouldCreateSessionForUnknownVersion(
- QuicVersionLabel /*version_label*/) {
- return false;
-}
-
-void QuicDispatcher::OnExpiredPackets(
- QuicConnectionId server_connection_id,
- BufferedPacketList early_arrived_packets) {
- QUIC_CODE_COUNT(quic_reject_buffered_packets_expired);
- StatelesslyTerminateConnection(
- server_connection_id,
- early_arrived_packets.ietf_quic ? IETF_QUIC_LONG_HEADER_PACKET
- : GOOGLE_QUIC_PACKET,
- /*version_flag=*/true,
- early_arrived_packets.version.HasLengthPrefixedConnectionIds(),
- early_arrived_packets.version, QUIC_HANDSHAKE_FAILED,
- "Packets buffered for too long",
- quic::QuicTimeWaitListManager::SEND_STATELESS_RESET);
-}
-
-void QuicDispatcher::ProcessBufferedChlos(size_t max_connections_to_create) {
- // Reset the counter before starting creating connections.
- new_sessions_allowed_per_event_loop_ = max_connections_to_create;
- for (; new_sessions_allowed_per_event_loop_ > 0;
- --new_sessions_allowed_per_event_loop_) {
- QuicConnectionId server_connection_id;
- BufferedPacketList packet_list =
- buffered_packets_.DeliverPacketsForNextConnection(
- &server_connection_id);
- const std::list<BufferedPacket>& packets = packet_list.buffered_packets;
- if (packets.empty()) {
- return;
- }
- if (!packet_list.parsed_chlo.has_value()) {
- QUIC_BUG(quic_dispatcher_no_parsed_chlo_in_buffered_packets)
- << "Buffered connection has no CHLO. connection_id:"
- << server_connection_id;
- continue;
- }
- const ParsedClientHello& parsed_chlo = *packet_list.parsed_chlo;
- QuicConnectionId original_connection_id = server_connection_id;
- server_connection_id = MaybeReplaceServerConnectionId(server_connection_id,
- packet_list.version);
- std::string alpn = SelectAlpn(parsed_chlo.alpns);
- std::unique_ptr<QuicSession> session = CreateQuicSession(
- server_connection_id, packets.front().self_address,
- packets.front().peer_address, alpn, packet_list.version, parsed_chlo);
- if (original_connection_id != server_connection_id) {
- session->connection()->SetOriginalDestinationConnectionId(
- original_connection_id);
- }
- QUIC_DLOG(INFO) << "Created new session for " << server_connection_id;
-
- auto insertion_result = reference_counted_session_map_.insert(
- std::make_pair(server_connection_id,
- std::shared_ptr<QuicSession>(std::move(session))));
- if (!insertion_result.second) {
- QUIC_BUG(quic_bug_12724_5)
- << "Tried to add a session to session_map with existing connection "
- "id: "
- << server_connection_id;
- } else {
- ++num_sessions_in_session_map_;
- }
- DeliverPacketsToSession(packets, insertion_result.first->second.get());
- }
-}
-
-bool QuicDispatcher::HasChlosBuffered() const {
- return buffered_packets_.HasChlosBuffered();
-}
-
-bool QuicDispatcher::ShouldCreateOrBufferPacketForConnection(
- const ReceivedPacketInfo& packet_info) {
- QUIC_VLOG(1) << "Received packet from new connection "
- << packet_info.destination_connection_id;
- return true;
-}
-
-// Return true if there is any packet buffered in the store.
-bool QuicDispatcher::HasBufferedPackets(QuicConnectionId server_connection_id) {
- return buffered_packets_.HasBufferedPackets(server_connection_id);
-}
-
-void QuicDispatcher::OnBufferPacketFailure(
- EnqueuePacketResult result,
- QuicConnectionId server_connection_id) {
- QUIC_DLOG(INFO) << "Fail to buffer packet on connection "
- << server_connection_id << " because of " << result;
-}
-
-QuicTimeWaitListManager* QuicDispatcher::CreateQuicTimeWaitListManager() {
- return new QuicTimeWaitListManager(writer_.get(), this, helper_->GetClock(),
- alarm_factory_.get());
-}
-
-void QuicDispatcher::BufferEarlyPacket(const ReceivedPacketInfo& packet_info) {
- bool is_new_connection = !buffered_packets_.HasBufferedPackets(
- packet_info.destination_connection_id);
- if (is_new_connection &&
- !ShouldCreateOrBufferPacketForConnection(packet_info)) {
- return;
- }
-
- EnqueuePacketResult rs = buffered_packets_.EnqueuePacket(
- packet_info.destination_connection_id,
- packet_info.form != GOOGLE_QUIC_PACKET, packet_info.packet,
- packet_info.self_address, packet_info.peer_address, packet_info.version,
- /*parsed_chlo=*/absl::nullopt);
- if (rs != EnqueuePacketResult::SUCCESS) {
- OnBufferPacketFailure(rs, packet_info.destination_connection_id);
- }
-}
-
-void QuicDispatcher::ProcessChlo(ParsedClientHello parsed_chlo,
- ReceivedPacketInfo* packet_info) {
- if (!buffered_packets_.HasBufferedPackets(
- packet_info->destination_connection_id) &&
- !ShouldCreateOrBufferPacketForConnection(*packet_info)) {
- return;
- }
- if (GetQuicFlag(FLAGS_quic_allow_chlo_buffering) &&
- new_sessions_allowed_per_event_loop_ <= 0) {
- // Can't create new session any more. Wait till next event loop.
- QUIC_BUG_IF(quic_bug_12724_7, buffered_packets_.HasChloForConnection(
- packet_info->destination_connection_id));
- EnqueuePacketResult rs = buffered_packets_.EnqueuePacket(
- packet_info->destination_connection_id,
- packet_info->form != GOOGLE_QUIC_PACKET, packet_info->packet,
- packet_info->self_address, packet_info->peer_address,
- packet_info->version, std::move(parsed_chlo));
- if (rs != EnqueuePacketResult::SUCCESS) {
- OnBufferPacketFailure(rs, packet_info->destination_connection_id);
- }
- return;
- }
-
- QuicConnectionId original_connection_id =
- packet_info->destination_connection_id;
- packet_info->destination_connection_id = MaybeReplaceServerConnectionId(
- original_connection_id, packet_info->version);
- // Creates a new session and process all buffered packets for this connection.
- std::string alpn = SelectAlpn(parsed_chlo.alpns);
- 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)) {
- QUIC_BUG(quic_bug_10287_8)
- << "CreateQuicSession returned nullptr for "
- << packet_info->destination_connection_id << " from "
- << packet_info->peer_address << " to " << packet_info->self_address
- << " ALPN \"" << alpn << "\" version " << packet_info->version;
- return;
- }
- if (original_connection_id != packet_info->destination_connection_id) {
- session->connection()->SetOriginalDestinationConnectionId(
- original_connection_id);
- }
- QUIC_DLOG(INFO) << "Created new session for "
- << packet_info->destination_connection_id;
-
- QuicSession* session_ptr;
- auto insertion_result = reference_counted_session_map_.insert(std::make_pair(
- packet_info->destination_connection_id,
- std::shared_ptr<QuicSession>(std::move(session.release()))));
- if (!insertion_result.second) {
- QUIC_BUG(quic_bug_10287_9)
- << "Tried to add a session to session_map with existing "
- "connection id: "
- << packet_info->destination_connection_id;
- } else {
- ++num_sessions_in_session_map_;
- }
- session_ptr = insertion_result.first->second.get();
- std::list<BufferedPacket> packets =
- buffered_packets_.DeliverPackets(packet_info->destination_connection_id)
- .buffered_packets;
- // Process CHLO at first.
- session_ptr->ProcessUdpPacket(packet_info->self_address,
- packet_info->peer_address, packet_info->packet);
- // Deliver queued-up packets in the same order as they arrived.
- // Do this even when flag is off because there might be still some packets
- // buffered in the store before flag is turned off.
- DeliverPacketsToSession(packets, session_ptr);
- --new_sessions_allowed_per_event_loop_;
-}
-
-bool QuicDispatcher::ShouldDestroySessionAsynchronously() {
- return true;
-}
-
-void QuicDispatcher::SetLastError(QuicErrorCode error) {
- last_error_ = error;
-}
-
-bool QuicDispatcher::OnFailedToDispatchPacket(
- const ReceivedPacketInfo& /*packet_info*/) {
- return false;
-}
-
-const ParsedQuicVersionVector& QuicDispatcher::GetSupportedVersions() {
- return version_manager_->GetSupportedVersions();
-}
-
-void QuicDispatcher::DeliverPacketsToSession(
- const std::list<BufferedPacket>& packets,
- QuicSession* session) {
- for (const BufferedPacket& packet : packets) {
- session->ProcessUdpPacket(packet.self_address, packet.peer_address,
- *(packet.packet));
- }
-}
-
-bool QuicDispatcher::IsSupportedVersion(const ParsedQuicVersion version) {
- for (const ParsedQuicVersion& supported_version :
- version_manager_->GetSupportedVersions()) {
- if (version == supported_version) {
- return true;
- }
- }
- return false;
-}
-
-void QuicDispatcher::MaybeResetPacketsWithNoVersion(
- const ReceivedPacketInfo& packet_info) {
- QUICHE_DCHECK(!packet_info.version_flag);
- // Do not send a stateless reset if a reset has been sent to this address
- // 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) {
- // Drop IETF packets smaller than the minimal stateless reset length.
- if (packet_info.packet.length() <=
- QuicFramer::GetMinStatelessResetPacketLength()) {
- QUIC_CODE_COUNT(quic_drop_too_small_short_header_packets);
- return;
- }
- } else {
- const size_t MinValidPacketLength =
- kPacketHeaderTypeSize + expected_server_connection_id_length_ +
- PACKET_1BYTE_PACKET_NUMBER + /*payload size=*/1 + /*tag size=*/12;
- if (packet_info.packet.length() < MinValidPacketLength) {
- // The packet size is too small.
- QUIC_CODE_COUNT(drop_too_small_packets);
- 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);
- }
-
- time_wait_list_manager()->SendPublicReset(
- packet_info.self_address, packet_info.peer_address,
- packet_info.destination_connection_id,
- packet_info.form != GOOGLE_QUIC_PACKET, packet_info.packet.length(),
- GetPerPacketContext());
-}
-
-size_t QuicDispatcher::NumSessions() const {
- return num_sessions_in_session_map_;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_dispatcher.h b/chromium/net/third_party/quiche/src/quic/core/quic_dispatcher.h
deleted file mode 100644
index f22d58aa4c9..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_dispatcher.h
+++ /dev/null
@@ -1,484 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// A server side dispatcher which dispatches a given client's data to their
-// stream.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_DISPATCHER_H_
-#define QUICHE_QUIC_CORE_QUIC_DISPATCHER_H_
-
-#include <cstddef>
-#include <memory>
-#include <string>
-#include <vector>
-
-#include "absl/container/flat_hash_map.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/crypto/quic_compressed_certs_cache.h"
-#include "quic/core/crypto/quic_random.h"
-#include "quic/core/quic_blocked_writer_interface.h"
-#include "quic/core/quic_buffered_packet_store.h"
-#include "quic/core/quic_connection.h"
-#include "quic/core/quic_connection_id.h"
-#include "quic/core/quic_crypto_server_stream_base.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_process_packet_interface.h"
-#include "quic/core/quic_session.h"
-#include "quic/core/quic_time_wait_list_manager.h"
-#include "quic/core/quic_version_manager.h"
-#include "quic/platform/api/quic_reference_counted.h"
-#include "quic/platform/api/quic_socket_address.h"
-#include "common/quiche_linked_hash_map.h"
-
-namespace quic {
-namespace test {
-class QuicDispatcherPeer;
-} // namespace test
-
-class QuicConfig;
-class QuicCryptoServerConfig;
-
-class QUIC_NO_EXPORT QuicDispatcher
- : public QuicTimeWaitListManager::Visitor,
- public ProcessPacketInterface,
- public QuicBufferedPacketStore::VisitorInterface {
- public:
- // Ideally we'd have a linked_hash_set: the boolean is unused.
- using WriteBlockedList =
- quiche::QuicheLinkedHashMap<QuicBlockedWriterInterface*, bool>;
-
- QuicDispatcher(
- 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);
- QuicDispatcher(const QuicDispatcher&) = delete;
- QuicDispatcher& operator=(const QuicDispatcher&) = delete;
-
- ~QuicDispatcher() override;
-
- // Takes ownership of |writer|.
- void InitializeWithWriter(QuicPacketWriter* writer);
-
- // Process the incoming packet by creating a new session, passing it to
- // an existing session, or passing it to the time wait list.
- void ProcessPacket(const QuicSocketAddress& self_address,
- const QuicSocketAddress& peer_address,
- const QuicReceivedPacket& packet) override;
-
- // Called when the socket becomes writable to allow queued writes to happen.
- virtual void OnCanWrite();
-
- // Returns true if there's anything in the blocked writer list.
- virtual bool HasPendingWrites() const;
-
- // Sends ConnectionClose frames to all connected clients.
- void Shutdown();
-
- // QuicSession::Visitor interface implementation (via inheritance of
- // QuicTimeWaitListManager::Visitor):
- // Ensure that the closed connection is cleaned up asynchronously.
- void OnConnectionClosed(QuicConnectionId server_connection_id,
- QuicErrorCode error,
- const std::string& error_details,
- ConnectionCloseSource source) override;
-
- // QuicSession::Visitor interface implementation (via inheritance of
- // QuicTimeWaitListManager::Visitor):
- // Queues the blocked writer for later resumption.
- void OnWriteBlocked(QuicBlockedWriterInterface* blocked_writer) override;
-
- // QuicSession::Visitor interface implementation (via inheritance of
- // QuicTimeWaitListManager::Visitor):
- // Collects reset error code received on streams.
- void OnRstStreamReceived(const QuicRstStreamFrame& frame) override;
-
- // QuicSession::Visitor interface implementation (via inheritance of
- // QuicTimeWaitListManager::Visitor):
- // Collects reset error code received on streams.
- void OnStopSendingReceived(const QuicStopSendingFrame& frame) override;
-
- // QuicSession::Visitor interface implementation (via inheritance of
- // QuicTimeWaitListManager::Visitor):
- // Add the newly issued connection ID to the session map.
- void OnNewConnectionIdSent(
- const QuicConnectionId& server_connection_id,
- const QuicConnectionId& new_connection_id) override;
-
- // QuicSession::Visitor interface implementation (via inheritance of
- // QuicTimeWaitListManager::Visitor):
- // Remove the retired connection ID from the session map.
- void OnConnectionIdRetired(
- const QuicConnectionId& server_connection_id) override;
-
- // QuicTimeWaitListManager::Visitor interface implementation
- // Called whenever the time wait list manager adds a new connection to the
- // time-wait list.
- void OnConnectionAddedToTimeWaitList(
- QuicConnectionId server_connection_id) override;
-
- using ReferenceCountedSessionMap =
- absl::flat_hash_map<QuicConnectionId,
- std::shared_ptr<QuicSession>,
- QuicConnectionIdHash>;
-
- size_t NumSessions() const;
-
- // Deletes all sessions on the closed session list and clears the list.
- virtual void DeleteSessions();
-
- // Clear recent_stateless_reset_addresses_.
- void ClearStatelessResetAddresses();
-
- using ConnectionIdMap = absl::
- flat_hash_map<QuicConnectionId, QuicConnectionId, QuicConnectionIdHash>;
-
- // QuicBufferedPacketStore::VisitorInterface implementation.
- void OnExpiredPackets(QuicConnectionId server_connection_id,
- QuicBufferedPacketStore::BufferedPacketList
- early_arrived_packets) override;
-
- // Create connections for previously buffered CHLOs as many as allowed.
- virtual void ProcessBufferedChlos(size_t max_connections_to_create);
-
- // Return true if there is CHLO buffered.
- virtual bool HasChlosBuffered() const;
-
- // Start accepting new ConnectionIds.
- void StartAcceptingNewConnections();
-
- // Stop accepting new ConnectionIds, either as a part of the lame
- // duck process or because explicitly configured.
- void StopAcceptingNewConnections();
-
- // Apply an operation for each session.
- void PerformActionOnActiveSessions(
- std::function<void(QuicSession*)> operation) const;
-
- // Get a snapshot of all sessions.
- std::vector<std::shared_ptr<QuicSession>> GetSessionsSnapshot() const;
-
- bool accept_new_connections() const { return accept_new_connections_; }
-
- protected:
- // Creates a QUIC session based on the given information.
- // |alpn| is the selected ALPN from |parsed_chlo.alpns|.
- virtual 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) = 0;
-
- // Tries to validate and dispatch packet based on available information.
- // Returns true if packet is dropped or successfully dispatched (e.g.,
- // processed by existing session, processed by time wait list, etc.),
- // otherwise, returns false and the packet needs further processing.
- virtual bool MaybeDispatchPacket(const ReceivedPacketInfo& packet_info);
-
- // Generate a connection ID with a length that is expected by the dispatcher.
- // Called only when |server_connection_id| is shorter than
- // |expected_connection_id_length|.
- // Note that this MUST produce a deterministic result (calling this method
- // with two connection IDs that are equal must produce the same result).
- // Note that this is not used in general operation because our default
- // |expected_server_connection_id_length| is 8, and the IETF specification
- // requires clients to use an initial length of at least 8. However, we
- // allow disabling that requirement via
- // |allow_short_initial_server_connection_ids_|.
- virtual QuicConnectionId ReplaceShortServerConnectionId(
- const ParsedQuicVersion& version,
- const QuicConnectionId& server_connection_id,
- uint8_t expected_server_connection_id_length) const;
-
- // Generate a connection ID with a length that is expected by the dispatcher.
- // Called only when |server_connection_id| is longer than
- // |expected_connection_id_length|.
- // Note that this MUST produce a deterministic result (calling this method
- // with two connection IDs that are equal must produce the same result).
- virtual QuicConnectionId ReplaceLongServerConnectionId(
- const ParsedQuicVersion& version,
- const QuicConnectionId& server_connection_id,
- uint8_t expected_server_connection_id_length) const;
-
- // Values to be returned by ValidityChecks() to indicate what should be done
- // with a packet. Fates with greater values are considered to be higher
- // priority. ValidityChecks should return fate based on the priority order
- // (i.e., returns higher priority fate first)
- enum QuicPacketFate {
- // Process the packet normally, which is usually to establish a connection.
- kFateProcess,
- // Put the connection ID into time-wait state and send a public reset.
- kFateTimeWait,
- // Drop the packet.
- kFateDrop,
- };
-
- // This method is called by ProcessHeader on packets not associated with a
- // known connection ID. It applies validity checks and returns a
- // QuicPacketFate to tell what should be done with the packet.
- // TODO(fayang): Merge ValidityChecks into MaybeDispatchPacket.
- virtual QuicPacketFate ValidityChecks(const ReceivedPacketInfo& packet_info);
-
- // Extra validity checks after the full Client Hello is parsed, this allows
- // subclasses to reject a connection based on sni or alpn.
- // Only called if ValidityChecks returns kFateProcess.
- virtual QuicPacketFate ValidityChecksOnFullChlo(
- const ReceivedPacketInfo& /*packet_info*/,
- const ParsedClientHello& /*parsed_chlo*/) const {
- return kFateProcess;
- }
-
- // Create and return the time wait list manager for this dispatcher, which
- // will be owned by the dispatcher as time_wait_list_manager_
- virtual QuicTimeWaitListManager* CreateQuicTimeWaitListManager();
-
- // Buffers packet until it can be delivered to a connection.
- void BufferEarlyPacket(const ReceivedPacketInfo& packet_info);
-
- // Called when |packet_info| is the last received packet of the client hello.
- // |parsed_chlo| is the parsed version of the client hello. Creates a new
- // connection and delivers any buffered packets for that connection id.
- void ProcessChlo(ParsedClientHello parsed_chlo,
- ReceivedPacketInfo* packet_info);
-
- // Return true if dispatcher wants to destroy session outside of
- // OnConnectionClosed() call stack.
- virtual bool ShouldDestroySessionAsynchronously();
-
- QuicTimeWaitListManager* time_wait_list_manager() {
- return time_wait_list_manager_.get();
- }
-
- const ParsedQuicVersionVector& GetSupportedVersions();
-
- const QuicConfig& config() const { return *config_; }
-
- const QuicCryptoServerConfig* crypto_config() const { return crypto_config_; }
-
- QuicCompressedCertsCache* compressed_certs_cache() {
- return &compressed_certs_cache_;
- }
-
- QuicConnectionHelperInterface* helper() { return helper_.get(); }
-
- QuicCryptoServerStreamBase::Helper* session_helper() {
- return session_helper_.get();
- }
-
- const QuicCryptoServerStreamBase::Helper* session_helper() const {
- return session_helper_.get();
- }
-
- QuicAlarmFactory* alarm_factory() { return alarm_factory_.get(); }
-
- QuicPacketWriter* writer() { return writer_.get(); }
-
- // Returns true if a session should be created for a connection with an
- // unknown version identified by |version_label|.
- virtual bool ShouldCreateSessionForUnknownVersion(
- QuicVersionLabel version_label);
-
- void SetLastError(QuicErrorCode error);
-
- // Called by MaybeDispatchPacket when current packet cannot be dispatched.
- // Used by subclasses to conduct specific logic to dispatch packet. Returns
- // true if packet is successfully dispatched.
- virtual bool OnFailedToDispatchPacket(const ReceivedPacketInfo& packet_info);
-
- // Called when a new connection starts to be handled by this dispatcher.
- // Either this connection is created or its packets is buffered while waiting
- // for CHLO. Returns true if a new connection should be created or its packets
- // should be buffered, false otherwise.
- virtual bool ShouldCreateOrBufferPacketForConnection(
- const ReceivedPacketInfo& packet_info);
-
- bool HasBufferedPackets(QuicConnectionId server_connection_id);
-
- // Called when BufferEarlyPacket() fail to buffer the packet.
- virtual void OnBufferPacketFailure(
- QuicBufferedPacketStore::EnqueuePacketResult result,
- QuicConnectionId server_connection_id);
-
- // Removes the session from the write blocked list, and adds the ConnectionId
- // to the time-wait list. The caller needs to manually remove the session
- // from the map after that.
- void CleanUpSession(QuicConnectionId server_connection_id,
- QuicConnection* connection,
- QuicErrorCode error,
- const std::string& error_details,
- ConnectionCloseSource source);
-
- // Called to terminate a connection statelessly. Depending on |format|, either
- // 1) send connection close with |error_code| and |error_details| and add
- // connection to time wait list or 2) directly add connection to time wait
- // list with |action|.
- void StatelesslyTerminateConnection(
- QuicConnectionId server_connection_id,
- PacketHeaderFormat format,
- bool version_flag,
- bool use_length_prefix,
- ParsedQuicVersion version,
- QuicErrorCode error_code,
- const std::string& error_details,
- QuicTimeWaitListManager::TimeWaitAction action);
-
- // Save/Restore per packet context.
- virtual std::unique_ptr<QuicPerPacketContext> GetPerPacketContext() const;
- virtual void RestorePerPacketContext(
- std::unique_ptr<QuicPerPacketContext> /*context*/) {}
-
- // If true, our framer will change its expected connection ID length
- // to the received destination connection ID length of all IETF long headers.
- void SetShouldUpdateExpectedServerConnectionIdLength(
- bool should_update_expected_server_connection_id_length) {
- should_update_expected_server_connection_id_length_ =
- should_update_expected_server_connection_id_length;
- }
-
- // If true, the dispatcher will allow incoming initial packets that have
- // destination connection IDs shorter than 64 bits.
- void SetAllowShortInitialServerConnectionIds(
- bool allow_short_initial_server_connection_ids) {
- allow_short_initial_server_connection_ids_ =
- allow_short_initial_server_connection_ids;
- }
-
- // Called if a packet from an unseen connection is reset or rejected.
- virtual void OnNewConnectionRejected() {}
-
- // Selects the preferred ALPN from a vector of ALPNs.
- // This runs through the list of ALPNs provided by the client and picks the
- // first one it supports. If no supported versions are found, the first
- // element of the vector is returned.
- std::string SelectAlpn(const std::vector<std::string>& alpns);
-
- // If the connection ID length is different from what the dispatcher expects,
- // replace the connection ID with one of the right length.
- // Note that this MUST produce a deterministic result (calling this method
- // with two connection IDs that are equal must produce the same result).
- QuicConnectionId MaybeReplaceServerConnectionId(
- const QuicConnectionId& server_connection_id,
- const ParsedQuicVersion& version) const;
-
- // Sends public/stateless reset packets with no version and unknown
- // connection ID according to the packet's size.
- virtual void MaybeResetPacketsWithNoVersion(
- const quic::ReceivedPacketInfo& packet_info);
-
- private:
- friend class test::QuicDispatcherPeer;
-
- // TODO(fayang): Consider to rename this function to
- // ProcessValidatedPacketWithUnknownConnectionId.
- void ProcessHeader(ReceivedPacketInfo* packet_info);
-
- // Try to extract information(sni, alpns, ...) if the full Client Hello has
- // been parsed.
- //
- // Return the parsed client hello if the full Client Hello has been
- // successfully parsed.
- //
- // Otherwise return absl::nullopt and either buffer or (rarely) drop the
- // packet.
- absl::optional<ParsedClientHello> TryExtractChloOrBufferEarlyPacket(
- const ReceivedPacketInfo& packet_info);
-
- // Deliver |packets| to |session| for further processing.
- void DeliverPacketsToSession(
- const std::list<QuicBufferedPacketStore::BufferedPacket>& packets,
- QuicSession* session);
-
- // Returns true if |version| is a supported protocol version.
- bool IsSupportedVersion(const ParsedQuicVersion version);
-
- const QuicConfig* config_;
-
- const QuicCryptoServerConfig* crypto_config_;
-
- // The cache for most recently compressed certs.
- QuicCompressedCertsCache compressed_certs_cache_;
-
- // The list of connections waiting to write.
- WriteBlockedList write_blocked_list_;
-
- ReferenceCountedSessionMap reference_counted_session_map_;
-
- // Entity that manages connection_ids in time wait state.
- std::unique_ptr<QuicTimeWaitListManager> time_wait_list_manager_;
-
- // The list of closed but not-yet-deleted sessions.
- std::vector<std::shared_ptr<QuicSession>> closed_session_list_;
-
- // The helper used for all connections.
- std::unique_ptr<QuicConnectionHelperInterface> helper_;
-
- // The helper used for all sessions.
- std::unique_ptr<QuicCryptoServerStreamBase::Helper> session_helper_;
-
- // Creates alarms.
- std::unique_ptr<QuicAlarmFactory> alarm_factory_;
-
- // An alarm which deletes closed sessions.
- std::unique_ptr<QuicAlarm> delete_sessions_alarm_;
-
- // The writer to write to the socket with.
- std::unique_ptr<QuicPacketWriter> writer_;
-
- // Packets which are buffered until a connection can be created to handle
- // them.
- QuicBufferedPacketStore buffered_packets_;
-
- // Used to get the supported versions based on flag. Does not own.
- QuicVersionManager* version_manager_;
-
- // The last error set by SetLastError().
- // TODO(fayang): consider removing last_error_.
- QuicErrorCode last_error_;
-
- // Number of unique session in session map.
- size_t num_sessions_in_session_map_ = 0;
-
- // A backward counter of how many new sessions can be create within current
- // event loop. When reaches 0, it means can't create sessions for now.
- int16_t new_sessions_allowed_per_event_loop_;
-
- // True if this dispatcher is accepting new ConnectionIds (new client
- // connections), false otherwise.
- bool accept_new_connections_;
-
- // If false, the dispatcher follows the IETF spec and rejects packets with
- // invalid destination connection IDs lengths below 64 bits.
- // If true they are allowed.
- bool allow_short_initial_server_connection_ids_;
-
- // IETF short headers contain a destination connection ID but do not
- // encode its length. This variable contains the length we expect to read.
- // This is also used to signal an error when a long header packet with
- // different destination connection ID length is received when
- // should_update_expected_server_connection_id_length_ is false and packet's
- // version does not allow variable length connection ID.
- uint8_t expected_server_connection_id_length_;
-
- // Records client addresses that have been recently reset.
- absl::flat_hash_set<QuicSocketAddress, QuicSocketAddressHash>
- recent_stateless_reset_addresses_;
-
- // An alarm which clear recent_stateless_reset_addresses_.
- std::unique_ptr<QuicAlarm> clear_stateless_reset_addresses_alarm_;
-
- // 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
-
-#endif // QUICHE_QUIC_CORE_QUIC_DISPATCHER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_dispatcher_test.cc b/chromium/net/third_party/quiche/src/quic/core/quic_dispatcher_test.cc
deleted file mode 100644
index add5164d674..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_dispatcher_test.cc
+++ /dev/null
@@ -1,2918 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_dispatcher.h"
-
-#include <memory>
-#include <ostream>
-#include <string>
-#include <utility>
-
-#include "absl/base/macros.h"
-#include "absl/strings/str_cat.h"
-#include "quic/core/chlo_extractor.h"
-#include "quic/core/crypto/crypto_handshake.h"
-#include "quic/core/crypto/crypto_protocol.h"
-#include "quic/core/crypto/quic_crypto_server_config.h"
-#include "quic/core/crypto/quic_random.h"
-#include "quic/core/frames/quic_new_connection_id_frame.h"
-#include "quic/core/quic_config.h"
-#include "quic/core/quic_connection.h"
-#include "quic/core/quic_connection_id.h"
-#include "quic/core/quic_crypto_stream.h"
-#include "quic/core/quic_packet_writer_wrapper.h"
-#include "quic/core/quic_time_wait_list_manager.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_utils.h"
-#include "quic/core/quic_versions.h"
-#include "quic/platform/api/quic_expect_bug.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/crypto_test_utils.h"
-#include "quic/test_tools/fake_proof_source.h"
-#include "quic/test_tools/first_flight.h"
-#include "quic/test_tools/mock_quic_time_wait_list_manager.h"
-#include "quic/test_tools/quic_buffered_packet_store_peer.h"
-#include "quic/test_tools/quic_connection_peer.h"
-#include "quic/test_tools/quic_crypto_server_config_peer.h"
-#include "quic/test_tools/quic_dispatcher_peer.h"
-#include "quic/test_tools/quic_test_utils.h"
-#include "quic/test_tools/quic_time_wait_list_manager_peer.h"
-#include "quic/tools/quic_simple_crypto_server_stream_helper.h"
-#include "common/test_tools/quiche_test_utils.h"
-
-using testing::_;
-using testing::ByMove;
-using testing::Eq;
-using testing::InSequence;
-using testing::Invoke;
-using testing::NiceMock;
-using testing::Return;
-using testing::WithArg;
-using testing::WithoutArgs;
-
-static const size_t kDefaultMaxConnectionsInStore = 100;
-static const size_t kMaxConnectionsWithoutCHLO =
- kDefaultMaxConnectionsInStore / 2;
-static const int16_t kMaxNumSessionsToCreate = 16;
-
-namespace quic {
-namespace test {
-namespace {
-
-class TestQuicSpdyServerSession : public QuicServerSessionBase {
- public:
- TestQuicSpdyServerSession(const QuicConfig& config,
- QuicConnection* connection,
- const QuicCryptoServerConfig* crypto_config,
- QuicCompressedCertsCache* compressed_certs_cache)
- : QuicServerSessionBase(config, CurrentSupportedVersions(), connection,
- nullptr, nullptr, crypto_config,
- compressed_certs_cache) {
- Initialize();
- }
- TestQuicSpdyServerSession(const TestQuicSpdyServerSession&) = delete;
- TestQuicSpdyServerSession& operator=(const TestQuicSpdyServerSession&) =
- delete;
-
- ~TestQuicSpdyServerSession() override { DeleteConnection(); }
-
- MOCK_METHOD(void, OnConnectionClosed,
- (const QuicConnectionCloseFrame& frame,
- ConnectionCloseSource source),
- (override));
- MOCK_METHOD(QuicSpdyStream*, CreateIncomingStream, (QuicStreamId id),
- (override));
- MOCK_METHOD(QuicSpdyStream*, CreateIncomingStream, (PendingStream*),
- (override));
- MOCK_METHOD(QuicSpdyStream*, CreateOutgoingBidirectionalStream, (),
- (override));
- MOCK_METHOD(QuicSpdyStream*, CreateOutgoingUnidirectionalStream, (),
- (override));
-
- std::unique_ptr<QuicCryptoServerStreamBase> CreateQuicCryptoServerStream(
- const QuicCryptoServerConfig* crypto_config,
- QuicCompressedCertsCache* compressed_certs_cache) override {
- return CreateCryptoServerStream(crypto_config, compressed_certs_cache, this,
- stream_helper());
- }
-
- QuicCryptoServerStreamBase::Helper* stream_helper() {
- return QuicServerSessionBase::stream_helper();
- }
-};
-
-class TestDispatcher : public QuicDispatcher {
- public:
- TestDispatcher(const QuicConfig* config,
- const QuicCryptoServerConfig* crypto_config,
- QuicVersionManager* version_manager, QuicRandom* random)
- : QuicDispatcher(config, crypto_config, version_manager,
- std::make_unique<MockQuicConnectionHelper>(),
- std::unique_ptr<QuicCryptoServerStreamBase::Helper>(
- new QuicSimpleCryptoServerStreamHelper()),
- std::make_unique<TestAlarmFactory>(),
- kQuicDefaultConnectionIdLength),
- random_(random) {}
-
- MOCK_METHOD(std::unique_ptr<QuicSession>, CreateQuicSession,
- (QuicConnectionId connection_id,
- const QuicSocketAddress& self_address,
- const QuicSocketAddress& peer_address, absl::string_view alpn,
- const ParsedQuicVersion& version,
- const ParsedClientHello& parsed_chlo),
- (override));
-
- MOCK_METHOD(bool, ShouldCreateOrBufferPacketForConnection,
- (const ReceivedPacketInfo& packet_info), (override));
-
- struct TestQuicPerPacketContext : public QuicPerPacketContext {
- std::string custom_packet_context;
- };
-
- std::unique_ptr<QuicPerPacketContext> GetPerPacketContext() const override {
- auto test_context = std::make_unique<TestQuicPerPacketContext>();
- test_context->custom_packet_context = custom_packet_context_;
- return std::move(test_context);
- }
-
- void RestorePerPacketContext(
- std::unique_ptr<QuicPerPacketContext> context) override {
- TestQuicPerPacketContext* test_context =
- static_cast<TestQuicPerPacketContext*>(context.get());
- custom_packet_context_ = test_context->custom_packet_context;
- }
-
- std::string custom_packet_context_;
-
- using QuicDispatcher::MaybeDispatchPacket;
- using QuicDispatcher::SetAllowShortInitialServerConnectionIds;
- using QuicDispatcher::writer;
-
- QuicRandom* random_;
-};
-
-// A Connection class which unregisters the session from the dispatcher when
-// sending connection close.
-// It'd be slightly more realistic to do this from the Session but it would
-// involve a lot more mocking.
-class MockServerConnection : public MockQuicConnection {
- public:
- MockServerConnection(QuicConnectionId connection_id,
- MockQuicConnectionHelper* helper,
- MockAlarmFactory* alarm_factory,
- QuicDispatcher* dispatcher)
- : MockQuicConnection(connection_id, helper, alarm_factory,
- Perspective::IS_SERVER),
- dispatcher_(dispatcher),
- active_connection_ids_({connection_id}) {}
-
- void AddNewConnectionId(QuicConnectionId id) {
- dispatcher_->OnNewConnectionIdSent(active_connection_ids_.back(), id);
- QuicConnectionPeer::SetServerConnectionId(this, id);
- active_connection_ids_.push_back(id);
- }
-
- void RetireConnectionId(QuicConnectionId id) {
- auto it = std::find(active_connection_ids_.begin(),
- active_connection_ids_.end(), id);
- QUICHE_DCHECK(it != active_connection_ids_.end());
- dispatcher_->OnConnectionIdRetired(id);
- active_connection_ids_.erase(it);
- }
-
- std::vector<QuicConnectionId> GetActiveServerConnectionIds() const override {
- return active_connection_ids_;
- }
-
- void UnregisterOnConnectionClosed() {
- QUIC_LOG(ERROR) << "Unregistering " << connection_id();
- dispatcher_->OnConnectionClosed(connection_id(), QUIC_NO_ERROR,
- "Unregistering.",
- ConnectionCloseSource::FROM_SELF);
- }
-
- private:
- QuicDispatcher* dispatcher_;
- std::vector<QuicConnectionId> active_connection_ids_;
-};
-
-class QuicDispatcherTestBase : public QuicTestWithParam<ParsedQuicVersion> {
- public:
- QuicDispatcherTestBase()
- : QuicDispatcherTestBase(crypto_test_utils::ProofSourceForTesting()) {}
-
- explicit QuicDispatcherTestBase(std::unique_ptr<ProofSource> proof_source)
- : version_(GetParam()),
- version_manager_(AllSupportedVersions()),
- crypto_config_(QuicCryptoServerConfig::TESTING,
- QuicRandom::GetInstance(), std::move(proof_source),
- KeyExchangeSource::Default()),
- server_address_(QuicIpAddress::Any4(), 5),
- dispatcher_(new NiceMock<TestDispatcher>(
- &config_, &crypto_config_, &version_manager_,
- mock_helper_.GetRandomGenerator())),
- time_wait_list_manager_(nullptr),
- session1_(nullptr),
- session2_(nullptr),
- store_(nullptr),
- connection_id_(1) {}
-
- void SetUp() override {
- dispatcher_->InitializeWithWriter(new NiceMock<MockPacketWriter>());
- // Set the counter to some value to start with.
- QuicDispatcherPeer::set_new_sessions_allowed_per_event_loop(
- dispatcher_.get(), kMaxNumSessionsToCreate);
- ON_CALL(*dispatcher_, ShouldCreateOrBufferPacketForConnection(_))
- .WillByDefault(Return(true));
- }
-
- MockQuicConnection* connection1() {
- if (session1_ == nullptr) {
- return nullptr;
- }
- return reinterpret_cast<MockQuicConnection*>(session1_->connection());
- }
-
- MockQuicConnection* connection2() {
- if (session2_ == nullptr) {
- return nullptr;
- }
- return reinterpret_cast<MockQuicConnection*>(session2_->connection());
- }
-
- // Process a packet with an 8 byte connection id,
- // 6 byte packet number, default path id, and packet number 1,
- // using the version under test.
- void ProcessPacket(QuicSocketAddress peer_address,
- QuicConnectionId server_connection_id,
- bool has_version_flag, const std::string& data) {
- ProcessPacket(peer_address, server_connection_id, has_version_flag, data,
- CONNECTION_ID_PRESENT, PACKET_4BYTE_PACKET_NUMBER);
- }
-
- // Process a packet with a default path id, and packet number 1,
- // using the version under test.
- void ProcessPacket(QuicSocketAddress peer_address,
- QuicConnectionId server_connection_id,
- bool has_version_flag, const std::string& data,
- QuicConnectionIdIncluded server_connection_id_included,
- QuicPacketNumberLength packet_number_length) {
- ProcessPacket(peer_address, server_connection_id, has_version_flag, data,
- server_connection_id_included, packet_number_length, 1);
- }
-
- // Process a packet using the version under test.
- void ProcessPacket(QuicSocketAddress peer_address,
- QuicConnectionId server_connection_id,
- bool has_version_flag, const std::string& data,
- QuicConnectionIdIncluded server_connection_id_included,
- QuicPacketNumberLength packet_number_length,
- uint64_t packet_number) {
- ProcessPacket(peer_address, server_connection_id, has_version_flag,
- version_, data, true, server_connection_id_included,
- packet_number_length, packet_number);
- }
-
- // Processes a packet.
- void ProcessPacket(QuicSocketAddress peer_address,
- QuicConnectionId server_connection_id,
- bool has_version_flag, ParsedQuicVersion version,
- const std::string& data, bool full_padding,
- QuicConnectionIdIncluded server_connection_id_included,
- QuicPacketNumberLength packet_number_length,
- uint64_t packet_number) {
- ProcessPacket(peer_address, server_connection_id, EmptyQuicConnectionId(),
- has_version_flag, version, data, full_padding,
- server_connection_id_included, CONNECTION_ID_ABSENT,
- packet_number_length, packet_number);
- }
-
- // Processes a packet.
- void ProcessPacket(QuicSocketAddress peer_address,
- QuicConnectionId server_connection_id,
- QuicConnectionId client_connection_id,
- bool has_version_flag, ParsedQuicVersion version,
- const std::string& data, bool full_padding,
- QuicConnectionIdIncluded server_connection_id_included,
- QuicConnectionIdIncluded client_connection_id_included,
- QuicPacketNumberLength packet_number_length,
- uint64_t packet_number) {
- ParsedQuicVersionVector versions(SupportedVersions(version));
- std::unique_ptr<QuicEncryptedPacket> packet(ConstructEncryptedPacket(
- server_connection_id, client_connection_id, has_version_flag, false,
- packet_number, data, full_padding, server_connection_id_included,
- client_connection_id_included, packet_number_length, &versions));
- std::unique_ptr<QuicReceivedPacket> received_packet(
- ConstructReceivedPacket(*packet, mock_helper_.GetClock()->Now()));
- ProcessReceivedPacket(std::move(received_packet), peer_address, version,
- server_connection_id);
- }
-
- void ProcessReceivedPacket(
- std::unique_ptr<QuicReceivedPacket> received_packet,
- const QuicSocketAddress& peer_address, const ParsedQuicVersion& version,
- const QuicConnectionId& server_connection_id) {
- if (version.UsesQuicCrypto() &&
- ChloExtractor::Extract(*received_packet, version, {}, nullptr,
- server_connection_id.length())) {
- // Add CHLO packet to the beginning to be verified first, because it is
- // also processed first by new session.
- data_connection_map_[server_connection_id].push_front(
- std::string(received_packet->data(), received_packet->length()));
- } else {
- // For non-CHLO, always append to last.
- data_connection_map_[server_connection_id].push_back(
- std::string(received_packet->data(), received_packet->length()));
- }
- dispatcher_->ProcessPacket(server_address_, peer_address, *received_packet);
- }
-
- void ValidatePacket(QuicConnectionId conn_id,
- const QuicEncryptedPacket& packet) {
- EXPECT_EQ(data_connection_map_[conn_id].front().length(),
- packet.AsStringPiece().length());
- EXPECT_EQ(data_connection_map_[conn_id].front(), packet.AsStringPiece());
- data_connection_map_[conn_id].pop_front();
- }
-
- std::unique_ptr<QuicSession> CreateSession(
- TestDispatcher* dispatcher, const QuicConfig& config,
- QuicConnectionId connection_id, const QuicSocketAddress& /*peer_address*/,
- MockQuicConnectionHelper* helper, MockAlarmFactory* alarm_factory,
- const QuicCryptoServerConfig* crypto_config,
- QuicCompressedCertsCache* compressed_certs_cache,
- TestQuicSpdyServerSession** session_ptr) {
- MockServerConnection* connection = new MockServerConnection(
- connection_id, helper, alarm_factory, dispatcher);
- connection->SetQuicPacketWriter(dispatcher->writer(),
- /*owns_writer=*/false);
- auto session = std::make_unique<TestQuicSpdyServerSession>(
- config, connection, crypto_config, compressed_certs_cache);
- *session_ptr = session.get();
- connection->set_visitor(session.get());
- ON_CALL(*connection, CloseConnection(_, _, _))
- .WillByDefault(WithoutArgs(Invoke(
- connection, &MockServerConnection::UnregisterOnConnectionClosed)));
- return session;
- }
-
- void CreateTimeWaitListManager() {
- time_wait_list_manager_ = new MockTimeWaitListManager(
- QuicDispatcherPeer::GetWriter(dispatcher_.get()), dispatcher_.get(),
- mock_helper_.GetClock(), &mock_alarm_factory_);
- // dispatcher_ takes the ownership of time_wait_list_manager_.
- QuicDispatcherPeer::SetTimeWaitListManager(dispatcher_.get(),
- time_wait_list_manager_);
- }
-
- std::string SerializeCHLO() {
- CryptoHandshakeMessage client_hello;
- client_hello.set_tag(kCHLO);
- client_hello.SetStringPiece(kALPN, ExpectedAlpn());
- return std::string(client_hello.GetSerialized().AsStringPiece());
- }
-
- void ProcessUndecryptableEarlyPacket(
- const QuicSocketAddress& peer_address,
- const QuicConnectionId& server_connection_id) {
- ProcessUndecryptableEarlyPacket(version_, peer_address,
- server_connection_id);
- }
-
- void ProcessUndecryptableEarlyPacket(
- const ParsedQuicVersion& version, const QuicSocketAddress& peer_address,
- const QuicConnectionId& server_connection_id) {
- std::unique_ptr<QuicEncryptedPacket> encrypted_packet =
- GetUndecryptableEarlyPacket(version, server_connection_id);
- std::unique_ptr<QuicReceivedPacket> received_packet(ConstructReceivedPacket(
- *encrypted_packet, mock_helper_.GetClock()->Now()));
- ProcessReceivedPacket(std::move(received_packet), peer_address, version,
- server_connection_id);
- }
-
- void ProcessFirstFlight(const QuicSocketAddress& peer_address,
- const QuicConnectionId& server_connection_id) {
- ProcessFirstFlight(version_, peer_address, server_connection_id);
- }
-
- void ProcessFirstFlight(const ParsedQuicVersion& version,
- const QuicSocketAddress& peer_address,
- const QuicConnectionId& server_connection_id) {
- ProcessFirstFlight(version, peer_address, server_connection_id,
- EmptyQuicConnectionId());
- }
-
- void ProcessFirstFlight(const ParsedQuicVersion& version,
- const QuicSocketAddress& peer_address,
- const QuicConnectionId& server_connection_id,
- const QuicConnectionId& client_connection_id) {
- ProcessFirstFlight(version, peer_address, server_connection_id,
- client_connection_id, TestClientCryptoConfig());
- }
-
- void ProcessFirstFlight(
- const ParsedQuicVersion& version, const QuicSocketAddress& peer_address,
- const QuicConnectionId& server_connection_id,
- const QuicConnectionId& client_connection_id,
- std::unique_ptr<QuicCryptoClientConfig> client_crypto_config) {
- std::vector<std::unique_ptr<QuicReceivedPacket>> packets =
- GetFirstFlightOfPackets(version, DefaultQuicConfig(),
- server_connection_id, client_connection_id,
- std::move(client_crypto_config));
- for (auto&& packet : packets) {
- ProcessReceivedPacket(std::move(packet), peer_address, version,
- server_connection_id);
- }
- }
-
- std::unique_ptr<QuicCryptoClientConfig> TestClientCryptoConfig() {
- auto client_crypto_config = std::make_unique<QuicCryptoClientConfig>(
- crypto_test_utils::ProofVerifierForTesting());
- if (address_token_.has_value()) {
- client_crypto_config->LookupOrCreate(TestServerId())
- ->set_source_address_token(*address_token_);
- }
- return client_crypto_config;
- }
-
- // If called, the first flight packets generated in |ProcessFirstFlight| will
- // contain the given |address_token|.
- void SetAddressToken(std::string address_token) {
- address_token_ = std::move(address_token);
- }
-
- std::string ExpectedAlpnForVersion(ParsedQuicVersion version) {
- return AlpnForVersion(version);
- }
-
- std::string ExpectedAlpn() { return ExpectedAlpnForVersion(version_); }
-
- ParsedClientHello ParsedClientHelloForTest() {
- ParsedClientHello parsed_chlo;
- parsed_chlo.alpns = {ExpectedAlpn()};
- parsed_chlo.sni = TestHostname();
- if (address_token_.has_value() &&
- !GetQuicReloadableFlag(quic_tls_use_token_in_session_cache)) {
- parsed_chlo.retry_token = *address_token_;
- }
- return parsed_chlo;
- }
-
- void MarkSession1Deleted() { session1_ = nullptr; }
-
- void VerifyVersionSupported(ParsedQuicVersion version) {
- QuicConnectionId connection_id = TestConnectionId(++connection_id_);
- QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
- EXPECT_CALL(*dispatcher_,
- CreateQuicSession(connection_id, _, client_address,
- Eq(ExpectedAlpnForVersion(version)), _, _))
- .WillOnce(Return(ByMove(CreateSession(
- dispatcher_.get(), config_, connection_id, client_address,
- &mock_helper_, &mock_alarm_factory_, &crypto_config_,
- QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
- EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
- ProcessUdpPacket(_, _, _))
- .WillOnce(WithArg<2>(
- Invoke([this, connection_id](const QuicEncryptedPacket& packet) {
- ValidatePacket(connection_id, packet);
- })));
- EXPECT_CALL(*dispatcher_,
- ShouldCreateOrBufferPacketForConnection(
- ReceivedPacketInfoConnectionIdEquals(connection_id)));
- ProcessFirstFlight(version, client_address, connection_id);
- }
-
- void VerifyVersionNotSupported(ParsedQuicVersion version) {
- QuicConnectionId connection_id = TestConnectionId(++connection_id_);
- QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
- EXPECT_CALL(*dispatcher_,
- CreateQuicSession(connection_id, _, client_address, _, _, _))
- .Times(0);
- ProcessFirstFlight(version, client_address, connection_id);
- }
-
- void TestTlsMultiPacketClientHello(bool add_reordering);
-
- void TestVersionNegotiationForUnknownVersionInvalidShortInitialConnectionId(
- const QuicConnectionId& server_connection_id,
- const QuicConnectionId& client_connection_id);
-
- TestAlarmFactory::TestAlarm* GetClearResetAddressesAlarm() {
- return reinterpret_cast<TestAlarmFactory::TestAlarm*>(
- QuicDispatcherPeer::GetClearResetAddressesAlarm(dispatcher_.get()));
- }
-
- ParsedQuicVersion version_;
- MockQuicConnectionHelper mock_helper_;
- MockAlarmFactory mock_alarm_factory_;
- QuicConfig config_;
- QuicVersionManager version_manager_;
- QuicCryptoServerConfig crypto_config_;
- QuicSocketAddress server_address_;
- std::unique_ptr<NiceMock<TestDispatcher>> dispatcher_;
- MockTimeWaitListManager* time_wait_list_manager_;
- TestQuicSpdyServerSession* session1_;
- TestQuicSpdyServerSession* session2_;
- std::map<QuicConnectionId, std::list<std::string>> data_connection_map_;
- QuicBufferedPacketStore* store_;
- uint64_t connection_id_;
- absl::optional<std::string> address_token_;
-};
-
-class QuicDispatcherTestAllVersions : public QuicDispatcherTestBase {};
-class QuicDispatcherTestOneVersion : public QuicDispatcherTestBase {};
-
-INSTANTIATE_TEST_SUITE_P(QuicDispatcherTestsAllVersions,
- QuicDispatcherTestAllVersions,
- ::testing::ValuesIn(CurrentSupportedVersions()),
- ::testing::PrintToStringParamName());
-
-INSTANTIATE_TEST_SUITE_P(QuicDispatcherTestsOneVersion,
- QuicDispatcherTestOneVersion,
- ::testing::Values(CurrentSupportedVersions().front()),
- ::testing::PrintToStringParamName());
-
-TEST_P(QuicDispatcherTestAllVersions, TlsClientHelloCreatesSession) {
- if (version_.UsesQuicCrypto()) {
- return;
- }
- SetAddressToken("hsdifghdsaifnasdpfjdsk");
-
- QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
-
- EXPECT_CALL(
- *dispatcher_,
- CreateQuicSession(TestConnectionId(1), _, client_address,
- Eq(ExpectedAlpn()), _, Eq(ParsedClientHelloForTest())))
- .WillOnce(Return(ByMove(CreateSession(
- dispatcher_.get(), config_, TestConnectionId(1), client_address,
- &mock_helper_, &mock_alarm_factory_, &crypto_config_,
- QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
- EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
- ProcessUdpPacket(_, _, _))
- .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
- ValidatePacket(TestConnectionId(1), packet);
- })));
- EXPECT_CALL(*dispatcher_,
- ShouldCreateOrBufferPacketForConnection(
- ReceivedPacketInfoConnectionIdEquals(TestConnectionId(1))));
-
- ProcessFirstFlight(client_address, TestConnectionId(1));
-}
-
-void QuicDispatcherTestBase::TestTlsMultiPacketClientHello(
- bool add_reordering) {
- if (!version_.UsesTls()) {
- return;
- }
- SetAddressToken("857293462398");
-
- QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
- QuicConnectionId server_connection_id = TestConnectionId();
- QuicConfig client_config = DefaultQuicConfig();
- // Add a 2000-byte custom parameter to increase the length of the CHLO.
- constexpr auto kCustomParameterId =
- static_cast<TransportParameters::TransportParameterId>(0xff33);
- std::string kCustomParameterValue(2000, '-');
- client_config.custom_transport_parameters_to_send()[kCustomParameterId] =
- kCustomParameterValue;
- std::vector<std::unique_ptr<QuicReceivedPacket>> packets =
- GetFirstFlightOfPackets(version_, client_config, server_connection_id,
- EmptyQuicConnectionId(),
- TestClientCryptoConfig());
- ASSERT_EQ(packets.size(), 2u);
- if (add_reordering) {
- std::swap(packets[0], packets[1]);
- }
-
- // Processing the first packet should not create a new session.
- EXPECT_CALL(*dispatcher_,
- ShouldCreateOrBufferPacketForConnection(
- ReceivedPacketInfoConnectionIdEquals(server_connection_id)));
- ProcessReceivedPacket(std::move(packets[0]), client_address, version_,
- server_connection_id);
-
- EXPECT_EQ(dispatcher_->NumSessions(), 0u)
- << "No session should be created before the rest of the CHLO arrives.";
-
- // Processing the second packet should create the new session.
- EXPECT_CALL(
- *dispatcher_,
- CreateQuicSession(server_connection_id, _, client_address,
- Eq(ExpectedAlpn()), _, Eq(ParsedClientHelloForTest())))
- .WillOnce(Return(ByMove(CreateSession(
- dispatcher_.get(), config_, server_connection_id, client_address,
- &mock_helper_, &mock_alarm_factory_, &crypto_config_,
- QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
- EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
- ProcessUdpPacket(_, _, _))
- .Times(2);
-
- ProcessReceivedPacket(std::move(packets[1]), client_address, version_,
- server_connection_id);
- EXPECT_EQ(dispatcher_->NumSessions(), 1u);
-}
-
-TEST_P(QuicDispatcherTestAllVersions, TlsMultiPacketClientHello) {
- TestTlsMultiPacketClientHello(/*add_reordering=*/false);
-}
-
-TEST_P(QuicDispatcherTestAllVersions, TlsMultiPacketClientHelloWithReordering) {
- TestTlsMultiPacketClientHello(/*add_reordering=*/true);
-}
-
-TEST_P(QuicDispatcherTestAllVersions, LegacyVersionEncapsulation) {
- if (!version_.HasLongHeaderLengths()) {
- // Decapsulating Legacy Version Encapsulation packets from these versions
- // is not currently supported in QuicDispatcher.
- return;
- }
- QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
- QuicConnectionId server_connection_id = TestConnectionId();
- QuicConfig client_config = DefaultQuicConfig();
- client_config.SetClientConnectionOptions(QuicTagVector{kQLVE});
- std::vector<std::unique_ptr<QuicReceivedPacket>> packets =
- GetFirstFlightOfPackets(version_, client_config, server_connection_id);
- ASSERT_EQ(packets.size(), 1u);
-
- // Validate that Legacy Version Encapsulation is actually being used by
- // checking the version of the packet before processing it.
- PacketHeaderFormat format = IETF_QUIC_LONG_HEADER_PACKET;
- QuicLongHeaderType long_packet_type;
- bool version_present;
- bool has_length_prefix;
- QuicVersionLabel version_label;
- ParsedQuicVersion parsed_version = ParsedQuicVersion::Unsupported();
- QuicConnectionId destination_connection_id, source_connection_id;
- absl::optional<absl::string_view> retry_token;
- std::string detailed_error;
- const QuicErrorCode error = QuicFramer::ParsePublicHeaderDispatcher(
- QuicEncryptedPacket(packets[0]->data(), packets[0]->length()),
- kQuicDefaultConnectionIdLength, &format, &long_packet_type,
- &version_present, &has_length_prefix, &version_label, &parsed_version,
- &destination_connection_id, &source_connection_id, &retry_token,
- &detailed_error);
- ASSERT_THAT(error, IsQuicNoError()) << detailed_error;
- EXPECT_EQ(format, GOOGLE_QUIC_PACKET);
- EXPECT_TRUE(version_present);
- EXPECT_FALSE(has_length_prefix);
- EXPECT_EQ(parsed_version, LegacyVersionForEncapsulation());
- EXPECT_EQ(destination_connection_id, server_connection_id);
- EXPECT_EQ(source_connection_id, EmptyQuicConnectionId());
- EXPECT_FALSE(retry_token.has_value());
- EXPECT_TRUE(detailed_error.empty());
-
- // Processing the packet should create a new session.
- EXPECT_CALL(*dispatcher_,
- CreateQuicSession(server_connection_id, _, client_address,
- Eq(ExpectedAlpn()), _, _))
- .WillOnce(Return(ByMove(CreateSession(
- dispatcher_.get(), config_, server_connection_id, client_address,
- &mock_helper_, &mock_alarm_factory_, &crypto_config_,
- QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
- EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
- ProcessUdpPacket(_, _, _))
- .Times(2);
-
- ProcessReceivedPacket(packets[0]->Clone(), client_address, version_,
- server_connection_id);
- EXPECT_EQ(dispatcher_->NumSessions(), 1u);
-
- // Processing the same packet a second time should also be routed by the
- // dispatcher to the right connection (we expect ProcessUdpPacket to be
- // called twice, see the EXPECT_CALL above).
- ProcessReceivedPacket(std::move(packets[0]), client_address, version_,
- server_connection_id);
-}
-
-TEST_P(QuicDispatcherTestAllVersions, ProcessPackets) {
- QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
-
- EXPECT_CALL(
- *dispatcher_,
- CreateQuicSession(TestConnectionId(1), _, client_address,
- Eq(ExpectedAlpn()), _, Eq(ParsedClientHelloForTest())))
- .WillOnce(Return(ByMove(CreateSession(
- dispatcher_.get(), config_, TestConnectionId(1), client_address,
- &mock_helper_, &mock_alarm_factory_, &crypto_config_,
- QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
- EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
- ProcessUdpPacket(_, _, _))
- .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
- ValidatePacket(TestConnectionId(1), packet);
- })));
- EXPECT_CALL(*dispatcher_,
- ShouldCreateOrBufferPacketForConnection(
- ReceivedPacketInfoConnectionIdEquals(TestConnectionId(1))));
- ProcessFirstFlight(client_address, TestConnectionId(1));
-
- EXPECT_CALL(
- *dispatcher_,
- CreateQuicSession(TestConnectionId(2), _, client_address,
- Eq(ExpectedAlpn()), _, Eq(ParsedClientHelloForTest())))
- .WillOnce(Return(ByMove(CreateSession(
- dispatcher_.get(), config_, TestConnectionId(2), client_address,
- &mock_helper_, &mock_alarm_factory_, &crypto_config_,
- QuicDispatcherPeer::GetCache(dispatcher_.get()), &session2_))));
- EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session2_->connection()),
- ProcessUdpPacket(_, _, _))
- .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
- ValidatePacket(TestConnectionId(2), packet);
- })));
- EXPECT_CALL(*dispatcher_,
- ShouldCreateOrBufferPacketForConnection(
- ReceivedPacketInfoConnectionIdEquals(TestConnectionId(2))));
- ProcessFirstFlight(client_address, TestConnectionId(2));
-
- EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
- ProcessUdpPacket(_, _, _))
- .Times(1)
- .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
- ValidatePacket(TestConnectionId(1), packet);
- })));
- ProcessPacket(client_address, TestConnectionId(1), false, "data");
-}
-
-// Regression test of b/93325907.
-TEST_P(QuicDispatcherTestAllVersions, DispatcherDoesNotRejectPacketNumberZero) {
- QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
-
- EXPECT_CALL(*dispatcher_,
- CreateQuicSession(TestConnectionId(1), _, client_address,
- Eq(ExpectedAlpn()), _, _))
- .WillOnce(Return(ByMove(CreateSession(
- dispatcher_.get(), config_, TestConnectionId(1), client_address,
- &mock_helper_, &mock_alarm_factory_, &crypto_config_,
- QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
- // Verify both packets 1 and 2 are processed by connection 1.
- EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
- ProcessUdpPacket(_, _, _))
- .Times(2)
- .WillRepeatedly(
- WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
- ValidatePacket(TestConnectionId(1), packet);
- })));
- EXPECT_CALL(*dispatcher_,
- ShouldCreateOrBufferPacketForConnection(
- ReceivedPacketInfoConnectionIdEquals(TestConnectionId(1))));
- ProcessFirstFlight(client_address, TestConnectionId(1));
- // Packet number 256 with packet number length 1 would be considered as 0 in
- // dispatcher.
- ProcessPacket(client_address, TestConnectionId(1), false, version_, "", true,
- CONNECTION_ID_PRESENT, PACKET_1BYTE_PACKET_NUMBER, 256);
-}
-
-TEST_P(QuicDispatcherTestOneVersion, StatelessVersionNegotiation) {
- CreateTimeWaitListManager();
- QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
-
- EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _)).Times(0);
- EXPECT_CALL(
- *time_wait_list_manager_,
- SendVersionNegotiationPacket(TestConnectionId(1), _, _, _, _, _, _, _))
- .Times(1);
- ProcessFirstFlight(QuicVersionReservedForNegotiation(), client_address,
- TestConnectionId(1));
-}
-
-TEST_P(QuicDispatcherTestOneVersion,
- StatelessVersionNegotiationWithVeryLongConnectionId) {
- QuicConnectionId connection_id = QuicUtils::CreateRandomConnectionId(33);
- CreateTimeWaitListManager();
- QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
-
- EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _)).Times(0);
- EXPECT_CALL(*time_wait_list_manager_,
- SendVersionNegotiationPacket(connection_id, _, _, _, _, _, _, _))
- .Times(1);
- ProcessFirstFlight(QuicVersionReservedForNegotiation(), client_address,
- connection_id);
-}
-
-TEST_P(QuicDispatcherTestOneVersion,
- StatelessVersionNegotiationWithClientConnectionId) {
- CreateTimeWaitListManager();
- QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
-
- EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _)).Times(0);
- EXPECT_CALL(*time_wait_list_manager_,
- SendVersionNegotiationPacket(
- TestConnectionId(1), TestConnectionId(2), _, _, _, _, _, _))
- .Times(1);
- ProcessFirstFlight(QuicVersionReservedForNegotiation(), client_address,
- TestConnectionId(1), TestConnectionId(2));
-}
-
-TEST_P(QuicDispatcherTestOneVersion, NoVersionNegotiationWithSmallPacket) {
- CreateTimeWaitListManager();
- QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
-
- EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _)).Times(0);
- EXPECT_CALL(*time_wait_list_manager_,
- SendVersionNegotiationPacket(_, _, _, _, _, _, _, _))
- .Times(0);
- std::string chlo = SerializeCHLO() + std::string(1200, 'a');
- // Truncate to 1100 bytes of payload which results in a packet just
- // under 1200 bytes after framing, packet, and encryption overhead.
- QUICHE_DCHECK_LE(1200u, chlo.length());
- std::string truncated_chlo = chlo.substr(0, 1100);
- QUICHE_DCHECK_EQ(1100u, truncated_chlo.length());
- ProcessPacket(client_address, TestConnectionId(1), true,
- QuicVersionReservedForNegotiation(), truncated_chlo, false,
- CONNECTION_ID_PRESENT, PACKET_4BYTE_PACKET_NUMBER, 1);
-}
-
-// Disabling CHLO size validation allows the dispatcher to send version
-// negotiation packets in response to a CHLO that is otherwise too small.
-TEST_P(QuicDispatcherTestOneVersion,
- VersionNegotiationWithoutChloSizeValidation) {
- crypto_config_.set_validate_chlo_size(false);
-
- CreateTimeWaitListManager();
- QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
-
- EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _)).Times(0);
- EXPECT_CALL(*time_wait_list_manager_,
- SendVersionNegotiationPacket(_, _, _, _, _, _, _, _))
- .Times(1);
- std::string chlo = SerializeCHLO() + std::string(1200, 'a');
- // Truncate to 1100 bytes of payload which results in a packet just
- // under 1200 bytes after framing, packet, and encryption overhead.
- QUICHE_DCHECK_LE(1200u, chlo.length());
- std::string truncated_chlo = chlo.substr(0, 1100);
- QUICHE_DCHECK_EQ(1100u, truncated_chlo.length());
- ProcessPacket(client_address, TestConnectionId(1), true,
- QuicVersionReservedForNegotiation(), truncated_chlo, true,
- CONNECTION_ID_PRESENT, PACKET_4BYTE_PACKET_NUMBER, 1);
-}
-
-TEST_P(QuicDispatcherTestAllVersions, Shutdown) {
- QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
-
- EXPECT_CALL(*dispatcher_,
- CreateQuicSession(_, _, client_address, Eq(ExpectedAlpn()), _, _))
- .WillOnce(Return(ByMove(CreateSession(
- dispatcher_.get(), config_, TestConnectionId(1), client_address,
- &mock_helper_, &mock_alarm_factory_, &crypto_config_,
- QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
- EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
- ProcessUdpPacket(_, _, _))
- .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
- ValidatePacket(TestConnectionId(1), packet);
- })));
-
- EXPECT_CALL(*dispatcher_,
- ShouldCreateOrBufferPacketForConnection(
- ReceivedPacketInfoConnectionIdEquals(TestConnectionId(1))));
- ProcessFirstFlight(client_address, TestConnectionId(1));
-
- EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
- CloseConnection(QUIC_PEER_GOING_AWAY, _, _));
-
- dispatcher_->Shutdown();
-}
-
-TEST_P(QuicDispatcherTestAllVersions, TimeWaitListManager) {
- CreateTimeWaitListManager();
-
- // Create a new session.
- QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
- QuicConnectionId connection_id = TestConnectionId(1);
- EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, _, client_address,
- Eq(ExpectedAlpn()), _, _))
- .WillOnce(Return(ByMove(CreateSession(
- dispatcher_.get(), config_, connection_id, client_address,
- &mock_helper_, &mock_alarm_factory_, &crypto_config_,
- QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
- EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
- ProcessUdpPacket(_, _, _))
- .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
- ValidatePacket(TestConnectionId(1), packet);
- })));
-
- EXPECT_CALL(*dispatcher_,
- ShouldCreateOrBufferPacketForConnection(
- ReceivedPacketInfoConnectionIdEquals(TestConnectionId(1))));
- ProcessFirstFlight(client_address, connection_id);
-
- // Now close the connection, which should add it to the time wait list.
- session1_->connection()->CloseConnection(
- QUIC_INVALID_VERSION,
- "Server: Packet 2 without version flag before version negotiated.",
- ConnectionCloseBehavior::SILENT_CLOSE);
- EXPECT_TRUE(time_wait_list_manager_->IsConnectionIdInTimeWait(connection_id));
-
- // Dispatcher forwards subsequent packets for this connection_id to the time
- // wait list manager.
- EXPECT_CALL(*time_wait_list_manager_,
- ProcessPacket(_, _, connection_id, _, _, _))
- .Times(1);
- EXPECT_CALL(*time_wait_list_manager_, AddConnectionIdToTimeWait(_, _))
- .Times(0);
- ProcessPacket(client_address, connection_id, true, "data");
-}
-
-TEST_P(QuicDispatcherTestAllVersions, NoVersionPacketToTimeWaitListManager) {
- CreateTimeWaitListManager();
-
- QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
- QuicConnectionId connection_id = TestConnectionId(1);
- // Dispatcher forwards all packets for this connection_id to the time wait
- // list manager.
- EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _)).Times(0);
- EXPECT_CALL(*time_wait_list_manager_,
- ProcessPacket(_, _, connection_id, _, _, _))
- .Times(0);
- EXPECT_CALL(*time_wait_list_manager_, AddConnectionIdToTimeWait(_, _))
- .Times(0);
- EXPECT_CALL(*time_wait_list_manager_, SendPublicReset(_, _, _, _, _, _))
- .Times(1);
- ProcessPacket(client_address, connection_id, /*has_version_flag=*/false,
- "data");
-}
-
-TEST_P(QuicDispatcherTestAllVersions,
- DonotTimeWaitPacketsWithUnknownConnectionIdAndNoVersion) {
- QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
- CreateTimeWaitListManager();
-
- uint8_t short_packet[21] = {0x70, 0xa7, 0x02, 0x6b};
- QuicReceivedPacket packet(reinterpret_cast<char*>(short_packet), 21,
- QuicTime::Zero());
- uint8_t valid_size_packet[23] = {0x70, 0xa7, 0x02, 0x6c};
- QuicReceivedPacket packet2(reinterpret_cast<char*>(valid_size_packet), 23,
- QuicTime::Zero());
- EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _)).Times(0);
- EXPECT_CALL(*time_wait_list_manager_, ProcessPacket(_, _, _, _, _, _))
- .Times(0);
- EXPECT_CALL(*time_wait_list_manager_, AddConnectionIdToTimeWait(_, _))
- .Times(0);
- // Verify small packet is silently dropped.
- EXPECT_CALL(*time_wait_list_manager_, SendPublicReset(_, _, _, _, _, _))
- .Times(0);
- dispatcher_->ProcessPacket(server_address_, client_address, packet);
- EXPECT_CALL(*time_wait_list_manager_, SendPublicReset(_, _, _, _, _, _))
- .Times(1);
- dispatcher_->ProcessPacket(server_address_, client_address, packet2);
-}
-
-TEST_P(QuicDispatcherTestOneVersion, DropPacketWithInvalidFlags) {
- QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
- CreateTimeWaitListManager();
- uint8_t all_zero_packet[1200] = {};
- QuicReceivedPacket packet(reinterpret_cast<char*>(all_zero_packet),
- sizeof(all_zero_packet), QuicTime::Zero());
- EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _)).Times(0);
- EXPECT_CALL(*time_wait_list_manager_, ProcessPacket(_, _, _, _, _, _))
- .Times(0);
- EXPECT_CALL(*time_wait_list_manager_, AddConnectionIdToTimeWait(_, _))
- .Times(0);
- EXPECT_CALL(*time_wait_list_manager_, SendPublicReset(_, _, _, _, _, _))
- .Times(0);
- dispatcher_->ProcessPacket(server_address_, client_address, packet);
-}
-
-TEST_P(QuicDispatcherTestAllVersions, LimitResetsToSameClientAddress) {
- CreateTimeWaitListManager();
-
- QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
- QuicSocketAddress client_address2(QuicIpAddress::Loopback4(), 2);
- 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);
- }
- ProcessPacket(client_address, connection_id, /*has_version_flag=*/false,
- "data");
- ProcessPacket(client_address, connection_id, /*has_version_flag=*/false,
- "data2");
- ProcessPacket(client_address, connection_id, /*has_version_flag=*/false,
- "data3");
-
- EXPECT_CALL(*time_wait_list_manager_, SendPublicReset(_, _, _, _, _, _))
- .Times(2);
- ProcessPacket(client_address2, connection_id, /*has_version_flag=*/false,
- "data");
- ProcessPacket(client_address3, connection_id, /*has_version_flag=*/false,
- "data");
-}
-
-TEST_P(QuicDispatcherTestAllVersions,
- StopSendingResetOnTooManyRecentAddresses) {
- SetQuicFlag(FLAGS_quic_max_recent_stateless_reset_addresses, 2);
- const size_t kTestLifeTimeMs = 10;
- SetQuicFlag(FLAGS_quic_recent_stateless_reset_addresses_lifetime_ms,
- kTestLifeTimeMs);
- CreateTimeWaitListManager();
-
- QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
- QuicSocketAddress client_address2(QuicIpAddress::Loopback4(), 2);
- QuicSocketAddress client_address3(QuicIpAddress::Loopback6(), 1);
- QuicConnectionId connection_id = TestConnectionId(1);
-
- EXPECT_CALL(*time_wait_list_manager_, SendPublicReset(_, _, _, _, _, _))
- .Times(2);
- EXPECT_FALSE(GetClearResetAddressesAlarm()->IsSet());
- ProcessPacket(client_address, connection_id, /*has_version_flag=*/false,
- "data");
- 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());
- }
- // 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);
- }
- 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);
- }
- ProcessPacket(client_address, connection_id, /*has_version_flag=*/false,
- "data");
- ProcessPacket(client_address2, connection_id, /*has_version_flag=*/false,
- "data");
- ProcessPacket(client_address3, connection_id, /*has_version_flag=*/false,
- "data");
-}
-
-// Makes sure nine-byte connection IDs are replaced by 8-byte ones.
-TEST_P(QuicDispatcherTestAllVersions, LongConnectionIdLengthReplaced) {
- if (!version_.AllowsVariableLengthConnectionIds()) {
- // When variable length connection IDs are not supported, the connection
- // fails. See StrayPacketTruncatedConnectionId.
- return;
- }
- QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
-
- QuicConnectionId bad_connection_id = TestConnectionIdNineBytesLong(2);
- QuicConnectionId fixed_connection_id =
- QuicUtils::CreateReplacementConnectionId(bad_connection_id);
-
- EXPECT_CALL(*dispatcher_,
- CreateQuicSession(fixed_connection_id, _, client_address,
- Eq(ExpectedAlpn()), _, _))
- .WillOnce(Return(ByMove(CreateSession(
- dispatcher_.get(), config_, fixed_connection_id, client_address,
- &mock_helper_, &mock_alarm_factory_, &crypto_config_,
- QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
- EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
- ProcessUdpPacket(_, _, _))
- .WillOnce(WithArg<2>(
- Invoke([this, bad_connection_id](const QuicEncryptedPacket& packet) {
- ValidatePacket(bad_connection_id, packet);
- })));
- EXPECT_CALL(*dispatcher_,
- ShouldCreateOrBufferPacketForConnection(
- ReceivedPacketInfoConnectionIdEquals(bad_connection_id)));
- ProcessFirstFlight(client_address, bad_connection_id);
-}
-
-// Makes sure zero-byte connection IDs are replaced by 8-byte ones.
-TEST_P(QuicDispatcherTestAllVersions, InvalidShortConnectionIdLengthReplaced) {
- if (!version_.AllowsVariableLengthConnectionIds()) {
- // When variable length connection IDs are not supported, the connection
- // fails. See StrayPacketTruncatedConnectionId.
- return;
- }
- QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
-
- QuicConnectionId bad_connection_id = EmptyQuicConnectionId();
- QuicConnectionId fixed_connection_id =
- QuicUtils::CreateReplacementConnectionId(bad_connection_id);
-
- // Disable validation of invalid short connection IDs.
- dispatcher_->SetAllowShortInitialServerConnectionIds(true);
- // Note that StrayPacketTruncatedConnectionId covers the case where the
- // validation is still enabled.
-
- EXPECT_CALL(*dispatcher_,
- CreateQuicSession(fixed_connection_id, _, client_address,
- Eq(ExpectedAlpn()), _, _))
- .WillOnce(Return(ByMove(CreateSession(
- dispatcher_.get(), config_, fixed_connection_id, client_address,
- &mock_helper_, &mock_alarm_factory_, &crypto_config_,
- QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
- EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
- ProcessUdpPacket(_, _, _))
- .WillOnce(WithArg<2>(
- Invoke([this, bad_connection_id](const QuicEncryptedPacket& packet) {
- ValidatePacket(bad_connection_id, packet);
- })));
- EXPECT_CALL(*dispatcher_,
- ShouldCreateOrBufferPacketForConnection(
- ReceivedPacketInfoConnectionIdEquals(bad_connection_id)));
- ProcessFirstFlight(client_address, bad_connection_id);
-}
-
-// Makes sure TestConnectionId(1) creates a new connection and
-// TestConnectionIdNineBytesLong(2) gets replaced.
-TEST_P(QuicDispatcherTestAllVersions, MixGoodAndBadConnectionIdLengthPackets) {
- if (!version_.AllowsVariableLengthConnectionIds()) {
- return;
- }
-
- QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
- QuicConnectionId bad_connection_id = TestConnectionIdNineBytesLong(2);
- QuicConnectionId fixed_connection_id =
- QuicUtils::CreateReplacementConnectionId(bad_connection_id);
-
- EXPECT_CALL(*dispatcher_,
- CreateQuicSession(TestConnectionId(1), _, client_address,
- Eq(ExpectedAlpn()), _, _))
- .WillOnce(Return(ByMove(CreateSession(
- dispatcher_.get(), config_, TestConnectionId(1), client_address,
- &mock_helper_, &mock_alarm_factory_, &crypto_config_,
- QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
- EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
- ProcessUdpPacket(_, _, _))
- .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
- ValidatePacket(TestConnectionId(1), packet);
- })));
- EXPECT_CALL(*dispatcher_,
- ShouldCreateOrBufferPacketForConnection(
- ReceivedPacketInfoConnectionIdEquals(TestConnectionId(1))));
- ProcessFirstFlight(client_address, TestConnectionId(1));
-
- EXPECT_CALL(*dispatcher_,
- CreateQuicSession(fixed_connection_id, _, client_address,
- Eq(ExpectedAlpn()), _, _))
- .WillOnce(Return(ByMove(CreateSession(
- dispatcher_.get(), config_, fixed_connection_id, client_address,
- &mock_helper_, &mock_alarm_factory_, &crypto_config_,
- QuicDispatcherPeer::GetCache(dispatcher_.get()), &session2_))));
- EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session2_->connection()),
- ProcessUdpPacket(_, _, _))
- .WillOnce(WithArg<2>(
- Invoke([this, bad_connection_id](const QuicEncryptedPacket& packet) {
- ValidatePacket(bad_connection_id, packet);
- })));
- EXPECT_CALL(*dispatcher_,
- ShouldCreateOrBufferPacketForConnection(
- ReceivedPacketInfoConnectionIdEquals(bad_connection_id)));
- ProcessFirstFlight(client_address, bad_connection_id);
-
- EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
- ProcessUdpPacket(_, _, _))
- .Times(1)
- .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
- ValidatePacket(TestConnectionId(1), packet);
- })));
- ProcessPacket(client_address, TestConnectionId(1), false, "data");
-}
-
-TEST_P(QuicDispatcherTestAllVersions, ProcessPacketWithZeroPort) {
- CreateTimeWaitListManager();
-
- QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 0);
-
- // dispatcher_ should drop this packet.
- EXPECT_CALL(*dispatcher_, CreateQuicSession(TestConnectionId(1), _,
- client_address, _, _, _))
- .Times(0);
- EXPECT_CALL(*time_wait_list_manager_, ProcessPacket(_, _, _, _, _, _))
- .Times(0);
- EXPECT_CALL(*time_wait_list_manager_, AddConnectionIdToTimeWait(_, _))
- .Times(0);
- ProcessPacket(client_address, TestConnectionId(1), /*has_version_flag=*/true,
- "data");
-}
-
-TEST_P(QuicDispatcherTestAllVersions, ProcessPacketWithBlockedPort) {
- CreateTimeWaitListManager();
-
- QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 17);
-
- // dispatcher_ should drop this packet.
- EXPECT_CALL(*dispatcher_, CreateQuicSession(TestConnectionId(1), _,
- client_address, _, _, _))
- .Times(0);
- EXPECT_CALL(*time_wait_list_manager_, ProcessPacket(_, _, _, _, _, _))
- .Times(0);
- EXPECT_CALL(*time_wait_list_manager_, AddConnectionIdToTimeWait(_, _))
- .Times(0);
- ProcessPacket(client_address, TestConnectionId(1), /*has_version_flag=*/true,
- "data");
-}
-
-TEST_P(QuicDispatcherTestAllVersions, ProcessPacketWithNonBlockedPort) {
- CreateTimeWaitListManager();
-
- // Port 443 must not be blocked because it might be useful for proxies to send
- // proxied traffic with source port 443 as that allows building a full QUIC
- // proxy using a single UDP socket.
- QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 443);
-
- // dispatcher_ should not drop this packet.
- EXPECT_CALL(*dispatcher_,
- CreateQuicSession(TestConnectionId(1), _, client_address,
- Eq(ExpectedAlpn()), _, _))
- .WillOnce(Return(ByMove(CreateSession(
- dispatcher_.get(), config_, TestConnectionId(1), client_address,
- &mock_helper_, &mock_alarm_factory_, &crypto_config_,
- QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
- ProcessFirstFlight(client_address, TestConnectionId(1));
-}
-
-TEST_P(QuicDispatcherTestAllVersions,
- DropPacketWithKnownVersionAndInvalidShortInitialConnectionId) {
- if (!version_.AllowsVariableLengthConnectionIds()) {
- return;
- }
- CreateTimeWaitListManager();
-
- QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
-
- // dispatcher_ should drop this packet.
- EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _)).Times(0);
- EXPECT_CALL(*time_wait_list_manager_, ProcessPacket(_, _, _, _, _, _))
- .Times(0);
- EXPECT_CALL(*time_wait_list_manager_, AddConnectionIdToTimeWait(_, _))
- .Times(0);
- ProcessFirstFlight(client_address, EmptyQuicConnectionId());
-}
-
-TEST_P(QuicDispatcherTestAllVersions,
- DropPacketWithKnownVersionAndInvalidInitialConnectionId) {
- CreateTimeWaitListManager();
-
- QuicSocketAddress server_address;
- QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
-
- // dispatcher_ should drop this packet with invalid connection ID.
- EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _)).Times(0);
- EXPECT_CALL(*time_wait_list_manager_, ProcessPacket(_, _, _, _, _, _))
- .Times(0);
- EXPECT_CALL(*time_wait_list_manager_, AddConnectionIdToTimeWait(_, _))
- .Times(0);
- absl::string_view cid_str = "123456789abcdefg123456789abcdefg";
- QuicConnectionId invalid_connection_id(cid_str.data(), cid_str.length());
- QuicReceivedPacket packet("packet", 6, QuicTime::Zero());
- ReceivedPacketInfo packet_info(server_address, client_address, packet);
- packet_info.version_flag = true;
- packet_info.version = version_;
- packet_info.destination_connection_id = invalid_connection_id;
-
- ASSERT_TRUE(dispatcher_->MaybeDispatchPacket(packet_info));
-}
-
-void QuicDispatcherTestBase::
- TestVersionNegotiationForUnknownVersionInvalidShortInitialConnectionId(
- const QuicConnectionId& server_connection_id,
- const QuicConnectionId& client_connection_id) {
- CreateTimeWaitListManager();
-
- QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
-
- EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _)).Times(0);
- EXPECT_CALL(*time_wait_list_manager_,
- SendVersionNegotiationPacket(
- server_connection_id, client_connection_id,
- /*ietf_quic=*/true,
- /*use_length_prefix=*/true, _, _, client_address, _))
- .Times(1);
- ProcessFirstFlight(ParsedQuicVersion::ReservedForNegotiation(),
- client_address, server_connection_id,
- client_connection_id);
-}
-
-TEST_P(QuicDispatcherTestOneVersion,
- VersionNegotiationForUnknownVersionInvalidShortInitialConnectionId) {
- TestVersionNegotiationForUnknownVersionInvalidShortInitialConnectionId(
- EmptyQuicConnectionId(), EmptyQuicConnectionId());
-}
-
-TEST_P(QuicDispatcherTestOneVersion,
- VersionNegotiationForUnknownVersionInvalidShortInitialConnectionId2) {
- char server_connection_id_bytes[3] = {1, 2, 3};
- QuicConnectionId server_connection_id(server_connection_id_bytes,
- sizeof(server_connection_id_bytes));
- TestVersionNegotiationForUnknownVersionInvalidShortInitialConnectionId(
- server_connection_id, EmptyQuicConnectionId());
-}
-
-TEST_P(QuicDispatcherTestOneVersion,
- VersionNegotiationForUnknownVersionInvalidShortInitialConnectionId3) {
- char client_connection_id_bytes[8] = {1, 2, 3, 4, 5, 6, 7, 8};
- QuicConnectionId client_connection_id(client_connection_id_bytes,
- sizeof(client_connection_id_bytes));
- TestVersionNegotiationForUnknownVersionInvalidShortInitialConnectionId(
- EmptyQuicConnectionId(), client_connection_id);
-}
-
-TEST_P(QuicDispatcherTestOneVersion, VersionsChangeInFlight) {
- VerifyVersionNotSupported(QuicVersionReservedForNegotiation());
- for (ParsedQuicVersion version : CurrentSupportedVersions()) {
- VerifyVersionSupported(version);
- QuicDisableVersion(version);
- VerifyVersionNotSupported(version);
- QuicEnableVersion(version);
- VerifyVersionSupported(version);
- }
-}
-
-TEST_P(QuicDispatcherTestOneVersion,
- RejectDeprecatedVersionDraft28WithVersionNegotiation) {
- QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
- CreateTimeWaitListManager();
- uint8_t packet[kMinPacketSizeForVersionNegotiation] = {
- 0xC0, 0xFF, 0x00, 0x00, 28, /*destination connection ID length*/ 0x08};
- QuicReceivedPacket received_packet(reinterpret_cast<char*>(packet),
- ABSL_ARRAYSIZE(packet), QuicTime::Zero());
- EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _)).Times(0);
- EXPECT_CALL(
- *time_wait_list_manager_,
- SendVersionNegotiationPacket(_, _, /*ietf_quic=*/true,
- /*use_length_prefix=*/true, _, _, _, _))
- .Times(1);
- dispatcher_->ProcessPacket(server_address_, client_address, received_packet);
-}
-
-TEST_P(QuicDispatcherTestOneVersion,
- RejectDeprecatedVersionDraft27WithVersionNegotiation) {
- QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
- CreateTimeWaitListManager();
- uint8_t packet[kMinPacketSizeForVersionNegotiation] = {
- 0xC0, 0xFF, 0x00, 0x00, 27, /*destination connection ID length*/ 0x08};
- QuicReceivedPacket received_packet(reinterpret_cast<char*>(packet),
- ABSL_ARRAYSIZE(packet), QuicTime::Zero());
- EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _)).Times(0);
- EXPECT_CALL(
- *time_wait_list_manager_,
- SendVersionNegotiationPacket(_, _, /*ietf_quic=*/true,
- /*use_length_prefix=*/true, _, _, _, _))
- .Times(1);
- dispatcher_->ProcessPacket(server_address_, client_address, received_packet);
-}
-
-TEST_P(QuicDispatcherTestOneVersion,
- RejectDeprecatedVersionDraft25WithVersionNegotiation) {
- QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
- CreateTimeWaitListManager();
- uint8_t packet[kMinPacketSizeForVersionNegotiation] = {
- 0xC0, 0xFF, 0x00, 0x00, 25, /*destination connection ID length*/ 0x08};
- QuicReceivedPacket received_packet(reinterpret_cast<char*>(packet),
- ABSL_ARRAYSIZE(packet), QuicTime::Zero());
- EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _)).Times(0);
- EXPECT_CALL(
- *time_wait_list_manager_,
- SendVersionNegotiationPacket(_, _, /*ietf_quic=*/true,
- /*use_length_prefix=*/true, _, _, _, _))
- .Times(1);
- dispatcher_->ProcessPacket(server_address_, client_address, received_packet);
-}
-
-TEST_P(QuicDispatcherTestOneVersion,
- RejectDeprecatedVersionT050WithVersionNegotiation) {
- QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
- CreateTimeWaitListManager();
- uint8_t packet[kMinPacketSizeForVersionNegotiation] = {
- 0xC0, 'T', '0', '5', '0', /*destination connection ID length*/ 0x08};
- QuicReceivedPacket received_packet(reinterpret_cast<char*>(packet),
- ABSL_ARRAYSIZE(packet), QuicTime::Zero());
- EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _)).Times(0);
- EXPECT_CALL(
- *time_wait_list_manager_,
- SendVersionNegotiationPacket(_, _, /*ietf_quic=*/true,
- /*use_length_prefix=*/true, _, _, _, _))
- .Times(1);
- dispatcher_->ProcessPacket(server_address_, client_address, received_packet);
-}
-
-TEST_P(QuicDispatcherTestOneVersion,
- RejectDeprecatedVersionQ049WithVersionNegotiation) {
- QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
- CreateTimeWaitListManager();
- uint8_t packet[kMinPacketSizeForVersionNegotiation] = {
- 0xC0, 'Q', '0', '4', '9', /*destination connection ID length*/ 0x08};
- QuicReceivedPacket received_packet(reinterpret_cast<char*>(packet),
- ABSL_ARRAYSIZE(packet), QuicTime::Zero());
- EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _)).Times(0);
- EXPECT_CALL(
- *time_wait_list_manager_,
- SendVersionNegotiationPacket(_, _, /*ietf_quic=*/true,
- /*use_length_prefix=*/true, _, _, _, _))
- .Times(1);
- dispatcher_->ProcessPacket(server_address_, client_address, received_packet);
-}
-
-TEST_P(QuicDispatcherTestOneVersion,
- RejectDeprecatedVersionQ048WithVersionNegotiation) {
- QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
- CreateTimeWaitListManager();
- uint8_t packet[kMinPacketSizeForVersionNegotiation] = {
- 0xC0, 'Q', '0', '4', '8', /*connection ID length byte*/ 0x50};
- QuicReceivedPacket received_packet(reinterpret_cast<char*>(packet),
- ABSL_ARRAYSIZE(packet), QuicTime::Zero());
- EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _)).Times(0);
- EXPECT_CALL(
- *time_wait_list_manager_,
- SendVersionNegotiationPacket(_, _, /*ietf_quic=*/true,
- /*use_length_prefix=*/false, _, _, _, _))
- .Times(1);
- dispatcher_->ProcessPacket(server_address_, client_address, received_packet);
-}
-
-TEST_P(QuicDispatcherTestOneVersion,
- RejectDeprecatedVersionQ047WithVersionNegotiation) {
- QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
- CreateTimeWaitListManager();
- uint8_t packet[kMinPacketSizeForVersionNegotiation] = {
- 0xC0, 'Q', '0', '4', '7', /*connection ID length byte*/ 0x50};
- QuicReceivedPacket received_packet(reinterpret_cast<char*>(packet),
- ABSL_ARRAYSIZE(packet), QuicTime::Zero());
- EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _)).Times(0);
- EXPECT_CALL(
- *time_wait_list_manager_,
- SendVersionNegotiationPacket(_, _, /*ietf_quic=*/true,
- /*use_length_prefix=*/false, _, _, _, _))
- .Times(1);
- dispatcher_->ProcessPacket(server_address_, client_address, received_packet);
-}
-
-TEST_P(QuicDispatcherTestOneVersion,
- RejectDeprecatedVersionQ045WithVersionNegotiation) {
- QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
- CreateTimeWaitListManager();
- uint8_t packet[kMinPacketSizeForVersionNegotiation] = {
- 0xC0, 'Q', '0', '4', '5', /*connection ID length byte*/ 0x50};
- QuicReceivedPacket received_packet(reinterpret_cast<char*>(packet),
- ABSL_ARRAYSIZE(packet), QuicTime::Zero());
- EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _)).Times(0);
- EXPECT_CALL(
- *time_wait_list_manager_,
- SendVersionNegotiationPacket(_, _, /*ietf_quic=*/true,
- /*use_length_prefix=*/false, _, _, _, _))
- .Times(1);
- dispatcher_->ProcessPacket(server_address_, client_address, received_packet);
-}
-
-TEST_P(QuicDispatcherTestOneVersion,
- RejectDeprecatedVersionQ044WithVersionNegotiation) {
- QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
- CreateTimeWaitListManager();
- uint8_t packet44[kMinPacketSizeForVersionNegotiation] = {
- 0xFF, 'Q', '0', '4', '4', /*connection ID length byte*/ 0x50};
- QuicReceivedPacket received_packet44(reinterpret_cast<char*>(packet44),
- kMinPacketSizeForVersionNegotiation,
- QuicTime::Zero());
- EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _)).Times(0);
- EXPECT_CALL(
- *time_wait_list_manager_,
- SendVersionNegotiationPacket(_, _, /*ietf_quic=*/true,
- /*use_length_prefix=*/false, _, _, _, _))
- .Times(1);
- dispatcher_->ProcessPacket(server_address_, client_address,
- received_packet44);
-}
-
-TEST_P(QuicDispatcherTestOneVersion,
- RejectDeprecatedVersionT051WithVersionNegotiation) {
- QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
- CreateTimeWaitListManager();
- uint8_t packet[kMinPacketSizeForVersionNegotiation] = {
- 0xFF, 'T', '0', '5', '1', /*destination connection ID length*/ 0x08};
- QuicReceivedPacket received_packet(reinterpret_cast<char*>(packet),
- kMinPacketSizeForVersionNegotiation,
- QuicTime::Zero());
- EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _)).Times(0);
- EXPECT_CALL(
- *time_wait_list_manager_,
- SendVersionNegotiationPacket(_, _, /*ietf_quic=*/true,
- /*use_length_prefix=*/true, _, _, _, _))
- .Times(1);
- dispatcher_->ProcessPacket(server_address_, client_address, received_packet);
-}
-
-static_assert(quic::SupportedVersions().size() == 6u,
- "Please add new RejectDeprecatedVersion tests above this assert "
- "when deprecating versions");
-
-TEST_P(QuicDispatcherTestOneVersion, VersionNegotiationProbe) {
- QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
- CreateTimeWaitListManager();
- char packet[1200];
- char destination_connection_id_bytes[] = {0x56, 0x4e, 0x20, 0x70,
- 0x6c, 0x7a, 0x20, 0x21};
- EXPECT_TRUE(QuicFramer::WriteClientVersionNegotiationProbePacket(
- packet, sizeof(packet), destination_connection_id_bytes,
- sizeof(destination_connection_id_bytes)));
- QuicEncryptedPacket encrypted(packet, sizeof(packet), false);
- std::unique_ptr<QuicReceivedPacket> received_packet(
- ConstructReceivedPacket(encrypted, mock_helper_.GetClock()->Now()));
- QuicConnectionId client_connection_id = EmptyQuicConnectionId();
- QuicConnectionId server_connection_id(
- destination_connection_id_bytes, sizeof(destination_connection_id_bytes));
- EXPECT_CALL(*time_wait_list_manager_,
- SendVersionNegotiationPacket(
- server_connection_id, client_connection_id,
- /*ietf_quic=*/true, /*use_length_prefix=*/true, _, _, _, _))
- .Times(1);
- EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _)).Times(0);
-
- dispatcher_->ProcessPacket(server_address_, client_address, *received_packet);
-}
-
-// Testing packet writer that saves all packets instead of sending them.
-// Useful for tests that need access to sent packets.
-class SavingWriter : public QuicPacketWriterWrapper {
- public:
- bool IsWriteBlocked() const override { return false; }
-
- WriteResult WritePacket(const char* buffer, size_t buf_len,
- const QuicIpAddress& /*self_client_address*/,
- const QuicSocketAddress& /*peer_client_address*/,
- PerPacketOptions* /*options*/) override {
- packets_.push_back(
- QuicEncryptedPacket(buffer, buf_len, /*owns_buffer=*/false).Clone());
- return WriteResult(WRITE_STATUS_OK, buf_len);
- }
-
- std::vector<std::unique_ptr<QuicEncryptedPacket>>* packets() {
- return &packets_;
- }
-
- private:
- std::vector<std::unique_ptr<QuicEncryptedPacket>> packets_;
-};
-
-TEST_P(QuicDispatcherTestOneVersion, VersionNegotiationProbeEndToEnd) {
- SavingWriter* saving_writer = new SavingWriter();
- // dispatcher_ takes ownership of saving_writer.
- QuicDispatcherPeer::UseWriter(dispatcher_.get(), saving_writer);
-
- QuicTimeWaitListManager* time_wait_list_manager = new QuicTimeWaitListManager(
- saving_writer, dispatcher_.get(), mock_helper_.GetClock(),
- &mock_alarm_factory_);
- // dispatcher_ takes ownership of time_wait_list_manager.
- QuicDispatcherPeer::SetTimeWaitListManager(dispatcher_.get(),
- time_wait_list_manager);
- char packet[1200] = {};
- char destination_connection_id_bytes[] = {0x56, 0x4e, 0x20, 0x70,
- 0x6c, 0x7a, 0x20, 0x21};
- EXPECT_TRUE(QuicFramer::WriteClientVersionNegotiationProbePacket(
- packet, sizeof(packet), destination_connection_id_bytes,
- sizeof(destination_connection_id_bytes)));
- QuicEncryptedPacket encrypted(packet, sizeof(packet), false);
- std::unique_ptr<QuicReceivedPacket> received_packet(
- ConstructReceivedPacket(encrypted, mock_helper_.GetClock()->Now()));
- EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _)).Times(0);
-
- QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
- dispatcher_->ProcessPacket(server_address_, client_address, *received_packet);
- ASSERT_EQ(1u, saving_writer->packets()->size());
-
- char source_connection_id_bytes[255] = {};
- uint8_t source_connection_id_length = sizeof(source_connection_id_bytes);
- std::string detailed_error = "foobar";
- EXPECT_TRUE(QuicFramer::ParseServerVersionNegotiationProbeResponse(
- (*(saving_writer->packets()))[0]->data(),
- (*(saving_writer->packets()))[0]->length(), source_connection_id_bytes,
- &source_connection_id_length, &detailed_error));
- EXPECT_EQ("", detailed_error);
-
- // The source connection ID of the probe response should match the
- // destination connection ID of the probe request.
- quiche::test::CompareCharArraysWithHexError(
- "parsed probe", source_connection_id_bytes, source_connection_id_length,
- destination_connection_id_bytes, sizeof(destination_connection_id_bytes));
-}
-
-TEST_P(QuicDispatcherTestOneVersion, AndroidConformanceTest) {
- // WARNING: do not remove or modify this test without making sure that we
- // still have adequate coverage for the Android conformance test.
- SavingWriter* saving_writer = new SavingWriter();
- // dispatcher_ takes ownership of saving_writer.
- QuicDispatcherPeer::UseWriter(dispatcher_.get(), saving_writer);
-
- QuicTimeWaitListManager* time_wait_list_manager = new QuicTimeWaitListManager(
- saving_writer, dispatcher_.get(), mock_helper_.GetClock(),
- &mock_alarm_factory_);
- // dispatcher_ takes ownership of time_wait_list_manager.
- QuicDispatcherPeer::SetTimeWaitListManager(dispatcher_.get(),
- time_wait_list_manager);
- // clang-format off
- static const unsigned char packet[1200] = {
- // Android UDP network conformance test packet as it was after this change:
- // https://android-review.googlesource.com/c/platform/cts/+/1454515
- 0xc0, // long header
- 0xaa, 0xda, 0xca, 0xca, // reserved-space version number
- 0x08, // destination connection ID length
- 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, // 8-byte connection ID
- 0x00, // source connection ID length
- };
- // clang-format on
-
- QuicEncryptedPacket encrypted(reinterpret_cast<const char*>(packet),
- sizeof(packet), false);
- std::unique_ptr<QuicReceivedPacket> received_packet(
- ConstructReceivedPacket(encrypted, mock_helper_.GetClock()->Now()));
- EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _)).Times(0);
-
- QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
- dispatcher_->ProcessPacket(server_address_, client_address, *received_packet);
- ASSERT_EQ(1u, saving_writer->packets()->size());
-
- // The Android UDP network conformance test directly checks that these bytes
- // of the response match the connection ID that was sent.
- ASSERT_GE((*(saving_writer->packets()))[0]->length(), 15u);
- quiche::test::CompareCharArraysWithHexError(
- "response connection ID", &(*(saving_writer->packets()))[0]->data()[7], 8,
- reinterpret_cast<const char*>(&packet[6]), 8);
-}
-
-TEST_P(QuicDispatcherTestOneVersion, AndroidConformanceTestOld) {
- // WARNING: this test covers an old Android Conformance Test that has now been
- // changed, but it'll take time for the change to propagate through the
- // Android ecosystem. The Android team has asked us to keep this test
- // supported until at least 2021-03-31. After that date, and when we drop
- // support for sending QUIC version negotiation packets using the legacy
- // Google QUIC format (Q001-Q043), then we can delete this test.
- // TODO(dschinazi) delete this test after 2021-03-31
- SavingWriter* saving_writer = new SavingWriter();
- // dispatcher_ takes ownership of saving_writer.
- QuicDispatcherPeer::UseWriter(dispatcher_.get(), saving_writer);
-
- QuicTimeWaitListManager* time_wait_list_manager = new QuicTimeWaitListManager(
- saving_writer, dispatcher_.get(), mock_helper_.GetClock(),
- &mock_alarm_factory_);
- // dispatcher_ takes ownership of time_wait_list_manager.
- QuicDispatcherPeer::SetTimeWaitListManager(dispatcher_.get(),
- time_wait_list_manager);
- // clang-format off
- static const unsigned char packet[1200] = {
- // Android UDP network conformance test packet as it was after this change:
- // https://android-review.googlesource.com/c/platform/cts/+/1104285
- // but before this change:
- // https://android-review.googlesource.com/c/platform/cts/+/1454515
- 0x0d, // public flags: version, 8-byte connection ID, 1-byte packet number
- 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, // 8-byte connection ID
- 0xaa, 0xda, 0xca, 0xaa, // reserved-space version number
- 0x01, // 1-byte packet number
- 0x00, // private flags
- 0x07, // PING frame
- };
- // clang-format on
-
- QuicEncryptedPacket encrypted(reinterpret_cast<const char*>(packet),
- sizeof(packet), false);
- std::unique_ptr<QuicReceivedPacket> received_packet(
- ConstructReceivedPacket(encrypted, mock_helper_.GetClock()->Now()));
- EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _)).Times(0);
-
- QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
- dispatcher_->ProcessPacket(server_address_, client_address, *received_packet);
- ASSERT_EQ(1u, saving_writer->packets()->size());
-
- // The Android UDP network conformance test directly checks that bytes 1-9
- // of the response match the connection ID that was sent.
- static const char connection_id_bytes[] = {0x71, 0x72, 0x73, 0x74,
- 0x75, 0x76, 0x77, 0x78};
- ASSERT_GE((*(saving_writer->packets()))[0]->length(),
- 1u + sizeof(connection_id_bytes));
- quiche::test::CompareCharArraysWithHexError(
- "response connection ID", &(*(saving_writer->packets()))[0]->data()[1],
- sizeof(connection_id_bytes), connection_id_bytes,
- sizeof(connection_id_bytes));
-}
-
-TEST_P(QuicDispatcherTestAllVersions, DoNotProcessSmallPacket) {
- CreateTimeWaitListManager();
- QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
-
- EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _)).Times(0);
- EXPECT_CALL(*time_wait_list_manager_, SendPacket(_, _, _)).Times(0);
- EXPECT_CALL(*time_wait_list_manager_, AddConnectionIdToTimeWait(_, _))
- .Times(0);
- ProcessPacket(client_address, TestConnectionId(1), /*has_version_flag=*/true,
- version_, SerializeCHLO(), /*full_padding=*/false,
- CONNECTION_ID_PRESENT, PACKET_4BYTE_PACKET_NUMBER, 1);
-}
-
-TEST_P(QuicDispatcherTestAllVersions, ProcessSmallCoalescedPacket) {
- CreateTimeWaitListManager();
- QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
-
- EXPECT_CALL(*time_wait_list_manager_, SendPacket(_, _, _)).Times(0);
-
- // clang-format off
- uint8_t coalesced_packet[1200] = {
- // first coalesced packet
- // public flags (long header with packet type INITIAL and
- // 4-byte packet number)
- 0xC3,
- // version
- 'Q', '0', '9', '9',
- // destination connection ID length
- 0x08,
- // destination connection ID
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // source connection ID length
- 0x00,
- // long header packet length
- 0x05,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
- // Padding
- 0x00,
- // second coalesced packet
- // public flags (long header with packet type ZERO_RTT_PROTECTED and
- // 4-byte packet number)
- 0xC3,
- // version
- 'Q', '0', '9', '9',
- // destination connection ID length
- 0x08,
- // destination connection ID
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // source connection ID length
- 0x00,
- // long header packet length
- 0x1E,
- // packet number
- 0x12, 0x34, 0x56, 0x79,
- };
- // clang-format on
- QuicReceivedPacket packet(reinterpret_cast<char*>(coalesced_packet), 1200,
- QuicTime::Zero());
- dispatcher_->ProcessPacket(server_address_, client_address, packet);
-}
-
-TEST_P(QuicDispatcherTestAllVersions, StopAcceptingNewConnections) {
- QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
-
- EXPECT_CALL(*dispatcher_,
- CreateQuicSession(TestConnectionId(1), _, client_address,
- Eq(ExpectedAlpn()), _, _))
- .WillOnce(Return(ByMove(CreateSession(
- dispatcher_.get(), config_, TestConnectionId(1), client_address,
- &mock_helper_, &mock_alarm_factory_, &crypto_config_,
- QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
- EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
- ProcessUdpPacket(_, _, _))
- .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
- ValidatePacket(TestConnectionId(1), packet);
- })));
- ProcessFirstFlight(client_address, TestConnectionId(1));
-
- dispatcher_->StopAcceptingNewConnections();
- EXPECT_FALSE(dispatcher_->accept_new_connections());
-
- // No more new connections afterwards.
- EXPECT_CALL(*dispatcher_,
- CreateQuicSession(TestConnectionId(2), _, client_address,
- Eq(ExpectedAlpn()), _, _))
- .Times(0u);
- ProcessFirstFlight(client_address, TestConnectionId(2));
-
- // Existing connections should be able to continue.
- EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
- ProcessUdpPacket(_, _, _))
- .Times(1u)
- .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
- ValidatePacket(TestConnectionId(1), packet);
- })));
- ProcessPacket(client_address, TestConnectionId(1), false, "data");
-}
-
-TEST_P(QuicDispatcherTestAllVersions, StartAcceptingNewConnections) {
- dispatcher_->StopAcceptingNewConnections();
- QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
-
- // No more new connections afterwards.
- EXPECT_CALL(*dispatcher_,
- CreateQuicSession(TestConnectionId(2), _, client_address,
- Eq(ExpectedAlpn()), _, _))
- .Times(0u);
- ProcessFirstFlight(client_address, TestConnectionId(2));
-
- dispatcher_->StartAcceptingNewConnections();
- EXPECT_TRUE(dispatcher_->accept_new_connections());
-
- EXPECT_CALL(*dispatcher_,
- CreateQuicSession(TestConnectionId(1), _, client_address,
- Eq(ExpectedAlpn()), _, _))
- .WillOnce(Return(ByMove(CreateSession(
- dispatcher_.get(), config_, TestConnectionId(1), client_address,
- &mock_helper_, &mock_alarm_factory_, &crypto_config_,
- QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
- EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
- ProcessUdpPacket(_, _, _))
- .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
- ValidatePacket(TestConnectionId(1), packet);
- })));
- ProcessFirstFlight(client_address, TestConnectionId(1));
-}
-
-TEST_P(QuicDispatcherTestOneVersion, SelectAlpn) {
- EXPECT_EQ(QuicDispatcherPeer::SelectAlpn(dispatcher_.get(), {}), "");
- EXPECT_EQ(QuicDispatcherPeer::SelectAlpn(dispatcher_.get(), {""}), "");
- EXPECT_EQ(QuicDispatcherPeer::SelectAlpn(dispatcher_.get(), {"hq"}), "hq");
- // Q033 is no longer supported but Q050 is.
- QuicEnableVersion(ParsedQuicVersion::Q050());
- EXPECT_EQ(
- QuicDispatcherPeer::SelectAlpn(dispatcher_.get(), {"h3-Q033", "h3-Q050"}),
- "h3-Q050");
-}
-
-// Verify the stopgap test: Packets with truncated connection IDs should be
-// dropped.
-class QuicDispatcherTestStrayPacketConnectionId
- : public QuicDispatcherTestBase {};
-
-INSTANTIATE_TEST_SUITE_P(QuicDispatcherTestsStrayPacketConnectionId,
- QuicDispatcherTestStrayPacketConnectionId,
- ::testing::ValuesIn(CurrentSupportedVersions()),
- ::testing::PrintToStringParamName());
-
-// Packets with truncated connection IDs should be dropped.
-TEST_P(QuicDispatcherTestStrayPacketConnectionId,
- StrayPacketTruncatedConnectionId) {
- CreateTimeWaitListManager();
-
- QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
- QuicConnectionId connection_id = TestConnectionId(1);
- EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _)).Times(0);
- EXPECT_CALL(*time_wait_list_manager_, ProcessPacket(_, _, _, _, _, _))
- .Times(0);
- EXPECT_CALL(*time_wait_list_manager_, AddConnectionIdToTimeWait(_, _))
- .Times(0);
-
- ProcessPacket(client_address, connection_id, true, "data",
- CONNECTION_ID_ABSENT, PACKET_4BYTE_PACKET_NUMBER);
-}
-
-class BlockingWriter : public QuicPacketWriterWrapper {
- public:
- BlockingWriter() : write_blocked_(false) {}
-
- bool IsWriteBlocked() const override { return write_blocked_; }
- void SetWritable() override { write_blocked_ = false; }
-
- WriteResult WritePacket(const char* /*buffer*/, size_t /*buf_len*/,
- const QuicIpAddress& /*self_client_address*/,
- const QuicSocketAddress& /*peer_client_address*/,
- PerPacketOptions* /*options*/) override {
- // It would be quite possible to actually implement this method here with
- // the fake blocked status, but it would be significantly more work in
- // Chromium, and since it's not called anyway, don't bother.
- QUIC_LOG(DFATAL) << "Not supported";
- return WriteResult();
- }
-
- bool write_blocked_;
-};
-
-class QuicDispatcherWriteBlockedListTest : public QuicDispatcherTestBase {
- public:
- void SetUp() override {
- QuicDispatcherTestBase::SetUp();
- writer_ = new BlockingWriter;
- QuicDispatcherPeer::UseWriter(dispatcher_.get(), writer_);
-
- QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
-
- EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, client_address,
- Eq(ExpectedAlpn()), _, _))
- .WillOnce(Return(ByMove(CreateSession(
- dispatcher_.get(), config_, TestConnectionId(1), client_address,
- &helper_, &alarm_factory_, &crypto_config_,
- QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
- EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
- ProcessUdpPacket(_, _, _))
- .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
- ValidatePacket(TestConnectionId(1), packet);
- })));
- EXPECT_CALL(*dispatcher_,
- ShouldCreateOrBufferPacketForConnection(
- ReceivedPacketInfoConnectionIdEquals(TestConnectionId(1))));
- ProcessFirstFlight(client_address, TestConnectionId(1));
-
- EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, client_address,
- Eq(ExpectedAlpn()), _, _))
- .WillOnce(Return(ByMove(CreateSession(
- dispatcher_.get(), config_, TestConnectionId(2), client_address,
- &helper_, &alarm_factory_, &crypto_config_,
- QuicDispatcherPeer::GetCache(dispatcher_.get()), &session2_))));
- EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session2_->connection()),
- ProcessUdpPacket(_, _, _))
- .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
- ValidatePacket(TestConnectionId(2), packet);
- })));
- EXPECT_CALL(*dispatcher_,
- ShouldCreateOrBufferPacketForConnection(
- ReceivedPacketInfoConnectionIdEquals(TestConnectionId(2))));
- ProcessFirstFlight(client_address, TestConnectionId(2));
-
- blocked_list_ = QuicDispatcherPeer::GetWriteBlockedList(dispatcher_.get());
- }
-
- void TearDown() override {
- if (connection1() != nullptr) {
- EXPECT_CALL(*connection1(), CloseConnection(QUIC_PEER_GOING_AWAY, _, _));
- }
-
- if (connection2() != nullptr) {
- EXPECT_CALL(*connection2(), CloseConnection(QUIC_PEER_GOING_AWAY, _, _));
- }
- dispatcher_->Shutdown();
- }
-
- // Set the dispatcher's writer to be blocked. By default, all connections use
- // the same writer as the dispatcher in this test.
- void SetBlocked() {
- QUIC_LOG(INFO) << "set writer " << writer_ << " to blocked";
- writer_->write_blocked_ = true;
- }
-
- // Simulate what happens when connection1 gets blocked when writing.
- void BlockConnection1() {
- Connection1Writer()->write_blocked_ = true;
- dispatcher_->OnWriteBlocked(connection1());
- }
-
- BlockingWriter* Connection1Writer() {
- return static_cast<BlockingWriter*>(connection1()->writer());
- }
-
- // Simulate what happens when connection2 gets blocked when writing.
- void BlockConnection2() {
- Connection2Writer()->write_blocked_ = true;
- dispatcher_->OnWriteBlocked(connection2());
- }
-
- BlockingWriter* Connection2Writer() {
- return static_cast<BlockingWriter*>(connection2()->writer());
- }
-
- protected:
- MockQuicConnectionHelper helper_;
- MockAlarmFactory alarm_factory_;
- BlockingWriter* writer_;
- QuicDispatcher::WriteBlockedList* blocked_list_;
-};
-
-INSTANTIATE_TEST_SUITE_P(QuicDispatcherWriteBlockedListTests,
- QuicDispatcherWriteBlockedListTest,
- ::testing::Values(CurrentSupportedVersions().front()),
- ::testing::PrintToStringParamName());
-
-TEST_P(QuicDispatcherWriteBlockedListTest, BasicOnCanWrite) {
- // No OnCanWrite calls because no connections are blocked.
- dispatcher_->OnCanWrite();
-
- // Register connection 1 for events, and make sure it's notified.
- SetBlocked();
- dispatcher_->OnWriteBlocked(connection1());
- EXPECT_CALL(*connection1(), OnCanWrite());
- dispatcher_->OnCanWrite();
-
- // It should get only one notification.
- EXPECT_CALL(*connection1(), OnCanWrite()).Times(0);
- dispatcher_->OnCanWrite();
- EXPECT_FALSE(dispatcher_->HasPendingWrites());
-}
-
-TEST_P(QuicDispatcherWriteBlockedListTest, OnCanWriteOrder) {
- // Make sure we handle events in order.
- InSequence s;
- SetBlocked();
- dispatcher_->OnWriteBlocked(connection1());
- dispatcher_->OnWriteBlocked(connection2());
- EXPECT_CALL(*connection1(), OnCanWrite());
- EXPECT_CALL(*connection2(), OnCanWrite());
- dispatcher_->OnCanWrite();
-
- // Check the other ordering.
- SetBlocked();
- dispatcher_->OnWriteBlocked(connection2());
- dispatcher_->OnWriteBlocked(connection1());
- EXPECT_CALL(*connection2(), OnCanWrite());
- EXPECT_CALL(*connection1(), OnCanWrite());
- dispatcher_->OnCanWrite();
-}
-
-TEST_P(QuicDispatcherWriteBlockedListTest, OnCanWriteRemove) {
- // Add and remove one connction.
- SetBlocked();
- dispatcher_->OnWriteBlocked(connection1());
- blocked_list_->erase(connection1());
- EXPECT_CALL(*connection1(), OnCanWrite()).Times(0);
- dispatcher_->OnCanWrite();
-
- // Add and remove one connction and make sure it doesn't affect others.
- SetBlocked();
- dispatcher_->OnWriteBlocked(connection1());
- dispatcher_->OnWriteBlocked(connection2());
- blocked_list_->erase(connection1());
- EXPECT_CALL(*connection2(), OnCanWrite());
- dispatcher_->OnCanWrite();
-
- // Add it, remove it, and add it back and make sure things are OK.
- SetBlocked();
- dispatcher_->OnWriteBlocked(connection1());
- blocked_list_->erase(connection1());
- dispatcher_->OnWriteBlocked(connection1());
- EXPECT_CALL(*connection1(), OnCanWrite()).Times(1);
- dispatcher_->OnCanWrite();
-}
-
-TEST_P(QuicDispatcherWriteBlockedListTest, DoubleAdd) {
- // Make sure a double add does not necessitate a double remove.
- SetBlocked();
- dispatcher_->OnWriteBlocked(connection1());
- dispatcher_->OnWriteBlocked(connection1());
- blocked_list_->erase(connection1());
- EXPECT_CALL(*connection1(), OnCanWrite()).Times(0);
- dispatcher_->OnCanWrite();
-
- // Make sure a double add does not result in two OnCanWrite calls.
- SetBlocked();
- dispatcher_->OnWriteBlocked(connection1());
- dispatcher_->OnWriteBlocked(connection1());
- EXPECT_CALL(*connection1(), OnCanWrite()).Times(1);
- dispatcher_->OnCanWrite();
-}
-
-TEST_P(QuicDispatcherWriteBlockedListTest, OnCanWriteHandleBlockConnection1) {
- // If the 1st blocked writer gets blocked in OnCanWrite, it will be added back
- // into the write blocked list.
- InSequence s;
- SetBlocked();
- dispatcher_->OnWriteBlocked(connection1());
- dispatcher_->OnWriteBlocked(connection2());
- EXPECT_CALL(*connection1(), OnCanWrite())
- .WillOnce(
- Invoke(this, &QuicDispatcherWriteBlockedListTest::BlockConnection1));
- EXPECT_CALL(*connection2(), OnCanWrite());
- dispatcher_->OnCanWrite();
-
- // connection1 should be still in the write blocked list.
- EXPECT_TRUE(dispatcher_->HasPendingWrites());
-
- // Now call OnCanWrite again, connection1 should get its second chance.
- EXPECT_CALL(*connection1(), OnCanWrite());
- EXPECT_CALL(*connection2(), OnCanWrite()).Times(0);
- dispatcher_->OnCanWrite();
- EXPECT_FALSE(dispatcher_->HasPendingWrites());
-}
-
-TEST_P(QuicDispatcherWriteBlockedListTest, OnCanWriteHandleBlockConnection2) {
- // If the 2nd blocked writer gets blocked in OnCanWrite, it will be added back
- // into the write blocked list.
- InSequence s;
- SetBlocked();
- dispatcher_->OnWriteBlocked(connection1());
- dispatcher_->OnWriteBlocked(connection2());
- EXPECT_CALL(*connection1(), OnCanWrite());
- EXPECT_CALL(*connection2(), OnCanWrite())
- .WillOnce(
- Invoke(this, &QuicDispatcherWriteBlockedListTest::BlockConnection2));
- dispatcher_->OnCanWrite();
-
- // connection2 should be still in the write blocked list.
- EXPECT_TRUE(dispatcher_->HasPendingWrites());
-
- // Now call OnCanWrite again, connection2 should get its second chance.
- EXPECT_CALL(*connection1(), OnCanWrite()).Times(0);
- EXPECT_CALL(*connection2(), OnCanWrite());
- dispatcher_->OnCanWrite();
- EXPECT_FALSE(dispatcher_->HasPendingWrites());
-}
-
-TEST_P(QuicDispatcherWriteBlockedListTest,
- OnCanWriteHandleBlockBothConnections) {
- // Both connections get blocked in OnCanWrite, and added back into the write
- // blocked list.
- InSequence s;
- SetBlocked();
- dispatcher_->OnWriteBlocked(connection1());
- dispatcher_->OnWriteBlocked(connection2());
- EXPECT_CALL(*connection1(), OnCanWrite())
- .WillOnce(
- Invoke(this, &QuicDispatcherWriteBlockedListTest::BlockConnection1));
- EXPECT_CALL(*connection2(), OnCanWrite())
- .WillOnce(
- Invoke(this, &QuicDispatcherWriteBlockedListTest::BlockConnection2));
- dispatcher_->OnCanWrite();
-
- // Both connections should be still in the write blocked list.
- EXPECT_TRUE(dispatcher_->HasPendingWrites());
-
- // Now call OnCanWrite again, both connections should get its second chance.
- EXPECT_CALL(*connection1(), OnCanWrite());
- EXPECT_CALL(*connection2(), OnCanWrite());
- dispatcher_->OnCanWrite();
- EXPECT_FALSE(dispatcher_->HasPendingWrites());
-}
-
-TEST_P(QuicDispatcherWriteBlockedListTest, PerConnectionWriterBlocked) {
- // By default, all connections share the same packet writer with the
- // dispatcher.
- EXPECT_EQ(dispatcher_->writer(), connection1()->writer());
- EXPECT_EQ(dispatcher_->writer(), connection2()->writer());
-
- // Test the case where connection1 shares the same packet writer as the
- // dispatcher, whereas connection2 owns it's packet writer.
- // Change connection2's writer.
- connection2()->SetQuicPacketWriter(new BlockingWriter, /*owns_writer=*/true);
- EXPECT_NE(dispatcher_->writer(), connection2()->writer());
-
- BlockConnection2();
- EXPECT_TRUE(dispatcher_->HasPendingWrites());
-
- EXPECT_CALL(*connection2(), OnCanWrite());
- dispatcher_->OnCanWrite();
- EXPECT_FALSE(dispatcher_->HasPendingWrites());
-}
-
-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();
-}
-
-class QuicDispatcherSupportMultipleConnectionIdPerConnectionTest
- : public QuicDispatcherTestBase {
- public:
- QuicDispatcherSupportMultipleConnectionIdPerConnectionTest()
- : QuicDispatcherTestBase(crypto_test_utils::ProofSourceForTesting()) {
- dispatcher_ = std::make_unique<NiceMock<TestDispatcher>>(
- &config_, &crypto_config_, &version_manager_,
- mock_helper_.GetRandomGenerator());
- }
- void AddConnection1() {
- QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
- EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, client_address,
- Eq(ExpectedAlpn()), _, _))
- .WillOnce(Return(ByMove(CreateSession(
- dispatcher_.get(), config_, TestConnectionId(1), client_address,
- &helper_, &alarm_factory_, &crypto_config_,
- QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
- EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
- ProcessUdpPacket(_, _, _))
- .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
- ValidatePacket(TestConnectionId(1), packet);
- })));
- EXPECT_CALL(*dispatcher_,
- ShouldCreateOrBufferPacketForConnection(
- ReceivedPacketInfoConnectionIdEquals(TestConnectionId(1))));
- ProcessFirstFlight(client_address, TestConnectionId(1));
- }
-
- void AddConnection2() {
- QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 2);
- EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, client_address,
- Eq(ExpectedAlpn()), _, _))
- .WillOnce(Return(ByMove(CreateSession(
- dispatcher_.get(), config_, TestConnectionId(2), client_address,
- &helper_, &alarm_factory_, &crypto_config_,
- QuicDispatcherPeer::GetCache(dispatcher_.get()), &session2_))));
- EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session2_->connection()),
- ProcessUdpPacket(_, _, _))
- .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
- ValidatePacket(TestConnectionId(2), packet);
- })));
- EXPECT_CALL(*dispatcher_,
- ShouldCreateOrBufferPacketForConnection(
- ReceivedPacketInfoConnectionIdEquals(TestConnectionId(2))));
- ProcessFirstFlight(client_address, TestConnectionId(2));
- }
-
- protected:
- MockQuicConnectionHelper helper_;
- MockAlarmFactory alarm_factory_;
-};
-
-INSTANTIATE_TEST_SUITE_P(
- QuicDispatcherSupportMultipleConnectionIdPerConnectionTests,
- QuicDispatcherSupportMultipleConnectionIdPerConnectionTest,
- ::testing::Values(CurrentSupportedVersions().front()),
- ::testing::PrintToStringParamName());
-
-TEST_P(QuicDispatcherSupportMultipleConnectionIdPerConnectionTest,
- OnNewConnectionIdSent) {
- AddConnection1();
- ASSERT_EQ(dispatcher_->NumSessions(), 1u);
- ASSERT_THAT(session1_, testing::NotNull());
- MockServerConnection* mock_server_connection1 =
- reinterpret_cast<MockServerConnection*>(connection1());
-
- {
- mock_server_connection1->AddNewConnectionId(TestConnectionId(3));
- EXPECT_EQ(dispatcher_->NumSessions(), 1u);
- auto* session =
- QuicDispatcherPeer::FindSession(dispatcher_.get(), TestConnectionId(3));
- ASSERT_EQ(session, session1_);
- }
-
- {
- mock_server_connection1->AddNewConnectionId(TestConnectionId(4));
- EXPECT_EQ(dispatcher_->NumSessions(), 1u);
- auto* session =
- QuicDispatcherPeer::FindSession(dispatcher_.get(), TestConnectionId(4));
- ASSERT_EQ(session, session1_);
- }
-
- EXPECT_CALL(*connection1(), CloseConnection(QUIC_PEER_GOING_AWAY, _, _));
- // Would timed out unless all sessions have been removed from the session map.
- dispatcher_->Shutdown();
-}
-
-TEST_P(QuicDispatcherSupportMultipleConnectionIdPerConnectionTest,
- RetireConnectionIdFromSingleConnection) {
- AddConnection1();
- ASSERT_EQ(dispatcher_->NumSessions(), 1u);
- ASSERT_THAT(session1_, testing::NotNull());
- MockServerConnection* mock_server_connection1 =
- reinterpret_cast<MockServerConnection*>(connection1());
-
- // Adds 1 new connection id every turn and retires 2 connection ids every
- // other turn.
- for (int i = 2; i < 10; ++i) {
- mock_server_connection1->AddNewConnectionId(TestConnectionId(i));
- ASSERT_EQ(
- QuicDispatcherPeer::FindSession(dispatcher_.get(), TestConnectionId(i)),
- session1_);
- ASSERT_EQ(QuicDispatcherPeer::FindSession(dispatcher_.get(),
- TestConnectionId(i - 1)),
- session1_);
- EXPECT_EQ(dispatcher_->NumSessions(), 1u);
- if (i % 2 == 1) {
- mock_server_connection1->RetireConnectionId(TestConnectionId(i - 2));
- mock_server_connection1->RetireConnectionId(TestConnectionId(i - 1));
- }
- }
-
- EXPECT_CALL(*connection1(), CloseConnection(QUIC_PEER_GOING_AWAY, _, _));
- // Would timed out unless all sessions have been removed from the session map.
- dispatcher_->Shutdown();
-}
-
-TEST_P(QuicDispatcherSupportMultipleConnectionIdPerConnectionTest,
- RetireConnectionIdFromMultipleConnections) {
- AddConnection1();
- AddConnection2();
- ASSERT_EQ(dispatcher_->NumSessions(), 2u);
- MockServerConnection* mock_server_connection1 =
- reinterpret_cast<MockServerConnection*>(connection1());
- MockServerConnection* mock_server_connection2 =
- reinterpret_cast<MockServerConnection*>(connection2());
-
- for (int i = 2; i < 10; ++i) {
- mock_server_connection1->AddNewConnectionId(TestConnectionId(2 * i - 1));
- mock_server_connection2->AddNewConnectionId(TestConnectionId(2 * i));
- ASSERT_EQ(QuicDispatcherPeer::FindSession(dispatcher_.get(),
- TestConnectionId(2 * i - 1)),
- session1_);
- ASSERT_EQ(QuicDispatcherPeer::FindSession(dispatcher_.get(),
- TestConnectionId(2 * i)),
- session2_);
- EXPECT_EQ(dispatcher_->NumSessions(), 2u);
- mock_server_connection1->RetireConnectionId(TestConnectionId(2 * i - 3));
- mock_server_connection2->RetireConnectionId(TestConnectionId(2 * i - 2));
- }
-
- mock_server_connection1->AddNewConnectionId(TestConnectionId(19));
- mock_server_connection2->AddNewConnectionId(TestConnectionId(20));
- EXPECT_CALL(*connection1(), CloseConnection(QUIC_PEER_GOING_AWAY, _, _));
- EXPECT_CALL(*connection2(), CloseConnection(QUIC_PEER_GOING_AWAY, _, _));
- // Would timed out unless all sessions have been removed from the session map.
- dispatcher_->Shutdown();
-}
-
-TEST_P(QuicDispatcherSupportMultipleConnectionIdPerConnectionTest,
- TimeWaitListPoplulateCorrectly) {
- QuicTimeWaitListManager* time_wait_list_manager =
- QuicDispatcherPeer::GetTimeWaitListManager(dispatcher_.get());
- AddConnection1();
- MockServerConnection* mock_server_connection1 =
- reinterpret_cast<MockServerConnection*>(connection1());
-
- mock_server_connection1->AddNewConnectionId(TestConnectionId(2));
- mock_server_connection1->AddNewConnectionId(TestConnectionId(3));
- mock_server_connection1->AddNewConnectionId(TestConnectionId(4));
- mock_server_connection1->RetireConnectionId(TestConnectionId(1));
- mock_server_connection1->RetireConnectionId(TestConnectionId(2));
-
- EXPECT_CALL(*connection1(), CloseConnection(QUIC_PEER_GOING_AWAY, _, _));
- connection1()->CloseConnection(
- QUIC_PEER_GOING_AWAY, "Close for testing",
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
-
- EXPECT_FALSE(
- time_wait_list_manager->IsConnectionIdInTimeWait(TestConnectionId(1)));
- EXPECT_FALSE(
- time_wait_list_manager->IsConnectionIdInTimeWait(TestConnectionId(2)));
- EXPECT_TRUE(
- time_wait_list_manager->IsConnectionIdInTimeWait(TestConnectionId(3)));
- EXPECT_TRUE(
- time_wait_list_manager->IsConnectionIdInTimeWait(TestConnectionId(4)));
-
- dispatcher_->Shutdown();
-}
-
-class BufferedPacketStoreTest : public QuicDispatcherTestBase {
- public:
- BufferedPacketStoreTest()
- : QuicDispatcherTestBase(),
- client_addr_(QuicIpAddress::Loopback4(), 1234) {}
-
- void ProcessFirstFlight(const ParsedQuicVersion& version,
- const QuicSocketAddress& peer_address,
- const QuicConnectionId& server_connection_id) {
- QuicDispatcherTestBase::ProcessFirstFlight(version, peer_address,
- server_connection_id);
- }
-
- void ProcessFirstFlight(const QuicSocketAddress& peer_address,
- const QuicConnectionId& server_connection_id) {
- ProcessFirstFlight(version_, peer_address, server_connection_id);
- }
-
- void ProcessFirstFlight(const QuicConnectionId& server_connection_id) {
- ProcessFirstFlight(client_addr_, server_connection_id);
- }
-
- void ProcessFirstFlight(const ParsedQuicVersion& version,
- const QuicConnectionId& server_connection_id) {
- ProcessFirstFlight(version, client_addr_, server_connection_id);
- }
-
- void ProcessUndecryptableEarlyPacket(
- const ParsedQuicVersion& version, const QuicSocketAddress& peer_address,
- const QuicConnectionId& server_connection_id) {
- QuicDispatcherTestBase::ProcessUndecryptableEarlyPacket(
- version, peer_address, server_connection_id);
- }
-
- void ProcessUndecryptableEarlyPacket(
- const QuicSocketAddress& peer_address,
- const QuicConnectionId& server_connection_id) {
- ProcessUndecryptableEarlyPacket(version_, peer_address,
- server_connection_id);
- }
-
- void ProcessUndecryptableEarlyPacket(
- const QuicConnectionId& server_connection_id) {
- ProcessUndecryptableEarlyPacket(version_, client_addr_,
- server_connection_id);
- }
-
- protected:
- QuicSocketAddress client_addr_;
-};
-
-INSTANTIATE_TEST_SUITE_P(BufferedPacketStoreTests, BufferedPacketStoreTest,
- ::testing::ValuesIn(CurrentSupportedVersions()),
- ::testing::PrintToStringParamName());
-
-TEST_P(BufferedPacketStoreTest, ProcessNonChloPacketBeforeChlo) {
- InSequence s;
- QuicConnectionId conn_id = TestConnectionId(1);
- // Non-CHLO should be buffered upon arrival, and should trigger
- // ShouldCreateOrBufferPacketForConnection().
- EXPECT_CALL(*dispatcher_, ShouldCreateOrBufferPacketForConnection(
- ReceivedPacketInfoConnectionIdEquals(conn_id)));
- // Process non-CHLO packet.
- ProcessUndecryptableEarlyPacket(conn_id);
- EXPECT_EQ(0u, dispatcher_->NumSessions())
- << "No session should be created before CHLO arrives.";
-
- // When CHLO arrives, a new session should be created, and all packets
- // buffered should be delivered to the session.
- EXPECT_CALL(*dispatcher_,
- CreateQuicSession(conn_id, _, client_addr_, Eq(ExpectedAlpn()), _,
- Eq(ParsedClientHelloForTest())))
- .WillOnce(Return(ByMove(CreateSession(
- dispatcher_.get(), config_, conn_id, client_addr_, &mock_helper_,
- &mock_alarm_factory_, &crypto_config_,
- QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
- EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
- ProcessUdpPacket(_, _, _))
- .Times(2) // non-CHLO + CHLO.
- .WillRepeatedly(
- WithArg<2>(Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
- if (version_.UsesQuicCrypto()) {
- ValidatePacket(conn_id, packet);
- }
- })));
- ProcessFirstFlight(conn_id);
-}
-
-TEST_P(BufferedPacketStoreTest, ProcessNonChloPacketsUptoLimitAndProcessChlo) {
- InSequence s;
- QuicConnectionId conn_id = TestConnectionId(1);
- // A bunch of non-CHLO should be buffered upon arrival, and the first one
- // should trigger ShouldCreateOrBufferPacketForConnection().
- EXPECT_CALL(*dispatcher_, ShouldCreateOrBufferPacketForConnection(
- ReceivedPacketInfoConnectionIdEquals(conn_id)));
- for (size_t i = 1; i <= kDefaultMaxUndecryptablePackets + 1; ++i) {
- ProcessUndecryptableEarlyPacket(conn_id);
- }
- EXPECT_EQ(0u, dispatcher_->NumSessions())
- << "No session should be created before CHLO arrives.";
-
- // Pop out the last packet as it is also be dropped by the store.
- data_connection_map_[conn_id].pop_back();
- // When CHLO arrives, a new session should be created, and all packets
- // buffered should be delivered to the session.
- EXPECT_CALL(*dispatcher_, CreateQuicSession(conn_id, _, client_addr_,
- Eq(ExpectedAlpn()), _, _))
- .WillOnce(Return(ByMove(CreateSession(
- dispatcher_.get(), config_, conn_id, client_addr_, &mock_helper_,
- &mock_alarm_factory_, &crypto_config_,
- QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
-
- // Only |kDefaultMaxUndecryptablePackets| packets were buffered, and they
- // should be delivered in arrival order.
- EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
- ProcessUdpPacket(_, _, _))
- .Times(kDefaultMaxUndecryptablePackets + 1) // + 1 for CHLO.
- .WillRepeatedly(
- WithArg<2>(Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
- if (version_.UsesQuicCrypto()) {
- ValidatePacket(conn_id, packet);
- }
- })));
- ProcessFirstFlight(conn_id);
-}
-
-TEST_P(BufferedPacketStoreTest,
- ProcessNonChloPacketsForDifferentConnectionsUptoLimit) {
- InSequence s;
- // A bunch of non-CHLO should be buffered upon arrival.
- size_t kNumConnections = kMaxConnectionsWithoutCHLO + 1;
- for (size_t i = 1; i <= kNumConnections; ++i) {
- QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 20000 + i);
- QuicConnectionId conn_id = TestConnectionId(i);
- EXPECT_CALL(*dispatcher_,
- ShouldCreateOrBufferPacketForConnection(
- ReceivedPacketInfoConnectionIdEquals(conn_id)));
- ProcessUndecryptableEarlyPacket(client_address, conn_id);
- }
-
- // Pop out the packet on last connection as it shouldn't be enqueued in store
- // as well.
- data_connection_map_[TestConnectionId(kNumConnections)].pop_front();
-
- // Reset session creation counter to ensure processing CHLO can always
- // create session.
- QuicDispatcherPeer::set_new_sessions_allowed_per_event_loop(dispatcher_.get(),
- kNumConnections);
- // Process CHLOs to create session for these connections.
- for (size_t i = 1; i <= kNumConnections; ++i) {
- QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 20000 + i);
- QuicConnectionId conn_id = TestConnectionId(i);
- if (i == kNumConnections) {
- EXPECT_CALL(*dispatcher_,
- ShouldCreateOrBufferPacketForConnection(
- ReceivedPacketInfoConnectionIdEquals(conn_id)));
- }
- EXPECT_CALL(*dispatcher_, CreateQuicSession(conn_id, _, client_address,
- Eq(ExpectedAlpn()), _, _))
- .WillOnce(Return(ByMove(CreateSession(
- dispatcher_.get(), config_, conn_id, client_address, &mock_helper_,
- &mock_alarm_factory_, &crypto_config_,
- QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
- // First |kNumConnections| - 1 connections should have buffered
- // a packet in store. The rest should have been dropped.
- size_t num_packet_to_process = i <= kMaxConnectionsWithoutCHLO ? 2u : 1u;
- EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
- ProcessUdpPacket(_, client_address, _))
- .Times(num_packet_to_process)
- .WillRepeatedly(WithArg<2>(
- Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
- if (version_.UsesQuicCrypto()) {
- ValidatePacket(conn_id, packet);
- }
- })));
-
- ProcessFirstFlight(client_address, conn_id);
- }
-}
-
-// Tests that store delivers empty packet list if CHLO arrives firstly.
-TEST_P(BufferedPacketStoreTest, DeliverEmptyPackets) {
- QuicConnectionId conn_id = TestConnectionId(1);
- EXPECT_CALL(*dispatcher_, ShouldCreateOrBufferPacketForConnection(
- ReceivedPacketInfoConnectionIdEquals(conn_id)));
- EXPECT_CALL(*dispatcher_, CreateQuicSession(conn_id, _, client_addr_,
- Eq(ExpectedAlpn()), _, _))
- .WillOnce(Return(ByMove(CreateSession(
- dispatcher_.get(), config_, conn_id, client_addr_, &mock_helper_,
- &mock_alarm_factory_, &crypto_config_,
- QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
- EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
- ProcessUdpPacket(_, client_addr_, _));
- ProcessFirstFlight(conn_id);
-}
-
-// Tests that a retransmitted CHLO arrives after a connection for the
-// CHLO has been created.
-TEST_P(BufferedPacketStoreTest, ReceiveRetransmittedCHLO) {
- InSequence s;
- QuicConnectionId conn_id = TestConnectionId(1);
- ProcessUndecryptableEarlyPacket(conn_id);
-
- // When CHLO arrives, a new session should be created, and all packets
- // buffered should be delivered to the session.
- EXPECT_CALL(*dispatcher_, CreateQuicSession(conn_id, _, client_addr_,
- Eq(ExpectedAlpn()), _, _))
- .Times(1) // Only triggered by 1st CHLO.
- .WillOnce(Return(ByMove(CreateSession(
- dispatcher_.get(), config_, conn_id, client_addr_, &mock_helper_,
- &mock_alarm_factory_, &crypto_config_,
- QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
- EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
- ProcessUdpPacket(_, _, _))
- .Times(3) // Triggered by 1 data packet and 2 CHLOs.
- .WillRepeatedly(
- WithArg<2>(Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
- if (version_.UsesQuicCrypto()) {
- ValidatePacket(conn_id, packet);
- }
- })));
-
- std::vector<std::unique_ptr<QuicReceivedPacket>> packets =
- GetFirstFlightOfPackets(version_, conn_id);
- ASSERT_EQ(packets.size(), 1u);
- // Receive the CHLO once.
- ProcessReceivedPacket(packets[0]->Clone(), client_addr_, version_, conn_id);
- // Receive the CHLO a second time to simulate retransmission.
- ProcessReceivedPacket(std::move(packets[0]), client_addr_, version_, conn_id);
-}
-
-// Tests that expiration of a connection add connection id to time wait list.
-TEST_P(BufferedPacketStoreTest, ReceiveCHLOAfterExpiration) {
- InSequence s;
- CreateTimeWaitListManager();
- QuicBufferedPacketStore* store =
- QuicDispatcherPeer::GetBufferedPackets(dispatcher_.get());
- QuicBufferedPacketStorePeer::set_clock(store, mock_helper_.GetClock());
-
- QuicConnectionId conn_id = TestConnectionId(1);
- ProcessPacket(client_addr_, conn_id, true, absl::StrCat("data packet ", 2),
- CONNECTION_ID_PRESENT, PACKET_4BYTE_PACKET_NUMBER,
- /*packet_number=*/2);
-
- mock_helper_.AdvanceTime(
- QuicTime::Delta::FromSeconds(kInitialIdleTimeoutSecs));
- QuicAlarm* alarm = QuicBufferedPacketStorePeer::expiration_alarm(store);
- // Cancel alarm as if it had been fired.
- alarm->Cancel();
- store->OnExpirationTimeout();
- // New arrived CHLO will be dropped because this connection is in time wait
- // list.
- ASSERT_TRUE(time_wait_list_manager_->IsConnectionIdInTimeWait(conn_id));
- EXPECT_CALL(*time_wait_list_manager_, ProcessPacket(_, _, conn_id, _, _, _));
- ProcessFirstFlight(conn_id);
-}
-
-TEST_P(BufferedPacketStoreTest, ProcessCHLOsUptoLimitAndBufferTheRest) {
- // Process more than (|kMaxNumSessionsToCreate| +
- // |kDefaultMaxConnectionsInStore|) CHLOs,
- // the first |kMaxNumSessionsToCreate| should create connections immediately,
- // the next |kDefaultMaxConnectionsInStore| should be buffered,
- // the rest should be dropped.
- QuicBufferedPacketStore* store =
- QuicDispatcherPeer::GetBufferedPackets(dispatcher_.get());
- const size_t kNumCHLOs =
- kMaxNumSessionsToCreate + kDefaultMaxConnectionsInStore + 1;
- for (uint64_t conn_id = 1; conn_id <= kNumCHLOs; ++conn_id) {
- EXPECT_CALL(
- *dispatcher_,
- ShouldCreateOrBufferPacketForConnection(
- ReceivedPacketInfoConnectionIdEquals(TestConnectionId(conn_id))));
- if (conn_id <= kMaxNumSessionsToCreate) {
- EXPECT_CALL(*dispatcher_,
- CreateQuicSession(TestConnectionId(conn_id), _, client_addr_,
- Eq(ExpectedAlpn()), _,
- Eq(ParsedClientHelloForTest())))
- .WillOnce(Return(ByMove(CreateSession(
- dispatcher_.get(), config_, TestConnectionId(conn_id),
- client_addr_, &mock_helper_, &mock_alarm_factory_,
- &crypto_config_, QuicDispatcherPeer::GetCache(dispatcher_.get()),
- &session1_))));
- EXPECT_CALL(
- *reinterpret_cast<MockQuicConnection*>(session1_->connection()),
- ProcessUdpPacket(_, _, _))
- .WillOnce(WithArg<2>(
- Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
- if (version_.UsesQuicCrypto()) {
- ValidatePacket(TestConnectionId(conn_id), packet);
- }
- })));
- }
- ProcessFirstFlight(TestConnectionId(conn_id));
- if (conn_id <= kMaxNumSessionsToCreate + kDefaultMaxConnectionsInStore &&
- conn_id > kMaxNumSessionsToCreate) {
- EXPECT_TRUE(store->HasChloForConnection(TestConnectionId(conn_id)));
- } else {
- // First |kMaxNumSessionsToCreate| CHLOs should be passed to new
- // connections immediately, and the last CHLO should be dropped as the
- // store is full.
- EXPECT_FALSE(store->HasChloForConnection(TestConnectionId(conn_id)));
- }
- }
-
- // Graduately consume buffered CHLOs. The buffered connections should be
- // created but the dropped one shouldn't.
- for (uint64_t conn_id = kMaxNumSessionsToCreate + 1;
- conn_id <= kMaxNumSessionsToCreate + kDefaultMaxConnectionsInStore;
- ++conn_id) {
- EXPECT_CALL(*dispatcher_,
- CreateQuicSession(TestConnectionId(conn_id), _, client_addr_,
- Eq(ExpectedAlpn()), _,
- Eq(ParsedClientHelloForTest())))
- .WillOnce(Return(ByMove(CreateSession(
- dispatcher_.get(), config_, TestConnectionId(conn_id), client_addr_,
- &mock_helper_, &mock_alarm_factory_, &crypto_config_,
- QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
- EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
- ProcessUdpPacket(_, _, _))
- .WillOnce(WithArg<2>(
- Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
- if (version_.UsesQuicCrypto()) {
- ValidatePacket(TestConnectionId(conn_id), packet);
- }
- })));
- }
- EXPECT_CALL(*dispatcher_,
- CreateQuicSession(TestConnectionId(kNumCHLOs), _, client_addr_,
- Eq(ExpectedAlpn()), _, _))
- .Times(0);
-
- while (store->HasChlosBuffered()) {
- dispatcher_->ProcessBufferedChlos(kMaxNumSessionsToCreate);
- }
-
- EXPECT_EQ(TestConnectionId(static_cast<size_t>(kMaxNumSessionsToCreate) +
- kDefaultMaxConnectionsInStore),
- session1_->connection_id());
-}
-
-// Duplicated CHLO shouldn't be buffered.
-TEST_P(BufferedPacketStoreTest, BufferDuplicatedCHLO) {
- for (uint64_t conn_id = 1; conn_id <= kMaxNumSessionsToCreate + 1;
- ++conn_id) {
- // Last CHLO will be buffered. Others will create connection right away.
- if (conn_id <= kMaxNumSessionsToCreate) {
- EXPECT_CALL(*dispatcher_,
- CreateQuicSession(TestConnectionId(conn_id), _, client_addr_,
- Eq(ExpectedAlpn()), _, _))
- .WillOnce(Return(ByMove(CreateSession(
- dispatcher_.get(), config_, TestConnectionId(conn_id),
- client_addr_, &mock_helper_, &mock_alarm_factory_,
- &crypto_config_, QuicDispatcherPeer::GetCache(dispatcher_.get()),
- &session1_))));
- EXPECT_CALL(
- *reinterpret_cast<MockQuicConnection*>(session1_->connection()),
- ProcessUdpPacket(_, _, _))
- .WillOnce(WithArg<2>(
- Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
- if (version_.UsesQuicCrypto()) {
- ValidatePacket(TestConnectionId(conn_id), packet);
- }
- })));
- }
- ProcessFirstFlight(TestConnectionId(conn_id));
- }
- // Retransmit CHLO on last connection should be dropped.
- QuicConnectionId last_connection =
- TestConnectionId(kMaxNumSessionsToCreate + 1);
- ProcessFirstFlight(last_connection);
-
- size_t packets_buffered = 2;
-
- // Reset counter and process buffered CHLO.
- EXPECT_CALL(*dispatcher_, CreateQuicSession(last_connection, _, client_addr_,
- Eq(ExpectedAlpn()), _, _))
- .WillOnce(Return(ByMove(CreateSession(
- dispatcher_.get(), config_, last_connection, client_addr_,
- &mock_helper_, &mock_alarm_factory_, &crypto_config_,
- QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
- // Only one packet(CHLO) should be process.
- EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
- ProcessUdpPacket(_, _, _))
- .Times(packets_buffered)
- .WillRepeatedly(WithArg<2>(
- Invoke([this, last_connection](const QuicEncryptedPacket& packet) {
- if (version_.UsesQuicCrypto()) {
- ValidatePacket(last_connection, packet);
- }
- })));
- dispatcher_->ProcessBufferedChlos(kMaxNumSessionsToCreate);
-}
-
-TEST_P(BufferedPacketStoreTest, BufferNonChloPacketsUptoLimitWithChloBuffered) {
- uint64_t last_conn_id = kMaxNumSessionsToCreate + 1;
- QuicConnectionId last_connection_id = TestConnectionId(last_conn_id);
- for (uint64_t conn_id = 1; conn_id <= last_conn_id; ++conn_id) {
- // Last CHLO will be buffered. Others will create connection right away.
- if (conn_id <= kMaxNumSessionsToCreate) {
- EXPECT_CALL(*dispatcher_,
- CreateQuicSession(TestConnectionId(conn_id), _, client_addr_,
- Eq(ExpectedAlpn()), _, _))
- .WillOnce(Return(ByMove(CreateSession(
- dispatcher_.get(), config_, TestConnectionId(conn_id),
- client_addr_, &mock_helper_, &mock_alarm_factory_,
- &crypto_config_, QuicDispatcherPeer::GetCache(dispatcher_.get()),
- &session1_))));
- EXPECT_CALL(
- *reinterpret_cast<MockQuicConnection*>(session1_->connection()),
- ProcessUdpPacket(_, _, _))
- .WillRepeatedly(WithArg<2>(
- Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
- if (version_.UsesQuicCrypto()) {
- ValidatePacket(TestConnectionId(conn_id), packet);
- }
- })));
- }
- ProcessFirstFlight(TestConnectionId(conn_id));
- }
-
- // Process another |kDefaultMaxUndecryptablePackets| + 1 data packets. The
- // last one should be dropped.
- for (uint64_t packet_number = 2;
- packet_number <= kDefaultMaxUndecryptablePackets + 2; ++packet_number) {
- ProcessPacket(client_addr_, last_connection_id, true, "data packet");
- }
-
- // Reset counter and process buffered CHLO.
- EXPECT_CALL(*dispatcher_,
- CreateQuicSession(last_connection_id, _, client_addr_,
- Eq(ExpectedAlpn()), _, _))
- .WillOnce(Return(ByMove(CreateSession(
- dispatcher_.get(), config_, last_connection_id, client_addr_,
- &mock_helper_, &mock_alarm_factory_, &crypto_config_,
- QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
- // Only CHLO and following |kDefaultMaxUndecryptablePackets| data packets
- // should be process.
- EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
- ProcessUdpPacket(_, _, _))
- .Times(kDefaultMaxUndecryptablePackets + 1)
- .WillRepeatedly(WithArg<2>(
- Invoke([this, last_connection_id](const QuicEncryptedPacket& packet) {
- if (version_.UsesQuicCrypto()) {
- ValidatePacket(last_connection_id, packet);
- }
- })));
- dispatcher_->ProcessBufferedChlos(kMaxNumSessionsToCreate);
-}
-
-// Tests that when dispatcher's packet buffer is full, a CHLO on connection
-// which doesn't have buffered CHLO should be buffered.
-TEST_P(BufferedPacketStoreTest, ReceiveCHLOForBufferedConnection) {
- QuicBufferedPacketStore* store =
- QuicDispatcherPeer::GetBufferedPackets(dispatcher_.get());
-
- uint64_t conn_id = 1;
- ProcessUndecryptableEarlyPacket(TestConnectionId(conn_id));
- // Fill packet buffer to full with CHLOs on other connections. Need to feed
- // extra CHLOs because the first |kMaxNumSessionsToCreate| are going to create
- // session directly.
- for (conn_id = 2;
- conn_id <= kDefaultMaxConnectionsInStore + kMaxNumSessionsToCreate;
- ++conn_id) {
- if (conn_id <= kMaxNumSessionsToCreate + 1) {
- EXPECT_CALL(*dispatcher_,
- CreateQuicSession(TestConnectionId(conn_id), _, client_addr_,
- Eq(ExpectedAlpn()), _, _))
- .WillOnce(Return(ByMove(CreateSession(
- dispatcher_.get(), config_, TestConnectionId(conn_id),
- client_addr_, &mock_helper_, &mock_alarm_factory_,
- &crypto_config_, QuicDispatcherPeer::GetCache(dispatcher_.get()),
- &session1_))));
- EXPECT_CALL(
- *reinterpret_cast<MockQuicConnection*>(session1_->connection()),
- ProcessUdpPacket(_, _, _))
- .WillOnce(WithArg<2>(
- Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
- if (version_.UsesQuicCrypto()) {
- ValidatePacket(TestConnectionId(conn_id), packet);
- }
- })));
- }
- ProcessFirstFlight(TestConnectionId(conn_id));
- }
- EXPECT_FALSE(store->HasChloForConnection(
- /*connection_id=*/TestConnectionId(1)));
-
- // CHLO on connection 1 should still be buffered.
- ProcessFirstFlight(TestConnectionId(1));
- EXPECT_TRUE(store->HasChloForConnection(
- /*connection_id=*/TestConnectionId(1)));
-}
-
-// Regression test for b/117874922.
-TEST_P(BufferedPacketStoreTest, ProcessBufferedChloWithDifferentVersion) {
- // Ensure the preferred version is not supported by the server.
- QuicDisableVersion(AllSupportedVersions().front());
-
- uint64_t last_connection_id = kMaxNumSessionsToCreate + 5;
- ParsedQuicVersionVector supported_versions = CurrentSupportedVersions();
- for (uint64_t conn_id = 1; conn_id <= last_connection_id; ++conn_id) {
- // Last 5 CHLOs will be buffered. Others will create connection right away.
- ParsedQuicVersion version =
- supported_versions[(conn_id - 1) % supported_versions.size()];
- if (conn_id <= kMaxNumSessionsToCreate) {
- EXPECT_CALL(
- *dispatcher_,
- CreateQuicSession(TestConnectionId(conn_id), _, client_addr_,
- Eq(ExpectedAlpnForVersion(version)), version, _))
- .WillOnce(Return(ByMove(CreateSession(
- dispatcher_.get(), config_, TestConnectionId(conn_id),
- client_addr_, &mock_helper_, &mock_alarm_factory_,
- &crypto_config_, QuicDispatcherPeer::GetCache(dispatcher_.get()),
- &session1_))));
- EXPECT_CALL(
- *reinterpret_cast<MockQuicConnection*>(session1_->connection()),
- ProcessUdpPacket(_, _, _))
- .WillRepeatedly(WithArg<2>(
- Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
- if (version_.UsesQuicCrypto()) {
- ValidatePacket(TestConnectionId(conn_id), packet);
- }
- })));
- }
- ProcessFirstFlight(version, TestConnectionId(conn_id));
- }
-
- // Process buffered CHLOs. Verify the version is correct.
- for (uint64_t conn_id = kMaxNumSessionsToCreate + 1;
- conn_id <= last_connection_id; ++conn_id) {
- ParsedQuicVersion version =
- supported_versions[(conn_id - 1) % supported_versions.size()];
- EXPECT_CALL(
- *dispatcher_,
- CreateQuicSession(TestConnectionId(conn_id), _, client_addr_,
- Eq(ExpectedAlpnForVersion(version)), version, _))
- .WillOnce(Return(ByMove(CreateSession(
- dispatcher_.get(), config_, TestConnectionId(conn_id), client_addr_,
- &mock_helper_, &mock_alarm_factory_, &crypto_config_,
- QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
- EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
- ProcessUdpPacket(_, _, _))
- .WillRepeatedly(WithArg<2>(
- Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
- if (version_.UsesQuicCrypto()) {
- ValidatePacket(TestConnectionId(conn_id), packet);
- }
- })));
- }
- dispatcher_->ProcessBufferedChlos(kMaxNumSessionsToCreate);
-}
-
-} // namespace
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_epoll_alarm_factory.cc b/chromium/net/third_party/quiche/src/quic/core/quic_epoll_alarm_factory.cc
deleted file mode 100644
index 2a088687ef1..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_epoll_alarm_factory.cc
+++ /dev/null
@@ -1,89 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_epoll_alarm_factory.h"
-
-#include <type_traits>
-
-#include "quic/core/quic_arena_scoped_ptr.h"
-
-namespace quic {
-namespace {
-
-class QuicEpollAlarm : public QuicAlarm {
- public:
- QuicEpollAlarm(QuicEpollServer* epoll_server,
- QuicArenaScopedPtr<QuicAlarm::Delegate> delegate)
- : QuicAlarm(std::move(delegate)),
- epoll_server_(epoll_server),
- epoll_alarm_impl_(this) {}
-
- protected:
- void SetImpl() override {
- QUICHE_DCHECK(deadline().IsInitialized());
- epoll_server_->RegisterAlarm(
- (deadline() - QuicTime::Zero()).ToMicroseconds(), &epoll_alarm_impl_);
- }
-
- void CancelImpl() override {
- QUICHE_DCHECK(!deadline().IsInitialized());
- epoll_alarm_impl_.UnregisterIfRegistered();
- }
-
- void UpdateImpl() override {
- QUICHE_DCHECK(deadline().IsInitialized());
- int64_t epoll_deadline = (deadline() - QuicTime::Zero()).ToMicroseconds();
- if (epoll_alarm_impl_.registered()) {
- epoll_alarm_impl_.ReregisterAlarm(epoll_deadline);
- } else {
- epoll_server_->RegisterAlarm(epoll_deadline, &epoll_alarm_impl_);
- }
- }
-
- private:
- class EpollAlarmImpl : public QuicEpollAlarmBase {
- public:
- using int64_epoll = decltype(QuicEpollAlarmBase().OnAlarm());
-
- explicit EpollAlarmImpl(QuicEpollAlarm* alarm) : alarm_(alarm) {}
-
- // Use the same integer type as the base class.
- int64_epoll OnAlarm() override {
- QuicEpollAlarmBase::OnAlarm();
- alarm_->Fire();
- // Fire will take care of registering the alarm, if needed.
- return 0;
- }
-
- private:
- QuicEpollAlarm* alarm_;
- };
-
- QuicEpollServer* epoll_server_;
- EpollAlarmImpl epoll_alarm_impl_;
-};
-
-} // namespace
-
-QuicEpollAlarmFactory::QuicEpollAlarmFactory(QuicEpollServer* epoll_server)
- : epoll_server_(epoll_server) {}
-
-QuicEpollAlarmFactory::~QuicEpollAlarmFactory() = default;
-
-QuicAlarm* QuicEpollAlarmFactory::CreateAlarm(QuicAlarm::Delegate* delegate) {
- return new QuicEpollAlarm(epoll_server_,
- QuicArenaScopedPtr<QuicAlarm::Delegate>(delegate));
-}
-
-QuicArenaScopedPtr<QuicAlarm> QuicEpollAlarmFactory::CreateAlarm(
- QuicArenaScopedPtr<QuicAlarm::Delegate> delegate,
- QuicConnectionArena* arena) {
- if (arena != nullptr) {
- return arena->New<QuicEpollAlarm>(epoll_server_, std::move(delegate));
- }
- return QuicArenaScopedPtr<QuicAlarm>(
- new QuicEpollAlarm(epoll_server_, std::move(delegate)));
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_epoll_alarm_factory.h b/chromium/net/third_party/quiche/src/quic/core/quic_epoll_alarm_factory.h
deleted file mode 100644
index 986b842ae8d..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_epoll_alarm_factory.h
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright (c) 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_EPOLL_ALARM_FACTORY_H_
-#define QUICHE_QUIC_CORE_QUIC_EPOLL_ALARM_FACTORY_H_
-
-#include "quic/core/quic_alarm.h"
-#include "quic/core/quic_alarm_factory.h"
-#include "quic/core/quic_one_block_arena.h"
-#include "quic/platform/api/quic_epoll.h"
-
-namespace quic {
-
-// Creates alarms that use the supplied EpollServer for timing and firing.
-class QUIC_EXPORT_PRIVATE QuicEpollAlarmFactory : public QuicAlarmFactory {
- public:
- explicit QuicEpollAlarmFactory(QuicEpollServer* epoll_server);
- QuicEpollAlarmFactory(const QuicEpollAlarmFactory&) = delete;
- QuicEpollAlarmFactory& operator=(const QuicEpollAlarmFactory&) = delete;
- ~QuicEpollAlarmFactory() override;
-
- // QuicAlarmFactory interface.
- QuicAlarm* CreateAlarm(QuicAlarm::Delegate* delegate) override;
- QuicArenaScopedPtr<QuicAlarm> CreateAlarm(
- QuicArenaScopedPtr<QuicAlarm::Delegate> delegate,
- QuicConnectionArena* arena) override;
-
- private:
- QuicEpollServer* epoll_server_; // Not owned.
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_QUIC_EPOLL_ALARM_FACTORY_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_epoll_alarm_factory_test.cc b/chromium/net/third_party/quiche/src/quic/core/quic_epoll_alarm_factory_test.cc
deleted file mode 100644
index d815fae8f4d..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_epoll_alarm_factory_test.cc
+++ /dev/null
@@ -1,141 +0,0 @@
-// Copyright (c) 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_epoll_alarm_factory.h"
-
-#include "quic/platform/api/quic_epoll_test_tools.h"
-#include "quic/platform/api/quic_test.h"
-#include "net/quic/platform/impl/quic_epoll_clock.h"
-
-namespace quic {
-namespace test {
-namespace {
-
-class TestDelegate : public QuicAlarm::DelegateWithoutContext {
- public:
- TestDelegate() : fired_(false) {}
-
- void OnAlarm() override { fired_ = true; }
-
- bool fired() const { return fired_; }
-
- private:
- bool fired_;
-};
-
-// The boolean parameter denotes whether or not to use an arena.
-class QuicEpollAlarmFactoryTest : public QuicTestWithParam<bool> {
- protected:
- QuicEpollAlarmFactoryTest()
- : clock_(&epoll_server_), alarm_factory_(&epoll_server_) {}
-
- QuicConnectionArena* GetArenaParam() {
- return GetParam() ? &arena_ : nullptr;
- }
-
- const QuicEpollClock clock_;
- QuicEpollAlarmFactory alarm_factory_;
- QuicFakeEpollServer epoll_server_;
- QuicConnectionArena arena_;
-};
-
-INSTANTIATE_TEST_SUITE_P(UseArena,
- QuicEpollAlarmFactoryTest,
- ::testing::ValuesIn({true, false}),
- ::testing::PrintToStringParamName());
-
-TEST_P(QuicEpollAlarmFactoryTest, CreateAlarm) {
- QuicArenaScopedPtr<TestDelegate> delegate =
- QuicArenaScopedPtr<TestDelegate>(new TestDelegate());
- QuicArenaScopedPtr<QuicAlarm> alarm(
- alarm_factory_.CreateAlarm(std::move(delegate), GetArenaParam()));
-
- QuicTime start = clock_.Now();
- QuicTime::Delta delta = QuicTime::Delta::FromMicroseconds(1);
- alarm->Set(start + delta);
-
- epoll_server_.AdvanceByAndWaitForEventsAndExecuteCallbacks(
- delta.ToMicroseconds());
- EXPECT_EQ(start + delta, clock_.Now());
-}
-
-TEST_P(QuicEpollAlarmFactoryTest, CreateAlarmAndCancel) {
- QuicArenaScopedPtr<TestDelegate> delegate =
- QuicArenaScopedPtr<TestDelegate>(new TestDelegate());
- TestDelegate* unowned_delegate = delegate.get();
- QuicArenaScopedPtr<QuicAlarm> alarm(
- alarm_factory_.CreateAlarm(std::move(delegate), GetArenaParam()));
-
- QuicTime start = clock_.Now();
- QuicTime::Delta delta = QuicTime::Delta::FromMicroseconds(1);
- alarm->Set(start + delta);
- alarm->Cancel();
-
- epoll_server_.AdvanceByExactlyAndCallCallbacks(delta.ToMicroseconds());
- EXPECT_EQ(start + delta, clock_.Now());
- EXPECT_FALSE(unowned_delegate->fired());
-}
-
-TEST_P(QuicEpollAlarmFactoryTest, CreateAlarmAndReset) {
- QuicArenaScopedPtr<TestDelegate> delegate =
- QuicArenaScopedPtr<TestDelegate>(new TestDelegate());
- TestDelegate* unowned_delegate = delegate.get();
- QuicArenaScopedPtr<QuicAlarm> alarm(
- alarm_factory_.CreateAlarm(std::move(delegate), GetArenaParam()));
-
- QuicTime start = clock_.Now();
- QuicTime::Delta delta = QuicTime::Delta::FromMicroseconds(1);
- alarm->Set(clock_.Now() + delta);
- alarm->Cancel();
- QuicTime::Delta new_delta = QuicTime::Delta::FromMicroseconds(3);
- alarm->Set(clock_.Now() + new_delta);
-
- epoll_server_.AdvanceByExactlyAndCallCallbacks(delta.ToMicroseconds());
- EXPECT_EQ(start + delta, clock_.Now());
- EXPECT_FALSE(unowned_delegate->fired());
-
- epoll_server_.AdvanceByExactlyAndCallCallbacks(
- (new_delta - delta).ToMicroseconds());
- EXPECT_EQ(start + new_delta, clock_.Now());
- EXPECT_TRUE(unowned_delegate->fired());
-}
-
-TEST_P(QuicEpollAlarmFactoryTest, CreateAlarmAndUpdate) {
- QuicArenaScopedPtr<TestDelegate> delegate =
- QuicArenaScopedPtr<TestDelegate>(new TestDelegate());
- TestDelegate* unowned_delegate = delegate.get();
- QuicArenaScopedPtr<QuicAlarm> alarm(
- alarm_factory_.CreateAlarm(std::move(delegate), GetArenaParam()));
-
- QuicTime start = clock_.Now();
- QuicTime::Delta delta = QuicTime::Delta::FromMicroseconds(1);
- alarm->Set(clock_.Now() + delta);
- QuicTime::Delta new_delta = QuicTime::Delta::FromMicroseconds(3);
- alarm->Update(clock_.Now() + new_delta, QuicTime::Delta::FromMicroseconds(1));
-
- epoll_server_.AdvanceByExactlyAndCallCallbacks(delta.ToMicroseconds());
- EXPECT_EQ(start + delta, clock_.Now());
- EXPECT_FALSE(unowned_delegate->fired());
-
- // Move the alarm forward 1us and ensure it doesn't move forward.
- alarm->Update(clock_.Now() + new_delta, QuicTime::Delta::FromMicroseconds(2));
-
- epoll_server_.AdvanceByExactlyAndCallCallbacks(
- (new_delta - delta).ToMicroseconds());
- EXPECT_EQ(start + new_delta, clock_.Now());
- EXPECT_TRUE(unowned_delegate->fired());
-
- // Set the alarm via an update call.
- new_delta = QuicTime::Delta::FromMicroseconds(5);
- alarm->Update(clock_.Now() + new_delta, QuicTime::Delta::FromMicroseconds(1));
- EXPECT_TRUE(alarm->IsSet());
-
- // Update it with an uninitialized time and ensure it's cancelled.
- alarm->Update(QuicTime::Zero(), QuicTime::Delta::FromMicroseconds(1));
- EXPECT_FALSE(alarm->IsSet());
-}
-
-} // namespace
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_epoll_connection_helper.cc b/chromium/net/third_party/quiche/src/quic/core/quic_epoll_connection_helper.cc
deleted file mode 100644
index 42d2e0230cc..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_epoll_connection_helper.cc
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_epoll_connection_helper.h"
-
-#include <errno.h>
-#include <sys/socket.h>
-
-#include "quic/core/crypto/quic_random.h"
-
-namespace quic {
-
-QuicEpollConnectionHelper::QuicEpollConnectionHelper(
- QuicEpollServer* epoll_server, QuicAllocator allocator_type)
- : clock_(epoll_server),
- random_generator_(QuicRandom::GetInstance()),
- allocator_type_(allocator_type) {}
-
-QuicEpollConnectionHelper::~QuicEpollConnectionHelper() = default;
-
-const QuicClock* QuicEpollConnectionHelper::GetClock() const {
- return &clock_;
-}
-
-QuicRandom* QuicEpollConnectionHelper::GetRandomGenerator() {
- return random_generator_;
-}
-
-QuicBufferAllocator* QuicEpollConnectionHelper::GetStreamSendBufferAllocator() {
- if (allocator_type_ == QuicAllocator::BUFFER_POOL) {
- return &stream_buffer_allocator_;
- } else {
- QUICHE_DCHECK(allocator_type_ == QuicAllocator::SIMPLE);
- return &simple_buffer_allocator_;
- }
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_epoll_connection_helper.h b/chromium/net/third_party/quiche/src/quic/core/quic_epoll_connection_helper.h
deleted file mode 100644
index d363d6bc97f..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_epoll_connection_helper.h
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// The epoll-specific helper for QuicConnection which uses
-// EpollAlarm for alarms, and used an int fd_ for writing data.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_EPOLL_CONNECTION_HELPER_H_
-#define QUICHE_QUIC_CORE_QUIC_EPOLL_CONNECTION_HELPER_H_
-
-#include <sys/types.h>
-#include <set>
-
-#include "quic/core/quic_connection.h"
-#include "quic/core/quic_default_packet_writer.h"
-#include "quic/core/quic_packet_writer.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_simple_buffer_allocator.h"
-#include "quic/core/quic_time.h"
-#include "quic/platform/api/quic_epoll.h"
-#include "quic/platform/api/quic_stream_buffer_allocator.h"
-#include "net/quic/platform/impl/quic_epoll_clock.h"
-
-namespace quic {
-
-class QuicRandom;
-
-enum class QuicAllocator { SIMPLE, BUFFER_POOL };
-
-class QUIC_EXPORT_PRIVATE QuicEpollConnectionHelper
- : public QuicConnectionHelperInterface {
- public:
- QuicEpollConnectionHelper(QuicEpollServer* epoll_server,
- QuicAllocator allocator_type);
- QuicEpollConnectionHelper(const QuicEpollConnectionHelper&) = delete;
- QuicEpollConnectionHelper& operator=(const QuicEpollConnectionHelper&) =
- delete;
- ~QuicEpollConnectionHelper() override;
-
- // QuicConnectionHelperInterface
- const QuicClock* GetClock() const override;
- QuicRandom* GetRandomGenerator() override;
- QuicBufferAllocator* GetStreamSendBufferAllocator() override;
-
- private:
- const QuicEpollClock clock_;
- QuicRandom* random_generator_;
- // Set up allocators. They take up minimal memory before use.
- // Allocator for stream send buffers.
- QuicStreamBufferAllocator stream_buffer_allocator_;
- SimpleBufferAllocator simple_buffer_allocator_;
- QuicAllocator allocator_type_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_QUIC_EPOLL_CONNECTION_HELPER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_epoll_connection_helper_test.cc b/chromium/net/third_party/quiche/src/quic/core/quic_epoll_connection_helper_test.cc
deleted file mode 100644
index b50ce6d4d52..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_epoll_connection_helper_test.cc
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_epoll_connection_helper.h"
-
-#include "quic/core/crypto/quic_random.h"
-#include "quic/platform/api/quic_epoll_test_tools.h"
-#include "quic/platform/api/quic_test.h"
-
-namespace quic {
-namespace test {
-namespace {
-
-class QuicEpollConnectionHelperTest : public QuicTest {
- protected:
- QuicEpollConnectionHelperTest()
- : helper_(&epoll_server_, QuicAllocator::BUFFER_POOL) {}
-
- QuicFakeEpollServer epoll_server_;
- QuicEpollConnectionHelper helper_;
-};
-
-TEST_F(QuicEpollConnectionHelperTest, GetClock) {
- const QuicClock* clock = helper_.GetClock();
- QuicTime start = clock->Now();
-
- QuicTime::Delta delta = QuicTime::Delta::FromMilliseconds(5);
- epoll_server_.AdvanceBy(delta.ToMicroseconds());
-
- EXPECT_EQ(start + delta, clock->Now());
-}
-
-TEST_F(QuicEpollConnectionHelperTest, GetRandomGenerator) {
- QuicRandom* random = helper_.GetRandomGenerator();
- EXPECT_EQ(QuicRandom::GetInstance(), random);
-}
-
-} // namespace
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_error_codes.cc b/chromium/net/third_party/quiche/src/quic/core/quic_error_codes.cc
deleted file mode 100644
index c7da0ae17ba..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_error_codes.cc
+++ /dev/null
@@ -1,972 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_error_codes.h"
-
-#include <cstdint>
-#include <cstring>
-
-#include "absl/strings/str_cat.h"
-#include "third_party/boringssl/src/include/openssl/ssl.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-#define RETURN_STRING_LITERAL(x) \
- case x: \
- return #x;
-
-const char* QuicRstStreamErrorCodeToString(QuicRstStreamErrorCode error) {
- switch (error) {
- RETURN_STRING_LITERAL(QUIC_STREAM_NO_ERROR);
- RETURN_STRING_LITERAL(QUIC_ERROR_PROCESSING_STREAM);
- RETURN_STRING_LITERAL(QUIC_MULTIPLE_TERMINATION_OFFSETS);
- RETURN_STRING_LITERAL(QUIC_BAD_APPLICATION_PAYLOAD);
- RETURN_STRING_LITERAL(QUIC_STREAM_CONNECTION_ERROR);
- RETURN_STRING_LITERAL(QUIC_STREAM_PEER_GOING_AWAY);
- RETURN_STRING_LITERAL(QUIC_STREAM_CANCELLED);
- RETURN_STRING_LITERAL(QUIC_RST_ACKNOWLEDGEMENT);
- RETURN_STRING_LITERAL(QUIC_REFUSED_STREAM);
- RETURN_STRING_LITERAL(QUIC_INVALID_PROMISE_URL);
- RETURN_STRING_LITERAL(QUIC_UNAUTHORIZED_PROMISE_URL);
- RETURN_STRING_LITERAL(QUIC_DUPLICATE_PROMISE_URL);
- RETURN_STRING_LITERAL(QUIC_PROMISE_VARY_MISMATCH);
- RETURN_STRING_LITERAL(QUIC_INVALID_PROMISE_METHOD);
- RETURN_STRING_LITERAL(QUIC_PUSH_STREAM_TIMED_OUT);
- RETURN_STRING_LITERAL(QUIC_HEADERS_TOO_LARGE);
- RETURN_STRING_LITERAL(QUIC_STREAM_TTL_EXPIRED);
- RETURN_STRING_LITERAL(QUIC_DATA_AFTER_CLOSE_OFFSET);
- RETURN_STRING_LITERAL(QUIC_STREAM_GENERAL_PROTOCOL_ERROR);
- RETURN_STRING_LITERAL(QUIC_STREAM_INTERNAL_ERROR);
- RETURN_STRING_LITERAL(QUIC_STREAM_STREAM_CREATION_ERROR);
- RETURN_STRING_LITERAL(QUIC_STREAM_CLOSED_CRITICAL_STREAM);
- RETURN_STRING_LITERAL(QUIC_STREAM_FRAME_UNEXPECTED);
- RETURN_STRING_LITERAL(QUIC_STREAM_FRAME_ERROR);
- RETURN_STRING_LITERAL(QUIC_STREAM_EXCESSIVE_LOAD);
- RETURN_STRING_LITERAL(QUIC_STREAM_ID_ERROR);
- RETURN_STRING_LITERAL(QUIC_STREAM_SETTINGS_ERROR);
- RETURN_STRING_LITERAL(QUIC_STREAM_MISSING_SETTINGS);
- RETURN_STRING_LITERAL(QUIC_STREAM_REQUEST_REJECTED);
- RETURN_STRING_LITERAL(QUIC_STREAM_REQUEST_INCOMPLETE);
- RETURN_STRING_LITERAL(QUIC_STREAM_CONNECT_ERROR);
- RETURN_STRING_LITERAL(QUIC_STREAM_VERSION_FALLBACK);
- RETURN_STRING_LITERAL(QUIC_STREAM_DECOMPRESSION_FAILED);
- RETURN_STRING_LITERAL(QUIC_STREAM_ENCODER_STREAM_ERROR);
- RETURN_STRING_LITERAL(QUIC_STREAM_DECODER_STREAM_ERROR);
- RETURN_STRING_LITERAL(QUIC_STREAM_UNKNOWN_APPLICATION_ERROR_CODE);
- RETURN_STRING_LITERAL(QUIC_STREAM_WEBTRANSPORT_SESSION_GONE);
- RETURN_STRING_LITERAL(
- QUIC_STREAM_WEBTRANSPORT_BUFFERED_STREAMS_LIMIT_EXCEEDED);
- RETURN_STRING_LITERAL(QUIC_STREAM_LAST_ERROR);
- }
- // Return a default value so that we return this when |error| doesn't match
- // any of the QuicRstStreamErrorCodes. This can happen when the RstStream
- // frame sent by the peer (attacker) has invalid error code.
- return "INVALID_RST_STREAM_ERROR_CODE";
-}
-
-const char* QuicErrorCodeToString(QuicErrorCode error) {
- switch (error) {
- RETURN_STRING_LITERAL(QUIC_NO_ERROR);
- RETURN_STRING_LITERAL(QUIC_INTERNAL_ERROR);
- RETURN_STRING_LITERAL(QUIC_STREAM_DATA_AFTER_TERMINATION);
- RETURN_STRING_LITERAL(QUIC_INVALID_PACKET_HEADER);
- RETURN_STRING_LITERAL(QUIC_INVALID_FRAME_DATA);
- RETURN_STRING_LITERAL(QUIC_MISSING_PAYLOAD);
- RETURN_STRING_LITERAL(QUIC_INVALID_FEC_DATA);
- RETURN_STRING_LITERAL(QUIC_INVALID_STREAM_DATA);
- RETURN_STRING_LITERAL(QUIC_OVERLAPPING_STREAM_DATA);
- RETURN_STRING_LITERAL(QUIC_UNENCRYPTED_STREAM_DATA);
- RETURN_STRING_LITERAL(QUIC_INVALID_RST_STREAM_DATA);
- RETURN_STRING_LITERAL(QUIC_INVALID_CONNECTION_CLOSE_DATA);
- RETURN_STRING_LITERAL(QUIC_INVALID_GOAWAY_DATA);
- RETURN_STRING_LITERAL(QUIC_INVALID_WINDOW_UPDATE_DATA);
- RETURN_STRING_LITERAL(QUIC_INVALID_BLOCKED_DATA);
- RETURN_STRING_LITERAL(QUIC_INVALID_STOP_WAITING_DATA);
- RETURN_STRING_LITERAL(QUIC_INVALID_PATH_CLOSE_DATA);
- RETURN_STRING_LITERAL(QUIC_INVALID_ACK_DATA);
- RETURN_STRING_LITERAL(QUIC_INVALID_VERSION_NEGOTIATION_PACKET);
- RETURN_STRING_LITERAL(QUIC_INVALID_PUBLIC_RST_PACKET);
- RETURN_STRING_LITERAL(QUIC_DECRYPTION_FAILURE);
- RETURN_STRING_LITERAL(QUIC_ENCRYPTION_FAILURE);
- RETURN_STRING_LITERAL(QUIC_PACKET_TOO_LARGE);
- RETURN_STRING_LITERAL(QUIC_PEER_GOING_AWAY);
- RETURN_STRING_LITERAL(QUIC_HANDSHAKE_FAILED);
- RETURN_STRING_LITERAL(QUIC_CRYPTO_TAGS_OUT_OF_ORDER);
- RETURN_STRING_LITERAL(QUIC_CRYPTO_TOO_MANY_ENTRIES);
- RETURN_STRING_LITERAL(QUIC_CRYPTO_TOO_MANY_REJECTS);
- RETURN_STRING_LITERAL(QUIC_CRYPTO_INVALID_VALUE_LENGTH)
- RETURN_STRING_LITERAL(QUIC_CRYPTO_MESSAGE_AFTER_HANDSHAKE_COMPLETE);
- RETURN_STRING_LITERAL(QUIC_CRYPTO_INTERNAL_ERROR);
- RETURN_STRING_LITERAL(QUIC_CRYPTO_VERSION_NOT_SUPPORTED);
- RETURN_STRING_LITERAL(QUIC_CRYPTO_NO_SUPPORT);
- RETURN_STRING_LITERAL(QUIC_INVALID_CRYPTO_MESSAGE_TYPE);
- RETURN_STRING_LITERAL(QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER);
- RETURN_STRING_LITERAL(QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND);
- RETURN_STRING_LITERAL(QUIC_CRYPTO_MESSAGE_PARAMETER_NO_OVERLAP);
- RETURN_STRING_LITERAL(QUIC_CRYPTO_MESSAGE_INDEX_NOT_FOUND);
- RETURN_STRING_LITERAL(QUIC_UNSUPPORTED_PROOF_DEMAND);
- RETURN_STRING_LITERAL(QUIC_INVALID_STREAM_ID);
- RETURN_STRING_LITERAL(QUIC_INVALID_PRIORITY);
- RETURN_STRING_LITERAL(QUIC_TOO_MANY_OPEN_STREAMS);
- RETURN_STRING_LITERAL(QUIC_PUBLIC_RESET);
- RETURN_STRING_LITERAL(QUIC_INVALID_VERSION);
- RETURN_STRING_LITERAL(QUIC_INVALID_0RTT_PACKET_NUMBER_OUT_OF_ORDER);
- RETURN_STRING_LITERAL(QUIC_INVALID_HEADER_ID);
- RETURN_STRING_LITERAL(QUIC_INVALID_NEGOTIATED_VALUE);
- RETURN_STRING_LITERAL(QUIC_DECOMPRESSION_FAILURE);
- RETURN_STRING_LITERAL(QUIC_NETWORK_IDLE_TIMEOUT);
- RETURN_STRING_LITERAL(QUIC_HANDSHAKE_TIMEOUT);
- RETURN_STRING_LITERAL(QUIC_ERROR_MIGRATING_ADDRESS);
- RETURN_STRING_LITERAL(QUIC_ERROR_MIGRATING_PORT);
- RETURN_STRING_LITERAL(QUIC_PACKET_WRITE_ERROR);
- RETURN_STRING_LITERAL(QUIC_PACKET_READ_ERROR);
- RETURN_STRING_LITERAL(QUIC_EMPTY_STREAM_FRAME_NO_FIN);
- RETURN_STRING_LITERAL(QUIC_INVALID_HEADERS_STREAM_DATA);
- RETURN_STRING_LITERAL(QUIC_HEADERS_STREAM_DATA_DECOMPRESS_FAILURE);
- RETURN_STRING_LITERAL(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA);
- RETURN_STRING_LITERAL(QUIC_FLOW_CONTROL_SENT_TOO_MUCH_DATA);
- RETURN_STRING_LITERAL(QUIC_FLOW_CONTROL_INVALID_WINDOW);
- RETURN_STRING_LITERAL(QUIC_CONNECTION_IP_POOLED);
- RETURN_STRING_LITERAL(QUIC_PROOF_INVALID);
- RETURN_STRING_LITERAL(QUIC_CRYPTO_DUPLICATE_TAG);
- RETURN_STRING_LITERAL(QUIC_CRYPTO_ENCRYPTION_LEVEL_INCORRECT);
- RETURN_STRING_LITERAL(QUIC_CRYPTO_SERVER_CONFIG_EXPIRED);
- RETURN_STRING_LITERAL(QUIC_INVALID_CHANNEL_ID_SIGNATURE);
- RETURN_STRING_LITERAL(QUIC_CRYPTO_SYMMETRIC_KEY_SETUP_FAILED);
- RETURN_STRING_LITERAL(QUIC_CRYPTO_MESSAGE_WHILE_VALIDATING_CLIENT_HELLO);
- RETURN_STRING_LITERAL(QUIC_CRYPTO_UPDATE_BEFORE_HANDSHAKE_COMPLETE);
- RETURN_STRING_LITERAL(QUIC_VERSION_NEGOTIATION_MISMATCH);
- RETURN_STRING_LITERAL(QUIC_TOO_MANY_OUTSTANDING_SENT_PACKETS);
- RETURN_STRING_LITERAL(QUIC_TOO_MANY_OUTSTANDING_RECEIVED_PACKETS);
- RETURN_STRING_LITERAL(QUIC_CONNECTION_CANCELLED);
- RETURN_STRING_LITERAL(QUIC_BAD_PACKET_LOSS_RATE);
- RETURN_STRING_LITERAL(QUIC_PUBLIC_RESETS_POST_HANDSHAKE);
- RETURN_STRING_LITERAL(QUIC_FAILED_TO_SERIALIZE_PACKET);
- RETURN_STRING_LITERAL(QUIC_TOO_MANY_AVAILABLE_STREAMS);
- RETURN_STRING_LITERAL(QUIC_UNENCRYPTED_FEC_DATA);
- RETURN_STRING_LITERAL(QUIC_BAD_MULTIPATH_FLAG);
- RETURN_STRING_LITERAL(QUIC_IP_ADDRESS_CHANGED);
- RETURN_STRING_LITERAL(QUIC_CONNECTION_MIGRATION_NO_MIGRATABLE_STREAMS);
- RETURN_STRING_LITERAL(QUIC_CONNECTION_MIGRATION_TOO_MANY_CHANGES);
- RETURN_STRING_LITERAL(QUIC_CONNECTION_MIGRATION_NO_NEW_NETWORK);
- RETURN_STRING_LITERAL(QUIC_CONNECTION_MIGRATION_NON_MIGRATABLE_STREAM);
- RETURN_STRING_LITERAL(QUIC_TOO_MANY_RTOS);
- RETURN_STRING_LITERAL(QUIC_ATTEMPT_TO_SEND_UNENCRYPTED_STREAM_DATA);
- RETURN_STRING_LITERAL(QUIC_MAYBE_CORRUPTED_MEMORY);
- RETURN_STRING_LITERAL(QUIC_CRYPTO_CHLO_TOO_LARGE);
- RETURN_STRING_LITERAL(QUIC_MULTIPATH_PATH_DOES_NOT_EXIST);
- RETURN_STRING_LITERAL(QUIC_MULTIPATH_PATH_NOT_ACTIVE);
- RETURN_STRING_LITERAL(QUIC_TOO_MANY_STREAM_DATA_INTERVALS);
- RETURN_STRING_LITERAL(QUIC_STREAM_SEQUENCER_INVALID_STATE);
- RETURN_STRING_LITERAL(QUIC_TOO_MANY_SESSIONS_ON_SERVER);
- RETURN_STRING_LITERAL(QUIC_STREAM_LENGTH_OVERFLOW);
- RETURN_STRING_LITERAL(QUIC_CONNECTION_MIGRATION_DISABLED_BY_CONFIG);
- RETURN_STRING_LITERAL(QUIC_CONNECTION_MIGRATION_INTERNAL_ERROR);
- RETURN_STRING_LITERAL(QUIC_INVALID_MAX_DATA_FRAME_DATA);
- RETURN_STRING_LITERAL(QUIC_INVALID_MAX_STREAM_DATA_FRAME_DATA);
- RETURN_STRING_LITERAL(QUIC_INVALID_STREAM_BLOCKED_DATA);
- RETURN_STRING_LITERAL(QUIC_MAX_STREAMS_DATA);
- RETURN_STRING_LITERAL(QUIC_STREAMS_BLOCKED_DATA);
- RETURN_STRING_LITERAL(QUIC_INVALID_NEW_CONNECTION_ID_DATA);
- RETURN_STRING_LITERAL(QUIC_INVALID_RETIRE_CONNECTION_ID_DATA);
- RETURN_STRING_LITERAL(QUIC_CONNECTION_ID_LIMIT_ERROR);
- RETURN_STRING_LITERAL(QUIC_TOO_MANY_CONNECTION_ID_WAITING_TO_RETIRE);
- RETURN_STRING_LITERAL(QUIC_INVALID_STOP_SENDING_FRAME_DATA);
- RETURN_STRING_LITERAL(QUIC_INVALID_PATH_CHALLENGE_DATA);
- RETURN_STRING_LITERAL(QUIC_INVALID_PATH_RESPONSE_DATA);
- RETURN_STRING_LITERAL(QUIC_CONNECTION_MIGRATION_HANDSHAKE_UNCONFIRMED);
- RETURN_STRING_LITERAL(QUIC_PEER_PORT_CHANGE_HANDSHAKE_UNCONFIRMED);
- RETURN_STRING_LITERAL(QUIC_INVALID_MESSAGE_DATA);
- RETURN_STRING_LITERAL(IETF_QUIC_PROTOCOL_VIOLATION);
- RETURN_STRING_LITERAL(QUIC_INVALID_NEW_TOKEN);
- RETURN_STRING_LITERAL(QUIC_DATA_RECEIVED_ON_WRITE_UNIDIRECTIONAL_STREAM);
- RETURN_STRING_LITERAL(QUIC_TRY_TO_WRITE_DATA_ON_READ_UNIDIRECTIONAL_STREAM);
- RETURN_STRING_LITERAL(QUIC_STREAMS_BLOCKED_ERROR);
- RETURN_STRING_LITERAL(QUIC_MAX_STREAMS_ERROR);
- RETURN_STRING_LITERAL(QUIC_HTTP_DECODER_ERROR);
- RETURN_STRING_LITERAL(QUIC_STALE_CONNECTION_CANCELLED);
- RETURN_STRING_LITERAL(QUIC_IETF_GQUIC_ERROR_MISSING);
- RETURN_STRING_LITERAL(
- QUIC_WINDOW_UPDATE_RECEIVED_ON_READ_UNIDIRECTIONAL_STREAM);
- RETURN_STRING_LITERAL(QUIC_TOO_MANY_BUFFERED_CONTROL_FRAMES);
- RETURN_STRING_LITERAL(QUIC_TRANSPORT_INVALID_CLIENT_INDICATION);
- RETURN_STRING_LITERAL(QUIC_QPACK_DECOMPRESSION_FAILED);
- RETURN_STRING_LITERAL(QUIC_QPACK_ENCODER_STREAM_ERROR);
- RETURN_STRING_LITERAL(QUIC_QPACK_DECODER_STREAM_ERROR);
- RETURN_STRING_LITERAL(QUIC_QPACK_ENCODER_STREAM_INTEGER_TOO_LARGE);
- RETURN_STRING_LITERAL(QUIC_QPACK_ENCODER_STREAM_STRING_LITERAL_TOO_LONG);
- RETURN_STRING_LITERAL(QUIC_QPACK_ENCODER_STREAM_HUFFMAN_ENCODING_ERROR);
- RETURN_STRING_LITERAL(QUIC_QPACK_ENCODER_STREAM_INVALID_STATIC_ENTRY);
- RETURN_STRING_LITERAL(QUIC_QPACK_ENCODER_STREAM_ERROR_INSERTING_STATIC);
- RETURN_STRING_LITERAL(
- QUIC_QPACK_ENCODER_STREAM_INSERTION_INVALID_RELATIVE_INDEX);
- RETURN_STRING_LITERAL(
- QUIC_QPACK_ENCODER_STREAM_INSERTION_DYNAMIC_ENTRY_NOT_FOUND);
- RETURN_STRING_LITERAL(QUIC_QPACK_ENCODER_STREAM_ERROR_INSERTING_DYNAMIC);
- RETURN_STRING_LITERAL(QUIC_QPACK_ENCODER_STREAM_ERROR_INSERTING_LITERAL);
- RETURN_STRING_LITERAL(
- QUIC_QPACK_ENCODER_STREAM_DUPLICATE_INVALID_RELATIVE_INDEX);
- RETURN_STRING_LITERAL(
- QUIC_QPACK_ENCODER_STREAM_DUPLICATE_DYNAMIC_ENTRY_NOT_FOUND);
- RETURN_STRING_LITERAL(QUIC_QPACK_ENCODER_STREAM_SET_DYNAMIC_TABLE_CAPACITY);
- RETURN_STRING_LITERAL(QUIC_QPACK_DECODER_STREAM_INTEGER_TOO_LARGE);
- RETURN_STRING_LITERAL(QUIC_QPACK_DECODER_STREAM_INVALID_ZERO_INCREMENT);
- RETURN_STRING_LITERAL(QUIC_QPACK_DECODER_STREAM_INCREMENT_OVERFLOW);
- RETURN_STRING_LITERAL(QUIC_QPACK_DECODER_STREAM_IMPOSSIBLE_INSERT_COUNT);
- RETURN_STRING_LITERAL(QUIC_QPACK_DECODER_STREAM_INCORRECT_ACKNOWLEDGEMENT);
- RETURN_STRING_LITERAL(QUIC_STREAM_DATA_BEYOND_CLOSE_OFFSET);
- RETURN_STRING_LITERAL(QUIC_STREAM_MULTIPLE_OFFSET);
- RETURN_STRING_LITERAL(QUIC_HTTP_FRAME_TOO_LARGE);
- RETURN_STRING_LITERAL(QUIC_HTTP_FRAME_ERROR);
- RETURN_STRING_LITERAL(QUIC_HTTP_FRAME_UNEXPECTED_ON_SPDY_STREAM);
- RETURN_STRING_LITERAL(QUIC_HTTP_FRAME_UNEXPECTED_ON_CONTROL_STREAM);
- RETURN_STRING_LITERAL(QUIC_HTTP_INVALID_FRAME_SEQUENCE_ON_SPDY_STREAM);
- RETURN_STRING_LITERAL(QUIC_HTTP_INVALID_FRAME_SEQUENCE_ON_CONTROL_STREAM);
- RETURN_STRING_LITERAL(QUIC_HTTP_DUPLICATE_UNIDIRECTIONAL_STREAM);
- RETURN_STRING_LITERAL(QUIC_HTTP_SERVER_INITIATED_BIDIRECTIONAL_STREAM);
- RETURN_STRING_LITERAL(QUIC_HTTP_STREAM_WRONG_DIRECTION);
- RETURN_STRING_LITERAL(QUIC_HTTP_CLOSED_CRITICAL_STREAM);
- RETURN_STRING_LITERAL(QUIC_HTTP_MISSING_SETTINGS_FRAME);
- RETURN_STRING_LITERAL(QUIC_HTTP_DUPLICATE_SETTING_IDENTIFIER);
- RETURN_STRING_LITERAL(QUIC_HTTP_INVALID_MAX_PUSH_ID);
- RETURN_STRING_LITERAL(QUIC_HTTP_STREAM_LIMIT_TOO_LOW);
- RETURN_STRING_LITERAL(QUIC_HTTP_ZERO_RTT_RESUMPTION_SETTINGS_MISMATCH);
- RETURN_STRING_LITERAL(QUIC_HTTP_ZERO_RTT_REJECTION_SETTINGS_MISMATCH);
- RETURN_STRING_LITERAL(QUIC_HTTP_GOAWAY_INVALID_STREAM_ID);
- RETURN_STRING_LITERAL(QUIC_HTTP_GOAWAY_ID_LARGER_THAN_PREVIOUS);
- RETURN_STRING_LITERAL(QUIC_HTTP_RECEIVE_SPDY_SETTING);
- RETURN_STRING_LITERAL(QUIC_HTTP_RECEIVE_SPDY_FRAME);
- RETURN_STRING_LITERAL(QUIC_HTTP_RECEIVE_SERVER_PUSH);
- RETURN_STRING_LITERAL(QUIC_HTTP_INVALID_SETTING_VALUE);
- RETURN_STRING_LITERAL(QUIC_HPACK_INDEX_VARINT_ERROR);
- RETURN_STRING_LITERAL(QUIC_HPACK_NAME_LENGTH_VARINT_ERROR);
- RETURN_STRING_LITERAL(QUIC_HPACK_VALUE_LENGTH_VARINT_ERROR);
- RETURN_STRING_LITERAL(QUIC_HPACK_NAME_TOO_LONG);
- RETURN_STRING_LITERAL(QUIC_HPACK_VALUE_TOO_LONG);
- RETURN_STRING_LITERAL(QUIC_HPACK_NAME_HUFFMAN_ERROR);
- RETURN_STRING_LITERAL(QUIC_HPACK_VALUE_HUFFMAN_ERROR);
- RETURN_STRING_LITERAL(QUIC_HPACK_MISSING_DYNAMIC_TABLE_SIZE_UPDATE);
- RETURN_STRING_LITERAL(QUIC_HPACK_INVALID_INDEX);
- RETURN_STRING_LITERAL(QUIC_HPACK_INVALID_NAME_INDEX);
- RETURN_STRING_LITERAL(QUIC_HPACK_DYNAMIC_TABLE_SIZE_UPDATE_NOT_ALLOWED);
- RETURN_STRING_LITERAL(
- QUIC_HPACK_INITIAL_TABLE_SIZE_UPDATE_IS_ABOVE_LOW_WATER_MARK);
- RETURN_STRING_LITERAL(
- QUIC_HPACK_TABLE_SIZE_UPDATE_IS_ABOVE_ACKNOWLEDGED_SETTING);
- RETURN_STRING_LITERAL(QUIC_HPACK_TRUNCATED_BLOCK);
- RETURN_STRING_LITERAL(QUIC_HPACK_FRAGMENT_TOO_LONG);
- RETURN_STRING_LITERAL(QUIC_HPACK_COMPRESSED_HEADER_SIZE_EXCEEDS_LIMIT);
- RETURN_STRING_LITERAL(QUIC_ZERO_RTT_UNRETRANSMITTABLE);
- RETURN_STRING_LITERAL(QUIC_ZERO_RTT_REJECTION_LIMIT_REDUCED);
- RETURN_STRING_LITERAL(QUIC_ZERO_RTT_RESUMPTION_LIMIT_REDUCED);
- RETURN_STRING_LITERAL(QUIC_SILENT_IDLE_TIMEOUT);
- RETURN_STRING_LITERAL(QUIC_MISSING_WRITE_KEYS);
- RETURN_STRING_LITERAL(QUIC_KEY_UPDATE_ERROR);
- RETURN_STRING_LITERAL(QUIC_AEAD_LIMIT_REACHED);
- RETURN_STRING_LITERAL(QUIC_MAX_AGE_TIMEOUT);
- RETURN_STRING_LITERAL(QUIC_INVALID_PRIORITY_UPDATE);
- RETURN_STRING_LITERAL(QUIC_TLS_BAD_CERTIFICATE);
- RETURN_STRING_LITERAL(QUIC_TLS_UNSUPPORTED_CERTIFICATE);
- RETURN_STRING_LITERAL(QUIC_TLS_CERTIFICATE_REVOKED);
- RETURN_STRING_LITERAL(QUIC_TLS_CERTIFICATE_EXPIRED);
- RETURN_STRING_LITERAL(QUIC_TLS_CERTIFICATE_UNKNOWN);
- RETURN_STRING_LITERAL(QUIC_TLS_INTERNAL_ERROR);
- RETURN_STRING_LITERAL(QUIC_TLS_UNRECOGNIZED_NAME);
- RETURN_STRING_LITERAL(QUIC_TLS_CERTIFICATE_REQUIRED);
- RETURN_STRING_LITERAL(QUIC_INVALID_CHARACTER_IN_FIELD_VALUE);
- RETURN_STRING_LITERAL(QUIC_TLS_UNEXPECTED_KEYING_MATERIAL_EXPORT_LABEL);
- RETURN_STRING_LITERAL(QUIC_TLS_KEYING_MATERIAL_EXPORTS_MISMATCH);
- RETURN_STRING_LITERAL(QUIC_TLS_KEYING_MATERIAL_EXPORT_NOT_AVAILABLE);
- RETURN_STRING_LITERAL(QUIC_UNEXPECTED_DATA_BEFORE_ENCRYPTION_ESTABLISHED);
-
- RETURN_STRING_LITERAL(QUIC_LAST_ERROR);
- // Intentionally have no default case, so we'll break the build
- // if we add errors and don't put them here.
- }
- // Return a default value so that we return this when |error| doesn't match
- // any of the QuicErrorCodes. This can happen when the ConnectionClose
- // frame sent by the peer (attacker) has invalid error code.
- return "INVALID_ERROR_CODE";
-}
-
-std::string QuicIetfTransportErrorCodeString(QuicIetfTransportErrorCodes c) {
- if (c >= CRYPTO_ERROR_FIRST && c <= CRYPTO_ERROR_LAST) {
- const int tls_error = static_cast<int>(c - CRYPTO_ERROR_FIRST);
- const char* tls_error_description = SSL_alert_desc_string_long(tls_error);
- if (strcmp("unknown", tls_error_description) != 0) {
- return absl::StrCat("CRYPTO_ERROR(", tls_error_description, ")");
- }
- return absl::StrCat("CRYPTO_ERROR(unknown(", tls_error, "))");
- }
-
- switch (c) {
- RETURN_STRING_LITERAL(NO_IETF_QUIC_ERROR);
- RETURN_STRING_LITERAL(INTERNAL_ERROR);
- RETURN_STRING_LITERAL(SERVER_BUSY_ERROR);
- RETURN_STRING_LITERAL(FLOW_CONTROL_ERROR);
- RETURN_STRING_LITERAL(STREAM_LIMIT_ERROR);
- RETURN_STRING_LITERAL(STREAM_STATE_ERROR);
- RETURN_STRING_LITERAL(FINAL_SIZE_ERROR);
- RETURN_STRING_LITERAL(FRAME_ENCODING_ERROR);
- RETURN_STRING_LITERAL(TRANSPORT_PARAMETER_ERROR);
- RETURN_STRING_LITERAL(CONNECTION_ID_LIMIT_ERROR);
- RETURN_STRING_LITERAL(PROTOCOL_VIOLATION);
- RETURN_STRING_LITERAL(INVALID_TOKEN);
- RETURN_STRING_LITERAL(CRYPTO_BUFFER_EXCEEDED);
- RETURN_STRING_LITERAL(KEY_UPDATE_ERROR);
- RETURN_STRING_LITERAL(AEAD_LIMIT_REACHED);
- // CRYPTO_ERROR is handled in the if before this switch, these cases do not
- // change behavior and are only here to make the compiler happy.
- case CRYPTO_ERROR_FIRST:
- case CRYPTO_ERROR_LAST:
- QUICHE_DCHECK(false) << "Unexpected error " << static_cast<uint64_t>(c);
- break;
- }
-
- return absl::StrCat("Unknown(", static_cast<uint64_t>(c), ")");
-}
-
-std::ostream& operator<<(std::ostream& os,
- const QuicIetfTransportErrorCodes& c) {
- os << QuicIetfTransportErrorCodeString(c);
- return os;
-}
-
-QuicErrorCodeToIetfMapping QuicErrorCodeToTransportErrorCode(
- QuicErrorCode error) {
- switch (error) {
- case QUIC_NO_ERROR:
- return {true, static_cast<uint64_t>(NO_IETF_QUIC_ERROR)};
- case QUIC_INTERNAL_ERROR:
- return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
- case QUIC_STREAM_DATA_AFTER_TERMINATION:
- return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
- case QUIC_INVALID_PACKET_HEADER:
- return {true, static_cast<uint64_t>(FRAME_ENCODING_ERROR)};
- case QUIC_INVALID_FRAME_DATA:
- return {true, static_cast<uint64_t>(FRAME_ENCODING_ERROR)};
- case QUIC_MISSING_PAYLOAD:
- return {true, static_cast<uint64_t>(FRAME_ENCODING_ERROR)};
- case QUIC_INVALID_FEC_DATA:
- return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
- case QUIC_INVALID_STREAM_DATA:
- return {true, static_cast<uint64_t>(FRAME_ENCODING_ERROR)};
- case QUIC_OVERLAPPING_STREAM_DATA:
- return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
- case QUIC_UNENCRYPTED_STREAM_DATA:
- return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
- case QUIC_ATTEMPT_TO_SEND_UNENCRYPTED_STREAM_DATA:
- return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
- case QUIC_MAYBE_CORRUPTED_MEMORY:
- return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
- case QUIC_UNENCRYPTED_FEC_DATA:
- return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
- case QUIC_INVALID_RST_STREAM_DATA:
- return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
- case QUIC_INVALID_CONNECTION_CLOSE_DATA:
- return {true, static_cast<uint64_t>(FRAME_ENCODING_ERROR)};
- case QUIC_INVALID_GOAWAY_DATA:
- return {true, static_cast<uint64_t>(FRAME_ENCODING_ERROR)};
- case QUIC_INVALID_WINDOW_UPDATE_DATA:
- return {true, static_cast<uint64_t>(FRAME_ENCODING_ERROR)};
- case QUIC_INVALID_BLOCKED_DATA:
- return {true, static_cast<uint64_t>(FRAME_ENCODING_ERROR)};
- case QUIC_INVALID_STOP_WAITING_DATA:
- return {true, static_cast<uint64_t>(FRAME_ENCODING_ERROR)};
- case QUIC_INVALID_PATH_CLOSE_DATA:
- return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
- case QUIC_INVALID_ACK_DATA:
- return {true, static_cast<uint64_t>(FRAME_ENCODING_ERROR)};
- case QUIC_INVALID_MESSAGE_DATA:
- return {true, static_cast<uint64_t>(FRAME_ENCODING_ERROR)};
- case QUIC_INVALID_VERSION_NEGOTIATION_PACKET:
- return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
- case QUIC_INVALID_PUBLIC_RST_PACKET:
- return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
- case QUIC_DECRYPTION_FAILURE:
- return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
- case QUIC_ENCRYPTION_FAILURE:
- return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
- case QUIC_PACKET_TOO_LARGE:
- return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
- case QUIC_PEER_GOING_AWAY:
- return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
- case QUIC_INVALID_STREAM_ID:
- return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
- case QUIC_INVALID_PRIORITY:
- return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
- case QUIC_TOO_MANY_OPEN_STREAMS:
- return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
- case QUIC_TOO_MANY_AVAILABLE_STREAMS:
- return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
- case QUIC_PUBLIC_RESET:
- return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
- case QUIC_INVALID_VERSION:
- return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
- case QUIC_INVALID_0RTT_PACKET_NUMBER_OUT_OF_ORDER:
- return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
- case QUIC_INVALID_HEADER_ID:
- return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
- case QUIC_INVALID_NEGOTIATED_VALUE:
- return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
- case QUIC_DECOMPRESSION_FAILURE:
- return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
- case QUIC_NETWORK_IDLE_TIMEOUT:
- return {true, static_cast<uint64_t>(NO_IETF_QUIC_ERROR)};
- case QUIC_SILENT_IDLE_TIMEOUT:
- return {true, static_cast<uint64_t>(NO_IETF_QUIC_ERROR)};
- case QUIC_HANDSHAKE_TIMEOUT:
- return {true, static_cast<uint64_t>(NO_IETF_QUIC_ERROR)};
- case QUIC_ERROR_MIGRATING_ADDRESS:
- return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
- case QUIC_ERROR_MIGRATING_PORT:
- return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
- case QUIC_PACKET_WRITE_ERROR:
- return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
- case QUIC_PACKET_READ_ERROR:
- return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
- case QUIC_EMPTY_STREAM_FRAME_NO_FIN:
- return {true, static_cast<uint64_t>(FRAME_ENCODING_ERROR)};
- case QUIC_INVALID_HEADERS_STREAM_DATA:
- return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
- case QUIC_HEADERS_STREAM_DATA_DECOMPRESS_FAILURE:
- return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
- case QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA:
- return {true, static_cast<uint64_t>(FLOW_CONTROL_ERROR)};
- case QUIC_FLOW_CONTROL_SENT_TOO_MUCH_DATA:
- return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
- case QUIC_FLOW_CONTROL_INVALID_WINDOW:
- return {true, static_cast<uint64_t>(FLOW_CONTROL_ERROR)};
- case QUIC_CONNECTION_IP_POOLED:
- return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
- case QUIC_TOO_MANY_OUTSTANDING_SENT_PACKETS:
- return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
- case QUIC_TOO_MANY_OUTSTANDING_RECEIVED_PACKETS:
- return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
- case QUIC_CONNECTION_CANCELLED:
- return {true, static_cast<uint64_t>(NO_IETF_QUIC_ERROR)};
- case QUIC_BAD_PACKET_LOSS_RATE:
- return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
- case QUIC_PUBLIC_RESETS_POST_HANDSHAKE:
- return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
- case QUIC_FAILED_TO_SERIALIZE_PACKET:
- return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
- case QUIC_TOO_MANY_RTOS:
- return {true, static_cast<uint64_t>(NO_IETF_QUIC_ERROR)};
- case QUIC_HANDSHAKE_FAILED:
- return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
- case QUIC_CRYPTO_TAGS_OUT_OF_ORDER:
- return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
- case QUIC_CRYPTO_TOO_MANY_ENTRIES:
- return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
- case QUIC_CRYPTO_INVALID_VALUE_LENGTH:
- return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
- case QUIC_CRYPTO_MESSAGE_AFTER_HANDSHAKE_COMPLETE:
- return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
- case QUIC_INVALID_CRYPTO_MESSAGE_TYPE:
- return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
- case QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER:
- return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
- case QUIC_INVALID_CHANNEL_ID_SIGNATURE:
- return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
- case QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND:
- return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
- case QUIC_CRYPTO_MESSAGE_PARAMETER_NO_OVERLAP:
- return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
- case QUIC_CRYPTO_MESSAGE_INDEX_NOT_FOUND:
- return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
- case QUIC_UNSUPPORTED_PROOF_DEMAND:
- return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
- case QUIC_CRYPTO_INTERNAL_ERROR:
- return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
- case QUIC_CRYPTO_VERSION_NOT_SUPPORTED:
- return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
- case QUIC_CRYPTO_NO_SUPPORT:
- return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
- case QUIC_CRYPTO_TOO_MANY_REJECTS:
- return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
- case QUIC_PROOF_INVALID:
- return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
- case QUIC_CRYPTO_DUPLICATE_TAG:
- return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
- case QUIC_CRYPTO_ENCRYPTION_LEVEL_INCORRECT:
- return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
- case QUIC_CRYPTO_SERVER_CONFIG_EXPIRED:
- return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
- case QUIC_CRYPTO_SYMMETRIC_KEY_SETUP_FAILED:
- return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
- case QUIC_CRYPTO_MESSAGE_WHILE_VALIDATING_CLIENT_HELLO:
- return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
- case QUIC_CRYPTO_UPDATE_BEFORE_HANDSHAKE_COMPLETE:
- return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
- case QUIC_CRYPTO_CHLO_TOO_LARGE:
- return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
- case QUIC_VERSION_NEGOTIATION_MISMATCH:
- return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
- case QUIC_BAD_MULTIPATH_FLAG:
- return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
- case QUIC_MULTIPATH_PATH_DOES_NOT_EXIST:
- return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
- case QUIC_MULTIPATH_PATH_NOT_ACTIVE:
- return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
- case QUIC_IP_ADDRESS_CHANGED:
- return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
- case QUIC_CONNECTION_MIGRATION_NO_MIGRATABLE_STREAMS:
- return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
- case QUIC_CONNECTION_MIGRATION_TOO_MANY_CHANGES:
- return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
- case QUIC_CONNECTION_MIGRATION_NO_NEW_NETWORK:
- return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
- case QUIC_CONNECTION_MIGRATION_NON_MIGRATABLE_STREAM:
- return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
- case QUIC_CONNECTION_MIGRATION_DISABLED_BY_CONFIG:
- return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
- case QUIC_CONNECTION_MIGRATION_INTERNAL_ERROR:
- return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
- case QUIC_CONNECTION_MIGRATION_HANDSHAKE_UNCONFIRMED:
- return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
- case QUIC_PEER_PORT_CHANGE_HANDSHAKE_UNCONFIRMED:
- return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
- case QUIC_TOO_MANY_STREAM_DATA_INTERVALS:
- return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
- case QUIC_STREAM_SEQUENCER_INVALID_STATE:
- return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
- case QUIC_TOO_MANY_SESSIONS_ON_SERVER:
- return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
- case QUIC_STREAM_LENGTH_OVERFLOW:
- return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
- case QUIC_INVALID_MAX_DATA_FRAME_DATA:
- return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
- case QUIC_INVALID_MAX_STREAM_DATA_FRAME_DATA:
- return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
- case QUIC_MAX_STREAMS_DATA:
- return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
- case QUIC_STREAMS_BLOCKED_DATA:
- return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
- case QUIC_INVALID_STREAM_BLOCKED_DATA:
- return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
- case QUIC_INVALID_NEW_CONNECTION_ID_DATA:
- return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
- case QUIC_INVALID_STOP_SENDING_FRAME_DATA:
- return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
- case QUIC_INVALID_PATH_CHALLENGE_DATA:
- return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
- case QUIC_INVALID_PATH_RESPONSE_DATA:
- return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
- case IETF_QUIC_PROTOCOL_VIOLATION:
- return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
- case QUIC_INVALID_NEW_TOKEN:
- return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
- case QUIC_DATA_RECEIVED_ON_WRITE_UNIDIRECTIONAL_STREAM:
- return {true, static_cast<uint64_t>(STREAM_STATE_ERROR)};
- case QUIC_TRY_TO_WRITE_DATA_ON_READ_UNIDIRECTIONAL_STREAM:
- return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
- case QUIC_INVALID_RETIRE_CONNECTION_ID_DATA:
- return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
- case QUIC_STREAMS_BLOCKED_ERROR:
- return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
- case QUIC_MAX_STREAMS_ERROR:
- return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
- case QUIC_HTTP_DECODER_ERROR:
- return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
- case QUIC_STALE_CONNECTION_CANCELLED:
- return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
- case QUIC_IETF_GQUIC_ERROR_MISSING:
- return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
- case QUIC_WINDOW_UPDATE_RECEIVED_ON_READ_UNIDIRECTIONAL_STREAM:
- return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
- case QUIC_TOO_MANY_BUFFERED_CONTROL_FRAMES:
- return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
- case QUIC_TRANSPORT_INVALID_CLIENT_INDICATION:
- return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
- case QUIC_QPACK_DECOMPRESSION_FAILED:
- return {false, static_cast<uint64_t>(
- QuicHttpQpackErrorCode::DECOMPRESSION_FAILED)};
- case QUIC_QPACK_ENCODER_STREAM_ERROR:
- return {false, static_cast<uint64_t>(
- QuicHttpQpackErrorCode::ENCODER_STREAM_ERROR)};
- case QUIC_QPACK_DECODER_STREAM_ERROR:
- return {false, static_cast<uint64_t>(
- QuicHttpQpackErrorCode::DECODER_STREAM_ERROR)};
- case QUIC_QPACK_ENCODER_STREAM_INTEGER_TOO_LARGE:
- return {false, static_cast<uint64_t>(
- QuicHttpQpackErrorCode::ENCODER_STREAM_ERROR)};
- case QUIC_QPACK_ENCODER_STREAM_STRING_LITERAL_TOO_LONG:
- return {false, static_cast<uint64_t>(
- QuicHttpQpackErrorCode::ENCODER_STREAM_ERROR)};
- case QUIC_QPACK_ENCODER_STREAM_HUFFMAN_ENCODING_ERROR:
- return {false, static_cast<uint64_t>(
- QuicHttpQpackErrorCode::ENCODER_STREAM_ERROR)};
- case QUIC_QPACK_ENCODER_STREAM_INVALID_STATIC_ENTRY:
- return {false, static_cast<uint64_t>(
- QuicHttpQpackErrorCode::ENCODER_STREAM_ERROR)};
- case QUIC_QPACK_ENCODER_STREAM_ERROR_INSERTING_STATIC:
- return {false, static_cast<uint64_t>(
- QuicHttpQpackErrorCode::ENCODER_STREAM_ERROR)};
- case QUIC_QPACK_ENCODER_STREAM_INSERTION_INVALID_RELATIVE_INDEX:
- return {false, static_cast<uint64_t>(
- QuicHttpQpackErrorCode::ENCODER_STREAM_ERROR)};
- case QUIC_QPACK_ENCODER_STREAM_INSERTION_DYNAMIC_ENTRY_NOT_FOUND:
- return {false, static_cast<uint64_t>(
- QuicHttpQpackErrorCode::ENCODER_STREAM_ERROR)};
- case QUIC_QPACK_ENCODER_STREAM_ERROR_INSERTING_DYNAMIC:
- return {false, static_cast<uint64_t>(
- QuicHttpQpackErrorCode::ENCODER_STREAM_ERROR)};
- case QUIC_QPACK_ENCODER_STREAM_ERROR_INSERTING_LITERAL:
- return {false, static_cast<uint64_t>(
- QuicHttpQpackErrorCode::ENCODER_STREAM_ERROR)};
- case QUIC_QPACK_ENCODER_STREAM_DUPLICATE_INVALID_RELATIVE_INDEX:
- return {false, static_cast<uint64_t>(
- QuicHttpQpackErrorCode::ENCODER_STREAM_ERROR)};
- case QUIC_QPACK_ENCODER_STREAM_DUPLICATE_DYNAMIC_ENTRY_NOT_FOUND:
- return {false, static_cast<uint64_t>(
- QuicHttpQpackErrorCode::ENCODER_STREAM_ERROR)};
- case QUIC_QPACK_ENCODER_STREAM_SET_DYNAMIC_TABLE_CAPACITY:
- return {false, static_cast<uint64_t>(
- QuicHttpQpackErrorCode::ENCODER_STREAM_ERROR)};
- case QUIC_QPACK_DECODER_STREAM_INTEGER_TOO_LARGE:
- return {false, static_cast<uint64_t>(
- QuicHttpQpackErrorCode::DECODER_STREAM_ERROR)};
- case QUIC_QPACK_DECODER_STREAM_INVALID_ZERO_INCREMENT:
- return {false, static_cast<uint64_t>(
- QuicHttpQpackErrorCode::DECODER_STREAM_ERROR)};
- case QUIC_QPACK_DECODER_STREAM_INCREMENT_OVERFLOW:
- return {false, static_cast<uint64_t>(
- QuicHttpQpackErrorCode::DECODER_STREAM_ERROR)};
- case QUIC_QPACK_DECODER_STREAM_IMPOSSIBLE_INSERT_COUNT:
- return {false, static_cast<uint64_t>(
- QuicHttpQpackErrorCode::DECODER_STREAM_ERROR)};
- case QUIC_QPACK_DECODER_STREAM_INCORRECT_ACKNOWLEDGEMENT:
- return {false, static_cast<uint64_t>(
- QuicHttpQpackErrorCode::DECODER_STREAM_ERROR)};
- case QUIC_STREAM_DATA_BEYOND_CLOSE_OFFSET:
- return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
- case QUIC_STREAM_MULTIPLE_OFFSET:
- return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
- case QUIC_HTTP_FRAME_TOO_LARGE:
- return {false, static_cast<uint64_t>(QuicHttp3ErrorCode::EXCESSIVE_LOAD)};
- case QUIC_HTTP_FRAME_ERROR:
- return {false, static_cast<uint64_t>(QuicHttp3ErrorCode::FRAME_ERROR)};
- case QUIC_HTTP_FRAME_UNEXPECTED_ON_SPDY_STREAM:
- return {false,
- static_cast<uint64_t>(QuicHttp3ErrorCode::FRAME_UNEXPECTED)};
- case QUIC_HTTP_FRAME_UNEXPECTED_ON_CONTROL_STREAM:
- return {false,
- static_cast<uint64_t>(QuicHttp3ErrorCode::FRAME_UNEXPECTED)};
- case QUIC_HTTP_INVALID_FRAME_SEQUENCE_ON_SPDY_STREAM:
- return {false,
- static_cast<uint64_t>(QuicHttp3ErrorCode::FRAME_UNEXPECTED)};
- case QUIC_HTTP_INVALID_FRAME_SEQUENCE_ON_CONTROL_STREAM:
- return {false,
- static_cast<uint64_t>(QuicHttp3ErrorCode::FRAME_UNEXPECTED)};
- case QUIC_HTTP_DUPLICATE_UNIDIRECTIONAL_STREAM:
- return {false,
- static_cast<uint64_t>(QuicHttp3ErrorCode::STREAM_CREATION_ERROR)};
- case QUIC_HTTP_SERVER_INITIATED_BIDIRECTIONAL_STREAM:
- return {false,
- static_cast<uint64_t>(QuicHttp3ErrorCode::STREAM_CREATION_ERROR)};
- case QUIC_HTTP_STREAM_WRONG_DIRECTION:
- return {true, static_cast<uint64_t>(STREAM_STATE_ERROR)};
- case QUIC_HTTP_CLOSED_CRITICAL_STREAM:
- return {false, static_cast<uint64_t>(
- QuicHttp3ErrorCode::CLOSED_CRITICAL_STREAM)};
- case QUIC_HTTP_MISSING_SETTINGS_FRAME:
- return {false,
- static_cast<uint64_t>(QuicHttp3ErrorCode::MISSING_SETTINGS)};
- case QUIC_HTTP_DUPLICATE_SETTING_IDENTIFIER:
- return {false, static_cast<uint64_t>(QuicHttp3ErrorCode::SETTINGS_ERROR)};
- case QUIC_HTTP_INVALID_MAX_PUSH_ID:
- return {false, static_cast<uint64_t>(QuicHttp3ErrorCode::ID_ERROR)};
- case QUIC_HTTP_STREAM_LIMIT_TOO_LOW:
- return {false, static_cast<uint64_t>(
- QuicHttp3ErrorCode::GENERAL_PROTOCOL_ERROR)};
- case QUIC_HTTP_RECEIVE_SERVER_PUSH:
- return {false, static_cast<uint64_t>(
- QuicHttp3ErrorCode::GENERAL_PROTOCOL_ERROR)};
- case QUIC_HTTP_ZERO_RTT_RESUMPTION_SETTINGS_MISMATCH:
- return {false, static_cast<uint64_t>(QuicHttp3ErrorCode::SETTINGS_ERROR)};
- case QUIC_HTTP_ZERO_RTT_REJECTION_SETTINGS_MISMATCH:
- return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
- case QUIC_HTTP_GOAWAY_INVALID_STREAM_ID:
- return {false, static_cast<uint64_t>(QuicHttp3ErrorCode::ID_ERROR)};
- case QUIC_HTTP_GOAWAY_ID_LARGER_THAN_PREVIOUS:
- return {false, static_cast<uint64_t>(QuicHttp3ErrorCode::ID_ERROR)};
- case QUIC_HTTP_RECEIVE_SPDY_SETTING:
- return {false, static_cast<uint64_t>(QuicHttp3ErrorCode::SETTINGS_ERROR)};
- case QUIC_HTTP_INVALID_SETTING_VALUE:
- return {false, static_cast<uint64_t>(QuicHttp3ErrorCode::SETTINGS_ERROR)};
- case QUIC_HTTP_RECEIVE_SPDY_FRAME:
- return {false,
- static_cast<uint64_t>(QuicHttp3ErrorCode::FRAME_UNEXPECTED)};
- case QUIC_HPACK_INDEX_VARINT_ERROR:
- return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
- case QUIC_HPACK_NAME_LENGTH_VARINT_ERROR:
- return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
- case QUIC_HPACK_VALUE_LENGTH_VARINT_ERROR:
- return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
- case QUIC_HPACK_NAME_TOO_LONG:
- return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
- case QUIC_HPACK_VALUE_TOO_LONG:
- return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
- case QUIC_HPACK_NAME_HUFFMAN_ERROR:
- return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
- case QUIC_HPACK_VALUE_HUFFMAN_ERROR:
- return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
- case QUIC_HPACK_MISSING_DYNAMIC_TABLE_SIZE_UPDATE:
- return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
- case QUIC_HPACK_INVALID_INDEX:
- return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
- case QUIC_HPACK_INVALID_NAME_INDEX:
- return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
- case QUIC_HPACK_DYNAMIC_TABLE_SIZE_UPDATE_NOT_ALLOWED:
- return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
- case QUIC_HPACK_INITIAL_TABLE_SIZE_UPDATE_IS_ABOVE_LOW_WATER_MARK:
- return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
- case QUIC_HPACK_TABLE_SIZE_UPDATE_IS_ABOVE_ACKNOWLEDGED_SETTING:
- return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
- case QUIC_HPACK_TRUNCATED_BLOCK:
- return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
- case QUIC_HPACK_FRAGMENT_TOO_LONG:
- return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
- case QUIC_HPACK_COMPRESSED_HEADER_SIZE_EXCEEDS_LIMIT:
- return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
- case QUIC_ZERO_RTT_UNRETRANSMITTABLE:
- return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
- case QUIC_ZERO_RTT_REJECTION_LIMIT_REDUCED:
- return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
- case QUIC_ZERO_RTT_RESUMPTION_LIMIT_REDUCED:
- return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
- case QUIC_MISSING_WRITE_KEYS:
- return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
- case QUIC_KEY_UPDATE_ERROR:
- return {true, static_cast<uint64_t>(KEY_UPDATE_ERROR)};
- case QUIC_AEAD_LIMIT_REACHED:
- return {true, static_cast<uint64_t>(AEAD_LIMIT_REACHED)};
- case QUIC_MAX_AGE_TIMEOUT:
- return {false, static_cast<uint64_t>(QuicHttp3ErrorCode::INTERNAL_ERROR)};
- case QUIC_INVALID_PRIORITY_UPDATE:
- return {false, static_cast<uint64_t>(
- QuicHttp3ErrorCode::GENERAL_PROTOCOL_ERROR)};
- case QUIC_TLS_BAD_CERTIFICATE:
- return {true, static_cast<uint64_t>(CRYPTO_ERROR_FIRST +
- SSL_AD_BAD_CERTIFICATE)};
- case QUIC_TLS_UNSUPPORTED_CERTIFICATE:
- return {true, static_cast<uint64_t>(CRYPTO_ERROR_FIRST +
- SSL_AD_UNSUPPORTED_CERTIFICATE)};
- case QUIC_TLS_CERTIFICATE_REVOKED:
- return {true, static_cast<uint64_t>(CRYPTO_ERROR_FIRST +
- SSL_AD_CERTIFICATE_REVOKED)};
- case QUIC_TLS_CERTIFICATE_EXPIRED:
- return {true, static_cast<uint64_t>(CRYPTO_ERROR_FIRST +
- SSL_AD_CERTIFICATE_EXPIRED)};
- case QUIC_TLS_CERTIFICATE_UNKNOWN:
- return {true, static_cast<uint64_t>(CRYPTO_ERROR_FIRST +
- SSL_AD_CERTIFICATE_UNKNOWN)};
- case QUIC_TLS_INTERNAL_ERROR:
- return {true, static_cast<uint64_t>(CRYPTO_ERROR_FIRST +
- SSL_AD_INTERNAL_ERROR)};
- case QUIC_TLS_UNRECOGNIZED_NAME:
- return {true, static_cast<uint64_t>(CRYPTO_ERROR_FIRST +
- SSL_AD_UNRECOGNIZED_NAME)};
- case QUIC_TLS_CERTIFICATE_REQUIRED:
- return {true, static_cast<uint64_t>(CRYPTO_ERROR_FIRST +
- SSL_AD_CERTIFICATE_REQUIRED)};
- case QUIC_CONNECTION_ID_LIMIT_ERROR:
- return {true, static_cast<uint64_t>(CONNECTION_ID_LIMIT_ERROR)};
- case QUIC_TOO_MANY_CONNECTION_ID_WAITING_TO_RETIRE:
- return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
- case QUIC_INVALID_CHARACTER_IN_FIELD_VALUE:
- return {false, static_cast<uint64_t>(QuicHttp3ErrorCode::MESSAGE_ERROR)};
- case QUIC_TLS_UNEXPECTED_KEYING_MATERIAL_EXPORT_LABEL:
- return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
- case QUIC_TLS_KEYING_MATERIAL_EXPORTS_MISMATCH:
- return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
- case QUIC_TLS_KEYING_MATERIAL_EXPORT_NOT_AVAILABLE:
- return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
- case QUIC_UNEXPECTED_DATA_BEFORE_ENCRYPTION_ESTABLISHED:
- return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
- case QUIC_LAST_ERROR:
- return {false, static_cast<uint64_t>(QUIC_LAST_ERROR)};
- }
- // This function should not be called with unknown error code.
- return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
-}
-
-QuicErrorCode TlsAlertToQuicErrorCode(uint8_t desc) {
- switch (desc) {
- case SSL_AD_BAD_CERTIFICATE:
- return QUIC_TLS_BAD_CERTIFICATE;
- case SSL_AD_UNSUPPORTED_CERTIFICATE:
- return QUIC_TLS_UNSUPPORTED_CERTIFICATE;
- case SSL_AD_CERTIFICATE_REVOKED:
- return QUIC_TLS_CERTIFICATE_REVOKED;
- case SSL_AD_CERTIFICATE_EXPIRED:
- return QUIC_TLS_CERTIFICATE_EXPIRED;
- case SSL_AD_CERTIFICATE_UNKNOWN:
- return QUIC_TLS_CERTIFICATE_UNKNOWN;
- case SSL_AD_INTERNAL_ERROR:
- return QUIC_TLS_INTERNAL_ERROR;
- case SSL_AD_UNRECOGNIZED_NAME:
- return QUIC_TLS_UNRECOGNIZED_NAME;
- case SSL_AD_CERTIFICATE_REQUIRED:
- return QUIC_TLS_CERTIFICATE_REQUIRED;
- default:
- return QUIC_HANDSHAKE_FAILED;
- }
-}
-
-// Convert a QuicRstStreamErrorCode to an application error code to be used in
-// an IETF QUIC RESET_STREAM frame
-uint64_t RstStreamErrorCodeToIetfResetStreamErrorCode(
- QuicRstStreamErrorCode rst_stream_error_code) {
- switch (rst_stream_error_code) {
- case QUIC_STREAM_NO_ERROR:
- return static_cast<uint64_t>(QuicHttp3ErrorCode::HTTP3_NO_ERROR);
- case QUIC_ERROR_PROCESSING_STREAM:
- return static_cast<uint64_t>(QuicHttp3ErrorCode::GENERAL_PROTOCOL_ERROR);
- case QUIC_MULTIPLE_TERMINATION_OFFSETS:
- return static_cast<uint64_t>(QuicHttp3ErrorCode::GENERAL_PROTOCOL_ERROR);
- case QUIC_BAD_APPLICATION_PAYLOAD:
- return static_cast<uint64_t>(QuicHttp3ErrorCode::GENERAL_PROTOCOL_ERROR);
- case QUIC_STREAM_CONNECTION_ERROR:
- return static_cast<uint64_t>(QuicHttp3ErrorCode::INTERNAL_ERROR);
- case QUIC_STREAM_PEER_GOING_AWAY:
- return static_cast<uint64_t>(QuicHttp3ErrorCode::GENERAL_PROTOCOL_ERROR);
- case QUIC_STREAM_CANCELLED:
- return static_cast<uint64_t>(QuicHttp3ErrorCode::REQUEST_CANCELLED);
- case QUIC_RST_ACKNOWLEDGEMENT:
- return static_cast<uint64_t>(QuicHttp3ErrorCode::HTTP3_NO_ERROR);
- case QUIC_REFUSED_STREAM:
- return static_cast<uint64_t>(QuicHttp3ErrorCode::ID_ERROR);
- case QUIC_INVALID_PROMISE_URL:
- return static_cast<uint64_t>(QuicHttp3ErrorCode::STREAM_CREATION_ERROR);
- case QUIC_UNAUTHORIZED_PROMISE_URL:
- return static_cast<uint64_t>(QuicHttp3ErrorCode::STREAM_CREATION_ERROR);
- case QUIC_DUPLICATE_PROMISE_URL:
- return static_cast<uint64_t>(QuicHttp3ErrorCode::STREAM_CREATION_ERROR);
- case QUIC_PROMISE_VARY_MISMATCH:
- return static_cast<uint64_t>(QuicHttp3ErrorCode::REQUEST_CANCELLED);
- case QUIC_INVALID_PROMISE_METHOD:
- return static_cast<uint64_t>(QuicHttp3ErrorCode::STREAM_CREATION_ERROR);
- case QUIC_PUSH_STREAM_TIMED_OUT:
- return static_cast<uint64_t>(QuicHttp3ErrorCode::REQUEST_CANCELLED);
- case QUIC_HEADERS_TOO_LARGE:
- return static_cast<uint64_t>(QuicHttp3ErrorCode::EXCESSIVE_LOAD);
- case QUIC_STREAM_TTL_EXPIRED:
- return static_cast<uint64_t>(QuicHttp3ErrorCode::REQUEST_CANCELLED);
- case QUIC_DATA_AFTER_CLOSE_OFFSET:
- return static_cast<uint64_t>(QuicHttp3ErrorCode::GENERAL_PROTOCOL_ERROR);
- case QUIC_STREAM_GENERAL_PROTOCOL_ERROR:
- return static_cast<uint64_t>(QuicHttp3ErrorCode::GENERAL_PROTOCOL_ERROR);
- case QUIC_STREAM_INTERNAL_ERROR:
- return static_cast<uint64_t>(QuicHttp3ErrorCode::INTERNAL_ERROR);
- case QUIC_STREAM_STREAM_CREATION_ERROR:
- return static_cast<uint64_t>(QuicHttp3ErrorCode::STREAM_CREATION_ERROR);
- case QUIC_STREAM_CLOSED_CRITICAL_STREAM:
- return static_cast<uint64_t>(QuicHttp3ErrorCode::CLOSED_CRITICAL_STREAM);
- case QUIC_STREAM_FRAME_UNEXPECTED:
- return static_cast<uint64_t>(QuicHttp3ErrorCode::FRAME_UNEXPECTED);
- case QUIC_STREAM_FRAME_ERROR:
- return static_cast<uint64_t>(QuicHttp3ErrorCode::FRAME_ERROR);
- case QUIC_STREAM_EXCESSIVE_LOAD:
- return static_cast<uint64_t>(QuicHttp3ErrorCode::EXCESSIVE_LOAD);
- case QUIC_STREAM_ID_ERROR:
- return static_cast<uint64_t>(QuicHttp3ErrorCode::ID_ERROR);
- case QUIC_STREAM_SETTINGS_ERROR:
- return static_cast<uint64_t>(QuicHttp3ErrorCode::SETTINGS_ERROR);
- case QUIC_STREAM_MISSING_SETTINGS:
- return static_cast<uint64_t>(QuicHttp3ErrorCode::MISSING_SETTINGS);
- case QUIC_STREAM_REQUEST_REJECTED:
- return static_cast<uint64_t>(QuicHttp3ErrorCode::REQUEST_REJECTED);
- case QUIC_STREAM_REQUEST_INCOMPLETE:
- return static_cast<uint64_t>(QuicHttp3ErrorCode::REQUEST_INCOMPLETE);
- case QUIC_STREAM_CONNECT_ERROR:
- return static_cast<uint64_t>(QuicHttp3ErrorCode::CONNECT_ERROR);
- case QUIC_STREAM_VERSION_FALLBACK:
- return static_cast<uint64_t>(QuicHttp3ErrorCode::VERSION_FALLBACK);
- case QUIC_STREAM_DECOMPRESSION_FAILED:
- return static_cast<uint64_t>(
- QuicHttpQpackErrorCode::DECOMPRESSION_FAILED);
- case QUIC_STREAM_ENCODER_STREAM_ERROR:
- return static_cast<uint64_t>(
- QuicHttpQpackErrorCode::ENCODER_STREAM_ERROR);
- case QUIC_STREAM_DECODER_STREAM_ERROR:
- return static_cast<uint64_t>(
- QuicHttpQpackErrorCode::DECODER_STREAM_ERROR);
- case QUIC_STREAM_UNKNOWN_APPLICATION_ERROR_CODE:
- return static_cast<uint64_t>(QuicHttp3ErrorCode::INTERNAL_ERROR);
- case QUIC_STREAM_WEBTRANSPORT_SESSION_GONE:
- return static_cast<uint64_t>(QuicHttp3ErrorCode::CONNECT_ERROR);
- case QUIC_STREAM_WEBTRANSPORT_BUFFERED_STREAMS_LIMIT_EXCEEDED:
- return static_cast<uint64_t>(QuicHttp3ErrorCode::CONNECT_ERROR);
- case QUIC_STREAM_LAST_ERROR:
- return static_cast<uint64_t>(QuicHttp3ErrorCode::INTERNAL_ERROR);
- }
- return static_cast<uint64_t>(QuicHttp3ErrorCode::INTERNAL_ERROR);
-}
-
-// Convert the application error code of an IETF QUIC RESET_STREAM frame
-// to QuicRstStreamErrorCode.
-QuicRstStreamErrorCode IetfResetStreamErrorCodeToRstStreamErrorCode(
- uint64_t ietf_error_code) {
- switch (ietf_error_code) {
- case static_cast<uint64_t>(QuicHttp3ErrorCode::HTTP3_NO_ERROR):
- return QUIC_STREAM_NO_ERROR;
- case static_cast<uint64_t>(QuicHttp3ErrorCode::GENERAL_PROTOCOL_ERROR):
- return QUIC_STREAM_GENERAL_PROTOCOL_ERROR;
- case static_cast<uint64_t>(QuicHttp3ErrorCode::INTERNAL_ERROR):
- return QUIC_STREAM_INTERNAL_ERROR;
- case static_cast<uint64_t>(QuicHttp3ErrorCode::STREAM_CREATION_ERROR):
- return QUIC_STREAM_STREAM_CREATION_ERROR;
- case static_cast<uint64_t>(QuicHttp3ErrorCode::CLOSED_CRITICAL_STREAM):
- return QUIC_STREAM_CLOSED_CRITICAL_STREAM;
- case static_cast<uint64_t>(QuicHttp3ErrorCode::FRAME_UNEXPECTED):
- return QUIC_STREAM_FRAME_UNEXPECTED;
- case static_cast<uint64_t>(QuicHttp3ErrorCode::FRAME_ERROR):
- return QUIC_STREAM_FRAME_ERROR;
- case static_cast<uint64_t>(QuicHttp3ErrorCode::EXCESSIVE_LOAD):
- return QUIC_STREAM_EXCESSIVE_LOAD;
- case static_cast<uint64_t>(QuicHttp3ErrorCode::ID_ERROR):
- return QUIC_STREAM_ID_ERROR;
- case static_cast<uint64_t>(QuicHttp3ErrorCode::SETTINGS_ERROR):
- return QUIC_STREAM_SETTINGS_ERROR;
- case static_cast<uint64_t>(QuicHttp3ErrorCode::MISSING_SETTINGS):
- return QUIC_STREAM_MISSING_SETTINGS;
- case static_cast<uint64_t>(QuicHttp3ErrorCode::REQUEST_REJECTED):
- return QUIC_STREAM_REQUEST_REJECTED;
- case static_cast<uint64_t>(QuicHttp3ErrorCode::REQUEST_CANCELLED):
- return QUIC_STREAM_CANCELLED;
- case static_cast<uint64_t>(QuicHttp3ErrorCode::REQUEST_INCOMPLETE):
- return QUIC_STREAM_REQUEST_INCOMPLETE;
- case static_cast<uint64_t>(QuicHttp3ErrorCode::CONNECT_ERROR):
- return QUIC_STREAM_CONNECT_ERROR;
- case static_cast<uint64_t>(QuicHttp3ErrorCode::VERSION_FALLBACK):
- return QUIC_STREAM_VERSION_FALLBACK;
- case static_cast<uint64_t>(QuicHttpQpackErrorCode::DECOMPRESSION_FAILED):
- return QUIC_STREAM_DECOMPRESSION_FAILED;
- case static_cast<uint64_t>(QuicHttpQpackErrorCode::ENCODER_STREAM_ERROR):
- return QUIC_STREAM_ENCODER_STREAM_ERROR;
- case static_cast<uint64_t>(QuicHttpQpackErrorCode::DECODER_STREAM_ERROR):
- return QUIC_STREAM_DECODER_STREAM_ERROR;
- }
- return QUIC_STREAM_UNKNOWN_APPLICATION_ERROR_CODE;
-}
-
-// static
-QuicResetStreamError QuicResetStreamError::FromInternal(
- QuicRstStreamErrorCode code) {
- return QuicResetStreamError(
- code, RstStreamErrorCodeToIetfResetStreamErrorCode(code));
-}
-
-// static
-QuicResetStreamError QuicResetStreamError::FromIetf(uint64_t code) {
- return QuicResetStreamError(
- IetfResetStreamErrorCodeToRstStreamErrorCode(code), code);
-}
-
-#undef RETURN_STRING_LITERAL // undef for jumbo builds
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_error_codes.h b/chromium/net/third_party/quiche/src/quic/core/quic_error_codes.h
deleted file mode 100644
index 0ecef013ff9..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_error_codes.h
+++ /dev/null
@@ -1,765 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_ERROR_CODES_H_
-#define QUICHE_QUIC_CORE_QUIC_ERROR_CODES_H_
-
-#include <cstdint>
-#include <limits>
-#include <string>
-
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-enum QuicRstStreamErrorCode {
- // Complete response has been sent, sending a RST to ask the other endpoint
- // to stop sending request data without discarding the response.
- QUIC_STREAM_NO_ERROR = 0,
-
- // There was some error which halted stream processing.
- QUIC_ERROR_PROCESSING_STREAM = 1,
- // We got two fin or reset offsets which did not match.
- QUIC_MULTIPLE_TERMINATION_OFFSETS = 2,
- // We got bad payload and can not respond to it at the protocol level.
- QUIC_BAD_APPLICATION_PAYLOAD = 3,
- // Stream closed due to connection error. No reset frame is sent when this
- // happens.
- QUIC_STREAM_CONNECTION_ERROR = 4,
- // GoAway frame sent. No more stream can be created.
- QUIC_STREAM_PEER_GOING_AWAY = 5,
- // The stream has been cancelled.
- QUIC_STREAM_CANCELLED = 6,
- // Closing stream locally, sending a RST to allow for proper flow control
- // accounting. Sent in response to a RST from the peer.
- QUIC_RST_ACKNOWLEDGEMENT = 7,
- // Receiver refused to create the stream (because its limit on open streams
- // has been reached). The sender should retry the request later (using
- // another stream).
- QUIC_REFUSED_STREAM = 8,
- // Invalid URL in PUSH_PROMISE request header.
- QUIC_INVALID_PROMISE_URL = 9,
- // Server is not authoritative for this URL.
- QUIC_UNAUTHORIZED_PROMISE_URL = 10,
- // Can't have more than one active PUSH_PROMISE per URL.
- QUIC_DUPLICATE_PROMISE_URL = 11,
- // Vary check failed.
- QUIC_PROMISE_VARY_MISMATCH = 12,
- // Only GET and HEAD methods allowed.
- QUIC_INVALID_PROMISE_METHOD = 13,
- // The push stream is unclaimed and timed out.
- QUIC_PUSH_STREAM_TIMED_OUT = 14,
- // Received headers were too large.
- QUIC_HEADERS_TOO_LARGE = 15,
- // The data is not likely arrive in time.
- QUIC_STREAM_TTL_EXPIRED = 16,
- // The stream received data that goes beyond its close offset.
- QUIC_DATA_AFTER_CLOSE_OFFSET = 17,
- // Peer violated protocol requirements in a way which does not match a more
- // specific error code, or endpoint declines to use the more specific error
- // code.
- QUIC_STREAM_GENERAL_PROTOCOL_ERROR = 18,
- // An internal error has occurred.
- QUIC_STREAM_INTERNAL_ERROR = 19,
- // Peer created a stream that will not be accepted.
- QUIC_STREAM_STREAM_CREATION_ERROR = 20,
- // A stream required by the connection was closed or reset.
- QUIC_STREAM_CLOSED_CRITICAL_STREAM = 21,
- // A frame was received which was not permitted in the current state or on the
- // current stream.
- QUIC_STREAM_FRAME_UNEXPECTED = 22,
- // A frame that fails to satisfy layout requirements or with an invalid size
- // was received.
- QUIC_STREAM_FRAME_ERROR = 23,
- // Peer exhibits a behavior that might be generating excessive load.
- QUIC_STREAM_EXCESSIVE_LOAD = 24,
- // A Stream ID or Push ID was used incorrectly, such as exceeding a limit,
- // reducing a limit, or being reused.
- QUIC_STREAM_ID_ERROR = 25,
- // Error in the payload of a SETTINGS frame.
- QUIC_STREAM_SETTINGS_ERROR = 26,
- // No SETTINGS frame was received at the beginning of the control stream.
- QUIC_STREAM_MISSING_SETTINGS = 27,
- // A server rejected a request without performing any application processing.
- QUIC_STREAM_REQUEST_REJECTED = 28,
- // The client's stream terminated without containing a fully-formed request.
- QUIC_STREAM_REQUEST_INCOMPLETE = 29,
- // The connection established in response to a CONNECT request was reset or
- // abnormally closed.
- QUIC_STREAM_CONNECT_ERROR = 30,
- // The requested operation cannot be served over HTTP/3.
- // The peer should retry over HTTP/1.1.
- QUIC_STREAM_VERSION_FALLBACK = 31,
- // The QPACK decoder failed to interpret a header block and is not able to
- // continue decoding that header block.
- QUIC_STREAM_DECOMPRESSION_FAILED = 32,
- // The QPACK decoder failed to interpret an encoder instruction received on
- // the encoder stream.
- QUIC_STREAM_ENCODER_STREAM_ERROR = 33,
- // The QPACK encoder failed to interpret a decoder instruction received on the
- // decoder stream.
- QUIC_STREAM_DECODER_STREAM_ERROR = 34,
- // IETF RESET_FRAME application error code not matching any HTTP/3 or QPACK
- // error codes.
- QUIC_STREAM_UNKNOWN_APPLICATION_ERROR_CODE = 35,
- // WebTransport session is going away, causing all underlying streams to be
- // reset.
- QUIC_STREAM_WEBTRANSPORT_SESSION_GONE = 36,
- // There is no corresponding WebTransport session to associate this stream
- // with, and the limit for buffered streams has been exceeded.
- QUIC_STREAM_WEBTRANSPORT_BUFFERED_STREAMS_LIMIT_EXCEEDED = 37,
- // No error. Used as bound while iterating.
- QUIC_STREAM_LAST_ERROR = 38,
-};
-// QuicRstStreamErrorCode is encoded as a single octet on-the-wire.
-static_assert(static_cast<int>(QUIC_STREAM_LAST_ERROR) <=
- std::numeric_limits<uint8_t>::max(),
- "QuicRstStreamErrorCode exceeds single octet");
-
-// These values must remain stable as they are uploaded to UMA histograms.
-// To add a new error code, use the current value of QUIC_LAST_ERROR and
-// increment QUIC_LAST_ERROR.
-enum QuicErrorCode {
- QUIC_NO_ERROR = 0,
-
- // Connection has reached an invalid state.
- QUIC_INTERNAL_ERROR = 1,
- // There were data frames after the a fin or reset.
- QUIC_STREAM_DATA_AFTER_TERMINATION = 2,
- // Control frame is malformed.
- QUIC_INVALID_PACKET_HEADER = 3,
- // Frame data is malformed.
- QUIC_INVALID_FRAME_DATA = 4,
- // The packet contained no payload.
- QUIC_MISSING_PAYLOAD = 48,
- // FEC data is malformed.
- QUIC_INVALID_FEC_DATA = 5,
- // STREAM frame data is malformed.
- QUIC_INVALID_STREAM_DATA = 46,
- // STREAM frame data overlaps with buffered data.
- QUIC_OVERLAPPING_STREAM_DATA = 87,
- // Received STREAM frame data is not encrypted.
- QUIC_UNENCRYPTED_STREAM_DATA = 61,
- // Attempt to send unencrypted STREAM frame.
- QUIC_ATTEMPT_TO_SEND_UNENCRYPTED_STREAM_DATA = 88,
- // Received a frame which is likely the result of memory corruption.
- QUIC_MAYBE_CORRUPTED_MEMORY = 89,
- // FEC frame data is not encrypted.
- QUIC_UNENCRYPTED_FEC_DATA = 77,
- // RST_STREAM frame data is malformed.
- QUIC_INVALID_RST_STREAM_DATA = 6,
- // CONNECTION_CLOSE frame data is malformed.
- QUIC_INVALID_CONNECTION_CLOSE_DATA = 7,
- // GOAWAY frame data is malformed.
- QUIC_INVALID_GOAWAY_DATA = 8,
- // WINDOW_UPDATE frame data is malformed.
- QUIC_INVALID_WINDOW_UPDATE_DATA = 57,
- // BLOCKED frame data is malformed.
- QUIC_INVALID_BLOCKED_DATA = 58,
- // STOP_WAITING frame data is malformed.
- QUIC_INVALID_STOP_WAITING_DATA = 60,
- // PATH_CLOSE frame data is malformed.
- QUIC_INVALID_PATH_CLOSE_DATA = 78,
- // ACK frame data is malformed.
- QUIC_INVALID_ACK_DATA = 9,
- // Message frame data is malformed.
- QUIC_INVALID_MESSAGE_DATA = 112,
-
- // Version negotiation packet is malformed.
- QUIC_INVALID_VERSION_NEGOTIATION_PACKET = 10,
- // Public RST packet is malformed.
- QUIC_INVALID_PUBLIC_RST_PACKET = 11,
- // There was an error decrypting.
- QUIC_DECRYPTION_FAILURE = 12,
- // There was an error encrypting.
- QUIC_ENCRYPTION_FAILURE = 13,
- // The packet exceeded kMaxOutgoingPacketSize.
- QUIC_PACKET_TOO_LARGE = 14,
- // The peer is going away. May be a client or server.
- QUIC_PEER_GOING_AWAY = 16,
- // A stream ID was invalid.
- QUIC_INVALID_STREAM_ID = 17,
- // A priority was invalid.
- QUIC_INVALID_PRIORITY = 49,
- // Too many streams already open.
- QUIC_TOO_MANY_OPEN_STREAMS = 18,
- // The peer created too many available streams.
- QUIC_TOO_MANY_AVAILABLE_STREAMS = 76,
- // Received public reset for this connection.
- QUIC_PUBLIC_RESET = 19,
- // Invalid protocol version.
- QUIC_INVALID_VERSION = 20,
-
- // The Header ID for a stream was too far from the previous.
- QUIC_INVALID_HEADER_ID = 22,
- // Negotiable parameter received during handshake had invalid value.
- QUIC_INVALID_NEGOTIATED_VALUE = 23,
- // There was an error decompressing data.
- QUIC_DECOMPRESSION_FAILURE = 24,
- // The connection timed out due to no network activity.
- QUIC_NETWORK_IDLE_TIMEOUT = 25,
- // The connection timed out waiting for the handshake to complete.
- QUIC_HANDSHAKE_TIMEOUT = 67,
- // There was an error encountered migrating addresses.
- QUIC_ERROR_MIGRATING_ADDRESS = 26,
- // There was an error encountered migrating port only.
- QUIC_ERROR_MIGRATING_PORT = 86,
- // There was an error while writing to the socket.
- QUIC_PACKET_WRITE_ERROR = 27,
- // There was an error while reading from the socket.
- QUIC_PACKET_READ_ERROR = 51,
- // We received a STREAM_FRAME with no data and no fin flag set.
- QUIC_EMPTY_STREAM_FRAME_NO_FIN = 50,
- // We received invalid data on the headers stream.
- QUIC_INVALID_HEADERS_STREAM_DATA = 56,
- // Invalid data on the headers stream received because of decompression
- // failure.
- QUIC_HEADERS_STREAM_DATA_DECOMPRESS_FAILURE = 97,
- // The peer received too much data, violating flow control.
- QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA = 59,
- // The peer sent too much data, violating flow control.
- QUIC_FLOW_CONTROL_SENT_TOO_MUCH_DATA = 63,
- // The peer received an invalid flow control window.
- QUIC_FLOW_CONTROL_INVALID_WINDOW = 64,
- // The connection has been IP pooled into an existing connection.
- QUIC_CONNECTION_IP_POOLED = 62,
- // The connection has too many outstanding sent packets.
- QUIC_TOO_MANY_OUTSTANDING_SENT_PACKETS = 68,
- // The connection has too many outstanding received packets.
- QUIC_TOO_MANY_OUTSTANDING_RECEIVED_PACKETS = 69,
- // The quic connection has been cancelled.
- QUIC_CONNECTION_CANCELLED = 70,
- // Disabled QUIC because of high packet loss rate.
- QUIC_BAD_PACKET_LOSS_RATE = 71,
- // Disabled QUIC because of too many PUBLIC_RESETs post handshake.
- QUIC_PUBLIC_RESETS_POST_HANDSHAKE = 73,
- // Closed because we failed to serialize a packet.
- QUIC_FAILED_TO_SERIALIZE_PACKET = 75,
- // QUIC timed out after too many RTOs.
- QUIC_TOO_MANY_RTOS = 85,
-
- // Crypto errors.
-
- // Handshake failed.
- QUIC_HANDSHAKE_FAILED = 28,
- // Handshake message contained out of order tags.
- QUIC_CRYPTO_TAGS_OUT_OF_ORDER = 29,
- // Handshake message contained too many entries.
- QUIC_CRYPTO_TOO_MANY_ENTRIES = 30,
- // Handshake message contained an invalid value length.
- QUIC_CRYPTO_INVALID_VALUE_LENGTH = 31,
- // A crypto message was received after the handshake was complete.
- QUIC_CRYPTO_MESSAGE_AFTER_HANDSHAKE_COMPLETE = 32,
- // A crypto message was received with an illegal message tag.
- QUIC_INVALID_CRYPTO_MESSAGE_TYPE = 33,
- // A crypto message was received with an illegal parameter.
- QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER = 34,
- // An invalid channel id signature was supplied.
- QUIC_INVALID_CHANNEL_ID_SIGNATURE = 52,
- // A crypto message was received with a mandatory parameter missing.
- QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND = 35,
- // A crypto message was received with a parameter that has no overlap
- // with the local parameter.
- QUIC_CRYPTO_MESSAGE_PARAMETER_NO_OVERLAP = 36,
- // A crypto message was received that contained a parameter with too few
- // values.
- QUIC_CRYPTO_MESSAGE_INDEX_NOT_FOUND = 37,
- // A demand for an unsupport proof type was received.
- QUIC_UNSUPPORTED_PROOF_DEMAND = 94,
- // An internal error occurred in crypto processing.
- QUIC_CRYPTO_INTERNAL_ERROR = 38,
- // A crypto handshake message specified an unsupported version.
- QUIC_CRYPTO_VERSION_NOT_SUPPORTED = 39,
- // (Deprecated) A crypto handshake message resulted in a stateless reject.
- // QUIC_CRYPTO_HANDSHAKE_STATELESS_REJECT = 72,
- // There was no intersection between the crypto primitives supported by the
- // peer and ourselves.
- QUIC_CRYPTO_NO_SUPPORT = 40,
- // The server rejected our client hello messages too many times.
- QUIC_CRYPTO_TOO_MANY_REJECTS = 41,
- // The client rejected the server's certificate chain or signature.
- QUIC_PROOF_INVALID = 42,
- // A crypto message was received with a duplicate tag.
- QUIC_CRYPTO_DUPLICATE_TAG = 43,
- // A crypto message was received with the wrong encryption level (i.e. it
- // should have been encrypted but was not.)
- QUIC_CRYPTO_ENCRYPTION_LEVEL_INCORRECT = 44,
- // The server config for a server has expired.
- QUIC_CRYPTO_SERVER_CONFIG_EXPIRED = 45,
- // We failed to setup the symmetric keys for a connection.
- QUIC_CRYPTO_SYMMETRIC_KEY_SETUP_FAILED = 53,
- // A handshake message arrived, but we are still validating the
- // previous handshake message.
- QUIC_CRYPTO_MESSAGE_WHILE_VALIDATING_CLIENT_HELLO = 54,
- // A server config update arrived before the handshake is complete.
- QUIC_CRYPTO_UPDATE_BEFORE_HANDSHAKE_COMPLETE = 65,
- // CHLO cannot fit in one packet.
- QUIC_CRYPTO_CHLO_TOO_LARGE = 90,
- // This connection involved a version negotiation which appears to have been
- // tampered with.
- QUIC_VERSION_NEGOTIATION_MISMATCH = 55,
-
- // Multipath errors.
- // Multipath is not enabled, but a packet with multipath flag on is received.
- QUIC_BAD_MULTIPATH_FLAG = 79,
- // A path is supposed to exist but does not.
- QUIC_MULTIPATH_PATH_DOES_NOT_EXIST = 91,
- // A path is supposed to be active but is not.
- QUIC_MULTIPATH_PATH_NOT_ACTIVE = 92,
-
- // IP address changed causing connection close.
- QUIC_IP_ADDRESS_CHANGED = 80,
-
- // Connection migration errors.
- // Network changed, but connection had no migratable streams.
- QUIC_CONNECTION_MIGRATION_NO_MIGRATABLE_STREAMS = 81,
- // Connection changed networks too many times.
- QUIC_CONNECTION_MIGRATION_TOO_MANY_CHANGES = 82,
- // Connection migration was attempted, but there was no new network to
- // migrate to.
- QUIC_CONNECTION_MIGRATION_NO_NEW_NETWORK = 83,
- // Network changed, but connection had one or more non-migratable streams.
- QUIC_CONNECTION_MIGRATION_NON_MIGRATABLE_STREAM = 84,
- // Network changed, but connection migration was disabled by config.
- QUIC_CONNECTION_MIGRATION_DISABLED_BY_CONFIG = 99,
- // Network changed, but error was encountered on the alternative network.
- QUIC_CONNECTION_MIGRATION_INTERNAL_ERROR = 100,
- // Network changed, but handshake is not confirmed yet.
- QUIC_CONNECTION_MIGRATION_HANDSHAKE_UNCONFIRMED = 111,
- QUIC_PEER_PORT_CHANGE_HANDSHAKE_UNCONFIRMED = 194,
-
- // Stream frames arrived too discontiguously so that stream sequencer buffer
- // maintains too many intervals.
- QUIC_TOO_MANY_STREAM_DATA_INTERVALS = 93,
-
- // Sequencer buffer get into weird state where continuing read/write will lead
- // to crash.
- QUIC_STREAM_SEQUENCER_INVALID_STATE = 95,
-
- // Connection closed because of server hits max number of sessions allowed.
- QUIC_TOO_MANY_SESSIONS_ON_SERVER = 96,
-
- // Receive a RST_STREAM with offset larger than kMaxStreamLength.
- QUIC_STREAM_LENGTH_OVERFLOW = 98,
- // Received a MAX DATA frame with errors.
- QUIC_INVALID_MAX_DATA_FRAME_DATA = 102,
- // Received a MAX STREAM DATA frame with errors.
- QUIC_INVALID_MAX_STREAM_DATA_FRAME_DATA = 103,
- // Received a MAX_STREAMS frame with bad data
- QUIC_MAX_STREAMS_DATA = 104,
- // Received a STREAMS_BLOCKED frame with bad data
- QUIC_STREAMS_BLOCKED_DATA = 105,
- // Error deframing a STREAM BLOCKED frame.
- QUIC_INVALID_STREAM_BLOCKED_DATA = 106,
- // NEW CONNECTION ID frame data is malformed.
- QUIC_INVALID_NEW_CONNECTION_ID_DATA = 107,
- // More connection IDs than allowed are issued.
- QUIC_CONNECTION_ID_LIMIT_ERROR = 203,
- // The peer retires connection IDs too quickly.
- QUIC_TOO_MANY_CONNECTION_ID_WAITING_TO_RETIRE = 204,
- // Received a MAX STREAM DATA frame with errors.
- QUIC_INVALID_STOP_SENDING_FRAME_DATA = 108,
- // Error deframing PATH CHALLENGE or PATH RESPONSE frames.
- QUIC_INVALID_PATH_CHALLENGE_DATA = 109,
- QUIC_INVALID_PATH_RESPONSE_DATA = 110,
- // This is used to indicate an IETF QUIC PROTOCOL VIOLATION
- // transport error within Google (pre-v99) QUIC.
- IETF_QUIC_PROTOCOL_VIOLATION = 113,
- QUIC_INVALID_NEW_TOKEN = 114,
-
- // Received stream data on a WRITE_UNIDIRECTIONAL stream.
- QUIC_DATA_RECEIVED_ON_WRITE_UNIDIRECTIONAL_STREAM = 115,
- // Try to send stream data on a READ_UNIDIRECTIONAL stream.
- QUIC_TRY_TO_WRITE_DATA_ON_READ_UNIDIRECTIONAL_STREAM = 116,
-
- // RETIRE CONNECTION ID frame data is malformed.
- QUIC_INVALID_RETIRE_CONNECTION_ID_DATA = 117,
-
- // Error in a received STREAMS BLOCKED frame.
- QUIC_STREAMS_BLOCKED_ERROR = 118,
- // Error in a received MAX STREAMS frame
- QUIC_MAX_STREAMS_ERROR = 119,
- // Error in Http decoder
- QUIC_HTTP_DECODER_ERROR = 120,
- // Connection from stale host needs to be cancelled.
- QUIC_STALE_CONNECTION_CANCELLED = 121,
-
- // A pseudo error, used as an extended error reason code in the error_details
- // of IETF-QUIC CONNECTION_CLOSE frames. It is used in
- // OnConnectionClosed upcalls to indicate that extended error information was
- // not available in a received CONNECTION_CLOSE frame.
- QUIC_IETF_GQUIC_ERROR_MISSING = 122,
-
- // Received WindowUpdate on a READ_UNIDIRECTIONAL stream.
- QUIC_WINDOW_UPDATE_RECEIVED_ON_READ_UNIDIRECTIONAL_STREAM = 123,
-
- // There are too many buffered control frames in control frame manager.
- QUIC_TOO_MANY_BUFFERED_CONTROL_FRAMES = 124,
-
- // QuicTransport received invalid client indication.
- QUIC_TRANSPORT_INVALID_CLIENT_INDICATION = 125,
-
- // Internal error codes for QPACK errors.
- QUIC_QPACK_DECOMPRESSION_FAILED = 126,
-
- // Obsolete generic QPACK encoder and decoder stream error codes.
- QUIC_QPACK_ENCODER_STREAM_ERROR = 127,
- QUIC_QPACK_DECODER_STREAM_ERROR = 128,
-
- // QPACK encoder stream errors.
-
- // Variable integer exceeding 2^64-1 received.
- QUIC_QPACK_ENCODER_STREAM_INTEGER_TOO_LARGE = 174,
- // String literal exceeding kStringLiteralLengthLimit in length received.
- QUIC_QPACK_ENCODER_STREAM_STRING_LITERAL_TOO_LONG = 175,
- // String literal with invalid Huffman encoding received.
- QUIC_QPACK_ENCODER_STREAM_HUFFMAN_ENCODING_ERROR = 176,
- // Invalid static table index in Insert With Name Reference instruction.
- QUIC_QPACK_ENCODER_STREAM_INVALID_STATIC_ENTRY = 177,
- // Error inserting entry with static name reference in Insert With Name
- // Reference instruction due to entry size exceeding dynamic table capacity.
- QUIC_QPACK_ENCODER_STREAM_ERROR_INSERTING_STATIC = 178,
- // Invalid relative index in Insert With Name Reference instruction.
- QUIC_QPACK_ENCODER_STREAM_INSERTION_INVALID_RELATIVE_INDEX = 179,
- // Dynamic entry not found in Insert With Name Reference instruction.
- QUIC_QPACK_ENCODER_STREAM_INSERTION_DYNAMIC_ENTRY_NOT_FOUND = 180,
- // Error inserting entry with dynamic name reference in Insert With Name
- // Reference instruction due to entry size exceeding dynamic table capacity.
- QUIC_QPACK_ENCODER_STREAM_ERROR_INSERTING_DYNAMIC = 181,
- // Error inserting entry in Insert With Literal Name instruction due to entry
- // size exceeding dynamic table capacity.
- QUIC_QPACK_ENCODER_STREAM_ERROR_INSERTING_LITERAL = 182,
- // Invalid relative index in Duplicate instruction.
- QUIC_QPACK_ENCODER_STREAM_DUPLICATE_INVALID_RELATIVE_INDEX = 183,
- // Dynamic entry not found in Duplicate instruction.
- QUIC_QPACK_ENCODER_STREAM_DUPLICATE_DYNAMIC_ENTRY_NOT_FOUND = 184,
- // Error in Set Dynamic Table Capacity instruction due to new capacity
- // exceeding maximum dynamic table capacity.
- QUIC_QPACK_ENCODER_STREAM_SET_DYNAMIC_TABLE_CAPACITY = 185,
-
- // QPACK decoder stream errors.
-
- // Variable integer exceeding 2^64-1 received.
- QUIC_QPACK_DECODER_STREAM_INTEGER_TOO_LARGE = 186,
- // Insert Count Increment instruction received with invalid 0 increment.
- QUIC_QPACK_DECODER_STREAM_INVALID_ZERO_INCREMENT = 187,
- // Insert Count Increment instruction causes uint64_t overflow.
- QUIC_QPACK_DECODER_STREAM_INCREMENT_OVERFLOW = 188,
- // Insert Count Increment instruction increases Known Received Count beyond
- // inserted entry cound.
- QUIC_QPACK_DECODER_STREAM_IMPOSSIBLE_INSERT_COUNT = 189,
- // Header Acknowledgement received for stream that has no outstanding header
- // blocks.
- QUIC_QPACK_DECODER_STREAM_INCORRECT_ACKNOWLEDGEMENT = 190,
-
- // Received stream data beyond close offset.
- QUIC_STREAM_DATA_BEYOND_CLOSE_OFFSET = 129,
-
- // Received multiple close offset.
- QUIC_STREAM_MULTIPLE_OFFSET = 130,
-
- // HTTP/3 errors.
-
- // Frame payload larger than what HttpDecoder is willing to buffer.
- QUIC_HTTP_FRAME_TOO_LARGE = 131,
- // Malformed HTTP/3 frame, or PUSH_PROMISE or CANCEL_PUSH received (which is
- // an error because MAX_PUSH_ID is never sent).
- QUIC_HTTP_FRAME_ERROR = 132,
- // A frame that is never allowed on a request stream is received.
- QUIC_HTTP_FRAME_UNEXPECTED_ON_SPDY_STREAM = 133,
- // A frame that is never allowed on the control stream is received.
- QUIC_HTTP_FRAME_UNEXPECTED_ON_CONTROL_STREAM = 134,
- // An invalid sequence of frames normally allowed on a request stream is
- // received.
- QUIC_HTTP_INVALID_FRAME_SEQUENCE_ON_SPDY_STREAM = 151,
- // A second SETTINGS frame is received on the control stream.
- QUIC_HTTP_INVALID_FRAME_SEQUENCE_ON_CONTROL_STREAM = 152,
- // A second instance of a unidirectional stream of a certain type is created.
- QUIC_HTTP_DUPLICATE_UNIDIRECTIONAL_STREAM = 153,
- // Client receives a server-initiated bidirectional stream.
- QUIC_HTTP_SERVER_INITIATED_BIDIRECTIONAL_STREAM = 154,
- // Server opens stream with stream ID corresponding to client-initiated
- // stream or vice versa.
- QUIC_HTTP_STREAM_WRONG_DIRECTION = 155,
- // Peer closes one of the six critical unidirectional streams (control, QPACK
- // encoder or decoder, in either direction).
- QUIC_HTTP_CLOSED_CRITICAL_STREAM = 156,
- // The first frame received on the control stream is not a SETTINGS frame.
- QUIC_HTTP_MISSING_SETTINGS_FRAME = 157,
- // The received SETTINGS frame contains duplicate setting identifiers.
- QUIC_HTTP_DUPLICATE_SETTING_IDENTIFIER = 158,
- // MAX_PUSH_ID frame received with push ID value smaller than a previously
- // received value.
- QUIC_HTTP_INVALID_MAX_PUSH_ID = 159,
- // Received unidirectional stream limit is lower than required by HTTP/3.
- QUIC_HTTP_STREAM_LIMIT_TOO_LOW = 160,
- // Received mismatched SETTINGS frame from HTTP/3 connection where early data
- // is accepted. Server violated the HTTP/3 spec.
- QUIC_HTTP_ZERO_RTT_RESUMPTION_SETTINGS_MISMATCH = 164,
- // Received mismatched SETTINGS frame from HTTP/3 connection where early data
- // is rejected. Our implementation currently doesn't support it.
- QUIC_HTTP_ZERO_RTT_REJECTION_SETTINGS_MISMATCH = 165,
- // Client received GOAWAY frame with stream ID that is not for a
- // client-initiated bidirectional stream.
- QUIC_HTTP_GOAWAY_INVALID_STREAM_ID = 166,
- // Received GOAWAY frame with ID that is greater than previously received ID.
- QUIC_HTTP_GOAWAY_ID_LARGER_THAN_PREVIOUS = 167,
- // HTTP/3 session received SETTINGS frame which contains HTTP/2 specific
- // settings.
- QUIC_HTTP_RECEIVE_SPDY_SETTING = 169,
- // HTTP/3 session received an HTTP/2 only frame.
- QUIC_HTTP_RECEIVE_SPDY_FRAME = 171,
- // HTTP/3 session received SERVER_PUSH stream, which is an error because
- // PUSH_PROMISE is not accepted.
- QUIC_HTTP_RECEIVE_SERVER_PUSH = 205,
- // HTTP/3 session received invalid SETTING value.
- QUIC_HTTP_INVALID_SETTING_VALUE = 207,
-
- // HPACK header block decoding errors.
- // Index varint beyond implementation limit.
- QUIC_HPACK_INDEX_VARINT_ERROR = 135,
- // Name length varint beyond implementation limit.
- QUIC_HPACK_NAME_LENGTH_VARINT_ERROR = 136,
- // Value length varint beyond implementation limit.
- QUIC_HPACK_VALUE_LENGTH_VARINT_ERROR = 137,
- // Name length exceeds buffer limit.
- QUIC_HPACK_NAME_TOO_LONG = 138,
- // Value length exceeds buffer limit.
- QUIC_HPACK_VALUE_TOO_LONG = 139,
- // Name Huffman encoding error.
- QUIC_HPACK_NAME_HUFFMAN_ERROR = 140,
- // Value Huffman encoding error.
- QUIC_HPACK_VALUE_HUFFMAN_ERROR = 141,
- // Next instruction should have been a dynamic table size update.
- QUIC_HPACK_MISSING_DYNAMIC_TABLE_SIZE_UPDATE = 142,
- // Invalid index in indexed header field representation.
- QUIC_HPACK_INVALID_INDEX = 143,
- // Invalid index in literal header field with indexed name representation.
- QUIC_HPACK_INVALID_NAME_INDEX = 144,
- // Dynamic table size update not allowed.
- QUIC_HPACK_DYNAMIC_TABLE_SIZE_UPDATE_NOT_ALLOWED = 145,
- // Initial dynamic table size update is above low water mark.
- QUIC_HPACK_INITIAL_TABLE_SIZE_UPDATE_IS_ABOVE_LOW_WATER_MARK = 146,
- // Dynamic table size update is above acknowledged setting.
- QUIC_HPACK_TABLE_SIZE_UPDATE_IS_ABOVE_ACKNOWLEDGED_SETTING = 147,
- // HPACK block ends in the middle of an instruction.
- QUIC_HPACK_TRUNCATED_BLOCK = 148,
- // Incoming data fragment exceeds buffer limit.
- QUIC_HPACK_FRAGMENT_TOO_LONG = 149,
- // Total compressed HPACK data size exceeds limit.
- QUIC_HPACK_COMPRESSED_HEADER_SIZE_EXCEEDS_LIMIT = 150,
-
- // Stream/flow control limit from 1-RTT handshake is too low to retransmit
- // 0-RTT data. This is our implentation error. We could in theory keep the
- // connection alive but chose not to for simplicity.
- QUIC_ZERO_RTT_UNRETRANSMITTABLE = 161,
- // Stream/flow control limit from 0-RTT rejection reduces cached limit.
- // This is our implentation error. We could in theory keep the connection
- // alive but chose not to for simplicity.
- QUIC_ZERO_RTT_REJECTION_LIMIT_REDUCED = 162,
- // Stream/flow control limit from 0-RTT resumption reduces cached limit.
- // This is the peer violating QUIC spec.
- QUIC_ZERO_RTT_RESUMPTION_LIMIT_REDUCED = 163,
-
- // The connection silently timed out due to no network activity.
- QUIC_SILENT_IDLE_TIMEOUT = 168,
-
- // Try to write data without the right write keys.
- QUIC_MISSING_WRITE_KEYS = 170,
-
- // An endpoint detected errors in performing key updates.
- QUIC_KEY_UPDATE_ERROR = 172,
-
- // An endpoint has reached the confidentiality or integrity limit for the
- // AEAD algorithm used by the given connection.
- QUIC_AEAD_LIMIT_REACHED = 173,
-
- // Connection reached maximum age (regardless of activity), no new requests
- // are accepted. This error code is sent in transport layer GOAWAY frame when
- // using gQUIC, and only used internally when using HTTP/3. Active requests
- // are still served, after which connection will be closed due to idle
- // timeout.
- QUIC_MAX_AGE_TIMEOUT = 191,
-
- // Decrypted a 0-RTT packet with a higher packet number than a 1-RTT packet.
- QUIC_INVALID_0RTT_PACKET_NUMBER_OUT_OF_ORDER = 192,
-
- // Received PRIORITY_UPDATE frame with invalid payload.
- QUIC_INVALID_PRIORITY_UPDATE = 193,
-
- // Maps to specific errors from the CRYPTO_ERROR range from
- // https://quicwg.org/base-drafts/draft-ietf-quic-transport.html#name-transport-error-codes
- // This attempts to choose a subset of the most interesting errors rather
- // than mapping every possible CRYPTO_ERROR code.
- QUIC_TLS_BAD_CERTIFICATE = 195,
- QUIC_TLS_UNSUPPORTED_CERTIFICATE = 196,
- QUIC_TLS_CERTIFICATE_REVOKED = 197,
- QUIC_TLS_CERTIFICATE_EXPIRED = 198,
- QUIC_TLS_CERTIFICATE_UNKNOWN = 199,
- QUIC_TLS_INTERNAL_ERROR = 200,
- QUIC_TLS_UNRECOGNIZED_NAME = 201,
- QUIC_TLS_CERTIFICATE_REQUIRED = 202,
-
- // An HTTP field value containing an invalid character has been received.
- QUIC_INVALID_CHARACTER_IN_FIELD_VALUE = 206,
-
- // Error code related to the usage of TLS keying material export.
- QUIC_TLS_UNEXPECTED_KEYING_MATERIAL_EXPORT_LABEL = 208,
- QUIC_TLS_KEYING_MATERIAL_EXPORTS_MISMATCH = 209,
- QUIC_TLS_KEYING_MATERIAL_EXPORT_NOT_AVAILABLE = 210,
- QUIC_UNEXPECTED_DATA_BEFORE_ENCRYPTION_ESTABLISHED = 211,
-
- // No error. Used as bound while iterating.
- QUIC_LAST_ERROR = 212,
-};
-// QuicErrorCodes is encoded as four octets on-the-wire when doing Google QUIC,
-// or a varint62 when doing IETF QUIC. Ensure that its value does not exceed
-// the smaller of the two limits.
-static_assert(static_cast<uint64_t>(QUIC_LAST_ERROR) <=
- static_cast<uint64_t>(std::numeric_limits<uint32_t>::max()),
- "QuicErrorCode exceeds four octets");
-
-// Represents a reason for resetting a stream in both gQUIC and IETF error code
-// space. Both error codes have to be present.
-class QUIC_EXPORT_PRIVATE QuicResetStreamError {
- public:
- // Constructs a QuicResetStreamError from QuicRstStreamErrorCode; the IETF
- // error code is inferred.
- static QuicResetStreamError FromInternal(QuicRstStreamErrorCode code);
- // Constructs a QuicResetStreamError from an IETF error code; the internal
- // error code is inferred.
- static QuicResetStreamError FromIetf(uint64_t code);
- // Constructs a QuicResetStreamError with no error.
- static QuicResetStreamError NoError() {
- return FromInternal(QUIC_STREAM_NO_ERROR);
- }
-
- QuicResetStreamError(QuicRstStreamErrorCode internal_code,
- uint64_t ietf_application_code)
- : internal_code_(internal_code),
- ietf_application_code_(ietf_application_code) {}
-
- QuicRstStreamErrorCode internal_code() const { return internal_code_; }
- uint64_t ietf_application_code() const { return ietf_application_code_; }
-
- bool operator==(const QuicResetStreamError& other) const {
- return internal_code() == other.internal_code() &&
- ietf_application_code() == other.ietf_application_code();
- }
-
- // Returns true if the object holds no error.
- bool ok() const { return internal_code() == QUIC_STREAM_NO_ERROR; }
-
- private:
- // Error code used in gQUIC. Even when IETF QUIC is in use, this needs to be
- // populated as we use those internally.
- QuicRstStreamErrorCode internal_code_;
- // Application error code used in IETF QUIC.
- uint64_t ietf_application_code_;
-};
-
-// Convert TLS alert code to QuicErrorCode.
-QUIC_EXPORT_PRIVATE QuicErrorCode TlsAlertToQuicErrorCode(uint8_t desc);
-
-// Returns the name of the QuicRstStreamErrorCode as a char*
-QUIC_EXPORT_PRIVATE const char* QuicRstStreamErrorCodeToString(
- QuicRstStreamErrorCode error);
-
-// Returns the name of the QuicErrorCode as a char*
-QUIC_EXPORT_PRIVATE const char* QuicErrorCodeToString(QuicErrorCode error);
-
-// Wire values for QUIC transport errors.
-// https://quicwg.org/base-drafts/draft-ietf-quic-transport.html#name-transport-error-codes
-enum QuicIetfTransportErrorCodes : uint64_t {
- NO_IETF_QUIC_ERROR = 0x0,
- INTERNAL_ERROR = 0x1,
- SERVER_BUSY_ERROR = 0x2,
- FLOW_CONTROL_ERROR = 0x3,
- STREAM_LIMIT_ERROR = 0x4,
- STREAM_STATE_ERROR = 0x5,
- FINAL_SIZE_ERROR = 0x6,
- FRAME_ENCODING_ERROR = 0x7,
- TRANSPORT_PARAMETER_ERROR = 0x8,
- CONNECTION_ID_LIMIT_ERROR = 0x9,
- PROTOCOL_VIOLATION = 0xA,
- INVALID_TOKEN = 0xB,
- CRYPTO_BUFFER_EXCEEDED = 0xD,
- KEY_UPDATE_ERROR = 0xE,
- AEAD_LIMIT_REACHED = 0xF,
- CRYPTO_ERROR_FIRST = 0x100,
- CRYPTO_ERROR_LAST = 0x1FF,
-};
-
-QUIC_EXPORT_PRIVATE std::string QuicIetfTransportErrorCodeString(
- QuicIetfTransportErrorCodes c);
-
-QUIC_EXPORT_PRIVATE std::ostream& operator<<(
- std::ostream& os, const QuicIetfTransportErrorCodes& c);
-
-// A transport error code (if is_transport_close is true) or application error
-// code (if is_transport_close is false) to be used in CONNECTION_CLOSE frames.
-struct QUIC_EXPORT_PRIVATE QuicErrorCodeToIetfMapping {
- bool is_transport_close;
- uint64_t error_code;
-};
-
-// Convert QuicErrorCode to transport or application IETF error code
-// to be used in CONNECTION_CLOSE frames.
-QUIC_EXPORT_PRIVATE QuicErrorCodeToIetfMapping
-QuicErrorCodeToTransportErrorCode(QuicErrorCode error);
-
-// Wire values for HTTP/3 errors.
-// https://quicwg.org/base-drafts/draft-ietf-quic-http.html#http-error-codes
-enum class QuicHttp3ErrorCode {
- // NO_ERROR is defined as a C preprocessor macro on Windows.
- HTTP3_NO_ERROR = 0x100,
- GENERAL_PROTOCOL_ERROR = 0x101,
- INTERNAL_ERROR = 0x102,
- STREAM_CREATION_ERROR = 0x103,
- CLOSED_CRITICAL_STREAM = 0x104,
- FRAME_UNEXPECTED = 0x105,
- FRAME_ERROR = 0x106,
- EXCESSIVE_LOAD = 0x107,
- ID_ERROR = 0x108,
- SETTINGS_ERROR = 0x109,
- MISSING_SETTINGS = 0x10A,
- REQUEST_REJECTED = 0x10B,
- REQUEST_CANCELLED = 0x10C,
- REQUEST_INCOMPLETE = 0x10D,
- MESSAGE_ERROR = 0x10E,
- CONNECT_ERROR = 0x10F,
- VERSION_FALLBACK = 0x110,
-};
-
-// Wire values for QPACK errors.
-// https://quicwg.org/base-drafts/draft-ietf-quic-qpack.html#error-code-registration
-enum class QuicHttpQpackErrorCode {
- DECOMPRESSION_FAILED = 0x200,
- ENCODER_STREAM_ERROR = 0x201,
- DECODER_STREAM_ERROR = 0x202
-};
-
-// Convert a QuicRstStreamErrorCode to an application error code to be used in
-// an IETF QUIC RESET_STREAM frame
-QUIC_EXPORT_PRIVATE uint64_t RstStreamErrorCodeToIetfResetStreamErrorCode(
- QuicRstStreamErrorCode rst_stream_error_code);
-
-// Convert the application error code of an IETF QUIC RESET_STREAM frame
-// to QuicRstStreamErrorCode.
-QUIC_EXPORT_PRIVATE QuicRstStreamErrorCode
-IetfResetStreamErrorCodeToRstStreamErrorCode(uint64_t ietf_error_code);
-
-QUIC_EXPORT_PRIVATE inline std::string HistogramEnumString(
- QuicErrorCode enum_value) {
- return QuicErrorCodeToString(enum_value);
-}
-
-QUIC_EXPORT_PRIVATE inline std::string HistogramEnumDescription(
- QuicErrorCode /*dummy*/) {
- return "cause";
-}
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_QUIC_ERROR_CODES_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_error_codes_test.cc b/chromium/net/third_party/quiche/src/quic/core/quic_error_codes_test.cc
deleted file mode 100644
index 4c5517ffb8e..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_error_codes_test.cc
+++ /dev/null
@@ -1,143 +0,0 @@
-// Copyright (c) 2013 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 "quic/core/quic_error_codes.h"
-
-#include <cstdint>
-
-#include "third_party/boringssl/src/include/openssl/ssl.h"
-#include "quic/platform/api/quic_test.h"
-
-namespace quic {
-namespace test {
-namespace {
-
-using QuicErrorCodesTest = QuicTest;
-
-TEST_F(QuicErrorCodesTest, QuicErrorCodeToString) {
- EXPECT_STREQ("QUIC_NO_ERROR", QuicErrorCodeToString(QUIC_NO_ERROR));
-}
-
-TEST_F(QuicErrorCodesTest, QuicIetfTransportErrorCodeString) {
- EXPECT_EQ("CRYPTO_ERROR(missing extension)",
- QuicIetfTransportErrorCodeString(
- static_cast<quic::QuicIetfTransportErrorCodes>(
- CRYPTO_ERROR_FIRST + SSL_AD_MISSING_EXTENSION)));
-
- EXPECT_EQ("NO_IETF_QUIC_ERROR",
- QuicIetfTransportErrorCodeString(NO_IETF_QUIC_ERROR));
- EXPECT_EQ("INTERNAL_ERROR", QuicIetfTransportErrorCodeString(INTERNAL_ERROR));
- EXPECT_EQ("SERVER_BUSY_ERROR",
- QuicIetfTransportErrorCodeString(SERVER_BUSY_ERROR));
- EXPECT_EQ("FLOW_CONTROL_ERROR",
- QuicIetfTransportErrorCodeString(FLOW_CONTROL_ERROR));
- EXPECT_EQ("STREAM_LIMIT_ERROR",
- QuicIetfTransportErrorCodeString(STREAM_LIMIT_ERROR));
- EXPECT_EQ("STREAM_STATE_ERROR",
- QuicIetfTransportErrorCodeString(STREAM_STATE_ERROR));
- EXPECT_EQ("FINAL_SIZE_ERROR",
- QuicIetfTransportErrorCodeString(FINAL_SIZE_ERROR));
- EXPECT_EQ("FRAME_ENCODING_ERROR",
- QuicIetfTransportErrorCodeString(FRAME_ENCODING_ERROR));
- EXPECT_EQ("TRANSPORT_PARAMETER_ERROR",
- QuicIetfTransportErrorCodeString(TRANSPORT_PARAMETER_ERROR));
- EXPECT_EQ("CONNECTION_ID_LIMIT_ERROR",
- QuicIetfTransportErrorCodeString(CONNECTION_ID_LIMIT_ERROR));
- EXPECT_EQ("PROTOCOL_VIOLATION",
- QuicIetfTransportErrorCodeString(PROTOCOL_VIOLATION));
- EXPECT_EQ("INVALID_TOKEN", QuicIetfTransportErrorCodeString(INVALID_TOKEN));
- EXPECT_EQ("CRYPTO_BUFFER_EXCEEDED",
- QuicIetfTransportErrorCodeString(CRYPTO_BUFFER_EXCEEDED));
- EXPECT_EQ("KEY_UPDATE_ERROR",
- QuicIetfTransportErrorCodeString(KEY_UPDATE_ERROR));
- EXPECT_EQ("AEAD_LIMIT_REACHED",
- QuicIetfTransportErrorCodeString(AEAD_LIMIT_REACHED));
-
- EXPECT_EQ("Unknown(1024)",
- QuicIetfTransportErrorCodeString(
- static_cast<quic::QuicIetfTransportErrorCodes>(0x400)));
-}
-
-TEST_F(QuicErrorCodesTest, QuicErrorCodeToTransportErrorCode) {
- for (int internal_error_code = 0; internal_error_code < QUIC_LAST_ERROR;
- ++internal_error_code) {
- std::string internal_error_code_string =
- QuicErrorCodeToString(static_cast<QuicErrorCode>(internal_error_code));
- if (internal_error_code_string == "INVALID_ERROR_CODE") {
- // Not a valid QuicErrorCode.
- continue;
- }
- QuicErrorCodeToIetfMapping ietf_error_code =
- QuicErrorCodeToTransportErrorCode(
- static_cast<QuicErrorCode>(internal_error_code));
- if (ietf_error_code.is_transport_close) {
- QuicIetfTransportErrorCodes transport_error_code =
- static_cast<QuicIetfTransportErrorCodes>(ietf_error_code.error_code);
- bool is_transport_crypto_error_code =
- transport_error_code >= 0x100 && transport_error_code <= 0x1ff;
- if (is_transport_crypto_error_code) {
- // Ensure that every QuicErrorCode that maps to a CRYPTO_ERROR code has
- // a corresponding reverse mapping in TlsAlertToQuicErrorCode:
- EXPECT_EQ(
- internal_error_code,
- TlsAlertToQuicErrorCode(transport_error_code - CRYPTO_ERROR_FIRST));
- }
- bool is_valid_transport_error_code =
- transport_error_code <= 0x0f || is_transport_crypto_error_code;
- EXPECT_TRUE(is_valid_transport_error_code) << internal_error_code_string;
- } else {
- // Non-transport errors are application errors, either HTTP/3 or QPACK.
- uint64_t application_error_code = ietf_error_code.error_code;
- bool is_valid_http3_error_code =
- application_error_code >= 0x100 && application_error_code <= 0x110;
- bool is_valid_qpack_error_code =
- application_error_code >= 0x200 && application_error_code <= 0x202;
- EXPECT_TRUE(is_valid_http3_error_code || is_valid_qpack_error_code)
- << internal_error_code_string;
- }
- }
-}
-
-using QuicRstErrorCodesTest = QuicTest;
-
-TEST_F(QuicRstErrorCodesTest, QuicRstStreamErrorCodeToString) {
- EXPECT_STREQ("QUIC_BAD_APPLICATION_PAYLOAD",
- QuicRstStreamErrorCodeToString(QUIC_BAD_APPLICATION_PAYLOAD));
-}
-
-// When an IETF application protocol error code (sent on the wire in
-// RESET_STREAM and STOP_SENDING frames) is translated into a
-// QuicRstStreamErrorCode and back, it must yield the original value.
-TEST_F(QuicRstErrorCodesTest,
- IetfResetStreamErrorCodeToRstStreamErrorCodeAndBack) {
- for (uint64_t wire_code :
- {static_cast<uint64_t>(QuicHttp3ErrorCode::HTTP3_NO_ERROR),
- static_cast<uint64_t>(QuicHttp3ErrorCode::GENERAL_PROTOCOL_ERROR),
- static_cast<uint64_t>(QuicHttp3ErrorCode::INTERNAL_ERROR),
- static_cast<uint64_t>(QuicHttp3ErrorCode::STREAM_CREATION_ERROR),
- static_cast<uint64_t>(QuicHttp3ErrorCode::CLOSED_CRITICAL_STREAM),
- static_cast<uint64_t>(QuicHttp3ErrorCode::FRAME_UNEXPECTED),
- static_cast<uint64_t>(QuicHttp3ErrorCode::FRAME_ERROR),
- static_cast<uint64_t>(QuicHttp3ErrorCode::EXCESSIVE_LOAD),
- static_cast<uint64_t>(QuicHttp3ErrorCode::ID_ERROR),
- static_cast<uint64_t>(QuicHttp3ErrorCode::SETTINGS_ERROR),
- static_cast<uint64_t>(QuicHttp3ErrorCode::MISSING_SETTINGS),
- static_cast<uint64_t>(QuicHttp3ErrorCode::REQUEST_REJECTED),
- static_cast<uint64_t>(QuicHttp3ErrorCode::REQUEST_CANCELLED),
- static_cast<uint64_t>(QuicHttp3ErrorCode::REQUEST_INCOMPLETE),
- static_cast<uint64_t>(QuicHttp3ErrorCode::CONNECT_ERROR),
- static_cast<uint64_t>(QuicHttp3ErrorCode::VERSION_FALLBACK),
- static_cast<uint64_t>(QuicHttpQpackErrorCode::DECOMPRESSION_FAILED),
- static_cast<uint64_t>(QuicHttpQpackErrorCode::ENCODER_STREAM_ERROR),
- static_cast<uint64_t>(QuicHttpQpackErrorCode::DECODER_STREAM_ERROR)}) {
- QuicRstStreamErrorCode rst_stream_error_code =
- IetfResetStreamErrorCodeToRstStreamErrorCode(wire_code);
- EXPECT_EQ(wire_code, RstStreamErrorCodeToIetfResetStreamErrorCode(
- rst_stream_error_code));
- }
-}
-
-} // namespace
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_flags_list.h b/chromium/net/third_party/quiche/src/quic/core/quic_flags_list.h
deleted file mode 100644
index 069ba10b822..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_flags_list.h
+++ /dev/null
@@ -1,142 +0,0 @@
-// 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.
-
-// This file is autogenerated by the QUICHE Copybara export script.
-
-#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)
-// A testonly reloadable flag that will always default to false.
-QUIC_FLAG(FLAGS_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)
-// A testonly restart flag that will always default to false.
-QUIC_FLAG(FLAGS_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)
-// Donot check amplification limit if there is available pending_timer_transmission_count.
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_donot_check_amplification_limit_with_pending_timer_credit, 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) NEW_TOKENs sent from a IETF QUIC session will include the cached network parameters proto, 2) A min_rtt received from a validated token will be used to set the initial rtt, 3) Enable bandwidth resumption for IETF QUIC when connection options BWRE or BWMX exists.
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_add_cached_network_parameters_to_address_token2, 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)
-// If true, QpackEncoder will stop emitting instructions on the encoder stream if amount of buffered data exceeds a hardcoded limit.
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_limit_encoder_stream_buffering, true)
-// 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)
-// 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)
-// If true, accept empty crypto frame.
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_accept_empty_crypto_frame, 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)
-// 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, false)
-// If true, change QuicCryptoServerStream::FinishProcessingHandshakeMessageAfterProcessClientHello to noop if connection is disconnected.
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_crypto_noop_if_disconnected_after_process_chlo, true)
-// If true, clear undecryptable packets on handshake complete.
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_clear_undecryptable_packets_on_handshake_complete, 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, default on PTO which unifies TLP + RTO loss recovery.
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_default_on_pto, false)
-// If true, default-enable 5RTO blachole detection.
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_default_enable_5rto_blackhole_detection2, true)
-// If true, delay block allocation in QuicStreamSequencerBuffer until there is actually new data available.
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_delay_sequencer_buffer_allocation_until_new_data, true)
-// If true, disable QUIC version Q043.
-QUIC_FLAG(FLAGS_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)
-// If true, disable QUIC version Q050.
-QUIC_FLAG(FLAGS_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)
-// If true, disable QUIC version h3-29.
-QUIC_FLAG(FLAGS_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)
-// 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 bundle 2nd ACK with connection close if there is an ACK queued.
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_single_ack_in_packet2, false)
-// If true, do not call ProofSourceHandle::SelectCertificate if QUIC connection has disconnected.
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_tls_no_select_cert_if_disconnected, 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)
-// If true, do not use the gQUIC common certificate set for certificate compression.
-QUIC_FLAG(FLAGS_quic_restart_flag_quic_no_common_cert_set, 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 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)
-// 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, false)
-// If true, ignore peer_max_ack_delay during handshake.
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_ignore_peer_max_ack_delay_during_handshake, true)
-// 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, pass the received PATH_RESPONSE payload to path validator to move forward the path validation.
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_pass_path_response_to_validator, 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)
-// 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)
-// If true, require handshake confirmation for QUIC connections, functionally disabling 0-rtt handshakes.
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_require_handshake_confirmation, false)
-// If true, reset per packet state before processing undecryptable packets.
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_reset_per_packet_state_for_undecryptable_packets, true)
-// If true, send PATH_RESPONSE upon receiving PATH_CHALLENGE regardless of perspective. --gfe2_reloadable_flag_quic_start_peer_migration_earlier has to be true before turn on this flag.
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_send_path_response2, true)
-// 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, false)
-// If true, set burst token to 2 in cwnd bootstrapping experiment.
-QUIC_FLAG(FLAGS_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, 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)
-// If true, use max(max_bw, send_rate) as the estimated bandwidth in QUIC\'s MaxAckHeightTracker.
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_bbr_use_send_rate_in_max_ack_height_tracker, true)
-// If true, use new connection ID in connection migration.
-QUIC_FLAG(FLAGS_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 client attempts TLS resumption, use token in session_cache_ instead of cached_states_ in QuicCryptoClientConfig.
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_tls_use_token_in_session_cache, true)
-// 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)
-// When true, QUIC will both send and validate the version_information transport parameter.
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_version_information, true)
-// When true, defaults to BBR congestion control instead of Cubic.
-QUIC_FLAG(FLAGS_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)
-// 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)
-// When true, support draft-ietf-quic-v2-01
-QUIC_FLAG(FLAGS_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)
-// 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)
-// 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)
-// 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)
-// 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)
-
-#endif
-
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_flow_controller.cc b/chromium/net/third_party/quiche/src/quic/core/quic_flow_controller.cc
deleted file mode 100644
index 88dc3edcd44..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_flow_controller.cc
+++ /dev/null
@@ -1,319 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_flow_controller.h"
-
-#include <cstdint>
-
-#include "absl/strings/str_cat.h"
-#include "quic/core/quic_connection.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_session.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_flag_utils.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-#define ENDPOINT \
- (perspective_ == Perspective::IS_SERVER ? "Server: " : "Client: ")
-
-std::string QuicFlowController::LogLabel() {
- if (is_connection_flow_controller_) {
- return "connection";
- }
- return absl::StrCat("stream ", id_);
-}
-
-QuicFlowController::QuicFlowController(
- QuicSession* session,
- QuicStreamId id,
- bool is_connection_flow_controller,
- QuicStreamOffset send_window_offset,
- QuicStreamOffset receive_window_offset,
- QuicByteCount receive_window_size_limit,
- bool should_auto_tune_receive_window,
- QuicFlowControllerInterface* session_flow_controller)
- : session_(session),
- connection_(session->connection()),
- id_(id),
- is_connection_flow_controller_(is_connection_flow_controller),
- perspective_(session->perspective()),
- bytes_sent_(0),
- send_window_offset_(send_window_offset),
- bytes_consumed_(0),
- highest_received_byte_offset_(0),
- receive_window_offset_(receive_window_offset),
- receive_window_size_(receive_window_offset),
- receive_window_size_limit_(receive_window_size_limit),
- auto_tune_receive_window_(should_auto_tune_receive_window),
- session_flow_controller_(session_flow_controller),
- last_blocked_send_window_offset_(0),
- prev_window_update_time_(QuicTime::Zero()) {
- QUICHE_DCHECK_LE(receive_window_size_, receive_window_size_limit_);
- QUICHE_DCHECK_EQ(
- is_connection_flow_controller_,
- QuicUtils::GetInvalidStreamId(session_->transport_version()) == id_);
-
- QUIC_DVLOG(1) << ENDPOINT << "Created flow controller for " << LogLabel()
- << ", setting initial receive window offset to: "
- << receive_window_offset_
- << ", max receive window to: " << receive_window_size_
- << ", max receive window limit to: "
- << receive_window_size_limit_
- << ", setting send window offset to: " << send_window_offset_;
-}
-
-void QuicFlowController::AddBytesConsumed(QuicByteCount bytes_consumed) {
- bytes_consumed_ += bytes_consumed;
- QUIC_DVLOG(1) << ENDPOINT << LogLabel() << " consumed " << bytes_consumed_
- << " bytes.";
-
- MaybeSendWindowUpdate();
-}
-
-bool QuicFlowController::UpdateHighestReceivedOffset(
- QuicStreamOffset new_offset) {
- // Only update if offset has increased.
- if (new_offset <= highest_received_byte_offset_) {
- return false;
- }
-
- QUIC_DVLOG(1) << ENDPOINT << LogLabel()
- << " highest byte offset increased from "
- << highest_received_byte_offset_ << " to " << new_offset;
- highest_received_byte_offset_ = new_offset;
- return true;
-}
-
-void QuicFlowController::AddBytesSent(QuicByteCount bytes_sent) {
- if (bytes_sent_ + bytes_sent > send_window_offset_) {
- QUIC_BUG(quic_bug_10836_1)
- << ENDPOINT << LogLabel() << " Trying to send an extra " << bytes_sent
- << " bytes, when bytes_sent = " << bytes_sent_
- << ", and send_window_offset_ = " << send_window_offset_;
- bytes_sent_ = send_window_offset_;
-
- // This is an error on our side, close the connection as soon as possible.
- connection_->CloseConnection(
- QUIC_FLOW_CONTROL_SENT_TOO_MUCH_DATA,
- absl::StrCat(send_window_offset_ - (bytes_sent_ + bytes_sent),
- "bytes over send window offset"),
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
- return;
- }
-
- bytes_sent_ += bytes_sent;
- QUIC_DVLOG(1) << ENDPOINT << LogLabel() << " sent " << bytes_sent_
- << " bytes.";
-}
-
-bool QuicFlowController::FlowControlViolation() {
- if (highest_received_byte_offset_ > receive_window_offset_) {
- QUIC_DLOG(INFO) << ENDPOINT << "Flow control violation on " << LogLabel()
- << ", receive window offset: " << receive_window_offset_
- << ", highest received byte offset: "
- << highest_received_byte_offset_;
- return true;
- }
- return false;
-}
-
-void QuicFlowController::MaybeIncreaseMaxWindowSize() {
- // Core of receive window auto tuning. This method should be called before a
- // WINDOW_UPDATE frame is sent. Ideally, window updates should occur close to
- // once per RTT. If a window update happens much faster than RTT, it implies
- // that the flow control window is imposing a bottleneck. To prevent this,
- // this method will increase the receive window size (subject to a reasonable
- // upper bound). For simplicity this algorithm is deliberately asymmetric, in
- // that it may increase window size but never decreases.
-
- // Keep track of timing between successive window updates.
- QuicTime now = connection_->clock()->ApproximateNow();
- QuicTime prev = prev_window_update_time_;
- prev_window_update_time_ = now;
- if (!prev.IsInitialized()) {
- QUIC_DVLOG(1) << ENDPOINT << "first window update for " << LogLabel();
- return;
- }
-
- if (!auto_tune_receive_window_) {
- return;
- }
-
- // Get outbound RTT.
- QuicTime::Delta rtt =
- connection_->sent_packet_manager().GetRttStats()->smoothed_rtt();
- if (rtt.IsZero()) {
- QUIC_DVLOG(1) << ENDPOINT << "rtt zero for " << LogLabel();
- return;
- }
-
- // Now we can compare timing of window updates with RTT.
- QuicTime::Delta since_last = now - prev;
- QuicTime::Delta two_rtt = 2 * rtt;
-
- if (since_last >= two_rtt) {
- // If interval between window updates is sufficiently large, there
- // is no need to increase receive_window_size_.
- return;
- }
- QuicByteCount old_window = receive_window_size_;
- IncreaseWindowSize();
-
- if (receive_window_size_ > old_window) {
- QUIC_DVLOG(1) << ENDPOINT << "New max window increase for " << LogLabel()
- << " after " << since_last.ToMicroseconds()
- << " us, and RTT is " << rtt.ToMicroseconds()
- << "us. max wndw: " << receive_window_size_;
- if (session_flow_controller_ != nullptr) {
- session_flow_controller_->EnsureWindowAtLeast(
- kSessionFlowControlMultiplier * receive_window_size_);
- }
- } else {
- // TODO(ckrasic) - add a varz to track this (?).
- QUIC_LOG_FIRST_N(INFO, 1)
- << ENDPOINT << "Max window at limit for " << LogLabel() << " after "
- << since_last.ToMicroseconds() << " us, and RTT is "
- << rtt.ToMicroseconds() << "us. Limit size: " << receive_window_size_;
- }
-}
-
-void QuicFlowController::IncreaseWindowSize() {
- receive_window_size_ *= 2;
- receive_window_size_ =
- std::min(receive_window_size_, receive_window_size_limit_);
-}
-
-QuicByteCount QuicFlowController::WindowUpdateThreshold() {
- return receive_window_size_ / 2;
-}
-
-void QuicFlowController::MaybeSendWindowUpdate() {
- if (!session_->connection()->connected()) {
- return;
- }
- // Send WindowUpdate to increase receive window if
- // (receive window offset - consumed bytes) < (max window / 2).
- // This is behaviour copied from SPDY.
- QUICHE_DCHECK_LE(bytes_consumed_, receive_window_offset_);
- QuicStreamOffset available_window = receive_window_offset_ - bytes_consumed_;
- QuicByteCount threshold = WindowUpdateThreshold();
-
- if (!prev_window_update_time_.IsInitialized()) {
- // Treat the initial window as if it is a window update, so if 1/2 the
- // window is used in less than 2 RTTs, the window is increased.
- prev_window_update_time_ = connection_->clock()->ApproximateNow();
- }
-
- if (available_window >= threshold) {
- QUIC_DVLOG(1) << ENDPOINT << "Not sending WindowUpdate for " << LogLabel()
- << ", available window: " << available_window
- << " >= threshold: " << threshold;
- return;
- }
-
- MaybeIncreaseMaxWindowSize();
- UpdateReceiveWindowOffsetAndSendWindowUpdate(available_window);
-}
-
-void QuicFlowController::UpdateReceiveWindowOffsetAndSendWindowUpdate(
- QuicStreamOffset available_window) {
- // Update our receive window.
- receive_window_offset_ += (receive_window_size_ - available_window);
-
- QUIC_DVLOG(1) << ENDPOINT << "Sending WindowUpdate frame for " << LogLabel()
- << ", consumed bytes: " << bytes_consumed_
- << ", available window: " << available_window
- << ", and threshold: " << WindowUpdateThreshold()
- << ", and receive window size: " << receive_window_size_
- << ". New receive window offset is: " << receive_window_offset_;
-
- SendWindowUpdate();
-}
-
-bool QuicFlowController::ShouldSendBlocked() {
- if (SendWindowSize() != 0 ||
- last_blocked_send_window_offset_ >= send_window_offset_) {
- return false;
- }
- QUIC_DLOG(INFO) << ENDPOINT << LogLabel() << " is flow control blocked. "
- << "Send window: " << SendWindowSize()
- << ", bytes sent: " << bytes_sent_
- << ", send limit: " << send_window_offset_;
- // The entire send_window has been consumed, we are now flow control
- // blocked.
-
- // 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;
-}
-
-bool QuicFlowController::UpdateSendWindowOffset(
- QuicStreamOffset new_send_window_offset) {
- // Only update if send window has increased.
- if (new_send_window_offset <= send_window_offset_) {
- return false;
- }
-
- QUIC_DVLOG(1) << ENDPOINT << "UpdateSendWindowOffset for " << LogLabel()
- << " with new offset " << new_send_window_offset
- << " current offset: " << send_window_offset_
- << " bytes_sent: " << bytes_sent_;
-
- // The flow is now unblocked but could have also been unblocked
- // before. Return true iff this update caused a change from blocked
- // to unblocked.
- const bool was_previously_blocked = IsBlocked();
- send_window_offset_ = new_send_window_offset;
- return was_previously_blocked;
-}
-
-void QuicFlowController::EnsureWindowAtLeast(QuicByteCount window_size) {
- if (receive_window_size_limit_ >= window_size) {
- return;
- }
-
- QuicStreamOffset available_window = receive_window_offset_ - bytes_consumed_;
- IncreaseWindowSize();
- UpdateReceiveWindowOffsetAndSendWindowUpdate(available_window);
-}
-
-bool QuicFlowController::IsBlocked() const {
- return SendWindowSize() == 0;
-}
-
-uint64_t QuicFlowController::SendWindowSize() const {
- if (bytes_sent_ > send_window_offset_) {
- return 0;
- }
- return send_window_offset_ - bytes_sent_;
-}
-
-void QuicFlowController::UpdateReceiveWindowSize(QuicStreamOffset size) {
- QUICHE_DCHECK_LE(size, receive_window_size_limit_);
- QUIC_DVLOG(1) << ENDPOINT << "UpdateReceiveWindowSize for " << LogLabel()
- << ": " << size;
- if (receive_window_size_ != receive_window_offset_) {
- QUIC_BUG(quic_bug_10836_2)
- << "receive_window_size_:" << receive_window_size_
- << " != receive_window_offset:" << receive_window_offset_;
- return;
- }
- receive_window_size_ = size;
- receive_window_offset_ = size;
-}
-
-void QuicFlowController::SendWindowUpdate() {
- QuicStreamId id = id_;
- if (is_connection_flow_controller_) {
- id = QuicUtils::GetInvalidStreamId(connection_->transport_version());
- }
- session_->SendWindowUpdate(id, receive_window_offset_);
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_flow_controller.h b/chromium/net/third_party/quiche/src/quic/core/quic_flow_controller.h
deleted file mode 100644
index 3998081736d..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_flow_controller.h
+++ /dev/null
@@ -1,217 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_FLOW_CONTROLLER_H_
-#define QUICHE_QUIC_CORE_QUIC_FLOW_CONTROLLER_H_
-
-#include "quic/core/quic_packets.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-namespace test {
-class QuicFlowControllerPeer;
-} // namespace test
-
-class QuicConnection;
-class QuicSession;
-
-// How much larger the session flow control window needs to be relative to any
-// stream's flow control window.
-const float kSessionFlowControlMultiplier = 1.5;
-
-class QUIC_EXPORT_PRIVATE QuicFlowControllerInterface {
- public:
- virtual ~QuicFlowControllerInterface() {}
-
- // Ensures the flow control window is at least |window_size| and send out an
- // update frame if it is increased.
- virtual void EnsureWindowAtLeast(QuicByteCount window_size) = 0;
-};
-
-// QuicFlowController allows a QUIC stream or connection to perform flow
-// control. The stream/connection owns a QuicFlowController which keeps track of
-// bytes sent/received, can tell the owner if it is flow control blocked, and
-// can send WINDOW_UPDATE or BLOCKED frames when needed.
-class QUIC_EXPORT_PRIVATE QuicFlowController
- : public QuicFlowControllerInterface {
- public:
- QuicFlowController(QuicSession* session,
- QuicStreamId id,
- bool is_connection_flow_controller,
- QuicStreamOffset send_window_offset,
- QuicStreamOffset receive_window_offset,
- QuicByteCount receive_window_size_limit,
- bool should_auto_tune_receive_window,
- QuicFlowControllerInterface* session_flow_controller);
-
- QuicFlowController(const QuicFlowController&) = delete;
- QuicFlowController(QuicFlowController&&) = default;
- QuicFlowController& operator=(const QuicFlowController&) = delete;
-
- ~QuicFlowController() override {}
-
- // Called when we see a new highest received byte offset from the peer, either
- // via a data frame or a RST.
- // Returns true if this call changes highest_received_byte_offset_, and false
- // in the case where |new_offset| is <= highest_received_byte_offset_.
- bool UpdateHighestReceivedOffset(QuicStreamOffset new_offset);
-
- // Called when bytes received from the peer are consumed locally. This may
- // trigger the sending of a WINDOW_UPDATE frame using |connection|.
- void AddBytesConsumed(QuicByteCount bytes_consumed);
-
- // Called when bytes are sent to the peer.
- void AddBytesSent(QuicByteCount bytes_sent);
-
- // Increases |send_window_offset_| if |new_send_window_offset| is
- // greater than the current value. Returns true if this increase
- // also causes us to change from a blocked state to unblocked. In
- // all other cases, returns false.
- bool UpdateSendWindowOffset(QuicStreamOffset new_send_window_offset);
-
- // QuicFlowControllerInterface.
- void EnsureWindowAtLeast(QuicByteCount window_size) override;
-
- // Returns the current available send window.
- QuicByteCount SendWindowSize() const;
-
- QuicByteCount receive_window_size() const { return receive_window_size_; }
-
- // Returns whether a BLOCKED frame should be sent.
- bool ShouldSendBlocked();
-
- // Returns true if flow control send limits have been reached.
- bool IsBlocked() const;
-
- // Returns true if flow control receive limits have been violated by the peer.
- bool FlowControlViolation();
-
- // Inform the peer of new receive window.
- void SendWindowUpdate();
-
- QuicByteCount bytes_consumed() const { return bytes_consumed_; }
-
- QuicByteCount bytes_sent() const { return bytes_sent_; }
-
- QuicStreamOffset send_window_offset() const { return send_window_offset_; }
-
- QuicStreamOffset highest_received_byte_offset() const {
- return highest_received_byte_offset_;
- }
-
- void set_receive_window_size_limit(QuicByteCount receive_window_size_limit) {
- QUICHE_DCHECK_GE(receive_window_size_limit, receive_window_size_limit_);
- receive_window_size_limit_ = receive_window_size_limit;
- }
-
- // Should only be called before any data is received.
- void UpdateReceiveWindowSize(QuicStreamOffset size);
-
- bool auto_tune_receive_window() { return auto_tune_receive_window_; }
-
- private:
- friend class test::QuicFlowControllerPeer;
-
- // Send a WINDOW_UPDATE frame if appropriate.
- void MaybeSendWindowUpdate();
-
- // Auto-tune the max receive window size.
- void MaybeIncreaseMaxWindowSize();
-
- // Updates the current offset and sends a window update frame.
- void UpdateReceiveWindowOffsetAndSendWindowUpdate(
- QuicStreamOffset available_window);
-
- // Double the window size as long as we haven't hit the max window size.
- void IncreaseWindowSize();
-
- // Returns "stream $ID" (where $ID is set to |id_|) or "connection" based on
- // |is_connection_flow_controller_|.
- std::string LogLabel();
-
- // The parent session/connection, used to send connection close on flow
- // control violation, and WINDOW_UPDATE and BLOCKED frames when appropriate.
- // Not owned.
- QuicSession* session_;
- QuicConnection* connection_;
-
- // ID of stream this flow controller belongs to. If
- // |is_connection_flow_controller_| is false, this must be a valid stream ID.
- QuicStreamId id_;
-
- // Whether this flow controller is the connection level flow controller
- // instead of the flow controller for a stream. If true, |id_| is ignored.
- bool is_connection_flow_controller_;
-
- // Tracks if this is owned by a server or a client.
- Perspective perspective_;
-
- // Tracks number of bytes sent to the peer.
- QuicByteCount bytes_sent_;
-
- // The absolute offset in the outgoing byte stream. If this offset is reached
- // then we become flow control blocked until we receive a WINDOW_UPDATE.
- QuicStreamOffset send_window_offset_;
-
- // Overview of receive flow controller.
- //
- // 0=...===1=======2-------3 ...... FIN
- // |<--- <= 4 --->|
- //
-
- // 1) bytes_consumed_ - moves forward when data is read out of the
- // stream.
- //
- // 2) highest_received_byte_offset_ - moves when data is received
- // from the peer.
- //
- // 3) receive_window_offset_ - moves when WINDOW_UPDATE is sent.
- //
- // 4) receive_window_size_ - maximum allowed unread data (3 - 1).
- // This value may be increased by auto-tuning.
- //
- // 5) receive_window_size_limit_ - limit on receive_window_size_;
- // auto-tuning will not increase window size beyond this limit.
-
- // Track number of bytes received from the peer, which have been consumed
- // locally.
- QuicByteCount bytes_consumed_;
-
- // The highest byte offset we have seen from the peer. This could be the
- // highest offset in a data frame, or a final value in a RST.
- QuicStreamOffset highest_received_byte_offset_;
-
- // The absolute offset in the incoming byte stream. The peer should never send
- // us bytes which are beyond this offset.
- QuicStreamOffset receive_window_offset_;
-
- // Largest size the receive window can grow to.
- QuicByteCount receive_window_size_;
-
- // Upper limit on receive_window_size_;
- QuicByteCount receive_window_size_limit_;
-
- // Used to dynamically enable receive window auto-tuning.
- bool auto_tune_receive_window_;
-
- // The session's flow controller. Null if this is the session flow controller.
- // Not owned.
- QuicFlowControllerInterface* session_flow_controller_;
-
- // Send window update when receive window size drops below this.
- QuicByteCount WindowUpdateThreshold();
-
- // Keep track of the last time we sent a BLOCKED frame. We should only send
- // another when the number of bytes we have sent has changed.
- QuicStreamOffset last_blocked_send_window_offset_;
-
- // Keep time of the last time a window update was sent. We use this
- // as part of the receive window auto tuning.
- QuicTime prev_window_update_time_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_QUIC_FLOW_CONTROLLER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_flow_controller_test.cc b/chromium/net/third_party/quiche/src/quic/core/quic_flow_controller_test.cc
deleted file mode 100644
index 4c2ce45860d..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_flow_controller_test.cc
+++ /dev/null
@@ -1,408 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_flow_controller.h"
-
-#include <memory>
-#include <utility>
-
-#include "absl/strings/str_cat.h"
-#include "quic/core/crypto/null_encrypter.h"
-#include "quic/platform/api/quic_expect_bug.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/quic_connection_peer.h"
-#include "quic/test_tools/quic_flow_controller_peer.h"
-#include "quic/test_tools/quic_sent_packet_manager_peer.h"
-#include "quic/test_tools/quic_test_utils.h"
-
-using testing::_;
-using testing::Invoke;
-
-namespace quic {
-namespace test {
-
-// Receive window auto-tuning uses RTT in its logic.
-const int64_t kRtt = 100;
-
-class MockFlowController : public QuicFlowControllerInterface {
- public:
- MockFlowController() {}
- MockFlowController(const MockFlowController&) = delete;
- MockFlowController& operator=(const MockFlowController&) = delete;
- ~MockFlowController() override {}
-
- MOCK_METHOD(void, EnsureWindowAtLeast, (QuicByteCount), (override));
-};
-
-class QuicFlowControllerTest : public QuicTest {
- public:
- void Initialize() {
- connection_ = new MockQuicConnection(&helper_, &alarm_factory_,
- Perspective::IS_CLIENT);
- connection_->SetEncrypter(
- ENCRYPTION_FORWARD_SECURE,
- std::make_unique<NullEncrypter>(connection_->perspective()));
- session_ = std::make_unique<MockQuicSession>(connection_);
- flow_controller_ = std::make_unique<QuicFlowController>(
- session_.get(), stream_id_, /*is_connection_flow_controller*/ false,
- send_window_, receive_window_, kStreamReceiveWindowLimit,
- should_auto_tune_receive_window_, &session_flow_controller_);
- }
-
- protected:
- QuicStreamId stream_id_ = 1234;
- QuicByteCount send_window_ = kInitialSessionFlowControlWindowForTest;
- QuicByteCount receive_window_ = kInitialSessionFlowControlWindowForTest;
- std::unique_ptr<QuicFlowController> flow_controller_;
- MockQuicConnectionHelper helper_;
- MockAlarmFactory alarm_factory_;
- MockQuicConnection* connection_;
- std::unique_ptr<MockQuicSession> session_;
- MockFlowController session_flow_controller_;
- bool should_auto_tune_receive_window_ = false;
-};
-
-TEST_F(QuicFlowControllerTest, SendingBytes) {
- Initialize();
-
- EXPECT_FALSE(flow_controller_->IsBlocked());
- EXPECT_FALSE(flow_controller_->FlowControlViolation());
- EXPECT_EQ(send_window_, flow_controller_->SendWindowSize());
-
- // Send some bytes, but not enough to block.
- flow_controller_->AddBytesSent(send_window_ / 2);
- EXPECT_FALSE(flow_controller_->IsBlocked());
- EXPECT_EQ(send_window_ / 2, flow_controller_->SendWindowSize());
-
- // Send enough bytes to block.
- flow_controller_->AddBytesSent(send_window_ / 2);
- EXPECT_TRUE(flow_controller_->IsBlocked());
- EXPECT_EQ(0u, flow_controller_->SendWindowSize());
-
- // BLOCKED frame should get sent.
- EXPECT_TRUE(flow_controller_->ShouldSendBlocked());
-
- // Update the send window, and verify this has unblocked.
- EXPECT_TRUE(flow_controller_->UpdateSendWindowOffset(2 * send_window_));
- EXPECT_FALSE(flow_controller_->IsBlocked());
- EXPECT_EQ(send_window_, flow_controller_->SendWindowSize());
-
- // Updating with a smaller offset doesn't change anything.
- EXPECT_FALSE(flow_controller_->UpdateSendWindowOffset(send_window_ / 10));
- 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),
- 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) {
- Initialize();
-
- EXPECT_FALSE(flow_controller_->IsBlocked());
- EXPECT_FALSE(flow_controller_->FlowControlViolation());
- EXPECT_EQ(kInitialSessionFlowControlWindowForTest,
- QuicFlowControllerPeer::ReceiveWindowSize(flow_controller_.get()));
-
- // Receive some bytes, updating highest received offset, but not enough to
- // fill flow control receive window.
- EXPECT_TRUE(
- flow_controller_->UpdateHighestReceivedOffset(1 + receive_window_ / 2));
- EXPECT_FALSE(flow_controller_->FlowControlViolation());
- EXPECT_EQ((receive_window_ / 2) - 1,
- QuicFlowControllerPeer::ReceiveWindowSize(flow_controller_.get()));
-
- // Consume enough bytes to send a WINDOW_UPDATE frame.
- EXPECT_CALL(*session_, WriteControlFrame(_, _)).Times(1);
-
- flow_controller_->AddBytesConsumed(1 + receive_window_ / 2);
-
- // Result is that once again we have a fully open receive window.
- EXPECT_FALSE(flow_controller_->FlowControlViolation());
- EXPECT_EQ(kInitialSessionFlowControlWindowForTest,
- QuicFlowControllerPeer::ReceiveWindowSize(flow_controller_.get()));
-}
-
-TEST_F(QuicFlowControllerTest, Move) {
- Initialize();
-
- flow_controller_->AddBytesSent(send_window_ / 2);
- EXPECT_FALSE(flow_controller_->IsBlocked());
- EXPECT_EQ(send_window_ / 2, flow_controller_->SendWindowSize());
-
- EXPECT_TRUE(
- flow_controller_->UpdateHighestReceivedOffset(1 + receive_window_ / 2));
- EXPECT_FALSE(flow_controller_->FlowControlViolation());
- EXPECT_EQ((receive_window_ / 2) - 1,
- QuicFlowControllerPeer::ReceiveWindowSize(flow_controller_.get()));
-
- QuicFlowController flow_controller2(std::move(*flow_controller_));
- EXPECT_EQ(send_window_ / 2, flow_controller2.SendWindowSize());
- EXPECT_FALSE(flow_controller2.FlowControlViolation());
- EXPECT_EQ((receive_window_ / 2) - 1,
- QuicFlowControllerPeer::ReceiveWindowSize(&flow_controller2));
-}
-
-TEST_F(QuicFlowControllerTest, OnlySendBlockedFrameOncePerOffset) {
- Initialize();
-
- // Test that we don't send duplicate BLOCKED frames. We should only send one
- // BLOCKED frame at a given send window offset.
- EXPECT_FALSE(flow_controller_->IsBlocked());
- EXPECT_FALSE(flow_controller_->FlowControlViolation());
- EXPECT_EQ(send_window_, flow_controller_->SendWindowSize());
-
- // Send enough bytes to block.
- flow_controller_->AddBytesSent(send_window_);
- EXPECT_TRUE(flow_controller_->IsBlocked());
- EXPECT_EQ(0u, flow_controller_->SendWindowSize());
-
- // BLOCKED frame should get sent.
- EXPECT_TRUE(flow_controller_->ShouldSendBlocked());
-
- // 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());
-
- // Update the send window, then send enough bytes to block again.
- EXPECT_TRUE(flow_controller_->UpdateSendWindowOffset(2 * send_window_));
- EXPECT_FALSE(flow_controller_->IsBlocked());
- EXPECT_EQ(send_window_, flow_controller_->SendWindowSize());
- flow_controller_->AddBytesSent(send_window_);
- EXPECT_TRUE(flow_controller_->IsBlocked());
- EXPECT_EQ(0u, flow_controller_->SendWindowSize());
-
- // BLOCKED frame should get sent as send offset has changed.
- EXPECT_TRUE(flow_controller_->ShouldSendBlocked());
-}
-
-TEST_F(QuicFlowControllerTest, ReceivingBytesFastIncreasesFlowWindow) {
- should_auto_tune_receive_window_ = true;
- Initialize();
- // This test will generate two WINDOW_UPDATE frames.
- EXPECT_CALL(*session_, WriteControlFrame(_, _)).Times(1);
- EXPECT_TRUE(flow_controller_->auto_tune_receive_window());
-
- // Make sure clock is inititialized.
- connection_->AdvanceTime(QuicTime::Delta::FromMilliseconds(1));
-
- QuicSentPacketManager* manager =
- QuicConnectionPeer::GetSentPacketManager(connection_);
-
- RttStats* rtt_stats = const_cast<RttStats*>(manager->GetRttStats());
- rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(kRtt),
- QuicTime::Delta::Zero(), QuicTime::Zero());
-
- EXPECT_FALSE(flow_controller_->IsBlocked());
- EXPECT_FALSE(flow_controller_->FlowControlViolation());
- EXPECT_EQ(kInitialSessionFlowControlWindowForTest,
- QuicFlowControllerPeer::ReceiveWindowSize(flow_controller_.get()));
-
- QuicByteCount threshold =
- QuicFlowControllerPeer::WindowUpdateThreshold(flow_controller_.get());
-
- QuicStreamOffset receive_offset = threshold + 1;
- // Receive some bytes, updating highest received offset, but not enough to
- // fill flow control receive window.
- EXPECT_TRUE(flow_controller_->UpdateHighestReceivedOffset(receive_offset));
- EXPECT_FALSE(flow_controller_->FlowControlViolation());
- EXPECT_EQ(kInitialSessionFlowControlWindowForTest - receive_offset,
- QuicFlowControllerPeer::ReceiveWindowSize(flow_controller_.get()));
- EXPECT_CALL(
- session_flow_controller_,
- EnsureWindowAtLeast(kInitialSessionFlowControlWindowForTest * 2 * 1.5));
-
- // Consume enough bytes to send a WINDOW_UPDATE frame.
- flow_controller_->AddBytesConsumed(threshold + 1);
- // Result is that once again we have a fully open receive window.
- EXPECT_FALSE(flow_controller_->FlowControlViolation());
- EXPECT_EQ(2 * kInitialSessionFlowControlWindowForTest,
- QuicFlowControllerPeer::ReceiveWindowSize(flow_controller_.get()));
-
- connection_->AdvanceTime(QuicTime::Delta::FromMilliseconds(2 * kRtt - 1));
- receive_offset += threshold + 1;
- EXPECT_TRUE(flow_controller_->UpdateHighestReceivedOffset(receive_offset));
- flow_controller_->AddBytesConsumed(threshold + 1);
- EXPECT_FALSE(flow_controller_->FlowControlViolation());
- QuicByteCount new_threshold =
- QuicFlowControllerPeer::WindowUpdateThreshold(flow_controller_.get());
- EXPECT_GT(new_threshold, threshold);
-}
-
-TEST_F(QuicFlowControllerTest, ReceivingBytesFastNoAutoTune) {
- Initialize();
- // This test will generate two WINDOW_UPDATE frames.
- EXPECT_CALL(*session_, WriteControlFrame(_, _))
- .Times(2)
- .WillRepeatedly(Invoke(&ClearControlFrameWithTransmissionType));
- EXPECT_FALSE(flow_controller_->auto_tune_receive_window());
-
- // Make sure clock is inititialized.
- connection_->AdvanceTime(QuicTime::Delta::FromMilliseconds(1));
-
- QuicSentPacketManager* manager =
- QuicConnectionPeer::GetSentPacketManager(connection_);
-
- RttStats* rtt_stats = const_cast<RttStats*>(manager->GetRttStats());
- rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(kRtt),
- QuicTime::Delta::Zero(), QuicTime::Zero());
-
- EXPECT_FALSE(flow_controller_->IsBlocked());
- EXPECT_FALSE(flow_controller_->FlowControlViolation());
- EXPECT_EQ(kInitialSessionFlowControlWindowForTest,
- QuicFlowControllerPeer::ReceiveWindowSize(flow_controller_.get()));
-
- QuicByteCount threshold =
- QuicFlowControllerPeer::WindowUpdateThreshold(flow_controller_.get());
-
- QuicStreamOffset receive_offset = threshold + 1;
- // Receive some bytes, updating highest received offset, but not enough to
- // fill flow control receive window.
- EXPECT_TRUE(flow_controller_->UpdateHighestReceivedOffset(receive_offset));
- EXPECT_FALSE(flow_controller_->FlowControlViolation());
- EXPECT_EQ(kInitialSessionFlowControlWindowForTest - receive_offset,
- QuicFlowControllerPeer::ReceiveWindowSize(flow_controller_.get()));
-
- // Consume enough bytes to send a WINDOW_UPDATE frame.
- flow_controller_->AddBytesConsumed(threshold + 1);
- // Result is that once again we have a fully open receive window.
- EXPECT_FALSE(flow_controller_->FlowControlViolation());
- EXPECT_EQ(kInitialSessionFlowControlWindowForTest,
- QuicFlowControllerPeer::ReceiveWindowSize(flow_controller_.get()));
-
- // Move time forward, but by less than two RTTs. Then receive and consume
- // some more, forcing a second WINDOW_UPDATE with an increased max window
- // size.
- connection_->AdvanceTime(QuicTime::Delta::FromMilliseconds(2 * kRtt - 1));
- receive_offset += threshold + 1;
- EXPECT_TRUE(flow_controller_->UpdateHighestReceivedOffset(receive_offset));
- flow_controller_->AddBytesConsumed(threshold + 1);
- EXPECT_FALSE(flow_controller_->FlowControlViolation());
- QuicByteCount new_threshold =
- QuicFlowControllerPeer::WindowUpdateThreshold(flow_controller_.get());
- EXPECT_EQ(new_threshold, threshold);
-}
-
-TEST_F(QuicFlowControllerTest, ReceivingBytesNormalStableFlowWindow) {
- should_auto_tune_receive_window_ = true;
- Initialize();
- // This test will generate two WINDOW_UPDATE frames.
- EXPECT_CALL(*session_, WriteControlFrame(_, _)).Times(1);
- EXPECT_TRUE(flow_controller_->auto_tune_receive_window());
-
- // Make sure clock is inititialized.
- connection_->AdvanceTime(QuicTime::Delta::FromMilliseconds(1));
-
- QuicSentPacketManager* manager =
- QuicConnectionPeer::GetSentPacketManager(connection_);
- RttStats* rtt_stats = const_cast<RttStats*>(manager->GetRttStats());
- rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(kRtt),
- QuicTime::Delta::Zero(), QuicTime::Zero());
-
- EXPECT_FALSE(flow_controller_->IsBlocked());
- EXPECT_FALSE(flow_controller_->FlowControlViolation());
- EXPECT_EQ(kInitialSessionFlowControlWindowForTest,
- QuicFlowControllerPeer::ReceiveWindowSize(flow_controller_.get()));
-
- QuicByteCount threshold =
- QuicFlowControllerPeer::WindowUpdateThreshold(flow_controller_.get());
-
- QuicStreamOffset receive_offset = threshold + 1;
- // Receive some bytes, updating highest received offset, but not enough to
- // fill flow control receive window.
- EXPECT_TRUE(flow_controller_->UpdateHighestReceivedOffset(receive_offset));
- EXPECT_FALSE(flow_controller_->FlowControlViolation());
- EXPECT_EQ(kInitialSessionFlowControlWindowForTest - receive_offset,
- QuicFlowControllerPeer::ReceiveWindowSize(flow_controller_.get()));
- EXPECT_CALL(
- session_flow_controller_,
- EnsureWindowAtLeast(kInitialSessionFlowControlWindowForTest * 2 * 1.5));
- flow_controller_->AddBytesConsumed(threshold + 1);
-
- // Result is that once again we have a fully open receive window.
- EXPECT_FALSE(flow_controller_->FlowControlViolation());
- EXPECT_EQ(2 * kInitialSessionFlowControlWindowForTest,
- QuicFlowControllerPeer::ReceiveWindowSize(flow_controller_.get()));
-
- // Move time forward, but by more than two RTTs. Then receive and consume
- // some more, forcing a second WINDOW_UPDATE with unchanged max window size.
- connection_->AdvanceTime(QuicTime::Delta::FromMilliseconds(2 * kRtt + 1));
-
- receive_offset += threshold + 1;
- EXPECT_TRUE(flow_controller_->UpdateHighestReceivedOffset(receive_offset));
-
- flow_controller_->AddBytesConsumed(threshold + 1);
- EXPECT_FALSE(flow_controller_->FlowControlViolation());
-
- QuicByteCount new_threshold =
- QuicFlowControllerPeer::WindowUpdateThreshold(flow_controller_.get());
- EXPECT_EQ(new_threshold, 2 * threshold);
-}
-
-TEST_F(QuicFlowControllerTest, ReceivingBytesNormalNoAutoTune) {
- Initialize();
- // This test will generate two WINDOW_UPDATE frames.
- EXPECT_CALL(*session_, WriteControlFrame(_, _))
- .Times(2)
- .WillRepeatedly(Invoke(&ClearControlFrameWithTransmissionType));
- EXPECT_FALSE(flow_controller_->auto_tune_receive_window());
-
- // Make sure clock is inititialized.
- connection_->AdvanceTime(QuicTime::Delta::FromMilliseconds(1));
-
- QuicSentPacketManager* manager =
- QuicConnectionPeer::GetSentPacketManager(connection_);
- RttStats* rtt_stats = const_cast<RttStats*>(manager->GetRttStats());
- rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(kRtt),
- QuicTime::Delta::Zero(), QuicTime::Zero());
-
- EXPECT_FALSE(flow_controller_->IsBlocked());
- EXPECT_FALSE(flow_controller_->FlowControlViolation());
- EXPECT_EQ(kInitialSessionFlowControlWindowForTest,
- QuicFlowControllerPeer::ReceiveWindowSize(flow_controller_.get()));
-
- QuicByteCount threshold =
- QuicFlowControllerPeer::WindowUpdateThreshold(flow_controller_.get());
-
- QuicStreamOffset receive_offset = threshold + 1;
- // Receive some bytes, updating highest received offset, but not enough to
- // fill flow control receive window.
- EXPECT_TRUE(flow_controller_->UpdateHighestReceivedOffset(receive_offset));
- EXPECT_FALSE(flow_controller_->FlowControlViolation());
- EXPECT_EQ(kInitialSessionFlowControlWindowForTest - receive_offset,
- QuicFlowControllerPeer::ReceiveWindowSize(flow_controller_.get()));
-
- flow_controller_->AddBytesConsumed(threshold + 1);
-
- // Result is that once again we have a fully open receive window.
- EXPECT_FALSE(flow_controller_->FlowControlViolation());
- EXPECT_EQ(kInitialSessionFlowControlWindowForTest,
- QuicFlowControllerPeer::ReceiveWindowSize(flow_controller_.get()));
-
- // Move time forward, but by more than two RTTs. Then receive and consume
- // some more, forcing a second WINDOW_UPDATE with unchanged max window size.
- connection_->AdvanceTime(QuicTime::Delta::FromMilliseconds(2 * kRtt + 1));
-
- receive_offset += threshold + 1;
- EXPECT_TRUE(flow_controller_->UpdateHighestReceivedOffset(receive_offset));
-
- flow_controller_->AddBytesConsumed(threshold + 1);
- EXPECT_FALSE(flow_controller_->FlowControlViolation());
-
- QuicByteCount new_threshold =
- QuicFlowControllerPeer::WindowUpdateThreshold(flow_controller_.get());
-
- EXPECT_EQ(new_threshold, threshold);
-}
-
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_framer.cc b/chromium/net/third_party/quiche/src/quic/core/quic_framer.cc
deleted file mode 100644
index da28e4c5b5c..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_framer.cc
+++ /dev/null
@@ -1,7243 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_framer.h"
-
-#include <cstddef>
-#include <cstdint>
-#include <limits>
-#include <memory>
-#include <string>
-#include <utility>
-
-#include "absl/base/attributes.h"
-#include "absl/base/macros.h"
-#include "absl/base/optimization.h"
-#include "absl/strings/escaping.h"
-#include "absl/strings/numbers.h"
-#include "absl/strings/str_cat.h"
-#include "absl/strings/str_split.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/crypto/crypto_framer.h"
-#include "quic/core/crypto/crypto_handshake.h"
-#include "quic/core/crypto/crypto_handshake_message.h"
-#include "quic/core/crypto/crypto_protocol.h"
-#include "quic/core/crypto/crypto_utils.h"
-#include "quic/core/crypto/null_decrypter.h"
-#include "quic/core/crypto/null_encrypter.h"
-#include "quic/core/crypto/quic_decrypter.h"
-#include "quic/core/crypto/quic_encrypter.h"
-#include "quic/core/crypto/quic_random.h"
-#include "quic/core/frames/quic_ack_frequency_frame.h"
-#include "quic/core/quic_connection_id.h"
-#include "quic/core/quic_constants.h"
-#include "quic/core/quic_data_reader.h"
-#include "quic/core/quic_data_writer.h"
-#include "quic/core/quic_error_codes.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_socket_address_coder.h"
-#include "quic/core/quic_stream_frame_data_producer.h"
-#include "quic/core/quic_time.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_utils.h"
-#include "quic/core/quic_versions.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_client_stats.h"
-#include "quic/platform/api/quic_flag_utils.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/platform/api/quic_stack_trace.h"
-#include "common/quiche_text_utils.h"
-
-namespace quic {
-
-namespace {
-
-#define ENDPOINT \
- (perspective_ == Perspective::IS_SERVER ? "Server: " : "Client: ")
-
-// Number of bits the packet number length bits are shifted from the right
-// edge of the header.
-const uint8_t kPublicHeaderSequenceNumberShift = 4;
-
-// There are two interpretations for the Frame Type byte in the QUIC protocol,
-// resulting in two Frame Types: Special Frame Types and Regular Frame Types.
-//
-// Regular Frame Types use the Frame Type byte simply. Currently defined
-// Regular Frame Types are:
-// Padding : 0b 00000000 (0x00)
-// ResetStream : 0b 00000001 (0x01)
-// ConnectionClose : 0b 00000010 (0x02)
-// GoAway : 0b 00000011 (0x03)
-// WindowUpdate : 0b 00000100 (0x04)
-// Blocked : 0b 00000101 (0x05)
-//
-// Special Frame Types encode both a Frame Type and corresponding flags
-// all in the Frame Type byte. Currently defined Special Frame Types
-// are:
-// Stream : 0b 1xxxxxxx
-// Ack : 0b 01xxxxxx
-//
-// Semantics of the flag bits above (the x bits) depends on the frame type.
-
-// Masks to determine if the frame type is a special use
-// and for specific special frame types.
-const uint8_t kQuicFrameTypeBrokenMask = 0xE0; // 0b 11100000
-const uint8_t kQuicFrameTypeSpecialMask = 0xC0; // 0b 11000000
-const uint8_t kQuicFrameTypeStreamMask = 0x80;
-const uint8_t kQuicFrameTypeAckMask = 0x40;
-static_assert(kQuicFrameTypeSpecialMask ==
- (kQuicFrameTypeStreamMask | kQuicFrameTypeAckMask),
- "Invalid kQuicFrameTypeSpecialMask");
-
-// The stream type format is 1FDOOOSS, where
-// F is the fin bit.
-// D is the data length bit (0 or 2 bytes).
-// OO/OOO are the size of the offset.
-// SS is the size of the stream ID.
-// Note that the stream encoding can not be determined by inspection. It can
-// be determined only by knowing the QUIC Version.
-// Stream frame relative shifts and masks for interpreting the stream flags.
-// StreamID may be 1, 2, 3, or 4 bytes.
-const uint8_t kQuicStreamIdShift = 2;
-const uint8_t kQuicStreamIDLengthMask = 0x03;
-
-// Offset may be 0, 2, 4, or 8 bytes.
-const uint8_t kQuicStreamShift = 3;
-const uint8_t kQuicStreamOffsetMask = 0x07;
-
-// Data length may be 0 or 2 bytes.
-const uint8_t kQuicStreamDataLengthShift = 1;
-const uint8_t kQuicStreamDataLengthMask = 0x01;
-
-// Fin bit may be set or not.
-const uint8_t kQuicStreamFinShift = 1;
-const uint8_t kQuicStreamFinMask = 0x01;
-
-// The format is 01M0LLOO, where
-// M if set, there are multiple ack blocks in the frame.
-// LL is the size of the largest ack field.
-// OO is the size of the ack blocks offset field.
-// packet number size shift used in AckFrames.
-const uint8_t kQuicSequenceNumberLengthNumBits = 2;
-const uint8_t kActBlockLengthOffset = 0;
-const uint8_t kLargestAckedOffset = 2;
-
-// Acks may have only one ack block.
-const uint8_t kQuicHasMultipleAckBlocksOffset = 5;
-
-// Timestamps are 4 bytes followed by 2 bytes.
-const uint8_t kQuicNumTimestampsLength = 1;
-const uint8_t kQuicFirstTimestampLength = 4;
-const uint8_t kQuicTimestampLength = 2;
-// Gaps between packet numbers are 1 byte.
-const uint8_t kQuicTimestampPacketNumberGapLength = 1;
-
-// Maximum length of encoded error strings.
-const int kMaxErrorStringLength = 256;
-
-const uint8_t kConnectionIdLengthAdjustment = 3;
-const uint8_t kDestinationConnectionIdLengthMask = 0xF0;
-const uint8_t kSourceConnectionIdLengthMask = 0x0F;
-
-// Returns the absolute value of the difference between |a| and |b|.
-uint64_t Delta(uint64_t a, uint64_t b) {
- // Since these are unsigned numbers, we can't just return abs(a - b)
- if (a < b) {
- return b - a;
- }
- return a - b;
-}
-
-uint64_t ClosestTo(uint64_t target, uint64_t a, uint64_t b) {
- return (Delta(target, a) < Delta(target, b)) ? a : b;
-}
-
-QuicPacketNumberLength ReadSequenceNumberLength(uint8_t flags) {
- switch (flags & PACKET_FLAGS_8BYTE_PACKET) {
- case PACKET_FLAGS_8BYTE_PACKET:
- return PACKET_6BYTE_PACKET_NUMBER;
- case PACKET_FLAGS_4BYTE_PACKET:
- return PACKET_4BYTE_PACKET_NUMBER;
- case PACKET_FLAGS_2BYTE_PACKET:
- return PACKET_2BYTE_PACKET_NUMBER;
- case PACKET_FLAGS_1BYTE_PACKET:
- return PACKET_1BYTE_PACKET_NUMBER;
- default:
- QUIC_BUG(quic_bug_10850_1) << "Unreachable case statement.";
- return PACKET_6BYTE_PACKET_NUMBER;
- }
-}
-
-QuicPacketNumberLength ReadAckPacketNumberLength(uint8_t flags) {
- switch (flags & PACKET_FLAGS_8BYTE_PACKET) {
- case PACKET_FLAGS_8BYTE_PACKET:
- return PACKET_6BYTE_PACKET_NUMBER;
- case PACKET_FLAGS_4BYTE_PACKET:
- return PACKET_4BYTE_PACKET_NUMBER;
- case PACKET_FLAGS_2BYTE_PACKET:
- return PACKET_2BYTE_PACKET_NUMBER;
- case PACKET_FLAGS_1BYTE_PACKET:
- return PACKET_1BYTE_PACKET_NUMBER;
- default:
- QUIC_BUG(quic_bug_10850_2) << "Unreachable case statement.";
- return PACKET_6BYTE_PACKET_NUMBER;
- }
-}
-
-uint8_t PacketNumberLengthToOnWireValue(
- QuicPacketNumberLength packet_number_length) {
- return packet_number_length - 1;
-}
-
-QuicPacketNumberLength GetShortHeaderPacketNumberLength(uint8_t type) {
- QUICHE_DCHECK(!(type & FLAGS_LONG_HEADER));
- return static_cast<QuicPacketNumberLength>((type & 0x03) + 1);
-}
-
-uint8_t LongHeaderTypeToOnWireValue(QuicLongHeaderType type,
- const ParsedQuicVersion& version) {
- switch (type) {
- case INITIAL:
- return version.UsesV2PacketTypes() ? (1 << 4) : 0;
- case ZERO_RTT_PROTECTED:
- return version.UsesV2PacketTypes() ? (2 << 4) : (1 << 4);
- case HANDSHAKE:
- return version.UsesV2PacketTypes() ? (3 << 4) : (2 << 4);
- case RETRY:
- return version.UsesV2PacketTypes() ? 0 : (3 << 4);
- case VERSION_NEGOTIATION:
- return 0xF0; // Value does not matter
- default:
- QUIC_BUG(quic_bug_10850_3) << "Invalid long header type: " << type;
- return 0xFF;
- }
-}
-
-QuicLongHeaderType GetLongHeaderType(uint8_t type,
- const ParsedQuicVersion& version) {
- QUICHE_DCHECK((type & FLAGS_LONG_HEADER));
- switch ((type & 0x30) >> 4) {
- case 0:
- return version.UsesV2PacketTypes() ? RETRY : INITIAL;
- case 1:
- return version.UsesV2PacketTypes() ? INITIAL : ZERO_RTT_PROTECTED;
- case 2:
- return version.UsesV2PacketTypes() ? ZERO_RTT_PROTECTED : HANDSHAKE;
- case 3:
- return version.UsesV2PacketTypes() ? HANDSHAKE : RETRY;
- default:
- QUIC_BUG(quic_bug_10850_4) << "Unreachable statement";
- return INVALID_PACKET_TYPE;
- }
-}
-
-QuicPacketNumberLength GetLongHeaderPacketNumberLength(uint8_t type) {
- return static_cast<QuicPacketNumberLength>((type & 0x03) + 1);
-}
-
-// Used to get packet number space before packet gets decrypted.
-PacketNumberSpace GetPacketNumberSpace(const QuicPacketHeader& header) {
- switch (header.form) {
- case GOOGLE_QUIC_PACKET:
- QUIC_BUG(quic_bug_10850_5)
- << "Try to get packet number space of Google QUIC packet";
- break;
- case IETF_QUIC_SHORT_HEADER_PACKET:
- return APPLICATION_DATA;
- case IETF_QUIC_LONG_HEADER_PACKET:
- switch (header.long_packet_type) {
- case INITIAL:
- return INITIAL_DATA;
- case HANDSHAKE:
- return HANDSHAKE_DATA;
- case ZERO_RTT_PROTECTED:
- return APPLICATION_DATA;
- case VERSION_NEGOTIATION:
- case RETRY:
- case INVALID_PACKET_TYPE:
- QUIC_BUG(quic_bug_10850_6)
- << "Try to get packet number space of long header type: "
- << QuicUtils::QuicLongHeaderTypetoString(header.long_packet_type);
- break;
- }
- }
-
- return NUM_PACKET_NUMBER_SPACES;
-}
-
-EncryptionLevel GetEncryptionLevel(const QuicPacketHeader& header) {
- switch (header.form) {
- case GOOGLE_QUIC_PACKET:
- QUIC_BUG(quic_bug_10850_7)
- << "Cannot determine EncryptionLevel from Google QUIC header";
- break;
- case IETF_QUIC_SHORT_HEADER_PACKET:
- return ENCRYPTION_FORWARD_SECURE;
- case IETF_QUIC_LONG_HEADER_PACKET:
- switch (header.long_packet_type) {
- case INITIAL:
- return ENCRYPTION_INITIAL;
- case HANDSHAKE:
- return ENCRYPTION_HANDSHAKE;
- case ZERO_RTT_PROTECTED:
- return ENCRYPTION_ZERO_RTT;
- case VERSION_NEGOTIATION:
- case RETRY:
- case INVALID_PACKET_TYPE:
- QUIC_BUG(quic_bug_10850_8)
- << "No encryption used with type "
- << QuicUtils::QuicLongHeaderTypetoString(header.long_packet_type);
- }
- }
- return NUM_ENCRYPTION_LEVELS;
-}
-
-absl::string_view TruncateErrorString(absl::string_view error) {
- if (error.length() <= kMaxErrorStringLength) {
- return error;
- }
- return absl::string_view(error.data(), kMaxErrorStringLength);
-}
-
-size_t TruncatedErrorStringSize(const absl::string_view& error) {
- if (error.length() < kMaxErrorStringLength) {
- return error.length();
- }
- return kMaxErrorStringLength;
-}
-
-uint8_t GetConnectionIdLengthValue(QuicConnectionIdLength length) {
- if (length == 0) {
- return 0;
- }
- return static_cast<uint8_t>(length - kConnectionIdLengthAdjustment);
-}
-
-bool IsValidPacketNumberLength(QuicPacketNumberLength packet_number_length) {
- size_t length = packet_number_length;
- return length == 1 || length == 2 || length == 4 || length == 6 ||
- length == 8;
-}
-
-bool IsValidFullPacketNumber(uint64_t full_packet_number,
- ParsedQuicVersion version) {
- return full_packet_number > 0 || version.HasIetfQuicFrames();
-}
-
-bool AppendIetfConnectionIds(bool version_flag, bool use_length_prefix,
- QuicConnectionId destination_connection_id,
- QuicConnectionId source_connection_id,
- QuicDataWriter* writer) {
- if (!version_flag) {
- return writer->WriteConnectionId(destination_connection_id);
- }
-
- if (use_length_prefix) {
- return writer->WriteLengthPrefixedConnectionId(destination_connection_id) &&
- writer->WriteLengthPrefixedConnectionId(source_connection_id);
- }
-
- // Compute connection ID length byte.
- uint8_t dcil = GetConnectionIdLengthValue(
- static_cast<QuicConnectionIdLength>(destination_connection_id.length()));
- uint8_t scil = GetConnectionIdLengthValue(
- static_cast<QuicConnectionIdLength>(source_connection_id.length()));
- uint8_t connection_id_length = dcil << 4 | scil;
-
- return writer->WriteUInt8(connection_id_length) &&
- writer->WriteConnectionId(destination_connection_id) &&
- writer->WriteConnectionId(source_connection_id);
-}
-
-enum class DroppedPacketReason {
- // General errors
- INVALID_PUBLIC_HEADER,
- VERSION_MISMATCH,
- // Version negotiation packet errors
- INVALID_VERSION_NEGOTIATION_PACKET,
- // Public reset packet errors, pre-v44
- INVALID_PUBLIC_RESET_PACKET,
- // Data packet errors
- INVALID_PACKET_NUMBER,
- INVALID_DIVERSIFICATION_NONCE,
- DECRYPTION_FAILURE,
- NUM_REASONS,
-};
-
-void RecordDroppedPacketReason(DroppedPacketReason reason) {
- QUIC_CLIENT_HISTOGRAM_ENUM("QuicDroppedPacketReason", reason,
- DroppedPacketReason::NUM_REASONS,
- "The reason a packet was not processed. Recorded "
- "each time such a packet is dropped");
-}
-
-PacketHeaderFormat GetIetfPacketHeaderFormat(uint8_t type_byte) {
- return type_byte & FLAGS_LONG_HEADER ? IETF_QUIC_LONG_HEADER_PACKET
- : IETF_QUIC_SHORT_HEADER_PACKET;
-}
-
-std::string GenerateErrorString(std::string initial_error_string,
- QuicErrorCode quic_error_code) {
- if (quic_error_code == QUIC_IETF_GQUIC_ERROR_MISSING) {
- // QUIC_IETF_GQUIC_ERROR_MISSING is special -- it means not to encode
- // the error value in the string.
- return initial_error_string;
- }
- return absl::StrCat(std::to_string(static_cast<unsigned>(quic_error_code)),
- ":", initial_error_string);
-}
-
-} // namespace
-
-QuicFramer::QuicFramer(const ParsedQuicVersionVector& supported_versions,
- QuicTime creation_time, Perspective perspective,
- uint8_t expected_server_connection_id_length)
- : visitor_(nullptr),
- error_(QUIC_NO_ERROR),
- last_serialized_server_connection_id_(EmptyQuicConnectionId()),
- last_serialized_client_connection_id_(EmptyQuicConnectionId()),
- version_(ParsedQuicVersion::Unsupported()),
- supported_versions_(supported_versions),
- decrypter_level_(ENCRYPTION_INITIAL),
- alternative_decrypter_level_(NUM_ENCRYPTION_LEVELS),
- alternative_decrypter_latch_(false),
- perspective_(perspective),
- validate_flags_(true),
- process_timestamps_(false),
- max_receive_timestamps_per_ack_(std::numeric_limits<uint32_t>::max()),
- receive_timestamps_exponent_(0),
- creation_time_(creation_time),
- last_timestamp_(QuicTime::Delta::Zero()),
- support_key_update_for_connection_(false),
- current_key_phase_bit_(false),
- potential_peer_key_update_attempt_count_(0),
- first_sending_packet_number_(FirstSendingPacketNumber()),
- data_producer_(nullptr),
- infer_packet_header_type_from_version_(perspective ==
- Perspective::IS_CLIENT),
- expected_server_connection_id_length_(
- expected_server_connection_id_length),
- expected_client_connection_id_length_(0),
- supports_multiple_packet_number_spaces_(false),
- last_written_packet_number_length_(0),
- peer_ack_delay_exponent_(kDefaultAckDelayExponent),
- local_ack_delay_exponent_(kDefaultAckDelayExponent),
- current_received_frame_type_(0),
- previously_received_frame_type_(0) {
- QUICHE_DCHECK(!supported_versions.empty());
- version_ = supported_versions_[0];
- QUICHE_DCHECK(version_.IsKnown())
- << ParsedQuicVersionVectorToString(supported_versions_);
-}
-
-QuicFramer::~QuicFramer() {}
-
-// static
-size_t QuicFramer::GetMinStreamFrameSize(QuicTransportVersion version,
- QuicStreamId stream_id,
- QuicStreamOffset offset,
- bool last_frame_in_packet,
- size_t data_length) {
- if (VersionHasIetfQuicFrames(version)) {
- return kQuicFrameTypeSize + QuicDataWriter::GetVarInt62Len(stream_id) +
- (last_frame_in_packet
- ? 0
- : QuicDataWriter::GetVarInt62Len(data_length)) +
- (offset != 0 ? QuicDataWriter::GetVarInt62Len(offset) : 0);
- }
- return kQuicFrameTypeSize + GetStreamIdSize(stream_id) +
- GetStreamOffsetSize(offset) +
- (last_frame_in_packet ? 0 : kQuicStreamPayloadLengthSize);
-}
-
-// static
-size_t QuicFramer::GetMinCryptoFrameSize(QuicStreamOffset offset,
- QuicPacketLength data_length) {
- return kQuicFrameTypeSize + QuicDataWriter::GetVarInt62Len(offset) +
- QuicDataWriter::GetVarInt62Len(data_length);
-}
-
-// static
-size_t QuicFramer::GetMessageFrameSize(QuicTransportVersion version,
- bool last_frame_in_packet,
- QuicByteCount length) {
- QUIC_BUG_IF(quic_bug_12975_1, !VersionSupportsMessageFrames(version))
- << "Try to serialize MESSAGE frame in " << version;
- return kQuicFrameTypeSize +
- (last_frame_in_packet ? 0 : QuicDataWriter::GetVarInt62Len(length)) +
- length;
-}
-
-// static
-size_t QuicFramer::GetMinAckFrameSize(
- QuicTransportVersion version, const QuicAckFrame& ack_frame,
- uint32_t local_ack_delay_exponent,
- bool use_ietf_ack_with_receive_timestamp) {
- if (VersionHasIetfQuicFrames(version)) {
- // The minimal ack frame consists of the following fields: Largest
- // Acknowledged, ACK Delay, 0 ACK Block Count, First ACK Block and either 0
- // Timestamp Range Count or ECN counts.
- // Type byte + largest acked.
- size_t min_size =
- kQuicFrameTypeSize +
- QuicDataWriter::GetVarInt62Len(LargestAcked(ack_frame).ToUint64());
- // Ack delay.
- min_size += QuicDataWriter::GetVarInt62Len(
- ack_frame.ack_delay_time.ToMicroseconds() >> local_ack_delay_exponent);
- // 0 ack block count.
- min_size += QuicDataWriter::GetVarInt62Len(0);
- // First ack block.
- min_size += QuicDataWriter::GetVarInt62Len(
- ack_frame.packets.Empty() ? 0
- : ack_frame.packets.rbegin()->Length() - 1);
-
- if (use_ietf_ack_with_receive_timestamp) {
- // 0 Timestamp Range Count.
- min_size += QuicDataWriter::GetVarInt62Len(0);
- } else if (ack_frame.ecn_counters_populated &&
- (ack_frame.ect_0_count || ack_frame.ect_1_count ||
- ack_frame.ecn_ce_count)) {
- // ECN counts.
- min_size += (QuicDataWriter::GetVarInt62Len(ack_frame.ect_0_count) +
- QuicDataWriter::GetVarInt62Len(ack_frame.ect_1_count) +
- QuicDataWriter::GetVarInt62Len(ack_frame.ecn_ce_count));
- }
- return min_size;
- }
- return kQuicFrameTypeSize +
- GetMinPacketNumberLength(LargestAcked(ack_frame)) +
- kQuicDeltaTimeLargestObservedSize + kQuicNumTimestampsSize;
-}
-
-// static
-size_t QuicFramer::GetStopWaitingFrameSize(
- QuicPacketNumberLength packet_number_length) {
- size_t min_size = kQuicFrameTypeSize + packet_number_length;
- return min_size;
-}
-
-// static
-size_t QuicFramer::GetRstStreamFrameSize(QuicTransportVersion version,
- const QuicRstStreamFrame& frame) {
- if (VersionHasIetfQuicFrames(version)) {
- return QuicDataWriter::GetVarInt62Len(frame.stream_id) +
- QuicDataWriter::GetVarInt62Len(frame.byte_offset) +
- kQuicFrameTypeSize +
- QuicDataWriter::GetVarInt62Len(frame.ietf_error_code);
- }
- return kQuicFrameTypeSize + kQuicMaxStreamIdSize + kQuicMaxStreamOffsetSize +
- kQuicErrorCodeSize;
-}
-
-// static
-size_t QuicFramer::GetConnectionCloseFrameSize(
- QuicTransportVersion version, const QuicConnectionCloseFrame& frame) {
- if (!VersionHasIetfQuicFrames(version)) {
- // Not IETF QUIC, return Google QUIC CONNECTION CLOSE frame size.
- return kQuicFrameTypeSize + kQuicErrorCodeSize +
- kQuicErrorDetailsLengthSize +
- TruncatedErrorStringSize(frame.error_details);
- }
-
- // Prepend the extra error information to the string and get the result's
- // length.
- const size_t truncated_error_string_size = TruncatedErrorStringSize(
- GenerateErrorString(frame.error_details, frame.quic_error_code));
-
- const size_t frame_size =
- truncated_error_string_size +
- QuicDataWriter::GetVarInt62Len(truncated_error_string_size) +
- kQuicFrameTypeSize +
- QuicDataWriter::GetVarInt62Len(frame.wire_error_code);
- if (frame.close_type == IETF_QUIC_APPLICATION_CONNECTION_CLOSE) {
- return frame_size;
- }
- // The Transport close frame has the transport_close_frame_type, so include
- // its length.
- return frame_size +
- QuicDataWriter::GetVarInt62Len(frame.transport_close_frame_type);
-}
-
-// static
-size_t QuicFramer::GetMinGoAwayFrameSize() {
- return kQuicFrameTypeSize + kQuicErrorCodeSize + kQuicErrorDetailsLengthSize +
- kQuicMaxStreamIdSize;
-}
-
-// static
-size_t QuicFramer::GetWindowUpdateFrameSize(
- QuicTransportVersion version, const QuicWindowUpdateFrame& frame) {
- if (!VersionHasIetfQuicFrames(version)) {
- return kQuicFrameTypeSize + kQuicMaxStreamIdSize + kQuicMaxStreamOffsetSize;
- }
- if (frame.stream_id == QuicUtils::GetInvalidStreamId(version)) {
- // Frame would be a MAX DATA frame, which has only a Maximum Data field.
- return kQuicFrameTypeSize + QuicDataWriter::GetVarInt62Len(frame.max_data);
- }
- // Frame would be MAX STREAM DATA, has Maximum Stream Data and Stream ID
- // fields.
- return kQuicFrameTypeSize + QuicDataWriter::GetVarInt62Len(frame.max_data) +
- QuicDataWriter::GetVarInt62Len(frame.stream_id);
-}
-
-// static
-size_t QuicFramer::GetMaxStreamsFrameSize(QuicTransportVersion version,
- const QuicMaxStreamsFrame& frame) {
- if (!VersionHasIetfQuicFrames(version)) {
- QUIC_BUG(quic_bug_10850_9)
- << "In version " << version
- << ", which does not support IETF Frames, and tried to serialize "
- "MaxStreams Frame.";
- }
- return kQuicFrameTypeSize +
- QuicDataWriter::GetVarInt62Len(frame.stream_count);
-}
-
-// static
-size_t QuicFramer::GetStreamsBlockedFrameSize(
- QuicTransportVersion version, const QuicStreamsBlockedFrame& frame) {
- if (!VersionHasIetfQuicFrames(version)) {
- QUIC_BUG(quic_bug_10850_10)
- << "In version " << version
- << ", which does not support IETF frames, and tried to serialize "
- "StreamsBlocked Frame.";
- }
-
- return kQuicFrameTypeSize +
- QuicDataWriter::GetVarInt62Len(frame.stream_count);
-}
-
-// static
-size_t QuicFramer::GetBlockedFrameSize(QuicTransportVersion version,
- const QuicBlockedFrame& frame) {
- if (!VersionHasIetfQuicFrames(version)) {
- return kQuicFrameTypeSize + kQuicMaxStreamIdSize;
- }
- if (frame.stream_id == QuicUtils::GetInvalidStreamId(version)) {
- // return size of IETF QUIC Blocked frame
- return kQuicFrameTypeSize + QuicDataWriter::GetVarInt62Len(frame.offset);
- }
- // return size of IETF QUIC Stream Blocked frame.
- return kQuicFrameTypeSize + QuicDataWriter::GetVarInt62Len(frame.offset) +
- QuicDataWriter::GetVarInt62Len(frame.stream_id);
-}
-
-// static
-size_t QuicFramer::GetStopSendingFrameSize(const QuicStopSendingFrame& frame) {
- return kQuicFrameTypeSize + QuicDataWriter::GetVarInt62Len(frame.stream_id) +
- QuicDataWriter::GetVarInt62Len(frame.ietf_error_code);
-}
-
-// static
-size_t QuicFramer::GetAckFrequencyFrameSize(
- const QuicAckFrequencyFrame& frame) {
- return QuicDataWriter::GetVarInt62Len(IETF_ACK_FREQUENCY) +
- QuicDataWriter::GetVarInt62Len(frame.sequence_number) +
- QuicDataWriter::GetVarInt62Len(frame.packet_tolerance) +
- QuicDataWriter::GetVarInt62Len(frame.max_ack_delay.ToMicroseconds()) +
- // One byte for encoding boolean
- 1;
-}
-
-// static
-size_t QuicFramer::GetPathChallengeFrameSize(
- const QuicPathChallengeFrame& frame) {
- return kQuicFrameTypeSize + sizeof(frame.data_buffer);
-}
-
-// static
-size_t QuicFramer::GetPathResponseFrameSize(
- const QuicPathResponseFrame& frame) {
- return kQuicFrameTypeSize + sizeof(frame.data_buffer);
-}
-
-// static
-size_t QuicFramer::GetRetransmittableControlFrameSize(
- QuicTransportVersion version, const QuicFrame& frame) {
- switch (frame.type) {
- case PING_FRAME:
- // Ping has no payload.
- return kQuicFrameTypeSize;
- case RST_STREAM_FRAME:
- return GetRstStreamFrameSize(version, *frame.rst_stream_frame);
- case CONNECTION_CLOSE_FRAME:
- return GetConnectionCloseFrameSize(version,
- *frame.connection_close_frame);
- case GOAWAY_FRAME:
- return GetMinGoAwayFrameSize() +
- TruncatedErrorStringSize(frame.goaway_frame->reason_phrase);
- case WINDOW_UPDATE_FRAME:
- // For IETF QUIC, this could be either a MAX DATA or MAX STREAM DATA.
- // GetWindowUpdateFrameSize figures this out and returns the correct
- // length.
- return GetWindowUpdateFrameSize(version, *frame.window_update_frame);
- case BLOCKED_FRAME:
- return GetBlockedFrameSize(version, *frame.blocked_frame);
- case NEW_CONNECTION_ID_FRAME:
- return GetNewConnectionIdFrameSize(*frame.new_connection_id_frame);
- case RETIRE_CONNECTION_ID_FRAME:
- return GetRetireConnectionIdFrameSize(*frame.retire_connection_id_frame);
- case NEW_TOKEN_FRAME:
- return GetNewTokenFrameSize(*frame.new_token_frame);
- case MAX_STREAMS_FRAME:
- return GetMaxStreamsFrameSize(version, frame.max_streams_frame);
- case STREAMS_BLOCKED_FRAME:
- return GetStreamsBlockedFrameSize(version, frame.streams_blocked_frame);
- case PATH_RESPONSE_FRAME:
- return GetPathResponseFrameSize(*frame.path_response_frame);
- case PATH_CHALLENGE_FRAME:
- return GetPathChallengeFrameSize(*frame.path_challenge_frame);
- case STOP_SENDING_FRAME:
- return GetStopSendingFrameSize(*frame.stop_sending_frame);
- case HANDSHAKE_DONE_FRAME:
- // HANDSHAKE_DONE has no payload.
- return kQuicFrameTypeSize;
- case ACK_FREQUENCY_FRAME:
- return GetAckFrequencyFrameSize(*frame.ack_frequency_frame);
- case STREAM_FRAME:
- case ACK_FRAME:
- case STOP_WAITING_FRAME:
- case MTU_DISCOVERY_FRAME:
- case PADDING_FRAME:
- case MESSAGE_FRAME:
- case CRYPTO_FRAME:
- case NUM_FRAME_TYPES:
- QUICHE_DCHECK(false);
- return 0;
- }
-
- // Not reachable, but some Chrome compilers can't figure that out. *sigh*
- QUICHE_DCHECK(false);
- return 0;
-}
-
-// static
-size_t QuicFramer::GetStreamIdSize(QuicStreamId stream_id) {
- // Sizes are 1 through 4 bytes.
- for (int i = 1; i <= 4; ++i) {
- stream_id >>= 8;
- if (stream_id == 0) {
- return i;
- }
- }
- QUIC_BUG(quic_bug_10850_11) << "Failed to determine StreamIDSize.";
- return 4;
-}
-
-// static
-size_t QuicFramer::GetStreamOffsetSize(QuicStreamOffset offset) {
- // 0 is a special case.
- if (offset == 0) {
- return 0;
- }
- // 2 through 8 are the remaining sizes.
- offset >>= 8;
- for (int i = 2; i <= 8; ++i) {
- offset >>= 8;
- if (offset == 0) {
- return i;
- }
- }
- QUIC_BUG(quic_bug_10850_12) << "Failed to determine StreamOffsetSize.";
- return 8;
-}
-
-// static
-size_t QuicFramer::GetNewConnectionIdFrameSize(
- const QuicNewConnectionIdFrame& frame) {
- return kQuicFrameTypeSize +
- QuicDataWriter::GetVarInt62Len(frame.sequence_number) +
- QuicDataWriter::GetVarInt62Len(frame.retire_prior_to) +
- kConnectionIdLengthSize + frame.connection_id.length() +
- sizeof(frame.stateless_reset_token);
-}
-
-// static
-size_t QuicFramer::GetRetireConnectionIdFrameSize(
- const QuicRetireConnectionIdFrame& frame) {
- return kQuicFrameTypeSize +
- QuicDataWriter::GetVarInt62Len(frame.sequence_number);
-}
-
-// static
-size_t QuicFramer::GetNewTokenFrameSize(const QuicNewTokenFrame& frame) {
- return kQuicFrameTypeSize +
- QuicDataWriter::GetVarInt62Len(frame.token.length()) +
- frame.token.length();
-}
-
-// TODO(nharper): Change this method to take a ParsedQuicVersion.
-bool QuicFramer::IsSupportedTransportVersion(
- const QuicTransportVersion version) const {
- for (const ParsedQuicVersion& supported_version : supported_versions_) {
- if (version == supported_version.transport_version) {
- return true;
- }
- }
- return false;
-}
-
-bool QuicFramer::IsSupportedVersion(const ParsedQuicVersion version) const {
- for (const ParsedQuicVersion& supported_version : supported_versions_) {
- if (version == supported_version) {
- return true;
- }
- }
- return false;
-}
-
-size_t QuicFramer::GetSerializedFrameLength(
- const QuicFrame& frame, size_t free_bytes, bool first_frame,
- bool last_frame, QuicPacketNumberLength packet_number_length) {
- // Prevent a rare crash reported in b/19458523.
- if (frame.type == ACK_FRAME && frame.ack_frame == nullptr) {
- QUIC_BUG(quic_bug_10850_13)
- << "Cannot compute the length of a null ack frame. free_bytes:"
- << free_bytes << " first_frame:" << first_frame
- << " last_frame:" << last_frame
- << " seq num length:" << packet_number_length;
- set_error(QUIC_INTERNAL_ERROR);
- visitor_->OnError(this);
- return 0;
- }
- if (frame.type == PADDING_FRAME) {
- if (frame.padding_frame.num_padding_bytes == -1) {
- // Full padding to the end of the packet.
- return free_bytes;
- } else {
- // Lite padding.
- return free_bytes <
- static_cast<size_t>(frame.padding_frame.num_padding_bytes)
- ? free_bytes
- : frame.padding_frame.num_padding_bytes;
- }
- }
-
- size_t frame_len =
- ComputeFrameLength(frame, last_frame, packet_number_length);
- if (frame_len <= free_bytes) {
- // Frame fits within packet. Note that acks may be truncated.
- return frame_len;
- }
- // Only truncate the first frame in a packet, so if subsequent ones go
- // over, stop including more frames.
- if (!first_frame) {
- return 0;
- }
- bool can_truncate =
- frame.type == ACK_FRAME &&
- free_bytes >=
- GetMinAckFrameSize(version_.transport_version, *frame.ack_frame,
- local_ack_delay_exponent_,
- UseIetfAckWithReceiveTimestamp(*frame.ack_frame));
- if (can_truncate) {
- // Truncate the frame so the packet will not exceed kMaxOutgoingPacketSize.
- // Note that we may not use every byte of the writer in this case.
- QUIC_DLOG(INFO) << ENDPOINT
- << "Truncating large frame, free bytes: " << free_bytes;
- return free_bytes;
- }
- return 0;
-}
-
-QuicFramer::AckFrameInfo::AckFrameInfo()
- : max_block_length(0), first_block_length(0), num_ack_blocks(0) {}
-
-QuicFramer::AckFrameInfo::AckFrameInfo(const AckFrameInfo& other) = default;
-
-QuicFramer::AckFrameInfo::~AckFrameInfo() {}
-
-bool QuicFramer::WriteIetfLongHeaderLength(const QuicPacketHeader& header,
- QuicDataWriter* writer,
- size_t length_field_offset,
- EncryptionLevel level) {
- if (!QuicVersionHasLongHeaderLengths(transport_version()) ||
- !header.version_flag || length_field_offset == 0) {
- return true;
- }
- if (writer->length() < length_field_offset ||
- writer->length() - length_field_offset <
- kQuicDefaultLongHeaderLengthLength) {
- set_detailed_error("Invalid length_field_offset.");
- QUIC_BUG(quic_bug_10850_14) << "Invalid length_field_offset.";
- return false;
- }
- size_t length_to_write = writer->length() - length_field_offset -
- kQuicDefaultLongHeaderLengthLength;
- // Add length of auth tag.
- length_to_write = GetCiphertextSize(level, length_to_write);
-
- QuicDataWriter length_writer(writer->length() - length_field_offset,
- writer->data() + length_field_offset);
- if (!length_writer.WriteVarInt62(length_to_write,
- kQuicDefaultLongHeaderLengthLength)) {
- set_detailed_error("Failed to overwrite long header length.");
- QUIC_BUG(quic_bug_10850_15) << "Failed to overwrite long header length.";
- return false;
- }
- return true;
-}
-
-size_t QuicFramer::BuildDataPacket(const QuicPacketHeader& header,
- const QuicFrames& frames, char* buffer,
- size_t packet_length,
- EncryptionLevel level) {
- QUIC_BUG_IF(quic_bug_12975_2,
- header.version_flag && version().HasIetfInvariantHeader() &&
- header.long_packet_type == RETRY && !frames.empty())
- << "IETF RETRY packets cannot contain frames " << header;
- QuicDataWriter writer(packet_length, buffer);
- size_t length_field_offset = 0;
- if (!AppendPacketHeader(header, &writer, &length_field_offset)) {
- QUIC_BUG(quic_bug_10850_16) << "AppendPacketHeader failed";
- return 0;
- }
-
- if (VersionHasIetfQuicFrames(transport_version())) {
- if (AppendIetfFrames(frames, &writer) == 0) {
- return 0;
- }
- if (!WriteIetfLongHeaderLength(header, &writer, length_field_offset,
- level)) {
- return 0;
- }
- return writer.length();
- }
-
- size_t i = 0;
- for (const QuicFrame& frame : frames) {
- // Determine if we should write stream frame length in header.
- const bool last_frame_in_packet = i == frames.size() - 1;
- if (!AppendTypeByte(frame, last_frame_in_packet, &writer)) {
- QUIC_BUG(quic_bug_10850_17) << "AppendTypeByte failed";
- return 0;
- }
-
- switch (frame.type) {
- case PADDING_FRAME:
- if (!AppendPaddingFrame(frame.padding_frame, &writer)) {
- QUIC_BUG(quic_bug_10850_18)
- << "AppendPaddingFrame of "
- << frame.padding_frame.num_padding_bytes << " failed";
- return 0;
- }
- break;
- case STREAM_FRAME:
- if (!AppendStreamFrame(frame.stream_frame, last_frame_in_packet,
- &writer)) {
- QUIC_BUG(quic_bug_10850_19) << "AppendStreamFrame failed";
- return 0;
- }
- break;
- case ACK_FRAME:
- if (!AppendAckFrameAndTypeByte(*frame.ack_frame, &writer)) {
- QUIC_BUG(quic_bug_10850_20)
- << "AppendAckFrameAndTypeByte failed: " << detailed_error_;
- return 0;
- }
- break;
- case STOP_WAITING_FRAME:
- if (!AppendStopWaitingFrame(header, frame.stop_waiting_frame,
- &writer)) {
- QUIC_BUG(quic_bug_10850_21) << "AppendStopWaitingFrame failed";
- return 0;
- }
- break;
- case MTU_DISCOVERY_FRAME:
- // MTU discovery frames are serialized as ping frames.
- ABSL_FALLTHROUGH_INTENDED;
- case PING_FRAME:
- // Ping has no payload.
- break;
- case RST_STREAM_FRAME:
- if (!AppendRstStreamFrame(*frame.rst_stream_frame, &writer)) {
- QUIC_BUG(quic_bug_10850_22) << "AppendRstStreamFrame failed";
- return 0;
- }
- break;
- case CONNECTION_CLOSE_FRAME:
- if (!AppendConnectionCloseFrame(*frame.connection_close_frame,
- &writer)) {
- QUIC_BUG(quic_bug_10850_23) << "AppendConnectionCloseFrame failed";
- return 0;
- }
- break;
- case GOAWAY_FRAME:
- if (!AppendGoAwayFrame(*frame.goaway_frame, &writer)) {
- QUIC_BUG(quic_bug_10850_24) << "AppendGoAwayFrame failed";
- return 0;
- }
- break;
- case WINDOW_UPDATE_FRAME:
- if (!AppendWindowUpdateFrame(*frame.window_update_frame, &writer)) {
- QUIC_BUG(quic_bug_10850_25) << "AppendWindowUpdateFrame failed";
- return 0;
- }
- break;
- case BLOCKED_FRAME:
- if (!AppendBlockedFrame(*frame.blocked_frame, &writer)) {
- QUIC_BUG(quic_bug_10850_26) << "AppendBlockedFrame failed";
- return 0;
- }
- break;
- case NEW_CONNECTION_ID_FRAME:
- set_detailed_error(
- "Attempt to append NEW_CONNECTION_ID frame and not in IETF QUIC.");
- return RaiseError(QUIC_INTERNAL_ERROR);
- case RETIRE_CONNECTION_ID_FRAME:
- set_detailed_error(
- "Attempt to append RETIRE_CONNECTION_ID frame and not in IETF "
- "QUIC.");
- return RaiseError(QUIC_INTERNAL_ERROR);
- case NEW_TOKEN_FRAME:
- set_detailed_error(
- "Attempt to append NEW_TOKEN_ID frame and not in IETF QUIC.");
- return RaiseError(QUIC_INTERNAL_ERROR);
- case MAX_STREAMS_FRAME:
- set_detailed_error(
- "Attempt to append MAX_STREAMS frame and not in IETF QUIC.");
- return RaiseError(QUIC_INTERNAL_ERROR);
- case STREAMS_BLOCKED_FRAME:
- set_detailed_error(
- "Attempt to append STREAMS_BLOCKED frame and not in IETF QUIC.");
- return RaiseError(QUIC_INTERNAL_ERROR);
- case PATH_RESPONSE_FRAME:
- set_detailed_error(
- "Attempt to append PATH_RESPONSE frame and not in IETF QUIC.");
- return RaiseError(QUIC_INTERNAL_ERROR);
- case PATH_CHALLENGE_FRAME:
- set_detailed_error(
- "Attempt to append PATH_CHALLENGE frame and not in IETF QUIC.");
- return RaiseError(QUIC_INTERNAL_ERROR);
- case STOP_SENDING_FRAME:
- set_detailed_error(
- "Attempt to append STOP_SENDING frame and not in IETF QUIC.");
- return RaiseError(QUIC_INTERNAL_ERROR);
- case MESSAGE_FRAME:
- if (!AppendMessageFrameAndTypeByte(*frame.message_frame,
- last_frame_in_packet, &writer)) {
- QUIC_BUG(quic_bug_10850_27) << "AppendMessageFrame failed";
- return 0;
- }
- break;
- case CRYPTO_FRAME:
- if (!QuicVersionUsesCryptoFrames(version_.transport_version)) {
- set_detailed_error(
- "Attempt to append CRYPTO frame in version prior to 47.");
- return RaiseError(QUIC_INTERNAL_ERROR);
- }
- if (!AppendCryptoFrame(*frame.crypto_frame, &writer)) {
- QUIC_BUG(quic_bug_10850_28) << "AppendCryptoFrame failed";
- return 0;
- }
- break;
- case HANDSHAKE_DONE_FRAME:
- // HANDSHAKE_DONE has no payload.
- break;
- default:
- RaiseError(QUIC_INVALID_FRAME_DATA);
- QUIC_BUG(quic_bug_10850_29) << "QUIC_INVALID_FRAME_DATA";
- return 0;
- }
- ++i;
- }
-
- if (!WriteIetfLongHeaderLength(header, &writer, length_field_offset, level)) {
- return 0;
- }
-
- return writer.length();
-}
-
-size_t QuicFramer::AppendIetfFrames(const QuicFrames& frames,
- QuicDataWriter* writer) {
- size_t i = 0;
- for (const QuicFrame& frame : frames) {
- // Determine if we should write stream frame length in header.
- const bool last_frame_in_packet = i == frames.size() - 1;
- if (!AppendIetfFrameType(frame, last_frame_in_packet, writer)) {
- QUIC_BUG(quic_bug_10850_30)
- << "AppendIetfFrameType failed: " << detailed_error();
- return 0;
- }
-
- switch (frame.type) {
- case PADDING_FRAME:
- if (!AppendPaddingFrame(frame.padding_frame, writer)) {
- QUIC_BUG(quic_bug_10850_31) << "AppendPaddingFrame of "
- << frame.padding_frame.num_padding_bytes
- << " failed: " << detailed_error();
- return 0;
- }
- break;
- case STREAM_FRAME:
- if (!AppendStreamFrame(frame.stream_frame, last_frame_in_packet,
- writer)) {
- QUIC_BUG(quic_bug_10850_32)
- << "AppendStreamFrame " << frame.stream_frame
- << " failed: " << detailed_error();
- return 0;
- }
- break;
- case ACK_FRAME:
- if (!AppendIetfAckFrameAndTypeByte(*frame.ack_frame, writer)) {
- QUIC_BUG(quic_bug_10850_33)
- << "AppendIetfAckFrameAndTypeByte failed: " << detailed_error();
- return 0;
- }
- break;
- case STOP_WAITING_FRAME:
- set_detailed_error(
- "Attempt to append STOP WAITING frame in IETF QUIC.");
- RaiseError(QUIC_INTERNAL_ERROR);
- QUIC_BUG(quic_bug_10850_34) << detailed_error();
- return 0;
- case MTU_DISCOVERY_FRAME:
- // MTU discovery frames are serialized as ping frames.
- ABSL_FALLTHROUGH_INTENDED;
- case PING_FRAME:
- // Ping has no payload.
- break;
- case RST_STREAM_FRAME:
- if (!AppendRstStreamFrame(*frame.rst_stream_frame, writer)) {
- QUIC_BUG(quic_bug_10850_35)
- << "AppendRstStreamFrame failed: " << detailed_error();
- return 0;
- }
- break;
- case CONNECTION_CLOSE_FRAME:
- if (!AppendIetfConnectionCloseFrame(*frame.connection_close_frame,
- writer)) {
- QUIC_BUG(quic_bug_10850_36)
- << "AppendIetfConnectionCloseFrame failed: " << detailed_error();
- return 0;
- }
- break;
- case GOAWAY_FRAME:
- set_detailed_error("Attempt to append GOAWAY frame in IETF QUIC.");
- RaiseError(QUIC_INTERNAL_ERROR);
- QUIC_BUG(quic_bug_10850_37) << detailed_error();
- return 0;
- case WINDOW_UPDATE_FRAME:
- // Depending on whether there is a stream ID or not, will be either a
- // MAX STREAM DATA frame or a MAX DATA frame.
- if (frame.window_update_frame->stream_id ==
- QuicUtils::GetInvalidStreamId(transport_version())) {
- if (!AppendMaxDataFrame(*frame.window_update_frame, writer)) {
- QUIC_BUG(quic_bug_10850_38)
- << "AppendMaxDataFrame failed: " << detailed_error();
- return 0;
- }
- } else {
- if (!AppendMaxStreamDataFrame(*frame.window_update_frame, writer)) {
- QUIC_BUG(quic_bug_10850_39)
- << "AppendMaxStreamDataFrame failed: " << detailed_error();
- return 0;
- }
- }
- break;
- case BLOCKED_FRAME:
- if (!AppendBlockedFrame(*frame.blocked_frame, writer)) {
- QUIC_BUG(quic_bug_10850_40)
- << "AppendBlockedFrame failed: " << detailed_error();
- return 0;
- }
- break;
- case MAX_STREAMS_FRAME:
- if (!AppendMaxStreamsFrame(frame.max_streams_frame, writer)) {
- QUIC_BUG(quic_bug_10850_41)
- << "AppendMaxStreamsFrame failed: " << detailed_error();
- return 0;
- }
- break;
- case STREAMS_BLOCKED_FRAME:
- if (!AppendStreamsBlockedFrame(frame.streams_blocked_frame, writer)) {
- QUIC_BUG(quic_bug_10850_42)
- << "AppendStreamsBlockedFrame failed: " << detailed_error();
- return 0;
- }
- break;
- case NEW_CONNECTION_ID_FRAME:
- if (!AppendNewConnectionIdFrame(*frame.new_connection_id_frame,
- writer)) {
- QUIC_BUG(quic_bug_10850_43)
- << "AppendNewConnectionIdFrame failed: " << detailed_error();
- return 0;
- }
- break;
- case RETIRE_CONNECTION_ID_FRAME:
- if (!AppendRetireConnectionIdFrame(*frame.retire_connection_id_frame,
- writer)) {
- QUIC_BUG(quic_bug_10850_44)
- << "AppendRetireConnectionIdFrame failed: " << detailed_error();
- return 0;
- }
- break;
- case NEW_TOKEN_FRAME:
- if (!AppendNewTokenFrame(*frame.new_token_frame, writer)) {
- QUIC_BUG(quic_bug_10850_45)
- << "AppendNewTokenFrame failed: " << detailed_error();
- return 0;
- }
- break;
- case STOP_SENDING_FRAME:
- if (!AppendStopSendingFrame(*frame.stop_sending_frame, writer)) {
- QUIC_BUG(quic_bug_10850_46)
- << "AppendStopSendingFrame failed: " << detailed_error();
- return 0;
- }
- break;
- case PATH_CHALLENGE_FRAME:
- if (!AppendPathChallengeFrame(*frame.path_challenge_frame, writer)) {
- QUIC_BUG(quic_bug_10850_47)
- << "AppendPathChallengeFrame failed: " << detailed_error();
- return 0;
- }
- break;
- case PATH_RESPONSE_FRAME:
- if (!AppendPathResponseFrame(*frame.path_response_frame, writer)) {
- QUIC_BUG(quic_bug_10850_48)
- << "AppendPathResponseFrame failed: " << detailed_error();
- return 0;
- }
- break;
- case MESSAGE_FRAME:
- if (!AppendMessageFrameAndTypeByte(*frame.message_frame,
- last_frame_in_packet, writer)) {
- QUIC_BUG(quic_bug_10850_49)
- << "AppendMessageFrame failed: " << detailed_error();
- return 0;
- }
- break;
- case CRYPTO_FRAME:
- if (!AppendCryptoFrame(*frame.crypto_frame, writer)) {
- QUIC_BUG(quic_bug_10850_50)
- << "AppendCryptoFrame failed: " << detailed_error();
- return 0;
- }
- break;
- case HANDSHAKE_DONE_FRAME:
- // HANDSHAKE_DONE has no payload.
- break;
- case ACK_FREQUENCY_FRAME:
- if (!AppendAckFrequencyFrame(*frame.ack_frequency_frame, writer)) {
- QUIC_BUG(quic_bug_10850_51)
- << "AppendAckFrequencyFrame failed: " << detailed_error();
- return 0;
- }
- break;
- default:
- set_detailed_error("Tried to append unknown frame type.");
- RaiseError(QUIC_INVALID_FRAME_DATA);
- QUIC_BUG(quic_bug_10850_52)
- << "QUIC_INVALID_FRAME_DATA: " << frame.type;
- return 0;
- }
- ++i;
- }
-
- return writer->length();
-}
-
-// static
-std::unique_ptr<QuicEncryptedPacket> QuicFramer::BuildPublicResetPacket(
- const QuicPublicResetPacket& packet) {
- CryptoHandshakeMessage reset;
- reset.set_tag(kPRST);
- reset.SetValue(kRNON, packet.nonce_proof);
- if (packet.client_address.host().address_family() !=
- IpAddressFamily::IP_UNSPEC) {
- // packet.client_address is non-empty.
- QuicSocketAddressCoder address_coder(packet.client_address);
- std::string serialized_address = address_coder.Encode();
- if (serialized_address.empty()) {
- return nullptr;
- }
- reset.SetStringPiece(kCADR, serialized_address);
- }
- if (!packet.endpoint_id.empty()) {
- reset.SetStringPiece(kEPID, packet.endpoint_id);
- }
- const QuicData& reset_serialized = reset.GetSerialized();
-
- size_t len = kPublicFlagsSize + packet.connection_id.length() +
- reset_serialized.length();
- std::unique_ptr<char[]> buffer(new char[len]);
- QuicDataWriter writer(len, buffer.get());
-
- uint8_t flags = static_cast<uint8_t>(PACKET_PUBLIC_FLAGS_RST |
- PACKET_PUBLIC_FLAGS_8BYTE_CONNECTION_ID);
- // This hack makes post-v33 public reset packet look like pre-v33 packets.
- flags |= static_cast<uint8_t>(PACKET_PUBLIC_FLAGS_8BYTE_CONNECTION_ID_OLD);
- if (!writer.WriteUInt8(flags)) {
- return nullptr;
- }
-
- if (!writer.WriteConnectionId(packet.connection_id)) {
- return nullptr;
- }
-
- if (!writer.WriteBytes(reset_serialized.data(), reset_serialized.length())) {
- return nullptr;
- }
-
- return std::make_unique<QuicEncryptedPacket>(buffer.release(), len, true);
-}
-
-// static
-size_t QuicFramer::GetMinStatelessResetPacketLength() {
- // 5 bytes (40 bits) = 2 Fixed Bits (01) + 38 Unpredictable bits
- return 5 + kStatelessResetTokenLength;
-}
-
-// static
-std::unique_ptr<QuicEncryptedPacket> QuicFramer::BuildIetfStatelessResetPacket(
- QuicConnectionId /*connection_id*/, size_t received_packet_length,
- StatelessResetToken stateless_reset_token) {
- QUIC_DVLOG(1) << "Building IETF stateless reset packet.";
- if (received_packet_length <= GetMinStatelessResetPacketLength()) {
- QUICHE_DLOG(ERROR)
- << "Tried to build stateless reset packet with received packet "
- "length "
- << received_packet_length;
- return nullptr;
- }
- // To ensure stateless reset is indistinguishable from a valid packet,
- // include the max connection ID length.
- size_t len = std::min(received_packet_length - 1,
- GetMinStatelessResetPacketLength() + 1 +
- kQuicMaxConnectionIdWithLengthPrefixLength);
- std::unique_ptr<char[]> buffer(new char[len]);
- QuicDataWriter writer(len, buffer.get());
- // Append random bytes. This randomness only exists to prevent middleboxes
- // from comparing the entire packet to a known value. Therefore it has no
- // cryptographic use, and does not need a secure cryptographic pseudo-random
- // number generator. It's therefore safe to use WriteInsecureRandomBytes.
- if (!writer.WriteInsecureRandomBytes(QuicRandom::GetInstance(),
- len - kStatelessResetTokenLength)) {
- QUIC_BUG(362045737_2) << "Failed to append random bytes of length: "
- << len - kStatelessResetTokenLength;
- return nullptr;
- }
- // Change first 2 fixed bits to 01.
- buffer[0] &= ~FLAGS_LONG_HEADER;
- buffer[0] |= FLAGS_FIXED_BIT;
-
- // Append stateless reset token.
- if (!writer.WriteBytes(&stateless_reset_token,
- sizeof(stateless_reset_token))) {
- QUIC_BUG(362045737_3) << "Failed to write stateless reset token";
- return nullptr;
- }
- return std::make_unique<QuicEncryptedPacket>(buffer.release(), len,
- /*owns_buffer=*/true);
-}
-
-// static
-std::unique_ptr<QuicEncryptedPacket> QuicFramer::BuildVersionNegotiationPacket(
- QuicConnectionId server_connection_id,
- QuicConnectionId client_connection_id, bool ietf_quic,
- bool use_length_prefix, const ParsedQuicVersionVector& versions) {
- QUIC_CODE_COUNT(quic_build_version_negotiation);
- if (use_length_prefix) {
- QUICHE_DCHECK(ietf_quic);
- QUIC_CODE_COUNT(quic_build_version_negotiation_ietf);
- } else if (ietf_quic) {
- QUIC_CODE_COUNT(quic_build_version_negotiation_old_ietf);
- } else {
- QUIC_CODE_COUNT(quic_build_version_negotiation_old_gquic);
- }
- ParsedQuicVersionVector wire_versions = versions;
- // Add a version reserved for negotiation as suggested by the
- // "Using Reserved Versions" section of draft-ietf-quic-transport.
- if (wire_versions.empty()) {
- // Ensure that version negotiation packets we send have at least two
- // versions. This guarantees that, under all circumstances, all QUIC
- // packets we send are at least 14 bytes long.
- wire_versions = {QuicVersionReservedForNegotiation(),
- QuicVersionReservedForNegotiation()};
- } else {
- // This is not uniformely distributed but is acceptable since no security
- // depends on this randomness.
- size_t version_index = 0;
- const bool disable_randomness =
- GetQuicFlag(FLAGS_quic_disable_version_negotiation_grease_randomness);
- if (!disable_randomness) {
- version_index =
- QuicRandom::GetInstance()->RandUint64() % (wire_versions.size() + 1);
- }
- wire_versions.insert(wire_versions.begin() + version_index,
- QuicVersionReservedForNegotiation());
- }
- if (ietf_quic) {
- return BuildIetfVersionNegotiationPacket(
- use_length_prefix, server_connection_id, client_connection_id,
- wire_versions);
- }
-
- // The GQUIC encoding does not support encoding client connection IDs.
- QUICHE_DCHECK(client_connection_id.IsEmpty());
- // The GQUIC encoding does not support length-prefixed connection IDs.
- QUICHE_DCHECK(!use_length_prefix);
-
- QUICHE_DCHECK(!wire_versions.empty());
- size_t len = kPublicFlagsSize + server_connection_id.length() +
- wire_versions.size() * kQuicVersionSize;
- std::unique_ptr<char[]> buffer(new char[len]);
- QuicDataWriter writer(len, buffer.get());
-
- uint8_t flags = static_cast<uint8_t>(
- PACKET_PUBLIC_FLAGS_VERSION | PACKET_PUBLIC_FLAGS_8BYTE_CONNECTION_ID |
- PACKET_PUBLIC_FLAGS_8BYTE_CONNECTION_ID_OLD);
- if (!writer.WriteUInt8(flags)) {
- return nullptr;
- }
-
- if (!writer.WriteConnectionId(server_connection_id)) {
- return nullptr;
- }
-
- for (const ParsedQuicVersion& version : wire_versions) {
- if (!writer.WriteUInt32(CreateQuicVersionLabel(version))) {
- return nullptr;
- }
- }
-
- return std::make_unique<QuicEncryptedPacket>(buffer.release(), len, true);
-}
-
-// static
-std::unique_ptr<QuicEncryptedPacket>
-QuicFramer::BuildIetfVersionNegotiationPacket(
- bool use_length_prefix, QuicConnectionId server_connection_id,
- QuicConnectionId client_connection_id,
- const ParsedQuicVersionVector& versions) {
- QUIC_DVLOG(1) << "Building IETF version negotiation packet with"
- << (use_length_prefix ? "" : "out")
- << " length prefix, server_connection_id "
- << server_connection_id << " client_connection_id "
- << client_connection_id << " versions "
- << ParsedQuicVersionVectorToString(versions);
- QUICHE_DCHECK(!versions.empty());
- size_t len = kPacketHeaderTypeSize + kConnectionIdLengthSize +
- client_connection_id.length() + server_connection_id.length() +
- (versions.size() + 1) * kQuicVersionSize;
- if (use_length_prefix) {
- // When using length-prefixed connection IDs, packets carry two lengths
- // instead of one.
- len += kConnectionIdLengthSize;
- }
- std::unique_ptr<char[]> buffer(new char[len]);
- QuicDataWriter writer(len, buffer.get());
-
- // TODO(fayang): Randomly select a value for the type.
- uint8_t type = static_cast<uint8_t>(FLAGS_LONG_HEADER | FLAGS_FIXED_BIT);
- if (!writer.WriteUInt8(type)) {
- return nullptr;
- }
-
- if (!writer.WriteUInt32(0)) {
- return nullptr;
- }
-
- if (!AppendIetfConnectionIds(true, use_length_prefix, client_connection_id,
- server_connection_id, &writer)) {
- return nullptr;
- }
-
- for (const ParsedQuicVersion& version : versions) {
- if (!writer.WriteUInt32(CreateQuicVersionLabel(version))) {
- return nullptr;
- }
- }
-
- return std::make_unique<QuicEncryptedPacket>(buffer.release(), len, true);
-}
-
-bool QuicFramer::ProcessPacket(const QuicEncryptedPacket& packet) {
- QUICHE_DCHECK(!is_processing_packet_) << ENDPOINT << "Nested ProcessPacket";
- is_processing_packet_ = true;
- bool result = ProcessPacketInternal(packet);
- is_processing_packet_ = false;
- return result;
-}
-
-bool QuicFramer::ProcessPacketInternal(const QuicEncryptedPacket& packet) {
- QuicDataReader reader(packet.data(), packet.length());
-
- bool packet_has_ietf_packet_header = false;
- if (infer_packet_header_type_from_version_) {
- packet_has_ietf_packet_header = version_.HasIetfInvariantHeader();
- } else if (!reader.IsDoneReading()) {
- uint8_t type = reader.PeekByte();
- packet_has_ietf_packet_header = QuicUtils::IsIetfPacketHeader(type);
- }
- if (packet_has_ietf_packet_header) {
- QUIC_DVLOG(1) << ENDPOINT << "Processing IETF QUIC packet.";
- }
-
- visitor_->OnPacket();
-
- QuicPacketHeader header;
- if (!ProcessPublicHeader(&reader, packet_has_ietf_packet_header, &header)) {
- QUICHE_DCHECK_NE("", detailed_error_);
- QUIC_DVLOG(1) << ENDPOINT << "Unable to process public header. Error: "
- << detailed_error_;
- QUICHE_DCHECK_NE("", detailed_error_);
- RecordDroppedPacketReason(DroppedPacketReason::INVALID_PUBLIC_HEADER);
- return RaiseError(QUIC_INVALID_PACKET_HEADER);
- }
-
- if (!visitor_->OnUnauthenticatedPublicHeader(header)) {
- // The visitor suppresses further processing of the packet.
- return true;
- }
-
- if (IsVersionNegotiation(header, packet_has_ietf_packet_header)) {
- if (perspective_ == Perspective::IS_CLIENT) {
- QUIC_DVLOG(1) << "Client received version negotiation packet";
- return ProcessVersionNegotiationPacket(&reader, header);
- } else {
- QUIC_DLOG(ERROR) << "Server received version negotiation packet";
- set_detailed_error("Server received version negotiation packet.");
- return RaiseError(QUIC_INVALID_VERSION_NEGOTIATION_PACKET);
- }
- }
-
- if (header.version_flag && header.version != version_) {
- if (perspective_ == Perspective::IS_SERVER) {
- if (!visitor_->OnProtocolVersionMismatch(header.version)) {
- RecordDroppedPacketReason(DroppedPacketReason::VERSION_MISMATCH);
- return true;
- }
- } else {
- // A client received a packet of a different version but that packet is
- // not a version negotiation packet. It is therefore invalid and dropped.
- QUIC_DLOG(ERROR) << "Client received unexpected version "
- << ParsedQuicVersionToString(header.version)
- << " instead of " << ParsedQuicVersionToString(version_);
- set_detailed_error("Client received unexpected version.");
- return RaiseError(QUIC_INVALID_VERSION);
- }
- }
-
- bool rv;
- if (header.long_packet_type == RETRY) {
- rv = ProcessRetryPacket(&reader, header);
- } else if (header.reset_flag) {
- rv = ProcessPublicResetPacket(&reader, header);
- } else if (packet.length() <= kMaxIncomingPacketSize) {
- // The optimized decryption algorithm implementations run faster when
- // operating on aligned memory.
- ABSL_CACHELINE_ALIGNED char buffer[kMaxIncomingPacketSize];
- if (packet_has_ietf_packet_header) {
- rv = ProcessIetfDataPacket(&reader, &header, packet, buffer,
- ABSL_ARRAYSIZE(buffer));
- } else {
- rv = ProcessDataPacket(&reader, &header, packet, buffer,
- ABSL_ARRAYSIZE(buffer));
- }
- } else {
- std::unique_ptr<char[]> large_buffer(new char[packet.length()]);
- if (packet_has_ietf_packet_header) {
- rv = ProcessIetfDataPacket(&reader, &header, packet, large_buffer.get(),
- packet.length());
- } else {
- rv = ProcessDataPacket(&reader, &header, packet, large_buffer.get(),
- packet.length());
- }
- QUIC_BUG_IF(quic_bug_10850_53, rv)
- << "QUIC should never successfully process packets larger"
- << "than kMaxIncomingPacketSize. packet size:" << packet.length();
- }
- return rv;
-}
-
-bool QuicFramer::ProcessVersionNegotiationPacket(
- QuicDataReader* reader, const QuicPacketHeader& header) {
- QUICHE_DCHECK_EQ(Perspective::IS_CLIENT, perspective_);
-
- QuicVersionNegotiationPacket packet(
- GetServerConnectionIdAsRecipient(header, perspective_));
- // Try reading at least once to raise error if the packet is invalid.
- do {
- QuicVersionLabel version_label;
- if (!ProcessVersionLabel(reader, &version_label)) {
- set_detailed_error("Unable to read supported version in negotiation.");
- RecordDroppedPacketReason(
- DroppedPacketReason::INVALID_VERSION_NEGOTIATION_PACKET);
- return RaiseError(QUIC_INVALID_VERSION_NEGOTIATION_PACKET);
- }
- ParsedQuicVersion parsed_version = ParseQuicVersionLabel(version_label);
- if (parsed_version != UnsupportedQuicVersion()) {
- packet.versions.push_back(parsed_version);
- }
- } while (!reader->IsDoneReading());
-
- QUIC_DLOG(INFO) << ENDPOINT << "parsed version negotiation: "
- << ParsedQuicVersionVectorToString(packet.versions);
-
- visitor_->OnVersionNegotiationPacket(packet);
- return true;
-}
-
-bool QuicFramer::ProcessRetryPacket(QuicDataReader* reader,
- const QuicPacketHeader& header) {
- QUICHE_DCHECK_EQ(Perspective::IS_CLIENT, perspective_);
- if (drop_incoming_retry_packets_) {
- QUIC_DLOG(INFO) << "Ignoring received RETRY packet";
- return true;
- }
-
- if (version_.UsesTls()) {
- QUICHE_DCHECK(version_.HasLengthPrefixedConnectionIds()) << version_;
- const size_t bytes_remaining = reader->BytesRemaining();
- if (bytes_remaining <= kRetryIntegrityTagLength) {
- set_detailed_error("Retry packet too short to parse integrity tag.");
- return false;
- }
- const size_t retry_token_length =
- bytes_remaining - kRetryIntegrityTagLength;
- QUICHE_DCHECK_GT(retry_token_length, 0u);
- absl::string_view retry_token;
- if (!reader->ReadStringPiece(&retry_token, retry_token_length)) {
- set_detailed_error("Failed to read retry token.");
- return false;
- }
- absl::string_view retry_without_tag = reader->PreviouslyReadPayload();
- absl::string_view integrity_tag = reader->ReadRemainingPayload();
- QUICHE_DCHECK_EQ(integrity_tag.length(), kRetryIntegrityTagLength);
- visitor_->OnRetryPacket(EmptyQuicConnectionId(),
- header.source_connection_id, retry_token,
- integrity_tag, retry_without_tag);
- return true;
- }
-
- QuicConnectionId original_destination_connection_id;
- if (version_.HasLengthPrefixedConnectionIds()) {
- // Parse Original Destination Connection ID.
- if (!reader->ReadLengthPrefixedConnectionId(
- &original_destination_connection_id)) {
- set_detailed_error("Unable to read Original Destination ConnectionId.");
- return false;
- }
- } else {
- // Parse Original Destination Connection ID Length.
- uint8_t odcil = header.type_byte & 0xf;
- if (odcil != 0) {
- odcil += kConnectionIdLengthAdjustment;
- }
-
- // Parse Original Destination Connection ID.
- if (!reader->ReadConnectionId(&original_destination_connection_id, odcil)) {
- set_detailed_error("Unable to read Original Destination ConnectionId.");
- return false;
- }
- }
-
- if (!QuicUtils::IsConnectionIdValidForVersion(
- original_destination_connection_id, transport_version())) {
- set_detailed_error(
- "Received Original Destination ConnectionId with invalid length.");
- return false;
- }
-
- absl::string_view retry_token = reader->ReadRemainingPayload();
- visitor_->OnRetryPacket(original_destination_connection_id,
- header.source_connection_id, retry_token,
- /*retry_integrity_tag=*/absl::string_view(),
- /*retry_without_tag=*/absl::string_view());
- return true;
-}
-
-// Seeks the current packet to check for a coalesced packet at the end.
-// If the IETF length field only spans part of the outer packet,
-// then there is a coalesced packet after this one.
-void QuicFramer::MaybeProcessCoalescedPacket(
- const QuicDataReader& encrypted_reader, uint64_t remaining_bytes_length,
- const QuicPacketHeader& header) {
- if (header.remaining_packet_length >= remaining_bytes_length) {
- // There is no coalesced packet.
- return;
- }
-
- absl::string_view remaining_data = encrypted_reader.PeekRemainingPayload();
- QUICHE_DCHECK_EQ(remaining_data.length(), remaining_bytes_length);
-
- const char* coalesced_data =
- remaining_data.data() + header.remaining_packet_length;
- uint64_t coalesced_data_length =
- remaining_bytes_length - header.remaining_packet_length;
- QuicDataReader coalesced_reader(coalesced_data, coalesced_data_length);
-
- QuicPacketHeader coalesced_header;
- if (!ProcessIetfPacketHeader(&coalesced_reader, &coalesced_header)) {
- // Some implementations pad their INITIAL packets by sending random invalid
- // data after the INITIAL, and that is allowed by the specification. If we
- // fail to parse a subsequent coalesced packet, simply ignore it.
- QUIC_DLOG(INFO) << ENDPOINT
- << "Failed to parse received coalesced header of length "
- << coalesced_data_length
- << " with error: " << detailed_error_ << ": "
- << absl::BytesToHexString(absl::string_view(
- coalesced_data, coalesced_data_length))
- << " previous header was " << header;
- return;
- }
-
- if (coalesced_header.destination_connection_id !=
- header.destination_connection_id) {
- // Drop coalesced packets with mismatched connection IDs.
- QUIC_DLOG(INFO) << ENDPOINT << "Received mismatched coalesced header "
- << coalesced_header << " previous header was " << header;
- QUIC_CODE_COUNT(
- quic_received_coalesced_packets_with_mismatched_connection_id);
- return;
- }
-
- QuicEncryptedPacket coalesced_packet(coalesced_data, coalesced_data_length,
- /*owns_buffer=*/false);
- visitor_->OnCoalescedPacket(coalesced_packet);
-}
-
-bool QuicFramer::MaybeProcessIetfLength(QuicDataReader* encrypted_reader,
- QuicPacketHeader* header) {
- if (!QuicVersionHasLongHeaderLengths(header->version.transport_version) ||
- header->form != IETF_QUIC_LONG_HEADER_PACKET ||
- (header->long_packet_type != INITIAL &&
- header->long_packet_type != HANDSHAKE &&
- header->long_packet_type != ZERO_RTT_PROTECTED)) {
- return true;
- }
- header->length_length = encrypted_reader->PeekVarInt62Length();
- if (!encrypted_reader->ReadVarInt62(&header->remaining_packet_length)) {
- set_detailed_error("Unable to read long header payload length.");
- return RaiseError(QUIC_INVALID_PACKET_HEADER);
- }
- uint64_t remaining_bytes_length = encrypted_reader->BytesRemaining();
- if (header->remaining_packet_length > remaining_bytes_length) {
- set_detailed_error("Long header payload length longer than packet.");
- return RaiseError(QUIC_INVALID_PACKET_HEADER);
- }
-
- MaybeProcessCoalescedPacket(*encrypted_reader, remaining_bytes_length,
- *header);
-
- if (!encrypted_reader->TruncateRemaining(header->remaining_packet_length)) {
- set_detailed_error("Length TruncateRemaining failed.");
- QUIC_BUG(quic_bug_10850_54) << "Length TruncateRemaining failed.";
- return RaiseError(QUIC_INVALID_PACKET_HEADER);
- }
- return true;
-}
-
-bool QuicFramer::ProcessIetfDataPacket(QuicDataReader* encrypted_reader,
- QuicPacketHeader* header,
- const QuicEncryptedPacket& packet,
- char* decrypted_buffer,
- size_t buffer_length) {
- QUICHE_DCHECK_NE(GOOGLE_QUIC_PACKET, header->form);
- QUICHE_DCHECK(!header->has_possible_stateless_reset_token);
- header->length_length = VARIABLE_LENGTH_INTEGER_LENGTH_0;
- header->remaining_packet_length = 0;
- if (header->form == IETF_QUIC_SHORT_HEADER_PACKET &&
- perspective_ == Perspective::IS_CLIENT) {
- // Peek possible stateless reset token. Will only be used on decryption
- // failure.
- absl::string_view remaining = encrypted_reader->PeekRemainingPayload();
- if (remaining.length() >= sizeof(header->possible_stateless_reset_token)) {
- header->has_possible_stateless_reset_token = true;
- memcpy(&header->possible_stateless_reset_token,
- &remaining.data()[remaining.length() -
- sizeof(header->possible_stateless_reset_token)],
- sizeof(header->possible_stateless_reset_token));
- }
- }
-
- if (!MaybeProcessIetfLength(encrypted_reader, header)) {
- return false;
- }
-
- absl::string_view associated_data;
- std::vector<char> ad_storage;
- QuicPacketNumber base_packet_number;
- if (header->form == IETF_QUIC_SHORT_HEADER_PACKET ||
- header->long_packet_type != VERSION_NEGOTIATION) {
- QUICHE_DCHECK(header->form == IETF_QUIC_SHORT_HEADER_PACKET ||
- header->long_packet_type == INITIAL ||
- header->long_packet_type == HANDSHAKE ||
- header->long_packet_type == ZERO_RTT_PROTECTED);
- // Process packet number.
- if (supports_multiple_packet_number_spaces_) {
- PacketNumberSpace pn_space = GetPacketNumberSpace(*header);
- if (pn_space == NUM_PACKET_NUMBER_SPACES) {
- return RaiseError(QUIC_INVALID_PACKET_HEADER);
- }
- base_packet_number = largest_decrypted_packet_numbers_[pn_space];
- } else {
- base_packet_number = largest_packet_number_;
- }
- uint64_t full_packet_number;
- bool hp_removal_failed = false;
- if (version_.HasHeaderProtection()) {
- if (!RemoveHeaderProtection(encrypted_reader, packet, header,
- &full_packet_number, &ad_storage)) {
- hp_removal_failed = true;
- }
- associated_data = absl::string_view(ad_storage.data(), ad_storage.size());
- } else if (!ProcessAndCalculatePacketNumber(
- encrypted_reader, header->packet_number_length,
- base_packet_number, &full_packet_number)) {
- set_detailed_error("Unable to read packet number.");
- RecordDroppedPacketReason(DroppedPacketReason::INVALID_PACKET_NUMBER);
- return RaiseError(QUIC_INVALID_PACKET_HEADER);
- }
-
- if (hp_removal_failed ||
- !IsValidFullPacketNumber(full_packet_number, version())) {
- if (IsIetfStatelessResetPacket(*header)) {
- // This is a stateless reset packet.
- QuicIetfStatelessResetPacket packet(
- *header, header->possible_stateless_reset_token);
- visitor_->OnAuthenticatedIetfStatelessResetPacket(packet);
- return true;
- }
- if (hp_removal_failed) {
- const EncryptionLevel decryption_level = GetEncryptionLevel(*header);
- const bool has_decryption_key = decrypter_[decryption_level] != nullptr;
- visitor_->OnUndecryptablePacket(
- QuicEncryptedPacket(encrypted_reader->FullPayload()),
- decryption_level, has_decryption_key);
- RecordDroppedPacketReason(DroppedPacketReason::DECRYPTION_FAILURE);
- set_detailed_error(absl::StrCat(
- "Unable to decrypt ", EncryptionLevelToString(decryption_level),
- " header protection", has_decryption_key ? "" : " (missing key)",
- "."));
- return RaiseError(QUIC_DECRYPTION_FAILURE);
- }
- RecordDroppedPacketReason(DroppedPacketReason::INVALID_PACKET_NUMBER);
- set_detailed_error("packet numbers cannot be 0.");
- return RaiseError(QUIC_INVALID_PACKET_HEADER);
- }
- header->packet_number = QuicPacketNumber(full_packet_number);
- }
-
- // A nonce should only present in SHLO from the server to the client when
- // using QUIC crypto.
- if (header->form == IETF_QUIC_LONG_HEADER_PACKET &&
- header->long_packet_type == ZERO_RTT_PROTECTED &&
- perspective_ == Perspective::IS_CLIENT &&
- version_.handshake_protocol == PROTOCOL_QUIC_CRYPTO) {
- if (!encrypted_reader->ReadBytes(
- reinterpret_cast<uint8_t*>(last_nonce_.data()),
- last_nonce_.size())) {
- set_detailed_error("Unable to read nonce.");
- RecordDroppedPacketReason(
- DroppedPacketReason::INVALID_DIVERSIFICATION_NONCE);
- return RaiseError(QUIC_INVALID_PACKET_HEADER);
- }
-
- header->nonce = &last_nonce_;
- } else {
- header->nonce = nullptr;
- }
-
- if (!visitor_->OnUnauthenticatedHeader(*header)) {
- set_detailed_error(
- "Visitor asked to stop processing of unauthenticated header.");
- return false;
- }
-
- absl::string_view encrypted = encrypted_reader->ReadRemainingPayload();
- if (!version_.HasHeaderProtection()) {
- associated_data = GetAssociatedDataFromEncryptedPacket(
- version_.transport_version, packet,
- GetIncludedDestinationConnectionIdLength(*header),
- GetIncludedSourceConnectionIdLength(*header), header->version_flag,
- header->nonce != nullptr, header->packet_number_length,
- header->retry_token_length_length, header->retry_token.length(),
- header->length_length);
- }
-
- size_t decrypted_length = 0;
- EncryptionLevel decrypted_level;
- if (!DecryptPayload(packet.length(), encrypted, associated_data, *header,
- decrypted_buffer, buffer_length, &decrypted_length,
- &decrypted_level)) {
- if (IsIetfStatelessResetPacket(*header)) {
- // This is a stateless reset packet.
- QuicIetfStatelessResetPacket packet(
- *header, header->possible_stateless_reset_token);
- visitor_->OnAuthenticatedIetfStatelessResetPacket(packet);
- return true;
- }
- const EncryptionLevel decryption_level = GetEncryptionLevel(*header);
- const bool has_decryption_key = version_.KnowsWhichDecrypterToUse() &&
- decrypter_[decryption_level] != nullptr;
- visitor_->OnUndecryptablePacket(
- QuicEncryptedPacket(encrypted_reader->FullPayload()), decryption_level,
- has_decryption_key);
- set_detailed_error(absl::StrCat(
- "Unable to decrypt ", EncryptionLevelToString(decryption_level),
- " payload with reconstructed packet number ",
- header->packet_number.ToString(), " (largest decrypted was ",
- base_packet_number.ToString(), ")",
- has_decryption_key || !version_.KnowsWhichDecrypterToUse()
- ? ""
- : " (missing key)",
- "."));
- RecordDroppedPacketReason(DroppedPacketReason::DECRYPTION_FAILURE);
- return RaiseError(QUIC_DECRYPTION_FAILURE);
- }
- QuicDataReader reader(decrypted_buffer, decrypted_length);
-
- // Update the largest packet number after we have decrypted the packet
- // so we are confident is not attacker controlled.
- if (supports_multiple_packet_number_spaces_) {
- largest_decrypted_packet_numbers_[QuicUtils::GetPacketNumberSpace(
- decrypted_level)]
- .UpdateMax(header->packet_number);
- } else {
- largest_packet_number_.UpdateMax(header->packet_number);
- }
-
- if (!visitor_->OnPacketHeader(*header)) {
- RecordDroppedPacketReason(DroppedPacketReason::INVALID_PACKET_NUMBER);
- // The visitor suppresses further processing of the packet.
- return true;
- }
-
- if (packet.length() > kMaxIncomingPacketSize) {
- set_detailed_error("Packet too large.");
- return RaiseError(QUIC_PACKET_TOO_LARGE);
- }
-
- // Handle the payload.
- if (VersionHasIetfQuicFrames(version_.transport_version)) {
- current_received_frame_type_ = 0;
- previously_received_frame_type_ = 0;
- if (!ProcessIetfFrameData(&reader, *header, decrypted_level)) {
- current_received_frame_type_ = 0;
- previously_received_frame_type_ = 0;
- QUICHE_DCHECK_NE(QUIC_NO_ERROR,
- error_); // ProcessIetfFrameData sets the error.
- QUICHE_DCHECK_NE("", detailed_error_);
- QUIC_DLOG(WARNING) << ENDPOINT << "Unable to process frame data. Error: "
- << detailed_error_;
- return false;
- }
- current_received_frame_type_ = 0;
- previously_received_frame_type_ = 0;
- } else {
- if (!ProcessFrameData(&reader, *header)) {
- QUICHE_DCHECK_NE(QUIC_NO_ERROR,
- error_); // ProcessFrameData sets the error.
- QUICHE_DCHECK_NE("", detailed_error_);
- QUIC_DLOG(WARNING) << ENDPOINT << "Unable to process frame data. Error: "
- << detailed_error_;
- return false;
- }
- }
-
- visitor_->OnPacketComplete();
- return true;
-}
-
-bool QuicFramer::ProcessDataPacket(QuicDataReader* encrypted_reader,
- QuicPacketHeader* header,
- const QuicEncryptedPacket& packet,
- char* decrypted_buffer,
- size_t buffer_length) {
- if (!ProcessUnauthenticatedHeader(encrypted_reader, header)) {
- QUICHE_DCHECK_NE("", detailed_error_);
- QUIC_DVLOG(1)
- << ENDPOINT
- << "Unable to process packet header. Stopping parsing. Error: "
- << detailed_error_;
- RecordDroppedPacketReason(DroppedPacketReason::INVALID_PACKET_NUMBER);
- return false;
- }
-
- absl::string_view encrypted = encrypted_reader->ReadRemainingPayload();
- absl::string_view associated_data = GetAssociatedDataFromEncryptedPacket(
- version_.transport_version, packet,
- GetIncludedDestinationConnectionIdLength(*header),
- GetIncludedSourceConnectionIdLength(*header), header->version_flag,
- header->nonce != nullptr, header->packet_number_length,
- header->retry_token_length_length, header->retry_token.length(),
- header->length_length);
-
- size_t decrypted_length = 0;
- EncryptionLevel decrypted_level;
- if (!DecryptPayload(packet.length(), encrypted, associated_data, *header,
- decrypted_buffer, buffer_length, &decrypted_length,
- &decrypted_level)) {
- const EncryptionLevel decryption_level = decrypter_level_;
- // This version uses trial decryption so we always report to our visitor
- // that we are not certain we have the correct decryption key.
- const bool has_decryption_key = false;
- visitor_->OnUndecryptablePacket(
- QuicEncryptedPacket(encrypted_reader->FullPayload()), decryption_level,
- has_decryption_key);
- RecordDroppedPacketReason(DroppedPacketReason::DECRYPTION_FAILURE);
- set_detailed_error(absl::StrCat("Unable to decrypt ",
- EncryptionLevelToString(decryption_level),
- " payload."));
- return RaiseError(QUIC_DECRYPTION_FAILURE);
- }
-
- QuicDataReader reader(decrypted_buffer, decrypted_length);
-
- // Update the largest packet number after we have decrypted the packet
- // so we are confident is not attacker controlled.
- if (supports_multiple_packet_number_spaces_) {
- largest_decrypted_packet_numbers_[QuicUtils::GetPacketNumberSpace(
- decrypted_level)]
- .UpdateMax(header->packet_number);
- } else {
- largest_packet_number_.UpdateMax(header->packet_number);
- }
-
- if (!visitor_->OnPacketHeader(*header)) {
- // The visitor suppresses further processing of the packet.
- return true;
- }
-
- if (packet.length() > kMaxIncomingPacketSize) {
- set_detailed_error("Packet too large.");
- return RaiseError(QUIC_PACKET_TOO_LARGE);
- }
-
- // Handle the payload.
- if (!ProcessFrameData(&reader, *header)) {
- QUICHE_DCHECK_NE(QUIC_NO_ERROR,
- error_); // ProcessFrameData sets the error.
- QUICHE_DCHECK_NE("", detailed_error_);
- QUIC_DLOG(WARNING) << ENDPOINT << "Unable to process frame data. Error: "
- << detailed_error_;
- return false;
- }
-
- visitor_->OnPacketComplete();
- return true;
-}
-
-bool QuicFramer::ProcessPublicResetPacket(QuicDataReader* reader,
- const QuicPacketHeader& header) {
- QuicPublicResetPacket packet(
- GetServerConnectionIdAsRecipient(header, perspective_));
-
- std::unique_ptr<CryptoHandshakeMessage> reset(
- CryptoFramer::ParseMessage(reader->ReadRemainingPayload()));
- if (!reset) {
- set_detailed_error("Unable to read reset message.");
- RecordDroppedPacketReason(DroppedPacketReason::INVALID_PUBLIC_RESET_PACKET);
- return RaiseError(QUIC_INVALID_PUBLIC_RST_PACKET);
- }
- if (reset->tag() != kPRST) {
- set_detailed_error("Incorrect message tag.");
- RecordDroppedPacketReason(DroppedPacketReason::INVALID_PUBLIC_RESET_PACKET);
- return RaiseError(QUIC_INVALID_PUBLIC_RST_PACKET);
- }
-
- if (reset->GetUint64(kRNON, &packet.nonce_proof) != QUIC_NO_ERROR) {
- set_detailed_error("Unable to read nonce proof.");
- RecordDroppedPacketReason(DroppedPacketReason::INVALID_PUBLIC_RESET_PACKET);
- return RaiseError(QUIC_INVALID_PUBLIC_RST_PACKET);
- }
- // TODO(satyamshekhar): validate nonce to protect against DoS.
-
- absl::string_view address;
- if (reset->GetStringPiece(kCADR, &address)) {
- QuicSocketAddressCoder address_coder;
- if (address_coder.Decode(address.data(), address.length())) {
- packet.client_address =
- QuicSocketAddress(address_coder.ip(), address_coder.port());
- }
- }
-
- absl::string_view endpoint_id;
- if (perspective_ == Perspective::IS_CLIENT &&
- reset->GetStringPiece(kEPID, &endpoint_id)) {
- packet.endpoint_id = std::string(endpoint_id);
- packet.endpoint_id += '\0';
- }
-
- visitor_->OnPublicResetPacket(packet);
- return true;
-}
-
-bool QuicFramer::IsIetfStatelessResetPacket(
- const QuicPacketHeader& header) const {
- QUIC_BUG_IF(quic_bug_12975_3, header.has_possible_stateless_reset_token &&
- perspective_ != Perspective::IS_CLIENT)
- << "has_possible_stateless_reset_token can only be true at client side.";
- return header.form == IETF_QUIC_SHORT_HEADER_PACKET &&
- header.has_possible_stateless_reset_token &&
- visitor_->IsValidStatelessResetToken(
- header.possible_stateless_reset_token);
-}
-
-bool QuicFramer::HasEncrypterOfEncryptionLevel(EncryptionLevel level) const {
- return encrypter_[level] != nullptr;
-}
-
-bool QuicFramer::HasDecrypterOfEncryptionLevel(EncryptionLevel level) const {
- return decrypter_[level] != nullptr;
-}
-
-bool QuicFramer::HasAnEncrypterForSpace(PacketNumberSpace space) const {
- switch (space) {
- case INITIAL_DATA:
- return HasEncrypterOfEncryptionLevel(ENCRYPTION_INITIAL);
- case HANDSHAKE_DATA:
- return HasEncrypterOfEncryptionLevel(ENCRYPTION_HANDSHAKE);
- case APPLICATION_DATA:
- return HasEncrypterOfEncryptionLevel(ENCRYPTION_ZERO_RTT) ||
- HasEncrypterOfEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
- case NUM_PACKET_NUMBER_SPACES:
- break;
- }
- QUIC_BUG(quic_bug_10850_55)
- << ENDPOINT
- << "Try to send data of space: " << PacketNumberSpaceToString(space);
- return false;
-}
-
-EncryptionLevel QuicFramer::GetEncryptionLevelToSendApplicationData() const {
- if (!HasAnEncrypterForSpace(APPLICATION_DATA)) {
- QUIC_BUG(quic_bug_12975_4)
- << "Tried to get encryption level to send application data with no "
- "encrypter available.";
- return NUM_ENCRYPTION_LEVELS;
- }
- if (HasEncrypterOfEncryptionLevel(ENCRYPTION_FORWARD_SECURE)) {
- return ENCRYPTION_FORWARD_SECURE;
- }
- QUICHE_DCHECK(HasEncrypterOfEncryptionLevel(ENCRYPTION_ZERO_RTT));
- return ENCRYPTION_ZERO_RTT;
-}
-
-bool QuicFramer::AppendPacketHeader(const QuicPacketHeader& header,
- QuicDataWriter* writer,
- size_t* length_field_offset) {
- if (version().HasIetfInvariantHeader()) {
- return AppendIetfPacketHeader(header, writer, length_field_offset);
- }
- QUIC_DVLOG(1) << ENDPOINT << "Appending header: " << header;
- uint8_t public_flags = 0;
- if (header.reset_flag) {
- public_flags |= PACKET_PUBLIC_FLAGS_RST;
- }
- if (header.version_flag) {
- public_flags |= PACKET_PUBLIC_FLAGS_VERSION;
- }
-
- public_flags |= GetPacketNumberFlags(header.packet_number_length)
- << kPublicHeaderSequenceNumberShift;
-
- if (header.nonce != nullptr) {
- QUICHE_DCHECK_EQ(Perspective::IS_SERVER, perspective_);
- public_flags |= PACKET_PUBLIC_FLAGS_NONCE;
- }
-
- QuicConnectionId server_connection_id =
- GetServerConnectionIdAsSender(header, perspective_);
- QuicConnectionIdIncluded server_connection_id_included =
- GetServerConnectionIdIncludedAsSender(header, perspective_);
- QUICHE_DCHECK_EQ(CONNECTION_ID_ABSENT,
- GetClientConnectionIdIncludedAsSender(header, perspective_))
- << ENDPOINT << ParsedQuicVersionToString(version_)
- << " invalid header: " << header;
-
- switch (server_connection_id_included) {
- case CONNECTION_ID_ABSENT:
- if (!writer->WriteUInt8(public_flags |
- PACKET_PUBLIC_FLAGS_0BYTE_CONNECTION_ID)) {
- return false;
- }
- break;
- case CONNECTION_ID_PRESENT:
- QUIC_BUG_IF(quic_bug_12975_5,
- !QuicUtils::IsConnectionIdValidForVersion(
- server_connection_id, transport_version()))
- << "AppendPacketHeader: attempted to use connection ID "
- << server_connection_id << " which is invalid with version "
- << version();
-
- public_flags |= PACKET_PUBLIC_FLAGS_8BYTE_CONNECTION_ID;
- if (perspective_ == Perspective::IS_CLIENT) {
- public_flags |= PACKET_PUBLIC_FLAGS_8BYTE_CONNECTION_ID_OLD;
- }
- if (!writer->WriteUInt8(public_flags) ||
- !writer->WriteConnectionId(server_connection_id)) {
- return false;
- }
- break;
- }
- last_serialized_server_connection_id_ = server_connection_id;
-
- if (header.version_flag) {
- QUICHE_DCHECK_EQ(Perspective::IS_CLIENT, perspective_);
- QuicVersionLabel version_label = CreateQuicVersionLabel(version_);
- if (!writer->WriteUInt32(version_label)) {
- return false;
- }
-
- QUIC_DVLOG(1) << ENDPOINT << "label = '"
- << QuicVersionLabelToString(version_label) << "'";
- }
-
- if (header.nonce != nullptr &&
- !writer->WriteBytes(header.nonce, kDiversificationNonceSize)) {
- return false;
- }
-
- if (!AppendPacketNumber(header.packet_number_length, header.packet_number,
- writer)) {
- return false;
- }
-
- return true;
-}
-
-bool QuicFramer::AppendIetfHeaderTypeByte(const QuicPacketHeader& header,
- QuicDataWriter* writer) {
- uint8_t type = 0;
- if (header.version_flag) {
- type = static_cast<uint8_t>(
- FLAGS_LONG_HEADER | FLAGS_FIXED_BIT |
- LongHeaderTypeToOnWireValue(header.long_packet_type, version_) |
- PacketNumberLengthToOnWireValue(header.packet_number_length));
- } else {
- type = static_cast<uint8_t>(
- FLAGS_FIXED_BIT | (current_key_phase_bit_ ? FLAGS_KEY_PHASE_BIT : 0) |
- PacketNumberLengthToOnWireValue(header.packet_number_length));
- }
- return writer->WriteUInt8(type);
-}
-
-bool QuicFramer::AppendIetfPacketHeader(const QuicPacketHeader& header,
- QuicDataWriter* writer,
- size_t* length_field_offset) {
- QUIC_DVLOG(1) << ENDPOINT << "Appending IETF header: " << header;
- QuicConnectionId server_connection_id =
- GetServerConnectionIdAsSender(header, perspective_);
- QUIC_BUG_IF(quic_bug_12975_6, !QuicUtils::IsConnectionIdValidForVersion(
- server_connection_id, transport_version()))
- << "AppendIetfPacketHeader: attempted to use connection ID "
- << server_connection_id << " which is invalid with version " << version();
- if (!AppendIetfHeaderTypeByte(header, writer)) {
- return false;
- }
-
- if (header.version_flag) {
- QUICHE_DCHECK_NE(VERSION_NEGOTIATION, header.long_packet_type)
- << "QuicFramer::AppendIetfPacketHeader does not support sending "
- "version negotiation packets, use "
- "QuicFramer::BuildVersionNegotiationPacket instead "
- << header;
- // Append version for long header.
- QuicVersionLabel version_label = CreateQuicVersionLabel(version_);
- if (!writer->WriteUInt32(version_label)) {
- return false;
- }
- }
-
- // Append connection ID.
- if (!AppendIetfConnectionIds(
- header.version_flag, version_.HasLengthPrefixedConnectionIds(),
- header.destination_connection_id_included != CONNECTION_ID_ABSENT
- ? header.destination_connection_id
- : EmptyQuicConnectionId(),
- header.source_connection_id_included != CONNECTION_ID_ABSENT
- ? header.source_connection_id
- : EmptyQuicConnectionId(),
- writer)) {
- return false;
- }
-
- last_serialized_server_connection_id_ = server_connection_id;
- if (version_.SupportsClientConnectionIds()) {
- last_serialized_client_connection_id_ =
- GetClientConnectionIdAsSender(header, perspective_);
- }
-
- // TODO(b/141924462) Remove this QUIC_BUG once we do support sending RETRY.
- QUIC_BUG_IF(quic_bug_12975_7,
- header.version_flag && header.long_packet_type == RETRY)
- << "Sending IETF RETRY packets is not currently supported " << header;
-
- if (QuicVersionHasLongHeaderLengths(transport_version()) &&
- header.version_flag) {
- if (header.long_packet_type == INITIAL) {
- QUICHE_DCHECK_NE(VARIABLE_LENGTH_INTEGER_LENGTH_0,
- header.retry_token_length_length)
- << ENDPOINT << ParsedQuicVersionToString(version_)
- << " bad retry token length length in header: " << header;
- // Write retry token length.
- if (!writer->WriteVarInt62(header.retry_token.length(),
- header.retry_token_length_length)) {
- return false;
- }
- // Write retry token.
- if (!header.retry_token.empty() &&
- !writer->WriteStringPiece(header.retry_token)) {
- return false;
- }
- }
- if (length_field_offset != nullptr) {
- *length_field_offset = writer->length();
- }
- // Add fake length to reserve two bytes to add length in later.
- writer->WriteVarInt62(256);
- } else if (length_field_offset != nullptr) {
- *length_field_offset = 0;
- }
-
- // Append packet number.
- if (!AppendPacketNumber(header.packet_number_length, header.packet_number,
- writer)) {
- return false;
- }
- last_written_packet_number_length_ = header.packet_number_length;
-
- if (!header.version_flag) {
- return true;
- }
-
- if (header.nonce != nullptr) {
- QUICHE_DCHECK(header.version_flag);
- QUICHE_DCHECK_EQ(ZERO_RTT_PROTECTED, header.long_packet_type);
- QUICHE_DCHECK_EQ(Perspective::IS_SERVER, perspective_);
- if (!writer->WriteBytes(header.nonce, kDiversificationNonceSize)) {
- return false;
- }
- }
-
- return true;
-}
-
-const QuicTime::Delta QuicFramer::CalculateTimestampFromWire(
- uint32_t time_delta_us) {
- // The new time_delta might have wrapped to the next epoch, or it
- // might have reverse wrapped to the previous epoch, or it might
- // remain in the same epoch. Select the time closest to the previous
- // time.
- //
- // epoch_delta is the delta between epochs. A delta is 4 bytes of
- // microseconds.
- const uint64_t epoch_delta = UINT64_C(1) << 32;
- uint64_t epoch = last_timestamp_.ToMicroseconds() & ~(epoch_delta - 1);
- // Wrapping is safe here because a wrapped value will not be ClosestTo below.
- uint64_t prev_epoch = epoch - epoch_delta;
- uint64_t next_epoch = epoch + epoch_delta;
-
- uint64_t time = ClosestTo(
- last_timestamp_.ToMicroseconds(), epoch + time_delta_us,
- ClosestTo(last_timestamp_.ToMicroseconds(), prev_epoch + time_delta_us,
- next_epoch + time_delta_us));
-
- return QuicTime::Delta::FromMicroseconds(time);
-}
-
-uint64_t QuicFramer::CalculatePacketNumberFromWire(
- QuicPacketNumberLength packet_number_length,
- QuicPacketNumber base_packet_number, uint64_t packet_number) const {
- // The new packet number might have wrapped to the next epoch, or
- // it might have reverse wrapped to the previous epoch, or it might
- // remain in the same epoch. Select the packet number closest to the
- // next expected packet number, the previous packet number plus 1.
-
- // epoch_delta is the delta between epochs the packet number was serialized
- // with, so the correct value is likely the same epoch as the last sequence
- // number or an adjacent epoch.
- if (!base_packet_number.IsInitialized()) {
- return packet_number;
- }
- const uint64_t epoch_delta = UINT64_C(1) << (8 * packet_number_length);
- uint64_t next_packet_number = base_packet_number.ToUint64() + 1;
- uint64_t epoch = base_packet_number.ToUint64() & ~(epoch_delta - 1);
- uint64_t prev_epoch = epoch - epoch_delta;
- uint64_t next_epoch = epoch + epoch_delta;
-
- return ClosestTo(next_packet_number, epoch + packet_number,
- ClosestTo(next_packet_number, prev_epoch + packet_number,
- next_epoch + packet_number));
-}
-
-bool QuicFramer::ProcessPublicHeader(QuicDataReader* reader,
- bool packet_has_ietf_packet_header,
- QuicPacketHeader* header) {
- if (packet_has_ietf_packet_header) {
- return ProcessIetfPacketHeader(reader, header);
- }
- uint8_t public_flags;
- if (!reader->ReadBytes(&public_flags, 1)) {
- set_detailed_error("Unable to read public flags.");
- return false;
- }
-
- header->reset_flag = (public_flags & PACKET_PUBLIC_FLAGS_RST) != 0;
- header->version_flag = (public_flags & PACKET_PUBLIC_FLAGS_VERSION) != 0;
-
- if (validate_flags_ && !header->version_flag &&
- public_flags > PACKET_PUBLIC_FLAGS_MAX) {
- set_detailed_error("Illegal public flags value.");
- return false;
- }
-
- if (header->reset_flag && header->version_flag) {
- set_detailed_error("Got version flag in reset packet");
- return false;
- }
-
- QuicConnectionId* header_connection_id = &header->destination_connection_id;
- QuicConnectionIdIncluded* header_connection_id_included =
- &header->destination_connection_id_included;
- if (perspective_ == Perspective::IS_CLIENT) {
- header_connection_id = &header->source_connection_id;
- header_connection_id_included = &header->source_connection_id_included;
- }
- switch (public_flags & PACKET_PUBLIC_FLAGS_8BYTE_CONNECTION_ID) {
- case PACKET_PUBLIC_FLAGS_8BYTE_CONNECTION_ID:
- if (!reader->ReadConnectionId(header_connection_id,
- kQuicDefaultConnectionIdLength)) {
- set_detailed_error("Unable to read ConnectionId.");
- return false;
- }
- *header_connection_id_included = CONNECTION_ID_PRESENT;
- break;
- case PACKET_PUBLIC_FLAGS_0BYTE_CONNECTION_ID:
- *header_connection_id_included = CONNECTION_ID_ABSENT;
- *header_connection_id = last_serialized_server_connection_id_;
- break;
- }
-
- header->packet_number_length = ReadSequenceNumberLength(
- public_flags >> kPublicHeaderSequenceNumberShift);
-
- // Read the version only if the packet is from the client.
- // version flag from the server means version negotiation packet.
- if (header->version_flag && perspective_ == Perspective::IS_SERVER) {
- QuicVersionLabel version_label;
- if (!ProcessVersionLabel(reader, &version_label)) {
- set_detailed_error("Unable to read protocol version.");
- return false;
- }
- // If the version from the new packet is the same as the version of this
- // framer, then the public flags should be set to something we understand.
- // If not, this raises an error.
- ParsedQuicVersion version = ParseQuicVersionLabel(version_label);
- if (version == version_ && public_flags > PACKET_PUBLIC_FLAGS_MAX) {
- set_detailed_error("Illegal public flags value.");
- return false;
- }
- header->version = version;
- }
-
- // A nonce should only be present in packets from the server to the client,
- // which are neither version negotiation nor public reset packets.
- if (public_flags & PACKET_PUBLIC_FLAGS_NONCE &&
- !(public_flags & PACKET_PUBLIC_FLAGS_VERSION) &&
- !(public_flags & PACKET_PUBLIC_FLAGS_RST) &&
- // The nonce flag from a client is ignored and is assumed to be an older
- // client indicating an eight-byte connection ID.
- perspective_ == Perspective::IS_CLIENT) {
- if (!reader->ReadBytes(reinterpret_cast<uint8_t*>(last_nonce_.data()),
- last_nonce_.size())) {
- set_detailed_error("Unable to read nonce.");
- return false;
- }
- header->nonce = &last_nonce_;
- } else {
- header->nonce = nullptr;
- }
-
- return true;
-}
-
-// static
-QuicPacketNumberLength QuicFramer::GetMinPacketNumberLength(
- QuicPacketNumber packet_number) {
- QUICHE_DCHECK(packet_number.IsInitialized());
- if (packet_number < QuicPacketNumber(1 << (PACKET_1BYTE_PACKET_NUMBER * 8))) {
- return PACKET_1BYTE_PACKET_NUMBER;
- } else if (packet_number <
- QuicPacketNumber(1 << (PACKET_2BYTE_PACKET_NUMBER * 8))) {
- return PACKET_2BYTE_PACKET_NUMBER;
- } else if (packet_number <
- QuicPacketNumber(UINT64_C(1)
- << (PACKET_4BYTE_PACKET_NUMBER * 8))) {
- return PACKET_4BYTE_PACKET_NUMBER;
- } else {
- return PACKET_6BYTE_PACKET_NUMBER;
- }
-}
-
-// static
-uint8_t QuicFramer::GetPacketNumberFlags(
- QuicPacketNumberLength packet_number_length) {
- switch (packet_number_length) {
- case PACKET_1BYTE_PACKET_NUMBER:
- return PACKET_FLAGS_1BYTE_PACKET;
- case PACKET_2BYTE_PACKET_NUMBER:
- return PACKET_FLAGS_2BYTE_PACKET;
- case PACKET_4BYTE_PACKET_NUMBER:
- return PACKET_FLAGS_4BYTE_PACKET;
- case PACKET_6BYTE_PACKET_NUMBER:
- case PACKET_8BYTE_PACKET_NUMBER:
- return PACKET_FLAGS_8BYTE_PACKET;
- default:
- QUIC_BUG(quic_bug_10850_56) << "Unreachable case statement.";
- return PACKET_FLAGS_8BYTE_PACKET;
- }
-}
-
-// static
-QuicFramer::AckFrameInfo QuicFramer::GetAckFrameInfo(
- const QuicAckFrame& frame) {
- AckFrameInfo new_ack_info;
- if (frame.packets.Empty()) {
- return new_ack_info;
- }
- // The first block is the last interval. It isn't encoded with the gap-length
- // encoding, so skip it.
- new_ack_info.first_block_length = frame.packets.LastIntervalLength();
- auto itr = frame.packets.rbegin();
- QuicPacketNumber previous_start = itr->min();
- new_ack_info.max_block_length = itr->Length();
- ++itr;
-
- // Don't do any more work after getting information for 256 ACK blocks; any
- // more can't be encoded anyway.
- for (; itr != frame.packets.rend() &&
- new_ack_info.num_ack_blocks < std::numeric_limits<uint8_t>::max();
- previous_start = itr->min(), ++itr) {
- const auto& interval = *itr;
- const QuicPacketCount total_gap = previous_start - interval.max();
- new_ack_info.num_ack_blocks +=
- (total_gap + std::numeric_limits<uint8_t>::max() - 1) /
- std::numeric_limits<uint8_t>::max();
- new_ack_info.max_block_length =
- std::max(new_ack_info.max_block_length, interval.Length());
- }
- return new_ack_info;
-}
-
-bool QuicFramer::ProcessUnauthenticatedHeader(QuicDataReader* encrypted_reader,
- QuicPacketHeader* header) {
- QuicPacketNumber base_packet_number;
- if (supports_multiple_packet_number_spaces_) {
- PacketNumberSpace pn_space = GetPacketNumberSpace(*header);
- if (pn_space == NUM_PACKET_NUMBER_SPACES) {
- set_detailed_error("Unable to determine packet number space.");
- return RaiseError(QUIC_INVALID_PACKET_HEADER);
- }
- base_packet_number = largest_decrypted_packet_numbers_[pn_space];
- } else {
- base_packet_number = largest_packet_number_;
- }
- uint64_t full_packet_number;
- if (!ProcessAndCalculatePacketNumber(
- encrypted_reader, header->packet_number_length, base_packet_number,
- &full_packet_number)) {
- set_detailed_error("Unable to read packet number.");
- return RaiseError(QUIC_INVALID_PACKET_HEADER);
- }
-
- if (!IsValidFullPacketNumber(full_packet_number, version())) {
- set_detailed_error("packet numbers cannot be 0.");
- return RaiseError(QUIC_INVALID_PACKET_HEADER);
- }
- header->packet_number = QuicPacketNumber(full_packet_number);
-
- if (!visitor_->OnUnauthenticatedHeader(*header)) {
- set_detailed_error(
- "Visitor asked to stop processing of unauthenticated header.");
- return false;
- }
- // The function we are in is called because the framer believes that it is
- // processing a packet that uses the non-IETF (i.e. Google QUIC) packet header
- // type. Usually, the framer makes that decision based on the framer's
- // version, but when the framer is used with Perspective::IS_SERVER, then
- // before version negotiation is complete (specifically, before
- // InferPacketHeaderTypeFromVersion is called), this decision is made based on
- // the type byte of the packet.
- //
- // If the framer's version KnowsWhichDecrypterToUse, then that version expects
- // to use the IETF packet header type. If that's the case and we're in this
- // function, then the packet received is invalid: the framer was expecting an
- // IETF packet header and didn't get one.
- if (version().KnowsWhichDecrypterToUse()) {
- set_detailed_error("Invalid public header type for expected version.");
- return RaiseError(QUIC_INVALID_PACKET_HEADER);
- }
- return true;
-}
-
-bool QuicFramer::ProcessIetfHeaderTypeByte(QuicDataReader* reader,
- QuicPacketHeader* header) {
- uint8_t type;
- if (!reader->ReadBytes(&type, 1)) {
- set_detailed_error("Unable to read first byte.");
- return false;
- }
- header->type_byte = type;
- // Determine whether this is a long or short header.
- header->form = GetIetfPacketHeaderFormat(type);
- if (header->form == IETF_QUIC_LONG_HEADER_PACKET) {
- // Version is always present in long headers.
- header->version_flag = true;
- // In versions that do not support client connection IDs, we mark the
- // corresponding connection ID as absent.
- header->destination_connection_id_included =
- (perspective_ == Perspective::IS_SERVER ||
- version_.SupportsClientConnectionIds())
- ? CONNECTION_ID_PRESENT
- : CONNECTION_ID_ABSENT;
- header->source_connection_id_included =
- (perspective_ == Perspective::IS_CLIENT ||
- version_.SupportsClientConnectionIds())
- ? CONNECTION_ID_PRESENT
- : CONNECTION_ID_ABSENT;
- // Read version tag.
- QuicVersionLabel version_label;
- if (!ProcessVersionLabel(reader, &version_label)) {
- set_detailed_error("Unable to read protocol version.");
- return false;
- }
- if (!version_label) {
- // Version label is 0 indicating this is a version negotiation packet.
- header->long_packet_type = VERSION_NEGOTIATION;
- } else {
- header->version = ParseQuicVersionLabel(version_label);
- if (header->version.IsKnown()) {
- if (!(type & FLAGS_FIXED_BIT)) {
- set_detailed_error("Fixed bit is 0 in long header.");
- return false;
- }
- header->long_packet_type = GetLongHeaderType(type, header->version);
- switch (header->long_packet_type) {
- case INVALID_PACKET_TYPE:
- set_detailed_error("Illegal long header type value.");
- return false;
- case RETRY:
- if (!version().SupportsRetry()) {
- set_detailed_error("RETRY not supported in this version.");
- return false;
- }
- if (perspective_ == Perspective::IS_SERVER) {
- set_detailed_error("Client-initiated RETRY is invalid.");
- return false;
- }
- break;
- default:
- if (!header->version.HasHeaderProtection()) {
- header->packet_number_length =
- GetLongHeaderPacketNumberLength(type);
- }
- break;
- }
- }
- }
-
- QUIC_DVLOG(1) << ENDPOINT << "Received IETF long header: "
- << QuicUtils::QuicLongHeaderTypetoString(
- header->long_packet_type);
- return true;
- }
-
- QUIC_DVLOG(1) << ENDPOINT << "Received IETF short header";
- // Version is not present in short headers.
- header->version_flag = false;
- // In versions that do not support client connection IDs, the client will not
- // receive destination connection IDs.
- header->destination_connection_id_included =
- (perspective_ == Perspective::IS_SERVER ||
- version_.SupportsClientConnectionIds())
- ? CONNECTION_ID_PRESENT
- : CONNECTION_ID_ABSENT;
- header->source_connection_id_included = CONNECTION_ID_ABSENT;
- if (!(type & FLAGS_FIXED_BIT)) {
- set_detailed_error("Fixed bit is 0 in short header.");
- return false;
- }
- if (!version_.HasHeaderProtection()) {
- header->packet_number_length = GetShortHeaderPacketNumberLength(type);
- }
- QUIC_DVLOG(1) << "packet_number_length = " << header->packet_number_length;
- return true;
-}
-
-// static
-bool QuicFramer::ProcessVersionLabel(QuicDataReader* reader,
- QuicVersionLabel* version_label) {
- if (!reader->ReadUInt32(version_label)) {
- return false;
- }
- return true;
-}
-
-// static
-bool QuicFramer::ProcessAndValidateIetfConnectionIdLength(
- QuicDataReader* reader, ParsedQuicVersion version, Perspective perspective,
- bool should_update_expected_server_connection_id_length,
- uint8_t* expected_server_connection_id_length,
- uint8_t* destination_connection_id_length,
- uint8_t* source_connection_id_length, std::string* detailed_error) {
- uint8_t connection_id_lengths_byte;
- if (!reader->ReadBytes(&connection_id_lengths_byte, 1)) {
- *detailed_error = "Unable to read ConnectionId length.";
- return false;
- }
- uint8_t dcil =
- (connection_id_lengths_byte & kDestinationConnectionIdLengthMask) >> 4;
- if (dcil != 0) {
- dcil += kConnectionIdLengthAdjustment;
- }
- uint8_t scil = connection_id_lengths_byte & kSourceConnectionIdLengthMask;
- if (scil != 0) {
- scil += kConnectionIdLengthAdjustment;
- }
- if (should_update_expected_server_connection_id_length) {
- uint8_t server_connection_id_length =
- perspective == Perspective::IS_SERVER ? dcil : scil;
- if (*expected_server_connection_id_length != server_connection_id_length) {
- QUIC_DVLOG(1) << "Updating expected_server_connection_id_length: "
- << static_cast<int>(*expected_server_connection_id_length)
- << " -> " << static_cast<int>(server_connection_id_length);
- *expected_server_connection_id_length = server_connection_id_length;
- }
- }
- if (!should_update_expected_server_connection_id_length &&
- (dcil != *destination_connection_id_length ||
- scil != *source_connection_id_length) &&
- version.IsKnown() && !version.AllowsVariableLengthConnectionIds()) {
- QUIC_DVLOG(1) << "dcil: " << static_cast<uint32_t>(dcil)
- << ", scil: " << static_cast<uint32_t>(scil);
- *detailed_error = "Invalid ConnectionId length.";
- return false;
- }
- *destination_connection_id_length = dcil;
- *source_connection_id_length = scil;
- return true;
-}
-
-bool QuicFramer::ValidateReceivedConnectionIds(const QuicPacketHeader& header) {
- bool skip_server_connection_id_validation =
- perspective_ == Perspective::IS_CLIENT &&
- header.form == IETF_QUIC_SHORT_HEADER_PACKET;
- if (!skip_server_connection_id_validation &&
- !QuicUtils::IsConnectionIdValidForVersion(
- GetServerConnectionIdAsRecipient(header, perspective_),
- transport_version())) {
- set_detailed_error("Received server connection ID with invalid length.");
- return false;
- }
-
- bool skip_client_connection_id_validation =
- perspective_ == Perspective::IS_SERVER &&
- header.form == IETF_QUIC_SHORT_HEADER_PACKET;
- if (!skip_client_connection_id_validation &&
- version_.SupportsClientConnectionIds() &&
- !QuicUtils::IsConnectionIdValidForVersion(
- GetClientConnectionIdAsRecipient(header, perspective_),
- transport_version())) {
- set_detailed_error("Received client connection ID with invalid length.");
- return false;
- }
- return true;
-}
-
-bool QuicFramer::ProcessIetfPacketHeader(QuicDataReader* reader,
- QuicPacketHeader* header) {
- if (version_.HasLengthPrefixedConnectionIds()) {
- uint8_t expected_destination_connection_id_length =
- perspective_ == Perspective::IS_CLIENT
- ? expected_client_connection_id_length_
- : expected_server_connection_id_length_;
- QuicVersionLabel version_label;
- bool has_length_prefix;
- std::string detailed_error;
- QuicErrorCode parse_result = QuicFramer::ParsePublicHeader(
- reader, expected_destination_connection_id_length,
- version_.HasIetfInvariantHeader(), &header->type_byte, &header->form,
- &header->version_flag, &has_length_prefix, &version_label,
- &header->version, &header->destination_connection_id,
- &header->source_connection_id, &header->long_packet_type,
- &header->retry_token_length_length, &header->retry_token,
- &detailed_error);
- if (parse_result != QUIC_NO_ERROR) {
- set_detailed_error(detailed_error);
- return false;
- }
- header->destination_connection_id_included = CONNECTION_ID_PRESENT;
- header->source_connection_id_included =
- header->version_flag ? CONNECTION_ID_PRESENT : CONNECTION_ID_ABSENT;
-
- if (!ValidateReceivedConnectionIds(*header)) {
- return false;
- }
-
- if (header->version_flag &&
- header->long_packet_type != VERSION_NEGOTIATION &&
- !(header->type_byte & FLAGS_FIXED_BIT)) {
- set_detailed_error("Fixed bit is 0 in long header.");
- return false;
- }
- if (!header->version_flag && !(header->type_byte & FLAGS_FIXED_BIT)) {
- set_detailed_error("Fixed bit is 0 in short header.");
- return false;
- }
- if (!header->version_flag) {
- if (!version_.HasHeaderProtection()) {
- header->packet_number_length =
- GetShortHeaderPacketNumberLength(header->type_byte);
- }
- return true;
- }
- if (header->long_packet_type == RETRY) {
- if (!version().SupportsRetry()) {
- set_detailed_error("RETRY not supported in this version.");
- return false;
- }
- if (perspective_ == Perspective::IS_SERVER) {
- set_detailed_error("Client-initiated RETRY is invalid.");
- return false;
- }
- return true;
- }
- if (header->version.IsKnown() && !header->version.HasHeaderProtection()) {
- header->packet_number_length =
- GetLongHeaderPacketNumberLength(header->type_byte);
- }
-
- return true;
- }
-
- if (!ProcessIetfHeaderTypeByte(reader, header)) {
- return false;
- }
-
- uint8_t destination_connection_id_length =
- header->destination_connection_id_included == CONNECTION_ID_PRESENT
- ? (perspective_ == Perspective::IS_SERVER
- ? expected_server_connection_id_length_
- : expected_client_connection_id_length_)
- : 0;
- uint8_t source_connection_id_length =
- header->source_connection_id_included == CONNECTION_ID_PRESENT
- ? (perspective_ == Perspective::IS_CLIENT
- ? expected_server_connection_id_length_
- : expected_client_connection_id_length_)
- : 0;
- if (header->form == IETF_QUIC_LONG_HEADER_PACKET) {
- if (!ProcessAndValidateIetfConnectionIdLength(
- reader, header->version, perspective_,
- /*should_update_expected_server_connection_id_length=*/false,
- &expected_server_connection_id_length_,
- &destination_connection_id_length, &source_connection_id_length,
- &detailed_error_)) {
- return false;
- }
- }
-
- // Read connection ID.
- if (!reader->ReadConnectionId(&header->destination_connection_id,
- destination_connection_id_length)) {
- set_detailed_error("Unable to read destination connection ID.");
- return false;
- }
-
- if (!reader->ReadConnectionId(&header->source_connection_id,
- source_connection_id_length)) {
- set_detailed_error("Unable to read source connection ID.");
- return false;
- }
-
- if (header->source_connection_id_included == CONNECTION_ID_ABSENT) {
- if (!header->source_connection_id.IsEmpty()) {
- QUICHE_DCHECK(!version_.SupportsClientConnectionIds());
- set_detailed_error("Client connection ID not supported in this version.");
- return false;
- }
- }
-
- return ValidateReceivedConnectionIds(*header);
-}
-
-bool QuicFramer::ProcessAndCalculatePacketNumber(
- QuicDataReader* reader, QuicPacketNumberLength packet_number_length,
- QuicPacketNumber base_packet_number, uint64_t* packet_number) {
- uint64_t wire_packet_number;
- if (!reader->ReadBytesToUInt64(packet_number_length, &wire_packet_number)) {
- return false;
- }
-
- // TODO(ianswett): Explore the usefulness of trying multiple packet numbers
- // in case the first guess is incorrect.
- *packet_number = CalculatePacketNumberFromWire(
- packet_number_length, base_packet_number, wire_packet_number);
- return true;
-}
-
-bool QuicFramer::ProcessFrameData(QuicDataReader* reader,
- const QuicPacketHeader& header) {
- QUICHE_DCHECK(!VersionHasIetfQuicFrames(version_.transport_version))
- << "IETF QUIC Framing negotiated but attempting to process frames as "
- "non-IETF QUIC.";
- if (reader->IsDoneReading()) {
- set_detailed_error("Packet has no frames.");
- return RaiseError(QUIC_MISSING_PAYLOAD);
- }
- QUIC_DVLOG(2) << ENDPOINT << "Processing packet with header " << header;
- while (!reader->IsDoneReading()) {
- uint8_t frame_type;
- if (!reader->ReadBytes(&frame_type, 1)) {
- set_detailed_error("Unable to read frame type.");
- return RaiseError(QUIC_INVALID_FRAME_DATA);
- }
- const uint8_t special_mask = version_.HasIetfInvariantHeader()
- ? kQuicFrameTypeSpecialMask
- : kQuicFrameTypeBrokenMask;
- if (frame_type & special_mask) {
- // Stream Frame
- if (frame_type & kQuicFrameTypeStreamMask) {
- QuicStreamFrame frame;
- if (!ProcessStreamFrame(reader, frame_type, &frame)) {
- return RaiseError(QUIC_INVALID_STREAM_DATA);
- }
- QUIC_DVLOG(2) << ENDPOINT << "Processing stream frame " << frame;
- if (!visitor_->OnStreamFrame(frame)) {
- QUIC_DVLOG(1) << ENDPOINT
- << "Visitor asked to stop further processing.";
- // Returning true since there was no parsing error.
- return true;
- }
- continue;
- }
-
- // Ack Frame
- if (frame_type & kQuicFrameTypeAckMask) {
- if (!ProcessAckFrame(reader, frame_type)) {
- return RaiseError(QUIC_INVALID_ACK_DATA);
- }
- QUIC_DVLOG(2) << ENDPOINT << "Processing ACK frame";
- continue;
- }
-
- // This was a special frame type that did not match any
- // of the known ones. Error.
- set_detailed_error("Illegal frame type.");
- QUIC_DLOG(WARNING) << ENDPOINT << "Illegal frame type: "
- << static_cast<int>(frame_type);
- return RaiseError(QUIC_INVALID_FRAME_DATA);
- }
-
- switch (frame_type) {
- case PADDING_FRAME: {
- QuicPaddingFrame frame;
- ProcessPaddingFrame(reader, &frame);
- QUIC_DVLOG(2) << ENDPOINT << "Processing padding frame " << frame;
- if (!visitor_->OnPaddingFrame(frame)) {
- QUIC_DVLOG(1) << "Visitor asked to stop further processing.";
- // Returning true since there was no parsing error.
- return true;
- }
- continue;
- }
-
- case RST_STREAM_FRAME: {
- QuicRstStreamFrame frame;
- if (!ProcessRstStreamFrame(reader, &frame)) {
- return RaiseError(QUIC_INVALID_RST_STREAM_DATA);
- }
- QUIC_DVLOG(2) << ENDPOINT << "Processing reset stream frame " << frame;
- if (!visitor_->OnRstStreamFrame(frame)) {
- QUIC_DVLOG(1) << "Visitor asked to stop further processing.";
- // Returning true since there was no parsing error.
- return true;
- }
- continue;
- }
-
- case CONNECTION_CLOSE_FRAME: {
- QuicConnectionCloseFrame frame;
- if (!ProcessConnectionCloseFrame(reader, &frame)) {
- return RaiseError(QUIC_INVALID_CONNECTION_CLOSE_DATA);
- }
-
- QUIC_DVLOG(2) << ENDPOINT << "Processing connection close frame "
- << frame;
- if (!visitor_->OnConnectionCloseFrame(frame)) {
- QUIC_DVLOG(1) << ENDPOINT
- << "Visitor asked to stop further processing.";
- // Returning true since there was no parsing error.
- return true;
- }
- continue;
- }
-
- case GOAWAY_FRAME: {
- QuicGoAwayFrame goaway_frame;
- if (!ProcessGoAwayFrame(reader, &goaway_frame)) {
- return RaiseError(QUIC_INVALID_GOAWAY_DATA);
- }
- QUIC_DVLOG(2) << ENDPOINT << "Processing go away frame "
- << goaway_frame;
- if (!visitor_->OnGoAwayFrame(goaway_frame)) {
- QUIC_DVLOG(1) << ENDPOINT
- << "Visitor asked to stop further processing.";
- // Returning true since there was no parsing error.
- return true;
- }
- continue;
- }
-
- case WINDOW_UPDATE_FRAME: {
- QuicWindowUpdateFrame window_update_frame;
- if (!ProcessWindowUpdateFrame(reader, &window_update_frame)) {
- return RaiseError(QUIC_INVALID_WINDOW_UPDATE_DATA);
- }
- QUIC_DVLOG(2) << ENDPOINT << "Processing window update frame "
- << window_update_frame;
- if (!visitor_->OnWindowUpdateFrame(window_update_frame)) {
- QUIC_DVLOG(1) << ENDPOINT
- << "Visitor asked to stop further processing.";
- // Returning true since there was no parsing error.
- return true;
- }
- continue;
- }
-
- case BLOCKED_FRAME: {
- QuicBlockedFrame blocked_frame;
- if (!ProcessBlockedFrame(reader, &blocked_frame)) {
- return RaiseError(QUIC_INVALID_BLOCKED_DATA);
- }
- QUIC_DVLOG(2) << ENDPOINT << "Processing blocked frame "
- << blocked_frame;
- if (!visitor_->OnBlockedFrame(blocked_frame)) {
- QUIC_DVLOG(1) << ENDPOINT
- << "Visitor asked to stop further processing.";
- // Returning true since there was no parsing error.
- return true;
- }
- continue;
- }
-
- case STOP_WAITING_FRAME: {
- QuicStopWaitingFrame stop_waiting_frame;
- if (!ProcessStopWaitingFrame(reader, header, &stop_waiting_frame)) {
- return RaiseError(QUIC_INVALID_STOP_WAITING_DATA);
- }
- QUIC_DVLOG(2) << ENDPOINT << "Processing stop waiting frame "
- << stop_waiting_frame;
- if (!visitor_->OnStopWaitingFrame(stop_waiting_frame)) {
- QUIC_DVLOG(1) << ENDPOINT
- << "Visitor asked to stop further processing.";
- // Returning true since there was no parsing error.
- return true;
- }
- continue;
- }
- case PING_FRAME: {
- // Ping has no payload.
- QuicPingFrame ping_frame;
- if (!visitor_->OnPingFrame(ping_frame)) {
- QUIC_DVLOG(1) << ENDPOINT
- << "Visitor asked to stop further processing.";
- // Returning true since there was no parsing error.
- return true;
- }
- QUIC_DVLOG(2) << ENDPOINT << "Processing ping frame " << ping_frame;
- continue;
- }
- case IETF_EXTENSION_MESSAGE_NO_LENGTH:
- ABSL_FALLTHROUGH_INTENDED;
- case IETF_EXTENSION_MESSAGE: {
- QuicMessageFrame message_frame;
- if (!ProcessMessageFrame(reader,
- frame_type == IETF_EXTENSION_MESSAGE_NO_LENGTH,
- &message_frame)) {
- return RaiseError(QUIC_INVALID_MESSAGE_DATA);
- }
- QUIC_DVLOG(2) << ENDPOINT << "Processing message frame "
- << message_frame;
- if (!visitor_->OnMessageFrame(message_frame)) {
- QUIC_DVLOG(1) << ENDPOINT
- << "Visitor asked to stop further processing.";
- // Returning true since there was no parsing error.
- return true;
- }
- break;
- }
- case CRYPTO_FRAME: {
- if (!QuicVersionUsesCryptoFrames(version_.transport_version)) {
- set_detailed_error("Illegal frame type.");
- return RaiseError(QUIC_INVALID_FRAME_DATA);
- }
- QuicCryptoFrame frame;
- if (!ProcessCryptoFrame(reader, GetEncryptionLevel(header), &frame)) {
- return RaiseError(QUIC_INVALID_FRAME_DATA);
- }
- QUIC_DVLOG(2) << ENDPOINT << "Processing crypto frame " << frame;
- if (!visitor_->OnCryptoFrame(frame)) {
- QUIC_DVLOG(1) << "Visitor asked to stop further processing.";
- // Returning true since there was no parsing error.
- return true;
- }
- break;
- }
- case HANDSHAKE_DONE_FRAME: {
- // HANDSHAKE_DONE has no payload.
- QuicHandshakeDoneFrame handshake_done_frame;
- QUIC_DVLOG(2) << ENDPOINT << "Processing handshake done frame "
- << handshake_done_frame;
- if (!visitor_->OnHandshakeDoneFrame(handshake_done_frame)) {
- QUIC_DVLOG(1) << ENDPOINT
- << "Visitor asked to stop further processing.";
- // Returning true since there was no parsing error.
- return true;
- }
- break;
- }
-
- default:
- set_detailed_error("Illegal frame type.");
- QUIC_DLOG(WARNING) << ENDPOINT << "Illegal frame type: "
- << static_cast<int>(frame_type);
- return RaiseError(QUIC_INVALID_FRAME_DATA);
- }
- }
-
- return true;
-}
-
-// static
-bool QuicFramer::IsIetfFrameTypeExpectedForEncryptionLevel(
- uint64_t frame_type, EncryptionLevel level) {
- switch (level) {
- case ENCRYPTION_INITIAL:
- case ENCRYPTION_HANDSHAKE:
- return frame_type == IETF_CRYPTO || frame_type == IETF_ACK ||
- frame_type == IETF_ACK_ECN ||
- frame_type == IETF_ACK_RECEIVE_TIMESTAMPS ||
- frame_type == IETF_PING || frame_type == IETF_PADDING ||
- frame_type == IETF_CONNECTION_CLOSE;
- 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_NEW_TOKEN ||
- frame_type == IETF_PATH_RESPONSE ||
- frame_type == IETF_RETIRE_CONNECTION_ID);
- case ENCRYPTION_FORWARD_SECURE:
- return true;
- default:
- QUIC_BUG(quic_bug_10850_57) << "Unknown encryption level: " << level;
- }
- return false;
-}
-
-bool QuicFramer::ProcessIetfFrameData(QuicDataReader* reader,
- const QuicPacketHeader& header,
- EncryptionLevel decrypted_level) {
- QUICHE_DCHECK(VersionHasIetfQuicFrames(version_.transport_version))
- << "Attempt to process frames as IETF frames but version ("
- << version_.transport_version << ") does not support IETF Framing.";
-
- if (reader->IsDoneReading()) {
- set_detailed_error("Packet has no frames.");
- return RaiseError(QUIC_MISSING_PAYLOAD);
- }
-
- QUIC_DVLOG(2) << ENDPOINT << "Processing IETF packet with header " << header;
- while (!reader->IsDoneReading()) {
- uint64_t frame_type;
- // Will be the number of bytes into which frame_type was encoded.
- size_t encoded_bytes = reader->BytesRemaining();
- if (!reader->ReadVarInt62(&frame_type)) {
- set_detailed_error("Unable to read frame type.");
- return RaiseError(QUIC_INVALID_FRAME_DATA);
- }
- if (!IsIetfFrameTypeExpectedForEncryptionLevel(frame_type,
- decrypted_level)) {
- set_detailed_error(absl::StrCat(
- "IETF frame type ",
- QuicIetfFrameTypeString(static_cast<QuicIetfFrameType>(frame_type)),
- " is unexpected at encryption level ",
- EncryptionLevelToString(decrypted_level)));
- return RaiseError(IETF_QUIC_PROTOCOL_VIOLATION);
- }
- previously_received_frame_type_ = current_received_frame_type_;
- current_received_frame_type_ = frame_type;
-
- // Is now the number of bytes into which the frame type was encoded.
- encoded_bytes -= reader->BytesRemaining();
-
- // Check that the frame type is minimally encoded.
- if (encoded_bytes !=
- static_cast<size_t>(QuicDataWriter::GetVarInt62Len(frame_type))) {
- // The frame type was not minimally encoded.
- set_detailed_error("Frame type not minimally encoded.");
- return RaiseError(IETF_QUIC_PROTOCOL_VIOLATION);
- }
-
- if (IS_IETF_STREAM_FRAME(frame_type)) {
- QuicStreamFrame frame;
- if (!ProcessIetfStreamFrame(reader, frame_type, &frame)) {
- return RaiseError(QUIC_INVALID_STREAM_DATA);
- }
- QUIC_DVLOG(2) << ENDPOINT << "Processing IETF stream frame " << frame;
- if (!visitor_->OnStreamFrame(frame)) {
- QUIC_DVLOG(1) << ENDPOINT
- << "Visitor asked to stop further processing.";
- // Returning true since there was no parsing error.
- return true;
- }
- } else {
- switch (frame_type) {
- case IETF_PADDING: {
- QuicPaddingFrame frame;
- ProcessPaddingFrame(reader, &frame);
- QUIC_DVLOG(2) << ENDPOINT << "Processing IETF padding frame "
- << frame;
- if (!visitor_->OnPaddingFrame(frame)) {
- QUIC_DVLOG(1) << "Visitor asked to stop further processing.";
- // Returning true since there was no parsing error.
- return true;
- }
- break;
- }
- case IETF_RST_STREAM: {
- QuicRstStreamFrame frame;
- if (!ProcessIetfResetStreamFrame(reader, &frame)) {
- return RaiseError(QUIC_INVALID_RST_STREAM_DATA);
- }
- QUIC_DVLOG(2) << ENDPOINT << "Processing IETF reset stream frame "
- << frame;
- if (!visitor_->OnRstStreamFrame(frame)) {
- QUIC_DVLOG(1) << "Visitor asked to stop further processing.";
- // Returning true since there was no parsing error.
- return true;
- }
- break;
- }
- case IETF_APPLICATION_CLOSE:
- case IETF_CONNECTION_CLOSE: {
- QuicConnectionCloseFrame frame;
- if (!ProcessIetfConnectionCloseFrame(
- reader,
- (frame_type == IETF_CONNECTION_CLOSE)
- ? IETF_QUIC_TRANSPORT_CONNECTION_CLOSE
- : IETF_QUIC_APPLICATION_CONNECTION_CLOSE,
- &frame)) {
- return RaiseError(QUIC_INVALID_CONNECTION_CLOSE_DATA);
- }
- QUIC_DVLOG(2) << ENDPOINT << "Processing IETF connection close frame "
- << frame;
- if (!visitor_->OnConnectionCloseFrame(frame)) {
- QUIC_DVLOG(1) << "Visitor asked to stop further processing.";
- // Returning true since there was no parsing error.
- return true;
- }
- break;
- }
- case IETF_MAX_DATA: {
- QuicWindowUpdateFrame frame;
- if (!ProcessMaxDataFrame(reader, &frame)) {
- return RaiseError(QUIC_INVALID_MAX_DATA_FRAME_DATA);
- }
- QUIC_DVLOG(2) << ENDPOINT << "Processing IETF max data frame "
- << frame;
- if (!visitor_->OnWindowUpdateFrame(frame)) {
- QUIC_DVLOG(1) << "Visitor asked to stop further processing.";
- // Returning true since there was no parsing error.
- return true;
- }
- break;
- }
- case IETF_MAX_STREAM_DATA: {
- QuicWindowUpdateFrame frame;
- if (!ProcessMaxStreamDataFrame(reader, &frame)) {
- return RaiseError(QUIC_INVALID_MAX_STREAM_DATA_FRAME_DATA);
- }
- QUIC_DVLOG(2) << ENDPOINT << "Processing IETF max stream data frame "
- << frame;
- if (!visitor_->OnWindowUpdateFrame(frame)) {
- QUIC_DVLOG(1) << "Visitor asked to stop further processing.";
- // Returning true since there was no parsing error.
- return true;
- }
- break;
- }
- case IETF_MAX_STREAMS_BIDIRECTIONAL:
- case IETF_MAX_STREAMS_UNIDIRECTIONAL: {
- QuicMaxStreamsFrame frame;
- if (!ProcessMaxStreamsFrame(reader, &frame, frame_type)) {
- return RaiseError(QUIC_MAX_STREAMS_DATA);
- }
- QUIC_CODE_COUNT_N(quic_max_streams_received, 1, 2);
- QUIC_DVLOG(2) << ENDPOINT << "Processing IETF max streams frame "
- << frame;
- if (!visitor_->OnMaxStreamsFrame(frame)) {
- QUIC_DVLOG(1) << "Visitor asked to stop further processing.";
- // Returning true since there was no parsing error.
- return true;
- }
- break;
- }
- case IETF_PING: {
- // Ping has no payload.
- QuicPingFrame ping_frame;
- QUIC_DVLOG(2) << ENDPOINT << "Processing IETF ping frame "
- << ping_frame;
- if (!visitor_->OnPingFrame(ping_frame)) {
- QUIC_DVLOG(1) << "Visitor asked to stop further processing.";
- // Returning true since there was no parsing error.
- return true;
- }
- break;
- }
- case IETF_DATA_BLOCKED: {
- QuicBlockedFrame frame;
- if (!ProcessDataBlockedFrame(reader, &frame)) {
- return RaiseError(QUIC_INVALID_BLOCKED_DATA);
- }
- QUIC_DVLOG(2) << ENDPOINT << "Processing IETF blocked frame "
- << frame;
- if (!visitor_->OnBlockedFrame(frame)) {
- QUIC_DVLOG(1) << "Visitor asked to stop further processing.";
- // Returning true since there was no parsing error.
- return true;
- }
- break;
- }
- case IETF_STREAM_DATA_BLOCKED: {
- QuicBlockedFrame frame;
- if (!ProcessStreamDataBlockedFrame(reader, &frame)) {
- return RaiseError(QUIC_INVALID_STREAM_BLOCKED_DATA);
- }
- QUIC_DVLOG(2) << ENDPOINT << "Processing IETF stream blocked frame "
- << frame;
- if (!visitor_->OnBlockedFrame(frame)) {
- QUIC_DVLOG(1) << "Visitor asked to stop further processing.";
- // Returning true since there was no parsing error.
- return true;
- }
- break;
- }
- case IETF_STREAMS_BLOCKED_UNIDIRECTIONAL:
- case IETF_STREAMS_BLOCKED_BIDIRECTIONAL: {
- QuicStreamsBlockedFrame frame;
- if (!ProcessStreamsBlockedFrame(reader, &frame, frame_type)) {
- return RaiseError(QUIC_STREAMS_BLOCKED_DATA);
- }
- QUIC_DVLOG(2) << ENDPOINT << "Processing IETF streams blocked frame "
- << frame;
- if (!visitor_->OnStreamsBlockedFrame(frame)) {
- QUIC_DVLOG(1) << "Visitor asked to stop further processing.";
- // Returning true since there was no parsing error.
- return true;
- }
- break;
- }
- case IETF_NEW_CONNECTION_ID: {
- QuicNewConnectionIdFrame frame;
- if (!ProcessNewConnectionIdFrame(reader, &frame)) {
- return RaiseError(QUIC_INVALID_NEW_CONNECTION_ID_DATA);
- }
- QUIC_DVLOG(2) << ENDPOINT
- << "Processing IETF new connection ID frame " << frame;
- if (!visitor_->OnNewConnectionIdFrame(frame)) {
- QUIC_DVLOG(1) << "Visitor asked to stop further processing.";
- // Returning true since there was no parsing error.
- return true;
- }
- break;
- }
- case IETF_RETIRE_CONNECTION_ID: {
- QuicRetireConnectionIdFrame frame;
- if (!ProcessRetireConnectionIdFrame(reader, &frame)) {
- return RaiseError(QUIC_INVALID_RETIRE_CONNECTION_ID_DATA);
- }
- QUIC_DVLOG(2) << ENDPOINT
- << "Processing IETF retire connection ID frame "
- << frame;
- if (!visitor_->OnRetireConnectionIdFrame(frame)) {
- QUIC_DVLOG(1) << "Visitor asked to stop further processing.";
- // Returning true since there was no parsing error.
- return true;
- }
- break;
- }
- case IETF_NEW_TOKEN: {
- QuicNewTokenFrame frame;
- if (!ProcessNewTokenFrame(reader, &frame)) {
- return RaiseError(QUIC_INVALID_NEW_TOKEN);
- }
- QUIC_DVLOG(2) << ENDPOINT << "Processing IETF new token frame "
- << frame;
- if (!visitor_->OnNewTokenFrame(frame)) {
- QUIC_DVLOG(1) << "Visitor asked to stop further processing.";
- // Returning true since there was no parsing error.
- return true;
- }
- break;
- }
- case IETF_STOP_SENDING: {
- QuicStopSendingFrame frame;
- if (!ProcessStopSendingFrame(reader, &frame)) {
- return RaiseError(QUIC_INVALID_STOP_SENDING_FRAME_DATA);
- }
- QUIC_DVLOG(2) << ENDPOINT << "Processing IETF stop sending frame "
- << frame;
- if (!visitor_->OnStopSendingFrame(frame)) {
- QUIC_DVLOG(1) << "Visitor asked to stop further processing.";
- // Returning true since there was no parsing error.
- return true;
- }
- break;
- }
- case IETF_ACK_RECEIVE_TIMESTAMPS:
- if (!process_timestamps_) {
- set_detailed_error("Unsupported frame type.");
- QUIC_DLOG(WARNING)
- << ENDPOINT << "IETF_ACK_RECEIVE_TIMESTAMPS not supported";
- return RaiseError(QUIC_INVALID_FRAME_DATA);
- }
- ABSL_FALLTHROUGH_INTENDED;
- case IETF_ACK_ECN:
- case IETF_ACK: {
- QuicAckFrame frame;
- if (!ProcessIetfAckFrame(reader, frame_type, &frame)) {
- return RaiseError(QUIC_INVALID_ACK_DATA);
- }
- QUIC_DVLOG(2) << ENDPOINT << "Processing IETF ACK frame " << frame;
- break;
- }
- case IETF_PATH_CHALLENGE: {
- QuicPathChallengeFrame frame;
- if (!ProcessPathChallengeFrame(reader, &frame)) {
- return RaiseError(QUIC_INVALID_PATH_CHALLENGE_DATA);
- }
- QUIC_DVLOG(2) << ENDPOINT << "Processing IETF path challenge frame "
- << frame;
- if (!visitor_->OnPathChallengeFrame(frame)) {
- QUIC_DVLOG(1) << "Visitor asked to stop further processing.";
- // Returning true since there was no parsing error.
- return true;
- }
- break;
- }
- case IETF_PATH_RESPONSE: {
- QuicPathResponseFrame frame;
- if (!ProcessPathResponseFrame(reader, &frame)) {
- return RaiseError(QUIC_INVALID_PATH_RESPONSE_DATA);
- }
- QUIC_DVLOG(2) << ENDPOINT << "Processing IETF path response frame "
- << frame;
- if (!visitor_->OnPathResponseFrame(frame)) {
- QUIC_DVLOG(1) << "Visitor asked to stop further processing.";
- // Returning true since there was no parsing error.
- return true;
- }
- break;
- }
- case IETF_EXTENSION_MESSAGE_NO_LENGTH_V99:
- ABSL_FALLTHROUGH_INTENDED;
- case IETF_EXTENSION_MESSAGE_V99: {
- QuicMessageFrame message_frame;
- if (!ProcessMessageFrame(
- reader, frame_type == IETF_EXTENSION_MESSAGE_NO_LENGTH_V99,
- &message_frame)) {
- return RaiseError(QUIC_INVALID_MESSAGE_DATA);
- }
- QUIC_DVLOG(2) << ENDPOINT << "Processing IETF message frame "
- << message_frame;
- if (!visitor_->OnMessageFrame(message_frame)) {
- QUIC_DVLOG(1) << ENDPOINT
- << "Visitor asked to stop further processing.";
- // Returning true since there was no parsing error.
- return true;
- }
- break;
- }
- case IETF_CRYPTO: {
- QuicCryptoFrame frame;
- if (!ProcessCryptoFrame(reader, GetEncryptionLevel(header), &frame)) {
- return RaiseError(QUIC_INVALID_FRAME_DATA);
- }
- QUIC_DVLOG(2) << ENDPOINT << "Processing IETF crypto frame " << frame;
- if (!visitor_->OnCryptoFrame(frame)) {
- QUIC_DVLOG(1) << "Visitor asked to stop further processing.";
- // Returning true since there was no parsing error.
- return true;
- }
- break;
- }
- case IETF_HANDSHAKE_DONE: {
- // HANDSHAKE_DONE has no payload.
- QuicHandshakeDoneFrame handshake_done_frame;
- if (!visitor_->OnHandshakeDoneFrame(handshake_done_frame)) {
- QUIC_DVLOG(1) << ENDPOINT
- << "Visitor asked to stop further processing.";
- // Returning true since there was no parsing error.
- return true;
- }
- QUIC_DVLOG(2) << ENDPOINT << "Processing handshake done frame "
- << handshake_done_frame;
- break;
- }
- case IETF_ACK_FREQUENCY: {
- QuicAckFrequencyFrame frame;
- if (!ProcessAckFrequencyFrame(reader, &frame)) {
- return RaiseError(QUIC_INVALID_FRAME_DATA);
- }
- QUIC_DVLOG(2) << ENDPOINT << "Processing IETF ack frequency frame "
- << frame;
- if (!visitor_->OnAckFrequencyFrame(frame)) {
- QUIC_DVLOG(1) << "Visitor asked to stop further processing.";
- // Returning true since there was no parsing error.
- return true;
- }
- break;
- }
- default:
- set_detailed_error("Illegal frame type.");
- QUIC_DLOG(WARNING)
- << ENDPOINT
- << "Illegal frame type: " << static_cast<int>(frame_type);
- return RaiseError(QUIC_INVALID_FRAME_DATA);
- }
- }
- }
- return true;
-}
-
-namespace {
-// Create a mask that sets the last |num_bits| to 1 and the rest to 0.
-inline uint8_t GetMaskFromNumBits(uint8_t num_bits) {
- return (1u << num_bits) - 1;
-}
-
-// Extract |num_bits| from |flags| offset by |offset|.
-uint8_t ExtractBits(uint8_t flags, uint8_t num_bits, uint8_t offset) {
- return (flags >> offset) & GetMaskFromNumBits(num_bits);
-}
-
-// Extract the bit at position |offset| from |flags| as a bool.
-bool ExtractBit(uint8_t flags, uint8_t offset) {
- return ((flags >> offset) & GetMaskFromNumBits(1)) != 0;
-}
-
-// Set |num_bits|, offset by |offset| to |val| in |flags|.
-void SetBits(uint8_t* flags, uint8_t val, uint8_t num_bits, uint8_t offset) {
- QUICHE_DCHECK_LE(val, GetMaskFromNumBits(num_bits));
- *flags |= val << offset;
-}
-
-// Set the bit at position |offset| to |val| in |flags|.
-void SetBit(uint8_t* flags, bool val, uint8_t offset) {
- SetBits(flags, val ? 1 : 0, 1, offset);
-}
-} // namespace
-
-bool QuicFramer::ProcessStreamFrame(QuicDataReader* reader, uint8_t frame_type,
- QuicStreamFrame* frame) {
- uint8_t stream_flags = frame_type;
-
- uint8_t stream_id_length = 0;
- uint8_t offset_length = 4;
- bool has_data_length = true;
- stream_flags &= ~kQuicFrameTypeStreamMask;
-
- // Read from right to left: StreamID, Offset, Data Length, Fin.
- stream_id_length = (stream_flags & kQuicStreamIDLengthMask) + 1;
- stream_flags >>= kQuicStreamIdShift;
-
- offset_length = (stream_flags & kQuicStreamOffsetMask);
- // There is no encoding for 1 byte, only 0 and 2 through 8.
- if (offset_length > 0) {
- offset_length += 1;
- }
- stream_flags >>= kQuicStreamShift;
-
- has_data_length =
- (stream_flags & kQuicStreamDataLengthMask) == kQuicStreamDataLengthMask;
- stream_flags >>= kQuicStreamDataLengthShift;
-
- frame->fin = (stream_flags & kQuicStreamFinMask) == kQuicStreamFinShift;
-
- uint64_t stream_id;
- if (!reader->ReadBytesToUInt64(stream_id_length, &stream_id)) {
- set_detailed_error("Unable to read stream_id.");
- return false;
- }
- frame->stream_id = static_cast<QuicStreamId>(stream_id);
-
- if (!reader->ReadBytesToUInt64(offset_length, &frame->offset)) {
- set_detailed_error("Unable to read offset.");
- return false;
- }
-
- // TODO(ianswett): Don't use absl::string_view as an intermediary.
- absl::string_view data;
- if (has_data_length) {
- if (!reader->ReadStringPiece16(&data)) {
- set_detailed_error("Unable to read frame data.");
- return false;
- }
- } else {
- if (!reader->ReadStringPiece(&data, reader->BytesRemaining())) {
- set_detailed_error("Unable to read frame data.");
- return false;
- }
- }
- frame->data_buffer = data.data();
- frame->data_length = static_cast<uint16_t>(data.length());
-
- return true;
-}
-
-bool QuicFramer::ProcessIetfStreamFrame(QuicDataReader* reader,
- uint8_t frame_type,
- QuicStreamFrame* frame) {
- // Read stream id from the frame. It's always present.
- if (!ReadUint32FromVarint62(reader, IETF_STREAM, &frame->stream_id)) {
- return false;
- }
-
- // If we have a data offset, read it. If not, set to 0.
- if (frame_type & IETF_STREAM_FRAME_OFF_BIT) {
- if (!reader->ReadVarInt62(&frame->offset)) {
- set_detailed_error("Unable to read stream data offset.");
- return false;
- }
- } else {
- // no offset in the frame, ensure it's 0 in the Frame.
- frame->offset = 0;
- }
-
- // If we have a data length, read it. If not, set to 0.
- if (frame_type & IETF_STREAM_FRAME_LEN_BIT) {
- uint64_t length;
- if (!reader->ReadVarInt62(&length)) {
- set_detailed_error("Unable to read stream data length.");
- return false;
- }
- if (length > std::numeric_limits<decltype(frame->data_length)>::max()) {
- set_detailed_error("Stream data length is too large.");
- return false;
- }
- frame->data_length = length;
- } else {
- // no length in the frame, it is the number of bytes remaining in the
- // packet.
- frame->data_length = reader->BytesRemaining();
- }
-
- if (frame_type & IETF_STREAM_FRAME_FIN_BIT) {
- frame->fin = true;
- } else {
- frame->fin = false;
- }
-
- // TODO(ianswett): Don't use absl::string_view as an intermediary.
- absl::string_view data;
- if (!reader->ReadStringPiece(&data, frame->data_length)) {
- set_detailed_error("Unable to read frame data.");
- return false;
- }
- frame->data_buffer = data.data();
- QUICHE_DCHECK_EQ(frame->data_length, data.length());
-
- return true;
-}
-
-bool QuicFramer::ProcessCryptoFrame(QuicDataReader* reader,
- EncryptionLevel encryption_level,
- QuicCryptoFrame* frame) {
- frame->level = encryption_level;
- if (!reader->ReadVarInt62(&frame->offset)) {
- set_detailed_error("Unable to read crypto data offset.");
- return false;
- }
- uint64_t len;
- if (!reader->ReadVarInt62(&len) ||
- len > std::numeric_limits<QuicPacketLength>::max()) {
- set_detailed_error("Invalid data length.");
- return false;
- }
- frame->data_length = len;
-
- // TODO(ianswett): Don't use absl::string_view as an intermediary.
- absl::string_view data;
- if (!reader->ReadStringPiece(&data, frame->data_length)) {
- set_detailed_error("Unable to read frame data.");
- return false;
- }
- frame->data_buffer = data.data();
- return true;
-}
-
-bool QuicFramer::ProcessAckFrequencyFrame(QuicDataReader* reader,
- QuicAckFrequencyFrame* frame) {
- if (!reader->ReadVarInt62(&frame->sequence_number)) {
- set_detailed_error("Unable to read sequence number.");
- return false;
- }
-
- if (!reader->ReadVarInt62(&frame->packet_tolerance)) {
- set_detailed_error("Unable to read packet tolerance.");
- return false;
- }
- if (frame->packet_tolerance == 0) {
- set_detailed_error("Invalid packet tolerance.");
- return false;
- }
- uint64_t max_ack_delay_us;
- if (!reader->ReadVarInt62(&max_ack_delay_us)) {
- set_detailed_error("Unable to read max_ack_delay_us.");
- return false;
- }
- constexpr uint64_t kMaxAckDelayUsBound = 1u << 24;
- if (max_ack_delay_us > kMaxAckDelayUsBound) {
- set_detailed_error("Invalid max_ack_delay_us.");
- return false;
- }
- frame->max_ack_delay = QuicTime::Delta::FromMicroseconds(max_ack_delay_us);
-
- uint8_t ignore_order;
- if (!reader->ReadUInt8(&ignore_order)) {
- set_detailed_error("Unable to read ignore_order.");
- return false;
- }
- if (ignore_order > 1) {
- set_detailed_error("Invalid ignore_order.");
- return false;
- }
- frame->ignore_order = ignore_order;
-
- return true;
-}
-
-bool QuicFramer::ProcessAckFrame(QuicDataReader* reader, uint8_t frame_type) {
- const bool has_ack_blocks =
- ExtractBit(frame_type, kQuicHasMultipleAckBlocksOffset);
- uint8_t num_ack_blocks = 0;
- uint8_t num_received_packets = 0;
-
- // Determine the two lengths from the frame type: largest acked length,
- // ack block length.
- const QuicPacketNumberLength ack_block_length =
- ReadAckPacketNumberLength(ExtractBits(
- frame_type, kQuicSequenceNumberLengthNumBits, kActBlockLengthOffset));
- const QuicPacketNumberLength largest_acked_length =
- ReadAckPacketNumberLength(ExtractBits(
- frame_type, kQuicSequenceNumberLengthNumBits, kLargestAckedOffset));
-
- uint64_t largest_acked;
- if (!reader->ReadBytesToUInt64(largest_acked_length, &largest_acked)) {
- set_detailed_error("Unable to read largest acked.");
- return false;
- }
-
- if (largest_acked < first_sending_packet_number_.ToUint64()) {
- // Connection always sends packet starting from kFirstSendingPacketNumber >
- // 0, peer has observed an unsent packet.
- set_detailed_error("Largest acked is 0.");
- return false;
- }
-
- uint64_t ack_delay_time_us;
- if (!reader->ReadUFloat16(&ack_delay_time_us)) {
- set_detailed_error("Unable to read ack delay time.");
- return false;
- }
-
- if (!visitor_->OnAckFrameStart(
- QuicPacketNumber(largest_acked),
- ack_delay_time_us == kUFloat16MaxValue
- ? QuicTime::Delta::Infinite()
- : QuicTime::Delta::FromMicroseconds(ack_delay_time_us))) {
- // The visitor suppresses further processing of the packet. Although this is
- // not a parsing error, returns false as this is in middle of processing an
- // ack frame,
- set_detailed_error("Visitor suppresses further processing of ack frame.");
- return false;
- }
-
- if (has_ack_blocks && !reader->ReadUInt8(&num_ack_blocks)) {
- set_detailed_error("Unable to read num of ack blocks.");
- return false;
- }
-
- uint64_t first_block_length;
- if (!reader->ReadBytesToUInt64(ack_block_length, &first_block_length)) {
- set_detailed_error("Unable to read first ack block length.");
- return false;
- }
-
- if (first_block_length == 0) {
- set_detailed_error("First block length is zero.");
- return false;
- }
- bool first_ack_block_underflow = first_block_length > largest_acked + 1;
- if (first_block_length + first_sending_packet_number_.ToUint64() >
- largest_acked + 1) {
- first_ack_block_underflow = true;
- }
- if (first_ack_block_underflow) {
- set_detailed_error(absl::StrCat("Underflow with first ack block length ",
- first_block_length, " largest acked is ",
- largest_acked, ".")
- .c_str());
- return false;
- }
-
- uint64_t first_received = largest_acked + 1 - first_block_length;
- if (!visitor_->OnAckRange(QuicPacketNumber(first_received),
- QuicPacketNumber(largest_acked + 1))) {
- // The visitor suppresses further processing of the packet. Although
- // this is not a parsing error, returns false as this is in middle
- // of processing an ack frame,
- set_detailed_error("Visitor suppresses further processing of ack frame.");
- return false;
- }
-
- if (num_ack_blocks > 0) {
- for (size_t i = 0; i < num_ack_blocks; ++i) {
- uint8_t gap = 0;
- if (!reader->ReadUInt8(&gap)) {
- set_detailed_error("Unable to read gap to next ack block.");
- return false;
- }
- uint64_t current_block_length;
- if (!reader->ReadBytesToUInt64(ack_block_length, &current_block_length)) {
- set_detailed_error("Unable to ack block length.");
- return false;
- }
- bool ack_block_underflow = first_received < gap + current_block_length;
- if (first_received < gap + current_block_length +
- first_sending_packet_number_.ToUint64()) {
- ack_block_underflow = true;
- }
- if (ack_block_underflow) {
- set_detailed_error(absl::StrCat("Underflow with ack block length ",
- current_block_length,
- ", end of block is ",
- first_received - gap, ".")
- .c_str());
- return false;
- }
-
- first_received -= (gap + current_block_length);
- if (current_block_length > 0) {
- if (!visitor_->OnAckRange(
- QuicPacketNumber(first_received),
- QuicPacketNumber(first_received) + current_block_length)) {
- // The visitor suppresses further processing of the packet. Although
- // this is not a parsing error, returns false as this is in middle
- // of processing an ack frame,
- set_detailed_error(
- "Visitor suppresses further processing of ack frame.");
- return false;
- }
- }
- }
- }
-
- if (!reader->ReadUInt8(&num_received_packets)) {
- set_detailed_error("Unable to read num received packets.");
- return false;
- }
-
- if (!ProcessTimestampsInAckFrame(num_received_packets,
- QuicPacketNumber(largest_acked), reader)) {
- return false;
- }
-
- // Done processing the ACK frame.
- if (!visitor_->OnAckFrameEnd(QuicPacketNumber(first_received))) {
- set_detailed_error(
- "Error occurs when visitor finishes processing the ACK frame.");
- return false;
- }
-
- return true;
-}
-
-bool QuicFramer::ProcessTimestampsInAckFrame(uint8_t num_received_packets,
- QuicPacketNumber largest_acked,
- QuicDataReader* reader) {
- if (num_received_packets == 0) {
- return true;
- }
- uint8_t delta_from_largest_observed;
- if (!reader->ReadUInt8(&delta_from_largest_observed)) {
- set_detailed_error("Unable to read sequence delta in received packets.");
- return false;
- }
-
- if (largest_acked.ToUint64() <= delta_from_largest_observed) {
- set_detailed_error(
- absl::StrCat("delta_from_largest_observed too high: ",
- delta_from_largest_observed,
- ", largest_acked: ", largest_acked.ToUint64())
- .c_str());
- return false;
- }
-
- // Time delta from the framer creation.
- uint32_t time_delta_us;
- if (!reader->ReadUInt32(&time_delta_us)) {
- set_detailed_error("Unable to read time delta in received packets.");
- return false;
- }
-
- QuicPacketNumber seq_num = largest_acked - delta_from_largest_observed;
- if (process_timestamps_) {
- last_timestamp_ = CalculateTimestampFromWire(time_delta_us);
-
- visitor_->OnAckTimestamp(seq_num, creation_time_ + last_timestamp_);
- }
-
- for (uint8_t i = 1; i < num_received_packets; ++i) {
- if (!reader->ReadUInt8(&delta_from_largest_observed)) {
- set_detailed_error("Unable to read sequence delta in received packets.");
- return false;
- }
- if (largest_acked.ToUint64() <= delta_from_largest_observed) {
- set_detailed_error(
- absl::StrCat("delta_from_largest_observed too high: ",
- delta_from_largest_observed,
- ", largest_acked: ", largest_acked.ToUint64())
- .c_str());
- return false;
- }
- seq_num = largest_acked - delta_from_largest_observed;
-
- // Time delta from the previous timestamp.
- uint64_t incremental_time_delta_us;
- if (!reader->ReadUFloat16(&incremental_time_delta_us)) {
- set_detailed_error(
- "Unable to read incremental time delta in received packets.");
- return false;
- }
-
- if (process_timestamps_) {
- last_timestamp_ = last_timestamp_ + QuicTime::Delta::FromMicroseconds(
- incremental_time_delta_us);
- visitor_->OnAckTimestamp(seq_num, creation_time_ + last_timestamp_);
- }
- }
- return true;
-}
-
-bool QuicFramer::ProcessIetfAckFrame(QuicDataReader* reader,
- uint64_t frame_type,
- QuicAckFrame* ack_frame) {
- uint64_t largest_acked;
- if (!reader->ReadVarInt62(&largest_acked)) {
- set_detailed_error("Unable to read largest acked.");
- return false;
- }
- if (largest_acked < first_sending_packet_number_.ToUint64()) {
- // Connection always sends packet starting from kFirstSendingPacketNumber >
- // 0, peer has observed an unsent packet.
- set_detailed_error("Largest acked is 0.");
- return false;
- }
- ack_frame->largest_acked = static_cast<QuicPacketNumber>(largest_acked);
- uint64_t ack_delay_time_in_us;
- if (!reader->ReadVarInt62(&ack_delay_time_in_us)) {
- set_detailed_error("Unable to read ack delay time.");
- return false;
- }
-
- if (ack_delay_time_in_us >= (kVarInt62MaxValue >> peer_ack_delay_exponent_)) {
- ack_frame->ack_delay_time = QuicTime::Delta::Infinite();
- } else {
- ack_delay_time_in_us = (ack_delay_time_in_us << peer_ack_delay_exponent_);
- ack_frame->ack_delay_time =
- QuicTime::Delta::FromMicroseconds(ack_delay_time_in_us);
- }
- if (!visitor_->OnAckFrameStart(QuicPacketNumber(largest_acked),
- ack_frame->ack_delay_time)) {
- // The visitor suppresses further processing of the packet. Although this is
- // not a parsing error, returns false as this is in middle of processing an
- // ACK frame.
- set_detailed_error("Visitor suppresses further processing of ACK frame.");
- return false;
- }
-
- // Get number of ACK blocks from the packet.
- uint64_t ack_block_count;
- if (!reader->ReadVarInt62(&ack_block_count)) {
- set_detailed_error("Unable to read ack block count.");
- return false;
- }
- // There always is a first ACK block, which is the (number of packets being
- // acked)-1, up to and including the packet at largest_acked. Therefore if the
- // value is 0, then only largest is acked. If it is 1, then largest-1,
- // largest] are acked, etc
- uint64_t ack_block_value;
- if (!reader->ReadVarInt62(&ack_block_value)) {
- set_detailed_error("Unable to read first ack block length.");
- return false;
- }
- // Calculate the packets being acked in the first block.
- // +1 because AddRange implementation requires [low,high)
- uint64_t block_high = largest_acked + 1;
- uint64_t block_low = largest_acked - ack_block_value;
-
- // ack_block_value is the number of packets preceding the
- // largest_acked packet which are in the block being acked. Thus,
- // its maximum value is largest_acked-1. Test this, reporting an
- // error if the value is wrong.
- if (ack_block_value + first_sending_packet_number_.ToUint64() >
- largest_acked) {
- set_detailed_error(absl::StrCat("Underflow with first ack block length ",
- ack_block_value + 1, " largest acked is ",
- largest_acked, ".")
- .c_str());
- return false;
- }
-
- if (!visitor_->OnAckRange(QuicPacketNumber(block_low),
- QuicPacketNumber(block_high))) {
- // The visitor suppresses further processing of the packet. Although
- // this is not a parsing error, returns false as this is in middle
- // of processing an ACK frame.
- set_detailed_error("Visitor suppresses further processing of ACK frame.");
- return false;
- }
-
- while (ack_block_count != 0) {
- uint64_t gap_block_value;
- // Get the sizes of the gap and ack blocks,
- if (!reader->ReadVarInt62(&gap_block_value)) {
- set_detailed_error("Unable to read gap block value.");
- return false;
- }
- // It's an error if the gap is larger than the space from packet
- // number 0 to the start of the block that's just been acked, PLUS
- // there must be space for at least 1 packet to be acked. For
- // example, if block_low is 10 and gap_block_value is 9, it means
- // the gap block is 10 packets long, leaving no room for a packet
- // to be acked. Thus, gap_block_value+2 can not be larger than
- // block_low.
- // The test is written this way to detect wrap-arounds.
- if ((gap_block_value + 2) > block_low) {
- set_detailed_error(
- absl::StrCat("Underflow with gap block length ", gap_block_value + 1,
- " previous ack block start is ", block_low, ".")
- .c_str());
- return false;
- }
-
- // Adjust block_high to be the top of the next ack block.
- // There is a gap of |gap_block_value| packets between the bottom
- // of ack block N and top of block N+1. Note that gap_block_value
- // is he size of the gap minus 1 (per the QUIC protocol), and
- // block_high is the packet number of the first packet of the gap
- // (per the implementation of OnAckRange/AddAckRange, below).
- block_high = block_low - 1 - gap_block_value;
-
- if (!reader->ReadVarInt62(&ack_block_value)) {
- set_detailed_error("Unable to read ack block value.");
- return false;
- }
- if (ack_block_value + first_sending_packet_number_.ToUint64() >
- (block_high - 1)) {
- set_detailed_error(
- absl::StrCat("Underflow with ack block length ", ack_block_value + 1,
- " latest ack block end is ", block_high - 1, ".")
- .c_str());
- return false;
- }
- // Calculate the low end of the new nth ack block. The +1 is
- // because the encoded value is the blocksize-1.
- block_low = block_high - 1 - ack_block_value;
- if (!visitor_->OnAckRange(QuicPacketNumber(block_low),
- QuicPacketNumber(block_high))) {
- // The visitor suppresses further processing of the packet. Although
- // this is not a parsing error, returns false as this is in middle
- // of processing an ACK frame.
- set_detailed_error("Visitor suppresses further processing of ACK frame.");
- return false;
- }
-
- // Another one done.
- ack_block_count--;
- }
-
- if (frame_type == IETF_ACK_RECEIVE_TIMESTAMPS) {
- QUICHE_DCHECK(process_timestamps_);
- if (!ProcessIetfTimestampsInAckFrame(ack_frame->largest_acked, reader)) {
- return false;
- }
- } else if (frame_type == IETF_ACK_ECN) {
- ack_frame->ecn_counters_populated = true;
- if (!reader->ReadVarInt62(&ack_frame->ect_0_count)) {
- set_detailed_error("Unable to read ack ect_0_count.");
- return false;
- }
- if (!reader->ReadVarInt62(&ack_frame->ect_1_count)) {
- set_detailed_error("Unable to read ack ect_1_count.");
- return false;
- }
- if (!reader->ReadVarInt62(&ack_frame->ecn_ce_count)) {
- set_detailed_error("Unable to read ack ecn_ce_count.");
- return false;
- }
- } else {
- ack_frame->ecn_counters_populated = false;
- ack_frame->ect_0_count = 0;
- ack_frame->ect_1_count = 0;
- ack_frame->ecn_ce_count = 0;
- }
- // TODO(fayang): Report ECN counts to visitor when they are actually used.
- if (!visitor_->OnAckFrameEnd(QuicPacketNumber(block_low))) {
- set_detailed_error(
- "Error occurs when visitor finishes processing the ACK frame.");
- return false;
- }
-
- return true;
-}
-
-bool QuicFramer::ProcessIetfTimestampsInAckFrame(QuicPacketNumber largest_acked,
- QuicDataReader* reader) {
- uint64_t timestamp_range_count;
- if (!reader->ReadVarInt62(&timestamp_range_count)) {
- set_detailed_error("Unable to read receive timestamp range count.");
- return false;
- }
- if (timestamp_range_count == 0) {
- return true;
- }
-
- QuicPacketNumber packet_number = largest_acked;
-
- // Iterate through all timestamp ranges, each of which represents a block of
- // contiguous packets for which receive timestamps are being reported. Each
- // range is of the form:
- //
- // Timestamp Range {
- // Gap (i),
- // Timestamp Delta Count (i),
- // Timestamp Delta (i) ...,
- // }
- for (uint64_t i = 0; i < timestamp_range_count; i++) {
- uint64_t gap;
- if (!reader->ReadVarInt62(&gap)) {
- set_detailed_error("Unable to read receive timestamp gap.");
- return false;
- }
- if (packet_number.ToUint64() < gap) {
- set_detailed_error("Receive timestamp gap too high.");
- return false;
- }
- packet_number = packet_number - gap;
- uint64_t timestamp_count;
- if (!reader->ReadVarInt62(&timestamp_count)) {
- set_detailed_error("Unable to read receive timestamp count.");
- return false;
- }
- if (packet_number.ToUint64() < timestamp_count) {
- set_detailed_error("Receive timestamp count too high.");
- return false;
- }
- for (uint64_t j = 0; j < timestamp_count; j++) {
- uint64_t timestamp_delta;
- if (!reader->ReadVarInt62(&timestamp_delta)) {
- set_detailed_error("Unable to read receive timestamp delta.");
- return false;
- }
- // The first timestamp delta is relative to framer creation time; whereas
- // subsequent deltas are relative to the previous delta in decreasing
- // packet order.
- timestamp_delta = timestamp_delta << receive_timestamps_exponent_;
- if (i == 0 && j == 0) {
- last_timestamp_ = QuicTime::Delta::FromMicroseconds(timestamp_delta);
- } else {
- last_timestamp_ = last_timestamp_ -
- QuicTime::Delta::FromMicroseconds(timestamp_delta);
- if (last_timestamp_ < QuicTime::Delta::Zero()) {
- set_detailed_error("Receive timestamp delta too high.");
- return false;
- }
- }
- visitor_->OnAckTimestamp(packet_number, creation_time_ + last_timestamp_);
- packet_number--;
- }
- packet_number--;
- }
- return true;
-}
-
-bool QuicFramer::ProcessStopWaitingFrame(QuicDataReader* reader,
- const QuicPacketHeader& header,
- QuicStopWaitingFrame* stop_waiting) {
- uint64_t least_unacked_delta;
- if (!reader->ReadBytesToUInt64(header.packet_number_length,
- &least_unacked_delta)) {
- set_detailed_error("Unable to read least unacked delta.");
- return false;
- }
- if (header.packet_number.ToUint64() <= least_unacked_delta) {
- set_detailed_error("Invalid unacked delta.");
- return false;
- }
- stop_waiting->least_unacked = header.packet_number - least_unacked_delta;
-
- return true;
-}
-
-bool QuicFramer::ProcessRstStreamFrame(QuicDataReader* reader,
- QuicRstStreamFrame* frame) {
- if (!reader->ReadUInt32(&frame->stream_id)) {
- set_detailed_error("Unable to read stream_id.");
- return false;
- }
-
- if (!reader->ReadUInt64(&frame->byte_offset)) {
- set_detailed_error("Unable to read rst stream sent byte offset.");
- return false;
- }
-
- uint32_t error_code;
- if (!reader->ReadUInt32(&error_code)) {
- set_detailed_error("Unable to read rst stream error code.");
- return false;
- }
-
- if (error_code >= QUIC_STREAM_LAST_ERROR) {
- // Ignore invalid stream error code if any.
- error_code = QUIC_STREAM_LAST_ERROR;
- }
-
- frame->error_code = static_cast<QuicRstStreamErrorCode>(error_code);
-
- return true;
-}
-
-bool QuicFramer::ProcessConnectionCloseFrame(QuicDataReader* reader,
- QuicConnectionCloseFrame* frame) {
- uint32_t error_code;
- frame->close_type = GOOGLE_QUIC_CONNECTION_CLOSE;
-
- if (!reader->ReadUInt32(&error_code)) {
- set_detailed_error("Unable to read connection close error code.");
- return false;
- }
-
- // For Google QUIC connection closes, |wire_error_code| and |quic_error_code|
- // must have the same value.
- frame->wire_error_code = error_code;
- frame->quic_error_code = static_cast<QuicErrorCode>(error_code);
-
- absl::string_view error_details;
- if (!reader->ReadStringPiece16(&error_details)) {
- set_detailed_error("Unable to read connection close error details.");
- return false;
- }
- frame->error_details = std::string(error_details);
-
- return true;
-}
-
-bool QuicFramer::ProcessGoAwayFrame(QuicDataReader* reader,
- QuicGoAwayFrame* frame) {
- uint32_t error_code;
- if (!reader->ReadUInt32(&error_code)) {
- set_detailed_error("Unable to read go away error code.");
- return false;
- }
-
- frame->error_code = static_cast<QuicErrorCode>(error_code);
-
- uint32_t stream_id;
- if (!reader->ReadUInt32(&stream_id)) {
- set_detailed_error("Unable to read last good stream id.");
- return false;
- }
- frame->last_good_stream_id = static_cast<QuicStreamId>(stream_id);
-
- absl::string_view reason_phrase;
- if (!reader->ReadStringPiece16(&reason_phrase)) {
- set_detailed_error("Unable to read goaway reason.");
- return false;
- }
- frame->reason_phrase = std::string(reason_phrase);
-
- return true;
-}
-
-bool QuicFramer::ProcessWindowUpdateFrame(QuicDataReader* reader,
- QuicWindowUpdateFrame* frame) {
- if (!reader->ReadUInt32(&frame->stream_id)) {
- set_detailed_error("Unable to read stream_id.");
- return false;
- }
-
- if (!reader->ReadUInt64(&frame->max_data)) {
- set_detailed_error("Unable to read window byte_offset.");
- return false;
- }
-
- return true;
-}
-
-bool QuicFramer::ProcessBlockedFrame(QuicDataReader* reader,
- QuicBlockedFrame* frame) {
- QUICHE_DCHECK(!VersionHasIetfQuicFrames(version_.transport_version))
- << "Attempt to process non-IETF QUIC frames in an IETF QUIC version.";
-
- if (!reader->ReadUInt32(&frame->stream_id)) {
- set_detailed_error("Unable to read stream_id.");
- return false;
- }
-
- return true;
-}
-
-void QuicFramer::ProcessPaddingFrame(QuicDataReader* reader,
- QuicPaddingFrame* frame) {
- // Type byte has been read.
- frame->num_padding_bytes = 1;
- uint8_t next_byte;
- while (!reader->IsDoneReading() && reader->PeekByte() == 0x00) {
- reader->ReadBytes(&next_byte, 1);
- QUICHE_DCHECK_EQ(0x00, next_byte);
- ++frame->num_padding_bytes;
- }
-}
-
-bool QuicFramer::ProcessMessageFrame(QuicDataReader* reader,
- bool no_message_length,
- QuicMessageFrame* frame) {
- if (no_message_length) {
- absl::string_view remaining(reader->ReadRemainingPayload());
- frame->data = remaining.data();
- frame->message_length = remaining.length();
- return true;
- }
-
- uint64_t message_length;
- if (!reader->ReadVarInt62(&message_length)) {
- set_detailed_error("Unable to read message length");
- return false;
- }
-
- absl::string_view message_piece;
- if (!reader->ReadStringPiece(&message_piece, message_length)) {
- set_detailed_error("Unable to read message data");
- return false;
- }
-
- frame->data = message_piece.data();
- frame->message_length = message_length;
-
- return true;
-}
-
-// static
-absl::string_view QuicFramer::GetAssociatedDataFromEncryptedPacket(
- QuicTransportVersion version, const QuicEncryptedPacket& encrypted,
- QuicConnectionIdLength destination_connection_id_length,
- QuicConnectionIdLength source_connection_id_length, bool includes_version,
- bool includes_diversification_nonce,
- QuicPacketNumberLength packet_number_length,
- QuicVariableLengthIntegerLength retry_token_length_length,
- uint64_t retry_token_length,
- QuicVariableLengthIntegerLength length_length) {
- // TODO(ianswett): This is identical to QuicData::AssociatedData.
- return absl::string_view(
- encrypted.data(),
- GetStartOfEncryptedData(version, destination_connection_id_length,
- source_connection_id_length, includes_version,
- includes_diversification_nonce,
- packet_number_length, retry_token_length_length,
- retry_token_length, length_length));
-}
-
-void QuicFramer::SetDecrypter(EncryptionLevel level,
- std::unique_ptr<QuicDecrypter> decrypter) {
- QUICHE_DCHECK_EQ(alternative_decrypter_level_, NUM_ENCRYPTION_LEVELS);
- QUICHE_DCHECK_GE(level, decrypter_level_);
- QUICHE_DCHECK(!version_.KnowsWhichDecrypterToUse());
- QUIC_DVLOG(1) << ENDPOINT << "Setting decrypter from level "
- << decrypter_level_ << " to " << level;
- decrypter_[decrypter_level_] = nullptr;
- decrypter_[level] = std::move(decrypter);
- decrypter_level_ = level;
-}
-
-void QuicFramer::SetAlternativeDecrypter(
- EncryptionLevel level, std::unique_ptr<QuicDecrypter> decrypter,
- bool latch_once_used) {
- QUICHE_DCHECK_NE(level, decrypter_level_);
- QUICHE_DCHECK(!version_.KnowsWhichDecrypterToUse());
- QUIC_DVLOG(1) << ENDPOINT << "Setting alternative decrypter from level "
- << alternative_decrypter_level_ << " to " << level;
- if (alternative_decrypter_level_ != NUM_ENCRYPTION_LEVELS) {
- decrypter_[alternative_decrypter_level_] = nullptr;
- }
- decrypter_[level] = std::move(decrypter);
- alternative_decrypter_level_ = level;
- alternative_decrypter_latch_ = latch_once_used;
-}
-
-void QuicFramer::InstallDecrypter(EncryptionLevel level,
- std::unique_ptr<QuicDecrypter> decrypter) {
- QUICHE_DCHECK(version_.KnowsWhichDecrypterToUse());
- QUIC_DVLOG(1) << ENDPOINT << "Installing decrypter at level " << level;
- decrypter_[level] = std::move(decrypter);
-}
-
-void QuicFramer::RemoveDecrypter(EncryptionLevel level) {
- QUICHE_DCHECK(version_.KnowsWhichDecrypterToUse());
- QUIC_DVLOG(1) << ENDPOINT << "Removing decrypter at level " << level;
- decrypter_[level] = nullptr;
-}
-
-void QuicFramer::SetKeyUpdateSupportForConnection(bool enabled) {
- QUIC_DVLOG(1) << ENDPOINT << "SetKeyUpdateSupportForConnection: " << enabled;
- support_key_update_for_connection_ = enabled;
-}
-
-void QuicFramer::DiscardPreviousOneRttKeys() {
- QUICHE_DCHECK(support_key_update_for_connection_);
- QUIC_DVLOG(1) << ENDPOINT << "Discarding previous set of 1-RTT keys";
- previous_decrypter_ = nullptr;
-}
-
-bool QuicFramer::DoKeyUpdate(KeyUpdateReason reason) {
- QUICHE_DCHECK(support_key_update_for_connection_);
- if (!next_decrypter_) {
- // If key update is locally initiated, next decrypter might not be created
- // yet.
- next_decrypter_ = visitor_->AdvanceKeysAndCreateCurrentOneRttDecrypter();
- }
- std::unique_ptr<QuicEncrypter> next_encrypter =
- visitor_->CreateCurrentOneRttEncrypter();
- if (!next_decrypter_ || !next_encrypter) {
- QUIC_BUG(quic_bug_10850_58) << "Failed to create next crypters";
- return false;
- }
- key_update_performed_ = true;
- current_key_phase_bit_ = !current_key_phase_bit_;
- QUIC_DLOG(INFO) << ENDPOINT << "DoKeyUpdate: new current_key_phase_bit_="
- << current_key_phase_bit_;
- current_key_phase_first_received_packet_number_.Clear();
- previous_decrypter_ = std::move(decrypter_[ENCRYPTION_FORWARD_SECURE]);
- decrypter_[ENCRYPTION_FORWARD_SECURE] = std::move(next_decrypter_);
- encrypter_[ENCRYPTION_FORWARD_SECURE] = std::move(next_encrypter);
- switch (reason) {
- case KeyUpdateReason::kInvalid:
- QUIC_CODE_COUNT(quic_key_update_invalid);
- break;
- case KeyUpdateReason::kRemote:
- QUIC_CODE_COUNT(quic_key_update_remote);
- break;
- case KeyUpdateReason::kLocalForTests:
- QUIC_CODE_COUNT(quic_key_update_local_for_tests);
- break;
- case KeyUpdateReason::kLocalForInteropRunner:
- QUIC_CODE_COUNT(quic_key_update_local_for_interop_runner);
- break;
- case KeyUpdateReason::kLocalAeadConfidentialityLimit:
- QUIC_CODE_COUNT(quic_key_update_local_aead_confidentiality_limit);
- break;
- case KeyUpdateReason::kLocalKeyUpdateLimitOverride:
- QUIC_CODE_COUNT(quic_key_update_local_limit_override);
- break;
- }
- visitor_->OnKeyUpdate(reason);
- return true;
-}
-
-QuicPacketCount QuicFramer::PotentialPeerKeyUpdateAttemptCount() const {
- return potential_peer_key_update_attempt_count_;
-}
-
-const QuicDecrypter* QuicFramer::GetDecrypter(EncryptionLevel level) const {
- QUICHE_DCHECK(version_.KnowsWhichDecrypterToUse());
- return decrypter_[level].get();
-}
-
-const QuicDecrypter* QuicFramer::decrypter() const {
- return decrypter_[decrypter_level_].get();
-}
-
-const QuicDecrypter* QuicFramer::alternative_decrypter() const {
- if (alternative_decrypter_level_ == NUM_ENCRYPTION_LEVELS) {
- return nullptr;
- }
- return decrypter_[alternative_decrypter_level_].get();
-}
-
-void QuicFramer::SetEncrypter(EncryptionLevel level,
- std::unique_ptr<QuicEncrypter> encrypter) {
- QUICHE_DCHECK_GE(level, 0);
- QUICHE_DCHECK_LT(level, NUM_ENCRYPTION_LEVELS);
- QUIC_DVLOG(1) << ENDPOINT << "Setting encrypter at level " << level;
- encrypter_[level] = std::move(encrypter);
-}
-
-void QuicFramer::RemoveEncrypter(EncryptionLevel level) {
- QUIC_DVLOG(1) << ENDPOINT << "Removing encrypter of " << level;
- encrypter_[level] = nullptr;
-}
-
-void QuicFramer::SetInitialObfuscators(QuicConnectionId connection_id) {
- CrypterPair crypters;
- CryptoUtils::CreateInitialObfuscators(perspective_, version_, connection_id,
- &crypters);
- encrypter_[ENCRYPTION_INITIAL] = std::move(crypters.encrypter);
- decrypter_[ENCRYPTION_INITIAL] = std::move(crypters.decrypter);
-}
-
-size_t QuicFramer::EncryptInPlace(EncryptionLevel level,
- QuicPacketNumber packet_number, size_t ad_len,
- size_t total_len, size_t buffer_len,
- char* buffer) {
- QUICHE_DCHECK(packet_number.IsInitialized());
- if (encrypter_[level] == nullptr) {
- QUIC_BUG(quic_bug_10850_59)
- << ENDPOINT
- << "Attempted to encrypt in place without encrypter at level " << level;
- RaiseError(QUIC_ENCRYPTION_FAILURE);
- return 0;
- }
-
- size_t output_length = 0;
- if (!encrypter_[level]->EncryptPacket(
- packet_number.ToUint64(),
- absl::string_view(buffer, ad_len), // Associated data
- absl::string_view(buffer + ad_len,
- total_len - ad_len), // Plaintext
- buffer + ad_len, // Destination buffer
- &output_length, buffer_len - ad_len)) {
- RaiseError(QUIC_ENCRYPTION_FAILURE);
- return 0;
- }
- if (version_.HasHeaderProtection() &&
- !ApplyHeaderProtection(level, buffer, ad_len + output_length, ad_len)) {
- QUIC_DLOG(ERROR) << "Applying header protection failed.";
- RaiseError(QUIC_ENCRYPTION_FAILURE);
- return 0;
- }
-
- return ad_len + output_length;
-}
-
-namespace {
-
-const size_t kHPSampleLen = 16;
-
-constexpr bool IsLongHeader(uint8_t type_byte) {
- return (type_byte & FLAGS_LONG_HEADER) != 0;
-}
-
-} // namespace
-
-bool QuicFramer::ApplyHeaderProtection(EncryptionLevel level, char* buffer,
- size_t buffer_len, size_t ad_len) {
- QuicDataReader buffer_reader(buffer, buffer_len);
- QuicDataWriter buffer_writer(buffer_len, buffer);
- // The sample starts 4 bytes after the start of the packet number.
- if (ad_len < last_written_packet_number_length_) {
- return false;
- }
- size_t pn_offset = ad_len - last_written_packet_number_length_;
- // Sample the ciphertext and generate the mask to use for header protection.
- size_t sample_offset = pn_offset + 4;
- QuicDataReader sample_reader(buffer, buffer_len);
- absl::string_view sample;
- if (!sample_reader.Seek(sample_offset) ||
- !sample_reader.ReadStringPiece(&sample, kHPSampleLen)) {
- QUIC_BUG(quic_bug_10850_60)
- << "Not enough bytes to sample: sample_offset " << sample_offset
- << ", sample len: " << kHPSampleLen << ", buffer len: " << buffer_len;
- return false;
- }
-
- if (encrypter_[level] == nullptr) {
- QUIC_BUG(quic_bug_12975_8)
- << ENDPOINT
- << "Attempted to apply header protection without encrypter at level "
- << level << " using " << version_;
- return false;
- }
-
- std::string mask = encrypter_[level]->GenerateHeaderProtectionMask(sample);
- if (mask.empty()) {
- QUIC_BUG(quic_bug_10850_61) << "Unable to generate header protection mask.";
- return false;
- }
- QuicDataReader mask_reader(mask.data(), mask.size());
-
- // Apply the mask to the 4 or 5 least significant bits of the first byte.
- uint8_t bitmask = 0x1f;
- uint8_t type_byte;
- if (!buffer_reader.ReadUInt8(&type_byte)) {
- return false;
- }
- QuicLongHeaderType header_type;
- if (IsLongHeader(type_byte)) {
- bitmask = 0x0f;
- header_type = GetLongHeaderType(type_byte, version_);
- if (header_type == INVALID_PACKET_TYPE) {
- return false;
- }
- }
- uint8_t mask_byte;
- if (!mask_reader.ReadUInt8(&mask_byte) ||
- !buffer_writer.WriteUInt8(type_byte ^ (mask_byte & bitmask))) {
- return false;
- }
-
- // Adjust |pn_offset| to account for the diversification nonce.
- if (IsLongHeader(type_byte) && header_type == ZERO_RTT_PROTECTED &&
- perspective_ == Perspective::IS_SERVER &&
- version_.handshake_protocol == PROTOCOL_QUIC_CRYPTO) {
- if (pn_offset <= kDiversificationNonceSize) {
- QUIC_BUG(quic_bug_10850_62)
- << "Expected diversification nonce, but not enough bytes";
- return false;
- }
- pn_offset -= kDiversificationNonceSize;
- }
- // Advance the reader and writer to the packet number. Both the reader and
- // writer have each read/written one byte.
- if (!buffer_writer.Seek(pn_offset - 1) ||
- !buffer_reader.Seek(pn_offset - 1)) {
- return false;
- }
- // Apply the rest of the mask to the packet number.
- for (size_t i = 0; i < last_written_packet_number_length_; ++i) {
- uint8_t buffer_byte;
- uint8_t mask_byte;
- if (!mask_reader.ReadUInt8(&mask_byte) ||
- !buffer_reader.ReadUInt8(&buffer_byte) ||
- !buffer_writer.WriteUInt8(buffer_byte ^ mask_byte)) {
- return false;
- }
- }
- return true;
-}
-
-bool QuicFramer::RemoveHeaderProtection(QuicDataReader* reader,
- const QuicEncryptedPacket& packet,
- QuicPacketHeader* header,
- uint64_t* full_packet_number,
- std::vector<char>* associated_data) {
- EncryptionLevel expected_decryption_level = GetEncryptionLevel(*header);
- QuicDecrypter* decrypter = decrypter_[expected_decryption_level].get();
- if (decrypter == nullptr) {
- QUIC_DVLOG(1)
- << ENDPOINT
- << "No decrypter available for removing header protection at level "
- << expected_decryption_level;
- return false;
- }
-
- bool has_diversification_nonce =
- header->form == IETF_QUIC_LONG_HEADER_PACKET &&
- header->long_packet_type == ZERO_RTT_PROTECTED &&
- perspective_ == Perspective::IS_CLIENT &&
- version_.handshake_protocol == PROTOCOL_QUIC_CRYPTO;
-
- // Read a sample from the ciphertext and compute the mask to use for header
- // protection.
- absl::string_view remaining_packet = reader->PeekRemainingPayload();
- QuicDataReader sample_reader(remaining_packet);
-
- // The sample starts 4 bytes after the start of the packet number.
- absl::string_view pn;
- if (!sample_reader.ReadStringPiece(&pn, 4)) {
- QUIC_DVLOG(1) << "Not enough data to sample";
- return false;
- }
- if (has_diversification_nonce) {
- // In Google QUIC, the diversification nonce comes between the packet number
- // and the sample.
- if (!sample_reader.Seek(kDiversificationNonceSize)) {
- QUIC_DVLOG(1) << "No diversification nonce to skip over";
- return false;
- }
- }
- std::string mask = decrypter->GenerateHeaderProtectionMask(&sample_reader);
- QuicDataReader mask_reader(mask.data(), mask.size());
- if (mask.empty()) {
- QUIC_DVLOG(1) << "Failed to compute mask";
- return false;
- }
-
- // Unmask the rest of the type byte.
- uint8_t bitmask = 0x1f;
- if (IsLongHeader(header->type_byte)) {
- bitmask = 0x0f;
- }
- uint8_t mask_byte;
- if (!mask_reader.ReadUInt8(&mask_byte)) {
- QUIC_DVLOG(1) << "No first byte to read from mask";
- return false;
- }
- header->type_byte ^= (mask_byte & bitmask);
-
- // Compute the packet number length.
- header->packet_number_length =
- static_cast<QuicPacketNumberLength>((header->type_byte & 0x03) + 1);
-
- char pn_buffer[IETF_MAX_PACKET_NUMBER_LENGTH] = {};
- QuicDataWriter pn_writer(ABSL_ARRAYSIZE(pn_buffer), pn_buffer);
-
- // Read the (protected) packet number from the reader and unmask the packet
- // number.
- for (size_t i = 0; i < header->packet_number_length; ++i) {
- uint8_t protected_pn_byte, mask_byte;
- if (!mask_reader.ReadUInt8(&mask_byte) ||
- !reader->ReadUInt8(&protected_pn_byte) ||
- !pn_writer.WriteUInt8(protected_pn_byte ^ mask_byte)) {
- QUIC_DVLOG(1) << "Failed to unmask packet number";
- return false;
- }
- }
- QuicDataReader packet_number_reader(pn_writer.data(), pn_writer.length());
- QuicPacketNumber base_packet_number;
- if (supports_multiple_packet_number_spaces_) {
- PacketNumberSpace pn_space = GetPacketNumberSpace(*header);
- if (pn_space == NUM_PACKET_NUMBER_SPACES) {
- return false;
- }
- base_packet_number = largest_decrypted_packet_numbers_[pn_space];
- } else {
- base_packet_number = largest_packet_number_;
- }
- if (!ProcessAndCalculatePacketNumber(
- &packet_number_reader, header->packet_number_length,
- base_packet_number, full_packet_number)) {
- return false;
- }
-
- // Get the associated data, and apply the same unmasking operations to it.
- absl::string_view ad = GetAssociatedDataFromEncryptedPacket(
- version_.transport_version, packet,
- GetIncludedDestinationConnectionIdLength(*header),
- GetIncludedSourceConnectionIdLength(*header), header->version_flag,
- has_diversification_nonce, header->packet_number_length,
- header->retry_token_length_length, header->retry_token.length(),
- header->length_length);
- *associated_data = std::vector<char>(ad.begin(), ad.end());
- QuicDataWriter ad_writer(associated_data->size(), associated_data->data());
-
- // Apply the unmasked type byte and packet number to |associated_data|.
- if (!ad_writer.WriteUInt8(header->type_byte)) {
- return false;
- }
- // Put the packet number at the end of the AD, or if there's a diversification
- // nonce, before that (which is at the end of the AD).
- size_t seek_len = ad_writer.remaining() - header->packet_number_length;
- if (has_diversification_nonce) {
- seek_len -= kDiversificationNonceSize;
- }
- if (!ad_writer.Seek(seek_len) ||
- !ad_writer.WriteBytes(pn_writer.data(), pn_writer.length())) {
- QUIC_DVLOG(1) << "Failed to apply unmasking operations to AD";
- return false;
- }
-
- return true;
-}
-
-size_t QuicFramer::EncryptPayload(EncryptionLevel level,
- QuicPacketNumber packet_number,
- const QuicPacket& packet, char* buffer,
- size_t buffer_len) {
- QUICHE_DCHECK(packet_number.IsInitialized());
- if (encrypter_[level] == nullptr) {
- QUIC_BUG(quic_bug_10850_63)
- << ENDPOINT << "Attempted to encrypt without encrypter at level "
- << level;
- RaiseError(QUIC_ENCRYPTION_FAILURE);
- return 0;
- }
-
- absl::string_view associated_data =
- packet.AssociatedData(version_.transport_version);
- // Copy in the header, because the encrypter only populates the encrypted
- // plaintext content.
- const size_t ad_len = associated_data.length();
- if (packet.length() < ad_len) {
- QUIC_BUG(quic_bug_10850_64)
- << ENDPOINT << "packet is shorter than associated data length. version:"
- << version() << ", packet length:" << packet.length()
- << ", associated data length:" << ad_len;
- RaiseError(QUIC_ENCRYPTION_FAILURE);
- return 0;
- }
- memmove(buffer, associated_data.data(), ad_len);
- // Encrypt the plaintext into the buffer.
- size_t output_length = 0;
- if (!encrypter_[level]->EncryptPacket(
- packet_number.ToUint64(), associated_data,
- packet.Plaintext(version_.transport_version), buffer + ad_len,
- &output_length, buffer_len - ad_len)) {
- RaiseError(QUIC_ENCRYPTION_FAILURE);
- return 0;
- }
- if (version_.HasHeaderProtection() &&
- !ApplyHeaderProtection(level, buffer, ad_len + output_length, ad_len)) {
- QUIC_DLOG(ERROR) << "Applying header protection failed.";
- RaiseError(QUIC_ENCRYPTION_FAILURE);
- return 0;
- }
-
- return ad_len + output_length;
-}
-
-size_t QuicFramer::GetCiphertextSize(EncryptionLevel level,
- size_t plaintext_size) const {
- if (encrypter_[level] == nullptr) {
- QUIC_BUG(quic_bug_10850_65)
- << ENDPOINT
- << "Attempted to get ciphertext size without encrypter at level "
- << level << " using " << version_;
- return plaintext_size;
- }
- return encrypter_[level]->GetCiphertextSize(plaintext_size);
-}
-
-size_t QuicFramer::GetMaxPlaintextSize(size_t ciphertext_size) {
- // In order to keep the code simple, we don't have the current encryption
- // level to hand. Both the NullEncrypter and AES-GCM have a tag length of 12.
- size_t min_plaintext_size = ciphertext_size;
-
- for (int i = ENCRYPTION_INITIAL; i < NUM_ENCRYPTION_LEVELS; i++) {
- if (encrypter_[i] != nullptr) {
- size_t size = encrypter_[i]->GetMaxPlaintextSize(ciphertext_size);
- if (size < min_plaintext_size) {
- min_plaintext_size = size;
- }
- }
- }
-
- return min_plaintext_size;
-}
-
-QuicPacketCount QuicFramer::GetOneRttEncrypterConfidentialityLimit() const {
- if (!encrypter_[ENCRYPTION_FORWARD_SECURE]) {
- QUIC_BUG(quic_bug_10850_66) << "1-RTT encrypter not set";
- return 0;
- }
- return encrypter_[ENCRYPTION_FORWARD_SECURE]->GetConfidentialityLimit();
-}
-
-bool QuicFramer::DecryptPayload(size_t udp_packet_length,
- absl::string_view encrypted,
- absl::string_view associated_data,
- const QuicPacketHeader& header,
- char* decrypted_buffer, size_t buffer_length,
- size_t* decrypted_length,
- EncryptionLevel* decrypted_level) {
- if (!EncryptionLevelIsValid(decrypter_level_)) {
- QUIC_BUG(quic_bug_10850_67)
- << "Attempted to decrypt with bad decrypter_level_";
- return false;
- }
- EncryptionLevel level = decrypter_level_;
- QuicDecrypter* decrypter = decrypter_[level].get();
- QuicDecrypter* alternative_decrypter = nullptr;
- bool key_phase_parsed = false;
- bool key_phase;
- bool attempt_key_update = false;
- if (version().KnowsWhichDecrypterToUse()) {
- if (header.form == GOOGLE_QUIC_PACKET) {
- QUIC_BUG(quic_bug_10850_68)
- << "Attempted to decrypt GOOGLE_QUIC_PACKET with a version that "
- "knows which decrypter to use";
- return false;
- }
- level = GetEncryptionLevel(header);
- if (!EncryptionLevelIsValid(level)) {
- QUIC_BUG(quic_bug_10850_69) << "Attempted to decrypt with bad level";
- return false;
- }
- decrypter = decrypter_[level].get();
- if (decrypter == nullptr) {
- return false;
- }
- if (level == ENCRYPTION_ZERO_RTT &&
- perspective_ == Perspective::IS_CLIENT && header.nonce != nullptr) {
- decrypter->SetDiversificationNonce(*header.nonce);
- }
- if (support_key_update_for_connection_ &&
- header.form == IETF_QUIC_SHORT_HEADER_PACKET) {
- QUICHE_DCHECK(version().UsesTls());
- QUICHE_DCHECK_EQ(level, ENCRYPTION_FORWARD_SECURE);
- key_phase = (header.type_byte & FLAGS_KEY_PHASE_BIT) != 0;
- key_phase_parsed = true;
- QUIC_DVLOG(1) << ENDPOINT << "packet " << header.packet_number
- << " received key_phase=" << key_phase
- << " current_key_phase_bit_=" << current_key_phase_bit_;
- if (key_phase != current_key_phase_bit_) {
- if ((current_key_phase_first_received_packet_number_.IsInitialized() &&
- header.packet_number >
- current_key_phase_first_received_packet_number_) ||
- (!current_key_phase_first_received_packet_number_.IsInitialized() &&
- !key_update_performed_)) {
- if (!next_decrypter_) {
- next_decrypter_ =
- visitor_->AdvanceKeysAndCreateCurrentOneRttDecrypter();
- if (!next_decrypter_) {
- QUIC_BUG(quic_bug_10850_70) << "Failed to create next_decrypter";
- return false;
- }
- }
- QUIC_DVLOG(1) << ENDPOINT << "packet " << header.packet_number
- << " attempt_key_update=true";
- attempt_key_update = true;
- potential_peer_key_update_attempt_count_++;
- decrypter = next_decrypter_.get();
- } else {
- if (previous_decrypter_) {
- QUIC_DVLOG(1) << ENDPOINT
- << "trying previous_decrypter_ for packet "
- << header.packet_number;
- decrypter = previous_decrypter_.get();
- } else {
- QUIC_DVLOG(1) << ENDPOINT << "dropping packet "
- << header.packet_number << " with old key phase";
- return false;
- }
- }
- }
- }
- } else if (alternative_decrypter_level_ != NUM_ENCRYPTION_LEVELS) {
- if (!EncryptionLevelIsValid(alternative_decrypter_level_)) {
- QUIC_BUG(quic_bug_10850_71)
- << "Attempted to decrypt with bad alternative_decrypter_level_";
- return false;
- }
- alternative_decrypter = decrypter_[alternative_decrypter_level_].get();
- }
-
- if (decrypter == nullptr) {
- QUIC_BUG(quic_bug_10850_72)
- << "Attempting to decrypt without decrypter, encryption level:" << level
- << " version:" << version();
- return false;
- }
-
- bool success = decrypter->DecryptPacket(
- header.packet_number.ToUint64(), associated_data, encrypted,
- decrypted_buffer, decrypted_length, buffer_length);
- if (success) {
- visitor_->OnDecryptedPacket(udp_packet_length, level);
- if (level == ENCRYPTION_ZERO_RTT &&
- current_key_phase_first_received_packet_number_.IsInitialized() &&
- header.packet_number >
- current_key_phase_first_received_packet_number_) {
- set_detailed_error(absl::StrCat(
- "Decrypted a 0-RTT packet with a packet number ",
- header.packet_number.ToString(),
- " which is higher than a 1-RTT packet number ",
- current_key_phase_first_received_packet_number_.ToString()));
- return RaiseError(QUIC_INVALID_0RTT_PACKET_NUMBER_OUT_OF_ORDER);
- }
- *decrypted_level = level;
- potential_peer_key_update_attempt_count_ = 0;
- if (attempt_key_update) {
- if (!DoKeyUpdate(KeyUpdateReason::kRemote)) {
- set_detailed_error("Key update failed due to internal error");
- return RaiseError(QUIC_INTERNAL_ERROR);
- }
- QUICHE_DCHECK_EQ(current_key_phase_bit_, key_phase);
- }
- if (key_phase_parsed &&
- !current_key_phase_first_received_packet_number_.IsInitialized() &&
- key_phase == current_key_phase_bit_) {
- // Set packet number for current key phase if it hasn't been initialized
- // yet. This is set outside of attempt_key_update since the key update
- // may have been initiated locally, and in that case we don't know yet
- // which packet number from the remote side to use until we receive a
- // packet with that phase.
- QUIC_DVLOG(1) << ENDPOINT
- << "current_key_phase_first_received_packet_number_ = "
- << header.packet_number;
- current_key_phase_first_received_packet_number_ = header.packet_number;
- visitor_->OnDecryptedFirstPacketInKeyPhase();
- }
- } else if (alternative_decrypter != nullptr) {
- if (header.nonce != nullptr) {
- QUICHE_DCHECK_EQ(perspective_, Perspective::IS_CLIENT);
- alternative_decrypter->SetDiversificationNonce(*header.nonce);
- }
- bool try_alternative_decryption = true;
- if (alternative_decrypter_level_ == ENCRYPTION_ZERO_RTT) {
- if (perspective_ == Perspective::IS_CLIENT) {
- if (header.nonce == nullptr) {
- // Can not use INITIAL decryption without a diversification nonce.
- try_alternative_decryption = false;
- }
- } else {
- QUICHE_DCHECK(header.nonce == nullptr);
- }
- }
-
- if (try_alternative_decryption) {
- success = alternative_decrypter->DecryptPacket(
- header.packet_number.ToUint64(), associated_data, encrypted,
- decrypted_buffer, decrypted_length, buffer_length);
- }
- if (success) {
- visitor_->OnDecryptedPacket(udp_packet_length,
- alternative_decrypter_level_);
- *decrypted_level = decrypter_level_;
- if (alternative_decrypter_latch_) {
- if (!EncryptionLevelIsValid(alternative_decrypter_level_)) {
- QUIC_BUG(quic_bug_10850_73)
- << "Attempted to latch alternate decrypter with bad "
- "alternative_decrypter_level_";
- return false;
- }
- // Switch to the alternative decrypter and latch so that we cannot
- // switch back.
- decrypter_level_ = alternative_decrypter_level_;
- alternative_decrypter_level_ = NUM_ENCRYPTION_LEVELS;
- } else {
- // Switch the alternative decrypter so that we use it first next time.
- EncryptionLevel level = alternative_decrypter_level_;
- alternative_decrypter_level_ = decrypter_level_;
- decrypter_level_ = level;
- }
- }
- }
-
- if (!success) {
- QUIC_DVLOG(1) << ENDPOINT << "DecryptPacket failed for: " << header;
- return false;
- }
-
- return true;
-}
-
-size_t QuicFramer::GetIetfAckFrameSize(const QuicAckFrame& frame) {
- // Type byte, largest_acked, and delay_time are straight-forward.
- size_t ack_frame_size = kQuicFrameTypeSize;
- QuicPacketNumber largest_acked = LargestAcked(frame);
- ack_frame_size += QuicDataWriter::GetVarInt62Len(largest_acked.ToUint64());
- uint64_t ack_delay_time_us;
- ack_delay_time_us = frame.ack_delay_time.ToMicroseconds();
- ack_delay_time_us = ack_delay_time_us >> local_ack_delay_exponent_;
- ack_frame_size += QuicDataWriter::GetVarInt62Len(ack_delay_time_us);
-
- if (frame.packets.Empty() || frame.packets.Max() != largest_acked) {
- QUIC_BUG(quic_bug_10850_74) << "Malformed ack frame";
- // ACK frame serialization will fail and connection will be closed.
- return ack_frame_size;
- }
-
- // Ack block count.
- ack_frame_size +=
- QuicDataWriter::GetVarInt62Len(frame.packets.NumIntervals() - 1);
-
- // First Ack range.
- auto iter = frame.packets.rbegin();
- ack_frame_size += QuicDataWriter::GetVarInt62Len(iter->Length() - 1);
- QuicPacketNumber previous_smallest = iter->min();
- ++iter;
-
- // Ack blocks.
- for (; iter != frame.packets.rend(); ++iter) {
- const uint64_t gap = previous_smallest - iter->max() - 1;
- const uint64_t ack_range = iter->Length() - 1;
- ack_frame_size += (QuicDataWriter::GetVarInt62Len(gap) +
- QuicDataWriter::GetVarInt62Len(ack_range));
- previous_smallest = iter->min();
- }
-
- if (UseIetfAckWithReceiveTimestamp(frame)) {
- ack_frame_size += GetIetfAckFrameTimestampSize(frame);
- } else if (frame.ecn_counters_populated &&
- (frame.ect_0_count || frame.ect_1_count || frame.ecn_ce_count)) {
- // ECN counts.
- ack_frame_size += QuicDataWriter::GetVarInt62Len(frame.ect_0_count);
- ack_frame_size += QuicDataWriter::GetVarInt62Len(frame.ect_1_count);
- ack_frame_size += QuicDataWriter::GetVarInt62Len(frame.ecn_ce_count);
- }
-
- return ack_frame_size;
-}
-
-size_t QuicFramer::GetIetfAckFrameTimestampSize(const QuicAckFrame& ack) {
- QUICHE_DCHECK(!ack.received_packet_times.empty());
- std::string detailed_error;
- absl::InlinedVector<AckTimestampRange, 2> timestamp_ranges =
- GetAckTimestampRanges(ack, detailed_error);
- if (!detailed_error.empty()) {
- return 0;
- }
-
- int64_t size =
- FrameAckTimestampRanges(ack, timestamp_ranges, /*writer=*/nullptr);
- return std::max<int64_t>(0, size);
-}
-
-size_t QuicFramer::GetAckFrameSize(
- const QuicAckFrame& ack, QuicPacketNumberLength /*packet_number_length*/) {
- QUICHE_DCHECK(!ack.packets.Empty());
- size_t ack_size = 0;
-
- if (VersionHasIetfQuicFrames(version_.transport_version)) {
- return GetIetfAckFrameSize(ack);
- }
- AckFrameInfo ack_info = GetAckFrameInfo(ack);
- QuicPacketNumberLength ack_block_length =
- GetMinPacketNumberLength(QuicPacketNumber(ack_info.max_block_length));
-
- ack_size = GetMinAckFrameSize(version_.transport_version, ack,
- local_ack_delay_exponent_,
- UseIetfAckWithReceiveTimestamp(ack));
- // First ack block length.
- ack_size += ack_block_length;
- if (ack_info.num_ack_blocks != 0) {
- ack_size += kNumberOfAckBlocksSize;
- ack_size += std::min(ack_info.num_ack_blocks, kMaxAckBlocks) *
- (ack_block_length + PACKET_1BYTE_PACKET_NUMBER);
- }
-
- // Include timestamps.
- if (process_timestamps_) {
- ack_size += GetAckFrameTimeStampSize(ack);
- }
-
- return ack_size;
-}
-
-size_t QuicFramer::GetAckFrameTimeStampSize(const QuicAckFrame& ack) {
- if (ack.received_packet_times.empty()) {
- return 0;
- }
-
- return kQuicNumTimestampsLength + kQuicFirstTimestampLength +
- (kQuicTimestampLength + kQuicTimestampPacketNumberGapLength) *
- (ack.received_packet_times.size() - 1);
-}
-
-size_t QuicFramer::ComputeFrameLength(
- const QuicFrame& frame, bool last_frame_in_packet,
- QuicPacketNumberLength packet_number_length) {
- switch (frame.type) {
- case STREAM_FRAME:
- return GetMinStreamFrameSize(
- version_.transport_version, frame.stream_frame.stream_id,
- frame.stream_frame.offset, last_frame_in_packet,
- frame.stream_frame.data_length) +
- frame.stream_frame.data_length;
- case CRYPTO_FRAME:
- return GetMinCryptoFrameSize(frame.crypto_frame->offset,
- frame.crypto_frame->data_length) +
- frame.crypto_frame->data_length;
- case ACK_FRAME: {
- return GetAckFrameSize(*frame.ack_frame, packet_number_length);
- }
- case STOP_WAITING_FRAME:
- return GetStopWaitingFrameSize(packet_number_length);
- case MTU_DISCOVERY_FRAME:
- // MTU discovery frames are serialized as ping frames.
- return kQuicFrameTypeSize;
- case MESSAGE_FRAME:
- return GetMessageFrameSize(version_.transport_version,
- last_frame_in_packet,
- frame.message_frame->message_length);
- case PADDING_FRAME:
- QUICHE_DCHECK(false);
- return 0;
- default:
- return GetRetransmittableControlFrameSize(version_.transport_version,
- frame);
- }
-}
-
-bool QuicFramer::AppendTypeByte(const QuicFrame& frame,
- bool last_frame_in_packet,
- QuicDataWriter* writer) {
- if (VersionHasIetfQuicFrames(version_.transport_version)) {
- return AppendIetfFrameType(frame, last_frame_in_packet, writer);
- }
- uint8_t type_byte = 0;
- switch (frame.type) {
- case STREAM_FRAME:
- type_byte =
- GetStreamFrameTypeByte(frame.stream_frame, last_frame_in_packet);
- break;
- case ACK_FRAME:
- return true;
- case MTU_DISCOVERY_FRAME:
- type_byte = static_cast<uint8_t>(PING_FRAME);
- break;
- case NEW_CONNECTION_ID_FRAME:
- set_detailed_error(
- "Attempt to append NEW_CONNECTION_ID frame and not in IETF QUIC.");
- return RaiseError(QUIC_INTERNAL_ERROR);
- case RETIRE_CONNECTION_ID_FRAME:
- set_detailed_error(
- "Attempt to append RETIRE_CONNECTION_ID frame and not in IETF QUIC.");
- return RaiseError(QUIC_INTERNAL_ERROR);
- case NEW_TOKEN_FRAME:
- set_detailed_error(
- "Attempt to append NEW_TOKEN frame and not in IETF QUIC.");
- return RaiseError(QUIC_INTERNAL_ERROR);
- case MAX_STREAMS_FRAME:
- set_detailed_error(
- "Attempt to append MAX_STREAMS frame and not in IETF QUIC.");
- return RaiseError(QUIC_INTERNAL_ERROR);
- case STREAMS_BLOCKED_FRAME:
- set_detailed_error(
- "Attempt to append STREAMS_BLOCKED frame and not in IETF QUIC.");
- return RaiseError(QUIC_INTERNAL_ERROR);
- case PATH_RESPONSE_FRAME:
- set_detailed_error(
- "Attempt to append PATH_RESPONSE frame and not in IETF QUIC.");
- return RaiseError(QUIC_INTERNAL_ERROR);
- case PATH_CHALLENGE_FRAME:
- set_detailed_error(
- "Attempt to append PATH_CHALLENGE frame and not in IETF QUIC.");
- return RaiseError(QUIC_INTERNAL_ERROR);
- case STOP_SENDING_FRAME:
- set_detailed_error(
- "Attempt to append STOP_SENDING frame and not in IETF QUIC.");
- return RaiseError(QUIC_INTERNAL_ERROR);
- case MESSAGE_FRAME:
- return true;
-
- default:
- type_byte = static_cast<uint8_t>(frame.type);
- break;
- }
-
- return writer->WriteUInt8(type_byte);
-}
-
-bool QuicFramer::AppendIetfFrameType(const QuicFrame& frame,
- bool last_frame_in_packet,
- QuicDataWriter* writer) {
- uint8_t type_byte = 0;
- switch (frame.type) {
- case PADDING_FRAME:
- type_byte = IETF_PADDING;
- break;
- case RST_STREAM_FRAME:
- type_byte = IETF_RST_STREAM;
- break;
- case CONNECTION_CLOSE_FRAME:
- switch (frame.connection_close_frame->close_type) {
- case IETF_QUIC_APPLICATION_CONNECTION_CLOSE:
- type_byte = IETF_APPLICATION_CLOSE;
- break;
- case IETF_QUIC_TRANSPORT_CONNECTION_CLOSE:
- type_byte = IETF_CONNECTION_CLOSE;
- break;
- default:
- set_detailed_error(absl::StrCat(
- "Invalid QuicConnectionCloseFrame type: ",
- static_cast<int>(frame.connection_close_frame->close_type)));
- return RaiseError(QUIC_INTERNAL_ERROR);
- }
- break;
- case GOAWAY_FRAME:
- set_detailed_error(
- "Attempt to create non-IETF QUIC GOAWAY frame in IETF QUIC.");
- return RaiseError(QUIC_INTERNAL_ERROR);
- case WINDOW_UPDATE_FRAME:
- // Depending on whether there is a stream ID or not, will be either a
- // MAX_STREAM_DATA frame or a MAX_DATA frame.
- if (frame.window_update_frame->stream_id ==
- QuicUtils::GetInvalidStreamId(transport_version())) {
- type_byte = IETF_MAX_DATA;
- } else {
- type_byte = IETF_MAX_STREAM_DATA;
- }
- break;
- case BLOCKED_FRAME:
- if (frame.blocked_frame->stream_id ==
- QuicUtils::GetInvalidStreamId(transport_version())) {
- type_byte = IETF_DATA_BLOCKED;
- } else {
- type_byte = IETF_STREAM_DATA_BLOCKED;
- }
- break;
- case STOP_WAITING_FRAME:
- set_detailed_error(
- "Attempt to append type byte of STOP WAITING frame in IETF QUIC.");
- return RaiseError(QUIC_INTERNAL_ERROR);
- case PING_FRAME:
- type_byte = IETF_PING;
- break;
- case STREAM_FRAME:
- type_byte =
- GetStreamFrameTypeByte(frame.stream_frame, last_frame_in_packet);
- break;
- case ACK_FRAME:
- // Do nothing here, AppendIetfAckFrameAndTypeByte() will put the type byte
- // in the buffer.
- return true;
- case MTU_DISCOVERY_FRAME:
- // The path MTU discovery frame is encoded as a PING frame on the wire.
- type_byte = IETF_PING;
- break;
- case NEW_CONNECTION_ID_FRAME:
- type_byte = IETF_NEW_CONNECTION_ID;
- break;
- case RETIRE_CONNECTION_ID_FRAME:
- type_byte = IETF_RETIRE_CONNECTION_ID;
- break;
- case NEW_TOKEN_FRAME:
- type_byte = IETF_NEW_TOKEN;
- break;
- case MAX_STREAMS_FRAME:
- if (frame.max_streams_frame.unidirectional) {
- type_byte = IETF_MAX_STREAMS_UNIDIRECTIONAL;
- } else {
- type_byte = IETF_MAX_STREAMS_BIDIRECTIONAL;
- }
- break;
- case STREAMS_BLOCKED_FRAME:
- if (frame.streams_blocked_frame.unidirectional) {
- type_byte = IETF_STREAMS_BLOCKED_UNIDIRECTIONAL;
- } else {
- type_byte = IETF_STREAMS_BLOCKED_BIDIRECTIONAL;
- }
- break;
- case PATH_RESPONSE_FRAME:
- type_byte = IETF_PATH_RESPONSE;
- break;
- case PATH_CHALLENGE_FRAME:
- type_byte = IETF_PATH_CHALLENGE;
- break;
- case STOP_SENDING_FRAME:
- type_byte = IETF_STOP_SENDING;
- break;
- case MESSAGE_FRAME:
- return true;
- case CRYPTO_FRAME:
- type_byte = IETF_CRYPTO;
- break;
- case HANDSHAKE_DONE_FRAME:
- type_byte = IETF_HANDSHAKE_DONE;
- break;
- case ACK_FREQUENCY_FRAME:
- type_byte = IETF_ACK_FREQUENCY;
- break;
- default:
- QUIC_BUG(quic_bug_10850_75)
- << "Attempt to generate a frame type for an unsupported value: "
- << frame.type;
- return false;
- }
- return writer->WriteVarInt62(type_byte);
-}
-
-// static
-bool QuicFramer::AppendPacketNumber(QuicPacketNumberLength packet_number_length,
- QuicPacketNumber packet_number,
- QuicDataWriter* writer) {
- QUICHE_DCHECK(packet_number.IsInitialized());
- if (!IsValidPacketNumberLength(packet_number_length)) {
- QUIC_BUG(quic_bug_10850_76)
- << "Invalid packet_number_length: " << packet_number_length;
- return false;
- }
- return writer->WriteBytesToUInt64(packet_number_length,
- packet_number.ToUint64());
-}
-
-// static
-bool QuicFramer::AppendStreamId(size_t stream_id_length, QuicStreamId stream_id,
- QuicDataWriter* writer) {
- if (stream_id_length == 0 || stream_id_length > 4) {
- QUIC_BUG(quic_bug_10850_77)
- << "Invalid stream_id_length: " << stream_id_length;
- return false;
- }
- return writer->WriteBytesToUInt64(stream_id_length, stream_id);
-}
-
-// static
-bool QuicFramer::AppendStreamOffset(size_t offset_length,
- QuicStreamOffset offset,
- QuicDataWriter* writer) {
- if (offset_length == 1 || offset_length > 8) {
- QUIC_BUG(quic_bug_10850_78)
- << "Invalid stream_offset_length: " << offset_length;
- return false;
- }
-
- return writer->WriteBytesToUInt64(offset_length, offset);
-}
-
-// static
-bool QuicFramer::AppendAckBlock(uint8_t gap,
- QuicPacketNumberLength length_length,
- uint64_t length, QuicDataWriter* writer) {
- if (length == 0) {
- if (!IsValidPacketNumberLength(length_length)) {
- QUIC_BUG(quic_bug_10850_79)
- << "Invalid packet_number_length: " << length_length;
- return false;
- }
- return writer->WriteUInt8(gap) &&
- writer->WriteBytesToUInt64(length_length, length);
- }
- return writer->WriteUInt8(gap) &&
- AppendPacketNumber(length_length, QuicPacketNumber(length), writer);
-}
-
-bool QuicFramer::AppendStreamFrame(const QuicStreamFrame& frame,
- bool no_stream_frame_length,
- QuicDataWriter* writer) {
- if (VersionHasIetfQuicFrames(version_.transport_version)) {
- return AppendIetfStreamFrame(frame, no_stream_frame_length, writer);
- }
- if (!AppendStreamId(GetStreamIdSize(frame.stream_id), frame.stream_id,
- writer)) {
- QUIC_BUG(quic_bug_10850_80) << "Writing stream id size failed.";
- return false;
- }
- if (!AppendStreamOffset(GetStreamOffsetSize(frame.offset), frame.offset,
- writer)) {
- QUIC_BUG(quic_bug_10850_81) << "Writing offset size failed.";
- return false;
- }
- if (!no_stream_frame_length) {
- static_assert(
- std::numeric_limits<decltype(frame.data_length)>::max() <=
- std::numeric_limits<uint16_t>::max(),
- "If frame.data_length can hold more than a uint16_t than we need to "
- "check that frame.data_length <= std::numeric_limits<uint16_t>::max()");
- if (!writer->WriteUInt16(static_cast<uint16_t>(frame.data_length))) {
- QUIC_BUG(quic_bug_10850_82) << "Writing stream frame length failed";
- return false;
- }
- }
-
- if (data_producer_ != nullptr) {
- QUICHE_DCHECK_EQ(nullptr, frame.data_buffer);
- if (frame.data_length == 0) {
- return true;
- }
- if (data_producer_->WriteStreamData(frame.stream_id, frame.offset,
- frame.data_length,
- writer) != WRITE_SUCCESS) {
- QUIC_BUG(quic_bug_10850_83) << "Writing frame data failed.";
- return false;
- }
- return true;
- }
-
- if (!writer->WriteBytes(frame.data_buffer, frame.data_length)) {
- QUIC_BUG(quic_bug_10850_84) << "Writing frame data failed.";
- return false;
- }
- return true;
-}
-
-bool QuicFramer::AppendNewTokenFrame(const QuicNewTokenFrame& frame,
- QuicDataWriter* writer) {
- if (!writer->WriteVarInt62(static_cast<uint64_t>(frame.token.length()))) {
- set_detailed_error("Writing token length failed.");
- return false;
- }
- if (!writer->WriteBytes(frame.token.data(), frame.token.length())) {
- set_detailed_error("Writing token buffer failed.");
- return false;
- }
- return true;
-}
-
-bool QuicFramer::ProcessNewTokenFrame(QuicDataReader* reader,
- QuicNewTokenFrame* frame) {
- uint64_t length;
- if (!reader->ReadVarInt62(&length)) {
- set_detailed_error("Unable to read new token length.");
- return false;
- }
- if (length > kMaxNewTokenTokenLength) {
- set_detailed_error("Token length larger than maximum.");
- return false;
- }
-
- // TODO(ianswett): Don't use absl::string_view as an intermediary.
- absl::string_view data;
- if (!reader->ReadStringPiece(&data, length)) {
- set_detailed_error("Unable to read new token data.");
- return false;
- }
- frame->token = std::string(data);
- return true;
-}
-
-// Add a new ietf-format stream frame.
-// Bits controlling whether there is a frame-length and frame-offset
-// are in the QuicStreamFrame.
-bool QuicFramer::AppendIetfStreamFrame(const QuicStreamFrame& frame,
- bool last_frame_in_packet,
- QuicDataWriter* writer) {
- if (!writer->WriteVarInt62(static_cast<uint64_t>(frame.stream_id))) {
- set_detailed_error("Writing stream id failed.");
- return false;
- }
-
- if (frame.offset != 0) {
- if (!writer->WriteVarInt62(static_cast<uint64_t>(frame.offset))) {
- set_detailed_error("Writing data offset failed.");
- return false;
- }
- }
-
- if (!last_frame_in_packet) {
- if (!writer->WriteVarInt62(frame.data_length)) {
- set_detailed_error("Writing data length failed.");
- return false;
- }
- }
-
- if (frame.data_length == 0) {
- return true;
- }
- if (data_producer_ == nullptr) {
- if (!writer->WriteBytes(frame.data_buffer, frame.data_length)) {
- set_detailed_error("Writing frame data failed.");
- return false;
- }
- } else {
- QUICHE_DCHECK_EQ(nullptr, frame.data_buffer);
-
- if (data_producer_->WriteStreamData(frame.stream_id, frame.offset,
- frame.data_length,
- writer) != WRITE_SUCCESS) {
- set_detailed_error("Writing frame data from producer failed.");
- return false;
- }
- }
- return true;
-}
-
-bool QuicFramer::AppendCryptoFrame(const QuicCryptoFrame& frame,
- QuicDataWriter* writer) {
- if (!writer->WriteVarInt62(static_cast<uint64_t>(frame.offset))) {
- set_detailed_error("Writing data offset failed.");
- return false;
- }
- if (!writer->WriteVarInt62(static_cast<uint64_t>(frame.data_length))) {
- set_detailed_error("Writing data length failed.");
- return false;
- }
- if (data_producer_ == nullptr) {
- if (frame.data_buffer == nullptr ||
- !writer->WriteBytes(frame.data_buffer, frame.data_length)) {
- set_detailed_error("Writing frame data failed.");
- return false;
- }
- } else {
- QUICHE_DCHECK_EQ(nullptr, frame.data_buffer);
- if (!data_producer_->WriteCryptoData(frame.level, frame.offset,
- frame.data_length, writer)) {
- return false;
- }
- }
- return true;
-}
-
-bool QuicFramer::AppendAckFrequencyFrame(const QuicAckFrequencyFrame& frame,
- QuicDataWriter* writer) {
- if (!writer->WriteVarInt62(frame.sequence_number)) {
- set_detailed_error("Writing sequence number failed.");
- return false;
- }
- if (!writer->WriteVarInt62(frame.packet_tolerance)) {
- set_detailed_error("Writing packet tolerance failed.");
- return false;
- }
- if (!writer->WriteVarInt62(
- static_cast<uint64_t>(frame.max_ack_delay.ToMicroseconds()))) {
- set_detailed_error("Writing max_ack_delay_us failed.");
- return false;
- }
- if (!writer->WriteUInt8(static_cast<uint8_t>(frame.ignore_order))) {
- set_detailed_error("Writing ignore_order failed.");
- return false;
- }
-
- return true;
-}
-
-void QuicFramer::set_version(const ParsedQuicVersion version) {
- QUICHE_DCHECK(IsSupportedVersion(version))
- << ParsedQuicVersionToString(version);
- version_ = version;
-}
-
-bool QuicFramer::AppendAckFrameAndTypeByte(const QuicAckFrame& frame,
- QuicDataWriter* writer) {
- if (VersionHasIetfQuicFrames(transport_version())) {
- return AppendIetfAckFrameAndTypeByte(frame, writer);
- }
-
- const AckFrameInfo new_ack_info = GetAckFrameInfo(frame);
- QuicPacketNumber largest_acked = LargestAcked(frame);
- QuicPacketNumberLength largest_acked_length =
- GetMinPacketNumberLength(largest_acked);
- QuicPacketNumberLength ack_block_length =
- GetMinPacketNumberLength(QuicPacketNumber(new_ack_info.max_block_length));
- // Calculate available bytes for timestamps and ack blocks.
- int32_t available_timestamp_and_ack_block_bytes =
- writer->capacity() - writer->length() - ack_block_length -
- GetMinAckFrameSize(version_.transport_version, frame,
- local_ack_delay_exponent_,
- UseIetfAckWithReceiveTimestamp(frame)) -
- (new_ack_info.num_ack_blocks != 0 ? kNumberOfAckBlocksSize : 0);
- QUICHE_DCHECK_LE(0, available_timestamp_and_ack_block_bytes);
-
- uint8_t type_byte = 0;
- SetBit(&type_byte, new_ack_info.num_ack_blocks != 0,
- kQuicHasMultipleAckBlocksOffset);
-
- SetBits(&type_byte, GetPacketNumberFlags(largest_acked_length),
- kQuicSequenceNumberLengthNumBits, kLargestAckedOffset);
-
- SetBits(&type_byte, GetPacketNumberFlags(ack_block_length),
- kQuicSequenceNumberLengthNumBits, kActBlockLengthOffset);
-
- type_byte |= kQuicFrameTypeAckMask;
-
- if (!writer->WriteUInt8(type_byte)) {
- return false;
- }
-
- size_t max_num_ack_blocks = available_timestamp_and_ack_block_bytes /
- (ack_block_length + PACKET_1BYTE_PACKET_NUMBER);
-
- // Number of ack blocks.
- size_t num_ack_blocks =
- std::min(new_ack_info.num_ack_blocks, max_num_ack_blocks);
- if (num_ack_blocks > std::numeric_limits<uint8_t>::max()) {
- num_ack_blocks = std::numeric_limits<uint8_t>::max();
- }
-
- // Largest acked.
- if (!AppendPacketNumber(largest_acked_length, largest_acked, writer)) {
- return false;
- }
-
- // Largest acked delta time.
- uint64_t ack_delay_time_us = kUFloat16MaxValue;
- if (!frame.ack_delay_time.IsInfinite()) {
- QUICHE_DCHECK_LE(0u, frame.ack_delay_time.ToMicroseconds());
- ack_delay_time_us = frame.ack_delay_time.ToMicroseconds();
- }
- if (!writer->WriteUFloat16(ack_delay_time_us)) {
- return false;
- }
-
- if (num_ack_blocks > 0) {
- if (!writer->WriteBytes(&num_ack_blocks, 1)) {
- return false;
- }
- }
-
- // First ack block length.
- if (!AppendPacketNumber(ack_block_length,
- QuicPacketNumber(new_ack_info.first_block_length),
- writer)) {
- return false;
- }
-
- // Ack blocks.
- if (num_ack_blocks > 0) {
- size_t num_ack_blocks_written = 0;
- // Append, in descending order from the largest ACKed packet, a series of
- // ACK blocks that represents the successfully acknoweldged packets. Each
- // appended gap/block length represents a descending delta from the previous
- // block. i.e.:
- // |--- length ---|--- gap ---|--- length ---|--- gap ---|--- largest ---|
- // For gaps larger than can be represented by a single encoded gap, a 0
- // length gap of the maximum is used, i.e.:
- // |--- length ---|--- gap ---|- 0 -|--- gap ---|--- largest ---|
- auto itr = frame.packets.rbegin();
- QuicPacketNumber previous_start = itr->min();
- ++itr;
-
- for (;
- itr != frame.packets.rend() && num_ack_blocks_written < num_ack_blocks;
- previous_start = itr->min(), ++itr) {
- const auto& interval = *itr;
- const uint64_t total_gap = previous_start - interval.max();
- const size_t num_encoded_gaps =
- (total_gap + std::numeric_limits<uint8_t>::max() - 1) /
- std::numeric_limits<uint8_t>::max();
-
- // Append empty ACK blocks because the gap is longer than a single gap.
- for (size_t i = 1;
- i < num_encoded_gaps && num_ack_blocks_written < num_ack_blocks;
- ++i) {
- if (!AppendAckBlock(std::numeric_limits<uint8_t>::max(),
- ack_block_length, 0, writer)) {
- return false;
- }
- ++num_ack_blocks_written;
- }
- if (num_ack_blocks_written >= num_ack_blocks) {
- if (QUIC_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;
- }
- break;
- }
-
- const uint8_t last_gap =
- total_gap -
- (num_encoded_gaps - 1) * std::numeric_limits<uint8_t>::max();
- // Append the final ACK block with a non-empty size.
- if (!AppendAckBlock(last_gap, ack_block_length, interval.Length(),
- writer)) {
- return false;
- }
- ++num_ack_blocks_written;
- }
- QUICHE_DCHECK_EQ(num_ack_blocks, num_ack_blocks_written);
- }
- // Timestamps.
- // If we don't process timestamps or if we don't have enough available space
- // to append all the timestamps, don't append any of them.
- if (process_timestamps_ && writer->capacity() - writer->length() >=
- GetAckFrameTimeStampSize(frame)) {
- if (!AppendTimestampsToAckFrame(frame, writer)) {
- return false;
- }
- } else {
- uint8_t num_received_packets = 0;
- if (!writer->WriteBytes(&num_received_packets, 1)) {
- return false;
- }
- }
-
- return true;
-}
-
-bool QuicFramer::AppendTimestampsToAckFrame(const QuicAckFrame& frame,
- QuicDataWriter* writer) {
- QUICHE_DCHECK_GE(std::numeric_limits<uint8_t>::max(),
- frame.received_packet_times.size());
- // num_received_packets is only 1 byte.
- if (frame.received_packet_times.size() >
- std::numeric_limits<uint8_t>::max()) {
- return false;
- }
-
- uint8_t num_received_packets = frame.received_packet_times.size();
- if (!writer->WriteBytes(&num_received_packets, 1)) {
- return false;
- }
- if (num_received_packets == 0) {
- return true;
- }
-
- auto it = frame.received_packet_times.begin();
- QuicPacketNumber packet_number = it->first;
- uint64_t delta_from_largest_observed = LargestAcked(frame) - packet_number;
-
- QUICHE_DCHECK_GE(std::numeric_limits<uint8_t>::max(),
- delta_from_largest_observed);
- if (delta_from_largest_observed > std::numeric_limits<uint8_t>::max()) {
- return false;
- }
-
- if (!writer->WriteUInt8(delta_from_largest_observed)) {
- return false;
- }
-
- // Use the lowest 4 bytes of the time delta from the creation_time_.
- const uint64_t time_epoch_delta_us = UINT64_C(1) << 32;
- uint32_t time_delta_us =
- static_cast<uint32_t>((it->second - creation_time_).ToMicroseconds() &
- (time_epoch_delta_us - 1));
- if (!writer->WriteUInt32(time_delta_us)) {
- return false;
- }
-
- QuicTime prev_time = it->second;
-
- for (++it; it != frame.received_packet_times.end(); ++it) {
- packet_number = it->first;
- delta_from_largest_observed = LargestAcked(frame) - packet_number;
-
- if (delta_from_largest_observed > std::numeric_limits<uint8_t>::max()) {
- return false;
- }
-
- if (!writer->WriteUInt8(delta_from_largest_observed)) {
- return false;
- }
-
- uint64_t frame_time_delta_us = (it->second - prev_time).ToMicroseconds();
- prev_time = it->second;
- if (!writer->WriteUFloat16(frame_time_delta_us)) {
- return false;
- }
- }
- return true;
-}
-
-absl::InlinedVector<QuicFramer::AckTimestampRange, 2>
-QuicFramer::GetAckTimestampRanges(const QuicAckFrame& frame,
- std::string& detailed_error) const {
- detailed_error = "";
- if (frame.received_packet_times.empty()) {
- return {};
- }
-
- absl::InlinedVector<AckTimestampRange, 2> timestamp_ranges;
-
- for (size_t r = 0; r < std::min<size_t>(max_receive_timestamps_per_ack_,
- frame.received_packet_times.size());
- ++r) {
- const size_t i = frame.received_packet_times.size() - 1 - r;
- const QuicPacketNumber packet_number = frame.received_packet_times[i].first;
- const QuicTime receive_timestamp = frame.received_packet_times[i].second;
-
- if (timestamp_ranges.empty()) {
- if (receive_timestamp < creation_time_ ||
- LargestAcked(frame) < packet_number) {
- detailed_error =
- "The first packet is either received earlier than framer creation "
- "time, or larger than largest acked packet.";
- QUIC_BUG(quic_framer_ack_ts_first_packet_bad)
- << detailed_error << " receive_timestamp:" << receive_timestamp
- << ", framer_creation_time:" << creation_time_
- << ", packet_number:" << packet_number
- << ", largest_acked:" << LargestAcked(frame);
- return {};
- }
- timestamp_ranges.push_back(AckTimestampRange());
- timestamp_ranges.back().gap = LargestAcked(frame) - packet_number;
- timestamp_ranges.back().range_begin = i;
- timestamp_ranges.back().range_end = i;
- continue;
- }
-
- const size_t prev_i = timestamp_ranges.back().range_end;
- const QuicPacketNumber prev_packet_number =
- frame.received_packet_times[prev_i].first;
- const QuicTime prev_receive_timestamp =
- frame.received_packet_times[prev_i].second;
-
- QUIC_DVLOG(3) << "prev_packet_number:" << prev_packet_number
- << ", packet_number:" << packet_number;
- if (prev_receive_timestamp < receive_timestamp ||
- prev_packet_number <= packet_number) {
- detailed_error = "Packet number and/or receive time not in order.";
- QUIC_BUG(quic_framer_ack_ts_packet_out_of_order)
- << detailed_error << " packet_number:" << packet_number
- << ", receive_timestamp:" << receive_timestamp
- << ", prev_packet_number:" << prev_packet_number
- << ", prev_receive_timestamp:" << prev_receive_timestamp;
- return {};
- }
-
- if (prev_packet_number == packet_number + 1) {
- timestamp_ranges.back().range_end = i;
- } else {
- timestamp_ranges.push_back(AckTimestampRange());
- timestamp_ranges.back().gap = prev_packet_number - 2 - packet_number;
- timestamp_ranges.back().range_begin = i;
- timestamp_ranges.back().range_end = i;
- }
- }
-
- return timestamp_ranges;
-}
-
-int64_t QuicFramer::FrameAckTimestampRanges(
- const QuicAckFrame& frame,
- const absl::InlinedVector<AckTimestampRange, 2>& timestamp_ranges,
- QuicDataWriter* writer) const {
- int64_t size = 0;
- auto maybe_write_var_int62 = [&](uint64_t value) {
- size += QuicDataWriter::GetVarInt62Len(value);
- if (writer != nullptr && !writer->WriteVarInt62(value)) {
- return false;
- }
- return true;
- };
-
- if (!maybe_write_var_int62(timestamp_ranges.size())) {
- return -1;
- }
-
- // |effective_prev_time| is the exponent-encoded timestamp of the previous
- // packet.
- absl::optional<QuicTime> effective_prev_time;
- for (const AckTimestampRange& range : timestamp_ranges) {
- QUIC_DVLOG(3) << "Range: gap:" << range.gap << ", beg:" << range.range_begin
- << ", end:" << range.range_end;
- if (!maybe_write_var_int62(range.gap)) {
- return -1;
- }
-
- if (!maybe_write_var_int62(range.range_begin - range.range_end + 1)) {
- return -1;
- }
-
- for (int64_t i = range.range_begin; i >= range.range_end; --i) {
- const QuicTime receive_timestamp = frame.received_packet_times[i].second;
- uint64_t time_delta;
- if (effective_prev_time.has_value()) {
- time_delta =
- (*effective_prev_time - receive_timestamp).ToMicroseconds();
- QUIC_DVLOG(3) << "time_delta:" << time_delta
- << ", exponent:" << receive_timestamps_exponent_
- << ", effective_prev_time:" << *effective_prev_time
- << ", recv_time:" << receive_timestamp;
- time_delta = time_delta >> receive_timestamps_exponent_;
- effective_prev_time = effective_prev_time.value() -
- QuicTime::Delta::FromMicroseconds(
- time_delta << receive_timestamps_exponent_);
- } else {
- // The first delta is from framer creation to the current receive
- // timestamp (forward in time), whereas in the common case subsequent
- // deltas move backwards in time.
- time_delta = (receive_timestamp - creation_time_).ToMicroseconds();
- QUIC_DVLOG(3) << "First time_delta:" << time_delta
- << ", exponent:" << receive_timestamps_exponent_
- << ", recv_time:" << receive_timestamp
- << ", creation_time:" << creation_time_;
- // Round up the first exponent-encoded time delta so that the next
- // receive timestamp is guaranteed to be decreasing.
- time_delta = ((time_delta - 1) >> receive_timestamps_exponent_) + 1;
- effective_prev_time =
- creation_time_ + QuicTime::Delta::FromMicroseconds(
- time_delta << receive_timestamps_exponent_);
- }
-
- if (!maybe_write_var_int62(time_delta)) {
- return -1;
- }
- }
- }
-
- return size;
-}
-
-bool QuicFramer::AppendIetfTimestampsToAckFrame(const QuicAckFrame& frame,
- QuicDataWriter* writer) {
- QUICHE_DCHECK(!frame.received_packet_times.empty());
- std::string detailed_error;
- const absl::InlinedVector<AckTimestampRange, 2> timestamp_ranges =
- GetAckTimestampRanges(frame, detailed_error);
- if (!detailed_error.empty()) {
- set_detailed_error(std::move(detailed_error));
- return false;
- }
-
- // Compute the size first using a null writer.
- int64_t size =
- FrameAckTimestampRanges(frame, timestamp_ranges, /*writer=*/nullptr);
- if (size > static_cast<int64_t>(writer->capacity() - writer->length())) {
- QUIC_DVLOG(1) << "Insufficient room to write IETF ack receive timestamps. "
- "size_remain:"
- << (writer->capacity() - writer->length())
- << ", size_needed:" << size;
- // Write a Timestamp Range Count of 0.
- return writer->WriteVarInt62(0);
- }
-
- return FrameAckTimestampRanges(frame, timestamp_ranges, writer) > 0;
-}
-
-bool QuicFramer::AppendStopWaitingFrame(const QuicPacketHeader& header,
- const QuicStopWaitingFrame& frame,
- QuicDataWriter* writer) {
- QUICHE_DCHECK(!version_.HasIetfInvariantHeader());
- QUICHE_DCHECK(frame.least_unacked.IsInitialized());
- QUICHE_DCHECK_GE(header.packet_number, frame.least_unacked);
- const uint64_t least_unacked_delta =
- header.packet_number - frame.least_unacked;
- const uint64_t length_shift = header.packet_number_length * 8;
-
- if (least_unacked_delta >> length_shift > 0) {
- QUIC_BUG(quic_bug_10850_86)
- << "packet_number_length " << header.packet_number_length
- << " is too small for least_unacked_delta: " << least_unacked_delta
- << " packet_number:" << header.packet_number
- << " least_unacked:" << frame.least_unacked
- << " version:" << version_.transport_version;
- return false;
- }
- if (least_unacked_delta == 0) {
- return writer->WriteBytesToUInt64(header.packet_number_length,
- least_unacked_delta);
- }
- if (!AppendPacketNumber(header.packet_number_length,
- QuicPacketNumber(least_unacked_delta), writer)) {
- QUIC_BUG(quic_bug_10850_87)
- << " seq failed: " << header.packet_number_length;
- return false;
- }
-
- return true;
-}
-
-bool QuicFramer::AppendIetfAckFrameAndTypeByte(const QuicAckFrame& frame,
- QuicDataWriter* writer) {
- uint8_t type = IETF_ACK;
- uint64_t ecn_size = 0;
- if (UseIetfAckWithReceiveTimestamp(frame)) {
- type = IETF_ACK_RECEIVE_TIMESTAMPS;
- } else if (frame.ecn_counters_populated &&
- (frame.ect_0_count || frame.ect_1_count || frame.ecn_ce_count)) {
- // Change frame type to ACK_ECN if any ECN count is available.
- type = IETF_ACK_ECN;
- ecn_size = (QuicDataWriter::GetVarInt62Len(frame.ect_0_count) +
- QuicDataWriter::GetVarInt62Len(frame.ect_1_count) +
- QuicDataWriter::GetVarInt62Len(frame.ecn_ce_count));
- }
-
- if (!writer->WriteVarInt62(type)) {
- set_detailed_error("No room for frame-type");
- return false;
- }
-
- QuicPacketNumber largest_acked = LargestAcked(frame);
- if (!writer->WriteVarInt62(largest_acked.ToUint64())) {
- set_detailed_error("No room for largest-acked in ack frame");
- return false;
- }
-
- uint64_t ack_delay_time_us = kVarInt62MaxValue;
- if (!frame.ack_delay_time.IsInfinite()) {
- QUICHE_DCHECK_LE(0u, frame.ack_delay_time.ToMicroseconds());
- ack_delay_time_us = frame.ack_delay_time.ToMicroseconds();
- ack_delay_time_us = ack_delay_time_us >> local_ack_delay_exponent_;
- }
-
- if (!writer->WriteVarInt62(ack_delay_time_us)) {
- set_detailed_error("No room for ack-delay in ack frame");
- return false;
- }
-
- if (frame.packets.Empty() || frame.packets.Max() != largest_acked) {
- QUIC_BUG(quic_bug_10850_88) << "Malformed ack frame: " << frame;
- set_detailed_error("Malformed ack frame");
- return false;
- }
-
- // Latch ack_block_count for potential truncation.
- const uint64_t ack_block_count = frame.packets.NumIntervals() - 1;
- QuicDataWriter count_writer(QuicDataWriter::GetVarInt62Len(ack_block_count),
- writer->data() + writer->length());
- if (!writer->WriteVarInt62(ack_block_count)) {
- set_detailed_error("No room for ack block count in ack frame");
- return false;
- }
- auto iter = frame.packets.rbegin();
- if (!writer->WriteVarInt62(iter->Length() - 1)) {
- set_detailed_error("No room for first ack block in ack frame");
- return false;
- }
- QuicPacketNumber previous_smallest = iter->min();
- ++iter;
- // Append remaining ACK blocks.
- uint64_t appended_ack_blocks = 0;
- for (; iter != frame.packets.rend(); ++iter) {
- const uint64_t gap = previous_smallest - iter->max() - 1;
- const uint64_t ack_range = iter->Length() - 1;
-
- if (type == IETF_ACK_RECEIVE_TIMESTAMPS &&
- writer->remaining() <
- static_cast<size_t>(QuicDataWriter::GetVarInt62Len(gap) +
- QuicDataWriter::GetVarInt62Len(ack_range) +
- QuicDataWriter::GetVarInt62Len(0))) {
- // If we write this ACK range we won't have space for a timestamp range
- // count of 0.
- break;
- } else if (writer->remaining() < ecn_size ||
- writer->remaining() - ecn_size <
- static_cast<size_t>(
- QuicDataWriter::GetVarInt62Len(gap) +
- QuicDataWriter::GetVarInt62Len(ack_range))) {
- // ACK range does not fit, truncate it.
- break;
- }
- const bool success =
- writer->WriteVarInt62(gap) && writer->WriteVarInt62(ack_range);
- QUICHE_DCHECK(success);
- previous_smallest = iter->min();
- ++appended_ack_blocks;
- }
-
- if (appended_ack_blocks < ack_block_count) {
- // Truncation is needed, rewrite the ack block count.
- if (QuicDataWriter::GetVarInt62Len(appended_ack_blocks) !=
- QuicDataWriter::GetVarInt62Len(ack_block_count) ||
- !count_writer.WriteVarInt62(appended_ack_blocks)) {
- // This should never happen as ack_block_count is limited by
- // max_ack_ranges_.
- QUIC_BUG(quic_bug_10850_89)
- << "Ack frame truncation fails. ack_block_count: " << ack_block_count
- << ", appended count: " << appended_ack_blocks;
- set_detailed_error("ACK frame truncation fails");
- return false;
- }
- QUIC_DLOG(INFO) << ENDPOINT << "ACK ranges get truncated from "
- << ack_block_count << " to " << appended_ack_blocks;
- }
-
- if (type == IETF_ACK_ECN) {
- // Encode the ECN counts.
- if (!writer->WriteVarInt62(frame.ect_0_count)) {
- set_detailed_error("No room for ect_0_count in ack frame");
- return false;
- }
- if (!writer->WriteVarInt62(frame.ect_1_count)) {
- set_detailed_error("No room for ect_1_count in ack frame");
- return false;
- }
- if (!writer->WriteVarInt62(frame.ecn_ce_count)) {
- set_detailed_error("No room for ecn_ce_count in ack frame");
- return false;
- }
- }
-
- if (type == IETF_ACK_RECEIVE_TIMESTAMPS) {
- if (!AppendIetfTimestampsToAckFrame(frame, writer)) {
- return false;
- }
- }
-
- return true;
-}
-
-bool QuicFramer::AppendRstStreamFrame(const QuicRstStreamFrame& frame,
- QuicDataWriter* writer) {
- if (VersionHasIetfQuicFrames(version_.transport_version)) {
- return AppendIetfResetStreamFrame(frame, writer);
- }
- if (!writer->WriteUInt32(frame.stream_id)) {
- return false;
- }
-
- if (!writer->WriteUInt64(frame.byte_offset)) {
- return false;
- }
-
- uint32_t error_code = static_cast<uint32_t>(frame.error_code);
- if (!writer->WriteUInt32(error_code)) {
- return false;
- }
-
- return true;
-}
-
-bool QuicFramer::AppendConnectionCloseFrame(
- const QuicConnectionCloseFrame& frame, QuicDataWriter* writer) {
- if (VersionHasIetfQuicFrames(version_.transport_version)) {
- return AppendIetfConnectionCloseFrame(frame, writer);
- }
- uint32_t error_code = static_cast<uint32_t>(frame.wire_error_code);
- if (!writer->WriteUInt32(error_code)) {
- return false;
- }
- if (!writer->WriteStringPiece16(TruncateErrorString(frame.error_details))) {
- return false;
- }
- return true;
-}
-
-bool QuicFramer::AppendGoAwayFrame(const QuicGoAwayFrame& frame,
- QuicDataWriter* writer) {
- uint32_t error_code = static_cast<uint32_t>(frame.error_code);
- if (!writer->WriteUInt32(error_code)) {
- return false;
- }
- uint32_t stream_id = static_cast<uint32_t>(frame.last_good_stream_id);
- if (!writer->WriteUInt32(stream_id)) {
- return false;
- }
- if (!writer->WriteStringPiece16(TruncateErrorString(frame.reason_phrase))) {
- return false;
- }
- return true;
-}
-
-bool QuicFramer::AppendWindowUpdateFrame(const QuicWindowUpdateFrame& frame,
- QuicDataWriter* writer) {
- uint32_t stream_id = static_cast<uint32_t>(frame.stream_id);
- if (!writer->WriteUInt32(stream_id)) {
- return false;
- }
- if (!writer->WriteUInt64(frame.max_data)) {
- return false;
- }
- return true;
-}
-
-bool QuicFramer::AppendBlockedFrame(const QuicBlockedFrame& frame,
- QuicDataWriter* writer) {
- if (VersionHasIetfQuicFrames(version_.transport_version)) {
- if (frame.stream_id == QuicUtils::GetInvalidStreamId(transport_version())) {
- return AppendDataBlockedFrame(frame, writer);
- }
- return AppendStreamDataBlockedFrame(frame, writer);
- }
- uint32_t stream_id = static_cast<uint32_t>(frame.stream_id);
- if (!writer->WriteUInt32(stream_id)) {
- return false;
- }
- return true;
-}
-
-bool QuicFramer::AppendPaddingFrame(const QuicPaddingFrame& frame,
- QuicDataWriter* writer) {
- if (frame.num_padding_bytes == 0) {
- return false;
- }
- if (frame.num_padding_bytes < 0) {
- QUIC_BUG_IF(quic_bug_12975_9, frame.num_padding_bytes != -1);
- writer->WritePadding();
- return true;
- }
- // Please note, num_padding_bytes includes type byte which has been written.
- return writer->WritePaddingBytes(frame.num_padding_bytes - 1);
-}
-
-bool QuicFramer::AppendMessageFrameAndTypeByte(const QuicMessageFrame& frame,
- bool last_frame_in_packet,
- QuicDataWriter* writer) {
- uint8_t type_byte;
- if (VersionHasIetfQuicFrames(version_.transport_version)) {
- type_byte = last_frame_in_packet ? IETF_EXTENSION_MESSAGE_NO_LENGTH_V99
- : IETF_EXTENSION_MESSAGE_V99;
- } else {
- type_byte = last_frame_in_packet ? IETF_EXTENSION_MESSAGE_NO_LENGTH
- : IETF_EXTENSION_MESSAGE;
- }
- if (!writer->WriteUInt8(type_byte)) {
- return false;
- }
- if (!last_frame_in_packet && !writer->WriteVarInt62(frame.message_length)) {
- return false;
- }
- for (const auto& slice : frame.message_data) {
- if (!writer->WriteBytes(slice.data(), slice.length())) {
- return false;
- }
- }
- return true;
-}
-
-bool QuicFramer::RaiseError(QuicErrorCode error) {
- QUIC_DLOG(INFO) << ENDPOINT << "Error: " << QuicErrorCodeToString(error)
- << " detail: " << detailed_error_;
- set_error(error);
- if (visitor_) {
- visitor_->OnError(this);
- }
- return false;
-}
-
-bool QuicFramer::IsVersionNegotiation(
- const QuicPacketHeader& header, bool packet_has_ietf_packet_header) const {
- if (!packet_has_ietf_packet_header &&
- perspective_ == Perspective::IS_CLIENT) {
- return header.version_flag;
- }
- if (header.form == IETF_QUIC_SHORT_HEADER_PACKET) {
- return false;
- }
- return header.long_packet_type == VERSION_NEGOTIATION;
-}
-
-bool QuicFramer::AppendIetfConnectionCloseFrame(
- const QuicConnectionCloseFrame& frame, QuicDataWriter* writer) {
- if (frame.close_type != IETF_QUIC_TRANSPORT_CONNECTION_CLOSE &&
- frame.close_type != IETF_QUIC_APPLICATION_CONNECTION_CLOSE) {
- QUIC_BUG(quic_bug_10850_90)
- << "Invalid close_type for writing IETF CONNECTION CLOSE.";
- set_detailed_error("Invalid close_type for writing IETF CONNECTION CLOSE.");
- return false;
- }
-
- if (!writer->WriteVarInt62(frame.wire_error_code)) {
- set_detailed_error("Can not write connection close frame error code");
- return false;
- }
-
- if (frame.close_type == IETF_QUIC_TRANSPORT_CONNECTION_CLOSE) {
- // Write the frame-type of the frame causing the error only
- // if it's a CONNECTION_CLOSE/Transport.
- if (!writer->WriteVarInt62(frame.transport_close_frame_type)) {
- set_detailed_error("Writing frame type failed.");
- return false;
- }
- }
-
- // There may be additional error information available in the extracted error
- // code. Encode the error information in the reason phrase and serialize the
- // result.
- std::string final_error_string =
- GenerateErrorString(frame.error_details, frame.quic_error_code);
- if (!writer->WriteStringPieceVarInt62(
- TruncateErrorString(final_error_string))) {
- set_detailed_error("Can not write connection close phrase");
- return false;
- }
- return true;
-}
-
-bool QuicFramer::ProcessIetfConnectionCloseFrame(
- QuicDataReader* reader, QuicConnectionCloseType type,
- QuicConnectionCloseFrame* frame) {
- frame->close_type = type;
-
- uint64_t error_code;
- if (!reader->ReadVarInt62(&error_code)) {
- set_detailed_error("Unable to read connection close error code.");
- return false;
- }
-
- frame->wire_error_code = error_code;
-
- if (type == IETF_QUIC_TRANSPORT_CONNECTION_CLOSE) {
- // The frame-type of the frame causing the error is present only
- // if it's a CONNECTION_CLOSE/Transport.
- if (!reader->ReadVarInt62(&frame->transport_close_frame_type)) {
- set_detailed_error("Unable to read connection close frame type.");
- return false;
- }
- }
-
- uint64_t phrase_length;
- if (!reader->ReadVarInt62(&phrase_length)) {
- set_detailed_error("Unable to read connection close error details.");
- return false;
- }
-
- absl::string_view phrase;
- if (!reader->ReadStringPiece(&phrase, static_cast<size_t>(phrase_length))) {
- set_detailed_error("Unable to read connection close error details.");
- return false;
- }
- frame->error_details = std::string(phrase);
-
- // The frame may have an extracted error code in it. Look for it and
- // extract it. If it's not present, MaybeExtract will return
- // QUIC_IETF_GQUIC_ERROR_MISSING.
- MaybeExtractQuicErrorCode(frame);
- return true;
-}
-
-// IETF Quic Path Challenge/Response frames.
-bool QuicFramer::ProcessPathChallengeFrame(QuicDataReader* reader,
- QuicPathChallengeFrame* frame) {
- if (!reader->ReadBytes(frame->data_buffer.data(),
- frame->data_buffer.size())) {
- set_detailed_error("Can not read path challenge data.");
- return false;
- }
- return true;
-}
-
-bool QuicFramer::ProcessPathResponseFrame(QuicDataReader* reader,
- QuicPathResponseFrame* frame) {
- if (!reader->ReadBytes(frame->data_buffer.data(),
- frame->data_buffer.size())) {
- set_detailed_error("Can not read path response data.");
- return false;
- }
- return true;
-}
-
-bool QuicFramer::AppendPathChallengeFrame(const QuicPathChallengeFrame& frame,
- QuicDataWriter* writer) {
- if (!writer->WriteBytes(frame.data_buffer.data(), frame.data_buffer.size())) {
- set_detailed_error("Writing Path Challenge data failed.");
- return false;
- }
- return true;
-}
-
-bool QuicFramer::AppendPathResponseFrame(const QuicPathResponseFrame& frame,
- QuicDataWriter* writer) {
- if (!writer->WriteBytes(frame.data_buffer.data(), frame.data_buffer.size())) {
- set_detailed_error("Writing Path Response data failed.");
- return false;
- }
- return true;
-}
-
-// Add a new ietf-format stream reset frame.
-// General format is
-// stream id
-// application error code
-// final offset
-bool QuicFramer::AppendIetfResetStreamFrame(const QuicRstStreamFrame& frame,
- QuicDataWriter* writer) {
- if (!writer->WriteVarInt62(static_cast<uint64_t>(frame.stream_id))) {
- set_detailed_error("Writing reset-stream stream id failed.");
- return false;
- }
- if (!writer->WriteVarInt62(static_cast<uint64_t>(frame.ietf_error_code))) {
- set_detailed_error("Writing reset-stream error code failed.");
- return false;
- }
- if (!writer->WriteVarInt62(static_cast<uint64_t>(frame.byte_offset))) {
- set_detailed_error("Writing reset-stream final-offset failed.");
- return false;
- }
- return true;
-}
-
-bool QuicFramer::ProcessIetfResetStreamFrame(QuicDataReader* reader,
- QuicRstStreamFrame* frame) {
- // Get Stream ID from frame. ReadVarIntStreamID returns false
- // if either A) there is a read error or B) the resulting value of
- // the Stream ID is larger than the maximum allowed value.
- if (!ReadUint32FromVarint62(reader, IETF_RST_STREAM, &frame->stream_id)) {
- return false;
- }
-
- if (!reader->ReadVarInt62(&frame->ietf_error_code)) {
- set_detailed_error("Unable to read rst stream error code.");
- return false;
- }
-
- frame->error_code =
- IetfResetStreamErrorCodeToRstStreamErrorCode(frame->ietf_error_code);
-
- if (!reader->ReadVarInt62(&frame->byte_offset)) {
- set_detailed_error("Unable to read rst stream sent byte offset.");
- return false;
- }
- return true;
-}
-
-bool QuicFramer::ProcessStopSendingFrame(
- QuicDataReader* reader, QuicStopSendingFrame* stop_sending_frame) {
- if (!ReadUint32FromVarint62(reader, IETF_STOP_SENDING,
- &stop_sending_frame->stream_id)) {
- return false;
- }
-
- if (!reader->ReadVarInt62(&stop_sending_frame->ietf_error_code)) {
- set_detailed_error("Unable to read stop sending application error code.");
- return false;
- }
-
- stop_sending_frame->error_code = IetfResetStreamErrorCodeToRstStreamErrorCode(
- stop_sending_frame->ietf_error_code);
- return true;
-}
-
-bool QuicFramer::AppendStopSendingFrame(
- const QuicStopSendingFrame& stop_sending_frame, QuicDataWriter* writer) {
- if (!writer->WriteVarInt62(stop_sending_frame.stream_id)) {
- set_detailed_error("Can not write stop sending stream id");
- return false;
- }
- if (!writer->WriteVarInt62(
- static_cast<uint64_t>(stop_sending_frame.ietf_error_code))) {
- set_detailed_error("Can not write application error code");
- return false;
- }
- return true;
-}
-
-// Append/process IETF-Format MAX_DATA Frame
-bool QuicFramer::AppendMaxDataFrame(const QuicWindowUpdateFrame& frame,
- QuicDataWriter* writer) {
- if (!writer->WriteVarInt62(frame.max_data)) {
- set_detailed_error("Can not write MAX_DATA byte-offset");
- return false;
- }
- return true;
-}
-
-bool QuicFramer::ProcessMaxDataFrame(QuicDataReader* reader,
- QuicWindowUpdateFrame* frame) {
- frame->stream_id = QuicUtils::GetInvalidStreamId(transport_version());
- if (!reader->ReadVarInt62(&frame->max_data)) {
- set_detailed_error("Can not read MAX_DATA byte-offset");
- return false;
- }
- return true;
-}
-
-// Append/process IETF-Format MAX_STREAM_DATA Frame
-bool QuicFramer::AppendMaxStreamDataFrame(const QuicWindowUpdateFrame& frame,
- QuicDataWriter* writer) {
- if (!writer->WriteVarInt62(frame.stream_id)) {
- set_detailed_error("Can not write MAX_STREAM_DATA stream id");
- return false;
- }
- if (!writer->WriteVarInt62(frame.max_data)) {
- set_detailed_error("Can not write MAX_STREAM_DATA byte-offset");
- return false;
- }
- return true;
-}
-
-bool QuicFramer::ProcessMaxStreamDataFrame(QuicDataReader* reader,
- QuicWindowUpdateFrame* frame) {
- if (!ReadUint32FromVarint62(reader, IETF_MAX_STREAM_DATA,
- &frame->stream_id)) {
- return false;
- }
- if (!reader->ReadVarInt62(&frame->max_data)) {
- set_detailed_error("Can not read MAX_STREAM_DATA byte-count");
- return false;
- }
- return true;
-}
-
-bool QuicFramer::AppendMaxStreamsFrame(const QuicMaxStreamsFrame& frame,
- QuicDataWriter* writer) {
- if (!writer->WriteVarInt62(frame.stream_count)) {
- set_detailed_error("Can not write MAX_STREAMS stream count");
- return false;
- }
- return true;
-}
-
-bool QuicFramer::ProcessMaxStreamsFrame(QuicDataReader* reader,
- QuicMaxStreamsFrame* frame,
- uint64_t frame_type) {
- if (!ReadUint32FromVarint62(reader,
- static_cast<QuicIetfFrameType>(frame_type),
- &frame->stream_count)) {
- return false;
- }
- frame->unidirectional = (frame_type == IETF_MAX_STREAMS_UNIDIRECTIONAL);
- return true;
-}
-
-bool QuicFramer::AppendDataBlockedFrame(const QuicBlockedFrame& frame,
- QuicDataWriter* writer) {
- if (!writer->WriteVarInt62(frame.offset)) {
- set_detailed_error("Can not write blocked offset.");
- return false;
- }
- return true;
-}
-
-bool QuicFramer::ProcessDataBlockedFrame(QuicDataReader* reader,
- QuicBlockedFrame* frame) {
- // Indicates that it is a BLOCKED frame (as opposed to STREAM_BLOCKED).
- frame->stream_id = QuicUtils::GetInvalidStreamId(transport_version());
- if (!reader->ReadVarInt62(&frame->offset)) {
- set_detailed_error("Can not read blocked offset.");
- return false;
- }
- return true;
-}
-
-bool QuicFramer::AppendStreamDataBlockedFrame(const QuicBlockedFrame& frame,
- QuicDataWriter* writer) {
- if (!writer->WriteVarInt62(frame.stream_id)) {
- set_detailed_error("Can not write stream blocked stream id.");
- return false;
- }
- if (!writer->WriteVarInt62(frame.offset)) {
- set_detailed_error("Can not write stream blocked offset.");
- return false;
- }
- return true;
-}
-
-bool QuicFramer::ProcessStreamDataBlockedFrame(QuicDataReader* reader,
- QuicBlockedFrame* frame) {
- if (!ReadUint32FromVarint62(reader, IETF_STREAM_DATA_BLOCKED,
- &frame->stream_id)) {
- return false;
- }
- if (!reader->ReadVarInt62(&frame->offset)) {
- set_detailed_error("Can not read stream blocked offset.");
- return false;
- }
- return true;
-}
-
-bool QuicFramer::AppendStreamsBlockedFrame(const QuicStreamsBlockedFrame& frame,
- QuicDataWriter* writer) {
- if (!writer->WriteVarInt62(frame.stream_count)) {
- set_detailed_error("Can not write STREAMS_BLOCKED stream count");
- return false;
- }
- return true;
-}
-
-bool QuicFramer::ProcessStreamsBlockedFrame(QuicDataReader* reader,
- QuicStreamsBlockedFrame* frame,
- uint64_t frame_type) {
- if (!ReadUint32FromVarint62(reader,
- static_cast<QuicIetfFrameType>(frame_type),
- &frame->stream_count)) {
- return false;
- }
- if (frame->stream_count > QuicUtils::GetMaxStreamCount()) {
- // If stream count is such that the resulting stream ID would exceed our
- // implementation limit, generate an error.
- set_detailed_error(
- "STREAMS_BLOCKED stream count exceeds implementation limit.");
- return false;
- }
- frame->unidirectional = (frame_type == IETF_STREAMS_BLOCKED_UNIDIRECTIONAL);
- return true;
-}
-
-bool QuicFramer::AppendNewConnectionIdFrame(
- const QuicNewConnectionIdFrame& frame, QuicDataWriter* writer) {
- if (!writer->WriteVarInt62(frame.sequence_number)) {
- set_detailed_error("Can not write New Connection ID sequence number");
- return false;
- }
- if (!writer->WriteVarInt62(frame.retire_prior_to)) {
- set_detailed_error("Can not write New Connection ID retire_prior_to");
- return false;
- }
- if (!writer->WriteLengthPrefixedConnectionId(frame.connection_id)) {
- set_detailed_error("Can not write New Connection ID frame connection ID");
- return false;
- }
-
- if (!writer->WriteBytes(
- static_cast<const void*>(&frame.stateless_reset_token),
- sizeof(frame.stateless_reset_token))) {
- set_detailed_error("Can not write New Connection ID Reset Token");
- return false;
- }
- return true;
-}
-
-bool QuicFramer::ProcessNewConnectionIdFrame(QuicDataReader* reader,
- QuicNewConnectionIdFrame* frame) {
- if (!reader->ReadVarInt62(&frame->sequence_number)) {
- set_detailed_error(
- "Unable to read new connection ID frame sequence number.");
- return false;
- }
-
- if (!reader->ReadVarInt62(&frame->retire_prior_to)) {
- set_detailed_error(
- "Unable to read new connection ID frame retire_prior_to.");
- return false;
- }
- if (frame->retire_prior_to > frame->sequence_number) {
- set_detailed_error("Retire_prior_to > sequence_number.");
- return false;
- }
-
- if (!reader->ReadLengthPrefixedConnectionId(&frame->connection_id)) {
- set_detailed_error("Unable to read new connection ID frame connection id.");
- return false;
- }
-
- if (!QuicUtils::IsConnectionIdValidForVersion(frame->connection_id,
- transport_version())) {
- set_detailed_error("Invalid new connection ID length for version.");
- return false;
- }
-
- if (!reader->ReadBytes(&frame->stateless_reset_token,
- sizeof(frame->stateless_reset_token))) {
- set_detailed_error("Can not read new connection ID frame reset token.");
- return false;
- }
- return true;
-}
-
-bool QuicFramer::AppendRetireConnectionIdFrame(
- const QuicRetireConnectionIdFrame& frame, QuicDataWriter* writer) {
- if (!writer->WriteVarInt62(frame.sequence_number)) {
- set_detailed_error("Can not write Retire Connection ID sequence number");
- return false;
- }
- return true;
-}
-
-bool QuicFramer::ProcessRetireConnectionIdFrame(
- QuicDataReader* reader, QuicRetireConnectionIdFrame* frame) {
- if (!reader->ReadVarInt62(&frame->sequence_number)) {
- set_detailed_error(
- "Unable to read retire connection ID frame sequence number.");
- return false;
- }
- return true;
-}
-
-bool QuicFramer::ReadUint32FromVarint62(QuicDataReader* reader,
- QuicIetfFrameType type,
- QuicStreamId* id) {
- uint64_t temp_uint64;
- if (!reader->ReadVarInt62(&temp_uint64)) {
- set_detailed_error("Unable to read " + QuicIetfFrameTypeString(type) +
- " frame stream id/count.");
- return false;
- }
- if (temp_uint64 > kMaxQuicStreamId) {
- set_detailed_error("Stream id/count of " + QuicIetfFrameTypeString(type) +
- "frame is too large.");
- return false;
- }
- *id = static_cast<uint32_t>(temp_uint64);
- return true;
-}
-
-uint8_t QuicFramer::GetStreamFrameTypeByte(const QuicStreamFrame& frame,
- bool last_frame_in_packet) const {
- if (VersionHasIetfQuicFrames(version_.transport_version)) {
- return GetIetfStreamFrameTypeByte(frame, last_frame_in_packet);
- }
- uint8_t type_byte = 0;
- // Fin bit.
- type_byte |= frame.fin ? kQuicStreamFinMask : 0;
-
- // Data Length bit.
- type_byte <<= kQuicStreamDataLengthShift;
- type_byte |= last_frame_in_packet ? 0 : kQuicStreamDataLengthMask;
-
- // Offset 3 bits.
- type_byte <<= kQuicStreamShift;
- const size_t offset_len = GetStreamOffsetSize(frame.offset);
- if (offset_len > 0) {
- type_byte |= offset_len - 1;
- }
-
- // stream id 2 bits.
- type_byte <<= kQuicStreamIdShift;
- type_byte |= GetStreamIdSize(frame.stream_id) - 1;
- type_byte |= kQuicFrameTypeStreamMask; // Set Stream Frame Type to 1.
-
- return type_byte;
-}
-
-uint8_t QuicFramer::GetIetfStreamFrameTypeByte(
- const QuicStreamFrame& frame, bool last_frame_in_packet) const {
- QUICHE_DCHECK(VersionHasIetfQuicFrames(version_.transport_version));
- uint8_t type_byte = IETF_STREAM;
- if (!last_frame_in_packet) {
- type_byte |= IETF_STREAM_FRAME_LEN_BIT;
- }
- if (frame.offset != 0) {
- type_byte |= IETF_STREAM_FRAME_OFF_BIT;
- }
- if (frame.fin) {
- type_byte |= IETF_STREAM_FRAME_FIN_BIT;
- }
- return type_byte;
-}
-
-void QuicFramer::InferPacketHeaderTypeFromVersion() {
- // This function should only be called when server connection negotiates the
- // version.
- QUICHE_DCHECK_EQ(perspective_, Perspective::IS_SERVER);
- QUICHE_DCHECK(!infer_packet_header_type_from_version_);
- infer_packet_header_type_from_version_ = true;
-}
-
-void QuicFramer::EnableMultiplePacketNumberSpacesSupport() {
- if (supports_multiple_packet_number_spaces_) {
- QUIC_BUG(quic_bug_10850_91)
- << "Multiple packet number spaces has already been enabled";
- return;
- }
- if (largest_packet_number_.IsInitialized()) {
- QUIC_BUG(quic_bug_10850_92)
- << "Try to enable multiple packet number spaces support after any "
- "packet has been received.";
- return;
- }
-
- supports_multiple_packet_number_spaces_ = true;
-}
-
-// static
-QuicErrorCode QuicFramer::ParsePublicHeaderDispatcher(
- const QuicEncryptedPacket& packet,
- uint8_t expected_destination_connection_id_length,
- PacketHeaderFormat* format, QuicLongHeaderType* long_packet_type,
- bool* version_present, bool* has_length_prefix,
- QuicVersionLabel* version_label, ParsedQuicVersion* parsed_version,
- QuicConnectionId* destination_connection_id,
- QuicConnectionId* source_connection_id,
- absl::optional<absl::string_view>* retry_token,
- std::string* detailed_error) {
- QuicDataReader reader(packet.data(), packet.length());
- if (reader.IsDoneReading()) {
- *detailed_error = "Unable to read first byte.";
- return QUIC_INVALID_PACKET_HEADER;
- }
- const uint8_t first_byte = reader.PeekByte();
- if ((first_byte & FLAGS_LONG_HEADER) == 0 &&
- (first_byte & FLAGS_FIXED_BIT) == 0 &&
- (first_byte & FLAGS_DEMULTIPLEXING_BIT) == 0) {
- // All versions of Google QUIC up to and including Q043 set
- // FLAGS_DEMULTIPLEXING_BIT to one on all client-to-server packets. Q044
- // and Q045 were never default-enabled in production. All subsequent
- // versions of Google QUIC (starting with Q046) require FLAGS_FIXED_BIT to
- // be set to one on all packets. All versions of IETF QUIC (since
- // draft-ietf-quic-transport-17 which was earlier than the first IETF QUIC
- // version that was deployed in production by any implementation) also
- // require FLAGS_FIXED_BIT to be set to one on all packets. If a packet
- // has the FLAGS_LONG_HEADER bit set to one, it could be a first flight
- // from an unknown future version that allows the other two bits to be set
- // to zero. Based on this, packets that have all three of those bits set
- // to zero are known to be invalid.
- *detailed_error = "Invalid flags.";
- return QUIC_INVALID_PACKET_HEADER;
- }
- const bool ietf_format = QuicUtils::IsIetfPacketHeader(first_byte);
- uint8_t unused_first_byte;
- QuicVariableLengthIntegerLength retry_token_length_length;
- absl::string_view maybe_retry_token;
- QuicErrorCode error_code = ParsePublicHeader(
- &reader, expected_destination_connection_id_length, ietf_format,
- &unused_first_byte, format, version_present, has_length_prefix,
- version_label, parsed_version, destination_connection_id,
- source_connection_id, long_packet_type, &retry_token_length_length,
- &maybe_retry_token, detailed_error);
- if (retry_token_length_length != VARIABLE_LENGTH_INTEGER_LENGTH_0) {
- *retry_token = maybe_retry_token;
- } else {
- retry_token->reset();
- }
- return error_code;
-}
-
-// static
-QuicErrorCode QuicFramer::ParsePublicHeaderGoogleQuic(
- QuicDataReader* reader, uint8_t* first_byte, PacketHeaderFormat* format,
- bool* version_present, QuicVersionLabel* version_label,
- ParsedQuicVersion* parsed_version,
- QuicConnectionId* destination_connection_id, std::string* detailed_error) {
- *format = GOOGLE_QUIC_PACKET;
- *version_present = (*first_byte & PACKET_PUBLIC_FLAGS_VERSION) != 0;
- uint8_t destination_connection_id_length = 0;
- if ((*first_byte & PACKET_PUBLIC_FLAGS_8BYTE_CONNECTION_ID) != 0) {
- destination_connection_id_length = kQuicDefaultConnectionIdLength;
- }
- if (!reader->ReadConnectionId(destination_connection_id,
- destination_connection_id_length)) {
- *detailed_error = "Unable to read ConnectionId.";
- return QUIC_INVALID_PACKET_HEADER;
- }
- if (*version_present) {
- if (!ProcessVersionLabel(reader, version_label)) {
- *detailed_error = "Unable to read protocol version.";
- return QUIC_INVALID_PACKET_HEADER;
- }
- *parsed_version = ParseQuicVersionLabel(*version_label);
- }
- return QUIC_NO_ERROR;
-}
-
-namespace {
-
-const QuicVersionLabel kProxVersionLabel = 0x50524F58; // "PROX"
-
-inline bool PacketHasLengthPrefixedConnectionIds(
- const QuicDataReader& reader, ParsedQuicVersion parsed_version,
- QuicVersionLabel version_label, uint8_t first_byte) {
- if (parsed_version.IsKnown()) {
- return parsed_version.HasLengthPrefixedConnectionIds();
- }
-
- // Received unsupported version, check known old unsupported versions.
- if (QuicVersionLabelUses4BitConnectionIdLength(version_label)) {
- return false;
- }
-
- // Received unknown version, check connection ID length byte.
- if (reader.IsDoneReading()) {
- // This check is required to safely peek the connection ID length byte.
- return true;
- }
- const uint8_t connection_id_length_byte = reader.PeekByte();
-
- // Check for packets produced by older versions of
- // QuicFramer::WriteClientVersionNegotiationProbePacket
- if (first_byte == 0xc0 && (connection_id_length_byte & 0x0f) == 0 &&
- connection_id_length_byte >= 0x50 && version_label == 0xcabadaba) {
- return false;
- }
-
- // Check for munged packets with version tag PROX.
- if ((connection_id_length_byte & 0x0f) == 0 &&
- connection_id_length_byte >= 0x20 && version_label == kProxVersionLabel) {
- return false;
- }
-
- return true;
-}
-
-inline bool ParseLongHeaderConnectionIds(
- QuicDataReader& reader, bool has_length_prefix,
- QuicVersionLabel version_label, QuicConnectionId& destination_connection_id,
- QuicConnectionId& source_connection_id, std::string& detailed_error) {
- if (has_length_prefix) {
- if (!reader.ReadLengthPrefixedConnectionId(&destination_connection_id)) {
- detailed_error = "Unable to read destination connection ID.";
- return false;
- }
- if (!reader.ReadLengthPrefixedConnectionId(&source_connection_id)) {
- if (version_label == kProxVersionLabel) {
- // The "PROX" version does not follow the length-prefixed invariants,
- // and can therefore attempt to read a payload byte and interpret it
- // as the source connection ID length, which could fail to parse.
- // In that scenario we keep the source connection ID empty but mark
- // parsing as successful.
- return true;
- }
- detailed_error = "Unable to read source connection ID.";
- return false;
- }
- } else {
- // Parse connection ID lengths.
- uint8_t connection_id_lengths_byte;
- if (!reader.ReadUInt8(&connection_id_lengths_byte)) {
- detailed_error = "Unable to read connection ID lengths.";
- return false;
- }
- uint8_t destination_connection_id_length =
- (connection_id_lengths_byte & kDestinationConnectionIdLengthMask) >> 4;
- if (destination_connection_id_length != 0) {
- destination_connection_id_length += kConnectionIdLengthAdjustment;
- }
- uint8_t source_connection_id_length =
- connection_id_lengths_byte & kSourceConnectionIdLengthMask;
- if (source_connection_id_length != 0) {
- source_connection_id_length += kConnectionIdLengthAdjustment;
- }
-
- // Read destination connection ID.
- if (!reader.ReadConnectionId(&destination_connection_id,
- destination_connection_id_length)) {
- detailed_error = "Unable to read destination connection ID.";
- return false;
- }
-
- // Read source connection ID.
- if (!reader.ReadConnectionId(&source_connection_id,
- source_connection_id_length)) {
- detailed_error = "Unable to read source connection ID.";
- return false;
- }
- }
- return true;
-}
-
-} // namespace
-
-// static
-QuicErrorCode QuicFramer::ParsePublicHeader(
- QuicDataReader* reader, uint8_t expected_destination_connection_id_length,
- bool ietf_format, uint8_t* first_byte, PacketHeaderFormat* format,
- bool* version_present, bool* has_length_prefix,
- QuicVersionLabel* version_label, ParsedQuicVersion* parsed_version,
- QuicConnectionId* destination_connection_id,
- QuicConnectionId* source_connection_id,
- QuicLongHeaderType* long_packet_type,
- QuicVariableLengthIntegerLength* retry_token_length_length,
- absl::string_view* retry_token, std::string* detailed_error) {
- *version_present = false;
- *has_length_prefix = false;
- *version_label = 0;
- *parsed_version = UnsupportedQuicVersion();
- *source_connection_id = EmptyQuicConnectionId();
- *long_packet_type = INVALID_PACKET_TYPE;
- *retry_token_length_length = VARIABLE_LENGTH_INTEGER_LENGTH_0;
- *retry_token = absl::string_view();
- *detailed_error = "";
-
- if (!reader->ReadUInt8(first_byte)) {
- *detailed_error = "Unable to read first byte.";
- return QUIC_INVALID_PACKET_HEADER;
- }
-
- if (!ietf_format) {
- return ParsePublicHeaderGoogleQuic(
- reader, first_byte, format, version_present, version_label,
- parsed_version, destination_connection_id, detailed_error);
- }
-
- *format = GetIetfPacketHeaderFormat(*first_byte);
-
- if (*format == IETF_QUIC_SHORT_HEADER_PACKET) {
- // Read destination connection ID using
- // expected_destination_connection_id_length to determine its length.
- if (!reader->ReadConnectionId(destination_connection_id,
- expected_destination_connection_id_length)) {
- *detailed_error = "Unable to read destination connection ID.";
- return QUIC_INVALID_PACKET_HEADER;
- }
- return QUIC_NO_ERROR;
- }
-
- QUICHE_DCHECK_EQ(IETF_QUIC_LONG_HEADER_PACKET, *format);
- *version_present = true;
- if (!ProcessVersionLabel(reader, version_label)) {
- *detailed_error = "Unable to read protocol version.";
- return QUIC_INVALID_PACKET_HEADER;
- }
-
- if (*version_label == 0) {
- *long_packet_type = VERSION_NEGOTIATION;
- }
-
- // Parse version.
- *parsed_version = ParseQuicVersionLabel(*version_label);
-
- // Figure out which IETF QUIC invariants this packet follows.
- *has_length_prefix = PacketHasLengthPrefixedConnectionIds(
- *reader, *parsed_version, *version_label, *first_byte);
-
- // Parse connection IDs.
- if (!ParseLongHeaderConnectionIds(*reader, *has_length_prefix, *version_label,
- *destination_connection_id,
- *source_connection_id, *detailed_error)) {
- return QUIC_INVALID_PACKET_HEADER;
- }
-
- if (!parsed_version->IsKnown()) {
- // Skip parsing of long packet type and retry token for unknown versions.
- return QUIC_NO_ERROR;
- }
-
- // Parse long packet type.
- *long_packet_type = GetLongHeaderType(*first_byte, *parsed_version);
-
- switch (*long_packet_type) {
- case INVALID_PACKET_TYPE:
- *detailed_error = "Unable to parse long packet type.";
- return QUIC_INVALID_PACKET_HEADER;
- case INITIAL:
- if (!parsed_version->SupportsRetry()) {
- // Retry token is only present on initial packets for some versions.
- return QUIC_NO_ERROR;
- }
- break;
- default:
- return QUIC_NO_ERROR;
- }
-
- *retry_token_length_length = reader->PeekVarInt62Length();
- uint64_t retry_token_length;
- if (!reader->ReadVarInt62(&retry_token_length)) {
- *retry_token_length_length = VARIABLE_LENGTH_INTEGER_LENGTH_0;
- *detailed_error = "Unable to read retry token length.";
- return QUIC_INVALID_PACKET_HEADER;
- }
-
- if (!reader->ReadStringPiece(retry_token, retry_token_length)) {
- *detailed_error = "Unable to read retry token.";
- return QUIC_INVALID_PACKET_HEADER;
- }
-
- return QUIC_NO_ERROR;
-}
-
-// static
-bool QuicFramer::WriteClientVersionNegotiationProbePacket(
- char* packet_bytes, QuicByteCount packet_length,
- const char* destination_connection_id_bytes,
- uint8_t destination_connection_id_length) {
- if (packet_bytes == nullptr) {
- QUIC_BUG(quic_bug_10850_93) << "Invalid packet_bytes";
- return false;
- }
- if (packet_length < kMinPacketSizeForVersionNegotiation ||
- packet_length > 65535) {
- QUIC_BUG(quic_bug_10850_94) << "Invalid packet_length";
- return false;
- }
- if (destination_connection_id_length > kQuicMaxConnectionId4BitLength ||
- destination_connection_id_length < kQuicDefaultConnectionIdLength) {
- QUIC_BUG(quic_bug_10850_95) << "Invalid connection_id_length";
- return false;
- }
- // clang-format off
- const unsigned char packet_start_bytes[] = {
- // IETF long header with fixed bit set, type initial, all-0 encrypted bits.
- 0xc0,
- // Version, part of the IETF space reserved for negotiation.
- // This intentionally differs from QuicVersionReservedForNegotiation()
- // to allow differentiating them over the wire.
- 0xca, 0xba, 0xda, 0xda,
- };
- // clang-format on
- static_assert(sizeof(packet_start_bytes) == 5, "bad packet_start_bytes size");
- QuicDataWriter writer(packet_length, packet_bytes);
- if (!writer.WriteBytes(packet_start_bytes, sizeof(packet_start_bytes))) {
- QUIC_BUG(quic_bug_10850_96) << "Failed to write packet start";
- return false;
- }
-
- QuicConnectionId destination_connection_id(destination_connection_id_bytes,
- destination_connection_id_length);
- if (!AppendIetfConnectionIds(
- /*version_flag=*/true, /*use_length_prefix=*/true,
- destination_connection_id, EmptyQuicConnectionId(), &writer)) {
- QUIC_BUG(quic_bug_10850_97) << "Failed to write connection IDs";
- return false;
- }
- // Add 8 bytes of zeroes followed by 8 bytes of ones to ensure that this does
- // not parse with any known version. The zeroes make sure that packet numbers,
- // retry token lengths and payload lengths are parsed as zero, and if the
- // zeroes are treated as padding frames, 0xff is known to not parse as a
- // valid frame type.
- if (!writer.WriteUInt64(0) ||
- !writer.WriteUInt64(std::numeric_limits<uint64_t>::max())) {
- QUIC_BUG(quic_bug_10850_98) << "Failed to write 18 bytes";
- return false;
- }
- // Make sure the polite greeting below is padded to a 16-byte boundary to
- // make it easier to read in tcpdump.
- while (writer.length() % 16 != 0) {
- if (!writer.WriteUInt8(0)) {
- QUIC_BUG(quic_bug_10850_99) << "Failed to write padding byte";
- return false;
- }
- }
- // Add a polite greeting in case a human sees this in tcpdump.
- static const char polite_greeting[] =
- "This packet only exists to trigger IETF QUIC version negotiation. "
- "Please respond with a Version Negotiation packet indicating what "
- "versions you support. Thank you and have a nice day.";
- if (!writer.WriteBytes(polite_greeting, sizeof(polite_greeting))) {
- QUIC_BUG(quic_bug_10850_100) << "Failed to write polite greeting";
- return false;
- }
- // Fill the rest of the packet with zeroes.
- writer.WritePadding();
- QUICHE_DCHECK_EQ(0u, writer.remaining());
- return true;
-}
-
-// static
-bool QuicFramer::ParseServerVersionNegotiationProbeResponse(
- const char* packet_bytes, QuicByteCount packet_length,
- char* source_connection_id_bytes, uint8_t* source_connection_id_length_out,
- std::string* detailed_error) {
- if (detailed_error == nullptr) {
- QUIC_BUG(quic_bug_10850_101) << "Invalid error_details";
- return false;
- }
- *detailed_error = "";
- if (packet_bytes == nullptr) {
- *detailed_error = "Invalid packet_bytes";
- return false;
- }
- if (packet_length < 6) {
- *detailed_error = "Invalid packet_length";
- return false;
- }
- if (source_connection_id_bytes == nullptr) {
- *detailed_error = "Invalid source_connection_id_bytes";
- return false;
- }
- if (source_connection_id_length_out == nullptr) {
- *detailed_error = "Invalid source_connection_id_length_out";
- return false;
- }
- QuicDataReader reader(packet_bytes, packet_length);
- uint8_t type_byte = 0;
- if (!reader.ReadUInt8(&type_byte)) {
- *detailed_error = "Failed to read type byte";
- return false;
- }
- if ((type_byte & 0x80) == 0) {
- *detailed_error = "Packet does not have long header";
- return false;
- }
- uint32_t version = 0;
- if (!reader.ReadUInt32(&version)) {
- *detailed_error = "Failed to read version";
- return false;
- }
- if (version != 0) {
- *detailed_error = "Packet is not a version negotiation packet";
- return false;
- }
-
- QuicConnectionId destination_connection_id, source_connection_id;
- if (!reader.ReadLengthPrefixedConnectionId(&destination_connection_id)) {
- *detailed_error = "Failed to read destination connection ID";
- return false;
- }
- if (!reader.ReadLengthPrefixedConnectionId(&source_connection_id)) {
- *detailed_error = "Failed to read source connection ID";
- return false;
- }
-
- if (destination_connection_id.length() != 0) {
- *detailed_error = "Received unexpected destination connection ID length";
- return false;
- }
- if (*source_connection_id_length_out < source_connection_id.length()) {
- *detailed_error =
- absl::StrCat("*source_connection_id_length_out too small ",
- static_cast<int>(*source_connection_id_length_out), " < ",
- static_cast<int>(source_connection_id.length()));
- return false;
- }
-
- memcpy(source_connection_id_bytes, source_connection_id.data(),
- source_connection_id.length());
- *source_connection_id_length_out = source_connection_id.length();
-
- return true;
-}
-
-// Look for and parse the error code from the "<quic_error_code>:" text that
-// may be present at the start of the CONNECTION_CLOSE error details string.
-// This text, inserted by the peer if it's using Google's QUIC implementation,
-// contains additional error information that narrows down the exact error. If
-// the string is not found, or is not properly formed, it returns
-// ErrorCode::QUIC_IETF_GQUIC_ERROR_MISSING
-void MaybeExtractQuicErrorCode(QuicConnectionCloseFrame* frame) {
- std::vector<absl::string_view> ed = absl::StrSplit(frame->error_details, ':');
- uint64_t extracted_error_code;
- if (ed.size() < 2 || !quiche::QuicheTextUtils::IsAllDigits(ed[0]) ||
- !absl::SimpleAtoi(ed[0], &extracted_error_code)) {
- if (frame->close_type == IETF_QUIC_TRANSPORT_CONNECTION_CLOSE &&
- frame->wire_error_code == NO_IETF_QUIC_ERROR) {
- frame->quic_error_code = QUIC_NO_ERROR;
- } else {
- frame->quic_error_code = QUIC_IETF_GQUIC_ERROR_MISSING;
- }
- return;
- }
- // Return the error code (numeric) and the error details string without the
- // error code prefix. Note that Split returns everything up to, but not
- // including, the split character, so the length of ed[0] is just the number
- // of digits in the error number. In removing the prefix, 1 is added to the
- // length to account for the :
- absl::string_view x = absl::string_view(frame->error_details);
- x.remove_prefix(ed[0].length() + 1);
- frame->error_details = std::string(x);
- frame->quic_error_code = static_cast<QuicErrorCode>(extracted_error_code);
-}
-
-#undef ENDPOINT // undef for jumbo builds
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_framer.h b/chromium/net/third_party/quiche/src/quic/core/quic_framer.h
deleted file mode 100644
index 306f0491d58..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_framer.h
+++ /dev/null
@@ -1,1265 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_FRAMER_H_
-#define QUICHE_QUIC_CORE_QUIC_FRAMER_H_
-
-#include <cstddef>
-#include <cstdint>
-#include <memory>
-#include <string>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/crypto/quic_decrypter.h"
-#include "quic/core/crypto/quic_encrypter.h"
-#include "quic/core/crypto/quic_random.h"
-#include "quic/core/quic_connection_id.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-namespace test {
-class QuicFramerPeer;
-} // namespace test
-
-class QuicDataReader;
-class QuicDataWriter;
-class QuicFramer;
-class QuicStreamFrameDataProducer;
-
-// Number of bytes reserved for the frame type preceding each frame.
-const size_t kQuicFrameTypeSize = 1;
-// Number of bytes reserved for error code.
-const size_t kQuicErrorCodeSize = 4;
-// Number of bytes reserved to denote the length of error details field.
-const size_t kQuicErrorDetailsLengthSize = 2;
-
-// Maximum number of bytes reserved for stream id.
-const size_t kQuicMaxStreamIdSize = 4;
-// Maximum number of bytes reserved for byte offset in stream frame.
-const size_t kQuicMaxStreamOffsetSize = 8;
-// Number of bytes reserved to store payload length in stream frame.
-const size_t kQuicStreamPayloadLengthSize = 2;
-// Number of bytes to reserve for IQ Error codes (for the Connection Close,
-// Application Close, and Reset Stream frames).
-const size_t kQuicIetfQuicErrorCodeSize = 2;
-// Minimum size of the IETF QUIC Error Phrase's length field
-const size_t kIetfQuicMinErrorPhraseLengthSize = 1;
-
-// Size in bytes reserved for the delta time of the largest observed
-// packet number in ack frames.
-const size_t kQuicDeltaTimeLargestObservedSize = 2;
-// Size in bytes reserved for the number of received packets with timestamps.
-const size_t kQuicNumTimestampsSize = 1;
-// Size in bytes reserved for the number of missing packets in ack frames.
-const size_t kNumberOfNackRangesSize = 1;
-// Size in bytes reserved for the number of ack blocks in ack frames.
-const size_t kNumberOfAckBlocksSize = 1;
-// Maximum number of missing packet ranges that can fit within an ack frame.
-const size_t kMaxNackRanges = (1 << (kNumberOfNackRangesSize * 8)) - 1;
-// Maximum number of ack blocks that can fit within an ack frame.
-const size_t kMaxAckBlocks = (1 << (kNumberOfAckBlocksSize * 8)) - 1;
-
-// This class receives callbacks from the framer when packets
-// are processed.
-class QUIC_EXPORT_PRIVATE QuicFramerVisitorInterface {
- public:
- virtual ~QuicFramerVisitorInterface() {}
-
- // Called if an error is detected in the QUIC protocol.
- virtual void OnError(QuicFramer* framer) = 0;
-
- // Called only when |perspective_| is IS_SERVER and the framer gets a
- // packet with version flag true and the version on the packet doesn't match
- // |quic_version_|. The visitor should return true after it updates the
- // version of the |framer_| to |received_version| or false to stop processing
- // this packet.
- virtual bool OnProtocolVersionMismatch(
- ParsedQuicVersion received_version) = 0;
-
- // Called when a new packet has been received, before it
- // has been validated or processed.
- virtual void OnPacket() = 0;
-
- // Called when a public reset packet has been parsed but has not yet
- // been validated.
- virtual void OnPublicResetPacket(const QuicPublicResetPacket& packet) = 0;
-
- // Called only when |perspective_| is IS_CLIENT and a version negotiation
- // packet has been parsed.
- virtual void OnVersionNegotiationPacket(
- const QuicVersionNegotiationPacket& packet) = 0;
-
- // Called only when |perspective_| is IS_CLIENT and a retry packet has been
- // parsed. |new_connection_id| contains the value of the Source Connection
- // ID field, and |retry_token| contains the value of the Retry Token field.
- // On versions where UsesTls() is false,
- // |original_connection_id| contains the value of the Original Destination
- // Connection ID field, and both |retry_integrity_tag| and
- // |retry_without_tag| are empty.
- // On versions where UsesTls() is true,
- // |original_connection_id| is empty, |retry_integrity_tag| contains the
- // value of the Retry Integrity Tag field, and |retry_without_tag| contains
- // the entire RETRY packet except the Retry Integrity Tag field.
- virtual void OnRetryPacket(QuicConnectionId original_connection_id,
- QuicConnectionId new_connection_id,
- absl::string_view retry_token,
- absl::string_view retry_integrity_tag,
- absl::string_view retry_without_tag) = 0;
-
- // Called when all fields except packet number has been parsed, but has not
- // been authenticated. If it returns false, framing for this packet will
- // cease.
- virtual bool OnUnauthenticatedPublicHeader(
- const QuicPacketHeader& header) = 0;
-
- // Called when the unauthenticated portion of the header has been parsed.
- // If OnUnauthenticatedHeader returns false, framing for this packet will
- // cease.
- virtual bool OnUnauthenticatedHeader(const QuicPacketHeader& header) = 0;
-
- // Called when a packet has been decrypted. |length| is the packet length,
- // and |level| is the encryption level of the packet.
- virtual void OnDecryptedPacket(size_t length, EncryptionLevel level) = 0;
-
- // Called when the complete header of a packet had been parsed.
- // If OnPacketHeader returns false, framing for this packet will cease.
- virtual bool OnPacketHeader(const QuicPacketHeader& header) = 0;
-
- // Called when the packet being processed contains multiple IETF QUIC packets,
- // which is due to there being more data after what is covered by the length
- // field. |packet| contains the remaining data which can be processed.
- // Note that this is called when the framer parses the length field, before
- // it attempts to decrypt the first payload. It is the visitor's
- // responsibility to buffer the packet and call ProcessPacket on it
- // after the framer is done parsing the current payload. |packet| does not
- // own its internal buffer, the visitor should make a copy of it.
- virtual void OnCoalescedPacket(const QuicEncryptedPacket& packet) = 0;
-
- // Called when the packet being processed failed to decrypt.
- // |has_decryption_key| indicates whether the framer knew which decryption
- // key to use for this packet and already had a suitable key.
- virtual void OnUndecryptablePacket(const QuicEncryptedPacket& packet,
- EncryptionLevel decryption_level,
- bool has_decryption_key) = 0;
-
- // Called when a StreamFrame has been parsed.
- virtual bool OnStreamFrame(const QuicStreamFrame& frame) = 0;
-
- // Called when a CRYPTO frame has been parsed.
- virtual bool OnCryptoFrame(const QuicCryptoFrame& frame) = 0;
-
- // Called when largest acked of an AckFrame has been parsed.
- virtual bool OnAckFrameStart(QuicPacketNumber largest_acked,
- QuicTime::Delta ack_delay_time) = 0;
-
- // Called when ack range [start, end) of an AckFrame has been parsed.
- virtual bool OnAckRange(QuicPacketNumber start, QuicPacketNumber end) = 0;
-
- // Called when a timestamp in the AckFrame has been parsed.
- virtual bool OnAckTimestamp(QuicPacketNumber packet_number,
- QuicTime timestamp) = 0;
-
- // Called after the last ack range in an AckFrame has been parsed.
- // |start| is the starting value of the last ack range.
- virtual bool OnAckFrameEnd(QuicPacketNumber start) = 0;
-
- // Called when a StopWaitingFrame has been parsed.
- virtual bool OnStopWaitingFrame(const QuicStopWaitingFrame& frame) = 0;
-
- // Called when a QuicPaddingFrame has been parsed.
- virtual bool OnPaddingFrame(const QuicPaddingFrame& frame) = 0;
-
- // Called when a PingFrame has been parsed.
- virtual bool OnPingFrame(const QuicPingFrame& frame) = 0;
-
- // Called when a RstStreamFrame has been parsed.
- virtual bool OnRstStreamFrame(const QuicRstStreamFrame& frame) = 0;
-
- // Called when a ConnectionCloseFrame, of any type, has been parsed.
- virtual bool OnConnectionCloseFrame(
- const QuicConnectionCloseFrame& frame) = 0;
-
- // Called when a StopSendingFrame has been parsed.
- virtual bool OnStopSendingFrame(const QuicStopSendingFrame& frame) = 0;
-
- // Called when a PathChallengeFrame has been parsed.
- virtual bool OnPathChallengeFrame(const QuicPathChallengeFrame& frame) = 0;
-
- // Called when a PathResponseFrame has been parsed.
- virtual bool OnPathResponseFrame(const QuicPathResponseFrame& frame) = 0;
-
- // Called when a GoAwayFrame has been parsed.
- virtual bool OnGoAwayFrame(const QuicGoAwayFrame& frame) = 0;
-
- // Called when a WindowUpdateFrame has been parsed.
- virtual bool OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame) = 0;
-
- // Called when a BlockedFrame has been parsed.
- virtual bool OnBlockedFrame(const QuicBlockedFrame& frame) = 0;
-
- // Called when a NewConnectionIdFrame has been parsed.
- virtual bool OnNewConnectionIdFrame(
- const QuicNewConnectionIdFrame& frame) = 0;
-
- // Called when a RetireConnectionIdFrame has been parsed.
- virtual bool OnRetireConnectionIdFrame(
- const QuicRetireConnectionIdFrame& frame) = 0;
-
- // Called when a NewTokenFrame has been parsed.
- virtual bool OnNewTokenFrame(const QuicNewTokenFrame& frame) = 0;
-
- // Called when a message frame has been parsed.
- virtual bool OnMessageFrame(const QuicMessageFrame& frame) = 0;
-
- // Called when a handshake done frame has been parsed.
- virtual bool OnHandshakeDoneFrame(const QuicHandshakeDoneFrame& frame) = 0;
-
- // Called when an AckFrequencyFrame has been parsed.
- virtual bool OnAckFrequencyFrame(const QuicAckFrequencyFrame& frame) = 0;
-
- // Called when a packet has been completely processed.
- virtual void OnPacketComplete() = 0;
-
- // Called to check whether |token| is a valid stateless reset token.
- virtual bool IsValidStatelessResetToken(
- const StatelessResetToken& token) const = 0;
-
- // Called when an IETF stateless reset packet has been parsed and validated
- // with the stateless reset token.
- virtual void OnAuthenticatedIetfStatelessResetPacket(
- const QuicIetfStatelessResetPacket& packet) = 0;
-
- // Called when an IETF MaxStreams frame has been parsed.
- virtual bool OnMaxStreamsFrame(const QuicMaxStreamsFrame& frame) = 0;
-
- // Called when an IETF StreamsBlocked frame has been parsed.
- virtual bool OnStreamsBlockedFrame(const QuicStreamsBlockedFrame& frame) = 0;
-
- // Called when a Key Phase Update has been initiated. This is called for both
- // locally and peer initiated key updates. If the key update was locally
- // initiated, this does not indicate the peer has received the key update yet.
- virtual void OnKeyUpdate(KeyUpdateReason reason) = 0;
-
- // Called on the first decrypted packet in each key phase (including the
- // first key phase.)
- virtual void OnDecryptedFirstPacketInKeyPhase() = 0;
-
- // Called when the framer needs to generate a decrypter for the next key
- // phase. Each call should generate the key for phase n+1.
- virtual std::unique_ptr<QuicDecrypter>
- AdvanceKeysAndCreateCurrentOneRttDecrypter() = 0;
-
- // Called when the framer needs to generate an encrypter. The key corresponds
- // to the key phase of the last decrypter returned by
- // AdvanceKeysAndCreateCurrentOneRttDecrypter().
- virtual std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() = 0;
-};
-
-// Class for parsing and constructing QUIC packets. It has a
-// QuicFramerVisitorInterface that is called when packets are parsed.
-class QUIC_EXPORT_PRIVATE QuicFramer {
- public:
- // Constructs a new framer that installs a kNULL QuicEncrypter and
- // QuicDecrypter for level ENCRYPTION_INITIAL. |supported_versions| specifies
- // the list of supported QUIC versions. |quic_version_| is set to the maximum
- // version in |supported_versions|.
- QuicFramer(const ParsedQuicVersionVector& supported_versions,
- QuicTime creation_time,
- Perspective perspective,
- uint8_t expected_server_connection_id_length);
- QuicFramer(const QuicFramer&) = delete;
- QuicFramer& operator=(const QuicFramer&) = delete;
-
- virtual ~QuicFramer();
-
- // Returns true if |version| is a supported transport version.
- bool IsSupportedTransportVersion(const QuicTransportVersion version) const;
-
- // Returns true if |version| is a supported protocol version.
- bool IsSupportedVersion(const ParsedQuicVersion version) const;
-
- // Set callbacks to be called from the framer. A visitor must be set, or
- // else the framer will likely crash. It is acceptable for the visitor
- // to do nothing. If this is called multiple times, only the last visitor
- // will be used.
- void set_visitor(QuicFramerVisitorInterface* visitor) { visitor_ = visitor; }
-
- const ParsedQuicVersionVector& supported_versions() const {
- return supported_versions_;
- }
-
- QuicTransportVersion transport_version() const {
- return version_.transport_version;
- }
-
- ParsedQuicVersion version() const { return version_; }
-
- void set_version(const ParsedQuicVersion version);
-
- // Does not QUICHE_DCHECK for supported version. Used by tests to set
- // unsupported version to trigger version negotiation.
- void set_version_for_tests(const ParsedQuicVersion version) {
- version_ = version;
- }
-
- QuicErrorCode error() const { return error_; }
-
- // Allows enabling or disabling of timestamp processing and serialization.
- // TODO(ianswett): Remove the const once timestamps are negotiated via
- // transport params.
- void set_process_timestamps(bool process_timestamps) const {
- process_timestamps_ = process_timestamps;
- }
-
- // Sets the max number of receive timestamps to send per ACK frame.
- // TODO(wub): Remove the const once timestamps are negotiated via
- // transport params.
- void set_max_receive_timestamps_per_ack(uint32_t max_timestamps) const {
- max_receive_timestamps_per_ack_ = max_timestamps;
- }
-
- // Sets the exponent to use when writing/reading ACK receive timestamps.
- void set_receive_timestamps_exponent(uint32_t exponent) const {
- receive_timestamps_exponent_ = exponent;
- }
-
- // Pass a UDP packet into the framer for parsing.
- // Return true if the packet was processed successfully. |packet| must be a
- // single, complete UDP packet (not a frame of a packet). This packet
- // might be null padded past the end of the payload, which will be correctly
- // ignored.
- bool ProcessPacket(const QuicEncryptedPacket& packet);
-
- // Whether we are in the middle of a call to this->ProcessPacket.
- bool is_processing_packet() const { return is_processing_packet_; }
-
- // Largest size in bytes of all stream frame fields without the payload.
- static size_t GetMinStreamFrameSize(QuicTransportVersion version,
- QuicStreamId stream_id,
- QuicStreamOffset offset,
- bool last_frame_in_packet,
- size_t data_length);
- // Returns the overhead of framing a CRYPTO frame with the specific offset and
- // data length provided, but not counting the size of the data payload.
- static size_t GetMinCryptoFrameSize(QuicStreamOffset offset,
- QuicPacketLength data_length);
- static size_t GetMessageFrameSize(QuicTransportVersion version,
- bool last_frame_in_packet,
- QuicByteCount length);
- // Size in bytes of all ack frame fields without the missing packets or ack
- // blocks.
- static size_t GetMinAckFrameSize(QuicTransportVersion version,
- const QuicAckFrame& ack_frame,
- uint32_t local_ack_delay_exponent,
- bool use_ietf_ack_with_receive_timestamp);
- // Size in bytes of a stop waiting frame.
- static size_t GetStopWaitingFrameSize(
- QuicPacketNumberLength packet_number_length);
- // Size in bytes of all reset stream frame fields.
- static size_t GetRstStreamFrameSize(QuicTransportVersion version,
- const QuicRstStreamFrame& frame);
- // Size in bytes of all ack frenquency frame fields.
- static size_t GetAckFrequencyFrameSize(const QuicAckFrequencyFrame& frame);
- // Size in bytes of all connection close frame fields, including the error
- // details.
- static size_t GetConnectionCloseFrameSize(
- QuicTransportVersion version,
- const QuicConnectionCloseFrame& frame);
- // Size in bytes of all GoAway frame fields without the reason phrase.
- static size_t GetMinGoAwayFrameSize();
- // Size in bytes of all WindowUpdate frame fields.
- // For version 99, determines whether a MAX DATA or MAX STREAM DATA frame will
- // be generated and calculates the appropriate size.
- static size_t GetWindowUpdateFrameSize(QuicTransportVersion version,
- const QuicWindowUpdateFrame& frame);
- // Size in bytes of all MaxStreams frame fields.
- static size_t GetMaxStreamsFrameSize(QuicTransportVersion version,
- const QuicMaxStreamsFrame& frame);
- // Size in bytes of all StreamsBlocked frame fields.
- static size_t GetStreamsBlockedFrameSize(
- QuicTransportVersion version,
- const QuicStreamsBlockedFrame& frame);
- // Size in bytes of all Blocked frame fields.
- static size_t GetBlockedFrameSize(QuicTransportVersion version,
- const QuicBlockedFrame& frame);
- // Size in bytes of PathChallenge frame.
- static size_t GetPathChallengeFrameSize(const QuicPathChallengeFrame& frame);
- // Size in bytes of PathResponse frame.
- static size_t GetPathResponseFrameSize(const QuicPathResponseFrame& frame);
- // Size in bytes required to serialize the stream id.
- static size_t GetStreamIdSize(QuicStreamId stream_id);
- // Size in bytes required to serialize the stream offset.
- static size_t GetStreamOffsetSize(QuicStreamOffset offset);
- // Size in bytes for a serialized new connection id frame
- static size_t GetNewConnectionIdFrameSize(
- const QuicNewConnectionIdFrame& frame);
-
- // Size in bytes for a serialized retire connection id frame
- static size_t GetRetireConnectionIdFrameSize(
- const QuicRetireConnectionIdFrame& frame);
-
- // Size in bytes for a serialized new token frame
- static size_t GetNewTokenFrameSize(const QuicNewTokenFrame& frame);
-
- // Size in bytes required for a serialized stop sending frame.
- static size_t GetStopSendingFrameSize(const QuicStopSendingFrame& frame);
-
- // Size in bytes required for a serialized retransmittable control |frame|.
- static size_t GetRetransmittableControlFrameSize(QuicTransportVersion version,
- const QuicFrame& frame);
-
- // Returns the number of bytes added to the packet for the specified frame,
- // and 0 if the frame doesn't fit. Includes the header size for the first
- // frame.
- size_t GetSerializedFrameLength(const QuicFrame& frame,
- size_t free_bytes,
- bool first_frame_in_packet,
- bool last_frame_in_packet,
- QuicPacketNumberLength packet_number_length);
-
- // Returns the associated data from the encrypted packet |encrypted| as a
- // stringpiece.
- static absl::string_view GetAssociatedDataFromEncryptedPacket(
- QuicTransportVersion version,
- const QuicEncryptedPacket& encrypted,
- QuicConnectionIdLength destination_connection_id_length,
- QuicConnectionIdLength source_connection_id_length,
- bool includes_version,
- bool includes_diversification_nonce,
- QuicPacketNumberLength packet_number_length,
- QuicVariableLengthIntegerLength retry_token_length_length,
- uint64_t retry_token_length,
- QuicVariableLengthIntegerLength length_length);
-
- // Parses the unencrypted fields in a QUIC header using |reader| as input,
- // stores the result in the other parameters.
- // |expected_destination_connection_id_length| is only used for short headers.
- static QuicErrorCode ParsePublicHeader(
- QuicDataReader* reader,
- uint8_t expected_destination_connection_id_length,
- bool ietf_format,
- uint8_t* first_byte,
- PacketHeaderFormat* format,
- bool* version_present,
- bool* has_length_prefix,
- QuicVersionLabel* version_label,
- ParsedQuicVersion* parsed_version,
- QuicConnectionId* destination_connection_id,
- QuicConnectionId* source_connection_id,
- QuicLongHeaderType* long_packet_type,
- QuicVariableLengthIntegerLength* retry_token_length_length,
- absl::string_view* retry_token,
- std::string* detailed_error);
-
- // Parses the unencrypted fields in |packet| and stores them in the other
- // parameters. This can only be called on the server.
- // |expected_destination_connection_id_length| is only used for short headers.
- static QuicErrorCode ParsePublicHeaderDispatcher(
- const QuicEncryptedPacket& packet,
- uint8_t expected_destination_connection_id_length,
- PacketHeaderFormat* format, QuicLongHeaderType* long_packet_type,
- bool* version_present, bool* has_length_prefix,
- QuicVersionLabel* version_label, ParsedQuicVersion* parsed_version,
- QuicConnectionId* destination_connection_id,
- QuicConnectionId* source_connection_id,
- absl::optional<absl::string_view>* retry_token,
- std::string* detailed_error);
-
- // Serializes a packet containing |frames| into |buffer|.
- // Returns the length of the packet, which must not be longer than
- // |packet_length|. Returns 0 if it fails to serialize.
- size_t BuildDataPacket(const QuicPacketHeader& header,
- const QuicFrames& frames,
- char* buffer,
- size_t packet_length,
- EncryptionLevel level);
-
- // Returns a new public reset packet.
- static std::unique_ptr<QuicEncryptedPacket> BuildPublicResetPacket(
- const QuicPublicResetPacket& packet);
-
- // Returns the minimal stateless reset packet length.
- static size_t GetMinStatelessResetPacketLength();
-
- // Returns a new IETF stateless reset packet.
- static std::unique_ptr<QuicEncryptedPacket> BuildIetfStatelessResetPacket(
- QuicConnectionId connection_id,
- size_t received_packet_length,
- StatelessResetToken stateless_reset_token);
-
- // Returns a new version negotiation packet.
- static std::unique_ptr<QuicEncryptedPacket> BuildVersionNegotiationPacket(
- QuicConnectionId server_connection_id,
- QuicConnectionId client_connection_id,
- bool ietf_quic,
- bool use_length_prefix,
- const ParsedQuicVersionVector& versions);
-
- // Returns a new IETF version negotiation packet.
- static std::unique_ptr<QuicEncryptedPacket> BuildIetfVersionNegotiationPacket(
- bool use_length_prefix,
- QuicConnectionId server_connection_id,
- QuicConnectionId client_connection_id,
- const ParsedQuicVersionVector& versions);
-
- // If header.version_flag is set, the version in the
- // packet will be set -- but it will be set from version_ not
- // header.versions.
- bool AppendPacketHeader(const QuicPacketHeader& header,
- QuicDataWriter* writer,
- size_t* length_field_offset);
- bool AppendIetfHeaderTypeByte(const QuicPacketHeader& header,
- QuicDataWriter* writer);
- bool AppendIetfPacketHeader(const QuicPacketHeader& header,
- QuicDataWriter* writer,
- size_t* length_field_offset);
- bool WriteIetfLongHeaderLength(const QuicPacketHeader& header,
- QuicDataWriter* writer,
- size_t length_field_offset,
- EncryptionLevel level);
- bool AppendTypeByte(const QuicFrame& frame,
- bool last_frame_in_packet,
- QuicDataWriter* writer);
- bool AppendIetfFrameType(const QuicFrame& frame,
- bool last_frame_in_packet,
- QuicDataWriter* writer);
- size_t AppendIetfFrames(const QuicFrames& frames, QuicDataWriter* writer);
- bool AppendStreamFrame(const QuicStreamFrame& frame,
- bool no_stream_frame_length, QuicDataWriter* writer);
- bool AppendCryptoFrame(const QuicCryptoFrame& frame, QuicDataWriter* writer);
- bool AppendAckFrequencyFrame(const QuicAckFrequencyFrame& frame,
- QuicDataWriter* writer);
-
- // SetDecrypter sets the primary decrypter, replacing any that already exists.
- // If an alternative decrypter is in place then the function QUICHE_DCHECKs.
- // This is intended for cases where one knows that future packets will be
- // using the new decrypter and the previous decrypter is now obsolete. |level|
- // indicates the encryption level of the new decrypter.
- void SetDecrypter(EncryptionLevel level,
- std::unique_ptr<QuicDecrypter> decrypter);
-
- // SetAlternativeDecrypter sets a decrypter that may be used to decrypt
- // future packets. |level| indicates the encryption level of the decrypter. If
- // |latch_once_used| is true, then the first time that the decrypter is
- // successful it will replace the primary decrypter. Otherwise both
- // decrypters will remain active and the primary decrypter will be the one
- // last used.
- void SetAlternativeDecrypter(EncryptionLevel level,
- std::unique_ptr<QuicDecrypter> decrypter,
- bool latch_once_used);
-
- void InstallDecrypter(EncryptionLevel level,
- std::unique_ptr<QuicDecrypter> decrypter);
- void RemoveDecrypter(EncryptionLevel level);
-
- // Enables key update support.
- void SetKeyUpdateSupportForConnection(bool enabled);
- // Discard the decrypter for the previous key phase.
- void DiscardPreviousOneRttKeys();
- // Update the key phase.
- bool DoKeyUpdate(KeyUpdateReason reason);
- // Returns the count of packets received that appeared to attempt a key
- // update but failed decryption which have been received since the last
- // successfully decrypted packet.
- QuicPacketCount PotentialPeerKeyUpdateAttemptCount() const;
-
- const QuicDecrypter* GetDecrypter(EncryptionLevel level) const;
- const QuicDecrypter* decrypter() const;
- const QuicDecrypter* alternative_decrypter() const;
-
- // Changes the encrypter used for level |level| to |encrypter|.
- void SetEncrypter(EncryptionLevel level,
- std::unique_ptr<QuicEncrypter> encrypter);
-
- // Called to remove encrypter of encryption |level|.
- void RemoveEncrypter(EncryptionLevel level);
-
- // Sets the encrypter and decrypter for the ENCRYPTION_INITIAL level.
- void SetInitialObfuscators(QuicConnectionId connection_id);
-
- // Encrypts a payload in |buffer|. |ad_len| is the length of the associated
- // data. |total_len| is the length of the associated data plus plaintext.
- // |buffer_len| is the full length of the allocated buffer.
- size_t EncryptInPlace(EncryptionLevel level,
- QuicPacketNumber packet_number,
- size_t ad_len,
- size_t total_len,
- size_t buffer_len,
- char* buffer);
-
- // Returns the length of the data encrypted into |buffer| if |buffer_len| is
- // long enough, and otherwise 0.
- size_t EncryptPayload(EncryptionLevel level,
- QuicPacketNumber packet_number,
- const QuicPacket& packet,
- char* buffer,
- size_t buffer_len);
-
- // Returns the length of the ciphertext that would be generated by encrypting
- // to plaintext of size |plaintext_size| at the given level.
- size_t GetCiphertextSize(EncryptionLevel level, size_t plaintext_size) const;
-
- // Returns the maximum length of plaintext that can be encrypted
- // to ciphertext no larger than |ciphertext_size|.
- size_t GetMaxPlaintextSize(size_t ciphertext_size);
-
- // Returns the maximum number of packets that can be safely encrypted with
- // the active AEAD. 1-RTT keys must be set before calling this method.
- QuicPacketCount GetOneRttEncrypterConfidentialityLimit() const;
-
- const std::string& detailed_error() { return detailed_error_; }
-
- // The minimum packet number length required to represent |packet_number|.
- static QuicPacketNumberLength GetMinPacketNumberLength(
- QuicPacketNumber packet_number);
-
- void SetSupportedVersions(const ParsedQuicVersionVector& versions) {
- supported_versions_ = versions;
- version_ = versions[0];
- }
-
- // Tell framer to infer packet header type from version_.
- void InferPacketHeaderTypeFromVersion();
-
- // Returns true if |header| is considered as an stateless reset packet.
- bool IsIetfStatelessResetPacket(const QuicPacketHeader& header) const;
-
- // Returns true if encrypter of |level| is available.
- bool HasEncrypterOfEncryptionLevel(EncryptionLevel level) const;
- // Returns true if decrypter of |level| is available.
- bool HasDecrypterOfEncryptionLevel(EncryptionLevel level) const;
-
- // Returns true if an encrypter of |space| is available.
- bool HasAnEncrypterForSpace(PacketNumberSpace space) const;
-
- // Returns the encryption level to send application data. This should be only
- // called with available encrypter for application data.
- EncryptionLevel GetEncryptionLevelToSendApplicationData() const;
-
- void set_validate_flags(bool value) { validate_flags_ = value; }
-
- Perspective perspective() const { return perspective_; }
-
- QuicStreamFrameDataProducer* data_producer() const { return data_producer_; }
-
- void set_data_producer(QuicStreamFrameDataProducer* data_producer) {
- data_producer_ = data_producer;
- }
-
- QuicTime creation_time() const { return creation_time_; }
-
- QuicPacketNumber first_sending_packet_number() const {
- return first_sending_packet_number_;
- }
-
- uint64_t current_received_frame_type() const {
- return current_received_frame_type_;
- }
-
- uint64_t previously_received_frame_type() const {
- return previously_received_frame_type_;
- }
-
- // The connection ID length the framer expects on incoming IETF short headers
- // on the server.
- uint8_t GetExpectedServerConnectionIdLength() {
- return expected_server_connection_id_length_;
- }
-
- // Change the expected destination connection ID length for short headers on
- // the client.
- void SetExpectedClientConnectionIdLength(
- uint8_t expected_client_connection_id_length) {
- expected_client_connection_id_length_ =
- expected_client_connection_id_length;
- }
-
- void EnableMultiplePacketNumberSpacesSupport();
-
- // Writes an array of bytes that, if sent as a UDP datagram, will trigger
- // IETF QUIC Version Negotiation on servers. The bytes will be written to
- // |packet_bytes|, which must point to |packet_length| bytes of memory.
- // |packet_length| must be in the range [1200, 65535].
- // |destination_connection_id_bytes| will be sent as the destination
- // connection ID, and must point to |destination_connection_id_length| bytes
- // of memory. |destination_connection_id_length| must be in the range [8,18].
- // When targeting Google servers, it is recommended to use a
- // |destination_connection_id_length| of 8.
- static bool WriteClientVersionNegotiationProbePacket(
- char* packet_bytes,
- QuicByteCount packet_length,
- const char* destination_connection_id_bytes,
- uint8_t destination_connection_id_length);
-
- // Parses a packet which a QUIC server sent in response to a packet sent by
- // WriteClientVersionNegotiationProbePacket. |packet_bytes| must point to
- // |packet_length| bytes in memory which represent the response.
- // |packet_length| must be greater or equal to 6. This method will fill in
- // |source_connection_id_bytes| which must point to at least
- // |*source_connection_id_length_out| bytes in memory.
- // |*source_connection_id_length_out| must be at least 18.
- // |*source_connection_id_length_out| will contain the length of the received
- // source connection ID, which on success will match the contents of the
- // destination connection ID passed in to
- // WriteClientVersionNegotiationProbePacket. In the case of a failure,
- // |detailed_error| will be filled in with an explanation of what failed.
- static bool ParseServerVersionNegotiationProbeResponse(
- const char* packet_bytes,
- QuicByteCount packet_length,
- char* source_connection_id_bytes,
- uint8_t* source_connection_id_length_out,
- std::string* detailed_error);
-
- void set_local_ack_delay_exponent(uint32_t exponent) {
- local_ack_delay_exponent_ = exponent;
- }
- uint32_t local_ack_delay_exponent() const {
- return local_ack_delay_exponent_;
- }
-
- void set_peer_ack_delay_exponent(uint32_t exponent) {
- peer_ack_delay_exponent_ = exponent;
- }
- uint32_t peer_ack_delay_exponent() const { return peer_ack_delay_exponent_; }
-
- void set_drop_incoming_retry_packets(bool drop_incoming_retry_packets) {
- drop_incoming_retry_packets_ = drop_incoming_retry_packets;
- }
-
- private:
- friend class test::QuicFramerPeer;
-
- using NackRangeMap = std::map<QuicPacketNumber, uint8_t>;
-
- // AckTimestampRange is a data structure derived from a QuicAckFrame. It is
- // used to serialize timestamps in a IETF_ACK_RECEIVE_TIMESTAMPS frame.
- struct QUIC_EXPORT_PRIVATE AckTimestampRange {
- QuicPacketCount gap;
- // |range_begin| and |range_end| are index(es) in
- // QuicAckFrame.received_packet_times, representing a continuous range of
- // packet numbers in descending order. |range_begin| >= |range_end|.
- int64_t range_begin; // Inclusive
- int64_t range_end; // Inclusive
- };
- absl::InlinedVector<AckTimestampRange, 2> GetAckTimestampRanges(
- const QuicAckFrame& frame, std::string& detailed_error) const;
- int64_t FrameAckTimestampRanges(
- const QuicAckFrame& frame,
- const absl::InlinedVector<AckTimestampRange, 2>& timestamp_ranges,
- QuicDataWriter* writer) const;
-
- struct QUIC_EXPORT_PRIVATE AckFrameInfo {
- AckFrameInfo();
- AckFrameInfo(const AckFrameInfo& other);
- ~AckFrameInfo();
-
- // The maximum ack block length.
- QuicPacketCount max_block_length;
- // Length of first ack block.
- QuicPacketCount first_block_length;
- // Number of ACK blocks needed for the ACK frame.
- size_t num_ack_blocks;
- };
-
- // Applies header protection to an IETF QUIC packet header in |buffer| using
- // the encrypter for level |level|. The buffer has |buffer_len| bytes of data,
- // with the first protected packet bytes starting at |ad_len|.
- bool ApplyHeaderProtection(EncryptionLevel level,
- char* buffer,
- size_t buffer_len,
- size_t ad_len);
-
- // Removes header protection from an IETF QUIC packet header.
- //
- // The packet number from the header is read from |reader|, where the packet
- // number is the next contents in |reader|. |reader| is only advanced by the
- // length of the packet number, but it is also used to peek the sample needed
- // for removing header protection.
- //
- // Properties needed for removing header protection are read from |header|.
- // The packet number length and type byte are written to |header|.
- //
- // The packet number, after removing header protection and decoding it, is
- // written to |full_packet_number|. Finally, the header, with header
- // protection removed, is written to |associated_data| to be used in packet
- // decryption. |packet| is used in computing the asociated data.
- bool RemoveHeaderProtection(QuicDataReader* reader,
- const QuicEncryptedPacket& packet,
- QuicPacketHeader* header,
- uint64_t* full_packet_number,
- std::vector<char>* associated_data);
-
- bool ProcessDataPacket(QuicDataReader* reader,
- QuicPacketHeader* header,
- const QuicEncryptedPacket& packet,
- char* decrypted_buffer,
- size_t buffer_length);
-
- bool ProcessIetfDataPacket(QuicDataReader* encrypted_reader,
- QuicPacketHeader* header,
- const QuicEncryptedPacket& packet,
- char* decrypted_buffer,
- size_t buffer_length);
-
- bool ProcessPublicResetPacket(QuicDataReader* reader,
- const QuicPacketHeader& header);
-
- bool ProcessVersionNegotiationPacket(QuicDataReader* reader,
- const QuicPacketHeader& header);
-
- bool ProcessRetryPacket(QuicDataReader* reader,
- const QuicPacketHeader& header);
-
- void MaybeProcessCoalescedPacket(const QuicDataReader& encrypted_reader,
- uint64_t remaining_bytes_length,
- const QuicPacketHeader& header);
-
- bool MaybeProcessIetfLength(QuicDataReader* encrypted_reader,
- QuicPacketHeader* header);
-
- bool ProcessPublicHeader(QuicDataReader* reader,
- bool packet_has_ietf_packet_header,
- QuicPacketHeader* header);
-
- // Processes the unauthenticated portion of the header into |header| from
- // the current QuicDataReader. Returns true on success, false on failure.
- bool ProcessUnauthenticatedHeader(QuicDataReader* encrypted_reader,
- QuicPacketHeader* header);
-
- // Processes the version label in the packet header.
- static bool ProcessVersionLabel(QuicDataReader* reader,
- QuicVersionLabel* version_label);
-
- // Validates and updates |destination_connection_id_length| and
- // |source_connection_id_length|. When
- // |should_update_expected_server_connection_id_length| is true, length
- // validation is disabled and |expected_server_connection_id_length| is set
- // to the appropriate length.
- // TODO(b/133873272) refactor this method.
- static bool ProcessAndValidateIetfConnectionIdLength(
- QuicDataReader* reader,
- ParsedQuicVersion version,
- Perspective perspective,
- bool should_update_expected_server_connection_id_length,
- uint8_t* expected_server_connection_id_length,
- uint8_t* destination_connection_id_length,
- uint8_t* source_connection_id_length,
- std::string* detailed_error);
-
- bool ProcessIetfHeaderTypeByte(QuicDataReader* reader,
- QuicPacketHeader* header);
- bool ProcessIetfPacketHeader(QuicDataReader* reader,
- QuicPacketHeader* header);
-
- // First processes possibly truncated packet number. Calculates the full
- // packet number from the truncated one and the last seen packet number, and
- // stores it to |packet_number|.
- bool ProcessAndCalculatePacketNumber(
- QuicDataReader* reader,
- QuicPacketNumberLength packet_number_length,
- QuicPacketNumber base_packet_number,
- uint64_t* packet_number);
- bool ProcessFrameData(QuicDataReader* reader, const QuicPacketHeader& header);
-
- static bool IsIetfFrameTypeExpectedForEncryptionLevel(uint64_t frame_type,
- EncryptionLevel level);
-
- bool ProcessIetfFrameData(QuicDataReader* reader,
- const QuicPacketHeader& header,
- EncryptionLevel decrypted_level);
- bool ProcessStreamFrame(QuicDataReader* reader,
- uint8_t frame_type,
- QuicStreamFrame* frame);
- bool ProcessAckFrame(QuicDataReader* reader, uint8_t frame_type);
- bool ProcessTimestampsInAckFrame(uint8_t num_received_packets,
- QuicPacketNumber largest_acked,
- QuicDataReader* reader);
- bool ProcessIetfAckFrame(QuicDataReader* reader,
- uint64_t frame_type,
- QuicAckFrame* ack_frame);
- bool ProcessIetfTimestampsInAckFrame(QuicPacketNumber largest_acked,
- QuicDataReader* reader);
- bool ProcessStopWaitingFrame(QuicDataReader* reader,
- const QuicPacketHeader& header,
- QuicStopWaitingFrame* stop_waiting);
- bool ProcessRstStreamFrame(QuicDataReader* reader, QuicRstStreamFrame* frame);
- bool ProcessConnectionCloseFrame(QuicDataReader* reader,
- QuicConnectionCloseFrame* frame);
- bool ProcessGoAwayFrame(QuicDataReader* reader, QuicGoAwayFrame* frame);
- bool ProcessWindowUpdateFrame(QuicDataReader* reader,
- QuicWindowUpdateFrame* frame);
- bool ProcessBlockedFrame(QuicDataReader* reader, QuicBlockedFrame* frame);
- void ProcessPaddingFrame(QuicDataReader* reader, QuicPaddingFrame* frame);
- bool ProcessMessageFrame(QuicDataReader* reader,
- bool no_message_length,
- QuicMessageFrame* frame);
-
- bool DecryptPayload(size_t udp_packet_length,
- absl::string_view encrypted,
- absl::string_view associated_data,
- const QuicPacketHeader& header,
- char* decrypted_buffer,
- size_t buffer_length,
- size_t* decrypted_length,
- EncryptionLevel* decrypted_level);
-
- // Returns the full packet number from the truncated
- // wire format version and the last seen packet number.
- uint64_t CalculatePacketNumberFromWire(
- QuicPacketNumberLength packet_number_length,
- QuicPacketNumber base_packet_number,
- uint64_t packet_number) const;
-
- // Returns the QuicTime::Delta corresponding to the time from when the framer
- // was created.
- const QuicTime::Delta CalculateTimestampFromWire(uint32_t time_delta_us);
-
- // Computes the wire size in bytes of time stamps in |ack|.
- size_t GetAckFrameTimeStampSize(const QuicAckFrame& ack);
- size_t GetIetfAckFrameTimestampSize(const QuicAckFrame& ack);
-
- // Computes the wire size in bytes of the |ack| frame.
- size_t GetAckFrameSize(const QuicAckFrame& ack,
- QuicPacketNumberLength packet_number_length);
- // Computes the wire-size, in bytes, of the |frame| ack frame, for IETF Quic.
- size_t GetIetfAckFrameSize(const QuicAckFrame& frame);
-
- // Computes the wire size in bytes of the |ack| frame.
- size_t GetAckFrameSize(const QuicAckFrame& ack);
-
- // Computes the wire size in bytes of the payload of |frame|.
- size_t ComputeFrameLength(const QuicFrame& frame,
- bool last_frame_in_packet,
- QuicPacketNumberLength packet_number_length);
-
- static bool AppendPacketNumber(QuicPacketNumberLength packet_number_length,
- QuicPacketNumber packet_number,
- QuicDataWriter* writer);
- static bool AppendStreamId(size_t stream_id_length,
- QuicStreamId stream_id,
- QuicDataWriter* writer);
- static bool AppendStreamOffset(size_t offset_length,
- QuicStreamOffset offset,
- QuicDataWriter* writer);
-
- // Appends a single ACK block to |writer| and returns true if the block was
- // successfully appended.
- static bool AppendAckBlock(uint8_t gap,
- QuicPacketNumberLength length_length,
- uint64_t length,
- QuicDataWriter* writer);
-
- static uint8_t GetPacketNumberFlags(
- QuicPacketNumberLength packet_number_length);
-
- static AckFrameInfo GetAckFrameInfo(const QuicAckFrame& frame);
-
- static QuicErrorCode ParsePublicHeaderGoogleQuic(
- QuicDataReader* reader,
- uint8_t* first_byte,
- PacketHeaderFormat* format,
- bool* version_present,
- QuicVersionLabel* version_label,
- ParsedQuicVersion* parsed_version,
- QuicConnectionId* destination_connection_id,
- std::string* detailed_error);
-
- bool ValidateReceivedConnectionIds(const QuicPacketHeader& header);
-
- // The Append* methods attempt to write the provided header or frame using the
- // |writer|, and return true if successful.
-
- bool AppendAckFrameAndTypeByte(const QuicAckFrame& frame,
- QuicDataWriter* writer);
- bool AppendTimestampsToAckFrame(const QuicAckFrame& frame,
- QuicDataWriter* writer);
-
- // Append IETF format ACK frame.
- //
- // AppendIetfAckFrameAndTypeByte adds the IETF type byte and the body
- // of the frame.
- bool AppendIetfAckFrameAndTypeByte(const QuicAckFrame& frame,
- QuicDataWriter* writer);
- bool AppendIetfTimestampsToAckFrame(const QuicAckFrame& frame,
- QuicDataWriter* writer);
-
- bool AppendStopWaitingFrame(const QuicPacketHeader& header,
- const QuicStopWaitingFrame& frame,
- QuicDataWriter* writer);
- bool AppendRstStreamFrame(const QuicRstStreamFrame& frame,
- QuicDataWriter* writer);
- bool AppendConnectionCloseFrame(const QuicConnectionCloseFrame& frame,
- QuicDataWriter* writer);
- bool AppendGoAwayFrame(const QuicGoAwayFrame& frame, QuicDataWriter* writer);
- bool AppendWindowUpdateFrame(const QuicWindowUpdateFrame& frame,
- QuicDataWriter* writer);
- bool AppendBlockedFrame(const QuicBlockedFrame& frame,
- QuicDataWriter* writer);
- bool AppendPaddingFrame(const QuicPaddingFrame& frame,
- QuicDataWriter* writer);
- bool AppendMessageFrameAndTypeByte(const QuicMessageFrame& frame,
- bool last_frame_in_packet,
- QuicDataWriter* writer);
-
- // IETF frame processing methods.
- bool ProcessIetfStreamFrame(QuicDataReader* reader,
- uint8_t frame_type,
- QuicStreamFrame* frame);
- bool ProcessIetfConnectionCloseFrame(QuicDataReader* reader,
- QuicConnectionCloseType type,
- QuicConnectionCloseFrame* frame);
- bool ProcessPathChallengeFrame(QuicDataReader* reader,
- QuicPathChallengeFrame* frame);
- bool ProcessPathResponseFrame(QuicDataReader* reader,
- QuicPathResponseFrame* frame);
- bool ProcessIetfResetStreamFrame(QuicDataReader* reader,
- QuicRstStreamFrame* frame);
- bool ProcessStopSendingFrame(QuicDataReader* reader,
- QuicStopSendingFrame* stop_sending_frame);
- bool ProcessCryptoFrame(QuicDataReader* reader,
- EncryptionLevel encryption_level,
- QuicCryptoFrame* frame);
- bool ProcessAckFrequencyFrame(QuicDataReader* reader,
- QuicAckFrequencyFrame* frame);
- // IETF frame appending methods. All methods append the type byte as well.
- bool AppendIetfStreamFrame(const QuicStreamFrame& frame,
- bool last_frame_in_packet,
- QuicDataWriter* writer);
- bool AppendIetfConnectionCloseFrame(const QuicConnectionCloseFrame& frame,
- QuicDataWriter* writer);
- bool AppendPathChallengeFrame(const QuicPathChallengeFrame& frame,
- QuicDataWriter* writer);
- bool AppendPathResponseFrame(const QuicPathResponseFrame& frame,
- QuicDataWriter* writer);
- bool AppendIetfResetStreamFrame(const QuicRstStreamFrame& frame,
- QuicDataWriter* writer);
- bool AppendStopSendingFrame(const QuicStopSendingFrame& stop_sending_frame,
- QuicDataWriter* writer);
-
- // Append/consume IETF-Format MAX_DATA and MAX_STREAM_DATA frames
- bool AppendMaxDataFrame(const QuicWindowUpdateFrame& frame,
- QuicDataWriter* writer);
- bool AppendMaxStreamDataFrame(const QuicWindowUpdateFrame& frame,
- QuicDataWriter* writer);
- bool ProcessMaxDataFrame(QuicDataReader* reader,
- QuicWindowUpdateFrame* frame);
- bool ProcessMaxStreamDataFrame(QuicDataReader* reader,
- QuicWindowUpdateFrame* frame);
-
- bool AppendMaxStreamsFrame(const QuicMaxStreamsFrame& frame,
- QuicDataWriter* writer);
- bool ProcessMaxStreamsFrame(QuicDataReader* reader,
- QuicMaxStreamsFrame* frame,
- uint64_t frame_type);
-
- bool AppendDataBlockedFrame(const QuicBlockedFrame& frame,
- QuicDataWriter* writer);
- bool ProcessDataBlockedFrame(QuicDataReader* reader, QuicBlockedFrame* frame);
-
- bool AppendStreamDataBlockedFrame(const QuicBlockedFrame& frame,
- QuicDataWriter* writer);
- bool ProcessStreamDataBlockedFrame(QuicDataReader* reader,
- QuicBlockedFrame* frame);
-
- bool AppendStreamsBlockedFrame(const QuicStreamsBlockedFrame& frame,
- QuicDataWriter* writer);
- bool ProcessStreamsBlockedFrame(QuicDataReader* reader,
- QuicStreamsBlockedFrame* frame,
- uint64_t frame_type);
-
- bool AppendNewConnectionIdFrame(const QuicNewConnectionIdFrame& frame,
- QuicDataWriter* writer);
- bool ProcessNewConnectionIdFrame(QuicDataReader* reader,
- QuicNewConnectionIdFrame* frame);
- bool AppendRetireConnectionIdFrame(const QuicRetireConnectionIdFrame& frame,
- QuicDataWriter* writer);
- bool ProcessRetireConnectionIdFrame(QuicDataReader* reader,
- QuicRetireConnectionIdFrame* frame);
-
- bool AppendNewTokenFrame(const QuicNewTokenFrame& frame,
- QuicDataWriter* writer);
- bool ProcessNewTokenFrame(QuicDataReader* reader, QuicNewTokenFrame* frame);
-
- bool RaiseError(QuicErrorCode error);
-
- // Returns true if |header| indicates a version negotiation packet.
- bool IsVersionNegotiation(const QuicPacketHeader& header,
- bool packet_has_ietf_packet_header) const;
-
- // Calculates and returns type byte of stream frame.
- uint8_t GetStreamFrameTypeByte(const QuicStreamFrame& frame,
- bool last_frame_in_packet) const;
- uint8_t GetIetfStreamFrameTypeByte(const QuicStreamFrame& frame,
- bool last_frame_in_packet) const;
-
- void set_error(QuicErrorCode error) { error_ = error; }
-
- void set_detailed_error(const char* error) { detailed_error_ = error; }
- void set_detailed_error(std::string error) { detailed_error_ = error; }
-
- // Returns false if the reading fails.
- bool ReadUint32FromVarint62(QuicDataReader* reader,
- QuicIetfFrameType type,
- QuicStreamId* id);
-
- bool ProcessPacketInternal(const QuicEncryptedPacket& packet);
-
- // Determine whether the given QuicAckFrame should be serialized with a
- // IETF_ACK_RECEIVE_TIMESTAMPS frame type.
- bool UseIetfAckWithReceiveTimestamp(const QuicAckFrame& frame) const {
- return VersionHasIetfQuicFrames(version_.transport_version) &&
- process_timestamps_ &&
- std::min<uint64_t>(max_receive_timestamps_per_ack_,
- frame.received_packet_times.size()) > 0;
- }
-
- std::string detailed_error_;
- QuicFramerVisitorInterface* visitor_;
- QuicErrorCode error_;
- // Updated by ProcessPacketHeader when it succeeds decrypting a larger packet.
- QuicPacketNumber largest_packet_number_;
- // Largest successfully decrypted packet number per packet number space. Only
- // used when supports_multiple_packet_number_spaces_ is true.
- QuicPacketNumber largest_decrypted_packet_numbers_[NUM_PACKET_NUMBER_SPACES];
- // Last server connection ID seen on the wire.
- QuicConnectionId last_serialized_server_connection_id_;
- // Last client connection ID seen on the wire.
- QuicConnectionId last_serialized_client_connection_id_;
- // Version of the protocol being used.
- ParsedQuicVersion version_;
- // This vector contains QUIC versions which we currently support.
- // This should be ordered such that the highest supported version is the first
- // element, with subsequent elements in descending order (versions can be
- // skipped as necessary).
- ParsedQuicVersionVector supported_versions_;
- // Decrypters used to decrypt packets during parsing.
- std::unique_ptr<QuicDecrypter> decrypter_[NUM_ENCRYPTION_LEVELS];
- // The encryption level of the primary decrypter to use in |decrypter_|.
- EncryptionLevel decrypter_level_;
- // The encryption level of the alternative decrypter to use in |decrypter_|.
- // When set to NUM_ENCRYPTION_LEVELS, indicates that there is no alternative
- // decrypter.
- EncryptionLevel alternative_decrypter_level_;
- // |alternative_decrypter_latch_| is true if, when the decrypter at
- // |alternative_decrypter_level_| successfully decrypts a packet, we should
- // install it as the only decrypter.
- bool alternative_decrypter_latch_;
- // Encrypters used to encrypt packets via EncryptPayload().
- std::unique_ptr<QuicEncrypter> encrypter_[NUM_ENCRYPTION_LEVELS];
- // Tracks if the framer is being used by the entity that received the
- // connection or the entity that initiated it.
- Perspective perspective_;
- // If false, skip validation that the public flags are set to legal values.
- bool validate_flags_;
- // The diversification nonce from the last received packet.
- DiversificationNonce last_nonce_;
- // If true, send and process timestamps in the ACK frame.
- // TODO(ianswett): Remove the mutables once set_process_timestamps and
- // set_receive_timestamp_exponent_ aren't const.
- mutable bool process_timestamps_;
- // The max number of receive timestamps to send per ACK frame.
- mutable uint32_t max_receive_timestamps_per_ack_;
- // The exponent to use when writing/reading ACK receive timestamps.
- mutable uint32_t receive_timestamps_exponent_;
- // The creation time of the connection, used to calculate timestamps.
- QuicTime creation_time_;
- // The last timestamp received if process_timestamps_ is true.
- QuicTime::Delta last_timestamp_;
-
- // Whether IETF QUIC Key Update is supported on this connection.
- bool support_key_update_for_connection_;
- // The value of the current key phase bit, which is toggled when the keys are
- // changed.
- bool current_key_phase_bit_;
- // Whether we have performed a key update at least once.
- bool key_update_performed_ = false;
- // Tracks the first packet received in the current key phase. Will be
- // uninitialized before the first one-RTT packet has been received or after a
- // locally initiated key update but before the first packet from the peer in
- // the new key phase is received.
- QuicPacketNumber current_key_phase_first_received_packet_number_;
- // Counts the number of packets received that might have been failed key
- // update attempts. Reset to zero every time a packet is successfully
- // decrypted.
- QuicPacketCount potential_peer_key_update_attempt_count_;
- // Decrypter for the previous key phase. Will be null if in the first key
- // phase or previous keys have been discarded.
- std::unique_ptr<QuicDecrypter> previous_decrypter_;
- // Decrypter for the next key phase. May be null if next keys haven't been
- // generated yet.
- std::unique_ptr<QuicDecrypter> next_decrypter_;
-
- // If this is a framer of a connection, this is the packet number of first
- // sending packet. If this is a framer of a framer of dispatcher, this is the
- // packet number of sent packets (for those which have packet number).
- const QuicPacketNumber first_sending_packet_number_;
-
- // If not null, framer asks data_producer_ to write stream frame data. Not
- // owned. TODO(fayang): Consider add data producer to framer's constructor.
- QuicStreamFrameDataProducer* data_producer_;
-
- // Whether we are in the middle of a call to this->ProcessPacket.
- bool is_processing_packet_ = false;
-
- // If true, framer infers packet header type (IETF/GQUIC) from version_.
- // Otherwise, framer infers packet header type from first byte of a received
- // packet.
- bool infer_packet_header_type_from_version_;
-
- // IETF short headers contain a destination connection ID but do not
- // encode its length. These variables contains the length we expect to read.
- // This is also used to validate the long header destination connection ID
- // lengths in older versions of QUIC.
- uint8_t expected_server_connection_id_length_;
- uint8_t expected_client_connection_id_length_;
-
- // Indicates whether this framer supports multiple packet number spaces.
- bool supports_multiple_packet_number_spaces_;
-
- // Indicates whether received RETRY packets should be dropped.
- bool drop_incoming_retry_packets_ = false;
-
- // The length in bytes of the last packet number written to an IETF-framed
- // packet.
- size_t last_written_packet_number_length_;
-
- // The amount to shift the ack timestamp in ACK frames. The default is 3.
- // Local_ is the amount this node shifts timestamps in ACK frames it
- // generates. it is sent to the peer in a transport parameter negotiation.
- // Peer_ is the amount the peer shifts timestamps when it sends ACK frames to
- // this node. This node "unshifts" by this amount. The value is received from
- // the peer in the transport parameter negotiation. IETF QUIC only.
- uint32_t peer_ack_delay_exponent_;
- uint32_t local_ack_delay_exponent_;
-
- // The type of received IETF frame currently being processed. 0 when not
- // processing a frame or when processing Google QUIC frames. Used to populate
- // the Transport Connection Close when there is an error during frame
- // processing.
- uint64_t current_received_frame_type_;
-
- // TODO(haoyuewang) Remove this debug utility.
- // The type of the IETF frame preceding the frame currently being processed. 0
- // when not processing a frame or only 1 frame has been processed.
- uint64_t previously_received_frame_type_;
-};
-
-// Look for and parse the error code from the "<quic_error_code>:" text that
-// may be present at the start of the CONNECTION_CLOSE error details string.
-// This text, inserted by the peer if it's using Google's QUIC implementation,
-// contains additional error information that narrows down the exact error. The
-// extracted error code and (possibly updated) error_details string are returned
-// in |*frame|. If an error code is not found in the error details, then
-// frame->quic_error_code is set to
-// QuicErrorCode::QUIC_IETF_GQUIC_ERROR_MISSING. If there is an error code in
-// the string then it is removed from the string.
-QUIC_EXPORT_PRIVATE void MaybeExtractQuicErrorCode(
- QuicConnectionCloseFrame* frame);
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_QUIC_FRAMER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_framer_test.cc b/chromium/net/third_party/quiche/src/quic/core/quic_framer_test.cc
deleted file mode 100644
index d24664dbded..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_framer_test.cc
+++ /dev/null
@@ -1,16375 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_framer.h"
-
-#include <algorithm>
-#include <cstdint>
-#include <map>
-#include <memory>
-#include <string>
-#include <utility>
-#include <vector>
-
-#include "absl/base/macros.h"
-#include "absl/memory/memory.h"
-#include "absl/strings/escaping.h"
-#include "absl/strings/match.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/crypto/null_decrypter.h"
-#include "quic/core/crypto/null_encrypter.h"
-#include "quic/core/crypto/quic_decrypter.h"
-#include "quic/core/crypto/quic_encrypter.h"
-#include "quic/core/quic_connection_id.h"
-#include "quic/core/quic_error_codes.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_utils.h"
-#include "quic/core/quic_versions.h"
-#include "quic/platform/api/quic_expect_bug.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/quic_framer_peer.h"
-#include "quic/test_tools/quic_test_utils.h"
-#include "quic/test_tools/simple_data_producer.h"
-#include "common/test_tools/quiche_test_utils.h"
-
-using testing::_;
-using testing::ContainerEq;
-using testing::Eq;
-using testing::IsNull;
-using testing::Return;
-
-namespace quic {
-namespace test {
-namespace {
-
-const uint64_t kEpoch = UINT64_C(1) << 32;
-const uint64_t kMask = kEpoch - 1;
-
-const StatelessResetToken kTestStatelessResetToken{
- 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
- 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f};
-
-// Use fields in which each byte is distinct to ensure that every byte is
-// framed correctly. The values are otherwise arbitrary.
-QuicConnectionId FramerTestConnectionId() {
- return TestConnectionId(UINT64_C(0xFEDCBA9876543210));
-}
-
-QuicConnectionId FramerTestConnectionIdPlusOne() {
- return TestConnectionId(UINT64_C(0xFEDCBA9876543211));
-}
-
-QuicConnectionId FramerTestConnectionIdNineBytes() {
- uint8_t connection_id_bytes[9] = {0xFE, 0xDC, 0xBA, 0x98, 0x76,
- 0x54, 0x32, 0x10, 0x42};
- return QuicConnectionId(reinterpret_cast<char*>(connection_id_bytes),
- sizeof(connection_id_bytes));
-}
-
-const QuicPacketNumber kPacketNumber = QuicPacketNumber(UINT64_C(0x12345678));
-const QuicPacketNumber kSmallLargestObserved =
- QuicPacketNumber(UINT16_C(0x1234));
-const QuicPacketNumber kSmallMissingPacket = QuicPacketNumber(UINT16_C(0x1233));
-const QuicPacketNumber kLeastUnacked = QuicPacketNumber(UINT64_C(0x012345670));
-const QuicStreamId kStreamId = UINT64_C(0x01020304);
-// Note that the high 4 bits of the stream offset must be less than 0x40
-// in order to ensure that the value can be encoded using VarInt62 encoding.
-const QuicStreamOffset kStreamOffset = UINT64_C(0x3A98FEDC32107654);
-const QuicPublicResetNonceProof kNonceProof = UINT64_C(0xABCDEF0123456789);
-
-// In testing that we can ack the full range of packets...
-// This is the largest packet number that can be represented in IETF QUIC
-// varint62 format.
-const QuicPacketNumber kLargestIetfLargestObserved =
- QuicPacketNumber(UINT64_C(0x3fffffffffffffff));
-// Encodings for the two bits in a VarInt62 that
-// describe the length of the VarInt61. For binary packet
-// formats in this file, the convention is to code the
-// first byte as
-// kVarInt62FourBytes + 0x<value_in_that_byte>
-const uint8_t kVarInt62OneByte = 0x00;
-const uint8_t kVarInt62TwoBytes = 0x40;
-const uint8_t kVarInt62FourBytes = 0x80;
-const uint8_t kVarInt62EightBytes = 0xc0;
-
-class TestEncrypter : public QuicEncrypter {
- public:
- ~TestEncrypter() override {}
- bool SetKey(absl::string_view /*key*/) override { return true; }
- bool SetNoncePrefix(absl::string_view /*nonce_prefix*/) override {
- return true;
- }
- bool SetIV(absl::string_view /*iv*/) override { return true; }
- bool SetHeaderProtectionKey(absl::string_view /*key*/) override {
- return true;
- }
- bool EncryptPacket(uint64_t packet_number, absl::string_view associated_data,
- absl::string_view plaintext, char* output,
- size_t* output_length,
- size_t /*max_output_length*/) override {
- packet_number_ = QuicPacketNumber(packet_number);
- associated_data_ = std::string(associated_data);
- plaintext_ = std::string(plaintext);
- memcpy(output, plaintext.data(), plaintext.length());
- *output_length = plaintext.length();
- return true;
- }
- std::string GenerateHeaderProtectionMask(
- absl::string_view /*sample*/) override {
- return std::string(5, 0);
- }
- size_t GetKeySize() const override { return 0; }
- size_t GetNoncePrefixSize() const override { return 0; }
- size_t GetIVSize() const override { return 0; }
- size_t GetMaxPlaintextSize(size_t ciphertext_size) const override {
- return ciphertext_size;
- }
- size_t GetCiphertextSize(size_t plaintext_size) const override {
- return plaintext_size;
- }
- QuicPacketCount GetConfidentialityLimit() const override {
- return std::numeric_limits<QuicPacketCount>::max();
- }
- absl::string_view GetKey() const override { return absl::string_view(); }
- absl::string_view GetNoncePrefix() const override {
- return absl::string_view();
- }
-
- QuicPacketNumber packet_number_;
- std::string associated_data_;
- std::string plaintext_;
-};
-
-class TestDecrypter : public QuicDecrypter {
- public:
- ~TestDecrypter() override {}
- bool SetKey(absl::string_view /*key*/) override { return true; }
- bool SetNoncePrefix(absl::string_view /*nonce_prefix*/) override {
- return true;
- }
- bool SetIV(absl::string_view /*iv*/) override { return true; }
- bool SetHeaderProtectionKey(absl::string_view /*key*/) override {
- return true;
- }
- bool SetPreliminaryKey(absl::string_view /*key*/) override {
- QUIC_BUG(quic_bug_10486_1) << "should not be called";
- return false;
- }
- bool SetDiversificationNonce(const DiversificationNonce& /*key*/) override {
- return true;
- }
- bool DecryptPacket(uint64_t packet_number, absl::string_view associated_data,
- absl::string_view ciphertext, char* output,
- size_t* output_length,
- size_t /*max_output_length*/) override {
- packet_number_ = QuicPacketNumber(packet_number);
- associated_data_ = std::string(associated_data);
- ciphertext_ = std::string(ciphertext);
- memcpy(output, ciphertext.data(), ciphertext.length());
- *output_length = ciphertext.length();
- return true;
- }
- std::string GenerateHeaderProtectionMask(
- QuicDataReader* /*sample_reader*/) override {
- return std::string(5, 0);
- }
- size_t GetKeySize() const override { return 0; }
- size_t GetNoncePrefixSize() const override { return 0; }
- size_t GetIVSize() const override { return 0; }
- absl::string_view GetKey() const override { return absl::string_view(); }
- absl::string_view GetNoncePrefix() const override {
- return absl::string_view();
- }
- // Use a distinct value starting with 0xFFFFFF, which is never used by TLS.
- uint32_t cipher_id() const override { return 0xFFFFFFF2; }
- QuicPacketCount GetIntegrityLimit() const override {
- return std::numeric_limits<QuicPacketCount>::max();
- }
- QuicPacketNumber packet_number_;
- std::string associated_data_;
- std::string ciphertext_;
-};
-
-std::unique_ptr<QuicEncryptedPacket> EncryptPacketWithTagAndPhase(
- const QuicPacket& packet, uint8_t tag, bool phase) {
- std::string packet_data = std::string(packet.AsStringPiece());
- if (phase) {
- packet_data[0] |= FLAGS_KEY_PHASE_BIT;
- } else {
- packet_data[0] &= ~FLAGS_KEY_PHASE_BIT;
- }
-
- TaggingEncrypter crypter(tag);
- const size_t packet_size = crypter.GetCiphertextSize(packet_data.size());
- char* buffer = new char[packet_size];
- size_t buf_len = 0;
- if (!crypter.EncryptPacket(0, absl::string_view(), packet_data, buffer,
- &buf_len, packet_size)) {
- delete[] buffer;
- return nullptr;
- }
-
- return std::make_unique<QuicEncryptedPacket>(buffer, buf_len,
- /*owns_buffer=*/true);
-}
-
-class TestQuicVisitor : public QuicFramerVisitorInterface {
- public:
- TestQuicVisitor()
- : error_count_(0),
- version_mismatch_(0),
- packet_count_(0),
- frame_count_(0),
- complete_packets_(0),
- derive_next_key_count_(0),
- decrypted_first_packet_in_key_phase_count_(0),
- accept_packet_(true),
- accept_public_header_(true) {}
-
- ~TestQuicVisitor() override {}
-
- void OnError(QuicFramer* f) override {
- QUIC_DLOG(INFO) << "QuicFramer Error: " << QuicErrorCodeToString(f->error())
- << " (" << f->error() << ")";
- ++error_count_;
- }
-
- void OnPacket() override {}
-
- void OnPublicResetPacket(const QuicPublicResetPacket& packet) override {
- public_reset_packet_ = std::make_unique<QuicPublicResetPacket>((packet));
- EXPECT_EQ(0u, framer_->current_received_frame_type());
- }
-
- void OnVersionNegotiationPacket(
- const QuicVersionNegotiationPacket& packet) override {
- version_negotiation_packet_ =
- std::make_unique<QuicVersionNegotiationPacket>((packet));
- EXPECT_EQ(0u, framer_->current_received_frame_type());
- }
-
- void OnRetryPacket(QuicConnectionId original_connection_id,
- QuicConnectionId new_connection_id,
- absl::string_view retry_token,
- absl::string_view retry_integrity_tag,
- absl::string_view retry_without_tag) override {
- on_retry_packet_called_ = true;
- retry_original_connection_id_ =
- std::make_unique<QuicConnectionId>(original_connection_id);
- retry_new_connection_id_ =
- std::make_unique<QuicConnectionId>(new_connection_id);
- retry_token_ = std::make_unique<std::string>(std::string(retry_token));
- retry_token_integrity_tag_ =
- std::make_unique<std::string>(std::string(retry_integrity_tag));
- retry_without_tag_ =
- std::make_unique<std::string>(std::string(retry_without_tag));
- EXPECT_EQ(0u, framer_->current_received_frame_type());
- }
-
- bool OnProtocolVersionMismatch(ParsedQuicVersion received_version) override {
- QUIC_DLOG(INFO) << "QuicFramer Version Mismatch, version: "
- << received_version;
- ++version_mismatch_;
- EXPECT_EQ(0u, framer_->current_received_frame_type());
- return false;
- }
-
- bool OnUnauthenticatedPublicHeader(const QuicPacketHeader& header) override {
- header_ = std::make_unique<QuicPacketHeader>((header));
- EXPECT_EQ(0u, framer_->current_received_frame_type());
- return accept_public_header_;
- }
-
- bool OnUnauthenticatedHeader(const QuicPacketHeader& /*header*/) override {
- EXPECT_EQ(0u, framer_->current_received_frame_type());
- return true;
- }
-
- void OnDecryptedPacket(size_t /*length*/,
- EncryptionLevel /*level*/) override {
- EXPECT_EQ(0u, framer_->current_received_frame_type());
- }
-
- bool OnPacketHeader(const QuicPacketHeader& header) override {
- ++packet_count_;
- header_ = std::make_unique<QuicPacketHeader>((header));
- EXPECT_EQ(0u, framer_->current_received_frame_type());
- return accept_packet_;
- }
-
- void OnCoalescedPacket(const QuicEncryptedPacket& packet) override {
- coalesced_packets_.push_back(packet.Clone());
- }
-
- void OnUndecryptablePacket(const QuicEncryptedPacket& packet,
- EncryptionLevel decryption_level,
- bool has_decryption_key) override {
- undecryptable_packets_.push_back(packet.Clone());
- undecryptable_decryption_levels_.push_back(decryption_level);
- undecryptable_has_decryption_keys_.push_back(has_decryption_key);
- }
-
- bool OnStreamFrame(const QuicStreamFrame& frame) override {
- ++frame_count_;
- // Save a copy of the data so it is valid after the packet is processed.
- std::string* string_data =
- new std::string(frame.data_buffer, frame.data_length);
- stream_data_.push_back(absl::WrapUnique(string_data));
- stream_frames_.push_back(std::make_unique<QuicStreamFrame>(
- frame.stream_id, frame.fin, frame.offset, *string_data));
- if (VersionHasIetfQuicFrames(transport_version_)) {
- // Low order bits of type encode flags, ignore them for this test.
- EXPECT_TRUE(IS_IETF_STREAM_FRAME(framer_->current_received_frame_type()));
- } else {
- EXPECT_EQ(0u, framer_->current_received_frame_type());
- }
- return true;
- }
-
- bool OnCryptoFrame(const QuicCryptoFrame& frame) override {
- ++frame_count_;
- // Save a copy of the data so it is valid after the packet is processed.
- std::string* string_data =
- new std::string(frame.data_buffer, frame.data_length);
- crypto_data_.push_back(absl::WrapUnique(string_data));
- crypto_frames_.push_back(std::make_unique<QuicCryptoFrame>(
- frame.level, frame.offset, *string_data));
- if (VersionHasIetfQuicFrames(transport_version_)) {
- EXPECT_EQ(IETF_CRYPTO, framer_->current_received_frame_type());
- } else {
- EXPECT_EQ(0u, framer_->current_received_frame_type());
- }
- return true;
- }
-
- bool OnAckFrameStart(QuicPacketNumber largest_acked,
- QuicTime::Delta ack_delay_time) override {
- ++frame_count_;
- QuicAckFrame ack_frame;
- ack_frame.largest_acked = largest_acked;
- ack_frame.ack_delay_time = ack_delay_time;
- ack_frames_.push_back(std::make_unique<QuicAckFrame>(ack_frame));
- if (VersionHasIetfQuicFrames(transport_version_)) {
- EXPECT_TRUE(IETF_ACK == framer_->current_received_frame_type() ||
- IETF_ACK_ECN == framer_->current_received_frame_type() ||
- IETF_ACK_RECEIVE_TIMESTAMPS ==
- framer_->current_received_frame_type());
- } else {
- EXPECT_EQ(0u, framer_->current_received_frame_type());
- }
- return true;
- }
-
- bool OnAckRange(QuicPacketNumber start, QuicPacketNumber end) override {
- QUICHE_DCHECK(!ack_frames_.empty());
- ack_frames_[ack_frames_.size() - 1]->packets.AddRange(start, end);
- if (VersionHasIetfQuicFrames(transport_version_)) {
- EXPECT_TRUE(IETF_ACK == framer_->current_received_frame_type() ||
- IETF_ACK_ECN == framer_->current_received_frame_type() ||
- IETF_ACK_RECEIVE_TIMESTAMPS ==
- framer_->current_received_frame_type());
- } else {
- EXPECT_EQ(0u, framer_->current_received_frame_type());
- }
- return true;
- }
-
- bool OnAckTimestamp(QuicPacketNumber packet_number,
- QuicTime timestamp) override {
- ack_frames_[ack_frames_.size() - 1]->received_packet_times.push_back(
- std::make_pair(packet_number, timestamp));
- if (VersionHasIetfQuicFrames(transport_version_)) {
- EXPECT_TRUE(IETF_ACK == framer_->current_received_frame_type() ||
- IETF_ACK_ECN == framer_->current_received_frame_type() ||
- IETF_ACK_RECEIVE_TIMESTAMPS ==
- framer_->current_received_frame_type());
- } else {
- EXPECT_EQ(0u, framer_->current_received_frame_type());
- }
- return true;
- }
-
- bool OnAckFrameEnd(QuicPacketNumber /*start*/) override { return true; }
-
- bool OnStopWaitingFrame(const QuicStopWaitingFrame& frame) override {
- ++frame_count_;
- stop_waiting_frames_.push_back(
- std::make_unique<QuicStopWaitingFrame>(frame));
- EXPECT_EQ(0u, framer_->current_received_frame_type());
- return true;
- }
-
- bool OnPaddingFrame(const QuicPaddingFrame& frame) override {
- padding_frames_.push_back(std::make_unique<QuicPaddingFrame>(frame));
- if (VersionHasIetfQuicFrames(transport_version_)) {
- EXPECT_EQ(IETF_PADDING, framer_->current_received_frame_type());
- } else {
- EXPECT_EQ(0u, framer_->current_received_frame_type());
- }
- return true;
- }
-
- bool OnPingFrame(const QuicPingFrame& frame) override {
- ++frame_count_;
- ping_frames_.push_back(std::make_unique<QuicPingFrame>(frame));
- if (VersionHasIetfQuicFrames(transport_version_)) {
- EXPECT_EQ(IETF_PING, framer_->current_received_frame_type());
- } else {
- EXPECT_EQ(0u, framer_->current_received_frame_type());
- }
- return true;
- }
-
- bool OnMessageFrame(const QuicMessageFrame& frame) override {
- ++frame_count_;
- message_frames_.push_back(
- std::make_unique<QuicMessageFrame>(frame.data, frame.message_length));
- if (VersionHasIetfQuicFrames(transport_version_)) {
- EXPECT_TRUE(IETF_EXTENSION_MESSAGE_NO_LENGTH_V99 ==
- framer_->current_received_frame_type() ||
- IETF_EXTENSION_MESSAGE_V99 ==
- framer_->current_received_frame_type());
- } else {
- EXPECT_EQ(0u, framer_->current_received_frame_type());
- }
- return true;
- }
-
- bool OnHandshakeDoneFrame(const QuicHandshakeDoneFrame& frame) override {
- ++frame_count_;
- handshake_done_frames_.push_back(
- std::make_unique<QuicHandshakeDoneFrame>(frame));
- QUICHE_DCHECK(VersionHasIetfQuicFrames(transport_version_));
- EXPECT_EQ(IETF_HANDSHAKE_DONE, framer_->current_received_frame_type());
- return true;
- }
-
- bool OnAckFrequencyFrame(const QuicAckFrequencyFrame& frame) override {
- ++frame_count_;
- ack_frequency_frames_.emplace_back(
- std::make_unique<QuicAckFrequencyFrame>(frame));
- QUICHE_DCHECK(VersionHasIetfQuicFrames(transport_version_));
- EXPECT_EQ(IETF_ACK_FREQUENCY, framer_->current_received_frame_type());
- return true;
- }
-
- void OnPacketComplete() override { ++complete_packets_; }
-
- bool OnRstStreamFrame(const QuicRstStreamFrame& frame) override {
- rst_stream_frame_ = frame;
- if (VersionHasIetfQuicFrames(transport_version_)) {
- EXPECT_EQ(IETF_RST_STREAM, framer_->current_received_frame_type());
- } else {
- EXPECT_EQ(0u, framer_->current_received_frame_type());
- }
- return true;
- }
-
- bool OnConnectionCloseFrame(const QuicConnectionCloseFrame& frame) override {
- connection_close_frame_ = frame;
- if (VersionHasIetfQuicFrames(transport_version_)) {
- EXPECT_NE(GOOGLE_QUIC_CONNECTION_CLOSE, frame.close_type);
- if (frame.close_type == IETF_QUIC_TRANSPORT_CONNECTION_CLOSE) {
- EXPECT_EQ(IETF_CONNECTION_CLOSE,
- framer_->current_received_frame_type());
- } else {
- EXPECT_EQ(IETF_APPLICATION_CLOSE,
- framer_->current_received_frame_type());
- }
- } else {
- EXPECT_EQ(0u, framer_->current_received_frame_type());
- }
- return true;
- }
-
- bool OnStopSendingFrame(const QuicStopSendingFrame& frame) override {
- stop_sending_frame_ = frame;
- EXPECT_EQ(IETF_STOP_SENDING, framer_->current_received_frame_type());
- EXPECT_TRUE(VersionHasIetfQuicFrames(transport_version_));
- return true;
- }
-
- bool OnPathChallengeFrame(const QuicPathChallengeFrame& frame) override {
- path_challenge_frame_ = frame;
- EXPECT_EQ(IETF_PATH_CHALLENGE, framer_->current_received_frame_type());
- EXPECT_TRUE(VersionHasIetfQuicFrames(transport_version_));
- return true;
- }
-
- bool OnPathResponseFrame(const QuicPathResponseFrame& frame) override {
- path_response_frame_ = frame;
- EXPECT_EQ(IETF_PATH_RESPONSE, framer_->current_received_frame_type());
- EXPECT_TRUE(VersionHasIetfQuicFrames(transport_version_));
- return true;
- }
-
- bool OnGoAwayFrame(const QuicGoAwayFrame& frame) override {
- goaway_frame_ = frame;
- EXPECT_FALSE(VersionHasIetfQuicFrames(transport_version_));
- EXPECT_EQ(0u, framer_->current_received_frame_type());
- return true;
- }
-
- bool OnMaxStreamsFrame(const QuicMaxStreamsFrame& frame) override {
- max_streams_frame_ = frame;
- EXPECT_TRUE(VersionHasIetfQuicFrames(transport_version_));
- EXPECT_TRUE(IETF_MAX_STREAMS_UNIDIRECTIONAL ==
- framer_->current_received_frame_type() ||
- IETF_MAX_STREAMS_BIDIRECTIONAL ==
- framer_->current_received_frame_type());
- return true;
- }
-
- bool OnStreamsBlockedFrame(const QuicStreamsBlockedFrame& frame) override {
- streams_blocked_frame_ = frame;
- EXPECT_TRUE(VersionHasIetfQuicFrames(transport_version_));
- EXPECT_TRUE(IETF_STREAMS_BLOCKED_UNIDIRECTIONAL ==
- framer_->current_received_frame_type() ||
- IETF_STREAMS_BLOCKED_BIDIRECTIONAL ==
- framer_->current_received_frame_type());
- return true;
- }
-
- bool OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame) override {
- window_update_frame_ = frame;
- if (VersionHasIetfQuicFrames(transport_version_)) {
- EXPECT_TRUE(IETF_MAX_DATA == framer_->current_received_frame_type() ||
- IETF_MAX_STREAM_DATA ==
- framer_->current_received_frame_type());
- } else {
- EXPECT_EQ(0u, framer_->current_received_frame_type());
- }
- return true;
- }
-
- bool OnBlockedFrame(const QuicBlockedFrame& frame) override {
- blocked_frame_ = frame;
- if (VersionHasIetfQuicFrames(transport_version_)) {
- EXPECT_TRUE(IETF_DATA_BLOCKED == framer_->current_received_frame_type() ||
- IETF_STREAM_DATA_BLOCKED ==
- framer_->current_received_frame_type());
- } else {
- EXPECT_EQ(0u, framer_->current_received_frame_type());
- }
- return true;
- }
-
- bool OnNewConnectionIdFrame(const QuicNewConnectionIdFrame& frame) override {
- new_connection_id_ = frame;
- EXPECT_EQ(IETF_NEW_CONNECTION_ID, framer_->current_received_frame_type());
- EXPECT_TRUE(VersionHasIetfQuicFrames(transport_version_));
- return true;
- }
-
- bool OnRetireConnectionIdFrame(
- const QuicRetireConnectionIdFrame& frame) override {
- EXPECT_EQ(IETF_RETIRE_CONNECTION_ID,
- framer_->current_received_frame_type());
- EXPECT_TRUE(VersionHasIetfQuicFrames(transport_version_));
- retire_connection_id_ = frame;
- return true;
- }
-
- bool OnNewTokenFrame(const QuicNewTokenFrame& frame) override {
- new_token_ = frame;
- EXPECT_EQ(IETF_NEW_TOKEN, framer_->current_received_frame_type());
- EXPECT_TRUE(VersionHasIetfQuicFrames(transport_version_));
- return true;
- }
-
- bool IsValidStatelessResetToken(
- const StatelessResetToken& token) const override {
- EXPECT_EQ(0u, framer_->current_received_frame_type());
- return token == kTestStatelessResetToken;
- }
-
- void OnAuthenticatedIetfStatelessResetPacket(
- const QuicIetfStatelessResetPacket& packet) override {
- stateless_reset_packet_ =
- std::make_unique<QuicIetfStatelessResetPacket>(packet);
- EXPECT_EQ(0u, framer_->current_received_frame_type());
- }
-
- void OnKeyUpdate(KeyUpdateReason reason) override {
- key_update_reasons_.push_back(reason);
- }
-
- void OnDecryptedFirstPacketInKeyPhase() override {
- decrypted_first_packet_in_key_phase_count_++;
- }
-
- std::unique_ptr<QuicDecrypter> AdvanceKeysAndCreateCurrentOneRttDecrypter()
- override {
- derive_next_key_count_++;
- return std::make_unique<StrictTaggingDecrypter>(derive_next_key_count_);
- }
- std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() override {
- return std::make_unique<TaggingEncrypter>(derive_next_key_count_);
- }
-
- void set_framer(QuicFramer* framer) {
- framer_ = framer;
- transport_version_ = framer->transport_version();
- }
-
- size_t key_update_count() const { return key_update_reasons_.size(); }
-
- // Counters from the visitor_ callbacks.
- int error_count_;
- int version_mismatch_;
- int packet_count_;
- int frame_count_;
- int complete_packets_;
- std::vector<KeyUpdateReason> key_update_reasons_;
- int derive_next_key_count_;
- int decrypted_first_packet_in_key_phase_count_;
- bool accept_packet_;
- bool accept_public_header_;
-
- std::unique_ptr<QuicPacketHeader> header_;
- std::unique_ptr<QuicPublicResetPacket> public_reset_packet_;
- std::unique_ptr<QuicIetfStatelessResetPacket> stateless_reset_packet_;
- std::unique_ptr<QuicVersionNegotiationPacket> version_negotiation_packet_;
- std::unique_ptr<QuicConnectionId> retry_original_connection_id_;
- std::unique_ptr<QuicConnectionId> retry_new_connection_id_;
- std::unique_ptr<std::string> retry_token_;
- std::unique_ptr<std::string> retry_token_integrity_tag_;
- std::unique_ptr<std::string> retry_without_tag_;
- bool on_retry_packet_called_ = false;
- std::vector<std::unique_ptr<QuicStreamFrame>> stream_frames_;
- std::vector<std::unique_ptr<QuicCryptoFrame>> crypto_frames_;
- std::vector<std::unique_ptr<QuicAckFrame>> ack_frames_;
- std::vector<std::unique_ptr<QuicStopWaitingFrame>> stop_waiting_frames_;
- std::vector<std::unique_ptr<QuicPaddingFrame>> padding_frames_;
- std::vector<std::unique_ptr<QuicPingFrame>> ping_frames_;
- std::vector<std::unique_ptr<QuicMessageFrame>> message_frames_;
- std::vector<std::unique_ptr<QuicHandshakeDoneFrame>> handshake_done_frames_;
- std::vector<std::unique_ptr<QuicAckFrequencyFrame>> ack_frequency_frames_;
- std::vector<std::unique_ptr<QuicEncryptedPacket>> coalesced_packets_;
- std::vector<std::unique_ptr<QuicEncryptedPacket>> undecryptable_packets_;
- std::vector<EncryptionLevel> undecryptable_decryption_levels_;
- std::vector<bool> undecryptable_has_decryption_keys_;
- QuicRstStreamFrame rst_stream_frame_;
- QuicConnectionCloseFrame connection_close_frame_;
- QuicStopSendingFrame stop_sending_frame_;
- QuicGoAwayFrame goaway_frame_;
- QuicPathChallengeFrame path_challenge_frame_;
- QuicPathResponseFrame path_response_frame_;
- QuicWindowUpdateFrame window_update_frame_;
- QuicBlockedFrame blocked_frame_;
- QuicStreamsBlockedFrame streams_blocked_frame_;
- QuicMaxStreamsFrame max_streams_frame_;
- QuicNewConnectionIdFrame new_connection_id_;
- QuicRetireConnectionIdFrame retire_connection_id_;
- QuicNewTokenFrame new_token_;
- std::vector<std::unique_ptr<std::string>> stream_data_;
- std::vector<std::unique_ptr<std::string>> crypto_data_;
- QuicTransportVersion transport_version_;
- QuicFramer* framer_;
-};
-
-// Simple struct for defining a packet's content, and associated
-// parse error.
-struct PacketFragment {
- std::string error_if_missing;
- std::vector<unsigned char> fragment;
-};
-
-using PacketFragments = std::vector<struct PacketFragment>;
-
-class QuicFramerTest : public QuicTestWithParam<ParsedQuicVersion> {
- public:
- QuicFramerTest()
- : encrypter_(new test::TestEncrypter()),
- decrypter_(new test::TestDecrypter()),
- version_(GetParam()),
- start_(QuicTime::Zero() + QuicTime::Delta::FromMicroseconds(0x10)),
- framer_(AllSupportedVersions(), start_, Perspective::IS_SERVER,
- kQuicDefaultConnectionIdLength) {
- framer_.set_version(version_);
- if (framer_.version().KnowsWhichDecrypterToUse()) {
- framer_.InstallDecrypter(ENCRYPTION_INITIAL,
- std::unique_ptr<QuicDecrypter>(decrypter_));
- } else {
- framer_.SetDecrypter(ENCRYPTION_INITIAL,
- std::unique_ptr<QuicDecrypter>(decrypter_));
- }
- framer_.SetEncrypter(ENCRYPTION_INITIAL,
- std::unique_ptr<QuicEncrypter>(encrypter_));
-
- framer_.set_visitor(&visitor_);
- framer_.InferPacketHeaderTypeFromVersion();
- visitor_.set_framer(&framer_);
- }
-
- void SetDecrypterLevel(EncryptionLevel level) {
- if (!framer_.version().KnowsWhichDecrypterToUse()) {
- return;
- }
- decrypter_ = new TestDecrypter();
- framer_.InstallDecrypter(level, std::unique_ptr<QuicDecrypter>(decrypter_));
- }
-
- // Helper function to get unsigned char representation of the handshake
- // protocol byte at position |pos| of the current QUIC version number.
- unsigned char GetQuicVersionByte(int pos) {
- return (CreateQuicVersionLabel(version_) >> 8 * (3 - pos)) & 0xff;
- }
-
- // Helper functions to take a v1 long header packet and make it v2. These are
- // not needed for short header packets, but if sent, this function will exit
- // cleanly. It needs to be called twice for coalesced packets (see references
- // to length_of_first_coalesced_packet below for examples of how to do this).
- inline void ReviseFirstByteByVersion(unsigned char packet_ietf[]) {
- if (version_.UsesV2PacketTypes() && (packet_ietf[0] >= 0x80)) {
- packet_ietf[0] = (packet_ietf[0] + 0x10) | 0xc0;
- }
- }
- inline void ReviseFirstByteByVersion(PacketFragments& packet_ietf) {
- ReviseFirstByteByVersion(&packet_ietf[0].fragment[0]);
- }
-
- bool CheckEncryption(QuicPacketNumber packet_number, QuicPacket* packet) {
- if (packet_number != encrypter_->packet_number_) {
- QUIC_LOG(ERROR) << "Encrypted incorrect packet number. expected "
- << packet_number
- << " actual: " << encrypter_->packet_number_;
- return false;
- }
- if (packet->AssociatedData(framer_.transport_version()) !=
- encrypter_->associated_data_) {
- QUIC_LOG(ERROR) << "Encrypted incorrect associated data. expected "
- << packet->AssociatedData(framer_.transport_version())
- << " actual: " << encrypter_->associated_data_;
- return false;
- }
- if (packet->Plaintext(framer_.transport_version()) !=
- encrypter_->plaintext_) {
- QUIC_LOG(ERROR) << "Encrypted incorrect plaintext data. expected "
- << packet->Plaintext(framer_.transport_version())
- << " actual: " << encrypter_->plaintext_;
- return false;
- }
- return true;
- }
-
- bool CheckDecryption(const QuicEncryptedPacket& encrypted,
- bool includes_version,
- bool includes_diversification_nonce,
- QuicConnectionIdLength destination_connection_id_length,
- QuicConnectionIdLength source_connection_id_length) {
- return CheckDecryption(
- encrypted, includes_version, includes_diversification_nonce,
- destination_connection_id_length, source_connection_id_length,
- VARIABLE_LENGTH_INTEGER_LENGTH_0, 0, VARIABLE_LENGTH_INTEGER_LENGTH_0);
- }
-
- bool CheckDecryption(
- const QuicEncryptedPacket& encrypted, bool includes_version,
- bool includes_diversification_nonce,
- QuicConnectionIdLength destination_connection_id_length,
- QuicConnectionIdLength source_connection_id_length,
- QuicVariableLengthIntegerLength retry_token_length_length,
- size_t retry_token_length,
- QuicVariableLengthIntegerLength length_length) {
- if (visitor_.header_->packet_number != decrypter_->packet_number_) {
- QUIC_LOG(ERROR) << "Decrypted incorrect packet number. expected "
- << visitor_.header_->packet_number
- << " actual: " << decrypter_->packet_number_;
- return false;
- }
- absl::string_view associated_data =
- QuicFramer::GetAssociatedDataFromEncryptedPacket(
- framer_.transport_version(), encrypted,
- destination_connection_id_length, source_connection_id_length,
- includes_version, includes_diversification_nonce,
- PACKET_4BYTE_PACKET_NUMBER, retry_token_length_length,
- retry_token_length, length_length);
- if (associated_data != decrypter_->associated_data_) {
- QUIC_LOG(ERROR) << "Decrypted incorrect associated data. expected "
- << absl::BytesToHexString(associated_data) << " actual: "
- << absl::BytesToHexString(decrypter_->associated_data_);
- return false;
- }
- absl::string_view ciphertext(
- encrypted.AsStringPiece().substr(GetStartOfEncryptedData(
- framer_.transport_version(), destination_connection_id_length,
- source_connection_id_length, includes_version,
- includes_diversification_nonce, PACKET_4BYTE_PACKET_NUMBER,
- retry_token_length_length, retry_token_length, length_length)));
- if (ciphertext != decrypter_->ciphertext_) {
- QUIC_LOG(ERROR) << "Decrypted incorrect ciphertext data. expected "
- << absl::BytesToHexString(ciphertext) << " actual: "
- << absl::BytesToHexString(decrypter_->ciphertext_)
- << " associated data: "
- << absl::BytesToHexString(associated_data);
- return false;
- }
- return true;
- }
-
- char* AsChars(unsigned char* data) { return reinterpret_cast<char*>(data); }
-
- // Creates a new QuicEncryptedPacket by concatenating the various
- // packet fragments in |fragments|.
- std::unique_ptr<QuicEncryptedPacket> AssemblePacketFromFragments(
- const PacketFragments& fragments) {
- char* buffer = new char[kMaxOutgoingPacketSize + 1];
- size_t len = 0;
- for (const auto& fragment : fragments) {
- memcpy(buffer + len, fragment.fragment.data(), fragment.fragment.size());
- len += fragment.fragment.size();
- }
- return std::make_unique<QuicEncryptedPacket>(buffer, len, true);
- }
-
- void CheckFramingBoundaries(const PacketFragments& fragments,
- QuicErrorCode error_code) {
- std::unique_ptr<QuicEncryptedPacket> packet(
- AssemblePacketFromFragments(fragments));
- // Check all the various prefixes of |packet| for the expected
- // parse error and error code.
- for (size_t i = 0; i < packet->length(); ++i) {
- std::string expected_error;
- size_t len = 0;
- for (const auto& fragment : fragments) {
- len += fragment.fragment.size();
- if (i < len) {
- expected_error = fragment.error_if_missing;
- break;
- }
- }
-
- if (expected_error.empty()) continue;
-
- CheckProcessingFails(*packet, i, expected_error, error_code);
- }
- }
-
- void CheckProcessingFails(const QuicEncryptedPacket& packet, size_t len,
- std::string expected_error,
- QuicErrorCode error_code) {
- QuicEncryptedPacket encrypted(packet.data(), len, false);
- EXPECT_FALSE(framer_.ProcessPacket(encrypted)) << "len: " << len;
- EXPECT_EQ(expected_error, framer_.detailed_error()) << "len: " << len;
- EXPECT_EQ(error_code, framer_.error()) << "len: " << len;
- }
-
- void CheckProcessingFails(unsigned char* packet, size_t len,
- std::string expected_error,
- QuicErrorCode error_code) {
- QuicEncryptedPacket encrypted(AsChars(packet), len, false);
- EXPECT_FALSE(framer_.ProcessPacket(encrypted)) << "len: " << len;
- EXPECT_EQ(expected_error, framer_.detailed_error()) << "len: " << len;
- EXPECT_EQ(error_code, framer_.error()) << "len: " << len;
- }
-
- // Checks if the supplied string matches data in the supplied StreamFrame.
- void CheckStreamFrameData(std::string str, QuicStreamFrame* frame) {
- EXPECT_EQ(str, std::string(frame->data_buffer, frame->data_length));
- }
-
- void CheckCalculatePacketNumber(uint64_t expected_packet_number,
- QuicPacketNumber last_packet_number) {
- uint64_t wire_packet_number = expected_packet_number & kMask;
- EXPECT_EQ(expected_packet_number,
- QuicFramerPeer::CalculatePacketNumberFromWire(
- &framer_, PACKET_4BYTE_PACKET_NUMBER, last_packet_number,
- wire_packet_number))
- << "last_packet_number: " << last_packet_number
- << " wire_packet_number: " << wire_packet_number;
- }
-
- std::unique_ptr<QuicPacket> BuildDataPacket(const QuicPacketHeader& header,
- const QuicFrames& frames) {
- return BuildUnsizedDataPacket(&framer_, header, frames);
- }
-
- std::unique_ptr<QuicPacket> BuildDataPacket(const QuicPacketHeader& header,
- const QuicFrames& frames,
- size_t packet_size) {
- return BuildUnsizedDataPacket(&framer_, header, frames, packet_size);
- }
-
- // N starts at 1.
- QuicStreamId GetNthStreamid(QuicTransportVersion transport_version,
- Perspective perspective, bool bidirectional,
- int n) {
- if (bidirectional) {
- return QuicUtils::GetFirstBidirectionalStreamId(transport_version,
- perspective) +
- ((n - 1) * QuicUtils::StreamIdDelta(transport_version));
- }
- // Unidirectional
- return QuicUtils::GetFirstUnidirectionalStreamId(transport_version,
- perspective) +
- ((n - 1) * QuicUtils::StreamIdDelta(transport_version));
- }
-
- QuicTime CreationTimePlus(uint64_t offset_us) {
- return framer_.creation_time() +
- QuicTime::Delta::FromMicroseconds(offset_us);
- }
-
- test::TestEncrypter* encrypter_;
- test::TestDecrypter* decrypter_;
- ParsedQuicVersion version_;
- QuicTime start_;
- QuicFramer framer_;
- test::TestQuicVisitor visitor_;
- SimpleBufferAllocator allocator_;
-};
-
-// Multiple test cases of QuicFramerTest use byte arrays to define packets for
-// testing, and these byte arrays contain the QUIC version. This macro explodes
-// the 32-bit version into four bytes in network order. Since it uses methods of
-// QuicFramerTest, it is only valid to use this in a QuicFramerTest.
-#define QUIC_VERSION_BYTES \
- GetQuicVersionByte(0), GetQuicVersionByte(1), GetQuicVersionByte(2), \
- GetQuicVersionByte(3)
-
-// Run all framer tests with all supported versions of QUIC.
-INSTANTIATE_TEST_SUITE_P(QuicFramerTests, QuicFramerTest,
- ::testing::ValuesIn(AllSupportedVersions()),
- ::testing::PrintToStringParamName());
-
-TEST_P(QuicFramerTest, CalculatePacketNumberFromWireNearEpochStart) {
- // A few quick manual sanity checks.
- CheckCalculatePacketNumber(UINT64_C(1), QuicPacketNumber());
- CheckCalculatePacketNumber(kEpoch + 1, QuicPacketNumber(kMask));
- CheckCalculatePacketNumber(kEpoch, QuicPacketNumber(kMask));
- for (uint64_t j = 0; j < 10; j++) {
- CheckCalculatePacketNumber(j, QuicPacketNumber());
- CheckCalculatePacketNumber(kEpoch - 1 - j, QuicPacketNumber());
- }
-
- // Cases where the last number was close to the start of the range.
- for (QuicPacketNumber last = QuicPacketNumber(1); last < QuicPacketNumber(10);
- last++) {
- // Small numbers should not wrap (even if they're out of order).
- for (uint64_t j = 0; j < 10; j++) {
- CheckCalculatePacketNumber(j, last);
- }
-
- // Large numbers should not wrap either (because we're near 0 already).
- for (uint64_t j = 0; j < 10; j++) {
- CheckCalculatePacketNumber(kEpoch - 1 - j, last);
- }
- }
-}
-
-TEST_P(QuicFramerTest, CalculatePacketNumberFromWireNearEpochEnd) {
- // Cases where the last number was close to the end of the range
- for (uint64_t i = 0; i < 10; i++) {
- QuicPacketNumber last = QuicPacketNumber(kEpoch - i);
-
- // Small numbers should wrap.
- for (uint64_t j = 0; j < 10; j++) {
- CheckCalculatePacketNumber(kEpoch + j, last);
- }
-
- // Large numbers should not (even if they're out of order).
- for (uint64_t j = 0; j < 10; j++) {
- CheckCalculatePacketNumber(kEpoch - 1 - j, last);
- }
- }
-}
-
-// Next check where we're in a non-zero epoch to verify we handle
-// reverse wrapping, too.
-TEST_P(QuicFramerTest, CalculatePacketNumberFromWireNearPrevEpoch) {
- const uint64_t prev_epoch = 1 * kEpoch;
- const uint64_t cur_epoch = 2 * kEpoch;
- // Cases where the last number was close to the start of the range
- for (uint64_t i = 0; i < 10; i++) {
- QuicPacketNumber last = QuicPacketNumber(cur_epoch + i);
- // Small number should not wrap (even if they're out of order).
- for (uint64_t j = 0; j < 10; j++) {
- CheckCalculatePacketNumber(cur_epoch + j, last);
- }
-
- // But large numbers should reverse wrap.
- for (uint64_t j = 0; j < 10; j++) {
- uint64_t num = kEpoch - 1 - j;
- CheckCalculatePacketNumber(prev_epoch + num, last);
- }
- }
-}
-
-TEST_P(QuicFramerTest, CalculatePacketNumberFromWireNearNextEpoch) {
- const uint64_t cur_epoch = 2 * kEpoch;
- const uint64_t next_epoch = 3 * kEpoch;
- // Cases where the last number was close to the end of the range
- for (uint64_t i = 0; i < 10; i++) {
- QuicPacketNumber last = QuicPacketNumber(next_epoch - 1 - i);
-
- // Small numbers should wrap.
- for (uint64_t j = 0; j < 10; j++) {
- CheckCalculatePacketNumber(next_epoch + j, last);
- }
-
- // but large numbers should not (even if they're out of order).
- for (uint64_t j = 0; j < 10; j++) {
- uint64_t num = kEpoch - 1 - j;
- CheckCalculatePacketNumber(cur_epoch + num, last);
- }
- }
-}
-
-TEST_P(QuicFramerTest, CalculatePacketNumberFromWireNearNextMax) {
- const uint64_t max_number = std::numeric_limits<uint64_t>::max();
- const uint64_t max_epoch = max_number & ~kMask;
-
- // Cases where the last number was close to the end of the range
- for (uint64_t i = 0; i < 10; i++) {
- // Subtract 1, because the expected next packet number is 1 more than the
- // last packet number.
- QuicPacketNumber last = QuicPacketNumber(max_number - i - 1);
-
- // Small numbers should not wrap, because they have nowhere to go.
- for (uint64_t j = 0; j < 10; j++) {
- CheckCalculatePacketNumber(max_epoch + j, last);
- }
-
- // Large numbers should not wrap either.
- for (uint64_t j = 0; j < 10; j++) {
- uint64_t num = kEpoch - 1 - j;
- CheckCalculatePacketNumber(max_epoch + num, last);
- }
- }
-}
-
-TEST_P(QuicFramerTest, EmptyPacket) {
- char packet[] = {0x00};
- QuicEncryptedPacket encrypted(packet, 0, false);
- EXPECT_FALSE(framer_.ProcessPacket(encrypted));
- EXPECT_THAT(framer_.error(), IsError(QUIC_INVALID_PACKET_HEADER));
-}
-
-TEST_P(QuicFramerTest, LargePacket) {
- SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
- // clang-format off
- unsigned char packet[kMaxIncomingPacketSize + 1] = {
- // public flags (8 byte connection_id)
- 0x28,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x78, 0x56, 0x34, 0x12,
- // private flags
- 0x00,
- };
- unsigned char packet46[kMaxIncomingPacketSize + 1] = {
- // type (short header 4 byte packet number)
- 0x43,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x78, 0x56, 0x34, 0x12,
- };
- // clang-format on
- unsigned char* p = packet;
- size_t p_size = ABSL_ARRAYSIZE(packet);
- if (framer_.version().HasIetfInvariantHeader()) {
- p = packet46;
- p_size = ABSL_ARRAYSIZE(packet46);
- }
-
- const size_t header_size = GetPacketHeaderSize(
- framer_.transport_version(), PACKET_8BYTE_CONNECTION_ID,
- PACKET_0BYTE_CONNECTION_ID, !kIncludeVersion,
- !kIncludeDiversificationNonce, PACKET_4BYTE_PACKET_NUMBER,
- VARIABLE_LENGTH_INTEGER_LENGTH_0, 0, VARIABLE_LENGTH_INTEGER_LENGTH_0);
-
- memset(p + header_size, 0, kMaxIncomingPacketSize - header_size);
-
- QuicEncryptedPacket encrypted(AsChars(p), p_size, false);
- EXPECT_FALSE(framer_.ProcessPacket(encrypted));
-
- ASSERT_TRUE(visitor_.header_.get());
- // Make sure we've parsed the packet header, so we can send an error.
- EXPECT_EQ(FramerTestConnectionId(),
- visitor_.header_->destination_connection_id);
- // Make sure the correct error is propagated.
- EXPECT_THAT(framer_.error(), IsError(QUIC_PACKET_TOO_LARGE));
- EXPECT_EQ("Packet too large.", framer_.detailed_error());
-}
-
-TEST_P(QuicFramerTest, PacketHeader) {
- if (framer_.version().HasIetfInvariantHeader()) {
- return;
- }
-
- // clang-format off
- PacketFragments packet = {
- // public flags (8 byte connection_id)
- {"Unable to read public flags.",
- {0x28}},
- // connection_id
- {"Unable to read ConnectionId.",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // packet number
- {"Unable to read packet number.",
- {0x12, 0x34, 0x56, 0x78}},
- };
- // clang-format on
-
- PacketFragments& fragments = packet;
-
- std::unique_ptr<QuicEncryptedPacket> encrypted(
- AssemblePacketFromFragments(fragments));
-
- EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
- EXPECT_THAT(framer_.error(), IsError(QUIC_MISSING_PAYLOAD));
- ASSERT_TRUE(visitor_.header_.get());
- EXPECT_EQ(FramerTestConnectionId(),
- visitor_.header_->destination_connection_id);
- EXPECT_FALSE(visitor_.header_->reset_flag);
- EXPECT_FALSE(visitor_.header_->version_flag);
- EXPECT_EQ(kPacketNumber, visitor_.header_->packet_number);
-
- CheckFramingBoundaries(fragments, QUIC_INVALID_PACKET_HEADER);
-
- PacketHeaderFormat format;
- QuicLongHeaderType long_packet_type = INVALID_PACKET_TYPE;
- bool version_flag;
- QuicConnectionId destination_connection_id, source_connection_id;
- QuicVersionLabel version_label;
- std::string detailed_error;
- bool use_length_prefix;
- absl::optional<absl::string_view> retry_token;
- ParsedQuicVersion parsed_version = UnsupportedQuicVersion();
- const QuicErrorCode error_code = QuicFramer::ParsePublicHeaderDispatcher(
- *encrypted, kQuicDefaultConnectionIdLength, &format, &long_packet_type,
- &version_flag, &use_length_prefix, &version_label, &parsed_version,
- &destination_connection_id, &source_connection_id, &retry_token,
- &detailed_error);
- EXPECT_FALSE(retry_token.has_value());
- EXPECT_FALSE(use_length_prefix);
- EXPECT_THAT(error_code, IsQuicNoError());
- EXPECT_EQ(GOOGLE_QUIC_PACKET, format);
- EXPECT_FALSE(version_flag);
- EXPECT_EQ(kQuicDefaultConnectionIdLength, destination_connection_id.length());
- EXPECT_EQ(FramerTestConnectionId(), destination_connection_id);
- EXPECT_EQ(EmptyQuicConnectionId(), source_connection_id);
-}
-
-TEST_P(QuicFramerTest, LongPacketHeader) {
- // clang-format off
- PacketFragments packet46 = {
- // type (long header with packet type ZERO_RTT)
- {"Unable to read first byte.",
- {0xD3}},
- // version tag
- {"Unable to read protocol version.",
- {QUIC_VERSION_BYTES}},
- // connection_id length
- {"Unable to read ConnectionId length.",
- {0x50}},
- // connection_id
- {"Unable to read destination connection ID.",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // packet number
- {"Unable to read packet number.",
- {0x12, 0x34, 0x56, 0x78}},
- };
- // clang-format on
-
- if (!framer_.version().HasIetfInvariantHeader() ||
- QuicVersionHasLongHeaderLengths(framer_.transport_version())) {
- return;
- }
-
- SetDecrypterLevel(ENCRYPTION_ZERO_RTT);
- std::unique_ptr<QuicEncryptedPacket> encrypted(
- AssemblePacketFromFragments(packet46));
-
- EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
- EXPECT_THAT(framer_.error(), IsError(QUIC_MISSING_PAYLOAD));
- ASSERT_TRUE(visitor_.header_.get());
- EXPECT_EQ(FramerTestConnectionId(),
- visitor_.header_->destination_connection_id);
- EXPECT_FALSE(visitor_.header_->reset_flag);
- EXPECT_TRUE(visitor_.header_->version_flag);
- EXPECT_EQ(kPacketNumber, visitor_.header_->packet_number);
-
- CheckFramingBoundaries(packet46, QUIC_INVALID_PACKET_HEADER);
-
- PacketHeaderFormat format;
- QuicLongHeaderType long_packet_type = INVALID_PACKET_TYPE;
- bool version_flag;
- QuicConnectionId destination_connection_id, source_connection_id;
- QuicVersionLabel version_label;
- std::string detailed_error;
- bool use_length_prefix;
- absl::optional<absl::string_view> retry_token;
- ParsedQuicVersion parsed_version = UnsupportedQuicVersion();
- const QuicErrorCode error_code = QuicFramer::ParsePublicHeaderDispatcher(
- *encrypted, kQuicDefaultConnectionIdLength, &format, &long_packet_type,
- &version_flag, &use_length_prefix, &version_label, &parsed_version,
- &destination_connection_id, &source_connection_id, &retry_token,
- &detailed_error);
- EXPECT_THAT(error_code, IsQuicNoError());
- EXPECT_EQ("", detailed_error);
- EXPECT_FALSE(retry_token.has_value());
- EXPECT_FALSE(use_length_prefix);
- EXPECT_EQ(IETF_QUIC_LONG_HEADER_PACKET, format);
- EXPECT_TRUE(version_flag);
- EXPECT_EQ(kQuicDefaultConnectionIdLength, destination_connection_id.length());
- EXPECT_EQ(FramerTestConnectionId(), destination_connection_id);
- EXPECT_EQ(EmptyQuicConnectionId(), source_connection_id);
-}
-
-TEST_P(QuicFramerTest, LongPacketHeaderWithBothConnectionIds) {
- if (!framer_.version().HasIetfInvariantHeader()) {
- // This test requires an IETF long header.
- return;
- }
- SetDecrypterLevel(ENCRYPTION_ZERO_RTT);
- // clang-format off
- unsigned char packet[] = {
- // public flags (long header with packet type ZERO_RTT_PROTECTED and
- // 4-byte packet number)
- 0xD3,
- // version
- QUIC_VERSION_BYTES,
- // connection ID lengths
- 0x55,
- // destination connection ID
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // source connection ID
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x11,
- // packet number
- 0x12, 0x34, 0x56, 0x00,
- // padding frame
- 0x00,
- };
- unsigned char packet49[] = {
- // public flags (long header with packet type ZERO_RTT_PROTECTED and
- // 4-byte packet number)
- 0xD3,
- // version
- QUIC_VERSION_BYTES,
- // destination connection ID length
- 0x08,
- // destination connection ID
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // source connection ID length
- 0x08,
- // source connection ID
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x11,
- // long header packet length
- 0x05,
- // packet number
- 0x12, 0x34, 0x56, 0x00,
- // padding frame
- 0x00,
- };
- // clang-format on
-
- unsigned char* p = packet;
- size_t p_length = ABSL_ARRAYSIZE(packet);
- if (framer_.version().HasLongHeaderLengths()) {
- ReviseFirstByteByVersion(packet49);
- p = packet49;
- p_length = ABSL_ARRAYSIZE(packet49);
- }
-
- QuicEncryptedPacket encrypted(AsChars(p), p_length, false);
- PacketHeaderFormat format = GOOGLE_QUIC_PACKET;
- QuicLongHeaderType long_packet_type = INVALID_PACKET_TYPE;
- bool version_flag = false;
- QuicConnectionId destination_connection_id, source_connection_id;
- QuicVersionLabel version_label = 0;
- std::string detailed_error = "";
- bool use_length_prefix;
- absl::optional<absl::string_view> retry_token;
- ParsedQuicVersion parsed_version = UnsupportedQuicVersion();
- const QuicErrorCode error_code = QuicFramer::ParsePublicHeaderDispatcher(
- encrypted, kQuicDefaultConnectionIdLength, &format, &long_packet_type,
- &version_flag, &use_length_prefix, &version_label, &parsed_version,
- &destination_connection_id, &source_connection_id, &retry_token,
- &detailed_error);
- EXPECT_THAT(error_code, IsQuicNoError());
- EXPECT_FALSE(retry_token.has_value());
- EXPECT_EQ(framer_.version().HasLengthPrefixedConnectionIds(),
- use_length_prefix);
- EXPECT_EQ("", detailed_error);
- EXPECT_EQ(IETF_QUIC_LONG_HEADER_PACKET, format);
- EXPECT_TRUE(version_flag);
- EXPECT_EQ(FramerTestConnectionId(), destination_connection_id);
- EXPECT_EQ(FramerTestConnectionIdPlusOne(), source_connection_id);
-}
-
-TEST_P(QuicFramerTest, AllZeroPacketParsingFails) {
- unsigned char packet[1200] = {};
- QuicEncryptedPacket encrypted(AsChars(packet), ABSL_ARRAYSIZE(packet), false);
- PacketHeaderFormat format = GOOGLE_QUIC_PACKET;
- QuicLongHeaderType long_packet_type = INVALID_PACKET_TYPE;
- bool version_flag = false;
- QuicConnectionId destination_connection_id, source_connection_id;
- QuicVersionLabel version_label = 0;
- std::string detailed_error = "";
- bool use_length_prefix;
- absl::optional<absl::string_view> retry_token;
- ParsedQuicVersion parsed_version = UnsupportedQuicVersion();
- const QuicErrorCode error_code = QuicFramer::ParsePublicHeaderDispatcher(
- encrypted, kQuicDefaultConnectionIdLength, &format, &long_packet_type,
- &version_flag, &use_length_prefix, &version_label, &parsed_version,
- &destination_connection_id, &source_connection_id, &retry_token,
- &detailed_error);
- EXPECT_EQ(error_code, QUIC_INVALID_PACKET_HEADER);
- EXPECT_EQ(detailed_error, "Invalid flags.");
-}
-
-TEST_P(QuicFramerTest, ParsePublicHeader) {
- // clang-format off
- unsigned char packet[] = {
- // public flags (version included, 8-byte connection ID,
- // 4-byte packet number)
- 0x29,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // version
- QUIC_VERSION_BYTES,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
- // padding frame
- 0x00,
- };
- unsigned char packet46[] = {
- // public flags (long header with packet type HANDSHAKE and
- // 4-byte packet number)
- 0xE3,
- // version
- QUIC_VERSION_BYTES,
- // connection ID lengths
- 0x50,
- // destination connection ID
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // long header packet length
- 0x05,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
- // padding frame
- 0x00,
- };
- unsigned char packet49[] = {
- // public flags (long header with packet type HANDSHAKE and
- // 4-byte packet number)
- 0xE3,
- // version
- QUIC_VERSION_BYTES,
- // destination connection ID length
- 0x08,
- // destination connection ID
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // source connection ID length
- 0x00,
- // long header packet length
- 0x05,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
- // padding frame
- 0x00,
- };
- // clang-format on
- unsigned char* p = packet;
- size_t p_length = ABSL_ARRAYSIZE(packet);
- if (framer_.version().HasLongHeaderLengths()) {
- ReviseFirstByteByVersion(packet49);
- p = packet49;
- p_length = ABSL_ARRAYSIZE(packet49);
- } else if (framer_.version().HasIetfInvariantHeader()) {
- p = packet46;
- p_length = ABSL_ARRAYSIZE(packet46);
- }
-
- uint8_t first_byte = 0x33;
- PacketHeaderFormat format = GOOGLE_QUIC_PACKET;
- bool version_present = false, has_length_prefix = false;
- QuicVersionLabel version_label = 0;
- ParsedQuicVersion parsed_version = UnsupportedQuicVersion();
- QuicConnectionId destination_connection_id = EmptyQuicConnectionId(),
- source_connection_id = EmptyQuicConnectionId();
- QuicLongHeaderType long_packet_type = INVALID_PACKET_TYPE;
- QuicVariableLengthIntegerLength retry_token_length_length =
- VARIABLE_LENGTH_INTEGER_LENGTH_4;
- absl::string_view retry_token;
- std::string detailed_error = "foobar";
-
- QuicDataReader reader(AsChars(p), p_length);
- const QuicErrorCode parse_error = QuicFramer::ParsePublicHeader(
- &reader, kQuicDefaultConnectionIdLength,
- /*ietf_format=*/
- framer_.version().HasIetfInvariantHeader(), &first_byte, &format,
- &version_present, &has_length_prefix, &version_label, &parsed_version,
- &destination_connection_id, &source_connection_id, &long_packet_type,
- &retry_token_length_length, &retry_token, &detailed_error);
- EXPECT_THAT(parse_error, IsQuicNoError());
- EXPECT_EQ("", detailed_error);
- EXPECT_EQ(p[0], first_byte);
- EXPECT_TRUE(version_present);
- EXPECT_EQ(framer_.version().HasLengthPrefixedConnectionIds(),
- has_length_prefix);
- EXPECT_EQ(CreateQuicVersionLabel(framer_.version()), version_label);
- EXPECT_EQ(framer_.version(), parsed_version);
- EXPECT_EQ(FramerTestConnectionId(), destination_connection_id);
- EXPECT_EQ(EmptyQuicConnectionId(), source_connection_id);
- EXPECT_EQ(VARIABLE_LENGTH_INTEGER_LENGTH_0, retry_token_length_length);
- EXPECT_EQ(absl::string_view(), retry_token);
- if (framer_.version().HasIetfInvariantHeader()) {
- EXPECT_EQ(IETF_QUIC_LONG_HEADER_PACKET, format);
- EXPECT_EQ(HANDSHAKE, long_packet_type);
- } else {
- EXPECT_EQ(GOOGLE_QUIC_PACKET, format);
- }
-}
-
-TEST_P(QuicFramerTest, ParsePublicHeaderProxBadSourceConnectionIdLength) {
- if (!framer_.version().HasLengthPrefixedConnectionIds()) {
- return;
- }
- // clang-format off
- unsigned char packet[] = {
- // public flags (long header with packet type HANDSHAKE and
- // 4-byte packet number)
- 0xE3,
- // version
- 'P', 'R', 'O', 'X',
- // destination connection ID length
- 0x08,
- // destination connection ID
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // source connection ID length (bogus)
- 0xEE,
- // long header packet length
- 0x05,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
- // padding frame
- 0x00,
- };
- // clang-format on
- unsigned char* p = packet;
- size_t p_length = ABSL_ARRAYSIZE(packet);
-
- uint8_t first_byte = 0x33;
- PacketHeaderFormat format = GOOGLE_QUIC_PACKET;
- bool version_present = false, has_length_prefix = false;
- QuicVersionLabel version_label = 0;
- ParsedQuicVersion parsed_version = UnsupportedQuicVersion();
- QuicConnectionId destination_connection_id = EmptyQuicConnectionId(),
- source_connection_id = EmptyQuicConnectionId();
- QuicLongHeaderType long_packet_type = INVALID_PACKET_TYPE;
- QuicVariableLengthIntegerLength retry_token_length_length =
- VARIABLE_LENGTH_INTEGER_LENGTH_4;
- absl::string_view retry_token;
- std::string detailed_error = "foobar";
-
- QuicDataReader reader(AsChars(p), p_length);
- const QuicErrorCode parse_error = QuicFramer::ParsePublicHeader(
- &reader, kQuicDefaultConnectionIdLength,
- /*ietf_format=*/true, &first_byte, &format, &version_present,
- &has_length_prefix, &version_label, &parsed_version,
- &destination_connection_id, &source_connection_id, &long_packet_type,
- &retry_token_length_length, &retry_token, &detailed_error);
- EXPECT_THAT(parse_error, IsQuicNoError());
- EXPECT_EQ("", detailed_error);
- EXPECT_EQ(p[0], first_byte);
- EXPECT_TRUE(version_present);
- EXPECT_TRUE(has_length_prefix);
- EXPECT_EQ(0x50524F58u, version_label); // "PROX"
- EXPECT_EQ(UnsupportedQuicVersion(), parsed_version);
- EXPECT_EQ(FramerTestConnectionId(), destination_connection_id);
- EXPECT_EQ(EmptyQuicConnectionId(), source_connection_id);
- EXPECT_EQ(VARIABLE_LENGTH_INTEGER_LENGTH_0, retry_token_length_length);
- EXPECT_EQ(absl::string_view(), retry_token);
- EXPECT_EQ(IETF_QUIC_LONG_HEADER_PACKET, format);
-}
-
-TEST_P(QuicFramerTest, ClientConnectionIdFromShortHeaderToClient) {
- if (!framer_.version().SupportsClientConnectionIds()) {
- return;
- }
- SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
- QuicFramerPeer::SetLastSerializedServerConnectionId(&framer_,
- TestConnectionId(0x33));
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
- framer_.SetExpectedClientConnectionIdLength(kQuicDefaultConnectionIdLength);
- // clang-format off
- unsigned char packet[] = {
- // type (short header, 4 byte packet number)
- 0x43,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x13, 0x37, 0x42, 0x33,
- // padding frame
- 0x00,
- };
- // clang-format on
- QuicEncryptedPacket encrypted(AsChars(packet), ABSL_ARRAYSIZE(packet), false);
- EXPECT_TRUE(framer_.ProcessPacket(encrypted));
- EXPECT_THAT(framer_.error(), IsQuicNoError());
- EXPECT_EQ("", framer_.detailed_error());
- ASSERT_TRUE(visitor_.header_.get());
- EXPECT_EQ(FramerTestConnectionId(),
- visitor_.header_->destination_connection_id);
-}
-
-// In short header packets from client to server, the client connection ID
-// is omitted, but the framer adds it to the header struct using its
-// last serialized client connection ID. This test ensures that this
-// mechanism behaves as expected.
-TEST_P(QuicFramerTest, ClientConnectionIdFromShortHeaderToServer) {
- if (!framer_.version().SupportsClientConnectionIds()) {
- return;
- }
- SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
- QuicFramerPeer::SetLastSerializedClientConnectionId(&framer_,
- TestConnectionId(0x33));
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
- // clang-format off
- unsigned char packet[] = {
- // type (short header, 4 byte packet number)
- 0x43,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x13, 0x37, 0x42, 0x33,
- // padding frame
- 0x00,
- };
- // clang-format on
- QuicEncryptedPacket encrypted(AsChars(packet), ABSL_ARRAYSIZE(packet), false);
- EXPECT_TRUE(framer_.ProcessPacket(encrypted));
- EXPECT_THAT(framer_.error(), IsQuicNoError());
- EXPECT_EQ("", framer_.detailed_error());
- ASSERT_TRUE(visitor_.header_.get());
- EXPECT_EQ(FramerTestConnectionId(),
- visitor_.header_->destination_connection_id);
-}
-
-TEST_P(QuicFramerTest, PacketHeaderWith0ByteConnectionId) {
- SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
- QuicFramerPeer::SetLastSerializedServerConnectionId(&framer_,
- FramerTestConnectionId());
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
-
- // clang-format off
- PacketFragments packet = {
- // public flags (0 byte connection_id)
- {"Unable to read public flags.",
- {0x20}},
- // connection_id
- // packet number
- {"Unable to read packet number.",
- {0x12, 0x34, 0x56, 0x78}},
- };
-
- PacketFragments packet46 = {
- // type (short header, 4 byte packet number)
- {"Unable to read first byte.",
- {0x43}},
- // connection_id
- // packet number
- {"Unable to read packet number.",
- {0x12, 0x34, 0x56, 0x78}},
- };
-
- PacketFragments packet_hp = {
- // type (short header, 4 byte packet number)
- {"Unable to read first byte.",
- {0x43}},
- // connection_id
- // packet number
- {"",
- {0x12, 0x34, 0x56, 0x78}},
- };
- // clang-format on
-
- PacketFragments& fragments =
- framer_.version().HasHeaderProtection()
- ? packet_hp
- : (framer_.version().HasIetfInvariantHeader() ? packet46 : packet);
- std::unique_ptr<QuicEncryptedPacket> encrypted(
- AssemblePacketFromFragments(fragments));
- EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
- EXPECT_THAT(framer_.error(), IsError(QUIC_MISSING_PAYLOAD));
- ASSERT_TRUE(visitor_.header_.get());
- EXPECT_FALSE(visitor_.header_->reset_flag);
- EXPECT_FALSE(visitor_.header_->version_flag);
- EXPECT_EQ(kPacketNumber, visitor_.header_->packet_number);
-
- CheckFramingBoundaries(fragments, QUIC_INVALID_PACKET_HEADER);
-}
-
-TEST_P(QuicFramerTest, PacketHeaderWithVersionFlag) {
- SetDecrypterLevel(ENCRYPTION_ZERO_RTT);
- // clang-format off
- PacketFragments packet = {
- // public flags (0 byte connection_id)
- {"Unable to read public flags.",
- {0x29}},
- // connection_id
- {"Unable to read ConnectionId.",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // version tag
- {"Unable to read protocol version.",
- {QUIC_VERSION_BYTES}},
- // packet number
- {"Unable to read packet number.",
- {0x12, 0x34, 0x56, 0x78}},
- };
-
- PacketFragments packet46 = {
- // type (long header with packet type ZERO_RTT_PROTECTED and 4 bytes
- // packet number)
- {"Unable to read first byte.",
- {0xD3}},
- // version tag
- {"Unable to read protocol version.",
- {QUIC_VERSION_BYTES}},
- // connection_id length
- {"Unable to read ConnectionId length.",
- {0x50}},
- // connection_id
- {"Unable to read destination connection ID.",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // packet number
- {"Unable to read packet number.",
- {0x12, 0x34, 0x56, 0x78}},
- };
-
- PacketFragments packet49 = {
- // type (long header with packet type ZERO_RTT_PROTECTED and 4 bytes
- // packet number)
- {"Unable to read first byte.",
- {0xD3}},
- // version tag
- {"Unable to read protocol version.",
- {QUIC_VERSION_BYTES}},
- // destination connection ID length
- {"Unable to read destination connection ID.",
- {0x08}},
- // destination connection ID
- {"Unable to read destination connection ID.",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // source connection ID length
- {"Unable to read source connection ID.",
- {0x00}},
- // long header packet length
- {"Unable to read long header payload length.",
- {0x04}},
- // packet number
- {"Long header payload length longer than packet.",
- {0x12, 0x34, 0x56, 0x78}},
- };
- // clang-format on
-
- ReviseFirstByteByVersion(packet49);
- PacketFragments& fragments =
- framer_.version().HasLongHeaderLengths()
- ? packet49
- : (framer_.version().HasIetfInvariantHeader() ? packet46 : packet);
- std::unique_ptr<QuicEncryptedPacket> encrypted(
- AssemblePacketFromFragments(fragments));
- EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
- EXPECT_THAT(framer_.error(), IsError(QUIC_MISSING_PAYLOAD));
- ASSERT_TRUE(visitor_.header_.get());
- EXPECT_EQ(FramerTestConnectionId(),
- visitor_.header_->destination_connection_id);
- EXPECT_FALSE(visitor_.header_->reset_flag);
- EXPECT_TRUE(visitor_.header_->version_flag);
- EXPECT_EQ(GetParam(), visitor_.header_->version);
- EXPECT_EQ(kPacketNumber, visitor_.header_->packet_number);
-
- CheckFramingBoundaries(fragments, QUIC_INVALID_PACKET_HEADER);
-}
-
-TEST_P(QuicFramerTest, PacketHeaderWith4BytePacketNumber) {
- SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
- QuicFramerPeer::SetLargestPacketNumber(&framer_, kPacketNumber - 2);
-
- // clang-format off
- PacketFragments packet = {
- // public flags (8 byte connection_id and 4 byte packet number)
- {"Unable to read public flags.",
- {0x28}},
- // connection_id
- {"Unable to read ConnectionId.",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // packet number
- {"Unable to read packet number.",
- {0x12, 0x34, 0x56, 0x78}},
- };
-
- PacketFragments packet46 = {
- // type (short header, 4 byte packet number)
- {"Unable to read first byte.",
- {0x43}},
- // connection_id
- {"Unable to read destination connection ID.",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // packet number
- {"Unable to read packet number.",
- {0x12, 0x34, 0x56, 0x78}},
- };
-
- PacketFragments packet_hp = {
- // type (short header, 4 byte packet number)
- {"Unable to read first byte.",
- {0x43}},
- // connection_id
- {"Unable to read destination connection ID.",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // packet number
- {"",
- {0x12, 0x34, 0x56, 0x78}},
- };
- // clang-format on
-
- PacketFragments& fragments =
- framer_.version().HasHeaderProtection()
- ? packet_hp
- : (framer_.version().HasIetfInvariantHeader() ? packet46 : packet);
- std::unique_ptr<QuicEncryptedPacket> encrypted(
- AssemblePacketFromFragments(fragments));
- EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
- EXPECT_THAT(framer_.error(), IsError(QUIC_MISSING_PAYLOAD));
- ASSERT_TRUE(visitor_.header_.get());
- EXPECT_EQ(FramerTestConnectionId(),
- visitor_.header_->destination_connection_id);
- EXPECT_FALSE(visitor_.header_->reset_flag);
- EXPECT_FALSE(visitor_.header_->version_flag);
- EXPECT_EQ(kPacketNumber, visitor_.header_->packet_number);
-
- CheckFramingBoundaries(fragments, QUIC_INVALID_PACKET_HEADER);
-}
-
-TEST_P(QuicFramerTest, PacketHeaderWith2BytePacketNumber) {
- SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
- QuicFramerPeer::SetLargestPacketNumber(&framer_, kPacketNumber - 2);
-
- // clang-format off
- PacketFragments packet = {
- // public flags (8 byte connection_id and 2 byte packet number)
- {"Unable to read public flags.",
- {0x18}},
- // connection_id
- {"Unable to read ConnectionId.",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // packet number
- {"Unable to read packet number.",
- {0x56, 0x78}},
- };
-
- PacketFragments packet46 = {
- // type (short header, 2 byte packet number)
- {"Unable to read first byte.",
- {0x41}},
- // connection_id
- {"Unable to read destination connection ID.",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // packet number
- {"Unable to read packet number.",
- {0x56, 0x78}},
- };
-
- PacketFragments packet_hp = {
- // type (short header, 2 byte packet number)
- {"Unable to read first byte.",
- {0x41}},
- // connection_id
- {"Unable to read destination connection ID.",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // packet number
- {"",
- {0x56, 0x78}},
- // padding
- {"", {0x00, 0x00}},
- };
- // clang-format on
-
- PacketFragments& fragments =
- framer_.version().HasHeaderProtection()
- ? packet_hp
- : (framer_.version().HasIetfInvariantHeader() ? packet46 : packet);
- std::unique_ptr<QuicEncryptedPacket> encrypted(
- AssemblePacketFromFragments(fragments));
- if (framer_.version().HasHeaderProtection()) {
- EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
- EXPECT_THAT(framer_.error(), IsQuicNoError());
- } else {
- EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
- EXPECT_THAT(framer_.error(), IsError(QUIC_MISSING_PAYLOAD));
- }
- ASSERT_TRUE(visitor_.header_.get());
- EXPECT_EQ(FramerTestConnectionId(),
- visitor_.header_->destination_connection_id);
- EXPECT_FALSE(visitor_.header_->reset_flag);
- EXPECT_FALSE(visitor_.header_->version_flag);
- EXPECT_EQ(PACKET_2BYTE_PACKET_NUMBER, visitor_.header_->packet_number_length);
- EXPECT_EQ(kPacketNumber, visitor_.header_->packet_number);
-
- CheckFramingBoundaries(fragments, QUIC_INVALID_PACKET_HEADER);
-}
-
-TEST_P(QuicFramerTest, PacketHeaderWith1BytePacketNumber) {
- SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
- QuicFramerPeer::SetLargestPacketNumber(&framer_, kPacketNumber - 2);
-
- // clang-format off
- PacketFragments packet = {
- // public flags (8 byte connection_id and 1 byte packet number)
- {"Unable to read public flags.",
- {0x08}},
- // connection_id
- {"Unable to read ConnectionId.",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // packet number
- {"Unable to read packet number.",
- {0x78}},
- };
-
- PacketFragments packet46 = {
- // type (8 byte connection_id and 1 byte packet number)
- {"Unable to read first byte.",
- {0x40}},
- // connection_id
- {"Unable to read destination connection ID.",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // packet number
- {"Unable to read packet number.",
- {0x78}},
- };
-
- PacketFragments packet_hp = {
- // type (8 byte connection_id and 1 byte packet number)
- {"Unable to read first byte.",
- {0x40}},
- // connection_id
- {"Unable to read destination connection ID.",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // packet number
- {"",
- {0x78}},
- // padding
- {"", {0x00, 0x00, 0x00}},
- };
-
- // clang-format on
-
- PacketFragments& fragments =
- framer_.version().HasHeaderProtection()
- ? packet_hp
- : (framer_.version().HasIetfInvariantHeader() ? packet46 : packet);
- std::unique_ptr<QuicEncryptedPacket> encrypted(
- AssemblePacketFromFragments(fragments));
- if (framer_.version().HasHeaderProtection()) {
- EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
- EXPECT_THAT(framer_.error(), IsQuicNoError());
- } else {
- EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
- EXPECT_THAT(framer_.error(), IsError(QUIC_MISSING_PAYLOAD));
- }
- ASSERT_TRUE(visitor_.header_.get());
- EXPECT_EQ(FramerTestConnectionId(),
- visitor_.header_->destination_connection_id);
- EXPECT_FALSE(visitor_.header_->reset_flag);
- EXPECT_FALSE(visitor_.header_->version_flag);
- EXPECT_EQ(PACKET_1BYTE_PACKET_NUMBER, visitor_.header_->packet_number_length);
- EXPECT_EQ(kPacketNumber, visitor_.header_->packet_number);
-
- CheckFramingBoundaries(fragments, QUIC_INVALID_PACKET_HEADER);
-}
-
-TEST_P(QuicFramerTest, PacketNumberDecreasesThenIncreases) {
- SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
- // Test the case when a packet is received from the past and future packet
- // numbers are still calculated relative to the largest received packet.
- QuicPacketHeader header;
- header.destination_connection_id = FramerTestConnectionId();
- header.reset_flag = false;
- header.version_flag = false;
- header.packet_number = kPacketNumber - 2;
-
- QuicFrames frames = {QuicFrame(QuicPaddingFrame())};
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
- std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
- ASSERT_TRUE(data != nullptr);
-
- QuicEncryptedPacket encrypted(data->data(), data->length(), false);
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
- EXPECT_TRUE(framer_.ProcessPacket(encrypted));
- ASSERT_TRUE(visitor_.header_.get());
- EXPECT_EQ(FramerTestConnectionId(),
- visitor_.header_->destination_connection_id);
- EXPECT_EQ(PACKET_4BYTE_PACKET_NUMBER, visitor_.header_->packet_number_length);
- EXPECT_EQ(kPacketNumber - 2, visitor_.header_->packet_number);
-
- // Receive a 1 byte packet number.
- header.packet_number = kPacketNumber;
- header.packet_number_length = PACKET_1BYTE_PACKET_NUMBER;
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
- data = BuildDataPacket(header, frames);
- QuicEncryptedPacket encrypted1(data->data(), data->length(), false);
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
- EXPECT_TRUE(framer_.ProcessPacket(encrypted1));
- ASSERT_TRUE(visitor_.header_.get());
- EXPECT_EQ(FramerTestConnectionId(),
- visitor_.header_->destination_connection_id);
- EXPECT_EQ(PACKET_1BYTE_PACKET_NUMBER, visitor_.header_->packet_number_length);
- EXPECT_EQ(kPacketNumber, visitor_.header_->packet_number);
-
- // Process a 2 byte packet number 256 packets ago.
- header.packet_number = kPacketNumber - 256;
- header.packet_number_length = PACKET_2BYTE_PACKET_NUMBER;
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
- data = BuildDataPacket(header, frames);
- QuicEncryptedPacket encrypted2(data->data(), data->length(), false);
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
- EXPECT_TRUE(framer_.ProcessPacket(encrypted2));
- ASSERT_TRUE(visitor_.header_.get());
- EXPECT_EQ(FramerTestConnectionId(),
- visitor_.header_->destination_connection_id);
- EXPECT_EQ(PACKET_2BYTE_PACKET_NUMBER, visitor_.header_->packet_number_length);
- EXPECT_EQ(kPacketNumber - 256, visitor_.header_->packet_number);
-
- // Process another 1 byte packet number and ensure it works.
- header.packet_number = kPacketNumber - 1;
- header.packet_number_length = PACKET_1BYTE_PACKET_NUMBER;
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
- data = BuildDataPacket(header, frames);
- QuicEncryptedPacket encrypted3(data->data(), data->length(), false);
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
- EXPECT_TRUE(framer_.ProcessPacket(encrypted3));
- ASSERT_TRUE(visitor_.header_.get());
- EXPECT_EQ(FramerTestConnectionId(),
- visitor_.header_->destination_connection_id);
- EXPECT_EQ(PACKET_1BYTE_PACKET_NUMBER, visitor_.header_->packet_number_length);
- EXPECT_EQ(kPacketNumber - 1, visitor_.header_->packet_number);
-}
-
-TEST_P(QuicFramerTest, PacketWithDiversificationNonce) {
- SetDecrypterLevel(ENCRYPTION_ZERO_RTT);
- // clang-format off
- unsigned char packet[] = {
- // public flags: includes nonce flag
- 0x2C,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // nonce
- 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
- 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
- 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
- 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
-
- // frame type (padding)
- 0x00,
- 0x00, 0x00, 0x00, 0x00
- };
-
- unsigned char packet46[] = {
- // type: Long header with packet type ZERO_RTT_PROTECTED and 1 byte packet
- // number.
- 0xD0,
- // version tag
- QUIC_VERSION_BYTES,
- // connection_id length
- 0x05,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x78,
- // nonce
- 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
- 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
- 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
- 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
-
- // frame type (padding)
- 0x00,
- 0x00, 0x00, 0x00, 0x00
- };
-
- unsigned char packet49[] = {
- // type: Long header with packet type ZERO_RTT_PROTECTED and 1 byte packet
- // number.
- 0xD0,
- // version tag
- QUIC_VERSION_BYTES,
- // destination connection ID length
- 0x00,
- // source connection ID length
- 0x08,
- // source connection ID
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // long header packet length
- 0x26,
- // packet number
- 0x78,
- // nonce
- 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
- 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
- 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
- 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
-
- // frame type (padding)
- 0x00,
- 0x00, 0x00, 0x00, 0x00
- };
- // clang-format on
-
- if (framer_.version().handshake_protocol != PROTOCOL_QUIC_CRYPTO) {
- return;
- }
-
- unsigned char* p = packet;
- size_t p_size = ABSL_ARRAYSIZE(packet);
- if (framer_.version().HasLongHeaderLengths()) {
- p = packet49;
- p_size = ABSL_ARRAYSIZE(packet49);
- } else if (framer_.version().HasIetfInvariantHeader()) {
- p = packet46;
- p_size = ABSL_ARRAYSIZE(packet46);
- }
-
- QuicEncryptedPacket encrypted(AsChars(p), p_size, false);
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
- EXPECT_TRUE(framer_.ProcessPacket(encrypted));
- ASSERT_TRUE(visitor_.header_->nonce != nullptr);
- for (char i = 0; i < 32; ++i) {
- EXPECT_EQ(i, (*visitor_.header_->nonce)[static_cast<size_t>(i)]);
- }
- EXPECT_EQ(1u, visitor_.padding_frames_.size());
- EXPECT_EQ(5, visitor_.padding_frames_[0]->num_padding_bytes);
-}
-
-TEST_P(QuicFramerTest, LargePublicFlagWithMismatchedVersions) {
- // clang-format off
- unsigned char packet[] = {
- // public flags (8 byte connection_id, version flag and an unknown flag)
- 0x29,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // version tag
- 'Q', '0', '0', '0',
- // packet number
- 0x12, 0x34, 0x56, 0x78,
-
- // frame type (padding frame)
- 0x00,
- 0x00, 0x00, 0x00, 0x00
- };
-
- unsigned char packet46[] = {
- // type (long header, ZERO_RTT_PROTECTED, 4-byte packet number)
- 0xD3,
- // version tag
- 'Q', '0', '0', '0',
- // connection_id length
- 0x50,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
-
- // frame type (padding frame)
- 0x00,
- 0x00, 0x00, 0x00, 0x00
- };
-
- unsigned char packet49[] = {
- // type (long header, ZERO_RTT_PROTECTED, 4-byte packet number)
- 0xD3,
- // version tag
- 'Q', '0', '0', '0',
- // destination connection ID length
- 0x08,
- // destination connection ID
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // source connection ID length
- 0x00,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
-
- // frame type (padding frame)
- 0x00,
- 0x00, 0x00, 0x00, 0x00
- };
- // clang-format on
-
- unsigned char* p = packet;
- size_t p_size = ABSL_ARRAYSIZE(packet);
- if (framer_.version().HasLongHeaderLengths()) {
- p = packet49;
- p_size = ABSL_ARRAYSIZE(packet49);
- } else if (framer_.version().HasIetfInvariantHeader()) {
- p = packet46;
- p_size = ABSL_ARRAYSIZE(packet46);
- }
- QuicEncryptedPacket encrypted(AsChars(p), p_size, false);
- EXPECT_TRUE(framer_.ProcessPacket(encrypted));
- EXPECT_THAT(framer_.error(), IsQuicNoError());
- ASSERT_TRUE(visitor_.header_.get());
- EXPECT_EQ(0, visitor_.frame_count_);
- EXPECT_EQ(1, visitor_.version_mismatch_);
-}
-
-TEST_P(QuicFramerTest, PaddingFrame) {
- SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
- // clang-format off
- unsigned char packet[] = {
- // public flags (8 byte connection_id)
- 0x28,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
-
- // paddings
- 0x00, 0x00,
- // frame type (stream frame with fin)
- 0xFF,
- // stream id
- 0x01, 0x02, 0x03, 0x04,
- // offset
- 0x3A, 0x98, 0xFE, 0xDC,
- 0x32, 0x10, 0x76, 0x54,
- // data length
- 0x00, 0x0c,
- // data
- 'h', 'e', 'l', 'l',
- 'o', ' ', 'w', 'o',
- 'r', 'l', 'd', '!',
- // paddings
- 0x00, 0x00,
- };
-
- unsigned char packet46[] = {
- // type (short header, 4 byte packet number)
- 0x43,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
-
- // paddings
- 0x00, 0x00,
- // frame type (stream frame with fin)
- 0xFF,
- // stream id
- 0x01, 0x02, 0x03, 0x04,
- // offset
- 0x3A, 0x98, 0xFE, 0xDC,
- 0x32, 0x10, 0x76, 0x54,
- // data length
- 0x00, 0x0c,
- // data
- 'h', 'e', 'l', 'l',
- 'o', ' ', 'w', 'o',
- 'r', 'l', 'd', '!',
- // paddings
- 0x00, 0x00,
- };
-
- unsigned char packet_ietf[] = {
- // type (short header, 4 byte packet number)
- 0x43,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
-
- // paddings
- 0x00, 0x00,
- // frame type - IETF_STREAM with FIN, LEN, and OFFSET bits set.
- 0x08 | 0x01 | 0x02 | 0x04,
-
- // stream id
- kVarInt62FourBytes + 0x01, 0x02, 0x03, 0x04,
- // offset
- kVarInt62EightBytes + 0x3A, 0x98, 0xFE, 0xDC,
- 0x32, 0x10, 0x76, 0x54,
- // data length
- kVarInt62OneByte + 0x0c,
- // data
- 'h', 'e', 'l', 'l',
- 'o', ' ', 'w', 'o',
- 'r', 'l', 'd', '!',
- // paddings
- 0x00, 0x00,
- };
- // clang-format on
-
- unsigned char* p = packet;
- size_t p_size = ABSL_ARRAYSIZE(packet);
- if (VersionHasIetfQuicFrames(framer_.transport_version())) {
- p = packet_ietf;
- p_size = ABSL_ARRAYSIZE(packet_ietf);
- } else if (framer_.version().HasIetfInvariantHeader()) {
- p = packet46;
- p_size = ABSL_ARRAYSIZE(packet46);
- }
-
- QuicEncryptedPacket encrypted(AsChars(p), p_size, false);
- EXPECT_TRUE(framer_.ProcessPacket(encrypted));
- EXPECT_THAT(framer_.error(), IsQuicNoError());
- ASSERT_TRUE(visitor_.header_.get());
- EXPECT_TRUE(CheckDecryption(
- encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
- PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
-
- ASSERT_EQ(1u, visitor_.stream_frames_.size());
- EXPECT_EQ(0u, visitor_.ack_frames_.size());
- EXPECT_EQ(2u, visitor_.padding_frames_.size());
- EXPECT_EQ(2, visitor_.padding_frames_[0]->num_padding_bytes);
- EXPECT_EQ(2, visitor_.padding_frames_[1]->num_padding_bytes);
- EXPECT_EQ(kStreamId, visitor_.stream_frames_[0]->stream_id);
- EXPECT_TRUE(visitor_.stream_frames_[0]->fin);
- EXPECT_EQ(kStreamOffset, visitor_.stream_frames_[0]->offset);
- CheckStreamFrameData("hello world!", visitor_.stream_frames_[0].get());
-}
-
-TEST_P(QuicFramerTest, StreamFrame) {
- SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
- // clang-format off
- PacketFragments packet = {
- // public flags (8 byte connection_id)
- {"",
- {0x28}},
- // connection_id
- {"",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // packet number
- {"",
- {0x12, 0x34, 0x56, 0x78}},
- // frame type (stream frame with fin)
- {"",
- {0xFF}},
- // stream id
- {"Unable to read stream_id.",
- {0x01, 0x02, 0x03, 0x04}},
- // offset
- {"Unable to read offset.",
- {0x3A, 0x98, 0xFE, 0xDC,
- 0x32, 0x10, 0x76, 0x54}},
- {"Unable to read frame data.",
- {
- // data length
- 0x00, 0x0c,
- // data
- 'h', 'e', 'l', 'l',
- 'o', ' ', 'w', 'o',
- 'r', 'l', 'd', '!'}},
- };
-
- PacketFragments packet46 = {
- // type (short header, 4 byte packet number)
- {"",
- {0x43}},
- // connection_id
- {"",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // packet number
- {"",
- {0x12, 0x34, 0x56, 0x78}},
- // frame type (stream frame with fin)
- {"",
- {0xFF}},
- // stream id
- {"Unable to read stream_id.",
- {0x01, 0x02, 0x03, 0x04}},
- // offset
- {"Unable to read offset.",
- {0x3A, 0x98, 0xFE, 0xDC,
- 0x32, 0x10, 0x76, 0x54}},
- {"Unable to read frame data.",
- {
- // data length
- 0x00, 0x0c,
- // data
- 'h', 'e', 'l', 'l',
- 'o', ' ', 'w', 'o',
- 'r', 'l', 'd', '!'}},
- };
-
- PacketFragments packet_ietf = {
- // type (short header, 4 byte packet number)
- {"",
- {0x43}},
- // connection_id
- {"",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // packet number
- {"",
- {0x12, 0x34, 0x56, 0x78}},
- // frame type - IETF_STREAM with FIN, LEN, and OFFSET bits set.
- {"",
- { 0x08 | 0x01 | 0x02 | 0x04 }},
- // stream id
- {"Unable to read IETF_STREAM frame stream id/count.",
- {kVarInt62FourBytes + 0x01, 0x02, 0x03, 0x04}},
- // offset
- {"Unable to read stream data offset.",
- {kVarInt62EightBytes + 0x3A, 0x98, 0xFE, 0xDC,
- 0x32, 0x10, 0x76, 0x54}},
- // data length
- {"Unable to read stream data length.",
- {kVarInt62OneByte + 0x0c}},
- // data
- {"Unable to read frame data.",
- { 'h', 'e', 'l', 'l',
- 'o', ' ', 'w', 'o',
- 'r', 'l', 'd', '!'}},
- };
- // clang-format on
-
- PacketFragments& fragments =
- VersionHasIetfQuicFrames(framer_.transport_version())
- ? packet_ietf
- : (framer_.version().HasIetfInvariantHeader() ? packet46 : packet);
- std::unique_ptr<QuicEncryptedPacket> encrypted(
- AssemblePacketFromFragments(fragments));
- EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
-
- EXPECT_THAT(framer_.error(), IsQuicNoError());
- ASSERT_TRUE(visitor_.header_.get());
- EXPECT_TRUE(CheckDecryption(
- *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
- PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
-
- ASSERT_EQ(1u, visitor_.stream_frames_.size());
- EXPECT_EQ(0u, visitor_.ack_frames_.size());
- EXPECT_EQ(kStreamId, visitor_.stream_frames_[0]->stream_id);
- EXPECT_TRUE(visitor_.stream_frames_[0]->fin);
- EXPECT_EQ(kStreamOffset, visitor_.stream_frames_[0]->offset);
- CheckStreamFrameData("hello world!", visitor_.stream_frames_[0].get());
-
- CheckFramingBoundaries(fragments, QUIC_INVALID_STREAM_DATA);
-}
-
-// Test an empty (no data) stream frame.
-TEST_P(QuicFramerTest, EmptyStreamFrame) {
- // Only the IETF QUIC spec explicitly says that empty
- // stream frames are supported.
- if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
- return;
- }
- SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
- // clang-format off
- PacketFragments packet = {
- // type (short header, 4 byte packet number)
- {"",
- {0x43}},
- // connection_id
- {"",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // packet number
- {"",
- {0x12, 0x34, 0x56, 0x78}},
- // frame type - IETF_STREAM with FIN, LEN, and OFFSET bits set.
- {"",
- { 0x08 | 0x01 | 0x02 | 0x04 }},
- // stream id
- {"Unable to read IETF_STREAM frame stream id/count.",
- {kVarInt62FourBytes + 0x01, 0x02, 0x03, 0x04}},
- // offset
- {"Unable to read stream data offset.",
- {kVarInt62EightBytes + 0x3A, 0x98, 0xFE, 0xDC,
- 0x32, 0x10, 0x76, 0x54}},
- // data length
- {"Unable to read stream data length.",
- {kVarInt62OneByte + 0x00}},
- };
- // clang-format on
-
- std::unique_ptr<QuicEncryptedPacket> encrypted(
- AssemblePacketFromFragments(packet));
- EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
-
- EXPECT_THAT(framer_.error(), IsQuicNoError());
- ASSERT_TRUE(visitor_.header_.get());
- EXPECT_TRUE(CheckDecryption(
- *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
- PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
-
- ASSERT_EQ(1u, visitor_.stream_frames_.size());
- EXPECT_EQ(0u, visitor_.ack_frames_.size());
- EXPECT_EQ(kStreamId, visitor_.stream_frames_[0]->stream_id);
- EXPECT_TRUE(visitor_.stream_frames_[0]->fin);
- EXPECT_EQ(kStreamOffset, visitor_.stream_frames_[0]->offset);
- EXPECT_EQ(visitor_.stream_frames_[0].get()->data_length, 0u);
-
- CheckFramingBoundaries(packet, QUIC_INVALID_STREAM_DATA);
-}
-
-TEST_P(QuicFramerTest, MissingDiversificationNonce) {
- if (framer_.version().handshake_protocol != PROTOCOL_QUIC_CRYPTO) {
- // TLS does not use diversification nonces.
- return;
- }
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
- decrypter_ = new test::TestDecrypter();
- if (framer_.version().KnowsWhichDecrypterToUse()) {
- framer_.InstallDecrypter(
- ENCRYPTION_INITIAL,
- std::make_unique<NullDecrypter>(Perspective::IS_CLIENT));
- framer_.InstallDecrypter(ENCRYPTION_ZERO_RTT,
- std::unique_ptr<QuicDecrypter>(decrypter_));
- } else {
- framer_.SetDecrypter(ENCRYPTION_INITIAL, std::make_unique<NullDecrypter>(
- Perspective::IS_CLIENT));
- framer_.SetAlternativeDecrypter(
- ENCRYPTION_ZERO_RTT, std::unique_ptr<QuicDecrypter>(decrypter_), false);
- }
-
- // clang-format off
- unsigned char packet[] = {
- // public flags (8 byte connection_id)
- 0x28,
- // connection_id
- 0x10, 0x32, 0x54, 0x76, 0x98, 0xBA, 0xDC, 0xFE,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
- // padding frame
- 0x00,
- };
-
- unsigned char packet46[] = {
- // type (long header, ZERO_RTT_PROTECTED, 4-byte packet number)
- 0xD3,
- // version tag
- QUIC_VERSION_BYTES,
- // connection_id length
- 0x05,
- // connection_id
- 0x10, 0x32, 0x54, 0x76, 0x98, 0xBA, 0xDC, 0xFE,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
- // padding frame
- 0x00,
- };
-
- unsigned char packet49[] = {
- // type (long header, ZERO_RTT_PROTECTED, 4-byte packet number)
- 0xD3,
- // version tag
- QUIC_VERSION_BYTES,
- // destination connection ID length
- 0x00,
- // source connection ID length
- 0x08,
- // source connection ID
- 0x10, 0x32, 0x54, 0x76, 0x98, 0xBA, 0xDC, 0xFE,
- // IETF long header payload length
- 0x05,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
- // padding frame
- 0x00,
- };
- // clang-format on
-
- unsigned char* p = packet;
- size_t p_length = ABSL_ARRAYSIZE(packet);
- if (framer_.version().HasLongHeaderLengths()) {
- p = packet49;
- p_length = ABSL_ARRAYSIZE(packet49);
- } else if (framer_.version().HasIetfInvariantHeader()) {
- p = packet46;
- p_length = ABSL_ARRAYSIZE(packet46);
- }
- QuicEncryptedPacket encrypted(AsChars(p), p_length, false);
- EXPECT_FALSE(framer_.ProcessPacket(encrypted));
- if (framer_.version().HasHeaderProtection()) {
- EXPECT_THAT(framer_.error(), IsError(QUIC_DECRYPTION_FAILURE));
- EXPECT_EQ("Unable to decrypt ENCRYPTION_ZERO_RTT header protection.",
- framer_.detailed_error());
- } else if (framer_.version().HasIetfInvariantHeader()) {
- // Cannot read diversification nonce.
- EXPECT_THAT(framer_.error(), IsError(QUIC_INVALID_PACKET_HEADER));
- EXPECT_EQ("Unable to read nonce.", framer_.detailed_error());
- } else {
- EXPECT_THAT(framer_.error(), IsError(QUIC_DECRYPTION_FAILURE));
- }
-}
-
-TEST_P(QuicFramerTest, StreamFrame3ByteStreamId) {
- if (framer_.version().HasIetfInvariantHeader()) {
- // This test is nonsensical for IETF Quic.
- return;
- }
- // clang-format off
- PacketFragments packet = {
- // public flags (8 byte connection_id)
- {"",
- {0x28}},
- // connection_id
- {"",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // packet number
- {"",
- {0x12, 0x34, 0x56, 0x78}},
- // frame type (stream frame with fin)
- {"",
- {0xFE}},
- // stream id
- {"Unable to read stream_id.",
- {0x02, 0x03, 0x04}},
- // offset
- {"Unable to read offset.",
- {0x3A, 0x98, 0xFE, 0xDC,
- 0x32, 0x10, 0x76, 0x54}},
- {"Unable to read frame data.",
- {
- // data length
- 0x00, 0x0c,
- // data
- 'h', 'e', 'l', 'l',
- 'o', ' ', 'w', 'o',
- 'r', 'l', 'd', '!'}},
- };
- // clang-format on
-
- PacketFragments& fragments = packet;
- std::unique_ptr<QuicEncryptedPacket> encrypted(
- AssemblePacketFromFragments(fragments));
- EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
-
- EXPECT_THAT(framer_.error(), IsQuicNoError());
- ASSERT_TRUE(visitor_.header_.get());
- EXPECT_TRUE(CheckDecryption(
- *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
- PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
-
- ASSERT_EQ(1u, visitor_.stream_frames_.size());
- EXPECT_EQ(0u, visitor_.ack_frames_.size());
- // Stream ID should be the last 3 bytes of kStreamId.
- EXPECT_EQ(0x00FFFFFF & kStreamId, visitor_.stream_frames_[0]->stream_id);
- EXPECT_TRUE(visitor_.stream_frames_[0]->fin);
- EXPECT_EQ(kStreamOffset, visitor_.stream_frames_[0]->offset);
- CheckStreamFrameData("hello world!", visitor_.stream_frames_[0].get());
-
- CheckFramingBoundaries(fragments, QUIC_INVALID_STREAM_DATA);
-}
-
-TEST_P(QuicFramerTest, StreamFrame2ByteStreamId) {
- SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
- // clang-format off
- PacketFragments packet = {
- // public flags (8 byte connection_id)
- {"",
- {0x28}},
- // connection_id
- {"",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // packet number
- {"",
- {0x12, 0x34, 0x56, 0x78}},
- // frame type (stream frame with fin)
- {"",
- {0xFD}},
- // stream id
- {"Unable to read stream_id.",
- {0x03, 0x04}},
- // offset
- {"Unable to read offset.",
- {0x3A, 0x98, 0xFE, 0xDC,
- 0x32, 0x10, 0x76, 0x54}},
- {"Unable to read frame data.",
- {
- // data length
- 0x00, 0x0c,
- // data
- 'h', 'e', 'l', 'l',
- 'o', ' ', 'w', 'o',
- 'r', 'l', 'd', '!'}},
- };
-
- PacketFragments packet46 = {
- // type (short header, 4 byte packet number)
- {"",
- {0x43}},
- // connection_id
- {"",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // packet number
- {"",
- {0x12, 0x34, 0x56, 0x78}},
- // frame type (stream frame with fin)
- {"",
- {0xFD}},
- // stream id
- {"Unable to read stream_id.",
- {0x03, 0x04}},
- // offset
- {"Unable to read offset.",
- {0x3A, 0x98, 0xFE, 0xDC,
- 0x32, 0x10, 0x76, 0x54}},
- {"Unable to read frame data.",
- {
- // data length
- 0x00, 0x0c,
- // data
- 'h', 'e', 'l', 'l',
- 'o', ' ', 'w', 'o',
- 'r', 'l', 'd', '!'}},
- };
-
- PacketFragments packet_ietf = {
- // type (short header, 4 byte packet number)
- {"",
- {0x43}},
- // connection_id
- {"",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // packet number
- {"",
- {0x12, 0x34, 0x56, 0x78}},
- // frame type (IETF_STREAM frame with LEN, FIN, and OFFSET bits set)
- {"",
- {0x08 | 0x01 | 0x02 | 0x04}},
- // stream id
- {"Unable to read IETF_STREAM frame stream id/count.",
- {kVarInt62TwoBytes + 0x03, 0x04}},
- // offset
- {"Unable to read stream data offset.",
- {kVarInt62EightBytes + 0x3A, 0x98, 0xFE, 0xDC,
- 0x32, 0x10, 0x76, 0x54}},
- // data length
- {"Unable to read stream data length.",
- {kVarInt62OneByte + 0x0c}},
- // data
- {"Unable to read frame data.",
- { 'h', 'e', 'l', 'l',
- 'o', ' ', 'w', 'o',
- 'r', 'l', 'd', '!'}},
- };
- // clang-format on
-
- PacketFragments& fragments =
- VersionHasIetfQuicFrames(framer_.transport_version())
- ? packet_ietf
- : (framer_.version().HasIetfInvariantHeader() ? packet46 : packet);
- std::unique_ptr<QuicEncryptedPacket> encrypted(
- AssemblePacketFromFragments(fragments));
- EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
-
- EXPECT_THAT(framer_.error(), IsQuicNoError());
- ASSERT_TRUE(visitor_.header_.get());
- EXPECT_TRUE(CheckDecryption(
- *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
- PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
-
- ASSERT_EQ(1u, visitor_.stream_frames_.size());
- EXPECT_EQ(0u, visitor_.ack_frames_.size());
- // Stream ID should be the last 2 bytes of kStreamId.
- EXPECT_EQ(0x0000FFFF & kStreamId, visitor_.stream_frames_[0]->stream_id);
- EXPECT_TRUE(visitor_.stream_frames_[0]->fin);
- EXPECT_EQ(kStreamOffset, visitor_.stream_frames_[0]->offset);
- CheckStreamFrameData("hello world!", visitor_.stream_frames_[0].get());
-
- CheckFramingBoundaries(fragments, QUIC_INVALID_STREAM_DATA);
-}
-
-TEST_P(QuicFramerTest, StreamFrame1ByteStreamId) {
- SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
- // clang-format off
- PacketFragments packet = {
- // public flags (8 byte connection_id)
- {"",
- {0x28}},
- // connection_id
- {"",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // packet number
- {"",
- {0x12, 0x34, 0x56, 0x78}},
- // frame type (stream frame with fin)
- {"",
- {0xFC}},
- // stream id
- {"Unable to read stream_id.",
- {0x04}},
- // offset
- {"Unable to read offset.",
- {0x3A, 0x98, 0xFE, 0xDC,
- 0x32, 0x10, 0x76, 0x54}},
- {"Unable to read frame data.",
- {
- // data length
- 0x00, 0x0c,
- // data
- 'h', 'e', 'l', 'l',
- 'o', ' ', 'w', 'o',
- 'r', 'l', 'd', '!'}},
- };
-
- PacketFragments packet46 = {
- // type (short header, 4 byte packet number)
- {"",
- {0x43}},
- // connection_id
- {"",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // packet number
- {"",
- {0x12, 0x34, 0x56, 0x78}},
- // frame type (stream frame with fin)
- {"",
- {0xFC}},
- // stream id
- {"Unable to read stream_id.",
- {0x04}},
- // offset
- {"Unable to read offset.",
- {0x3A, 0x98, 0xFE, 0xDC,
- 0x32, 0x10, 0x76, 0x54}},
- {"Unable to read frame data.",
- {
- // data length
- 0x00, 0x0c,
- // data
- 'h', 'e', 'l', 'l',
- 'o', ' ', 'w', 'o',
- 'r', 'l', 'd', '!'}},
- };
-
- PacketFragments packet_ietf = {
- // type (short header, 4 byte packet number)
- {"",
- {0x43}},
- // connection_id
- {"",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // packet number
- {"",
- {0x12, 0x34, 0x56, 0x78}},
- // frame type (IETF_STREAM frame with LEN, FIN, and OFFSET bits set)
- {"",
- {0x08 | 0x01 | 0x02 | 0x04}},
- // stream id
- {"Unable to read IETF_STREAM frame stream id/count.",
- {kVarInt62OneByte + 0x04}},
- // offset
- {"Unable to read stream data offset.",
- {kVarInt62EightBytes + 0x3A, 0x98, 0xFE, 0xDC,
- 0x32, 0x10, 0x76, 0x54}},
- // data length
- {"Unable to read stream data length.",
- {kVarInt62OneByte + 0x0c}},
- // data
- {"Unable to read frame data.",
- { 'h', 'e', 'l', 'l',
- 'o', ' ', 'w', 'o',
- 'r', 'l', 'd', '!'}},
- };
- // clang-format on
-
- PacketFragments& fragments =
- VersionHasIetfQuicFrames(framer_.transport_version())
- ? packet_ietf
- : (framer_.version().HasIetfInvariantHeader() ? packet46 : packet);
- std::unique_ptr<QuicEncryptedPacket> encrypted(
- AssemblePacketFromFragments(fragments));
- EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
-
- EXPECT_THAT(framer_.error(), IsQuicNoError());
- ASSERT_TRUE(visitor_.header_.get());
- EXPECT_TRUE(CheckDecryption(
- *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
- PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
-
- ASSERT_EQ(1u, visitor_.stream_frames_.size());
- EXPECT_EQ(0u, visitor_.ack_frames_.size());
- // Stream ID should be the last 1 byte of kStreamId.
- EXPECT_EQ(0x000000FF & kStreamId, visitor_.stream_frames_[0]->stream_id);
- EXPECT_TRUE(visitor_.stream_frames_[0]->fin);
- EXPECT_EQ(kStreamOffset, visitor_.stream_frames_[0]->offset);
- CheckStreamFrameData("hello world!", visitor_.stream_frames_[0].get());
-
- CheckFramingBoundaries(fragments, QUIC_INVALID_STREAM_DATA);
-}
-
-TEST_P(QuicFramerTest, StreamFrameWithVersion) {
- // If IETF frames are in use then we must also have the IETF
- // header invariants.
- if (VersionHasIetfQuicFrames(framer_.transport_version())) {
- QUICHE_DCHECK(framer_.version().HasIetfInvariantHeader());
- }
-
- SetDecrypterLevel(ENCRYPTION_ZERO_RTT);
- // clang-format off
- PacketFragments packet = {
- // public flags (version, 8 byte connection_id)
- {"",
- {0x29}},
- // connection_id
- {"",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // version tag
- {"",
- {QUIC_VERSION_BYTES}},
- // packet number
- {"",
- {0x12, 0x34, 0x56, 0x78}},
- // frame type (stream frame with fin)
- {"",
- {0xFE}},
- // stream id
- {"Unable to read stream_id.",
- {0x02, 0x03, 0x04}},
- // offset
- {"Unable to read offset.",
- {0x3A, 0x98, 0xFE, 0xDC,
- 0x32, 0x10, 0x76, 0x54}},
- {"Unable to read frame data.",
- {
- // data length
- 0x00, 0x0c,
- // data
- 'h', 'e', 'l', 'l',
- 'o', ' ', 'w', 'o',
- 'r', 'l', 'd', '!'}},
- };
-
- PacketFragments packet46 = {
- // public flags (long header with packet type ZERO_RTT_PROTECTED and
- // 4-byte packet number)
- {"",
- {0xD3}},
- // version tag
- {"",
- {QUIC_VERSION_BYTES}},
- // connection_id length
- {"",
- {0x50}},
- // connection_id
- {"",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // packet number
- {"",
- {0x12, 0x34, 0x56, 0x78}},
- // frame type (stream frame with fin)
- {"",
- {0xFE}},
- // stream id
- {"Unable to read stream_id.",
- {0x02, 0x03, 0x04}},
- // offset
- {"Unable to read offset.",
- {0x3A, 0x98, 0xFE, 0xDC,
- 0x32, 0x10, 0x76, 0x54}},
- {"Unable to read frame data.",
- {
- // data length
- 0x00, 0x0c,
- // data
- 'h', 'e', 'l', 'l',
- 'o', ' ', 'w', 'o',
- 'r', 'l', 'd', '!'}},
- };
-
- PacketFragments packet49 = {
- // public flags (long header with packet type ZERO_RTT_PROTECTED and
- // 4-byte packet number)
- {"",
- {0xD3}},
- // version tag
- {"",
- {QUIC_VERSION_BYTES}},
- // destination connection ID length
- {"",
- {0x08}},
- // destination connection ID
- {"",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // source connection ID length
- {"",
- {0x00}},
- // long header packet length
- {"",
- {0x1E}},
- // packet number
- {"",
- {0x12, 0x34, 0x56, 0x78}},
- // frame type (stream frame with fin)
- {"",
- {0xFE}},
- // stream id
- {"Long header payload length longer than packet.",
- {0x02, 0x03, 0x04}},
- // offset
- {"Long header payload length longer than packet.",
- {0x3A, 0x98, 0xFE, 0xDC,
- 0x32, 0x10, 0x76, 0x54}},
- {"Long header payload length longer than packet.",
- {
- // data length
- 0x00, 0x0c,
- // data
- 'h', 'e', 'l', 'l',
- 'o', ' ', 'w', 'o',
- 'r', 'l', 'd', '!'}},
- };
-
- PacketFragments packet_ietf = {
- // public flags (long header with packet type ZERO_RTT_PROTECTED and
- // 4-byte packet number)
- {"",
- {0xD3}},
- // version tag
- {"",
- {QUIC_VERSION_BYTES}},
- // destination connection ID length
- {"",
- {0x08}},
- // destination connection ID
- {"",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // source connection ID length
- {"",
- {0x00}},
- // long header packet length
- {"",
- {0x1E}},
- // packet number
- {"",
- {0x12, 0x34, 0x56, 0x78}},
- // frame type (IETF_STREAM frame with FIN, LEN, and OFFSET bits set)
- {"",
- {0x08 | 0x01 | 0x02 | 0x04}},
- // stream id
- {"Long header payload length longer than packet.",
- {kVarInt62FourBytes + 0x00, 0x02, 0x03, 0x04}},
- // offset
- {"Long header payload length longer than packet.",
- {kVarInt62EightBytes + 0x3A, 0x98, 0xFE, 0xDC,
- 0x32, 0x10, 0x76, 0x54}},
- // data length
- {"Long header payload length longer than packet.",
- {kVarInt62OneByte + 0x0c}},
- // data
- {"Long header payload length longer than packet.",
- { 'h', 'e', 'l', 'l',
- 'o', ' ', 'w', 'o',
- 'r', 'l', 'd', '!'}},
- };
- // clang-format on
-
- QuicVariableLengthIntegerLength retry_token_length_length =
- VARIABLE_LENGTH_INTEGER_LENGTH_0;
- size_t retry_token_length = 0;
- QuicVariableLengthIntegerLength length_length =
- QuicVersionHasLongHeaderLengths(framer_.transport_version())
- ? VARIABLE_LENGTH_INTEGER_LENGTH_1
- : VARIABLE_LENGTH_INTEGER_LENGTH_0;
-
- ReviseFirstByteByVersion(packet_ietf);
- PacketFragments& fragments =
- VersionHasIetfQuicFrames(framer_.transport_version())
- ? packet_ietf
- : (framer_.version().HasLongHeaderLengths()
- ? packet49
- : (framer_.version().HasIetfInvariantHeader() ? packet46
- : packet));
- std::unique_ptr<QuicEncryptedPacket> encrypted(
- AssemblePacketFromFragments(fragments));
- EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
-
- EXPECT_THAT(framer_.error(), IsQuicNoError());
- ASSERT_TRUE(visitor_.header_.get());
- EXPECT_TRUE(CheckDecryption(
- *encrypted, kIncludeVersion, !kIncludeDiversificationNonce,
- PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID,
- retry_token_length_length, retry_token_length, length_length));
-
- ASSERT_EQ(1u, visitor_.stream_frames_.size());
- EXPECT_EQ(0u, visitor_.ack_frames_.size());
- // Stream ID should be the last 3 bytes of kStreamId.
- EXPECT_EQ(0x00FFFFFF & kStreamId, visitor_.stream_frames_[0]->stream_id);
- EXPECT_TRUE(visitor_.stream_frames_[0]->fin);
- EXPECT_EQ(kStreamOffset, visitor_.stream_frames_[0]->offset);
- CheckStreamFrameData("hello world!", visitor_.stream_frames_[0].get());
-
- CheckFramingBoundaries(fragments, framer_.version().HasLongHeaderLengths()
- ? QUIC_INVALID_PACKET_HEADER
- : QUIC_INVALID_STREAM_DATA);
-}
-
-TEST_P(QuicFramerTest, RejectPacket) {
- SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
- visitor_.accept_packet_ = false;
-
- // clang-format off
- unsigned char packet[] = {
- // public flags (8 byte connection_id)
- 0x28,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
-
- // frame type (stream frame with fin)
- 0xFF,
- // stream id
- 0x01, 0x02, 0x03, 0x04,
- // offset
- 0x3A, 0x98, 0xFE, 0xDC,
- 0x32, 0x10, 0x76, 0x54,
- // data length
- 0x00, 0x0c,
- // data
- 'h', 'e', 'l', 'l',
- 'o', ' ', 'w', 'o',
- 'r', 'l', 'd', '!',
- };
-
- unsigned char packet46[] = {
- // type (short header, 4 byte packet number)
- 0x43,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
-
- // frame type (STREAM Frame with FIN, LEN, and OFFSET bits set)
- 0x10 | 0x01 | 0x02 | 0x04,
- // stream id
- kVarInt62FourBytes + 0x01, 0x02, 0x03, 0x04,
- // offset
- kVarInt62EightBytes + 0x3A, 0x98, 0xFE, 0xDC,
- 0x32, 0x10, 0x76, 0x54,
- // data length
- kVarInt62OneByte + 0x0c,
- // data
- 'h', 'e', 'l', 'l',
- 'o', ' ', 'w', 'o',
- 'r', 'l', 'd', '!',
- };
- // clang-format on
-
- unsigned char* p = packet;
- if (framer_.version().HasIetfInvariantHeader()) {
- p = packet46;
- }
- QuicEncryptedPacket encrypted(AsChars(p),
- framer_.version().HasIetfInvariantHeader()
- ? ABSL_ARRAYSIZE(packet46)
- : ABSL_ARRAYSIZE(packet),
- false);
- EXPECT_TRUE(framer_.ProcessPacket(encrypted));
-
- EXPECT_THAT(framer_.error(), IsQuicNoError());
- ASSERT_TRUE(visitor_.header_.get());
- EXPECT_TRUE(CheckDecryption(
- encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
- PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
-
- ASSERT_EQ(0u, visitor_.stream_frames_.size());
- EXPECT_EQ(0u, visitor_.ack_frames_.size());
-}
-
-TEST_P(QuicFramerTest, RejectPublicHeader) {
- visitor_.accept_public_header_ = false;
-
- // clang-format off
- unsigned char packet[] = {
- // public flags (8 byte connection_id)
- 0x28,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- };
-
- unsigned char packet46[] = {
- // type (short header, 1 byte packet number)
- 0x40,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x01,
- };
- // clang-format on
-
- QuicEncryptedPacket encrypted(
- framer_.version().HasIetfInvariantHeader() ? AsChars(packet46)
- : AsChars(packet),
- framer_.version().HasIetfInvariantHeader() ? ABSL_ARRAYSIZE(packet46)
- : ABSL_ARRAYSIZE(packet),
- false);
- EXPECT_TRUE(framer_.ProcessPacket(encrypted));
-
- EXPECT_THAT(framer_.error(), IsQuicNoError());
- ASSERT_TRUE(visitor_.header_.get());
- EXPECT_FALSE(visitor_.header_->packet_number.IsInitialized());
-}
-
-TEST_P(QuicFramerTest, AckFrameOneAckBlock) {
- SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
- // clang-format off
- PacketFragments packet = {
- // public flags (8 byte connection_id)
- {"",
- {0x2C}},
- // connection_id
- {"",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // packet number
- {"",
- {0x12, 0x34, 0x56, 0x78}},
- // frame type (ack frame)
- // (one ack block, 2 byte largest observed, 2 byte block length)
- {"",
- {0x45}},
- // largest acked
- {"Unable to read largest acked.",
- {0x12, 0x34}},
- // Zero delta time.
- {"Unable to read ack delay time.",
- {0x00, 0x00}},
- // first ack block length.
- {"Unable to read first ack block length.",
- {0x12, 0x34}},
- // num timestamps.
- {"Unable to read num received packets.",
- {0x00}}
- };
-
- PacketFragments packet46 = {
- // type (short packet, 4 byte packet number)
- {"",
- {0x43}},
- // connection_id
- {"",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // packet number
- {"",
- {0x12, 0x34, 0x56, 0x78}},
- // frame type (ack frame)
- // (one ack block, 2 byte largest observed, 2 byte block length)
- {"",
- {0x45}},
- // largest acked
- {"Unable to read largest acked.",
- {0x12, 0x34}},
- // Zero delta time.
- {"Unable to read ack delay time.",
- {0x00, 0x00}},
- // first ack block length.
- {"Unable to read first ack block length.",
- {0x12, 0x34}},
- // num timestamps.
- {"Unable to read num received packets.",
- {0x00}}
- };
-
- PacketFragments packet_ietf = {
- // type (short packet, 4 byte packet number)
- {"",
- {0x43}},
- // connection_id
- {"",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // packet number
- {"",
- {0x12, 0x34, 0x56, 0x78}},
- // frame type (IETF_ACK)
- // (one ack block, 2 byte largest observed, 2 byte block length)
- // IETF-Quic ignores the bit-fields in the ack type, all of
- // that information is encoded elsewhere in the frame.
- {"",
- {0x02}},
- // largest acked
- {"Unable to read largest acked.",
- {kVarInt62TwoBytes + 0x12, 0x34}},
- // Zero delta time.
- {"Unable to read ack delay time.",
- {kVarInt62OneByte + 0x00}},
- // Ack block count (0 -- no blocks after the first)
- {"Unable to read ack block count.",
- {kVarInt62OneByte + 0x00}},
- // first ack block length - 1.
- // IETF Quic defines the ack block's value as the "number of
- // packets that preceed the largest packet number in the block"
- // which for the 1st ack block is the largest acked field,
- // above. This means that if we are acking just packet 0x1234
- // then the 1st ack block will be 0.
- {"Unable to read first ack block length.",
- {kVarInt62TwoBytes + 0x12, 0x33}}
- };
- // clang-format on
-
- PacketFragments& fragments =
- VersionHasIetfQuicFrames(framer_.transport_version())
- ? packet_ietf
- : (framer_.version().HasIetfInvariantHeader() ? packet46 : packet);
- std::unique_ptr<QuicEncryptedPacket> encrypted(
- AssemblePacketFromFragments(fragments));
- EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
-
- EXPECT_THAT(framer_.error(), IsQuicNoError());
- ASSERT_TRUE(visitor_.header_.get());
- EXPECT_TRUE(CheckDecryption(
- *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
- PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
-
- EXPECT_EQ(0u, visitor_.stream_frames_.size());
- ASSERT_EQ(1u, visitor_.ack_frames_.size());
- const QuicAckFrame& frame = *visitor_.ack_frames_[0];
- EXPECT_EQ(kSmallLargestObserved, LargestAcked(frame));
- ASSERT_EQ(4660u, frame.packets.NumPacketsSlow());
-
- CheckFramingBoundaries(fragments, QUIC_INVALID_ACK_DATA);
-}
-
-// This test checks that the ack frame processor correctly identifies
-// and handles the case where the first ack block is larger than the
-// largest_acked packet.
-TEST_P(QuicFramerTest, FirstAckFrameUnderflow) {
- SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
- // clang-format off
- PacketFragments packet = {
- // public flags (8 byte connection_id)
- {"",
- {0x2C}},
- // connection_id
- {"",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // packet number
- {"",
- {0x12, 0x34, 0x56, 0x78}},
- // frame type (ack frame)
- // (one ack block, 2 byte largest observed, 2 byte block length)
- {"",
- {0x45}},
- // largest acked
- {"Unable to read largest acked.",
- {0x12, 0x34}},
- // Zero delta time.
- {"Unable to read ack delay time.",
- {0x00, 0x00}},
- // first ack block length.
- {"Unable to read first ack block length.",
- {0x88, 0x88}},
- // num timestamps.
- {"Underflow with first ack block length 34952 largest acked is 4660.",
- {0x00}}
- };
-
- PacketFragments packet46 = {
- // type (short header, 4 byte packet number)
- {"",
- {0x43}},
- // connection_id
- {"",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // packet number
- {"",
- {0x12, 0x34, 0x56, 0x78}},
- // frame type (ack frame)
- // (one ack block, 2 byte largest observed, 2 byte block length)
- {"",
- {0x45}},
- // largest acked
- {"Unable to read largest acked.",
- {0x12, 0x34}},
- // Zero delta time.
- {"Unable to read ack delay time.",
- {0x00, 0x00}},
- // first ack block length.
- {"Unable to read first ack block length.",
- {0x88, 0x88}},
- // num timestamps.
- {"Underflow with first ack block length 34952 largest acked is 4660.",
- {0x00}}
- };
-
- PacketFragments packet_ietf = {
- // type (short header, 4 byte packet number)
- {"",
- {0x43}},
- // connection_id
- {"",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // packet number
- {"",
- {0x12, 0x34, 0x56, 0x78}},
- // frame type (IETF_ACK)
- {"",
- {0x02}},
- // largest acked
- {"Unable to read largest acked.",
- {kVarInt62TwoBytes + 0x12, 0x34}},
- // Zero delta time.
- {"Unable to read ack delay time.",
- {kVarInt62OneByte + 0x00}},
- // Ack block count (0 -- no blocks after the first)
- {"Unable to read ack block count.",
- {kVarInt62OneByte + 0x00}},
- // first ack block length.
- {"Unable to read first ack block length.",
- {kVarInt62TwoBytes + 0x28, 0x88}}
- };
- // clang-format on
-
- PacketFragments& fragments =
- VersionHasIetfQuicFrames(framer_.transport_version())
- ? packet_ietf
- : (framer_.version().HasIetfInvariantHeader() ? packet46 : packet);
- std::unique_ptr<QuicEncryptedPacket> encrypted(
- AssemblePacketFromFragments(fragments));
- EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
- CheckFramingBoundaries(fragments, QUIC_INVALID_ACK_DATA);
-}
-
-// This test checks that the ack frame processor correctly identifies
-// and handles the case where the third ack block's gap is larger than the
-// available space in the ack range.
-TEST_P(QuicFramerTest, ThirdAckBlockUnderflowGap) {
- if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
- // Test originally written for development of IETF QUIC. The test may
- // also apply to Google QUIC. If so, the test should be extended to
- // include Google QUIC (frame formats, etc). See b/141858819.
- return;
- }
- SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
- // clang-format off
- PacketFragments packet_ietf = {
- // type (short header, 4 byte packet number)
- {"",
- {0x43}},
- // connection_id
- {"",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // packet number
- {"",
- {0x12, 0x34, 0x56, 0x78}},
- // frame type (IETF_ACK frame)
- {"",
- {0x02}},
- // largest acked
- {"Unable to read largest acked.",
- {kVarInt62OneByte + 63}},
- // Zero delta time.
- {"Unable to read ack delay time.",
- {kVarInt62OneByte + 0x00}},
- // Ack block count (2 -- 2 blocks after the first)
- {"Unable to read ack block count.",
- {kVarInt62OneByte + 0x02}},
- // first ack block length.
- {"Unable to read first ack block length.",
- {kVarInt62OneByte + 13}}, // Ack 14 packets, range 50..63 (inclusive)
-
- {"Unable to read gap block value.",
- {kVarInt62OneByte + 9}}, // Gap 10 packets, 40..49 (inclusive)
- {"Unable to read ack block value.",
- {kVarInt62OneByte + 9}}, // Ack 10 packets, 30..39 (inclusive)
- {"Unable to read gap block value.",
- {kVarInt62OneByte + 29}}, // A gap of 30 packets (0..29 inclusive)
- // should be too big, leaving no room
- // for the ack.
- {"Underflow with gap block length 30 previous ack block start is 30.",
- {kVarInt62OneByte + 10}}, // Don't care
- };
- // clang-format on
-
- std::unique_ptr<QuicEncryptedPacket> encrypted(
- AssemblePacketFromFragments(packet_ietf));
- EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
- EXPECT_EQ(
- framer_.detailed_error(),
- "Underflow with gap block length 30 previous ack block start is 30.");
- CheckFramingBoundaries(packet_ietf, QUIC_INVALID_ACK_DATA);
-}
-
-// This test checks that the ack frame processor correctly identifies
-// and handles the case where the third ack block's length is larger than the
-// available space in the ack range.
-TEST_P(QuicFramerTest, ThirdAckBlockUnderflowAck) {
- if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
- // Test originally written for development of IETF QUIC. The test may
- // also apply to Google QUIC. If so, the test should be extended to
- // include Google QUIC (frame formats, etc). See b/141858819.
- return;
- }
- SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
- // clang-format off
- PacketFragments packet_ietf = {
- // type (short header, 4 byte packet number)
- {"",
- {0x43}},
- // connection_id
- {"",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // packet number
- {"",
- {0x12, 0x34, 0x56, 0x78}},
- // frame type (IETF_ACK frame)
- {"",
- {0x02}},
- // largest acked
- {"Unable to read largest acked.",
- {kVarInt62OneByte + 63}},
- // Zero delta time.
- {"Unable to read ack delay time.",
- {kVarInt62OneByte + 0x00}},
- // Ack block count (2 -- 2 blocks after the first)
- {"Unable to read ack block count.",
- {kVarInt62OneByte + 0x02}},
- // first ack block length.
- {"Unable to read first ack block length.",
- {kVarInt62OneByte + 13}}, // only 50 packet numbers "left"
-
- {"Unable to read gap block value.",
- {kVarInt62OneByte + 10}}, // Only 40 packet numbers left
- {"Unable to read ack block value.",
- {kVarInt62OneByte + 10}}, // only 30 packet numbers left.
- {"Unable to read gap block value.",
- {kVarInt62OneByte + 1}}, // Gap is OK, 29 packet numbers left
- {"Unable to read ack block value.",
- {kVarInt62OneByte + 30}}, // Use up all 30, should be an error
- };
- // clang-format on
-
- std::unique_ptr<QuicEncryptedPacket> encrypted(
- AssemblePacketFromFragments(packet_ietf));
- EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
- EXPECT_EQ(framer_.detailed_error(),
- "Underflow with ack block length 31 latest ack block end is 25.");
- CheckFramingBoundaries(packet_ietf, QUIC_INVALID_ACK_DATA);
-}
-
-// Tests a variety of ack block wrap scenarios. For example, if the
-// N-1th block causes packet 0 to be acked, then a gap would wrap
-// around to 0x3fffffff ffffffff... Make sure we detect this
-// condition.
-TEST_P(QuicFramerTest, AckBlockUnderflowGapWrap) {
- if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
- // Test originally written for development of IETF QUIC. The test may
- // also apply to Google QUIC. If so, the test should be extended to
- // include Google QUIC (frame formats, etc). See b/141858819.
- return;
- }
- SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
- // clang-format off
- PacketFragments packet_ietf = {
- // type (short header, 4 byte packet number)
- {"",
- {0x43}},
- // connection_id
- {"",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // packet number
- {"",
- {0x12, 0x34, 0x56, 0x78}},
- // frame type (IETF_ACK frame)
- {"",
- {0x02}},
- // largest acked
- {"Unable to read largest acked.",
- {kVarInt62OneByte + 10}},
- // Zero delta time.
- {"Unable to read ack delay time.",
- {kVarInt62OneByte + 0x00}},
- // Ack block count (1 -- 1 blocks after the first)
- {"Unable to read ack block count.",
- {kVarInt62OneByte + 1}},
- // first ack block length.
- {"Unable to read first ack block length.",
- {kVarInt62OneByte + 9}}, // Ack packets 1..10 (inclusive)
-
- {"Unable to read gap block value.",
- {kVarInt62OneByte + 1}}, // Gap of 2 packets (-1...0), should wrap
- {"Underflow with gap block length 2 previous ack block start is 1.",
- {kVarInt62OneByte + 9}}, // irrelevant
- };
- // clang-format on
-
- std::unique_ptr<QuicEncryptedPacket> encrypted(
- AssemblePacketFromFragments(packet_ietf));
- EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
- EXPECT_EQ(framer_.detailed_error(),
- "Underflow with gap block length 2 previous ack block start is 1.");
- CheckFramingBoundaries(packet_ietf, QUIC_INVALID_ACK_DATA);
-}
-
-// As AckBlockUnderflowGapWrap, but in this test, it's the ack
-// component of the ack-block that causes the wrap, not the gap.
-TEST_P(QuicFramerTest, AckBlockUnderflowAckWrap) {
- if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
- // Test originally written for development of IETF QUIC. The test may
- // also apply to Google QUIC. If so, the test should be extended to
- // include Google QUIC (frame formats, etc). See b/141858819.
- return;
- }
- SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
- // clang-format off
- PacketFragments packet_ietf = {
- // type (short header, 4 byte packet number)
- {"",
- {0x43}},
- // connection_id
- {"",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // packet number
- {"",
- {0x12, 0x34, 0x56, 0x78}},
- // frame type (IETF_ACK frame)
- {"",
- {0x02}},
- // largest acked
- {"Unable to read largest acked.",
- {kVarInt62OneByte + 10}},
- // Zero delta time.
- {"Unable to read ack delay time.",
- {kVarInt62OneByte + 0x00}},
- // Ack block count (1 -- 1 blocks after the first)
- {"Unable to read ack block count.",
- {kVarInt62OneByte + 1}},
- // first ack block length.
- {"Unable to read first ack block length.",
- {kVarInt62OneByte + 6}}, // Ack packets 4..10 (inclusive)
-
- {"Unable to read gap block value.",
- {kVarInt62OneByte + 1}}, // Gap of 2 packets (2..3)
- {"Unable to read ack block value.",
- {kVarInt62OneByte + 9}}, // Should wrap.
- };
- // clang-format on
-
- std::unique_ptr<QuicEncryptedPacket> encrypted(
- AssemblePacketFromFragments(packet_ietf));
- EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
- EXPECT_EQ(framer_.detailed_error(),
- "Underflow with ack block length 10 latest ack block end is 1.");
- CheckFramingBoundaries(packet_ietf, QUIC_INVALID_ACK_DATA);
-}
-
-// An ack block that acks the entire range, 1...0x3fffffffffffffff
-TEST_P(QuicFramerTest, AckBlockAcksEverything) {
- if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
- // Test originally written for development of IETF QUIC. The test may
- // also apply to Google QUIC. If so, the test should be extended to
- // include Google QUIC (frame formats, etc). See b/141858819.
- return;
- }
- SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
- // clang-format off
- PacketFragments packet_ietf = {
- // type (short header, 4 byte packet number)
- {"",
- {0x43}},
- // connection_id
- {"",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // packet number
- {"",
- {0x12, 0x34, 0x56, 0x78}},
- // frame type (IETF_ACK frame)
- {"",
- {0x02}},
- // largest acked
- {"Unable to read largest acked.",
- {kVarInt62EightBytes + 0x3f, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff}},
- // Zero delta time.
- {"Unable to read ack delay time.",
- {kVarInt62OneByte + 0x00}},
- // Ack block count No additional blocks
- {"Unable to read ack block count.",
- {kVarInt62OneByte + 0}},
- // first ack block length.
- {"Unable to read first ack block length.",
- {kVarInt62EightBytes + 0x3f, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xfe}},
- };
- // clang-format on
-
- std::unique_ptr<QuicEncryptedPacket> encrypted(
- AssemblePacketFromFragments(packet_ietf));
- EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
- EXPECT_EQ(1u, visitor_.ack_frames_.size());
- const QuicAckFrame& frame = *visitor_.ack_frames_[0];
- EXPECT_EQ(1u, frame.packets.NumIntervals());
- EXPECT_EQ(kLargestIetfLargestObserved, LargestAcked(frame));
- EXPECT_EQ(kLargestIetfLargestObserved.ToUint64(),
- frame.packets.NumPacketsSlow());
-}
-
-// This test looks for a malformed ack where
-// - There is a largest-acked value (that is, the frame is acking
-// something,
-// - But the length of the first ack block is 0 saying that no frames
-// are being acked with the largest-acked value or there are no
-// additional ack blocks.
-//
-TEST_P(QuicFramerTest, AckFrameFirstAckBlockLengthZero) {
- if (VersionHasIetfQuicFrames(framer_.transport_version())) {
- // Not applicable to version 99 -- first ack block contains the
- // number of packets that preceed the largest_acked packet.
- // A value of 0 means no packets preceed --- that the block's
- // length is 1. Therefore the condition that this test checks can
- // not arise.
- return;
- }
- SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-
- // clang-format off
- PacketFragments packet = {
- // public flags (8 byte connection_id)
- {"",
- { 0x2C }},
- // connection_id
- {"",
- { 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 }},
- // packet number
- {"",
- { 0x12, 0x34, 0x56, 0x78 }},
-
- // frame type (ack frame)
- // (more than one ack block, 2 byte largest observed, 2 byte block length)
- {"",
- { 0x65 }},
- // largest acked
- {"Unable to read largest acked.",
- { 0x12, 0x34 }},
- // Zero delta time.
- {"Unable to read ack delay time.",
- { 0x00, 0x00 }},
- // num ack blocks ranges.
- {"Unable to read num of ack blocks.",
- { 0x01 }},
- // first ack block length.
- {"Unable to read first ack block length.",
- { 0x00, 0x00 }},
- // gap to next block.
- { "First block length is zero.",
- { 0x01 }},
- // ack block length.
- { "First block length is zero.",
- { 0x0e, 0xaf }},
- // Number of timestamps.
- { "First block length is zero.",
- { 0x00 }},
- };
-
- PacketFragments packet46 = {
- // type (short header, 4 byte packet number)
- {"",
- { 0x43 }},
- // connection_id
- {"",
- { 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 }},
- // packet number
- {"",
- { 0x12, 0x34, 0x56, 0x78 }},
-
- // frame type (ack frame)
- // (more than one ack block, 2 byte largest observed, 2 byte block length)
- {"",
- { 0x65 }},
- // largest acked
- {"Unable to read largest acked.",
- { 0x12, 0x34 }},
- // Zero delta time.
- {"Unable to read ack delay time.",
- { 0x00, 0x00 }},
- // num ack blocks ranges.
- {"Unable to read num of ack blocks.",
- { 0x01 }},
- // first ack block length.
- {"Unable to read first ack block length.",
- { 0x00, 0x00 }},
- // gap to next block.
- { "First block length is zero.",
- { 0x01 }},
- // ack block length.
- { "First block length is zero.",
- { 0x0e, 0xaf }},
- // Number of timestamps.
- { "First block length is zero.",
- { 0x00 }},
- };
-
- // clang-format on
- PacketFragments& fragments =
- framer_.version().HasIetfInvariantHeader() ? packet46 : packet;
-
- std::unique_ptr<QuicEncryptedPacket> encrypted(
- AssemblePacketFromFragments(fragments));
-
- EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
- EXPECT_THAT(framer_.error(), IsError(QUIC_INVALID_ACK_DATA));
-
- ASSERT_TRUE(visitor_.header_.get());
- EXPECT_TRUE(CheckDecryption(
- *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
- PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
-
- EXPECT_EQ(0u, visitor_.stream_frames_.size());
- ASSERT_EQ(1u, visitor_.ack_frames_.size());
-
- CheckFramingBoundaries(fragments, QUIC_INVALID_ACK_DATA);
-}
-
-TEST_P(QuicFramerTest, AckFrameOneAckBlockMaxLength) {
- SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
- // clang-format off
- PacketFragments packet = {
- // public flags (8 byte connection_id)
- {"",
- {0x2C}},
- // connection_id
- {"",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // packet number
- {"",
- {0x12, 0x34, 0x56, 0x78}},
- // frame type (ack frame)
- // (one ack block, 4 byte largest observed, 2 byte block length)
- {"",
- {0x49}},
- // largest acked
- {"Unable to read largest acked.",
- {0x12, 0x34, 0x56, 0x78}},
- // Zero delta time.
- {"Unable to read ack delay time.",
- {0x00, 0x00}},
- // first ack block length.
- {"Unable to read first ack block length.",
- {0x12, 0x34}},
- // num timestamps.
- {"Unable to read num received packets.",
- {0x00}}
- };
-
- PacketFragments packet46 = {
- // type (short header, 4 byte packet number)
- {"",
- {0x43}},
- // connection_id
- {"",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // packet number
- {"",
- {0x56, 0x78, 0x9A, 0xBC}},
- // frame type (ack frame)
- // (one ack block, 4 byte largest observed, 2 byte block length)
- {"",
- {0x49}},
- // largest acked
- {"Unable to read largest acked.",
- {0x12, 0x34, 0x56, 0x78}},
- // Zero delta time.
- {"Unable to read ack delay time.",
- {0x00, 0x00}},
- // first ack block length.
- {"Unable to read first ack block length.",
- {0x12, 0x34}},
- // num timestamps.
- {"Unable to read num received packets.",
- {0x00}}
- };
-
- PacketFragments packet_ietf = {
- // type (short header, 4 byte packet number)
- {"",
- {0x43}},
- // connection_id
- {"",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // packet number
- {"",
- {0x56, 0x78, 0x9A, 0xBC}},
- // frame type (IETF_ACK frame)
- {"",
- {0x02}},
- // largest acked
- {"Unable to read largest acked.",
- {kVarInt62FourBytes + 0x12, 0x34, 0x56, 0x78}},
- // Zero delta time.
- {"Unable to read ack delay time.",
- {kVarInt62OneByte + 0x00}},
- // Number of ack blocks after first
- {"Unable to read ack block count.",
- {kVarInt62OneByte + 0x00}},
- // first ack block length.
- {"Unable to read first ack block length.",
- {kVarInt62TwoBytes + 0x12, 0x33}}
- };
- // clang-format on
-
- PacketFragments& fragments =
- VersionHasIetfQuicFrames(framer_.transport_version())
- ? packet_ietf
- : (framer_.version().HasIetfInvariantHeader() ? packet46 : packet);
- std::unique_ptr<QuicEncryptedPacket> encrypted(
- AssemblePacketFromFragments(fragments));
- EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
-
- EXPECT_THAT(framer_.error(), IsQuicNoError());
- ASSERT_TRUE(visitor_.header_.get());
- EXPECT_TRUE(CheckDecryption(
- *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
- PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
-
- EXPECT_EQ(0u, visitor_.stream_frames_.size());
- ASSERT_EQ(1u, visitor_.ack_frames_.size());
- const QuicAckFrame& frame = *visitor_.ack_frames_[0];
- EXPECT_EQ(kPacketNumber, LargestAcked(frame));
- ASSERT_EQ(4660u, frame.packets.NumPacketsSlow());
-
- CheckFramingBoundaries(fragments, QUIC_INVALID_ACK_DATA);
-}
-
-// Tests ability to handle multiple ackblocks after the first ack
-// block. Non-version-99 tests include multiple timestamps as well.
-TEST_P(QuicFramerTest, AckFrameTwoTimeStampsMultipleAckBlocks) {
- SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
- // clang-format off
- PacketFragments packet = {
- // public flags (8 byte connection_id)
- {"",
- { 0x2C }},
- // connection_id
- {"",
- { 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 }},
- // packet number
- {"",
- { 0x12, 0x34, 0x56, 0x78 }},
-
- // frame type (ack frame)
- // (more than one ack block, 2 byte largest observed, 2 byte block length)
- {"",
- { 0x65 }},
- // largest acked
- {"Unable to read largest acked.",
- { 0x12, 0x34 }},
- // Zero delta time.
- {"Unable to read ack delay time.",
- { 0x00, 0x00 }},
- // num ack blocks ranges.
- {"Unable to read num of ack blocks.",
- { 0x04 }},
- // first ack block length.
- {"Unable to read first ack block length.",
- { 0x00, 0x01 }},
- // gap to next block.
- { "Unable to read gap to next ack block.",
- { 0x01 }},
- // ack block length.
- { "Unable to ack block length.",
- { 0x0e, 0xaf }},
- // gap to next block.
- { "Unable to read gap to next ack block.",
- { 0xff }},
- // ack block length.
- { "Unable to ack block length.",
- { 0x00, 0x00 }},
- // gap to next block.
- { "Unable to read gap to next ack block.",
- { 0x91 }},
- // ack block length.
- { "Unable to ack block length.",
- { 0x01, 0xea }},
- // gap to next block.
- { "Unable to read gap to next ack block.",
- { 0x05 }},
- // ack block length.
- { "Unable to ack block length.",
- { 0x00, 0x04 }},
- // Number of timestamps.
- { "Unable to read num received packets.",
- { 0x02 }},
- // Delta from largest observed.
- { "Unable to read sequence delta in received packets.",
- { 0x01 }},
- // Delta time.
- { "Unable to read time delta in received packets.",
- { 0x76, 0x54, 0x32, 0x10 }},
- // Delta from largest observed.
- { "Unable to read sequence delta in received packets.",
- { 0x02 }},
- // Delta time.
- { "Unable to read incremental time delta in received packets.",
- { 0x32, 0x10 }},
- };
-
- PacketFragments packet46 = {
- // type (short header, 4 byte packet number)
- {"",
- { 0x43 }},
- // connection_id
- {"",
- { 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 }},
- // packet number
- {"",
- { 0x12, 0x34, 0x56, 0x78 }},
-
- // frame type (ack frame)
- // (more than one ack block, 2 byte largest observed, 2 byte block length)
- {"",
- { 0x65 }},
- // largest acked
- {"Unable to read largest acked.",
- { 0x12, 0x34 }},
- // Zero delta time.
- {"Unable to read ack delay time.",
- { 0x00, 0x00 }},
- // num ack blocks ranges.
- {"Unable to read num of ack blocks.",
- { 0x04 }},
- // first ack block length.
- {"Unable to read first ack block length.",
- { 0x00, 0x01 }},
- // gap to next block.
- { "Unable to read gap to next ack block.",
- { 0x01 }},
- // ack block length.
- { "Unable to ack block length.",
- { 0x0e, 0xaf }},
- // gap to next block.
- { "Unable to read gap to next ack block.",
- { 0xff }},
- // ack block length.
- { "Unable to ack block length.",
- { 0x00, 0x00 }},
- // gap to next block.
- { "Unable to read gap to next ack block.",
- { 0x91 }},
- // ack block length.
- { "Unable to ack block length.",
- { 0x01, 0xea }},
- // gap to next block.
- { "Unable to read gap to next ack block.",
- { 0x05 }},
- // ack block length.
- { "Unable to ack block length.",
- { 0x00, 0x04 }},
- // Number of timestamps.
- { "Unable to read num received packets.",
- { 0x02 }},
- // Delta from largest observed.
- { "Unable to read sequence delta in received packets.",
- { 0x01 }},
- // Delta time.
- { "Unable to read time delta in received packets.",
- { 0x76, 0x54, 0x32, 0x10 }},
- // Delta from largest observed.
- { "Unable to read sequence delta in received packets.",
- { 0x02 }},
- // Delta time.
- { "Unable to read incremental time delta in received packets.",
- { 0x32, 0x10 }},
- };
-
- PacketFragments packet_ietf = {
- // type (short header, 4 byte packet number)
- {"",
- { 0x43 }},
- // connection_id
- {"",
- { 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 }},
- // packet number
- {"",
- { 0x12, 0x34, 0x56, 0x78 }},
-
- // frame type (IETF_ACK_RECEIVE_TIMESTAMPS frame)
- {"",
- { 0x22 }},
- // largest acked
- {"Unable to read largest acked.",
- { kVarInt62TwoBytes + 0x12, 0x34 }}, // = 4660
- // Zero delta time.
- {"Unable to read ack delay time.",
- { kVarInt62OneByte + 0x00 }},
- // number of additional ack blocks
- {"Unable to read ack block count.",
- { kVarInt62OneByte + 0x03 }},
- // first ack block length.
- {"Unable to read first ack block length.",
- { kVarInt62OneByte + 0x00 }}, // 1st block length = 1
-
- // Additional ACK Block #1
- // gap to next block.
- { "Unable to read gap block value.",
- { kVarInt62OneByte + 0x00 }}, // gap of 1 packet
- // ack block length.
- { "Unable to read ack block value.",
- { kVarInt62TwoBytes + 0x0e, 0xae }}, // 3759
-
- // pre-version-99 test includes an ack block of 0 length. this
- // can not happen in version 99. ergo the second block is not
- // present in the v99 test and the gap length of the next block
- // is the sum of the two gaps in the pre-version-99 tests.
- // Additional ACK Block #2
- // gap to next block.
- { "Unable to read gap block value.",
- { kVarInt62TwoBytes + 0x01, 0x8f }}, // Gap is 400 (0x190) pkts
- // ack block length.
- { "Unable to read ack block value.",
- { kVarInt62TwoBytes + 0x01, 0xe9 }}, // block is 389 (x1ea) pkts
-
- // Additional ACK Block #3
- // gap to next block.
- { "Unable to read gap block value.",
- { kVarInt62OneByte + 0x04 }}, // Gap is 5 packets.
- // ack block length.
- { "Unable to read ack block value.",
- { kVarInt62OneByte + 0x03 }}, // block is 3 packets.
-
- // Receive Timestamps.
- { "Unable to read receive timestamp range count.",
- { kVarInt62OneByte + 0x01 }},
- { "Unable to read receive timestamp gap.",
- { kVarInt62OneByte + 0x01 }},
- { "Unable to read receive timestamp count.",
- { kVarInt62OneByte + 0x02 }},
- { "Unable to read receive timestamp delta.",
- { kVarInt62FourBytes + 0x36, 0x54, 0x32, 0x10 }},
- { "Unable to read receive timestamp delta.",
- { kVarInt62TwoBytes + 0x32, 0x10 }},
- };
-
- // clang-format on
- PacketFragments& fragments =
- VersionHasIetfQuicFrames(framer_.transport_version())
- ? packet_ietf
- : (framer_.version().HasIetfInvariantHeader() ? packet46 : packet);
-
- std::unique_ptr<QuicEncryptedPacket> encrypted(
- AssemblePacketFromFragments(fragments));
-
- framer_.set_process_timestamps(true);
- EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
-
- EXPECT_THAT(framer_.error(), IsQuicNoError());
- ASSERT_TRUE(visitor_.header_.get());
- EXPECT_TRUE(CheckDecryption(
- *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
- PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
-
- EXPECT_EQ(0u, visitor_.stream_frames_.size());
- ASSERT_EQ(1u, visitor_.ack_frames_.size());
- const QuicAckFrame& frame = *visitor_.ack_frames_[0];
- EXPECT_EQ(kSmallLargestObserved, LargestAcked(frame));
- ASSERT_EQ(4254u, frame.packets.NumPacketsSlow());
- EXPECT_EQ(4u, frame.packets.NumIntervals());
- EXPECT_EQ(2u, frame.received_packet_times.size());
-}
-
-TEST_P(QuicFramerTest, AckFrameMultipleReceiveTimestampRanges) {
- if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
- return;
- }
- SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
- // clang-format off
- PacketFragments packet_ietf = {
- // type (short header, 4 byte packet number)
- {"",
- { 0x43 }},
- // connection_id
- {"",
- { 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 }},
- // packet number
- {"",
- { 0x12, 0x34, 0x56, 0x78 }},
-
- // frame type (IETF_ACK_RECEIVE_TIMESTAMPS frame)
- {"",
- { 0x22 }},
- // largest acked
- {"Unable to read largest acked.",
- { kVarInt62TwoBytes + 0x12, 0x34 }}, // = 4660
- // Zero delta time.
- {"Unable to read ack delay time.",
- { kVarInt62OneByte + 0x00 }},
- // number of additional ack blocks
- {"Unable to read ack block count.",
- { kVarInt62OneByte + 0x00 }},
- // first ack block length.
- {"Unable to read first ack block length.",
- { kVarInt62OneByte + 0x00 }}, // 1st block length = 1
-
- // Receive Timestamps.
- { "Unable to read receive timestamp range count.",
- { kVarInt62OneByte + 0x03 }},
-
- // Timestamp range 1 (three packets).
- { "Unable to read receive timestamp gap.",
- { kVarInt62OneByte + 0x02 }},
- { "Unable to read receive timestamp count.",
- { kVarInt62OneByte + 0x03 }},
- { "Unable to read receive timestamp delta.",
- { kVarInt62FourBytes + 0x29, 0xff, 0xff, 0xff}},
- { "Unable to read receive timestamp delta.",
- { kVarInt62TwoBytes + 0x11, 0x11 }},
- { "Unable to read receive timestamp delta.",
- { kVarInt62OneByte + 0x01}},
-
- // Timestamp range 2 (one packet).
- { "Unable to read receive timestamp gap.",
- { kVarInt62OneByte + 0x05 }},
- { "Unable to read receive timestamp count.",
- { kVarInt62OneByte + 0x01 }},
- { "Unable to read receive timestamp delta.",
- { kVarInt62TwoBytes + 0x10, 0x00 }},
-
- // Timestamp range 3 (two packets).
- { "Unable to read receive timestamp gap.",
- { kVarInt62OneByte + 0x08 }},
- { "Unable to read receive timestamp count.",
- { kVarInt62OneByte + 0x02 }},
- { "Unable to read receive timestamp delta.",
- { kVarInt62OneByte + 0x10 }},
- { "Unable to read receive timestamp delta.",
- { kVarInt62TwoBytes + 0x01, 0x00 }},
- };
- // clang-format on
-
- std::unique_ptr<QuicEncryptedPacket> encrypted(
- AssemblePacketFromFragments(packet_ietf));
-
- framer_.set_process_timestamps(true);
- EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
- EXPECT_THAT(framer_.error(), IsQuicNoError());
- ASSERT_TRUE(visitor_.header_.get());
- const QuicAckFrame& frame = *visitor_.ack_frames_[0];
-
- EXPECT_THAT(frame.received_packet_times,
- ContainerEq(PacketTimeVector{
- // Timestamp Range 1.
- {LargestAcked(frame) - 2, CreationTimePlus(0x29ffffff)},
- {LargestAcked(frame) - 3, CreationTimePlus(0x29ffeeee)},
- {LargestAcked(frame) - 4, CreationTimePlus(0x29ffeeed)},
- // Timestamp Range 2.
- {LargestAcked(frame) - 11, CreationTimePlus(0x29ffdeed)},
- // Timestamp Range 3.
- {LargestAcked(frame) - 21, CreationTimePlus(0x29ffdedd)},
- {LargestAcked(frame) - 22, CreationTimePlus(0x29ffdddd)},
- }));
-}
-
-TEST_P(QuicFramerTest, AckFrameReceiveTimestampWithExponent) {
- if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
- return;
- }
- SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
- // clang-format off
- PacketFragments packet_ietf = {
- // type (short header, 4 byte packet number)
- {"",
- { 0x43 }},
- // connection_id
- {"",
- { 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 }},
- // packet number
- {"",
- { 0x12, 0x34, 0x56, 0x78 }},
-
- // frame type (IETF_ACK_RECEIVE_TIMESTAMPS frame)
- {"",
- { 0x22 }},
- // largest acked
- {"Unable to read largest acked.",
- { kVarInt62TwoBytes + 0x12, 0x34 }}, // = 4660
- // Zero delta time.
- {"Unable to read ack delay time.",
- { kVarInt62OneByte + 0x00 }},
- // number of additional ack blocks
- {"Unable to read ack block count.",
- { kVarInt62OneByte + 0x00 }},
- // first ack block length.
- {"Unable to read first ack block length.",
- { kVarInt62OneByte + 0x00 }}, // 1st block length = 1
-
- // Receive Timestamps.
- { "Unable to read receive timestamp range count.",
- { kVarInt62OneByte + 0x01 }},
- { "Unable to read receive timestamp gap.",
- { kVarInt62OneByte + 0x00 }},
- { "Unable to read receive timestamp count.",
- { kVarInt62OneByte + 0x03 }},
- { "Unable to read receive timestamp delta.",
- { kVarInt62TwoBytes + 0x29, 0xff}},
- { "Unable to read receive timestamp delta.",
- { kVarInt62TwoBytes + 0x11, 0x11 }},
- { "Unable to read receive timestamp delta.",
- { kVarInt62OneByte + 0x01}},
- };
- // clang-format on
-
- std::unique_ptr<QuicEncryptedPacket> encrypted(
- AssemblePacketFromFragments(packet_ietf));
-
- framer_.set_receive_timestamps_exponent(3);
- framer_.set_process_timestamps(true);
- EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
- EXPECT_THAT(framer_.error(), IsQuicNoError());
- ASSERT_TRUE(visitor_.header_.get());
- const QuicAckFrame& frame = *visitor_.ack_frames_[0];
-
- EXPECT_THAT(frame.received_packet_times,
- ContainerEq(PacketTimeVector{
- // Timestamp Range 1.
- {LargestAcked(frame), CreationTimePlus(0x29ff << 3)},
- {LargestAcked(frame) - 1, CreationTimePlus(0x18ee << 3)},
- {LargestAcked(frame) - 2, CreationTimePlus(0x18ed << 3)},
- }));
-}
-
-TEST_P(QuicFramerTest, AckFrameReceiveTimestampGapTooHigh) {
- if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
- return;
- }
- SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
- // clang-format off
- PacketFragments packet_ietf = {
- // type (short header, 4 byte packet number)
- {"",
- { 0x43 }},
- // connection_id
- {"",
- { 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 }},
- // packet number
- {"",
- { 0x12, 0x34, 0x56, 0x78 }},
-
- // frame type (IETF_ACK_RECEIVE_TIMESTAMPS frame)
- {"",
- { 0x22 }},
- // largest acked
- {"Unable to read largest acked.",
- { kVarInt62TwoBytes + 0x12, 0x34 }}, // = 4660
- // Zero delta time.
- {"Unable to read ack delay time.",
- { kVarInt62OneByte + 0x00 }},
- // number of additional ack blocks
- {"Unable to read ack block count.",
- { kVarInt62OneByte + 0x00 }},
- // first ack block length.
- {"Unable to read first ack block length.",
- { kVarInt62OneByte + 0x00 }}, // 1st block length = 1
-
- // Receive Timestamps.
- { "Unable to read receive timestamp range count.",
- { kVarInt62OneByte + 0x01 }},
- { "Unable to read receive timestamp gap.",
- { kVarInt62FourBytes + 0x12, 0x34, 0x56, 0x79 }},
- { "Unable to read receive timestamp count.",
- { kVarInt62OneByte + 0x01 }},
- { "Unable to read receive timestamp delta.",
- { kVarInt62TwoBytes + 0x29, 0xff}},
- };
- // clang-format on
-
- std::unique_ptr<QuicEncryptedPacket> encrypted(
- AssemblePacketFromFragments(packet_ietf));
-
- framer_.set_process_timestamps(true);
- EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
- EXPECT_TRUE(absl::StartsWith(framer_.detailed_error(),
- "Receive timestamp gap too high."));
-}
-
-TEST_P(QuicFramerTest, AckFrameReceiveTimestampCountTooHigh) {
- if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
- return;
- }
- SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
- // clang-format off
- PacketFragments packet_ietf = {
- // type (short header, 4 byte packet number)
- {"",
- { 0x43 }},
- // connection_id
- {"",
- { 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 }},
- // packet number
- {"",
- { 0x12, 0x34, 0x56, 0x78 }},
-
- // frame type (IETF_ACK_RECEIVE_TIMESTAMPS frame)
- {"",
- { 0x22 }},
- // largest acked
- {"Unable to read largest acked.",
- { kVarInt62TwoBytes + 0x12, 0x34 }}, // = 4660
- // Zero delta time.
- {"Unable to read ack delay time.",
- { kVarInt62OneByte + 0x00 }},
- // number of additional ack blocks
- {"Unable to read ack block count.",
- { kVarInt62OneByte + 0x00 }},
- // first ack block length.
- {"Unable to read first ack block length.",
- { kVarInt62OneByte + 0x00 }}, // 1st block length = 1
-
- // Receive Timestamps.
- { "Unable to read receive timestamp range count.",
- { kVarInt62OneByte + 0x01 }},
- { "Unable to read receive timestamp gap.",
- { kVarInt62OneByte + 0x02 }},
- { "Unable to read receive timestamp count.",
- { kVarInt62OneByte + 0x02 }},
- { "Unable to read receive timestamp delta.",
- { kVarInt62OneByte + 0x0a}},
- { "Unable to read receive timestamp delta.",
- { kVarInt62OneByte + 0x0b}},
- };
- // clang-format on
-
- std::unique_ptr<QuicEncryptedPacket> encrypted(
- AssemblePacketFromFragments(packet_ietf));
-
- framer_.set_process_timestamps(true);
- EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
- EXPECT_TRUE(absl::StartsWith(framer_.detailed_error(),
- "Receive timestamp delta too high."));
-}
-
-TEST_P(QuicFramerTest, AckFrameReceiveTimestampDeltaTooHigh) {
- if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
- return;
- }
- SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
- // clang-format off
- PacketFragments packet_ietf = {
- // type (short header, 4 byte packet number)
- {"",
- { 0x43 }},
- // connection_id
- {"",
- { 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 }},
- // packet number
- {"",
- { 0x12, 0x34, 0x56, 0x78 }},
-
- // frame type (IETF_ACK_RECEIVE_TIMESTAMPS frame)
- {"",
- { 0x22 }},
- // largest acked
- {"Unable to read largest acked.",
- { kVarInt62TwoBytes + 0x12, 0x34 }}, // = 4660
- // Zero delta time.
- {"Unable to read ack delay time.",
- { kVarInt62OneByte + 0x00 }},
- // number of additional ack blocks
- {"Unable to read ack block count.",
- { kVarInt62OneByte + 0x00 }},
- // first ack block length.
- {"Unable to read first ack block length.",
- { kVarInt62OneByte + 0x00 }}, // 1st block length = 1
-
- // Receive Timestamps.
- { "Unable to read receive timestamp range count.",
- { kVarInt62OneByte + 0x01 }},
- { "Unable to read receive timestamp gap.",
- { kVarInt62OneByte + 0x02 }},
- { "Unable to read receive timestamp count.",
- { kVarInt62FourBytes + 0x12, 0x34, 0x56, 0x77 }},
- { "Unable to read receive timestamp delta.",
- { kVarInt62TwoBytes + 0x29, 0xff}},
- };
- // clang-format on
-
- std::unique_ptr<QuicEncryptedPacket> encrypted(
- AssemblePacketFromFragments(packet_ietf));
-
- framer_.set_process_timestamps(true);
- EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
- EXPECT_TRUE(absl::StartsWith(framer_.detailed_error(),
- "Receive timestamp count too high."));
-}
-
-TEST_P(QuicFramerTest, AckFrameTimeStampDeltaTooHigh) {
- SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
- // clang-format off
- unsigned char packet[] = {
- // public flags (8 byte connection_id)
- 0x28,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
-
- // frame type (ack frame)
- // (no ack blocks, 1 byte largest observed, 1 byte block length)
- 0x40,
- // largest acked
- 0x01,
- // Zero delta time.
- 0x00, 0x00,
- // first ack block length.
- 0x01,
- // num timestamps.
- 0x01,
- // Delta from largest observed.
- 0x01,
- // Delta time.
- 0x10, 0x32, 0x54, 0x76,
- };
-
- unsigned char packet46[] = {
- // type (short header, 4 byte packet number)
- 0x43,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
-
- // frame type (ack frame)
- // (no ack blocks, 1 byte largest observed, 1 byte block length)
- 0x40,
- // largest acked
- 0x01,
- // Zero delta time.
- 0x00, 0x00,
- // first ack block length.
- 0x01,
- // num timestamps.
- 0x01,
- // Delta from largest observed.
- 0x01,
- // Delta time.
- 0x10, 0x32, 0x54, 0x76,
- };
- // clang-format on
- if (VersionHasIetfQuicFrames(framer_.transport_version())) {
- // ACK Timestamp is not a feature of IETF QUIC.
- return;
- }
- QuicEncryptedPacket encrypted(
- AsChars(framer_.version().HasIetfInvariantHeader() ? packet46 : packet),
- ABSL_ARRAYSIZE(packet), false);
- EXPECT_FALSE(framer_.ProcessPacket(encrypted));
- EXPECT_TRUE(absl::StartsWith(framer_.detailed_error(),
- "delta_from_largest_observed too high"));
-}
-
-TEST_P(QuicFramerTest, AckFrameTimeStampSecondDeltaTooHigh) {
- SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
- // clang-format off
- unsigned char packet[] = {
- // public flags (8 byte connection_id)
- 0x28,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
-
- // frame type (ack frame)
- // (no ack blocks, 1 byte largest observed, 1 byte block length)
- 0x40,
- // largest acked
- 0x03,
- // Zero delta time.
- 0x00, 0x00,
- // first ack block length.
- 0x03,
- // num timestamps.
- 0x02,
- // Delta from largest observed.
- 0x01,
- // Delta time.
- 0x10, 0x32, 0x54, 0x76,
- // Delta from largest observed.
- 0x03,
- // Delta time.
- 0x10, 0x32,
- };
-
- unsigned char packet46[] = {
- // type (short header, 4 byte packet number)
- 0x43,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
-
- // frame type (ack frame)
- // (no ack blocks, 1 byte largest observed, 1 byte block length)
- 0x40,
- // largest acked
- 0x03,
- // Zero delta time.
- 0x00, 0x00,
- // first ack block length.
- 0x03,
- // num timestamps.
- 0x02,
- // Delta from largest observed.
- 0x01,
- // Delta time.
- 0x10, 0x32, 0x54, 0x76,
- // Delta from largest observed.
- 0x03,
- // Delta time.
- 0x10, 0x32,
- };
- // clang-format on
- if (VersionHasIetfQuicFrames(framer_.transport_version())) {
- // ACK Timestamp is not a feature of IETF QUIC.
- return;
- }
- QuicEncryptedPacket encrypted(
- AsChars(framer_.version().HasIetfInvariantHeader() ? packet46 : packet),
- ABSL_ARRAYSIZE(packet), false);
- EXPECT_FALSE(framer_.ProcessPacket(encrypted));
- EXPECT_TRUE(absl::StartsWith(framer_.detailed_error(),
- "delta_from_largest_observed too high"));
-}
-
-TEST_P(QuicFramerTest, NewStopWaitingFrame) {
- if (VersionHasIetfQuicFrames(version_.transport_version)) {
- // The Stop Waiting frame is not in IETF QUIC
- return;
- }
- SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
- // clang-format off
- PacketFragments packet = {
- // public flags (8 byte connection_id)
- {"",
- {0x2C}},
- // connection_id
- {"",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // packet number
- {"",
- {0x12, 0x34, 0x56, 0x78}},
- // frame type (stop waiting frame)
- {"",
- {0x06}},
- // least packet number awaiting an ack, delta from packet number.
- {"Unable to read least unacked delta.",
- {0x00, 0x00, 0x00, 0x08}}
- };
-
- PacketFragments packet46 = {
- // type (short header, 4 byte packet number)
- {"",
- {0x43}},
- // connection_id
- {"",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // packet number
- {"",
- {0x12, 0x34, 0x56, 0x78}},
- // frame type (stop waiting frame)
- {"",
- {0x06}},
- // least packet number awaiting an ack, delta from packet number.
- {"Unable to read least unacked delta.",
- {0x00, 0x00, 0x00, 0x08}}
- };
- // clang-format on
-
- PacketFragments& fragments =
- framer_.version().HasIetfInvariantHeader() ? packet46 : packet;
-
- std::unique_ptr<QuicEncryptedPacket> encrypted(
- AssemblePacketFromFragments(fragments));
-
- EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
- EXPECT_THAT(framer_.error(), IsQuicNoError());
- ASSERT_TRUE(visitor_.header_.get());
- EXPECT_TRUE(CheckDecryption(
- *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
- PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
-
- EXPECT_EQ(0u, visitor_.stream_frames_.size());
- ASSERT_EQ(1u, visitor_.stop_waiting_frames_.size());
- const QuicStopWaitingFrame& frame = *visitor_.stop_waiting_frames_[0];
- EXPECT_EQ(kLeastUnacked, frame.least_unacked);
-
- CheckFramingBoundaries(fragments, QUIC_INVALID_STOP_WAITING_DATA);
-}
-
-TEST_P(QuicFramerTest, InvalidNewStopWaitingFrame) {
- // The Stop Waiting frame is not in IETF QUIC
- if (VersionHasIetfQuicFrames(version_.transport_version) &&
- framer_.version().HasIetfInvariantHeader()) {
- return;
- }
- SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
- // clang-format off
- unsigned char packet[] = {
- // public flags (8 byte connection_id)
- 0x2C,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
- // frame type (stop waiting frame)
- 0x06,
- // least packet number awaiting an ack, delta from packet number.
- 0x13, 0x34, 0x56, 0x78,
- 0x9A, 0xA8,
- };
-
- unsigned char packet46[] = {
- // type (short header, 4 byte packet number)
- 0x43,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
- // frame type (stop waiting frame)
- 0x06,
- // least packet number awaiting an ack, delta from packet number.
- 0x57, 0x78, 0x9A, 0xA8,
- };
- // clang-format on
-
- QuicEncryptedPacket encrypted(
- AsChars(framer_.version().HasIetfInvariantHeader() ? packet46 : packet),
- framer_.version().HasIetfInvariantHeader() ? ABSL_ARRAYSIZE(packet46)
- : ABSL_ARRAYSIZE(packet),
- false);
- EXPECT_FALSE(framer_.ProcessPacket(encrypted));
- EXPECT_THAT(framer_.error(), IsError(QUIC_INVALID_STOP_WAITING_DATA));
- EXPECT_EQ("Invalid unacked delta.", framer_.detailed_error());
-}
-
-TEST_P(QuicFramerTest, RstStreamFrame) {
- SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
- // clang-format off
- PacketFragments packet = {
- // public flags (8 byte connection_id)
- {"",
- {0x28}},
- // connection_id
- {"",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // packet number
- {"",
- {0x12, 0x34, 0x56, 0x78}},
- // frame type (rst stream frame)
- {"",
- {0x01}},
- // stream id
- {"Unable to read stream_id.",
- {0x01, 0x02, 0x03, 0x04}},
- // sent byte offset
- {"Unable to read rst stream sent byte offset.",
- {0x3A, 0x98, 0xFE, 0xDC,
- 0x32, 0x10, 0x76, 0x54}},
- // error code QUIC_STREAM_CANCELLED
- {"Unable to read rst stream error code.",
- {0x00, 0x00, 0x00, 0x06}}
- };
-
- PacketFragments packet46 = {
- // type (short header, 4 byte packet number)
- {"",
- {0x43}},
- // connection_id
- {"",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // packet number
- {"",
- {0x12, 0x34, 0x56, 0x78}},
- // frame type (rst stream frame)
- {"",
- {0x01}},
- // stream id
- {"Unable to read stream_id.",
- {0x01, 0x02, 0x03, 0x04}},
- // sent byte offset
- {"Unable to read rst stream sent byte offset.",
- {0x3A, 0x98, 0xFE, 0xDC,
- 0x32, 0x10, 0x76, 0x54}},
- // error code QUIC_STREAM_CANCELLED
- {"Unable to read rst stream error code.",
- {0x00, 0x00, 0x00, 0x06}}
- };
-
- PacketFragments packet_ietf = {
- // type (short header, 4 byte packet number)
- {"",
- {0x43}},
- // connection_id
- {"",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // packet number
- {"",
- {0x12, 0x34, 0x56, 0x78}},
- // frame type (IETF_RST_STREAM frame)
- {"",
- {0x04}},
- // stream id
- {"Unable to read IETF_RST_STREAM frame stream id/count.",
- {kVarInt62FourBytes + 0x01, 0x02, 0x03, 0x04}},
- // application error code H3_REQUEST_CANCELLED gets translated to
- // QuicRstStreamErrorCode::QUIC_STREAM_CANCELLED.
- {"Unable to read rst stream error code.",
- {kVarInt62TwoBytes + 0x01, 0x0c}},
- // Final Offset
- {"Unable to read rst stream sent byte offset.",
- {kVarInt62EightBytes + 0x3a, 0x98, 0xFE, 0xDC, 0x32, 0x10, 0x76, 0x54}}
- };
- // clang-format on
-
- PacketFragments& fragments =
- VersionHasIetfQuicFrames(framer_.transport_version())
- ? packet_ietf
- : (framer_.version().HasIetfInvariantHeader() ? packet46 : packet);
- std::unique_ptr<QuicEncryptedPacket> encrypted(
- AssemblePacketFromFragments(fragments));
- EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
-
- EXPECT_THAT(framer_.error(), IsQuicNoError());
- ASSERT_TRUE(visitor_.header_.get());
- EXPECT_TRUE(CheckDecryption(
- *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
- PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
-
- EXPECT_EQ(kStreamId, visitor_.rst_stream_frame_.stream_id);
- EXPECT_EQ(QUIC_STREAM_CANCELLED, visitor_.rst_stream_frame_.error_code);
- EXPECT_EQ(kStreamOffset, visitor_.rst_stream_frame_.byte_offset);
- CheckFramingBoundaries(fragments, QUIC_INVALID_RST_STREAM_DATA);
-}
-
-TEST_P(QuicFramerTest, ConnectionCloseFrame) {
- SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
- // clang-format off
- PacketFragments packet = {
- // public flags (8 byte connection_id)
- {"",
- {0x28}},
- // connection_id
- {"",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // packet number
- {"",
- {0x12, 0x34, 0x56, 0x78}},
- // frame type (connection close frame)
- {"",
- {0x02}},
- // error code
- {"Unable to read connection close error code.",
- {0x00, 0x00, 0x00, 0x11}},
- {"Unable to read connection close error details.",
- {
- // error details length
- 0x0, 0x0d,
- // error details
- 'b', 'e', 'c', 'a',
- 'u', 's', 'e', ' ',
- 'I', ' ', 'c', 'a',
- 'n'}
- }
- };
-
- PacketFragments packet46 = {
- // type (short header, 4 byte packet number)
- {"",
- {0x43}},
- // connection_id
- {"",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // packet number
- {"",
- {0x12, 0x34, 0x56, 0x78}},
- // frame type (connection close frame)
- {"",
- {0x02}},
- // error code
- {"Unable to read connection close error code.",
- {0x00, 0x00, 0x00, 0x11}},
- {"Unable to read connection close error details.",
- {
- // error details length
- 0x0, 0x0d,
- // error details
- 'b', 'e', 'c', 'a',
- 'u', 's', 'e', ' ',
- 'I', ' ', 'c', 'a',
- 'n'}
- }
- };
-
- PacketFragments packet_ietf = {
- // type (short header, 4 byte packet number)
- {"",
- {0x43}},
- // connection_id
- {"",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // packet number
- {"",
- {0x12, 0x34, 0x56, 0x78}},
- // frame type (IETF Transport CONNECTION_CLOSE frame)
- {"",
- {0x1c}},
- // error code
- {"Unable to read connection close error code.",
- {kVarInt62TwoBytes + 0x00, 0x11}},
- {"Unable to read connection close frame type.",
- {kVarInt62TwoBytes + 0x12, 0x34 }},
- {"Unable to read connection close error details.",
- {
- // error details length
- kVarInt62OneByte + 0x11,
- // error details with QuicErrorCode serialized
- '1', '1', '5', ':',
- 'b', 'e', 'c', 'a',
- 'u', 's', 'e', ' ',
- 'I', ' ', 'c', 'a',
- 'n'}
- }
- };
- // clang-format on
-
- PacketFragments& fragments =
- VersionHasIetfQuicFrames(framer_.transport_version())
- ? packet_ietf
- : (framer_.version().HasIetfInvariantHeader() ? packet46 : packet);
- std::unique_ptr<QuicEncryptedPacket> encrypted(
- AssemblePacketFromFragments(fragments));
- EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
-
- EXPECT_THAT(framer_.error(), IsQuicNoError());
- ASSERT_TRUE(visitor_.header_.get());
- EXPECT_TRUE(CheckDecryption(
- *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
- PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
-
- EXPECT_EQ(0u, visitor_.stream_frames_.size());
- EXPECT_EQ(0x11u, static_cast<unsigned>(
- visitor_.connection_close_frame_.wire_error_code));
- EXPECT_EQ("because I can", visitor_.connection_close_frame_.error_details);
- if (VersionHasIetfQuicFrames(framer_.transport_version())) {
- EXPECT_EQ(0x1234u,
- visitor_.connection_close_frame_.transport_close_frame_type);
- EXPECT_EQ(115u, visitor_.connection_close_frame_.quic_error_code);
- } else {
- // For Google QUIC frame, |quic_error_code| and |wire_error_code| has the
- // same value.
- EXPECT_EQ(0x11u, static_cast<unsigned>(
- visitor_.connection_close_frame_.quic_error_code));
- }
-
- ASSERT_EQ(0u, visitor_.ack_frames_.size());
-
- CheckFramingBoundaries(fragments, QUIC_INVALID_CONNECTION_CLOSE_DATA);
-}
-
-TEST_P(QuicFramerTest, ConnectionCloseFrameWithUnknownErrorCode) {
- SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
- // clang-format off
- PacketFragments packet = {
- // public flags (8 byte connection_id)
- {"",
- {0x28}},
- // connection_id
- {"",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // packet number
- {"",
- {0x12, 0x34, 0x56, 0x78}},
- // frame type (connection close frame)
- {"",
- {0x02}},
- // error code larger than QUIC_LAST_ERROR
- {"Unable to read connection close error code.",
- {0x00, 0x00, 0xC0, 0xDE}},
- {"Unable to read connection close error details.",
- {
- // error details length
- 0x0, 0x0d,
- // error details
- 'b', 'e', 'c', 'a',
- 'u', 's', 'e', ' ',
- 'I', ' ', 'c', 'a',
- 'n'}
- }
- };
-
- PacketFragments packet46 = {
- // type (short header, 4 byte packet number)
- {"",
- {0x43}},
- // connection_id
- {"",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // packet number
- {"",
- {0x12, 0x34, 0x56, 0x78}},
- // frame type (connection close frame)
- {"",
- {0x02}},
- // error code larger than QUIC_LAST_ERROR
- {"Unable to read connection close error code.",
- {0x00, 0x00, 0xC0, 0xDE}},
- {"Unable to read connection close error details.",
- {
- // error details length
- 0x0, 0x0d,
- // error details
- 'b', 'e', 'c', 'a',
- 'u', 's', 'e', ' ',
- 'I', ' ', 'c', 'a',
- 'n'}
- }
- };
-
- PacketFragments packet_ietf = {
- // type (short header, 4 byte packet number)
- {"",
- {0x43}},
- // connection_id
- {"",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // packet number
- {"",
- {0x12, 0x34, 0x56, 0x78}},
- // frame type (IETF Transport CONNECTION_CLOSE frame)
- {"",
- {0x1c}},
- // error code
- {"Unable to read connection close error code.",
- {kVarInt62FourBytes + 0x00, 0x00, 0xC0, 0xDE}},
- {"Unable to read connection close frame type.",
- {kVarInt62TwoBytes + 0x12, 0x34 }},
- {"Unable to read connection close error details.",
- {
- // error details length
- kVarInt62OneByte + 0x11,
- // error details with QuicErrorCode larger than QUIC_LAST_ERROR
- '8', '4', '9', ':',
- 'b', 'e', 'c', 'a',
- 'u', 's', 'e', ' ',
- 'I', ' ', 'c', 'a',
- 'n'}
- }
- };
- // clang-format on
-
- PacketFragments& fragments =
- VersionHasIetfQuicFrames(framer_.transport_version())
- ? packet_ietf
- : (framer_.version().HasIetfInvariantHeader() ? packet46 : packet);
- std::unique_ptr<QuicEncryptedPacket> encrypted(
- AssemblePacketFromFragments(fragments));
- EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
-
- EXPECT_THAT(framer_.error(), IsQuicNoError());
- ASSERT_TRUE(visitor_.header_.get());
- EXPECT_TRUE(CheckDecryption(
- *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
- PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
-
- EXPECT_EQ(0u, visitor_.stream_frames_.size());
- EXPECT_EQ("because I can", visitor_.connection_close_frame_.error_details);
- if (VersionHasIetfQuicFrames(framer_.transport_version())) {
- EXPECT_EQ(0x1234u,
- visitor_.connection_close_frame_.transport_close_frame_type);
- EXPECT_EQ(0xC0DEu, visitor_.connection_close_frame_.wire_error_code);
- EXPECT_EQ(849u, visitor_.connection_close_frame_.quic_error_code);
- } else {
- // For Google QUIC frame, |quic_error_code| and |wire_error_code| has the
- // same value.
- EXPECT_EQ(0xC0DEu, visitor_.connection_close_frame_.wire_error_code);
- EXPECT_EQ(0xC0DEu, visitor_.connection_close_frame_.quic_error_code);
- }
-
- ASSERT_EQ(0u, visitor_.ack_frames_.size());
-
- CheckFramingBoundaries(fragments, QUIC_INVALID_CONNECTION_CLOSE_DATA);
-}
-
-// As above, but checks that for Google-QUIC, if there happens
-// to be an ErrorCode string at the start of the details, it is
-// NOT extracted/parsed/folded/spindled/and/mutilated.
-TEST_P(QuicFramerTest, ConnectionCloseFrameWithExtractedInfoIgnoreGCuic) {
- SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-
- // clang-format off
- PacketFragments packet = {
- // public flags (8 byte connection_id)
- {"",
- {0x28}},
- // connection_id
- {"",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // packet number
- {"",
- {0x12, 0x34, 0x56, 0x78}},
- // frame type (connection close frame)
- {"",
- {0x02}},
- // error code
- {"Unable to read connection close error code.",
- {0x00, 0x00, 0x00, 0x11}},
- {"Unable to read connection close error details.",
- {
- // error details length
- 0x0, 0x13,
- // error details
- '1', '7', '7', '6',
- '7', ':', 'b', 'e',
- 'c', 'a', 'u', 's',
- 'e', ' ', 'I', ' ',
- 'c', 'a', 'n'}
- }
- };
-
- PacketFragments packet46 = {
- // type (short header, 4 byte packet number)
- {"",
- {0x43}},
- // connection_id
- {"",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // packet number
- {"",
- {0x12, 0x34, 0x56, 0x78}},
- // frame type (connection close frame)
- {"",
- {0x02}},
- // error code
- {"Unable to read connection close error code.",
- {0x00, 0x00, 0x00, 0x11}},
- {"Unable to read connection close error details.",
- {
- // error details length
- 0x0, 0x13,
- // error details
- '1', '7', '7', '6',
- '7', ':', 'b', 'e',
- 'c', 'a', 'u', 's',
- 'e', ' ', 'I', ' ',
- 'c', 'a', 'n'}
- }
- };
-
- PacketFragments packet_ietf = {
- // type (short header, 4 byte packet number)
- {"",
- {0x43}},
- // connection_id
- {"",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // packet number
- {"",
- {0x12, 0x34, 0x56, 0x78}},
- // frame type (IETF Transport CONNECTION_CLOSE frame)
- {"",
- {0x1c}},
- // error code
- {"Unable to read connection close error code.",
- {kVarInt62OneByte + 0x11}},
- {"Unable to read connection close frame type.",
- {kVarInt62TwoBytes + 0x12, 0x34 }},
- {"Unable to read connection close error details.",
- {
- // error details length
- kVarInt62OneByte + 0x13,
- // error details
- '1', '7', '7', '6',
- '7', ':', 'b', 'e',
- 'c', 'a', 'u', 's',
- 'e', ' ', 'I', ' ',
- 'c', 'a', 'n'}
- }
- };
- // clang-format on
-
- PacketFragments& fragments =
- VersionHasIetfQuicFrames(framer_.transport_version())
- ? packet_ietf
- : (framer_.version().HasIetfInvariantHeader() ? packet46 : packet);
- std::unique_ptr<QuicEncryptedPacket> encrypted(
- AssemblePacketFromFragments(fragments));
- EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
-
- EXPECT_THAT(framer_.error(), IsQuicNoError());
- ASSERT_TRUE(visitor_.header_.get());
- EXPECT_TRUE(CheckDecryption(
- *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
- PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
-
- EXPECT_EQ(0u, visitor_.stream_frames_.size());
- EXPECT_EQ(0x11u, static_cast<unsigned>(
- visitor_.connection_close_frame_.wire_error_code));
-
- if (VersionHasIetfQuicFrames(framer_.transport_version())) {
- EXPECT_EQ(0x1234u,
- visitor_.connection_close_frame_.transport_close_frame_type);
- EXPECT_EQ(17767u, visitor_.connection_close_frame_.quic_error_code);
- EXPECT_EQ("because I can", visitor_.connection_close_frame_.error_details);
- } else {
- EXPECT_EQ(0x11u, visitor_.connection_close_frame_.quic_error_code);
- // Error code is not prepended in GQUIC, so it is not removed and should
- // remain in the reason phrase.
- EXPECT_EQ("17767:because I can",
- visitor_.connection_close_frame_.error_details);
- }
-
- ASSERT_EQ(0u, visitor_.ack_frames_.size());
-
- CheckFramingBoundaries(fragments, QUIC_INVALID_CONNECTION_CLOSE_DATA);
-}
-
-// Test the CONNECTION_CLOSE/Application variant.
-TEST_P(QuicFramerTest, ApplicationCloseFrame) {
- if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
- // This frame is only in IETF QUIC.
- return;
- }
- SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-
- // clang-format off
- PacketFragments packet_ietf = {
- // type (short header, 4 byte packet number)
- {"",
- {0x43}},
- // connection_id
- {"",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // packet number
- {"",
- {0x12, 0x34, 0x56, 0x78}},
- // frame type (IETF_CONNECTION_CLOSE/Application frame)
- {"",
- {0x1d}},
- // error code
- {"Unable to read connection close error code.",
- {kVarInt62TwoBytes + 0x00, 0x11}},
- {"Unable to read connection close error details.",
- {
- // error details length
- kVarInt62OneByte + 0x0d,
- // error details
- 'b', 'e', 'c', 'a',
- 'u', 's', 'e', ' ',
- 'I', ' ', 'c', 'a',
- 'n'}
- }
- };
- // clang-format on
-
- std::unique_ptr<QuicEncryptedPacket> encrypted(
- AssemblePacketFromFragments(packet_ietf));
- EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
-
- EXPECT_THAT(framer_.error(), IsQuicNoError());
- ASSERT_TRUE(visitor_.header_.get());
- EXPECT_TRUE(CheckDecryption(
- *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
- PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
-
- EXPECT_EQ(0u, visitor_.stream_frames_.size());
-
- EXPECT_EQ(IETF_QUIC_APPLICATION_CONNECTION_CLOSE,
- visitor_.connection_close_frame_.close_type);
- EXPECT_EQ(122u, visitor_.connection_close_frame_.quic_error_code);
- EXPECT_EQ(0x11u, visitor_.connection_close_frame_.wire_error_code);
- EXPECT_EQ("because I can", visitor_.connection_close_frame_.error_details);
-
- ASSERT_EQ(0u, visitor_.ack_frames_.size());
-
- CheckFramingBoundaries(packet_ietf, QUIC_INVALID_CONNECTION_CLOSE_DATA);
-}
-
-// Check that we can extract an error code from an application close.
-TEST_P(QuicFramerTest, ApplicationCloseFrameExtract) {
- if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
- // This frame is only in IETF QUIC.
- return;
- }
- SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-
- // clang-format off
- PacketFragments packet_ietf = {
- // type (short header, 4 byte packet number)
- {"",
- {0x43}},
- // connection_id
- {"",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // packet number
- {"",
- {0x12, 0x34, 0x56, 0x78}},
- // frame type (IETF_CONNECTION_CLOSE/Application frame)
- {"",
- {0x1d}},
- // error code
- {"Unable to read connection close error code.",
- {kVarInt62OneByte + 0x11}},
- {"Unable to read connection close error details.",
- {
- // error details length
- kVarInt62OneByte + 0x13,
- // error details
- '1', '7', '7', '6',
- '7', ':', 'b', 'e',
- 'c', 'a', 'u', 's',
- 'e', ' ', 'I', ' ',
- 'c', 'a', 'n'}
- }
- };
- // clang-format on
-
- std::unique_ptr<QuicEncryptedPacket> encrypted(
- AssemblePacketFromFragments(packet_ietf));
- EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
-
- EXPECT_THAT(framer_.error(), IsQuicNoError());
- ASSERT_TRUE(visitor_.header_.get());
- EXPECT_TRUE(CheckDecryption(
- *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
- PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
-
- EXPECT_EQ(0u, visitor_.stream_frames_.size());
-
- EXPECT_EQ(IETF_QUIC_APPLICATION_CONNECTION_CLOSE,
- visitor_.connection_close_frame_.close_type);
- EXPECT_EQ(17767u, visitor_.connection_close_frame_.quic_error_code);
- EXPECT_EQ(0x11u, visitor_.connection_close_frame_.wire_error_code);
- EXPECT_EQ("because I can", visitor_.connection_close_frame_.error_details);
-
- ASSERT_EQ(0u, visitor_.ack_frames_.size());
-
- CheckFramingBoundaries(packet_ietf, QUIC_INVALID_CONNECTION_CLOSE_DATA);
-}
-
-TEST_P(QuicFramerTest, GoAwayFrame) {
- if (VersionHasIetfQuicFrames(framer_.transport_version())) {
- // This frame is not in IETF QUIC.
- return;
- }
- SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
- // clang-format off
- PacketFragments packet = {
- // public flags (8 byte connection_id)
- {"",
- {0x28}},
- // connection_id
- {"",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // packet number
- {"",
- {0x12, 0x34, 0x56, 0x78}},
- // frame type (go away frame)
- {"",
- {0x03}},
- // error code
- {"Unable to read go away error code.",
- {0x00, 0x00, 0x00, 0x09}},
- // stream id
- {"Unable to read last good stream id.",
- {0x01, 0x02, 0x03, 0x04}},
- // stream id
- {"Unable to read goaway reason.",
- {
- // error details length
- 0x0, 0x0d,
- // error details
- 'b', 'e', 'c', 'a',
- 'u', 's', 'e', ' ',
- 'I', ' ', 'c', 'a',
- 'n'}
- }
- };
-
- PacketFragments packet46 = {
- // type (short header, 4 byte packet number)
- {"",
- {0x43}},
- // connection_id
- {"",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // packet number
- {"",
- {0x12, 0x34, 0x56, 0x78}},
- // frame type (go away frame)
- {"",
- {0x03}},
- // error code
- {"Unable to read go away error code.",
- {0x00, 0x00, 0x00, 0x09}},
- // stream id
- {"Unable to read last good stream id.",
- {0x01, 0x02, 0x03, 0x04}},
- // stream id
- {"Unable to read goaway reason.",
- {
- // error details length
- 0x0, 0x0d,
- // error details
- 'b', 'e', 'c', 'a',
- 'u', 's', 'e', ' ',
- 'I', ' ', 'c', 'a',
- 'n'}
- }
- };
- // clang-format on
-
- PacketFragments& fragments =
- framer_.version().HasIetfInvariantHeader() ? packet46 : packet;
- std::unique_ptr<QuicEncryptedPacket> encrypted(
- AssemblePacketFromFragments(fragments));
- EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
-
- EXPECT_THAT(framer_.error(), IsQuicNoError());
- ASSERT_TRUE(visitor_.header_.get());
- EXPECT_TRUE(CheckDecryption(
- *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
- PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
-
- EXPECT_EQ(kStreamId, visitor_.goaway_frame_.last_good_stream_id);
- EXPECT_EQ(0x9u, visitor_.goaway_frame_.error_code);
- EXPECT_EQ("because I can", visitor_.goaway_frame_.reason_phrase);
-
- CheckFramingBoundaries(fragments, QUIC_INVALID_GOAWAY_DATA);
-}
-
-TEST_P(QuicFramerTest, GoAwayFrameWithUnknownErrorCode) {
- if (VersionHasIetfQuicFrames(framer_.transport_version())) {
- // This frame is not in IETF QUIC.
- return;
- }
- SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
- // clang-format off
- PacketFragments packet = {
- // public flags (8 byte connection_id)
- {"",
- {0x28}},
- // connection_id
- {"",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // packet number
- {"",
- {0x12, 0x34, 0x56, 0x78}},
- // frame type (go away frame)
- {"",
- {0x03}},
- // error code larger than QUIC_LAST_ERROR
- {"Unable to read go away error code.",
- {0x00, 0x00, 0xC0, 0xDE}},
- // stream id
- {"Unable to read last good stream id.",
- {0x01, 0x02, 0x03, 0x04}},
- // stream id
- {"Unable to read goaway reason.",
- {
- // error details length
- 0x0, 0x0d,
- // error details
- 'b', 'e', 'c', 'a',
- 'u', 's', 'e', ' ',
- 'I', ' ', 'c', 'a',
- 'n'}
- }
- };
-
- PacketFragments packet46 = {
- // type (short header, 4 byte packet number)
- {"",
- {0x43}},
- // connection_id
- {"",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // packet number
- {"",
- {0x12, 0x34, 0x56, 0x78}},
- // frame type (go away frame)
- {"",
- {0x03}},
- // error code larger than QUIC_LAST_ERROR
- {"Unable to read go away error code.",
- {0x00, 0x00, 0xC0, 0xDE}},
- // stream id
- {"Unable to read last good stream id.",
- {0x01, 0x02, 0x03, 0x04}},
- // stream id
- {"Unable to read goaway reason.",
- {
- // error details length
- 0x0, 0x0d,
- // error details
- 'b', 'e', 'c', 'a',
- 'u', 's', 'e', ' ',
- 'I', ' ', 'c', 'a',
- 'n'}
- }
- };
- // clang-format on
-
- PacketFragments& fragments =
- framer_.version().HasIetfInvariantHeader() ? packet46 : packet;
- std::unique_ptr<QuicEncryptedPacket> encrypted(
- AssemblePacketFromFragments(fragments));
- EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
-
- EXPECT_THAT(framer_.error(), IsQuicNoError());
- ASSERT_TRUE(visitor_.header_.get());
- EXPECT_TRUE(CheckDecryption(
- *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
- PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
-
- EXPECT_EQ(kStreamId, visitor_.goaway_frame_.last_good_stream_id);
- EXPECT_EQ(0xC0DE, visitor_.goaway_frame_.error_code);
- EXPECT_EQ("because I can", visitor_.goaway_frame_.reason_phrase);
-
- CheckFramingBoundaries(fragments, QUIC_INVALID_GOAWAY_DATA);
-}
-
-TEST_P(QuicFramerTest, WindowUpdateFrame) {
- if (VersionHasIetfQuicFrames(framer_.transport_version())) {
- // This frame is not in IETF QUIC, see MaxDataFrame and MaxStreamDataFrame
- // for IETF QUIC equivalents.
- return;
- }
- SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
- // clang-format off
- PacketFragments packet = {
- // public flags (8 byte connection_id)
- {"",
- {0x28}},
- // connection_id
- {"",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // packet number
- {"",
- {0x12, 0x34, 0x56, 0x78}},
- // frame type (window update frame)
- {"",
- {0x04}},
- // stream id
- {"Unable to read stream_id.",
- {0x01, 0x02, 0x03, 0x04}},
- // byte offset
- {"Unable to read window byte_offset.",
- {0x3A, 0x98, 0xFE, 0xDC,
- 0x32, 0x10, 0x76, 0x54}},
- };
-
- PacketFragments packet46 = {
- // type (short header, 4 byte packet number)
- {"",
- {0x43}},
- // connection_id
- {"",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // packet number
- {"",
- {0x12, 0x34, 0x56, 0x78}},
- // frame type (window update frame)
- {"",
- {0x04}},
- // stream id
- {"Unable to read stream_id.",
- {0x01, 0x02, 0x03, 0x04}},
- // byte offset
- {"Unable to read window byte_offset.",
- {0x3A, 0x98, 0xFE, 0xDC,
- 0x32, 0x10, 0x76, 0x54}},
- };
-
- // clang-format on
-
- PacketFragments& fragments =
- framer_.version().HasIetfInvariantHeader() ? packet46 : packet;
- std::unique_ptr<QuicEncryptedPacket> encrypted(
- AssemblePacketFromFragments(fragments));
- EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
-
- EXPECT_THAT(framer_.error(), IsQuicNoError());
- ASSERT_TRUE(visitor_.header_.get());
- EXPECT_TRUE(CheckDecryption(
- *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
- PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
-
- EXPECT_EQ(kStreamId, visitor_.window_update_frame_.stream_id);
- EXPECT_EQ(kStreamOffset, visitor_.window_update_frame_.max_data);
-
- CheckFramingBoundaries(fragments, QUIC_INVALID_WINDOW_UPDATE_DATA);
-}
-
-TEST_P(QuicFramerTest, MaxDataFrame) {
- if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
- // This frame is available only in IETF QUIC.
- return;
- }
- SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
- // clang-format off
- PacketFragments packet_ietf = {
- // type (short header, 4 byte packet number)
- {"",
- {0x43}},
- // connection_id
- {"",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // packet number
- {"",
- {0x12, 0x34, 0x56, 0x78}},
- // frame type (IETF_MAX_DATA frame)
- {"",
- {0x10}},
- // byte offset
- {"Can not read MAX_DATA byte-offset",
- {kVarInt62EightBytes + 0x3A, 0x98, 0xFE, 0xDC,
- 0x32, 0x10, 0x76, 0x54}},
- };
- // clang-format on
-
- std::unique_ptr<QuicEncryptedPacket> encrypted(
- AssemblePacketFromFragments(packet_ietf));
- EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
-
- EXPECT_THAT(framer_.error(), IsQuicNoError());
- ASSERT_TRUE(visitor_.header_.get());
- EXPECT_TRUE(CheckDecryption(
- *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
- PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
-
- EXPECT_EQ(QuicUtils::GetInvalidStreamId(framer_.transport_version()),
- visitor_.window_update_frame_.stream_id);
- EXPECT_EQ(kStreamOffset, visitor_.window_update_frame_.max_data);
-
- CheckFramingBoundaries(packet_ietf, QUIC_INVALID_MAX_DATA_FRAME_DATA);
-}
-
-TEST_P(QuicFramerTest, MaxStreamDataFrame) {
- if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
- // This frame available only in IETF QUIC.
- return;
- }
- SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
- // clang-format off
- PacketFragments packet_ietf = {
- // type (short header, 4 byte packet number)
- {"",
- {0x43}},
- // connection_id
- {"",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // packet number
- {"",
- {0x12, 0x34, 0x56, 0x78}},
- // frame type (IETF_MAX_STREAM_DATA frame)
- {"",
- {0x11}},
- // stream id
- {"Unable to read IETF_MAX_STREAM_DATA frame stream id/count.",
- {kVarInt62FourBytes + 0x01, 0x02, 0x03, 0x04}},
- // byte offset
- {"Can not read MAX_STREAM_DATA byte-count",
- {kVarInt62EightBytes + 0x3A, 0x98, 0xFE, 0xDC,
- 0x32, 0x10, 0x76, 0x54}},
- };
- // clang-format on
-
- std::unique_ptr<QuicEncryptedPacket> encrypted(
- AssemblePacketFromFragments(packet_ietf));
- EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
-
- EXPECT_THAT(framer_.error(), IsQuicNoError());
- ASSERT_TRUE(visitor_.header_.get());
- EXPECT_TRUE(CheckDecryption(
- *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
- PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
-
- EXPECT_EQ(kStreamId, visitor_.window_update_frame_.stream_id);
- EXPECT_EQ(kStreamOffset, visitor_.window_update_frame_.max_data);
-
- CheckFramingBoundaries(packet_ietf, QUIC_INVALID_MAX_STREAM_DATA_FRAME_DATA);
-}
-
-TEST_P(QuicFramerTest, BlockedFrame) {
- SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
- // clang-format off
- PacketFragments packet = {
- // public flags (8 byte connection_id)
- {"",
- {0x28}},
- // connection_id
- {"",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // packet number
- {"",
- {0x12, 0x34, 0x56, 0x78}},
- // frame type (blocked frame)
- {"",
- {0x05}},
- // stream id
- {"Unable to read stream_id.",
- {0x01, 0x02, 0x03, 0x04}},
- };
-
- PacketFragments packet46 = {
- // type (short header, 4 byte packet number)
- {"",
- {0x43}},
- // connection_id
- {"",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // packet number
- {"",
- {0x12, 0x34, 0x56, 0x78}},
- // frame type (blocked frame)
- {"",
- {0x05}},
- // stream id
- {"Unable to read stream_id.",
- {0x01, 0x02, 0x03, 0x04}},
- };
-
- PacketFragments packet_ietf = {
- // type (short header, 4 byte packet number)
- {"",
- {0x43}},
- // connection_id
- {"",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // packet number
- {"",
- {0x12, 0x34, 0x56, 0x78}},
- // frame type (IETF_STREAM_BLOCKED frame)
- {"",
- {0x15}},
- // stream id
- {"Unable to read IETF_STREAM_DATA_BLOCKED frame stream id/count.",
- {kVarInt62FourBytes + 0x01, 0x02, 0x03, 0x04}},
- // Offset
- {"Can not read stream blocked offset.",
- {kVarInt62EightBytes + 0x3a, 0x98, 0xFE, 0xDC, 0x32, 0x10, 0x76, 0x54}},
- };
- // clang-format on
-
- PacketFragments& fragments =
- VersionHasIetfQuicFrames(framer_.transport_version())
- ? packet_ietf
- : (framer_.version().HasIetfInvariantHeader() ? packet46 : packet);
- std::unique_ptr<QuicEncryptedPacket> encrypted(
- AssemblePacketFromFragments(fragments));
- EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
-
- EXPECT_THAT(framer_.error(), IsQuicNoError());
- ASSERT_TRUE(visitor_.header_.get());
- EXPECT_TRUE(CheckDecryption(
- *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
- PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
-
- if (VersionHasIetfQuicFrames(framer_.transport_version())) {
- EXPECT_EQ(kStreamOffset, visitor_.blocked_frame_.offset);
- } else {
- EXPECT_EQ(0u, visitor_.blocked_frame_.offset);
- }
- EXPECT_EQ(kStreamId, visitor_.blocked_frame_.stream_id);
-
- if (VersionHasIetfQuicFrames(framer_.transport_version())) {
- CheckFramingBoundaries(fragments, QUIC_INVALID_STREAM_BLOCKED_DATA);
- } else {
- CheckFramingBoundaries(fragments, QUIC_INVALID_BLOCKED_DATA);
- }
-}
-
-TEST_P(QuicFramerTest, PingFrame) {
- SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
- // clang-format off
- unsigned char packet[] = {
- // public flags (8 byte connection_id)
- 0x28,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
-
- // frame type (ping frame)
- 0x07,
- };
-
- unsigned char packet46[] = {
- // type (short header, 4 byte packet number)
- 0x43,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
-
- // frame type
- 0x07,
- };
-
- unsigned char packet_ietf[] = {
- // type (short header, 4 byte packet number)
- 0x43,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
-
- // frame type (IETF_PING frame)
- 0x01,
- };
- // clang-format on
-
- QuicEncryptedPacket encrypted(
- AsChars(VersionHasIetfQuicFrames(framer_.transport_version())
- ? packet_ietf
- : (framer_.version().HasIetfInvariantHeader() ? packet46
- : packet)),
- VersionHasIetfQuicFrames(framer_.transport_version())
- ? ABSL_ARRAYSIZE(packet_ietf)
- : (framer_.version().HasIetfInvariantHeader()
- ? ABSL_ARRAYSIZE(packet46)
- : ABSL_ARRAYSIZE(packet)),
- false);
- EXPECT_TRUE(framer_.ProcessPacket(encrypted));
-
- EXPECT_THAT(framer_.error(), IsQuicNoError());
- ASSERT_TRUE(visitor_.header_.get());
- EXPECT_TRUE(CheckDecryption(
- encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
- PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
-
- EXPECT_EQ(1u, visitor_.ping_frames_.size());
-
- // No need to check the PING frame boundaries because it has no payload.
-}
-
-TEST_P(QuicFramerTest, HandshakeDoneFrame) {
- SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
- // clang-format off
- unsigned char packet[] = {
- // type (short header, 4 byte packet number)
- 0x43,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
-
- // frame type (Handshake done frame)
- 0x1e,
- };
- // clang-format on
-
- if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
- return;
- }
-
- QuicEncryptedPacket encrypted(AsChars(packet), ABSL_ARRAYSIZE(packet), false);
- EXPECT_TRUE(framer_.ProcessPacket(encrypted));
-
- EXPECT_THAT(framer_.error(), IsQuicNoError());
- ASSERT_TRUE(visitor_.header_.get());
- EXPECT_TRUE(CheckDecryption(
- encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
- PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
-
- EXPECT_EQ(1u, visitor_.handshake_done_frames_.size());
-}
-
-TEST_P(QuicFramerTest, ParseAckFrequencyFrame) {
- SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
- // clang-format off
- unsigned char packet[] = {
- // type (short header, 4 byte packet number)
- 0x43,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
-
- // ack frequency frame type (which needs two bytes as it is > 0x3F)
- 0x40, 0xAF,
- // sequence_number
- 0x11,
- // packet_tolerance
- 0x02,
- // max_ack_delay_us = 2'5000 us
- 0x80, 0x00, 0x61, 0xA8,
- // ignore_order
- 0x01
- };
- // clang-format on
-
- if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
- return;
- }
-
- QuicEncryptedPacket encrypted(AsChars(packet), ABSL_ARRAYSIZE(packet), false);
- EXPECT_TRUE(framer_.ProcessPacket(encrypted));
-
- EXPECT_THAT(framer_.error(), IsQuicNoError());
- ASSERT_TRUE(visitor_.header_.get());
- EXPECT_TRUE(CheckDecryption(
- encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
- PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
-
- ASSERT_EQ(1u, visitor_.ack_frequency_frames_.size());
- const auto& frame = visitor_.ack_frequency_frames_.front();
- EXPECT_EQ(17u, frame->sequence_number);
- EXPECT_EQ(2u, frame->packet_tolerance);
- EXPECT_EQ(2'5000u, frame->max_ack_delay.ToMicroseconds());
- EXPECT_EQ(true, frame->ignore_order);
-}
-
-TEST_P(QuicFramerTest, MessageFrame) {
- if (!VersionSupportsMessageFrames(framer_.transport_version())) {
- return;
- }
- SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
- // clang-format off
- PacketFragments packet46 = {
- // type (short header, 4 byte packet number)
- {"",
- {0x43}},
- // connection_id
- {"",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // packet number
- {"",
- {0x12, 0x34, 0x56, 0x78}},
- // message frame type.
- {"",
- { 0x21 }},
- // message length
- {"Unable to read message length",
- {0x07}},
- // message data
- {"Unable to read message data",
- {'m', 'e', 's', 's', 'a', 'g', 'e'}},
- // message frame no length.
- {"",
- { 0x20 }},
- // message data
- {{},
- {'m', 'e', 's', 's', 'a', 'g', 'e', '2'}},
- };
- PacketFragments packet_ietf = {
- // type (short header, 4 byte packet number)
- {"",
- {0x43}},
- // connection_id
- {"",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // packet number
- {"",
- {0x12, 0x34, 0x56, 0x78}},
- // message frame type.
- {"",
- { 0x31 }},
- // message length
- {"Unable to read message length",
- {0x07}},
- // message data
- {"Unable to read message data",
- {'m', 'e', 's', 's', 'a', 'g', 'e'}},
- // message frame no length.
- {"",
- { 0x30 }},
- // message data
- {{},
- {'m', 'e', 's', 's', 'a', 'g', 'e', '2'}},
- };
- // clang-format on
-
- std::unique_ptr<QuicEncryptedPacket> encrypted;
- if (VersionHasIetfQuicFrames(framer_.transport_version())) {
- encrypted = AssemblePacketFromFragments(packet_ietf);
- } else {
- encrypted = AssemblePacketFromFragments(packet46);
- }
- EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
-
- EXPECT_THAT(framer_.error(), IsQuicNoError());
- ASSERT_TRUE(visitor_.header_.get());
- EXPECT_TRUE(CheckDecryption(
- *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
- PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
-
- ASSERT_EQ(2u, visitor_.message_frames_.size());
- EXPECT_EQ(7u, visitor_.message_frames_[0]->message_length);
- EXPECT_EQ(8u, visitor_.message_frames_[1]->message_length);
-
- if (VersionHasIetfQuicFrames(framer_.transport_version())) {
- CheckFramingBoundaries(packet_ietf, QUIC_INVALID_MESSAGE_DATA);
- } else {
- CheckFramingBoundaries(packet46, QUIC_INVALID_MESSAGE_DATA);
- }
-}
-
-TEST_P(QuicFramerTest, PublicResetPacketV33) {
- // clang-format off
- PacketFragments packet = {
- // public flags (public reset, 8 byte connection_id)
- {"",
- {0x0A}},
- // connection_id
- {"",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- {"Unable to read reset message.",
- {
- // message tag (kPRST)
- 'P', 'R', 'S', 'T',
- // num_entries (2) + padding
- 0x02, 0x00, 0x00, 0x00,
- // tag kRNON
- 'R', 'N', 'O', 'N',
- // end offset 8
- 0x08, 0x00, 0x00, 0x00,
- // tag kRSEQ
- 'R', 'S', 'E', 'Q',
- // end offset 16
- 0x10, 0x00, 0x00, 0x00,
- // nonce proof
- 0x89, 0x67, 0x45, 0x23,
- 0x01, 0xEF, 0xCD, 0xAB,
- // rejected packet number
- 0xBC, 0x9A, 0x78, 0x56,
- 0x34, 0x12, 0x00, 0x00,
- }
- }
- };
- // clang-format on
- if (framer_.version().HasIetfInvariantHeader()) {
- return;
- }
-
- std::unique_ptr<QuicEncryptedPacket> encrypted(
- AssemblePacketFromFragments(packet));
- EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
- ASSERT_THAT(framer_.error(), IsQuicNoError());
- ASSERT_TRUE(visitor_.public_reset_packet_.get());
- EXPECT_EQ(FramerTestConnectionId(),
- visitor_.public_reset_packet_->connection_id);
- EXPECT_EQ(kNonceProof, visitor_.public_reset_packet_->nonce_proof);
- EXPECT_EQ(
- IpAddressFamily::IP_UNSPEC,
- visitor_.public_reset_packet_->client_address.host().address_family());
-
- CheckFramingBoundaries(packet, QUIC_INVALID_PUBLIC_RST_PACKET);
-}
-
-TEST_P(QuicFramerTest, PublicResetPacket) {
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
-
- // clang-format off
- PacketFragments packet = {
- // public flags (public reset, 8 byte connection_id)
- {"",
- {0x0E}},
- // connection_id
- {"",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- {"Unable to read reset message.",
- {
- // message tag (kPRST)
- 'P', 'R', 'S', 'T',
- // num_entries (2) + padding
- 0x02, 0x00, 0x00, 0x00,
- // tag kRNON
- 'R', 'N', 'O', 'N',
- // end offset 8
- 0x08, 0x00, 0x00, 0x00,
- // tag kRSEQ
- 'R', 'S', 'E', 'Q',
- // end offset 16
- 0x10, 0x00, 0x00, 0x00,
- // nonce proof
- 0x89, 0x67, 0x45, 0x23,
- 0x01, 0xEF, 0xCD, 0xAB,
- // rejected packet number
- 0xBC, 0x9A, 0x78, 0x56,
- 0x34, 0x12, 0x00, 0x00,
- }
- }
- };
- // clang-format on
-
- if (framer_.version().HasIetfInvariantHeader()) {
- return;
- }
-
- std::unique_ptr<QuicEncryptedPacket> encrypted(
- AssemblePacketFromFragments(packet));
- EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
- ASSERT_THAT(framer_.error(), IsQuicNoError());
- ASSERT_TRUE(visitor_.public_reset_packet_.get());
- EXPECT_EQ(FramerTestConnectionId(),
- visitor_.public_reset_packet_->connection_id);
- EXPECT_EQ(kNonceProof, visitor_.public_reset_packet_->nonce_proof);
- EXPECT_EQ(
- IpAddressFamily::IP_UNSPEC,
- visitor_.public_reset_packet_->client_address.host().address_family());
-
- CheckFramingBoundaries(packet, QUIC_INVALID_PUBLIC_RST_PACKET);
-}
-
-TEST_P(QuicFramerTest, PublicResetPacketWithTrailingJunk) {
- // clang-format off
- unsigned char packet[] = {
- // public flags (public reset, 8 byte connection_id)
- 0x0A,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // message tag (kPRST)
- 'P', 'R', 'S', 'T',
- // num_entries (2) + padding
- 0x02, 0x00, 0x00, 0x00,
- // tag kRNON
- 'R', 'N', 'O', 'N',
- // end offset 8
- 0x08, 0x00, 0x00, 0x00,
- // tag kRSEQ
- 'R', 'S', 'E', 'Q',
- // end offset 16
- 0x10, 0x00, 0x00, 0x00,
- // nonce proof
- 0x89, 0x67, 0x45, 0x23,
- 0x01, 0xEF, 0xCD, 0xAB,
- // rejected packet number
- 0xBC, 0x9A, 0x78, 0x56,
- 0x34, 0x12, 0x00, 0x00,
- // trailing junk
- 'j', 'u', 'n', 'k',
- };
- // clang-format on
- if (framer_.version().HasIetfInvariantHeader()) {
- return;
- }
-
- QuicEncryptedPacket encrypted(AsChars(packet), ABSL_ARRAYSIZE(packet), false);
- EXPECT_FALSE(framer_.ProcessPacket(encrypted));
- ASSERT_THAT(framer_.error(), IsError(QUIC_INVALID_PUBLIC_RST_PACKET));
- EXPECT_EQ("Unable to read reset message.", framer_.detailed_error());
-}
-
-TEST_P(QuicFramerTest, PublicResetPacketWithClientAddress) {
- // clang-format off
- PacketFragments packet = {
- // public flags (public reset, 8 byte connection_id)
- {"",
- {0x0A}},
- // connection_id
- {"",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- {"Unable to read reset message.",
- {
- // message tag (kPRST)
- 'P', 'R', 'S', 'T',
- // num_entries (2) + padding
- 0x03, 0x00, 0x00, 0x00,
- // tag kRNON
- 'R', 'N', 'O', 'N',
- // end offset 8
- 0x08, 0x00, 0x00, 0x00,
- // tag kRSEQ
- 'R', 'S', 'E', 'Q',
- // end offset 16
- 0x10, 0x00, 0x00, 0x00,
- // tag kCADR
- 'C', 'A', 'D', 'R',
- // end offset 24
- 0x18, 0x00, 0x00, 0x00,
- // nonce proof
- 0x89, 0x67, 0x45, 0x23,
- 0x01, 0xEF, 0xCD, 0xAB,
- // rejected packet number
- 0xBC, 0x9A, 0x78, 0x56,
- 0x34, 0x12, 0x00, 0x00,
- // client address: 4.31.198.44:443
- 0x02, 0x00,
- 0x04, 0x1F, 0xC6, 0x2C,
- 0xBB, 0x01,
- }
- }
- };
- // clang-format on
- if (framer_.version().HasIetfInvariantHeader()) {
- return;
- }
-
- std::unique_ptr<QuicEncryptedPacket> encrypted(
- AssemblePacketFromFragments(packet));
- EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
- ASSERT_THAT(framer_.error(), IsQuicNoError());
- ASSERT_TRUE(visitor_.public_reset_packet_.get());
- EXPECT_EQ(FramerTestConnectionId(),
- visitor_.public_reset_packet_->connection_id);
- EXPECT_EQ(kNonceProof, visitor_.public_reset_packet_->nonce_proof);
- EXPECT_EQ("4.31.198.44",
- visitor_.public_reset_packet_->client_address.host().ToString());
- EXPECT_EQ(443, visitor_.public_reset_packet_->client_address.port());
-
- CheckFramingBoundaries(packet, QUIC_INVALID_PUBLIC_RST_PACKET);
-}
-
-TEST_P(QuicFramerTest, IetfStatelessResetPacket) {
- // clang-format off
- unsigned char packet[] = {
- // type (short packet, 1 byte packet number)
- 0x50,
- // Random bytes
- 0x01, 0x11, 0x02, 0x22, 0x03, 0x33, 0x04, 0x44,
- 0x01, 0x11, 0x02, 0x22, 0x03, 0x33, 0x04, 0x44,
- 0x01, 0x11, 0x02, 0x22, 0x03, 0x33, 0x04, 0x44,
- 0x01, 0x11, 0x02, 0x22, 0x03, 0x33, 0x04, 0x44,
- // stateless reset token
- 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
- 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
- };
- // clang-format on
- if (!framer_.version().HasIetfInvariantHeader()) {
- return;
- }
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
- QuicFramerPeer::SetLastSerializedServerConnectionId(&framer_,
- TestConnectionId(0x33));
- decrypter_ = new test::TestDecrypter();
- if (framer_.version().KnowsWhichDecrypterToUse()) {
- framer_.InstallDecrypter(
- ENCRYPTION_INITIAL,
- std::make_unique<NullDecrypter>(Perspective::IS_CLIENT));
- framer_.InstallDecrypter(ENCRYPTION_ZERO_RTT,
- std::unique_ptr<QuicDecrypter>(decrypter_));
- } else {
- framer_.SetDecrypter(ENCRYPTION_INITIAL, std::make_unique<NullDecrypter>(
- Perspective::IS_CLIENT));
- framer_.SetAlternativeDecrypter(
- ENCRYPTION_ZERO_RTT, std::unique_ptr<QuicDecrypter>(decrypter_), false);
- }
- // This packet cannot be decrypted because diversification nonce is missing.
- QuicEncryptedPacket encrypted(AsChars(packet), ABSL_ARRAYSIZE(packet), false);
- EXPECT_TRUE(framer_.ProcessPacket(encrypted));
- ASSERT_THAT(framer_.error(), IsQuicNoError());
- ASSERT_TRUE(visitor_.stateless_reset_packet_.get());
- EXPECT_EQ(kTestStatelessResetToken,
- visitor_.stateless_reset_packet_->stateless_reset_token);
-}
-
-TEST_P(QuicFramerTest, IetfStatelessResetPacketInvalidStatelessResetToken) {
- // clang-format off
- unsigned char packet[] = {
- // type (short packet, 1 byte packet number)
- 0x50,
- // Random bytes
- 0x01, 0x11, 0x02, 0x22, 0x03, 0x33, 0x04, 0x44,
- 0x01, 0x11, 0x02, 0x22, 0x03, 0x33, 0x04, 0x44,
- 0x01, 0x11, 0x02, 0x22, 0x03, 0x33, 0x04, 0x44,
- 0x01, 0x11, 0x02, 0x22, 0x03, 0x33, 0x04, 0x44,
- // stateless reset token
- 0xB6, 0x69, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- };
- // clang-format on
- if (!framer_.version().HasIetfInvariantHeader()) {
- return;
- }
- QuicFramerPeer::SetLastSerializedServerConnectionId(&framer_,
- TestConnectionId(0x33));
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
- decrypter_ = new test::TestDecrypter();
- if (framer_.version().KnowsWhichDecrypterToUse()) {
- framer_.InstallDecrypter(
- ENCRYPTION_INITIAL,
- std::make_unique<NullDecrypter>(Perspective::IS_CLIENT));
- framer_.InstallDecrypter(ENCRYPTION_ZERO_RTT,
- std::unique_ptr<QuicDecrypter>(decrypter_));
- } else {
- framer_.SetDecrypter(ENCRYPTION_INITIAL, std::make_unique<NullDecrypter>(
- Perspective::IS_CLIENT));
- framer_.SetAlternativeDecrypter(
- ENCRYPTION_ZERO_RTT, std::unique_ptr<QuicDecrypter>(decrypter_), false);
- }
- // This packet cannot be decrypted because diversification nonce is missing.
- QuicEncryptedPacket encrypted(AsChars(packet), ABSL_ARRAYSIZE(packet), false);
- EXPECT_FALSE(framer_.ProcessPacket(encrypted));
- EXPECT_THAT(framer_.error(), IsError(QUIC_DECRYPTION_FAILURE));
- ASSERT_FALSE(visitor_.stateless_reset_packet_);
-}
-
-TEST_P(QuicFramerTest, VersionNegotiationPacketClient) {
- // clang-format off
- PacketFragments packet = {
- // public flags (version, 8 byte connection_id)
- {"",
- {0x29}},
- // connection_id
- {"",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // version tag
- {"Unable to read supported version in negotiation.",
- {QUIC_VERSION_BYTES,
- 'Q', '2', '.', '0'}},
- };
-
- PacketFragments packet46 = {
- // type (long header)
- {"",
- {0x8F}},
- // version tag
- {"",
- {0x00, 0x00, 0x00, 0x00}},
- {"",
- {0x05}},
- // connection_id
- {"",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // Supported versions
- {"Unable to read supported version in negotiation.",
- {QUIC_VERSION_BYTES,
- 'Q', '2', '.', '0'}},
- };
-
- PacketFragments packet49 = {
- // type (long header)
- {"",
- {0x8F}},
- // version tag
- {"",
- {0x00, 0x00, 0x00, 0x00}},
- {"",
- {0x08}},
- // connection_id
- {"",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- {"",
- {0x00}},
- // Supported versions
- {"Unable to read supported version in negotiation.",
- {QUIC_VERSION_BYTES,
- 'Q', '2', '.', '0'}},
- };
- // clang-format on
-
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
-
- PacketFragments& fragments =
- framer_.version().HasLongHeaderLengths() ? packet49
- : framer_.version().HasIetfInvariantHeader() ? packet46
- : packet;
- std::unique_ptr<QuicEncryptedPacket> encrypted(
- AssemblePacketFromFragments(fragments));
- EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
- ASSERT_THAT(framer_.error(), IsQuicNoError());
- ASSERT_TRUE(visitor_.version_negotiation_packet_.get());
- EXPECT_EQ(1u, visitor_.version_negotiation_packet_->versions.size());
- EXPECT_EQ(GetParam(), visitor_.version_negotiation_packet_->versions[0]);
-
- // Remove the last version from the packet so that every truncated
- // version of the packet is invalid, otherwise checking boundaries
- // is annoyingly complicated.
- for (size_t i = 0; i < 4; ++i) {
- fragments.back().fragment.pop_back();
- }
- CheckFramingBoundaries(fragments, QUIC_INVALID_VERSION_NEGOTIATION_PACKET);
-}
-
-TEST_P(QuicFramerTest, VersionNegotiationPacketServer) {
- if (!framer_.version().HasIetfInvariantHeader()) {
- return;
- }
-
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
- // clang-format off
- unsigned char packet[] = {
- // public flags (long header with all ignored bits set)
- 0xFF,
- // version
- 0x00, 0x00, 0x00, 0x00,
- // connection ID lengths
- 0x50,
- // destination connection ID
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x11,
- // supported versions
- QUIC_VERSION_BYTES,
- 'Q', '2', '.', '0',
- };
- unsigned char packet2[] = {
- // public flags (long header with all ignored bits set)
- 0xFF,
- // version
- 0x00, 0x00, 0x00, 0x00,
- // destination connection ID length
- 0x08,
- // destination connection ID
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x11,
- // source connection ID length
- 0x00,
- // supported versions
- QUIC_VERSION_BYTES,
- 'Q', '2', '.', '0',
- };
- // clang-format on
- unsigned char* p = packet;
- size_t p_length = ABSL_ARRAYSIZE(packet);
- if (framer_.version().HasLengthPrefixedConnectionIds()) {
- p = packet2;
- p_length = ABSL_ARRAYSIZE(packet2);
- }
-
- QuicEncryptedPacket encrypted(AsChars(p), p_length, false);
- EXPECT_FALSE(framer_.ProcessPacket(encrypted));
- EXPECT_THAT(framer_.error(),
- IsError(QUIC_INVALID_VERSION_NEGOTIATION_PACKET));
- EXPECT_EQ("Server received version negotiation packet.",
- framer_.detailed_error());
- EXPECT_FALSE(visitor_.version_negotiation_packet_.get());
-}
-
-TEST_P(QuicFramerTest, OldVersionNegotiationPacket) {
- // clang-format off
- PacketFragments packet = {
- // public flags (version, 8 byte connection_id)
- {"",
- {0x2D}},
- // connection_id
- {"",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // version tag
- {"Unable to read supported version in negotiation.",
- {QUIC_VERSION_BYTES,
- 'Q', '2', '.', '0'}},
- };
- // clang-format on
-
- if (framer_.version().HasIetfInvariantHeader()) {
- return;
- }
-
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
-
- std::unique_ptr<QuicEncryptedPacket> encrypted(
- AssemblePacketFromFragments(packet));
- EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
- ASSERT_THAT(framer_.error(), IsQuicNoError());
- ASSERT_TRUE(visitor_.version_negotiation_packet_.get());
- EXPECT_EQ(1u, visitor_.version_negotiation_packet_->versions.size());
- EXPECT_EQ(GetParam(), visitor_.version_negotiation_packet_->versions[0]);
-
- // Remove the last version from the packet so that every truncated
- // version of the packet is invalid, otherwise checking boundaries
- // is annoyingly complicated.
- for (size_t i = 0; i < 4; ++i) {
- packet.back().fragment.pop_back();
- }
- CheckFramingBoundaries(packet, QUIC_INVALID_VERSION_NEGOTIATION_PACKET);
-}
-
-TEST_P(QuicFramerTest, ParseIetfRetryPacket) {
- if (!framer_.version().SupportsRetry()) {
- return;
- }
- // IETF RETRY is only sent from client to server.
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
- // clang-format off
- unsigned char packet[] = {
- // public flags (long header with packet type RETRY and ODCIL=8)
- 0xF5,
- // version
- QUIC_VERSION_BYTES,
- // connection ID lengths
- 0x05,
- // source connection ID
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x11,
- // original destination connection ID
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // retry token
- 'H', 'e', 'l', 'l', 'o', ' ', 't', 'h', 'i', 's',
- ' ', 'i', 's', ' ', 'R', 'E', 'T', 'R', 'Y', '!',
- };
- unsigned char packet49[] = {
- // public flags (long header with packet type RETRY)
- 0xF0,
- // version
- QUIC_VERSION_BYTES,
- // destination connection ID length
- 0x00,
- // source connection ID length
- 0x08,
- // source connection ID
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x11,
- // original destination connection ID length
- 0x08,
- // original destination connection ID
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // retry token
- 'H', 'e', 'l', 'l', 'o', ' ', 't', 'h', 'i', 's',
- ' ', 'i', 's', ' ', 'R', 'E', 'T', 'R', 'Y', '!',
- };
- unsigned char packet_with_tag[] = {
- // public flags (long header with packet type RETRY)
- 0xF0,
- // version
- QUIC_VERSION_BYTES,
- // destination connection ID length
- 0x00,
- // source connection ID length
- 0x08,
- // source connection ID
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x11,
- // retry token
- 'H', 'e', 'l', 'l', 'o', ' ', 't', 'h', 'i', 's',
- ' ', 'i', 's', ' ', 'R', 'E', 'T', 'R', 'Y', '!',
- // retry token integrity tag
- 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
- 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
- };
- // clang-format on
-
- unsigned char* p = packet;
- size_t p_length = ABSL_ARRAYSIZE(packet);
- if (framer_.version().UsesTls()) {
- ReviseFirstByteByVersion(packet_with_tag);
- p = packet_with_tag;
- p_length = ABSL_ARRAYSIZE(packet_with_tag);
- } else if (framer_.version().HasLongHeaderLengths()) {
- p = packet49;
- p_length = ABSL_ARRAYSIZE(packet49);
- }
- QuicEncryptedPacket encrypted(AsChars(p), p_length, false);
- EXPECT_TRUE(framer_.ProcessPacket(encrypted));
-
- EXPECT_THAT(framer_.error(), IsQuicNoError());
- ASSERT_TRUE(visitor_.header_.get());
-
- ASSERT_TRUE(visitor_.on_retry_packet_called_);
- ASSERT_TRUE(visitor_.retry_new_connection_id_.get());
- ASSERT_TRUE(visitor_.retry_token_.get());
-
- if (framer_.version().UsesTls()) {
- ASSERT_TRUE(visitor_.retry_token_integrity_tag_.get());
- static const unsigned char expected_integrity_tag[16] = {
- 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
- 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
- };
- quiche::test::CompareCharArraysWithHexError(
- "retry integrity tag", visitor_.retry_token_integrity_tag_->data(),
- visitor_.retry_token_integrity_tag_->length(),
- reinterpret_cast<const char*>(expected_integrity_tag),
- ABSL_ARRAYSIZE(expected_integrity_tag));
- ASSERT_TRUE(visitor_.retry_without_tag_.get());
- quiche::test::CompareCharArraysWithHexError(
- "retry without tag", visitor_.retry_without_tag_->data(),
- visitor_.retry_without_tag_->length(),
- reinterpret_cast<const char*>(packet_with_tag), 35);
- } else {
- ASSERT_TRUE(visitor_.retry_original_connection_id_.get());
- EXPECT_EQ(FramerTestConnectionId(),
- *visitor_.retry_original_connection_id_.get());
- }
-
- EXPECT_EQ(FramerTestConnectionIdPlusOne(),
- *visitor_.retry_new_connection_id_.get());
- EXPECT_EQ("Hello this is RETRY!", *visitor_.retry_token_.get());
-
- // IETF RETRY is only sent from client to server, the rest of this test
- // ensures that the server correctly drops them without acting on them.
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
- // Reset our visitor state to default settings.
- visitor_.retry_original_connection_id_.reset();
- visitor_.retry_new_connection_id_.reset();
- visitor_.retry_token_.reset();
- visitor_.retry_token_integrity_tag_.reset();
- visitor_.retry_without_tag_.reset();
- visitor_.on_retry_packet_called_ = false;
-
- EXPECT_FALSE(framer_.ProcessPacket(encrypted));
-
- EXPECT_THAT(framer_.error(), IsError(QUIC_INVALID_PACKET_HEADER));
- EXPECT_EQ("Client-initiated RETRY is invalid.", framer_.detailed_error());
-
- EXPECT_FALSE(visitor_.on_retry_packet_called_);
- EXPECT_FALSE(visitor_.retry_new_connection_id_.get());
- EXPECT_FALSE(visitor_.retry_token_.get());
- EXPECT_FALSE(visitor_.retry_token_integrity_tag_.get());
- EXPECT_FALSE(visitor_.retry_without_tag_.get());
-}
-
-TEST_P(QuicFramerTest, BuildPaddingFramePacket) {
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
- QuicPacketHeader header;
- header.destination_connection_id = FramerTestConnectionId();
- header.reset_flag = false;
- header.version_flag = false;
- header.packet_number = kPacketNumber;
-
- QuicFrames frames = {QuicFrame(QuicPaddingFrame())};
-
- // clang-format off
- unsigned char packet[kMaxOutgoingPacketSize] = {
- // public flags (8 byte connection_id)
- 0x2C,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
-
- // frame type (padding frame)
- 0x00,
- 0x00, 0x00, 0x00, 0x00
- };
-
- unsigned char packet46[kMaxOutgoingPacketSize] = {
- // type (short header, 4 byte packet number)
- 0x43,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
-
- // frame type (padding frame)
- 0x00,
- 0x00, 0x00, 0x00, 0x00
- };
-
- unsigned char packet_ietf[kMaxOutgoingPacketSize] = {
- // type (short header, 4 byte packet number)
- 0x43,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
-
- // frame type (padding frame)
- 0x00,
- 0x00, 0x00, 0x00, 0x00
- };
- // clang-format on
-
- unsigned char* p = packet;
- if (VersionHasIetfQuicFrames(framer_.transport_version())) {
- p = packet_ietf;
- } else if (framer_.version().HasIetfInvariantHeader()) {
- p = packet46;
- }
-
- uint64_t header_size = GetPacketHeaderSize(
- framer_.transport_version(), PACKET_8BYTE_CONNECTION_ID,
- PACKET_0BYTE_CONNECTION_ID, !kIncludeVersion,
- !kIncludeDiversificationNonce, PACKET_4BYTE_PACKET_NUMBER,
- VARIABLE_LENGTH_INTEGER_LENGTH_0, 0, VARIABLE_LENGTH_INTEGER_LENGTH_0);
- memset(p + header_size + 1, 0x00, kMaxOutgoingPacketSize - header_size - 1);
-
- std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
- ASSERT_TRUE(data != nullptr);
-
- quiche::test::CompareCharArraysWithHexError(
- "constructed packet", data->data(), data->length(), AsChars(p),
- framer_.version().HasIetfInvariantHeader() ? ABSL_ARRAYSIZE(packet46)
- : ABSL_ARRAYSIZE(packet));
-}
-
-TEST_P(QuicFramerTest, BuildStreamFramePacketWithNewPaddingFrame) {
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
- QuicPacketHeader header;
- header.destination_connection_id = FramerTestConnectionId();
- header.reset_flag = false;
- header.version_flag = false;
- header.packet_number = kPacketNumber;
- QuicStreamFrame stream_frame(kStreamId, true, kStreamOffset,
- absl::string_view("hello world!"));
- QuicPaddingFrame padding_frame(2);
- QuicFrames frames = {QuicFrame(padding_frame), QuicFrame(stream_frame),
- QuicFrame(padding_frame)};
-
- // clang-format off
- unsigned char packet[] = {
- // public flags (8 byte connection_id)
- 0x2C,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
-
- // paddings
- 0x00, 0x00,
- // frame type (stream frame with fin)
- 0xFF,
- // stream id
- 0x01, 0x02, 0x03, 0x04,
- // offset
- 0x3A, 0x98, 0xFE, 0xDC,
- 0x32, 0x10, 0x76, 0x54,
- // data length
- 0x00, 0x0c,
- // data
- 'h', 'e', 'l', 'l',
- 'o', ' ', 'w', 'o',
- 'r', 'l', 'd', '!',
- // paddings
- 0x00, 0x00,
- };
-
- unsigned char packet46[] = {
- // type (short header, 4 byte packet number)
- 0x43,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
-
- // paddings
- 0x00, 0x00,
- // frame type (stream frame with fin)
- 0xFF,
- // stream id
- 0x01, 0x02, 0x03, 0x04,
- // offset
- 0x3A, 0x98, 0xFE, 0xDC,
- 0x32, 0x10, 0x76, 0x54,
- // data length
- 0x00, 0x0c,
- // data
- 'h', 'e', 'l', 'l',
- 'o', ' ', 'w', 'o',
- 'r', 'l', 'd', '!',
- // paddings
- 0x00, 0x00,
- };
-
- unsigned char packet_ietf[] = {
- // type (short header, 4 byte packet number)
- 0x43,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
-
- // paddings
- 0x00, 0x00,
- // frame type (IETF_STREAM with FIN, LEN, and OFFSET bits set)
- 0x08 | 0x01 | 0x02 | 0x04,
- // stream id
- kVarInt62FourBytes + 0x01, 0x02, 0x03, 0x04,
- // offset
- kVarInt62EightBytes + 0x3A, 0x98, 0xFE, 0xDC,
- 0x32, 0x10, 0x76, 0x54,
- // data length
- kVarInt62OneByte + 0x0c,
- // data
- 'h', 'e', 'l', 'l',
- 'o', ' ', 'w', 'o',
- 'r', 'l', 'd', '!',
- // paddings
- 0x00, 0x00,
- };
- // clang-format on
-
- std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
- ASSERT_TRUE(data != nullptr);
-
- unsigned char* p = packet;
- size_t p_size = ABSL_ARRAYSIZE(packet);
- if (VersionHasIetfQuicFrames(framer_.transport_version())) {
- p = packet_ietf;
- p_size = ABSL_ARRAYSIZE(packet_ietf);
- } else if (framer_.version().HasIetfInvariantHeader()) {
- p = packet46;
- p_size = ABSL_ARRAYSIZE(packet46);
- }
- QuicEncryptedPacket encrypted(AsChars(p), p_size, false);
-
- quiche::test::CompareCharArraysWithHexError(
- "constructed packet", data->data(), data->length(), AsChars(p), p_size);
-}
-
-TEST_P(QuicFramerTest, Build4ByteSequenceNumberPaddingFramePacket) {
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
- QuicPacketHeader header;
- header.destination_connection_id = FramerTestConnectionId();
- header.reset_flag = false;
- header.version_flag = false;
- header.packet_number_length = PACKET_4BYTE_PACKET_NUMBER;
- header.packet_number = kPacketNumber;
-
- QuicFrames frames = {QuicFrame(QuicPaddingFrame())};
-
- // clang-format off
- unsigned char packet[kMaxOutgoingPacketSize] = {
- // public flags (8 byte connection_id and 4 byte packet number)
- 0x2C,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
-
- // frame type (padding frame)
- 0x00,
- 0x00, 0x00, 0x00, 0x00
- };
-
- unsigned char packet46[kMaxOutgoingPacketSize] = {
- // type (short header, 4 byte packet number)
- 0x43,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
-
- // frame type (padding frame)
- 0x00,
- 0x00, 0x00, 0x00, 0x00
- };
-
- unsigned char packet_ietf[kMaxOutgoingPacketSize] = {
- // type (short header, 4 byte packet number)
- 0x43,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
-
- // frame type (padding frame)
- 0x00,
- 0x00, 0x00, 0x00, 0x00
- };
- // clang-format on
-
- unsigned char* p = packet;
- if (VersionHasIetfQuicFrames(framer_.transport_version())) {
- p = packet_ietf;
- } else if (framer_.version().HasIetfInvariantHeader()) {
- p = packet46;
- }
-
- uint64_t header_size = GetPacketHeaderSize(
- framer_.transport_version(), PACKET_8BYTE_CONNECTION_ID,
- PACKET_0BYTE_CONNECTION_ID, !kIncludeVersion,
- !kIncludeDiversificationNonce, PACKET_4BYTE_PACKET_NUMBER,
- VARIABLE_LENGTH_INTEGER_LENGTH_0, 0, VARIABLE_LENGTH_INTEGER_LENGTH_0);
- memset(p + header_size + 1, 0x00, kMaxOutgoingPacketSize - header_size - 1);
-
- std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
- ASSERT_TRUE(data != nullptr);
-
- quiche::test::CompareCharArraysWithHexError(
- "constructed packet", data->data(), data->length(), AsChars(p),
- framer_.version().HasIetfInvariantHeader() ? ABSL_ARRAYSIZE(packet46)
- : ABSL_ARRAYSIZE(packet));
-}
-
-TEST_P(QuicFramerTest, Build2ByteSequenceNumberPaddingFramePacket) {
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
- QuicPacketHeader header;
- header.destination_connection_id = FramerTestConnectionId();
- header.reset_flag = false;
- header.version_flag = false;
- header.packet_number_length = PACKET_2BYTE_PACKET_NUMBER;
- header.packet_number = kPacketNumber;
-
- QuicFrames frames = {QuicFrame(QuicPaddingFrame())};
-
- // clang-format off
- unsigned char packet[kMaxOutgoingPacketSize] = {
- // public flags (8 byte connection_id and 2 byte packet number)
- 0x1C,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x56, 0x78,
-
- // frame type (padding frame)
- 0x00,
- 0x00, 0x00, 0x00, 0x00
- };
-
- unsigned char packet46[kMaxOutgoingPacketSize] = {
- // type (short header, 2 byte packet number)
- 0x41,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x56, 0x78,
-
- // frame type (padding frame)
- 0x00,
- 0x00, 0x00, 0x00, 0x00
- };
-
- unsigned char packet_ietf[kMaxOutgoingPacketSize] = {
- // type (short header, 2 byte packet number)
- 0x41,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x56, 0x78,
-
- // frame type (padding frame)
- 0x00,
- 0x00, 0x00, 0x00, 0x00
- };
- // clang-format on
-
- unsigned char* p = packet;
- if (VersionHasIetfQuicFrames(framer_.transport_version())) {
- p = packet_ietf;
- } else if (framer_.version().HasIetfInvariantHeader()) {
- p = packet46;
- }
-
- uint64_t header_size = GetPacketHeaderSize(
- framer_.transport_version(), PACKET_8BYTE_CONNECTION_ID,
- PACKET_0BYTE_CONNECTION_ID, !kIncludeVersion,
- !kIncludeDiversificationNonce, PACKET_2BYTE_PACKET_NUMBER,
- VARIABLE_LENGTH_INTEGER_LENGTH_0, 0, VARIABLE_LENGTH_INTEGER_LENGTH_0);
- memset(p + header_size + 1, 0x00, kMaxOutgoingPacketSize - header_size - 1);
-
- std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
- ASSERT_TRUE(data != nullptr);
-
- quiche::test::CompareCharArraysWithHexError(
- "constructed packet", data->data(), data->length(), AsChars(p),
- framer_.version().HasIetfInvariantHeader() ? ABSL_ARRAYSIZE(packet46)
- : ABSL_ARRAYSIZE(packet));
-}
-
-TEST_P(QuicFramerTest, Build1ByteSequenceNumberPaddingFramePacket) {
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
- QuicPacketHeader header;
- header.destination_connection_id = FramerTestConnectionId();
- header.reset_flag = false;
- header.version_flag = false;
- header.packet_number_length = PACKET_1BYTE_PACKET_NUMBER;
- header.packet_number = kPacketNumber;
-
- QuicFrames frames = {QuicFrame(QuicPaddingFrame())};
-
- // clang-format off
- unsigned char packet[kMaxOutgoingPacketSize] = {
- // public flags (8 byte connection_id and 1 byte packet number)
- 0x0C,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x78,
-
- // frame type (padding frame)
- 0x00,
- 0x00, 0x00, 0x00, 0x00
- };
-
- unsigned char packet46[kMaxOutgoingPacketSize] = {
- // type (short header, 1 byte packet number)
- 0x40,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x78,
-
- // frame type (padding frame)
- 0x00,
- 0x00, 0x00, 0x00, 0x00
- };
-
- unsigned char packet_ietf[kMaxOutgoingPacketSize] = {
- // type (short header, 1 byte packet number)
- 0x40,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x78,
-
- // frame type (padding frame)
- 0x00,
- 0x00, 0x00, 0x00, 0x00
- };
- // clang-format on
-
- unsigned char* p = packet;
- if (VersionHasIetfQuicFrames(framer_.transport_version())) {
- p = packet_ietf;
- } else if (framer_.version().HasIetfInvariantHeader()) {
- p = packet46;
- }
-
- uint64_t header_size = GetPacketHeaderSize(
- framer_.transport_version(), PACKET_8BYTE_CONNECTION_ID,
- PACKET_0BYTE_CONNECTION_ID, !kIncludeVersion,
- !kIncludeDiversificationNonce, PACKET_1BYTE_PACKET_NUMBER,
- VARIABLE_LENGTH_INTEGER_LENGTH_0, 0, VARIABLE_LENGTH_INTEGER_LENGTH_0);
- memset(p + header_size + 1, 0x00, kMaxOutgoingPacketSize - header_size - 1);
-
- std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
- ASSERT_TRUE(data != nullptr);
-
- quiche::test::CompareCharArraysWithHexError(
- "constructed packet", data->data(), data->length(), AsChars(p),
- framer_.version().HasIetfInvariantHeader() ? ABSL_ARRAYSIZE(packet46)
- : ABSL_ARRAYSIZE(packet));
-}
-
-TEST_P(QuicFramerTest, BuildStreamFramePacket) {
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
- QuicPacketHeader header;
- header.destination_connection_id = FramerTestConnectionId();
- header.reset_flag = false;
- header.version_flag = false;
- header.packet_number = kPacketNumber;
- if (QuicVersionHasLongHeaderLengths(framer_.transport_version())) {
- header.length_length = VARIABLE_LENGTH_INTEGER_LENGTH_2;
- }
-
- QuicStreamFrame stream_frame(kStreamId, true, kStreamOffset,
- absl::string_view("hello world!"));
-
- QuicFrames frames = {QuicFrame(stream_frame)};
-
- // clang-format off
- unsigned char packet[] = {
- // public flags (8 byte connection_id)
- 0x2C,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
-
- // frame type (stream frame with fin and no length)
- 0xDF,
- // stream id
- 0x01, 0x02, 0x03, 0x04,
- // offset
- 0x3A, 0x98, 0xFE, 0xDC,
- 0x32, 0x10, 0x76, 0x54,
- // data
- 'h', 'e', 'l', 'l',
- 'o', ' ', 'w', 'o',
- 'r', 'l', 'd', '!',
- };
-
- unsigned char packet46[] = {
- // type (short header, 4 byte packet number)
- 0x43,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
-
- // frame type (stream frame with fin and no length)
- 0xDF,
- // stream id
- 0x01, 0x02, 0x03, 0x04,
- // offset
- 0x3A, 0x98, 0xFE, 0xDC,
- 0x32, 0x10, 0x76, 0x54,
- // data
- 'h', 'e', 'l', 'l',
- 'o', ' ', 'w', 'o',
- 'r', 'l', 'd', '!',
- };
-
- unsigned char packet_ietf[] = {
- // type (short header, 4 byte packet number)
- 0x43,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
-
- // frame type (IETF_STREAM frame with FIN and OFFSET, no length)
- 0x08 | 0x01 | 0x04,
- // stream id
- kVarInt62FourBytes + 0x01, 0x02, 0x03, 0x04,
- // offset
- kVarInt62EightBytes + 0x3A, 0x98, 0xFE, 0xDC,
- 0x32, 0x10, 0x76, 0x54,
- // data
- 'h', 'e', 'l', 'l',
- 'o', ' ', 'w', 'o',
- 'r', 'l', 'd', '!',
- };
- // clang-format on
-
- std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
- ASSERT_TRUE(data != nullptr);
-
- unsigned char* p = packet;
- size_t p_size = ABSL_ARRAYSIZE(packet);
- if (VersionHasIetfQuicFrames(framer_.transport_version())) {
- p = packet_ietf;
- p_size = ABSL_ARRAYSIZE(packet_ietf);
- } else if (framer_.version().HasIetfInvariantHeader()) {
- p = packet46;
- p_size = ABSL_ARRAYSIZE(packet46);
- }
- quiche::test::CompareCharArraysWithHexError(
- "constructed packet", data->data(), data->length(), AsChars(p), p_size);
-}
-
-TEST_P(QuicFramerTest, BuildStreamFramePacketWithVersionFlag) {
- QuicPacketHeader header;
- header.destination_connection_id = FramerTestConnectionId();
- header.reset_flag = false;
- header.version_flag = true;
- if (framer_.version().HasIetfInvariantHeader()) {
- header.long_packet_type = ZERO_RTT_PROTECTED;
- }
- header.packet_number = kPacketNumber;
- if (QuicVersionHasLongHeaderLengths(framer_.transport_version())) {
- header.length_length = VARIABLE_LENGTH_INTEGER_LENGTH_2;
- }
-
- QuicStreamFrame stream_frame(kStreamId, true, kStreamOffset,
- absl::string_view("hello world!"));
- QuicFrames frames = {QuicFrame(stream_frame)};
-
- // clang-format off
- unsigned char packet[] = {
- // public flags (version, 8 byte connection_id)
- 0x2D,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // version tag
- QUIC_VERSION_BYTES,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
-
- // frame type (stream frame with fin and no length)
- 0xDF,
- // stream id
- 0x01, 0x02, 0x03, 0x04,
- // offset
- 0x3A, 0x98, 0xFE, 0xDC, 0x32, 0x10, 0x76, 0x54,
- // data
- 'h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd', '!',
- };
-
- unsigned char packet46[] = {
- // type (long header with packet type ZERO_RTT_PROTECTED)
- 0xD3,
- // version tag
- QUIC_VERSION_BYTES,
- // connection_id length
- 0x50,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
-
- // frame type (stream frame with fin and no length)
- 0xDF,
- // stream id
- 0x01, 0x02, 0x03, 0x04,
- // offset
- 0x3A, 0x98, 0xFE, 0xDC, 0x32, 0x10, 0x76, 0x54,
- // data
- 'h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd', '!',
- };
-
- unsigned char packet49[] = {
- // type (long header with packet type ZERO_RTT_PROTECTED)
- 0xD3,
- // version tag
- QUIC_VERSION_BYTES,
- // destination connection ID length
- 0x08,
- // destination connection ID
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // source connection ID length
- 0x00,
- // length
- 0x40, 0x1D,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
-
- // frame type (stream frame with fin and no length)
- 0xDF,
- // stream id
- 0x01, 0x02, 0x03, 0x04,
- // offset
- 0x3A, 0x98, 0xFE, 0xDC, 0x32, 0x10, 0x76, 0x54,
- // data
- 'h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd', '!',
- };
-
- unsigned char packet_ietf[] = {
- // type (long header with packet type ZERO_RTT_PROTECTED)
- 0xD3,
- // version tag
- QUIC_VERSION_BYTES,
- // destination connection ID length
- 0x08,
- // destination connection ID
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // source connection ID length
- 0x00,
- // length
- 0x40, 0x1D,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
-
- // frame type (IETF_STREAM frame with fin and offset, no length)
- 0x08 | 0x01 | 0x04,
- // stream id
- kVarInt62FourBytes + 0x01, 0x02, 0x03, 0x04,
- // offset
- kVarInt62EightBytes + 0x3A, 0x98, 0xFE, 0xDC, 0x32, 0x10, 0x76, 0x54,
- // data
- 'h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd', '!',
- };
- // clang-format on
-
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
- std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
- ASSERT_TRUE(data != nullptr);
-
- unsigned char* p = packet;
- size_t p_size = ABSL_ARRAYSIZE(packet);
- if (VersionHasIetfQuicFrames(framer_.transport_version())) {
- ReviseFirstByteByVersion(packet_ietf);
- p = packet_ietf;
- p_size = ABSL_ARRAYSIZE(packet_ietf);
- } else if (framer_.version().HasLongHeaderLengths()) {
- p = packet49;
- p_size = ABSL_ARRAYSIZE(packet49);
- } else if (framer_.version().HasIetfInvariantHeader()) {
- p = packet46;
- p_size = ABSL_ARRAYSIZE(packet46);
- }
- quiche::test::CompareCharArraysWithHexError(
- "constructed packet", data->data(), data->length(), AsChars(p), p_size);
-}
-
-TEST_P(QuicFramerTest, BuildCryptoFramePacket) {
- if (!QuicVersionUsesCryptoFrames(framer_.transport_version())) {
- return;
- }
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
- QuicPacketHeader header;
- header.destination_connection_id = FramerTestConnectionId();
- header.reset_flag = false;
- header.version_flag = false;
- header.packet_number = kPacketNumber;
-
- SimpleDataProducer data_producer;
- framer_.set_data_producer(&data_producer);
-
- absl::string_view crypto_frame_contents("hello world!");
- QuicCryptoFrame crypto_frame(ENCRYPTION_INITIAL, kStreamOffset,
- crypto_frame_contents.length());
- data_producer.SaveCryptoData(ENCRYPTION_INITIAL, kStreamOffset,
- crypto_frame_contents);
-
- QuicFrames frames = {QuicFrame(&crypto_frame)};
-
- // clang-format off
- unsigned char packet48[] = {
- // type (short header, 4 byte packet number)
- 0x43,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
-
- // frame type (QuicFrameType CRYPTO_FRAME)
- 0x08,
- // offset
- kVarInt62EightBytes + 0x3A, 0x98, 0xFE, 0xDC,
- 0x32, 0x10, 0x76, 0x54,
- // length
- kVarInt62OneByte + 12,
- // data
- 'h', 'e', 'l', 'l',
- 'o', ' ', 'w', 'o',
- 'r', 'l', 'd', '!',
- };
-
- unsigned char packet_ietf[] = {
- // type (short header, 4 byte packet number)
- 0x43,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
-
- // frame type (IETF_CRYPTO frame)
- 0x06,
- // offset
- kVarInt62EightBytes + 0x3A, 0x98, 0xFE, 0xDC,
- 0x32, 0x10, 0x76, 0x54,
- // length
- kVarInt62OneByte + 12,
- // data
- 'h', 'e', 'l', 'l',
- 'o', ' ', 'w', 'o',
- 'r', 'l', 'd', '!',
- };
- // clang-format on
-
- unsigned char* packet = packet48;
- size_t packet_size = ABSL_ARRAYSIZE(packet48);
- if (framer_.version().HasIetfQuicFrames()) {
- packet = packet_ietf;
- packet_size = ABSL_ARRAYSIZE(packet_ietf);
- }
-
- std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
- ASSERT_TRUE(data != nullptr);
- quiche::test::CompareCharArraysWithHexError("constructed packet",
- data->data(), data->length(),
- AsChars(packet), packet_size);
-}
-
-TEST_P(QuicFramerTest, CryptoFrame) {
- if (!QuicVersionUsesCryptoFrames(framer_.transport_version())) {
- // CRYPTO frames aren't supported prior to v48.
- return;
- }
- SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-
- // clang-format off
- PacketFragments packet48 = {
- // type (short header, 4 byte packet number)
- {"",
- {0x43}},
- // connection_id
- {"",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // packet number
- {"",
- {0x12, 0x34, 0x56, 0x78}},
- // frame type (QuicFrameType CRYPTO_FRAME)
- {"",
- {0x08}},
- // offset
- {"",
- {kVarInt62EightBytes + 0x3A, 0x98, 0xFE, 0xDC,
- 0x32, 0x10, 0x76, 0x54}},
- // data length
- {"Invalid data length.",
- {kVarInt62OneByte + 12}},
- // data
- {"Unable to read frame data.",
- {'h', 'e', 'l', 'l',
- 'o', ' ', 'w', 'o',
- 'r', 'l', 'd', '!'}},
- };
-
- PacketFragments packet_ietf = {
- // type (short header, 4 byte packet number)
- {"",
- {0x43}},
- // connection_id
- {"",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // packet number
- {"",
- {0x12, 0x34, 0x56, 0x78}},
- // frame type (IETF_CRYPTO frame)
- {"",
- {0x06}},
- // offset
- {"",
- {kVarInt62EightBytes + 0x3A, 0x98, 0xFE, 0xDC,
- 0x32, 0x10, 0x76, 0x54}},
- // data length
- {"Invalid data length.",
- {kVarInt62OneByte + 12}},
- // data
- {"Unable to read frame data.",
- {'h', 'e', 'l', 'l',
- 'o', ' ', 'w', 'o',
- 'r', 'l', 'd', '!'}},
- };
- // clang-format on
-
- PacketFragments& fragments =
- framer_.version().HasIetfQuicFrames() ? packet_ietf : packet48;
- std::unique_ptr<QuicEncryptedPacket> encrypted(
- AssemblePacketFromFragments(fragments));
- EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
-
- EXPECT_THAT(framer_.error(), IsQuicNoError());
- ASSERT_TRUE(visitor_.header_.get());
- EXPECT_TRUE(CheckDecryption(
- *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
- PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
- ASSERT_EQ(1u, visitor_.crypto_frames_.size());
- QuicCryptoFrame* frame = visitor_.crypto_frames_[0].get();
- EXPECT_EQ(ENCRYPTION_FORWARD_SECURE, frame->level);
- EXPECT_EQ(kStreamOffset, frame->offset);
- EXPECT_EQ("hello world!",
- std::string(frame->data_buffer, frame->data_length));
-
- CheckFramingBoundaries(fragments, QUIC_INVALID_FRAME_DATA);
-}
-
-TEST_P(QuicFramerTest, BuildVersionNegotiationPacket) {
- SetQuicFlag(FLAGS_quic_disable_version_negotiation_grease_randomness, true);
- // clang-format off
- unsigned char packet[] = {
- // public flags (version, 8 byte connection_id)
- 0x0D,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // supported versions
- 0xDA, 0x5A, 0x3A, 0x3A,
- QUIC_VERSION_BYTES,
- };
- unsigned char packet46[] = {
- // type (long header)
- 0xC0,
- // version tag
- 0x00, 0x00, 0x00, 0x00,
- // connection_id length
- 0x05,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // supported versions
- 0xDA, 0x5A, 0x3A, 0x3A,
- QUIC_VERSION_BYTES,
- };
- unsigned char packet49[] = {
- // type (long header)
- 0xC0,
- // version tag
- 0x00, 0x00, 0x00, 0x00,
- // destination connection ID length
- 0x00,
- // source connection ID length
- 0x08,
- // source connection ID
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // supported versions
- 0xDA, 0x5A, 0x3A, 0x3A,
- QUIC_VERSION_BYTES,
- };
- // clang-format on
- unsigned char* p = packet;
- size_t p_size = ABSL_ARRAYSIZE(packet);
- if (framer_.version().HasLongHeaderLengths()) {
- p = packet49;
- p_size = ABSL_ARRAYSIZE(packet49);
- } else if (framer_.version().HasIetfInvariantHeader()) {
- p = packet46;
- p_size = ABSL_ARRAYSIZE(packet46);
- }
-
- QuicConnectionId connection_id = FramerTestConnectionId();
- std::unique_ptr<QuicEncryptedPacket> data(
- QuicFramer::BuildVersionNegotiationPacket(
- connection_id, EmptyQuicConnectionId(),
- framer_.version().HasIetfInvariantHeader(),
- framer_.version().HasLengthPrefixedConnectionIds(),
- SupportedVersions(GetParam())));
- quiche::test::CompareCharArraysWithHexError(
- "constructed packet", data->data(), data->length(), AsChars(p), p_size);
-}
-
-TEST_P(QuicFramerTest, BuildVersionNegotiationPacketWithClientConnectionId) {
- if (!framer_.version().SupportsClientConnectionIds()) {
- return;
- }
-
- SetQuicFlag(FLAGS_quic_disable_version_negotiation_grease_randomness, true);
-
- // clang-format off
- unsigned char packet[] = {
- // type (long header)
- 0xC0,
- // version tag
- 0x00, 0x00, 0x00, 0x00,
- // client/destination connection ID
- 0x08,
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x11,
- // server/source connection ID
- 0x08,
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // supported versions
- 0xDA, 0x5A, 0x3A, 0x3A,
- QUIC_VERSION_BYTES,
- };
- // clang-format on
-
- QuicConnectionId server_connection_id = FramerTestConnectionId();
- QuicConnectionId client_connection_id = FramerTestConnectionIdPlusOne();
- std::unique_ptr<QuicEncryptedPacket> data(
- QuicFramer::BuildVersionNegotiationPacket(
- server_connection_id, client_connection_id, true, true,
- SupportedVersions(GetParam())));
- quiche::test::CompareCharArraysWithHexError(
- "constructed packet", data->data(), data->length(), AsChars(packet),
- ABSL_ARRAYSIZE(packet));
-}
-
-TEST_P(QuicFramerTest, BuildAckFramePacketOneAckBlock) {
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
- QuicPacketHeader header;
- header.destination_connection_id = FramerTestConnectionId();
- header.reset_flag = false;
- header.version_flag = false;
- header.packet_number = kPacketNumber;
-
- // Use kSmallLargestObserved to make this test finished in a short time.
- QuicAckFrame ack_frame = InitAckFrame(kSmallLargestObserved);
- ack_frame.ack_delay_time = QuicTime::Delta::Zero();
-
- QuicFrames frames = {QuicFrame(&ack_frame)};
-
- // clang-format off
- unsigned char packet[] = {
- // public flags (8 byte connection_id)
- 0x2C,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
-
- // frame type (ack frame)
- // (no ack blocks, 2 byte largest observed, 2 byte block length)
- 0x45,
- // largest acked
- 0x12, 0x34,
- // Zero delta time.
- 0x00, 0x00,
- // first ack block length.
- 0x12, 0x34,
- // num timestamps.
- 0x00,
- };
-
- unsigned char packet46[] = {
- // type (short header, 4 byte packet number)
- 0x43,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
-
- // frame type (ack frame)
- // (no ack blocks, 2 byte largest observed, 2 byte block length)
- 0x45,
- // largest acked
- 0x12, 0x34,
- // Zero delta time.
- 0x00, 0x00,
- // first ack block length.
- 0x12, 0x34,
- // num timestamps.
- 0x00,
- };
-
- unsigned char packet_ietf[] = {
- // type (short header, 4 byte packet number)
- 0x43,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
-
- // frame type (IETF_ACK frame)
- 0x02,
- // largest acked
- kVarInt62TwoBytes + 0x12, 0x34,
- // Zero delta time.
- kVarInt62OneByte + 0x00,
- // Number of additional ack blocks.
- kVarInt62OneByte + 0x00,
- // first ack block length.
- kVarInt62TwoBytes + 0x12, 0x33,
- };
- // clang-format on
- unsigned char* p = packet;
- size_t p_size = ABSL_ARRAYSIZE(packet);
- if (VersionHasIetfQuicFrames(framer_.transport_version())) {
- p = packet_ietf;
- p_size = ABSL_ARRAYSIZE(packet_ietf);
- } else if (framer_.version().HasIetfInvariantHeader()) {
- p = packet46;
- p_size = ABSL_ARRAYSIZE(packet46);
- }
-
- std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
- ASSERT_TRUE(data != nullptr);
- quiche::test::CompareCharArraysWithHexError(
- "constructed packet", data->data(), data->length(), AsChars(p), p_size);
-}
-
-TEST_P(QuicFramerTest, BuildAckReceiveTimestampsFrameMultipleRanges) {
- if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
- return;
- }
-
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
- QuicPacketHeader header;
- header.destination_connection_id = FramerTestConnectionId();
- header.reset_flag = false;
- header.version_flag = false;
- header.packet_number = kPacketNumber;
-
- QuicAckFrame ack_frame = InitAckFrame(kSmallLargestObserved);
- ack_frame.received_packet_times = PacketTimeVector{
- // Timestamp Range 3.
- {kSmallLargestObserved - 22, CreationTimePlus(0x29ffdddd)},
- {kSmallLargestObserved - 21, CreationTimePlus(0x29ffdedd)},
- // Timestamp Range 2.
- {kSmallLargestObserved - 11, CreationTimePlus(0x29ffdeed)},
- // Timestamp Range 1.
- {kSmallLargestObserved - 4, CreationTimePlus(0x29ffeeed)},
- {kSmallLargestObserved - 3, CreationTimePlus(0x29ffeeee)},
- {kSmallLargestObserved - 2, CreationTimePlus(0x29ffffff)},
- };
- ack_frame.ack_delay_time = QuicTime::Delta::Zero();
- QuicFrames frames = {QuicFrame(&ack_frame)};
-
- unsigned char packet_ietf[] = {
- // type (short header, 4 byte packet number)
- 0x43,
- // connection_id
- 0xFE,
- 0xDC,
- 0xBA,
- 0x98,
- 0x76,
- 0x54,
- 0x32,
- 0x10,
- // packet number
- 0x12,
- 0x34,
- 0x56,
- 0x78,
-
- // frame type (IETF_ACK_RECEIVE_TIMESTAMPS frame)
- 0x22,
- // largest acked
- kVarInt62TwoBytes + 0x12,
- 0x34, // = 4660
- // Zero delta time.
- kVarInt62OneByte + 0x00,
- // number of additional ack blocks
- kVarInt62OneByte + 0x00,
- // first ack block length.
- kVarInt62TwoBytes + 0x12,
- 0x33,
-
- // Receive Timestamps.
-
- // Timestamp Range Count
- kVarInt62OneByte + 0x03,
-
- // Timestamp range 1 (three packets).
- // Gap
- kVarInt62OneByte + 0x02,
- // Timestamp Range Count
- kVarInt62OneByte + 0x03,
- // Timestamp Delta
- kVarInt62FourBytes + 0x29,
- 0xff,
- 0xff,
- 0xff,
- // Timestamp Delta
- kVarInt62TwoBytes + 0x11,
- 0x11,
- // Timestamp Delta
- kVarInt62OneByte + 0x01,
-
- // Timestamp range 2 (one packet).
- // Gap
- kVarInt62OneByte + 0x05,
- // Timestamp Range Count
- kVarInt62OneByte + 0x01,
- // Timestamp Delta
- kVarInt62TwoBytes + 0x10,
- 0x00,
-
- // Timestamp range 3 (two packets).
- // Gap
- kVarInt62OneByte + 0x08,
- // Timestamp Range Count
- kVarInt62OneByte + 0x02,
- // Timestamp Delta
- kVarInt62OneByte + 0x10,
- // Timestamp Delta
- kVarInt62TwoBytes + 0x01,
- 0x00,
- };
- // clang-format on
-
- framer_.set_process_timestamps(true);
- framer_.set_max_receive_timestamps_per_ack(8);
- std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
- ASSERT_TRUE(data != nullptr);
- quiche::test::CompareCharArraysWithHexError(
- "constructed packet", data->data(), data->length(), AsChars(packet_ietf),
- ABSL_ARRAYSIZE(packet_ietf));
-}
-
-TEST_P(QuicFramerTest, BuildAckReceiveTimestampsFrameExceedsMaxTimestamps) {
- if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
- return;
- }
-
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
- QuicPacketHeader header;
- header.destination_connection_id = FramerTestConnectionId();
- header.reset_flag = false;
- header.version_flag = false;
- header.packet_number = kPacketNumber;
-
- QuicAckFrame ack_frame = InitAckFrame(kSmallLargestObserved);
- ack_frame.received_packet_times = PacketTimeVector{
- // Timestamp Range 3 (not included because max receive timestamps = 4).
- {kSmallLargestObserved - 20, CreationTimePlus(0x29ffdddd)},
- // Timestamp Range 2.
- {kSmallLargestObserved - 10, CreationTimePlus(0x29ffdedd)},
- {kSmallLargestObserved - 9, CreationTimePlus(0x29ffdeed)},
- // Timestamp Range 1.
- {kSmallLargestObserved - 2, CreationTimePlus(0x29ffeeed)},
- {kSmallLargestObserved - 1, CreationTimePlus(0x29ffeeee)},
- {kSmallLargestObserved, CreationTimePlus(0x29ffffff)},
- };
- ack_frame.ack_delay_time = QuicTime::Delta::Zero();
- QuicFrames frames = {QuicFrame(&ack_frame)};
-
- unsigned char packet_ietf[] = {
- // type (short header, 4 byte packet number)
- 0x43,
- // connection_id
- 0xFE,
- 0xDC,
- 0xBA,
- 0x98,
- 0x76,
- 0x54,
- 0x32,
- 0x10,
- // packet number
- 0x12,
- 0x34,
- 0x56,
- 0x78,
-
- // frame type (IETF_ACK_RECEIVE_TIMESTAMPS frame)
- 0x22,
- // largest acked
- kVarInt62TwoBytes + 0x12,
- 0x34, // = 4660
- // Zero delta time.
- kVarInt62OneByte + 0x00,
- // number of additional ack blocks
- kVarInt62OneByte + 0x00,
- // first ack block length.
- kVarInt62TwoBytes + 0x12,
- 0x33,
-
- // Receive Timestamps.
-
- // Timestamp Range Count
- kVarInt62OneByte + 0x02,
-
- // Timestamp range 1 (three packets).
- // Gap
- kVarInt62OneByte + 0x00,
- // Timestamp Range Count
- kVarInt62OneByte + 0x03,
- // Timestamp Delta
- kVarInt62FourBytes + 0x29,
- 0xff,
- 0xff,
- 0xff,
- // Timestamp Delta
- kVarInt62TwoBytes + 0x11,
- 0x11,
- // Timestamp Delta
- kVarInt62OneByte + 0x01,
-
- // Timestamp range 2 (one packet).
- // Gap
- kVarInt62OneByte + 0x05,
- // Timestamp Range Count
- kVarInt62OneByte + 0x01,
- // Timestamp Delta
- kVarInt62TwoBytes + 0x10,
- 0x00,
- };
- // clang-format on
-
- framer_.set_process_timestamps(true);
- framer_.set_max_receive_timestamps_per_ack(4);
- std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
- ASSERT_TRUE(data != nullptr);
- quiche::test::CompareCharArraysWithHexError(
- "constructed packet", data->data(), data->length(), AsChars(packet_ietf),
- ABSL_ARRAYSIZE(packet_ietf));
-}
-
-TEST_P(QuicFramerTest, BuildAckReceiveTimestampsFrameWithExponentEncoding) {
- if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
- return;
- }
-
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
- QuicPacketHeader header;
- header.destination_connection_id = FramerTestConnectionId();
- header.reset_flag = false;
- header.version_flag = false;
- header.packet_number = kPacketNumber;
-
- QuicAckFrame ack_frame = InitAckFrame(kSmallLargestObserved);
- ack_frame.received_packet_times = PacketTimeVector{
- // Timestamp Range 2.
- {kSmallLargestObserved - 12, CreationTimePlus((0x06c00 << 3) + 0x03)},
- {kSmallLargestObserved - 11, CreationTimePlus((0x28e00 << 3) + 0x00)},
- // Timestamp Range 1.
- {kSmallLargestObserved - 5, CreationTimePlus((0x29f00 << 3) + 0x00)},
- {kSmallLargestObserved - 4, CreationTimePlus((0x29f00 << 3) + 0x01)},
- {kSmallLargestObserved - 3, CreationTimePlus((0x29f00 << 3) + 0x02)},
- {kSmallLargestObserved - 2, CreationTimePlus((0x29f00 << 3) + 0x03)},
- };
- ack_frame.ack_delay_time = QuicTime::Delta::Zero();
-
- QuicFrames frames = {QuicFrame(&ack_frame)};
-
- unsigned char packet_ietf[] = {
- // type (short header, 4 byte packet number)
- 0x43,
- // connection_id
- 0xFE,
- 0xDC,
- 0xBA,
- 0x98,
- 0x76,
- 0x54,
- 0x32,
- 0x10,
- // packet number
- 0x12,
- 0x34,
- 0x56,
- 0x78,
-
- // frame type (IETF_ACK_RECEIVE_TIMESTAMPS frame)
- 0x22,
- // largest acked
- kVarInt62TwoBytes + 0x12,
- 0x34, // = 4660
- // Zero delta time.
- kVarInt62OneByte + 0x00,
- // number of additional ack blocks
- kVarInt62OneByte + 0x00,
- // first ack block length.
- kVarInt62TwoBytes + 0x12,
- 0x33,
-
- // Receive Timestamps.
-
- // Timestamp Range Count
- kVarInt62OneByte + 0x02,
-
- // Timestamp range 1 (three packets).
- // Gap
- kVarInt62OneByte + 0x02,
- // Timestamp Range Count
- kVarInt62OneByte + 0x04,
- // Timestamp Delta
- kVarInt62FourBytes + 0x00,
- 0x02,
- 0x9f,
- 0x01, // round up
- // Timestamp Delta
- kVarInt62OneByte + 0x00,
- // Timestamp Delta
- kVarInt62OneByte + 0x00,
- // Timestamp Delta
- kVarInt62OneByte + 0x01,
-
- // Timestamp range 2 (one packet).
- // Gap
- kVarInt62OneByte + 0x04,
- // Timestamp Range Count
- kVarInt62OneByte + 0x02,
- // Timestamp Delta
- kVarInt62TwoBytes + 0x11,
- 0x00,
- // Timestamp Delta
- kVarInt62FourBytes + 0x00,
- 0x02,
- 0x21,
- 0xff,
- };
- // clang-format on
-
- framer_.set_process_timestamps(true);
- framer_.set_max_receive_timestamps_per_ack(8);
- framer_.set_receive_timestamps_exponent(3);
- std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
- ASSERT_TRUE(data != nullptr);
- quiche::test::CompareCharArraysWithHexError(
- "constructed packet", data->data(), data->length(), AsChars(packet_ietf),
- ABSL_ARRAYSIZE(packet_ietf));
-}
-
-TEST_P(QuicFramerTest, BuildAndProcessAckReceiveTimestampsWithMultipleRanges) {
- if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
- return;
- }
- framer_.InstallDecrypter(ENCRYPTION_FORWARD_SECURE,
- std::make_unique<StrictTaggingDecrypter>(/*key=*/0));
- framer_.SetKeyUpdateSupportForConnection(true);
- framer_.set_process_timestamps(true);
- framer_.set_max_receive_timestamps_per_ack(8);
-
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
- QuicPacketHeader header;
- header.destination_connection_id = FramerTestConnectionId();
- header.reset_flag = false;
- header.version_flag = false;
- header.packet_number = kPacketNumber;
-
- QuicAckFrame ack_frame = InitAckFrame(kSmallLargestObserved);
- ack_frame.received_packet_times = PacketTimeVector{
- {kSmallLargestObserved - 1201, CreationTimePlus(0x8bcaef234)},
- {kSmallLargestObserved - 1200, CreationTimePlus(0x8bcdef123)},
- {kSmallLargestObserved - 1000, CreationTimePlus(0xaacdef123)},
- {kSmallLargestObserved - 4, CreationTimePlus(0xabcdea125)},
- {kSmallLargestObserved - 2, CreationTimePlus(0xabcdee124)},
- {kSmallLargestObserved - 1, CreationTimePlus(0xabcdef123)},
- {kSmallLargestObserved, CreationTimePlus(0xabcdef123)},
- };
- ack_frame.ack_delay_time = QuicTime::Delta::Zero();
- QuicFrames frames = {QuicFrame(&ack_frame)};
-
- std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
- ASSERT_TRUE(data != nullptr);
- std::unique_ptr<QuicEncryptedPacket> encrypted(
- EncryptPacketWithTagAndPhase(*data, 0, false));
- ASSERT_TRUE(encrypted);
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
- EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
- EXPECT_THAT(framer_.error(), IsQuicNoError());
-
- const QuicAckFrame& frame = *visitor_.ack_frames_[0];
- EXPECT_THAT(frame.received_packet_times,
- ContainerEq(PacketTimeVector{
- {kSmallLargestObserved, CreationTimePlus(0xabcdef123)},
- {kSmallLargestObserved - 1, CreationTimePlus(0xabcdef123)},
- {kSmallLargestObserved - 2, CreationTimePlus(0xabcdee124)},
- {kSmallLargestObserved - 4, CreationTimePlus(0xabcdea125)},
- {kSmallLargestObserved - 1000, CreationTimePlus(0xaacdef123)},
- {kSmallLargestObserved - 1200, CreationTimePlus(0x8bcdef123)},
- {kSmallLargestObserved - 1201, CreationTimePlus(0x8bcaef234)},
- }));
-}
-
-TEST_P(QuicFramerTest,
- BuildAndProcessAckReceiveTimestampsExceedsMaxTimestamps) {
- if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
- return;
- }
- framer_.InstallDecrypter(ENCRYPTION_FORWARD_SECURE,
- std::make_unique<StrictTaggingDecrypter>(/*key=*/0));
- framer_.SetKeyUpdateSupportForConnection(true);
- framer_.set_process_timestamps(true);
- framer_.set_max_receive_timestamps_per_ack(2);
-
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
- QuicPacketHeader header;
- header.destination_connection_id = FramerTestConnectionId();
- header.reset_flag = false;
- header.version_flag = false;
- header.packet_number = kPacketNumber;
-
- QuicAckFrame ack_frame = InitAckFrame(kSmallLargestObserved);
- ack_frame.received_packet_times = PacketTimeVector{
- {kSmallLargestObserved - 1201, CreationTimePlus(0x8bcaef234)},
- {kSmallLargestObserved - 1200, CreationTimePlus(0x8bcdef123)},
- {kSmallLargestObserved - 1000, CreationTimePlus(0xaacdef123)},
- {kSmallLargestObserved - 5, CreationTimePlus(0xabcdea125)},
- {kSmallLargestObserved - 3, CreationTimePlus(0xabcded124)},
- {kSmallLargestObserved - 2, CreationTimePlus(0xabcdee124)},
- {kSmallLargestObserved - 1, CreationTimePlus(0xabcdef123)},
- };
- ack_frame.ack_delay_time = QuicTime::Delta::Zero();
- QuicFrames frames = {QuicFrame(&ack_frame)};
-
- std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
- ASSERT_TRUE(data != nullptr);
- std::unique_ptr<QuicEncryptedPacket> encrypted(
- EncryptPacketWithTagAndPhase(*data, 0, false));
- ASSERT_TRUE(encrypted);
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
- EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
- EXPECT_THAT(framer_.error(), IsQuicNoError());
-
- const QuicAckFrame& frame = *visitor_.ack_frames_[0];
- EXPECT_THAT(frame.received_packet_times,
- ContainerEq(PacketTimeVector{
- {kSmallLargestObserved - 1, CreationTimePlus(0xabcdef123)},
- {kSmallLargestObserved - 2, CreationTimePlus(0xabcdee124)},
- }));
-}
-
-TEST_P(QuicFramerTest,
- BuildAndProcessAckReceiveTimestampsWithExponentNoTruncation) {
- if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
- return;
- }
- framer_.InstallDecrypter(ENCRYPTION_FORWARD_SECURE,
- std::make_unique<StrictTaggingDecrypter>(/*key=*/0));
- framer_.SetKeyUpdateSupportForConnection(true);
- framer_.set_process_timestamps(true);
- framer_.set_max_receive_timestamps_per_ack(8);
- framer_.set_receive_timestamps_exponent(3);
-
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
- QuicPacketHeader header;
- header.destination_connection_id = FramerTestConnectionId();
- header.reset_flag = false;
- header.version_flag = false;
- header.packet_number = kPacketNumber;
-
- QuicAckFrame ack_frame = InitAckFrame(kSmallLargestObserved);
- ack_frame.received_packet_times = PacketTimeVector{
- {kSmallLargestObserved - 8, CreationTimePlus(0x1add << 3)},
- {kSmallLargestObserved - 7, CreationTimePlus(0x29ed << 3)},
- {kSmallLargestObserved - 3, CreationTimePlus(0x29fe << 3)},
- {kSmallLargestObserved - 2, CreationTimePlus(0x29ff << 3)},
- };
- ack_frame.ack_delay_time = QuicTime::Delta::Zero();
- QuicFrames frames = {QuicFrame(&ack_frame)};
-
- std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
- ASSERT_TRUE(data != nullptr);
- std::unique_ptr<QuicEncryptedPacket> encrypted(
- EncryptPacketWithTagAndPhase(*data, 0, false));
- ASSERT_TRUE(encrypted);
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
- EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
- EXPECT_THAT(framer_.error(), IsQuicNoError());
-
- const QuicAckFrame& frame = *visitor_.ack_frames_[0];
- EXPECT_THAT(frame.received_packet_times,
- ContainerEq(PacketTimeVector{
- {kSmallLargestObserved - 2, CreationTimePlus(0x29ff << 3)},
- {kSmallLargestObserved - 3, CreationTimePlus(0x29fe << 3)},
- {kSmallLargestObserved - 7, CreationTimePlus(0x29ed << 3)},
- {kSmallLargestObserved - 8, CreationTimePlus(0x1add << 3)},
- }));
-}
-
-TEST_P(QuicFramerTest,
- BuildAndProcessAckReceiveTimestampsWithExponentTruncation) {
- if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
- return;
- }
- framer_.InstallDecrypter(ENCRYPTION_FORWARD_SECURE,
- std::make_unique<StrictTaggingDecrypter>(/*key=*/0));
- framer_.SetKeyUpdateSupportForConnection(true);
- framer_.set_process_timestamps(true);
- framer_.set_max_receive_timestamps_per_ack(8);
- framer_.set_receive_timestamps_exponent(3);
-
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
- QuicPacketHeader header;
- header.destination_connection_id = FramerTestConnectionId();
- header.reset_flag = false;
- header.version_flag = false;
- header.packet_number = kPacketNumber;
-
- QuicAckFrame ack_frame = InitAckFrame(kSmallLargestObserved);
- ack_frame.received_packet_times = PacketTimeVector{
- {kSmallLargestObserved - 10, CreationTimePlus((0x1001 << 3) + 1)},
- {kSmallLargestObserved - 9, CreationTimePlus((0x2995 << 3) - 1)},
- {kSmallLargestObserved - 8, CreationTimePlus((0x2995 << 3) + 0)},
- {kSmallLargestObserved - 7, CreationTimePlus((0x2995 << 3) + 1)},
- {kSmallLargestObserved - 6, CreationTimePlus((0x2995 << 3) + 2)},
- {kSmallLargestObserved - 3, CreationTimePlus((0x2995 << 3) + 3)},
- {kSmallLargestObserved - 2, CreationTimePlus((0x2995 << 3) + 4)},
- };
- ack_frame.ack_delay_time = QuicTime::Delta::Zero();
- QuicFrames frames = {QuicFrame(&ack_frame)};
-
- std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
- ASSERT_TRUE(data != nullptr);
- std::unique_ptr<QuicEncryptedPacket> encrypted(
- EncryptPacketWithTagAndPhase(*data, 0, false));
- ASSERT_TRUE(encrypted);
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
- EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
- EXPECT_THAT(framer_.error(), IsQuicNoError());
-
- const QuicAckFrame& frame = *visitor_.ack_frames_[0];
- EXPECT_THAT(frame.received_packet_times,
- ContainerEq(PacketTimeVector{
- {kSmallLargestObserved - 2, CreationTimePlus(0x2996 << 3)},
- {kSmallLargestObserved - 3, CreationTimePlus(0x2996 << 3)},
- {kSmallLargestObserved - 6, CreationTimePlus(0x2996 << 3)},
- {kSmallLargestObserved - 7, CreationTimePlus(0x2996 << 3)},
- {kSmallLargestObserved - 8, CreationTimePlus(0x2995 << 3)},
- {kSmallLargestObserved - 9, CreationTimePlus(0x2995 << 3)},
- {kSmallLargestObserved - 10, CreationTimePlus(0x1002 << 3)},
- }));
-}
-
-TEST_P(QuicFramerTest, AckReceiveTimestamps) {
- if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
- return;
- }
- framer_.InstallDecrypter(ENCRYPTION_FORWARD_SECURE,
- std::make_unique<StrictTaggingDecrypter>(/*key=*/0));
- framer_.SetKeyUpdateSupportForConnection(true);
- framer_.set_process_timestamps(true);
- framer_.set_max_receive_timestamps_per_ack(8);
- framer_.set_receive_timestamps_exponent(3);
-
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
- QuicPacketHeader header;
- header.destination_connection_id = FramerTestConnectionId();
- header.reset_flag = false;
- header.version_flag = false;
- header.packet_number = kPacketNumber;
-
- // Use kSmallLargestObserved to make this test finished in a short time.
- QuicAckFrame ack_frame = InitAckFrame(kSmallLargestObserved);
- ack_frame.received_packet_times = PacketTimeVector{
- {kSmallLargestObserved - 5, CreationTimePlus((0x29ff << 3))},
- {kSmallLargestObserved - 4, CreationTimePlus((0x29ff << 3))},
- {kSmallLargestObserved - 3, CreationTimePlus((0x29ff << 3))},
- {kSmallLargestObserved - 2, CreationTimePlus((0x29ff << 3))},
- };
- ack_frame.ack_delay_time = QuicTime::Delta::Zero();
- QuicFrames frames = {QuicFrame(&ack_frame)};
-
- std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
- ASSERT_TRUE(data != nullptr);
- std::unique_ptr<QuicEncryptedPacket> encrypted(
- EncryptPacketWithTagAndPhase(*data, 0, false));
- ASSERT_TRUE(encrypted);
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
- EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
- EXPECT_THAT(framer_.error(), IsQuicNoError());
-
- const QuicAckFrame& frame = *visitor_.ack_frames_[0];
- EXPECT_THAT(frame.received_packet_times,
- ContainerEq(PacketTimeVector{
- {kSmallLargestObserved - 2, CreationTimePlus(0x29ff << 3)},
- {kSmallLargestObserved - 3, CreationTimePlus(0x29ff << 3)},
- {kSmallLargestObserved - 4, CreationTimePlus(0x29ff << 3)},
- {kSmallLargestObserved - 5, CreationTimePlus(0x29ff << 3)},
- }));
-}
-
-TEST_P(QuicFramerTest, AckReceiveTimestampsPacketOutOfOrder) {
- if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
- return;
- }
- framer_.InstallDecrypter(ENCRYPTION_FORWARD_SECURE,
- std::make_unique<StrictTaggingDecrypter>(/*key=*/0));
- framer_.SetKeyUpdateSupportForConnection(true);
- framer_.set_process_timestamps(true);
- framer_.set_max_receive_timestamps_per_ack(8);
- framer_.set_receive_timestamps_exponent(3);
-
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
- QuicPacketHeader header;
- header.destination_connection_id = FramerTestConnectionId();
- header.reset_flag = false;
- header.version_flag = false;
- header.packet_number = kPacketNumber;
-
- // Use kSmallLargestObserved to make this test finished in a short time.
- QuicAckFrame ack_frame = InitAckFrame(kSmallLargestObserved);
-
- // The packet numbers below are out of order, this is impossible because we
- // don't record out of order packets in received_packet_times. The test is
- // intended to ensure this error is raised when it happens.
- ack_frame.received_packet_times = PacketTimeVector{
- {kSmallLargestObserved - 5, CreationTimePlus((0x29ff << 3))},
- {kSmallLargestObserved - 2, CreationTimePlus((0x29ff << 3))},
- {kSmallLargestObserved - 4, CreationTimePlus((0x29ff << 3))},
- {kSmallLargestObserved - 3, CreationTimePlus((0x29ff << 3))},
- };
- ack_frame.ack_delay_time = QuicTime::Delta::Zero();
- QuicFrames frames = {QuicFrame(&ack_frame)};
-
- EXPECT_QUIC_BUG(BuildDataPacket(header, frames),
- "Packet number and/or receive time not in order.");
-}
-
-// If there's insufficient room for IETF ack receive timestamps, don't write any
-// timestamp ranges.
-TEST_P(QuicFramerTest, IetfAckReceiveTimestampsTruncate) {
- if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
- return;
- }
- framer_.InstallDecrypter(ENCRYPTION_FORWARD_SECURE,
- std::make_unique<StrictTaggingDecrypter>(/*key=*/0));
- framer_.SetKeyUpdateSupportForConnection(true);
- framer_.set_process_timestamps(true);
- framer_.set_max_receive_timestamps_per_ack(8192);
- framer_.set_receive_timestamps_exponent(3);
-
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
- QuicPacketHeader header;
- header.destination_connection_id = FramerTestConnectionId();
- header.reset_flag = false;
- header.version_flag = false;
- header.packet_number = kPacketNumber;
-
- // Use kSmallLargestObserved to make this test finished in a short time.
- QuicAckFrame ack_frame = InitAckFrame(kSmallLargestObserved);
- for (QuicPacketNumber i(1); i <= kSmallLargestObserved; i += 2) {
- ack_frame.received_packet_times.push_back(
- {i, CreationTimePlus((0x29ff << 3))});
- }
-
- ack_frame.ack_delay_time = QuicTime::Delta::Zero();
- QuicFrames frames = {QuicFrame(&ack_frame)};
-
- std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
- ASSERT_TRUE(data != nullptr);
- std::unique_ptr<QuicEncryptedPacket> encrypted(
- EncryptPacketWithTagAndPhase(*data, 0, false));
- ASSERT_TRUE(encrypted);
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
- EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
- EXPECT_THAT(framer_.error(), IsQuicNoError());
-
- const QuicAckFrame& frame = *visitor_.ack_frames_[0];
- EXPECT_TRUE(frame.received_packet_times.empty());
-}
-
-// If there are too many ack ranges, they will be truncated to make room for a
-// timestamp range count of 0.
-TEST_P(QuicFramerTest, IetfAckReceiveTimestampsAckRangeTruncation) {
- if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
- return;
- }
- SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
- framer_.set_process_timestamps(true);
- framer_.set_max_receive_timestamps_per_ack(8);
- framer_.set_receive_timestamps_exponent(3);
-
- QuicPacketHeader header;
- header.destination_connection_id = FramerTestConnectionId();
- header.reset_flag = false;
- header.version_flag = false;
- header.packet_number = kPacketNumber;
-
- QuicAckFrame ack_frame;
- // Create a packet with just the ack.
- ack_frame = MakeAckFrameWithGaps(/*gap_size=*/0xffffffff,
- /*max_num_gaps=*/200,
- /*largest_acked=*/kMaxIetfVarInt);
- ack_frame.received_packet_times = PacketTimeVector{
- {QuicPacketNumber(kMaxIetfVarInt) - 2, CreationTimePlus((0x29ff << 3))},
- };
- QuicFrames frames = {QuicFrame(&ack_frame)};
- // Build an ACK packet.
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
- std::unique_ptr<QuicPacket> raw_ack_packet(BuildDataPacket(header, frames));
- ASSERT_TRUE(raw_ack_packet != nullptr);
- char buffer[kMaxOutgoingPacketSize];
- size_t encrypted_length =
- framer_.EncryptPayload(ENCRYPTION_INITIAL, header.packet_number,
- *raw_ack_packet, buffer, kMaxOutgoingPacketSize);
- ASSERT_NE(0u, encrypted_length);
- // Now make sure we can turn our ack packet back into an ack frame.
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
- ASSERT_TRUE(framer_.ProcessPacket(
- QuicEncryptedPacket(buffer, encrypted_length, false)));
- ASSERT_EQ(1u, visitor_.ack_frames_.size());
- QuicAckFrame& processed_ack_frame = *visitor_.ack_frames_[0];
- EXPECT_EQ(QuicPacketNumber(kMaxIetfVarInt),
- LargestAcked(processed_ack_frame));
- // Verify ACK ranges in the frame gets truncated.
- ASSERT_LT(processed_ack_frame.packets.NumPacketsSlow(),
- ack_frame.packets.NumIntervals());
- EXPECT_EQ(158u, processed_ack_frame.packets.NumPacketsSlow());
- EXPECT_LT(processed_ack_frame.packets.NumIntervals(),
- ack_frame.packets.NumIntervals());
- EXPECT_EQ(QuicPacketNumber(kMaxIetfVarInt),
- processed_ack_frame.packets.Max());
- // But the receive timestamps are not truncated because they are small.
- EXPECT_FALSE(processed_ack_frame.received_packet_times.empty());
-}
-
-TEST_P(QuicFramerTest, BuildAckFramePacketOneAckBlockMaxLength) {
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
- QuicPacketHeader header;
- header.destination_connection_id = FramerTestConnectionId();
- header.reset_flag = false;
- header.version_flag = false;
- header.packet_number = kPacketNumber;
-
- QuicAckFrame ack_frame = InitAckFrame(kPacketNumber);
- ack_frame.ack_delay_time = QuicTime::Delta::Zero();
-
- QuicFrames frames = {QuicFrame(&ack_frame)};
-
- // clang-format off
- unsigned char packet[] = {
- // public flags (8 byte connection_id)
- 0x2C,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
-
- // frame type (ack frame)
- // (no ack blocks, 4 byte largest observed, 4 byte block length)
- 0x4A,
- // largest acked
- 0x12, 0x34, 0x56, 0x78,
- // Zero delta time.
- 0x00, 0x00,
- // first ack block length.
- 0x12, 0x34, 0x56, 0x78,
- // num timestamps.
- 0x00,
- };
-
- unsigned char packet46[] = {
- // type (short header, 4 byte packet number)
- 0x43,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
-
- // frame type (ack frame)
- // (no ack blocks, 4 byte largest observed, 4 byte block length)
- 0x4A,
- // largest acked
- 0x12, 0x34, 0x56, 0x78,
- // Zero delta time.
- 0x00, 0x00,
- // first ack block length.
- 0x12, 0x34, 0x56, 0x78,
- // num timestamps.
- 0x00,
- };
-
-
- unsigned char packet_ietf[] = {
- // type (short header, 4 byte packet number)
- 0x43,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
-
- // frame type (IETF_ACK frame)
- 0x02,
- // largest acked
- kVarInt62FourBytes + 0x12, 0x34, 0x56, 0x78,
- // Zero delta time.
- kVarInt62OneByte + 0x00,
- // Nr. of additional ack blocks
- kVarInt62OneByte + 0x00,
- // first ack block length.
- kVarInt62FourBytes + 0x12, 0x34, 0x56, 0x77,
- };
- // clang-format on
- unsigned char* p = packet;
- size_t p_size = ABSL_ARRAYSIZE(packet);
- if (VersionHasIetfQuicFrames(framer_.transport_version())) {
- p = packet_ietf;
- p_size = ABSL_ARRAYSIZE(packet_ietf);
- } else if (framer_.version().HasIetfInvariantHeader()) {
- p = packet46;
- p_size = ABSL_ARRAYSIZE(packet46);
- }
-
- std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
- ASSERT_TRUE(data != nullptr);
- quiche::test::CompareCharArraysWithHexError(
- "constructed packet", data->data(), data->length(), AsChars(p), p_size);
-}
-
-TEST_P(QuicFramerTest, BuildAckFramePacketMultipleAckBlocks) {
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
- QuicPacketHeader header;
- header.destination_connection_id = FramerTestConnectionId();
- header.reset_flag = false;
- header.version_flag = false;
- header.packet_number = kPacketNumber;
-
- // Use kSmallLargestObserved to make this test finished in a short time.
- QuicAckFrame ack_frame =
- InitAckFrame({{QuicPacketNumber(1), QuicPacketNumber(5)},
- {QuicPacketNumber(10), QuicPacketNumber(500)},
- {QuicPacketNumber(900), kSmallMissingPacket},
- {kSmallMissingPacket + 1, kSmallLargestObserved + 1}});
- ack_frame.ack_delay_time = QuicTime::Delta::Zero();
-
- QuicFrames frames = {QuicFrame(&ack_frame)};
-
- // clang-format off
- unsigned char packet[] = {
- // public flags (8 byte connection_id)
- 0x2C,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
-
- // frame type (ack frame)
- // (has ack blocks, 2 byte largest observed, 2 byte block length)
- 0x65,
- // largest acked
- 0x12, 0x34,
- // Zero delta time.
- 0x00, 0x00,
- // num ack blocks ranges.
- 0x04,
- // first ack block length.
- 0x00, 0x01,
- // gap to next block.
- 0x01,
- // ack block length.
- 0x0e, 0xaf,
- // gap to next block.
- 0xff,
- // ack block length.
- 0x00, 0x00,
- // gap to next block.
- 0x91,
- // ack block length.
- 0x01, 0xea,
- // gap to next block.
- 0x05,
- // ack block length.
- 0x00, 0x04,
- // num timestamps.
- 0x00,
- };
-
- unsigned char packet46[] = {
- // type (short header, 4 byte packet number)
- 0x43,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
-
- // frame type (ack frame)
- // (has ack blocks, 2 byte largest observed, 2 byte block length)
- 0x65,
- // largest acked
- 0x12, 0x34,
- // Zero delta time.
- 0x00, 0x00,
- // num ack blocks ranges.
- 0x04,
- // first ack block length.
- 0x00, 0x01,
- // gap to next block.
- 0x01,
- // ack block length.
- 0x0e, 0xaf,
- // gap to next block.
- 0xff,
- // ack block length.
- 0x00, 0x00,
- // gap to next block.
- 0x91,
- // ack block length.
- 0x01, 0xea,
- // gap to next block.
- 0x05,
- // ack block length.
- 0x00, 0x04,
- // num timestamps.
- 0x00,
- };
-
- unsigned char packet_ietf[] = {
- // type (short header, 4 byte packet number)
- 0x43,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
-
- // frame type (IETF_ACK frame)
- 0x02,
- // largest acked
- kVarInt62TwoBytes + 0x12, 0x34,
- // Zero delta time.
- kVarInt62OneByte + 0x00,
- // num additional ack blocks.
- kVarInt62OneByte + 0x03,
- // first ack block length.
- kVarInt62OneByte + 0x00,
-
- // gap to next block.
- kVarInt62OneByte + 0x00,
- // ack block length.
- kVarInt62TwoBytes + 0x0e, 0xae,
-
- // gap to next block.
- kVarInt62TwoBytes + 0x01, 0x8f,
- // ack block length.
- kVarInt62TwoBytes + 0x01, 0xe9,
-
- // gap to next block.
- kVarInt62OneByte + 0x04,
- // ack block length.
- kVarInt62OneByte + 0x03,
- };
- // clang-format on
- unsigned char* p = packet;
- size_t p_size = ABSL_ARRAYSIZE(packet);
- if (VersionHasIetfQuicFrames(framer_.transport_version())) {
- p = packet_ietf;
- p_size = ABSL_ARRAYSIZE(packet_ietf);
- } else if (framer_.version().HasIetfInvariantHeader()) {
- p = packet46;
- p_size = ABSL_ARRAYSIZE(packet46);
- }
-
- std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
- ASSERT_TRUE(data != nullptr);
-
- quiche::test::CompareCharArraysWithHexError(
- "constructed packet", data->data(), data->length(), AsChars(p), p_size);
-}
-
-TEST_P(QuicFramerTest, BuildAckFramePacketMaxAckBlocks) {
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
- QuicPacketHeader header;
- header.destination_connection_id = FramerTestConnectionId();
- header.reset_flag = false;
- header.version_flag = false;
- header.packet_number = kPacketNumber;
-
- // Use kSmallLargestObservedto make this test finished in a short time.
- QuicAckFrame ack_frame;
- ack_frame.largest_acked = kSmallLargestObserved;
- ack_frame.ack_delay_time = QuicTime::Delta::Zero();
- // 300 ack blocks.
- for (size_t i = 2; i < 2 * 300; i += 2) {
- ack_frame.packets.Add(QuicPacketNumber(i));
- }
- ack_frame.packets.AddRange(QuicPacketNumber(600), kSmallLargestObserved + 1);
-
- QuicFrames frames = {QuicFrame(&ack_frame)};
-
- // clang-format off
- unsigned char packet[] = {
- // public flags (8 byte connection_id)
- 0x2C,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
- // frame type (ack frame)
- // (has ack blocks, 2 byte largest observed, 2 byte block length)
- 0x65,
- // largest acked
- 0x12, 0x34,
- // Zero delta time.
- 0x00, 0x00,
- // num ack blocks ranges.
- 0xff,
- // first ack block length.
- 0x0f, 0xdd,
- // 255 = 4 * 63 + 3
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
- // num timestamps.
- 0x00,
- };
-
- unsigned char packet46[] = {
- // type (short header, 4 byte packet number)
- 0x43,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
- // frame type (ack frame)
- // (has ack blocks, 2 byte largest observed, 2 byte block length)
- 0x65,
- // largest acked
- 0x12, 0x34,
- // Zero delta time.
- 0x00, 0x00,
- // num ack blocks ranges.
- 0xff,
- // first ack block length.
- 0x0f, 0xdd,
- // 255 = 4 * 63 + 3
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
- 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
- // num timestamps.
- 0x00,
- };
-
- unsigned char packet_ietf[] = {
- // type (short header, 4 byte packet number)
- 0x43,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
- // frame type (IETF_ACK frame)
- 0x02,
- // largest acked
- kVarInt62TwoBytes + 0x12, 0x34,
- // Zero delta time.
- kVarInt62OneByte + 0x00,
- // num ack blocks ranges.
- kVarInt62TwoBytes + 0x01, 0x2b,
- // first ack block length.
- kVarInt62TwoBytes + 0x0f, 0xdc,
- // 255 added blocks of gap_size == 1, ack_size == 1
-#define V99AddedBLOCK kVarInt62OneByte + 0x00, kVarInt62OneByte + 0x00
- V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
- V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
- V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
- V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
- V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
- V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
- V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
- V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
- V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
- V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
- V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
- V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
- V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
- V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
- V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
- V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
- V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
- V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
- V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
- V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
-
- V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
- V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
- V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
- V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
- V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
- V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
- V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
- V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
- V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
- V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
- V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
- V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
- V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
- V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
- V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
- V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
- V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
- V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
- V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
- V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
-
- V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
- V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
- V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
- V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
- V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
- V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
- V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
- V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
- V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
- V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
- V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
- V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
- V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
- V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
- V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
- V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
- V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
- V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
- V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
- V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
-
-#undef V99AddedBLOCK
- };
- // clang-format on
- unsigned char* p = packet;
- size_t p_size = ABSL_ARRAYSIZE(packet);
- if (VersionHasIetfQuicFrames(framer_.transport_version())) {
- p = packet_ietf;
- p_size = ABSL_ARRAYSIZE(packet_ietf);
- } else if (framer_.version().HasIetfInvariantHeader()) {
- p = packet46;
- p_size = ABSL_ARRAYSIZE(packet46);
- }
-
- std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
- ASSERT_TRUE(data != nullptr);
-
- quiche::test::CompareCharArraysWithHexError(
- "constructed packet", data->data(), data->length(), AsChars(p), p_size);
-}
-
-TEST_P(QuicFramerTest, BuildNewStopWaitingPacket) {
- if (framer_.version().HasIetfInvariantHeader()) {
- return;
- }
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
- QuicPacketHeader header;
- header.destination_connection_id = FramerTestConnectionId();
- header.reset_flag = false;
- header.version_flag = false;
- header.packet_number = kPacketNumber;
-
- QuicStopWaitingFrame stop_waiting_frame;
- stop_waiting_frame.least_unacked = kLeastUnacked;
-
- QuicFrames frames = {QuicFrame(stop_waiting_frame)};
-
- // clang-format off
- unsigned char packet[] = {
- // public flags (8 byte connection_id)
- 0x2C,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
-
- // frame type (stop waiting frame)
- 0x06,
- // least packet number awaiting an ack, delta from packet number.
- 0x00, 0x00, 0x00, 0x08,
- };
-
- // clang-format on
-
- std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
- ASSERT_TRUE(data != nullptr);
-
- quiche::test::CompareCharArraysWithHexError(
- "constructed packet", data->data(), data->length(), AsChars(packet),
- ABSL_ARRAYSIZE(packet));
-}
-
-TEST_P(QuicFramerTest, BuildRstFramePacketQuic) {
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
- QuicPacketHeader header;
- header.destination_connection_id = FramerTestConnectionId();
- header.reset_flag = false;
- header.version_flag = false;
- header.packet_number = kPacketNumber;
-
- QuicRstStreamFrame rst_frame;
- rst_frame.stream_id = kStreamId;
- if (VersionHasIetfQuicFrames(framer_.transport_version())) {
- rst_frame.ietf_error_code = 0x01;
- } else {
- rst_frame.error_code = static_cast<QuicRstStreamErrorCode>(0x05060708);
- }
- rst_frame.byte_offset = 0x0807060504030201;
-
- // clang-format off
- unsigned char packet[] = {
- // public flags (8 byte connection_id)
- 0x2C,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
-
- // frame type (rst stream frame)
- 0x01,
- // stream id
- 0x01, 0x02, 0x03, 0x04,
- // sent byte offset
- 0x08, 0x07, 0x06, 0x05,
- 0x04, 0x03, 0x02, 0x01,
- // error code
- 0x05, 0x06, 0x07, 0x08,
- };
-
- unsigned char packet46[] = {
- // type (short packet, 4 byte packet number)
- 0x43,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
-
- // frame type (rst stream frame)
- 0x01,
- // stream id
- 0x01, 0x02, 0x03, 0x04,
- // sent byte offset
- 0x08, 0x07, 0x06, 0x05,
- 0x04, 0x03, 0x02, 0x01,
- // error code
- 0x05, 0x06, 0x07, 0x08,
- };
-
- unsigned char packet_ietf[] = {
- // type (short packet, 4 byte packet number)
- 0x43,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
-
- // frame type (IETF_RST_STREAM frame)
- 0x04,
- // stream id
- kVarInt62FourBytes + 0x01, 0x02, 0x03, 0x04,
- // error code
- kVarInt62OneByte + 0x01,
- // sent byte offset
- kVarInt62EightBytes + 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01
- };
- // clang-format on
-
- QuicFrames frames = {QuicFrame(&rst_frame)};
-
- std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
- ASSERT_TRUE(data != nullptr);
-
- unsigned char* p = packet;
- size_t p_size = ABSL_ARRAYSIZE(packet);
- if (VersionHasIetfQuicFrames(framer_.transport_version())) {
- p = packet_ietf;
- p_size = ABSL_ARRAYSIZE(packet_ietf);
- } else if (framer_.version().HasIetfInvariantHeader()) {
- p = packet46;
- p_size = ABSL_ARRAYSIZE(packet46);
- }
- QuicEncryptedPacket encrypted(AsChars(p), p_size, false);
-
- quiche::test::CompareCharArraysWithHexError(
- "constructed packet", data->data(), data->length(), AsChars(p), p_size);
-}
-
-TEST_P(QuicFramerTest, BuildCloseFramePacket) {
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
- QuicPacketHeader header;
- header.destination_connection_id = FramerTestConnectionId();
- header.reset_flag = false;
- header.version_flag = false;
- header.packet_number = kPacketNumber;
-
- QuicConnectionCloseFrame close_frame(framer_.transport_version(),
- QUIC_INTERNAL_ERROR, NO_IETF_QUIC_ERROR,
- "because I can", 0x05);
- QuicFrames frames = {QuicFrame(&close_frame)};
-
- // clang-format off
- unsigned char packet[] = {
- // public flags (8 byte connection_id)
- 0x2C,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
-
- // frame type (connection close frame)
- 0x02,
- // error code
- 0x00, 0x00, 0x00, 0x01,
- // error details length
- 0x00, 0x0d,
- // error details
- 'b', 'e', 'c', 'a',
- 'u', 's', 'e', ' ',
- 'I', ' ', 'c', 'a',
- 'n',
- };
-
- unsigned char packet46[] = {
- // type (short header, 4 byte packet number)
- 0x43,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
-
- // frame type (connection close frame)
- 0x02,
- // error code
- 0x00, 0x00, 0x00, 0x01,
- // error details length
- 0x00, 0x0d,
- // error details
- 'b', 'e', 'c', 'a',
- 'u', 's', 'e', ' ',
- 'I', ' ', 'c', 'a',
- 'n',
- };
-
- unsigned char packet_ietf[] = {
- // type (short header, 4 byte packet number)
- 0x43,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
-
- // frame type (IETF_CONNECTION_CLOSE frame)
- 0x1c,
- // error code
- kVarInt62OneByte + 0x01,
- // Frame type within the CONNECTION_CLOSE frame
- kVarInt62OneByte + 0x05,
- // error details length
- kVarInt62OneByte + 0x0f,
- // error details
- '1', ':', 'b', 'e',
- 'c', 'a', 'u', 's',
- 'e', ' ', 'I', ' ',
- 'c', 'a', 'n',
- };
- // clang-format on
-
- unsigned char* p = packet;
- size_t p_size = ABSL_ARRAYSIZE(packet);
- if (VersionHasIetfQuicFrames(framer_.transport_version())) {
- p = packet_ietf;
- p_size = ABSL_ARRAYSIZE(packet_ietf);
- } else if (framer_.version().HasIetfInvariantHeader()) {
- p = packet46;
- p_size = ABSL_ARRAYSIZE(packet46);
- }
-
- std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
- ASSERT_TRUE(data != nullptr);
-
- quiche::test::CompareCharArraysWithHexError(
- "constructed packet", data->data(), data->length(), AsChars(p), p_size);
-}
-
-TEST_P(QuicFramerTest, BuildCloseFramePacketExtendedInfo) {
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
- QuicPacketHeader header;
- header.destination_connection_id = FramerTestConnectionId();
- header.reset_flag = false;
- header.version_flag = false;
- header.packet_number = kPacketNumber;
-
- QuicConnectionCloseFrame close_frame(
- framer_.transport_version(),
- static_cast<QuicErrorCode>(
- VersionHasIetfQuicFrames(framer_.transport_version()) ? 0x01
- : 0x05060708),
- NO_IETF_QUIC_ERROR, "because I can", 0x05);
- // Set this so that it is "there" for both Google QUIC and IETF QUIC
- // framing. It better not show up for Google QUIC!
- close_frame.quic_error_code = static_cast<QuicErrorCode>(0x4567);
-
- QuicFrames frames = {QuicFrame(&close_frame)};
-
- // clang-format off
- unsigned char packet[] = {
- // public flags (8 byte connection_id)
- 0x2C,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
-
- // frame type (connection close frame)
- 0x02,
- // error code
- 0x05, 0x06, 0x07, 0x08,
- // error details length
- 0x00, 0x0d,
- // error details
- 'b', 'e', 'c', 'a',
- 'u', 's', 'e', ' ',
- 'I', ' ', 'c', 'a',
- 'n',
- };
-
- unsigned char packet46[] = {
- // type (short header, 4 byte packet number)
- 0x43,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
-
- // frame type (connection close frame)
- 0x02,
- // error code
- 0x05, 0x06, 0x07, 0x08,
- // error details length
- 0x00, 0x0d,
- // error details
- 'b', 'e', 'c', 'a',
- 'u', 's', 'e', ' ',
- 'I', ' ', 'c', 'a',
- 'n',
- };
-
- unsigned char packet_ietf[] = {
- // type (short header, 4 byte packet number)
- 0x43,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
-
- // frame type (IETF_CONNECTION_CLOSE frame)
- 0x1c,
- // IETF error code INTERNAL_ERROR = 0x01 corresponding to
- // QuicErrorCode::QUIC_INTERNAL_ERROR = 0x01.
- kVarInt62OneByte + 0x01,
- // Frame type within the CONNECTION_CLOSE frame
- kVarInt62OneByte + 0x05,
- // error details length
- kVarInt62OneByte + 0x13,
- // error details
- '1', '7', '7', '6',
- '7', ':', 'b', 'e',
- 'c', 'a', 'u', 's',
- 'e', ' ', 'I', ' ',
- 'c', 'a', 'n'
- };
- // clang-format on
-
- unsigned char* p = packet;
- size_t p_size = ABSL_ARRAYSIZE(packet);
- if (VersionHasIetfQuicFrames(framer_.transport_version())) {
- p = packet_ietf;
- p_size = ABSL_ARRAYSIZE(packet_ietf);
- } else if (framer_.version().HasIetfInvariantHeader()) {
- p = packet46;
- p_size = ABSL_ARRAYSIZE(packet46);
- }
-
- std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
- ASSERT_TRUE(data != nullptr);
-
- quiche::test::CompareCharArraysWithHexError(
- "constructed packet", data->data(), data->length(), AsChars(p), p_size);
-}
-
-TEST_P(QuicFramerTest, BuildTruncatedCloseFramePacket) {
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
- QuicPacketHeader header;
- header.destination_connection_id = FramerTestConnectionId();
- header.reset_flag = false;
- header.version_flag = false;
- header.packet_number = kPacketNumber;
-
- QuicConnectionCloseFrame close_frame(framer_.transport_version(),
- QUIC_INTERNAL_ERROR, NO_IETF_QUIC_ERROR,
- std::string(2048, 'A'), 0x05);
- QuicFrames frames = {QuicFrame(&close_frame)};
-
- // clang-format off
- unsigned char packet[] = {
- // public flags (8 byte connection_id)
- 0x2C,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
-
- // frame type (connection close frame)
- 0x02,
- // error code
- 0x00, 0x00, 0x00, 0x01,
- // error details length
- 0x01, 0x00,
- // error details (truncated to 256 bytes)
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- };
-
- unsigned char packet46[] = {
- // type (short header, 4 byte packet number)
- 0x43,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
-
- // frame type (connection close frame)
- 0x02,
- // error code
- 0x00, 0x00, 0x00, 0x01,
- // error details length
- 0x01, 0x00,
- // error details (truncated to 256 bytes)
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- };
-
- unsigned char packet_ietf[] = {
- // type (short header, 4 byte packet number)
- 0x43,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
-
- // frame type (IETF_CONNECTION_CLOSE frame)
- 0x1c,
- // error code
- kVarInt62OneByte + 0x01,
- // Frame type within the CONNECTION_CLOSE frame
- kVarInt62OneByte + 0x05,
- // error details length
- kVarInt62TwoBytes + 0x01, 0x00,
- // error details (truncated to 256 bytes)
- '1', ':', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- };
- // clang-format on
-
- unsigned char* p = packet;
- size_t p_size = ABSL_ARRAYSIZE(packet);
- if (VersionHasIetfQuicFrames(framer_.transport_version())) {
- p = packet_ietf;
- p_size = ABSL_ARRAYSIZE(packet_ietf);
- } else if (framer_.version().HasIetfInvariantHeader()) {
- p = packet46;
- p_size = ABSL_ARRAYSIZE(packet46);
- }
-
- std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
- ASSERT_TRUE(data != nullptr);
-
- quiche::test::CompareCharArraysWithHexError(
- "constructed packet", data->data(), data->length(), AsChars(p), p_size);
-}
-
-TEST_P(QuicFramerTest, BuildApplicationCloseFramePacket) {
- if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
- // This frame is only for IETF QUIC.
- return;
- }
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
- QuicPacketHeader header;
- header.destination_connection_id = FramerTestConnectionId();
- header.reset_flag = false;
- header.version_flag = false;
- header.packet_number = kPacketNumber;
-
- QuicConnectionCloseFrame app_close_frame;
- app_close_frame.wire_error_code = 0x11;
- app_close_frame.error_details = "because I can";
- app_close_frame.close_type = IETF_QUIC_APPLICATION_CONNECTION_CLOSE;
-
- QuicFrames frames = {QuicFrame(&app_close_frame)};
-
- // clang-format off
-
- unsigned char packet_ietf[] = {
- // type (short header, 4 byte packet number)
- 0x43,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
-
- // frame type (IETF_APPLICATION_CLOSE frame)
- 0x1d,
- // error code
- kVarInt62OneByte + 0x11,
- // error details length
- kVarInt62OneByte + 0x0f,
- // error details, note that it includes an extended error code.
- '0', ':', 'b', 'e',
- 'c', 'a', 'u', 's',
- 'e', ' ', 'I', ' ',
- 'c', 'a', 'n',
- };
- // clang-format on
-
- std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
- ASSERT_TRUE(data != nullptr);
-
- quiche::test::CompareCharArraysWithHexError(
- "constructed packet", data->data(), data->length(), AsChars(packet_ietf),
- ABSL_ARRAYSIZE(packet_ietf));
-}
-
-TEST_P(QuicFramerTest, BuildTruncatedApplicationCloseFramePacket) {
- if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
- // This frame is only for IETF QUIC.
- return;
- }
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
- QuicPacketHeader header;
- header.destination_connection_id = FramerTestConnectionId();
- header.reset_flag = false;
- header.version_flag = false;
- header.packet_number = kPacketNumber;
-
- QuicConnectionCloseFrame app_close_frame;
- app_close_frame.wire_error_code = 0x11;
- app_close_frame.error_details = std::string(2048, 'A');
- app_close_frame.close_type = IETF_QUIC_APPLICATION_CONNECTION_CLOSE;
- // Setting to missing ensures that if it is missing, the extended
- // code is not added to the text message.
- app_close_frame.quic_error_code = QUIC_IETF_GQUIC_ERROR_MISSING;
-
- QuicFrames frames = {QuicFrame(&app_close_frame)};
-
- // clang-format off
- unsigned char packet_ietf[] = {
- // type (short header, 4 byte packet number)
- 0x43,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
-
- // frame type (IETF_APPLICATION_CLOSE frame)
- 0x1d,
- // error code
- kVarInt62OneByte + 0x11,
- // error details length
- kVarInt62TwoBytes + 0x01, 0x00,
- // error details (truncated to 256 bytes)
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- };
- // clang-format on
-
- std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
- ASSERT_TRUE(data != nullptr);
-
- quiche::test::CompareCharArraysWithHexError(
- "constructed packet", data->data(), data->length(), AsChars(packet_ietf),
- ABSL_ARRAYSIZE(packet_ietf));
-}
-
-TEST_P(QuicFramerTest, BuildGoAwayPacket) {
- if (VersionHasIetfQuicFrames(framer_.transport_version())) {
- // This frame is only for Google QUIC.
- return;
- }
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
- QuicPacketHeader header;
- header.destination_connection_id = FramerTestConnectionId();
- header.reset_flag = false;
- header.version_flag = false;
- header.packet_number = kPacketNumber;
-
- QuicGoAwayFrame goaway_frame;
- goaway_frame.error_code = static_cast<QuicErrorCode>(0x05060708);
- goaway_frame.last_good_stream_id = kStreamId;
- goaway_frame.reason_phrase = "because I can";
-
- QuicFrames frames = {QuicFrame(&goaway_frame)};
-
- // clang-format off
- unsigned char packet[] = {
- // public flags (8 byte connection_id)
- 0x2C,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
-
- // frame type (go away frame)
- 0x03,
- // error code
- 0x05, 0x06, 0x07, 0x08,
- // stream id
- 0x01, 0x02, 0x03, 0x04,
- // error details length
- 0x00, 0x0d,
- // error details
- 'b', 'e', 'c', 'a',
- 'u', 's', 'e', ' ',
- 'I', ' ', 'c', 'a',
- 'n',
- };
-
- unsigned char packet46[] = {
- // type (short header, 4 byte packet number)
- 0x43,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
-
- // frame type (go away frame)
- 0x03,
- // error code
- 0x05, 0x06, 0x07, 0x08,
- // stream id
- 0x01, 0x02, 0x03, 0x04,
- // error details length
- 0x00, 0x0d,
- // error details
- 'b', 'e', 'c', 'a',
- 'u', 's', 'e', ' ',
- 'I', ' ', 'c', 'a',
- 'n',
- };
-
- // clang-format on
-
- unsigned char* p = packet;
- size_t p_size = ABSL_ARRAYSIZE(packet);
- if (framer_.version().HasIetfInvariantHeader()) {
- p = packet46;
- p_size = ABSL_ARRAYSIZE(packet46);
- }
-
- std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
- ASSERT_TRUE(data != nullptr);
-
- quiche::test::CompareCharArraysWithHexError(
- "constructed packet", data->data(), data->length(), AsChars(p), p_size);
-}
-
-TEST_P(QuicFramerTest, BuildTruncatedGoAwayPacket) {
- if (VersionHasIetfQuicFrames(framer_.transport_version())) {
- // This frame is only for Google QUIC.
- return;
- }
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
- QuicPacketHeader header;
- header.destination_connection_id = FramerTestConnectionId();
- header.reset_flag = false;
- header.version_flag = false;
- header.packet_number = kPacketNumber;
-
- QuicGoAwayFrame goaway_frame;
- goaway_frame.error_code = static_cast<QuicErrorCode>(0x05060708);
- goaway_frame.last_good_stream_id = kStreamId;
- goaway_frame.reason_phrase = std::string(2048, 'A');
-
- QuicFrames frames = {QuicFrame(&goaway_frame)};
-
- // clang-format off
- unsigned char packet[] = {
- // public flags (8 byte connection_id)
- 0x2C,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
-
- // frame type (go away frame)
- 0x03,
- // error code
- 0x05, 0x06, 0x07, 0x08,
- // stream id
- 0x01, 0x02, 0x03, 0x04,
- // error details length
- 0x01, 0x00,
- // error details (truncated to 256 bytes)
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- };
-
- unsigned char packet46[] = {
- // type (short header, 4 byte packet number)
- 0x43,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
-
- // frame type (go away frame)
- 0x03,
- // error code
- 0x05, 0x06, 0x07, 0x08,
- // stream id
- 0x01, 0x02, 0x03, 0x04,
- // error details length
- 0x01, 0x00,
- // error details (truncated to 256 bytes)
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
- };
- // clang-format on
-
- unsigned char* p = packet;
- size_t p_size = ABSL_ARRAYSIZE(packet);
- if (framer_.version().HasIetfInvariantHeader()) {
- p = packet46;
- p_size = ABSL_ARRAYSIZE(packet46);
- }
-
- std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
- ASSERT_TRUE(data != nullptr);
-
- quiche::test::CompareCharArraysWithHexError(
- "constructed packet", data->data(), data->length(), AsChars(p), p_size);
-}
-
-TEST_P(QuicFramerTest, BuildWindowUpdatePacket) {
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
- QuicPacketHeader header;
- header.destination_connection_id = FramerTestConnectionId();
- header.reset_flag = false;
- header.version_flag = false;
- header.packet_number = kPacketNumber;
-
- QuicWindowUpdateFrame window_update_frame;
- window_update_frame.stream_id = kStreamId;
- window_update_frame.max_data = 0x1122334455667788;
-
- QuicFrames frames = {QuicFrame(&window_update_frame)};
-
- // clang-format off
- unsigned char packet[] = {
- // public flags (8 byte connection_id)
- 0x2C,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
-
- // frame type (window update frame)
- 0x04,
- // stream id
- 0x01, 0x02, 0x03, 0x04,
- // byte offset
- 0x11, 0x22, 0x33, 0x44,
- 0x55, 0x66, 0x77, 0x88,
- };
-
- unsigned char packet46[] = {
- // type (short header, 4 byte packet number)
- 0x43,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
-
- // frame type (window update frame)
- 0x04,
- // stream id
- 0x01, 0x02, 0x03, 0x04,
- // byte offset
- 0x11, 0x22, 0x33, 0x44,
- 0x55, 0x66, 0x77, 0x88,
- };
-
- unsigned char packet_ietf[] = {
- // type (short header, 4 byte packet number)
- 0x43,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
-
- // frame type (IETF_MAX_STREAM_DATA frame)
- 0x11,
- // stream id
- kVarInt62FourBytes + 0x01, 0x02, 0x03, 0x04,
- // byte offset
- kVarInt62EightBytes + 0x11, 0x22, 0x33, 0x44,
- 0x55, 0x66, 0x77, 0x88,
- };
- // clang-format on
-
- std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
- ASSERT_TRUE(data != nullptr);
-
- unsigned char* p = packet;
- size_t p_size = ABSL_ARRAYSIZE(packet);
- if (VersionHasIetfQuicFrames(framer_.transport_version())) {
- p = packet_ietf;
- p_size = ABSL_ARRAYSIZE(packet_ietf);
- } else if (framer_.version().HasIetfInvariantHeader()) {
- p = packet46;
- p_size = ABSL_ARRAYSIZE(packet46);
- }
-
- quiche::test::CompareCharArraysWithHexError(
- "constructed packet", data->data(), data->length(), AsChars(p), p_size);
-}
-
-TEST_P(QuicFramerTest, BuildMaxStreamDataPacket) {
- if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
- // This frame is only for IETF QUIC.
- return;
- }
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
- QuicPacketHeader header;
- header.destination_connection_id = FramerTestConnectionId();
- header.reset_flag = false;
- header.version_flag = false;
- header.packet_number = kPacketNumber;
-
- QuicWindowUpdateFrame window_update_frame;
- window_update_frame.stream_id = kStreamId;
- window_update_frame.max_data = 0x1122334455667788;
-
- QuicFrames frames = {QuicFrame(&window_update_frame)};
-
- // clang-format off
- unsigned char packet_ietf[] = {
- // type (short header, 4 byte packet number)
- 0x43,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
-
- // frame type (IETF_MAX_STREAM_DATA frame)
- 0x11,
- // stream id
- kVarInt62FourBytes + 0x01, 0x02, 0x03, 0x04,
- // byte offset
- kVarInt62EightBytes + 0x11, 0x22, 0x33, 0x44,
- 0x55, 0x66, 0x77, 0x88,
- };
- // clang-format on
-
- std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
- ASSERT_TRUE(data != nullptr);
-
- quiche::test::CompareCharArraysWithHexError(
- "constructed packet", data->data(), data->length(), AsChars(packet_ietf),
- ABSL_ARRAYSIZE(packet_ietf));
-}
-
-TEST_P(QuicFramerTest, BuildMaxDataPacket) {
- if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
- // This frame is only for IETF QUIC.
- return;
- }
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
- QuicPacketHeader header;
- header.destination_connection_id = FramerTestConnectionId();
- header.reset_flag = false;
- header.version_flag = false;
- header.packet_number = kPacketNumber;
-
- QuicWindowUpdateFrame window_update_frame;
- window_update_frame.stream_id =
- QuicUtils::GetInvalidStreamId(framer_.transport_version());
- window_update_frame.max_data = 0x1122334455667788;
-
- QuicFrames frames = {QuicFrame(&window_update_frame)};
-
- // clang-format off
- unsigned char packet_ietf[] = {
- // type (short header, 4 byte packet number)
- 0x43,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
-
- // frame type (IETF_MAX_DATA frame)
- 0x10,
- // byte offset
- kVarInt62EightBytes + 0x11, 0x22, 0x33, 0x44,
- 0x55, 0x66, 0x77, 0x88,
- };
- // clang-format on
-
- std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
- ASSERT_TRUE(data != nullptr);
-
- quiche::test::CompareCharArraysWithHexError(
- "constructed packet", data->data(), data->length(), AsChars(packet_ietf),
- ABSL_ARRAYSIZE(packet_ietf));
-}
-
-TEST_P(QuicFramerTest, BuildBlockedPacket) {
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
- QuicPacketHeader header;
- header.destination_connection_id = FramerTestConnectionId();
- header.reset_flag = false;
- header.version_flag = false;
- header.packet_number = kPacketNumber;
-
- QuicBlockedFrame blocked_frame;
- if (VersionHasIetfQuicFrames(framer_.transport_version())) {
- // For IETF QUIC, the stream ID must be <invalid> for the frame
- // to be a BLOCKED frame. if it's valid, it will be a
- // STREAM_BLOCKED frame.
- blocked_frame.stream_id =
- QuicUtils::GetInvalidStreamId(framer_.transport_version());
- } else {
- blocked_frame.stream_id = kStreamId;
- }
- blocked_frame.offset = kStreamOffset;
-
- QuicFrames frames = {QuicFrame(&blocked_frame)};
-
- // clang-format off
- unsigned char packet[] = {
- // public flags (8 byte connection_id)
- 0x2C,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
-
- // frame type (blocked frame)
- 0x05,
- // stream id
- 0x01, 0x02, 0x03, 0x04,
- };
-
- unsigned char packet46[] = {
- // type (short packet, 4 byte packet number)
- 0x43,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
-
- // frame type (blocked frame)
- 0x05,
- // stream id
- 0x01, 0x02, 0x03, 0x04,
- };
-
- unsigned char packet_ietf[] = {
- // type (short packet, 4 byte packet number)
- 0x43,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
-
- // frame type (IETF_DATA_BLOCKED frame)
- 0x14,
- // Offset
- kVarInt62EightBytes + 0x3a, 0x98, 0xFE, 0xDC, 0x32, 0x10, 0x76, 0x54
- };
- // clang-format on
-
- std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
- ASSERT_TRUE(data != nullptr);
-
- unsigned char* p = packet;
- size_t p_size = ABSL_ARRAYSIZE(packet);
- if (VersionHasIetfQuicFrames(framer_.transport_version())) {
- p = packet_ietf;
- p_size = ABSL_ARRAYSIZE(packet_ietf);
- } else if (framer_.version().HasIetfInvariantHeader()) {
- p = packet46;
- p_size = ABSL_ARRAYSIZE(packet46);
- }
-
- quiche::test::CompareCharArraysWithHexError(
- "constructed packet", data->data(), data->length(), AsChars(p), p_size);
-}
-
-TEST_P(QuicFramerTest, BuildPingPacket) {
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
- QuicPacketHeader header;
- header.destination_connection_id = FramerTestConnectionId();
- header.reset_flag = false;
- header.version_flag = false;
- header.packet_number = kPacketNumber;
-
- QuicFrames frames = {QuicFrame(QuicPingFrame())};
-
- // clang-format off
- unsigned char packet[] = {
- // public flags (8 byte connection_id)
- 0x2C,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
-
- // frame type (ping frame)
- 0x07,
- };
-
- unsigned char packet46[] = {
- // type (short header, 4 byte packet number)
- 0x43,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
-
- // frame type
- 0x07,
- };
-
- unsigned char packet_ietf[] = {
- // type (short header, 4 byte packet number)
- 0x43,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
-
- // frame type (IETF_PING frame)
- 0x01,
- };
- // clang-format on
-
- unsigned char* p = packet;
- if (VersionHasIetfQuicFrames(framer_.transport_version())) {
- p = packet_ietf;
- } else if (framer_.version().HasIetfInvariantHeader()) {
- p = packet46;
- }
-
- std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
- ASSERT_TRUE(data != nullptr);
-
- quiche::test::CompareCharArraysWithHexError(
- "constructed packet", data->data(), data->length(), AsChars(p),
- framer_.version().HasIetfInvariantHeader() ? ABSL_ARRAYSIZE(packet46)
- : ABSL_ARRAYSIZE(packet));
-}
-
-TEST_P(QuicFramerTest, BuildHandshakeDonePacket) {
- QuicPacketHeader header;
- header.destination_connection_id = FramerTestConnectionId();
- header.reset_flag = false;
- header.version_flag = false;
- header.packet_number = kPacketNumber;
-
- QuicFrames frames = {QuicFrame(QuicHandshakeDoneFrame())};
-
- // clang-format off
- unsigned char packet[] = {
- // type (short header, 4 byte packet number)
- 0x43,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
-
- // frame type (Handshake done frame)
- 0x1e,
- };
- // clang-format on
- if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
- return;
- }
-
- std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
- ASSERT_TRUE(data != nullptr);
-
- quiche::test::CompareCharArraysWithHexError(
- "constructed packet", data->data(), data->length(), AsChars(packet),
- ABSL_ARRAYSIZE(packet));
-}
-
-TEST_P(QuicFramerTest, BuildAckFrequencyPacket) {
- QuicPacketHeader header;
- header.destination_connection_id = FramerTestConnectionId();
- header.reset_flag = false;
- header.version_flag = false;
- header.packet_number = kPacketNumber;
-
- QuicAckFrequencyFrame ack_frequency_frame;
- ack_frequency_frame.sequence_number = 3;
- ack_frequency_frame.packet_tolerance = 5;
- ack_frequency_frame.max_ack_delay = QuicTime::Delta::FromMicroseconds(0x3fff);
- ack_frequency_frame.ignore_order = false;
- QuicFrames frames = {QuicFrame(&ack_frequency_frame)};
-
- // clang-format off
- unsigned char packet[] = {
- // type (short header, 4 byte packet number)
- 0x43,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
-
- // frame type (Ack Frequency frame)
- 0x40, 0xaf,
- // sequence number
- 0x03,
- // packet tolerance
- 0x05,
- // max_ack_delay_us
- 0x7f, 0xff,
- // ignore_oder
- 0x00
- };
- // clang-format on
- if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
- return;
- }
-
- std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
- ASSERT_TRUE(data != nullptr);
-
- quiche::test::CompareCharArraysWithHexError(
- "constructed packet", data->data(), data->length(), AsChars(packet),
- ABSL_ARRAYSIZE(packet));
-}
-
-TEST_P(QuicFramerTest, BuildMessagePacket) {
- if (!VersionSupportsMessageFrames(framer_.transport_version())) {
- return;
- }
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
- QuicPacketHeader header;
- header.destination_connection_id = FramerTestConnectionId();
- header.reset_flag = false;
- header.version_flag = false;
- header.packet_number = kPacketNumber;
-
- QuicMessageFrame frame(1, MemSliceFromString("message"));
- QuicMessageFrame frame2(2, MemSliceFromString("message2"));
- QuicFrames frames = {QuicFrame(&frame), QuicFrame(&frame2)};
-
- // clang-format off
- unsigned char packet46[] = {
- // type (short header, 4 byte packet number)
- 0x43,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
-
- // frame type (message frame)
- 0x21,
- // Length
- 0x07,
- // Message Data
- 'm', 'e', 's', 's', 'a', 'g', 'e',
- // frame type (message frame no length)
- 0x20,
- // Message Data
- 'm', 'e', 's', 's', 'a', 'g', 'e', '2'
- };
-
- unsigned char packet_ietf[] = {
- // type (short header, 4 byte packet number)
- 0x43,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
-
- // frame type (IETF_MESSAGE frame)
- 0x31,
- // Length
- 0x07,
- // Message Data
- 'm', 'e', 's', 's', 'a', 'g', 'e',
- // frame type (message frame no length)
- 0x30,
- // Message Data
- 'm', 'e', 's', 's', 'a', 'g', 'e', '2'
- };
- // clang-format on
-
- unsigned char* p = packet46;
- if (VersionHasIetfQuicFrames(framer_.transport_version())) {
- p = packet_ietf;
- }
-
- std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
- ASSERT_TRUE(data != nullptr);
-
- quiche::test::CompareCharArraysWithHexError(
- "constructed packet", data->data(), data->length(), AsChars(p),
- ABSL_ARRAYSIZE(packet46));
-}
-
-// Test that the MTU discovery packet is serialized correctly as a PING packet.
-TEST_P(QuicFramerTest, BuildMtuDiscoveryPacket) {
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
- QuicPacketHeader header;
- header.destination_connection_id = FramerTestConnectionId();
- header.reset_flag = false;
- header.version_flag = false;
- header.packet_number = kPacketNumber;
-
- QuicFrames frames = {QuicFrame(QuicMtuDiscoveryFrame())};
-
- // clang-format off
- unsigned char packet[] = {
- // public flags (8 byte connection_id)
- 0x2C,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
-
- // frame type (ping frame)
- 0x07,
- };
-
- unsigned char packet46[] = {
- // type (short header, 4 byte packet number)
- 0x43,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
-
- // frame type
- 0x07,
- };
-
- unsigned char packet_ietf[] = {
- // type (short header, 4 byte packet number)
- 0x43,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
-
- // frame type (IETF_PING frame)
- 0x01,
- };
- // clang-format on
-
- std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
- ASSERT_TRUE(data != nullptr);
-
- unsigned char* p = packet;
- if (VersionHasIetfQuicFrames(framer_.transport_version())) {
- p = packet_ietf;
- } else if (framer_.version().HasIetfInvariantHeader()) {
- p = packet46;
- }
-
- quiche::test::CompareCharArraysWithHexError(
- "constructed packet", data->data(), data->length(), AsChars(p),
- framer_.version().HasIetfInvariantHeader() ? ABSL_ARRAYSIZE(packet46)
- : ABSL_ARRAYSIZE(packet));
-}
-
-TEST_P(QuicFramerTest, BuildPublicResetPacket) {
- QuicPublicResetPacket reset_packet;
- reset_packet.connection_id = FramerTestConnectionId();
- reset_packet.nonce_proof = kNonceProof;
-
- // clang-format off
- unsigned char packet[] = {
- // public flags (public reset, 8 byte ConnectionId)
- 0x0E,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // message tag (kPRST)
- 'P', 'R', 'S', 'T',
- // num_entries (1) + padding
- 0x01, 0x00, 0x00, 0x00,
- // tag kRNON
- 'R', 'N', 'O', 'N',
- // end offset 8
- 0x08, 0x00, 0x00, 0x00,
- // nonce proof
- 0x89, 0x67, 0x45, 0x23,
- 0x01, 0xEF, 0xCD, 0xAB,
- };
- // clang-format on
-
- if (framer_.version().HasIetfInvariantHeader()) {
- return;
- }
-
- std::unique_ptr<QuicEncryptedPacket> data(
- framer_.BuildPublicResetPacket(reset_packet));
- ASSERT_TRUE(data != nullptr);
- quiche::test::CompareCharArraysWithHexError(
- "constructed packet", data->data(), data->length(), AsChars(packet),
- ABSL_ARRAYSIZE(packet));
-}
-
-TEST_P(QuicFramerTest, BuildPublicResetPacketWithClientAddress) {
- QuicPublicResetPacket reset_packet;
- reset_packet.connection_id = FramerTestConnectionId();
- reset_packet.nonce_proof = kNonceProof;
- reset_packet.client_address =
- QuicSocketAddress(QuicIpAddress::Loopback4(), 0x1234);
-
- // clang-format off
- unsigned char packet[] = {
- // public flags (public reset, 8 byte ConnectionId)
- 0x0E,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98,
- 0x76, 0x54, 0x32, 0x10,
- // message tag (kPRST)
- 'P', 'R', 'S', 'T',
- // num_entries (2) + padding
- 0x02, 0x00, 0x00, 0x00,
- // tag kRNON
- 'R', 'N', 'O', 'N',
- // end offset 8
- 0x08, 0x00, 0x00, 0x00,
- // tag kCADR
- 'C', 'A', 'D', 'R',
- // end offset 16
- 0x10, 0x00, 0x00, 0x00,
- // nonce proof
- 0x89, 0x67, 0x45, 0x23,
- 0x01, 0xEF, 0xCD, 0xAB,
- // client address
- 0x02, 0x00,
- 0x7F, 0x00, 0x00, 0x01,
- 0x34, 0x12,
- };
- // clang-format on
-
- if (framer_.version().HasIetfInvariantHeader()) {
- return;
- }
-
- std::unique_ptr<QuicEncryptedPacket> data(
- framer_.BuildPublicResetPacket(reset_packet));
- ASSERT_TRUE(data != nullptr);
-
- quiche::test::CompareCharArraysWithHexError(
- "constructed packet", data->data(), data->length(), AsChars(packet),
- ABSL_ARRAYSIZE(packet));
-}
-
-TEST_P(QuicFramerTest, BuildPublicResetPacketWithEndpointId) {
- QuicPublicResetPacket reset_packet;
- reset_packet.connection_id = FramerTestConnectionId();
- reset_packet.nonce_proof = kNonceProof;
- reset_packet.endpoint_id = "FakeServerId";
-
- // The tag value map in CryptoHandshakeMessage is a std::map, so the two tags
- // in the packet, kRNON and kEPID, have unspecified ordering w.r.t each other.
- // clang-format off
- unsigned char packet_variant1[] = {
- // public flags (public reset, 8 byte ConnectionId)
- 0x0E,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98,
- 0x76, 0x54, 0x32, 0x10,
- // message tag (kPRST)
- 'P', 'R', 'S', 'T',
- // num_entries (2) + padding
- 0x02, 0x00, 0x00, 0x00,
- // tag kRNON
- 'R', 'N', 'O', 'N',
- // end offset 8
- 0x08, 0x00, 0x00, 0x00,
- // tag kEPID
- 'E', 'P', 'I', 'D',
- // end offset 20
- 0x14, 0x00, 0x00, 0x00,
- // nonce proof
- 0x89, 0x67, 0x45, 0x23,
- 0x01, 0xEF, 0xCD, 0xAB,
- // Endpoint ID
- 'F', 'a', 'k', 'e', 'S', 'e', 'r', 'v', 'e', 'r', 'I', 'd',
- };
- unsigned char packet_variant2[] = {
- // public flags (public reset, 8 byte ConnectionId)
- 0x0E,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98,
- 0x76, 0x54, 0x32, 0x10,
- // message tag (kPRST)
- 'P', 'R', 'S', 'T',
- // num_entries (2) + padding
- 0x02, 0x00, 0x00, 0x00,
- // tag kEPID
- 'E', 'P', 'I', 'D',
- // end offset 12
- 0x0C, 0x00, 0x00, 0x00,
- // tag kRNON
- 'R', 'N', 'O', 'N',
- // end offset 20
- 0x14, 0x00, 0x00, 0x00,
- // Endpoint ID
- 'F', 'a', 'k', 'e', 'S', 'e', 'r', 'v', 'e', 'r', 'I', 'd',
- // nonce proof
- 0x89, 0x67, 0x45, 0x23,
- 0x01, 0xEF, 0xCD, 0xAB,
- };
- // clang-format on
-
- if (framer_.version().HasIetfInvariantHeader()) {
- return;
- }
-
- std::unique_ptr<QuicEncryptedPacket> data(
- framer_.BuildPublicResetPacket(reset_packet));
- ASSERT_TRUE(data != nullptr);
-
- // Variant 1 ends with char 'd'. Variant 1 ends with char 0xAB.
- if ('d' == data->data()[data->length() - 1]) {
- quiche::test::CompareCharArraysWithHexError(
- "constructed packet", data->data(), data->length(),
- AsChars(packet_variant1), ABSL_ARRAYSIZE(packet_variant1));
- } else {
- quiche::test::CompareCharArraysWithHexError(
- "constructed packet", data->data(), data->length(),
- AsChars(packet_variant2), ABSL_ARRAYSIZE(packet_variant2));
- }
-}
-
-TEST_P(QuicFramerTest, BuildIetfStatelessResetPacket) {
- // clang-format off
- unsigned char packet[] = {
- // 1st byte 01XX XXXX
- 0x40,
- // At least 4 bytes of random bytes.
- 0x00, 0x00, 0x00, 0x00,
- // stateless reset token
- 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
- 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f
- };
- // clang-format on
-
- // Build the minimal stateless reset packet.
- std::unique_ptr<QuicEncryptedPacket> data(
- framer_.BuildIetfStatelessResetPacket(
- FramerTestConnectionId(),
- QuicFramer::GetMinStatelessResetPacketLength() + 1,
- kTestStatelessResetToken));
- ASSERT_TRUE(data);
- EXPECT_EQ(QuicFramer::GetMinStatelessResetPacketLength(), data->length());
- // Verify the first 2 bits are 01.
- EXPECT_FALSE(data->data()[0] & FLAGS_LONG_HEADER);
- EXPECT_TRUE(data->data()[0] & FLAGS_FIXED_BIT);
- // Verify stateless reset token.
- quiche::test::CompareCharArraysWithHexError(
- "constructed packet",
- data->data() + data->length() - kStatelessResetTokenLength,
- kStatelessResetTokenLength,
- AsChars(packet) + ABSL_ARRAYSIZE(packet) - kStatelessResetTokenLength,
- kStatelessResetTokenLength);
-
- // Packets with length <= minimal stateless reset does not trigger stateless
- // reset.
- std::unique_ptr<QuicEncryptedPacket> data2(
- framer_.BuildIetfStatelessResetPacket(
- FramerTestConnectionId(),
- QuicFramer::GetMinStatelessResetPacketLength(),
- kTestStatelessResetToken));
- ASSERT_FALSE(data2);
-
- // Do not send stateless reset >= minimal stateless reset + 1 + max
- // connection ID length.
- std::unique_ptr<QuicEncryptedPacket> data3(
- framer_.BuildIetfStatelessResetPacket(FramerTestConnectionId(), 1000,
- kTestStatelessResetToken));
- ASSERT_TRUE(data3);
- EXPECT_EQ(QuicFramer::GetMinStatelessResetPacketLength() + 1 +
- kQuicMaxConnectionIdWithLengthPrefixLength,
- data3->length());
-}
-
-TEST_P(QuicFramerTest, EncryptPacket) {
- QuicPacketNumber packet_number = kPacketNumber;
- // clang-format off
- unsigned char packet[] = {
- // public flags (8 byte connection_id)
- 0x28,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
-
- // redundancy
- 'a', 'b', 'c', 'd',
- 'e', 'f', 'g', 'h',
- 'i', 'j', 'k', 'l',
- 'm', 'n', 'o', 'p',
- };
-
- unsigned char packet46[] = {
- // type (short header, 4 byte packet number)
- 0x43,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
-
- // redundancy
- 'a', 'b', 'c', 'd',
- 'e', 'f', 'g', 'h',
- 'i', 'j', 'k', 'l',
- 'm', 'n', 'o', 'p',
- };
-
- unsigned char packet50[] = {
- // type (short header, 4 byte packet number)
- 0x43,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
-
- // redundancy
- 'a', 'b', 'c', 'd',
- 'e', 'f', 'g', 'h',
- 'i', 'j', 'k', 'l',
- 'm', 'n', 'o', 'p',
- 'q', 'r', 's', 't',
- };
- // clang-format on
-
- unsigned char* p = packet;
- size_t p_size = ABSL_ARRAYSIZE(packet);
- if (framer_.version().HasHeaderProtection()) {
- p = packet50;
- p_size = ABSL_ARRAYSIZE(packet50);
- } else if (framer_.version().HasIetfInvariantHeader()) {
- p = packet46;
- }
-
- std::unique_ptr<QuicPacket> raw(new QuicPacket(
- AsChars(p), p_size, false, PACKET_8BYTE_CONNECTION_ID,
- PACKET_0BYTE_CONNECTION_ID, !kIncludeVersion,
- !kIncludeDiversificationNonce, PACKET_4BYTE_PACKET_NUMBER,
- VARIABLE_LENGTH_INTEGER_LENGTH_0, 0, VARIABLE_LENGTH_INTEGER_LENGTH_0));
- char buffer[kMaxOutgoingPacketSize];
- size_t encrypted_length = framer_.EncryptPayload(
- ENCRYPTION_INITIAL, packet_number, *raw, buffer, kMaxOutgoingPacketSize);
-
- ASSERT_NE(0u, encrypted_length);
- EXPECT_TRUE(CheckEncryption(packet_number, raw.get()));
-}
-
-// Regression test for b/158014497.
-TEST_P(QuicFramerTest, EncryptEmptyPacket) {
- auto packet = std::make_unique<QuicPacket>(
- new char[100], 0, true, PACKET_8BYTE_CONNECTION_ID,
- PACKET_0BYTE_CONNECTION_ID,
- /*includes_version=*/true,
- /*includes_diversification_nonce=*/true, PACKET_1BYTE_PACKET_NUMBER,
- VARIABLE_LENGTH_INTEGER_LENGTH_0,
- /*retry_token_length=*/0, VARIABLE_LENGTH_INTEGER_LENGTH_0);
- char buffer[kMaxOutgoingPacketSize];
- size_t encrypted_length = 1;
- EXPECT_QUIC_BUG(encrypted_length = framer_.EncryptPayload(
- ENCRYPTION_INITIAL, kPacketNumber, *packet, buffer,
- kMaxOutgoingPacketSize),
- "packet is shorter than associated data length");
- EXPECT_EQ(0u, encrypted_length);
-}
-
-TEST_P(QuicFramerTest, EncryptPacketWithVersionFlag) {
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
- QuicPacketNumber packet_number = kPacketNumber;
- // clang-format off
- unsigned char packet[] = {
- // public flags (version, 8 byte connection_id)
- 0x29,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // version tag
- 'Q', '.', '1', '0',
- // packet number
- 0x12, 0x34, 0x56, 0x78,
-
- // redundancy
- 'a', 'b', 'c', 'd',
- 'e', 'f', 'g', 'h',
- 'i', 'j', 'k', 'l',
- 'm', 'n', 'o', 'p',
- };
-
- unsigned char packet46[] = {
- // type (long header with packet type ZERO_RTT_PROTECTED)
- 0xD3,
- // version tag
- 'Q', '.', '1', '0',
- // connection_id length
- 0x50,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
-
- // redundancy
- 'a', 'b', 'c', 'd',
- 'e', 'f', 'g', 'h',
- 'i', 'j', 'k', 'l',
- 'm', 'n', 'o', 'p',
- };
-
- unsigned char packet50[] = {
- // type (long header with packet type ZERO_RTT_PROTECTED)
- 0xD3,
- // version tag
- 'Q', '.', '1', '0',
- // destination connection ID length
- 0x08,
- // destination connection ID
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // source connection ID length
- 0x00,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
-
- // redundancy
- 'a', 'b', 'c', 'd',
- 'e', 'f', 'g', 'h',
- 'i', 'j', 'k', 'l',
- 'm', 'n', 'o', 'p',
- 'q', 'r', 's', 't',
- };
- // clang-format on
-
- unsigned char* p = packet;
- size_t p_size = ABSL_ARRAYSIZE(packet);
- // TODO(ianswett): see todo in previous test.
- if (framer_.version().HasHeaderProtection()) {
- p = packet50;
- p_size = ABSL_ARRAYSIZE(packet50);
- } else if (framer_.version().HasIetfInvariantHeader()) {
- p = packet46;
- p_size = ABSL_ARRAYSIZE(packet46);
- }
-
- std::unique_ptr<QuicPacket> raw(new QuicPacket(
- AsChars(p), p_size, false, PACKET_8BYTE_CONNECTION_ID,
- PACKET_0BYTE_CONNECTION_ID, kIncludeVersion,
- !kIncludeDiversificationNonce, PACKET_4BYTE_PACKET_NUMBER,
- VARIABLE_LENGTH_INTEGER_LENGTH_0, 0, VARIABLE_LENGTH_INTEGER_LENGTH_0));
- char buffer[kMaxOutgoingPacketSize];
- size_t encrypted_length = framer_.EncryptPayload(
- ENCRYPTION_INITIAL, packet_number, *raw, buffer, kMaxOutgoingPacketSize);
-
- ASSERT_NE(0u, encrypted_length);
- EXPECT_TRUE(CheckEncryption(packet_number, raw.get()));
-}
-
-TEST_P(QuicFramerTest, AckTruncationLargePacket) {
- if (VersionHasIetfQuicFrames(framer_.transport_version())) {
- // This test is not applicable to this version; the range count is
- // effectively unlimited
- return;
- }
- SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-
- QuicPacketHeader header;
- header.destination_connection_id = FramerTestConnectionId();
- header.reset_flag = false;
- header.version_flag = false;
- header.packet_number = kPacketNumber;
-
- QuicAckFrame ack_frame;
- // Create a packet with just the ack.
- ack_frame = MakeAckFrameWithAckBlocks(300, 0u);
- QuicFrames frames = {QuicFrame(&ack_frame)};
-
- // Build an ack packet with truncation due to limit in number of nack ranges.
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
- std::unique_ptr<QuicPacket> raw_ack_packet(BuildDataPacket(header, frames));
- ASSERT_TRUE(raw_ack_packet != nullptr);
- char buffer[kMaxOutgoingPacketSize];
- size_t encrypted_length =
- framer_.EncryptPayload(ENCRYPTION_INITIAL, header.packet_number,
- *raw_ack_packet, buffer, kMaxOutgoingPacketSize);
- ASSERT_NE(0u, encrypted_length);
- // Now make sure we can turn our ack packet back into an ack frame.
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
- ASSERT_TRUE(framer_.ProcessPacket(
- QuicEncryptedPacket(buffer, encrypted_length, false)));
- ASSERT_EQ(1u, visitor_.ack_frames_.size());
- QuicAckFrame& processed_ack_frame = *visitor_.ack_frames_[0];
- EXPECT_EQ(QuicPacketNumber(600u), LargestAcked(processed_ack_frame));
- ASSERT_EQ(256u, processed_ack_frame.packets.NumPacketsSlow());
- EXPECT_EQ(QuicPacketNumber(90u), processed_ack_frame.packets.Min());
- EXPECT_EQ(QuicPacketNumber(600u), processed_ack_frame.packets.Max());
-}
-
-// Regression test for b/150386368.
-TEST_P(QuicFramerTest, IetfAckFrameTruncation) {
- if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
- return;
- }
- SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-
- QuicPacketHeader header;
- header.destination_connection_id = FramerTestConnectionId();
- header.reset_flag = false;
- header.version_flag = false;
- header.packet_number = kPacketNumber;
-
- QuicAckFrame ack_frame;
- // Create a packet with just the ack.
- ack_frame = MakeAckFrameWithGaps(/*gap_size=*/0xffffffff,
- /*max_num_gaps=*/200,
- /*largest_acked=*/kMaxIetfVarInt);
- ack_frame.ecn_counters_populated = true;
- ack_frame.ect_0_count = 100;
- ack_frame.ect_1_count = 10000;
- ack_frame.ecn_ce_count = 1000000;
- QuicFrames frames = {QuicFrame(&ack_frame)};
- // Build an ACK packet.
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
- std::unique_ptr<QuicPacket> raw_ack_packet(BuildDataPacket(header, frames));
- ASSERT_TRUE(raw_ack_packet != nullptr);
- char buffer[kMaxOutgoingPacketSize];
- size_t encrypted_length =
- framer_.EncryptPayload(ENCRYPTION_INITIAL, header.packet_number,
- *raw_ack_packet, buffer, kMaxOutgoingPacketSize);
- ASSERT_NE(0u, encrypted_length);
- // Now make sure we can turn our ack packet back into an ack frame.
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
- ASSERT_TRUE(framer_.ProcessPacket(
- QuicEncryptedPacket(buffer, encrypted_length, false)));
- ASSERT_EQ(1u, visitor_.ack_frames_.size());
- QuicAckFrame& processed_ack_frame = *visitor_.ack_frames_[0];
- EXPECT_EQ(QuicPacketNumber(kMaxIetfVarInt),
- LargestAcked(processed_ack_frame));
- // Verify ACK frame gets truncated.
- ASSERT_LT(processed_ack_frame.packets.NumPacketsSlow(),
- ack_frame.packets.NumIntervals());
- EXPECT_EQ(157u, processed_ack_frame.packets.NumPacketsSlow());
- EXPECT_LT(processed_ack_frame.packets.NumIntervals(),
- ack_frame.packets.NumIntervals());
- EXPECT_EQ(QuicPacketNumber(kMaxIetfVarInt),
- processed_ack_frame.packets.Max());
-}
-
-TEST_P(QuicFramerTest, AckTruncationSmallPacket) {
- if (VersionHasIetfQuicFrames(framer_.transport_version())) {
- // This test is not applicable to this version; the range count is
- // effectively unlimited
- return;
- }
- SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-
- QuicPacketHeader header;
- header.destination_connection_id = FramerTestConnectionId();
- header.reset_flag = false;
- header.version_flag = false;
- header.packet_number = kPacketNumber;
-
- // Create a packet with just the ack.
- QuicAckFrame ack_frame;
- ack_frame = MakeAckFrameWithAckBlocks(300, 0u);
- QuicFrames frames = {QuicFrame(&ack_frame)};
-
- // Build an ack packet with truncation due to limit in number of nack ranges.
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
- std::unique_ptr<QuicPacket> raw_ack_packet(
- BuildDataPacket(header, frames, 500));
- ASSERT_TRUE(raw_ack_packet != nullptr);
- char buffer[kMaxOutgoingPacketSize];
- size_t encrypted_length =
- framer_.EncryptPayload(ENCRYPTION_INITIAL, header.packet_number,
- *raw_ack_packet, buffer, kMaxOutgoingPacketSize);
- ASSERT_NE(0u, encrypted_length);
- // Now make sure we can turn our ack packet back into an ack frame.
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
- ASSERT_TRUE(framer_.ProcessPacket(
- QuicEncryptedPacket(buffer, encrypted_length, false)));
- ASSERT_EQ(1u, visitor_.ack_frames_.size());
- QuicAckFrame& processed_ack_frame = *visitor_.ack_frames_[0];
- EXPECT_EQ(QuicPacketNumber(600u), LargestAcked(processed_ack_frame));
- ASSERT_EQ(240u, processed_ack_frame.packets.NumPacketsSlow());
- EXPECT_EQ(QuicPacketNumber(122u), processed_ack_frame.packets.Min());
- EXPECT_EQ(QuicPacketNumber(600u), processed_ack_frame.packets.Max());
-}
-
-TEST_P(QuicFramerTest, CleanTruncation) {
- if (VersionHasIetfQuicFrames(framer_.transport_version())) {
- // This test is not applicable to this version; the range count is
- // effectively unlimited
- return;
- }
- SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-
- QuicPacketHeader header;
- header.destination_connection_id = FramerTestConnectionId();
- header.reset_flag = false;
- header.version_flag = false;
- header.packet_number = kPacketNumber;
-
- QuicAckFrame ack_frame = InitAckFrame(201);
-
- // Create a packet with just the ack.
- QuicFrames frames = {QuicFrame(&ack_frame)};
- if (framer_.version().HasHeaderProtection()) {
- frames.push_back(QuicFrame(QuicPaddingFrame(12)));
- }
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
- std::unique_ptr<QuicPacket> raw_ack_packet(BuildDataPacket(header, frames));
- ASSERT_TRUE(raw_ack_packet != nullptr);
-
- char buffer[kMaxOutgoingPacketSize];
- size_t encrypted_length =
- framer_.EncryptPayload(ENCRYPTION_INITIAL, header.packet_number,
- *raw_ack_packet, buffer, kMaxOutgoingPacketSize);
- ASSERT_NE(0u, encrypted_length);
-
- // Now make sure we can turn our ack packet back into an ack frame.
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
- ASSERT_TRUE(framer_.ProcessPacket(
- QuicEncryptedPacket(buffer, encrypted_length, false)));
-
- // Test for clean truncation of the ack by comparing the length of the
- // original packets to the re-serialized packets.
- frames.clear();
- frames.push_back(QuicFrame(visitor_.ack_frames_[0].get()));
- if (framer_.version().HasHeaderProtection()) {
- frames.push_back(QuicFrame(*visitor_.padding_frames_[0].get()));
- }
-
- size_t original_raw_length = raw_ack_packet->length();
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
- raw_ack_packet = BuildDataPacket(header, frames);
- ASSERT_TRUE(raw_ack_packet != nullptr);
- EXPECT_EQ(original_raw_length, raw_ack_packet->length());
- ASSERT_TRUE(raw_ack_packet != nullptr);
-}
-
-TEST_P(QuicFramerTest, StopPacketProcessing) {
- SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
- // clang-format off
- unsigned char packet[] = {
- // public flags (8 byte connection_id)
- 0x28,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
-
- // frame type (stream frame with fin)
- 0xFF,
- // stream id
- 0x01, 0x02, 0x03, 0x04,
- // offset
- 0x3A, 0x98, 0xFE, 0xDC,
- 0x32, 0x10, 0x76, 0x54,
- // data length
- 0x00, 0x0c,
- // data
- 'h', 'e', 'l', 'l',
- 'o', ' ', 'w', 'o',
- 'r', 'l', 'd', '!',
-
- // frame type (ack frame)
- 0x40,
- // least packet number awaiting an ack
- 0x12, 0x34, 0x56, 0x78,
- 0x9A, 0xA0,
- // largest observed packet number
- 0x12, 0x34, 0x56, 0x78,
- 0x9A, 0xBF,
- // num missing packets
- 0x01,
- // missing packet
- 0x12, 0x34, 0x56, 0x78,
- 0x9A, 0xBE,
- };
-
- unsigned char packet46[] = {
- // type (short header, 4 byte packet number)
- 0x43,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
-
- // frame type (stream frame with fin)
- 0xFF,
- // stream id
- 0x01, 0x02, 0x03, 0x04,
- // offset
- 0x3A, 0x98, 0xFE, 0xDC,
- 0x32, 0x10, 0x76, 0x54,
- // data length
- 0x00, 0x0c,
- // data
- 'h', 'e', 'l', 'l',
- 'o', ' ', 'w', 'o',
- 'r', 'l', 'd', '!',
-
- // frame type (ack frame)
- 0x40,
- // least packet number awaiting an ack
- 0x12, 0x34, 0x56, 0x78,
- 0x9A, 0xA0,
- // largest observed packet number
- 0x12, 0x34, 0x56, 0x78,
- 0x9A, 0xBF,
- // num missing packets
- 0x01,
- // missing packet
- 0x12, 0x34, 0x56, 0x78,
- 0x9A, 0xBE,
- };
-
- unsigned char packet_ietf[] = {
- // type (short header, 4 byte packet number)
- 0x43,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
-
- // frame type (IETF_STREAM frame with fin, length, and offset bits set)
- 0x08 | 0x01 | 0x02 | 0x04,
- // stream id
- kVarInt62FourBytes + 0x01, 0x02, 0x03, 0x04,
- // offset
- kVarInt62EightBytes + 0x3A, 0x98, 0xFE, 0xDC,
- 0x32, 0x10, 0x76, 0x54,
- // data length
- kVarInt62TwoBytes + 0x00, 0x0c,
- // data
- 'h', 'e', 'l', 'l',
- 'o', ' ', 'w', 'o',
- 'r', 'l', 'd', '!',
-
- // frame type (ack frame)
- 0x0d,
- // largest observed packet number
- kVarInt62FourBytes + 0x12, 0x34, 0x56, 0x78,
- // Delta time
- kVarInt62OneByte + 0x00,
- // Ack Block count
- kVarInt62OneByte + 0x01,
- // First block size (one packet)
- kVarInt62OneByte + 0x00,
-
- // Next gap size & ack. Missing all preceding packets
- kVarInt62FourBytes + 0x12, 0x34, 0x56, 0x77,
- kVarInt62OneByte + 0x00,
- };
- // clang-format on
-
- MockFramerVisitor visitor;
- framer_.set_visitor(&visitor);
- EXPECT_CALL(visitor, OnPacket());
- EXPECT_CALL(visitor, OnPacketHeader(_));
- EXPECT_CALL(visitor, OnStreamFrame(_)).WillOnce(Return(false));
- EXPECT_CALL(visitor, OnPacketComplete());
- EXPECT_CALL(visitor, OnUnauthenticatedPublicHeader(_)).WillOnce(Return(true));
- EXPECT_CALL(visitor, OnUnauthenticatedHeader(_)).WillOnce(Return(true));
- EXPECT_CALL(visitor, OnDecryptedPacket(_, _));
-
- unsigned char* p = packet;
- size_t p_size = ABSL_ARRAYSIZE(packet);
- if (VersionHasIetfQuicFrames(framer_.transport_version())) {
- p = packet_ietf;
- p_size = ABSL_ARRAYSIZE(packet_ietf);
- } else if (framer_.version().HasIetfInvariantHeader()) {
- p = packet46;
- p_size = ABSL_ARRAYSIZE(packet46);
- }
- QuicEncryptedPacket encrypted(AsChars(p), p_size, false);
- EXPECT_TRUE(framer_.ProcessPacket(encrypted));
- EXPECT_THAT(framer_.error(), IsQuicNoError());
-}
-
-static char kTestString[] = "At least 20 characters.";
-static QuicStreamId kTestQuicStreamId = 1;
-
-MATCHER_P(ExpectedStreamFrame, version, "") {
- return (arg.stream_id == kTestQuicStreamId ||
- QuicUtils::IsCryptoStreamId(version.transport_version,
- arg.stream_id)) &&
- !arg.fin && arg.offset == 0 &&
- std::string(arg.data_buffer, arg.data_length) == kTestString;
- // FIN is hard-coded false in ConstructEncryptedPacket.
- // Offset 0 is hard-coded in ConstructEncryptedPacket.
-}
-
-// Verify that the packet returned by ConstructEncryptedPacket() can be properly
-// parsed by the framer.
-TEST_P(QuicFramerTest, ConstructEncryptedPacket) {
- // Since we are using ConstructEncryptedPacket, we have to set the framer's
- // crypto to be Null.
- if (framer_.version().KnowsWhichDecrypterToUse()) {
- framer_.InstallDecrypter(
- ENCRYPTION_FORWARD_SECURE,
- std::make_unique<NullDecrypter>(framer_.perspective()));
- } else {
- framer_.SetDecrypter(ENCRYPTION_INITIAL, std::make_unique<NullDecrypter>(
- framer_.perspective()));
- }
- ParsedQuicVersionVector versions;
- versions.push_back(framer_.version());
- std::unique_ptr<QuicEncryptedPacket> packet(ConstructEncryptedPacket(
- TestConnectionId(), EmptyQuicConnectionId(), false, false,
- kTestQuicStreamId, kTestString, CONNECTION_ID_PRESENT,
- CONNECTION_ID_ABSENT, PACKET_4BYTE_PACKET_NUMBER, &versions));
-
- MockFramerVisitor visitor;
- framer_.set_visitor(&visitor);
- EXPECT_CALL(visitor, OnPacket()).Times(1);
- EXPECT_CALL(visitor, OnUnauthenticatedPublicHeader(_))
- .Times(1)
- .WillOnce(Return(true));
- EXPECT_CALL(visitor, OnUnauthenticatedHeader(_))
- .Times(1)
- .WillOnce(Return(true));
- EXPECT_CALL(visitor, OnPacketHeader(_)).Times(1).WillOnce(Return(true));
- EXPECT_CALL(visitor, OnDecryptedPacket(_, _)).Times(1);
- EXPECT_CALL(visitor, OnError(_)).Times(0);
- EXPECT_CALL(visitor, OnStreamFrame(_)).Times(0);
- if (!QuicVersionUsesCryptoFrames(framer_.version().transport_version)) {
- EXPECT_CALL(visitor, OnStreamFrame(ExpectedStreamFrame(framer_.version())))
- .Times(1);
- } else {
- EXPECT_CALL(visitor, OnCryptoFrame(_)).Times(1);
- }
- EXPECT_CALL(visitor, OnPacketComplete()).Times(1);
-
- EXPECT_TRUE(framer_.ProcessPacket(*packet));
- EXPECT_THAT(framer_.error(), IsQuicNoError());
-}
-
-// Verify that the packet returned by ConstructMisFramedEncryptedPacket()
-// does cause the framer to return an error.
-TEST_P(QuicFramerTest, ConstructMisFramedEncryptedPacket) {
- // Since we are using ConstructEncryptedPacket, we have to set the framer's
- // crypto to be Null.
- if (framer_.version().KnowsWhichDecrypterToUse()) {
- framer_.InstallDecrypter(
- ENCRYPTION_FORWARD_SECURE,
- std::make_unique<NullDecrypter>(framer_.perspective()));
- } else {
- framer_.SetDecrypter(ENCRYPTION_INITIAL, std::make_unique<NullDecrypter>(
- framer_.perspective()));
- }
- framer_.SetEncrypter(ENCRYPTION_INITIAL,
- std::make_unique<NullEncrypter>(framer_.perspective()));
- std::unique_ptr<QuicEncryptedPacket> packet(ConstructMisFramedEncryptedPacket(
- TestConnectionId(), EmptyQuicConnectionId(), false, false,
- kTestQuicStreamId, kTestString, CONNECTION_ID_PRESENT,
- CONNECTION_ID_ABSENT, PACKET_4BYTE_PACKET_NUMBER, framer_.version(),
- Perspective::IS_CLIENT));
-
- MockFramerVisitor visitor;
- framer_.set_visitor(&visitor);
- EXPECT_CALL(visitor, OnPacket()).Times(1);
- EXPECT_CALL(visitor, OnUnauthenticatedPublicHeader(_))
- .Times(1)
- .WillOnce(Return(true));
- EXPECT_CALL(visitor, OnUnauthenticatedHeader(_))
- .Times(1)
- .WillOnce(Return(true));
- EXPECT_CALL(visitor, OnPacketHeader(_)).Times(1);
- EXPECT_CALL(visitor, OnDecryptedPacket(_, _)).Times(1);
- EXPECT_CALL(visitor, OnError(_)).Times(1);
- EXPECT_CALL(visitor, OnStreamFrame(_)).Times(0);
- EXPECT_CALL(visitor, OnPacketComplete()).Times(0);
-
- EXPECT_FALSE(framer_.ProcessPacket(*packet));
- EXPECT_THAT(framer_.error(), IsError(QUIC_INVALID_FRAME_DATA));
-}
-
-TEST_P(QuicFramerTest, IetfBlockedFrame) {
- // This frame is only for IETF QUIC.
- if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
- return;
- }
- SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-
- // clang-format off
- PacketFragments packet_ietf = {
- // type (short header, 4 byte packet number)
- {"",
- {0x43}},
- // connection_id
- {"",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // packet number
- {"",
- {0x12, 0x34, 0x9A, 0xBC}},
- // frame type (IETF_DATA_BLOCKED)
- {"",
- {0x14}},
- // blocked offset
- {"Can not read blocked offset.",
- {kVarInt62EightBytes + 0x3a, 0x98, 0xFE, 0xDC, 0x32, 0x10, 0x76, 0x54}},
- };
- // clang-format on
-
- std::unique_ptr<QuicEncryptedPacket> encrypted(
- AssemblePacketFromFragments(packet_ietf));
- EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
-
- EXPECT_THAT(framer_.error(), IsQuicNoError());
- ASSERT_TRUE(visitor_.header_.get());
- EXPECT_TRUE(CheckDecryption(
- *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
- PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
-
- EXPECT_EQ(kStreamOffset, visitor_.blocked_frame_.offset);
-
- CheckFramingBoundaries(packet_ietf, QUIC_INVALID_BLOCKED_DATA);
-}
-
-TEST_P(QuicFramerTest, BuildIetfBlockedPacket) {
- // This frame is only for IETF QUIC.
- if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
- return;
- }
-
- QuicPacketHeader header;
- header.destination_connection_id = FramerTestConnectionId();
- header.reset_flag = false;
- header.version_flag = false;
- header.packet_number = kPacketNumber;
-
- QuicBlockedFrame frame;
- frame.stream_id = QuicUtils::GetInvalidStreamId(framer_.transport_version());
- frame.offset = kStreamOffset;
- QuicFrames frames = {QuicFrame(&frame)};
-
- // clang-format off
- unsigned char packet_ietf[] = {
- // type (short header, 4 byte packet number)
- 0x43,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
-
- // frame type (IETF_DATA_BLOCKED)
- 0x14,
- // Offset
- kVarInt62EightBytes + 0x3a, 0x98, 0xFE, 0xDC, 0x32, 0x10, 0x76, 0x54
- };
- // clang-format on
-
- std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
- ASSERT_TRUE(data != nullptr);
-
- quiche::test::CompareCharArraysWithHexError(
- "constructed packet", data->data(), data->length(), AsChars(packet_ietf),
- ABSL_ARRAYSIZE(packet_ietf));
-}
-
-TEST_P(QuicFramerTest, IetfStreamBlockedFrame) {
- // This frame is only for IETF QUIC.
- if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
- return;
- }
- SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-
- // clang-format off
- PacketFragments packet_ietf = {
- // type (short header, 4 byte packet number)
- {"",
- {0x43}},
- // connection_id
- {"",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // packet number
- {"",
- {0x12, 0x34, 0x9A, 0xBC}},
- // frame type (IETF_STREAM_DATA_BLOCKED)
- {"",
- {0x15}},
- // blocked offset
- {"Unable to read IETF_STREAM_DATA_BLOCKED frame stream id/count.",
- {kVarInt62FourBytes + 0x01, 0x02, 0x03, 0x04}},
- {"Can not read stream blocked offset.",
- {kVarInt62EightBytes + 0x3a, 0x98, 0xFE, 0xDC, 0x32, 0x10, 0x76, 0x54}},
- };
- // clang-format on
-
- std::unique_ptr<QuicEncryptedPacket> encrypted(
- AssemblePacketFromFragments(packet_ietf));
- EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
-
- EXPECT_THAT(framer_.error(), IsQuicNoError());
- ASSERT_TRUE(visitor_.header_.get());
- EXPECT_TRUE(CheckDecryption(
- *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
- PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
-
- EXPECT_EQ(kStreamId, visitor_.blocked_frame_.stream_id);
- EXPECT_EQ(kStreamOffset, visitor_.blocked_frame_.offset);
-
- CheckFramingBoundaries(packet_ietf, QUIC_INVALID_STREAM_BLOCKED_DATA);
-}
-
-TEST_P(QuicFramerTest, BuildIetfStreamBlockedPacket) {
- // This frame is only for IETF QUIC.
- if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
- return;
- }
-
- QuicPacketHeader header;
- header.destination_connection_id = FramerTestConnectionId();
- header.reset_flag = false;
- header.version_flag = false;
- header.packet_number = kPacketNumber;
-
- QuicBlockedFrame frame;
- frame.stream_id = kStreamId;
- frame.offset = kStreamOffset;
- QuicFrames frames = {QuicFrame(&frame)};
-
- // clang-format off
- unsigned char packet_ietf[] = {
- // type (short header, 4 byte packet number)
- 0x43,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
-
- // frame type (IETF_STREAM_DATA_BLOCKED)
- 0x15,
- // Stream ID
- kVarInt62FourBytes + 0x01, 0x02, 0x03, 0x04,
- // Offset
- kVarInt62EightBytes + 0x3a, 0x98, 0xFE, 0xDC, 0x32, 0x10, 0x76, 0x54
- };
- // clang-format on
-
- std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
- ASSERT_TRUE(data != nullptr);
-
- quiche::test::CompareCharArraysWithHexError(
- "constructed packet", data->data(), data->length(), AsChars(packet_ietf),
- ABSL_ARRAYSIZE(packet_ietf));
-}
-
-TEST_P(QuicFramerTest, BiDiMaxStreamsFrame) {
- // This frame is only for IETF QUIC.
- if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
- return;
- }
- SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-
- // clang-format off
- PacketFragments packet_ietf = {
- // type (short header, 4 byte packet number)
- {"",
- {0x43}},
- // connection_id
- {"",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // packet number
- {"",
- {0x12, 0x34, 0x9A, 0xBC}},
- // frame type (IETF_MAX_STREAMS_BIDIRECTIONAL)
- {"",
- {0x12}},
- // max. streams
- {"Unable to read IETF_MAX_STREAMS_BIDIRECTIONAL frame stream id/count.",
- {kVarInt62OneByte + 0x03}},
- };
- // clang-format on
-
- std::unique_ptr<QuicEncryptedPacket> encrypted(
- AssemblePacketFromFragments(packet_ietf));
- EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
-
- EXPECT_THAT(framer_.error(), IsQuicNoError());
- ASSERT_TRUE(visitor_.header_.get());
- EXPECT_TRUE(CheckDecryption(
- *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
- PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
-
- EXPECT_EQ(3u, visitor_.max_streams_frame_.stream_count);
- EXPECT_FALSE(visitor_.max_streams_frame_.unidirectional);
- CheckFramingBoundaries(packet_ietf, QUIC_MAX_STREAMS_DATA);
-}
-
-TEST_P(QuicFramerTest, UniDiMaxStreamsFrame) {
- // This frame is only for IETF QUIC.
- if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
- return;
- }
- SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-
- // clang-format off
- PacketFragments packet_ietf = {
- // type (short header, 4 byte packet number)
- {"",
- {0x43}},
- // Test runs in client mode, no connection id
- // packet number
- {"",
- {0x12, 0x34, 0x9A, 0xBC}},
- // frame type (IETF_MAX_STREAMS_UNIDIRECTIONAL)
- {"",
- {0x13}},
- // max. streams
- {"Unable to read IETF_MAX_STREAMS_UNIDIRECTIONAL frame stream id/count.",
- {kVarInt62OneByte + 0x03}},
- };
- // clang-format on
-
- std::unique_ptr<QuicEncryptedPacket> encrypted(
- AssemblePacketFromFragments(packet_ietf));
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
- EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
-
- EXPECT_THAT(framer_.error(), IsQuicNoError());
- ASSERT_TRUE(visitor_.header_.get());
- EXPECT_TRUE(CheckDecryption(
- *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
- PACKET_0BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
-
- EXPECT_EQ(3u, visitor_.max_streams_frame_.stream_count);
- EXPECT_TRUE(visitor_.max_streams_frame_.unidirectional);
- CheckFramingBoundaries(packet_ietf, QUIC_MAX_STREAMS_DATA);
-}
-
-TEST_P(QuicFramerTest, ServerUniDiMaxStreamsFrame) {
- // This frame is only for IETF QUIC.
- if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
- return;
- }
- SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-
- // clang-format off
- PacketFragments packet_ietf = {
- // type (short header, 4 byte packet number)
- {"",
- {0x43}},
- // connection_id
- {"",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // packet number
- {"",
- {0x12, 0x34, 0x9A, 0xBC}},
- // frame type (IETF_MAX_STREAMS_UNIDIRECTIONAL)
- {"",
- {0x13}},
- // max. streams
- {"Unable to read IETF_MAX_STREAMS_UNIDIRECTIONAL frame stream id/count.",
- {kVarInt62OneByte + 0x03}},
- };
- // clang-format on
-
- std::unique_ptr<QuicEncryptedPacket> encrypted(
- AssemblePacketFromFragments(packet_ietf));
- EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
-
- EXPECT_THAT(framer_.error(), IsQuicNoError());
- ASSERT_TRUE(visitor_.header_.get());
- EXPECT_TRUE(CheckDecryption(
- *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
- PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
-
- EXPECT_EQ(3u, visitor_.max_streams_frame_.stream_count);
- EXPECT_TRUE(visitor_.max_streams_frame_.unidirectional);
- CheckFramingBoundaries(packet_ietf, QUIC_MAX_STREAMS_DATA);
-}
-
-TEST_P(QuicFramerTest, ClientUniDiMaxStreamsFrame) {
- // This frame is only for IETF QUIC.
- if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
- return;
- }
- SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-
- // clang-format off
- PacketFragments packet_ietf = {
- // type (short header, 4 byte packet number)
- {"",
- {0x43}},
- // Test runs in client mode, no connection id
- // packet number
- {"",
- {0x12, 0x34, 0x9A, 0xBC}},
- // frame type (IETF_MAX_STREAMS_UNIDIRECTIONAL)
- {"",
- {0x13}},
- // max. streams
- {"Unable to read IETF_MAX_STREAMS_UNIDIRECTIONAL frame stream id/count.",
- {kVarInt62OneByte + 0x03}},
- };
- // clang-format on
-
- std::unique_ptr<QuicEncryptedPacket> encrypted(
- AssemblePacketFromFragments(packet_ietf));
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
- EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
-
- EXPECT_THAT(framer_.error(), IsQuicNoError());
- ASSERT_TRUE(visitor_.header_.get());
- EXPECT_TRUE(CheckDecryption(
- *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
- PACKET_0BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
-
- EXPECT_EQ(3u, visitor_.max_streams_frame_.stream_count);
- EXPECT_TRUE(visitor_.max_streams_frame_.unidirectional);
- CheckFramingBoundaries(packet_ietf, QUIC_MAX_STREAMS_DATA);
-}
-
-// The following four tests ensure that the framer can deserialize a stream
-// count that is large enough to cause the resulting stream ID to exceed the
-// current implementation limit(32 bits). The intent is that when this happens,
-// the stream limit is pegged to the maximum supported value. There are four
-// tests, for the four combinations of uni- and bi-directional, server- and
-// client- initiated.
-TEST_P(QuicFramerTest, BiDiMaxStreamsFrameTooBig) {
- // This frame is only for IETF QUIC.
- if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
- return;
- }
- SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-
- // clang-format off
- unsigned char packet_ietf[] = {
- // type (short header, 4 byte packet number)
- 0x43,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x12, 0x34, 0x9A, 0xBC,
- // frame type (IETF_MAX_STREAMS_BIDIRECTIONAL)
- 0x12,
-
- // max. streams. Max stream ID allowed is 0xffffffff
- // This encodes a count of 0x40000000, leading to stream
- // IDs in the range 0x1 00000000 to 0x1 00000003.
- kVarInt62EightBytes + 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00
- };
- // clang-format on
-
- QuicEncryptedPacket encrypted(AsChars(packet_ietf),
- ABSL_ARRAYSIZE(packet_ietf), false);
- EXPECT_TRUE(framer_.ProcessPacket(encrypted));
- EXPECT_THAT(framer_.error(), IsQuicNoError());
- ASSERT_TRUE(visitor_.header_.get());
- EXPECT_TRUE(CheckDecryption(
- encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
- PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
-
- EXPECT_EQ(0x40000000u, visitor_.max_streams_frame_.stream_count);
- EXPECT_FALSE(visitor_.max_streams_frame_.unidirectional);
-}
-
-TEST_P(QuicFramerTest, ClientBiDiMaxStreamsFrameTooBig) {
- // This frame is only for IETF QUIC.
- if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
- return;
- }
- SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-
- // clang-format off
- unsigned char packet_ietf[] = {
- // type (short header, 4 byte packet number)
- 0x43,
- // Test runs in client mode, no connection id
- // packet number
- 0x12, 0x34, 0x9A, 0xBC,
- // frame type (IETF_MAX_STREAMS_BIDIRECTIONAL)
- 0x12,
-
- // max. streams. Max stream ID allowed is 0xffffffff
- // This encodes a count of 0x40000000, leading to stream
- // IDs in the range 0x1 00000000 to 0x1 00000003.
- kVarInt62EightBytes + 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00
- };
- // clang-format on
-
- QuicEncryptedPacket encrypted(AsChars(packet_ietf),
- ABSL_ARRAYSIZE(packet_ietf), false);
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
- EXPECT_TRUE(framer_.ProcessPacket(encrypted));
-
- EXPECT_THAT(framer_.error(), IsQuicNoError());
- ASSERT_TRUE(visitor_.header_.get());
- EXPECT_TRUE(CheckDecryption(
- encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
- PACKET_0BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
-
- EXPECT_EQ(0x40000000u, visitor_.max_streams_frame_.stream_count);
- EXPECT_FALSE(visitor_.max_streams_frame_.unidirectional);
-}
-
-TEST_P(QuicFramerTest, ServerUniDiMaxStreamsFrameTooBig) {
- // This frame is only for IETF QUIC.
- if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
- return;
- }
- SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-
- // clang-format off
- unsigned char packet_ietf[] = {
- // type (short header, 4 byte packet number)
- 0x43,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x12, 0x34, 0x9A, 0xBC,
- // frame type (IETF_MAX_STREAMS_UNIDIRECTIONAL)
- 0x13,
-
- // max. streams. Max stream ID allowed is 0xffffffff
- // This encodes a count of 0x40000000, leading to stream
- // IDs in the range 0x1 00000000 to 0x1 00000003.
- kVarInt62EightBytes + 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00
- };
- // clang-format on
-
- QuicEncryptedPacket encrypted(AsChars(packet_ietf),
- ABSL_ARRAYSIZE(packet_ietf), false);
- EXPECT_TRUE(framer_.ProcessPacket(encrypted));
-
- EXPECT_THAT(framer_.error(), IsQuicNoError());
- ASSERT_TRUE(visitor_.header_.get());
- EXPECT_TRUE(CheckDecryption(
- encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
- PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
-
- EXPECT_EQ(0x40000000u, visitor_.max_streams_frame_.stream_count);
- EXPECT_TRUE(visitor_.max_streams_frame_.unidirectional);
-}
-
-TEST_P(QuicFramerTest, ClientUniDiMaxStreamsFrameTooBig) {
- // This frame is only for IETF QUIC.
- if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
- return;
- }
- SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-
- // clang-format off
- unsigned char packet_ietf[] = {
- // type (short header, 4 byte packet number)
- 0x43,
- // Test runs in client mode, no connection id
- // packet number
- 0x12, 0x34, 0x9A, 0xBC,
- // frame type (IETF_MAX_STREAMS_UNDIRECTIONAL)
- 0x13,
-
- // max. streams. Max stream ID allowed is 0xffffffff
- // This encodes a count of 0x40000000, leading to stream
- // IDs in the range 0x1 00000000 to 0x1 00000003.
- kVarInt62EightBytes + 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00
- };
- // clang-format on
-
- QuicEncryptedPacket encrypted(AsChars(packet_ietf),
- ABSL_ARRAYSIZE(packet_ietf), false);
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
- EXPECT_TRUE(framer_.ProcessPacket(encrypted));
-
- EXPECT_THAT(framer_.error(), IsQuicNoError());
- ASSERT_TRUE(visitor_.header_.get());
- EXPECT_TRUE(CheckDecryption(
- encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
- PACKET_0BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
-
- EXPECT_EQ(0x40000000u, visitor_.max_streams_frame_.stream_count);
- EXPECT_TRUE(visitor_.max_streams_frame_.unidirectional);
-}
-
-// Specifically test that count==0 is accepted.
-TEST_P(QuicFramerTest, MaxStreamsFrameZeroCount) {
- // This frame is only for IETF QUIC.
- if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
- return;
- }
- SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-
- // clang-format off
- unsigned char packet_ietf[] = {
- // type (short header, 4 byte packet number)
- 0x43,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x12, 0x34, 0x9A, 0xBC,
- // frame type (IETF_MAX_STREAMS_BIDIRECTIONAL)
- 0x12,
- // max. streams == 0.
- kVarInt62OneByte + 0x00
- };
- // clang-format on
-
- QuicEncryptedPacket encrypted(AsChars(packet_ietf),
- ABSL_ARRAYSIZE(packet_ietf), false);
- EXPECT_TRUE(framer_.ProcessPacket(encrypted));
-}
-
-TEST_P(QuicFramerTest, ServerBiDiStreamsBlockedFrame) {
- // This frame is only for IETF QUIC.
- if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
- return;
- }
- SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-
- // clang-format off
- PacketFragments packet_ietf = {
- // type (short header, 4 byte packet number)
- {"",
- {0x43}},
- // connection_id
- {"",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // packet number
- {"",
- {0x12, 0x34, 0x9A, 0xBC}},
- // frame type (IETF_MAX_STREAMS_UNIDIRECTIONAL frame)
- {"",
- {0x13}},
- // stream count
- {"Unable to read IETF_MAX_STREAMS_UNIDIRECTIONAL frame stream id/count.",
- {kVarInt62OneByte + 0x00}},
- };
- // clang-format on
-
- std::unique_ptr<QuicEncryptedPacket> encrypted(
- AssemblePacketFromFragments(packet_ietf));
- EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
-
- EXPECT_THAT(framer_.error(), IsQuicNoError());
- ASSERT_TRUE(visitor_.header_.get());
- EXPECT_TRUE(CheckDecryption(
- *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
- PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
-
- EXPECT_EQ(0u, visitor_.max_streams_frame_.stream_count);
- EXPECT_TRUE(visitor_.max_streams_frame_.unidirectional);
-
- CheckFramingBoundaries(packet_ietf, QUIC_MAX_STREAMS_DATA);
-}
-
-TEST_P(QuicFramerTest, BiDiStreamsBlockedFrame) {
- // This frame is only for IETF QUIC.
- if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
- return;
- }
- SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-
- // clang-format off
- PacketFragments packet_ietf = {
- // type (short header, 4 byte packet number)
- {"",
- {0x43}},
- // connection_id
- {"",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // packet number
- {"",
- {0x12, 0x34, 0x9A, 0xBC}},
- // frame type (IETF_STREAMS_BLOCKED_BIDIRECTIONAL frame)
- {"",
- {0x16}},
- // stream id
- {"Unable to read IETF_STREAMS_BLOCKED_BIDIRECTIONAL "
- "frame stream id/count.",
- {kVarInt62OneByte + 0x03}},
- };
- // clang-format on
-
- std::unique_ptr<QuicEncryptedPacket> encrypted(
- AssemblePacketFromFragments(packet_ietf));
- EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
-
- EXPECT_THAT(framer_.error(), IsQuicNoError());
- ASSERT_TRUE(visitor_.header_.get());
- EXPECT_TRUE(CheckDecryption(
- *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
- PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
-
- EXPECT_EQ(3u, visitor_.streams_blocked_frame_.stream_count);
- EXPECT_FALSE(visitor_.streams_blocked_frame_.unidirectional);
-
- CheckFramingBoundaries(packet_ietf, QUIC_STREAMS_BLOCKED_DATA);
-}
-
-TEST_P(QuicFramerTest, UniDiStreamsBlockedFrame) {
- // This frame is only for IETF QUIC.
- if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
- return;
- }
- SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-
- // clang-format off
- PacketFragments packet_ietf = {
- // type (short header, 4 byte packet number)
- {"",
- {0x43}},
- // connection_id
- {"",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // packet number
- {"",
- {0x12, 0x34, 0x9A, 0xBC}},
- // frame type (IETF_STREAMS_BLOCKED_UNIDIRECTIONAL frame)
- {"",
- {0x17}},
- // stream id
- {"Unable to read IETF_STREAMS_BLOCKED_UNIDIRECTIONAL "
- "frame stream id/count.",
- {kVarInt62OneByte + 0x03}},
- };
- // clang-format on
-
- std::unique_ptr<QuicEncryptedPacket> encrypted(
- AssemblePacketFromFragments(packet_ietf));
- EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
-
- EXPECT_THAT(framer_.error(), IsQuicNoError());
- ASSERT_TRUE(visitor_.header_.get());
- EXPECT_TRUE(CheckDecryption(
- *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
- PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
-
- EXPECT_EQ(3u, visitor_.streams_blocked_frame_.stream_count);
- EXPECT_TRUE(visitor_.streams_blocked_frame_.unidirectional);
- CheckFramingBoundaries(packet_ietf, QUIC_STREAMS_BLOCKED_DATA);
-}
-
-TEST_P(QuicFramerTest, ClientUniDiStreamsBlockedFrame) {
- // This frame is only for IETF QUIC.
- if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
- return;
- }
- SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-
- // clang-format off
- PacketFragments packet_ietf = {
- // type (short header, 4 byte packet number)
- {"",
- {0x43}},
- // Test runs in client mode, no connection id
- // packet number
- {"",
- {0x12, 0x34, 0x9A, 0xBC}},
- // frame type (IETF_STREAMS_BLOCKED_UNIDIRECTIONAL frame)
- {"",
- {0x17}},
- // stream id
- {"Unable to read IETF_STREAMS_BLOCKED_UNIDIRECTIONAL "
- "frame stream id/count.",
- {kVarInt62OneByte + 0x03}},
- };
- // clang-format on
-
- std::unique_ptr<QuicEncryptedPacket> encrypted(
- AssemblePacketFromFragments(packet_ietf));
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
- EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
-
- EXPECT_THAT(framer_.error(), IsQuicNoError());
- ASSERT_TRUE(visitor_.header_.get());
- EXPECT_TRUE(CheckDecryption(
- *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
- PACKET_0BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
-
- EXPECT_EQ(3u, visitor_.streams_blocked_frame_.stream_count);
- EXPECT_TRUE(visitor_.streams_blocked_frame_.unidirectional);
- CheckFramingBoundaries(packet_ietf, QUIC_STREAMS_BLOCKED_DATA);
-}
-
-// Check that when we get a STREAMS_BLOCKED frame that specifies too large
-// a stream count, we reject with an appropriate error. There is no need to
-// check for different combinations of Uni/Bi directional and client/server
-// initiated; the logic does not take these into account.
-TEST_P(QuicFramerTest, StreamsBlockedFrameTooBig) {
- // This frame is only for IETF QUIC.
- if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
- return;
- }
- SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-
- // clang-format off
- unsigned char packet_ietf[] = {
- // type (short header, 4 byte packet number)
- 0x43,
- // Test runs in client mode, no connection id
- // packet number
- 0x12, 0x34, 0x9A, 0xBC,
- // frame type (IETF_STREAMS_BLOCKED_BIDIRECTIONAL)
- 0x16,
-
- // max. streams. Max stream ID allowed is 0xffffffff
- // This encodes a count of 0x40000000, leading to stream
- // IDs in the range 0x1 00000000 to 0x1 00000003.
- kVarInt62EightBytes + 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x01
- };
- // clang-format on
-
- QuicEncryptedPacket encrypted(AsChars(packet_ietf),
- ABSL_ARRAYSIZE(packet_ietf), false);
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
- EXPECT_FALSE(framer_.ProcessPacket(encrypted));
-
- EXPECT_THAT(framer_.error(), IsError(QUIC_STREAMS_BLOCKED_DATA));
- EXPECT_EQ(framer_.detailed_error(),
- "STREAMS_BLOCKED stream count exceeds implementation limit.");
-}
-
-// Specifically test that count==0 is accepted.
-TEST_P(QuicFramerTest, StreamsBlockedFrameZeroCount) {
- // This frame is only for IETF QUIC.
- if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
- return;
- }
-
- SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-
- // clang-format off
- PacketFragments packet_ietf = {
- // type (short header, 4 byte packet number)
- {"",
- {0x43}},
- // connection_id
- {"",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // packet number
- {"",
- {0x12, 0x34, 0x9A, 0xBC}},
- // frame type (IETF_STREAMS_BLOCKED_UNIDIRECTIONAL frame)
- {"",
- {0x17}},
- // stream id
- {"Unable to read IETF_STREAMS_BLOCKED_UNIDIRECTIONAL "
- "frame stream id/count.",
- {kVarInt62OneByte + 0x00}},
- };
- // clang-format on
-
- std::unique_ptr<QuicEncryptedPacket> encrypted(
- AssemblePacketFromFragments(packet_ietf));
- EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
-
- EXPECT_THAT(framer_.error(), IsQuicNoError());
- ASSERT_TRUE(visitor_.header_.get());
- EXPECT_TRUE(CheckDecryption(
- *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
- PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
-
- EXPECT_EQ(0u, visitor_.streams_blocked_frame_.stream_count);
- EXPECT_TRUE(visitor_.streams_blocked_frame_.unidirectional);
-
- CheckFramingBoundaries(packet_ietf, QUIC_STREAMS_BLOCKED_DATA);
-}
-
-TEST_P(QuicFramerTest, BuildBiDiStreamsBlockedPacket) {
- // This frame is only for IETF QUIC.
- if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
- return;
- }
-
- QuicPacketHeader header;
- header.destination_connection_id = FramerTestConnectionId();
- header.reset_flag = false;
- header.version_flag = false;
- header.packet_number = kPacketNumber;
-
- QuicStreamsBlockedFrame frame;
- frame.stream_count = 3;
- frame.unidirectional = false;
-
- QuicFrames frames = {QuicFrame(frame)};
-
- // clang-format off
- unsigned char packet_ietf[] = {
- // type (short header, 4 byte packet number)
- 0x43,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
-
- // frame type (IETF_STREAMS_BLOCKED_BIDIRECTIONAL frame)
- 0x16,
- // Stream count
- kVarInt62OneByte + 0x03
- };
- // clang-format on
-
- std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
- ASSERT_TRUE(data != nullptr);
-
- quiche::test::CompareCharArraysWithHexError(
- "constructed packet", data->data(), data->length(), AsChars(packet_ietf),
- ABSL_ARRAYSIZE(packet_ietf));
-}
-
-TEST_P(QuicFramerTest, BuildUniStreamsBlockedPacket) {
- // This frame is only for IETF QUIC.
- if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
- return;
- }
-
- QuicPacketHeader header;
- header.destination_connection_id = FramerTestConnectionId();
- header.reset_flag = false;
- header.version_flag = false;
- header.packet_number = kPacketNumber;
-
- QuicStreamsBlockedFrame frame;
- frame.stream_count = 3;
- frame.unidirectional = true;
-
- QuicFrames frames = {QuicFrame(frame)};
-
- // clang-format off
- unsigned char packet_ietf[] = {
- // type (short header, 4 byte packet number)
- 0x43,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
-
- // frame type (IETF_STREAMS_BLOCKED_UNIDIRECTIONAL frame)
- 0x17,
- // Stream count
- kVarInt62OneByte + 0x03
- };
- // clang-format on
-
- std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
- ASSERT_TRUE(data != nullptr);
-
- quiche::test::CompareCharArraysWithHexError(
- "constructed packet", data->data(), data->length(), AsChars(packet_ietf),
- ABSL_ARRAYSIZE(packet_ietf));
-}
-
-TEST_P(QuicFramerTest, BuildBiDiMaxStreamsPacket) {
- // This frame is only for IETF QUIC.
- if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
- return;
- }
-
- QuicPacketHeader header;
- header.destination_connection_id = FramerTestConnectionId();
- header.reset_flag = false;
- header.version_flag = false;
- header.packet_number = kPacketNumber;
-
- QuicMaxStreamsFrame frame;
- frame.stream_count = 3;
- frame.unidirectional = false;
-
- QuicFrames frames = {QuicFrame(frame)};
-
- // clang-format off
- unsigned char packet_ietf[] = {
- // type (short header, 4 byte packet number)
- 0x43,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
-
- // frame type (IETF_MAX_STREAMS_BIDIRECTIONAL frame)
- 0x12,
- // Stream count
- kVarInt62OneByte + 0x03
- };
- // clang-format on
-
- std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
- ASSERT_TRUE(data != nullptr);
-
- quiche::test::CompareCharArraysWithHexError(
- "constructed packet", data->data(), data->length(), AsChars(packet_ietf),
- ABSL_ARRAYSIZE(packet_ietf));
-}
-
-TEST_P(QuicFramerTest, BuildUniDiMaxStreamsPacket) {
- // This frame is only for IETF QUIC.
- if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
- return;
- }
-
- // This test runs in client mode.
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
-
- QuicPacketHeader header;
- header.destination_connection_id = FramerTestConnectionId();
- header.reset_flag = false;
- header.version_flag = false;
- header.packet_number = kPacketNumber;
-
- QuicMaxStreamsFrame frame;
- frame.stream_count = 3;
- frame.unidirectional = true;
-
- QuicFrames frames = {QuicFrame(frame)};
-
- // clang-format off
- unsigned char packet_ietf[] = {
- // type (short header, 4 byte packet number)
- 0x43,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
-
- // frame type (IETF_MAX_STREAMS_UNIDIRECTIONAL frame)
- 0x13,
- // Stream count
- kVarInt62OneByte + 0x03
- };
- // clang-format on
-
- std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
- ASSERT_TRUE(data != nullptr);
-
- quiche::test::CompareCharArraysWithHexError(
- "constructed packet", data->data(), data->length(), AsChars(packet_ietf),
- ABSL_ARRAYSIZE(packet_ietf));
-}
-
-TEST_P(QuicFramerTest, NewConnectionIdFrame) {
- if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
- // This frame is only for IETF QUIC.
- return;
- }
- SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
- // clang-format off
- PacketFragments packet_ietf = {
- // type (short header, 4 byte packet number)
- {"",
- {0x43}},
- // connection_id
- {"",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // packet number
- {"",
- {0x12, 0x34, 0x56, 0x78}},
- // frame type (IETF_NEW_CONNECTION_ID frame)
- {"",
- {0x18}},
- // error code
- {"Unable to read new connection ID frame sequence number.",
- {kVarInt62OneByte + 0x11}},
- {"Unable to read new connection ID frame retire_prior_to.",
- {kVarInt62OneByte + 0x09}},
- {"Unable to read new connection ID frame connection id.",
- {0x08}}, // connection ID length
- {"Unable to read new connection ID frame connection id.",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x11}},
- {"Can not read new connection ID frame reset token.",
- {0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
- 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f}}
- };
- // clang-format on
-
- std::unique_ptr<QuicEncryptedPacket> encrypted(
- AssemblePacketFromFragments(packet_ietf));
- EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
-
- EXPECT_THAT(framer_.error(), IsQuicNoError());
- ASSERT_TRUE(visitor_.header_.get());
- EXPECT_TRUE(CheckDecryption(
- *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
- PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
-
- EXPECT_EQ(0u, visitor_.stream_frames_.size());
-
- EXPECT_EQ(FramerTestConnectionIdPlusOne(),
- visitor_.new_connection_id_.connection_id);
- EXPECT_EQ(0x11u, visitor_.new_connection_id_.sequence_number);
- EXPECT_EQ(0x09u, visitor_.new_connection_id_.retire_prior_to);
- EXPECT_EQ(kTestStatelessResetToken,
- visitor_.new_connection_id_.stateless_reset_token);
-
- ASSERT_EQ(0u, visitor_.ack_frames_.size());
-
- CheckFramingBoundaries(packet_ietf, QUIC_INVALID_NEW_CONNECTION_ID_DATA);
-}
-
-TEST_P(QuicFramerTest, NewConnectionIdFrameVariableLength) {
- if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
- // This frame is only for IETF QUIC.
- return;
- }
- SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
- // clang-format off
- PacketFragments packet_ietf = {
- // type (short header, 4 byte packet number)
- {"",
- {0x43}},
- // connection_id
- {"",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // packet number
- {"",
- {0x12, 0x34, 0x56, 0x78}},
- // frame type (IETF_NEW_CONNECTION_ID frame)
- {"",
- {0x18}},
- // error code
- {"Unable to read new connection ID frame sequence number.",
- {kVarInt62OneByte + 0x11}},
- {"Unable to read new connection ID frame retire_prior_to.",
- {kVarInt62OneByte + 0x0a}},
- {"Unable to read new connection ID frame connection id.",
- {0x09}}, // connection ID length
- {"Unable to read new connection ID frame connection id.",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10, 0x42}},
- {"Can not read new connection ID frame reset token.",
- {0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
- 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f}}
- };
- // clang-format on
-
- std::unique_ptr<QuicEncryptedPacket> encrypted(
- AssemblePacketFromFragments(packet_ietf));
- EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
-
- EXPECT_THAT(framer_.error(), IsQuicNoError());
- ASSERT_TRUE(visitor_.header_.get());
- EXPECT_TRUE(CheckDecryption(
- *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
- PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
-
- EXPECT_EQ(0u, visitor_.stream_frames_.size());
-
- EXPECT_EQ(FramerTestConnectionIdNineBytes(),
- visitor_.new_connection_id_.connection_id);
- EXPECT_EQ(0x11u, visitor_.new_connection_id_.sequence_number);
- EXPECT_EQ(0x0au, visitor_.new_connection_id_.retire_prior_to);
- EXPECT_EQ(kTestStatelessResetToken,
- visitor_.new_connection_id_.stateless_reset_token);
-
- ASSERT_EQ(0u, visitor_.ack_frames_.size());
-
- CheckFramingBoundaries(packet_ietf, QUIC_INVALID_NEW_CONNECTION_ID_DATA);
-}
-
-// Verifies that parsing a NEW_CONNECTION_ID frame with a length above the
-// specified maximum fails.
-TEST_P(QuicFramerTest, InvalidLongNewConnectionIdFrame) {
- if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
- // The NEW_CONNECTION_ID frame is only for IETF QUIC.
- return;
- }
- SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
- // clang-format off
- PacketFragments packet_ietf = {
- // type (short header, 4 byte packet number)
- {"",
- {0x43}},
- // connection_id
- {"",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // packet number
- {"",
- {0x12, 0x34, 0x56, 0x78}},
- // frame type (IETF_NEW_CONNECTION_ID frame)
- {"",
- {0x18}},
- // error code
- {"Unable to read new connection ID frame sequence number.",
- {kVarInt62OneByte + 0x11}},
- {"Unable to read new connection ID frame retire_prior_to.",
- {kVarInt62OneByte + 0x0b}},
- {"Unable to read new connection ID frame connection id.",
- {0x40}}, // connection ID length
- {"Unable to read new connection ID frame connection id.",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- 0xF0, 0xD2, 0xB4, 0x96, 0x78, 0x5A, 0x3C, 0x1E,
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- 0xF0, 0xD2, 0xB4, 0x96, 0x78, 0x5A, 0x3C, 0x1E,
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- 0xF0, 0xD2, 0xB4, 0x96, 0x78, 0x5A, 0x3C, 0x1E,
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- 0xF0, 0xD2, 0xB4, 0x96, 0x78, 0x5A, 0x3C, 0x1E}},
- {"Can not read new connection ID frame reset token.",
- {0xb5, 0x69, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}
- };
- // clang-format on
-
- std::unique_ptr<QuicEncryptedPacket> encrypted(
- AssemblePacketFromFragments(packet_ietf));
- EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
- EXPECT_THAT(framer_.error(), IsError(QUIC_INVALID_NEW_CONNECTION_ID_DATA));
- EXPECT_EQ("Invalid new connection ID length for version.",
- framer_.detailed_error());
-}
-
-// Verifies that parsing a NEW_CONNECTION_ID frame with an invalid
-// retire-prior-to fails.
-TEST_P(QuicFramerTest, InvalidRetirePriorToNewConnectionIdFrame) {
- if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
- // This frame is only for IETF QUIC only.
- return;
- }
- SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
- // clang-format off
- PacketFragments packet_ietf = {
- // type (short header, 4 byte packet number)
- {"",
- {0x43}},
- // connection_id
- {"",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // packet number
- {"",
- {0x12, 0x34, 0x56, 0x78}},
- // frame type (IETF_NEW_CONNECTION_ID frame)
- {"",
- {0x18}},
- // sequence number
- {"Unable to read new connection ID frame sequence number.",
- {kVarInt62OneByte + 0x11}},
- {"Unable to read new connection ID frame retire_prior_to.",
- {kVarInt62OneByte + 0x1b}},
- {"Unable to read new connection ID frame connection id length.",
- {0x08}}, // connection ID length
- {"Unable to read new connection ID frame connection id.",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x11}},
- {"Can not read new connection ID frame reset token.",
- {0xb5, 0x69, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}
- };
- // clang-format on
-
- std::unique_ptr<QuicEncryptedPacket> encrypted(
- AssemblePacketFromFragments(packet_ietf));
- EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
- EXPECT_THAT(framer_.error(), IsError(QUIC_INVALID_NEW_CONNECTION_ID_DATA));
- EXPECT_EQ("Retire_prior_to > sequence_number.", framer_.detailed_error());
-}
-
-TEST_P(QuicFramerTest, BuildNewConnectionIdFramePacket) {
- if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
- // This frame is only for IETF QUIC only.
- return;
- }
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
- QuicPacketHeader header;
- header.destination_connection_id = FramerTestConnectionId();
- header.reset_flag = false;
- header.version_flag = false;
- header.packet_number = kPacketNumber;
-
- QuicNewConnectionIdFrame frame;
- frame.sequence_number = 0x11;
- frame.retire_prior_to = 0x0c;
- // Use this value to force a 4-byte encoded variable length connection ID
- // in the frame.
- frame.connection_id = FramerTestConnectionIdPlusOne();
- frame.stateless_reset_token = kTestStatelessResetToken;
-
- QuicFrames frames = {QuicFrame(&frame)};
-
- // clang-format off
- unsigned char packet_ietf[] = {
- // type (short header, 4 byte packet number)
- 0x43,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
-
- // frame type (IETF_NEW_CONNECTION_ID frame)
- 0x18,
- // sequence number
- kVarInt62OneByte + 0x11,
- // retire_prior_to
- kVarInt62OneByte + 0x0c,
- // new connection id length
- 0x08,
- // new connection id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x11,
- // stateless reset token
- 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
- 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
- };
- // clang-format on
-
- std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
- ASSERT_TRUE(data != nullptr);
-
- quiche::test::CompareCharArraysWithHexError(
- "constructed packet", data->data(), data->length(), AsChars(packet_ietf),
- ABSL_ARRAYSIZE(packet_ietf));
-}
-
-TEST_P(QuicFramerTest, NewTokenFrame) {
- if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
- // This frame is only for IETF QUIC only.
- return;
- }
- SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
- // clang-format off
- PacketFragments packet = {
- // type (short header, 4 byte packet number)
- {"",
- {0x43}},
- // connection_id
- {"",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // packet number
- {"",
- {0x12, 0x34, 0x56, 0x78}},
- // frame type (IETF_NEW_TOKEN frame)
- {"",
- {0x07}},
- // Length
- {"Unable to read new token length.",
- {kVarInt62OneByte + 0x08}},
- {"Unable to read new token data.",
- {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}}
- };
- // clang-format on
- uint8_t expected_token_value[] = {0x00, 0x01, 0x02, 0x03,
- 0x04, 0x05, 0x06, 0x07};
-
- std::unique_ptr<QuicEncryptedPacket> encrypted(
- AssemblePacketFromFragments(packet));
- EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
-
- EXPECT_THAT(framer_.error(), IsQuicNoError());
- ASSERT_TRUE(visitor_.header_.get());
- EXPECT_TRUE(CheckDecryption(
- *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
- PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
-
- EXPECT_EQ(0u, visitor_.stream_frames_.size());
-
- EXPECT_EQ(sizeof(expected_token_value), visitor_.new_token_.token.length());
- EXPECT_EQ(0, memcmp(expected_token_value, visitor_.new_token_.token.data(),
- sizeof(expected_token_value)));
-
- CheckFramingBoundaries(packet, QUIC_INVALID_NEW_TOKEN);
-}
-
-TEST_P(QuicFramerTest, BuildNewTokenFramePacket) {
- if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
- // This frame is only for IETF QUIC only.
- return;
- }
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
- QuicPacketHeader header;
- header.destination_connection_id = FramerTestConnectionId();
- header.reset_flag = false;
- header.version_flag = false;
- header.packet_number = kPacketNumber;
-
- uint8_t expected_token_value[] = {0x00, 0x01, 0x02, 0x03,
- 0x04, 0x05, 0x06, 0x07};
-
- QuicNewTokenFrame frame(0,
- absl::string_view((const char*)(expected_token_value),
- sizeof(expected_token_value)));
-
- QuicFrames frames = {QuicFrame(&frame)};
-
- // clang-format off
- unsigned char packet[] = {
- // type (short header, 4 byte packet number)
- 0x43,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
-
- // frame type (IETF_NEW_TOKEN frame)
- 0x07,
- // Length and token
- kVarInt62OneByte + 0x08,
- 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07
- };
- // clang-format on
-
- std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
- ASSERT_TRUE(data != nullptr);
-
- quiche::test::CompareCharArraysWithHexError(
- "constructed packet", data->data(), data->length(), AsChars(packet),
- ABSL_ARRAYSIZE(packet));
-}
-
-TEST_P(QuicFramerTest, IetfStopSendingFrame) {
- if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
- // Stop sending frame is IETF QUIC only.
- return;
- }
- SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-
- // clang-format off
- PacketFragments packet_ietf = {
- // type (short header, 4 byte packet number)
- {"",
- {0x43}},
- // connection_id
- {"",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // packet number
- {"",
- {0x12, 0x34, 0x9A, 0xBC}},
- // frame type (IETF_STOP_SENDING frame)
- {"",
- {0x05}},
- // stream id
- {"Unable to read IETF_STOP_SENDING frame stream id/count.",
- {kVarInt62FourBytes + 0x01, 0x02, 0x03, 0x04}},
- {"Unable to read stop sending application error code.",
- {kVarInt62FourBytes + 0x00, 0x00, 0x76, 0x54}},
- };
- // clang-format on
-
- std::unique_ptr<QuicEncryptedPacket> encrypted(
- AssemblePacketFromFragments(packet_ietf));
- EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
-
- EXPECT_THAT(framer_.error(), IsQuicNoError());
- ASSERT_TRUE(visitor_.header_.get());
- EXPECT_TRUE(CheckDecryption(
- *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
- PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
-
- EXPECT_EQ(kStreamId, visitor_.stop_sending_frame_.stream_id);
- EXPECT_EQ(QUIC_STREAM_UNKNOWN_APPLICATION_ERROR_CODE,
- visitor_.stop_sending_frame_.error_code);
- EXPECT_EQ(static_cast<uint64_t>(0x7654),
- visitor_.stop_sending_frame_.ietf_error_code);
-
- CheckFramingBoundaries(packet_ietf, QUIC_INVALID_STOP_SENDING_FRAME_DATA);
-}
-
-TEST_P(QuicFramerTest, BuildIetfStopSendingPacket) {
- if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
- // Stop sending frame is IETF QUIC only.
- return;
- }
-
- QuicPacketHeader header;
- header.destination_connection_id = FramerTestConnectionId();
- header.reset_flag = false;
- header.version_flag = false;
- header.packet_number = kPacketNumber;
-
- QuicStopSendingFrame frame;
- frame.stream_id = kStreamId;
- frame.error_code = QUIC_STREAM_ENCODER_STREAM_ERROR;
- frame.ietf_error_code =
- static_cast<uint64_t>(QuicHttpQpackErrorCode::ENCODER_STREAM_ERROR);
- QuicFrames frames = {QuicFrame(&frame)};
-
- // clang-format off
- unsigned char packet_ietf[] = {
- // type (short header, 4 byte packet number)
- 0x43,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
-
- // frame type (IETF_STOP_SENDING frame)
- 0x05,
- // Stream ID
- kVarInt62FourBytes + 0x01, 0x02, 0x03, 0x04,
- // Application error code
- kVarInt62TwoBytes + 0x02, 0x01,
- };
- // clang-format on
-
- std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
- ASSERT_TRUE(data != nullptr);
-
- quiche::test::CompareCharArraysWithHexError(
- "constructed packet", data->data(), data->length(), AsChars(packet_ietf),
- ABSL_ARRAYSIZE(packet_ietf));
-}
-
-TEST_P(QuicFramerTest, IetfPathChallengeFrame) {
- if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
- // Path Challenge frame is IETF QUIC only.
- return;
- }
- SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-
- // clang-format off
- PacketFragments packet_ietf = {
- // type (short header, 4 byte packet number)
- {"",
- {0x43}},
- // connection_id
- {"",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // packet number
- {"",
- {0x12, 0x34, 0x9A, 0xBC}},
- // frame type (IETF_PATH_CHALLENGE)
- {"",
- {0x1a}},
- // data
- {"Can not read path challenge data.",
- {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}},
- };
- // clang-format on
-
- std::unique_ptr<QuicEncryptedPacket> encrypted(
- AssemblePacketFromFragments(packet_ietf));
- EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
-
- EXPECT_THAT(framer_.error(), IsQuicNoError());
- ASSERT_TRUE(visitor_.header_.get());
- EXPECT_TRUE(CheckDecryption(
- *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
- PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
-
- EXPECT_EQ(QuicPathFrameBuffer({{0, 1, 2, 3, 4, 5, 6, 7}}),
- visitor_.path_challenge_frame_.data_buffer);
-
- CheckFramingBoundaries(packet_ietf, QUIC_INVALID_PATH_CHALLENGE_DATA);
-}
-
-TEST_P(QuicFramerTest, BuildIetfPathChallengePacket) {
- if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
- // Path Challenge frame is IETF QUIC only.
- return;
- }
-
- QuicPacketHeader header;
- header.destination_connection_id = FramerTestConnectionId();
- header.reset_flag = false;
- header.version_flag = false;
- header.packet_number = kPacketNumber;
-
- QuicPathChallengeFrame frame;
- frame.data_buffer = QuicPathFrameBuffer({{0, 1, 2, 3, 4, 5, 6, 7}});
- QuicFrames frames = {QuicFrame(&frame)};
-
- // clang-format off
- unsigned char packet_ietf[] = {
- // type (short header, 4 byte packet number)
- 0x43,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
-
- // frame type (IETF_PATH_CHALLENGE)
- 0x1a,
- // Data
- 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07
- };
- // clang-format on
-
- std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
- ASSERT_TRUE(data != nullptr);
-
- quiche::test::CompareCharArraysWithHexError(
- "constructed packet", data->data(), data->length(), AsChars(packet_ietf),
- ABSL_ARRAYSIZE(packet_ietf));
-}
-
-TEST_P(QuicFramerTest, IetfPathResponseFrame) {
- if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
- // Path response frame is IETF QUIC only.
- return;
- }
- SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-
- // clang-format off
- PacketFragments packet_ietf = {
- // type (short header, 4 byte packet number)
- {"",
- {0x43}},
- // connection_id
- {"",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // packet number
- {"",
- {0x12, 0x34, 0x9A, 0xBC}},
- // frame type (IETF_PATH_RESPONSE)
- {"",
- {0x1b}},
- // data
- {"Can not read path response data.",
- {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}},
- };
- // clang-format on
-
- std::unique_ptr<QuicEncryptedPacket> encrypted(
- AssemblePacketFromFragments(packet_ietf));
- EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
-
- EXPECT_THAT(framer_.error(), IsQuicNoError());
- ASSERT_TRUE(visitor_.header_.get());
- EXPECT_TRUE(CheckDecryption(
- *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
- PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
-
- EXPECT_EQ(QuicPathFrameBuffer({{0, 1, 2, 3, 4, 5, 6, 7}}),
- visitor_.path_response_frame_.data_buffer);
-
- CheckFramingBoundaries(packet_ietf, QUIC_INVALID_PATH_RESPONSE_DATA);
-}
-
-TEST_P(QuicFramerTest, BuildIetfPathResponsePacket) {
- if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
- // Path response frame is IETF QUIC only
- return;
- }
-
- QuicPacketHeader header;
- header.destination_connection_id = FramerTestConnectionId();
- header.reset_flag = false;
- header.version_flag = false;
- header.packet_number = kPacketNumber;
-
- QuicPathResponseFrame frame;
- frame.data_buffer = QuicPathFrameBuffer({{0, 1, 2, 3, 4, 5, 6, 7}});
- QuicFrames frames = {QuicFrame(&frame)};
-
- // clang-format off
- unsigned char packet_ietf[] = {
- // type (short header, 4 byte packet number)
- 0x43,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
-
- // frame type (IETF_PATH_RESPONSE)
- 0x1b,
- // Data
- 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07
- };
- // clang-format on
-
- std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
- ASSERT_TRUE(data != nullptr);
-
- quiche::test::CompareCharArraysWithHexError(
- "constructed packet", data->data(), data->length(), AsChars(packet_ietf),
- ABSL_ARRAYSIZE(packet_ietf));
-}
-
-TEST_P(QuicFramerTest, GetRetransmittableControlFrameSize) {
- QuicRstStreamFrame rst_stream(1, 3, QUIC_STREAM_CANCELLED, 1024);
- EXPECT_EQ(QuicFramer::GetRstStreamFrameSize(framer_.transport_version(),
- rst_stream),
- QuicFramer::GetRetransmittableControlFrameSize(
- framer_.transport_version(), QuicFrame(&rst_stream)));
-
- std::string error_detail(2048, 'e');
- QuicConnectionCloseFrame connection_close(framer_.transport_version(),
- QUIC_NETWORK_IDLE_TIMEOUT,
- NO_IETF_QUIC_ERROR, error_detail,
- /*transport_close_frame_type=*/0);
-
- EXPECT_EQ(QuicFramer::GetConnectionCloseFrameSize(framer_.transport_version(),
- connection_close),
- QuicFramer::GetRetransmittableControlFrameSize(
- framer_.transport_version(), QuicFrame(&connection_close)));
-
- QuicGoAwayFrame goaway(2, QUIC_PEER_GOING_AWAY, 3, error_detail);
- EXPECT_EQ(QuicFramer::GetMinGoAwayFrameSize() + 256,
- QuicFramer::GetRetransmittableControlFrameSize(
- framer_.transport_version(), QuicFrame(&goaway)));
-
- QuicWindowUpdateFrame window_update(3, 3, 1024);
- EXPECT_EQ(QuicFramer::GetWindowUpdateFrameSize(framer_.transport_version(),
- window_update),
- QuicFramer::GetRetransmittableControlFrameSize(
- framer_.transport_version(), QuicFrame(&window_update)));
-
- QuicBlockedFrame blocked(4, 3, 1024);
- EXPECT_EQ(
- QuicFramer::GetBlockedFrameSize(framer_.transport_version(), blocked),
- QuicFramer::GetRetransmittableControlFrameSize(
- framer_.transport_version(), QuicFrame(&blocked)));
-
- // Following frames are IETF QUIC frames only.
- if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
- return;
- }
-
- QuicNewConnectionIdFrame new_connection_id(5, TestConnectionId(), 1,
- kTestStatelessResetToken, 1);
- EXPECT_EQ(QuicFramer::GetNewConnectionIdFrameSize(new_connection_id),
- QuicFramer::GetRetransmittableControlFrameSize(
- framer_.transport_version(), QuicFrame(&new_connection_id)));
-
- QuicMaxStreamsFrame max_streams(6, 3, /*unidirectional=*/false);
- EXPECT_EQ(QuicFramer::GetMaxStreamsFrameSize(framer_.transport_version(),
- max_streams),
- QuicFramer::GetRetransmittableControlFrameSize(
- framer_.transport_version(), QuicFrame(max_streams)));
-
- QuicStreamsBlockedFrame streams_blocked(7, 3, /*unidirectional=*/false);
- EXPECT_EQ(QuicFramer::GetStreamsBlockedFrameSize(framer_.transport_version(),
- streams_blocked),
- QuicFramer::GetRetransmittableControlFrameSize(
- framer_.transport_version(), QuicFrame(streams_blocked)));
-
- QuicPathFrameBuffer buffer = {
- {0x80, 0x91, 0xa2, 0xb3, 0xc4, 0xd5, 0xe5, 0xf7}};
- QuicPathResponseFrame path_response_frame(8, buffer);
- EXPECT_EQ(QuicFramer::GetPathResponseFrameSize(path_response_frame),
- QuicFramer::GetRetransmittableControlFrameSize(
- framer_.transport_version(), QuicFrame(&path_response_frame)));
-
- QuicPathChallengeFrame path_challenge_frame(9, buffer);
- EXPECT_EQ(QuicFramer::GetPathChallengeFrameSize(path_challenge_frame),
- QuicFramer::GetRetransmittableControlFrameSize(
- framer_.transport_version(), QuicFrame(&path_challenge_frame)));
-
- QuicStopSendingFrame stop_sending_frame(10, 3, QUIC_STREAM_CANCELLED);
- EXPECT_EQ(QuicFramer::GetStopSendingFrameSize(stop_sending_frame),
- QuicFramer::GetRetransmittableControlFrameSize(
- framer_.transport_version(), QuicFrame(&stop_sending_frame)));
-}
-
-// A set of tests to ensure that bad frame-type encodings
-// are properly detected and handled.
-// First, four tests to see that unknown frame types generate
-// a QUIC_INVALID_FRAME_DATA error with detailed information
-// "Illegal frame type." This regardless of the encoding of the type
-// (1/2/4/8 bytes).
-// This only for version 99.
-TEST_P(QuicFramerTest, IetfFrameTypeEncodingErrorUnknown1Byte) {
- if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
- // Only IETF QUIC encodes frame types such that this test is relevant.
- return;
- }
- SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
- // clang-format off
- PacketFragments packet = {
- // type (short header, 4 byte packet number)
- {"",
- {0x43}},
- // connection_id
- {"",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // packet number
- {"",
- {0x12, 0x34, 0x9A, 0xBC}},
- // frame type (unknown value, single-byte encoding)
- {"",
- {0x38}}
- };
- // clang-format on
-
- std::unique_ptr<QuicEncryptedPacket> encrypted(
- AssemblePacketFromFragments(packet));
-
- EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
-
- EXPECT_THAT(framer_.error(), IsError(QUIC_INVALID_FRAME_DATA));
- EXPECT_EQ("Illegal frame type.", framer_.detailed_error());
-}
-
-TEST_P(QuicFramerTest, IetfFrameTypeEncodingErrorUnknown2Bytes) {
- if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
- // Only IETF QUIC encodes frame types such that this test is relevant.
- return;
- }
- SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-
- // clang-format off
- PacketFragments packet = {
- // type (short header, 4 byte packet number)
- {"",
- {0x43}},
- // connection_id
- {"",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // packet number
- {"",
- {0x12, 0x34, 0x9A, 0xBC}},
- // frame type (unknown value, two-byte encoding)
- {"",
- {kVarInt62TwoBytes + 0x01, 0x38}}
- };
- // clang-format on
-
- std::unique_ptr<QuicEncryptedPacket> encrypted(
- AssemblePacketFromFragments(packet));
-
- EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
-
- EXPECT_THAT(framer_.error(), IsError(QUIC_INVALID_FRAME_DATA));
- EXPECT_EQ("Illegal frame type.", framer_.detailed_error());
-}
-
-TEST_P(QuicFramerTest, IetfFrameTypeEncodingErrorUnknown4Bytes) {
- if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
- // Only IETF QUIC encodes frame types such that this test is relevant.
- return;
- }
- SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-
- // clang-format off
- PacketFragments packet = {
- // type (short header, 4 byte packet number)
- {"",
- {0x43}},
- // connection_id
- {"",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // packet number
- {"",
- {0x12, 0x34, 0x9A, 0xBC}},
- // frame type (unknown value, four-byte encoding)
- {"",
- {kVarInt62FourBytes + 0x01, 0x00, 0x00, 0x38}}
- };
- // clang-format on
-
- std::unique_ptr<QuicEncryptedPacket> encrypted(
- AssemblePacketFromFragments(packet));
-
- EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
-
- EXPECT_THAT(framer_.error(), IsError(QUIC_INVALID_FRAME_DATA));
- EXPECT_EQ("Illegal frame type.", framer_.detailed_error());
-}
-
-TEST_P(QuicFramerTest, IetfFrameTypeEncodingErrorUnknown8Bytes) {
- if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
- // Only IETF QUIC encodes frame types such that this test is relevant.
- return;
- }
- SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
- // clang-format off
- PacketFragments packet = {
- // type (short header, 4 byte packet number)
- {"",
- {0x43}},
- // connection_id
- {"",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // packet number
- {"",
- {0x12, 0x34, 0x9A, 0xBC}},
- // frame type (unknown value, eight-byte encoding)
- {"",
- {kVarInt62EightBytes + 0x01, 0x00, 0x00, 0x01, 0x02, 0x34, 0x56, 0x38}}
- };
- // clang-format on
-
- std::unique_ptr<QuicEncryptedPacket> encrypted(
- AssemblePacketFromFragments(packet));
-
- EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
-
- EXPECT_THAT(framer_.error(), IsError(QUIC_INVALID_FRAME_DATA));
- EXPECT_EQ("Illegal frame type.", framer_.detailed_error());
-}
-
-// Three tests to check that known frame types that are not minimally
-// encoded generate IETF_QUIC_PROTOCOL_VIOLATION errors with detailed
-// information "Frame type not minimally encoded."
-// Look at the frame-type encoded in 2, 4, and 8 bytes.
-TEST_P(QuicFramerTest, IetfFrameTypeEncodingErrorKnown2Bytes) {
- if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
- // Only IETF QUIC encodes frame types such that this test is relevant.
- return;
- }
- SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-
- // clang-format off
- PacketFragments packet = {
- // type (short header, 4 byte packet number)
- {"",
- {0x43}},
- // connection_id
- {"",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // packet number
- {"",
- {0x12, 0x34, 0x9A, 0xBC}},
- // frame type (Blocked, two-byte encoding)
- {"",
- {kVarInt62TwoBytes + 0x00, 0x08}}
- };
- // clang-format on
-
- std::unique_ptr<QuicEncryptedPacket> encrypted(
- AssemblePacketFromFragments(packet));
-
- EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
-
- EXPECT_THAT(framer_.error(), IsError(IETF_QUIC_PROTOCOL_VIOLATION));
- EXPECT_EQ("Frame type not minimally encoded.", framer_.detailed_error());
-}
-
-TEST_P(QuicFramerTest, IetfFrameTypeEncodingErrorKnown4Bytes) {
- if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
- // Only IETF QUIC encodes frame types such that this test is relevant.
- return;
- }
- SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-
- // clang-format off
- PacketFragments packet = {
- // type (short header, 4 byte packet number)
- {"",
- {0x43}},
- // connection_id
- {"",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // packet number
- {"",
- {0x12, 0x34, 0x9A, 0xBC}},
- // frame type (Blocked, four-byte encoding)
- {"",
- {kVarInt62FourBytes + 0x00, 0x00, 0x00, 0x08}}
- };
- // clang-format on
-
- std::unique_ptr<QuicEncryptedPacket> encrypted(
- AssemblePacketFromFragments(packet));
-
- EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
-
- EXPECT_THAT(framer_.error(), IsError(IETF_QUIC_PROTOCOL_VIOLATION));
- EXPECT_EQ("Frame type not minimally encoded.", framer_.detailed_error());
-}
-
-TEST_P(QuicFramerTest, IetfFrameTypeEncodingErrorKnown8Bytes) {
- if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
- // Only IETF QUIC encodes frame types such that this test is relevant.
- return;
- }
- SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
- // clang-format off
- PacketFragments packet = {
- // type (short header, 4 byte packet number)
- {"",
- {0x43}},
- // connection_id
- {"",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // packet number
- {"",
- {0x12, 0x34, 0x9A, 0xBC}},
- // frame type (Blocked, eight-byte encoding)
- {"",
- {kVarInt62EightBytes + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08}}
- };
- // clang-format on
-
- std::unique_ptr<QuicEncryptedPacket> encrypted(
- AssemblePacketFromFragments(packet));
-
- EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
-
- EXPECT_THAT(framer_.error(), IsError(IETF_QUIC_PROTOCOL_VIOLATION));
- EXPECT_EQ("Frame type not minimally encoded.", framer_.detailed_error());
-}
-
-// Tests to check that all known IETF frame types that are not minimally
-// encoded generate IETF_QUIC_PROTOCOL_VIOLATION errors with detailed
-// information "Frame type not minimally encoded."
-// Just look at 2-byte encoding.
-TEST_P(QuicFramerTest, IetfFrameTypeEncodingErrorKnown2BytesAllTypes) {
- if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
- // Only IETF QUIC encodes frame types such that this test is relevant.
- return;
- }
- SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-
- // clang-format off
- PacketFragments packets[] = {
- {
- // type (short header, 4 byte packet number)
- {"",
- {0x43}},
- // connection_id
- {"",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // packet number
- {"",
- {0x12, 0x34, 0x9A, 0xBC}},
- // frame type (two-byte encoding)
- {"",
- {kVarInt62TwoBytes + 0x00, 0x00}}
- },
- {
- // type (short header, 4 byte packet number)
- {"",
- {0x43}},
- // connection_id
- {"",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // packet number
- {"",
- {0x12, 0x34, 0x9A, 0xBC}},
- // frame type (two-byte encoding)
- {"",
- {kVarInt62TwoBytes + 0x00, 0x01}}
- },
- {
- // type (short header, 4 byte packet number)
- {"",
- {0x43}},
- // connection_id
- {"",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // packet number
- {"",
- {0x12, 0x34, 0x9A, 0xBC}},
- // frame type (two-byte encoding)
- {"",
- {kVarInt62TwoBytes + 0x00, 0x02}}
- },
- {
- // type (short header, 4 byte packet number)
- {"",
- {0x43}},
- // connection_id
- {"",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // packet number
- {"",
- {0x12, 0x34, 0x9A, 0xBC}},
- // frame type (two-byte encoding)
- {"",
- {kVarInt62TwoBytes + 0x00, 0x03}}
- },
- {
- // type (short header, 4 byte packet number)
- {"",
- {0x43}},
- // connection_id
- {"",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // packet number
- {"",
- {0x12, 0x34, 0x9A, 0xBC}},
- // frame type (two-byte encoding)
- {"",
- {kVarInt62TwoBytes + 0x00, 0x04}}
- },
- {
- // type (short header, 4 byte packet number)
- {"",
- {0x43}},
- // connection_id
- {"",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // packet number
- {"",
- {0x12, 0x34, 0x9A, 0xBC}},
- // frame type (two-byte encoding)
- {"",
- {kVarInt62TwoBytes + 0x00, 0x05}}
- },
- {
- // type (short header, 4 byte packet number)
- {"",
- {0x43}},
- // connection_id
- {"",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // packet number
- {"",
- {0x12, 0x34, 0x9A, 0xBC}},
- // frame type (two-byte encoding)
- {"",
- {kVarInt62TwoBytes + 0x00, 0x06}}
- },
- {
- // type (short header, 4 byte packet number)
- {"",
- {0x43}},
- // connection_id
- {"",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // packet number
- {"",
- {0x12, 0x34, 0x9A, 0xBC}},
- // frame type (two-byte encoding)
- {"",
- {kVarInt62TwoBytes + 0x00, 0x07}}
- },
- {
- // type (short header, 4 byte packet number)
- {"",
- {0x43}},
- // connection_id
- {"",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // packet number
- {"",
- {0x12, 0x34, 0x9A, 0xBC}},
- // frame type (two-byte encoding)
- {"",
- {kVarInt62TwoBytes + 0x00, 0x08}}
- },
- {
- // type (short header, 4 byte packet number)
- {"",
- {0x43}},
- // connection_id
- {"",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // packet number
- {"",
- {0x12, 0x34, 0x9A, 0xBC}},
- // frame type (two-byte encoding)
- {"",
- {kVarInt62TwoBytes + 0x00, 0x09}}
- },
- {
- // type (short header, 4 byte packet number)
- {"",
- {0x43}},
- // connection_id
- {"",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // packet number
- {"",
- {0x12, 0x34, 0x9A, 0xBC}},
- // frame type (two-byte encoding)
- {"",
- {kVarInt62TwoBytes + 0x00, 0x0a}}
- },
- {
- // type (short header, 4 byte packet number)
- {"",
- {0x43}},
- // connection_id
- {"",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // packet number
- {"",
- {0x12, 0x34, 0x9A, 0xBC}},
- // frame type (two-byte encoding)
- {"",
- {kVarInt62TwoBytes + 0x00, 0x0b}}
- },
- {
- // type (short header, 4 byte packet number)
- {"",
- {0x43}},
- // connection_id
- {"",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // packet number
- {"",
- {0x12, 0x34, 0x9A, 0xBC}},
- // frame type (two-byte encoding)
- {"",
- {kVarInt62TwoBytes + 0x00, 0x0c}}
- },
- {
- // type (short header, 4 byte packet number)
- {"",
- {0x43}},
- // connection_id
- {"",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // packet number
- {"",
- {0x12, 0x34, 0x9A, 0xBC}},
- // frame type (two-byte encoding)
- {"",
- {kVarInt62TwoBytes + 0x00, 0x0d}}
- },
- {
- // type (short header, 4 byte packet number)
- {"",
- {0x43}},
- // connection_id
- {"",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // packet number
- {"",
- {0x12, 0x34, 0x9A, 0xBC}},
- // frame type (two-byte encoding)
- {"",
- {kVarInt62TwoBytes + 0x00, 0x0e}}
- },
- {
- // type (short header, 4 byte packet number)
- {"",
- {0x43}},
- // connection_id
- {"",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // packet number
- {"",
- {0x12, 0x34, 0x9A, 0xBC}},
- // frame type (two-byte encoding)
- {"",
- {kVarInt62TwoBytes + 0x00, 0x0f}}
- },
- {
- // type (short header, 4 byte packet number)
- {"",
- {0x43}},
- // connection_id
- {"",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // packet number
- {"",
- {0x12, 0x34, 0x9A, 0xBC}},
- // frame type (two-byte encoding)
- {"",
- {kVarInt62TwoBytes + 0x00, 0x10}}
- },
- {
- // type (short header, 4 byte packet number)
- {"",
- {0x43}},
- // connection_id
- {"",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // packet number
- {"",
- {0x12, 0x34, 0x9A, 0xBC}},
- // frame type (two-byte encoding)
- {"",
- {kVarInt62TwoBytes + 0x00, 0x11}}
- },
- {
- // type (short header, 4 byte packet number)
- {"",
- {0x43}},
- // connection_id
- {"",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // packet number
- {"",
- {0x12, 0x34, 0x9A, 0xBC}},
- // frame type (two-byte encoding)
- {"",
- {kVarInt62TwoBytes + 0x00, 0x12}}
- },
- {
- // type (short header, 4 byte packet number)
- {"",
- {0x43}},
- // connection_id
- {"",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // packet number
- {"",
- {0x12, 0x34, 0x9A, 0xBC}},
- // frame type (two-byte encoding)
- {"",
- {kVarInt62TwoBytes + 0x00, 0x13}}
- },
- {
- // type (short header, 4 byte packet number)
- {"",
- {0x43}},
- // connection_id
- {"",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // packet number
- {"",
- {0x12, 0x34, 0x9A, 0xBC}},
- // frame type (two-byte encoding)
- {"",
- {kVarInt62TwoBytes + 0x00, 0x14}}
- },
- {
- // type (short header, 4 byte packet number)
- {"",
- {0x43}},
- // connection_id
- {"",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // packet number
- {"",
- {0x12, 0x34, 0x9A, 0xBC}},
- // frame type (two-byte encoding)
- {"",
- {kVarInt62TwoBytes + 0x00, 0x15}}
- },
- {
- // type (short header, 4 byte packet number)
- {"",
- {0x43}},
- // connection_id
- {"",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // packet number
- {"",
- {0x12, 0x34, 0x9A, 0xBC}},
- // frame type (two-byte encoding)
- {"",
- {kVarInt62TwoBytes + 0x00, 0x16}}
- },
- {
- // type (short header, 4 byte packet number)
- {"",
- {0x43}},
- // connection_id
- {"",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // packet number
- {"",
- {0x12, 0x34, 0x9A, 0xBC}},
- // frame type (two-byte encoding)
- {"",
- {kVarInt62TwoBytes + 0x00, 0x17}}
- },
- {
- // type (short header, 4 byte packet number)
- {"",
- {0x43}},
- // connection_id
- {"",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // packet number
- {"",
- {0x12, 0x34, 0x9A, 0xBC}},
- // frame type (two-byte encoding)
- {"",
- {kVarInt62TwoBytes + 0x00, 0x18}}
- },
- {
- // type (short header, 4 byte packet number)
- {"",
- {0x43}},
- // connection_id
- {"",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // packet number
- {"",
- {0x12, 0x34, 0x9A, 0xBC}},
- // frame type (two-byte encoding)
- {"",
- {kVarInt62TwoBytes + 0x00, 0x20}}
- },
- {
- // type (short header, 4 byte packet number)
- {"",
- {0x43}},
- // connection_id
- {"",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // packet number
- {"",
- {0x12, 0x34, 0x9A, 0xBC}},
- // frame type (two-byte encoding)
- {"",
- {kVarInt62TwoBytes + 0x00, 0x21}}
- },
- };
- // clang-format on
-
- for (PacketFragments& packet : packets) {
- std::unique_ptr<QuicEncryptedPacket> encrypted(
- AssemblePacketFromFragments(packet));
-
- EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
-
- EXPECT_THAT(framer_.error(), IsError(IETF_QUIC_PROTOCOL_VIOLATION));
- EXPECT_EQ("Frame type not minimally encoded.", framer_.detailed_error());
- }
-}
-
-TEST_P(QuicFramerTest, RetireConnectionIdFrame) {
- if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
- // This frame is only for version 99.
- return;
- }
- SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
- // clang-format off
- PacketFragments packet_ietf = {
- // type (short header, 4 byte packet number)
- {"",
- {0x43}},
- // connection_id
- {"",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // packet number
- {"",
- {0x12, 0x34, 0x56, 0x78}},
- // frame type (IETF_RETIRE_CONNECTION_ID frame)
- {"",
- {0x19}},
- // Sequence number
- {"Unable to read retire connection ID frame sequence number.",
- {kVarInt62TwoBytes + 0x11, 0x22}}
- };
- // clang-format on
-
- std::unique_ptr<QuicEncryptedPacket> encrypted(
- AssemblePacketFromFragments(packet_ietf));
- EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
-
- EXPECT_THAT(framer_.error(), IsQuicNoError());
- ASSERT_TRUE(visitor_.header_.get());
- EXPECT_TRUE(CheckDecryption(
- *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
- PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
-
- EXPECT_EQ(0u, visitor_.stream_frames_.size());
-
- EXPECT_EQ(0x1122u, visitor_.retire_connection_id_.sequence_number);
-
- ASSERT_EQ(0u, visitor_.ack_frames_.size());
-
- CheckFramingBoundaries(packet_ietf, QUIC_INVALID_RETIRE_CONNECTION_ID_DATA);
-}
-
-TEST_P(QuicFramerTest, BuildRetireConnectionIdFramePacket) {
- if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
- // This frame is only for version 99.
- return;
- }
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
- QuicPacketHeader header;
- header.destination_connection_id = FramerTestConnectionId();
- header.reset_flag = false;
- header.version_flag = false;
- header.packet_number = kPacketNumber;
-
- QuicRetireConnectionIdFrame frame;
- frame.sequence_number = 0x1122;
-
- QuicFrames frames = {QuicFrame(&frame)};
-
- // clang-format off
- unsigned char packet_ietf[] = {
- // type (short header, 4 byte packet number)
- 0x43,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
-
- // frame type (IETF_RETIRE_CONNECTION_ID frame)
- 0x19,
- // sequence number
- kVarInt62TwoBytes + 0x11, 0x22
- };
- // clang-format on
-
- std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
- ASSERT_TRUE(data != nullptr);
-
- quiche::test::CompareCharArraysWithHexError(
- "constructed packet", data->data(), data->length(), AsChars(packet_ietf),
- ABSL_ARRAYSIZE(packet_ietf));
-}
-
-TEST_P(QuicFramerTest, AckFrameWithInvalidLargestObserved) {
- SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
- // clang-format off
- unsigned char packet[] = {
- // public flags (8 byte connection_id)
- 0x2C,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
-
- // frame type (ack frame)
- 0x45,
- // largest observed
- 0x00, 0x00,
- // Zero delta time.
- 0x00, 0x00,
- // first ack block length.
- 0x00, 0x00,
- // num timestamps.
- 0x00
- };
-
- unsigned char packet46[] = {
- // type (short header, 4 byte packet number)
- 0x43,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
-
- // frame type (ack frame)
- 0x45,
- // largest observed
- 0x00, 0x00,
- // Zero delta time.
- 0x00, 0x00,
- // first ack block length.
- 0x00, 0x00,
- // num timestamps.
- 0x00
- };
-
- unsigned char packet_ietf[] = {
- // type (short header, 4 byte packet number)
- 0x43,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
-
- // frame type (IETF_ACK frame)
- 0x02,
- // Largest acked
- kVarInt62OneByte + 0x00,
- // Zero delta time.
- kVarInt62OneByte + 0x00,
- // Ack block count 0
- kVarInt62OneByte + 0x00,
- // First ack block length
- kVarInt62OneByte + 0x00,
- };
- // clang-format on
-
- unsigned char* p = packet;
- size_t p_size = ABSL_ARRAYSIZE(packet);
- if (VersionHasIetfQuicFrames(framer_.transport_version())) {
- p = packet_ietf;
- p_size = ABSL_ARRAYSIZE(packet_ietf);
- } else if (framer_.version().HasIetfInvariantHeader()) {
- p = packet46;
- }
-
- QuicEncryptedPacket encrypted(AsChars(p), p_size, false);
- EXPECT_FALSE(framer_.ProcessPacket(encrypted));
- EXPECT_EQ(framer_.detailed_error(), "Largest acked is 0.");
-}
-
-TEST_P(QuicFramerTest, FirstAckBlockJustUnderFlow) {
- SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
- // clang-format off
- unsigned char packet[] = {
- // public flags (8 byte connection_id)
- 0x2C,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
-
- // frame type (ack frame)
- 0x45,
- // largest observed
- 0x00, 0x02,
- // Zero delta time.
- 0x00, 0x00,
- // first ack block length.
- 0x00, 0x03,
- // num timestamps.
- 0x00
- };
-
- unsigned char packet46[] = {
- // type (short header, 4 byte packet number)
- 0x43,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
-
- // frame type (ack frame)
- 0x45,
- // largest observed
- 0x00, 0x02,
- // Zero delta time.
- 0x00, 0x00,
- // first ack block length.
- 0x00, 0x03,
- // num timestamps.
- 0x00
- };
-
- unsigned char packet_ietf[] = {
- // type (short header, 4 byte packet number)
- 0x43,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
-
- // frame type (IETF_ACK frame)
- 0x02,
- // Largest acked
- kVarInt62OneByte + 0x02,
- // Zero delta time.
- kVarInt62OneByte + 0x00,
- // Ack block count 0
- kVarInt62OneByte + 0x00,
- // First ack block length
- kVarInt62OneByte + 0x02,
- };
- // clang-format on
-
- unsigned char* p = packet;
- size_t p_size = ABSL_ARRAYSIZE(packet);
- if (VersionHasIetfQuicFrames(framer_.transport_version())) {
- p = packet_ietf;
- p_size = ABSL_ARRAYSIZE(packet_ietf);
- } else if (framer_.version().HasIetfInvariantHeader()) {
- p = packet46;
- p_size = ABSL_ARRAYSIZE(packet46);
- }
-
- QuicEncryptedPacket encrypted(AsChars(p), p_size, false);
- EXPECT_FALSE(framer_.ProcessPacket(encrypted));
- EXPECT_EQ(framer_.detailed_error(),
- "Underflow with first ack block length 3 largest acked is 2.");
-}
-
-TEST_P(QuicFramerTest, ThirdAckBlockJustUnderflow) {
- SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
- // clang-format off
- unsigned char packet[] = {
- // public flags (8 byte connection_id)
- 0x2C,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
-
- // frame type (ack frame)
- 0x60,
- // largest observed
- 0x0A,
- // Zero delta time.
- 0x00, 0x00,
- // Num of ack blocks
- 0x02,
- // first ack block length.
- 0x02,
- // gap to next block
- 0x01,
- // ack block length
- 0x01,
- // gap to next block
- 0x01,
- // ack block length
- 0x06,
- // num timestamps.
- 0x00
- };
-
- unsigned char packet46[] = {
- // type (short header, 4 byte packet number)
- 0x43,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
-
- // frame type (ack frame)
- 0x60,
- // largest observed
- 0x0A,
- // Zero delta time.
- 0x00, 0x00,
- // Num of ack blocks
- 0x02,
- // first ack block length.
- 0x02,
- // gap to next block
- 0x01,
- // ack block length
- 0x01,
- // gap to next block
- 0x01,
- // ack block length
- 0x06,
- // num timestamps.
- 0x00
- };
-
- unsigned char packet_ietf[] = {
- // type (short header, 4 byte packet number)
- 0x43,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
-
- // frame type (IETF_ACK frame)
- 0x02,
- // Largest acked
- kVarInt62OneByte + 0x0A,
- // Zero delta time.
- kVarInt62OneByte + 0x00,
- // Ack block count 2
- kVarInt62OneByte + 0x02,
- // First ack block length
- kVarInt62OneByte + 0x01,
- // gap to next block length
- kVarInt62OneByte + 0x00,
- // ack block length
- kVarInt62OneByte + 0x00,
- // gap to next block length
- kVarInt62OneByte + 0x00,
- // ack block length
- kVarInt62OneByte + 0x05,
- };
- // clang-format on
-
- unsigned char* p = packet;
- size_t p_size = ABSL_ARRAYSIZE(packet);
- if (VersionHasIetfQuicFrames(framer_.transport_version())) {
- p = packet_ietf;
- p_size = ABSL_ARRAYSIZE(packet_ietf);
- } else if (framer_.version().HasIetfInvariantHeader()) {
- p = packet46;
- p_size = ABSL_ARRAYSIZE(packet46);
- }
-
- QuicEncryptedPacket encrypted(AsChars(p), p_size, false);
- EXPECT_FALSE(framer_.ProcessPacket(encrypted));
- if (VersionHasIetfQuicFrames(framer_.transport_version())) {
- EXPECT_EQ(framer_.detailed_error(),
- "Underflow with ack block length 6 latest ack block end is 5.");
- } else {
- EXPECT_EQ(framer_.detailed_error(),
- "Underflow with ack block length 6, end of block is 6.");
- }
-}
-
-TEST_P(QuicFramerTest, CoalescedPacket) {
- if (!QuicVersionHasLongHeaderLengths(framer_.transport_version())) {
- return;
- }
- SetDecrypterLevel(ENCRYPTION_ZERO_RTT);
- // clang-format off
- unsigned char packet[] = {
- // first coalesced packet
- // public flags (long header with packet type ZERO_RTT_PROTECTED and
- // 4-byte packet number)
- 0xD3,
- // version
- QUIC_VERSION_BYTES,
- // destination connection ID length
- 0x08,
- // destination connection ID
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // source connection ID length
- 0x00,
- // long header packet length
- 0x1E,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
- // frame type (stream frame with fin)
- 0xFE,
- // stream id
- 0x02, 0x03, 0x04,
- // offset
- 0x3A, 0x98, 0xFE, 0xDC, 0x32, 0x10, 0x76, 0x54,
- // data length
- 0x00, 0x0c,
- // data
- 'h', 'e', 'l', 'l',
- 'o', ' ', 'w', 'o',
- 'r', 'l', 'd', '!',
- // second coalesced packet
- // public flags (long header with packet type ZERO_RTT_PROTECTED and
- // 4-byte packet number)
- 0xD3,
- // version
- QUIC_VERSION_BYTES,
- // destination connection ID length
- 0x08,
- // destination connection ID
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // source connection ID length
- 0x00,
- // long header packet length
- 0x1E,
- // packet number
- 0x12, 0x34, 0x56, 0x79,
- // frame type (stream frame with fin)
- 0xFE,
- // stream id
- 0x02, 0x03, 0x04,
- // offset
- 0x3A, 0x98, 0xFE, 0xDC, 0x32, 0x10, 0x76, 0x54,
- // data length
- 0x00, 0x0c,
- // data
- 'H', 'E', 'L', 'L',
- 'O', '_', 'W', 'O',
- 'R', 'L', 'D', '?',
- };
- unsigned char packet_ietf[] = {
- // first coalesced packet
- // public flags (long header with packet type ZERO_RTT_PROTECTED and
- // 4-byte packet number)
- 0xD3,
- // version
- QUIC_VERSION_BYTES,
- // destination connection ID length
- 0x08,
- // destination connection ID
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // source connection ID length
- 0x00,
- // long header packet length
- 0x1E,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
- // frame type (IETF_STREAM frame with FIN, LEN, and OFFSET bits set)
- 0x08 | 0x01 | 0x02 | 0x04,
- // stream id
- kVarInt62FourBytes + 0x00, 0x02, 0x03, 0x04,
- // offset
- kVarInt62EightBytes + 0x3A, 0x98, 0xFE, 0xDC,
- 0x32, 0x10, 0x76, 0x54,
- // data length
- kVarInt62OneByte + 0x0c,
- // data
- 'h', 'e', 'l', 'l',
- 'o', ' ', 'w', 'o',
- 'r', 'l', 'd', '!',
- // second coalesced packet
- // public flags (long header with packet type ZERO_RTT_PROTECTED and
- // 4-byte packet number)
- 0xD3,
- // version
- QUIC_VERSION_BYTES,
- // destination connection ID length
- 0x08,
- // destination connection ID
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // source connection ID length
- 0x00,
- // long header packet length
- 0x1E,
- // packet number
- 0x12, 0x34, 0x56, 0x79,
- // frame type (IETF_STREAM frame with FIN, LEN, and OFFSET bits set)
- 0x08 | 0x01 | 0x02 | 0x04,
- // stream id
- kVarInt62FourBytes + 0x00, 0x02, 0x03, 0x04,
- // offset
- kVarInt62EightBytes + 0x3A, 0x98, 0xFE, 0xDC,
- 0x32, 0x10, 0x76, 0x54,
- // data length
- kVarInt62OneByte + 0x0c,
- // data
- 'H', 'E', 'L', 'L',
- 'O', '_', 'W', 'O',
- 'R', 'L', 'D', '?',
- };
- // clang-format on
- const size_t first_packet_ietf_size = 46;
- // If the first packet changes, the attempt to fix the first byte of the
- // second packet will fail.
- EXPECT_EQ(packet_ietf[first_packet_ietf_size], 0xD3);
-
- unsigned char* p = packet;
- size_t p_length = ABSL_ARRAYSIZE(packet);
- if (framer_.version().HasIetfQuicFrames()) {
- ReviseFirstByteByVersion(packet_ietf);
- ReviseFirstByteByVersion(&packet_ietf[first_packet_ietf_size]);
- p = packet_ietf;
- p_length = ABSL_ARRAYSIZE(packet_ietf);
- }
-
- QuicEncryptedPacket encrypted(AsChars(p), p_length, false);
- EXPECT_TRUE(framer_.ProcessPacket(encrypted));
-
- EXPECT_THAT(framer_.error(), IsQuicNoError());
- ASSERT_TRUE(visitor_.header_.get());
-
- ASSERT_EQ(1u, visitor_.stream_frames_.size());
- EXPECT_EQ(0u, visitor_.ack_frames_.size());
-
- // Stream ID should be the last 3 bytes of kStreamId.
- EXPECT_EQ(0x00FFFFFF & kStreamId, visitor_.stream_frames_[0]->stream_id);
- EXPECT_TRUE(visitor_.stream_frames_[0]->fin);
- EXPECT_EQ(kStreamOffset, visitor_.stream_frames_[0]->offset);
- CheckStreamFrameData("hello world!", visitor_.stream_frames_[0].get());
-
- ASSERT_EQ(visitor_.coalesced_packets_.size(), 1u);
- EXPECT_TRUE(framer_.ProcessPacket(*visitor_.coalesced_packets_[0].get()));
-
- EXPECT_THAT(framer_.error(), IsQuicNoError());
- ASSERT_TRUE(visitor_.header_.get());
-
- ASSERT_EQ(2u, visitor_.stream_frames_.size());
- EXPECT_EQ(0u, visitor_.ack_frames_.size());
-
- // Stream ID should be the last 3 bytes of kStreamId.
- EXPECT_EQ(0x00FFFFFF & kStreamId, visitor_.stream_frames_[1]->stream_id);
- EXPECT_TRUE(visitor_.stream_frames_[1]->fin);
- EXPECT_EQ(kStreamOffset, visitor_.stream_frames_[1]->offset);
- CheckStreamFrameData("HELLO_WORLD?", visitor_.stream_frames_[1].get());
-}
-
-TEST_P(QuicFramerTest, CoalescedPacketWithUdpPadding) {
- if (!framer_.version().HasLongHeaderLengths()) {
- return;
- }
- SetDecrypterLevel(ENCRYPTION_ZERO_RTT);
- // clang-format off
- unsigned char packet[] = {
- // first coalesced packet
- // public flags (long header with packet type ZERO_RTT_PROTECTED and
- // 4-byte packet number)
- 0xD3,
- // version
- QUIC_VERSION_BYTES,
- // destination connection ID length
- 0x08,
- // destination connection ID
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // source connection ID length
- 0x00,
- // long header packet length
- 0x1E,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
- // frame type (stream frame with fin)
- 0xFE,
- // stream id
- 0x02, 0x03, 0x04,
- // offset
- 0x3A, 0x98, 0xFE, 0xDC, 0x32, 0x10, 0x76, 0x54,
- // data length
- 0x00, 0x0c,
- // data
- 'h', 'e', 'l', 'l',
- 'o', ' ', 'w', 'o',
- 'r', 'l', 'd', '!',
- // padding
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00,
- };
- unsigned char packet_ietf[] = {
- // first coalesced packet
- // public flags (long header with packet type ZERO_RTT_PROTECTED and
- // 4-byte packet number)
- 0xD3,
- // version
- QUIC_VERSION_BYTES,
- // destination connection ID length
- 0x08,
- // destination connection ID
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // source connection ID length
- 0x00,
- // long header packet length
- 0x1E,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
- // frame type (IETF_STREAM frame with FIN, LEN, and OFFSET bits set)
- 0x08 | 0x01 | 0x02 | 0x04,
- // stream id
- kVarInt62FourBytes + 0x00, 0x02, 0x03, 0x04,
- // offset
- kVarInt62EightBytes + 0x3A, 0x98, 0xFE, 0xDC,
- 0x32, 0x10, 0x76, 0x54,
- // data length
- kVarInt62OneByte + 0x0c,
- // data
- 'h', 'e', 'l', 'l',
- 'o', ' ', 'w', 'o',
- 'r', 'l', 'd', '!',
- // padding
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00,
- };
- // clang-format on
-
- unsigned char* p = packet;
- size_t p_length = ABSL_ARRAYSIZE(packet);
- if (framer_.version().HasIetfQuicFrames()) {
- ReviseFirstByteByVersion(packet_ietf);
- p = packet_ietf;
- p_length = ABSL_ARRAYSIZE(packet_ietf);
- }
-
- QuicEncryptedPacket encrypted(AsChars(p), p_length, false);
- EXPECT_TRUE(framer_.ProcessPacket(encrypted));
-
- EXPECT_THAT(framer_.error(), IsQuicNoError());
- ASSERT_TRUE(visitor_.header_.get());
-
- ASSERT_EQ(1u, visitor_.stream_frames_.size());
- EXPECT_EQ(0u, visitor_.ack_frames_.size());
-
- // Stream ID should be the last 3 bytes of kStreamId.
- EXPECT_EQ(0x00FFFFFF & kStreamId, visitor_.stream_frames_[0]->stream_id);
- EXPECT_TRUE(visitor_.stream_frames_[0]->fin);
- EXPECT_EQ(kStreamOffset, visitor_.stream_frames_[0]->offset);
- CheckStreamFrameData("hello world!", visitor_.stream_frames_[0].get());
-
- EXPECT_EQ(visitor_.coalesced_packets_.size(), 0u);
-}
-
-TEST_P(QuicFramerTest, CoalescedPacketWithDifferentVersion) {
- if (!QuicVersionHasLongHeaderLengths(framer_.transport_version())) {
- return;
- }
- SetDecrypterLevel(ENCRYPTION_ZERO_RTT);
- // clang-format off
- unsigned char packet[] = {
- // first coalesced packet
- // public flags (long header with packet type ZERO_RTT_PROTECTED and
- // 4-byte packet number)
- 0xD3,
- // version
- QUIC_VERSION_BYTES,
- // destination connection ID length
- 0x08,
- // destination connection ID
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // source connection ID length
- 0x00,
- // long header packet length
- 0x1E,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
- // frame type (stream frame with fin)
- 0xFE,
- // stream id
- 0x02, 0x03, 0x04,
- // offset
- 0x3A, 0x98, 0xFE, 0xDC, 0x32, 0x10, 0x76, 0x54,
- // data length
- 0x00, 0x0c,
- // data
- 'h', 'e', 'l', 'l',
- 'o', ' ', 'w', 'o',
- 'r', 'l', 'd', '!',
- // second coalesced packet
- // public flags (long header with packet type ZERO_RTT_PROTECTED and
- // 4-byte packet number)
- 0xD3,
- // garbage version
- 'G', 'A', 'B', 'G',
- // destination connection ID length
- 0x08,
- // destination connection ID
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // source connection ID length
- 0x00,
- // long header packet length
- 0x1E,
- // packet number
- 0x12, 0x34, 0x56, 0x79,
- // frame type (stream frame with fin)
- 0xFE,
- // stream id
- 0x02, 0x03, 0x04,
- // offset
- 0x3A, 0x98, 0xFE, 0xDC, 0x32, 0x10, 0x76, 0x54,
- // data length
- 0x00, 0x0c,
- // data
- 'H', 'E', 'L', 'L',
- 'O', '_', 'W', 'O',
- 'R', 'L', 'D', '?',
- };
- unsigned char packet_ietf[] = {
- // first coalesced packet
- // public flags (long header with packet type ZERO_RTT_PROTECTED and
- // 4-byte packet number)
- 0xD3,
- // version
- QUIC_VERSION_BYTES,
- // destination connection ID length
- 0x08,
- // destination connection ID
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // source connection ID length
- 0x00,
- // long header packet length
- 0x1E,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
- // frame type (IETF_STREAM frame with FIN, LEN, and OFFSET bits set)
- 0x08 | 0x01 | 0x02 | 0x04,
- // stream id
- kVarInt62FourBytes + 0x00, 0x02, 0x03, 0x04,
- // offset
- kVarInt62EightBytes + 0x3A, 0x98, 0xFE, 0xDC,
- 0x32, 0x10, 0x76, 0x54,
- // data length
- kVarInt62OneByte + 0x0c,
- // data
- 'h', 'e', 'l', 'l',
- 'o', ' ', 'w', 'o',
- 'r', 'l', 'd', '!',
- // second coalesced packet
- // public flags (long header with packet type ZERO_RTT_PROTECTED and
- // 4-byte packet number)
- 0xD3,
- // garbage version
- 'G', 'A', 'B', 'G',
- // destination connection ID length
- 0x08,
- // destination connection ID
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // source connection ID length
- 0x00,
- // long header packet length
- 0x1E,
- // packet number
- 0x12, 0x34, 0x56, 0x79,
- // frame type (IETF_STREAM frame with FIN, LEN, and OFFSET bits set)
- 0x08 | 0x01 | 0x02 | 0x04,
- // stream id
- kVarInt62FourBytes + 0x00, 0x02, 0x03, 0x04,
- // offset
- kVarInt62EightBytes + 0x3A, 0x98, 0xFE, 0xDC,
- 0x32, 0x10, 0x76, 0x54,
- // data length
- kVarInt62OneByte + 0x0c,
- // data
- 'H', 'E', 'L', 'L',
- 'O', '_', 'W', 'O',
- 'R', 'L', 'D', '?',
- };
- // clang-format on
- const size_t first_packet_ietf_size = 46;
- // If the first packet changes, the attempt to fix the first byte of the
- // second packet will fail.
- EXPECT_EQ(packet_ietf[first_packet_ietf_size], 0xD3);
-
- unsigned char* p = packet;
- size_t p_length = ABSL_ARRAYSIZE(packet);
- if (framer_.version().HasIetfQuicFrames()) {
- ReviseFirstByteByVersion(packet_ietf);
- ReviseFirstByteByVersion(&packet_ietf[first_packet_ietf_size]);
- p = packet_ietf;
- p_length = ABSL_ARRAYSIZE(packet_ietf);
- }
-
- QuicEncryptedPacket encrypted(AsChars(p), p_length, false);
- EXPECT_TRUE(framer_.ProcessPacket(encrypted));
-
- EXPECT_THAT(framer_.error(), IsQuicNoError());
- ASSERT_TRUE(visitor_.header_.get());
-
- ASSERT_EQ(1u, visitor_.stream_frames_.size());
- EXPECT_EQ(0u, visitor_.ack_frames_.size());
-
- // Stream ID should be the last 3 bytes of kStreamId.
- EXPECT_EQ(0x00FFFFFF & kStreamId, visitor_.stream_frames_[0]->stream_id);
- EXPECT_TRUE(visitor_.stream_frames_[0]->fin);
- EXPECT_EQ(kStreamOffset, visitor_.stream_frames_[0]->offset);
- CheckStreamFrameData("hello world!", visitor_.stream_frames_[0].get());
-
- ASSERT_EQ(visitor_.coalesced_packets_.size(), 1u);
- EXPECT_TRUE(framer_.ProcessPacket(*visitor_.coalesced_packets_[0].get()));
-
- EXPECT_THAT(framer_.error(), IsQuicNoError());
- ASSERT_TRUE(visitor_.header_.get());
-
- ASSERT_EQ(1u, visitor_.stream_frames_.size());
- // Verify version mismatch gets reported.
- EXPECT_EQ(1, visitor_.version_mismatch_);
-}
-
-TEST_P(QuicFramerTest, UndecryptablePacketWithoutDecrypter) {
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
-
- if (!framer_.version().KnowsWhichDecrypterToUse()) {
- // We create a bad client decrypter by using initial encryption with a
- // bogus connection ID; it should fail to decrypt everything.
- QuicConnectionId bogus_connection_id = TestConnectionId(0xbad);
- CrypterPair bogus_crypters;
- CryptoUtils::CreateInitialObfuscators(Perspective::IS_CLIENT,
- framer_.version(),
- bogus_connection_id, &bogus_crypters);
- // This removes all other decrypters.
- framer_.SetDecrypter(ENCRYPTION_FORWARD_SECURE,
- std::move(bogus_crypters.decrypter));
- }
-
- // clang-format off
- unsigned char packet[] = {
- // public flags (version included, 8-byte connection ID,
- // 4-byte packet number)
- 0x28,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x12, 0x34, 0x56, 0x00,
- // padding frames
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- };
- unsigned char packet46[] = {
- // public flags (long header with packet type HANDSHAKE and
- // 4-byte packet number)
- 0xE3,
- // version
- QUIC_VERSION_BYTES,
- // connection ID lengths
- 0x05,
- // source connection ID
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // long header packet length
- 0x05,
- // packet number
- 0x12, 0x34, 0x56, 0x00,
- // padding frames
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- };
- unsigned char packet49[] = {
- // public flags (long header with packet type HANDSHAKE and
- // 4-byte packet number)
- 0xE3,
- // version
- QUIC_VERSION_BYTES,
- // destination connection ID length
- 0x00,
- // source connection ID length
- 0x08,
- // source connection ID
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // long header packet length
- 0x24,
- // packet number
- 0x12, 0x34, 0x56, 0x00,
- // padding frames
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- };
- // clang-format on
- unsigned char* p = packet;
- size_t p_length = ABSL_ARRAYSIZE(packet);
- if (framer_.version().HasLongHeaderLengths()) {
- ReviseFirstByteByVersion(packet49);
- p = packet49;
- p_length = ABSL_ARRAYSIZE(packet49);
- } else if (framer_.version().HasIetfInvariantHeader()) {
- p = packet46;
- p_length = ABSL_ARRAYSIZE(packet46);
- }
- // First attempt decryption without the handshake crypter.
- EXPECT_FALSE(
- framer_.ProcessPacket(QuicEncryptedPacket(AsChars(p), p_length, false)));
- EXPECT_THAT(framer_.error(), IsError(QUIC_DECRYPTION_FAILURE));
- ASSERT_EQ(1u, visitor_.undecryptable_packets_.size());
- ASSERT_EQ(1u, visitor_.undecryptable_decryption_levels_.size());
- ASSERT_EQ(1u, visitor_.undecryptable_has_decryption_keys_.size());
- quiche::test::CompareCharArraysWithHexError(
- "undecryptable packet", visitor_.undecryptable_packets_[0]->data(),
- visitor_.undecryptable_packets_[0]->length(), AsChars(p), p_length);
- if (framer_.version().KnowsWhichDecrypterToUse()) {
- EXPECT_EQ(ENCRYPTION_HANDSHAKE,
- visitor_.undecryptable_decryption_levels_[0]);
- }
- EXPECT_FALSE(visitor_.undecryptable_has_decryption_keys_[0]);
-}
-
-TEST_P(QuicFramerTest, UndecryptablePacketWithDecrypter) {
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
-
- // We create a bad client decrypter by using initial encryption with a
- // bogus connection ID; it should fail to decrypt everything.
- QuicConnectionId bogus_connection_id = TestConnectionId(0xbad);
- CrypterPair bad_handshake_crypters;
- CryptoUtils::CreateInitialObfuscators(Perspective::IS_CLIENT,
- framer_.version(), bogus_connection_id,
- &bad_handshake_crypters);
- if (framer_.version().KnowsWhichDecrypterToUse()) {
- framer_.InstallDecrypter(ENCRYPTION_HANDSHAKE,
- std::move(bad_handshake_crypters.decrypter));
- } else {
- framer_.SetDecrypter(ENCRYPTION_HANDSHAKE,
- std::move(bad_handshake_crypters.decrypter));
- }
-
- // clang-format off
- unsigned char packet[] = {
- // public flags (version included, 8-byte connection ID,
- // 4-byte packet number)
- 0x28,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x12, 0x34, 0x56, 0x00,
- // padding frames
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- };
- unsigned char packet46[] = {
- // public flags (long header with packet type HANDSHAKE and
- // 4-byte packet number)
- 0xE3,
- // version
- QUIC_VERSION_BYTES,
- // connection ID lengths
- 0x05,
- // source connection ID
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // long header packet length
- 0x05,
- // packet number
- 0x12, 0x34, 0x56, 0x00,
- // padding frames
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- };
- unsigned char packet49[] = {
- // public flags (long header with packet type HANDSHAKE and
- // 4-byte packet number)
- 0xE3,
- // version
- QUIC_VERSION_BYTES,
- // destination connection ID length
- 0x00,
- // source connection ID length
- 0x08,
- // source connection ID
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // long header packet length
- 0x24,
- // packet number
- 0x12, 0x34, 0x56, 0x00,
- // padding frames
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- };
- // clang-format on
- unsigned char* p = packet;
- size_t p_length = ABSL_ARRAYSIZE(packet);
- if (framer_.version().HasLongHeaderLengths()) {
- ReviseFirstByteByVersion(packet49);
- p = packet49;
- p_length = ABSL_ARRAYSIZE(packet49);
- } else if (framer_.version().HasIetfInvariantHeader()) {
- p = packet46;
- p_length = ABSL_ARRAYSIZE(packet46);
- }
-
- EXPECT_FALSE(
- framer_.ProcessPacket(QuicEncryptedPacket(AsChars(p), p_length, false)));
- EXPECT_THAT(framer_.error(), IsError(QUIC_DECRYPTION_FAILURE));
- ASSERT_EQ(1u, visitor_.undecryptable_packets_.size());
- ASSERT_EQ(1u, visitor_.undecryptable_decryption_levels_.size());
- ASSERT_EQ(1u, visitor_.undecryptable_has_decryption_keys_.size());
- quiche::test::CompareCharArraysWithHexError(
- "undecryptable packet", visitor_.undecryptable_packets_[0]->data(),
- visitor_.undecryptable_packets_[0]->length(), AsChars(p), p_length);
- if (framer_.version().KnowsWhichDecrypterToUse()) {
- EXPECT_EQ(ENCRYPTION_HANDSHAKE,
- visitor_.undecryptable_decryption_levels_[0]);
- }
- EXPECT_EQ(framer_.version().KnowsWhichDecrypterToUse(),
- visitor_.undecryptable_has_decryption_keys_[0]);
-}
-
-TEST_P(QuicFramerTest, UndecryptableCoalescedPacket) {
- if (!QuicVersionHasLongHeaderLengths(framer_.transport_version())) {
- return;
- }
- ASSERT_TRUE(framer_.version().KnowsWhichDecrypterToUse());
- SetDecrypterLevel(ENCRYPTION_ZERO_RTT);
- // We create a bad client decrypter by using initial encryption with a
- // bogus connection ID; it should fail to decrypt everything.
- QuicConnectionId bogus_connection_id = TestConnectionId(0xbad);
- CrypterPair bad_handshake_crypters;
- CryptoUtils::CreateInitialObfuscators(Perspective::IS_CLIENT,
- framer_.version(), bogus_connection_id,
- &bad_handshake_crypters);
- framer_.InstallDecrypter(ENCRYPTION_HANDSHAKE,
- std::move(bad_handshake_crypters.decrypter));
- // clang-format off
- unsigned char packet[] = {
- // first coalesced packet
- // public flags (long header with packet type HANDSHAKE and
- // 4-byte packet number)
- 0xE3,
- // version
- QUIC_VERSION_BYTES,
- // destination connection ID length
- 0x08,
- // destination connection ID
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // source connection ID length
- 0x00,
- // long header packet length
- 0x1E,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
- // frame type (stream frame with fin)
- 0xFE,
- // stream id
- 0x02, 0x03, 0x04,
- // offset
- 0x3A, 0x98, 0xFE, 0xDC, 0x32, 0x10, 0x76, 0x54,
- // data length
- 0x00, 0x0c,
- // data
- 'h', 'e', 'l', 'l',
- 'o', ' ', 'w', 'o',
- 'r', 'l', 'd', '!',
- // second coalesced packet
- // public flags (long header with packet type ZERO_RTT_PROTECTED and
- // 4-byte packet number)
- 0xD3,
- // version
- QUIC_VERSION_BYTES,
- // destination connection ID length
- 0x08,
- // destination connection ID
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // source connection ID length
- 0x00,
- // long header packet length
- 0x1E,
- // packet number
- 0x12, 0x34, 0x56, 0x79,
- // frame type (stream frame with fin)
- 0xFE,
- // stream id
- 0x02, 0x03, 0x04,
- // offset
- 0x3A, 0x98, 0xFE, 0xDC, 0x32, 0x10, 0x76, 0x54,
- // data length
- 0x00, 0x0c,
- // data
- 'H', 'E', 'L', 'L',
- 'O', '_', 'W', 'O',
- 'R', 'L', 'D', '?',
- };
- unsigned char packet_ietf[] = {
- // first coalesced packet
- // public flags (long header with packet type HANDSHAKE and
- // 4-byte packet number)
- 0xE3,
- // version
- QUIC_VERSION_BYTES,
- // destination connection ID length
- 0x08,
- // destination connection ID
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // source connection ID length
- 0x00,
- // long header packet length
- 0x1E,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
- // frame type (IETF_STREAM frame with FIN, LEN, and OFFSET bits set)
- 0x08 | 0x01 | 0x02 | 0x04,
- // stream id
- kVarInt62FourBytes + 0x00, 0x02, 0x03, 0x04,
- // offset
- kVarInt62EightBytes + 0x3A, 0x98, 0xFE, 0xDC,
- 0x32, 0x10, 0x76, 0x54,
- // data length
- kVarInt62OneByte + 0x0c,
- // data
- 'h', 'e', 'l', 'l',
- 'o', ' ', 'w', 'o',
- 'r', 'l', 'd', '!',
- // second coalesced packet
- // public flags (long header with packet type ZERO_RTT_PROTECTED and
- // 4-byte packet number)
- 0xD3,
- // version
- QUIC_VERSION_BYTES,
- // destination connection ID length
- 0x08,
- // destination connection ID
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // source connection ID length
- 0x00,
- // long header packet length
- 0x1E,
- // packet number
- 0x12, 0x34, 0x56, 0x79,
- // frame type (IETF_STREAM frame with FIN, LEN, and OFFSET bits set)
- 0x08 | 0x01 | 0x02 | 0x04,
- // stream id
- kVarInt62FourBytes + 0x00, 0x02, 0x03, 0x04,
- // offset
- kVarInt62EightBytes + 0x3A, 0x98, 0xFE, 0xDC,
- 0x32, 0x10, 0x76, 0x54,
- // data length
- kVarInt62OneByte + 0x0c,
- // data
- 'H', 'E', 'L', 'L',
- 'O', '_', 'W', 'O',
- 'R', 'L', 'D', '?',
- };
- // clang-format on
- const size_t length_of_first_coalesced_packet = 46;
- // If the first packet changes, the attempt to fix the first byte of the
- // second packet will fail.
- EXPECT_EQ(packet_ietf[length_of_first_coalesced_packet], 0xD3);
-
- unsigned char* p = packet;
- size_t p_length = ABSL_ARRAYSIZE(packet);
- if (framer_.version().HasIetfQuicFrames()) {
- ReviseFirstByteByVersion(packet_ietf);
- ReviseFirstByteByVersion(&packet_ietf[length_of_first_coalesced_packet]);
- p = packet_ietf;
- p_length = ABSL_ARRAYSIZE(packet_ietf);
- }
-
- QuicEncryptedPacket encrypted(AsChars(p), p_length, false);
-
- EXPECT_FALSE(framer_.ProcessPacket(encrypted));
-
- EXPECT_THAT(framer_.error(), IsError(QUIC_DECRYPTION_FAILURE));
-
- ASSERT_EQ(1u, visitor_.undecryptable_packets_.size());
- ASSERT_EQ(1u, visitor_.undecryptable_decryption_levels_.size());
- ASSERT_EQ(1u, visitor_.undecryptable_has_decryption_keys_.size());
- // Make sure we only receive the first undecryptable packet and not the
- // full packet including the second coalesced packet.
- quiche::test::CompareCharArraysWithHexError(
- "undecryptable packet", visitor_.undecryptable_packets_[0]->data(),
- visitor_.undecryptable_packets_[0]->length(), AsChars(p),
- length_of_first_coalesced_packet);
- EXPECT_EQ(ENCRYPTION_HANDSHAKE, visitor_.undecryptable_decryption_levels_[0]);
- EXPECT_TRUE(visitor_.undecryptable_has_decryption_keys_[0]);
-
- // Make sure the second coalesced packet is parsed correctly.
- ASSERT_EQ(visitor_.coalesced_packets_.size(), 1u);
- EXPECT_TRUE(framer_.ProcessPacket(*visitor_.coalesced_packets_[0].get()));
-
- ASSERT_TRUE(visitor_.header_.get());
-
- ASSERT_EQ(1u, visitor_.stream_frames_.size());
- EXPECT_EQ(0u, visitor_.ack_frames_.size());
-
- // Stream ID should be the last 3 bytes of kStreamId.
- EXPECT_EQ(0x00FFFFFF & kStreamId, visitor_.stream_frames_[0]->stream_id);
- EXPECT_TRUE(visitor_.stream_frames_[0]->fin);
- EXPECT_EQ(kStreamOffset, visitor_.stream_frames_[0]->offset);
- CheckStreamFrameData("HELLO_WORLD?", visitor_.stream_frames_[0].get());
-}
-
-TEST_P(QuicFramerTest, MismatchedCoalescedPacket) {
- if (!QuicVersionHasLongHeaderLengths(framer_.transport_version())) {
- return;
- }
- SetDecrypterLevel(ENCRYPTION_ZERO_RTT);
- // clang-format off
- unsigned char packet[] = {
- // first coalesced packet
- // public flags (long header with packet type ZERO_RTT_PROTECTED and
- // 4-byte packet number)
- 0xD3,
- // version
- QUIC_VERSION_BYTES,
- // destination connection ID length
- 0x08,
- // destination connection ID
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // source connection ID length
- 0x00,
- // long header packet length
- 0x1E,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
- // frame type (stream frame with fin)
- 0xFE,
- // stream id
- 0x02, 0x03, 0x04,
- // offset
- 0x3A, 0x98, 0xFE, 0xDC, 0x32, 0x10, 0x76, 0x54,
- // data length
- 0x00, 0x0c,
- // data
- 'h', 'e', 'l', 'l',
- 'o', ' ', 'w', 'o',
- 'r', 'l', 'd', '!',
- // second coalesced packet
- // public flags (long header with packet type ZERO_RTT_PROTECTED and
- // 4-byte packet number)
- 0xD3,
- // version
- QUIC_VERSION_BYTES,
- // destination connection ID length
- 0x08,
- // destination connection ID
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x11,
- // source connection ID length
- 0x00,
- // long header packet length
- 0x1E,
- // packet number
- 0x12, 0x34, 0x56, 0x79,
- // frame type (stream frame with fin)
- 0xFE,
- // stream id
- 0x02, 0x03, 0x04,
- // offset
- 0x3A, 0x98, 0xFE, 0xDC, 0x32, 0x10, 0x76, 0x54,
- // data length
- 0x00, 0x0c,
- // data
- 'H', 'E', 'L', 'L',
- 'O', '_', 'W', 'O',
- 'R', 'L', 'D', '?',
- };
- unsigned char packet_ietf[] = {
- // first coalesced packet
- // public flags (long header with packet type ZERO_RTT_PROTECTED and
- // 4-byte packet number)
- 0xD3,
- // version
- QUIC_VERSION_BYTES,
- // destination connection ID length
- 0x08,
- // destination connection ID
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // source connection ID length
- 0x00,
- // long header packet length
- 0x1E,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
- // frame type (IETF_STREAM frame with FIN, LEN, and OFFSET bits set)
- 0x08 | 0x01 | 0x02 | 0x04,
- // stream id
- kVarInt62FourBytes + 0x00, 0x02, 0x03, 0x04,
- // offset
- kVarInt62EightBytes + 0x3A, 0x98, 0xFE, 0xDC,
- 0x32, 0x10, 0x76, 0x54,
- // data length
- kVarInt62OneByte + 0x0c,
- // data
- 'h', 'e', 'l', 'l',
- 'o', ' ', 'w', 'o',
- 'r', 'l', 'd', '!',
- // second coalesced packet
- // public flags (long header with packet type ZERO_RTT_PROTECTED and
- // 4-byte packet number)
- 0xD3,
- // version
- QUIC_VERSION_BYTES,
- // destination connection ID length
- 0x08,
- // destination connection ID
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x11,
- // source connection ID length
- 0x00,
- // long header packet length
- 0x1E,
- // packet number
- 0x12, 0x34, 0x56, 0x79,
- // frame type (IETF_STREAM frame with FIN, LEN, and OFFSET bits set)
- 0x08 | 0x01 | 0x02 | 0x04,
- // stream id
- kVarInt62FourBytes + 0x00, 0x02, 0x03, 0x04,
- // offset
- kVarInt62EightBytes + 0x3A, 0x98, 0xFE, 0xDC,
- 0x32, 0x10, 0x76, 0x54,
- // data length
- kVarInt62OneByte + 0x0c,
- // data
- 'H', 'E', 'L', 'L',
- 'O', '_', 'W', 'O',
- 'R', 'L', 'D', '?',
- };
- // clang-format on
- const size_t length_of_first_coalesced_packet = 46;
- // If the first packet changes, the attempt to fix the first byte of the
- // second packet will fail.
- EXPECT_EQ(packet_ietf[length_of_first_coalesced_packet], 0xD3);
-
- unsigned char* p = packet;
- size_t p_length = ABSL_ARRAYSIZE(packet);
- if (framer_.version().HasIetfQuicFrames()) {
- ReviseFirstByteByVersion(packet_ietf);
- ReviseFirstByteByVersion(&packet_ietf[length_of_first_coalesced_packet]);
- p = packet_ietf;
- p_length = ABSL_ARRAYSIZE(packet_ietf);
- }
-
- QuicEncryptedPacket encrypted(AsChars(p), p_length, false);
-
- EXPECT_TRUE(framer_.ProcessPacket(encrypted));
-
- EXPECT_THAT(framer_.error(), IsQuicNoError());
- ASSERT_TRUE(visitor_.header_.get());
-
- ASSERT_EQ(1u, visitor_.stream_frames_.size());
- EXPECT_EQ(0u, visitor_.ack_frames_.size());
-
- // Stream ID should be the last 3 bytes of kStreamId.
- EXPECT_EQ(0x00FFFFFF & kStreamId, visitor_.stream_frames_[0]->stream_id);
- EXPECT_TRUE(visitor_.stream_frames_[0]->fin);
- EXPECT_EQ(kStreamOffset, visitor_.stream_frames_[0]->offset);
- CheckStreamFrameData("hello world!", visitor_.stream_frames_[0].get());
-
- ASSERT_EQ(visitor_.coalesced_packets_.size(), 0u);
-}
-
-TEST_P(QuicFramerTest, InvalidCoalescedPacket) {
- if (!QuicVersionHasLongHeaderLengths(framer_.transport_version())) {
- return;
- }
- SetDecrypterLevel(ENCRYPTION_ZERO_RTT);
- // clang-format off
- unsigned char packet[] = {
- // first coalesced packet
- // public flags (long header with packet type ZERO_RTT_PROTECTED and
- // 4-byte packet number)
- 0xD3,
- // version
- QUIC_VERSION_BYTES,
- // destination connection ID length
- 0x08,
- // destination connection ID
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // source connection ID length
- 0x00,
- // long header packet length
- 0x1E,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
- // frame type (stream frame with fin)
- 0xFE,
- // stream id
- 0x02, 0x03, 0x04,
- // offset
- 0x3A, 0x98, 0xFE, 0xDC, 0x32, 0x10, 0x76, 0x54,
- // data length
- 0x00, 0x0c,
- // data
- 'h', 'e', 'l', 'l',
- 'o', ' ', 'w', 'o',
- 'r', 'l', 'd', '!',
- // second coalesced packet
- // public flags (long header with packet type ZERO_RTT_PROTECTED and
- // 4-byte packet number)
- 0xD3,
- // version would be here but we cut off the invalid coalesced header.
- };
- unsigned char packet_ietf[] = {
- // first coalesced packet
- // public flags (long header with packet type ZERO_RTT_PROTECTED and
- // 4-byte packet number)
- 0xD3,
- // version
- QUIC_VERSION_BYTES,
- // destination connection ID length
- 0x08,
- // destination connection ID
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // source connection ID length
- 0x00,
- // long header packet length
- 0x1E,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
- // frame type (IETF_STREAM frame with FIN, LEN, and OFFSET bits set)
- 0x08 | 0x01 | 0x02 | 0x04,
- // stream id
- kVarInt62FourBytes + 0x00, 0x02, 0x03, 0x04,
- // offset
- kVarInt62EightBytes + 0x3A, 0x98, 0xFE, 0xDC,
- 0x32, 0x10, 0x76, 0x54,
- // data length
- kVarInt62OneByte + 0x0c,
- // data
- 'h', 'e', 'l', 'l',
- 'o', ' ', 'w', 'o',
- 'r', 'l', 'd', '!',
- // second coalesced packet
- // public flags (long header with packet type ZERO_RTT_PROTECTED and
- // 4-byte packet number)
- 0xD3,
- // version would be here but we cut off the invalid coalesced header.
- };
- // clang-format on
- const size_t length_of_first_coalesced_packet = 46;
- // If the first packet changes, the attempt to fix the first byte of the
- // second packet will fail.
- EXPECT_EQ(packet_ietf[length_of_first_coalesced_packet], 0xD3);
-
- unsigned char* p = packet;
- size_t p_length = ABSL_ARRAYSIZE(packet);
- if (framer_.version().HasIetfQuicFrames()) {
- ReviseFirstByteByVersion(packet_ietf);
- ReviseFirstByteByVersion(&packet_ietf[length_of_first_coalesced_packet]);
- p = packet_ietf;
- p_length = ABSL_ARRAYSIZE(packet_ietf);
- }
-
- QuicEncryptedPacket encrypted(AsChars(p), p_length, false);
-
- EXPECT_TRUE(framer_.ProcessPacket(encrypted));
-
- EXPECT_THAT(framer_.error(), IsQuicNoError());
- ASSERT_TRUE(visitor_.header_.get());
-
- ASSERT_EQ(1u, visitor_.stream_frames_.size());
- EXPECT_EQ(0u, visitor_.ack_frames_.size());
-
- // Stream ID should be the last 3 bytes of kStreamId.
- EXPECT_EQ(0x00FFFFFF & kStreamId, visitor_.stream_frames_[0]->stream_id);
- EXPECT_TRUE(visitor_.stream_frames_[0]->fin);
- EXPECT_EQ(kStreamOffset, visitor_.stream_frames_[0]->offset);
- CheckStreamFrameData("hello world!", visitor_.stream_frames_[0].get());
-
- ASSERT_EQ(visitor_.coalesced_packets_.size(), 0u);
-}
-
-// Some IETF implementations send an initial followed by zeroes instead of
-// padding inside the initial. We need to make sure that we still process
-// the initial correctly and ignore the zeroes.
-TEST_P(QuicFramerTest, CoalescedPacketWithZeroesRoundTrip) {
- if (!QuicVersionHasLongHeaderLengths(framer_.transport_version()) ||
- !framer_.version().UsesInitialObfuscators()) {
- return;
- }
- ASSERT_TRUE(framer_.version().KnowsWhichDecrypterToUse());
- QuicConnectionId connection_id = FramerTestConnectionId();
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
-
- CrypterPair client_crypters;
- CryptoUtils::CreateInitialObfuscators(Perspective::IS_CLIENT,
- framer_.version(), connection_id,
- &client_crypters);
- framer_.SetEncrypter(ENCRYPTION_INITIAL,
- std::move(client_crypters.encrypter));
-
- QuicPacketHeader header;
- header.destination_connection_id = connection_id;
- header.version_flag = true;
- header.packet_number = kPacketNumber;
- header.packet_number_length = PACKET_4BYTE_PACKET_NUMBER;
- header.long_packet_type = INITIAL;
- header.length_length = VARIABLE_LENGTH_INTEGER_LENGTH_2;
- header.retry_token_length_length = VARIABLE_LENGTH_INTEGER_LENGTH_1;
- QuicFrames frames = {QuicFrame(QuicPingFrame()),
- QuicFrame(QuicPaddingFrame(3))};
-
- std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
- ASSERT_NE(nullptr, data);
-
- // Add zeroes after the valid initial packet.
- unsigned char packet[kMaxOutgoingPacketSize] = {};
- size_t encrypted_length =
- framer_.EncryptPayload(ENCRYPTION_INITIAL, header.packet_number, *data,
- AsChars(packet), ABSL_ARRAYSIZE(packet));
- ASSERT_NE(0u, encrypted_length);
-
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
- CrypterPair server_crypters;
- CryptoUtils::CreateInitialObfuscators(Perspective::IS_SERVER,
- framer_.version(), connection_id,
- &server_crypters);
- framer_.InstallDecrypter(ENCRYPTION_INITIAL,
- std::move(server_crypters.decrypter));
-
- // Make sure the first long header initial packet parses correctly.
- QuicEncryptedPacket encrypted(AsChars(packet), ABSL_ARRAYSIZE(packet), false);
-
- // Make sure we discard the subsequent zeroes.
- EXPECT_TRUE(framer_.ProcessPacket(encrypted));
- EXPECT_TRUE(visitor_.coalesced_packets_.empty());
-}
-
-TEST_P(QuicFramerTest, ClientReceivesInvalidVersion) {
- if (!framer_.version().HasIetfInvariantHeader()) {
- return;
- }
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
-
- // clang-format off
- unsigned char packet[] = {
- // public flags (long header with packet type INITIAL)
- 0xC3,
- // version that is different from the framer's version
- 'Q', '0', '4', '3',
- // connection ID lengths
- 0x05,
- // source connection ID
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x01,
- // padding frame
- 0x00,
- };
- // clang-format on
-
- QuicEncryptedPacket encrypted(AsChars(packet), ABSL_ARRAYSIZE(packet), false);
- EXPECT_FALSE(framer_.ProcessPacket(encrypted));
-
- EXPECT_THAT(framer_.error(), IsError(QUIC_INVALID_VERSION));
- EXPECT_EQ("Client received unexpected version.", framer_.detailed_error());
-}
-
-TEST_P(QuicFramerTest, PacketHeaderWithVariableLengthConnectionId) {
- if (!framer_.version().AllowsVariableLengthConnectionIds()) {
- return;
- }
- SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
- uint8_t connection_id_bytes[9] = {0xFE, 0xDC, 0xBA, 0x98, 0x76,
- 0x54, 0x32, 0x10, 0x42};
- QuicConnectionId connection_id(reinterpret_cast<char*>(connection_id_bytes),
- sizeof(connection_id_bytes));
- QuicFramerPeer::SetLargestPacketNumber(&framer_, kPacketNumber - 2);
- QuicFramerPeer::SetExpectedServerConnectionIDLength(&framer_,
- connection_id.length());
-
- // clang-format off
- PacketFragments packet = {
- // type (8 byte connection_id and 1 byte packet number)
- {"Unable to read first byte.",
- {0x40}},
- // connection_id
- {"Unable to read destination connection ID.",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10, 0x42}},
- // packet number
- {"Unable to read packet number.",
- {0x78}},
- };
-
- PacketFragments packet_with_padding = {
- // type (8 byte connection_id and 1 byte packet number)
- {"Unable to read first byte.",
- {0x40}},
- // connection_id
- {"Unable to read destination connection ID.",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10, 0x42}},
- // packet number
- {"",
- {0x78}},
- // padding
- {"", {0x00, 0x00, 0x00}},
- };
- // clang-format on
-
- PacketFragments& fragments =
- framer_.version().HasHeaderProtection() ? packet_with_padding : packet;
- std::unique_ptr<QuicEncryptedPacket> encrypted(
- AssemblePacketFromFragments(fragments));
- if (framer_.version().HasHeaderProtection()) {
- EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
- EXPECT_THAT(framer_.error(), IsQuicNoError());
- } else {
- EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
- EXPECT_THAT(framer_.error(), IsError(QUIC_MISSING_PAYLOAD));
- }
- ASSERT_TRUE(visitor_.header_.get());
- EXPECT_EQ(connection_id, visitor_.header_->destination_connection_id);
- EXPECT_FALSE(visitor_.header_->reset_flag);
- EXPECT_FALSE(visitor_.header_->version_flag);
- EXPECT_EQ(PACKET_1BYTE_PACKET_NUMBER, visitor_.header_->packet_number_length);
- EXPECT_EQ(kPacketNumber, visitor_.header_->packet_number);
-
- CheckFramingBoundaries(fragments, QUIC_INVALID_PACKET_HEADER);
-}
-
-TEST_P(QuicFramerTest, MultiplePacketNumberSpaces) {
- if (!framer_.version().HasIetfInvariantHeader()) {
- return;
- }
- framer_.EnableMultiplePacketNumberSpacesSupport();
-
- // clang-format off
- unsigned char long_header_packet[] = {
- // public flags (long header with packet type ZERO_RTT_PROTECTED and
- // 4-byte packet number)
- 0xD3,
- // version
- QUIC_VERSION_BYTES,
- // destination connection ID length
- 0x50,
- // destination connection ID
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
- // padding frame
- 0x00,
- };
- unsigned char long_header_packet_ietf[] = {
- // public flags (long header with packet type ZERO_RTT_PROTECTED and
- // 4-byte packet number)
- 0xD3,
- // version
- QUIC_VERSION_BYTES,
- // destination connection ID length
- 0x08,
- // destination connection ID
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // source connection ID length
- 0x00,
- // long header packet length
- 0x05,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
- // padding frame
- 0x00,
- };
- // clang-format on
-
- if (framer_.version().KnowsWhichDecrypterToUse()) {
- framer_.InstallDecrypter(ENCRYPTION_ZERO_RTT,
- std::make_unique<TestDecrypter>());
- framer_.RemoveDecrypter(ENCRYPTION_INITIAL);
- } else {
- framer_.SetDecrypter(ENCRYPTION_ZERO_RTT,
- std::make_unique<TestDecrypter>());
- }
- if (!QuicVersionHasLongHeaderLengths(framer_.transport_version())) {
- EXPECT_TRUE(framer_.ProcessPacket(
- QuicEncryptedPacket(AsChars(long_header_packet),
- ABSL_ARRAYSIZE(long_header_packet), false)));
- } else {
- ReviseFirstByteByVersion(long_header_packet_ietf);
- EXPECT_TRUE(framer_.ProcessPacket(
- QuicEncryptedPacket(AsChars(long_header_packet_ietf),
- ABSL_ARRAYSIZE(long_header_packet_ietf), false)));
- }
-
- EXPECT_THAT(framer_.error(), IsQuicNoError());
- EXPECT_FALSE(
- QuicFramerPeer::GetLargestDecryptedPacketNumber(&framer_, INITIAL_DATA)
- .IsInitialized());
- EXPECT_FALSE(
- QuicFramerPeer::GetLargestDecryptedPacketNumber(&framer_, HANDSHAKE_DATA)
- .IsInitialized());
- EXPECT_EQ(kPacketNumber, QuicFramerPeer::GetLargestDecryptedPacketNumber(
- &framer_, APPLICATION_DATA));
-
- // clang-format off
- unsigned char short_header_packet[] = {
- // type (short header, 1 byte packet number)
- 0x40,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x79,
- // padding frame
- 0x00, 0x00, 0x00,
- };
- // clang-format on
-
- QuicEncryptedPacket short_header_encrypted(
- AsChars(short_header_packet), ABSL_ARRAYSIZE(short_header_packet), false);
- if (framer_.version().KnowsWhichDecrypterToUse()) {
- framer_.InstallDecrypter(ENCRYPTION_FORWARD_SECURE,
- std::make_unique<TestDecrypter>());
- framer_.RemoveDecrypter(ENCRYPTION_ZERO_RTT);
- } else {
- framer_.SetDecrypter(ENCRYPTION_FORWARD_SECURE,
- std::make_unique<TestDecrypter>());
- }
- EXPECT_TRUE(framer_.ProcessPacket(short_header_encrypted));
-
- EXPECT_THAT(framer_.error(), IsQuicNoError());
- EXPECT_FALSE(
- QuicFramerPeer::GetLargestDecryptedPacketNumber(&framer_, INITIAL_DATA)
- .IsInitialized());
- EXPECT_FALSE(
- QuicFramerPeer::GetLargestDecryptedPacketNumber(&framer_, HANDSHAKE_DATA)
- .IsInitialized());
- EXPECT_EQ(kPacketNumber + 1, QuicFramerPeer::GetLargestDecryptedPacketNumber(
- &framer_, APPLICATION_DATA));
-}
-
-TEST_P(QuicFramerTest, IetfRetryPacketRejected) {
- if (!framer_.version().KnowsWhichDecrypterToUse() ||
- framer_.version().SupportsRetry()) {
- return;
- }
-
- // clang-format off
- PacketFragments packet46 = {
- // public flags (IETF Retry packet, 0-length original destination CID)
- {"Unable to read first byte.",
- {0xf0}},
- // version tag
- {"Unable to read protocol version.",
- {QUIC_VERSION_BYTES}},
- // connection_id length
- {"RETRY not supported in this version.",
- {0x00}},
- };
- // clang-format on
-
- std::unique_ptr<QuicEncryptedPacket> encrypted(
- AssemblePacketFromFragments(packet46));
-
- EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
- EXPECT_THAT(framer_.error(), IsError(QUIC_INVALID_PACKET_HEADER));
- CheckFramingBoundaries(packet46, QUIC_INVALID_PACKET_HEADER);
-}
-
-TEST_P(QuicFramerTest, RetryPacketRejectedWithMultiplePacketNumberSpaces) {
- if (!framer_.version().HasIetfInvariantHeader() ||
- framer_.version().SupportsRetry()) {
- return;
- }
- framer_.EnableMultiplePacketNumberSpacesSupport();
-
- // clang-format off
- PacketFragments packet = {
- // public flags (IETF Retry packet, 0-length original destination CID)
- {"Unable to read first byte.",
- {0xf0}},
- // version tag
- {"Unable to read protocol version.",
- {QUIC_VERSION_BYTES}},
- // connection_id length
- {"RETRY not supported in this version.",
- {0x00}},
- };
- // clang-format on
-
- std::unique_ptr<QuicEncryptedPacket> encrypted(
- AssemblePacketFromFragments(packet));
-
- EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
- EXPECT_THAT(framer_.error(), IsError(QUIC_INVALID_PACKET_HEADER));
- CheckFramingBoundaries(packet, QUIC_INVALID_PACKET_HEADER);
-}
-
-TEST_P(QuicFramerTest, ProcessPublicHeaderNoVersionInferredType) {
- // The framer needs to have Perspective::IS_SERVER and configured to infer the
- // packet header type from the packet (not the version). The framer's version
- // needs to be one that uses the IETF packet format.
- if (!framer_.version().KnowsWhichDecrypterToUse()) {
- return;
- }
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
-
- // Prepare a packet that uses the Google QUIC packet header but has no version
- // field.
-
- // clang-format off
- PacketFragments packet = {
- // public flags (1-byte packet number, 8-byte connection_id, no version)
- {"Unable to read public flags.",
- {0x08}},
- // connection_id
- {"Unable to read ConnectionId.",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // packet number
- {"Unable to read packet number.",
- {0x01}},
- // padding
- {"Invalid public header type for expected version.",
- {0x00}},
- };
- // clang-format on
-
- PacketFragments& fragments = packet;
-
- std::unique_ptr<QuicEncryptedPacket> encrypted(
- AssemblePacketFromFragments(fragments));
-
- EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
- EXPECT_THAT(framer_.error(), IsError(QUIC_INVALID_PACKET_HEADER));
- EXPECT_EQ("Invalid public header type for expected version.",
- framer_.detailed_error());
- CheckFramingBoundaries(fragments, QUIC_INVALID_PACKET_HEADER);
-}
-
-TEST_P(QuicFramerTest, ProcessMismatchedHeaderVersion) {
- // The framer needs to have Perspective::IS_SERVER and configured to infer the
- // packet header type from the packet (not the version). The framer's version
- // needs to be one that uses the IETF packet format.
- if (!framer_.version().KnowsWhichDecrypterToUse()) {
- return;
- }
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
-
- // clang-format off
- PacketFragments packet = {
- // public flags (Google QUIC header with version present)
- {"Unable to read public flags.",
- {0x09}},
- // connection_id
- {"Unable to read ConnectionId.",
- {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
- // version tag
- {"Unable to read protocol version.",
- {QUIC_VERSION_BYTES}},
- // packet number
- {"Unable to read packet number.",
- {0x01}},
- };
- // clang-format on
-
- std::unique_ptr<QuicEncryptedPacket> encrypted(
- AssemblePacketFromFragments(packet));
- framer_.ProcessPacket(*encrypted);
-
- EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
- EXPECT_THAT(framer_.error(), IsError(QUIC_INVALID_PACKET_HEADER));
- EXPECT_EQ("Invalid public header type for expected version.",
- framer_.detailed_error());
- CheckFramingBoundaries(packet, QUIC_INVALID_PACKET_HEADER);
-}
-
-TEST_P(QuicFramerTest, WriteClientVersionNegotiationProbePacket) {
- // clang-format off
- static const uint8_t expected_packet[1200] = {
- // IETF long header with fixed bit set, type initial, all-0 encrypted bits.
- 0xc0,
- // Version, part of the IETF space reserved for negotiation.
- 0xca, 0xba, 0xda, 0xda,
- // Destination connection ID length 8.
- 0x08,
- // 8-byte destination connection ID.
- 0x56, 0x4e, 0x20, 0x70, 0x6c, 0x7a, 0x20, 0x21,
- // Source connection ID length 0.
- 0x00,
- // 8 bytes of zeroes followed by 8 bytes of ones to ensure that this does
- // not parse with any known version.
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- // zeroes to pad to 16 byte boundary.
- 0x00,
- // A polite greeting in case a human sees this in tcpdump.
- 0x54, 0x68, 0x69, 0x73, 0x20, 0x70, 0x61, 0x63,
- 0x6b, 0x65, 0x74, 0x20, 0x6f, 0x6e, 0x6c, 0x79,
- 0x20, 0x65, 0x78, 0x69, 0x73, 0x74, 0x73, 0x20,
- 0x74, 0x6f, 0x20, 0x74, 0x72, 0x69, 0x67, 0x67,
- 0x65, 0x72, 0x20, 0x49, 0x45, 0x54, 0x46, 0x20,
- 0x51, 0x55, 0x49, 0x43, 0x20, 0x76, 0x65, 0x72,
- 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x6e, 0x65, 0x67,
- 0x6f, 0x74, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e,
- 0x2e, 0x20, 0x50, 0x6c, 0x65, 0x61, 0x73, 0x65,
- 0x20, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x64,
- 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x61, 0x20,
- 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20,
- 0x4e, 0x65, 0x67, 0x6f, 0x74, 0x69, 0x61, 0x74,
- 0x69, 0x6f, 0x6e, 0x20, 0x70, 0x61, 0x63, 0x6b,
- 0x65, 0x74, 0x20, 0x69, 0x6e, 0x64, 0x69, 0x63,
- 0x61, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x77, 0x68,
- 0x61, 0x74, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69,
- 0x6f, 0x6e, 0x73, 0x20, 0x79, 0x6f, 0x75, 0x20,
- 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x2e,
- 0x20, 0x54, 0x68, 0x61, 0x6e, 0x6b, 0x20, 0x79,
- 0x6f, 0x75, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x68,
- 0x61, 0x76, 0x65, 0x20, 0x61, 0x20, 0x6e, 0x69,
- 0x63, 0x65, 0x20, 0x64, 0x61, 0x79, 0x2e, 0x00,
- };
- // clang-format on
- char packet[1200];
- char destination_connection_id_bytes[] = {0x56, 0x4e, 0x20, 0x70,
- 0x6c, 0x7a, 0x20, 0x21};
- EXPECT_TRUE(QuicFramer::WriteClientVersionNegotiationProbePacket(
- packet, sizeof(packet), destination_connection_id_bytes,
- sizeof(destination_connection_id_bytes)));
- quiche::test::CompareCharArraysWithHexError(
- "constructed packet", packet, sizeof(packet),
- reinterpret_cast<const char*>(expected_packet), sizeof(expected_packet));
- QuicEncryptedPacket encrypted(reinterpret_cast<const char*>(packet),
- sizeof(packet), false);
- if (!framer_.version().HasLengthPrefixedConnectionIds()) {
- // We can only parse the connection ID with a parser expecting
- // length-prefixed connection IDs.
- EXPECT_FALSE(framer_.ProcessPacket(encrypted));
- return;
- }
- EXPECT_TRUE(framer_.ProcessPacket(encrypted));
- ASSERT_TRUE(visitor_.header_.get());
- QuicConnectionId probe_payload_connection_id(
- reinterpret_cast<const char*>(destination_connection_id_bytes),
- sizeof(destination_connection_id_bytes));
- EXPECT_EQ(probe_payload_connection_id,
- visitor_.header_.get()->destination_connection_id);
-}
-
-TEST_P(QuicFramerTest, DispatcherParseOldClientVersionNegotiationProbePacket) {
- // clang-format off
- static const uint8_t packet[1200] = {
- // IETF long header with fixed bit set, type initial, all-0 encrypted bits.
- 0xc0,
- // Version, part of the IETF space reserved for negotiation.
- 0xca, 0xba, 0xda, 0xba,
- // Destination connection ID length 8, source connection ID length 0.
- 0x50,
- // 8-byte destination connection ID.
- 0x56, 0x4e, 0x20, 0x70, 0x6c, 0x7a, 0x20, 0x21,
- // 8 bytes of zeroes followed by 8 bytes of ones to ensure that this does
- // not parse with any known version.
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- // 2 bytes of zeroes to pad to 16 byte boundary.
- 0x00, 0x00,
- // A polite greeting in case a human sees this in tcpdump.
- 0x54, 0x68, 0x69, 0x73, 0x20, 0x70, 0x61, 0x63,
- 0x6b, 0x65, 0x74, 0x20, 0x6f, 0x6e, 0x6c, 0x79,
- 0x20, 0x65, 0x78, 0x69, 0x73, 0x74, 0x73, 0x20,
- 0x74, 0x6f, 0x20, 0x74, 0x72, 0x69, 0x67, 0x67,
- 0x65, 0x72, 0x20, 0x49, 0x45, 0x54, 0x46, 0x20,
- 0x51, 0x55, 0x49, 0x43, 0x20, 0x76, 0x65, 0x72,
- 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x6e, 0x65, 0x67,
- 0x6f, 0x74, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e,
- 0x2e, 0x20, 0x50, 0x6c, 0x65, 0x61, 0x73, 0x65,
- 0x20, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x64,
- 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x61, 0x20,
- 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20,
- 0x4e, 0x65, 0x67, 0x6f, 0x74, 0x69, 0x61, 0x74,
- 0x69, 0x6f, 0x6e, 0x20, 0x70, 0x61, 0x63, 0x6b,
- 0x65, 0x74, 0x20, 0x69, 0x6e, 0x64, 0x69, 0x63,
- 0x61, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x77, 0x68,
- 0x61, 0x74, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69,
- 0x6f, 0x6e, 0x73, 0x20, 0x79, 0x6f, 0x75, 0x20,
- 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x2e,
- 0x20, 0x54, 0x68, 0x61, 0x6e, 0x6b, 0x20, 0x79,
- 0x6f, 0x75, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x68,
- 0x61, 0x76, 0x65, 0x20, 0x61, 0x20, 0x6e, 0x69,
- 0x63, 0x65, 0x20, 0x64, 0x61, 0x79, 0x2e, 0x00,
- };
- // clang-format on
- char expected_destination_connection_id_bytes[] = {0x56, 0x4e, 0x20, 0x70,
- 0x6c, 0x7a, 0x20, 0x21};
- QuicConnectionId expected_destination_connection_id(
- reinterpret_cast<const char*>(expected_destination_connection_id_bytes),
- sizeof(expected_destination_connection_id_bytes));
-
- QuicEncryptedPacket encrypted(reinterpret_cast<const char*>(packet),
- sizeof(packet));
- PacketHeaderFormat format = GOOGLE_QUIC_PACKET;
- QuicLongHeaderType long_packet_type = INVALID_PACKET_TYPE;
- bool version_present = false, has_length_prefix = true;
- QuicVersionLabel version_label = 33;
- ParsedQuicVersion parsed_version = UnsupportedQuicVersion();
- QuicConnectionId destination_connection_id = TestConnectionId(1);
- QuicConnectionId source_connection_id = TestConnectionId(2);
- absl::optional<absl::string_view> retry_token;
- std::string detailed_error = "foobar";
- QuicErrorCode header_parse_result = QuicFramer::ParsePublicHeaderDispatcher(
- encrypted, kQuicDefaultConnectionIdLength, &format, &long_packet_type,
- &version_present, &has_length_prefix, &version_label, &parsed_version,
- &destination_connection_id, &source_connection_id, &retry_token,
- &detailed_error);
- EXPECT_THAT(header_parse_result, IsQuicNoError());
- EXPECT_EQ(IETF_QUIC_LONG_HEADER_PACKET, format);
- EXPECT_TRUE(version_present);
- EXPECT_FALSE(has_length_prefix);
- EXPECT_EQ(0xcabadaba, version_label);
- EXPECT_EQ(expected_destination_connection_id, destination_connection_id);
- EXPECT_EQ(EmptyQuicConnectionId(), source_connection_id);
- EXPECT_FALSE(retry_token.has_value());
- EXPECT_EQ("", detailed_error);
-}
-
-TEST_P(QuicFramerTest, DispatcherParseClientVersionNegotiationProbePacket) {
- // clang-format off
- static const uint8_t packet[1200] = {
- // IETF long header with fixed bit set, type initial, all-0 encrypted bits.
- 0xc0,
- // Version, part of the IETF space reserved for negotiation.
- 0xca, 0xba, 0xda, 0xba,
- // Destination connection ID length 8.
- 0x08,
- // 8-byte destination connection ID.
- 0x56, 0x4e, 0x20, 0x70, 0x6c, 0x7a, 0x20, 0x21,
- // Source connection ID length 0.
- 0x00,
- // 8 bytes of zeroes followed by 8 bytes of ones to ensure that this does
- // not parse with any known version.
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- // 1 byte of zeroes to pad to 16 byte boundary.
- 0x00,
- // A polite greeting in case a human sees this in tcpdump.
- 0x54, 0x68, 0x69, 0x73, 0x20, 0x70, 0x61, 0x63,
- 0x6b, 0x65, 0x74, 0x20, 0x6f, 0x6e, 0x6c, 0x79,
- 0x20, 0x65, 0x78, 0x69, 0x73, 0x74, 0x73, 0x20,
- 0x74, 0x6f, 0x20, 0x74, 0x72, 0x69, 0x67, 0x67,
- 0x65, 0x72, 0x20, 0x49, 0x45, 0x54, 0x46, 0x20,
- 0x51, 0x55, 0x49, 0x43, 0x20, 0x76, 0x65, 0x72,
- 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x6e, 0x65, 0x67,
- 0x6f, 0x74, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e,
- 0x2e, 0x20, 0x50, 0x6c, 0x65, 0x61, 0x73, 0x65,
- 0x20, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x64,
- 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x61, 0x20,
- 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20,
- 0x4e, 0x65, 0x67, 0x6f, 0x74, 0x69, 0x61, 0x74,
- 0x69, 0x6f, 0x6e, 0x20, 0x70, 0x61, 0x63, 0x6b,
- 0x65, 0x74, 0x20, 0x69, 0x6e, 0x64, 0x69, 0x63,
- 0x61, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x77, 0x68,
- 0x61, 0x74, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69,
- 0x6f, 0x6e, 0x73, 0x20, 0x79, 0x6f, 0x75, 0x20,
- 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x2e,
- 0x20, 0x54, 0x68, 0x61, 0x6e, 0x6b, 0x20, 0x79,
- 0x6f, 0x75, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x68,
- 0x61, 0x76, 0x65, 0x20, 0x61, 0x20, 0x6e, 0x69,
- 0x63, 0x65, 0x20, 0x64, 0x61, 0x79, 0x2e, 0x00,
- };
- // clang-format on
- char expected_destination_connection_id_bytes[] = {0x56, 0x4e, 0x20, 0x70,
- 0x6c, 0x7a, 0x20, 0x21};
- QuicConnectionId expected_destination_connection_id(
- reinterpret_cast<const char*>(expected_destination_connection_id_bytes),
- sizeof(expected_destination_connection_id_bytes));
-
- QuicEncryptedPacket encrypted(reinterpret_cast<const char*>(packet),
- sizeof(packet));
- PacketHeaderFormat format = GOOGLE_QUIC_PACKET;
- QuicLongHeaderType long_packet_type = INVALID_PACKET_TYPE;
- bool version_present = false, has_length_prefix = false;
- QuicVersionLabel version_label = 33;
- ParsedQuicVersion parsed_version = UnsupportedQuicVersion();
- QuicConnectionId destination_connection_id = TestConnectionId(1);
- QuicConnectionId source_connection_id = TestConnectionId(2);
- absl::optional<absl::string_view> retry_token;
- std::string detailed_error = "foobar";
- QuicErrorCode header_parse_result = QuicFramer::ParsePublicHeaderDispatcher(
- encrypted, kQuicDefaultConnectionIdLength, &format, &long_packet_type,
- &version_present, &has_length_prefix, &version_label, &parsed_version,
- &destination_connection_id, &source_connection_id, &retry_token,
- &detailed_error);
- EXPECT_THAT(header_parse_result, IsQuicNoError());
- EXPECT_EQ(IETF_QUIC_LONG_HEADER_PACKET, format);
- EXPECT_TRUE(version_present);
- EXPECT_TRUE(has_length_prefix);
- EXPECT_EQ(0xcabadaba, version_label);
- EXPECT_EQ(expected_destination_connection_id, destination_connection_id);
- EXPECT_EQ(EmptyQuicConnectionId(), source_connection_id);
- EXPECT_EQ("", detailed_error);
-}
-
-TEST_P(QuicFramerTest, ParseServerVersionNegotiationProbeResponse) {
- // clang-format off
- const uint8_t packet[] = {
- // IETF long header with fixed bit set, type initial, all-0 encrypted bits.
- 0xc0,
- // Version of 0, indicating version negotiation.
- 0x00, 0x00, 0x00, 0x00,
- // Destination connection ID length 0, source connection ID length 8.
- 0x00, 0x08,
- // 8-byte source connection ID.
- 0x56, 0x4e, 0x20, 0x70, 0x6c, 0x7a, 0x20, 0x21,
- // A few supported versions.
- 0xaa, 0xaa, 0xaa, 0xaa,
- QUIC_VERSION_BYTES,
- };
- // clang-format on
- char probe_payload_bytes[] = {0x56, 0x4e, 0x20, 0x70, 0x6c, 0x7a, 0x20, 0x21};
- char parsed_probe_payload_bytes[255] = {};
- uint8_t parsed_probe_payload_length = sizeof(parsed_probe_payload_bytes);
- std::string parse_detailed_error = "";
- EXPECT_TRUE(QuicFramer::ParseServerVersionNegotiationProbeResponse(
- reinterpret_cast<const char*>(packet), sizeof(packet),
- reinterpret_cast<char*>(parsed_probe_payload_bytes),
- &parsed_probe_payload_length, &parse_detailed_error));
- EXPECT_EQ("", parse_detailed_error);
- quiche::test::CompareCharArraysWithHexError(
- "parsed probe", parsed_probe_payload_bytes, parsed_probe_payload_length,
- probe_payload_bytes, sizeof(probe_payload_bytes));
-}
-
-TEST_P(QuicFramerTest, ParseClientVersionNegotiationProbePacket) {
- char packet[1200];
- char input_destination_connection_id_bytes[] = {0x56, 0x4e, 0x20, 0x70,
- 0x6c, 0x7a, 0x20, 0x21};
- ASSERT_TRUE(QuicFramer::WriteClientVersionNegotiationProbePacket(
- packet, sizeof(packet), input_destination_connection_id_bytes,
- sizeof(input_destination_connection_id_bytes)));
- char parsed_destination_connection_id_bytes[255] = {0};
- uint8_t parsed_destination_connection_id_length =
- sizeof(parsed_destination_connection_id_bytes);
- ASSERT_TRUE(ParseClientVersionNegotiationProbePacket(
- packet, sizeof(packet), parsed_destination_connection_id_bytes,
- &parsed_destination_connection_id_length));
- quiche::test::CompareCharArraysWithHexError(
- "parsed destination connection ID",
- parsed_destination_connection_id_bytes,
- parsed_destination_connection_id_length,
- input_destination_connection_id_bytes,
- sizeof(input_destination_connection_id_bytes));
-}
-
-TEST_P(QuicFramerTest, WriteServerVersionNegotiationProbeResponse) {
- char packet[1200];
- size_t packet_length = sizeof(packet);
- char input_source_connection_id_bytes[] = {0x56, 0x4e, 0x20, 0x70,
- 0x6c, 0x7a, 0x20, 0x21};
- ASSERT_TRUE(WriteServerVersionNegotiationProbeResponse(
- packet, &packet_length, input_source_connection_id_bytes,
- sizeof(input_source_connection_id_bytes)));
- char parsed_source_connection_id_bytes[255] = {0};
- uint8_t parsed_source_connection_id_length =
- sizeof(parsed_source_connection_id_bytes);
- std::string detailed_error;
- ASSERT_TRUE(QuicFramer::ParseServerVersionNegotiationProbeResponse(
- packet, packet_length, parsed_source_connection_id_bytes,
- &parsed_source_connection_id_length, &detailed_error))
- << detailed_error;
- quiche::test::CompareCharArraysWithHexError(
- "parsed destination connection ID", parsed_source_connection_id_bytes,
- parsed_source_connection_id_length, input_source_connection_id_bytes,
- sizeof(input_source_connection_id_bytes));
-}
-
-TEST_P(QuicFramerTest, ClientConnectionIdFromLongHeaderToClient) {
- if (!framer_.version().HasIetfInvariantHeader()) {
- // This test requires an IETF long header.
- return;
- }
- SetDecrypterLevel(ENCRYPTION_HANDSHAKE);
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
- // clang-format off
- unsigned char packet[] = {
- // public flags (long header with packet type HANDSHAKE and
- // 4-byte packet number)
- 0xE3,
- // version
- QUIC_VERSION_BYTES,
- // connection ID lengths
- 0x50,
- // destination connection ID
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // long header packet length
- 0x05,
- // packet number
- 0x12, 0x34, 0x56, 0x00,
- // padding frame
- 0x00,
- };
- unsigned char packet49[] = {
- // public flags (long header with packet type HANDSHAKE and
- // 4-byte packet number)
- 0xE3,
- // version
- QUIC_VERSION_BYTES,
- // destination connection ID length
- 0x08,
- // destination connection ID
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // source connection ID length
- 0x00,
- // long header packet length
- 0x05,
- // packet number
- 0x12, 0x34, 0x56, 0x00,
- // padding frame
- 0x00,
- };
- // clang-format on
-
- unsigned char* p = packet;
- size_t p_length = ABSL_ARRAYSIZE(packet);
- if (framer_.version().HasLongHeaderLengths()) {
- ReviseFirstByteByVersion(packet49);
- p = packet49;
- p_length = ABSL_ARRAYSIZE(packet49);
- }
- const bool parse_success =
- framer_.ProcessPacket(QuicEncryptedPacket(AsChars(p), p_length, false));
- if (!framer_.version().AllowsVariableLengthConnectionIds()) {
- EXPECT_FALSE(parse_success);
- EXPECT_THAT(framer_.error(), IsError(QUIC_INVALID_PACKET_HEADER));
- EXPECT_EQ("Invalid ConnectionId length.", framer_.detailed_error());
- return;
- }
- EXPECT_TRUE(parse_success);
- EXPECT_THAT(framer_.error(), IsQuicNoError());
- EXPECT_EQ("", framer_.detailed_error());
- ASSERT_TRUE(visitor_.header_.get());
- EXPECT_EQ(FramerTestConnectionId(),
- visitor_.header_.get()->destination_connection_id);
-}
-
-TEST_P(QuicFramerTest, ClientConnectionIdFromLongHeaderToServer) {
- if (!framer_.version().HasIetfInvariantHeader()) {
- // This test requires an IETF long header.
- return;
- }
- SetDecrypterLevel(ENCRYPTION_HANDSHAKE);
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
- // clang-format off
- unsigned char packet[] = {
- // public flags (long header with packet type HANDSHAKE and
- // 4-byte packet number)
- 0xE3,
- // version
- QUIC_VERSION_BYTES,
- // connection ID lengths
- 0x05,
- // source connection ID
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // long header packet length
- 0x05,
- // packet number
- 0x12, 0x34, 0x56, 0x00,
- // padding frame
- 0x00,
- };
- unsigned char packet49[] = {
- // public flags (long header with packet type HANDSHAKE and
- // 4-byte packet number)
- 0xE3,
- // version
- QUIC_VERSION_BYTES,
- // connection ID lengths
- 0x00, 0x08,
- // source connection ID
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // long header packet length
- 0x05,
- // packet number
- 0x12, 0x34, 0x56, 0x00,
- // padding frame
- 0x00,
- };
- // clang-format on
- unsigned char* p = packet;
- size_t p_length = ABSL_ARRAYSIZE(packet);
- if (framer_.version().HasLongHeaderLengths()) {
- ReviseFirstByteByVersion(packet49);
- p = packet49;
- p_length = ABSL_ARRAYSIZE(packet49);
- }
- const bool parse_success =
- framer_.ProcessPacket(QuicEncryptedPacket(AsChars(p), p_length, false));
- if (!framer_.version().AllowsVariableLengthConnectionIds()) {
- EXPECT_FALSE(parse_success);
- EXPECT_THAT(framer_.error(), IsError(QUIC_INVALID_PACKET_HEADER));
- EXPECT_EQ("Invalid ConnectionId length.", framer_.detailed_error());
- return;
- }
- if (!framer_.version().SupportsClientConnectionIds()) {
- EXPECT_FALSE(parse_success);
- EXPECT_THAT(framer_.error(), IsError(QUIC_INVALID_PACKET_HEADER));
- EXPECT_EQ("Client connection ID not supported in this version.",
- framer_.detailed_error());
- return;
- }
- EXPECT_TRUE(parse_success);
- EXPECT_THAT(framer_.error(), IsQuicNoError());
- EXPECT_EQ("", framer_.detailed_error());
- ASSERT_TRUE(visitor_.header_.get());
- EXPECT_EQ(FramerTestConnectionId(),
- visitor_.header_.get()->source_connection_id);
-}
-
-TEST_P(QuicFramerTest, ProcessAndValidateIetfConnectionIdLengthClient) {
- if (!framer_.version().HasIetfInvariantHeader()) {
- // This test requires an IETF long header.
- return;
- }
- char connection_id_lengths = 0x05;
- QuicDataReader reader(&connection_id_lengths, 1);
-
- bool should_update_expected_server_connection_id_length = false;
- uint8_t expected_server_connection_id_length = 8;
- uint8_t destination_connection_id_length = 0;
- uint8_t source_connection_id_length = 8;
- std::string detailed_error = "";
-
- EXPECT_TRUE(QuicFramerPeer::ProcessAndValidateIetfConnectionIdLength(
- &reader, framer_.version(), Perspective::IS_CLIENT,
- should_update_expected_server_connection_id_length,
- &expected_server_connection_id_length, &destination_connection_id_length,
- &source_connection_id_length, &detailed_error));
- EXPECT_EQ(8, expected_server_connection_id_length);
- EXPECT_EQ(0, destination_connection_id_length);
- EXPECT_EQ(8, source_connection_id_length);
- EXPECT_EQ("", detailed_error);
-
- QuicDataReader reader2(&connection_id_lengths, 1);
- should_update_expected_server_connection_id_length = true;
- expected_server_connection_id_length = 33;
- EXPECT_TRUE(QuicFramerPeer::ProcessAndValidateIetfConnectionIdLength(
- &reader2, framer_.version(), Perspective::IS_CLIENT,
- should_update_expected_server_connection_id_length,
- &expected_server_connection_id_length, &destination_connection_id_length,
- &source_connection_id_length, &detailed_error));
- EXPECT_EQ(8, expected_server_connection_id_length);
- EXPECT_EQ(0, destination_connection_id_length);
- EXPECT_EQ(8, source_connection_id_length);
- EXPECT_EQ("", detailed_error);
-}
-
-TEST_P(QuicFramerTest, ProcessAndValidateIetfConnectionIdLengthServer) {
- if (!framer_.version().HasIetfInvariantHeader()) {
- // This test requires an IETF long header.
- return;
- }
- char connection_id_lengths = 0x50;
- QuicDataReader reader(&connection_id_lengths, 1);
-
- bool should_update_expected_server_connection_id_length = false;
- uint8_t expected_server_connection_id_length = 8;
- uint8_t destination_connection_id_length = 8;
- uint8_t source_connection_id_length = 0;
- std::string detailed_error = "";
-
- EXPECT_TRUE(QuicFramerPeer::ProcessAndValidateIetfConnectionIdLength(
- &reader, framer_.version(), Perspective::IS_SERVER,
- should_update_expected_server_connection_id_length,
- &expected_server_connection_id_length, &destination_connection_id_length,
- &source_connection_id_length, &detailed_error));
- EXPECT_EQ(8, expected_server_connection_id_length);
- EXPECT_EQ(8, destination_connection_id_length);
- EXPECT_EQ(0, source_connection_id_length);
- EXPECT_EQ("", detailed_error);
-
- QuicDataReader reader2(&connection_id_lengths, 1);
- should_update_expected_server_connection_id_length = true;
- expected_server_connection_id_length = 33;
- EXPECT_TRUE(QuicFramerPeer::ProcessAndValidateIetfConnectionIdLength(
- &reader2, framer_.version(), Perspective::IS_SERVER,
- should_update_expected_server_connection_id_length,
- &expected_server_connection_id_length, &destination_connection_id_length,
- &source_connection_id_length, &detailed_error));
- EXPECT_EQ(8, expected_server_connection_id_length);
- EXPECT_EQ(8, destination_connection_id_length);
- EXPECT_EQ(0, source_connection_id_length);
- EXPECT_EQ("", detailed_error);
-}
-
-TEST_P(QuicFramerTest, TestExtendedErrorCodeParser) {
- if (VersionHasIetfQuicFrames(framer_.transport_version())) {
- // Extended error codes only in IETF QUIC
- return;
- }
- QuicConnectionCloseFrame frame;
-
- frame.error_details = "this has no error code info in it";
- MaybeExtractQuicErrorCode(&frame);
- EXPECT_THAT(frame.quic_error_code, IsError(QUIC_IETF_GQUIC_ERROR_MISSING));
- EXPECT_EQ("this has no error code info in it", frame.error_details);
-
- frame.error_details = "1234this does not have the colon in it";
- MaybeExtractQuicErrorCode(&frame);
- EXPECT_THAT(frame.quic_error_code, IsError(QUIC_IETF_GQUIC_ERROR_MISSING));
- EXPECT_EQ("1234this does not have the colon in it", frame.error_details);
-
- frame.error_details = "1a234:this has a colon, but a malformed error number";
- MaybeExtractQuicErrorCode(&frame);
- EXPECT_THAT(frame.quic_error_code, IsError(QUIC_IETF_GQUIC_ERROR_MISSING));
- EXPECT_EQ("1a234:this has a colon, but a malformed error number",
- frame.error_details);
-
- frame.error_details = "1234:this is good";
- MaybeExtractQuicErrorCode(&frame);
- EXPECT_EQ(1234u, frame.quic_error_code);
- EXPECT_EQ("this is good", frame.error_details);
-
- frame.error_details =
- "1234 :this is not good, space between last digit and colon";
- MaybeExtractQuicErrorCode(&frame);
- EXPECT_THAT(frame.quic_error_code, IsError(QUIC_IETF_GQUIC_ERROR_MISSING));
- EXPECT_EQ("1234 :this is not good, space between last digit and colon",
- frame.error_details);
-
- frame.error_details = "123456789";
- MaybeExtractQuicErrorCode(&frame);
- EXPECT_THAT(
- frame.quic_error_code,
- IsError(QUIC_IETF_GQUIC_ERROR_MISSING)); // Not good, all numbers, no :
- EXPECT_EQ("123456789", frame.error_details);
-
- frame.error_details = "1234:";
- MaybeExtractQuicErrorCode(&frame);
- EXPECT_EQ(1234u,
- frame.quic_error_code); // corner case.
- EXPECT_EQ("", frame.error_details);
-
- frame.error_details = "1234:5678";
- MaybeExtractQuicErrorCode(&frame);
- EXPECT_EQ(1234u,
- frame.quic_error_code); // another corner case.
- EXPECT_EQ("5678", frame.error_details);
-
- frame.error_details = "12345 6789:";
- MaybeExtractQuicErrorCode(&frame);
- EXPECT_THAT(frame.quic_error_code,
- IsError(QUIC_IETF_GQUIC_ERROR_MISSING)); // Not good
- EXPECT_EQ("12345 6789:", frame.error_details);
-
- frame.error_details = ":no numbers, is not good";
- MaybeExtractQuicErrorCode(&frame);
- EXPECT_THAT(frame.quic_error_code, IsError(QUIC_IETF_GQUIC_ERROR_MISSING));
- EXPECT_EQ(":no numbers, is not good", frame.error_details);
-
- frame.error_details = "qwer:also no numbers, is not good";
- MaybeExtractQuicErrorCode(&frame);
- EXPECT_THAT(frame.quic_error_code, IsError(QUIC_IETF_GQUIC_ERROR_MISSING));
- EXPECT_EQ("qwer:also no numbers, is not good", frame.error_details);
-
- frame.error_details = " 1234:this is not good, space before first digit";
- MaybeExtractQuicErrorCode(&frame);
- EXPECT_THAT(frame.quic_error_code, IsError(QUIC_IETF_GQUIC_ERROR_MISSING));
- EXPECT_EQ(" 1234:this is not good, space before first digit",
- frame.error_details);
-
- frame.error_details = "1234:";
- MaybeExtractQuicErrorCode(&frame);
- EXPECT_EQ(1234u,
- frame.quic_error_code); // this is good
- EXPECT_EQ("", frame.error_details);
-}
-
-// Regression test for crbug/1029636.
-TEST_P(QuicFramerTest, OverlyLargeAckDelay) {
- if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
- return;
- }
- SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
- // clang-format off
- unsigned char packet_ietf[] = {
- // type (short header, 4 byte packet number)
- 0x43,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
-
- // frame type (IETF_ACK frame)
- 0x02,
- // largest acked
- kVarInt62FourBytes + 0x12, 0x34, 0x56, 0x78,
- // ack delay time.
- kVarInt62EightBytes + 0x31, 0x00, 0x00, 0x00, 0xF3, 0xA0, 0x81, 0xE0,
- // Nr. of additional ack blocks
- kVarInt62OneByte + 0x00,
- // first ack block length.
- kVarInt62FourBytes + 0x12, 0x34, 0x56, 0x77,
- };
- // clang-format on
-
- framer_.ProcessPacket(QuicEncryptedPacket(
- AsChars(packet_ietf), ABSL_ARRAYSIZE(packet_ietf), false));
- ASSERT_EQ(1u, visitor_.ack_frames_.size());
- // Verify ack_delay_time is set correctly.
- EXPECT_EQ(QuicTime::Delta::Infinite(),
- visitor_.ack_frames_[0]->ack_delay_time);
-}
-
-TEST_P(QuicFramerTest, KeyUpdate) {
- if (!framer_.version().UsesTls()) {
- // Key update is only used in QUIC+TLS.
- return;
- }
- ASSERT_TRUE(framer_.version().KnowsWhichDecrypterToUse());
- // Doesn't use SetDecrypterLevel since we want to use StrictTaggingDecrypter
- // instead of TestDecrypter.
- framer_.InstallDecrypter(ENCRYPTION_FORWARD_SECURE,
- std::make_unique<StrictTaggingDecrypter>(/*key=*/0));
- framer_.SetKeyUpdateSupportForConnection(true);
-
- QuicPacketHeader header;
- header.destination_connection_id = FramerTestConnectionId();
- header.reset_flag = false;
- header.version_flag = false;
- header.packet_number = kPacketNumber;
-
- QuicFrames frames = {QuicFrame(QuicPaddingFrame())};
-
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
- std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
- ASSERT_TRUE(data != nullptr);
- std::unique_ptr<QuicEncryptedPacket> encrypted(
- EncryptPacketWithTagAndPhase(*data, 0, false));
- ASSERT_TRUE(encrypted);
-
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
- EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
- // Processed valid packet with phase=0, key=1: no key update.
- EXPECT_EQ(0u, visitor_.key_update_count());
- EXPECT_EQ(0, visitor_.derive_next_key_count_);
- EXPECT_EQ(1, visitor_.decrypted_first_packet_in_key_phase_count_);
-
- header.packet_number += 1;
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
- data = BuildDataPacket(header, frames);
- ASSERT_TRUE(data != nullptr);
- encrypted = EncryptPacketWithTagAndPhase(*data, 1, true);
- ASSERT_TRUE(encrypted);
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
- EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
- // Processed valid packet with phase=1, key=2: key update should have
- // occurred.
- ASSERT_EQ(1u, visitor_.key_update_count());
- EXPECT_EQ(KeyUpdateReason::kRemote, visitor_.key_update_reasons_[0]);
- EXPECT_EQ(1, visitor_.derive_next_key_count_);
- EXPECT_EQ(2, visitor_.decrypted_first_packet_in_key_phase_count_);
-
- header.packet_number += 1;
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
- data = BuildDataPacket(header, frames);
- ASSERT_TRUE(data != nullptr);
- encrypted = EncryptPacketWithTagAndPhase(*data, 1, true);
- ASSERT_TRUE(encrypted);
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
- EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
- // Processed another valid packet with phase=1, key=2: no key update.
- EXPECT_EQ(1u, visitor_.key_update_count());
- EXPECT_EQ(1, visitor_.derive_next_key_count_);
- EXPECT_EQ(2, visitor_.decrypted_first_packet_in_key_phase_count_);
-
- // Process another key update.
- header.packet_number += 1;
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
- data = BuildDataPacket(header, frames);
- ASSERT_TRUE(data != nullptr);
- encrypted = EncryptPacketWithTagAndPhase(*data, 2, false);
- ASSERT_TRUE(encrypted);
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
- EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
- ASSERT_EQ(2u, visitor_.key_update_count());
- EXPECT_EQ(KeyUpdateReason::kRemote, visitor_.key_update_reasons_[1]);
- EXPECT_EQ(2, visitor_.derive_next_key_count_);
- EXPECT_EQ(3, visitor_.decrypted_first_packet_in_key_phase_count_);
-}
-
-TEST_P(QuicFramerTest, KeyUpdateOldPacketAfterUpdate) {
- if (!framer_.version().UsesTls()) {
- // Key update is only used in QUIC+TLS.
- return;
- }
- ASSERT_TRUE(framer_.version().KnowsWhichDecrypterToUse());
- // Doesn't use SetDecrypterLevel since we want to use StrictTaggingDecrypter
- // instead of TestDecrypter.
- framer_.InstallDecrypter(ENCRYPTION_FORWARD_SECURE,
- std::make_unique<StrictTaggingDecrypter>(/*key=*/0));
- framer_.SetKeyUpdateSupportForConnection(true);
-
- QuicPacketHeader header;
- header.destination_connection_id = FramerTestConnectionId();
- header.reset_flag = false;
- header.version_flag = false;
- header.packet_number = kPacketNumber;
-
- QuicFrames frames = {QuicFrame(QuicPaddingFrame())};
-
- // Process packet N with phase 0.
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
- std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
- ASSERT_TRUE(data != nullptr);
- std::unique_ptr<QuicEncryptedPacket> encrypted(
- EncryptPacketWithTagAndPhase(*data, 0, false));
- ASSERT_TRUE(encrypted);
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
- EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
- EXPECT_EQ(0u, visitor_.key_update_count());
- EXPECT_EQ(0, visitor_.derive_next_key_count_);
- EXPECT_EQ(1, visitor_.decrypted_first_packet_in_key_phase_count_);
-
- // Process packet N+2 with phase 1.
- header.packet_number = kPacketNumber + 2;
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
- data = BuildDataPacket(header, frames);
- ASSERT_TRUE(data != nullptr);
- encrypted = EncryptPacketWithTagAndPhase(*data, 1, true);
- ASSERT_TRUE(encrypted);
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
- EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
- EXPECT_EQ(1u, visitor_.key_update_count());
- EXPECT_EQ(1, visitor_.derive_next_key_count_);
- EXPECT_EQ(2, visitor_.decrypted_first_packet_in_key_phase_count_);
-
- // Process packet N+1 with phase 0. (Receiving packet from previous phase
- // after packet from new phase was received.)
- header.packet_number = kPacketNumber + 1;
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
- data = BuildDataPacket(header, frames);
- ASSERT_TRUE(data != nullptr);
- encrypted = EncryptPacketWithTagAndPhase(*data, 0, false);
- ASSERT_TRUE(encrypted);
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
- // Packet should decrypt and key update count should not change.
- EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
- EXPECT_EQ(1u, visitor_.key_update_count());
- EXPECT_EQ(1, visitor_.derive_next_key_count_);
- EXPECT_EQ(2, visitor_.decrypted_first_packet_in_key_phase_count_);
-}
-
-TEST_P(QuicFramerTest, KeyUpdateOldPacketAfterDiscardPreviousOneRttKeys) {
- if (!framer_.version().UsesTls()) {
- // Key update is only used in QUIC+TLS.
- return;
- }
- ASSERT_TRUE(framer_.version().KnowsWhichDecrypterToUse());
- // Doesn't use SetDecrypterLevel since we want to use StrictTaggingDecrypter
- // instead of TestDecrypter.
- framer_.InstallDecrypter(ENCRYPTION_FORWARD_SECURE,
- std::make_unique<StrictTaggingDecrypter>(/*key=*/0));
- framer_.SetKeyUpdateSupportForConnection(true);
-
- QuicPacketHeader header;
- header.destination_connection_id = FramerTestConnectionId();
- header.reset_flag = false;
- header.version_flag = false;
- header.packet_number = kPacketNumber;
-
- QuicFrames frames = {QuicFrame(QuicPaddingFrame())};
-
- // Process packet N with phase 0.
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
- std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
- ASSERT_TRUE(data != nullptr);
- std::unique_ptr<QuicEncryptedPacket> encrypted(
- EncryptPacketWithTagAndPhase(*data, 0, false));
- ASSERT_TRUE(encrypted);
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
- EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
- EXPECT_EQ(0u, visitor_.key_update_count());
- EXPECT_EQ(0, visitor_.derive_next_key_count_);
- EXPECT_EQ(1, visitor_.decrypted_first_packet_in_key_phase_count_);
-
- // Process packet N+2 with phase 1.
- header.packet_number = kPacketNumber + 2;
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
- data = BuildDataPacket(header, frames);
- ASSERT_TRUE(data != nullptr);
- encrypted = EncryptPacketWithTagAndPhase(*data, 1, true);
- ASSERT_TRUE(encrypted);
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
- EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
- EXPECT_EQ(1u, visitor_.key_update_count());
- EXPECT_EQ(1, visitor_.derive_next_key_count_);
- EXPECT_EQ(2, visitor_.decrypted_first_packet_in_key_phase_count_);
-
- // Discard keys for previous key phase.
- framer_.DiscardPreviousOneRttKeys();
-
- // Process packet N+1 with phase 0. (Receiving packet from previous phase
- // after packet from new phase was received.)
- header.packet_number = kPacketNumber + 1;
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
- data = BuildDataPacket(header, frames);
- ASSERT_TRUE(data != nullptr);
- encrypted = EncryptPacketWithTagAndPhase(*data, 0, false);
- ASSERT_TRUE(encrypted);
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
- // Packet should not decrypt and key update count should not change.
- EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
- EXPECT_EQ(1u, visitor_.key_update_count());
- EXPECT_EQ(1, visitor_.derive_next_key_count_);
- EXPECT_EQ(2, visitor_.decrypted_first_packet_in_key_phase_count_);
-}
-
-TEST_P(QuicFramerTest, KeyUpdatePacketsOutOfOrder) {
- if (!framer_.version().UsesTls()) {
- // Key update is only used in QUIC+TLS.
- return;
- }
- ASSERT_TRUE(framer_.version().KnowsWhichDecrypterToUse());
- // Doesn't use SetDecrypterLevel since we want to use StrictTaggingDecrypter
- // instead of TestDecrypter.
- framer_.InstallDecrypter(ENCRYPTION_FORWARD_SECURE,
- std::make_unique<StrictTaggingDecrypter>(/*key=*/0));
- framer_.SetKeyUpdateSupportForConnection(true);
-
- QuicPacketHeader header;
- header.destination_connection_id = FramerTestConnectionId();
- header.reset_flag = false;
- header.version_flag = false;
- header.packet_number = kPacketNumber;
-
- QuicFrames frames = {QuicFrame(QuicPaddingFrame())};
-
- // Process packet N with phase 0.
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
- std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
- ASSERT_TRUE(data != nullptr);
- std::unique_ptr<QuicEncryptedPacket> encrypted(
- EncryptPacketWithTagAndPhase(*data, 0, false));
- ASSERT_TRUE(encrypted);
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
- EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
- EXPECT_EQ(0u, visitor_.key_update_count());
- EXPECT_EQ(0, visitor_.derive_next_key_count_);
- EXPECT_EQ(1, visitor_.decrypted_first_packet_in_key_phase_count_);
-
- // Process packet N+2 with phase 1.
- header.packet_number = kPacketNumber + 2;
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
- data = BuildDataPacket(header, frames);
- ASSERT_TRUE(data != nullptr);
- encrypted = EncryptPacketWithTagAndPhase(*data, 1, true);
- ASSERT_TRUE(encrypted);
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
- EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
- EXPECT_EQ(1u, visitor_.key_update_count());
- EXPECT_EQ(1, visitor_.derive_next_key_count_);
- EXPECT_EQ(2, visitor_.decrypted_first_packet_in_key_phase_count_);
-
- // Process packet N+1 with phase 1. (Receiving packet from new phase out of
- // order.)
- header.packet_number = kPacketNumber + 1;
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
- data = BuildDataPacket(header, frames);
- ASSERT_TRUE(data != nullptr);
- encrypted = EncryptPacketWithTagAndPhase(*data, 1, true);
- ASSERT_TRUE(encrypted);
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
- // Packet should decrypt and key update count should not change.
- EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
- EXPECT_EQ(1u, visitor_.key_update_count());
- EXPECT_EQ(1, visitor_.derive_next_key_count_);
- EXPECT_EQ(2, visitor_.decrypted_first_packet_in_key_phase_count_);
-}
-
-TEST_P(QuicFramerTest, KeyUpdateWrongKey) {
- if (!framer_.version().UsesTls()) {
- // Key update is only used in QUIC+TLS.
- return;
- }
- ASSERT_TRUE(framer_.version().KnowsWhichDecrypterToUse());
- // Doesn't use SetDecrypterLevel since we want to use StrictTaggingDecrypter
- // instead of TestDecrypter.
- framer_.InstallDecrypter(ENCRYPTION_FORWARD_SECURE,
- std::make_unique<StrictTaggingDecrypter>(/*key=*/0));
- framer_.SetKeyUpdateSupportForConnection(true);
-
- QuicPacketHeader header;
- header.destination_connection_id = FramerTestConnectionId();
- header.reset_flag = false;
- header.version_flag = false;
- header.packet_number = kPacketNumber;
-
- QuicFrames frames = {QuicFrame(QuicPaddingFrame())};
-
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
- std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
- ASSERT_TRUE(data != nullptr);
- std::unique_ptr<QuicEncryptedPacket> encrypted(
- EncryptPacketWithTagAndPhase(*data, 0, false));
- ASSERT_TRUE(encrypted);
-
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
- EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
- // Processed valid packet with phase=0, key=1: no key update.
- EXPECT_EQ(0u, visitor_.key_update_count());
- EXPECT_EQ(0, visitor_.derive_next_key_count_);
- EXPECT_EQ(1, visitor_.decrypted_first_packet_in_key_phase_count_);
- EXPECT_EQ(0u, framer_.PotentialPeerKeyUpdateAttemptCount());
-
- header.packet_number += 1;
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
- data = BuildDataPacket(header, frames);
- ASSERT_TRUE(data != nullptr);
- encrypted = EncryptPacketWithTagAndPhase(*data, 2, true);
- ASSERT_TRUE(encrypted);
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
- // Packet with phase=1 but key=3, should not process and should not cause key
- // update, but next decrypter key should have been created to attempt to
- // decode it.
- EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
- EXPECT_EQ(0u, visitor_.key_update_count());
- EXPECT_EQ(1, visitor_.derive_next_key_count_);
- EXPECT_EQ(1, visitor_.decrypted_first_packet_in_key_phase_count_);
- EXPECT_EQ(1u, framer_.PotentialPeerKeyUpdateAttemptCount());
-
- header.packet_number += 1;
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
- data = BuildDataPacket(header, frames);
- ASSERT_TRUE(data != nullptr);
- encrypted = EncryptPacketWithTagAndPhase(*data, 0, true);
- ASSERT_TRUE(encrypted);
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
- // Packet with phase=1 but key=1, should not process and should not cause key
- // update.
- EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
- EXPECT_EQ(0u, visitor_.key_update_count());
- EXPECT_EQ(1, visitor_.derive_next_key_count_);
- EXPECT_EQ(1, visitor_.decrypted_first_packet_in_key_phase_count_);
- EXPECT_EQ(2u, framer_.PotentialPeerKeyUpdateAttemptCount());
-
- header.packet_number += 1;
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
- data = BuildDataPacket(header, frames);
- ASSERT_TRUE(data != nullptr);
- encrypted = EncryptPacketWithTagAndPhase(*data, 1, false);
- ASSERT_TRUE(encrypted);
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
- // Packet with phase=0 but key=2, should not process and should not cause key
- // update.
- EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
- EXPECT_EQ(0u, visitor_.key_update_count());
- EXPECT_EQ(1, visitor_.derive_next_key_count_);
- EXPECT_EQ(1, visitor_.decrypted_first_packet_in_key_phase_count_);
- EXPECT_EQ(2u, framer_.PotentialPeerKeyUpdateAttemptCount());
-
- header.packet_number += 1;
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
- data = BuildDataPacket(header, frames);
- ASSERT_TRUE(data != nullptr);
- encrypted = EncryptPacketWithTagAndPhase(*data, 0, false);
- ASSERT_TRUE(encrypted);
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
- // Packet with phase=0 and key=0, should process and reset
- // potential_peer_key_update_attempt_count_.
- EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
- EXPECT_EQ(0u, visitor_.key_update_count());
- EXPECT_EQ(1, visitor_.derive_next_key_count_);
- EXPECT_EQ(1, visitor_.decrypted_first_packet_in_key_phase_count_);
- EXPECT_EQ(0u, framer_.PotentialPeerKeyUpdateAttemptCount());
-}
-
-TEST_P(QuicFramerTest, KeyUpdateReceivedWhenNotEnabled) {
- if (!framer_.version().UsesTls()) {
- // Key update is only used in QUIC+TLS.
- return;
- }
- ASSERT_TRUE(framer_.version().KnowsWhichDecrypterToUse());
- // Doesn't use SetDecrypterLevel since we want to use StrictTaggingDecrypter
- // instead of TestDecrypter.
- framer_.InstallDecrypter(ENCRYPTION_FORWARD_SECURE,
- std::make_unique<StrictTaggingDecrypter>(/*key=*/0));
-
- QuicPacketHeader header;
- header.destination_connection_id = FramerTestConnectionId();
- header.reset_flag = false;
- header.version_flag = false;
- header.packet_number = kPacketNumber;
-
- QuicFrames frames = {QuicFrame(QuicPaddingFrame())};
-
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
- std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
- ASSERT_TRUE(data != nullptr);
- std::unique_ptr<QuicEncryptedPacket> encrypted(
- EncryptPacketWithTagAndPhase(*data, 1, true));
- ASSERT_TRUE(encrypted);
-
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
- // Received a packet with key phase updated even though framer hasn't had key
- // update enabled (SetNextOneRttCrypters never called). Should fail to
- // process.
- EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
- EXPECT_EQ(0u, visitor_.key_update_count());
- EXPECT_EQ(0, visitor_.derive_next_key_count_);
- EXPECT_EQ(0, visitor_.decrypted_first_packet_in_key_phase_count_);
-}
-
-TEST_P(QuicFramerTest, KeyUpdateLocallyInitiated) {
- if (!framer_.version().UsesTls()) {
- // Key update is only used in QUIC+TLS.
- return;
- }
- ASSERT_TRUE(framer_.version().KnowsWhichDecrypterToUse());
- // Doesn't use SetDecrypterLevel since we want to use StrictTaggingDecrypter
- // instead of TestDecrypter.
- framer_.InstallDecrypter(ENCRYPTION_FORWARD_SECURE,
- std::make_unique<StrictTaggingDecrypter>(/*key=*/0));
- framer_.SetKeyUpdateSupportForConnection(true);
-
- EXPECT_TRUE(framer_.DoKeyUpdate(KeyUpdateReason::kLocalForTests));
- // Key update count should be updated, but haven't received packet from peer
- // with new key phase.
- ASSERT_EQ(1u, visitor_.key_update_count());
- EXPECT_EQ(KeyUpdateReason::kLocalForTests, visitor_.key_update_reasons_[0]);
- EXPECT_EQ(1, visitor_.derive_next_key_count_);
- EXPECT_EQ(0, visitor_.decrypted_first_packet_in_key_phase_count_);
-
- QuicPacketHeader header;
- header.destination_connection_id = FramerTestConnectionId();
- header.reset_flag = false;
- header.version_flag = false;
- header.packet_number = kPacketNumber;
-
- QuicFrames frames = {QuicFrame(QuicPaddingFrame())};
-
- // Process packet N with phase 1.
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
- std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
- ASSERT_TRUE(data != nullptr);
- std::unique_ptr<QuicEncryptedPacket> encrypted(
- EncryptPacketWithTagAndPhase(*data, 1, true));
- ASSERT_TRUE(encrypted);
-
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
- // Packet should decrypt and key update count should not change and
- // OnDecryptedFirstPacketInKeyPhase should have been called.
- EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
- EXPECT_EQ(1u, visitor_.key_update_count());
- EXPECT_EQ(1, visitor_.derive_next_key_count_);
- EXPECT_EQ(1, visitor_.decrypted_first_packet_in_key_phase_count_);
-
- // Process packet N-1 with phase 0. (Receiving packet from previous phase
- // after packet from new phase was received.)
- header.packet_number = kPacketNumber - 1;
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
- data = BuildDataPacket(header, frames);
- ASSERT_TRUE(data != nullptr);
- encrypted = EncryptPacketWithTagAndPhase(*data, 0, false);
- ASSERT_TRUE(encrypted);
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
- // Packet should decrypt and key update count should not change.
- EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
- EXPECT_EQ(1u, visitor_.key_update_count());
- EXPECT_EQ(1, visitor_.derive_next_key_count_);
- EXPECT_EQ(1, visitor_.decrypted_first_packet_in_key_phase_count_);
-
- // Process packet N+1 with phase 0 and key 1. This should not decrypt even
- // though it's using the previous key, since the packet number is higher than
- // a packet number received using the current key.
- header.packet_number = kPacketNumber + 1;
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
- data = BuildDataPacket(header, frames);
- ASSERT_TRUE(data != nullptr);
- encrypted = EncryptPacketWithTagAndPhase(*data, 0, false);
- ASSERT_TRUE(encrypted);
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
- // Packet should not decrypt and key update count should not change.
- EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
- EXPECT_EQ(1u, visitor_.key_update_count());
- EXPECT_EQ(2, visitor_.derive_next_key_count_);
- EXPECT_EQ(1, visitor_.decrypted_first_packet_in_key_phase_count_);
-}
-
-TEST_P(QuicFramerTest, KeyUpdateLocallyInitiatedReceivedOldPacket) {
- if (!framer_.version().UsesTls()) {
- // Key update is only used in QUIC+TLS.
- return;
- }
- ASSERT_TRUE(framer_.version().KnowsWhichDecrypterToUse());
- // Doesn't use SetDecrypterLevel since we want to use StrictTaggingDecrypter
- // instead of TestDecrypter.
- framer_.InstallDecrypter(ENCRYPTION_FORWARD_SECURE,
- std::make_unique<StrictTaggingDecrypter>(/*key=*/0));
- framer_.SetKeyUpdateSupportForConnection(true);
-
- EXPECT_TRUE(framer_.DoKeyUpdate(KeyUpdateReason::kLocalForTests));
- // Key update count should be updated, but haven't received packet
- // from peer with new key phase.
- EXPECT_EQ(1u, visitor_.key_update_count());
- EXPECT_EQ(1, visitor_.derive_next_key_count_);
- EXPECT_EQ(0, visitor_.decrypted_first_packet_in_key_phase_count_);
-
- QuicPacketHeader header;
- header.destination_connection_id = FramerTestConnectionId();
- header.reset_flag = false;
- header.version_flag = false;
- header.packet_number = kPacketNumber;
-
- QuicFrames frames = {QuicFrame(QuicPaddingFrame())};
-
- // Process packet N with phase 0. (Receiving packet from previous phase
- // after locally initiated key update, but before any packet from new phase
- // was received.)
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
- std::unique_ptr<QuicPacket> data = BuildDataPacket(header, frames);
- ASSERT_TRUE(data != nullptr);
- std::unique_ptr<QuicEncryptedPacket> encrypted =
- EncryptPacketWithTagAndPhase(*data, 0, false);
- ASSERT_TRUE(encrypted);
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
- // Packet should decrypt and key update count should not change and
- // OnDecryptedFirstPacketInKeyPhase should not have been called since the
- // packet was from the previous key phase.
- EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
- EXPECT_EQ(1u, visitor_.key_update_count());
- EXPECT_EQ(1, visitor_.derive_next_key_count_);
- EXPECT_EQ(0, visitor_.decrypted_first_packet_in_key_phase_count_);
-
- // Process packet N+1 with phase 1.
- header.packet_number = kPacketNumber + 1;
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
- data = BuildDataPacket(header, frames);
- ASSERT_TRUE(data != nullptr);
- encrypted = EncryptPacketWithTagAndPhase(*data, 1, true);
- ASSERT_TRUE(encrypted);
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
- // Packet should decrypt and key update count should not change, but
- // OnDecryptedFirstPacketInKeyPhase should have been called.
- EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
- EXPECT_EQ(1u, visitor_.key_update_count());
- EXPECT_EQ(1, visitor_.derive_next_key_count_);
- EXPECT_EQ(1, visitor_.decrypted_first_packet_in_key_phase_count_);
-
- // Process packet N+2 with phase 0 and key 1. This should not decrypt even
- // though it's using the previous key, since the packet number is higher than
- // a packet number received using the current key.
- header.packet_number = kPacketNumber + 2;
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
- data = BuildDataPacket(header, frames);
- ASSERT_TRUE(data != nullptr);
- encrypted = EncryptPacketWithTagAndPhase(*data, 0, false);
- ASSERT_TRUE(encrypted);
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
- // Packet should not decrypt and key update count should not change.
- EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
- EXPECT_EQ(1u, visitor_.key_update_count());
- EXPECT_EQ(2, visitor_.derive_next_key_count_);
- EXPECT_EQ(1, visitor_.decrypted_first_packet_in_key_phase_count_);
-}
-
-TEST_P(QuicFramerTest, KeyUpdateOnFirstReceivedPacket) {
- if (!framer_.version().UsesTls()) {
- // Key update is only used in QUIC+TLS.
- return;
- }
- ASSERT_TRUE(framer_.version().KnowsWhichDecrypterToUse());
- // Doesn't use SetDecrypterLevel since we want to use StrictTaggingDecrypter
- // instead of TestDecrypter.
- framer_.InstallDecrypter(ENCRYPTION_FORWARD_SECURE,
- std::make_unique<StrictTaggingDecrypter>(/*key=*/0));
- framer_.SetKeyUpdateSupportForConnection(true);
-
- QuicPacketHeader header;
- header.destination_connection_id = FramerTestConnectionId();
- header.reset_flag = false;
- header.version_flag = false;
- header.packet_number = QuicPacketNumber(123);
-
- QuicFrames frames = {QuicFrame(QuicPaddingFrame())};
-
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
- std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
- ASSERT_TRUE(data != nullptr);
- std::unique_ptr<QuicEncryptedPacket> encrypted(
- EncryptPacketWithTagAndPhase(*data, /*tag=*/1, /*phase=*/true));
- ASSERT_TRUE(encrypted);
-
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
- EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
- // Processed valid packet with phase=1, key=1: do key update.
- EXPECT_EQ(1u, visitor_.key_update_count());
- EXPECT_EQ(1, visitor_.derive_next_key_count_);
- EXPECT_EQ(1, visitor_.decrypted_first_packet_in_key_phase_count_);
-}
-
-TEST_P(QuicFramerTest, ErrorWhenUnexpectedFrameTypeEncountered) {
- if (!VersionHasIetfQuicFrames(framer_.transport_version()) ||
- !QuicVersionHasLongHeaderLengths(framer_.transport_version()) ||
- !framer_.version().HasLongHeaderLengths()) {
- return;
- }
- SetDecrypterLevel(ENCRYPTION_ZERO_RTT);
- // clang-format off
- unsigned char packet[] = {
- // public flags (long header with packet type ZERO_RTT_PROTECTED and
- // 4-byte packet number)
- 0xD3,
- // version
- QUIC_VERSION_BYTES,
- // destination connection ID length
- 0x08,
- // destination connection ID
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // source connection ID length
- 0x08,
- // source connection ID
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x11,
- // long header packet length
- 0x05,
- // packet number
- 0x12, 0x34, 0x56, 0x00,
- // unexpected ietf ack frame type in 0-RTT packet
- 0x02,
- };
- // clang-format on
-
- ReviseFirstByteByVersion(packet);
- QuicEncryptedPacket encrypted(AsChars(packet), ABSL_ARRAYSIZE(packet), false);
-
- EXPECT_FALSE(framer_.ProcessPacket(encrypted));
-
- EXPECT_THAT(framer_.error(), IsError(IETF_QUIC_PROTOCOL_VIOLATION));
- EXPECT_EQ(
- "IETF frame type IETF_ACK is unexpected at encryption level "
- "ENCRYPTION_ZERO_RTT",
- framer_.detailed_error());
-}
-
-} // namespace
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_idle_network_detector.cc b/chromium/net/third_party/quiche/src/quic/core/quic_idle_network_detector.cc
deleted file mode 100644
index fceb1e7e9b0..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_idle_network_detector.cc
+++ /dev/null
@@ -1,145 +0,0 @@
-// Copyright (c) 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_idle_network_detector.h"
-
-#include "quic/core/quic_constants.h"
-#include "quic/platform/api/quic_flag_utils.h"
-
-namespace quic {
-
-namespace {
-
-class AlarmDelegate : public QuicAlarm::DelegateWithContext {
- public:
- explicit AlarmDelegate(QuicIdleNetworkDetector* detector,
- QuicConnectionContext* context)
- : QuicAlarm::DelegateWithContext(context), detector_(detector) {}
- AlarmDelegate(const AlarmDelegate&) = delete;
- AlarmDelegate& operator=(const AlarmDelegate&) = delete;
-
- void OnAlarm() override { detector_->OnAlarm(); }
-
- private:
- QuicIdleNetworkDetector* detector_;
-};
-
-} // namespace
-
-QuicIdleNetworkDetector::QuicIdleNetworkDetector(
- Delegate* delegate, QuicTime now, QuicConnectionArena* arena,
- QuicAlarmFactory* alarm_factory, QuicConnectionContext* context)
- : delegate_(delegate),
- start_time_(now),
- handshake_timeout_(QuicTime::Delta::Infinite()),
- time_of_last_received_packet_(now),
- time_of_first_packet_sent_after_receiving_(QuicTime::Zero()),
- idle_network_timeout_(QuicTime::Delta::Infinite()),
- alarm_(alarm_factory->CreateAlarm(
- arena->New<AlarmDelegate>(this, context), arena)) {}
-
-void QuicIdleNetworkDetector::OnAlarm() {
- if (handshake_timeout_.IsInfinite()) {
- delegate_->OnIdleNetworkDetected();
- return;
- }
- if (idle_network_timeout_.IsInfinite()) {
- delegate_->OnHandshakeTimeout();
- return;
- }
- if (last_network_activity_time() + idle_network_timeout_ >
- start_time_ + handshake_timeout_) {
- delegate_->OnHandshakeTimeout();
- return;
- }
- delegate_->OnIdleNetworkDetected();
-}
-
-void QuicIdleNetworkDetector::SetTimeouts(
- QuicTime::Delta handshake_timeout,
- QuicTime::Delta idle_network_timeout) {
- handshake_timeout_ = handshake_timeout;
- idle_network_timeout_ = idle_network_timeout;
-
- SetAlarm();
-}
-
-void QuicIdleNetworkDetector::StopDetection() {
- alarm_->PermanentCancel();
- handshake_timeout_ = QuicTime::Delta::Infinite();
- idle_network_timeout_ = QuicTime::Delta::Infinite();
- stopped_ = true;
-}
-
-void QuicIdleNetworkDetector::OnPacketSent(QuicTime now,
- QuicTime::Delta pto_delay) {
- if (time_of_first_packet_sent_after_receiving_ >
- time_of_last_received_packet_) {
- return;
- }
- time_of_first_packet_sent_after_receiving_ =
- std::max(time_of_first_packet_sent_after_receiving_, now);
- if (shorter_idle_timeout_on_sent_packet_) {
- MaybeSetAlarmOnSentPacket(pto_delay);
- return;
- }
-
- SetAlarm();
-}
-
-void QuicIdleNetworkDetector::OnPacketReceived(QuicTime now) {
- time_of_last_received_packet_ = std::max(time_of_last_received_packet_, now);
-
- SetAlarm();
-}
-
-void QuicIdleNetworkDetector::SetAlarm() {
- if (stopped_) {
- // TODO(wub): If this QUIC_BUG fires, it indicates a problem in the
- // QuicConnection, which somehow called this function while disconnected.
- // That problem needs to be fixed.
- QUIC_BUG(quic_idle_detector_set_alarm_after_stopped)
- << "SetAlarm called after stopped";
- return;
- }
- // Set alarm to the nearer deadline.
- QuicTime new_deadline = QuicTime::Zero();
- if (!handshake_timeout_.IsInfinite()) {
- new_deadline = start_time_ + handshake_timeout_;
- }
- if (!idle_network_timeout_.IsInfinite()) {
- const QuicTime idle_network_deadline = GetIdleNetworkDeadline();
- if (new_deadline.IsInitialized()) {
- new_deadline = std::min(new_deadline, idle_network_deadline);
- } else {
- new_deadline = idle_network_deadline;
- }
- }
- alarm_->Update(new_deadline, kAlarmGranularity);
-}
-
-void QuicIdleNetworkDetector::MaybeSetAlarmOnSentPacket(
- QuicTime::Delta pto_delay) {
- QUICHE_DCHECK(shorter_idle_timeout_on_sent_packet_);
- if (!handshake_timeout_.IsInfinite() || !alarm_->IsSet()) {
- SetAlarm();
- return;
- }
- // Make sure connection will be alive for another PTO.
- const QuicTime deadline = alarm_->deadline();
- const QuicTime min_deadline = last_network_activity_time() + pto_delay;
- if (deadline > min_deadline) {
- return;
- }
- alarm_->Update(min_deadline, kAlarmGranularity);
-}
-
-QuicTime QuicIdleNetworkDetector::GetIdleNetworkDeadline() const {
- if (idle_network_timeout_.IsInfinite()) {
- return QuicTime::Zero();
- }
- return last_network_activity_time() + idle_network_timeout_;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_idle_network_detector.h b/chromium/net/third_party/quiche/src/quic/core/quic_idle_network_detector.h
deleted file mode 100644
index 2381c12cdc6..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_idle_network_detector.h
+++ /dev/null
@@ -1,118 +0,0 @@
-// Copyright (c) 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_IDLE_NETWORK_DETECTOR_H_
-#define QUICHE_QUIC_CORE_QUIC_IDLE_NETWORK_DETECTOR_H_
-
-#include "quic/core/quic_alarm.h"
-#include "quic/core/quic_alarm_factory.h"
-#include "quic/core/quic_one_block_arena.h"
-#include "quic/core/quic_time.h"
-#include "quic/platform/api/quic_export.h"
-#include "quic/platform/api/quic_flags.h"
-
-namespace quic {
-
-namespace test {
-class QuicConnectionPeer;
-class QuicIdleNetworkDetectorTestPeer;
-} // namespace test
-
-// QuicIdleNetworkDetector detects handshake timeout and idle network timeout.
-// Handshake timeout detection is disabled after handshake completes. Idle
-// network deadline is extended by network activity (e.g., sending or receiving
-// packets).
-class QUIC_EXPORT_PRIVATE QuicIdleNetworkDetector {
- public:
- class QUIC_EXPORT_PRIVATE Delegate {
- public:
- virtual ~Delegate() {}
-
- // Called when handshake times out.
- virtual void OnHandshakeTimeout() = 0;
-
- // Called when idle network has been detected.
- virtual void OnIdleNetworkDetected() = 0;
- };
-
- QuicIdleNetworkDetector(Delegate* delegate, QuicTime now,
- QuicConnectionArena* arena,
- QuicAlarmFactory* alarm_factory,
- QuicConnectionContext* context);
-
- void OnAlarm();
-
- // Called to set handshake_timeout_ and idle_network_timeout_.
- void SetTimeouts(QuicTime::Delta handshake_timeout,
- QuicTime::Delta idle_network_timeout);
-
- // Stop the detection once and for all.
- void StopDetection();
-
- // Called when a packet gets sent.
- void OnPacketSent(QuicTime now, QuicTime::Delta pto_delay);
-
- // Called when a packet gets received.
- void OnPacketReceived(QuicTime now);
-
- void enable_shorter_idle_timeout_on_sent_packet() {
- shorter_idle_timeout_on_sent_packet_ = true;
- }
-
- QuicTime::Delta handshake_timeout() const { return handshake_timeout_; }
-
- QuicTime time_of_last_received_packet() const {
- return time_of_last_received_packet_;
- }
-
- QuicTime last_network_activity_time() const {
- return std::max(time_of_last_received_packet_,
- time_of_first_packet_sent_after_receiving_);
- }
-
- QuicTime::Delta idle_network_timeout() const { return idle_network_timeout_; }
-
- QuicTime GetIdleNetworkDeadline() const;
-
- private:
- friend class test::QuicConnectionPeer;
- friend class test::QuicIdleNetworkDetectorTestPeer;
-
- void SetAlarm();
-
- void MaybeSetAlarmOnSentPacket(QuicTime::Delta pto_delay);
-
- 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.
- QuicTime::Delta handshake_timeout_;
-
- // Time that last packet is received for this connection. Initialized to
- // start_time_.
- QuicTime time_of_last_received_packet_;
-
- // Time that the first packet gets sent after the received packet. idle
- // network deadline = std::max(time_of_last_received_packet_,
- // time_of_first_packet_sent_after_receiving_) + idle_network_timeout_.
- // Initialized to 0.
- QuicTime time_of_first_packet_sent_after_receiving_;
-
- // Idle network timeout. Infinit means no idle network timeout.
- QuicTime::Delta idle_network_timeout_;
-
- QuicArenaScopedPtr<QuicAlarm> alarm_;
-
- bool shorter_idle_timeout_on_sent_packet_ = false;
-
- // Whether |StopDetection| has been called.
- bool stopped_ = false;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_QUIC_IDLE_NETWORK_DETECTOR_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_idle_network_detector_test.cc b/chromium/net/third_party/quiche/src/quic/core/quic_idle_network_detector_test.cc
deleted file mode 100644
index a6fd5d28ce7..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_idle_network_detector_test.cc
+++ /dev/null
@@ -1,200 +0,0 @@
-// Copyright (c) 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_idle_network_detector.h"
-
-#include "quic/core/quic_one_block_arena.h"
-#include "quic/platform/api/quic_expect_bug.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/quic_test_utils.h"
-
-namespace quic {
-namespace test {
-
-class QuicIdleNetworkDetectorTestPeer {
- public:
- static QuicAlarm* GetAlarm(QuicIdleNetworkDetector* detector) {
- return detector->alarm_.get();
- }
-};
-
-namespace {
-
-class MockDelegate : public QuicIdleNetworkDetector::Delegate {
- public:
- MOCK_METHOD(void, OnHandshakeTimeout, (), (override));
- MOCK_METHOD(void, OnIdleNetworkDetected, (), (override));
-};
-
-class QuicIdleNetworkDetectorTest : public QuicTest {
- public:
- QuicIdleNetworkDetectorTest() {
- clock_.AdvanceTime(QuicTime::Delta::FromSeconds(1));
- detector_ = std::make_unique<QuicIdleNetworkDetector>(
- &delegate_, clock_.Now(), &arena_, &alarm_factory_,
- /*context=*/nullptr);
- alarm_ = static_cast<MockAlarmFactory::TestAlarm*>(
- QuicIdleNetworkDetectorTestPeer::GetAlarm(detector_.get()));
- }
-
- protected:
- testing::StrictMock<MockDelegate> delegate_;
- QuicConnectionArena arena_;
- MockAlarmFactory alarm_factory_;
-
- std::unique_ptr<QuicIdleNetworkDetector> detector_;
-
- MockAlarmFactory::TestAlarm* alarm_;
- MockClock clock_;
-};
-
-TEST_F(QuicIdleNetworkDetectorTest,
- IdleNetworkDetectedBeforeHandshakeCompletes) {
- EXPECT_FALSE(alarm_->IsSet());
- detector_->SetTimeouts(
- /*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());
-
- // No network activity for 20s.
- clock_.AdvanceTime(QuicTime::Delta::FromSeconds(20));
- EXPECT_CALL(delegate_, OnIdleNetworkDetected());
- alarm_->Fire();
-}
-
-TEST_F(QuicIdleNetworkDetectorTest, HandshakeTimeout) {
- EXPECT_FALSE(alarm_->IsSet());
- detector_->SetTimeouts(
- /*handshake_timeout=*/QuicTime::Delta::FromSeconds(30),
- /*idle_network_timeout=*/QuicTime::Delta::FromSeconds(20));
- EXPECT_TRUE(alarm_->IsSet());
-
- // Has network activity after 15s.
- clock_.AdvanceTime(QuicTime::Delta::FromSeconds(15));
- detector_->OnPacketReceived(clock_.Now());
- EXPECT_EQ(clock_.Now() + QuicTime::Delta::FromSeconds(15),
- alarm_->deadline());
- // Handshake does not complete for another 15s.
- clock_.AdvanceTime(QuicTime::Delta::FromSeconds(15));
- EXPECT_CALL(delegate_, OnHandshakeTimeout());
- alarm_->Fire();
-}
-
-TEST_F(QuicIdleNetworkDetectorTest,
- IdleNetworkDetectedAfterHandshakeCompletes) {
- EXPECT_FALSE(alarm_->IsSet());
- detector_->SetTimeouts(
- /*handshake_timeout=*/QuicTime::Delta::FromSeconds(30),
- /*idle_network_timeout=*/QuicTime::Delta::FromSeconds(20));
- EXPECT_TRUE(alarm_->IsSet());
-
- // Handshake completes in 200ms.
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(200));
- detector_->OnPacketReceived(clock_.Now());
- detector_->SetTimeouts(
- /*handshake_timeout=*/QuicTime::Delta::Infinite(),
- /*idle_network_timeout=*/QuicTime::Delta::FromSeconds(600));
- 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();
-}
-
-TEST_F(QuicIdleNetworkDetectorTest,
- DoNotExtendIdleDeadlineOnConsecutiveSentPackets) {
- EXPECT_FALSE(alarm_->IsSet());
- detector_->SetTimeouts(
- /*handshake_timeout=*/QuicTime::Delta::FromSeconds(30),
- /*idle_network_timeout=*/QuicTime::Delta::FromSeconds(20));
- EXPECT_TRUE(alarm_->IsSet());
-
- // Handshake completes in 200ms.
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(200));
- detector_->OnPacketReceived(clock_.Now());
- detector_->SetTimeouts(
- /*handshake_timeout=*/QuicTime::Delta::Infinite(),
- /*idle_network_timeout=*/QuicTime::Delta::FromSeconds(600));
- EXPECT_EQ(clock_.Now() + QuicTime::Delta::FromSeconds(600),
- alarm_->deadline());
-
- // Sent packets after 200ms.
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(200));
- detector_->OnPacketSent(clock_.Now(), QuicTime::Delta::Zero());
- const QuicTime packet_sent_time = clock_.Now();
- EXPECT_EQ(packet_sent_time + QuicTime::Delta::FromSeconds(600),
- alarm_->deadline());
-
- // 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.
- EXPECT_EQ(packet_sent_time + QuicTime::Delta::FromSeconds(600),
- alarm_->deadline());
-
- // No network activity for 600s.
- clock_.AdvanceTime(QuicTime::Delta::FromSeconds(600) -
- QuicTime::Delta::FromMilliseconds(200));
- EXPECT_CALL(delegate_, OnIdleNetworkDetected());
- alarm_->Fire();
-}
-
-TEST_F(QuicIdleNetworkDetectorTest, ShorterIdleTimeoutOnSentPacket) {
- detector_->enable_shorter_idle_timeout_on_sent_packet();
- detector_->SetTimeouts(
- /*handshake_timeout=*/QuicTime::Delta::Infinite(),
- /*idle_network_timeout=*/QuicTime::Delta::FromSeconds(30));
- EXPECT_TRUE(alarm_->IsSet());
- const QuicTime deadline = alarm_->deadline();
- EXPECT_EQ(clock_.Now() + QuicTime::Delta::FromSeconds(30), deadline);
-
- // Send a packet after 15s and 2s PTO delay.
- clock_.AdvanceTime(QuicTime::Delta::FromSeconds(15));
- detector_->OnPacketSent(clock_.Now(), QuicTime::Delta::FromSeconds(2));
- EXPECT_TRUE(alarm_->IsSet());
- // Verify alarm does not get extended because deadline is > PTO delay.
- EXPECT_EQ(deadline, alarm_->deadline());
-
- // Send another packet near timeout and 2 s PTO delay.
- clock_.AdvanceTime(QuicTime::Delta::FromSeconds(14));
- detector_->OnPacketSent(clock_.Now(), QuicTime::Delta::FromSeconds(2));
- EXPECT_TRUE(alarm_->IsSet());
- // Verify alarm does not get extended although it is shorter than PTO.
- EXPECT_EQ(deadline, alarm_->deadline());
-
- // Receive a packet after 1s.
- clock_.AdvanceTime(QuicTime::Delta::FromSeconds(1));
- detector_->OnPacketReceived(clock_.Now());
- EXPECT_TRUE(alarm_->IsSet());
- // Verify idle timeout gets extended by 30s.
- EXPECT_EQ(clock_.Now() + QuicTime::Delta::FromSeconds(30),
- alarm_->deadline());
-
- // Send a packet near timeout..
- clock_.AdvanceTime(QuicTime::Delta::FromSeconds(29));
- detector_->OnPacketSent(clock_.Now(), QuicTime::Delta::FromSeconds(2));
- EXPECT_TRUE(alarm_->IsSet());
- // Verify idle timeout gets extended by 1s.
- EXPECT_EQ(clock_.Now() + QuicTime::Delta::FromSeconds(2), alarm_->deadline());
-}
-
-TEST_F(QuicIdleNetworkDetectorTest, NoAlarmAfterStopped) {
- detector_->StopDetection();
-
- EXPECT_QUIC_BUG(
- detector_->SetTimeouts(
- /*handshake_timeout=*/QuicTime::Delta::FromSeconds(30),
- /*idle_network_timeout=*/QuicTime::Delta::FromSeconds(20)),
- "SetAlarm called after stopped");
- EXPECT_FALSE(alarm_->IsSet());
-}
-
-} // namespace
-
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_interval.h b/chromium/net/third_party/quiche/src/quic/core/quic_interval.h
deleted file mode 100644
index 81a4d626883..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_interval.h
+++ /dev/null
@@ -1,390 +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_CORE_QUIC_INTERVAL_H_
-#define QUICHE_QUIC_CORE_QUIC_INTERVAL_H_
-
-// An QuicInterval<T> is a data structure used to represent a contiguous,
-// mutable range over an ordered type T. Supported operations include testing a
-// value to see whether it is included in the QuicInterval, comparing two
-// QuicIntervals, and performing their union, intersection, and difference. For
-// the purposes of this library, an "ordered type" is any type that induces a
-// total order on its values via its less-than operator (operator<()). Examples
-// of such types are basic arithmetic types like int and double as well as class
-// types like string.
-//
-// An QuicInterval<T> is represented using the usual C++ STL convention, namely
-// as the half-open QuicInterval [min, max). A point p is considered to be
-// contained in the QuicInterval iff p >= min && p < max. One consequence of
-// this definition is that for any non-empty QuicInterval, min is contained in
-// the QuicInterval but max is not. There is no canonical representation for the
-// empty QuicInterval; rather, any QuicInterval where max <= min is regarded as
-// empty. As a consequence, two empty QuicIntervals will still compare as equal
-// despite possibly having different underlying min() or max() values. Also
-// beware of the terminology used here: the library uses the terms "min" and
-// "max" rather than "begin" and "end" as is conventional for the STL.
-//
-// T is required to be default- and copy-constructable, to have an assignment
-// operator, and the full complement of comparison operators (<, <=, ==, !=, >=,
-// >). A difference operator (operator-()) is required if
-// QuicInterval<T>::Length is used.
-//
-// QuicInterval supports operator==. Two QuicIntervals are considered equal if
-// either they are both empty or if their corresponding min and max fields
-// compare equal. QuicInterval also provides an operator<. Unfortunately,
-// operator< is currently buggy because its behavior is inconsistent with
-// operator==: two empty ranges with different representations may be regarded
-// as equal by operator== but regarded as different by operator<. Bug 9240050
-// has been created to address this.
-//
-//
-// Examples:
-// QuicInterval<int> r1(0, 100); // The QuicInterval [0, 100).
-// EXPECT_TRUE(r1.Contains(0));
-// EXPECT_TRUE(r1.Contains(50));
-// EXPECT_FALSE(r1.Contains(100)); // 100 is just outside the QuicInterval.
-//
-// QuicInterval<int> r2(50, 150); // The QuicInterval [50, 150).
-// EXPECT_TRUE(r1.Intersects(r2));
-// EXPECT_FALSE(r1.Contains(r2));
-// EXPECT_TRUE(r1.IntersectWith(r2)); // Mutates r1.
-// EXPECT_EQ(QuicInterval<int>(50, 100), r1); // r1 is now [50, 100).
-//
-// QuicInterval<int> r3(1000, 2000); // The QuicInterval [1000, 2000).
-// EXPECT_TRUE(r1.IntersectWith(r3)); // Mutates r1.
-// EXPECT_TRUE(r1.Empty()); // Now r1 is empty.
-// EXPECT_FALSE(r1.Contains(r1.min())); // e.g. doesn't contain its own min.
-
-#include <stddef.h>
-#include <algorithm>
-#include <ostream>
-#include <type_traits>
-#include <utility>
-#include <vector>
-
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-template <typename T>
-class QUIC_NO_EXPORT QuicInterval {
- private:
- // Type trait for deriving the return type for QuicInterval::Length. If
- // operator-() is not defined for T, then the return type is void. This makes
- // the signature for Length compile so that the class can be used for such T,
- // but code that calls Length would still generate a compilation error.
- template <typename U>
- class QUIC_NO_EXPORT DiffTypeOrVoid {
- private:
- template <typename V>
- static auto f(const V* v) -> decltype(*v - *v);
- template <typename V>
- static void f(...);
-
- public:
- using type = typename std::decay<decltype(f<U>(nullptr))>::type;
- };
-
- public:
- // Construct an QuicInterval representing an empty QuicInterval.
- QuicInterval() : min_(), max_() {}
-
- // Construct an QuicInterval representing the QuicInterval [min, max). If min
- // < max, the constructed object will represent the non-empty QuicInterval
- // containing all values from min up to (but not including) max. On the other
- // hand, if min >= max, the constructed object will represent the empty
- // QuicInterval.
- QuicInterval(const T& min, const T& max) : min_(min), max_(max) {}
-
- template <typename U1,
- typename U2,
- typename = typename std::enable_if<
- std::is_convertible<U1, T>::value &&
- std::is_convertible<U2, T>::value>::type>
- QuicInterval(U1&& min, U2&& max)
- : min_(std::forward<U1>(min)), max_(std::forward<U2>(max)) {}
-
- const T& min() const { return min_; }
- const T& max() const { return max_; }
- void SetMin(const T& t) { min_ = t; }
- void SetMax(const T& t) { max_ = t; }
-
- void Set(const T& min, const T& max) {
- SetMin(min);
- SetMax(max);
- }
-
- void Clear() { *this = {}; }
-
- bool Empty() const { return min() >= max(); }
-
- // Returns the length of this QuicInterval. The value returned is zero if
- // Empty() is true; otherwise the value returned is max() - min().
- typename DiffTypeOrVoid<T>::type Length() const {
- return (Empty() ? min() : max()) - min();
- }
-
- // Returns true iff t >= min() && t < max().
- bool Contains(const T& t) const { return min() <= t && max() > t; }
-
- // Returns true iff *this and i are non-empty, and *this includes i. "*this
- // includes i" means that for all t, if i.Contains(t) then this->Contains(t).
- // Note the unintuitive consequence of this definition: this method always
- // returns false when i is the empty QuicInterval.
- bool Contains(const QuicInterval& i) const {
- return !Empty() && !i.Empty() && min() <= i.min() && max() >= i.max();
- }
-
- // Returns true iff there exists some point t for which this->Contains(t) &&
- // i.Contains(t) evaluates to true, i.e. if the intersection is non-empty.
- bool Intersects(const QuicInterval& i) const {
- return !Empty() && !i.Empty() && min() < i.max() && max() > i.min();
- }
-
- // Returns true iff there exists some point t for which this->Contains(t) &&
- // i.Contains(t) evaluates to true, i.e. if the intersection is non-empty.
- // Furthermore, if the intersection is non-empty and the out pointer is not
- // null, this method stores the calculated intersection in *out.
- bool Intersects(const QuicInterval& i, QuicInterval* out) const;
-
- // Sets *this to be the intersection of itself with i. Returns true iff
- // *this was modified.
- bool IntersectWith(const QuicInterval& i);
-
- // Returns true iff this and other have disjoint closures. For nonempty
- // intervals, that means there is at least one point between this and other.
- // Roughly speaking that means the intervals don't intersect, and they are not
- // adjacent. Empty intervals are always separated from any other interval.
- bool Separated(const QuicInterval& other) const {
- if (Empty() || other.Empty())
- return true;
- return other.max() < min() || max() < other.min();
- }
-
- // Calculates the smallest QuicInterval containing both *this i, and updates
- // *this to represent that QuicInterval, and returns true iff *this was
- // modified.
- bool SpanningUnion(const QuicInterval& i);
-
- // Determines the difference between two QuicIntervals by finding all points
- // that are contained in *this but not in i, coalesces those points into the
- // largest possible contiguous QuicIntervals, and appends those QuicIntervals
- // to the *difference vector. Intuitively this can be thought of as "erasing"
- // i from *this. This will either completely erase *this (leaving nothing
- // behind), partially erase some of *this from the left or right side (leaving
- // some residual behind), or erase a hole in the middle of *this (leaving
- // behind an QuicInterval on either side). Therefore, 0, 1, or 2 QuicIntervals
- // will be appended to *difference. The method returns true iff the
- // intersection of *this and i is non-empty. The caller owns the vector and
- // the QuicInterval* pointers inside it. The difference vector is required to
- // be non-null.
- bool Difference(const QuicInterval& i,
- std::vector<QuicInterval*>* difference) const;
-
- // Determines the difference between two QuicIntervals as in
- // Difference(QuicInterval&, vector*), but stores the results directly in out
- // parameters rather than dynamically allocating an QuicInterval* and
- // appending it to a vector. If two results are generated, the one with the
- // smaller value of min() will be stored in *lo and the other in *hi.
- // Otherwise (if fewer than two results are generated), unused arguments will
- // be set to the empty QuicInterval (it is possible that *lo will be empty and
- // *hi non-empty). The method returns true iff the intersection of *this and i
- // is non-empty.
- bool Difference(const QuicInterval& i,
- QuicInterval* lo,
- QuicInterval* hi) const;
-
- friend bool operator==(const QuicInterval& a, const QuicInterval& b) {
- bool ae = a.Empty();
- bool be = b.Empty();
- if (ae && be)
- return true; // All empties are equal.
- if (ae != be)
- return false; // Empty cannot equal nonempty.
- return a.min() == b.min() && a.max() == b.max();
- }
-
- friend bool operator!=(const QuicInterval& a, const QuicInterval& b) {
- return !(a == b);
- }
-
- // Defines a comparator which can be used to induce an order on QuicIntervals,
- // so that, for example, they can be stored in an ordered container such as
- // std::set. The ordering is arbitrary, but does provide the guarantee that,
- // for non-empty QuicIntervals X and Y, if X contains Y, then X <= Y.
- // TODO(kosak): The current implementation of this comparator has a problem
- // because the ordering it induces is inconsistent with that of Equals(). In
- // particular, this comparator does not properly consider all empty
- // QuicIntervals equivalent. Bug 9240050 has been created to track this.
- friend bool operator<(const QuicInterval& a, const QuicInterval& b) {
- return a.min() < b.min() || (!(b.min() < a.min()) && b.max() < a.max());
- }
-
- private:
- T min_; // Inclusive lower bound.
- T max_; // Exclusive upper bound.
-};
-
-// Constructs an QuicInterval by deducing the types from the function arguments.
-template <typename T>
-QuicInterval<T> MakeQuicInterval(T&& lhs, T&& rhs) {
- return QuicInterval<T>(std::forward<T>(lhs), std::forward<T>(rhs));
-}
-
-// Note: ideally we'd use
-// decltype(out << "[" << i.min() << ", " << i.max() << ")")
-// as return type of the function, but as of July 2017 this triggers g++
-// "sorry, unimplemented: string literal in function template signature" error.
-template <typename T>
-auto operator<<(std::ostream& out, const QuicInterval<T>& i)
- -> decltype(out << i.min()) {
- return out << "[" << i.min() << ", " << i.max() << ")";
-}
-
-//==============================================================================
-// Implementation details: Clients can stop reading here.
-
-template <typename T>
-bool QuicInterval<T>::Intersects(const QuicInterval& i,
- QuicInterval* out) const {
- if (!Intersects(i))
- return false;
- if (out != nullptr) {
- *out = QuicInterval(std::max(min(), i.min()), std::min(max(), i.max()));
- }
- return true;
-}
-
-template <typename T>
-bool QuicInterval<T>::IntersectWith(const QuicInterval& i) {
- if (Empty())
- return false;
- bool modified = false;
- if (i.min() > min()) {
- SetMin(i.min());
- modified = true;
- }
- if (i.max() < max()) {
- SetMax(i.max());
- modified = true;
- }
- return modified;
-}
-
-template <typename T>
-bool QuicInterval<T>::SpanningUnion(const QuicInterval& i) {
- if (i.Empty())
- return false;
- if (Empty()) {
- *this = i;
- return true;
- }
- bool modified = false;
- if (i.min() < min()) {
- SetMin(i.min());
- modified = true;
- }
- if (i.max() > max()) {
- SetMax(i.max());
- modified = true;
- }
- return modified;
-}
-
-template <typename T>
-bool QuicInterval<T>::Difference(const QuicInterval& i,
- std::vector<QuicInterval*>* difference) const {
- if (Empty()) {
- // <empty> - <i> = <empty>
- return false;
- }
- if (i.Empty()) {
- // <this> - <empty> = <this>
- difference->push_back(new QuicInterval(*this));
- return false;
- }
- if (min() < i.max() && min() >= i.min() && max() > i.max()) {
- // [------ this ------)
- // [------ i ------)
- // [-- result ---)
- difference->push_back(new QuicInterval(i.max(), max()));
- return true;
- }
- if (max() > i.min() && max() <= i.max() && min() < i.min()) {
- // [------ this ------)
- // [------ i ------)
- // [- result -)
- difference->push_back(new QuicInterval(min(), i.min()));
- return true;
- }
- if (min() < i.min() && max() > i.max()) {
- // [------- this --------)
- // [---- i ----)
- // [ R1 ) [ R2 )
- // There are two results: R1 and R2.
- difference->push_back(new QuicInterval(min(), i.min()));
- difference->push_back(new QuicInterval(i.max(), max()));
- return true;
- }
- if (min() >= i.min() && max() <= i.max()) {
- // [--- this ---)
- // [------ i --------)
- // Intersection is <this>, so difference yields the empty QuicInterval.
- // Nothing is appended to *difference.
- return true;
- }
- // No intersection. Append <this>.
- difference->push_back(new QuicInterval(*this));
- return false;
-}
-
-template <typename T>
-bool QuicInterval<T>::Difference(const QuicInterval& i,
- QuicInterval* lo,
- QuicInterval* hi) const {
- // Initialize *lo and *hi to empty
- *lo = {};
- *hi = {};
- if (Empty())
- return false;
- if (i.Empty()) {
- *lo = *this;
- return false;
- }
- if (min() < i.max() && min() >= i.min() && max() > i.max()) {
- // [------ this ------)
- // [------ i ------)
- // [-- result ---)
- *hi = QuicInterval(i.max(), max());
- return true;
- }
- if (max() > i.min() && max() <= i.max() && min() < i.min()) {
- // [------ this ------)
- // [------ i ------)
- // [- result -)
- *lo = QuicInterval(min(), i.min());
- return true;
- }
- if (min() < i.min() && max() > i.max()) {
- // [------- this --------)
- // [---- i ----)
- // [ R1 ) [ R2 )
- // There are two results: R1 and R2.
- *lo = QuicInterval(min(), i.min());
- *hi = QuicInterval(i.max(), max());
- return true;
- }
- if (min() >= i.min() && max() <= i.max()) {
- // [--- this ---)
- // [------ i --------)
- // Intersection is <this>, so difference yields the empty QuicInterval.
- return true;
- }
- *lo = *this; // No intersection.
- return false;
-}
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_QUIC_INTERVAL_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_interval_deque.h b/chromium/net/third_party/quiche/src/quic/core/quic_interval_deque.h
deleted file mode 100644
index 274c2e384df..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_interval_deque.h
+++ /dev/null
@@ -1,393 +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_CORE_QUIC_INTERVAL_DEQUE_H_
-#define QUICHE_QUIC_CORE_QUIC_INTERVAL_DEQUE_H_
-
-#include <algorithm>
-
-#include "absl/types/optional.h"
-#include "quic/core/quic_interval.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_export.h"
-#include "quic/platform/api/quic_logging.h"
-#include "common/quiche_circular_deque.h"
-
-namespace quic {
-
-namespace test {
-class QuicIntervalDequePeer;
-} // namespace test
-
-// QuicIntervalDeque<T, C> is a templated wrapper container, wrapping random
-// access data structures. The wrapper allows items to be added to the
-// underlying container with intervals associated with each item. The intervals
-// _should_ be added already sorted and represent searchable indices. The search
-// is optimized for sequential usage.
-//
-// As the intervals are to be searched sequentially the search for the next
-// interval can be achieved in O(1), by simply remembering the last interval
-// consumed. The structure also checks for an "off-by-one" use case wherein the
-// |cached_index_| is off by one index as the caller didn't call operator |++|
-// to increment the index. Other intervals can be found in O(log(n)) as they are
-// binary searchable. A use case for this structure is packet buffering: Packets
-// are sent sequentially but can sometimes needed for retransmission. The
-// packets and their payloads are added with associated intervals representing
-// data ranges they carry. When a user asks for a particular interval it's very
-// likely they are requesting the next sequential interval, receiving it in O(1)
-// time. Updating the sequential index is done automatically through the
-// |DataAt| method and its iterator operator |++|.
-//
-// The intervals are represented using the usual C++ STL convention, namely as
-// the half-open QuicInterval [min, max). A point p is considered to be
-// contained in the QuicInterval iff p >= min && p < max. One consequence of
-// this definition is that for any non-empty QuicInterval, min is contained in
-// the QuicInterval but max is not. There is no canonical representation for the
-// empty QuicInterval; and empty intervals are forbidden from being added to
-// this container as they would be unsearchable.
-//
-// The type T is required to be copy-constructable or move-constructable. The
-// type T is also expected to have an |interval()| method returning a
-// QuicInterval<std::size> for the particular value. The type C is required to
-// be a random access container supporting the methods |pop_front|, |push_back|,
-// |operator[]|, |size|, and iterator support for |std::lower_bound| eg. a
-// |deque| or |vector|.
-//
-// The QuicIntervalDeque<T, C>, like other C++ STL random access containers,
-// doesn't have any explicit support for any equality operators.
-//
-//
-// Examples with internal state:
-//
-// // An example class to be stored inside the Interval Deque.
-// struct IntervalVal {
-// const int32_t val;
-// const size_t interval_begin, interval_end;
-// QuicInterval<size_t> interval();
-// };
-// typedef IntervalVal IV;
-// QuicIntervialDeque<IntervalValue> deque;
-//
-// // State:
-// // cached_index -> None
-// // container -> {}
-//
-// // Add interval items
-// deque.PushBack(IV(val: 0, interval_begin: 0, interval_end: 10));
-// deque.PushBack(IV(val: 1, interval_begin: 20, interval_end: 25));
-// deque.PushBack(IV(val: 2, interval_begin: 25, interval_end: 30));
-//
-// // State:
-// // cached_index -> 0
-// // container -> {{0, [0, 10)}, {1, [20, 25)}, {2, [25, 30)}}
-//
-// // Look for 0 and return [0, 10). Time: O(1)
-// auto it = deque.DataAt(0);
-// assert(it->val == 0);
-// it++; // Increment and move the |cached_index_| over [0, 10) to [20, 25).
-// assert(it->val == 1);
-//
-// // State:
-// // cached_index -> 1
-// // container -> {{0, [0, 10)}, {1, [20, 25)}, {2, [25, 30)}}
-//
-// // Look for 20 and return [20, 25). Time: O(1)
-// auto it = deque.DataAt(20); // |cached_index_| remains unchanged.
-// assert(it->val == 1);
-//
-// // State:
-// // cached_index -> 1
-// // container -> {{0, [0, 10)}, {1, [20, 25)}, {2, [25, 30)}}
-//
-// // Look for 15 and return deque.DataEnd(). Time: O(log(n))
-// auto it = deque.DataAt(15); // |cached_index_| remains unchanged.
-// assert(it == deque.DataEnd());
-//
-// // Look for 25 and return [25, 30). Time: O(1) with off-by-one.
-// auto it = deque.DataAt(25); // |cached_index_| is updated to 2.
-// assert(it->val == 2);
-// it++; // |cached_index_| is set to |None| as all data has been iterated.
-//
-//
-// // State:
-// // cached_index -> None
-// // container -> {{0, [0, 10)}, {1, [20, 25)}, {2, [25, 30)}}
-//
-// // Look again for 0 and return [0, 10). Time: O(log(n))
-// auto it = deque.DataAt(0);
-//
-//
-// deque.PopFront(); // Pop -> {0, [0, 10)}
-//
-// // State:
-// // cached_index -> None
-// // container -> {{1, [20, 25)}, {2, [25, 30)}}
-//
-// deque.PopFront(); // Pop -> {1, [20, 25)}
-//
-// // State:
-// // cached_index -> None
-// // container -> {{2, [25, 30)}}
-//
-// deque.PushBack(IV(val: 3, interval_begin: 35, interval_end: 50));
-//
-// // State:
-// // cached_index -> 1
-// // container -> {{2, [25, 30)}, {3, [35, 50)}}
-
-template <class T, class C = QUIC_NO_EXPORT quiche::QuicheCircularDeque<T>>
-class QUIC_NO_EXPORT QuicIntervalDeque {
- public:
- class QUIC_NO_EXPORT Iterator {
- public:
- // Used by |std::lower_bound|
- using iterator_category = std::forward_iterator_tag;
- using value_type = T;
- using difference_type = std::ptrdiff_t;
- using pointer = T*;
- using reference = T&;
-
- // Every increment of the iterator will increment the |cached_index_| if
- // |index_| is larger than the current |cached_index_|. |index_| is bounded
- // at |deque_.size()| and any attempt to increment above that will be
- // ignored. Once an iterator has iterated all elements the |cached_index_|
- // will be reset.
- Iterator(std::size_t index, QuicIntervalDeque* deque)
- : index_(index), deque_(deque) {}
- // Only the ++ operator attempts to update the cached index. Other operators
- // are used by |lower_bound| to binary search and are thus private.
- Iterator& operator++() {
- // Don't increment when we are at the end.
- const std::size_t container_size = deque_->container_.size();
- if (index_ >= container_size) {
- QUIC_BUG(quic_bug_10862_1) << "Iterator out of bounds.";
- return *this;
- }
- index_++;
- if (deque_->cached_index_.has_value()) {
- const std::size_t cached_index = deque_->cached_index_.value();
- // If all items are iterated then reset the |cached_index_|
- if (index_ == container_size) {
- deque_->cached_index_.reset();
- } else {
- // Otherwise the new |cached_index_| is the max of itself and |index_|
- if (cached_index < index_) {
- deque_->cached_index_ = index_;
- }
- }
- }
- return *this;
- }
- Iterator operator++(int) {
- Iterator copy = *this;
- ++(*this);
- return copy;
- }
- reference operator*() { return deque_->container_[index_]; }
- reference operator*() const { return deque_->container_[index_]; }
- pointer operator->() { return &deque_->container_[index_]; }
- bool operator==(const Iterator& rhs) const {
- return index_ == rhs.index_ && deque_ == rhs.deque_;
- }
- bool operator!=(const Iterator& rhs) const { return !(*this == rhs); }
-
- private:
- // A set of private operators for |std::lower_bound|
- Iterator operator+(difference_type amount) const {
- Iterator copy = *this;
- copy.index_ += amount;
- QUICHE_DCHECK(copy.index_ < copy.deque_->size());
- return copy;
- }
- Iterator& operator+=(difference_type amount) {
- index_ += amount;
- QUICHE_DCHECK(index_ < deque_->size());
- return *this;
- }
- difference_type operator-(const Iterator& rhs) const {
- return static_cast<difference_type>(index_) -
- static_cast<difference_type>(rhs.index_);
- }
-
- // |index_| is the index of the item in |*deque_|.
- std::size_t index_;
- // |deque_| is a pointer to the container the iterator came from.
- QuicIntervalDeque* deque_;
-
- friend class QuicIntervalDeque;
- };
-
- QuicIntervalDeque();
-
- // Adds an item to the underlying container. The |item|'s interval _should_ be
- // strictly greater than the last interval added.
- void PushBack(T&& item);
- void PushBack(const T& item);
- // Removes the front/top of the underlying container and the associated
- // interval.
- void PopFront();
- // Returns an iterator to the beginning of the data. The iterator will move
- // the |cached_index_| as the iterator moves.
- Iterator DataBegin();
- // Returns an iterator to the end of the data.
- Iterator DataEnd();
- // Returns an iterator pointing to the item in |interval_begin|. The iterator
- // will move the |cached_index_| as the iterator moves.
- Iterator DataAt(const std::size_t interval_begin);
-
- // Returns the number of items contained inside the structure.
- std::size_t Size() const;
- // Returns whether the structure is empty.
- bool Empty() const;
-
- private:
- struct QUIC_NO_EXPORT IntervalCompare {
- bool operator()(const T& item, std::size_t interval_begin) const {
- return item.interval().max() <= interval_begin;
- }
- };
-
- template <class U>
- void PushBackUniversal(U&& item);
-
- Iterator Search(const std::size_t interval_begin,
- const std::size_t begin_index,
- const std::size_t end_index);
-
- // For accessing the |cached_index_|
- friend class test::QuicIntervalDequePeer;
-
- C container_;
- absl::optional<std::size_t> cached_index_;
-};
-
-template <class T, class C>
-QuicIntervalDeque<T, C>::QuicIntervalDeque() {}
-
-template <class T, class C>
-void QuicIntervalDeque<T, C>::PushBack(T&& item) {
- PushBackUniversal(std::move(item));
-}
-
-template <class T, class C>
-void QuicIntervalDeque<T, C>::PushBack(const T& item) {
- PushBackUniversal(item);
-}
-
-template <class T, class C>
-void QuicIntervalDeque<T, C>::PopFront() {
- if (container_.size() == 0) {
- QUIC_BUG(quic_bug_10862_2) << "Trying to pop from an empty container.";
- return;
- }
- container_.pop_front();
- if (container_.size() == 0) {
- cached_index_.reset();
- }
- if (cached_index_.value_or(0) > 0) {
- cached_index_ = cached_index_.value() - 1;
- }
-}
-
-template <class T, class C>
-typename QuicIntervalDeque<T, C>::Iterator
-QuicIntervalDeque<T, C>::DataBegin() {
- return Iterator(0, this);
-}
-
-template <class T, class C>
-typename QuicIntervalDeque<T, C>::Iterator QuicIntervalDeque<T, C>::DataEnd() {
- return Iterator(container_.size(), this);
-}
-
-template <class T, class C>
-typename QuicIntervalDeque<T, C>::Iterator QuicIntervalDeque<T, C>::DataAt(
- const std::size_t interval_begin) {
- // No |cached_index_| value means all items can be searched.
- if (!cached_index_.has_value()) {
- return Search(interval_begin, 0, container_.size());
- }
-
- const std::size_t cached_index = cached_index_.value();
- QUICHE_DCHECK(cached_index < container_.size());
-
- const QuicInterval<size_t> cached_interval =
- container_[cached_index].interval();
- // Does our cached index point directly to what we want?
- if (cached_interval.Contains(interval_begin)) {
- return Iterator(cached_index, this);
- }
-
- // Are we off-by-one?
- const std::size_t next_index = cached_index + 1;
- if (next_index < container_.size()) {
- if (container_[next_index].interval().Contains(interval_begin)) {
- cached_index_ = next_index;
- return Iterator(next_index, this);
- }
- }
-
- // Small optimization:
- // Determine if we should binary search above or below the cached interval.
- const std::size_t cached_begin = cached_interval.min();
- bool looking_below = interval_begin < cached_begin;
- const std::size_t lower = looking_below ? 0 : cached_index + 1;
- const std::size_t upper = looking_below ? cached_index : container_.size();
- Iterator ret = Search(interval_begin, lower, upper);
- if (ret == DataEnd()) {
- return ret;
- }
- // Update the |cached_index_| to point to the higher index.
- if (!looking_below) {
- cached_index_ = ret.index_;
- }
- return ret;
-}
-
-template <class T, class C>
-std::size_t QuicIntervalDeque<T, C>::Size() const {
- return container_.size();
-}
-
-template <class T, class C>
-bool QuicIntervalDeque<T, C>::Empty() const {
- return container_.size() == 0;
-}
-
-template <class T, class C>
-template <class U>
-void QuicIntervalDeque<T, C>::PushBackUniversal(U&& item) {
- QuicInterval<std::size_t> interval = item.interval();
- // Adding an empty interval is a bug.
- if (interval.Empty()) {
- QUIC_BUG(quic_bug_10862_3)
- << "Trying to save empty interval to quiche::QuicheCircularDeque.";
- return;
- }
- container_.push_back(std::forward<U>(item));
- if (!cached_index_.has_value()) {
- cached_index_ = container_.size() - 1;
- }
-}
-
-template <class T, class C>
-typename QuicIntervalDeque<T, C>::Iterator QuicIntervalDeque<T, C>::Search(
- const std::size_t interval_begin,
- const std::size_t begin_index,
- const std::size_t end_index) {
- auto begin = container_.begin() + begin_index;
- auto end = container_.begin() + end_index;
- auto res = std::lower_bound(begin, end, interval_begin, IntervalCompare());
- // Just because we run |lower_bound| and it didn't return |container_.end()|
- // doesn't mean we found our desired interval.
- if (res != end && res->interval().Contains(interval_begin)) {
- return Iterator(std::distance(begin, res) + begin_index, this);
- }
- return DataEnd();
-}
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_QUIC_INTERVAL_DEQUE_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_interval_deque_test.cc b/chromium/net/third_party/quiche/src/quic/core/quic_interval_deque_test.cc
deleted file mode 100644
index 71a69cc7793..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_interval_deque_test.cc
+++ /dev/null
@@ -1,360 +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 "quic/core/quic_interval_deque.h"
-#include <cstdint>
-#include <ostream>
-#include "quic/core/quic_interval.h"
-#include "quic/platform/api/quic_expect_bug.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/quic_interval_deque_peer.h"
-#include "quic/test_tools/quic_test_utils.h"
-
-namespace quic {
-namespace test {
-namespace {
-
-const int32_t kSize = 100;
-const std::size_t kIntervalStep = 10;
-
-} // namespace
-
-struct TestIntervalItem {
- int32_t val;
- std::size_t interval_start, interval_end;
- QuicInterval<std::size_t> interval() const {
- return QuicInterval<std::size_t>(interval_start, interval_end);
- }
- TestIntervalItem(int32_t val,
- std::size_t interval_start,
- std::size_t interval_end)
- : val(val), interval_start(interval_start), interval_end(interval_end) {}
-};
-
-using QID = QuicIntervalDeque<TestIntervalItem>;
-
-class QuicIntervalDequeTest : public QuicTest {
- public:
- QuicIntervalDequeTest() {
- // Add items with intervals of |kIntervalStep| size.
- for (int32_t i = 0; i < kSize; ++i) {
- const std::size_t interval_begin = kIntervalStep * i;
- const std::size_t interval_end = interval_begin + kIntervalStep;
- qid_.PushBack(TestIntervalItem(i, interval_begin, interval_end));
- }
- }
-
- QID qid_;
-};
-
-// The goal of this test is to show insertion/push_back, iteration, and and
-// deletion/pop_front from the container.
-TEST_F(QuicIntervalDequeTest, InsertRemoveSize) {
- QID qid;
-
- EXPECT_EQ(qid.Size(), std::size_t(0));
- qid.PushBack(TestIntervalItem(0, 0, 10));
- EXPECT_EQ(qid.Size(), std::size_t(1));
- qid.PushBack(TestIntervalItem(1, 10, 20));
- EXPECT_EQ(qid.Size(), std::size_t(2));
- qid.PushBack(TestIntervalItem(2, 20, 30));
- EXPECT_EQ(qid.Size(), std::size_t(3));
- qid.PushBack(TestIntervalItem(3, 30, 40));
- EXPECT_EQ(qid.Size(), std::size_t(4));
-
- // Advance the index all the way...
- int32_t i = 0;
- for (auto it = qid.DataAt(0); it != qid.DataEnd(); ++it, ++i) {
- const int32_t index = QuicIntervalDequePeer::GetCachedIndex(&qid);
- EXPECT_EQ(index, i);
- EXPECT_EQ(it->val, i);
- }
- const int32_t index = QuicIntervalDequePeer::GetCachedIndex(&qid);
- EXPECT_EQ(index, -1);
-
- qid.PopFront();
- EXPECT_EQ(qid.Size(), std::size_t(3));
- qid.PopFront();
- EXPECT_EQ(qid.Size(), std::size_t(2));
- qid.PopFront();
- EXPECT_EQ(qid.Size(), std::size_t(1));
- qid.PopFront();
- EXPECT_EQ(qid.Size(), std::size_t(0));
-
- EXPECT_QUIC_BUG(qid.PopFront(), "Trying to pop from an empty container.");
-}
-
-// The goal of this test is to push data into the container at specific
-// intervals and show how the |DataAt| method can move the |cached_index| as the
-// iterator moves through the data.
-TEST_F(QuicIntervalDequeTest, InsertIterateWhole) {
- // The write index should point to the beginning of the container.
- const int32_t cached_index = QuicIntervalDequePeer::GetCachedIndex(&qid_);
- EXPECT_EQ(cached_index, 0);
-
- auto it = qid_.DataBegin();
- auto end = qid_.DataEnd();
- for (int32_t i = 0; i < kSize; ++i, ++it) {
- EXPECT_EQ(it->val, i);
- const std::size_t current_iteraval_begin = i * kIntervalStep;
- // The |DataAt| method should find the correct interval.
- auto lookup = qid_.DataAt(current_iteraval_begin);
- EXPECT_EQ(i, lookup->val);
- // Make sure the index hasn't changed just from using |DataAt|
- const int32_t index_before = QuicIntervalDequePeer::GetCachedIndex(&qid_);
- EXPECT_EQ(index_before, i);
- // This increment should move the index forward.
- lookup++;
- // Check that the index has changed.
- const int32_t index_after = QuicIntervalDequePeer::GetCachedIndex(&qid_);
- const int32_t after_i = (i + 1) == kSize ? -1 : (i + 1);
- EXPECT_EQ(index_after, after_i);
- EXPECT_NE(it, end);
- }
-}
-
-// The goal of this test is to push data into the container at specific
-// intervals and show how the |DataAt| method can move the |cached_index| using
-// the off-by-one logic.
-TEST_F(QuicIntervalDequeTest, OffByOne) {
- // The write index should point to the beginning of the container.
- const int32_t cached_index = QuicIntervalDequePeer::GetCachedIndex(&qid_);
- EXPECT_EQ(cached_index, 0);
-
- auto it = qid_.DataBegin();
- auto end = qid_.DataEnd();
- for (int32_t i = 0; i < kSize - 1; ++i, ++it) {
- EXPECT_EQ(it->val, i);
- const int32_t off_by_one_i = i + 1;
- const std::size_t current_iteraval_begin = off_by_one_i * kIntervalStep;
- // Make sure the index has changed just from using |DataAt|
- const int32_t index_before = QuicIntervalDequePeer::GetCachedIndex(&qid_);
- EXPECT_EQ(index_before, i);
- // The |DataAt| method should find the correct interval.
- auto lookup = qid_.DataAt(current_iteraval_begin);
- EXPECT_EQ(off_by_one_i, lookup->val);
- // Check that the index has changed.
- const int32_t index_after = QuicIntervalDequePeer::GetCachedIndex(&qid_);
- const int32_t after_i = off_by_one_i == kSize ? -1 : off_by_one_i;
- EXPECT_EQ(index_after, after_i);
- EXPECT_NE(it, end);
- }
-}
-
-// The goal of this test is to push data into the container at specific
-// intervals and show modify the structure with a live iterator.
-TEST_F(QuicIntervalDequeTest, IteratorInvalidation) {
- // The write index should point to the beginning of the container.
- const int32_t cached_index = QuicIntervalDequePeer::GetCachedIndex(&qid_);
- EXPECT_EQ(cached_index, 0);
-
- const std::size_t iteraval_begin = (kSize - 1) * kIntervalStep;
- auto lookup = qid_.DataAt(iteraval_begin);
- EXPECT_EQ((*lookup).val, (kSize - 1));
- qid_.PopFront();
- EXPECT_QUIC_BUG(lookup++, "Iterator out of bounds.");
- auto lookup_end = qid_.DataAt(iteraval_begin + kIntervalStep);
- EXPECT_EQ(lookup_end, qid_.DataEnd());
-}
-
-// The goal of this test is the same as |InsertIterateWhole| but to
-// skip certain intervals and show the |cached_index| is updated properly.
-TEST_F(QuicIntervalDequeTest, InsertIterateSkip) {
- // The write index should point to the beginning of the container.
- const int32_t cached_index = QuicIntervalDequePeer::GetCachedIndex(&qid_);
- EXPECT_EQ(cached_index, 0);
-
- const std::size_t step = 4;
- for (int32_t i = 0; i < kSize; i += 4) {
- if (i != 0) {
- const int32_t before_i = (i - (step - 1));
- EXPECT_EQ(QuicIntervalDequePeer::GetCachedIndex(&qid_), before_i);
- }
- const std::size_t current_iteraval_begin = i * kIntervalStep;
- // The |DataAt| method should find the correct interval.
- auto lookup = qid_.DataAt(current_iteraval_begin);
- EXPECT_EQ(i, lookup->val);
- // Make sure the index _has_ changed just from using |DataAt| since we're
- // skipping data.
- const int32_t index_before = QuicIntervalDequePeer::GetCachedIndex(&qid_);
- EXPECT_EQ(index_before, i);
- // This increment should move the index forward.
- lookup++;
- // Check that the index has changed.
- const int32_t index_after = QuicIntervalDequePeer::GetCachedIndex(&qid_);
- const int32_t after_i = (i + 1) == kSize ? -1 : (i + 1);
- EXPECT_EQ(index_after, after_i);
- }
-}
-
-// The goal of this test is the same as |InsertIterateWhole| but it has
-// |PopFront| calls interleaved to show the |cached_index| updates correctly.
-TEST_F(QuicIntervalDequeTest, InsertDeleteIterate) {
- // The write index should point to the beginning of the container.
- const int32_t index = QuicIntervalDequePeer::GetCachedIndex(&qid_);
- EXPECT_EQ(index, 0);
-
- std::size_t limit = 0;
- for (int32_t i = 0; limit < qid_.Size(); ++i, ++limit) {
- // Always point to the beginning of the container.
- auto it = qid_.DataBegin();
- EXPECT_EQ(it->val, i);
-
- // Get an iterator.
- const std::size_t current_iteraval_begin = i * kIntervalStep;
- auto lookup = qid_.DataAt(current_iteraval_begin);
- const int32_t index_before = QuicIntervalDequePeer::GetCachedIndex(&qid_);
- // The index should always point to 0.
- EXPECT_EQ(index_before, 0);
- // This iterator increment should effect the index.
- lookup++;
- const int32_t index_after = QuicIntervalDequePeer::GetCachedIndex(&qid_);
- EXPECT_EQ(index_after, 1);
- // Decrement the |temp_size| and pop from the front.
- qid_.PopFront();
- // Show the index has been updated to point to 0 again (from 1).
- const int32_t index_after_pop =
- QuicIntervalDequePeer::GetCachedIndex(&qid_);
- EXPECT_EQ(index_after_pop, 0);
- }
-}
-
-// The goal of this test is to move the index to the end and then add more data
-// to show it can be reset to a valid index.
-TEST_F(QuicIntervalDequeTest, InsertIterateInsert) {
- // The write index should point to the beginning of the container.
- const int32_t index = QuicIntervalDequePeer::GetCachedIndex(&qid_);
- EXPECT_EQ(index, 0);
-
- int32_t iterated_elements = 0;
- for (int32_t i = 0; i < kSize; ++i, ++iterated_elements) {
- // Get an iterator.
- const std::size_t current_iteraval_begin = i * kIntervalStep;
- auto lookup = qid_.DataAt(current_iteraval_begin);
- const int32_t index_before = QuicIntervalDequePeer::GetCachedIndex(&qid_);
- // The index should always point to i.
- EXPECT_EQ(index_before, i);
- // This iterator increment should effect the index.
- lookup++;
- // Show the index has been updated to point to i + 1 or -1 if at the end.
- const int32_t index_after = QuicIntervalDequePeer::GetCachedIndex(&qid_);
- const int32_t after_i = (i + 1) == kSize ? -1 : (i + 1);
- EXPECT_EQ(index_after, after_i);
- }
- const int32_t invalid_index = QuicIntervalDequePeer::GetCachedIndex(&qid_);
- EXPECT_EQ(invalid_index, -1);
-
- // Add more data to the container, making the index valid.
- const std::size_t offset = qid_.Size();
- for (int32_t i = 0; i < kSize; ++i) {
- const std::size_t interval_begin = offset + (kIntervalStep * i);
- const std::size_t interval_end = offset + interval_begin + kIntervalStep;
- qid_.PushBack(TestIntervalItem(i + offset, interval_begin, interval_end));
- const int32_t index_current = QuicIntervalDequePeer::GetCachedIndex(&qid_);
- // Index should now be valid and equal to the size of the container before
- // adding more items to it.
- EXPECT_EQ(index_current, iterated_elements);
- }
- // Show the index is still valid and hasn't changed since the first iteration
- // of the loop.
- const int32_t index_after_add = QuicIntervalDequePeer::GetCachedIndex(&qid_);
- EXPECT_EQ(index_after_add, iterated_elements);
-
- // Iterate over all the data in the container and eventually reset the index
- // as we did before.
- for (int32_t i = 0; i < kSize; ++i, ++iterated_elements) {
- const std::size_t interval_begin = offset + (kIntervalStep * i);
- const int32_t index_current = QuicIntervalDequePeer::GetCachedIndex(&qid_);
- EXPECT_EQ(index_current, iterated_elements);
- auto lookup = qid_.DataAt(interval_begin);
- const int32_t expected_value = i + offset;
- EXPECT_EQ(lookup->val, expected_value);
- lookup++;
- const int32_t after_inc =
- (iterated_elements + 1) == (kSize * 2) ? -1 : (iterated_elements + 1);
- const int32_t after_index = QuicIntervalDequePeer::GetCachedIndex(&qid_);
- EXPECT_EQ(after_index, after_inc);
- }
- // Show the index is now invalid.
- const int32_t invalid_index_again =
- QuicIntervalDequePeer::GetCachedIndex(&qid_);
- EXPECT_EQ(invalid_index_again, -1);
-}
-
-// The goal of this test is to push data into the container at specific
-// intervals and show how the |DataAt| can iterate over already scanned data.
-TEST_F(QuicIntervalDequeTest, RescanData) {
- // The write index should point to the beginning of the container.
- const int32_t index = QuicIntervalDequePeer::GetCachedIndex(&qid_);
- EXPECT_EQ(index, 0);
-
- auto it = qid_.DataBegin();
- auto end = qid_.DataEnd();
- for (int32_t i = 0; i < kSize - 1; ++i, ++it) {
- EXPECT_EQ(it->val, i);
- const std::size_t current_iteraval_begin = i * kIntervalStep;
- // The |DataAt| method should find the correct interval.
- auto lookup = qid_.DataAt(current_iteraval_begin);
- EXPECT_EQ(i, lookup->val);
- // Make sure the index has changed just from using |DataAt|
- const int32_t cached_index_before =
- QuicIntervalDequePeer::GetCachedIndex(&qid_);
- EXPECT_EQ(cached_index_before, i);
- // Ensure the real index has changed just from using |DataAt| and the
- // off-by-one logic
- const int32_t index_before = QuicIntervalDequePeer::GetCachedIndex(&qid_);
- const int32_t before_i = i;
- EXPECT_EQ(index_before, before_i);
- // This increment should move the cached index forward.
- lookup++;
- // Check that the cached index has moved foward.
- const int32_t cached_index_after =
- QuicIntervalDequePeer::GetCachedIndex(&qid_);
- const int32_t after_i = (i + 1);
- EXPECT_EQ(cached_index_after, after_i);
- EXPECT_NE(it, end);
- }
-
- // Iterate over items which have been consumed before.
- int32_t expected_index = static_cast<int32_t>(kSize - 1);
- for (int32_t i = 0; i < kSize - 1; ++i) {
- const std::size_t current_iteraval_begin = i * kIntervalStep;
- // The |DataAt| method should find the correct interval.
- auto lookup = qid_.DataAt(current_iteraval_begin);
- EXPECT_EQ(i, lookup->val);
- // This increment shouldn't move the index forward as the index is currently
- // ahead.
- lookup++;
- // Check that the index hasn't moved foward.
- const int32_t index_after = QuicIntervalDequePeer::GetCachedIndex(&qid_);
- EXPECT_EQ(index_after, expected_index);
- EXPECT_NE(it, end);
- }
-}
-
-// The goal of this test is to show that popping from an empty container is a
-// bug.
-TEST_F(QuicIntervalDequeTest, PopEmpty) {
- QID qid;
- EXPECT_TRUE(qid.Empty());
- EXPECT_QUIC_BUG(qid.PopFront(), "Trying to pop from an empty container.");
-}
-
-// The goal of this test is to show that adding a zero-sized interval is a bug.
-TEST_F(QuicIntervalDequeTest, ZeroSizedInterval) {
- QID qid;
- EXPECT_QUIC_BUG(qid.PushBack(TestIntervalItem(0, 0, 0)),
- "Trying to save empty interval to .");
-}
-
-// The goal of this test is to show that an iterator to an empty container
-// returns |DataEnd|.
-TEST_F(QuicIntervalDequeTest, IteratorEmpty) {
- QID qid;
- auto it = qid.DataAt(0);
- EXPECT_EQ(it, qid.DataEnd());
-}
-
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_interval_set.h b/chromium/net/third_party/quiche/src/quic/core/quic_interval_set.h
deleted file mode 100644
index d69fa710604..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_interval_set.h
+++ /dev/null
@@ -1,896 +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_CORE_QUIC_INTERVAL_SET_H_
-#define QUICHE_QUIC_CORE_QUIC_INTERVAL_SET_H_
-
-// QuicIntervalSet<T> is a data structure used to represent a sorted set of
-// non-empty, non-adjacent, and mutually disjoint intervals. Mutations to an
-// interval set preserve these properties, altering the set as needed. For
-// example, adding [2, 3) to a set containing only [1, 2) would result in the
-// set containing the single interval [1, 3).
-//
-// Supported operations include testing whether an Interval is contained in the
-// QuicIntervalSet, comparing two QuicIntervalSets, and performing
-// QuicIntervalSet union, intersection, and difference.
-//
-// QuicIntervalSet maintains the minimum number of entries needed to represent
-// the set of underlying intervals. When the QuicIntervalSet is modified (e.g.
-// due to an Add operation), other interval entries may be coalesced, removed,
-// or otherwise modified in order to maintain this invariant. The intervals are
-// maintained in sorted order, by ascending min() value.
-//
-// The reader is cautioned to beware of the terminology used here: this library
-// uses the terms "min" and "max" rather than "begin" and "end" as is
-// conventional for the STL. The terminology [min, max) refers to the half-open
-// interval which (if the interval is not empty) contains min but does not
-// contain max. An interval is considered empty if min >= max.
-//
-// T is required to be default- and copy-constructible, to have an assignment
-// operator, a difference operator (operator-()), and the full complement of
-// comparison operators (<, <=, ==, !=, >=, >). These requirements are inherited
-// from value_type.
-//
-// QuicIntervalSet has constant-time move operations.
-//
-//
-// Examples:
-// QuicIntervalSet<int> intervals;
-// intervals.Add(Interval<int>(10, 20));
-// intervals.Add(Interval<int>(30, 40));
-// // intervals contains [10,20) and [30,40).
-// intervals.Add(Interval<int>(15, 35));
-// // intervals has been coalesced. It now contains the single range [10,40).
-// EXPECT_EQ(1, intervals.Size());
-// EXPECT_TRUE(intervals.Contains(Interval<int>(10, 40)));
-//
-// intervals.Difference(Interval<int>(10, 20));
-// // intervals should now contain the single range [20, 40).
-// EXPECT_EQ(1, intervals.Size());
-// EXPECT_TRUE(intervals.Contains(Interval<int>(20, 40)));
-
-#include <stddef.h>
-#include <algorithm>
-#include <initializer_list>
-#include <set>
-#include <utility>
-#include <vector>
-
-#include <string>
-
-#include "quic/core/quic_interval.h"
-#include "quic/platform/api/quic_containers.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-template <typename T>
-class QUIC_NO_EXPORT QuicIntervalSet {
- public:
- using value_type = QuicInterval<T>;
-
- private:
- struct QUIC_NO_EXPORT IntervalLess {
- using is_transparent = void;
- bool operator()(const value_type& a, const value_type& b) const;
- // These transparent overloads are used when we do all of our searches (via
- // Set::lower_bound() and Set::upper_bound()), which avoids the need to
- // construct an interval when we are looking for a point and also avoids
- // needing to worry about comparing overlapping intervals in the overload
- // that takes two value_types (the one just above this comment).
- bool operator()(const value_type& a, const T& point) const;
- bool operator()(const value_type& a, T&& point) const;
- bool operator()(const T& point, const value_type& a) const;
- bool operator()(T&& point, const value_type& a) const;
- };
-
- using Set = QuicSmallOrderedSet<value_type, IntervalLess>;
-
- public:
- using const_iterator = typename Set::const_iterator;
- using const_reverse_iterator = typename Set::const_reverse_iterator;
-
- // Instantiates an empty QuicIntervalSet.
- QuicIntervalSet() = default;
-
- // Instantiates a QuicIntervalSet containing exactly one initial half-open
- // interval [min, max), unless the given interval is empty, in which case the
- // QuicIntervalSet will be empty.
- explicit QuicIntervalSet(const value_type& interval) { Add(interval); }
-
- // Instantiates a QuicIntervalSet containing the half-open interval [min,
- // max).
- QuicIntervalSet(const T& min, const T& max) { Add(min, max); }
-
- QuicIntervalSet(std::initializer_list<value_type> il) { assign(il); }
-
- // Clears this QuicIntervalSet.
- void Clear() { intervals_.clear(); }
-
- // Returns the number of disjoint intervals contained in this QuicIntervalSet.
- size_t Size() const { return intervals_.size(); }
-
- // Returns the smallest interval that contains all intervals in this
- // QuicIntervalSet, or the empty interval if the set is empty.
- value_type SpanningInterval() const;
-
- // Adds "interval" to this QuicIntervalSet. Adding the empty interval has no
- // effect.
- void Add(const value_type& interval);
-
- // Adds the interval [min, max) to this QuicIntervalSet. Adding the empty
- // interval has no effect.
- void Add(const T& min, const T& max) { Add(value_type(min, max)); }
-
- // Same semantics as Add(const value_type&), but optimized for the case where
- // rbegin()->min() <= |interval|.min() <= rbegin()->max().
- void AddOptimizedForAppend(const value_type& interval) {
- if (Empty()) {
- Add(interval);
- return;
- }
-
- const_reverse_iterator last_interval = intervals_.rbegin();
-
- // If interval.min() is outside of [last_interval->min, last_interval->max],
- // we can not simply extend last_interval->max.
- if (interval.min() < last_interval->min() ||
- interval.min() > last_interval->max()) {
- Add(interval);
- return;
- }
-
- if (interval.max() <= last_interval->max()) {
- // interval is fully contained by last_interval.
- return;
- }
-
- // Extend last_interval.max to interval.max, in place.
- //
- // Set does not allow in-place updates due to the potential of violating its
- // ordering requirements. But we know setting the max of the last interval
- // is safe w.r.t set ordering and other invariants of QuicIntervalSet, so we
- // force an in-place update for performance.
- const_cast<value_type*>(&(*last_interval))->SetMax(interval.max());
- }
-
- // Same semantics as Add(const T&, const T&), but optimized for the case where
- // rbegin()->max() == |min|.
- void AddOptimizedForAppend(const T& min, const T& max) {
- AddOptimizedForAppend(value_type(min, max));
- }
-
- // TODO(wub): Similar to AddOptimizedForAppend, we can also have a
- // AddOptimizedForPrepend if there is a use case.
-
- // Remove the first interval.
- // REQUIRES: !Empty()
- void PopFront() {
- QUICHE_DCHECK(!Empty());
- intervals_.erase(intervals_.begin());
- }
-
- // Trim all values that are smaller than |value|. Which means
- // a) If all values in an interval is smaller than |value|, the entire
- // interval is removed.
- // b) If some but not all values in an interval is smaller than |value|, the
- // min of that interval is raised to |value|.
- // Returns true if some intervals are trimmed.
- bool TrimLessThan(const T& value) {
- // Number of intervals that are fully or partially trimmed.
- size_t num_intervals_trimmed = 0;
-
- while (!intervals_.empty()) {
- const_iterator first_interval = intervals_.begin();
- if (first_interval->min() >= value) {
- break;
- }
-
- ++num_intervals_trimmed;
-
- if (first_interval->max() <= value) {
- // a) Trim the entire interval.
- intervals_.erase(first_interval);
- continue;
- }
-
- // b) Trim a prefix of the interval.
- //
- // Set does not allow in-place updates due to the potential of violating
- // its ordering requirements. But increasing the min of the first interval
- // will not break the ordering, hence the const_cast.
- const_cast<value_type*>(&(*first_interval))->SetMin(value);
- break;
- }
-
- return num_intervals_trimmed != 0;
- }
-
- // Returns true if this QuicIntervalSet is empty.
- bool Empty() const { return intervals_.empty(); }
-
- // Returns true if any interval in this QuicIntervalSet contains the indicated
- // value.
- bool Contains(const T& value) const;
-
- // Returns true if there is some interval in this QuicIntervalSet that wholly
- // contains the given interval. An interval O "wholly contains" a non-empty
- // interval I if O.Contains(p) is true for every p in I. This is the same
- // definition used by value_type::Contains(). This method returns false on
- // the empty interval, due to a (perhaps unintuitive) convention inherited
- // from value_type.
- // Example:
- // Assume an QuicIntervalSet containing the entries { [10,20), [30,40) }.
- // Contains(Interval(15, 16)) returns true, because [10,20) contains
- // [15,16). However, Contains(Interval(15, 35)) returns false.
- bool Contains(const value_type& interval) const;
-
- // Returns true if for each interval in "other", there is some (possibly
- // different) interval in this QuicIntervalSet which wholly contains it. See
- // Contains(const value_type& interval) for the meaning of "wholly contains".
- // Perhaps unintuitively, this method returns false if "other" is the empty
- // set. The algorithmic complexity of this method is O(other.Size() *
- // log(this->Size())). The method could be rewritten to run in O(other.Size()
- // + this->Size()), and this alternative could be implemented as a free
- // function using the public API.
- bool Contains(const QuicIntervalSet<T>& other) const;
-
- // Returns true if there is some interval in this QuicIntervalSet that wholly
- // contains the interval [min, max). See Contains(const value_type&).
- bool Contains(const T& min, const T& max) const {
- return Contains(value_type(min, max));
- }
-
- // Returns true if for some interval in "other", there is some interval in
- // this QuicIntervalSet that intersects with it. See value_type::Intersects()
- // for the definition of interval intersection. Runs in time O(n+m) where n
- // is the number of intervals in this and m is the number of intervals in
- // other.
- bool Intersects(const QuicIntervalSet& other) const;
-
- // Returns an iterator to the value_type in the QuicIntervalSet that contains
- // the given value. In other words, returns an iterator to the unique interval
- // [min, max) in the QuicIntervalSet that has the property min <= value < max.
- // If there is no such interval, this method returns end().
- const_iterator Find(const T& value) const;
-
- // Returns an iterator to the value_type in the QuicIntervalSet that wholly
- // contains the given interval. In other words, returns an iterator to the
- // unique interval outer in the QuicIntervalSet that has the property that
- // outer.Contains(interval). If there is no such interval, or if interval is
- // empty, returns end().
- const_iterator Find(const value_type& interval) const;
-
- // Returns an iterator to the value_type in the QuicIntervalSet that wholly
- // contains [min, max). In other words, returns an iterator to the unique
- // interval outer in the QuicIntervalSet that has the property that
- // outer.Contains(Interval<T>(min, max)). If there is no such interval, or if
- // interval is empty, returns end().
- const_iterator Find(const T& min, const T& max) const {
- return Find(value_type(min, max));
- }
-
- // Returns an iterator pointing to the first value_type which contains or
- // goes after the given value.
- //
- // Example:
- // [10, 20) [30, 40)
- // ^ LowerBound(10)
- // ^ LowerBound(15)
- // ^ LowerBound(20)
- // ^ LowerBound(25)
- const_iterator LowerBound(const T& value) const;
-
- // Returns an iterator pointing to the first value_type which goes after
- // the given value.
- //
- // Example:
- // [10, 20) [30, 40)
- // ^ UpperBound(10)
- // ^ UpperBound(15)
- // ^ UpperBound(20)
- // ^ UpperBound(25)
- const_iterator UpperBound(const T& value) const;
-
- // Returns true if every value within the passed interval is not Contained
- // within the QuicIntervalSet.
- // Note that empty intervals are always considered disjoint from the
- // QuicIntervalSet (even though the QuicIntervalSet doesn't `Contain` them).
- bool IsDisjoint(const value_type& interval) const;
-
- // Merges all the values contained in "other" into this QuicIntervalSet.
- //
- // Performance: Let n == Size() and m = other.Size(). Union() runs in O(m)
- // Set operations, so that if Set is a tree, it runs in time O(m log(n+m)) and
- // if Set is a flat_set it runs in time O(m(n+m)). In principle, for the
- // flat_set, we should be able to make this run in time O(n+m).
- //
- // TODO(bradleybear): Make Union() run in time O(n+m) for flat_set. This may
- // require an additional template parameter to indicate that the Set is a
- // linear-time data structure instead of a log-time data structure.
- void Union(const QuicIntervalSet& other);
-
- // Modifies this QuicIntervalSet so that it contains only those values that
- // are currently present both in *this and in the QuicIntervalSet "other".
- void Intersection(const QuicIntervalSet& other);
-
- // Mutates this QuicIntervalSet so that it contains only those values that are
- // currently in *this but not in "interval".
- void Difference(const value_type& interval);
-
- // Mutates this QuicIntervalSet so that it contains only those values that are
- // currently in *this but not in the interval [min, max).
- void Difference(const T& min, const T& max);
-
- // Mutates this QuicIntervalSet so that it contains only those values that are
- // currently in *this but not in the QuicIntervalSet "other". Runs in time
- // O(n+m) where n is this->Size(), m is other.Size(), regardless of whether
- // the Set is a flat_set or a std::set.
- void Difference(const QuicIntervalSet& other);
-
- // Mutates this QuicIntervalSet so that it contains only those values that are
- // in [min, max) but not currently in *this.
- void Complement(const T& min, const T& max);
-
- // QuicIntervalSet's begin() iterator. The invariants of QuicIntervalSet
- // guarantee that for each entry e in the set, e.min() < e.max() (because the
- // entries are non-empty) and for each entry f that appears later in the set,
- // e.max() < f.min() (because the entries are ordered, pairwise-disjoint, and
- // non-adjacent). Modifications to this QuicIntervalSet invalidate these
- // iterators.
- const_iterator begin() const { return intervals_.begin(); }
-
- // QuicIntervalSet's end() iterator.
- const_iterator end() const { return intervals_.end(); }
-
- // QuicIntervalSet's rbegin() and rend() iterators. Iterator invalidation
- // semantics are the same as those for begin() / end().
- const_reverse_iterator rbegin() const { return intervals_.rbegin(); }
-
- const_reverse_iterator rend() const { return intervals_.rend(); }
-
- template <typename Iter>
- void assign(Iter first, Iter last) {
- Clear();
- for (; first != last; ++first)
- Add(*first);
- }
-
- void assign(std::initializer_list<value_type> il) {
- assign(il.begin(), il.end());
- }
-
- // Returns a human-readable representation of this set. This will typically be
- // (though is not guaranteed to be) of the form
- // "[a1, b1) [a2, b2) ... [an, bn)"
- // where the intervals are in the same order as given by traversal from
- // begin() to end(). This representation is intended for human consumption;
- // computer programs should not rely on the output being in exactly this form.
- std::string ToString() const;
-
- QuicIntervalSet& operator=(std::initializer_list<value_type> il) {
- assign(il.begin(), il.end());
- return *this;
- }
-
- friend bool operator==(const QuicIntervalSet& a, const QuicIntervalSet& b) {
- return a.Size() == b.Size() &&
- std::equal(a.begin(), a.end(), b.begin(), NonemptyIntervalEq());
- }
-
- friend bool operator!=(const QuicIntervalSet& a, const QuicIntervalSet& b) {
- return !(a == b);
- }
-
- private:
- // Simple member-wise equality, since all intervals are non-empty.
- struct QUIC_NO_EXPORT NonemptyIntervalEq {
- bool operator()(const value_type& a, const value_type& b) const {
- return a.min() == b.min() && a.max() == b.max();
- }
- };
-
- // Returns true if this set is valid (i.e. all intervals in it are non-empty,
- // non-adjacent, and mutually disjoint). Currently this is used as an
- // integrity check by the Intersection() and Difference() methods, but is only
- // invoked for debug builds (via QUICHE_DCHECK).
- bool Valid() const;
-
- // Finds the first interval that potentially intersects 'other'.
- const_iterator FindIntersectionCandidate(const QuicIntervalSet& other) const;
-
- // Finds the first interval that potentially intersects 'interval'. More
- // precisely, return an interator it pointing at the last interval J such that
- // interval <= J. If all the intervals are > J then return begin().
- const_iterator FindIntersectionCandidate(const value_type& interval) const;
-
- // Helper for Intersection() and Difference(): Finds the next pair of
- // intervals from 'x' and 'y' that intersect. 'mine' is an iterator
- // over x->intervals_. 'theirs' is an iterator over y.intervals_. 'mine'
- // and 'theirs' are advanced until an intersecting pair is found.
- // Non-intersecting intervals (aka "holes") from x->intervals_ can be
- // optionally erased by "on_hole". "on_hole" must return an iterator to the
- // first element in 'x' after the hole, or x->intervals_.end() if no elements
- // exist after the hole.
- template <typename X, typename Func>
- static bool FindNextIntersectingPairImpl(X* x,
- const QuicIntervalSet& y,
- const_iterator* mine,
- const_iterator* theirs,
- Func on_hole);
-
- // The variant of the above method that doesn't mutate this QuicIntervalSet.
- bool FindNextIntersectingPair(const QuicIntervalSet& other,
- const_iterator* mine,
- const_iterator* theirs) const {
- return FindNextIntersectingPairImpl(
- this, other, mine, theirs,
- [](const QuicIntervalSet*, const_iterator, const_iterator end) {
- return end;
- });
- }
-
- // The variant of the above method that mutates this QuicIntervalSet by
- // erasing holes.
- bool FindNextIntersectingPairAndEraseHoles(const QuicIntervalSet& other,
- const_iterator* mine,
- const_iterator* theirs) {
- return FindNextIntersectingPairImpl(
- this, other, mine, theirs,
- [](QuicIntervalSet* x, const_iterator from, const_iterator to) {
- return x->intervals_.erase(from, to);
- });
- }
-
- // The representation for the intervals. The intervals in this set are
- // non-empty, pairwise-disjoint, non-adjacent and ordered in ascending order
- // by min().
- Set intervals_;
-};
-
-template <typename T>
-auto operator<<(std::ostream& out, const QuicIntervalSet<T>& seq)
- -> decltype(out << *seq.begin()) {
- out << "{";
- for (const auto& interval : seq) {
- out << " " << interval;
- }
- out << " }";
-
- return out;
-}
-
-//==============================================================================
-// Implementation details: Clients can stop reading here.
-
-template <typename T>
-typename QuicIntervalSet<T>::value_type QuicIntervalSet<T>::SpanningInterval()
- const {
- value_type result;
- if (!intervals_.empty()) {
- result.SetMin(intervals_.begin()->min());
- result.SetMax(intervals_.rbegin()->max());
- }
- return result;
-}
-
-template <typename T>
-void QuicIntervalSet<T>::Add(const value_type& interval) {
- if (interval.Empty())
- return;
- const_iterator it = intervals_.lower_bound(interval.min());
- value_type the_union = interval;
- if (it != intervals_.begin()) {
- --it;
- if (it->Separated(the_union)) {
- ++it;
- }
- }
- // Don't erase the elements one at a time, since that will produce quadratic
- // work on a flat_set, and apparently an extra log-factor of work for a
- // tree-based set. Instead identify the first and last intervals that need to
- // be erased, and call erase only once.
- const_iterator start = it;
- while (it != intervals_.end() && !it->Separated(the_union)) {
- the_union.SpanningUnion(*it);
- ++it;
- }
- intervals_.erase(start, it);
- intervals_.insert(the_union);
-}
-
-template <typename T>
-bool QuicIntervalSet<T>::Contains(const T& value) const {
- // Find the first interval with min() > value, then move back one step
- const_iterator it = intervals_.upper_bound(value);
- if (it == intervals_.begin())
- return false;
- --it;
- return it->Contains(value);
-}
-
-template <typename T>
-bool QuicIntervalSet<T>::Contains(const value_type& interval) const {
- // Find the first interval with min() > value, then move back one step.
- const_iterator it = intervals_.upper_bound(interval.min());
- if (it == intervals_.begin())
- return false;
- --it;
- return it->Contains(interval);
-}
-
-template <typename T>
-bool QuicIntervalSet<T>::Contains(const QuicIntervalSet<T>& other) const {
- if (!SpanningInterval().Contains(other.SpanningInterval())) {
- return false;
- }
-
- for (const_iterator i = other.begin(); i != other.end(); ++i) {
- // If we don't contain the interval, can return false now.
- if (!Contains(*i)) {
- return false;
- }
- }
- return true;
-}
-
-// This method finds the interval that Contains() "value", if such an interval
-// exists in the QuicIntervalSet. The way this is done is to locate the
-// "candidate interval", the only interval that could *possibly* contain value,
-// and test it using Contains(). The candidate interval is the interval with the
-// largest min() having min() <= value.
-//
-// Another detail involves the choice of which Set method to use to try to find
-// the candidate interval. The most appropriate entry point is
-// Set::upper_bound(), which finds the least interval with a min > the
-// value. The semantics of upper_bound() are slightly different from what we
-// want (namely, to find the greatest interval which is <= the probe interval)
-// but they are close enough; the interval found by upper_bound() will always be
-// one step past the interval we are looking for (if it exists) or at begin()
-// (if it does not). Getting to the proper interval is a simple matter of
-// decrementing the iterator.
-template <typename T>
-typename QuicIntervalSet<T>::const_iterator QuicIntervalSet<T>::Find(
- const T& value) const {
- const_iterator it = intervals_.upper_bound(value);
- if (it == intervals_.begin())
- return intervals_.end();
- --it;
- if (it->Contains(value))
- return it;
- else
- return intervals_.end();
-}
-
-// This method finds the interval that Contains() the interval "probe", if such
-// an interval exists in the QuicIntervalSet. The way this is done is to locate
-// the "candidate interval", the only interval that could *possibly* contain
-// "probe", and test it using Contains(). We use the same algorithm as for
-// Find(value), except that instead of checking that the value is contained, we
-// check that the probe is contained.
-template <typename T>
-typename QuicIntervalSet<T>::const_iterator QuicIntervalSet<T>::Find(
- const value_type& probe) const {
- const_iterator it = intervals_.upper_bound(probe.min());
- if (it == intervals_.begin())
- return intervals_.end();
- --it;
- if (it->Contains(probe))
- return it;
- else
- return intervals_.end();
-}
-
-template <typename T>
-typename QuicIntervalSet<T>::const_iterator QuicIntervalSet<T>::LowerBound(
- const T& value) const {
- const_iterator it = intervals_.lower_bound(value);
- if (it == intervals_.begin()) {
- return it;
- }
-
- // The previous intervals_.lower_bound() checking is essentially based on
- // interval.min(), so we need to check whether the `value` is contained in
- // the previous interval.
- --it;
- if (it->Contains(value)) {
- return it;
- } else {
- return ++it;
- }
-}
-
-template <typename T>
-typename QuicIntervalSet<T>::const_iterator QuicIntervalSet<T>::UpperBound(
- const T& value) const {
- return intervals_.upper_bound(value);
-}
-
-template <typename T>
-bool QuicIntervalSet<T>::IsDisjoint(const value_type& interval) const {
- if (interval.Empty())
- return true;
- // Find the first interval with min() > interval.min()
- const_iterator it = intervals_.upper_bound(interval.min());
- if (it != intervals_.end() && interval.max() > it->min())
- return false;
- if (it == intervals_.begin())
- return true;
- --it;
- return it->max() <= interval.min();
-}
-
-template <typename T>
-void QuicIntervalSet<T>::Union(const QuicIntervalSet& other) {
- for (const value_type& interval : other.intervals_) {
- Add(interval);
- }
-}
-
-template <typename T>
-typename QuicIntervalSet<T>::const_iterator
-QuicIntervalSet<T>::FindIntersectionCandidate(
- const QuicIntervalSet& other) const {
- return FindIntersectionCandidate(*other.intervals_.begin());
-}
-
-template <typename T>
-typename QuicIntervalSet<T>::const_iterator
-QuicIntervalSet<T>::FindIntersectionCandidate(
- const value_type& interval) const {
- // Use upper_bound to efficiently find the first interval in intervals_
- // where min() is greater than interval.min(). If the result
- // isn't the beginning of intervals_ then move backwards one interval since
- // the interval before it is the first candidate where max() may be
- // greater than interval.min().
- // In other words, no interval before that can possibly intersect with any
- // of other.intervals_.
- const_iterator mine = intervals_.upper_bound(interval.min());
- if (mine != intervals_.begin()) {
- --mine;
- }
- return mine;
-}
-
-template <typename T>
-template <typename X, typename Func>
-bool QuicIntervalSet<T>::FindNextIntersectingPairImpl(X* x,
- const QuicIntervalSet& y,
- const_iterator* mine,
- const_iterator* theirs,
- Func on_hole) {
- QUICHE_CHECK(x != nullptr);
- if ((*mine == x->intervals_.end()) || (*theirs == y.intervals_.end())) {
- return false;
- }
- while (!(**mine).Intersects(**theirs)) {
- const_iterator erase_first = *mine;
- // Skip over intervals in 'mine' that don't reach 'theirs'.
- while (*mine != x->intervals_.end() && (**mine).max() <= (**theirs).min()) {
- ++(*mine);
- }
- *mine = on_hole(x, erase_first, *mine);
- // We're done if the end of intervals_ is reached.
- if (*mine == x->intervals_.end()) {
- return false;
- }
- // Skip over intervals 'theirs' that don't reach 'mine'.
- while (*theirs != y.intervals_.end() &&
- (**theirs).max() <= (**mine).min()) {
- ++(*theirs);
- }
- // If the end of other.intervals_ is reached, we're done.
- if (*theirs == y.intervals_.end()) {
- on_hole(x, *mine, x->intervals_.end());
- return false;
- }
- }
- return true;
-}
-
-template <typename T>
-void QuicIntervalSet<T>::Intersection(const QuicIntervalSet& other) {
- if (!SpanningInterval().Intersects(other.SpanningInterval())) {
- intervals_.clear();
- return;
- }
-
- const_iterator mine = FindIntersectionCandidate(other);
- // Remove any intervals that cannot possibly intersect with other.intervals_.
- mine = intervals_.erase(intervals_.begin(), mine);
- const_iterator theirs = other.FindIntersectionCandidate(*this);
-
- while (FindNextIntersectingPairAndEraseHoles(other, &mine, &theirs)) {
- // OK, *mine and *theirs intersect. Now, we find the largest
- // span of intervals in other (starting at theirs) - say [a..b]
- // - that intersect *mine, and we replace *mine with (*mine
- // intersect x) for all x in [a..b] Note that subsequent
- // intervals in this can't intersect any intervals in [a..b) --
- // they may only intersect b or subsequent intervals in other.
- value_type i(*mine);
- intervals_.erase(mine);
- mine = intervals_.end();
- value_type intersection;
- while (theirs != other.intervals_.end() &&
- i.Intersects(*theirs, &intersection)) {
- std::pair<const_iterator, bool> ins = intervals_.insert(intersection);
- QUICHE_DCHECK(ins.second);
- mine = ins.first;
- ++theirs;
- }
- QUICHE_DCHECK(mine != intervals_.end());
- --theirs;
- ++mine;
- }
- QUICHE_DCHECK(Valid());
-}
-
-template <typename T>
-bool QuicIntervalSet<T>::Intersects(const QuicIntervalSet& other) const {
- // Don't bother to handle nonoverlapping spanning intervals as a special case.
- // This code runs in time O(n+m), as guaranteed, even for that case .
- // Handling the nonoverlapping spanning intervals as a special case doesn't
- // improve the asymptotics but does make the code more complex.
- auto mine = intervals_.begin();
- auto theirs = other.intervals_.begin();
- while (mine != intervals_.end() && theirs != other.intervals_.end()) {
- if (mine->Intersects(*theirs))
- return true;
- else if (*mine < *theirs)
- ++mine;
- else
- ++theirs;
- }
- return false;
-}
-
-template <typename T>
-void QuicIntervalSet<T>::Difference(const value_type& interval) {
- if (!SpanningInterval().Intersects(interval)) {
- return;
- }
- Difference(QuicIntervalSet<T>(interval));
-}
-
-template <typename T>
-void QuicIntervalSet<T>::Difference(const T& min, const T& max) {
- Difference(value_type(min, max));
-}
-
-template <typename T>
-void QuicIntervalSet<T>::Difference(const QuicIntervalSet& other) {
- // In order to avoid quadratic-time when using a flat set, we don't try to
- // update intervals_ in place. Instead we build up a new result_, always
- // inserting at the end which is O(1) time per insertion. Since the number of
- // elements in the result is O(Size() + other.Size()), the cost for all the
- // insertions is also O(Size() + other.Size()).
- //
- // We look at all the elements of intervals_, so that's O(Size()).
- //
- // We also look at all the elements of other.intervals_, for O(other.Size()).
- if (Empty())
- return;
- Set result;
- const_iterator mine = intervals_.begin();
- value_type myinterval = *mine;
- const_iterator theirs = other.intervals_.begin();
- while (mine != intervals_.end()) {
- // Loop invariants:
- // myinterval is nonempty.
- // mine points at a range that is a suffix of myinterval.
- QUICHE_DCHECK(!myinterval.Empty());
- QUICHE_DCHECK(myinterval.max() == mine->max());
-
- // There are 3 cases.
- // myinterval is completely before theirs (treat theirs==end() as if it is
- // infinity).
- // --> consume myinterval into result.
- // myinterval is completely after theirs
- // --> theirs can no longer affect us, so ++theirs.
- // myinterval touches theirs with a prefix of myinterval not touching
- // *theirs.
- // --> consume the prefix of myinterval into the result.
- // myinterval touches theirs, with the first element of myinterval in
- // *theirs.
- // -> reduce myinterval
- if (theirs == other.intervals_.end() || myinterval.max() <= theirs->min()) {
- // Keep all of my_interval.
- result.insert(result.end(), myinterval);
- myinterval.Clear();
- } else if (theirs->max() <= myinterval.min()) {
- ++theirs;
- } else if (myinterval.min() < theirs->min()) {
- // Keep a nonempty prefix of my interval.
- result.insert(result.end(), value_type(myinterval.min(), theirs->min()));
- myinterval.SetMin(theirs->max());
- } else {
- // myinterval starts at or after *theirs, chop down myinterval.
- myinterval.SetMin(theirs->max());
- }
- // if myinterval became empty, find the next interval
- if (myinterval.Empty()) {
- ++mine;
- if (mine != intervals_.end()) {
- myinterval = *mine;
- }
- }
- }
- std::swap(result, intervals_);
- QUICHE_DCHECK(Valid());
-}
-
-template <typename T>
-void QuicIntervalSet<T>::Complement(const T& min, const T& max) {
- QuicIntervalSet<T> span(min, max);
- span.Difference(*this);
- intervals_.swap(span.intervals_);
-}
-
-template <typename T>
-std::string QuicIntervalSet<T>::ToString() const {
- std::ostringstream os;
- os << *this;
- return os.str();
-}
-
-template <typename T>
-bool QuicIntervalSet<T>::Valid() const {
- const_iterator prev = end();
- for (const_iterator it = begin(); it != end(); ++it) {
- // invalid or empty interval.
- if (it->min() >= it->max())
- return false;
- // Not sorted, not disjoint, or adjacent.
- if (prev != end() && prev->max() >= it->min())
- return false;
- prev = it;
- }
- return true;
-}
-
-// This comparator orders intervals first by ascending min(). The Set never
-// contains overlapping intervals, so that suffices.
-template <typename T>
-bool QuicIntervalSet<T>::IntervalLess::operator()(const value_type& a,
- const value_type& b) const {
- // This overload is probably used only by Set::insert().
- return a.min() < b.min();
-}
-
-// It appears that the Set::lower_bound(T) method uses only two overloads of the
-// comparison operator that take a T as the second argument.. In contrast
-// Set::upper_bound(T) uses the two overloads that take T as the first argument.
-template <typename T>
-bool QuicIntervalSet<T>::IntervalLess::operator()(const value_type& a,
- const T& point) const {
- // Compare an interval to a point.
- return a.min() < point;
-}
-
-template <typename T>
-bool QuicIntervalSet<T>::IntervalLess::operator()(const value_type& a,
- T&& point) const {
- // Compare an interval to a point
- return a.min() < point;
-}
-
-// It appears that the Set::upper_bound(T) method uses only the next two
-// overloads of the comparison operator.
-template <typename T>
-bool QuicIntervalSet<T>::IntervalLess::operator()(const T& point,
- const value_type& a) const {
- // Compare an interval to a point.
- return point < a.min();
-}
-
-template <typename T>
-bool QuicIntervalSet<T>::IntervalLess::operator()(T&& point,
- const value_type& a) const {
- // Compare an interval to a point.
- return point < a.min();
-}
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_QUIC_INTERVAL_SET_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_interval_set_test.cc b/chromium/net/third_party/quiche/src/quic/core/quic_interval_set_test.cc
deleted file mode 100644
index 14db466a926..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_interval_set_test.cc
+++ /dev/null
@@ -1,1071 +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 "quic/core/quic_interval_set.h"
-
-#include <stdarg.h>
-
-#include <algorithm>
-#include <iostream>
-#include <iterator>
-#include <limits>
-#include <string>
-#include <vector>
-
-#include "quic/platform/api/quic_test.h"
-
-namespace quic {
-namespace test {
-namespace {
-
-using ::testing::ElementsAreArray;
-
-class QuicIntervalSetTest : public QuicTest {
- protected:
- virtual void SetUp() {
- // Initialize two QuicIntervalSets for union, intersection, and difference
- // tests
- is.Add(100, 200);
- is.Add(300, 400);
- is.Add(500, 600);
- is.Add(700, 800);
- is.Add(900, 1000);
- is.Add(1100, 1200);
- is.Add(1300, 1400);
- is.Add(1500, 1600);
- is.Add(1700, 1800);
- is.Add(1900, 2000);
- is.Add(2100, 2200);
-
- // Lots of different cases:
- other.Add(50, 70); // disjoint, at the beginning
- other.Add(2250, 2270); // disjoint, at the end
- other.Add(650, 670); // disjoint, in the middle
- other.Add(350, 360); // included
- other.Add(370, 380); // also included (two at once)
- other.Add(470, 530); // overlaps low end
- other.Add(770, 830); // overlaps high end
- other.Add(870, 900); // meets at low end
- other.Add(1200, 1230); // meets at high end
- other.Add(1270, 1830); // overlaps multiple ranges
- }
-
- virtual void TearDown() {
- is.Clear();
- EXPECT_TRUE(is.Empty());
- other.Clear();
- EXPECT_TRUE(other.Empty());
- }
- QuicIntervalSet<int> is;
- QuicIntervalSet<int> other;
-};
-
-TEST_F(QuicIntervalSetTest, IsDisjoint) {
- EXPECT_TRUE(is.IsDisjoint(QuicInterval<int>(0, 99)));
- EXPECT_TRUE(is.IsDisjoint(QuicInterval<int>(0, 100)));
- EXPECT_TRUE(is.IsDisjoint(QuicInterval<int>(200, 200)));
- EXPECT_TRUE(is.IsDisjoint(QuicInterval<int>(200, 299)));
- EXPECT_TRUE(is.IsDisjoint(QuicInterval<int>(400, 407)));
- EXPECT_TRUE(is.IsDisjoint(QuicInterval<int>(405, 499)));
- EXPECT_TRUE(is.IsDisjoint(QuicInterval<int>(2300, 2300)));
- EXPECT_TRUE(
- is.IsDisjoint(QuicInterval<int>(2300, std::numeric_limits<int>::max())));
- EXPECT_FALSE(is.IsDisjoint(QuicInterval<int>(100, 105)));
- EXPECT_FALSE(is.IsDisjoint(QuicInterval<int>(199, 300)));
- EXPECT_FALSE(is.IsDisjoint(QuicInterval<int>(250, 450)));
- EXPECT_FALSE(is.IsDisjoint(QuicInterval<int>(299, 400)));
- EXPECT_FALSE(is.IsDisjoint(QuicInterval<int>(250, 2000)));
- EXPECT_FALSE(
- is.IsDisjoint(QuicInterval<int>(2199, std::numeric_limits<int>::max())));
- // Empty intervals.
- EXPECT_TRUE(is.IsDisjoint(QuicInterval<int>(90, 90)));
- EXPECT_TRUE(is.IsDisjoint(QuicInterval<int>(100, 100)));
- EXPECT_TRUE(is.IsDisjoint(QuicInterval<int>(100, 90)));
- EXPECT_TRUE(is.IsDisjoint(QuicInterval<int>(150, 150)));
- EXPECT_TRUE(is.IsDisjoint(QuicInterval<int>(200, 200)));
- EXPECT_TRUE(is.IsDisjoint(QuicInterval<int>(400, 300)));
-}
-
-// Base helper method for verifying the contents of an interval set.
-// Returns true iff <is> contains <count> intervals whose successive
-// endpoints match the sequence of args in <ap>:
-static bool VA_Check(const QuicIntervalSet<int>& is, int count, va_list ap) {
- std::vector<QuicInterval<int>> intervals(is.begin(), is.end());
- if (count != static_cast<int>(intervals.size())) {
- QUIC_LOG(ERROR) << "Expected " << count << " intervals, got "
- << intervals.size() << ": " << is;
- return false;
- }
- if (count != static_cast<int>(is.Size())) {
- QUIC_LOG(ERROR) << "Expected " << count << " intervals, got Size "
- << is.Size() << ": " << is;
- return false;
- }
- bool result = true;
- for (int i = 0; i < count; i++) {
- int min = va_arg(ap, int);
- int max = va_arg(ap, int);
- if (min != intervals[i].min() || max != intervals[i].max()) {
- QUIC_LOG(ERROR) << "Expected: [" << min << ", " << max << ") got "
- << intervals[i] << " in " << is;
- result = false;
- }
- }
- return result;
-}
-
-static bool Check(const QuicIntervalSet<int>& is, int count, ...) {
- va_list ap;
- va_start(ap, count);
- const bool result = VA_Check(is, count, ap);
- va_end(ap);
- return result;
-}
-
-// Some helper functions for testing Contains and Find, which are logically the
-// same.
-static void TestContainsAndFind(const QuicIntervalSet<int>& is, int value) {
- EXPECT_TRUE(is.Contains(value)) << "Set does not contain " << value;
- auto it = is.Find(value);
- EXPECT_NE(it, is.end()) << "No iterator to interval containing " << value;
- EXPECT_TRUE(it->Contains(value)) << "Iterator does not contain " << value;
-}
-
-static void TestContainsAndFind(const QuicIntervalSet<int>& is,
- int min,
- int max) {
- EXPECT_TRUE(is.Contains(min, max))
- << "Set does not contain interval with min " << min << "and max " << max;
- auto it = is.Find(min, max);
- EXPECT_NE(it, is.end()) << "No iterator to interval with min " << min
- << "and max " << max;
- EXPECT_TRUE(it->Contains(QuicInterval<int>(min, max)))
- << "Iterator does not contain interval with min " << min << "and max "
- << max;
-}
-
-static void TestNotContainsAndFind(const QuicIntervalSet<int>& is, int value) {
- EXPECT_FALSE(is.Contains(value)) << "Set contains " << value;
- auto it = is.Find(value);
- EXPECT_EQ(it, is.end()) << "There is iterator to interval containing "
- << value;
-}
-
-static void TestNotContainsAndFind(const QuicIntervalSet<int>& is,
- int min,
- int max) {
- EXPECT_FALSE(is.Contains(min, max))
- << "Set contains interval with min " << min << "and max " << max;
- auto it = is.Find(min, max);
- EXPECT_EQ(it, is.end()) << "There is iterator to interval with min " << min
- << "and max " << max;
-}
-
-TEST_F(QuicIntervalSetTest, AddInterval) {
- QuicIntervalSet<int> s;
- s.Add(QuicInterval<int>(0, 10));
- EXPECT_TRUE(Check(s, 1, 0, 10));
-}
-
-TEST_F(QuicIntervalSetTest, DecrementIterator) {
- auto it = is.end();
- EXPECT_NE(it, is.begin());
- --it;
- EXPECT_EQ(*it, QuicInterval<int>(2100, 2200));
- ++it;
- EXPECT_EQ(it, is.end());
-}
-
-TEST_F(QuicIntervalSetTest, AddOptimizedForAppend) {
- QuicIntervalSet<int> empty_one, empty_two;
- empty_one.AddOptimizedForAppend(QuicInterval<int>(0, 99));
- EXPECT_TRUE(Check(empty_one, 1, 0, 99));
-
- empty_two.AddOptimizedForAppend(1, 50);
- EXPECT_TRUE(Check(empty_two, 1, 1, 50));
-
- QuicIntervalSet<int> iset;
- iset.AddOptimizedForAppend(100, 150);
- iset.AddOptimizedForAppend(200, 250);
- EXPECT_TRUE(Check(iset, 2, 100, 150, 200, 250));
-
- iset.AddOptimizedForAppend(199, 200);
- EXPECT_TRUE(Check(iset, 2, 100, 150, 199, 250));
-
- iset.AddOptimizedForAppend(251, 260);
- EXPECT_TRUE(Check(iset, 3, 100, 150, 199, 250, 251, 260));
-
- iset.AddOptimizedForAppend(252, 260);
- EXPECT_TRUE(Check(iset, 3, 100, 150, 199, 250, 251, 260));
-
- iset.AddOptimizedForAppend(252, 300);
- EXPECT_TRUE(Check(iset, 3, 100, 150, 199, 250, 251, 300));
-
- iset.AddOptimizedForAppend(300, 350);
- EXPECT_TRUE(Check(iset, 3, 100, 150, 199, 250, 251, 350));
-}
-
-TEST_F(QuicIntervalSetTest, PopFront) {
- QuicIntervalSet<int> iset{{100, 200}, {400, 500}, {700, 800}};
- EXPECT_TRUE(Check(iset, 3, 100, 200, 400, 500, 700, 800));
-
- iset.PopFront();
- EXPECT_TRUE(Check(iset, 2, 400, 500, 700, 800));
-
- iset.PopFront();
- EXPECT_TRUE(Check(iset, 1, 700, 800));
-
- iset.PopFront();
- EXPECT_TRUE(iset.Empty());
-}
-
-TEST_F(QuicIntervalSetTest, TrimLessThan) {
- QuicIntervalSet<int> iset{{100, 200}, {400, 500}, {700, 800}};
- EXPECT_TRUE(Check(iset, 3, 100, 200, 400, 500, 700, 800));
-
- EXPECT_FALSE(iset.TrimLessThan(99));
- EXPECT_FALSE(iset.TrimLessThan(100));
- EXPECT_TRUE(Check(iset, 3, 100, 200, 400, 500, 700, 800));
-
- EXPECT_TRUE(iset.TrimLessThan(101));
- EXPECT_TRUE(Check(iset, 3, 101, 200, 400, 500, 700, 800));
-
- EXPECT_TRUE(iset.TrimLessThan(199));
- EXPECT_TRUE(Check(iset, 3, 199, 200, 400, 500, 700, 800));
-
- EXPECT_TRUE(iset.TrimLessThan(450));
- EXPECT_TRUE(Check(iset, 2, 450, 500, 700, 800));
-
- EXPECT_TRUE(iset.TrimLessThan(500));
- EXPECT_TRUE(Check(iset, 1, 700, 800));
-
- EXPECT_TRUE(iset.TrimLessThan(801));
- EXPECT_TRUE(iset.Empty());
-
- EXPECT_FALSE(iset.TrimLessThan(900));
- EXPECT_TRUE(iset.Empty());
-}
-
-TEST_F(QuicIntervalSetTest, QuicIntervalSetBasic) {
- // Test Add, Get, Contains and Find
- QuicIntervalSet<int> iset;
- EXPECT_TRUE(iset.Empty());
- EXPECT_EQ(0u, iset.Size());
- iset.Add(100, 200);
- EXPECT_FALSE(iset.Empty());
- EXPECT_EQ(1u, iset.Size());
- iset.Add(100, 150);
- iset.Add(150, 200);
- iset.Add(130, 170);
- iset.Add(90, 150);
- iset.Add(170, 220);
- iset.Add(300, 400);
- iset.Add(250, 450);
- EXPECT_FALSE(iset.Empty());
- EXPECT_EQ(2u, iset.Size());
- EXPECT_TRUE(Check(iset, 2, 90, 220, 250, 450));
-
- // Test two intervals with a.max == b.min, that will just join up.
- iset.Clear();
- iset.Add(100, 200);
- iset.Add(200, 300);
- EXPECT_FALSE(iset.Empty());
- EXPECT_EQ(1u, iset.Size());
- EXPECT_TRUE(Check(iset, 1, 100, 300));
-
- // Test adding two sets together.
- iset.Clear();
- QuicIntervalSet<int> iset_add;
- iset.Add(100, 200);
- iset.Add(100, 150);
- iset.Add(150, 200);
- iset.Add(130, 170);
- iset_add.Add(90, 150);
- iset_add.Add(170, 220);
- iset_add.Add(300, 400);
- iset_add.Add(250, 450);
-
- iset.Union(iset_add);
- EXPECT_FALSE(iset.Empty());
- EXPECT_EQ(2u, iset.Size());
- EXPECT_TRUE(Check(iset, 2, 90, 220, 250, 450));
-
- // Test begin()/end(), and rbegin()/rend()
- // to iterate over intervals.
- {
- std::vector<QuicInterval<int>> expected(iset.begin(), iset.end());
-
- std::vector<QuicInterval<int>> actual1;
- std::copy(iset.begin(), iset.end(), back_inserter(actual1));
- ASSERT_EQ(expected.size(), actual1.size());
-
- std::vector<QuicInterval<int>> actual2;
- std::copy(iset.begin(), iset.end(), back_inserter(actual2));
- ASSERT_EQ(expected.size(), actual2.size());
-
- for (size_t i = 0; i < expected.size(); i++) {
- EXPECT_EQ(expected[i].min(), actual1[i].min());
- EXPECT_EQ(expected[i].max(), actual1[i].max());
-
- EXPECT_EQ(expected[i].min(), actual2[i].min());
- EXPECT_EQ(expected[i].max(), actual2[i].max());
- }
-
- // Ensure that the rbegin()/rend() iterators correctly yield the intervals
- // in reverse order.
- EXPECT_THAT(std::vector<QuicInterval<int>>(iset.rbegin(), iset.rend()),
- ElementsAreArray(expected.rbegin(), expected.rend()));
- }
-
- TestNotContainsAndFind(iset, 89);
- TestContainsAndFind(iset, 90);
- TestContainsAndFind(iset, 120);
- TestContainsAndFind(iset, 219);
- TestNotContainsAndFind(iset, 220);
- TestNotContainsAndFind(iset, 235);
- TestNotContainsAndFind(iset, 249);
- TestContainsAndFind(iset, 250);
- TestContainsAndFind(iset, 300);
- TestContainsAndFind(iset, 449);
- TestNotContainsAndFind(iset, 450);
- TestNotContainsAndFind(iset, 451);
-
- TestNotContainsAndFind(iset, 50, 60);
- TestNotContainsAndFind(iset, 50, 90);
- TestNotContainsAndFind(iset, 50, 200);
- TestNotContainsAndFind(iset, 90, 90);
- TestContainsAndFind(iset, 90, 200);
- TestContainsAndFind(iset, 100, 200);
- TestContainsAndFind(iset, 100, 220);
- TestNotContainsAndFind(iset, 100, 221);
- TestNotContainsAndFind(iset, 220, 220);
- TestNotContainsAndFind(iset, 240, 300);
- TestContainsAndFind(iset, 250, 300);
- TestContainsAndFind(iset, 260, 300);
- TestContainsAndFind(iset, 300, 450);
- TestNotContainsAndFind(iset, 300, 451);
-
- QuicIntervalSet<int> iset_contains;
- iset_contains.Add(50, 90);
- EXPECT_FALSE(iset.Contains(iset_contains));
- iset_contains.Clear();
-
- iset_contains.Add(90, 200);
- EXPECT_TRUE(iset.Contains(iset_contains));
- iset_contains.Add(100, 200);
- EXPECT_TRUE(iset.Contains(iset_contains));
- iset_contains.Add(100, 220);
- EXPECT_TRUE(iset.Contains(iset_contains));
- iset_contains.Add(250, 300);
- EXPECT_TRUE(iset.Contains(iset_contains));
- iset_contains.Add(300, 450);
- EXPECT_TRUE(iset.Contains(iset_contains));
- iset_contains.Add(300, 451);
- EXPECT_FALSE(iset.Contains(iset_contains));
- EXPECT_FALSE(iset.Contains(QuicInterval<int>()));
- EXPECT_FALSE(iset.Contains(QuicIntervalSet<int>()));
-
- // Check the case where the query set isn't contained, but the spanning
- // intervals do overlap.
- QuicIntervalSet<int> i2({{220, 230}});
- EXPECT_FALSE(iset.Contains(i2));
-}
-
-TEST_F(QuicIntervalSetTest, QuicIntervalSetContainsEmpty) {
- const QuicIntervalSet<int> empty;
- const QuicIntervalSet<int> other_empty;
- const QuicIntervalSet<int> non_empty({{10, 20}, {40, 50}});
- EXPECT_FALSE(empty.Contains(empty));
- EXPECT_FALSE(empty.Contains(other_empty));
- EXPECT_FALSE(empty.Contains(non_empty));
- EXPECT_FALSE(non_empty.Contains(empty));
-}
-
-TEST_F(QuicIntervalSetTest, Equality) {
- QuicIntervalSet<int> is_copy = is;
- EXPECT_EQ(is, is);
- EXPECT_EQ(is, is_copy);
- EXPECT_NE(is, other);
- EXPECT_NE(is, QuicIntervalSet<int>());
- EXPECT_EQ(QuicIntervalSet<int>(), QuicIntervalSet<int>());
-}
-
-TEST_F(QuicIntervalSetTest, LowerAndUpperBound) {
- QuicIntervalSet<int> intervals;
- intervals.Add(10, 20);
- intervals.Add(30, 40);
-
- // [10, 20) [30, 40) end
- // ^ LowerBound(5)
- // ^ LowerBound(10)
- // ^ LowerBound(15)
- // ^ LowerBound(20)
- // ^ LowerBound(25)
- // ^ LowerBound(30)
- // ^ LowerBound(35)
- // ^ LowerBound(40)
- // ^ LowerBound(50)
- EXPECT_EQ(intervals.LowerBound(5)->min(), 10);
- EXPECT_EQ(intervals.LowerBound(10)->min(), 10);
- EXPECT_EQ(intervals.LowerBound(15)->min(), 10);
- EXPECT_EQ(intervals.LowerBound(20)->min(), 30);
- EXPECT_EQ(intervals.LowerBound(25)->min(), 30);
- EXPECT_EQ(intervals.LowerBound(30)->min(), 30);
- EXPECT_EQ(intervals.LowerBound(35)->min(), 30);
- EXPECT_EQ(intervals.LowerBound(40), intervals.end());
- EXPECT_EQ(intervals.LowerBound(50), intervals.end());
-
- // [10, 20) [30, 40) end
- // ^ UpperBound(5)
- // ^ UpperBound(10)
- // ^ UpperBound(15)
- // ^ UpperBound(20)
- // ^ UpperBound(25)
- // ^ UpperBound(30)
- // ^ UpperBound(35)
- // ^ UpperBound(40)
- // ^ UpperBound(50)
- EXPECT_EQ(intervals.UpperBound(5)->min(), 10);
- EXPECT_EQ(intervals.UpperBound(10)->min(), 30);
- EXPECT_EQ(intervals.UpperBound(15)->min(), 30);
- EXPECT_EQ(intervals.UpperBound(20)->min(), 30);
- EXPECT_EQ(intervals.UpperBound(25)->min(), 30);
- EXPECT_EQ(intervals.UpperBound(30), intervals.end());
- EXPECT_EQ(intervals.UpperBound(35), intervals.end());
- EXPECT_EQ(intervals.UpperBound(40), intervals.end());
- EXPECT_EQ(intervals.UpperBound(50), intervals.end());
-}
-
-TEST_F(QuicIntervalSetTest, SpanningInterval) {
- // Spanning interval of an empty set is empty:
- {
- QuicIntervalSet<int> iset;
- const QuicInterval<int>& ival = iset.SpanningInterval();
- EXPECT_TRUE(ival.Empty());
- }
-
- // Spanning interval of a set with one interval is that interval:
- {
- QuicIntervalSet<int> iset;
- iset.Add(100, 200);
- const QuicInterval<int>& ival = iset.SpanningInterval();
- EXPECT_EQ(100, ival.min());
- EXPECT_EQ(200, ival.max());
- }
-
- // Spanning interval of a set with multiple elements is determined
- // by the endpoints of the first and last element:
- {
- const QuicInterval<int>& ival = is.SpanningInterval();
- EXPECT_EQ(100, ival.min());
- EXPECT_EQ(2200, ival.max());
- }
- {
- const QuicInterval<int>& ival = other.SpanningInterval();
- EXPECT_EQ(50, ival.min());
- EXPECT_EQ(2270, ival.max());
- }
-}
-
-TEST_F(QuicIntervalSetTest, QuicIntervalSetUnion) {
- is.Union(other);
- EXPECT_TRUE(Check(is, 12, 50, 70, 100, 200, 300, 400, 470, 600, 650, 670, 700,
- 830, 870, 1000, 1100, 1230, 1270, 1830, 1900, 2000, 2100,
- 2200, 2250, 2270));
-}
-
-TEST_F(QuicIntervalSetTest, QuicIntervalSetIntersection) {
- EXPECT_TRUE(is.Intersects(other));
- EXPECT_TRUE(other.Intersects(is));
- is.Intersection(other);
- EXPECT_TRUE(Check(is, 7, 350, 360, 370, 380, 500, 530, 770, 800, 1300, 1400,
- 1500, 1600, 1700, 1800));
- EXPECT_TRUE(is.Intersects(other));
- EXPECT_TRUE(other.Intersects(is));
-}
-
-TEST_F(QuicIntervalSetTest, QuicIntervalSetIntersectionBothEmpty) {
- QuicIntervalSet<std::string> mine, theirs;
- EXPECT_FALSE(mine.Intersects(theirs));
- EXPECT_FALSE(theirs.Intersects(mine));
- mine.Intersection(theirs);
- EXPECT_TRUE(mine.Empty());
- EXPECT_FALSE(mine.Intersects(theirs));
- EXPECT_FALSE(theirs.Intersects(mine));
-}
-
-TEST_F(QuicIntervalSetTest, QuicIntervalSetIntersectionEmptyMine) {
- QuicIntervalSet<std::string> mine;
- QuicIntervalSet<std::string> theirs("a", "b");
- EXPECT_FALSE(mine.Intersects(theirs));
- EXPECT_FALSE(theirs.Intersects(mine));
- mine.Intersection(theirs);
- EXPECT_TRUE(mine.Empty());
- EXPECT_FALSE(mine.Intersects(theirs));
- EXPECT_FALSE(theirs.Intersects(mine));
-}
-
-TEST_F(QuicIntervalSetTest, QuicIntervalSetIntersectionEmptyTheirs) {
- QuicIntervalSet<std::string> mine("a", "b");
- QuicIntervalSet<std::string> theirs;
- EXPECT_FALSE(mine.Intersects(theirs));
- EXPECT_FALSE(theirs.Intersects(mine));
- mine.Intersection(theirs);
- EXPECT_TRUE(mine.Empty());
- EXPECT_FALSE(mine.Intersects(theirs));
- EXPECT_FALSE(theirs.Intersects(mine));
-}
-
-TEST_F(QuicIntervalSetTest, QuicIntervalSetIntersectionTheirsBeforeMine) {
- QuicIntervalSet<std::string> mine("y", "z");
- QuicIntervalSet<std::string> theirs;
- theirs.Add("a", "b");
- theirs.Add("c", "d");
- EXPECT_FALSE(mine.Intersects(theirs));
- EXPECT_FALSE(theirs.Intersects(mine));
- mine.Intersection(theirs);
- EXPECT_TRUE(mine.Empty());
- EXPECT_FALSE(mine.Intersects(theirs));
- EXPECT_FALSE(theirs.Intersects(mine));
-}
-
-TEST_F(QuicIntervalSetTest, QuicIntervalSetIntersectionMineBeforeTheirs) {
- QuicIntervalSet<std::string> mine;
- mine.Add("a", "b");
- mine.Add("c", "d");
- QuicIntervalSet<std::string> theirs("y", "z");
- EXPECT_FALSE(mine.Intersects(theirs));
- EXPECT_FALSE(theirs.Intersects(mine));
- mine.Intersection(theirs);
- EXPECT_TRUE(mine.Empty());
- EXPECT_FALSE(mine.Intersects(theirs));
- EXPECT_FALSE(theirs.Intersects(mine));
-}
-
-TEST_F(QuicIntervalSetTest,
- QuicIntervalSetIntersectionTheirsBeforeMineInt64Singletons) {
- QuicIntervalSet<int64_t> mine({{10, 15}});
- QuicIntervalSet<int64_t> theirs({{-20, -5}});
- EXPECT_FALSE(mine.Intersects(theirs));
- EXPECT_FALSE(theirs.Intersects(mine));
- mine.Intersection(theirs);
- EXPECT_TRUE(mine.Empty());
- EXPECT_FALSE(mine.Intersects(theirs));
- EXPECT_FALSE(theirs.Intersects(mine));
-}
-
-TEST_F(QuicIntervalSetTest,
- QuicIntervalSetIntersectionMineBeforeTheirsIntSingletons) {
- QuicIntervalSet<int> mine({{10, 15}});
- QuicIntervalSet<int> theirs({{90, 95}});
- EXPECT_FALSE(mine.Intersects(theirs));
- EXPECT_FALSE(theirs.Intersects(mine));
- mine.Intersection(theirs);
- EXPECT_TRUE(mine.Empty());
- EXPECT_FALSE(mine.Intersects(theirs));
- EXPECT_FALSE(theirs.Intersects(mine));
-}
-
-TEST_F(QuicIntervalSetTest, QuicIntervalSetIntersectionTheirsBetweenMine) {
- QuicIntervalSet<int64_t> mine({{0, 5}, {40, 50}});
- QuicIntervalSet<int64_t> theirs({{10, 15}});
- EXPECT_FALSE(mine.Intersects(theirs));
- EXPECT_FALSE(theirs.Intersects(mine));
- mine.Intersection(theirs);
- EXPECT_TRUE(mine.Empty());
- EXPECT_FALSE(mine.Intersects(theirs));
- EXPECT_FALSE(theirs.Intersects(mine));
-}
-
-TEST_F(QuicIntervalSetTest, QuicIntervalSetIntersectionMineBetweenTheirs) {
- QuicIntervalSet<int> mine({{20, 25}});
- QuicIntervalSet<int> theirs({{10, 15}, {30, 32}});
- EXPECT_FALSE(mine.Intersects(theirs));
- EXPECT_FALSE(theirs.Intersects(mine));
- mine.Intersection(theirs);
- EXPECT_TRUE(mine.Empty());
- EXPECT_FALSE(mine.Intersects(theirs));
- EXPECT_FALSE(theirs.Intersects(mine));
-}
-
-TEST_F(QuicIntervalSetTest, QuicIntervalSetIntersectionAlternatingIntervals) {
- QuicIntervalSet<int> mine, theirs;
- mine.Add(10, 20);
- mine.Add(40, 50);
- mine.Add(60, 70);
- theirs.Add(25, 39);
- theirs.Add(55, 59);
- theirs.Add(75, 79);
- EXPECT_FALSE(mine.Intersects(theirs));
- EXPECT_FALSE(theirs.Intersects(mine));
- mine.Intersection(theirs);
- EXPECT_TRUE(mine.Empty());
- EXPECT_FALSE(mine.Intersects(theirs));
- EXPECT_FALSE(theirs.Intersects(mine));
-}
-
-TEST_F(QuicIntervalSetTest,
- QuicIntervalSetIntersectionAdjacentAlternatingNonIntersectingIntervals) {
- // Make sure that intersection with adjacent interval set is empty.
- const QuicIntervalSet<int> x1({{0, 10}});
- const QuicIntervalSet<int> y1({{-50, 0}, {10, 95}});
-
- QuicIntervalSet<int> result1 = x1;
- result1.Intersection(y1);
- EXPECT_TRUE(result1.Empty()) << result1;
-
- const QuicIntervalSet<int16_t> x2({{0, 10}, {20, 30}, {40, 90}});
- const QuicIntervalSet<int16_t> y2(
- {{-50, -40}, {-2, 0}, {10, 20}, {32, 40}, {90, 95}});
-
- QuicIntervalSet<int16_t> result2 = x2;
- result2.Intersection(y2);
- EXPECT_TRUE(result2.Empty()) << result2;
-
- const QuicIntervalSet<int64_t> x3({{-1, 5}, {5, 10}});
- const QuicIntervalSet<int64_t> y3({{-10, -1}, {10, 95}});
-
- QuicIntervalSet<int64_t> result3 = x3;
- result3.Intersection(y3);
- EXPECT_TRUE(result3.Empty()) << result3;
-}
-
-TEST_F(QuicIntervalSetTest,
- QuicIntervalSetIntersectionAlternatingIntersectingIntervals) {
- const QuicIntervalSet<int> x1({{0, 10}});
- const QuicIntervalSet<int> y1({{-50, 1}, {9, 95}});
- const QuicIntervalSet<int> expected_result1({{0, 1}, {9, 10}});
-
- QuicIntervalSet<int> result1 = x1;
- result1.Intersection(y1);
- EXPECT_EQ(result1, expected_result1);
-
- const QuicIntervalSet<int16_t> x2({{0, 10}, {20, 30}, {40, 90}});
- const QuicIntervalSet<int16_t> y2(
- {{-50, -40}, {-2, 2}, {9, 21}, {32, 41}, {85, 95}});
- const QuicIntervalSet<int16_t> expected_result2(
- {{0, 2}, {9, 10}, {20, 21}, {40, 41}, {85, 90}});
-
- QuicIntervalSet<int16_t> result2 = x2;
- result2.Intersection(y2);
- EXPECT_EQ(result2, expected_result2);
-
- const QuicIntervalSet<int64_t> x3({{-1, 5}, {5, 10}});
- const QuicIntervalSet<int64_t> y3({{-10, 3}, {4, 95}});
- const QuicIntervalSet<int64_t> expected_result3({{-1, 3}, {4, 10}});
-
- QuicIntervalSet<int64_t> result3 = x3;
- result3.Intersection(y3);
- EXPECT_EQ(result3, expected_result3);
-}
-
-TEST_F(QuicIntervalSetTest, QuicIntervalSetIntersectionIdentical) {
- QuicIntervalSet<int> copy(is);
- EXPECT_TRUE(copy.Intersects(is));
- EXPECT_TRUE(is.Intersects(copy));
- is.Intersection(copy);
- EXPECT_EQ(copy, is);
-}
-
-TEST_F(QuicIntervalSetTest, QuicIntervalSetIntersectionSuperset) {
- QuicIntervalSet<int> mine(-1, 10000);
- EXPECT_TRUE(mine.Intersects(is));
- EXPECT_TRUE(is.Intersects(mine));
- mine.Intersection(is);
- EXPECT_EQ(is, mine);
-}
-
-TEST_F(QuicIntervalSetTest, QuicIntervalSetIntersectionSubset) {
- QuicIntervalSet<int> copy(is);
- QuicIntervalSet<int> theirs(-1, 10000);
- EXPECT_TRUE(copy.Intersects(theirs));
- EXPECT_TRUE(theirs.Intersects(copy));
- is.Intersection(theirs);
- EXPECT_EQ(copy, is);
-}
-
-TEST_F(QuicIntervalSetTest, QuicIntervalSetIntersectionLargeSet) {
- QuicIntervalSet<int> mine, theirs;
- // mine: [0, 9), [10, 19), ..., [990, 999)
- for (int i = 0; i < 1000; i += 10) {
- mine.Add(i, i + 9);
- }
-
- theirs.Add(500, 520);
- theirs.Add(535, 545);
- theirs.Add(801, 809);
- EXPECT_TRUE(mine.Intersects(theirs));
- EXPECT_TRUE(theirs.Intersects(mine));
- mine.Intersection(theirs);
- EXPECT_TRUE(Check(mine, 5, 500, 509, 510, 519, 535, 539, 540, 545, 801, 809));
- EXPECT_TRUE(mine.Intersects(theirs));
- EXPECT_TRUE(theirs.Intersects(mine));
-}
-
-TEST_F(QuicIntervalSetTest, QuicIntervalSetDifference) {
- is.Difference(other);
- EXPECT_TRUE(Check(is, 10, 100, 200, 300, 350, 360, 370, 380, 400, 530, 600,
- 700, 770, 900, 1000, 1100, 1200, 1900, 2000, 2100, 2200));
- QuicIntervalSet<int> copy = is;
- is.Difference(copy);
- EXPECT_TRUE(is.Empty());
-}
-
-TEST_F(QuicIntervalSetTest, QuicIntervalSetDifferenceSingleBounds) {
- std::vector<QuicInterval<int>> ivals(other.begin(), other.end());
- for (const QuicInterval<int>& ival : ivals) {
- is.Difference(ival.min(), ival.max());
- }
- EXPECT_TRUE(Check(is, 10, 100, 200, 300, 350, 360, 370, 380, 400, 530, 600,
- 700, 770, 900, 1000, 1100, 1200, 1900, 2000, 2100, 2200));
-}
-
-TEST_F(QuicIntervalSetTest, QuicIntervalSetDifferenceSingleInterval) {
- std::vector<QuicInterval<int>> ivals(other.begin(), other.end());
- for (const QuicInterval<int>& ival : ivals) {
- is.Difference(ival);
- }
- EXPECT_TRUE(Check(is, 10, 100, 200, 300, 350, 360, 370, 380, 400, 530, 600,
- 700, 770, 900, 1000, 1100, 1200, 1900, 2000, 2100, 2200));
-}
-
-TEST_F(QuicIntervalSetTest, QuicIntervalSetDifferenceAlternatingIntervals) {
- QuicIntervalSet<int> mine, theirs;
- mine.Add(10, 20);
- mine.Add(40, 50);
- mine.Add(60, 70);
- theirs.Add(25, 39);
- theirs.Add(55, 59);
- theirs.Add(75, 79);
-
- mine.Difference(theirs);
- EXPECT_TRUE(Check(mine, 3, 10, 20, 40, 50, 60, 70));
-}
-
-TEST_F(QuicIntervalSetTest, QuicIntervalSetDifferenceEmptyMine) {
- QuicIntervalSet<std::string> mine, theirs;
- theirs.Add("a", "b");
-
- mine.Difference(theirs);
- EXPECT_TRUE(mine.Empty());
-}
-
-TEST_F(QuicIntervalSetTest, QuicIntervalSetDifferenceEmptyTheirs) {
- QuicIntervalSet<std::string> mine, theirs;
- mine.Add("a", "b");
-
- mine.Difference(theirs);
- EXPECT_EQ(1u, mine.Size());
- EXPECT_EQ("a", mine.begin()->min());
- EXPECT_EQ("b", mine.begin()->max());
-}
-
-TEST_F(QuicIntervalSetTest, QuicIntervalSetDifferenceTheirsBeforeMine) {
- QuicIntervalSet<std::string> mine, theirs;
- mine.Add("y", "z");
- theirs.Add("a", "b");
-
- mine.Difference(theirs);
- EXPECT_EQ(1u, mine.Size());
- EXPECT_EQ("y", mine.begin()->min());
- EXPECT_EQ("z", mine.begin()->max());
-}
-
-TEST_F(QuicIntervalSetTest, QuicIntervalSetDifferenceMineBeforeTheirs) {
- QuicIntervalSet<std::string> mine, theirs;
- mine.Add("a", "b");
- theirs.Add("y", "z");
-
- mine.Difference(theirs);
- EXPECT_EQ(1u, mine.Size());
- EXPECT_EQ("a", mine.begin()->min());
- EXPECT_EQ("b", mine.begin()->max());
-}
-
-TEST_F(QuicIntervalSetTest, QuicIntervalSetDifferenceIdentical) {
- QuicIntervalSet<std::string> mine;
- mine.Add("a", "b");
- mine.Add("c", "d");
- QuicIntervalSet<std::string> theirs(mine);
-
- mine.Difference(theirs);
- EXPECT_TRUE(mine.Empty());
-}
-
-TEST_F(QuicIntervalSetTest, EmptyComplement) {
- // The complement of an empty set is the input interval:
- QuicIntervalSet<int> iset;
- iset.Complement(100, 200);
- EXPECT_TRUE(Check(iset, 1, 100, 200));
-}
-
-TEST(QuicIntervalSetMultipleCompactionTest, OuterCovering) {
- QuicIntervalSet<int> iset;
- // First add a bunch of disjoint ranges
- iset.Add(100, 150);
- iset.Add(200, 250);
- iset.Add(300, 350);
- iset.Add(400, 450);
- EXPECT_TRUE(Check(iset, 4, 100, 150, 200, 250, 300, 350, 400, 450));
- // Now add a big range that covers all of these ranges
- iset.Add(0, 500);
- EXPECT_TRUE(Check(iset, 1, 0, 500));
-}
-
-TEST(QuicIntervalSetMultipleCompactionTest, InnerCovering) {
- QuicIntervalSet<int> iset;
- // First add a bunch of disjoint ranges
- iset.Add(100, 150);
- iset.Add(200, 250);
- iset.Add(300, 350);
- iset.Add(400, 450);
- EXPECT_TRUE(Check(iset, 4, 100, 150, 200, 250, 300, 350, 400, 450));
- // Now add a big range that partially covers the left and right most ranges.
- iset.Add(125, 425);
- EXPECT_TRUE(Check(iset, 1, 100, 450));
-}
-
-TEST(QuicIntervalSetMultipleCompactionTest, LeftCovering) {
- QuicIntervalSet<int> iset;
- // First add a bunch of disjoint ranges
- iset.Add(100, 150);
- iset.Add(200, 250);
- iset.Add(300, 350);
- iset.Add(400, 450);
- EXPECT_TRUE(Check(iset, 4, 100, 150, 200, 250, 300, 350, 400, 450));
- // Now add a big range that partially covers the left most range.
- iset.Add(125, 500);
- EXPECT_TRUE(Check(iset, 1, 100, 500));
-}
-
-TEST(QuicIntervalSetMultipleCompactionTest, RightCovering) {
- QuicIntervalSet<int> iset;
- // First add a bunch of disjoint ranges
- iset.Add(100, 150);
- iset.Add(200, 250);
- iset.Add(300, 350);
- iset.Add(400, 450);
- EXPECT_TRUE(Check(iset, 4, 100, 150, 200, 250, 300, 350, 400, 450));
- // Now add a big range that partially covers the right most range.
- iset.Add(0, 425);
- EXPECT_TRUE(Check(iset, 1, 0, 450));
-}
-
-// Helper method for testing and verifying the results of a one-interval
-// completement case.
-static bool CheckOneComplement(int add_min,
- int add_max,
- int comp_min,
- int comp_max,
- int count,
- ...) {
- QuicIntervalSet<int> iset;
- iset.Add(add_min, add_max);
- iset.Complement(comp_min, comp_max);
- bool result = true;
- va_list ap;
- va_start(ap, count);
- if (!VA_Check(iset, count, ap)) {
- result = false;
- }
- va_end(ap);
- return result;
-}
-
-TEST_F(QuicIntervalSetTest, SingleIntervalComplement) {
- // Verify the complement of a set with one interval (i):
- // |----- i -----|
- // |----- args -----|
- EXPECT_TRUE(CheckOneComplement(0, 10, 50, 150, 1, 50, 150));
-
- // |----- i -----|
- // |----- args -----|
- EXPECT_TRUE(CheckOneComplement(50, 150, 0, 100, 1, 0, 50));
-
- // |----- i -----|
- // |----- args -----|
- EXPECT_TRUE(CheckOneComplement(50, 150, 50, 150, 0));
-
- // |---------- i ----------|
- // |----- args -----|
- EXPECT_TRUE(CheckOneComplement(50, 500, 100, 300, 0));
-
- // |----- i -----|
- // |---------- args ----------|
- EXPECT_TRUE(CheckOneComplement(50, 500, 0, 800, 2, 0, 50, 500, 800));
-
- // |----- i -----|
- // |----- args -----|
- EXPECT_TRUE(CheckOneComplement(50, 150, 100, 300, 1, 150, 300));
-
- // |----- i -----|
- // |----- args -----|
- EXPECT_TRUE(CheckOneComplement(50, 150, 200, 300, 1, 200, 300));
-}
-
-// Helper method that copies <iset> and takes its complement,
-// returning false if Check succeeds.
-static bool CheckComplement(const QuicIntervalSet<int>& iset,
- int comp_min,
- int comp_max,
- int count,
- ...) {
- QuicIntervalSet<int> iset_copy = iset;
- iset_copy.Complement(comp_min, comp_max);
- bool result = true;
- va_list ap;
- va_start(ap, count);
- if (!VA_Check(iset_copy, count, ap)) {
- result = false;
- }
- va_end(ap);
- return result;
-}
-
-TEST_F(QuicIntervalSetTest, MultiIntervalComplement) {
- // Initialize a small test set:
- QuicIntervalSet<int> iset;
- iset.Add(100, 200);
- iset.Add(300, 400);
- iset.Add(500, 600);
-
- // |----- i -----|
- // |----- comp -----|
- EXPECT_TRUE(CheckComplement(iset, 0, 50, 1, 0, 50));
-
- // |----- i -----|
- // |----- comp -----|
- EXPECT_TRUE(CheckComplement(iset, 0, 200, 1, 0, 100));
- EXPECT_TRUE(CheckComplement(iset, 0, 220, 2, 0, 100, 200, 220));
-
- // |----- i -----|
- // |----- comp -----|
- EXPECT_TRUE(CheckComplement(iset, 100, 600, 2, 200, 300, 400, 500));
-
- // |---------- i ----------|
- // |----- comp -----|
- EXPECT_TRUE(CheckComplement(iset, 300, 400, 0));
- EXPECT_TRUE(CheckComplement(iset, 250, 400, 1, 250, 300));
- EXPECT_TRUE(CheckComplement(iset, 300, 450, 1, 400, 450));
- EXPECT_TRUE(CheckComplement(iset, 250, 450, 2, 250, 300, 400, 450));
-
- // |----- i -----|
- // |---------- comp ----------|
- EXPECT_TRUE(
- CheckComplement(iset, 0, 700, 4, 0, 100, 200, 300, 400, 500, 600, 700));
-
- // |----- i -----|
- // |----- comp -----|
- EXPECT_TRUE(CheckComplement(iset, 400, 700, 2, 400, 500, 600, 700));
- EXPECT_TRUE(CheckComplement(iset, 350, 700, 2, 400, 500, 600, 700));
-
- // |----- i -----|
- // |----- comp -----|
- EXPECT_TRUE(CheckComplement(iset, 700, 800, 1, 700, 800));
-}
-
-// Verifies ToString, operator<< don't assert.
-TEST_F(QuicIntervalSetTest, ToString) {
- QuicIntervalSet<int> iset;
- iset.Add(300, 400);
- iset.Add(100, 200);
- iset.Add(500, 600);
- EXPECT_TRUE(!iset.ToString().empty());
- QUIC_VLOG(2) << iset;
- // Order and format of ToString() output is guaranteed.
- EXPECT_EQ("{ [100, 200) [300, 400) [500, 600) }", iset.ToString());
- EXPECT_EQ("{ [1, 2) }", QuicIntervalSet<int>(1, 2).ToString());
- EXPECT_EQ("{ }", QuicIntervalSet<int>().ToString());
-}
-
-TEST_F(QuicIntervalSetTest, ConstructionDiscardsEmptyInterval) {
- EXPECT_TRUE(QuicIntervalSet<int>(QuicInterval<int>(2, 2)).Empty());
- EXPECT_TRUE(QuicIntervalSet<int>(2, 2).Empty());
- EXPECT_FALSE(QuicIntervalSet<int>(QuicInterval<int>(2, 3)).Empty());
- EXPECT_FALSE(QuicIntervalSet<int>(2, 3).Empty());
-}
-
-TEST_F(QuicIntervalSetTest, Swap) {
- QuicIntervalSet<int> a, b;
- a.Add(300, 400);
- b.Add(100, 200);
- b.Add(500, 600);
- std::swap(a, b);
- EXPECT_TRUE(Check(a, 2, 100, 200, 500, 600));
- EXPECT_TRUE(Check(b, 1, 300, 400));
- std::swap(a, b);
- EXPECT_TRUE(Check(a, 1, 300, 400));
- EXPECT_TRUE(Check(b, 2, 100, 200, 500, 600));
-}
-
-TEST_F(QuicIntervalSetTest, OutputReturnsOstreamRef) {
- std::stringstream ss;
- const QuicIntervalSet<int> v(QuicInterval<int>(1, 2));
- auto return_type_is_a_ref = [](std::ostream&) {};
- return_type_is_a_ref(ss << v);
-}
-
-struct NotOstreamable {
- bool operator<(const NotOstreamable&) const { return false; }
- bool operator>(const NotOstreamable&) const { return false; }
- bool operator!=(const NotOstreamable&) const { return false; }
- bool operator>=(const NotOstreamable&) const { return true; }
- bool operator<=(const NotOstreamable&) const { return true; }
- bool operator==(const NotOstreamable&) const { return true; }
-};
-
-TEST_F(QuicIntervalSetTest, IntervalOfTypeWithNoOstreamSupport) {
- const NotOstreamable v;
- const QuicIntervalSet<NotOstreamable> d(QuicInterval<NotOstreamable>(v, v));
- // EXPECT_EQ builds a string representation of d. If d::operator<<()
- // would be defined then this test would not compile because NotOstreamable
- // objects lack the operator<<() support.
- EXPECT_EQ(d, d);
-}
-
-class QuicIntervalSetInitTest : public QuicTest {
- protected:
- const std::vector<QuicInterval<int>> intervals_{{0, 1}, {2, 4}};
-};
-
-TEST_F(QuicIntervalSetInitTest, DirectInit) {
- std::initializer_list<QuicInterval<int>> il = {{0, 1}, {2, 3}, {3, 4}};
- QuicIntervalSet<int> s(il);
- EXPECT_THAT(s, ElementsAreArray(intervals_));
-}
-
-TEST_F(QuicIntervalSetInitTest, CopyInit) {
- std::initializer_list<QuicInterval<int>> il = {{0, 1}, {2, 3}, {3, 4}};
- QuicIntervalSet<int> s = il;
- EXPECT_THAT(s, ElementsAreArray(intervals_));
-}
-
-TEST_F(QuicIntervalSetInitTest, AssignIterPair) {
- QuicIntervalSet<int> s(0, 1000); // Make sure assign clears.
- s.assign(intervals_.begin(), intervals_.end());
- EXPECT_THAT(s, ElementsAreArray(intervals_));
-}
-
-TEST_F(QuicIntervalSetInitTest, AssignInitList) {
- QuicIntervalSet<int> s(0, 1000); // Make sure assign clears.
- s.assign({{0, 1}, {2, 3}, {3, 4}});
- EXPECT_THAT(s, ElementsAreArray(intervals_));
-}
-
-TEST_F(QuicIntervalSetInitTest, AssignmentInitList) {
- std::initializer_list<QuicInterval<int>> il = {{0, 1}, {2, 3}, {3, 4}};
- QuicIntervalSet<int> s;
- s = il;
- EXPECT_THAT(s, ElementsAreArray(intervals_));
-}
-
-TEST_F(QuicIntervalSetInitTest, BracedInitThenBracedAssign) {
- QuicIntervalSet<int> s{{0, 1}, {2, 3}, {3, 4}};
- s = {{0, 1}, {2, 4}};
- EXPECT_THAT(s, ElementsAreArray(intervals_));
-}
-
-} // namespace
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_interval_test.cc b/chromium/net/third_party/quiche/src/quic/core/quic_interval_test.cc
deleted file mode 100644
index 4ec9fa69454..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_interval_test.cc
+++ /dev/null
@@ -1,470 +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 "quic/core/quic_interval.h"
-
-#include <sstream>
-#include <string>
-#include <type_traits>
-#include <utility>
-
-#include "quic/core/quic_time.h"
-#include "quic/platform/api/quic_test.h"
-
-namespace quic {
-namespace test {
-namespace {
-
-template <typename ForwardIterator>
-void STLDeleteContainerPointers(ForwardIterator begin, ForwardIterator end) {
- while (begin != end) {
- auto temp = begin;
- ++begin;
- delete *temp;
- }
-}
-
-template <typename T>
-void STLDeleteElements(T* container) {
- if (!container)
- return;
- STLDeleteContainerPointers(container->begin(), container->end());
- container->clear();
-}
-
-class ConstructorListener {
- public:
- ConstructorListener(int* copy_construct_counter, int* move_construct_counter)
- : copy_construct_counter_(copy_construct_counter),
- move_construct_counter_(move_construct_counter) {
- *copy_construct_counter_ = 0;
- *move_construct_counter_ = 0;
- }
- ConstructorListener(const ConstructorListener& other) {
- copy_construct_counter_ = other.copy_construct_counter_;
- move_construct_counter_ = other.move_construct_counter_;
- ++*copy_construct_counter_;
- }
- ConstructorListener(ConstructorListener&& other) {
- copy_construct_counter_ = other.copy_construct_counter_;
- move_construct_counter_ = other.move_construct_counter_;
- ++*move_construct_counter_;
- }
- bool operator<(const ConstructorListener&) { return false; }
- bool operator>(const ConstructorListener&) { return false; }
- bool operator<=(const ConstructorListener&) { return true; }
- bool operator>=(const ConstructorListener&) { return true; }
- bool operator==(const ConstructorListener&) { return true; }
-
- private:
- int* copy_construct_counter_;
- int* move_construct_counter_;
-};
-
-TEST(QuicIntervalConstructorTest, Move) {
- int object1_copy_count, object1_move_count;
- ConstructorListener object1(&object1_copy_count, &object1_move_count);
- int object2_copy_count, object2_move_count;
- ConstructorListener object2(&object2_copy_count, &object2_move_count);
-
- QuicInterval<ConstructorListener> interval(object1, std::move(object2));
- EXPECT_EQ(1, object1_copy_count);
- EXPECT_EQ(0, object1_move_count);
- EXPECT_EQ(0, object2_copy_count);
- EXPECT_EQ(1, object2_move_count);
-}
-
-TEST(QuicIntervalConstructorTest, ImplicitConversion) {
- struct WrappedInt {
- WrappedInt(int value) : value(value) {}
- bool operator<(const WrappedInt& other) { return value < other.value; }
- bool operator>(const WrappedInt& other) { return value > other.value; }
- bool operator<=(const WrappedInt& other) { return value <= other.value; }
- bool operator>=(const WrappedInt& other) { return value >= other.value; }
- bool operator==(const WrappedInt& other) { return value == other.value; }
- int value;
- };
-
- static_assert(std::is_convertible<int, WrappedInt>::value, "");
- static_assert(
- std::is_constructible<QuicInterval<WrappedInt>, int, int>::value, "");
-
- QuicInterval<WrappedInt> i(10, 20);
- EXPECT_EQ(10, i.min().value);
- EXPECT_EQ(20, i.max().value);
-}
-
-class QuicIntervalTest : public QuicTest {
- protected:
- // Test intersection between the two intervals i1 and i2. Tries
- // i1.IntersectWith(i2) and vice versa. The intersection should change i1 iff
- // changes_i1 is true, and the same for changes_i2. The resulting
- // intersection should be result.
- void TestIntersect(const QuicInterval<int64_t>& i1,
- const QuicInterval<int64_t>& i2,
- bool changes_i1,
- bool changes_i2,
- const QuicInterval<int64_t>& result) {
- QuicInterval<int64_t> i;
- i = i1;
- EXPECT_TRUE(i.IntersectWith(i2) == changes_i1 && i == result);
- i = i2;
- EXPECT_TRUE(i.IntersectWith(i1) == changes_i2 && i == result);
- }
-};
-
-TEST_F(QuicIntervalTest, ConstructorsCopyAndClear) {
- QuicInterval<int32_t> empty;
- EXPECT_TRUE(empty.Empty());
-
- QuicInterval<int32_t> d2(0, 100);
- EXPECT_EQ(0, d2.min());
- EXPECT_EQ(100, d2.max());
- EXPECT_EQ(QuicInterval<int32_t>(0, 100), d2);
- EXPECT_NE(QuicInterval<int32_t>(0, 99), d2);
-
- empty = d2;
- EXPECT_EQ(0, d2.min());
- EXPECT_EQ(100, d2.max());
- EXPECT_TRUE(empty == d2);
- EXPECT_EQ(empty, d2);
- EXPECT_TRUE(d2 == empty);
- EXPECT_EQ(d2, empty);
-
- QuicInterval<int32_t> max_less_than_min(40, 20);
- EXPECT_TRUE(max_less_than_min.Empty());
- EXPECT_EQ(40, max_less_than_min.min());
- EXPECT_EQ(20, max_less_than_min.max());
-
- QuicInterval<int> d3(10, 20);
- d3.Clear();
- EXPECT_TRUE(d3.Empty());
-}
-
-TEST_F(QuicIntervalTest, MakeQuicInterval) {
- static_assert(
- std::is_same<QuicInterval<int>, decltype(MakeQuicInterval(0, 3))>::value,
- "Type is deduced incorrectly.");
- static_assert(std::is_same<QuicInterval<double>,
- decltype(MakeQuicInterval(0., 3.))>::value,
- "Type is deduced incorrectly.");
-
- EXPECT_EQ(MakeQuicInterval(0., 3.), QuicInterval<double>(0, 3));
-}
-
-TEST_F(QuicIntervalTest, GettersSetters) {
- QuicInterval<int32_t> d1(100, 200);
-
- // SetMin:
- d1.SetMin(30);
- EXPECT_EQ(30, d1.min());
- EXPECT_EQ(200, d1.max());
-
- // SetMax:
- d1.SetMax(220);
- EXPECT_EQ(30, d1.min());
- EXPECT_EQ(220, d1.max());
-
- // Set:
- d1.Clear();
- d1.Set(30, 220);
- EXPECT_EQ(30, d1.min());
- EXPECT_EQ(220, d1.max());
-
- // SpanningUnion:
- QuicInterval<int32_t> d2;
- EXPECT_TRUE(!d1.SpanningUnion(d2));
- EXPECT_EQ(30, d1.min());
- EXPECT_EQ(220, d1.max());
-
- EXPECT_TRUE(d2.SpanningUnion(d1));
- EXPECT_EQ(30, d2.min());
- EXPECT_EQ(220, d2.max());
-
- d2.SetMin(40);
- d2.SetMax(100);
- EXPECT_TRUE(!d1.SpanningUnion(d2));
- EXPECT_EQ(30, d1.min());
- EXPECT_EQ(220, d1.max());
-
- d2.SetMin(20);
- d2.SetMax(100);
- EXPECT_TRUE(d1.SpanningUnion(d2));
- EXPECT_EQ(20, d1.min());
- EXPECT_EQ(220, d1.max());
-
- d2.SetMin(50);
- d2.SetMax(300);
- EXPECT_TRUE(d1.SpanningUnion(d2));
- EXPECT_EQ(20, d1.min());
- EXPECT_EQ(300, d1.max());
-
- d2.SetMin(0);
- d2.SetMax(500);
- EXPECT_TRUE(d1.SpanningUnion(d2));
- EXPECT_EQ(0, d1.min());
- EXPECT_EQ(500, d1.max());
-
- d2.SetMin(100);
- d2.SetMax(0);
- EXPECT_TRUE(!d1.SpanningUnion(d2));
- EXPECT_EQ(0, d1.min());
- EXPECT_EQ(500, d1.max());
- EXPECT_TRUE(d2.SpanningUnion(d1));
- EXPECT_EQ(0, d2.min());
- EXPECT_EQ(500, d2.max());
-}
-
-TEST_F(QuicIntervalTest, CoveringOps) {
- const QuicInterval<int64_t> empty;
- const QuicInterval<int64_t> d(100, 200);
- const QuicInterval<int64_t> d1(0, 50);
- const QuicInterval<int64_t> d2(50, 110);
- const QuicInterval<int64_t> d3(110, 180);
- const QuicInterval<int64_t> d4(180, 220);
- const QuicInterval<int64_t> d5(220, 300);
- const QuicInterval<int64_t> d6(100, 150);
- const QuicInterval<int64_t> d7(150, 200);
- const QuicInterval<int64_t> d8(0, 300);
-
- // Intersection:
- EXPECT_TRUE(d.Intersects(d));
- EXPECT_TRUE(!empty.Intersects(d) && !d.Intersects(empty));
- EXPECT_TRUE(!d.Intersects(d1) && !d1.Intersects(d));
- EXPECT_TRUE(d.Intersects(d2) && d2.Intersects(d));
- EXPECT_TRUE(d.Intersects(d3) && d3.Intersects(d));
- EXPECT_TRUE(d.Intersects(d4) && d4.Intersects(d));
- EXPECT_TRUE(!d.Intersects(d5) && !d5.Intersects(d));
- EXPECT_TRUE(d.Intersects(d6) && d6.Intersects(d));
- EXPECT_TRUE(d.Intersects(d7) && d7.Intersects(d));
- EXPECT_TRUE(d.Intersects(d8) && d8.Intersects(d));
-
- QuicInterval<int64_t> i;
- EXPECT_TRUE(d.Intersects(d, &i) && d == i);
- EXPECT_TRUE(!empty.Intersects(d, nullptr) && !d.Intersects(empty, nullptr));
- EXPECT_TRUE(!d.Intersects(d1, nullptr) && !d1.Intersects(d, nullptr));
- EXPECT_TRUE(d.Intersects(d2, &i) && i == QuicInterval<int64_t>(100, 110));
- EXPECT_TRUE(d2.Intersects(d, &i) && i == QuicInterval<int64_t>(100, 110));
- EXPECT_TRUE(d.Intersects(d3, &i) && i == d3);
- EXPECT_TRUE(d3.Intersects(d, &i) && i == d3);
- EXPECT_TRUE(d.Intersects(d4, &i) && i == QuicInterval<int64_t>(180, 200));
- EXPECT_TRUE(d4.Intersects(d, &i) && i == QuicInterval<int64_t>(180, 200));
- EXPECT_TRUE(!d.Intersects(d5, nullptr) && !d5.Intersects(d, nullptr));
- EXPECT_TRUE(d.Intersects(d6, &i) && i == d6);
- EXPECT_TRUE(d6.Intersects(d, &i) && i == d6);
- EXPECT_TRUE(d.Intersects(d7, &i) && i == d7);
- EXPECT_TRUE(d7.Intersects(d, &i) && i == d7);
- EXPECT_TRUE(d.Intersects(d8, &i) && i == d);
- EXPECT_TRUE(d8.Intersects(d, &i) && i == d);
-
- // Test IntersectsWith().
- // Arguments are TestIntersect(i1, i2, changes_i1, changes_i2, result).
- TestIntersect(empty, d, false, true, empty);
- TestIntersect(d, d1, true, true, empty);
- TestIntersect(d1, d2, true, true, empty);
- TestIntersect(d, d2, true, true, QuicInterval<int64_t>(100, 110));
- TestIntersect(d8, d, true, false, d);
- TestIntersect(d8, d1, true, false, d1);
- TestIntersect(d8, d5, true, false, d5);
-
- // Contains:
- EXPECT_TRUE(!empty.Contains(d) && !d.Contains(empty));
- EXPECT_TRUE(d.Contains(d));
- EXPECT_TRUE(!d.Contains(d1) && !d1.Contains(d));
- EXPECT_TRUE(!d.Contains(d2) && !d2.Contains(d));
- EXPECT_TRUE(d.Contains(d3) && !d3.Contains(d));
- EXPECT_TRUE(!d.Contains(d4) && !d4.Contains(d));
- EXPECT_TRUE(!d.Contains(d5) && !d5.Contains(d));
- EXPECT_TRUE(d.Contains(d6) && !d6.Contains(d));
- EXPECT_TRUE(d.Contains(d7) && !d7.Contains(d));
- EXPECT_TRUE(!d.Contains(d8) && d8.Contains(d));
-
- EXPECT_TRUE(d.Contains(100));
- EXPECT_TRUE(!d.Contains(200));
- EXPECT_TRUE(d.Contains(150));
- EXPECT_TRUE(!d.Contains(99));
- EXPECT_TRUE(!d.Contains(201));
-
- // Difference:
- std::vector<QuicInterval<int64_t>*> diff;
-
- EXPECT_TRUE(!d.Difference(empty, &diff));
- EXPECT_EQ(1u, diff.size());
- EXPECT_EQ(100, diff[0]->min());
- EXPECT_EQ(200, diff[0]->max());
- STLDeleteElements(&diff);
- EXPECT_TRUE(!empty.Difference(d, &diff) && diff.empty());
-
- EXPECT_TRUE(d.Difference(d, &diff) && diff.empty());
- EXPECT_TRUE(!d.Difference(d1, &diff));
- EXPECT_EQ(1u, diff.size());
- EXPECT_EQ(100, diff[0]->min());
- EXPECT_EQ(200, diff[0]->max());
- STLDeleteElements(&diff);
-
- QuicInterval<int64_t> lo;
- QuicInterval<int64_t> hi;
-
- EXPECT_TRUE(d.Difference(d2, &lo, &hi));
- EXPECT_TRUE(lo.Empty());
- EXPECT_EQ(110, hi.min());
- EXPECT_EQ(200, hi.max());
- EXPECT_TRUE(d.Difference(d2, &diff));
- EXPECT_EQ(1u, diff.size());
- EXPECT_EQ(110, diff[0]->min());
- EXPECT_EQ(200, diff[0]->max());
- STLDeleteElements(&diff);
-
- EXPECT_TRUE(d.Difference(d3, &lo, &hi));
- EXPECT_EQ(100, lo.min());
- EXPECT_EQ(110, lo.max());
- EXPECT_EQ(180, hi.min());
- EXPECT_EQ(200, hi.max());
- EXPECT_TRUE(d.Difference(d3, &diff));
- EXPECT_EQ(2u, diff.size());
- EXPECT_EQ(100, diff[0]->min());
- EXPECT_EQ(110, diff[0]->max());
- EXPECT_EQ(180, diff[1]->min());
- EXPECT_EQ(200, diff[1]->max());
- STLDeleteElements(&diff);
-
- EXPECT_TRUE(d.Difference(d4, &lo, &hi));
- EXPECT_EQ(100, lo.min());
- EXPECT_EQ(180, lo.max());
- EXPECT_TRUE(hi.Empty());
- EXPECT_TRUE(d.Difference(d4, &diff));
- EXPECT_EQ(1u, diff.size());
- EXPECT_EQ(100, diff[0]->min());
- EXPECT_EQ(180, diff[0]->max());
- STLDeleteElements(&diff);
-
- EXPECT_FALSE(d.Difference(d5, &lo, &hi));
- EXPECT_EQ(100, lo.min());
- EXPECT_EQ(200, lo.max());
- EXPECT_TRUE(hi.Empty());
- EXPECT_FALSE(d.Difference(d5, &diff));
- EXPECT_EQ(1u, diff.size());
- EXPECT_EQ(100, diff[0]->min());
- EXPECT_EQ(200, diff[0]->max());
- STLDeleteElements(&diff);
-
- EXPECT_TRUE(d.Difference(d6, &lo, &hi));
- EXPECT_TRUE(lo.Empty());
- EXPECT_EQ(150, hi.min());
- EXPECT_EQ(200, hi.max());
- EXPECT_TRUE(d.Difference(d6, &diff));
- EXPECT_EQ(1u, diff.size());
- EXPECT_EQ(150, diff[0]->min());
- EXPECT_EQ(200, diff[0]->max());
- STLDeleteElements(&diff);
-
- EXPECT_TRUE(d.Difference(d7, &lo, &hi));
- EXPECT_EQ(100, lo.min());
- EXPECT_EQ(150, lo.max());
- EXPECT_TRUE(hi.Empty());
- EXPECT_TRUE(d.Difference(d7, &diff));
- EXPECT_EQ(1u, diff.size());
- EXPECT_EQ(100, diff[0]->min());
- EXPECT_EQ(150, diff[0]->max());
- STLDeleteElements(&diff);
-
- EXPECT_TRUE(d.Difference(d8, &lo, &hi));
- EXPECT_TRUE(lo.Empty());
- EXPECT_TRUE(hi.Empty());
- EXPECT_TRUE(d.Difference(d8, &diff) && diff.empty());
-}
-
-TEST_F(QuicIntervalTest, Separated) {
- using QI = QuicInterval<int>;
- EXPECT_FALSE(QI(100, 200).Separated(QI(100, 200)));
- EXPECT_FALSE(QI(100, 200).Separated(QI(200, 300)));
- EXPECT_TRUE(QI(100, 200).Separated(QI(201, 300)));
- EXPECT_FALSE(QI(100, 200).Separated(QI(0, 100)));
- EXPECT_TRUE(QI(100, 200).Separated(QI(0, 99)));
- EXPECT_FALSE(QI(100, 200).Separated(QI(150, 170)));
- EXPECT_FALSE(QI(150, 170).Separated(QI(100, 200)));
- EXPECT_FALSE(QI(100, 200).Separated(QI(150, 250)));
- EXPECT_FALSE(QI(150, 250).Separated(QI(100, 200)));
-}
-
-TEST_F(QuicIntervalTest, Length) {
- const QuicInterval<int> empty1;
- const QuicInterval<int> empty2(1, 1);
- const QuicInterval<int> empty3(1, 0);
- const QuicInterval<QuicTime> empty4(
- QuicTime::Zero() + QuicTime::Delta::FromSeconds(1), QuicTime::Zero());
- const QuicInterval<int> d1(1, 2);
- const QuicInterval<int> d2(0, 50);
- const QuicInterval<QuicTime> d3(
- QuicTime::Zero(), QuicTime::Zero() + QuicTime::Delta::FromSeconds(1));
- const QuicInterval<QuicTime> d4(
- QuicTime::Zero() + QuicTime::Delta::FromSeconds(3600),
- QuicTime::Zero() + QuicTime::Delta::FromSeconds(5400));
-
- EXPECT_EQ(0, empty1.Length());
- EXPECT_EQ(0, empty2.Length());
- EXPECT_EQ(0, empty3.Length());
- EXPECT_EQ(QuicTime::Delta::Zero(), empty4.Length());
- EXPECT_EQ(1, d1.Length());
- EXPECT_EQ(50, d2.Length());
- EXPECT_EQ(QuicTime::Delta::FromSeconds(1), d3.Length());
- EXPECT_EQ(QuicTime::Delta::FromSeconds(1800), d4.Length());
-}
-
-TEST_F(QuicIntervalTest, IntervalOfTypeWithNoOperatorMinus) {
- // QuicInterval<T> should work even if T does not support operator-(). We
- // just can't call QuicInterval<T>::Length() for such types.
- const QuicInterval<std::string> d1("a", "b");
- const QuicInterval<std::pair<int, int>> d2({1, 2}, {4, 3});
- EXPECT_EQ("a", d1.min());
- EXPECT_EQ("b", d1.max());
- EXPECT_EQ(std::make_pair(1, 2), d2.min());
- EXPECT_EQ(std::make_pair(4, 3), d2.max());
-}
-
-struct NoEquals {
- NoEquals(int v) : value(v) {} // NOLINT
- int value;
- bool operator<(const NoEquals& other) const { return value < other.value; }
-};
-
-TEST_F(QuicIntervalTest, OrderedComparisonForTypeWithoutEquals) {
- const QuicInterval<NoEquals> d1(0, 4);
- const QuicInterval<NoEquals> d2(0, 3);
- const QuicInterval<NoEquals> d3(1, 4);
- const QuicInterval<NoEquals> d4(1, 5);
- const QuicInterval<NoEquals> d6(0, 4);
- EXPECT_TRUE(d1 < d2);
- EXPECT_TRUE(d1 < d3);
- EXPECT_TRUE(d1 < d4);
- EXPECT_FALSE(d1 < d6);
-}
-
-TEST_F(QuicIntervalTest, OutputReturnsOstreamRef) {
- std::stringstream ss;
- const QuicInterval<int> v(1, 2);
- // If (ss << v) were to return a value, it wouldn't match the signature of
- // return_type_is_a_ref() function.
- auto return_type_is_a_ref = [](std::ostream&) {};
- return_type_is_a_ref(ss << v);
-}
-
-struct NotOstreamable {
- bool operator<(const NotOstreamable&) const { return false; }
- bool operator>=(const NotOstreamable&) const { return true; }
- bool operator==(const NotOstreamable&) const { return true; }
-};
-
-TEST_F(QuicIntervalTest, IntervalOfTypeWithNoOstreamSupport) {
- const NotOstreamable v;
- const QuicInterval<NotOstreamable> d(v, v);
- // EXPECT_EQ builds a string representation of d. If d::operator<<() would be
- // defined then this test would not compile because NotOstreamable objects
- // lack the operator<<() support.
- EXPECT_EQ(d, d);
-}
-
-} // namespace
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_legacy_version_encapsulator.cc b/chromium/net/third_party/quiche/src/quic/core/quic_legacy_version_encapsulator.cc
deleted file mode 100644
index 11d2293bee5..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_legacy_version_encapsulator.cc
+++ /dev/null
@@ -1,153 +0,0 @@
-// Copyright (c) 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_legacy_version_encapsulator.h"
-#include "quic/core/crypto/crypto_handshake_message.h"
-#include "quic/core/crypto/crypto_protocol.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-
-namespace quic {
-
-QuicLegacyVersionEncapsulator::QuicLegacyVersionEncapsulator(
- QuicPacketBuffer packet_buffer)
- : packet_buffer_(packet_buffer) {}
-
-QuicLegacyVersionEncapsulator::~QuicLegacyVersionEncapsulator() {}
-
-// static
-QuicByteCount QuicLegacyVersionEncapsulator::GetMinimumOverhead(
- absl::string_view sni) {
- // The number 52 is the sum of:
- // - Flags (1 byte)
- // - Server Connection ID (8 bytes)
- // - Version (4 bytes)
- // - Packet Number (1 byte)
- // - Message Authentication Hash (12 bytes)
- // - Frame Type (1 byte)
- // - Stream ID (1 byte)
- // - ClientHello tag (4 bytes)
- // - ClientHello num tags (2 bytes)
- // - Padding (2 bytes)
- // - SNI tag (4 bytes)
- // - SNI end offset (4 bytes)
- // - QLVE tag (4 bytes)
- // - QLVE end offset (4 bytes)
- return 52 + sni.length();
-}
-
-QuicPacketBuffer QuicLegacyVersionEncapsulator::GetPacketBuffer() {
- return packet_buffer_;
-}
-
-void QuicLegacyVersionEncapsulator::OnSerializedPacket(
- SerializedPacket serialized_packet) {
- if (encrypted_length_ != 0) {
- unrecoverable_failure_encountered_ = true;
- QUIC_BUG(quic_bug_10615_1) << "OnSerializedPacket called twice";
- return;
- }
- if (serialized_packet.encrypted_length == 0) {
- unrecoverable_failure_encountered_ = true;
- QUIC_BUG(quic_bug_10615_2) << "OnSerializedPacket called with empty packet";
- return;
- }
- encrypted_length_ = serialized_packet.encrypted_length;
-}
-
-void QuicLegacyVersionEncapsulator::OnUnrecoverableError(
- QuicErrorCode error,
- const std::string& error_details) {
- unrecoverable_failure_encountered_ = true;
- QUIC_BUG(quic_bug_10615_3) << "QuicLegacyVersionEncapsulator received error "
- << error << ": " << error_details;
-}
-
-bool QuicLegacyVersionEncapsulator::ShouldGeneratePacket(
- HasRetransmittableData /*retransmittable*/,
- IsHandshake /*handshake*/) {
- return true;
-}
-
-const QuicFrames
-QuicLegacyVersionEncapsulator::MaybeBundleAckOpportunistically() {
- // We do not want to ever include any ACKs here, return an empty array.
- return QuicFrames();
-}
-
-SerializedPacketFate QuicLegacyVersionEncapsulator::GetSerializedPacketFate(
- bool /*is_mtu_discovery*/,
- EncryptionLevel /*encryption_level*/) {
- return SEND_TO_WRITER;
-}
-
-// static
-QuicPacketLength QuicLegacyVersionEncapsulator::Encapsulate(
- absl::string_view sni,
- absl::string_view inner_packet,
- const QuicConnectionId& server_connection_id,
- QuicTime creation_time,
- QuicByteCount outer_max_packet_length,
- char* out) {
- if (outer_max_packet_length > kMaxOutgoingPacketSize) {
- outer_max_packet_length = kMaxOutgoingPacketSize;
- }
- CryptoHandshakeMessage outer_chlo;
- outer_chlo.set_tag(kCHLO);
- outer_chlo.SetStringPiece(kSNI, sni);
- outer_chlo.SetStringPiece(kQLVE, inner_packet);
- const QuicData& serialized_outer_chlo = outer_chlo.GetSerialized();
- QUICHE_DCHECK(!LegacyVersionForEncapsulation().UsesCryptoFrames());
- QUICHE_DCHECK(LegacyVersionForEncapsulation().UsesQuicCrypto());
- QuicStreamFrame outer_stream_frame(
- QuicUtils::GetCryptoStreamId(
- LegacyVersionForEncapsulation().transport_version),
- /*fin=*/false,
- /*offset=*/0, serialized_outer_chlo.AsStringPiece());
- QuicFramer outer_framer(
- ParsedQuicVersionVector{LegacyVersionForEncapsulation()}, creation_time,
- Perspective::IS_CLIENT, kQuicDefaultConnectionIdLength);
- outer_framer.SetInitialObfuscators(server_connection_id);
- char outer_encrypted_packet[kMaxOutgoingPacketSize];
- QuicPacketBuffer outer_packet_buffer(outer_encrypted_packet, nullptr);
- QuicLegacyVersionEncapsulator creator_delegate(outer_packet_buffer);
- QuicPacketCreator outer_creator(server_connection_id, &outer_framer,
- &creator_delegate);
- outer_creator.SetMaxPacketLength(outer_max_packet_length);
- outer_creator.set_encryption_level(ENCRYPTION_INITIAL);
- outer_creator.SetTransmissionType(NOT_RETRANSMISSION);
- if (!outer_creator.AddPaddedSavedFrame(QuicFrame(outer_stream_frame),
- NOT_RETRANSMISSION)) {
- QUIC_BUG(quic_bug_10615_4)
- << "Failed to add Legacy Version Encapsulation stream frame "
- "(max packet length is "
- << outer_creator.max_packet_length() << ") " << outer_stream_frame;
- return 0;
- }
- outer_creator.FlushCurrentPacket();
- const QuicPacketLength encrypted_length = creator_delegate.encrypted_length_;
- if (creator_delegate.unrecoverable_failure_encountered_ ||
- encrypted_length == 0) {
- QUIC_BUG(quic_bug_10615_5)
- << "Failed to perform Legacy Version Encapsulation of "
- << inner_packet.length() << " bytes";
- return 0;
- }
- if (encrypted_length > kMaxOutgoingPacketSize) {
- QUIC_BUG(quic_bug_10615_6)
- << "Legacy Version Encapsulation outer creator generated a "
- "packet with unexpected length "
- << encrypted_length;
- return 0;
- }
-
- QUIC_DLOG(INFO) << "Successfully performed Legacy Version Encapsulation from "
- << inner_packet.length() << " bytes to " << encrypted_length;
-
- // Replace our current packet with the encapsulated one.
- memcpy(out, outer_encrypted_packet, encrypted_length);
- return encrypted_length;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_legacy_version_encapsulator.h b/chromium/net/third_party/quiche/src/quic/core/quic_legacy_version_encapsulator.h
deleted file mode 100644
index 1d528fec62c..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_legacy_version_encapsulator.h
+++ /dev/null
@@ -1,74 +0,0 @@
-// Copyright (c) 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_LEGACY_VERSION_ENCAPSULATOR_H_
-#define QUICHE_QUIC_CORE_QUIC_LEGACY_VERSION_ENCAPSULATOR_H_
-
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_packet_creator.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// QuicLegacyVersionEncapsulator is responsible for encapsulation of packets
-// using Legacy Version Encapsulation.
-
-class QUIC_EXPORT_PRIVATE QuicLegacyVersionEncapsulator
- : public QuicPacketCreator::DelegateInterface {
- public:
- // Encapsulates |inner_packet| into a new encapsulated packet that uses a
- // CHLO of version LegacyVersionForEncapsulation() with server name |sni|
- // exposed and using |server_connection_id|. The packet will be padded up to
- // |outer_max_packet_length| bytes if necessary. On failure, returns 0. On
- // success, returns the length of the outer encapsulated packet, and copies
- // the contents of the encapsulated packet to |out|. |out| must point to a
- // valid memory buffer capable of holding kMaxOutgoingPacketSize bytes.
- static QuicPacketLength Encapsulate(
- absl::string_view sni,
- absl::string_view inner_packet,
- const QuicConnectionId& server_connection_id,
- QuicTime creation_time,
- QuicByteCount outer_max_packet_length,
- char* out);
-
- // Returns the number of bytes of minimum overhead caused by Legacy Version
- // Encapsulation, based on the length of the provided server name |sni|.
- // The overhead may be higher due to extra padding added.
- static QuicByteCount GetMinimumOverhead(absl::string_view sni);
-
- // Overrides for QuicPacketCreator::DelegateInterface.
- QuicPacketBuffer GetPacketBuffer() override;
- void OnSerializedPacket(SerializedPacket serialized_packet) override;
- void OnUnrecoverableError(QuicErrorCode error,
- const std::string& error_details) override;
- bool ShouldGeneratePacket(HasRetransmittableData retransmittable,
- IsHandshake handshake) override;
- const QuicFrames MaybeBundleAckOpportunistically() override;
- SerializedPacketFate GetSerializedPacketFate(
- bool is_mtu_discovery,
- EncryptionLevel encryption_level) override;
-
- ~QuicLegacyVersionEncapsulator() override;
-
- private:
- explicit QuicLegacyVersionEncapsulator(QuicPacketBuffer packet_buffer);
-
- // Disallow copy, move and assignment.
- QuicLegacyVersionEncapsulator(const QuicLegacyVersionEncapsulator&) = delete;
- QuicLegacyVersionEncapsulator(QuicLegacyVersionEncapsulator&&) = delete;
- QuicLegacyVersionEncapsulator& operator=(
- const QuicLegacyVersionEncapsulator&) = delete;
- QuicLegacyVersionEncapsulator& operator=(QuicLegacyVersionEncapsulator&&) =
- delete;
-
- QuicPacketBuffer packet_buffer_;
- QuicPacketLength encrypted_length_ = 0;
- bool unrecoverable_failure_encountered_ = false;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_QUIC_LEGACY_VERSION_ENCAPSULATOR_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_legacy_version_encapsulator_test.cc b/chromium/net/third_party/quiche/src/quic/core/quic_legacy_version_encapsulator_test.cc
deleted file mode 100644
index b0e11a3dee7..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_legacy_version_encapsulator_test.cc
+++ /dev/null
@@ -1,107 +0,0 @@
-// Copyright (c) 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_legacy_version_encapsulator.h"
-
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_versions.h"
-#include "quic/platform/api/quic_expect_bug.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/quic_test_utils.h"
-
-namespace quic {
-namespace test {
-namespace {
-
-class QuicLegacyVersionEncapsulatorTest
- : public QuicTestWithParam<ParsedQuicVersion> {
- protected:
- QuicLegacyVersionEncapsulatorTest()
- : version_(GetParam()),
- sni_("test.example.org"),
- server_connection_id_(TestConnectionId()),
- outer_max_packet_length_(kMaxOutgoingPacketSize),
- encapsulated_length_(0) {}
-
- void Encapsulate(const std::string& inner_packet) {
- encapsulated_length_ = QuicLegacyVersionEncapsulator::Encapsulate(
- sni_, inner_packet, server_connection_id_, QuicTime::Zero(),
- outer_max_packet_length_, outer_buffer_);
- }
-
- void CheckEncapsulation() {
- ASSERT_NE(encapsulated_length_, 0u);
- ASSERT_EQ(encapsulated_length_, outer_max_packet_length_);
- // Verify that the encapsulated packet parses as encapsulated.
- PacketHeaderFormat format = IETF_QUIC_LONG_HEADER_PACKET;
- QuicLongHeaderType long_packet_type;
- bool version_present;
- bool has_length_prefix;
- QuicVersionLabel version_label;
- ParsedQuicVersion parsed_version = ParsedQuicVersion::Unsupported();
- QuicConnectionId destination_connection_id, source_connection_id;
- absl::optional<absl::string_view> retry_token;
- std::string detailed_error;
- const QuicErrorCode error = QuicFramer::ParsePublicHeaderDispatcher(
- QuicEncryptedPacket(outer_buffer_, encapsulated_length_),
- kQuicDefaultConnectionIdLength, &format, &long_packet_type,
- &version_present, &has_length_prefix, &version_label, &parsed_version,
- &destination_connection_id, &source_connection_id, &retry_token,
- &detailed_error);
- ASSERT_THAT(error, IsQuicNoError()) << detailed_error;
- EXPECT_EQ(format, GOOGLE_QUIC_PACKET);
- EXPECT_TRUE(version_present);
- EXPECT_FALSE(has_length_prefix);
- EXPECT_EQ(parsed_version, LegacyVersionForEncapsulation());
- EXPECT_EQ(destination_connection_id, server_connection_id_);
- EXPECT_EQ(source_connection_id, EmptyQuicConnectionId());
- EXPECT_FALSE(retry_token.has_value());
- EXPECT_TRUE(detailed_error.empty());
- }
-
- QuicByteCount Overhead() {
- return QuicLegacyVersionEncapsulator::GetMinimumOverhead(sni_);
- }
-
- ParsedQuicVersion version_;
- std::string sni_;
- QuicConnectionId server_connection_id_;
- QuicByteCount outer_max_packet_length_;
- char outer_buffer_[kMaxOutgoingPacketSize];
- QuicPacketLength encapsulated_length_;
-};
-
-INSTANTIATE_TEST_SUITE_P(QuicLegacyVersionEncapsulatorTests,
- QuicLegacyVersionEncapsulatorTest,
- ::testing::ValuesIn(AllSupportedVersions()),
- ::testing::PrintToStringParamName());
-
-TEST_P(QuicLegacyVersionEncapsulatorTest, Simple) {
- Encapsulate("TEST_INNER_PACKET");
- CheckEncapsulation();
-}
-
-TEST_P(QuicLegacyVersionEncapsulatorTest, TooBig) {
- std::string inner_packet(kMaxOutgoingPacketSize, '?');
- EXPECT_QUIC_BUG(Encapsulate(inner_packet), "Legacy Version Encapsulation");
- ASSERT_EQ(encapsulated_length_, 0u);
-}
-
-TEST_P(QuicLegacyVersionEncapsulatorTest, BarelyFits) {
- QuicByteCount inner_size = kMaxOutgoingPacketSize - Overhead();
- std::string inner_packet(inner_size, '?');
- Encapsulate(inner_packet);
- CheckEncapsulation();
-}
-
-TEST_P(QuicLegacyVersionEncapsulatorTest, DoesNotQuiteFit) {
- QuicByteCount inner_size = 1 + kMaxOutgoingPacketSize - Overhead();
- std::string inner_packet(inner_size, '?');
- EXPECT_QUIC_BUG(Encapsulate(inner_packet), "Legacy Version Encapsulation");
- ASSERT_EQ(encapsulated_length_, 0u);
-}
-
-} // namespace
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_linux_socket_utils.cc b/chromium/net/third_party/quiche/src/quic/core/quic_linux_socket_utils.cc
deleted file mode 100644
index 888b658eec0..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_linux_socket_utils.cc
+++ /dev/null
@@ -1,315 +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 "quic/core/quic_linux_socket_utils.h"
-
-#include <linux/net_tstamp.h>
-#include <netinet/in.h>
-#include <cstdint>
-
-#include "quic/core/quic_syscall_wrapper.h"
-#include "quic/platform/api/quic_ip_address.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/platform/api/quic_socket_address.h"
-
-namespace quic {
-
-QuicMsgHdr::QuicMsgHdr(const char* buffer,
- size_t buf_len,
- const QuicSocketAddress& peer_address,
- char* cbuf,
- size_t cbuf_size)
- : iov_{const_cast<char*>(buffer), buf_len},
- cbuf_(cbuf),
- cbuf_size_(cbuf_size),
- cmsg_(nullptr) {
- // Only support unconnected sockets.
- QUICHE_DCHECK(peer_address.IsInitialized());
-
- raw_peer_address_ = peer_address.generic_address();
- hdr_.msg_name = &raw_peer_address_;
- hdr_.msg_namelen = raw_peer_address_.ss_family == AF_INET
- ? sizeof(sockaddr_in)
- : sizeof(sockaddr_in6);
-
- hdr_.msg_iov = &iov_;
- hdr_.msg_iovlen = 1;
- hdr_.msg_flags = 0;
-
- hdr_.msg_control = nullptr;
- hdr_.msg_controllen = 0;
-}
-
-void QuicMsgHdr::SetIpInNextCmsg(const QuicIpAddress& self_address) {
- if (!self_address.IsInitialized()) {
- return;
- }
-
- if (self_address.IsIPv4()) {
- QuicLinuxSocketUtils::SetIpInfoInCmsgData(
- self_address, GetNextCmsgData<in_pktinfo>(IPPROTO_IP, IP_PKTINFO));
- } else {
- QuicLinuxSocketUtils::SetIpInfoInCmsgData(
- self_address, GetNextCmsgData<in6_pktinfo>(IPPROTO_IPV6, IPV6_PKTINFO));
- }
-}
-
-void* QuicMsgHdr::GetNextCmsgDataInternal(int cmsg_level,
- int cmsg_type,
- size_t data_size) {
- // msg_controllen needs to be increased first, otherwise CMSG_NXTHDR will
- // return nullptr.
- hdr_.msg_controllen += CMSG_SPACE(data_size);
- QUICHE_DCHECK_LE(hdr_.msg_controllen, cbuf_size_);
-
- if (cmsg_ == nullptr) {
- QUICHE_DCHECK_EQ(nullptr, hdr_.msg_control);
- memset(cbuf_, 0, cbuf_size_);
- hdr_.msg_control = cbuf_;
- cmsg_ = CMSG_FIRSTHDR(&hdr_);
- } else {
- QUICHE_DCHECK_NE(nullptr, hdr_.msg_control);
- cmsg_ = CMSG_NXTHDR(&hdr_, cmsg_);
- }
-
- QUICHE_DCHECK_NE(nullptr, cmsg_) << "Insufficient control buffer space";
-
- cmsg_->cmsg_len = CMSG_LEN(data_size);
- cmsg_->cmsg_level = cmsg_level;
- cmsg_->cmsg_type = cmsg_type;
-
- return CMSG_DATA(cmsg_);
-}
-
-void QuicMMsgHdr::InitOneHeader(int i, const BufferedWrite& buffered_write) {
- mmsghdr* mhdr = GetMMsgHdr(i);
- msghdr* hdr = &mhdr->msg_hdr;
- iovec* iov = GetIov(i);
-
- iov->iov_base = const_cast<char*>(buffered_write.buffer);
- iov->iov_len = buffered_write.buf_len;
- hdr->msg_iov = iov;
- hdr->msg_iovlen = 1;
- hdr->msg_control = nullptr;
- hdr->msg_controllen = 0;
-
- // Only support unconnected sockets.
- QUICHE_DCHECK(buffered_write.peer_address.IsInitialized());
-
- sockaddr_storage* peer_address_storage = GetPeerAddressStorage(i);
- *peer_address_storage = buffered_write.peer_address.generic_address();
- hdr->msg_name = peer_address_storage;
- hdr->msg_namelen = peer_address_storage->ss_family == AF_INET
- ? sizeof(sockaddr_in)
- : sizeof(sockaddr_in6);
-}
-
-void QuicMMsgHdr::SetIpInNextCmsg(int i, const QuicIpAddress& self_address) {
- if (!self_address.IsInitialized()) {
- return;
- }
-
- if (self_address.IsIPv4()) {
- QuicLinuxSocketUtils::SetIpInfoInCmsgData(
- self_address, GetNextCmsgData<in_pktinfo>(i, IPPROTO_IP, IP_PKTINFO));
- } else {
- QuicLinuxSocketUtils::SetIpInfoInCmsgData(
- self_address,
- GetNextCmsgData<in6_pktinfo>(i, IPPROTO_IPV6, IPV6_PKTINFO));
- }
-}
-
-void* QuicMMsgHdr::GetNextCmsgDataInternal(int i,
- int cmsg_level,
- int cmsg_type,
- size_t data_size) {
- mmsghdr* mhdr = GetMMsgHdr(i);
- msghdr* hdr = &mhdr->msg_hdr;
- cmsghdr*& cmsg = *GetCmsgHdr(i);
-
- // msg_controllen needs to be increased first, otherwise CMSG_NXTHDR will
- // return nullptr.
- hdr->msg_controllen += CMSG_SPACE(data_size);
- QUICHE_DCHECK_LE(hdr->msg_controllen, cbuf_size_);
-
- if (cmsg == nullptr) {
- QUICHE_DCHECK_EQ(nullptr, hdr->msg_control);
- hdr->msg_control = GetCbuf(i);
- cmsg = CMSG_FIRSTHDR(hdr);
- } else {
- QUICHE_DCHECK_NE(nullptr, hdr->msg_control);
- cmsg = CMSG_NXTHDR(hdr, cmsg);
- }
-
- QUICHE_DCHECK_NE(nullptr, cmsg) << "Insufficient control buffer space";
-
- cmsg->cmsg_len = CMSG_LEN(data_size);
- cmsg->cmsg_level = cmsg_level;
- cmsg->cmsg_type = cmsg_type;
-
- return CMSG_DATA(cmsg);
-}
-
-int QuicMMsgHdr::num_bytes_sent(int num_packets_sent) {
- QUICHE_DCHECK_LE(0, num_packets_sent);
- QUICHE_DCHECK_LE(num_packets_sent, num_msgs_);
-
- int bytes_sent = 0;
- iovec* iov = GetIov(0);
- for (int i = 0; i < num_packets_sent; ++i) {
- bytes_sent += iov[i].iov_len;
- }
- return bytes_sent;
-}
-
-// static
-int QuicLinuxSocketUtils::GetUDPSegmentSize(int fd) {
- int optval;
- socklen_t optlen = sizeof(optval);
- int rc = getsockopt(fd, SOL_UDP, UDP_SEGMENT, &optval, &optlen);
- if (rc < 0) {
- QUIC_LOG_EVERY_N_SEC(INFO, 10)
- << "getsockopt(UDP_SEGMENT) failed: " << strerror(errno);
- return -1;
- }
- QUIC_LOG_EVERY_N_SEC(INFO, 10)
- << "getsockopt(UDP_SEGMENT) returned segment size: " << optval;
- return optval;
-}
-
-// static
-bool QuicLinuxSocketUtils::EnableReleaseTime(int fd, clockid_t clockid) {
- // TODO(wub): Change to sock_txtime once it is available in linux/net_tstamp.h
- struct LinuxSockTxTime {
- clockid_t clockid; /* reference clockid */
- uint32_t flags; /* flags defined by enum txtime_flags */
- };
-
- LinuxSockTxTime so_txtime_val{clockid, 0};
-
- if (setsockopt(fd, SOL_SOCKET, SO_TXTIME, &so_txtime_val,
- sizeof(so_txtime_val)) != 0) {
- QUIC_LOG_EVERY_N_SEC(INFO, 10)
- << "setsockopt(SOL_SOCKET,SO_TXTIME) failed: " << strerror(errno);
- return false;
- }
-
- return true;
-}
-
-// static
-bool QuicLinuxSocketUtils::GetTtlFromMsghdr(struct msghdr* hdr, int* ttl) {
- if (hdr->msg_controllen > 0) {
- struct cmsghdr* cmsg;
- for (cmsg = CMSG_FIRSTHDR(hdr); cmsg != nullptr;
- cmsg = CMSG_NXTHDR(hdr, cmsg)) {
- if ((cmsg->cmsg_level == IPPROTO_IP && cmsg->cmsg_type == IP_TTL) ||
- (cmsg->cmsg_level == IPPROTO_IPV6 &&
- cmsg->cmsg_type == IPV6_HOPLIMIT)) {
- *ttl = *(reinterpret_cast<int*>(CMSG_DATA(cmsg)));
- return true;
- }
- }
- }
- return false;
-}
-
-// static
-void QuicLinuxSocketUtils::SetIpInfoInCmsgData(
- const QuicIpAddress& self_address,
- void* cmsg_data) {
- QUICHE_DCHECK(self_address.IsInitialized());
- const std::string& address_str = self_address.ToPackedString();
- if (self_address.IsIPv4()) {
- in_pktinfo* pktinfo = static_cast<in_pktinfo*>(cmsg_data);
- pktinfo->ipi_ifindex = 0;
- memcpy(&pktinfo->ipi_spec_dst, address_str.c_str(), address_str.length());
- } else if (self_address.IsIPv6()) {
- in6_pktinfo* pktinfo = static_cast<in6_pktinfo*>(cmsg_data);
- memcpy(&pktinfo->ipi6_addr, address_str.c_str(), address_str.length());
- } else {
- QUIC_BUG(quic_bug_10598_1) << "Unrecognized IPAddress";
- }
-}
-
-// static
-size_t QuicLinuxSocketUtils::SetIpInfoInCmsg(const QuicIpAddress& self_address,
- cmsghdr* cmsg) {
- std::string address_string;
- if (self_address.IsIPv4()) {
- cmsg->cmsg_len = CMSG_LEN(sizeof(in_pktinfo));
- cmsg->cmsg_level = IPPROTO_IP;
- cmsg->cmsg_type = IP_PKTINFO;
- in_pktinfo* pktinfo = reinterpret_cast<in_pktinfo*>(CMSG_DATA(cmsg));
- memset(pktinfo, 0, sizeof(in_pktinfo));
- pktinfo->ipi_ifindex = 0;
- address_string = self_address.ToPackedString();
- memcpy(&pktinfo->ipi_spec_dst, address_string.c_str(),
- address_string.length());
- return sizeof(in_pktinfo);
- } else if (self_address.IsIPv6()) {
- cmsg->cmsg_len = CMSG_LEN(sizeof(in6_pktinfo));
- cmsg->cmsg_level = IPPROTO_IPV6;
- cmsg->cmsg_type = IPV6_PKTINFO;
- in6_pktinfo* pktinfo = reinterpret_cast<in6_pktinfo*>(CMSG_DATA(cmsg));
- memset(pktinfo, 0, sizeof(in6_pktinfo));
- address_string = self_address.ToPackedString();
- memcpy(&pktinfo->ipi6_addr, address_string.c_str(),
- address_string.length());
- return sizeof(in6_pktinfo);
- } else {
- QUIC_BUG(quic_bug_10598_2) << "Unrecognized IPAddress";
- return 0;
- }
-}
-
-// static
-WriteResult QuicLinuxSocketUtils::WritePacket(int fd, const QuicMsgHdr& hdr) {
- int rc;
- do {
- rc = GetGlobalSyscallWrapper()->Sendmsg(fd, hdr.hdr(), 0);
- } while (rc < 0 && errno == EINTR);
- if (rc >= 0) {
- return WriteResult(WRITE_STATUS_OK, rc);
- }
- return WriteResult((errno == EAGAIN || errno == EWOULDBLOCK)
- ? WRITE_STATUS_BLOCKED
- : WRITE_STATUS_ERROR,
- errno);
-}
-
-// static
-WriteResult QuicLinuxSocketUtils::WriteMultiplePackets(int fd,
- QuicMMsgHdr* mhdr,
- int* num_packets_sent) {
- *num_packets_sent = 0;
-
- if (mhdr->num_msgs() <= 0) {
- return WriteResult(WRITE_STATUS_ERROR, EINVAL);
- }
-
- int rc;
- do {
- rc = GetGlobalSyscallWrapper()->Sendmmsg(fd, mhdr->mhdr(), mhdr->num_msgs(),
- 0);
- } while (rc < 0 && errno == EINTR);
-
- if (rc > 0) {
- *num_packets_sent = rc;
-
- return WriteResult(WRITE_STATUS_OK, mhdr->num_bytes_sent(rc));
- } else if (rc == 0) {
- QUIC_BUG(quic_bug_10598_3)
- << "sendmmsg returned 0, returning WRITE_STATUS_ERROR. errno: "
- << errno;
- errno = EIO;
- }
-
- return WriteResult((errno == EAGAIN || errno == EWOULDBLOCK)
- ? WRITE_STATUS_BLOCKED
- : WRITE_STATUS_ERROR,
- errno);
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_linux_socket_utils.h b/chromium/net/third_party/quiche/src/quic/core/quic_linux_socket_utils.h
deleted file mode 100644
index 5bbd875180b..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_linux_socket_utils.h
+++ /dev/null
@@ -1,297 +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_IMPL_QUIC_LINUX_SOCKET_UTILS_H_
-#define QUICHE_QUIC_PLATFORM_IMPL_QUIC_LINUX_SOCKET_UTILS_H_
-
-#include <errno.h>
-#include <stddef.h>
-#include <string.h>
-#include <sys/socket.h>
-#include <sys/uio.h>
-#include <deque>
-#include <functional>
-#include <iterator>
-#include <memory>
-#include <type_traits>
-#include <utility>
-
-#include "quic/core/quic_packet_writer.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_ip_address.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/platform/api/quic_socket_address.h"
-
-#ifndef SOL_UDP
-#define SOL_UDP 17
-#endif
-
-#ifndef UDP_SEGMENT
-#define UDP_SEGMENT 103
-#endif
-
-#ifndef UDP_MAX_SEGMENTS
-#define UDP_MAX_SEGMENTS (1 << 6UL)
-#endif
-
-#ifndef SO_TXTIME
-#define SO_TXTIME 61
-#endif
-
-namespace quic {
-
-const int kCmsgSpaceForIpv4 = CMSG_SPACE(sizeof(in_pktinfo));
-const int kCmsgSpaceForIpv6 = CMSG_SPACE(sizeof(in6_pktinfo));
-// kCmsgSpaceForIp should be big enough to hold both IPv4 and IPv6 packet info.
-const int kCmsgSpaceForIp = (kCmsgSpaceForIpv4 < kCmsgSpaceForIpv6)
- ? kCmsgSpaceForIpv6
- : kCmsgSpaceForIpv4;
-
-const int kCmsgSpaceForSegmentSize = CMSG_SPACE(sizeof(uint16_t));
-
-const int kCmsgSpaceForTxTime = CMSG_SPACE(sizeof(uint64_t));
-
-const int kCmsgSpaceForTTL = CMSG_SPACE(sizeof(int));
-
-// QuicMsgHdr is used to build msghdr objects that can be used send packets via
-// ::sendmsg.
-//
-// Example:
-// // cbuf holds control messages(cmsgs). The size is determined from what
-// // cmsgs will be set for this msghdr.
-// char cbuf[kCmsgSpaceForIp + kCmsgSpaceForSegmentSize];
-// QuicMsgHdr hdr(packet_buf, packet_buf_len, peer_addr, cbuf, sizeof(cbuf));
-//
-// // Set IP in cmsgs.
-// hdr.SetIpInNextCmsg(self_addr);
-//
-// // Set GSO size in cmsgs.
-// *hdr.GetNextCmsgData<uint16_t>(SOL_UDP, UDP_SEGMENT) = 1200;
-//
-// QuicLinuxSocketUtils::WritePacket(fd, hdr);
-class QUIC_EXPORT_PRIVATE QuicMsgHdr {
- public:
- QuicMsgHdr(const char* buffer,
- size_t buf_len,
- const QuicSocketAddress& peer_address,
- char* cbuf,
- size_t cbuf_size);
-
- // Set IP info in the next cmsg. Both IPv4 and IPv6 are supported.
- void SetIpInNextCmsg(const QuicIpAddress& self_address);
-
- template <typename DataType>
- DataType* GetNextCmsgData(int cmsg_level, int cmsg_type) {
- return reinterpret_cast<DataType*>(
- GetNextCmsgDataInternal(cmsg_level, cmsg_type, sizeof(DataType)));
- }
-
- const msghdr* hdr() const { return &hdr_; }
-
- protected:
- void* GetNextCmsgDataInternal(int cmsg_level,
- int cmsg_type,
- size_t data_size);
-
- msghdr hdr_;
- iovec iov_;
- sockaddr_storage raw_peer_address_;
- char* cbuf_;
- const size_t cbuf_size_;
- // The last cmsg populated so far. nullptr means nothing has been populated.
- cmsghdr* cmsg_;
-};
-
-// BufferedWrite holds all information needed to send a packet.
-struct QUIC_EXPORT_PRIVATE BufferedWrite {
- BufferedWrite(const char* buffer,
- size_t buf_len,
- const QuicIpAddress& self_address,
- const QuicSocketAddress& peer_address)
- : BufferedWrite(buffer,
- buf_len,
- self_address,
- peer_address,
- std::unique_ptr<PerPacketOptions>(),
- /*release_time=*/0) {}
-
- BufferedWrite(const char* buffer,
- size_t buf_len,
- const QuicIpAddress& self_address,
- const QuicSocketAddress& peer_address,
- std::unique_ptr<PerPacketOptions> options,
- uint64_t release_time)
- : buffer(buffer),
- buf_len(buf_len),
- self_address(self_address),
- peer_address(peer_address),
- options(std::move(options)),
- release_time(release_time) {}
-
- const char* buffer; // Not owned.
- size_t buf_len;
- QuicIpAddress self_address;
- QuicSocketAddress peer_address;
- std::unique_ptr<PerPacketOptions> options;
-
- // The release time according to the owning packet writer's clock, which is
- // often not a QuicClock. Calculated from packet writer's Now() and the
- // release time delay in |options|.
- // 0 means it can be sent at the same time as the previous packet in a batch,
- // or can be sent Now() if this is the first packet of a batch.
- uint64_t release_time;
-};
-
-// QuicMMsgHdr is used to build mmsghdr objects that can be used to send
-// multiple packets at once via ::sendmmsg.
-//
-// Example:
-// quiche::QuicheCircularDeque<BufferedWrite> buffered_writes;
-// ... (Populate buffered_writes) ...
-//
-// QuicMMsgHdr mhdr(
-// buffered_writes.begin(), buffered_writes.end(), kCmsgSpaceForIp,
-// [](QuicMMsgHdr* mhdr, int i, const BufferedWrite& buffered_write) {
-// mhdr->SetIpInNextCmsg(i, buffered_write.self_address);
-// });
-//
-// int num_packets_sent;
-// QuicSocketUtils::WriteMultiplePackets(fd, &mhdr, &num_packets_sent);
-class QUIC_EXPORT_PRIVATE QuicMMsgHdr {
- public:
- using ControlBufferInitializer = std::function<
- void(QuicMMsgHdr* mhdr, int i, const BufferedWrite& buffered_write)>;
- template <typename IteratorT>
- QuicMMsgHdr(const IteratorT& first,
- const IteratorT& last,
- size_t cbuf_size,
- ControlBufferInitializer cbuf_initializer)
- : num_msgs_(std::distance(first, last)), cbuf_size_(cbuf_size) {
- static_assert(
- std::is_same<typename std::iterator_traits<IteratorT>::value_type,
- BufferedWrite>::value,
- "Must iterate over a collection of BufferedWrite.");
-
- QUICHE_DCHECK_LE(0, num_msgs_);
- if (num_msgs_ == 0) {
- return;
- }
-
- storage_.reset(new char[StorageSize()]);
- memset(&storage_[0], 0, StorageSize());
-
- int i = -1;
- for (auto it = first; it != last; ++it) {
- ++i;
-
- InitOneHeader(i, *it);
- if (cbuf_initializer) {
- cbuf_initializer(this, i, *it);
- }
- }
- }
-
- void SetIpInNextCmsg(int i, const QuicIpAddress& self_address);
-
- template <typename DataType>
- DataType* GetNextCmsgData(int i, int cmsg_level, int cmsg_type) {
- return reinterpret_cast<DataType*>(
- GetNextCmsgDataInternal(i, cmsg_level, cmsg_type, sizeof(DataType)));
- }
-
- mmsghdr* mhdr() { return GetMMsgHdr(0); }
-
- int num_msgs() const { return num_msgs_; }
-
- // Get the total number of bytes in the first |num_packets_sent| packets.
- int num_bytes_sent(int num_packets_sent);
-
- protected:
- void InitOneHeader(int i, const BufferedWrite& buffered_write);
-
- void* GetNextCmsgDataInternal(int i,
- int cmsg_level,
- int cmsg_type,
- size_t data_size);
-
- size_t StorageSize() const {
- return num_msgs_ *
- (sizeof(mmsghdr) + sizeof(iovec) + sizeof(sockaddr_storage) +
- sizeof(cmsghdr*) + cbuf_size_);
- }
-
- mmsghdr* GetMMsgHdr(int i) {
- auto* first = reinterpret_cast<mmsghdr*>(&storage_[0]);
- return &first[i];
- }
-
- iovec* GetIov(int i) {
- auto* first = reinterpret_cast<iovec*>(GetMMsgHdr(num_msgs_));
- return &first[i];
- }
-
- sockaddr_storage* GetPeerAddressStorage(int i) {
- auto* first = reinterpret_cast<sockaddr_storage*>(GetIov(num_msgs_));
- return &first[i];
- }
-
- cmsghdr** GetCmsgHdr(int i) {
- auto* first = reinterpret_cast<cmsghdr**>(GetPeerAddressStorage(num_msgs_));
- return &first[i];
- }
-
- char* GetCbuf(int i) {
- auto* first = reinterpret_cast<char*>(GetCmsgHdr(num_msgs_));
- return &first[i * cbuf_size_];
- }
-
- const int num_msgs_;
- // Size of cmsg buffer for each message.
- const size_t cbuf_size_;
- // storage_ holds the memory of
- // |num_msgs_| mmsghdr
- // |num_msgs_| iovec
- // |num_msgs_| sockaddr_storage, for peer addresses
- // |num_msgs_| cmsghdr*
- // |num_msgs_| cbuf, each of size cbuf_size
- std::unique_ptr<char[]> storage_;
-};
-
-class QUIC_EXPORT_PRIVATE QuicLinuxSocketUtils {
- public:
- // Return the UDP segment size of |fd|, 0 means segment size has not been set
- // on this socket. If GSO is not supported, return -1.
- static int GetUDPSegmentSize(int fd);
-
- // Enable release time on |fd|.
- static bool EnableReleaseTime(int fd, clockid_t clockid);
-
- // If the msghdr contains an IP_TTL entry, this will set ttl to the correct
- // value and return true. Otherwise it will return false.
- static bool GetTtlFromMsghdr(struct msghdr* hdr, int* ttl);
-
- // Set IP(self_address) in |cmsg_data|. Does not touch other fields in the
- // containing cmsghdr.
- static void SetIpInfoInCmsgData(const QuicIpAddress& self_address,
- void* cmsg_data);
-
- // A helper for WritePacket which fills in the cmsg with the supplied self
- // address.
- // Returns the length of the packet info structure used.
- static size_t SetIpInfoInCmsg(const QuicIpAddress& self_address,
- cmsghdr* cmsg);
-
- // Writes the packet in |hdr| to the socket, using ::sendmsg.
- static WriteResult WritePacket(int fd, const QuicMsgHdr& hdr);
-
- // Writes the packets in |mhdr| to the socket, using ::sendmmsg if available.
- static WriteResult WriteMultiplePackets(int fd,
- QuicMMsgHdr* mhdr,
- int* num_packets_sent);
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_PLATFORM_IMPL_QUIC_LINUX_SOCKET_UTILS_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_linux_socket_utils_test.cc b/chromium/net/third_party/quiche/src/quic/core/quic_linux_socket_utils_test.cc
deleted file mode 100644
index 588c2be8480..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_linux_socket_utils_test.cc
+++ /dev/null
@@ -1,329 +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 "quic/core/quic_linux_socket_utils.h"
-
-#include <netinet/in.h>
-#include <stdint.h>
-#include <cstddef>
-#include <sstream>
-#include <vector>
-
-#include <string>
-
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/quic_mock_syscall_wrapper.h"
-#include "common/quiche_circular_deque.h"
-
-using testing::_;
-using testing::InSequence;
-using testing::Invoke;
-
-namespace quic {
-namespace test {
-namespace {
-
-class QuicLinuxSocketUtilsTest : public QuicTest {
- protected:
- WriteResult TestWriteMultiplePackets(
- int fd,
- const quiche::QuicheCircularDeque<BufferedWrite>::const_iterator& first,
- const quiche::QuicheCircularDeque<BufferedWrite>::const_iterator& last,
- int* num_packets_sent) {
- QuicMMsgHdr mhdr(
- first, last, kCmsgSpaceForIp,
- [](QuicMMsgHdr* mhdr, int i, const BufferedWrite& buffered_write) {
- mhdr->SetIpInNextCmsg(i, buffered_write.self_address);
- });
-
- WriteResult res =
- QuicLinuxSocketUtils::WriteMultiplePackets(fd, &mhdr, num_packets_sent);
- return res;
- }
-
- MockQuicSyscallWrapper mock_syscalls_;
- ScopedGlobalSyscallWrapperOverride syscall_override_{&mock_syscalls_};
-};
-
-void CheckIpAndTtlInCbuf(msghdr* hdr,
- const void* cbuf,
- const QuicIpAddress& self_addr,
- int ttl) {
- const bool is_ipv4 = self_addr.IsIPv4();
- const size_t ip_cmsg_space = is_ipv4 ? kCmsgSpaceForIpv4 : kCmsgSpaceForIpv6;
-
- EXPECT_EQ(cbuf, hdr->msg_control);
- EXPECT_EQ(ip_cmsg_space + CMSG_SPACE(sizeof(uint16_t)), hdr->msg_controllen);
-
- cmsghdr* cmsg = CMSG_FIRSTHDR(hdr);
- EXPECT_EQ(cmsg->cmsg_len, is_ipv4 ? CMSG_LEN(sizeof(in_pktinfo))
- : CMSG_LEN(sizeof(in6_pktinfo)));
- EXPECT_EQ(cmsg->cmsg_level, is_ipv4 ? IPPROTO_IP : IPPROTO_IPV6);
- EXPECT_EQ(cmsg->cmsg_type, is_ipv4 ? IP_PKTINFO : IPV6_PKTINFO);
-
- const std::string& self_addr_str = self_addr.ToPackedString();
- if (is_ipv4) {
- in_pktinfo* pktinfo = reinterpret_cast<in_pktinfo*>(CMSG_DATA(cmsg));
- EXPECT_EQ(0, memcmp(&pktinfo->ipi_spec_dst, self_addr_str.c_str(),
- self_addr_str.length()));
- } else {
- in6_pktinfo* pktinfo = reinterpret_cast<in6_pktinfo*>(CMSG_DATA(cmsg));
- EXPECT_EQ(0, memcmp(&pktinfo->ipi6_addr, self_addr_str.c_str(),
- self_addr_str.length()));
- }
-
- cmsg = CMSG_NXTHDR(hdr, cmsg);
- EXPECT_EQ(cmsg->cmsg_len, CMSG_LEN(sizeof(int)));
- EXPECT_EQ(cmsg->cmsg_level, is_ipv4 ? IPPROTO_IP : IPPROTO_IPV6);
- EXPECT_EQ(cmsg->cmsg_type, is_ipv4 ? IP_TTL : IPV6_HOPLIMIT);
- EXPECT_EQ(ttl, *reinterpret_cast<int*>(CMSG_DATA(cmsg)));
-
- EXPECT_EQ(nullptr, CMSG_NXTHDR(hdr, cmsg));
-}
-
-void CheckMsghdrWithoutCbuf(const msghdr* hdr,
- const void* buffer,
- size_t buf_len,
- const QuicSocketAddress& peer_addr) {
- EXPECT_EQ(
- peer_addr.host().IsIPv4() ? sizeof(sockaddr_in) : sizeof(sockaddr_in6),
- hdr->msg_namelen);
- sockaddr_storage peer_generic_addr = peer_addr.generic_address();
- EXPECT_EQ(0, memcmp(hdr->msg_name, &peer_generic_addr, hdr->msg_namelen));
- EXPECT_EQ(1u, hdr->msg_iovlen);
- EXPECT_EQ(buffer, hdr->msg_iov->iov_base);
- EXPECT_EQ(buf_len, hdr->msg_iov->iov_len);
- EXPECT_EQ(0, hdr->msg_flags);
- EXPECT_EQ(nullptr, hdr->msg_control);
- EXPECT_EQ(0u, hdr->msg_controllen);
-}
-
-void CheckIpAndGsoSizeInCbuf(msghdr* hdr,
- const void* cbuf,
- const QuicIpAddress& self_addr,
- uint16_t gso_size) {
- const bool is_ipv4 = self_addr.IsIPv4();
- const size_t ip_cmsg_space = is_ipv4 ? kCmsgSpaceForIpv4 : kCmsgSpaceForIpv6;
-
- EXPECT_EQ(cbuf, hdr->msg_control);
- EXPECT_EQ(ip_cmsg_space + CMSG_SPACE(sizeof(uint16_t)), hdr->msg_controllen);
-
- cmsghdr* cmsg = CMSG_FIRSTHDR(hdr);
- EXPECT_EQ(cmsg->cmsg_len, is_ipv4 ? CMSG_LEN(sizeof(in_pktinfo))
- : CMSG_LEN(sizeof(in6_pktinfo)));
- EXPECT_EQ(cmsg->cmsg_level, is_ipv4 ? IPPROTO_IP : IPPROTO_IPV6);
- EXPECT_EQ(cmsg->cmsg_type, is_ipv4 ? IP_PKTINFO : IPV6_PKTINFO);
-
- const std::string& self_addr_str = self_addr.ToPackedString();
- if (is_ipv4) {
- in_pktinfo* pktinfo = reinterpret_cast<in_pktinfo*>(CMSG_DATA(cmsg));
- EXPECT_EQ(0, memcmp(&pktinfo->ipi_spec_dst, self_addr_str.c_str(),
- self_addr_str.length()));
- } else {
- in6_pktinfo* pktinfo = reinterpret_cast<in6_pktinfo*>(CMSG_DATA(cmsg));
- EXPECT_EQ(0, memcmp(&pktinfo->ipi6_addr, self_addr_str.c_str(),
- self_addr_str.length()));
- }
-
- cmsg = CMSG_NXTHDR(hdr, cmsg);
- EXPECT_EQ(cmsg->cmsg_len, CMSG_LEN(sizeof(uint16_t)));
- EXPECT_EQ(cmsg->cmsg_level, SOL_UDP);
- EXPECT_EQ(cmsg->cmsg_type, UDP_SEGMENT);
- EXPECT_EQ(gso_size, *reinterpret_cast<uint16_t*>(CMSG_DATA(cmsg)));
-
- EXPECT_EQ(nullptr, CMSG_NXTHDR(hdr, cmsg));
-}
-
-TEST_F(QuicLinuxSocketUtilsTest, QuicMsgHdr) {
- QuicSocketAddress peer_addr(QuicIpAddress::Loopback4(), 1234);
- char packet_buf[1024];
-
- QuicMsgHdr quic_hdr(packet_buf, sizeof(packet_buf), peer_addr, nullptr, 0);
- CheckMsghdrWithoutCbuf(quic_hdr.hdr(), packet_buf, sizeof(packet_buf),
- peer_addr);
-
- for (bool is_ipv4 : {true, false}) {
- QuicIpAddress self_addr =
- is_ipv4 ? QuicIpAddress::Loopback4() : QuicIpAddress::Loopback6();
- char cbuf[kCmsgSpaceForIp + kCmsgSpaceForTTL];
- QuicMsgHdr quic_hdr(packet_buf, sizeof(packet_buf), peer_addr, cbuf,
- sizeof(cbuf));
- msghdr* hdr = const_cast<msghdr*>(quic_hdr.hdr());
-
- EXPECT_EQ(nullptr, hdr->msg_control);
- EXPECT_EQ(0u, hdr->msg_controllen);
-
- quic_hdr.SetIpInNextCmsg(self_addr);
- EXPECT_EQ(cbuf, hdr->msg_control);
- const size_t ip_cmsg_space =
- is_ipv4 ? kCmsgSpaceForIpv4 : kCmsgSpaceForIpv6;
- EXPECT_EQ(ip_cmsg_space, hdr->msg_controllen);
-
- if (is_ipv4) {
- *quic_hdr.GetNextCmsgData<int>(IPPROTO_IP, IP_TTL) = 32;
- } else {
- *quic_hdr.GetNextCmsgData<int>(IPPROTO_IPV6, IPV6_HOPLIMIT) = 32;
- }
-
- CheckIpAndTtlInCbuf(hdr, cbuf, self_addr, 32);
- }
-}
-
-TEST_F(QuicLinuxSocketUtilsTest, QuicMMsgHdr) {
- quiche::QuicheCircularDeque<BufferedWrite> buffered_writes;
- char packet_buf1[1024];
- char packet_buf2[512];
- buffered_writes.emplace_back(
- packet_buf1, sizeof(packet_buf1), QuicIpAddress::Loopback4(),
- QuicSocketAddress(QuicIpAddress::Loopback4(), 4));
- buffered_writes.emplace_back(
- packet_buf2, sizeof(packet_buf2), QuicIpAddress::Loopback6(),
- QuicSocketAddress(QuicIpAddress::Loopback6(), 6));
-
- QuicMMsgHdr quic_mhdr_without_cbuf(buffered_writes.begin(),
- buffered_writes.end(), 0, nullptr);
- for (size_t i = 0; i < buffered_writes.size(); ++i) {
- const BufferedWrite& bw = buffered_writes[i];
- CheckMsghdrWithoutCbuf(&quic_mhdr_without_cbuf.mhdr()[i].msg_hdr, bw.buffer,
- bw.buf_len, bw.peer_address);
- }
-
- QuicMMsgHdr quic_mhdr_with_cbuf(
- buffered_writes.begin(), buffered_writes.end(),
- kCmsgSpaceForIp + kCmsgSpaceForSegmentSize,
- [](QuicMMsgHdr* mhdr, int i, const BufferedWrite& buffered_write) {
- mhdr->SetIpInNextCmsg(i, buffered_write.self_address);
- *mhdr->GetNextCmsgData<uint16_t>(i, SOL_UDP, UDP_SEGMENT) = 1300;
- });
- for (size_t i = 0; i < buffered_writes.size(); ++i) {
- const BufferedWrite& bw = buffered_writes[i];
- msghdr* hdr = &quic_mhdr_with_cbuf.mhdr()[i].msg_hdr;
- CheckIpAndGsoSizeInCbuf(hdr, hdr->msg_control, bw.self_address, 1300);
- }
-}
-
-TEST_F(QuicLinuxSocketUtilsTest, WriteMultiplePackets_NoPacketsToSend) {
- int num_packets_sent;
- quiche::QuicheCircularDeque<BufferedWrite> buffered_writes;
-
- EXPECT_CALL(mock_syscalls_, Sendmmsg(_, _, _, _)).Times(0);
-
- EXPECT_EQ(WriteResult(WRITE_STATUS_ERROR, EINVAL),
- TestWriteMultiplePackets(1, buffered_writes.begin(),
- buffered_writes.end(), &num_packets_sent));
-}
-
-TEST_F(QuicLinuxSocketUtilsTest, WriteMultiplePackets_WriteBlocked) {
- int num_packets_sent;
- quiche::QuicheCircularDeque<BufferedWrite> buffered_writes;
- buffered_writes.emplace_back(nullptr, 0, QuicIpAddress(),
- QuicSocketAddress(QuicIpAddress::Any4(), 0));
-
- EXPECT_CALL(mock_syscalls_, Sendmmsg(_, _, _, _))
- .WillOnce(Invoke([](int /*fd*/, mmsghdr* /*msgvec*/,
- unsigned int /*vlen*/, int /*flags*/) {
- errno = EWOULDBLOCK;
- return -1;
- }));
-
- EXPECT_EQ(WriteResult(WRITE_STATUS_BLOCKED, EWOULDBLOCK),
- TestWriteMultiplePackets(1, buffered_writes.begin(),
- buffered_writes.end(), &num_packets_sent));
- EXPECT_EQ(0, num_packets_sent);
-}
-
-TEST_F(QuicLinuxSocketUtilsTest, WriteMultiplePackets_WriteError) {
- int num_packets_sent;
- quiche::QuicheCircularDeque<BufferedWrite> buffered_writes;
- buffered_writes.emplace_back(nullptr, 0, QuicIpAddress(),
- QuicSocketAddress(QuicIpAddress::Any4(), 0));
-
- EXPECT_CALL(mock_syscalls_, Sendmmsg(_, _, _, _))
- .WillOnce(Invoke([](int /*fd*/, mmsghdr* /*msgvec*/,
- unsigned int /*vlen*/, int /*flags*/) {
- errno = EPERM;
- return -1;
- }));
-
- EXPECT_EQ(WriteResult(WRITE_STATUS_ERROR, EPERM),
- TestWriteMultiplePackets(1, buffered_writes.begin(),
- buffered_writes.end(), &num_packets_sent));
- EXPECT_EQ(0, num_packets_sent);
-}
-
-TEST_F(QuicLinuxSocketUtilsTest, WriteMultiplePackets_WriteSuccess) {
- int num_packets_sent;
- quiche::QuicheCircularDeque<BufferedWrite> buffered_writes;
- const int kNumBufferedWrites = 10;
- static_assert(kNumBufferedWrites < 256, "Must be less than 256");
- std::vector<std::string> buffer_holder;
- for (int i = 0; i < kNumBufferedWrites; ++i) {
- size_t buf_len = (i + 1) * 2;
- std::ostringstream buffer_ostream;
- while (buffer_ostream.str().length() < buf_len) {
- buffer_ostream << i;
- }
- buffer_holder.push_back(buffer_ostream.str().substr(0, buf_len - 1) + '$');
-
- buffered_writes.emplace_back(buffer_holder.back().data(), buf_len,
- QuicIpAddress(),
- QuicSocketAddress(QuicIpAddress::Any4(), 0));
-
- // Leave the first self_address uninitialized.
- if (i != 0) {
- ASSERT_TRUE(buffered_writes.back().self_address.FromString("127.0.0.1"));
- }
-
- std::ostringstream peer_ip_ostream;
- QuicIpAddress peer_ip_address;
- peer_ip_ostream << "127.0.1." << i + 1;
- ASSERT_TRUE(peer_ip_address.FromString(peer_ip_ostream.str()));
- buffered_writes.back().peer_address =
- QuicSocketAddress(peer_ip_address, i + 1);
- }
-
- InSequence s;
-
- for (int expected_num_packets_sent : {1, 2, 3, 10}) {
- SCOPED_TRACE(testing::Message()
- << "expected_num_packets_sent=" << expected_num_packets_sent);
- EXPECT_CALL(mock_syscalls_, Sendmmsg(_, _, _, _))
- .WillOnce(Invoke(
- [&](int /*fd*/, mmsghdr* msgvec, unsigned int vlen, int /*flags*/) {
- EXPECT_LE(static_cast<unsigned int>(expected_num_packets_sent),
- vlen);
- for (unsigned int i = 0; i < vlen; ++i) {
- const BufferedWrite& buffered_write = buffered_writes[i];
- const msghdr& hdr = msgvec[i].msg_hdr;
- EXPECT_EQ(1u, hdr.msg_iovlen);
- EXPECT_EQ(buffered_write.buffer, hdr.msg_iov->iov_base);
- EXPECT_EQ(buffered_write.buf_len, hdr.msg_iov->iov_len);
- sockaddr_storage expected_peer_address =
- buffered_write.peer_address.generic_address();
- EXPECT_EQ(0, memcmp(&expected_peer_address, hdr.msg_name,
- sizeof(sockaddr_storage)));
- EXPECT_EQ(buffered_write.self_address.IsInitialized(),
- hdr.msg_control != nullptr);
- }
- return expected_num_packets_sent;
- }))
- .RetiresOnSaturation();
-
- int expected_bytes_written = 0;
- for (auto it = buffered_writes.cbegin();
- it != buffered_writes.cbegin() + expected_num_packets_sent; ++it) {
- expected_bytes_written += it->buf_len;
- }
-
- EXPECT_EQ(
- WriteResult(WRITE_STATUS_OK, expected_bytes_written),
- TestWriteMultiplePackets(1, buffered_writes.cbegin(),
- buffered_writes.cend(), &num_packets_sent));
- EXPECT_EQ(expected_num_packets_sent, num_packets_sent);
- }
-}
-
-} // namespace
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_lru_cache.h b/chromium/net/third_party/quiche/src/quic/core/quic_lru_cache.h
deleted file mode 100644
index 44024b679e3..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_lru_cache.h
+++ /dev/null
@@ -1,98 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_LRU_CACHE_H_
-#define QUICHE_QUIC_CORE_QUIC_LRU_CACHE_H_
-
-#include <memory>
-
-#include "quic/platform/api/quic_export.h"
-#include "quic/platform/api/quic_flag_utils.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-#include "common/quiche_linked_hash_map.h"
-
-namespace quic {
-
-// A LRU cache that maps from type Key to Value* in QUIC.
-// This cache CANNOT be shared by multiple threads (even with locks) because
-// Value* returned by Lookup() can be invalid if the entry is evicted by other
-// threads.
-template <class K, class V, class Hash = std::hash<K>,
- class Eq = std::equal_to<K>>
-class QUIC_NO_EXPORT QuicLRUCache {
- private:
- using HashMapType =
- typename quiche::QuicheLinkedHashMap<K, std::unique_ptr<V>, Hash, Eq>;
-
- public:
- // The iterator, if valid, points to std::pair<K, std::unique_ptr<V>>.
- using iterator = typename HashMapType::iterator;
- using const_iterator = typename HashMapType::const_iterator;
- using reverse_iterator = typename HashMapType::reverse_iterator;
- using const_reverse_iterator = typename HashMapType::const_reverse_iterator;
-
- explicit QuicLRUCache(size_t capacity) : capacity_(capacity) {}
- QuicLRUCache(const QuicLRUCache&) = delete;
- QuicLRUCache& operator=(const QuicLRUCache&) = delete;
-
- iterator begin() { return cache_.begin(); }
- const_iterator begin() const { return cache_.begin(); }
-
- iterator end() { return cache_.end(); }
- const_iterator end() const { return cache_.end(); }
-
- reverse_iterator rbegin() { return cache_.rbegin(); }
- const_reverse_iterator rbegin() const { return cache_.rbegin(); }
-
- reverse_iterator rend() { return cache_.rend(); }
- const_reverse_iterator rend() const { return cache_.rend(); }
-
- // Inserts one unit of |key|, |value| pair to the cache. Cache takes ownership
- // of inserted |value|.
- void Insert(const K& key, std::unique_ptr<V> value) {
- auto it = cache_.find(key);
- if (it != cache_.end()) {
- cache_.erase(it);
- }
- cache_.emplace(key, std::move(value));
-
- if (cache_.size() > capacity_) {
- cache_.pop_front();
- }
- QUICHE_DCHECK_LE(cache_.size(), capacity_);
- }
-
- iterator Lookup(const K& key) {
- auto iter = cache_.find(key);
- if (iter == cache_.end()) {
- return iter;
- }
-
- std::unique_ptr<V> value = std::move(iter->second);
- cache_.erase(iter);
- auto result = cache_.emplace(key, std::move(value));
- QUICHE_DCHECK(result.second);
- return result.first;
- }
-
- iterator Erase(iterator iter) { return cache_.erase(iter); }
-
- // Removes all entries from the cache.
- void Clear() { cache_.clear(); }
-
- // Returns maximum size of the cache.
- size_t MaxSize() const { return capacity_; }
-
- // Returns current size of the cache.
- size_t Size() const { return cache_.size(); }
-
- private:
- quiche::QuicheLinkedHashMap<K, std::unique_ptr<V>, Hash, Eq> cache_;
- const size_t capacity_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_QUIC_LRU_CACHE_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_lru_cache_test.cc b/chromium/net/third_party/quiche/src/quic/core/quic_lru_cache_test.cc
deleted file mode 100644
index 8c6b5b87a74..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_lru_cache_test.cc
+++ /dev/null
@@ -1,81 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_lru_cache.h"
-
-#include "quic/platform/api/quic_test.h"
-
-namespace quic {
-namespace test {
-namespace {
-
-struct CachedItem {
- explicit CachedItem(uint32_t new_value) : value(new_value) {}
-
- uint32_t value;
-};
-
-TEST(QuicLRUCacheTest, InsertAndLookup) {
- QuicLRUCache<int, CachedItem> cache(5);
- EXPECT_EQ(cache.end(), cache.Lookup(1));
- EXPECT_EQ(0u, cache.Size());
- EXPECT_EQ(5u, cache.MaxSize());
-
- // Check that item 1 was properly inserted.
- std::unique_ptr<CachedItem> item1(new CachedItem(11));
- cache.Insert(1, std::move(item1));
- EXPECT_EQ(1u, cache.Size());
- EXPECT_EQ(11u, cache.Lookup(1)->second->value);
-
- // Check that item 2 overrides item 1.
- std::unique_ptr<CachedItem> item2(new CachedItem(12));
- cache.Insert(1, std::move(item2));
- EXPECT_EQ(1u, cache.Size());
- EXPECT_EQ(12u, cache.Lookup(1)->second->value);
-
- std::unique_ptr<CachedItem> item3(new CachedItem(13));
- cache.Insert(3, std::move(item3));
- EXPECT_EQ(2u, cache.Size());
- auto iter = cache.Lookup(3);
- ASSERT_NE(cache.end(), iter);
- EXPECT_EQ(13u, iter->second->value);
- cache.Erase(iter);
- ASSERT_EQ(cache.end(), cache.Lookup(3));
- EXPECT_EQ(1u, cache.Size());
-
- // No memory leakage.
- cache.Clear();
- EXPECT_EQ(0u, cache.Size());
-}
-
-TEST(QuicLRUCacheTest, Eviction) {
- QuicLRUCache<int, CachedItem> cache(3);
-
- for (size_t i = 1; i <= 4; ++i) {
- std::unique_ptr<CachedItem> item(new CachedItem(10 + i));
- cache.Insert(i, std::move(item));
- }
-
- EXPECT_EQ(3u, cache.Size());
- EXPECT_EQ(3u, cache.MaxSize());
-
- // Make sure item 1 is evicted.
- EXPECT_EQ(cache.end(), cache.Lookup(1));
- EXPECT_EQ(14u, cache.Lookup(4)->second->value);
-
- EXPECT_EQ(12u, cache.Lookup(2)->second->value);
- std::unique_ptr<CachedItem> item5(new CachedItem(15));
- cache.Insert(5, std::move(item5));
- // Make sure item 3 is evicted.
- EXPECT_EQ(cache.end(), cache.Lookup(3));
- EXPECT_EQ(15u, cache.Lookup(5)->second->value);
-
- // No memory leakage.
- cache.Clear();
- EXPECT_EQ(0u, cache.Size());
-}
-
-} // namespace
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_mtu_discovery.cc b/chromium/net/third_party/quiche/src/quic/core/quic_mtu_discovery.cc
deleted file mode 100644
index 056a4bd5bde..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_mtu_discovery.cc
+++ /dev/null
@@ -1,139 +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 "quic/core/quic_mtu_discovery.h"
-#include "quic/platform/api/quic_flag_utils.h"
-#include "quic/platform/api/quic_stack_trace.h"
-
-namespace quic {
-
-QuicConnectionMtuDiscoverer::QuicConnectionMtuDiscoverer(
- QuicPacketCount packets_between_probes_base,
- QuicPacketNumber next_probe_at)
- : packets_between_probes_(packets_between_probes_base),
- next_probe_at_(next_probe_at) {}
-
-void QuicConnectionMtuDiscoverer::Enable(
- QuicByteCount max_packet_length,
- QuicByteCount target_max_packet_length) {
- QUICHE_DCHECK(!IsEnabled());
-
- if (target_max_packet_length <= max_packet_length) {
- QUIC_DVLOG(1) << "MtuDiscoverer not enabled. target_max_packet_length:"
- << target_max_packet_length
- << " <= max_packet_length:" << max_packet_length;
- return;
- }
-
- min_probe_length_ = max_packet_length;
- max_probe_length_ = target_max_packet_length;
- QUICHE_DCHECK(IsEnabled());
-
- QUIC_DVLOG(1) << "MtuDiscoverer enabled. min:" << min_probe_length_
- << ", max:" << max_probe_length_
- << ", next:" << next_probe_packet_length();
-}
-
-void QuicConnectionMtuDiscoverer::Disable() {
- *this = QuicConnectionMtuDiscoverer(packets_between_probes_, next_probe_at_);
-}
-
-bool QuicConnectionMtuDiscoverer::IsEnabled() const {
- return min_probe_length_ < max_probe_length_;
-}
-
-bool QuicConnectionMtuDiscoverer::ShouldProbeMtu(
- QuicPacketNumber largest_sent_packet) const {
- if (!IsEnabled()) {
- return false;
- }
-
- if (remaining_probe_count_ == 0) {
- QUIC_DVLOG(1)
- << "ShouldProbeMtu returns false because max probe count reached";
- return false;
- }
-
- if (largest_sent_packet < next_probe_at_) {
- QUIC_DVLOG(1) << "ShouldProbeMtu returns false because not enough packets "
- "sent since last probe. largest_sent_packet:"
- << largest_sent_packet
- << ", next_probe_at_:" << next_probe_at_;
- return false;
- }
-
- QUIC_DVLOG(1) << "ShouldProbeMtu returns true. largest_sent_packet:"
- << largest_sent_packet;
- return true;
-}
-
-QuicPacketLength QuicConnectionMtuDiscoverer::GetUpdatedMtuProbeSize(
- QuicPacketNumber largest_sent_packet) {
- QUICHE_DCHECK(ShouldProbeMtu(largest_sent_packet));
-
- QuicPacketLength probe_packet_length = next_probe_packet_length();
- if (probe_packet_length == last_probe_length_) {
- // The next probe packet is as big as the previous one. Assuming the
- // previous one exceeded MTU, we need to decrease the probe packet length.
- max_probe_length_ = probe_packet_length;
- } else {
- QUICHE_DCHECK_GT(probe_packet_length, last_probe_length_);
- }
- last_probe_length_ = next_probe_packet_length();
-
- packets_between_probes_ *= 2;
- next_probe_at_ = largest_sent_packet + packets_between_probes_ + 1;
- if (remaining_probe_count_ > 0) {
- --remaining_probe_count_;
- }
-
- QUIC_DVLOG(1) << "GetUpdatedMtuProbeSize: probe_packet_length:"
- << last_probe_length_
- << ", New packets_between_probes_:" << packets_between_probes_
- << ", next_probe_at_:" << next_probe_at_
- << ", remaining_probe_count_:" << remaining_probe_count_;
- QUICHE_DCHECK(!ShouldProbeMtu(largest_sent_packet));
- return last_probe_length_;
-}
-
-QuicPacketLength QuicConnectionMtuDiscoverer::next_probe_packet_length() const {
- QUICHE_DCHECK_NE(min_probe_length_, 0);
- QUICHE_DCHECK_NE(max_probe_length_, 0);
- QUICHE_DCHECK_GE(max_probe_length_, min_probe_length_);
-
- const QuicPacketLength normal_next_probe_length =
- (min_probe_length_ + max_probe_length_ + 1) / 2;
-
- if (remaining_probe_count_ == 1 &&
- normal_next_probe_length > last_probe_length_) {
- // If the previous probe succeeded, and there is only one last probe to
- // send, use |max_probe_length_| for the last probe.
- return max_probe_length_;
- }
- return normal_next_probe_length;
-}
-
-void QuicConnectionMtuDiscoverer::OnMaxPacketLengthUpdated(
- QuicByteCount old_value,
- QuicByteCount new_value) {
- if (!IsEnabled() || new_value <= old_value) {
- return;
- }
-
- QUICHE_DCHECK_EQ(old_value, min_probe_length_);
- min_probe_length_ = new_value;
-}
-
-std::ostream& operator<<(std::ostream& os,
- const QuicConnectionMtuDiscoverer& d) {
- os << "{ min_probe_length_:" << d.min_probe_length_
- << " max_probe_length_:" << d.max_probe_length_
- << " last_probe_length_:" << d.last_probe_length_
- << " remaining_probe_count_:" << d.remaining_probe_count_
- << " packets_between_probes_:" << d.packets_between_probes_
- << " next_probe_at_:" << d.next_probe_at_ << " }";
- return os;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_mtu_discovery.h b/chromium/net/third_party/quiche/src/quic/core/quic_mtu_discovery.h
deleted file mode 100644
index dddd33de7dd..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_mtu_discovery.h
+++ /dev/null
@@ -1,117 +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_CORE_QUIC_MTU_DISCOVERY_H_
-#define QUICHE_QUIC_CORE_QUIC_MTU_DISCOVERY_H_
-
-#include <iostream>
-
-#include "quic/core/quic_constants.h"
-#include "quic/core/quic_types.h"
-
-namespace quic {
-
-// The initial number of packets between MTU probes. After each attempt the
-// number is doubled.
-const QuicPacketCount kPacketsBetweenMtuProbesBase = 100;
-
-// The number of MTU probes that get sent before giving up.
-const size_t kMtuDiscoveryAttempts = 3;
-
-// Ensure that exponential back-off does not result in an integer overflow.
-// The number of packets can be potentially capped, but that is not useful at
-// current kMtuDiscoveryAttempts value, and hence is not implemented at present.
-static_assert(kMtuDiscoveryAttempts + 8 < 8 * sizeof(QuicPacketNumber),
- "The number of MTU discovery attempts is too high");
-static_assert(kPacketsBetweenMtuProbesBase < (1 << 8),
- "The initial number of packets between MTU probes is too high");
-
-// The increased packet size targeted when doing path MTU discovery.
-const QuicByteCount kMtuDiscoveryTargetPacketSizeHigh = 1400;
-const QuicByteCount kMtuDiscoveryTargetPacketSizeLow = 1380;
-
-static_assert(kMtuDiscoveryTargetPacketSizeLow <= kMaxOutgoingPacketSize,
- "MTU discovery target is too large");
-static_assert(kMtuDiscoveryTargetPacketSizeHigh <= kMaxOutgoingPacketSize,
- "MTU discovery target is too large");
-
-static_assert(kMtuDiscoveryTargetPacketSizeLow > kDefaultMaxPacketSize,
- "MTU discovery target does not exceed the default packet size");
-static_assert(kMtuDiscoveryTargetPacketSizeHigh > kDefaultMaxPacketSize,
- "MTU discovery target does not exceed the default packet size");
-
-// QuicConnectionMtuDiscoverer is a MTU discovery controller, it answers two
-// questions:
-// 1) Probe scheduling: Whether a connection should send a MTU probe packet
-// right now.
-// 2) MTU search stradegy: When it is time to send, what should be the size of
-// the probing packet.
-// Note the discoverer does not actually send or process probing packets.
-//
-// Unit tests are in QuicConnectionTest.MtuDiscovery*.
-class QUIC_EXPORT_PRIVATE QuicConnectionMtuDiscoverer {
- public:
- // Construct a discoverer in the disabled state.
- QuicConnectionMtuDiscoverer() = default;
-
- // Construct a discoverer in the disabled state, with the given parameters.
- QuicConnectionMtuDiscoverer(QuicPacketCount packets_between_probes_base,
- QuicPacketNumber next_probe_at);
-
- // Enable the discoverer by setting the probe target.
- // max_packet_length: The max packet length currently used.
- // target_max_packet_length: The target max packet length to probe.
- void Enable(QuicByteCount max_packet_length,
- QuicByteCount target_max_packet_length);
-
- // Disable the discoverer by unsetting the probe target.
- void Disable();
-
- // Whether a MTU probe packet should be sent right now.
- // Always return false if disabled.
- bool ShouldProbeMtu(QuicPacketNumber largest_sent_packet) const;
-
- // Called immediately before a probing packet is sent, to get the size of the
- // packet.
- // REQUIRES: ShouldProbeMtu(largest_sent_packet) == true.
- QuicPacketLength GetUpdatedMtuProbeSize(QuicPacketNumber largest_sent_packet);
-
- // Called after the max packet length is updated, which is triggered by a ack
- // of a probing packet.
- void OnMaxPacketLengthUpdated(QuicByteCount old_value,
- QuicByteCount new_value);
-
- QuicPacketCount packets_between_probes() const {
- return packets_between_probes_;
- }
-
- QuicPacketNumber next_probe_at() const { return next_probe_at_; }
-
- QUIC_EXPORT_PRIVATE friend std::ostream& operator<<(
- std::ostream& os,
- const QuicConnectionMtuDiscoverer& d);
-
- private:
- bool IsEnabled() const;
- QuicPacketLength next_probe_packet_length() const;
-
- QuicPacketLength min_probe_length_ = 0;
- QuicPacketLength max_probe_length_ = 0;
-
- QuicPacketLength last_probe_length_ = 0;
-
- uint16_t remaining_probe_count_ = kMtuDiscoveryAttempts;
-
- // The number of packets between MTU probes.
- QuicPacketCount packets_between_probes_ = kPacketsBetweenMtuProbesBase;
-
- // The packet number of the packet after which the next MTU probe will be
- // sent.
- QuicPacketNumber next_probe_at_ =
- QuicPacketNumber(kPacketsBetweenMtuProbesBase);
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_QUIC_MTU_DISCOVERY_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_network_blackhole_detector.cc b/chromium/net/third_party/quiche/src/quic/core/quic_network_blackhole_detector.cc
deleted file mode 100644
index 2d9fc2d3a61..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_network_blackhole_detector.cc
+++ /dev/null
@@ -1,136 +0,0 @@
-// Copyright (c) 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_network_blackhole_detector.h"
-
-#include "quic/core/quic_constants.h"
-
-namespace quic {
-
-namespace {
-
-class AlarmDelegate : public QuicAlarm::DelegateWithContext {
- public:
- explicit AlarmDelegate(QuicNetworkBlackholeDetector* detector,
- QuicConnectionContext* context)
- : QuicAlarm::DelegateWithContext(context), detector_(detector) {}
- AlarmDelegate(const AlarmDelegate&) = delete;
- AlarmDelegate& operator=(const AlarmDelegate&) = delete;
-
- void OnAlarm() override { detector_->OnAlarm(); }
-
- private:
- QuicNetworkBlackholeDetector* detector_;
-};
-
-} // namespace
-
-QuicNetworkBlackholeDetector::QuicNetworkBlackholeDetector(
- Delegate* delegate, QuicConnectionArena* arena,
- QuicAlarmFactory* alarm_factory, QuicConnectionContext* context)
- : delegate_(delegate),
- alarm_(alarm_factory->CreateAlarm(
- arena->New<AlarmDelegate>(this, context), arena)) {}
-
-void QuicNetworkBlackholeDetector::OnAlarm() {
- QuicTime next_deadline = GetEarliestDeadline();
- if (!next_deadline.IsInitialized()) {
- QUIC_BUG(quic_bug_10328_1) << "BlackholeDetector alarm fired unexpectedly";
- return;
- }
-
- QUIC_DVLOG(1) << "BlackholeDetector alarm firing. next_deadline:"
- << next_deadline
- << ", path_degrading_deadline_:" << path_degrading_deadline_
- << ", path_mtu_reduction_deadline_:"
- << path_mtu_reduction_deadline_
- << ", blackhole_deadline_:" << blackhole_deadline_;
- if (path_degrading_deadline_ == next_deadline) {
- path_degrading_deadline_ = QuicTime::Zero();
- delegate_->OnPathDegradingDetected();
- }
-
- if (path_mtu_reduction_deadline_ == next_deadline) {
- path_mtu_reduction_deadline_ = QuicTime::Zero();
- delegate_->OnPathMtuReductionDetected();
- }
-
- if (blackhole_deadline_ == next_deadline) {
- blackhole_deadline_ = QuicTime::Zero();
- delegate_->OnBlackholeDetected();
- }
-
- UpdateAlarm();
-}
-
-void QuicNetworkBlackholeDetector::StopDetection(bool permanent) {
- if (permanent) {
- alarm_->PermanentCancel();
- } else {
- alarm_->Cancel();
- }
- path_degrading_deadline_ = QuicTime::Zero();
- blackhole_deadline_ = QuicTime::Zero();
- path_mtu_reduction_deadline_ = QuicTime::Zero();
-}
-
-void QuicNetworkBlackholeDetector::RestartDetection(
- QuicTime path_degrading_deadline,
- QuicTime blackhole_deadline,
- QuicTime path_mtu_reduction_deadline) {
- path_degrading_deadline_ = path_degrading_deadline;
- blackhole_deadline_ = blackhole_deadline;
- path_mtu_reduction_deadline_ = path_mtu_reduction_deadline;
-
- QUIC_BUG_IF(quic_bug_12708_1, blackhole_deadline_.IsInitialized() &&
- blackhole_deadline_ != GetLastDeadline())
- << "Blackhole detection deadline should be the last deadline.";
-
- UpdateAlarm();
-}
-
-QuicTime QuicNetworkBlackholeDetector::GetEarliestDeadline() const {
- QuicTime result = QuicTime::Zero();
- for (QuicTime t : {path_degrading_deadline_, blackhole_deadline_,
- path_mtu_reduction_deadline_}) {
- if (!t.IsInitialized()) {
- continue;
- }
-
- if (!result.IsInitialized() || t < result) {
- result = t;
- }
- }
-
- return result;
-}
-
-QuicTime QuicNetworkBlackholeDetector::GetLastDeadline() const {
- return std::max({path_degrading_deadline_, blackhole_deadline_,
- path_mtu_reduction_deadline_});
-}
-
-void QuicNetworkBlackholeDetector::UpdateAlarm() const {
- // If called after OnBlackholeDetected(), the alarm may have been permanently
- // cancelled and is not safe to be armed again.
- if (alarm_->IsPermanentlyCancelled()) {
- return;
- }
-
- QuicTime next_deadline = GetEarliestDeadline();
-
- QUIC_DVLOG(1) << "Updating alarm. next_deadline:" << next_deadline
- << ", path_degrading_deadline_:" << path_degrading_deadline_
- << ", path_mtu_reduction_deadline_:"
- << path_mtu_reduction_deadline_
- << ", blackhole_deadline_:" << blackhole_deadline_;
-
- alarm_->Update(next_deadline, kAlarmGranularity);
-}
-
-bool QuicNetworkBlackholeDetector::IsDetectionInProgress() const {
- return alarm_->IsSet();
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_network_blackhole_detector.h b/chromium/net/third_party/quiche/src/quic/core/quic_network_blackhole_detector.h
deleted file mode 100644
index db52e8faa4f..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_network_blackhole_detector.h
+++ /dev/null
@@ -1,91 +0,0 @@
-// Copyright (c) 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_NETWORK_BLACKHOLE_DETECTOR_H_
-#define QUICHE_QUIC_CORE_QUIC_NETWORK_BLACKHOLE_DETECTOR_H_
-
-#include "quic/core/quic_alarm.h"
-#include "quic/core/quic_alarm_factory.h"
-#include "quic/core/quic_one_block_arena.h"
-#include "quic/core/quic_time.h"
-#include "quic/platform/api/quic_export.h"
-#include "quic/platform/api/quic_flags.h"
-
-namespace quic {
-
-namespace test {
-class QuicConnectionPeer;
-class QuicNetworkBlackholeDetectorPeer;
-} // namespace test
-
-// QuicNetworkBlackholeDetector can detect path degrading and/or network
-// blackhole. If both detections are in progress, detector will be in path
-// degrading detection mode. After reporting path degrading detected, detector
-// switches to blackhole detection mode. So blackhole detection deadline must
-// be later than path degrading deadline.
-class QUIC_EXPORT_PRIVATE QuicNetworkBlackholeDetector {
- public:
- class QUIC_EXPORT_PRIVATE Delegate {
- public:
- virtual ~Delegate() {}
-
- // Called when the path degrading alarm fires.
- virtual void OnPathDegradingDetected() = 0;
-
- // Called when the path blackhole alarm fires.
- virtual void OnBlackholeDetected() = 0;
-
- // Called when the path mtu reduction alarm fires.
- virtual void OnPathMtuReductionDetected() = 0;
- };
-
- QuicNetworkBlackholeDetector(Delegate* delegate, QuicConnectionArena* arena,
- QuicAlarmFactory* alarm_factory,
- QuicConnectionContext* context);
-
- // Called to stop all detections. If |permanent|, the alarm will be cancelled
- // permanently and future calls to RestartDetection will be no-op.
- void StopDetection(bool permanent);
-
- // Called to restart path degrading, path mtu reduction and blackhole
- // detections. Please note, if |blackhole_deadline| is set, it must be the
- // furthest in the future of all deadlines.
- void RestartDetection(QuicTime path_degrading_deadline,
- QuicTime blackhole_deadline,
- QuicTime path_mtu_reduction_deadline);
-
- // Called when |alarm_| fires.
- void OnAlarm();
-
- // Returns true if |alarm_| is set.
- bool IsDetectionInProgress() const;
-
- private:
- friend class test::QuicConnectionPeer;
- friend class test::QuicNetworkBlackholeDetectorPeer;
-
- QuicTime GetEarliestDeadline() const;
- QuicTime GetLastDeadline() const;
-
- // Update alarm to the next deadline.
- void UpdateAlarm() const;
-
- Delegate* delegate_; // Not owned.
-
- // Time that Delegate::OnPathDegrading will be called. 0 means no path
- // degrading detection is in progress.
- QuicTime path_degrading_deadline_ = QuicTime::Zero();
- // Time that Delegate::OnBlackholeDetected will be called. 0 means no
- // blackhole detection is in progress.
- QuicTime blackhole_deadline_ = QuicTime::Zero();
- // Time that Delegate::OnPathMtuReductionDetected will be called. 0 means no
- // path mtu reduction detection is in progress.
- QuicTime path_mtu_reduction_deadline_ = QuicTime::Zero();
-
- QuicArenaScopedPtr<QuicAlarm> alarm_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_QUIC_NETWORK_BLACKHOLE_DETECTOR_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_network_blackhole_detector_test.cc b/chromium/net/third_party/quiche/src/quic/core/quic_network_blackhole_detector_test.cc
deleted file mode 100644
index 764ee9a1f5d..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_network_blackhole_detector_test.cc
+++ /dev/null
@@ -1,139 +0,0 @@
-// Copyright (c) 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_network_blackhole_detector.h"
-
-#include "quic/core/quic_one_block_arena.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/quic_test_utils.h"
-
-namespace quic {
-namespace test {
-
-class QuicNetworkBlackholeDetectorPeer {
- public:
- static QuicAlarm* GetAlarm(QuicNetworkBlackholeDetector* detector) {
- return detector->alarm_.get();
- }
-};
-
-namespace {
-class MockDelegate : public QuicNetworkBlackholeDetector::Delegate {
- public:
- MOCK_METHOD(void, OnPathDegradingDetected, (), (override));
- MOCK_METHOD(void, OnBlackholeDetected, (), (override));
- MOCK_METHOD(void, OnPathMtuReductionDetected, (), (override));
-};
-
-const size_t kPathDegradingDelayInSeconds = 5;
-const size_t kPathMtuReductionDelayInSeconds = 7;
-const size_t kBlackholeDelayInSeconds = 10;
-
-class QuicNetworkBlackholeDetectorTest : public QuicTest {
- public:
- QuicNetworkBlackholeDetectorTest()
- : detector_(&delegate_, &arena_, &alarm_factory_, /*context=*/nullptr),
- alarm_(static_cast<MockAlarmFactory::TestAlarm*>(
- QuicNetworkBlackholeDetectorPeer::GetAlarm(&detector_))),
- path_degrading_delay_(
- QuicTime::Delta::FromSeconds(kPathDegradingDelayInSeconds)),
- path_mtu_reduction_delay_(
- QuicTime::Delta::FromSeconds(kPathMtuReductionDelayInSeconds)),
- blackhole_delay_(
- QuicTime::Delta::FromSeconds(kBlackholeDelayInSeconds)) {
- clock_.AdvanceTime(QuicTime::Delta::FromSeconds(1));
- }
-
- protected:
- void RestartDetection() {
- detector_.RestartDetection(clock_.Now() + path_degrading_delay_,
- clock_.Now() + blackhole_delay_,
- clock_.Now() + path_mtu_reduction_delay_);
- }
-
- testing::StrictMock<MockDelegate> delegate_;
- QuicConnectionArena arena_;
- MockAlarmFactory alarm_factory_;
-
- QuicNetworkBlackholeDetector detector_;
-
- MockAlarmFactory::TestAlarm* alarm_;
- MockClock clock_;
- const QuicTime::Delta path_degrading_delay_;
- const QuicTime::Delta path_mtu_reduction_delay_;
- const QuicTime::Delta blackhole_delay_;
-};
-
-TEST_F(QuicNetworkBlackholeDetectorTest, StartAndFire) {
- EXPECT_FALSE(detector_.IsDetectionInProgress());
-
- RestartDetection();
- EXPECT_TRUE(detector_.IsDetectionInProgress());
- EXPECT_EQ(clock_.Now() + path_degrading_delay_, alarm_->deadline());
-
- // Fire path degrading alarm.
- clock_.AdvanceTime(path_degrading_delay_);
- EXPECT_CALL(delegate_, OnPathDegradingDetected());
- alarm_->Fire();
-
- // Verify path mtu reduction detection is still in progress.
- EXPECT_TRUE(detector_.IsDetectionInProgress());
- EXPECT_EQ(clock_.Now() + path_mtu_reduction_delay_ - path_degrading_delay_,
- alarm_->deadline());
-
- // Fire path mtu reduction detection alarm.
- clock_.AdvanceTime(path_mtu_reduction_delay_ - path_degrading_delay_);
- EXPECT_CALL(delegate_, OnPathMtuReductionDetected());
- alarm_->Fire();
-
- // Verify blackhole detection is still in progress.
- EXPECT_TRUE(detector_.IsDetectionInProgress());
- EXPECT_EQ(clock_.Now() + blackhole_delay_ - path_mtu_reduction_delay_,
- alarm_->deadline());
-
- // Fire blackhole detection alarm.
- clock_.AdvanceTime(blackhole_delay_ - path_mtu_reduction_delay_);
- EXPECT_CALL(delegate_, OnBlackholeDetected());
- alarm_->Fire();
- EXPECT_FALSE(detector_.IsDetectionInProgress());
-}
-
-TEST_F(QuicNetworkBlackholeDetectorTest, RestartAndStop) {
- RestartDetection();
-
- clock_.AdvanceTime(QuicTime::Delta::FromSeconds(1));
- RestartDetection();
- EXPECT_EQ(clock_.Now() + path_degrading_delay_, alarm_->deadline());
-
- detector_.StopDetection(/*permanent=*/false);
- EXPECT_FALSE(detector_.IsDetectionInProgress());
-}
-
-TEST_F(QuicNetworkBlackholeDetectorTest, PathDegradingFiresAndRestart) {
- EXPECT_FALSE(detector_.IsDetectionInProgress());
- RestartDetection();
- EXPECT_TRUE(detector_.IsDetectionInProgress());
- EXPECT_EQ(clock_.Now() + path_degrading_delay_, alarm_->deadline());
-
- // Fire path degrading alarm.
- clock_.AdvanceTime(path_degrading_delay_);
- EXPECT_CALL(delegate_, OnPathDegradingDetected());
- alarm_->Fire();
-
- // Verify path mtu reduction detection is still in progress.
- EXPECT_TRUE(detector_.IsDetectionInProgress());
- EXPECT_EQ(clock_.Now() + path_mtu_reduction_delay_ - path_degrading_delay_,
- alarm_->deadline());
-
- // After 100ms, restart detections on forward progress.
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(100));
- RestartDetection();
- // Verify alarm is armed based on path degrading deadline.
- EXPECT_EQ(clock_.Now() + path_degrading_delay_, alarm_->deadline());
-}
-
-} // namespace
-
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_one_block_arena.h b/chromium/net/third_party/quiche/src/quic/core/quic_one_block_arena.h
deleted file mode 100644
index 02aae871e02..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_one_block_arena.h
+++ /dev/null
@@ -1,76 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// An arena that consists of a single inlined block of |ArenaSize|. Useful to
-// avoid repeated calls to malloc/new and to improve memory locality.
-// QUICHE_DCHECK's if an allocation out of the arena ever fails in debug builds;
-// falls back to heap allocation in release builds.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_ONE_BLOCK_ARENA_H_
-#define QUICHE_QUIC_CORE_QUIC_ONE_BLOCK_ARENA_H_
-
-#include <cstdint>
-
-#include "quic/core/quic_arena_scoped_ptr.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-template <uint32_t ArenaSize>
-class QUIC_EXPORT_PRIVATE QuicOneBlockArena {
- static const uint32_t kMaxAlign = 8;
-
- public:
- QuicOneBlockArena() : offset_(0) {}
- QuicOneBlockArena(const QuicOneBlockArena&) = delete;
- QuicOneBlockArena& operator=(const QuicOneBlockArena&) = delete;
-
- // Instantiates an object of type |T| with |args|. |args| are perfectly
- // forwarded to |T|'s constructor. The returned pointer's lifetime is
- // controlled by QuicArenaScopedPtr.
- template <typename T, typename... Args>
- QuicArenaScopedPtr<T> New(Args&&... args) {
- QUICHE_DCHECK_LT(AlignedSize<T>(), ArenaSize)
- << "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>())) {
- QUIC_BUG(quic_bug_10593_1)
- << "Ran out of space in QuicOneBlockArena at " << this
- << ", max size was " << ArenaSize << ", failing request was "
- << AlignedSize<T>() << ", end of arena was " << offset_;
- return QuicArenaScopedPtr<T>(new T(std::forward<Args>(args)...));
- }
-
- void* buf = &storage_[offset_];
- new (buf) T(std::forward<Args>(args)...);
- offset_ += AlignedSize<T>();
- return QuicArenaScopedPtr<T>(buf,
- QuicArenaScopedPtr<T>::ConstructFrom::kArena);
- }
-
- private:
- // Returns the size of |T| aligned up to |kMaxAlign|.
- template <typename T>
- static inline uint32_t AlignedSize() {
- return ((sizeof(T) + (kMaxAlign - 1)) / kMaxAlign) * kMaxAlign;
- }
-
- // Actual storage.
- // Subtle/annoying: the value '8' must be coded explicitly into the alignment
- // declaration for MSVC.
- alignas(8) char storage_[ArenaSize];
- // Current offset into the storage.
- uint32_t offset_;
-};
-
-// 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>;
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_QUIC_ONE_BLOCK_ARENA_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_one_block_arena_test.cc b/chromium/net/third_party/quiche/src/quic/core/quic_one_block_arena_test.cc
deleted file mode 100644
index 181ab3f852c..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_one_block_arena_test.cc
+++ /dev/null
@@ -1,60 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_one_block_arena.h"
-
-#include <cstdint>
-
-#include "quic/platform/api/quic_containers.h"
-#include "quic/platform/api/quic_expect_bug.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/quic_test_utils.h"
-
-namespace quic {
-namespace {
-
-static const uint32_t kMaxAlign = 8;
-
-struct TestObject {
- uint32_t value;
-};
-
-class QuicOneBlockArenaTest : public QuicTest {};
-
-TEST_F(QuicOneBlockArenaTest, AllocateSuccess) {
- QuicOneBlockArena<1024> arena;
- QuicArenaScopedPtr<TestObject> ptr = arena.New<TestObject>();
- EXPECT_TRUE(ptr.is_from_arena());
-}
-
-TEST_F(QuicOneBlockArenaTest, Exhaust) {
- QuicOneBlockArena<1024> arena;
- for (size_t i = 0; i < 1024 / kMaxAlign; ++i) {
- QuicArenaScopedPtr<TestObject> ptr = arena.New<TestObject>();
- EXPECT_TRUE(ptr.is_from_arena());
- }
- QuicArenaScopedPtr<TestObject> ptr;
- EXPECT_QUIC_BUG(ptr = arena.New<TestObject>(),
- "Ran out of space in QuicOneBlockArena");
- EXPECT_FALSE(ptr.is_from_arena());
-}
-
-TEST_F(QuicOneBlockArenaTest, NoOverlaps) {
- QuicOneBlockArena<1024> arena;
- std::vector<QuicArenaScopedPtr<TestObject>> objects;
- QuicIntervalSet<uintptr_t> used;
- for (size_t i = 0; i < 1024 / kMaxAlign; ++i) {
- QuicArenaScopedPtr<TestObject> ptr = arena.New<TestObject>();
- EXPECT_TRUE(ptr.is_from_arena());
-
- uintptr_t begin = reinterpret_cast<uintptr_t>(ptr.get());
- uintptr_t end = begin + sizeof(TestObject);
- EXPECT_FALSE(used.Contains(begin));
- EXPECT_FALSE(used.Contains(end - 1));
- used.Add(begin, end);
- }
-}
-
-} // namespace
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_packet_creator.cc b/chromium/net/third_party/quiche/src/quic/core/quic_packet_creator.cc
deleted file mode 100644
index 388aada7baa..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_packet_creator.cc
+++ /dev/null
@@ -1,2251 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_packet_creator.h"
-
-#include <algorithm>
-#include <cstddef>
-#include <cstdint>
-#include <limits>
-#include <string>
-#include <utility>
-
-#include "absl/base/macros.h"
-#include "absl/base/optimization.h"
-#include "absl/strings/str_cat.h"
-#include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
-#include "quic/core/crypto/crypto_protocol.h"
-#include "quic/core/frames/quic_frame.h"
-#include "quic/core/frames/quic_path_challenge_frame.h"
-#include "quic/core/frames/quic_stream_frame.h"
-#include "quic/core/quic_chaos_protector.h"
-#include "quic/core/quic_connection_id.h"
-#include "quic/core/quic_constants.h"
-#include "quic/core/quic_data_writer.h"
-#include "quic/core/quic_error_codes.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_utils.h"
-#include "quic/core/quic_versions.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_exported_stats.h"
-#include "quic/platform/api/quic_flag_utils.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/platform/api/quic_server_stats.h"
-#include "common/print_elements.h"
-
-namespace quic {
-namespace {
-
-QuicLongHeaderType EncryptionlevelToLongHeaderType(EncryptionLevel level) {
- switch (level) {
- case ENCRYPTION_INITIAL:
- return INITIAL;
- case ENCRYPTION_HANDSHAKE:
- return HANDSHAKE;
- case ENCRYPTION_ZERO_RTT:
- return ZERO_RTT_PROTECTED;
- case ENCRYPTION_FORWARD_SECURE:
- QUIC_BUG(quic_bug_12398_1)
- << "Try to derive long header type for packet with encryption level: "
- << level;
- return INVALID_PACKET_TYPE;
- default:
- QUIC_BUG(quic_bug_10752_1) << level;
- return INVALID_PACKET_TYPE;
- }
-}
-
-void LogCoalesceStreamFrameStatus(bool success) {
- QUIC_HISTOGRAM_BOOL("QuicSession.CoalesceStreamFrameStatus", success,
- "Success rate of coalesing stream frames attempt.");
-}
-
-// ScopedPacketContextSwitcher saves |packet|'s states and change states
-// during its construction. When the switcher goes out of scope, it restores
-// saved states.
-class ScopedPacketContextSwitcher {
- public:
- ScopedPacketContextSwitcher(QuicPacketNumber packet_number,
- QuicPacketNumberLength packet_number_length,
- EncryptionLevel encryption_level,
- SerializedPacket* packet)
-
- : saved_packet_number_(packet->packet_number),
- saved_packet_number_length_(packet->packet_number_length),
- saved_encryption_level_(packet->encryption_level),
- packet_(packet) {
- packet_->packet_number = packet_number,
- packet_->packet_number_length = packet_number_length;
- packet_->encryption_level = encryption_level;
- }
-
- ~ScopedPacketContextSwitcher() {
- packet_->packet_number = saved_packet_number_;
- packet_->packet_number_length = saved_packet_number_length_;
- packet_->encryption_level = saved_encryption_level_;
- }
-
- private:
- const QuicPacketNumber saved_packet_number_;
- const QuicPacketNumberLength saved_packet_number_length_;
- const EncryptionLevel saved_encryption_level_;
- SerializedPacket* packet_;
-};
-
-} // namespace
-
-#define ENDPOINT \
- (framer_->perspective() == Perspective::IS_SERVER ? "Server: " : "Client: ")
-
-QuicPacketCreator::QuicPacketCreator(QuicConnectionId server_connection_id,
- QuicFramer* framer,
- DelegateInterface* delegate)
- : QuicPacketCreator(server_connection_id,
- framer,
- QuicRandom::GetInstance(),
- delegate) {}
-
-QuicPacketCreator::QuicPacketCreator(QuicConnectionId server_connection_id,
- QuicFramer* framer, QuicRandom* random,
- DelegateInterface* delegate)
- : delegate_(delegate),
- debug_delegate_(nullptr),
- framer_(framer),
- random_(random),
- send_version_in_packet_(framer->perspective() == Perspective::IS_CLIENT),
- have_diversification_nonce_(false),
- max_packet_length_(0),
- server_connection_id_included_(CONNECTION_ID_PRESENT),
- packet_size_(0),
- server_connection_id_(server_connection_id),
- client_connection_id_(EmptyQuicConnectionId()),
- packet_(QuicPacketNumber(), PACKET_1BYTE_PACKET_NUMBER, nullptr, 0, false,
- false),
- pending_padding_bytes_(0),
- needs_full_padding_(false),
- next_transmission_type_(NOT_RETRANSMISSION),
- flusher_attached_(false),
- fully_pad_crypto_handshake_packets_(true),
- latched_hard_max_packet_length_(0),
- max_datagram_frame_size_(0),
- chaos_protection_enabled_(
- GetQuicFlag(FLAGS_quic_enable_chaos_protection) &&
- framer->perspective() == Perspective::IS_CLIENT) {
- SetMaxPacketLength(kDefaultMaxPacketSize);
- if (!framer_->version().UsesTls()) {
- // QUIC+TLS negotiates the maximum datagram frame size via the
- // IETF QUIC max_datagram_frame_size transport parameter.
- // QUIC_CRYPTO however does not negotiate this so we set its value here.
- SetMaxDatagramFrameSize(kMaxAcceptedDatagramFrameSize);
- }
-}
-
-QuicPacketCreator::~QuicPacketCreator() {
- DeleteFrames(&packet_.retransmittable_frames);
-}
-
-void QuicPacketCreator::SetEncrypter(EncryptionLevel level,
- std::unique_ptr<QuicEncrypter> encrypter) {
- framer_->SetEncrypter(level, std::move(encrypter));
- max_plaintext_size_ = framer_->GetMaxPlaintextSize(max_packet_length_);
-}
-
-bool QuicPacketCreator::CanSetMaxPacketLength() const {
- // |max_packet_length_| should not be changed mid-packet.
- return queued_frames_.empty();
-}
-
-void QuicPacketCreator::SetMaxPacketLength(QuicByteCount length) {
- QUICHE_DCHECK(CanSetMaxPacketLength()) << ENDPOINT;
-
- // Avoid recomputing |max_plaintext_size_| if the length does not actually
- // change.
- if (length == max_packet_length_) {
- return;
- }
- QUIC_DVLOG(1) << ENDPOINT << "Updating packet creator max packet length from "
- << max_packet_length_ << " to " << length;
-
- max_packet_length_ = length;
- max_plaintext_size_ = framer_->GetMaxPlaintextSize(max_packet_length_);
- QUIC_BUG_IF(quic_bug_12398_2, max_plaintext_size_ - PacketHeaderSize() <
- MinPlaintextPacketSize(framer_->version()))
- << ENDPOINT << "Attempted to set max packet length too small";
-}
-
-void QuicPacketCreator::SetMaxDatagramFrameSize(
- QuicByteCount max_datagram_frame_size) {
- constexpr QuicByteCount upper_bound =
- std::min<QuicByteCount>(std::numeric_limits<QuicPacketLength>::max(),
- std::numeric_limits<size_t>::max());
- if (max_datagram_frame_size > upper_bound) {
- // A value of |max_datagram_frame_size| that is equal or greater than
- // 2^16-1 is effectively infinite because QUIC packets cannot be that large.
- // We therefore clamp the value here to allow us to safely cast
- // |max_datagram_frame_size_| to QuicPacketLength or size_t.
- max_datagram_frame_size = upper_bound;
- }
- max_datagram_frame_size_ = max_datagram_frame_size;
-}
-
-void QuicPacketCreator::SetSoftMaxPacketLength(QuicByteCount length) {
- QUICHE_DCHECK(CanSetMaxPacketLength()) << ENDPOINT;
- if (length > max_packet_length_) {
- QUIC_BUG(quic_bug_10752_2)
- << ENDPOINT
- << "Try to increase max_packet_length_ in "
- "SetSoftMaxPacketLength, use SetMaxPacketLength instead.";
- return;
- }
- if (framer_->GetMaxPlaintextSize(length) <
- PacketHeaderSize() + MinPlaintextPacketSize(framer_->version())) {
- // Please note: this would not guarantee to fit next packet if the size of
- // packet header increases (e.g., encryption level changes).
- QUIC_DLOG(INFO) << ENDPOINT << length
- << " is too small to fit packet header";
- RemoveSoftMaxPacketLength();
- return;
- }
- QUIC_DVLOG(1) << ENDPOINT << "Setting soft max packet length to: " << length;
- latched_hard_max_packet_length_ = max_packet_length_;
- max_packet_length_ = length;
- max_plaintext_size_ = framer_->GetMaxPlaintextSize(length);
-}
-
-// Stops serializing version of the protocol in packets sent after this call.
-// A packet that is already open might send kQuicVersionSize bytes less than the
-// maximum packet size if we stop sending version before it is serialized.
-void QuicPacketCreator::StopSendingVersion() {
- QUICHE_DCHECK(send_version_in_packet_) << ENDPOINT;
- QUICHE_DCHECK(!version().HasIetfInvariantHeader()) << ENDPOINT;
- send_version_in_packet_ = false;
- if (packet_size_ > 0) {
- QUICHE_DCHECK_LT(kQuicVersionSize, packet_size_) << ENDPOINT;
- packet_size_ -= kQuicVersionSize;
- }
-}
-
-void QuicPacketCreator::SetDiversificationNonce(
- const DiversificationNonce& nonce) {
- QUICHE_DCHECK(!have_diversification_nonce_) << ENDPOINT;
- have_diversification_nonce_ = true;
- diversification_nonce_ = nonce;
-}
-
-void QuicPacketCreator::UpdatePacketNumberLength(
- QuicPacketNumber least_packet_awaited_by_peer,
- QuicPacketCount max_packets_in_flight) {
- if (!queued_frames_.empty()) {
- // Don't change creator state if there are frames queued.
- QUIC_BUG(quic_bug_10752_3)
- << ENDPOINT << "Called UpdatePacketNumberLength with "
- << queued_frames_.size()
- << " queued_frames. First frame type:" << queued_frames_.front().type
- << " last frame type:" << queued_frames_.back().type;
- return;
- }
-
- const QuicPacketNumber next_packet_number = NextSendingPacketNumber();
- QUICHE_DCHECK_LE(least_packet_awaited_by_peer, next_packet_number)
- << ENDPOINT;
- const uint64_t current_delta =
- next_packet_number - least_packet_awaited_by_peer;
- const uint64_t delta = std::max(current_delta, max_packets_in_flight);
- const QuicPacketNumberLength packet_number_length =
- QuicFramer::GetMinPacketNumberLength(QuicPacketNumber(delta * 4));
- if (packet_.packet_number_length == packet_number_length) {
- return;
- }
- QUIC_DVLOG(1) << ENDPOINT << "Updating packet number length from "
- << static_cast<int>(packet_.packet_number_length) << " to "
- << static_cast<int>(packet_number_length)
- << ", least_packet_awaited_by_peer: "
- << least_packet_awaited_by_peer
- << " max_packets_in_flight: " << max_packets_in_flight
- << " next_packet_number: " << next_packet_number;
- packet_.packet_number_length = packet_number_length;
-}
-
-void QuicPacketCreator::SkipNPacketNumbers(
- QuicPacketCount count,
- QuicPacketNumber least_packet_awaited_by_peer,
- QuicPacketCount max_packets_in_flight) {
- if (!queued_frames_.empty()) {
- // Don't change creator state if there are frames queued.
- QUIC_BUG(quic_bug_10752_4)
- << ENDPOINT << "Called SkipNPacketNumbers with "
- << queued_frames_.size()
- << " queued_frames. First frame type:" << queued_frames_.front().type
- << " last frame type:" << queued_frames_.back().type;
- return;
- }
- if (packet_.packet_number > packet_.packet_number + count) {
- // Skipping count packet numbers causes packet number wrapping around,
- // reject it.
- QUIC_LOG(WARNING) << ENDPOINT << "Skipping " << count
- << " packet numbers causes packet number wrapping "
- "around, least_packet_awaited_by_peer: "
- << least_packet_awaited_by_peer
- << " packet_number:" << packet_.packet_number;
- return;
- }
- packet_.packet_number += count;
- // Packet number changes, update packet number length if necessary.
- UpdatePacketNumberLength(least_packet_awaited_by_peer, max_packets_in_flight);
-}
-
-bool QuicPacketCreator::ConsumeCryptoDataToFillCurrentPacket(
- EncryptionLevel level,
- size_t write_length,
- QuicStreamOffset offset,
- bool needs_full_padding,
- TransmissionType transmission_type,
- QuicFrame* frame) {
- QUIC_DVLOG(2) << ENDPOINT << "ConsumeCryptoDataToFillCurrentPacket " << level
- << " write_length " << write_length << " offset " << offset
- << (needs_full_padding ? " needs_full_padding" : "") << " "
- << transmission_type;
- if (!CreateCryptoFrame(level, write_length, offset, frame)) {
- return false;
- }
- // When crypto data was sent in stream frames, ConsumeData is called with
- // |needs_full_padding = true|. Keep the same behavior here when sending
- // crypto frames.
- //
- // TODO(nharper): Check what the IETF drafts say about padding out initial
- // messages and change this as appropriate.
- if (needs_full_padding) {
- needs_full_padding_ = true;
- }
- return AddFrame(*frame, transmission_type);
-}
-
-bool QuicPacketCreator::ConsumeDataToFillCurrentPacket(
- QuicStreamId id,
- size_t data_size,
- QuicStreamOffset offset,
- bool fin,
- bool needs_full_padding,
- TransmissionType transmission_type,
- QuicFrame* frame) {
- if (!HasRoomForStreamFrame(id, offset, data_size)) {
- return false;
- }
- CreateStreamFrame(id, data_size, offset, fin, frame);
- // Explicitly disallow multi-packet CHLOs.
- if (GetQuicFlag(FLAGS_quic_enforce_single_packet_chlo) &&
- StreamFrameIsClientHello(frame->stream_frame) &&
- frame->stream_frame.data_length < data_size) {
- const std::string error_details =
- "Client hello won't fit in a single packet.";
- QUIC_BUG(quic_bug_10752_5)
- << ENDPOINT << error_details << " Constructed stream frame length: "
- << frame->stream_frame.data_length << " CHLO length: " << data_size;
- delegate_->OnUnrecoverableError(QUIC_CRYPTO_CHLO_TOO_LARGE, error_details);
- return false;
- }
- if (!AddFrame(*frame, transmission_type)) {
- // Fails if we try to write unencrypted stream data.
- return false;
- }
- if (needs_full_padding) {
- needs_full_padding_ = true;
- }
-
- return true;
-}
-
-bool QuicPacketCreator::HasRoomForStreamFrame(QuicStreamId id,
- QuicStreamOffset offset,
- size_t data_size) {
- const size_t min_stream_frame_size = QuicFramer::GetMinStreamFrameSize(
- framer_->transport_version(), id, offset, /*last_frame_in_packet=*/true,
- data_size);
- if (BytesFree() > min_stream_frame_size) {
- return true;
- }
- if (!RemoveSoftMaxPacketLength()) {
- return false;
- }
- return BytesFree() > min_stream_frame_size;
-}
-
-bool QuicPacketCreator::HasRoomForMessageFrame(QuicByteCount length) {
- const size_t message_frame_size = QuicFramer::GetMessageFrameSize(
- framer_->transport_version(), /*last_frame_in_packet=*/true, length);
- if (static_cast<QuicByteCount>(message_frame_size) >
- max_datagram_frame_size_) {
- return false;
- }
- if (BytesFree() >= message_frame_size) {
- return true;
- }
- if (!RemoveSoftMaxPacketLength()) {
- return false;
- }
- return BytesFree() >= message_frame_size;
-}
-
-// static
-size_t QuicPacketCreator::StreamFramePacketOverhead(
- QuicTransportVersion version,
- QuicConnectionIdLength destination_connection_id_length,
- QuicConnectionIdLength source_connection_id_length,
- bool include_version,
- bool include_diversification_nonce,
- QuicPacketNumberLength packet_number_length,
- QuicVariableLengthIntegerLength retry_token_length_length,
- QuicVariableLengthIntegerLength length_length,
- QuicStreamOffset offset) {
- return GetPacketHeaderSize(version, destination_connection_id_length,
- source_connection_id_length, include_version,
- include_diversification_nonce,
- packet_number_length, retry_token_length_length, 0,
- length_length) +
-
- // Assumes a packet with a single stream frame, which omits the length,
- // causing the data length argument to be ignored.
- QuicFramer::GetMinStreamFrameSize(version, 1u, offset, true,
- kMaxOutgoingPacketSize /* unused */);
-}
-
-void QuicPacketCreator::CreateStreamFrame(QuicStreamId id,
- size_t data_size,
- QuicStreamOffset offset,
- bool fin,
- QuicFrame* frame) {
- // Make sure max_packet_length_ is greater than the largest possible overhead
- // or max_packet_length_ is set to the soft limit.
- QUICHE_DCHECK(
- max_packet_length_ >
- StreamFramePacketOverhead(
- framer_->transport_version(), GetDestinationConnectionIdLength(),
- GetSourceConnectionIdLength(), kIncludeVersion,
- IncludeNonceInPublicHeader(), PACKET_6BYTE_PACKET_NUMBER,
- GetRetryTokenLengthLength(), GetLengthLength(), offset) ||
- latched_hard_max_packet_length_ > 0)
- << ENDPOINT;
-
- QUIC_BUG_IF(quic_bug_12398_3, !HasRoomForStreamFrame(id, offset, data_size))
- << ENDPOINT << "No room for Stream frame, BytesFree: " << BytesFree()
- << " MinStreamFrameSize: "
- << QuicFramer::GetMinStreamFrameSize(framer_->transport_version(), id,
- offset, true, data_size);
-
- QUIC_BUG_IF(quic_bug_12398_4, data_size == 0 && !fin)
- << ENDPOINT << "Creating a stream frame for stream ID:" << id
- << " with no data or fin.";
- size_t min_frame_size = QuicFramer::GetMinStreamFrameSize(
- framer_->transport_version(), id, offset,
- /* last_frame_in_packet= */ true, data_size);
- size_t bytes_consumed =
- std::min<size_t>(BytesFree() - min_frame_size, data_size);
-
- bool set_fin = fin && bytes_consumed == data_size; // Last frame.
- *frame = QuicFrame(QuicStreamFrame(id, set_fin, offset, bytes_consumed));
-}
-
-bool QuicPacketCreator::CreateCryptoFrame(EncryptionLevel level,
- size_t write_length,
- QuicStreamOffset offset,
- QuicFrame* frame) {
- const size_t min_frame_size =
- QuicFramer::GetMinCryptoFrameSize(write_length, offset);
- if (BytesFree() <= min_frame_size &&
- (!RemoveSoftMaxPacketLength() || BytesFree() <= min_frame_size)) {
- return false;
- }
- size_t max_write_length = BytesFree() - min_frame_size;
- size_t bytes_consumed = std::min<size_t>(max_write_length, write_length);
- *frame = QuicFrame(new QuicCryptoFrame(level, offset, bytes_consumed));
- return true;
-}
-
-void QuicPacketCreator::FlushCurrentPacket() {
- if (!HasPendingFrames() && pending_padding_bytes_ == 0) {
- return;
- }
-
- ABSL_CACHELINE_ALIGNED char stack_buffer[kMaxOutgoingPacketSize];
- QuicOwnedPacketBuffer external_buffer(delegate_->GetPacketBuffer());
-
- if (external_buffer.buffer == nullptr) {
- external_buffer.buffer = stack_buffer;
- external_buffer.release_buffer = nullptr;
- }
-
- QUICHE_DCHECK_EQ(nullptr, packet_.encrypted_buffer) << ENDPOINT;
- if (!SerializePacket(std::move(external_buffer), kMaxOutgoingPacketSize)) {
- return;
- }
- OnSerializedPacket();
-}
-
-void QuicPacketCreator::OnSerializedPacket() {
- QUIC_BUG_IF(quic_bug_12398_5, packet_.encrypted_buffer == nullptr)
- << ENDPOINT;
-
- SerializedPacket packet(std::move(packet_));
- ClearPacket();
- RemoveSoftMaxPacketLength();
- delegate_->OnSerializedPacket(std::move(packet));
-}
-
-void QuicPacketCreator::ClearPacket() {
- packet_.has_ack = false;
- packet_.has_stop_waiting = false;
- packet_.has_crypto_handshake = NOT_HANDSHAKE;
- packet_.transmission_type = NOT_RETRANSMISSION;
- packet_.encrypted_buffer = nullptr;
- packet_.encrypted_length = 0;
- packet_.has_ack_frequency = false;
- packet_.has_message = false;
- packet_.fate = SEND_TO_WRITER;
- QUIC_BUG_IF(quic_bug_12398_6, packet_.release_encrypted_buffer != nullptr)
- << ENDPOINT << "packet_.release_encrypted_buffer should be empty";
- packet_.release_encrypted_buffer = nullptr;
- QUICHE_DCHECK(packet_.retransmittable_frames.empty()) << ENDPOINT;
- QUICHE_DCHECK(packet_.nonretransmittable_frames.empty()) << ENDPOINT;
- packet_.largest_acked.Clear();
- needs_full_padding_ = false;
-}
-
-size_t QuicPacketCreator::ReserializeInitialPacketInCoalescedPacket(
- const SerializedPacket& packet,
- size_t padding_size,
- char* buffer,
- size_t buffer_len) {
- QUIC_BUG_IF(quic_bug_12398_7, packet.encryption_level != ENCRYPTION_INITIAL);
- QUIC_BUG_IF(quic_bug_12398_8, packet.nonretransmittable_frames.empty() &&
- packet.retransmittable_frames.empty())
- << ENDPOINT
- << "Attempt to serialize empty ENCRYPTION_INITIAL packet in coalesced "
- "packet";
- ScopedPacketContextSwitcher switcher(
- packet.packet_number -
- 1, // -1 because serialize packet increase packet number.
- packet.packet_number_length, packet.encryption_level, &packet_);
- for (const QuicFrame& frame : packet.nonretransmittable_frames) {
- if (!AddFrame(frame, packet.transmission_type)) {
- QUIC_BUG(quic_bug_10752_6)
- << ENDPOINT << "Failed to serialize frame: " << frame;
- return 0;
- }
- }
- for (const QuicFrame& frame : packet.retransmittable_frames) {
- if (!AddFrame(frame, packet.transmission_type)) {
- QUIC_BUG(quic_bug_10752_7)
- << ENDPOINT << "Failed to serialize frame: " << frame;
- return 0;
- }
- }
- // Add necessary padding.
- if (padding_size > 0) {
- QUIC_DVLOG(2) << ENDPOINT << "Add padding of size: " << padding_size;
- if (!AddFrame(QuicFrame(QuicPaddingFrame(padding_size)),
- packet.transmission_type)) {
- QUIC_BUG(quic_bug_10752_8)
- << ENDPOINT << "Failed to add padding of size " << padding_size
- << " when serializing ENCRYPTION_INITIAL "
- "packet in coalesced packet";
- return 0;
- }
- }
- if (!SerializePacket(QuicOwnedPacketBuffer(buffer, nullptr), buffer_len)) {
- return 0;
- }
- const size_t encrypted_length = packet_.encrypted_length;
- // Clear frames in packet_. No need to DeleteFrames since frames are owned by
- // initial_packet.
- packet_.retransmittable_frames.clear();
- packet_.nonretransmittable_frames.clear();
- ClearPacket();
- return encrypted_length;
-}
-
-void QuicPacketCreator::CreateAndSerializeStreamFrame(
- QuicStreamId id,
- size_t write_length,
- QuicStreamOffset iov_offset,
- QuicStreamOffset stream_offset,
- bool fin,
- TransmissionType transmission_type,
- size_t* num_bytes_consumed) {
- // TODO(b/167222597): consider using ScopedSerializationFailureHandler.
- QUICHE_DCHECK(queued_frames_.empty()) << ENDPOINT;
- QUICHE_DCHECK(!QuicUtils::IsCryptoStreamId(transport_version(), id))
- << ENDPOINT;
- // Write out the packet header
- QuicPacketHeader header;
- FillPacketHeader(&header);
- packet_.fate = delegate_->GetSerializedPacketFate(
- /*is_mtu_discovery=*/false, packet_.encryption_level);
- QUIC_DVLOG(1) << ENDPOINT << "fate of packet " << packet_.packet_number
- << ": " << SerializedPacketFateToString(packet_.fate) << " of "
- << EncryptionLevelToString(packet_.encryption_level);
-
- ABSL_CACHELINE_ALIGNED char stack_buffer[kMaxOutgoingPacketSize];
- QuicOwnedPacketBuffer packet_buffer(delegate_->GetPacketBuffer());
-
- if (packet_buffer.buffer == nullptr) {
- packet_buffer.buffer = stack_buffer;
- packet_buffer.release_buffer = nullptr;
- }
-
- char* encrypted_buffer = packet_buffer.buffer;
-
- QuicDataWriter writer(kMaxOutgoingPacketSize, encrypted_buffer);
- size_t length_field_offset = 0;
- if (!framer_->AppendPacketHeader(header, &writer, &length_field_offset)) {
- QUIC_BUG(quic_bug_10752_9) << ENDPOINT << "AppendPacketHeader failed";
- return;
- }
-
- // Create a Stream frame with the remaining space.
- QUIC_BUG_IF(quic_bug_12398_9, iov_offset == write_length && !fin)
- << ENDPOINT << "Creating a stream frame with no data or fin.";
- const size_t remaining_data_size = write_length - iov_offset;
- size_t min_frame_size = QuicFramer::GetMinStreamFrameSize(
- framer_->transport_version(), id, stream_offset,
- /* last_frame_in_packet= */ true, remaining_data_size);
- size_t available_size =
- max_plaintext_size_ - writer.length() - min_frame_size;
- size_t bytes_consumed = std::min<size_t>(available_size, remaining_data_size);
- size_t plaintext_bytes_written = min_frame_size + bytes_consumed;
- bool needs_padding = false;
- if (plaintext_bytes_written < MinPlaintextPacketSize(framer_->version())) {
- needs_padding = true;
- // Recalculate sizes with the stream frame not being marked as the last
- // frame in the packet.
- min_frame_size = QuicFramer::GetMinStreamFrameSize(
- framer_->transport_version(), id, stream_offset,
- /* last_frame_in_packet= */ false, remaining_data_size);
- available_size = max_plaintext_size_ - writer.length() - min_frame_size;
- bytes_consumed = std::min<size_t>(available_size, remaining_data_size);
- plaintext_bytes_written = min_frame_size + bytes_consumed;
- }
-
- const bool set_fin = fin && (bytes_consumed == remaining_data_size);
- QuicStreamFrame frame(id, set_fin, stream_offset, bytes_consumed);
- if (debug_delegate_ != nullptr) {
- debug_delegate_->OnFrameAddedToPacket(QuicFrame(frame));
- }
- QUIC_DVLOG(1) << ENDPOINT << "Adding frame: " << frame;
-
- QUIC_DVLOG(2) << ENDPOINT << "Serializing stream packet " << header << frame;
-
- // TODO(ianswett): AppendTypeByte and AppendStreamFrame could be optimized
- // into one method that takes a QuicStreamFrame, if warranted.
- bool omit_frame_length = !needs_padding;
- if (!framer_->AppendTypeByte(QuicFrame(frame), omit_frame_length, &writer)) {
- QUIC_BUG(quic_bug_10752_10) << ENDPOINT << "AppendTypeByte failed";
- return;
- }
- if (!framer_->AppendStreamFrame(frame, omit_frame_length, &writer)) {
- QUIC_BUG(quic_bug_10752_11) << ENDPOINT << "AppendStreamFrame failed";
- return;
- }
- if (needs_padding &&
- plaintext_bytes_written < MinPlaintextPacketSize(framer_->version()) &&
- !writer.WritePaddingBytes(MinPlaintextPacketSize(framer_->version()) -
- plaintext_bytes_written)) {
- QUIC_BUG(quic_bug_10752_12) << ENDPOINT << "Unable to add padding bytes";
- return;
- }
-
- if (!framer_->WriteIetfLongHeaderLength(header, &writer, length_field_offset,
- packet_.encryption_level)) {
- return;
- }
-
- packet_.transmission_type = transmission_type;
-
- QUICHE_DCHECK(packet_.encryption_level == ENCRYPTION_FORWARD_SECURE ||
- packet_.encryption_level == ENCRYPTION_ZERO_RTT)
- << ENDPOINT << packet_.encryption_level;
- size_t encrypted_length = framer_->EncryptInPlace(
- packet_.encryption_level, packet_.packet_number,
- GetStartOfEncryptedData(framer_->transport_version(), header),
- writer.length(), kMaxOutgoingPacketSize, encrypted_buffer);
- if (encrypted_length == 0) {
- QUIC_BUG(quic_bug_10752_13)
- << ENDPOINT << "Failed to encrypt packet number "
- << header.packet_number;
- return;
- }
- // TODO(ianswett): Optimize the storage so RetransmitableFrames can be
- // unioned with a QuicStreamFrame and a UniqueStreamBuffer.
- *num_bytes_consumed = bytes_consumed;
- packet_size_ = 0;
- packet_.encrypted_buffer = encrypted_buffer;
- packet_.encrypted_length = encrypted_length;
-
- packet_buffer.buffer = nullptr;
- packet_.release_encrypted_buffer = std::move(packet_buffer).release_buffer;
-
- packet_.retransmittable_frames.push_back(QuicFrame(frame));
- OnSerializedPacket();
-}
-
-bool QuicPacketCreator::HasPendingFrames() const {
- return !queued_frames_.empty();
-}
-
-std::string QuicPacketCreator::GetPendingFramesInfo() const {
- return QuicFramesToString(queued_frames_);
-}
-
-bool QuicPacketCreator::HasPendingRetransmittableFrames() const {
- return !packet_.retransmittable_frames.empty();
-}
-
-bool QuicPacketCreator::HasPendingStreamFramesOfStream(QuicStreamId id) const {
- for (const auto& frame : packet_.retransmittable_frames) {
- if (frame.type == STREAM_FRAME && frame.stream_frame.stream_id == id) {
- return true;
- }
- }
- return false;
-}
-
-size_t QuicPacketCreator::ExpansionOnNewFrame() const {
- // If the last frame in the packet is a message frame, then it will expand to
- // include the varint message length when a new frame is added.
- if (queued_frames_.empty()) {
- return 0;
- }
- return ExpansionOnNewFrameWithLastFrame(queued_frames_.back(),
- framer_->transport_version());
-}
-
-// static
-size_t QuicPacketCreator::ExpansionOnNewFrameWithLastFrame(
- const QuicFrame& last_frame,
- QuicTransportVersion version) {
- if (last_frame.type == MESSAGE_FRAME) {
- return QuicDataWriter::GetVarInt62Len(
- last_frame.message_frame->message_length);
- }
- if (last_frame.type != STREAM_FRAME) {
- return 0;
- }
- if (VersionHasIetfQuicFrames(version)) {
- return QuicDataWriter::GetVarInt62Len(last_frame.stream_frame.data_length);
- }
- return kQuicStreamPayloadLengthSize;
-}
-
-size_t QuicPacketCreator::BytesFree() const {
- return max_plaintext_size_ -
- std::min(max_plaintext_size_, PacketSize() + ExpansionOnNewFrame());
-}
-
-size_t QuicPacketCreator::PacketSize() const {
- return queued_frames_.empty() ? PacketHeaderSize() : packet_size_;
-}
-
-bool QuicPacketCreator::AddPaddedSavedFrame(
- const QuicFrame& frame,
- TransmissionType transmission_type) {
- if (AddFrame(frame, transmission_type)) {
- needs_full_padding_ = true;
- return true;
- }
- return false;
-}
-
-absl::optional<size_t>
-QuicPacketCreator::MaybeBuildDataPacketWithChaosProtection(
- const QuicPacketHeader& header,
- char* buffer) {
- if (!chaos_protection_enabled_ ||
- packet_.encryption_level != ENCRYPTION_INITIAL ||
- !framer_->version().UsesCryptoFrames() || queued_frames_.size() != 2u ||
- queued_frames_[0].type != CRYPTO_FRAME ||
- queued_frames_[1].type != PADDING_FRAME ||
- // Do not perform chaos protection if we do not have a known number of
- // padding bytes to work with.
- queued_frames_[1].padding_frame.num_padding_bytes <= 0 ||
- // Chaos protection relies on the framer using a crypto data producer,
- // which is always the case in practice.
- framer_->data_producer() == nullptr) {
- return absl::nullopt;
- }
- const QuicCryptoFrame& crypto_frame = *queued_frames_[0].crypto_frame;
- if (packet_.encryption_level != crypto_frame.level) {
- QUIC_BUG(chaos frame level)
- << ENDPOINT << packet_.encryption_level << " != " << crypto_frame.level;
- return absl::nullopt;
- }
- QuicChaosProtector chaos_protector(
- crypto_frame, queued_frames_[1].padding_frame.num_padding_bytes,
- packet_size_, framer_, random_);
- return chaos_protector.BuildDataPacket(header, buffer);
-}
-
-bool QuicPacketCreator::SerializePacket(QuicOwnedPacketBuffer encrypted_buffer,
- size_t encrypted_buffer_len) {
- if (packet_.encrypted_buffer != nullptr) {
- const std::string error_details =
- "Packet's encrypted buffer is not empty before serialization";
- QUIC_BUG(quic_bug_10752_14) << ENDPOINT << error_details;
- delegate_->OnUnrecoverableError(QUIC_FAILED_TO_SERIALIZE_PACKET,
- error_details);
- return false;
- }
- ScopedSerializationFailureHandler handler(this);
-
- QUICHE_DCHECK_LT(0u, encrypted_buffer_len) << ENDPOINT;
- QUIC_BUG_IF(quic_bug_12398_10,
- queued_frames_.empty() && pending_padding_bytes_ == 0)
- << ENDPOINT << "Attempt to serialize empty packet";
- QuicPacketHeader header;
- // FillPacketHeader increments packet_number_.
- FillPacketHeader(&header);
- if (delegate_ != nullptr) {
- packet_.fate = delegate_->GetSerializedPacketFate(
- /*is_mtu_discovery=*/QuicUtils::ContainsFrameType(queued_frames_,
- MTU_DISCOVERY_FRAME),
- packet_.encryption_level);
- QUIC_DVLOG(1) << ENDPOINT << "fate of packet " << packet_.packet_number
- << ": " << SerializedPacketFateToString(packet_.fate)
- << " of "
- << EncryptionLevelToString(packet_.encryption_level);
- }
-
- MaybeAddPadding();
-
- QUIC_DVLOG(2) << ENDPOINT << "Serializing packet " << header
- << QuicFramesToString(queued_frames_) << " at encryption_level "
- << packet_.encryption_level;
-
- if (!framer_->HasEncrypterOfEncryptionLevel(packet_.encryption_level)) {
- // TODO(fayang): Use QUIC_MISSING_WRITE_KEYS for serialization failures due
- // to missing keys.
- QUIC_BUG(quic_bug_10752_15)
- << ENDPOINT << "Attempting to serialize " << header
- << QuicFramesToString(queued_frames_) << " at missing encryption_level "
- << packet_.encryption_level << " using " << framer_->version();
- return false;
- }
-
- QUICHE_DCHECK_GE(max_plaintext_size_, packet_size_) << ENDPOINT;
- // Use the packet_size_ instead of the buffer size to ensure smaller
- // packet sizes are properly used.
-
- size_t length;
- absl::optional<size_t> length_with_chaos_protection =
- MaybeBuildDataPacketWithChaosProtection(header, encrypted_buffer.buffer);
- if (length_with_chaos_protection.has_value()) {
- length = length_with_chaos_protection.value();
- } else {
- length = framer_->BuildDataPacket(header, queued_frames_,
- encrypted_buffer.buffer, packet_size_,
- packet_.encryption_level);
- }
-
- if (length == 0) {
- QUIC_BUG(quic_bug_10752_16)
- << ENDPOINT << "Failed to serialize "
- << QuicFramesToString(queued_frames_)
- << " at encryption_level: " << packet_.encryption_level
- << ", needs_full_padding_: " << needs_full_padding_
- << ", pending_padding_bytes_: " << pending_padding_bytes_
- << ", latched_hard_max_packet_length_: "
- << latched_hard_max_packet_length_
- << ", max_packet_length_: " << max_packet_length_
- << ", header: " << header;
- return false;
- }
-
- // ACK Frames will be truncated due to length only if they're the only frame
- // in the packet, and if packet_size_ was set to max_plaintext_size_. If
- // truncation due to length occurred, then GetSerializedFrameLength will have
- // returned all bytes free.
- bool possibly_truncated_by_length = packet_size_ == max_plaintext_size_ &&
- queued_frames_.size() == 1 &&
- queued_frames_.back().type == ACK_FRAME;
- // Because of possible truncation, we can't be confident that our
- // packet size calculation worked correctly.
- if (!possibly_truncated_by_length) {
- QUICHE_DCHECK_EQ(packet_size_, length) << ENDPOINT;
- }
- const size_t encrypted_length = framer_->EncryptInPlace(
- packet_.encryption_level, packet_.packet_number,
- GetStartOfEncryptedData(framer_->transport_version(), header), length,
- encrypted_buffer_len, encrypted_buffer.buffer);
- if (encrypted_length == 0) {
- QUIC_BUG(quic_bug_10752_17)
- << ENDPOINT << "Failed to encrypt packet number "
- << packet_.packet_number;
- return false;
- }
-
- packet_size_ = 0;
- packet_.encrypted_buffer = encrypted_buffer.buffer;
- packet_.encrypted_length = encrypted_length;
-
- encrypted_buffer.buffer = nullptr;
- packet_.release_encrypted_buffer = std::move(encrypted_buffer).release_buffer;
- return true;
-}
-
-std::unique_ptr<SerializedPacket>
-QuicPacketCreator::SerializeConnectivityProbingPacket() {
- QUIC_BUG_IF(quic_bug_12398_11,
- VersionHasIetfQuicFrames(framer_->transport_version()))
- << ENDPOINT
- << "Must not be version 99 to serialize padded ping connectivity probe";
- RemoveSoftMaxPacketLength();
- QuicPacketHeader header;
- // FillPacketHeader increments packet_number_.
- FillPacketHeader(&header);
-
- QUIC_DVLOG(2) << ENDPOINT << "Serializing connectivity probing packet "
- << header;
-
- std::unique_ptr<char[]> buffer(new char[kMaxOutgoingPacketSize]);
- size_t length = BuildConnectivityProbingPacket(
- header, buffer.get(), max_plaintext_size_, packet_.encryption_level);
- QUICHE_DCHECK(length) << ENDPOINT;
-
- QUICHE_DCHECK_EQ(packet_.encryption_level, ENCRYPTION_FORWARD_SECURE)
- << ENDPOINT;
- const size_t encrypted_length = framer_->EncryptInPlace(
- packet_.encryption_level, packet_.packet_number,
- GetStartOfEncryptedData(framer_->transport_version(), header), length,
- kMaxOutgoingPacketSize, buffer.get());
- QUICHE_DCHECK(encrypted_length) << ENDPOINT;
-
- std::unique_ptr<SerializedPacket> serialize_packet(new SerializedPacket(
- header.packet_number, header.packet_number_length, buffer.release(),
- encrypted_length, /*has_ack=*/false, /*has_stop_waiting=*/false));
-
- serialize_packet->release_encrypted_buffer = [](const char* p) {
- delete[] p;
- };
- serialize_packet->encryption_level = packet_.encryption_level;
- serialize_packet->transmission_type = NOT_RETRANSMISSION;
-
- return serialize_packet;
-}
-
-std::unique_ptr<SerializedPacket>
-QuicPacketCreator::SerializePathChallengeConnectivityProbingPacket(
- const QuicPathFrameBuffer& payload) {
- QUIC_BUG_IF(quic_bug_12398_12,
- !VersionHasIetfQuicFrames(framer_->transport_version()))
- << ENDPOINT
- << "Must be version 99 to serialize path challenge connectivity probe, "
- "is version "
- << framer_->transport_version();
- RemoveSoftMaxPacketLength();
- QuicPacketHeader header;
- // FillPacketHeader increments packet_number_.
- FillPacketHeader(&header);
-
- QUIC_DVLOG(2) << ENDPOINT << "Serializing path challenge packet " << header;
-
- std::unique_ptr<char[]> buffer(new char[kMaxOutgoingPacketSize]);
- size_t length =
- BuildPaddedPathChallengePacket(header, buffer.get(), max_plaintext_size_,
- payload, packet_.encryption_level);
- QUICHE_DCHECK(length) << ENDPOINT;
-
- QUICHE_DCHECK_EQ(packet_.encryption_level, ENCRYPTION_FORWARD_SECURE)
- << ENDPOINT;
- const size_t encrypted_length = framer_->EncryptInPlace(
- packet_.encryption_level, packet_.packet_number,
- GetStartOfEncryptedData(framer_->transport_version(), header), length,
- kMaxOutgoingPacketSize, buffer.get());
- QUICHE_DCHECK(encrypted_length) << ENDPOINT;
-
- std::unique_ptr<SerializedPacket> serialize_packet(
- new SerializedPacket(header.packet_number, header.packet_number_length,
- buffer.release(), encrypted_length,
- /*has_ack=*/false, /*has_stop_waiting=*/false));
-
- serialize_packet->release_encrypted_buffer = [](const char* p) {
- delete[] p;
- };
- serialize_packet->encryption_level = packet_.encryption_level;
- serialize_packet->transmission_type = NOT_RETRANSMISSION;
-
- return serialize_packet;
-}
-
-std::unique_ptr<SerializedPacket>
-QuicPacketCreator::SerializePathResponseConnectivityProbingPacket(
- const quiche::QuicheCircularDeque<QuicPathFrameBuffer>& payloads,
- const bool is_padded) {
- QUIC_BUG_IF(quic_bug_12398_13,
- !VersionHasIetfQuicFrames(framer_->transport_version()))
- << ENDPOINT
- << "Must be version 99 to serialize path response connectivity probe, is "
- "version "
- << framer_->transport_version();
- RemoveSoftMaxPacketLength();
- QuicPacketHeader header;
- // FillPacketHeader increments packet_number_.
- FillPacketHeader(&header);
-
- QUIC_DVLOG(2) << ENDPOINT << "Serializing path response packet " << header;
-
- std::unique_ptr<char[]> buffer(new char[kMaxOutgoingPacketSize]);
- size_t length =
- BuildPathResponsePacket(header, buffer.get(), max_plaintext_size_,
- payloads, is_padded, packet_.encryption_level);
- QUICHE_DCHECK(length) << ENDPOINT;
-
- QUICHE_DCHECK_EQ(packet_.encryption_level, ENCRYPTION_FORWARD_SECURE)
- << ENDPOINT;
- const size_t encrypted_length = framer_->EncryptInPlace(
- packet_.encryption_level, packet_.packet_number,
- GetStartOfEncryptedData(framer_->transport_version(), header), length,
- kMaxOutgoingPacketSize, buffer.get());
- QUICHE_DCHECK(encrypted_length) << ENDPOINT;
-
- std::unique_ptr<SerializedPacket> serialize_packet(
- new SerializedPacket(header.packet_number, header.packet_number_length,
- buffer.release(), encrypted_length,
- /*has_ack=*/false, /*has_stop_waiting=*/false));
-
- serialize_packet->release_encrypted_buffer = [](const char* p) {
- delete[] p;
- };
- serialize_packet->encryption_level = packet_.encryption_level;
- serialize_packet->transmission_type = NOT_RETRANSMISSION;
-
- return serialize_packet;
-}
-
-size_t QuicPacketCreator::BuildPaddedPathChallengePacket(
- const QuicPacketHeader& header,
- char* buffer,
- size_t packet_length,
- const QuicPathFrameBuffer& payload,
- EncryptionLevel level) {
- QUICHE_DCHECK(VersionHasIetfQuicFrames(framer_->transport_version()))
- << ENDPOINT;
- QuicFrames frames;
-
- // Write a PATH_CHALLENGE frame, which has a random 8-byte payload
- QuicPathChallengeFrame path_challenge_frame(0, payload);
- frames.push_back(QuicFrame(&path_challenge_frame));
-
- if (debug_delegate_ != nullptr) {
- debug_delegate_->OnFrameAddedToPacket(QuicFrame(&path_challenge_frame));
- }
-
- // Add padding to the rest of the packet in order to assess Path MTU
- // characteristics.
- QuicPaddingFrame padding_frame;
- frames.push_back(QuicFrame(padding_frame));
-
- return framer_->BuildDataPacket(header, frames, buffer, packet_length, level);
-}
-
-size_t QuicPacketCreator::BuildPathResponsePacket(
- const QuicPacketHeader& header,
- char* buffer,
- size_t packet_length,
- const quiche::QuicheCircularDeque<QuicPathFrameBuffer>& payloads,
- const bool is_padded,
- EncryptionLevel level) {
- if (payloads.empty()) {
- QUIC_BUG(quic_bug_12398_14)
- << ENDPOINT
- << "Attempt to generate connectivity response with no request payloads";
- return 0;
- }
- QUICHE_DCHECK(VersionHasIetfQuicFrames(framer_->transport_version()))
- << ENDPOINT;
-
- std::vector<std::unique_ptr<QuicPathResponseFrame>> path_response_frames;
- for (const QuicPathFrameBuffer& payload : payloads) {
- // Note that the control frame ID can be 0 since this is not retransmitted.
- path_response_frames.push_back(
- std::make_unique<QuicPathResponseFrame>(0, payload));
- }
-
- QuicFrames frames;
- for (const std::unique_ptr<QuicPathResponseFrame>& path_response_frame :
- path_response_frames) {
- frames.push_back(QuicFrame(path_response_frame.get()));
- if (debug_delegate_ != nullptr) {
- debug_delegate_->OnFrameAddedToPacket(
- QuicFrame(path_response_frame.get()));
- }
- }
-
- if (is_padded) {
- // Add padding to the rest of the packet in order to assess Path MTU
- // characteristics.
- QuicPaddingFrame padding_frame;
- frames.push_back(QuicFrame(padding_frame));
- }
-
- return framer_->BuildDataPacket(header, frames, buffer, packet_length, level);
-}
-
-size_t QuicPacketCreator::BuildConnectivityProbingPacket(
- const QuicPacketHeader& header,
- char* buffer,
- size_t packet_length,
- EncryptionLevel level) {
- QuicFrames frames;
-
- // Write a PING frame, which has no data payload.
- QuicPingFrame ping_frame;
- frames.push_back(QuicFrame(ping_frame));
-
- // Add padding to the rest of the packet.
- QuicPaddingFrame padding_frame;
- frames.push_back(QuicFrame(padding_frame));
-
- return framer_->BuildDataPacket(header, frames, buffer, packet_length, level);
-}
-
-size_t QuicPacketCreator::SerializeCoalescedPacket(
- const QuicCoalescedPacket& coalesced,
- char* buffer,
- size_t buffer_len) {
- if (HasPendingFrames()) {
- QUIC_BUG(quic_bug_10752_18)
- << ENDPOINT << "Try to serialize coalesced packet with pending frames";
- return 0;
- }
- RemoveSoftMaxPacketLength();
- QUIC_BUG_IF(quic_bug_12398_15, coalesced.length() == 0)
- << ENDPOINT << "Attempt to serialize empty coalesced packet";
- size_t packet_length = 0;
- if (coalesced.initial_packet() != nullptr) {
- // Padding coalesced packet containing initial packet to full.
- size_t padding_size = coalesced.max_packet_length() - coalesced.length();
- if (framer_->perspective() == Perspective::IS_SERVER &&
- QuicUtils::ContainsFrameType(
- coalesced.initial_packet()->retransmittable_frames,
- CONNECTION_CLOSE_FRAME)) {
- // Do not pad server initial connection close packet.
- padding_size = 0;
- }
- size_t initial_length = ReserializeInitialPacketInCoalescedPacket(
- *coalesced.initial_packet(), padding_size, buffer, buffer_len);
- if (initial_length == 0) {
- QUIC_BUG(quic_bug_10752_19)
- << ENDPOINT
- << "Failed to reserialize ENCRYPTION_INITIAL packet in "
- "coalesced packet";
- return 0;
- }
- buffer += initial_length;
- buffer_len -= initial_length;
- packet_length += initial_length;
- }
- size_t length_copied = 0;
- if (!coalesced.CopyEncryptedBuffers(buffer, buffer_len, &length_copied)) {
- return 0;
- }
- packet_length += length_copied;
- QUIC_DVLOG(1) << ENDPOINT
- << "Successfully serialized coalesced packet of length: "
- << packet_length;
- return packet_length;
-}
-
-// TODO(b/74062209): Make this a public method of framer?
-SerializedPacket QuicPacketCreator::NoPacket() {
- return SerializedPacket(QuicPacketNumber(), PACKET_1BYTE_PACKET_NUMBER,
- nullptr, 0, false, false);
-}
-
-QuicConnectionId QuicPacketCreator::GetDestinationConnectionId() const {
- if (framer_->perspective() == Perspective::IS_SERVER) {
- return client_connection_id_;
- }
- return server_connection_id_;
-}
-
-QuicConnectionId QuicPacketCreator::GetSourceConnectionId() const {
- if (framer_->perspective() == Perspective::IS_CLIENT) {
- return client_connection_id_;
- }
- return server_connection_id_;
-}
-
-QuicConnectionIdIncluded QuicPacketCreator::GetDestinationConnectionIdIncluded()
- const {
- // In versions that do not support client connection IDs, the destination
- // connection ID is only sent from client to server.
- return (framer_->perspective() == Perspective::IS_CLIENT ||
- framer_->version().SupportsClientConnectionIds())
- ? CONNECTION_ID_PRESENT
- : CONNECTION_ID_ABSENT;
-}
-
-QuicConnectionIdIncluded QuicPacketCreator::GetSourceConnectionIdIncluded()
- const {
- // Long header packets sent by server include source connection ID.
- // Ones sent by the client only include source connection ID if the version
- // supports client connection IDs.
- if (HasIetfLongHeader() &&
- (framer_->perspective() == Perspective::IS_SERVER ||
- framer_->version().SupportsClientConnectionIds())) {
- return CONNECTION_ID_PRESENT;
- }
- if (framer_->perspective() == Perspective::IS_SERVER) {
- return server_connection_id_included_;
- }
- return CONNECTION_ID_ABSENT;
-}
-
-QuicConnectionIdLength QuicPacketCreator::GetDestinationConnectionIdLength()
- const {
- QUICHE_DCHECK(QuicUtils::IsConnectionIdValidForVersion(server_connection_id_,
- transport_version()))
- << ENDPOINT;
- return GetDestinationConnectionIdIncluded() == CONNECTION_ID_PRESENT
- ? static_cast<QuicConnectionIdLength>(
- GetDestinationConnectionId().length())
- : PACKET_0BYTE_CONNECTION_ID;
-}
-
-QuicConnectionIdLength QuicPacketCreator::GetSourceConnectionIdLength() const {
- QUICHE_DCHECK(QuicUtils::IsConnectionIdValidForVersion(server_connection_id_,
- transport_version()))
- << ENDPOINT;
- return GetSourceConnectionIdIncluded() == CONNECTION_ID_PRESENT
- ? static_cast<QuicConnectionIdLength>(
- GetSourceConnectionId().length())
- : PACKET_0BYTE_CONNECTION_ID;
-}
-
-QuicPacketNumberLength QuicPacketCreator::GetPacketNumberLength() const {
- if (HasIetfLongHeader() &&
- !framer_->version().SendsVariableLengthPacketNumberInLongHeader()) {
- return PACKET_4BYTE_PACKET_NUMBER;
- }
- return packet_.packet_number_length;
-}
-
-size_t QuicPacketCreator::PacketHeaderSize() const {
- return GetPacketHeaderSize(
- framer_->transport_version(), GetDestinationConnectionIdLength(),
- GetSourceConnectionIdLength(), IncludeVersionInHeader(),
- IncludeNonceInPublicHeader(), GetPacketNumberLength(),
- GetRetryTokenLengthLength(), GetRetryToken().length(), GetLengthLength());
-}
-
-QuicVariableLengthIntegerLength QuicPacketCreator::GetRetryTokenLengthLength()
- const {
- if (QuicVersionHasLongHeaderLengths(framer_->transport_version()) &&
- HasIetfLongHeader() &&
- EncryptionlevelToLongHeaderType(packet_.encryption_level) == INITIAL) {
- return QuicDataWriter::GetVarInt62Len(GetRetryToken().length());
- }
- return VARIABLE_LENGTH_INTEGER_LENGTH_0;
-}
-
-absl::string_view QuicPacketCreator::GetRetryToken() const {
- if (QuicVersionHasLongHeaderLengths(framer_->transport_version()) &&
- HasIetfLongHeader() &&
- EncryptionlevelToLongHeaderType(packet_.encryption_level) == INITIAL) {
- return retry_token_;
- }
- return absl::string_view();
-}
-
-void QuicPacketCreator::SetRetryToken(absl::string_view retry_token) {
- retry_token_ = std::string(retry_token);
-}
-
-bool QuicPacketCreator::ConsumeRetransmittableControlFrame(
- const QuicFrame& frame) {
- QUIC_BUG_IF(quic_bug_12398_16, IsControlFrame(frame.type) &&
- !GetControlFrameId(frame) &&
- frame.type != PING_FRAME)
- << ENDPOINT
- << "Adding a control frame with no control frame id: " << frame;
- QUICHE_DCHECK(QuicUtils::IsRetransmittableFrame(frame.type))
- << ENDPOINT << frame;
- MaybeBundleAckOpportunistically();
- if (HasPendingFrames()) {
- if (AddFrame(frame, next_transmission_type_)) {
- // There is pending frames and current frame fits.
- return true;
- }
- }
- QUICHE_DCHECK(!HasPendingFrames()) << ENDPOINT;
- if (frame.type != PING_FRAME && frame.type != CONNECTION_CLOSE_FRAME &&
- !delegate_->ShouldGeneratePacket(HAS_RETRANSMITTABLE_DATA,
- NOT_HANDSHAKE)) {
- // Do not check congestion window for ping or connection close frames.
- return false;
- }
- const bool success = AddFrame(frame, next_transmission_type_);
- QUIC_BUG_IF(quic_bug_10752_20, !success)
- << ENDPOINT << "Failed to add frame:" << frame
- << " transmission_type:" << next_transmission_type_;
- return success;
-}
-
-QuicConsumedData QuicPacketCreator::ConsumeData(QuicStreamId id,
- size_t write_length,
- QuicStreamOffset offset,
- StreamSendingState state) {
- QUIC_BUG_IF(quic_bug_10752_21, !flusher_attached_)
- << ENDPOINT
- << "Packet flusher is not attached when "
- "generator tries to write stream data.";
- bool has_handshake = QuicUtils::IsCryptoStreamId(transport_version(), id);
- MaybeBundleAckOpportunistically();
- bool fin = state != NO_FIN;
- QUIC_BUG_IF(quic_bug_12398_17, has_handshake && fin)
- << ENDPOINT << "Handshake packets should never send a fin";
- // To make reasoning about crypto frames easier, we don't combine them with
- // other retransmittable frames in a single packet.
- if (has_handshake && HasPendingRetransmittableFrames()) {
- FlushCurrentPacket();
- }
-
- size_t total_bytes_consumed = 0;
- bool fin_consumed = false;
-
- if (!HasRoomForStreamFrame(id, offset, write_length)) {
- FlushCurrentPacket();
- }
-
- if (!fin && (write_length == 0)) {
- QUIC_BUG(quic_bug_10752_22)
- << ENDPOINT << "Attempt to consume empty data without FIN.";
- return QuicConsumedData(0, false);
- }
- // We determine if we can enter the fast path before executing
- // the slow path loop.
- bool run_fast_path =
- !has_handshake && state != FIN_AND_PADDING && !HasPendingFrames() &&
- write_length - total_bytes_consumed > kMaxOutgoingPacketSize &&
- latched_hard_max_packet_length_ == 0;
-
- while (!run_fast_path &&
- (has_handshake || delegate_->ShouldGeneratePacket(
- HAS_RETRANSMITTABLE_DATA, NOT_HANDSHAKE))) {
- QuicFrame frame;
- bool needs_full_padding =
- has_handshake && fully_pad_crypto_handshake_packets_;
-
- if (!ConsumeDataToFillCurrentPacket(id, write_length - total_bytes_consumed,
- offset + total_bytes_consumed, fin,
- needs_full_padding,
- next_transmission_type_, &frame)) {
- // The creator is always flushed if there's not enough room for a new
- // stream frame before ConsumeData, so ConsumeData should always succeed.
- QUIC_BUG(quic_bug_10752_23)
- << ENDPOINT << "Failed to ConsumeData, stream:" << id;
- return QuicConsumedData(0, false);
- }
-
- // A stream frame is created and added.
- size_t bytes_consumed = frame.stream_frame.data_length;
- total_bytes_consumed += bytes_consumed;
- fin_consumed = fin && total_bytes_consumed == write_length;
- if (fin_consumed && state == FIN_AND_PADDING) {
- AddRandomPadding();
- }
- QUICHE_DCHECK(total_bytes_consumed == write_length ||
- (bytes_consumed > 0 && HasPendingFrames()))
- << ENDPOINT;
-
- if (total_bytes_consumed == write_length) {
- // We're done writing the data. Exit the loop.
- // We don't make this a precondition because we could have 0 bytes of data
- // if we're simply writing a fin.
- break;
- }
- FlushCurrentPacket();
-
- run_fast_path =
- !has_handshake && state != FIN_AND_PADDING && !HasPendingFrames() &&
- write_length - total_bytes_consumed > kMaxOutgoingPacketSize &&
- latched_hard_max_packet_length_ == 0;
- }
-
- if (run_fast_path) {
- return ConsumeDataFastPath(id, write_length, offset, state != NO_FIN,
- total_bytes_consumed);
- }
-
- // Don't allow the handshake to be bundled with other retransmittable frames.
- if (has_handshake) {
- FlushCurrentPacket();
- }
-
- return QuicConsumedData(total_bytes_consumed, fin_consumed);
-}
-
-QuicConsumedData QuicPacketCreator::ConsumeDataFastPath(
- QuicStreamId id,
- size_t write_length,
- QuicStreamOffset offset,
- bool fin,
- size_t total_bytes_consumed) {
- QUICHE_DCHECK(!QuicUtils::IsCryptoStreamId(transport_version(), id))
- << ENDPOINT;
- if (AttemptingToSendUnencryptedStreamData()) {
- return QuicConsumedData(total_bytes_consumed,
- fin && (total_bytes_consumed == write_length));
- }
-
- while (total_bytes_consumed < write_length &&
- delegate_->ShouldGeneratePacket(HAS_RETRANSMITTABLE_DATA,
- NOT_HANDSHAKE)) {
- // Serialize and encrypt the packet.
- size_t bytes_consumed = 0;
- CreateAndSerializeStreamFrame(id, write_length, total_bytes_consumed,
- offset + total_bytes_consumed, fin,
- next_transmission_type_, &bytes_consumed);
- if (bytes_consumed == 0) {
- const std::string error_details =
- "Failed in CreateAndSerializeStreamFrame.";
- QUIC_BUG(quic_bug_10752_24) << ENDPOINT << error_details;
- delegate_->OnUnrecoverableError(QUIC_FAILED_TO_SERIALIZE_PACKET,
- error_details);
- break;
- }
- total_bytes_consumed += bytes_consumed;
- }
-
- return QuicConsumedData(total_bytes_consumed,
- fin && (total_bytes_consumed == write_length));
-}
-
-size_t QuicPacketCreator::ConsumeCryptoData(EncryptionLevel level,
- size_t write_length,
- QuicStreamOffset offset) {
- QUIC_DVLOG(2) << ENDPOINT << "ConsumeCryptoData " << level << " write_length "
- << write_length << " offset " << offset;
- QUIC_BUG_IF(quic_bug_10752_25, !flusher_attached_)
- << ENDPOINT
- << "Packet flusher is not attached when "
- "generator tries to write crypto data.";
- MaybeBundleAckOpportunistically();
- // To make reasoning about crypto frames easier, we don't combine them with
- // other retransmittable frames in a single packet.
- // TODO(nharper): Once we have separate packet number spaces, everything
- // should be driven by encryption level, and we should stop flushing in this
- // spot.
- if (HasPendingRetransmittableFrames()) {
- FlushCurrentPacket();
- }
-
- size_t total_bytes_consumed = 0;
-
- while (
- total_bytes_consumed < write_length &&
- delegate_->ShouldGeneratePacket(HAS_RETRANSMITTABLE_DATA, IS_HANDSHAKE)) {
- QuicFrame frame;
- if (!ConsumeCryptoDataToFillCurrentPacket(
- level, write_length - total_bytes_consumed,
- offset + total_bytes_consumed, fully_pad_crypto_handshake_packets_,
- next_transmission_type_, &frame)) {
- // The only pending data in the packet is non-retransmittable frames. I'm
- // assuming here that they won't occupy so much of the packet that a
- // CRYPTO frame won't fit.
- const std::string error_message = absl::StrCat(
- ENDPOINT, "Failed to ConsumeCryptoData at level ", level,
- ", pending_frames: ", GetPendingFramesInfo(),
- ", has_soft_max_packet_length: ", HasSoftMaxPacketLength(),
- ", max_packet_length: ", max_packet_length_, ", transmission_type: ",
- TransmissionTypeToString(next_transmission_type_),
- ", packet_number: ", packet_number().ToString());
- QUIC_BUG(quic_bug_10752_26) << error_message;
- return 0;
- }
- total_bytes_consumed += frame.crypto_frame->data_length;
- FlushCurrentPacket();
- }
-
- // Don't allow the handshake to be bundled with other retransmittable frames.
- FlushCurrentPacket();
-
- return total_bytes_consumed;
-}
-
-void QuicPacketCreator::GenerateMtuDiscoveryPacket(QuicByteCount target_mtu) {
- // MTU discovery frames must be sent by themselves.
- if (!CanSetMaxPacketLength()) {
- QUIC_BUG(quic_bug_10752_27)
- << ENDPOINT
- << "MTU discovery packets should only be sent when no other "
- << "frames needs to be sent.";
- return;
- }
- const QuicByteCount current_mtu = max_packet_length();
-
- // The MTU discovery frame is allocated on the stack, since it is going to be
- // serialized within this function.
- QuicMtuDiscoveryFrame mtu_discovery_frame;
- QuicFrame frame(mtu_discovery_frame);
-
- // Send the probe packet with the new length.
- SetMaxPacketLength(target_mtu);
- const bool success = AddPaddedSavedFrame(frame, next_transmission_type_);
- FlushCurrentPacket();
- // The only reason AddFrame can fail is that the packet is too full to fit in
- // a ping. This is not possible for any sane MTU.
- QUIC_BUG_IF(quic_bug_10752_28, !success)
- << ENDPOINT << "Failed to send path MTU target_mtu:" << target_mtu
- << " transmission_type:" << next_transmission_type_;
-
- // Reset the packet length back.
- SetMaxPacketLength(current_mtu);
-}
-
-void QuicPacketCreator::MaybeBundleAckOpportunistically() {
- if (has_ack()) {
- // Ack already queued, nothing to do.
- return;
- }
- if (!delegate_->ShouldGeneratePacket(NO_RETRANSMITTABLE_DATA,
- NOT_HANDSHAKE)) {
- return;
- }
- const bool flushed =
- FlushAckFrame(delegate_->MaybeBundleAckOpportunistically());
- QUIC_BUG_IF(quic_bug_10752_29, !flushed)
- << ENDPOINT << "Failed to flush ACK frame. encryption_level:"
- << packet_.encryption_level;
-}
-
-bool QuicPacketCreator::FlushAckFrame(const QuicFrames& frames) {
- QUIC_BUG_IF(quic_bug_10752_30, !flusher_attached_)
- << ENDPOINT
- << "Packet flusher is not attached when "
- "generator tries to send ACK frame.";
- // MaybeBundleAckOpportunistically could be called nestedly when sending a
- // control frame causing another control frame to be sent.
- QUIC_BUG_IF(quic_bug_12398_18,
- GetQuicReloadableFlag(quic_single_ack_in_packet2) &&
- !frames.empty() && has_ack())
- << ENDPOINT << "Trying to flush " << quiche::PrintElements(frames)
- << " when there is ACK queued";
- for (const auto& frame : frames) {
- QUICHE_DCHECK(frame.type == ACK_FRAME || frame.type == STOP_WAITING_FRAME)
- << ENDPOINT;
- if (HasPendingFrames()) {
- if (AddFrame(frame, next_transmission_type_)) {
- // There is pending frames and current frame fits.
- continue;
- }
- }
- QUICHE_DCHECK(!HasPendingFrames()) << ENDPOINT;
- // There is no pending frames, consult the delegate whether a packet can be
- // generated.
- if (!delegate_->ShouldGeneratePacket(NO_RETRANSMITTABLE_DATA,
- NOT_HANDSHAKE)) {
- return false;
- }
- const bool success = AddFrame(frame, next_transmission_type_);
- QUIC_BUG_IF(quic_bug_10752_31, !success)
- << ENDPOINT << "Failed to flush " << frame;
- }
- return true;
-}
-
-void QuicPacketCreator::AddRandomPadding() {
- AddPendingPadding(random_->RandUint64() % kMaxNumRandomPaddingBytes + 1);
-}
-
-void QuicPacketCreator::AttachPacketFlusher() {
- flusher_attached_ = true;
- if (!write_start_packet_number_.IsInitialized()) {
- write_start_packet_number_ = NextSendingPacketNumber();
- }
-}
-
-void QuicPacketCreator::Flush() {
- FlushCurrentPacket();
- SendRemainingPendingPadding();
- flusher_attached_ = false;
- if (GetQuicFlag(FLAGS_quic_export_write_path_stats_at_server)) {
- if (!write_start_packet_number_.IsInitialized()) {
- QUIC_BUG(quic_bug_10752_32)
- << ENDPOINT << "write_start_packet_number is not initialized";
- return;
- }
- QUIC_SERVER_HISTOGRAM_COUNTS(
- "quic_server_num_written_packets_per_write",
- NextSendingPacketNumber() - write_start_packet_number_, 1, 200, 50,
- "Number of QUIC packets written per write operation");
- }
- write_start_packet_number_.Clear();
-}
-
-void QuicPacketCreator::SendRemainingPendingPadding() {
- while (
- pending_padding_bytes() > 0 && !HasPendingFrames() &&
- delegate_->ShouldGeneratePacket(NO_RETRANSMITTABLE_DATA, NOT_HANDSHAKE)) {
- FlushCurrentPacket();
- }
-}
-
-void QuicPacketCreator::SetServerConnectionIdLength(uint32_t length) {
- if (length == 0) {
- SetServerConnectionIdIncluded(CONNECTION_ID_ABSENT);
- } else {
- SetServerConnectionIdIncluded(CONNECTION_ID_PRESENT);
- }
-}
-
-void QuicPacketCreator::SetTransmissionType(TransmissionType type) {
- next_transmission_type_ = type;
-}
-
-MessageStatus QuicPacketCreator::AddMessageFrame(
- QuicMessageId message_id, absl::Span<QuicMemSlice> message) {
- QUIC_BUG_IF(quic_bug_10752_33, !flusher_attached_)
- << ENDPOINT
- << "Packet flusher is not attached when "
- "generator tries to add message frame.";
- MaybeBundleAckOpportunistically();
- const QuicByteCount message_length = MemSliceSpanTotalSize(message);
- if (message_length > GetCurrentLargestMessagePayload()) {
- return MESSAGE_STATUS_TOO_LARGE;
- }
- if (!HasRoomForMessageFrame(message_length)) {
- FlushCurrentPacket();
- }
- QuicMessageFrame* frame = new QuicMessageFrame(message_id, message);
- const bool success = AddFrame(QuicFrame(frame), next_transmission_type_);
- if (!success) {
- QUIC_BUG(quic_bug_10752_34)
- << ENDPOINT << "Failed to send message " << message_id;
- delete frame;
- return MESSAGE_STATUS_INTERNAL_ERROR;
- }
- QUICHE_DCHECK_EQ(MemSliceSpanTotalSize(message),
- 0u); // Ensure the old slices are empty.
- return MESSAGE_STATUS_SUCCESS;
-}
-
-QuicVariableLengthIntegerLength QuicPacketCreator::GetLengthLength() const {
- if (QuicVersionHasLongHeaderLengths(framer_->transport_version()) &&
- HasIetfLongHeader()) {
- QuicLongHeaderType long_header_type =
- EncryptionlevelToLongHeaderType(packet_.encryption_level);
- if (long_header_type == INITIAL || long_header_type == ZERO_RTT_PROTECTED ||
- long_header_type == HANDSHAKE) {
- return VARIABLE_LENGTH_INTEGER_LENGTH_2;
- }
- }
- return VARIABLE_LENGTH_INTEGER_LENGTH_0;
-}
-
-void QuicPacketCreator::FillPacketHeader(QuicPacketHeader* header) {
- header->destination_connection_id = GetDestinationConnectionId();
- header->destination_connection_id_included =
- GetDestinationConnectionIdIncluded();
- header->source_connection_id = GetSourceConnectionId();
- header->source_connection_id_included = GetSourceConnectionIdIncluded();
- header->reset_flag = false;
- header->version_flag = IncludeVersionInHeader();
- if (IncludeNonceInPublicHeader()) {
- QUICHE_DCHECK_EQ(Perspective::IS_SERVER, framer_->perspective())
- << ENDPOINT;
- header->nonce = &diversification_nonce_;
- } else {
- header->nonce = nullptr;
- }
- packet_.packet_number = NextSendingPacketNumber();
- header->packet_number = packet_.packet_number;
- header->packet_number_length = GetPacketNumberLength();
- header->retry_token_length_length = GetRetryTokenLengthLength();
- header->retry_token = GetRetryToken();
- header->length_length = GetLengthLength();
- header->remaining_packet_length = 0;
- if (!HasIetfLongHeader()) {
- return;
- }
- header->long_packet_type =
- EncryptionlevelToLongHeaderType(packet_.encryption_level);
-}
-
-size_t QuicPacketCreator::GetSerializedFrameLength(const QuicFrame& frame) {
- size_t serialized_frame_length = framer_->GetSerializedFrameLength(
- frame, BytesFree(), queued_frames_.empty(),
- /* last_frame_in_packet= */ true, GetPacketNumberLength());
- if (!framer_->version().HasHeaderProtection() ||
- serialized_frame_length == 0) {
- return serialized_frame_length;
- }
- // Calculate frame bytes and bytes free with this frame added.
- const size_t frame_bytes = PacketSize() - PacketHeaderSize() +
- ExpansionOnNewFrame() + serialized_frame_length;
- if (frame_bytes >= MinPlaintextPacketSize(framer_->version())) {
- // No extra bytes is needed.
- return serialized_frame_length;
- }
- if (BytesFree() < serialized_frame_length) {
- QUIC_BUG(quic_bug_10752_35) << ENDPOINT << "Frame does not fit: " << frame;
- return 0;
- }
- // Please note bytes_free does not take |frame|'s expansion into account.
- size_t bytes_free = BytesFree() - serialized_frame_length;
- // Extra bytes needed (this is NOT padding needed) should be at least 1
- // padding + expansion.
- const size_t extra_bytes_needed = std::max(
- 1 + ExpansionOnNewFrameWithLastFrame(frame, framer_->transport_version()),
- MinPlaintextPacketSize(framer_->version()) - frame_bytes);
- if (bytes_free < extra_bytes_needed) {
- // This frame does not fit.
- return 0;
- }
- return serialized_frame_length;
-}
-
-bool QuicPacketCreator::AddFrame(const QuicFrame& frame,
- TransmissionType transmission_type) {
- QUIC_DVLOG(1) << ENDPOINT << "Adding frame with transmission type "
- << transmission_type << ": " << frame;
- if (frame.type == STREAM_FRAME &&
- !QuicUtils::IsCryptoStreamId(framer_->transport_version(),
- frame.stream_frame.stream_id) &&
- AttemptingToSendUnencryptedStreamData()) {
- return false;
- }
-
- // Sanity check to ensure we don't send frames at the wrong encryption level.
- QUICHE_DCHECK(
- packet_.encryption_level == ENCRYPTION_ZERO_RTT ||
- packet_.encryption_level == ENCRYPTION_FORWARD_SECURE ||
- (frame.type != GOAWAY_FRAME && frame.type != WINDOW_UPDATE_FRAME &&
- frame.type != HANDSHAKE_DONE_FRAME &&
- frame.type != NEW_CONNECTION_ID_FRAME &&
- frame.type != MAX_STREAMS_FRAME && frame.type != STREAMS_BLOCKED_FRAME &&
- frame.type != PATH_RESPONSE_FRAME &&
- frame.type != PATH_CHALLENGE_FRAME && frame.type != STOP_SENDING_FRAME &&
- frame.type != MESSAGE_FRAME && frame.type != NEW_TOKEN_FRAME &&
- frame.type != RETIRE_CONNECTION_ID_FRAME &&
- frame.type != ACK_FREQUENCY_FRAME))
- << ENDPOINT << frame.type << " not allowed at "
- << packet_.encryption_level;
-
- if (frame.type == STREAM_FRAME) {
- if (MaybeCoalesceStreamFrame(frame.stream_frame)) {
- LogCoalesceStreamFrameStatus(true);
- return true;
- } else {
- LogCoalesceStreamFrameStatus(false);
- }
- }
-
- // If this is an ACK frame, validate that it is non-empty and that
- // largest_acked matches the max packet number.
- QUICHE_DCHECK(frame.type != ACK_FRAME || (!frame.ack_frame->packets.Empty() &&
- frame.ack_frame->packets.Max() ==
- frame.ack_frame->largest_acked))
- << ENDPOINT << "Invalid ACK frame: " << frame;
-
- size_t frame_len = GetSerializedFrameLength(frame);
- if (frame_len == 0 && RemoveSoftMaxPacketLength()) {
- // Remove soft max_packet_length and retry.
- frame_len = GetSerializedFrameLength(frame);
- }
- if (frame_len == 0) {
- QUIC_DVLOG(1) << ENDPOINT
- << "Flushing because current open packet is full when adding "
- << frame;
- FlushCurrentPacket();
- return false;
- }
- if (queued_frames_.empty()) {
- packet_size_ = PacketHeaderSize();
- }
- QUICHE_DCHECK_LT(0u, packet_size_) << ENDPOINT;
-
- packet_size_ += ExpansionOnNewFrame() + frame_len;
-
- if (QuicUtils::IsRetransmittableFrame(frame.type)) {
- packet_.retransmittable_frames.push_back(frame);
- queued_frames_.push_back(frame);
- if (QuicUtils::IsHandshakeFrame(frame, framer_->transport_version())) {
- packet_.has_crypto_handshake = IS_HANDSHAKE;
- }
- } else {
- if (frame.type == PADDING_FRAME &&
- frame.padding_frame.num_padding_bytes == -1) {
- // Populate the actual length of full padding frame, such that one can
- // know how much padding is actually added.
- packet_.nonretransmittable_frames.push_back(
- QuicFrame(QuicPaddingFrame(frame_len)));
- } else {
- packet_.nonretransmittable_frames.push_back(frame);
- }
- queued_frames_.push_back(frame);
- }
-
- if (frame.type == ACK_FRAME) {
- packet_.has_ack = true;
- packet_.largest_acked = LargestAcked(*frame.ack_frame);
- } else if (frame.type == STOP_WAITING_FRAME) {
- packet_.has_stop_waiting = true;
- } else if (frame.type == ACK_FREQUENCY_FRAME) {
- packet_.has_ack_frequency = true;
- } else if (frame.type == MESSAGE_FRAME) {
- packet_.has_message = true;
- }
- if (debug_delegate_ != nullptr) {
- debug_delegate_->OnFrameAddedToPacket(frame);
- }
-
- // Packet transmission type is determined by the last added retransmittable
- // frame.
- if (QuicUtils::IsRetransmittableFrame(frame.type)) {
- packet_.transmission_type = transmission_type;
- }
- return true;
-}
-
-void QuicPacketCreator::MaybeAddExtraPaddingForHeaderProtection() {
- if (!framer_->version().HasHeaderProtection() || needs_full_padding_) {
- return;
- }
- const size_t frame_bytes = PacketSize() - PacketHeaderSize();
- if (frame_bytes >= MinPlaintextPacketSize(framer_->version())) {
- return;
- }
- const QuicByteCount min_header_protection_padding =
- std::max(1 + ExpansionOnNewFrame(),
- MinPlaintextPacketSize(framer_->version()) - frame_bytes) -
- ExpansionOnNewFrame();
- // Update pending_padding_bytes_.
- pending_padding_bytes_ =
- std::max(pending_padding_bytes_, min_header_protection_padding);
-}
-
-bool QuicPacketCreator::MaybeCoalesceStreamFrame(const QuicStreamFrame& frame) {
- if (queued_frames_.empty() || queued_frames_.back().type != STREAM_FRAME) {
- return false;
- }
- QuicStreamFrame* candidate = &queued_frames_.back().stream_frame;
- if (candidate->stream_id != frame.stream_id ||
- candidate->offset + candidate->data_length != frame.offset ||
- frame.data_length > BytesFree()) {
- return false;
- }
- candidate->data_length += frame.data_length;
- candidate->fin = frame.fin;
-
- // The back of retransmittable frames must be the same as the original
- // queued frames' back.
- QUICHE_DCHECK_EQ(packet_.retransmittable_frames.back().type, STREAM_FRAME)
- << ENDPOINT;
- QuicStreamFrame* retransmittable =
- &packet_.retransmittable_frames.back().stream_frame;
- QUICHE_DCHECK_EQ(retransmittable->stream_id, frame.stream_id) << ENDPOINT;
- QUICHE_DCHECK_EQ(retransmittable->offset + retransmittable->data_length,
- frame.offset)
- << ENDPOINT;
- retransmittable->data_length = candidate->data_length;
- retransmittable->fin = candidate->fin;
- packet_size_ += frame.data_length;
- if (debug_delegate_ != nullptr) {
- debug_delegate_->OnStreamFrameCoalesced(*candidate);
- }
- return true;
-}
-
-bool QuicPacketCreator::RemoveSoftMaxPacketLength() {
- if (latched_hard_max_packet_length_ == 0) {
- return false;
- }
- if (!CanSetMaxPacketLength()) {
- return false;
- }
- QUIC_DVLOG(1) << ENDPOINT << "Restoring max packet length to: "
- << latched_hard_max_packet_length_;
- SetMaxPacketLength(latched_hard_max_packet_length_);
- // Reset latched_max_packet_length_.
- latched_hard_max_packet_length_ = 0;
- return true;
-}
-
-void QuicPacketCreator::MaybeAddPadding() {
- // The current packet should have no padding bytes because padding is only
- // added when this method is called just before the packet is serialized.
- if (BytesFree() == 0) {
- // Don't pad full packets.
- 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.
- needs_full_padding_ = false;
- }
-
- // Header protection requires a minimum plaintext packet size.
- MaybeAddExtraPaddingForHeaderProtection();
-
- if (!needs_full_padding_ && pending_padding_bytes_ == 0) {
- // Do not need padding.
- return;
- }
-
- int padding_bytes = -1;
- if (!needs_full_padding_) {
- padding_bytes = std::min<int16_t>(pending_padding_bytes_, BytesFree());
- pending_padding_bytes_ -= padding_bytes;
- }
-
- bool success = AddFrame(QuicFrame(QuicPaddingFrame(padding_bytes)),
- packet_.transmission_type);
- QUIC_BUG_IF(quic_bug_10752_36, !success)
- << ENDPOINT << "Failed to add padding_bytes: " << padding_bytes
- << " transmission_type: " << packet_.transmission_type;
-}
-
-bool QuicPacketCreator::IncludeNonceInPublicHeader() const {
- return have_diversification_nonce_ &&
- packet_.encryption_level == ENCRYPTION_ZERO_RTT;
-}
-
-bool QuicPacketCreator::IncludeVersionInHeader() const {
- if (version().HasIetfInvariantHeader()) {
- return packet_.encryption_level < ENCRYPTION_FORWARD_SECURE;
- }
- return send_version_in_packet_;
-}
-
-void QuicPacketCreator::AddPendingPadding(QuicByteCount size) {
- pending_padding_bytes_ += size;
-}
-
-bool QuicPacketCreator::StreamFrameIsClientHello(
- const QuicStreamFrame& frame) const {
- if (framer_->perspective() == Perspective::IS_SERVER ||
- !QuicUtils::IsCryptoStreamId(framer_->transport_version(),
- frame.stream_id)) {
- return false;
- }
- // The ClientHello is always sent with INITIAL encryption.
- return packet_.encryption_level == ENCRYPTION_INITIAL;
-}
-
-void QuicPacketCreator::SetServerConnectionIdIncluded(
- QuicConnectionIdIncluded server_connection_id_included) {
- QUICHE_DCHECK(server_connection_id_included == CONNECTION_ID_PRESENT ||
- server_connection_id_included == CONNECTION_ID_ABSENT)
- << ENDPOINT;
- QUICHE_DCHECK(framer_->perspective() == Perspective::IS_SERVER ||
- server_connection_id_included != CONNECTION_ID_ABSENT)
- << ENDPOINT;
- server_connection_id_included_ = server_connection_id_included;
-}
-
-void QuicPacketCreator::SetServerConnectionId(
- QuicConnectionId server_connection_id) {
- server_connection_id_ = server_connection_id;
-}
-
-void QuicPacketCreator::SetClientConnectionId(
- QuicConnectionId client_connection_id) {
- QUICHE_DCHECK(client_connection_id.IsEmpty() ||
- framer_->version().SupportsClientConnectionIds())
- << ENDPOINT;
- client_connection_id_ = client_connection_id;
-}
-
-QuicPacketLength QuicPacketCreator::GetCurrentLargestMessagePayload() const {
- if (!VersionSupportsMessageFrames(framer_->transport_version())) {
- return 0;
- }
- const size_t packet_header_size = GetPacketHeaderSize(
- framer_->transport_version(), GetDestinationConnectionIdLength(),
- GetSourceConnectionIdLength(), IncludeVersionInHeader(),
- IncludeNonceInPublicHeader(), GetPacketNumberLength(),
- // No Retry token on packets containing application data.
- VARIABLE_LENGTH_INTEGER_LENGTH_0, 0, GetLengthLength());
- // This is the largest possible message payload when the length field is
- // omitted.
- size_t max_plaintext_size =
- latched_hard_max_packet_length_ == 0
- ? max_plaintext_size_
- : framer_->GetMaxPlaintextSize(latched_hard_max_packet_length_);
- size_t largest_frame =
- max_plaintext_size - std::min(max_plaintext_size, packet_header_size);
- if (static_cast<QuicByteCount>(largest_frame) > max_datagram_frame_size_) {
- largest_frame = static_cast<size_t>(max_datagram_frame_size_);
- }
- return largest_frame - std::min(largest_frame, kQuicFrameTypeSize);
-}
-
-QuicPacketLength QuicPacketCreator::GetGuaranteedLargestMessagePayload() const {
- if (!VersionSupportsMessageFrames(framer_->transport_version())) {
- return 0;
- }
- // QUIC Crypto server packets may include a diversification nonce.
- const bool may_include_nonce =
- framer_->version().handshake_protocol == PROTOCOL_QUIC_CRYPTO &&
- framer_->perspective() == Perspective::IS_SERVER;
- // IETF QUIC long headers include a length on client 0RTT packets.
- QuicVariableLengthIntegerLength length_length =
- VARIABLE_LENGTH_INTEGER_LENGTH_0;
- if (framer_->perspective() == Perspective::IS_CLIENT) {
- length_length = VARIABLE_LENGTH_INTEGER_LENGTH_2;
- }
- if (!QuicVersionHasLongHeaderLengths(framer_->transport_version())) {
- length_length = VARIABLE_LENGTH_INTEGER_LENGTH_0;
- }
- const size_t packet_header_size = GetPacketHeaderSize(
- framer_->transport_version(), GetDestinationConnectionIdLength(),
- // Assume CID lengths don't change, but version may be present.
- GetSourceConnectionIdLength(), kIncludeVersion, may_include_nonce,
- PACKET_4BYTE_PACKET_NUMBER,
- // No Retry token on packets containing application data.
- VARIABLE_LENGTH_INTEGER_LENGTH_0, 0, length_length);
- // This is the largest possible message payload when the length field is
- // omitted.
- size_t max_plaintext_size =
- latched_hard_max_packet_length_ == 0
- ? max_plaintext_size_
- : framer_->GetMaxPlaintextSize(latched_hard_max_packet_length_);
- size_t largest_frame =
- max_plaintext_size - std::min(max_plaintext_size, packet_header_size);
- if (static_cast<QuicByteCount>(largest_frame) > max_datagram_frame_size_) {
- largest_frame = static_cast<size_t>(max_datagram_frame_size_);
- }
- const QuicPacketLength largest_payload =
- largest_frame - std::min(largest_frame, kQuicFrameTypeSize);
- // This must always be less than or equal to GetCurrentLargestMessagePayload.
- QUICHE_DCHECK_LE(largest_payload, GetCurrentLargestMessagePayload())
- << ENDPOINT;
- return largest_payload;
-}
-
-bool QuicPacketCreator::AttemptingToSendUnencryptedStreamData() {
- if (packet_.encryption_level == ENCRYPTION_ZERO_RTT ||
- packet_.encryption_level == ENCRYPTION_FORWARD_SECURE) {
- return false;
- }
- const std::string error_details =
- absl::StrCat("Cannot send stream data with level: ",
- EncryptionLevelToString(packet_.encryption_level));
- QUIC_BUG(quic_bug_10752_37) << ENDPOINT << error_details;
- delegate_->OnUnrecoverableError(QUIC_ATTEMPT_TO_SEND_UNENCRYPTED_STREAM_DATA,
- error_details);
- return true;
-}
-
-bool QuicPacketCreator::HasIetfLongHeader() const {
- return version().HasIetfInvariantHeader() &&
- packet_.encryption_level < ENCRYPTION_FORWARD_SECURE;
-}
-
-// static
-size_t QuicPacketCreator::MinPlaintextPacketSize(
- const ParsedQuicVersion& version) {
- if (!version.HasHeaderProtection()) {
- return 0;
- }
- // Header protection samples 16 bytes of ciphertext starting 4 bytes after the
- // packet number. In IETF QUIC, all AEAD algorithms have a 16-byte auth tag
- // (i.e. the ciphertext is 16 bytes larger than the plaintext). Since packet
- // numbers could be as small as 1 byte, but the sample starts 4 bytes after
- // the packet number, at least 3 bytes of plaintext are needed to make sure
- // that there is enough ciphertext to sample.
- //
- // Google QUIC crypto uses different AEAD algorithms - in particular the auth
- // tags are only 12 bytes instead of 16 bytes. Since the auth tag is 4 bytes
- // shorter, 4 more bytes of plaintext are needed to guarantee there is enough
- // ciphertext to sample.
- //
- // This method could check for PROTOCOL_TLS1_3 vs PROTOCOL_QUIC_CRYPTO and
- // return 3 when TLS 1.3 is in use (the use of IETF vs Google QUIC crypters is
- // determined based on the handshake protocol used). However, even when TLS
- // 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.
- return 7;
-}
-
-QuicPacketNumber QuicPacketCreator::NextSendingPacketNumber() const {
- if (!packet_number().IsInitialized()) {
- return framer_->first_sending_packet_number();
- }
- return packet_number() + 1;
-}
-
-bool QuicPacketCreator::PacketFlusherAttached() const {
- return flusher_attached_;
-}
-
-bool QuicPacketCreator::HasSoftMaxPacketLength() const {
- return latched_hard_max_packet_length_ != 0;
-}
-
-void QuicPacketCreator::SetDefaultPeerAddress(QuicSocketAddress address) {
- if (!packet_.peer_address.IsInitialized()) {
- packet_.peer_address = address;
- return;
- }
- if (packet_.peer_address != address) {
- FlushCurrentPacket();
- packet_.peer_address = address;
- }
-}
-
-#define ENDPOINT2 \
- (creator_->framer_->perspective() == Perspective::IS_SERVER ? "Server: " \
- : "Client: ")
-
-QuicPacketCreator::ScopedPeerAddressContext::ScopedPeerAddressContext(
- QuicPacketCreator* creator,
- QuicSocketAddress address,
- bool update_connection_id)
- : ScopedPeerAddressContext(creator,
- address,
- EmptyQuicConnectionId(),
- EmptyQuicConnectionId(),
- update_connection_id) {}
-
-QuicPacketCreator::ScopedPeerAddressContext::ScopedPeerAddressContext(
- QuicPacketCreator* creator,
- QuicSocketAddress address,
- const QuicConnectionId& client_connection_id,
- const QuicConnectionId& server_connection_id,
- bool update_connection_id)
- : creator_(creator),
- old_peer_address_(creator_->packet_.peer_address),
- old_client_connection_id_(creator_->GetClientConnectionId()),
- old_server_connection_id_(creator_->GetServerConnectionId()),
- update_connection_id_(update_connection_id) {
- QUIC_BUG_IF(quic_bug_12398_19, !old_peer_address_.IsInitialized())
- << ENDPOINT2
- << "Context is used before serialized packet's peer address is "
- "initialized.";
- creator_->SetDefaultPeerAddress(address);
- if (update_connection_id_) {
- // Flush current packet if connection ID length changes.
- if (address == old_peer_address_ &&
- ((client_connection_id.length() !=
- old_client_connection_id_.length()) ||
- (server_connection_id.length() !=
- old_server_connection_id_.length()))) {
- creator_->FlushCurrentPacket();
- }
- creator_->SetClientConnectionId(client_connection_id);
- creator_->SetServerConnectionId(server_connection_id);
- }
-}
-
-QuicPacketCreator::ScopedPeerAddressContext::~ScopedPeerAddressContext() {
- creator_->SetDefaultPeerAddress(old_peer_address_);
- if (update_connection_id_) {
- creator_->SetClientConnectionId(old_client_connection_id_);
- creator_->SetServerConnectionId(old_server_connection_id_);
- }
-}
-
-QuicPacketCreator::ScopedSerializationFailureHandler::
- ScopedSerializationFailureHandler(QuicPacketCreator* creator)
- : creator_(creator) {}
-
-QuicPacketCreator::ScopedSerializationFailureHandler::
- ~ScopedSerializationFailureHandler() {
- if (creator_ == nullptr) {
- return;
- }
- // Always clear queued_frames_.
- creator_->queued_frames_.clear();
-
- if (creator_->packet_.encrypted_buffer == nullptr) {
- const std::string error_details = "Failed to SerializePacket.";
- QUIC_BUG(quic_bug_10752_38) << ENDPOINT2 << error_details;
- creator_->delegate_->OnUnrecoverableError(QUIC_FAILED_TO_SERIALIZE_PACKET,
- error_details);
- }
-}
-
-#undef ENDPOINT2
-
-void QuicPacketCreator::set_encryption_level(EncryptionLevel level) {
- QUICHE_DCHECK(level == packet_.encryption_level || !HasPendingFrames())
- << ENDPOINT << "Cannot update encryption level from "
- << packet_.encryption_level << " to " << level
- << " when we already have pending frames: "
- << QuicFramesToString(queued_frames_);
- packet_.encryption_level = level;
-}
-
-void QuicPacketCreator::AddPathChallengeFrame(
- const QuicPathFrameBuffer& payload) {
- // TODO(danzh) Unify similar checks at several entry points into one in
- // AddFrame(). Sort out test helper functions and peer class that don't
- // enforce this check.
- QUIC_BUG_IF(quic_bug_10752_39, !flusher_attached_)
- << ENDPOINT
- << "Packet flusher is not attached when "
- "generator tries to write stream data.";
- // Write a PATH_CHALLENGE frame, which has a random 8-byte payload.
- auto path_challenge_frame = new QuicPathChallengeFrame(0, payload);
- QuicFrame frame(path_challenge_frame);
- if (AddPaddedFrameWithRetry(frame)) {
- return;
- }
- // Fail silently if the probing packet cannot be written, path validation
- // initiator will retry sending automatically.
- // TODO(danzh) This will consume retry budget, if it causes performance
- // regression, consider to notify the caller about the sending failure and let
- // the caller to decide if it worth retrying.
- QUIC_DVLOG(1) << ENDPOINT << "Can't send PATH_CHALLENGE now";
- delete path_challenge_frame;
-}
-
-bool QuicPacketCreator::AddPathResponseFrame(
- const QuicPathFrameBuffer& data_buffer) {
- auto path_response =
- new QuicPathResponseFrame(kInvalidControlFrameId, data_buffer);
- QuicFrame frame(path_response);
- if (AddPaddedFrameWithRetry(frame)) {
- return true;
- }
-
- QUIC_DVLOG(1) << ENDPOINT << "Can't send PATH_RESPONSE now";
- QUIC_RELOADABLE_FLAG_COUNT_N(quic_send_path_response2, 5, 5);
- delete path_response;
- return false;
-}
-
-bool QuicPacketCreator::AddPaddedFrameWithRetry(const QuicFrame& frame) {
- if (HasPendingFrames()) {
- if (AddPaddedSavedFrame(frame, NOT_RETRANSMISSION)) {
- // Frame is queued.
- return true;
- }
- }
- // Frame was not queued but queued frames were flushed.
- QUICHE_DCHECK(!HasPendingFrames()) << ENDPOINT;
- if (!delegate_->ShouldGeneratePacket(NO_RETRANSMITTABLE_DATA,
- NOT_HANDSHAKE)) {
- return false;
- }
- bool success = AddPaddedSavedFrame(frame, NOT_RETRANSMISSION);
- QUIC_BUG_IF(quic_bug_12398_20, !success) << ENDPOINT;
- return true;
-}
-
-bool QuicPacketCreator::HasRetryToken() const {
- return !retry_token_.empty();
-}
-
-#undef ENDPOINT // undef for jumbo builds
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_packet_creator.h b/chromium/net/third_party/quiche/src/quic/core/quic_packet_creator.h
deleted file mode 100644
index 9cc4bcae92e..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_packet_creator.h
+++ /dev/null
@@ -1,719 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Responsible for creating packets on behalf of a QuicConnection.
-// Packets are serialized just-in-time. Stream data and control frames will be
-// requested from the Connection just-in-time. Frames are accumulated into
-// "current" packet until no more frames can fit, then current packet gets
-// serialized and passed to connection via OnSerializedPacket().
-//
-// Whether a packet should be serialized is determined by whether delegate is
-// writable. If the Delegate is not writable, then no operations will cause
-// a packet to be serialized.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_PACKET_CREATOR_H_
-#define QUICHE_QUIC_CORE_QUIC_PACKET_CREATOR_H_
-
-#include <cstddef>
-#include <memory>
-#include <utility>
-#include <vector>
-
-#include "absl/base/attributes.h"
-#include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
-#include "quic/core/frames/quic_stream_frame.h"
-#include "quic/core/quic_coalesced_packet.h"
-#include "quic/core/quic_connection_id.h"
-#include "quic/core/quic_framer.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_export.h"
-#include "common/quiche_circular_deque.h"
-
-namespace quic {
-namespace test {
-class QuicPacketCreatorPeer;
-}
-
-class QUIC_EXPORT_PRIVATE QuicPacketCreator {
- public:
- // A delegate interface for further processing serialized packet.
- class QUIC_EXPORT_PRIVATE DelegateInterface {
- public:
- virtual ~DelegateInterface() {}
- // Get a buffer of kMaxOutgoingPacketSize bytes to serialize the next
- // packet. If the return value's buffer is nullptr, QuicPacketCreator will
- // serialize on a stack buffer.
- virtual QuicPacketBuffer GetPacketBuffer() = 0;
- // Called when a packet is serialized. Delegate take the ownership of
- // |serialized_packet|.
- virtual void OnSerializedPacket(SerializedPacket serialized_packet) = 0;
-
- // Called when an unrecoverable error is encountered.
- virtual void OnUnrecoverableError(QuicErrorCode error,
- const std::string& error_details) = 0;
-
- // Consults delegate whether a packet should be generated.
- virtual bool ShouldGeneratePacket(HasRetransmittableData retransmittable,
- IsHandshake handshake) = 0;
- // Called when there is data to be sent. Retrieves updated ACK frame from
- // the delegate.
- virtual const QuicFrames MaybeBundleAckOpportunistically() = 0;
-
- // Returns the packet fate for serialized packets which will be handed over
- // to delegate via OnSerializedPacket(). Called when a packet is about to be
- // serialized.
- virtual SerializedPacketFate GetSerializedPacketFate(
- bool is_mtu_discovery,
- EncryptionLevel encryption_level) = 0;
- };
-
- // Interface which gets callbacks from the QuicPacketCreator at interesting
- // points. Implementations must not mutate the state of the creator
- // as a result of these callbacks.
- class QUIC_EXPORT_PRIVATE DebugDelegate {
- public:
- virtual ~DebugDelegate() {}
-
- // Called when a frame has been added to the current packet.
- virtual void OnFrameAddedToPacket(const QuicFrame& /*frame*/) {}
-
- // Called when a stream frame is coalesced with an existing stream frame.
- // |frame| is the new stream frame.
- virtual void OnStreamFrameCoalesced(const QuicStreamFrame& /*frame*/) {}
- };
-
- // Set the peer address and connection IDs with which the serialized packet
- // will be sent to during the scope of this object. Upon exiting the scope,
- // the original peer address and connection IDs are restored.
- class QUIC_EXPORT_PRIVATE ScopedPeerAddressContext {
- public:
- ScopedPeerAddressContext(QuicPacketCreator* creator,
- QuicSocketAddress address,
- bool update_connection_id);
-
- ScopedPeerAddressContext(QuicPacketCreator* creator,
- QuicSocketAddress address,
- const QuicConnectionId& client_connection_id,
- const QuicConnectionId& server_connection_id,
- bool update_connection_id);
- ~ScopedPeerAddressContext();
-
- private:
- QuicPacketCreator* creator_;
- QuicSocketAddress old_peer_address_;
- QuicConnectionId old_client_connection_id_;
- QuicConnectionId old_server_connection_id_;
- bool update_connection_id_;
- };
-
- QuicPacketCreator(QuicConnectionId server_connection_id,
- QuicFramer* framer,
- DelegateInterface* delegate);
- QuicPacketCreator(QuicConnectionId server_connection_id,
- QuicFramer* framer,
- QuicRandom* random,
- DelegateInterface* delegate);
- QuicPacketCreator(const QuicPacketCreator&) = delete;
- QuicPacketCreator& operator=(const QuicPacketCreator&) = delete;
-
- ~QuicPacketCreator();
-
- // Makes the framer not serialize the protocol version in sent packets.
- void StopSendingVersion();
-
- // SetDiversificationNonce sets the nonce that will be sent in each public
- // header of packets encrypted at the initial encryption level. Should only
- // be called by servers.
- void SetDiversificationNonce(const DiversificationNonce& nonce);
-
- // Update the packet number length to use in future packets as soon as it
- // can be safely changed.
- // TODO(fayang): Directly set packet number length instead of compute it in
- // creator.
- void UpdatePacketNumberLength(QuicPacketNumber least_packet_awaited_by_peer,
- QuicPacketCount max_packets_in_flight);
-
- // Skip |count| packet numbers.
- void SkipNPacketNumbers(QuicPacketCount count,
- QuicPacketNumber least_packet_awaited_by_peer,
- QuicPacketCount max_packets_in_flight);
-
- // The overhead the framing will add for a packet with one frame.
- static size_t StreamFramePacketOverhead(
- QuicTransportVersion version,
- QuicConnectionIdLength destination_connection_id_length,
- QuicConnectionIdLength source_connection_id_length,
- bool include_version,
- bool include_diversification_nonce,
- QuicPacketNumberLength packet_number_length,
- QuicVariableLengthIntegerLength retry_token_length_length,
- QuicVariableLengthIntegerLength length_length,
- QuicStreamOffset offset);
-
- // Returns false and flushes all pending frames if current open packet is
- // full.
- // If current packet is not full, creates a stream frame that fits into the
- // open packet and adds it to the packet.
- bool ConsumeDataToFillCurrentPacket(QuicStreamId id,
- size_t data_size,
- QuicStreamOffset offset,
- bool fin,
- bool needs_full_padding,
- TransmissionType transmission_type,
- QuicFrame* frame);
-
- // Creates a CRYPTO frame that fits into the current packet (which must be
- // empty) and adds it to the packet.
- bool ConsumeCryptoDataToFillCurrentPacket(EncryptionLevel level,
- size_t write_length,
- QuicStreamOffset offset,
- bool needs_full_padding,
- TransmissionType transmission_type,
- QuicFrame* frame);
-
- // Returns true if current open packet can accommodate more stream frames of
- // stream |id| at |offset| and data length |data_size|, false otherwise.
- // TODO(fayang): mark this const by moving RemoveSoftMaxPacketLength out.
- bool HasRoomForStreamFrame(QuicStreamId id,
- QuicStreamOffset offset,
- size_t data_size);
-
- // Returns true if current open packet can accommodate a message frame of
- // |length|.
- // TODO(fayang): mark this const by moving RemoveSoftMaxPacketLength out.
- bool HasRoomForMessageFrame(QuicByteCount length);
-
- // Serializes all added frames into a single packet and invokes the delegate_
- // to further process the SerializedPacket.
- void FlushCurrentPacket();
-
- // Optimized method to create a QuicStreamFrame and serialize it. Adds the
- // QuicStreamFrame to the returned SerializedPacket. Sets
- // |num_bytes_consumed| to the number of bytes consumed to create the
- // QuicStreamFrame.
- void CreateAndSerializeStreamFrame(QuicStreamId id,
- size_t write_length,
- QuicStreamOffset iov_offset,
- QuicStreamOffset stream_offset,
- bool fin,
- TransmissionType transmission_type,
- size_t* num_bytes_consumed);
-
- // Returns true if there are frames pending to be serialized.
- bool HasPendingFrames() const;
-
- // TODO(haoyuewang) Remove this debug utility.
- // Returns the information of pending frames as a string.
- std::string GetPendingFramesInfo() const;
-
- // Returns true if there are retransmittable frames pending to be serialized.
- bool HasPendingRetransmittableFrames() const;
-
- // Returns true if there are stream frames for |id| pending to be serialized.
- bool HasPendingStreamFramesOfStream(QuicStreamId id) const;
-
- // Returns the number of bytes which are available to be used by additional
- // frames in the packet. Since stream frames are slightly smaller when they
- // are the last frame in a packet, this method will return a different
- // value than max_packet_size - PacketSize(), in this case.
- size_t BytesFree() const;
-
- // Returns the number of bytes that the packet will expand by if a new frame
- // is added to the packet. If the last frame was a stream frame, it will
- // expand slightly when a new frame is added, and this method returns the
- // amount of expected expansion.
- size_t ExpansionOnNewFrame() const;
-
- // Returns the number of bytes that the packet will expand by when a new frame
- // is going to be added. |last_frame| is the last frame of the packet.
- static size_t ExpansionOnNewFrameWithLastFrame(const QuicFrame& last_frame,
- QuicTransportVersion version);
-
- // Returns the number of bytes in the current packet, including the header,
- // if serialized with the current frames. Adding a frame to the packet
- // may change the serialized length of existing frames, as per the comment
- // in BytesFree.
- size_t PacketSize() const;
-
- // Tries to add |frame| to the packet creator's list of frames to be
- // serialized. If the frame does not fit into the current packet, flushes the
- // packet and returns false.
- bool AddFrame(const QuicFrame& frame, TransmissionType transmission_type);
-
- // Identical to AddSavedFrame, but allows the frame to be padded.
- bool AddPaddedSavedFrame(const QuicFrame& frame,
- TransmissionType transmission_type);
-
- // Creates a connectivity probing packet for versions prior to version 99.
- std::unique_ptr<SerializedPacket> SerializeConnectivityProbingPacket();
-
- // Create connectivity probing request and response packets using PATH
- // CHALLENGE and PATH RESPONSE frames, respectively, for version 99/IETF QUIC.
- // SerializePathChallengeConnectivityProbingPacket will pad the packet to be
- // MTU bytes long.
- std::unique_ptr<SerializedPacket>
- SerializePathChallengeConnectivityProbingPacket(
- const QuicPathFrameBuffer& payload);
-
- // If |is_padded| is true then SerializePathResponseConnectivityProbingPacket
- // will pad the packet to be MTU bytes long, else it will not pad the packet.
- // |payloads| is cleared.
- std::unique_ptr<SerializedPacket>
- SerializePathResponseConnectivityProbingPacket(
- const quiche::QuicheCircularDeque<QuicPathFrameBuffer>& payloads,
- const bool is_padded);
-
- // Add PATH_RESPONSE to current packet, flush before or afterwards if needed.
- bool AddPathResponseFrame(const QuicPathFrameBuffer& data_buffer);
-
- // Add PATH_CHALLENGE to current packet, flush before or afterwards if needed.
- // This is a best effort adding. It may fail becasue of delegate state, but
- // it's okay because of path validation retry mechanism.
- void AddPathChallengeFrame(const QuicPathFrameBuffer& payload);
-
- // Returns a dummy packet that is valid but contains no useful information.
- static SerializedPacket NoPacket();
-
- // Returns the server connection ID to send over the wire.
- const QuicConnectionId& GetServerConnectionId() const {
- return server_connection_id_;
- }
-
- // Returns the client connection ID to send over the wire.
- const QuicConnectionId& GetClientConnectionId() const {
- return client_connection_id_;
- }
-
- // Returns the destination connection ID to send over the wire.
- QuicConnectionId GetDestinationConnectionId() const;
-
- // Returns the source connection ID to send over the wire.
- QuicConnectionId GetSourceConnectionId() const;
-
- // Returns length of destination connection ID to send over the wire.
- QuicConnectionIdLength GetDestinationConnectionIdLength() const;
-
- // Returns length of source connection ID to send over the wire.
- QuicConnectionIdLength GetSourceConnectionIdLength() const;
-
- // Sets whether the server connection ID should be sent over the wire.
- void SetServerConnectionIdIncluded(
- QuicConnectionIdIncluded server_connection_id_included);
-
- // Update the server connection ID used in outgoing packets.
- void SetServerConnectionId(QuicConnectionId server_connection_id);
-
- // Update the client connection ID used in outgoing packets.
- void SetClientConnectionId(QuicConnectionId client_connection_id);
-
- // Sets the encryption level that will be applied to new packets.
- void set_encryption_level(EncryptionLevel level);
- EncryptionLevel encryption_level() { return packet_.encryption_level; }
-
- // Sets whether initial packets are protected with chaos.
- void set_chaos_protection_enabled(bool chaos_protection_enabled) {
- chaos_protection_enabled_ = chaos_protection_enabled;
- }
-
- // packet number of the last created packet, or 0 if no packets have been
- // created.
- QuicPacketNumber packet_number() const { return packet_.packet_number; }
-
- QuicByteCount max_packet_length() const { return max_packet_length_; }
-
- bool has_ack() const { return packet_.has_ack; }
-
- bool has_stop_waiting() const { return packet_.has_stop_waiting; }
-
- // Sets the encrypter to use for the encryption level and updates the max
- // plaintext size.
- void SetEncrypter(EncryptionLevel level,
- std::unique_ptr<QuicEncrypter> encrypter);
-
- // Indicates whether the packet creator is in a state where it can change
- // current maximum packet length.
- bool CanSetMaxPacketLength() const;
-
- // Sets the maximum packet length.
- void SetMaxPacketLength(QuicByteCount length);
-
- // Sets the maximum DATAGRAM/MESSAGE frame size we can send.
- void SetMaxDatagramFrameSize(QuicByteCount max_datagram_frame_size);
-
- // Set a soft maximum packet length in the creator. If a packet cannot be
- // successfully created, creator will remove the soft limit and use the actual
- // max packet length.
- void SetSoftMaxPacketLength(QuicByteCount length);
-
- // Increases pending_padding_bytes by |size|. Pending padding will be sent by
- // MaybeAddPadding().
- void AddPendingPadding(QuicByteCount size);
-
- // Sets the retry token to be sent over the wire in IETF Initial packets.
- void SetRetryToken(absl::string_view retry_token);
-
- // Consumes retransmittable control |frame|. Returns true if the frame is
- // successfully consumed. Returns false otherwise.
- bool ConsumeRetransmittableControlFrame(const QuicFrame& frame);
-
- // Given some data, may consume part or all of it and pass it to the
- // packet creator to be serialized into packets. If not in batch
- // mode, these packets will also be sent during this call.
- // When |state| is FIN_AND_PADDING, random padding of size [1, 256] will be
- // added after stream frames. If current constructed packet cannot
- // accommodate, the padding will overflow to the next packet(s).
- QuicConsumedData ConsumeData(QuicStreamId id,
- size_t write_length,
- QuicStreamOffset offset,
- StreamSendingState state);
-
- // Sends as many data only packets as allowed by the send algorithm and the
- // available iov.
- // This path does not support padding, or bundling pending frames.
- // In case we access this method from ConsumeData, total_bytes_consumed
- // keeps track of how many bytes have already been consumed.
- QuicConsumedData ConsumeDataFastPath(QuicStreamId id,
- size_t write_length,
- QuicStreamOffset offset,
- bool fin,
- size_t total_bytes_consumed);
-
- // Consumes data for CRYPTO frames sent at |level| starting at |offset| for a
- // total of |write_length| bytes, and returns the number of bytes consumed.
- // The data is passed into the packet creator and serialized into one or more
- // packets.
- size_t ConsumeCryptoData(EncryptionLevel level,
- size_t write_length,
- QuicStreamOffset offset);
-
- // Generates an MTU discovery packet of specified size.
- void GenerateMtuDiscoveryPacket(QuicByteCount target_mtu);
-
- // Called when there is data to be sent, Retrieves updated ACK frame from
- // delegate_ and flushes it.
- void MaybeBundleAckOpportunistically();
-
- // Called to flush ACK and STOP_WAITING frames, returns false if the flush
- // fails.
- bool FlushAckFrame(const QuicFrames& frames);
-
- // Adds a random amount of padding (between 1 to 256 bytes).
- void AddRandomPadding();
-
- // Attaches packet flusher.
- void AttachPacketFlusher();
-
- // Flushes everything, including current open packet and pending padding.
- void Flush();
-
- // Sends remaining pending padding.
- // Pending paddings should only be sent when there is nothing else to send.
- void SendRemainingPendingPadding();
-
- // Set the minimum number of bytes for the server connection id length;
- void SetServerConnectionIdLength(uint32_t length);
-
- // Set transmission type of next constructed packets.
- void SetTransmissionType(TransmissionType type);
-
- // Tries to add a message frame containing |message| and returns the status.
- MessageStatus AddMessageFrame(QuicMessageId message_id,
- absl::Span<QuicMemSlice> message);
-
- // Returns the largest payload that will fit into a single MESSAGE frame.
- QuicPacketLength GetCurrentLargestMessagePayload() const;
- // Returns the largest payload that will fit into a single MESSAGE frame at
- // any point during the connection. This assumes the version and
- // connection ID lengths do not change.
- QuicPacketLength GetGuaranteedLargestMessagePayload() const;
-
- // Packet number of next created packet.
- QuicPacketNumber NextSendingPacketNumber() const;
-
- void set_debug_delegate(DebugDelegate* debug_delegate) {
- debug_delegate_ = debug_delegate;
- }
-
- QuicByteCount pending_padding_bytes() const { return pending_padding_bytes_; }
-
- ParsedQuicVersion version() const { return framer_->version(); }
-
- QuicTransportVersion transport_version() const {
- return framer_->transport_version();
- }
-
- // Returns the minimum size that the plaintext of a packet must be.
- static size_t MinPlaintextPacketSize(const ParsedQuicVersion& version);
-
- // Indicates whether packet flusher is currently attached.
- bool PacketFlusherAttached() const;
-
- void set_fully_pad_crypto_handshake_packets(bool new_value) {
- fully_pad_crypto_handshake_packets_ = new_value;
- }
-
- bool fully_pad_crypto_handshake_packets() const {
- return fully_pad_crypto_handshake_packets_;
- }
-
- // Serialize a probing packet that uses IETF QUIC's PATH CHALLENGE frame. Also
- // fills the packet with padding.
- size_t BuildPaddedPathChallengePacket(const QuicPacketHeader& header,
- char* buffer,
- size_t packet_length,
- const QuicPathFrameBuffer& payload,
- EncryptionLevel level);
-
- // Serialize a probing response packet that uses IETF QUIC's PATH RESPONSE
- // frame. Also fills the packet with padding if |is_padded| is
- // true. |payloads| is always emptied, even if the packet can not be
- // successfully built.
- size_t BuildPathResponsePacket(
- const QuicPacketHeader& header,
- char* buffer,
- size_t packet_length,
- const quiche::QuicheCircularDeque<QuicPathFrameBuffer>& payloads,
- const bool is_padded,
- EncryptionLevel level);
-
- // Serializes a probing packet, which is a padded PING packet. Returns the
- // length of the packet. Returns 0 if it fails to serialize.
- size_t BuildConnectivityProbingPacket(const QuicPacketHeader& header,
- char* buffer,
- size_t packet_length,
- EncryptionLevel level);
-
- // Serializes |coalesced| to provided |buffer|, returns coalesced packet
- // length if serialization succeeds. Otherwise, returns 0.
- size_t SerializeCoalescedPacket(const QuicCoalescedPacket& coalesced,
- char* buffer,
- size_t buffer_len);
-
- // Returns true if max_packet_length_ is currently a soft value.
- bool HasSoftMaxPacketLength() const;
-
- // Use this address to sent to the peer from now on. If this address is
- // different from the current one, flush all the queue frames first.
- void SetDefaultPeerAddress(QuicSocketAddress address);
-
- // Return true if retry_token_ is not empty.
- bool HasRetryToken() const;
-
- const QuicSocketAddress& peer_address() const { return packet_.peer_address; }
-
- private:
- friend class test::QuicPacketCreatorPeer;
-
- // Used to 1) clear queued_frames_, 2) report unrecoverable error (if
- // serialization fails) upon exiting the scope.
- class QUIC_EXPORT_PRIVATE ScopedSerializationFailureHandler {
- public:
- explicit ScopedSerializationFailureHandler(QuicPacketCreator* creator);
- ~ScopedSerializationFailureHandler();
-
- private:
- QuicPacketCreator* creator_; // Unowned.
- };
-
- // Attempts to build a data packet with chaos protection. If this packet isn't
- // supposed to be protected or if serialization fails then absl::nullopt is
- // returned. Otherwise returns the serialized length.
- absl::optional<size_t> MaybeBuildDataPacketWithChaosProtection(
- const QuicPacketHeader& header,
- char* buffer);
-
- // Creates a stream frame which fits into the current open packet. If
- // |data_size| is 0 and fin is true, the expected behavior is to consume
- // the fin.
- void CreateStreamFrame(QuicStreamId id,
- size_t data_size,
- QuicStreamOffset offset,
- bool fin,
- QuicFrame* frame);
-
- // Creates a CRYPTO frame which fits into the current open packet. Returns
- // false if there isn't enough room in the current open packet for a CRYPTO
- // frame, and true if there is.
- bool CreateCryptoFrame(EncryptionLevel level,
- size_t write_length,
- QuicStreamOffset offset,
- QuicFrame* frame);
-
- void FillPacketHeader(QuicPacketHeader* header);
-
- // Adds a padding frame to the current packet (if there is space) when (1)
- // current packet needs full padding or (2) there are pending paddings.
- void MaybeAddPadding();
-
- // Serializes all frames which have been added and adds any which should be
- // retransmitted to packet_.retransmittable_frames. All frames must fit into
- // a single packet. Returns true on success, otherwise, returns false.
- // Fails if |encrypted_buffer| is not large enough for the encrypted packet.
- ABSL_MUST_USE_RESULT bool SerializePacket(
- QuicOwnedPacketBuffer encrypted_buffer,
- size_t encrypted_buffer_len);
-
- // Called after a new SerialiedPacket is created to call the delegate's
- // OnSerializedPacket and reset state.
- void OnSerializedPacket();
-
- // Clears all fields of packet_ that should be cleared between serializations.
- void ClearPacket();
-
- // Re-serialzes frames of ENCRYPTION_INITIAL packet in coalesced packet with
- // the original packet's packet number and packet number length.
- // |padding_size| indicates the size of necessary padding. Returns 0 if
- // serialization fails.
- size_t ReserializeInitialPacketInCoalescedPacket(
- const SerializedPacket& packet,
- size_t padding_size,
- char* buffer,
- size_t buffer_len);
-
- // Tries to coalesce |frame| with the back of |queued_frames_|.
- // Returns true on success.
- bool MaybeCoalesceStreamFrame(const QuicStreamFrame& frame);
-
- // Called to remove the soft max_packet_length and restores
- // latched_hard_max_packet_length_ if the packet cannot accommodate a single
- // frame. Returns true if the soft limit is successfully removed. Returns
- // false if either there is no current soft limit or there are queued frames
- // (such that the packet length cannot be changed).
- bool RemoveSoftMaxPacketLength();
-
- // Returns true if a diversification nonce should be included in the current
- // packet's header.
- bool IncludeNonceInPublicHeader() const;
-
- // Returns true if version should be included in current packet's header.
- bool IncludeVersionInHeader() const;
-
- // Returns length of packet number to send over the wire.
- // packet_.packet_number_length should never be read directly, use this
- // function instead.
- QuicPacketNumberLength GetPacketNumberLength() const;
-
- // Returns the size in bytes of the packet header.
- size_t PacketHeaderSize() const;
-
- // Returns whether the destination connection ID is sent over the wire.
- QuicConnectionIdIncluded GetDestinationConnectionIdIncluded() const;
-
- // Returns whether the source connection ID is sent over the wire.
- QuicConnectionIdIncluded GetSourceConnectionIdIncluded() const;
-
- // Returns length of the retry token variable length integer to send over the
- // wire. Is non-zero for v99 IETF Initial packets.
- QuicVariableLengthIntegerLength GetRetryTokenLengthLength() const;
-
- // Returns the retry token to send over the wire, only sent in
- // v99 IETF Initial packets.
- absl::string_view GetRetryToken() const;
-
- // Returns length of the length variable length integer to send over the
- // wire. Is non-zero for v99 IETF Initial, 0-RTT or Handshake packets.
- QuicVariableLengthIntegerLength GetLengthLength() const;
-
- // Returns true if |frame| is a ClientHello.
- bool StreamFrameIsClientHello(const QuicStreamFrame& frame) const;
-
- // Returns true if packet under construction has IETF long header.
- bool HasIetfLongHeader() const;
-
- // Get serialized frame length. Returns 0 if the frame does not fit into
- // current packet.
- size_t GetSerializedFrameLength(const QuicFrame& frame);
-
- // Add extra padding to pending_padding_bytes_ to meet minimum plaintext
- // packet size required for header protection.
- void MaybeAddExtraPaddingForHeaderProtection();
-
- // Returns true and close connection if it attempts to send unencrypted data.
- bool AttemptingToSendUnencryptedStreamData();
-
- // Add the given frame to the current packet with full padding. If the current
- // packet doesn't have enough space, flush once and try again. Return false if
- // fail to add.
- bool AddPaddedFrameWithRetry(const QuicFrame& frame);
-
- // Does not own these delegates or the framer.
- DelegateInterface* delegate_;
- DebugDelegate* debug_delegate_;
- QuicFramer* framer_;
- QuicRandom* random_;
-
- // Controls whether version should be included while serializing the packet.
- // send_version_in_packet_ should never be read directly, use
- // IncludeVersionInHeader() instead.
- bool send_version_in_packet_;
- // If true, then |diversification_nonce_| will be included in the header of
- // all packets created at the initial encryption level.
- bool have_diversification_nonce_;
- DiversificationNonce diversification_nonce_;
- // Maximum length including headers and encryption (UDP payload length.)
- QuicByteCount max_packet_length_;
- size_t max_plaintext_size_;
- // Whether the server_connection_id is sent over the wire.
- QuicConnectionIdIncluded server_connection_id_included_;
-
- // Frames to be added to the next SerializedPacket
- QuicFrames queued_frames_;
-
- // Serialization size of header + frames. If there is no queued frames,
- // packet_size_ is 0.
- // TODO(ianswett): Move packet_size_ into SerializedPacket once
- // QuicEncryptedPacket has been flattened into SerializedPacket.
- size_t packet_size_;
- QuicConnectionId server_connection_id_;
- QuicConnectionId client_connection_id_;
-
- // Packet used to invoke OnSerializedPacket.
- SerializedPacket packet_;
-
- // Retry token to send over the wire in v99 IETF Initial packets.
- std::string retry_token_;
-
- // Pending padding bytes to send. Pending padding bytes will be sent in next
- // packet(s) (after all other frames) if current constructed packet does not
- // have room to send all of them.
- QuicByteCount pending_padding_bytes_;
-
- // Indicates whether current constructed packet needs full padding to max
- // packet size. Please note, full padding does not consume pending padding
- // bytes.
- bool needs_full_padding_;
-
- // Transmission type of the next serialized packet.
- TransmissionType next_transmission_type_;
-
- // True if packet flusher is currently attached.
- bool flusher_attached_;
-
- // Whether crypto handshake packets should be fully padded.
- bool fully_pad_crypto_handshake_packets_;
-
- // Packet number of the first packet of a write operation. This gets set
- // when the out-most flusher attaches and gets cleared when the out-most
- // flusher detaches.
- QuicPacketNumber write_start_packet_number_;
-
- // If not 0, this latches the actual max_packet_length when
- // SetSoftMaxPacketLength is called and max_packet_length_ gets
- // set to a soft value.
- QuicByteCount latched_hard_max_packet_length_;
-
- // The maximum length of a MESSAGE/DATAGRAM frame that our peer is willing to
- // accept. There is no limit for QUIC_CRYPTO connections, but QUIC+TLS
- // negotiates this during the handshake.
- QuicByteCount max_datagram_frame_size_;
-
- // Whether to attempt protecting initial packets with chaos.
- bool chaos_protection_enabled_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_QUIC_PACKET_CREATOR_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_packet_creator_test.cc b/chromium/net/third_party/quiche/src/quic/core/quic_packet_creator_test.cc
deleted file mode 100644
index 55385641426..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_packet_creator_test.cc
+++ /dev/null
@@ -1,4010 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_packet_creator.h"
-
-#include <cstdint>
-#include <limits>
-#include <memory>
-#include <ostream>
-#include <string>
-#include <utility>
-
-#include "absl/base/macros.h"
-#include "absl/strings/str_cat.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/crypto/null_decrypter.h"
-#include "quic/core/crypto/null_encrypter.h"
-#include "quic/core/crypto/quic_decrypter.h"
-#include "quic/core/crypto/quic_encrypter.h"
-#include "quic/core/frames/quic_stream_frame.h"
-#include "quic/core/quic_connection_id.h"
-#include "quic/core/quic_data_writer.h"
-#include "quic/core/quic_simple_buffer_allocator.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_expect_bug.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_socket_address.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/quic_framer_peer.h"
-#include "quic/test_tools/quic_packet_creator_peer.h"
-#include "quic/test_tools/quic_test_utils.h"
-#include "quic/test_tools/simple_data_producer.h"
-#include "quic/test_tools/simple_quic_framer.h"
-#include "common/test_tools/quiche_test_utils.h"
-
-using ::testing::_;
-using ::testing::AtLeast;
-using ::testing::DoAll;
-using ::testing::InSequence;
-using ::testing::Invoke;
-using ::testing::Return;
-using ::testing::SaveArg;
-using ::testing::StrictMock;
-
-namespace quic {
-namespace test {
-namespace {
-
-const QuicPacketNumber kPacketNumber = QuicPacketNumber(UINT64_C(0x12345678));
-// Use fields in which each byte is distinct to ensure that every byte is
-// framed correctly. The values are otherwise arbitrary.
-QuicConnectionId CreateTestConnectionId() {
- return TestConnectionId(UINT64_C(0xFEDCBA9876543210));
-}
-
-// Run tests with combinations of {ParsedQuicVersion,
-// ToggleVersionSerialization}.
-struct TestParams {
- TestParams(ParsedQuicVersion version, bool version_serialization)
- : version(version), version_serialization(version_serialization) {}
-
- ParsedQuicVersion version;
- bool version_serialization;
-};
-
-// Used by ::testing::PrintToStringParamName().
-std::string PrintToString(const TestParams& p) {
- return absl::StrCat(ParsedQuicVersionToString(p.version), "_",
- (p.version_serialization ? "Include" : "No"), "Version");
-}
-
-// Constructs various test permutations.
-std::vector<TestParams> GetTestParams() {
- std::vector<TestParams> params;
- ParsedQuicVersionVector all_supported_versions = AllSupportedVersions();
- for (size_t i = 0; i < all_supported_versions.size(); ++i) {
- params.push_back(TestParams(all_supported_versions[i], true));
- params.push_back(TestParams(all_supported_versions[i], false));
- }
- return params;
-}
-
-class MockDebugDelegate : public QuicPacketCreator::DebugDelegate {
- public:
- ~MockDebugDelegate() override = default;
-
- MOCK_METHOD(void, OnFrameAddedToPacket, (const QuicFrame& frame), (override));
-
- MOCK_METHOD(void,
- OnStreamFrameCoalesced,
- (const QuicStreamFrame& frame),
- (override));
-};
-
-class TestPacketCreator : public QuicPacketCreator {
- public:
- TestPacketCreator(QuicConnectionId connection_id,
- QuicFramer* framer,
- DelegateInterface* delegate,
- SimpleDataProducer* producer)
- : QuicPacketCreator(connection_id, framer, delegate),
- producer_(producer),
- version_(framer->version()) {}
-
- bool ConsumeDataToFillCurrentPacket(QuicStreamId id,
- const struct iovec* iov,
- int iov_count,
- size_t total_length,
- size_t iov_offset,
- QuicStreamOffset offset,
- bool fin,
- bool needs_full_padding,
- TransmissionType transmission_type,
- QuicFrame* frame) {
- // Save data before data is consumed.
- QuicByteCount data_length = total_length - iov_offset;
- if (data_length > 0) {
- producer_->SaveStreamData(id, iov, iov_count, iov_offset, data_length);
- }
- return QuicPacketCreator::ConsumeDataToFillCurrentPacket(
- id, data_length - iov_offset, offset, fin, needs_full_padding,
- transmission_type, frame);
- }
-
- void StopSendingVersion() {
- if (version_.HasIetfInvariantHeader()) {
- set_encryption_level(ENCRYPTION_FORWARD_SECURE);
- return;
- }
- QuicPacketCreator::StopSendingVersion();
- }
-
- SimpleDataProducer* producer_;
- ParsedQuicVersion version_;
-};
-
-class QuicPacketCreatorTest : public QuicTestWithParam<TestParams> {
- public:
- void ClearSerializedPacketForTests(SerializedPacket /*serialized_packet*/) {
- // serialized packet self-clears on destruction.
- }
-
- void SaveSerializedPacket(SerializedPacket serialized_packet) {
- serialized_packet_.reset(CopySerializedPacket(
- serialized_packet, &allocator_, /*copy_buffer=*/true));
- }
-
- void DeleteSerializedPacket() { serialized_packet_ = nullptr; }
-
- protected:
- QuicPacketCreatorTest()
- : connection_id_(TestConnectionId(2)),
- server_framer_(SupportedVersions(GetParam().version),
- QuicTime::Zero(),
- Perspective::IS_SERVER,
- connection_id_.length()),
- client_framer_(SupportedVersions(GetParam().version),
- QuicTime::Zero(),
- Perspective::IS_CLIENT,
- connection_id_.length()),
- data_("foo"),
- creator_(connection_id_, &client_framer_, &delegate_, &producer_) {
- EXPECT_CALL(delegate_, GetPacketBuffer())
- .WillRepeatedly(Return(QuicPacketBuffer()));
- EXPECT_CALL(delegate_, GetSerializedPacketFate(_, _))
- .WillRepeatedly(Return(SEND_TO_WRITER));
- creator_.SetEncrypter(ENCRYPTION_INITIAL, std::make_unique<NullEncrypter>(
- Perspective::IS_CLIENT));
- creator_.SetEncrypter(ENCRYPTION_HANDSHAKE, std::make_unique<NullEncrypter>(
- Perspective::IS_CLIENT));
- creator_.SetEncrypter(ENCRYPTION_ZERO_RTT, std::make_unique<NullEncrypter>(
- Perspective::IS_CLIENT));
- creator_.SetEncrypter(
- ENCRYPTION_FORWARD_SECURE,
- std::make_unique<NullEncrypter>(Perspective::IS_CLIENT));
- client_framer_.set_visitor(&framer_visitor_);
- server_framer_.set_visitor(&framer_visitor_);
- client_framer_.set_data_producer(&producer_);
- if (server_framer_.version().KnowsWhichDecrypterToUse()) {
- server_framer_.InstallDecrypter(
- ENCRYPTION_INITIAL,
- std::make_unique<NullDecrypter>(Perspective::IS_SERVER));
- server_framer_.InstallDecrypter(
- ENCRYPTION_ZERO_RTT,
- std::make_unique<NullDecrypter>(Perspective::IS_SERVER));
- server_framer_.InstallDecrypter(
- ENCRYPTION_HANDSHAKE,
- std::make_unique<NullDecrypter>(Perspective::IS_SERVER));
- server_framer_.InstallDecrypter(
- ENCRYPTION_FORWARD_SECURE,
- std::make_unique<NullDecrypter>(Perspective::IS_SERVER));
- } else {
- server_framer_.SetDecrypter(
- ENCRYPTION_INITIAL,
- std::make_unique<NullDecrypter>(Perspective::IS_SERVER));
- }
- }
-
- ~QuicPacketCreatorTest() override {}
-
- SerializedPacket SerializeAllFrames(const QuicFrames& frames) {
- SerializedPacket packet = QuicPacketCreatorPeer::SerializeAllFrames(
- &creator_, frames, buffer_, kMaxOutgoingPacketSize);
- EXPECT_EQ(QuicPacketCreatorPeer::GetEncryptionLevel(&creator_),
- packet.encryption_level);
- return packet;
- }
-
- void ProcessPacket(const SerializedPacket& packet) {
- QuicEncryptedPacket encrypted_packet(packet.encrypted_buffer,
- packet.encrypted_length);
- server_framer_.ProcessPacket(encrypted_packet);
- }
-
- void CheckStreamFrame(const QuicFrame& frame,
- QuicStreamId stream_id,
- const std::string& data,
- QuicStreamOffset offset,
- bool fin) {
- EXPECT_EQ(STREAM_FRAME, frame.type);
- EXPECT_EQ(stream_id, frame.stream_frame.stream_id);
- char buf[kMaxOutgoingPacketSize];
- QuicDataWriter writer(kMaxOutgoingPacketSize, buf, quiche::HOST_BYTE_ORDER);
- if (frame.stream_frame.data_length > 0) {
- producer_.WriteStreamData(stream_id, frame.stream_frame.offset,
- frame.stream_frame.data_length, &writer);
- }
- EXPECT_EQ(data, absl::string_view(buf, frame.stream_frame.data_length));
- EXPECT_EQ(offset, frame.stream_frame.offset);
- EXPECT_EQ(fin, frame.stream_frame.fin);
- }
-
- // Returns the number of bytes consumed by the header of packet, including
- // the version.
- size_t GetPacketHeaderOverhead(QuicTransportVersion version) {
- return GetPacketHeaderSize(
- version, creator_.GetDestinationConnectionIdLength(),
- creator_.GetSourceConnectionIdLength(),
- QuicPacketCreatorPeer::SendVersionInPacket(&creator_),
- !kIncludeDiversificationNonce,
- QuicPacketCreatorPeer::GetPacketNumberLength(&creator_),
- QuicPacketCreatorPeer::GetRetryTokenLengthLength(&creator_), 0,
- QuicPacketCreatorPeer::GetLengthLength(&creator_));
- }
-
- // Returns the number of bytes of overhead that will be added to a packet
- // of maximum length.
- size_t GetEncryptionOverhead() {
- return creator_.max_packet_length() -
- client_framer_.GetMaxPlaintextSize(creator_.max_packet_length());
- }
-
- // Returns the number of bytes consumed by the non-data fields of a stream
- // frame, assuming it is the last frame in the packet
- size_t GetStreamFrameOverhead(QuicTransportVersion version) {
- return QuicFramer::GetMinStreamFrameSize(
- version, GetNthClientInitiatedStreamId(1), kOffset, true,
- /* data_length= */ 0);
- }
-
- bool IsDefaultTestConfiguration() {
- TestParams p = GetParam();
- return p.version == AllSupportedVersions()[0] && p.version_serialization;
- }
-
- QuicStreamId GetNthClientInitiatedStreamId(int n) const {
- return QuicUtils::GetFirstBidirectionalStreamId(
- creator_.transport_version(), Perspective::IS_CLIENT) +
- n * 2;
- }
-
- void TestChaosProtection(bool enabled);
-
- static constexpr QuicStreamOffset kOffset = 0u;
-
- char buffer_[kMaxOutgoingPacketSize];
- QuicConnectionId connection_id_;
- QuicFrames frames_;
- QuicFramer server_framer_;
- QuicFramer client_framer_;
- StrictMock<MockFramerVisitor> framer_visitor_;
- StrictMock<MockPacketCreatorDelegate> delegate_;
- std::string data_;
- struct iovec iov_;
- TestPacketCreator creator_;
- std::unique_ptr<SerializedPacket> serialized_packet_;
- SimpleDataProducer producer_;
- SimpleBufferAllocator allocator_;
-};
-
-// Run all packet creator tests with all supported versions of QUIC, and with
-// and without version in the packet header, as well as doing a run for each
-// length of truncated connection id.
-INSTANTIATE_TEST_SUITE_P(QuicPacketCreatorTests,
- QuicPacketCreatorTest,
- ::testing::ValuesIn(GetTestParams()),
- ::testing::PrintToStringParamName());
-
-TEST_P(QuicPacketCreatorTest, SerializeFrames) {
- for (int i = ENCRYPTION_INITIAL; i < NUM_ENCRYPTION_LEVELS; ++i) {
- EncryptionLevel level = static_cast<EncryptionLevel>(i);
- creator_.set_encryption_level(level);
- if (level != ENCRYPTION_ZERO_RTT) {
- frames_.push_back(QuicFrame(new QuicAckFrame(InitAckFrame(1))));
- }
- QuicStreamId stream_id = QuicUtils::GetFirstBidirectionalStreamId(
- client_framer_.transport_version(), Perspective::IS_CLIENT);
- if (level != ENCRYPTION_INITIAL && level != ENCRYPTION_HANDSHAKE) {
- frames_.push_back(QuicFrame(
- QuicStreamFrame(stream_id, false, 0u, absl::string_view())));
- }
- SerializedPacket serialized = SerializeAllFrames(frames_);
- EXPECT_EQ(level, serialized.encryption_level);
- if (level != ENCRYPTION_ZERO_RTT) {
- delete frames_[0].ack_frame;
- }
- frames_.clear();
-
- {
- InSequence s;
- EXPECT_CALL(framer_visitor_, OnPacket());
- EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_));
- EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_));
- EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_, _));
- EXPECT_CALL(framer_visitor_, OnPacketHeader(_));
- if (level != ENCRYPTION_ZERO_RTT) {
- EXPECT_CALL(framer_visitor_, OnAckFrameStart(_, _))
- .WillOnce(Return(true));
- EXPECT_CALL(framer_visitor_,
- OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2)))
- .WillOnce(Return(true));
- EXPECT_CALL(framer_visitor_, OnAckFrameEnd(QuicPacketNumber(1)))
- .WillOnce(Return(true));
- }
- if (level != ENCRYPTION_INITIAL && level != ENCRYPTION_HANDSHAKE) {
- EXPECT_CALL(framer_visitor_, OnStreamFrame(_));
- }
- if (client_framer_.version().HasHeaderProtection()) {
- EXPECT_CALL(framer_visitor_, OnPaddingFrame(_))
- .Times(testing::AnyNumber());
- }
- EXPECT_CALL(framer_visitor_, OnPacketComplete());
- }
- ProcessPacket(serialized);
- }
-}
-
-TEST_P(QuicPacketCreatorTest, SerializeConnectionClose) {
- QuicConnectionCloseFrame* frame = new QuicConnectionCloseFrame(
- creator_.transport_version(), QUIC_NO_ERROR, NO_IETF_QUIC_ERROR, "error",
- /*transport_close_frame_type=*/0);
-
- QuicFrames frames;
- frames.push_back(QuicFrame(frame));
- SerializedPacket serialized = SerializeAllFrames(frames);
- EXPECT_EQ(ENCRYPTION_INITIAL, serialized.encryption_level);
- ASSERT_EQ(QuicPacketNumber(1u), serialized.packet_number);
- ASSERT_EQ(QuicPacketNumber(1u), creator_.packet_number());
-
- InSequence s;
- EXPECT_CALL(framer_visitor_, OnPacket());
- EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_));
- EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_));
- EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_, _));
- EXPECT_CALL(framer_visitor_, OnPacketHeader(_));
- EXPECT_CALL(framer_visitor_, OnConnectionCloseFrame(_));
- EXPECT_CALL(framer_visitor_, OnPacketComplete());
-
- ProcessPacket(serialized);
-}
-
-TEST_P(QuicPacketCreatorTest, ConsumeCryptoDataToFillCurrentPacket) {
- std::string data = "crypto data";
- QuicFrame frame;
- ASSERT_TRUE(creator_.ConsumeCryptoDataToFillCurrentPacket(
- ENCRYPTION_INITIAL, data.length(), 0,
- /*needs_full_padding=*/true, NOT_RETRANSMISSION, &frame));
- EXPECT_EQ(frame.crypto_frame->data_length, data.length());
- EXPECT_TRUE(creator_.HasPendingFrames());
-}
-
-TEST_P(QuicPacketCreatorTest, ConsumeDataToFillCurrentPacket) {
- creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
- QuicFrame frame;
- MakeIOVector("test", &iov_);
- QuicStreamId stream_id = QuicUtils::GetFirstBidirectionalStreamId(
- client_framer_.transport_version(), Perspective::IS_CLIENT);
- ASSERT_TRUE(creator_.ConsumeDataToFillCurrentPacket(
- stream_id, &iov_, 1u, iov_.iov_len, 0u, 0u, false, false,
- NOT_RETRANSMISSION, &frame));
- size_t consumed = frame.stream_frame.data_length;
- EXPECT_EQ(4u, consumed);
- CheckStreamFrame(frame, stream_id, "test", 0u, false);
- EXPECT_TRUE(creator_.HasPendingFrames());
-}
-
-TEST_P(QuicPacketCreatorTest, ConsumeDataFin) {
- creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
- QuicFrame frame;
- MakeIOVector("test", &iov_);
- QuicStreamId stream_id = QuicUtils::GetFirstBidirectionalStreamId(
- client_framer_.transport_version(), Perspective::IS_CLIENT);
- ASSERT_TRUE(creator_.ConsumeDataToFillCurrentPacket(
- stream_id, &iov_, 1u, iov_.iov_len, 0u, 0u, true, false,
- NOT_RETRANSMISSION, &frame));
- size_t consumed = frame.stream_frame.data_length;
- EXPECT_EQ(4u, consumed);
- CheckStreamFrame(frame, stream_id, "test", 0u, true);
- EXPECT_TRUE(creator_.HasPendingFrames());
-}
-
-TEST_P(QuicPacketCreatorTest, ConsumeDataFinOnly) {
- creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
- QuicFrame frame;
- QuicStreamId stream_id = QuicUtils::GetFirstBidirectionalStreamId(
- client_framer_.transport_version(), Perspective::IS_CLIENT);
- ASSERT_TRUE(creator_.ConsumeDataToFillCurrentPacket(
- stream_id, nullptr, 0u, 0u, 0u, 0u, true, false, NOT_RETRANSMISSION,
- &frame));
- size_t consumed = frame.stream_frame.data_length;
- EXPECT_EQ(0u, consumed);
- CheckStreamFrame(frame, stream_id, std::string(), 0u, true);
- EXPECT_TRUE(creator_.HasPendingFrames());
- EXPECT_TRUE(absl::StartsWith(creator_.GetPendingFramesInfo(),
- "type { STREAM_FRAME }"));
-}
-
-TEST_P(QuicPacketCreatorTest, CreateAllFreeBytesForStreamFrames) {
- creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
- const size_t overhead =
- GetPacketHeaderOverhead(client_framer_.transport_version()) +
- GetEncryptionOverhead();
- for (size_t i = overhead + QuicPacketCreator::MinPlaintextPacketSize(
- client_framer_.version());
- i < overhead + 100; ++i) {
- SCOPED_TRACE(i);
- creator_.SetMaxPacketLength(i);
- const bool should_have_room =
- i >
- overhead + GetStreamFrameOverhead(client_framer_.transport_version());
- ASSERT_EQ(should_have_room,
- creator_.HasRoomForStreamFrame(GetNthClientInitiatedStreamId(1),
- kOffset, /* data_size=*/0xffff));
- if (should_have_room) {
- QuicFrame frame;
- MakeIOVector("testdata", &iov_);
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .WillRepeatedly(Invoke(
- this, &QuicPacketCreatorTest::ClearSerializedPacketForTests));
- ASSERT_TRUE(creator_.ConsumeDataToFillCurrentPacket(
- GetNthClientInitiatedStreamId(1), &iov_, 1u, iov_.iov_len, 0u,
- kOffset, false, false, NOT_RETRANSMISSION, &frame));
- size_t bytes_consumed = frame.stream_frame.data_length;
- EXPECT_LT(0u, bytes_consumed);
- creator_.FlushCurrentPacket();
- }
- }
-}
-
-TEST_P(QuicPacketCreatorTest, StreamFrameConsumption) {
- creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
- // Compute the total overhead for a single frame in packet.
- const size_t overhead =
- GetPacketHeaderOverhead(client_framer_.transport_version()) +
- GetEncryptionOverhead() +
- GetStreamFrameOverhead(client_framer_.transport_version());
- size_t capacity = kDefaultMaxPacketSize - overhead;
- // Now, test various sizes around this size.
- for (int delta = -5; delta <= 5; ++delta) {
- std::string data(capacity + delta, 'A');
- size_t bytes_free = delta > 0 ? 0 : 0 - delta;
- QuicFrame frame;
- MakeIOVector(data, &iov_);
- ASSERT_TRUE(creator_.ConsumeDataToFillCurrentPacket(
- GetNthClientInitiatedStreamId(1), &iov_, 1u, iov_.iov_len, 0u, kOffset,
- false, false, NOT_RETRANSMISSION, &frame));
-
- // BytesFree() returns bytes available for the next frame, which will
- // be two bytes smaller since the stream frame would need to be grown.
- EXPECT_EQ(2u, creator_.ExpansionOnNewFrame());
- size_t expected_bytes_free = bytes_free < 3 ? 0 : bytes_free - 2;
- EXPECT_EQ(expected_bytes_free, creator_.BytesFree()) << "delta: " << delta;
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .WillOnce(Invoke(this, &QuicPacketCreatorTest::SaveSerializedPacket));
- creator_.FlushCurrentPacket();
- ASSERT_TRUE(serialized_packet_->encrypted_buffer);
- DeleteSerializedPacket();
- }
-}
-
-TEST_P(QuicPacketCreatorTest, CryptoStreamFramePacketPadding) {
- // This test serializes crypto payloads slightly larger than a packet, which
- // Causes the multi-packet ClientHello check to fail.
- SetQuicFlag(FLAGS_quic_enforce_single_packet_chlo, false);
- // Compute the total overhead for a single frame in packet.
- size_t overhead =
- GetPacketHeaderOverhead(client_framer_.transport_version()) +
- GetEncryptionOverhead();
- if (QuicVersionUsesCryptoFrames(client_framer_.transport_version())) {
- overhead +=
- QuicFramer::GetMinCryptoFrameSize(kOffset, kMaxOutgoingPacketSize);
- } else {
- overhead += GetStreamFrameOverhead(client_framer_.transport_version());
- }
- ASSERT_GT(kMaxOutgoingPacketSize, overhead);
- size_t capacity = kDefaultMaxPacketSize - overhead;
- // Now, test various sizes around this size.
- for (int delta = -5; delta <= 5; ++delta) {
- SCOPED_TRACE(delta);
- std::string data(capacity + delta, 'A');
- size_t bytes_free = delta > 0 ? 0 : 0 - delta;
-
- QuicFrame frame;
- MakeIOVector(data, &iov_);
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .WillRepeatedly(
- Invoke(this, &QuicPacketCreatorTest::SaveSerializedPacket));
- if (client_framer_.version().CanSendCoalescedPackets()) {
- EXPECT_CALL(delegate_, GetSerializedPacketFate(_, _))
- .WillRepeatedly(Return(COALESCE));
- }
- if (!QuicVersionUsesCryptoFrames(client_framer_.transport_version())) {
- ASSERT_TRUE(creator_.ConsumeDataToFillCurrentPacket(
- QuicUtils::GetCryptoStreamId(client_framer_.transport_version()),
- &iov_, 1u, iov_.iov_len, 0u, kOffset, false, true, NOT_RETRANSMISSION,
- &frame));
- size_t bytes_consumed = frame.stream_frame.data_length;
- EXPECT_LT(0u, bytes_consumed);
- } else {
- producer_.SaveCryptoData(ENCRYPTION_INITIAL, kOffset, data);
- ASSERT_TRUE(creator_.ConsumeCryptoDataToFillCurrentPacket(
- ENCRYPTION_INITIAL, data.length(), kOffset,
- /*needs_full_padding=*/true, NOT_RETRANSMISSION, &frame));
- size_t bytes_consumed = frame.crypto_frame->data_length;
- EXPECT_LT(0u, bytes_consumed);
- }
- creator_.FlushCurrentPacket();
- ASSERT_TRUE(serialized_packet_->encrypted_buffer);
- // If there is not enough space in the packet to fit a padding frame
- // (1 byte) and to expand the stream frame (another 2 bytes) the packet
- // will not be padded.
- // Padding is skipped when we try to send coalesced packets.
- if ((bytes_free < 3 &&
- !QuicVersionUsesCryptoFrames(client_framer_.transport_version())) ||
- client_framer_.version().CanSendCoalescedPackets()) {
- EXPECT_EQ(kDefaultMaxPacketSize - bytes_free,
- serialized_packet_->encrypted_length);
- } else {
- EXPECT_EQ(kDefaultMaxPacketSize, serialized_packet_->encrypted_length);
- }
- DeleteSerializedPacket();
- }
-}
-
-TEST_P(QuicPacketCreatorTest, NonCryptoStreamFramePacketNonPadding) {
- creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
- // Compute the total overhead for a single frame in packet.
- const size_t overhead =
- GetPacketHeaderOverhead(client_framer_.transport_version()) +
- GetEncryptionOverhead() +
- GetStreamFrameOverhead(client_framer_.transport_version());
- ASSERT_GT(kDefaultMaxPacketSize, overhead);
- size_t capacity = kDefaultMaxPacketSize - overhead;
- // Now, test various sizes around this size.
- for (int delta = -5; delta <= 5; ++delta) {
- std::string data(capacity + delta, 'A');
- size_t bytes_free = delta > 0 ? 0 : 0 - delta;
-
- QuicFrame frame;
- MakeIOVector(data, &iov_);
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .WillOnce(Invoke(this, &QuicPacketCreatorTest::SaveSerializedPacket));
- ASSERT_TRUE(creator_.ConsumeDataToFillCurrentPacket(
- GetNthClientInitiatedStreamId(1), &iov_, 1u, iov_.iov_len, 0u, kOffset,
- false, false, NOT_RETRANSMISSION, &frame));
- size_t bytes_consumed = frame.stream_frame.data_length;
- EXPECT_LT(0u, bytes_consumed);
- creator_.FlushCurrentPacket();
- ASSERT_TRUE(serialized_packet_->encrypted_buffer);
- if (bytes_free > 0) {
- EXPECT_EQ(kDefaultMaxPacketSize - bytes_free,
- serialized_packet_->encrypted_length);
- } else {
- EXPECT_EQ(kDefaultMaxPacketSize, serialized_packet_->encrypted_length);
- }
- DeleteSerializedPacket();
- }
-}
-
-// Test that the path challenge connectivity probing packet is serialized
-// correctly as a padded PATH CHALLENGE packet.
-TEST_P(QuicPacketCreatorTest, BuildPathChallengePacket) {
- if (!VersionHasIetfQuicFrames(creator_.transport_version())) {
- // This frame is only for IETF QUIC.
- return;
- }
-
- QuicPacketHeader header;
- header.destination_connection_id = CreateTestConnectionId();
- header.reset_flag = false;
- header.version_flag = false;
- header.packet_number = kPacketNumber;
- MockRandom randomizer;
- QuicPathFrameBuffer payload;
- randomizer.RandBytes(payload.data(), payload.size());
-
- // clang-format off
- unsigned char packet[] = {
- // type (short header, 4 byte packet number)
- 0x43,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
-
- // Path Challenge Frame type (IETF_PATH_CHALLENGE)
- 0x1a,
- // 8 "random" bytes, MockRandom makes lots of r's
- 'r', 'r', 'r', 'r', 'r', 'r', 'r', 'r',
- // frame type (padding frame)
- 0x00,
- 0x00, 0x00, 0x00, 0x00
- };
- // clang-format on
-
- std::unique_ptr<char[]> buffer(new char[kMaxOutgoingPacketSize]);
-
- size_t length = creator_.BuildPaddedPathChallengePacket(
- header, buffer.get(), ABSL_ARRAYSIZE(packet), payload,
- ENCRYPTION_INITIAL);
- EXPECT_EQ(length, ABSL_ARRAYSIZE(packet));
-
- // Payload has the random bytes that were generated. Copy them into packet,
- // above, before checking that the generated packet is correct.
- EXPECT_EQ(kQuicPathFrameBufferSize, payload.size());
-
- QuicPacket data(creator_.transport_version(), buffer.release(), length, true,
- header);
-
- quiche::test::CompareCharArraysWithHexError(
- "constructed packet", data.data(), data.length(),
- reinterpret_cast<char*>(packet), ABSL_ARRAYSIZE(packet));
-}
-
-TEST_P(QuicPacketCreatorTest, BuildConnectivityProbingPacket) {
- QuicPacketHeader header;
- header.destination_connection_id = CreateTestConnectionId();
- header.reset_flag = false;
- header.version_flag = false;
- header.packet_number = kPacketNumber;
-
- // clang-format off
- unsigned char packet[] = {
- // public flags (8 byte connection_id)
- 0x2C,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
-
- // frame type (ping frame)
- 0x07,
- // frame type (padding frame)
- 0x00,
- 0x00, 0x00, 0x00, 0x00
- };
-
- unsigned char packet46[] = {
- // type (short header, 4 byte packet number)
- 0x43,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
-
- // frame type
- 0x07,
- // frame type (padding frame)
- 0x00,
- 0x00, 0x00, 0x00, 0x00
- };
-
- unsigned char packet99[] = {
- // type (short header, 4 byte packet number)
- 0x43,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
-
- // frame type (IETF_PING frame)
- 0x01,
- // frame type (padding frame)
- 0x00,
- 0x00, 0x00, 0x00, 0x00
- };
- // clang-format on
-
- unsigned char* p = packet;
- size_t packet_size = ABSL_ARRAYSIZE(packet);
- if (creator_.version().HasIetfQuicFrames()) {
- p = packet99;
- packet_size = ABSL_ARRAYSIZE(packet99);
- } else if (creator_.version().HasIetfInvariantHeader()) {
- p = packet46;
- packet_size = ABSL_ARRAYSIZE(packet46);
- }
-
- std::unique_ptr<char[]> buffer(new char[kMaxOutgoingPacketSize]);
-
- size_t length = creator_.BuildConnectivityProbingPacket(
- header, buffer.get(), packet_size, ENCRYPTION_INITIAL);
-
- EXPECT_NE(0u, length);
- QuicPacket data(creator_.transport_version(), buffer.release(), length, true,
- header);
-
- quiche::test::CompareCharArraysWithHexError(
- "constructed packet", data.data(), data.length(),
- reinterpret_cast<char*>(p), packet_size);
-}
-
-// Several tests that the path response connectivity probing packet is
-// serialized correctly as either a padded and unpadded PATH RESPONSE
-// packet. Also generates packets with 1 and 3 PATH_RESPONSES in them to
-// exercised the single- and multiple- payload cases.
-TEST_P(QuicPacketCreatorTest, BuildPathResponsePacket1ResponseUnpadded) {
- if (!VersionHasIetfQuicFrames(creator_.transport_version())) {
- // This frame is only for IETF QUIC.
- return;
- }
-
- QuicPacketHeader header;
- header.destination_connection_id = CreateTestConnectionId();
- header.reset_flag = false;
- header.version_flag = false;
- header.packet_number = kPacketNumber;
- QuicPathFrameBuffer payload0 = {
- {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}};
-
- // Build 1 PATH RESPONSE, not padded
- // clang-format off
- unsigned char packet[] = {
- // type (short header, 4 byte packet number)
- 0x43,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
-
- // Path Response Frame type (IETF_PATH_RESPONSE)
- 0x1b,
- // 8 "random" bytes
- 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
- };
- // clang-format on
- std::unique_ptr<char[]> buffer(new char[kMaxOutgoingPacketSize]);
- quiche::QuicheCircularDeque<QuicPathFrameBuffer> payloads;
- payloads.push_back(payload0);
- size_t length = creator_.BuildPathResponsePacket(
- header, buffer.get(), ABSL_ARRAYSIZE(packet), payloads,
- /*is_padded=*/false, ENCRYPTION_INITIAL);
- EXPECT_EQ(length, ABSL_ARRAYSIZE(packet));
- QuicPacket data(creator_.transport_version(), buffer.release(), length, true,
- header);
-
- quiche::test::CompareCharArraysWithHexError(
- "constructed packet", data.data(), data.length(),
- reinterpret_cast<char*>(packet), ABSL_ARRAYSIZE(packet));
-}
-
-TEST_P(QuicPacketCreatorTest, BuildPathResponsePacket1ResponsePadded) {
- if (!VersionHasIetfQuicFrames(creator_.transport_version())) {
- // This frame is only for IETF QUIC.
- return;
- }
-
- QuicPacketHeader header;
- header.destination_connection_id = CreateTestConnectionId();
- header.reset_flag = false;
- header.version_flag = false;
- header.packet_number = kPacketNumber;
- QuicPathFrameBuffer payload0 = {
- {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}};
-
- // Build 1 PATH RESPONSE, padded
- // clang-format off
- unsigned char packet[] = {
- // type (short header, 4 byte packet number)
- 0x43,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
-
- // Path Response Frame type (IETF_PATH_RESPONSE)
- 0x1b,
- // 8 "random" bytes
- 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
- // Padding type and pad
- 0x00, 0x00, 0x00, 0x00, 0x00
- };
- // clang-format on
- std::unique_ptr<char[]> buffer(new char[kMaxOutgoingPacketSize]);
- quiche::QuicheCircularDeque<QuicPathFrameBuffer> payloads;
- payloads.push_back(payload0);
- size_t length = creator_.BuildPathResponsePacket(
- header, buffer.get(), ABSL_ARRAYSIZE(packet), payloads,
- /*is_padded=*/true, ENCRYPTION_INITIAL);
- EXPECT_EQ(length, ABSL_ARRAYSIZE(packet));
- QuicPacket data(creator_.transport_version(), buffer.release(), length, true,
- header);
-
- quiche::test::CompareCharArraysWithHexError(
- "constructed packet", data.data(), data.length(),
- reinterpret_cast<char*>(packet), ABSL_ARRAYSIZE(packet));
-}
-
-TEST_P(QuicPacketCreatorTest, BuildPathResponsePacket3ResponsesUnpadded) {
- if (!VersionHasIetfQuicFrames(creator_.transport_version())) {
- // This frame is only for IETF QUIC.
- return;
- }
-
- QuicPacketHeader header;
- header.destination_connection_id = CreateTestConnectionId();
- header.reset_flag = false;
- header.version_flag = false;
- header.packet_number = kPacketNumber;
- QuicPathFrameBuffer payload0 = {
- {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}};
- QuicPathFrameBuffer payload1 = {
- {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18}};
- QuicPathFrameBuffer payload2 = {
- {0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28}};
-
- // Build one packet with 3 PATH RESPONSES, no padding
- // clang-format off
- unsigned char packet[] = {
- // type (short header, 4 byte packet number)
- 0x43,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
-
- // 3 path response frames (IETF_PATH_RESPONSE type byte and payload)
- 0x1b, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
- 0x1b, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
- 0x1b, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
- };
- // clang-format on
-
- std::unique_ptr<char[]> buffer(new char[kMaxOutgoingPacketSize]);
- quiche::QuicheCircularDeque<QuicPathFrameBuffer> payloads;
- payloads.push_back(payload0);
- payloads.push_back(payload1);
- payloads.push_back(payload2);
- size_t length = creator_.BuildPathResponsePacket(
- header, buffer.get(), ABSL_ARRAYSIZE(packet), payloads,
- /*is_padded=*/false, ENCRYPTION_INITIAL);
- EXPECT_EQ(length, ABSL_ARRAYSIZE(packet));
- QuicPacket data(creator_.transport_version(), buffer.release(), length, true,
- header);
-
- quiche::test::CompareCharArraysWithHexError(
- "constructed packet", data.data(), data.length(),
- reinterpret_cast<char*>(packet), ABSL_ARRAYSIZE(packet));
-}
-
-TEST_P(QuicPacketCreatorTest, BuildPathResponsePacket3ResponsesPadded) {
- if (!VersionHasIetfQuicFrames(creator_.transport_version())) {
- // This frame is only for IETF QUIC.
- return;
- }
-
- QuicPacketHeader header;
- header.destination_connection_id = CreateTestConnectionId();
- header.reset_flag = false;
- header.version_flag = false;
- header.packet_number = kPacketNumber;
- QuicPathFrameBuffer payload0 = {
- {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}};
- QuicPathFrameBuffer payload1 = {
- {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18}};
- QuicPathFrameBuffer payload2 = {
- {0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28}};
-
- // Build one packet with 3 PATH RESPONSES, with padding
- // clang-format off
- unsigned char packet[] = {
- // type (short header, 4 byte packet number)
- 0x43,
- // connection_id
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
- // packet number
- 0x12, 0x34, 0x56, 0x78,
-
- // 3 path response frames (IETF_PATH_RESPONSE byte and payload)
- 0x1b, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
- 0x1b, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
- 0x1b, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
- // Padding
- 0x00, 0x00, 0x00, 0x00, 0x00
- };
- // clang-format on
-
- std::unique_ptr<char[]> buffer(new char[kMaxOutgoingPacketSize]);
- quiche::QuicheCircularDeque<QuicPathFrameBuffer> payloads;
- payloads.push_back(payload0);
- payloads.push_back(payload1);
- payloads.push_back(payload2);
- size_t length = creator_.BuildPathResponsePacket(
- header, buffer.get(), ABSL_ARRAYSIZE(packet), payloads,
- /*is_padded=*/true, ENCRYPTION_INITIAL);
- EXPECT_EQ(length, ABSL_ARRAYSIZE(packet));
- QuicPacket data(creator_.transport_version(), buffer.release(), length, true,
- header);
-
- quiche::test::CompareCharArraysWithHexError(
- "constructed packet", data.data(), data.length(),
- reinterpret_cast<char*>(packet), ABSL_ARRAYSIZE(packet));
-}
-
-TEST_P(QuicPacketCreatorTest, SerializeConnectivityProbingPacket) {
- creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
-
- std::unique_ptr<SerializedPacket> encrypted;
- if (VersionHasIetfQuicFrames(creator_.transport_version())) {
- QuicPathFrameBuffer payload = {
- {0xde, 0xad, 0xbe, 0xef, 0xba, 0xdc, 0x0f, 0xfe}};
- encrypted =
- creator_.SerializePathChallengeConnectivityProbingPacket(payload);
- } else {
- encrypted = creator_.SerializeConnectivityProbingPacket();
- }
- {
- InSequence s;
- EXPECT_CALL(framer_visitor_, OnPacket());
- EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_));
- EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_));
- EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_, _));
- EXPECT_CALL(framer_visitor_, OnPacketHeader(_));
- if (VersionHasIetfQuicFrames(creator_.transport_version())) {
- EXPECT_CALL(framer_visitor_, OnPathChallengeFrame(_));
- EXPECT_CALL(framer_visitor_, OnPaddingFrame(_));
- } else {
- EXPECT_CALL(framer_visitor_, OnPingFrame(_));
- EXPECT_CALL(framer_visitor_, OnPaddingFrame(_));
- }
- EXPECT_CALL(framer_visitor_, OnPacketComplete());
- }
- // QuicFramerPeer::SetPerspective(&client_framer_, Perspective::IS_SERVER);
- server_framer_.ProcessPacket(QuicEncryptedPacket(
- encrypted->encrypted_buffer, encrypted->encrypted_length));
-}
-
-TEST_P(QuicPacketCreatorTest, SerializePathChallengeProbePacket) {
- if (!VersionHasIetfQuicFrames(creator_.transport_version())) {
- return;
- }
- QuicPathFrameBuffer payload = {
- {0xde, 0xad, 0xbe, 0xef, 0xba, 0xdc, 0x0f, 0xee}};
-
- creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
-
- std::unique_ptr<SerializedPacket> encrypted(
- creator_.SerializePathChallengeConnectivityProbingPacket(payload));
- {
- InSequence s;
- EXPECT_CALL(framer_visitor_, OnPacket());
- EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_));
- EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_));
- EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_, _));
- EXPECT_CALL(framer_visitor_, OnPacketHeader(_));
- EXPECT_CALL(framer_visitor_, OnPathChallengeFrame(_));
- EXPECT_CALL(framer_visitor_, OnPaddingFrame(_));
- EXPECT_CALL(framer_visitor_, OnPacketComplete());
- }
- // QuicFramerPeer::SetPerspective(&client_framer_, Perspective::IS_SERVER);
- server_framer_.ProcessPacket(QuicEncryptedPacket(
- encrypted->encrypted_buffer, encrypted->encrypted_length));
-}
-
-TEST_P(QuicPacketCreatorTest, SerializePathResponseProbePacket1PayloadPadded) {
- if (!VersionHasIetfQuicFrames(creator_.transport_version())) {
- return;
- }
- QuicPathFrameBuffer payload0 = {
- {0xde, 0xad, 0xbe, 0xef, 0xba, 0xdc, 0x0f, 0xee}};
-
- creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
-
- quiche::QuicheCircularDeque<QuicPathFrameBuffer> payloads;
- payloads.push_back(payload0);
-
- std::unique_ptr<SerializedPacket> encrypted(
- creator_.SerializePathResponseConnectivityProbingPacket(payloads, true));
- {
- InSequence s;
- EXPECT_CALL(framer_visitor_, OnPacket());
- EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_));
- EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_));
- EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_, _));
- EXPECT_CALL(framer_visitor_, OnPacketHeader(_));
- EXPECT_CALL(framer_visitor_, OnPathResponseFrame(_));
- EXPECT_CALL(framer_visitor_, OnPaddingFrame(_));
- EXPECT_CALL(framer_visitor_, OnPacketComplete());
- }
- server_framer_.ProcessPacket(QuicEncryptedPacket(
- encrypted->encrypted_buffer, encrypted->encrypted_length));
-}
-
-TEST_P(QuicPacketCreatorTest,
- SerializePathResponseProbePacket1PayloadUnPadded) {
- if (!VersionHasIetfQuicFrames(creator_.transport_version())) {
- return;
- }
- QuicPathFrameBuffer payload0 = {
- {0xde, 0xad, 0xbe, 0xef, 0xba, 0xdc, 0x0f, 0xee}};
-
- creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
-
- quiche::QuicheCircularDeque<QuicPathFrameBuffer> payloads;
- payloads.push_back(payload0);
-
- std::unique_ptr<SerializedPacket> encrypted(
- creator_.SerializePathResponseConnectivityProbingPacket(payloads, false));
- {
- InSequence s;
- EXPECT_CALL(framer_visitor_, OnPacket());
- EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_));
- EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_));
- EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_, _));
- EXPECT_CALL(framer_visitor_, OnPacketHeader(_));
- EXPECT_CALL(framer_visitor_, OnPathResponseFrame(_));
- EXPECT_CALL(framer_visitor_, OnPacketComplete());
- }
- server_framer_.ProcessPacket(QuicEncryptedPacket(
- encrypted->encrypted_buffer, encrypted->encrypted_length));
-}
-
-TEST_P(QuicPacketCreatorTest, SerializePathResponseProbePacket2PayloadsPadded) {
- if (!VersionHasIetfQuicFrames(creator_.transport_version())) {
- return;
- }
- QuicPathFrameBuffer payload0 = {
- {0xde, 0xad, 0xbe, 0xef, 0xba, 0xdc, 0x0f, 0xee}};
- QuicPathFrameBuffer payload1 = {
- {0xad, 0xbe, 0xef, 0xba, 0xdc, 0x0f, 0xee, 0xde}};
-
- creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
-
- quiche::QuicheCircularDeque<QuicPathFrameBuffer> payloads;
- payloads.push_back(payload0);
- payloads.push_back(payload1);
-
- std::unique_ptr<SerializedPacket> encrypted(
- creator_.SerializePathResponseConnectivityProbingPacket(payloads, true));
- {
- InSequence s;
- EXPECT_CALL(framer_visitor_, OnPacket());
- EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_));
- EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_));
- EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_, _));
- EXPECT_CALL(framer_visitor_, OnPacketHeader(_));
- EXPECT_CALL(framer_visitor_, OnPathResponseFrame(_)).Times(2);
- EXPECT_CALL(framer_visitor_, OnPaddingFrame(_));
- EXPECT_CALL(framer_visitor_, OnPacketComplete());
- }
- server_framer_.ProcessPacket(QuicEncryptedPacket(
- encrypted->encrypted_buffer, encrypted->encrypted_length));
-}
-
-TEST_P(QuicPacketCreatorTest,
- SerializePathResponseProbePacket2PayloadsUnPadded) {
- if (!VersionHasIetfQuicFrames(creator_.transport_version())) {
- return;
- }
- QuicPathFrameBuffer payload0 = {
- {0xde, 0xad, 0xbe, 0xef, 0xba, 0xdc, 0x0f, 0xee}};
- QuicPathFrameBuffer payload1 = {
- {0xad, 0xbe, 0xef, 0xba, 0xdc, 0x0f, 0xee, 0xde}};
-
- creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
-
- quiche::QuicheCircularDeque<QuicPathFrameBuffer> payloads;
- payloads.push_back(payload0);
- payloads.push_back(payload1);
-
- std::unique_ptr<SerializedPacket> encrypted(
- creator_.SerializePathResponseConnectivityProbingPacket(payloads, false));
- {
- InSequence s;
- EXPECT_CALL(framer_visitor_, OnPacket());
- EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_));
- EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_));
- EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_, _));
- EXPECT_CALL(framer_visitor_, OnPacketHeader(_));
- EXPECT_CALL(framer_visitor_, OnPathResponseFrame(_)).Times(2);
- EXPECT_CALL(framer_visitor_, OnPacketComplete());
- }
- server_framer_.ProcessPacket(QuicEncryptedPacket(
- encrypted->encrypted_buffer, encrypted->encrypted_length));
-}
-
-TEST_P(QuicPacketCreatorTest, SerializePathResponseProbePacket3PayloadsPadded) {
- if (!VersionHasIetfQuicFrames(creator_.transport_version())) {
- return;
- }
- QuicPathFrameBuffer payload0 = {
- {0xde, 0xad, 0xbe, 0xef, 0xba, 0xdc, 0x0f, 0xee}};
- QuicPathFrameBuffer payload1 = {
- {0xad, 0xbe, 0xef, 0xba, 0xdc, 0x0f, 0xee, 0xde}};
- QuicPathFrameBuffer payload2 = {
- {0xbe, 0xef, 0xba, 0xdc, 0x0f, 0xee, 0xde, 0xad}};
-
- creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
-
- quiche::QuicheCircularDeque<QuicPathFrameBuffer> payloads;
- payloads.push_back(payload0);
- payloads.push_back(payload1);
- payloads.push_back(payload2);
-
- std::unique_ptr<SerializedPacket> encrypted(
- creator_.SerializePathResponseConnectivityProbingPacket(payloads, true));
- {
- InSequence s;
- EXPECT_CALL(framer_visitor_, OnPacket());
- EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_));
- EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_));
- EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_, _));
- EXPECT_CALL(framer_visitor_, OnPacketHeader(_));
- EXPECT_CALL(framer_visitor_, OnPathResponseFrame(_)).Times(3);
- EXPECT_CALL(framer_visitor_, OnPaddingFrame(_));
- EXPECT_CALL(framer_visitor_, OnPacketComplete());
- }
- server_framer_.ProcessPacket(QuicEncryptedPacket(
- encrypted->encrypted_buffer, encrypted->encrypted_length));
-}
-
-TEST_P(QuicPacketCreatorTest,
- SerializePathResponseProbePacket3PayloadsUnpadded) {
- if (!VersionHasIetfQuicFrames(creator_.transport_version())) {
- return;
- }
- QuicPathFrameBuffer payload0 = {
- {0xde, 0xad, 0xbe, 0xef, 0xba, 0xdc, 0x0f, 0xee}};
- QuicPathFrameBuffer payload1 = {
- {0xad, 0xbe, 0xef, 0xba, 0xdc, 0x0f, 0xee, 0xde}};
- QuicPathFrameBuffer payload2 = {
- {0xbe, 0xef, 0xba, 0xdc, 0x0f, 0xee, 0xde, 0xad}};
-
- creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
-
- quiche::QuicheCircularDeque<QuicPathFrameBuffer> payloads;
- payloads.push_back(payload0);
- payloads.push_back(payload1);
- payloads.push_back(payload2);
-
- std::unique_ptr<SerializedPacket> encrypted(
- creator_.SerializePathResponseConnectivityProbingPacket(payloads, false));
- InSequence s;
- EXPECT_CALL(framer_visitor_, OnPacket());
- EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_));
- EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_));
- EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_, _));
- EXPECT_CALL(framer_visitor_, OnPacketHeader(_));
- EXPECT_CALL(framer_visitor_, OnPathResponseFrame(_)).Times(3);
- EXPECT_CALL(framer_visitor_, OnPacketComplete());
-
- server_framer_.ProcessPacket(QuicEncryptedPacket(
- encrypted->encrypted_buffer, encrypted->encrypted_length));
-}
-
-TEST_P(QuicPacketCreatorTest, UpdatePacketSequenceNumberLengthLeastAwaiting) {
- if (creator_.version().HasIetfInvariantHeader() &&
- !GetParam().version.SendsVariableLengthPacketNumberInLongHeader()) {
- EXPECT_EQ(PACKET_4BYTE_PACKET_NUMBER,
- QuicPacketCreatorPeer::GetPacketNumberLength(&creator_));
- creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
- } else {
- EXPECT_EQ(PACKET_1BYTE_PACKET_NUMBER,
- QuicPacketCreatorPeer::GetPacketNumberLength(&creator_));
- }
-
- QuicPacketCreatorPeer::SetPacketNumber(&creator_, 64);
- creator_.UpdatePacketNumberLength(QuicPacketNumber(2),
- 10000 / kDefaultMaxPacketSize);
- EXPECT_EQ(PACKET_1BYTE_PACKET_NUMBER,
- QuicPacketCreatorPeer::GetPacketNumberLength(&creator_));
-
- QuicPacketCreatorPeer::SetPacketNumber(&creator_, 64 * 256);
- creator_.UpdatePacketNumberLength(QuicPacketNumber(2),
- 10000 / kDefaultMaxPacketSize);
- EXPECT_EQ(PACKET_2BYTE_PACKET_NUMBER,
- QuicPacketCreatorPeer::GetPacketNumberLength(&creator_));
-
- QuicPacketCreatorPeer::SetPacketNumber(&creator_, 64 * 256 * 256);
- creator_.UpdatePacketNumberLength(QuicPacketNumber(2),
- 10000 / kDefaultMaxPacketSize);
- EXPECT_EQ(PACKET_4BYTE_PACKET_NUMBER,
- QuicPacketCreatorPeer::GetPacketNumberLength(&creator_));
-
- QuicPacketCreatorPeer::SetPacketNumber(&creator_,
- UINT64_C(64) * 256 * 256 * 256 * 256);
- creator_.UpdatePacketNumberLength(QuicPacketNumber(2),
- 10000 / kDefaultMaxPacketSize);
- EXPECT_EQ(PACKET_6BYTE_PACKET_NUMBER,
- QuicPacketCreatorPeer::GetPacketNumberLength(&creator_));
-}
-
-TEST_P(QuicPacketCreatorTest, UpdatePacketSequenceNumberLengthCwnd) {
- QuicPacketCreatorPeer::SetPacketNumber(&creator_, 1);
- if (creator_.version().HasIetfInvariantHeader() &&
- !GetParam().version.SendsVariableLengthPacketNumberInLongHeader()) {
- EXPECT_EQ(PACKET_4BYTE_PACKET_NUMBER,
- QuicPacketCreatorPeer::GetPacketNumberLength(&creator_));
- creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
- } else {
- EXPECT_EQ(PACKET_1BYTE_PACKET_NUMBER,
- QuicPacketCreatorPeer::GetPacketNumberLength(&creator_));
- }
-
- creator_.UpdatePacketNumberLength(QuicPacketNumber(1),
- 10000 / kDefaultMaxPacketSize);
- EXPECT_EQ(PACKET_1BYTE_PACKET_NUMBER,
- QuicPacketCreatorPeer::GetPacketNumberLength(&creator_));
-
- creator_.UpdatePacketNumberLength(QuicPacketNumber(1),
- 10000 * 256 / kDefaultMaxPacketSize);
- EXPECT_EQ(PACKET_2BYTE_PACKET_NUMBER,
- QuicPacketCreatorPeer::GetPacketNumberLength(&creator_));
-
- creator_.UpdatePacketNumberLength(QuicPacketNumber(1),
- 10000 * 256 * 256 / kDefaultMaxPacketSize);
- EXPECT_EQ(PACKET_4BYTE_PACKET_NUMBER,
- QuicPacketCreatorPeer::GetPacketNumberLength(&creator_));
-
- creator_.UpdatePacketNumberLength(
- QuicPacketNumber(1),
- UINT64_C(1000) * 256 * 256 * 256 * 256 / kDefaultMaxPacketSize);
- EXPECT_EQ(PACKET_6BYTE_PACKET_NUMBER,
- QuicPacketCreatorPeer::GetPacketNumberLength(&creator_));
-}
-
-TEST_P(QuicPacketCreatorTest, SkipNPacketNumbers) {
- QuicPacketCreatorPeer::SetPacketNumber(&creator_, 1);
- if (creator_.version().HasIetfInvariantHeader() &&
- !GetParam().version.SendsVariableLengthPacketNumberInLongHeader()) {
- EXPECT_EQ(PACKET_4BYTE_PACKET_NUMBER,
- QuicPacketCreatorPeer::GetPacketNumberLength(&creator_));
- creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
- } else {
- EXPECT_EQ(PACKET_1BYTE_PACKET_NUMBER,
- QuicPacketCreatorPeer::GetPacketNumberLength(&creator_));
- }
- creator_.SkipNPacketNumbers(63, QuicPacketNumber(2),
- 10000 / kDefaultMaxPacketSize);
- EXPECT_EQ(QuicPacketNumber(64), creator_.packet_number());
- EXPECT_EQ(PACKET_1BYTE_PACKET_NUMBER,
- QuicPacketCreatorPeer::GetPacketNumberLength(&creator_));
-
- creator_.SkipNPacketNumbers(64 * 255, QuicPacketNumber(2),
- 10000 / kDefaultMaxPacketSize);
- EXPECT_EQ(QuicPacketNumber(64 * 256), creator_.packet_number());
- EXPECT_EQ(PACKET_2BYTE_PACKET_NUMBER,
- QuicPacketCreatorPeer::GetPacketNumberLength(&creator_));
-
- creator_.SkipNPacketNumbers(64 * 256 * 255, QuicPacketNumber(2),
- 10000 / kDefaultMaxPacketSize);
- EXPECT_EQ(QuicPacketNumber(64 * 256 * 256), creator_.packet_number());
- EXPECT_EQ(PACKET_4BYTE_PACKET_NUMBER,
- QuicPacketCreatorPeer::GetPacketNumberLength(&creator_));
-}
-
-TEST_P(QuicPacketCreatorTest, SerializeFrame) {
- if (!GetParam().version_serialization) {
- creator_.StopSendingVersion();
- }
- std::string data("test data");
- if (!QuicVersionUsesCryptoFrames(client_framer_.transport_version())) {
- QuicStreamFrame stream_frame(
- QuicUtils::GetCryptoStreamId(client_framer_.transport_version()),
- /*fin=*/false, 0u, absl::string_view());
- frames_.push_back(QuicFrame(stream_frame));
- } else {
- producer_.SaveCryptoData(ENCRYPTION_INITIAL, 0, data);
- frames_.push_back(
- QuicFrame(new QuicCryptoFrame(ENCRYPTION_INITIAL, 0, data.length())));
- }
- SerializedPacket serialized = SerializeAllFrames(frames_);
-
- QuicPacketHeader header;
- {
- InSequence s;
- EXPECT_CALL(framer_visitor_, OnPacket());
- EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_));
- EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_));
- EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_, _));
- EXPECT_CALL(framer_visitor_, OnPacketHeader(_))
- .WillOnce(DoAll(SaveArg<0>(&header), Return(true)));
- if (QuicVersionUsesCryptoFrames(client_framer_.transport_version())) {
- EXPECT_CALL(framer_visitor_, OnCryptoFrame(_));
- } else {
- EXPECT_CALL(framer_visitor_, OnStreamFrame(_));
- }
- EXPECT_CALL(framer_visitor_, OnPacketComplete());
- }
- ProcessPacket(serialized);
- EXPECT_EQ(GetParam().version_serialization, header.version_flag);
-}
-
-TEST_P(QuicPacketCreatorTest, SerializeFrameShortData) {
- if (!GetParam().version_serialization) {
- creator_.StopSendingVersion();
- }
- std::string data("Hello World!");
- if (!QuicVersionUsesCryptoFrames(client_framer_.transport_version())) {
- QuicStreamFrame stream_frame(
- QuicUtils::GetCryptoStreamId(client_framer_.transport_version()),
- /*fin=*/false, 0u, absl::string_view());
- frames_.push_back(QuicFrame(stream_frame));
- } else {
- producer_.SaveCryptoData(ENCRYPTION_INITIAL, 0, data);
- frames_.push_back(
- QuicFrame(new QuicCryptoFrame(ENCRYPTION_INITIAL, 0, data.length())));
- }
- SerializedPacket serialized = SerializeAllFrames(frames_);
-
- QuicPacketHeader header;
- {
- InSequence s;
- EXPECT_CALL(framer_visitor_, OnPacket());
- EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_));
- EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_));
- EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_, _));
- EXPECT_CALL(framer_visitor_, OnPacketHeader(_))
- .WillOnce(DoAll(SaveArg<0>(&header), Return(true)));
- if (QuicVersionUsesCryptoFrames(client_framer_.transport_version())) {
- EXPECT_CALL(framer_visitor_, OnCryptoFrame(_));
- } else {
- EXPECT_CALL(framer_visitor_, OnStreamFrame(_));
- }
- EXPECT_CALL(framer_visitor_, OnPacketComplete());
- }
- ProcessPacket(serialized);
- EXPECT_EQ(GetParam().version_serialization, header.version_flag);
-}
-
-void QuicPacketCreatorTest::TestChaosProtection(bool enabled) {
- if (!GetParam().version.UsesCryptoFrames()) {
- return;
- }
- MockRandom mock_random(2);
- QuicPacketCreatorPeer::SetRandom(&creator_, &mock_random);
- creator_.set_chaos_protection_enabled(enabled);
- std::string data("ChAoS_ThEoRy!");
- producer_.SaveCryptoData(ENCRYPTION_INITIAL, 0, data);
- frames_.push_back(
- QuicFrame(new QuicCryptoFrame(ENCRYPTION_INITIAL, 0, data.length())));
- frames_.push_back(QuicFrame(QuicPaddingFrame(33)));
- SerializedPacket serialized = SerializeAllFrames(frames_);
- EXPECT_CALL(framer_visitor_, OnPacket());
- EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_));
- EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_));
- EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_, _));
- EXPECT_CALL(framer_visitor_, OnPacketHeader(_));
- if (enabled) {
- EXPECT_CALL(framer_visitor_, OnCryptoFrame(_)).Times(AtLeast(2));
- EXPECT_CALL(framer_visitor_, OnPaddingFrame(_)).Times(AtLeast(2));
- EXPECT_CALL(framer_visitor_, OnPingFrame(_)).Times(AtLeast(1));
- } else {
- EXPECT_CALL(framer_visitor_, OnCryptoFrame(_)).Times(1);
- EXPECT_CALL(framer_visitor_, OnPaddingFrame(_)).Times(1);
- EXPECT_CALL(framer_visitor_, OnPingFrame(_)).Times(0);
- }
- EXPECT_CALL(framer_visitor_, OnPacketComplete());
- ProcessPacket(serialized);
-}
-
-TEST_P(QuicPacketCreatorTest, ChaosProtectionEnabled) {
- TestChaosProtection(/*enabled=*/true);
-}
-
-TEST_P(QuicPacketCreatorTest, ChaosProtectionDisabled) {
- TestChaosProtection(/*enabled=*/false);
-}
-
-TEST_P(QuicPacketCreatorTest, ConsumeDataLargerThanOneStreamFrame) {
- if (!GetParam().version_serialization) {
- creator_.StopSendingVersion();
- }
- creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
- // A string larger than fits into a frame.
- QuicFrame frame;
- size_t payload_length = creator_.max_packet_length();
- const std::string too_long_payload(payload_length, 'a');
- MakeIOVector(too_long_payload, &iov_);
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .WillOnce(Invoke(this, &QuicPacketCreatorTest::SaveSerializedPacket));
- QuicStreamId stream_id = QuicUtils::GetFirstBidirectionalStreamId(
- client_framer_.transport_version(), Perspective::IS_CLIENT);
- ASSERT_TRUE(creator_.ConsumeDataToFillCurrentPacket(
- stream_id, &iov_, 1u, iov_.iov_len, 0u, 0u, true, false,
- NOT_RETRANSMISSION, &frame));
- size_t consumed = frame.stream_frame.data_length;
- // The entire payload could not be consumed.
- EXPECT_GT(payload_length, consumed);
- creator_.FlushCurrentPacket();
- DeleteSerializedPacket();
-}
-
-TEST_P(QuicPacketCreatorTest, AddFrameAndFlush) {
- if (!GetParam().version_serialization) {
- creator_.StopSendingVersion();
- }
- const size_t max_plaintext_size =
- client_framer_.GetMaxPlaintextSize(creator_.max_packet_length());
- EXPECT_FALSE(creator_.HasPendingFrames());
- creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
- QuicStreamId stream_id = QuicUtils::GetFirstBidirectionalStreamId(
- client_framer_.transport_version(), Perspective::IS_CLIENT);
- if (!QuicVersionUsesCryptoFrames(client_framer_.transport_version())) {
- stream_id =
- QuicUtils::GetCryptoStreamId(client_framer_.transport_version());
- }
- EXPECT_FALSE(creator_.HasPendingStreamFramesOfStream(stream_id));
- EXPECT_EQ(max_plaintext_size -
- GetPacketHeaderSize(
- client_framer_.transport_version(),
- creator_.GetDestinationConnectionIdLength(),
- creator_.GetSourceConnectionIdLength(),
- QuicPacketCreatorPeer::SendVersionInPacket(&creator_),
- !kIncludeDiversificationNonce,
- QuicPacketCreatorPeer::GetPacketNumberLength(&creator_),
- QuicPacketCreatorPeer::GetRetryTokenLengthLength(&creator_),
- 0, QuicPacketCreatorPeer::GetLengthLength(&creator_)),
- creator_.BytesFree());
- StrictMock<MockDebugDelegate> debug;
- creator_.set_debug_delegate(&debug);
-
- // Add a variety of frame types and then a padding frame.
- QuicAckFrame ack_frame(InitAckFrame(10u));
- EXPECT_CALL(debug, OnFrameAddedToPacket(_));
- EXPECT_TRUE(creator_.AddFrame(QuicFrame(&ack_frame), NOT_RETRANSMISSION));
- EXPECT_TRUE(creator_.HasPendingFrames());
- EXPECT_FALSE(creator_.HasPendingStreamFramesOfStream(stream_id));
-
- QuicFrame frame;
- MakeIOVector("test", &iov_);
- EXPECT_CALL(debug, OnFrameAddedToPacket(_));
- ASSERT_TRUE(creator_.ConsumeDataToFillCurrentPacket(
- stream_id, &iov_, 1u, iov_.iov_len, 0u, 0u, false, false,
- NOT_RETRANSMISSION, &frame));
- size_t consumed = frame.stream_frame.data_length;
- EXPECT_EQ(4u, consumed);
- EXPECT_TRUE(creator_.HasPendingFrames());
- EXPECT_TRUE(creator_.HasPendingStreamFramesOfStream(stream_id));
-
- QuicPaddingFrame padding_frame;
- EXPECT_CALL(debug, OnFrameAddedToPacket(_));
- EXPECT_TRUE(creator_.AddFrame(QuicFrame(padding_frame), NOT_RETRANSMISSION));
- EXPECT_TRUE(creator_.HasPendingFrames());
- EXPECT_EQ(0u, creator_.BytesFree());
-
- // Packet is full. Creator will flush.
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .WillOnce(Invoke(this, &QuicPacketCreatorTest::SaveSerializedPacket));
- EXPECT_FALSE(creator_.AddFrame(QuicFrame(&ack_frame), NOT_RETRANSMISSION));
-
- // Ensure the packet is successfully created.
- ASSERT_TRUE(serialized_packet_->encrypted_buffer);
- ASSERT_FALSE(serialized_packet_->retransmittable_frames.empty());
- const QuicFrames& retransmittable =
- serialized_packet_->retransmittable_frames;
- ASSERT_EQ(1u, retransmittable.size());
- EXPECT_EQ(STREAM_FRAME, retransmittable[0].type);
- EXPECT_TRUE(serialized_packet_->has_ack);
- EXPECT_EQ(QuicPacketNumber(10u), serialized_packet_->largest_acked);
- DeleteSerializedPacket();
-
- EXPECT_FALSE(creator_.HasPendingFrames());
- EXPECT_FALSE(creator_.HasPendingStreamFramesOfStream(stream_id));
- EXPECT_EQ(max_plaintext_size -
- GetPacketHeaderSize(
- client_framer_.transport_version(),
- creator_.GetDestinationConnectionIdLength(),
- creator_.GetSourceConnectionIdLength(),
- QuicPacketCreatorPeer::SendVersionInPacket(&creator_),
- !kIncludeDiversificationNonce,
- QuicPacketCreatorPeer::GetPacketNumberLength(&creator_),
- QuicPacketCreatorPeer::GetRetryTokenLengthLength(&creator_),
- 0, QuicPacketCreatorPeer::GetLengthLength(&creator_)),
- creator_.BytesFree());
-}
-
-TEST_P(QuicPacketCreatorTest, SerializeAndSendStreamFrame) {
- creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
- if (!GetParam().version_serialization) {
- creator_.StopSendingVersion();
- }
- EXPECT_FALSE(creator_.HasPendingFrames());
-
- MakeIOVector("test", &iov_);
- producer_.SaveStreamData(GetNthClientInitiatedStreamId(0), &iov_, 1u, 0u,
- iov_.iov_len);
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .WillOnce(Invoke(this, &QuicPacketCreatorTest::SaveSerializedPacket));
- size_t num_bytes_consumed;
- StrictMock<MockDebugDelegate> debug;
- creator_.set_debug_delegate(&debug);
- EXPECT_CALL(debug, OnFrameAddedToPacket(_));
- creator_.CreateAndSerializeStreamFrame(
- GetNthClientInitiatedStreamId(0), iov_.iov_len, 0, 0, true,
- NOT_RETRANSMISSION, &num_bytes_consumed);
- EXPECT_EQ(4u, num_bytes_consumed);
-
- // Ensure the packet is successfully created.
- ASSERT_TRUE(serialized_packet_->encrypted_buffer);
- ASSERT_FALSE(serialized_packet_->retransmittable_frames.empty());
- const QuicFrames& retransmittable =
- serialized_packet_->retransmittable_frames;
- ASSERT_EQ(1u, retransmittable.size());
- EXPECT_EQ(STREAM_FRAME, retransmittable[0].type);
- DeleteSerializedPacket();
-
- EXPECT_FALSE(creator_.HasPendingFrames());
-}
-
-TEST_P(QuicPacketCreatorTest, SerializeStreamFrameWithPadding) {
- // Regression test to check that CreateAndSerializeStreamFrame uses a
- // correctly formatted stream frame header when appending padding.
-
- creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
- if (!GetParam().version_serialization) {
- creator_.StopSendingVersion();
- }
- EXPECT_FALSE(creator_.HasPendingFrames());
-
- // Send one byte of stream data.
- MakeIOVector("a", &iov_);
- producer_.SaveStreamData(GetNthClientInitiatedStreamId(0), &iov_, 1u, 0u,
- iov_.iov_len);
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .WillOnce(Invoke(this, &QuicPacketCreatorTest::SaveSerializedPacket));
- size_t num_bytes_consumed;
- creator_.CreateAndSerializeStreamFrame(
- GetNthClientInitiatedStreamId(0), iov_.iov_len, 0, 0, true,
- NOT_RETRANSMISSION, &num_bytes_consumed);
- EXPECT_EQ(1u, num_bytes_consumed);
-
- // Check that a packet is created.
- ASSERT_TRUE(serialized_packet_->encrypted_buffer);
- ASSERT_FALSE(serialized_packet_->retransmittable_frames.empty());
- {
- InSequence s;
- EXPECT_CALL(framer_visitor_, OnPacket());
- EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_));
- EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_));
- EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_, _));
- EXPECT_CALL(framer_visitor_, OnPacketHeader(_));
- EXPECT_CALL(framer_visitor_, OnStreamFrame(_));
- if (client_framer_.version().HasHeaderProtection()) {
- EXPECT_CALL(framer_visitor_, OnPaddingFrame(_));
- }
- EXPECT_CALL(framer_visitor_, OnPacketComplete());
- }
- ProcessPacket(*serialized_packet_);
-}
-
-TEST_P(QuicPacketCreatorTest, AddUnencryptedStreamDataClosesConnection) {
- // EXPECT_QUIC_BUG tests are expensive so only run one instance of them.
- if (!IsDefaultTestConfiguration()) {
- return;
- }
-
- 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),
- "Cannot send stream data with level: ENCRYPTION_INITIAL");
-}
-
-TEST_P(QuicPacketCreatorTest, SendStreamDataWithEncryptionHandshake) {
- // EXPECT_QUIC_BUG tests are expensive so only run one instance of them.
- if (!IsDefaultTestConfiguration()) {
- return;
- }
-
- 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),
- "Cannot send stream data with level: ENCRYPTION_HANDSHAKE");
-}
-
-TEST_P(QuicPacketCreatorTest, ChloTooLarge) {
- // EXPECT_QUIC_BUG tests are expensive so only run one instance of them.
- if (!IsDefaultTestConfiguration()) {
- return;
- }
-
- // This test only matters when the crypto handshake is sent in stream frames.
- // TODO(b/128596274): Re-enable when this check is supported for CRYPTO
- // frames.
- if (QuicVersionUsesCryptoFrames(client_framer_.transport_version())) {
- return;
- }
-
- CryptoHandshakeMessage message;
- message.set_tag(kCHLO);
- message.set_minimum_size(kMaxOutgoingPacketSize);
- CryptoFramer framer;
- std::unique_ptr<QuicData> message_data;
- message_data = framer.ConstructHandshakeMessage(message);
-
- struct iovec iov;
- MakeIOVector(absl::string_view(message_data->data(), message_data->length()),
- &iov);
- QuicFrame frame;
- EXPECT_CALL(delegate_, OnUnrecoverableError(QUIC_CRYPTO_CHLO_TOO_LARGE, _));
- EXPECT_QUIC_BUG(
- creator_.ConsumeDataToFillCurrentPacket(
- QuicUtils::GetCryptoStreamId(client_framer_.transport_version()),
- &iov, 1u, iov.iov_len, 0u, 0u, false, false, NOT_RETRANSMISSION,
- &frame),
- "Client hello won't fit in a single packet.");
-}
-
-TEST_P(QuicPacketCreatorTest, PendingPadding) {
- EXPECT_EQ(0u, creator_.pending_padding_bytes());
- creator_.AddPendingPadding(kMaxNumRandomPaddingBytes * 10);
- EXPECT_EQ(kMaxNumRandomPaddingBytes * 10, creator_.pending_padding_bytes());
-
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .WillRepeatedly(
- Invoke(this, &QuicPacketCreatorTest::SaveSerializedPacket));
- // Flush all paddings.
- while (creator_.pending_padding_bytes() > 0) {
- creator_.FlushCurrentPacket();
- {
- InSequence s;
- EXPECT_CALL(framer_visitor_, OnPacket());
- EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_));
- EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_));
- EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_, _));
- EXPECT_CALL(framer_visitor_, OnPacketHeader(_));
- EXPECT_CALL(framer_visitor_, OnPaddingFrame(_));
- EXPECT_CALL(framer_visitor_, OnPacketComplete());
- }
- // Packet only contains padding.
- ProcessPacket(*serialized_packet_);
- }
- EXPECT_EQ(0u, creator_.pending_padding_bytes());
-}
-
-TEST_P(QuicPacketCreatorTest, FullPaddingDoesNotConsumePendingPadding) {
- creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
- creator_.AddPendingPadding(kMaxNumRandomPaddingBytes);
- QuicFrame frame;
- MakeIOVector("test", &iov_);
- QuicStreamId stream_id = QuicUtils::GetFirstBidirectionalStreamId(
- client_framer_.transport_version(), Perspective::IS_CLIENT);
- ASSERT_TRUE(creator_.ConsumeDataToFillCurrentPacket(
- stream_id, &iov_, 1u, iov_.iov_len, 0u, 0u, false,
- /*needs_full_padding=*/true, NOT_RETRANSMISSION, &frame));
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .WillOnce(Invoke(this, &QuicPacketCreatorTest::SaveSerializedPacket));
- creator_.FlushCurrentPacket();
- EXPECT_EQ(kMaxNumRandomPaddingBytes, creator_.pending_padding_bytes());
-}
-
-TEST_P(QuicPacketCreatorTest, ConsumeDataAndRandomPadding) {
- creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
- const QuicByteCount kStreamFramePayloadSize = 100u;
- // Set the packet size be enough for one stream frame with 0 stream offset +
- // 1.
- QuicStreamId stream_id = QuicUtils::GetFirstBidirectionalStreamId(
- client_framer_.transport_version(), Perspective::IS_CLIENT);
- size_t length =
- GetPacketHeaderOverhead(client_framer_.transport_version()) +
- GetEncryptionOverhead() +
- QuicFramer::GetMinStreamFrameSize(
- client_framer_.transport_version(), stream_id, 0,
- /*last_frame_in_packet=*/false, kStreamFramePayloadSize + 1) +
- kStreamFramePayloadSize + 1;
- creator_.SetMaxPacketLength(length);
- creator_.AddPendingPadding(kMaxNumRandomPaddingBytes);
- QuicByteCount pending_padding_bytes = creator_.pending_padding_bytes();
- QuicFrame frame;
- char buf[kStreamFramePayloadSize + 1] = {};
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .WillRepeatedly(
- Invoke(this, &QuicPacketCreatorTest::SaveSerializedPacket));
- // Send stream frame of size kStreamFramePayloadSize.
- MakeIOVector(absl::string_view(buf, kStreamFramePayloadSize), &iov_);
- creator_.ConsumeDataToFillCurrentPacket(stream_id, &iov_, 1u, iov_.iov_len,
- 0u, 0u, false, false,
- NOT_RETRANSMISSION, &frame);
- creator_.FlushCurrentPacket();
- // 1 byte padding is sent.
- EXPECT_EQ(pending_padding_bytes - 1, creator_.pending_padding_bytes());
- // Send stream frame of size kStreamFramePayloadSize + 1.
- MakeIOVector(absl::string_view(buf, kStreamFramePayloadSize + 1), &iov_);
- creator_.ConsumeDataToFillCurrentPacket(stream_id, &iov_, 1u, iov_.iov_len,
- 0u, kStreamFramePayloadSize, false,
- false, NOT_RETRANSMISSION, &frame);
- // No padding is sent.
- creator_.FlushCurrentPacket();
- EXPECT_EQ(pending_padding_bytes - 1, creator_.pending_padding_bytes());
- // Flush all paddings.
- while (creator_.pending_padding_bytes() > 0) {
- creator_.FlushCurrentPacket();
- }
- EXPECT_EQ(0u, creator_.pending_padding_bytes());
-}
-
-TEST_P(QuicPacketCreatorTest, FlushWithExternalBuffer) {
- creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
- char* buffer = new char[kMaxOutgoingPacketSize];
- QuicPacketBuffer external_buffer = {buffer,
- [](const char* p) { delete[] p; }};
- EXPECT_CALL(delegate_, GetPacketBuffer()).WillOnce(Return(external_buffer));
-
- QuicFrame frame;
- MakeIOVector("test", &iov_);
- QuicStreamId stream_id = QuicUtils::GetFirstBidirectionalStreamId(
- client_framer_.transport_version(), Perspective::IS_CLIENT);
- ASSERT_TRUE(creator_.ConsumeDataToFillCurrentPacket(
- stream_id, &iov_, 1u, iov_.iov_len, 0u, 0u, false,
- /*needs_full_padding=*/true, NOT_RETRANSMISSION, &frame));
-
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .WillOnce(Invoke([&external_buffer](SerializedPacket serialized_packet) {
- EXPECT_EQ(external_buffer.buffer, serialized_packet.encrypted_buffer);
- }));
- creator_.FlushCurrentPacket();
-}
-
-// Test for error found in
-// https://bugs.chromium.org/p/chromium/issues/detail?id=859949 where a gap
-// length that crosses an IETF VarInt length boundary would cause a
-// failure. While this test is not applicable to versions other than version 99,
-// it should still work. Hence, it is not made version-specific.
-TEST_P(QuicPacketCreatorTest, IetfAckGapErrorRegression) {
- QuicAckFrame ack_frame =
- InitAckFrame({{QuicPacketNumber(60), QuicPacketNumber(61)},
- {QuicPacketNumber(125), QuicPacketNumber(126)}});
- frames_.push_back(QuicFrame(&ack_frame));
- SerializeAllFrames(frames_);
-}
-
-TEST_P(QuicPacketCreatorTest, AddMessageFrame) {
- if (!VersionSupportsMessageFrames(client_framer_.transport_version())) {
- return;
- }
- if (client_framer_.version().UsesTls()) {
- creator_.SetMaxDatagramFrameSize(kMaxAcceptedDatagramFrameSize);
- }
- creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .Times(3)
- .WillRepeatedly(
- Invoke(this, &QuicPacketCreatorTest::ClearSerializedPacketForTests));
- // Verify that there is enough room for the largest message payload.
- EXPECT_TRUE(creator_.HasRoomForMessageFrame(
- creator_.GetCurrentLargestMessagePayload()));
- std::string large_message(creator_.GetCurrentLargestMessagePayload(), 'a');
- QuicMessageFrame* message_frame =
- new QuicMessageFrame(1, MemSliceFromString(large_message));
- EXPECT_TRUE(creator_.AddFrame(QuicFrame(message_frame), NOT_RETRANSMISSION));
- EXPECT_TRUE(creator_.HasPendingFrames());
- creator_.FlushCurrentPacket();
-
- QuicMessageFrame* frame2 =
- new QuicMessageFrame(2, MemSliceFromString("message"));
- EXPECT_TRUE(creator_.AddFrame(QuicFrame(frame2), NOT_RETRANSMISSION));
- EXPECT_TRUE(creator_.HasPendingFrames());
- // Verify if a new frame is added, 1 byte message length will be added.
- EXPECT_EQ(1u, creator_.ExpansionOnNewFrame());
- QuicMessageFrame* frame3 =
- new QuicMessageFrame(3, MemSliceFromString("message2"));
- EXPECT_TRUE(creator_.AddFrame(QuicFrame(frame3), NOT_RETRANSMISSION));
- EXPECT_EQ(1u, creator_.ExpansionOnNewFrame());
- creator_.FlushCurrentPacket();
-
- QuicFrame frame;
- MakeIOVector("test", &iov_);
- QuicStreamId stream_id = QuicUtils::GetFirstBidirectionalStreamId(
- client_framer_.transport_version(), Perspective::IS_CLIENT);
- EXPECT_TRUE(creator_.ConsumeDataToFillCurrentPacket(
- stream_id, &iov_, 1u, iov_.iov_len, 0u, 0u, false, false,
- NOT_RETRANSMISSION, &frame));
- QuicMessageFrame* frame4 =
- new QuicMessageFrame(4, MemSliceFromString("message"));
- EXPECT_TRUE(creator_.AddFrame(QuicFrame(frame4), NOT_RETRANSMISSION));
- EXPECT_TRUE(creator_.HasPendingFrames());
- // Verify there is not enough room for largest payload.
- EXPECT_FALSE(creator_.HasRoomForMessageFrame(
- creator_.GetCurrentLargestMessagePayload()));
- // Add largest message will causes the flush of the stream frame.
- QuicMessageFrame frame5(5, MemSliceFromString(large_message));
- EXPECT_FALSE(creator_.AddFrame(QuicFrame(&frame5), NOT_RETRANSMISSION));
- EXPECT_FALSE(creator_.HasPendingFrames());
-}
-
-TEST_P(QuicPacketCreatorTest, MessageFrameConsumption) {
- if (!VersionSupportsMessageFrames(client_framer_.transport_version())) {
- return;
- }
- if (client_framer_.version().UsesTls()) {
- creator_.SetMaxDatagramFrameSize(kMaxAcceptedDatagramFrameSize);
- }
- std::string message_data(kDefaultMaxPacketSize, 'a');
- // Test all possible encryption levels of message frames.
- for (EncryptionLevel level :
- {ENCRYPTION_ZERO_RTT, ENCRYPTION_FORWARD_SECURE}) {
- creator_.set_encryption_level(level);
- // Test all possible sizes of message frames.
- for (size_t message_size = 0;
- message_size <= creator_.GetCurrentLargestMessagePayload();
- ++message_size) {
- QuicMessageFrame* frame =
- new QuicMessageFrame(0, MemSliceFromString(absl::string_view(
- message_data.data(), message_size)));
- EXPECT_TRUE(creator_.AddFrame(QuicFrame(frame), NOT_RETRANSMISSION));
- EXPECT_TRUE(creator_.HasPendingFrames());
-
- size_t expansion_bytes = message_size >= 64 ? 2 : 1;
- EXPECT_EQ(expansion_bytes, creator_.ExpansionOnNewFrame());
- // Verify BytesFree returns bytes available for the next frame, which
- // should subtract the message length.
- size_t expected_bytes_free =
- creator_.GetCurrentLargestMessagePayload() - message_size <
- expansion_bytes
- ? 0
- : creator_.GetCurrentLargestMessagePayload() - expansion_bytes -
- message_size;
- EXPECT_EQ(expected_bytes_free, creator_.BytesFree());
- EXPECT_LE(creator_.GetGuaranteedLargestMessagePayload(),
- creator_.GetCurrentLargestMessagePayload());
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .WillOnce(Invoke(this, &QuicPacketCreatorTest::SaveSerializedPacket));
- creator_.FlushCurrentPacket();
- ASSERT_TRUE(serialized_packet_->encrypted_buffer);
- DeleteSerializedPacket();
- }
- }
-}
-
-TEST_P(QuicPacketCreatorTest, GetGuaranteedLargestMessagePayload) {
- ParsedQuicVersion version = GetParam().version;
- if (!version.SupportsMessageFrames()) {
- return;
- }
- if (version.UsesTls()) {
- creator_.SetMaxDatagramFrameSize(kMaxAcceptedDatagramFrameSize);
- }
- QuicPacketLength expected_largest_payload = 1219;
- if (version.HasLongHeaderLengths()) {
- expected_largest_payload -= 2;
- }
- if (version.HasLengthPrefixedConnectionIds()) {
- expected_largest_payload -= 1;
- }
- EXPECT_EQ(expected_largest_payload,
- creator_.GetGuaranteedLargestMessagePayload());
- EXPECT_TRUE(creator_.HasRoomForMessageFrame(
- creator_.GetGuaranteedLargestMessagePayload()));
-
- // Now test whether SetMaxDatagramFrameSize works.
- creator_.SetMaxDatagramFrameSize(expected_largest_payload + 1 +
- kQuicFrameTypeSize);
- EXPECT_EQ(expected_largest_payload,
- creator_.GetGuaranteedLargestMessagePayload());
- EXPECT_TRUE(creator_.HasRoomForMessageFrame(
- creator_.GetGuaranteedLargestMessagePayload()));
-
- creator_.SetMaxDatagramFrameSize(expected_largest_payload +
- kQuicFrameTypeSize);
- EXPECT_EQ(expected_largest_payload,
- creator_.GetGuaranteedLargestMessagePayload());
- EXPECT_TRUE(creator_.HasRoomForMessageFrame(
- creator_.GetGuaranteedLargestMessagePayload()));
-
- creator_.SetMaxDatagramFrameSize(expected_largest_payload - 1 +
- kQuicFrameTypeSize);
- EXPECT_EQ(expected_largest_payload - 1,
- creator_.GetGuaranteedLargestMessagePayload());
- EXPECT_TRUE(creator_.HasRoomForMessageFrame(
- creator_.GetGuaranteedLargestMessagePayload()));
-
- constexpr QuicPacketLength kFrameSizeLimit = 1000;
- constexpr QuicPacketLength kPayloadSizeLimit =
- kFrameSizeLimit - kQuicFrameTypeSize;
- creator_.SetMaxDatagramFrameSize(kFrameSizeLimit);
- EXPECT_EQ(creator_.GetGuaranteedLargestMessagePayload(), kPayloadSizeLimit);
- EXPECT_TRUE(creator_.HasRoomForMessageFrame(kPayloadSizeLimit));
- EXPECT_FALSE(creator_.HasRoomForMessageFrame(kPayloadSizeLimit + 1));
-}
-
-TEST_P(QuicPacketCreatorTest, GetCurrentLargestMessagePayload) {
- ParsedQuicVersion version = GetParam().version;
- if (!version.SupportsMessageFrames()) {
- return;
- }
- if (version.UsesTls()) {
- creator_.SetMaxDatagramFrameSize(kMaxAcceptedDatagramFrameSize);
- }
- QuicPacketLength expected_largest_payload = 1219;
- if (version.SendsVariableLengthPacketNumberInLongHeader()) {
- expected_largest_payload += 3;
- }
- if (version.HasLongHeaderLengths()) {
- expected_largest_payload -= 2;
- }
- if (version.HasLengthPrefixedConnectionIds()) {
- expected_largest_payload -= 1;
- }
- EXPECT_EQ(expected_largest_payload,
- creator_.GetCurrentLargestMessagePayload());
-
- // Now test whether SetMaxDatagramFrameSize works.
- creator_.SetMaxDatagramFrameSize(expected_largest_payload + 1 +
- kQuicFrameTypeSize);
- EXPECT_EQ(expected_largest_payload,
- creator_.GetCurrentLargestMessagePayload());
-
- creator_.SetMaxDatagramFrameSize(expected_largest_payload +
- kQuicFrameTypeSize);
- EXPECT_EQ(expected_largest_payload,
- creator_.GetCurrentLargestMessagePayload());
-
- creator_.SetMaxDatagramFrameSize(expected_largest_payload - 1 +
- kQuicFrameTypeSize);
- EXPECT_EQ(expected_largest_payload - 1,
- creator_.GetCurrentLargestMessagePayload());
-}
-
-TEST_P(QuicPacketCreatorTest, PacketTransmissionType) {
- creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
-
- QuicAckFrame temp_ack_frame = InitAckFrame(1);
- QuicFrame ack_frame(&temp_ack_frame);
- ASSERT_FALSE(QuicUtils::IsRetransmittableFrame(ack_frame.type));
-
- QuicStreamId stream_id = QuicUtils::GetFirstBidirectionalStreamId(
- client_framer_.transport_version(), Perspective::IS_CLIENT);
- QuicFrame stream_frame(QuicStreamFrame(stream_id,
- /*fin=*/false, 0u,
- absl::string_view()));
- ASSERT_TRUE(QuicUtils::IsRetransmittableFrame(stream_frame.type));
-
- QuicFrame padding_frame{QuicPaddingFrame()};
- ASSERT_FALSE(QuicUtils::IsRetransmittableFrame(padding_frame.type));
-
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .WillOnce(Invoke(this, &QuicPacketCreatorTest::SaveSerializedPacket));
-
- EXPECT_TRUE(creator_.AddFrame(ack_frame, LOSS_RETRANSMISSION));
- ASSERT_EQ(serialized_packet_, nullptr);
-
- EXPECT_TRUE(creator_.AddFrame(stream_frame, RTO_RETRANSMISSION));
- ASSERT_EQ(serialized_packet_, nullptr);
-
- EXPECT_TRUE(creator_.AddFrame(padding_frame, TLP_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);
- DeleteSerializedPacket();
-}
-
-TEST_P(QuicPacketCreatorTest, RetryToken) {
- if (!GetParam().version_serialization ||
- !QuicVersionHasLongHeaderLengths(client_framer_.transport_version())) {
- return;
- }
-
- char retry_token_bytes[] = {1, 2, 3, 4, 5, 6, 7, 8,
- 9, 10, 11, 12, 13, 14, 15, 16};
-
- creator_.SetRetryToken(
- std::string(retry_token_bytes, sizeof(retry_token_bytes)));
-
- frames_.push_back(QuicFrame(QuicPingFrame()));
- SerializedPacket serialized = SerializeAllFrames(frames_);
-
- QuicPacketHeader header;
- {
- InSequence s;
- EXPECT_CALL(framer_visitor_, OnPacket());
- EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_));
- EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_));
- EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_, _));
- EXPECT_CALL(framer_visitor_, OnPacketHeader(_))
- .WillOnce(DoAll(SaveArg<0>(&header), Return(true)));
- EXPECT_CALL(framer_visitor_, OnPingFrame(_));
- if (client_framer_.version().HasHeaderProtection()) {
- EXPECT_CALL(framer_visitor_, OnPaddingFrame(_));
- }
- EXPECT_CALL(framer_visitor_, OnPacketComplete());
- }
- ProcessPacket(serialized);
- ASSERT_TRUE(header.version_flag);
- ASSERT_EQ(header.long_packet_type, INITIAL);
- ASSERT_EQ(header.retry_token.length(), sizeof(retry_token_bytes));
- quiche::test::CompareCharArraysWithHexError(
- "retry token", header.retry_token.data(), header.retry_token.length(),
- retry_token_bytes, sizeof(retry_token_bytes));
-}
-
-TEST_P(QuicPacketCreatorTest, GetConnectionId) {
- EXPECT_EQ(TestConnectionId(2), creator_.GetDestinationConnectionId());
- EXPECT_EQ(EmptyQuicConnectionId(), creator_.GetSourceConnectionId());
-}
-
-TEST_P(QuicPacketCreatorTest, ClientConnectionId) {
- if (!client_framer_.version().SupportsClientConnectionIds()) {
- return;
- }
- EXPECT_EQ(TestConnectionId(2), creator_.GetDestinationConnectionId());
- EXPECT_EQ(EmptyQuicConnectionId(), creator_.GetSourceConnectionId());
- creator_.SetClientConnectionId(TestConnectionId(0x33));
- EXPECT_EQ(TestConnectionId(2), creator_.GetDestinationConnectionId());
- EXPECT_EQ(TestConnectionId(0x33), creator_.GetSourceConnectionId());
-}
-
-TEST_P(QuicPacketCreatorTest, CoalesceStreamFrames) {
- InSequence s;
- if (!GetParam().version_serialization) {
- creator_.StopSendingVersion();
- }
- const size_t max_plaintext_size =
- client_framer_.GetMaxPlaintextSize(creator_.max_packet_length());
- EXPECT_FALSE(creator_.HasPendingFrames());
- creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
- QuicStreamId stream_id1 = QuicUtils::GetFirstBidirectionalStreamId(
- client_framer_.transport_version(), Perspective::IS_CLIENT);
- QuicStreamId stream_id2 = GetNthClientInitiatedStreamId(1);
- EXPECT_FALSE(creator_.HasPendingStreamFramesOfStream(stream_id1));
- EXPECT_EQ(max_plaintext_size -
- GetPacketHeaderSize(
- client_framer_.transport_version(),
- creator_.GetDestinationConnectionIdLength(),
- creator_.GetSourceConnectionIdLength(),
- QuicPacketCreatorPeer::SendVersionInPacket(&creator_),
- !kIncludeDiversificationNonce,
- QuicPacketCreatorPeer::GetPacketNumberLength(&creator_),
- QuicPacketCreatorPeer::GetRetryTokenLengthLength(&creator_),
- 0, QuicPacketCreatorPeer::GetLengthLength(&creator_)),
- creator_.BytesFree());
- StrictMock<MockDebugDelegate> debug;
- creator_.set_debug_delegate(&debug);
-
- MakeIOVector("test", &iov_);
- QuicFrame frame;
- EXPECT_CALL(debug, OnFrameAddedToPacket(_));
- ASSERT_TRUE(creator_.ConsumeDataToFillCurrentPacket(
- stream_id1, &iov_, 1u, iov_.iov_len, 0u, 0u, false, false,
- NOT_RETRANSMISSION, &frame));
- EXPECT_TRUE(creator_.HasPendingFrames());
- EXPECT_TRUE(creator_.HasPendingStreamFramesOfStream(stream_id1));
-
- MakeIOVector("coalesce", &iov_);
- // frame will be coalesced with the first frame.
- const auto previous_size = creator_.PacketSize();
- QuicStreamFrame target(stream_id1, true, 0, 12);
- EXPECT_CALL(debug, OnStreamFrameCoalesced(target));
- ASSERT_TRUE(creator_.ConsumeDataToFillCurrentPacket(
- stream_id1, &iov_, 1u, iov_.iov_len, 0u, 4u, true, false,
- NOT_RETRANSMISSION, &frame));
- EXPECT_EQ(frame.stream_frame.data_length,
- creator_.PacketSize() - previous_size);
-
- // frame is for another stream, so it won't be coalesced.
- const auto length = creator_.BytesFree() - 10u;
- std::string large_data(length, 'x');
- MakeIOVector(large_data, &iov_);
- EXPECT_CALL(debug, OnFrameAddedToPacket(_));
- ASSERT_TRUE(creator_.ConsumeDataToFillCurrentPacket(
- stream_id2, &iov_, 1u, iov_.iov_len, 0u, 0u, false, false,
- NOT_RETRANSMISSION, &frame));
- EXPECT_TRUE(creator_.HasPendingStreamFramesOfStream(stream_id2));
-
- // The packet doesn't have enough free bytes for all data, but will still be
- // able to consume and coalesce part of them.
- EXPECT_CALL(debug, OnStreamFrameCoalesced(_));
- MakeIOVector("somerandomdata", &iov_);
- ASSERT_TRUE(creator_.ConsumeDataToFillCurrentPacket(
- stream_id2, &iov_, 1u, iov_.iov_len, 0u, length, false, false,
- NOT_RETRANSMISSION, &frame));
-
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .WillOnce(Invoke(this, &QuicPacketCreatorTest::SaveSerializedPacket));
- creator_.FlushCurrentPacket();
- EXPECT_CALL(framer_visitor_, OnPacket());
- EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_));
- EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_));
- EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_, _));
- EXPECT_CALL(framer_visitor_, OnPacketHeader(_));
- // The packet should only have 2 stream frames.
- EXPECT_CALL(framer_visitor_, OnStreamFrame(_));
- EXPECT_CALL(framer_visitor_, OnStreamFrame(_));
- EXPECT_CALL(framer_visitor_, OnPacketComplete());
- ProcessPacket(*serialized_packet_);
-}
-
-TEST_P(QuicPacketCreatorTest, SaveNonRetransmittableFrames) {
- QuicAckFrame ack_frame(InitAckFrame(1));
- frames_.push_back(QuicFrame(&ack_frame));
- frames_.push_back(QuicFrame(QuicPaddingFrame(-1)));
- SerializedPacket serialized = SerializeAllFrames(frames_);
- ASSERT_EQ(2u, serialized.nonretransmittable_frames.size());
- EXPECT_EQ(ACK_FRAME, serialized.nonretransmittable_frames[0].type);
- EXPECT_EQ(PADDING_FRAME, serialized.nonretransmittable_frames[1].type);
- // Verify full padding frame is translated to a padding frame with actual
- // bytes of padding.
- EXPECT_LT(
- 0,
- serialized.nonretransmittable_frames[1].padding_frame.num_padding_bytes);
- frames_.clear();
-
- // Serialize another packet with the same frames.
- SerializedPacket packet = QuicPacketCreatorPeer::SerializeAllFrames(
- &creator_, serialized.nonretransmittable_frames, buffer_,
- kMaxOutgoingPacketSize);
- // Verify the packet length of both packets are equal.
- EXPECT_EQ(serialized.encrypted_length, packet.encrypted_length);
-}
-
-TEST_P(QuicPacketCreatorTest, SerializeCoalescedPacket) {
- QuicCoalescedPacket coalesced;
- SimpleBufferAllocator allocator;
- QuicSocketAddress self_address(QuicIpAddress::Loopback4(), 1);
- QuicSocketAddress peer_address(QuicIpAddress::Loopback4(), 2);
- for (size_t i = ENCRYPTION_INITIAL; i < NUM_ENCRYPTION_LEVELS; ++i) {
- EncryptionLevel level = static_cast<EncryptionLevel>(i);
- creator_.set_encryption_level(level);
- QuicAckFrame ack_frame(InitAckFrame(1));
- if (level != ENCRYPTION_ZERO_RTT) {
- frames_.push_back(QuicFrame(&ack_frame));
- }
- if (level != ENCRYPTION_INITIAL && level != ENCRYPTION_HANDSHAKE) {
- frames_.push_back(
- QuicFrame(QuicStreamFrame(1, false, 0u, absl::string_view())));
- }
- SerializedPacket serialized = SerializeAllFrames(frames_);
- EXPECT_EQ(level, serialized.encryption_level);
- frames_.clear();
- ASSERT_TRUE(coalesced.MaybeCoalescePacket(serialized, self_address,
- peer_address, &allocator,
- creator_.max_packet_length()));
- }
- char buffer[kMaxOutgoingPacketSize];
- size_t coalesced_length = creator_.SerializeCoalescedPacket(
- coalesced, buffer, kMaxOutgoingPacketSize);
- // Verify packet is padded to full.
- ASSERT_EQ(coalesced.max_packet_length(), coalesced_length);
- if (!QuicVersionHasLongHeaderLengths(server_framer_.transport_version())) {
- return;
- }
- // Verify packet process.
- std::unique_ptr<QuicEncryptedPacket> packets[NUM_ENCRYPTION_LEVELS];
- packets[ENCRYPTION_INITIAL] =
- std::make_unique<QuicEncryptedPacket>(buffer, coalesced_length);
- for (size_t i = ENCRYPTION_INITIAL; i < NUM_ENCRYPTION_LEVELS; ++i) {
- InSequence s;
- EXPECT_CALL(framer_visitor_, OnPacket());
- EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_));
- if (i < ENCRYPTION_FORWARD_SECURE) {
- // Save coalesced packet.
- EXPECT_CALL(framer_visitor_, OnCoalescedPacket(_))
- .WillOnce(Invoke([i, &packets](const QuicEncryptedPacket& packet) {
- packets[i + 1] = packet.Clone();
- }));
- }
- EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_));
- EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_, _));
- EXPECT_CALL(framer_visitor_, OnPacketHeader(_));
- if (i != ENCRYPTION_ZERO_RTT) {
- EXPECT_CALL(framer_visitor_, OnAckFrameStart(_, _))
- .WillOnce(Return(true));
- EXPECT_CALL(framer_visitor_,
- OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2)))
- .WillOnce(Return(true));
- EXPECT_CALL(framer_visitor_, OnAckFrameEnd(_)).WillOnce(Return(true));
- }
- if (i == ENCRYPTION_INITIAL) {
- // Verify padding is added.
- EXPECT_CALL(framer_visitor_, OnPaddingFrame(_));
- } else if (i != ENCRYPTION_ZERO_RTT) {
- EXPECT_CALL(framer_visitor_, OnPaddingFrame(_)).Times(testing::AtMost(1));
- }
- if (i != ENCRYPTION_INITIAL && i != ENCRYPTION_HANDSHAKE) {
- EXPECT_CALL(framer_visitor_, OnStreamFrame(_));
- }
- if (i == ENCRYPTION_ZERO_RTT) {
- EXPECT_CALL(framer_visitor_, OnPaddingFrame(_));
- }
- EXPECT_CALL(framer_visitor_, OnPacketComplete());
-
- server_framer_.ProcessPacket(*packets[i]);
- }
-}
-
-TEST_P(QuicPacketCreatorTest, SoftMaxPacketLength) {
- creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
- QuicByteCount previous_max_packet_length = creator_.max_packet_length();
- const size_t overhead =
- GetPacketHeaderOverhead(client_framer_.transport_version()) +
- QuicPacketCreator::MinPlaintextPacketSize(client_framer_.version()) +
- GetEncryptionOverhead();
- // Make sure a length which cannot accommodate header (includes header
- // protection minimal length) gets rejected.
- creator_.SetSoftMaxPacketLength(overhead - 1);
- EXPECT_EQ(previous_max_packet_length, creator_.max_packet_length());
-
- creator_.SetSoftMaxPacketLength(overhead);
- EXPECT_EQ(overhead, creator_.max_packet_length());
-
- // Verify creator has room for stream frame because max_packet_length_ gets
- // restored.
- ASSERT_TRUE(creator_.HasRoomForStreamFrame(
- GetNthClientInitiatedStreamId(1), kMaxIetfVarInt,
- std::numeric_limits<uint32_t>::max()));
- EXPECT_EQ(previous_max_packet_length, creator_.max_packet_length());
-
- // Same for message frame.
- if (VersionSupportsMessageFrames(client_framer_.transport_version())) {
- creator_.SetSoftMaxPacketLength(overhead);
- if (client_framer_.version().UsesTls()) {
- creator_.SetMaxDatagramFrameSize(kMaxAcceptedDatagramFrameSize);
- }
- // Verify GetCurrentLargestMessagePayload is based on the actual
- // max_packet_length.
- EXPECT_LT(1u, creator_.GetCurrentLargestMessagePayload());
- EXPECT_EQ(overhead, creator_.max_packet_length());
- ASSERT_TRUE(creator_.HasRoomForMessageFrame(
- creator_.GetCurrentLargestMessagePayload()));
- EXPECT_EQ(previous_max_packet_length, creator_.max_packet_length());
- }
-
- // Verify creator can consume crypto data because max_packet_length_ gets
- // restored.
- creator_.SetSoftMaxPacketLength(overhead);
- EXPECT_EQ(overhead, creator_.max_packet_length());
- std::string data = "crypto data";
- MakeIOVector(data, &iov_);
- QuicFrame frame;
- if (!QuicVersionUsesCryptoFrames(client_framer_.transport_version())) {
- ASSERT_TRUE(creator_.ConsumeDataToFillCurrentPacket(
- QuicUtils::GetCryptoStreamId(client_framer_.transport_version()), &iov_,
- 1u, iov_.iov_len, 0u, kOffset, false, true, NOT_RETRANSMISSION,
- &frame));
- size_t bytes_consumed = frame.stream_frame.data_length;
- EXPECT_LT(0u, bytes_consumed);
- } else {
- producer_.SaveCryptoData(ENCRYPTION_INITIAL, kOffset, data);
- ASSERT_TRUE(creator_.ConsumeCryptoDataToFillCurrentPacket(
- ENCRYPTION_INITIAL, data.length(), kOffset,
- /*needs_full_padding=*/true, NOT_RETRANSMISSION, &frame));
- size_t bytes_consumed = frame.crypto_frame->data_length;
- EXPECT_LT(0u, bytes_consumed);
- }
- EXPECT_TRUE(creator_.HasPendingFrames());
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .WillOnce(Invoke(this, &QuicPacketCreatorTest::SaveSerializedPacket));
- creator_.FlushCurrentPacket();
-
- // Verify ACK frame can be consumed.
- creator_.SetSoftMaxPacketLength(overhead);
- EXPECT_EQ(overhead, creator_.max_packet_length());
- QuicAckFrame ack_frame(InitAckFrame(10u));
- EXPECT_TRUE(creator_.AddFrame(QuicFrame(&ack_frame), NOT_RETRANSMISSION));
- EXPECT_TRUE(creator_.HasPendingFrames());
-}
-
-TEST_P(QuicPacketCreatorTest,
- ChangingEncryptionLevelRemovesSoftMaxPacketLength) {
- if (!client_framer_.version().CanSendCoalescedPackets()) {
- return;
- }
- // First set encryption level to forward secure which has the shortest header.
- creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
- const QuicByteCount previous_max_packet_length = creator_.max_packet_length();
- const size_t min_acceptable_packet_size =
- GetPacketHeaderOverhead(client_framer_.transport_version()) +
- QuicPacketCreator::MinPlaintextPacketSize(client_framer_.version()) +
- GetEncryptionOverhead();
- // Then set the soft max packet length to the lowest allowed value.
- creator_.SetSoftMaxPacketLength(min_acceptable_packet_size);
- // Make sure that the low value was accepted.
- EXPECT_EQ(creator_.max_packet_length(), min_acceptable_packet_size);
- // Now set the encryption level to handshake which increases the header size.
- creator_.set_encryption_level(ENCRYPTION_HANDSHAKE);
- // Make sure that adding a frame removes the the soft max packet length.
- QuicAckFrame ack_frame(InitAckFrame(1));
- frames_.push_back(QuicFrame(&ack_frame));
- SerializedPacket serialized = SerializeAllFrames(frames_);
- EXPECT_EQ(serialized.encryption_level, ENCRYPTION_HANDSHAKE);
- EXPECT_EQ(creator_.max_packet_length(), previous_max_packet_length);
-}
-
-class MockDelegate : public QuicPacketCreator::DelegateInterface {
- public:
- MockDelegate() {}
- MockDelegate(const MockDelegate&) = delete;
- MockDelegate& operator=(const MockDelegate&) = delete;
- ~MockDelegate() override {}
-
- MOCK_METHOD(bool,
- ShouldGeneratePacket,
- (HasRetransmittableData retransmittable, IsHandshake handshake),
- (override));
- MOCK_METHOD(const QuicFrames,
- MaybeBundleAckOpportunistically,
- (),
- (override));
- MOCK_METHOD(QuicPacketBuffer, GetPacketBuffer, (), (override));
- MOCK_METHOD(void, OnSerializedPacket, (SerializedPacket), (override));
- MOCK_METHOD(void,
- OnUnrecoverableError,
- (QuicErrorCode, const std::string&),
- (override));
- MOCK_METHOD(SerializedPacketFate,
- GetSerializedPacketFate,
- (bool, EncryptionLevel),
- (override));
-
- void SetCanWriteAnything() {
- EXPECT_CALL(*this, ShouldGeneratePacket(_, _)).WillRepeatedly(Return(true));
- EXPECT_CALL(*this, ShouldGeneratePacket(NO_RETRANSMITTABLE_DATA, _))
- .WillRepeatedly(Return(true));
- }
-
- void SetCanNotWrite() {
- EXPECT_CALL(*this, ShouldGeneratePacket(_, _))
- .WillRepeatedly(Return(false));
- EXPECT_CALL(*this, ShouldGeneratePacket(NO_RETRANSMITTABLE_DATA, _))
- .WillRepeatedly(Return(false));
- }
-
- // Use this when only ack frames should be allowed to be written.
- void SetCanWriteOnlyNonRetransmittable() {
- EXPECT_CALL(*this, ShouldGeneratePacket(_, _))
- .WillRepeatedly(Return(false));
- EXPECT_CALL(*this, ShouldGeneratePacket(NO_RETRANSMITTABLE_DATA, _))
- .WillRepeatedly(Return(true));
- }
-};
-
-// Simple struct for describing the contents of a packet.
-// Useful in conjunction with a SimpleQuicFrame for validating that a packet
-// contains the expected frames.
-struct PacketContents {
- PacketContents()
- : num_ack_frames(0),
- num_connection_close_frames(0),
- num_goaway_frames(0),
- num_rst_stream_frames(0),
- num_stop_waiting_frames(0),
- num_stream_frames(0),
- num_crypto_frames(0),
- num_ping_frames(0),
- num_mtu_discovery_frames(0),
- num_padding_frames(0) {}
-
- size_t num_ack_frames;
- size_t num_connection_close_frames;
- size_t num_goaway_frames;
- size_t num_rst_stream_frames;
- size_t num_stop_waiting_frames;
- size_t num_stream_frames;
- size_t num_crypto_frames;
- size_t num_ping_frames;
- size_t num_mtu_discovery_frames;
- size_t num_padding_frames;
-};
-
-class MultiplePacketsTestPacketCreator : public QuicPacketCreator {
- public:
- MultiplePacketsTestPacketCreator(
- QuicConnectionId connection_id,
- QuicFramer* framer,
- QuicRandom* random_generator,
- QuicPacketCreator::DelegateInterface* delegate,
- SimpleDataProducer* producer)
- : QuicPacketCreator(connection_id, framer, random_generator, delegate),
- ack_frame_(InitAckFrame(1)),
- delegate_(static_cast<MockDelegate*>(delegate)),
- producer_(producer) {}
-
- bool ConsumeRetransmittableControlFrame(const QuicFrame& frame,
- bool bundle_ack) {
- if (!has_ack()) {
- QuicFrames frames;
- if (bundle_ack) {
- frames.push_back(QuicFrame(&ack_frame_));
- }
- if (delegate_->ShouldGeneratePacket(NO_RETRANSMITTABLE_DATA,
- NOT_HANDSHAKE)) {
- EXPECT_CALL(*delegate_, MaybeBundleAckOpportunistically())
- .WillOnce(Return(frames));
- }
- }
- return QuicPacketCreator::ConsumeRetransmittableControlFrame(frame);
- }
-
- QuicConsumedData ConsumeDataFastPath(QuicStreamId id,
- const struct iovec* iov,
- int iov_count,
- size_t total_length,
- QuicStreamOffset offset,
- bool fin) {
- // Save data before data is consumed.
- if (total_length > 0) {
- producer_->SaveStreamData(id, iov, iov_count, 0, total_length);
- }
- return QuicPacketCreator::ConsumeDataFastPath(id, total_length, offset, fin,
- 0);
- }
-
- QuicConsumedData ConsumeData(QuicStreamId id,
- const struct iovec* iov,
- int iov_count,
- size_t total_length,
- QuicStreamOffset offset,
- StreamSendingState state) {
- // Save data before data is consumed.
- if (total_length > 0) {
- producer_->SaveStreamData(id, iov, iov_count, 0, total_length);
- }
- if (!has_ack() && delegate_->ShouldGeneratePacket(NO_RETRANSMITTABLE_DATA,
- NOT_HANDSHAKE)) {
- EXPECT_CALL(*delegate_, MaybeBundleAckOpportunistically()).Times(1);
- }
- return QuicPacketCreator::ConsumeData(id, total_length, offset, state);
- }
-
- MessageStatus AddMessageFrame(QuicMessageId message_id,
- QuicMemSlice message) {
- if (!has_ack() && delegate_->ShouldGeneratePacket(NO_RETRANSMITTABLE_DATA,
- NOT_HANDSHAKE)) {
- EXPECT_CALL(*delegate_, MaybeBundleAckOpportunistically()).Times(1);
- }
- return QuicPacketCreator::AddMessageFrame(message_id,
- absl::MakeSpan(&message, 1));
- }
-
- size_t ConsumeCryptoData(EncryptionLevel level,
- absl::string_view data,
- QuicStreamOffset offset) {
- producer_->SaveCryptoData(level, offset, data);
- if (!has_ack() && delegate_->ShouldGeneratePacket(NO_RETRANSMITTABLE_DATA,
- NOT_HANDSHAKE)) {
- EXPECT_CALL(*delegate_, MaybeBundleAckOpportunistically()).Times(1);
- }
- return QuicPacketCreator::ConsumeCryptoData(level, data.length(), offset);
- }
-
- QuicAckFrame ack_frame_;
- MockDelegate* delegate_;
- SimpleDataProducer* producer_;
-};
-
-class QuicPacketCreatorMultiplePacketsTest : public QuicTest {
- public:
- QuicPacketCreatorMultiplePacketsTest()
- : framer_(AllSupportedVersions(),
- QuicTime::Zero(),
- Perspective::IS_CLIENT,
- kQuicDefaultConnectionIdLength),
- creator_(TestConnectionId(),
- &framer_,
- &random_creator_,
- &delegate_,
- &producer_),
- ack_frame_(InitAckFrame(1)) {
- EXPECT_CALL(delegate_, GetPacketBuffer())
- .WillRepeatedly(Return(QuicPacketBuffer()));
- EXPECT_CALL(delegate_, GetSerializedPacketFate(_, _))
- .WillRepeatedly(Return(SEND_TO_WRITER));
- creator_.SetEncrypter(
- ENCRYPTION_FORWARD_SECURE,
- std::make_unique<NullEncrypter>(Perspective::IS_CLIENT));
- creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
- framer_.set_data_producer(&producer_);
- if (simple_framer_.framer()->version().KnowsWhichDecrypterToUse()) {
- simple_framer_.framer()->InstallDecrypter(
- ENCRYPTION_FORWARD_SECURE,
- std::make_unique<NullDecrypter>(Perspective::IS_SERVER));
- }
- creator_.AttachPacketFlusher();
- }
-
- ~QuicPacketCreatorMultiplePacketsTest() override {}
-
- void SavePacket(SerializedPacket packet) {
- QUICHE_DCHECK(packet.release_encrypted_buffer == nullptr);
- packet.encrypted_buffer = CopyBuffer(packet);
- packet.release_encrypted_buffer = [](const char* p) { delete[] p; };
- packets_.push_back(std::move(packet));
- }
-
- protected:
- QuicRstStreamFrame* CreateRstStreamFrame() {
- return new QuicRstStreamFrame(1, 1, QUIC_STREAM_NO_ERROR, 0);
- }
-
- QuicGoAwayFrame* CreateGoAwayFrame() {
- return new QuicGoAwayFrame(2, QUIC_NO_ERROR, 1, std::string());
- }
-
- void CheckPacketContains(const PacketContents& contents,
- size_t packet_index) {
- ASSERT_GT(packets_.size(), packet_index);
- const SerializedPacket& packet = packets_[packet_index];
- size_t num_retransmittable_frames =
- contents.num_connection_close_frames + contents.num_goaway_frames +
- contents.num_rst_stream_frames + contents.num_stream_frames +
- contents.num_crypto_frames + contents.num_ping_frames;
- size_t num_frames =
- contents.num_ack_frames + contents.num_stop_waiting_frames +
- contents.num_mtu_discovery_frames + contents.num_padding_frames +
- num_retransmittable_frames;
-
- if (num_retransmittable_frames == 0) {
- ASSERT_TRUE(packet.retransmittable_frames.empty());
- } else {
- ASSERT_FALSE(packet.retransmittable_frames.empty());
- EXPECT_EQ(num_retransmittable_frames,
- packet.retransmittable_frames.size());
- }
-
- ASSERT_TRUE(packet.encrypted_buffer != nullptr);
- ASSERT_TRUE(simple_framer_.ProcessPacket(
- QuicEncryptedPacket(packet.encrypted_buffer, packet.encrypted_length)));
- size_t num_padding_frames = 0;
- if (contents.num_padding_frames == 0) {
- num_padding_frames = simple_framer_.padding_frames().size();
- }
- EXPECT_EQ(num_frames + num_padding_frames, simple_framer_.num_frames());
- EXPECT_EQ(contents.num_ack_frames, simple_framer_.ack_frames().size());
- EXPECT_EQ(contents.num_connection_close_frames,
- simple_framer_.connection_close_frames().size());
- EXPECT_EQ(contents.num_goaway_frames,
- simple_framer_.goaway_frames().size());
- EXPECT_EQ(contents.num_rst_stream_frames,
- simple_framer_.rst_stream_frames().size());
- EXPECT_EQ(contents.num_stream_frames,
- simple_framer_.stream_frames().size());
- EXPECT_EQ(contents.num_crypto_frames,
- simple_framer_.crypto_frames().size());
- EXPECT_EQ(contents.num_stop_waiting_frames,
- simple_framer_.stop_waiting_frames().size());
- if (contents.num_padding_frames != 0) {
- EXPECT_EQ(contents.num_padding_frames,
- simple_framer_.padding_frames().size());
- }
-
- // From the receiver's perspective, MTU discovery frames are ping frames.
- EXPECT_EQ(contents.num_ping_frames + contents.num_mtu_discovery_frames,
- simple_framer_.ping_frames().size());
- }
-
- void CheckPacketHasSingleStreamFrame(size_t packet_index) {
- ASSERT_GT(packets_.size(), packet_index);
- const SerializedPacket& packet = packets_[packet_index];
- ASSERT_FALSE(packet.retransmittable_frames.empty());
- EXPECT_EQ(1u, packet.retransmittable_frames.size());
- ASSERT_TRUE(packet.encrypted_buffer != nullptr);
- ASSERT_TRUE(simple_framer_.ProcessPacket(
- QuicEncryptedPacket(packet.encrypted_buffer, packet.encrypted_length)));
- EXPECT_EQ(1u, simple_framer_.num_frames());
- EXPECT_EQ(1u, simple_framer_.stream_frames().size());
- }
-
- void CheckAllPacketsHaveSingleStreamFrame() {
- for (size_t i = 0; i < packets_.size(); i++) {
- CheckPacketHasSingleStreamFrame(i);
- }
- }
-
- void CreateData(size_t len) {
- data_array_.reset(new char[len]);
- memset(data_array_.get(), '?', len);
- iov_.iov_base = data_array_.get();
- iov_.iov_len = len;
- }
-
- QuicFramer framer_;
- MockRandom random_creator_;
- StrictMock<MockDelegate> delegate_;
- MultiplePacketsTestPacketCreator creator_;
- SimpleQuicFramer simple_framer_;
- std::vector<SerializedPacket> packets_;
- QuicAckFrame ack_frame_;
- struct iovec iov_;
- SimpleBufferAllocator allocator_;
-
- private:
- std::unique_ptr<char[]> data_array_;
- SimpleDataProducer producer_;
-};
-
-TEST_F(QuicPacketCreatorMultiplePacketsTest, AddControlFrame_NotWritable) {
- delegate_.SetCanNotWrite();
-
- QuicRstStreamFrame* rst_frame = CreateRstStreamFrame();
- const bool consumed =
- creator_.ConsumeRetransmittableControlFrame(QuicFrame(rst_frame),
- /*bundle_ack=*/false);
- EXPECT_FALSE(consumed);
- EXPECT_FALSE(creator_.HasPendingFrames());
- EXPECT_FALSE(creator_.HasPendingRetransmittableFrames());
- delete rst_frame;
-}
-
-TEST_F(QuicPacketCreatorMultiplePacketsTest,
- WrongEncryptionLevelForStreamDataFastPath) {
- creator_.set_encryption_level(ENCRYPTION_HANDSHAKE);
- delegate_.SetCanWriteAnything();
- // Create a 10000 byte IOVector.
- CreateData(10000);
- EXPECT_CALL(delegate_, OnSerializedPacket(_)).Times(0);
- EXPECT_CALL(delegate_, OnUnrecoverableError(_, _));
- EXPECT_QUIC_BUG(creator_.ConsumeDataFastPath(
- QuicUtils::GetFirstBidirectionalStreamId(
- framer_.transport_version(), Perspective::IS_CLIENT),
- &iov_, 1u, iov_.iov_len, 0, true),
- "");
-}
-
-TEST_F(QuicPacketCreatorMultiplePacketsTest, AddControlFrame_OnlyAckWritable) {
- delegate_.SetCanWriteOnlyNonRetransmittable();
-
- QuicRstStreamFrame* rst_frame = CreateRstStreamFrame();
- const bool consumed =
- creator_.ConsumeRetransmittableControlFrame(QuicFrame(rst_frame),
- /*bundle_ack=*/false);
- EXPECT_FALSE(consumed);
- EXPECT_FALSE(creator_.HasPendingFrames());
- EXPECT_FALSE(creator_.HasPendingRetransmittableFrames());
- delete rst_frame;
-}
-
-TEST_F(QuicPacketCreatorMultiplePacketsTest,
- AddControlFrame_WritableAndShouldNotFlush) {
- delegate_.SetCanWriteAnything();
-
- creator_.ConsumeRetransmittableControlFrame(QuicFrame(CreateRstStreamFrame()),
- /*bundle_ack=*/false);
- EXPECT_TRUE(creator_.HasPendingFrames());
- EXPECT_TRUE(creator_.HasPendingRetransmittableFrames());
-}
-
-TEST_F(QuicPacketCreatorMultiplePacketsTest,
- AddControlFrame_NotWritableBatchThenFlush) {
- delegate_.SetCanNotWrite();
-
- QuicRstStreamFrame* rst_frame = CreateRstStreamFrame();
- const bool consumed =
- creator_.ConsumeRetransmittableControlFrame(QuicFrame(rst_frame),
- /*bundle_ack=*/false);
- EXPECT_FALSE(consumed);
- EXPECT_FALSE(creator_.HasPendingFrames());
- EXPECT_FALSE(creator_.HasPendingRetransmittableFrames());
- delete rst_frame;
-}
-
-TEST_F(QuicPacketCreatorMultiplePacketsTest,
- AddControlFrame_WritableAndShouldFlush) {
- delegate_.SetCanWriteAnything();
-
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .WillOnce(
- Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket));
-
- creator_.ConsumeRetransmittableControlFrame(QuicFrame(CreateRstStreamFrame()),
- /*bundle_ack=*/false);
- creator_.Flush();
- EXPECT_FALSE(creator_.HasPendingFrames());
- EXPECT_FALSE(creator_.HasPendingRetransmittableFrames());
-
- PacketContents contents;
- contents.num_rst_stream_frames = 1;
- CheckPacketContains(contents, 0);
-}
-
-TEST_F(QuicPacketCreatorMultiplePacketsTest, ConsumeCryptoData) {
- delegate_.SetCanWriteAnything();
-
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .WillOnce(
- Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket));
- std::string data = "crypto data";
- size_t consumed_bytes =
- creator_.ConsumeCryptoData(ENCRYPTION_INITIAL, data, 0);
- creator_.Flush();
- EXPECT_EQ(data.length(), consumed_bytes);
- EXPECT_FALSE(creator_.HasPendingFrames());
- EXPECT_FALSE(creator_.HasPendingRetransmittableFrames());
-
- PacketContents contents;
- contents.num_crypto_frames = 1;
- contents.num_padding_frames = 1;
- CheckPacketContains(contents, 0);
-}
-
-TEST_F(QuicPacketCreatorMultiplePacketsTest,
- ConsumeCryptoDataCheckShouldGeneratePacket) {
- delegate_.SetCanNotWrite();
-
- EXPECT_CALL(delegate_, OnSerializedPacket(_)).Times(0);
- std::string data = "crypto data";
- size_t consumed_bytes =
- creator_.ConsumeCryptoData(ENCRYPTION_INITIAL, data, 0);
- creator_.Flush();
- EXPECT_EQ(0u, consumed_bytes);
- EXPECT_FALSE(creator_.HasPendingFrames());
- EXPECT_FALSE(creator_.HasPendingRetransmittableFrames());
-}
-
-TEST_F(QuicPacketCreatorMultiplePacketsTest, ConsumeData_NotWritable) {
- delegate_.SetCanNotWrite();
-
- MakeIOVector("foo", &iov_);
- QuicConsumedData consumed = creator_.ConsumeData(
- QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(),
- Perspective::IS_CLIENT),
- &iov_, 1u, iov_.iov_len, 0, FIN);
- EXPECT_EQ(0u, consumed.bytes_consumed);
- EXPECT_FALSE(consumed.fin_consumed);
- EXPECT_FALSE(creator_.HasPendingFrames());
- EXPECT_FALSE(creator_.HasPendingRetransmittableFrames());
-}
-
-TEST_F(QuicPacketCreatorMultiplePacketsTest,
- ConsumeData_WritableAndShouldNotFlush) {
- delegate_.SetCanWriteAnything();
-
- MakeIOVector("foo", &iov_);
- QuicConsumedData consumed = creator_.ConsumeData(
- QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(),
- Perspective::IS_CLIENT),
- &iov_, 1u, iov_.iov_len, 0, FIN);
- EXPECT_EQ(3u, consumed.bytes_consumed);
- EXPECT_TRUE(consumed.fin_consumed);
- EXPECT_TRUE(creator_.HasPendingFrames());
- EXPECT_TRUE(creator_.HasPendingRetransmittableFrames());
-}
-
-TEST_F(QuicPacketCreatorMultiplePacketsTest,
- ConsumeData_WritableAndShouldFlush) {
- delegate_.SetCanWriteAnything();
-
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .WillOnce(
- Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket));
- MakeIOVector("foo", &iov_);
- QuicConsumedData consumed = creator_.ConsumeData(
- QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(),
- Perspective::IS_CLIENT),
- &iov_, 1u, iov_.iov_len, 0, FIN);
- creator_.Flush();
- EXPECT_EQ(3u, consumed.bytes_consumed);
- EXPECT_TRUE(consumed.fin_consumed);
- EXPECT_FALSE(creator_.HasPendingFrames());
- EXPECT_FALSE(creator_.HasPendingRetransmittableFrames());
-
- PacketContents contents;
- contents.num_stream_frames = 1;
- CheckPacketContains(contents, 0);
-}
-
-// Test the behavior of ConsumeData when the data consumed is for the crypto
-// handshake stream. Ensure that the packet is always sent and padded even if
-// the creator operates in batch mode.
-TEST_F(QuicPacketCreatorMultiplePacketsTest, ConsumeData_Handshake) {
- delegate_.SetCanWriteAnything();
-
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .WillOnce(
- Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket));
- std::string data = "foo bar";
- MakeIOVector(data, &iov_);
- size_t consumed_bytes = 0;
- if (QuicVersionUsesCryptoFrames(framer_.transport_version())) {
- consumed_bytes = creator_.ConsumeCryptoData(ENCRYPTION_INITIAL, data, 0);
- } else {
- consumed_bytes =
- creator_
- .ConsumeData(
- QuicUtils::GetCryptoStreamId(framer_.transport_version()),
- &iov_, 1u, iov_.iov_len, 0, NO_FIN)
- .bytes_consumed;
- }
- EXPECT_EQ(7u, consumed_bytes);
- EXPECT_FALSE(creator_.HasPendingFrames());
- EXPECT_FALSE(creator_.HasPendingRetransmittableFrames());
-
- PacketContents contents;
- if (QuicVersionUsesCryptoFrames(framer_.transport_version())) {
- contents.num_crypto_frames = 1;
- } else {
- contents.num_stream_frames = 1;
- }
- contents.num_padding_frames = 1;
- CheckPacketContains(contents, 0);
-
- ASSERT_EQ(1u, packets_.size());
- ASSERT_EQ(kDefaultMaxPacketSize, creator_.max_packet_length());
- EXPECT_EQ(kDefaultMaxPacketSize, packets_[0].encrypted_length);
-}
-
-// Test the behavior of ConsumeData when the data is for the crypto handshake
-// stream, but padding is disabled.
-TEST_F(QuicPacketCreatorMultiplePacketsTest,
- ConsumeData_Handshake_PaddingDisabled) {
- creator_.set_fully_pad_crypto_handshake_packets(false);
-
- delegate_.SetCanWriteAnything();
-
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .WillOnce(
- Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket));
- std::string data = "foo";
- MakeIOVector(data, &iov_);
- size_t bytes_consumed = 0;
- if (QuicVersionUsesCryptoFrames(framer_.transport_version())) {
- bytes_consumed = creator_.ConsumeCryptoData(ENCRYPTION_INITIAL, data, 0);
- } else {
- bytes_consumed =
- creator_
- .ConsumeData(
- QuicUtils::GetCryptoStreamId(framer_.transport_version()),
- &iov_, 1u, iov_.iov_len, 0, NO_FIN)
- .bytes_consumed;
- }
- EXPECT_EQ(3u, bytes_consumed);
- EXPECT_FALSE(creator_.HasPendingFrames());
- EXPECT_FALSE(creator_.HasPendingRetransmittableFrames());
-
- PacketContents contents;
- if (QuicVersionUsesCryptoFrames(framer_.transport_version())) {
- contents.num_crypto_frames = 1;
- } else {
- contents.num_stream_frames = 1;
- }
- contents.num_padding_frames = 0;
- CheckPacketContains(contents, 0);
-
- ASSERT_EQ(1u, packets_.size());
-
- // Packet is not fully padded, but we want to future packets to be larger.
- ASSERT_EQ(kDefaultMaxPacketSize, creator_.max_packet_length());
- size_t expected_packet_length = 27;
- if (QuicVersionUsesCryptoFrames(framer_.transport_version())) {
- // The framing of CRYPTO frames is slightly different than that of stream
- // frames, so the expected packet length differs slightly.
- expected_packet_length = 28;
- }
- if (framer_.version().HasHeaderProtection()) {
- expected_packet_length = 29;
- }
- EXPECT_EQ(expected_packet_length, packets_[0].encrypted_length);
-}
-
-TEST_F(QuicPacketCreatorMultiplePacketsTest, ConsumeData_EmptyData) {
- delegate_.SetCanWriteAnything();
-
- EXPECT_QUIC_BUG(creator_.ConsumeData(
- QuicUtils::QuicUtils::GetFirstBidirectionalStreamId(
- framer_.transport_version(), Perspective::IS_CLIENT),
- nullptr, 0, 0, 0, NO_FIN),
- "Attempt to consume empty data without FIN.");
-}
-
-TEST_F(QuicPacketCreatorMultiplePacketsTest,
- ConsumeDataMultipleTimes_WritableAndShouldNotFlush) {
- delegate_.SetCanWriteAnything();
-
- MakeIOVector("foo", &iov_);
- creator_.ConsumeData(QuicUtils::GetFirstBidirectionalStreamId(
- framer_.transport_version(), Perspective::IS_CLIENT),
- &iov_, 1u, iov_.iov_len, 0, FIN);
- MakeIOVector("quux", &iov_);
- QuicConsumedData consumed =
- creator_.ConsumeData(3, &iov_, 1u, iov_.iov_len, 3, NO_FIN);
- EXPECT_EQ(4u, consumed.bytes_consumed);
- EXPECT_FALSE(consumed.fin_consumed);
- EXPECT_TRUE(creator_.HasPendingFrames());
- EXPECT_TRUE(creator_.HasPendingRetransmittableFrames());
-}
-
-TEST_F(QuicPacketCreatorMultiplePacketsTest, ConsumeData_BatchOperations) {
- delegate_.SetCanWriteAnything();
-
- MakeIOVector("foo", &iov_);
- creator_.ConsumeData(QuicUtils::GetFirstBidirectionalStreamId(
- framer_.transport_version(), Perspective::IS_CLIENT),
- &iov_, 1u, iov_.iov_len, 0, NO_FIN);
- MakeIOVector("quux", &iov_);
- QuicConsumedData consumed = creator_.ConsumeData(
- QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(),
- Perspective::IS_CLIENT),
- &iov_, 1u, iov_.iov_len, 3, FIN);
- EXPECT_EQ(4u, consumed.bytes_consumed);
- EXPECT_TRUE(consumed.fin_consumed);
- EXPECT_TRUE(creator_.HasPendingFrames());
- EXPECT_TRUE(creator_.HasPendingRetransmittableFrames());
-
- // Now both frames will be flushed out.
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .WillOnce(
- Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket));
- creator_.Flush();
- EXPECT_FALSE(creator_.HasPendingFrames());
- EXPECT_FALSE(creator_.HasPendingRetransmittableFrames());
-
- PacketContents contents;
- contents.num_stream_frames = 1;
- CheckPacketContains(contents, 0);
-}
-
-TEST_F(QuicPacketCreatorMultiplePacketsTest,
- ConsumeData_FramesPreviouslyQueued) {
- // Set the packet size be enough for two stream frames with 0 stream offset,
- // but not enough for a stream frame of 0 offset and one with non-zero offset.
- size_t length =
- NullEncrypter(Perspective::IS_CLIENT).GetCiphertextSize(0) +
- GetPacketHeaderSize(
- framer_.transport_version(),
- creator_.GetDestinationConnectionIdLength(),
- creator_.GetSourceConnectionIdLength(),
- QuicPacketCreatorPeer::SendVersionInPacket(&creator_),
- !kIncludeDiversificationNonce,
- QuicPacketCreatorPeer::GetPacketNumberLength(&creator_),
- QuicPacketCreatorPeer::GetRetryTokenLengthLength(&creator_), 0,
- QuicPacketCreatorPeer::GetLengthLength(&creator_)) +
- // Add an extra 3 bytes for the payload and 1 byte so
- // BytesFree is larger than the GetMinStreamFrameSize.
- QuicFramer::GetMinStreamFrameSize(framer_.transport_version(), 1, 0,
- false, 3) +
- 3 +
- QuicFramer::GetMinStreamFrameSize(framer_.transport_version(), 1, 0, true,
- 1) +
- 1;
- creator_.SetMaxPacketLength(length);
- delegate_.SetCanWriteAnything();
- {
- InSequence dummy;
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .WillOnce(
- Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket));
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .WillOnce(
- Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket));
- }
- // Queue enough data to prevent a stream frame with a non-zero offset from
- // fitting.
- MakeIOVector("foo", &iov_);
- QuicConsumedData consumed = creator_.ConsumeData(
- QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(),
- Perspective::IS_CLIENT),
- &iov_, 1u, iov_.iov_len, 0, NO_FIN);
- EXPECT_EQ(3u, consumed.bytes_consumed);
- EXPECT_FALSE(consumed.fin_consumed);
- EXPECT_TRUE(creator_.HasPendingFrames());
- EXPECT_TRUE(creator_.HasPendingRetransmittableFrames());
-
- // This frame will not fit with the existing frame, causing the queued frame
- // to be serialized, and it will be added to a new open packet.
- MakeIOVector("bar", &iov_);
- consumed = creator_.ConsumeData(
- QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(),
- Perspective::IS_CLIENT),
- &iov_, 1u, iov_.iov_len, 3, FIN);
- EXPECT_EQ(3u, consumed.bytes_consumed);
- EXPECT_TRUE(consumed.fin_consumed);
- EXPECT_TRUE(creator_.HasPendingFrames());
- EXPECT_TRUE(creator_.HasPendingRetransmittableFrames());
-
- creator_.FlushCurrentPacket();
- EXPECT_FALSE(creator_.HasPendingFrames());
- EXPECT_FALSE(creator_.HasPendingRetransmittableFrames());
-
- PacketContents contents;
- contents.num_stream_frames = 1;
- CheckPacketContains(contents, 0);
- CheckPacketContains(contents, 1);
-}
-
-TEST_F(QuicPacketCreatorMultiplePacketsTest, ConsumeDataFastPath) {
- delegate_.SetCanWriteAnything();
- creator_.SetTransmissionType(LOSS_RETRANSMISSION);
-
- // Create a 10000 byte IOVector.
- CreateData(10000);
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .WillRepeatedly(
- Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket));
- QuicConsumedData consumed = creator_.ConsumeDataFastPath(
- QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(),
- Perspective::IS_CLIENT),
- &iov_, 1u, iov_.iov_len, 0, true);
- EXPECT_EQ(10000u, consumed.bytes_consumed);
- EXPECT_TRUE(consumed.fin_consumed);
- EXPECT_FALSE(creator_.HasPendingFrames());
- EXPECT_FALSE(creator_.HasPendingRetransmittableFrames());
-
- PacketContents contents;
- contents.num_stream_frames = 1;
- CheckPacketContains(contents, 0);
- EXPECT_FALSE(packets_.empty());
- SerializedPacket& packet = packets_.back();
- EXPECT_TRUE(!packet.retransmittable_frames.empty());
- EXPECT_EQ(LOSS_RETRANSMISSION, packet.transmission_type);
- EXPECT_EQ(STREAM_FRAME, packet.retransmittable_frames.front().type);
- const QuicStreamFrame& stream_frame =
- packet.retransmittable_frames.front().stream_frame;
- EXPECT_EQ(10000u, stream_frame.data_length + stream_frame.offset);
-}
-
-TEST_F(QuicPacketCreatorMultiplePacketsTest, ConsumeDataLarge) {
- delegate_.SetCanWriteAnything();
-
- // Create a 10000 byte IOVector.
- CreateData(10000);
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .WillRepeatedly(
- Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket));
- QuicConsumedData consumed = creator_.ConsumeData(
- QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(),
- Perspective::IS_CLIENT),
- &iov_, 1u, iov_.iov_len, 0, FIN);
- EXPECT_EQ(10000u, consumed.bytes_consumed);
- EXPECT_TRUE(consumed.fin_consumed);
- EXPECT_FALSE(creator_.HasPendingFrames());
- EXPECT_FALSE(creator_.HasPendingRetransmittableFrames());
-
- PacketContents contents;
- contents.num_stream_frames = 1;
- CheckPacketContains(contents, 0);
- EXPECT_FALSE(packets_.empty());
- SerializedPacket& packet = packets_.back();
- EXPECT_TRUE(!packet.retransmittable_frames.empty());
- EXPECT_EQ(STREAM_FRAME, packet.retransmittable_frames.front().type);
- const QuicStreamFrame& stream_frame =
- packet.retransmittable_frames.front().stream_frame;
- EXPECT_EQ(10000u, stream_frame.data_length + stream_frame.offset);
-}
-
-TEST_F(QuicPacketCreatorMultiplePacketsTest, ConsumeDataLargeSendAckFalse) {
- delegate_.SetCanNotWrite();
-
- QuicRstStreamFrame* rst_frame = CreateRstStreamFrame();
- const bool success =
- creator_.ConsumeRetransmittableControlFrame(QuicFrame(rst_frame),
- /*bundle_ack=*/true);
- EXPECT_FALSE(success);
- EXPECT_FALSE(creator_.HasPendingFrames());
- EXPECT_FALSE(creator_.HasPendingRetransmittableFrames());
-
- delegate_.SetCanWriteAnything();
-
- creator_.ConsumeRetransmittableControlFrame(QuicFrame(rst_frame),
- /*bundle_ack=*/false);
-
- // Create a 10000 byte IOVector.
- CreateData(10000);
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .WillRepeatedly(
- Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket));
- creator_.ConsumeRetransmittableControlFrame(QuicFrame(CreateRstStreamFrame()),
- /*bundle_ack=*/true);
- QuicConsumedData consumed = creator_.ConsumeData(
- QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(),
- Perspective::IS_CLIENT),
- &iov_, 1u, iov_.iov_len, 0, FIN);
- creator_.Flush();
-
- EXPECT_EQ(10000u, consumed.bytes_consumed);
- EXPECT_TRUE(consumed.fin_consumed);
- EXPECT_FALSE(creator_.HasPendingFrames());
- EXPECT_FALSE(creator_.HasPendingRetransmittableFrames());
-
- EXPECT_FALSE(packets_.empty());
- SerializedPacket& packet = packets_.back();
- EXPECT_TRUE(!packet.retransmittable_frames.empty());
- EXPECT_EQ(STREAM_FRAME, packet.retransmittable_frames.front().type);
- const QuicStreamFrame& stream_frame =
- packet.retransmittable_frames.front().stream_frame;
- EXPECT_EQ(10000u, stream_frame.data_length + stream_frame.offset);
-}
-
-TEST_F(QuicPacketCreatorMultiplePacketsTest, ConsumeDataLargeSendAckTrue) {
- delegate_.SetCanNotWrite();
- delegate_.SetCanWriteAnything();
-
- // Create a 10000 byte IOVector.
- CreateData(10000);
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .WillRepeatedly(
- Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket));
- QuicConsumedData consumed = creator_.ConsumeData(
- QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(),
- Perspective::IS_CLIENT),
- &iov_, 1u, iov_.iov_len, 0, FIN);
- creator_.Flush();
-
- EXPECT_EQ(10000u, consumed.bytes_consumed);
- EXPECT_TRUE(consumed.fin_consumed);
- EXPECT_FALSE(creator_.HasPendingFrames());
- EXPECT_FALSE(creator_.HasPendingRetransmittableFrames());
-
- EXPECT_FALSE(packets_.empty());
- SerializedPacket& packet = packets_.back();
- EXPECT_TRUE(!packet.retransmittable_frames.empty());
- EXPECT_EQ(STREAM_FRAME, packet.retransmittable_frames.front().type);
- const QuicStreamFrame& stream_frame =
- packet.retransmittable_frames.front().stream_frame;
- EXPECT_EQ(10000u, stream_frame.data_length + stream_frame.offset);
-}
-
-TEST_F(QuicPacketCreatorMultiplePacketsTest, NotWritableThenBatchOperations) {
- delegate_.SetCanNotWrite();
-
- QuicRstStreamFrame* rst_frame = CreateRstStreamFrame();
- const bool consumed =
- creator_.ConsumeRetransmittableControlFrame(QuicFrame(rst_frame),
- /*bundle_ack=*/true);
- EXPECT_FALSE(consumed);
- EXPECT_FALSE(creator_.HasPendingFrames());
- EXPECT_FALSE(creator_.HasPendingRetransmittableFrames());
- EXPECT_FALSE(creator_.HasPendingStreamFramesOfStream(3));
-
- delegate_.SetCanWriteAnything();
-
- EXPECT_TRUE(
- creator_.ConsumeRetransmittableControlFrame(QuicFrame(rst_frame),
- /*bundle_ack=*/false));
- // Send some data and a control frame
- MakeIOVector("quux", &iov_);
- creator_.ConsumeData(3, &iov_, 1u, iov_.iov_len, 0, NO_FIN);
- if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
- creator_.ConsumeRetransmittableControlFrame(QuicFrame(CreateGoAwayFrame()),
- /*bundle_ack=*/false);
- }
- EXPECT_TRUE(creator_.HasPendingStreamFramesOfStream(3));
-
- // All five frames will be flushed out in a single packet.
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .WillOnce(
- Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket));
- creator_.Flush();
- EXPECT_FALSE(creator_.HasPendingFrames());
- EXPECT_FALSE(creator_.HasPendingRetransmittableFrames());
- EXPECT_FALSE(creator_.HasPendingStreamFramesOfStream(3));
-
- PacketContents contents;
- // ACK will be flushed by connection.
- contents.num_ack_frames = 0;
- if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
- contents.num_goaway_frames = 1;
- } else {
- contents.num_goaway_frames = 0;
- }
- contents.num_rst_stream_frames = 1;
- contents.num_stream_frames = 1;
- CheckPacketContains(contents, 0);
-}
-
-TEST_F(QuicPacketCreatorMultiplePacketsTest, NotWritableThenBatchOperations2) {
- delegate_.SetCanNotWrite();
-
- QuicRstStreamFrame* rst_frame = CreateRstStreamFrame();
- const bool success =
- creator_.ConsumeRetransmittableControlFrame(QuicFrame(rst_frame),
- /*bundle_ack=*/true);
- EXPECT_FALSE(success);
- EXPECT_FALSE(creator_.HasPendingFrames());
- EXPECT_FALSE(creator_.HasPendingRetransmittableFrames());
-
- delegate_.SetCanWriteAnything();
-
- {
- InSequence dummy;
- // All five frames will be flushed out in a single packet
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .WillOnce(
- Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket));
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .WillOnce(
- Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket));
- }
- EXPECT_TRUE(
- creator_.ConsumeRetransmittableControlFrame(QuicFrame(rst_frame),
- /*bundle_ack=*/false));
- // Send enough data to exceed one packet
- size_t data_len = kDefaultMaxPacketSize + 100;
- CreateData(data_len);
- QuicConsumedData consumed =
- creator_.ConsumeData(3, &iov_, 1u, iov_.iov_len, 0, FIN);
- EXPECT_EQ(data_len, consumed.bytes_consumed);
- EXPECT_TRUE(consumed.fin_consumed);
- if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
- creator_.ConsumeRetransmittableControlFrame(QuicFrame(CreateGoAwayFrame()),
- /*bundle_ack=*/false);
- }
-
- creator_.Flush();
- EXPECT_FALSE(creator_.HasPendingFrames());
- EXPECT_FALSE(creator_.HasPendingRetransmittableFrames());
-
- // The first packet should have the queued data and part of the stream data.
- PacketContents contents;
- // ACK will be sent by connection.
- contents.num_ack_frames = 0;
- contents.num_rst_stream_frames = 1;
- contents.num_stream_frames = 1;
- CheckPacketContains(contents, 0);
-
- // The second should have the remainder of the stream data.
- PacketContents contents2;
- if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
- contents2.num_goaway_frames = 1;
- } else {
- contents2.num_goaway_frames = 0;
- }
- contents2.num_stream_frames = 1;
- CheckPacketContains(contents2, 1);
-}
-
-// Regression test of b/120493795.
-TEST_F(QuicPacketCreatorMultiplePacketsTest, PacketTransmissionType) {
- delegate_.SetCanWriteAnything();
-
- // The first ConsumeData will fill the packet without flush.
- creator_.SetTransmissionType(LOSS_RETRANSMISSION);
-
- size_t data_len = 1224;
- CreateData(data_len);
- QuicStreamId stream1_id = QuicUtils::GetFirstBidirectionalStreamId(
- framer_.transport_version(), Perspective::IS_CLIENT);
- QuicConsumedData consumed =
- creator_.ConsumeData(stream1_id, &iov_, 1u, iov_.iov_len, 0, NO_FIN);
- EXPECT_EQ(data_len, consumed.bytes_consumed);
- ASSERT_EQ(0u, creator_.BytesFree())
- << "Test setup failed: Please increase data_len to "
- << data_len + creator_.BytesFree() << " bytes.";
-
- // The second ConsumeData can not be added to the packet and will flush.
- creator_.SetTransmissionType(NOT_RETRANSMISSION);
-
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .WillOnce(
- Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket));
-
- QuicStreamId stream2_id = stream1_id + 4;
-
- consumed =
- creator_.ConsumeData(stream2_id, &iov_, 1u, iov_.iov_len, 0, NO_FIN);
- EXPECT_EQ(data_len, consumed.bytes_consumed);
-
- // Ensure the packet is successfully created.
- ASSERT_EQ(1u, packets_.size());
- ASSERT_TRUE(packets_[0].encrypted_buffer);
- ASSERT_EQ(1u, packets_[0].retransmittable_frames.size());
- EXPECT_EQ(stream1_id,
- packets_[0].retransmittable_frames[0].stream_frame.stream_id);
-
- // Since the second frame was not added, the packet's transmission type
- // should be the first frame's type.
- EXPECT_EQ(packets_[0].transmission_type, LOSS_RETRANSMISSION);
-}
-
-TEST_F(QuicPacketCreatorMultiplePacketsTest, TestConnectionIdLength) {
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
- creator_.SetServerConnectionIdLength(0);
- EXPECT_EQ(PACKET_0BYTE_CONNECTION_ID,
- creator_.GetDestinationConnectionIdLength());
-
- for (size_t i = 1; i < 10; i++) {
- creator_.SetServerConnectionIdLength(i);
- if (framer_.version().HasIetfInvariantHeader()) {
- EXPECT_EQ(PACKET_0BYTE_CONNECTION_ID,
- creator_.GetDestinationConnectionIdLength());
- } else {
- EXPECT_EQ(PACKET_8BYTE_CONNECTION_ID,
- creator_.GetDestinationConnectionIdLength());
- }
- }
-}
-
-// Test whether SetMaxPacketLength() works in the situation when the queue is
-// empty, and we send three packets worth of data.
-TEST_F(QuicPacketCreatorMultiplePacketsTest, SetMaxPacketLength_Initial) {
- delegate_.SetCanWriteAnything();
-
- // Send enough data for three packets.
- size_t data_len = 3 * kDefaultMaxPacketSize + 1;
- size_t packet_len = kDefaultMaxPacketSize + 100;
- ASSERT_LE(packet_len, kMaxOutgoingPacketSize);
- creator_.SetMaxPacketLength(packet_len);
- EXPECT_EQ(packet_len, creator_.max_packet_length());
-
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .Times(3)
- .WillRepeatedly(
- Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket));
- CreateData(data_len);
- QuicConsumedData consumed = creator_.ConsumeData(
- QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(),
- Perspective::IS_CLIENT),
- &iov_, 1u, iov_.iov_len,
- /*offset=*/0, FIN);
- EXPECT_EQ(data_len, consumed.bytes_consumed);
- EXPECT_TRUE(consumed.fin_consumed);
- EXPECT_FALSE(creator_.HasPendingFrames());
- EXPECT_FALSE(creator_.HasPendingRetransmittableFrames());
-
- // We expect three packets, and first two of them have to be of packet_len
- // size. We check multiple packets (instead of just one) because we want to
- // ensure that |max_packet_length_| does not get changed incorrectly by the
- // creator after first packet is serialized.
- ASSERT_EQ(3u, packets_.size());
- EXPECT_EQ(packet_len, packets_[0].encrypted_length);
- EXPECT_EQ(packet_len, packets_[1].encrypted_length);
- CheckAllPacketsHaveSingleStreamFrame();
-}
-
-// Test whether SetMaxPacketLength() works in the situation when we first write
-// data, then change packet size, then write data again.
-TEST_F(QuicPacketCreatorMultiplePacketsTest, SetMaxPacketLength_Middle) {
- delegate_.SetCanWriteAnything();
-
- // We send enough data to overflow default packet length, but not the altered
- // one.
- size_t data_len = kDefaultMaxPacketSize;
- size_t packet_len = kDefaultMaxPacketSize + 100;
- ASSERT_LE(packet_len, kMaxOutgoingPacketSize);
-
- // We expect to see three packets in total.
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .Times(3)
- .WillRepeatedly(
- Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket));
-
- // Send two packets before packet size change.
- CreateData(data_len);
- QuicConsumedData consumed = creator_.ConsumeData(
- QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(),
- Perspective::IS_CLIENT),
- &iov_, 1u, iov_.iov_len,
- /*offset=*/0, NO_FIN);
- creator_.Flush();
- EXPECT_EQ(data_len, consumed.bytes_consumed);
- EXPECT_FALSE(consumed.fin_consumed);
- EXPECT_FALSE(creator_.HasPendingFrames());
- EXPECT_FALSE(creator_.HasPendingRetransmittableFrames());
-
- // Make sure we already have two packets.
- ASSERT_EQ(2u, packets_.size());
-
- // Increase packet size.
- creator_.SetMaxPacketLength(packet_len);
- EXPECT_EQ(packet_len, creator_.max_packet_length());
-
- // Send a packet after packet size change.
- CreateData(data_len);
- creator_.AttachPacketFlusher();
- consumed = creator_.ConsumeData(
- QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(),
- Perspective::IS_CLIENT),
- &iov_, 1u, iov_.iov_len, data_len, FIN);
- creator_.Flush();
- EXPECT_EQ(data_len, consumed.bytes_consumed);
- EXPECT_TRUE(consumed.fin_consumed);
- EXPECT_FALSE(creator_.HasPendingFrames());
- EXPECT_FALSE(creator_.HasPendingRetransmittableFrames());
-
- // We expect first data chunk to get fragmented, but the second one to fit
- // into a single packet.
- ASSERT_EQ(3u, packets_.size());
- EXPECT_EQ(kDefaultMaxPacketSize, packets_[0].encrypted_length);
- EXPECT_LE(kDefaultMaxPacketSize, packets_[2].encrypted_length);
- CheckAllPacketsHaveSingleStreamFrame();
-}
-
-// Test whether SetMaxPacketLength() works correctly when we force the change of
-// the packet size in the middle of the batched packet.
-TEST_F(QuicPacketCreatorMultiplePacketsTest,
- SetMaxPacketLength_MidpacketFlush) {
- delegate_.SetCanWriteAnything();
-
- size_t first_write_len = kDefaultMaxPacketSize / 2;
- size_t packet_len = kDefaultMaxPacketSize + 100;
- size_t second_write_len = packet_len + 1;
- ASSERT_LE(packet_len, kMaxOutgoingPacketSize);
-
- // First send half of the packet worth of data. We are in the batch mode, so
- // should not cause packet serialization.
- CreateData(first_write_len);
- QuicConsumedData consumed = creator_.ConsumeData(
- QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(),
- Perspective::IS_CLIENT),
- &iov_, 1u, iov_.iov_len,
- /*offset=*/0, NO_FIN);
- EXPECT_EQ(first_write_len, consumed.bytes_consumed);
- EXPECT_FALSE(consumed.fin_consumed);
- EXPECT_TRUE(creator_.HasPendingFrames());
- EXPECT_TRUE(creator_.HasPendingRetransmittableFrames());
-
- // Make sure we have no packets so far.
- ASSERT_EQ(0u, packets_.size());
-
- // Expect a packet to be flushed.
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .WillOnce(
- Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket));
-
- // Increase packet size after flushing all frames.
- // Ensure it's immediately enacted.
- creator_.FlushCurrentPacket();
- creator_.SetMaxPacketLength(packet_len);
- EXPECT_EQ(packet_len, creator_.max_packet_length());
- EXPECT_FALSE(creator_.HasPendingFrames());
- EXPECT_FALSE(creator_.HasPendingRetransmittableFrames());
-
- // We expect to see exactly one packet serialized after that, because we send
- // a value somewhat exceeding new max packet size, and the tail data does not
- // get serialized because we are still in the batch mode.
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .WillOnce(
- Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket));
-
- // Send a more than a packet worth of data to the same stream. This should
- // trigger serialization of one packet, and queue another one.
- CreateData(second_write_len);
- consumed = creator_.ConsumeData(
- QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(),
- Perspective::IS_CLIENT),
- &iov_, 1u, iov_.iov_len,
- /*offset=*/first_write_len, FIN);
- EXPECT_EQ(second_write_len, consumed.bytes_consumed);
- EXPECT_TRUE(consumed.fin_consumed);
- EXPECT_TRUE(creator_.HasPendingFrames());
- EXPECT_TRUE(creator_.HasPendingRetransmittableFrames());
-
- // We expect the first packet to be underfilled, and the second packet be up
- // to the new max packet size.
- ASSERT_EQ(2u, packets_.size());
- EXPECT_GT(kDefaultMaxPacketSize, packets_[0].encrypted_length);
- EXPECT_EQ(packet_len, packets_[1].encrypted_length);
-
- CheckAllPacketsHaveSingleStreamFrame();
-}
-
-// Test sending a connectivity probing packet.
-TEST_F(QuicPacketCreatorMultiplePacketsTest,
- GenerateConnectivityProbingPacket) {
- delegate_.SetCanWriteAnything();
-
- std::unique_ptr<SerializedPacket> probing_packet;
- if (VersionHasIetfQuicFrames(framer_.transport_version())) {
- QuicPathFrameBuffer payload = {
- {0xde, 0xad, 0xbe, 0xef, 0xba, 0xdc, 0x0f, 0xfe}};
- probing_packet =
- creator_.SerializePathChallengeConnectivityProbingPacket(payload);
- } else {
- probing_packet = creator_.SerializeConnectivityProbingPacket();
- }
-
- ASSERT_TRUE(simple_framer_.ProcessPacket(QuicEncryptedPacket(
- probing_packet->encrypted_buffer, probing_packet->encrypted_length)));
-
- EXPECT_EQ(2u, simple_framer_.num_frames());
- if (VersionHasIetfQuicFrames(framer_.transport_version())) {
- EXPECT_EQ(1u, simple_framer_.path_challenge_frames().size());
- } else {
- EXPECT_EQ(1u, simple_framer_.ping_frames().size());
- }
- EXPECT_EQ(1u, simple_framer_.padding_frames().size());
-}
-
-// Test sending an MTU probe, without any surrounding data.
-TEST_F(QuicPacketCreatorMultiplePacketsTest,
- GenerateMtuDiscoveryPacket_Simple) {
- delegate_.SetCanWriteAnything();
-
- const size_t target_mtu = kDefaultMaxPacketSize + 100;
- static_assert(target_mtu < kMaxOutgoingPacketSize,
- "The MTU probe used by the test exceeds maximum packet size");
-
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .WillOnce(
- Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket));
-
- creator_.GenerateMtuDiscoveryPacket(target_mtu);
-
- EXPECT_FALSE(creator_.HasPendingFrames());
- EXPECT_FALSE(creator_.HasPendingRetransmittableFrames());
- ASSERT_EQ(1u, packets_.size());
- EXPECT_EQ(target_mtu, packets_[0].encrypted_length);
-
- PacketContents contents;
- contents.num_mtu_discovery_frames = 1;
- contents.num_padding_frames = 1;
- CheckPacketContains(contents, 0);
-}
-
-// Test sending an MTU probe. Surround it with data, to ensure that it resets
-// the MTU to the value before the probe was sent.
-TEST_F(QuicPacketCreatorMultiplePacketsTest,
- GenerateMtuDiscoveryPacket_SurroundedByData) {
- delegate_.SetCanWriteAnything();
-
- const size_t target_mtu = kDefaultMaxPacketSize + 100;
- static_assert(target_mtu < kMaxOutgoingPacketSize,
- "The MTU probe used by the test exceeds maximum packet size");
-
- // Send enough data so it would always cause two packets to be sent.
- const size_t data_len = target_mtu + 1;
-
- // Send a total of five packets: two packets before the probe, the probe
- // itself, and two packets after the probe.
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .Times(5)
- .WillRepeatedly(
- Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket));
-
- // Send data before the MTU probe.
- CreateData(data_len);
- QuicConsumedData consumed = creator_.ConsumeData(
- QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(),
- Perspective::IS_CLIENT),
- &iov_, 1u, iov_.iov_len,
- /*offset=*/0, NO_FIN);
- creator_.Flush();
- EXPECT_EQ(data_len, consumed.bytes_consumed);
- EXPECT_FALSE(consumed.fin_consumed);
- EXPECT_FALSE(creator_.HasPendingFrames());
- EXPECT_FALSE(creator_.HasPendingRetransmittableFrames());
-
- // Send the MTU probe.
- creator_.GenerateMtuDiscoveryPacket(target_mtu);
- EXPECT_FALSE(creator_.HasPendingFrames());
- EXPECT_FALSE(creator_.HasPendingRetransmittableFrames());
-
- // Send data after the MTU probe.
- CreateData(data_len);
- creator_.AttachPacketFlusher();
- consumed = creator_.ConsumeData(
- QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(),
- Perspective::IS_CLIENT),
- &iov_, 1u, iov_.iov_len,
- /*offset=*/data_len, FIN);
- creator_.Flush();
- EXPECT_EQ(data_len, consumed.bytes_consumed);
- EXPECT_TRUE(consumed.fin_consumed);
- EXPECT_FALSE(creator_.HasPendingFrames());
- EXPECT_FALSE(creator_.HasPendingRetransmittableFrames());
-
- ASSERT_EQ(5u, packets_.size());
- EXPECT_EQ(kDefaultMaxPacketSize, packets_[0].encrypted_length);
- EXPECT_EQ(target_mtu, packets_[2].encrypted_length);
- EXPECT_EQ(kDefaultMaxPacketSize, packets_[3].encrypted_length);
-
- PacketContents probe_contents;
- probe_contents.num_mtu_discovery_frames = 1;
- probe_contents.num_padding_frames = 1;
-
- CheckPacketHasSingleStreamFrame(0);
- CheckPacketHasSingleStreamFrame(1);
- CheckPacketContains(probe_contents, 2);
- CheckPacketHasSingleStreamFrame(3);
- CheckPacketHasSingleStreamFrame(4);
-}
-
-TEST_F(QuicPacketCreatorMultiplePacketsTest, DontCrashOnInvalidStopWaiting) {
- if (VersionSupportsMessageFrames(framer_.transport_version())) {
- return;
- }
- // Test added to ensure the creator does not crash when an invalid frame is
- // added. Because this is an indication of internal programming errors,
- // DFATALs are expected.
- // A 1 byte packet number length can't encode a gap of 1000.
- QuicPacketCreatorPeer::SetPacketNumber(&creator_, 1000);
-
- delegate_.SetCanNotWrite();
- delegate_.SetCanWriteAnything();
-
- // This will not serialize any packets, because of the invalid frame.
- EXPECT_CALL(delegate_,
- OnUnrecoverableError(QUIC_FAILED_TO_SERIALIZE_PACKET, _));
- EXPECT_QUIC_BUG(creator_.Flush(),
- "packet_number_length 1 is too small "
- "for least_unacked_delta: 1001");
-}
-
-// Regression test for b/31486443.
-TEST_F(QuicPacketCreatorMultiplePacketsTest,
- ConnectionCloseFrameLargerThanPacketSize) {
- delegate_.SetCanWriteAnything();
- char buf[2000] = {};
- absl::string_view error_details(buf, 2000);
- const QuicErrorCode kQuicErrorCode = QUIC_PACKET_WRITE_ERROR;
-
- QuicConnectionCloseFrame* frame = new QuicConnectionCloseFrame(
- framer_.transport_version(), kQuicErrorCode, NO_IETF_QUIC_ERROR,
- std::string(error_details),
- /*transport_close_frame_type=*/0);
- creator_.ConsumeRetransmittableControlFrame(QuicFrame(frame),
- /*bundle_ack=*/false);
- EXPECT_TRUE(creator_.HasPendingFrames());
- EXPECT_TRUE(creator_.HasPendingRetransmittableFrames());
-}
-
-TEST_F(QuicPacketCreatorMultiplePacketsTest,
- RandomPaddingAfterFinSingleStreamSinglePacket) {
- const QuicByteCount kStreamFramePayloadSize = 100u;
- char buf[kStreamFramePayloadSize] = {};
- const QuicStreamId kDataStreamId = 5;
- // Set the packet size be enough for one stream frame with 0 stream offset and
- // max size of random padding.
- size_t length =
- NullEncrypter(Perspective::IS_CLIENT).GetCiphertextSize(0) +
- GetPacketHeaderSize(
- framer_.transport_version(),
- creator_.GetDestinationConnectionIdLength(),
- creator_.GetSourceConnectionIdLength(),
- QuicPacketCreatorPeer::SendVersionInPacket(&creator_),
- !kIncludeDiversificationNonce,
- QuicPacketCreatorPeer::GetPacketNumberLength(&creator_),
- QuicPacketCreatorPeer::GetRetryTokenLengthLength(&creator_), 0,
- QuicPacketCreatorPeer::GetLengthLength(&creator_)) +
- QuicFramer::GetMinStreamFrameSize(
- framer_.transport_version(), kDataStreamId, 0,
- /*last_frame_in_packet=*/false,
- kStreamFramePayloadSize + kMaxNumRandomPaddingBytes) +
- kStreamFramePayloadSize + kMaxNumRandomPaddingBytes;
- creator_.SetMaxPacketLength(length);
- delegate_.SetCanWriteAnything();
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .WillOnce(
- Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket));
- MakeIOVector(absl::string_view(buf, kStreamFramePayloadSize), &iov_);
- QuicConsumedData consumed = creator_.ConsumeData(
- kDataStreamId, &iov_, 1u, iov_.iov_len, 0, FIN_AND_PADDING);
- creator_.Flush();
- EXPECT_EQ(kStreamFramePayloadSize, consumed.bytes_consumed);
- EXPECT_FALSE(creator_.HasPendingFrames());
- EXPECT_FALSE(creator_.HasPendingRetransmittableFrames());
-
- EXPECT_EQ(1u, packets_.size());
- PacketContents contents;
- // The packet has both stream and padding frames.
- contents.num_padding_frames = 1;
- contents.num_stream_frames = 1;
- CheckPacketContains(contents, 0);
-}
-
-TEST_F(QuicPacketCreatorMultiplePacketsTest,
- RandomPaddingAfterFinSingleStreamMultiplePackets) {
- const QuicByteCount kStreamFramePayloadSize = 100u;
- char buf[kStreamFramePayloadSize] = {};
- const QuicStreamId kDataStreamId = 5;
- // Set the packet size be enough for one stream frame with 0 stream offset +
- // 1. One or more packets will accommodate.
- size_t length =
- NullEncrypter(Perspective::IS_CLIENT).GetCiphertextSize(0) +
- GetPacketHeaderSize(
- framer_.transport_version(),
- creator_.GetDestinationConnectionIdLength(),
- creator_.GetSourceConnectionIdLength(),
- QuicPacketCreatorPeer::SendVersionInPacket(&creator_),
- !kIncludeDiversificationNonce,
- QuicPacketCreatorPeer::GetPacketNumberLength(&creator_),
- QuicPacketCreatorPeer::GetRetryTokenLengthLength(&creator_), 0,
- QuicPacketCreatorPeer::GetLengthLength(&creator_)) +
- QuicFramer::GetMinStreamFrameSize(
- framer_.transport_version(), kDataStreamId, 0,
- /*last_frame_in_packet=*/false, kStreamFramePayloadSize + 1) +
- kStreamFramePayloadSize + 1;
- creator_.SetMaxPacketLength(length);
- delegate_.SetCanWriteAnything();
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .WillRepeatedly(
- Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket));
- MakeIOVector(absl::string_view(buf, kStreamFramePayloadSize), &iov_);
- QuicConsumedData consumed = creator_.ConsumeData(
- kDataStreamId, &iov_, 1u, iov_.iov_len, 0, FIN_AND_PADDING);
- creator_.Flush();
- EXPECT_EQ(kStreamFramePayloadSize, consumed.bytes_consumed);
- EXPECT_FALSE(creator_.HasPendingFrames());
- EXPECT_FALSE(creator_.HasPendingRetransmittableFrames());
-
- EXPECT_LE(1u, packets_.size());
- PacketContents contents;
- // The first packet has both stream and padding frames.
- contents.num_stream_frames = 1;
- contents.num_padding_frames = 1;
- CheckPacketContains(contents, 0);
-
- for (size_t i = 1; i < packets_.size(); ++i) {
- // Following packets only have paddings.
- contents.num_stream_frames = 0;
- contents.num_padding_frames = 1;
- CheckPacketContains(contents, i);
- }
-}
-
-TEST_F(QuicPacketCreatorMultiplePacketsTest,
- RandomPaddingAfterFinMultipleStreamsMultiplePackets) {
- const QuicByteCount kStreamFramePayloadSize = 100u;
- char buf[kStreamFramePayloadSize] = {};
- const QuicStreamId kDataStreamId1 = 5;
- const QuicStreamId kDataStreamId2 = 6;
- // Set the packet size be enough for first frame with 0 stream offset + second
- // frame + 1 byte payload. two or more packets will accommodate.
- size_t length =
- NullEncrypter(Perspective::IS_CLIENT).GetCiphertextSize(0) +
- GetPacketHeaderSize(
- framer_.transport_version(),
- creator_.GetDestinationConnectionIdLength(),
- creator_.GetSourceConnectionIdLength(),
- QuicPacketCreatorPeer::SendVersionInPacket(&creator_),
- !kIncludeDiversificationNonce,
- QuicPacketCreatorPeer::GetPacketNumberLength(&creator_),
- QuicPacketCreatorPeer::GetRetryTokenLengthLength(&creator_), 0,
- QuicPacketCreatorPeer::GetLengthLength(&creator_)) +
- QuicFramer::GetMinStreamFrameSize(
- framer_.transport_version(), kDataStreamId1, 0,
- /*last_frame_in_packet=*/false, kStreamFramePayloadSize) +
- kStreamFramePayloadSize +
- QuicFramer::GetMinStreamFrameSize(framer_.transport_version(),
- kDataStreamId1, 0,
- /*last_frame_in_packet=*/false, 1) +
- 1;
- creator_.SetMaxPacketLength(length);
- delegate_.SetCanWriteAnything();
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .WillRepeatedly(
- Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket));
- MakeIOVector(absl::string_view(buf, kStreamFramePayloadSize), &iov_);
- QuicConsumedData consumed = creator_.ConsumeData(
- kDataStreamId1, &iov_, 1u, iov_.iov_len, 0, FIN_AND_PADDING);
- EXPECT_EQ(kStreamFramePayloadSize, consumed.bytes_consumed);
- MakeIOVector(absl::string_view(buf, kStreamFramePayloadSize), &iov_);
- consumed = creator_.ConsumeData(kDataStreamId2, &iov_, 1u, iov_.iov_len, 0,
- FIN_AND_PADDING);
- EXPECT_EQ(kStreamFramePayloadSize, consumed.bytes_consumed);
- creator_.Flush();
- EXPECT_FALSE(creator_.HasPendingFrames());
- EXPECT_FALSE(creator_.HasPendingRetransmittableFrames());
-
- EXPECT_LE(2u, packets_.size());
- PacketContents contents;
- // The first packet has two stream frames.
- contents.num_stream_frames = 2;
- CheckPacketContains(contents, 0);
-
- // The second packet has one stream frame and padding frames.
- contents.num_stream_frames = 1;
- contents.num_padding_frames = 1;
- CheckPacketContains(contents, 1);
-
- for (size_t i = 2; i < packets_.size(); ++i) {
- // Following packets only have paddings.
- contents.num_stream_frames = 0;
- contents.num_padding_frames = 1;
- CheckPacketContains(contents, i);
- }
-}
-
-TEST_F(QuicPacketCreatorMultiplePacketsTest, AddMessageFrame) {
- if (!VersionSupportsMessageFrames(framer_.transport_version())) {
- return;
- }
- if (framer_.version().UsesTls()) {
- creator_.SetMaxDatagramFrameSize(kMaxAcceptedDatagramFrameSize);
- }
- delegate_.SetCanWriteAnything();
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .WillOnce(
- Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket));
-
- MakeIOVector("foo", &iov_);
- creator_.ConsumeData(QuicUtils::GetFirstBidirectionalStreamId(
- framer_.transport_version(), Perspective::IS_CLIENT),
- &iov_, 1u, iov_.iov_len, 0, FIN);
- EXPECT_EQ(MESSAGE_STATUS_SUCCESS,
- creator_.AddMessageFrame(1, MemSliceFromString("message")));
- EXPECT_TRUE(creator_.HasPendingFrames());
- EXPECT_TRUE(creator_.HasPendingRetransmittableFrames());
-
- // Add a message which causes the flush of current packet.
- EXPECT_EQ(MESSAGE_STATUS_SUCCESS,
- creator_.AddMessageFrame(
- 2, MemSliceFromString(std::string(
- creator_.GetCurrentLargestMessagePayload(), 'a'))));
- EXPECT_TRUE(creator_.HasPendingRetransmittableFrames());
-
- // Failed to send messages which cannot fit into one packet.
- EXPECT_EQ(MESSAGE_STATUS_TOO_LARGE,
- creator_.AddMessageFrame(
- 3, MemSliceFromString(std::string(
- creator_.GetCurrentLargestMessagePayload() + 10, 'a'))));
-}
-
-TEST_F(QuicPacketCreatorMultiplePacketsTest, ConnectionId) {
- creator_.SetServerConnectionId(TestConnectionId(0x1337));
- EXPECT_EQ(TestConnectionId(0x1337), creator_.GetDestinationConnectionId());
- EXPECT_EQ(EmptyQuicConnectionId(), creator_.GetSourceConnectionId());
- if (!framer_.version().SupportsClientConnectionIds()) {
- return;
- }
- creator_.SetClientConnectionId(TestConnectionId(0x33));
- EXPECT_EQ(TestConnectionId(0x1337), creator_.GetDestinationConnectionId());
- EXPECT_EQ(TestConnectionId(0x33), creator_.GetSourceConnectionId());
-}
-
-// Regresstion test for b/159812345.
-TEST_F(QuicPacketCreatorMultiplePacketsTest, ExtraPaddingNeeded) {
- if (!framer_.version().HasHeaderProtection()) {
- return;
- }
- delegate_.SetCanWriteAnything();
-
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .WillOnce(
- Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket));
- MakeIOVector("a", &iov_);
- creator_.ConsumeData(QuicUtils::GetFirstBidirectionalStreamId(
- framer_.transport_version(), Perspective::IS_CLIENT),
- &iov_, 1u, iov_.iov_len, 0, FIN);
- creator_.Flush();
- ASSERT_FALSE(packets_[0].nonretransmittable_frames.empty());
- QuicFrame padding = packets_[0].nonretransmittable_frames[0];
- // Verify stream frame expansion is excluded.
- padding.padding_frame.num_padding_bytes = 3;
-}
-
-TEST_F(QuicPacketCreatorMultiplePacketsTest,
- PeerAddressContextWithSameAddress) {
- QuicConnectionId client_connection_id = TestConnectionId(1);
- QuicConnectionId server_connection_id = TestConnectionId(2);
- QuicSocketAddress peer_addr(QuicIpAddress::Any4(), 12345);
- creator_.SetDefaultPeerAddress(peer_addr);
- creator_.SetClientConnectionId(client_connection_id);
- creator_.SetServerConnectionId(server_connection_id);
- // Send some stream data.
- MakeIOVector("foo", &iov_);
- EXPECT_CALL(delegate_, ShouldGeneratePacket(_, _))
- .WillRepeatedly(Return(true));
- QuicConsumedData consumed = creator_.ConsumeData(
- QuicUtils::GetFirstBidirectionalStreamId(creator_.transport_version(),
- Perspective::IS_CLIENT),
- &iov_, 1u, iov_.iov_len, 0, NO_FIN);
- EXPECT_EQ(3u, consumed.bytes_consumed);
- EXPECT_TRUE(creator_.HasPendingFrames());
- {
- // Set the same address via context which should not trigger flush.
- QuicPacketCreator::ScopedPeerAddressContext context(
- &creator_, peer_addr, client_connection_id, server_connection_id,
- /*update_connection_id=*/true);
- ASSERT_EQ(client_connection_id, creator_.GetClientConnectionId());
- ASSERT_EQ(server_connection_id, creator_.GetServerConnectionId());
- EXPECT_TRUE(creator_.HasPendingFrames());
- // Queue another STREAM_FRAME.
- QuicConsumedData consumed = creator_.ConsumeData(
- QuicUtils::GetFirstBidirectionalStreamId(creator_.transport_version(),
- Perspective::IS_CLIENT),
- &iov_, 1u, iov_.iov_len, 0, FIN);
- EXPECT_EQ(3u, consumed.bytes_consumed);
- }
- // After exiting the scope, the last queued frame should be flushed.
- EXPECT_TRUE(creator_.HasPendingFrames());
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .WillOnce(Invoke([=](SerializedPacket packet) {
- EXPECT_EQ(peer_addr, packet.peer_address);
- ASSERT_EQ(2u, packet.retransmittable_frames.size());
- EXPECT_EQ(STREAM_FRAME, packet.retransmittable_frames.front().type);
- EXPECT_EQ(STREAM_FRAME, packet.retransmittable_frames.back().type);
- }));
- creator_.FlushCurrentPacket();
-}
-
-TEST_F(QuicPacketCreatorMultiplePacketsTest,
- PeerAddressContextWithDifferentAddress) {
- QuicSocketAddress peer_addr(QuicIpAddress::Any4(), 12345);
- creator_.SetDefaultPeerAddress(peer_addr);
- // Send some stream data.
- MakeIOVector("foo", &iov_);
- EXPECT_CALL(delegate_, ShouldGeneratePacket(_, _))
- .WillRepeatedly(Return(true));
- QuicConsumedData consumed = creator_.ConsumeData(
- QuicUtils::GetFirstBidirectionalStreamId(creator_.transport_version(),
- Perspective::IS_CLIENT),
- &iov_, 1u, iov_.iov_len, 0, NO_FIN);
- EXPECT_EQ(3u, consumed.bytes_consumed);
-
- QuicSocketAddress peer_addr1(QuicIpAddress::Any4(), 12346);
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .WillOnce(Invoke([=](SerializedPacket packet) {
- EXPECT_EQ(peer_addr, packet.peer_address);
- ASSERT_EQ(1u, packet.retransmittable_frames.size());
- EXPECT_EQ(STREAM_FRAME, packet.retransmittable_frames.front().type);
- }))
- .WillOnce(Invoke([=](SerializedPacket packet) {
- EXPECT_EQ(peer_addr1, packet.peer_address);
- ASSERT_EQ(1u, packet.retransmittable_frames.size());
- EXPECT_EQ(STREAM_FRAME, packet.retransmittable_frames.front().type);
- }));
- EXPECT_TRUE(creator_.HasPendingFrames());
- {
- QuicConnectionId client_connection_id = TestConnectionId(1);
- QuicConnectionId server_connection_id = TestConnectionId(2);
- // Set a different address via context which should trigger flush.
- QuicPacketCreator::ScopedPeerAddressContext context(
- &creator_, peer_addr1, client_connection_id, server_connection_id,
- /*update_connection_id=*/true);
- ASSERT_EQ(client_connection_id, creator_.GetClientConnectionId());
- ASSERT_EQ(server_connection_id, creator_.GetServerConnectionId());
- EXPECT_FALSE(creator_.HasPendingFrames());
- // Queue another STREAM_FRAME.
- QuicConsumedData consumed = creator_.ConsumeData(
- QuicUtils::GetFirstBidirectionalStreamId(creator_.transport_version(),
- Perspective::IS_CLIENT),
- &iov_, 1u, iov_.iov_len, 0, FIN);
- EXPECT_EQ(3u, consumed.bytes_consumed);
- EXPECT_TRUE(creator_.HasPendingFrames());
- }
- // After exiting the scope, the last queued frame should be flushed.
- EXPECT_FALSE(creator_.HasPendingFrames());
-}
-
-TEST_F(QuicPacketCreatorMultiplePacketsTest,
- NestedPeerAddressContextWithDifferentAddress) {
- QuicConnectionId client_connection_id1 = creator_.GetClientConnectionId();
- QuicConnectionId server_connection_id1 = creator_.GetServerConnectionId();
- QuicSocketAddress peer_addr(QuicIpAddress::Any4(), 12345);
- creator_.SetDefaultPeerAddress(peer_addr);
- QuicPacketCreator::ScopedPeerAddressContext context(
- &creator_, peer_addr, client_connection_id1, server_connection_id1,
- /*update_connection_id=*/true);
- ASSERT_EQ(client_connection_id1, creator_.GetClientConnectionId());
- ASSERT_EQ(server_connection_id1, creator_.GetServerConnectionId());
-
- // Send some stream data.
- MakeIOVector("foo", &iov_);
- EXPECT_CALL(delegate_, ShouldGeneratePacket(_, _))
- .WillRepeatedly(Return(true));
- QuicConsumedData consumed = creator_.ConsumeData(
- QuicUtils::GetFirstBidirectionalStreamId(creator_.transport_version(),
- Perspective::IS_CLIENT),
- &iov_, 1u, iov_.iov_len, 0, NO_FIN);
- EXPECT_EQ(3u, consumed.bytes_consumed);
- EXPECT_TRUE(creator_.HasPendingFrames());
-
- QuicSocketAddress peer_addr1(QuicIpAddress::Any4(), 12346);
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .WillOnce(Invoke([=](SerializedPacket packet) {
- EXPECT_EQ(peer_addr, packet.peer_address);
- ASSERT_EQ(1u, packet.retransmittable_frames.size());
- EXPECT_EQ(STREAM_FRAME, packet.retransmittable_frames.front().type);
-
- QuicConnectionId client_connection_id2 = TestConnectionId(3);
- QuicConnectionId server_connection_id2 = TestConnectionId(4);
- // Set up another context with a different address.
- QuicPacketCreator::ScopedPeerAddressContext context(
- &creator_, peer_addr1, client_connection_id2, server_connection_id2,
- /*update_connection_id=*/true);
- ASSERT_EQ(client_connection_id2, creator_.GetClientConnectionId());
- ASSERT_EQ(server_connection_id2, creator_.GetServerConnectionId());
- MakeIOVector("foo", &iov_);
- EXPECT_CALL(delegate_, ShouldGeneratePacket(_, _))
- .WillRepeatedly(Return(true));
- QuicConsumedData consumed = creator_.ConsumeData(
- QuicUtils::GetFirstBidirectionalStreamId(
- creator_.transport_version(), Perspective::IS_CLIENT),
- &iov_, 1u, iov_.iov_len, 0, NO_FIN);
- EXPECT_EQ(3u, consumed.bytes_consumed);
- EXPECT_TRUE(creator_.HasPendingFrames());
- // This should trigger another OnSerializedPacket() with the 2nd
- // address.
- creator_.FlushCurrentPacket();
- }))
- .WillOnce(Invoke([=](SerializedPacket packet) {
- EXPECT_EQ(peer_addr1, packet.peer_address);
- ASSERT_EQ(1u, packet.retransmittable_frames.size());
- EXPECT_EQ(STREAM_FRAME, packet.retransmittable_frames.front().type);
- }));
- creator_.FlushCurrentPacket();
-}
-
-} // namespace
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_packet_number.cc b/chromium/net/third_party/quiche/src/quic/core/quic_packet_number.cc
deleted file mode 100644
index b2821b454d7..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_packet_number.cc
+++ /dev/null
@@ -1,111 +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 "quic/core/quic_packet_number.h"
-
-#include <algorithm>
-#include <limits>
-
-#include "absl/strings/str_cat.h"
-
-namespace quic {
-
-void QuicPacketNumber::Clear() {
- packet_number_ = UninitializedPacketNumber();
-}
-
-void QuicPacketNumber::UpdateMax(QuicPacketNumber new_value) {
- if (!new_value.IsInitialized()) {
- return;
- }
- if (!IsInitialized()) {
- packet_number_ = new_value.ToUint64();
- } else {
- packet_number_ = std::max(packet_number_, new_value.ToUint64());
- }
-}
-
-uint64_t QuicPacketNumber::Hash() const {
- QUICHE_DCHECK(IsInitialized());
- return packet_number_;
-}
-
-uint64_t QuicPacketNumber::ToUint64() const {
- QUICHE_DCHECK(IsInitialized());
- return packet_number_;
-}
-
-bool QuicPacketNumber::IsInitialized() const {
- return packet_number_ != UninitializedPacketNumber();
-}
-
-QuicPacketNumber& QuicPacketNumber::operator++() {
-#ifndef NDEBUG
- QUICHE_DCHECK(IsInitialized());
- QUICHE_DCHECK_LT(ToUint64(), std::numeric_limits<uint64_t>::max() - 1);
-#endif
- packet_number_++;
- return *this;
-}
-
-QuicPacketNumber QuicPacketNumber::operator++(int) {
-#ifndef NDEBUG
- QUICHE_DCHECK(IsInitialized());
- QUICHE_DCHECK_LT(ToUint64(), std::numeric_limits<uint64_t>::max() - 1);
-#endif
- QuicPacketNumber previous(*this);
- packet_number_++;
- return previous;
-}
-
-QuicPacketNumber& QuicPacketNumber::operator--() {
-#ifndef NDEBUG
- QUICHE_DCHECK(IsInitialized());
- QUICHE_DCHECK_GE(ToUint64(), 1UL);
-#endif
- packet_number_--;
- return *this;
-}
-
-QuicPacketNumber QuicPacketNumber::operator--(int) {
-#ifndef NDEBUG
- QUICHE_DCHECK(IsInitialized());
- QUICHE_DCHECK_GE(ToUint64(), 1UL);
-#endif
- QuicPacketNumber previous(*this);
- packet_number_--;
- return previous;
-}
-
-QuicPacketNumber& QuicPacketNumber::operator+=(uint64_t delta) {
-#ifndef NDEBUG
- QUICHE_DCHECK(IsInitialized());
- QUICHE_DCHECK_GT(std::numeric_limits<uint64_t>::max() - ToUint64(), delta);
-#endif
- packet_number_ += delta;
- return *this;
-}
-
-QuicPacketNumber& QuicPacketNumber::operator-=(uint64_t delta) {
-#ifndef NDEBUG
- QUICHE_DCHECK(IsInitialized());
- QUICHE_DCHECK_GE(ToUint64(), delta);
-#endif
- packet_number_ -= delta;
- return *this;
-}
-
-std::string QuicPacketNumber::ToString() const {
- if (!IsInitialized()) {
- return "uninitialized";
- }
- return absl::StrCat(ToUint64());
-}
-
-std::ostream& operator<<(std::ostream& os, const QuicPacketNumber& p) {
- os << p.ToString();
- return os;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_packet_number.h b/chromium/net/third_party/quiche/src/quic/core/quic_packet_number.h
deleted file mode 100644
index affd714336e..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_packet_number.h
+++ /dev/null
@@ -1,165 +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_CORE_QUIC_PACKET_NUMBER_H_
-#define QUICHE_QUIC_CORE_QUIC_PACKET_NUMBER_H_
-
-#include <limits>
-#include <ostream>
-#include <string>
-
-#include "quic/platform/api/quic_export.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-// QuicPacketNumber can either initialized or uninitialized. An initialized
-// packet number is simply an ordinal number. A sentinel value is used to
-// represent an uninitialized packet number.
-class QUIC_EXPORT_PRIVATE QuicPacketNumber {
- public:
- // Construct an uninitialized packet number.
- constexpr QuicPacketNumber() : packet_number_(UninitializedPacketNumber()) {}
-
- // Construct a packet number from uint64_t. |packet_number| cannot equal the
- // sentinel value.
- explicit constexpr QuicPacketNumber(uint64_t packet_number)
- : packet_number_(packet_number) {
- QUICHE_DCHECK_NE(UninitializedPacketNumber(), packet_number)
- << "Use default constructor for uninitialized packet number";
- }
-
- // The sentinel value representing an uninitialized packet number.
- static constexpr uint64_t UninitializedPacketNumber() {
- return std::numeric_limits<uint64_t>::max();
- }
-
- // Packet number becomes uninitialized after calling this function.
- void Clear();
-
- // Updates this packet number to be |new_value| if it is greater than current
- // value.
- void UpdateMax(QuicPacketNumber new_value);
-
- // REQUIRES: IsInitialized() == true.
- uint64_t Hash() const;
-
- // Converts packet number to uint64_t.
- // REQUIRES: IsInitialized() == true.
- uint64_t ToUint64() const;
-
- // Returns true if packet number is considered initialized.
- bool IsInitialized() const;
-
- // REQUIRES: IsInitialized() == true && ToUint64() <
- // numeric_limits<uint64_t>::max() - 1.
- QuicPacketNumber& operator++();
- QuicPacketNumber operator++(int);
- // REQUIRES: IsInitialized() == true && ToUint64() >= 1.
- QuicPacketNumber& operator--();
- QuicPacketNumber operator--(int);
-
- // REQUIRES: IsInitialized() == true && numeric_limits<uint64_t>::max() -
- // ToUint64() > |delta|.
- QuicPacketNumber& operator+=(uint64_t delta);
- // REQUIRES: IsInitialized() == true && ToUint64() >= |delta|.
- QuicPacketNumber& operator-=(uint64_t delta);
-
- // Human-readable representation suitable for logging.
- std::string ToString() const;
-
- QUIC_EXPORT_PRIVATE friend std::ostream& operator<<(
- std::ostream& os,
- const QuicPacketNumber& p);
-
- private:
- // All following operators REQUIRE operands.Initialized() == true.
- friend inline bool operator==(QuicPacketNumber lhs, QuicPacketNumber rhs);
- friend inline bool operator!=(QuicPacketNumber lhs, QuicPacketNumber rhs);
- friend inline bool operator<(QuicPacketNumber lhs, QuicPacketNumber rhs);
- friend inline bool operator<=(QuicPacketNumber lhs, QuicPacketNumber rhs);
- friend inline bool operator>(QuicPacketNumber lhs, QuicPacketNumber rhs);
- friend inline bool operator>=(QuicPacketNumber lhs, QuicPacketNumber rhs);
-
- // REQUIRES: numeric_limits<uint64_t>::max() - lhs.ToUint64() > |delta|.
- friend inline QuicPacketNumber operator+(QuicPacketNumber lhs,
- uint64_t delta);
- // REQUIRES: lhs.ToUint64() >= |delta|.
- friend inline QuicPacketNumber operator-(QuicPacketNumber lhs,
- uint64_t delta);
- // REQUIRES: lhs >= rhs.
- friend inline uint64_t operator-(QuicPacketNumber lhs, QuicPacketNumber rhs);
-
- uint64_t packet_number_;
-};
-
-class QUIC_EXPORT_PRIVATE QuicPacketNumberHash {
- public:
- uint64_t operator()(QuicPacketNumber packet_number) const noexcept {
- return packet_number.Hash();
- }
-};
-
-inline bool operator==(QuicPacketNumber lhs, QuicPacketNumber rhs) {
- QUICHE_DCHECK(lhs.IsInitialized() && rhs.IsInitialized())
- << lhs << " vs. " << rhs;
- return lhs.packet_number_ == rhs.packet_number_;
-}
-
-inline bool operator!=(QuicPacketNumber lhs, QuicPacketNumber rhs) {
- QUICHE_DCHECK(lhs.IsInitialized() && rhs.IsInitialized())
- << lhs << " vs. " << rhs;
- return lhs.packet_number_ != rhs.packet_number_;
-}
-
-inline bool operator<(QuicPacketNumber lhs, QuicPacketNumber rhs) {
- QUICHE_DCHECK(lhs.IsInitialized() && rhs.IsInitialized())
- << lhs << " vs. " << rhs;
- return lhs.packet_number_ < rhs.packet_number_;
-}
-
-inline bool operator<=(QuicPacketNumber lhs, QuicPacketNumber rhs) {
- QUICHE_DCHECK(lhs.IsInitialized() && rhs.IsInitialized())
- << lhs << " vs. " << rhs;
- return lhs.packet_number_ <= rhs.packet_number_;
-}
-
-inline bool operator>(QuicPacketNumber lhs, QuicPacketNumber rhs) {
- QUICHE_DCHECK(lhs.IsInitialized() && rhs.IsInitialized())
- << lhs << " vs. " << rhs;
- return lhs.packet_number_ > rhs.packet_number_;
-}
-
-inline bool operator>=(QuicPacketNumber lhs, QuicPacketNumber rhs) {
- QUICHE_DCHECK(lhs.IsInitialized() && rhs.IsInitialized())
- << lhs << " vs. " << rhs;
- return lhs.packet_number_ >= rhs.packet_number_;
-}
-
-inline QuicPacketNumber operator+(QuicPacketNumber lhs, uint64_t delta) {
-#ifndef NDEBUG
- QUICHE_DCHECK(lhs.IsInitialized());
- QUICHE_DCHECK_GT(std::numeric_limits<uint64_t>::max() - lhs.ToUint64(),
- delta);
-#endif
- return QuicPacketNumber(lhs.packet_number_ + delta);
-}
-
-inline QuicPacketNumber operator-(QuicPacketNumber lhs, uint64_t delta) {
-#ifndef NDEBUG
- QUICHE_DCHECK(lhs.IsInitialized());
- QUICHE_DCHECK_GE(lhs.ToUint64(), delta);
-#endif
- return QuicPacketNumber(lhs.packet_number_ - delta);
-}
-
-inline uint64_t operator-(QuicPacketNumber lhs, QuicPacketNumber rhs) {
- QUICHE_DCHECK(lhs.IsInitialized() && rhs.IsInitialized() && lhs >= rhs)
- << lhs << " vs. " << rhs;
- return lhs.packet_number_ - rhs.packet_number_;
-}
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_QUIC_PACKET_NUMBER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_packet_number_test.cc b/chromium/net/third_party/quiche/src/quic/core/quic_packet_number_test.cc
deleted file mode 100644
index b696025094d..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_packet_number_test.cc
+++ /dev/null
@@ -1,67 +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 "quic/core/quic_packet_number.h"
-
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_test.h"
-
-namespace quic {
-
-namespace test {
-
-namespace {
-
-TEST(QuicPacketNumberTest, BasicTest) {
- QuicPacketNumber num;
- EXPECT_FALSE(num.IsInitialized());
-
- QuicPacketNumber num2(10);
- EXPECT_TRUE(num2.IsInitialized());
- EXPECT_EQ(10u, num2.ToUint64());
- EXPECT_EQ(10u, num2.Hash());
- num2.UpdateMax(num);
- EXPECT_EQ(10u, num2.ToUint64());
- num2.UpdateMax(QuicPacketNumber(9));
- EXPECT_EQ(10u, num2.ToUint64());
- num2.UpdateMax(QuicPacketNumber(11));
- EXPECT_EQ(11u, num2.ToUint64());
- num2.Clear();
- EXPECT_FALSE(num2.IsInitialized());
- num2.UpdateMax(QuicPacketNumber(9));
- EXPECT_EQ(9u, num2.ToUint64());
-
- QuicPacketNumber num4(0);
- EXPECT_TRUE(num4.IsInitialized());
- EXPECT_EQ(0u, num4.ToUint64());
- EXPECT_EQ(0u, num4.Hash());
- num4.Clear();
- EXPECT_FALSE(num4.IsInitialized());
-}
-
-TEST(QuicPacketNumberTest, Operators) {
- QuicPacketNumber num(100);
- EXPECT_EQ(QuicPacketNumber(100), num++);
- EXPECT_EQ(QuicPacketNumber(101), num);
- EXPECT_EQ(QuicPacketNumber(101), num--);
- EXPECT_EQ(QuicPacketNumber(100), num);
-
- EXPECT_EQ(QuicPacketNumber(101), ++num);
- EXPECT_EQ(QuicPacketNumber(100), --num);
-
- QuicPacketNumber num3(0);
- EXPECT_EQ(QuicPacketNumber(0), num3++);
- EXPECT_EQ(QuicPacketNumber(1), num3);
- EXPECT_EQ(QuicPacketNumber(2), ++num3);
-
- EXPECT_EQ(QuicPacketNumber(2), num3--);
- EXPECT_EQ(QuicPacketNumber(1), num3);
- EXPECT_EQ(QuicPacketNumber(0), --num3);
-}
-
-} // namespace
-
-} // namespace test
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_packet_reader.cc b/chromium/net/third_party/quiche/src/quic/core/quic_packet_reader.cc
deleted file mode 100644
index 3a8a9b4fe3d..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_packet_reader.cc
+++ /dev/null
@@ -1,135 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_packet_reader.h"
-
-#include "absl/base/macros.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_process_packet_interface.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_flag_utils.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_ip_address.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/platform/api/quic_server_stats.h"
-#include "quic/platform/api/quic_socket_address.h"
-
-namespace quic {
-
-QuicPacketReader::QuicPacketReader()
- : read_buffers_(kNumPacketsPerReadMmsgCall),
- read_results_(kNumPacketsPerReadMmsgCall) {
- QUICHE_DCHECK_EQ(read_buffers_.size(), read_results_.size());
- for (size_t i = 0; i < read_results_.size(); ++i) {
- read_results_[i].packet_buffer.buffer = read_buffers_[i].packet_buffer;
- read_results_[i].packet_buffer.buffer_len =
- sizeof(read_buffers_[i].packet_buffer);
-
- read_results_[i].control_buffer.buffer = read_buffers_[i].control_buffer;
- read_results_[i].control_buffer.buffer_len =
- sizeof(read_buffers_[i].control_buffer);
- }
-}
-
-QuicPacketReader::~QuicPacketReader() = default;
-
-bool QuicPacketReader::ReadAndDispatchPackets(
- int fd,
- int port,
- const QuicClock& clock,
- ProcessPacketInterface* processor,
- QuicPacketCount* /*packets_dropped*/) {
- // Reset all read_results for reuse.
- for (size_t i = 0; i < read_results_.size(); ++i) {
- read_results_[i].Reset(
- /*packet_buffer_length=*/sizeof(read_buffers_[i].packet_buffer));
- }
-
- // Use clock.Now() as the packet receipt time, the time between packet
- // arriving at the host and now is considered part of the network delay.
- QuicTime now = clock.Now();
-
- size_t packets_read = socket_api_.ReadMultiplePackets(
- fd,
- BitMask64(QuicUdpPacketInfoBit::DROPPED_PACKETS,
- QuicUdpPacketInfoBit::PEER_ADDRESS,
- QuicUdpPacketInfoBit::V4_SELF_IP,
- QuicUdpPacketInfoBit::V6_SELF_IP,
- QuicUdpPacketInfoBit::RECV_TIMESTAMP, QuicUdpPacketInfoBit::TTL,
- QuicUdpPacketInfoBit::GOOGLE_PACKET_HEADER),
- &read_results_);
- for (size_t i = 0; i < packets_read; ++i) {
- auto& result = read_results_[i];
- if (!result.ok) {
- QUIC_CODE_COUNT(quic_packet_reader_read_failure);
- continue;
- }
-
- if (!result.packet_info.HasValue(QuicUdpPacketInfoBit::PEER_ADDRESS)) {
- QUIC_BUG(quic_bug_10329_1) << "Unable to get peer socket address.";
- continue;
- }
-
- QuicSocketAddress peer_address =
- result.packet_info.peer_address().Normalized();
-
- QuicIpAddress self_ip = GetSelfIpFromPacketInfo(
- result.packet_info, peer_address.host().IsIPv6());
- if (!self_ip.IsInitialized()) {
- QUIC_BUG(quic_bug_10329_2) << "Unable to get self IP address.";
- continue;
- }
-
- bool has_ttl = result.packet_info.HasValue(QuicUdpPacketInfoBit::TTL);
- int ttl = has_ttl ? result.packet_info.ttl() : 0;
- if (!has_ttl) {
- QUIC_CODE_COUNT(quic_packet_reader_no_ttl);
- }
-
- char* headers = nullptr;
- size_t headers_length = 0;
- if (result.packet_info.HasValue(
- QuicUdpPacketInfoBit::GOOGLE_PACKET_HEADER)) {
- headers = result.packet_info.google_packet_headers().buffer;
- headers_length = result.packet_info.google_packet_headers().buffer_len;
- } else {
- QUIC_CODE_COUNT(quic_packet_reader_no_google_packet_header);
- }
-
- QuicReceivedPacket packet(
- result.packet_buffer.buffer, result.packet_buffer.buffer_len, now,
- /*owns_buffer=*/false, ttl, has_ttl, headers, headers_length,
- /*owns_header_buffer=*/false);
-
- QuicSocketAddress self_address(self_ip, port);
- processor->ProcessPacket(self_address, peer_address, packet);
- }
-
- // We may not have read all of the packets available on the socket.
- return packets_read == kNumPacketsPerReadMmsgCall;
-}
-
-// static
-QuicIpAddress QuicPacketReader::GetSelfIpFromPacketInfo(
- const QuicUdpPacketInfo& packet_info,
- bool prefer_v6_ip) {
- if (prefer_v6_ip) {
- if (packet_info.HasValue(QuicUdpPacketInfoBit::V6_SELF_IP)) {
- return packet_info.self_v6_ip();
- }
- if (packet_info.HasValue(QuicUdpPacketInfoBit::V4_SELF_IP)) {
- return packet_info.self_v4_ip();
- }
- } else {
- if (packet_info.HasValue(QuicUdpPacketInfoBit::V4_SELF_IP)) {
- return packet_info.self_v4_ip();
- }
- if (packet_info.HasValue(QuicUdpPacketInfoBit::V6_SELF_IP)) {
- return packet_info.self_v6_ip();
- }
- }
- return QuicIpAddress();
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_packet_reader.h b/chromium/net/third_party/quiche/src/quic/core/quic_packet_reader.h
deleted file mode 100644
index 1c93722f9ed..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_packet_reader.h
+++ /dev/null
@@ -1,67 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// A class to read incoming QUIC packets from the UDP socket.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_PACKET_READER_H_
-#define QUICHE_QUIC_CORE_QUIC_PACKET_READER_H_
-
-#include "absl/base/optimization.h"
-#include "quic/core/quic_clock.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_process_packet_interface.h"
-#include "quic/core/quic_udp_socket.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_socket_address.h"
-
-namespace quic {
-
-// Read in larger batches to minimize recvmmsg overhead.
-const int kNumPacketsPerReadMmsgCall = 16;
-
-class QUIC_EXPORT_PRIVATE QuicPacketReader {
- public:
- QuicPacketReader();
- QuicPacketReader(const QuicPacketReader&) = delete;
- QuicPacketReader& operator=(const QuicPacketReader&) = delete;
-
- virtual ~QuicPacketReader();
-
- // Reads a number of packets from the given fd, and then passes them off to
- // the PacketProcessInterface. Returns true if there may be additional
- // packets available on the socket.
- // Populates |packets_dropped| if it is non-null and the socket is configured
- // to track dropped packets and some packets are read.
- // If the socket has timestamping enabled, the per packet timestamps will be
- // passed to the processor. Otherwise, |clock| will be used.
- virtual bool ReadAndDispatchPackets(int fd,
- int port,
- const QuicClock& clock,
- ProcessPacketInterface* processor,
- QuicPacketCount* packets_dropped);
-
- private:
- // Return the self ip from |packet_info|.
- // For dual stack sockets, |packet_info| may contain both a v4 and a v6 ip, in
- // that case, |prefer_v6_ip| is used to determine which one is used as the
- // return value. If neither v4 nor v6 ip exists, return an uninitialized ip.
- static QuicIpAddress GetSelfIpFromPacketInfo(
- const QuicUdpPacketInfo& packet_info,
- bool prefer_v6_ip);
-
- struct QUIC_EXPORT_PRIVATE ReadBuffer {
- ABSL_CACHELINE_ALIGNED char
- control_buffer[kDefaultUdpPacketControlBufferSize]; // For ancillary
- // data.
- ABSL_CACHELINE_ALIGNED char packet_buffer[kMaxIncomingPacketSize];
- };
-
- QuicUdpSocketApi socket_api_;
- std::vector<ReadBuffer> read_buffers_;
- QuicUdpSocketApi::ReadPacketResults read_results_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_QUIC_PACKET_READER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_packet_writer.h b/chromium/net/third_party/quiche/src/quic/core/quic_packet_writer.h
deleted file mode 100644
index 875f25a8f9a..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_packet_writer.h
+++ /dev/null
@@ -1,163 +0,0 @@
-// Copyright 2013 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_PACKET_WRITER_H_
-#define QUICHE_QUIC_CORE_QUIC_PACKET_WRITER_H_
-
-#include <cstddef>
-#include <utility>
-
-#include "quic/core/quic_packets.h"
-#include "quic/platform/api/quic_export.h"
-#include "quic/platform/api/quic_socket_address.h"
-
-namespace quic {
-
-struct WriteResult;
-
-struct QUIC_EXPORT_PRIVATE PerPacketOptions {
- virtual ~PerPacketOptions() {}
-
- // Returns a heap-allocated copy of |this|.
- //
- // The subclass implementation of this method should look like this:
- // return std::make_unique<MyAwesomePerPacketOptions>(*this);
- //
- // This method is declared pure virtual in order to ensure the subclasses
- // would not forget to override it.
- virtual std::unique_ptr<PerPacketOptions> Clone() const = 0;
-
- // Specifies ideal release time delay for this packet.
- QuicTime::Delta release_time_delay = QuicTime::Delta::Zero();
- // Whether it is allowed to send this packet without |release_time_delay|.
- bool allow_burst = false;
-};
-
-// An interface between writers and the entity managing the
-// socket (in our case the QuicDispatcher). This allows the Dispatcher to
-// control writes, and manage any writers who end up write blocked.
-// A concrete writer works in one of the two modes:
-// - PassThrough mode. This is the default mode. Caller calls WritePacket with
-// caller-allocated packet buffer. Unless the writer is blocked, each call to
-// WritePacket triggers a write using the underlying socket API.
-//
-// - Batch mode. In this mode, a call to WritePacket may not cause a packet to
-// be sent using the underlying socket API. Instead, multiple packets are
-// saved in the writer's internal buffer until they are flushed. The flush can
-// be explicit, by calling Flush, or implicit, e.g. by calling
-// WritePacket when the internal buffer is near full.
-//
-// Buffer management:
-// In Batch mode, a writer manages an internal buffer, which is large enough to
-// hold multiple packets' data. If the caller calls WritePacket with a
-// caller-allocated packet buffer, the writer will memcpy the buffer into the
-// internal buffer. Caller can also avoid this memcpy by:
-// 1. Call GetNextWriteLocation to get a pointer P into the internal buffer.
-// 2. Serialize the packet directly to P.
-// 3. Call WritePacket with P as the |buffer|.
-class QUIC_EXPORT_PRIVATE QuicPacketWriter {
- public:
- virtual ~QuicPacketWriter() {}
-
- // PassThrough mode:
- // Sends the packet out to the peer, with some optional per-packet options.
- // If the write succeeded, the result's status is WRITE_STATUS_OK and
- // bytes_written is populated. If the write failed, the result's status is
- // WRITE_STATUS_BLOCKED or WRITE_STATUS_ERROR and error_code is populated.
- //
- // Batch mode:
- // If the writer is blocked, return WRITE_STATUS_BLOCKED immediately.
- // If the packet can be batched with other buffered packets, save the packet
- // to the internal buffer.
- // If the packet can not be batched, or the internal buffer is near full after
- // it is buffered, the internal buffer is flushed to free up space.
- // Return WriteResult(WRITE_STATUS_OK, <bytes_flushed>) on success. When
- // <bytes_flushed> is zero, it means the packet is buffered and not flushed.
- // Return WRITE_STATUS_BLOCKED if the packet is not buffered and the socket is
- // blocked while flushing.
- // Otherwise return an error status.
- //
- // Options must be either null, or created for the particular QuicPacketWriter
- // implementation. Options may be ignored, depending on the implementation.
- //
- // Some comment about memory management if |buffer| was previously acquired
- // by a call to "GetNextWriteLocation()":
- //
- // a) When WRITE_STATUS_OK is returned, the caller expects the writer owns the
- // packet buffers and they will be released when the write finishes.
- //
- // b) When this function returns any status >= WRITE_STATUS_ERROR, the caller
- // expects the writer releases the buffer (if needed) before the function
- // returns.
- //
- // c) When WRITE_STATUS_BLOCKED is returned, the caller makes a copy of the
- // buffer and will retry after unblock, so if |payload| is allocated from
- // GetNextWriteLocation(), it
- // 1) needs to be released before return, and
- // 2) the content of |payload| should not change after return.
- //
- // d) When WRITE_STATUS_BLOCKED_DATA_BUFFERED is returned, the caller expects
- // 1) the writer owns the packet buffers, and 2) the writer will re-send the
- // packet when it unblocks.
- virtual WriteResult WritePacket(const char* buffer,
- size_t buf_len,
- const QuicIpAddress& self_address,
- const QuicSocketAddress& peer_address,
- PerPacketOptions* options) = 0;
-
- // Returns true if the network socket is not writable.
- virtual bool IsWriteBlocked() const = 0;
-
- // Records that the socket has become writable, for example when an EPOLLOUT
- // is received or an asynchronous write completes.
- virtual void SetWritable() = 0;
-
- // Returns the maximum size of the packet which can be written using this
- // writer for the supplied peer address. This size may actually exceed the
- // size of a valid QUIC packet.
- virtual QuicByteCount GetMaxPacketSize(
- const QuicSocketAddress& peer_address) const = 0;
-
- // Returns true if the socket supports release timestamp.
- virtual bool SupportsReleaseTime() const = 0;
-
- // True=Batch mode. False=PassThrough mode.
- virtual bool IsBatchMode() const = 0;
-
- // PassThrough mode: Return {nullptr, nullptr}
- //
- // Batch mode:
- // Return the QuicPacketBuffer for the next packet. A minimum of
- // kMaxOutgoingPacketSize is guaranteed to be available from the returned
- // address. If the internal buffer does not have enough space,
- // {nullptr, nullptr} is returned. All arguments should be identical to the
- // follow-up call to |WritePacket|, they are here to allow advanced packet
- // memory management in packet writers, e.g. one packet buffer pool per
- // |peer_address|.
- //
- // If QuicPacketBuffer.release_buffer is !nullptr, it should be called iff
- // the caller does not call WritePacket for the returned buffer.
- virtual QuicPacketBuffer GetNextWriteLocation(
- const QuicIpAddress& self_address,
- const QuicSocketAddress& peer_address) = 0;
-
- // PassThrough mode: Return WriteResult(WRITE_STATUS_OK, 0).
- //
- // Batch mode:
- // Try send all buffered packets.
- // - Return WriteResult(WRITE_STATUS_OK, <bytes_flushed>) if all buffered
- // packets were sent successfully.
- // - Return WRITE_STATUS_BLOCKED if the underlying socket is blocked while
- // sending. Some packets may have been sent, packets not sent will stay in
- // the internal buffer.
- // - Return a status >= WRITE_STATUS_ERROR if an error was encuontered while
- // sending. As this is not a re-tryable error, any batched packets which
- // were on memory acquired via GetNextWriteLocation() should be released and
- // the batch should be dropped.
- virtual WriteResult Flush() = 0;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_QUIC_PACKET_WRITER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_packet_writer_wrapper.cc b/chromium/net/third_party/quiche/src/quic/core/quic_packet_writer_wrapper.cc
deleted file mode 100644
index 6f7c54ef4a4..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_packet_writer_wrapper.cc
+++ /dev/null
@@ -1,79 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_packet_writer_wrapper.h"
-
-#include "quic/core/quic_types.h"
-
-namespace quic {
-
-QuicPacketWriterWrapper::QuicPacketWriterWrapper() = default;
-
-QuicPacketWriterWrapper::~QuicPacketWriterWrapper() {
- unset_writer();
-}
-
-WriteResult QuicPacketWriterWrapper::WritePacket(
- const char* buffer,
- size_t buf_len,
- const QuicIpAddress& self_address,
- const QuicSocketAddress& peer_address,
- PerPacketOptions* options) {
- return writer_->WritePacket(buffer, buf_len, self_address, peer_address,
- options);
-}
-
-bool QuicPacketWriterWrapper::IsWriteBlocked() const {
- return writer_->IsWriteBlocked();
-}
-
-void QuicPacketWriterWrapper::SetWritable() {
- writer_->SetWritable();
-}
-
-QuicByteCount QuicPacketWriterWrapper::GetMaxPacketSize(
- const QuicSocketAddress& peer_address) const {
- return writer_->GetMaxPacketSize(peer_address);
-}
-
-bool QuicPacketWriterWrapper::SupportsReleaseTime() const {
- return writer_->SupportsReleaseTime();
-}
-
-bool QuicPacketWriterWrapper::IsBatchMode() const {
- return writer_->IsBatchMode();
-}
-
-QuicPacketBuffer QuicPacketWriterWrapper::GetNextWriteLocation(
- const QuicIpAddress& self_address,
- const QuicSocketAddress& peer_address) {
- return writer_->GetNextWriteLocation(self_address, peer_address);
-}
-
-WriteResult QuicPacketWriterWrapper::Flush() {
- return writer_->Flush();
-}
-
-void QuicPacketWriterWrapper::set_writer(QuicPacketWriter* writer) {
- unset_writer();
- writer_ = writer;
- owns_writer_ = true;
-}
-
-void QuicPacketWriterWrapper::set_non_owning_writer(QuicPacketWriter* writer) {
- unset_writer();
- writer_ = writer;
- owns_writer_ = false;
-}
-
-void QuicPacketWriterWrapper::unset_writer() {
- if (owns_writer_) {
- delete writer_;
- }
-
- owns_writer_ = false;
- writer_ = nullptr;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_packet_writer_wrapper.h b/chromium/net/third_party/quiche/src/quic/core/quic_packet_writer_wrapper.h
deleted file mode 100644
index e6dac045a89..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_packet_writer_wrapper.h
+++ /dev/null
@@ -1,62 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_PACKET_WRITER_WRAPPER_H_
-#define QUICHE_QUIC_CORE_QUIC_PACKET_WRITER_WRAPPER_H_
-
-#include <cstddef>
-#include <memory>
-
-#include "quic/core/quic_packet_writer.h"
-
-namespace quic {
-
-// Wraps a writer object to allow dynamically extending functionality. Use
-// cases: replace writer while dispatcher and connections hold on to the
-// wrapper; mix in monitoring; mix in mocks in unit tests.
-class QUIC_NO_EXPORT QuicPacketWriterWrapper : public QuicPacketWriter {
- public:
- QuicPacketWriterWrapper();
- QuicPacketWriterWrapper(const QuicPacketWriterWrapper&) = delete;
- QuicPacketWriterWrapper& operator=(const QuicPacketWriterWrapper&) = delete;
- ~QuicPacketWriterWrapper() override;
-
- // Default implementation of the QuicPacketWriter interface. Passes everything
- // to |writer_|.
- WriteResult WritePacket(const char* buffer,
- size_t buf_len,
- const QuicIpAddress& self_address,
- const QuicSocketAddress& peer_address,
- PerPacketOptions* options) override;
- bool IsWriteBlocked() const override;
- void SetWritable() override;
- QuicByteCount GetMaxPacketSize(
- const QuicSocketAddress& peer_address) const override;
- bool SupportsReleaseTime() const override;
- bool IsBatchMode() const override;
- QuicPacketBuffer GetNextWriteLocation(
- const QuicIpAddress& self_address,
- const QuicSocketAddress& peer_address) override;
- WriteResult Flush() override;
-
- // Takes ownership of |writer|.
- void set_writer(QuicPacketWriter* writer);
-
- // Does not take ownership of |writer|.
- void set_non_owning_writer(QuicPacketWriter* writer);
-
- virtual void set_peer_address(const QuicSocketAddress& /*peer_address*/) {}
-
- QuicPacketWriter* writer() { return writer_; }
-
- private:
- void unset_writer();
-
- QuicPacketWriter* writer_ = nullptr;
- bool owns_writer_ = false;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_QUIC_PACKET_WRITER_WRAPPER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_packets.cc b/chromium/net/third_party/quiche/src/quic/core/quic_packets.cc
deleted file mode 100644
index d625b5dcb6a..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_packets.cc
+++ /dev/null
@@ -1,596 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_packets.h"
-
-#include <utility>
-
-#include "absl/strings/escaping.h"
-#include "absl/strings/str_cat.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_connection_id.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_utils.h"
-#include "quic/core/quic_versions.h"
-#include "quic/platform/api/quic_flag_utils.h"
-#include "quic/platform/api/quic_flags.h"
-
-namespace quic {
-
-QuicConnectionId GetServerConnectionIdAsRecipient(
- const QuicPacketHeader& header,
- Perspective perspective) {
- if (perspective == Perspective::IS_SERVER) {
- return header.destination_connection_id;
- }
- return header.source_connection_id;
-}
-
-QuicConnectionId GetClientConnectionIdAsRecipient(
- const QuicPacketHeader& header,
- Perspective perspective) {
- if (perspective == Perspective::IS_CLIENT) {
- return header.destination_connection_id;
- }
- return header.source_connection_id;
-}
-
-QuicConnectionId GetServerConnectionIdAsSender(const QuicPacketHeader& header,
- Perspective perspective) {
- if (perspective == Perspective::IS_CLIENT) {
- return header.destination_connection_id;
- }
- return header.source_connection_id;
-}
-
-QuicConnectionIdIncluded GetServerConnectionIdIncludedAsSender(
- const QuicPacketHeader& header,
- Perspective perspective) {
- if (perspective == Perspective::IS_CLIENT) {
- return header.destination_connection_id_included;
- }
- return header.source_connection_id_included;
-}
-
-QuicConnectionId GetClientConnectionIdAsSender(const QuicPacketHeader& header,
- Perspective perspective) {
- if (perspective == Perspective::IS_CLIENT) {
- return header.source_connection_id;
- }
- return header.destination_connection_id;
-}
-
-QuicConnectionIdIncluded GetClientConnectionIdIncludedAsSender(
- const QuicPacketHeader& header,
- Perspective perspective) {
- if (perspective == Perspective::IS_CLIENT) {
- return header.source_connection_id_included;
- }
- return header.destination_connection_id_included;
-}
-
-QuicConnectionIdLength GetIncludedConnectionIdLength(
- QuicConnectionId connection_id,
- QuicConnectionIdIncluded connection_id_included) {
- QUICHE_DCHECK(connection_id_included == CONNECTION_ID_PRESENT ||
- connection_id_included == CONNECTION_ID_ABSENT);
- return connection_id_included == CONNECTION_ID_PRESENT
- ? static_cast<QuicConnectionIdLength>(connection_id.length())
- : PACKET_0BYTE_CONNECTION_ID;
-}
-
-QuicConnectionIdLength GetIncludedDestinationConnectionIdLength(
- const QuicPacketHeader& header) {
- return GetIncludedConnectionIdLength(
- header.destination_connection_id,
- header.destination_connection_id_included);
-}
-
-QuicConnectionIdLength GetIncludedSourceConnectionIdLength(
- const QuicPacketHeader& header) {
- return GetIncludedConnectionIdLength(header.source_connection_id,
- header.source_connection_id_included);
-}
-
-size_t GetPacketHeaderSize(QuicTransportVersion version,
- const QuicPacketHeader& header) {
- return GetPacketHeaderSize(
- version, GetIncludedDestinationConnectionIdLength(header),
- GetIncludedSourceConnectionIdLength(header), header.version_flag,
- header.nonce != nullptr, header.packet_number_length,
- header.retry_token_length_length, header.retry_token.length(),
- header.length_length);
-}
-
-size_t GetPacketHeaderSize(
- QuicTransportVersion version,
- QuicConnectionIdLength destination_connection_id_length,
- QuicConnectionIdLength source_connection_id_length,
- bool include_version,
- bool include_diversification_nonce,
- QuicPacketNumberLength packet_number_length,
- QuicVariableLengthIntegerLength retry_token_length_length,
- QuicByteCount retry_token_length,
- QuicVariableLengthIntegerLength length_length) {
- if (VersionHasIetfInvariantHeader(version)) {
- if (include_version) {
- // Long header.
- size_t size = kPacketHeaderTypeSize + kConnectionIdLengthSize +
- destination_connection_id_length +
- source_connection_id_length + packet_number_length +
- kQuicVersionSize;
- if (include_diversification_nonce) {
- size += kDiversificationNonceSize;
- }
- if (VersionHasLengthPrefixedConnectionIds(version)) {
- size += kConnectionIdLengthSize;
- }
- QUICHE_DCHECK(
- QuicVersionHasLongHeaderLengths(version) ||
- retry_token_length_length + retry_token_length + length_length == 0);
- if (QuicVersionHasLongHeaderLengths(version)) {
- size += retry_token_length_length + retry_token_length + length_length;
- }
- return size;
- }
- // Short header.
- return kPacketHeaderTypeSize + destination_connection_id_length +
- packet_number_length;
- }
- // Google QUIC versions <= 43 can only carry one connection ID.
- QUICHE_DCHECK(destination_connection_id_length == 0 ||
- source_connection_id_length == 0);
- return kPublicFlagsSize + destination_connection_id_length +
- source_connection_id_length +
- (include_version ? kQuicVersionSize : 0) + packet_number_length +
- (include_diversification_nonce ? kDiversificationNonceSize : 0);
-}
-
-size_t GetStartOfEncryptedData(QuicTransportVersion version,
- const QuicPacketHeader& header) {
- return GetPacketHeaderSize(version, header);
-}
-
-size_t GetStartOfEncryptedData(
- QuicTransportVersion version,
- QuicConnectionIdLength destination_connection_id_length,
- QuicConnectionIdLength source_connection_id_length,
- bool include_version,
- bool include_diversification_nonce,
- QuicPacketNumberLength packet_number_length,
- QuicVariableLengthIntegerLength retry_token_length_length,
- QuicByteCount retry_token_length,
- QuicVariableLengthIntegerLength length_length) {
- // Encryption starts before private flags.
- return GetPacketHeaderSize(
- version, destination_connection_id_length, source_connection_id_length,
- include_version, include_diversification_nonce, packet_number_length,
- retry_token_length_length, retry_token_length, length_length);
-}
-
-QuicPacketHeader::QuicPacketHeader()
- : destination_connection_id(EmptyQuicConnectionId()),
- destination_connection_id_included(CONNECTION_ID_PRESENT),
- source_connection_id(EmptyQuicConnectionId()),
- source_connection_id_included(CONNECTION_ID_ABSENT),
- reset_flag(false),
- version_flag(false),
- has_possible_stateless_reset_token(false),
- packet_number_length(PACKET_4BYTE_PACKET_NUMBER),
- version(UnsupportedQuicVersion()),
- nonce(nullptr),
- form(GOOGLE_QUIC_PACKET),
- long_packet_type(INITIAL),
- possible_stateless_reset_token({}),
- retry_token_length_length(VARIABLE_LENGTH_INTEGER_LENGTH_0),
- retry_token(absl::string_view()),
- length_length(VARIABLE_LENGTH_INTEGER_LENGTH_0),
- remaining_packet_length(0) {}
-
-QuicPacketHeader::QuicPacketHeader(const QuicPacketHeader& other) = default;
-
-QuicPacketHeader::~QuicPacketHeader() {}
-
-QuicPacketHeader& QuicPacketHeader::operator=(const QuicPacketHeader& other) =
- default;
-
-QuicPublicResetPacket::QuicPublicResetPacket()
- : connection_id(EmptyQuicConnectionId()), nonce_proof(0) {}
-
-QuicPublicResetPacket::QuicPublicResetPacket(QuicConnectionId connection_id)
- : connection_id(connection_id), nonce_proof(0) {}
-
-QuicVersionNegotiationPacket::QuicVersionNegotiationPacket()
- : connection_id(EmptyQuicConnectionId()) {}
-
-QuicVersionNegotiationPacket::QuicVersionNegotiationPacket(
- QuicConnectionId connection_id)
- : connection_id(connection_id) {}
-
-QuicVersionNegotiationPacket::QuicVersionNegotiationPacket(
- const QuicVersionNegotiationPacket& other) = default;
-
-QuicVersionNegotiationPacket::~QuicVersionNegotiationPacket() {}
-
-QuicIetfStatelessResetPacket::QuicIetfStatelessResetPacket()
- : stateless_reset_token({}) {}
-
-QuicIetfStatelessResetPacket::QuicIetfStatelessResetPacket(
- const QuicPacketHeader& header,
- StatelessResetToken token)
- : header(header), stateless_reset_token(token) {}
-
-QuicIetfStatelessResetPacket::QuicIetfStatelessResetPacket(
- const QuicIetfStatelessResetPacket& other) = default;
-
-QuicIetfStatelessResetPacket::~QuicIetfStatelessResetPacket() {}
-
-std::ostream& operator<<(std::ostream& os, const QuicPacketHeader& header) {
- os << "{ destination_connection_id: " << header.destination_connection_id
- << " ("
- << (header.destination_connection_id_included == CONNECTION_ID_PRESENT
- ? "present"
- : "absent")
- << "), source_connection_id: " << header.source_connection_id << " ("
- << (header.source_connection_id_included == CONNECTION_ID_PRESENT
- ? "present"
- : "absent")
- << "), packet_number_length: "
- << static_cast<int>(header.packet_number_length)
- << ", reset_flag: " << header.reset_flag
- << ", version_flag: " << header.version_flag;
- if (header.version_flag) {
- os << ", version: " << ParsedQuicVersionToString(header.version);
- if (header.long_packet_type != INVALID_PACKET_TYPE) {
- os << ", long_packet_type: "
- << QuicUtils::QuicLongHeaderTypetoString(header.long_packet_type);
- }
- if (header.retry_token_length_length != VARIABLE_LENGTH_INTEGER_LENGTH_0) {
- os << ", retry_token_length_length: "
- << static_cast<int>(header.retry_token_length_length);
- }
- if (header.retry_token.length() != 0) {
- os << ", retry_token_length: " << header.retry_token.length();
- }
- if (header.length_length != VARIABLE_LENGTH_INTEGER_LENGTH_0) {
- os << ", length_length: " << static_cast<int>(header.length_length);
- }
- if (header.remaining_packet_length != 0) {
- os << ", remaining_packet_length: " << header.remaining_packet_length;
- }
- }
- if (header.nonce != nullptr) {
- os << ", diversification_nonce: "
- << absl::BytesToHexString(
- absl::string_view(header.nonce->data(), header.nonce->size()));
- }
- os << ", packet_number: " << header.packet_number << " }\n";
- return os;
-}
-
-QuicData::QuicData(const char* buffer, size_t length)
- : buffer_(buffer), length_(length), owns_buffer_(false) {}
-
-QuicData::QuicData(const char* buffer, size_t length, bool owns_buffer)
- : buffer_(buffer), length_(length), owns_buffer_(owns_buffer) {}
-
-QuicData::QuicData(absl::string_view packet_data)
- : buffer_(packet_data.data()),
- length_(packet_data.length()),
- owns_buffer_(false) {}
-
-QuicData::~QuicData() {
- if (owns_buffer_) {
- delete[] const_cast<char*>(buffer_);
- }
-}
-
-QuicPacket::QuicPacket(
- char* buffer,
- size_t length,
- bool owns_buffer,
- QuicConnectionIdLength destination_connection_id_length,
- QuicConnectionIdLength source_connection_id_length,
- bool includes_version,
- bool includes_diversification_nonce,
- QuicPacketNumberLength packet_number_length,
- QuicVariableLengthIntegerLength retry_token_length_length,
- QuicByteCount retry_token_length,
- QuicVariableLengthIntegerLength length_length)
- : QuicData(buffer, length, owns_buffer),
- buffer_(buffer),
- destination_connection_id_length_(destination_connection_id_length),
- source_connection_id_length_(source_connection_id_length),
- includes_version_(includes_version),
- includes_diversification_nonce_(includes_diversification_nonce),
- packet_number_length_(packet_number_length),
- retry_token_length_length_(retry_token_length_length),
- retry_token_length_(retry_token_length),
- length_length_(length_length) {}
-
-QuicPacket::QuicPacket(QuicTransportVersion /*version*/,
- char* buffer,
- size_t length,
- bool owns_buffer,
- const QuicPacketHeader& header)
- : QuicPacket(buffer,
- length,
- owns_buffer,
- GetIncludedDestinationConnectionIdLength(header),
- GetIncludedSourceConnectionIdLength(header),
- header.version_flag,
- header.nonce != nullptr,
- header.packet_number_length,
- header.retry_token_length_length,
- header.retry_token.length(),
- header.length_length) {}
-
-QuicEncryptedPacket::QuicEncryptedPacket(const char* buffer, size_t length)
- : QuicData(buffer, length) {}
-
-QuicEncryptedPacket::QuicEncryptedPacket(const char* buffer,
- size_t length,
- bool owns_buffer)
- : QuicData(buffer, length, owns_buffer) {}
-
-QuicEncryptedPacket::QuicEncryptedPacket(absl::string_view data)
- : QuicData(data) {}
-
-std::unique_ptr<QuicEncryptedPacket> QuicEncryptedPacket::Clone() const {
- char* buffer = new char[this->length()];
- memcpy(buffer, this->data(), this->length());
- return std::make_unique<QuicEncryptedPacket>(buffer, this->length(), true);
-}
-
-std::ostream& operator<<(std::ostream& os, const QuicEncryptedPacket& s) {
- os << s.length() << "-byte data";
- return os;
-}
-
-QuicReceivedPacket::QuicReceivedPacket(const char* buffer,
- size_t length,
- QuicTime receipt_time)
- : QuicReceivedPacket(buffer,
- length,
- receipt_time,
- false /* owns_buffer */) {}
-
-QuicReceivedPacket::QuicReceivedPacket(const char* buffer,
- size_t length,
- QuicTime receipt_time,
- bool owns_buffer)
- : QuicReceivedPacket(buffer,
- length,
- receipt_time,
- owns_buffer,
- 0 /* ttl */,
- true /* ttl_valid */) {}
-
-QuicReceivedPacket::QuicReceivedPacket(const char* buffer,
- size_t length,
- QuicTime receipt_time,
- bool owns_buffer,
- int ttl,
- bool ttl_valid)
- : quic::QuicReceivedPacket(buffer,
- length,
- receipt_time,
- owns_buffer,
- ttl,
- ttl_valid,
- nullptr /* packet_headers */,
- 0 /* headers_length */,
- false /* owns_header_buffer */) {}
-
-QuicReceivedPacket::QuicReceivedPacket(const char* buffer,
- size_t length,
- QuicTime receipt_time,
- bool owns_buffer,
- int ttl,
- bool ttl_valid,
- char* packet_headers,
- size_t headers_length,
- bool owns_header_buffer)
- : QuicEncryptedPacket(buffer, length, owns_buffer),
- receipt_time_(receipt_time),
- ttl_(ttl_valid ? ttl : -1),
- packet_headers_(packet_headers),
- headers_length_(headers_length),
- owns_header_buffer_(owns_header_buffer) {}
-
-QuicReceivedPacket::~QuicReceivedPacket() {
- if (owns_header_buffer_) {
- delete[] static_cast<char*>(packet_headers_);
- }
-}
-
-std::unique_ptr<QuicReceivedPacket> QuicReceivedPacket::Clone() const {
- char* buffer = new char[this->length()];
- memcpy(buffer, this->data(), this->length());
- if (this->packet_headers()) {
- char* headers_buffer = new char[this->headers_length()];
- memcpy(headers_buffer, this->packet_headers(), this->headers_length());
- return std::make_unique<QuicReceivedPacket>(
- buffer, this->length(), receipt_time(), true, ttl(), ttl() >= 0,
- headers_buffer, this->headers_length(), true);
- }
-
- return std::make_unique<QuicReceivedPacket>(
- buffer, this->length(), receipt_time(), true, ttl(), ttl() >= 0);
-}
-
-std::ostream& operator<<(std::ostream& os, const QuicReceivedPacket& s) {
- os << s.length() << "-byte data";
- return os;
-}
-
-absl::string_view QuicPacket::AssociatedData(
- QuicTransportVersion version) const {
- return absl::string_view(
- data(),
- GetStartOfEncryptedData(version, destination_connection_id_length_,
- source_connection_id_length_, includes_version_,
- includes_diversification_nonce_,
- packet_number_length_, retry_token_length_length_,
- retry_token_length_, length_length_));
-}
-
-absl::string_view QuicPacket::Plaintext(QuicTransportVersion version) const {
- const size_t start_of_encrypted_data = GetStartOfEncryptedData(
- version, destination_connection_id_length_, source_connection_id_length_,
- includes_version_, includes_diversification_nonce_, packet_number_length_,
- retry_token_length_length_, retry_token_length_, length_length_);
- return absl::string_view(data() + start_of_encrypted_data,
- length() - start_of_encrypted_data);
-}
-
-SerializedPacket::SerializedPacket(QuicPacketNumber packet_number,
- QuicPacketNumberLength packet_number_length,
- const char* encrypted_buffer,
- QuicPacketLength encrypted_length,
- bool has_ack,
- bool has_stop_waiting)
- : encrypted_buffer(encrypted_buffer),
- encrypted_length(encrypted_length),
- has_crypto_handshake(NOT_HANDSHAKE),
- packet_number(packet_number),
- packet_number_length(packet_number_length),
- encryption_level(ENCRYPTION_INITIAL),
- has_ack(has_ack),
- has_stop_waiting(has_stop_waiting),
- transmission_type(NOT_RETRANSMISSION),
- has_ack_frame_copy(false),
- has_ack_frequency(false),
- has_message(false),
- fate(SEND_TO_WRITER) {}
-
-SerializedPacket::SerializedPacket(SerializedPacket&& other)
- : has_crypto_handshake(other.has_crypto_handshake),
- packet_number(other.packet_number),
- packet_number_length(other.packet_number_length),
- encryption_level(other.encryption_level),
- has_ack(other.has_ack),
- has_stop_waiting(other.has_stop_waiting),
- transmission_type(other.transmission_type),
- largest_acked(other.largest_acked),
- has_ack_frame_copy(other.has_ack_frame_copy),
- has_ack_frequency(other.has_ack_frequency),
- has_message(other.has_message),
- fate(other.fate),
- peer_address(other.peer_address) {
- if (this != &other) {
- if (release_encrypted_buffer && encrypted_buffer != nullptr) {
- release_encrypted_buffer(encrypted_buffer);
- }
- encrypted_buffer = other.encrypted_buffer;
- encrypted_length = other.encrypted_length;
- release_encrypted_buffer = std::move(other.release_encrypted_buffer);
- other.release_encrypted_buffer = nullptr;
-
- retransmittable_frames.swap(other.retransmittable_frames);
- nonretransmittable_frames.swap(other.nonretransmittable_frames);
- }
-}
-
-SerializedPacket::~SerializedPacket() {
- if (release_encrypted_buffer && encrypted_buffer != nullptr) {
- release_encrypted_buffer(encrypted_buffer);
- }
-
- if (!retransmittable_frames.empty()) {
- DeleteFrames(&retransmittable_frames);
- }
- for (auto& frame : nonretransmittable_frames) {
- if (!has_ack_frame_copy && frame.type == ACK_FRAME) {
- // Do not delete ack frame if the packet does not own a copy of it.
- continue;
- }
- DeleteFrame(&frame);
- }
-}
-
-SerializedPacket* CopySerializedPacket(const SerializedPacket& serialized,
- QuicBufferAllocator* allocator,
- bool copy_buffer) {
- SerializedPacket* copy = new SerializedPacket(
- serialized.packet_number, serialized.packet_number_length,
- serialized.encrypted_buffer, serialized.encrypted_length,
- serialized.has_ack, serialized.has_stop_waiting);
- copy->has_crypto_handshake = serialized.has_crypto_handshake;
- copy->encryption_level = serialized.encryption_level;
- copy->transmission_type = serialized.transmission_type;
- copy->largest_acked = serialized.largest_acked;
- copy->has_ack_frequency = serialized.has_ack_frequency;
- copy->has_message = serialized.has_message;
- copy->fate = serialized.fate;
- copy->peer_address = serialized.peer_address;
-
- if (copy_buffer) {
- copy->encrypted_buffer = CopyBuffer(serialized);
- copy->release_encrypted_buffer = [](const char* p) { delete[] p; };
- }
- // Copy underlying frames.
- copy->retransmittable_frames =
- CopyQuicFrames(allocator, serialized.retransmittable_frames);
- QUICHE_DCHECK(copy->nonretransmittable_frames.empty());
- for (const auto& frame : serialized.nonretransmittable_frames) {
- if (frame.type == ACK_FRAME) {
- copy->has_ack_frame_copy = true;
- }
- copy->nonretransmittable_frames.push_back(CopyQuicFrame(allocator, frame));
- }
- return copy;
-}
-
-char* CopyBuffer(const SerializedPacket& packet) {
- return CopyBuffer(packet.encrypted_buffer, packet.encrypted_length);
-}
-
-char* CopyBuffer(const char* encrypted_buffer,
- QuicPacketLength encrypted_length) {
- char* dst_buffer = new char[encrypted_length];
- memcpy(dst_buffer, encrypted_buffer, encrypted_length);
- return dst_buffer;
-}
-
-ReceivedPacketInfo::ReceivedPacketInfo(const QuicSocketAddress& self_address,
- const QuicSocketAddress& peer_address,
- const QuicReceivedPacket& packet)
- : self_address(self_address),
- peer_address(peer_address),
- packet(packet),
- form(GOOGLE_QUIC_PACKET),
- long_packet_type(INVALID_PACKET_TYPE),
- version_flag(false),
- use_length_prefix(false),
- version_label(0),
- version(ParsedQuicVersion::Unsupported()),
- destination_connection_id(EmptyQuicConnectionId()),
- source_connection_id(EmptyQuicConnectionId()) {}
-
-ReceivedPacketInfo::~ReceivedPacketInfo() {}
-
-std::string ReceivedPacketInfo::ToString() const {
- std::string output =
- absl::StrCat("{ self_address: ", self_address.ToString(),
- ", peer_address: ", peer_address.ToString(),
- ", packet_length: ", packet.length(),
- ", header_format: ", form, ", version_flag: ", version_flag);
- if (version_flag) {
- absl::StrAppend(&output, ", version: ", ParsedQuicVersionToString(version));
- }
- absl::StrAppend(
- &output,
- ", destination_connection_id: ", destination_connection_id.ToString(),
- ", source_connection_id: ", source_connection_id.ToString(), " }\n");
- return output;
-}
-
-std::ostream& operator<<(std::ostream& os,
- const ReceivedPacketInfo& packet_info) {
- os << packet_info.ToString();
- return os;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_packets.h b/chromium/net/third_party/quiche/src/quic/core/quic_packets.h
deleted file mode 100644
index c79e5a54db7..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_packets.h
+++ /dev/null
@@ -1,463 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_PACKETS_H_
-#define QUICHE_QUIC_CORE_QUIC_PACKETS_H_
-
-#include <cstddef>
-#include <cstdint>
-#include <memory>
-#include <ostream>
-#include <string>
-#include <utility>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/frames/quic_frame.h"
-#include "quic/core/quic_ack_listener_interface.h"
-#include "quic/core/quic_bandwidth.h"
-#include "quic/core/quic_constants.h"
-#include "quic/core/quic_error_codes.h"
-#include "quic/core/quic_time.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_versions.h"
-#include "quic/platform/api/quic_export.h"
-#include "quic/platform/api/quic_socket_address.h"
-
-namespace quic {
-
-class QuicPacket;
-struct QuicPacketHeader;
-
-// Returns the destination connection ID of |header| when |perspective| is
-// server, and the source connection ID when |perspective| is client.
-QUIC_EXPORT_PRIVATE QuicConnectionId
-GetServerConnectionIdAsRecipient(const QuicPacketHeader& header,
- Perspective perspective);
-
-// Returns the destination connection ID of |header| when |perspective| is
-// client, and the source connection ID when |perspective| is server.
-QUIC_EXPORT_PRIVATE QuicConnectionId
-GetClientConnectionIdAsRecipient(const QuicPacketHeader& header,
- Perspective perspective);
-
-// Returns the destination connection ID of |header| when |perspective| is
-// client, and the source connection ID when |perspective| is server.
-QUIC_EXPORT_PRIVATE QuicConnectionId
-GetServerConnectionIdAsSender(const QuicPacketHeader& header,
- Perspective perspective);
-
-// Returns the destination connection ID included of |header| when |perspective|
-// is client, and the source connection ID included when |perspective| is
-// server.
-QUIC_EXPORT_PRIVATE QuicConnectionIdIncluded
-GetServerConnectionIdIncludedAsSender(const QuicPacketHeader& header,
- Perspective perspective);
-
-// Returns the destination connection ID of |header| when |perspective| is
-// server, and the source connection ID when |perspective| is client.
-QUIC_EXPORT_PRIVATE QuicConnectionId
-GetClientConnectionIdAsSender(const QuicPacketHeader& header,
- Perspective perspective);
-
-// Returns the destination connection ID included of |header| when |perspective|
-// is server, and the source connection ID included when |perspective| is
-// client.
-QUIC_EXPORT_PRIVATE QuicConnectionIdIncluded
-GetClientConnectionIdIncludedAsSender(const QuicPacketHeader& header,
- Perspective perspective);
-
-// Number of connection ID bytes that are actually included over the wire.
-QUIC_EXPORT_PRIVATE QuicConnectionIdLength
-GetIncludedConnectionIdLength(QuicConnectionId connection_id,
- QuicConnectionIdIncluded connection_id_included);
-
-// Number of destination connection ID bytes that are actually included over the
-// wire for this particular header.
-QUIC_EXPORT_PRIVATE QuicConnectionIdLength
-GetIncludedDestinationConnectionIdLength(const QuicPacketHeader& header);
-
-// Number of source connection ID bytes that are actually included over the
-// wire for this particular header.
-QUIC_EXPORT_PRIVATE QuicConnectionIdLength
-GetIncludedSourceConnectionIdLength(const QuicPacketHeader& header);
-
-// Size in bytes of the data packet header.
-QUIC_EXPORT_PRIVATE size_t GetPacketHeaderSize(QuicTransportVersion version,
- const QuicPacketHeader& header);
-
-QUIC_EXPORT_PRIVATE size_t
-GetPacketHeaderSize(QuicTransportVersion version,
- QuicConnectionIdLength destination_connection_id_length,
- QuicConnectionIdLength source_connection_id_length,
- bool include_version,
- bool include_diversification_nonce,
- QuicPacketNumberLength packet_number_length,
- QuicVariableLengthIntegerLength retry_token_length_length,
- QuicByteCount retry_token_length,
- QuicVariableLengthIntegerLength length_length);
-
-// Index of the first byte in a QUIC packet of encrypted data.
-QUIC_EXPORT_PRIVATE size_t
-GetStartOfEncryptedData(QuicTransportVersion version,
- const QuicPacketHeader& header);
-
-QUIC_EXPORT_PRIVATE size_t GetStartOfEncryptedData(
- QuicTransportVersion version,
- QuicConnectionIdLength destination_connection_id_length,
- QuicConnectionIdLength source_connection_id_length,
- bool include_version,
- bool include_diversification_nonce,
- QuicPacketNumberLength packet_number_length,
- QuicVariableLengthIntegerLength retry_token_length_length,
- QuicByteCount retry_token_length,
- QuicVariableLengthIntegerLength length_length);
-
-struct QUIC_EXPORT_PRIVATE QuicPacketHeader {
- QuicPacketHeader();
- QuicPacketHeader(const QuicPacketHeader& other);
- ~QuicPacketHeader();
-
- QuicPacketHeader& operator=(const QuicPacketHeader& other);
-
- QUIC_EXPORT_PRIVATE friend std::ostream& operator<<(
- std::ostream& os,
- const QuicPacketHeader& header);
-
- // Universal header. All QuicPacket headers will have a connection_id and
- // public flags.
- QuicConnectionId destination_connection_id;
- QuicConnectionIdIncluded destination_connection_id_included;
- QuicConnectionId source_connection_id;
- QuicConnectionIdIncluded source_connection_id_included;
- // This is only used for Google QUIC.
- bool reset_flag;
- // For Google QUIC, version flag in packets from the server means version
- // negotiation packet. For IETF QUIC, version flag means long header.
- bool version_flag;
- // Indicates whether |possible_stateless_reset_token| contains a valid value
- // parsed from the packet buffer. IETF QUIC only, always false for GQUIC.
- bool has_possible_stateless_reset_token;
- QuicPacketNumberLength packet_number_length;
- uint8_t type_byte;
- ParsedQuicVersion version;
- // nonce contains an optional, 32-byte nonce value. If not included in the
- // packet, |nonce| will be empty.
- DiversificationNonce* nonce;
- QuicPacketNumber packet_number;
- // Format of this header.
- PacketHeaderFormat form;
- // Short packet type is reflected in packet_number_length.
- QuicLongHeaderType long_packet_type;
- // Only valid if |has_possible_stateless_reset_token| is true.
- // Stores last 16 bytes of a this packet, used to check whether this packet is
- // a stateless reset packet on decryption failure.
- StatelessResetToken possible_stateless_reset_token;
- // Length of the retry token length variable length integer field,
- // carried only by v99 IETF Initial packets.
- QuicVariableLengthIntegerLength retry_token_length_length;
- // Retry token, carried only by v99 IETF Initial packets.
- absl::string_view retry_token;
- // Length of the length variable length integer field,
- // carried only by v99 IETF Initial, 0-RTT and Handshake packets.
- QuicVariableLengthIntegerLength length_length;
- // Length of the packet number and payload, carried only by v99 IETF Initial,
- // 0-RTT and Handshake packets. Also includes the length of the
- // diversification nonce in server to client 0-RTT packets.
- QuicByteCount remaining_packet_length;
-};
-
-struct QUIC_EXPORT_PRIVATE QuicPublicResetPacket {
- QuicPublicResetPacket();
- explicit QuicPublicResetPacket(QuicConnectionId connection_id);
-
- QuicConnectionId connection_id;
- QuicPublicResetNonceProof nonce_proof;
- QuicSocketAddress client_address;
- // An arbitrary string to identify an endpoint. Used by clients to
- // differentiate traffic from Google servers vs Non-google servers.
- // Will not be used if empty().
- std::string endpoint_id;
-};
-
-struct QUIC_EXPORT_PRIVATE QuicVersionNegotiationPacket {
- QuicVersionNegotiationPacket();
- explicit QuicVersionNegotiationPacket(QuicConnectionId connection_id);
- QuicVersionNegotiationPacket(const QuicVersionNegotiationPacket& other);
- ~QuicVersionNegotiationPacket();
-
- QuicConnectionId connection_id;
- ParsedQuicVersionVector versions;
-};
-
-struct QUIC_EXPORT_PRIVATE QuicIetfStatelessResetPacket {
- QuicIetfStatelessResetPacket();
- QuicIetfStatelessResetPacket(const QuicPacketHeader& header,
- StatelessResetToken token);
- QuicIetfStatelessResetPacket(const QuicIetfStatelessResetPacket& other);
- ~QuicIetfStatelessResetPacket();
-
- QuicPacketHeader header;
- StatelessResetToken stateless_reset_token;
-};
-
-class QUIC_EXPORT_PRIVATE QuicData {
- public:
- // Creates a QuicData from a buffer and length. Does not own the buffer.
- QuicData(const char* buffer, size_t length);
- // Creates a QuicData from a buffer and length,
- // optionally taking ownership of the buffer.
- QuicData(const char* buffer, size_t length, bool owns_buffer);
- // Creates a QuicData from a absl::string_view. Does not own the
- // buffer.
- QuicData(absl::string_view data);
- QuicData(const QuicData&) = delete;
- QuicData& operator=(const QuicData&) = delete;
- virtual ~QuicData();
-
- absl::string_view AsStringPiece() const {
- return absl::string_view(data(), length());
- }
-
- const char* data() const { return buffer_; }
- size_t length() const { return length_; }
-
- private:
- const char* buffer_;
- size_t length_;
- bool owns_buffer_;
-};
-
-class QUIC_EXPORT_PRIVATE QuicPacket : public QuicData {
- public:
- QuicPacket(char* buffer,
- size_t length,
- bool owns_buffer,
- QuicConnectionIdLength destination_connection_id_length,
- QuicConnectionIdLength source_connection_id_length,
- bool includes_version,
- bool includes_diversification_nonce,
- QuicPacketNumberLength packet_number_length,
- QuicVariableLengthIntegerLength retry_token_length_length,
- QuicByteCount retry_token_length,
- QuicVariableLengthIntegerLength length_length);
- QuicPacket(QuicTransportVersion version,
- char* buffer,
- size_t length,
- bool owns_buffer,
- const QuicPacketHeader& header);
- QuicPacket(const QuicPacket&) = delete;
- QuicPacket& operator=(const QuicPacket&) = delete;
-
- absl::string_view AssociatedData(QuicTransportVersion version) const;
- absl::string_view Plaintext(QuicTransportVersion version) const;
-
- char* mutable_data() { return buffer_; }
-
- private:
- char* buffer_;
- const QuicConnectionIdLength destination_connection_id_length_;
- const QuicConnectionIdLength source_connection_id_length_;
- const bool includes_version_;
- const bool includes_diversification_nonce_;
- const QuicPacketNumberLength packet_number_length_;
- const QuicVariableLengthIntegerLength retry_token_length_length_;
- const QuicByteCount retry_token_length_;
- const QuicVariableLengthIntegerLength length_length_;
-};
-
-class QUIC_EXPORT_PRIVATE QuicEncryptedPacket : public QuicData {
- public:
- // Creates a QuicEncryptedPacket from a buffer and length.
- // Does not own the buffer.
- QuicEncryptedPacket(const char* buffer, size_t length);
- // Creates a QuicEncryptedPacket from a buffer and length,
- // optionally taking ownership of the buffer.
- QuicEncryptedPacket(const char* buffer, size_t length, bool owns_buffer);
- // Creates a QuicEncryptedPacket from a absl::string_view.
- // Does not own the buffer.
- QuicEncryptedPacket(absl::string_view data);
-
- QuicEncryptedPacket(const QuicEncryptedPacket&) = delete;
- QuicEncryptedPacket& operator=(const QuicEncryptedPacket&) = delete;
-
- // Clones the packet into a new packet which owns the buffer.
- std::unique_ptr<QuicEncryptedPacket> Clone() const;
-
- // By default, gtest prints the raw bytes of an object. The bool data
- // member (in the base class QuicData) causes this object to have padding
- // bytes, which causes the default gtest object printer to read
- // uninitialize memory. So we need to teach gtest how to print this object.
- QUIC_EXPORT_PRIVATE friend std::ostream& operator<<(
- std::ostream& os,
- const QuicEncryptedPacket& s);
-};
-
-// A received encrypted QUIC packet, with a recorded time of receipt.
-class QUIC_EXPORT_PRIVATE QuicReceivedPacket : public QuicEncryptedPacket {
- public:
- QuicReceivedPacket(const char* buffer, size_t length, QuicTime receipt_time);
- QuicReceivedPacket(const char* buffer,
- size_t length,
- QuicTime receipt_time,
- bool owns_buffer);
- QuicReceivedPacket(const char* buffer,
- size_t length,
- QuicTime receipt_time,
- bool owns_buffer,
- int ttl,
- bool ttl_valid);
- QuicReceivedPacket(const char* buffer,
- size_t length,
- QuicTime receipt_time,
- bool owns_buffer,
- int ttl,
- bool ttl_valid,
- char* packet_headers,
- size_t headers_length,
- bool owns_header_buffer);
- ~QuicReceivedPacket();
- QuicReceivedPacket(const QuicReceivedPacket&) = delete;
- QuicReceivedPacket& operator=(const QuicReceivedPacket&) = delete;
-
- // Clones the packet into a new packet which owns the buffer.
- std::unique_ptr<QuicReceivedPacket> Clone() const;
-
- // Returns the time at which the packet was received.
- QuicTime receipt_time() const { return receipt_time_; }
-
- // This is the TTL of the packet, assuming ttl_vaild_ is true.
- int ttl() const { return ttl_; }
-
- // Start of packet headers.
- char* packet_headers() const { return packet_headers_; }
-
- // Length of packet headers.
- int headers_length() const { return headers_length_; }
-
- // By default, gtest prints the raw bytes of an object. The bool data
- // member (in the base class QuicData) causes this object to have padding
- // bytes, which causes the default gtest object printer to read
- // uninitialize memory. So we need to teach gtest how to print this object.
- QUIC_EXPORT_PRIVATE friend std::ostream& operator<<(
- std::ostream& os,
- const QuicReceivedPacket& s);
-
- private:
- const QuicTime receipt_time_;
- int ttl_;
- // Points to the start of packet headers.
- char* packet_headers_;
- // Length of packet headers.
- int headers_length_;
- // Whether owns the buffer for packet headers.
- bool owns_header_buffer_;
-};
-
-// SerializedPacket contains information of a serialized(encrypted) packet.
-//
-// WARNING:
-//
-// If you add a member field to this class, please make sure it is properly
-// copied in |CopySerializedPacket|.
-//
-struct QUIC_EXPORT_PRIVATE SerializedPacket {
- SerializedPacket(QuicPacketNumber packet_number,
- QuicPacketNumberLength packet_number_length,
- const char* encrypted_buffer,
- QuicPacketLength encrypted_length,
- bool has_ack,
- bool has_stop_waiting);
-
- // Copy constructor & assignment are deleted. Use |CopySerializedPacket| to
- // make a copy.
- SerializedPacket(const SerializedPacket& other) = delete;
- SerializedPacket& operator=(const SerializedPacket& other) = delete;
- SerializedPacket(SerializedPacket&& other);
- ~SerializedPacket();
-
- // TODO(wub): replace |encrypted_buffer|+|release_encrypted_buffer| by a
- // QuicOwnedPacketBuffer.
- // Not owned if |release_encrypted_buffer| is nullptr. Otherwise it is
- // released by |release_encrypted_buffer| on destruction.
- const char* encrypted_buffer;
- QuicPacketLength encrypted_length;
- std::function<void(const char*)> release_encrypted_buffer;
-
- QuicFrames retransmittable_frames;
- QuicFrames nonretransmittable_frames;
- IsHandshake has_crypto_handshake;
- QuicPacketNumber packet_number;
- QuicPacketNumberLength packet_number_length;
- EncryptionLevel encryption_level;
- // TODO(fayang): Remove has_ack and has_stop_waiting.
- bool has_ack;
- bool has_stop_waiting;
- TransmissionType transmission_type;
- // The largest acked of the AckFrame in this packet if has_ack is true,
- // 0 otherwise.
- QuicPacketNumber largest_acked;
- // Indicates whether this packet has a copy of ack frame in
- // nonretransmittable_frames.
- bool has_ack_frame_copy;
- bool has_ack_frequency;
- bool has_message;
- SerializedPacketFate fate;
- QuicSocketAddress peer_address;
-};
-
-// Make a copy of |serialized| (including the underlying frames). |copy_buffer|
-// indicates whether the encrypted buffer should be copied.
-QUIC_EXPORT_PRIVATE SerializedPacket* CopySerializedPacket(
- const SerializedPacket& serialized,
- QuicBufferAllocator* allocator,
- bool copy_buffer);
-
-// Allocates a new char[] of size |packet.encrypted_length| and copies in
-// |packet.encrypted_buffer|.
-QUIC_EXPORT_PRIVATE char* CopyBuffer(const SerializedPacket& packet);
-// Allocates a new char[] of size |encrypted_length| and copies in
-// |encrypted_buffer|.
-QUIC_EXPORT_PRIVATE char* CopyBuffer(const char* encrypted_buffer,
- QuicPacketLength encrypted_length);
-
-// Context for an incoming packet.
-struct QUIC_EXPORT_PRIVATE QuicPerPacketContext {
- virtual ~QuicPerPacketContext() {}
-};
-
-// ReceivedPacketInfo comprises information obtained by parsing the unencrypted
-// bytes of a received packet.
-struct QUIC_EXPORT_PRIVATE ReceivedPacketInfo {
- ReceivedPacketInfo(const QuicSocketAddress& self_address,
- const QuicSocketAddress& peer_address,
- const QuicReceivedPacket& packet);
- ReceivedPacketInfo(const ReceivedPacketInfo& other) = default;
-
- ~ReceivedPacketInfo();
-
- std::string ToString() const;
-
- QUIC_EXPORT_PRIVATE friend std::ostream& operator<<(
- std::ostream& os,
- const ReceivedPacketInfo& packet_info);
-
- const QuicSocketAddress& self_address;
- const QuicSocketAddress& peer_address;
- const QuicReceivedPacket& packet;
-
- PacketHeaderFormat form;
- // This is only used if the form is IETF_QUIC_LONG_HEADER_PACKET.
- QuicLongHeaderType long_packet_type;
- bool version_flag;
- bool use_length_prefix;
- QuicVersionLabel version_label;
- ParsedQuicVersion version;
- QuicConnectionId destination_connection_id;
- QuicConnectionId source_connection_id;
- absl::optional<absl::string_view> retry_token;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_QUIC_PACKETS_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_packets_test.cc b/chromium/net/third_party/quiche/src/quic/core/quic_packets_test.cc
deleted file mode 100644
index a07e289cb71..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_packets_test.cc
+++ /dev/null
@@ -1,113 +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 "quic/core/quic_packets.h"
-
-#include "absl/memory/memory.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/quic_test_utils.h"
-#include "common/test_tools/quiche_test_utils.h"
-
-namespace quic {
-namespace test {
-namespace {
-
-QuicPacketHeader CreateFakePacketHeader() {
- QuicPacketHeader header;
- header.destination_connection_id = TestConnectionId(1);
- header.destination_connection_id_included = CONNECTION_ID_PRESENT;
- header.source_connection_id = TestConnectionId(2);
- header.source_connection_id_included = CONNECTION_ID_ABSENT;
- return header;
-}
-
-class QuicPacketsTest : public QuicTest {};
-
-TEST_F(QuicPacketsTest, GetServerConnectionIdAsRecipient) {
- QuicPacketHeader header = CreateFakePacketHeader();
- EXPECT_EQ(TestConnectionId(1),
- GetServerConnectionIdAsRecipient(header, Perspective::IS_SERVER));
- EXPECT_EQ(TestConnectionId(2),
- GetServerConnectionIdAsRecipient(header, Perspective::IS_CLIENT));
-}
-
-TEST_F(QuicPacketsTest, GetServerConnectionIdAsSender) {
- QuicPacketHeader header = CreateFakePacketHeader();
- EXPECT_EQ(TestConnectionId(2),
- GetServerConnectionIdAsSender(header, Perspective::IS_SERVER));
- EXPECT_EQ(TestConnectionId(1),
- GetServerConnectionIdAsSender(header, Perspective::IS_CLIENT));
-}
-
-TEST_F(QuicPacketsTest, GetServerConnectionIdIncludedAsSender) {
- QuicPacketHeader header = CreateFakePacketHeader();
- EXPECT_EQ(CONNECTION_ID_ABSENT, GetServerConnectionIdIncludedAsSender(
- header, Perspective::IS_SERVER));
- EXPECT_EQ(CONNECTION_ID_PRESENT, GetServerConnectionIdIncludedAsSender(
- header, Perspective::IS_CLIENT));
-}
-
-TEST_F(QuicPacketsTest, GetClientConnectionIdIncludedAsSender) {
- QuicPacketHeader header = CreateFakePacketHeader();
- EXPECT_EQ(CONNECTION_ID_PRESENT, GetClientConnectionIdIncludedAsSender(
- header, Perspective::IS_SERVER));
- EXPECT_EQ(CONNECTION_ID_ABSENT, GetClientConnectionIdIncludedAsSender(
- header, Perspective::IS_CLIENT));
-}
-
-TEST_F(QuicPacketsTest, GetClientConnectionIdAsRecipient) {
- QuicPacketHeader header = CreateFakePacketHeader();
- EXPECT_EQ(TestConnectionId(2),
- GetClientConnectionIdAsRecipient(header, Perspective::IS_SERVER));
- EXPECT_EQ(TestConnectionId(1),
- GetClientConnectionIdAsRecipient(header, Perspective::IS_CLIENT));
-}
-
-TEST_F(QuicPacketsTest, GetClientConnectionIdAsSender) {
- QuicPacketHeader header = CreateFakePacketHeader();
- EXPECT_EQ(TestConnectionId(1),
- GetClientConnectionIdAsSender(header, Perspective::IS_SERVER));
- EXPECT_EQ(TestConnectionId(2),
- GetClientConnectionIdAsSender(header, Perspective::IS_CLIENT));
-}
-
-TEST_F(QuicPacketsTest, CopySerializedPacket) {
- std::string buffer(1000, 'a');
- SimpleBufferAllocator allocator;
- SerializedPacket packet(QuicPacketNumber(1), PACKET_1BYTE_PACKET_NUMBER,
- buffer.data(), buffer.length(), /*has_ack=*/false,
- /*has_stop_waiting=*/false);
- packet.retransmittable_frames.push_back(
- QuicFrame(new QuicWindowUpdateFrame()));
- packet.retransmittable_frames.push_back(QuicFrame(QuicStreamFrame()));
-
- QuicAckFrame ack_frame(InitAckFrame(1));
- packet.nonretransmittable_frames.push_back(QuicFrame(&ack_frame));
- packet.nonretransmittable_frames.push_back(QuicFrame(QuicPaddingFrame(-1)));
-
- std::unique_ptr<SerializedPacket> copy = absl::WrapUnique<SerializedPacket>(
- CopySerializedPacket(packet, &allocator, /*copy_buffer=*/true));
- EXPECT_EQ(quic::QuicPacketNumber(1), copy->packet_number);
- EXPECT_EQ(PACKET_1BYTE_PACKET_NUMBER, copy->packet_number_length);
- ASSERT_EQ(2u, copy->retransmittable_frames.size());
- EXPECT_EQ(WINDOW_UPDATE_FRAME, copy->retransmittable_frames[0].type);
- EXPECT_EQ(STREAM_FRAME, copy->retransmittable_frames[1].type);
-
- ASSERT_EQ(2u, copy->nonretransmittable_frames.size());
- EXPECT_EQ(ACK_FRAME, copy->nonretransmittable_frames[0].type);
- EXPECT_EQ(PADDING_FRAME, copy->nonretransmittable_frames[1].type);
- EXPECT_EQ(1000u, copy->encrypted_length);
- quiche::test::CompareCharArraysWithHexError(
- "encrypted_buffer", copy->encrypted_buffer, copy->encrypted_length,
- packet.encrypted_buffer, packet.encrypted_length);
-
- std::unique_ptr<SerializedPacket> copy2 = absl::WrapUnique<SerializedPacket>(
- CopySerializedPacket(packet, &allocator, /*copy_buffer=*/false));
- EXPECT_EQ(packet.encrypted_buffer, copy2->encrypted_buffer);
- EXPECT_EQ(1000u, copy2->encrypted_length);
-}
-
-} // namespace
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_path_validator.cc b/chromium/net/third_party/quiche/src/quic/core/quic_path_validator.cc
deleted file mode 100644
index 658dfefdce9..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_path_validator.cc
+++ /dev/null
@@ -1,148 +0,0 @@
-// Copyright (c) 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_path_validator.h"
-
-#include "quic/core/quic_constants.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_socket_address.h"
-
-namespace quic {
-
-class RetryAlarmDelegate : public QuicAlarm::DelegateWithContext {
- public:
- explicit RetryAlarmDelegate(QuicPathValidator* path_validator,
- QuicConnectionContext* context)
- : QuicAlarm::DelegateWithContext(context),
- path_validator_(path_validator) {}
- RetryAlarmDelegate(const RetryAlarmDelegate&) = delete;
- RetryAlarmDelegate& operator=(const RetryAlarmDelegate&) = delete;
-
- void OnAlarm() override { path_validator_->OnRetryTimeout(); }
-
- private:
- QuicPathValidator* path_validator_;
-};
-
-std::ostream& operator<<(std::ostream& os,
- const QuicPathValidationContext& context) {
- return os << " from " << context.self_address_ << " to "
- << context.peer_address_;
-}
-
-QuicPathValidator::QuicPathValidator(QuicAlarmFactory* alarm_factory,
- QuicConnectionArena* arena,
- SendDelegate* send_delegate,
- QuicRandom* random,
- QuicConnectionContext* context)
- : send_delegate_(send_delegate),
- random_(random),
- retry_timer_(alarm_factory->CreateAlarm(
- arena->New<RetryAlarmDelegate>(this, context), arena)),
- retry_count_(0u) {}
-
-void QuicPathValidator::OnPathResponse(const QuicPathFrameBuffer& probing_data,
- QuicSocketAddress self_address) {
- if (!HasPendingPathValidation()) {
- return;
- }
-
- QUIC_DVLOG(1) << "Match PATH_RESPONSE received on " << self_address;
- QUIC_BUG_IF(quic_bug_12402_1, !path_context_->self_address().IsInitialized())
- << "Self address should have been known by now";
- if (self_address != path_context_->self_address()) {
- QUIC_DVLOG(1) << "Expect the response to be received on "
- << path_context_->self_address();
- return;
- }
- // This iterates at most 3 times.
- if (std::find(probing_data_.begin(), probing_data_.end(), probing_data) !=
- probing_data_.end()) {
- result_delegate_->OnPathValidationSuccess(std::move(path_context_));
- ResetPathValidation();
- } else {
- QUIC_DVLOG(1) << "PATH_RESPONSE with payload " << probing_data.data()
- << " doesn't match the probing data.";
- }
-}
-
-void QuicPathValidator::StartPathValidation(
- std::unique_ptr<QuicPathValidationContext> context,
- std::unique_ptr<ResultDelegate> result_delegate) {
- QUICHE_DCHECK(context);
- QUIC_DLOG(INFO) << "Start validating path " << *context
- << " via writer: " << context->WriterToUse();
- if (path_context_ != nullptr) {
- QUIC_BUG(quic_bug_10876_1)
- << "There is an on-going validation on path " << *path_context_;
- ResetPathValidation();
- }
-
- path_context_ = std::move(context);
- result_delegate_ = std::move(result_delegate);
- SendPathChallengeAndSetAlarm();
-}
-
-void QuicPathValidator::ResetPathValidation() {
- path_context_ = nullptr;
- result_delegate_ = nullptr;
- retry_timer_->Cancel();
- retry_count_ = 0;
-}
-
-void QuicPathValidator::CancelPathValidation() {
- if (path_context_ == nullptr) {
- return;
- }
- QUIC_DVLOG(1) << "Cancel validation on path" << *path_context_;
- result_delegate_->OnPathValidationFailure(std::move(path_context_));
- ResetPathValidation();
-}
-
-bool QuicPathValidator::HasPendingPathValidation() const {
- return path_context_ != nullptr;
-}
-
-QuicPathValidationContext* QuicPathValidator::GetContext() const {
- return path_context_.get();
-}
-
-const QuicPathFrameBuffer& QuicPathValidator::GeneratePathChallengePayload() {
- probing_data_.push_back(QuicPathFrameBuffer());
- random_->RandBytes(probing_data_.back().data(), sizeof(QuicPathFrameBuffer));
- return probing_data_.back();
-}
-
-void QuicPathValidator::OnRetryTimeout() {
- ++retry_count_;
- if (retry_count_ > kMaxRetryTimes) {
- CancelPathValidation();
- return;
- }
- QUIC_DVLOG(1) << "Send another PATH_CHALLENGE on path " << *path_context_;
- SendPathChallengeAndSetAlarm();
-}
-
-void QuicPathValidator::SendPathChallengeAndSetAlarm() {
- bool should_continue = send_delegate_->SendPathChallenge(
- GeneratePathChallengePayload(), path_context_->self_address(),
- path_context_->peer_address(), path_context_->effective_peer_address(),
- path_context_->WriterToUse());
-
- if (!should_continue) {
- // The delegate doesn't want to continue the path validation.
- CancelPathValidation();
- return;
- }
- retry_timer_->Set(send_delegate_->GetRetryTimeout(
- path_context_->peer_address(), path_context_->WriterToUse()));
-}
-
-bool QuicPathValidator::IsValidatingPeerAddress(
- const QuicSocketAddress& effective_peer_address) {
- return path_context_ != nullptr &&
- path_context_->effective_peer_address() == effective_peer_address;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_path_validator.h b/chromium/net/third_party/quiche/src/quic/core/quic_path_validator.h
deleted file mode 100644
index 9fe2cef9884..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_path_validator.h
+++ /dev/null
@@ -1,160 +0,0 @@
-// Copyright (c) 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_PATH_VALIDATOR_H_
-#define QUICHE_QUIC_CORE_QUIC_PATH_VALIDATOR_H_
-
-#include <ostream>
-
-#include "absl/container/inlined_vector.h"
-#include "quic/core/crypto/quic_random.h"
-#include "quic/core/quic_alarm.h"
-#include "quic/core/quic_alarm_factory.h"
-#include "quic/core/quic_arena_scoped_ptr.h"
-#include "quic/core/quic_clock.h"
-#include "quic/core/quic_connection_context.h"
-#include "quic/core/quic_one_block_arena.h"
-#include "quic/core/quic_packet_writer.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_export.h"
-#include "quic/platform/api/quic_socket_address.h"
-
-namespace quic {
-
-namespace test {
-class QuicPathValidatorPeer;
-}
-
-class QuicConnection;
-
-// Interface to provide the information of the path to be validated.
-class QUIC_EXPORT_PRIVATE QuicPathValidationContext {
- public:
- QuicPathValidationContext(const QuicSocketAddress& self_address,
- const QuicSocketAddress& peer_address)
- : self_address_(self_address),
- peer_address_(peer_address),
- effective_peer_address_(peer_address) {}
-
- QuicPathValidationContext(const QuicSocketAddress& self_address,
- const QuicSocketAddress& peer_address,
- const QuicSocketAddress& effective_peer_address)
- : self_address_(self_address),
- peer_address_(peer_address),
- effective_peer_address_(effective_peer_address) {}
-
- virtual ~QuicPathValidationContext() = default;
-
- virtual QuicPacketWriter* WriterToUse() = 0;
-
- const QuicSocketAddress& self_address() const { return self_address_; }
- const QuicSocketAddress& peer_address() const { return peer_address_; }
- const QuicSocketAddress& effective_peer_address() const {
- return effective_peer_address_;
- }
-
- private:
- QUIC_EXPORT_PRIVATE friend std::ostream& operator<<(
- std::ostream& os,
- const QuicPathValidationContext& context);
-
- QuicSocketAddress self_address_;
- // The address to send PATH_CHALLENGE.
- QuicSocketAddress peer_address_;
- // The actual peer address which is different from |peer_address_| if the peer
- // is behind a proxy.
- QuicSocketAddress effective_peer_address_;
-};
-
-// Used to validate a path by sending up to 3 PATH_CHALLENGE frames before
-// declaring a path validation failure.
-class QUIC_EXPORT_PRIVATE QuicPathValidator {
- public:
- static const uint16_t kMaxRetryTimes = 2;
-
- // Used to write PATH_CHALLENGE on the path to be validated and to get retry
- // timeout.
- class QUIC_EXPORT_PRIVATE SendDelegate {
- public:
- virtual ~SendDelegate() = default;
-
- // Send a PATH_CHALLENGE with |data_buffer| as the frame payload using given
- // path information. Return false if the delegate doesn't want to continue
- // the validation.
- virtual bool SendPathChallenge(
- const QuicPathFrameBuffer& data_buffer,
- const QuicSocketAddress& self_address,
- const QuicSocketAddress& peer_address,
- const QuicSocketAddress& effective_peer_address,
- QuicPacketWriter* writer) = 0;
- // Return the time to retry sending PATH_CHALLENGE again based on given peer
- // address and writer.
- virtual QuicTime GetRetryTimeout(const QuicSocketAddress& peer_address,
- QuicPacketWriter* writer) const = 0;
- };
-
- // Handles the validation result.
- // TODO(danzh) consider to simplify this interface and its life time to
- // outlive a validation.
- class QUIC_EXPORT_PRIVATE ResultDelegate {
- public:
- virtual ~ResultDelegate() = default;
-
- virtual void OnPathValidationSuccess(
- std::unique_ptr<QuicPathValidationContext> context) = 0;
-
- virtual void OnPathValidationFailure(
- std::unique_ptr<QuicPathValidationContext> context) = 0;
- };
-
- QuicPathValidator(QuicAlarmFactory* alarm_factory, QuicConnectionArena* arena,
- SendDelegate* delegate, QuicRandom* random,
- QuicConnectionContext* context);
-
- // Send PATH_CHALLENGE and start the retry timer.
- void StartPathValidation(std::unique_ptr<QuicPathValidationContext> context,
- std::unique_ptr<ResultDelegate> result_delegate);
-
- // Called when a PATH_RESPONSE frame has been received. Matches the received
- // PATH_RESPONSE payload with the payloads previously sent in PATH_CHALLANGE
- // frames and the self address on which it was sent.
- void OnPathResponse(const QuicPathFrameBuffer& probing_data,
- QuicSocketAddress self_address);
-
- // Cancel the retry timer and reset the path and result delegate.
- void CancelPathValidation();
-
- bool HasPendingPathValidation() const;
-
- QuicPathValidationContext* GetContext() const;
-
- // Send another PATH_CHALLENGE on the same path. After retrying
- // |kMaxRetryTimes| times, fail the current path validation.
- void OnRetryTimeout();
-
- bool IsValidatingPeerAddress(const QuicSocketAddress& effective_peer_address);
-
- private:
- friend class test::QuicPathValidatorPeer;
-
- // Return the payload to be used in the next PATH_CHALLENGE frame.
- const QuicPathFrameBuffer& GeneratePathChallengePayload();
-
- void SendPathChallengeAndSetAlarm();
-
- void ResetPathValidation();
-
- // Has at most 3 entries due to validation timeout.
- absl::InlinedVector<QuicPathFrameBuffer, 3> probing_data_;
- SendDelegate* send_delegate_;
- QuicRandom* random_;
- std::unique_ptr<QuicPathValidationContext> path_context_;
- std::unique_ptr<ResultDelegate> result_delegate_;
- QuicArenaScopedPtr<QuicAlarm> retry_timer_;
- size_t retry_count_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_QUIC_PATH_VALIDATOR_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_path_validator_test.cc b/chromium/net/third_party/quiche/src/quic/core/quic_path_validator_test.cc
deleted file mode 100644
index 28e12593e94..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_path_validator_test.cc
+++ /dev/null
@@ -1,254 +0,0 @@
-// Copyright (c) 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_path_validator.h"
-
-#include <memory>
-
-#include "quic/core/frames/quic_path_challenge_frame.h"
-#include "quic/core/quic_constants.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_ip_address.h"
-#include "quic/platform/api/quic_socket_address.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/mock_clock.h"
-#include "quic/test_tools/mock_random.h"
-#include "quic/test_tools/quic_path_validator_peer.h"
-#include "quic/test_tools/quic_test_utils.h"
-#include "quic/test_tools/quic_transport_test_tools.h"
-
-using testing::_;
-using testing::Invoke;
-using testing::Return;
-
-namespace quic {
-namespace test {
-
-class MockSendDelegate : public QuicPathValidator::SendDelegate {
- public:
- // Send a PATH_CHALLENGE frame using given path information and populate
- // |data_buffer| with the frame payload. Return true if the validator should
- // move forward in validation, i.e. arm the retry timer.
- MOCK_METHOD(bool,
- SendPathChallenge,
- (const QuicPathFrameBuffer&,
- const QuicSocketAddress&,
- const QuicSocketAddress&,
- const QuicSocketAddress&,
- QuicPacketWriter*),
- (override));
-
- MOCK_METHOD(QuicTime,
- GetRetryTimeout,
- (const QuicSocketAddress&, QuicPacketWriter*),
- (const, override));
-};
-
-class QuicPathValidatorTest : public QuicTest {
- public:
- QuicPathValidatorTest()
- : path_validator_(&alarm_factory_, &arena_, &send_delegate_, &random_,
- /*context=*/nullptr),
- context_(new MockQuicPathValidationContext(
- self_address_, peer_address_, effective_peer_address_, &writer_)),
- result_delegate_(
- new testing::StrictMock<MockQuicPathValidationResultDelegate>()) {
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(1));
- ON_CALL(send_delegate_, GetRetryTimeout(_, _))
- .WillByDefault(
- Return(clock_.ApproximateNow() +
- 3 * QuicTime::Delta::FromMilliseconds(kInitialRttMs)));
- }
-
- protected:
- quic::test::MockAlarmFactory alarm_factory_;
- MockSendDelegate send_delegate_;
- MockRandom random_;
- MockClock clock_;
- QuicConnectionArena arena_;
- QuicPathValidator path_validator_;
- QuicSocketAddress self_address_{QuicIpAddress::Any4(), 443};
- QuicSocketAddress peer_address_{QuicIpAddress::Loopback4(), 443};
- QuicSocketAddress effective_peer_address_{QuicIpAddress::Loopback4(), 12345};
- MockPacketWriter writer_;
- MockQuicPathValidationContext* context_;
- MockQuicPathValidationResultDelegate* result_delegate_;
-};
-
-TEST_F(QuicPathValidatorTest, PathValidationSuccessOnFirstRound) {
- QuicPathFrameBuffer challenge_data;
- EXPECT_CALL(send_delegate_,
- SendPathChallenge(_, self_address_, peer_address_,
- effective_peer_address_, &writer_))
- .WillOnce(Invoke([&](const QuicPathFrameBuffer& payload,
- const QuicSocketAddress&, const QuicSocketAddress&,
- const QuicSocketAddress&, QuicPacketWriter*) {
- memcpy(challenge_data.data(), payload.data(), payload.size());
- return true;
- }));
- EXPECT_CALL(send_delegate_, GetRetryTimeout(peer_address_, &writer_));
- path_validator_.StartPathValidation(
- std::unique_ptr<QuicPathValidationContext>(context_),
- std::unique_ptr<MockQuicPathValidationResultDelegate>(result_delegate_));
- EXPECT_TRUE(path_validator_.HasPendingPathValidation());
- EXPECT_TRUE(path_validator_.IsValidatingPeerAddress(effective_peer_address_));
- EXPECT_CALL(*result_delegate_, OnPathValidationSuccess(_))
- .WillOnce(Invoke([=](std::unique_ptr<QuicPathValidationContext> context) {
- EXPECT_EQ(context.get(), context_);
- }));
- path_validator_.OnPathResponse(challenge_data, self_address_);
- EXPECT_FALSE(path_validator_.HasPendingPathValidation());
-}
-
-TEST_F(QuicPathValidatorTest, RespondWithDifferentSelfAddress) {
- QuicPathFrameBuffer challenge_data;
- EXPECT_CALL(send_delegate_,
- SendPathChallenge(_, self_address_, peer_address_,
- effective_peer_address_, &writer_))
- .WillOnce(Invoke([&](const QuicPathFrameBuffer payload,
- const QuicSocketAddress&, const QuicSocketAddress&,
- const QuicSocketAddress&, QuicPacketWriter*) {
- memcpy(challenge_data.data(), payload.data(), payload.size());
- return true;
- }));
- EXPECT_CALL(send_delegate_, GetRetryTimeout(peer_address_, &writer_));
- path_validator_.StartPathValidation(
- std::unique_ptr<QuicPathValidationContext>(context_),
- std::unique_ptr<MockQuicPathValidationResultDelegate>(result_delegate_));
-
- // Reception of a PATH_RESPONSE on a different self address should be ignored.
- const QuicSocketAddress kAlternativeSelfAddress(QuicIpAddress::Any6(), 54321);
- EXPECT_NE(kAlternativeSelfAddress, self_address_);
- path_validator_.OnPathResponse(challenge_data, kAlternativeSelfAddress);
-
- EXPECT_CALL(*result_delegate_, OnPathValidationSuccess(_))
- .WillOnce(Invoke([=](std::unique_ptr<QuicPathValidationContext> context) {
- EXPECT_EQ(context->self_address(), self_address_);
- }));
- path_validator_.OnPathResponse(challenge_data, self_address_);
-}
-
-TEST_F(QuicPathValidatorTest, RespondAfter1stRetry) {
- QuicPathFrameBuffer challenge_data;
- EXPECT_CALL(send_delegate_,
- SendPathChallenge(_, self_address_, peer_address_,
- effective_peer_address_, &writer_))
- .WillOnce(Invoke([&](const QuicPathFrameBuffer& payload,
- const QuicSocketAddress&, const QuicSocketAddress&,
- const QuicSocketAddress&, QuicPacketWriter*) {
- // Store up the 1st PATH_CHALLANGE payload.
- memcpy(challenge_data.data(), payload.data(), payload.size());
- return true;
- }))
- .WillOnce(Invoke([&](const QuicPathFrameBuffer& payload,
- const QuicSocketAddress&, const QuicSocketAddress&,
- const QuicSocketAddress&, QuicPacketWriter*) {
- EXPECT_NE(payload, challenge_data);
- return true;
- }));
- EXPECT_CALL(send_delegate_, GetRetryTimeout(peer_address_, &writer_))
- .Times(2u);
- path_validator_.StartPathValidation(
- std::unique_ptr<QuicPathValidationContext>(context_),
- std::unique_ptr<MockQuicPathValidationResultDelegate>(result_delegate_));
-
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(3 * kInitialRttMs));
- random_.ChangeValue();
- alarm_factory_.FireAlarm(
- QuicPathValidatorPeer::retry_timer(&path_validator_));
-
- EXPECT_CALL(*result_delegate_, OnPathValidationSuccess(_));
- // Respond to the 1st PATH_CHALLENGE should complete the validation.
- path_validator_.OnPathResponse(challenge_data, self_address_);
- EXPECT_FALSE(path_validator_.HasPendingPathValidation());
-}
-
-TEST_F(QuicPathValidatorTest, RespondToRetryChallenge) {
- QuicPathFrameBuffer challenge_data;
- EXPECT_CALL(send_delegate_,
- SendPathChallenge(_, self_address_, peer_address_,
- effective_peer_address_, &writer_))
- .WillOnce(Invoke([&](const QuicPathFrameBuffer& payload,
- const QuicSocketAddress&, const QuicSocketAddress&,
- const QuicSocketAddress&, QuicPacketWriter*) {
- memcpy(challenge_data.data(), payload.data(), payload.size());
- return true;
- }))
- .WillOnce(Invoke([&](const QuicPathFrameBuffer& payload,
- const QuicSocketAddress&, const QuicSocketAddress&,
- const QuicSocketAddress&, QuicPacketWriter*) {
- EXPECT_NE(challenge_data, payload);
- memcpy(challenge_data.data(), payload.data(), payload.size());
- return true;
- }));
- EXPECT_CALL(send_delegate_, GetRetryTimeout(peer_address_, &writer_))
- .Times(2u);
- path_validator_.StartPathValidation(
- std::unique_ptr<QuicPathValidationContext>(context_),
- std::unique_ptr<MockQuicPathValidationResultDelegate>(result_delegate_));
-
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(3 * kInitialRttMs));
- random_.ChangeValue();
- alarm_factory_.FireAlarm(
- QuicPathValidatorPeer::retry_timer(&path_validator_));
-
- // Respond to the 2nd PATH_CHALLENGE should complete the validation.
- EXPECT_CALL(*result_delegate_, OnPathValidationSuccess(_));
- path_validator_.OnPathResponse(challenge_data, self_address_);
- EXPECT_FALSE(path_validator_.HasPendingPathValidation());
-}
-
-TEST_F(QuicPathValidatorTest, ValidationTimeOut) {
- EXPECT_CALL(send_delegate_,
- SendPathChallenge(_, self_address_, peer_address_,
- effective_peer_address_, &writer_))
- .Times(3u)
- .WillRepeatedly(Return(true));
- EXPECT_CALL(send_delegate_, GetRetryTimeout(peer_address_, &writer_))
- .Times(3u);
- path_validator_.StartPathValidation(
- std::unique_ptr<QuicPathValidationContext>(context_),
- std::unique_ptr<MockQuicPathValidationResultDelegate>(result_delegate_));
-
- QuicPathFrameBuffer challenge_data;
- memset(challenge_data.data(), 'a', challenge_data.size());
- // Reception of a PATH_RESPONSE with different payload should be ignored.
- path_validator_.OnPathResponse(challenge_data, self_address_);
-
- // Retry 3 times. The 3rd time should fail the validation.
- EXPECT_CALL(*result_delegate_, OnPathValidationFailure(_))
- .WillOnce(Invoke([=](std::unique_ptr<QuicPathValidationContext> context) {
- EXPECT_EQ(context_, context.get());
- }));
- for (size_t i = 0; i <= QuicPathValidator::kMaxRetryTimes; ++i) {
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(3 * kInitialRttMs));
- alarm_factory_.FireAlarm(
- QuicPathValidatorPeer::retry_timer(&path_validator_));
- }
-}
-
-TEST_F(QuicPathValidatorTest, SendPathChallengeError) {
- EXPECT_CALL(send_delegate_,
- SendPathChallenge(_, self_address_, peer_address_,
- effective_peer_address_, &writer_))
- .WillOnce(Invoke([&](const QuicPathFrameBuffer&, const QuicSocketAddress&,
- const QuicSocketAddress&, const QuicSocketAddress&,
- QuicPacketWriter*) {
- // Abandon this validation in the call stack shouldn't cause crash and
- // should cancel the alarm.
- path_validator_.CancelPathValidation();
- return false;
- }));
- EXPECT_CALL(send_delegate_, GetRetryTimeout(peer_address_, &writer_))
- .Times(0u);
- EXPECT_CALL(*result_delegate_, OnPathValidationFailure(_));
- path_validator_.StartPathValidation(
- std::unique_ptr<QuicPathValidationContext>(context_),
- std::unique_ptr<MockQuicPathValidationResultDelegate>(result_delegate_));
- EXPECT_FALSE(path_validator_.HasPendingPathValidation());
- EXPECT_FALSE(QuicPathValidatorPeer::retry_timer(&path_validator_)->IsSet());
-}
-
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_process_packet_interface.h b/chromium/net/third_party/quiche/src/quic/core/quic_process_packet_interface.h
deleted file mode 100644
index cbe257f269f..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_process_packet_interface.h
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_PROCESS_PACKET_INTERFACE_H_
-#define QUICHE_QUIC_CORE_QUIC_PROCESS_PACKET_INTERFACE_H_
-
-#include "quic/core/quic_packets.h"
-#include "quic/platform/api/quic_socket_address.h"
-
-namespace quic {
-
-// A class to process each incoming packet.
-class QUIC_NO_EXPORT ProcessPacketInterface {
- public:
- virtual ~ProcessPacketInterface() {}
- virtual void ProcessPacket(const QuicSocketAddress& self_address,
- const QuicSocketAddress& peer_address,
- const QuicReceivedPacket& packet) = 0;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_QUIC_PROCESS_PACKET_INTERFACE_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_protocol_flags_list.h b/chromium/net/third_party/quiche/src/quic/core/quic_protocol_flags_list.h
deleted file mode 100644
index 3e327139a18..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_protocol_flags_list.h
+++ /dev/null
@@ -1,290 +0,0 @@
-// Copyright (c) 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// NOLINT(build/header_guard)
-// This file intentionally does not have header guards, it's intended to be
-// included multiple times, each time with a different definition of
-// QUIC_PROTOCOL_FLAG.
-
-#if defined(QUIC_PROTOCOL_FLAG)
-
-QUIC_PROTOCOL_FLAG(
- bool,
- quic_allow_chlo_buffering,
- true,
- "If true, allows packets to be buffered in anticipation of a "
- "future CHLO, and allow CHLO packets to be buffered until next "
- "iteration of the event loop.")
-
-QUIC_PROTOCOL_FLAG(bool,
- quic_disable_pacing_for_perf_tests,
- false,
- "If true, disable pacing in QUIC")
-
-QUIC_PROTOCOL_FLAG(bool,
- quic_enforce_single_packet_chlo,
- true,
- "If true, enforce that QUIC CHLOs fit in one packet")
-
-// Currently, this number is quite conservative. At a hypothetical 1000 qps,
-// this means that the longest time-wait list we should see is:
-// 200 seconds * 1000 qps = 200000.
-// Of course, there are usually many queries per QUIC connection, so we allow a
-// factor of 3 leeway.
-QUIC_PROTOCOL_FLAG(int64_t,
- quic_time_wait_list_max_connections,
- 600000,
- "Maximum number of connections on the time-wait list. "
- "A negative value implies no configured limit.")
-
-QUIC_PROTOCOL_FLAG(int64_t,
- quic_time_wait_list_seconds,
- 200,
- "Time period for which a given connection_id should live in "
- "the time-wait state.")
-
-// This number is relatively conservative. For example, there are at most 1K
-// queued stateless resets, which consume 1K * 21B = 21KB.
-QUIC_PROTOCOL_FLAG(
- uint64_t, quic_time_wait_list_max_pending_packets, 1024,
- "Upper limit of pending packets in time wait list when writer is blocked.")
-
-// Stop sending a reset if the recorded number of addresses that server has
-// recently sent stateless reset to exceeds this limit.
-QUIC_PROTOCOL_FLAG(uint64_t, quic_max_recent_stateless_reset_addresses, 1024,
- "Max number of recorded recent reset addresses.")
-
-// After this timeout, recent reset addresses will be cleared.
-// FLAGS_quic_max_recent_stateless_reset_addresses * (1000ms /
-// FLAGS_quic_recent_stateless_reset_addresses_lifetime_ms) is roughly the max
-// reset per second. For example, 1024 * (1000ms / 1000ms) = 1K reset per
-// second.
-QUIC_PROTOCOL_FLAG(
- uint64_t, quic_recent_stateless_reset_addresses_lifetime_ms, 1000,
- "Max time that a client address lives in recent reset addresses set.")
-
-QUIC_PROTOCOL_FLAG(double,
- quic_bbr_cwnd_gain,
- 2.0f,
- "Congestion window gain for QUIC BBR during PROBE_BW phase.")
-
-QUIC_PROTOCOL_FLAG(
- int32_t,
- quic_buffered_data_threshold,
- 8 * 1024,
- "If buffered data in QUIC stream is less than this "
- "threshold, buffers all provided data or asks upper layer for more data")
-
-QUIC_PROTOCOL_FLAG(
- uint64_t,
- quic_send_buffer_max_data_slice_size,
- 4 * 1024,
- "Max size of data slice in bytes for QUIC stream send buffer.")
-
-QUIC_PROTOCOL_FLAG(
- int32_t,
- quic_lumpy_pacing_size,
- 2,
- "Number of packets that the pacing sender allows in bursts during "
- "pacing. This flag is ignored if a flow's estimated bandwidth is "
- "lower than 1200 kbps.")
-
-QUIC_PROTOCOL_FLAG(
- double,
- quic_lumpy_pacing_cwnd_fraction,
- 0.25f,
- "Congestion window fraction that the pacing sender allows in bursts "
- "during pacing.")
-
-QUIC_PROTOCOL_FLAG(
- int32_t, quic_lumpy_pacing_min_bandwidth_kbps, 1200,
- "The minimum estimated client bandwidth below which the pacing sender will "
- "not allow bursts.")
-
-QUIC_PROTOCOL_FLAG(int32_t,
- quic_max_pace_time_into_future_ms,
- 10,
- "Max time that QUIC can pace packets into the future in ms.")
-
-QUIC_PROTOCOL_FLAG(
- double,
- quic_pace_time_into_future_srtt_fraction,
- 0.125f, // One-eighth smoothed RTT
- "Smoothed RTT fraction that a connection can pace packets into the future.")
-
-QUIC_PROTOCOL_FLAG(bool,
- quic_export_write_path_stats_at_server,
- false,
- "If true, export detailed write path statistics at server.")
-
-QUIC_PROTOCOL_FLAG(bool,
- quic_disable_version_negotiation_grease_randomness,
- false,
- "If true, use predictable version negotiation versions.")
-
-QUIC_PROTOCOL_FLAG(bool,
- quic_enable_http3_grease_randomness,
- true,
- "If true, use random greased settings and frames.")
-
-QUIC_PROTOCOL_FLAG(
- bool, quic_enable_chaos_protection, true,
- "If true, use chaos protection to randomize client initials.")
-
-QUIC_PROTOCOL_FLAG(int64_t,
- quic_max_tracked_packet_count,
- 10000,
- "Maximum number of tracked packets.")
-
-QUIC_PROTOCOL_FLAG(
- bool,
- quic_client_convert_http_header_name_to_lowercase,
- true,
- "If true, HTTP request header names sent from QuicSpdyClientBase(and "
- "descendents) will be automatically converted to lower case.")
-
-QUIC_PROTOCOL_FLAG(
- int32_t,
- quic_bbr2_default_probe_bw_base_duration_ms,
- 2000,
- "The default minimum duration for BBRv2-native probes, in milliseconds.")
-
-QUIC_PROTOCOL_FLAG(
- int32_t,
- quic_bbr2_default_probe_bw_max_rand_duration_ms,
- 1000,
- "The default upper bound of the random amount of BBRv2-native "
- "probes, in milliseconds.")
-
-QUIC_PROTOCOL_FLAG(
- int32_t,
- quic_bbr2_default_probe_rtt_period_ms,
- 10000,
- "The default period for entering PROBE_RTT, in milliseconds.")
-
-QUIC_PROTOCOL_FLAG(
- double,
- quic_bbr2_default_loss_threshold,
- 0.02,
- "The default loss threshold for QUIC BBRv2, should be a value "
- "between 0 and 1.")
-
-QUIC_PROTOCOL_FLAG(
- int32_t,
- quic_bbr2_default_startup_full_loss_count,
- 8,
- "The default minimum number of loss marking events to exit STARTUP.")
-
-QUIC_PROTOCOL_FLAG(
- int32_t,
- quic_bbr2_default_probe_bw_full_loss_count,
- 2,
- "The default minimum number of loss marking events to exit PROBE_UP phase.")
-
-QUIC_PROTOCOL_FLAG(
- double,
- quic_bbr2_default_inflight_hi_headroom,
- 0.15,
- "The default fraction of unutilized headroom to try to leave in path "
- "upon high loss.")
-
-QUIC_PROTOCOL_FLAG(
- int32_t,
- quic_bbr2_default_initial_ack_height_filter_window,
- 10,
- "The default initial value of the max ack height filter's window length.")
-
-QUIC_PROTOCOL_FLAG(
- double,
- quic_ack_aggregation_bandwidth_threshold,
- 1.0,
- "If the bandwidth during ack aggregation is smaller than (estimated "
- "bandwidth * this flag), consider the current aggregation completed "
- "and starts a new one.")
-
-// TODO(b/153892665): Change the default value of
-// quic_anti_amplification_factor back to 3 when cert compression is
-// supported.
-QUIC_PROTOCOL_FLAG(
- int32_t,
- quic_anti_amplification_factor,
- 5,
- 3,
- "Anti-amplification factor. Before address validation, server will "
- "send no more than factor times bytes received.")
-
-QUIC_PROTOCOL_FLAG(
- int32_t,
- quic_max_buffered_crypto_bytes,
- 16 * 1024, // 16 KB
- "The maximum amount of CRYPTO frame data that can be buffered.")
-
-QUIC_PROTOCOL_FLAG(
- int32_t,
- quic_max_aggressive_retransmittable_on_wire_ping_count,
- 5,
- "Maximum number of consecutive pings that can be sent with the "
- "aggressive initial retransmittable on the wire timeout if there is "
- "no new stream data received. After this limit, the timeout will be "
- "doubled each ping until it exceeds the default ping timeout.")
-
-QUIC_PROTOCOL_FLAG(
- int32_t,
- quic_max_retransmittable_on_wire_ping_count,
- 1000,
- "Maximum number of pings that can be sent with the retransmittable "
- "on the wire timeout, over the lifetime of a connection. After this "
- "limit, the timeout will be the default ping timeout.")
-
-QUIC_PROTOCOL_FLAG(int32_t,
- quic_max_congestion_window,
- 2000,
- "The maximum congestion window in packets.")
-
-QUIC_PROTOCOL_FLAG(
- int32_t,
- quic_max_streams_window_divisor,
- 2,
- "The divisor that controls how often MAX_STREAMS frame is sent.")
-
-QUIC_PROTOCOL_FLAG(
- uint64_t,
- quic_key_update_confidentiality_limit,
- 0,
- "If non-zero and key update is allowed, the maximum number of "
- "packets sent for each key phase before initiating a key update.")
-
-QUIC_PROTOCOL_FLAG(bool,
- quic_disable_client_tls_zero_rtt,
- false,
- "If true, QUIC client with TLS will not try 0-RTT.")
-
-QUIC_PROTOCOL_FLAG(bool,
- quic_disable_server_tls_resumption,
- false,
- "If true, QUIC server will disable TLS resumption by not "
- "issuing or processing session tickets.")
-
-QUIC_PROTOCOL_FLAG(bool,
- quic_defer_send_in_response,
- true,
- "If true, QUIC servers will defer sending in response to "
- "incoming packets by default.")
-
-QUIC_PROTOCOL_FLAG(
- bool,
- quic_header_size_limit_includes_overhead,
- true,
- "If true, QUIC QPACK decoder includes 32-bytes overheader per entry while "
- "comparing request/response header size against its upper limit.")
-
-QUIC_PROTOCOL_FLAG(
- bool,
- quic_reject_retry_token_in_initial_packet,
- false,
- "If true, always reject retry_token received in INITIAL packets")
-
-QUIC_PROTOCOL_FLAG(bool, quic_use_lower_server_response_mtu_for_test, false,
- "If true, cap server response packet size at 1250.")
-#endif
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_received_packet_manager.cc b/chromium/net/third_party/quiche/src/quic/core/quic_received_packet_manager.cc
deleted file mode 100644
index d0f1578fa79..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_received_packet_manager.cc
+++ /dev/null
@@ -1,338 +0,0 @@
-// Copyright 2013 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 "quic/core/quic_received_packet_manager.h"
-
-#include <algorithm>
-#include <limits>
-#include <utility>
-
-#include "quic/core/congestion_control/rtt_stats.h"
-#include "quic/core/crypto/crypto_protocol.h"
-#include "quic/core/quic_connection_stats.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-namespace {
-
-// The maximum number of packets to ack immediately after a missing packet for
-// fast retransmission to kick in at the sender. This limit is created to
-// reduce the number of acks sent that have no benefit for fast retransmission.
-// Set to the number of nacks needed for fast retransmit plus one for protection
-// against an ack loss
-const size_t kMaxPacketsAfterNewMissing = 4;
-
-// One eighth RTT delay when doing ack decimation.
-const float kShortAckDecimationDelay = 0.125;
-} // namespace
-
-QuicReceivedPacketManager::QuicReceivedPacketManager()
- : QuicReceivedPacketManager(nullptr) {}
-
-QuicReceivedPacketManager::QuicReceivedPacketManager(QuicConnectionStats* stats)
- : ack_frame_updated_(false),
- max_ack_ranges_(0),
- time_largest_observed_(QuicTime::Zero()),
- save_timestamps_(false),
- save_timestamps_for_in_order_packets_(false),
- stats_(stats),
- num_retransmittable_packets_received_since_last_ack_sent_(0),
- min_received_before_ack_decimation_(kMinReceivedBeforeAckDecimation),
- ack_frequency_(kDefaultRetransmittablePacketsBeforeAck),
- ack_decimation_delay_(kAckDecimationDelay),
- unlimited_ack_decimation_(false),
- one_immediate_ack_(false),
- ignore_order_(false),
- local_max_ack_delay_(
- QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs)),
- ack_timeout_(QuicTime::Zero()),
- time_of_previous_received_packet_(QuicTime::Zero()),
- was_last_packet_missing_(false),
- last_ack_frequency_frame_sequence_number_(-1) {}
-
-QuicReceivedPacketManager::~QuicReceivedPacketManager() {}
-
-void QuicReceivedPacketManager::SetFromConfig(const QuicConfig& config,
- Perspective perspective) {
- if (config.HasClientSentConnectionOption(kAKD3, perspective)) {
- ack_decimation_delay_ = kShortAckDecimationDelay;
- }
- if (config.HasClientSentConnectionOption(kAKDU, perspective)) {
- unlimited_ack_decimation_ = true;
- }
- if (config.HasClientSentConnectionOption(k1ACK, perspective)) {
- one_immediate_ack_ = true;
- }
-}
-
-void QuicReceivedPacketManager::RecordPacketReceived(
- const QuicPacketHeader& header,
- QuicTime receipt_time) {
- const QuicPacketNumber packet_number = header.packet_number;
- QUICHE_DCHECK(IsAwaitingPacket(packet_number))
- << " packet_number:" << packet_number;
- was_last_packet_missing_ = IsMissing(packet_number);
- if (!ack_frame_updated_) {
- ack_frame_.received_packet_times.clear();
- }
- ack_frame_updated_ = true;
-
- // Whether |packet_number| is received out of order.
- bool packet_reordered = false;
- if (LargestAcked(ack_frame_).IsInitialized() &&
- LargestAcked(ack_frame_) > packet_number) {
- // Record how out of order stats.
- packet_reordered = true;
- ++stats_->packets_reordered;
- stats_->max_sequence_reordering =
- std::max(stats_->max_sequence_reordering,
- LargestAcked(ack_frame_) - packet_number);
- int64_t reordering_time_us =
- (receipt_time - time_largest_observed_).ToMicroseconds();
- stats_->max_time_reordering_us =
- std::max(stats_->max_time_reordering_us, reordering_time_us);
- }
- if (!LargestAcked(ack_frame_).IsInitialized() ||
- packet_number > LargestAcked(ack_frame_)) {
- ack_frame_.largest_acked = packet_number;
- time_largest_observed_ = receipt_time;
- }
- ack_frame_.packets.Add(packet_number);
-
- if (save_timestamps_) {
- // The timestamp format only handles packets in time order.
- if (save_timestamps_for_in_order_packets_ && packet_reordered) {
- QUIC_DLOG(WARNING) << "Not saving receive timestamp for packet "
- << packet_number;
- } else if (!ack_frame_.received_packet_times.empty() &&
- ack_frame_.received_packet_times.back().second > receipt_time) {
- QUIC_LOG(WARNING)
- << "Receive time went backwards from: "
- << ack_frame_.received_packet_times.back().second.ToDebuggingValue()
- << " to " << receipt_time.ToDebuggingValue();
- } else {
- ack_frame_.received_packet_times.push_back(
- std::make_pair(packet_number, receipt_time));
- }
- }
-
- if (least_received_packet_number_.IsInitialized()) {
- least_received_packet_number_ =
- std::min(least_received_packet_number_, packet_number);
- } else {
- least_received_packet_number_ = packet_number;
- }
-}
-
-bool QuicReceivedPacketManager::IsMissing(QuicPacketNumber packet_number) {
- return LargestAcked(ack_frame_).IsInitialized() &&
- packet_number < LargestAcked(ack_frame_) &&
- !ack_frame_.packets.Contains(packet_number);
-}
-
-bool QuicReceivedPacketManager::IsAwaitingPacket(
- QuicPacketNumber packet_number) const {
- return quic::IsAwaitingPacket(ack_frame_, packet_number,
- peer_least_packet_awaiting_ack_);
-}
-
-const QuicFrame QuicReceivedPacketManager::GetUpdatedAckFrame(
- QuicTime approximate_now) {
- if (time_largest_observed_ == QuicTime::Zero()) {
- // We have received no packets.
- ack_frame_.ack_delay_time = QuicTime::Delta::Infinite();
- } else {
- // Ensure the delta is zero if approximate now is "in the past".
- ack_frame_.ack_delay_time = approximate_now < time_largest_observed_
- ? QuicTime::Delta::Zero()
- : approximate_now - time_largest_observed_;
- }
- while (max_ack_ranges_ > 0 &&
- ack_frame_.packets.NumIntervals() > max_ack_ranges_) {
- ack_frame_.packets.RemoveSmallestInterval();
- }
- // Clear all packet times if any are too far from largest observed.
- // It's expected this is extremely rare.
- for (auto it = ack_frame_.received_packet_times.begin();
- it != ack_frame_.received_packet_times.end();) {
- if (LargestAcked(ack_frame_) - it->first >=
- std::numeric_limits<uint8_t>::max()) {
- it = ack_frame_.received_packet_times.erase(it);
- } else {
- ++it;
- }
- }
-
-#if QUIC_FRAME_DEBUG
- QuicFrame frame = QuicFrame(&ack_frame_);
- frame.delete_forbidden = true;
- return frame;
-#else // QUIC_FRAME_DEBUG
- return QuicFrame(&ack_frame_);
-#endif // QUIC_FRAME_DEBUG
-}
-
-void QuicReceivedPacketManager::DontWaitForPacketsBefore(
- QuicPacketNumber least_unacked) {
- if (!least_unacked.IsInitialized()) {
- return;
- }
- // ValidateAck() should fail if peer_least_packet_awaiting_ack shrinks.
- QUICHE_DCHECK(!peer_least_packet_awaiting_ack_.IsInitialized() ||
- peer_least_packet_awaiting_ack_ <= least_unacked);
- if (!peer_least_packet_awaiting_ack_.IsInitialized() ||
- least_unacked > peer_least_packet_awaiting_ack_) {
- peer_least_packet_awaiting_ack_ = least_unacked;
- bool packets_updated = ack_frame_.packets.RemoveUpTo(least_unacked);
- if (packets_updated) {
- // Ack frame gets updated because packets set is updated because of stop
- // waiting frame.
- ack_frame_updated_ = true;
- }
- }
- QUICHE_DCHECK(ack_frame_.packets.Empty() ||
- !peer_least_packet_awaiting_ack_.IsInitialized() ||
- ack_frame_.packets.Min() >= peer_least_packet_awaiting_ack_);
-}
-
-QuicTime::Delta QuicReceivedPacketManager::GetMaxAckDelay(
- QuicPacketNumber last_received_packet_number,
- const RttStats& rtt_stats) const {
- if (AckFrequencyFrameReceived() ||
- last_received_packet_number < PeerFirstSendingPacketNumber() +
- min_received_before_ack_decimation_) {
- return local_max_ack_delay_;
- }
-
- // Wait for the minimum of the ack decimation delay or the delayed ack time
- // before sending an ack.
- QuicTime::Delta ack_delay = std::min(
- local_max_ack_delay_, rtt_stats.min_rtt() * ack_decimation_delay_);
- return std::max(ack_delay, kAlarmGranularity);
-}
-
-void QuicReceivedPacketManager::MaybeUpdateAckFrequency(
- QuicPacketNumber last_received_packet_number) {
- if (AckFrequencyFrameReceived()) {
- // Skip Ack Decimation below after receiving an AckFrequencyFrame from the
- // other end point.
- return;
- }
- if (last_received_packet_number <
- PeerFirstSendingPacketNumber() + min_received_before_ack_decimation_) {
- return;
- }
- ack_frequency_ = unlimited_ack_decimation_
- ? std::numeric_limits<size_t>::max()
- : kMaxRetransmittablePacketsBeforeAck;
-}
-
-void QuicReceivedPacketManager::MaybeUpdateAckTimeout(
- bool should_last_packet_instigate_acks,
- QuicPacketNumber last_received_packet_number,
- QuicTime now,
- const RttStats* rtt_stats) {
- if (!ack_frame_updated_) {
- // ACK frame has not been updated, nothing to do.
- return;
- }
-
- if (!ignore_order_ && was_last_packet_missing_ &&
- last_sent_largest_acked_.IsInitialized() &&
- last_received_packet_number < last_sent_largest_acked_) {
- // Only ack immediately if an ACK frame was sent with a larger largest acked
- // than the newly received packet number.
- ack_timeout_ = now;
- return;
- }
-
- if (!should_last_packet_instigate_acks) {
- return;
- }
-
- ++num_retransmittable_packets_received_since_last_ack_sent_;
-
- MaybeUpdateAckFrequency(last_received_packet_number);
- if (num_retransmittable_packets_received_since_last_ack_sent_ >=
- ack_frequency_) {
- ack_timeout_ = now;
- return;
- }
-
- if (!ignore_order_ && HasNewMissingPackets()) {
- ack_timeout_ = now;
- return;
- }
-
- QuicTime updated_ack_time =
- now + GetMaxAckDelay(last_received_packet_number, *rtt_stats);
- if (!ack_timeout_.IsInitialized() || ack_timeout_ > updated_ack_time) {
- ack_timeout_ = updated_ack_time;
- }
-}
-
-void QuicReceivedPacketManager::ResetAckStates() {
- ack_frame_updated_ = false;
- ack_timeout_ = QuicTime::Zero();
- num_retransmittable_packets_received_since_last_ack_sent_ = 0;
- last_sent_largest_acked_ = LargestAcked(ack_frame_);
-}
-
-bool QuicReceivedPacketManager::HasMissingPackets() const {
- if (ack_frame_.packets.Empty()) {
- return false;
- }
- if (ack_frame_.packets.NumIntervals() > 1) {
- return true;
- }
- return peer_least_packet_awaiting_ack_.IsInitialized() &&
- ack_frame_.packets.Min() > peer_least_packet_awaiting_ack_;
-}
-
-bool QuicReceivedPacketManager::HasNewMissingPackets() const {
- if (one_immediate_ack_) {
- return HasMissingPackets() && ack_frame_.packets.LastIntervalLength() == 1;
- }
- return HasMissingPackets() &&
- ack_frame_.packets.LastIntervalLength() <= kMaxPacketsAfterNewMissing;
-}
-
-bool QuicReceivedPacketManager::ack_frame_updated() const {
- return ack_frame_updated_;
-}
-
-QuicPacketNumber QuicReceivedPacketManager::GetLargestObserved() const {
- return LargestAcked(ack_frame_);
-}
-
-QuicPacketNumber QuicReceivedPacketManager::PeerFirstSendingPacketNumber()
- const {
- if (!least_received_packet_number_.IsInitialized()) {
- QUIC_BUG(quic_bug_10849_1) << "No packets have been received yet";
- return QuicPacketNumber(1);
- }
- return least_received_packet_number_;
-}
-
-bool QuicReceivedPacketManager::IsAckFrameEmpty() const {
- return ack_frame_.packets.Empty();
-}
-
-void QuicReceivedPacketManager::OnAckFrequencyFrame(
- const QuicAckFrequencyFrame& frame) {
- int64_t new_sequence_number = frame.sequence_number;
- if (new_sequence_number <= last_ack_frequency_frame_sequence_number_) {
- // Ignore old ACK_FREQUENCY frames.
- return;
- }
- last_ack_frequency_frame_sequence_number_ = new_sequence_number;
- ack_frequency_ = frame.packet_tolerance;
- local_max_ack_delay_ = frame.max_ack_delay;
- ignore_order_ = frame.ignore_order;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_received_packet_manager.h b/chromium/net/third_party/quiche/src/quic/core/quic_received_packet_manager.h
deleted file mode 100644
index 21f7f045d4a..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_received_packet_manager.h
+++ /dev/null
@@ -1,218 +0,0 @@
-// Copyright 2013 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_RECEIVED_PACKET_MANAGER_H_
-#define QUICHE_QUIC_CORE_QUIC_RECEIVED_PACKET_MANAGER_H_
-
-#include <cstddef>
-#include "quic/core/frames/quic_ack_frequency_frame.h"
-#include "quic/core/quic_config.h"
-#include "quic/core/quic_framer.h"
-#include "quic/core/quic_packets.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-class RttStats;
-
-namespace test {
-class QuicConnectionPeer;
-class QuicReceivedPacketManagerPeer;
-class UberReceivedPacketManagerPeer;
-} // namespace test
-
-struct QuicConnectionStats;
-
-// Records all received packets by a connection.
-class QUIC_EXPORT_PRIVATE QuicReceivedPacketManager {
- public:
- QuicReceivedPacketManager();
- explicit QuicReceivedPacketManager(QuicConnectionStats* stats);
- QuicReceivedPacketManager(const QuicReceivedPacketManager&) = delete;
- QuicReceivedPacketManager& operator=(const QuicReceivedPacketManager&) =
- delete;
- virtual ~QuicReceivedPacketManager();
-
- void SetFromConfig(const QuicConfig& config, Perspective perspective);
-
- // Updates the internal state concerning which packets have been received.
- // header: the packet header.
- // timestamp: the arrival time of the packet.
- virtual void RecordPacketReceived(const QuicPacketHeader& header,
- QuicTime receipt_time);
-
- // Checks whether |packet_number| is missing and less than largest observed.
- virtual bool IsMissing(QuicPacketNumber packet_number);
-
- // Checks if we're still waiting for the packet with |packet_number|.
- virtual bool IsAwaitingPacket(QuicPacketNumber packet_number) const;
-
- // Retrieves a frame containing a QuicAckFrame. The ack frame may not be
- // changed outside QuicReceivedPacketManager and must be serialized before
- // another packet is received, or it will change.
- const QuicFrame GetUpdatedAckFrame(QuicTime approximate_now);
-
- // Deletes all missing packets before least unacked. The connection won't
- // process any packets with packet number before |least_unacked| that it
- // received after this call.
- void DontWaitForPacketsBefore(QuicPacketNumber least_unacked);
-
- // Called to update ack_timeout_ to the time when an ACK needs to be sent. A
- // caller can decide whether and when to send an ACK by retrieving
- // ack_timeout_. If ack_timeout_ is not initialized, no ACK needs to be sent.
- // Otherwise, ACK needs to be sent by the specified time.
- void MaybeUpdateAckTimeout(bool should_last_packet_instigate_acks,
- QuicPacketNumber last_received_packet_number,
- QuicTime now,
- const RttStats* rtt_stats);
-
- // Resets ACK related states, called after an ACK is successfully sent.
- void ResetAckStates();
-
- // Returns true if there are any missing packets.
- bool HasMissingPackets() const;
-
- // Returns true when there are new missing packets to be reported within 3
- // packets of the largest observed.
- virtual bool HasNewMissingPackets() const;
-
- QuicPacketNumber peer_least_packet_awaiting_ack() const {
- return peer_least_packet_awaiting_ack_;
- }
-
- virtual bool ack_frame_updated() const;
-
- QuicPacketNumber GetLargestObserved() const;
-
- // Returns peer first sending packet number to our best knowledge. Considers
- // least_received_packet_number_ as peer first sending packet number. Please
- // note, this function should only be called when at least one packet has been
- // received.
- QuicPacketNumber PeerFirstSendingPacketNumber() const;
-
- // Returns true if ack frame is empty.
- bool IsAckFrameEmpty() const;
-
- void set_connection_stats(QuicConnectionStats* stats) { stats_ = stats; }
-
- // For logging purposes.
- const QuicAckFrame& ack_frame() const { return ack_frame_; }
-
- void set_max_ack_ranges(size_t max_ack_ranges) {
- max_ack_ranges_ = max_ack_ranges;
- }
-
- void set_save_timestamps(bool save_timestamps, bool in_order_packets_only) {
- save_timestamps_ = save_timestamps;
- save_timestamps_for_in_order_packets_ = in_order_packets_only;
- }
-
- size_t min_received_before_ack_decimation() const {
- return min_received_before_ack_decimation_;
- }
- void set_min_received_before_ack_decimation(size_t new_value) {
- min_received_before_ack_decimation_ = new_value;
- }
-
- void set_ack_frequency(size_t new_value) {
- QUICHE_DCHECK_GT(new_value, 0u);
- ack_frequency_ = new_value;
- }
-
- void set_local_max_ack_delay(QuicTime::Delta local_max_ack_delay) {
- local_max_ack_delay_ = local_max_ack_delay;
- }
-
- QuicTime ack_timeout() const { return ack_timeout_; }
-
- void OnAckFrequencyFrame(const QuicAckFrequencyFrame& frame);
-
- private:
- friend class test::QuicConnectionPeer;
- friend class test::QuicReceivedPacketManagerPeer;
- friend class test::UberReceivedPacketManagerPeer;
-
- // Sets ack_timeout_ to |time| if ack_timeout_ is not initialized or > time.
- void MaybeUpdateAckTimeoutTo(QuicTime time);
-
- // Maybe update ack_frequency_ when condition meets.
- void MaybeUpdateAckFrequency(QuicPacketNumber last_received_packet_number);
-
- QuicTime::Delta GetMaxAckDelay(QuicPacketNumber last_received_packet_number,
- const RttStats& rtt_stats) const;
-
- bool AckFrequencyFrameReceived() const {
- return last_ack_frequency_frame_sequence_number_ >= 0;
- }
-
- // Least packet number of the the packet sent by the peer for which it
- // hasn't received an ack.
- QuicPacketNumber peer_least_packet_awaiting_ack_;
-
- // Received packet information used to produce acks.
- QuicAckFrame ack_frame_;
-
- // True if |ack_frame_| has been updated since UpdateReceivedPacketInfo was
- // last called.
- bool ack_frame_updated_;
-
- // Maximum number of ack ranges allowed to be stored in the ack frame.
- size_t max_ack_ranges_;
-
- // The time we received the largest_observed packet number, or zero if
- // no packet numbers have been received since UpdateReceivedPacketInfo.
- // Needed for calculating ack_delay_time.
- QuicTime time_largest_observed_;
-
- // If true, save timestamps in the ack_frame_.
- bool save_timestamps_;
-
- // If true and |save_timestamps_|, only save timestamps for packets that are
- // received in order.
- bool save_timestamps_for_in_order_packets_;
-
- // Least packet number received from peer.
- QuicPacketNumber least_received_packet_number_;
-
- QuicConnectionStats* stats_;
-
- // How many retransmittable packets have arrived without sending an ack.
- QuicPacketCount num_retransmittable_packets_received_since_last_ack_sent_;
- // Ack decimation will start happening after this many packets are received.
- size_t min_received_before_ack_decimation_;
- // Ack every n-th packet.
- size_t ack_frequency_;
- // The max delay in fraction of min_rtt to use when sending decimated acks.
- float ack_decimation_delay_;
- // When true, removes ack decimation's max number of packets(10) before
- // sending an ack.
- bool unlimited_ack_decimation_;
- // When true, only send 1 immediate ACK when reordering is detected.
- bool one_immediate_ack_;
- // When true, do not ack immediately upon observation of packet reordering.
- bool ignore_order_;
-
- // The local node's maximum ack delay time. This is the maximum amount of
- // time to wait before sending an acknowledgement.
- QuicTime::Delta local_max_ack_delay_;
- // Time that an ACK needs to be sent. 0 means no ACK is pending. Used when
- // decide_when_to_send_acks_ is true.
- QuicTime ack_timeout_;
-
- // The time the previous ack-instigating packet was received and processed.
- QuicTime time_of_previous_received_packet_;
- // Whether the most recent packet was missing before it was received.
- bool was_last_packet_missing_;
-
- // Last sent largest acked, which gets updated when ACK was successfully sent.
- QuicPacketNumber last_sent_largest_acked_;
-
- // The sequence number of the last received AckFrequencyFrame. Negative if
- // none received.
- int64_t last_ack_frequency_frame_sequence_number_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_QUIC_RECEIVED_PACKET_MANAGER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_received_packet_manager_test.cc b/chromium/net/third_party/quiche/src/quic/core/quic_received_packet_manager_test.cc
deleted file mode 100644
index cc0438140fe..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_received_packet_manager_test.cc
+++ /dev/null
@@ -1,642 +0,0 @@
-// Copyright 2013 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 "quic/core/quic_received_packet_manager.h"
-
-#include <algorithm>
-#include <cstddef>
-#include <ostream>
-#include <vector>
-
-#include "quic/core/congestion_control/rtt_stats.h"
-#include "quic/core/crypto/crypto_protocol.h"
-#include "quic/core/quic_connection_stats.h"
-#include "quic/core/quic_constants.h"
-#include "quic/platform/api/quic_expect_bug.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/mock_clock.h"
-
-namespace quic {
-namespace test {
-
-class QuicReceivedPacketManagerPeer {
- public:
- static void SetOneImmediateAck(QuicReceivedPacketManager* manager,
- bool one_immediate_ack) {
- manager->one_immediate_ack_ = one_immediate_ack;
- }
-
- static void SetAckDecimationDelay(QuicReceivedPacketManager* manager,
- float ack_decimation_delay) {
- manager->ack_decimation_delay_ = ack_decimation_delay;
- }
-};
-
-namespace {
-
-const bool kInstigateAck = true;
-const QuicTime::Delta kMinRttMs = QuicTime::Delta::FromMilliseconds(40);
-const QuicTime::Delta kDelayedAckTime =
- QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
-
-class QuicReceivedPacketManagerTest : public QuicTest {
- protected:
- QuicReceivedPacketManagerTest() : received_manager_(&stats_) {
- clock_.AdvanceTime(QuicTime::Delta::FromSeconds(1));
- rtt_stats_.UpdateRtt(kMinRttMs, QuicTime::Delta::Zero(), QuicTime::Zero());
- received_manager_.set_save_timestamps(true, false);
- }
-
- void RecordPacketReceipt(uint64_t packet_number) {
- RecordPacketReceipt(packet_number, QuicTime::Zero());
- }
-
- void RecordPacketReceipt(uint64_t packet_number, QuicTime receipt_time) {
- QuicPacketHeader header;
- header.packet_number = QuicPacketNumber(packet_number);
- received_manager_.RecordPacketReceived(header, receipt_time);
- }
-
- bool HasPendingAck() {
- return received_manager_.ack_timeout().IsInitialized();
- }
-
- void MaybeUpdateAckTimeout(bool should_last_packet_instigate_acks,
- uint64_t last_received_packet_number) {
- received_manager_.MaybeUpdateAckTimeout(
- should_last_packet_instigate_acks,
- QuicPacketNumber(last_received_packet_number), clock_.ApproximateNow(),
- &rtt_stats_);
- }
-
- void CheckAckTimeout(QuicTime time) {
- QUICHE_DCHECK(HasPendingAck());
- QUICHE_DCHECK_EQ(received_manager_.ack_timeout(), time);
- if (time <= clock_.ApproximateNow()) {
- // ACK timeout expires, send an ACK.
- received_manager_.ResetAckStates();
- QUICHE_DCHECK(!HasPendingAck());
- }
- }
-
- MockClock clock_;
- RttStats rtt_stats_;
- QuicConnectionStats stats_;
- QuicReceivedPacketManager received_manager_;
-};
-
-TEST_F(QuicReceivedPacketManagerTest, DontWaitForPacketsBefore) {
- QuicPacketHeader header;
- header.packet_number = QuicPacketNumber(2u);
- received_manager_.RecordPacketReceived(header, QuicTime::Zero());
- header.packet_number = QuicPacketNumber(7u);
- received_manager_.RecordPacketReceived(header, QuicTime::Zero());
- EXPECT_TRUE(received_manager_.IsAwaitingPacket(QuicPacketNumber(3u)));
- EXPECT_TRUE(received_manager_.IsAwaitingPacket(QuicPacketNumber(6u)));
- received_manager_.DontWaitForPacketsBefore(QuicPacketNumber(4));
- EXPECT_FALSE(received_manager_.IsAwaitingPacket(QuicPacketNumber(3u)));
- EXPECT_TRUE(received_manager_.IsAwaitingPacket(QuicPacketNumber(6u)));
-}
-
-TEST_F(QuicReceivedPacketManagerTest, GetUpdatedAckFrame) {
- QuicPacketHeader header;
- header.packet_number = QuicPacketNumber(2u);
- QuicTime two_ms = QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(2);
- EXPECT_FALSE(received_manager_.ack_frame_updated());
- received_manager_.RecordPacketReceived(header, two_ms);
- EXPECT_TRUE(received_manager_.ack_frame_updated());
-
- QuicFrame ack = received_manager_.GetUpdatedAckFrame(QuicTime::Zero());
- received_manager_.ResetAckStates();
- EXPECT_FALSE(received_manager_.ack_frame_updated());
- // When UpdateReceivedPacketInfo with a time earlier than the time of the
- // largest observed packet, make sure that the delta is 0, not negative.
- EXPECT_EQ(QuicTime::Delta::Zero(), ack.ack_frame->ack_delay_time);
- EXPECT_EQ(1u, ack.ack_frame->received_packet_times.size());
-
- QuicTime four_ms = QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(4);
- ack = received_manager_.GetUpdatedAckFrame(four_ms);
- received_manager_.ResetAckStates();
- EXPECT_FALSE(received_manager_.ack_frame_updated());
- // When UpdateReceivedPacketInfo after not having received a new packet,
- // the delta should still be accurate.
- EXPECT_EQ(QuicTime::Delta::FromMilliseconds(2),
- ack.ack_frame->ack_delay_time);
- // And received packet times won't have change.
- EXPECT_EQ(1u, ack.ack_frame->received_packet_times.size());
-
- header.packet_number = QuicPacketNumber(999u);
- received_manager_.RecordPacketReceived(header, two_ms);
- header.packet_number = QuicPacketNumber(4u);
- received_manager_.RecordPacketReceived(header, two_ms);
- header.packet_number = QuicPacketNumber(1000u);
- received_manager_.RecordPacketReceived(header, two_ms);
- EXPECT_TRUE(received_manager_.ack_frame_updated());
- ack = received_manager_.GetUpdatedAckFrame(two_ms);
- received_manager_.ResetAckStates();
- EXPECT_FALSE(received_manager_.ack_frame_updated());
- // UpdateReceivedPacketInfo should discard any times which can't be
- // expressed on the wire.
- EXPECT_EQ(2u, ack.ack_frame->received_packet_times.size());
-}
-
-TEST_F(QuicReceivedPacketManagerTest, UpdateReceivedConnectionStats) {
- EXPECT_FALSE(received_manager_.ack_frame_updated());
- RecordPacketReceipt(1);
- EXPECT_TRUE(received_manager_.ack_frame_updated());
- RecordPacketReceipt(6);
- RecordPacketReceipt(2,
- QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(1));
-
- EXPECT_EQ(4u, stats_.max_sequence_reordering);
- EXPECT_EQ(1000, stats_.max_time_reordering_us);
- EXPECT_EQ(1u, stats_.packets_reordered);
-}
-
-TEST_F(QuicReceivedPacketManagerTest, LimitAckRanges) {
- received_manager_.set_max_ack_ranges(10);
- EXPECT_FALSE(received_manager_.ack_frame_updated());
- for (int i = 0; i < 100; ++i) {
- RecordPacketReceipt(1 + 2 * i);
- EXPECT_TRUE(received_manager_.ack_frame_updated());
- received_manager_.GetUpdatedAckFrame(QuicTime::Zero());
- EXPECT_GE(10u, received_manager_.ack_frame().packets.NumIntervals());
- EXPECT_EQ(QuicPacketNumber(1u + 2 * i),
- received_manager_.ack_frame().packets.Max());
- for (int j = 0; j < std::min(10, i + 1); ++j) {
- ASSERT_GE(i, j);
- EXPECT_TRUE(received_manager_.ack_frame().packets.Contains(
- QuicPacketNumber(1 + (i - j) * 2)));
- if (i > j) {
- EXPECT_FALSE(received_manager_.ack_frame().packets.Contains(
- QuicPacketNumber((i - j) * 2)));
- }
- }
- }
-}
-
-TEST_F(QuicReceivedPacketManagerTest, IgnoreOutOfOrderTimestamps) {
- EXPECT_FALSE(received_manager_.ack_frame_updated());
- RecordPacketReceipt(1, QuicTime::Zero());
- EXPECT_TRUE(received_manager_.ack_frame_updated());
- EXPECT_EQ(1u, received_manager_.ack_frame().received_packet_times.size());
- RecordPacketReceipt(2,
- QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(1));
- EXPECT_EQ(2u, received_manager_.ack_frame().received_packet_times.size());
- RecordPacketReceipt(3, QuicTime::Zero());
- EXPECT_EQ(2u, received_manager_.ack_frame().received_packet_times.size());
-}
-
-TEST_F(QuicReceivedPacketManagerTest, IgnoreOutOfOrderPackets) {
- received_manager_.set_save_timestamps(true, true);
- EXPECT_FALSE(received_manager_.ack_frame_updated());
- RecordPacketReceipt(1, QuicTime::Zero());
- EXPECT_TRUE(received_manager_.ack_frame_updated());
- EXPECT_EQ(1u, received_manager_.ack_frame().received_packet_times.size());
- RecordPacketReceipt(4,
- QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(1));
- EXPECT_EQ(2u, received_manager_.ack_frame().received_packet_times.size());
-
- RecordPacketReceipt(3,
- QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(3));
- EXPECT_EQ(2u, received_manager_.ack_frame().received_packet_times.size());
-}
-
-TEST_F(QuicReceivedPacketManagerTest, HasMissingPackets) {
- EXPECT_QUIC_BUG(received_manager_.PeerFirstSendingPacketNumber(),
- "No packets have been received yet");
- RecordPacketReceipt(4, QuicTime::Zero());
- EXPECT_EQ(QuicPacketNumber(4),
- received_manager_.PeerFirstSendingPacketNumber());
- EXPECT_FALSE(received_manager_.HasMissingPackets());
- RecordPacketReceipt(3, QuicTime::Zero());
- EXPECT_FALSE(received_manager_.HasMissingPackets());
- EXPECT_EQ(QuicPacketNumber(3),
- received_manager_.PeerFirstSendingPacketNumber());
- RecordPacketReceipt(1, QuicTime::Zero());
- EXPECT_EQ(QuicPacketNumber(1),
- received_manager_.PeerFirstSendingPacketNumber());
- EXPECT_TRUE(received_manager_.HasMissingPackets());
- RecordPacketReceipt(2, QuicTime::Zero());
- EXPECT_EQ(QuicPacketNumber(1),
- received_manager_.PeerFirstSendingPacketNumber());
- EXPECT_FALSE(received_manager_.HasMissingPackets());
-}
-
-TEST_F(QuicReceivedPacketManagerTest, OutOfOrderReceiptCausesAckSent) {
- EXPECT_FALSE(HasPendingAck());
-
- RecordPacketReceipt(3, clock_.ApproximateNow());
- MaybeUpdateAckTimeout(kInstigateAck, 3);
- // Delayed ack is scheduled.
- CheckAckTimeout(clock_.ApproximateNow() + kDelayedAckTime);
-
- RecordPacketReceipt(5, clock_.ApproximateNow());
- MaybeUpdateAckTimeout(kInstigateAck, 5);
- // Immediate ack is sent.
- CheckAckTimeout(clock_.ApproximateNow());
-
- RecordPacketReceipt(6, clock_.ApproximateNow());
- MaybeUpdateAckTimeout(kInstigateAck, 6);
- // Immediate ack is scheduled, because 4 is still missing.
- CheckAckTimeout(clock_.ApproximateNow());
-
- RecordPacketReceipt(2, clock_.ApproximateNow());
- MaybeUpdateAckTimeout(kInstigateAck, 2);
- CheckAckTimeout(clock_.ApproximateNow());
-
- RecordPacketReceipt(1, clock_.ApproximateNow());
- MaybeUpdateAckTimeout(kInstigateAck, 1);
- // Should ack immediately, since this fills the last hole.
- CheckAckTimeout(clock_.ApproximateNow());
-
- RecordPacketReceipt(7, clock_.ApproximateNow());
- MaybeUpdateAckTimeout(kInstigateAck, 7);
- // Immediate ack is scheduled, because 4 is still missing.
- CheckAckTimeout(clock_.ApproximateNow());
-}
-
-TEST_F(QuicReceivedPacketManagerTest, OutOfOrderReceiptCausesAckSent1Ack) {
- QuicReceivedPacketManagerPeer::SetOneImmediateAck(&received_manager_, true);
- EXPECT_FALSE(HasPendingAck());
-
- RecordPacketReceipt(3, clock_.ApproximateNow());
- MaybeUpdateAckTimeout(kInstigateAck, 3);
- // Delayed ack is scheduled.
- CheckAckTimeout(clock_.ApproximateNow() + kDelayedAckTime);
-
- RecordPacketReceipt(5, clock_.ApproximateNow());
- MaybeUpdateAckTimeout(kInstigateAck, 5);
- // Immediate ack is sent.
- CheckAckTimeout(clock_.ApproximateNow());
-
- RecordPacketReceipt(6, clock_.ApproximateNow());
- MaybeUpdateAckTimeout(kInstigateAck, 6);
- // Delayed ack is scheduled.
- CheckAckTimeout(clock_.ApproximateNow() + kDelayedAckTime);
-
- RecordPacketReceipt(2, clock_.ApproximateNow());
- MaybeUpdateAckTimeout(kInstigateAck, 2);
- CheckAckTimeout(clock_.ApproximateNow());
-
- RecordPacketReceipt(1, clock_.ApproximateNow());
- MaybeUpdateAckTimeout(kInstigateAck, 1);
- // Should ack immediately, since this fills the last hole.
- CheckAckTimeout(clock_.ApproximateNow());
-
- RecordPacketReceipt(7, clock_.ApproximateNow());
- MaybeUpdateAckTimeout(kInstigateAck, 7);
- // Delayed ack is scheduled, even though 4 is still missing.
- CheckAckTimeout(clock_.ApproximateNow() + kDelayedAckTime);
-}
-
-TEST_F(QuicReceivedPacketManagerTest, OutOfOrderAckReceiptCausesNoAck) {
- EXPECT_FALSE(HasPendingAck());
-
- RecordPacketReceipt(2, clock_.ApproximateNow());
- MaybeUpdateAckTimeout(!kInstigateAck, 2);
- EXPECT_FALSE(HasPendingAck());
-
- RecordPacketReceipt(1, clock_.ApproximateNow());
- MaybeUpdateAckTimeout(!kInstigateAck, 1);
- EXPECT_FALSE(HasPendingAck());
-}
-
-TEST_F(QuicReceivedPacketManagerTest, AckReceiptCausesAckSend) {
- EXPECT_FALSE(HasPendingAck());
-
- RecordPacketReceipt(1, clock_.ApproximateNow());
- MaybeUpdateAckTimeout(!kInstigateAck, 1);
- EXPECT_FALSE(HasPendingAck());
-
- RecordPacketReceipt(2, clock_.ApproximateNow());
- MaybeUpdateAckTimeout(!kInstigateAck, 2);
- EXPECT_FALSE(HasPendingAck());
-
- RecordPacketReceipt(3, clock_.ApproximateNow());
- MaybeUpdateAckTimeout(kInstigateAck, 3);
- // Delayed ack is scheduled.
- CheckAckTimeout(clock_.ApproximateNow() + kDelayedAckTime);
- clock_.AdvanceTime(kDelayedAckTime);
- CheckAckTimeout(clock_.ApproximateNow());
-
- RecordPacketReceipt(4, clock_.ApproximateNow());
- MaybeUpdateAckTimeout(!kInstigateAck, 4);
- EXPECT_FALSE(HasPendingAck());
-
- RecordPacketReceipt(5, clock_.ApproximateNow());
- MaybeUpdateAckTimeout(!kInstigateAck, 5);
- EXPECT_FALSE(HasPendingAck());
-}
-
-TEST_F(QuicReceivedPacketManagerTest, AckSentEveryNthPacket) {
- EXPECT_FALSE(HasPendingAck());
- received_manager_.set_ack_frequency(3);
-
- // Receives packets 1 - 39.
- for (size_t i = 1; i <= 39; ++i) {
- RecordPacketReceipt(i, clock_.ApproximateNow());
- MaybeUpdateAckTimeout(kInstigateAck, i);
- if (i % 3 == 0) {
- CheckAckTimeout(clock_.ApproximateNow());
- } else {
- CheckAckTimeout(clock_.ApproximateNow() + kDelayedAckTime);
- }
- }
-}
-
-TEST_F(QuicReceivedPacketManagerTest, AckDecimationReducesAcks) {
- EXPECT_FALSE(HasPendingAck());
-
- // Start ack decimation from 10th packet.
- received_manager_.set_min_received_before_ack_decimation(10);
-
- // Receives packets 1 - 29.
- for (size_t i = 1; i <= 29; ++i) {
- RecordPacketReceipt(i, clock_.ApproximateNow());
- MaybeUpdateAckTimeout(kInstigateAck, i);
- if (i <= 10) {
- // For packets 1-10, ack every 2 packets.
- if (i % 2 == 0) {
- CheckAckTimeout(clock_.ApproximateNow());
- } else {
- CheckAckTimeout(clock_.ApproximateNow() + kDelayedAckTime);
- }
- continue;
- }
- // ack at 20.
- if (i == 20) {
- CheckAckTimeout(clock_.ApproximateNow());
- } else {
- CheckAckTimeout(clock_.ApproximateNow() + kMinRttMs * 0.25);
- }
- }
-
- // We now receive the 30th packet, and so we send an ack.
- RecordPacketReceipt(30, clock_.ApproximateNow());
- MaybeUpdateAckTimeout(kInstigateAck, 30);
- CheckAckTimeout(clock_.ApproximateNow());
-}
-
-TEST_F(QuicReceivedPacketManagerTest, SendDelayedAckDecimation) {
- EXPECT_FALSE(HasPendingAck());
- // The ack time should be based on min_rtt * 1/4, since it's less than the
- // default delayed ack time.
- QuicTime ack_time = clock_.ApproximateNow() + kMinRttMs * 0.25;
-
- // Process all the packets in order so there aren't missing packets.
- uint64_t kFirstDecimatedPacket = 101;
- for (uint64_t i = 1; i < kFirstDecimatedPacket; ++i) {
- RecordPacketReceipt(i, clock_.ApproximateNow());
- MaybeUpdateAckTimeout(kInstigateAck, i);
- if (i % 2 == 0) {
- // Ack every 2 packets by default.
- CheckAckTimeout(clock_.ApproximateNow());
- } else {
- CheckAckTimeout(clock_.ApproximateNow() + kDelayedAckTime);
- }
- }
-
- RecordPacketReceipt(kFirstDecimatedPacket, clock_.ApproximateNow());
- MaybeUpdateAckTimeout(kInstigateAck, kFirstDecimatedPacket);
- CheckAckTimeout(ack_time);
-
- // The 10th received packet causes an ack to be sent.
- for (uint64_t i = 1; i < 10; ++i) {
- RecordPacketReceipt(kFirstDecimatedPacket + i, clock_.ApproximateNow());
- MaybeUpdateAckTimeout(kInstigateAck, kFirstDecimatedPacket + i);
- }
- CheckAckTimeout(clock_.ApproximateNow());
-}
-
-TEST_F(QuicReceivedPacketManagerTest, SendDelayedAckDecimationMin1ms) {
- EXPECT_FALSE(HasPendingAck());
- // Seed the min_rtt with a kAlarmGranularity signal.
- rtt_stats_.UpdateRtt(kAlarmGranularity, QuicTime::Delta::Zero(),
- clock_.ApproximateNow());
- // The ack time should be based on kAlarmGranularity, since the RTT is 1ms.
- QuicTime ack_time = clock_.ApproximateNow() + kAlarmGranularity;
-
- // Process all the packets in order so there aren't missing packets.
- uint64_t kFirstDecimatedPacket = 101;
- for (uint64_t i = 1; i < kFirstDecimatedPacket; ++i) {
- RecordPacketReceipt(i, clock_.ApproximateNow());
- MaybeUpdateAckTimeout(kInstigateAck, i);
- if (i % 2 == 0) {
- // Ack every 2 packets by default.
- CheckAckTimeout(clock_.ApproximateNow());
- } else {
- CheckAckTimeout(clock_.ApproximateNow() + kDelayedAckTime);
- }
- }
-
- RecordPacketReceipt(kFirstDecimatedPacket, clock_.ApproximateNow());
- MaybeUpdateAckTimeout(kInstigateAck, kFirstDecimatedPacket);
- CheckAckTimeout(ack_time);
-
- // The 10th received packet causes an ack to be sent.
- for (uint64_t i = 1; i < 10; ++i) {
- RecordPacketReceipt(kFirstDecimatedPacket + i, clock_.ApproximateNow());
- MaybeUpdateAckTimeout(kInstigateAck, kFirstDecimatedPacket + i);
- }
- CheckAckTimeout(clock_.ApproximateNow());
-}
-
-TEST_F(QuicReceivedPacketManagerTest,
- SendDelayedAckDecimationUnlimitedAggregation) {
- EXPECT_FALSE(HasPendingAck());
- QuicConfig config;
- QuicTagVector connection_options;
- // No limit on the number of packets received before sending an ack.
- connection_options.push_back(kAKDU);
- config.SetConnectionOptionsToSend(connection_options);
- received_manager_.SetFromConfig(config, Perspective::IS_CLIENT);
-
- // The ack time should be based on min_rtt/4, since it's less than the
- // default delayed ack time.
- QuicTime ack_time = clock_.ApproximateNow() + kMinRttMs * 0.25;
-
- // Process all the initial packets in order so there aren't missing packets.
- uint64_t kFirstDecimatedPacket = 101;
- for (uint64_t i = 1; i < kFirstDecimatedPacket; ++i) {
- RecordPacketReceipt(i, clock_.ApproximateNow());
- MaybeUpdateAckTimeout(kInstigateAck, i);
- if (i % 2 == 0) {
- // Ack every 2 packets by default.
- CheckAckTimeout(clock_.ApproximateNow());
- } else {
- CheckAckTimeout(clock_.ApproximateNow() + kDelayedAckTime);
- }
- }
-
- RecordPacketReceipt(kFirstDecimatedPacket, clock_.ApproximateNow());
- MaybeUpdateAckTimeout(kInstigateAck, kFirstDecimatedPacket);
- CheckAckTimeout(ack_time);
-
- // 18 packets will not cause an ack to be sent. 19 will because when
- // stop waiting frames are in use, we ack every 20 packets no matter what.
- for (int i = 1; i <= 18; ++i) {
- RecordPacketReceipt(kFirstDecimatedPacket + i, clock_.ApproximateNow());
- MaybeUpdateAckTimeout(kInstigateAck, kFirstDecimatedPacket + i);
- }
- CheckAckTimeout(ack_time);
-}
-
-TEST_F(QuicReceivedPacketManagerTest, SendDelayedAckDecimationEighthRtt) {
- EXPECT_FALSE(HasPendingAck());
- QuicReceivedPacketManagerPeer::SetAckDecimationDelay(&received_manager_,
- 0.125);
-
- // The ack time should be based on min_rtt/8, since it's less than the
- // default delayed ack time.
- QuicTime ack_time = clock_.ApproximateNow() + kMinRttMs * 0.125;
-
- // Process all the packets in order so there aren't missing packets.
- uint64_t kFirstDecimatedPacket = 101;
- for (uint64_t i = 1; i < kFirstDecimatedPacket; ++i) {
- RecordPacketReceipt(i, clock_.ApproximateNow());
- MaybeUpdateAckTimeout(kInstigateAck, i);
- if (i % 2 == 0) {
- // Ack every 2 packets by default.
- CheckAckTimeout(clock_.ApproximateNow());
- } else {
- CheckAckTimeout(clock_.ApproximateNow() + kDelayedAckTime);
- }
- }
-
- RecordPacketReceipt(kFirstDecimatedPacket, clock_.ApproximateNow());
- MaybeUpdateAckTimeout(kInstigateAck, kFirstDecimatedPacket);
- CheckAckTimeout(ack_time);
-
- // The 10th received packet causes an ack to be sent.
- for (uint64_t i = 1; i < 10; ++i) {
- RecordPacketReceipt(kFirstDecimatedPacket + i, clock_.ApproximateNow());
- MaybeUpdateAckTimeout(kInstigateAck, kFirstDecimatedPacket + i);
- }
- CheckAckTimeout(clock_.ApproximateNow());
-}
-
-TEST_F(QuicReceivedPacketManagerTest,
- UpdateMaxAckDelayAndAckFrequencyFromAckFrequencyFrame) {
- EXPECT_FALSE(HasPendingAck());
-
- QuicAckFrequencyFrame frame;
- frame.max_ack_delay = QuicTime::Delta::FromMilliseconds(10);
- frame.packet_tolerance = 5;
- received_manager_.OnAckFrequencyFrame(frame);
-
- for (int i = 1; i <= 50; ++i) {
- RecordPacketReceipt(i, clock_.ApproximateNow());
- MaybeUpdateAckTimeout(kInstigateAck, i);
- if (i % frame.packet_tolerance == 0) {
- CheckAckTimeout(clock_.ApproximateNow());
- } else {
- CheckAckTimeout(clock_.ApproximateNow() + frame.max_ack_delay);
- }
- }
-}
-
-TEST_F(QuicReceivedPacketManagerTest,
- DisableOutOfOrderAckByIgnoreOrderFromAckFrequencyFrame) {
- EXPECT_FALSE(HasPendingAck());
-
- QuicAckFrequencyFrame frame;
- frame.max_ack_delay = kDelayedAckTime;
- frame.packet_tolerance = 2;
- frame.ignore_order = true;
- received_manager_.OnAckFrequencyFrame(frame);
-
- RecordPacketReceipt(4, clock_.ApproximateNow());
- MaybeUpdateAckTimeout(kInstigateAck, 4);
- CheckAckTimeout(clock_.ApproximateNow() + kDelayedAckTime);
- RecordPacketReceipt(5, clock_.ApproximateNow());
- MaybeUpdateAckTimeout(kInstigateAck, 5);
- // Immediate ack is sent as this is the 2nd packet of every two packets.
- CheckAckTimeout(clock_.ApproximateNow());
-
- RecordPacketReceipt(3, clock_.ApproximateNow());
- MaybeUpdateAckTimeout(kInstigateAck, 3);
- // Don't ack as ignore_order is set by AckFrequencyFrame.
- CheckAckTimeout(clock_.ApproximateNow() + kDelayedAckTime);
-
- RecordPacketReceipt(2, clock_.ApproximateNow());
- MaybeUpdateAckTimeout(kInstigateAck, 2);
- // Immediate ack is sent as this is the 2nd packet of every two packets.
- CheckAckTimeout(clock_.ApproximateNow());
-
- RecordPacketReceipt(1, clock_.ApproximateNow());
- MaybeUpdateAckTimeout(kInstigateAck, 1);
- // Don't ack as ignore_order is set by AckFrequencyFrame.
- CheckAckTimeout(clock_.ApproximateNow() + kDelayedAckTime);
-}
-
-TEST_F(QuicReceivedPacketManagerTest,
- DisableMissingPaketsAckByIgnoreOrderFromAckFrequencyFrame) {
- EXPECT_FALSE(HasPendingAck());
- QuicConfig config;
- config.SetConnectionOptionsToSend({kAFFE});
- received_manager_.SetFromConfig(config, Perspective::IS_CLIENT);
-
- QuicAckFrequencyFrame frame;
- frame.max_ack_delay = kDelayedAckTime;
- frame.packet_tolerance = 2;
- frame.ignore_order = true;
- received_manager_.OnAckFrequencyFrame(frame);
-
- RecordPacketReceipt(1, clock_.ApproximateNow());
- MaybeUpdateAckTimeout(kInstigateAck, 1);
- CheckAckTimeout(clock_.ApproximateNow() + kDelayedAckTime);
- RecordPacketReceipt(2, clock_.ApproximateNow());
- MaybeUpdateAckTimeout(kInstigateAck, 2);
- // Immediate ack is sent as this is the 2nd packet of every two packets.
- CheckAckTimeout(clock_.ApproximateNow());
-
- RecordPacketReceipt(4, clock_.ApproximateNow());
- MaybeUpdateAckTimeout(kInstigateAck, 4);
- // Don't ack even if packet 3 is newly missing as ignore_order is set by
- // AckFrequencyFrame.
- CheckAckTimeout(clock_.ApproximateNow() + kDelayedAckTime);
-
- RecordPacketReceipt(5, clock_.ApproximateNow());
- MaybeUpdateAckTimeout(kInstigateAck, 5);
- // Immediate ack is sent as this is the 2nd packet of every two packets.
- CheckAckTimeout(clock_.ApproximateNow());
-
- RecordPacketReceipt(7, clock_.ApproximateNow());
- MaybeUpdateAckTimeout(kInstigateAck, 7);
- // Don't ack even if packet 6 is newly missing as ignore_order is set by
- // AckFrequencyFrame.
- CheckAckTimeout(clock_.ApproximateNow() + kDelayedAckTime);
-}
-
-TEST_F(QuicReceivedPacketManagerTest,
- AckDecimationDisabledWhenAckFrequencyFrameIsReceived) {
- EXPECT_FALSE(HasPendingAck());
-
- QuicAckFrequencyFrame frame;
- frame.max_ack_delay = kDelayedAckTime;
- frame.packet_tolerance = 3;
- frame.ignore_order = true;
- received_manager_.OnAckFrequencyFrame(frame);
-
- // Process all the packets in order so there aren't missing packets.
- uint64_t kFirstDecimatedPacket = 101;
- uint64_t FiftyPacketsAfterAckDecimation = kFirstDecimatedPacket + 50;
- for (uint64_t i = 1; i < FiftyPacketsAfterAckDecimation; ++i) {
- RecordPacketReceipt(i, clock_.ApproximateNow());
- MaybeUpdateAckTimeout(kInstigateAck, i);
- if (i % 3 == 0) {
- // Ack every 3 packets as decimation is disabled.
- CheckAckTimeout(clock_.ApproximateNow());
- } else {
- // Ack at default delay as decimation is disabled.
- CheckAckTimeout(clock_.ApproximateNow() + kDelayedAckTime);
- }
- }
-}
-
-} // namespace
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_sent_packet_manager.cc b/chromium/net/third_party/quiche/src/quic/core/quic_sent_packet_manager.cc
deleted file mode 100644
index 55dbe057887..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_sent_packet_manager.cc
+++ /dev/null
@@ -1,1837 +0,0 @@
-// Copyright 2013 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 "quic/core/quic_sent_packet_manager.h"
-
-#include <algorithm>
-#include <cstddef>
-#include <string>
-
-#include "quic/core/congestion_control/general_loss_algorithm.h"
-#include "quic/core/congestion_control/pacing_sender.h"
-#include "quic/core/congestion_control/send_algorithm_interface.h"
-#include "quic/core/crypto/crypto_protocol.h"
-#include "quic/core/frames/quic_ack_frequency_frame.h"
-#include "quic/core/proto/cached_network_parameters_proto.h"
-#include "quic/core/quic_connection_stats.h"
-#include "quic/core/quic_constants.h"
-#include "quic/core/quic_packet_number.h"
-#include "quic/core/quic_transmission_info.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_flag_utils.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-#include "common/print_elements.h"
-
-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.
-static const int64_t kMinHandshakeTimeoutMs = 10;
-
-// Sends up to two tail loss probes before firing an RTO,
-// per draft RFC draft-dukkipati-tcpm-tcp-loss-probe.
-static const size_t kDefaultMaxTailLossProbes = 2;
-
-// 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;
-}
-
-// If pacing rate is accurate, > 2 burst token is not likely to help first ACK
-// to arrive earlier, and overly large burst token could cause incast packet
-// losses.
-static const uint32_t kConservativeUnpacedBurst = 2;
-
-} // namespace
-
-#define ENDPOINT \
- (unacked_packets_.perspective() == Perspective::IS_SERVER ? "Server: " \
- : "Client: ")
-
-QuicSentPacketManager::QuicSentPacketManager(
- Perspective perspective,
- const QuicClock* clock,
- QuicRandom* random,
- QuicConnectionStats* stats,
- CongestionControlType congestion_control_type)
- : unacked_packets_(perspective),
- clock_(clock),
- random_(random),
- stats_(stats),
- debug_delegate_(nullptr),
- 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_(GetQuicReloadableFlag(quic_default_on_pto)),
- 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_(0),
- ignore_pings_(false),
- ignore_ack_delay_(false) {
- SetSendAlgorithm(congestion_control_type);
- if (pto_enabled_) {
- QUIC_RELOADABLE_FLAG_COUNT_N(quic_default_on_pto, 1, 2);
- // TODO(fayang): change the default values when deprecating
- // quic_default_on_pto.
- first_pto_srtt_multiplier_ = 1.5;
- pto_rttvar_multiplier_ = 2;
- }
-}
-
-QuicSentPacketManager::~QuicSentPacketManager() {}
-
-void QuicSentPacketManager::SetFromConfig(const QuicConfig& config) {
- const Perspective perspective = unacked_packets_.perspective();
- if (config.HasReceivedInitialRoundTripTimeUs() &&
- config.ReceivedInitialRoundTripTimeUs() > 0) {
- if (!config.HasClientSentConnectionOption(kNRTT, perspective)) {
- SetInitialRtt(QuicTime::Delta::FromMicroseconds(
- config.ReceivedInitialRoundTripTimeUs()));
- }
- } else if (config.HasInitialRoundTripTimeUsToSend() &&
- config.GetInitialRoundTripTimeUsToSend() > 0) {
- SetInitialRtt(QuicTime::Delta::FromMicroseconds(
- config.GetInitialRoundTripTimeUsToSend()));
- }
- if (config.HasReceivedMaxAckDelayMs()) {
- peer_max_ack_delay_ =
- QuicTime::Delta::FromMilliseconds(config.ReceivedMaxAckDelayMs());
- }
- if (GetQuicReloadableFlag(quic_can_send_ack_frequency) &&
- perspective == Perspective::IS_SERVER) {
- if (config.HasReceivedMinAckDelayMs()) {
- peer_min_ack_delay_ =
- QuicTime::Delta::FromMilliseconds(config.ReceivedMinAckDelayMs());
- }
- if (config.HasClientSentConnectionOption(kAFF1, perspective)) {
- use_smoothed_rtt_in_ack_delay_ = true;
- }
- }
- if (config.HasClientSentConnectionOption(kMAD0, perspective)) {
- ignore_ack_delay_ = true;
- }
- if (config.HasClientSentConnectionOption(kMAD2, perspective)) {
- // Set the minimum to the alarm granularity.
- min_tlp_timeout_ = kAlarmGranularity;
- }
- if (config.HasClientSentConnectionOption(kMAD3, perspective)) {
- // Set the minimum to the alarm granularity.
- min_rto_timeout_ = kAlarmGranularity;
- }
-
- 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(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(kPDP4, perspective)) {
- num_ptos_for_path_degrading_ = 4;
- }
- if (config.HasClientRequestedIndependentOption(kPDP5, perspective)) {
- num_ptos_for_path_degrading_ = 5;
- }
- }
-
- // Configure congestion control.
- if (config.HasClientRequestedIndependentOption(kTBBR, perspective)) {
- SetSendAlgorithm(kBBR);
- }
- if (GetQuicReloadableFlag(quic_allow_client_enabled_bbr_v2) &&
- config.HasClientRequestedIndependentOption(kB2ON, perspective)) {
- QUIC_RELOADABLE_FLAG_COUNT(quic_allow_client_enabled_bbr_v2);
- SetSendAlgorithm(kBBRv2);
- }
-
- if (config.HasClientRequestedIndependentOption(kRENO, perspective)) {
- SetSendAlgorithm(kRenoBytes);
- } else if (config.HasClientRequestedIndependentOption(kBYTE, perspective) ||
- (GetQuicReloadableFlag(quic_default_to_bbr) &&
- config.HasClientRequestedIndependentOption(kQBIC, perspective))) {
- SetSendAlgorithm(kCubicBytes);
- }
-
- // Initial window.
- if (GetQuicReloadableFlag(quic_unified_iw_options)) {
- if (config.HasClientRequestedIndependentOption(kIW03, perspective)) {
- QUIC_RELOADABLE_FLAG_COUNT_N(quic_unified_iw_options, 1, 4);
- initial_congestion_window_ = 3;
- send_algorithm_->SetInitialCongestionWindowInPackets(3);
- }
- if (config.HasClientRequestedIndependentOption(kIW10, perspective)) {
- QUIC_RELOADABLE_FLAG_COUNT_N(quic_unified_iw_options, 2, 4);
- initial_congestion_window_ = 10;
- send_algorithm_->SetInitialCongestionWindowInPackets(10);
- }
- if (config.HasClientRequestedIndependentOption(kIW20, perspective)) {
- QUIC_RELOADABLE_FLAG_COUNT_N(quic_unified_iw_options, 3, 4);
- initial_congestion_window_ = 20;
- send_algorithm_->SetInitialCongestionWindowInPackets(20);
- }
- if (config.HasClientRequestedIndependentOption(kIW50, perspective)) {
- QUIC_RELOADABLE_FLAG_COUNT_N(quic_unified_iw_options, 4, 4);
- initial_congestion_window_ = 50;
- send_algorithm_->SetInitialCongestionWindowInPackets(50);
- }
- }
- if (config.HasClientRequestedIndependentOption(kBWS5, perspective)) {
- initial_congestion_window_ = 10;
- send_algorithm_->SetInitialCongestionWindowInPackets(10);
- }
-
- if (config.HasClientRequestedIndependentOption(kIGNP, perspective)) {
- ignore_pings_ = true;
- }
-
- 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);
- uber_loss_algorithm_.DisableAdaptiveReorderingThreshold();
- }
- if (config.HasClientRequestedIndependentOption(kILD1, perspective)) {
- uber_loss_algorithm_.SetReorderingShift(kDefaultLossDelayShift);
- uber_loss_algorithm_.DisableAdaptiveReorderingThreshold();
- }
- if (config.HasClientRequestedIndependentOption(kILD2, perspective)) {
- uber_loss_algorithm_.EnableAdaptiveReorderingThreshold();
- uber_loss_algorithm_.SetReorderingShift(kDefaultIetfLossDelayShift);
- }
- if (config.HasClientRequestedIndependentOption(kILD3, perspective)) {
- uber_loss_algorithm_.SetReorderingShift(kDefaultLossDelayShift);
- uber_loss_algorithm_.EnableAdaptiveReorderingThreshold();
- }
- if (config.HasClientRequestedIndependentOption(kILD4, perspective)) {
- uber_loss_algorithm_.SetReorderingShift(kDefaultLossDelayShift);
- uber_loss_algorithm_.EnableAdaptiveReorderingThreshold();
- uber_loss_algorithm_.EnableAdaptiveTimeThreshold();
- }
- if (config.HasClientRequestedIndependentOption(kRUNT, perspective)) {
- uber_loss_algorithm_.DisablePacketThresholdForRuntPackets();
- }
- if (config.HasClientSentConnectionOption(kCONH, perspective)) {
- conservative_handshake_retransmits_ = true;
- }
- send_algorithm_->SetFromConfig(config, perspective);
- loss_algorithm_->SetFromConfig(config, perspective);
-
- if (network_change_visitor_ != nullptr) {
- network_change_visitor_->OnCongestionChange();
- }
-
- if (debug_delegate_ != nullptr) {
- DebugDelegate::SendParameters parameters;
- parameters.congestion_control_type =
- send_algorithm_->GetCongestionControlType();
- parameters.use_pacing = using_pacing_;
- parameters.initial_congestion_window = initial_congestion_window_;
- debug_delegate_->OnConfigProcessed(parameters);
- }
-}
-
-void QuicSentPacketManager::ApplyConnectionOptions(
- const QuicTagVector& connection_options) {
- absl::optional<CongestionControlType> cc_type;
- if (ContainsQuicTag(connection_options, kB2ON)) {
- cc_type = kBBRv2;
- } else if (ContainsQuicTag(connection_options, kTBBR)) {
- cc_type = kBBR;
- } else if (ContainsQuicTag(connection_options, kRENO)) {
- cc_type = kRenoBytes;
- } else if (ContainsQuicTag(connection_options, kQBIC)) {
- cc_type = kCubicBytes;
- }
-
- if (cc_type.has_value()) {
- SetSendAlgorithm(*cc_type);
- }
-
- send_algorithm_->ApplyConnectionOptions(connection_options);
-}
-
-void QuicSentPacketManager::ResumeConnectionState(
- const CachedNetworkParameters& cached_network_params,
- bool max_bandwidth_resumption) {
- QuicBandwidth bandwidth = QuicBandwidth::FromBytesPerSecond(
- max_bandwidth_resumption
- ? cached_network_params.max_bandwidth_estimate_bytes_per_second()
- : cached_network_params.bandwidth_estimate_bytes_per_second());
- QuicTime::Delta rtt =
- QuicTime::Delta::FromMilliseconds(cached_network_params.min_rtt_ms());
- // This calls the old AdjustNetworkParameters interface, and fills certain
- // fields in SendAlgorithmInterface::NetworkParams
- // (e.g., quic_bbr_fix_pacing_rate) using GFE flags.
- AdjustNetworkParameters(SendAlgorithmInterface::NetworkParams(
- bandwidth, rtt, /*allow_cwnd_to_decrease = */ false));
-}
-
-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 (!rtt.IsZero()) {
- SetInitialRtt(rtt);
- }
- const QuicByteCount old_cwnd = send_algorithm_->GetCongestionWindow();
- if (GetQuicReloadableFlag(quic_conservative_bursts) && using_pacing_ &&
- !bandwidth.IsZero()) {
- QUIC_RELOADABLE_FLAG_COUNT(quic_conservative_bursts);
- pacing_sender_.SetBurstTokens(kConservativeUnpacedBurst);
- }
- send_algorithm_->AdjustNetworkParameters(params);
- if (debug_delegate_ != nullptr) {
- debug_delegate_->OnAdjustNetworkParameters(
- bandwidth, rtt.IsZero() ? rtt_stats_.MinOrInitialRtt() : rtt, old_cwnd,
- send_algorithm_->GetCongestionWindow());
- }
-}
-
-void QuicSentPacketManager::SetLossDetectionTuner(
- std::unique_ptr<LossDetectionTunerInterface> tuner) {
- uber_loss_algorithm_.SetLossDetectionTuner(std::move(tuner));
-}
-
-void QuicSentPacketManager::OnConfigNegotiated() {
- loss_algorithm_->OnConfigNegotiated();
-}
-
-void QuicSentPacketManager::OnConnectionClosed() {
- loss_algorithm_->OnConnectionClosed();
-}
-
-void QuicSentPacketManager::SetHandshakeConfirmed() {
- if (!handshake_finished_) {
- handshake_finished_ = true;
- NeuterHandshakePackets();
- }
-}
-
-void QuicSentPacketManager::PostProcessNewlyAckedPackets(
- QuicPacketNumber ack_packet_number,
- EncryptionLevel ack_decrypted_level,
- const QuicAckFrame& ack_frame,
- QuicTime ack_receive_time,
- bool rtt_updated,
- QuicByteCount prior_bytes_in_flight) {
- 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();
-
- sustained_bandwidth_recorder_.RecordEstimate(
- send_algorithm_->InRecovery(), send_algorithm_->InSlowStart(),
- send_algorithm_->BandwidthEstimate(), ack_receive_time, clock_->WallNow(),
- rtt_stats_.smoothed_rtt());
-
- // 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_ >
- 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;
- }
-
- if (debug_delegate_ != nullptr) {
- debug_delegate_->OnIncomingAck(
- ack_packet_number, ack_decrypted_level, ack_frame, ack_receive_time,
- LargestAcked(ack_frame), rtt_updated, GetLeastUnacked());
- }
- // Remove packets below least unacked from all_packets_acked_ and
- // last_ack_frame_.
- last_ack_frame_.packets.RemoveUpTo(unacked_packets_.GetLeastUnacked());
- last_ack_frame_.received_packet_times.clear();
-}
-
-void QuicSentPacketManager::MaybeInvokeCongestionEvent(
- bool rtt_updated,
- QuicByteCount prior_in_flight,
- QuicTime event_time) {
- if (!rtt_updated && packets_acked_.empty() && packets_lost_.empty()) {
- return;
- }
- const bool overshooting_detected =
- stats_->overshooting_detected_with_network_parameters_adjusted;
- if (using_pacing_) {
- pacing_sender_.OnCongestionEvent(rtt_updated, prior_in_flight, event_time,
- packets_acked_, packets_lost_);
- } else {
- send_algorithm_->OnCongestionEvent(rtt_updated, prior_in_flight, event_time,
- packets_acked_, packets_lost_);
- }
- if (debug_delegate_ != nullptr && !overshooting_detected &&
- stats_->overshooting_detected_with_network_parameters_adjusted) {
- debug_delegate_->OnOvershootingDetected();
- }
- packets_acked_.clear();
- packets_lost_.clear();
- if (network_change_visitor_ != nullptr) {
- network_change_visitor_->OnCongestionChange();
- }
-}
-
-void QuicSentPacketManager::MarkInitialPacketsForRetransmission() {
- if (unacked_packets_.empty()) {
- return;
- }
- QuicPacketNumber packet_number = unacked_packets_.GetLeastUnacked();
- QuicPacketNumber largest_sent_packet = unacked_packets_.largest_sent_packet();
- for (; packet_number <= largest_sent_packet; ++packet_number) {
- QuicTransmissionInfo* transmission_info =
- unacked_packets_.GetMutableTransmissionInfo(packet_number);
- if (transmission_info->encryption_level == ENCRYPTION_INITIAL) {
- if (transmission_info->in_flight) {
- unacked_packets_.RemoveFromInFlight(transmission_info);
- }
- if (unacked_packets_.HasRetransmittableFrames(*transmission_info)) {
- MarkForRetransmission(packet_number, ALL_INITIAL_RETRANSMISSION);
- }
- }
- }
-}
-
-void QuicSentPacketManager::MarkZeroRttPacketsForRetransmission() {
- if (unacked_packets_.empty()) {
- return;
- }
- QuicPacketNumber packet_number = unacked_packets_.GetLeastUnacked();
- QuicPacketNumber largest_sent_packet = unacked_packets_.largest_sent_packet();
- for (; packet_number <= largest_sent_packet; ++packet_number) {
- QuicTransmissionInfo* transmission_info =
- unacked_packets_.GetMutableTransmissionInfo(packet_number);
- if (transmission_info->encryption_level == ENCRYPTION_ZERO_RTT) {
- if (transmission_info->in_flight) {
- // Remove 0-RTT packets and packets of the wrong version from flight,
- // because neither can be processed by the peer.
- unacked_packets_.RemoveFromInFlight(transmission_info);
- }
- if (unacked_packets_.HasRetransmittableFrames(*transmission_info)) {
- MarkForRetransmission(packet_number, ALL_ZERO_RTT_RETRANSMISSION);
- }
- }
- }
-}
-
-void QuicSentPacketManager::NeuterUnencryptedPackets() {
- for (QuicPacketNumber packet_number :
- unacked_packets_.NeuterUnencryptedPackets()) {
- send_algorithm_->OnPacketNeutered(packet_number);
- }
- if (handshake_mode_disabled_) {
- consecutive_pto_count_ = 0;
- uber_loss_algorithm_.ResetLossDetection(INITIAL_DATA);
- }
-}
-
-void QuicSentPacketManager::NeuterHandshakePackets() {
- for (QuicPacketNumber packet_number :
- unacked_packets_.NeuterHandshakePackets()) {
- send_algorithm_->OnPacketNeutered(packet_number);
- }
- if (handshake_mode_disabled_) {
- consecutive_pto_count_ = 0;
- uber_loss_algorithm_.ResetLossDetection(HANDSHAKE_DATA);
- }
-}
-
-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;
-}
-
-QuicTime QuicSentPacketManager::GetEarliestPacketSentTimeForPto(
- PacketNumberSpace* packet_number_space) const {
- QUICHE_DCHECK(supports_multiple_packet_number_spaces());
- QuicTime earliest_sent_time = QuicTime::Zero();
- for (int8_t i = 0; i < NUM_PACKET_NUMBER_SPACES; ++i) {
- const QuicTime sent_time = unacked_packets_.GetLastInFlightPacketSentTime(
- static_cast<PacketNumberSpace>(i));
- if (!handshake_finished_ && i == APPLICATION_DATA) {
- // Do not arm PTO for application data until handshake gets confirmed.
- continue;
- }
- if (!sent_time.IsInitialized() || (earliest_sent_time.IsInitialized() &&
- earliest_sent_time <= sent_time)) {
- continue;
- }
- earliest_sent_time = sent_time;
- *packet_number_space = static_cast<PacketNumberSpace>(i);
- }
-
- return earliest_sent_time;
-}
-
-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.
- 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);
-
- HandleRetransmission(transmission_type, transmission_info);
-
- // Get the latest transmission_info here as it can be invalidated after
- // HandleRetransmission adding new sent packets into unacked_packets_.
- transmission_info =
- unacked_packets_.GetMutableTransmissionInfo(packet_number);
-
- // Update packet state according to transmission type.
- transmission_info->state =
- QuicUtils::RetransmissionTypeToPacketState(transmission_type);
-}
-
-void QuicSentPacketManager::HandleRetransmission(
- TransmissionType transmission_type,
- QuicTransmissionInfo* transmission_info) {
- if (ShouldForceRetransmission(transmission_type)) {
- // TODO(fayang): Consider to make RTO and PROBING retransmission
- // strategies be configurable by applications. Today, TLP, RTO and PROBING
- // retransmissions are handled similarly, i.e., always retranmist the
- // oldest outstanding data. This is not ideal in general because different
- // applications may want different strategies. For example, some
- // applications may want to use higher priority stream data for bandwidth
- // probing, and some applications want to consider RTO is an indication of
- // loss, etc.
- // transmission_info owning these frames may be deallocated after each
- // retransimission. Make a copy of retransmissible frames to prevent the
- // invalidation.
- unacked_packets_.RetransmitFrames(
- QuicFrames(transmission_info->retransmittable_frames),
- transmission_type);
- return;
- }
-
- unacked_packets_.NotifyFramesLost(*transmission_info, transmission_type);
- if (transmission_info->retransmittable_frames.empty()) {
- return;
- }
-
- if (transmission_type == LOSS_RETRANSMISSION) {
- // Record the first packet sent after loss, which allows to wait 1
- // more RTT before giving up on this lost packet.
- transmission_info->first_sent_after_loss =
- unacked_packets_.largest_sent_packet() + 1;
- } else {
- // Clear the recorded first packet sent after loss when version or
- // encryption changes.
- transmission_info->first_sent_after_loss.Clear();
- }
-}
-
-void QuicSentPacketManager::RecordOneSpuriousRetransmission(
- const QuicTransmissionInfo& info) {
- stats_->bytes_spuriously_retransmitted += info.bytes_sent;
- ++stats_->packets_spuriously_retransmitted;
- if (debug_delegate_ != nullptr) {
- debug_delegate_->OnSpuriousPacketRetransmission(info.transmission_type,
- info.bytes_sent);
- }
-}
-
-void QuicSentPacketManager::MarkPacketHandled(QuicPacketNumber packet_number,
- QuicTransmissionInfo* info,
- QuicTime ack_receive_time,
- QuicTime::Delta ack_delay_time,
- QuicTime receive_timestamp) {
- if (info->has_ack_frequency) {
- for (const auto& frame : info->retransmittable_frames) {
- if (frame.type == ACK_FREQUENCY_FRAME) {
- OnAckFrequencyFrameAcked(*frame.ack_frequency_frame);
- }
- }
- }
- // Try to aggregate acked stream frames if acked packet is not a
- // retransmission.
- if (info->transmission_type == NOT_RETRANSMISSION) {
- unacked_packets_.MaybeAggregateAckedStreamFrame(*info, ack_delay_time,
- receive_timestamp);
- } else {
- unacked_packets_.NotifyAggregatedStreamFrameAcked(ack_delay_time);
- const bool new_data_acked = unacked_packets_.NotifyFramesAcked(
- *info, ack_delay_time, receive_timestamp);
- if (!new_data_acked && info->transmission_type != NOT_RETRANSMISSION) {
- // Record as a spurious retransmission if this packet is a
- // retransmission and no new data gets acked.
- QUIC_DVLOG(1) << "Detect spurious retransmitted packet " << packet_number
- << " transmission type: " << info->transmission_type;
- RecordOneSpuriousRetransmission(*info);
- }
- }
- if (info->state == LOST) {
- // Record as a spurious loss as a packet previously declared lost gets
- // acked.
- const PacketNumberSpace packet_number_space =
- unacked_packets_.GetPacketNumberSpace(info->encryption_level);
- const QuicPacketNumber previous_largest_acked =
- supports_multiple_packet_number_spaces()
- ? unacked_packets_.GetLargestAckedOfPacketNumberSpace(
- packet_number_space)
- : unacked_packets_.largest_acked();
- QUIC_DVLOG(1) << "Packet " << packet_number
- << " was detected lost spuriously, "
- "previous_largest_acked: "
- << previous_largest_acked;
- loss_algorithm_->SpuriousLossDetected(unacked_packets_, rtt_stats_,
- ack_receive_time, packet_number,
- previous_largest_acked);
- ++stats_->packet_spuriously_detected_lost;
- }
-
- if (network_change_visitor_ != nullptr &&
- info->bytes_sent > largest_mtu_acked_) {
- largest_mtu_acked_ = info->bytes_sent;
- network_change_visitor_->OnPathMtuIncreased(largest_mtu_acked_);
- }
- unacked_packets_.RemoveFromInFlight(info);
- unacked_packets_.RemoveRetransmittability(info);
- info->state = ACKED;
-}
-
-bool QuicSentPacketManager::CanSendAckFrequency() const {
- return !peer_min_ack_delay_.IsInfinite() && handshake_finished_;
-}
-
-QuicAckFrequencyFrame QuicSentPacketManager::GetUpdatedAckFrequencyFrame()
- const {
- QuicAckFrequencyFrame frame;
- if (!CanSendAckFrequency()) {
- QUIC_BUG(quic_bug_10750_1)
- << "New AckFrequencyFrame is created while it shouldn't.";
- return frame;
- }
-
- QUIC_RELOADABLE_FLAG_COUNT_N(quic_can_send_ack_frequency, 1, 3);
- frame.packet_tolerance = kMaxRetransmittablePacketsBeforeAck;
- auto rtt = use_smoothed_rtt_in_ack_delay_ ? rtt_stats_.SmoothedOrInitialRtt()
- : rtt_stats_.MinOrInitialRtt();
- frame.max_ack_delay = rtt * kAckDecimationDelay;
- frame.max_ack_delay = std::max(frame.max_ack_delay, peer_min_ack_delay_);
- // TODO(haoyuewang) Remove this once kDefaultMinAckDelayTimeMs is updated to
- // 5 ms on the client side.
- frame.max_ack_delay =
- std::max(frame.max_ack_delay,
- QuicTime::Delta::FromMilliseconds(kDefaultMinAckDelayTimeMs));
- return frame;
-}
-
-bool QuicSentPacketManager::OnPacketSent(
- SerializedPacket* mutable_packet,
- QuicTime sent_time,
- TransmissionType transmission_type,
- HasRetransmittableData has_retransmittable_data,
- bool measure_rtt) {
- const SerializedPacket& packet = *mutable_packet;
- QuicPacketNumber packet_number = packet.packet_number;
- QUICHE_DCHECK_LE(FirstSendingPacketNumber(), packet_number);
- QUICHE_DCHECK(!unacked_packets_.IsUnacked(packet_number));
- QUIC_BUG_IF(quic_bug_10750_2, packet.encrypted_length == 0)
- << "Cannot send empty packets.";
- if (pending_timer_transmission_count_ > 0) {
- --pending_timer_transmission_count_;
- }
-
- bool in_flight = has_retransmittable_data == HAS_RETRANSMITTABLE_DATA;
- if (ignore_pings_ && mutable_packet->retransmittable_frames.size() == 1 &&
- mutable_packet->retransmittable_frames[0].type == PING_FRAME) {
- // Dot not use PING only packet for RTT measure or congestion control.
- in_flight = false;
- measure_rtt = false;
- }
- if (using_pacing_) {
- pacing_sender_.OnPacketSent(sent_time, unacked_packets_.bytes_in_flight(),
- packet_number, packet.encrypted_length,
- has_retransmittable_data);
- } else {
- send_algorithm_->OnPacketSent(sent_time, unacked_packets_.bytes_in_flight(),
- packet_number, packet.encrypted_length,
- has_retransmittable_data);
- }
-
- // Deallocate message data in QuicMessageFrame immediately after packet
- // sent.
- if (packet.has_message) {
- for (auto& frame : mutable_packet->retransmittable_frames) {
- if (frame.type == MESSAGE_FRAME) {
- frame.message_frame->message_data.clear();
- frame.message_frame->message_length = 0;
- }
- }
- }
-
- if (packet.has_ack_frequency) {
- for (const auto& frame : packet.retransmittable_frames) {
- if (frame.type == ACK_FREQUENCY_FRAME) {
- OnAckFrequencyFrameSent(*frame.ack_frequency_frame);
- }
- }
- }
- unacked_packets_.AddSentPacket(mutable_packet, transmission_type, sent_time,
- in_flight, measure_rtt);
- // Reset the retransmission timer anytime a pending packet is sent.
- return in_flight;
-}
-
-QuicSentPacketManager::RetransmissionTimeoutMode
-QuicSentPacketManager::OnRetransmissionTimeout() {
- QUICHE_DCHECK(unacked_packets_.HasInFlightPackets() ||
- (handshake_mode_disabled_ && !handshake_finished_));
- QUICHE_DCHECK_EQ(0u, pending_timer_transmission_count_);
- // Handshake retransmission, timer based loss detection, TLP, and RTO are
- // implemented with a single alarm. The handshake alarm is set when the
- // handshake has not completed, the loss alarm is set when the loss detection
- // algorithm says to, and the TLP and RTO alarms are set after that.
- // The TLP alarm is always set to run for under an RTO.
- switch (GetRetransmissionMode()) {
- case HANDSHAKE_MODE:
- QUICHE_DCHECK(!handshake_mode_disabled_);
- ++stats_->crypto_retransmit_count;
- RetransmitCryptoPackets();
- return HANDSHAKE_MODE;
- case LOSS_MODE: {
- ++stats_->loss_timeout_count;
- QuicByteCount prior_in_flight = unacked_packets_.bytes_in_flight();
- const QuicTime now = clock_->Now();
- InvokeLossDetection(now);
- 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;
- if (handshake_mode_disabled_ && !handshake_finished_) {
- ++stats_->crypto_retransmit_count;
- }
- ++consecutive_pto_count_;
- pending_timer_transmission_count_ = max_probe_packets_per_pto_;
- return PTO_MODE;
- }
- QUIC_BUG(quic_bug_10750_3)
- << "Unknown retransmission mode " << GetRetransmissionMode();
- return GetRetransmissionMode();
-}
-
-void QuicSentPacketManager::RetransmitCryptoPackets() {
- QUICHE_DCHECK_EQ(HANDSHAKE_MODE, GetRetransmissionMode());
- ++consecutive_crypto_retransmission_count_;
- bool packet_retransmitted = false;
- std::vector<QuicPacketNumber> crypto_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);
- // Only retransmit frames which are in flight, and therefore have been
- // sent.
- if (!transmission_info->in_flight ||
- transmission_info->state != OUTSTANDING ||
- !transmission_info->has_crypto_handshake ||
- !unacked_packets_.HasRetransmittableFrames(*transmission_info)) {
- continue;
- }
- packet_retransmitted = true;
- crypto_retransmissions.push_back(packet_number);
- ++pending_timer_transmission_count_;
- }
- }
- QUICHE_DCHECK(packet_retransmitted)
- << "No crypto packets found to retransmit.";
- for (QuicPacketNumber retransmission : crypto_retransmissions) {
- MarkForRetransmission(retransmission, HANDSHAKE_RETRANSMISSION);
- }
-}
-
-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();
- QuicPacketNumber largest_sent_packet =
- unacked_packets_.largest_sent_packet();
- for (; packet_number <= largest_sent_packet; ++packet_number) {
- QuicTransmissionInfo* transmission_info =
- unacked_packets_.GetMutableTransmissionInfo(packet_number);
- // Only retransmit frames which are in flight, and therefore have been
- // sent.
- if (!transmission_info->in_flight ||
- transmission_info->state != OUTSTANDING ||
- !unacked_packets_.HasRetransmittableFrames(*transmission_info)) {
- continue;
- }
- MarkForRetransmission(packet_number, type);
- return true;
- }
- }
- QUIC_DVLOG(1)
- << "No retransmittable packets, so RetransmitOldestPacket failed.";
- 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() {
- if (pending_timer_transmission_count_ == 0) {
- return;
- }
- PacketNumberSpace packet_number_space;
- if (supports_multiple_packet_number_spaces()) {
- // Find out the packet number space to send probe packets.
- if (!GetEarliestPacketSentTimeForPto(&packet_number_space)
- .IsInitialized()) {
- QUIC_BUG_IF(quic_earliest_sent_time_not_initialized,
- unacked_packets_.perspective() == Perspective::IS_SERVER)
- << "earliest_sent_time not initialized when trying to send PTO "
- "retransmissions";
- return;
- }
- }
- std::vector<QuicPacketNumber> probing_packets;
- if (!unacked_packets_.empty()) {
- QuicPacketNumber packet_number = unacked_packets_.GetLeastUnacked();
- QuicPacketNumber largest_sent_packet =
- unacked_packets_.largest_sent_packet();
- for (; packet_number <= largest_sent_packet; ++packet_number) {
- QuicTransmissionInfo* transmission_info =
- unacked_packets_.GetMutableTransmissionInfo(packet_number);
- if (transmission_info->state == OUTSTANDING &&
- unacked_packets_.HasRetransmittableFrames(*transmission_info) &&
- (!supports_multiple_packet_number_spaces() ||
- unacked_packets_.GetPacketNumberSpace(
- transmission_info->encryption_level) == packet_number_space)) {
- QUICHE_DCHECK(transmission_info->in_flight);
- probing_packets.push_back(packet_number);
- if (probing_packets.size() == pending_timer_transmission_count_) {
- break;
- }
- }
- }
- }
-
- for (QuicPacketNumber retransmission : probing_packets) {
- QUIC_DVLOG(1) << ENDPOINT << "Marking " << retransmission
- << " for probing retransmission";
- MarkForRetransmission(retransmission, PTO_RETRANSMISSION);
- }
- // 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_RELOADABLE_FLAG_COUNT_N(quic_default_on_pto, 2, 2);
- // Disable handshake mode.
- handshake_mode_disabled_ = true;
- return;
- }
- pto_enabled_ = true;
- 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(
- PacketNumberSpace space) {
- QUICHE_DCHECK(supports_multiple_packet_number_spaces());
- if (!unacked_packets_.GetLastInFlightPacketSentTime(space).IsInitialized()) {
- // No in flight data of space.
- return;
- }
- if (unacked_packets_.empty()) {
- return;
- }
- QuicPacketNumber packet_number = unacked_packets_.GetLeastUnacked();
- QuicPacketNumber largest_sent_packet = unacked_packets_.largest_sent_packet();
- for (; packet_number <= largest_sent_packet; ++packet_number) {
- QuicTransmissionInfo* transmission_info =
- unacked_packets_.GetMutableTransmissionInfo(packet_number);
- if (transmission_info->state == OUTSTANDING &&
- unacked_packets_.HasRetransmittableFrames(*transmission_info) &&
- unacked_packets_.GetPacketNumberSpace(
- transmission_info->encryption_level) == space) {
- QUICHE_DCHECK(transmission_info->in_flight);
- if (pending_timer_transmission_count_ == 0) {
- pending_timer_transmission_count_ = 1;
- }
- MarkForRetransmission(packet_number, PTO_RETRANSMISSION);
- return;
- }
- }
-}
-
-QuicSentPacketManager::RetransmissionTimeoutMode
-QuicSentPacketManager::GetRetransmissionMode() const {
- QUICHE_DCHECK(unacked_packets_.HasInFlightPackets() ||
- (handshake_mode_disabled_ && !handshake_finished_));
- if (!handshake_mode_disabled_ && !handshake_finished_ &&
- unacked_packets_.HasPendingCryptoPackets()) {
- return HANDSHAKE_MODE;
- }
- 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;
-}
-
-void QuicSentPacketManager::InvokeLossDetection(QuicTime time) {
- if (!packets_acked_.empty()) {
- QUICHE_DCHECK_LE(packets_acked_.front().packet_number,
- packets_acked_.back().packet_number);
- largest_newly_acked_ = packets_acked_.back().packet_number;
- }
- LossDetectionInterface::DetectionStats detection_stats =
- loss_algorithm_->DetectLosses(unacked_packets_, time, rtt_stats_,
- largest_newly_acked_, packets_acked_,
- &packets_lost_);
-
- if (detection_stats.sent_packets_max_sequence_reordering >
- stats_->sent_packets_max_sequence_reordering) {
- stats_->sent_packets_max_sequence_reordering =
- detection_stats.sent_packets_max_sequence_reordering;
- }
-
- stats_->sent_packets_num_borderline_time_reorderings +=
- detection_stats.sent_packets_num_borderline_time_reorderings;
-
- stats_->total_loss_detection_response_time +=
- detection_stats.total_loss_detection_response_time;
-
- for (const LostPacket& packet : packets_lost_) {
- QuicTransmissionInfo* info =
- unacked_packets_.GetMutableTransmissionInfo(packet.packet_number);
- ++stats_->packets_lost;
- if (debug_delegate_ != nullptr) {
- debug_delegate_->OnPacketLoss(packet.packet_number,
- info->encryption_level, LOSS_RETRANSMISSION,
- time);
- }
- unacked_packets_.RemoveFromInFlight(info);
-
- MarkForRetransmission(packet.packet_number, LOSS_RETRANSMISSION);
- }
-}
-
-bool QuicSentPacketManager::MaybeUpdateRTT(QuicPacketNumber largest_acked,
- QuicTime::Delta ack_delay_time,
- QuicTime ack_receive_time) {
- // We rely on ack_delay_time to compute an RTT estimate, so we
- // only update rtt when the largest observed gets acked and the acked packet
- // is not useless.
- if (!unacked_packets_.IsUnacked(largest_acked)) {
- return false;
- }
- // We calculate the RTT based on the highest ACKed packet number, the lower
- // packet numbers will include the ACK aggregation delay.
- const QuicTransmissionInfo& transmission_info =
- unacked_packets_.GetTransmissionInfo(largest_acked);
- // Ensure the packet has a valid sent time.
- if (transmission_info.sent_time == QuicTime::Zero()) {
- QUIC_BUG(quic_bug_10750_4)
- << "Acked packet has zero sent time, largest_acked:" << largest_acked;
- return false;
- }
- if (transmission_info.state == NOT_CONTRIBUTING_RTT) {
- return false;
- }
- if (transmission_info.sent_time > ack_receive_time) {
- QUIC_CODE_COUNT(quic_receive_acked_before_sending);
- }
-
- QuicTime::Delta send_delta = ack_receive_time - transmission_info.sent_time;
- const bool min_rtt_available = !rtt_stats_.min_rtt().IsZero();
- rtt_stats_.UpdateRtt(send_delta, ack_delay_time, ack_receive_time);
-
- if (!min_rtt_available && !rtt_stats_.min_rtt().IsZero()) {
- loss_algorithm_->OnMinRttAvailable();
- }
-
- return true;
-}
-
-QuicTime::Delta QuicSentPacketManager::TimeUntilSend(QuicTime now) const {
- // The TLP logic is entirely contained within QuicSentPacketManager, so the
- // send algorithm does not need to be consulted.
- if (pending_timer_transmission_count_ > 0) {
- return QuicTime::Delta::Zero();
- }
-
- if (using_pacing_) {
- return pacing_sender_.TimeUntilSend(now,
- unacked_packets_.bytes_in_flight());
- }
-
- return send_algorithm_->CanSend(unacked_packets_.bytes_in_flight())
- ? QuicTime::Delta::Zero()
- : QuicTime::Delta::Infinite();
-}
-
-const QuicTime QuicSentPacketManager::GetRetransmissionTime() const {
- if (!unacked_packets_.HasInFlightPackets() &&
- PeerCompletedAddressValidation()) {
- return QuicTime::Zero();
- }
- if (pending_timer_transmission_count_ > 0) {
- // Do not set the timer if there is any credit left.
- return QuicTime::Zero();
- }
- PacketNumberSpace packet_number_space;
- if (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() &&
- 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
- // in flight packet.
- return std::max(
- clock_->ApproximateNow(),
- std::max(unacked_packets_.GetFirstInFlightTransmissionInfo()
- ->sent_time +
- GetProbeTimeoutDelay(NUM_PACKET_NUMBER_SPACES),
- unacked_packets_.GetLastInFlightPacketSentTime() +
- first_pto_srtt_multiplier_ *
- rtt_stats_.SmoothedOrInitialRtt()));
- }
- // Ensure PTO never gets set to a time in the past.
- return std::max(clock_->ApproximateNow(),
- unacked_packets_.GetLastInFlightPacketSentTime() +
- GetProbeTimeoutDelay(NUM_PACKET_NUMBER_SPACES));
- }
-
- PacketNumberSpace packet_number_space = NUM_PACKET_NUMBER_SPACES;
- // earliest_right_edge is the earliest sent time of the last in flight
- // packet of all packet number spaces.
- QuicTime earliest_right_edge =
- GetEarliestPacketSentTimeForPto(&packet_number_space);
- if (!earliest_right_edge.IsInitialized()) {
- // 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 &&
- 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
- // 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_ *
- rtt_stats_.SmoothedOrInitialRtt()));
- }
- }
- return std::max(
- clock_->ApproximateNow(),
- earliest_right_edge + GetProbeTimeoutDelay(packet_number_space));
- }
- }
- QUICHE_DCHECK(false);
- return QuicTime::Zero();
-}
-
-const QuicTime::Delta QuicSentPacketManager::GetPathDegradingDelay() const {
- if (num_ptos_for_path_degrading_ > 0) {
- return num_ptos_for_path_degrading_ * GetPtoDelay();
- }
- return GetNConsecutiveRetransmissionTimeoutDelay(
- max_tail_loss_probes_ + kNumRetransmissionDelaysForPathDegradingDelay);
-}
-
-const QuicTime::Delta QuicSentPacketManager::GetNetworkBlackholeDelay(
- int8_t num_rtos_for_blackhole_detection) const {
- return GetNConsecutiveRetransmissionTimeoutDelay(
- max_tail_loss_probes_ + num_rtos_for_blackhole_detection);
-}
-
-QuicTime::Delta QuicSentPacketManager::GetMtuReductionDelay(
- int8_t num_rtos_for_blackhole_detection) const {
- return GetNetworkBlackholeDelay(num_rtos_for_blackhole_detection / 2);
-}
-
-const QuicTime::Delta QuicSentPacketManager::GetCryptoRetransmissionDelay()
- const {
- // This is equivalent to the TailLossProbeDelay, but slightly more aggressive
- // because crypto handshake messages don't incur a delayed ack time.
- QuicTime::Delta srtt = rtt_stats_.SmoothedOrInitialRtt();
- int64_t delay_ms;
- if (conservative_handshake_retransmits_) {
- // Using the delayed ack time directly could cause conservative handshake
- // retransmissions to actually be more aggressive than the default.
- delay_ms = std::max(peer_max_ack_delay_.ToMilliseconds(),
- static_cast<int64_t>(2 * srtt.ToMilliseconds()));
- } else {
- delay_ms = std::max(kMinHandshakeTimeoutMs,
- static_cast<int64_t>(1.5 * srtt.ToMilliseconds()));
- }
- return QuicTime::Delta::FromMilliseconds(
- 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)) *
- (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) +
- (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;
-}
-
-QuicTime::Delta QuicSentPacketManager::GetSlowStartDuration() const {
- if (send_algorithm_->GetCongestionControlType() == kBBR ||
- send_algorithm_->GetCongestionControlType() == kBBRv2) {
- return stats_->slowstart_duration.GetTotalElapsedTime(
- clock_->ApproximateNow());
- }
- return QuicTime::Delta::Infinite();
-}
-
-std::string QuicSentPacketManager::GetDebugState() const {
- return send_algorithm_->GetDebugState();
-}
-
-void QuicSentPacketManager::SetSendAlgorithm(
- CongestionControlType congestion_control_type) {
- if (send_algorithm_ &&
- send_algorithm_->GetCongestionControlType() == congestion_control_type) {
- return;
- }
-
- SetSendAlgorithm(SendAlgorithmInterface::Create(
- clock_, &rtt_stats_, &unacked_packets_, congestion_control_type, random_,
- stats_, initial_congestion_window_, send_algorithm_.get()));
-}
-
-void QuicSentPacketManager::SetSendAlgorithm(
- SendAlgorithmInterface* send_algorithm) {
- send_algorithm_.reset(send_algorithm);
- pacing_sender_.set_sender(send_algorithm);
-}
-
-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) {
- send_algorithm_->OnConnectionMigration();
- return nullptr;
- }
-
- std::unique_ptr<SendAlgorithmInterface> old_send_algorithm =
- std::move(send_algorithm_);
- SetSendAlgorithm(old_send_algorithm->GetCongestionControlType());
- // Treat all in flight packets sent to the old peer address as lost and
- // retransmit them.
- QuicPacketNumber packet_number = unacked_packets_.GetLeastUnacked();
- for (auto it = unacked_packets_.begin(); it != unacked_packets_.end();
- ++it, ++packet_number) {
- if (it->in_flight) {
- // Proactively retransmit any packet which is in flight on the old path.
- // As a result, these packets will not contribute to congestion control.
- unacked_packets_.RemoveFromInFlight(packet_number);
- // Retransmitting these packets with PATH_CHANGE_RETRANSMISSION will mark
- // them as useless, thus not contributing to RTT stats.
- if (unacked_packets_.HasRetransmittableFrames(packet_number)) {
- MarkForRetransmission(packet_number, PATH_RETRANSMISSION);
- QUICHE_DCHECK_EQ(it->state, NOT_CONTRIBUTING_RTT);
- }
- }
- it->state = NOT_CONTRIBUTING_RTT;
- }
- return old_send_algorithm;
-}
-
-void QuicSentPacketManager::OnAckFrameStart(QuicPacketNumber largest_acked,
- QuicTime::Delta ack_delay_time,
- QuicTime ack_receive_time) {
- QUICHE_DCHECK(packets_acked_.empty());
- QUICHE_DCHECK_LE(largest_acked, unacked_packets_.largest_sent_packet());
- if (GetQuicReloadableFlag(quic_ignore_peer_max_ack_delay_during_handshake) &&
- supports_multiple_packet_number_spaces() && !handshake_finished_) {
- QUIC_RELOADABLE_FLAG_COUNT(quic_ignore_peer_max_ack_delay_during_handshake);
- // Ignore peer_max_ack_delay and use received ack_delay during
- // handshake.
- } else {
- if (ack_delay_time > peer_max_ack_delay()) {
- ack_delay_time = peer_max_ack_delay();
- }
- if (ignore_ack_delay_) {
- ack_delay_time = QuicTime::Delta::Zero();
- }
- }
- rtt_updated_ =
- MaybeUpdateRTT(largest_acked, ack_delay_time, ack_receive_time);
- last_ack_frame_.ack_delay_time = ack_delay_time;
- acked_packets_iter_ = last_ack_frame_.packets.rbegin();
-}
-
-void QuicSentPacketManager::OnAckRange(QuicPacketNumber start,
- QuicPacketNumber end) {
- if (!last_ack_frame_.largest_acked.IsInitialized() ||
- end > last_ack_frame_.largest_acked + 1) {
- // Largest acked increases.
- unacked_packets_.IncreaseLargestAcked(end - 1);
- last_ack_frame_.largest_acked = end - 1;
- }
- // Drop ack ranges which ack packets below least_unacked.
- QuicPacketNumber least_unacked = unacked_packets_.GetLeastUnacked();
- if (least_unacked.IsInitialized() && end <= least_unacked) {
- return;
- }
- start = std::max(start, least_unacked);
- do {
- QuicPacketNumber newly_acked_start = start;
- if (acked_packets_iter_ != last_ack_frame_.packets.rend()) {
- newly_acked_start = std::max(start, acked_packets_iter_->max());
- }
- for (QuicPacketNumber acked = end - 1; acked >= newly_acked_start;
- --acked) {
- // Check if end is above the current range. If so add newly acked packets
- // in descending order.
- packets_acked_.push_back(AckedPacket(acked, 0, QuicTime::Zero()));
- if (acked == FirstSendingPacketNumber()) {
- break;
- }
- }
- if (acked_packets_iter_ == last_ack_frame_.packets.rend() ||
- start > acked_packets_iter_->min()) {
- // Finish adding all newly acked packets.
- return;
- }
- end = std::min(end, acked_packets_iter_->min());
- ++acked_packets_iter_;
- } while (start < end);
-}
-
-void QuicSentPacketManager::OnAckTimestamp(QuicPacketNumber packet_number,
- QuicTime timestamp) {
- last_ack_frame_.received_packet_times.push_back({packet_number, timestamp});
- for (AckedPacket& packet : packets_acked_) {
- if (packet.packet_number == packet_number) {
- packet.receive_timestamp = timestamp;
- return;
- }
- }
-}
-
-AckResult QuicSentPacketManager::OnAckFrameEnd(
- QuicTime ack_receive_time,
- QuicPacketNumber ack_packet_number,
- EncryptionLevel ack_decrypted_level) {
- QuicByteCount prior_bytes_in_flight = unacked_packets_.bytes_in_flight();
- // Reverse packets_acked_ so that it is in ascending order.
- std::reverse(packets_acked_.begin(), packets_acked_.end());
- for (AckedPacket& acked_packet : packets_acked_) {
- QuicTransmissionInfo* info =
- unacked_packets_.GetMutableTransmissionInfo(acked_packet.packet_number);
- if (!QuicUtils::IsAckable(info->state)) {
- if (info->state == ACKED) {
- QUIC_BUG(quic_bug_10750_5)
- << "Trying to ack an already acked packet: "
- << acked_packet.packet_number
- << ", last_ack_frame_: " << last_ack_frame_
- << ", least_unacked: " << unacked_packets_.GetLeastUnacked()
- << ", packets_acked_: " << quiche::PrintElements(packets_acked_);
- } else {
- QUIC_PEER_BUG(quic_peer_bug_10750_6)
- << "Received " << ack_decrypted_level
- << " ack for unackable packet: " << acked_packet.packet_number
- << " with state: "
- << QuicUtils::SentPacketStateToString(info->state);
- if (supports_multiple_packet_number_spaces()) {
- if (info->state == NEVER_SENT) {
- return UNSENT_PACKETS_ACKED;
- }
- return UNACKABLE_PACKETS_ACKED;
- }
- }
- continue;
- }
- QUIC_DVLOG(1) << ENDPOINT << "Got an " << ack_decrypted_level
- << " ack for packet " << acked_packet.packet_number
- << " , state: "
- << QuicUtils::SentPacketStateToString(info->state);
- const PacketNumberSpace packet_number_space =
- unacked_packets_.GetPacketNumberSpace(info->encryption_level);
- if (supports_multiple_packet_number_spaces() &&
- QuicUtils::GetPacketNumberSpace(ack_decrypted_level) !=
- packet_number_space) {
- return PACKETS_ACKED_IN_WRONG_PACKET_NUMBER_SPACE;
- }
- last_ack_frame_.packets.Add(acked_packet.packet_number);
- if (info->encryption_level == ENCRYPTION_HANDSHAKE) {
- handshake_packet_acked_ = true;
- } else if (info->encryption_level == ENCRYPTION_ZERO_RTT) {
- zero_rtt_packet_acked_ = true;
- } else if (info->encryption_level == ENCRYPTION_FORWARD_SECURE) {
- one_rtt_packet_acked_ = true;
- }
- largest_packet_peer_knows_is_acked_.UpdateMax(info->largest_acked);
- if (supports_multiple_packet_number_spaces()) {
- largest_packets_peer_knows_is_acked_[packet_number_space].UpdateMax(
- info->largest_acked);
- }
- // If data is associated with the most recent transmission of this
- // packet, then inform the caller.
- if (info->in_flight) {
- acked_packet.bytes_acked = info->bytes_sent;
- } else {
- // Unackable packets are skipped earlier.
- largest_newly_acked_ = acked_packet.packet_number;
- }
- unacked_packets_.MaybeUpdateLargestAckedOfPacketNumberSpace(
- packet_number_space, acked_packet.packet_number);
- MarkPacketHandled(acked_packet.packet_number, info, ack_receive_time,
- last_ack_frame_.ack_delay_time,
- acked_packet.receive_timestamp);
- }
- const bool acked_new_packet = !packets_acked_.empty();
- PostProcessNewlyAckedPackets(ack_packet_number, ack_decrypted_level,
- last_ack_frame_, ack_receive_time, rtt_updated_,
- prior_bytes_in_flight);
-
- return acked_new_packet ? PACKETS_NEWLY_ACKED : NO_PACKETS_NEWLY_ACKED;
-}
-
-void QuicSentPacketManager::SetDebugDelegate(DebugDelegate* debug_delegate) {
- debug_delegate_ = debug_delegate;
-}
-
-void QuicSentPacketManager::OnApplicationLimited() {
- if (using_pacing_) {
- pacing_sender_.OnApplicationLimited();
- }
- send_algorithm_->OnApplicationLimited(unacked_packets_.bytes_in_flight());
- if (debug_delegate_ != nullptr) {
- debug_delegate_->OnApplicationLimited();
- }
-}
-
-NextReleaseTimeResult QuicSentPacketManager::GetNextReleaseTime() const {
- if (!using_pacing_) {
- return {QuicTime::Zero(), false};
- }
-
- return pacing_sender_.GetNextReleaseTime();
-}
-
-void QuicSentPacketManager::SetInitialRtt(QuicTime::Delta rtt) {
- const QuicTime::Delta min_rtt =
- QuicTime::Delta::FromMicroseconds(kMinInitialRoundTripTimeUs);
- QuicTime::Delta max_rtt =
- QuicTime::Delta::FromMicroseconds(kMaxInitialRoundTripTimeUs);
- rtt_stats_.set_initial_rtt(std::max(min_rtt, std::min(max_rtt, rtt)));
-}
-
-void QuicSentPacketManager::EnableMultiplePacketNumberSpacesSupport() {
- EnableIetfPtoAndLossDetection();
- unacked_packets_.EnableMultiplePacketNumberSpacesSupport();
-}
-
-QuicPacketNumber QuicSentPacketManager::GetLargestAckedPacket(
- EncryptionLevel decrypted_packet_level) const {
- QUICHE_DCHECK(supports_multiple_packet_number_spaces());
- return unacked_packets_.GetLargestAckedOfPacketNumberSpace(
- QuicUtils::GetPacketNumberSpace(decrypted_packet_level));
-}
-
-QuicPacketNumber QuicSentPacketManager::GetLeastPacketAwaitedByPeer(
- EncryptionLevel encryption_level) const {
- QuicPacketNumber largest_acked;
- if (supports_multiple_packet_number_spaces()) {
- largest_acked = GetLargestAckedPacket(encryption_level);
- } else {
- largest_acked = GetLargestObserved();
- }
- if (!largest_acked.IsInitialized()) {
- // If no packets have been acked, return the first sent packet to ensure
- // we use a large enough packet number length.
- return FirstSendingPacketNumber();
- }
- QuicPacketNumber least_awaited = largest_acked + 1;
- QuicPacketNumber least_unacked = GetLeastUnacked();
- if (least_unacked.IsInitialized() && least_unacked < least_awaited) {
- least_awaited = least_unacked;
- }
- return least_awaited;
-}
-
-QuicPacketNumber QuicSentPacketManager::GetLargestPacketPeerKnowsIsAcked(
- EncryptionLevel decrypted_packet_level) const {
- QUICHE_DCHECK(supports_multiple_packet_number_spaces());
- return largest_packets_peer_knows_is_acked_[QuicUtils::GetPacketNumberSpace(
- decrypted_packet_level)];
-}
-
-QuicTime::Delta
-QuicSentPacketManager::GetNConsecutiveRetransmissionTimeoutDelay(
- int num_timeouts) const {
- 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_));
- 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)));
- total_delay = total_delay + num_tlps * tlp_delay;
- }
- if (num_timeouts == 0) {
- return total_delay;
- }
-
- 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_);
- total_delay = total_delay + ((1 << num_timeouts) - 1) * retransmission_delay;
- return total_delay;
-}
-
-bool QuicSentPacketManager::PeerCompletedAddressValidation() const {
- if (unacked_packets_.perspective() == Perspective::IS_SERVER ||
- !handshake_mode_disabled_) {
- return true;
- }
-
- // To avoid handshake deadlock due to anti-amplification limit, client needs
- // to set PTO timer until server successfully processed any HANDSHAKE packet.
- return handshake_finished_ || handshake_packet_acked_;
-}
-
-bool QuicSentPacketManager::IsLessThanThreePTOs(QuicTime::Delta timeout) const {
- return timeout < 3 * GetPtoDelay();
-}
-
-QuicTime::Delta QuicSentPacketManager::GetPtoDelay() const {
- return pto_enabled_ ? GetProbeTimeoutDelay(APPLICATION_DATA)
- : GetRetransmissionDelay();
-}
-
-void QuicSentPacketManager::OnAckFrequencyFrameSent(
- const QuicAckFrequencyFrame& ack_frequency_frame) {
- in_use_sent_ack_delays_.emplace_back(ack_frequency_frame.max_ack_delay,
- ack_frequency_frame.sequence_number);
- if (ack_frequency_frame.max_ack_delay > peer_max_ack_delay_) {
- peer_max_ack_delay_ = ack_frequency_frame.max_ack_delay;
- }
-}
-
-void QuicSentPacketManager::OnAckFrequencyFrameAcked(
- const QuicAckFrequencyFrame& ack_frequency_frame) {
- int stale_entry_count = 0;
- for (auto it = in_use_sent_ack_delays_.cbegin();
- it != in_use_sent_ack_delays_.cend(); ++it) {
- if (it->second < ack_frequency_frame.sequence_number) {
- ++stale_entry_count;
- } else {
- break;
- }
- }
- if (stale_entry_count > 0) {
- in_use_sent_ack_delays_.pop_front_n(stale_entry_count);
- }
- if (in_use_sent_ack_delays_.empty()) {
- QUIC_BUG(quic_bug_10750_7) << "in_use_sent_ack_delays_ is empty.";
- return;
- }
- peer_max_ack_delay_ = std::max_element(in_use_sent_ack_delays_.cbegin(),
- in_use_sent_ack_delays_.cend())
- ->first;
-}
-
-#undef ENDPOINT // undef for jumbo builds
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_sent_packet_manager.h b/chromium/net/third_party/quiche/src/quic/core/quic_sent_packet_manager.h
deleted file mode 100644
index dac8ccf08d8..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_sent_packet_manager.h
+++ /dev/null
@@ -1,769 +0,0 @@
-// Copyright 2013 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_SENT_PACKET_MANAGER_H_
-#define QUICHE_QUIC_CORE_QUIC_SENT_PACKET_MANAGER_H_
-
-#include <cstddef>
-#include <cstdint>
-#include <map>
-#include <memory>
-#include <set>
-#include <string>
-#include <utility>
-#include <vector>
-
-#include "quic/core/congestion_control/pacing_sender.h"
-#include "quic/core/congestion_control/rtt_stats.h"
-#include "quic/core/congestion_control/send_algorithm_interface.h"
-#include "quic/core/congestion_control/uber_loss_algorithm.h"
-#include "quic/core/proto/cached_network_parameters_proto.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_sustained_bandwidth_recorder.h"
-#include "quic/core/quic_time.h"
-#include "quic/core/quic_transmission_info.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_unacked_packet_map.h"
-#include "quic/platform/api/quic_containers.h"
-#include "quic/platform/api/quic_export.h"
-#include "common/quiche_circular_deque.h"
-
-namespace quic {
-
-namespace test {
-class QuicConnectionPeer;
-class QuicSentPacketManagerPeer;
-} // namespace test
-
-class QuicClock;
-class QuicConfig;
-struct QuicConnectionStats;
-
-// Class which tracks the set of packets sent on a QUIC connection and contains
-// a send algorithm to decide when to send new packets. It keeps track of any
-// retransmittable data associated with each packet. If a packet is
-// retransmitted, it will keep track of each version of a packet so that if a
-// previous transmission is acked, the data will not be retransmitted.
-class QUIC_EXPORT_PRIVATE QuicSentPacketManager {
- public:
- // Interface which gets callbacks from the QuicSentPacketManager at
- // interesting points. Implementations must not mutate the state of
- // the packet manager or connection as a result of these callbacks.
- class QUIC_EXPORT_PRIVATE DebugDelegate {
- public:
- struct QUIC_EXPORT_PRIVATE SendParameters {
- CongestionControlType congestion_control_type;
- bool use_pacing;
- QuicPacketCount initial_congestion_window;
- };
-
- virtual ~DebugDelegate() {}
-
- // Called when a spurious retransmission is detected.
- virtual void OnSpuriousPacketRetransmission(
- TransmissionType /*transmission_type*/,
- QuicByteCount /*byte_size*/) {}
-
- virtual void OnIncomingAck(QuicPacketNumber /*ack_packet_number*/,
- EncryptionLevel /*ack_decrypted_level*/,
- const QuicAckFrame& /*ack_frame*/,
- QuicTime /*ack_receive_time*/,
- QuicPacketNumber /*largest_observed*/,
- bool /*rtt_updated*/,
- QuicPacketNumber /*least_unacked_sent_packet*/) {
- }
-
- virtual void OnPacketLoss(QuicPacketNumber /*lost_packet_number*/,
- EncryptionLevel /*encryption_level*/,
- TransmissionType /*transmission_type*/,
- QuicTime /*detection_time*/) {}
-
- virtual void OnApplicationLimited() {}
-
- virtual void OnAdjustNetworkParameters(QuicBandwidth /*bandwidth*/,
- QuicTime::Delta /*rtt*/,
- QuicByteCount /*old_cwnd*/,
- QuicByteCount /*new_cwnd*/) {}
-
- virtual void OnAdjustBurstSize(int /*old_burst_size*/,
- int /*new_burst_size*/) {}
-
- virtual void OnOvershootingDetected() {}
-
- virtual void OnConfigProcessed(const SendParameters& /*parameters*/) {}
- };
-
- // Interface which gets callbacks from the QuicSentPacketManager when
- // network-related state changes. Implementations must not mutate the
- // state of the packet manager as a result of these callbacks.
- class QUIC_EXPORT_PRIVATE NetworkChangeVisitor {
- public:
- virtual ~NetworkChangeVisitor() {}
-
- // Called when congestion window or RTT may have changed.
- virtual void OnCongestionChange() = 0;
-
- // Called when the Path MTU may have increased.
- virtual void OnPathMtuIncreased(QuicPacketLength packet_size) = 0;
- };
-
- // 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
- // loss detection algorithm expects.
- LOSS_MODE,
- // A probe timeout. At least one probe packet must be sent when timer
- // expires.
- PTO_MODE,
- };
-
- QuicSentPacketManager(Perspective perspective,
- const QuicClock* clock,
- QuicRandom* random,
- QuicConnectionStats* stats,
- CongestionControlType congestion_control_type);
- QuicSentPacketManager(const QuicSentPacketManager&) = delete;
- QuicSentPacketManager& operator=(const QuicSentPacketManager&) = delete;
- virtual ~QuicSentPacketManager();
-
- virtual void SetFromConfig(const QuicConfig& config);
-
- void ReserveUnackedPacketsInitialCapacity(int initial_capacity) {
- unacked_packets_.ReserveInitialCapacity(initial_capacity);
- }
-
- void ApplyConnectionOptions(const QuicTagVector& connection_options);
-
- // Pass the CachedNetworkParameters to the send algorithm.
- void ResumeConnectionState(
- const CachedNetworkParameters& cached_network_params,
- bool max_bandwidth_resumption);
-
- void SetMaxPacingRate(QuicBandwidth max_pacing_rate) {
- pacing_sender_.set_max_pacing_rate(max_pacing_rate);
- }
-
- QuicBandwidth MaxPacingRate() const {
- return pacing_sender_.max_pacing_rate();
- }
-
- // Called to mark the handshake state complete, and all handshake packets are
- // neutered.
- // TODO(fayang): Rename this function to OnHandshakeComplete.
- void SetHandshakeConfirmed();
-
- // Requests retransmission of all unacked 0-RTT packets.
- // Only 0-RTT encrypted packets will be retransmitted. This can happen,
- // for example, when a CHLO has been rejected and the previously encrypted
- // data needs to be encrypted with a new key.
- void MarkZeroRttPacketsForRetransmission();
-
- // Request retransmission of all unacked INITIAL packets.
- void MarkInitialPacketsForRetransmission();
-
- // Notify the sent packet manager of an external network measurement or
- // prediction for either |bandwidth| or |rtt|; either can be empty.
- void AdjustNetworkParameters(
- const SendAlgorithmInterface::NetworkParams& params);
-
- void SetLossDetectionTuner(
- std::unique_ptr<LossDetectionTunerInterface> tuner);
- 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);
-
- // Removes the retransmittable frames from all unencrypted packets to ensure
- // they don't get retransmitted.
- void NeuterUnencryptedPackets();
-
- // Returns true if there's outstanding crypto data.
- bool HasUnackedCryptoPackets() const {
- return unacked_packets_.HasPendingCryptoPackets();
- }
-
- // Returns true if there are packets in flight expecting to be acknowledged.
- bool HasInFlightPackets() const {
- return unacked_packets_.HasInFlightPackets();
- }
-
- // Returns the smallest packet number of a serialized packet which has not
- // been acked by the peer.
- QuicPacketNumber GetLeastUnacked() const {
- return unacked_packets_.GetLeastUnacked();
- }
-
- // Called when we have sent bytes to the peer. This informs the manager both
- // the number of bytes sent and if they were retransmitted and if this packet
- // is used for rtt measuring. Returns true if the sender should reset the
- // retransmission timer.
- bool OnPacketSent(SerializedPacket* mutable_packet,
- QuicTime sent_time,
- TransmissionType transmission_type,
- HasRetransmittableData has_retransmittable_data,
- bool measure_rtt);
-
- bool CanSendAckFrequency() const;
-
- QuicAckFrequencyFrame GetUpdatedAckFrequencyFrame() const;
-
- // Called when the retransmission timer expires and returns the retransmission
- // mode.
- RetransmissionTimeoutMode OnRetransmissionTimeout();
-
- // Calculate the time until we can send the next packet to the wire.
- // Note 1: When kUnknownWaitTime is returned, there is no need to poll
- // TimeUntilSend again until we receive an OnIncomingAckFrame event.
- // Note 2: Send algorithms may or may not use |retransmit| in their
- // calculations.
- QuicTime::Delta TimeUntilSend(QuicTime now) const;
-
- // Returns the current delay for the retransmission timer, which may send
- // either a tail loss probe or do a full RTO. Returns QuicTime::Zero() if
- // there are no retransmittable packets.
- const QuicTime GetRetransmissionTime() const;
-
- // Returns the current delay for the path degrading timer, which is used to
- // notify the session that this connection is degrading.
- const QuicTime::Delta GetPathDegradingDelay() const;
-
- // Returns the current delay for detecting network blackhole.
- const QuicTime::Delta GetNetworkBlackholeDelay(
- int8_t num_rtos_for_blackhole_detection) const;
-
- // Returns the delay before reducing max packet size. This delay is guranteed
- // to be smaller than the network blackhole delay.
- QuicTime::Delta GetMtuReductionDelay(
- int8_t num_rtos_for_blackhole_detection) const;
-
- const RttStats* GetRttStats() const { return &rtt_stats_; }
-
- void SetRttStats(const RttStats& rtt_stats) {
- rtt_stats_.CloneFrom(rtt_stats);
- }
-
- // Returns the estimated bandwidth calculated by the congestion algorithm.
- QuicBandwidth BandwidthEstimate() const {
- return send_algorithm_->BandwidthEstimate();
- }
-
- const QuicSustainedBandwidthRecorder* SustainedBandwidthRecorder() const {
- return &sustained_bandwidth_recorder_;
- }
-
- // Returns the size of the current congestion window in number of
- // kDefaultTCPMSS-sized segments. Note, this is not the *available* window.
- // Some send algorithms may not use a congestion window and will return 0.
- QuicPacketCount GetCongestionWindowInTcpMss() const {
- return send_algorithm_->GetCongestionWindow() / kDefaultTCPMSS;
- }
-
- // Returns the number of packets of length |max_packet_length| which fit in
- // the current congestion window. More packets may end up in flight if the
- // congestion window has been recently reduced, of if non-full packets are
- // sent.
- QuicPacketCount EstimateMaxPacketsInFlight(
- QuicByteCount max_packet_length) const {
- return send_algorithm_->GetCongestionWindow() / max_packet_length;
- }
-
- // Returns the size of the current congestion window size in bytes.
- QuicByteCount GetCongestionWindowInBytes() const {
- return send_algorithm_->GetCongestionWindow();
- }
-
- QuicBandwidth GetPacingRate() const {
- return send_algorithm_->PacingRate(GetBytesInFlight());
- }
-
- // Returns the size of the slow start congestion window in nume of 1460 byte
- // TCP segments, aka ssthresh. Some send algorithms do not define a slow
- // start threshold and will return 0.
- QuicPacketCount GetSlowStartThresholdInTcpMss() const {
- return send_algorithm_->GetSlowStartThreshold() / kDefaultTCPMSS;
- }
-
- // Return the total time spent in slow start so far. If the sender is
- // currently in slow start, the return value will include the duration between
- // the most recent entry to slow start and now.
- //
- // Only implemented for BBR. Return QuicTime::Delta::Infinite() for other
- // congestion controllers.
- QuicTime::Delta GetSlowStartDuration() const;
-
- // Returns debugging information about the state of the congestion controller.
- std::string GetDebugState() const;
-
- // Returns the number of bytes that are considered in-flight, i.e. not lost or
- // acknowledged.
- QuicByteCount GetBytesInFlight() const {
- return unacked_packets_.bytes_in_flight();
- }
-
- // Called when peer address changes. Must be called IFF the address change is
- // not NAT rebinding. If reset_send_algorithm is true, switch to a new send
- // algorithm object and retransmit all the in-flight packets. Return the send
- // algorithm object used on the previous path.
- std::unique_ptr<SendAlgorithmInterface> OnConnectionMigration(
- bool reset_send_algorithm);
-
- // Called when an ack frame is initially parsed.
- void OnAckFrameStart(QuicPacketNumber largest_acked,
- QuicTime::Delta ack_delay_time,
- QuicTime ack_receive_time);
-
- // Called when ack range [start, end) is received. Populates packets_acked_
- // with newly acked packets.
- void OnAckRange(QuicPacketNumber start, QuicPacketNumber end);
-
- // Called when a timestamp is processed. If it's present in packets_acked_,
- // the timestamp field is set. Otherwise, the timestamp is ignored.
- void OnAckTimestamp(QuicPacketNumber packet_number, QuicTime timestamp);
-
- // Called when an ack frame is parsed completely.
- AckResult OnAckFrameEnd(QuicTime ack_receive_time,
- QuicPacketNumber ack_packet_number,
- EncryptionLevel ack_decrypted_level);
-
- void EnableMultiplePacketNumberSpacesSupport();
-
- void SetDebugDelegate(DebugDelegate* debug_delegate);
-
- void SetPacingAlarmGranularity(QuicTime::Delta alarm_granularity) {
- pacing_sender_.set_alarm_granularity(alarm_granularity);
- }
-
- QuicPacketNumber GetLargestObserved() const {
- return unacked_packets_.largest_acked();
- }
-
- QuicPacketNumber GetLargestAckedPacket(
- EncryptionLevel decrypted_packet_level) const;
-
- QuicPacketNumber GetLargestSentPacket() const {
- return unacked_packets_.largest_sent_packet();
- }
-
- // Returns the lowest of the largest acknowledged packet and the least
- // unacked packet. This is designed to be used when computing the packet
- // number length to send.
- QuicPacketNumber GetLeastPacketAwaitedByPeer(
- EncryptionLevel encryption_level) const;
-
- QuicPacketNumber GetLargestPacketPeerKnowsIsAcked(
- EncryptionLevel decrypted_packet_level) const;
-
- void SetNetworkChangeVisitor(NetworkChangeVisitor* visitor) {
- QUICHE_DCHECK(!network_change_visitor_);
- QUICHE_DCHECK(visitor);
- network_change_visitor_ = visitor;
- }
-
- 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();
-
- const SendAlgorithmInterface* GetSendAlgorithm() const {
- return send_algorithm_.get();
- }
-
- void SetSessionNotifier(SessionNotifierInterface* session_notifier) {
- unacked_packets_.SetSessionNotifier(session_notifier);
- }
-
- NextReleaseTimeResult GetNextReleaseTime() const;
-
- QuicPacketCount initial_congestion_window() const {
- return initial_congestion_window_;
- }
-
- QuicPacketNumber largest_packet_peer_knows_is_acked() const {
- QUICHE_DCHECK(!supports_multiple_packet_number_spaces());
- return largest_packet_peer_knows_is_acked_;
- }
-
- size_t pending_timer_transmission_count() const {
- return pending_timer_transmission_count_;
- }
-
- QuicTime::Delta peer_max_ack_delay() const { return peer_max_ack_delay_; }
-
- 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));
- peer_max_ack_delay_ = peer_max_ack_delay;
- }
-
- const QuicUnackedPacketMap& unacked_packets() const {
- return unacked_packets_;
- }
-
- const UberLossAlgorithm* uber_loss_algorithm() const {
- return &uber_loss_algorithm_;
- }
-
- // Sets the send algorithm to the given congestion control type and points the
- // pacing sender at |send_algorithm_|. Can be called any number of times.
- void SetSendAlgorithm(CongestionControlType congestion_control_type);
-
- // Sets the send algorithm to |send_algorithm| and points the pacing sender at
- // |send_algorithm_|. Takes ownership of |send_algorithm|. Can be called any
- // number of times.
- // 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();
-
- // 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);
-
- // Returns true if |timeout| is less than 3 * RTO/PTO delay.
- bool IsLessThanThreePTOs(QuicTime::Delta timeout) const;
-
- // Returns current PTO delay.
- QuicTime::Delta GetPtoDelay() const;
-
- bool supports_multiple_packet_number_spaces() const {
- 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_; }
-
- void OnUserAgentIdKnown() { loss_algorithm_->OnUserAgentIdKnown(); }
-
- // Gets the earliest in flight packet sent time to calculate PTO. Also
- // updates |packet_number_space| if a PTO timer should be armed.
- QuicTime GetEarliestPacketSentTimeForPto(
- PacketNumberSpace* packet_number_space) const;
-
- void set_num_ptos_for_path_degrading(int num_ptos_for_path_degrading) {
- num_ptos_for_path_degrading_ = num_ptos_for_path_degrading;
- }
-
- // Sets the initial RTT of the connection.
- void SetInitialRtt(QuicTime::Delta rtt);
-
- private:
- friend class test::QuicConnectionPeer;
- friend class test::QuicSentPacketManagerPeer;
-
- // Returns the current retransmission mode.
- RetransmissionTimeoutMode GetRetransmissionMode() const;
-
- // 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;
-
- // Update the RTT if the ack is for the largest acked packet number.
- // Returns true if the rtt was updated.
- bool MaybeUpdateRTT(QuicPacketNumber largest_acked,
- QuicTime::Delta ack_delay_time,
- QuicTime ack_receive_time);
-
- // Invokes the loss detection algorithm and loses and retransmits packets if
- // necessary.
- void InvokeLossDetection(QuicTime time);
-
- // Invokes OnCongestionEvent if |rtt_updated| is true, there are pending acks,
- // or pending losses. Clears pending acks and pending losses afterwards.
- // |prior_in_flight| is the number of bytes in flight before the losses or
- // acks, |event_time| is normally the timestamp of the ack packet which caused
- // the event, although it can be the time at which loss detection was
- // triggered.
- void MaybeInvokeCongestionEvent(bool rtt_updated,
- QuicByteCount prior_in_flight,
- QuicTime event_time);
-
- // Removes the retransmittability and in flight properties from the packet at
- // |info| due to receipt by the peer.
- void MarkPacketHandled(QuicPacketNumber packet_number,
- QuicTransmissionInfo* info,
- QuicTime ack_receive_time,
- QuicTime::Delta ack_delay_time,
- QuicTime receive_timestamp);
-
- // Request that |packet_number| be retransmitted after the other pending
- // retransmissions. Does not add it to the retransmissions if it's already
- // a pending retransmission. Do not reuse iterator of the underlying
- // unacked_packets_ after calling this function as it can be invalidated.
- void MarkForRetransmission(QuicPacketNumber packet_number,
- TransmissionType transmission_type);
-
- // Performs whatever work is need to retransmit the data correctly, either
- // by retransmitting the frames directly or by notifying that the frames
- // are lost.
- void HandleRetransmission(TransmissionType transmission_type,
- QuicTransmissionInfo* transmission_info);
-
- // Called after packets have been marked handled with last received ack frame.
- void PostProcessNewlyAckedPackets(QuicPacketNumber ack_packet_number,
- EncryptionLevel ack_decrypted_level,
- const QuicAckFrame& ack_frame,
- QuicTime ack_receive_time,
- bool rtt_updated,
- QuicByteCount prior_bytes_in_flight);
-
- // Notify observers that packet with QuicTransmissionInfo |info| is a spurious
- // retransmission. It is caller's responsibility to guarantee the packet with
- // QuicTransmissionInfo |info| is a spurious retransmission before calling
- // this function.
- void RecordOneSpuriousRetransmission(const QuicTransmissionInfo& info);
-
- // Called when handshake is confirmed to remove the retransmittable frames
- // from all packets of HANDSHAKE_DATA packet number space to ensure they don't
- // get retransmitted and will eventually be removed from unacked packets map.
- void NeuterHandshakePackets();
-
- // Indicates whether including peer_max_ack_delay_ when calculating PTO
- // timeout.
- bool ShouldAddMaxAckDelay(PacketNumberSpace space) const;
-
- // A helper function to return total delay of |num_timeouts| retransmission
- // timeout with TLP and RTO mode.
- QuicTime::Delta GetNConsecutiveRetransmissionTimeoutDelay(
- int num_timeouts) const;
-
- // Returns true if peer has finished address validation, such that
- // retransmission timer is not armed if there is no packets in flight.
- bool PeerCompletedAddressValidation() const;
-
- // Called when an AckFrequencyFrame is sent.
- void OnAckFrequencyFrameSent(
- const QuicAckFrequencyFrame& ack_frequency_frame);
-
- // Called when an AckFrequencyFrame is acked.
- void OnAckFrequencyFrameAcked(
- const QuicAckFrequencyFrame& ack_frequency_frame);
-
- // Newly serialized retransmittable packets are added to this map, which
- // contains owning pointers to any contained frames. If a packet is
- // retransmitted, this map will contain entries for both the old and the new
- // packet. The old packet's retransmittable frames entry will be nullptr,
- // while the new packet's entry will contain the frames to retransmit.
- // If the old packet is acked before the new packet, then the old entry will
- // be removed from the map and the new entry's retransmittable frames will be
- // set to nullptr.
- QuicUnackedPacketMap unacked_packets_;
-
- const QuicClock* clock_;
- QuicRandom* random_;
- QuicConnectionStats* stats_;
-
- DebugDelegate* debug_delegate_;
- NetworkChangeVisitor* network_change_visitor_;
- QuicPacketCount initial_congestion_window_;
- RttStats rtt_stats_;
- std::unique_ptr<SendAlgorithmInterface> send_algorithm_;
- // Not owned. Always points to |uber_loss_algorithm_| outside of tests.
- 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.
- 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_;
- LostPacketVector packets_lost_;
- // Largest newly acknowledged packet.
- QuicPacketNumber largest_newly_acked_;
- // Largest packet in bytes ever acknowledged.
- QuicPacketLength largest_mtu_acked_;
-
- // Replaces certain calls to |send_algorithm_| when |using_pacing_| is true.
- // Calls into |send_algorithm_| for the underlying congestion control.
- PacingSender pacing_sender_;
-
- // Indicates whether handshake is finished. This is purely used to determine
- // retransmission mode. DONOT use this to infer handshake state.
- bool handshake_finished_;
-
- // Records bandwidth from server to client in normal operation, over periods
- // of time with no loss events.
- QuicSustainedBandwidthRecorder sustained_bandwidth_recorder_;
-
- // The largest acked value that was sent in an ack, which has then been acked.
- QuicPacketNumber largest_packet_peer_knows_is_acked_;
- // The largest acked value that was sent in an ack, which has then been acked
- // for per packet number space. Only used when connection supports multiple
- // packet number spaces.
- QuicPacketNumber
- largest_packets_peer_knows_is_acked_[NUM_PACKET_NUMBER_SPACES];
-
- // The maximum ACK delay time that the peer might uses. Initialized to be the
- // same as local_max_ack_delay_, may be changed via transport parameter
- // negotiation or subsequently by AckFrequencyFrame.
- QuicTime::Delta peer_max_ack_delay_;
-
- // Peer sends min_ack_delay in TransportParameter to advertise its support for
- // AckFrequencyFrame.
- QuicTime::Delta peer_min_ack_delay_ = QuicTime::Delta::Infinite();
-
- // Use smoothed RTT for computing max_ack_delay in AckFrequency frame.
- bool use_smoothed_rtt_in_ack_delay_ = false;
-
- // The history of outstanding max_ack_delays sent to peer. Outstanding means
- // a max_ack_delay is sent as part of the last acked AckFrequencyFrame or
- // an unacked AckFrequencyFrame after that.
- quiche::QuicheCircularDeque<
- std::pair<QuicTime::Delta, /*sequence_number=*/uint64_t>>
- in_use_sent_ack_delays_;
-
- // Latest received ack frame.
- QuicAckFrame last_ack_frame_;
-
- // Record whether RTT gets updated by last largest acked..
- bool rtt_updated_;
-
- // A reverse iterator of last_ack_frame_.packets. This is reset in
- // 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_;
-
- // True if any 0-RTT packet gets acknowledged.
- bool zero_rtt_packet_acked_;
-
- // 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_;
-
- // If true, do not use PING only packets for RTT measurement or congestion
- // control.
- bool ignore_pings_;
-
- // Whether to ignore the ack_delay in received ACKs.
- bool ignore_ack_delay_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_QUIC_SENT_PACKET_MANAGER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_sent_packet_manager_test.cc b/chromium/net/third_party/quiche/src/quic/core/quic_sent_packet_manager_test.cc
deleted file mode 100644
index 1ce3da8e396..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_sent_packet_manager_test.cc
+++ /dev/null
@@ -1,4640 +0,0 @@
-// Copyright 2013 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 "quic/core/quic_sent_packet_manager.h"
-
-#include <memory>
-#include <utility>
-
-#include "absl/base/macros.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/frames/quic_ack_frequency_frame.h"
-#include "quic/core/quic_time.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_expect_bug.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/quic_config_peer.h"
-#include "quic/test_tools/quic_sent_packet_manager_peer.h"
-#include "quic/test_tools/quic_test_utils.h"
-
-using testing::_;
-using testing::AnyNumber;
-using testing::Invoke;
-using testing::InvokeWithoutArgs;
-using testing::IsEmpty;
-using testing::Not;
-using testing::Pointwise;
-using testing::Return;
-using testing::StrictMock;
-using testing::WithArgs;
-
-namespace quic {
-namespace test {
-namespace {
-// Default packet length.
-const uint32_t kDefaultLength = 1000;
-
-// Stream ID for data sent in CreatePacket().
-const QuicStreamId kStreamId = 7;
-
-// Matcher to check that the packet number matches the second argument.
-MATCHER(PacketNumberEq, "") {
- return std::get<0>(arg).packet_number == QuicPacketNumber(std::get<1>(arg));
-}
-
-class MockDebugDelegate : public QuicSentPacketManager::DebugDelegate {
- public:
- MOCK_METHOD(void,
- OnSpuriousPacketRetransmission,
- (TransmissionType transmission_type, QuicByteCount byte_size),
- (override));
- MOCK_METHOD(void,
- OnPacketLoss,
- (QuicPacketNumber lost_packet_number,
- EncryptionLevel encryption_level,
- TransmissionType transmission_type,
- QuicTime detection_time),
- (override));
-};
-
-class QuicSentPacketManagerTest : public QuicTest {
- public:
- void RetransmitCryptoPacket(uint64_t packet_number) {
- EXPECT_CALL(
- *send_algorithm_,
- OnPacketSent(_, BytesInFlight(), QuicPacketNumber(packet_number),
- kDefaultLength, HAS_RETRANSMITTABLE_DATA));
- SerializedPacket packet(CreatePacket(packet_number, false));
- packet.retransmittable_frames.push_back(
- QuicFrame(QuicStreamFrame(1, false, 0, absl::string_view())));
- packet.has_crypto_handshake = IS_HANDSHAKE;
- manager_.OnPacketSent(&packet, clock_.Now(), HANDSHAKE_RETRANSMISSION,
- HAS_RETRANSMITTABLE_DATA, true);
- }
-
- void RetransmitDataPacket(uint64_t packet_number,
- TransmissionType type,
- EncryptionLevel level) {
- EXPECT_CALL(
- *send_algorithm_,
- OnPacketSent(_, BytesInFlight(), QuicPacketNumber(packet_number),
- kDefaultLength, HAS_RETRANSMITTABLE_DATA));
- SerializedPacket packet(CreatePacket(packet_number, true));
- packet.encryption_level = level;
- manager_.OnPacketSent(&packet, clock_.Now(), type, HAS_RETRANSMITTABLE_DATA,
- true);
- }
-
- void RetransmitDataPacket(uint64_t packet_number, TransmissionType type) {
- RetransmitDataPacket(packet_number, type, ENCRYPTION_INITIAL);
- }
-
- protected:
- const CongestionControlType kInitialCongestionControlType = kCubicBytes;
- QuicSentPacketManagerTest()
- : manager_(Perspective::IS_SERVER,
- &clock_,
- QuicRandom::GetInstance(),
- &stats_,
- kInitialCongestionControlType),
- 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());
- manager_.SetSessionNotifier(&notifier_);
-
- EXPECT_CALL(*send_algorithm_, GetCongestionControlType())
- .WillRepeatedly(Return(kInitialCongestionControlType));
- EXPECT_CALL(*send_algorithm_, BandwidthEstimate())
- .Times(AnyNumber())
- .WillRepeatedly(Return(QuicBandwidth::Zero()));
- EXPECT_CALL(*send_algorithm_, InSlowStart()).Times(AnyNumber());
- EXPECT_CALL(*send_algorithm_, InRecovery()).Times(AnyNumber());
- EXPECT_CALL(*send_algorithm_, OnPacketNeutered(_)).Times(AnyNumber());
- EXPECT_CALL(*network_change_visitor_, OnPathMtuIncreased(1000))
- .Times(AnyNumber());
- EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(true));
- EXPECT_CALL(notifier_, HasUnackedCryptoData())
- .WillRepeatedly(Return(false));
- EXPECT_CALL(notifier_, OnStreamFrameRetransmitted(_)).Times(AnyNumber());
- EXPECT_CALL(notifier_, OnFrameAcked(_, _, _)).WillRepeatedly(Return(true));
- }
-
- ~QuicSentPacketManagerTest() override {}
-
- QuicByteCount BytesInFlight() { return manager_.GetBytesInFlight(); }
- void VerifyUnackedPackets(uint64_t* packets, size_t num_packets) {
- if (num_packets == 0) {
- EXPECT_TRUE(manager_.unacked_packets().empty());
- EXPECT_EQ(0u, QuicSentPacketManagerPeer::GetNumRetransmittablePackets(
- &manager_));
- return;
- }
-
- EXPECT_FALSE(manager_.unacked_packets().empty());
- EXPECT_EQ(QuicPacketNumber(packets[0]), manager_.GetLeastUnacked());
- for (size_t i = 0; i < num_packets; ++i) {
- EXPECT_TRUE(
- manager_.unacked_packets().IsUnacked(QuicPacketNumber(packets[i])))
- << packets[i];
- }
- }
-
- void VerifyRetransmittablePackets(uint64_t* packets, size_t num_packets) {
- EXPECT_EQ(
- num_packets,
- QuicSentPacketManagerPeer::GetNumRetransmittablePackets(&manager_));
- for (size_t i = 0; i < num_packets; ++i) {
- EXPECT_TRUE(QuicSentPacketManagerPeer::HasRetransmittableFrames(
- &manager_, packets[i]))
- << " packets[" << i << "]:" << packets[i];
- }
- }
-
- void ExpectAck(uint64_t largest_observed) {
- EXPECT_CALL(
- *send_algorithm_,
- // Ensure the AckedPacketVector argument contains largest_observed.
- OnCongestionEvent(true, _, _,
- Pointwise(PacketNumberEq(), {largest_observed}),
- IsEmpty()));
- EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
- }
-
- void ExpectUpdatedRtt(uint64_t /*largest_observed*/) {
- EXPECT_CALL(*send_algorithm_,
- OnCongestionEvent(true, _, _, IsEmpty(), IsEmpty()));
- EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
- }
-
- void ExpectAckAndLoss(bool rtt_updated,
- uint64_t largest_observed,
- uint64_t lost_packet) {
- EXPECT_CALL(
- *send_algorithm_,
- OnCongestionEvent(rtt_updated, _, _,
- Pointwise(PacketNumberEq(), {largest_observed}),
- Pointwise(PacketNumberEq(), {lost_packet})));
- EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
- }
-
- // |packets_acked| and |packets_lost| should be in packet number order.
- void ExpectAcksAndLosses(bool rtt_updated,
- uint64_t* packets_acked,
- size_t num_packets_acked,
- uint64_t* packets_lost,
- size_t num_packets_lost) {
- std::vector<QuicPacketNumber> ack_vector;
- for (size_t i = 0; i < num_packets_acked; ++i) {
- ack_vector.push_back(QuicPacketNumber(packets_acked[i]));
- }
- std::vector<QuicPacketNumber> lost_vector;
- for (size_t i = 0; i < num_packets_lost; ++i) {
- lost_vector.push_back(QuicPacketNumber(packets_lost[i]));
- }
- EXPECT_CALL(*send_algorithm_,
- OnCongestionEvent(rtt_updated, _, _,
- Pointwise(PacketNumberEq(), ack_vector),
- Pointwise(PacketNumberEq(), lost_vector)));
- EXPECT_CALL(*network_change_visitor_, OnCongestionChange())
- .Times(AnyNumber());
- }
-
- void RetransmitAndSendPacket(uint64_t old_packet_number,
- uint64_t new_packet_number) {
- RetransmitAndSendPacket(old_packet_number, new_packet_number,
- TLP_RETRANSMISSION);
- }
-
- void RetransmitAndSendPacket(uint64_t old_packet_number,
- uint64_t new_packet_number,
- TransmissionType transmission_type) {
- bool is_lost = false;
- if (transmission_type == HANDSHAKE_RETRANSMISSION ||
- transmission_type == TLP_RETRANSMISSION ||
- transmission_type == RTO_RETRANSMISSION ||
- transmission_type == PROBING_RETRANSMISSION) {
- EXPECT_CALL(notifier_, RetransmitFrames(_, _))
- .WillOnce(WithArgs<1>(
- Invoke([this, new_packet_number](TransmissionType type) {
- RetransmitDataPacket(new_packet_number, type);
- })));
- } else {
- EXPECT_CALL(notifier_, OnFrameLost(_)).Times(1);
- is_lost = true;
- }
- QuicSentPacketManagerPeer::MarkForRetransmission(
- &manager_, old_packet_number, transmission_type);
- if (!is_lost) {
- return;
- }
- EXPECT_CALL(
- *send_algorithm_,
- OnPacketSent(_, BytesInFlight(), QuicPacketNumber(new_packet_number),
- kDefaultLength, HAS_RETRANSMITTABLE_DATA));
- SerializedPacket packet(CreatePacket(new_packet_number, true));
- manager_.OnPacketSent(&packet, clock_.Now(), transmission_type,
- HAS_RETRANSMITTABLE_DATA, true);
- }
-
- SerializedPacket CreateDataPacket(uint64_t packet_number) {
- return CreatePacket(packet_number, true);
- }
-
- SerializedPacket CreatePacket(uint64_t packet_number, bool retransmittable) {
- SerializedPacket packet(QuicPacketNumber(packet_number),
- PACKET_4BYTE_PACKET_NUMBER, nullptr, kDefaultLength,
- false, false);
- if (retransmittable) {
- packet.retransmittable_frames.push_back(
- QuicFrame(QuicStreamFrame(kStreamId, false, 0, absl::string_view())));
- }
- return packet;
- }
-
- SerializedPacket CreatePingPacket(uint64_t packet_number) {
- SerializedPacket packet(QuicPacketNumber(packet_number),
- PACKET_4BYTE_PACKET_NUMBER, nullptr, kDefaultLength,
- false, false);
- packet.retransmittable_frames.push_back(QuicFrame(QuicPingFrame()));
- return packet;
- }
-
- void SendDataPacket(uint64_t packet_number) {
- SendDataPacket(packet_number, ENCRYPTION_INITIAL);
- }
-
- void SendDataPacket(uint64_t packet_number,
- EncryptionLevel encryption_level) {
- EXPECT_CALL(*send_algorithm_,
- OnPacketSent(_, BytesInFlight(),
- QuicPacketNumber(packet_number), _, _));
- SerializedPacket packet(CreateDataPacket(packet_number));
- packet.encryption_level = encryption_level;
- manager_.OnPacketSent(&packet, clock_.Now(), NOT_RETRANSMISSION,
- HAS_RETRANSMITTABLE_DATA, true);
- }
-
- void SendPingPacket(uint64_t packet_number,
- EncryptionLevel encryption_level) {
- EXPECT_CALL(*send_algorithm_,
- OnPacketSent(_, BytesInFlight(),
- QuicPacketNumber(packet_number), _, _));
- SerializedPacket packet(CreatePingPacket(packet_number));
- packet.encryption_level = encryption_level;
- manager_.OnPacketSent(&packet, clock_.Now(), NOT_RETRANSMISSION,
- HAS_RETRANSMITTABLE_DATA, true);
- }
-
- void SendCryptoPacket(uint64_t packet_number) {
- EXPECT_CALL(
- *send_algorithm_,
- OnPacketSent(_, BytesInFlight(), QuicPacketNumber(packet_number),
- kDefaultLength, HAS_RETRANSMITTABLE_DATA));
- SerializedPacket packet(CreatePacket(packet_number, false));
- packet.retransmittable_frames.push_back(
- QuicFrame(QuicStreamFrame(1, false, 0, absl::string_view())));
- packet.has_crypto_handshake = IS_HANDSHAKE;
- manager_.OnPacketSent(&packet, clock_.Now(), NOT_RETRANSMISSION,
- HAS_RETRANSMITTABLE_DATA, true);
- EXPECT_CALL(notifier_, HasUnackedCryptoData()).WillRepeatedly(Return(true));
- }
-
- void SendAckPacket(uint64_t packet_number, uint64_t largest_acked) {
- SendAckPacket(packet_number, largest_acked, ENCRYPTION_INITIAL);
- }
-
- void SendAckPacket(uint64_t packet_number,
- uint64_t largest_acked,
- EncryptionLevel level) {
- EXPECT_CALL(
- *send_algorithm_,
- OnPacketSent(_, BytesInFlight(), QuicPacketNumber(packet_number),
- kDefaultLength, NO_RETRANSMITTABLE_DATA));
- SerializedPacket packet(CreatePacket(packet_number, false));
- packet.largest_acked = QuicPacketNumber(largest_acked);
- packet.encryption_level = level;
- manager_.OnPacketSent(&packet, clock_.Now(), NOT_RETRANSMISSION,
- 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 (GetQuicReloadableFlag(quic_default_on_pto) ||
- manager_.handshake_mode_disabled()) {
- return 2;
- }
- return 4;
- }
-
- SimpleBufferAllocator allocator_;
- QuicSentPacketManager manager_;
- MockClock clock_;
- QuicConnectionStats stats_;
- MockSendAlgorithm* send_algorithm_;
- std::unique_ptr<MockNetworkChangeVisitor> network_change_visitor_;
- StrictMock<MockSessionNotifier> notifier_;
-};
-
-TEST_F(QuicSentPacketManagerTest, IsUnacked) {
- VerifyUnackedPackets(nullptr, 0);
- SendDataPacket(1);
-
- uint64_t unacked[] = {1};
- VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked));
- uint64_t retransmittable[] = {1};
- VerifyRetransmittablePackets(retransmittable,
- ABSL_ARRAYSIZE(retransmittable));
-}
-
-TEST_F(QuicSentPacketManagerTest, IsUnAckedRetransmit) {
- SendDataPacket(1);
- RetransmitAndSendPacket(1, 2);
-
- EXPECT_TRUE(QuicSentPacketManagerPeer::IsRetransmission(&manager_, 2));
- uint64_t unacked[] = {1, 2};
- VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked));
- std::vector<uint64_t> retransmittable = {1, 2};
- VerifyRetransmittablePackets(&retransmittable[0], retransmittable.size());
-}
-
-TEST_F(QuicSentPacketManagerTest, RetransmitThenAck) {
- SendDataPacket(1);
- RetransmitAndSendPacket(1, 2);
-
- // Ack 2 but not 1.
- ExpectAck(2);
- manager_.OnAckFrameStart(QuicPacketNumber(2), QuicTime::Delta::Infinite(),
- clock_.Now());
- manager_.OnAckRange(QuicPacketNumber(2), QuicPacketNumber(3));
- EXPECT_EQ(PACKETS_NEWLY_ACKED,
- manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
- ENCRYPTION_INITIAL));
- EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(false));
- // Packet 1 is unacked, pending, but not retransmittable.
- uint64_t unacked[] = {1};
- VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked));
- EXPECT_TRUE(manager_.HasInFlightPackets());
- VerifyRetransmittablePackets(nullptr, 0);
-}
-
-TEST_F(QuicSentPacketManagerTest, RetransmitThenAckBeforeSend) {
- SendDataPacket(1);
- EXPECT_CALL(notifier_, RetransmitFrames(_, _))
- .WillOnce(WithArgs<1>(Invoke(
- [this](TransmissionType type) { RetransmitDataPacket(2, type); })));
- QuicSentPacketManagerPeer::MarkForRetransmission(&manager_, 1,
- TLP_RETRANSMISSION);
- // Ack 1.
- ExpectAck(1);
- 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));
-
- EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(false));
- uint64_t unacked[] = {2};
- VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked));
- // We do not know packet 2 is a spurious retransmission until it gets acked.
- VerifyRetransmittablePackets(nullptr, 0);
- EXPECT_EQ(0u, stats_.packets_spuriously_retransmitted);
-}
-
-TEST_F(QuicSentPacketManagerTest, RetransmitThenStopRetransmittingBeforeSend) {
- SendDataPacket(1);
- EXPECT_CALL(notifier_, RetransmitFrames(_, _));
- QuicSentPacketManagerPeer::MarkForRetransmission(&manager_, 1,
- TLP_RETRANSMISSION);
-
- EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(false));
-
- uint64_t unacked[] = {1};
- VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked));
- VerifyRetransmittablePackets(nullptr, 0);
- EXPECT_EQ(0u, stats_.packets_spuriously_retransmitted);
-}
-
-TEST_F(QuicSentPacketManagerTest, RetransmitThenAckPrevious) {
- SendDataPacket(1);
- RetransmitAndSendPacket(1, 2);
- QuicTime::Delta rtt = QuicTime::Delta::FromMilliseconds(15);
- clock_.AdvanceTime(rtt);
-
- // Ack 1 but not 2.
- ExpectAck(1);
- 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));
- EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(false));
- // 2 remains unacked, but no packets have retransmittable data.
- uint64_t unacked[] = {2};
- VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked));
- EXPECT_TRUE(manager_.HasInFlightPackets());
- VerifyRetransmittablePackets(nullptr, 0);
- // Ack 2 causes 2 be considered as spurious retransmission.
- EXPECT_CALL(notifier_, OnFrameAcked(_, _, _)).WillOnce(Return(false));
- ExpectAck(2);
- 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(2),
- ENCRYPTION_INITIAL));
-
- EXPECT_EQ(1u, stats_.packets_spuriously_retransmitted);
-}
-
-TEST_F(QuicSentPacketManagerTest, RetransmitThenAckPreviousThenNackRetransmit) {
- SendDataPacket(1);
- RetransmitAndSendPacket(1, 2);
- QuicTime::Delta rtt = QuicTime::Delta::FromMilliseconds(15);
- clock_.AdvanceTime(rtt);
-
- // First, ACK packet 1 which makes packet 2 non-retransmittable.
- ExpectAck(1);
- 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));
-
- SendDataPacket(3);
- SendDataPacket(4);
- SendDataPacket(5);
- clock_.AdvanceTime(rtt);
-
- // Next, NACK packet 2 three times.
- EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(false));
- EXPECT_CALL(notifier_, OnFrameLost(_)).Times(1);
- ExpectAckAndLoss(true, 3, 2);
- manager_.OnAckFrameStart(QuicPacketNumber(3), QuicTime::Delta::Infinite(),
- clock_.Now());
- manager_.OnAckRange(QuicPacketNumber(3), QuicPacketNumber(4));
- manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
- EXPECT_EQ(PACKETS_NEWLY_ACKED,
- manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(2),
- ENCRYPTION_INITIAL));
-
- ExpectAck(4);
- 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(3),
- ENCRYPTION_INITIAL));
-
- ExpectAck(5);
- manager_.OnAckFrameStart(QuicPacketNumber(5), QuicTime::Delta::Infinite(),
- clock_.Now());
- manager_.OnAckRange(QuicPacketNumber(3), QuicPacketNumber(6));
- manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
- EXPECT_EQ(PACKETS_NEWLY_ACKED,
- manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(4),
- ENCRYPTION_INITIAL));
-
- uint64_t unacked[] = {2};
- VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked));
- EXPECT_FALSE(manager_.HasInFlightPackets());
- VerifyRetransmittablePackets(nullptr, 0);
-
- // Verify that the retransmission alarm would not fire,
- // since there is no retransmittable data outstanding.
- EXPECT_EQ(QuicTime::Zero(), manager_.GetRetransmissionTime());
-}
-
-TEST_F(QuicSentPacketManagerTest,
- DISABLED_RetransmitTwiceThenAckPreviousBeforeSend) {
- SendDataPacket(1);
- RetransmitAndSendPacket(1, 2);
-
- // Fire the RTO, which will mark 2 for retransmission (but will not send it).
- EXPECT_CALL(*send_algorithm_, OnRetransmissionTimeout(true));
- EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
- manager_.OnRetransmissionTimeout();
-
- // Ack 1 but not 2, before 2 is able to be sent.
- // Since 1 has been retransmitted, it has already been lost, and so the
- // send algorithm is not informed that it has been ACK'd.
- ExpectUpdatedRtt(1);
- 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));
-
- // Since 2 was marked for retransmit, when 1 is acked, 2 is kept for RTT.
- uint64_t unacked[] = {2};
- VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked));
- EXPECT_FALSE(manager_.HasInFlightPackets());
- VerifyRetransmittablePackets(nullptr, 0);
-
- // Verify that the retransmission alarm would not fire,
- // since there is no retransmittable data outstanding.
- EXPECT_EQ(QuicTime::Zero(), manager_.GetRetransmissionTime());
-}
-
-TEST_F(QuicSentPacketManagerTest, RetransmitTwiceThenAckFirst) {
- StrictMock<MockDebugDelegate> debug_delegate;
- EXPECT_CALL(debug_delegate, OnSpuriousPacketRetransmission(TLP_RETRANSMISSION,
- kDefaultLength))
- .Times(1);
- manager_.SetDebugDelegate(&debug_delegate);
-
- SendDataPacket(1);
- RetransmitAndSendPacket(1, 2);
- RetransmitAndSendPacket(2, 3);
- QuicTime::Delta rtt = QuicTime::Delta::FromMilliseconds(15);
- clock_.AdvanceTime(rtt);
-
- // Ack 1 but not 2 or 3.
- ExpectAck(1);
- 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));
- // Frames in packets 2 and 3 are acked.
- EXPECT_CALL(notifier_, IsFrameOutstanding(_))
- .Times(2)
- .WillRepeatedly(Return(false));
-
- // 2 and 3 remain unacked, but no packets have retransmittable data.
- uint64_t unacked[] = {2, 3};
- VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked));
- EXPECT_TRUE(manager_.HasInFlightPackets());
- VerifyRetransmittablePackets(nullptr, 0);
-
- // Ensure packet 2 is lost when 4 is sent and 3 and 4 are acked.
- SendDataPacket(4);
- // No new data gets acked in packet 3.
- EXPECT_CALL(notifier_, OnFrameAcked(_, _, _))
- .WillOnce(Return(false))
- .WillRepeatedly(Return(true));
- uint64_t acked[] = {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(2),
- ENCRYPTION_INITIAL));
-
- uint64_t unacked2[] = {2};
- VerifyUnackedPackets(unacked2, ABSL_ARRAYSIZE(unacked2));
- EXPECT_TRUE(manager_.HasInFlightPackets());
-
- SendDataPacket(5);
- ExpectAckAndLoss(true, 5, 2);
- EXPECT_CALL(debug_delegate,
- OnPacketLoss(QuicPacketNumber(2), _, LOSS_RETRANSMISSION, _));
- // Frames in all packets are acked.
- EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(false));
- // Notify session that stream frame in packet 2 gets lost although it is
- // not outstanding.
- EXPECT_CALL(notifier_, OnFrameLost(_)).Times(1);
- manager_.OnAckFrameStart(QuicPacketNumber(5), QuicTime::Delta::Infinite(),
- clock_.Now());
- manager_.OnAckRange(QuicPacketNumber(3), QuicPacketNumber(6));
- manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
- EXPECT_EQ(PACKETS_NEWLY_ACKED,
- manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(3),
- ENCRYPTION_INITIAL));
-
- uint64_t unacked3[] = {2};
- VerifyUnackedPackets(unacked3, ABSL_ARRAYSIZE(unacked3));
- EXPECT_FALSE(manager_.HasInFlightPackets());
- // Spurious retransmission is detected when packet 3 gets acked. We cannot
- // know packet 2 is a spurious until it gets acked.
- EXPECT_EQ(1u, stats_.packets_spuriously_retransmitted);
- EXPECT_EQ(1u, stats_.packets_lost);
- EXPECT_LT(0.0, stats_.total_loss_detection_response_time);
- EXPECT_LE(1u, stats_.sent_packets_max_sequence_reordering);
-}
-
-TEST_F(QuicSentPacketManagerTest, AckOriginalTransmission) {
- auto loss_algorithm = std::make_unique<MockLossAlgorithm>();
- QuicSentPacketManagerPeer::SetLossAlgorithm(&manager_, loss_algorithm.get());
-
- SendDataPacket(1);
- RetransmitAndSendPacket(1, 2);
-
- // Ack original transmission, but that wasn't lost via fast retransmit,
- // so no call on OnSpuriousRetransmission is expected.
- {
- ExpectAck(1);
- EXPECT_CALL(*loss_algorithm, DetectLosses(_, _, _, _, _, _));
- 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));
- }
-
- SendDataPacket(3);
- SendDataPacket(4);
- // Ack 4, which causes 3 to be retransmitted.
- {
- ExpectAck(4);
- EXPECT_CALL(*loss_algorithm, DetectLosses(_, _, _, _, _, _));
- manager_.OnAckFrameStart(QuicPacketNumber(4), QuicTime::Delta::Infinite(),
- clock_.Now());
- manager_.OnAckRange(QuicPacketNumber(4), QuicPacketNumber(5));
- manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
- EXPECT_EQ(PACKETS_NEWLY_ACKED,
- manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(2),
- ENCRYPTION_INITIAL));
- RetransmitAndSendPacket(3, 5, LOSS_RETRANSMISSION);
- }
-
- // Ack 3, which causes SpuriousRetransmitDetected to be called.
- {
- uint64_t acked[] = {3};
- ExpectAcksAndLosses(false, acked, ABSL_ARRAYSIZE(acked), nullptr, 0);
- EXPECT_CALL(*loss_algorithm, DetectLosses(_, _, _, _, _, _));
- EXPECT_CALL(*loss_algorithm,
- SpuriousLossDetected(_, _, _, QuicPacketNumber(3),
- QuicPacketNumber(4)));
- manager_.OnAckFrameStart(QuicPacketNumber(4), QuicTime::Delta::Infinite(),
- clock_.Now());
- manager_.OnAckRange(QuicPacketNumber(3), QuicPacketNumber(5));
- manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
- EXPECT_EQ(0u, stats_.packet_spuriously_detected_lost);
- EXPECT_EQ(PACKETS_NEWLY_ACKED,
- manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(3),
- ENCRYPTION_INITIAL));
- EXPECT_EQ(1u, stats_.packet_spuriously_detected_lost);
- // Ack 3 will not cause 5 be considered as a spurious retransmission. Ack
- // 5 will cause 5 be considered as a spurious retransmission as no new
- // data gets acked.
- ExpectAck(5);
- EXPECT_CALL(*loss_algorithm, DetectLosses(_, _, _, _, _, _));
- EXPECT_CALL(notifier_, OnFrameAcked(_, _, _)).WillOnce(Return(false));
- manager_.OnAckFrameStart(QuicPacketNumber(5), QuicTime::Delta::Infinite(),
- clock_.Now());
- manager_.OnAckRange(QuicPacketNumber(3), QuicPacketNumber(6));
- manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
- EXPECT_EQ(PACKETS_NEWLY_ACKED,
- manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(4),
- ENCRYPTION_INITIAL));
- }
-}
-
-TEST_F(QuicSentPacketManagerTest, GetLeastUnacked) {
- EXPECT_EQ(QuicPacketNumber(1u), manager_.GetLeastUnacked());
-}
-
-TEST_F(QuicSentPacketManagerTest, GetLeastUnackedUnacked) {
- SendDataPacket(1);
- EXPECT_EQ(QuicPacketNumber(1u), manager_.GetLeastUnacked());
-}
-
-TEST_F(QuicSentPacketManagerTest, AckAckAndUpdateRtt) {
- EXPECT_FALSE(manager_.largest_packet_peer_knows_is_acked().IsInitialized());
- SendDataPacket(1);
- SendAckPacket(2, 1);
-
- // Now ack the ack and expect an RTT update.
- uint64_t acked[] = {1, 2};
- ExpectAcksAndLosses(true, acked, ABSL_ARRAYSIZE(acked), nullptr, 0);
- manager_.OnAckFrameStart(QuicPacketNumber(2),
- QuicTime::Delta::FromMilliseconds(5), clock_.Now());
- manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(3));
- EXPECT_EQ(PACKETS_NEWLY_ACKED,
- manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
- ENCRYPTION_INITIAL));
- EXPECT_EQ(QuicPacketNumber(1), manager_.largest_packet_peer_knows_is_acked());
-
- SendAckPacket(3, 3);
-
- // Now ack the ack and expect only an RTT update.
- uint64_t acked2[] = {3};
- ExpectAcksAndLosses(true, acked2, ABSL_ARRAYSIZE(acked2), nullptr, 0);
- manager_.OnAckFrameStart(QuicPacketNumber(3), QuicTime::Delta::Infinite(),
- clock_.Now());
- manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(4));
- EXPECT_EQ(PACKETS_NEWLY_ACKED,
- manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(2),
- ENCRYPTION_INITIAL));
- EXPECT_EQ(QuicPacketNumber(3u),
- manager_.largest_packet_peer_knows_is_acked());
-}
-
-TEST_F(QuicSentPacketManagerTest, Rtt) {
- QuicTime::Delta expected_rtt = QuicTime::Delta::FromMilliseconds(20);
- SendDataPacket(1);
- clock_.AdvanceTime(expected_rtt);
-
- ExpectAck(1);
- 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));
- EXPECT_EQ(expected_rtt, manager_.GetRttStats()->latest_rtt());
-}
-
-TEST_F(QuicSentPacketManagerTest, RttWithInvalidDelta) {
- // Expect that the RTT is equal to the local time elapsed, since the
- // ack_delay_time is larger than the local time elapsed
- // and is hence invalid.
- QuicTime::Delta expected_rtt = QuicTime::Delta::FromMilliseconds(10);
- SendDataPacket(1);
- clock_.AdvanceTime(expected_rtt);
-
- ExpectAck(1);
- manager_.OnAckFrameStart(QuicPacketNumber(1),
- QuicTime::Delta::FromMilliseconds(11), clock_.Now());
- manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
- EXPECT_EQ(PACKETS_NEWLY_ACKED,
- manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
- ENCRYPTION_INITIAL));
- EXPECT_EQ(expected_rtt, manager_.GetRttStats()->latest_rtt());
-}
-
-TEST_F(QuicSentPacketManagerTest, RttWithInfiniteDelta) {
- // Expect that the RTT is equal to the local time elapsed, since the
- // ack_delay_time is infinite, and is hence invalid.
- QuicTime::Delta expected_rtt = QuicTime::Delta::FromMilliseconds(10);
- SendDataPacket(1);
- clock_.AdvanceTime(expected_rtt);
-
- ExpectAck(1);
- 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));
- EXPECT_EQ(expected_rtt, manager_.GetRttStats()->latest_rtt());
-}
-
-TEST_F(QuicSentPacketManagerTest, RttWithDeltaExceedingLimit) {
- // Initialize min and smoothed rtt to 10ms.
- RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
- rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(10),
- QuicTime::Delta::Zero(), QuicTime::Zero());
-
- QuicTime::Delta send_delta = QuicTime::Delta::FromMilliseconds(100);
- QuicTime::Delta ack_delay =
- QuicTime::Delta::FromMilliseconds(5) + manager_.peer_max_ack_delay();
- ASSERT_GT(send_delta - rtt_stats->min_rtt(), ack_delay);
- SendDataPacket(1);
- clock_.AdvanceTime(send_delta);
-
- ExpectAck(1);
- manager_.OnAckFrameStart(QuicPacketNumber(1), ack_delay, clock_.Now());
- manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
- EXPECT_EQ(PACKETS_NEWLY_ACKED,
- manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
- ENCRYPTION_FORWARD_SECURE));
-
- QuicTime::Delta expected_rtt_sample =
- send_delta - manager_.peer_max_ack_delay();
- EXPECT_EQ(expected_rtt_sample, manager_.GetRttStats()->latest_rtt());
-}
-
-TEST_F(QuicSentPacketManagerTest, RttZeroDelta) {
- // Expect that the RTT is the time between send and receive since the
- // ack_delay_time is zero.
- QuicTime::Delta expected_rtt = QuicTime::Delta::FromMilliseconds(10);
- SendDataPacket(1);
- clock_.AdvanceTime(expected_rtt);
-
- ExpectAck(1);
- manager_.OnAckFrameStart(QuicPacketNumber(1), QuicTime::Delta::Zero(),
- clock_.Now());
- manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
- EXPECT_EQ(PACKETS_NEWLY_ACKED,
- manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
- ENCRYPTION_INITIAL));
- EXPECT_EQ(expected_rtt, manager_.GetRttStats()->latest_rtt());
-}
-
-TEST_F(QuicSentPacketManagerTest, TailLossProbeTimeout) {
- if (GetQuicReloadableFlag(quic_default_on_pto)) {
- 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) { 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) { 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 (GetQuicReloadableFlag(quic_default_on_pto)) {
- 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) { 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) { 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) { RetransmitDataPacket(103, type); })))
- .WillOnce(WithArgs<1>(Invoke(
- [this](TransmissionType type) { 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;
- for (size_t i = 1; i <= kNumSentCryptoPackets; ++i) {
- SendCryptoPacket(i);
- }
- const size_t kNumSentDataPackets = 3;
- for (size_t i = 1; i <= kNumSentDataPackets; ++i) {
- SendDataPacket(kNumSentCryptoPackets + i);
- }
- EXPECT_TRUE(manager_.HasUnackedCryptoPackets());
- EXPECT_EQ(5 * kDefaultLength, manager_.GetBytesInFlight());
-
- // The first retransmits 2 packets.
- EXPECT_CALL(notifier_, RetransmitFrames(_, _))
- .Times(2)
- .WillOnce(InvokeWithoutArgs([this]() { RetransmitCryptoPacket(6); }))
- .WillOnce(InvokeWithoutArgs([this]() { RetransmitCryptoPacket(7); }));
- manager_.OnRetransmissionTimeout();
- // Expect all 4 handshake packets to be in flight and 3 data packets.
- EXPECT_EQ(7 * kDefaultLength, manager_.GetBytesInFlight());
- EXPECT_TRUE(manager_.HasUnackedCryptoPackets());
-
- // The second retransmits 2 packets.
- EXPECT_CALL(notifier_, RetransmitFrames(_, _))
- .Times(2)
- .WillOnce(InvokeWithoutArgs([this]() { RetransmitCryptoPacket(8); }))
- .WillOnce(InvokeWithoutArgs([this]() { RetransmitCryptoPacket(9); }));
- manager_.OnRetransmissionTimeout();
- EXPECT_EQ(9 * kDefaultLength, manager_.GetBytesInFlight());
- EXPECT_TRUE(manager_.HasUnackedCryptoPackets());
-
- // Now ack the two crypto packets and the speculatively encrypted request,
- // and ensure the first four crypto packets get abandoned, but not lost.
- // Crypto packets remain in flight, so any that aren't acked will be lost.
- uint64_t acked[] = {3, 4, 5, 8, 9};
- uint64_t lost[] = {1, 2, 6};
- ExpectAcksAndLosses(true, acked, ABSL_ARRAYSIZE(acked), lost,
- ABSL_ARRAYSIZE(lost));
- EXPECT_CALL(notifier_, OnFrameLost(_)).Times(3);
- EXPECT_CALL(notifier_, HasUnackedCryptoData()).WillRepeatedly(Return(false));
- manager_.OnAckFrameStart(QuicPacketNumber(9), QuicTime::Delta::Infinite(),
- clock_.Now());
- manager_.OnAckRange(QuicPacketNumber(8), QuicPacketNumber(10));
- manager_.OnAckRange(QuicPacketNumber(3), QuicPacketNumber(6));
- EXPECT_EQ(PACKETS_NEWLY_ACKED,
- manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
- ENCRYPTION_INITIAL));
-
- EXPECT_FALSE(manager_.HasUnackedCryptoPackets());
-}
-
-TEST_F(QuicSentPacketManagerTest, CryptoHandshakeSpuriousRetransmission) {
- // Send 1 crypto packet.
- SendCryptoPacket(1);
- EXPECT_TRUE(manager_.HasUnackedCryptoPackets());
-
- // Retransmit the crypto packet as 2.
- EXPECT_CALL(notifier_, RetransmitFrames(_, _))
- .WillOnce(InvokeWithoutArgs([this]() { RetransmitCryptoPacket(2); }));
- manager_.OnRetransmissionTimeout();
-
- // Retransmit the crypto packet as 3.
- EXPECT_CALL(notifier_, RetransmitFrames(_, _))
- .WillOnce(InvokeWithoutArgs([this]() { RetransmitCryptoPacket(3); }));
- manager_.OnRetransmissionTimeout();
-
- // Now ack the second crypto packet, and ensure the first gets removed, but
- // the third does not.
- uint64_t acked[] = {2};
- ExpectAcksAndLosses(true, acked, ABSL_ARRAYSIZE(acked), nullptr, 0);
- EXPECT_CALL(notifier_, HasUnackedCryptoData()).WillRepeatedly(Return(false));
- EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(false));
- manager_.OnAckFrameStart(QuicPacketNumber(2), QuicTime::Delta::Infinite(),
- clock_.Now());
- manager_.OnAckRange(QuicPacketNumber(2), QuicPacketNumber(3));
- EXPECT_EQ(PACKETS_NEWLY_ACKED,
- manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
- ENCRYPTION_INITIAL));
-
- EXPECT_FALSE(manager_.HasUnackedCryptoPackets());
- uint64_t unacked[] = {1, 3};
- VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked));
-}
-
-TEST_F(QuicSentPacketManagerTest, CryptoHandshakeTimeoutUnsentDataPacket) {
- // Send 2 crypto packets and 1 data packet.
- const size_t kNumSentCryptoPackets = 2;
- for (size_t i = 1; i <= kNumSentCryptoPackets; ++i) {
- SendCryptoPacket(i);
- }
- SendDataPacket(3);
- EXPECT_TRUE(manager_.HasUnackedCryptoPackets());
-
- // Retransmit 2 crypto packets, but not the serialized packet.
- EXPECT_CALL(notifier_, RetransmitFrames(_, _))
- .Times(2)
- .WillOnce(InvokeWithoutArgs([this]() { RetransmitCryptoPacket(4); }))
- .WillOnce(InvokeWithoutArgs([this]() { RetransmitCryptoPacket(5); }));
- manager_.OnRetransmissionTimeout();
- EXPECT_TRUE(manager_.HasUnackedCryptoPackets());
-}
-
-TEST_F(QuicSentPacketManagerTest,
- CryptoHandshakeRetransmissionThenNeuterAndAck) {
- // Send 1 crypto packet.
- SendCryptoPacket(1);
-
- EXPECT_TRUE(manager_.HasUnackedCryptoPackets());
-
- // Retransmit the crypto packet as 2.
- EXPECT_CALL(notifier_, RetransmitFrames(_, _))
- .WillOnce(InvokeWithoutArgs([this]() { RetransmitCryptoPacket(2); }));
- manager_.OnRetransmissionTimeout();
- EXPECT_TRUE(manager_.HasUnackedCryptoPackets());
-
- // Retransmit the crypto packet as 3.
- EXPECT_CALL(notifier_, RetransmitFrames(_, _))
- .WillOnce(InvokeWithoutArgs([this]() { RetransmitCryptoPacket(3); }));
- manager_.OnRetransmissionTimeout();
- EXPECT_TRUE(manager_.HasUnackedCryptoPackets());
-
- // Now neuter all unacked unencrypted packets, which occurs when the
- // connection goes forward secure.
- EXPECT_CALL(notifier_, HasUnackedCryptoData()).WillRepeatedly(Return(false));
- EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(false));
- manager_.NeuterUnencryptedPackets();
- EXPECT_FALSE(manager_.HasUnackedCryptoPackets());
- uint64_t unacked[] = {1, 2, 3};
- VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked));
- VerifyRetransmittablePackets(nullptr, 0);
- EXPECT_FALSE(manager_.HasUnackedCryptoPackets());
- EXPECT_FALSE(manager_.HasInFlightPackets());
-
- // Ensure both packets get discarded when packet 2 is acked.
- uint64_t acked[] = {3};
- ExpectAcksAndLosses(true, acked, ABSL_ARRAYSIZE(acked), nullptr, 0);
- 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));
- VerifyUnackedPackets(nullptr, 0);
- VerifyRetransmittablePackets(nullptr, 0);
-}
-
-TEST_F(QuicSentPacketManagerTest, RetransmissionTimeout) {
- if (GetQuicReloadableFlag(quic_default_on_pto)) {
- 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) { RetransmitDataPacket(101, type); })))
- .WillOnce(WithArgs<1>(Invoke(
- [this](TransmissionType type) { 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 (GetQuicReloadableFlag(quic_default_on_pto)) {
- 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) { RetransmitDataPacket(101, type); })));
- manager_.OnRetransmissionTimeout();
- EXPECT_EQ(101 * kDefaultLength, manager_.GetBytesInFlight());
-}
-
-TEST_F(QuicSentPacketManagerTest, NewRetransmissionTimeout) {
- if (GetQuicReloadableFlag(quic_default_on_pto)) {
- 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) { RetransmitDataPacket(101, type); })))
- .WillOnce(WithArgs<1>(Invoke(
- [this](TransmissionType type) { 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 (GetQuicReloadableFlag(quic_default_on_pto)) {
- return;
- }
- // Send 1 packet.
- SendDataPacket(1);
-
- EXPECT_CALL(notifier_, RetransmitFrames(_, _))
- .WillOnce(WithArgs<1>(Invoke(
- [this](TransmissionType type) { 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) { 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 (GetQuicReloadableFlag(quic_default_on_pto)) {
- return;
- }
- // Send 1 packet.
- SendDataPacket(1);
-
- EXPECT_CALL(notifier_, RetransmitFrames(_, _))
- .WillOnce(WithArgs<1>(Invoke(
- [this](TransmissionType type) { 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) { 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());
-}
-
-TEST_F(QuicSentPacketManagerTest, GetTransmissionTimeCryptoHandshake) {
- QuicTime crypto_packet_send_time = clock_.Now();
- SendCryptoPacket(1);
-
- // 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 expected_time = clock_.Now() + 1.5 * srtt;
- EXPECT_EQ(expected_time, manager_.GetRetransmissionTime());
-
- // Retransmit the packet by invoking the retransmission timeout.
- clock_.AdvanceTime(1.5 * srtt);
- EXPECT_CALL(notifier_, RetransmitFrames(_, _))
- .WillOnce(InvokeWithoutArgs([this]() { RetransmitCryptoPacket(2); }));
- // When session decides what to write, crypto_packet_send_time gets updated.
- crypto_packet_send_time = clock_.Now();
- manager_.OnRetransmissionTimeout();
-
- // The retransmission time should now be twice as far in the future.
- expected_time = crypto_packet_send_time + srtt * 2 * 1.5;
- EXPECT_EQ(expected_time, manager_.GetRetransmissionTime());
-
- // Retransmit the packet for the 2nd time.
- clock_.AdvanceTime(2 * 1.5 * srtt);
- EXPECT_CALL(notifier_, RetransmitFrames(_, _))
- .WillOnce(InvokeWithoutArgs([this]() { RetransmitCryptoPacket(3); }));
- // When session decides what to write, crypto_packet_send_time gets updated.
- crypto_packet_send_time = clock_.Now();
- manager_.OnRetransmissionTimeout();
-
- // Verify exponential backoff of the retransmission timeout.
- expected_time = crypto_packet_send_time + srtt * 4 * 1.5;
- EXPECT_EQ(expected_time, manager_.GetRetransmissionTime());
-}
-
-TEST_F(QuicSentPacketManagerTest,
- GetConservativeTransmissionTimeCryptoHandshake) {
- QuicConfig config;
- QuicTagVector options;
- options.push_back(kCONH);
- QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
- EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
- manager_.SetFromConfig(config);
- // Calling SetFromConfig requires mocking out some send algorithm methods.
- EXPECT_CALL(*send_algorithm_, PacingRate(_))
- .WillRepeatedly(Return(QuicBandwidth::Zero()));
- EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
- .WillRepeatedly(Return(10 * kDefaultTCPMSS));
-
- QuicTime crypto_packet_send_time = clock_.Now();
- SendCryptoPacket(1);
-
- // 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(25),
- 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 expected_time = clock_.Now() + 2 * srtt;
- EXPECT_EQ(expected_time, manager_.GetRetransmissionTime());
-
- // Retransmit the packet by invoking the retransmission timeout.
- clock_.AdvanceTime(2 * srtt);
- EXPECT_CALL(notifier_, RetransmitFrames(_, _))
- .WillOnce(InvokeWithoutArgs([this]() { RetransmitCryptoPacket(2); }));
- crypto_packet_send_time = clock_.Now();
- manager_.OnRetransmissionTimeout();
-
- // The retransmission time should now be twice as far in the future.
- expected_time = crypto_packet_send_time + srtt * 2 * 2;
- EXPECT_EQ(expected_time, manager_.GetRetransmissionTime());
-}
-
-TEST_F(QuicSentPacketManagerTest, GetTransmissionTimeTailLossProbe) {
- if (GetQuicReloadableFlag(quic_default_on_pto)) {
- 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) { 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 (GetQuicReloadableFlag(quic_default_on_pto)) {
- 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) { RetransmitDataPacket(5, type); })))
- .WillOnce(WithArgs<1>(Invoke(
- [this](TransmissionType type) { 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 (GetQuicReloadableFlag(quic_default_on_pto)) {
- 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) {
- RetransmitDataPacket(i + 2, type);
- })));
- manager_.OnRetransmissionTimeout();
- }
-}
-
-TEST_F(QuicSentPacketManagerTest, GetTransmissionDelayMax) {
- if (GetQuicReloadableFlag(quic_default_on_pto)) {
- 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 (GetQuicReloadableFlag(quic_default_on_pto)) {
- 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) {
- RetransmitDataPacket(i + 2, type);
- })));
- manager_.OnRetransmissionTimeout();
- }
-}
-
-TEST_F(QuicSentPacketManagerTest, RetransmissionDelay) {
- if (GetQuicReloadableFlag(quic_default_on_pto)) {
- 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());
-
- EXPECT_CALL(*loss_algorithm, GetLossTimeout())
- .WillRepeatedly(Return(QuicTime::Zero()));
- SendDataPacket(1);
- SendDataPacket(2);
-
- // Handle an ack which causes the loss algorithm to be evaluated and
- // set the loss timeout.
- ExpectAck(2);
- EXPECT_CALL(*loss_algorithm, DetectLosses(_, _, _, _, _, _));
- manager_.OnAckFrameStart(QuicPacketNumber(2), QuicTime::Delta::Infinite(),
- clock_.Now());
- manager_.OnAckRange(QuicPacketNumber(2), QuicPacketNumber(3));
- EXPECT_EQ(PACKETS_NEWLY_ACKED,
- manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
- ENCRYPTION_INITIAL));
-
- QuicTime timeout(clock_.Now() + QuicTime::Delta::FromMilliseconds(10));
- EXPECT_CALL(*loss_algorithm, GetLossTimeout())
- .WillRepeatedly(Return(timeout));
- EXPECT_EQ(timeout, manager_.GetRetransmissionTime());
-
- // Fire the retransmission timeout and ensure the loss detection algorithm
- // is invoked.
- EXPECT_CALL(*loss_algorithm, DetectLosses(_, _, _, _, _, _));
- manager_.OnRetransmissionTimeout();
-}
-
-TEST_F(QuicSentPacketManagerTest, NegotiateIetfLossDetectionFromOptions) {
- EXPECT_TRUE(
- QuicSentPacketManagerPeer::AdaptiveReorderingThresholdEnabled(&manager_));
- EXPECT_FALSE(
- QuicSentPacketManagerPeer::AdaptiveTimeThresholdEnabled(&manager_));
- EXPECT_EQ(kDefaultLossDelayShift,
- QuicSentPacketManagerPeer::GetReorderingShift(&manager_));
-
- QuicConfig config;
- QuicTagVector options;
- options.push_back(kILD0);
- QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
- EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
- manager_.SetFromConfig(config);
-
- EXPECT_EQ(3, QuicSentPacketManagerPeer::GetReorderingShift(&manager_));
- EXPECT_FALSE(
- QuicSentPacketManagerPeer::AdaptiveReorderingThresholdEnabled(&manager_));
-}
-
-TEST_F(QuicSentPacketManagerTest,
- NegotiateIetfLossDetectionOneFourthRttFromOptions) {
- EXPECT_TRUE(
- QuicSentPacketManagerPeer::AdaptiveReorderingThresholdEnabled(&manager_));
- EXPECT_FALSE(
- QuicSentPacketManagerPeer::AdaptiveTimeThresholdEnabled(&manager_));
- EXPECT_EQ(kDefaultLossDelayShift,
- QuicSentPacketManagerPeer::GetReorderingShift(&manager_));
-
- QuicConfig config;
- QuicTagVector options;
- options.push_back(kILD1);
- QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
- EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
- manager_.SetFromConfig(config);
-
- EXPECT_EQ(kDefaultLossDelayShift,
- QuicSentPacketManagerPeer::GetReorderingShift(&manager_));
- EXPECT_FALSE(
- QuicSentPacketManagerPeer::AdaptiveReorderingThresholdEnabled(&manager_));
-}
-
-TEST_F(QuicSentPacketManagerTest,
- NegotiateIetfLossDetectionAdaptiveReorderingThreshold) {
- EXPECT_TRUE(
- QuicSentPacketManagerPeer::AdaptiveReorderingThresholdEnabled(&manager_));
- EXPECT_FALSE(
- QuicSentPacketManagerPeer::AdaptiveTimeThresholdEnabled(&manager_));
- EXPECT_EQ(kDefaultLossDelayShift,
- QuicSentPacketManagerPeer::GetReorderingShift(&manager_));
-
- QuicConfig config;
- QuicTagVector options;
- options.push_back(kILD2);
- QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
- EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
- manager_.SetFromConfig(config);
-
- EXPECT_EQ(3, QuicSentPacketManagerPeer::GetReorderingShift(&manager_));
- EXPECT_TRUE(
- QuicSentPacketManagerPeer::AdaptiveReorderingThresholdEnabled(&manager_));
-}
-
-TEST_F(QuicSentPacketManagerTest,
- NegotiateIetfLossDetectionAdaptiveReorderingThreshold2) {
- EXPECT_TRUE(
- QuicSentPacketManagerPeer::AdaptiveReorderingThresholdEnabled(&manager_));
- EXPECT_FALSE(
- QuicSentPacketManagerPeer::AdaptiveTimeThresholdEnabled(&manager_));
- EXPECT_EQ(kDefaultLossDelayShift,
- QuicSentPacketManagerPeer::GetReorderingShift(&manager_));
-
- QuicConfig config;
- QuicTagVector options;
- options.push_back(kILD3);
- QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
- EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
- manager_.SetFromConfig(config);
- EXPECT_EQ(kDefaultLossDelayShift,
- QuicSentPacketManagerPeer::GetReorderingShift(&manager_));
- EXPECT_TRUE(
- QuicSentPacketManagerPeer::AdaptiveReorderingThresholdEnabled(&manager_));
-}
-
-TEST_F(QuicSentPacketManagerTest,
- NegotiateIetfLossDetectionAdaptiveReorderingAndTimeThreshold) {
- EXPECT_TRUE(
- QuicSentPacketManagerPeer::AdaptiveReorderingThresholdEnabled(&manager_));
- EXPECT_FALSE(
- QuicSentPacketManagerPeer::AdaptiveTimeThresholdEnabled(&manager_));
- EXPECT_EQ(kDefaultLossDelayShift,
- QuicSentPacketManagerPeer::GetReorderingShift(&manager_));
-
- QuicConfig config;
- QuicTagVector options;
- options.push_back(kILD4);
- QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
- EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
- manager_.SetFromConfig(config);
-
- EXPECT_EQ(kDefaultLossDelayShift,
- QuicSentPacketManagerPeer::GetReorderingShift(&manager_));
- EXPECT_TRUE(
- QuicSentPacketManagerPeer::AdaptiveReorderingThresholdEnabled(&manager_));
- EXPECT_TRUE(
- QuicSentPacketManagerPeer::AdaptiveTimeThresholdEnabled(&manager_));
-}
-
-TEST_F(QuicSentPacketManagerTest, NegotiateCongestionControlFromOptions) {
- QuicConfig config;
- QuicTagVector options;
-
- options.push_back(kRENO);
- QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
- EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
- manager_.SetFromConfig(config);
- EXPECT_EQ(kRenoBytes, QuicSentPacketManagerPeer::GetSendAlgorithm(manager_)
- ->GetCongestionControlType());
-
- options.clear();
- options.push_back(kTBBR);
- QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
- EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
- manager_.SetFromConfig(config);
- EXPECT_EQ(kBBR, QuicSentPacketManagerPeer::GetSendAlgorithm(manager_)
- ->GetCongestionControlType());
-
- options.clear();
- options.push_back(kBYTE);
- QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
- EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
- manager_.SetFromConfig(config);
- EXPECT_EQ(kCubicBytes, QuicSentPacketManagerPeer::GetSendAlgorithm(manager_)
- ->GetCongestionControlType());
- options.clear();
- options.push_back(kRENO);
- options.push_back(kBYTE);
- QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
- EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
- manager_.SetFromConfig(config);
- EXPECT_EQ(kRenoBytes, QuicSentPacketManagerPeer::GetSendAlgorithm(manager_)
- ->GetCongestionControlType());
-}
-
-TEST_F(QuicSentPacketManagerTest, NegotiateClientCongestionControlFromOptions) {
- QuicConfig config;
- QuicTagVector options;
-
- // No change if the server receives client options.
- const SendAlgorithmInterface* mock_sender =
- QuicSentPacketManagerPeer::GetSendAlgorithm(manager_);
- options.push_back(kRENO);
- config.SetClientConnectionOptions(options);
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
- EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
- manager_.SetFromConfig(config);
- EXPECT_EQ(mock_sender, QuicSentPacketManagerPeer::GetSendAlgorithm(manager_));
-
- // Change the congestion control on the client with client options.
- QuicSentPacketManagerPeer::SetPerspective(&manager_, Perspective::IS_CLIENT);
- EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
- manager_.SetFromConfig(config);
- EXPECT_EQ(kRenoBytes, QuicSentPacketManagerPeer::GetSendAlgorithm(manager_)
- ->GetCongestionControlType());
-
- options.clear();
- options.push_back(kTBBR);
- config.SetClientConnectionOptions(options);
- EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
- manager_.SetFromConfig(config);
- EXPECT_EQ(kBBR, QuicSentPacketManagerPeer::GetSendAlgorithm(manager_)
- ->GetCongestionControlType());
-
- options.clear();
- options.push_back(kBYTE);
- config.SetClientConnectionOptions(options);
- EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
- manager_.SetFromConfig(config);
- EXPECT_EQ(kCubicBytes, QuicSentPacketManagerPeer::GetSendAlgorithm(manager_)
- ->GetCongestionControlType());
-
- options.clear();
- options.push_back(kRENO);
- options.push_back(kBYTE);
- config.SetClientConnectionOptions(options);
- EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
- manager_.SetFromConfig(config);
- EXPECT_EQ(kRenoBytes, QuicSentPacketManagerPeer::GetSendAlgorithm(manager_)
- ->GetCongestionControlType());
-}
-
-TEST_F(QuicSentPacketManagerTest, NegotiateNoMinTLPFromOptionsAtServer) {
- if (GetQuicReloadableFlag(quic_default_on_pto)) {
- 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 (GetQuicReloadableFlag(quic_default_on_pto)) {
- 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 (GetQuicReloadableFlag(quic_default_on_pto)) {
- 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 (GetQuicReloadableFlag(quic_default_on_pto)) {
- 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 (GetQuicReloadableFlag(quic_default_on_pto)) {
- 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 (GetQuicReloadableFlag(quic_default_on_pto)) {
- 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 (GetQuicReloadableFlag(quic_default_on_pto)) {
- 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 (GetQuicReloadableFlag(quic_default_on_pto)) {
- 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 (GetQuicReloadableFlag(quic_default_on_pto)) {
- 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 (GetQuicReloadableFlag(quic_default_on_pto)) {
- 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());
-
- QuicConfig config;
- config.SetInitialRoundTripTimeUsToSend(initial_rtt.ToMicroseconds());
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
- EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
- manager_.SetFromConfig(config);
-
- EXPECT_EQ(QuicTime::Delta::Zero(), manager_.GetRttStats()->smoothed_rtt());
- EXPECT_EQ(initial_rtt, manager_.GetRttStats()->initial_rtt());
-}
-
-TEST_F(QuicSentPacketManagerTest, ResumeConnectionState) {
- // The sent packet manager should use the RTT from CachedNetworkParameters if
- // it is provided.
- const QuicTime::Delta kRtt = QuicTime::Delta::FromMilliseconds(123);
- CachedNetworkParameters cached_network_params;
- cached_network_params.set_min_rtt_ms(kRtt.ToMilliseconds());
-
- SendAlgorithmInterface::NetworkParams params;
- params.bandwidth = QuicBandwidth::Zero();
- params.allow_cwnd_to_decrease = false;
- params.rtt = kRtt;
-
- EXPECT_CALL(*send_algorithm_, AdjustNetworkParameters(params));
- EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
- .Times(testing::AnyNumber());
- manager_.ResumeConnectionState(cached_network_params, false);
- EXPECT_EQ(kRtt, manager_.GetRttStats()->initial_rtt());
-}
-
-TEST_F(QuicSentPacketManagerTest, ConnectionMigrationUnspecifiedChange) {
- RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
- QuicTime::Delta default_init_rtt = rtt_stats->initial_rtt();
- 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());
-
- 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());
-}
-
-// Tests that ResetCongestionControlUponPeerAddressChange() resets send
-// algorithm and RTT. And unACK'ed packets are handled correctly.
-TEST_F(QuicSentPacketManagerTest,
- ConnectionMigrationUnspecifiedChangeResetSendAlgorithm) {
- auto loss_algorithm = std::make_unique<MockLossAlgorithm>();
- QuicSentPacketManagerPeer::SetLossAlgorithm(&manager_, loss_algorithm.get());
-
- RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
- QuicTime::Delta default_init_rtt = rtt_stats->initial_rtt();
- 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());
-
- SendDataPacket(1, ENCRYPTION_FORWARD_SECURE);
-
- RttStats old_rtt_stats;
- old_rtt_stats.CloneFrom(*manager_.GetRttStats());
-
- // Packet1 will be mark for retransmission upon migration.
- EXPECT_CALL(notifier_, OnFrameLost(_));
- std::unique_ptr<SendAlgorithmInterface> old_send_algorithm =
- manager_.OnConnectionMigration(/*reset_send_algorithm=*/true);
-
- EXPECT_NE(old_send_algorithm.get(), manager_.GetSendAlgorithm());
- 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());
- // Packets sent earlier shouldn't be regarded as in flight.
- EXPECT_EQ(0u, BytesInFlight());
-
- // Replace the new send algorithm with the mock object.
- manager_.SetSendAlgorithm(old_send_algorithm.release());
-
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
- // Application retransmit the data as LOSS_RETRANSMISSION.
- RetransmitDataPacket(2, LOSS_RETRANSMISSION, ENCRYPTION_FORWARD_SECURE);
- EXPECT_EQ(kDefaultLength, BytesInFlight());
-
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
- // Receiving an ACK for packet1 20s later shouldn't update the RTT, and
- // shouldn't be treated as spurious retransmission.
- EXPECT_CALL(*send_algorithm_,
- OnCongestionEvent(/*rtt_updated=*/false, kDefaultLength, _, _, _))
- .WillOnce(testing::WithArg<3>(
- Invoke([](const AckedPacketVector& acked_packets) {
- EXPECT_EQ(1u, acked_packets.size());
- EXPECT_EQ(QuicPacketNumber(1), acked_packets[0].packet_number);
- // The bytes in packet1 shouldn't contribute to congestion control.
- EXPECT_EQ(0u, acked_packets[0].bytes_acked);
- })));
- EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
- manager_.OnAckFrameStart(QuicPacketNumber(1), QuicTime::Delta::Infinite(),
- clock_.Now());
- manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
- EXPECT_CALL(*loss_algorithm, DetectLosses(_, _, _, _, _, _));
- EXPECT_CALL(*loss_algorithm, SpuriousLossDetected(_, _, _, _, _)).Times(0u);
- EXPECT_EQ(PACKETS_NEWLY_ACKED,
- manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
- ENCRYPTION_FORWARD_SECURE));
- EXPECT_TRUE(manager_.GetRttStats()->latest_rtt().IsZero());
-
- // Receiving an ACK for packet2 should update RTT and congestion control.
- manager_.OnAckFrameStart(QuicPacketNumber(2), QuicTime::Delta::Infinite(),
- clock_.Now());
- manager_.OnAckRange(QuicPacketNumber(2), QuicPacketNumber(3));
- EXPECT_CALL(*loss_algorithm, DetectLosses(_, _, _, _, _, _));
- EXPECT_CALL(*send_algorithm_,
- OnCongestionEvent(/*rtt_updated=*/true, kDefaultLength, _, _, _))
- .WillOnce(testing::WithArg<3>(
- Invoke([](const AckedPacketVector& acked_packets) {
- EXPECT_EQ(1u, acked_packets.size());
- EXPECT_EQ(QuicPacketNumber(2), acked_packets[0].packet_number);
- // The bytes in packet2 should contribute to congestion control.
- EXPECT_EQ(kDefaultLength, acked_packets[0].bytes_acked);
- })));
- EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
- EXPECT_EQ(PACKETS_NEWLY_ACKED,
- manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(2),
- ENCRYPTION_FORWARD_SECURE));
- EXPECT_EQ(0u, BytesInFlight());
- EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10),
- manager_.GetRttStats()->latest_rtt());
-
- SendDataPacket(3, ENCRYPTION_FORWARD_SECURE);
- // Trigger loss timeout and mark packet3 for retransmission.
- EXPECT_CALL(*loss_algorithm, GetLossTimeout())
- .WillOnce(Return(clock_.Now() + QuicTime::Delta::FromMilliseconds(10)));
- EXPECT_CALL(*loss_algorithm, DetectLosses(_, _, _, _, _, _))
- .WillOnce(WithArgs<5>(Invoke([](LostPacketVector* packet_lost) {
- packet_lost->emplace_back(QuicPacketNumber(3u), kDefaultLength);
- return LossDetectionInterface::DetectionStats();
- })));
- EXPECT_CALL(notifier_, OnFrameLost(_));
- EXPECT_CALL(*send_algorithm_,
- OnCongestionEvent(false, kDefaultLength, _, _, _));
- EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
- manager_.OnRetransmissionTimeout();
- EXPECT_EQ(0u, BytesInFlight());
-
- // Migrate again with unACK'ed but not in-flight packet.
- // Packet3 shouldn't be marked for retransmission again as it is not in
- // flight.
- old_send_algorithm =
- manager_.OnConnectionMigration(/*reset_send_algorithm=*/true);
-
- EXPECT_NE(old_send_algorithm.get(), manager_.GetSendAlgorithm());
- 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, BytesInFlight());
- EXPECT_TRUE(manager_.GetRttStats()->latest_rtt().IsZero());
-
- manager_.SetSendAlgorithm(old_send_algorithm.release());
-
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(30));
- // Receiving an ACK for packet3 shouldn't update RTT. Though packet 3 was
- // marked lost, this spurious retransmission shouldn't be reported to the loss
- // algorithm.
- manager_.OnAckFrameStart(QuicPacketNumber(3), QuicTime::Delta::Infinite(),
- clock_.Now());
- manager_.OnAckRange(QuicPacketNumber(3), QuicPacketNumber(4));
- EXPECT_CALL(*loss_algorithm, DetectLosses(_, _, _, _, _, _));
- EXPECT_CALL(*loss_algorithm, SpuriousLossDetected(_, _, _, _, _)).Times(0u);
- EXPECT_CALL(*send_algorithm_,
- OnCongestionEvent(/*rtt_updated=*/false, 0, _, _, _));
- EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
- EXPECT_EQ(PACKETS_NEWLY_ACKED,
- manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(3),
- ENCRYPTION_FORWARD_SECURE));
- EXPECT_EQ(0u, BytesInFlight());
- EXPECT_TRUE(manager_.GetRttStats()->latest_rtt().IsZero());
-
- SendDataPacket(4, ENCRYPTION_FORWARD_SECURE);
- // Trigger loss timeout and mark packet4 for retransmission.
- EXPECT_CALL(*loss_algorithm, GetLossTimeout())
- .WillOnce(Return(clock_.Now() + QuicTime::Delta::FromMilliseconds(10)));
- EXPECT_CALL(*loss_algorithm, DetectLosses(_, _, _, _, _, _))
- .WillOnce(WithArgs<5>(Invoke([](LostPacketVector* packet_lost) {
- packet_lost->emplace_back(QuicPacketNumber(4u), kDefaultLength);
- return LossDetectionInterface::DetectionStats();
- })));
- EXPECT_CALL(notifier_, OnFrameLost(_));
- EXPECT_CALL(*send_algorithm_,
- OnCongestionEvent(false, kDefaultLength, _, _, _));
- EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
- manager_.OnRetransmissionTimeout();
- EXPECT_EQ(0u, BytesInFlight());
-
- // Application retransmit the data as LOSS_RETRANSMISSION.
- RetransmitDataPacket(5, LOSS_RETRANSMISSION, ENCRYPTION_FORWARD_SECURE);
- EXPECT_EQ(kDefaultLength, BytesInFlight());
-
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(30));
- // Receiving an ACK for packet4 should update RTT, but not bytes in flight.
- // This spurious retransmission should be reported to the loss algorithm.
- manager_.OnAckFrameStart(QuicPacketNumber(4), QuicTime::Delta::Infinite(),
- clock_.Now());
- manager_.OnAckRange(QuicPacketNumber(4), QuicPacketNumber(5));
- EXPECT_CALL(*loss_algorithm, DetectLosses(_, _, _, _, _, _));
- EXPECT_CALL(*loss_algorithm, SpuriousLossDetected(_, _, _, _, _));
- EXPECT_CALL(*send_algorithm_,
- OnCongestionEvent(/*rtt_updated=*/true, kDefaultLength, _, _, _));
- EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
- EXPECT_CALL(notifier_, OnFrameAcked(_, _, _));
- EXPECT_EQ(PACKETS_NEWLY_ACKED,
- manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(3),
- ENCRYPTION_FORWARD_SECURE));
- EXPECT_EQ(kDefaultLength, BytesInFlight());
- EXPECT_EQ(QuicTime::Delta::FromMilliseconds(30),
- manager_.GetRttStats()->latest_rtt());
-
- // Migrate again with in-flight packet5 whose retransmittable frames are all
- // ACKed. Packet5 should be marked for retransmission but nothing to
- // retransmit.
- EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillOnce(Return(false));
- EXPECT_CALL(notifier_, OnFrameLost(_)).Times(0u);
- 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, BytesInFlight());
- EXPECT_TRUE(manager_.GetRttStats()->latest_rtt().IsZero());
-
- manager_.SetSendAlgorithm(old_send_algorithm.release());
-
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
- // Receiving an ACK for packet5 shouldn't update RTT. Though packet 5 was
- // marked for retransmission, this spurious retransmission shouldn't be
- // reported to the loss algorithm.
- manager_.OnAckFrameStart(QuicPacketNumber(5), QuicTime::Delta::Infinite(),
- clock_.Now());
- manager_.OnAckRange(QuicPacketNumber(5), QuicPacketNumber(6));
- EXPECT_CALL(*loss_algorithm, DetectLosses(_, _, _, _, _, _));
- EXPECT_CALL(*loss_algorithm, SpuriousLossDetected(_, _, _, _, _)).Times(0u);
- EXPECT_CALL(*send_algorithm_,
- OnCongestionEvent(/*rtt_updated=*/false, 0, _, _, _));
- EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
- EXPECT_CALL(notifier_, OnFrameAcked(_, _, _));
- EXPECT_EQ(PACKETS_NEWLY_ACKED,
- manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(3),
- ENCRYPTION_FORWARD_SECURE));
- EXPECT_EQ(0u, BytesInFlight());
- EXPECT_TRUE(manager_.GetRttStats()->latest_rtt().IsZero());
-}
-
-TEST_F(QuicSentPacketManagerTest, PathMtuIncreased) {
- EXPECT_CALL(*send_algorithm_,
- OnPacketSent(_, BytesInFlight(), QuicPacketNumber(1), _, _));
- SerializedPacket packet(QuicPacketNumber(1), PACKET_4BYTE_PACKET_NUMBER,
- nullptr, kDefaultLength + 100, false, false);
- manager_.OnPacketSent(&packet, clock_.Now(), NOT_RETRANSMISSION,
- HAS_RETRANSMITTABLE_DATA, true);
-
- // Ack the large packet and expect the path MTU to increase.
- ExpectAck(1);
- EXPECT_CALL(*network_change_visitor_,
- OnPathMtuIncreased(kDefaultLength + 100));
- QuicAckFrame ack_frame = InitAckFrame(1);
- 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));
-}
-
-TEST_F(QuicSentPacketManagerTest, OnAckRangeSlowPath) {
- // Send packets 1 - 20.
- for (size_t i = 1; i <= 20; ++i) {
- SendDataPacket(i);
- }
- // Ack [5, 7), [10, 12), [15, 17).
- uint64_t acked1[] = {5, 6, 10, 11, 15, 16};
- uint64_t lost1[] = {1, 2, 3, 4, 7, 8, 9, 12, 13};
- ExpectAcksAndLosses(true, acked1, ABSL_ARRAYSIZE(acked1), lost1,
- ABSL_ARRAYSIZE(lost1));
- EXPECT_CALL(notifier_, OnFrameLost(_)).Times(AnyNumber());
- manager_.OnAckFrameStart(QuicPacketNumber(16), QuicTime::Delta::Infinite(),
- clock_.Now());
- manager_.OnAckRange(QuicPacketNumber(15), QuicPacketNumber(17));
- manager_.OnAckRange(QuicPacketNumber(10), QuicPacketNumber(12));
- manager_.OnAckRange(QuicPacketNumber(5), QuicPacketNumber(7));
- // Make sure empty range does not harm.
- manager_.OnAckRange(QuicPacketNumber(4), QuicPacketNumber(4));
- EXPECT_EQ(PACKETS_NEWLY_ACKED,
- manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
- ENCRYPTION_INITIAL));
-
- // Ack [4, 8), [9, 13), [14, 21).
- uint64_t acked2[] = {4, 7, 9, 12, 14, 17, 18, 19, 20};
- ExpectAcksAndLosses(true, acked2, ABSL_ARRAYSIZE(acked2), nullptr, 0);
- manager_.OnAckFrameStart(QuicPacketNumber(20), QuicTime::Delta::Infinite(),
- clock_.Now());
- manager_.OnAckRange(QuicPacketNumber(14), QuicPacketNumber(21));
- manager_.OnAckRange(QuicPacketNumber(9), QuicPacketNumber(13));
- manager_.OnAckRange(QuicPacketNumber(4), QuicPacketNumber(8));
- EXPECT_EQ(PACKETS_NEWLY_ACKED,
- manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(2),
- ENCRYPTION_INITIAL));
-}
-
-TEST_F(QuicSentPacketManagerTest, TolerateReneging) {
- // Send packets 1 - 20.
- for (size_t i = 1; i <= 20; ++i) {
- SendDataPacket(i);
- }
- // Ack [5, 7), [10, 12), [15, 17).
- uint64_t acked1[] = {5, 6, 10, 11, 15, 16};
- uint64_t lost1[] = {1, 2, 3, 4, 7, 8, 9, 12, 13};
- ExpectAcksAndLosses(true, acked1, ABSL_ARRAYSIZE(acked1), lost1,
- ABSL_ARRAYSIZE(lost1));
- EXPECT_CALL(notifier_, OnFrameLost(_)).Times(AnyNumber());
- manager_.OnAckFrameStart(QuicPacketNumber(16), QuicTime::Delta::Infinite(),
- clock_.Now());
- manager_.OnAckRange(QuicPacketNumber(15), QuicPacketNumber(17));
- manager_.OnAckRange(QuicPacketNumber(10), QuicPacketNumber(12));
- manager_.OnAckRange(QuicPacketNumber(5), QuicPacketNumber(7));
- EXPECT_EQ(PACKETS_NEWLY_ACKED,
- manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
- ENCRYPTION_INITIAL));
-
- // Making sure reneged ACK does not harm. Ack [4, 8), [9, 13).
- uint64_t acked2[] = {4, 7, 9, 12};
- ExpectAcksAndLosses(true, acked2, ABSL_ARRAYSIZE(acked2), nullptr, 0);
- manager_.OnAckFrameStart(QuicPacketNumber(12), QuicTime::Delta::Infinite(),
- clock_.Now());
- manager_.OnAckRange(QuicPacketNumber(9), QuicPacketNumber(13));
- manager_.OnAckRange(QuicPacketNumber(4), QuicPacketNumber(8));
- EXPECT_EQ(PACKETS_NEWLY_ACKED,
- manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(2),
- ENCRYPTION_INITIAL));
- EXPECT_EQ(QuicPacketNumber(16), manager_.GetLargestObserved());
-}
-
-TEST_F(QuicSentPacketManagerTest, MultiplePacketNumberSpaces) {
- manager_.EnableMultiplePacketNumberSpacesSupport();
- const QuicUnackedPacketMap* unacked_packets =
- QuicSentPacketManagerPeer::GetUnackedPacketMap(&manager_);
- EXPECT_FALSE(
- unacked_packets
- ->GetLargestSentRetransmittableOfPacketNumberSpace(INITIAL_DATA)
- .IsInitialized());
- EXPECT_FALSE(
- manager_.GetLargestAckedPacket(ENCRYPTION_INITIAL).IsInitialized());
- // Send packet 1.
- SendDataPacket(1, ENCRYPTION_INITIAL);
- EXPECT_EQ(QuicPacketNumber(1),
- unacked_packets->GetLargestSentRetransmittableOfPacketNumberSpace(
- INITIAL_DATA));
- EXPECT_FALSE(
- unacked_packets
- ->GetLargestSentRetransmittableOfPacketNumberSpace(HANDSHAKE_DATA)
- .IsInitialized());
- // Ack packet 1.
- ExpectAck(1);
- 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));
- EXPECT_EQ(QuicPacketNumber(1),
- manager_.GetLargestAckedPacket(ENCRYPTION_INITIAL));
- EXPECT_FALSE(
- manager_.GetLargestAckedPacket(ENCRYPTION_HANDSHAKE).IsInitialized());
- // Send packets 2 and 3.
- SendDataPacket(2, ENCRYPTION_HANDSHAKE);
- SendDataPacket(3, ENCRYPTION_HANDSHAKE);
- EXPECT_EQ(QuicPacketNumber(1),
- unacked_packets->GetLargestSentRetransmittableOfPacketNumberSpace(
- INITIAL_DATA));
- EXPECT_EQ(QuicPacketNumber(3),
- unacked_packets->GetLargestSentRetransmittableOfPacketNumberSpace(
- HANDSHAKE_DATA));
- EXPECT_FALSE(
- unacked_packets
- ->GetLargestSentRetransmittableOfPacketNumberSpace(APPLICATION_DATA)
- .IsInitialized());
- // Ack packet 2.
- ExpectAck(2);
- manager_.OnAckFrameStart(QuicPacketNumber(2), QuicTime::Delta::Infinite(),
- clock_.Now());
- manager_.OnAckRange(QuicPacketNumber(2), QuicPacketNumber(3));
- EXPECT_EQ(PACKETS_NEWLY_ACKED,
- manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(2),
- ENCRYPTION_HANDSHAKE));
- EXPECT_EQ(QuicPacketNumber(2),
- manager_.GetLargestAckedPacket(ENCRYPTION_HANDSHAKE));
- EXPECT_FALSE(
- manager_.GetLargestAckedPacket(ENCRYPTION_ZERO_RTT).IsInitialized());
- // Ack packet 3.
- ExpectAck(3);
- manager_.OnAckFrameStart(QuicPacketNumber(3), QuicTime::Delta::Infinite(),
- clock_.Now());
- manager_.OnAckRange(QuicPacketNumber(2), QuicPacketNumber(4));
- EXPECT_EQ(PACKETS_NEWLY_ACKED,
- manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(3),
- ENCRYPTION_HANDSHAKE));
- EXPECT_EQ(QuicPacketNumber(3),
- manager_.GetLargestAckedPacket(ENCRYPTION_HANDSHAKE));
- EXPECT_FALSE(
- manager_.GetLargestAckedPacket(ENCRYPTION_ZERO_RTT).IsInitialized());
- // Send packets 4 and 5.
- SendDataPacket(4, ENCRYPTION_ZERO_RTT);
- SendDataPacket(5, ENCRYPTION_ZERO_RTT);
- EXPECT_EQ(QuicPacketNumber(1),
- unacked_packets->GetLargestSentRetransmittableOfPacketNumberSpace(
- INITIAL_DATA));
- EXPECT_EQ(QuicPacketNumber(3),
- unacked_packets->GetLargestSentRetransmittableOfPacketNumberSpace(
- HANDSHAKE_DATA));
- EXPECT_EQ(QuicPacketNumber(5),
- unacked_packets->GetLargestSentRetransmittableOfPacketNumberSpace(
- APPLICATION_DATA));
- // Ack packet 5.
- ExpectAck(5);
- manager_.OnAckFrameStart(QuicPacketNumber(5), QuicTime::Delta::Infinite(),
- clock_.Now());
- manager_.OnAckRange(QuicPacketNumber(5), QuicPacketNumber(6));
- EXPECT_EQ(PACKETS_NEWLY_ACKED,
- manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(4),
- ENCRYPTION_FORWARD_SECURE));
- EXPECT_EQ(QuicPacketNumber(3),
- manager_.GetLargestAckedPacket(ENCRYPTION_HANDSHAKE));
- EXPECT_EQ(QuicPacketNumber(5),
- manager_.GetLargestAckedPacket(ENCRYPTION_ZERO_RTT));
- EXPECT_EQ(QuicPacketNumber(5),
- manager_.GetLargestAckedPacket(ENCRYPTION_FORWARD_SECURE));
-
- // Send packets 6 - 8.
- SendDataPacket(6, ENCRYPTION_FORWARD_SECURE);
- SendDataPacket(7, ENCRYPTION_FORWARD_SECURE);
- SendDataPacket(8, ENCRYPTION_FORWARD_SECURE);
- EXPECT_EQ(QuicPacketNumber(1),
- unacked_packets->GetLargestSentRetransmittableOfPacketNumberSpace(
- INITIAL_DATA));
- EXPECT_EQ(QuicPacketNumber(3),
- unacked_packets->GetLargestSentRetransmittableOfPacketNumberSpace(
- HANDSHAKE_DATA));
- EXPECT_EQ(QuicPacketNumber(8),
- unacked_packets->GetLargestSentRetransmittableOfPacketNumberSpace(
- APPLICATION_DATA));
- // Ack all packets.
- uint64_t acked[] = {4, 6, 7, 8};
- ExpectAcksAndLosses(true, acked, ABSL_ARRAYSIZE(acked), nullptr, 0);
- manager_.OnAckFrameStart(QuicPacketNumber(8), QuicTime::Delta::Infinite(),
- clock_.Now());
- manager_.OnAckRange(QuicPacketNumber(4), QuicPacketNumber(9));
- EXPECT_EQ(PACKETS_NEWLY_ACKED,
- manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(5),
- ENCRYPTION_FORWARD_SECURE));
- EXPECT_EQ(QuicPacketNumber(3),
- manager_.GetLargestAckedPacket(ENCRYPTION_HANDSHAKE));
- EXPECT_EQ(QuicPacketNumber(8),
- manager_.GetLargestAckedPacket(ENCRYPTION_ZERO_RTT));
- EXPECT_EQ(QuicPacketNumber(8),
- manager_.GetLargestAckedPacket(ENCRYPTION_FORWARD_SECURE));
-}
-
-TEST_F(QuicSentPacketManagerTest, PacketsGetAckedInWrongPacketNumberSpace) {
- manager_.EnableMultiplePacketNumberSpacesSupport();
- // Send packet 1.
- SendDataPacket(1, ENCRYPTION_INITIAL);
- // Send packets 2 and 3.
- SendDataPacket(2, ENCRYPTION_HANDSHAKE);
- SendDataPacket(3, ENCRYPTION_HANDSHAKE);
-
- // ACK packets 2 and 3 in the wrong packet number space.
- manager_.OnAckFrameStart(QuicPacketNumber(3), QuicTime::Delta::Infinite(),
- clock_.Now());
- manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(4));
- EXPECT_EQ(PACKETS_ACKED_IN_WRONG_PACKET_NUMBER_SPACE,
- manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
- ENCRYPTION_INITIAL));
-}
-
-TEST_F(QuicSentPacketManagerTest, PacketsGetAckedInWrongPacketNumberSpace2) {
- manager_.EnableMultiplePacketNumberSpacesSupport();
- // Send packet 1.
- SendDataPacket(1, ENCRYPTION_INITIAL);
- // Send packets 2 and 3.
- SendDataPacket(2, ENCRYPTION_HANDSHAKE);
- SendDataPacket(3, ENCRYPTION_HANDSHAKE);
-
- // ACK packet 1 in the wrong packet number space.
- manager_.OnAckFrameStart(QuicPacketNumber(3), QuicTime::Delta::Infinite(),
- clock_.Now());
- manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(4));
- EXPECT_EQ(PACKETS_ACKED_IN_WRONG_PACKET_NUMBER_SPACE,
- manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
- ENCRYPTION_HANDSHAKE));
-}
-
-TEST_F(QuicSentPacketManagerTest,
- ToleratePacketsGetAckedInWrongPacketNumberSpace) {
- manager_.EnableMultiplePacketNumberSpacesSupport();
- // Send packet 1.
- SendDataPacket(1, ENCRYPTION_INITIAL);
- // Ack packet 1.
- ExpectAck(1);
- 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));
-
- // Send packets 2 and 3.
- SendDataPacket(2, ENCRYPTION_HANDSHAKE);
- SendDataPacket(3, ENCRYPTION_HANDSHAKE);
-
- // Packet 1 gets acked in the wrong packet number space. Since packet 1 has
- // been acked in the correct packet number space, tolerate it.
- uint64_t acked[] = {2, 3};
- ExpectAcksAndLosses(true, acked, ABSL_ARRAYSIZE(acked), nullptr, 0);
- manager_.OnAckFrameStart(QuicPacketNumber(3), QuicTime::Delta::Infinite(),
- clock_.Now());
- manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(4));
- EXPECT_EQ(PACKETS_NEWLY_ACKED,
- manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(2),
- ENCRYPTION_HANDSHAKE));
-}
-
-// Regression test for b/133771183.
-TEST_F(QuicSentPacketManagerTest, PacketInLimbo) {
- if (GetQuicReloadableFlag(quic_default_on_pto)) {
- 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]() { 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) {
- 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 (GetQuicReloadableFlag(quic_default_on_pto)) {
- 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) { RetransmitDataPacket(11, type); })))
- .WillOnce(WithArgs<1>(Invoke(
- [this](TransmissionType type) { 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())
- .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 =
- srtt + GetPtoRttvarMultiplier() * rtt_stats->mean_deviation() +
- QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
- QuicTime packet1_sent_time = clock_.Now();
- 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.
- QuicTime deadline = clock_.Now() + expected_pto_delay;
- if (GetQuicReloadableFlag(quic_default_on_pto)) {
- // 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);
- EXPECT_EQ(0u, stats_.max_consecutive_rto_with_forward_progress);
-
- // Verify two probe packets get sent.
- EXPECT_CALL(notifier_, RetransmitFrames(_, _))
- .Times(2)
- .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
- RetransmitDataPacket(3, type, ENCRYPTION_FORWARD_SECURE);
- })))
- .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
- RetransmitDataPacket(4, type, ENCRYPTION_FORWARD_SECURE);
- })));
- manager_.MaybeSendProbePackets();
- // Verify PTO period gets set to twice the current value.
- 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.
- EXPECT_EQ(sent_time + expected_pto_delay, manager_.GetRetransmissionTime());
- EXPECT_EQ(1u, stats_.max_consecutive_rto_with_forward_progress);
-}
-
-TEST_F(QuicSentPacketManagerTest, SendOneProbePacket) {
- EnablePto(k1PTO);
- EXPECT_CALL(*send_algorithm_, PacingRate(_))
- .WillRepeatedly(Return(QuicBandwidth::Zero()));
- EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
- .WillRepeatedly(Return(10 * kDefaultTCPMSS));
-
- SendDataPacket(1, ENCRYPTION_FORWARD_SECURE);
- QuicTime packet1_sent_time = clock_.Now();
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
- SendDataPacket(2, ENCRYPTION_FORWARD_SECURE);
-
- 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();
- // Verify PTO period is correctly set.
- QuicTime::Delta expected_pto_delay =
- srtt + GetPtoRttvarMultiplier() * rtt_stats->mean_deviation() +
- QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
- QuicTime deadline = clock_.Now() + expected_pto_delay;
- if (GetQuicReloadableFlag(quic_default_on_pto)) {
- // Verify PTO is set based on left edge.
- deadline = packet1_sent_time + expected_pto_delay;
- }
- EXPECT_EQ(deadline, manager_.GetRetransmissionTime());
-
- // Invoke PTO.
- clock_.AdvanceTime(deadline - clock_.Now());
- manager_.OnRetransmissionTimeout();
- EXPECT_EQ(QuicTime::Delta::Zero(), manager_.TimeUntilSend(clock_.Now()));
-
- // Verify one probe packet gets sent.
- EXPECT_CALL(notifier_, RetransmitFrames(_, _))
- .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
- RetransmitDataPacket(3, type, ENCRYPTION_FORWARD_SECURE);
- })));
- manager_.MaybeSendProbePackets();
-}
-
-TEST_F(QuicSentPacketManagerTest, DisableHandshakeModeClient) {
- QuicSentPacketManagerPeer::SetPerspective(&manager_, Perspective::IS_CLIENT);
- manager_.EnableMultiplePacketNumberSpacesSupport();
- // Send CHLO.
- SendCryptoPacket(1);
- EXPECT_NE(QuicTime::Zero(), manager_.GetRetransmissionTime());
- // Ack packet 1.
- ExpectAck(1);
- 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));
- EXPECT_EQ(0u, manager_.GetBytesInFlight());
- // Verify retransmission timeout is not zero because handshake is not
- // confirmed although there is no in flight packet.
- EXPECT_NE(QuicTime::Zero(), manager_.GetRetransmissionTime());
- // Fire PTO.
- EXPECT_EQ(QuicSentPacketManager::PTO_MODE,
- manager_.OnRetransmissionTimeout());
- // Send handshake packet.
- SendDataPacket(2, ENCRYPTION_HANDSHAKE);
- // Ack packet 2.
- ExpectAck(2);
- manager_.OnAckFrameStart(QuicPacketNumber(2), QuicTime::Delta::Infinite(),
- clock_.Now());
- manager_.OnAckRange(QuicPacketNumber(2), QuicPacketNumber(3));
- EXPECT_EQ(PACKETS_NEWLY_ACKED,
- manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(2),
- ENCRYPTION_HANDSHAKE));
- // Verify retransmission timeout is zero because server has successfully
- // processed HANDSHAKE packet.
- EXPECT_EQ(QuicTime::Zero(), manager_.GetRetransmissionTime());
-}
-
-TEST_F(QuicSentPacketManagerTest, DisableHandshakeModeServer) {
- manager_.EnableIetfPtoAndLossDetection();
- // Send SHLO.
- SendCryptoPacket(1);
- EXPECT_NE(QuicTime::Zero(), manager_.GetRetransmissionTime());
- // Ack packet 1.
- ExpectAck(1);
- 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));
- EXPECT_EQ(0u, manager_.GetBytesInFlight());
- // Verify retransmission timeout is not set on server side because there is
- // nothing in flight.
- EXPECT_EQ(QuicTime::Zero(), manager_.GetRetransmissionTime());
-}
-
-TEST_F(QuicSentPacketManagerTest, PtoTimeoutIncludesMaxAckDelay) {
- 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 (GetQuicReloadableFlag(quic_default_on_pto)) {
- 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) {
- 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) {
- 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 (GetQuicReloadableFlag(quic_default_on_pto)) {
- // 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) {
- RetransmitDataPacket(3, type, ENCRYPTION_FORWARD_SECURE);
- })))
- .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
- 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) {
- RetransmitDataPacket(5, type, ENCRYPTION_FORWARD_SECURE);
- })))
- .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
- 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) {
- RetransmitDataPacket(7, type, ENCRYPTION_FORWARD_SECURE);
- })))
- .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
- 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) {
- RetransmitDataPacket(9, type, ENCRYPTION_FORWARD_SECURE);
- })))
- .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
- 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())
- .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 based on 2 times rtt var.
- QuicTime::Delta expected_pto_delay =
- srtt + 2 * 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 (GetQuicReloadableFlag(quic_default_on_pto)) {
- 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) {
- RetransmitDataPacket(3, type, ENCRYPTION_FORWARD_SECURE);
- })));
- manager_.MaybeRetransmitTailLossProbe();
-
- // 2nd TLP.
- manager_.OnRetransmissionTimeout();
- EXPECT_CALL(notifier_, RetransmitFrames(_, _))
- .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
- 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);
- })));
- manager_.OnRetransmissionTimeout();
-}
-
-TEST_F(QuicSentPacketManagerTest, Aggressive1Pto) {
- 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) {
- 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) {
- 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) {
- 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) {
- 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;
- options.push_back(kBWS5);
- QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
- EXPECT_CALL(*send_algorithm_, SetInitialCongestionWindowInPackets(10));
- EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
- manager_.SetFromConfig(config);
-
- EXPECT_EQ(10u, manager_.initial_congestion_window());
-}
-
-TEST_F(QuicSentPacketManagerTest, ClientMultiplePacketNumberSpacePtoTimeout) {
- manager_.EnableMultiplePacketNumberSpacesSupport();
- EnablePto(k1PTO);
- 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();
- QuicSentPacketManagerPeer::SetPerspective(&manager_, Perspective::IS_CLIENT);
-
- // Send packet 1.
- SendDataPacket(1, ENCRYPTION_INITIAL);
- // Verify PTO is correctly set.
- QuicTime::Delta expected_pto_delay =
- srtt + GetPtoRttvarMultiplier() * rtt_stats->mean_deviation() +
- QuicTime::Delta::Zero();
- EXPECT_EQ(clock_.Now() + expected_pto_delay,
- manager_.GetRetransmissionTime());
-
- // Discard initial key and send packet 2 in handshake.
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
- EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(false));
- manager_.NeuterUnencryptedPackets();
-
- EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(true));
- SendDataPacket(2, ENCRYPTION_HANDSHAKE);
- // Verify PTO is correctly set based on sent time of packet 2.
- 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);
- EXPECT_EQ(1u, stats_.crypto_retransmit_count);
-
- // Verify probe packet gets sent.
- EXPECT_CALL(notifier_, RetransmitFrames(_, _))
- .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
- RetransmitDataPacket(3, type, ENCRYPTION_HANDSHAKE);
- })));
- manager_.MaybeSendProbePackets();
- // 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,
- manager_.GetRetransmissionTime());
-
- // Send packet 4 in application data with 0-RTT.
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
- SendDataPacket(4, ENCRYPTION_ZERO_RTT);
- const QuicTime packet4_sent_time = clock_.Now();
- // Verify PTO timeout is still based on packet 3.
- EXPECT_EQ(packet3_sent_time + expected_pto_delay * 2,
- manager_.GetRetransmissionTime());
-
- // Send packet 5 in handshake.
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
- SendDataPacket(5, ENCRYPTION_HANDSHAKE);
- const QuicTime packet5_sent_time = clock_.Now();
- // Verify PTO timeout is now based on packet 5 because packet 4 should be
- // ignored.
- EXPECT_EQ(clock_.Now() + expected_pto_delay * 2,
- manager_.GetRetransmissionTime());
-
- // Send packet 6 in 1-RTT.
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
- SendDataPacket(6, ENCRYPTION_FORWARD_SECURE);
- // Verify PTO timeout is now based on packet 5.
- EXPECT_EQ(packet5_sent_time + expected_pto_delay * 2,
- manager_.GetRetransmissionTime());
-
- // Send packet 7 in handshake.
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
- const QuicTime packet7_sent_time = clock_.Now();
- SendDataPacket(7, ENCRYPTION_HANDSHAKE);
-
- expected_pto_delay =
- srtt + GetPtoRttvarMultiplier() * rtt_stats->mean_deviation();
- // Verify PTO timeout is now based on packet 7.
- EXPECT_EQ(packet7_sent_time + expected_pto_delay * 2,
- manager_.GetRetransmissionTime());
-
- // Neuter handshake key.
- manager_.SetHandshakeConfirmed();
- // 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() +
- QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
- EXPECT_EQ(packet4_sent_time + expected_pto_delay,
- manager_.GetRetransmissionTime());
-}
-
-TEST_F(QuicSentPacketManagerTest, ServerMultiplePacketNumberSpacePtoTimeout) {
- manager_.EnableMultiplePacketNumberSpacesSupport();
- EnablePto(k1PTO);
- EXPECT_CALL(*send_algorithm_, PacingRate(_))
- .WillRepeatedly(Return(QuicBandwidth::Zero()));
- EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
- .WillRepeatedly(Return(10 * kDefaultTCPMSS));
- RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
- rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(100),
- QuicTime::Delta::Zero(), QuicTime::Zero());
- QuicTime::Delta srtt = rtt_stats->smoothed_rtt();
-
- // Send packet 1.
- SendDataPacket(1, ENCRYPTION_INITIAL);
- const QuicTime packet1_sent_time = clock_.Now();
- // Verify PTO is correctly set.
- QuicTime::Delta expected_pto_delay =
- srtt + GetPtoRttvarMultiplier() * rtt_stats->mean_deviation() +
- QuicTime::Delta::Zero();
- EXPECT_EQ(packet1_sent_time + expected_pto_delay,
- manager_.GetRetransmissionTime());
-
- // Send packet 2 in handshake.
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
- SendDataPacket(2, ENCRYPTION_HANDSHAKE);
- const QuicTime packet2_sent_time = clock_.Now();
- // Verify PTO timeout is still based on packet 1.
- EXPECT_EQ(packet1_sent_time + expected_pto_delay,
- manager_.GetRetransmissionTime());
-
- // Discard initial keys.
- EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(false));
- manager_.NeuterUnencryptedPackets();
-
- // Send packet 3 in 1-RTT.
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
- SendDataPacket(3, ENCRYPTION_FORWARD_SECURE);
- // Verify PTO timeout is based on packet 2.
- const QuicTime packet3_sent_time = clock_.Now();
- EXPECT_EQ(packet2_sent_time + expected_pto_delay,
- manager_.GetRetransmissionTime());
-
- // Send packet 4 in handshake.
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
- SendDataPacket(4, ENCRYPTION_HANDSHAKE);
- // Verify PTO timeout is based on packet 4 as application data is ignored.
- EXPECT_EQ(clock_.Now() + expected_pto_delay,
- manager_.GetRetransmissionTime());
-
- // Discard handshake keys.
- manager_.SetHandshakeConfirmed();
- expected_pto_delay =
- srtt + GetPtoRttvarMultiplier() * rtt_stats->mean_deviation() +
- QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
- // Verify PTO timeout is now based on packet 3 as handshake is
- // complete/confirmed.
- EXPECT_EQ(packet3_sent_time + expected_pto_delay,
- manager_.GetRetransmissionTime());
-}
-
-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()));
- 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 =
- srtt + GetPtoRttvarMultiplier() * rtt_stats->mean_deviation() +
- QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
- const QuicTime packet1_sent_time = clock_.Now();
- EXPECT_EQ(packet1_sent_time + expected_pto_delay,
- manager_.GetRetransmissionTime());
-
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
- SendDataPacket(2, ENCRYPTION_FORWARD_SECURE);
- // Verify PTO is still based on packet 1.
- EXPECT_EQ(packet1_sent_time + expected_pto_delay,
- manager_.GetRetransmissionTime());
- EXPECT_EQ(0u, stats_.pto_count);
-
- // Invoke PTO.
- clock_.AdvanceTime(expected_pto_delay);
- manager_.OnRetransmissionTimeout();
- EXPECT_EQ(QuicTime::Delta::Zero(), manager_.TimeUntilSend(clock_.Now()));
- EXPECT_EQ(1u, stats_.pto_count);
-
- EXPECT_CALL(notifier_, RetransmitFrames(_, _))
- .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
- RetransmitDataPacket(3, type, ENCRYPTION_FORWARD_SECURE);
- })));
- manager_.MaybeSendProbePackets();
- // 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,
- 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.
- EXPECT_EQ(packet3_sent_time + expected_pto_delay,
- manager_.GetRetransmissionTime());
-}
-
-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()));
- 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 =
- srtt + GetPtoRttvarMultiplier() * rtt_stats->mean_deviation() +
- QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
- const QuicTime packet1_sent_time = clock_.Now();
- EXPECT_EQ(packet1_sent_time + expected_pto_delay,
- manager_.GetRetransmissionTime());
-
- // Sent a packet 10ms before PTO expiring.
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(
- 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();
- EXPECT_EQ(clock_.Now() + expected_pto_delay,
- manager_.GetRetransmissionTime());
- EXPECT_EQ(0u, stats_.pto_count);
-
- // Invoke PTO.
- clock_.AdvanceTime(expected_pto_delay);
- manager_.OnRetransmissionTimeout();
- EXPECT_EQ(QuicTime::Delta::Zero(), manager_.TimeUntilSend(clock_.Now()));
- EXPECT_EQ(1u, stats_.pto_count);
-
- EXPECT_CALL(notifier_, RetransmitFrames(_, _))
- .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
- RetransmitDataPacket(3, type, ENCRYPTION_FORWARD_SECURE);
- })));
- manager_.MaybeSendProbePackets();
- // 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() +
- QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
- QuicTime packet3_sent_time = clock_.Now();
- EXPECT_EQ(packet3_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 3 (left
- // edge).
- EXPECT_EQ(packet3_sent_time + expected_pto_delay,
- manager_.GetRetransmissionTime());
-}
-
-TEST_F(QuicSentPacketManagerTest, ComputingProbeTimeoutUsingStandardDeviation) {
- 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()));
- EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
- .WillRepeatedly(Return(10 * kDefaultTCPMSS));
- RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
- rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(100),
- QuicTime::Delta::Zero(), QuicTime::Zero());
- QuicTime::Delta srtt = rtt_stats->smoothed_rtt();
-
- // Send packet 1.
- SendDataPacket(1, ENCRYPTION_INITIAL);
- const QuicTime packet1_sent_time = clock_.Now();
- // Verify PTO is correctly set.
- QuicTime::Delta expected_pto_delay =
- srtt + GetPtoRttvarMultiplier() * rtt_stats->mean_deviation() +
- QuicTime::Delta::Zero();
- EXPECT_EQ(packet1_sent_time + expected_pto_delay,
- manager_.GetRetransmissionTime());
-
- // Send packet 2 in handshake.
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
- SendDataPacket(2, ENCRYPTION_HANDSHAKE);
- const QuicTime packet2_sent_time = clock_.Now();
- // Verify PTO timeout is still based on packet 1.
- EXPECT_EQ(packet1_sent_time + expected_pto_delay,
- manager_.GetRetransmissionTime());
-
- // Discard initial keys.
- EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(false));
- manager_.NeuterUnencryptedPackets();
-
- // Send packet 3 in 1-RTT.
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
- SendDataPacket(3, ENCRYPTION_FORWARD_SECURE);
- // Verify PTO timeout is based on packet 2.
- const QuicTime packet3_sent_time = clock_.Now();
- EXPECT_EQ(packet2_sent_time + expected_pto_delay,
- manager_.GetRetransmissionTime());
-
- // Send packet 4 in handshake.
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
- SendDataPacket(4, ENCRYPTION_HANDSHAKE);
- // Verify PTO timeout is based on packet 4 as application data is ignored.
- EXPECT_EQ(clock_.Now() + expected_pto_delay,
- manager_.GetRetransmissionTime());
-
- // Discard handshake keys.
- manager_.SetHandshakeConfirmed();
- // Verify PTO timeout is now based on packet 3 as handshake is
- // complete/confirmed.
- expected_pto_delay =
- srtt + GetPtoRttvarMultiplier() * rtt_stats->mean_deviation() +
- QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
- EXPECT_EQ(packet3_sent_time + expected_pto_delay,
- manager_.GetRetransmissionTime());
-
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
- SendDataPacket(5, ENCRYPTION_FORWARD_SECURE);
- // Verify PTO timeout is still based on packet 3.
- EXPECT_EQ(packet3_sent_time + expected_pto_delay,
- manager_.GetRetransmissionTime());
-}
-
-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()));
- EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
- .WillRepeatedly(Return(10 * kDefaultTCPMSS));
- RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
- rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(100),
- QuicTime::Delta::Zero(), QuicTime::Zero());
- QuicTime::Delta srtt = rtt_stats->smoothed_rtt();
-
- // Send packet 1.
- SendDataPacket(1, ENCRYPTION_INITIAL);
- const QuicTime packet1_sent_time = clock_.Now();
- // Verify PTO is correctly set.
- QuicTime::Delta expected_pto_delay =
- srtt + GetPtoRttvarMultiplier() * rtt_stats->mean_deviation() +
- QuicTime::Delta::Zero();
- EXPECT_EQ(packet1_sent_time + expected_pto_delay,
- manager_.GetRetransmissionTime());
-
- // Send packet 2 in handshake.
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
- SendDataPacket(2, ENCRYPTION_HANDSHAKE);
- const QuicTime packet2_sent_time = clock_.Now();
- // Verify PTO timeout is still based on packet 1.
- EXPECT_EQ(packet1_sent_time + expected_pto_delay,
- manager_.GetRetransmissionTime());
-
- // Discard initial keys.
- EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(false));
- manager_.NeuterUnencryptedPackets();
-
- // Send packet 3 in 1-RTT.
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
- SendDataPacket(3, ENCRYPTION_FORWARD_SECURE);
- // Verify PTO timeout is based on packet 2.
- const QuicTime packet3_sent_time = clock_.Now();
- EXPECT_EQ(packet2_sent_time + expected_pto_delay,
- manager_.GetRetransmissionTime());
-
- // Send packet 4 in handshake.
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
- SendDataPacket(4, ENCRYPTION_HANDSHAKE);
- // Verify PTO timeout is based on packet 4 as application data is ignored.
- EXPECT_EQ(clock_.Now() + expected_pto_delay,
- manager_.GetRetransmissionTime());
-
- // Discard handshake keys.
- manager_.SetHandshakeConfirmed();
- // Verify PTO timeout is now based on packet 3 as handshake is
- // complete/confirmed.
- expected_pto_delay =
- srtt + GetPtoRttvarMultiplier() * rtt_stats->mean_deviation() +
- QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
- EXPECT_EQ(packet3_sent_time + expected_pto_delay,
- manager_.GetRetransmissionTime());
-
- // Send packet 5 10ms before PTO expiring.
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(
- 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(),
- manager_.GetRetransmissionTime());
-}
-
-TEST_F(QuicSentPacketManagerTest, SetHandshakeConfirmed) {
- QuicSentPacketManagerPeer::SetPerspective(&manager_, Perspective::IS_CLIENT);
- manager_.EnableMultiplePacketNumberSpacesSupport();
-
- SendDataPacket(1, ENCRYPTION_INITIAL);
-
- SendDataPacket(2, ENCRYPTION_HANDSHAKE);
-
- EXPECT_CALL(notifier_, OnFrameAcked(_, _, _))
- .WillOnce(
- Invoke([](const QuicFrame& /*frame*/, QuicTime::Delta ack_delay_time,
- QuicTime receive_timestamp) {
- EXPECT_TRUE(ack_delay_time.IsZero());
- EXPECT_EQ(receive_timestamp, QuicTime::Zero());
- return true;
- }));
-
- EXPECT_CALL(*send_algorithm_, OnPacketNeutered(QuicPacketNumber(2))).Times(1);
- manager_.SetHandshakeConfirmed();
-}
-
-// Regresstion test for b/148841700.
-TEST_F(QuicSentPacketManagerTest, NeuterUnencryptedPackets) {
- SendCryptoPacket(1);
- SendPingPacket(2, ENCRYPTION_INITIAL);
- // Crypto data has been discarded but ping does not.
- EXPECT_CALL(notifier_, OnFrameAcked(_, _, _))
- .Times(2)
- .WillOnce(Return(false))
- .WillOnce(Return(true));
- EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(false));
-
- EXPECT_CALL(*send_algorithm_, OnPacketNeutered(QuicPacketNumber(1))).Times(1);
- manager_.NeuterUnencryptedPackets();
-}
-
-TEST_F(QuicSentPacketManagerTest, MarkInitialPacketsForRetransmission) {
- SendCryptoPacket(1);
- SendPingPacket(2, ENCRYPTION_HANDSHAKE);
- // Only the INITIAL packet will be retransmitted.
- EXPECT_CALL(notifier_, OnFrameLost(_)).Times(1);
- manager_.MarkInitialPacketsForRetransmission();
-}
-
-TEST_F(QuicSentPacketManagerTest, NoPacketThresholdDetectionForRuntPackets) {
- EXPECT_TRUE(
- QuicSentPacketManagerPeer::UsePacketThresholdForRuntPackets(&manager_));
-
- QuicConfig config;
- QuicTagVector options;
- options.push_back(kRUNT);
- QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
- EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
- manager_.SetFromConfig(config);
-
- EXPECT_FALSE(
- QuicSentPacketManagerPeer::UsePacketThresholdForRuntPackets(&manager_));
-}
-
-TEST_F(QuicSentPacketManagerTest, GetPathDegradingDelay) {
- 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, 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());
-}
-
-TEST_F(QuicSentPacketManagerTest, ClientsIgnorePings) {
- QuicSentPacketManagerPeer::SetPerspective(&manager_, Perspective::IS_CLIENT);
- QuicConfig client_config;
- QuicTagVector options;
- QuicTagVector client_options;
- client_options.push_back(kIGNP);
- 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_CALL(*send_algorithm_, PacingRate(_))
- .WillRepeatedly(Return(QuicBandwidth::Zero()));
- EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
- .WillRepeatedly(Return(10 * kDefaultTCPMSS));
- EXPECT_CALL(*send_algorithm_, CanSend(_)).WillRepeatedly(Return(true));
-
- SendPingPacket(1, ENCRYPTION_INITIAL);
- // Verify PING only packet is not considered in flight.
- EXPECT_EQ(QuicTime::Zero(), manager_.GetRetransmissionTime());
- SendDataPacket(2, ENCRYPTION_INITIAL);
- EXPECT_NE(QuicTime::Zero(), manager_.GetRetransmissionTime());
-
- uint64_t acked[] = {1};
- ExpectAcksAndLosses(/*rtt_updated=*/false, acked, ABSL_ARRAYSIZE(acked),
- nullptr, 0);
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(90));
- manager_.OnAckFrameStart(QuicPacketNumber(1), QuicTime::Delta::Infinite(),
- clock_.Now());
- manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
- EXPECT_EQ(PACKETS_NEWLY_ACKED,
- manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
- ENCRYPTION_INITIAL));
- RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
- // Verify no RTT samples for PING only packet.
- EXPECT_TRUE(rtt_stats->smoothed_rtt().IsZero());
-
- ExpectAck(2);
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
- 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(2),
- ENCRYPTION_INITIAL));
- EXPECT_EQ(QuicTime::Delta::FromMilliseconds(100), rtt_stats->smoothed_rtt());
-}
-
-// Regression test for b/154050235.
-TEST_F(QuicSentPacketManagerTest, ExponentialBackoffWithNoRttMeasurement) {
- QuicSentPacketManagerPeer::SetPerspective(&manager_, Perspective::IS_CLIENT);
- manager_.EnableMultiplePacketNumberSpacesSupport();
- RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
- EXPECT_EQ(QuicTime::Delta::FromMilliseconds(kInitialRttMs),
- rtt_stats->initial_rtt());
- EXPECT_TRUE(rtt_stats->smoothed_rtt().IsZero());
-
- SendCryptoPacket(1);
- QuicTime::Delta expected_pto_delay =
- QuicTime::Delta::FromMilliseconds(3 * kInitialRttMs);
- EXPECT_EQ(clock_.Now() + expected_pto_delay,
- manager_.GetRetransmissionTime());
-
- // Invoke PTO.
- clock_.AdvanceTime(expected_pto_delay);
- manager_.OnRetransmissionTimeout();
-
- EXPECT_CALL(notifier_, RetransmitFrames(_, _))
- .WillOnce(WithArgs<1>(Invoke([this]() { RetransmitCryptoPacket(3); })));
- manager_.MaybeSendProbePackets();
- if (GetQuicReloadableFlag(quic_default_on_pto)) {
- manager_.AdjustPendingTimerTransmissions();
- }
- // Verify exponential backoff of the PTO timeout.
- EXPECT_EQ(clock_.Now() + 2 * expected_pto_delay,
- manager_.GetRetransmissionTime());
-}
-
-TEST_F(QuicSentPacketManagerTest, PtoDelayWithTinyInitialRtt) {
- manager_.EnableMultiplePacketNumberSpacesSupport();
- RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
- // Assume client provided a tiny initial RTT.
- rtt_stats->set_initial_rtt(QuicTime::Delta::FromMicroseconds(1));
- EXPECT_EQ(QuicTime::Delta::FromMicroseconds(1), rtt_stats->initial_rtt());
- EXPECT_TRUE(rtt_stats->smoothed_rtt().IsZero());
-
- SendCryptoPacket(1);
- QuicTime::Delta expected_pto_delay = QuicTime::Delta::FromMilliseconds(10);
- // Verify kMinHandshakeTimeoutMs is respected.
- EXPECT_EQ(clock_.Now() + expected_pto_delay,
- manager_.GetRetransmissionTime());
-
- // Invoke PTO.
- clock_.AdvanceTime(expected_pto_delay);
- manager_.OnRetransmissionTimeout();
-
- EXPECT_CALL(notifier_, RetransmitFrames(_, _))
- .WillOnce(WithArgs<1>(Invoke([this]() { RetransmitCryptoPacket(3); })));
- manager_.MaybeSendProbePackets();
- if (GetQuicReloadableFlag(quic_default_on_pto)) {
- manager_.AdjustPendingTimerTransmissions();
- }
- // Verify exponential backoff of the PTO timeout.
- EXPECT_EQ(clock_.Now() + 2 * expected_pto_delay,
- manager_.GetRetransmissionTime());
-}
-
-TEST_F(QuicSentPacketManagerTest, HandshakeAckCausesInitialKeyDropping) {
- manager_.EnableMultiplePacketNumberSpacesSupport();
- QuicSentPacketManagerPeer::SetPerspective(&manager_, Perspective::IS_CLIENT);
- // Send INITIAL packet 1.
- SendDataPacket(1, ENCRYPTION_INITIAL);
- QuicTime::Delta expected_pto_delay =
- QuicTime::Delta::FromMilliseconds(3 * kInitialRttMs);
- EXPECT_EQ(clock_.Now() + expected_pto_delay,
- manager_.GetRetransmissionTime());
- // Send HANDSHAKE ack.
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
- SendAckPacket(2, /*largest_acked=*/1, ENCRYPTION_HANDSHAKE);
- // Sending HANDSHAKE packet causes dropping of INITIAL key.
- EXPECT_CALL(notifier_, HasUnackedCryptoData()).WillRepeatedly(Return(false));
- EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(false));
- manager_.NeuterUnencryptedPackets();
- // There is no in flight packets.
- EXPECT_FALSE(manager_.HasInFlightPackets());
- // Verify PTO timer gets rearmed from now because of anti-amplification.
- EXPECT_EQ(clock_.Now() + expected_pto_delay,
- manager_.GetRetransmissionTime());
-
- // Invoke PTO.
- clock_.AdvanceTime(expected_pto_delay);
- manager_.OnRetransmissionTimeout();
- // Verify nothing to probe (and connection will send PING for current
- // encryption level).
- EXPECT_CALL(notifier_, RetransmitFrames(_, _)).Times(0);
- manager_.MaybeSendProbePackets();
-}
-
-// Regression test for b/156487311
-TEST_F(QuicSentPacketManagerTest, ClearLastInflightPacketsSentTime) {
- manager_.EnableMultiplePacketNumberSpacesSupport();
- EXPECT_CALL(*send_algorithm_, PacingRate(_))
- .WillRepeatedly(Return(QuicBandwidth::Zero()));
- EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
- .WillRepeatedly(Return(10 * kDefaultTCPMSS));
-
- // Send INITIAL 1.
- SendDataPacket(1, ENCRYPTION_INITIAL);
- // Send HANDSHAKE 2.
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
- SendDataPacket(2, ENCRYPTION_HANDSHAKE);
- SendDataPacket(3, ENCRYPTION_HANDSHAKE);
- SendDataPacket(4, ENCRYPTION_HANDSHAKE);
- const QuicTime packet2_sent_time = clock_.Now();
-
- // Send half RTT 5.
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
- SendDataPacket(5, ENCRYPTION_FORWARD_SECURE);
-
- // Received ACK for INITIAL 1.
- ExpectAck(1);
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(90));
- manager_.OnAckFrameStart(QuicPacketNumber(1), QuicTime::Delta::Infinite(),
- clock_.Now());
- manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
- EXPECT_EQ(PACKETS_NEWLY_ACKED,
- manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
- ENCRYPTION_INITIAL));
- RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
- const QuicTime::Delta pto_delay =
- rtt_stats->smoothed_rtt() +
- GetPtoRttvarMultiplier() * 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) {
- 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(_))
- .WillRepeatedly(Return(QuicBandwidth::Zero()));
- EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
- .WillRepeatedly(Return(10 * kDefaultTCPMSS));
- RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
- rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(100),
- QuicTime::Delta::Zero(), QuicTime::Zero());
- QuicTime::Delta srtt = rtt_stats->smoothed_rtt();
-
- // Send packet 1.
- SendDataPacket(1, ENCRYPTION_INITIAL);
- QuicTime packet1_sent_time = clock_.Now();
-
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
- // Send packets 2 and 3.
- SendDataPacket(2, ENCRYPTION_HANDSHAKE);
- QuicTime packet2_sent_time = clock_.Now();
- SendDataPacket(3, ENCRYPTION_HANDSHAKE);
- // Verify PTO is correctly set based on packet 1.
- QuicTime::Delta expected_pto_delay =
- srtt + GetPtoRttvarMultiplier() * rtt_stats->mean_deviation() +
- QuicTime::Delta::Zero();
- EXPECT_EQ(packet1_sent_time + expected_pto_delay,
- manager_.GetRetransmissionTime());
-
- // Assume connection is going to send INITIAL ACK.
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
- EXPECT_CALL(notifier_, RetransmitFrames(_, _))
- .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
- RetransmitDataPacket(4, type, ENCRYPTION_INITIAL);
- })));
- manager_.RetransmitDataOfSpaceIfAny(INITIAL_DATA);
- // Verify PTO is re-armed based on packet 2.
- EXPECT_EQ(packet2_sent_time + expected_pto_delay,
- manager_.GetRetransmissionTime());
-
- // Connection is going to send another INITIAL ACK.
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
- EXPECT_CALL(notifier_, RetransmitFrames(_, _))
- .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
- RetransmitDataPacket(5, type, ENCRYPTION_INITIAL);
- })));
- manager_.RetransmitDataOfSpaceIfAny(INITIAL_DATA);
- // Verify PTO does not change.
- EXPECT_EQ(packet2_sent_time + expected_pto_delay,
- manager_.GetRetransmissionTime());
-}
-
-TEST_F(QuicSentPacketManagerTest,
- AggressivePtoBeforeAnyRttSamplesAreAvailable) {
- manager_.EnableMultiplePacketNumberSpacesSupport();
- EXPECT_CALL(*send_algorithm_, PacingRate(_))
- .WillRepeatedly(Return(QuicBandwidth::Zero()));
- EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
- .WillRepeatedly(Return(10 * kDefaultTCPMSS));
- RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
-
- QuicConfig config;
- QuicTagVector options;
- options.push_back(kAPTO);
- QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
- EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
- manager_.SetFromConfig(config);
-
- // Send INITIAL 1.
- SendDataPacket(1, ENCRYPTION_INITIAL);
- // Verify retransmission timeout is expected.
- EXPECT_EQ(clock_.Now() + 1.5 * rtt_stats->initial_rtt(),
- manager_.GetRetransmissionTime());
-}
-
-TEST_F(QuicSentPacketManagerTest, SendPathChallengeAndGetAck) {
- QuicPacketNumber packet_number(1);
- EXPECT_CALL(*send_algorithm_,
- OnPacketSent(_, BytesInFlight(), packet_number, _, _));
- SerializedPacket packet(packet_number, PACKET_4BYTE_PACKET_NUMBER, nullptr,
- kDefaultLength, false, false);
- QuicPathFrameBuffer path_frame_buffer{0, 1, 2, 3, 4, 5, 6, 7};
- packet.nonretransmittable_frames.push_back(
- QuicFrame(new QuicPathChallengeFrame(0, path_frame_buffer)));
- packet.encryption_level = ENCRYPTION_FORWARD_SECURE;
- manager_.OnPacketSent(&packet, clock_.Now(), NOT_RETRANSMISSION,
- NO_RETRANSMITTABLE_DATA, false);
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
- EXPECT_CALL(*send_algorithm_,
- OnCongestionEvent(/*rtt_updated=*/false, _, _,
- Pointwise(PacketNumberEq(), {1}), IsEmpty()));
- EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
-
- // Get ACK for the packet.
- 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_FORWARD_SECURE));
-}
-
-SerializedPacket MakePacketWithAckFrequencyFrame(
- int packet_number,
- int ack_frequency_sequence_number,
- QuicTime::Delta max_ack_delay) {
- auto* ack_frequency_frame = new QuicAckFrequencyFrame();
- ack_frequency_frame->max_ack_delay = max_ack_delay;
- ack_frequency_frame->sequence_number = ack_frequency_sequence_number;
- SerializedPacket packet(QuicPacketNumber(packet_number),
- PACKET_4BYTE_PACKET_NUMBER, nullptr, kDefaultLength,
- /*has_ack=*/false,
- /*has_stop_waiting=*/false);
- packet.retransmittable_frames.push_back(QuicFrame(ack_frequency_frame));
- packet.has_ack_frequency = true;
- packet.encryption_level = ENCRYPTION_FORWARD_SECURE;
- return packet;
-}
-
-TEST_F(QuicSentPacketManagerTest,
- PeerMaxAckDelayUpdatedFromAckFrequencyFrameOneAtATime) {
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AnyNumber());
- EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _))
- .Times(AnyNumber());
- EXPECT_CALL(*network_change_visitor_, OnCongestionChange())
- .Times(AnyNumber());
-
- auto initial_peer_max_ack_delay = manager_.peer_max_ack_delay();
- auto one_ms = QuicTime::Delta::FromMilliseconds(1);
- auto plus_1_ms_delay = initial_peer_max_ack_delay + one_ms;
- auto minus_1_ms_delay = initial_peer_max_ack_delay - one_ms;
-
- // Send and Ack frame1.
- SerializedPacket packet1 = MakePacketWithAckFrequencyFrame(
- /*packet_number=*/1, /*ack_frequency_sequence_number=*/1,
- plus_1_ms_delay);
- // Higher on the fly max_ack_delay changes peer_max_ack_delay.
- manager_.OnPacketSent(&packet1, clock_.Now(), NOT_RETRANSMISSION,
- HAS_RETRANSMITTABLE_DATA, /*measure_rtt=*/true);
- EXPECT_EQ(manager_.peer_max_ack_delay(), plus_1_ms_delay);
- manager_.OnAckFrameStart(QuicPacketNumber(1), QuicTime::Delta::Infinite(),
- clock_.Now());
- manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
- manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
- ENCRYPTION_FORWARD_SECURE);
- EXPECT_EQ(manager_.peer_max_ack_delay(), plus_1_ms_delay);
-
- // Send and Ack frame2.
- SerializedPacket packet2 = MakePacketWithAckFrequencyFrame(
- /*packet_number=*/2, /*ack_frequency_sequence_number=*/2,
- minus_1_ms_delay);
- // Lower on the fly max_ack_delay does not change peer_max_ack_delay.
- manager_.OnPacketSent(&packet2, clock_.Now(), NOT_RETRANSMISSION,
- HAS_RETRANSMITTABLE_DATA, /*measure_rtt=*/true);
- EXPECT_EQ(manager_.peer_max_ack_delay(), plus_1_ms_delay);
- manager_.OnAckFrameStart(QuicPacketNumber(2), QuicTime::Delta::Infinite(),
- clock_.Now());
- manager_.OnAckRange(QuicPacketNumber(2), QuicPacketNumber(3));
- manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(2),
- ENCRYPTION_FORWARD_SECURE);
- EXPECT_EQ(manager_.peer_max_ack_delay(), minus_1_ms_delay);
-}
-
-TEST_F(QuicSentPacketManagerTest,
- PeerMaxAckDelayUpdatedFromInOrderAckFrequencyFrames) {
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AnyNumber());
- EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _))
- .Times(AnyNumber());
- EXPECT_CALL(*network_change_visitor_, OnCongestionChange())
- .Times(AnyNumber());
-
- auto initial_peer_max_ack_delay = manager_.peer_max_ack_delay();
- auto one_ms = QuicTime::Delta::FromMilliseconds(1);
- auto extra_1_ms = initial_peer_max_ack_delay + one_ms;
- auto extra_2_ms = initial_peer_max_ack_delay + 2 * one_ms;
- auto extra_3_ms = initial_peer_max_ack_delay + 3 * one_ms;
- SerializedPacket packet1 = MakePacketWithAckFrequencyFrame(
- /*packet_number=*/1, /*ack_frequency_sequence_number=*/1, extra_1_ms);
- SerializedPacket packet2 = MakePacketWithAckFrequencyFrame(
- /*packet_number=*/2, /*ack_frequency_sequence_number=*/2, extra_3_ms);
- SerializedPacket packet3 = MakePacketWithAckFrequencyFrame(
- /*packet_number=*/3, /*ack_frequency_sequence_number=*/3, extra_2_ms);
-
- // Send frame1, farme2, frame3.
- manager_.OnPacketSent(&packet1, clock_.Now(), NOT_RETRANSMISSION,
- HAS_RETRANSMITTABLE_DATA, /*measure_rtt=*/true);
- EXPECT_EQ(manager_.peer_max_ack_delay(), extra_1_ms);
- manager_.OnPacketSent(&packet2, clock_.Now(), NOT_RETRANSMISSION,
- HAS_RETRANSMITTABLE_DATA, /*measure_rtt=*/true);
- EXPECT_EQ(manager_.peer_max_ack_delay(), extra_3_ms);
- manager_.OnPacketSent(&packet3, clock_.Now(), NOT_RETRANSMISSION,
- HAS_RETRANSMITTABLE_DATA, /*measure_rtt=*/true);
- EXPECT_EQ(manager_.peer_max_ack_delay(), extra_3_ms);
-
- // Ack frame1, farme2, frame3.
- manager_.OnAckFrameStart(QuicPacketNumber(1), QuicTime::Delta::Infinite(),
- clock_.Now());
- manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
- manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
- ENCRYPTION_FORWARD_SECURE);
- EXPECT_EQ(manager_.peer_max_ack_delay(), extra_3_ms);
- manager_.OnAckFrameStart(QuicPacketNumber(2), QuicTime::Delta::Infinite(),
- clock_.Now());
- manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(3));
- manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
- ENCRYPTION_FORWARD_SECURE);
- EXPECT_EQ(manager_.peer_max_ack_delay(), extra_3_ms);
- manager_.OnAckFrameStart(QuicPacketNumber(3), QuicTime::Delta::Infinite(),
- clock_.Now());
- manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(4));
- manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
- ENCRYPTION_FORWARD_SECURE);
- EXPECT_EQ(manager_.peer_max_ack_delay(), extra_2_ms);
-}
-
-TEST_F(QuicSentPacketManagerTest,
- PeerMaxAckDelayUpdatedFromOutOfOrderAckedAckFrequencyFrames) {
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AnyNumber());
- EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _))
- .Times(AnyNumber());
- EXPECT_CALL(*network_change_visitor_, OnCongestionChange())
- .Times(AnyNumber());
-
- auto initial_peer_max_ack_delay = manager_.peer_max_ack_delay();
- auto one_ms = QuicTime::Delta::FromMilliseconds(1);
- auto extra_1_ms = initial_peer_max_ack_delay + one_ms;
- auto extra_2_ms = initial_peer_max_ack_delay + 2 * one_ms;
- auto extra_3_ms = initial_peer_max_ack_delay + 3 * one_ms;
- auto extra_4_ms = initial_peer_max_ack_delay + 4 * one_ms;
- SerializedPacket packet1 = MakePacketWithAckFrequencyFrame(
- /*packet_number=*/1, /*ack_frequency_sequence_number=*/1, extra_4_ms);
- SerializedPacket packet2 = MakePacketWithAckFrequencyFrame(
- /*packet_number=*/2, /*ack_frequency_sequence_number=*/2, extra_3_ms);
- SerializedPacket packet3 = MakePacketWithAckFrequencyFrame(
- /*packet_number=*/3, /*ack_frequency_sequence_number=*/3, extra_2_ms);
- SerializedPacket packet4 = MakePacketWithAckFrequencyFrame(
- /*packet_number=*/4, /*ack_frequency_sequence_number=*/4, extra_1_ms);
-
- // Send frame1, farme2, frame3, frame4.
- manager_.OnPacketSent(&packet1, clock_.Now(), NOT_RETRANSMISSION,
- HAS_RETRANSMITTABLE_DATA, /*measure_rtt=*/true);
- manager_.OnPacketSent(&packet2, clock_.Now(), NOT_RETRANSMISSION,
- HAS_RETRANSMITTABLE_DATA, /*measure_rtt=*/true);
- manager_.OnPacketSent(&packet3, clock_.Now(), NOT_RETRANSMISSION,
- HAS_RETRANSMITTABLE_DATA, /*measure_rtt=*/true);
- manager_.OnPacketSent(&packet4, clock_.Now(), NOT_RETRANSMISSION,
- NO_RETRANSMITTABLE_DATA, /*measure_rtt=*/true);
- EXPECT_EQ(manager_.peer_max_ack_delay(), extra_4_ms);
-
- // Ack frame3.
- manager_.OnAckFrameStart(QuicPacketNumber(3), QuicTime::Delta::Infinite(),
- clock_.Now());
- manager_.OnAckRange(QuicPacketNumber(3), QuicPacketNumber(4));
- manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
- ENCRYPTION_FORWARD_SECURE);
- EXPECT_EQ(manager_.peer_max_ack_delay(), extra_2_ms);
- // Acking frame1 do not affect peer_max_ack_delay after frame3 is acked.
- manager_.OnAckFrameStart(QuicPacketNumber(3), QuicTime::Delta::Infinite(),
- clock_.Now());
- manager_.OnAckRange(QuicPacketNumber(3), QuicPacketNumber(4));
- manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
- manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
- ENCRYPTION_FORWARD_SECURE);
- EXPECT_EQ(manager_.peer_max_ack_delay(), extra_2_ms);
- // Acking frame2 do not affect peer_max_ack_delay after frame3 is acked.
- manager_.OnAckFrameStart(QuicPacketNumber(3), QuicTime::Delta::Infinite(),
- clock_.Now());
- manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(4));
- manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
- ENCRYPTION_FORWARD_SECURE);
- EXPECT_EQ(manager_.peer_max_ack_delay(), extra_2_ms);
- // Acking frame4 updates peer_max_ack_delay.
- manager_.OnAckFrameStart(QuicPacketNumber(4), QuicTime::Delta::Infinite(),
- clock_.Now());
- manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(5));
- manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
- ENCRYPTION_FORWARD_SECURE);
- EXPECT_EQ(manager_.peer_max_ack_delay(), extra_1_ms);
-}
-
-TEST_F(QuicSentPacketManagerTest, ClearDataInMessageFrameAfterPacketSent) {
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
-
- QuicMessageFrame* message_frame = nullptr;
- {
- QuicMemSlice slice(MakeUniqueBuffer(&allocator_, 1024), 1024);
- message_frame = new QuicMessageFrame(/*message_id=*/1, std::move(slice));
- EXPECT_FALSE(message_frame->message_data.empty());
- EXPECT_EQ(message_frame->message_length, 1024);
-
- SerializedPacket packet(QuicPacketNumber(1), PACKET_4BYTE_PACKET_NUMBER,
- /*encrypted_buffer=*/nullptr, kDefaultLength,
- /*has_ack=*/false,
- /*has_stop_waiting*/ false);
- packet.encryption_level = ENCRYPTION_FORWARD_SECURE;
- packet.retransmittable_frames.push_back(QuicFrame(message_frame));
- packet.has_message = true;
- manager_.OnPacketSent(&packet, clock_.Now(), NOT_RETRANSMISSION,
- HAS_RETRANSMITTABLE_DATA, /*measure_rtt=*/true);
- }
-
- EXPECT_TRUE(message_frame->message_data.empty());
- EXPECT_EQ(message_frame->message_length, 0);
-}
-
-TEST_F(QuicSentPacketManagerTest, BuildAckFrequencyFrame) {
- SetQuicReloadableFlag(quic_can_send_ack_frequency, true);
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
- EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
- QuicConfig config;
- QuicConfigPeer::SetReceivedMinAckDelayMs(&config, /*min_ack_delay_ms=*/1);
- manager_.SetFromConfig(config);
- manager_.SetHandshakeConfirmed();
-
- // Set up RTTs.
- auto* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
- rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(80),
- /*ack_delay=*/QuicTime::Delta::Zero(),
- /*now=*/QuicTime::Zero());
- // Make sure srtt and min_rtt are different.
- rtt_stats->UpdateRtt(
- QuicTime::Delta::FromMilliseconds(160),
- /*ack_delay=*/QuicTime::Delta::Zero(),
- /*now=*/QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(24));
-
- auto frame = manager_.GetUpdatedAckFrequencyFrame();
- EXPECT_EQ(frame.max_ack_delay,
- std::max(rtt_stats->min_rtt() * 0.25,
- QuicTime::Delta::FromMilliseconds(1u)));
- EXPECT_EQ(frame.packet_tolerance, 10u);
-}
-
-TEST_F(QuicSentPacketManagerTest, SmoothedRttIgnoreAckDelay) {
- QuicConfig config;
- QuicTagVector options;
- options.push_back(kMAD0);
- QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
- EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
- EXPECT_CALL(*send_algorithm_, CanSend(_)).WillRepeatedly(Return(true));
- EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
- .WillRepeatedly(Return(10 * kDefaultTCPMSS));
- manager_.SetFromConfig(config);
-
- SendDataPacket(1);
- // Ack 1.
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(300));
- ExpectAck(1);
- manager_.OnAckFrameStart(QuicPacketNumber(1),
- QuicTime::Delta::FromMilliseconds(100),
- clock_.Now());
- manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
- EXPECT_EQ(PACKETS_NEWLY_ACKED,
- manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
- ENCRYPTION_INITIAL));
- // Verify that ack_delay is ignored in the first measurement.
- EXPECT_EQ(QuicTime::Delta::FromMilliseconds(300),
- manager_.GetRttStats()->latest_rtt());
- EXPECT_EQ(QuicTime::Delta::FromMilliseconds(300),
- manager_.GetRttStats()->smoothed_rtt());
-
- SendDataPacket(2);
- // Ack 2.
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(300));
- ExpectAck(2);
- manager_.OnAckFrameStart(QuicPacketNumber(2),
- QuicTime::Delta::FromMilliseconds(100),
- clock_.Now());
- manager_.OnAckRange(QuicPacketNumber(2), QuicPacketNumber(3));
- EXPECT_EQ(PACKETS_NEWLY_ACKED,
- manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(2),
- ENCRYPTION_INITIAL));
- EXPECT_EQ(QuicTime::Delta::FromMilliseconds(300),
- manager_.GetRttStats()->latest_rtt());
- EXPECT_EQ(QuicTime::Delta::FromMilliseconds(300),
- manager_.GetRttStats()->smoothed_rtt());
-
- SendDataPacket(3);
- // Ack 3.
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(300));
- ExpectAck(3);
- manager_.OnAckFrameStart(QuicPacketNumber(3),
- QuicTime::Delta::FromMilliseconds(50), clock_.Now());
- manager_.OnAckRange(QuicPacketNumber(3), QuicPacketNumber(4));
- EXPECT_EQ(PACKETS_NEWLY_ACKED,
- manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(3),
- ENCRYPTION_INITIAL));
- EXPECT_EQ(QuicTime::Delta::FromMilliseconds(300),
- manager_.GetRttStats()->latest_rtt());
- EXPECT_EQ(QuicTime::Delta::FromMilliseconds(300),
- manager_.GetRttStats()->smoothed_rtt());
-
- SendDataPacket(4);
- // Ack 4.
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(200));
- ExpectAck(4);
- manager_.OnAckFrameStart(QuicPacketNumber(4),
- QuicTime::Delta::FromMilliseconds(300),
- clock_.Now());
- manager_.OnAckRange(QuicPacketNumber(4), QuicPacketNumber(5));
- EXPECT_EQ(PACKETS_NEWLY_ACKED,
- manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(4),
- ENCRYPTION_INITIAL));
- // Verify that large erroneous ack_delay does not change Smoothed RTT.
- EXPECT_EQ(QuicTime::Delta::FromMilliseconds(200),
- manager_.GetRttStats()->latest_rtt());
- EXPECT_EQ(QuicTime::Delta::FromMicroseconds(287500),
- manager_.GetRttStats()->smoothed_rtt());
-}
-
-TEST_F(QuicSentPacketManagerTest, IgnorePeerMaxAckDelayDuringHandshake) {
- manager_.EnableMultiplePacketNumberSpacesSupport();
- // 100ms RTT.
- const QuicTime::Delta kTestRTT = QuicTime::Delta::FromMilliseconds(100);
-
- // Server sends INITIAL 1 and HANDSHAKE 2.
- SendDataPacket(1, ENCRYPTION_INITIAL);
- SendDataPacket(2, ENCRYPTION_HANDSHAKE);
-
- // Receive client ACK for INITIAL 1 after one RTT.
- clock_.AdvanceTime(kTestRTT);
- ExpectAck(1);
- 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));
- EXPECT_EQ(kTestRTT, manager_.GetRttStats()->latest_rtt());
-
- // Assume the cert verification on client takes 50ms, such that the HANDSHAKE
- // packet is queued for 50ms.
- const QuicTime::Delta queuing_delay = QuicTime::Delta::FromMilliseconds(50);
- clock_.AdvanceTime(queuing_delay);
- // Ack 2.
- ExpectAck(2);
- manager_.OnAckFrameStart(QuicPacketNumber(2), queuing_delay, clock_.Now());
- manager_.OnAckRange(QuicPacketNumber(2), QuicPacketNumber(3));
- EXPECT_EQ(PACKETS_NEWLY_ACKED,
- manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(2),
- ENCRYPTION_HANDSHAKE));
- if (GetQuicReloadableFlag(quic_ignore_peer_max_ack_delay_during_handshake)) {
- EXPECT_EQ(kTestRTT, manager_.GetRttStats()->latest_rtt());
- } else {
- // Verify the ack_delay gets capped by the peer_max_ack_delay.
- EXPECT_EQ(kTestRTT + queuing_delay -
- QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs),
- manager_.GetRttStats()->latest_rtt());
- }
-}
-
-TEST_F(QuicSentPacketManagerTest, BuildAckFrequencyFrameWithSRTT) {
- SetQuicReloadableFlag(quic_can_send_ack_frequency, true);
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
- EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
- QuicConfig config;
- QuicConfigPeer::SetReceivedMinAckDelayMs(&config, /*min_ack_delay_ms=*/1);
- QuicTagVector quic_tag_vector;
- quic_tag_vector.push_back(kAFF1); // SRTT enabling tag.
- QuicConfigPeer::SetReceivedConnectionOptions(&config, quic_tag_vector);
- manager_.SetFromConfig(config);
- manager_.SetHandshakeConfirmed();
-
- // Set up RTTs.
- auto* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
- rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(80),
- /*ack_delay=*/QuicTime::Delta::Zero(),
- /*now=*/QuicTime::Zero());
- // Make sure srtt and min_rtt are different.
- rtt_stats->UpdateRtt(
- QuicTime::Delta::FromMilliseconds(160),
- /*ack_delay=*/QuicTime::Delta::Zero(),
- /*now=*/QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(24));
-
- auto frame = manager_.GetUpdatedAckFrequencyFrame();
- EXPECT_EQ(frame.max_ack_delay,
- std::max(rtt_stats->SmoothedOrInitialRtt() * 0.25,
- QuicTime::Delta::FromMilliseconds(1u)));
-}
-
-} // namespace
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_server_id.cc b/chromium/net/third_party/quiche/src/quic/core/quic_server_id.cc
deleted file mode 100644
index 0c034514ef4..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_server_id.cc
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_server_id.h"
-
-#include <string>
-#include <tuple>
-
-namespace quic {
-
-QuicServerId::QuicServerId() : QuicServerId("", 0, false) {}
-
-QuicServerId::QuicServerId(const std::string& host, uint16_t port)
- : QuicServerId(host, port, false) {}
-
-QuicServerId::QuicServerId(const std::string& host,
- uint16_t port,
- bool privacy_mode_enabled)
- : host_(host), port_(port), privacy_mode_enabled_(privacy_mode_enabled) {}
-
-QuicServerId::~QuicServerId() {}
-
-bool QuicServerId::operator<(const QuicServerId& other) const {
- return std::tie(port_, host_, privacy_mode_enabled_) <
- std::tie(other.port_, other.host_, other.privacy_mode_enabled_);
-}
-
-bool QuicServerId::operator==(const QuicServerId& other) const {
- return privacy_mode_enabled_ == other.privacy_mode_enabled_ &&
- host_ == other.host_ && port_ == other.port_;
-}
-
-bool QuicServerId::operator!=(const QuicServerId& other) const {
- return !(*this == other);
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_server_id.h b/chromium/net/third_party/quiche/src/quic/core/quic_server_id.h
deleted file mode 100644
index 17c30db7cc0..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_server_id.h
+++ /dev/null
@@ -1,55 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_SERVER_ID_H_
-#define QUICHE_QUIC_CORE_QUIC_SERVER_ID_H_
-
-#include <cstdint>
-#include <string>
-
-#include "absl/hash/hash.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// The id used to identify sessions. Includes the hostname, port, scheme and
-// privacy_mode.
-class QUIC_EXPORT_PRIVATE QuicServerId {
- public:
- QuicServerId();
- QuicServerId(const std::string& host, uint16_t port);
- QuicServerId(const std::string& host,
- uint16_t port,
- bool privacy_mode_enabled);
- ~QuicServerId();
-
- // Needed to be an element of an ordered container.
- bool operator<(const QuicServerId& other) const;
- bool operator==(const QuicServerId& other) const;
-
- bool operator!=(const QuicServerId& other) const;
-
- const std::string& host() const { return host_; }
-
- uint16_t port() const { return port_; }
-
- bool privacy_mode_enabled() const { return privacy_mode_enabled_; }
-
- private:
- std::string host_;
- uint16_t port_;
- bool privacy_mode_enabled_;
-};
-
-class QUIC_EXPORT_PRIVATE QuicServerIdHash {
- public:
- size_t operator()(const quic::QuicServerId& server_id) const noexcept {
- return absl::HashOf(server_id.host(), server_id.port(),
- server_id.privacy_mode_enabled());
- }
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_QUIC_SERVER_ID_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_server_id_test.cc b/chromium/net/third_party/quiche/src/quic/core/quic_server_id_test.cc
deleted file mode 100644
index 1ad425abbd8..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_server_id_test.cc
+++ /dev/null
@@ -1,124 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_server_id.h"
-
-#include <string>
-
-#include "quic/platform/api/quic_test.h"
-
-namespace quic {
-
-namespace {
-
-class QuicServerIdTest : public QuicTest {};
-
-TEST_F(QuicServerIdTest, Constructor) {
- QuicServerId google_server_id("google.com", 10, false);
- EXPECT_EQ("google.com", google_server_id.host());
- EXPECT_EQ(10, google_server_id.port());
- EXPECT_FALSE(google_server_id.privacy_mode_enabled());
-
- QuicServerId private_server_id("mail.google.com", 12, true);
- EXPECT_EQ("mail.google.com", private_server_id.host());
- EXPECT_EQ(12, private_server_id.port());
- EXPECT_TRUE(private_server_id.privacy_mode_enabled());
-}
-
-TEST_F(QuicServerIdTest, LessThan) {
- QuicServerId a_10_https("a.com", 10, false);
- QuicServerId a_11_https("a.com", 11, false);
- QuicServerId b_10_https("b.com", 10, false);
- QuicServerId b_11_https("b.com", 11, false);
-
- QuicServerId a_10_https_private("a.com", 10, true);
- QuicServerId a_11_https_private("a.com", 11, true);
- QuicServerId b_10_https_private("b.com", 10, true);
- QuicServerId b_11_https_private("b.com", 11, true);
-
- // Test combinations of host, port, and privacy being same on left and
- // right side of less than.
- EXPECT_FALSE(a_10_https < a_10_https);
- EXPECT_TRUE(a_10_https < a_10_https_private);
- EXPECT_FALSE(a_10_https_private < a_10_https);
- EXPECT_FALSE(a_10_https_private < a_10_https_private);
-
- // Test with either host, port or https being different on left and right side
- // of less than.
- bool left_privacy;
- bool right_privacy;
- for (int i = 0; i < 4; i++) {
- left_privacy = (i / 2 == 0);
- right_privacy = (i % 2 == 0);
- QuicServerId a_10_https_left_private("a.com", 10, left_privacy);
- QuicServerId a_10_https_right_private("a.com", 10, right_privacy);
- QuicServerId a_11_https_left_private("a.com", 11, left_privacy);
- QuicServerId a_11_https_right_private("a.com", 11, right_privacy);
-
- QuicServerId b_10_https_left_private("b.com", 10, left_privacy);
- QuicServerId b_10_https_right_private("b.com", 10, right_privacy);
- QuicServerId b_11_https_left_private("b.com", 11, left_privacy);
- QuicServerId b_11_https_right_private("b.com", 11, right_privacy);
-
- EXPECT_TRUE(a_10_https_left_private < a_11_https_right_private);
- EXPECT_TRUE(a_10_https_left_private < b_10_https_right_private);
- EXPECT_TRUE(a_10_https_left_private < b_11_https_right_private);
- EXPECT_FALSE(a_11_https_left_private < a_10_https_right_private);
- EXPECT_FALSE(a_11_https_left_private < b_10_https_right_private);
- EXPECT_TRUE(a_11_https_left_private < b_11_https_right_private);
- EXPECT_FALSE(b_10_https_left_private < a_10_https_right_private);
- EXPECT_TRUE(b_10_https_left_private < a_11_https_right_private);
- EXPECT_TRUE(b_10_https_left_private < b_11_https_right_private);
- EXPECT_FALSE(b_11_https_left_private < a_10_https_right_private);
- EXPECT_FALSE(b_11_https_left_private < a_11_https_right_private);
- EXPECT_FALSE(b_11_https_left_private < b_10_https_right_private);
- }
-}
-
-TEST_F(QuicServerIdTest, Equals) {
- bool left_privacy;
- bool right_privacy;
- for (int i = 0; i < 2; i++) {
- left_privacy = right_privacy = (i == 0);
- QuicServerId a_10_https_right_private("a.com", 10, right_privacy);
- QuicServerId a_11_https_right_private("a.com", 11, right_privacy);
- QuicServerId b_10_https_right_private("b.com", 10, right_privacy);
- QuicServerId b_11_https_right_private("b.com", 11, right_privacy);
-
- EXPECT_NE(a_10_https_right_private, a_11_https_right_private);
- EXPECT_NE(a_10_https_right_private, b_10_https_right_private);
- EXPECT_NE(a_10_https_right_private, b_11_https_right_private);
-
- QuicServerId new_a_10_https_left_private("a.com", 10, left_privacy);
- QuicServerId new_a_11_https_left_private("a.com", 11, left_privacy);
- QuicServerId new_b_10_https_left_private("b.com", 10, left_privacy);
- QuicServerId new_b_11_https_left_private("b.com", 11, left_privacy);
-
- EXPECT_EQ(new_a_10_https_left_private, a_10_https_right_private);
- EXPECT_EQ(new_a_11_https_left_private, a_11_https_right_private);
- EXPECT_EQ(new_b_10_https_left_private, b_10_https_right_private);
- EXPECT_EQ(new_b_11_https_left_private, b_11_https_right_private);
- }
-
- for (int i = 0; i < 2; i++) {
- right_privacy = (i == 0);
- QuicServerId a_10_https_right_private("a.com", 10, right_privacy);
- QuicServerId a_11_https_right_private("a.com", 11, right_privacy);
- QuicServerId b_10_https_right_private("b.com", 10, right_privacy);
- QuicServerId b_11_https_right_private("b.com", 11, right_privacy);
-
- QuicServerId new_a_10_https_left_private("a.com", 10, false);
-
- EXPECT_NE(new_a_10_https_left_private, a_11_https_right_private);
- EXPECT_NE(new_a_10_https_left_private, b_10_https_right_private);
- EXPECT_NE(new_a_10_https_left_private, b_11_https_right_private);
- }
- QuicServerId a_10_https_private("a.com", 10, true);
- QuicServerId new_a_10_https_no_private("a.com", 10, false);
- EXPECT_NE(new_a_10_https_no_private, a_10_https_private);
-}
-
-} // namespace
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_session.cc b/chromium/net/third_party/quiche/src/quic/core/quic_session.cc
deleted file mode 100644
index 202bff43e1f..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_session.cc
+++ /dev/null
@@ -1,2675 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_session.h"
-
-#include <cstdint>
-#include <string>
-#include <utility>
-
-#include "absl/memory/memory.h"
-#include "absl/strings/str_cat.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/frames/quic_ack_frequency_frame.h"
-#include "quic/core/frames/quic_window_update_frame.h"
-#include "quic/core/quic_connection.h"
-#include "quic/core/quic_connection_context.h"
-#include "quic/core/quic_error_codes.h"
-#include "quic/core/quic_flow_controller.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_utils.h"
-#include "quic/core/quic_versions.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_flag_utils.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/platform/api/quic_server_stats.h"
-#include "quic/platform/api/quic_stack_trace.h"
-#include "common/quiche_text_utils.h"
-
-using spdy::SpdyPriority;
-
-namespace quic {
-
-namespace {
-
-class ClosedStreamsCleanUpDelegate : public QuicAlarm::Delegate {
- public:
- explicit ClosedStreamsCleanUpDelegate(QuicSession* session)
- : session_(session) {}
- ClosedStreamsCleanUpDelegate(const ClosedStreamsCleanUpDelegate&) = delete;
- ClosedStreamsCleanUpDelegate& operator=(const ClosedStreamsCleanUpDelegate&) =
- delete;
-
- QuicConnectionContext* GetConnectionContext() override {
- return (session_->connection() == nullptr)
- ? nullptr
- : session_->connection()->context();
- }
-
- void OnAlarm() override { session_->CleanUpClosedStreams(); }
-
- private:
- QuicSession* session_;
-};
-
-} // namespace
-
-#define ENDPOINT \
- (perspective() == Perspective::IS_SERVER ? "Server: " : "Client: ")
-
-QuicSession::QuicSession(
- QuicConnection* connection, Visitor* owner, const QuicConfig& config,
- const ParsedQuicVersionVector& supported_versions,
- QuicStreamCount num_expected_unidirectional_static_streams)
- : QuicSession(connection, owner, config, supported_versions,
- num_expected_unidirectional_static_streams, nullptr) {}
-
-QuicSession::QuicSession(
- QuicConnection* connection, Visitor* owner, const QuicConfig& config,
- const ParsedQuicVersionVector& supported_versions,
- QuicStreamCount num_expected_unidirectional_static_streams,
- std::unique_ptr<QuicDatagramQueue::Observer> datagram_observer)
- : connection_(connection),
- perspective_(connection->perspective()),
- visitor_(owner),
- write_blocked_streams_(connection->transport_version()),
- config_(config),
- stream_id_manager_(perspective(), connection->transport_version(),
- kDefaultMaxStreamsPerConnection,
- config_.GetMaxBidirectionalStreamsToSend()),
- ietf_streamid_manager_(perspective(), connection->version(), this, 0,
- num_expected_unidirectional_static_streams,
- config_.GetMaxBidirectionalStreamsToSend(),
- config_.GetMaxUnidirectionalStreamsToSend() +
- num_expected_unidirectional_static_streams),
- num_draining_streams_(0),
- num_outgoing_draining_streams_(0),
- num_static_streams_(0),
- num_zombie_streams_(0),
- flow_controller_(
- this, QuicUtils::GetInvalidStreamId(connection->transport_version()),
- /*is_connection_flow_controller*/ true,
- connection->version().AllowsLowFlowControlLimits()
- ? 0
- : kMinimumFlowControlSendWindow,
- config_.GetInitialSessionFlowControlWindowToSend(),
- kSessionReceiveWindowLimit, perspective() == Perspective::IS_SERVER,
- nullptr),
- currently_writing_stream_id_(0),
- transport_goaway_sent_(false),
- transport_goaway_received_(false),
- control_frame_manager_(this),
- last_message_id_(0),
- datagram_queue_(this, std::move(datagram_observer)),
- closed_streams_clean_up_alarm_(nullptr),
- supported_versions_(supported_versions),
- is_configured_(false),
- was_zero_rtt_rejected_(false),
- liveness_testing_in_progress_(false) {
- closed_streams_clean_up_alarm_ =
- absl::WrapUnique<QuicAlarm>(connection_->alarm_factory()->CreateAlarm(
- new ClosedStreamsCleanUpDelegate(this)));
- if (perspective() == Perspective::IS_SERVER &&
- connection_->version().handshake_protocol == PROTOCOL_TLS1_3) {
- config_.SetStatelessResetTokenToSend(GetStatelessResetToken());
- }
- if (VersionHasIetfQuicFrames(transport_version())) {
- config_.SetMaxUnidirectionalStreamsToSend(
- config_.GetMaxUnidirectionalStreamsToSend() +
- num_expected_unidirectional_static_streams);
- }
-}
-
-void QuicSession::Initialize() {
- connection_->set_visitor(this);
- connection_->SetSessionNotifier(this);
- connection_->SetDataProducer(this);
- connection_->SetUnackedMapInitialCapacity();
- connection_->SetFromConfig(config_);
- if (perspective_ == Perspective::IS_CLIENT) {
- if (config_.HasClientRequestedIndependentOption(kAFFE, perspective_) &&
- version().HasIetfQuicFrames()) {
- connection_->set_can_receive_ack_frequency_frame();
- config_.SetMinAckDelayMs(kDefaultMinAckDelayTimeMs);
- }
- if (config_.HasClientRequestedIndependentOption(kNBPE, perspective_)) {
- permutes_tls_extensions_ = false;
- }
- }
-
- connection_->CreateConnectionIdManager();
-
- // On the server side, version negotiation has been done by the dispatcher,
- // and the server session is created with the right version.
- if (perspective() == Perspective::IS_SERVER) {
- connection_->OnSuccessfulVersionNegotiation();
- }
-
- if (QuicVersionUsesCryptoFrames(transport_version())) {
- return;
- }
-
- QUICHE_DCHECK_EQ(QuicUtils::GetCryptoStreamId(transport_version()),
- GetMutableCryptoStream()->id());
-}
-
-QuicSession::~QuicSession() {
- if (closed_streams_clean_up_alarm_ != nullptr) {
- closed_streams_clean_up_alarm_->PermanentCancel();
- }
-}
-
-PendingStream* QuicSession::PendingStreamOnStreamFrame(
- const QuicStreamFrame& frame) {
- QUICHE_DCHECK(VersionUsesHttp3(transport_version()));
- QuicStreamId stream_id = frame.stream_id;
-
- PendingStream* pending = GetOrCreatePendingStream(stream_id);
-
- if (!pending) {
- if (frame.fin) {
- QuicStreamOffset final_byte_offset = frame.offset + frame.data_length;
- OnFinalByteOffsetReceived(stream_id, final_byte_offset);
- }
- return nullptr;
- }
-
- pending->OnStreamFrame(frame);
- if (!connection()->connected()) {
- return nullptr;
- }
- return pending;
-}
-
-void QuicSession::MaybeProcessPendingStream(PendingStream* pending) {
- QUICHE_DCHECK(pending != nullptr);
- QuicStreamId stream_id = pending->id();
- absl::optional<QuicResetStreamError> stop_sending_error_code =
- pending->GetStopSendingErrorCode();
- QuicStream* stream = ProcessPendingStream(pending);
- if (stream != nullptr) {
- // The pending stream should now be in the scope of normal streams.
- QUICHE_DCHECK(IsClosedStream(stream_id) || IsOpenStream(stream_id))
- << "Stream " << stream_id << " not created";
- pending_stream_map_.erase(stream_id);
- if (stop_sending_error_code) {
- stream->OnStopSending(*stop_sending_error_code);
- if (!connection()->connected()) {
- return;
- }
- }
- stream->OnStreamCreatedFromPendingStream();
- return;
- }
- // At this point, none of the bytes has been successfully consumed by the
- // application layer. We should close the pending stream even if it is
- // bidirectionl as no application will be able to write in a bidirectional
- // stream with zero byte as input.
- if (pending->sequencer()->IsClosed()) {
- ClosePendingStream(stream_id);
- }
-}
-
-void QuicSession::PendingStreamOnWindowUpdateFrame(
- const QuicWindowUpdateFrame& frame) {
- QUICHE_DCHECK(VersionUsesHttp3(transport_version()));
- PendingStream* pending = GetOrCreatePendingStream(frame.stream_id);
- if (pending) {
- pending->OnWindowUpdateFrame(frame);
- }
-}
-
-void QuicSession::PendingStreamOnStopSendingFrame(
- const QuicStopSendingFrame& frame) {
- QUICHE_DCHECK(VersionUsesHttp3(transport_version()));
- PendingStream* pending = GetOrCreatePendingStream(frame.stream_id);
- if (pending) {
- pending->OnStopSending(frame.error());
- }
-}
-
-void QuicSession::OnStreamFrame(const QuicStreamFrame& frame) {
- QuicStreamId stream_id = frame.stream_id;
- if (stream_id == QuicUtils::GetInvalidStreamId(transport_version())) {
- connection()->CloseConnection(
- QUIC_INVALID_STREAM_ID, "Received data for an invalid stream",
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
- return;
- }
-
- if (ShouldProcessFrameByPendingStream(STREAM_FRAME, stream_id)) {
- PendingStream* pending = PendingStreamOnStreamFrame(frame);
- if (pending != nullptr && ShouldProcessPendingStreamImmediately()) {
- MaybeProcessPendingStream(pending);
- }
- return;
- }
-
- QuicStream* stream = GetOrCreateStream(stream_id);
-
- if (!stream) {
- // The stream no longer exists, but we may still be interested in the
- // final stream byte offset sent by the peer. A frame with a FIN can give
- // us this offset.
- if (frame.fin) {
- QuicStreamOffset final_byte_offset = frame.offset + frame.data_length;
- OnFinalByteOffsetReceived(stream_id, final_byte_offset);
- }
- return;
- }
- stream->OnStreamFrame(frame);
-}
-
-void QuicSession::OnCryptoFrame(const QuicCryptoFrame& frame) {
- GetMutableCryptoStream()->OnCryptoFrame(frame);
-}
-
-void QuicSession::OnStopSendingFrame(const QuicStopSendingFrame& frame) {
- // STOP_SENDING is in IETF QUIC only.
- QUICHE_DCHECK(VersionHasIetfQuicFrames(transport_version()));
- QUICHE_DCHECK(QuicVersionUsesCryptoFrames(transport_version()));
-
- QuicStreamId stream_id = frame.stream_id;
- // If Stream ID is invalid then close the connection.
- // TODO(ianswett): This check is redundant to checks for IsClosedStream,
- // but removing it requires removing multiple QUICHE_DCHECKs.
- // TODO(ianswett): Multiple QUIC_DVLOGs could be QUIC_PEER_BUGs.
- if (stream_id == QuicUtils::GetInvalidStreamId(transport_version())) {
- QUIC_DVLOG(1) << ENDPOINT
- << "Received STOP_SENDING with invalid stream_id: "
- << stream_id << " Closing connection";
- connection()->CloseConnection(
- QUIC_INVALID_STREAM_ID, "Received STOP_SENDING for an invalid stream",
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
- return;
- }
-
- // If stream_id is READ_UNIDIRECTIONAL, close the connection.
- if (QuicUtils::GetStreamType(stream_id, perspective(),
- IsIncomingStream(stream_id),
- version()) == READ_UNIDIRECTIONAL) {
- QUIC_DVLOG(1) << ENDPOINT
- << "Received STOP_SENDING for a read-only stream_id: "
- << stream_id << ".";
- connection()->CloseConnection(
- QUIC_INVALID_STREAM_ID, "Received STOP_SENDING for a read-only stream",
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
- return;
- }
-
- if (visitor_) {
- visitor_->OnStopSendingReceived(frame);
- }
- if (ShouldProcessFrameByPendingStream(STOP_SENDING_FRAME, stream_id)) {
- PendingStreamOnStopSendingFrame(frame);
- return;
- }
-
- QuicStream* stream = GetOrCreateStream(stream_id);
- if (!stream) {
- // Errors are handled by GetOrCreateStream.
- return;
- }
-
- stream->OnStopSending(frame.error());
-}
-
-void QuicSession::OnPacketDecrypted(EncryptionLevel level) {
- GetMutableCryptoStream()->OnPacketDecrypted(level);
- if (liveness_testing_in_progress_) {
- liveness_testing_in_progress_ = false;
- OnCanCreateNewOutgoingStream(/*unidirectional=*/false);
- }
-}
-
-void QuicSession::OnOneRttPacketAcknowledged() {
- GetMutableCryptoStream()->OnOneRttPacketAcknowledged();
-}
-
-void QuicSession::OnHandshakePacketSent() {
- GetMutableCryptoStream()->OnHandshakePacketSent();
-}
-
-std::unique_ptr<QuicDecrypter>
-QuicSession::AdvanceKeysAndCreateCurrentOneRttDecrypter() {
- return GetMutableCryptoStream()->AdvanceKeysAndCreateCurrentOneRttDecrypter();
-}
-
-std::unique_ptr<QuicEncrypter> QuicSession::CreateCurrentOneRttEncrypter() {
- return GetMutableCryptoStream()->CreateCurrentOneRttEncrypter();
-}
-
-void QuicSession::PendingStreamOnRstStream(const QuicRstStreamFrame& frame) {
- QUICHE_DCHECK(VersionUsesHttp3(transport_version()));
- QuicStreamId stream_id = frame.stream_id;
-
- PendingStream* pending = GetOrCreatePendingStream(stream_id);
-
- if (!pending) {
- HandleRstOnValidNonexistentStream(frame);
- return;
- }
-
- pending->OnRstStreamFrame(frame);
- // At this point, none of the bytes has been consumed by the application
- // layer. It is safe to close the pending stream even if it is bidirectionl as
- // no application will be able to write in a bidirectional stream with zero
- // byte as input.
- ClosePendingStream(stream_id);
-}
-
-void QuicSession::OnRstStream(const QuicRstStreamFrame& frame) {
- QuicStreamId stream_id = frame.stream_id;
- if (stream_id == QuicUtils::GetInvalidStreamId(transport_version())) {
- connection()->CloseConnection(
- QUIC_INVALID_STREAM_ID, "Received data for an invalid stream",
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
- return;
- }
-
- if (VersionHasIetfQuicFrames(transport_version()) &&
- QuicUtils::GetStreamType(stream_id, perspective(),
- IsIncomingStream(stream_id),
- version()) == WRITE_UNIDIRECTIONAL) {
- connection()->CloseConnection(
- QUIC_INVALID_STREAM_ID, "Received RESET_STREAM for a write-only stream",
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
- return;
- }
-
- if (visitor_) {
- visitor_->OnRstStreamReceived(frame);
- }
-
- if (ShouldProcessFrameByPendingStream(RST_STREAM_FRAME, stream_id)) {
- PendingStreamOnRstStream(frame);
- return;
- }
-
- QuicStream* stream = GetOrCreateStream(stream_id);
-
- if (!stream) {
- HandleRstOnValidNonexistentStream(frame);
- return; // Errors are handled by GetOrCreateStream.
- }
- stream->OnStreamReset(frame);
-}
-
-void QuicSession::OnGoAway(const QuicGoAwayFrame& /*frame*/) {
- QUIC_BUG_IF(quic_bug_12435_1, version().UsesHttp3())
- << "gQUIC GOAWAY received on version " << version();
-
- transport_goaway_received_ = true;
-}
-
-void QuicSession::OnMessageReceived(absl::string_view message) {
- QUIC_DVLOG(1) << ENDPOINT << "Received message of length "
- << message.length();
- QUIC_DVLOG(2) << ENDPOINT << "Contents of message of length "
- << message.length() << ":" << std::endl
- << quiche::QuicheTextUtils::HexDump(message);
-}
-
-void QuicSession::OnHandshakeDoneReceived() {
- QUIC_DVLOG(1) << ENDPOINT << "OnHandshakeDoneReceived";
- GetMutableCryptoStream()->OnHandshakeDoneReceived();
-}
-
-void QuicSession::OnNewTokenReceived(absl::string_view token) {
- QUICHE_DCHECK_EQ(perspective_, Perspective::IS_CLIENT);
- GetMutableCryptoStream()->OnNewTokenReceived(token);
-}
-
-// static
-void QuicSession::RecordConnectionCloseAtServer(QuicErrorCode error,
- ConnectionCloseSource source) {
- if (error != QUIC_NO_ERROR) {
- if (source == ConnectionCloseSource::FROM_SELF) {
- QUIC_SERVER_HISTOGRAM_ENUM(
- "quic_server_connection_close_errors", error, QUIC_LAST_ERROR,
- "QuicErrorCode for server-closed connections.");
- } else {
- QUIC_SERVER_HISTOGRAM_ENUM(
- "quic_client_connection_close_errors", error, QUIC_LAST_ERROR,
- "QuicErrorCode for client-closed connections.");
- }
- }
-}
-
-void QuicSession::OnConnectionClosed(const QuicConnectionCloseFrame& frame,
- ConnectionCloseSource source) {
- QUICHE_DCHECK(!connection_->connected());
- if (perspective() == Perspective::IS_SERVER) {
- RecordConnectionCloseAtServer(frame.quic_error_code, source);
- }
-
- if (on_closed_frame_.quic_error_code == QUIC_NO_ERROR) {
- // Save all of the connection close information
- on_closed_frame_ = frame;
- }
-
- GetMutableCryptoStream()->OnConnectionClosed(frame.quic_error_code, source);
-
- PerformActionOnActiveStreams([this, frame, source](QuicStream* stream) {
- QuicStreamId id = stream->id();
- stream->OnConnectionClosed(frame.quic_error_code, source);
- auto it = stream_map_.find(id);
- if (it != stream_map_.end()) {
- QUIC_BUG_IF(quic_bug_12435_2, !it->second->IsZombie())
- << ENDPOINT << "Non-zombie stream " << id
- << " failed to close under OnConnectionClosed";
- }
- return true;
- });
-
- closed_streams_clean_up_alarm_->Cancel();
-
- if (visitor_) {
- visitor_->OnConnectionClosed(connection_->GetOneActiveServerConnectionId(),
- frame.quic_error_code, frame.error_details,
- source);
- }
-}
-
-void QuicSession::OnWriteBlocked() {
- if (!connection_->connected()) {
- return;
- }
- if (visitor_) {
- visitor_->OnWriteBlocked(connection_);
- }
-}
-
-void QuicSession::OnSuccessfulVersionNegotiation(
- const ParsedQuicVersion& /*version*/) {}
-
-void QuicSession::OnPacketReceived(const QuicSocketAddress& /*self_address*/,
- const QuicSocketAddress& peer_address,
- bool is_connectivity_probe) {
- if (is_connectivity_probe && perspective() == Perspective::IS_SERVER) {
- // Server only sends back a connectivity probe after received a
- // connectivity probe from a new peer address.
- if (connection_->send_path_response()) {
- // SendConnectivityProbingResponsePacket() will be deprecated.
- // SendConnectivityProbingPacket() will be used to send both probing
- // request and response as both of them are padded PING.
- connection_->SendConnectivityProbingPacket(nullptr, peer_address);
- } else {
- connection_->SendConnectivityProbingResponsePacket(peer_address);
- }
- }
-}
-
-void QuicSession::OnPathDegrading() {}
-
-void QuicSession::OnForwardProgressMadeAfterPathDegrading() {}
-
-bool QuicSession::AllowSelfAddressChange() const { return false; }
-
-void QuicSession::OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame) {
- // Stream may be closed by the time we receive a WINDOW_UPDATE, so we can't
- // assume that it still exists.
- QuicStreamId stream_id = frame.stream_id;
- if (stream_id == QuicUtils::GetInvalidStreamId(transport_version())) {
- // This is a window update that applies to the connection, rather than an
- // individual stream.
- QUIC_DVLOG(1) << ENDPOINT
- << "Received connection level flow control window "
- "update with max data: "
- << frame.max_data;
- flow_controller_.UpdateSendWindowOffset(frame.max_data);
- return;
- }
-
- if (VersionHasIetfQuicFrames(transport_version()) &&
- QuicUtils::GetStreamType(stream_id, perspective(),
- IsIncomingStream(stream_id),
- version()) == READ_UNIDIRECTIONAL) {
- connection()->CloseConnection(
- QUIC_WINDOW_UPDATE_RECEIVED_ON_READ_UNIDIRECTIONAL_STREAM,
- "WindowUpdateFrame received on READ_UNIDIRECTIONAL stream.",
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
- return;
- }
-
- if (ShouldProcessFrameByPendingStream(WINDOW_UPDATE_FRAME, stream_id)) {
- PendingStreamOnWindowUpdateFrame(frame);
- return;
- }
-
- QuicStream* stream = GetOrCreateStream(stream_id);
- if (stream != nullptr) {
- stream->OnWindowUpdateFrame(frame);
- }
-}
-
-void QuicSession::OnBlockedFrame(const QuicBlockedFrame& frame) {
- // TODO(rjshade): Compare our flow control receive windows for specified
- // 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;
-}
-
-bool QuicSession::CheckStreamNotBusyLooping(QuicStream* stream,
- uint64_t previous_bytes_written,
- bool previous_fin_sent) {
- if ( // Stream should not be closed.
- !stream->write_side_closed() &&
- // Not connection flow control blocked.
- !flow_controller_.IsBlocked() &&
- // Detect lack of forward progress.
- previous_bytes_written == stream->stream_bytes_written() &&
- previous_fin_sent == stream->fin_sent()) {
- stream->set_busy_counter(stream->busy_counter() + 1);
- QUIC_DVLOG(1) << ENDPOINT << "Suspected busy loop on stream id "
- << stream->id() << " stream_bytes_written "
- << stream->stream_bytes_written() << " fin "
- << stream->fin_sent() << " count " << stream->busy_counter();
- // Wait a few iterations before firing, the exact count is
- // arbitrary, more than a few to cover a few test-only false
- // positives.
- if (stream->busy_counter() > 20) {
- QUIC_LOG(ERROR) << ENDPOINT << "Detected busy loop on stream id "
- << stream->id() << " stream_bytes_written "
- << stream->stream_bytes_written() << " fin "
- << stream->fin_sent();
- return false;
- }
- } else {
- stream->set_busy_counter(0);
- }
- return true;
-}
-
-bool QuicSession::CheckStreamWriteBlocked(QuicStream* stream) const {
- if (!stream->write_side_closed() && stream->HasBufferedData() &&
- !stream->IsFlowControlBlocked() &&
- !write_blocked_streams_.IsStreamBlocked(stream->id())) {
- QUIC_DLOG(ERROR) << ENDPOINT << "stream " << stream->id()
- << " has buffered " << stream->BufferedDataBytes()
- << " bytes, and is not flow control blocked, "
- "but it is not in the write block list.";
- return false;
- }
- return true;
-}
-
-void QuicSession::OnCanWrite() {
- if (connection_->framer().is_processing_packet()) {
- // Do not write data in the middle of packet processing because rest
- // frames in the packet may change the data to write. For example, lost
- // data could be acknowledged. Also, connection is going to emit
- // OnCanWrite signal post packet processing.
- QUIC_BUG(session_write_mid_packet_processing)
- << ENDPOINT << "Try to write mid packet processing.";
- return;
- }
- if (!RetransmitLostData()) {
- // Cannot finish retransmitting lost data, connection is write blocked.
- QUIC_DVLOG(1) << ENDPOINT
- << "Cannot finish retransmitting lost data, connection is "
- "write blocked.";
- return;
- }
- // We limit the number of writes to the number of pending streams. If more
- // streams become pending, WillingAndAbleToWrite will be true, which will
- // cause the connection to request resumption before yielding to other
- // connections.
- // If we are connection level flow control blocked, then only allow the
- // crypto and headers streams to try writing as all other streams will be
- // blocked.
- size_t num_writes = flow_controller_.IsBlocked()
- ? write_blocked_streams_.NumBlockedSpecialStreams()
- : write_blocked_streams_.NumBlockedStreams();
- if (num_writes == 0 && !control_frame_manager_.WillingToWrite() &&
- datagram_queue_.empty() &&
- (!QuicVersionUsesCryptoFrames(transport_version()) ||
- !GetCryptoStream()->HasBufferedCryptoFrames())) {
- return;
- }
-
- QuicConnection::ScopedPacketFlusher flusher(connection_);
- if (QuicVersionUsesCryptoFrames(transport_version())) {
- QuicCryptoStream* crypto_stream = GetMutableCryptoStream();
- if (crypto_stream->HasBufferedCryptoFrames()) {
- crypto_stream->WriteBufferedCryptoFrames();
- }
- if (crypto_stream->HasBufferedCryptoFrames()) {
- // Cannot finish writing buffered crypto frames, connection is write
- // blocked.
- return;
- }
- }
- if (control_frame_manager_.WillingToWrite()) {
- control_frame_manager_.OnCanWrite();
- }
- // TODO(b/147146815): this makes all datagrams go before stream data. We
- // should have a better priority scheme for this.
- if (!datagram_queue_.empty()) {
- size_t written = datagram_queue_.SendDatagrams();
- QUIC_DVLOG(1) << ENDPOINT << "Sent " << written << " datagrams";
- if (!datagram_queue_.empty()) {
- return;
- }
- }
- std::vector<QuicStreamId> last_writing_stream_ids;
- for (size_t i = 0; i < num_writes; ++i) {
- if (!(write_blocked_streams_.HasWriteBlockedSpecialStream() ||
- write_blocked_streams_.HasWriteBlockedDataStreams())) {
- // Writing one stream removed another!? Something's broken.
- QUIC_BUG(quic_bug_10866_1)
- << "WriteBlockedStream is missing, num_writes: " << num_writes
- << ", finished_writes: " << i
- << ", connected: " << connection_->connected()
- << ", connection level flow control blocked: "
- << flow_controller_.IsBlocked();
- for (QuicStreamId id : last_writing_stream_ids) {
- QUIC_LOG(WARNING) << "last_writing_stream_id: " << id;
- }
- connection_->CloseConnection(QUIC_INTERNAL_ERROR,
- "WriteBlockedStream is missing",
- ConnectionCloseBehavior::SILENT_CLOSE);
- return;
- }
- if (!CanWriteStreamData()) {
- return;
- }
- currently_writing_stream_id_ = write_blocked_streams_.PopFront();
- last_writing_stream_ids.push_back(currently_writing_stream_id_);
- QUIC_DVLOG(1) << ENDPOINT << "Removing stream "
- << currently_writing_stream_id_ << " from write-blocked list";
- QuicStream* stream = GetOrCreateStream(currently_writing_stream_id_);
- if (stream != nullptr && !stream->IsFlowControlBlocked()) {
- // If the stream can't write all bytes it'll re-add itself to the blocked
- // list.
- uint64_t previous_bytes_written = stream->stream_bytes_written();
- bool previous_fin_sent = stream->fin_sent();
- QUIC_DVLOG(1) << ENDPOINT << "stream " << stream->id()
- << " bytes_written " << previous_bytes_written << " fin "
- << previous_fin_sent;
- stream->OnCanWrite();
- QUICHE_DCHECK(CheckStreamWriteBlocked(stream));
- QUICHE_DCHECK(CheckStreamNotBusyLooping(stream, previous_bytes_written,
- previous_fin_sent));
- }
- currently_writing_stream_id_ = 0;
- }
-}
-
-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
- // 2) any stream has pending retransmissions, or
- // 3) If the crypto or headers streams are blocked, or
- // 4) connection is not flow control blocked and there are write blocked
- // streams.
- if (QuicVersionUsesCryptoFrames(transport_version())) {
- if (HasPendingHandshake()) {
- return true;
- }
- if (!IsEncryptionEstablished()) {
- return false;
- }
- }
- if (control_frame_manager_.WillingToWrite() ||
- !streams_with_pending_retransmission_.empty()) {
- return true;
- }
- if (flow_controller_.IsBlocked()) {
- if (VersionUsesHttp3(transport_version())) {
- return false;
- }
- // Crypto and headers streams are not blocked by connection level flow
- // control.
- return write_blocked_streams_.HasWriteBlockedSpecialStream();
- }
- return write_blocked_streams_.HasWriteBlockedSpecialStream() ||
- write_blocked_streams_.HasWriteBlockedDataStreams();
-}
-
-std::string QuicSession::GetStreamsInfoForLogging() const {
- std::string info = absl::StrCat(
- "num_active_streams: ", GetNumActiveStreams(),
- ", num_pending_streams: ", pending_streams_size(),
- ", num_outgoing_draining_streams: ", num_outgoing_draining_streams(),
- " ");
- // Log info for up to 5 streams.
- size_t i = 5;
- for (const auto& it : stream_map_) {
- if (it.second->is_static()) {
- continue;
- }
- // Calculate the stream creation delay.
- const QuicTime::Delta delay =
- connection_->clock()->ApproximateNow() - it.second->creation_time();
- absl::StrAppend(
- &info, "{", it.second->id(), ":", delay.ToDebuggingValue(), ";",
- it.second->stream_bytes_written(), ",", it.second->fin_sent(), ",",
- it.second->HasBufferedData(), ",", it.second->fin_buffered(), ";",
- it.second->stream_bytes_read(), ",", it.second->fin_received(), "}");
- --i;
- if (i == 0) {
- break;
- }
- }
- return info;
-}
-
-bool QuicSession::HasPendingHandshake() const {
- if (QuicVersionUsesCryptoFrames(transport_version())) {
- return GetCryptoStream()->HasPendingCryptoRetransmission() ||
- GetCryptoStream()->HasBufferedCryptoFrames();
- }
- return streams_with_pending_retransmission_.contains(
- QuicUtils::GetCryptoStreamId(transport_version())) ||
- write_blocked_streams_.IsStreamBlocked(
- QuicUtils::GetCryptoStreamId(transport_version()));
-}
-
-void QuicSession::ProcessUdpPacket(const QuicSocketAddress& self_address,
- const QuicSocketAddress& peer_address,
- const QuicReceivedPacket& packet) {
- QuicConnectionContextSwitcher cs(connection_->context());
- connection_->ProcessUdpPacket(self_address, peer_address, packet);
-}
-
-QuicConsumedData QuicSession::WritevData(QuicStreamId id, size_t write_length,
- QuicStreamOffset offset,
- StreamSendingState state,
- TransmissionType type,
- EncryptionLevel level) {
- QUICHE_DCHECK(connection_->connected())
- << ENDPOINT << "Try to write stream data when connection is closed.";
- if (!IsEncryptionEstablished() &&
- !QuicUtils::IsCryptoStreamId(transport_version(), id)) {
- // Do not let streams write without encryption. The calling stream will end
- // up write blocked until OnCanWrite is next called.
- if (was_zero_rtt_rejected_ && !OneRttKeysAvailable()) {
- QUICHE_DCHECK(version().UsesTls() &&
- perspective() == Perspective::IS_CLIENT);
- QUIC_DLOG(INFO) << ENDPOINT
- << "Suppress the write while 0-RTT gets rejected and "
- "1-RTT keys are not available. Version: "
- << ParsedQuicVersionToString(version());
- } else if (version().UsesTls() || perspective() == Perspective::IS_SERVER) {
- QUIC_BUG(quic_bug_10866_2)
- << ENDPOINT << "Try to send data of stream " << id
- << " before encryption is established. Version: "
- << ParsedQuicVersionToString(version());
- } else {
- // In QUIC crypto, this could happen when the client sends full CHLO and
- // 0-RTT request, then receives an inchoate REJ and sends an inchoate
- // CHLO. The client then gets the ACK of the inchoate CHLO or the client
- // gets the full REJ and needs to verify the proof (before it sends the
- // full CHLO), such that there is no outstanding crypto data.
- // Retransmission alarm fires in TLP mode which tries to retransmit the
- // 0-RTT request (without encryption).
- QUIC_DLOG(INFO) << ENDPOINT << "Try to send data of stream " << id
- << " before encryption is established.";
- }
- return QuicConsumedData(0, false);
- }
-
- SetTransmissionType(type);
- QuicConnection::ScopedEncryptionLevelContext context(connection(), level);
-
- QuicConsumedData data =
- connection_->SendStreamData(id, write_length, offset, state);
- if (type == NOT_RETRANSMISSION) {
- // This is new stream data.
- write_blocked_streams_.UpdateBytesForStream(id, data.bytes_consumed);
- }
-
- return data;
-}
-
-size_t QuicSession::SendCryptoData(EncryptionLevel level, size_t write_length,
- QuicStreamOffset offset,
- TransmissionType type) {
- QUICHE_DCHECK(QuicVersionUsesCryptoFrames(transport_version()));
- if (!connection()->framer().HasEncrypterOfEncryptionLevel(level)) {
- const std::string error_details = absl::StrCat(
- "Try to send crypto data with missing keys of encryption level: ",
- EncryptionLevelToString(level));
- QUIC_BUG(quic_bug_10866_3) << ENDPOINT << error_details;
- connection()->CloseConnection(
- QUIC_MISSING_WRITE_KEYS, error_details,
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
- return 0;
- }
- SetTransmissionType(type);
- QuicConnection::ScopedEncryptionLevelContext context(connection(), level);
- const auto bytes_consumed =
- connection_->SendCryptoData(level, write_length, offset);
- return bytes_consumed;
-}
-
-void QuicSession::OnControlFrameManagerError(QuicErrorCode error_code,
- std::string error_details) {
- connection_->CloseConnection(
- error_code, error_details,
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
-}
-
-bool QuicSession::WriteControlFrame(const QuicFrame& frame,
- TransmissionType type) {
- QUICHE_DCHECK(connection()->connected())
- << ENDPOINT << "Try to write control frames when connection is closed.";
- if (!IsEncryptionEstablished()) {
- // Suppress the write before encryption gets established.
- return false;
- }
- SetTransmissionType(type);
- QuicConnection::ScopedEncryptionLevelContext context(
- connection(), GetEncryptionLevelToSendApplicationData());
- return connection_->SendControlFrame(frame);
-}
-
-void QuicSession::ResetStream(QuicStreamId id, QuicRstStreamErrorCode error) {
- QuicStream* stream = GetStream(id);
- if (stream != nullptr && stream->is_static()) {
- connection()->CloseConnection(
- QUIC_INVALID_STREAM_ID, "Try to reset a static stream",
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
- return;
- }
-
- if (stream != nullptr) {
- stream->Reset(error);
- return;
- }
-
- QuicConnection::ScopedPacketFlusher flusher(connection());
- MaybeSendStopSendingFrame(id, QuicResetStreamError::FromInternal(error));
- MaybeSendRstStreamFrame(id, QuicResetStreamError::FromInternal(error), 0);
-}
-
-void QuicSession::MaybeSendRstStreamFrame(QuicStreamId id,
- QuicResetStreamError error,
- QuicStreamOffset bytes_written) {
- if (!connection()->connected()) {
- return;
- }
- if (!VersionHasIetfQuicFrames(transport_version()) ||
- QuicUtils::GetStreamType(id, perspective(), IsIncomingStream(id),
- version()) != READ_UNIDIRECTIONAL) {
- control_frame_manager_.WriteOrBufferRstStream(id, error, bytes_written);
- }
-
- connection_->OnStreamReset(id, error.internal_code());
-}
-
-void QuicSession::MaybeSendStopSendingFrame(QuicStreamId id,
- QuicResetStreamError error) {
- if (!connection()->connected()) {
- return;
- }
- if (VersionHasIetfQuicFrames(transport_version()) &&
- QuicUtils::GetStreamType(id, perspective(), IsIncomingStream(id),
- version()) != WRITE_UNIDIRECTIONAL) {
- control_frame_manager_.WriteOrBufferStopSending(error, id);
- }
-}
-
-void QuicSession::SendGoAway(QuicErrorCode error_code,
- const std::string& reason) {
- // GOAWAY frame is not supported in IETF QUIC.
- QUICHE_DCHECK(!VersionHasIetfQuicFrames(transport_version()));
- if (!IsEncryptionEstablished()) {
- QUIC_CODE_COUNT(quic_goaway_before_encryption_established);
- connection_->CloseConnection(
- error_code, reason,
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
- return;
- }
- if (transport_goaway_sent_) {
- return;
- }
- transport_goaway_sent_ = true;
-
- QUICHE_DCHECK_EQ(perspective(), Perspective::IS_SERVER);
- control_frame_manager_.WriteOrBufferGoAway(
- error_code,
- QuicUtils::GetMaxClientInitiatedBidirectionalStreamId(
- transport_version()),
- reason);
-}
-
-void QuicSession::SendBlocked(QuicStreamId id) {
- control_frame_manager_.WriteOrBufferBlocked(id);
-}
-
-void QuicSession::SendWindowUpdate(QuicStreamId id,
- QuicStreamOffset byte_offset) {
- control_frame_manager_.WriteOrBufferWindowUpdate(id, byte_offset);
-}
-
-void QuicSession::OnStreamError(QuicErrorCode error_code,
- std::string error_details) {
- connection_->CloseConnection(
- error_code, error_details,
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
-}
-
-void QuicSession::OnStreamError(QuicErrorCode error_code,
- QuicIetfTransportErrorCodes ietf_error,
- std::string error_details) {
- connection_->CloseConnection(
- error_code, ietf_error, error_details,
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
-}
-
-void QuicSession::SendMaxStreams(QuicStreamCount stream_count,
- bool unidirectional) {
- if (!is_configured_) {
- QUIC_BUG(quic_bug_10866_5)
- << "Try to send max streams before config negotiated.";
- return;
- }
- control_frame_manager_.WriteOrBufferMaxStreams(stream_count, unidirectional);
-}
-
-void QuicSession::InsertLocallyClosedStreamsHighestOffset(
- const QuicStreamId id, QuicStreamOffset offset) {
- locally_closed_streams_highest_offset_[id] = offset;
-}
-
-void QuicSession::OnStreamClosed(QuicStreamId stream_id) {
- QUIC_DVLOG(1) << ENDPOINT << "Closing stream: " << stream_id;
- StreamMap::iterator it = stream_map_.find(stream_id);
- if (it == stream_map_.end()) {
- QUIC_BUG(quic_bug_10866_6)
- << ENDPOINT << "Stream is already closed: " << stream_id;
- return;
- }
- QuicStream* stream = it->second.get();
- StreamType type = stream->type();
-
- const bool stream_waiting_for_acks = stream->IsWaitingForAcks();
- if (stream_waiting_for_acks) {
- // The stream needs to be kept alive because it's waiting for acks.
- ++num_zombie_streams_;
- } else {
- closed_streams_.push_back(std::move(it->second));
- stream_map_.erase(it);
- // Do not retransmit data of a closed stream.
- streams_with_pending_retransmission_.erase(stream_id);
- if (!closed_streams_clean_up_alarm_->IsSet()) {
- closed_streams_clean_up_alarm_->Set(
- connection_->clock()->ApproximateNow());
- }
- QUIC_BUG_IF(
- 364846171_1,
- connection_->packet_creator().HasPendingStreamFramesOfStream(stream_id))
- << "Stream " << stream_id
- << " gets closed while there are pending frames.";
- }
-
- if (!stream->HasReceivedFinalOffset()) {
- // If we haven't received a FIN or RST for this stream, we need to keep
- // track of the how many bytes the stream's flow controller believes it has
- // received, for accurate connection level flow control accounting.
- // If this is an outgoing stream, it is technically open from peer's
- // perspective. Do not inform stream Id manager yet.
- QUICHE_DCHECK(!stream->was_draining());
- InsertLocallyClosedStreamsHighestOffset(
- stream_id, stream->highest_received_byte_offset());
- return;
- }
-
- const bool stream_was_draining = stream->was_draining();
- QUIC_DVLOG_IF(1, stream_was_draining)
- << ENDPOINT << "Stream " << stream_id << " was draining";
- if (stream_was_draining) {
- QUIC_BUG_IF(quic_bug_12435_4, num_draining_streams_ == 0);
- --num_draining_streams_;
- if (!IsIncomingStream(stream_id)) {
- QUIC_BUG_IF(quic_bug_12435_5, num_outgoing_draining_streams_ == 0);
- --num_outgoing_draining_streams_;
- }
- // Stream Id manager has been informed with draining streams.
- return;
- }
- if (!VersionHasIetfQuicFrames(transport_version())) {
- stream_id_manager_.OnStreamClosed(
- /*is_incoming=*/IsIncomingStream(stream_id));
- }
- if (!connection_->connected()) {
- return;
- }
- if (IsIncomingStream(stream_id)) {
- // Stream Id manager is only interested in peer initiated stream IDs.
- if (VersionHasIetfQuicFrames(transport_version())) {
- ietf_streamid_manager_.OnStreamClosed(stream_id);
- }
- return;
- }
- if (!VersionHasIetfQuicFrames(transport_version())) {
- OnCanCreateNewOutgoingStream(type != BIDIRECTIONAL);
- }
-}
-
-void QuicSession::ClosePendingStream(QuicStreamId stream_id) {
- QUIC_DVLOG(1) << ENDPOINT << "Closing stream " << stream_id;
- QUICHE_DCHECK(VersionHasIetfQuicFrames(transport_version()));
- pending_stream_map_.erase(stream_id);
- if (connection_->connected()) {
- ietf_streamid_manager_.OnStreamClosed(stream_id);
- }
-}
-
-bool QuicSession::ShouldProcessFrameByPendingStream(QuicFrameType type,
- QuicStreamId id) const {
- return UsesPendingStreamForFrame(type, id) &&
- stream_map_.find(id) == stream_map_.end();
-}
-
-void QuicSession::OnFinalByteOffsetReceived(
- QuicStreamId stream_id, QuicStreamOffset final_byte_offset) {
- auto it = locally_closed_streams_highest_offset_.find(stream_id);
- if (it == locally_closed_streams_highest_offset_.end()) {
- return;
- }
-
- QUIC_DVLOG(1) << ENDPOINT << "Received final byte offset "
- << final_byte_offset << " for stream " << stream_id;
- QuicByteCount offset_diff = final_byte_offset - it->second;
- if (flow_controller_.UpdateHighestReceivedOffset(
- flow_controller_.highest_received_byte_offset() + offset_diff)) {
- // If the final offset violates flow control, close the connection now.
- if (flow_controller_.FlowControlViolation()) {
- connection_->CloseConnection(
- QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA,
- "Connection level flow control violation",
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
- return;
- }
- }
-
- flow_controller_.AddBytesConsumed(offset_diff);
- locally_closed_streams_highest_offset_.erase(it);
- if (!VersionHasIetfQuicFrames(transport_version())) {
- stream_id_manager_.OnStreamClosed(
- /*is_incoming=*/IsIncomingStream(stream_id));
- }
- if (IsIncomingStream(stream_id)) {
- if (VersionHasIetfQuicFrames(transport_version())) {
- ietf_streamid_manager_.OnStreamClosed(stream_id);
- }
- } else if (!VersionHasIetfQuicFrames(transport_version())) {
- OnCanCreateNewOutgoingStream(false);
- }
-}
-
-bool QuicSession::IsEncryptionEstablished() const {
- if (GetCryptoStream() == nullptr) {
- return false;
- }
- return GetCryptoStream()->encryption_established();
-}
-
-bool QuicSession::OneRttKeysAvailable() const {
- if (GetCryptoStream() == nullptr) {
- return false;
- }
- return GetCryptoStream()->one_rtt_keys_available();
-}
-
-void QuicSession::OnConfigNegotiated() {
- // In versions with TLS, the configs will be set twice if 0-RTT is available.
- // In the second config setting, 1-RTT keys are guaranteed to be available.
- if (version().UsesTls() && is_configured_ &&
- connection_->encryption_level() != ENCRYPTION_FORWARD_SECURE) {
- QUIC_BUG(quic_bug_12435_6)
- << ENDPOINT
- << "1-RTT keys missing when config is negotiated for the second time.";
- connection_->CloseConnection(
- QUIC_INTERNAL_ERROR,
- "1-RTT keys missing when config is negotiated for the second time.",
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
- return;
- }
-
- QUIC_DVLOG(1) << ENDPOINT << "OnConfigNegotiated";
- connection_->SetFromConfig(config_);
-
- if (VersionHasIetfQuicFrames(transport_version())) {
- uint32_t max_streams = 0;
- if (config_.HasReceivedMaxBidirectionalStreams()) {
- max_streams = config_.ReceivedMaxBidirectionalStreams();
- }
- if (was_zero_rtt_rejected_ &&
- max_streams <
- ietf_streamid_manager_.outgoing_bidirectional_stream_count()) {
- connection_->CloseConnection(
- QUIC_ZERO_RTT_UNRETRANSMITTABLE,
- absl::StrCat(
- "Server rejected 0-RTT, aborting because new bidirectional "
- "initial stream limit ",
- max_streams, " is less than current open streams: ",
- ietf_streamid_manager_.outgoing_bidirectional_stream_count()),
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
- return;
- }
- QUIC_DVLOG(1) << ENDPOINT
- << "Setting Bidirectional outgoing_max_streams_ to "
- << max_streams;
- if (perspective_ == Perspective::IS_CLIENT &&
- max_streams <
- ietf_streamid_manager_.max_outgoing_bidirectional_streams()) {
- connection_->CloseConnection(
- was_zero_rtt_rejected_ ? QUIC_ZERO_RTT_REJECTION_LIMIT_REDUCED
- : QUIC_ZERO_RTT_RESUMPTION_LIMIT_REDUCED,
- absl::StrCat(
- was_zero_rtt_rejected_
- ? "Server rejected 0-RTT, aborting because "
- : "",
- "new bidirectional limit ", max_streams,
- " decreases the current limit: ",
- ietf_streamid_manager_.max_outgoing_bidirectional_streams()),
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
- return;
- }
- if (ietf_streamid_manager_.MaybeAllowNewOutgoingBidirectionalStreams(
- max_streams)) {
- OnCanCreateNewOutgoingStream(/*unidirectional = */ false);
- }
-
- max_streams = 0;
- if (config_.HasReceivedMaxUnidirectionalStreams()) {
- max_streams = config_.ReceivedMaxUnidirectionalStreams();
- }
-
- if (was_zero_rtt_rejected_ &&
- max_streams <
- ietf_streamid_manager_.outgoing_unidirectional_stream_count()) {
- connection_->CloseConnection(
- QUIC_ZERO_RTT_UNRETRANSMITTABLE,
- absl::StrCat(
- "Server rejected 0-RTT, aborting because new unidirectional "
- "initial stream limit ",
- max_streams, " is less than current open streams: ",
- ietf_streamid_manager_.outgoing_unidirectional_stream_count()),
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
- return;
- }
-
- if (max_streams <
- ietf_streamid_manager_.max_outgoing_unidirectional_streams()) {
- connection_->CloseConnection(
- was_zero_rtt_rejected_ ? QUIC_ZERO_RTT_REJECTION_LIMIT_REDUCED
- : QUIC_ZERO_RTT_RESUMPTION_LIMIT_REDUCED,
- absl::StrCat(
- was_zero_rtt_rejected_
- ? "Server rejected 0-RTT, aborting because "
- : "",
- "new unidirectional limit ", max_streams,
- " decreases the current limit: ",
- ietf_streamid_manager_.max_outgoing_unidirectional_streams()),
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
- return;
- }
- QUIC_DVLOG(1) << ENDPOINT
- << "Setting Unidirectional outgoing_max_streams_ to "
- << max_streams;
- if (ietf_streamid_manager_.MaybeAllowNewOutgoingUnidirectionalStreams(
- max_streams)) {
- OnCanCreateNewOutgoingStream(/*unidirectional = */ true);
- }
- } else {
- uint32_t max_streams = 0;
- if (config_.HasReceivedMaxBidirectionalStreams()) {
- max_streams = config_.ReceivedMaxBidirectionalStreams();
- }
- QUIC_DVLOG(1) << ENDPOINT << "Setting max_open_outgoing_streams_ to "
- << max_streams;
- if (was_zero_rtt_rejected_ &&
- max_streams < stream_id_manager_.num_open_outgoing_streams()) {
- connection_->CloseConnection(
- QUIC_INTERNAL_ERROR,
- absl::StrCat(
- "Server rejected 0-RTT, aborting because new stream limit ",
- max_streams, " is less than current open streams: ",
- stream_id_manager_.num_open_outgoing_streams()),
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
- return;
- }
- stream_id_manager_.set_max_open_outgoing_streams(max_streams);
- }
-
- if (perspective() == Perspective::IS_SERVER) {
- if (config_.HasReceivedConnectionOptions()) {
- // The following variations change the initial receive flow control
- // window sizes.
- if (ContainsQuicTag(config_.ReceivedConnectionOptions(), kIFW6)) {
- AdjustInitialFlowControlWindows(64 * 1024);
- }
- if (ContainsQuicTag(config_.ReceivedConnectionOptions(), kIFW7)) {
- AdjustInitialFlowControlWindows(128 * 1024);
- }
- if (ContainsQuicTag(config_.ReceivedConnectionOptions(), kIFW8)) {
- AdjustInitialFlowControlWindows(256 * 1024);
- }
- if (ContainsQuicTag(config_.ReceivedConnectionOptions(), kIFW9)) {
- AdjustInitialFlowControlWindows(512 * 1024);
- }
- if (ContainsQuicTag(config_.ReceivedConnectionOptions(), kIFWA)) {
- AdjustInitialFlowControlWindows(1024 * 1024);
- }
- }
-
- config_.SetStatelessResetTokenToSend(GetStatelessResetToken());
- }
-
- if (VersionHasIetfQuicFrames(transport_version())) {
- ietf_streamid_manager_.SetMaxOpenIncomingBidirectionalStreams(
- config_.GetMaxBidirectionalStreamsToSend());
- ietf_streamid_manager_.SetMaxOpenIncomingUnidirectionalStreams(
- config_.GetMaxUnidirectionalStreamsToSend());
- } else {
- // A small number of additional incoming streams beyond the limit should be
- // allowed. This helps avoid early connection termination when FIN/RSTs for
- // old streams are lost or arrive out of order.
- // Use a minimum number of additional streams, or a percentage increase,
- // whichever is larger.
- uint32_t max_incoming_streams_to_send =
- config_.GetMaxBidirectionalStreamsToSend();
- uint32_t max_incoming_streams =
- std::max(max_incoming_streams_to_send + kMaxStreamsMinimumIncrement,
- static_cast<uint32_t>(max_incoming_streams_to_send *
- kMaxStreamsMultiplier));
- stream_id_manager_.set_max_open_incoming_streams(max_incoming_streams);
- }
-
- if (connection_->version().handshake_protocol == PROTOCOL_TLS1_3) {
- // When using IETF-style TLS transport parameters, inform existing streams
- // of new flow-control limits.
- if (config_.HasReceivedInitialMaxStreamDataBytesOutgoingBidirectional()) {
- OnNewStreamOutgoingBidirectionalFlowControlWindow(
- config_.ReceivedInitialMaxStreamDataBytesOutgoingBidirectional());
- }
- if (config_.HasReceivedInitialMaxStreamDataBytesIncomingBidirectional()) {
- OnNewStreamIncomingBidirectionalFlowControlWindow(
- config_.ReceivedInitialMaxStreamDataBytesIncomingBidirectional());
- }
- if (config_.HasReceivedInitialMaxStreamDataBytesUnidirectional()) {
- OnNewStreamUnidirectionalFlowControlWindow(
- config_.ReceivedInitialMaxStreamDataBytesUnidirectional());
- }
- } else { // The version uses Google QUIC Crypto.
- if (config_.HasReceivedInitialStreamFlowControlWindowBytes()) {
- // Streams which were created before the SHLO was received (0-RTT
- // requests) are now informed of the peer's initial flow control window.
- OnNewStreamFlowControlWindow(
- config_.ReceivedInitialStreamFlowControlWindowBytes());
- }
- }
-
- if (config_.HasReceivedInitialSessionFlowControlWindowBytes()) {
- OnNewSessionFlowControlWindow(
- config_.ReceivedInitialSessionFlowControlWindowBytes());
- }
-
- is_configured_ = true;
- connection()->OnConfigNegotiated();
-
- // Ask flow controllers to try again since the config could have unblocked us.
- // Or if this session is configured on TLS enabled QUIC versions,
- // attempt to retransmit 0-RTT data if there's any.
- // TODO(fayang): consider removing this OnCanWrite call.
- if (!connection_->framer().is_processing_packet() &&
- (connection_->version().AllowsLowFlowControlLimits() ||
- version().UsesTls())) {
- QUIC_CODE_COUNT(quic_session_on_can_write_on_config_negotiated);
- OnCanWrite();
- }
-}
-
-absl::optional<std::string> QuicSession::OnAlpsData(
- const uint8_t* /*alps_data*/, size_t /*alps_length*/) {
- return absl::nullopt;
-}
-
-void QuicSession::AdjustInitialFlowControlWindows(size_t stream_window) {
- const float session_window_multiplier =
- config_.GetInitialStreamFlowControlWindowToSend()
- ? static_cast<float>(
- config_.GetInitialSessionFlowControlWindowToSend()) /
- config_.GetInitialStreamFlowControlWindowToSend()
- : 1.5;
-
- QUIC_DVLOG(1) << ENDPOINT << "Set stream receive window to " << stream_window;
- config_.SetInitialStreamFlowControlWindowToSend(stream_window);
-
- size_t session_window = session_window_multiplier * stream_window;
- QUIC_DVLOG(1) << ENDPOINT << "Set session receive window to "
- << session_window;
- config_.SetInitialSessionFlowControlWindowToSend(session_window);
- flow_controller_.UpdateReceiveWindowSize(session_window);
- // Inform all existing streams about the new window.
- for (auto const& kv : stream_map_) {
- kv.second->UpdateReceiveWindowSize(stream_window);
- }
- if (!QuicVersionUsesCryptoFrames(transport_version())) {
- GetMutableCryptoStream()->UpdateReceiveWindowSize(stream_window);
- }
-}
-
-void QuicSession::HandleFrameOnNonexistentOutgoingStream(
- QuicStreamId stream_id) {
- QUICHE_DCHECK(!IsClosedStream(stream_id));
- // Received a frame for a locally-created stream that is not currently
- // active. This is an error.
- if (VersionHasIetfQuicFrames(transport_version())) {
- connection()->CloseConnection(
- QUIC_HTTP_STREAM_WRONG_DIRECTION, "Data for nonexistent stream",
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
- return;
- }
- connection()->CloseConnection(
- QUIC_INVALID_STREAM_ID, "Data for nonexistent stream",
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
-}
-
-void QuicSession::HandleRstOnValidNonexistentStream(
- const QuicRstStreamFrame& frame) {
- // If the stream is neither originally in active streams nor created in
- // GetOrCreateStream(), it could be a closed stream in which case its
- // final received byte offset need to be updated.
- if (IsClosedStream(frame.stream_id)) {
- // The RST frame contains the final byte offset for the stream: we can now
- // update the connection level flow controller if needed.
- OnFinalByteOffsetReceived(frame.stream_id, frame.byte_offset);
- }
-}
-
-void QuicSession::OnNewStreamFlowControlWindow(QuicStreamOffset new_window) {
- QUICHE_DCHECK(version().UsesQuicCrypto());
- QUIC_DVLOG(1) << ENDPOINT << "OnNewStreamFlowControlWindow " << new_window;
- if (new_window < kMinimumFlowControlSendWindow) {
- QUIC_LOG_FIRST_N(ERROR, 1)
- << "Peer sent us an invalid stream flow control send window: "
- << new_window << ", below minimum: " << kMinimumFlowControlSendWindow;
- connection_->CloseConnection(
- QUIC_FLOW_CONTROL_INVALID_WINDOW, "New stream window too low",
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
- return;
- }
-
- // Inform all existing streams about the new window.
- for (auto const& kv : stream_map_) {
- QUIC_DVLOG(1) << ENDPOINT << "Informing stream " << kv.first
- << " of new stream flow control window " << new_window;
- if (!kv.second->MaybeConfigSendWindowOffset(
- new_window, /* was_zero_rtt_rejected = */ false)) {
- return;
- }
- }
- if (!QuicVersionUsesCryptoFrames(transport_version())) {
- QUIC_DVLOG(1)
- << ENDPOINT
- << "Informing crypto stream of new stream flow control window "
- << new_window;
- GetMutableCryptoStream()->MaybeConfigSendWindowOffset(
- new_window, /* was_zero_rtt_rejected = */ false);
- }
-}
-
-void QuicSession::OnNewStreamUnidirectionalFlowControlWindow(
- QuicStreamOffset new_window) {
- QUICHE_DCHECK_EQ(connection_->version().handshake_protocol, PROTOCOL_TLS1_3);
- QUIC_DVLOG(1) << ENDPOINT << "OnNewStreamUnidirectionalFlowControlWindow "
- << new_window;
- // Inform all existing outgoing unidirectional streams about the new window.
- for (auto const& kv : stream_map_) {
- const QuicStreamId id = kv.first;
- if (!version().HasIetfQuicFrames()) {
- if (kv.second->type() == BIDIRECTIONAL) {
- continue;
- }
- } else {
- if (QuicUtils::IsBidirectionalStreamId(id, version())) {
- continue;
- }
- }
- if (!QuicUtils::IsOutgoingStreamId(connection_->version(), id,
- perspective())) {
- continue;
- }
- QUIC_DVLOG(1) << ENDPOINT << "Informing unidirectional stream " << id
- << " of new stream flow control window " << new_window;
- if (!kv.second->MaybeConfigSendWindowOffset(new_window,
- was_zero_rtt_rejected_)) {
- return;
- }
- }
-}
-
-void QuicSession::OnNewStreamOutgoingBidirectionalFlowControlWindow(
- QuicStreamOffset new_window) {
- QUICHE_DCHECK_EQ(connection_->version().handshake_protocol, PROTOCOL_TLS1_3);
- QUIC_DVLOG(1) << ENDPOINT
- << "OnNewStreamOutgoingBidirectionalFlowControlWindow "
- << new_window;
- // Inform all existing outgoing bidirectional streams about the new window.
- for (auto const& kv : stream_map_) {
- const QuicStreamId id = kv.first;
- if (!version().HasIetfQuicFrames()) {
- if (kv.second->type() != BIDIRECTIONAL) {
- continue;
- }
- } else {
- if (!QuicUtils::IsBidirectionalStreamId(id, version())) {
- continue;
- }
- }
- if (!QuicUtils::IsOutgoingStreamId(connection_->version(), id,
- perspective())) {
- continue;
- }
- QUIC_DVLOG(1) << ENDPOINT << "Informing outgoing bidirectional stream "
- << id << " of new stream flow control window " << new_window;
- if (!kv.second->MaybeConfigSendWindowOffset(new_window,
- was_zero_rtt_rejected_)) {
- return;
- }
- }
-}
-
-void QuicSession::OnNewStreamIncomingBidirectionalFlowControlWindow(
- QuicStreamOffset new_window) {
- QUICHE_DCHECK_EQ(connection_->version().handshake_protocol, PROTOCOL_TLS1_3);
- QUIC_DVLOG(1) << ENDPOINT
- << "OnNewStreamIncomingBidirectionalFlowControlWindow "
- << new_window;
- // Inform all existing incoming bidirectional streams about the new window.
- for (auto const& kv : stream_map_) {
- const QuicStreamId id = kv.first;
- if (!version().HasIetfQuicFrames()) {
- if (kv.second->type() != BIDIRECTIONAL) {
- continue;
- }
- } else {
- if (!QuicUtils::IsBidirectionalStreamId(id, version())) {
- continue;
- }
- }
- if (QuicUtils::IsOutgoingStreamId(connection_->version(), id,
- perspective())) {
- continue;
- }
- QUIC_DVLOG(1) << ENDPOINT << "Informing incoming bidirectional stream "
- << id << " of new stream flow control window " << new_window;
- if (!kv.second->MaybeConfigSendWindowOffset(new_window,
- was_zero_rtt_rejected_)) {
- return;
- }
- }
-}
-
-void QuicSession::OnNewSessionFlowControlWindow(QuicStreamOffset new_window) {
- QUIC_DVLOG(1) << ENDPOINT << "OnNewSessionFlowControlWindow " << new_window;
-
- if (was_zero_rtt_rejected_ && new_window < flow_controller_.bytes_sent()) {
- std::string error_details = absl::StrCat(
- "Server rejected 0-RTT. Aborting because the client received session "
- "flow control send window: ",
- new_window,
- ", which is below currently used: ", flow_controller_.bytes_sent());
- QUIC_LOG(ERROR) << error_details;
- connection_->CloseConnection(
- QUIC_ZERO_RTT_UNRETRANSMITTABLE, error_details,
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
- return;
- }
- if (!connection_->version().AllowsLowFlowControlLimits() &&
- new_window < kMinimumFlowControlSendWindow) {
- std::string error_details = absl::StrCat(
- "Peer sent us an invalid session flow control send window: ",
- new_window, ", below minimum: ", kMinimumFlowControlSendWindow);
- QUIC_LOG_FIRST_N(ERROR, 1) << error_details;
- connection_->CloseConnection(
- QUIC_FLOW_CONTROL_INVALID_WINDOW, error_details,
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
- return;
- }
- if (perspective_ == Perspective::IS_CLIENT &&
- new_window < flow_controller_.send_window_offset()) {
- // The client receives a lower limit than remembered, violating
- // https://tools.ietf.org/html/draft-ietf-quic-transport-27#section-7.3.1
- std::string error_details = absl::StrCat(
- was_zero_rtt_rejected_ ? "Server rejected 0-RTT, aborting because "
- : "",
- "new session max data ", new_window,
- " decreases current limit: ", flow_controller_.send_window_offset());
- QUIC_LOG(ERROR) << error_details;
- connection_->CloseConnection(
- was_zero_rtt_rejected_ ? QUIC_ZERO_RTT_REJECTION_LIMIT_REDUCED
- : QUIC_ZERO_RTT_RESUMPTION_LIMIT_REDUCED,
- error_details, ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
- return;
- }
-
- flow_controller_.UpdateSendWindowOffset(new_window);
-}
-
-bool QuicSession::OnNewDecryptionKeyAvailable(
- EncryptionLevel level, std::unique_ptr<QuicDecrypter> decrypter,
- bool set_alternative_decrypter, bool latch_once_used) {
- if (connection_->version().handshake_protocol == PROTOCOL_TLS1_3 &&
- !connection()->framer().HasEncrypterOfEncryptionLevel(
- QuicUtils::GetEncryptionLevel(
- QuicUtils::GetPacketNumberSpace(level)))) {
- // This should never happen because connection should never decrypt a packet
- // while an ACK for it cannot be encrypted.
- return false;
- }
- if (connection()->version().KnowsWhichDecrypterToUse()) {
- connection()->InstallDecrypter(level, std::move(decrypter));
- return true;
- }
- if (set_alternative_decrypter) {
- connection()->SetAlternativeDecrypter(level, std::move(decrypter),
- latch_once_used);
- return true;
- }
- connection()->SetDecrypter(level, std::move(decrypter));
- return true;
-}
-
-void QuicSession::OnNewEncryptionKeyAvailable(
- EncryptionLevel level, std::unique_ptr<QuicEncrypter> encrypter) {
- connection()->SetEncrypter(level, std::move(encrypter));
- if (connection_->version().handshake_protocol != PROTOCOL_TLS1_3) {
- return;
- }
-
- bool reset_encryption_level = false;
- if (IsEncryptionEstablished() && level == ENCRYPTION_HANDSHAKE) {
- // ENCRYPTION_HANDSHAKE keys are only used for the handshake. If
- // ENCRYPTION_ZERO_RTT keys exist, it is possible for a client to send
- // stream data, which must not be sent at the ENCRYPTION_HANDSHAKE level.
- // Therefore, we avoid setting the default encryption level to
- // ENCRYPTION_HANDSHAKE.
- reset_encryption_level = true;
- }
- QUIC_DVLOG(1) << ENDPOINT << "Set default encryption level to " << level;
- connection()->SetDefaultEncryptionLevel(level);
- if (reset_encryption_level) {
- connection()->SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
- }
- QUIC_BUG_IF(quic_bug_12435_7,
- IsEncryptionEstablished() &&
- (connection()->encryption_level() == ENCRYPTION_INITIAL ||
- connection()->encryption_level() == ENCRYPTION_HANDSHAKE))
- << "Encryption is established, but the encryption level " << level
- << " does not support sending stream data";
-}
-
-void QuicSession::SetDefaultEncryptionLevel(EncryptionLevel level) {
- QUICHE_DCHECK_EQ(PROTOCOL_QUIC_CRYPTO,
- connection_->version().handshake_protocol);
- QUIC_DVLOG(1) << ENDPOINT << "Set default encryption level to " << level;
- connection()->SetDefaultEncryptionLevel(level);
-
- switch (level) {
- case ENCRYPTION_INITIAL:
- break;
- case ENCRYPTION_ZERO_RTT:
- if (perspective() == Perspective::IS_CLIENT) {
- // Retransmit old 0-RTT data (if any) with the new 0-RTT keys, since
- // they can't be decrypted by the server.
- connection_->MarkZeroRttPacketsForRetransmission(0);
- if (!connection_->framer().is_processing_packet()) {
- // TODO(fayang): consider removing this OnCanWrite call.
- // Given any streams blocked by encryption a chance to write.
- QUIC_CODE_COUNT(
- quic_session_on_can_write_set_default_encryption_level);
- OnCanWrite();
- }
- }
- break;
- case ENCRYPTION_HANDSHAKE:
- break;
- case ENCRYPTION_FORWARD_SECURE:
- QUIC_BUG_IF(quic_bug_12435_8, !config_.negotiated())
- << ENDPOINT << "Handshake confirmed without parameter negotiation.";
- connection()->mutable_stats().handshake_completion_time =
- connection()->clock()->ApproximateNow();
- break;
- default:
- QUIC_BUG(quic_bug_10866_7) << "Unknown encryption level: " << level;
- }
-}
-
-void QuicSession::OnTlsHandshakeComplete() {
- QUICHE_DCHECK_EQ(PROTOCOL_TLS1_3, connection_->version().handshake_protocol);
- QUIC_BUG_IF(quic_bug_12435_9,
- !GetCryptoStream()->crypto_negotiated_params().cipher_suite)
- << ENDPOINT << "Handshake completes without cipher suite negotiation.";
- QUIC_BUG_IF(quic_bug_12435_10, !config_.negotiated())
- << ENDPOINT << "Handshake completes without parameter negotiation.";
- connection()->mutable_stats().handshake_completion_time =
- connection()->clock()->ApproximateNow();
- if (connection()->version().UsesTls() &&
- perspective_ == Perspective::IS_SERVER) {
- // Server sends HANDSHAKE_DONE to signal confirmation of the handshake
- // to the client.
- control_frame_manager_.WriteOrBufferHandshakeDone();
- if (connection()->version().HasIetfQuicFrames()) {
- MaybeSendAddressToken();
- }
- }
-}
-
-bool QuicSession::MaybeSendAddressToken() {
- QUICHE_DCHECK(perspective_ == Perspective::IS_SERVER &&
- connection()->version().HasIetfQuicFrames());
- absl::optional<CachedNetworkParameters> cached_network_params;
- if (add_cached_network_parameters_to_address_token()) {
- cached_network_params = GenerateCachedNetworkParameters();
- }
- std::string address_token = GetCryptoStream()->GetAddressToken(
- cached_network_params.has_value() ? &cached_network_params.value()
- : nullptr);
- if (address_token.empty()) {
- return false;
- }
- const size_t buf_len = address_token.length() + 1;
- auto buffer = std::make_unique<char[]>(buf_len);
- QuicDataWriter writer(buf_len, buffer.get());
- // Add prefix 0 for token sent in NEW_TOKEN frame.
- writer.WriteUInt8(0);
- writer.WriteBytes(address_token.data(), address_token.length());
- control_frame_manager_.WriteOrBufferNewToken(
- absl::string_view(buffer.get(), buf_len));
- if (add_cached_network_parameters_to_address_token() &&
- cached_network_params.has_value()) {
- connection()->OnSendConnectionState(*cached_network_params);
- QUIC_RELOADABLE_FLAG_COUNT_N(
- quic_add_cached_network_parameters_to_address_token2, 1, 2);
- }
- return true;
-}
-
-void QuicSession::DiscardOldDecryptionKey(EncryptionLevel level) {
- if (!connection()->version().KnowsWhichDecrypterToUse()) {
- return;
- }
- connection()->RemoveDecrypter(level);
-}
-
-void QuicSession::DiscardOldEncryptionKey(EncryptionLevel level) {
- QUIC_DLOG(INFO) << ENDPOINT << "Discarding " << level << " keys";
- if (connection()->version().handshake_protocol == PROTOCOL_TLS1_3) {
- connection()->RemoveEncrypter(level);
- }
- switch (level) {
- case ENCRYPTION_INITIAL:
- NeuterUnencryptedData();
- break;
- case ENCRYPTION_HANDSHAKE:
- NeuterHandshakeData();
- break;
- case ENCRYPTION_ZERO_RTT:
- break;
- case ENCRYPTION_FORWARD_SECURE:
- QUIC_BUG(quic_bug_10866_8)
- << ENDPOINT << "Discarding 1-RTT keys is not allowed";
- break;
- default:
- QUIC_BUG(quic_bug_10866_9)
- << ENDPOINT
- << "Cannot discard keys for unknown encryption level: " << level;
- }
-}
-
-void QuicSession::NeuterHandshakeData() {
- GetMutableCryptoStream()->NeuterStreamDataOfEncryptionLevel(
- ENCRYPTION_HANDSHAKE);
- connection()->OnHandshakeComplete();
-}
-
-void QuicSession::OnZeroRttRejected(int reason) {
- was_zero_rtt_rejected_ = true;
- connection_->MarkZeroRttPacketsForRetransmission(reason);
- if (connection_->encryption_level() == ENCRYPTION_FORWARD_SECURE) {
- QUIC_BUG(quic_bug_10866_10)
- << "1-RTT keys already available when 0-RTT is rejected.";
- connection_->CloseConnection(
- QUIC_INTERNAL_ERROR,
- "1-RTT keys already available when 0-RTT is rejected.",
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
- }
-}
-
-bool QuicSession::FillTransportParameters(TransportParameters* params) {
- if (version().UsesTls()) {
- if (perspective() == Perspective::IS_SERVER) {
- config_.SetOriginalConnectionIdToSend(
- connection_->GetOriginalDestinationConnectionId());
- config_.SetInitialSourceConnectionIdToSend(connection_->connection_id());
- } else {
- config_.SetInitialSourceConnectionIdToSend(
- connection_->client_connection_id());
- }
- }
- return config_.FillTransportParameters(params);
-}
-
-QuicErrorCode QuicSession::ProcessTransportParameters(
- const TransportParameters& params, bool is_resumption,
- std::string* error_details) {
- return config_.ProcessTransportParameters(params, is_resumption,
- error_details);
-}
-
-void QuicSession::OnHandshakeCallbackDone() {
- if (!connection_->connected()) {
- return;
- }
-
- if (!connection()->is_processing_packet()) {
- connection()->MaybeProcessUndecryptablePackets();
- }
-}
-
-bool QuicSession::PacketFlusherAttached() const {
- QUICHE_DCHECK(connection_->connected());
- return connection()->packet_creator().PacketFlusherAttached();
-}
-
-void QuicSession::OnCryptoHandshakeMessageSent(
- const CryptoHandshakeMessage& /*message*/) {}
-
-void QuicSession::OnCryptoHandshakeMessageReceived(
- const CryptoHandshakeMessage& /*message*/) {}
-
-void QuicSession::RegisterStreamPriority(
- QuicStreamId id, bool is_static,
- const spdy::SpdyStreamPrecedence& precedence) {
- write_blocked_streams()->RegisterStream(id, is_static, precedence);
-}
-
-void QuicSession::UnregisterStreamPriority(QuicStreamId id, bool is_static) {
- write_blocked_streams()->UnregisterStream(id, is_static);
-}
-
-void QuicSession::UpdateStreamPriority(
- QuicStreamId id, const spdy::SpdyStreamPrecedence& new_precedence) {
- write_blocked_streams()->UpdateStreamPriority(id, new_precedence);
-}
-
-QuicConfig* QuicSession::config() { return &config_; }
-
-void QuicSession::ActivateStream(std::unique_ptr<QuicStream> stream) {
- QuicStreamId stream_id = stream->id();
- bool is_static = stream->is_static();
- QUIC_DVLOG(1) << ENDPOINT << "num_streams: " << stream_map_.size()
- << ". activating stream " << stream_id;
- QUICHE_DCHECK(!stream_map_.contains(stream_id));
- stream_map_[stream_id] = std::move(stream);
- if (is_static) {
- ++num_static_streams_;
- return;
- }
- if (!VersionHasIetfQuicFrames(transport_version())) {
- // Do not inform stream ID manager of static streams.
- stream_id_manager_.ActivateStream(
- /*is_incoming=*/IsIncomingStream(stream_id));
- }
-}
-
-QuicStreamId QuicSession::GetNextOutgoingBidirectionalStreamId() {
- if (VersionHasIetfQuicFrames(transport_version())) {
- return ietf_streamid_manager_.GetNextOutgoingBidirectionalStreamId();
- }
- return stream_id_manager_.GetNextOutgoingStreamId();
-}
-
-QuicStreamId QuicSession::GetNextOutgoingUnidirectionalStreamId() {
- if (VersionHasIetfQuicFrames(transport_version())) {
- return ietf_streamid_manager_.GetNextOutgoingUnidirectionalStreamId();
- }
- return stream_id_manager_.GetNextOutgoingStreamId();
-}
-
-bool QuicSession::CanOpenNextOutgoingBidirectionalStream() {
- if (liveness_testing_in_progress_) {
- QUICHE_DCHECK_EQ(Perspective::IS_CLIENT, perspective());
- return false;
- }
- if (!VersionHasIetfQuicFrames(transport_version())) {
- if (!stream_id_manager_.CanOpenNextOutgoingStream()) {
- return false;
- }
- } else {
- if (!ietf_streamid_manager_.CanOpenNextOutgoingBidirectionalStream()) {
- if (is_configured_) {
- // Send STREAM_BLOCKED after config negotiated.
- control_frame_manager_.WriteOrBufferStreamsBlocked(
- ietf_streamid_manager_.max_outgoing_bidirectional_streams(),
- /*unidirectional=*/false);
- }
- return false;
- }
- }
- if (perspective() == Perspective::IS_CLIENT &&
- connection_->MaybeTestLiveness()) {
- // Now is relatively close to the idle timeout having the risk that requests
- // could be discarded at the server.
- liveness_testing_in_progress_ = true;
- return false;
- }
- return true;
-}
-
-bool QuicSession::CanOpenNextOutgoingUnidirectionalStream() {
- if (!VersionHasIetfQuicFrames(transport_version())) {
- return stream_id_manager_.CanOpenNextOutgoingStream();
- }
- if (ietf_streamid_manager_.CanOpenNextOutgoingUnidirectionalStream()) {
- return true;
- }
- if (is_configured_) {
- // Send STREAM_BLOCKED after config negotiated.
- control_frame_manager_.WriteOrBufferStreamsBlocked(
- ietf_streamid_manager_.max_outgoing_unidirectional_streams(),
- /*unidirectional=*/true);
- }
- return false;
-}
-
-QuicStreamCount QuicSession::GetAdvertisedMaxIncomingBidirectionalStreams()
- const {
- QUICHE_DCHECK(VersionHasIetfQuicFrames(transport_version()));
- return ietf_streamid_manager_.advertised_max_incoming_bidirectional_streams();
-}
-
-QuicStream* QuicSession::GetOrCreateStream(const QuicStreamId stream_id) {
- QUICHE_DCHECK(!pending_stream_map_.contains(stream_id));
- if (QuicUtils::IsCryptoStreamId(transport_version(), stream_id)) {
- return GetMutableCryptoStream();
- }
-
- StreamMap::iterator it = stream_map_.find(stream_id);
- if (it != stream_map_.end()) {
- return it->second->IsZombie() ? nullptr : it->second.get();
- }
-
- if (IsClosedStream(stream_id)) {
- return nullptr;
- }
-
- if (!IsIncomingStream(stream_id)) {
- HandleFrameOnNonexistentOutgoingStream(stream_id);
- return nullptr;
- }
-
- // TODO(fkastenholz): If we are creating a new stream and we have sent a
- // goaway, we should ignore the stream creation. Need to add code to A) test
- // if goaway was sent ("if (transport_goaway_sent_)") and B) reject stream
- // creation ("return nullptr")
-
- if (!MaybeIncreaseLargestPeerStreamId(stream_id)) {
- return nullptr;
- }
-
- if (!VersionHasIetfQuicFrames(transport_version()) &&
- !stream_id_manager_.CanOpenIncomingStream()) {
- // Refuse to open the stream.
- ResetStream(stream_id, QUIC_REFUSED_STREAM);
- return nullptr;
- }
-
- return CreateIncomingStream(stream_id);
-}
-
-void QuicSession::StreamDraining(QuicStreamId stream_id, bool unidirectional) {
- QUICHE_DCHECK(stream_map_.contains(stream_id));
- QUIC_DVLOG(1) << ENDPOINT << "Stream " << stream_id << " is draining";
- if (VersionHasIetfQuicFrames(transport_version())) {
- ietf_streamid_manager_.OnStreamClosed(stream_id);
- } else {
- stream_id_manager_.OnStreamClosed(
- /*is_incoming=*/IsIncomingStream(stream_id));
- }
- ++num_draining_streams_;
- if (!IsIncomingStream(stream_id)) {
- ++num_outgoing_draining_streams_;
- if (!VersionHasIetfQuicFrames(transport_version())) {
- OnCanCreateNewOutgoingStream(unidirectional);
- }
- }
-}
-
-bool QuicSession::MaybeIncreaseLargestPeerStreamId(
- const QuicStreamId stream_id) {
- if (VersionHasIetfQuicFrames(transport_version())) {
- std::string error_details;
- if (ietf_streamid_manager_.MaybeIncreaseLargestPeerStreamId(
- stream_id, &error_details)) {
- return true;
- }
- connection()->CloseConnection(
- QUIC_INVALID_STREAM_ID, error_details,
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
- return false;
- }
- if (!stream_id_manager_.MaybeIncreaseLargestPeerStreamId(stream_id)) {
- connection()->CloseConnection(
- QUIC_TOO_MANY_AVAILABLE_STREAMS,
- absl::StrCat(stream_id, " exceeds available streams ",
- stream_id_manager_.MaxAvailableStreams()),
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
- return false;
- }
- return true;
-}
-
-bool QuicSession::ShouldYield(QuicStreamId stream_id) {
- if (stream_id == currently_writing_stream_id_) {
- return false;
- }
- return write_blocked_streams()->ShouldYield(stream_id);
-}
-
-PendingStream* QuicSession::GetOrCreatePendingStream(QuicStreamId stream_id) {
- auto it = pending_stream_map_.find(stream_id);
- if (it != pending_stream_map_.end()) {
- return it->second.get();
- }
-
- if (IsClosedStream(stream_id) ||
- !MaybeIncreaseLargestPeerStreamId(stream_id)) {
- return nullptr;
- }
-
- auto pending = std::make_unique<PendingStream>(stream_id, this);
- PendingStream* unowned_pending = pending.get();
- pending_stream_map_[stream_id] = std::move(pending);
- return unowned_pending;
-}
-
-void QuicSession::set_largest_peer_created_stream_id(
- QuicStreamId largest_peer_created_stream_id) {
- QUICHE_DCHECK(!VersionHasIetfQuicFrames(transport_version()));
- stream_id_manager_.set_largest_peer_created_stream_id(
- largest_peer_created_stream_id);
-}
-
-QuicStreamId QuicSession::GetLargestPeerCreatedStreamId(
- bool unidirectional) const {
- // This method is only used in IETF QUIC.
- QUICHE_DCHECK(VersionHasIetfQuicFrames(transport_version()));
- return ietf_streamid_manager_.GetLargestPeerCreatedStreamId(unidirectional);
-}
-
-void QuicSession::DeleteConnection() {
- if (connection_) {
- delete connection_;
- connection_ = nullptr;
- }
-}
-
-bool QuicSession::MaybeSetStreamPriority(
- QuicStreamId stream_id, const spdy::SpdyStreamPrecedence& precedence) {
- auto active_stream = stream_map_.find(stream_id);
- if (active_stream != stream_map_.end()) {
- active_stream->second->SetPriority(precedence);
- return true;
- }
-
- return false;
-}
-
-bool QuicSession::IsClosedStream(QuicStreamId id) {
- QUICHE_DCHECK_NE(QuicUtils::GetInvalidStreamId(transport_version()), id);
- if (IsOpenStream(id)) {
- // Stream is active
- return false;
- }
-
- if (VersionHasIetfQuicFrames(transport_version())) {
- return !ietf_streamid_manager_.IsAvailableStream(id);
- }
-
- return !stream_id_manager_.IsAvailableStream(id);
-}
-
-bool QuicSession::IsOpenStream(QuicStreamId id) {
- QUICHE_DCHECK_NE(QuicUtils::GetInvalidStreamId(transport_version()), id);
- const StreamMap::iterator it = stream_map_.find(id);
- if (it != stream_map_.end()) {
- return !it->second->IsZombie();
- }
- if (pending_stream_map_.contains(id) ||
- QuicUtils::IsCryptoStreamId(transport_version(), id)) {
- // Stream is active
- return true;
- }
- return false;
-}
-
-bool QuicSession::IsStaticStream(QuicStreamId id) const {
- auto it = stream_map_.find(id);
- if (it == stream_map_.end()) {
- return false;
- }
- return it->second->is_static();
-}
-
-size_t QuicSession::GetNumActiveStreams() const {
- QUICHE_DCHECK_GE(
- static_cast<QuicStreamCount>(stream_map_.size()),
- num_static_streams_ + num_draining_streams_ + num_zombie_streams_);
- return stream_map_.size() - num_draining_streams_ - num_static_streams_ -
- num_zombie_streams_;
-}
-
-void QuicSession::MarkConnectionLevelWriteBlocked(QuicStreamId id) {
- if (GetOrCreateStream(id) == nullptr) {
- QUIC_BUG(quic_bug_10866_11)
- << "Marking unknown stream " << id << " blocked.";
- QUIC_LOG_FIRST_N(ERROR, 2) << QuicStackTrace();
- }
-
- QUIC_DVLOG(1) << ENDPOINT << "Adding stream " << id
- << " to write-blocked list";
-
- write_blocked_streams_.AddStream(id);
-}
-
-bool QuicSession::HasDataToWrite() const {
- return write_blocked_streams_.HasWriteBlockedSpecialStream() ||
- write_blocked_streams_.HasWriteBlockedDataStreams() ||
- connection_->HasQueuedData() ||
- !streams_with_pending_retransmission_.empty() ||
- control_frame_manager_.WillingToWrite();
-}
-
-void QuicSession::OnAckNeedsRetransmittableFrame() {
- flow_controller_.SendWindowUpdate();
-}
-
-void QuicSession::SendAckFrequency(const QuicAckFrequencyFrame& frame) {
- control_frame_manager_.WriteOrBufferAckFrequency(frame);
-}
-
-void QuicSession::SendNewConnectionId(const QuicNewConnectionIdFrame& frame) {
- // Count NEW_CONNECTION_ID frames sent to client.
- QUIC_RELOADABLE_FLAG_COUNT_N(quic_connection_migration_use_new_cid_v2, 1, 6);
- control_frame_manager_.WriteOrBufferNewConnectionId(
- frame.connection_id, frame.sequence_number, frame.retire_prior_to,
- frame.stateless_reset_token);
-}
-
-void QuicSession::SendRetireConnectionId(uint64_t sequence_number) {
- // Count RETIRE_CONNECTION_ID frames sent to client.
- QUIC_RELOADABLE_FLAG_COUNT_N(quic_connection_migration_use_new_cid_v2, 2, 6);
- control_frame_manager_.WriteOrBufferRetireConnectionId(sequence_number);
-}
-
-void QuicSession::OnServerConnectionIdIssued(
- const QuicConnectionId& server_connection_id) {
- if (visitor_) {
- visitor_->OnNewConnectionIdSent(
- connection_->GetOneActiveServerConnectionId(), server_connection_id);
- }
-}
-
-void QuicSession::OnServerConnectionIdRetired(
- const QuicConnectionId& server_connection_id) {
- if (visitor_) {
- visitor_->OnConnectionIdRetired(server_connection_id);
- }
-}
-
-bool QuicSession::IsConnectionFlowControlBlocked() const {
- return flow_controller_.IsBlocked();
-}
-
-bool QuicSession::IsStreamFlowControlBlocked() {
- for (auto const& kv : stream_map_) {
- if (kv.second->IsFlowControlBlocked()) {
- return true;
- }
- }
- if (!QuicVersionUsesCryptoFrames(transport_version()) &&
- GetMutableCryptoStream()->IsFlowControlBlocked()) {
- return true;
- }
- return false;
-}
-
-size_t QuicSession::MaxAvailableBidirectionalStreams() const {
- if (VersionHasIetfQuicFrames(transport_version())) {
- return ietf_streamid_manager_.GetMaxAllowdIncomingBidirectionalStreams();
- }
- return stream_id_manager_.MaxAvailableStreams();
-}
-
-size_t QuicSession::MaxAvailableUnidirectionalStreams() const {
- if (VersionHasIetfQuicFrames(transport_version())) {
- return ietf_streamid_manager_.GetMaxAllowdIncomingUnidirectionalStreams();
- }
- return stream_id_manager_.MaxAvailableStreams();
-}
-
-bool QuicSession::IsIncomingStream(QuicStreamId id) const {
- if (VersionHasIetfQuicFrames(transport_version())) {
- return !QuicUtils::IsOutgoingStreamId(version(), id, perspective_);
- }
- return stream_id_manager_.IsIncomingStream(id);
-}
-
-void QuicSession::MaybeCloseZombieStream(QuicStreamId id) {
- auto it = stream_map_.find(id);
- if (it == stream_map_.end()) {
- return;
- }
- --num_zombie_streams_;
- closed_streams_.push_back(std::move(it->second));
- stream_map_.erase(it);
-
- if (!closed_streams_clean_up_alarm_->IsSet()) {
- closed_streams_clean_up_alarm_->Set(connection_->clock()->ApproximateNow());
- }
- // 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.";
-}
-
-QuicStream* QuicSession::GetStream(QuicStreamId id) const {
- auto active_stream = stream_map_.find(id);
- if (active_stream != stream_map_.end()) {
- return active_stream->second.get();
- }
-
- if (QuicUtils::IsCryptoStreamId(transport_version(), id)) {
- return const_cast<QuicCryptoStream*>(GetCryptoStream());
- }
-
- return nullptr;
-}
-
-QuicStream* QuicSession::GetActiveStream(QuicStreamId id) const {
- auto stream = stream_map_.find(id);
- if (stream != stream_map_.end() && !stream->second->is_static()) {
- return stream->second.get();
- }
- return nullptr;
-}
-
-bool QuicSession::OnFrameAcked(const QuicFrame& frame,
- QuicTime::Delta ack_delay_time,
- QuicTime receive_timestamp) {
- if (frame.type == MESSAGE_FRAME) {
- OnMessageAcked(frame.message_frame->message_id, receive_timestamp);
- return true;
- }
- if (frame.type == CRYPTO_FRAME) {
- return GetMutableCryptoStream()->OnCryptoFrameAcked(*frame.crypto_frame,
- ack_delay_time);
- }
- if (frame.type != STREAM_FRAME) {
- return control_frame_manager_.OnControlFrameAcked(frame);
- }
- bool new_stream_data_acked = false;
- QuicStream* stream = GetStream(frame.stream_frame.stream_id);
- // Stream can already be reset when sent frame gets acked.
- if (stream != nullptr) {
- QuicByteCount newly_acked_length = 0;
- new_stream_data_acked = stream->OnStreamFrameAcked(
- frame.stream_frame.offset, frame.stream_frame.data_length,
- frame.stream_frame.fin, ack_delay_time, receive_timestamp,
- &newly_acked_length);
- if (!stream->HasPendingRetransmission()) {
- streams_with_pending_retransmission_.erase(stream->id());
- }
- }
- return new_stream_data_acked;
-}
-
-void QuicSession::OnStreamFrameRetransmitted(const QuicStreamFrame& frame) {
- QuicStream* stream = GetStream(frame.stream_id);
- if (stream == nullptr) {
- QUIC_BUG(quic_bug_10866_12)
- << "Stream: " << frame.stream_id << " is closed when " << frame
- << " is retransmitted.";
- connection()->CloseConnection(
- QUIC_INTERNAL_ERROR, "Attempt to retransmit frame of a closed stream",
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
- return;
- }
- stream->OnStreamFrameRetransmitted(frame.offset, frame.data_length,
- frame.fin);
-}
-
-void QuicSession::OnFrameLost(const QuicFrame& frame) {
- if (frame.type == MESSAGE_FRAME) {
- OnMessageLost(frame.message_frame->message_id);
- return;
- }
- if (frame.type == CRYPTO_FRAME) {
- GetMutableCryptoStream()->OnCryptoFrameLost(frame.crypto_frame);
- return;
- }
- if (frame.type != STREAM_FRAME) {
- control_frame_manager_.OnControlFrameLost(frame);
- return;
- }
- QuicStream* stream = GetStream(frame.stream_frame.stream_id);
- if (stream == nullptr) {
- return;
- }
- stream->OnStreamFrameLost(frame.stream_frame.offset,
- frame.stream_frame.data_length,
- frame.stream_frame.fin);
- if (stream->HasPendingRetransmission() &&
- !streams_with_pending_retransmission_.contains(
- frame.stream_frame.stream_id)) {
- streams_with_pending_retransmission_.insert(
- std::make_pair(frame.stream_frame.stream_id, true));
- }
-}
-
-void QuicSession::RetransmitFrames(const QuicFrames& frames,
- TransmissionType type) {
- QuicConnection::ScopedPacketFlusher retransmission_flusher(connection_);
- for (const QuicFrame& frame : frames) {
- if (frame.type == MESSAGE_FRAME) {
- // Do not retransmit MESSAGE frames.
- continue;
- }
- if (frame.type == CRYPTO_FRAME) {
- GetMutableCryptoStream()->RetransmitData(frame.crypto_frame, type);
- continue;
- }
- if (frame.type != STREAM_FRAME) {
- if (!control_frame_manager_.RetransmitControlFrame(frame, type)) {
- break;
- }
- continue;
- }
- QuicStream* stream = GetStream(frame.stream_frame.stream_id);
- if (stream != nullptr &&
- !stream->RetransmitStreamData(frame.stream_frame.offset,
- frame.stream_frame.data_length,
- frame.stream_frame.fin, type)) {
- break;
- }
- }
-}
-
-bool QuicSession::IsFrameOutstanding(const QuicFrame& frame) const {
- if (frame.type == MESSAGE_FRAME) {
- return false;
- }
- if (frame.type == CRYPTO_FRAME) {
- return GetCryptoStream()->IsFrameOutstanding(
- frame.crypto_frame->level, frame.crypto_frame->offset,
- frame.crypto_frame->data_length);
- }
- if (frame.type != STREAM_FRAME) {
- return control_frame_manager_.IsControlFrameOutstanding(frame);
- }
- QuicStream* stream = GetStream(frame.stream_frame.stream_id);
- return stream != nullptr &&
- stream->IsStreamFrameOutstanding(frame.stream_frame.offset,
- frame.stream_frame.data_length,
- frame.stream_frame.fin);
-}
-
-bool QuicSession::HasUnackedCryptoData() const {
- const QuicCryptoStream* crypto_stream = GetCryptoStream();
- return crypto_stream->IsWaitingForAcks() || crypto_stream->HasBufferedData();
-}
-
-bool QuicSession::HasUnackedStreamData() const {
- for (const auto& it : stream_map_) {
- if (it.second->IsWaitingForAcks()) {
- return true;
- }
- }
- return false;
-}
-
-HandshakeState QuicSession::GetHandshakeState() const {
- return GetCryptoStream()->GetHandshakeState();
-}
-
-WriteStreamDataResult QuicSession::WriteStreamData(QuicStreamId id,
- QuicStreamOffset offset,
- QuicByteCount data_length,
- QuicDataWriter* writer) {
- QuicStream* stream = GetStream(id);
- if (stream == nullptr) {
- // This causes the connection to be closed because of failed to serialize
- // packet.
- QUIC_BUG(quic_bug_10866_13)
- << "Stream " << id << " does not exist when trying to write data."
- << " version:" << transport_version();
- return STREAM_MISSING;
- }
- if (stream->WriteStreamData(offset, data_length, writer)) {
- return WRITE_SUCCESS;
- }
- return WRITE_FAILED;
-}
-
-bool QuicSession::WriteCryptoData(EncryptionLevel level,
- QuicStreamOffset offset,
- QuicByteCount data_length,
- QuicDataWriter* writer) {
- return GetMutableCryptoStream()->WriteCryptoFrame(level, offset, data_length,
- writer);
-}
-
-StatelessResetToken QuicSession::GetStatelessResetToken() const {
- return QuicUtils::GenerateStatelessResetToken(connection_->connection_id());
-}
-
-bool QuicSession::CanWriteStreamData() const {
- // Don't write stream data if there are queued data packets.
- if (connection_->HasQueuedPackets()) {
- return false;
- }
- // Immediately write handshake data.
- if (HasPendingHandshake()) {
- return true;
- }
- return connection_->CanWrite(HAS_RETRANSMITTABLE_DATA);
-}
-
-bool QuicSession::RetransmitLostData() {
- QuicConnection::ScopedPacketFlusher retransmission_flusher(connection_);
- // Retransmit crypto data first.
- bool uses_crypto_frames = QuicVersionUsesCryptoFrames(transport_version());
- QuicCryptoStream* crypto_stream = GetMutableCryptoStream();
- if (uses_crypto_frames && crypto_stream->HasPendingCryptoRetransmission()) {
- crypto_stream->WritePendingCryptoRetransmission();
- }
- // Retransmit crypto data in stream 1 frames (version < 47).
- if (!uses_crypto_frames &&
- streams_with_pending_retransmission_.contains(
- QuicUtils::GetCryptoStreamId(transport_version()))) {
- // Retransmit crypto data first.
- QuicStream* crypto_stream =
- GetStream(QuicUtils::GetCryptoStreamId(transport_version()));
- crypto_stream->OnCanWrite();
- QUICHE_DCHECK(CheckStreamWriteBlocked(crypto_stream));
- if (crypto_stream->HasPendingRetransmission()) {
- // Connection is write blocked.
- return false;
- } else {
- streams_with_pending_retransmission_.erase(
- QuicUtils::GetCryptoStreamId(transport_version()));
- }
- }
- if (control_frame_manager_.HasPendingRetransmission()) {
- control_frame_manager_.OnCanWrite();
- if (control_frame_manager_.HasPendingRetransmission()) {
- return false;
- }
- }
- while (!streams_with_pending_retransmission_.empty()) {
- if (!CanWriteStreamData()) {
- break;
- }
- // Retransmit lost data on headers and data streams.
- const QuicStreamId id = streams_with_pending_retransmission_.begin()->first;
- QuicStream* stream = GetStream(id);
- if (stream != nullptr) {
- stream->OnCanWrite();
- QUICHE_DCHECK(CheckStreamWriteBlocked(stream));
- if (stream->HasPendingRetransmission()) {
- // Connection is write blocked.
- break;
- } else if (!streams_with_pending_retransmission_.empty() &&
- streams_with_pending_retransmission_.begin()->first == id) {
- // Retransmit lost data may cause connection close. If this stream
- // has not yet sent fin, a RST_STREAM will be sent and it will be
- // removed from streams_with_pending_retransmission_.
- streams_with_pending_retransmission_.pop_front();
- }
- } else {
- QUIC_BUG(quic_bug_10866_14)
- << "Try to retransmit data of a closed stream";
- streams_with_pending_retransmission_.pop_front();
- }
- }
-
- return streams_with_pending_retransmission_.empty();
-}
-
-void QuicSession::NeuterUnencryptedData() {
- QuicCryptoStream* crypto_stream = GetMutableCryptoStream();
- crypto_stream->NeuterUnencryptedStreamData();
- if (!crypto_stream->HasPendingRetransmission() &&
- !QuicVersionUsesCryptoFrames(transport_version())) {
- streams_with_pending_retransmission_.erase(
- QuicUtils::GetCryptoStreamId(transport_version()));
- }
- connection_->NeuterUnencryptedPackets();
-}
-
-void QuicSession::SetTransmissionType(TransmissionType type) {
- connection_->SetTransmissionType(type);
-}
-
-MessageResult QuicSession::SendMessage(absl::Span<QuicMemSlice> message) {
- return SendMessage(message, /*flush=*/false);
-}
-
-MessageResult QuicSession::SendMessage(QuicMemSlice message) {
- return SendMessage(absl::MakeSpan(&message, 1), /*flush=*/false);
-}
-
-MessageResult QuicSession::SendMessage(absl::Span<QuicMemSlice> message,
- bool flush) {
- QUICHE_DCHECK(connection_->connected())
- << ENDPOINT << "Try to write messages when connection is closed.";
- if (!IsEncryptionEstablished()) {
- return {MESSAGE_STATUS_ENCRYPTION_NOT_ESTABLISHED, 0};
- }
- QuicConnection::ScopedEncryptionLevelContext context(
- connection(), GetEncryptionLevelToSendApplicationData());
- MessageStatus result =
- connection_->SendMessage(last_message_id_ + 1, message, flush);
- if (result == MESSAGE_STATUS_SUCCESS) {
- return {result, ++last_message_id_};
- }
- return {result, 0};
-}
-
-void QuicSession::OnMessageAcked(QuicMessageId message_id,
- QuicTime /*receive_timestamp*/) {
- QUIC_DVLOG(1) << ENDPOINT << "message " << message_id << " gets acked.";
-}
-
-void QuicSession::OnMessageLost(QuicMessageId message_id) {
- QUIC_DVLOG(1) << ENDPOINT << "message " << message_id
- << " is considered lost";
-}
-
-void QuicSession::CleanUpClosedStreams() { closed_streams_.clear(); }
-
-QuicPacketLength QuicSession::GetCurrentLargestMessagePayload() const {
- return connection_->GetCurrentLargestMessagePayload();
-}
-
-QuicPacketLength QuicSession::GetGuaranteedLargestMessagePayload() const {
- return connection_->GetGuaranteedLargestMessagePayload();
-}
-
-QuicStreamId QuicSession::next_outgoing_bidirectional_stream_id() const {
- if (VersionHasIetfQuicFrames(transport_version())) {
- return ietf_streamid_manager_.next_outgoing_bidirectional_stream_id();
- }
- return stream_id_manager_.next_outgoing_stream_id();
-}
-
-QuicStreamId QuicSession::next_outgoing_unidirectional_stream_id() const {
- if (VersionHasIetfQuicFrames(transport_version())) {
- return ietf_streamid_manager_.next_outgoing_unidirectional_stream_id();
- }
- return stream_id_manager_.next_outgoing_stream_id();
-}
-
-bool QuicSession::OnMaxStreamsFrame(const QuicMaxStreamsFrame& frame) {
- const bool allow_new_streams =
- frame.unidirectional
- ? ietf_streamid_manager_.MaybeAllowNewOutgoingUnidirectionalStreams(
- frame.stream_count)
- : ietf_streamid_manager_.MaybeAllowNewOutgoingBidirectionalStreams(
- frame.stream_count);
- if (allow_new_streams) {
- OnCanCreateNewOutgoingStream(frame.unidirectional);
- }
-
- return true;
-}
-
-bool QuicSession::OnStreamsBlockedFrame(const QuicStreamsBlockedFrame& frame) {
- std::string error_details;
- if (ietf_streamid_manager_.OnStreamsBlockedFrame(frame, &error_details)) {
- return true;
- }
- connection_->CloseConnection(
- QUIC_STREAMS_BLOCKED_ERROR, error_details,
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
- return false;
-}
-
-size_t QuicSession::max_open_incoming_bidirectional_streams() const {
- if (VersionHasIetfQuicFrames(transport_version())) {
- return ietf_streamid_manager_.GetMaxAllowdIncomingBidirectionalStreams();
- }
- return stream_id_manager_.max_open_incoming_streams();
-}
-
-size_t QuicSession::max_open_incoming_unidirectional_streams() const {
- if (VersionHasIetfQuicFrames(transport_version())) {
- return ietf_streamid_manager_.GetMaxAllowdIncomingUnidirectionalStreams();
- }
- return stream_id_manager_.max_open_incoming_streams();
-}
-
-std::vector<absl::string_view>::const_iterator QuicSession::SelectAlpn(
- const std::vector<absl::string_view>& alpns) const {
- const std::string alpn = AlpnForVersion(connection()->version());
- return std::find(alpns.cbegin(), alpns.cend(), alpn);
-}
-
-void QuicSession::OnAlpnSelected(absl::string_view alpn) {
- QUIC_DLOG(INFO) << (perspective() == Perspective::IS_SERVER ? "Server: "
- : "Client: ")
- << "ALPN selected: " << alpn;
-}
-
-void QuicSession::NeuterCryptoDataOfEncryptionLevel(EncryptionLevel level) {
- GetMutableCryptoStream()->NeuterStreamDataOfEncryptionLevel(level);
-}
-
-void QuicSession::PerformActionOnActiveStreams(
- std::function<bool(QuicStream*)> action) {
- std::vector<QuicStream*> active_streams;
- for (const auto& it : stream_map_) {
- if (!it.second->is_static() && !it.second->IsZombie()) {
- active_streams.push_back(it.second.get());
- }
- }
-
- for (QuicStream* stream : active_streams) {
- if (!action(stream)) {
- return;
- }
- }
-}
-
-void QuicSession::PerformActionOnActiveStreams(
- std::function<bool(QuicStream*)> action) const {
- for (const auto& it : stream_map_) {
- if (!it.second->is_static() && !it.second->IsZombie() &&
- !action(it.second.get())) {
- return;
- }
- }
-}
-
-EncryptionLevel QuicSession::GetEncryptionLevelToSendApplicationData() const {
- return connection_->framer().GetEncryptionLevelToSendApplicationData();
-}
-
-void QuicSession::ProcessAllPendingStreams() {
- std::vector<PendingStream*> pending_streams;
- pending_streams.reserve(pending_stream_map_.size());
- for (auto it = pending_stream_map_.cbegin(); it != pending_stream_map_.cend();
- ++it) {
- pending_streams.push_back(it->second.get());
- }
- for (auto* pending_stream : pending_streams) {
- MaybeProcessPendingStream(pending_stream);
- if (!connection()->connected()) {
- return;
- }
- }
-}
-
-void QuicSession::ValidatePath(
- std::unique_ptr<QuicPathValidationContext> context,
- std::unique_ptr<QuicPathValidator::ResultDelegate> result_delegate) {
- connection_->ValidatePath(std::move(context), std::move(result_delegate));
-}
-
-bool QuicSession::HasPendingPathValidation() const {
- return connection_->HasPendingPathValidation();
-}
-
-bool QuicSession::MigratePath(const QuicSocketAddress& self_address,
- const QuicSocketAddress& peer_address,
- QuicPacketWriter* writer, bool owns_writer) {
- return connection_->MigratePath(self_address, peer_address, writer,
- owns_writer);
-}
-
-bool QuicSession::ValidateToken(absl::string_view token) {
- QUICHE_DCHECK_EQ(perspective_, Perspective::IS_SERVER);
- if (GetQuicFlag(FLAGS_quic_reject_retry_token_in_initial_packet)) {
- return false;
- }
- if (token.empty() || token[0] != 0) {
- // Validate the prefix for token received in NEW_TOKEN frame.
- return false;
- }
- const bool valid = GetCryptoStream()->ValidateAddressToken(
- absl::string_view(token.data() + 1, token.length() - 1));
- if (add_cached_network_parameters_to_address_token() && valid) {
- const CachedNetworkParameters* cached_network_params =
- GetCryptoStream()->PreviousCachedNetworkParams();
- if (cached_network_params != nullptr &&
- cached_network_params->timestamp() > 0) {
- connection()->OnReceiveConnectionState(*cached_network_params);
- QUIC_RELOADABLE_FLAG_COUNT_N(
- quic_add_cached_network_parameters_to_address_token2, 2, 2);
- }
- }
- return valid;
-}
-
-#undef ENDPOINT // undef for jumbo builds
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_session.h b/chromium/net/third_party/quiche/src/quic/core/quic_session.h
deleted file mode 100644
index 88ae992880d..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_session.h
+++ /dev/null
@@ -1,1028 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// A QuicSession, which demuxes a single connection to individual streams.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_SESSION_H_
-#define QUICHE_QUIC_CORE_QUIC_SESSION_H_
-
-#include <cstddef>
-#include <cstdint>
-#include <map>
-#include <memory>
-#include <string>
-#include <vector>
-
-#include "absl/container/flat_hash_map.h"
-#include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
-#include "absl/types/span.h"
-#include "quic/core/crypto/tls_connection.h"
-#include "quic/core/frames/quic_ack_frequency_frame.h"
-#include "quic/core/frames/quic_stop_sending_frame.h"
-#include "quic/core/frames/quic_window_update_frame.h"
-#include "quic/core/handshaker_delegate_interface.h"
-#include "quic/core/legacy_quic_stream_id_manager.h"
-#include "quic/core/proto/cached_network_parameters_proto.h"
-#include "quic/core/quic_connection.h"
-#include "quic/core/quic_control_frame_manager.h"
-#include "quic/core/quic_crypto_stream.h"
-#include "quic/core/quic_datagram_queue.h"
-#include "quic/core/quic_error_codes.h"
-#include "quic/core/quic_packet_creator.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_path_validator.h"
-#include "quic/core/quic_stream.h"
-#include "quic/core/quic_stream_frame_data_producer.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_write_blocked_list.h"
-#include "quic/core/session_notifier_interface.h"
-#include "quic/core/stream_delegate_interface.h"
-#include "quic/core/uber_quic_stream_id_manager.h"
-#include "quic/platform/api/quic_export.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_mem_slice.h"
-#include "quic/platform/api/quic_socket_address.h"
-#include "common/quiche_linked_hash_map.h"
-
-namespace quic {
-
-class QuicCryptoStream;
-class QuicFlowController;
-class QuicStream;
-class QuicStreamIdManager;
-
-namespace test {
-class QuicSessionPeer;
-} // namespace test
-
-class QUIC_EXPORT_PRIVATE QuicSession
- : public QuicConnectionVisitorInterface,
- public SessionNotifierInterface,
- public QuicStreamFrameDataProducer,
- public QuicStreamIdManager::DelegateInterface,
- public HandshakerDelegateInterface,
- public StreamDelegateInterface,
- public QuicControlFrameManager::DelegateInterface {
- public:
- // An interface from the session to the entity owning the session.
- // This lets the session notify its owner (the Dispatcher) when the connection
- // is closed, blocked, or added/removed from the time-wait list.
- class QUIC_EXPORT_PRIVATE Visitor {
- public:
- virtual ~Visitor() {}
-
- // Called when the connection is closed after the streams have been closed.
- virtual void OnConnectionClosed(QuicConnectionId server_connection_id,
- QuicErrorCode error,
- const std::string& error_details,
- ConnectionCloseSource source) = 0;
-
- // Called when the session has become write blocked.
- virtual void OnWriteBlocked(QuicBlockedWriterInterface* blocked_writer) = 0;
-
- // Called when the session receives reset on a stream from the peer.
- virtual void OnRstStreamReceived(const QuicRstStreamFrame& frame) = 0;
-
- // Called when the session receives a STOP_SENDING for a stream from the
- // peer.
- virtual void OnStopSendingReceived(const QuicStopSendingFrame& frame) = 0;
-
- // Called when a NewConnectionId frame has been sent.
- virtual void OnNewConnectionIdSent(
- const QuicConnectionId& server_connection_id,
- const QuicConnectionId& new_connection_id) = 0;
-
- // Called when a ConnectionId has been retired.
- virtual void OnConnectionIdRetired(
- const QuicConnectionId& server_connection_id) = 0;
- };
-
- // Does not take ownership of |connection| or |visitor|.
- QuicSession(QuicConnection* connection, Visitor* owner,
- const QuicConfig& config,
- const ParsedQuicVersionVector& supported_versions,
- QuicStreamCount num_expected_unidirectional_static_streams);
- QuicSession(QuicConnection* connection, Visitor* owner,
- const QuicConfig& config,
- const ParsedQuicVersionVector& supported_versions,
- QuicStreamCount num_expected_unidirectional_static_streams,
- std::unique_ptr<QuicDatagramQueue::Observer> datagram_observer);
- QuicSession(const QuicSession&) = delete;
- QuicSession& operator=(const QuicSession&) = delete;
-
- ~QuicSession() override;
-
- virtual void Initialize();
-
- // Return the reserved crypto stream as a constant pointer.
- virtual const QuicCryptoStream* GetCryptoStream() const = 0;
-
- // QuicConnectionVisitorInterface methods:
- void OnStreamFrame(const QuicStreamFrame& frame) override;
- void OnCryptoFrame(const QuicCryptoFrame& frame) override;
- void OnRstStream(const QuicRstStreamFrame& frame) override;
- void OnGoAway(const QuicGoAwayFrame& frame) override;
- void OnMessageReceived(absl::string_view message) override;
- void OnHandshakeDoneReceived() override;
- void OnNewTokenReceived(absl::string_view token) override;
- void OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame) override;
- void OnBlockedFrame(const QuicBlockedFrame& frame) override;
- void OnConnectionClosed(const QuicConnectionCloseFrame& frame,
- ConnectionCloseSource source) override;
- void OnWriteBlocked() override;
- void OnSuccessfulVersionNegotiation(
- const ParsedQuicVersion& version) override;
- void OnPacketReceived(const QuicSocketAddress& self_address,
- const QuicSocketAddress& peer_address,
- bool is_connectivity_probe) override;
- void OnCanWrite() override;
- bool SendProbingData() override;
- bool ValidateStatelessReset(
- const quic::QuicSocketAddress& /*self_address*/,
- const quic::QuicSocketAddress& /*peer_address*/) override {
- return true;
- }
- void OnCongestionWindowChange(QuicTime /*now*/) override {}
- void OnConnectionMigration(AddressChangeType /*type*/) override {}
- // Adds a connection level WINDOW_UPDATE frame.
- void OnAckNeedsRetransmittableFrame() override;
- void SendAckFrequency(const QuicAckFrequencyFrame& frame) override;
- void SendNewConnectionId(const QuicNewConnectionIdFrame& frame) override;
- void SendRetireConnectionId(uint64_t sequence_number) override;
- void OnServerConnectionIdIssued(
- const QuicConnectionId& server_connection_id) override;
- void OnServerConnectionIdRetired(
- const QuicConnectionId& server_connection_id) override;
- bool WillingAndAbleToWrite() const override;
- std::string GetStreamsInfoForLogging() const override;
- void OnPathDegrading() override;
- void OnForwardProgressMadeAfterPathDegrading() override;
- bool AllowSelfAddressChange() const override;
- HandshakeState GetHandshakeState() const override;
- bool OnMaxStreamsFrame(const QuicMaxStreamsFrame& frame) override;
- bool OnStreamsBlockedFrame(const QuicStreamsBlockedFrame& frame) override;
- void OnStopSendingFrame(const QuicStopSendingFrame& frame) override;
- void OnPacketDecrypted(EncryptionLevel level) override;
- void OnOneRttPacketAcknowledged() override;
- void OnHandshakePacketSent() override;
- void OnKeyUpdate(KeyUpdateReason /*reason*/) override {}
- std::unique_ptr<QuicDecrypter> AdvanceKeysAndCreateCurrentOneRttDecrypter()
- override;
- std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() override;
- void BeforeConnectionCloseSent() override {}
- bool ValidateToken(absl::string_view token) override;
- bool MaybeSendAddressToken() override;
- bool IsKnownServerAddress(
- const QuicSocketAddress& /*address*/) const override {
- return false;
- }
-
- // QuicStreamFrameDataProducer
- WriteStreamDataResult WriteStreamData(QuicStreamId id,
- QuicStreamOffset offset,
- QuicByteCount data_length,
- QuicDataWriter* writer) override;
- bool WriteCryptoData(EncryptionLevel level, QuicStreamOffset offset,
- QuicByteCount data_length,
- QuicDataWriter* writer) override;
-
- // SessionNotifierInterface methods:
- bool OnFrameAcked(const QuicFrame& frame, QuicTime::Delta ack_delay_time,
- QuicTime receive_timestamp) override;
- void OnStreamFrameRetransmitted(const QuicStreamFrame& frame) override;
- void OnFrameLost(const QuicFrame& frame) override;
- void RetransmitFrames(const QuicFrames& frames,
- TransmissionType type) override;
- bool IsFrameOutstanding(const QuicFrame& frame) const override;
- bool HasUnackedCryptoData() const override;
- bool HasUnackedStreamData() const override;
-
- void SendMaxStreams(QuicStreamCount stream_count,
- bool unidirectional) override;
- // The default implementation does nothing. Subclasses should override if
- // for example they queue up stream requests.
- virtual void OnCanCreateNewOutgoingStream(bool /*unidirectional*/) {}
-
- // Called on every incoming packet. Passes |packet| through to |connection_|.
- virtual void ProcessUdpPacket(const QuicSocketAddress& self_address,
- const QuicSocketAddress& peer_address,
- const QuicReceivedPacket& packet);
-
- // Sends |message| as a QUIC DATAGRAM frame (QUIC MESSAGE frame in gQUIC).
- // See <https://datatracker.ietf.org/doc/html/draft-ietf-quic-datagram> for
- // more details.
- //
- // Returns a MessageResult struct which includes the status of the write
- // operation and a message ID. The message ID (not sent on the wire) can be
- // used to track the message; OnMessageAcked and OnMessageLost are called when
- // a specific message gets acked or lost.
- //
- // If the write operation is successful, all of the slices in |message| are
- // consumed, leaving them empty. If MESSAGE_STATUS_INTERNAL_ERROR is
- // returned, the slices in question may or may not be consumed; it is no
- // longer safe to access those. For all other status codes, |message| is kept
- // intact.
- //
- // Note that SendMessage will fail with status = MESSAGE_STATUS_BLOCKED
- // if the connection is congestion control blocked or the underlying socket is
- // write blocked. In this case the caller can retry sending message again when
- // connection becomes available, for example after getting OnCanWrite()
- // callback.
- //
- // SendMessage flushes the current packet even it is not full; if the
- // application needs to bundle other data in the same packet, consider using
- // QuicConnection::ScopedPacketFlusher around the relevant write operations.
- MessageResult SendMessage(absl::Span<QuicMemSlice> message);
-
- // Same as above SendMessage, except caller can specify if the given |message|
- // should be flushed even if the underlying connection is deemed unwritable.
- MessageResult SendMessage(absl::Span<QuicMemSlice> message, bool flush);
-
- // Single-slice version of SendMessage(). Unlike the version above, this
- // version always takes ownership of the slice.
- MessageResult SendMessage(QuicMemSlice message);
-
- // Called when message with |message_id| gets acked.
- virtual void OnMessageAcked(QuicMessageId message_id,
- QuicTime receive_timestamp);
-
- // Called when message with |message_id| is considered as lost.
- virtual void OnMessageLost(QuicMessageId message_id);
-
- // QuicControlFrameManager::DelegateInterface
- // Close the connection on error.
- void OnControlFrameManagerError(QuicErrorCode error_code,
- std::string error_details) override;
- // Called by control frame manager when it wants to write control frames to
- // the peer. Returns true if |frame| is consumed, false otherwise. The frame
- // will be sent in specified transmission |type|.
- bool WriteControlFrame(const QuicFrame& frame,
- TransmissionType type) override;
-
- // Called to send RST_STREAM (and STOP_SENDING) and close stream. If stream
- // |id| does not exist, just send RST_STREAM (and STOP_SENDING).
- virtual void ResetStream(QuicStreamId id, QuicRstStreamErrorCode error);
-
- // Called when the session wants to go away and not accept any new streams.
- virtual void SendGoAway(QuicErrorCode error_code, const std::string& reason);
-
- // Sends a BLOCKED frame.
- virtual void SendBlocked(QuicStreamId id);
-
- // Sends a WINDOW_UPDATE frame.
- virtual void SendWindowUpdate(QuicStreamId id, QuicStreamOffset byte_offset);
-
- // Called by stream |stream_id| when it gets closed.
- virtual void OnStreamClosed(QuicStreamId stream_id);
-
- // Returns true if outgoing packets will be encrypted, even if the server
- // hasn't confirmed the handshake yet.
- virtual bool IsEncryptionEstablished() const;
-
- // Returns true if 1RTT keys are available.
- bool OneRttKeysAvailable() const;
-
- // Called by the QuicCryptoStream when a new QuicConfig has been negotiated.
- virtual void OnConfigNegotiated();
-
- // Called by the TLS handshaker when ALPS data is received.
- // Returns an error message if an error has occurred, or nullopt otherwise.
- virtual absl::optional<std::string> OnAlpsData(const uint8_t* alps_data,
- size_t alps_length);
-
- // From HandshakerDelegateInterface
- bool OnNewDecryptionKeyAvailable(EncryptionLevel level,
- std::unique_ptr<QuicDecrypter> decrypter,
- bool set_alternative_decrypter,
- bool latch_once_used) override;
- void OnNewEncryptionKeyAvailable(
- EncryptionLevel level, std::unique_ptr<QuicEncrypter> encrypter) override;
- void SetDefaultEncryptionLevel(EncryptionLevel level) override;
- void OnTlsHandshakeComplete() override;
- void DiscardOldDecryptionKey(EncryptionLevel level) override;
- void DiscardOldEncryptionKey(EncryptionLevel level) override;
- void NeuterUnencryptedData() override;
- void NeuterHandshakeData() override;
- void OnZeroRttRejected(int reason) override;
- bool FillTransportParameters(TransportParameters* params) override;
- QuicErrorCode ProcessTransportParameters(const TransportParameters& params,
- bool is_resumption,
- std::string* error_details) override;
- void OnHandshakeCallbackDone() override;
- bool PacketFlusherAttached() const override;
- ParsedQuicVersion parsed_version() const override { return version(); }
-
- // Implement StreamDelegateInterface.
- void OnStreamError(QuicErrorCode error_code,
- std::string error_details) override;
- void OnStreamError(QuicErrorCode error_code,
- QuicIetfTransportErrorCodes ietf_error,
- std::string error_details) override;
- // Sets priority in the write blocked list.
- void RegisterStreamPriority(
- QuicStreamId id, bool is_static,
- const spdy::SpdyStreamPrecedence& precedence) override;
- // Clears priority from the write blocked list.
- void UnregisterStreamPriority(QuicStreamId id, bool is_static) override;
- // Updates priority on the write blocked list.
- void UpdateStreamPriority(
- QuicStreamId id,
- const spdy::SpdyStreamPrecedence& new_precedence) override;
-
- // Called by streams when they want to write data to the peer.
- // Returns a pair with the number of bytes consumed from data, and a boolean
- // indicating if the fin bit was consumed. This does not indicate the data
- // has been sent on the wire: it may have been turned into a packet and queued
- // if the socket was unexpectedly blocked.
- QuicConsumedData WritevData(QuicStreamId id, size_t write_length,
- QuicStreamOffset offset, StreamSendingState state,
- TransmissionType type,
- EncryptionLevel level) override;
-
- size_t SendCryptoData(EncryptionLevel level, size_t write_length,
- QuicStreamOffset offset,
- TransmissionType type) override;
-
- // Called by the QuicCryptoStream when a handshake message is sent.
- virtual void OnCryptoHandshakeMessageSent(
- const CryptoHandshakeMessage& message);
-
- // Called by the QuicCryptoStream when a handshake message is received.
- virtual void OnCryptoHandshakeMessageReceived(
- const CryptoHandshakeMessage& message);
-
- // Returns mutable config for this session. Returned config is owned
- // by QuicSession.
- QuicConfig* config();
-
- // Returns true if the stream existed previously and has been closed.
- // Returns false if the stream is still active or if the stream has
- // not yet been created.
- bool IsClosedStream(QuicStreamId id);
-
- QuicConnection* connection() { return connection_; }
- const QuicConnection* connection() const { return connection_; }
- const QuicSocketAddress& peer_address() const {
- return connection_->peer_address();
- }
- const QuicSocketAddress& self_address() const {
- return connection_->self_address();
- }
- QuicConnectionId connection_id() const {
- return connection_->connection_id();
- }
-
- // Returns the number of currently open streams, excluding static streams, and
- // never counting unfinished streams.
- size_t GetNumActiveStreams() const;
-
- // Add the stream to the session's write-blocked list because it is blocked by
- // connection-level flow control but not by its own stream-level flow control.
- // The stream will be given a chance to write when a connection-level
- // WINDOW_UPDATE arrives.
- virtual void MarkConnectionLevelWriteBlocked(QuicStreamId id);
-
- // Called to close zombie stream |id|.
- void MaybeCloseZombieStream(QuicStreamId id);
-
- // Returns true if there is pending handshake data in the crypto stream.
- // TODO(ianswett): Make this private or remove.
- bool HasPendingHandshake() const;
-
- // Returns true if the session has data to be sent, either queued in the
- // connection, or in a write-blocked stream.
- bool HasDataToWrite() const;
-
- // Initiates a path validation on the path described in the given context,
- // asynchronously calls |result_delegate| upon success or failure.
- // The initiator should extend QuicPathValidationContext to provide the writer
- // and ResultDelegate to react upon the validation result.
- // Example implementations of these for path validation for connection
- // migration could be:
- // class QUIC_EXPORT_PRIVATE PathMigrationContext
- // : public QuicPathValidationContext {
- // public:
- // PathMigrationContext(std::unique_ptr<QuicPacketWriter> writer,
- // const QuicSocketAddress& self_address,
- // const QuicSocketAddress& peer_address)
- // : QuicPathValidationContext(self_address, peer_address),
- // alternative_writer_(std::move(writer)) {}
- //
- // QuicPacketWriter* WriterToUse() override {
- // return alternative_writer_.get();
- // }
- //
- // QuicPacketWriter* ReleaseWriter() {
- // return alternative_writer_.release();
- // }
- //
- // private:
- // std::unique_ptr<QuicPacketWriter> alternative_writer_;
- // };
- //
- // class PathMigrationValidationResultDelegate
- // : public QuicPathValidator::ResultDelegate {
- // public:
- // PathMigrationValidationResultDelegate(QuicConnection* connection)
- // : QuicPathValidator::ResultDelegate(), connection_(connection) {}
- //
- // void OnPathValidationSuccess(
- // std::unique_ptr<QuicPathValidationContext> context) override {
- // // Do some work to prepare for migration.
- // // ...
- //
- // // Actually migrate to the validated path.
- // auto migration_context = std::unique_ptr<PathMigrationContext>(
- // static_cast<PathMigrationContext*>(context.release()));
- // connection_->MigratePath(migration_context->self_address(),
- // migration_context->peer_address(),
- // migration_context->ReleaseWriter(),
- // /*owns_writer=*/true);
- //
- // // Post-migration actions
- // // ...
- // }
- //
- // void OnPathValidationFailure(
- // std::unique_ptr<QuicPathValidationContext> /*context*/) override {
- // // Handle validation failure.
- // }
- //
- // private:
- // QuicConnection* connection_;
- // };
- void ValidatePath(
- std::unique_ptr<QuicPathValidationContext> context,
- std::unique_ptr<QuicPathValidator::ResultDelegate> result_delegate);
-
- // Return true if there is a path being validated.
- bool HasPendingPathValidation() const;
-
- // Switch to the path described in |context| without validating the path.
- bool MigratePath(const QuicSocketAddress& self_address,
- const QuicSocketAddress& peer_address,
- QuicPacketWriter* writer, bool owns_writer);
-
- // Returns the largest payload that will fit into a single MESSAGE frame.
- // Because overhead can vary during a connection, this method should be
- // checked for every message.
- QuicPacketLength GetCurrentLargestMessagePayload() const;
-
- // Returns the largest payload that will fit into a single MESSAGE frame at
- // any point during the connection. This assumes the version and
- // connection ID lengths do not change.
- QuicPacketLength GetGuaranteedLargestMessagePayload() const;
-
- bool transport_goaway_sent() const { return transport_goaway_sent_; }
-
- bool transport_goaway_received() const { return transport_goaway_received_; }
-
- // Returns the Google QUIC error code
- QuicErrorCode error() const { return on_closed_frame_.quic_error_code; }
- const std::string& error_details() const {
- return on_closed_frame_.error_details;
- }
- uint64_t transport_close_frame_type() const {
- return on_closed_frame_.transport_close_frame_type;
- }
- QuicConnectionCloseType close_type() const {
- return on_closed_frame_.close_type;
- }
-
- Perspective perspective() const { return perspective_; }
-
- QuicFlowController* flow_controller() { return &flow_controller_; }
-
- // Returns true if connection is flow controller blocked.
- bool IsConnectionFlowControlBlocked() const;
-
- // Returns true if any stream is flow controller blocked.
- bool IsStreamFlowControlBlocked();
-
- size_t max_open_incoming_bidirectional_streams() const;
- size_t max_open_incoming_unidirectional_streams() const;
-
- size_t MaxAvailableBidirectionalStreams() const;
- size_t MaxAvailableUnidirectionalStreams() const;
-
- // Returns existing stream with id = |stream_id|. If no
- // such stream exists, and |stream_id| is a peer-created stream id,
- // then a new stream is created and returned. In all other cases, nullptr is
- // returned.
- // Caller does not own the returned stream.
- QuicStream* GetOrCreateStream(const QuicStreamId stream_id);
-
- // Mark a stream as draining.
- void StreamDraining(QuicStreamId id, bool unidirectional);
-
- // Returns true if this stream should yield writes to another blocked stream.
- virtual bool ShouldYield(QuicStreamId stream_id);
-
- // Clean up closed_streams_.
- void CleanUpClosedStreams();
-
- const ParsedQuicVersionVector& supported_versions() const {
- return supported_versions_;
- }
-
- QuicStreamId next_outgoing_bidirectional_stream_id() const;
- QuicStreamId next_outgoing_unidirectional_stream_id() const;
-
- // Return true if given stream is peer initiated.
- bool IsIncomingStream(QuicStreamId id) const;
-
- // Record errors when a connection is closed at the server side, should only
- // be called from server's perspective.
- // Noop if |error| is QUIC_NO_ERROR.
- static void RecordConnectionCloseAtServer(QuicErrorCode error,
- ConnectionCloseSource source);
-
- inline QuicTransportVersion transport_version() const {
- return connection_->transport_version();
- }
-
- inline ParsedQuicVersion version() const { return connection_->version(); }
-
- bool is_configured() const { return is_configured_; }
-
- // Called to neuter crypto data of encryption |level|.
- void NeuterCryptoDataOfEncryptionLevel(EncryptionLevel level);
-
- // Returns the ALPN values to negotiate on this session.
- virtual std::vector<std::string> GetAlpnsToOffer() const {
- // TODO(vasilvv): this currently sets HTTP/3 by default. Switch all
- // non-HTTP applications to appropriate ALPNs.
- return std::vector<std::string>({AlpnForVersion(connection()->version())});
- }
-
- // Provided a list of ALPNs offered by the client, selects an ALPN from the
- // list, or alpns.end() if none of the ALPNs are acceptable.
- virtual std::vector<absl::string_view>::const_iterator SelectAlpn(
- const std::vector<absl::string_view>& alpns) const;
-
- // Called when the ALPN of the connection is established for a connection that
- // uses TLS handshake.
- virtual void OnAlpnSelected(absl::string_view alpn);
-
- // Called on clients by the crypto handshaker to provide application state
- // necessary for sending application data in 0-RTT. The state provided here is
- // the same state that was provided to the crypto handshaker in
- // QuicCryptoStream::SetServerApplicationStateForResumption on a previous
- // connection. Application protocols that require state to be carried over
- // from the previous connection to support 0-RTT data must implement this
- // method to ingest this state. For example, an HTTP/3 QuicSession would
- // implement this function to process the remembered server SETTINGS and apply
- // those SETTINGS to 0-RTT data. This function returns true if the application
- // state has been successfully processed, and false if there was an error
- // processing the cached state and the connection should be closed.
- virtual bool ResumeApplicationState(ApplicationState* /*cached_state*/) {
- return true;
- }
-
- // Does actual work of sending RESET_STREAM, if the stream type allows.
- // Also informs the connection so that pending stream frames can be flushed.
- virtual void MaybeSendRstStreamFrame(QuicStreamId id,
- QuicResetStreamError error,
- QuicStreamOffset bytes_written);
-
- // Sends a STOP_SENDING frame if the stream type allows.
- virtual void MaybeSendStopSendingFrame(QuicStreamId id,
- QuicResetStreamError error);
-
- // Returns the encryption level to send application data.
- EncryptionLevel GetEncryptionLevelToSendApplicationData() const;
-
- const absl::optional<std::string> user_agent_id() const {
- return user_agent_id_;
- }
-
- // TODO(wub): remove saving user-agent to QuicSession.
- void SetUserAgentId(std::string user_agent_id) {
- user_agent_id_ = std::move(user_agent_id);
- connection()->OnUserAgentIdKnown(user_agent_id_.value());
- }
-
- void SetSourceAddressTokenToSend(absl::string_view token) {
- connection()->SetSourceAddressTokenToSend(token);
- }
-
- const QuicClock* GetClock() const {
- return connection()->helper()->GetClock();
- }
-
- bool liveness_testing_in_progress() const {
- return liveness_testing_in_progress_;
- }
-
- bool permutes_tls_extensions() const { return permutes_tls_extensions_; }
-
- 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_; }
-
- // Get latched flag value.
- bool add_cached_network_parameters_to_address_token() const {
- return add_cached_network_parameters_to_address_token_;
- }
-
- // Try converting all pending streams to normal streams.
- void ProcessAllPendingStreams();
-
- const ParsedQuicVersionVector& client_original_supported_versions() const {
- QUICHE_DCHECK_EQ(perspective_, Perspective::IS_CLIENT);
- return client_original_supported_versions_;
- }
- void set_client_original_supported_versions(
- const ParsedQuicVersionVector& client_original_supported_versions) {
- QUICHE_DCHECK_EQ(perspective_, Perspective::IS_CLIENT);
- client_original_supported_versions_ = client_original_supported_versions;
- }
-
- protected:
- using StreamMap =
- absl::flat_hash_map<QuicStreamId, std::unique_ptr<QuicStream>>;
-
- using PendingStreamMap =
- absl::flat_hash_map<QuicStreamId, std::unique_ptr<PendingStream>>;
-
- using ClosedStreams = std::vector<std::unique_ptr<QuicStream>>;
-
- using ZombieStreamMap =
- absl::flat_hash_map<QuicStreamId, std::unique_ptr<QuicStream>>;
-
- // Creates a new stream to handle a peer-initiated stream.
- // Caller does not own the returned stream.
- // Returns nullptr and does error handling if the stream can not be created.
- virtual QuicStream* CreateIncomingStream(QuicStreamId id) = 0;
- virtual QuicStream* CreateIncomingStream(PendingStream* pending) = 0;
-
- // Return the reserved crypto stream.
- virtual QuicCryptoStream* GetMutableCryptoStream() = 0;
-
- // Adds |stream| to the stream map.
- virtual void ActivateStream(std::unique_ptr<QuicStream> stream);
-
- // Set transmission type of next sending packets.
- void SetTransmissionType(TransmissionType type);
-
- // Returns the stream ID for a new outgoing bidirectional/unidirectional
- // stream, and increments the underlying counter.
- QuicStreamId GetNextOutgoingBidirectionalStreamId();
- QuicStreamId GetNextOutgoingUnidirectionalStreamId();
-
- // Indicates whether the next outgoing bidirectional/unidirectional stream ID
- // can be allocated or not. The test for version-99/IETF QUIC is whether it
- // will exceed the maximum-stream-id or not. For non-version-99 (Google) QUIC
- // it checks whether the next stream would exceed the limit on the number of
- // open streams.
- bool CanOpenNextOutgoingBidirectionalStream();
- bool CanOpenNextOutgoingUnidirectionalStream();
-
- // Returns the maximum bidirectional streams parameter sent with the handshake
- // as a transport parameter, or in the most recent MAX_STREAMS frame.
- QuicStreamCount GetAdvertisedMaxIncomingBidirectionalStreams() const;
-
- // When a stream is closed locally, it may not yet know how many bytes the
- // peer sent on that stream.
- // When this data arrives (via stream frame w. FIN, trailing headers, or RST)
- // this method is called, and correctly updates the connection level flow
- // controller.
- virtual void OnFinalByteOffsetReceived(QuicStreamId id,
- QuicStreamOffset final_byte_offset);
-
- // Returns true if a frame with the given type and id can be prcoessed by a
- // PendingStream. However, the frame will always be processed by a QuicStream
- // if one exists with the given stream_id.
- virtual bool UsesPendingStreamForFrame(QuicFrameType /*type*/,
- QuicStreamId /*stream_id*/) const {
- return false;
- }
-
- // Returns true if a pending stream should be converted to a real stream after
- // a corresponding STREAM_FRAME is received.
- virtual bool ShouldProcessPendingStreamImmediately() const { return true; }
-
- spdy::SpdyPriority GetSpdyPriorityofStream(QuicStreamId stream_id) const {
- return write_blocked_streams_.GetSpdyPriorityofStream(stream_id);
- }
-
- size_t pending_streams_size() const { return pending_stream_map_.size(); }
-
- ClosedStreams* closed_streams() { return &closed_streams_; }
-
- void set_largest_peer_created_stream_id(
- QuicStreamId largest_peer_created_stream_id);
-
- QuicWriteBlockedList* write_blocked_streams() {
- return &write_blocked_streams_;
- }
-
- // Returns true if the stream is still active.
- bool IsOpenStream(QuicStreamId id);
-
- // Returns true if the stream is a static stream.
- bool IsStaticStream(QuicStreamId id) const;
-
- // Close connection when receive a frame for a locally-created nonexistent
- // stream.
- // Prerequisite: IsClosedStream(stream_id) == false
- // Server session might need to override this method to allow server push
- // stream to be promised before creating an active stream.
- virtual void HandleFrameOnNonexistentOutgoingStream(QuicStreamId stream_id);
-
- virtual bool MaybeIncreaseLargestPeerStreamId(const QuicStreamId stream_id);
-
- void InsertLocallyClosedStreamsHighestOffset(const QuicStreamId id,
- QuicStreamOffset offset);
- // If stream is a locally closed stream, this RST will update FIN offset.
- // Otherwise stream is a preserved stream and the behavior of it depends on
- // derived class's own implementation.
- virtual void HandleRstOnValidNonexistentStream(
- const QuicRstStreamFrame& frame);
-
- // Returns a stateless reset token which will be included in the public reset
- // packet.
- virtual StatelessResetToken GetStatelessResetToken() const;
-
- QuicControlFrameManager& control_frame_manager() {
- return control_frame_manager_;
- }
-
- const LegacyQuicStreamIdManager& stream_id_manager() const {
- return stream_id_manager_;
- }
-
- QuicDatagramQueue* datagram_queue() { return &datagram_queue_; }
-
- size_t num_static_streams() const { return num_static_streams_; }
-
- size_t num_zombie_streams() const { return num_zombie_streams_; }
-
- bool was_zero_rtt_rejected() const { return was_zero_rtt_rejected_; }
-
- size_t num_outgoing_draining_streams() const {
- return num_outgoing_draining_streams_;
- }
-
- size_t num_draining_streams() const { return num_draining_streams_; }
-
- // Processes the stream type information of |pending| depending on
- // different kinds of sessions' own rules. If the pending stream has been
- // converted to a normal stream, returns a pointer to the new stream;
- // otherwise, returns nullptr.
- virtual QuicStream* ProcessPendingStream(PendingStream* /*pending*/) {
- return nullptr;
- }
-
- // Called by applications to perform |action| on active streams.
- // Stream iteration will be stopped if action returns false.
- void PerformActionOnActiveStreams(std::function<bool(QuicStream*)> action);
- void PerformActionOnActiveStreams(
- std::function<bool(QuicStream*)> action) const;
-
- // Return the largest peer created stream id depending on directionality
- // indicated by |unidirectional|.
- QuicStreamId GetLargestPeerCreatedStreamId(bool unidirectional) const;
-
- // Deletes the connection and sets it to nullptr, so calling it mulitiple
- // times is safe.
- void DeleteConnection();
-
- // Call SetPriority() on stream id |id| and return true if stream is active.
- bool MaybeSetStreamPriority(QuicStreamId stream_id,
- const spdy::SpdyStreamPrecedence& precedence);
-
- void SetLossDetectionTuner(
- std::unique_ptr<LossDetectionTunerInterface> tuner) {
- connection()->SetLossDetectionTuner(std::move(tuner));
- }
-
- // Find stream with |id|, returns nullptr if the stream does not exist or
- // closed. static streams and zombie streams are not considered active
- // streams.
- QuicStream* GetActiveStream(QuicStreamId id) const;
-
- const UberQuicStreamIdManager& ietf_streamid_manager() const {
- QUICHE_DCHECK(VersionHasIetfQuicFrames(transport_version()));
- return ietf_streamid_manager_;
- }
-
- // Only called at a server session. Generate a CachedNetworkParameters that
- // can be sent to the client as part of the address token, based on the latest
- // bandwidth/rtt information. If return absl::nullopt, address token will not
- // contain the CachedNetworkParameters.
- virtual absl::optional<CachedNetworkParameters>
- GenerateCachedNetworkParameters() const {
- return absl::nullopt;
- }
-
- private:
- friend class test::QuicSessionPeer;
-
- // Called in OnConfigNegotiated when we receive a new stream level flow
- // control window in a negotiated config. Closes the connection if invalid.
- void OnNewStreamFlowControlWindow(QuicStreamOffset new_window);
-
- // Called in OnConfigNegotiated when we receive a new unidirectional stream
- // flow control window in a negotiated config.
- void OnNewStreamUnidirectionalFlowControlWindow(QuicStreamOffset new_window);
-
- // Called in OnConfigNegotiated when we receive a new outgoing bidirectional
- // stream flow control window in a negotiated config.
- void OnNewStreamOutgoingBidirectionalFlowControlWindow(
- QuicStreamOffset new_window);
-
- // Called in OnConfigNegotiated when we receive a new incoming bidirectional
- // stream flow control window in a negotiated config.
- void OnNewStreamIncomingBidirectionalFlowControlWindow(
- QuicStreamOffset new_window);
-
- // Called in OnConfigNegotiated when we receive a new connection level flow
- // control window in a negotiated config. Closes the connection if invalid.
- void OnNewSessionFlowControlWindow(QuicStreamOffset new_window);
-
- // Debug helper for |OnCanWrite()|, check that OnStreamWrite() makes
- // forward progress. Returns false if busy loop detected.
- bool CheckStreamNotBusyLooping(QuicStream* stream,
- uint64_t previous_bytes_written,
- bool previous_fin_sent);
-
- // Debug helper for OnCanWrite. Check that after QuicStream::OnCanWrite(),
- // if stream has buffered data and is not stream level flow control blocked,
- // it has to be in the write blocked list.
- bool CheckStreamWriteBlocked(QuicStream* stream) const;
-
- // Called in OnConfigNegotiated for Finch trials to measure performance of
- // starting with larger flow control receive windows.
- void AdjustInitialFlowControlWindows(size_t stream_window);
-
- // Find stream with |id|, returns nullptr if the stream does not exist or
- // closed.
- QuicStream* GetStream(QuicStreamId id) const;
-
- // Can return NULL, e.g., if the stream has been closed before.
- PendingStream* GetOrCreatePendingStream(QuicStreamId stream_id);
-
- // Let streams and control frame managers retransmit lost data, returns true
- // if all lost data is retransmitted. Returns false otherwise.
- bool RetransmitLostData();
-
- // Returns true if stream data should be written.
- bool CanWriteStreamData() const;
-
- // Closes the pending stream |stream_id| before it has been created.
- void ClosePendingStream(QuicStreamId stream_id);
-
- // Whether the frame with given type and id should be feed to a pending
- // stream.
- bool ShouldProcessFrameByPendingStream(QuicFrameType type,
- QuicStreamId id) const;
-
- // Process the pending stream if possible.
- void MaybeProcessPendingStream(PendingStream* pending);
-
- // Creates or gets pending stream, feeds it with |frame|, and returns the
- // pending stream. Can return NULL, e.g., if the stream ID is invalid.
- PendingStream* PendingStreamOnStreamFrame(const QuicStreamFrame& frame);
-
- // Creates or gets pending strea, feed it with |frame|, and closes the pending
- // stream.
- void PendingStreamOnRstStream(const QuicRstStreamFrame& frame);
-
- // Creates or gets pending stream, feeds it with |frame|, and records the
- // max_data in the pending stream.
- void PendingStreamOnWindowUpdateFrame(const QuicWindowUpdateFrame& frame);
-
- // Creates or gets pending stream, feeds it with |frame|, and records the
- // ietf_error_code in the pending stream.
- void PendingStreamOnStopSendingFrame(const QuicStopSendingFrame& frame);
-
- // Keep track of highest received byte offset of locally closed streams, while
- // waiting for a definitive final highest offset from the peer.
- absl::flat_hash_map<QuicStreamId, QuicStreamOffset>
- locally_closed_streams_highest_offset_;
-
- QuicConnection* connection_;
-
- // Store perspective on QuicSession during the constructor as it may be needed
- // during our destructor when connection_ may have already been destroyed.
- Perspective perspective_;
-
- // May be null.
- Visitor* visitor_;
-
- // A list of streams which need to write more data. Stream register
- // themselves in their constructor, and unregisterm themselves in their
- // destructors, so the write blocked list must outlive all streams.
- QuicWriteBlockedList write_blocked_streams_;
-
- ClosedStreams closed_streams_;
-
- QuicConfig config_;
-
- // Map from StreamId to pointers to streams. Owns the streams.
- StreamMap stream_map_;
-
- // Map from StreamId to PendingStreams for peer-created unidirectional streams
- // which are waiting for the first byte of payload to arrive.
- PendingStreamMap pending_stream_map_;
-
- // TODO(fayang): Consider moving LegacyQuicStreamIdManager into
- // UberQuicStreamIdManager.
- // Manages stream IDs for Google QUIC.
- LegacyQuicStreamIdManager stream_id_manager_;
-
- // Manages stream IDs for version99/IETF QUIC
- UberQuicStreamIdManager ietf_streamid_manager_;
-
- // A counter for streams which have sent and received FIN but waiting for
- // application to consume data.
- size_t num_draining_streams_;
-
- // A counter for self initiated streams which have sent and received FIN but
- // waiting for application to consume data.
- size_t num_outgoing_draining_streams_;
-
- // A counter for static streams which are in stream_map_.
- size_t num_static_streams_;
-
- // A counter for streams which have done reading and writing, but are waiting
- // for acks.
- size_t num_zombie_streams_;
-
- // Received information for a connection close.
- QuicConnectionCloseFrame on_closed_frame_;
-
- // Used for connection-level flow control.
- QuicFlowController flow_controller_;
-
- // The stream id which was last popped in OnCanWrite, or 0, if not under the
- // call stack of OnCanWrite.
- QuicStreamId currently_writing_stream_id_;
-
- // Whether a transport layer GOAWAY frame has been sent.
- // Such a frame only exists in Google QUIC, therefore |transport_goaway_sent_|
- // is always false when using IETF QUIC.
- bool transport_goaway_sent_;
-
- // Whether a transport layer GOAWAY frame has been received.
- // Such a frame only exists in Google QUIC, therefore
- // |transport_goaway_received_| is always false when using IETF QUIC.
- bool transport_goaway_received_;
-
- QuicControlFrameManager control_frame_manager_;
-
- // Id of latest successfully sent message.
- QuicMessageId last_message_id_;
-
- // The buffer used to queue the DATAGRAM frames.
- QuicDatagramQueue datagram_queue_;
-
- // TODO(fayang): switch to linked_hash_set when chromium supports it. The bool
- // is not used here.
- // List of streams with pending retransmissions.
- quiche::QuicheLinkedHashMap<QuicStreamId, bool>
- streams_with_pending_retransmission_;
-
- // Clean up closed_streams_ when this alarm fires.
- std::unique_ptr<QuicAlarm> closed_streams_clean_up_alarm_;
-
- // Supported version list used by the crypto handshake only. Please note, this
- // list may be a superset of the connection framer's supported versions.
- ParsedQuicVersionVector supported_versions_;
-
- // Only non-empty on the client after receiving a version negotiation packet,
- // contains the configured versions from the original session before version
- // negotiation was received.
- ParsedQuicVersionVector client_original_supported_versions_;
-
- absl::optional<std::string> user_agent_id_;
-
- // Initialized to false. Set to true when the session has been properly
- // configured and is ready for general operation.
- bool is_configured_;
-
- // Whether the session has received a 0-RTT rejection (QUIC+TLS only).
- bool was_zero_rtt_rejected_;
-
- // This indicates a liveness testing is in progress, and push back the
- // creation of new outgoing bidirectional streams.
- bool liveness_testing_in_progress_;
-
- const bool add_cached_network_parameters_to_address_token_ =
- GetQuicReloadableFlag(
- quic_add_cached_network_parameters_to_address_token2);
-
- // 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
-
-#endif // QUICHE_QUIC_CORE_QUIC_SESSION_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_session_test.cc b/chromium/net/third_party/quiche/src/quic/core/quic_session_test.cc
deleted file mode 100644
index 256865d9e7b..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_session_test.cc
+++ /dev/null
@@ -1,3144 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_session.h"
-
-#include <cstdint>
-#include <set>
-#include <string>
-#include <utility>
-
-#include "absl/base/macros.h"
-#include "absl/memory/memory.h"
-#include "absl/strings/str_cat.h"
-#include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
-#include "quic/core/crypto/crypto_protocol.h"
-#include "quic/core/crypto/null_decrypter.h"
-#include "quic/core/crypto/null_encrypter.h"
-#include "quic/core/crypto/transport_parameters.h"
-#include "quic/core/frames/quic_max_streams_frame.h"
-#include "quic/core/quic_crypto_stream.h"
-#include "quic/core/quic_data_writer.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_stream.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_utils.h"
-#include "quic/core/quic_versions.h"
-#include "quic/platform/api/quic_expect_bug.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_mem_slice_storage.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/mock_quic_session_visitor.h"
-#include "quic/test_tools/quic_config_peer.h"
-#include "quic/test_tools/quic_connection_peer.h"
-#include "quic/test_tools/quic_flow_controller_peer.h"
-#include "quic/test_tools/quic_session_peer.h"
-#include "quic/test_tools/quic_stream_id_manager_peer.h"
-#include "quic/test_tools/quic_stream_peer.h"
-#include "quic/test_tools/quic_stream_send_buffer_peer.h"
-#include "quic/test_tools/quic_test_utils.h"
-
-using spdy::kV3HighestPriority;
-using spdy::SpdyPriority;
-using ::testing::_;
-using ::testing::AnyNumber;
-using ::testing::AtLeast;
-using ::testing::InSequence;
-using ::testing::Invoke;
-using ::testing::NiceMock;
-using ::testing::Return;
-using ::testing::StrictMock;
-using ::testing::WithArg;
-
-namespace quic {
-namespace test {
-namespace {
-
-class TestCryptoStream : public QuicCryptoStream, public QuicCryptoHandshaker {
- public:
- explicit TestCryptoStream(QuicSession* session)
- : QuicCryptoStream(session),
- QuicCryptoHandshaker(this, session),
- encryption_established_(false),
- one_rtt_keys_available_(false),
- params_(new QuicCryptoNegotiatedParameters) {
- // Simulate a negotiated cipher_suite with a fake value.
- params_->cipher_suite = 1;
- }
-
- void EstablishZeroRttEncryption() {
- encryption_established_ = true;
- session()->connection()->SetEncrypter(
- ENCRYPTION_ZERO_RTT,
- std::make_unique<NullEncrypter>(session()->perspective()));
- }
-
- void OnHandshakeMessage(const CryptoHandshakeMessage& /*message*/) override {
- encryption_established_ = true;
- one_rtt_keys_available_ = true;
- QuicErrorCode error;
- std::string error_details;
- session()->config()->SetInitialStreamFlowControlWindowToSend(
- kInitialStreamFlowControlWindowForTest);
- session()->config()->SetInitialSessionFlowControlWindowToSend(
- kInitialSessionFlowControlWindowForTest);
- if (session()->version().UsesTls()) {
- if (session()->perspective() == Perspective::IS_CLIENT) {
- session()->config()->SetOriginalConnectionIdToSend(
- session()->connection()->connection_id());
- session()->config()->SetInitialSourceConnectionIdToSend(
- session()->connection()->connection_id());
- } else {
- session()->config()->SetInitialSourceConnectionIdToSend(
- session()->connection()->client_connection_id());
- }
- TransportParameters transport_parameters;
- EXPECT_TRUE(
- session()->config()->FillTransportParameters(&transport_parameters));
- error = session()->config()->ProcessTransportParameters(
- transport_parameters, /* is_resumption = */ false, &error_details);
- } else {
- CryptoHandshakeMessage msg;
- session()->config()->ToHandshakeMessage(&msg, transport_version());
- error =
- session()->config()->ProcessPeerHello(msg, CLIENT, &error_details);
- }
- EXPECT_THAT(error, IsQuicNoError());
- session()->OnNewEncryptionKeyAvailable(
- ENCRYPTION_FORWARD_SECURE,
- std::make_unique<NullEncrypter>(session()->perspective()));
- session()->OnConfigNegotiated();
- if (session()->connection()->version().handshake_protocol ==
- PROTOCOL_TLS1_3) {
- session()->OnTlsHandshakeComplete();
- } else {
- session()->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
- }
- session()->DiscardOldEncryptionKey(ENCRYPTION_INITIAL);
- }
-
- // QuicCryptoStream implementation
- ssl_early_data_reason_t EarlyDataReason() const override {
- return ssl_early_data_unknown;
- }
- bool encryption_established() const override {
- return encryption_established_;
- }
- bool one_rtt_keys_available() const override {
- return one_rtt_keys_available_;
- }
- const QuicCryptoNegotiatedParameters& crypto_negotiated_params()
- const override {
- return *params_;
- }
- CryptoMessageParser* crypto_message_parser() override {
- return QuicCryptoHandshaker::crypto_message_parser();
- }
- void OnPacketDecrypted(EncryptionLevel /*level*/) override {}
- void OnOneRttPacketAcknowledged() override {}
- void OnHandshakePacketSent() override {}
- void OnHandshakeDoneReceived() override {}
- void OnNewTokenReceived(absl::string_view /*token*/) override {}
- std::string GetAddressToken(
- const CachedNetworkParameters* /*cached_network_parameters*/)
- const override {
- return "";
- }
- bool ValidateAddressToken(absl::string_view /*token*/) const override {
- return true;
- }
- const CachedNetworkParameters* PreviousCachedNetworkParams() const override {
- return nullptr;
- }
- void SetPreviousCachedNetworkParams(
- CachedNetworkParameters /*cached_network_params*/) override {}
- HandshakeState GetHandshakeState() const override {
- return one_rtt_keys_available() ? HANDSHAKE_COMPLETE : HANDSHAKE_START;
- }
- void SetServerApplicationStateForResumption(
- std::unique_ptr<ApplicationState> /*application_state*/) override {}
- MOCK_METHOD(std::unique_ptr<QuicDecrypter>,
- AdvanceKeysAndCreateCurrentOneRttDecrypter,
- (),
- (override));
- MOCK_METHOD(std::unique_ptr<QuicEncrypter>,
- CreateCurrentOneRttEncrypter,
- (),
- (override));
-
- MOCK_METHOD(void, OnCanWrite, (), (override));
- bool HasPendingCryptoRetransmission() const override { return false; }
-
- MOCK_METHOD(bool, HasPendingRetransmission, (), (const, override));
-
- void OnConnectionClosed(QuicErrorCode /*error*/,
- ConnectionCloseSource /*source*/) override {}
-
- bool ExportKeyingMaterial(absl::string_view /*label*/,
- absl::string_view /*context*/,
- size_t /*result_len*/,
- std::string* /*result*/) override {
- return false;
- }
-
- SSL* GetSsl() const override { return nullptr; }
-
- private:
- using QuicCryptoStream::session;
-
- bool encryption_established_;
- bool one_rtt_keys_available_;
- QuicReferenceCountedPointer<QuicCryptoNegotiatedParameters> params_;
-};
-
-class TestStream : public QuicStream {
- public:
- TestStream(QuicStreamId id, QuicSession* session, StreamType type)
- : TestStream(id, session, /*is_static=*/false, type) {}
-
- TestStream(QuicStreamId id,
- QuicSession* session,
- bool is_static,
- StreamType type)
- : QuicStream(id, session, is_static, type) {}
-
- TestStream(PendingStream* pending, QuicSession* session)
- : QuicStream(pending, session, /*is_static=*/false) {}
-
- using QuicStream::CloseWriteSide;
- using QuicStream::WriteMemSlices;
-
- void OnDataAvailable() override {}
-
- MOCK_METHOD(void, OnCanWrite, (), (override));
- MOCK_METHOD(bool,
- RetransmitStreamData,
- (QuicStreamOffset, QuicByteCount, bool, TransmissionType),
- (override));
-
- MOCK_METHOD(bool, HasPendingRetransmission, (), (const, override));
-};
-
-class TestSession : public QuicSession {
- public:
- explicit TestSession(QuicConnection* connection,
- MockQuicSessionVisitor* session_visitor)
- : QuicSession(connection,
- session_visitor,
- DefaultQuicConfig(),
- CurrentSupportedVersions(),
- /*num_expected_unidirectional_static_streams = */ 0),
- crypto_stream_(this),
- writev_consumes_all_data_(false),
- uses_pending_streams_(false),
- num_incoming_streams_created_(0) {
- Initialize();
- this->connection()->SetEncrypter(
- ENCRYPTION_FORWARD_SECURE,
- std::make_unique<NullEncrypter>(connection->perspective()));
- if (this->connection()->version().SupportsAntiAmplificationLimit()) {
- QuicConnectionPeer::SetAddressValidated(this->connection());
- }
- }
-
- ~TestSession() override { DeleteConnection(); }
-
- TestCryptoStream* GetMutableCryptoStream() override {
- return &crypto_stream_;
- }
-
- const TestCryptoStream* GetCryptoStream() const override {
- return &crypto_stream_;
- }
-
- TestStream* CreateOutgoingBidirectionalStream() {
- QuicStreamId id = GetNextOutgoingBidirectionalStreamId();
- if (id ==
- QuicUtils::GetInvalidStreamId(connection()->transport_version())) {
- return nullptr;
- }
- TestStream* stream = new TestStream(id, this, BIDIRECTIONAL);
- ActivateStream(absl::WrapUnique(stream));
- return stream;
- }
-
- TestStream* CreateOutgoingUnidirectionalStream() {
- TestStream* stream = new TestStream(GetNextOutgoingUnidirectionalStreamId(),
- this, WRITE_UNIDIRECTIONAL);
- ActivateStream(absl::WrapUnique(stream));
- return stream;
- }
-
- TestStream* CreateIncomingStream(QuicStreamId id) override {
- // Enforce the limit on the number of open streams.
- if (!VersionHasIetfQuicFrames(connection()->transport_version()) &&
- stream_id_manager().num_open_incoming_streams() + 1 >
- max_open_incoming_bidirectional_streams()) {
- // No need to do this test for version 99; it's done by
- // QuicSession::GetOrCreateStream.
- connection()->CloseConnection(
- QUIC_TOO_MANY_OPEN_STREAMS, "Too many streams!",
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
- return nullptr;
- }
-
- TestStream* stream = new TestStream(
- id, this,
- DetermineStreamType(id, connection()->version(), perspective(),
- /*is_incoming=*/true, BIDIRECTIONAL));
- ActivateStream(absl::WrapUnique(stream));
- ++num_incoming_streams_created_;
- return stream;
- }
-
- TestStream* CreateIncomingStream(PendingStream* pending) override {
- TestStream* stream = new TestStream(pending, this);
- ActivateStream(absl::WrapUnique(stream));
- ++num_incoming_streams_created_;
- return stream;
- }
-
- // QuicSession doesn't do anything in this method. So it's overridden here to
- // test that the session handles pending streams correctly in terms of
- // receiving stream frames.
- QuicStream* ProcessPendingStream(PendingStream* pending) override {
- if (pending->is_bidirectional()) {
- return CreateIncomingStream(pending);
- }
- struct iovec iov;
- if (pending->sequencer()->GetReadableRegion(&iov)) {
- // Create TestStream once the first byte is received.
- return CreateIncomingStream(pending);
- }
- return nullptr;
- }
-
- bool IsClosedStream(QuicStreamId id) {
- return QuicSession::IsClosedStream(id);
- }
-
- QuicStream* GetOrCreateStream(QuicStreamId stream_id) {
- return QuicSession::GetOrCreateStream(stream_id);
- }
-
- bool ShouldKeepConnectionAlive() const override {
- return GetNumActiveStreams() > 0;
- }
-
- QuicConsumedData WritevData(QuicStreamId id, size_t write_length,
- QuicStreamOffset offset, StreamSendingState state,
- TransmissionType type,
- EncryptionLevel level) override {
- bool fin = state != NO_FIN;
- QuicConsumedData consumed(write_length, fin);
- if (!writev_consumes_all_data_) {
- consumed =
- QuicSession::WritevData(id, write_length, offset, state, type, level);
- }
- QuicSessionPeer::GetWriteBlockedStreams(this)->UpdateBytesForStream(
- id, consumed.bytes_consumed);
- return consumed;
- }
-
- MOCK_METHOD(void,
- OnCanCreateNewOutgoingStream,
- (bool unidirectional),
- (override));
-
- void set_writev_consumes_all_data(bool val) {
- writev_consumes_all_data_ = val;
- }
-
- QuicConsumedData SendStreamData(QuicStream* stream) {
- struct iovec iov;
- if (!QuicUtils::IsCryptoStreamId(connection()->transport_version(),
- stream->id()) &&
- this->connection()->encryption_level() != ENCRYPTION_FORWARD_SECURE) {
- this->connection()->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
- }
- MakeIOVector("not empty", &iov);
- QuicStreamPeer::SendBuffer(stream).SaveStreamData(&iov, 1, 0, 9);
- QuicConsumedData consumed =
- WritevData(stream->id(), 9, 0, FIN, NOT_RETRANSMISSION,
- GetEncryptionLevelToSendApplicationData());
- QuicStreamPeer::SendBuffer(stream).OnStreamDataConsumed(
- consumed.bytes_consumed);
- return consumed;
- }
-
- const QuicFrame& save_frame() { return save_frame_; }
-
- bool SaveFrame(const QuicFrame& frame) {
- save_frame_ = frame;
- DeleteFrame(&const_cast<QuicFrame&>(frame));
- return true;
- }
-
- QuicConsumedData SendLargeFakeData(QuicStream* stream, int bytes) {
- QUICHE_DCHECK(writev_consumes_all_data_);
- return WritevData(stream->id(), bytes, 0, FIN, NOT_RETRANSMISSION,
- GetEncryptionLevelToSendApplicationData());
- }
-
- bool UsesPendingStreamForFrame(QuicFrameType type,
- QuicStreamId stream_id) const override {
- if (!uses_pending_streams_) {
- return false;
- }
- // Uses pending stream for STREAM/RST_STREAM frames with unidirectional read
- // stream and uses pending stream for
- // STREAM/RST_STREAM/STOP_SENDING/WINDOW_UPDATE frames with bidirectional
- // stream.
- bool is_incoming_stream = IsIncomingStream(stream_id);
- StreamType stream_type = QuicUtils::GetStreamType(
- stream_id, perspective(), is_incoming_stream, version());
- switch (type) {
- case STREAM_FRAME:
- ABSL_FALLTHROUGH_INTENDED;
- case RST_STREAM_FRAME:
- return is_incoming_stream;
- case STOP_SENDING_FRAME:
- ABSL_FALLTHROUGH_INTENDED;
- case WINDOW_UPDATE_FRAME:
- return stream_type == BIDIRECTIONAL;
- default:
- return false;
- }
- }
-
- bool ShouldProcessPendingStreamImmediately() const override {
- return process_pending_stream_immediately_;
- }
-
- void set_uses_pending_streams(bool uses_pending_streams) {
- uses_pending_streams_ = uses_pending_streams;
- }
-
- void set_process_pending_stream_immediately(
- bool process_pending_stream_immediately) {
- process_pending_stream_immediately_ = process_pending_stream_immediately;
- }
-
- int num_incoming_streams_created() const {
- return num_incoming_streams_created_;
- }
-
- using QuicSession::ActivateStream;
- using QuicSession::CanOpenNextOutgoingBidirectionalStream;
- using QuicSession::CanOpenNextOutgoingUnidirectionalStream;
- using QuicSession::closed_streams;
- using QuicSession::GetNextOutgoingBidirectionalStreamId;
- using QuicSession::GetNextOutgoingUnidirectionalStreamId;
-
- private:
- StrictMock<TestCryptoStream> crypto_stream_;
-
- bool writev_consumes_all_data_;
- bool uses_pending_streams_;
- bool process_pending_stream_immediately_ = true;
- QuicFrame save_frame_;
- int num_incoming_streams_created_;
-};
-
-class QuicSessionTestBase : public QuicTestWithParam<ParsedQuicVersion> {
- protected:
- QuicSessionTestBase(Perspective perspective, bool configure_session)
- : connection_(
- new StrictMock<MockQuicConnection>(&helper_,
- &alarm_factory_,
- perspective,
- SupportedVersions(GetParam()))),
- session_(connection_, &session_visitor_),
- configure_session_(configure_session) {
- session_.config()->SetInitialStreamFlowControlWindowToSend(
- kInitialStreamFlowControlWindowForTest);
- session_.config()->SetInitialSessionFlowControlWindowToSend(
- kInitialSessionFlowControlWindowForTest);
-
- if (configure_session) {
- if (VersionHasIetfQuicFrames(transport_version())) {
- EXPECT_CALL(session_, OnCanCreateNewOutgoingStream(false)).Times(1);
- EXPECT_CALL(session_, OnCanCreateNewOutgoingStream(true)).Times(1);
- }
- QuicConfigPeer::SetReceivedMaxBidirectionalStreams(
- session_.config(), kDefaultMaxStreamsPerConnection);
- QuicConfigPeer::SetReceivedMaxUnidirectionalStreams(
- session_.config(), kDefaultMaxStreamsPerConnection);
- QuicConfigPeer::SetReceivedInitialMaxStreamDataBytesUnidirectional(
- session_.config(), kMinimumFlowControlSendWindow);
- QuicConfigPeer::SetReceivedInitialMaxStreamDataBytesIncomingBidirectional(
- session_.config(), kMinimumFlowControlSendWindow);
- QuicConfigPeer::SetReceivedInitialMaxStreamDataBytesOutgoingBidirectional(
- session_.config(), kMinimumFlowControlSendWindow);
- QuicConfigPeer::SetReceivedInitialSessionFlowControlWindow(
- session_.config(), kMinimumFlowControlSendWindow);
- connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
- session_.OnConfigNegotiated();
- }
- TestCryptoStream* crypto_stream = session_.GetMutableCryptoStream();
- EXPECT_CALL(*crypto_stream, HasPendingRetransmission())
- .Times(testing::AnyNumber());
- testing::Mock::VerifyAndClearExpectations(&session_);
- }
-
- ~QuicSessionTestBase() {
- if (configure_session_) {
- EXPECT_TRUE(session_.is_configured());
- }
- }
-
- void CheckClosedStreams() {
- QuicStreamId first_stream_id = QuicUtils::GetFirstBidirectionalStreamId(
- connection_->transport_version(), Perspective::IS_CLIENT);
- if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
- first_stream_id =
- QuicUtils::GetCryptoStreamId(connection_->transport_version());
- }
- for (QuicStreamId i = first_stream_id; i < 100; i++) {
- if (closed_streams_.find(i) == closed_streams_.end()) {
- EXPECT_FALSE(session_.IsClosedStream(i)) << " stream id: " << i;
- } else {
- EXPECT_TRUE(session_.IsClosedStream(i)) << " stream id: " << i;
- }
- }
- }
-
- void CloseStream(QuicStreamId id) {
- if (VersionHasIetfQuicFrames(transport_version())) {
- if (QuicUtils::GetStreamType(
- id, session_.perspective(), session_.IsIncomingStream(id),
- connection_->version()) == READ_UNIDIRECTIONAL) {
- // Verify STOP_SENDING but no RESET_STREAM is sent for
- // READ_UNIDIRECTIONAL streams.
- EXPECT_CALL(*connection_, SendControlFrame(_))
- .Times(1)
- .WillOnce(Invoke(&ClearControlFrame));
- EXPECT_CALL(*connection_, OnStreamReset(id, _)).Times(1);
- } else if (QuicUtils::GetStreamType(
- id, session_.perspective(), session_.IsIncomingStream(id),
- connection_->version()) == WRITE_UNIDIRECTIONAL) {
- // Verify RESET_STREAM but not STOP_SENDING is sent for write-only
- // stream.
- EXPECT_CALL(*connection_, SendControlFrame(_))
- .Times(1)
- .WillOnce(Invoke(&ClearControlFrame));
- EXPECT_CALL(*connection_, OnStreamReset(id, _));
- } else {
- // Verify RESET_STREAM and STOP_SENDING are sent for BIDIRECTIONAL
- // streams.
- EXPECT_CALL(*connection_, SendControlFrame(_))
- .Times(2)
- .WillRepeatedly(Invoke(&ClearControlFrame));
- EXPECT_CALL(*connection_, OnStreamReset(id, _));
- }
- } else {
- EXPECT_CALL(*connection_, SendControlFrame(_))
- .WillOnce(Invoke(&ClearControlFrame));
- EXPECT_CALL(*connection_, OnStreamReset(id, _));
- }
- session_.ResetStream(id, QUIC_STREAM_CANCELLED);
- closed_streams_.insert(id);
- }
-
- void CompleteHandshake() {
- CryptoHandshakeMessage msg;
- if (connection_->version().UsesTls() &&
- connection_->perspective() == Perspective::IS_SERVER) {
- // HANDSHAKE_DONE frame.
- EXPECT_CALL(*connection_, SendControlFrame(_))
- .WillOnce(Invoke(&ClearControlFrame));
- }
- session_.GetMutableCryptoStream()->OnHandshakeMessage(msg);
- }
-
- QuicTransportVersion transport_version() const {
- return connection_->transport_version();
- }
-
- QuicStreamId GetNthClientInitiatedBidirectionalId(int n) {
- return QuicUtils::GetFirstBidirectionalStreamId(
- connection_->transport_version(), Perspective::IS_CLIENT) +
- QuicUtils::StreamIdDelta(connection_->transport_version()) * n;
- }
-
- QuicStreamId GetNthClientInitiatedUnidirectionalId(int n) {
- return QuicUtils::GetFirstUnidirectionalStreamId(
- connection_->transport_version(), Perspective::IS_CLIENT) +
- QuicUtils::StreamIdDelta(connection_->transport_version()) * n;
- }
-
- QuicStreamId GetNthServerInitiatedBidirectionalId(int n) {
- return QuicUtils::GetFirstBidirectionalStreamId(
- connection_->transport_version(), Perspective::IS_SERVER) +
- QuicUtils::StreamIdDelta(connection_->transport_version()) * n;
- }
-
- QuicStreamId GetNthServerInitiatedUnidirectionalId(int n) {
- return QuicUtils::GetFirstUnidirectionalStreamId(
- connection_->transport_version(), Perspective::IS_SERVER) +
- QuicUtils::StreamIdDelta(connection_->transport_version()) * n;
- }
-
- QuicStreamId StreamCountToId(QuicStreamCount stream_count,
- Perspective perspective,
- bool bidirectional) {
- // Calculate and build up stream ID rather than use
- // GetFirst... because tests that rely on this method
- // needs to do the stream count where #1 is 0/1/2/3, and not
- // take into account that stream 0 is special.
- QuicStreamId id =
- ((stream_count - 1) * QuicUtils::StreamIdDelta(transport_version()));
- if (!bidirectional) {
- id |= 0x2;
- }
- if (perspective == Perspective::IS_SERVER) {
- id |= 0x1;
- }
- return id;
- }
-
- MockQuicConnectionHelper helper_;
- MockAlarmFactory alarm_factory_;
- NiceMock<MockQuicSessionVisitor> session_visitor_;
- StrictMock<MockQuicConnection>* connection_;
- TestSession session_;
- std::set<QuicStreamId> closed_streams_;
- bool configure_session_;
-};
-
-class QuicSessionTestServer : public QuicSessionTestBase {
- public:
- // CheckMultiPathResponse validates that a written packet
- // contains both expected path responses.
- WriteResult CheckMultiPathResponse(const char* buffer,
- size_t buf_len,
- const QuicIpAddress& /*self_address*/,
- const QuicSocketAddress& /*peer_address*/,
- PerPacketOptions* /*options*/) {
- QuicEncryptedPacket packet(buffer, buf_len);
- {
- InSequence s;
- EXPECT_CALL(framer_visitor_, OnPacket());
- EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_));
- EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_));
- EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_, _));
- EXPECT_CALL(framer_visitor_, OnPacketHeader(_));
- EXPECT_CALL(framer_visitor_, OnPathResponseFrame(_))
- .WillOnce(
- WithArg<0>(Invoke([this](const QuicPathResponseFrame& frame) {
- EXPECT_EQ(path_frame_buffer1_, frame.data_buffer);
- return true;
- })));
- EXPECT_CALL(framer_visitor_, OnPathResponseFrame(_))
- .WillOnce(
- WithArg<0>(Invoke([this](const QuicPathResponseFrame& frame) {
- EXPECT_EQ(path_frame_buffer2_, frame.data_buffer);
- return true;
- })));
- EXPECT_CALL(framer_visitor_, OnPacketComplete());
- }
- client_framer_.ProcessPacket(packet);
- return WriteResult(WRITE_STATUS_OK, 0);
- }
-
- protected:
- QuicSessionTestServer()
- : QuicSessionTestBase(Perspective::IS_SERVER, /*configure_session=*/true),
- path_frame_buffer1_({0, 1, 2, 3, 4, 5, 6, 7}),
- path_frame_buffer2_({8, 9, 10, 11, 12, 13, 14, 15}),
- client_framer_(SupportedVersions(GetParam()),
- QuicTime::Zero(),
- Perspective::IS_CLIENT,
- kQuicDefaultConnectionIdLength) {
- client_framer_.set_visitor(&framer_visitor_);
- client_framer_.SetInitialObfuscators(TestConnectionId());
- if (client_framer_.version().KnowsWhichDecrypterToUse()) {
- client_framer_.InstallDecrypter(
- ENCRYPTION_FORWARD_SECURE,
- std::make_unique<NullDecrypter>(Perspective::IS_CLIENT));
- }
- }
-
- QuicPathFrameBuffer path_frame_buffer1_;
- QuicPathFrameBuffer path_frame_buffer2_;
- StrictMock<MockFramerVisitor> framer_visitor_;
- // Framer used to process packets sent by server.
- QuicFramer client_framer_;
-};
-
-INSTANTIATE_TEST_SUITE_P(Tests,
- QuicSessionTestServer,
- ::testing::ValuesIn(AllSupportedVersions()),
- ::testing::PrintToStringParamName());
-
-TEST_P(QuicSessionTestServer, PeerAddress) {
- EXPECT_EQ(QuicSocketAddress(QuicIpAddress::Loopback4(), kTestPort),
- session_.peer_address());
-}
-
-TEST_P(QuicSessionTestServer, SelfAddress) {
- EXPECT_TRUE(session_.self_address().IsInitialized());
-}
-
-TEST_P(QuicSessionTestServer, DontCallOnWriteBlockedForDisconnectedConnection) {
- EXPECT_CALL(*connection_, CloseConnection(_, _, _))
- .WillOnce(
- Invoke(connection_, &MockQuicConnection::ReallyCloseConnection));
- connection_->CloseConnection(QUIC_NO_ERROR, "Everything is fine.",
- ConnectionCloseBehavior::SILENT_CLOSE);
- ASSERT_FALSE(connection_->connected());
-
- EXPECT_CALL(session_visitor_, OnWriteBlocked(_)).Times(0);
- session_.OnWriteBlocked();
-}
-
-TEST_P(QuicSessionTestServer, OneRttKeysAvailable) {
- EXPECT_FALSE(session_.OneRttKeysAvailable());
- CompleteHandshake();
- EXPECT_TRUE(session_.OneRttKeysAvailable());
-}
-
-TEST_P(QuicSessionTestServer, IsClosedStreamDefault) {
- // Ensure that no streams are initially closed.
- QuicStreamId first_stream_id = QuicUtils::GetFirstBidirectionalStreamId(
- connection_->transport_version(), Perspective::IS_CLIENT);
- if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
- first_stream_id =
- QuicUtils::GetCryptoStreamId(connection_->transport_version());
- }
- for (QuicStreamId i = first_stream_id; i < 100; i++) {
- EXPECT_FALSE(session_.IsClosedStream(i)) << "stream id: " << i;
- }
-}
-
-TEST_P(QuicSessionTestServer, AvailableBidirectionalStreams) {
- ASSERT_TRUE(session_.GetOrCreateStream(
- GetNthClientInitiatedBidirectionalId(3)) != nullptr);
- // Smaller bidirectional streams should be available.
- EXPECT_TRUE(QuicSessionPeer::IsStreamAvailable(
- &session_, GetNthClientInitiatedBidirectionalId(1)));
- EXPECT_TRUE(QuicSessionPeer::IsStreamAvailable(
- &session_, GetNthClientInitiatedBidirectionalId(2)));
- ASSERT_TRUE(session_.GetOrCreateStream(
- GetNthClientInitiatedBidirectionalId(2)) != nullptr);
- ASSERT_TRUE(session_.GetOrCreateStream(
- GetNthClientInitiatedBidirectionalId(1)) != nullptr);
-}
-
-TEST_P(QuicSessionTestServer, AvailableUnidirectionalStreams) {
- ASSERT_TRUE(session_.GetOrCreateStream(
- GetNthClientInitiatedUnidirectionalId(3)) != nullptr);
- // Smaller unidirectional streams should be available.
- EXPECT_TRUE(QuicSessionPeer::IsStreamAvailable(
- &session_, GetNthClientInitiatedUnidirectionalId(1)));
- EXPECT_TRUE(QuicSessionPeer::IsStreamAvailable(
- &session_, GetNthClientInitiatedUnidirectionalId(2)));
- ASSERT_TRUE(session_.GetOrCreateStream(
- GetNthClientInitiatedUnidirectionalId(2)) != nullptr);
- ASSERT_TRUE(session_.GetOrCreateStream(
- GetNthClientInitiatedUnidirectionalId(1)) != nullptr);
-}
-
-TEST_P(QuicSessionTestServer, MaxAvailableBidirectionalStreams) {
- if (VersionHasIetfQuicFrames(transport_version())) {
- EXPECT_EQ(session_.max_open_incoming_bidirectional_streams(),
- session_.MaxAvailableBidirectionalStreams());
- } else {
- // The protocol specification requires that there can be at least 10 times
- // as many available streams as the connection's maximum open streams.
- EXPECT_EQ(session_.max_open_incoming_bidirectional_streams() *
- kMaxAvailableStreamsMultiplier,
- session_.MaxAvailableBidirectionalStreams());
- }
-}
-
-TEST_P(QuicSessionTestServer, MaxAvailableUnidirectionalStreams) {
- if (VersionHasIetfQuicFrames(transport_version())) {
- EXPECT_EQ(session_.max_open_incoming_unidirectional_streams(),
- session_.MaxAvailableUnidirectionalStreams());
- } else {
- // The protocol specification requires that there can be at least 10 times
- // as many available streams as the connection's maximum open streams.
- EXPECT_EQ(session_.max_open_incoming_unidirectional_streams() *
- kMaxAvailableStreamsMultiplier,
- session_.MaxAvailableUnidirectionalStreams());
- }
-}
-
-TEST_P(QuicSessionTestServer, IsClosedBidirectionalStreamLocallyCreated) {
- CompleteHandshake();
- TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
- EXPECT_EQ(GetNthServerInitiatedBidirectionalId(0), stream2->id());
- TestStream* stream4 = session_.CreateOutgoingBidirectionalStream();
- EXPECT_EQ(GetNthServerInitiatedBidirectionalId(1), stream4->id());
-
- CheckClosedStreams();
- CloseStream(GetNthServerInitiatedBidirectionalId(0));
- CheckClosedStreams();
- CloseStream(GetNthServerInitiatedBidirectionalId(1));
- CheckClosedStreams();
-}
-
-TEST_P(QuicSessionTestServer, IsClosedUnidirectionalStreamLocallyCreated) {
- CompleteHandshake();
- TestStream* stream2 = session_.CreateOutgoingUnidirectionalStream();
- EXPECT_EQ(GetNthServerInitiatedUnidirectionalId(0), stream2->id());
- TestStream* stream4 = session_.CreateOutgoingUnidirectionalStream();
- EXPECT_EQ(GetNthServerInitiatedUnidirectionalId(1), stream4->id());
-
- CheckClosedStreams();
- CloseStream(GetNthServerInitiatedUnidirectionalId(0));
- CheckClosedStreams();
- CloseStream(GetNthServerInitiatedUnidirectionalId(1));
- CheckClosedStreams();
-}
-
-TEST_P(QuicSessionTestServer, IsClosedBidirectionalStreamPeerCreated) {
- CompleteHandshake();
- QuicStreamId stream_id1 = GetNthClientInitiatedBidirectionalId(0);
- QuicStreamId stream_id2 = GetNthClientInitiatedBidirectionalId(1);
- session_.GetOrCreateStream(stream_id1);
- session_.GetOrCreateStream(stream_id2);
-
- CheckClosedStreams();
- CloseStream(stream_id1);
- CheckClosedStreams();
- CloseStream(stream_id2);
- // Create a stream, and make another available.
- QuicStream* stream3 = session_.GetOrCreateStream(
- stream_id2 +
- 2 * QuicUtils::StreamIdDelta(connection_->transport_version()));
- CheckClosedStreams();
- // Close one, but make sure the other is still not closed
- CloseStream(stream3->id());
- CheckClosedStreams();
-}
-
-TEST_P(QuicSessionTestServer, IsClosedUnidirectionalStreamPeerCreated) {
- CompleteHandshake();
- QuicStreamId stream_id1 = GetNthClientInitiatedUnidirectionalId(0);
- QuicStreamId stream_id2 = GetNthClientInitiatedUnidirectionalId(1);
- session_.GetOrCreateStream(stream_id1);
- session_.GetOrCreateStream(stream_id2);
-
- CheckClosedStreams();
- CloseStream(stream_id1);
- CheckClosedStreams();
- CloseStream(stream_id2);
- // Create a stream, and make another available.
- QuicStream* stream3 = session_.GetOrCreateStream(
- stream_id2 +
- 2 * QuicUtils::StreamIdDelta(connection_->transport_version()));
- CheckClosedStreams();
- // Close one, but make sure the other is still not closed
- CloseStream(stream3->id());
- CheckClosedStreams();
-}
-
-TEST_P(QuicSessionTestServer, MaximumAvailableOpenedBidirectionalStreams) {
- QuicStreamId stream_id = GetNthClientInitiatedBidirectionalId(0);
- session_.GetOrCreateStream(stream_id);
- EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
- EXPECT_NE(nullptr,
- session_.GetOrCreateStream(GetNthClientInitiatedBidirectionalId(
- session_.max_open_incoming_bidirectional_streams() - 1)));
-}
-
-TEST_P(QuicSessionTestServer, MaximumAvailableOpenedUnidirectionalStreams) {
- QuicStreamId stream_id = GetNthClientInitiatedUnidirectionalId(0);
- session_.GetOrCreateStream(stream_id);
- EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
- EXPECT_NE(nullptr,
- session_.GetOrCreateStream(GetNthClientInitiatedUnidirectionalId(
- session_.max_open_incoming_unidirectional_streams() - 1)));
-}
-
-TEST_P(QuicSessionTestServer, TooManyAvailableBidirectionalStreams) {
- QuicStreamId stream_id1 = GetNthClientInitiatedBidirectionalId(0);
- QuicStreamId stream_id2;
- EXPECT_NE(nullptr, session_.GetOrCreateStream(stream_id1));
- // A stream ID which is too large to create.
- stream_id2 = GetNthClientInitiatedBidirectionalId(
- session_.MaxAvailableBidirectionalStreams() + 2);
- if (VersionHasIetfQuicFrames(transport_version())) {
- // IETF QUIC terminates the connection with invalid stream id
- EXPECT_CALL(*connection_, CloseConnection(QUIC_INVALID_STREAM_ID, _, _));
- } else {
- // other versions terminate the connection with
- // QUIC_TOO_MANY_AVAILABLE_STREAMS.
- EXPECT_CALL(*connection_,
- CloseConnection(QUIC_TOO_MANY_AVAILABLE_STREAMS, _, _));
- }
- EXPECT_EQ(nullptr, session_.GetOrCreateStream(stream_id2));
-}
-
-TEST_P(QuicSessionTestServer, TooManyAvailableUnidirectionalStreams) {
- QuicStreamId stream_id1 = GetNthClientInitiatedUnidirectionalId(0);
- QuicStreamId stream_id2;
- EXPECT_NE(nullptr, session_.GetOrCreateStream(stream_id1));
- // A stream ID which is too large to create.
- stream_id2 = GetNthClientInitiatedUnidirectionalId(
- session_.MaxAvailableUnidirectionalStreams() + 2);
- if (VersionHasIetfQuicFrames(transport_version())) {
- // IETF QUIC terminates the connection with invalid stream id
- EXPECT_CALL(*connection_, CloseConnection(QUIC_INVALID_STREAM_ID, _, _));
- } else {
- // other versions terminate the connection with
- // QUIC_TOO_MANY_AVAILABLE_STREAMS.
- EXPECT_CALL(*connection_,
- CloseConnection(QUIC_TOO_MANY_AVAILABLE_STREAMS, _, _));
- }
- EXPECT_EQ(nullptr, session_.GetOrCreateStream(stream_id2));
-}
-
-TEST_P(QuicSessionTestServer, ManyAvailableBidirectionalStreams) {
- // When max_open_streams_ is 200, should be able to create 200 streams
- // out-of-order, that is, creating the one with the largest stream ID first.
- if (VersionHasIetfQuicFrames(transport_version())) {
- QuicSessionPeer::SetMaxOpenIncomingBidirectionalStreams(&session_, 200);
- // Smaller limit on unidirectional streams to help detect crossed wires.
- QuicSessionPeer::SetMaxOpenIncomingUnidirectionalStreams(&session_, 50);
- } else {
- QuicSessionPeer::SetMaxOpenIncomingStreams(&session_, 200);
- }
- // Create a stream at the start of the range.
- QuicStreamId stream_id = GetNthClientInitiatedBidirectionalId(0);
- EXPECT_NE(nullptr, session_.GetOrCreateStream(stream_id));
-
- // Create the largest stream ID of a threatened total of 200 streams.
- // GetNth... starts at 0, so for 200 streams, get the 199th.
- EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
- EXPECT_NE(nullptr, session_.GetOrCreateStream(
- GetNthClientInitiatedBidirectionalId(199)));
-
- if (VersionHasIetfQuicFrames(transport_version())) {
- // If IETF QUIC, check to make sure that creating bidirectional
- // streams does not mess up the unidirectional streams.
- stream_id = GetNthClientInitiatedUnidirectionalId(0);
- EXPECT_NE(nullptr, session_.GetOrCreateStream(stream_id));
- // Now try to get the last possible unidirectional stream.
- EXPECT_NE(nullptr, session_.GetOrCreateStream(
- GetNthClientInitiatedUnidirectionalId(49)));
- // and this should fail because it exceeds the unidirectional limit
- // (but not the bi-)
- EXPECT_CALL(
- *connection_,
- CloseConnection(QUIC_INVALID_STREAM_ID,
- "Stream id 798 would exceed stream count limit 50",
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET))
- .Times(1);
- EXPECT_EQ(nullptr, session_.GetOrCreateStream(
- GetNthClientInitiatedUnidirectionalId(199)));
- }
-}
-
-TEST_P(QuicSessionTestServer, ManyAvailableUnidirectionalStreams) {
- // When max_open_streams_ is 200, should be able to create 200 streams
- // out-of-order, that is, creating the one with the largest stream ID first.
- if (VersionHasIetfQuicFrames(transport_version())) {
- QuicSessionPeer::SetMaxOpenIncomingUnidirectionalStreams(&session_, 200);
- // Smaller limit on unidirectional streams to help detect crossed wires.
- QuicSessionPeer::SetMaxOpenIncomingBidirectionalStreams(&session_, 50);
- } else {
- QuicSessionPeer::SetMaxOpenIncomingStreams(&session_, 200);
- }
- // Create one stream.
- QuicStreamId stream_id = GetNthClientInitiatedUnidirectionalId(0);
- EXPECT_NE(nullptr, session_.GetOrCreateStream(stream_id));
-
- // Create the largest stream ID of a threatened total of 200 streams.
- // GetNth... starts at 0, so for 200 streams, get the 199th.
- EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
- EXPECT_NE(nullptr, session_.GetOrCreateStream(
- GetNthClientInitiatedUnidirectionalId(199)));
- if (VersionHasIetfQuicFrames(transport_version())) {
- // If IETF QUIC, check to make sure that creating unidirectional
- // streams does not mess up the bidirectional streams.
- stream_id = GetNthClientInitiatedBidirectionalId(0);
- EXPECT_NE(nullptr, session_.GetOrCreateStream(stream_id));
- // Now try to get the last possible bidirectional stream.
- EXPECT_NE(nullptr, session_.GetOrCreateStream(
- GetNthClientInitiatedBidirectionalId(49)));
- // and this should fail because it exceeds the bnidirectional limit
- // (but not the uni-)
- std::string error_detail;
- if (QuicVersionUsesCryptoFrames(transport_version())) {
- error_detail = "Stream id 796 would exceed stream count limit 50";
- } else {
- error_detail = "Stream id 800 would exceed stream count limit 50";
- }
- EXPECT_CALL(
- *connection_,
- CloseConnection(QUIC_INVALID_STREAM_ID, error_detail,
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET))
- .Times(1);
- EXPECT_EQ(nullptr, session_.GetOrCreateStream(
- GetNthClientInitiatedBidirectionalId(199)));
- }
-}
-
-TEST_P(QuicSessionTestServer, DebugDFatalIfMarkingClosedStreamWriteBlocked) {
- CompleteHandshake();
- TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
- QuicStreamId closed_stream_id = stream2->id();
- // Close the stream.
- EXPECT_CALL(*connection_, SendControlFrame(_));
- EXPECT_CALL(*connection_, OnStreamReset(closed_stream_id, _));
- stream2->Reset(QUIC_BAD_APPLICATION_PAYLOAD);
- std::string msg =
- absl::StrCat("Marking unknown stream ", closed_stream_id, " blocked.");
- EXPECT_QUIC_BUG(session_.MarkConnectionLevelWriteBlocked(closed_stream_id),
- msg);
-}
-
-TEST_P(QuicSessionTestServer, OnCanWrite) {
- CompleteHandshake();
- session_.set_writev_consumes_all_data(true);
- TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
- TestStream* stream4 = session_.CreateOutgoingBidirectionalStream();
- TestStream* stream6 = session_.CreateOutgoingBidirectionalStream();
-
- session_.MarkConnectionLevelWriteBlocked(stream2->id());
- session_.MarkConnectionLevelWriteBlocked(stream6->id());
- session_.MarkConnectionLevelWriteBlocked(stream4->id());
-
- InSequence s;
-
- // Reregister, to test the loop limit.
- EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
- session_.SendStreamData(stream2);
- session_.MarkConnectionLevelWriteBlocked(stream2->id());
- }));
- // 2 will get called a second time as it didn't finish its block
- EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
- session_.SendStreamData(stream2);
- }));
- EXPECT_CALL(*stream6, OnCanWrite()).WillOnce(Invoke([this, stream6]() {
- session_.SendStreamData(stream6);
- }));
- // 4 will not get called, as we exceeded the loop limit.
- session_.OnCanWrite();
- EXPECT_TRUE(session_.WillingAndAbleToWrite());
-}
-
-TEST_P(QuicSessionTestServer, TestBatchedWrites) {
- session_.set_writev_consumes_all_data(true);
- TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
- TestStream* stream4 = session_.CreateOutgoingBidirectionalStream();
- TestStream* stream6 = session_.CreateOutgoingBidirectionalStream();
-
- session_.set_writev_consumes_all_data(true);
- session_.MarkConnectionLevelWriteBlocked(stream2->id());
- session_.MarkConnectionLevelWriteBlocked(stream4->id());
-
- // With two sessions blocked, we should get two write calls. They should both
- // go to the first stream as it will only write 6k and mark itself blocked
- // again.
- InSequence s;
- EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
- session_.SendLargeFakeData(stream2, 6000);
- session_.MarkConnectionLevelWriteBlocked(stream2->id());
- }));
- EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
- session_.SendLargeFakeData(stream2, 6000);
- session_.MarkConnectionLevelWriteBlocked(stream2->id());
- }));
- session_.OnCanWrite();
-
- // We should get one more call for stream2, at which point it has used its
- // write quota and we move over to stream 4.
- EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
- session_.SendLargeFakeData(stream2, 6000);
- session_.MarkConnectionLevelWriteBlocked(stream2->id());
- }));
- EXPECT_CALL(*stream4, OnCanWrite()).WillOnce(Invoke([this, stream4]() {
- session_.SendLargeFakeData(stream4, 6000);
- session_.MarkConnectionLevelWriteBlocked(stream4->id());
- }));
- session_.OnCanWrite();
-
- // Now let stream 4 do the 2nd of its 3 writes, but add a block for a high
- // priority stream 6. 4 should be preempted. 6 will write but *not* block so
- // will cede back to 4.
- stream6->SetPriority(spdy::SpdyStreamPrecedence(kV3HighestPriority));
- EXPECT_CALL(*stream4, OnCanWrite())
- .WillOnce(Invoke([this, stream4, stream6]() {
- session_.SendLargeFakeData(stream4, 6000);
- session_.MarkConnectionLevelWriteBlocked(stream4->id());
- session_.MarkConnectionLevelWriteBlocked(stream6->id());
- }));
- EXPECT_CALL(*stream6, OnCanWrite())
- .WillOnce(Invoke([this, stream4, stream6]() {
- session_.SendStreamData(stream6);
- session_.SendLargeFakeData(stream4, 6000);
- }));
- session_.OnCanWrite();
-
- // Stream4 alread did 6k worth of writes, so after doing another 12k it should
- // cede and 2 should resume.
- EXPECT_CALL(*stream4, OnCanWrite()).WillOnce(Invoke([this, stream4]() {
- session_.SendLargeFakeData(stream4, 12000);
- session_.MarkConnectionLevelWriteBlocked(stream4->id());
- }));
- EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
- session_.SendLargeFakeData(stream2, 6000);
- session_.MarkConnectionLevelWriteBlocked(stream2->id());
- }));
- session_.OnCanWrite();
-}
-
-TEST_P(QuicSessionTestServer, OnCanWriteBundlesStreams) {
- // Encryption needs to be established before data can be sent.
- CompleteHandshake();
- MockPacketWriter* writer = static_cast<MockPacketWriter*>(
- QuicConnectionPeer::GetWriter(session_.connection()));
-
- // Drive congestion control manually.
- MockSendAlgorithm* send_algorithm = new StrictMock<MockSendAlgorithm>;
- QuicConnectionPeer::SetSendAlgorithm(session_.connection(), send_algorithm);
-
- TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
- TestStream* stream4 = session_.CreateOutgoingBidirectionalStream();
- TestStream* stream6 = session_.CreateOutgoingBidirectionalStream();
-
- session_.MarkConnectionLevelWriteBlocked(stream2->id());
- session_.MarkConnectionLevelWriteBlocked(stream6->id());
- session_.MarkConnectionLevelWriteBlocked(stream4->id());
-
- EXPECT_CALL(*send_algorithm, CanSend(_)).WillRepeatedly(Return(true));
- EXPECT_CALL(*send_algorithm, GetCongestionWindow())
- .WillRepeatedly(Return(kMaxOutgoingPacketSize * 10));
- EXPECT_CALL(*send_algorithm, InRecovery()).WillRepeatedly(Return(false));
- EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
- session_.SendStreamData(stream2);
- }));
- EXPECT_CALL(*stream4, OnCanWrite()).WillOnce(Invoke([this, stream4]() {
- session_.SendStreamData(stream4);
- }));
- EXPECT_CALL(*stream6, OnCanWrite()).WillOnce(Invoke([this, stream6]() {
- session_.SendStreamData(stream6);
- }));
-
- // Expect that we only send one packet, the writes from different streams
- // should be bundled together.
- EXPECT_CALL(*writer, WritePacket(_, _, _, _, _))
- .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 0)));
- EXPECT_CALL(*send_algorithm, OnPacketSent(_, _, _, _, _));
- EXPECT_CALL(*send_algorithm, OnApplicationLimited(_));
- session_.OnCanWrite();
- EXPECT_FALSE(session_.WillingAndAbleToWrite());
-}
-
-TEST_P(QuicSessionTestServer, OnCanWriteCongestionControlBlocks) {
- CompleteHandshake();
- session_.set_writev_consumes_all_data(true);
- InSequence s;
-
- // Drive congestion control manually.
- MockSendAlgorithm* send_algorithm = new StrictMock<MockSendAlgorithm>;
- QuicConnectionPeer::SetSendAlgorithm(session_.connection(), send_algorithm);
-
- TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
- TestStream* stream4 = session_.CreateOutgoingBidirectionalStream();
- TestStream* stream6 = session_.CreateOutgoingBidirectionalStream();
-
- session_.MarkConnectionLevelWriteBlocked(stream2->id());
- session_.MarkConnectionLevelWriteBlocked(stream6->id());
- session_.MarkConnectionLevelWriteBlocked(stream4->id());
-
- EXPECT_CALL(*send_algorithm, CanSend(_)).WillOnce(Return(true));
- EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
- session_.SendStreamData(stream2);
- }));
- EXPECT_CALL(*send_algorithm, GetCongestionWindow()).Times(AnyNumber());
- EXPECT_CALL(*send_algorithm, CanSend(_)).WillOnce(Return(true));
- EXPECT_CALL(*stream6, OnCanWrite()).WillOnce(Invoke([this, stream6]() {
- session_.SendStreamData(stream6);
- }));
- EXPECT_CALL(*send_algorithm, CanSend(_)).WillOnce(Return(false));
- // stream4->OnCanWrite is not called.
-
- session_.OnCanWrite();
- EXPECT_TRUE(session_.WillingAndAbleToWrite());
-
- // Still congestion-control blocked.
- EXPECT_CALL(*send_algorithm, CanSend(_)).WillOnce(Return(false));
- session_.OnCanWrite();
- EXPECT_TRUE(session_.WillingAndAbleToWrite());
-
- // stream4->OnCanWrite is called once the connection stops being
- // congestion-control blocked.
- EXPECT_CALL(*send_algorithm, CanSend(_)).WillOnce(Return(true));
- EXPECT_CALL(*stream4, OnCanWrite()).WillOnce(Invoke([this, stream4]() {
- session_.SendStreamData(stream4);
- }));
- EXPECT_CALL(*send_algorithm, OnApplicationLimited(_));
- session_.OnCanWrite();
- EXPECT_FALSE(session_.WillingAndAbleToWrite());
-}
-
-TEST_P(QuicSessionTestServer, OnCanWriteWriterBlocks) {
- CompleteHandshake();
- // Drive congestion control manually in order to ensure that
- // application-limited signaling is handled correctly.
- MockSendAlgorithm* send_algorithm = new StrictMock<MockSendAlgorithm>;
- QuicConnectionPeer::SetSendAlgorithm(session_.connection(), send_algorithm);
- EXPECT_CALL(*send_algorithm, CanSend(_)).WillRepeatedly(Return(true));
-
- // Drive packet writer manually.
- MockPacketWriter* writer = static_cast<MockPacketWriter*>(
- QuicConnectionPeer::GetWriter(session_.connection()));
- EXPECT_CALL(*writer, IsWriteBlocked()).WillRepeatedly(Return(true));
- EXPECT_CALL(*writer, WritePacket(_, _, _, _, _)).Times(0);
-
- TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
-
- session_.MarkConnectionLevelWriteBlocked(stream2->id());
-
- EXPECT_CALL(*stream2, OnCanWrite()).Times(0);
- EXPECT_CALL(*send_algorithm, OnApplicationLimited(_)).Times(0);
-
- session_.OnCanWrite();
- EXPECT_TRUE(session_.WillingAndAbleToWrite());
-}
-
-TEST_P(QuicSessionTestServer, SendStreamsBlocked) {
- if (!VersionHasIetfQuicFrames(transport_version())) {
- return;
- }
- CompleteHandshake();
- for (size_t i = 0; i < kDefaultMaxStreamsPerConnection; ++i) {
- ASSERT_TRUE(session_.CanOpenNextOutgoingBidirectionalStream());
- session_.GetNextOutgoingBidirectionalStreamId();
- }
- // Next checking causes STREAMS_BLOCKED to be sent.
- EXPECT_CALL(*connection_, SendControlFrame(_))
- .WillOnce(Invoke([](const QuicFrame& frame) {
- EXPECT_FALSE(frame.streams_blocked_frame.unidirectional);
- EXPECT_EQ(kDefaultMaxStreamsPerConnection,
- frame.streams_blocked_frame.stream_count);
- ClearControlFrame(frame);
- return true;
- }));
- EXPECT_FALSE(session_.CanOpenNextOutgoingBidirectionalStream());
-
- for (size_t i = 0; i < kDefaultMaxStreamsPerConnection; ++i) {
- ASSERT_TRUE(session_.CanOpenNextOutgoingUnidirectionalStream());
- session_.GetNextOutgoingUnidirectionalStreamId();
- }
- // Next checking causes STREAM_BLOCKED to be sent.
- EXPECT_CALL(*connection_, SendControlFrame(_))
- .WillOnce(Invoke([](const QuicFrame& frame) {
- EXPECT_TRUE(frame.streams_blocked_frame.unidirectional);
- EXPECT_EQ(kDefaultMaxStreamsPerConnection,
- frame.streams_blocked_frame.stream_count);
- ClearControlFrame(frame);
- return true;
- }));
- EXPECT_FALSE(session_.CanOpenNextOutgoingUnidirectionalStream());
-}
-
-TEST_P(QuicSessionTestServer, BufferedHandshake) {
- // This test is testing behavior of crypto stream flow control, but when
- // CRYPTO frames are used, there is no flow control for the crypto handshake.
- if (QuicVersionUsesCryptoFrames(connection_->transport_version())) {
- return;
- }
- session_.set_writev_consumes_all_data(true);
- EXPECT_FALSE(session_.HasPendingHandshake()); // Default value.
-
- // Test that blocking other streams does not change our status.
- TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
- session_.MarkConnectionLevelWriteBlocked(stream2->id());
- EXPECT_FALSE(session_.HasPendingHandshake());
-
- TestStream* stream3 = session_.CreateOutgoingBidirectionalStream();
- session_.MarkConnectionLevelWriteBlocked(stream3->id());
- EXPECT_FALSE(session_.HasPendingHandshake());
-
- // Blocking (due to buffering of) the Crypto stream is detected.
- session_.MarkConnectionLevelWriteBlocked(
- QuicUtils::GetCryptoStreamId(connection_->transport_version()));
- EXPECT_TRUE(session_.HasPendingHandshake());
-
- TestStream* stream4 = session_.CreateOutgoingBidirectionalStream();
- session_.MarkConnectionLevelWriteBlocked(stream4->id());
- EXPECT_TRUE(session_.HasPendingHandshake());
-
- InSequence s;
- // Force most streams to re-register, which is common scenario when we block
- // the Crypto stream, and only the crypto stream can "really" write.
-
- // Due to prioritization, we *should* be asked to write the crypto stream
- // first.
- // Don't re-register the crypto stream (which signals complete writing).
- TestCryptoStream* crypto_stream = session_.GetMutableCryptoStream();
- EXPECT_CALL(*crypto_stream, OnCanWrite());
-
- EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
- session_.SendStreamData(stream2);
- }));
- EXPECT_CALL(*stream3, OnCanWrite()).WillOnce(Invoke([this, stream3]() {
- session_.SendStreamData(stream3);
- }));
- EXPECT_CALL(*stream4, OnCanWrite()).WillOnce(Invoke([this, stream4]() {
- session_.SendStreamData(stream4);
- session_.MarkConnectionLevelWriteBlocked(stream4->id());
- }));
-
- session_.OnCanWrite();
- EXPECT_TRUE(session_.WillingAndAbleToWrite());
- EXPECT_FALSE(session_.HasPendingHandshake()); // Crypto stream wrote.
-}
-
-TEST_P(QuicSessionTestServer, OnCanWriteWithClosedStream) {
- CompleteHandshake();
- session_.set_writev_consumes_all_data(true);
- TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
- TestStream* stream4 = session_.CreateOutgoingBidirectionalStream();
- TestStream* stream6 = session_.CreateOutgoingBidirectionalStream();
-
- session_.MarkConnectionLevelWriteBlocked(stream2->id());
- session_.MarkConnectionLevelWriteBlocked(stream6->id());
- session_.MarkConnectionLevelWriteBlocked(stream4->id());
- CloseStream(stream6->id());
-
- InSequence s;
- EXPECT_CALL(*connection_, SendControlFrame(_))
- .WillRepeatedly(Invoke(&ClearControlFrame));
- EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
- session_.SendStreamData(stream2);
- }));
- EXPECT_CALL(*stream4, OnCanWrite()).WillOnce(Invoke([this, stream4]() {
- session_.SendStreamData(stream4);
- }));
- session_.OnCanWrite();
- EXPECT_FALSE(session_.WillingAndAbleToWrite());
-}
-
-TEST_P(QuicSessionTestServer, OnCanWriteLimitsNumWritesIfFlowControlBlocked) {
- // Drive congestion control manually in order to ensure that
- // application-limited signaling is handled correctly.
- MockSendAlgorithm* send_algorithm = new StrictMock<MockSendAlgorithm>;
- QuicConnectionPeer::SetSendAlgorithm(session_.connection(), send_algorithm);
- EXPECT_CALL(*send_algorithm, CanSend(_)).WillRepeatedly(Return(true));
-
- // Ensure connection level flow control blockage.
- QuicFlowControllerPeer::SetSendWindowOffset(session_.flow_controller(), 0);
- EXPECT_TRUE(session_.flow_controller()->IsBlocked());
- EXPECT_TRUE(session_.IsConnectionFlowControlBlocked());
- EXPECT_FALSE(session_.IsStreamFlowControlBlocked());
-
- // Mark the crypto and headers streams as write blocked, we expect them to be
- // allowed to write later.
- if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
- session_.MarkConnectionLevelWriteBlocked(
- QuicUtils::GetCryptoStreamId(connection_->transport_version()));
- }
-
- // Create a data stream, and although it is write blocked we never expect it
- // to be allowed to write as we are connection level flow control blocked.
- TestStream* stream = session_.CreateOutgoingBidirectionalStream();
- session_.MarkConnectionLevelWriteBlocked(stream->id());
- EXPECT_CALL(*stream, OnCanWrite()).Times(0);
-
- // The crypto and headers streams should be called even though we are
- // connection flow control blocked.
- if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
- TestCryptoStream* crypto_stream = session_.GetMutableCryptoStream();
- EXPECT_CALL(*crypto_stream, OnCanWrite());
- }
-
- // After the crypto and header streams perform a write, the connection will be
- // blocked by the flow control, hence it should become application-limited.
- EXPECT_CALL(*send_algorithm, OnApplicationLimited(_));
-
- session_.OnCanWrite();
- EXPECT_FALSE(session_.WillingAndAbleToWrite());
-}
-
-TEST_P(QuicSessionTestServer, SendGoAway) {
- if (VersionHasIetfQuicFrames(transport_version())) {
- // In IETF QUIC, GOAWAY lives up in the HTTP layer.
- return;
- }
- CompleteHandshake();
- connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
- MockPacketWriter* writer = static_cast<MockPacketWriter*>(
- QuicConnectionPeer::GetWriter(session_.connection()));
- EXPECT_CALL(*writer, WritePacket(_, _, _, _, _))
- .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 0)));
-
- EXPECT_CALL(*connection_, SendControlFrame(_))
- .WillOnce(
- Invoke(connection_, &MockQuicConnection::ReallySendControlFrame));
- session_.SendGoAway(QUIC_PEER_GOING_AWAY, "Going Away.");
- EXPECT_TRUE(session_.transport_goaway_sent());
-
- const QuicStreamId kTestStreamId = 5u;
- EXPECT_CALL(*connection_, SendControlFrame(_)).Times(0);
- EXPECT_CALL(*connection_,
- OnStreamReset(kTestStreamId, QUIC_STREAM_PEER_GOING_AWAY))
- .Times(0);
- EXPECT_TRUE(session_.GetOrCreateStream(kTestStreamId));
-}
-
-TEST_P(QuicSessionTestServer, DoNotSendGoAwayTwice) {
- CompleteHandshake();
- if (VersionHasIetfQuicFrames(transport_version())) {
- // In IETF QUIC, GOAWAY lives up in the HTTP layer.
- return;
- }
- EXPECT_CALL(*connection_, SendControlFrame(_))
- .WillOnce(Invoke(&ClearControlFrame));
- session_.SendGoAway(QUIC_PEER_GOING_AWAY, "Going Away.");
- EXPECT_TRUE(session_.transport_goaway_sent());
- session_.SendGoAway(QUIC_PEER_GOING_AWAY, "Going Away.");
-}
-
-TEST_P(QuicSessionTestServer, InvalidGoAway) {
- if (VersionHasIetfQuicFrames(transport_version())) {
- // In IETF QUIC, GOAWAY lives up in the HTTP layer.
- return;
- }
- QuicGoAwayFrame go_away(kInvalidControlFrameId, QUIC_PEER_GOING_AWAY,
- session_.next_outgoing_bidirectional_stream_id(), "");
- session_.OnGoAway(go_away);
-}
-
-// Test that server session will send a connectivity probe in response to a
-// connectivity probe on the same path.
-TEST_P(QuicSessionTestServer, ServerReplyToConnectivityProbe) {
- if (connection_->send_path_response() &&
- VersionHasIetfQuicFrames(transport_version())) {
- return;
- }
- connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
- QuicSocketAddress old_peer_address =
- QuicSocketAddress(QuicIpAddress::Loopback4(), kTestPort);
- EXPECT_EQ(old_peer_address, session_.peer_address());
-
- QuicSocketAddress new_peer_address =
- QuicSocketAddress(QuicIpAddress::Loopback4(), kTestPort + 1);
-
- MockPacketWriter* writer = static_cast<MockPacketWriter*>(
- QuicConnectionPeer::GetWriter(session_.connection()));
- EXPECT_CALL(*writer, WritePacket(_, _, _, new_peer_address, _))
- .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 0)));
- if (connection_->send_path_response()) {
- EXPECT_CALL(*connection_, SendConnectivityProbingPacket(_, _))
- .WillOnce(
- Invoke(connection_,
- &MockQuicConnection::ReallySendConnectivityProbingPacket));
- } else {
- EXPECT_CALL(*connection_, SendConnectivityProbingResponsePacket(_))
- .WillOnce(Invoke(
- connection_,
- &MockQuicConnection::ReallySendConnectivityProbingResponsePacket));
- }
- if (VersionHasIetfQuicFrames(transport_version())) {
- // Need to explicitly do this to emulate the reception of a PathChallenge,
- // which stores its payload for use in generating the response.
- connection_->OnPathChallengeFrame(
- QuicPathChallengeFrame(0, path_frame_buffer1_));
- }
- session_.OnPacketReceived(session_.self_address(), new_peer_address,
- /*is_connectivity_probe=*/true);
- EXPECT_EQ(old_peer_address, session_.peer_address());
-}
-
-// Same as above, but check that if there are two PATH_CHALLENGE frames in the
-// packet, the response has both of them AND we do not do migration. This for
-// IETF QUIC only.
-TEST_P(QuicSessionTestServer, ServerReplyToConnectivityProbes) {
- if (connection_->send_path_response() ||
- !VersionHasIetfQuicFrames(transport_version())) {
- return;
- }
- connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
- QuicSocketAddress old_peer_address =
- QuicSocketAddress(QuicIpAddress::Loopback4(), kTestPort);
- EXPECT_EQ(old_peer_address, session_.peer_address());
-
- MockPacketWriter* writer = static_cast<MockPacketWriter*>(
- QuicConnectionPeer::GetWriter(session_.connection()));
- // CheckMultiPathResponse validates that the written packet
- // contains both path responses.
- EXPECT_CALL(*writer, WritePacket(_, _, _, old_peer_address, _))
- .WillOnce(Invoke(this, &QuicSessionTestServer::CheckMultiPathResponse));
-
- EXPECT_CALL(*connection_, SendConnectivityProbingResponsePacket(_))
- .WillOnce(Invoke(
- connection_,
- &MockQuicConnection::ReallySendConnectivityProbingResponsePacket));
- QuicConnectionPeer::SetLastHeaderFormat(connection_,
- IETF_QUIC_SHORT_HEADER_PACKET);
- // Need to explicitly do this to emulate the reception of a PathChallenge,
- // which stores its payload for use in generating the response.
- connection_->OnPathChallengeFrame(
- QuicPathChallengeFrame(0, path_frame_buffer1_));
- connection_->OnPathChallengeFrame(
- QuicPathChallengeFrame(0, path_frame_buffer2_));
- session_.OnPacketReceived(session_.self_address(), old_peer_address,
- /*is_connectivity_probe=*/true);
-}
-
-TEST_P(QuicSessionTestServer, IncreasedTimeoutAfterCryptoHandshake) {
- EXPECT_EQ(kInitialIdleTimeoutSecs + 3,
- QuicConnectionPeer::GetNetworkTimeout(connection_).ToSeconds());
- CompleteHandshake();
- EXPECT_EQ(kMaximumIdleTimeoutSecs + 3,
- QuicConnectionPeer::GetNetworkTimeout(connection_).ToSeconds());
-}
-
-TEST_P(QuicSessionTestServer, OnStreamFrameFinStaticStreamId) {
- if (VersionUsesHttp3(connection_->transport_version())) {
- // The test relies on headers stream, which no longer exists in IETF QUIC.
- return;
- }
- QuicStreamId headers_stream_id =
- QuicUtils::GetHeadersStreamId(connection_->transport_version());
- std::unique_ptr<TestStream> fake_headers_stream =
- std::make_unique<TestStream>(headers_stream_id, &session_,
- /*is_static*/ true, BIDIRECTIONAL);
- QuicSessionPeer::ActivateStream(&session_, std::move(fake_headers_stream));
- // Send two bytes of payload.
- QuicStreamFrame data1(headers_stream_id, true, 0, absl::string_view("HT"));
- EXPECT_CALL(*connection_,
- CloseConnection(
- QUIC_INVALID_STREAM_ID, "Attempt to close a static stream",
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET));
- session_.OnStreamFrame(data1);
-}
-
-TEST_P(QuicSessionTestServer, OnStreamFrameInvalidStreamId) {
- // Send two bytes of payload.
- QuicStreamFrame data1(
- QuicUtils::GetInvalidStreamId(connection_->transport_version()), true, 0,
- absl::string_view("HT"));
- EXPECT_CALL(*connection_,
- CloseConnection(
- QUIC_INVALID_STREAM_ID, "Received data for an invalid stream",
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET));
- session_.OnStreamFrame(data1);
-}
-
-TEST_P(QuicSessionTestServer, OnRstStreamInvalidStreamId) {
- // Send two bytes of payload.
- QuicRstStreamFrame rst1(
- kInvalidControlFrameId,
- QuicUtils::GetInvalidStreamId(connection_->transport_version()),
- QUIC_ERROR_PROCESSING_STREAM, 0);
- EXPECT_CALL(*connection_,
- CloseConnection(
- QUIC_INVALID_STREAM_ID, "Received data for an invalid stream",
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET));
- session_.OnRstStream(rst1);
-}
-
-TEST_P(QuicSessionTestServer, HandshakeUnblocksFlowControlBlockedStream) {
- if (connection_->version().handshake_protocol == PROTOCOL_TLS1_3) {
- // This test requires Google QUIC crypto because it assumes streams start
- // off unblocked.
- return;
- }
- // Test that if a stream is flow control blocked, then on receipt of the SHLO
- // containing a suitable send window offset, the stream becomes unblocked.
-
- // Ensure that Writev consumes all the data it is given (simulate no socket
- // blocking).
- session_.set_writev_consumes_all_data(true);
- session_.GetMutableCryptoStream()->EstablishZeroRttEncryption();
-
- // Create a stream, and send enough data to make it flow control blocked.
- TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
- std::string body(kMinimumFlowControlSendWindow, '.');
- EXPECT_FALSE(stream2->IsFlowControlBlocked());
- EXPECT_FALSE(session_.IsConnectionFlowControlBlocked());
- EXPECT_FALSE(session_.IsStreamFlowControlBlocked());
- EXPECT_CALL(*connection_, SendControlFrame(_)).Times(AtLeast(1));
- stream2->WriteOrBufferData(body, false, nullptr);
- EXPECT_TRUE(stream2->IsFlowControlBlocked());
- EXPECT_TRUE(session_.IsConnectionFlowControlBlocked());
- EXPECT_TRUE(session_.IsStreamFlowControlBlocked());
-
- // Now complete the crypto handshake, resulting in an increased flow control
- // send window.
- CompleteHandshake();
- EXPECT_TRUE(QuicSessionPeer::IsStreamWriteBlocked(&session_, stream2->id()));
- // Stream is now unblocked.
- EXPECT_FALSE(stream2->IsFlowControlBlocked());
- EXPECT_FALSE(session_.IsConnectionFlowControlBlocked());
- EXPECT_FALSE(session_.IsStreamFlowControlBlocked());
-}
-
-TEST_P(QuicSessionTestServer, ConnectionFlowControlAccountingRstOutOfOrder) {
- CompleteHandshake();
- // Test that when we receive an out of order stream RST we correctly adjust
- // our connection level flow control receive window.
- // On close, the stream should mark as consumed all bytes between the highest
- // byte consumed so far and the final byte offset from the RST frame.
- TestStream* stream = session_.CreateOutgoingBidirectionalStream();
-
- const QuicStreamOffset kByteOffset =
- 1 + kInitialSessionFlowControlWindowForTest / 2;
-
- EXPECT_CALL(*connection_, SendControlFrame(_))
- .Times(2)
- .WillRepeatedly(Invoke(&ClearControlFrame));
- EXPECT_CALL(*connection_, OnStreamReset(stream->id(), _));
-
- QuicRstStreamFrame rst_frame(kInvalidControlFrameId, stream->id(),
- QUIC_STREAM_CANCELLED, kByteOffset);
- session_.OnRstStream(rst_frame);
- if (VersionHasIetfQuicFrames(transport_version())) {
- // The test requires the stream to be fully closed in both directions. For
- // IETF QUIC, the RST_STREAM only closes one side.
- QuicStopSendingFrame frame(kInvalidControlFrameId, stream->id(),
- QUIC_STREAM_CANCELLED);
- EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
- session_.OnStopSendingFrame(frame);
- }
- EXPECT_EQ(kByteOffset, session_.flow_controller()->bytes_consumed());
-}
-
-TEST_P(QuicSessionTestServer, ConnectionFlowControlAccountingFinAndLocalReset) {
- CompleteHandshake();
- // Test the situation where we receive a FIN on a stream, and before we fully
- // consume all the data from the sequencer buffer we locally RST the stream.
- // The bytes between highest consumed byte, and the final byte offset that we
- // determined when the FIN arrived, should be marked as consumed at the
- // connection level flow controller when the stream is reset.
- TestStream* stream = session_.CreateOutgoingBidirectionalStream();
-
- const QuicStreamOffset kByteOffset =
- kInitialSessionFlowControlWindowForTest / 2 - 1;
- QuicStreamFrame frame(stream->id(), true, kByteOffset, ".");
- session_.OnStreamFrame(frame);
- EXPECT_TRUE(connection_->connected());
-
- EXPECT_EQ(0u, session_.flow_controller()->bytes_consumed());
- EXPECT_EQ(kByteOffset + frame.data_length,
- stream->highest_received_byte_offset());
-
- // Reset stream locally.
- EXPECT_CALL(*connection_, SendControlFrame(_));
- EXPECT_CALL(*connection_, OnStreamReset(stream->id(), _));
- stream->Reset(QUIC_STREAM_CANCELLED);
- EXPECT_EQ(kByteOffset + frame.data_length,
- session_.flow_controller()->bytes_consumed());
-}
-
-TEST_P(QuicSessionTestServer, ConnectionFlowControlAccountingFinAfterRst) {
- CompleteHandshake();
- // Test that when we RST the stream (and tear down stream state), and then
- // receive a FIN from the peer, we correctly adjust our connection level flow
- // control receive window.
-
- // Connection starts with some non-zero highest received byte offset,
- // due to other active streams.
- const uint64_t kInitialConnectionBytesConsumed = 567;
- const uint64_t kInitialConnectionHighestReceivedOffset = 1234;
- EXPECT_LT(kInitialConnectionBytesConsumed,
- kInitialConnectionHighestReceivedOffset);
- session_.flow_controller()->UpdateHighestReceivedOffset(
- kInitialConnectionHighestReceivedOffset);
- session_.flow_controller()->AddBytesConsumed(kInitialConnectionBytesConsumed);
-
- // Reset our stream: this results in the stream being closed locally.
- TestStream* stream = session_.CreateOutgoingBidirectionalStream();
- EXPECT_CALL(*connection_, SendControlFrame(_));
- EXPECT_CALL(*connection_, OnStreamReset(stream->id(), _));
- stream->Reset(QUIC_STREAM_CANCELLED);
-
- // Now receive a response from the peer with a FIN. We should handle this by
- // adjusting the connection level flow control receive window to take into
- // account the total number of bytes sent by the peer.
- const QuicStreamOffset kByteOffset = 5678;
- std::string body = "hello";
- QuicStreamFrame frame(stream->id(), true, kByteOffset,
- absl::string_view(body));
- session_.OnStreamFrame(frame);
-
- QuicStreamOffset total_stream_bytes_sent_by_peer =
- kByteOffset + body.length();
- EXPECT_EQ(kInitialConnectionBytesConsumed + total_stream_bytes_sent_by_peer,
- session_.flow_controller()->bytes_consumed());
- EXPECT_EQ(
- kInitialConnectionHighestReceivedOffset + total_stream_bytes_sent_by_peer,
- session_.flow_controller()->highest_received_byte_offset());
-}
-
-TEST_P(QuicSessionTestServer, ConnectionFlowControlAccountingRstAfterRst) {
- CompleteHandshake();
- // Test that when we RST the stream (and tear down stream state), and then
- // receive a RST from the peer, we correctly adjust our connection level flow
- // control receive window.
-
- // Connection starts with some non-zero highest received byte offset,
- // due to other active streams.
- const uint64_t kInitialConnectionBytesConsumed = 567;
- const uint64_t kInitialConnectionHighestReceivedOffset = 1234;
- EXPECT_LT(kInitialConnectionBytesConsumed,
- kInitialConnectionHighestReceivedOffset);
- session_.flow_controller()->UpdateHighestReceivedOffset(
- kInitialConnectionHighestReceivedOffset);
- session_.flow_controller()->AddBytesConsumed(kInitialConnectionBytesConsumed);
-
- // Reset our stream: this results in the stream being closed locally.
- TestStream* stream = session_.CreateOutgoingBidirectionalStream();
- EXPECT_CALL(*connection_, SendControlFrame(_));
- EXPECT_CALL(*connection_, OnStreamReset(stream->id(), _));
- stream->Reset(QUIC_STREAM_CANCELLED);
- EXPECT_TRUE(QuicStreamPeer::read_side_closed(stream));
-
- // Now receive a RST from the peer. We should handle this by adjusting the
- // connection level flow control receive window to take into account the total
- // number of bytes sent by the peer.
- const QuicStreamOffset kByteOffset = 5678;
- QuicRstStreamFrame rst_frame(kInvalidControlFrameId, stream->id(),
- QUIC_STREAM_CANCELLED, kByteOffset);
- session_.OnRstStream(rst_frame);
-
- EXPECT_EQ(kInitialConnectionBytesConsumed + kByteOffset,
- session_.flow_controller()->bytes_consumed());
- EXPECT_EQ(kInitialConnectionHighestReceivedOffset + kByteOffset,
- session_.flow_controller()->highest_received_byte_offset());
-}
-
-TEST_P(QuicSessionTestServer, InvalidStreamFlowControlWindowInHandshake) {
- // Test that receipt of an invalid (< default) stream flow control window from
- // the peer results in the connection being torn down.
- const uint32_t kInvalidWindow = kMinimumFlowControlSendWindow - 1;
- QuicConfigPeer::SetReceivedInitialStreamFlowControlWindow(session_.config(),
- kInvalidWindow);
-
- if (connection_->version().handshake_protocol != PROTOCOL_TLS1_3) {
- EXPECT_CALL(*connection_,
- CloseConnection(QUIC_FLOW_CONTROL_INVALID_WINDOW, _, _));
- } else {
- EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
- }
- connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
- session_.OnConfigNegotiated();
-}
-
-// Test negotiation of custom server initial flow control window.
-TEST_P(QuicSessionTestServer, CustomFlowControlWindow) {
- QuicTagVector copt;
- copt.push_back(kIFW7);
- QuicConfigPeer::SetReceivedConnectionOptions(session_.config(), copt);
-
- connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
- session_.OnConfigNegotiated();
- EXPECT_EQ(192 * 1024u, QuicFlowControllerPeer::ReceiveWindowSize(
- session_.flow_controller()));
-}
-
-TEST_P(QuicSessionTestServer, FlowControlWithInvalidFinalOffset) {
- CompleteHandshake();
- // Test that if we receive a stream RST with a highest byte offset that
- // violates flow control, that we close the connection.
- const uint64_t kLargeOffset = kInitialSessionFlowControlWindowForTest + 1;
- EXPECT_CALL(*connection_,
- CloseConnection(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA, _, _))
- .Times(2);
-
- // Check that stream frame + FIN results in connection close.
- TestStream* stream = session_.CreateOutgoingBidirectionalStream();
- EXPECT_CALL(*connection_, SendControlFrame(_));
- EXPECT_CALL(*connection_, OnStreamReset(stream->id(), _));
- stream->Reset(QUIC_STREAM_CANCELLED);
- QuicStreamFrame frame(stream->id(), true, kLargeOffset, absl::string_view());
- session_.OnStreamFrame(frame);
-
- // Check that RST results in connection close.
- QuicRstStreamFrame rst_frame(kInvalidControlFrameId, stream->id(),
- QUIC_STREAM_CANCELLED, kLargeOffset);
- session_.OnRstStream(rst_frame);
-}
-
-TEST_P(QuicSessionTestServer, TooManyUnfinishedStreamsCauseServerRejectStream) {
- CompleteHandshake();
- // If a buggy/malicious peer creates too many streams that are not ended
- // with a FIN or RST then we send an RST to refuse streams. For IETF QUIC the
- // connection is closed.
- const QuicStreamId kMaxStreams = 5;
- if (VersionHasIetfQuicFrames(transport_version())) {
- QuicSessionPeer::SetMaxOpenIncomingBidirectionalStreams(&session_,
- kMaxStreams);
- } else {
- QuicSessionPeer::SetMaxOpenIncomingStreams(&session_, kMaxStreams);
- }
- const QuicStreamId kFirstStreamId = GetNthClientInitiatedBidirectionalId(0);
- const QuicStreamId kFinalStreamId =
- GetNthClientInitiatedBidirectionalId(kMaxStreams);
- // Create kMaxStreams data streams, and close them all without receiving a
- // FIN or a RST_STREAM from the client.
- for (QuicStreamId i = kFirstStreamId; i < kFinalStreamId;
- i += QuicUtils::StreamIdDelta(connection_->transport_version())) {
- QuicStreamFrame data1(i, false, 0, absl::string_view("HT"));
- session_.OnStreamFrame(data1);
- CloseStream(i);
- }
-
- if (VersionHasIetfQuicFrames(transport_version())) {
- EXPECT_CALL(
- *connection_,
- CloseConnection(QUIC_INVALID_STREAM_ID,
- "Stream id 20 would exceed stream count limit 5", _));
- } else {
- EXPECT_CALL(*connection_, SendControlFrame(_)).Times(1);
- EXPECT_CALL(*connection_,
- OnStreamReset(kFinalStreamId, QUIC_REFUSED_STREAM))
- .Times(1);
- }
- // Create one more data streams to exceed limit of open stream.
- QuicStreamFrame data1(kFinalStreamId, false, 0, absl::string_view("HT"));
- session_.OnStreamFrame(data1);
-}
-
-TEST_P(QuicSessionTestServer, DrainingStreamsDoNotCountAsOpenedOutgoing) {
- // Verify that a draining stream (which has received a FIN but not consumed
- // it) does not count against the open quota (because it is closed from the
- // protocol point of view).
- CompleteHandshake();
- TestStream* stream = session_.CreateOutgoingBidirectionalStream();
- QuicStreamId stream_id = stream->id();
- QuicStreamFrame data1(stream_id, true, 0, absl::string_view("HT"));
- session_.OnStreamFrame(data1);
- if (!VersionHasIetfQuicFrames(transport_version())) {
- EXPECT_CALL(session_, OnCanCreateNewOutgoingStream(false)).Times(1);
- }
- session_.StreamDraining(stream_id, /*unidirectional=*/false);
-}
-
-TEST_P(QuicSessionTestServer, NoPendingStreams) {
- session_.set_uses_pending_streams(false);
-
- QuicStreamId stream_id = QuicUtils::GetFirstUnidirectionalStreamId(
- transport_version(), Perspective::IS_CLIENT);
- QuicStreamFrame data1(stream_id, true, 10, absl::string_view("HT"));
- session_.OnStreamFrame(data1);
- EXPECT_EQ(1, session_.num_incoming_streams_created());
-
- QuicStreamFrame data2(stream_id, false, 0, absl::string_view("HT"));
- session_.OnStreamFrame(data2);
- EXPECT_EQ(1, session_.num_incoming_streams_created());
-}
-
-TEST_P(QuicSessionTestServer, PendingStreams) {
- if (!VersionUsesHttp3(transport_version())) {
- return;
- }
- session_.set_uses_pending_streams(true);
- session_.set_process_pending_stream_immediately(true);
-
- QuicStreamId stream_id = QuicUtils::GetFirstUnidirectionalStreamId(
- transport_version(), Perspective::IS_CLIENT);
- QuicStreamFrame data1(stream_id, true, 10, absl::string_view("HT"));
- session_.OnStreamFrame(data1);
- EXPECT_TRUE(QuicSessionPeer::GetPendingStream(&session_, stream_id));
- EXPECT_EQ(0, session_.num_incoming_streams_created());
-
- QuicStreamFrame data2(stream_id, false, 0, absl::string_view("HT"));
- session_.OnStreamFrame(data2);
- EXPECT_FALSE(QuicSessionPeer::GetPendingStream(&session_, stream_id));
- EXPECT_EQ(1, session_.num_incoming_streams_created());
-}
-
-TEST_P(QuicSessionTestServer, BufferAllIncomingStreams) {
- if (!VersionUsesHttp3(transport_version())) {
- return;
- }
- session_.set_uses_pending_streams(true);
- session_.set_process_pending_stream_immediately(false);
-
- QuicStreamId stream_id = QuicUtils::GetFirstUnidirectionalStreamId(
- transport_version(), Perspective::IS_CLIENT);
- QuicStreamFrame data1(stream_id, true, 10, absl::string_view("HT"));
- session_.OnStreamFrame(data1);
- EXPECT_TRUE(QuicSessionPeer::GetPendingStream(&session_, stream_id));
- EXPECT_EQ(0, session_.num_incoming_streams_created());
- // Read unidirectional stream is still buffered when the first byte arrives.
- QuicStreamFrame data2(stream_id, false, 0, absl::string_view("HT"));
- session_.OnStreamFrame(data2);
- EXPECT_TRUE(QuicSessionPeer::GetPendingStream(&session_, stream_id));
- EXPECT_EQ(0, session_.num_incoming_streams_created());
-
- // Bidirectional stream is buffered.
- QuicStreamId bidirectional_stream_id =
- QuicUtils::GetFirstBidirectionalStreamId(transport_version(),
- Perspective::IS_CLIENT);
- QuicStreamFrame data3(bidirectional_stream_id, false, 0,
- absl::string_view("HT"));
- session_.OnStreamFrame(data3);
- EXPECT_TRUE(
- QuicSessionPeer::GetPendingStream(&session_, bidirectional_stream_id));
- EXPECT_EQ(0, session_.num_incoming_streams_created());
-
- session_.ProcessAllPendingStreams();
- // Both bidirectional and read-unidirectional streams are unbuffered.
- EXPECT_FALSE(QuicSessionPeer::GetPendingStream(&session_, stream_id));
- EXPECT_FALSE(
- QuicSessionPeer::GetPendingStream(&session_, bidirectional_stream_id));
- EXPECT_EQ(2, session_.num_incoming_streams_created());
-}
-
-TEST_P(QuicSessionTestServer, RstPendingStreams) {
- if (!VersionUsesHttp3(transport_version())) {
- return;
- }
- session_.set_uses_pending_streams(true);
- session_.set_process_pending_stream_immediately(false);
-
- QuicStreamId stream_id = QuicUtils::GetFirstUnidirectionalStreamId(
- transport_version(), Perspective::IS_CLIENT);
- QuicStreamFrame data1(stream_id, true, 10, absl::string_view("HT"));
- session_.OnStreamFrame(data1);
- EXPECT_TRUE(QuicSessionPeer::GetPendingStream(&session_, stream_id));
- EXPECT_EQ(0, session_.num_incoming_streams_created());
- EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(&session_));
-
- QuicRstStreamFrame rst1(kInvalidControlFrameId, stream_id,
- QUIC_ERROR_PROCESSING_STREAM, 12);
- session_.OnRstStream(rst1);
- EXPECT_FALSE(QuicSessionPeer::GetPendingStream(&session_, stream_id));
- EXPECT_EQ(0, session_.num_incoming_streams_created());
- EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(&session_));
-
- QuicStreamFrame data2(stream_id, false, 0, absl::string_view("HT"));
- session_.OnStreamFrame(data2);
- EXPECT_FALSE(QuicSessionPeer::GetPendingStream(&session_, stream_id));
- EXPECT_EQ(0, session_.num_incoming_streams_created());
- EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(&session_));
-
- session_.ProcessAllPendingStreams();
- // Bidirectional stream is buffered.
- QuicStreamId bidirectional_stream_id =
- QuicUtils::GetFirstBidirectionalStreamId(transport_version(),
- Perspective::IS_CLIENT);
- QuicStreamFrame data3(bidirectional_stream_id, false, 0,
- absl::string_view("HT"));
- session_.OnStreamFrame(data3);
- EXPECT_TRUE(
- QuicSessionPeer::GetPendingStream(&session_, bidirectional_stream_id));
- EXPECT_EQ(0, session_.num_incoming_streams_created());
-
- // Bidirectional pending stream is removed after RST_STREAM is received.
- QuicRstStreamFrame rst2(kInvalidControlFrameId, bidirectional_stream_id,
- QUIC_ERROR_PROCESSING_STREAM, 12);
- session_.OnRstStream(rst2);
- EXPECT_FALSE(
- QuicSessionPeer::GetPendingStream(&session_, bidirectional_stream_id));
- EXPECT_EQ(0, session_.num_incoming_streams_created());
- EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(&session_));
-}
-
-TEST_P(QuicSessionTestServer, OnFinPendingStreams) {
- if (!VersionUsesHttp3(transport_version())) {
- return;
- }
- session_.set_uses_pending_streams(true);
- session_.set_process_pending_stream_immediately(true);
-
- QuicStreamId stream_id = QuicUtils::GetFirstUnidirectionalStreamId(
- transport_version(), Perspective::IS_CLIENT);
- QuicStreamFrame data(stream_id, true, 0, "");
- session_.OnStreamFrame(data);
-
- EXPECT_FALSE(QuicSessionPeer::GetPendingStream(&session_, stream_id));
- EXPECT_EQ(0, session_.num_incoming_streams_created());
- EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(&session_));
-
- session_.set_process_pending_stream_immediately(false);
- // Bidirectional pending stream remains after Fin is received.
- // Bidirectional stream is buffered.
- QuicStreamId bidirectional_stream_id =
- QuicUtils::GetFirstBidirectionalStreamId(transport_version(),
- Perspective::IS_CLIENT);
- QuicStreamFrame data2(bidirectional_stream_id, true, 0,
- absl::string_view("HT"));
- session_.OnStreamFrame(data2);
- EXPECT_TRUE(
- QuicSessionPeer::GetPendingStream(&session_, bidirectional_stream_id));
- EXPECT_EQ(0, session_.num_incoming_streams_created());
-
- session_.ProcessAllPendingStreams();
- EXPECT_FALSE(
- QuicSessionPeer::GetPendingStream(&session_, bidirectional_stream_id));
- EXPECT_EQ(1, session_.num_incoming_streams_created());
- QuicStream* bidirectional_stream =
- QuicSessionPeer::GetStream(&session_, bidirectional_stream_id);
- EXPECT_TRUE(bidirectional_stream->fin_received());
-}
-
-TEST_P(QuicSessionTestServer, UnidirectionalPendingStreamOnWindowUpdate) {
- if (!VersionUsesHttp3(transport_version())) {
- return;
- }
-
- session_.set_uses_pending_streams(true);
- QuicStreamId stream_id = QuicUtils::GetFirstUnidirectionalStreamId(
- transport_version(), Perspective::IS_CLIENT);
- QuicStreamFrame data1(stream_id, true, 10, absl::string_view("HT"));
- session_.OnStreamFrame(data1);
- EXPECT_TRUE(QuicSessionPeer::GetPendingStream(&session_, stream_id));
- EXPECT_EQ(0, session_.num_incoming_streams_created());
- QuicWindowUpdateFrame window_update_frame(kInvalidControlFrameId, stream_id,
- 0);
- EXPECT_CALL(
- *connection_,
- CloseConnection(
- QUIC_WINDOW_UPDATE_RECEIVED_ON_READ_UNIDIRECTIONAL_STREAM,
- "WindowUpdateFrame received on READ_UNIDIRECTIONAL stream.", _));
- session_.OnWindowUpdateFrame(window_update_frame);
-}
-
-TEST_P(QuicSessionTestServer, BidirectionalPendingStreamOnWindowUpdate) {
- if (!VersionUsesHttp3(transport_version())) {
- return;
- }
-
- session_.set_uses_pending_streams(true);
- session_.set_process_pending_stream_immediately(false);
- QuicStreamId stream_id = QuicUtils::GetFirstBidirectionalStreamId(
- transport_version(), Perspective::IS_CLIENT);
- QuicStreamFrame data(stream_id, true, 10, absl::string_view("HT"));
- session_.OnStreamFrame(data);
- QuicWindowUpdateFrame window_update_frame(kInvalidControlFrameId, stream_id,
- kDefaultFlowControlSendWindow * 2);
- session_.OnWindowUpdateFrame(window_update_frame);
- EXPECT_TRUE(QuicSessionPeer::GetPendingStream(&session_, stream_id));
- EXPECT_EQ(0, session_.num_incoming_streams_created());
-
- session_.ProcessAllPendingStreams();
- EXPECT_FALSE(QuicSessionPeer::GetPendingStream(&session_, stream_id));
- EXPECT_EQ(1, session_.num_incoming_streams_created());
- QuicStream* bidirectional_stream =
- QuicSessionPeer::GetStream(&session_, stream_id);
- QuicByteCount send_window =
- QuicStreamPeer::SendWindowSize(bidirectional_stream);
- EXPECT_EQ(send_window, kDefaultFlowControlSendWindow * 2);
-}
-
-TEST_P(QuicSessionTestServer, UnidirectionalPendingStreamOnStopSending) {
- if (!VersionUsesHttp3(transport_version())) {
- return;
- }
-
- session_.set_uses_pending_streams(true);
- QuicStreamId stream_id = QuicUtils::GetFirstUnidirectionalStreamId(
- transport_version(), Perspective::IS_CLIENT);
- QuicStreamFrame data1(stream_id, true, 10, absl::string_view("HT"));
- session_.OnStreamFrame(data1);
- EXPECT_TRUE(QuicSessionPeer::GetPendingStream(&session_, stream_id));
- EXPECT_EQ(0, session_.num_incoming_streams_created());
- QuicStopSendingFrame stop_sending_frame(kInvalidControlFrameId, stream_id,
- QUIC_STREAM_CANCELLED);
- EXPECT_CALL(
- *connection_,
- CloseConnection(QUIC_INVALID_STREAM_ID,
- "Received STOP_SENDING for a read-only stream", _));
- session_.OnStopSendingFrame(stop_sending_frame);
-}
-
-TEST_P(QuicSessionTestServer, BidirectionalPendingStreamOnStopSending) {
- if (!VersionUsesHttp3(transport_version())) {
- return;
- }
-
- session_.set_uses_pending_streams(true);
- session_.set_process_pending_stream_immediately(false);
- QuicStreamId stream_id = QuicUtils::GetFirstBidirectionalStreamId(
- transport_version(), Perspective::IS_CLIENT);
- QuicStreamFrame data(stream_id, true, 0, absl::string_view("HT"));
- session_.OnStreamFrame(data);
- QuicStopSendingFrame stop_sending_frame(kInvalidControlFrameId, stream_id,
- QUIC_STREAM_CANCELLED);
- session_.OnStopSendingFrame(stop_sending_frame);
- EXPECT_TRUE(QuicSessionPeer::GetPendingStream(&session_, stream_id));
- EXPECT_EQ(0, session_.num_incoming_streams_created());
-
- EXPECT_CALL(*connection_, OnStreamReset(stream_id, _));
- session_.ProcessAllPendingStreams();
- EXPECT_FALSE(QuicSessionPeer::GetPendingStream(&session_, stream_id));
- EXPECT_EQ(1, session_.num_incoming_streams_created());
- QuicStream* bidirectional_stream =
- QuicSessionPeer::GetStream(&session_, stream_id);
- EXPECT_TRUE(bidirectional_stream->write_side_closed());
-}
-
-TEST_P(QuicSessionTestServer, DrainingStreamsDoNotCountAsOpened) {
- // Verify that a draining stream (which has received a FIN but not consumed
- // it) does not count against the open quota (because it is closed from the
- // protocol point of view).
- CompleteHandshake();
- if (VersionHasIetfQuicFrames(transport_version())) {
- // On IETF QUIC, we will expect to see a MAX_STREAMS go out when there are
- // not enough streams to create the next one.
- EXPECT_CALL(*connection_, SendControlFrame(_)).Times(1);
- } else {
- EXPECT_CALL(*connection_, SendControlFrame(_)).Times(0);
- }
- EXPECT_CALL(*connection_, OnStreamReset(_, QUIC_REFUSED_STREAM)).Times(0);
- const QuicStreamId kMaxStreams = 5;
- if (VersionHasIetfQuicFrames(transport_version())) {
- QuicSessionPeer::SetMaxOpenIncomingBidirectionalStreams(&session_,
- kMaxStreams);
- } else {
- QuicSessionPeer::SetMaxOpenIncomingStreams(&session_, kMaxStreams);
- }
-
- // Create kMaxStreams + 1 data streams, and mark them draining.
- const QuicStreamId kFirstStreamId = GetNthClientInitiatedBidirectionalId(0);
- const QuicStreamId kFinalStreamId =
- GetNthClientInitiatedBidirectionalId(2 * kMaxStreams + 1);
- for (QuicStreamId i = kFirstStreamId; i < kFinalStreamId;
- i += QuicUtils::StreamIdDelta(connection_->transport_version())) {
- QuicStreamFrame data1(i, true, 0, absl::string_view("HT"));
- session_.OnStreamFrame(data1);
- EXPECT_EQ(1u, QuicSessionPeer::GetNumOpenDynamicStreams(&session_));
- session_.StreamDraining(i, /*unidirectional=*/false);
- EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(&session_));
- }
-}
-
-class QuicSessionTestClient : public QuicSessionTestBase {
- protected:
- QuicSessionTestClient()
- : QuicSessionTestBase(Perspective::IS_CLIENT,
- /*configure_session=*/true) {}
-};
-
-INSTANTIATE_TEST_SUITE_P(Tests,
- QuicSessionTestClient,
- ::testing::ValuesIn(AllSupportedVersions()),
- ::testing::PrintToStringParamName());
-
-TEST_P(QuicSessionTestClient, AvailableBidirectionalStreamsClient) {
- ASSERT_TRUE(session_.GetOrCreateStream(
- GetNthServerInitiatedBidirectionalId(2)) != nullptr);
- // Smaller bidirectional streams should be available.
- EXPECT_TRUE(QuicSessionPeer::IsStreamAvailable(
- &session_, GetNthServerInitiatedBidirectionalId(0)));
- EXPECT_TRUE(QuicSessionPeer::IsStreamAvailable(
- &session_, GetNthServerInitiatedBidirectionalId(1)));
- ASSERT_TRUE(session_.GetOrCreateStream(
- GetNthServerInitiatedBidirectionalId(0)) != nullptr);
- ASSERT_TRUE(session_.GetOrCreateStream(
- GetNthServerInitiatedBidirectionalId(1)) != nullptr);
- // And 5 should be not available.
- EXPECT_FALSE(QuicSessionPeer::IsStreamAvailable(
- &session_, GetNthClientInitiatedBidirectionalId(1)));
-}
-
-TEST_P(QuicSessionTestClient, InvalidSessionFlowControlWindowInHandshake) {
- // Test that receipt of an invalid (< default for gQUIC, < current for TLS)
- // session flow control window from the peer results in the connection being
- // torn down.
- const uint32_t kInvalidWindow = kMinimumFlowControlSendWindow - 1;
- QuicConfigPeer::SetReceivedInitialSessionFlowControlWindow(session_.config(),
- kInvalidWindow);
- EXPECT_CALL(
- *connection_,
- CloseConnection(connection_->version().AllowsLowFlowControlLimits()
- ? QUIC_ZERO_RTT_RESUMPTION_LIMIT_REDUCED
- : QUIC_FLOW_CONTROL_INVALID_WINDOW,
- _, _));
- connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
- session_.OnConfigNegotiated();
-}
-
-TEST_P(QuicSessionTestClient, InvalidBidiStreamLimitInHandshake) {
- // IETF QUIC only feature.
- if (!VersionHasIetfQuicFrames(transport_version())) {
- return;
- }
- QuicConfigPeer::SetReceivedMaxBidirectionalStreams(
- session_.config(), kDefaultMaxStreamsPerConnection - 1);
- EXPECT_CALL(*connection_,
- CloseConnection(QUIC_ZERO_RTT_RESUMPTION_LIMIT_REDUCED, _, _));
- connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
- session_.OnConfigNegotiated();
-}
-
-TEST_P(QuicSessionTestClient, InvalidUniStreamLimitInHandshake) {
- // IETF QUIC only feature.
- if (!VersionHasIetfQuicFrames(transport_version())) {
- return;
- }
- QuicConfigPeer::SetReceivedMaxUnidirectionalStreams(
- session_.config(), kDefaultMaxStreamsPerConnection - 1);
- EXPECT_CALL(*connection_,
- CloseConnection(QUIC_ZERO_RTT_RESUMPTION_LIMIT_REDUCED, _, _));
- connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
- session_.OnConfigNegotiated();
-}
-
-TEST_P(QuicSessionTestClient, InvalidStreamFlowControlWindowInHandshake) {
- // IETF QUIC only feature.
- if (!VersionHasIetfQuicFrames(transport_version())) {
- return;
- }
- session_.CreateOutgoingBidirectionalStream();
- session_.CreateOutgoingBidirectionalStream();
- QuicConfigPeer::SetReceivedInitialMaxStreamDataBytesOutgoingBidirectional(
- session_.config(), kMinimumFlowControlSendWindow - 1);
-
- EXPECT_CALL(*connection_, CloseConnection(_, _, _))
- .WillOnce(
- Invoke(connection_, &MockQuicConnection::ReallyCloseConnection));
- EXPECT_CALL(*connection_, SendConnectionClosePacket(_, _, _));
-
- connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
- session_.OnConfigNegotiated();
-}
-
-TEST_P(QuicSessionTestClient, OnMaxStreamFrame) {
- if (!VersionUsesHttp3(transport_version())) {
- return;
- }
- QuicMaxStreamsFrame frame;
- frame.unidirectional = false;
- frame.stream_count = 120;
- EXPECT_CALL(session_, OnCanCreateNewOutgoingStream(false)).Times(1);
- session_.OnMaxStreamsFrame(frame);
-
- QuicMaxStreamsFrame frame2;
- frame2.unidirectional = false;
- frame2.stream_count = 110;
- EXPECT_CALL(session_, OnCanCreateNewOutgoingStream(false)).Times(0);
- session_.OnMaxStreamsFrame(frame2);
-}
-
-TEST_P(QuicSessionTestClient, AvailableUnidirectionalStreamsClient) {
- ASSERT_TRUE(session_.GetOrCreateStream(
- GetNthServerInitiatedUnidirectionalId(2)) != nullptr);
- // Smaller unidirectional streams should be available.
- EXPECT_TRUE(QuicSessionPeer::IsStreamAvailable(
- &session_, GetNthServerInitiatedUnidirectionalId(0)));
- EXPECT_TRUE(QuicSessionPeer::IsStreamAvailable(
- &session_, GetNthServerInitiatedUnidirectionalId(1)));
- ASSERT_TRUE(session_.GetOrCreateStream(
- GetNthServerInitiatedUnidirectionalId(0)) != nullptr);
- ASSERT_TRUE(session_.GetOrCreateStream(
- GetNthServerInitiatedUnidirectionalId(1)) != nullptr);
- // And 5 should be not available.
- EXPECT_FALSE(QuicSessionPeer::IsStreamAvailable(
- &session_, GetNthClientInitiatedUnidirectionalId(1)));
-}
-
-TEST_P(QuicSessionTestClient, RecordFinAfterReadSideClosed) {
- CompleteHandshake();
- // Verify that an incoming FIN is recorded in a stream object even if the read
- // side has been closed. This prevents an entry from being made in
- // locally_closed_streams_highest_offset_ (which will never be deleted).
- TestStream* stream = session_.CreateOutgoingBidirectionalStream();
- QuicStreamId stream_id = stream->id();
-
- // Close the read side manually.
- QuicStreamPeer::CloseReadSide(stream);
-
- // Receive a stream data frame with FIN.
- QuicStreamFrame frame(stream_id, true, 0, absl::string_view());
- session_.OnStreamFrame(frame);
- EXPECT_TRUE(stream->fin_received());
-
- // Reset stream locally.
- EXPECT_CALL(*connection_, SendControlFrame(_));
- EXPECT_CALL(*connection_, OnStreamReset(stream->id(), _));
- stream->Reset(QUIC_STREAM_CANCELLED);
- EXPECT_TRUE(QuicStreamPeer::read_side_closed(stream));
-
- EXPECT_TRUE(connection_->connected());
- EXPECT_TRUE(QuicSessionPeer::IsStreamClosed(&session_, stream_id));
- EXPECT_FALSE(QuicSessionPeer::IsStreamCreated(&session_, stream_id));
-
- // The stream is not waiting for the arrival of the peer's final offset as it
- // was received with the FIN earlier.
- EXPECT_EQ(
- 0u,
- QuicSessionPeer::GetLocallyClosedStreamsHighestOffset(&session_).size());
-}
-
-TEST_P(QuicSessionTestClient, IncomingStreamWithClientInitiatedStreamId) {
- const QuicErrorCode expected_error =
- VersionHasIetfQuicFrames(transport_version())
- ? QUIC_HTTP_STREAM_WRONG_DIRECTION
- : QUIC_INVALID_STREAM_ID;
- EXPECT_CALL(
- *connection_,
- CloseConnection(expected_error, "Data for nonexistent stream",
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET));
-
- QuicStreamFrame frame(GetNthClientInitiatedBidirectionalId(1),
- /* fin = */ false, /* offset = */ 0,
- absl::string_view("foo"));
- session_.OnStreamFrame(frame);
-}
-
-TEST_P(QuicSessionTestClient, MinAckDelaySetOnTheClientQuicConfig) {
- if (!session_.version().HasIetfQuicFrames()) {
- return;
- }
- session_.config()->SetClientConnectionOptions({kAFFE});
- session_.Initialize();
- ASSERT_EQ(session_.config()->GetMinAckDelayToSendMs(),
- kDefaultMinAckDelayTimeMs);
- ASSERT_TRUE(session_.connection()->can_receive_ack_frequency_frame());
-}
-
-TEST_P(QuicSessionTestClient, FailedToCreateStreamIfTooCloseToIdleTimeout) {
- connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
- EXPECT_TRUE(session_.CanOpenNextOutgoingBidirectionalStream());
- QuicTime deadline = QuicConnectionPeer::GetIdleNetworkDeadline(connection_);
- ASSERT_TRUE(deadline.IsInitialized());
- QuicTime::Delta timeout = deadline - helper_.GetClock()->ApproximateNow();
- // Advance time to very close idle timeout.
- connection_->AdvanceTime(timeout - QuicTime::Delta::FromMilliseconds(1));
- // Verify creation of new stream gets pushed back and connectivity probing
- // packet gets sent.
- EXPECT_CALL(*connection_, SendConnectivityProbingPacket(_, _)).Times(1);
- EXPECT_FALSE(session_.CanOpenNextOutgoingBidirectionalStream());
-
- // New packet gets received, idle deadline gets extended.
- EXPECT_CALL(session_, OnCanCreateNewOutgoingStream(false));
- QuicConnectionPeer::GetIdleNetworkDetector(connection_)
- .OnPacketReceived(helper_.GetClock()->ApproximateNow());
- session_.OnPacketDecrypted(ENCRYPTION_FORWARD_SECURE);
-
- EXPECT_TRUE(session_.CanOpenNextOutgoingBidirectionalStream());
-}
-
-TEST_P(QuicSessionTestServer, ZombieStreams) {
- CompleteHandshake();
- TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
- QuicStreamPeer::SetStreamBytesWritten(3, stream2);
- EXPECT_TRUE(stream2->IsWaitingForAcks());
-
- CloseStream(stream2->id());
- ASSERT_EQ(1u, session_.closed_streams()->size());
- EXPECT_EQ(stream2->id(), session_.closed_streams()->front()->id());
- session_.MaybeCloseZombieStream(stream2->id());
- EXPECT_EQ(1u, session_.closed_streams()->size());
- EXPECT_EQ(stream2->id(), session_.closed_streams()->front()->id());
-}
-
-TEST_P(QuicSessionTestServer, RstStreamReceivedAfterRstStreamSent) {
- CompleteHandshake();
- TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
- QuicStreamPeer::SetStreamBytesWritten(3, stream2);
- EXPECT_TRUE(stream2->IsWaitingForAcks());
-
- EXPECT_CALL(*connection_, SendControlFrame(_));
- EXPECT_CALL(*connection_, OnStreamReset(stream2->id(), _));
- EXPECT_CALL(session_, OnCanCreateNewOutgoingStream(false)).Times(0);
- stream2->Reset(quic::QUIC_STREAM_CANCELLED);
-
- QuicRstStreamFrame rst1(kInvalidControlFrameId, stream2->id(),
- QUIC_ERROR_PROCESSING_STREAM, 0);
- if (!VersionHasIetfQuicFrames(transport_version())) {
- EXPECT_CALL(session_, OnCanCreateNewOutgoingStream(false)).Times(1);
- }
- session_.OnRstStream(rst1);
-}
-
-// Regression test of b/71548958.
-TEST_P(QuicSessionTestServer, TestZombieStreams) {
- CompleteHandshake();
- session_.set_writev_consumes_all_data(true);
-
- TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
- std::string body(100, '.');
- stream2->WriteOrBufferData(body, false, nullptr);
- EXPECT_TRUE(stream2->IsWaitingForAcks());
- EXPECT_EQ(1u, QuicStreamPeer::SendBuffer(stream2).size());
-
- QuicRstStreamFrame rst_frame(kInvalidControlFrameId, stream2->id(),
- QUIC_STREAM_CANCELLED, 1234);
- // Just for the RST_STREAM
- EXPECT_CALL(*connection_, SendControlFrame(_))
- .WillOnce(Invoke(&ClearControlFrame));
- if (VersionHasIetfQuicFrames(transport_version())) {
- EXPECT_CALL(*connection_,
- OnStreamReset(stream2->id(), QUIC_STREAM_CANCELLED));
- } else {
- EXPECT_CALL(*connection_,
- OnStreamReset(stream2->id(), QUIC_RST_ACKNOWLEDGEMENT));
- }
- stream2->OnStreamReset(rst_frame);
-
- if (VersionHasIetfQuicFrames(transport_version())) {
- // The test requires the stream to be fully closed in both directions. For
- // IETF QUIC, the RST_STREAM only closes one side.
- QuicStopSendingFrame frame(kInvalidControlFrameId, stream2->id(),
- QUIC_STREAM_CANCELLED);
- EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
- session_.OnStopSendingFrame(frame);
- }
- ASSERT_EQ(1u, session_.closed_streams()->size());
- EXPECT_EQ(stream2->id(), session_.closed_streams()->front()->id());
-
- TestStream* stream4 = session_.CreateOutgoingBidirectionalStream();
- if (VersionHasIetfQuicFrames(transport_version())) {
- // Once for the RST_STREAM, once for the STOP_SENDING
- EXPECT_CALL(*connection_, SendControlFrame(_))
- .Times(2)
- .WillRepeatedly(Invoke(&ClearControlFrame));
- } else {
- // Just for the RST_STREAM
- EXPECT_CALL(*connection_, SendControlFrame(_)).Times(1);
- }
- EXPECT_CALL(*connection_,
- OnStreamReset(stream4->id(), QUIC_STREAM_CANCELLED));
- stream4->WriteOrBufferData(body, false, nullptr);
- // Note well: Reset() actually closes the stream in both directions. For
- // GOOGLE QUIC it sends a RST_STREAM (which does a 2-way close), for IETF
- // QUIC it sends both a RST_STREAM and a STOP_SENDING (each of which
- // closes in only one direction).
- stream4->Reset(QUIC_STREAM_CANCELLED);
- EXPECT_EQ(2u, session_.closed_streams()->size());
-}
-
-TEST_P(QuicSessionTestServer, OnStreamFrameLost) {
- CompleteHandshake();
- InSequence s;
-
- // Drive congestion control manually.
- MockSendAlgorithm* send_algorithm = new StrictMock<MockSendAlgorithm>;
- QuicConnectionPeer::SetSendAlgorithm(session_.connection(), send_algorithm);
-
- TestCryptoStream* crypto_stream = session_.GetMutableCryptoStream();
- TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
- TestStream* stream4 = session_.CreateOutgoingBidirectionalStream();
-
- QuicStreamFrame frame1;
- if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
- frame1 = QuicStreamFrame(
- QuicUtils::GetCryptoStreamId(connection_->transport_version()), false,
- 0, 1300);
- }
- QuicStreamFrame frame2(stream2->id(), false, 0, 9);
- QuicStreamFrame frame3(stream4->id(), false, 0, 9);
-
- // Lost data on cryption stream, streams 2 and 4.
- EXPECT_CALL(*stream4, HasPendingRetransmission()).WillOnce(Return(true));
- if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
- EXPECT_CALL(*crypto_stream, HasPendingRetransmission())
- .WillOnce(Return(true));
- }
- EXPECT_CALL(*stream2, HasPendingRetransmission()).WillOnce(Return(true));
- session_.OnFrameLost(QuicFrame(frame3));
- if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
- session_.OnFrameLost(QuicFrame(frame1));
- } else {
- QuicCryptoFrame crypto_frame(ENCRYPTION_INITIAL, 0, 1300);
- session_.OnFrameLost(QuicFrame(&crypto_frame));
- }
- session_.OnFrameLost(QuicFrame(frame2));
- EXPECT_TRUE(session_.WillingAndAbleToWrite());
-
- // Mark streams 2 and 4 write blocked.
- session_.MarkConnectionLevelWriteBlocked(stream2->id());
- session_.MarkConnectionLevelWriteBlocked(stream4->id());
-
- // Lost data is retransmitted before new data, and retransmissions for crypto
- // stream go first.
- // Do not check congestion window when crypto stream has lost data.
- EXPECT_CALL(*send_algorithm, CanSend(_)).Times(0);
- if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
- EXPECT_CALL(*crypto_stream, OnCanWrite());
- EXPECT_CALL(*crypto_stream, HasPendingRetransmission())
- .WillOnce(Return(false));
- }
- // Check congestion window for non crypto streams.
- EXPECT_CALL(*send_algorithm, CanSend(_)).WillOnce(Return(true));
- EXPECT_CALL(*stream4, OnCanWrite());
- EXPECT_CALL(*stream4, HasPendingRetransmission()).WillOnce(Return(false));
- // Connection is blocked.
- EXPECT_CALL(*send_algorithm, CanSend(_)).WillRepeatedly(Return(false));
-
- session_.OnCanWrite();
- EXPECT_TRUE(session_.WillingAndAbleToWrite());
-
- // Unblock connection.
- // Stream 2 retransmits lost data.
- EXPECT_CALL(*send_algorithm, CanSend(_)).WillOnce(Return(true));
- EXPECT_CALL(*stream2, OnCanWrite());
- EXPECT_CALL(*stream2, HasPendingRetransmission()).WillOnce(Return(false));
- EXPECT_CALL(*send_algorithm, CanSend(_)).WillOnce(Return(true));
- // Stream 2 sends new data.
- EXPECT_CALL(*stream2, OnCanWrite());
- EXPECT_CALL(*send_algorithm, CanSend(_)).WillOnce(Return(true));
- EXPECT_CALL(*stream4, OnCanWrite());
- EXPECT_CALL(*send_algorithm, OnApplicationLimited(_));
-
- session_.OnCanWrite();
- EXPECT_FALSE(session_.WillingAndAbleToWrite());
-}
-
-TEST_P(QuicSessionTestServer, DonotRetransmitDataOfClosedStreams) {
- CompleteHandshake();
- InSequence s;
-
- TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
- TestStream* stream4 = session_.CreateOutgoingBidirectionalStream();
- TestStream* stream6 = session_.CreateOutgoingBidirectionalStream();
-
- QuicStreamFrame frame1(stream2->id(), false, 0, 9);
- QuicStreamFrame frame2(stream4->id(), false, 0, 9);
- QuicStreamFrame frame3(stream6->id(), false, 0, 9);
-
- EXPECT_CALL(*stream6, HasPendingRetransmission()).WillOnce(Return(true));
- EXPECT_CALL(*stream4, HasPendingRetransmission()).WillOnce(Return(true));
- EXPECT_CALL(*stream2, HasPendingRetransmission()).WillOnce(Return(true));
- session_.OnFrameLost(QuicFrame(frame3));
- session_.OnFrameLost(QuicFrame(frame2));
- session_.OnFrameLost(QuicFrame(frame1));
-
- session_.MarkConnectionLevelWriteBlocked(stream2->id());
- session_.MarkConnectionLevelWriteBlocked(stream4->id());
- session_.MarkConnectionLevelWriteBlocked(stream6->id());
-
- // Reset stream 4 locally.
- EXPECT_CALL(*connection_, SendControlFrame(_));
- EXPECT_CALL(*connection_, OnStreamReset(stream4->id(), _));
- stream4->Reset(QUIC_STREAM_CANCELLED);
-
- // Verify stream 4 is removed from streams with lost data list.
- EXPECT_CALL(*stream6, OnCanWrite());
- EXPECT_CALL(*stream6, HasPendingRetransmission()).WillOnce(Return(false));
- EXPECT_CALL(*stream2, OnCanWrite());
- EXPECT_CALL(*stream2, HasPendingRetransmission()).WillOnce(Return(false));
- EXPECT_CALL(*connection_, SendControlFrame(_))
- .WillRepeatedly(Invoke(&ClearControlFrame));
- EXPECT_CALL(*stream2, OnCanWrite());
- EXPECT_CALL(*stream6, OnCanWrite());
- session_.OnCanWrite();
-}
-
-TEST_P(QuicSessionTestServer, RetransmitFrames) {
- CompleteHandshake();
- MockSendAlgorithm* send_algorithm = new StrictMock<MockSendAlgorithm>;
- QuicConnectionPeer::SetSendAlgorithm(session_.connection(), send_algorithm);
- InSequence s;
-
- TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
- TestStream* stream4 = session_.CreateOutgoingBidirectionalStream();
- TestStream* stream6 = session_.CreateOutgoingBidirectionalStream();
- EXPECT_CALL(*connection_, SendControlFrame(_))
- .WillOnce(Invoke(&ClearControlFrame));
- session_.SendWindowUpdate(stream2->id(), 9);
-
- QuicStreamFrame frame1(stream2->id(), false, 0, 9);
- QuicStreamFrame frame2(stream4->id(), false, 0, 9);
- QuicStreamFrame frame3(stream6->id(), false, 0, 9);
- QuicWindowUpdateFrame window_update(1, stream2->id(), 9);
- QuicFrames frames;
- frames.push_back(QuicFrame(frame1));
- frames.push_back(QuicFrame(&window_update));
- frames.push_back(QuicFrame(frame2));
- frames.push_back(QuicFrame(frame3));
- EXPECT_FALSE(session_.WillingAndAbleToWrite());
-
- EXPECT_CALL(*stream2, RetransmitStreamData(_, _, _, _))
- .WillOnce(Return(true));
- EXPECT_CALL(*connection_, SendControlFrame(_))
- .WillOnce(Invoke(&ClearControlFrame));
- EXPECT_CALL(*stream4, RetransmitStreamData(_, _, _, _))
- .WillOnce(Return(true));
- EXPECT_CALL(*stream6, RetransmitStreamData(_, _, _, _))
- .WillOnce(Return(true));
- EXPECT_CALL(*send_algorithm, OnApplicationLimited(_));
- session_.RetransmitFrames(frames, TLP_RETRANSMISSION);
-}
-
-// Regression test of b/110082001.
-TEST_P(QuicSessionTestServer, RetransmitLostDataCausesConnectionClose) {
- CompleteHandshake();
- // This test mimics the scenario when a dynamic stream retransmits lost data
- // and causes connection close.
- TestStream* stream = session_.CreateOutgoingBidirectionalStream();
- QuicStreamFrame frame(stream->id(), false, 0, 9);
-
- EXPECT_CALL(*stream, HasPendingRetransmission())
- .Times(2)
- .WillOnce(Return(true))
- .WillOnce(Return(false));
- session_.OnFrameLost(QuicFrame(frame));
- // Retransmit stream data causes connection close. Stream has not sent fin
- // yet, so an RST is sent.
- EXPECT_CALL(*stream, OnCanWrite()).WillOnce(Invoke([this, stream]() {
- session_.ResetStream(stream->id(), QUIC_STREAM_CANCELLED);
- }));
- if (VersionHasIetfQuicFrames(transport_version())) {
- // Once for the RST_STREAM, once for the STOP_SENDING
- EXPECT_CALL(*connection_, SendControlFrame(_))
- .Times(2)
- .WillRepeatedly(Invoke(&session_, &TestSession::SaveFrame));
- } else {
- // Just for the RST_STREAM
- EXPECT_CALL(*connection_, SendControlFrame(_))
- .WillOnce(Invoke(&session_, &TestSession::SaveFrame));
- }
- EXPECT_CALL(*connection_, OnStreamReset(stream->id(), _));
- session_.OnCanWrite();
-}
-
-TEST_P(QuicSessionTestServer, SendMessage) {
- // Cannot send message when encryption is not established.
- EXPECT_FALSE(session_.OneRttKeysAvailable());
- EXPECT_EQ(MessageResult(MESSAGE_STATUS_ENCRYPTION_NOT_ESTABLISHED, 0),
- session_.SendMessage(MemSliceFromString("")));
-
- CompleteHandshake();
- EXPECT_TRUE(session_.OneRttKeysAvailable());
-
- EXPECT_CALL(*connection_, SendMessage(1, _, false))
- .WillOnce(Return(MESSAGE_STATUS_SUCCESS));
- EXPECT_EQ(MessageResult(MESSAGE_STATUS_SUCCESS, 1),
- session_.SendMessage(MemSliceFromString("")));
- // Verify message_id increases.
- EXPECT_CALL(*connection_, SendMessage(2, _, false))
- .WillOnce(Return(MESSAGE_STATUS_TOO_LARGE));
- EXPECT_EQ(MessageResult(MESSAGE_STATUS_TOO_LARGE, 0),
- session_.SendMessage(MemSliceFromString("")));
- // Verify unsent message does not consume a message_id.
- EXPECT_CALL(*connection_, SendMessage(2, _, false))
- .WillOnce(Return(MESSAGE_STATUS_SUCCESS));
- EXPECT_EQ(MessageResult(MESSAGE_STATUS_SUCCESS, 2),
- session_.SendMessage(MemSliceFromString("")));
-
- QuicMessageFrame frame(1);
- QuicMessageFrame frame2(2);
- EXPECT_FALSE(session_.IsFrameOutstanding(QuicFrame(&frame)));
- EXPECT_FALSE(session_.IsFrameOutstanding(QuicFrame(&frame2)));
-
- // Lost message 2.
- session_.OnMessageLost(2);
- EXPECT_FALSE(session_.IsFrameOutstanding(QuicFrame(&frame2)));
-
- // message 1 gets acked.
- session_.OnMessageAcked(1, QuicTime::Zero());
- EXPECT_FALSE(session_.IsFrameOutstanding(QuicFrame(&frame)));
-}
-
-// Regression test of b/115323618.
-TEST_P(QuicSessionTestServer, LocallyResetZombieStreams) {
- CompleteHandshake();
- session_.set_writev_consumes_all_data(true);
- TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
- std::string body(100, '.');
- QuicStreamPeer::CloseReadSide(stream2);
- stream2->WriteOrBufferData(body, true, nullptr);
- EXPECT_TRUE(stream2->IsWaitingForAcks());
- // Verify stream2 is a zombie streams.
- auto& stream_map = QuicSessionPeer::stream_map(&session_);
- ASSERT_TRUE(stream_map.contains(stream2->id()));
- auto* stream = stream_map.find(stream2->id())->second.get();
- EXPECT_TRUE(stream->IsZombie());
-
- QuicStreamFrame frame(stream2->id(), true, 0, 100);
- EXPECT_CALL(*stream2, HasPendingRetransmission())
- .WillRepeatedly(Return(true));
- session_.OnFrameLost(QuicFrame(frame));
-
- // Reset stream2 locally.
- EXPECT_CALL(*connection_, SendControlFrame(_))
- .WillRepeatedly(Invoke(&ClearControlFrame));
- EXPECT_CALL(*connection_, OnStreamReset(stream2->id(), _));
- stream2->Reset(QUIC_STREAM_CANCELLED);
-
- // Verify stream 2 gets closed.
- EXPECT_TRUE(session_.IsClosedStream(stream2->id()));
- EXPECT_CALL(*stream2, OnCanWrite()).Times(0);
- session_.OnCanWrite();
-}
-
-TEST_P(QuicSessionTestServer, CleanUpClosedStreamsAlarm) {
- CompleteHandshake();
- EXPECT_FALSE(
- QuicSessionPeer::GetCleanUpClosedStreamsAlarm(&session_)->IsSet());
-
- session_.set_writev_consumes_all_data(true);
- TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
- EXPECT_FALSE(stream2->IsWaitingForAcks());
-
- CloseStream(stream2->id());
- EXPECT_EQ(1u, session_.closed_streams()->size());
- EXPECT_TRUE(
- QuicSessionPeer::GetCleanUpClosedStreamsAlarm(&session_)->IsSet());
-
- alarm_factory_.FireAlarm(
- QuicSessionPeer::GetCleanUpClosedStreamsAlarm(&session_));
- EXPECT_TRUE(session_.closed_streams()->empty());
-}
-
-TEST_P(QuicSessionTestServer, WriteUnidirectionalStream) {
- session_.set_writev_consumes_all_data(true);
- TestStream* stream4 = new TestStream(GetNthServerInitiatedUnidirectionalId(1),
- &session_, WRITE_UNIDIRECTIONAL);
- session_.ActivateStream(absl::WrapUnique(stream4));
- std::string body(100, '.');
- stream4->WriteOrBufferData(body, false, nullptr);
- stream4->WriteOrBufferData(body, true, nullptr);
- auto& stream_map = QuicSessionPeer::stream_map(&session_);
- ASSERT_TRUE(stream_map.contains(stream4->id()));
- auto* stream = stream_map.find(stream4->id())->second.get();
- EXPECT_TRUE(stream->IsZombie());
-}
-
-TEST_P(QuicSessionTestServer, ReceivedDataOnWriteUnidirectionalStream) {
- TestStream* stream4 = new TestStream(GetNthServerInitiatedUnidirectionalId(1),
- &session_, WRITE_UNIDIRECTIONAL);
- session_.ActivateStream(absl::WrapUnique(stream4));
-
- EXPECT_CALL(
- *connection_,
- CloseConnection(QUIC_DATA_RECEIVED_ON_WRITE_UNIDIRECTIONAL_STREAM, _, _))
- .Times(1);
- QuicStreamFrame stream_frame(GetNthServerInitiatedUnidirectionalId(1), false,
- 0, 2);
- session_.OnStreamFrame(stream_frame);
-}
-
-TEST_P(QuicSessionTestServer, ReadUnidirectionalStream) {
- TestStream* stream4 = new TestStream(GetNthClientInitiatedUnidirectionalId(1),
- &session_, READ_UNIDIRECTIONAL);
- session_.ActivateStream(absl::WrapUnique(stream4));
- EXPECT_FALSE(stream4->IsWaitingForAcks());
- // Discard all incoming data.
- stream4->StopReading();
-
- std::string data(100, '.');
- QuicStreamFrame stream_frame(GetNthClientInitiatedUnidirectionalId(1), false,
- 0, data);
- stream4->OnStreamFrame(stream_frame);
- EXPECT_TRUE(session_.closed_streams()->empty());
-
- QuicStreamFrame stream_frame2(GetNthClientInitiatedUnidirectionalId(1), true,
- 100, data);
- stream4->OnStreamFrame(stream_frame2);
- EXPECT_EQ(1u, session_.closed_streams()->size());
-}
-
-TEST_P(QuicSessionTestServer, WriteOrBufferDataOnReadUnidirectionalStream) {
- TestStream* stream4 = new TestStream(GetNthClientInitiatedUnidirectionalId(1),
- &session_, READ_UNIDIRECTIONAL);
- session_.ActivateStream(absl::WrapUnique(stream4));
-
- EXPECT_CALL(*connection_,
- CloseConnection(
- QUIC_TRY_TO_WRITE_DATA_ON_READ_UNIDIRECTIONAL_STREAM, _, _))
- .Times(1);
- std::string body(100, '.');
- stream4->WriteOrBufferData(body, false, nullptr);
-}
-
-TEST_P(QuicSessionTestServer, WritevDataOnReadUnidirectionalStream) {
- TestStream* stream4 = new TestStream(GetNthClientInitiatedUnidirectionalId(1),
- &session_, READ_UNIDIRECTIONAL);
- session_.ActivateStream(absl::WrapUnique(stream4));
-
- EXPECT_CALL(*connection_,
- CloseConnection(
- QUIC_TRY_TO_WRITE_DATA_ON_READ_UNIDIRECTIONAL_STREAM, _, _))
- .Times(1);
- std::string body(100, '.');
- struct iovec iov = {const_cast<char*>(body.data()), body.length()};
- QuicMemSliceStorage storage(
- &iov, 1, session_.connection()->helper()->GetStreamSendBufferAllocator(),
- 1024);
- stream4->WriteMemSlices(storage.ToSpan(), false);
-}
-
-TEST_P(QuicSessionTestServer, WriteMemSlicesOnReadUnidirectionalStream) {
- TestStream* stream4 = new TestStream(GetNthClientInitiatedUnidirectionalId(1),
- &session_, READ_UNIDIRECTIONAL);
- session_.ActivateStream(absl::WrapUnique(stream4));
-
- EXPECT_CALL(*connection_,
- CloseConnection(
- QUIC_TRY_TO_WRITE_DATA_ON_READ_UNIDIRECTIONAL_STREAM, _, _))
- .Times(1);
- std::string data(1024, 'a');
- std::vector<QuicMemSlice> buffers;
- buffers.push_back(MemSliceFromString(data));
- buffers.push_back(MemSliceFromString(data));
- stream4->WriteMemSlices(absl::MakeSpan(buffers), false);
-}
-
-// Test code that tests that an incoming stream frame with a new (not previously
-// seen) stream id is acceptable. The ID must not be larger than has been
-// advertised. It may be equal to what has been advertised. These tests
-// invoke QuicStreamIdManager::MaybeIncreaseLargestPeerStreamId by calling
-// QuicSession::OnStreamFrame in order to check that all the steps are connected
-// properly and that nothing in the call path interferes with the check.
-// First test make sure that streams with ids below the limit are accepted.
-TEST_P(QuicSessionTestServer, NewStreamIdBelowLimit) {
- if (!VersionHasIetfQuicFrames(transport_version())) {
- // Applicable only to IETF QUIC
- return;
- }
- QuicStreamId bidirectional_stream_id = StreamCountToId(
- QuicSessionPeer::ietf_streamid_manager(&session_)
- ->advertised_max_incoming_bidirectional_streams() -
- 1,
- Perspective::IS_CLIENT,
- /*bidirectional=*/true);
-
- QuicStreamFrame bidirectional_stream_frame(bidirectional_stream_id, false, 0,
- "Random String");
- EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
- session_.OnStreamFrame(bidirectional_stream_frame);
-
- QuicStreamId unidirectional_stream_id = StreamCountToId(
- QuicSessionPeer::ietf_streamid_manager(&session_)
- ->advertised_max_incoming_unidirectional_streams() -
- 1,
- Perspective::IS_CLIENT,
- /*bidirectional=*/false);
- QuicStreamFrame unidirectional_stream_frame(unidirectional_stream_id, false,
- 0, "Random String");
- EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
- session_.OnStreamFrame(unidirectional_stream_frame);
-}
-
-// Accept a stream with an ID that equals the limit.
-TEST_P(QuicSessionTestServer, NewStreamIdAtLimit) {
- if (!VersionHasIetfQuicFrames(transport_version())) {
- // Applicable only to IETF QUIC
- return;
- }
- QuicStreamId bidirectional_stream_id =
- StreamCountToId(QuicSessionPeer::ietf_streamid_manager(&session_)
- ->advertised_max_incoming_bidirectional_streams(),
- Perspective::IS_CLIENT, /*bidirectional=*/true);
- QuicStreamFrame bidirectional_stream_frame(bidirectional_stream_id, false, 0,
- "Random String");
- EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
- session_.OnStreamFrame(bidirectional_stream_frame);
-
- QuicStreamId unidirectional_stream_id =
- StreamCountToId(QuicSessionPeer::ietf_streamid_manager(&session_)
- ->advertised_max_incoming_unidirectional_streams(),
- Perspective::IS_CLIENT, /*bidirectional=*/false);
- QuicStreamFrame unidirectional_stream_frame(unidirectional_stream_id, false,
- 0, "Random String");
- EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
- session_.OnStreamFrame(unidirectional_stream_frame);
-}
-
-// Close the connection if the id exceeds the limit.
-TEST_P(QuicSessionTestServer, NewStreamIdAboveLimit) {
- if (!VersionHasIetfQuicFrames(transport_version())) {
- // Applicable only to IETF QUIC
- return;
- }
-
- QuicStreamId bidirectional_stream_id = StreamCountToId(
- QuicSessionPeer::ietf_streamid_manager(&session_)
- ->advertised_max_incoming_bidirectional_streams() +
- 1,
- Perspective::IS_CLIENT, /*bidirectional=*/true);
- QuicStreamFrame bidirectional_stream_frame(bidirectional_stream_id, false, 0,
- "Random String");
- EXPECT_CALL(
- *connection_,
- CloseConnection(QUIC_INVALID_STREAM_ID,
- "Stream id 400 would exceed stream count limit 100", _));
- session_.OnStreamFrame(bidirectional_stream_frame);
-
- QuicStreamId unidirectional_stream_id = StreamCountToId(
- QuicSessionPeer::ietf_streamid_manager(&session_)
- ->advertised_max_incoming_unidirectional_streams() +
- 1,
- Perspective::IS_CLIENT, /*bidirectional=*/false);
- QuicStreamFrame unidirectional_stream_frame(unidirectional_stream_id, false,
- 0, "Random String");
- EXPECT_CALL(
- *connection_,
- CloseConnection(QUIC_INVALID_STREAM_ID,
- "Stream id 402 would exceed stream count limit 100", _));
- session_.OnStreamFrame(unidirectional_stream_frame);
-}
-
-// Checks that invalid stream ids are handled.
-TEST_P(QuicSessionTestServer, OnStopSendingInvalidStreamId) {
- if (!VersionHasIetfQuicFrames(transport_version())) {
- return;
- }
- // Check that "invalid" stream ids are rejected.
- QuicStopSendingFrame frame(1, -1, QUIC_STREAM_CANCELLED);
- EXPECT_CALL(
- *connection_,
- CloseConnection(QUIC_INVALID_STREAM_ID,
- "Received STOP_SENDING for an invalid stream", _));
- session_.OnStopSendingFrame(frame);
-}
-
-TEST_P(QuicSessionTestServer, OnStopSendingReadUnidirectional) {
- if (!VersionHasIetfQuicFrames(transport_version())) {
- return;
- }
- // It's illegal to send STOP_SENDING with a stream ID that is read-only.
- QuicStopSendingFrame frame(1, GetNthClientInitiatedUnidirectionalId(1),
- QUIC_STREAM_CANCELLED);
- EXPECT_CALL(
- *connection_,
- CloseConnection(QUIC_INVALID_STREAM_ID,
- "Received STOP_SENDING for a read-only stream", _));
- session_.OnStopSendingFrame(frame);
-}
-
-// Static streams ignore STOP_SENDING.
-TEST_P(QuicSessionTestServer, OnStopSendingStaticStreams) {
- if (!VersionHasIetfQuicFrames(transport_version())) {
- return;
- }
- QuicStreamId stream_id = 0;
- std::unique_ptr<TestStream> fake_static_stream = std::make_unique<TestStream>(
- stream_id, &session_, /*is_static*/ true, BIDIRECTIONAL);
- QuicSessionPeer::ActivateStream(&session_, std::move(fake_static_stream));
- // Check that a stream id in the static stream map is ignored.
- QuicStopSendingFrame frame(1, stream_id, QUIC_STREAM_CANCELLED);
- EXPECT_CALL(*connection_,
- CloseConnection(QUIC_INVALID_STREAM_ID,
- "Received STOP_SENDING for a static stream", _));
- session_.OnStopSendingFrame(frame);
-}
-
-// If stream is write closed, do not send a RESET_STREAM frame.
-TEST_P(QuicSessionTestServer, OnStopSendingForWriteClosedStream) {
- if (!VersionHasIetfQuicFrames(transport_version())) {
- return;
- }
-
- TestStream* stream = session_.CreateOutgoingBidirectionalStream();
- QuicStreamId stream_id = stream->id();
- QuicStreamPeer::SetFinSent(stream);
- stream->CloseWriteSide();
- EXPECT_TRUE(stream->write_side_closed());
- QuicStopSendingFrame frame(1, stream_id, QUIC_STREAM_CANCELLED);
- EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
- session_.OnStopSendingFrame(frame);
-}
-
-// If stream is closed, return true and do not close the connection.
-TEST_P(QuicSessionTestServer, OnStopSendingClosedStream) {
- if (!VersionHasIetfQuicFrames(transport_version())) {
- return;
- }
- CompleteHandshake();
- TestStream* stream = session_.CreateOutgoingBidirectionalStream();
- QuicStreamId stream_id = stream->id();
- CloseStream(stream_id);
- QuicStopSendingFrame frame(1, stream_id, QUIC_STREAM_CANCELLED);
- EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
- session_.OnStopSendingFrame(frame);
-}
-
-// If stream id is a nonexistent local stream, return false and close the
-// connection.
-TEST_P(QuicSessionTestServer, OnStopSendingInputNonExistentLocalStream) {
- if (!VersionHasIetfQuicFrames(transport_version())) {
- return;
- }
-
- QuicStopSendingFrame frame(1, GetNthServerInitiatedBidirectionalId(123456),
- QUIC_STREAM_CANCELLED);
- EXPECT_CALL(*connection_, CloseConnection(QUIC_HTTP_STREAM_WRONG_DIRECTION,
- "Data for nonexistent stream", _))
- .Times(1);
- session_.OnStopSendingFrame(frame);
-}
-
-// If a STOP_SENDING is received for a peer initiated stream, the new stream
-// will be created.
-TEST_P(QuicSessionTestServer, OnStopSendingNewStream) {
- CompleteHandshake();
- if (!VersionHasIetfQuicFrames(transport_version())) {
- return;
- }
- QuicStopSendingFrame frame(1, GetNthClientInitiatedBidirectionalId(1),
- QUIC_STREAM_CANCELLED);
-
- // A Rst will be sent as a response for STOP_SENDING.
- EXPECT_CALL(*connection_, SendControlFrame(_)).Times(1);
- EXPECT_CALL(*connection_, OnStreamReset(_, _)).Times(1);
- session_.OnStopSendingFrame(frame);
-
- QuicStream* stream =
- session_.GetOrCreateStream(GetNthClientInitiatedBidirectionalId(1));
- EXPECT_TRUE(stream);
- EXPECT_TRUE(stream->write_side_closed());
-}
-
-// For a valid stream, ensure that all works
-TEST_P(QuicSessionTestServer, OnStopSendingInputValidStream) {
- CompleteHandshake();
- if (!VersionHasIetfQuicFrames(transport_version())) {
- // Applicable only to IETF QUIC
- return;
- }
-
- TestStream* stream = session_.CreateOutgoingBidirectionalStream();
-
- // Ensure that the stream starts out open in both directions.
- EXPECT_FALSE(stream->write_side_closed());
- EXPECT_FALSE(QuicStreamPeer::read_side_closed(stream));
-
- QuicStreamId stream_id = stream->id();
- QuicStopSendingFrame frame(1, stream_id, QUIC_STREAM_CANCELLED);
- // Expect a reset to come back out.
- EXPECT_CALL(*connection_, SendControlFrame(_));
- EXPECT_CALL(*connection_, OnStreamReset(stream_id, QUIC_STREAM_CANCELLED));
- EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
- session_.OnStopSendingFrame(frame);
-
- EXPECT_FALSE(QuicStreamPeer::read_side_closed(stream));
- EXPECT_TRUE(stream->write_side_closed());
-}
-
-TEST_P(QuicSessionTestServer, WriteBufferedCryptoFrames) {
- if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
- return;
- }
- std::string data(1350, 'a');
- TestCryptoStream* crypto_stream = session_.GetMutableCryptoStream();
- // Only consumed 1000 bytes.
- EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_INITIAL, 1350, 0))
- .WillOnce(Return(1000));
- crypto_stream->WriteCryptoData(ENCRYPTION_INITIAL, data);
- EXPECT_TRUE(session_.HasPendingHandshake());
- EXPECT_TRUE(session_.WillingAndAbleToWrite());
-
- EXPECT_CALL(*connection_, SendCryptoData(_, _, _)).Times(0);
- connection_->SetEncrypter(
- ENCRYPTION_ZERO_RTT,
- std::make_unique<NullEncrypter>(connection_->perspective()));
- crypto_stream->WriteCryptoData(ENCRYPTION_ZERO_RTT, data);
-
- EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_INITIAL, 350, 1000))
- .WillOnce(Return(350));
- EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_ZERO_RTT, 1350, 0))
- .WillOnce(Return(1350));
- session_.OnCanWrite();
- EXPECT_FALSE(session_.HasPendingHandshake());
- EXPECT_FALSE(session_.WillingAndAbleToWrite());
-}
-
-// Regression test for
-// https://bugs.chromium.org/p/chromium/issues/detail?id=1002119
-TEST_P(QuicSessionTestServer, StreamFrameReceivedAfterFin) {
- TestStream* stream = session_.CreateOutgoingBidirectionalStream();
- QuicStreamFrame frame(stream->id(), true, 0, ",");
- session_.OnStreamFrame(frame);
-
- QuicStreamFrame frame1(stream->id(), false, 1, ",");
- EXPECT_CALL(*connection_,
- CloseConnection(QUIC_STREAM_DATA_BEYOND_CLOSE_OFFSET, _, _));
- session_.OnStreamFrame(frame1);
-}
-
-TEST_P(QuicSessionTestServer, ResetForIETFStreamTypes) {
- CompleteHandshake();
- if (!VersionHasIetfQuicFrames(transport_version())) {
- return;
- }
-
- QuicStreamId read_only = GetNthClientInitiatedUnidirectionalId(0);
-
- EXPECT_CALL(*connection_, SendControlFrame(_))
- .Times(1)
- .WillOnce(Invoke(&ClearControlFrame));
- EXPECT_CALL(*connection_, OnStreamReset(read_only, _));
- session_.ResetStream(read_only, QUIC_STREAM_CANCELLED);
-
- QuicStreamId write_only = GetNthServerInitiatedUnidirectionalId(0);
- EXPECT_CALL(*connection_, SendControlFrame(_))
- .Times(1)
- .WillOnce(Invoke(&ClearControlFrame));
- EXPECT_CALL(*connection_, OnStreamReset(write_only, _));
- session_.ResetStream(write_only, QUIC_STREAM_CANCELLED);
-
- QuicStreamId bidirectional = GetNthClientInitiatedBidirectionalId(0);
- EXPECT_CALL(*connection_, SendControlFrame(_))
- .Times(2)
- .WillRepeatedly(Invoke(&ClearControlFrame));
- EXPECT_CALL(*connection_, OnStreamReset(bidirectional, _));
- session_.ResetStream(bidirectional, QUIC_STREAM_CANCELLED);
-}
-
-TEST_P(QuicSessionTestServer, DecryptionKeyAvailableBeforeEncryptionKey) {
- if (connection_->version().handshake_protocol != PROTOCOL_TLS1_3) {
- return;
- }
- ASSERT_FALSE(connection_->framer().HasEncrypterOfEncryptionLevel(
- ENCRYPTION_HANDSHAKE));
- EXPECT_FALSE(session_.OnNewDecryptionKeyAvailable(
- ENCRYPTION_HANDSHAKE, /*decrypter=*/nullptr,
- /*set_alternative_decrypter=*/false, /*latch_once_used=*/false));
-}
-
-TEST_P(QuicSessionTestServer, IncomingStreamWithServerInitiatedStreamId) {
- const QuicErrorCode expected_error =
- VersionHasIetfQuicFrames(transport_version())
- ? QUIC_HTTP_STREAM_WRONG_DIRECTION
- : QUIC_INVALID_STREAM_ID;
- EXPECT_CALL(
- *connection_,
- CloseConnection(expected_error, "Data for nonexistent stream",
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET));
-
- QuicStreamFrame frame(GetNthServerInitiatedBidirectionalId(1),
- /* fin = */ false, /* offset = */ 0,
- absl::string_view("foo"));
- session_.OnStreamFrame(frame);
-}
-
-// A client test class that can be used when the automatic configuration is not
-// desired.
-class QuicSessionTestClientUnconfigured : public QuicSessionTestBase {
- protected:
- QuicSessionTestClientUnconfigured()
- : QuicSessionTestBase(Perspective::IS_CLIENT,
- /*configure_session=*/false) {}
-};
-
-INSTANTIATE_TEST_SUITE_P(Tests,
- QuicSessionTestClientUnconfigured,
- ::testing::ValuesIn(AllSupportedVersions()),
- ::testing::PrintToStringParamName());
-
-TEST_P(QuicSessionTestClientUnconfigured, StreamInitiallyBlockedThenUnblocked) {
- if (!connection_->version().AllowsLowFlowControlLimits()) {
- return;
- }
- // Create a stream before negotiating the config and verify it starts off
- // blocked.
- QuicSessionPeer::SetMaxOpenOutgoingBidirectionalStreams(&session_, 10);
- TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
- EXPECT_TRUE(stream2->IsFlowControlBlocked());
- EXPECT_TRUE(session_.IsConnectionFlowControlBlocked());
- EXPECT_TRUE(session_.IsStreamFlowControlBlocked());
-
- // Negotiate the config with higher received limits.
- QuicConfigPeer::SetReceivedInitialMaxStreamDataBytesOutgoingBidirectional(
- session_.config(), kMinimumFlowControlSendWindow);
- QuicConfigPeer::SetReceivedInitialSessionFlowControlWindow(
- session_.config(), kMinimumFlowControlSendWindow);
- session_.OnConfigNegotiated();
-
- // Stream is now unblocked.
- EXPECT_FALSE(stream2->IsFlowControlBlocked());
- EXPECT_FALSE(session_.IsConnectionFlowControlBlocked());
- EXPECT_FALSE(session_.IsStreamFlowControlBlocked());
-}
-
-} // namespace
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_simple_buffer_allocator.cc b/chromium/net/third_party/quiche/src/quic/core/quic_simple_buffer_allocator.cc
deleted file mode 100644
index aba8c437f3e..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_simple_buffer_allocator.cc
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_simple_buffer_allocator.h"
-
-namespace quic {
-
-char* SimpleBufferAllocator::New(size_t size) {
- return new char[size];
-}
-
-char* SimpleBufferAllocator::New(size_t size, bool /* flag_enable */) {
- return New(size);
-}
-
-void SimpleBufferAllocator::Delete(char* buffer) {
- delete[] buffer;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_simple_buffer_allocator.h b/chromium/net/third_party/quiche/src/quic/core/quic_simple_buffer_allocator.h
deleted file mode 100644
index c2a800d5753..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_simple_buffer_allocator.h
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_SIMPLE_BUFFER_ALLOCATOR_H_
-#define QUICHE_QUIC_CORE_QUIC_SIMPLE_BUFFER_ALLOCATOR_H_
-
-#include "quic/core/quic_buffer_allocator.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-class QUIC_EXPORT_PRIVATE SimpleBufferAllocator : public QuicBufferAllocator {
- public:
- static SimpleBufferAllocator* Get() {
- static SimpleBufferAllocator* singleton = new SimpleBufferAllocator();
- return singleton;
- }
-
- char* New(size_t size) override;
- char* New(size_t size, bool flag_enable) override;
- void Delete(char* buffer) override;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_QUIC_SIMPLE_BUFFER_ALLOCATOR_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_simple_buffer_allocator_test.cc b/chromium/net/third_party/quiche/src/quic/core/quic_simple_buffer_allocator_test.cc
deleted file mode 100644
index 5416cd424ef..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_simple_buffer_allocator_test.cc
+++ /dev/null
@@ -1,66 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_simple_buffer_allocator.h"
-
-#include "quic/core/quic_packets.h"
-#include "quic/platform/api/quic_test.h"
-
-namespace quic {
-namespace {
-
-class SimpleBufferAllocatorTest : public QuicTest {};
-
-TEST_F(SimpleBufferAllocatorTest, NewDelete) {
- SimpleBufferAllocator alloc;
- char* buf = alloc.New(4);
- EXPECT_NE(nullptr, buf);
- alloc.Delete(buf);
-}
-
-TEST_F(SimpleBufferAllocatorTest, DeleteNull) {
- SimpleBufferAllocator alloc;
- alloc.Delete(nullptr);
-}
-
-TEST_F(SimpleBufferAllocatorTest, MoveBuffersConstructor) {
- SimpleBufferAllocator alloc;
- QuicBuffer buffer1(&alloc, 16);
-
- EXPECT_NE(buffer1.data(), nullptr);
- EXPECT_EQ(buffer1.size(), 16u);
-
- QuicBuffer buffer2(std::move(buffer1));
- EXPECT_EQ(buffer1.data(), nullptr); // NOLINT(bugprone-use-after-move)
- EXPECT_EQ(buffer1.size(), 0u);
- EXPECT_NE(buffer2.data(), nullptr);
- EXPECT_EQ(buffer2.size(), 16u);
-}
-
-TEST_F(SimpleBufferAllocatorTest, MoveBuffersAssignment) {
- SimpleBufferAllocator alloc;
- QuicBuffer buffer1(&alloc, 16);
- QuicBuffer buffer2;
-
- EXPECT_NE(buffer1.data(), nullptr);
- EXPECT_EQ(buffer1.size(), 16u);
- EXPECT_EQ(buffer2.data(), nullptr);
- EXPECT_EQ(buffer2.size(), 0u);
-
- buffer2 = std::move(buffer1);
- EXPECT_EQ(buffer1.data(), nullptr); // NOLINT(bugprone-use-after-move)
- EXPECT_EQ(buffer1.size(), 0u);
- EXPECT_NE(buffer2.data(), nullptr);
- EXPECT_EQ(buffer2.size(), 16u);
-}
-
-TEST_F(SimpleBufferAllocatorTest, CopyBuffer) {
- SimpleBufferAllocator alloc;
- const absl::string_view original = "Test string";
- QuicBuffer copy = QuicBuffer::Copy(&alloc, original);
- EXPECT_EQ(copy.AsStringView(), original);
-}
-
-} // namespace
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_socket_address_coder.cc b/chromium/net/third_party/quiche/src/quic/core/quic_socket_address_coder.cc
deleted file mode 100644
index 5eeb95d3bcb..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_socket_address_coder.cc
+++ /dev/null
@@ -1,90 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_socket_address_coder.h"
-
-#include <cstring>
-#include <string>
-#include <vector>
-
-namespace quic {
-
-namespace {
-
-// For convenience, the values of these constants match the values of AF_INET
-// and AF_INET6 on Linux.
-const uint16_t kIPv4 = 2;
-const uint16_t kIPv6 = 10;
-
-} // namespace
-
-QuicSocketAddressCoder::QuicSocketAddressCoder() {}
-
-QuicSocketAddressCoder::QuicSocketAddressCoder(const QuicSocketAddress& address)
- : address_(address) {}
-
-QuicSocketAddressCoder::~QuicSocketAddressCoder() {}
-
-std::string QuicSocketAddressCoder::Encode() const {
- std::string serialized;
- uint16_t address_family;
- switch (address_.host().address_family()) {
- case IpAddressFamily::IP_V4:
- address_family = kIPv4;
- break;
- case IpAddressFamily::IP_V6:
- address_family = kIPv6;
- break;
- default:
- return serialized;
- }
- serialized.append(reinterpret_cast<const char*>(&address_family),
- sizeof(address_family));
- serialized.append(address_.host().ToPackedString());
- uint16_t port = address_.port();
- serialized.append(reinterpret_cast<const char*>(&port), sizeof(port));
- return serialized;
-}
-
-bool QuicSocketAddressCoder::Decode(const char* data, size_t length) {
- uint16_t address_family;
- if (length < sizeof(address_family)) {
- return false;
- }
- memcpy(&address_family, data, sizeof(address_family));
- data += sizeof(address_family);
- length -= sizeof(address_family);
-
- size_t ip_length;
- switch (address_family) {
- case kIPv4:
- ip_length = QuicIpAddress::kIPv4AddressSize;
- break;
- case kIPv6:
- ip_length = QuicIpAddress::kIPv6AddressSize;
- break;
- default:
- return false;
- }
- if (length < ip_length) {
- return false;
- }
- std::vector<uint8_t> ip(ip_length);
- memcpy(&ip[0], data, ip_length);
- data += ip_length;
- length -= ip_length;
-
- uint16_t port;
- if (length != sizeof(port)) {
- return false;
- }
- memcpy(&port, data, length);
-
- QuicIpAddress ip_address;
- ip_address.FromPackedString(reinterpret_cast<const char*>(&ip[0]), ip_length);
- address_ = QuicSocketAddress(ip_address, port);
- return true;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_socket_address_coder.h b/chromium/net/third_party/quiche/src/quic/core/quic_socket_address_coder.h
deleted file mode 100644
index 468e6d88755..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_socket_address_coder.h
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_SOCKET_ADDRESS_CODER_H_
-#define QUICHE_QUIC_CORE_QUIC_SOCKET_ADDRESS_CODER_H_
-
-#include <cstdint>
-#include <string>
-
-#include "quic/platform/api/quic_export.h"
-#include "quic/platform/api/quic_socket_address.h"
-
-namespace quic {
-
-// Serializes and parses a socket address (IP address and port), to be used in
-// the kCADR tag in the ServerHello handshake message and the Public Reset
-// packet.
-class QUIC_EXPORT_PRIVATE QuicSocketAddressCoder {
- public:
- QuicSocketAddressCoder();
- explicit QuicSocketAddressCoder(const QuicSocketAddress& address);
- QuicSocketAddressCoder(const QuicSocketAddressCoder&) = delete;
- QuicSocketAddressCoder& operator=(const QuicSocketAddressCoder&) = delete;
- ~QuicSocketAddressCoder();
-
- std::string Encode() const;
-
- bool Decode(const char* data, size_t length);
-
- QuicIpAddress ip() const { return address_.host(); }
-
- uint16_t port() const { return address_.port(); }
-
- private:
- QuicSocketAddress address_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_QUIC_SOCKET_ADDRESS_CODER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_socket_address_coder_test.cc b/chromium/net/third_party/quiche/src/quic/core/quic_socket_address_coder_test.cc
deleted file mode 100644
index 0287cd37010..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_socket_address_coder_test.cc
+++ /dev/null
@@ -1,128 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_socket_address_coder.h"
-
-#include <string>
-
-#include "absl/base/macros.h"
-#include "quic/platform/api/quic_test.h"
-
-namespace quic {
-namespace test {
-
-class QuicSocketAddressCoderTest : public QuicTest {};
-
-TEST_F(QuicSocketAddressCoderTest, EncodeIPv4) {
- QuicIpAddress ip;
- ip.FromString("4.31.198.44");
- QuicSocketAddressCoder coder(QuicSocketAddress(ip, 0x1234));
- std::string serialized = coder.Encode();
- std::string expected("\x02\x00\x04\x1f\xc6\x2c\x34\x12", 8);
- EXPECT_EQ(expected, serialized);
-}
-
-TEST_F(QuicSocketAddressCoderTest, EncodeIPv6) {
- QuicIpAddress ip;
- ip.FromString("2001:700:300:1800::f");
- QuicSocketAddressCoder coder(QuicSocketAddress(ip, 0x5678));
- std::string serialized = coder.Encode();
- std::string expected(
- "\x0a\x00"
- "\x20\x01\x07\x00\x03\x00\x18\x00"
- "\x00\x00\x00\x00\x00\x00\x00\x0f"
- "\x78\x56",
- 20);
- EXPECT_EQ(expected, serialized);
-}
-
-TEST_F(QuicSocketAddressCoderTest, DecodeIPv4) {
- std::string serialized("\x02\x00\x04\x1f\xc6\x2c\x34\x12", 8);
- QuicSocketAddressCoder coder;
- ASSERT_TRUE(coder.Decode(serialized.data(), serialized.length()));
- EXPECT_EQ(IpAddressFamily::IP_V4, coder.ip().address_family());
- std::string expected_addr("\x04\x1f\xc6\x2c");
- EXPECT_EQ(expected_addr, coder.ip().ToPackedString());
- EXPECT_EQ(0x1234, coder.port());
-}
-
-TEST_F(QuicSocketAddressCoderTest, DecodeIPv6) {
- std::string serialized(
- "\x0a\x00"
- "\x20\x01\x07\x00\x03\x00\x18\x00"
- "\x00\x00\x00\x00\x00\x00\x00\x0f"
- "\x78\x56",
- 20);
- QuicSocketAddressCoder coder;
- ASSERT_TRUE(coder.Decode(serialized.data(), serialized.length()));
- EXPECT_EQ(IpAddressFamily::IP_V6, coder.ip().address_family());
- std::string expected_addr(
- "\x20\x01\x07\x00\x03\x00\x18\x00"
- "\x00\x00\x00\x00\x00\x00\x00\x0f",
- 16);
- EXPECT_EQ(expected_addr, coder.ip().ToPackedString());
- EXPECT_EQ(0x5678, coder.port());
-}
-
-TEST_F(QuicSocketAddressCoderTest, DecodeBad) {
- std::string serialized(
- "\x0a\x00"
- "\x20\x01\x07\x00\x03\x00\x18\x00"
- "\x00\x00\x00\x00\x00\x00\x00\x0f"
- "\x78\x56",
- 20);
- QuicSocketAddressCoder coder;
- EXPECT_TRUE(coder.Decode(serialized.data(), serialized.length()));
- // Append junk.
- serialized.push_back('\0');
- EXPECT_FALSE(coder.Decode(serialized.data(), serialized.length()));
- // Undo.
- serialized.resize(20);
- EXPECT_TRUE(coder.Decode(serialized.data(), serialized.length()));
-
- // Set an unknown address family.
- serialized[0] = '\x03';
- EXPECT_FALSE(coder.Decode(serialized.data(), serialized.length()));
- // Undo.
- serialized[0] = '\x0a';
- EXPECT_TRUE(coder.Decode(serialized.data(), serialized.length()));
-
- // Truncate.
- size_t len = serialized.length();
- for (size_t i = 0; i < len; i++) {
- ASSERT_FALSE(serialized.empty());
- serialized.erase(serialized.length() - 1);
- EXPECT_FALSE(coder.Decode(serialized.data(), serialized.length()));
- }
- EXPECT_TRUE(serialized.empty());
-}
-
-TEST_F(QuicSocketAddressCoderTest, EncodeAndDecode) {
- struct {
- const char* ip_literal;
- uint16_t port;
- } test_case[] = {
- {"93.184.216.119", 0x1234},
- {"199.204.44.194", 80},
- {"149.20.4.69", 443},
- {"127.0.0.1", 8080},
- {"2001:700:300:1800::", 0x5678},
- {"::1", 65534},
- };
-
- for (size_t i = 0; i < ABSL_ARRAYSIZE(test_case); i++) {
- QuicIpAddress ip;
- ASSERT_TRUE(ip.FromString(test_case[i].ip_literal));
- QuicSocketAddressCoder encoder(QuicSocketAddress(ip, test_case[i].port));
- std::string serialized = encoder.Encode();
-
- QuicSocketAddressCoder decoder;
- ASSERT_TRUE(decoder.Decode(serialized.data(), serialized.length()));
- EXPECT_EQ(encoder.ip(), decoder.ip());
- EXPECT_EQ(encoder.port(), decoder.port());
- }
-}
-
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_stream.cc b/chromium/net/third_party/quiche/src/quic/core/quic_stream.cc
deleted file mode 100644
index 6237dae2f62..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_stream.cc
+++ /dev/null
@@ -1,1457 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_stream.h"
-
-#include <limits>
-#include <string>
-
-#include "absl/strings/str_cat.h"
-#include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
-#include "quic/core/quic_error_codes.h"
-#include "quic/core/quic_flow_controller.h"
-#include "quic/core/quic_session.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_utils.h"
-#include "quic/core/quic_versions.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_flag_utils.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/platform/api/quic_mem_slice.h"
-#include "common/platform/api/quiche_logging.h"
-
-using spdy::SpdyPriority;
-
-namespace quic {
-
-#define ENDPOINT \
- (perspective_ == Perspective::IS_SERVER ? "Server: " : "Client: ")
-
-namespace {
-
-QuicByteCount DefaultFlowControlWindow(ParsedQuicVersion version) {
- if (!version.AllowsLowFlowControlLimits()) {
- return kDefaultFlowControlSendWindow;
- }
- return 0;
-}
-
-QuicByteCount GetInitialStreamFlowControlWindowToSend(QuicSession* session,
- QuicStreamId stream_id) {
- ParsedQuicVersion version = session->connection()->version();
- if (version.handshake_protocol != PROTOCOL_TLS1_3) {
- return session->config()->GetInitialStreamFlowControlWindowToSend();
- }
-
- // Unidirectional streams (v99 only).
- if (VersionHasIetfQuicFrames(version.transport_version) &&
- !QuicUtils::IsBidirectionalStreamId(stream_id, version)) {
- return session->config()
- ->GetInitialMaxStreamDataBytesUnidirectionalToSend();
- }
-
- if (QuicUtils::IsOutgoingStreamId(version, stream_id,
- session->perspective())) {
- return session->config()
- ->GetInitialMaxStreamDataBytesOutgoingBidirectionalToSend();
- }
-
- return session->config()
- ->GetInitialMaxStreamDataBytesIncomingBidirectionalToSend();
-}
-
-QuicByteCount GetReceivedFlowControlWindow(QuicSession* session,
- QuicStreamId stream_id) {
- ParsedQuicVersion version = session->connection()->version();
- if (version.handshake_protocol != PROTOCOL_TLS1_3) {
- if (session->config()->HasReceivedInitialStreamFlowControlWindowBytes()) {
- return session->config()->ReceivedInitialStreamFlowControlWindowBytes();
- }
-
- return DefaultFlowControlWindow(version);
- }
-
- // Unidirectional streams (v99 only).
- if (VersionHasIetfQuicFrames(version.transport_version) &&
- !QuicUtils::IsBidirectionalStreamId(stream_id, version)) {
- if (session->config()
- ->HasReceivedInitialMaxStreamDataBytesUnidirectional()) {
- return session->config()
- ->ReceivedInitialMaxStreamDataBytesUnidirectional();
- }
-
- return DefaultFlowControlWindow(version);
- }
-
- if (QuicUtils::IsOutgoingStreamId(version, stream_id,
- session->perspective())) {
- if (session->config()
- ->HasReceivedInitialMaxStreamDataBytesOutgoingBidirectional()) {
- return session->config()
- ->ReceivedInitialMaxStreamDataBytesOutgoingBidirectional();
- }
-
- return DefaultFlowControlWindow(version);
- }
-
- if (session->config()
- ->HasReceivedInitialMaxStreamDataBytesIncomingBidirectional()) {
- return session->config()
- ->ReceivedInitialMaxStreamDataBytesIncomingBidirectional();
- }
-
- return DefaultFlowControlWindow(version);
-}
-
-} // namespace
-
-// static
-const SpdyPriority QuicStream::kDefaultPriority;
-
-// static
-const int QuicStream::kDefaultUrgency;
-
-PendingStream::PendingStream(QuicStreamId id, QuicSession* session)
- : id_(id),
- version_(session->version()),
- stream_delegate_(session),
- stream_bytes_read_(0),
- fin_received_(false),
- is_bidirectional_(QuicUtils::GetStreamType(id, session->perspective(),
- /*peer_initiated = */ true,
- session->version()) ==
- BIDIRECTIONAL),
- connection_flow_controller_(session->flow_controller()),
- flow_controller_(session, id,
- /*is_connection_flow_controller*/ false,
- GetReceivedFlowControlWindow(session, id),
- GetInitialStreamFlowControlWindowToSend(session, id),
- kStreamReceiveWindowLimit,
- session->flow_controller()->auto_tune_receive_window(),
- session->flow_controller()),
- sequencer_(this) {}
-
-void PendingStream::OnDataAvailable() {
- // Data should be kept in the sequencer so that
- // QuicSession::ProcessPendingStream() can read it.
-}
-
-void PendingStream::OnFinRead() { QUICHE_DCHECK(sequencer_.IsClosed()); }
-
-void PendingStream::AddBytesConsumed(QuicByteCount bytes) {
- // It will be called when the metadata of the stream is consumed.
- flow_controller_.AddBytesConsumed(bytes);
- connection_flow_controller_->AddBytesConsumed(bytes);
-}
-
-void PendingStream::ResetWithError(QuicResetStreamError /*error*/) {
- // Currently PendingStream is only read-unidirectional. It shouldn't send
- // Reset.
- QUIC_NOTREACHED();
-}
-
-void PendingStream::OnUnrecoverableError(QuicErrorCode error,
- const std::string& details) {
- stream_delegate_->OnStreamError(error, details);
-}
-
-void PendingStream::OnUnrecoverableError(QuicErrorCode error,
- QuicIetfTransportErrorCodes ietf_error,
- const std::string& details) {
- stream_delegate_->OnStreamError(error, ietf_error, details);
-}
-
-QuicStreamId PendingStream::id() const { return id_; }
-
-ParsedQuicVersion PendingStream::version() const { return version_; }
-
-void PendingStream::OnStreamFrame(const QuicStreamFrame& frame) {
- QUICHE_DCHECK_EQ(frame.stream_id, id_);
-
- bool is_stream_too_long =
- (frame.offset > kMaxStreamLength) ||
- (kMaxStreamLength - frame.offset < frame.data_length);
- if (is_stream_too_long) {
- // Close connection if stream becomes too long.
- QUIC_PEER_BUG(quic_peer_bug_12570_1)
- << "Receive stream frame reaches max stream length. frame offset "
- << frame.offset << " length " << frame.data_length;
- OnUnrecoverableError(QUIC_STREAM_LENGTH_OVERFLOW,
- "Peer sends more data than allowed on this stream.");
- return;
- }
-
- if (frame.offset + frame.data_length > sequencer_.close_offset()) {
- OnUnrecoverableError(
- QUIC_STREAM_DATA_BEYOND_CLOSE_OFFSET,
- absl::StrCat(
- "Stream ", id_,
- " received data with offset: ", frame.offset + frame.data_length,
- ", which is beyond close offset: ", sequencer()->close_offset()));
- return;
- }
-
- if (frame.fin) {
- fin_received_ = true;
- }
-
- // This count includes duplicate data received.
- QuicByteCount frame_payload_size = frame.data_length;
- stream_bytes_read_ += frame_payload_size;
-
- // Flow control is interested in tracking highest received offset.
- // Only interested in received frames that carry data.
- if (frame_payload_size > 0 &&
- MaybeIncreaseHighestReceivedOffset(frame.offset + frame_payload_size)) {
- // As the highest received offset has changed, check to see if this is a
- // violation of flow control.
- if (flow_controller_.FlowControlViolation() ||
- connection_flow_controller_->FlowControlViolation()) {
- OnUnrecoverableError(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA,
- "Flow control violation after increasing offset");
- return;
- }
- }
-
- sequencer_.OnStreamFrame(frame);
-}
-
-void PendingStream::OnRstStreamFrame(const QuicRstStreamFrame& frame) {
- QUICHE_DCHECK_EQ(frame.stream_id, id_);
-
- if (frame.byte_offset > kMaxStreamLength) {
- // Peer are not suppose to write bytes more than maxium allowed.
- OnUnrecoverableError(QUIC_STREAM_LENGTH_OVERFLOW,
- "Reset frame stream offset overflow.");
- return;
- }
-
- const QuicStreamOffset kMaxOffset =
- std::numeric_limits<QuicStreamOffset>::max();
- if (sequencer()->close_offset() != kMaxOffset &&
- frame.byte_offset != sequencer()->close_offset()) {
- OnUnrecoverableError(
- QUIC_STREAM_MULTIPLE_OFFSET,
- absl::StrCat("Stream ", id_,
- " received new final offset: ", frame.byte_offset,
- ", which is different from close offset: ",
- sequencer()->close_offset()));
- return;
- }
-
- MaybeIncreaseHighestReceivedOffset(frame.byte_offset);
- if (flow_controller_.FlowControlViolation() ||
- connection_flow_controller_->FlowControlViolation()) {
- OnUnrecoverableError(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA,
- "Flow control violation after increasing offset");
- return;
- }
-}
-
-void PendingStream::OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame) {
- QUICHE_DCHECK(is_bidirectional_);
- flow_controller_.UpdateSendWindowOffset(frame.max_data);
-}
-
-bool PendingStream::MaybeIncreaseHighestReceivedOffset(
- QuicStreamOffset new_offset) {
- uint64_t increment =
- new_offset - flow_controller_.highest_received_byte_offset();
- if (!flow_controller_.UpdateHighestReceivedOffset(new_offset)) {
- return false;
- }
-
- // If |new_offset| increased the stream flow controller's highest received
- // offset, increase the connection flow controller's value by the incremental
- // difference.
- connection_flow_controller_->UpdateHighestReceivedOffset(
- connection_flow_controller_->highest_received_byte_offset() + increment);
- return true;
-}
-
-void PendingStream::OnStopSending(
- QuicResetStreamError stop_sending_error_code) {
- if (!stop_sending_error_code_) {
- stop_sending_error_code_ = stop_sending_error_code;
- }
-}
-
-void PendingStream::MarkConsumed(QuicByteCount num_bytes) {
- sequencer_.MarkConsumed(num_bytes);
-}
-
-void PendingStream::StopReading() {
- QUIC_DVLOG(1) << "Stop reading from pending stream " << id();
- sequencer_.StopReading();
-}
-
-QuicStream::QuicStream(PendingStream* pending, QuicSession* session,
- bool is_static)
- : QuicStream(pending->id_, session, std::move(pending->sequencer_),
- is_static,
- QuicUtils::GetStreamType(pending->id_, session->perspective(),
- /*peer_initiated = */ true,
- session->version()),
- pending->stream_bytes_read_, pending->fin_received_,
- std::move(pending->flow_controller_),
- pending->connection_flow_controller_) {
- QUICHE_DCHECK(session->version().HasIetfQuicFrames());
- sequencer_.set_stream(this);
-}
-
-namespace {
-
-absl::optional<QuicFlowController> FlowController(QuicStreamId id,
- QuicSession* session,
- StreamType type) {
- if (type == CRYPTO) {
- // The only QuicStream with a StreamType of CRYPTO is QuicCryptoStream, when
- // it is using crypto frames instead of stream frames. The QuicCryptoStream
- // doesn't have any flow control in that case, so we don't create a
- // QuicFlowController for it.
- return absl::nullopt;
- }
- return QuicFlowController(
- session, id,
- /*is_connection_flow_controller*/ false,
- GetReceivedFlowControlWindow(session, id),
- GetInitialStreamFlowControlWindowToSend(session, id),
- kStreamReceiveWindowLimit,
- session->flow_controller()->auto_tune_receive_window(),
- session->flow_controller());
-}
-
-} // namespace
-
-QuicStream::QuicStream(QuicStreamId id, QuicSession* session, bool is_static,
- StreamType type)
- : QuicStream(id, session, QuicStreamSequencer(this), is_static, type, 0,
- false, FlowController(id, session, type),
- session->flow_controller()) {}
-
-QuicStream::QuicStream(QuicStreamId id, QuicSession* session,
- QuicStreamSequencer sequencer, bool is_static,
- StreamType type, uint64_t stream_bytes_read,
- bool fin_received,
- absl::optional<QuicFlowController> flow_controller,
- QuicFlowController* connection_flow_controller)
- : sequencer_(std::move(sequencer)),
- id_(id),
- session_(session),
- stream_delegate_(session),
- precedence_(CalculateDefaultPriority(session)),
- stream_bytes_read_(stream_bytes_read),
- stream_error_(QuicResetStreamError::NoError()),
- connection_error_(QUIC_NO_ERROR),
- read_side_closed_(false),
- write_side_closed_(false),
- write_side_data_recvd_state_notified_(false),
- fin_buffered_(false),
- fin_sent_(false),
- fin_outstanding_(false),
- fin_lost_(false),
- fin_received_(fin_received),
- rst_sent_(false),
- rst_received_(false),
- stop_sending_sent_(false),
- flow_controller_(std::move(flow_controller)),
- connection_flow_controller_(connection_flow_controller),
- stream_contributes_to_connection_flow_control_(true),
- busy_counter_(0),
- add_random_padding_after_fin_(false),
- send_buffer_(
- session->connection()->helper()->GetStreamSendBufferAllocator()),
- buffered_data_threshold_(GetQuicFlag(FLAGS_quic_buffered_data_threshold)),
- is_static_(is_static),
- deadline_(QuicTime::Zero()),
- was_draining_(false),
- type_(VersionHasIetfQuicFrames(session->transport_version()) &&
- type != CRYPTO
- ? QuicUtils::GetStreamType(id_, session->perspective(),
- session->IsIncomingStream(id_),
- session->version())
- : type),
- creation_time_(session->connection()->clock()->ApproximateNow()),
- perspective_(session->perspective()) {
- if (type_ == WRITE_UNIDIRECTIONAL) {
- fin_received_ = true;
- CloseReadSide();
- } else if (type_ == READ_UNIDIRECTIONAL) {
- fin_sent_ = true;
- CloseWriteSide();
- }
- if (type_ != CRYPTO) {
- stream_delegate_->RegisterStreamPriority(id, is_static_, precedence_);
- }
-}
-
-QuicStream::~QuicStream() {
- if (session_ != nullptr && IsWaitingForAcks()) {
- QUIC_DVLOG(1)
- << ENDPOINT << "Stream " << id_
- << " gets destroyed while waiting for acks. stream_bytes_outstanding = "
- << send_buffer_.stream_bytes_outstanding()
- << ", fin_outstanding: " << fin_outstanding_;
- }
- if (stream_delegate_ != nullptr && type_ != CRYPTO) {
- stream_delegate_->UnregisterStreamPriority(id(), is_static_);
- }
-}
-
-void QuicStream::OnStreamFrame(const QuicStreamFrame& frame) {
- QUICHE_DCHECK_EQ(frame.stream_id, id_);
-
- QUICHE_DCHECK(!(read_side_closed_ && write_side_closed_));
-
- if (frame.fin && is_static_) {
- OnUnrecoverableError(QUIC_INVALID_STREAM_ID,
- "Attempt to close a static stream");
- return;
- }
-
- if (type_ == WRITE_UNIDIRECTIONAL) {
- OnUnrecoverableError(QUIC_DATA_RECEIVED_ON_WRITE_UNIDIRECTIONAL_STREAM,
- "Data received on write unidirectional stream");
- return;
- }
-
- bool is_stream_too_long =
- (frame.offset > kMaxStreamLength) ||
- (kMaxStreamLength - frame.offset < frame.data_length);
- if (is_stream_too_long) {
- // Close connection if stream becomes too long.
- QUIC_PEER_BUG(quic_peer_bug_10586_1)
- << "Receive stream frame on stream " << id_
- << " reaches max stream length. frame offset " << frame.offset
- << " length " << frame.data_length << ". " << sequencer_.DebugString();
- OnUnrecoverableError(
- QUIC_STREAM_LENGTH_OVERFLOW,
- absl::StrCat("Peer sends more data than allowed on stream ", id_,
- ". frame: offset = ", frame.offset, ", length = ",
- frame.data_length, ". ", sequencer_.DebugString()));
- return;
- }
-
- if (frame.offset + frame.data_length > sequencer_.close_offset()) {
- OnUnrecoverableError(
- QUIC_STREAM_DATA_BEYOND_CLOSE_OFFSET,
- absl::StrCat(
- "Stream ", id_,
- " received data with offset: ", frame.offset + frame.data_length,
- ", which is beyond close offset: ", sequencer_.close_offset()));
- return;
- }
-
- if (frame.fin && !fin_received_) {
- fin_received_ = true;
- if (fin_sent_) {
- QUICHE_DCHECK(!was_draining_);
- session_->StreamDraining(id_,
- /*unidirectional=*/type_ != BIDIRECTIONAL);
- was_draining_ = true;
- }
- }
-
- if (read_side_closed_) {
- QUIC_DLOG(INFO)
- << ENDPOINT << "Stream " << frame.stream_id
- << " is closed for reading. Ignoring newly received stream data.";
- // The subclass does not want to read data: blackhole the data.
- return;
- }
-
- // This count includes duplicate data received.
- QuicByteCount frame_payload_size = frame.data_length;
- stream_bytes_read_ += frame_payload_size;
-
- // Flow control is interested in tracking highest received offset.
- // Only interested in received frames that carry data.
- if (frame_payload_size > 0 &&
- MaybeIncreaseHighestReceivedOffset(frame.offset + frame_payload_size)) {
- // As the highest received offset has changed, check to see if this is a
- // violation of flow control.
- QUIC_BUG_IF(quic_bug_12570_2, !flow_controller_.has_value())
- << ENDPOINT << "OnStreamFrame called on stream without flow control";
- if ((flow_controller_.has_value() &&
- flow_controller_->FlowControlViolation()) ||
- connection_flow_controller_->FlowControlViolation()) {
- OnUnrecoverableError(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA,
- "Flow control violation after increasing offset");
- return;
- }
- }
-
- sequencer_.OnStreamFrame(frame);
-}
-
-bool QuicStream::OnStopSending(QuicResetStreamError error) {
- // Do not reset the stream if all data has been sent and acknowledged.
- if (write_side_closed() && !IsWaitingForAcks()) {
- QUIC_DVLOG(1) << ENDPOINT
- << "Ignoring STOP_SENDING for a write closed stream, id: "
- << id_;
- return false;
- }
-
- if (is_static_) {
- QUIC_DVLOG(1) << ENDPOINT
- << "Received STOP_SENDING for a static stream, id: " << id_
- << " Closing connection";
- OnUnrecoverableError(QUIC_INVALID_STREAM_ID,
- "Received STOP_SENDING for a static stream");
- return false;
- }
-
- stream_error_ = error;
- MaybeSendRstStream(error);
- return true;
-}
-
-int QuicStream::num_frames_received() const {
- return sequencer_.num_frames_received();
-}
-
-int QuicStream::num_duplicate_frames_received() const {
- return sequencer_.num_duplicate_frames_received();
-}
-
-void QuicStream::OnStreamReset(const QuicRstStreamFrame& frame) {
- rst_received_ = true;
- if (frame.byte_offset > kMaxStreamLength) {
- // Peer are not suppose to write bytes more than maxium allowed.
- OnUnrecoverableError(QUIC_STREAM_LENGTH_OVERFLOW,
- "Reset frame stream offset overflow.");
- return;
- }
-
- const QuicStreamOffset kMaxOffset =
- std::numeric_limits<QuicStreamOffset>::max();
- if (sequencer()->close_offset() != kMaxOffset &&
- frame.byte_offset != sequencer()->close_offset()) {
- OnUnrecoverableError(
- QUIC_STREAM_MULTIPLE_OFFSET,
- absl::StrCat("Stream ", id_,
- " received new final offset: ", frame.byte_offset,
- ", which is different from close offset: ",
- sequencer_.close_offset()));
- return;
- }
-
- MaybeIncreaseHighestReceivedOffset(frame.byte_offset);
- QUIC_BUG_IF(quic_bug_12570_3, !flow_controller_.has_value())
- << ENDPOINT << "OnStreamReset called on stream without flow control";
- if ((flow_controller_.has_value() &&
- flow_controller_->FlowControlViolation()) ||
- connection_flow_controller_->FlowControlViolation()) {
- OnUnrecoverableError(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA,
- "Flow control violation after increasing offset");
- return;
- }
-
- stream_error_ = frame.error();
- // Google QUIC closes both sides of the stream in response to a
- // RESET_STREAM, IETF QUIC closes only the read side.
- if (!VersionHasIetfQuicFrames(transport_version())) {
- CloseWriteSide();
- }
- CloseReadSide();
-}
-
-void QuicStream::OnConnectionClosed(QuicErrorCode error,
- ConnectionCloseSource /*source*/) {
- if (read_side_closed_ && write_side_closed_) {
- return;
- }
- if (error != QUIC_NO_ERROR) {
- stream_error_ =
- QuicResetStreamError::FromInternal(QUIC_STREAM_CONNECTION_ERROR);
- connection_error_ = error;
- }
-
- CloseWriteSide();
- CloseReadSide();
-}
-
-void QuicStream::OnFinRead() {
- QUICHE_DCHECK(sequencer_.IsClosed());
- // OnFinRead can be called due to a FIN flag in a headers block, so there may
- // have been no OnStreamFrame call with a FIN in the frame.
- fin_received_ = true;
- // If fin_sent_ is true, then CloseWriteSide has already been called, and the
- // stream will be destroyed by CloseReadSide, so don't need to call
- // StreamDraining.
- CloseReadSide();
-}
-
-void QuicStream::SetFinSent() {
- QUICHE_DCHECK(!VersionUsesHttp3(transport_version()));
- fin_sent_ = true;
-}
-
-void QuicStream::Reset(QuicRstStreamErrorCode error) {
- ResetWithError(QuicResetStreamError::FromInternal(error));
-}
-
-void QuicStream::ResetWithError(QuicResetStreamError error) {
- stream_error_ = error;
- QuicConnection::ScopedPacketFlusher flusher(session()->connection());
- MaybeSendStopSending(error);
- MaybeSendRstStream(error);
-
- if (read_side_closed_ && write_side_closed_ && !IsWaitingForAcks()) {
- session()->MaybeCloseZombieStream(id_);
- }
-}
-
-void QuicStream::ResetWriteSide(QuicResetStreamError error) {
- stream_error_ = error;
- MaybeSendRstStream(error);
-
- if (read_side_closed_ && write_side_closed_ && !IsWaitingForAcks()) {
- session()->MaybeCloseZombieStream(id_);
- }
-}
-
-void QuicStream::SendStopSending(QuicResetStreamError error) {
- stream_error_ = error;
- MaybeSendStopSending(error);
-
- if (read_side_closed_ && write_side_closed_ && !IsWaitingForAcks()) {
- session()->MaybeCloseZombieStream(id_);
- }
-}
-
-void QuicStream::OnUnrecoverableError(QuicErrorCode error,
- const std::string& details) {
- stream_delegate_->OnStreamError(error, details);
-}
-
-void QuicStream::OnUnrecoverableError(QuicErrorCode error,
- QuicIetfTransportErrorCodes ietf_error,
- const std::string& details) {
- stream_delegate_->OnStreamError(error, ietf_error, details);
-}
-
-const spdy::SpdyStreamPrecedence& QuicStream::precedence() const {
- return precedence_;
-}
-
-void QuicStream::SetPriority(const spdy::SpdyStreamPrecedence& precedence) {
- precedence_ = precedence;
-
- MaybeSendPriorityUpdateFrame();
-
- stream_delegate_->UpdateStreamPriority(id(), precedence);
-}
-
-void QuicStream::WriteOrBufferData(
- absl::string_view data, bool fin,
- QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener) {
- QUIC_BUG_IF(quic_bug_12570_4,
- QuicUtils::IsCryptoStreamId(transport_version(), id_))
- << ENDPOINT
- << "WriteOrBufferData is used to send application data, use "
- "WriteOrBufferDataAtLevel to send crypto data.";
- return WriteOrBufferDataAtLevel(
- data, fin, session()->GetEncryptionLevelToSendApplicationData(),
- ack_listener);
-}
-
-void QuicStream::WriteOrBufferDataAtLevel(
- absl::string_view data, bool fin, EncryptionLevel level,
- QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener) {
- if (data.empty() && !fin) {
- QUIC_BUG(quic_bug_10586_2) << "data.empty() && !fin";
- return;
- }
-
- if (fin_buffered_) {
- QUIC_BUG(quic_bug_10586_3) << "Fin already buffered";
- return;
- }
- if (write_side_closed_) {
- QUIC_DLOG(ERROR) << ENDPOINT
- << "Attempt to write when the write side is closed";
- if (type_ == READ_UNIDIRECTIONAL) {
- OnUnrecoverableError(QUIC_TRY_TO_WRITE_DATA_ON_READ_UNIDIRECTIONAL_STREAM,
- "Try to send data on read unidirectional stream");
- }
- return;
- }
-
- fin_buffered_ = fin;
-
- bool had_buffered_data = HasBufferedData();
- // Do not respect buffered data upper limit as WriteOrBufferData guarantees
- // all data to be consumed.
- if (data.length() > 0) {
- struct iovec iov(QuicUtils::MakeIovec(data));
- QuicStreamOffset offset = send_buffer_.stream_offset();
- if (kMaxStreamLength - offset < data.length()) {
- QUIC_BUG(quic_bug_10586_4) << "Write too many data via stream " << id_;
- OnUnrecoverableError(
- QUIC_STREAM_LENGTH_OVERFLOW,
- absl::StrCat("Write too many data via stream ", id_));
- return;
- }
- send_buffer_.SaveStreamData(&iov, 1, 0, data.length());
- OnDataBuffered(offset, data.length(), ack_listener);
- }
- if (!had_buffered_data && (HasBufferedData() || fin_buffered_)) {
- // Write data if there is no buffered data before.
- WriteBufferedData(level);
- }
-}
-
-void QuicStream::OnCanWrite() {
- if (HasDeadlinePassed()) {
- OnDeadlinePassed();
- return;
- }
- if (HasPendingRetransmission()) {
- WritePendingRetransmission();
- // Exit early to allow other streams to write pending retransmissions if
- // any.
- return;
- }
-
- if (write_side_closed_) {
- QUIC_DLOG(ERROR)
- << ENDPOINT << "Stream " << id()
- << " attempting to write new data when the write side is closed";
- return;
- }
- if (HasBufferedData() || (fin_buffered_ && !fin_sent_)) {
- WriteBufferedData(session()->GetEncryptionLevelToSendApplicationData());
- }
- if (!fin_buffered_ && !fin_sent_ && CanWriteNewData()) {
- // Notify upper layer to write new data when buffered data size is below
- // low water mark.
- OnCanWriteNewData();
- }
-}
-
-void QuicStream::MaybeSendBlocked() {
- if (!flow_controller_.has_value()) {
- QUIC_BUG(quic_bug_10586_5)
- << ENDPOINT << "MaybeSendBlocked called on stream without flow control";
- return;
- }
- if (flow_controller_->ShouldSendBlocked()) {
- session_->SendBlocked(id_);
- }
- if (!stream_contributes_to_connection_flow_control_) {
- return;
- }
- if (connection_flow_controller_->ShouldSendBlocked()) {
- session_->SendBlocked(QuicUtils::GetInvalidStreamId(transport_version()));
- }
- // 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
- // WINDOW_UPDATE arrives.
- if (connection_flow_controller_->IsBlocked() &&
- !flow_controller_->IsBlocked()) {
- session_->MarkConnectionLevelWriteBlocked(id());
- }
-}
-
-QuicConsumedData QuicStream::WriteMemSlice(QuicMemSlice span, bool fin) {
- return WriteMemSlices(absl::MakeSpan(&span, 1), fin);
-}
-
-QuicConsumedData QuicStream::WriteMemSlices(absl::Span<QuicMemSlice> span,
- bool fin) {
- QuicConsumedData consumed_data(0, false);
- if (span.empty() && !fin) {
- QUIC_BUG(quic_bug_10586_6) << "span.empty() && !fin";
- return consumed_data;
- }
-
- if (fin_buffered_) {
- QUIC_BUG(quic_bug_10586_7) << "Fin already buffered";
- return consumed_data;
- }
-
- if (write_side_closed_) {
- QUIC_DLOG(ERROR) << ENDPOINT << "Stream " << id()
- << " attempting to write when the write side is closed";
- if (type_ == READ_UNIDIRECTIONAL) {
- OnUnrecoverableError(QUIC_TRY_TO_WRITE_DATA_ON_READ_UNIDIRECTIONAL_STREAM,
- "Try to send data on read unidirectional stream");
- }
- return consumed_data;
- }
-
- bool had_buffered_data = HasBufferedData();
- if (CanWriteNewData() || span.empty()) {
- consumed_data.fin_consumed = fin;
- if (!span.empty()) {
- // Buffer all data if buffered data size is below limit.
- QuicStreamOffset offset = send_buffer_.stream_offset();
- consumed_data.bytes_consumed = send_buffer_.SaveMemSliceSpan(span);
- if (offset > send_buffer_.stream_offset() ||
- kMaxStreamLength < send_buffer_.stream_offset()) {
- QUIC_BUG(quic_bug_10586_8) << "Write too many data via stream " << id_;
- OnUnrecoverableError(
- QUIC_STREAM_LENGTH_OVERFLOW,
- absl::StrCat("Write too many data via stream ", id_));
- return consumed_data;
- }
- OnDataBuffered(offset, consumed_data.bytes_consumed, nullptr);
- }
- }
- fin_buffered_ = consumed_data.fin_consumed;
-
- if (!had_buffered_data && (HasBufferedData() || fin_buffered_)) {
- // Write data if there is no buffered data before.
- WriteBufferedData(session()->GetEncryptionLevelToSendApplicationData());
- }
-
- return consumed_data;
-}
-
-bool QuicStream::HasPendingRetransmission() const {
- return send_buffer_.HasPendingRetransmission() || fin_lost_;
-}
-
-bool QuicStream::IsStreamFrameOutstanding(QuicStreamOffset offset,
- QuicByteCount data_length,
- bool fin) const {
- return send_buffer_.IsStreamDataOutstanding(offset, data_length) ||
- (fin && fin_outstanding_);
-}
-
-void QuicStream::CloseReadSide() {
- if (read_side_closed_) {
- return;
- }
- QUIC_DVLOG(1) << ENDPOINT << "Done reading from stream " << id();
-
- read_side_closed_ = true;
- sequencer_.ReleaseBuffer();
-
- if (write_side_closed_) {
- QUIC_DVLOG(1) << ENDPOINT << "Closing stream " << id();
- session_->OnStreamClosed(id());
- OnClose();
- }
-}
-
-void QuicStream::CloseWriteSide() {
- if (write_side_closed_) {
- return;
- }
- QUIC_DVLOG(1) << ENDPOINT << "Done writing to stream " << id();
-
- write_side_closed_ = true;
- if (read_side_closed_) {
- QUIC_DVLOG(1) << ENDPOINT << "Closing stream " << id();
- session_->OnStreamClosed(id());
- OnClose();
- }
-}
-
-void QuicStream::MaybeSendStopSending(QuicResetStreamError error) {
- if (stop_sending_sent_) {
- return;
- }
-
- if (!session()->version().UsesHttp3() && !error.ok()) {
- // In gQUIC, RST with error closes both read and write side.
- return;
- }
-
- if (session()->version().UsesHttp3()) {
- session()->MaybeSendStopSendingFrame(id(), error);
- } else {
- QUICHE_DCHECK_EQ(QUIC_STREAM_NO_ERROR, error.internal_code());
- session()->MaybeSendRstStreamFrame(id(), QuicResetStreamError::NoError(),
- stream_bytes_written());
- }
- stop_sending_sent_ = true;
- CloseReadSide();
-}
-
-void QuicStream::MaybeSendRstStream(QuicResetStreamError error) {
- if (rst_sent_) {
- return;
- }
-
- if (!session()->version().UsesHttp3()) {
- QUIC_BUG_IF(quic_bug_12570_5, error.ok());
- stop_sending_sent_ = true;
- CloseReadSide();
- }
- session()->MaybeSendRstStreamFrame(id(), error, stream_bytes_written());
- rst_sent_ = true;
- CloseWriteSide();
-}
-
-bool QuicStream::HasBufferedData() const {
- QUICHE_DCHECK_GE(send_buffer_.stream_offset(), stream_bytes_written());
- return send_buffer_.stream_offset() > stream_bytes_written();
-}
-
-ParsedQuicVersion QuicStream::version() const { return session_->version(); }
-
-QuicTransportVersion QuicStream::transport_version() const {
- return session_->transport_version();
-}
-
-HandshakeProtocol QuicStream::handshake_protocol() const {
- return session_->connection()->version().handshake_protocol;
-}
-
-void QuicStream::StopReading() {
- QUIC_DVLOG(1) << ENDPOINT << "Stop reading from stream " << id();
- sequencer_.StopReading();
-}
-
-void QuicStream::OnClose() {
- QUICHE_DCHECK(read_side_closed_ && write_side_closed_);
-
- if (!fin_sent_ && !rst_sent_) {
- QUIC_BUG_IF(quic_bug_12570_6, session()->connection()->connected() &&
- session()->version().UsesHttp3())
- << "The stream should've already sent RST in response to "
- "STOP_SENDING";
- // For flow control accounting, tell the peer how many bytes have been
- // written on this stream before termination. Done here if needed, using a
- // RST_STREAM frame.
- MaybeSendRstStream(QUIC_RST_ACKNOWLEDGEMENT);
- session_->MaybeCloseZombieStream(id_);
- }
-
- if (!flow_controller_.has_value() ||
- flow_controller_->FlowControlViolation() ||
- connection_flow_controller_->FlowControlViolation()) {
- return;
- }
- // The stream is being closed and will not process any further incoming bytes.
- // As there may be more bytes in flight, to ensure that both endpoints have
- // the same connection level flow control state, mark all unreceived or
- // buffered bytes as consumed.
- QuicByteCount bytes_to_consume =
- flow_controller_->highest_received_byte_offset() -
- flow_controller_->bytes_consumed();
- AddBytesConsumed(bytes_to_consume);
-}
-
-void QuicStream::OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame) {
- if (type_ == READ_UNIDIRECTIONAL) {
- OnUnrecoverableError(
- QUIC_WINDOW_UPDATE_RECEIVED_ON_READ_UNIDIRECTIONAL_STREAM,
- "WindowUpdateFrame received on READ_UNIDIRECTIONAL stream.");
- return;
- }
-
- if (!flow_controller_.has_value()) {
- QUIC_BUG(quic_bug_10586_9)
- << ENDPOINT
- << "OnWindowUpdateFrame called on stream without flow control";
- return;
- }
-
- if (flow_controller_->UpdateSendWindowOffset(frame.max_data)) {
- // Let session unblock this stream.
- session_->MarkConnectionLevelWriteBlocked(id_);
- }
-}
-
-bool QuicStream::MaybeIncreaseHighestReceivedOffset(
- QuicStreamOffset new_offset) {
- if (!flow_controller_.has_value()) {
- QUIC_BUG(quic_bug_10586_10)
- << ENDPOINT
- << "MaybeIncreaseHighestReceivedOffset called on stream without "
- "flow control";
- return false;
- }
- uint64_t increment =
- new_offset - flow_controller_->highest_received_byte_offset();
- if (!flow_controller_->UpdateHighestReceivedOffset(new_offset)) {
- return false;
- }
-
- // If |new_offset| increased the stream flow controller's highest received
- // offset, increase the connection flow controller's value by the incremental
- // difference.
- if (stream_contributes_to_connection_flow_control_) {
- connection_flow_controller_->UpdateHighestReceivedOffset(
- connection_flow_controller_->highest_received_byte_offset() +
- increment);
- }
- return true;
-}
-
-void QuicStream::AddBytesSent(QuicByteCount bytes) {
- if (!flow_controller_.has_value()) {
- QUIC_BUG(quic_bug_10586_11)
- << ENDPOINT << "AddBytesSent called on stream without flow control";
- return;
- }
- flow_controller_->AddBytesSent(bytes);
- if (stream_contributes_to_connection_flow_control_) {
- connection_flow_controller_->AddBytesSent(bytes);
- }
-}
-
-void QuicStream::AddBytesConsumed(QuicByteCount bytes) {
- if (type_ == CRYPTO) {
- // A stream with type CRYPTO has no flow control, so there's nothing this
- // function needs to do. This function still gets called by the
- // QuicStreamSequencers used by QuicCryptoStream.
- return;
- }
- if (!flow_controller_.has_value()) {
- QUIC_BUG(quic_bug_12570_7)
- << ENDPOINT
- << "AddBytesConsumed called on non-crypto stream without flow control";
- return;
- }
- // Only adjust stream level flow controller if still reading.
- if (!read_side_closed_) {
- flow_controller_->AddBytesConsumed(bytes);
- }
-
- if (stream_contributes_to_connection_flow_control_) {
- connection_flow_controller_->AddBytesConsumed(bytes);
- }
-}
-
-bool QuicStream::MaybeConfigSendWindowOffset(QuicStreamOffset new_offset,
- bool was_zero_rtt_rejected) {
- if (!flow_controller_.has_value()) {
- QUIC_BUG(quic_bug_10586_12)
- << ENDPOINT
- << "ConfigSendWindowOffset called on stream without flow control";
- return false;
- }
-
- // The validation code below is for QUIC with TLS only.
- if (new_offset < flow_controller_->send_window_offset()) {
- QUICHE_DCHECK(session()->version().UsesTls());
- if (was_zero_rtt_rejected && new_offset < flow_controller_->bytes_sent()) {
- // The client is given flow control window lower than what's written in
- // 0-RTT. This QUIC implementation is unable to retransmit them.
- QUIC_BUG_IF(quic_bug_12570_8, perspective_ == Perspective::IS_SERVER)
- << "Server streams' flow control should never be configured twice.";
- OnUnrecoverableError(
- QUIC_ZERO_RTT_UNRETRANSMITTABLE,
- absl::StrCat(
- "Server rejected 0-RTT, aborting because new stream max data ",
- new_offset, " for stream ", id_, " is less than currently used: ",
- flow_controller_->bytes_sent()));
- return false;
- } else if (session()->version().AllowsLowFlowControlLimits()) {
- // In IETF QUIC, if the client receives flow control limit lower than what
- // was resumed from 0-RTT, depending on 0-RTT status, it's either the
- // peer's fault or our implementation's fault.
- QUIC_BUG_IF(quic_bug_12570_9, perspective_ == Perspective::IS_SERVER)
- << "Server streams' flow control should never be configured twice.";
- OnUnrecoverableError(
- was_zero_rtt_rejected ? QUIC_ZERO_RTT_REJECTION_LIMIT_REDUCED
- : QUIC_ZERO_RTT_RESUMPTION_LIMIT_REDUCED,
- absl::StrCat(
- was_zero_rtt_rejected ? "Server rejected 0-RTT, aborting because "
- : "",
- "new stream max data ", new_offset, " decreases current limit: ",
- flow_controller_->send_window_offset()));
- return false;
- }
- }
-
- if (flow_controller_->UpdateSendWindowOffset(new_offset)) {
- // Let session unblock this stream.
- session_->MarkConnectionLevelWriteBlocked(id_);
- }
- return true;
-}
-
-void QuicStream::AddRandomPaddingAfterFin() {
- add_random_padding_after_fin_ = true;
-}
-
-bool QuicStream::OnStreamFrameAcked(QuicStreamOffset offset,
- QuicByteCount data_length, bool fin_acked,
- QuicTime::Delta /*ack_delay_time*/,
- QuicTime /*receive_timestamp*/,
- QuicByteCount* newly_acked_length) {
- QUIC_DVLOG(1) << ENDPOINT << "stream " << id_ << " Acking "
- << "[" << offset << ", " << offset + data_length << "]"
- << " fin = " << fin_acked;
- *newly_acked_length = 0;
- if (!send_buffer_.OnStreamDataAcked(offset, data_length,
- newly_acked_length)) {
- OnUnrecoverableError(QUIC_INTERNAL_ERROR, "Trying to ack unsent data.");
- return false;
- }
- if (!fin_sent_ && fin_acked) {
- OnUnrecoverableError(QUIC_INTERNAL_ERROR, "Trying to ack unsent fin.");
- return false;
- }
- // Indicates whether ack listener's OnPacketAcked should be called.
- const bool new_data_acked =
- *newly_acked_length > 0 || (fin_acked && fin_outstanding_);
- if (fin_acked) {
- fin_outstanding_ = false;
- fin_lost_ = false;
- }
- if (!IsWaitingForAcks() && write_side_closed_ &&
- !write_side_data_recvd_state_notified_) {
- OnWriteSideInDataRecvdState();
- write_side_data_recvd_state_notified_ = true;
- }
- if (!IsWaitingForAcks() && read_side_closed_ && write_side_closed_) {
- session_->MaybeCloseZombieStream(id_);
- }
- return new_data_acked;
-}
-
-void QuicStream::OnStreamFrameRetransmitted(QuicStreamOffset offset,
- QuicByteCount data_length,
- bool fin_retransmitted) {
- send_buffer_.OnStreamDataRetransmitted(offset, data_length);
- if (fin_retransmitted) {
- fin_lost_ = false;
- }
-}
-
-void QuicStream::OnStreamFrameLost(QuicStreamOffset offset,
- QuicByteCount data_length, bool fin_lost) {
- QUIC_DVLOG(1) << ENDPOINT << "stream " << id_ << " Losting "
- << "[" << offset << ", " << offset + data_length << "]"
- << " fin = " << fin_lost;
- if (data_length > 0) {
- send_buffer_.OnStreamDataLost(offset, data_length);
- }
- if (fin_lost && fin_outstanding_) {
- fin_lost_ = true;
- }
-}
-
-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);
- if (HasDeadlinePassed()) {
- OnDeadlinePassed();
- return true;
- }
- QuicIntervalSet<QuicStreamOffset> retransmission(offset,
- offset + data_length);
- retransmission.Difference(bytes_acked());
- bool retransmit_fin = fin && fin_outstanding_;
- if (retransmission.Empty() && !retransmit_fin) {
- return true;
- }
- QuicConsumedData consumed(0, false);
- for (const auto& interval : retransmission) {
- QuicStreamOffset retransmission_offset = interval.min();
- QuicByteCount retransmission_length = interval.max() - interval.min();
- const bool can_bundle_fin =
- retransmit_fin && (retransmission_offset + retransmission_length ==
- stream_bytes_written());
- consumed = stream_delegate_->WritevData(
- id_, retransmission_length, retransmission_offset,
- can_bundle_fin ? FIN : NO_FIN, type,
- session()->GetEncryptionLevelToSendApplicationData());
- QUIC_DVLOG(1) << ENDPOINT << "stream " << id_
- << " is forced to retransmit stream data ["
- << retransmission_offset << ", "
- << retransmission_offset + retransmission_length
- << ") and fin: " << can_bundle_fin
- << ", consumed: " << consumed;
- OnStreamFrameRetransmitted(retransmission_offset, consumed.bytes_consumed,
- consumed.fin_consumed);
- if (can_bundle_fin) {
- retransmit_fin = !consumed.fin_consumed;
- }
- if (consumed.bytes_consumed < retransmission_length ||
- (can_bundle_fin && !consumed.fin_consumed)) {
- // Connection is write blocked.
- return false;
- }
- }
- if (retransmit_fin) {
- QUIC_DVLOG(1) << ENDPOINT << "stream " << id_
- << " retransmits fin only frame.";
- consumed = stream_delegate_->WritevData(
- id_, 0, stream_bytes_written(), FIN, type,
- session()->GetEncryptionLevelToSendApplicationData());
- if (!consumed.fin_consumed) {
- return false;
- }
- }
- return true;
-}
-
-bool QuicStream::IsWaitingForAcks() const {
- return (!rst_sent_ || stream_error_.ok()) &&
- (send_buffer_.stream_bytes_outstanding() || fin_outstanding_);
-}
-
-QuicByteCount QuicStream::ReadableBytes() const {
- return sequencer_.ReadableBytes();
-}
-
-bool QuicStream::WriteStreamData(QuicStreamOffset offset,
- QuicByteCount data_length,
- QuicDataWriter* writer) {
- QUICHE_DCHECK_LT(0u, data_length);
- QUIC_DVLOG(2) << ENDPOINT << "Write stream " << id_ << " data from offset "
- << offset << " length " << data_length;
- return send_buffer_.WriteStreamData(offset, data_length, writer);
-}
-
-void QuicStream::WriteBufferedData(EncryptionLevel level) {
- QUICHE_DCHECK(!write_side_closed_ && (HasBufferedData() || fin_buffered_));
-
- if (session_->ShouldYield(id())) {
- session_->MarkConnectionLevelWriteBlocked(id());
- return;
- }
-
- // Size of buffered data.
- QuicByteCount write_length = BufferedDataBytes();
-
- // A FIN with zero data payload should not be flow control blocked.
- bool fin_with_zero_data = (fin_buffered_ && write_length == 0);
-
- bool fin = fin_buffered_;
-
- // How much data flow control permits to be written.
- QuicByteCount send_window;
- if (flow_controller_.has_value()) {
- send_window = flow_controller_->SendWindowSize();
- } else {
- send_window = std::numeric_limits<QuicByteCount>::max();
- QUIC_BUG(quic_bug_10586_13)
- << ENDPOINT
- << "WriteBufferedData called on stream without flow control";
- }
- if (stream_contributes_to_connection_flow_control_) {
- send_window =
- std::min(send_window, connection_flow_controller_->SendWindowSize());
- }
-
- if (send_window == 0 && !fin_with_zero_data) {
- // Quick return if nothing can be sent.
- MaybeSendBlocked();
- return;
- }
-
- if (write_length > send_window) {
- // Don't send the FIN unless all the data will be sent.
- fin = false;
-
- // Writing more data would be a violation of flow control.
- write_length = send_window;
- QUIC_DVLOG(1) << "stream " << id() << " shortens write length to "
- << write_length << " due to flow control";
- }
-
- StreamSendingState state = fin ? FIN : NO_FIN;
- if (fin && add_random_padding_after_fin_) {
- state = FIN_AND_PADDING;
- }
- QuicConsumedData consumed_data =
- stream_delegate_->WritevData(id(), write_length, stream_bytes_written(),
- state, NOT_RETRANSMISSION, level);
-
- OnStreamDataConsumed(consumed_data.bytes_consumed);
-
- AddBytesSent(consumed_data.bytes_consumed);
- QUIC_DVLOG(1) << ENDPOINT << "stream " << id_ << " sends "
- << stream_bytes_written() << " bytes "
- << " and has buffered data " << BufferedDataBytes() << " bytes."
- << " fin is sent: " << consumed_data.fin_consumed
- << " fin is buffered: " << fin_buffered_;
-
- // The write may have generated a write error causing this stream to be
- // closed. If so, simply return without marking the stream write blocked.
- if (write_side_closed_) {
- return;
- }
-
- if (consumed_data.bytes_consumed == write_length) {
- if (!fin_with_zero_data) {
- MaybeSendBlocked();
- }
- if (fin && consumed_data.fin_consumed) {
- QUICHE_DCHECK(!fin_sent_);
- fin_sent_ = true;
- fin_outstanding_ = true;
- if (fin_received_) {
- QUICHE_DCHECK(!was_draining_);
- session_->StreamDraining(id_,
- /*unidirectional=*/type_ != BIDIRECTIONAL);
- was_draining_ = true;
- }
- CloseWriteSide();
- } else if (fin && !consumed_data.fin_consumed) {
- session_->MarkConnectionLevelWriteBlocked(id());
- }
- } else {
- session_->MarkConnectionLevelWriteBlocked(id());
- }
- if (consumed_data.bytes_consumed > 0 || consumed_data.fin_consumed) {
- busy_counter_ = 0;
- }
-}
-
-uint64_t QuicStream::BufferedDataBytes() const {
- QUICHE_DCHECK_GE(send_buffer_.stream_offset(), stream_bytes_written());
- return send_buffer_.stream_offset() - stream_bytes_written();
-}
-
-bool QuicStream::CanWriteNewData() const {
- return BufferedDataBytes() < buffered_data_threshold_;
-}
-
-bool QuicStream::CanWriteNewDataAfterData(QuicByteCount length) const {
- return (BufferedDataBytes() + length) < buffered_data_threshold_;
-}
-
-uint64_t QuicStream::stream_bytes_written() const {
- return send_buffer_.stream_bytes_written();
-}
-
-const QuicIntervalSet<QuicStreamOffset>& QuicStream::bytes_acked() const {
- return send_buffer_.bytes_acked();
-}
-
-void QuicStream::OnStreamDataConsumed(QuicByteCount bytes_consumed) {
- send_buffer_.OnStreamDataConsumed(bytes_consumed);
-}
-
-void QuicStream::WritePendingRetransmission() {
- while (HasPendingRetransmission()) {
- QuicConsumedData consumed(0, false);
- if (!send_buffer_.HasPendingRetransmission()) {
- QUIC_DVLOG(1) << ENDPOINT << "stream " << id_
- << " retransmits fin only frame.";
- consumed = stream_delegate_->WritevData(
- id_, 0, stream_bytes_written(), FIN, LOSS_RETRANSMISSION,
- session()->GetEncryptionLevelToSendApplicationData());
- fin_lost_ = !consumed.fin_consumed;
- if (fin_lost_) {
- // Connection is write blocked.
- return;
- }
- } else {
- StreamPendingRetransmission pending =
- send_buffer_.NextPendingRetransmission();
- // Determine whether the lost fin can be bundled with the data.
- const bool can_bundle_fin =
- fin_lost_ &&
- (pending.offset + pending.length == stream_bytes_written());
- consumed = stream_delegate_->WritevData(
- id_, pending.length, pending.offset, can_bundle_fin ? FIN : NO_FIN,
- LOSS_RETRANSMISSION,
- session()->GetEncryptionLevelToSendApplicationData());
- QUIC_DVLOG(1) << ENDPOINT << "stream " << id_
- << " tries to retransmit stream data [" << pending.offset
- << ", " << pending.offset + pending.length
- << ") and fin: " << can_bundle_fin
- << ", consumed: " << consumed;
- OnStreamFrameRetransmitted(pending.offset, consumed.bytes_consumed,
- consumed.fin_consumed);
- if (consumed.bytes_consumed < pending.length ||
- (can_bundle_fin && !consumed.fin_consumed)) {
- // Connection is write blocked.
- return;
- }
- }
- }
-}
-
-bool QuicStream::MaybeSetTtl(QuicTime::Delta ttl) {
- if (is_static_) {
- QUIC_BUG(quic_bug_10586_14) << "Cannot set TTL of a static stream.";
- return false;
- }
- if (deadline_.IsInitialized()) {
- QUIC_DLOG(WARNING) << "Deadline has already been set.";
- return false;
- }
- QuicTime now = session()->connection()->clock()->ApproximateNow();
- deadline_ = now + ttl;
- return true;
-}
-
-bool QuicStream::HasDeadlinePassed() const {
- if (!deadline_.IsInitialized()) {
- // No deadline has been set.
- return false;
- }
- QuicTime now = session()->connection()->clock()->ApproximateNow();
- if (now < deadline_) {
- return false;
- }
- // TTL expired.
- QUIC_DVLOG(1) << "stream " << id() << " deadline has passed";
- return true;
-}
-
-void QuicStream::OnDeadlinePassed() { Reset(QUIC_STREAM_TTL_EXPIRED); }
-
-bool QuicStream::IsFlowControlBlocked() const {
- if (!flow_controller_.has_value()) {
- QUIC_BUG(quic_bug_10586_15)
- << "Trying to access non-existent flow controller.";
- return false;
- }
- return flow_controller_->IsBlocked();
-}
-
-QuicStreamOffset QuicStream::highest_received_byte_offset() const {
- if (!flow_controller_.has_value()) {
- QUIC_BUG(quic_bug_10586_16)
- << "Trying to access non-existent flow controller.";
- return 0;
- }
- return flow_controller_->highest_received_byte_offset();
-}
-
-void QuicStream::UpdateReceiveWindowSize(QuicStreamOffset size) {
- if (!flow_controller_.has_value()) {
- QUIC_BUG(quic_bug_10586_17)
- << "Trying to access non-existent flow controller.";
- return;
- }
- flow_controller_->UpdateReceiveWindowSize(size);
-}
-
-// static
-spdy::SpdyStreamPrecedence QuicStream::CalculateDefaultPriority(
- const QuicSession* session) {
- return spdy::SpdyStreamPrecedence(
- VersionUsesHttp3(session->transport_version())
- ? kDefaultUrgency
- : QuicStream::kDefaultPriority);
-}
-
-absl::optional<QuicByteCount> QuicStream::GetSendWindow() const {
- return flow_controller_.has_value()
- ? absl::optional<QuicByteCount>(flow_controller_->SendWindowSize())
- : absl::nullopt;
-}
-
-absl::optional<QuicByteCount> QuicStream::GetReceiveWindow() const {
- return flow_controller_.has_value()
- ? absl::optional<QuicByteCount>(
- flow_controller_->receive_window_size())
- : absl::nullopt;
-}
-
-void QuicStream::OnStreamCreatedFromPendingStream() {
- sequencer()->SetUnblocked();
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_stream.h b/chromium/net/third_party/quiche/src/quic/core/quic_stream.h
deleted file mode 100644
index dc129a28ee6..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_stream.h
+++ /dev/null
@@ -1,623 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// The base class for client/server QUIC streams.
-
-// It does not contain the entire interface needed by an application to interact
-// with a QUIC stream. Some parts of the interface must be obtained by
-// accessing the owning session object. A subclass of QuicStream
-// connects the object and the application that generates and consumes the data
-// of the stream.
-
-// The QuicStream object has a dependent QuicStreamSequencer object,
-// which is given the stream frames as they arrive, and provides stream data in
-// order by invoking ProcessRawData().
-
-#ifndef QUICHE_QUIC_CORE_QUIC_STREAM_H_
-#define QUICHE_QUIC_CORE_QUIC_STREAM_H_
-
-#include <cstddef>
-#include <cstdint>
-#include <list>
-#include <string>
-
-#include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
-#include "absl/types/span.h"
-#include "quic/core/frames/quic_rst_stream_frame.h"
-#include "quic/core/quic_error_codes.h"
-#include "quic/core/quic_flow_controller.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_stream_send_buffer.h"
-#include "quic/core/quic_stream_sequencer.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/session_notifier_interface.h"
-#include "quic/core/stream_delegate_interface.h"
-#include "quic/platform/api/quic_export.h"
-#include "quic/platform/api/quic_mem_slice.h"
-#include "quic/platform/api/quic_reference_counted.h"
-#include "spdy/core/spdy_protocol.h"
-
-namespace quic {
-
-namespace test {
-class QuicStreamPeer;
-} // namespace test
-
-class QuicSession;
-class QuicStream;
-
-// Buffers frames for a stream until the first byte of that frame arrives.
-class QUIC_EXPORT_PRIVATE PendingStream
- : public QuicStreamSequencer::StreamInterface {
- public:
- PendingStream(QuicStreamId id, QuicSession* session);
- PendingStream(const PendingStream&) = delete;
- PendingStream(PendingStream&&) = default;
- ~PendingStream() override = default;
-
- // QuicStreamSequencer::StreamInterface
- void OnDataAvailable() override;
- void OnFinRead() override;
- void AddBytesConsumed(QuicByteCount bytes) override;
- void ResetWithError(QuicResetStreamError error) override;
- void OnUnrecoverableError(QuicErrorCode error,
- const std::string& details) override;
- void OnUnrecoverableError(QuicErrorCode error,
- QuicIetfTransportErrorCodes ietf_error,
- const std::string& details) override;
- QuicStreamId id() const override;
- ParsedQuicVersion version() const override;
-
- // Buffers the contents of |frame|. Frame must have a non-zero offset.
- // If the data violates flow control, the connection will be closed.
- void OnStreamFrame(const QuicStreamFrame& frame);
-
- bool is_bidirectional() const { return is_bidirectional_; }
-
- // Stores the final byte offset from |frame|.
- // If the final offset violates flow control, the connection will be closed.
- void OnRstStreamFrame(const QuicRstStreamFrame& frame);
-
- void OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame);
-
- void OnStopSending(QuicResetStreamError stop_sending_error_code);
-
- // The error code received from QuicStopSendingFrame (if any).
- const absl::optional<QuicResetStreamError>& GetStopSendingErrorCode() const {
- return stop_sending_error_code_;
- }
-
- // Returns the number of bytes read on this stream.
- uint64_t stream_bytes_read() { return stream_bytes_read_; }
-
- const QuicStreamSequencer* sequencer() const { return &sequencer_; }
-
- void MarkConsumed(QuicByteCount num_bytes);
-
- // Tells the sequencer to ignore all incoming data itself and not call
- // OnDataAvailable().
- void StopReading();
-
- private:
- friend class QuicStream;
-
- bool MaybeIncreaseHighestReceivedOffset(QuicStreamOffset new_offset);
-
- // ID of this stream.
- QuicStreamId id_;
-
- // QUIC version being used by this stream.
- ParsedQuicVersion version_;
-
- // |stream_delegate_| must outlive this stream.
- StreamDelegateInterface* stream_delegate_;
-
- // Bytes read refers to payload bytes only: they do not include framing,
- // encryption overhead etc.
- uint64_t stream_bytes_read_;
-
- // True if a frame containing a fin has been received.
- bool fin_received_;
-
- // True if this pending stream is backing a bidirectional stream.
- bool is_bidirectional_;
-
- // Connection-level flow controller. Owned by the session.
- QuicFlowController* connection_flow_controller_;
- // Stream-level flow controller.
- QuicFlowController flow_controller_;
- // Stores the buffered frames.
- QuicStreamSequencer sequencer_;
- // The error code received from QuicStopSendingFrame (if any).
- absl::optional<QuicResetStreamError> stop_sending_error_code_;
-};
-
-class QUIC_EXPORT_PRIVATE QuicStream
- : public QuicStreamSequencer::StreamInterface {
- public:
- // Default priority for Google QUIC.
- // This is somewhat arbitrary. It's possible, but unlikely, we will either
- // fail to set a priority client-side, or cancel a stream before stripping the
- // priority from the wire server-side. In either case, start out with a
- // priority in the middle in case of Google QUIC.
- static const spdy::SpdyPriority kDefaultPriority = 3;
- static_assert(kDefaultPriority ==
- (spdy::kV3LowestPriority + spdy::kV3HighestPriority) / 2,
- "Unexpected value of kDefaultPriority");
-
- // Creates a new stream with stream_id |id| associated with |session|. If
- // |is_static| is true, then the stream will be given precedence
- // over other streams when determing what streams should write next.
- // |type| indicates whether the stream is bidirectional, read unidirectional
- // or write unidirectional.
- // TODO(fayang): Remove |type| when IETF stream ID numbering fully kicks in.
- QuicStream(QuicStreamId id, QuicSession* session, bool is_static,
- StreamType type);
- QuicStream(PendingStream* pending, QuicSession* session, bool is_static);
- QuicStream(const QuicStream&) = delete;
- QuicStream& operator=(const QuicStream&) = delete;
-
- virtual ~QuicStream();
-
- // Default priority for IETF QUIC, defined by the priority extension at
- // https://httpwg.org/http-extensions/draft-ietf-httpbis-priority.html#urgency.
- static const int kDefaultUrgency = 3;
-
- // QuicStreamSequencer::StreamInterface implementation.
- QuicStreamId id() const override { return id_; }
- ParsedQuicVersion version() const override;
- // Called by the stream subclass after it has consumed the final incoming
- // data.
- void OnFinRead() override;
-
- // Called by the subclass or the sequencer to reset the stream from this
- // end.
- void ResetWithError(QuicResetStreamError error) override;
- // Convenience wrapper for the method above.
- // TODO(b/200606367): switch all calls to using QuicResetStreamError
- // interface.
- void Reset(QuicRstStreamErrorCode error);
-
- // Reset() sends both RESET_STREAM and STOP_SENDING; the two methods below
- // allow to send only one of those.
- void ResetWriteSide(QuicResetStreamError error);
- void SendStopSending(QuicResetStreamError error);
-
- // Called by the subclass or the sequencer to close the entire connection from
- // this end.
- void OnUnrecoverableError(QuicErrorCode error,
- const std::string& details) override;
- void OnUnrecoverableError(QuicErrorCode error,
- QuicIetfTransportErrorCodes ietf_error,
- const std::string& details) override;
-
- // Called by the session when a (potentially duplicate) stream frame has been
- // received for this stream.
- virtual void OnStreamFrame(const QuicStreamFrame& frame);
-
- // Called by the session when the connection becomes writeable to allow the
- // stream to write any pending data.
- virtual void OnCanWrite();
-
- // Called by the session when the endpoint receives a RST_STREAM from the
- // peer.
- virtual void OnStreamReset(const QuicRstStreamFrame& frame);
-
- // Called by the session when the endpoint receives or sends a connection
- // close, and should immediately close the stream.
- virtual void OnConnectionClosed(QuicErrorCode error,
- ConnectionCloseSource source);
-
- const spdy::SpdyStreamPrecedence& precedence() const;
-
- // Send PRIORITY_UPDATE frame if application protocol supports it.
- virtual void MaybeSendPriorityUpdateFrame() {}
-
- // Sets |priority_| to priority. This should only be called before bytes are
- // written to the server. For a server stream, this is called when a
- // PRIORITY_UPDATE frame is received. This calls
- // MaybeSendPriorityUpdateFrame(), which for a client stream might send a
- // PRIORITY_UPDATE frame.
- void SetPriority(const spdy::SpdyStreamPrecedence& precedence);
-
- // Returns true if this stream is still waiting for acks of sent data.
- // This will return false if all data has been acked, or if the stream
- // is no longer interested in data being acked (which happens when
- // a stream is reset because of an error).
- bool IsWaitingForAcks() const;
-
- // Number of bytes available to read.
- QuicByteCount ReadableBytes() const;
-
- QuicRstStreamErrorCode stream_error() const {
- return stream_error_.internal_code();
- }
- QuicErrorCode connection_error() const { return connection_error_; }
-
- bool reading_stopped() const {
- return sequencer_.ignore_read_data() || read_side_closed_;
- }
- bool write_side_closed() const { return write_side_closed_; }
- bool read_side_closed() const { return read_side_closed_; }
-
- bool IsZombie() const {
- return read_side_closed_ && write_side_closed_ && IsWaitingForAcks();
- }
-
- bool rst_received() const { return rst_received_; }
- bool rst_sent() const { return rst_sent_; }
- bool fin_received() const { return fin_received_; }
- bool fin_sent() const { return fin_sent_; }
- bool fin_outstanding() const { return fin_outstanding_; }
- bool fin_lost() const { return fin_lost_; }
-
- uint64_t BufferedDataBytes() const;
-
- uint64_t stream_bytes_read() const { return stream_bytes_read_; }
- uint64_t stream_bytes_written() const;
-
- size_t busy_counter() const { return busy_counter_; }
- void set_busy_counter(size_t busy_counter) { busy_counter_ = busy_counter; }
-
- // Adjust the flow control window according to new offset in |frame|.
- virtual void OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame);
-
- int num_frames_received() const;
- int num_duplicate_frames_received() const;
-
- // Flow controller related methods.
- bool IsFlowControlBlocked() const;
- QuicStreamOffset highest_received_byte_offset() const;
- void UpdateReceiveWindowSize(QuicStreamOffset size);
-
- // Called when endpoint receives a frame which could increase the highest
- // offset.
- // Returns true if the highest offset did increase.
- bool MaybeIncreaseHighestReceivedOffset(QuicStreamOffset new_offset);
-
- // Set the flow controller's send window offset from session config.
- // |was_zero_rtt_rejected| is true if this config is from a rejected IETF QUIC
- // 0-RTT attempt. Closes the connection and returns false if |new_offset| is
- // not valid.
- bool MaybeConfigSendWindowOffset(QuicStreamOffset new_offset,
- bool was_zero_rtt_rejected);
-
- // Returns true if the stream has received either a RST_STREAM or a FIN -
- // either of which gives a definitive number of bytes which the peer has
- // sent. If this is not true on deletion of the stream object, the session
- // must keep track of the stream's byte offset until a definitive final value
- // arrives.
- bool HasReceivedFinalOffset() const { return fin_received_ || rst_received_; }
-
- // Returns true if the stream has queued data waiting to write.
- bool HasBufferedData() const;
-
- // Returns the version of QUIC being used for this stream.
- QuicTransportVersion transport_version() const;
-
- // Returns the crypto handshake protocol that was used on this stream's
- // connection.
- HandshakeProtocol handshake_protocol() const;
-
- // Sets the sequencer to consume all incoming data itself and not call
- // OnDataAvailable().
- // When the FIN is received, the stream will be notified automatically (via
- // OnFinRead()) (which may happen during the call of StopReading()).
- // TODO(dworley): There should be machinery to send a RST_STREAM/NO_ERROR and
- // stop sending stream-level flow-control updates when this end sends FIN.
- virtual void StopReading();
-
- // Sends as much of |data| to the connection on the application encryption
- // level as the connection will consume, and then buffers any remaining data
- // in the send buffer. If fin is true: if it is immediately passed on to the
- // session, write_side_closed() becomes true, otherwise fin_buffered_ becomes
- // true.
- void WriteOrBufferData(
- absl::string_view data, bool fin,
- QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener);
-
- // Sends |data| to connection with specified |level|.
- void WriteOrBufferDataAtLevel(
- absl::string_view data, bool fin, EncryptionLevel level,
- QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener);
-
- // Adds random padding after the fin is consumed for this stream.
- void AddRandomPaddingAfterFin();
-
- // Write |data_length| of data starts at |offset| from send buffer.
- bool WriteStreamData(QuicStreamOffset offset, QuicByteCount data_length,
- QuicDataWriter* writer);
-
- // Called when data [offset, offset + data_length) is acked. |fin_acked|
- // indicates whether the fin is acked. Returns true and updates
- // |newly_acked_length| if any new stream data (including fin) gets acked.
- virtual bool OnStreamFrameAcked(QuicStreamOffset offset,
- QuicByteCount data_length, bool fin_acked,
- QuicTime::Delta ack_delay_time,
- QuicTime receive_timestamp,
- QuicByteCount* newly_acked_length);
-
- // Called when data [offset, offset + data_length) was retransmitted.
- // |fin_retransmitted| indicates whether fin was retransmitted.
- virtual void OnStreamFrameRetransmitted(QuicStreamOffset offset,
- QuicByteCount data_length,
- bool fin_retransmitted);
-
- // Called when data [offset, offset + data_length) is considered as lost.
- // |fin_lost| indicates whether the fin is considered as lost.
- virtual void OnStreamFrameLost(QuicStreamOffset offset,
- QuicByteCount data_length, bool fin_lost);
-
- // Called to retransmit outstanding portion in data [offset, offset +
- // data_length) and |fin| with Transmission |type|.
- // Returns true if all data gets retransmitted.
- virtual bool RetransmitStreamData(QuicStreamOffset offset,
- QuicByteCount data_length, bool fin,
- TransmissionType type);
-
- // Sets deadline of this stream to be now + |ttl|, returns true if the setting
- // succeeds.
- bool MaybeSetTtl(QuicTime::Delta ttl);
-
- // Commits data into the stream write buffer, and potentially sends it over
- // the wire. This method has all-or-nothing semantics: if the write buffer is
- // not full, all of the memslices in |span| are moved into it; otherwise,
- // nothing happens.
- QuicConsumedData WriteMemSlices(absl::Span<QuicMemSlice> span, bool fin);
- QuicConsumedData WriteMemSlice(QuicMemSlice span, bool fin);
-
- // Returns true if any stream data is lost (including fin) and needs to be
- // retransmitted.
- virtual bool HasPendingRetransmission() const;
-
- // Returns true if any portion of data [offset, offset + data_length) is
- // outstanding or fin is outstanding (if |fin| is true). Returns false
- // otherwise.
- bool IsStreamFrameOutstanding(QuicStreamOffset offset,
- QuicByteCount data_length, bool fin) const;
-
- StreamType type() const { return type_; }
-
- // Handle received StopSending frame. Returns true if the processing finishes
- // gracefully.
- virtual bool OnStopSending(QuicResetStreamError error);
-
- // Returns true if the stream is static.
- bool is_static() const { return is_static_; }
-
- bool was_draining() const { return was_draining_; }
-
- static spdy::SpdyStreamPrecedence CalculateDefaultPriority(
- const QuicSession* session);
-
- QuicTime creation_time() const { return creation_time_; }
-
- bool fin_buffered() const { return fin_buffered_; }
-
- // True if buffered data in send buffer is below buffered_data_threshold_.
- bool CanWriteNewData() const;
-
- // Called immediately after the stream is created from a pending stream,
- // indicating it can start processing data.
- void OnStreamCreatedFromPendingStream();
-
- protected:
- // Called when data of [offset, offset + data_length] is buffered in send
- // buffer.
- virtual void OnDataBuffered(
- QuicStreamOffset /*offset*/, QuicByteCount /*data_length*/,
- const QuicReferenceCountedPointer<QuicAckListenerInterface>&
- /*ack_listener*/) {}
-
- // Called just before the object is destroyed.
- // The object should not be accessed after OnClose is called.
- // Sends a RST_STREAM with code QUIC_RST_ACKNOWLEDGEMENT if neither a FIN nor
- // a RST_STREAM has been sent.
- virtual void OnClose();
-
- // True if buffered data in send buffer is still below
- // buffered_data_threshold_ even after writing |length| bytes.
- bool CanWriteNewDataAfterData(QuicByteCount length) const;
-
- // Called when upper layer can write new data.
- virtual void OnCanWriteNewData() {}
-
- // Called when |bytes_consumed| bytes has been consumed.
- virtual void OnStreamDataConsumed(QuicByteCount bytes_consumed);
-
- // Called by the stream sequencer as bytes are consumed from the buffer.
- // If the receive window has dropped below the threshold, then send a
- // WINDOW_UPDATE frame.
- void AddBytesConsumed(QuicByteCount bytes) override;
-
- // Writes pending retransmissions if any.
- virtual void WritePendingRetransmission();
-
- // This is called when stream tries to retransmit data after deadline_. Make
- // this virtual so that subclasses can implement their own logics.
- virtual void OnDeadlinePassed();
-
- // Called to set fin_sent_. This is only used by Google QUIC while body is
- // empty.
- void SetFinSent();
-
- // Send STOP_SENDING if it hasn't been sent yet.
- void MaybeSendStopSending(QuicResetStreamError error);
-
- // Send RESET_STREAM if it hasn't been sent yet.
- void MaybeSendRstStream(QuicResetStreamError error);
-
- // Convenience warppers for two methods above.
- void MaybeSendRstStream(QuicRstStreamErrorCode error) {
- MaybeSendRstStream(QuicResetStreamError::FromInternal(error));
- }
- void MaybeSendStopSending(QuicRstStreamErrorCode error) {
- MaybeSendStopSending(QuicResetStreamError::FromInternal(error));
- }
-
- // Close the write side of the socket. Further writes will fail.
- // Can be called by the subclass or internally.
- // Does not send a FIN. May cause the stream to be closed.
- virtual void CloseWriteSide();
-
- void set_rst_received(bool rst_received) { rst_received_ = rst_received; }
- void set_stream_error(QuicResetStreamError error) { stream_error_ = error; }
-
- StreamDelegateInterface* stream_delegate() { return stream_delegate_; }
-
- const QuicSession* session() const { return session_; }
- QuicSession* session() { return session_; }
-
- const QuicStreamSequencer* sequencer() const { return &sequencer_; }
- QuicStreamSequencer* sequencer() { return &sequencer_; }
-
- void DisableConnectionFlowControlForThisStream() {
- stream_contributes_to_connection_flow_control_ = false;
- }
-
- const QuicIntervalSet<QuicStreamOffset>& bytes_acked() const;
-
- const QuicStreamSendBuffer& send_buffer() const { return send_buffer_; }
-
- QuicStreamSendBuffer& send_buffer() { return send_buffer_; }
-
- // Called when the write side of the stream is closed, and all of the outgoing
- // data has been acknowledged. This corresponds to the "Data Recvd" state of
- // RFC 9000.
- virtual void OnWriteSideInDataRecvdState() {}
-
- // Return the current flow control send window in bytes.
- absl::optional<QuicByteCount> GetSendWindow() const;
- absl::optional<QuicByteCount> GetReceiveWindow() const;
-
- private:
- friend class test::QuicStreamPeer;
- friend class QuicStreamUtils;
-
- QuicStream(QuicStreamId id, QuicSession* session,
- QuicStreamSequencer sequencer, bool is_static, StreamType type,
- uint64_t stream_bytes_read, bool fin_received,
- absl::optional<QuicFlowController> flow_controller,
- QuicFlowController* connection_flow_controller);
-
- // Calls MaybeSendBlocked on the stream's flow controller and the connection
- // level flow controller. If the stream is flow control blocked by the
- // connection-level flow controller but not by the stream-level flow
- // controller, marks this stream as connection-level write blocked.
- void MaybeSendBlocked();
-
- // Write buffered data (in send buffer) at |level|.
- void WriteBufferedData(EncryptionLevel level);
-
- // Close the read side of the stream. May cause the stream to be closed.
- void CloseReadSide();
-
- // Called when bytes are sent to the peer.
- void AddBytesSent(QuicByteCount bytes);
-
- // Returns true if deadline_ has passed.
- bool HasDeadlinePassed() const;
-
- QuicStreamSequencer sequencer_;
- QuicStreamId id_;
- // Pointer to the owning QuicSession object.
- // TODO(b/136274541): Remove session pointer from streams.
- QuicSession* session_;
- StreamDelegateInterface* stream_delegate_;
- // The precedence of the stream, once parsed.
- spdy::SpdyStreamPrecedence precedence_;
- // Bytes read refers to payload bytes only: they do not include framing,
- // encryption overhead etc.
- uint64_t stream_bytes_read_;
-
- // Stream error code received from a RstStreamFrame or error code sent by the
- // visitor or sequencer in the RstStreamFrame.
- QuicResetStreamError stream_error_;
- // Connection error code due to which the stream was closed. |stream_error_|
- // is set to |QUIC_STREAM_CONNECTION_ERROR| when this happens and consumers
- // should check |connection_error_|.
- QuicErrorCode connection_error_;
-
- // True if the read side is closed and further frames should be rejected.
- bool read_side_closed_;
- // True if the write side is closed, and further writes should fail.
- bool write_side_closed_;
-
- // True if OnWriteSideInDataRecvdState() has already been called.
- bool write_side_data_recvd_state_notified_;
-
- // True if the subclass has written a FIN with WriteOrBufferData, but it was
- // buffered in queued_data_ rather than being sent to the session.
- bool fin_buffered_;
- // True if a FIN has been sent to the session.
- bool fin_sent_;
- // True if a FIN is waiting to be acked.
- bool fin_outstanding_;
- // True if a FIN is lost.
- bool fin_lost_;
-
- // True if this stream has received (and the sequencer has accepted) a
- // StreamFrame with the FIN set.
- bool fin_received_;
-
- // True if an RST_STREAM has been sent to the session.
- // In combination with fin_sent_, used to ensure that a FIN and/or a
- // RST_STREAM is always sent to terminate the stream.
- bool rst_sent_;
-
- // True if this stream has received a RST_STREAM frame.
- bool rst_received_;
-
- // True if the stream has sent STOP_SENDING to the session.
- bool stop_sending_sent_;
-
- absl::optional<QuicFlowController> flow_controller_;
-
- // The connection level flow controller. Not owned.
- QuicFlowController* connection_flow_controller_;
-
- // Special streams, such as the crypto and headers streams, do not respect
- // connection level flow control limits (but are stream level flow control
- // limited).
- bool stream_contributes_to_connection_flow_control_;
-
- // A counter incremented when OnCanWrite() is called and no progress is made.
- // For debugging only.
- size_t busy_counter_;
-
- // Indicates whether paddings will be added after the fin is consumed for this
- // stream.
- bool add_random_padding_after_fin_;
-
- // Send buffer of this stream. Send buffer is cleaned up when data gets acked
- // or discarded.
- QuicStreamSendBuffer send_buffer_;
-
- // Latched value of quic_buffered_data_threshold.
- const QuicByteCount buffered_data_threshold_;
-
- // If true, then this stream has precedence over other streams for write
- // scheduling.
- const bool is_static_;
-
- // If initialized, reset this stream at this deadline.
- QuicTime deadline_;
-
- // True if this stream has entered draining state.
- bool was_draining_;
-
- // Indicates whether this stream is bidirectional, read unidirectional or
- // write unidirectional.
- const StreamType type_;
-
- // Creation time of this stream, as reported by the QuicClock.
- const QuicTime creation_time_;
-
- Perspective perspective_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_QUIC_STREAM_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_stream_frame_data_producer.h b/chromium/net/third_party/quiche/src/quic/core/quic_stream_frame_data_producer.h
deleted file mode 100644
index edcc84b55ce..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_stream_frame_data_producer.h
+++ /dev/null
@@ -1,39 +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_CORE_QUIC_STREAM_FRAME_DATA_PRODUCER_H_
-#define QUICHE_QUIC_CORE_QUIC_STREAM_FRAME_DATA_PRODUCER_H_
-
-#include "quic/core/quic_types.h"
-
-namespace quic {
-
-class QuicDataWriter;
-
-// Pure virtual class to retrieve stream data.
-class QUIC_EXPORT_PRIVATE QuicStreamFrameDataProducer {
- public:
- virtual ~QuicStreamFrameDataProducer() {}
-
- // Let |writer| write |data_length| data with |offset| of stream |id|. The
- // write fails when either stream is closed or corresponding data is failed to
- // be retrieved. This method allows writing a single stream frame from data
- // that spans multiple buffers.
- virtual WriteStreamDataResult WriteStreamData(QuicStreamId id,
- QuicStreamOffset offset,
- QuicByteCount data_length,
- QuicDataWriter* writer) = 0;
-
- // Writes the data for a CRYPTO frame to |writer| for a frame at encryption
- // level |level| starting at offset |offset| for |data_length| bytes. Returns
- // whether writing the data was successful.
- virtual bool WriteCryptoData(EncryptionLevel level,
- QuicStreamOffset offset,
- QuicByteCount data_length,
- QuicDataWriter* writer) = 0;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_QUIC_STREAM_FRAME_DATA_PRODUCER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_stream_id_manager.cc b/chromium/net/third_party/quiche/src/quic/core/quic_stream_id_manager.cc
deleted file mode 100644
index 40aa3d0f949..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_stream_id_manager.cc
+++ /dev/null
@@ -1,243 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-#include "quic/core/quic_stream_id_manager.h"
-
-#include <cstdint>
-#include <string>
-
-#include "absl/strings/str_cat.h"
-#include "quic/core/quic_connection.h"
-#include "quic/core/quic_constants.h"
-#include "quic/core/quic_session.h"
-#include "quic/core/quic_utils.h"
-#include "quic/core/quic_versions.h"
-#include "quic/platform/api/quic_flag_utils.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-#define ENDPOINT \
- (perspective_ == Perspective::IS_SERVER ? " Server: " : " Client: ")
-
-QuicStreamIdManager::QuicStreamIdManager(
- DelegateInterface* delegate,
- bool unidirectional,
- Perspective perspective,
- ParsedQuicVersion version,
- QuicStreamCount max_allowed_outgoing_streams,
- QuicStreamCount max_allowed_incoming_streams)
- : delegate_(delegate),
- unidirectional_(unidirectional),
- perspective_(perspective),
- version_(version),
- outgoing_max_streams_(max_allowed_outgoing_streams),
- next_outgoing_stream_id_(GetFirstOutgoingStreamId()),
- outgoing_stream_count_(0),
- incoming_actual_max_streams_(max_allowed_incoming_streams),
- incoming_advertised_max_streams_(max_allowed_incoming_streams),
- incoming_initial_max_open_streams_(max_allowed_incoming_streams),
- incoming_stream_count_(0),
- largest_peer_created_stream_id_(
- QuicUtils::GetInvalidStreamId(version.transport_version)) {}
-
-QuicStreamIdManager::~QuicStreamIdManager() {}
-
-bool QuicStreamIdManager::OnStreamsBlockedFrame(
- const QuicStreamsBlockedFrame& frame,
- std::string* error_details) {
- QUICHE_DCHECK_EQ(frame.unidirectional, unidirectional_);
- if (frame.stream_count > incoming_advertised_max_streams_) {
- // Peer thinks it can send more streams that we've told it.
- *error_details = absl::StrCat(
- "StreamsBlockedFrame's stream count ", frame.stream_count,
- " exceeds incoming max stream ", incoming_advertised_max_streams_);
- return false;
- }
- QUICHE_DCHECK_LE(incoming_advertised_max_streams_,
- incoming_actual_max_streams_);
- if (incoming_advertised_max_streams_ == incoming_actual_max_streams_) {
- // We have told peer about current max.
- return true;
- }
- if (frame.stream_count < incoming_actual_max_streams_) {
- // Peer thinks it's blocked on a stream count that is less than our current
- // max. Inform the peer of the correct stream count.
- SendMaxStreamsFrame();
- }
- return true;
-}
-
-bool QuicStreamIdManager::MaybeAllowNewOutgoingStreams(
- QuicStreamCount max_open_streams) {
- if (max_open_streams <= outgoing_max_streams_) {
- // Only update the stream count if it would increase the limit.
- return false;
- }
-
- // This implementation only supports 32 bit Stream IDs, so limit max streams
- // if it would exceed the max 32 bits can express.
- outgoing_max_streams_ =
- std::min(max_open_streams, QuicUtils::GetMaxStreamCount());
-
- return true;
-}
-
-void QuicStreamIdManager::SetMaxOpenIncomingStreams(
- QuicStreamCount max_open_streams) {
- QUIC_BUG_IF(quic_bug_12413_1, incoming_stream_count_ > 0)
- << "non-zero incoming stream count " << incoming_stream_count_
- << " when setting max incoming stream to " << max_open_streams;
- QUIC_DLOG_IF(WARNING, incoming_initial_max_open_streams_ != max_open_streams)
- << absl::StrCat(unidirectional_ ? "unidirectional " : "bidirectional: ",
- "incoming stream limit changed from ",
- incoming_initial_max_open_streams_, " to ",
- max_open_streams);
- incoming_actual_max_streams_ = max_open_streams;
- incoming_advertised_max_streams_ = max_open_streams;
- incoming_initial_max_open_streams_ = max_open_streams;
-}
-
-void QuicStreamIdManager::MaybeSendMaxStreamsFrame() {
- int divisor = GetQuicFlag(FLAGS_quic_max_streams_window_divisor);
-
- if (divisor > 0) {
- if ((incoming_advertised_max_streams_ - incoming_stream_count_) >
- (incoming_initial_max_open_streams_ / divisor)) {
- // window too large, no advertisement
- return;
- }
- }
- SendMaxStreamsFrame();
-}
-
-void QuicStreamIdManager::SendMaxStreamsFrame() {
- QUIC_BUG_IF(quic_bug_12413_2,
- incoming_advertised_max_streams_ >= incoming_actual_max_streams_);
- incoming_advertised_max_streams_ = incoming_actual_max_streams_;
- delegate_->SendMaxStreams(incoming_advertised_max_streams_, unidirectional_);
-}
-
-void QuicStreamIdManager::OnStreamClosed(QuicStreamId stream_id) {
- QUICHE_DCHECK_NE(QuicUtils::IsBidirectionalStreamId(stream_id, version_),
- unidirectional_);
- if (QuicUtils::IsOutgoingStreamId(version_, stream_id, perspective_)) {
- // Nothing to do for outgoing streams.
- return;
- }
- // If the stream is inbound, we can increase the actual stream limit and maybe
- // advertise the new limit to the peer.
- if (incoming_actual_max_streams_ == QuicUtils::GetMaxStreamCount()) {
- // Reached the maximum stream id value that the implementation
- // supports. Nothing can be done here.
- return;
- }
- // One stream closed, and another one can be opened.
- incoming_actual_max_streams_++;
- MaybeSendMaxStreamsFrame();
-}
-
-QuicStreamId QuicStreamIdManager::GetNextOutgoingStreamId() {
- QUIC_BUG_IF(quic_bug_12413_3, outgoing_stream_count_ >= outgoing_max_streams_)
- << "Attempt to allocate a new outgoing stream that would exceed the "
- "limit ("
- << outgoing_max_streams_ << ")";
- QuicStreamId id = next_outgoing_stream_id_;
- next_outgoing_stream_id_ +=
- QuicUtils::StreamIdDelta(version_.transport_version);
- outgoing_stream_count_++;
- return id;
-}
-
-bool QuicStreamIdManager::CanOpenNextOutgoingStream() const {
- QUICHE_DCHECK(VersionHasIetfQuicFrames(version_.transport_version));
- return outgoing_stream_count_ < outgoing_max_streams_;
-}
-
-bool QuicStreamIdManager::MaybeIncreaseLargestPeerStreamId(
- const QuicStreamId stream_id,
- std::string* error_details) {
- // |stream_id| must be an incoming stream of the right directionality.
- QUICHE_DCHECK_NE(QuicUtils::IsBidirectionalStreamId(stream_id, version_),
- unidirectional_);
- QUICHE_DCHECK_NE(QuicUtils::IsServerInitiatedStreamId(
- version_.transport_version, stream_id),
- perspective_ == Perspective::IS_SERVER);
- if (available_streams_.erase(stream_id) == 1) {
- // stream_id is available.
- return true;
- }
-
- if (largest_peer_created_stream_id_ !=
- QuicUtils::GetInvalidStreamId(version_.transport_version)) {
- QUICHE_DCHECK_GT(stream_id, largest_peer_created_stream_id_);
- }
-
- // Calculate increment of incoming_stream_count_ by creating stream_id.
- const QuicStreamCount delta =
- QuicUtils::StreamIdDelta(version_.transport_version);
- const QuicStreamId least_new_stream_id =
- largest_peer_created_stream_id_ ==
- QuicUtils::GetInvalidStreamId(version_.transport_version)
- ? GetFirstIncomingStreamId()
- : largest_peer_created_stream_id_ + delta;
- const QuicStreamCount stream_count_increment =
- (stream_id - least_new_stream_id) / delta + 1;
-
- if (incoming_stream_count_ + stream_count_increment >
- incoming_advertised_max_streams_) {
- QUIC_DLOG(INFO) << ENDPOINT
- << "Failed to create a new incoming stream with id:"
- << stream_id << ", reaching MAX_STREAMS limit: "
- << incoming_advertised_max_streams_ << ".";
- *error_details = absl::StrCat("Stream id ", stream_id,
- " would exceed stream count limit ",
- incoming_advertised_max_streams_);
- return false;
- }
-
- for (QuicStreamId id = least_new_stream_id; id < stream_id; id += delta) {
- available_streams_.insert(id);
- }
- incoming_stream_count_ += stream_count_increment;
- largest_peer_created_stream_id_ = stream_id;
- return true;
-}
-
-bool QuicStreamIdManager::IsAvailableStream(QuicStreamId id) const {
- QUICHE_DCHECK_NE(QuicUtils::IsBidirectionalStreamId(id, version_),
- unidirectional_);
- if (QuicUtils::IsOutgoingStreamId(version_, id, perspective_)) {
- // Stream IDs under next_ougoing_stream_id_ are either open or previously
- // open but now closed.
- return id >= next_outgoing_stream_id_;
- }
- // For peer created streams, we also need to consider available streams.
- return largest_peer_created_stream_id_ ==
- QuicUtils::GetInvalidStreamId(version_.transport_version) ||
- id > largest_peer_created_stream_id_ ||
- available_streams_.contains(id);
-}
-
-QuicStreamId QuicStreamIdManager::GetFirstOutgoingStreamId() const {
- return (unidirectional_) ? QuicUtils::GetFirstUnidirectionalStreamId(
- version_.transport_version, perspective_)
- : QuicUtils::GetFirstBidirectionalStreamId(
- version_.transport_version, perspective_);
-}
-
-QuicStreamId QuicStreamIdManager::GetFirstIncomingStreamId() const {
- return (unidirectional_) ? QuicUtils::GetFirstUnidirectionalStreamId(
- version_.transport_version,
- QuicUtils::InvertPerspective(perspective_))
- : QuicUtils::GetFirstBidirectionalStreamId(
- version_.transport_version,
- QuicUtils::InvertPerspective(perspective_));
-}
-
-QuicStreamCount QuicStreamIdManager::available_incoming_streams() const {
- return incoming_advertised_max_streams_ - incoming_stream_count_;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_stream_id_manager.h b/chromium/net/third_party/quiche/src/quic/core/quic_stream_id_manager.h
deleted file mode 100644
index 4261f43982b..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_stream_id_manager.h
+++ /dev/null
@@ -1,186 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-#ifndef QUICHE_QUIC_CORE_QUIC_STREAM_ID_MANAGER_H_
-#define QUICHE_QUIC_CORE_QUIC_STREAM_ID_MANAGER_H_
-
-#include "absl/container/flat_hash_set.h"
-#include "absl/strings/str_cat.h"
-#include "quic/core/frames/quic_frame.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_versions.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-namespace test {
-class QuicSessionPeer;
-class QuicStreamIdManagerPeer;
-} // namespace test
-
-// This class manages the stream ids for IETF QUIC.
-class QUIC_EXPORT_PRIVATE QuicStreamIdManager {
- public:
- class QUIC_EXPORT_PRIVATE DelegateInterface {
- public:
- virtual ~DelegateInterface() = default;
-
- // Send a MAX_STREAMS frame.
- virtual void SendMaxStreams(QuicStreamCount stream_count,
- bool unidirectional) = 0;
- };
-
- QuicStreamIdManager(DelegateInterface* delegate,
- bool unidirectional,
- Perspective perspective,
- ParsedQuicVersion version,
- QuicStreamCount max_allowed_outgoing_streams,
- QuicStreamCount max_allowed_incoming_streams);
-
- ~QuicStreamIdManager();
-
- // Generate a string suitable for sending to the log/etc to show current state
- // of the stream ID manager.
- std::string DebugString() const {
- return absl::StrCat(
- " { unidirectional_: ", unidirectional_,
- ", perspective: ", perspective_,
- ", outgoing_max_streams_: ", outgoing_max_streams_,
- ", next_outgoing_stream_id_: ", next_outgoing_stream_id_,
- ", outgoing_stream_count_: ", outgoing_stream_count_,
- ", incoming_actual_max_streams_: ", incoming_actual_max_streams_,
- ", incoming_advertised_max_streams_: ",
- incoming_advertised_max_streams_,
- ", incoming_stream_count_: ", incoming_stream_count_,
- ", available_streams_.size(): ", available_streams_.size(),
- ", largest_peer_created_stream_id_: ", largest_peer_created_stream_id_,
- " }");
- }
-
- // Processes the STREAMS_BLOCKED frame. If error is encountered, populates
- // |error_details| and returns false.
- bool OnStreamsBlockedFrame(const QuicStreamsBlockedFrame& frame,
- std::string* error_details);
-
- // Returns whether the next outgoing stream ID can be allocated or not.
- bool CanOpenNextOutgoingStream() const;
-
- // Generate and send a MAX_STREAMS frame.
- void SendMaxStreamsFrame();
-
- // Invoked to deal with releasing a stream. Does nothing if the stream is
- // outgoing. If the stream is incoming, the number of streams that the peer
- // can open will be updated and a MAX_STREAMS frame, informing the peer of
- // the additional streams, may be sent.
- void OnStreamClosed(QuicStreamId stream_id);
-
- // Returns the next outgoing stream id. Applications must call
- // CanOpenNextOutgoingStream() first.
- QuicStreamId GetNextOutgoingStreamId();
-
- void SetMaxOpenIncomingStreams(QuicStreamCount max_open_streams);
-
- // Called on |max_open_streams| outgoing streams can be created because of 1)
- // config negotiated or 2) MAX_STREAMS received. Returns true if new
- // streams can be created.
- bool MaybeAllowNewOutgoingStreams(QuicStreamCount max_open_streams);
-
- // Checks if the incoming stream ID exceeds the MAX_STREAMS limit. If the
- // limit is exceeded, populates |error_detials| and returns false.
- bool MaybeIncreaseLargestPeerStreamId(const QuicStreamId stream_id,
- std::string* error_details);
-
- // Returns true if |id| is still available.
- bool IsAvailableStream(QuicStreamId id) const;
-
- QuicStreamCount incoming_initial_max_open_streams() const {
- return incoming_initial_max_open_streams_;
- }
-
- QuicStreamId next_outgoing_stream_id() const {
- return next_outgoing_stream_id_;
- }
-
- // Number of streams that the peer believes that it can still create.
- QuicStreamCount available_incoming_streams() const;
-
- QuicStreamId largest_peer_created_stream_id() const {
- return largest_peer_created_stream_id_;
- }
-
- QuicStreamCount outgoing_max_streams() const { return outgoing_max_streams_; }
- QuicStreamCount incoming_actual_max_streams() const {
- return incoming_actual_max_streams_;
- }
- QuicStreamCount incoming_advertised_max_streams() const {
- return incoming_advertised_max_streams_;
- }
- QuicStreamCount outgoing_stream_count() const {
- return outgoing_stream_count_;
- }
-
- private:
- friend class test::QuicSessionPeer;
- friend class test::QuicStreamIdManagerPeer;
-
- // Check whether the MAX_STREAMS window has opened up enough and, if so,
- // generate and send a MAX_STREAMS frame.
- void MaybeSendMaxStreamsFrame();
-
- // Get what should be the first incoming/outgoing stream ID that
- // this stream id manager will manage, taking into account directionality and
- // client/server perspective.
- QuicStreamId GetFirstOutgoingStreamId() const;
- QuicStreamId GetFirstIncomingStreamId() const;
-
- // Back reference to the session containing this Stream ID Manager.
- DelegateInterface* delegate_;
-
- // Whether this stream id manager is for unidrectional (true) or bidirectional
- // (false) streams.
- const bool unidirectional_;
-
- // Is this manager a client or a server.
- const Perspective perspective_;
-
- // QUIC version used for this manager.
- const ParsedQuicVersion version_;
-
- // The number of streams that this node can initiate.
- // This limit is first set when config is negotiated, but may be updated upon
- // receiving MAX_STREAMS frame.
- QuicStreamCount outgoing_max_streams_;
-
- // The ID to use for the next outgoing stream.
- QuicStreamId next_outgoing_stream_id_;
-
- // The number of outgoing streams that have ever been opened, including those
- // that have been closed. This number must never be larger than
- // outgoing_max_streams_.
- QuicStreamCount outgoing_stream_count_;
-
- // FOR INCOMING STREAMS
-
- // The actual maximum number of streams that can be opened by the peer.
- QuicStreamCount incoming_actual_max_streams_;
- // Max incoming stream number that has been advertised to the peer and is <=
- // incoming_actual_max_streams_. It is set to incoming_actual_max_streams_
- // when a MAX_STREAMS is sent.
- QuicStreamCount incoming_advertised_max_streams_;
-
- // Initial maximum on the number of open streams allowed.
- QuicStreamCount incoming_initial_max_open_streams_;
-
- // The number of streams that have been created, including open ones and
- // closed ones.
- QuicStreamCount incoming_stream_count_;
-
- // Set of stream ids that are less than the largest stream id that has been
- // received, but are nonetheless available to be created.
- absl::flat_hash_set<QuicStreamId> available_streams_;
-
- QuicStreamId largest_peer_created_stream_id_;
-};
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_QUIC_STREAM_ID_MANAGER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_stream_id_manager_test.cc b/chromium/net/third_party/quiche/src/quic/core/quic_stream_id_manager_test.cc
deleted file mode 100644
index 47ba76faf79..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_stream_id_manager_test.cc
+++ /dev/null
@@ -1,479 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-#include "quic/core/quic_stream_id_manager.h"
-
-#include <cstdint>
-#include <string>
-#include <utility>
-
-#include "absl/strings/str_cat.h"
-#include "quic/core/quic_constants.h"
-#include "quic/core/quic_utils.h"
-#include "quic/core/quic_versions.h"
-#include "quic/platform/api/quic_expect_bug.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/quic_stream_id_manager_peer.h"
-
-using testing::_;
-using testing::StrictMock;
-
-namespace quic {
-namespace test {
-namespace {
-
-class MockDelegate : public QuicStreamIdManager::DelegateInterface {
- public:
- MOCK_METHOD(void,
- SendMaxStreams,
- (QuicStreamCount stream_count, bool unidirectional),
- (override));
-};
-
-struct TestParams {
- TestParams(ParsedQuicVersion version,
- Perspective perspective,
- bool is_unidirectional)
- : version(version),
- perspective(perspective),
- is_unidirectional(is_unidirectional) {}
-
- ParsedQuicVersion version;
- Perspective perspective;
- bool is_unidirectional;
-};
-
-// Used by ::testing::PrintToStringParamName().
-std::string PrintToString(const TestParams& p) {
- return absl::StrCat(
- ParsedQuicVersionToString(p.version), "_",
- (p.perspective == Perspective::IS_CLIENT ? "Client" : "Server"),
- (p.is_unidirectional ? "Unidirectional" : "Bidirectional"));
-}
-
-std::vector<TestParams> GetTestParams() {
- std::vector<TestParams> params;
- for (const ParsedQuicVersion& version : AllSupportedVersions()) {
- if (!version.HasIetfQuicFrames()) {
- continue;
- }
- for (Perspective perspective :
- {Perspective::IS_CLIENT, Perspective::IS_SERVER}) {
- for (bool is_unidirectional : {true, false}) {
- params.push_back(TestParams(version, perspective, is_unidirectional));
- }
- }
- }
- return params;
-}
-
-class QuicStreamIdManagerTest : public QuicTestWithParam<TestParams> {
- protected:
- QuicStreamIdManagerTest()
- : stream_id_manager_(&delegate_,
- IsUnidirectional(),
- perspective(),
- GetParam().version,
- 0,
- kDefaultMaxStreamsPerConnection) {
- QUICHE_DCHECK(VersionHasIetfQuicFrames(transport_version()));
- }
-
- QuicTransportVersion transport_version() const {
- return GetParam().version.transport_version;
- }
-
- // Returns the stream ID for the Nth incoming stream (created by the peer)
- // of the corresponding directionality of this manager.
- QuicStreamId GetNthIncomingStreamId(int n) {
- return QuicUtils::StreamIdDelta(transport_version()) * n +
- (IsUnidirectional()
- ? QuicUtils::GetFirstUnidirectionalStreamId(
- transport_version(),
- QuicUtils::InvertPerspective(perspective()))
- : QuicUtils::GetFirstBidirectionalStreamId(
- transport_version(),
- QuicUtils::InvertPerspective(perspective())));
- }
-
- bool IsUnidirectional() { return GetParam().is_unidirectional; }
- Perspective perspective() { return GetParam().perspective; }
-
- StrictMock<MockDelegate> delegate_;
- QuicStreamIdManager stream_id_manager_;
-};
-
-INSTANTIATE_TEST_SUITE_P(Tests,
- QuicStreamIdManagerTest,
- ::testing::ValuesIn(GetTestParams()),
- ::testing::PrintToStringParamName());
-
-TEST_P(QuicStreamIdManagerTest, Initialization) {
- EXPECT_EQ(0u, stream_id_manager_.outgoing_max_streams());
-
- EXPECT_EQ(kDefaultMaxStreamsPerConnection,
- stream_id_manager_.incoming_actual_max_streams());
- EXPECT_EQ(kDefaultMaxStreamsPerConnection,
- stream_id_manager_.incoming_advertised_max_streams());
- EXPECT_EQ(kDefaultMaxStreamsPerConnection,
- stream_id_manager_.incoming_initial_max_open_streams());
-}
-
-// This test checks that the stream advertisement window is set to 1
-// if the number of stream ids is 1. This is a special case in the code.
-TEST_P(QuicStreamIdManagerTest, CheckMaxStreamsWindowForSingleStream) {
- stream_id_manager_.SetMaxOpenIncomingStreams(1);
- EXPECT_EQ(1u, stream_id_manager_.incoming_initial_max_open_streams());
- EXPECT_EQ(1u, stream_id_manager_.incoming_actual_max_streams());
-}
-
-TEST_P(QuicStreamIdManagerTest, CheckMaxStreamsBadValuesOverMaxFailsOutgoing) {
- QuicStreamCount implementation_max = QuicUtils::GetMaxStreamCount();
- // Ensure that the limit is less than the implementation maximum.
- EXPECT_LT(stream_id_manager_.outgoing_max_streams(), implementation_max);
-
- EXPECT_TRUE(
- stream_id_manager_.MaybeAllowNewOutgoingStreams(implementation_max + 1));
- // Should be pegged at the max.
- EXPECT_EQ(implementation_max, stream_id_manager_.outgoing_max_streams());
-}
-
-// Check the case of the stream count in a STREAMS_BLOCKED frame is less than
-// the count most recently advertised in a MAX_STREAMS frame.
-TEST_P(QuicStreamIdManagerTest, ProcessStreamsBlockedOk) {
- QuicStreamCount stream_count =
- stream_id_manager_.incoming_initial_max_open_streams();
- QuicStreamsBlockedFrame frame(0, stream_count - 1, IsUnidirectional());
- // We have notified peer about current max.
- EXPECT_CALL(delegate_, SendMaxStreams(stream_count, IsUnidirectional()))
- .Times(0);
- std::string error_details;
- EXPECT_TRUE(stream_id_manager_.OnStreamsBlockedFrame(frame, &error_details));
-}
-
-// Check the case of the stream count in a STREAMS_BLOCKED frame is equal to the
-// count most recently advertised in a MAX_STREAMS frame. No MAX_STREAMS
-// should be generated.
-TEST_P(QuicStreamIdManagerTest, ProcessStreamsBlockedNoOp) {
- QuicStreamCount stream_count =
- stream_id_manager_.incoming_initial_max_open_streams();
- QuicStreamsBlockedFrame frame(0, stream_count, IsUnidirectional());
- EXPECT_CALL(delegate_, SendMaxStreams(_, _)).Times(0);
-}
-
-// Check the case of the stream count in a STREAMS_BLOCKED frame is greater than
-// the count most recently advertised in a MAX_STREAMS frame. Expect a
-// connection close with an error.
-TEST_P(QuicStreamIdManagerTest, ProcessStreamsBlockedTooBig) {
- EXPECT_CALL(delegate_, SendMaxStreams(_, _)).Times(0);
- QuicStreamCount stream_count =
- stream_id_manager_.incoming_initial_max_open_streams() + 1;
- QuicStreamsBlockedFrame frame(0, stream_count, IsUnidirectional());
- std::string error_details;
- EXPECT_FALSE(stream_id_manager_.OnStreamsBlockedFrame(frame, &error_details));
- EXPECT_EQ(
- error_details,
- "StreamsBlockedFrame's stream count 101 exceeds incoming max stream 100");
-}
-
-// Same basic tests as above, but calls
-// QuicStreamIdManager::MaybeIncreaseLargestPeerStreamId directly, avoiding the
-// call chain. The intent is that if there is a problem, the following tests
-// will point to either the stream ID manager or the call chain. They also
-// provide specific, small scale, tests of a public QuicStreamIdManager method.
-// First test make sure that streams with ids below the limit are accepted.
-TEST_P(QuicStreamIdManagerTest, IsIncomingStreamIdValidBelowLimit) {
- QuicStreamId stream_id = GetNthIncomingStreamId(
- stream_id_manager_.incoming_actual_max_streams() - 2);
- EXPECT_TRUE(
- stream_id_manager_.MaybeIncreaseLargestPeerStreamId(stream_id, nullptr));
-}
-
-// Accept a stream with an ID that equals the limit.
-TEST_P(QuicStreamIdManagerTest, IsIncomingStreamIdValidAtLimit) {
- QuicStreamId stream_id = GetNthIncomingStreamId(
- stream_id_manager_.incoming_actual_max_streams() - 1);
- EXPECT_TRUE(
- stream_id_manager_.MaybeIncreaseLargestPeerStreamId(stream_id, nullptr));
-}
-
-// Close the connection if the id exceeds the limit.
-TEST_P(QuicStreamIdManagerTest, IsIncomingStreamIdInValidAboveLimit) {
- QuicStreamId stream_id =
- GetNthIncomingStreamId(stream_id_manager_.incoming_actual_max_streams());
- std::string error_details;
- EXPECT_FALSE(stream_id_manager_.MaybeIncreaseLargestPeerStreamId(
- stream_id, &error_details));
- EXPECT_EQ(error_details,
- absl::StrCat("Stream id ", stream_id,
- " would exceed stream count limit 100"));
-}
-
-TEST_P(QuicStreamIdManagerTest, OnStreamsBlockedFrame) {
- // Get the current maximum allowed incoming stream count.
- QuicStreamCount advertised_stream_count =
- stream_id_manager_.incoming_advertised_max_streams();
-
- QuicStreamsBlockedFrame frame;
-
- frame.unidirectional = IsUnidirectional();
-
- // If the peer is saying it's blocked on the stream count that
- // we've advertised, it's a noop since the peer has the correct information.
- frame.stream_count = advertised_stream_count;
- std::string error_details;
- EXPECT_TRUE(stream_id_manager_.OnStreamsBlockedFrame(frame, &error_details));
-
- // If the peer is saying it's blocked on a stream count that is larger
- // than what we've advertised, the connection should get closed.
- frame.stream_count = advertised_stream_count + 1;
- EXPECT_FALSE(stream_id_manager_.OnStreamsBlockedFrame(frame, &error_details));
- EXPECT_EQ(
- error_details,
- "StreamsBlockedFrame's stream count 101 exceeds incoming max stream 100");
-
- // If the peer is saying it's blocked on a count that is less than
- // our actual count, we send a MAX_STREAMS frame and update
- // the advertised value.
- // First, need to bump up the actual max so there is room for the MAX
- // STREAMS frame to send a larger ID.
- QuicStreamCount actual_stream_count =
- stream_id_manager_.incoming_actual_max_streams();
-
- // Closing a stream will result in the ability to initiate one more
- // stream
- stream_id_manager_.OnStreamClosed(
- QuicStreamIdManagerPeer::GetFirstIncomingStreamId(&stream_id_manager_));
- EXPECT_EQ(actual_stream_count + 1u,
- stream_id_manager_.incoming_actual_max_streams());
- EXPECT_EQ(stream_id_manager_.incoming_actual_max_streams(),
- stream_id_manager_.incoming_advertised_max_streams() + 1u);
-
- // Now simulate receiving a STREAMS_BLOCKED frame...
- // Changing the actual maximum, above, forces a MAX_STREAMS frame to be
- // sent, so the logic for that (SendMaxStreamsFrame(), etc) is tested.
-
- // The STREAMS_BLOCKED frame contains the previous advertised count,
- // not the one that the peer would have received as a result of the
- // MAX_STREAMS sent earler.
- frame.stream_count = advertised_stream_count;
-
- EXPECT_CALL(delegate_,
- SendMaxStreams(stream_id_manager_.incoming_actual_max_streams(),
- IsUnidirectional()));
-
- EXPECT_TRUE(stream_id_manager_.OnStreamsBlockedFrame(frame, &error_details));
- // Check that the saved frame is correct.
- EXPECT_EQ(stream_id_manager_.incoming_actual_max_streams(),
- stream_id_manager_.incoming_advertised_max_streams());
-}
-
-TEST_P(QuicStreamIdManagerTest, GetNextOutgoingStream) {
- // Number of streams we can open and the first one we should get when
- // opening...
- size_t number_of_streams = kDefaultMaxStreamsPerConnection;
-
- EXPECT_TRUE(
- stream_id_manager_.MaybeAllowNewOutgoingStreams(number_of_streams));
-
- QuicStreamId stream_id = IsUnidirectional()
- ? QuicUtils::GetFirstUnidirectionalStreamId(
- transport_version(), perspective())
- : QuicUtils::GetFirstBidirectionalStreamId(
- transport_version(), perspective());
-
- EXPECT_EQ(number_of_streams, stream_id_manager_.outgoing_max_streams());
- while (number_of_streams) {
- EXPECT_TRUE(stream_id_manager_.CanOpenNextOutgoingStream());
- EXPECT_EQ(stream_id, stream_id_manager_.GetNextOutgoingStreamId());
- stream_id += QuicUtils::StreamIdDelta(transport_version());
- number_of_streams--;
- }
-
- // If we try to check that the next outgoing stream id is available it should
- // fail.
- EXPECT_FALSE(stream_id_manager_.CanOpenNextOutgoingStream());
-
- // If we try to get the next id (above the limit), it should cause a quic-bug.
- EXPECT_QUIC_BUG(
- stream_id_manager_.GetNextOutgoingStreamId(),
- "Attempt to allocate a new outgoing stream that would exceed the limit");
-}
-
-TEST_P(QuicStreamIdManagerTest, MaybeIncreaseLargestPeerStreamId) {
- QuicStreamId max_stream_id = GetNthIncomingStreamId(
- stream_id_manager_.incoming_actual_max_streams() - 1);
- EXPECT_TRUE(stream_id_manager_.MaybeIncreaseLargestPeerStreamId(max_stream_id,
- nullptr));
-
- QuicStreamId first_stream_id = GetNthIncomingStreamId(0);
- EXPECT_TRUE(stream_id_manager_.MaybeIncreaseLargestPeerStreamId(
- first_stream_id, nullptr));
- // A bad stream ID results in a closed connection.
- std::string error_details;
- EXPECT_FALSE(stream_id_manager_.MaybeIncreaseLargestPeerStreamId(
- max_stream_id + QuicUtils::StreamIdDelta(transport_version()),
- &error_details));
- EXPECT_EQ(error_details,
- absl::StrCat(
- "Stream id ",
- max_stream_id + QuicUtils::StreamIdDelta(transport_version()),
- " would exceed stream count limit 100"));
-}
-
-TEST_P(QuicStreamIdManagerTest, MaxStreamsWindow) {
- // Open and then close a number of streams to get close to the threshold of
- // sending a MAX_STREAM_FRAME.
- int stream_count = stream_id_manager_.incoming_initial_max_open_streams() /
- GetQuicFlag(FLAGS_quic_max_streams_window_divisor) -
- 1;
-
- // Should not get a control-frame transmission since the peer should have
- // "plenty" of stream IDs to use.
- EXPECT_CALL(delegate_, SendMaxStreams(_, _)).Times(0);
-
- // Get the first incoming stream ID to try and allocate.
- QuicStreamId stream_id = GetNthIncomingStreamId(0);
- size_t old_available_incoming_streams =
- stream_id_manager_.available_incoming_streams();
- auto i = stream_count;
- while (i) {
- EXPECT_TRUE(stream_id_manager_.MaybeIncreaseLargestPeerStreamId(stream_id,
- nullptr));
-
- // This node should think that the peer believes it has one fewer
- // stream it can create.
- old_available_incoming_streams--;
- EXPECT_EQ(old_available_incoming_streams,
- stream_id_manager_.available_incoming_streams());
-
- i--;
- stream_id += QuicUtils::StreamIdDelta(transport_version());
- }
-
- // Now close them, still should get no MAX_STREAMS
- stream_id = GetNthIncomingStreamId(0);
- QuicStreamCount expected_actual_max =
- stream_id_manager_.incoming_actual_max_streams();
- QuicStreamCount expected_advertised_max_streams =
- stream_id_manager_.incoming_advertised_max_streams();
- while (stream_count) {
- stream_id_manager_.OnStreamClosed(stream_id);
- stream_count--;
- stream_id += QuicUtils::StreamIdDelta(transport_version());
- expected_actual_max++;
- EXPECT_EQ(expected_actual_max,
- stream_id_manager_.incoming_actual_max_streams());
- // Advertised maximum should remain the same.
- EXPECT_EQ(expected_advertised_max_streams,
- stream_id_manager_.incoming_advertised_max_streams());
- }
-
- // This should not change.
- EXPECT_EQ(old_available_incoming_streams,
- stream_id_manager_.available_incoming_streams());
-
- // Now whenever we close a stream we should get a MAX_STREAMS frame.
- // Above code closed all the open streams, so we have to open/close
- // EXPECT_CALL(delegate_,
- // SendMaxStreams(stream_id_manager_.incoming_actual_max_streams(),
- // IsUnidirectional()));
- EXPECT_CALL(delegate_, SendMaxStreams(_, IsUnidirectional()));
- EXPECT_TRUE(
- stream_id_manager_.MaybeIncreaseLargestPeerStreamId(stream_id, nullptr));
- stream_id_manager_.OnStreamClosed(stream_id);
-}
-
-TEST_P(QuicStreamIdManagerTest, StreamsBlockedEdgeConditions) {
- QuicStreamsBlockedFrame frame;
- frame.unidirectional = IsUnidirectional();
-
- // Check that receipt of a STREAMS BLOCKED with stream-count = 0 does nothing
- // when max_allowed_incoming_streams is 0.
- EXPECT_CALL(delegate_, SendMaxStreams(_, _)).Times(0);
- stream_id_manager_.SetMaxOpenIncomingStreams(0);
- frame.stream_count = 0;
- std::string error_details;
- EXPECT_TRUE(stream_id_manager_.OnStreamsBlockedFrame(frame, &error_details));
-
- // Check that receipt of a STREAMS BLOCKED with stream-count = 0 invokes a
- // MAX STREAMS, count = 123, when the MaxOpen... is set to 123.
- EXPECT_CALL(delegate_, SendMaxStreams(123u, IsUnidirectional()));
- QuicStreamIdManagerPeer::set_incoming_actual_max_streams(&stream_id_manager_,
- 123);
- frame.stream_count = 0;
- EXPECT_TRUE(stream_id_manager_.OnStreamsBlockedFrame(frame, &error_details));
-}
-
-// Test that a MAX_STREAMS frame is generated when half the stream ids become
-// available. This has a useful side effect of testing that when streams are
-// closed, the number of available stream ids increases.
-TEST_P(QuicStreamIdManagerTest, MaxStreamsSlidingWindow) {
- QuicStreamCount first_advert =
- stream_id_manager_.incoming_advertised_max_streams();
-
- // Open/close enough streams to shrink the window without causing a MAX
- // STREAMS to be generated. The loop
- // will make that many stream IDs available, so the last CloseStream should
- // cause a MAX STREAMS frame to be generated.
- int i =
- static_cast<int>(stream_id_manager_.incoming_initial_max_open_streams() /
- GetQuicFlag(FLAGS_quic_max_streams_window_divisor));
- QuicStreamId id =
- QuicStreamIdManagerPeer::GetFirstIncomingStreamId(&stream_id_manager_);
- EXPECT_CALL(delegate_, SendMaxStreams(first_advert + i, IsUnidirectional()));
- while (i) {
- EXPECT_TRUE(
- stream_id_manager_.MaybeIncreaseLargestPeerStreamId(id, nullptr));
- stream_id_manager_.OnStreamClosed(id);
- i--;
- id += QuicUtils::StreamIdDelta(transport_version());
- }
-}
-
-TEST_P(QuicStreamIdManagerTest, NewStreamDoesNotExceedLimit) {
- EXPECT_TRUE(stream_id_manager_.MaybeAllowNewOutgoingStreams(100));
-
- size_t stream_count = stream_id_manager_.outgoing_max_streams();
- EXPECT_NE(0u, stream_count);
-
- while (stream_count) {
- EXPECT_TRUE(stream_id_manager_.CanOpenNextOutgoingStream());
- stream_id_manager_.GetNextOutgoingStreamId();
- stream_count--;
- }
-
- EXPECT_EQ(stream_id_manager_.outgoing_stream_count(),
- stream_id_manager_.outgoing_max_streams());
- // Create another, it should fail.
- EXPECT_FALSE(stream_id_manager_.CanOpenNextOutgoingStream());
-}
-
-TEST_P(QuicStreamIdManagerTest, AvailableStreams) {
- stream_id_manager_.MaybeIncreaseLargestPeerStreamId(GetNthIncomingStreamId(3),
- nullptr);
-
- EXPECT_TRUE(stream_id_manager_.IsAvailableStream(GetNthIncomingStreamId(1)));
- EXPECT_TRUE(stream_id_manager_.IsAvailableStream(GetNthIncomingStreamId(2)));
- EXPECT_FALSE(stream_id_manager_.IsAvailableStream(GetNthIncomingStreamId(3)));
- EXPECT_TRUE(stream_id_manager_.IsAvailableStream(GetNthIncomingStreamId(4)));
-}
-
-// Tests that if MaybeIncreaseLargestPeerStreamId is given an extremely
-// large stream ID (larger than the limit) it is rejected.
-// This is a regression for Chromium bugs 909987 and 910040
-TEST_P(QuicStreamIdManagerTest, ExtremeMaybeIncreaseLargestPeerStreamId) {
- QuicStreamId too_big_stream_id = GetNthIncomingStreamId(
- stream_id_manager_.incoming_actual_max_streams() + 20);
-
- std::string error_details;
- EXPECT_FALSE(stream_id_manager_.MaybeIncreaseLargestPeerStreamId(
- too_big_stream_id, &error_details));
- EXPECT_EQ(error_details,
- absl::StrCat("Stream id ", too_big_stream_id,
- " would exceed stream count limit 100"));
-}
-
-} // namespace
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_stream_send_buffer.cc b/chromium/net/third_party/quiche/src/quic/core/quic_stream_send_buffer.cc
deleted file mode 100644
index b2ac6bfc7c4..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_stream_send_buffer.cc
+++ /dev/null
@@ -1,297 +0,0 @@
-// Copyright (c) 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <algorithm>
-
-#include "quic/core/quic_data_writer.h"
-#include "quic/core/quic_interval.h"
-#include "quic/core/quic_stream_send_buffer.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_flag_utils.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/platform/api/quic_mem_slice.h"
-
-namespace quic {
-
-namespace {
-
-struct CompareOffset {
- bool operator()(const BufferedSlice& slice, QuicStreamOffset offset) const {
- return slice.offset + slice.slice.length() < offset;
- }
-};
-
-} // namespace
-
-BufferedSlice::BufferedSlice(QuicMemSlice mem_slice, QuicStreamOffset offset)
- : slice(std::move(mem_slice)), offset(offset) {}
-
-BufferedSlice::BufferedSlice(BufferedSlice&& other) = default;
-
-BufferedSlice& BufferedSlice::operator=(BufferedSlice&& other) = default;
-
-BufferedSlice::~BufferedSlice() {}
-
-QuicInterval<std::size_t> BufferedSlice::interval() const {
- const std::size_t length = slice.length();
- return QuicInterval<std::size_t>(offset, offset + length);
-}
-
-bool StreamPendingRetransmission::operator==(
- const StreamPendingRetransmission& other) const {
- return offset == other.offset && length == other.length;
-}
-
-QuicStreamSendBuffer::QuicStreamSendBuffer(QuicBufferAllocator* allocator)
- : current_end_offset_(0),
- stream_offset_(0),
- allocator_(allocator),
- stream_bytes_written_(0),
- stream_bytes_outstanding_(0),
- write_index_(-1) {}
-
-QuicStreamSendBuffer::~QuicStreamSendBuffer() {}
-
-void QuicStreamSendBuffer::SaveStreamData(const struct iovec* iov,
- int iov_count,
- size_t iov_offset,
- QuicByteCount data_length) {
- QUICHE_DCHECK_LT(0u, data_length);
- // Latch the maximum data slice size.
- const QuicByteCount max_data_slice_size =
- GetQuicFlag(FLAGS_quic_send_buffer_max_data_slice_size);
- while (data_length > 0) {
- size_t slice_len = std::min(data_length, max_data_slice_size);
- QuicUniqueBufferPtr buffer = MakeUniqueBuffer(allocator_, slice_len);
- QuicUtils::CopyToBuffer(iov, iov_count, iov_offset, slice_len,
- buffer.get());
- SaveMemSlice(QuicMemSlice(std::move(buffer), slice_len));
- data_length -= slice_len;
- iov_offset += slice_len;
- }
-}
-
-void QuicStreamSendBuffer::SaveMemSlice(QuicMemSlice slice) {
- QUIC_DVLOG(2) << "Save slice offset " << stream_offset_ << " length "
- << slice.length();
- if (slice.empty()) {
- QUIC_BUG(quic_bug_10853_1) << "Try to save empty MemSlice to send buffer.";
- return;
- }
- size_t length = slice.length();
- // Need to start the offsets at the right interval.
- if (interval_deque_.Empty()) {
- const QuicStreamOffset end = stream_offset_ + length;
- current_end_offset_ = std::max(current_end_offset_, end);
- }
- BufferedSlice bs = BufferedSlice(std::move(slice), stream_offset_);
- interval_deque_.PushBack(std::move(bs));
- stream_offset_ += length;
-}
-
-QuicByteCount QuicStreamSendBuffer::SaveMemSliceSpan(
- absl::Span<QuicMemSlice> span) {
- QuicByteCount total = 0;
- for (QuicMemSlice& slice : span) {
- if (slice.length() == 0) {
- // Skip empty slices.
- continue;
- }
- total += slice.length();
- SaveMemSlice(std::move(slice));
- }
- return total;
-}
-
-void QuicStreamSendBuffer::OnStreamDataConsumed(size_t bytes_consumed) {
- stream_bytes_written_ += bytes_consumed;
- stream_bytes_outstanding_ += bytes_consumed;
-}
-
-bool QuicStreamSendBuffer::WriteStreamData(QuicStreamOffset offset,
- QuicByteCount data_length,
- QuicDataWriter* writer) {
- QUIC_BUG_IF(quic_bug_12823_1, current_end_offset_ < offset)
- << "Tried to write data out of sequence. last_offset_end:"
- << current_end_offset_ << ", offset:" << offset;
- // The iterator returned from |interval_deque_| will automatically advance
- // the internal write index for the QuicIntervalDeque. The incrementing is
- // done in operator++.
- for (auto slice_it = interval_deque_.DataAt(offset);
- slice_it != interval_deque_.DataEnd(); ++slice_it) {
- if (data_length == 0 || offset < slice_it->offset) {
- break;
- }
-
- QuicByteCount slice_offset = offset - slice_it->offset;
- QuicByteCount available_bytes_in_slice =
- slice_it->slice.length() - slice_offset;
- QuicByteCount copy_length = std::min(data_length, available_bytes_in_slice);
- if (!writer->WriteBytes(slice_it->slice.data() + slice_offset,
- copy_length)) {
- QUIC_BUG(quic_bug_10853_2) << "Writer fails to write.";
- return false;
- }
- offset += copy_length;
- data_length -= copy_length;
- const QuicStreamOffset new_end =
- slice_it->offset + slice_it->slice.length();
- current_end_offset_ = std::max(current_end_offset_, new_end);
- }
- return data_length == 0;
-}
-
-bool QuicStreamSendBuffer::OnStreamDataAcked(
- QuicStreamOffset offset,
- QuicByteCount data_length,
- QuicByteCount* newly_acked_length) {
- *newly_acked_length = 0;
- if (data_length == 0) {
- return true;
- }
- if (bytes_acked_.Empty() || offset >= bytes_acked_.rbegin()->max() ||
- bytes_acked_.IsDisjoint(
- QuicInterval<QuicStreamOffset>(offset, offset + data_length))) {
- // Optimization for the typical case, when all data is newly acked.
- if (stream_bytes_outstanding_ < data_length) {
- return false;
- }
- bytes_acked_.AddOptimizedForAppend(offset, offset + data_length);
- *newly_acked_length = data_length;
- stream_bytes_outstanding_ -= data_length;
- pending_retransmissions_.Difference(offset, offset + data_length);
- if (!FreeMemSlices(offset, offset + data_length)) {
- return false;
- }
- CleanUpBufferedSlices();
- return true;
- }
- // Exit if no new data gets acked.
- if (bytes_acked_.Contains(offset, offset + data_length)) {
- return true;
- }
- // Execute the slow path if newly acked data fill in existing holes.
- QuicIntervalSet<QuicStreamOffset> newly_acked(offset, offset + data_length);
- newly_acked.Difference(bytes_acked_);
- for (const auto& interval : newly_acked) {
- *newly_acked_length += (interval.max() - interval.min());
- }
- if (stream_bytes_outstanding_ < *newly_acked_length) {
- return false;
- }
- stream_bytes_outstanding_ -= *newly_acked_length;
- bytes_acked_.Add(offset, offset + data_length);
- pending_retransmissions_.Difference(offset, offset + data_length);
- if (newly_acked.Empty()) {
- return true;
- }
- if (!FreeMemSlices(newly_acked.begin()->min(), newly_acked.rbegin()->max())) {
- return false;
- }
- CleanUpBufferedSlices();
- return true;
-}
-
-void QuicStreamSendBuffer::OnStreamDataLost(QuicStreamOffset offset,
- QuicByteCount data_length) {
- if (data_length == 0) {
- return;
- }
- QuicIntervalSet<QuicStreamOffset> bytes_lost(offset, offset + data_length);
- bytes_lost.Difference(bytes_acked_);
- if (bytes_lost.Empty()) {
- return;
- }
- for (const auto& lost : bytes_lost) {
- pending_retransmissions_.Add(lost.min(), lost.max());
- }
-}
-
-void QuicStreamSendBuffer::OnStreamDataRetransmitted(
- QuicStreamOffset offset,
- QuicByteCount data_length) {
- if (data_length == 0) {
- return;
- }
- pending_retransmissions_.Difference(offset, offset + data_length);
-}
-
-bool QuicStreamSendBuffer::HasPendingRetransmission() const {
- return !pending_retransmissions_.Empty();
-}
-
-StreamPendingRetransmission QuicStreamSendBuffer::NextPendingRetransmission()
- const {
- if (HasPendingRetransmission()) {
- const auto pending = pending_retransmissions_.begin();
- return {pending->min(), pending->max() - pending->min()};
- }
- QUIC_BUG(quic_bug_10853_3)
- << "NextPendingRetransmission is called unexpected with no "
- "pending retransmissions.";
- return {0, 0};
-}
-
-bool QuicStreamSendBuffer::FreeMemSlices(QuicStreamOffset start,
- QuicStreamOffset end) {
- auto it = interval_deque_.DataBegin();
- if (it == interval_deque_.DataEnd() || it->slice.empty()) {
- QUIC_BUG(quic_bug_10853_4)
- << "Trying to ack stream data [" << start << ", " << end << "), "
- << (it == interval_deque_.DataEnd()
- ? "and there is no outstanding data."
- : "and the first slice is empty.");
- return false;
- }
- if (!it->interval().Contains(start)) {
- // Slow path that not the earliest outstanding data gets acked.
- it = std::lower_bound(interval_deque_.DataBegin(),
- interval_deque_.DataEnd(), start, CompareOffset());
- }
- if (it == interval_deque_.DataEnd() || it->slice.empty()) {
- QUIC_BUG(quic_bug_10853_5)
- << "Offset " << start << " with iterator offset: " << it->offset
- << (it == interval_deque_.DataEnd() ? " does not exist."
- : " has already been acked.");
- return false;
- }
- for (; it != interval_deque_.DataEnd(); ++it) {
- if (it->offset >= end) {
- break;
- }
- if (!it->slice.empty() &&
- bytes_acked_.Contains(it->offset, it->offset + it->slice.length())) {
- it->slice.Reset();
- }
- }
- return true;
-}
-
-void QuicStreamSendBuffer::CleanUpBufferedSlices() {
- while (!interval_deque_.Empty() &&
- interval_deque_.DataBegin()->slice.empty()) {
- QUIC_BUG_IF(quic_bug_12823_2,
- interval_deque_.DataBegin()->offset > current_end_offset_)
- << "Fail to pop front from interval_deque_. Front element contained "
- "a slice whose data has not all be written. Front offset "
- << interval_deque_.DataBegin()->offset << " length "
- << interval_deque_.DataBegin()->slice.length();
- interval_deque_.PopFront();
- }
-}
-
-bool QuicStreamSendBuffer::IsStreamDataOutstanding(
- QuicStreamOffset offset,
- QuicByteCount data_length) const {
- return data_length > 0 &&
- !bytes_acked_.Contains(offset, offset + data_length);
-}
-
-size_t QuicStreamSendBuffer::size() const {
- return interval_deque_.Size();
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_stream_send_buffer.h b/chromium/net/third_party/quiche/src/quic/core/quic_stream_send_buffer.h
deleted file mode 100644
index bf50217cefd..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_stream_send_buffer.h
+++ /dev/null
@@ -1,177 +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_CORE_QUIC_STREAM_SEND_BUFFER_H_
-#define QUICHE_QUIC_CORE_QUIC_STREAM_SEND_BUFFER_H_
-
-#include "absl/types/span.h"
-#include "quic/core/frames/quic_stream_frame.h"
-#include "quic/core/quic_interval_deque.h"
-#include "quic/core/quic_interval_set.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_iovec.h"
-#include "quic/platform/api/quic_mem_slice.h"
-#include "common/quiche_circular_deque.h"
-
-namespace quic {
-
-namespace test {
-class QuicStreamSendBufferPeer;
-class QuicStreamPeer;
-} // namespace test
-
-class QuicDataWriter;
-
-// BufferedSlice comprises information of a piece of stream data stored in
-// contiguous memory space. Please note, BufferedSlice is constructed when
-// stream data is saved in send buffer and is removed when stream data is fully
-// acked. It is move-only.
-struct QUIC_EXPORT_PRIVATE BufferedSlice {
- BufferedSlice(QuicMemSlice mem_slice, QuicStreamOffset offset);
- BufferedSlice(BufferedSlice&& other);
- BufferedSlice& operator=(BufferedSlice&& other);
-
- BufferedSlice(const BufferedSlice& other) = delete;
- BufferedSlice& operator=(const BufferedSlice& other) = delete;
- ~BufferedSlice();
-
- // Return an interval representing the offset and length.
- QuicInterval<std::size_t> interval() const;
-
- // Stream data of this data slice.
- QuicMemSlice slice;
- // Location of this data slice in the stream.
- QuicStreamOffset offset;
-};
-
-struct QUIC_EXPORT_PRIVATE StreamPendingRetransmission {
- constexpr StreamPendingRetransmission(QuicStreamOffset offset,
- QuicByteCount length)
- : offset(offset), length(length) {}
-
- // Starting offset of this pending retransmission.
- QuicStreamOffset offset;
- // Length of this pending retransmission.
- QuicByteCount length;
-
- bool operator==(const StreamPendingRetransmission& other) const;
-};
-
-// QuicStreamSendBuffer contains a list of QuicStreamDataSlices. New data slices
-// are added to the tail of the list. Data slices are removed from the head of
-// the list when they get fully acked. Stream data can be retrieved and acked
-// across slice boundaries.
-class QUIC_EXPORT_PRIVATE QuicStreamSendBuffer {
- public:
- explicit QuicStreamSendBuffer(QuicBufferAllocator* allocator);
- QuicStreamSendBuffer(const QuicStreamSendBuffer& other) = delete;
- QuicStreamSendBuffer(QuicStreamSendBuffer&& other) = delete;
- ~QuicStreamSendBuffer();
-
- // Save |data_length| of data starts at |iov_offset| in |iov| to send buffer.
- void SaveStreamData(const struct iovec* iov,
- int iov_count,
- size_t iov_offset,
- QuicByteCount data_length);
-
- // Save |slice| to send buffer.
- void SaveMemSlice(QuicMemSlice slice);
-
- // Save all slices in |span| to send buffer. Return total bytes saved.
- QuicByteCount SaveMemSliceSpan(absl::Span<QuicMemSlice> span);
-
- // Called when |bytes_consumed| bytes has been consumed by the stream.
- void OnStreamDataConsumed(size_t bytes_consumed);
-
- // Write |data_length| of data starts at |offset|.
- bool WriteStreamData(QuicStreamOffset offset,
- QuicByteCount data_length,
- QuicDataWriter* writer);
-
- // Called when data [offset, offset + data_length) is acked or removed as
- // stream is canceled. Removes fully acked data slice from send buffer. Set
- // |newly_acked_length|. Returns false if trying to ack unsent data.
- bool OnStreamDataAcked(QuicStreamOffset offset,
- QuicByteCount data_length,
- QuicByteCount* newly_acked_length);
-
- // Called when data [offset, offset + data_length) is considered as lost.
- void OnStreamDataLost(QuicStreamOffset offset, QuicByteCount data_length);
-
- // Called when data [offset, offset + length) was retransmitted.
- void OnStreamDataRetransmitted(QuicStreamOffset offset,
- QuicByteCount data_length);
-
- // Returns true if there is pending retransmissions.
- bool HasPendingRetransmission() const;
-
- // Returns next pending retransmissions.
- StreamPendingRetransmission NextPendingRetransmission() const;
-
- // Returns true if data [offset, offset + data_length) is outstanding and
- // waiting to be acked. Returns false otherwise.
- bool IsStreamDataOutstanding(QuicStreamOffset offset,
- QuicByteCount data_length) const;
-
- // Number of data slices in send buffer.
- size_t size() const;
-
- QuicStreamOffset stream_offset() const { return stream_offset_; }
-
- uint64_t stream_bytes_written() const { return stream_bytes_written_; }
-
- uint64_t stream_bytes_outstanding() const {
- return stream_bytes_outstanding_;
- }
-
- const QuicIntervalSet<QuicStreamOffset>& bytes_acked() const {
- return bytes_acked_;
- }
-
- const QuicIntervalSet<QuicStreamOffset>& pending_retransmissions() const {
- return pending_retransmissions_;
- }
-
- private:
- friend class test::QuicStreamSendBufferPeer;
- friend class test::QuicStreamPeer;
-
- // Called when data within offset [start, end) gets acked. Frees fully
- // acked buffered slices if any. Returns false if the corresponding data does
- // not exist or has been acked.
- bool FreeMemSlices(QuicStreamOffset start, QuicStreamOffset end);
-
- // Cleanup empty slices in order from buffered_slices_.
- void CleanUpBufferedSlices();
-
- // |current_end_offset_| stores the end offset of the current slice to ensure
- // data isn't being written out of order when using the |interval_deque_|.
- QuicStreamOffset current_end_offset_;
- QuicIntervalDeque<BufferedSlice> interval_deque_;
-
- // Offset of next inserted byte.
- QuicStreamOffset stream_offset_;
-
- QuicBufferAllocator* allocator_;
-
- // Bytes that have been consumed by the stream.
- uint64_t stream_bytes_written_;
-
- // Bytes that have been consumed and are waiting to be acked.
- uint64_t stream_bytes_outstanding_;
-
- // Offsets of data that has been acked.
- QuicIntervalSet<QuicStreamOffset> bytes_acked_;
-
- // Data considered as lost and needs to be retransmitted.
- QuicIntervalSet<QuicStreamOffset> pending_retransmissions_;
-
- // Index of slice which contains data waiting to be written for the first
- // time. -1 if send buffer is empty or all data has been written.
- int32_t write_index_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_QUIC_STREAM_SEND_BUFFER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_stream_send_buffer_test.cc b/chromium/net/third_party/quiche/src/quic/core/quic_stream_send_buffer_test.cc
deleted file mode 100644
index 9aaec4d2c6a..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_stream_send_buffer_test.cc
+++ /dev/null
@@ -1,350 +0,0 @@
-// Copyright (c) 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_stream_send_buffer.h"
-
-#include <string>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_data_writer.h"
-#include "quic/core/quic_simple_buffer_allocator.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_expect_bug.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/quic_stream_send_buffer_peer.h"
-#include "quic/test_tools/quic_test_utils.h"
-
-namespace quic {
-namespace test {
-namespace {
-
-struct iovec MakeIovec(absl::string_view data) {
- struct iovec iov = {const_cast<char*>(data.data()),
- static_cast<size_t>(data.size())};
- return iov;
-}
-
-class QuicStreamSendBufferTest : public QuicTest {
- public:
- QuicStreamSendBufferTest() : send_buffer_(&allocator_) {
- EXPECT_EQ(0u, send_buffer_.size());
- EXPECT_EQ(0u, send_buffer_.stream_bytes_written());
- EXPECT_EQ(0u, send_buffer_.stream_bytes_outstanding());
- std::string data1(1536, 'a');
- std::string data2 = std::string(256, 'b') + std::string(256, 'c');
- struct iovec iov[2];
- iov[0] = MakeIovec(absl::string_view(data1));
- iov[1] = MakeIovec(absl::string_view(data2));
-
- QuicBuffer buffer1(&allocator_, 1024);
- memset(buffer1.data(), 'c', buffer1.size());
- QuicMemSlice slice1(std::move(buffer1));
- QuicBuffer buffer2(&allocator_, 768);
- memset(buffer2.data(), 'd', buffer2.size());
- QuicMemSlice slice2(std::move(buffer2));
-
- // The stream offset should be 0 since nothing is written.
- EXPECT_EQ(0u, QuicStreamSendBufferPeer::EndOffset(&send_buffer_));
-
- // Save all data.
- SetQuicFlag(FLAGS_quic_send_buffer_max_data_slice_size, 1024);
- send_buffer_.SaveStreamData(iov, 2, 0, 2048);
- send_buffer_.SaveMemSlice(std::move(slice1));
- EXPECT_TRUE(slice1.empty());
- send_buffer_.SaveMemSlice(std::move(slice2));
- EXPECT_TRUE(slice2.empty());
-
- EXPECT_EQ(4u, send_buffer_.size());
- // At this point, the whole buffer looks like:
- // | a * 1536 |b * 256| c * 1280 | d * 768 |
- // | slice1 | slice2 | slice3 | slice4 |
- }
-
- void WriteAllData() {
- // Write all data.
- char buf[4000];
- QuicDataWriter writer(4000, buf, quiche::HOST_BYTE_ORDER);
- send_buffer_.WriteStreamData(0, 3840u, &writer);
-
- send_buffer_.OnStreamDataConsumed(3840u);
- EXPECT_EQ(3840u, send_buffer_.stream_bytes_written());
- EXPECT_EQ(3840u, send_buffer_.stream_bytes_outstanding());
- }
-
- SimpleBufferAllocator allocator_;
- QuicStreamSendBuffer send_buffer_;
-};
-
-TEST_F(QuicStreamSendBufferTest, CopyDataToBuffer) {
- char buf[4000];
- QuicDataWriter writer(4000, buf, quiche::HOST_BYTE_ORDER);
- std::string copy1(1024, 'a');
- std::string copy2 =
- std::string(512, 'a') + std::string(256, 'b') + std::string(256, 'c');
- std::string copy3(1024, 'c');
- std::string copy4(768, 'd');
-
- ASSERT_TRUE(send_buffer_.WriteStreamData(0, 1024, &writer));
- EXPECT_EQ(copy1, absl::string_view(buf, 1024));
- ASSERT_TRUE(send_buffer_.WriteStreamData(1024, 1024, &writer));
- EXPECT_EQ(copy2, absl::string_view(buf + 1024, 1024));
- ASSERT_TRUE(send_buffer_.WriteStreamData(2048, 1024, &writer));
- EXPECT_EQ(copy3, absl::string_view(buf + 2048, 1024));
- ASSERT_TRUE(send_buffer_.WriteStreamData(3072, 768, &writer));
- EXPECT_EQ(copy4, absl::string_view(buf + 3072, 768));
-
- // Test data piece across boundries.
- QuicDataWriter writer2(4000, buf, quiche::HOST_BYTE_ORDER);
- std::string copy5 =
- std::string(536, 'a') + std::string(256, 'b') + std::string(232, 'c');
- ASSERT_TRUE(send_buffer_.WriteStreamData(1000, 1024, &writer2));
- EXPECT_EQ(copy5, absl::string_view(buf, 1024));
- ASSERT_TRUE(send_buffer_.WriteStreamData(2500, 1024, &writer2));
- std::string copy6 = std::string(572, 'c') + std::string(452, 'd');
- EXPECT_EQ(copy6, absl::string_view(buf + 1024, 1024));
-
- // Invalid data copy.
- QuicDataWriter writer3(4000, buf, quiche::HOST_BYTE_ORDER);
- EXPECT_FALSE(send_buffer_.WriteStreamData(3000, 1024, &writer3));
- EXPECT_QUIC_BUG(send_buffer_.WriteStreamData(0, 4000, &writer3),
- "Writer fails to write.");
-
- send_buffer_.OnStreamDataConsumed(3840);
- EXPECT_EQ(3840u, send_buffer_.stream_bytes_written());
- EXPECT_EQ(3840u, send_buffer_.stream_bytes_outstanding());
-}
-
-// Regression test for b/143491027.
-TEST_F(QuicStreamSendBufferTest,
- WriteStreamDataContainsBothRetransmissionAndNewData) {
- std::string copy1(1024, 'a');
- std::string copy2 =
- std::string(512, 'a') + std::string(256, 'b') + std::string(256, 'c');
- std::string copy3 = std::string(1024, 'c') + std::string(100, 'd');
- char buf[6000];
- QuicDataWriter writer(6000, buf, quiche::HOST_BYTE_ORDER);
- // Write more than one slice.
- EXPECT_EQ(0, QuicStreamSendBufferPeer::write_index(&send_buffer_));
- ASSERT_TRUE(send_buffer_.WriteStreamData(0, 1024, &writer));
- EXPECT_EQ(copy1, absl::string_view(buf, 1024));
- EXPECT_EQ(1, QuicStreamSendBufferPeer::write_index(&send_buffer_));
-
- // Retransmit the first frame and also send new data.
- ASSERT_TRUE(send_buffer_.WriteStreamData(0, 2048, &writer));
- EXPECT_EQ(copy1 + copy2, absl::string_view(buf + 1024, 2048));
-
- // Write new data.
- EXPECT_EQ(2048u, QuicStreamSendBufferPeer::EndOffset(&send_buffer_));
- ASSERT_TRUE(send_buffer_.WriteStreamData(2048, 50, &writer));
- EXPECT_EQ(std::string(50, 'c'), absl::string_view(buf + 1024 + 2048, 50));
- EXPECT_EQ(3072u, QuicStreamSendBufferPeer::EndOffset(&send_buffer_));
- ASSERT_TRUE(send_buffer_.WriteStreamData(2048, 1124, &writer));
- EXPECT_EQ(copy3, absl::string_view(buf + 1024 + 2048 + 50, 1124));
- EXPECT_EQ(3840u, QuicStreamSendBufferPeer::EndOffset(&send_buffer_));
-}
-
-TEST_F(QuicStreamSendBufferTest, RemoveStreamFrame) {
- WriteAllData();
-
- QuicByteCount newly_acked_length;
- EXPECT_TRUE(send_buffer_.OnStreamDataAcked(1024, 1024, &newly_acked_length));
- EXPECT_EQ(1024u, newly_acked_length);
- EXPECT_EQ(4u, send_buffer_.size());
-
- EXPECT_TRUE(send_buffer_.OnStreamDataAcked(2048, 1024, &newly_acked_length));
- EXPECT_EQ(1024u, newly_acked_length);
- EXPECT_EQ(4u, send_buffer_.size());
-
- EXPECT_TRUE(send_buffer_.OnStreamDataAcked(0, 1024, &newly_acked_length));
- EXPECT_EQ(1024u, newly_acked_length);
-
- // Send buffer is cleaned up in order.
- EXPECT_EQ(1u, send_buffer_.size());
- EXPECT_TRUE(send_buffer_.OnStreamDataAcked(3072, 768, &newly_acked_length));
- EXPECT_EQ(768u, newly_acked_length);
- EXPECT_EQ(0u, send_buffer_.size());
-}
-
-TEST_F(QuicStreamSendBufferTest, RemoveStreamFrameAcrossBoundries) {
- WriteAllData();
-
- QuicByteCount newly_acked_length;
- EXPECT_TRUE(send_buffer_.OnStreamDataAcked(2024, 576, &newly_acked_length));
- EXPECT_EQ(576u, newly_acked_length);
- EXPECT_EQ(4u, send_buffer_.size());
-
- EXPECT_TRUE(send_buffer_.OnStreamDataAcked(0, 1000, &newly_acked_length));
- EXPECT_EQ(1000u, newly_acked_length);
- EXPECT_EQ(4u, send_buffer_.size());
-
- EXPECT_TRUE(send_buffer_.OnStreamDataAcked(1000, 1024, &newly_acked_length));
- EXPECT_EQ(1024u, newly_acked_length);
- // Send buffer is cleaned up in order.
- EXPECT_EQ(2u, send_buffer_.size());
-
- EXPECT_TRUE(send_buffer_.OnStreamDataAcked(2600, 1024, &newly_acked_length));
- EXPECT_EQ(1024u, newly_acked_length);
- EXPECT_EQ(1u, send_buffer_.size());
-
- EXPECT_TRUE(send_buffer_.OnStreamDataAcked(3624, 216, &newly_acked_length));
- EXPECT_EQ(216u, newly_acked_length);
- EXPECT_EQ(0u, send_buffer_.size());
-}
-
-TEST_F(QuicStreamSendBufferTest, AckStreamDataMultipleTimes) {
- WriteAllData();
- QuicByteCount newly_acked_length;
- EXPECT_TRUE(send_buffer_.OnStreamDataAcked(100, 1500, &newly_acked_length));
- EXPECT_EQ(1500u, newly_acked_length);
- EXPECT_EQ(4u, send_buffer_.size());
-
- EXPECT_TRUE(send_buffer_.OnStreamDataAcked(2000, 500, &newly_acked_length));
- EXPECT_EQ(500u, newly_acked_length);
- EXPECT_EQ(4u, send_buffer_.size());
-
- EXPECT_TRUE(send_buffer_.OnStreamDataAcked(0, 2600, &newly_acked_length));
- EXPECT_EQ(600u, newly_acked_length);
- // Send buffer is cleaned up in order.
- EXPECT_EQ(2u, send_buffer_.size());
-
- EXPECT_TRUE(send_buffer_.OnStreamDataAcked(2200, 1640, &newly_acked_length));
- EXPECT_EQ(1240u, newly_acked_length);
- EXPECT_EQ(0u, send_buffer_.size());
-
- EXPECT_FALSE(send_buffer_.OnStreamDataAcked(4000, 100, &newly_acked_length));
-}
-
-TEST_F(QuicStreamSendBufferTest, AckStreamDataOutOfOrder) {
- WriteAllData();
- QuicByteCount newly_acked_length;
- EXPECT_TRUE(send_buffer_.OnStreamDataAcked(500, 1000, &newly_acked_length));
- EXPECT_EQ(1000u, newly_acked_length);
- EXPECT_EQ(4u, send_buffer_.size());
- EXPECT_EQ(3840u, QuicStreamSendBufferPeer::TotalLength(&send_buffer_));
-
- EXPECT_TRUE(send_buffer_.OnStreamDataAcked(1200, 1000, &newly_acked_length));
- EXPECT_EQ(700u, newly_acked_length);
- EXPECT_EQ(4u, send_buffer_.size());
- // Slice 2 gets fully acked.
- EXPECT_EQ(2816u, QuicStreamSendBufferPeer::TotalLength(&send_buffer_));
-
- EXPECT_TRUE(send_buffer_.OnStreamDataAcked(2000, 1840, &newly_acked_length));
- EXPECT_EQ(1640u, newly_acked_length);
- EXPECT_EQ(4u, send_buffer_.size());
- // Slices 3 and 4 get fully acked.
- EXPECT_EQ(1024u, QuicStreamSendBufferPeer::TotalLength(&send_buffer_));
-
- EXPECT_TRUE(send_buffer_.OnStreamDataAcked(0, 1000, &newly_acked_length));
- EXPECT_EQ(500u, newly_acked_length);
- EXPECT_EQ(0u, send_buffer_.size());
- EXPECT_EQ(0u, QuicStreamSendBufferPeer::TotalLength(&send_buffer_));
-}
-
-TEST_F(QuicStreamSendBufferTest, PendingRetransmission) {
- WriteAllData();
- EXPECT_TRUE(send_buffer_.IsStreamDataOutstanding(0, 3840));
- EXPECT_FALSE(send_buffer_.HasPendingRetransmission());
- // Lost data [0, 1200).
- send_buffer_.OnStreamDataLost(0, 1200);
- // Lost data [1500, 2000).
- send_buffer_.OnStreamDataLost(1500, 500);
- EXPECT_TRUE(send_buffer_.HasPendingRetransmission());
-
- EXPECT_EQ(StreamPendingRetransmission(0, 1200),
- send_buffer_.NextPendingRetransmission());
- // Retransmit data [0, 500).
- send_buffer_.OnStreamDataRetransmitted(0, 500);
- EXPECT_TRUE(send_buffer_.IsStreamDataOutstanding(0, 500));
- EXPECT_EQ(StreamPendingRetransmission(500, 700),
- send_buffer_.NextPendingRetransmission());
- // Ack data [500, 1200).
- QuicByteCount newly_acked_length = 0;
- EXPECT_TRUE(send_buffer_.OnStreamDataAcked(500, 700, &newly_acked_length));
- EXPECT_FALSE(send_buffer_.IsStreamDataOutstanding(500, 700));
- EXPECT_TRUE(send_buffer_.HasPendingRetransmission());
- EXPECT_EQ(StreamPendingRetransmission(1500, 500),
- send_buffer_.NextPendingRetransmission());
- // Retransmit data [1500, 2000).
- send_buffer_.OnStreamDataRetransmitted(1500, 500);
- EXPECT_FALSE(send_buffer_.HasPendingRetransmission());
-
- // Lost [200, 800).
- send_buffer_.OnStreamDataLost(200, 600);
- EXPECT_TRUE(send_buffer_.HasPendingRetransmission());
- // Verify [200, 500) is considered as lost, as [500, 800) has been acked.
- EXPECT_EQ(StreamPendingRetransmission(200, 300),
- send_buffer_.NextPendingRetransmission());
-
- // Verify 0 length data is not outstanding.
- EXPECT_FALSE(send_buffer_.IsStreamDataOutstanding(100, 0));
- // Verify partially acked data is outstanding.
- EXPECT_TRUE(send_buffer_.IsStreamDataOutstanding(400, 800));
-}
-
-TEST_F(QuicStreamSendBufferTest, EndOffset) {
- char buf[4000];
- QuicDataWriter writer(4000, buf, quiche::HOST_BYTE_ORDER);
-
- EXPECT_EQ(1024u, QuicStreamSendBufferPeer::EndOffset(&send_buffer_));
- ASSERT_TRUE(send_buffer_.WriteStreamData(0, 1024, &writer));
- // Last offset we've seen is 1024
- EXPECT_EQ(1024u, QuicStreamSendBufferPeer::EndOffset(&send_buffer_));
-
- ASSERT_TRUE(send_buffer_.WriteStreamData(1024, 512, &writer));
- // Last offset is now 2048 as that's the end of the next slice.
- EXPECT_EQ(2048u, QuicStreamSendBufferPeer::EndOffset(&send_buffer_));
- send_buffer_.OnStreamDataConsumed(1024);
-
- // If data in 1st slice gets ACK'ed, it shouldn't change the indexed slice
- QuicByteCount newly_acked_length;
- EXPECT_TRUE(send_buffer_.OnStreamDataAcked(0, 1024, &newly_acked_length));
- // Last offset is still 2048.
- EXPECT_EQ(2048u, QuicStreamSendBufferPeer::EndOffset(&send_buffer_));
-
- ASSERT_TRUE(
- send_buffer_.WriteStreamData(1024 + 512, 3840 - 1024 - 512, &writer));
-
- // Last offset is end offset of last slice.
- EXPECT_EQ(3840u, QuicStreamSendBufferPeer::EndOffset(&send_buffer_));
- QuicBuffer buffer(&allocator_, 60);
- memset(buffer.data(), 'e', buffer.size());
- QuicMemSlice slice(std::move(buffer));
- send_buffer_.SaveMemSlice(std::move(slice));
-
- EXPECT_EQ(3840u, QuicStreamSendBufferPeer::EndOffset(&send_buffer_));
-}
-
-TEST_F(QuicStreamSendBufferTest, SaveMemSliceSpan) {
- SimpleBufferAllocator allocator;
- QuicStreamSendBuffer send_buffer(&allocator);
-
- std::string data(1024, 'a');
- std::vector<QuicMemSlice> buffers;
- for (size_t i = 0; i < 10; ++i) {
- buffers.push_back(MemSliceFromString(data));
- }
-
- EXPECT_EQ(10 * 1024u, send_buffer.SaveMemSliceSpan(absl::MakeSpan(buffers)));
- EXPECT_EQ(10u, send_buffer.size());
-}
-
-TEST_F(QuicStreamSendBufferTest, SaveEmptyMemSliceSpan) {
- SimpleBufferAllocator allocator;
- QuicStreamSendBuffer send_buffer(&allocator);
-
- std::string data(1024, 'a');
- std::vector<QuicMemSlice> buffers;
- for (size_t i = 0; i < 10; ++i) {
- buffers.push_back(MemSliceFromString(data));
- }
-
- EXPECT_EQ(10 * 1024u, send_buffer.SaveMemSliceSpan(absl::MakeSpan(buffers)));
- // Verify the empty slice does not get saved.
- EXPECT_EQ(10u, send_buffer.size());
-}
-
-} // namespace
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_stream_sequencer.cc b/chromium/net/third_party/quiche/src/quic/core/quic_stream_sequencer.cc
deleted file mode 100644
index 8059334fda8..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_stream_sequencer.cc
+++ /dev/null
@@ -1,312 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_stream_sequencer.h"
-
-#include <algorithm>
-#include <cstddef>
-#include <limits>
-#include <string>
-#include <utility>
-
-#include "absl/strings/str_cat.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_clock.h"
-#include "quic/core/quic_error_codes.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_stream.h"
-#include "quic/core/quic_stream_sequencer_buffer.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_flag_utils.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/platform/api/quic_stack_trace.h"
-
-namespace quic {
-
-QuicStreamSequencer::QuicStreamSequencer(StreamInterface* quic_stream)
- : stream_(quic_stream),
- buffered_frames_(kStreamReceiveWindowLimit),
- highest_offset_(0),
- close_offset_(std::numeric_limits<QuicStreamOffset>::max()),
- blocked_(false),
- num_frames_received_(0),
- num_duplicate_frames_received_(0),
- ignore_read_data_(false),
- level_triggered_(false) {}
-
-QuicStreamSequencer::~QuicStreamSequencer() {
- if (stream_ == nullptr) {
- QUIC_BUG(quic_bug_10858_1) << "Double free'ing QuicStreamSequencer at "
- << this << ". " << QuicStackTrace();
- }
- stream_ = nullptr;
-}
-
-void QuicStreamSequencer::OnStreamFrame(const QuicStreamFrame& frame) {
- QUICHE_DCHECK_LE(frame.offset + frame.data_length, close_offset_);
- ++num_frames_received_;
- const QuicStreamOffset byte_offset = frame.offset;
- const size_t data_len = frame.data_length;
-
- if (frame.fin &&
- (!CloseStreamAtOffset(frame.offset + data_len) || data_len == 0)) {
- return;
- }
- if (stream_->version().HasIetfQuicFrames() && data_len == 0) {
- QUICHE_DCHECK(!frame.fin);
- // Ignore empty frame with no fin.
- return;
- }
- OnFrameData(byte_offset, data_len, frame.data_buffer);
-}
-
-void QuicStreamSequencer::OnCryptoFrame(const QuicCryptoFrame& frame) {
- ++num_frames_received_;
- if (GetQuicReloadableFlag(quic_accept_empty_crypto_frame)) {
- QUIC_RELOADABLE_FLAG_COUNT(quic_accept_empty_crypto_frame);
- if (frame.data_length == 0) {
- // Ignore empty crypto frame.
- return;
- }
- }
- OnFrameData(frame.offset, frame.data_length, frame.data_buffer);
-}
-
-void QuicStreamSequencer::OnFrameData(QuicStreamOffset byte_offset,
- size_t data_len,
- const char* data_buffer) {
- highest_offset_ = std::max(highest_offset_, byte_offset + data_len);
- const size_t previous_readable_bytes = buffered_frames_.ReadableBytes();
- size_t bytes_written;
- std::string error_details;
- QuicErrorCode result = buffered_frames_.OnStreamData(
- byte_offset, absl::string_view(data_buffer, data_len), &bytes_written,
- &error_details);
- if (result != QUIC_NO_ERROR) {
- std::string details =
- absl::StrCat("Stream ", stream_->id(), ": ",
- QuicErrorCodeToString(result), ": ", error_details);
- QUIC_LOG_FIRST_N(WARNING, 50) << QuicErrorCodeToString(result);
- QUIC_LOG_FIRST_N(WARNING, 50) << details;
- stream_->OnUnrecoverableError(result, details);
- return;
- }
-
- if (bytes_written == 0) {
- ++num_duplicate_frames_received_;
- // Silently ignore duplicates.
- return;
- }
-
- if (blocked_) {
- return;
- }
-
- if (level_triggered_) {
- if (buffered_frames_.ReadableBytes() > previous_readable_bytes) {
- // Readable bytes has changed, let stream decide if to inform application
- // or not.
- if (ignore_read_data_) {
- FlushBufferedFrames();
- } else {
- stream_->OnDataAvailable();
- }
- }
- return;
- }
- const bool stream_unblocked =
- previous_readable_bytes == 0 && buffered_frames_.ReadableBytes() > 0;
- if (stream_unblocked) {
- if (ignore_read_data_) {
- FlushBufferedFrames();
- } else {
- stream_->OnDataAvailable();
- }
- }
-}
-
-bool QuicStreamSequencer::CloseStreamAtOffset(QuicStreamOffset offset) {
- const QuicStreamOffset kMaxOffset =
- std::numeric_limits<QuicStreamOffset>::max();
-
- // If there is a scheduled close, the new offset should match it.
- if (close_offset_ != kMaxOffset && offset != close_offset_) {
- stream_->OnUnrecoverableError(
- QUIC_STREAM_SEQUENCER_INVALID_STATE,
- absl::StrCat(
- "Stream ", stream_->id(), " received new final offset: ", offset,
- ", which is different from close offset: ", close_offset_));
- return false;
- }
-
- // The final offset should be no less than the highest offset that is
- // received.
- if (offset < highest_offset_) {
- stream_->OnUnrecoverableError(
- QUIC_STREAM_SEQUENCER_INVALID_STATE,
- absl::StrCat(
- "Stream ", stream_->id(), " received fin with offset: ", offset,
- ", which reduces current highest offset: ", highest_offset_));
- return false;
- }
-
- close_offset_ = offset;
-
- MaybeCloseStream();
- return true;
-}
-
-void QuicStreamSequencer::MaybeCloseStream() {
- if (blocked_ || !IsClosed()) {
- return;
- }
-
- QUIC_DVLOG(1) << "Passing up termination, as we've processed "
- << buffered_frames_.BytesConsumed() << " of " << close_offset_
- << " bytes.";
- // This will cause the stream to consume the FIN.
- // Technically it's an error if |num_bytes_consumed| isn't exactly
- // equal to |close_offset|, but error handling seems silly at this point.
- if (ignore_read_data_) {
- // The sequencer is discarding stream data and must notify the stream on
- // receipt of a FIN because the consumer won't.
- stream_->OnFinRead();
- } else {
- stream_->OnDataAvailable();
- }
- buffered_frames_.Clear();
-}
-
-int QuicStreamSequencer::GetReadableRegions(iovec* iov, size_t iov_len) const {
- QUICHE_DCHECK(!blocked_);
- return buffered_frames_.GetReadableRegions(iov, iov_len);
-}
-
-bool QuicStreamSequencer::GetReadableRegion(iovec* iov) const {
- QUICHE_DCHECK(!blocked_);
- return buffered_frames_.GetReadableRegion(iov);
-}
-
-bool QuicStreamSequencer::PeekRegion(QuicStreamOffset offset,
- iovec* iov) const {
- QUICHE_DCHECK(!blocked_);
- return buffered_frames_.PeekRegion(offset, iov);
-}
-
-void QuicStreamSequencer::Read(std::string* buffer) {
- QUICHE_DCHECK(!blocked_);
- buffer->resize(buffer->size() + ReadableBytes());
- iovec iov;
- iov.iov_len = ReadableBytes();
- iov.iov_base = &(*buffer)[buffer->size() - iov.iov_len];
- Readv(&iov, 1);
-}
-
-size_t QuicStreamSequencer::Readv(const struct iovec* iov, size_t iov_len) {
- QUICHE_DCHECK(!blocked_);
- std::string error_details;
- size_t bytes_read;
- QuicErrorCode read_error =
- buffered_frames_.Readv(iov, iov_len, &bytes_read, &error_details);
- if (read_error != QUIC_NO_ERROR) {
- std::string details =
- absl::StrCat("Stream ", stream_->id(), ": ", error_details);
- stream_->OnUnrecoverableError(read_error, details);
- return bytes_read;
- }
-
- stream_->AddBytesConsumed(bytes_read);
- return bytes_read;
-}
-
-bool QuicStreamSequencer::HasBytesToRead() const {
- return buffered_frames_.HasBytesToRead();
-}
-
-size_t QuicStreamSequencer::ReadableBytes() const {
- return buffered_frames_.ReadableBytes();
-}
-
-bool QuicStreamSequencer::IsClosed() const {
- return buffered_frames_.BytesConsumed() >= close_offset_;
-}
-
-void QuicStreamSequencer::MarkConsumed(size_t num_bytes_consumed) {
- QUICHE_DCHECK(!blocked_);
- bool result = buffered_frames_.MarkConsumed(num_bytes_consumed);
- if (!result) {
- QUIC_BUG(quic_bug_10858_2)
- << "Invalid argument to MarkConsumed."
- << " expect to consume: " << num_bytes_consumed
- << ", but not enough bytes available. " << DebugString();
- stream_->ResetWithError(
- QuicResetStreamError::FromInternal(QUIC_ERROR_PROCESSING_STREAM));
- return;
- }
- stream_->AddBytesConsumed(num_bytes_consumed);
-}
-
-void QuicStreamSequencer::SetBlockedUntilFlush() {
- blocked_ = true;
-}
-
-void QuicStreamSequencer::SetUnblocked() {
- blocked_ = false;
- if (IsClosed() || HasBytesToRead()) {
- stream_->OnDataAvailable();
- }
-}
-
-void QuicStreamSequencer::StopReading() {
- if (ignore_read_data_) {
- return;
- }
- ignore_read_data_ = true;
- FlushBufferedFrames();
-}
-
-void QuicStreamSequencer::ReleaseBuffer() {
- buffered_frames_.ReleaseWholeBuffer();
-}
-
-void QuicStreamSequencer::ReleaseBufferIfEmpty() {
- if (buffered_frames_.Empty()) {
- buffered_frames_.ReleaseWholeBuffer();
- }
-}
-
-void QuicStreamSequencer::FlushBufferedFrames() {
- QUICHE_DCHECK(ignore_read_data_);
- size_t bytes_flushed = buffered_frames_.FlushBufferedFrames();
- QUIC_DVLOG(1) << "Flushing buffered data at offset "
- << buffered_frames_.BytesConsumed() << " length "
- << bytes_flushed << " for stream " << stream_->id();
- stream_->AddBytesConsumed(bytes_flushed);
- MaybeCloseStream();
-}
-
-size_t QuicStreamSequencer::NumBytesBuffered() const {
- return buffered_frames_.BytesBuffered();
-}
-
-QuicStreamOffset QuicStreamSequencer::NumBytesConsumed() const {
- return buffered_frames_.BytesConsumed();
-}
-
-const std::string QuicStreamSequencer::DebugString() const {
- // clang-format off
- return absl::StrCat("QuicStreamSequencer:",
- "\n bytes buffered: ", NumBytesBuffered(),
- "\n bytes consumed: ", NumBytesConsumed(),
- "\n has bytes to read: ", HasBytesToRead() ? "true" : "false",
- "\n frames received: ", num_frames_received(),
- "\n close offset bytes: ", close_offset_,
- "\n is closed: ", IsClosed() ? "true" : "false");
- // clang-format on
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_stream_sequencer.h b/chromium/net/third_party/quiche/src/quic/core/quic_stream_sequencer.h
deleted file mode 100644
index fe96f253dad..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_stream_sequencer.h
+++ /dev/null
@@ -1,217 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_STREAM_SEQUENCER_H_
-#define QUICHE_QUIC_CORE_QUIC_STREAM_SEQUENCER_H_
-
-#include <cstddef>
-#include <map>
-#include <string>
-
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_stream_sequencer_buffer.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-namespace test {
-class QuicStreamSequencerPeer;
-} // namespace test
-
-// Buffers frames until we have something which can be passed
-// up to the next layer.
-class QUIC_EXPORT_PRIVATE QuicStreamSequencer {
- public:
- // Interface that thie Sequencer uses to communicate with the Stream.
- class QUIC_EXPORT_PRIVATE StreamInterface {
- public:
- virtual ~StreamInterface() = default;
-
- // Called when new data is available to be read from the sequencer.
- virtual void OnDataAvailable() = 0;
- // Called when the end of the stream has been read.
- virtual void OnFinRead() = 0;
- // Called when bytes have been consumed from the sequencer.
- virtual void AddBytesConsumed(QuicByteCount bytes) = 0;
- // Called when an error has occurred which should result in the stream
- // being reset.
- virtual void ResetWithError(QuicResetStreamError error) = 0;
- // Called when an error has occurred which should result in the connection
- // being closed.
- virtual void OnUnrecoverableError(QuicErrorCode error,
- const std::string& details) = 0;
- // Called when an error has occurred which should result in the connection
- // being closed, specifying the wire error code |ietf_error| explicitly.
- virtual void OnUnrecoverableError(QuicErrorCode error,
- QuicIetfTransportErrorCodes ietf_error,
- const std::string& details) = 0;
- // Returns the stream id of this stream.
- virtual QuicStreamId id() const = 0;
-
- // Returns the QUIC version being used by this stream.
- virtual ParsedQuicVersion version() const = 0;
- };
-
- explicit QuicStreamSequencer(StreamInterface* quic_stream);
- QuicStreamSequencer(const QuicStreamSequencer&) = delete;
- QuicStreamSequencer(QuicStreamSequencer&&) = default;
- QuicStreamSequencer& operator=(const QuicStreamSequencer&) = delete;
- QuicStreamSequencer& operator=(QuicStreamSequencer&&) = default;
- virtual ~QuicStreamSequencer();
-
- // If the frame is the next one we need in order to process in-order data,
- // ProcessData will be immediately called on the stream until all buffered
- // data is processed or the stream fails to consume data. Any unconsumed
- // data will be buffered. If the frame is not the next in line, it will be
- // buffered.
- void OnStreamFrame(const QuicStreamFrame& frame);
-
- // If the frame is the next one we need in order to process in-order data,
- // ProcessData will be immediately called on the crypto stream until all
- // buffered data is processed or the crypto stream fails to consume data. Any
- // unconsumed data will be buffered. If the frame is not the next in line, it
- // will be buffered.
- void OnCryptoFrame(const QuicCryptoFrame& frame);
-
- // Once data is buffered, it's up to the stream to read it when the stream
- // can handle more data. The following three functions make that possible.
-
- // Fills in up to iov_len iovecs with the next readable regions. Returns the
- // number of iovs used. Non-destructive of the underlying data.
- int GetReadableRegions(iovec* iov, size_t iov_len) const;
-
- // Fills in one iovec with the next readable region. Returns false if there
- // is no readable region available.
- bool GetReadableRegion(iovec* iov) const;
-
- // Fills in one iovec with the region starting at |offset| and returns true.
- // Returns false if no readable region is available, either because data has
- // not been received yet or has already been consumed.
- bool PeekRegion(QuicStreamOffset offset, iovec* iov) const;
-
- // Copies the data into the iov_len buffers provided. Returns the number of
- // bytes read. Any buffered data no longer in use will be released.
- // TODO(rch): remove this method and instead implement it as a helper method
- // based on GetReadableRegions and MarkConsumed.
- size_t Readv(const struct iovec* iov, size_t iov_len);
-
- // Consumes |num_bytes| data. Used in conjunction with |GetReadableRegions|
- // to do zero-copy reads.
- void MarkConsumed(size_t num_bytes);
-
- // Appends all of the readable data to |buffer| and marks all of the appended
- // data as consumed.
- void Read(std::string* buffer);
-
- // Returns true if the sequncer has bytes available for reading.
- bool HasBytesToRead() const;
-
- // Number of bytes available to read.
- size_t ReadableBytes() const;
-
- // Returns true if the sequencer has delivered the fin.
- bool IsClosed() const;
-
- // Calls |OnDataAvailable| on |stream_| if there is buffered data that can
- // be processed, and causes |OnDataAvailable| to be called as new data
- // arrives.
- void SetUnblocked();
-
- // Blocks processing of frames until |SetUnblocked| is called.
- void SetBlockedUntilFlush();
-
- // Sets the sequencer to discard all incoming data itself and not call
- // |stream_->OnDataAvailable()|. |stream_->OnFinRead()| will be called
- // automatically when the FIN is consumed (which may be immediately).
- void StopReading();
-
- // Free the memory of underlying buffer.
- void ReleaseBuffer();
-
- // Free the memory of underlying buffer when no bytes remain in it.
- void ReleaseBufferIfEmpty();
-
- // Number of bytes in the buffer right now.
- size_t NumBytesBuffered() const;
-
- // Number of bytes has been consumed.
- QuicStreamOffset NumBytesConsumed() const;
-
- QuicStreamOffset close_offset() const { return close_offset_; }
-
- int num_frames_received() const { return num_frames_received_; }
-
- int num_duplicate_frames_received() const {
- return num_duplicate_frames_received_;
- }
-
- bool ignore_read_data() const { return ignore_read_data_; }
-
- void set_level_triggered(bool level_triggered) {
- level_triggered_ = level_triggered;
- }
-
- bool level_triggered() const { return level_triggered_; }
-
- void set_stream(StreamInterface* stream) { stream_ = stream; }
-
- // Returns string describing internal state.
- const std::string DebugString() const;
-
- private:
- friend class test::QuicStreamSequencerPeer;
-
- // Deletes and records as consumed any buffered data that is now in-sequence.
- // (To be called only after StopReading has been called.)
- void FlushBufferedFrames();
-
- // Wait until we've seen 'offset' bytes, and then terminate the stream.
- // Returns true if |stream_| is still available to receive data, and false if
- // |stream_| is reset.
- bool CloseStreamAtOffset(QuicStreamOffset offset);
-
- // If we've received a FIN and have processed all remaining data, then inform
- // the stream of FIN, and clear buffers.
- void MaybeCloseStream();
-
- // Shared implementation between OnStreamFrame and OnCryptoFrame.
- void OnFrameData(QuicStreamOffset byte_offset,
- size_t data_len,
- const char* data_buffer);
-
- // The stream which owns this sequencer.
- StreamInterface* stream_;
-
- // Stores received data in offset order.
- QuicStreamSequencerBuffer buffered_frames_;
-
- // The highest offset that is received so far.
- QuicStreamOffset highest_offset_;
-
- // The offset, if any, we got a stream termination for. When this many bytes
- // have been processed, the sequencer will be closed.
- QuicStreamOffset close_offset_;
-
- // If true, the sequencer is blocked from passing data to the stream and will
- // buffer all new incoming data until FlushBufferedFrames is called.
- bool blocked_;
-
- // Count of the number of frames received.
- int num_frames_received_;
-
- // Count of the number of duplicate frames received.
- int num_duplicate_frames_received_;
-
- // If true, all incoming data will be discarded.
- bool ignore_read_data_;
-
- // If false, only call OnDataAvailable() when it becomes newly unblocked.
- // Otherwise, call OnDataAvailable() when number of readable bytes changes.
- bool level_triggered_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_QUIC_STREAM_SEQUENCER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_stream_sequencer_buffer.cc b/chromium/net/third_party/quiche/src/quic/core/quic_stream_sequencer_buffer.cc
deleted file mode 100644
index 78c55c7523d..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_stream_sequencer_buffer.cc
+++ /dev/null
@@ -1,557 +0,0 @@
-// Copyright (c) 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_stream_sequencer_buffer.h"
-
-#include <algorithm>
-#include <cstddef>
-#include <memory>
-#include <string>
-
-#include "absl/strings/str_cat.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_constants.h"
-#include "quic/core/quic_interval.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_flag_utils.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-namespace {
-
-size_t CalculateBlockCount(size_t max_capacity_bytes) {
- return (max_capacity_bytes + QuicStreamSequencerBuffer::kBlockSizeBytes - 1) /
- QuicStreamSequencerBuffer::kBlockSizeBytes;
-}
-
-// Upper limit of how many gaps allowed in buffer, which ensures a reasonable
-// number of iterations needed to find the right gap to fill when a frame
-// arrives.
-const size_t kMaxNumDataIntervalsAllowed = 2 * kMaxPacketGap;
-
-// Number of blocks allocated initially.
-constexpr size_t kInitialBlockCount = 8u;
-
-// How fast block pointers container grow in size.
-// Choose 4 to reduce the amount of reallocation.
-constexpr int kBlocksGrowthFactor = 4;
-
-} // namespace
-
-QuicStreamSequencerBuffer::QuicStreamSequencerBuffer(size_t max_capacity_bytes)
- : max_buffer_capacity_bytes_(max_capacity_bytes),
- max_blocks_count_(CalculateBlockCount(max_capacity_bytes)),
- current_blocks_count_(0u),
- total_bytes_read_(0),
- blocks_(nullptr) {
- QUICHE_DCHECK_GE(max_blocks_count_, kInitialBlockCount);
- Clear();
-}
-
-QuicStreamSequencerBuffer::~QuicStreamSequencerBuffer() {
- Clear();
-}
-
-void QuicStreamSequencerBuffer::Clear() {
- if (blocks_ != nullptr) {
- for (size_t i = 0; i < current_blocks_count_; ++i) {
- if (blocks_[i] != nullptr) {
- RetireBlock(i);
- }
- }
- }
- num_bytes_buffered_ = 0;
- bytes_received_.Clear();
- bytes_received_.Add(0, total_bytes_read_);
-}
-
-bool QuicStreamSequencerBuffer::RetireBlock(size_t index) {
- if (blocks_[index] == nullptr) {
- QUIC_BUG(quic_bug_10610_1) << "Try to retire block twice";
- return false;
- }
- delete blocks_[index];
- blocks_[index] = nullptr;
- QUIC_DVLOG(1) << "Retired block with index: " << index;
- return true;
-}
-
-void QuicStreamSequencerBuffer::MaybeAddMoreBlocks(
- QuicStreamOffset next_expected_byte) {
- if (current_blocks_count_ == max_blocks_count_) {
- return;
- }
- QuicStreamOffset last_byte = next_expected_byte - 1;
- size_t num_of_blocks_needed;
- // As long as last_byte does not wrap around, its index plus one blocks are
- // needed. Otherwise, block_count_ blocks are needed.
- if (last_byte < max_buffer_capacity_bytes_) {
- num_of_blocks_needed =
- std::max(GetBlockIndex(last_byte) + 1, kInitialBlockCount);
- } else {
- num_of_blocks_needed = max_blocks_count_;
- }
- if (current_blocks_count_ >= num_of_blocks_needed) {
- return;
- }
- size_t new_block_count = kBlocksGrowthFactor * current_blocks_count_;
- new_block_count = std::min(std::max(new_block_count, num_of_blocks_needed),
- max_blocks_count_);
- auto new_blocks = std::make_unique<BufferBlock*[]>(new_block_count);
- if (blocks_ != nullptr) {
- memcpy(new_blocks.get(), blocks_.get(),
- current_blocks_count_ * sizeof(BufferBlock*));
- }
- blocks_ = std::move(new_blocks);
- current_blocks_count_ = new_block_count;
-}
-
-QuicErrorCode QuicStreamSequencerBuffer::OnStreamData(
- QuicStreamOffset starting_offset,
- absl::string_view data,
- size_t* const bytes_buffered,
- std::string* error_details) {
- *bytes_buffered = 0;
- size_t size = data.size();
- if (size == 0) {
- *error_details = "Received empty stream frame without FIN.";
- return QUIC_EMPTY_STREAM_FRAME_NO_FIN;
- }
- // Write beyond the current range this buffer is covering.
- if (starting_offset + size > total_bytes_read_ + max_buffer_capacity_bytes_ ||
- starting_offset + size < starting_offset) {
- *error_details = "Received data beyond available range.";
- return QUIC_INTERNAL_ERROR;
- }
- if (!delay_allocation_until_new_data_) {
- MaybeAddMoreBlocks(starting_offset + size);
- }
-
- if (bytes_received_.Empty() ||
- starting_offset >= bytes_received_.rbegin()->max() ||
- bytes_received_.IsDisjoint(QuicInterval<QuicStreamOffset>(
- starting_offset, starting_offset + size))) {
- // Optimization for the typical case, when all data is newly received.
- bytes_received_.AddOptimizedForAppend(starting_offset,
- starting_offset + size);
- if (bytes_received_.Size() >= kMaxNumDataIntervalsAllowed) {
- // This frame is going to create more intervals than allowed. Stop
- // processing.
- *error_details = "Too many data intervals received for this stream.";
- return QUIC_TOO_MANY_STREAM_DATA_INTERVALS;
- }
- if (delay_allocation_until_new_data_) {
- QUIC_RELOADABLE_FLAG_COUNT_N(
- quic_delay_sequencer_buffer_allocation_until_new_data, 1, 2);
- MaybeAddMoreBlocks(starting_offset + size);
- }
-
- size_t bytes_copy = 0;
- if (!CopyStreamData(starting_offset, data, &bytes_copy, error_details)) {
- return QUIC_STREAM_SEQUENCER_INVALID_STATE;
- }
- *bytes_buffered += bytes_copy;
- num_bytes_buffered_ += *bytes_buffered;
- return QUIC_NO_ERROR;
- }
- // Slow path, received data overlaps with received data.
- QuicIntervalSet<QuicStreamOffset> newly_received(starting_offset,
- starting_offset + size);
- newly_received.Difference(bytes_received_);
- if (newly_received.Empty()) {
- return QUIC_NO_ERROR;
- }
- bytes_received_.Add(starting_offset, starting_offset + size);
- if (bytes_received_.Size() >= kMaxNumDataIntervalsAllowed) {
- // This frame is going to create more intervals than allowed. Stop
- // processing.
- *error_details = "Too many data intervals received for this stream.";
- return QUIC_TOO_MANY_STREAM_DATA_INTERVALS;
- }
- if (delay_allocation_until_new_data_) {
- QUIC_RELOADABLE_FLAG_COUNT_N(
- quic_delay_sequencer_buffer_allocation_until_new_data, 2, 2);
- MaybeAddMoreBlocks(starting_offset + size);
- }
- for (const auto& interval : newly_received) {
- const QuicStreamOffset copy_offset = interval.min();
- const QuicByteCount copy_length = interval.max() - interval.min();
- size_t bytes_copy = 0;
- if (!CopyStreamData(copy_offset,
- data.substr(copy_offset - starting_offset, copy_length),
- &bytes_copy, error_details)) {
- return QUIC_STREAM_SEQUENCER_INVALID_STATE;
- }
- *bytes_buffered += bytes_copy;
- }
- num_bytes_buffered_ += *bytes_buffered;
- return QUIC_NO_ERROR;
-}
-
-bool QuicStreamSequencerBuffer::CopyStreamData(QuicStreamOffset offset,
- absl::string_view data,
- size_t* bytes_copy,
- std::string* error_details) {
- *bytes_copy = 0;
- size_t source_remaining = data.size();
- if (source_remaining == 0) {
- return true;
- }
- const char* source = data.data();
- // Write data block by block. If corresponding block has not created yet,
- // create it first.
- // Stop when all data are written or reaches the logical end of the buffer.
- while (source_remaining > 0) {
- const size_t write_block_num = GetBlockIndex(offset);
- const size_t write_block_offset = GetInBlockOffset(offset);
- size_t current_blocks_count = current_blocks_count_;
- QUICHE_DCHECK_GT(current_blocks_count, write_block_num);
-
- size_t block_capacity = GetBlockCapacity(write_block_num);
- size_t bytes_avail = block_capacity - write_block_offset;
-
- // If this write meets the upper boundary of the buffer,
- // reduce the available free bytes.
- if (offset + bytes_avail > total_bytes_read_ + max_buffer_capacity_bytes_) {
- bytes_avail = total_bytes_read_ + max_buffer_capacity_bytes_ - offset;
- }
-
- if (write_block_num >= current_blocks_count) {
- *error_details = absl::StrCat(
- "QuicStreamSequencerBuffer error: OnStreamData() exceed array bounds."
- "write offset = ",
- offset, " write_block_num = ", write_block_num,
- " current_blocks_count_ = ", current_blocks_count);
- return false;
- }
- if (blocks_ == nullptr) {
- *error_details =
- "QuicStreamSequencerBuffer error: OnStreamData() blocks_ is null";
- return false;
- }
- if (blocks_[write_block_num] == nullptr) {
- // TODO(danzh): Investigate if using a freelist would improve performance.
- // Same as RetireBlock().
- blocks_[write_block_num] = new BufferBlock();
- }
-
- const size_t bytes_to_copy =
- std::min<size_t>(bytes_avail, source_remaining);
- char* dest = blocks_[write_block_num]->buffer + write_block_offset;
- QUIC_DVLOG(1) << "Write at offset: " << offset
- << " length: " << bytes_to_copy;
-
- if (dest == nullptr || source == nullptr) {
- *error_details = absl::StrCat(
- "QuicStreamSequencerBuffer error: OnStreamData()"
- " dest == nullptr: ",
- (dest == nullptr), " source == nullptr: ", (source == nullptr),
- " Writing at offset ", offset,
- " Received frames: ", ReceivedFramesDebugString(),
- " total_bytes_read_ = ", total_bytes_read_);
- return false;
- }
- memcpy(dest, source, bytes_to_copy);
- source += bytes_to_copy;
- source_remaining -= bytes_to_copy;
- offset += bytes_to_copy;
- *bytes_copy += bytes_to_copy;
- }
- return true;
-}
-
-QuicErrorCode QuicStreamSequencerBuffer::Readv(const iovec* dest_iov,
- size_t dest_count,
- size_t* bytes_read,
- std::string* error_details) {
- *bytes_read = 0;
- for (size_t i = 0; i < dest_count && ReadableBytes() > 0; ++i) {
- char* dest = reinterpret_cast<char*>(dest_iov[i].iov_base);
- QUICHE_DCHECK(dest != nullptr);
- size_t dest_remaining = dest_iov[i].iov_len;
- while (dest_remaining > 0 && ReadableBytes() > 0) {
- size_t block_idx = NextBlockToRead();
- size_t start_offset_in_block = ReadOffset();
- size_t block_capacity = GetBlockCapacity(block_idx);
- size_t bytes_available_in_block = std::min<size_t>(
- ReadableBytes(), block_capacity - start_offset_in_block);
- size_t bytes_to_copy =
- std::min<size_t>(bytes_available_in_block, dest_remaining);
- QUICHE_DCHECK_GT(bytes_to_copy, 0u);
- if (blocks_[block_idx] == nullptr || dest == nullptr) {
- *error_details = absl::StrCat(
- "QuicStreamSequencerBuffer error:"
- " Readv() dest == nullptr: ",
- (dest == nullptr), " blocks_[", block_idx,
- "] == nullptr: ", (blocks_[block_idx] == nullptr),
- " Received frames: ", ReceivedFramesDebugString(),
- " total_bytes_read_ = ", total_bytes_read_);
- return QUIC_STREAM_SEQUENCER_INVALID_STATE;
- }
- memcpy(dest, blocks_[block_idx]->buffer + start_offset_in_block,
- bytes_to_copy);
- dest += bytes_to_copy;
- dest_remaining -= bytes_to_copy;
- num_bytes_buffered_ -= bytes_to_copy;
- total_bytes_read_ += bytes_to_copy;
- *bytes_read += bytes_to_copy;
-
- // Retire the block if all the data is read out and no other data is
- // stored in this block.
- // In case of failing to retire a block which is ready to retire, return
- // immediately.
- if (bytes_to_copy == bytes_available_in_block) {
- bool retire_successfully = RetireBlockIfEmpty(block_idx);
- if (!retire_successfully) {
- *error_details = absl::StrCat(
- "QuicStreamSequencerBuffer error: fail to retire block ",
- block_idx,
- " as the block is already released, total_bytes_read_ = ",
- total_bytes_read_,
- " Received frames: ", ReceivedFramesDebugString());
- return QUIC_STREAM_SEQUENCER_INVALID_STATE;
- }
- }
- }
- }
-
- return QUIC_NO_ERROR;
-}
-
-int QuicStreamSequencerBuffer::GetReadableRegions(struct iovec* iov,
- int iov_len) const {
- QUICHE_DCHECK(iov != nullptr);
- QUICHE_DCHECK_GT(iov_len, 0);
-
- if (ReadableBytes() == 0) {
- iov[0].iov_base = nullptr;
- iov[0].iov_len = 0;
- return 0;
- }
-
- size_t start_block_idx = NextBlockToRead();
- QuicStreamOffset readable_offset_end = FirstMissingByte() - 1;
- QUICHE_DCHECK_GE(readable_offset_end + 1, total_bytes_read_);
- size_t end_block_offset = GetInBlockOffset(readable_offset_end);
- size_t end_block_idx = GetBlockIndex(readable_offset_end);
-
- // If readable region is within one block, deal with it seperately.
- if (start_block_idx == end_block_idx && ReadOffset() <= end_block_offset) {
- iov[0].iov_base = blocks_[start_block_idx]->buffer + ReadOffset();
- iov[0].iov_len = ReadableBytes();
- QUIC_DVLOG(1) << "Got only a single block with index: " << start_block_idx;
- return 1;
- }
-
- // Get first block
- iov[0].iov_base = blocks_[start_block_idx]->buffer + ReadOffset();
- iov[0].iov_len = GetBlockCapacity(start_block_idx) - ReadOffset();
- QUIC_DVLOG(1) << "Got first block " << start_block_idx << " with len "
- << iov[0].iov_len;
- QUICHE_DCHECK_GT(readable_offset_end + 1, total_bytes_read_ + iov[0].iov_len)
- << "there should be more available data";
-
- // Get readable regions of the rest blocks till either 2nd to last block
- // before gap is met or |iov| is filled. For these blocks, one whole block is
- // a region.
- int iov_used = 1;
- size_t block_idx = (start_block_idx + iov_used) % max_blocks_count_;
- while (block_idx != end_block_idx && iov_used < iov_len) {
- QUICHE_DCHECK(nullptr != blocks_[block_idx]);
- iov[iov_used].iov_base = blocks_[block_idx]->buffer;
- iov[iov_used].iov_len = GetBlockCapacity(block_idx);
- QUIC_DVLOG(1) << "Got block with index: " << block_idx;
- ++iov_used;
- block_idx = (start_block_idx + iov_used) % max_blocks_count_;
- }
-
- // Deal with last block if |iov| can hold more.
- if (iov_used < iov_len) {
- QUICHE_DCHECK(nullptr != blocks_[block_idx]);
- iov[iov_used].iov_base = blocks_[end_block_idx]->buffer;
- iov[iov_used].iov_len = end_block_offset + 1;
- QUIC_DVLOG(1) << "Got last block with index: " << end_block_idx;
- ++iov_used;
- }
- return iov_used;
-}
-
-bool QuicStreamSequencerBuffer::GetReadableRegion(iovec* iov) const {
- return GetReadableRegions(iov, 1) == 1;
-}
-
-bool QuicStreamSequencerBuffer::PeekRegion(QuicStreamOffset offset,
- iovec* iov) const {
- QUICHE_DCHECK(iov);
-
- if (offset < total_bytes_read_) {
- // Data at |offset| has already been consumed.
- return false;
- }
-
- if (offset >= FirstMissingByte()) {
- // Data at |offset| has not been received yet.
- return false;
- }
-
- // Beginning of region.
- size_t block_idx = GetBlockIndex(offset);
- size_t block_offset = GetInBlockOffset(offset);
- iov->iov_base = blocks_[block_idx]->buffer + block_offset;
-
- // Determine if entire block has been received.
- size_t end_block_idx = GetBlockIndex(FirstMissingByte());
- if (block_idx == end_block_idx) {
- // Only read part of block before FirstMissingByte().
- iov->iov_len = GetInBlockOffset(FirstMissingByte()) - block_offset;
- } else {
- // Read entire block.
- iov->iov_len = GetBlockCapacity(block_idx) - block_offset;
- }
-
- return true;
-}
-
-bool QuicStreamSequencerBuffer::MarkConsumed(size_t bytes_consumed) {
- if (bytes_consumed > ReadableBytes()) {
- return false;
- }
- size_t bytes_to_consume = bytes_consumed;
- while (bytes_to_consume > 0) {
- size_t block_idx = NextBlockToRead();
- size_t offset_in_block = ReadOffset();
- size_t bytes_available = std::min<size_t>(
- ReadableBytes(), GetBlockCapacity(block_idx) - offset_in_block);
- size_t bytes_read = std::min<size_t>(bytes_to_consume, bytes_available);
- total_bytes_read_ += bytes_read;
- num_bytes_buffered_ -= bytes_read;
- bytes_to_consume -= bytes_read;
- // If advanced to the end of current block and end of buffer hasn't wrapped
- // to this block yet.
- if (bytes_available == bytes_read) {
- RetireBlockIfEmpty(block_idx);
- }
- }
-
- return true;
-}
-
-size_t QuicStreamSequencerBuffer::FlushBufferedFrames() {
- size_t prev_total_bytes_read = total_bytes_read_;
- total_bytes_read_ = NextExpectedByte();
- Clear();
- return total_bytes_read_ - prev_total_bytes_read;
-}
-
-void QuicStreamSequencerBuffer::ReleaseWholeBuffer() {
- Clear();
- current_blocks_count_ = 0;
- blocks_.reset(nullptr);
-}
-
-size_t QuicStreamSequencerBuffer::ReadableBytes() const {
- return FirstMissingByte() - total_bytes_read_;
-}
-
-bool QuicStreamSequencerBuffer::HasBytesToRead() const {
- return ReadableBytes() > 0;
-}
-
-QuicStreamOffset QuicStreamSequencerBuffer::BytesConsumed() const {
- return total_bytes_read_;
-}
-
-size_t QuicStreamSequencerBuffer::BytesBuffered() const {
- return num_bytes_buffered_;
-}
-
-size_t QuicStreamSequencerBuffer::GetBlockIndex(QuicStreamOffset offset) const {
- return (offset % max_buffer_capacity_bytes_) / kBlockSizeBytes;
-}
-
-size_t QuicStreamSequencerBuffer::GetInBlockOffset(
- QuicStreamOffset offset) const {
- return (offset % max_buffer_capacity_bytes_) % kBlockSizeBytes;
-}
-
-size_t QuicStreamSequencerBuffer::ReadOffset() const {
- return GetInBlockOffset(total_bytes_read_);
-}
-
-size_t QuicStreamSequencerBuffer::NextBlockToRead() const {
- return GetBlockIndex(total_bytes_read_);
-}
-
-bool QuicStreamSequencerBuffer::RetireBlockIfEmpty(size_t block_index) {
- QUICHE_DCHECK(ReadableBytes() == 0 ||
- GetInBlockOffset(total_bytes_read_) == 0)
- << "RetireBlockIfEmpty() should only be called when advancing to next "
- << "block or a gap has been reached.";
- // If the whole buffer becomes empty, the last piece of data has been read.
- if (Empty()) {
- return RetireBlock(block_index);
- }
-
- // Check where the logical end of this buffer is.
- // Not empty if the end of circular buffer has been wrapped to this block.
- if (GetBlockIndex(NextExpectedByte() - 1) == block_index) {
- return true;
- }
-
- // Read index remains in this block, which means a gap has been reached.
- if (NextBlockToRead() == block_index) {
- if (bytes_received_.Size() > 1) {
- auto it = bytes_received_.begin();
- ++it;
- if (GetBlockIndex(it->min()) == block_index) {
- // Do not retire the block if next data interval is in this block.
- return true;
- }
- } else {
- QUIC_BUG(quic_bug_10610_2) << "Read stopped at where it shouldn't.";
- return false;
- }
- }
- return RetireBlock(block_index);
-}
-
-bool QuicStreamSequencerBuffer::Empty() const {
- return bytes_received_.Empty() ||
- (bytes_received_.Size() == 1 && total_bytes_read_ > 0 &&
- bytes_received_.begin()->max() == total_bytes_read_);
-}
-
-size_t QuicStreamSequencerBuffer::GetBlockCapacity(size_t block_index) const {
- if ((block_index + 1) == max_blocks_count_) {
- size_t result = max_buffer_capacity_bytes_ % kBlockSizeBytes;
- if (result == 0) { // whole block
- result = kBlockSizeBytes;
- }
- return result;
- } else {
- return kBlockSizeBytes;
- }
-}
-
-std::string QuicStreamSequencerBuffer::ReceivedFramesDebugString() const {
- return bytes_received_.ToString();
-}
-
-QuicStreamOffset QuicStreamSequencerBuffer::FirstMissingByte() const {
- if (bytes_received_.Empty() || bytes_received_.begin()->min() > 0) {
- // Offset 0 is not received yet.
- return 0;
- }
- return bytes_received_.begin()->max();
-}
-
-QuicStreamOffset QuicStreamSequencerBuffer::NextExpectedByte() const {
- if (bytes_received_.Empty()) {
- return 0;
- }
- return bytes_received_.rbegin()->max();
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_stream_sequencer_buffer.h b/chromium/net/third_party/quiche/src/quic/core/quic_stream_sequencer_buffer.h
deleted file mode 100644
index 83ce01bd366..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_stream_sequencer_buffer.h
+++ /dev/null
@@ -1,249 +0,0 @@
-// Copyright (c) 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_STREAM_SEQUENCER_BUFFER_H_
-#define QUICHE_QUIC_CORE_QUIC_STREAM_SEQUENCER_BUFFER_H_
-
-// QuicStreamSequencerBuffer is a circular stream buffer with random write and
-// in-sequence read. It consists of a vector of pointers pointing
-// to memory blocks created as needed and an interval set recording received
-// data.
-// - Data are written in with offset indicating where it should be in the
-// stream, and the buffer grown as needed (up to the maximum buffer capacity),
-// without expensive copying (extra blocks are allocated).
-// - Data can be read from the buffer if there is no gap before it,
-// and the buffer shrinks as the data are consumed.
-// - An upper limit on the number of blocks in the buffer provides an upper
-// bound on memory use.
-//
-// This class is thread-unsafe.
-//
-// QuicStreamSequencerBuffer maintains a concept of the readable region, which
-// contains all written data that has not been read.
-// It promises stability of the underlying memory addresses in the readable
-// region, so pointers into it can be maintained, and the offset of a pointer
-// from the start of the read region can be calculated.
-//
-// Expected Use:
-// QuicStreamSequencerBuffer buffer(2.5 * 8 * 1024);
-// std::string source(1024, 'a');
-// absl::string_view string_piece(source.data(), source.size());
-// size_t written = 0;
-// buffer.OnStreamData(800, string_piece, GetEpollClockNow(), &written);
-// source = std::string{800, 'b'};
-// absl::string_view string_piece1(source.data(), 800);
-// // Try to write to [1, 801), but should fail due to overlapping,
-// // res should be QUIC_INVALID_STREAM_DATA
-// auto res = buffer.OnStreamData(1, string_piece1, &written));
-// // write to [0, 800), res should be QUIC_NO_ERROR
-// auto res = buffer.OnStreamData(0, string_piece1, GetEpollClockNow(),
-// &written);
-//
-// // Read into a iovec array with total capacity of 120 bytes.
-// char dest[120];
-// iovec iovecs[3]{iovec{dest, 40}, iovec{dest + 40, 40},
-// iovec{dest + 80, 40}};
-// size_t read = buffer.Readv(iovecs, 3);
-//
-// // Get single readable region.
-// iovec iov;
-// buffer.GetReadableRegion(iov);
-//
-// // Get readable regions from [256, 1024) and consume some of it.
-// iovec iovs[2];
-// int iov_count = buffer.GetReadableRegions(iovs, 2);
-// // Consume some bytes in iovs, returning number of bytes having been
-// consumed.
-// size_t consumed = consume_iovs(iovs, iov_count);
-// buffer.MarkConsumed(consumed);
-
-#include <cstddef>
-#include <functional>
-#include <list>
-#include <memory>
-#include <string>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_interval_set.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_export.h"
-#include "quic/platform/api/quic_iovec.h"
-
-namespace quic {
-
-namespace test {
-class QuicStreamSequencerBufferPeer;
-} // namespace test
-
-class QUIC_EXPORT_PRIVATE QuicStreamSequencerBuffer {
- public:
- // Size of blocks used by this buffer.
- // Choose 8K to make block large enough to hold multiple frames, each of
- // which could be up to 1.5 KB.
- static const size_t kBlockSizeBytes = 8 * 1024; // 8KB
-
- // The basic storage block used by this buffer.
- struct QUIC_EXPORT_PRIVATE BufferBlock {
- char buffer[kBlockSizeBytes];
- };
-
- explicit QuicStreamSequencerBuffer(size_t max_capacity_bytes);
- QuicStreamSequencerBuffer(const QuicStreamSequencerBuffer&) = delete;
- QuicStreamSequencerBuffer(QuicStreamSequencerBuffer&&) = default;
- QuicStreamSequencerBuffer& operator=(const QuicStreamSequencerBuffer&) =
- delete;
- QuicStreamSequencerBuffer& operator=(QuicStreamSequencerBuffer&&) = default;
- ~QuicStreamSequencerBuffer();
-
- // Free the space used to buffer data.
- void Clear();
-
- // Returns true if there is nothing to read in this buffer.
- bool Empty() const;
-
- // Called to buffer new data received for this stream. If the data was
- // successfully buffered, returns QUIC_NO_ERROR and stores the number of
- // bytes buffered in |bytes_buffered|. Returns an error otherwise.
- QuicErrorCode OnStreamData(QuicStreamOffset offset,
- absl::string_view data,
- size_t* bytes_buffered,
- std::string* error_details);
-
- // Reads from this buffer into given iovec array, up to number of iov_len
- // iovec objects and returns the number of bytes read.
- QuicErrorCode Readv(const struct iovec* dest_iov,
- size_t dest_count,
- size_t* bytes_read,
- std::string* error_details);
-
- // Returns the readable region of valid data in iovec format. The readable
- // region is the buffer region where there is valid data not yet read by
- // client.
- // Returns the number of iovec entries in |iov| which were populated.
- // If the region is empty, one iovec entry with 0 length
- // is returned, and the function returns 0. If there are more readable
- // regions than |iov_size|, the function only processes the first
- // |iov_size| of them.
- int GetReadableRegions(struct iovec* iov, int iov_len) const;
-
- // Fills in one iovec with data from the next readable region.
- // Returns false if there is no readable region available.
- bool GetReadableRegion(iovec* iov) const;
-
- // Returns true and sets |*iov| to point to a region starting at |offset|.
- // Returns false if no data can be read at |offset|, which can be because data
- // has not been received yet or it is already consumed.
- // Does not consume data.
- bool PeekRegion(QuicStreamOffset offset, iovec* iov) const;
-
- // Called after GetReadableRegions() to free up |bytes_consumed| space if
- // these bytes are processed.
- // Pre-requisite: bytes_consumed <= available bytes to read.
- bool MarkConsumed(size_t bytes_consumed);
-
- // Deletes and records as consumed any buffered data and clear the buffer.
- // (To be called only after sequencer's StopReading has been called.)
- size_t FlushBufferedFrames();
-
- // Free the memory of buffered data.
- void ReleaseWholeBuffer();
-
- // Whether there are bytes can be read out.
- bool HasBytesToRead() const;
-
- // Count how many bytes have been consumed (read out of buffer).
- QuicStreamOffset BytesConsumed() const;
-
- // Count how many bytes are in buffer at this moment.
- size_t BytesBuffered() const;
-
- // Returns number of bytes available to be read out.
- size_t ReadableBytes() const;
-
- private:
- friend class test::QuicStreamSequencerBufferPeer;
-
- // Copies |data| to blocks_, sets |bytes_copy|. Returns true if the copy is
- // successful. Otherwise, sets |error_details| and returns false.
- bool CopyStreamData(QuicStreamOffset offset,
- absl::string_view data,
- size_t* bytes_copy,
- std::string* error_details);
-
- // Dispose the given buffer block.
- // After calling this method, blocks_[index] is set to nullptr
- // in order to indicate that no memory set is allocated for that block.
- // Returns true on success, false otherwise.
- bool RetireBlock(size_t index);
-
- // Should only be called after the indexed block is read till the end of the
- // block or missing data has been reached.
- // If the block at |block_index| contains no buffered data, the block
- // should be retired.
- // Returns true on success, or false otherwise.
- bool RetireBlockIfEmpty(size_t block_index);
-
- // Calculate the capacity of block at specified index.
- // Return value should be either kBlockSizeBytes for non-trailing blocks and
- // max_buffer_capacity % kBlockSizeBytes for trailing block.
- size_t GetBlockCapacity(size_t index) const;
-
- // Does not check if offset is within reasonable range.
- size_t GetBlockIndex(QuicStreamOffset offset) const;
-
- // Given an offset in the stream, return the offset from the beginning of the
- // block which contains this data.
- size_t GetInBlockOffset(QuicStreamOffset offset) const;
-
- // Get offset relative to index 0 in logical 1st block to start next read.
- size_t ReadOffset() const;
-
- // Get the index of the logical 1st block to start next read.
- size_t NextBlockToRead() const;
-
- // Returns offset of first missing byte.
- QuicStreamOffset FirstMissingByte() const;
-
- // Returns offset of highest received byte + 1.
- QuicStreamOffset NextExpectedByte() const;
-
- // Return all received frames as a string.
- std::string ReceivedFramesDebugString() const;
-
- // Resize blocks_ if more blocks are needed to accomodate bytes before
- // next_expected_byte.
- void MaybeAddMoreBlocks(QuicStreamOffset next_expected_byte);
-
- // The maximum total capacity of this buffer in byte, as constructed.
- size_t max_buffer_capacity_bytes_;
-
- // Number of blocks this buffer would have when it reaches full capacity,
- // i.e., maximal number of blocks in blocks_.
- size_t max_blocks_count_;
-
- // Number of blocks this buffer currently has.
- size_t current_blocks_count_;
-
- // Number of bytes read out of buffer.
- QuicStreamOffset total_bytes_read_;
-
- // An ordered, variable-length list of blocks, with the length limited
- // such that the number of blocks never exceeds max_blocks_count_.
- // Each list entry can hold up to kBlockSizeBytes bytes.
- std::unique_ptr<BufferBlock*[]> blocks_;
-
- // Number of bytes in buffer.
- size_t num_bytes_buffered_;
-
- // Currently received data.
- QuicIntervalSet<QuicStreamOffset> bytes_received_;
-
- bool delay_allocation_until_new_data_ = GetQuicReloadableFlag(
- quic_delay_sequencer_buffer_allocation_until_new_data);
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_QUIC_STREAM_SEQUENCER_BUFFER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_stream_sequencer_buffer_test.cc b/chromium/net/third_party/quiche/src/quic/core/quic_stream_sequencer_buffer_test.cc
deleted file mode 100644
index 212c25f7366..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_stream_sequencer_buffer_test.cc
+++ /dev/null
@@ -1,1139 +0,0 @@
-// Copyright (c) 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_stream_sequencer_buffer.h"
-
-#include <algorithm>
-#include <cstddef>
-#include <cstdint>
-#include <map>
-#include <string>
-#include <utility>
-
-#include "absl/strings/str_cat.h"
-#include "absl/strings/string_view.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/quic_stream_sequencer_buffer_peer.h"
-#include "quic/test_tools/quic_test_utils.h"
-
-namespace quic {
-
-namespace test {
-
-absl::string_view IovecToStringPiece(iovec iov) {
- return absl::string_view(reinterpret_cast<const char*>(iov.iov_base),
- iov.iov_len);
-}
-
-char GetCharFromIOVecs(size_t offset, iovec iov[], size_t count) {
- size_t start_offset = 0;
- for (size_t i = 0; i < count; i++) {
- if (iov[i].iov_len == 0) {
- continue;
- }
- size_t end_offset = start_offset + iov[i].iov_len - 1;
- if (offset >= start_offset && offset <= end_offset) {
- const char* buf = reinterpret_cast<const char*>(iov[i].iov_base);
- return buf[offset - start_offset];
- }
- start_offset += iov[i].iov_len;
- }
- QUIC_LOG(ERROR) << "Could not locate char at offset " << offset << " in "
- << count << " iovecs";
- for (size_t i = 0; i < count; ++i) {
- QUIC_LOG(ERROR) << " iov[" << i << "].iov_len = " << iov[i].iov_len;
- }
- return '\0';
-}
-
-const size_t kMaxNumGapsAllowed = 2 * kMaxPacketGap;
-
-static const size_t kBlockSizeBytes =
- QuicStreamSequencerBuffer::kBlockSizeBytes;
-using BufferBlock = QuicStreamSequencerBuffer::BufferBlock;
-
-namespace {
-
-class QuicStreamSequencerBufferTest : public QuicTest {
- public:
- void SetUp() override { Initialize(); }
-
- void ResetMaxCapacityBytes(size_t max_capacity_bytes) {
- max_capacity_bytes_ = max_capacity_bytes;
- Initialize();
- }
-
- protected:
- void Initialize() {
- buffer_ =
- std::make_unique<QuicStreamSequencerBuffer>((max_capacity_bytes_));
- helper_ = std::make_unique<QuicStreamSequencerBufferPeer>((buffer_.get()));
- }
-
- // Use 8.5 here to make sure that the buffer has more than
- // QuicStreamSequencerBuffer::kInitialBlockCount block and its end doesn't
- // align with the end of a block in order to test all the offset calculation.
- size_t max_capacity_bytes_ = 8.5 * kBlockSizeBytes;
-
- std::unique_ptr<QuicStreamSequencerBuffer> buffer_;
- std::unique_ptr<QuicStreamSequencerBufferPeer> helper_;
- size_t written_ = 0;
- std::string error_details_;
-};
-
-TEST_F(QuicStreamSequencerBufferTest, InitializeWithMaxRecvWindowSize) {
- ResetMaxCapacityBytes(16 * 1024 * 1024); // 16MB
- EXPECT_EQ(2 * 1024u, // 16MB / 8KB = 2K
- helper_->max_blocks_count());
- EXPECT_EQ(max_capacity_bytes_, helper_->max_buffer_capacity());
- EXPECT_TRUE(helper_->CheckInitialState());
-}
-
-TEST_F(QuicStreamSequencerBufferTest, InitializationWithDifferentSizes) {
- const size_t kCapacity = 16 * QuicStreamSequencerBuffer::kBlockSizeBytes;
- ResetMaxCapacityBytes(kCapacity);
- EXPECT_EQ(max_capacity_bytes_, helper_->max_buffer_capacity());
- EXPECT_TRUE(helper_->CheckInitialState());
-
- const size_t kCapacity1 = 32 * QuicStreamSequencerBuffer::kBlockSizeBytes;
- ResetMaxCapacityBytes(kCapacity1);
- EXPECT_EQ(kCapacity1, helper_->max_buffer_capacity());
- EXPECT_TRUE(helper_->CheckInitialState());
-}
-
-TEST_F(QuicStreamSequencerBufferTest, ClearOnEmpty) {
- buffer_->Clear();
- EXPECT_TRUE(helper_->CheckBufferInvariants());
-}
-
-TEST_F(QuicStreamSequencerBufferTest, OnStreamData0length) {
- QuicErrorCode error =
- buffer_->OnStreamData(800, "", &written_, &error_details_);
- EXPECT_THAT(error, IsError(QUIC_EMPTY_STREAM_FRAME_NO_FIN));
- EXPECT_TRUE(helper_->CheckBufferInvariants());
-}
-
-TEST_F(QuicStreamSequencerBufferTest, OnStreamDataWithinBlock) {
- EXPECT_FALSE(helper_->IsBufferAllocated());
- std::string source(1024, 'a');
- EXPECT_THAT(buffer_->OnStreamData(800, source, &written_, &error_details_),
- IsQuicNoError());
- BufferBlock* block_ptr = helper_->GetBlock(0);
- for (size_t i = 0; i < source.size(); ++i) {
- ASSERT_EQ('a', block_ptr->buffer[helper_->GetInBlockOffset(800) + i]);
- }
- EXPECT_EQ(2, helper_->IntervalSize());
- EXPECT_EQ(0u, helper_->ReadableBytes());
- EXPECT_EQ(1u, helper_->bytes_received().Size());
- EXPECT_EQ(800u, helper_->bytes_received().begin()->min());
- EXPECT_EQ(1824u, helper_->bytes_received().begin()->max());
- EXPECT_TRUE(helper_->CheckBufferInvariants());
- EXPECT_TRUE(helper_->IsBufferAllocated());
-}
-
-TEST_F(QuicStreamSequencerBufferTest, Move) {
- EXPECT_FALSE(helper_->IsBufferAllocated());
- std::string source(1024, 'a');
- EXPECT_THAT(buffer_->OnStreamData(800, source, &written_, &error_details_),
- IsQuicNoError());
- BufferBlock* block_ptr = helper_->GetBlock(0);
- for (size_t i = 0; i < source.size(); ++i) {
- ASSERT_EQ('a', block_ptr->buffer[helper_->GetInBlockOffset(800) + i]);
- }
-
- QuicStreamSequencerBuffer buffer2(std::move(*buffer_));
- QuicStreamSequencerBufferPeer helper2(&buffer2);
-
- EXPECT_FALSE(helper_->IsBufferAllocated());
-
- EXPECT_EQ(2, helper2.IntervalSize());
- EXPECT_EQ(0u, helper2.ReadableBytes());
- EXPECT_EQ(1u, helper2.bytes_received().Size());
- EXPECT_EQ(800u, helper2.bytes_received().begin()->min());
- EXPECT_EQ(1824u, helper2.bytes_received().begin()->max());
- EXPECT_TRUE(helper2.CheckBufferInvariants());
- EXPECT_TRUE(helper2.IsBufferAllocated());
-}
-
-TEST_F(QuicStreamSequencerBufferTest, OnStreamDataInvalidSource) {
- // Pass in an invalid source, expects to return error.
- absl::string_view source;
- source = absl::string_view(nullptr, 1024);
- EXPECT_THAT(buffer_->OnStreamData(800, source, &written_, &error_details_),
- IsError(QUIC_STREAM_SEQUENCER_INVALID_STATE));
- EXPECT_EQ(0u, error_details_.find(absl::StrCat(
- "QuicStreamSequencerBuffer error: OnStreamData() "
- "dest == nullptr: ",
- false, " source == nullptr: ", true)));
-}
-
-TEST_F(QuicStreamSequencerBufferTest, OnStreamDataWithOverlap) {
- std::string source(1024, 'a');
- // Write something into [800, 1824)
- EXPECT_THAT(buffer_->OnStreamData(800, source, &written_, &error_details_),
- IsQuicNoError());
- // Try to write to [0, 1024) and [1024, 2048).
- EXPECT_THAT(buffer_->OnStreamData(0, source, &written_, &error_details_),
- IsQuicNoError());
- EXPECT_THAT(buffer_->OnStreamData(1024, source, &written_, &error_details_),
- IsQuicNoError());
-}
-
-TEST_F(QuicStreamSequencerBufferTest,
- OnStreamDataOverlapAndDuplicateCornerCases) {
- std::string source(1024, 'a');
- // Write something into [800, 1824)
- buffer_->OnStreamData(800, source, &written_, &error_details_);
- source = std::string(800, 'b');
- std::string one_byte = "c";
- // Write [1, 801).
- EXPECT_THAT(buffer_->OnStreamData(1, source, &written_, &error_details_),
- IsQuicNoError());
- // Write [0, 800).
- EXPECT_THAT(buffer_->OnStreamData(0, source, &written_, &error_details_),
- IsQuicNoError());
- // Write [1823, 1824).
- EXPECT_THAT(buffer_->OnStreamData(1823, one_byte, &written_, &error_details_),
- IsQuicNoError());
- EXPECT_EQ(0u, written_);
- // write one byte to [1824, 1825)
- EXPECT_THAT(buffer_->OnStreamData(1824, one_byte, &written_, &error_details_),
- IsQuicNoError());
- EXPECT_TRUE(helper_->CheckBufferInvariants());
-}
-
-TEST_F(QuicStreamSequencerBufferTest, OnStreamDataWithoutOverlap) {
- std::string source(1024, 'a');
- // Write something into [800, 1824).
- EXPECT_THAT(buffer_->OnStreamData(800, source, &written_, &error_details_),
- IsQuicNoError());
- source = std::string(100, 'b');
- // Write something into [kBlockSizeBytes * 2 - 20, kBlockSizeBytes * 2 + 80).
- EXPECT_THAT(buffer_->OnStreamData(kBlockSizeBytes * 2 - 20, source, &written_,
- &error_details_),
- IsQuicNoError());
- EXPECT_EQ(3, helper_->IntervalSize());
- EXPECT_EQ(1024u + 100u, buffer_->BytesBuffered());
- EXPECT_TRUE(helper_->CheckBufferInvariants());
-}
-
-TEST_F(QuicStreamSequencerBufferTest, OnStreamDataInLongStreamWithOverlap) {
- // Assume a stream has already buffered almost 4GB.
- uint64_t total_bytes_read = pow(2, 32) - 1;
- helper_->set_total_bytes_read(total_bytes_read);
- helper_->AddBytesReceived(0, total_bytes_read);
-
- // Three new out of order frames arrive.
- const size_t kBytesToWrite = 100;
- std::string source(kBytesToWrite, 'a');
- // Frame [2^32 + 500, 2^32 + 600).
- QuicStreamOffset offset = pow(2, 32) + 500;
- EXPECT_THAT(buffer_->OnStreamData(offset, source, &written_, &error_details_),
- IsQuicNoError());
- EXPECT_EQ(2, helper_->IntervalSize());
-
- // Frame [2^32 + 700, 2^32 + 800).
- offset = pow(2, 32) + 700;
- EXPECT_THAT(buffer_->OnStreamData(offset, source, &written_, &error_details_),
- IsQuicNoError());
- EXPECT_EQ(3, helper_->IntervalSize());
-
- // Another frame [2^32 + 300, 2^32 + 400).
- offset = pow(2, 32) + 300;
- EXPECT_THAT(buffer_->OnStreamData(offset, source, &written_, &error_details_),
- IsQuicNoError());
- EXPECT_EQ(4, helper_->IntervalSize());
-}
-
-TEST_F(QuicStreamSequencerBufferTest, OnStreamDataTillEnd) {
- // Write 50 bytes to the end.
- const size_t kBytesToWrite = 50;
- std::string source(kBytesToWrite, 'a');
- EXPECT_THAT(buffer_->OnStreamData(max_capacity_bytes_ - kBytesToWrite, source,
- &written_, &error_details_),
- IsQuicNoError());
- EXPECT_EQ(50u, buffer_->BytesBuffered());
- EXPECT_TRUE(helper_->CheckBufferInvariants());
-}
-
-TEST_F(QuicStreamSequencerBufferTest, OnStreamDataTillEndCorner) {
- // Write 1 byte to the end.
- const size_t kBytesToWrite = 1;
- std::string source(kBytesToWrite, 'a');
- EXPECT_THAT(buffer_->OnStreamData(max_capacity_bytes_ - kBytesToWrite, source,
- &written_, &error_details_),
- IsQuicNoError());
- EXPECT_EQ(1u, buffer_->BytesBuffered());
- EXPECT_TRUE(helper_->CheckBufferInvariants());
-}
-
-TEST_F(QuicStreamSequencerBufferTest, OnStreamDataBeyondCapacity) {
- std::string source(60, 'a');
- EXPECT_THAT(buffer_->OnStreamData(max_capacity_bytes_ - 50, source, &written_,
- &error_details_),
- IsError(QUIC_INTERNAL_ERROR));
- EXPECT_TRUE(helper_->CheckBufferInvariants());
-
- source = "b";
- EXPECT_THAT(buffer_->OnStreamData(max_capacity_bytes_, source, &written_,
- &error_details_),
- IsError(QUIC_INTERNAL_ERROR));
- EXPECT_TRUE(helper_->CheckBufferInvariants());
-
- EXPECT_THAT(buffer_->OnStreamData(max_capacity_bytes_ * 1000, source,
- &written_, &error_details_),
- IsError(QUIC_INTERNAL_ERROR));
- EXPECT_TRUE(helper_->CheckBufferInvariants());
-
- // Disallow current_gap != gaps_.end()
- EXPECT_THAT(buffer_->OnStreamData(static_cast<QuicStreamOffset>(-1), source,
- &written_, &error_details_),
- IsError(QUIC_INTERNAL_ERROR));
- EXPECT_TRUE(helper_->CheckBufferInvariants());
-
- // Disallow offset + size overflow
- source = "bbb";
- EXPECT_THAT(buffer_->OnStreamData(static_cast<QuicStreamOffset>(-2), source,
- &written_, &error_details_),
- IsError(QUIC_INTERNAL_ERROR));
- EXPECT_TRUE(helper_->CheckBufferInvariants());
- EXPECT_EQ(0u, buffer_->BytesBuffered());
-}
-
-TEST_F(QuicStreamSequencerBufferTest, Readv100Bytes) {
- std::string source(1024, 'a');
- // Write something into [kBlockSizeBytes, kBlockSizeBytes + 1024).
- buffer_->OnStreamData(kBlockSizeBytes, source, &written_, &error_details_);
- EXPECT_FALSE(buffer_->HasBytesToRead());
- source = std::string(100, 'b');
- // Write something into [0, 100).
- buffer_->OnStreamData(0, source, &written_, &error_details_);
- EXPECT_TRUE(buffer_->HasBytesToRead());
- // Read into a iovec array with total capacity of 120 bytes.
- char dest[120];
- iovec iovecs[3]{iovec{dest, 40}, iovec{dest + 40, 40}, iovec{dest + 80, 40}};
- size_t read;
- EXPECT_THAT(buffer_->Readv(iovecs, 3, &read, &error_details_),
- IsQuicNoError());
- QUIC_LOG(ERROR) << error_details_;
- EXPECT_EQ(100u, read);
- EXPECT_EQ(100u, buffer_->BytesConsumed());
- EXPECT_EQ(source, absl::string_view(dest, read));
- // The first block should be released as its data has been read out.
- EXPECT_EQ(nullptr, helper_->GetBlock(0));
- EXPECT_TRUE(helper_->CheckBufferInvariants());
-}
-
-TEST_F(QuicStreamSequencerBufferTest, ReadvAcrossBlocks) {
- std::string source(kBlockSizeBytes + 50, 'a');
- // Write 1st block to full and extand 50 bytes to next block.
- buffer_->OnStreamData(0, source, &written_, &error_details_);
- EXPECT_EQ(source.size(), helper_->ReadableBytes());
- // Iteratively read 512 bytes from buffer_-> Overwrite dest[] each time.
- char dest[512];
- while (helper_->ReadableBytes()) {
- std::fill(dest, dest + 512, 0);
- iovec iovecs[2]{iovec{dest, 256}, iovec{dest + 256, 256}};
- size_t read;
- EXPECT_THAT(buffer_->Readv(iovecs, 2, &read, &error_details_),
- IsQuicNoError());
- }
- // The last read only reads the rest 50 bytes in 2nd block.
- EXPECT_EQ(std::string(50, 'a'), std::string(dest, 50));
- EXPECT_EQ(0, dest[50]) << "Dest[50] shouln't be filled.";
- EXPECT_EQ(source.size(), buffer_->BytesConsumed());
- EXPECT_TRUE(buffer_->Empty());
- EXPECT_TRUE(helper_->CheckBufferInvariants());
-}
-
-TEST_F(QuicStreamSequencerBufferTest, ClearAfterRead) {
- std::string source(kBlockSizeBytes + 50, 'a');
- // Write 1st block to full with 'a'.
- buffer_->OnStreamData(0, source, &written_, &error_details_);
- // Read first 512 bytes from buffer to make space at the beginning.
- char dest[512]{0};
- const iovec iov{dest, 512};
- size_t read;
- EXPECT_THAT(buffer_->Readv(&iov, 1, &read, &error_details_), IsQuicNoError());
- // Clear() should make buffer empty while preserving BytesConsumed()
- buffer_->Clear();
- EXPECT_TRUE(buffer_->Empty());
- EXPECT_TRUE(helper_->CheckBufferInvariants());
-}
-
-TEST_F(QuicStreamSequencerBufferTest,
- OnStreamDataAcrossLastBlockAndFillCapacity) {
- std::string source(kBlockSizeBytes + 50, 'a');
- // Write 1st block to full with 'a'.
- buffer_->OnStreamData(0, source, &written_, &error_details_);
- // Read first 512 bytes from buffer to make space at the beginning.
- char dest[512]{0};
- const iovec iov{dest, 512};
- size_t read;
- EXPECT_THAT(buffer_->Readv(&iov, 1, &read, &error_details_), IsQuicNoError());
- EXPECT_EQ(source.size(), written_);
-
- // Write more than half block size of bytes in the last block with 'b', which
- // will wrap to the beginning and reaches the full capacity.
- source = std::string(0.5 * kBlockSizeBytes + 512, 'b');
- EXPECT_THAT(buffer_->OnStreamData(2 * kBlockSizeBytes, source, &written_,
- &error_details_),
- IsQuicNoError());
- EXPECT_EQ(source.size(), written_);
- EXPECT_TRUE(helper_->CheckBufferInvariants());
-}
-
-TEST_F(QuicStreamSequencerBufferTest,
- OnStreamDataAcrossLastBlockAndExceedCapacity) {
- std::string source(kBlockSizeBytes + 50, 'a');
- // Write 1st block to full.
- buffer_->OnStreamData(0, source, &written_, &error_details_);
- // Read first 512 bytes from buffer to make space at the beginning.
- char dest[512]{0};
- const iovec iov{dest, 512};
- size_t read;
- EXPECT_THAT(buffer_->Readv(&iov, 1, &read, &error_details_), IsQuicNoError());
-
- // Try to write from [max_capacity_bytes_ - 0.5 * kBlockSizeBytes,
- // max_capacity_bytes_ + 512 + 1). But last bytes exceeds current capacity.
- source = std::string(0.5 * kBlockSizeBytes + 512 + 1, 'b');
- EXPECT_THAT(buffer_->OnStreamData(8 * kBlockSizeBytes, source, &written_,
- &error_details_),
- IsError(QUIC_INTERNAL_ERROR));
- EXPECT_TRUE(helper_->CheckBufferInvariants());
-}
-
-TEST_F(QuicStreamSequencerBufferTest, ReadvAcrossLastBlock) {
- // Write to full capacity and read out 512 bytes at beginning and continue
- // appending 256 bytes.
- std::string source(max_capacity_bytes_, 'a');
- buffer_->OnStreamData(0, source, &written_, &error_details_);
- char dest[512]{0};
- const iovec iov{dest, 512};
- size_t read;
- EXPECT_THAT(buffer_->Readv(&iov, 1, &read, &error_details_), IsQuicNoError());
- source = std::string(256, 'b');
- buffer_->OnStreamData(max_capacity_bytes_, source, &written_,
- &error_details_);
- EXPECT_TRUE(helper_->CheckBufferInvariants());
-
- // Read all data out.
- std::unique_ptr<char[]> dest1{new char[max_capacity_bytes_]};
- dest1[0] = 0;
- const iovec iov1{dest1.get(), max_capacity_bytes_};
- EXPECT_THAT(buffer_->Readv(&iov1, 1, &read, &error_details_),
- IsQuicNoError());
- EXPECT_EQ(max_capacity_bytes_ - 512 + 256, read);
- EXPECT_EQ(max_capacity_bytes_ + 256, buffer_->BytesConsumed());
- EXPECT_TRUE(buffer_->Empty());
- EXPECT_TRUE(helper_->CheckBufferInvariants());
-}
-
-TEST_F(QuicStreamSequencerBufferTest, ReadvEmpty) {
- char dest[512]{0};
- iovec iov{dest, 512};
- size_t read;
- EXPECT_THAT(buffer_->Readv(&iov, 1, &read, &error_details_), IsQuicNoError());
- EXPECT_EQ(0u, read);
- EXPECT_TRUE(helper_->CheckBufferInvariants());
-}
-
-TEST_F(QuicStreamSequencerBufferTest, GetReadableRegionsEmpty) {
- iovec iovs[2];
- int iov_count = buffer_->GetReadableRegions(iovs, 2);
- EXPECT_EQ(0, iov_count);
- EXPECT_EQ(nullptr, iovs[iov_count].iov_base);
- EXPECT_EQ(0u, iovs[iov_count].iov_len);
-}
-
-TEST_F(QuicStreamSequencerBufferTest, ReleaseWholeBuffer) {
- // Tests that buffer is not deallocated unless ReleaseWholeBuffer() is called.
- std::string source(100, 'b');
- // Write something into [0, 100).
- buffer_->OnStreamData(0, source, &written_, &error_details_);
- EXPECT_TRUE(buffer_->HasBytesToRead());
- char dest[120];
- iovec iovecs[3]{iovec{dest, 40}, iovec{dest + 40, 40}, iovec{dest + 80, 40}};
- size_t read;
- EXPECT_THAT(buffer_->Readv(iovecs, 3, &read, &error_details_),
- IsQuicNoError());
- EXPECT_EQ(100u, read);
- EXPECT_EQ(100u, buffer_->BytesConsumed());
- EXPECT_TRUE(helper_->CheckBufferInvariants());
- EXPECT_TRUE(helper_->IsBufferAllocated());
- buffer_->ReleaseWholeBuffer();
- EXPECT_FALSE(helper_->IsBufferAllocated());
-}
-
-TEST_F(QuicStreamSequencerBufferTest, GetReadableRegionsBlockedByGap) {
- // Write into [1, 1024).
- std::string source(1023, 'a');
- buffer_->OnStreamData(1, source, &written_, &error_details_);
- // Try to get readable regions, but none is there.
- iovec iovs[2];
- int iov_count = buffer_->GetReadableRegions(iovs, 2);
- EXPECT_EQ(0, iov_count);
-}
-
-TEST_F(QuicStreamSequencerBufferTest, GetReadableRegionsTillEndOfBlock) {
- // Write first block to full with [0, 256) 'a' and the rest 'b' then read out
- // [0, 256)
- std::string source(kBlockSizeBytes, 'a');
- buffer_->OnStreamData(0, source, &written_, &error_details_);
- char dest[256];
- helper_->Read(dest, 256);
- // Get readable region from [256, 1024)
- iovec iovs[2];
- int iov_count = buffer_->GetReadableRegions(iovs, 2);
- EXPECT_EQ(1, iov_count);
- EXPECT_EQ(std::string(kBlockSizeBytes - 256, 'a'),
- IovecToStringPiece(iovs[0]));
-}
-
-TEST_F(QuicStreamSequencerBufferTest, GetReadableRegionsWithinOneBlock) {
- // Write into [0, 1024) and then read out [0, 256)
- std::string source(1024, 'a');
- buffer_->OnStreamData(0, source, &written_, &error_details_);
- char dest[256];
- helper_->Read(dest, 256);
- // Get readable region from [256, 1024)
- iovec iovs[2];
- int iov_count = buffer_->GetReadableRegions(iovs, 2);
- EXPECT_EQ(1, iov_count);
- EXPECT_EQ(std::string(1024 - 256, 'a'), IovecToStringPiece(iovs[0]));
-}
-
-TEST_F(QuicStreamSequencerBufferTest,
- GetReadableRegionsAcrossBlockWithLongIOV) {
- // Write into [0, 2 * kBlockSizeBytes + 1024) and then read out [0, 1024)
- std::string source(2 * kBlockSizeBytes + 1024, 'a');
- buffer_->OnStreamData(0, source, &written_, &error_details_);
- char dest[1024];
- helper_->Read(dest, 1024);
-
- iovec iovs[4];
- int iov_count = buffer_->GetReadableRegions(iovs, 4);
- EXPECT_EQ(3, iov_count);
- EXPECT_EQ(kBlockSizeBytes - 1024, iovs[0].iov_len);
- EXPECT_EQ(kBlockSizeBytes, iovs[1].iov_len);
- EXPECT_EQ(1024u, iovs[2].iov_len);
-}
-
-TEST_F(QuicStreamSequencerBufferTest,
- GetReadableRegionsWithMultipleIOVsAcrossEnd) {
- // Write into [0, 8.5 * kBlockSizeBytes - 1024) and then read out [0, 1024)
- // and then append 1024 + 512 bytes.
- std::string source(8.5 * kBlockSizeBytes - 1024, 'a');
- buffer_->OnStreamData(0, source, &written_, &error_details_);
- char dest[1024];
- helper_->Read(dest, 1024);
- // Write across the end.
- source = std::string(1024 + 512, 'b');
- buffer_->OnStreamData(8.5 * kBlockSizeBytes - 1024, source, &written_,
- &error_details_);
- // Use short iovec's.
- iovec iovs[2];
- int iov_count = buffer_->GetReadableRegions(iovs, 2);
- EXPECT_EQ(2, iov_count);
- EXPECT_EQ(kBlockSizeBytes - 1024, iovs[0].iov_len);
- EXPECT_EQ(kBlockSizeBytes, iovs[1].iov_len);
- // Use long iovec's and wrap the end of buffer.
- iovec iovs1[11];
- EXPECT_EQ(10, buffer_->GetReadableRegions(iovs1, 11));
- EXPECT_EQ(0.5 * kBlockSizeBytes, iovs1[8].iov_len);
- EXPECT_EQ(512u, iovs1[9].iov_len);
- EXPECT_EQ(std::string(512, 'b'), IovecToStringPiece(iovs1[9]));
-}
-
-TEST_F(QuicStreamSequencerBufferTest, GetReadableRegionEmpty) {
- iovec iov;
- EXPECT_FALSE(buffer_->GetReadableRegion(&iov));
- EXPECT_EQ(nullptr, iov.iov_base);
- EXPECT_EQ(0u, iov.iov_len);
-}
-
-TEST_F(QuicStreamSequencerBufferTest, GetReadableRegionBeforeGap) {
- // Write into [1, 1024).
- std::string source(1023, 'a');
- buffer_->OnStreamData(1, source, &written_, &error_details_);
- // GetReadableRegion should return false because range [0,1) hasn't been
- // filled yet.
- iovec iov;
- EXPECT_FALSE(buffer_->GetReadableRegion(&iov));
-}
-
-TEST_F(QuicStreamSequencerBufferTest, GetReadableRegionTillEndOfBlock) {
- // Write into [0, kBlockSizeBytes + 1) and then read out [0, 256)
- std::string source(kBlockSizeBytes + 1, 'a');
- buffer_->OnStreamData(0, source, &written_, &error_details_);
- char dest[256];
- helper_->Read(dest, 256);
- // Get readable region from [256, 1024)
- iovec iov;
- EXPECT_TRUE(buffer_->GetReadableRegion(&iov));
- EXPECT_EQ(std::string(kBlockSizeBytes - 256, 'a'), IovecToStringPiece(iov));
-}
-
-TEST_F(QuicStreamSequencerBufferTest, GetReadableRegionTillGap) {
- // Write into [0, kBlockSizeBytes - 1) and then read out [0, 256)
- std::string source(kBlockSizeBytes - 1, 'a');
- buffer_->OnStreamData(0, source, &written_, &error_details_);
- char dest[256];
- helper_->Read(dest, 256);
- // Get readable region from [256, 1023)
- iovec iov;
- EXPECT_TRUE(buffer_->GetReadableRegion(&iov));
- EXPECT_EQ(std::string(kBlockSizeBytes - 1 - 256, 'a'),
- IovecToStringPiece(iov));
-}
-
-TEST_F(QuicStreamSequencerBufferTest, PeekEmptyBuffer) {
- iovec iov;
- EXPECT_FALSE(buffer_->PeekRegion(0, &iov));
- EXPECT_FALSE(buffer_->PeekRegion(1, &iov));
- EXPECT_FALSE(buffer_->PeekRegion(100, &iov));
-}
-
-TEST_F(QuicStreamSequencerBufferTest, PeekSingleBlock) {
- std::string source(kBlockSizeBytes, 'a');
- buffer_->OnStreamData(0, source, &written_, &error_details_);
-
- iovec iov;
- EXPECT_TRUE(buffer_->PeekRegion(0, &iov));
- EXPECT_EQ(source, IovecToStringPiece(iov));
-
- // Peeking again gives the same result.
- EXPECT_TRUE(buffer_->PeekRegion(0, &iov));
- EXPECT_EQ(source, IovecToStringPiece(iov));
-
- // Peek at a different offset.
- EXPECT_TRUE(buffer_->PeekRegion(100, &iov));
- EXPECT_EQ(absl::string_view(source).substr(100), IovecToStringPiece(iov));
-
- // Peeking at or after FirstMissingByte() returns false.
- EXPECT_FALSE(buffer_->PeekRegion(kBlockSizeBytes, &iov));
- EXPECT_FALSE(buffer_->PeekRegion(kBlockSizeBytes + 1, &iov));
-}
-
-TEST_F(QuicStreamSequencerBufferTest, PeekTwoWritesInSingleBlock) {
- const size_t length1 = 1024;
- std::string source1(length1, 'a');
- buffer_->OnStreamData(0, source1, &written_, &error_details_);
-
- iovec iov;
- EXPECT_TRUE(buffer_->PeekRegion(0, &iov));
- EXPECT_EQ(source1, IovecToStringPiece(iov));
-
- // The second frame goes into the same block.
- const size_t length2 = 800;
- std::string source2(length2, 'b');
- buffer_->OnStreamData(length1, source2, &written_, &error_details_);
-
- EXPECT_TRUE(buffer_->PeekRegion(length1, &iov));
- EXPECT_EQ(source2, IovecToStringPiece(iov));
-
- // Peek with an offset inside the first write.
- const QuicStreamOffset offset1 = 500;
- EXPECT_TRUE(buffer_->PeekRegion(offset1, &iov));
- EXPECT_EQ(absl::string_view(source1).substr(offset1),
- IovecToStringPiece(iov).substr(0, length1 - offset1));
- EXPECT_EQ(absl::string_view(source2),
- IovecToStringPiece(iov).substr(length1 - offset1));
-
- // Peek with an offset inside the second write.
- const QuicStreamOffset offset2 = 1500;
- EXPECT_TRUE(buffer_->PeekRegion(offset2, &iov));
- EXPECT_EQ(absl::string_view(source2).substr(offset2 - length1),
- IovecToStringPiece(iov));
-
- // Peeking at or after FirstMissingByte() returns false.
- EXPECT_FALSE(buffer_->PeekRegion(length1 + length2, &iov));
- EXPECT_FALSE(buffer_->PeekRegion(length1 + length2 + 1, &iov));
-}
-
-TEST_F(QuicStreamSequencerBufferTest, PeekBufferWithMultipleBlocks) {
- const size_t length1 = 1024;
- std::string source1(length1, 'a');
- buffer_->OnStreamData(0, source1, &written_, &error_details_);
-
- iovec iov;
- EXPECT_TRUE(buffer_->PeekRegion(0, &iov));
- EXPECT_EQ(source1, IovecToStringPiece(iov));
-
- const size_t length2 = kBlockSizeBytes + 2;
- std::string source2(length2, 'b');
- buffer_->OnStreamData(length1, source2, &written_, &error_details_);
-
- // Peek with offset 0 returns the entire block.
- EXPECT_TRUE(buffer_->PeekRegion(0, &iov));
- EXPECT_EQ(kBlockSizeBytes, iov.iov_len);
- EXPECT_EQ(source1, IovecToStringPiece(iov).substr(0, length1));
- EXPECT_EQ(absl::string_view(source2).substr(0, kBlockSizeBytes - length1),
- IovecToStringPiece(iov).substr(length1));
-
- EXPECT_TRUE(buffer_->PeekRegion(length1, &iov));
- EXPECT_EQ(absl::string_view(source2).substr(0, kBlockSizeBytes - length1),
- IovecToStringPiece(iov));
-
- EXPECT_TRUE(buffer_->PeekRegion(kBlockSizeBytes, &iov));
- EXPECT_EQ(absl::string_view(source2).substr(kBlockSizeBytes - length1),
- IovecToStringPiece(iov));
-
- // Peeking at or after FirstMissingByte() returns false.
- EXPECT_FALSE(buffer_->PeekRegion(length1 + length2, &iov));
- EXPECT_FALSE(buffer_->PeekRegion(length1 + length2 + 1, &iov));
-}
-
-TEST_F(QuicStreamSequencerBufferTest, PeekAfterConsumed) {
- std::string source1(kBlockSizeBytes, 'a');
- buffer_->OnStreamData(0, source1, &written_, &error_details_);
-
- iovec iov;
- EXPECT_TRUE(buffer_->PeekRegion(0, &iov));
- EXPECT_EQ(source1, IovecToStringPiece(iov));
-
- // Consume some data.
- EXPECT_TRUE(buffer_->MarkConsumed(1024));
-
- // Peeking into consumed data fails.
- EXPECT_FALSE(buffer_->PeekRegion(0, &iov));
- EXPECT_FALSE(buffer_->PeekRegion(512, &iov));
-
- EXPECT_TRUE(buffer_->PeekRegion(1024, &iov));
- EXPECT_EQ(absl::string_view(source1).substr(1024), IovecToStringPiece(iov));
-
- EXPECT_TRUE(buffer_->PeekRegion(1500, &iov));
- EXPECT_EQ(absl::string_view(source1).substr(1500), IovecToStringPiece(iov));
-
- // Consume rest of block.
- EXPECT_TRUE(buffer_->MarkConsumed(kBlockSizeBytes - 1024));
-
- // Read new data.
- std::string source2(300, 'b');
- buffer_->OnStreamData(kBlockSizeBytes, source2, &written_, &error_details_);
-
- // Peek into new data.
- EXPECT_TRUE(buffer_->PeekRegion(kBlockSizeBytes, &iov));
- EXPECT_EQ(source2, IovecToStringPiece(iov));
-
- EXPECT_TRUE(buffer_->PeekRegion(kBlockSizeBytes + 128, &iov));
- EXPECT_EQ(absl::string_view(source2).substr(128), IovecToStringPiece(iov));
-
- // Peeking into consumed data still fails.
- EXPECT_FALSE(buffer_->PeekRegion(0, &iov));
- EXPECT_FALSE(buffer_->PeekRegion(512, &iov));
- EXPECT_FALSE(buffer_->PeekRegion(1024, &iov));
- EXPECT_FALSE(buffer_->PeekRegion(1500, &iov));
-}
-
-TEST_F(QuicStreamSequencerBufferTest, PeekContinously) {
- std::string source1(kBlockSizeBytes, 'a');
- buffer_->OnStreamData(0, source1, &written_, &error_details_);
-
- iovec iov;
- EXPECT_TRUE(buffer_->PeekRegion(0, &iov));
- EXPECT_EQ(source1, IovecToStringPiece(iov));
-
- std::string source2(kBlockSizeBytes, 'b');
- buffer_->OnStreamData(kBlockSizeBytes, source2, &written_, &error_details_);
-
- EXPECT_TRUE(buffer_->PeekRegion(kBlockSizeBytes, &iov));
- EXPECT_EQ(source2, IovecToStringPiece(iov));
-
- // First block is still there.
- EXPECT_TRUE(buffer_->PeekRegion(0, &iov));
- EXPECT_EQ(source1, IovecToStringPiece(iov));
-}
-
-TEST_F(QuicStreamSequencerBufferTest, MarkConsumedInOneBlock) {
- // Write into [0, 1024) and then read out [0, 256)
- std::string source(1024, 'a');
- buffer_->OnStreamData(0, source, &written_, &error_details_);
- char dest[256];
- helper_->Read(dest, 256);
-
- EXPECT_TRUE(buffer_->MarkConsumed(512));
- EXPECT_EQ(256u + 512u, buffer_->BytesConsumed());
- EXPECT_EQ(256u, helper_->ReadableBytes());
- buffer_->MarkConsumed(256);
- EXPECT_TRUE(buffer_->Empty());
- EXPECT_TRUE(helper_->CheckBufferInvariants());
-}
-
-TEST_F(QuicStreamSequencerBufferTest, MarkConsumedNotEnoughBytes) {
- // Write into [0, 1024) and then read out [0, 256)
- std::string source(1024, 'a');
- buffer_->OnStreamData(0, source, &written_, &error_details_);
- char dest[256];
- helper_->Read(dest, 256);
-
- // Consume 1st 512 bytes
- EXPECT_TRUE(buffer_->MarkConsumed(512));
- EXPECT_EQ(256u + 512u, buffer_->BytesConsumed());
- EXPECT_EQ(256u, helper_->ReadableBytes());
- // Try to consume one bytes more than available. Should return false.
- EXPECT_FALSE(buffer_->MarkConsumed(257));
- EXPECT_EQ(256u + 512u, buffer_->BytesConsumed());
- iovec iov;
- EXPECT_TRUE(buffer_->GetReadableRegion(&iov));
- EXPECT_TRUE(helper_->CheckBufferInvariants());
-}
-
-TEST_F(QuicStreamSequencerBufferTest, MarkConsumedAcrossBlock) {
- // Write into [0, 2 * kBlockSizeBytes + 1024) and then read out [0, 1024)
- std::string source(2 * kBlockSizeBytes + 1024, 'a');
- buffer_->OnStreamData(0, source, &written_, &error_details_);
- char dest[1024];
- helper_->Read(dest, 1024);
-
- buffer_->MarkConsumed(2 * kBlockSizeBytes);
- EXPECT_EQ(source.size(), buffer_->BytesConsumed());
- EXPECT_TRUE(buffer_->Empty());
- EXPECT_TRUE(helper_->CheckBufferInvariants());
-}
-
-TEST_F(QuicStreamSequencerBufferTest, MarkConsumedAcrossEnd) {
- // Write into [0, 8.5 * kBlockSizeBytes - 1024) and then read out [0, 1024)
- // and then append 1024 + 512 bytes.
- std::string source(8.5 * kBlockSizeBytes - 1024, 'a');
- buffer_->OnStreamData(0, source, &written_, &error_details_);
- char dest[1024];
- helper_->Read(dest, 1024);
- source = std::string(1024 + 512, 'b');
- buffer_->OnStreamData(8.5 * kBlockSizeBytes - 1024, source, &written_,
- &error_details_);
- EXPECT_EQ(1024u, buffer_->BytesConsumed());
-
- // Consume to the end of 8th block.
- buffer_->MarkConsumed(8 * kBlockSizeBytes - 1024);
- EXPECT_EQ(8 * kBlockSizeBytes, buffer_->BytesConsumed());
- // Consume across the physical end of buffer
- buffer_->MarkConsumed(0.5 * kBlockSizeBytes + 500);
- EXPECT_EQ(max_capacity_bytes_ + 500, buffer_->BytesConsumed());
- EXPECT_EQ(12u, helper_->ReadableBytes());
- // Consume to the logical end of buffer
- buffer_->MarkConsumed(12);
- EXPECT_EQ(max_capacity_bytes_ + 512, buffer_->BytesConsumed());
- EXPECT_TRUE(buffer_->Empty());
- EXPECT_TRUE(helper_->CheckBufferInvariants());
-}
-
-TEST_F(QuicStreamSequencerBufferTest, FlushBufferedFrames) {
- // Write into [0, 8.5 * kBlockSizeBytes - 1024) and then read out [0, 1024).
- std::string source(max_capacity_bytes_ - 1024, 'a');
- buffer_->OnStreamData(0, source, &written_, &error_details_);
- char dest[1024];
- helper_->Read(dest, 1024);
- EXPECT_EQ(1024u, buffer_->BytesConsumed());
- // Write [1024, 512) to the physical beginning.
- source = std::string(512, 'b');
- buffer_->OnStreamData(max_capacity_bytes_, source, &written_,
- &error_details_);
- EXPECT_EQ(512u, written_);
- EXPECT_EQ(max_capacity_bytes_ - 1024 + 512, buffer_->FlushBufferedFrames());
- EXPECT_EQ(max_capacity_bytes_ + 512, buffer_->BytesConsumed());
- EXPECT_TRUE(buffer_->Empty());
- EXPECT_TRUE(helper_->CheckBufferInvariants());
- // Clear buffer at this point should still preserve BytesConsumed().
- buffer_->Clear();
- EXPECT_EQ(max_capacity_bytes_ + 512, buffer_->BytesConsumed());
- EXPECT_TRUE(helper_->CheckBufferInvariants());
-}
-
-TEST_F(QuicStreamSequencerBufferTest, TooManyGaps) {
- // Make sure max capacity is large enough that it is possible to have more
- // than |kMaxNumGapsAllowed| number of gaps.
- max_capacity_bytes_ = 3 * kBlockSizeBytes;
- // Feed buffer with 1-byte discontiguous frames. e.g. [1,2), [3,4), [5,6)...
- for (QuicStreamOffset begin = 1; begin <= max_capacity_bytes_; begin += 2) {
- QuicErrorCode rs =
- buffer_->OnStreamData(begin, "a", &written_, &error_details_);
-
- QuicStreamOffset last_straw = 2 * kMaxNumGapsAllowed - 1;
- if (begin == last_straw) {
- EXPECT_THAT(rs, IsError(QUIC_TOO_MANY_STREAM_DATA_INTERVALS));
- EXPECT_EQ("Too many data intervals received for this stream.",
- error_details_);
- break;
- }
- }
-}
-
-class QuicStreamSequencerBufferRandomIOTest
- : public QuicStreamSequencerBufferTest {
- public:
- using OffsetSizePair = std::pair<QuicStreamOffset, size_t>;
-
- void SetUp() override {
- // Test against a larger capacity then above tests. Also make sure the last
- // block is partially available to use.
- max_capacity_bytes_ = 8.25 * kBlockSizeBytes;
- // Stream to be buffered should be larger than the capacity to test wrap
- // around.
- bytes_to_buffer_ = 2 * max_capacity_bytes_;
- Initialize();
-
- uint64_t seed = QuicRandom::GetInstance()->RandUint64();
- QUIC_LOG(INFO) << "**** The current seed is " << seed << " ****";
- rng_.set_seed(seed);
- }
-
- // Create an out-of-order source stream with given size to populate
- // shuffled_buf_.
- void CreateSourceAndShuffle(size_t max_chunk_size_bytes) {
- max_chunk_size_bytes_ = max_chunk_size_bytes;
- std::unique_ptr<OffsetSizePair[]> chopped_stream(
- new OffsetSizePair[bytes_to_buffer_]);
-
- // Split stream into small chunks with random length. chopped_stream will be
- // populated with segmented stream chunks.
- size_t start_chopping_offset = 0;
- size_t iterations = 0;
- while (start_chopping_offset < bytes_to_buffer_) {
- size_t max_chunk = std::min<size_t>(
- max_chunk_size_bytes_, bytes_to_buffer_ - start_chopping_offset);
- size_t chunk_size = rng_.RandUint64() % max_chunk + 1;
- chopped_stream[iterations] =
- OffsetSizePair(start_chopping_offset, chunk_size);
- start_chopping_offset += chunk_size;
- ++iterations;
- }
- QUICHE_DCHECK(start_chopping_offset == bytes_to_buffer_);
- size_t chunk_num = iterations;
-
- // Randomly change the sequence of in-ordered OffsetSizePairs to make a
- // out-of-order array of OffsetSizePairs.
- for (int i = chunk_num - 1; i >= 0; --i) {
- size_t random_idx = rng_.RandUint64() % (i + 1);
- QUIC_DVLOG(1) << "chunk offset " << chopped_stream[random_idx].first
- << " size " << chopped_stream[random_idx].second;
- shuffled_buf_.push_front(chopped_stream[random_idx]);
- chopped_stream[random_idx] = chopped_stream[i];
- }
- }
-
- // Write the currently first chunk of data in the out-of-order stream into
- // QuicStreamSequencerBuffer. If current chuck cannot be written into buffer
- // because it goes beyond current capacity, move it to the end of
- // shuffled_buf_ and write it later.
- void WriteNextChunkToBuffer() {
- OffsetSizePair& chunk = shuffled_buf_.front();
- QuicStreamOffset offset = chunk.first;
- const size_t num_to_write = chunk.second;
- std::unique_ptr<char[]> write_buf{new char[max_chunk_size_bytes_]};
- for (size_t i = 0; i < num_to_write; ++i) {
- write_buf[i] = (offset + i) % 256;
- }
- absl::string_view string_piece_w(write_buf.get(), num_to_write);
- auto result = buffer_->OnStreamData(offset, string_piece_w, &written_,
- &error_details_);
- if (result == QUIC_NO_ERROR) {
- shuffled_buf_.pop_front();
- total_bytes_written_ += num_to_write;
- } else {
- // This chunk offset exceeds window size.
- shuffled_buf_.push_back(chunk);
- shuffled_buf_.pop_front();
- }
- QUIC_DVLOG(1) << " write at offset: " << offset
- << " len to write: " << num_to_write
- << " write result: " << result
- << " left over: " << shuffled_buf_.size();
- }
-
- protected:
- std::list<OffsetSizePair> shuffled_buf_;
- size_t max_chunk_size_bytes_;
- QuicStreamOffset bytes_to_buffer_;
- size_t total_bytes_written_ = 0;
- size_t total_bytes_read_ = 0;
- SimpleRandom rng_;
-};
-
-TEST_F(QuicStreamSequencerBufferRandomIOTest, RandomWriteAndReadv) {
- // Set kMaxReadSize larger than kBlockSizeBytes to test both small and large
- // read.
- const size_t kMaxReadSize = kBlockSizeBytes * 2;
- // kNumReads is larger than 1 to test how multiple read destinations work.
- const size_t kNumReads = 2;
- // Since write and read operation have equal possibility to be called. Bytes
- // to be written into and read out of should roughly the same.
- const size_t kMaxWriteSize = kNumReads * kMaxReadSize;
- size_t iterations = 0;
-
- CreateSourceAndShuffle(kMaxWriteSize);
-
- while ((!shuffled_buf_.empty() || total_bytes_read_ < bytes_to_buffer_) &&
- iterations <= 2 * bytes_to_buffer_) {
- uint8_t next_action =
- shuffled_buf_.empty() ? uint8_t{1} : rng_.RandUint64() % 2;
- QUIC_DVLOG(1) << "iteration: " << iterations;
- switch (next_action) {
- case 0: { // write
- WriteNextChunkToBuffer();
- ASSERT_TRUE(helper_->CheckBufferInvariants());
- break;
- }
- case 1: { // readv
- std::unique_ptr<char[][kMaxReadSize]> read_buf{
- new char[kNumReads][kMaxReadSize]};
- iovec dest_iov[kNumReads];
- size_t num_to_read = 0;
- for (size_t i = 0; i < kNumReads; ++i) {
- dest_iov[i].iov_base =
- reinterpret_cast<void*>(const_cast<char*>(read_buf[i]));
- dest_iov[i].iov_len = rng_.RandUint64() % kMaxReadSize;
- num_to_read += dest_iov[i].iov_len;
- }
- size_t actually_read;
- EXPECT_THAT(buffer_->Readv(dest_iov, kNumReads, &actually_read,
- &error_details_),
- IsQuicNoError());
- ASSERT_LE(actually_read, num_to_read);
- QUIC_DVLOG(1) << " read from offset: " << total_bytes_read_
- << " size: " << num_to_read
- << " actual read: " << actually_read;
- for (size_t i = 0; i < actually_read; ++i) {
- char ch = (i + total_bytes_read_) % 256;
- ASSERT_EQ(ch, GetCharFromIOVecs(i, dest_iov, kNumReads))
- << " at iteration " << iterations;
- }
- total_bytes_read_ += actually_read;
- ASSERT_EQ(total_bytes_read_, buffer_->BytesConsumed());
- ASSERT_TRUE(helper_->CheckBufferInvariants());
- break;
- }
- }
- ++iterations;
- ASSERT_LE(total_bytes_read_, total_bytes_written_);
- }
- EXPECT_LT(iterations, bytes_to_buffer_) << "runaway test";
- EXPECT_LE(bytes_to_buffer_, total_bytes_read_)
- << "iterations: " << iterations;
- EXPECT_LE(bytes_to_buffer_, total_bytes_written_);
-}
-
-TEST_F(QuicStreamSequencerBufferRandomIOTest, RandomWriteAndConsumeInPlace) {
- // The value 4 is chosen such that the max write size is no larger than the
- // maximum buffer capacity.
- const size_t kMaxNumReads = 4;
- // Adjust write amount be roughly equal to that GetReadableRegions() can get.
- const size_t kMaxWriteSize = kMaxNumReads * kBlockSizeBytes;
- ASSERT_LE(kMaxWriteSize, max_capacity_bytes_);
- size_t iterations = 0;
-
- CreateSourceAndShuffle(kMaxWriteSize);
-
- while ((!shuffled_buf_.empty() || total_bytes_read_ < bytes_to_buffer_) &&
- iterations <= 2 * bytes_to_buffer_) {
- uint8_t next_action =
- shuffled_buf_.empty() ? uint8_t{1} : rng_.RandUint64() % 2;
- QUIC_DVLOG(1) << "iteration: " << iterations;
- switch (next_action) {
- case 0: { // write
- WriteNextChunkToBuffer();
- ASSERT_TRUE(helper_->CheckBufferInvariants());
- break;
- }
- case 1: { // GetReadableRegions and then MarkConsumed
- size_t num_read = rng_.RandUint64() % kMaxNumReads + 1;
- iovec dest_iov[kMaxNumReads];
- ASSERT_TRUE(helper_->CheckBufferInvariants());
- size_t actually_num_read =
- buffer_->GetReadableRegions(dest_iov, num_read);
- ASSERT_LE(actually_num_read, num_read);
- size_t avail_bytes = 0;
- for (size_t i = 0; i < actually_num_read; ++i) {
- avail_bytes += dest_iov[i].iov_len;
- }
- // process random number of bytes (check the value of each byte).
- size_t bytes_to_process = rng_.RandUint64() % (avail_bytes + 1);
- size_t bytes_processed = 0;
- for (size_t i = 0; i < actually_num_read; ++i) {
- size_t bytes_in_block = std::min<size_t>(
- bytes_to_process - bytes_processed, dest_iov[i].iov_len);
- if (bytes_in_block == 0) {
- break;
- }
- for (size_t j = 0; j < bytes_in_block; ++j) {
- ASSERT_LE(bytes_processed, bytes_to_process);
- char char_expected =
- (buffer_->BytesConsumed() + bytes_processed) % 256;
- ASSERT_EQ(char_expected,
- reinterpret_cast<const char*>(dest_iov[i].iov_base)[j])
- << " at iteration " << iterations;
- ++bytes_processed;
- }
- }
-
- buffer_->MarkConsumed(bytes_processed);
-
- QUIC_DVLOG(1) << "iteration " << iterations << ": try to get "
- << num_read << " readable regions, actually get "
- << actually_num_read
- << " from offset: " << total_bytes_read_
- << "\nprocesse bytes: " << bytes_processed;
- total_bytes_read_ += bytes_processed;
- ASSERT_EQ(total_bytes_read_, buffer_->BytesConsumed());
- ASSERT_TRUE(helper_->CheckBufferInvariants());
- break;
- }
- }
- ++iterations;
- ASSERT_LE(total_bytes_read_, total_bytes_written_);
- }
- EXPECT_LT(iterations, bytes_to_buffer_) << "runaway test";
- EXPECT_LE(bytes_to_buffer_, total_bytes_read_)
- << "iterations: " << iterations;
- EXPECT_LE(bytes_to_buffer_, total_bytes_written_);
-}
-
-TEST_F(QuicStreamSequencerBufferTest, GrowBlockSizeOnDemand) {
- max_capacity_bytes_ = 1024 * kBlockSizeBytes;
- std::string source_of_one_block(kBlockSizeBytes, 'a');
- Initialize();
-
- ASSERT_EQ(helper_->current_blocks_count(), 0u);
-
- // A minimum of 8 blocks are allocated
- buffer_->OnStreamData(0, source_of_one_block, &written_, &error_details_);
- ASSERT_EQ(helper_->current_blocks_count(), 8u);
-
- // Number of blocks doesn't grow if the data is within the capacity.
- buffer_->OnStreamData(kBlockSizeBytes * 7, source_of_one_block, &written_,
- &error_details_);
- ASSERT_EQ(helper_->current_blocks_count(), 8u);
-
- // Number of blocks grows by a factor of 4 normally.
- buffer_->OnStreamData(kBlockSizeBytes * 8, "a", &written_, &error_details_);
- ASSERT_EQ(helper_->current_blocks_count(), 32u);
-
- // Number of blocks grow to the demanded size of 140 instead of 128 since
- // that's not enough.
- buffer_->OnStreamData(kBlockSizeBytes * 139, source_of_one_block, &written_,
- &error_details_);
- ASSERT_EQ(helper_->current_blocks_count(), 140u);
-
- // Number of blocks grows by a factor of 4 normally.
- buffer_->OnStreamData(kBlockSizeBytes * 140, source_of_one_block, &written_,
- &error_details_);
- ASSERT_EQ(helper_->current_blocks_count(), 560u);
-
- // max_capacity_bytes is reached and number of blocks is capped.
- buffer_->OnStreamData(kBlockSizeBytes * 560, source_of_one_block, &written_,
- &error_details_);
- ASSERT_EQ(helper_->current_blocks_count(), 1024u);
-
- // max_capacity_bytes is reached and number of blocks is capped.
- buffer_->OnStreamData(kBlockSizeBytes * 1025, source_of_one_block, &written_,
- &error_details_);
- ASSERT_EQ(helper_->current_blocks_count(), 1024u);
-}
-
-} // anonymous namespace
-
-} // namespace test
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_stream_sequencer_test.cc b/chromium/net/third_party/quiche/src/quic/core/quic_stream_sequencer_test.cc
deleted file mode 100644
index 0a15e96d3c4..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_stream_sequencer_test.cc
+++ /dev/null
@@ -1,781 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_stream_sequencer.h"
-
-#include <algorithm>
-#include <cstdint>
-#include <memory>
-#include <string>
-#include <utility>
-#include <vector>
-
-#include "absl/base/macros.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_stream.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_expect_bug.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/quic_stream_sequencer_peer.h"
-#include "quic/test_tools/quic_test_utils.h"
-
-using testing::_;
-using testing::AnyNumber;
-using testing::InSequence;
-
-namespace quic {
-namespace test {
-
-class MockStream : public QuicStreamSequencer::StreamInterface {
- public:
- MOCK_METHOD(void, OnFinRead, (), (override));
- MOCK_METHOD(void, OnDataAvailable, (), (override));
- MOCK_METHOD(void,
- OnUnrecoverableError,
- (QuicErrorCode error, const std::string& details),
- (override));
- MOCK_METHOD(void,
- OnUnrecoverableError,
- (QuicErrorCode error,
- QuicIetfTransportErrorCodes ietf_error,
- const std::string& details),
- (override));
- MOCK_METHOD(void, ResetWithError, (QuicResetStreamError error), (override));
- MOCK_METHOD(void, AddBytesConsumed, (QuicByteCount bytes), (override));
-
- QuicStreamId id() const override { return 1; }
- ParsedQuicVersion version() const override {
- return CurrentSupportedVersions()[0];
- }
-};
-
-namespace {
-
-static const char kPayload[] =
- "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
-
-class QuicStreamSequencerTest : public QuicTest {
- public:
- void ConsumeData(size_t num_bytes) {
- char buffer[1024];
- ASSERT_GT(ABSL_ARRAYSIZE(buffer), num_bytes);
- struct iovec iov;
- iov.iov_base = buffer;
- iov.iov_len = num_bytes;
- ASSERT_EQ(num_bytes, sequencer_->Readv(&iov, 1));
- }
-
- protected:
- QuicStreamSequencerTest()
- : stream_(), sequencer_(new QuicStreamSequencer(&stream_)) {}
-
- // Verify that the data in first region match with the expected[0].
- bool VerifyReadableRegion(const std::vector<std::string>& expected) {
- return VerifyReadableRegion(*sequencer_, expected);
- }
-
- // Verify that the data in each of currently readable regions match with each
- // item given in |expected|.
- bool VerifyReadableRegions(const std::vector<std::string>& expected) {
- return VerifyReadableRegions(*sequencer_, expected);
- }
-
- bool VerifyIovecs(iovec* iovecs,
- size_t num_iovecs,
- const std::vector<std::string>& expected) {
- return VerifyIovecs(*sequencer_, iovecs, num_iovecs, expected);
- }
-
- bool VerifyReadableRegion(const QuicStreamSequencer& sequencer,
- const std::vector<std::string>& expected) {
- iovec iovecs[1];
- if (sequencer.GetReadableRegions(iovecs, 1)) {
- return (VerifyIovecs(sequencer, iovecs, 1,
- std::vector<std::string>{expected[0]}));
- }
- return false;
- }
-
- // Verify that the data in each of currently readable regions match with each
- // item given in |expected|.
- bool VerifyReadableRegions(const QuicStreamSequencer& sequencer,
- const std::vector<std::string>& expected) {
- iovec iovecs[5];
- size_t num_iovecs =
- sequencer.GetReadableRegions(iovecs, ABSL_ARRAYSIZE(iovecs));
- return VerifyReadableRegion(sequencer, expected) &&
- VerifyIovecs(sequencer, iovecs, num_iovecs, expected);
- }
-
- bool VerifyIovecs(const QuicStreamSequencer& /*sequencer*/,
- iovec* iovecs,
- size_t num_iovecs,
- const std::vector<std::string>& expected) {
- int start_position = 0;
- for (size_t i = 0; i < num_iovecs; ++i) {
- if (!VerifyIovec(iovecs[i],
- expected[0].substr(start_position, iovecs[i].iov_len))) {
- return false;
- }
- start_position += iovecs[i].iov_len;
- }
- return true;
- }
-
- bool VerifyIovec(const iovec& iovec, absl::string_view expected) {
- if (iovec.iov_len != expected.length()) {
- QUIC_LOG(ERROR) << "Invalid length: " << iovec.iov_len << " vs "
- << expected.length();
- return false;
- }
- if (memcmp(iovec.iov_base, expected.data(), expected.length()) != 0) {
- QUIC_LOG(ERROR) << "Invalid data: " << static_cast<char*>(iovec.iov_base)
- << " vs " << expected;
- return false;
- }
- return true;
- }
-
- void OnFinFrame(QuicStreamOffset byte_offset, const char* data) {
- QuicStreamFrame frame;
- frame.stream_id = 1;
- frame.offset = byte_offset;
- frame.data_buffer = data;
- frame.data_length = strlen(data);
- frame.fin = true;
- sequencer_->OnStreamFrame(frame);
- }
-
- void OnFrame(QuicStreamOffset byte_offset, const char* data) {
- QuicStreamFrame frame;
- frame.stream_id = 1;
- frame.offset = byte_offset;
- frame.data_buffer = data;
- frame.data_length = strlen(data);
- frame.fin = false;
- sequencer_->OnStreamFrame(frame);
- }
-
- size_t NumBufferedBytes() {
- return QuicStreamSequencerPeer::GetNumBufferedBytes(sequencer_.get());
- }
-
- testing::StrictMock<MockStream> stream_;
- std::unique_ptr<QuicStreamSequencer> sequencer_;
-};
-
-// TODO(rch): reorder these tests so they build on each other.
-
-TEST_F(QuicStreamSequencerTest, RejectOldFrame) {
- EXPECT_CALL(stream_, AddBytesConsumed(3));
- EXPECT_CALL(stream_, OnDataAvailable()).WillOnce(testing::Invoke([this]() {
- ConsumeData(3);
- }));
-
- OnFrame(0, "abc");
-
- EXPECT_EQ(0u, NumBufferedBytes());
- EXPECT_EQ(3u, sequencer_->NumBytesConsumed());
- // Ignore this - it matches a past packet number and we should not see it
- // again.
- OnFrame(0, "def");
- EXPECT_EQ(0u, NumBufferedBytes());
-}
-
-TEST_F(QuicStreamSequencerTest, RejectBufferedFrame) {
- EXPECT_CALL(stream_, OnDataAvailable());
-
- OnFrame(0, "abc");
- EXPECT_EQ(3u, NumBufferedBytes());
- EXPECT_EQ(0u, sequencer_->NumBytesConsumed());
-
- // Ignore this - it matches a buffered frame.
- // Right now there's no checking that the payload is consistent.
- OnFrame(0, "def");
- EXPECT_EQ(3u, NumBufferedBytes());
-}
-
-TEST_F(QuicStreamSequencerTest, FullFrameConsumed) {
- EXPECT_CALL(stream_, AddBytesConsumed(3));
- EXPECT_CALL(stream_, OnDataAvailable()).WillOnce(testing::Invoke([this]() {
- ConsumeData(3);
- }));
-
- OnFrame(0, "abc");
- EXPECT_EQ(0u, NumBufferedBytes());
- EXPECT_EQ(3u, sequencer_->NumBytesConsumed());
-}
-
-TEST_F(QuicStreamSequencerTest, BlockedThenFullFrameConsumed) {
- sequencer_->SetBlockedUntilFlush();
-
- OnFrame(0, "abc");
- EXPECT_EQ(3u, NumBufferedBytes());
- EXPECT_EQ(0u, sequencer_->NumBytesConsumed());
-
- EXPECT_CALL(stream_, AddBytesConsumed(3));
- EXPECT_CALL(stream_, OnDataAvailable()).WillOnce(testing::Invoke([this]() {
- ConsumeData(3);
- }));
- sequencer_->SetUnblocked();
- EXPECT_EQ(0u, NumBufferedBytes());
- EXPECT_EQ(3u, sequencer_->NumBytesConsumed());
-
- EXPECT_CALL(stream_, AddBytesConsumed(3));
- EXPECT_CALL(stream_, OnDataAvailable()).WillOnce(testing::Invoke([this]() {
- ConsumeData(3);
- }));
- EXPECT_FALSE(sequencer_->IsClosed());
- OnFinFrame(3, "def");
- EXPECT_TRUE(sequencer_->IsClosed());
-}
-
-TEST_F(QuicStreamSequencerTest, BlockedThenFullFrameAndFinConsumed) {
- sequencer_->SetBlockedUntilFlush();
-
- OnFinFrame(0, "abc");
- EXPECT_EQ(3u, NumBufferedBytes());
- EXPECT_EQ(0u, sequencer_->NumBytesConsumed());
-
- EXPECT_CALL(stream_, AddBytesConsumed(3));
- EXPECT_CALL(stream_, OnDataAvailable()).WillOnce(testing::Invoke([this]() {
- ConsumeData(3);
- }));
- EXPECT_FALSE(sequencer_->IsClosed());
- sequencer_->SetUnblocked();
- EXPECT_TRUE(sequencer_->IsClosed());
- EXPECT_EQ(0u, NumBufferedBytes());
- EXPECT_EQ(3u, sequencer_->NumBytesConsumed());
-}
-
-TEST_F(QuicStreamSequencerTest, EmptyFrame) {
- if (!stream_.version().HasIetfQuicFrames()) {
- EXPECT_CALL(stream_,
- OnUnrecoverableError(QUIC_EMPTY_STREAM_FRAME_NO_FIN, _));
- }
- OnFrame(0, "");
- EXPECT_EQ(0u, NumBufferedBytes());
- EXPECT_EQ(0u, sequencer_->NumBytesConsumed());
-}
-
-TEST_F(QuicStreamSequencerTest, EmptyFinFrame) {
- EXPECT_CALL(stream_, OnDataAvailable());
- OnFinFrame(0, "");
- EXPECT_EQ(0u, NumBufferedBytes());
- EXPECT_EQ(0u, sequencer_->NumBytesConsumed());
-}
-
-TEST_F(QuicStreamSequencerTest, PartialFrameConsumed) {
- EXPECT_CALL(stream_, AddBytesConsumed(2));
- EXPECT_CALL(stream_, OnDataAvailable()).WillOnce(testing::Invoke([this]() {
- ConsumeData(2);
- }));
-
- OnFrame(0, "abc");
- EXPECT_EQ(1u, NumBufferedBytes());
- EXPECT_EQ(2u, sequencer_->NumBytesConsumed());
-}
-
-TEST_F(QuicStreamSequencerTest, NextxFrameNotConsumed) {
- EXPECT_CALL(stream_, OnDataAvailable());
-
- OnFrame(0, "abc");
- EXPECT_EQ(3u, NumBufferedBytes());
- EXPECT_EQ(0u, sequencer_->NumBytesConsumed());
-}
-
-TEST_F(QuicStreamSequencerTest, FutureFrameNotProcessed) {
- OnFrame(3, "abc");
- EXPECT_EQ(3u, NumBufferedBytes());
- EXPECT_EQ(0u, sequencer_->NumBytesConsumed());
-}
-
-TEST_F(QuicStreamSequencerTest, OutOfOrderFrameProcessed) {
- // Buffer the first
- OnFrame(6, "ghi");
- EXPECT_EQ(3u, NumBufferedBytes());
- EXPECT_EQ(0u, sequencer_->NumBytesConsumed());
- EXPECT_EQ(3u, sequencer_->NumBytesBuffered());
- // Buffer the second
- OnFrame(3, "def");
- EXPECT_EQ(6u, NumBufferedBytes());
- EXPECT_EQ(0u, sequencer_->NumBytesConsumed());
- EXPECT_EQ(6u, sequencer_->NumBytesBuffered());
-
- EXPECT_CALL(stream_, AddBytesConsumed(9));
- EXPECT_CALL(stream_, OnDataAvailable()).WillOnce(testing::Invoke([this]() {
- ConsumeData(9);
- }));
-
- // Now process all of them at once.
- OnFrame(0, "abc");
- EXPECT_EQ(9u, sequencer_->NumBytesConsumed());
- EXPECT_EQ(0u, sequencer_->NumBytesBuffered());
-
- EXPECT_EQ(0u, NumBufferedBytes());
-}
-
-TEST_F(QuicStreamSequencerTest, BasicHalfCloseOrdered) {
- InSequence s;
-
- EXPECT_CALL(stream_, OnDataAvailable()).WillOnce(testing::Invoke([this]() {
- ConsumeData(3);
- }));
- EXPECT_CALL(stream_, AddBytesConsumed(3));
- OnFinFrame(0, "abc");
-
- EXPECT_EQ(3u, QuicStreamSequencerPeer::GetCloseOffset(sequencer_.get()));
-}
-
-TEST_F(QuicStreamSequencerTest, BasicHalfCloseUnorderedWithFlush) {
- OnFinFrame(6, "");
- EXPECT_EQ(6u, QuicStreamSequencerPeer::GetCloseOffset(sequencer_.get()));
-
- OnFrame(3, "def");
- EXPECT_CALL(stream_, AddBytesConsumed(6));
- EXPECT_CALL(stream_, OnDataAvailable()).WillOnce(testing::Invoke([this]() {
- ConsumeData(6);
- }));
- EXPECT_FALSE(sequencer_->IsClosed());
- OnFrame(0, "abc");
- EXPECT_TRUE(sequencer_->IsClosed());
-}
-
-TEST_F(QuicStreamSequencerTest, BasicHalfUnordered) {
- OnFinFrame(3, "");
- EXPECT_EQ(3u, QuicStreamSequencerPeer::GetCloseOffset(sequencer_.get()));
-
- EXPECT_CALL(stream_, AddBytesConsumed(3));
- EXPECT_CALL(stream_, OnDataAvailable()).WillOnce(testing::Invoke([this]() {
- ConsumeData(3);
- }));
- EXPECT_FALSE(sequencer_->IsClosed());
- OnFrame(0, "abc");
- EXPECT_TRUE(sequencer_->IsClosed());
-}
-
-TEST_F(QuicStreamSequencerTest, TerminateWithReadv) {
- char buffer[3];
-
- OnFinFrame(3, "");
- EXPECT_EQ(3u, QuicStreamSequencerPeer::GetCloseOffset(sequencer_.get()));
-
- EXPECT_FALSE(sequencer_->IsClosed());
-
- EXPECT_CALL(stream_, OnDataAvailable());
- OnFrame(0, "abc");
-
- EXPECT_CALL(stream_, AddBytesConsumed(3));
- iovec iov = {&buffer[0], 3};
- int bytes_read = sequencer_->Readv(&iov, 1);
- EXPECT_EQ(3, bytes_read);
- EXPECT_TRUE(sequencer_->IsClosed());
-}
-
-TEST_F(QuicStreamSequencerTest, MultipleOffsets) {
- OnFinFrame(3, "");
- EXPECT_EQ(3u, QuicStreamSequencerPeer::GetCloseOffset(sequencer_.get()));
-
- EXPECT_CALL(stream_, OnUnrecoverableError(
- QUIC_STREAM_SEQUENCER_INVALID_STATE,
- "Stream 1 received new final offset: 1, which is "
- "different from close offset: 3"));
- OnFinFrame(1, "");
-}
-
-class QuicSequencerRandomTest : public QuicStreamSequencerTest {
- public:
- using Frame = std::pair<int, std::string>;
- using FrameList = std::vector<Frame>;
-
- void CreateFrames() {
- int payload_size = ABSL_ARRAYSIZE(kPayload) - 1;
- int remaining_payload = payload_size;
- while (remaining_payload != 0) {
- int size = std::min(OneToN(6), remaining_payload);
- int index = payload_size - remaining_payload;
- list_.push_back(
- std::make_pair(index, std::string(kPayload + index, size)));
- remaining_payload -= size;
- }
- }
-
- QuicSequencerRandomTest() {
- uint64_t seed = QuicRandom::GetInstance()->RandUint64();
- QUIC_LOG(INFO) << "**** The current seed is " << seed << " ****";
- random_.set_seed(seed);
-
- CreateFrames();
- }
-
- int OneToN(int n) { return random_.RandUint64() % n + 1; }
-
- void ReadAvailableData() {
- // Read all available data
- char output[ABSL_ARRAYSIZE(kPayload) + 1];
- iovec iov;
- iov.iov_base = output;
- iov.iov_len = ABSL_ARRAYSIZE(output);
- int bytes_read = sequencer_->Readv(&iov, 1);
- EXPECT_NE(0, bytes_read);
- output_.append(output, bytes_read);
- }
-
- std::string output_;
- // Data which peek at using GetReadableRegion if we back up.
- std::string peeked_;
- SimpleRandom random_;
- FrameList list_;
-};
-
-// All frames are processed as soon as we have sequential data.
-// Infinite buffering, so all frames are acked right away.
-TEST_F(QuicSequencerRandomTest, RandomFramesNoDroppingNoBackup) {
- EXPECT_CALL(stream_, OnDataAvailable())
- .Times(AnyNumber())
- .WillRepeatedly(
- Invoke(this, &QuicSequencerRandomTest::ReadAvailableData));
- QuicByteCount total_bytes_consumed = 0;
- EXPECT_CALL(stream_, AddBytesConsumed(_))
- .Times(AnyNumber())
- .WillRepeatedly(
- testing::Invoke([&total_bytes_consumed](QuicByteCount bytes) {
- total_bytes_consumed += bytes;
- }));
-
- while (!list_.empty()) {
- int index = OneToN(list_.size()) - 1;
- QUIC_LOG(ERROR) << "Sending index " << index << " " << list_[index].second;
- OnFrame(list_[index].first, list_[index].second.data());
-
- list_.erase(list_.begin() + index);
- }
-
- ASSERT_EQ(ABSL_ARRAYSIZE(kPayload) - 1, output_.size());
- EXPECT_EQ(kPayload, output_);
- EXPECT_EQ(ABSL_ARRAYSIZE(kPayload) - 1, total_bytes_consumed);
-}
-
-TEST_F(QuicSequencerRandomTest, RandomFramesNoDroppingBackup) {
- char buffer[10];
- iovec iov[2];
- iov[0].iov_base = &buffer[0];
- iov[0].iov_len = 5;
- iov[1].iov_base = &buffer[5];
- iov[1].iov_len = 5;
-
- EXPECT_CALL(stream_, OnDataAvailable()).Times(AnyNumber());
- QuicByteCount total_bytes_consumed = 0;
- EXPECT_CALL(stream_, AddBytesConsumed(_))
- .Times(AnyNumber())
- .WillRepeatedly(
- testing::Invoke([&total_bytes_consumed](QuicByteCount bytes) {
- total_bytes_consumed += bytes;
- }));
-
- while (output_.size() != ABSL_ARRAYSIZE(kPayload) - 1) {
- if (!list_.empty() && OneToN(2) == 1) { // Send data
- int index = OneToN(list_.size()) - 1;
- OnFrame(list_[index].first, list_[index].second.data());
- list_.erase(list_.begin() + index);
- } else { // Read data
- bool has_bytes = sequencer_->HasBytesToRead();
- iovec peek_iov[20];
- int iovs_peeked = sequencer_->GetReadableRegions(peek_iov, 20);
- if (has_bytes) {
- ASSERT_LT(0, iovs_peeked);
- ASSERT_TRUE(sequencer_->GetReadableRegion(peek_iov));
- } else {
- ASSERT_EQ(0, iovs_peeked);
- ASSERT_FALSE(sequencer_->GetReadableRegion(peek_iov));
- }
- int total_bytes_to_peek = ABSL_ARRAYSIZE(buffer);
- for (int i = 0; i < iovs_peeked; ++i) {
- int bytes_to_peek =
- std::min<int>(peek_iov[i].iov_len, total_bytes_to_peek);
- peeked_.append(static_cast<char*>(peek_iov[i].iov_base), bytes_to_peek);
- total_bytes_to_peek -= bytes_to_peek;
- if (total_bytes_to_peek == 0) {
- break;
- }
- }
- int bytes_read = sequencer_->Readv(iov, 2);
- output_.append(buffer, bytes_read);
- ASSERT_EQ(output_.size(), peeked_.size());
- }
- }
- EXPECT_EQ(std::string(kPayload), output_);
- EXPECT_EQ(std::string(kPayload), peeked_);
- EXPECT_EQ(ABSL_ARRAYSIZE(kPayload) - 1, total_bytes_consumed);
-}
-
-// Same as above, just using a different method for reading.
-TEST_F(QuicStreamSequencerTest, MarkConsumed) {
- InSequence s;
- EXPECT_CALL(stream_, OnDataAvailable());
-
- OnFrame(0, "abc");
- OnFrame(3, "def");
- OnFrame(6, "ghi");
-
- // abcdefghi buffered.
- EXPECT_EQ(9u, sequencer_->NumBytesBuffered());
-
- // Peek into the data.
- std::vector<std::string> expected = {"abcdefghi"};
- ASSERT_TRUE(VerifyReadableRegions(expected));
-
- // Consume 1 byte.
- EXPECT_CALL(stream_, AddBytesConsumed(1));
- sequencer_->MarkConsumed(1);
- // Verify data.
- std::vector<std::string> expected2 = {"bcdefghi"};
- ASSERT_TRUE(VerifyReadableRegions(expected2));
- EXPECT_EQ(8u, sequencer_->NumBytesBuffered());
-
- // Consume 2 bytes.
- EXPECT_CALL(stream_, AddBytesConsumed(2));
- sequencer_->MarkConsumed(2);
- // Verify data.
- std::vector<std::string> expected3 = {"defghi"};
- ASSERT_TRUE(VerifyReadableRegions(expected3));
- EXPECT_EQ(6u, sequencer_->NumBytesBuffered());
-
- // Consume 5 bytes.
- EXPECT_CALL(stream_, AddBytesConsumed(5));
- sequencer_->MarkConsumed(5);
- // Verify data.
- std::vector<std::string> expected4{"i"};
- ASSERT_TRUE(VerifyReadableRegions(expected4));
- EXPECT_EQ(1u, sequencer_->NumBytesBuffered());
-}
-
-TEST_F(QuicStreamSequencerTest, MarkConsumedError) {
- EXPECT_CALL(stream_, OnDataAvailable());
-
- OnFrame(0, "abc");
- OnFrame(9, "jklmnopqrstuvwxyz");
-
- // Peek into the data. Only the first chunk should be readable because of the
- // missing data.
- std::vector<std::string> expected{"abc"};
- ASSERT_TRUE(VerifyReadableRegions(expected));
-
- // 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.");
-}
-
-TEST_F(QuicStreamSequencerTest, MarkConsumedWithMissingPacket) {
- InSequence s;
- EXPECT_CALL(stream_, OnDataAvailable());
-
- OnFrame(0, "abc");
- OnFrame(3, "def");
- // Missing packet: 6, ghi.
- OnFrame(9, "jkl");
-
- std::vector<std::string> expected = {"abcdef"};
- ASSERT_TRUE(VerifyReadableRegions(expected));
-
- EXPECT_CALL(stream_, AddBytesConsumed(6));
- sequencer_->MarkConsumed(6);
-}
-
-TEST_F(QuicStreamSequencerTest, Move) {
- InSequence s;
- EXPECT_CALL(stream_, OnDataAvailable());
-
- OnFrame(0, "abc");
- OnFrame(3, "def");
- OnFrame(6, "ghi");
-
- // abcdefghi buffered.
- EXPECT_EQ(9u, sequencer_->NumBytesBuffered());
-
- // Peek into the data.
- std::vector<std::string> expected = {"abcdefghi"};
- ASSERT_TRUE(VerifyReadableRegions(expected));
-
- QuicStreamSequencer sequencer2(std::move(*sequencer_));
- ASSERT_TRUE(VerifyReadableRegions(sequencer2, expected));
-}
-
-TEST_F(QuicStreamSequencerTest, OverlappingFramesReceived) {
- // The peer should never send us non-identical stream frames which contain
- // overlapping byte ranges - if they do, we close the connection.
- QuicStreamId id = 1;
-
- QuicStreamFrame frame1(id, false, 1, absl::string_view("hello"));
- sequencer_->OnStreamFrame(frame1);
-
- QuicStreamFrame frame2(id, false, 2, absl::string_view("hello"));
- EXPECT_CALL(stream_, OnUnrecoverableError(QUIC_OVERLAPPING_STREAM_DATA, _))
- .Times(0);
- sequencer_->OnStreamFrame(frame2);
-}
-
-TEST_F(QuicStreamSequencerTest, DataAvailableOnOverlappingFrames) {
- QuicStreamId id = 1;
- const std::string data(1000, '.');
-
- // Received [0, 1000).
- QuicStreamFrame frame1(id, false, 0, data);
- EXPECT_CALL(stream_, OnDataAvailable());
- sequencer_->OnStreamFrame(frame1);
- // Consume [0, 500).
- EXPECT_CALL(stream_, AddBytesConsumed(500));
- QuicStreamSequencerTest::ConsumeData(500);
- EXPECT_EQ(500u, sequencer_->NumBytesConsumed());
- EXPECT_EQ(500u, sequencer_->NumBytesBuffered());
-
- // Received [500, 1500).
- QuicStreamFrame frame2(id, false, 500, data);
- // Do not call OnDataAvailable as there are readable bytes left in the buffer.
- EXPECT_CALL(stream_, OnDataAvailable()).Times(0);
- sequencer_->OnStreamFrame(frame2);
- // Consume [1000, 1500).
- EXPECT_CALL(stream_, AddBytesConsumed(1000));
- QuicStreamSequencerTest::ConsumeData(1000);
- EXPECT_EQ(1500u, sequencer_->NumBytesConsumed());
- EXPECT_EQ(0u, sequencer_->NumBytesBuffered());
-
- // Received [1498, 1503).
- QuicStreamFrame frame3(id, false, 1498, absl::string_view("hello"));
- EXPECT_CALL(stream_, OnDataAvailable());
- sequencer_->OnStreamFrame(frame3);
- EXPECT_CALL(stream_, AddBytesConsumed(3));
- QuicStreamSequencerTest::ConsumeData(3);
- EXPECT_EQ(1503u, sequencer_->NumBytesConsumed());
- EXPECT_EQ(0u, sequencer_->NumBytesBuffered());
-
- // Received [1000, 1005).
- QuicStreamFrame frame4(id, false, 1000, absl::string_view("hello"));
- EXPECT_CALL(stream_, OnDataAvailable()).Times(0);
- sequencer_->OnStreamFrame(frame4);
- EXPECT_EQ(1503u, sequencer_->NumBytesConsumed());
- EXPECT_EQ(0u, sequencer_->NumBytesBuffered());
-}
-
-TEST_F(QuicStreamSequencerTest, OnDataAvailableWhenReadableBytesIncrease) {
- sequencer_->set_level_triggered(true);
- QuicStreamId id = 1;
-
- // Received [0, 5).
- QuicStreamFrame frame1(id, false, 0, "hello");
- EXPECT_CALL(stream_, OnDataAvailable());
- sequencer_->OnStreamFrame(frame1);
- EXPECT_EQ(5u, sequencer_->NumBytesBuffered());
-
- // Without consuming the buffer bytes, continue receiving [5, 11).
- QuicStreamFrame frame2(id, false, 5, " world");
- // OnDataAvailable should still be called because there are more data to read.
- EXPECT_CALL(stream_, OnDataAvailable());
- sequencer_->OnStreamFrame(frame2);
- EXPECT_EQ(11u, sequencer_->NumBytesBuffered());
-
- // Without consuming the buffer bytes, continue receiving [12, 13).
- QuicStreamFrame frame3(id, false, 5, "a");
- // OnDataAvailable shouldn't be called becasue there are still only 11 bytes
- // available.
- EXPECT_CALL(stream_, OnDataAvailable()).Times(0);
- sequencer_->OnStreamFrame(frame3);
- EXPECT_EQ(11u, sequencer_->NumBytesBuffered());
-}
-
-TEST_F(QuicStreamSequencerTest, ReadSingleFrame) {
- EXPECT_CALL(stream_, OnDataAvailable());
- OnFrame(0u, "abc");
- std::string actual;
- EXPECT_CALL(stream_, AddBytesConsumed(3));
- sequencer_->Read(&actual);
- EXPECT_EQ("abc", actual);
- EXPECT_EQ(0u, sequencer_->NumBytesBuffered());
-}
-
-TEST_F(QuicStreamSequencerTest, ReadMultipleFramesWithMissingFrame) {
- EXPECT_CALL(stream_, OnDataAvailable());
- OnFrame(0u, "abc");
- OnFrame(3u, "def");
- OnFrame(6u, "ghi");
- OnFrame(10u, "xyz"); // Byte 9 is missing.
- std::string actual;
- EXPECT_CALL(stream_, AddBytesConsumed(9));
- sequencer_->Read(&actual);
- EXPECT_EQ("abcdefghi", actual);
- EXPECT_EQ(3u, sequencer_->NumBytesBuffered());
-}
-
-TEST_F(QuicStreamSequencerTest, ReadAndAppendToString) {
- EXPECT_CALL(stream_, OnDataAvailable());
- OnFrame(0u, "def");
- OnFrame(3u, "ghi");
- std::string actual = "abc";
- EXPECT_CALL(stream_, AddBytesConsumed(6));
- sequencer_->Read(&actual);
- EXPECT_EQ("abcdefghi", actual);
- EXPECT_EQ(0u, sequencer_->NumBytesBuffered());
-}
-
-TEST_F(QuicStreamSequencerTest, StopReading) {
- EXPECT_CALL(stream_, OnDataAvailable()).Times(0);
- EXPECT_CALL(stream_, OnFinRead());
-
- EXPECT_CALL(stream_, AddBytesConsumed(0));
- sequencer_->StopReading();
-
- EXPECT_CALL(stream_, AddBytesConsumed(3));
- OnFrame(0u, "abc");
- EXPECT_CALL(stream_, AddBytesConsumed(3));
- OnFrame(3u, "def");
- EXPECT_CALL(stream_, AddBytesConsumed(3));
- OnFinFrame(6u, "ghi");
-}
-
-TEST_F(QuicStreamSequencerTest, StopReadingWithLevelTriggered) {
- EXPECT_CALL(stream_, AddBytesConsumed(0));
- EXPECT_CALL(stream_, AddBytesConsumed(3)).Times(3);
- EXPECT_CALL(stream_, OnDataAvailable()).Times(0);
- EXPECT_CALL(stream_, OnFinRead());
-
- sequencer_->set_level_triggered(true);
- sequencer_->StopReading();
-
- OnFrame(0u, "abc");
- OnFrame(3u, "def");
- OnFinFrame(6u, "ghi");
-}
-
-// Regression test for https://crbug.com/992486.
-TEST_F(QuicStreamSequencerTest, CorruptFinFrames) {
- EXPECT_CALL(stream_, OnUnrecoverableError(
- QUIC_STREAM_SEQUENCER_INVALID_STATE,
- "Stream 1 received new final offset: 1, which is "
- "different from close offset: 2"));
-
- OnFinFrame(2u, "");
- OnFinFrame(0u, "a");
- EXPECT_FALSE(sequencer_->HasBytesToRead());
-}
-
-// Regression test for crbug.com/1015693
-TEST_F(QuicStreamSequencerTest, ReceiveFinLessThanHighestOffset) {
- EXPECT_CALL(stream_, OnDataAvailable()).Times(1);
- EXPECT_CALL(stream_, OnUnrecoverableError(
- QUIC_STREAM_SEQUENCER_INVALID_STATE,
- "Stream 1 received fin with offset: 0, which "
- "reduces current highest offset: 3"));
- OnFrame(0u, "abc");
- OnFinFrame(0u, "");
-}
-
-} // namespace
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_stream_test.cc b/chromium/net/third_party/quiche/src/quic/core/quic_stream_test.cc
deleted file mode 100644
index 9d48b1fa295..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_stream_test.cc
+++ /dev/null
@@ -1,1734 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_stream.h"
-
-#include <memory>
-#include <string>
-#include <utility>
-
-#include "absl/base/macros.h"
-#include "absl/memory/memory.h"
-#include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
-#include "quic/core/crypto/null_encrypter.h"
-#include "quic/core/frames/quic_rst_stream_frame.h"
-#include "quic/core/quic_connection.h"
-#include "quic/core/quic_constants.h"
-#include "quic/core/quic_error_codes.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_utils.h"
-#include "quic/core/quic_versions.h"
-#include "quic/core/quic_write_blocked_list.h"
-#include "quic/platform/api/quic_expect_bug.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/platform/api/quic_mem_slice_storage.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/quic_config_peer.h"
-#include "quic/test_tools/quic_connection_peer.h"
-#include "quic/test_tools/quic_flow_controller_peer.h"
-#include "quic/test_tools/quic_session_peer.h"
-#include "quic/test_tools/quic_stream_peer.h"
-#include "quic/test_tools/quic_stream_sequencer_peer.h"
-#include "quic/test_tools/quic_test_utils.h"
-
-using testing::_;
-using testing::AnyNumber;
-using testing::AtLeast;
-using testing::InSequence;
-using testing::Invoke;
-using testing::InvokeWithoutArgs;
-using testing::Return;
-using testing::StrictMock;
-
-namespace quic {
-namespace test {
-namespace {
-
-const char kData1[] = "FooAndBar";
-const char kData2[] = "EepAndBaz";
-const QuicByteCount kDataLen = 9;
-
-class TestStream : public QuicStream {
- public:
- TestStream(QuicStreamId id, QuicSession* session, StreamType type)
- : QuicStream(id, session, /*is_static=*/false, type) {
- sequencer()->set_level_triggered(true);
- }
-
- TestStream(PendingStream* pending, QuicSession* session, bool is_static)
- : QuicStream(pending, session, is_static) {}
-
- MOCK_METHOD(void, OnDataAvailable, (), (override));
-
- MOCK_METHOD(void, OnCanWriteNewData, (), (override));
-
- MOCK_METHOD(void, OnWriteSideInDataRecvdState, (), (override));
-
- using QuicStream::CanWriteNewData;
- using QuicStream::CanWriteNewDataAfterData;
- using QuicStream::CloseWriteSide;
- using QuicStream::fin_buffered;
- using QuicStream::MaybeSendStopSending;
- using QuicStream::OnClose;
- using QuicStream::WriteMemSlices;
- using QuicStream::WriteOrBufferData;
-
- private:
- std::string data_;
-};
-
-class QuicStreamTest : public QuicTestWithParam<ParsedQuicVersion> {
- public:
- QuicStreamTest()
- : zero_(QuicTime::Delta::Zero()),
- supported_versions_(AllSupportedVersions()) {}
-
- void Initialize(Perspective perspective = Perspective::IS_SERVER) {
- ParsedQuicVersionVector version_vector;
- version_vector.push_back(GetParam());
- connection_ = new StrictMock<MockQuicConnection>(
- &helper_, &alarm_factory_, perspective, version_vector);
- connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
- session_ = std::make_unique<StrictMock<MockQuicSession>>(connection_);
- session_->Initialize();
- connection_->SetEncrypter(
- ENCRYPTION_FORWARD_SECURE,
- std::make_unique<NullEncrypter>(connection_->perspective()));
- QuicConfigPeer::SetReceivedInitialSessionFlowControlWindow(
- session_->config(), kMinimumFlowControlSendWindow);
- QuicConfigPeer::SetReceivedInitialMaxStreamDataBytesUnidirectional(
- session_->config(), kMinimumFlowControlSendWindow);
- QuicConfigPeer::SetReceivedInitialMaxStreamDataBytesIncomingBidirectional(
- session_->config(), kMinimumFlowControlSendWindow);
- QuicConfigPeer::SetReceivedInitialMaxStreamDataBytesOutgoingBidirectional(
- session_->config(), kMinimumFlowControlSendWindow);
- QuicConfigPeer::SetReceivedMaxUnidirectionalStreams(session_->config(), 10);
- session_->OnConfigNegotiated();
-
- stream_ = new StrictMock<TestStream>(kTestStreamId, session_.get(),
- BIDIRECTIONAL);
- EXPECT_NE(nullptr, stream_);
- // session_ now owns stream_.
- session_->ActivateStream(absl::WrapUnique(stream_));
- // Ignore resetting when session_ is terminated.
- EXPECT_CALL(*session_, MaybeSendStopSendingFrame(kTestStreamId, _))
- .Times(AnyNumber());
- EXPECT_CALL(*session_, MaybeSendRstStreamFrame(kTestStreamId, _, _))
- .Times(AnyNumber());
- write_blocked_list_ =
- QuicSessionPeer::GetWriteBlockedStreams(session_.get());
- }
-
- bool fin_sent() { return stream_->fin_sent(); }
- bool rst_sent() { return stream_->rst_sent(); }
-
- bool HasWriteBlockedStreams() {
- return write_blocked_list_->HasWriteBlockedSpecialStream() ||
- write_blocked_list_->HasWriteBlockedDataStreams();
- }
-
- QuicConsumedData CloseStreamOnWriteError(
- QuicStreamId id, QuicByteCount /*write_length*/,
- QuicStreamOffset /*offset*/, StreamSendingState /*state*/,
- TransmissionType /*type*/, absl::optional<EncryptionLevel> /*level*/) {
- session_->ResetStream(id, QUIC_STREAM_CANCELLED);
- return QuicConsumedData(1, false);
- }
-
- bool ClearResetStreamFrame(const QuicFrame& frame) {
- EXPECT_EQ(RST_STREAM_FRAME, frame.type);
- DeleteFrame(&const_cast<QuicFrame&>(frame));
- return true;
- }
-
- bool ClearStopSendingFrame(const QuicFrame& frame) {
- EXPECT_EQ(STOP_SENDING_FRAME, frame.type);
- DeleteFrame(&const_cast<QuicFrame&>(frame));
- return true;
- }
-
- protected:
- MockQuicConnectionHelper helper_;
- MockAlarmFactory alarm_factory_;
- MockQuicConnection* connection_;
- std::unique_ptr<MockQuicSession> session_;
- StrictMock<TestStream>* stream_;
- QuicWriteBlockedList* write_blocked_list_;
- QuicTime::Delta zero_;
- ParsedQuicVersionVector supported_versions_;
- QuicStreamId kTestStreamId =
- GetNthClientInitiatedBidirectionalStreamId(GetParam().transport_version,
- 1);
- const QuicStreamId kTestPendingStreamId =
- GetNthClientInitiatedUnidirectionalStreamId(GetParam().transport_version,
- 1);
-};
-
-INSTANTIATE_TEST_SUITE_P(QuicStreamTests, QuicStreamTest,
- ::testing::ValuesIn(AllSupportedVersions()),
- ::testing::PrintToStringParamName());
-
-using PendingStreamTest = QuicStreamTest;
-
-INSTANTIATE_TEST_SUITE_P(PendingStreamTests, PendingStreamTest,
- ::testing::ValuesIn(CurrentSupportedHttp3Versions()),
- ::testing::PrintToStringParamName());
-
-TEST_P(PendingStreamTest, PendingStreamStaticness) {
- Initialize();
-
- PendingStream pending(kTestPendingStreamId, session_.get());
- TestStream stream(&pending, session_.get(), false);
- EXPECT_FALSE(stream.is_static());
-
- PendingStream pending2(kTestPendingStreamId + 4, session_.get());
- TestStream stream2(&pending2, session_.get(), true);
- EXPECT_TRUE(stream2.is_static());
-}
-
-TEST_P(PendingStreamTest, PendingStreamType) {
- Initialize();
-
- PendingStream pending(kTestPendingStreamId, session_.get());
- TestStream stream(&pending, session_.get(), false);
- EXPECT_EQ(stream.type(), READ_UNIDIRECTIONAL);
-}
-
-TEST_P(PendingStreamTest, PendingStreamTypeOnClient) {
- Initialize(Perspective::IS_CLIENT);
-
- QuicStreamId server_initiated_pending_stream_id =
- GetNthServerInitiatedUnidirectionalStreamId(session_->transport_version(),
- 1);
- PendingStream pending(server_initiated_pending_stream_id, session_.get());
- TestStream stream(&pending, session_.get(), false);
- EXPECT_EQ(stream.type(), READ_UNIDIRECTIONAL);
-}
-
-TEST_P(PendingStreamTest, PendingStreamTooMuchData) {
- Initialize();
-
- PendingStream pending(kTestPendingStreamId, session_.get());
- // Receive a stream frame that violates flow control: the byte offset is
- // higher than the receive window offset.
- QuicStreamFrame frame(kTestPendingStreamId, false,
- kInitialSessionFlowControlWindowForTest + 1, ".");
-
- // Stream should not accept the frame, and the connection should be closed.
- EXPECT_CALL(*connection_,
- CloseConnection(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA, _, _));
- pending.OnStreamFrame(frame);
-}
-
-TEST_P(PendingStreamTest, PendingStreamTooMuchDataInRstStream) {
- Initialize();
-
- PendingStream pending1(kTestPendingStreamId, session_.get());
- // Receive a rst stream frame that violates flow control: the byte offset is
- // higher than the receive window offset.
- QuicRstStreamFrame frame1(kInvalidControlFrameId, kTestPendingStreamId,
- QUIC_STREAM_CANCELLED,
- kInitialSessionFlowControlWindowForTest + 1);
-
- // Pending stream should not accept the frame, and the connection should be
- // closed.
- EXPECT_CALL(*connection_,
- CloseConnection(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA, _, _));
- pending1.OnRstStreamFrame(frame1);
-
- QuicStreamId bidirection_stream_id = QuicUtils::GetFirstBidirectionalStreamId(
- session_->transport_version(), Perspective::IS_CLIENT);
- PendingStream pending2(bidirection_stream_id, session_.get());
- // Receive a rst stream frame that violates flow control: the byte offset is
- // higher than the receive window offset.
- QuicRstStreamFrame frame2(kInvalidControlFrameId, bidirection_stream_id,
- QUIC_STREAM_CANCELLED,
- kInitialSessionFlowControlWindowForTest + 1);
- // Bidirectional Pending stream should not accept the frame, and the
- // connection should be closed.
- EXPECT_CALL(*connection_,
- CloseConnection(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA, _, _));
- pending2.OnRstStreamFrame(frame2);
-}
-
-TEST_P(PendingStreamTest, PendingStreamRstStream) {
- Initialize();
-
- PendingStream pending(kTestPendingStreamId, session_.get());
- QuicStreamOffset final_byte_offset = 7;
- QuicRstStreamFrame frame(kInvalidControlFrameId, kTestPendingStreamId,
- QUIC_STREAM_CANCELLED, final_byte_offset);
-
- // Pending stream should accept the frame and not close the connection.
- EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
- pending.OnRstStreamFrame(frame);
-}
-
-TEST_P(PendingStreamTest, PendingStreamWindowUpdate) {
- Initialize();
-
- QuicStreamId bidirection_stream_id = QuicUtils::GetFirstBidirectionalStreamId(
- session_->transport_version(), Perspective::IS_CLIENT);
- PendingStream pending(bidirection_stream_id, session_.get());
- QuicWindowUpdateFrame frame(kInvalidControlFrameId, bidirection_stream_id,
- kDefaultFlowControlSendWindow * 2);
- pending.OnWindowUpdateFrame(frame);
- TestStream stream(&pending, session_.get(), false);
-
- EXPECT_EQ(QuicStreamPeer::SendWindowSize(&stream),
- kDefaultFlowControlSendWindow * 2);
-}
-
-TEST_P(PendingStreamTest, PendingStreamStopSending) {
- Initialize();
-
- QuicStreamId bidirection_stream_id = QuicUtils::GetFirstBidirectionalStreamId(
- session_->transport_version(), Perspective::IS_CLIENT);
- PendingStream pending(bidirection_stream_id, session_.get());
- QuicResetStreamError error =
- QuicResetStreamError::FromInternal(QUIC_STREAM_INTERNAL_ERROR);
- pending.OnStopSending(error);
- EXPECT_TRUE(pending.GetStopSendingErrorCode());
- auto actual_error = *pending.GetStopSendingErrorCode();
- EXPECT_EQ(actual_error, error);
-}
-
-TEST_P(PendingStreamTest, FromPendingStream) {
- Initialize();
-
- PendingStream pending(kTestPendingStreamId, session_.get());
-
- QuicStreamFrame frame(kTestPendingStreamId, false, 2, ".");
- pending.OnStreamFrame(frame);
- pending.OnStreamFrame(frame);
- QuicStreamFrame frame2(kTestPendingStreamId, true, 3, ".");
- pending.OnStreamFrame(frame2);
-
- TestStream stream(&pending, session_.get(), false);
- EXPECT_EQ(3, stream.num_frames_received());
- EXPECT_EQ(3u, stream.stream_bytes_read());
- EXPECT_EQ(1, stream.num_duplicate_frames_received());
- EXPECT_EQ(true, stream.fin_received());
- EXPECT_EQ(frame2.offset + 1, stream.highest_received_byte_offset());
- EXPECT_EQ(frame2.offset + 1,
- session_->flow_controller()->highest_received_byte_offset());
-}
-
-TEST_P(PendingStreamTest, FromPendingStreamThenData) {
- Initialize();
-
- PendingStream pending(kTestPendingStreamId, session_.get());
-
- QuicStreamFrame frame(kTestPendingStreamId, false, 2, ".");
- pending.OnStreamFrame(frame);
-
- auto stream = new TestStream(&pending, session_.get(), false);
- session_->ActivateStream(absl::WrapUnique(stream));
-
- QuicStreamFrame frame2(kTestPendingStreamId, true, 3, ".");
- stream->OnStreamFrame(frame2);
-
- EXPECT_EQ(2, stream->num_frames_received());
- EXPECT_EQ(2u, stream->stream_bytes_read());
- EXPECT_EQ(true, stream->fin_received());
- EXPECT_EQ(frame2.offset + 1, stream->highest_received_byte_offset());
- EXPECT_EQ(frame2.offset + 1,
- session_->flow_controller()->highest_received_byte_offset());
-}
-
-TEST_P(QuicStreamTest, WriteAllData) {
- Initialize();
-
- QuicByteCount length =
- 1 + QuicPacketCreator::StreamFramePacketOverhead(
- connection_->transport_version(), PACKET_8BYTE_CONNECTION_ID,
- PACKET_0BYTE_CONNECTION_ID, !kIncludeVersion,
- !kIncludeDiversificationNonce, PACKET_4BYTE_PACKET_NUMBER,
- VARIABLE_LENGTH_INTEGER_LENGTH_0,
- VARIABLE_LENGTH_INTEGER_LENGTH_0, 0u);
- connection_->SetMaxPacketLength(length);
-
- EXPECT_CALL(*session_, WritevData(kTestStreamId, _, _, _, _, _))
- .WillOnce(Invoke(session_.get(), &MockQuicSession::ConsumeData));
- stream_->WriteOrBufferData(kData1, false, nullptr);
- EXPECT_FALSE(HasWriteBlockedStreams());
-}
-
-TEST_P(QuicStreamTest, NoBlockingIfNoDataOrFin) {
- Initialize();
-
- // Write no data and no fin. If we consume nothing we should not be write
- // blocked.
- EXPECT_QUIC_BUG(
- stream_->WriteOrBufferData(absl::string_view(), false, nullptr), "");
- EXPECT_FALSE(HasWriteBlockedStreams());
-}
-
-TEST_P(QuicStreamTest, BlockIfOnlySomeDataConsumed) {
- Initialize();
-
- // Write some data and no fin. If we consume some but not all of the data,
- // we should be write blocked a not all the data was consumed.
- EXPECT_CALL(*session_, WritevData(kTestStreamId, _, _, _, _, _))
- .WillOnce(InvokeWithoutArgs([this]() {
- return session_->ConsumeData(stream_->id(), 1u, 0u, NO_FIN,
- NOT_RETRANSMISSION, absl::nullopt);
- }));
- stream_->WriteOrBufferData(absl::string_view(kData1, 2), false, nullptr);
- EXPECT_TRUE(session_->HasUnackedStreamData());
- ASSERT_EQ(1u, write_blocked_list_->NumBlockedStreams());
- EXPECT_EQ(1u, stream_->BufferedDataBytes());
-}
-
-TEST_P(QuicStreamTest, BlockIfFinNotConsumedWithData) {
- Initialize();
-
- // Write some data and no fin. If we consume all the data but not the fin,
- // we should be write blocked because the fin was not consumed.
- // (This should never actually happen as the fin should be sent out with the
- // last data)
- EXPECT_CALL(*session_, WritevData(kTestStreamId, _, _, _, _, _))
- .WillOnce(InvokeWithoutArgs([this]() {
- return session_->ConsumeData(stream_->id(), 2u, 0u, NO_FIN,
- NOT_RETRANSMISSION, absl::nullopt);
- }));
- stream_->WriteOrBufferData(absl::string_view(kData1, 2), true, nullptr);
- EXPECT_TRUE(session_->HasUnackedStreamData());
- ASSERT_EQ(1u, write_blocked_list_->NumBlockedStreams());
-}
-
-TEST_P(QuicStreamTest, BlockIfSoloFinNotConsumed) {
- Initialize();
-
- // Write no data and a fin. If we consume nothing we should be write blocked,
- // as the fin was not consumed.
- EXPECT_CALL(*session_, WritevData(kTestStreamId, _, _, _, _, _))
- .WillOnce(Return(QuicConsumedData(0, false)));
- stream_->WriteOrBufferData(absl::string_view(), true, nullptr);
- ASSERT_EQ(1u, write_blocked_list_->NumBlockedStreams());
-}
-
-TEST_P(QuicStreamTest, CloseOnPartialWrite) {
- Initialize();
-
- // Write some data and no fin. However, while writing the data
- // close the stream and verify that MarkConnectionLevelWriteBlocked does not
- // crash with an unknown stream.
- EXPECT_CALL(*session_, WritevData(kTestStreamId, _, _, _, _, _))
- .WillOnce(Invoke(this, &QuicStreamTest::CloseStreamOnWriteError));
- stream_->WriteOrBufferData(absl::string_view(kData1, 2), false, nullptr);
- ASSERT_EQ(0u, write_blocked_list_->NumBlockedStreams());
-}
-
-TEST_P(QuicStreamTest, WriteOrBufferData) {
- Initialize();
-
- EXPECT_FALSE(HasWriteBlockedStreams());
- QuicByteCount length =
- 1 + QuicPacketCreator::StreamFramePacketOverhead(
- connection_->transport_version(), PACKET_8BYTE_CONNECTION_ID,
- PACKET_0BYTE_CONNECTION_ID, !kIncludeVersion,
- !kIncludeDiversificationNonce, PACKET_4BYTE_PACKET_NUMBER,
- VARIABLE_LENGTH_INTEGER_LENGTH_0,
- VARIABLE_LENGTH_INTEGER_LENGTH_0, 0u);
- connection_->SetMaxPacketLength(length);
-
- EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
- .WillOnce(InvokeWithoutArgs([this]() {
- return session_->ConsumeData(stream_->id(), kDataLen - 1, 0u, NO_FIN,
- NOT_RETRANSMISSION, absl::nullopt);
- }));
- stream_->WriteOrBufferData(kData1, false, nullptr);
-
- EXPECT_TRUE(session_->HasUnackedStreamData());
- EXPECT_EQ(1u, stream_->BufferedDataBytes());
- EXPECT_TRUE(HasWriteBlockedStreams());
-
- // Queue a bytes_consumed write.
- stream_->WriteOrBufferData(kData2, false, nullptr);
- EXPECT_EQ(10u, stream_->BufferedDataBytes());
- // Make sure we get the tail of the first write followed by the bytes_consumed
- InSequence s;
- EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
- .WillOnce(InvokeWithoutArgs([this]() {
- return session_->ConsumeData(stream_->id(), kDataLen - 1, kDataLen - 1,
- NO_FIN, NOT_RETRANSMISSION, absl::nullopt);
- }));
- EXPECT_CALL(*stream_, OnCanWriteNewData());
- stream_->OnCanWrite();
- EXPECT_TRUE(session_->HasUnackedStreamData());
-
- // And finally the end of the bytes_consumed.
- EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
- .WillOnce(InvokeWithoutArgs([this]() {
- return session_->ConsumeData(stream_->id(), 2u, 2 * kDataLen - 2,
- NO_FIN, NOT_RETRANSMISSION, absl::nullopt);
- }));
- EXPECT_CALL(*stream_, OnCanWriteNewData());
- stream_->OnCanWrite();
- EXPECT_TRUE(session_->HasUnackedStreamData());
-}
-
-TEST_P(QuicStreamTest, WriteOrBufferDataReachStreamLimit) {
- Initialize();
- std::string data("aaaaa");
- QuicStreamPeer::SetStreamBytesWritten(kMaxStreamLength - data.length(),
- stream_);
- EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
- .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");
-}
-
-TEST_P(QuicStreamTest, ConnectionCloseAfterStreamClose) {
- Initialize();
-
- QuicRstStreamFrame rst_frame(kInvalidControlFrameId, stream_->id(),
- QUIC_STREAM_CANCELLED, 1234);
- stream_->OnStreamReset(rst_frame);
- if (VersionHasIetfQuicFrames(session_->transport_version())) {
- // Create and inject a STOP SENDING frame to complete the close
- // of the stream. This is only needed for version 99/IETF QUIC.
- QuicStopSendingFrame stop_sending(kInvalidControlFrameId, stream_->id(),
- QUIC_STREAM_CANCELLED);
- session_->OnStopSendingFrame(stop_sending);
- }
- EXPECT_THAT(stream_->stream_error(), IsStreamError(QUIC_STREAM_CANCELLED));
- EXPECT_THAT(stream_->connection_error(), IsQuicNoError());
- stream_->OnConnectionClosed(QUIC_INTERNAL_ERROR,
- ConnectionCloseSource::FROM_SELF);
- EXPECT_THAT(stream_->stream_error(), IsStreamError(QUIC_STREAM_CANCELLED));
- EXPECT_THAT(stream_->connection_error(), IsQuicNoError());
-}
-
-TEST_P(QuicStreamTest, RstAlwaysSentIfNoFinSent) {
- // For flow control accounting, a stream must send either a FIN or a RST frame
- // before termination.
- // Test that if no FIN has been sent, we send a RST.
-
- Initialize();
- EXPECT_FALSE(fin_sent());
- EXPECT_FALSE(rst_sent());
-
- // Write some data, with no FIN.
- EXPECT_CALL(*session_, WritevData(kTestStreamId, _, _, _, _, _))
- .WillOnce(InvokeWithoutArgs([this]() {
- return session_->ConsumeData(stream_->id(), 1u, 0u, NO_FIN,
- NOT_RETRANSMISSION, absl::nullopt);
- }));
- stream_->WriteOrBufferData(absl::string_view(kData1, 1), false, nullptr);
- EXPECT_TRUE(session_->HasUnackedStreamData());
- EXPECT_FALSE(fin_sent());
- EXPECT_FALSE(rst_sent());
-
- // Now close the stream, and expect that we send a RST.
- EXPECT_CALL(*session_, MaybeSendRstStreamFrame(kTestStreamId, _, _));
- QuicRstStreamFrame rst_frame(kInvalidControlFrameId, stream_->id(),
- QUIC_STREAM_CANCELLED, 1234);
- stream_->OnStreamReset(rst_frame);
- if (VersionHasIetfQuicFrames(session_->transport_version())) {
- // Create and inject a STOP SENDING frame to complete the close
- // of the stream. This is only needed for version 99/IETF QUIC.
- QuicStopSendingFrame stop_sending(kInvalidControlFrameId, stream_->id(),
- QUIC_STREAM_CANCELLED);
- session_->OnStopSendingFrame(stop_sending);
- }
- EXPECT_FALSE(session_->HasUnackedStreamData());
- EXPECT_FALSE(fin_sent());
- EXPECT_TRUE(rst_sent());
-}
-
-TEST_P(QuicStreamTest, RstNotSentIfFinSent) {
- // For flow control accounting, a stream must send either a FIN or a RST frame
- // before termination.
- // Test that if a FIN has been sent, we don't also send a RST.
-
- Initialize();
- EXPECT_FALSE(fin_sent());
- EXPECT_FALSE(rst_sent());
-
- // Write some data, with FIN.
- EXPECT_CALL(*session_, WritevData(kTestStreamId, _, _, _, _, _))
- .WillOnce(InvokeWithoutArgs([this]() {
- return session_->ConsumeData(stream_->id(), 1u, 0u, FIN,
- NOT_RETRANSMISSION, absl::nullopt);
- }));
- stream_->WriteOrBufferData(absl::string_view(kData1, 1), true, nullptr);
- EXPECT_TRUE(fin_sent());
- EXPECT_FALSE(rst_sent());
-
- // Now close the stream, and expect that we do not send a RST.
- QuicStreamPeer::CloseReadSide(stream_);
- stream_->CloseWriteSide();
- EXPECT_TRUE(fin_sent());
- EXPECT_FALSE(rst_sent());
-}
-
-TEST_P(QuicStreamTest, OnlySendOneRst) {
- // For flow control accounting, a stream must send either a FIN or a RST frame
- // before termination.
- // Test that if a stream sends a RST, it doesn't send an additional RST during
- // OnClose() (this shouldn't be harmful, but we shouldn't do it anyway...)
-
- Initialize();
- EXPECT_FALSE(fin_sent());
- EXPECT_FALSE(rst_sent());
-
- // Reset the stream.
- EXPECT_CALL(*session_, MaybeSendRstStreamFrame(kTestStreamId, _, _)).Times(1);
- stream_->Reset(QUIC_STREAM_CANCELLED);
- EXPECT_FALSE(fin_sent());
- EXPECT_TRUE(rst_sent());
-
- // Now close the stream (any further resets being sent would break the
- // expectation above).
- QuicStreamPeer::CloseReadSide(stream_);
- stream_->CloseWriteSide();
- EXPECT_FALSE(fin_sent());
- EXPECT_TRUE(rst_sent());
-}
-
-TEST_P(QuicStreamTest, StreamFlowControlMultipleWindowUpdates) {
- Initialize();
-
- // If we receive multiple WINDOW_UPDATES (potentially out of order), then we
- // want to make sure we latch the largest offset we see.
-
- // Initially should be default.
- EXPECT_EQ(kMinimumFlowControlSendWindow,
- QuicStreamPeer::SendWindowOffset(stream_));
-
- // Check a single WINDOW_UPDATE results in correct offset.
- QuicWindowUpdateFrame window_update_1(kInvalidControlFrameId, stream_->id(),
- kMinimumFlowControlSendWindow + 5);
- stream_->OnWindowUpdateFrame(window_update_1);
- EXPECT_EQ(window_update_1.max_data,
- QuicStreamPeer::SendWindowOffset(stream_));
-
- // Now send a few more WINDOW_UPDATES and make sure that only the largest is
- // remembered.
- QuicWindowUpdateFrame window_update_2(kInvalidControlFrameId, stream_->id(),
- 1);
- QuicWindowUpdateFrame window_update_3(kInvalidControlFrameId, stream_->id(),
- kMinimumFlowControlSendWindow + 10);
- QuicWindowUpdateFrame window_update_4(kInvalidControlFrameId, stream_->id(),
- 5678);
- stream_->OnWindowUpdateFrame(window_update_2);
- stream_->OnWindowUpdateFrame(window_update_3);
- stream_->OnWindowUpdateFrame(window_update_4);
- EXPECT_EQ(window_update_3.max_data,
- QuicStreamPeer::SendWindowOffset(stream_));
-}
-
-TEST_P(QuicStreamTest, FrameStats) {
- Initialize();
-
- EXPECT_EQ(0, stream_->num_frames_received());
- EXPECT_EQ(0, stream_->num_duplicate_frames_received());
- QuicStreamFrame frame(stream_->id(), false, 0, ".");
- EXPECT_CALL(*stream_, OnDataAvailable()).Times(2);
- stream_->OnStreamFrame(frame);
- EXPECT_EQ(1, stream_->num_frames_received());
- EXPECT_EQ(0, stream_->num_duplicate_frames_received());
- stream_->OnStreamFrame(frame);
- EXPECT_EQ(2, stream_->num_frames_received());
- EXPECT_EQ(1, stream_->num_duplicate_frames_received());
- QuicStreamFrame frame2(stream_->id(), false, 1, "abc");
- stream_->OnStreamFrame(frame2);
-}
-
-// Verify that when we receive a packet which violates flow control (i.e. sends
-// too much data on the stream) that the stream sequencer never sees this frame,
-// as we check for violation and close the connection early.
-TEST_P(QuicStreamTest, StreamSequencerNeverSeesPacketsViolatingFlowControl) {
- Initialize();
-
- // Receive a stream frame that violates flow control: the byte offset is
- // higher than the receive window offset.
- QuicStreamFrame frame(stream_->id(), false,
- kInitialSessionFlowControlWindowForTest + 1, ".");
- EXPECT_GT(frame.offset, QuicStreamPeer::ReceiveWindowOffset(stream_));
-
- // Stream should not accept the frame, and the connection should be closed.
- EXPECT_CALL(*connection_,
- CloseConnection(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA, _, _));
- stream_->OnStreamFrame(frame);
-}
-
-// Verify that after the consumer calls StopReading(), the stream still sends
-// flow control updates.
-TEST_P(QuicStreamTest, StopReadingSendsFlowControl) {
- Initialize();
-
- stream_->StopReading();
-
- // Connection should not get terminated due to flow control errors.
- EXPECT_CALL(*connection_,
- CloseConnection(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA, _, _))
- .Times(0);
- EXPECT_CALL(*session_, WriteControlFrame(_, _))
- .Times(AtLeast(1))
- .WillRepeatedly(Invoke(&ClearControlFrameWithTransmissionType));
-
- std::string data(1000, 'x');
- for (QuicStreamOffset offset = 0;
- offset < 2 * kInitialStreamFlowControlWindowForTest;
- offset += data.length()) {
- QuicStreamFrame frame(stream_->id(), false, offset, data);
- stream_->OnStreamFrame(frame);
- }
- EXPECT_LT(kInitialStreamFlowControlWindowForTest,
- QuicStreamPeer::ReceiveWindowOffset(stream_));
-}
-
-TEST_P(QuicStreamTest, FinalByteOffsetFromFin) {
- Initialize();
-
- EXPECT_FALSE(stream_->HasReceivedFinalOffset());
-
- QuicStreamFrame stream_frame_no_fin(stream_->id(), false, 1234, ".");
- stream_->OnStreamFrame(stream_frame_no_fin);
- EXPECT_FALSE(stream_->HasReceivedFinalOffset());
-
- QuicStreamFrame stream_frame_with_fin(stream_->id(), true, 1234, ".");
- stream_->OnStreamFrame(stream_frame_with_fin);
- EXPECT_TRUE(stream_->HasReceivedFinalOffset());
-}
-
-TEST_P(QuicStreamTest, FinalByteOffsetFromRst) {
- Initialize();
-
- EXPECT_FALSE(stream_->HasReceivedFinalOffset());
- QuicRstStreamFrame rst_frame(kInvalidControlFrameId, stream_->id(),
- QUIC_STREAM_CANCELLED, 1234);
- stream_->OnStreamReset(rst_frame);
- EXPECT_TRUE(stream_->HasReceivedFinalOffset());
-}
-
-TEST_P(QuicStreamTest, InvalidFinalByteOffsetFromRst) {
- Initialize();
-
- EXPECT_FALSE(stream_->HasReceivedFinalOffset());
- QuicRstStreamFrame rst_frame(kInvalidControlFrameId, stream_->id(),
- QUIC_STREAM_CANCELLED, 0xFFFFFFFFFFFF);
- // Stream should not accept the frame, and the connection should be closed.
- EXPECT_CALL(*connection_,
- CloseConnection(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA, _, _));
- stream_->OnStreamReset(rst_frame);
- EXPECT_TRUE(stream_->HasReceivedFinalOffset());
-}
-
-TEST_P(QuicStreamTest, FinalByteOffsetFromZeroLengthStreamFrame) {
- // When receiving Trailers, an empty stream frame is created with the FIN set,
- // and is passed to OnStreamFrame. The Trailers may be sent in advance of
- // queued body bytes being sent, and thus the final byte offset may exceed
- // current flow control limits. Flow control should only be concerned with
- // data that has actually been sent/received, so verify that flow control
- // ignores such a stream frame.
- Initialize();
-
- EXPECT_FALSE(stream_->HasReceivedFinalOffset());
- const QuicStreamOffset kByteOffsetExceedingFlowControlWindow =
- kInitialSessionFlowControlWindowForTest + 1;
- const QuicStreamOffset current_stream_flow_control_offset =
- QuicStreamPeer::ReceiveWindowOffset(stream_);
- const QuicStreamOffset current_connection_flow_control_offset =
- QuicFlowControllerPeer::ReceiveWindowOffset(session_->flow_controller());
- ASSERT_GT(kByteOffsetExceedingFlowControlWindow,
- current_stream_flow_control_offset);
- ASSERT_GT(kByteOffsetExceedingFlowControlWindow,
- current_connection_flow_control_offset);
- QuicStreamFrame zero_length_stream_frame_with_fin(
- stream_->id(), /*fin=*/true, kByteOffsetExceedingFlowControlWindow,
- absl::string_view());
- EXPECT_EQ(0, zero_length_stream_frame_with_fin.data_length);
-
- EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
- stream_->OnStreamFrame(zero_length_stream_frame_with_fin);
- EXPECT_TRUE(stream_->HasReceivedFinalOffset());
-
- // The flow control receive offset values should not have changed.
- EXPECT_EQ(current_stream_flow_control_offset,
- QuicStreamPeer::ReceiveWindowOffset(stream_));
- EXPECT_EQ(
- current_connection_flow_control_offset,
- QuicFlowControllerPeer::ReceiveWindowOffset(session_->flow_controller()));
-}
-
-TEST_P(QuicStreamTest, OnStreamResetOffsetOverflow) {
- Initialize();
- QuicRstStreamFrame rst_frame(kInvalidControlFrameId, stream_->id(),
- QUIC_STREAM_CANCELLED, kMaxStreamLength + 1);
- EXPECT_CALL(*connection_, CloseConnection(QUIC_STREAM_LENGTH_OVERFLOW, _, _));
- stream_->OnStreamReset(rst_frame);
-}
-
-TEST_P(QuicStreamTest, OnStreamFrameUpperLimit) {
- Initialize();
-
- // Modify receive window offset and sequencer buffer total_bytes_read_ to
- // avoid flow control violation.
- QuicStreamPeer::SetReceiveWindowOffset(stream_, kMaxStreamLength + 5u);
- QuicFlowControllerPeer::SetReceiveWindowOffset(session_->flow_controller(),
- kMaxStreamLength + 5u);
- QuicStreamSequencerPeer::SetFrameBufferTotalBytesRead(
- QuicStreamPeer::sequencer(stream_), kMaxStreamLength - 10u);
-
- EXPECT_CALL(*connection_, CloseConnection(QUIC_STREAM_LENGTH_OVERFLOW, _, _))
- .Times(0);
- QuicStreamFrame stream_frame(stream_->id(), false, kMaxStreamLength - 1, ".");
- stream_->OnStreamFrame(stream_frame);
- QuicStreamFrame stream_frame2(stream_->id(), true, kMaxStreamLength, "");
- stream_->OnStreamFrame(stream_frame2);
-}
-
-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),
- absl::StrCat("Receive stream frame on stream ", stream_->id(),
- " reaches max stream length"));
-}
-
-TEST_P(QuicStreamTest, SetDrainingIncomingOutgoing) {
- // Don't have incoming data consumed.
- Initialize();
-
- // Incoming data with FIN.
- QuicStreamFrame stream_frame_with_fin(stream_->id(), true, 1234, ".");
- stream_->OnStreamFrame(stream_frame_with_fin);
- // The FIN has been received but not consumed.
- EXPECT_TRUE(stream_->HasReceivedFinalOffset());
- EXPECT_FALSE(QuicStreamPeer::read_side_closed(stream_));
- EXPECT_FALSE(stream_->reading_stopped());
-
- EXPECT_EQ(1u, QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()));
-
- // Outgoing data with FIN.
- EXPECT_CALL(*session_, WritevData(kTestStreamId, _, _, _, _, _))
- .WillOnce(InvokeWithoutArgs([this]() {
- return session_->ConsumeData(stream_->id(), 2u, 0u, FIN,
- NOT_RETRANSMISSION, absl::nullopt);
- }));
- stream_->WriteOrBufferData(absl::string_view(kData1, 2), true, nullptr);
- EXPECT_TRUE(stream_->write_side_closed());
-
- EXPECT_EQ(1u, QuicSessionPeer::GetNumDrainingStreams(session_.get()));
- EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()));
-}
-
-TEST_P(QuicStreamTest, SetDrainingOutgoingIncoming) {
- // Don't have incoming data consumed.
- Initialize();
-
- // Outgoing data with FIN.
- EXPECT_CALL(*session_, WritevData(kTestStreamId, _, _, _, _, _))
- .WillOnce(InvokeWithoutArgs([this]() {
- return session_->ConsumeData(stream_->id(), 2u, 0u, FIN,
- NOT_RETRANSMISSION, absl::nullopt);
- }));
- stream_->WriteOrBufferData(absl::string_view(kData1, 2), true, nullptr);
- EXPECT_TRUE(stream_->write_side_closed());
-
- EXPECT_EQ(1u, QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()));
-
- // Incoming data with FIN.
- QuicStreamFrame stream_frame_with_fin(stream_->id(), true, 1234, ".");
- stream_->OnStreamFrame(stream_frame_with_fin);
- // The FIN has been received but not consumed.
- EXPECT_TRUE(stream_->HasReceivedFinalOffset());
- EXPECT_FALSE(QuicStreamPeer::read_side_closed(stream_));
- EXPECT_FALSE(stream_->reading_stopped());
-
- EXPECT_EQ(1u, QuicSessionPeer::GetNumDrainingStreams(session_.get()));
- EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()));
-}
-
-TEST_P(QuicStreamTest, EarlyResponseFinHandling) {
- // Verify that if the server completes the response before reading the end of
- // the request, the received FIN is recorded.
-
- Initialize();
- EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
- EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
- .WillRepeatedly(Invoke(session_.get(), &MockQuicSession::ConsumeData));
-
- // Receive data for the request.
- EXPECT_CALL(*stream_, OnDataAvailable()).Times(1);
- QuicStreamFrame frame1(stream_->id(), false, 0, "Start");
- stream_->OnStreamFrame(frame1);
- // When QuicSimpleServerStream sends the response, it calls
- // QuicStream::CloseReadSide() first.
- QuicStreamPeer::CloseReadSide(stream_);
- // Send data and FIN for the response.
- stream_->WriteOrBufferData(kData1, false, nullptr);
- EXPECT_TRUE(QuicStreamPeer::read_side_closed(stream_));
- // Receive remaining data and FIN for the request.
- QuicStreamFrame frame2(stream_->id(), true, 0, "End");
- stream_->OnStreamFrame(frame2);
- EXPECT_TRUE(stream_->fin_received());
- EXPECT_TRUE(stream_->HasReceivedFinalOffset());
-}
-
-TEST_P(QuicStreamTest, StreamWaitsForAcks) {
- Initialize();
- EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
- .WillRepeatedly(Invoke(session_.get(), &MockQuicSession::ConsumeData));
- // Stream is not waiting for acks initially.
- EXPECT_FALSE(stream_->IsWaitingForAcks());
- EXPECT_EQ(0u, QuicStreamPeer::SendBuffer(stream_).size());
- EXPECT_FALSE(session_->HasUnackedStreamData());
-
- // Send kData1.
- stream_->WriteOrBufferData(kData1, false, nullptr);
- EXPECT_TRUE(session_->HasUnackedStreamData());
- EXPECT_EQ(1u, QuicStreamPeer::SendBuffer(stream_).size());
- EXPECT_TRUE(stream_->IsWaitingForAcks());
- QuicByteCount newly_acked_length = 0;
- EXPECT_TRUE(stream_->OnStreamFrameAcked(0, 9, false, QuicTime::Delta::Zero(),
- QuicTime::Zero(),
- &newly_acked_length));
- EXPECT_EQ(9u, newly_acked_length);
- // Stream is not waiting for acks as all sent data is acked.
- EXPECT_FALSE(stream_->IsWaitingForAcks());
- EXPECT_FALSE(session_->HasUnackedStreamData());
- EXPECT_EQ(0u, QuicStreamPeer::SendBuffer(stream_).size());
-
- // Send kData2.
- stream_->WriteOrBufferData(kData2, false, nullptr);
- EXPECT_TRUE(stream_->IsWaitingForAcks());
- EXPECT_TRUE(session_->HasUnackedStreamData());
- EXPECT_EQ(1u, QuicStreamPeer::SendBuffer(stream_).size());
- // Send FIN.
- stream_->WriteOrBufferData("", true, nullptr);
- // Fin only frame is not stored in send buffer.
- EXPECT_EQ(1u, QuicStreamPeer::SendBuffer(stream_).size());
-
- // kData2 is retransmitted.
- stream_->OnStreamFrameRetransmitted(9, 9, false);
-
- // kData2 is acked.
- EXPECT_TRUE(stream_->OnStreamFrameAcked(9, 9, false, QuicTime::Delta::Zero(),
- QuicTime::Zero(),
- &newly_acked_length));
- EXPECT_EQ(9u, newly_acked_length);
- // Stream is waiting for acks as FIN is not acked.
- EXPECT_TRUE(stream_->IsWaitingForAcks());
- EXPECT_TRUE(session_->HasUnackedStreamData());
- EXPECT_EQ(0u, QuicStreamPeer::SendBuffer(stream_).size());
-
- // FIN is acked.
- EXPECT_CALL(*stream_, OnWriteSideInDataRecvdState());
- EXPECT_TRUE(stream_->OnStreamFrameAcked(18, 0, true, QuicTime::Delta::Zero(),
- QuicTime::Zero(),
- &newly_acked_length));
- EXPECT_EQ(0u, newly_acked_length);
- EXPECT_FALSE(stream_->IsWaitingForAcks());
- EXPECT_FALSE(session_->HasUnackedStreamData());
- EXPECT_EQ(0u, QuicStreamPeer::SendBuffer(stream_).size());
-}
-
-TEST_P(QuicStreamTest, StreamDataGetAckedOutOfOrder) {
- Initialize();
- EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
- .WillRepeatedly(Invoke(session_.get(), &MockQuicSession::ConsumeData));
- // Send data.
- stream_->WriteOrBufferData(kData1, false, nullptr);
- stream_->WriteOrBufferData(kData1, false, nullptr);
- stream_->WriteOrBufferData(kData1, false, nullptr);
- stream_->WriteOrBufferData("", true, nullptr);
- EXPECT_EQ(3u, QuicStreamPeer::SendBuffer(stream_).size());
- EXPECT_TRUE(stream_->IsWaitingForAcks());
- EXPECT_TRUE(session_->HasUnackedStreamData());
- QuicByteCount newly_acked_length = 0;
- EXPECT_TRUE(stream_->OnStreamFrameAcked(9, 9, false, QuicTime::Delta::Zero(),
- QuicTime::Zero(),
- &newly_acked_length));
- EXPECT_TRUE(session_->HasUnackedStreamData());
- EXPECT_EQ(9u, newly_acked_length);
- EXPECT_EQ(3u, QuicStreamPeer::SendBuffer(stream_).size());
- EXPECT_TRUE(stream_->OnStreamFrameAcked(18, 9, false, QuicTime::Delta::Zero(),
- QuicTime::Zero(),
- &newly_acked_length));
- EXPECT_TRUE(session_->HasUnackedStreamData());
- EXPECT_EQ(9u, newly_acked_length);
- EXPECT_EQ(3u, QuicStreamPeer::SendBuffer(stream_).size());
- EXPECT_TRUE(stream_->OnStreamFrameAcked(0, 9, false, QuicTime::Delta::Zero(),
- QuicTime::Zero(),
- &newly_acked_length));
- EXPECT_TRUE(session_->HasUnackedStreamData());
- EXPECT_EQ(9u, newly_acked_length);
- EXPECT_EQ(0u, QuicStreamPeer::SendBuffer(stream_).size());
- // FIN is not acked yet.
- EXPECT_TRUE(stream_->IsWaitingForAcks());
- EXPECT_TRUE(session_->HasUnackedStreamData());
- EXPECT_CALL(*stream_, OnWriteSideInDataRecvdState());
- EXPECT_TRUE(stream_->OnStreamFrameAcked(27, 0, true, QuicTime::Delta::Zero(),
- QuicTime::Zero(),
- &newly_acked_length));
- EXPECT_EQ(0u, newly_acked_length);
- EXPECT_FALSE(stream_->IsWaitingForAcks());
- EXPECT_FALSE(session_->HasUnackedStreamData());
-}
-
-TEST_P(QuicStreamTest, CancelStream) {
- Initialize();
- EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
- .WillRepeatedly(Invoke(session_.get(), &MockQuicSession::ConsumeData));
- EXPECT_FALSE(stream_->IsWaitingForAcks());
- EXPECT_FALSE(session_->HasUnackedStreamData());
- EXPECT_EQ(0u, QuicStreamPeer::SendBuffer(stream_).size());
-
- stream_->WriteOrBufferData(kData1, false, nullptr);
- EXPECT_TRUE(stream_->IsWaitingForAcks());
- EXPECT_TRUE(session_->HasUnackedStreamData());
- EXPECT_EQ(1u, QuicStreamPeer::SendBuffer(stream_).size());
- // Cancel stream.
- stream_->MaybeSendStopSending(QUIC_STREAM_NO_ERROR);
- // stream still waits for acks as the error code is QUIC_STREAM_NO_ERROR, and
- // data is going to be retransmitted.
- EXPECT_TRUE(stream_->IsWaitingForAcks());
- EXPECT_TRUE(session_->HasUnackedStreamData());
- EXPECT_CALL(*connection_,
- OnStreamReset(stream_->id(), QUIC_STREAM_CANCELLED));
- EXPECT_CALL(*session_, WriteControlFrame(_, _))
- .Times(AtLeast(1))
- .WillRepeatedly(Invoke(&ClearControlFrameWithTransmissionType));
-
- EXPECT_CALL(*session_, MaybeSendRstStreamFrame(_, _, _))
- .WillOnce(InvokeWithoutArgs([this]() {
- session_->ReallyMaybeSendRstStreamFrame(
- stream_->id(), QUIC_STREAM_CANCELLED,
- stream_->stream_bytes_written());
- }));
-
- stream_->Reset(QUIC_STREAM_CANCELLED);
- EXPECT_EQ(1u, QuicStreamPeer::SendBuffer(stream_).size());
- // Stream stops waiting for acks as data is not going to be retransmitted.
- EXPECT_FALSE(stream_->IsWaitingForAcks());
- EXPECT_FALSE(session_->HasUnackedStreamData());
-}
-
-TEST_P(QuicStreamTest, RstFrameReceivedStreamNotFinishSending) {
- if (VersionHasIetfQuicFrames(GetParam().transport_version)) {
- // In IETF QUIC, receiving a RESET_STREAM will only close the read side. The
- // stream itself is not closed and will not send reset.
- return;
- }
-
- Initialize();
- EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
- .WillRepeatedly(Invoke(session_.get(), &MockQuicSession::ConsumeData));
- EXPECT_FALSE(stream_->IsWaitingForAcks());
- EXPECT_FALSE(session_->HasUnackedStreamData());
- EXPECT_EQ(0u, QuicStreamPeer::SendBuffer(stream_).size());
-
- stream_->WriteOrBufferData(kData1, false, nullptr);
- EXPECT_TRUE(stream_->IsWaitingForAcks());
- EXPECT_TRUE(session_->HasUnackedStreamData());
- EXPECT_EQ(1u, QuicStreamPeer::SendBuffer(stream_).size());
-
- // RST_STREAM received.
- QuicRstStreamFrame rst_frame(kInvalidControlFrameId, stream_->id(),
- QUIC_STREAM_CANCELLED, 9);
-
- EXPECT_CALL(
- *session_,
- MaybeSendRstStreamFrame(
- stream_->id(),
- QuicResetStreamError::FromInternal(QUIC_RST_ACKNOWLEDGEMENT), 9));
- stream_->OnStreamReset(rst_frame);
- EXPECT_EQ(1u, QuicStreamPeer::SendBuffer(stream_).size());
- // Stream stops waiting for acks as it does not finish sending and rst is
- // sent.
- EXPECT_FALSE(stream_->IsWaitingForAcks());
- EXPECT_FALSE(session_->HasUnackedStreamData());
-}
-
-TEST_P(QuicStreamTest, RstFrameReceivedStreamFinishSending) {
- Initialize();
- EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
- .WillRepeatedly(Invoke(session_.get(), &MockQuicSession::ConsumeData));
- EXPECT_FALSE(stream_->IsWaitingForAcks());
- EXPECT_FALSE(session_->HasUnackedStreamData());
- EXPECT_EQ(0u, QuicStreamPeer::SendBuffer(stream_).size());
-
- stream_->WriteOrBufferData(kData1, true, nullptr);
- EXPECT_TRUE(stream_->IsWaitingForAcks());
- EXPECT_TRUE(session_->HasUnackedStreamData());
-
- // RST_STREAM received.
- QuicRstStreamFrame rst_frame(kInvalidControlFrameId, stream_->id(),
- QUIC_STREAM_CANCELLED, 1234);
- stream_->OnStreamReset(rst_frame);
- // Stream still waits for acks as it finishes sending and has unacked data.
- EXPECT_TRUE(stream_->IsWaitingForAcks());
- EXPECT_TRUE(session_->HasUnackedStreamData());
- EXPECT_EQ(1u, QuicStreamPeer::SendBuffer(stream_).size());
-}
-
-TEST_P(QuicStreamTest, ConnectionClosed) {
- Initialize();
- EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
- .WillRepeatedly(Invoke(session_.get(), &MockQuicSession::ConsumeData));
- EXPECT_FALSE(stream_->IsWaitingForAcks());
- EXPECT_FALSE(session_->HasUnackedStreamData());
- EXPECT_EQ(0u, QuicStreamPeer::SendBuffer(stream_).size());
-
- stream_->WriteOrBufferData(kData1, false, nullptr);
- EXPECT_TRUE(stream_->IsWaitingForAcks());
- EXPECT_TRUE(session_->HasUnackedStreamData());
- EXPECT_CALL(
- *session_,
- MaybeSendRstStreamFrame(
- stream_->id(),
- QuicResetStreamError::FromInternal(QUIC_RST_ACKNOWLEDGEMENT), 9));
- QuicConnectionPeer::SetConnectionClose(connection_);
- stream_->OnConnectionClosed(QUIC_INTERNAL_ERROR,
- ConnectionCloseSource::FROM_SELF);
- EXPECT_EQ(1u, QuicStreamPeer::SendBuffer(stream_).size());
- // Stream stops waiting for acks as connection is going to close.
- EXPECT_FALSE(stream_->IsWaitingForAcks());
- EXPECT_FALSE(session_->HasUnackedStreamData());
-}
-
-TEST_P(QuicStreamTest, CanWriteNewDataAfterData) {
- SetQuicFlag(FLAGS_quic_buffered_data_threshold, 100);
- Initialize();
- EXPECT_TRUE(stream_->CanWriteNewDataAfterData(99));
- EXPECT_FALSE(stream_->CanWriteNewDataAfterData(100));
-}
-
-TEST_P(QuicStreamTest, WriteBufferedData) {
- // Set buffered data low water mark to be 100.
- SetQuicFlag(FLAGS_quic_buffered_data_threshold, 100);
-
- Initialize();
- std::string data(1024, 'a');
- EXPECT_TRUE(stream_->CanWriteNewData());
-
- // Testing WriteOrBufferData.
- EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
- .WillOnce(InvokeWithoutArgs([this]() {
- return session_->ConsumeData(stream_->id(), 100u, 0u, NO_FIN,
- NOT_RETRANSMISSION, absl::nullopt);
- }));
- stream_->WriteOrBufferData(data, false, nullptr);
- stream_->WriteOrBufferData(data, false, nullptr);
- stream_->WriteOrBufferData(data, false, nullptr);
- EXPECT_TRUE(stream_->IsWaitingForAcks());
-
- // Verify all data is saved.
- EXPECT_EQ(3 * data.length() - 100, stream_->BufferedDataBytes());
-
- EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
- .WillOnce(InvokeWithoutArgs([this]() {
- return session_->ConsumeData(stream_->id(), 100, 100u, NO_FIN,
- NOT_RETRANSMISSION, absl::nullopt);
- }));
- // Buffered data size > threshold, do not ask upper layer for more data.
- EXPECT_CALL(*stream_, OnCanWriteNewData()).Times(0);
- stream_->OnCanWrite();
- EXPECT_EQ(3 * data.length() - 200, stream_->BufferedDataBytes());
- EXPECT_FALSE(stream_->CanWriteNewData());
-
- // Send buffered data to make buffered data size < threshold.
- QuicByteCount data_to_write =
- 3 * data.length() - 200 -
- GetQuicFlag(FLAGS_quic_buffered_data_threshold) + 1;
- EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
- .WillOnce(InvokeWithoutArgs([this, data_to_write]() {
- return session_->ConsumeData(stream_->id(), data_to_write, 200u, NO_FIN,
- NOT_RETRANSMISSION, absl::nullopt);
- }));
- // Buffered data size < threshold, ask upper layer for more data.
- EXPECT_CALL(*stream_, OnCanWriteNewData()).Times(1);
- stream_->OnCanWrite();
- EXPECT_EQ(static_cast<uint64_t>(
- GetQuicFlag(FLAGS_quic_buffered_data_threshold) - 1),
- stream_->BufferedDataBytes());
- EXPECT_TRUE(stream_->CanWriteNewData());
-
- // Flush all buffered data.
- EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
- .WillOnce(Invoke(session_.get(), &MockQuicSession::ConsumeData));
- EXPECT_CALL(*stream_, OnCanWriteNewData()).Times(1);
- stream_->OnCanWrite();
- EXPECT_EQ(0u, stream_->BufferedDataBytes());
- EXPECT_FALSE(stream_->HasBufferedData());
- EXPECT_TRUE(stream_->CanWriteNewData());
-
- // Testing Writev.
- EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
- .WillOnce(Return(QuicConsumedData(0, false)));
- struct iovec iov = {const_cast<char*>(data.data()), data.length()};
- QuicMemSliceStorage storage(
- &iov, 1, session_->connection()->helper()->GetStreamSendBufferAllocator(),
- 1024);
- QuicConsumedData consumed = stream_->WriteMemSlices(storage.ToSpan(), false);
-
- // There is no buffered data before, all data should be consumed without
- // respecting buffered data upper limit.
- EXPECT_EQ(data.length(), consumed.bytes_consumed);
- EXPECT_FALSE(consumed.fin_consumed);
- EXPECT_EQ(data.length(), stream_->BufferedDataBytes());
- EXPECT_FALSE(stream_->CanWriteNewData());
-
- EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _)).Times(0);
- QuicMemSliceStorage storage2(
- &iov, 1, session_->connection()->helper()->GetStreamSendBufferAllocator(),
- 1024);
- consumed = stream_->WriteMemSlices(storage2.ToSpan(), false);
- // No Data can be consumed as buffered data is beyond upper limit.
- EXPECT_EQ(0u, consumed.bytes_consumed);
- EXPECT_FALSE(consumed.fin_consumed);
- EXPECT_EQ(data.length(), stream_->BufferedDataBytes());
-
- data_to_write =
- data.length() - GetQuicFlag(FLAGS_quic_buffered_data_threshold) + 1;
- EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
- .WillOnce(InvokeWithoutArgs([this, data_to_write]() {
- return session_->ConsumeData(stream_->id(), data_to_write, 0u, NO_FIN,
- NOT_RETRANSMISSION, absl::nullopt);
- }));
-
- EXPECT_CALL(*stream_, OnCanWriteNewData()).Times(1);
- stream_->OnCanWrite();
- EXPECT_EQ(static_cast<uint64_t>(
- GetQuicFlag(FLAGS_quic_buffered_data_threshold) - 1),
- stream_->BufferedDataBytes());
- EXPECT_TRUE(stream_->CanWriteNewData());
-
- EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _)).Times(0);
- // All data can be consumed as buffered data is below upper limit.
- QuicMemSliceStorage storage3(
- &iov, 1, session_->connection()->helper()->GetStreamSendBufferAllocator(),
- 1024);
- consumed = stream_->WriteMemSlices(storage3.ToSpan(), false);
- EXPECT_EQ(data.length(), consumed.bytes_consumed);
- EXPECT_FALSE(consumed.fin_consumed);
- EXPECT_EQ(data.length() + GetQuicFlag(FLAGS_quic_buffered_data_threshold) - 1,
- stream_->BufferedDataBytes());
- EXPECT_FALSE(stream_->CanWriteNewData());
-}
-
-TEST_P(QuicStreamTest, WritevDataReachStreamLimit) {
- Initialize();
- std::string data("aaaaa");
- QuicStreamPeer::SetStreamBytesWritten(kMaxStreamLength - data.length(),
- stream_);
- EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
- .WillOnce(Invoke(session_.get(), &MockQuicSession::ConsumeData));
- struct iovec iov = {const_cast<char*>(data.data()), 5u};
- QuicMemSliceStorage storage(
- &iov, 1, session_->connection()->helper()->GetStreamSendBufferAllocator(),
- 1024);
- QuicConsumedData consumed = stream_->WriteMemSlices(storage.ToSpan(), false);
- EXPECT_EQ(data.length(), consumed.bytes_consumed);
- struct iovec iov2 = {const_cast<char*>(data.data()), 1u};
- QuicMemSliceStorage 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");
-}
-
-TEST_P(QuicStreamTest, WriteMemSlices) {
- // Set buffered data low water mark to be 100.
- SetQuicFlag(FLAGS_quic_buffered_data_threshold, 100);
-
- Initialize();
- constexpr QuicByteCount kDataSize = 1024;
- QuicBufferAllocator* allocator =
- connection_->helper()->GetStreamSendBufferAllocator();
- std::vector<QuicMemSlice> vector1;
- vector1.push_back(QuicMemSlice(QuicBuffer(allocator, kDataSize)));
- vector1.push_back(QuicMemSlice(QuicBuffer(allocator, kDataSize)));
- std::vector<QuicMemSlice> vector2;
- vector2.push_back(QuicMemSlice(QuicBuffer(allocator, kDataSize)));
- vector2.push_back(QuicMemSlice(QuicBuffer(allocator, kDataSize)));
- absl::Span<QuicMemSlice> span1(vector1);
- absl::Span<QuicMemSlice> span2(vector2);
-
- EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
- .WillOnce(InvokeWithoutArgs([this]() {
- return session_->ConsumeData(stream_->id(), 100u, 0u, NO_FIN,
- NOT_RETRANSMISSION, absl::nullopt);
- }));
- // There is no buffered data before, all data should be consumed.
- QuicConsumedData consumed = stream_->WriteMemSlices(span1, false);
- EXPECT_EQ(2048u, consumed.bytes_consumed);
- EXPECT_FALSE(consumed.fin_consumed);
- EXPECT_EQ(2 * kDataSize - 100, stream_->BufferedDataBytes());
- EXPECT_FALSE(stream_->fin_buffered());
-
- EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _)).Times(0);
- // No Data can be consumed as buffered data is beyond upper limit.
- consumed = stream_->WriteMemSlices(span2, true);
- EXPECT_EQ(0u, consumed.bytes_consumed);
- EXPECT_FALSE(consumed.fin_consumed);
- EXPECT_EQ(2 * kDataSize - 100, stream_->BufferedDataBytes());
- EXPECT_FALSE(stream_->fin_buffered());
-
- QuicByteCount data_to_write =
- 2 * kDataSize - 100 - GetQuicFlag(FLAGS_quic_buffered_data_threshold) + 1;
- EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
- .WillOnce(InvokeWithoutArgs([this, data_to_write]() {
- return session_->ConsumeData(stream_->id(), data_to_write, 100u, NO_FIN,
- NOT_RETRANSMISSION, absl::nullopt);
- }));
- EXPECT_CALL(*stream_, OnCanWriteNewData()).Times(1);
- stream_->OnCanWrite();
- EXPECT_EQ(static_cast<uint64_t>(
- GetQuicFlag(FLAGS_quic_buffered_data_threshold) - 1),
- stream_->BufferedDataBytes());
- // Try to write slices2 again.
- EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _)).Times(0);
- consumed = stream_->WriteMemSlices(span2, true);
- EXPECT_EQ(2048u, consumed.bytes_consumed);
- EXPECT_TRUE(consumed.fin_consumed);
- EXPECT_EQ(2 * kDataSize + GetQuicFlag(FLAGS_quic_buffered_data_threshold) - 1,
- stream_->BufferedDataBytes());
- EXPECT_TRUE(stream_->fin_buffered());
-
- // Flush all buffered data.
- EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
- .WillOnce(Invoke(session_.get(), &MockQuicSession::ConsumeData));
- stream_->OnCanWrite();
- EXPECT_CALL(*stream_, OnCanWriteNewData()).Times(0);
- EXPECT_FALSE(stream_->HasBufferedData());
- EXPECT_TRUE(stream_->write_side_closed());
-}
-
-TEST_P(QuicStreamTest, WriteMemSlicesReachStreamLimit) {
- Initialize();
- QuicStreamPeer::SetStreamBytesWritten(kMaxStreamLength - 5u, stream_);
- std::vector<std::pair<char*, size_t>> buffers;
- QuicMemSlice slice1 = MemSliceFromString("12345");
- EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
- .WillOnce(InvokeWithoutArgs([this]() {
- return session_->ConsumeData(stream_->id(), 5u, 0u, NO_FIN,
- NOT_RETRANSMISSION, absl::nullopt);
- }));
- // There is no buffered data before, all data should be consumed.
- QuicConsumedData consumed = stream_->WriteMemSlice(std::move(slice1), false);
- EXPECT_EQ(5u, consumed.bytes_consumed);
-
- QuicMemSlice 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");
-}
-
-TEST_P(QuicStreamTest, StreamDataGetAckedMultipleTimes) {
- Initialize();
- EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
- .WillRepeatedly(Invoke(session_.get(), &MockQuicSession::ConsumeData));
- EXPECT_FALSE(stream_->IsWaitingForAcks());
- EXPECT_FALSE(session_->HasUnackedStreamData());
-
- // Send [0, 27) and fin.
- stream_->WriteOrBufferData(kData1, false, nullptr);
- stream_->WriteOrBufferData(kData1, false, nullptr);
- stream_->WriteOrBufferData(kData1, true, nullptr);
- EXPECT_EQ(3u, QuicStreamPeer::SendBuffer(stream_).size());
- EXPECT_TRUE(stream_->IsWaitingForAcks());
- EXPECT_TRUE(session_->HasUnackedStreamData());
- // Ack [0, 9), [5, 22) and [18, 26)
- // Verify [0, 9) 9 bytes are acked.
- QuicByteCount newly_acked_length = 0;
- EXPECT_TRUE(stream_->OnStreamFrameAcked(0, 9, false, QuicTime::Delta::Zero(),
- QuicTime::Zero(),
- &newly_acked_length));
- EXPECT_EQ(9u, newly_acked_length);
- EXPECT_EQ(2u, QuicStreamPeer::SendBuffer(stream_).size());
- // Verify [9, 22) 13 bytes are acked.
- EXPECT_TRUE(stream_->OnStreamFrameAcked(5, 17, false, QuicTime::Delta::Zero(),
- QuicTime::Zero(),
- &newly_acked_length));
- EXPECT_EQ(13u, newly_acked_length);
- EXPECT_EQ(1u, QuicStreamPeer::SendBuffer(stream_).size());
- // Verify [22, 26) 4 bytes are acked.
- EXPECT_TRUE(stream_->OnStreamFrameAcked(18, 8, false, QuicTime::Delta::Zero(),
- QuicTime::Zero(),
- &newly_acked_length));
- EXPECT_EQ(4u, newly_acked_length);
- EXPECT_EQ(1u, QuicStreamPeer::SendBuffer(stream_).size());
- EXPECT_TRUE(stream_->IsWaitingForAcks());
- EXPECT_TRUE(session_->HasUnackedStreamData());
-
- // Ack [0, 27). Verify [26, 27) 1 byte is acked.
- EXPECT_TRUE(stream_->OnStreamFrameAcked(26, 1, false, QuicTime::Delta::Zero(),
- QuicTime::Zero(),
- &newly_acked_length));
- EXPECT_EQ(1u, newly_acked_length);
- EXPECT_EQ(0u, QuicStreamPeer::SendBuffer(stream_).size());
- EXPECT_TRUE(stream_->IsWaitingForAcks());
- EXPECT_TRUE(session_->HasUnackedStreamData());
-
- // Ack Fin.
- EXPECT_CALL(*stream_, OnWriteSideInDataRecvdState()).Times(1);
- EXPECT_TRUE(stream_->OnStreamFrameAcked(27, 0, true, QuicTime::Delta::Zero(),
- QuicTime::Zero(),
- &newly_acked_length));
- EXPECT_EQ(0u, newly_acked_length);
- EXPECT_EQ(0u, QuicStreamPeer::SendBuffer(stream_).size());
- EXPECT_FALSE(stream_->IsWaitingForAcks());
- EXPECT_FALSE(session_->HasUnackedStreamData());
-
- // Ack [10, 27) and fin. No new data is acked.
- EXPECT_FALSE(
- stream_->OnStreamFrameAcked(10, 17, true, QuicTime::Delta::Zero(),
- QuicTime::Zero(), &newly_acked_length));
- EXPECT_EQ(0u, newly_acked_length);
- EXPECT_EQ(0u, QuicStreamPeer::SendBuffer(stream_).size());
- EXPECT_FALSE(stream_->IsWaitingForAcks());
- EXPECT_FALSE(session_->HasUnackedStreamData());
-}
-
-TEST_P(QuicStreamTest, OnStreamFrameLost) {
- Initialize();
-
- // Send [0, 9).
- EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
- .WillOnce(Invoke(session_.get(), &MockQuicSession::ConsumeData));
- stream_->WriteOrBufferData(kData1, false, nullptr);
- EXPECT_FALSE(stream_->HasBufferedData());
- EXPECT_TRUE(stream_->IsStreamFrameOutstanding(0, 9, false));
-
- // Try to send [9, 27), but connection is blocked.
- EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
- .WillOnce(Return(QuicConsumedData(0, false)));
- stream_->WriteOrBufferData(kData2, false, nullptr);
- stream_->WriteOrBufferData(kData2, false, nullptr);
- EXPECT_TRUE(stream_->HasBufferedData());
- EXPECT_FALSE(stream_->HasPendingRetransmission());
-
- // Lost [0, 9). When stream gets a chance to write, only lost data is
- // transmitted.
- stream_->OnStreamFrameLost(0, 9, false);
- EXPECT_TRUE(stream_->HasPendingRetransmission());
- EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
- .WillOnce(Invoke(session_.get(), &MockQuicSession::ConsumeData));
- EXPECT_CALL(*stream_, OnCanWriteNewData()).Times(1);
- stream_->OnCanWrite();
- EXPECT_FALSE(stream_->HasPendingRetransmission());
- EXPECT_TRUE(stream_->HasBufferedData());
-
- // This OnCanWrite causes [9, 27) to be sent.
- EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
- .WillOnce(Invoke(session_.get(), &MockQuicSession::ConsumeData));
- stream_->OnCanWrite();
- EXPECT_FALSE(stream_->HasBufferedData());
-
- // Send a fin only frame.
- EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
- .WillOnce(Invoke(session_.get(), &MockQuicSession::ConsumeData));
- stream_->WriteOrBufferData("", true, nullptr);
-
- // Lost [9, 27) and fin.
- stream_->OnStreamFrameLost(9, 18, false);
- stream_->OnStreamFrameLost(27, 0, true);
- EXPECT_TRUE(stream_->HasPendingRetransmission());
-
- // Ack [9, 18).
- QuicByteCount newly_acked_length = 0;
- EXPECT_TRUE(stream_->OnStreamFrameAcked(9, 9, false, QuicTime::Delta::Zero(),
- QuicTime::Zero(),
- &newly_acked_length));
- EXPECT_EQ(9u, newly_acked_length);
- EXPECT_FALSE(stream_->IsStreamFrameOutstanding(9, 3, false));
- EXPECT_TRUE(stream_->HasPendingRetransmission());
- // This OnCanWrite causes [18, 27) and fin to be retransmitted. Verify fin can
- // be bundled with data.
- EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
- .WillOnce(InvokeWithoutArgs([this]() {
- return session_->ConsumeData(stream_->id(), 9u, 18u, FIN,
- NOT_RETRANSMISSION, absl::nullopt);
- }));
- stream_->OnCanWrite();
- EXPECT_FALSE(stream_->HasPendingRetransmission());
- // Lost [9, 18) again, but it is not considered as lost because kData2
- // has been acked.
- stream_->OnStreamFrameLost(9, 9, false);
- EXPECT_FALSE(stream_->HasPendingRetransmission());
- EXPECT_TRUE(stream_->IsStreamFrameOutstanding(27, 0, true));
-}
-
-TEST_P(QuicStreamTest, CannotBundleLostFin) {
- Initialize();
-
- // Send [0, 18) and fin.
- EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
- .WillRepeatedly(Invoke(session_.get(), &MockQuicSession::ConsumeData));
- stream_->WriteOrBufferData(kData1, false, nullptr);
- stream_->WriteOrBufferData(kData2, true, nullptr);
-
- // Lost [0, 9) and fin.
- stream_->OnStreamFrameLost(0, 9, false);
- stream_->OnStreamFrameLost(18, 0, true);
-
- // Retransmit lost data. Verify [0, 9) and fin are retransmitted in two
- // frames.
- InSequence s;
- EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
- .WillOnce(InvokeWithoutArgs([this]() {
- return session_->ConsumeData(stream_->id(), 9u, 0u, NO_FIN,
- NOT_RETRANSMISSION, absl::nullopt);
- }));
- EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
- .WillOnce(Return(QuicConsumedData(0, true)));
- stream_->OnCanWrite();
-}
-
-TEST_P(QuicStreamTest, MarkConnectionLevelWriteBlockedOnWindowUpdateFrame) {
- Initialize();
-
- // Set the config to a small value so that a newly created stream has small
- // send flow control window.
- QuicConfigPeer::SetReceivedInitialStreamFlowControlWindow(session_->config(),
- 100);
- QuicConfigPeer::SetReceivedInitialMaxStreamDataBytesIncomingBidirectional(
- session_->config(), 100);
- auto stream = new TestStream(GetNthClientInitiatedBidirectionalStreamId(
- GetParam().transport_version, 2),
- session_.get(), BIDIRECTIONAL);
- session_->ActivateStream(absl::WrapUnique(stream));
-
- EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
- .WillRepeatedly(Invoke(session_.get(), &MockQuicSession::ConsumeData));
- EXPECT_CALL(*session_, WriteControlFrame(_, _))
- .WillOnce(Invoke(&ClearControlFrameWithTransmissionType));
- std::string data(1024, '.');
- stream->WriteOrBufferData(data, false, nullptr);
- EXPECT_FALSE(HasWriteBlockedStreams());
-
- QuicWindowUpdateFrame window_update(kInvalidControlFrameId, stream_->id(),
- 1234);
-
- stream->OnWindowUpdateFrame(window_update);
- // Verify stream is marked connection level write blocked.
- EXPECT_TRUE(HasWriteBlockedStreams());
- EXPECT_TRUE(stream->HasBufferedData());
-}
-
-// Regression test for b/73282665.
-TEST_P(QuicStreamTest,
- MarkConnectionLevelWriteBlockedOnWindowUpdateFrameWithNoBufferedData) {
- Initialize();
-
- // Set the config to a small value so that a newly created stream has small
- // send flow control window.
- QuicConfigPeer::SetReceivedInitialStreamFlowControlWindow(session_->config(),
- 100);
- QuicConfigPeer::SetReceivedInitialMaxStreamDataBytesIncomingBidirectional(
- session_->config(), 100);
- auto stream = new TestStream(GetNthClientInitiatedBidirectionalStreamId(
- GetParam().transport_version, 2),
- session_.get(), BIDIRECTIONAL);
- session_->ActivateStream(absl::WrapUnique(stream));
-
- std::string data(100, '.');
- EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
- .WillRepeatedly(Invoke(session_.get(), &MockQuicSession::ConsumeData));
- EXPECT_CALL(*session_, WriteControlFrame(_, _))
- .WillOnce(Invoke(&ClearControlFrameWithTransmissionType));
- stream->WriteOrBufferData(data, false, nullptr);
- EXPECT_FALSE(HasWriteBlockedStreams());
-
- QuicWindowUpdateFrame window_update(kInvalidControlFrameId, stream_->id(),
- 120);
- stream->OnWindowUpdateFrame(window_update);
- EXPECT_FALSE(stream->HasBufferedData());
- // Verify stream is marked as blocked although there is no buffered data.
- EXPECT_TRUE(HasWriteBlockedStreams());
-}
-
-TEST_P(QuicStreamTest, RetransmitStreamData) {
- Initialize();
- InSequence s;
-
- // Send [0, 18) with fin.
- EXPECT_CALL(*session_, WritevData(stream_->id(), _, _, _, _, _))
- .Times(2)
- .WillRepeatedly(Invoke(session_.get(), &MockQuicSession::ConsumeData));
- stream_->WriteOrBufferData(kData1, false, nullptr);
- stream_->WriteOrBufferData(kData1, true, nullptr);
- // Ack [10, 13).
- QuicByteCount newly_acked_length = 0;
- stream_->OnStreamFrameAcked(10, 3, false, QuicTime::Delta::Zero(),
- QuicTime::Zero(), &newly_acked_length);
- EXPECT_EQ(3u, newly_acked_length);
- // Retransmit [0, 18) with fin, and only [0, 8) is consumed.
- EXPECT_CALL(*session_, WritevData(stream_->id(), 10, 0, NO_FIN, _, _))
- .WillOnce(InvokeWithoutArgs([this]() {
- return session_->ConsumeData(stream_->id(), 8, 0u, NO_FIN,
- NOT_RETRANSMISSION, absl::nullopt);
- }));
- EXPECT_FALSE(stream_->RetransmitStreamData(0, 18, true, PTO_RETRANSMISSION));
-
- // Retransmit [0, 18) with fin, and all is consumed.
- EXPECT_CALL(*session_, WritevData(stream_->id(), 10, 0, NO_FIN, _, _))
- .WillOnce(Invoke(session_.get(), &MockQuicSession::ConsumeData));
- EXPECT_CALL(*session_, WritevData(stream_->id(), 5, 13, FIN, _, _))
- .WillOnce(Invoke(session_.get(), &MockQuicSession::ConsumeData));
- EXPECT_TRUE(stream_->RetransmitStreamData(0, 18, true, PTO_RETRANSMISSION));
-
- // Retransmit [0, 8) with fin, and all is consumed.
- EXPECT_CALL(*session_, WritevData(stream_->id(), 8, 0, NO_FIN, _, _))
- .WillOnce(Invoke(session_.get(), &MockQuicSession::ConsumeData));
- EXPECT_CALL(*session_, WritevData(stream_->id(), 0, 18, FIN, _, _))
- .WillOnce(Invoke(session_.get(), &MockQuicSession::ConsumeData));
- EXPECT_TRUE(stream_->RetransmitStreamData(0, 8, true, PTO_RETRANSMISSION));
-}
-
-TEST_P(QuicStreamTest, ResetStreamOnTtlExpiresRetransmitLostData) {
- Initialize();
-
- EXPECT_CALL(*session_, WritevData(stream_->id(), 200, 0, FIN, _, _))
- .WillOnce(Invoke(session_.get(), &MockQuicSession::ConsumeData));
- std::string body(200, 'a');
- stream_->WriteOrBufferData(body, true, nullptr);
-
- // Set TTL to be 1 s.
- QuicTime::Delta ttl = QuicTime::Delta::FromSeconds(1);
- ASSERT_TRUE(stream_->MaybeSetTtl(ttl));
- // Verify data gets retransmitted because TTL does not expire.
- EXPECT_CALL(*session_, WritevData(stream_->id(), 100, 0, NO_FIN, _, _))
- .WillOnce(Invoke(session_.get(), &MockQuicSession::ConsumeData));
- EXPECT_TRUE(stream_->RetransmitStreamData(0, 100, false, PTO_RETRANSMISSION));
- stream_->OnStreamFrameLost(100, 100, true);
- EXPECT_TRUE(stream_->HasPendingRetransmission());
-
- connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
- // Verify stream gets reset because TTL expires.
- if (session_->version().UsesHttp3()) {
- EXPECT_CALL(*session_,
- MaybeSendStopSendingFrame(_, QuicResetStreamError::FromInternal(
- QUIC_STREAM_TTL_EXPIRED)))
- .Times(1);
- }
- EXPECT_CALL(
- *session_,
- MaybeSendRstStreamFrame(
- _, QuicResetStreamError::FromInternal(QUIC_STREAM_TTL_EXPIRED), _))
- .Times(1);
- stream_->OnCanWrite();
-}
-
-TEST_P(QuicStreamTest, ResetStreamOnTtlExpiresEarlyRetransmitData) {
- Initialize();
-
- EXPECT_CALL(*session_, WritevData(stream_->id(), 200, 0, FIN, _, _))
- .WillOnce(Invoke(session_.get(), &MockQuicSession::ConsumeData));
- std::string body(200, 'a');
- stream_->WriteOrBufferData(body, true, nullptr);
-
- // Set TTL to be 1 s.
- QuicTime::Delta ttl = QuicTime::Delta::FromSeconds(1);
- ASSERT_TRUE(stream_->MaybeSetTtl(ttl));
-
- connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
- // Verify stream gets reset because TTL expires.
- if (session_->version().UsesHttp3()) {
- EXPECT_CALL(*session_,
- MaybeSendStopSendingFrame(_, QuicResetStreamError::FromInternal(
- QUIC_STREAM_TTL_EXPIRED)))
- .Times(1);
- }
- EXPECT_CALL(
- *session_,
- MaybeSendRstStreamFrame(
- _, QuicResetStreamError::FromInternal(QUIC_STREAM_TTL_EXPIRED), _))
- .Times(1);
- stream_->RetransmitStreamData(0, 100, false, PTO_RETRANSMISSION);
-}
-
-// Test that OnStreamReset does one-way (read) closes if version 99, two way
-// (read and write) if not version 99.
-TEST_P(QuicStreamTest, OnStreamResetReadOrReadWrite) {
- Initialize();
- EXPECT_FALSE(stream_->write_side_closed());
- EXPECT_FALSE(QuicStreamPeer::read_side_closed(stream_));
-
- QuicRstStreamFrame rst_frame(kInvalidControlFrameId, stream_->id(),
- QUIC_STREAM_CANCELLED, 1234);
- stream_->OnStreamReset(rst_frame);
- if (VersionHasIetfQuicFrames(connection_->transport_version())) {
- // Version 99/IETF QUIC should close just the read side.
- EXPECT_TRUE(QuicStreamPeer::read_side_closed(stream_));
- EXPECT_FALSE(stream_->write_side_closed());
- } else {
- // Google QUIC should close both sides of the stream.
- EXPECT_TRUE(stream_->write_side_closed());
- EXPECT_TRUE(QuicStreamPeer::read_side_closed(stream_));
- }
-}
-
-TEST_P(QuicStreamTest, WindowUpdateForReadOnlyStream) {
- Initialize();
-
- QuicStreamId stream_id = QuicUtils::GetFirstUnidirectionalStreamId(
- connection_->transport_version(), Perspective::IS_CLIENT);
- TestStream stream(stream_id, session_.get(), READ_UNIDIRECTIONAL);
- QuicWindowUpdateFrame window_update_frame(kInvalidControlFrameId, stream_id,
- 0);
- EXPECT_CALL(
- *connection_,
- CloseConnection(
- QUIC_WINDOW_UPDATE_RECEIVED_ON_READ_UNIDIRECTIONAL_STREAM,
- "WindowUpdateFrame received on READ_UNIDIRECTIONAL stream.", _));
- stream.OnWindowUpdateFrame(window_update_frame);
-}
-
-TEST_P(QuicStreamTest, RstStreamFrameChangesCloseOffset) {
- Initialize();
-
- QuicStreamFrame stream_frame(stream_->id(), true, 0, "abc");
- EXPECT_CALL(*stream_, OnDataAvailable());
- stream_->OnStreamFrame(stream_frame);
- QuicRstStreamFrame rst(kInvalidControlFrameId, stream_->id(),
- QUIC_STREAM_CANCELLED, 0u);
-
- EXPECT_CALL(*connection_, CloseConnection(QUIC_STREAM_MULTIPLE_OFFSET, _, _));
- stream_->OnStreamReset(rst);
-}
-
-// Regression test for b/176073284.
-TEST_P(QuicStreamTest, EmptyStreamFrameWithNoFin) {
- Initialize();
- QuicStreamFrame empty_stream_frame(stream_->id(), false, 0, "");
- if (stream_->version().HasIetfQuicFrames()) {
- EXPECT_CALL(*connection_,
- CloseConnection(QUIC_EMPTY_STREAM_FRAME_NO_FIN, _, _))
- .Times(0);
- } else {
- EXPECT_CALL(*connection_,
- CloseConnection(QUIC_EMPTY_STREAM_FRAME_NO_FIN, _, _));
- }
- EXPECT_CALL(*stream_, OnDataAvailable()).Times(0);
- stream_->OnStreamFrame(empty_stream_frame);
-}
-
-TEST_P(QuicStreamTest, SendRstWithCustomIetfCode) {
- Initialize();
- QuicResetStreamError error(QUIC_STREAM_CANCELLED, 0x1234abcd);
- EXPECT_CALL(*session_, MaybeSendRstStreamFrame(kTestStreamId, error, _))
- .Times(1);
- stream_->ResetWithError(error);
- EXPECT_TRUE(rst_sent());
-}
-
-} // namespace
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_sustained_bandwidth_recorder.cc b/chromium/net/third_party/quiche/src/quic/core/quic_sustained_bandwidth_recorder.cc
deleted file mode 100644
index 178c4c6b239..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_sustained_bandwidth_recorder.cc
+++ /dev/null
@@ -1,62 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_sustained_bandwidth_recorder.h"
-
-#include "quic/core/quic_bandwidth.h"
-#include "quic/core/quic_time.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-QuicSustainedBandwidthRecorder::QuicSustainedBandwidthRecorder()
- : has_estimate_(false),
- is_recording_(false),
- bandwidth_estimate_recorded_during_slow_start_(false),
- bandwidth_estimate_(QuicBandwidth::Zero()),
- max_bandwidth_estimate_(QuicBandwidth::Zero()),
- max_bandwidth_timestamp_(0),
- start_time_(QuicTime::Zero()) {}
-
-void QuicSustainedBandwidthRecorder::RecordEstimate(bool in_recovery,
- bool in_slow_start,
- QuicBandwidth bandwidth,
- QuicTime estimate_time,
- QuicWallTime wall_time,
- QuicTime::Delta srtt) {
- if (in_recovery) {
- is_recording_ = false;
- QUIC_DVLOG(1) << "Stopped recording at: "
- << estimate_time.ToDebuggingValue();
- return;
- }
-
- if (!is_recording_) {
- // This is the first estimate of a new recording period.
- start_time_ = estimate_time;
- is_recording_ = true;
- QUIC_DVLOG(1) << "Started recording at: " << start_time_.ToDebuggingValue();
- return;
- }
-
- // If we have been recording for at least 3 * srtt, then record the latest
- // bandwidth estimate as a valid sustained bandwidth estimate.
- if (estimate_time - start_time_ >= 3 * srtt) {
- has_estimate_ = true;
- bandwidth_estimate_recorded_during_slow_start_ = in_slow_start;
- bandwidth_estimate_ = bandwidth;
- QUIC_DVLOG(1) << "New sustained bandwidth estimate (KBytes/s): "
- << bandwidth_estimate_.ToKBytesPerSecond();
- }
-
- // Check for an increase in max bandwidth.
- if (bandwidth > max_bandwidth_estimate_) {
- max_bandwidth_estimate_ = bandwidth;
- max_bandwidth_timestamp_ = wall_time.ToUNIXSeconds();
- QUIC_DVLOG(1) << "New max bandwidth estimate (KBytes/s): "
- << max_bandwidth_estimate_.ToKBytesPerSecond();
- }
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_sustained_bandwidth_recorder.h b/chromium/net/third_party/quiche/src/quic/core/quic_sustained_bandwidth_recorder.h
deleted file mode 100644
index f1fdfebe1f1..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_sustained_bandwidth_recorder.h
+++ /dev/null
@@ -1,95 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_SUSTAINED_BANDWIDTH_RECORDER_H_
-#define QUICHE_QUIC_CORE_QUIC_SUSTAINED_BANDWIDTH_RECORDER_H_
-
-#include <cstdint>
-
-#include "quic/core/quic_bandwidth.h"
-#include "quic/core/quic_time.h"
-#include "quic/platform/api/quic_export.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-namespace test {
-class QuicSustainedBandwidthRecorderPeer;
-} // namespace test
-
-// This class keeps track of a sustained bandwidth estimate to ultimately send
-// to the client in a server config update message. A sustained bandwidth
-// estimate is only marked as valid if the QuicSustainedBandwidthRecorder has
-// been given uninterrupted reliable estimates over a certain period of time.
-class QUIC_EXPORT_PRIVATE QuicSustainedBandwidthRecorder {
- public:
- QuicSustainedBandwidthRecorder();
- QuicSustainedBandwidthRecorder(const QuicSustainedBandwidthRecorder&) =
- delete;
- QuicSustainedBandwidthRecorder& operator=(
- const QuicSustainedBandwidthRecorder&) = delete;
-
- // As long as |in_recovery| is consistently false, multiple calls to this
- // method over a 3 * srtt period results in storage of a valid sustained
- // bandwidth estimate.
- // |time_now| is used as a max bandwidth timestamp if needed.
- void RecordEstimate(bool in_recovery,
- bool in_slow_start,
- QuicBandwidth bandwidth,
- QuicTime estimate_time,
- QuicWallTime wall_time,
- QuicTime::Delta srtt);
-
- bool HasEstimate() const { return has_estimate_; }
-
- QuicBandwidth BandwidthEstimate() const {
- QUICHE_DCHECK(has_estimate_);
- return bandwidth_estimate_;
- }
-
- QuicBandwidth MaxBandwidthEstimate() const {
- QUICHE_DCHECK(has_estimate_);
- return max_bandwidth_estimate_;
- }
-
- int64_t MaxBandwidthTimestamp() const {
- QUICHE_DCHECK(has_estimate_);
- return max_bandwidth_timestamp_;
- }
-
- bool EstimateRecordedDuringSlowStart() const {
- QUICHE_DCHECK(has_estimate_);
- return bandwidth_estimate_recorded_during_slow_start_;
- }
-
- private:
- friend class test::QuicSustainedBandwidthRecorderPeer;
-
- // True if we have been able to calculate sustained bandwidth, over at least
- // one recording period (3 * rtt).
- bool has_estimate_;
-
- // True if the last call to RecordEstimate had a reliable estimate.
- bool is_recording_;
-
- // True if the current sustained bandwidth estimate was generated while in
- // slow start.
- bool bandwidth_estimate_recorded_during_slow_start_;
-
- // The latest sustained bandwidth estimate.
- QuicBandwidth bandwidth_estimate_;
-
- // The maximum sustained bandwidth seen over the lifetime of the connection.
- QuicBandwidth max_bandwidth_estimate_;
-
- // Timestamp indicating when the max_bandwidth_estimate_ was seen.
- int64_t max_bandwidth_timestamp_;
-
- // Timestamp marking the beginning of the latest recording period.
- QuicTime start_time_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_QUIC_SUSTAINED_BANDWIDTH_RECORDER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_sustained_bandwidth_recorder_test.cc b/chromium/net/third_party/quiche/src/quic/core/quic_sustained_bandwidth_recorder_test.cc
deleted file mode 100644
index 1231ee1761d..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_sustained_bandwidth_recorder_test.cc
+++ /dev/null
@@ -1,133 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_sustained_bandwidth_recorder.h"
-
-#include "quic/core/quic_bandwidth.h"
-#include "quic/core/quic_time.h"
-#include "quic/platform/api/quic_test.h"
-
-namespace quic {
-namespace test {
-namespace {
-
-class QuicSustainedBandwidthRecorderTest : public QuicTest {};
-
-TEST_F(QuicSustainedBandwidthRecorderTest, BandwidthEstimates) {
- QuicSustainedBandwidthRecorder recorder;
- EXPECT_FALSE(recorder.HasEstimate());
-
- QuicTime estimate_time = QuicTime::Zero();
- QuicWallTime wall_time = QuicWallTime::Zero();
- QuicTime::Delta srtt = QuicTime::Delta::FromMilliseconds(150);
- const int kBandwidthBitsPerSecond = 12345678;
- QuicBandwidth bandwidth =
- QuicBandwidth::FromBitsPerSecond(kBandwidthBitsPerSecond);
-
- bool in_recovery = false;
- bool in_slow_start = false;
-
- // This triggers recording, but should not yield a valid estimate yet.
- recorder.RecordEstimate(in_recovery, in_slow_start, bandwidth, estimate_time,
- wall_time, srtt);
- EXPECT_FALSE(recorder.HasEstimate());
-
- // Send a second reading, again this should not result in a valid estimate,
- // as not enough time has passed.
- estimate_time = estimate_time + srtt;
- recorder.RecordEstimate(in_recovery, in_slow_start, bandwidth, estimate_time,
- wall_time, srtt);
- EXPECT_FALSE(recorder.HasEstimate());
-
- // Now 3 * kSRTT has elapsed since first recording, expect a valid estimate.
- estimate_time = estimate_time + srtt;
- estimate_time = estimate_time + srtt;
- recorder.RecordEstimate(in_recovery, in_slow_start, bandwidth, estimate_time,
- wall_time, srtt);
- EXPECT_TRUE(recorder.HasEstimate());
- EXPECT_EQ(recorder.BandwidthEstimate(), bandwidth);
- EXPECT_EQ(recorder.BandwidthEstimate(), recorder.MaxBandwidthEstimate());
-
- // Resetting, and sending a different estimate will only change output after
- // a further 3 * kSRTT has passed.
- QuicBandwidth second_bandwidth =
- QuicBandwidth::FromBitsPerSecond(2 * kBandwidthBitsPerSecond);
- // Reset the recorder by passing in a measurement while in recovery.
- in_recovery = true;
- recorder.RecordEstimate(in_recovery, in_slow_start, bandwidth, estimate_time,
- wall_time, srtt);
- in_recovery = false;
- recorder.RecordEstimate(in_recovery, in_slow_start, bandwidth, estimate_time,
- wall_time, srtt);
- EXPECT_EQ(recorder.BandwidthEstimate(), bandwidth);
-
- estimate_time = estimate_time + 3 * srtt;
- const int64_t kSeconds = 556677;
- QuicWallTime second_bandwidth_wall_time =
- QuicWallTime::FromUNIXSeconds(kSeconds);
- recorder.RecordEstimate(in_recovery, in_slow_start, second_bandwidth,
- estimate_time, second_bandwidth_wall_time, srtt);
- EXPECT_EQ(recorder.BandwidthEstimate(), second_bandwidth);
- EXPECT_EQ(recorder.BandwidthEstimate(), recorder.MaxBandwidthEstimate());
- EXPECT_EQ(recorder.MaxBandwidthTimestamp(), kSeconds);
-
- // Reset again, this time recording a lower bandwidth than before.
- QuicBandwidth third_bandwidth =
- QuicBandwidth::FromBitsPerSecond(0.5 * kBandwidthBitsPerSecond);
- // Reset the recorder by passing in an unreliable measurement.
- recorder.RecordEstimate(in_recovery, in_slow_start, third_bandwidth,
- estimate_time, wall_time, srtt);
- recorder.RecordEstimate(in_recovery, in_slow_start, third_bandwidth,
- estimate_time, wall_time, srtt);
- EXPECT_EQ(recorder.BandwidthEstimate(), third_bandwidth);
-
- estimate_time = estimate_time + 3 * srtt;
- recorder.RecordEstimate(in_recovery, in_slow_start, third_bandwidth,
- estimate_time, wall_time, srtt);
- EXPECT_EQ(recorder.BandwidthEstimate(), third_bandwidth);
-
- // Max bandwidth should not have changed.
- EXPECT_LT(third_bandwidth, second_bandwidth);
- EXPECT_EQ(recorder.MaxBandwidthEstimate(), second_bandwidth);
- EXPECT_EQ(recorder.MaxBandwidthTimestamp(), kSeconds);
-}
-
-TEST_F(QuicSustainedBandwidthRecorderTest, SlowStart) {
- // Verify that slow start status is correctly recorded.
- QuicSustainedBandwidthRecorder recorder;
- EXPECT_FALSE(recorder.HasEstimate());
-
- QuicTime estimate_time = QuicTime::Zero();
- QuicWallTime wall_time = QuicWallTime::Zero();
- QuicTime::Delta srtt = QuicTime::Delta::FromMilliseconds(150);
- const int kBandwidthBitsPerSecond = 12345678;
- QuicBandwidth bandwidth =
- QuicBandwidth::FromBitsPerSecond(kBandwidthBitsPerSecond);
-
- bool in_recovery = false;
- bool in_slow_start = true;
-
- // This triggers recording, but should not yield a valid estimate yet.
- recorder.RecordEstimate(in_recovery, in_slow_start, bandwidth, estimate_time,
- wall_time, srtt);
-
- // Now 3 * kSRTT has elapsed since first recording, expect a valid estimate.
- estimate_time = estimate_time + 3 * srtt;
- recorder.RecordEstimate(in_recovery, in_slow_start, bandwidth, estimate_time,
- wall_time, srtt);
- EXPECT_TRUE(recorder.HasEstimate());
- EXPECT_TRUE(recorder.EstimateRecordedDuringSlowStart());
-
- // Now send another estimate, this time not in slow start.
- estimate_time = estimate_time + 3 * srtt;
- in_slow_start = false;
- recorder.RecordEstimate(in_recovery, in_slow_start, bandwidth, estimate_time,
- wall_time, srtt);
- EXPECT_TRUE(recorder.HasEstimate());
- EXPECT_FALSE(recorder.EstimateRecordedDuringSlowStart());
-}
-
-} // namespace
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_syscall_wrapper.cc b/chromium/net/third_party/quiche/src/quic/core/quic_syscall_wrapper.cc
deleted file mode 100644
index a98331f60f9..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_syscall_wrapper.cc
+++ /dev/null
@@ -1,49 +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 "quic/core/quic_syscall_wrapper.h"
-
-#include <atomic>
-#include <cerrno>
-
-namespace quic {
-namespace {
-std::atomic<QuicSyscallWrapper*> global_syscall_wrapper(new QuicSyscallWrapper);
-} // namespace
-
-ssize_t QuicSyscallWrapper::Sendmsg(int sockfd, const msghdr* msg, int flags) {
- return ::sendmsg(sockfd, msg, flags);
-}
-
-int QuicSyscallWrapper::Sendmmsg(int sockfd,
- mmsghdr* msgvec,
- unsigned int vlen,
- int flags) {
-#if defined(__linux__) && !defined(__ANDROID__)
- return ::sendmmsg(sockfd, msgvec, vlen, flags);
-#else
- errno = ENOSYS;
- return -1;
-#endif
-}
-
-QuicSyscallWrapper* GetGlobalSyscallWrapper() {
- return global_syscall_wrapper.load();
-}
-
-void SetGlobalSyscallWrapper(QuicSyscallWrapper* wrapper) {
- global_syscall_wrapper.store(wrapper);
-}
-
-ScopedGlobalSyscallWrapperOverride::ScopedGlobalSyscallWrapperOverride(
- QuicSyscallWrapper* wrapper_in_scope)
- : original_wrapper_(GetGlobalSyscallWrapper()) {
- SetGlobalSyscallWrapper(wrapper_in_scope);
-}
-
-ScopedGlobalSyscallWrapperOverride::~ScopedGlobalSyscallWrapperOverride() {
- SetGlobalSyscallWrapper(original_wrapper_);
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_syscall_wrapper.h b/chromium/net/third_party/quiche/src/quic/core/quic_syscall_wrapper.h
deleted file mode 100644
index 5b99d0a0345..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_syscall_wrapper.h
+++ /dev/null
@@ -1,49 +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_IMPL_QUIC_SYSCALL_WRAPPER_H_
-#define QUICHE_QUIC_PLATFORM_IMPL_QUIC_SYSCALL_WRAPPER_H_
-
-#include <sys/socket.h>
-#include <sys/types.h>
-
-#include "quic/platform/api/quic_export.h"
-
-struct mmsghdr;
-namespace quic {
-
-// QuicSyscallWrapper is a pass-through proxy to the real syscalls.
-class QUIC_EXPORT_PRIVATE QuicSyscallWrapper {
- public:
- virtual ~QuicSyscallWrapper() = default;
-
- virtual ssize_t Sendmsg(int sockfd, const msghdr* msg, int flags);
-
- virtual int Sendmmsg(int sockfd,
- mmsghdr* msgvec,
- unsigned int vlen,
- int flags);
-};
-
-// A global instance of QuicSyscallWrapper, used by some socket util functions.
-QuicSyscallWrapper* GetGlobalSyscallWrapper();
-
-// Change the global QuicSyscallWrapper to |wrapper|, for testing.
-void SetGlobalSyscallWrapper(QuicSyscallWrapper* wrapper);
-
-// ScopedGlobalSyscallWrapperOverride changes the global QuicSyscallWrapper
-// during its lifetime, for testing.
-class QUIC_EXPORT_PRIVATE ScopedGlobalSyscallWrapperOverride {
- public:
- explicit ScopedGlobalSyscallWrapperOverride(
- QuicSyscallWrapper* wrapper_in_scope);
- ~ScopedGlobalSyscallWrapperOverride();
-
- private:
- QuicSyscallWrapper* original_wrapper_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_PLATFORM_IMPL_QUIC_SYSCALL_WRAPPER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_tag.cc b/chromium/net/third_party/quiche/src/quic/core/quic_tag.cc
deleted file mode 100644
index b5f64f1a775..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_tag.cc
+++ /dev/null
@@ -1,110 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_tag.h"
-
-#include <algorithm>
-#include <string>
-
-#include "absl/base/macros.h"
-#include "absl/strings/escaping.h"
-#include "absl/strings/str_split.h"
-#include "quic/platform/api/quic_flag_utils.h"
-#include "quic/platform/api/quic_flags.h"
-#include "common/quiche_text_utils.h"
-
-namespace quic {
-
-bool FindMutualQuicTag(const QuicTagVector& our_tags,
- const QuicTagVector& their_tags,
- QuicTag* out_result,
- size_t* out_index) {
- const size_t num_our_tags = our_tags.size();
- const size_t num_their_tags = their_tags.size();
- for (size_t i = 0; i < num_our_tags; i++) {
- for (size_t j = 0; j < num_their_tags; j++) {
- if (our_tags[i] == their_tags[j]) {
- *out_result = our_tags[i];
- if (out_index != nullptr) {
- *out_index = j;
- }
- return true;
- }
- }
- }
-
- return false;
-}
-
-std::string QuicTagToString(QuicTag tag) {
- if (tag == 0) {
- return "0";
- }
- char chars[sizeof tag];
- bool ascii = true;
- const QuicTag orig_tag = tag;
-
- for (size_t i = 0; i < ABSL_ARRAYSIZE(chars); i++) {
- chars[i] = static_cast<char>(tag);
- if ((chars[i] == 0 || chars[i] == '\xff') &&
- i == ABSL_ARRAYSIZE(chars) - 1) {
- chars[i] = ' ';
- }
- if (!isprint(static_cast<unsigned char>(chars[i]))) {
- ascii = false;
- break;
- }
- tag >>= 8;
- }
-
- if (ascii) {
- return std::string(chars, sizeof(chars));
- }
-
- return absl::BytesToHexString(absl::string_view(
- reinterpret_cast<const char*>(&orig_tag), sizeof(orig_tag)));
-}
-
-uint32_t MakeQuicTag(uint8_t a, uint8_t b, uint8_t c, uint8_t d) {
- return static_cast<uint32_t>(a) | static_cast<uint32_t>(b) << 8 |
- static_cast<uint32_t>(c) << 16 | static_cast<uint32_t>(d) << 24;
-}
-
-bool ContainsQuicTag(const QuicTagVector& tag_vector, QuicTag tag) {
- return std::find(tag_vector.begin(), tag_vector.end(), tag) !=
- tag_vector.end();
-}
-
-QuicTag ParseQuicTag(absl::string_view tag_string) {
- quiche::QuicheTextUtils::RemoveLeadingAndTrailingWhitespace(&tag_string);
- std::string tag_bytes;
- if (tag_string.length() == 8) {
- tag_bytes = absl::HexStringToBytes(tag_string);
- tag_string = tag_bytes;
- }
- QuicTag tag = 0;
- // Iterate over every character from right to left.
- for (auto it = tag_string.rbegin(); it != tag_string.rend(); ++it) {
- // The cast here is required on platforms where char is signed.
- unsigned char token_char = static_cast<unsigned char>(*it);
- tag <<= 8;
- tag |= token_char;
- }
- return tag;
-}
-
-QuicTagVector ParseQuicTagVector(absl::string_view tags_string) {
- QuicTagVector tag_vector;
- quiche::QuicheTextUtils::RemoveLeadingAndTrailingWhitespace(&tags_string);
- if (!tags_string.empty()) {
- std::vector<absl::string_view> tag_strings =
- absl::StrSplit(tags_string, ',');
- for (absl::string_view tag_string : tag_strings) {
- tag_vector.push_back(ParseQuicTag(tag_string));
- }
- }
- return tag_vector;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_tag.h b/chromium/net/third_party/quiche/src/quic/core/quic_tag.h
deleted file mode 100644
index 1dfc754f870..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_tag.h
+++ /dev/null
@@ -1,67 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_TAG_H_
-#define QUICHE_QUIC_CORE_QUIC_TAG_H_
-
-#include <cstdint>
-#include <map>
-#include <string>
-#include <vector>
-
-#include "absl/strings/string_view.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// A QuicTag is a 32-bit used as identifiers in the QUIC handshake. The use of
-// a uint32_t seeks to provide a balance between the tyranny of magic number
-// registries and the verbosity of strings. As far as the wire protocol is
-// concerned, these are opaque, 32-bit values.
-//
-// Tags will often be referred to by their ASCII equivalent, e.g. EXMP. This is
-// just a mnemonic for the value 0x504d5845 (little-endian version of the ASCII
-// string E X M P).
-using QuicTag = uint32_t;
-using QuicTagValueMap = std::map<QuicTag, std::string>;
-using QuicTagVector = std::vector<QuicTag>;
-
-// MakeQuicTag returns a value given the four bytes. For example:
-// MakeQuicTag('C', 'H', 'L', 'O');
-QUIC_EXPORT_PRIVATE QuicTag MakeQuicTag(uint8_t a, uint8_t b, uint8_t c,
- uint8_t d);
-
-// Returns true if |tag_vector| contains |tag|.
-QUIC_EXPORT_PRIVATE bool ContainsQuicTag(const QuicTagVector& tag_vector,
- QuicTag tag);
-
-// Sets |out_result| to the first tag in |our_tags| that is also in |their_tags|
-// and returns true. If there is no intersection it returns false.
-//
-// If |out_index| is non-nullptr and a match is found then the index of that
-// match in |their_tags| is written to |out_index|.
-QUIC_EXPORT_PRIVATE bool FindMutualQuicTag(const QuicTagVector& our_tags,
- const QuicTagVector& their_tags,
- QuicTag* out_result,
- size_t* out_index);
-
-// A utility function that converts a tag to a string. It will try to maintain
-// the human friendly name if possible (i.e. kABCD -> "ABCD"), or will just
-// treat it as a number if not.
-QUIC_EXPORT_PRIVATE std::string QuicTagToString(QuicTag tag);
-
-// Utility function that converts a string of the form "ABCD" to its
-// corresponding QuicTag. Note that tags that are less than four characters
-// long are right-padded with zeroes. Tags that contain non-ASCII characters
-// are represented as 8-character-long hexadecimal strings.
-QUIC_EXPORT_PRIVATE QuicTag ParseQuicTag(absl::string_view tag_string);
-
-// Utility function that converts a string of the form "ABCD,EFGH" to a vector
-// of the form {kABCD,kEFGH}. Note the caveats on ParseQuicTag.
-QUIC_EXPORT_PRIVATE QuicTagVector
-ParseQuicTagVector(absl::string_view tags_string);
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_QUIC_TAG_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_tag_test.cc b/chromium/net/third_party/quiche/src/quic/core/quic_tag_test.cc
deleted file mode 100644
index 71617f3751d..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_tag_test.cc
+++ /dev/null
@@ -1,80 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_tag.h"
-
-#include "quic/core/crypto/crypto_protocol.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_test.h"
-
-namespace quic {
-namespace test {
-namespace {
-
-class QuicTagTest : public QuicTest {};
-
-TEST_F(QuicTagTest, TagToString) {
- EXPECT_EQ("SCFG", QuicTagToString(kSCFG));
- EXPECT_EQ("SNO ", QuicTagToString(kServerNonceTag));
- EXPECT_EQ("CRT ", QuicTagToString(kCertificateTag));
- EXPECT_EQ("CHLO", QuicTagToString(MakeQuicTag('C', 'H', 'L', 'O')));
- // A tag that contains a non-printing character will be printed as hex.
- EXPECT_EQ("43484c1f", QuicTagToString(MakeQuicTag('C', 'H', 'L', '\x1f')));
-}
-
-TEST_F(QuicTagTest, MakeQuicTag) {
- QuicTag tag = MakeQuicTag('A', 'B', 'C', 'D');
- char bytes[4];
- memcpy(bytes, &tag, 4);
- EXPECT_EQ('A', bytes[0]);
- EXPECT_EQ('B', bytes[1]);
- EXPECT_EQ('C', bytes[2]);
- EXPECT_EQ('D', bytes[3]);
-}
-
-TEST_F(QuicTagTest, ParseQuicTag) {
- QuicTag tag_abcd = MakeQuicTag('A', 'B', 'C', 'D');
- EXPECT_EQ(ParseQuicTag("ABCD"), tag_abcd);
- EXPECT_EQ(ParseQuicTag("ABCDE"), tag_abcd);
- QuicTag tag_efgh = MakeQuicTag('E', 'F', 'G', 'H');
- EXPECT_EQ(ParseQuicTag("EFGH"), tag_efgh);
- QuicTag tag_ijk = MakeQuicTag('I', 'J', 'K', 0);
- EXPECT_EQ(ParseQuicTag("IJK"), tag_ijk);
- QuicTag tag_l = MakeQuicTag('L', 0, 0, 0);
- EXPECT_EQ(ParseQuicTag("L"), tag_l);
- QuicTag tag_hex = MakeQuicTag('M', 'N', 'O', static_cast<char>(255));
- EXPECT_EQ(ParseQuicTag("4d4e4fff"), tag_hex);
- EXPECT_EQ(ParseQuicTag("4D4E4FFF"), tag_hex);
- QuicTag tag_with_numbers = MakeQuicTag('P', 'Q', '1', '2');
- EXPECT_EQ(ParseQuicTag("PQ12"), tag_with_numbers);
- QuicTag tag_with_custom_chars = MakeQuicTag('r', '$', '_', '7');
- EXPECT_EQ(ParseQuicTag("r$_7"), tag_with_custom_chars);
- QuicTag tag_zero = 0;
- EXPECT_EQ(ParseQuicTag(""), tag_zero);
- QuicTagVector tag_vector;
- EXPECT_EQ(ParseQuicTagVector(""), tag_vector);
- EXPECT_EQ(ParseQuicTagVector(" "), tag_vector);
- tag_vector.push_back(tag_abcd);
- EXPECT_EQ(ParseQuicTagVector("ABCD"), tag_vector);
- tag_vector.push_back(tag_efgh);
- EXPECT_EQ(ParseQuicTagVector("ABCD,EFGH"), tag_vector);
- tag_vector.push_back(tag_ijk);
- EXPECT_EQ(ParseQuicTagVector("ABCD,EFGH,IJK"), tag_vector);
- tag_vector.push_back(tag_l);
- EXPECT_EQ(ParseQuicTagVector("ABCD,EFGH,IJK,L"), tag_vector);
- tag_vector.push_back(tag_hex);
- EXPECT_EQ(ParseQuicTagVector("ABCD,EFGH,IJK,L,4d4e4fff"), tag_vector);
- tag_vector.push_back(tag_with_numbers);
- EXPECT_EQ(ParseQuicTagVector("ABCD,EFGH,IJK,L,4d4e4fff,PQ12"), tag_vector);
- tag_vector.push_back(tag_with_custom_chars);
- EXPECT_EQ(ParseQuicTagVector("ABCD,EFGH,IJK,L,4d4e4fff,PQ12,r$_7"),
- tag_vector);
- tag_vector.push_back(tag_zero);
- EXPECT_EQ(ParseQuicTagVector("ABCD,EFGH,IJK,L,4d4e4fff,PQ12,r$_7,"),
- tag_vector);
-}
-
-} // namespace
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_time.cc b/chromium/net/third_party/quiche/src/quic/core/quic_time.cc
deleted file mode 100644
index 08e0906c7cb..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_time.cc
+++ /dev/null
@@ -1,87 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_time.h"
-
-#include <cinttypes>
-#include <cstdlib>
-#include <limits>
-#include <string>
-
-#include "absl/strings/str_cat.h"
-
-namespace quic {
-
-std::string QuicTime::Delta::ToDebuggingValue() const {
- constexpr int64_t kMillisecondInMicroseconds = 1000;
- constexpr int64_t kSecondInMicroseconds = 1000 * kMillisecondInMicroseconds;
-
- int64_t absolute_value = std::abs(time_offset_);
-
- // For debugging purposes, always display the value with the highest precision
- // available.
- if (absolute_value >= kSecondInMicroseconds &&
- absolute_value % kSecondInMicroseconds == 0) {
- return absl::StrCat(time_offset_ / kSecondInMicroseconds, "s");
- }
- if (absolute_value >= kMillisecondInMicroseconds &&
- absolute_value % kMillisecondInMicroseconds == 0) {
- return absl::StrCat(time_offset_ / kMillisecondInMicroseconds, "ms");
- }
- return absl::StrCat(time_offset_, "us");
-}
-
-uint64_t QuicWallTime::ToUNIXSeconds() const {
- return microseconds_ / 1000000;
-}
-
-uint64_t QuicWallTime::ToUNIXMicroseconds() const {
- return microseconds_;
-}
-
-bool QuicWallTime::IsAfter(QuicWallTime other) const {
- return microseconds_ > other.microseconds_;
-}
-
-bool QuicWallTime::IsBefore(QuicWallTime other) const {
- return microseconds_ < other.microseconds_;
-}
-
-bool QuicWallTime::IsZero() const {
- return microseconds_ == 0;
-}
-
-QuicTime::Delta QuicWallTime::AbsoluteDifference(QuicWallTime other) const {
- uint64_t d;
-
- if (microseconds_ > other.microseconds_) {
- d = microseconds_ - other.microseconds_;
- } else {
- d = other.microseconds_ - microseconds_;
- }
-
- if (d > static_cast<uint64_t>(std::numeric_limits<int64_t>::max())) {
- d = std::numeric_limits<int64_t>::max();
- }
- return QuicTime::Delta::FromMicroseconds(d);
-}
-
-QuicWallTime QuicWallTime::Add(QuicTime::Delta delta) const {
- uint64_t microseconds = microseconds_ + delta.ToMicroseconds();
- if (microseconds < microseconds_) {
- microseconds = std::numeric_limits<uint64_t>::max();
- }
- return QuicWallTime(microseconds);
-}
-
-// TODO(ianswett) Test this.
-QuicWallTime QuicWallTime::Subtract(QuicTime::Delta delta) const {
- uint64_t microseconds = microseconds_ - delta.ToMicroseconds();
- if (microseconds > microseconds_) {
- microseconds = 0;
- }
- return QuicWallTime(microseconds);
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_time.h b/chromium/net/third_party/quiche/src/quic/core/quic_time.h
deleted file mode 100644
index 5fe9b2e672b..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_time.h
+++ /dev/null
@@ -1,294 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// QuicTime represents one point in time, stored in microsecond resolution.
-// QuicTime is monotonically increasing, even across system clock adjustments.
-// The epoch (time 0) of QuicTime is unspecified.
-//
-// This implementation wraps a int64_t of usec since the epoch. While
-// the epoch is the Unix epoch, do not depend on this fact because other
-// implementations, like Chrome's, do NOT have the same epoch.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_TIME_H_
-#define QUICHE_QUIC_CORE_QUIC_TIME_H_
-
-#include <cmath>
-#include <cstdint>
-#include <limits>
-#include <ostream>
-#include <string>
-
-#include "quic/platform/api/quic_export.h"
-
-// TODO(vasilvv): replace with ABSL_MUST_USE_RESULT once we're using absl.
-#if defined(__clang__)
-#define QUIC_TIME_WARN_UNUSED_RESULT __attribute__((warn_unused_result))
-#else
-#define QUIC_TIME_WARN_UNUSED_RESULT
-#endif /* defined(__clang__) */
-
-namespace quic {
-
-class QuicClock;
-
-// A QuicTime is a purely relative time. QuicTime values from different clocks
-// cannot be compared to each other. If you need an absolute time, see
-// QuicWallTime, below.
-class QUIC_EXPORT_PRIVATE QuicTime {
- public:
- // A QuicTime::Delta represents the signed difference between two points in
- // time, stored in microsecond resolution.
- class QUIC_EXPORT_PRIVATE Delta {
- public:
- // Create a object with an offset of 0.
- static constexpr Delta Zero() { return Delta(0); }
-
- // Create a object with infinite offset time.
- static constexpr Delta Infinite() { return Delta(kQuicInfiniteTimeUs); }
-
- // Converts a number of seconds to a time offset.
- static constexpr Delta FromSeconds(int64_t secs) {
- return Delta(secs * 1000 * 1000);
- }
-
- // Converts a number of milliseconds to a time offset.
- static constexpr Delta FromMilliseconds(int64_t ms) {
- return Delta(ms * 1000);
- }
-
- // Converts a number of microseconds to a time offset.
- static constexpr Delta FromMicroseconds(int64_t us) { return Delta(us); }
-
- // Converts the time offset to a rounded number of seconds.
- inline int64_t ToSeconds() const { return time_offset_ / 1000 / 1000; }
-
- // Converts the time offset to a rounded number of milliseconds.
- inline int64_t ToMilliseconds() const { return time_offset_ / 1000; }
-
- // Converts the time offset to a rounded number of microseconds.
- inline int64_t ToMicroseconds() const { return time_offset_; }
-
- inline bool IsZero() const { return time_offset_ == 0; }
-
- inline bool IsInfinite() const {
- return time_offset_ == kQuicInfiniteTimeUs;
- }
-
- std::string ToDebuggingValue() const;
-
- private:
- friend inline bool operator==(QuicTime::Delta lhs, QuicTime::Delta rhs);
- friend inline bool operator<(QuicTime::Delta lhs, QuicTime::Delta rhs);
- friend inline QuicTime::Delta operator<<(QuicTime::Delta lhs, size_t rhs);
- friend inline QuicTime::Delta operator>>(QuicTime::Delta lhs, size_t rhs);
-
- friend inline QuicTime::Delta operator+(QuicTime::Delta lhs,
- QuicTime::Delta rhs);
- friend inline QuicTime::Delta operator-(QuicTime::Delta lhs,
- QuicTime::Delta rhs);
- friend inline QuicTime::Delta operator*(QuicTime::Delta lhs, int rhs);
- friend inline QuicTime::Delta operator*(QuicTime::Delta lhs, double rhs);
-
- friend inline QuicTime operator+(QuicTime lhs, QuicTime::Delta rhs);
- friend inline QuicTime operator-(QuicTime lhs, QuicTime::Delta rhs);
- friend inline QuicTime::Delta operator-(QuicTime lhs, QuicTime rhs);
-
- static const int64_t kQuicInfiniteTimeUs =
- std::numeric_limits<int64_t>::max();
-
- explicit constexpr Delta(int64_t time_offset) : time_offset_(time_offset) {}
-
- int64_t time_offset_;
- friend class QuicTime;
- };
-
- // Creates a new QuicTime with an internal value of 0. IsInitialized()
- // will return false for these times.
- static constexpr QuicTime Zero() { return QuicTime(0); }
-
- // Creates a new QuicTime with an infinite time.
- static constexpr QuicTime Infinite() {
- return QuicTime(Delta::kQuicInfiniteTimeUs);
- }
-
- QuicTime(const QuicTime& other) = default;
-
- QuicTime& operator=(const QuicTime& other) {
- time_ = other.time_;
- return *this;
- }
-
- // Produce the internal value to be used when logging. This value
- // represents the number of microseconds since some epoch. It may
- // be the UNIX epoch on some platforms. On others, it may
- // be a CPU ticks based value.
- inline int64_t ToDebuggingValue() const { return time_; }
-
- inline bool IsInitialized() const { return 0 != time_; }
-
- private:
- friend class QuicClock;
-
- friend inline bool operator==(QuicTime lhs, QuicTime rhs);
- friend inline bool operator<(QuicTime lhs, QuicTime rhs);
- friend inline QuicTime operator+(QuicTime lhs, QuicTime::Delta rhs);
- friend inline QuicTime operator-(QuicTime lhs, QuicTime::Delta rhs);
- friend inline QuicTime::Delta operator-(QuicTime lhs, QuicTime rhs);
-
- explicit constexpr QuicTime(int64_t time) : time_(time) {}
-
- int64_t time_;
-};
-
-// A QuicWallTime represents an absolute time that is globally consistent. In
-// practice, clock-skew means that comparing values from different machines
-// requires some flexibility.
-class QUIC_EXPORT_PRIVATE QuicWallTime {
- public:
- // FromUNIXSeconds constructs a QuicWallTime from a count of the seconds
- // since the UNIX epoch.
- static constexpr QuicWallTime FromUNIXSeconds(uint64_t seconds) {
- return QuicWallTime(seconds * 1000000);
- }
-
- static constexpr QuicWallTime FromUNIXMicroseconds(uint64_t microseconds) {
- return QuicWallTime(microseconds);
- }
-
- // Zero returns a QuicWallTime set to zero. IsZero will return true for this
- // value.
- static constexpr QuicWallTime Zero() { return QuicWallTime(0); }
-
- // Returns the number of seconds since the UNIX epoch.
- uint64_t ToUNIXSeconds() const;
- // Returns the number of microseconds since the UNIX epoch.
- uint64_t ToUNIXMicroseconds() const;
-
- bool IsAfter(QuicWallTime other) const;
- bool IsBefore(QuicWallTime other) const;
-
- // IsZero returns true if this object is the result of calling |Zero|.
- bool IsZero() const;
-
- // AbsoluteDifference returns the absolute value of the time difference
- // between |this| and |other|.
- QuicTime::Delta AbsoluteDifference(QuicWallTime other) const;
-
- // Add returns a new QuicWallTime that represents the time of |this| plus
- // |delta|.
- QUIC_TIME_WARN_UNUSED_RESULT QuicWallTime Add(QuicTime::Delta delta) const;
-
- // Subtract returns a new QuicWallTime that represents the time of |this|
- // minus |delta|.
- QUIC_TIME_WARN_UNUSED_RESULT QuicWallTime
- Subtract(QuicTime::Delta delta) const;
-
- bool operator==(const QuicWallTime& other) const {
- return microseconds_ == other.microseconds_;
- }
-
- QuicTime::Delta operator-(const QuicWallTime& rhs) const {
- return QuicTime::Delta::FromMicroseconds(microseconds_ - rhs.microseconds_);
- }
-
- private:
- explicit constexpr QuicWallTime(uint64_t microseconds)
- : microseconds_(microseconds) {}
-
- uint64_t microseconds_;
-};
-
-// Non-member relational operators for QuicTime::Delta.
-inline bool operator==(QuicTime::Delta lhs, QuicTime::Delta rhs) {
- return lhs.time_offset_ == rhs.time_offset_;
-}
-inline bool operator!=(QuicTime::Delta lhs, QuicTime::Delta rhs) {
- return !(lhs == rhs);
-}
-inline bool operator<(QuicTime::Delta lhs, QuicTime::Delta rhs) {
- return lhs.time_offset_ < rhs.time_offset_;
-}
-inline bool operator>(QuicTime::Delta lhs, QuicTime::Delta rhs) {
- return rhs < lhs;
-}
-inline bool operator<=(QuicTime::Delta lhs, QuicTime::Delta rhs) {
- return !(rhs < lhs);
-}
-inline bool operator>=(QuicTime::Delta lhs, QuicTime::Delta rhs) {
- return !(lhs < rhs);
-}
-inline QuicTime::Delta operator<<(QuicTime::Delta lhs, size_t rhs) {
- return QuicTime::Delta(lhs.time_offset_ << rhs);
-}
-inline QuicTime::Delta operator>>(QuicTime::Delta lhs, size_t rhs) {
- return QuicTime::Delta(lhs.time_offset_ >> rhs);
-}
-
-// Non-member relational operators for QuicTime.
-inline bool operator==(QuicTime lhs, QuicTime rhs) {
- return lhs.time_ == rhs.time_;
-}
-inline bool operator!=(QuicTime lhs, QuicTime rhs) {
- return !(lhs == rhs);
-}
-inline bool operator<(QuicTime lhs, QuicTime rhs) {
- return lhs.time_ < rhs.time_;
-}
-inline bool operator>(QuicTime lhs, QuicTime rhs) {
- return rhs < lhs;
-}
-inline bool operator<=(QuicTime lhs, QuicTime rhs) {
- return !(rhs < lhs);
-}
-inline bool operator>=(QuicTime lhs, QuicTime rhs) {
- return !(lhs < rhs);
-}
-
-// Override stream output operator for gtest or QUICHE_CHECK macros.
-inline std::ostream& operator<<(std::ostream& output, const QuicTime t) {
- output << t.ToDebuggingValue();
- return output;
-}
-
-// Non-member arithmetic operators for QuicTime::Delta.
-inline QuicTime::Delta operator+(QuicTime::Delta lhs, QuicTime::Delta rhs) {
- return QuicTime::Delta(lhs.time_offset_ + rhs.time_offset_);
-}
-inline QuicTime::Delta operator-(QuicTime::Delta lhs, QuicTime::Delta rhs) {
- return QuicTime::Delta(lhs.time_offset_ - rhs.time_offset_);
-}
-inline QuicTime::Delta operator*(QuicTime::Delta lhs, int rhs) {
- return QuicTime::Delta(lhs.time_offset_ * rhs);
-}
-inline QuicTime::Delta operator*(QuicTime::Delta lhs, double rhs) {
- return QuicTime::Delta(static_cast<int64_t>(
- std::llround(static_cast<double>(lhs.time_offset_) * rhs)));
-}
-inline QuicTime::Delta operator*(int lhs, QuicTime::Delta rhs) {
- return rhs * lhs;
-}
-inline QuicTime::Delta operator*(double lhs, QuicTime::Delta rhs) {
- return rhs * lhs;
-}
-
-// Non-member arithmetic operators for QuicTime and QuicTime::Delta.
-inline QuicTime operator+(QuicTime lhs, QuicTime::Delta rhs) {
- return QuicTime(lhs.time_ + rhs.time_offset_);
-}
-inline QuicTime operator-(QuicTime lhs, QuicTime::Delta rhs) {
- return QuicTime(lhs.time_ - rhs.time_offset_);
-}
-inline QuicTime::Delta operator-(QuicTime lhs, QuicTime rhs) {
- return QuicTime::Delta(lhs.time_ - rhs.time_);
-}
-
-// Override stream output operator for gtest.
-inline std::ostream& operator<<(std::ostream& output,
- const QuicTime::Delta delta) {
- output << delta.ToDebuggingValue();
- return output;
-}
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_QUIC_TIME_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_time_accumulator.h b/chromium/net/third_party/quiche/src/quic/core/quic_time_accumulator.h
deleted file mode 100644
index 8680cb61645..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_time_accumulator.h
+++ /dev/null
@@ -1,69 +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_CORE_QUIC_TIME_ACCUMULATOR_H_
-#define QUICHE_QUIC_CORE_QUIC_TIME_ACCUMULATOR_H_
-
-#include "quic/core/quic_time.h"
-#include "quic/platform/api/quic_export.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-// QuicTimeAccumulator accumulates elapsed times between Start(s) and Stop(s).
-class QUIC_EXPORT_PRIVATE QuicTimeAccumulator {
- // TODO(wub): Switch to a data member called kNotRunningSentinel after c++17.
- static constexpr QuicTime NotRunningSentinel() {
- return QuicTime::Infinite();
- }
-
- public:
- // True if Started and not Stopped.
- bool IsRunning() const { return last_start_time_ != NotRunningSentinel(); }
-
- void Start(QuicTime now) {
- QUICHE_DCHECK(!IsRunning());
- last_start_time_ = now;
- QUICHE_DCHECK(IsRunning());
- }
-
- void Stop(QuicTime now) {
- QUICHE_DCHECK(IsRunning());
- if (now > last_start_time_) {
- total_elapsed_ = total_elapsed_ + (now - last_start_time_);
- }
- last_start_time_ = NotRunningSentinel();
- QUICHE_DCHECK(!IsRunning());
- }
-
- // Get total elapsed time between COMPLETED Start/Stop pairs.
- QuicTime::Delta GetTotalElapsedTime() const { return total_elapsed_; }
-
- // Get total elapsed time between COMPLETED Start/Stop pairs, plus, if it is
- // running, the elapsed time between |last_start_time_| and |now|.
- QuicTime::Delta GetTotalElapsedTime(QuicTime now) const {
- if (!IsRunning()) {
- return total_elapsed_;
- }
- if (now <= last_start_time_) {
- return total_elapsed_;
- }
- return total_elapsed_ + (now - last_start_time_);
- }
-
- private:
- //
- // |last_start_time_|
- // |
- // V
- // Start => Stop => Start => Stop => Start
- // | | | |
- // |___________| + |___________| = |total_elapsed_|
- QuicTime::Delta total_elapsed_ = QuicTime::Delta::Zero();
- QuicTime last_start_time_ = NotRunningSentinel();
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_QUIC_TIME_ACCUMULATOR_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_time_accumulator_test.cc b/chromium/net/third_party/quiche/src/quic/core/quic_time_accumulator_test.cc
deleted file mode 100644
index 35980065310..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_time_accumulator_test.cc
+++ /dev/null
@@ -1,82 +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 "quic/core/quic_time_accumulator.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/mock_clock.h"
-
-namespace quic {
-namespace test {
-
-TEST(QuicTimeAccumulator, DefaultConstruct) {
- MockClock clock;
- clock.AdvanceTime(QuicTime::Delta::FromMilliseconds(1));
-
- QuicTimeAccumulator acc;
- EXPECT_FALSE(acc.IsRunning());
-
- clock.AdvanceTime(QuicTime::Delta::FromMilliseconds(1));
- EXPECT_EQ(QuicTime::Delta::Zero(), acc.GetTotalElapsedTime());
- EXPECT_EQ(QuicTime::Delta::Zero(), acc.GetTotalElapsedTime(clock.Now()));
-}
-
-TEST(QuicTimeAccumulator, StartStop) {
- MockClock clock;
- clock.AdvanceTime(QuicTime::Delta::FromMilliseconds(1));
-
- QuicTimeAccumulator acc;
- acc.Start(clock.Now());
- EXPECT_TRUE(acc.IsRunning());
-
- clock.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
- acc.Stop(clock.Now());
- EXPECT_FALSE(acc.IsRunning());
-
- clock.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
- EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10), acc.GetTotalElapsedTime());
- EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10),
- acc.GetTotalElapsedTime(clock.Now()));
-
- acc.Start(clock.Now());
- clock.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
- EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10), acc.GetTotalElapsedTime());
- EXPECT_EQ(QuicTime::Delta::FromMilliseconds(15),
- acc.GetTotalElapsedTime(clock.Now()));
-
- clock.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
- EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10), acc.GetTotalElapsedTime());
- EXPECT_EQ(QuicTime::Delta::FromMilliseconds(20),
- acc.GetTotalElapsedTime(clock.Now()));
-
- acc.Stop(clock.Now());
- EXPECT_EQ(QuicTime::Delta::FromMilliseconds(20), acc.GetTotalElapsedTime());
- EXPECT_EQ(QuicTime::Delta::FromMilliseconds(20),
- acc.GetTotalElapsedTime(clock.Now()));
-}
-
-TEST(QuicTimeAccumulator, ClockStepBackwards) {
- MockClock clock;
- clock.AdvanceTime(QuicTime::Delta::FromMilliseconds(100));
-
- QuicTimeAccumulator acc;
- acc.Start(clock.Now());
-
- clock.AdvanceTime(QuicTime::Delta::FromMilliseconds(-10));
- acc.Stop(clock.Now());
- EXPECT_EQ(QuicTime::Delta::Zero(), acc.GetTotalElapsedTime());
- EXPECT_EQ(QuicTime::Delta::Zero(), acc.GetTotalElapsedTime(clock.Now()));
-
- acc.Start(clock.Now());
- clock.AdvanceTime(QuicTime::Delta::FromMilliseconds(50));
- acc.Stop(clock.Now());
-
- acc.Start(clock.Now());
- clock.AdvanceTime(QuicTime::Delta::FromMilliseconds(-80));
- EXPECT_EQ(QuicTime::Delta::FromMilliseconds(50), acc.GetTotalElapsedTime());
- EXPECT_EQ(QuicTime::Delta::FromMilliseconds(50),
- acc.GetTotalElapsedTime(clock.Now()));
-}
-
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_time_test.cc b/chromium/net/third_party/quiche/src/quic/core/quic_time_test.cc
deleted file mode 100644
index e5bb2857d0a..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_time_test.cc
+++ /dev/null
@@ -1,185 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_time.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/mock_clock.h"
-
-namespace quic {
-namespace test {
-
-class QuicTimeDeltaTest : public QuicTest {};
-
-TEST_F(QuicTimeDeltaTest, Zero) {
- EXPECT_TRUE(QuicTime::Delta::Zero().IsZero());
- EXPECT_FALSE(QuicTime::Delta::Zero().IsInfinite());
- EXPECT_FALSE(QuicTime::Delta::FromMilliseconds(1).IsZero());
-}
-
-TEST_F(QuicTimeDeltaTest, Infinite) {
- EXPECT_TRUE(QuicTime::Delta::Infinite().IsInfinite());
- EXPECT_FALSE(QuicTime::Delta::Zero().IsInfinite());
- EXPECT_FALSE(QuicTime::Delta::FromMilliseconds(1).IsInfinite());
-}
-
-TEST_F(QuicTimeDeltaTest, FromTo) {
- EXPECT_EQ(QuicTime::Delta::FromMilliseconds(1),
- QuicTime::Delta::FromMicroseconds(1000));
- EXPECT_EQ(QuicTime::Delta::FromSeconds(1),
- QuicTime::Delta::FromMilliseconds(1000));
- EXPECT_EQ(QuicTime::Delta::FromSeconds(1),
- QuicTime::Delta::FromMicroseconds(1000000));
-
- EXPECT_EQ(1, QuicTime::Delta::FromMicroseconds(1000).ToMilliseconds());
- EXPECT_EQ(2, QuicTime::Delta::FromMilliseconds(2000).ToSeconds());
- EXPECT_EQ(1000, QuicTime::Delta::FromMilliseconds(1).ToMicroseconds());
- EXPECT_EQ(1, QuicTime::Delta::FromMicroseconds(1000).ToMilliseconds());
- EXPECT_EQ(QuicTime::Delta::FromMilliseconds(2000).ToMicroseconds(),
- QuicTime::Delta::FromSeconds(2).ToMicroseconds());
-}
-
-TEST_F(QuicTimeDeltaTest, Add) {
- EXPECT_EQ(QuicTime::Delta::FromMicroseconds(2000),
- QuicTime::Delta::Zero() + QuicTime::Delta::FromMilliseconds(2));
-}
-
-TEST_F(QuicTimeDeltaTest, Subtract) {
- EXPECT_EQ(QuicTime::Delta::FromMicroseconds(1000),
- QuicTime::Delta::FromMilliseconds(2) -
- QuicTime::Delta::FromMilliseconds(1));
-}
-
-TEST_F(QuicTimeDeltaTest, Multiply) {
- int i = 2;
- EXPECT_EQ(QuicTime::Delta::FromMicroseconds(4000),
- QuicTime::Delta::FromMilliseconds(2) * i);
- EXPECT_EQ(QuicTime::Delta::FromMicroseconds(4000),
- i * QuicTime::Delta::FromMilliseconds(2));
- double d = 2;
- EXPECT_EQ(QuicTime::Delta::FromMicroseconds(4000),
- QuicTime::Delta::FromMilliseconds(2) * d);
- EXPECT_EQ(QuicTime::Delta::FromMicroseconds(4000),
- d * QuicTime::Delta::FromMilliseconds(2));
-
- // Ensure we are rounding correctly within a single-bit level of precision.
- EXPECT_EQ(QuicTime::Delta::FromMicroseconds(5),
- QuicTime::Delta::FromMicroseconds(9) * 0.5);
- EXPECT_EQ(QuicTime::Delta::FromMicroseconds(2),
- QuicTime::Delta::FromMicroseconds(12) * 0.2);
-}
-
-TEST_F(QuicTimeDeltaTest, Max) {
- EXPECT_EQ(QuicTime::Delta::FromMicroseconds(2000),
- std::max(QuicTime::Delta::FromMicroseconds(1000),
- QuicTime::Delta::FromMicroseconds(2000)));
-}
-
-TEST_F(QuicTimeDeltaTest, NotEqual) {
- EXPECT_TRUE(QuicTime::Delta::FromSeconds(0) !=
- QuicTime::Delta::FromSeconds(1));
- EXPECT_FALSE(QuicTime::Delta::FromSeconds(0) !=
- QuicTime::Delta::FromSeconds(0));
-}
-
-TEST_F(QuicTimeDeltaTest, DebuggingValue) {
- const QuicTime::Delta one_us = QuicTime::Delta::FromMicroseconds(1);
- const QuicTime::Delta one_ms = QuicTime::Delta::FromMilliseconds(1);
- const QuicTime::Delta one_s = QuicTime::Delta::FromSeconds(1);
-
- EXPECT_EQ("1s", one_s.ToDebuggingValue());
- EXPECT_EQ("3s", (3 * one_s).ToDebuggingValue());
- EXPECT_EQ("1ms", one_ms.ToDebuggingValue());
- EXPECT_EQ("3ms", (3 * one_ms).ToDebuggingValue());
- EXPECT_EQ("1us", one_us.ToDebuggingValue());
- EXPECT_EQ("3us", (3 * one_us).ToDebuggingValue());
-
- EXPECT_EQ("3001us", (3 * one_ms + one_us).ToDebuggingValue());
- EXPECT_EQ("3001ms", (3 * one_s + one_ms).ToDebuggingValue());
- EXPECT_EQ("3000001us", (3 * one_s + one_us).ToDebuggingValue());
-}
-
-class QuicTimeTest : public QuicTest {
- protected:
- MockClock clock_;
-};
-
-TEST_F(QuicTimeTest, Initialized) {
- EXPECT_FALSE(QuicTime::Zero().IsInitialized());
- EXPECT_TRUE((QuicTime::Zero() + QuicTime::Delta::FromMicroseconds(1))
- .IsInitialized());
-}
-
-TEST_F(QuicTimeTest, CopyConstruct) {
- QuicTime time_1 = QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(1234);
- EXPECT_NE(time_1, QuicTime(QuicTime::Zero()));
- EXPECT_EQ(time_1, QuicTime(time_1));
-}
-
-TEST_F(QuicTimeTest, CopyAssignment) {
- QuicTime time_1 = QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(1234);
- QuicTime time_2 = QuicTime::Zero();
- EXPECT_NE(time_1, time_2);
- time_2 = time_1;
- EXPECT_EQ(time_1, time_2);
-}
-
-TEST_F(QuicTimeTest, Add) {
- QuicTime time_1 = QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(1);
- QuicTime time_2 = QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(2);
-
- QuicTime::Delta diff = time_2 - time_1;
-
- EXPECT_EQ(QuicTime::Delta::FromMilliseconds(1), diff);
- EXPECT_EQ(1000, diff.ToMicroseconds());
- EXPECT_EQ(1, diff.ToMilliseconds());
-}
-
-TEST_F(QuicTimeTest, Subtract) {
- QuicTime time_1 = QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(1);
- QuicTime time_2 = QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(2);
-
- EXPECT_EQ(QuicTime::Delta::FromMilliseconds(1), time_2 - time_1);
-}
-
-TEST_F(QuicTimeTest, SubtractDelta) {
- QuicTime time = QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(2);
- EXPECT_EQ(QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(1),
- time - QuicTime::Delta::FromMilliseconds(1));
-}
-
-TEST_F(QuicTimeTest, Max) {
- QuicTime time_1 = QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(1);
- QuicTime time_2 = QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(2);
-
- EXPECT_EQ(time_2, std::max(time_1, time_2));
-}
-
-TEST_F(QuicTimeTest, MockClock) {
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(1));
-
- QuicTime now = clock_.ApproximateNow();
- QuicTime time = QuicTime::Zero() + QuicTime::Delta::FromMicroseconds(1000);
-
- EXPECT_EQ(now, time);
-
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(1));
- now = clock_.ApproximateNow();
-
- EXPECT_NE(now, time);
-
- time = time + QuicTime::Delta::FromMilliseconds(1);
- EXPECT_EQ(now, time);
-}
-
-TEST_F(QuicTimeTest, LE) {
- const QuicTime zero = QuicTime::Zero();
- const QuicTime one = zero + QuicTime::Delta::FromSeconds(1);
- EXPECT_TRUE(zero <= zero);
- EXPECT_TRUE(zero <= one);
- EXPECT_TRUE(one <= one);
- EXPECT_FALSE(one <= zero);
-}
-
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_time_wait_list_manager.cc b/chromium/net/third_party/quiche/src/quic/core/quic_time_wait_list_manager.cc
deleted file mode 100644
index da01d2a2264..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_time_wait_list_manager.cc
+++ /dev/null
@@ -1,503 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_time_wait_list_manager.h"
-
-#include <errno.h>
-
-#include <memory>
-#include <utility>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/crypto/crypto_protocol.h"
-#include "quic/core/crypto/quic_decrypter.h"
-#include "quic/core/crypto/quic_encrypter.h"
-#include "quic/core/quic_clock.h"
-#include "quic/core/quic_connection_id.h"
-#include "quic/core/quic_framer.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_flag_utils.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/platform/api/quic_socket_address.h"
-#include "common/quiche_text_utils.h"
-
-namespace quic {
-
-// A very simple alarm that just informs the QuicTimeWaitListManager to clean
-// up old connection_ids. This alarm should be cancelled and deleted before
-// the QuicTimeWaitListManager is deleted.
-class ConnectionIdCleanUpAlarm : public QuicAlarm::DelegateWithoutContext {
- public:
- explicit ConnectionIdCleanUpAlarm(
- QuicTimeWaitListManager* time_wait_list_manager)
- : time_wait_list_manager_(time_wait_list_manager) {}
- ConnectionIdCleanUpAlarm(const ConnectionIdCleanUpAlarm&) = delete;
- ConnectionIdCleanUpAlarm& operator=(const ConnectionIdCleanUpAlarm&) = delete;
-
- void OnAlarm() override {
- time_wait_list_manager_->CleanUpOldConnectionIds();
- }
-
- private:
- // Not owned.
- QuicTimeWaitListManager* time_wait_list_manager_;
-};
-
-TimeWaitConnectionInfo::TimeWaitConnectionInfo(
- bool ietf_quic,
- std::vector<std::unique_ptr<QuicEncryptedPacket>>* termination_packets,
- std::vector<QuicConnectionId> active_connection_ids)
- : TimeWaitConnectionInfo(ietf_quic,
- termination_packets,
- std::move(active_connection_ids),
- QuicTime::Delta::Zero()) {}
-
-TimeWaitConnectionInfo::TimeWaitConnectionInfo(
- bool ietf_quic,
- std::vector<std::unique_ptr<QuicEncryptedPacket>>* termination_packets,
- std::vector<QuicConnectionId> active_connection_ids,
- QuicTime::Delta srtt)
- : ietf_quic(ietf_quic),
- active_connection_ids(std::move(active_connection_ids)),
- srtt(srtt) {
- if (termination_packets != nullptr) {
- this->termination_packets.swap(*termination_packets);
- }
-}
-
-QuicTimeWaitListManager::QuicTimeWaitListManager(
- QuicPacketWriter* writer,
- Visitor* visitor,
- const QuicClock* clock,
- QuicAlarmFactory* alarm_factory)
- : time_wait_period_(QuicTime::Delta::FromSeconds(
- GetQuicFlag(FLAGS_quic_time_wait_list_seconds))),
- connection_id_clean_up_alarm_(
- alarm_factory->CreateAlarm(new ConnectionIdCleanUpAlarm(this))),
- clock_(clock),
- writer_(writer),
- visitor_(visitor) {
- SetConnectionIdCleanUpAlarm();
-}
-
-QuicTimeWaitListManager::~QuicTimeWaitListManager() {
- connection_id_clean_up_alarm_->Cancel();
-}
-
-QuicTimeWaitListManager::ConnectionIdMap::iterator
-QuicTimeWaitListManager::FindConnectionIdDataInMap(
- const QuicConnectionId& connection_id) {
- auto it = indirect_connection_id_map_.find(connection_id);
- if (it == indirect_connection_id_map_.end()) {
- return connection_id_map_.end();
- }
- return connection_id_map_.find(it->second);
-}
-
-void QuicTimeWaitListManager::AddConnectionIdDataToMap(
- const QuicConnectionId& canonical_connection_id,
- int num_packets,
- TimeWaitAction action,
- TimeWaitConnectionInfo info) {
- for (const auto& cid : info.active_connection_ids) {
- indirect_connection_id_map_[cid] = canonical_connection_id;
- }
- ConnectionIdData data(num_packets, clock_->ApproximateNow(), action,
- std::move(info));
- connection_id_map_.emplace(
- std::make_pair(canonical_connection_id, std::move(data)));
-}
-
-void QuicTimeWaitListManager::RemoveConnectionDataFromMap(
- ConnectionIdMap::iterator it) {
- for (const auto& cid : it->second.info.active_connection_ids) {
- indirect_connection_id_map_.erase(cid);
- }
- connection_id_map_.erase(it);
-}
-
-void QuicTimeWaitListManager::AddConnectionIdToTimeWait(
- TimeWaitAction action,
- TimeWaitConnectionInfo info) {
- QUICHE_DCHECK(!info.active_connection_ids.empty());
- const QuicConnectionId& canonical_connection_id =
- info.active_connection_ids.front();
- QUICHE_DCHECK(action != SEND_TERMINATION_PACKETS ||
- !info.termination_packets.empty());
- QUICHE_DCHECK(action != DO_NOTHING || info.ietf_quic);
- int num_packets = 0;
- auto it = FindConnectionIdDataInMap(canonical_connection_id);
- const bool new_connection_id = it == connection_id_map_.end();
- if (!new_connection_id) { // Replace record if it is reinserted.
- num_packets = it->second.num_packets;
- RemoveConnectionDataFromMap(it);
- }
- TrimTimeWaitListIfNeeded();
- int64_t max_connections =
- GetQuicFlag(FLAGS_quic_time_wait_list_max_connections);
- QUICHE_DCHECK(connection_id_map_.empty() ||
- num_connections() < static_cast<size_t>(max_connections));
- if (new_connection_id) {
- for (const auto& cid : info.active_connection_ids) {
- visitor_->OnConnectionAddedToTimeWaitList(cid);
- }
- }
- AddConnectionIdDataToMap(canonical_connection_id, num_packets, action,
- std::move(info));
-}
-
-bool QuicTimeWaitListManager::IsConnectionIdInTimeWait(
- QuicConnectionId connection_id) const {
- return indirect_connection_id_map_.contains(connection_id);
-}
-
-void QuicTimeWaitListManager::OnBlockedWriterCanWrite() {
- writer_->SetWritable();
- while (!pending_packets_queue_.empty()) {
- QueuedPacket* queued_packet = pending_packets_queue_.front().get();
- if (!WriteToWire(queued_packet)) {
- return;
- }
- pending_packets_queue_.pop_front();
- }
-}
-
-void QuicTimeWaitListManager::ProcessPacket(
- const QuicSocketAddress& self_address,
- const QuicSocketAddress& peer_address,
- QuicConnectionId connection_id,
- PacketHeaderFormat header_format,
- size_t received_packet_length,
- std::unique_ptr<QuicPerPacketContext> packet_context) {
- QUICHE_DCHECK(IsConnectionIdInTimeWait(connection_id));
- // TODO(satyamshekhar): Think about handling packets from different peer
- // addresses.
- auto it = FindConnectionIdDataInMap(connection_id);
- QUICHE_DCHECK(it != connection_id_map_.end());
- // Increment the received packet count.
- ConnectionIdData* connection_data = &it->second;
- ++(connection_data->num_packets);
- const QuicTime now = clock_->ApproximateNow();
- QuicTime::Delta delta = QuicTime::Delta::Zero();
- if (now > connection_data->time_added) {
- delta = now - connection_data->time_added;
- }
- OnPacketReceivedForKnownConnection(connection_data->num_packets, delta,
- connection_data->info.srtt);
-
- if (!ShouldSendResponse(connection_data->num_packets)) {
- QUIC_DLOG(INFO) << "Processing " << connection_id << " in time wait state: "
- << "throttled";
- return;
- }
-
- QUIC_DLOG(INFO) << "Processing " << connection_id << " in time wait state: "
- << "header format=" << header_format
- << " ietf=" << connection_data->info.ietf_quic
- << ", action=" << connection_data->action
- << ", number termination packets="
- << connection_data->info.termination_packets.size();
- switch (connection_data->action) {
- case SEND_TERMINATION_PACKETS:
- if (connection_data->info.termination_packets.empty()) {
- QUIC_BUG(quic_bug_10608_1) << "There are no termination packets.";
- return;
- }
- switch (header_format) {
- case IETF_QUIC_LONG_HEADER_PACKET:
- if (!connection_data->info.ietf_quic) {
- QUIC_CODE_COUNT(quic_received_long_header_packet_for_gquic);
- }
- break;
- case IETF_QUIC_SHORT_HEADER_PACKET:
- if (!connection_data->info.ietf_quic) {
- QUIC_CODE_COUNT(quic_received_short_header_packet_for_gquic);
- }
- // Send stateless reset in response to short header packets.
- SendPublicReset(self_address, peer_address, connection_id,
- connection_data->info.ietf_quic,
- received_packet_length, std::move(packet_context));
- return;
- case GOOGLE_QUIC_PACKET:
- if (connection_data->info.ietf_quic) {
- QUIC_CODE_COUNT(quic_received_gquic_packet_for_ietf_quic);
- }
- break;
- }
-
- for (const auto& packet : connection_data->info.termination_packets) {
- SendOrQueuePacket(std::make_unique<QueuedPacket>(
- self_address, peer_address, packet->Clone()),
- packet_context.get());
- }
- return;
-
- case SEND_CONNECTION_CLOSE_PACKETS:
- if (connection_data->info.termination_packets.empty()) {
- QUIC_BUG(quic_bug_10608_2) << "There are no termination packets.";
- return;
- }
- for (const auto& packet : connection_data->info.termination_packets) {
- SendOrQueuePacket(std::make_unique<QueuedPacket>(
- self_address, peer_address, packet->Clone()),
- packet_context.get());
- }
- return;
-
- case SEND_STATELESS_RESET:
- if (header_format == IETF_QUIC_LONG_HEADER_PACKET) {
- QUIC_CODE_COUNT(quic_stateless_reset_long_header_packet);
- }
- SendPublicReset(self_address, peer_address, connection_id,
- connection_data->info.ietf_quic, received_packet_length,
- std::move(packet_context));
- return;
- case DO_NOTHING:
- QUIC_CODE_COUNT(quic_time_wait_list_do_nothing);
- QUICHE_DCHECK(connection_data->info.ietf_quic);
- }
-}
-
-void QuicTimeWaitListManager::SendVersionNegotiationPacket(
- QuicConnectionId server_connection_id,
- QuicConnectionId client_connection_id,
- bool ietf_quic,
- bool use_length_prefix,
- const ParsedQuicVersionVector& supported_versions,
- const QuicSocketAddress& self_address,
- const QuicSocketAddress& peer_address,
- std::unique_ptr<QuicPerPacketContext> packet_context) {
- std::unique_ptr<QuicEncryptedPacket> version_packet =
- QuicFramer::BuildVersionNegotiationPacket(
- server_connection_id, client_connection_id, ietf_quic,
- use_length_prefix, supported_versions);
- QUIC_DVLOG(2) << "Dispatcher sending version negotiation packet {"
- << ParsedQuicVersionVectorToString(supported_versions) << "}, "
- << (ietf_quic ? "" : "!") << "ietf_quic, "
- << (use_length_prefix ? "" : "!")
- << "use_length_prefix:" << std::endl
- << quiche::QuicheTextUtils::HexDump(absl::string_view(
- version_packet->data(), version_packet->length()));
- SendOrQueuePacket(std::make_unique<QueuedPacket>(self_address, peer_address,
- std::move(version_packet)),
- packet_context.get());
-}
-
-// Returns true if the number of packets received for this connection_id is a
-// power of 2 to throttle the number of public reset packets we send to a peer.
-bool QuicTimeWaitListManager::ShouldSendResponse(int received_packet_count) {
- return (received_packet_count & (received_packet_count - 1)) == 0;
-}
-
-void QuicTimeWaitListManager::SendPublicReset(
- const QuicSocketAddress& self_address,
- const QuicSocketAddress& peer_address,
- QuicConnectionId connection_id,
- bool ietf_quic,
- size_t received_packet_length,
- std::unique_ptr<QuicPerPacketContext> packet_context) {
- if (ietf_quic) {
- std::unique_ptr<QuicEncryptedPacket> ietf_reset_packet =
- BuildIetfStatelessResetPacket(connection_id, received_packet_length);
- if (ietf_reset_packet == nullptr) {
- // This could happen when trying to reject a short header packet of
- // a connection which is in the time wait list (and with no termination
- // packet).
- return;
- }
- QUIC_DVLOG(2) << "Dispatcher sending IETF reset packet for "
- << connection_id << std::endl
- << quiche::QuicheTextUtils::HexDump(
- absl::string_view(ietf_reset_packet->data(),
- ietf_reset_packet->length()));
- SendOrQueuePacket(
- std::make_unique<QueuedPacket>(self_address, peer_address,
- std::move(ietf_reset_packet)),
- packet_context.get());
- return;
- }
- // Google QUIC public resets donot elicit resets in response.
- QuicPublicResetPacket packet;
- packet.connection_id = connection_id;
- // TODO(satyamshekhar): generate a valid nonce for this connection_id.
- packet.nonce_proof = 1010101;
- // TODO(wub): This is wrong for proxied sessions. Fix it.
- packet.client_address = peer_address;
- GetEndpointId(&packet.endpoint_id);
- // Takes ownership of the packet.
- std::unique_ptr<QuicEncryptedPacket> reset_packet = BuildPublicReset(packet);
- QUIC_DVLOG(2) << "Dispatcher sending reset packet for " << connection_id
- << std::endl
- << quiche::QuicheTextUtils::HexDump(absl::string_view(
- reset_packet->data(), reset_packet->length()));
- SendOrQueuePacket(std::make_unique<QueuedPacket>(self_address, peer_address,
- std::move(reset_packet)),
- packet_context.get());
-}
-
-void QuicTimeWaitListManager::SendPacket(const QuicSocketAddress& self_address,
- const QuicSocketAddress& peer_address,
- const QuicEncryptedPacket& packet) {
- SendOrQueuePacket(std::make_unique<QueuedPacket>(self_address, peer_address,
- packet.Clone()),
- nullptr);
-}
-
-std::unique_ptr<QuicEncryptedPacket> QuicTimeWaitListManager::BuildPublicReset(
- const QuicPublicResetPacket& packet) {
- return QuicFramer::BuildPublicResetPacket(packet);
-}
-
-std::unique_ptr<QuicEncryptedPacket>
-QuicTimeWaitListManager::BuildIetfStatelessResetPacket(
- QuicConnectionId connection_id,
- size_t received_packet_length) {
- return QuicFramer::BuildIetfStatelessResetPacket(
- connection_id, received_packet_length,
- GetStatelessResetToken(connection_id));
-}
-
-// Either sends the packet and deletes it or makes pending queue the
-// owner of the packet.
-bool QuicTimeWaitListManager::SendOrQueuePacket(
- std::unique_ptr<QueuedPacket> packet,
- const QuicPerPacketContext* /*packet_context*/) {
- if (packet == nullptr) {
- QUIC_LOG(ERROR) << "Tried to send or queue a null packet";
- return true;
- }
- if (pending_packets_queue_.size() >=
- GetQuicFlag(FLAGS_quic_time_wait_list_max_pending_packets)) {
- // There are too many pending packets.
- QUIC_CODE_COUNT(quic_too_many_pending_packets_in_time_wait);
- return true;
- }
- if (WriteToWire(packet.get())) {
- // Allow the packet to be deleted upon leaving this function.
- return true;
- }
- pending_packets_queue_.push_back(std::move(packet));
- return false;
-}
-
-bool QuicTimeWaitListManager::WriteToWire(QueuedPacket* queued_packet) {
- if (writer_->IsWriteBlocked()) {
- visitor_->OnWriteBlocked(this);
- return false;
- }
- WriteResult result = writer_->WritePacket(
- queued_packet->packet()->data(), queued_packet->packet()->length(),
- queued_packet->self_address().host(), queued_packet->peer_address(),
- nullptr);
-
- // If using a batch writer and the packet is buffered, flush it.
- if (writer_->IsBatchMode() && result.status == WRITE_STATUS_OK &&
- result.bytes_written == 0) {
- result = writer_->Flush();
- }
-
- if (IsWriteBlockedStatus(result.status)) {
- // If blocked and unbuffered, return false to retry sending.
- QUICHE_DCHECK(writer_->IsWriteBlocked());
- visitor_->OnWriteBlocked(this);
- return result.status == WRITE_STATUS_BLOCKED_DATA_BUFFERED;
- } else if (IsWriteError(result.status)) {
- QUIC_LOG_FIRST_N(WARNING, 1)
- << "Received unknown error while sending termination packet to "
- << queued_packet->peer_address().ToString() << ": "
- << strerror(result.error_code);
- }
- return true;
-}
-
-void QuicTimeWaitListManager::SetConnectionIdCleanUpAlarm() {
- QuicTime::Delta next_alarm_interval = QuicTime::Delta::Zero();
- if (!connection_id_map_.empty()) {
- QuicTime oldest_connection_id =
- connection_id_map_.begin()->second.time_added;
- QuicTime now = clock_->ApproximateNow();
- if (now - oldest_connection_id < time_wait_period_) {
- next_alarm_interval = oldest_connection_id + time_wait_period_ - now;
- } else {
- QUIC_LOG(ERROR)
- << "ConnectionId lingered for longer than time_wait_period_";
- }
- } else {
- // No connection_ids added so none will expire before time_wait_period_.
- next_alarm_interval = time_wait_period_;
- }
-
- connection_id_clean_up_alarm_->Update(
- clock_->ApproximateNow() + next_alarm_interval, QuicTime::Delta::Zero());
-}
-
-bool QuicTimeWaitListManager::MaybeExpireOldestConnection(
- QuicTime expiration_time) {
- if (connection_id_map_.empty()) {
- return false;
- }
- auto it = connection_id_map_.begin();
- QuicTime oldest_connection_id_time = it->second.time_added;
- if (oldest_connection_id_time > expiration_time) {
- // Too recent, don't retire.
- return false;
- }
- // This connection_id has lived its age, retire it now.
- QUIC_DLOG(INFO) << "Connection " << it->first
- << " expired from time wait list";
- RemoveConnectionDataFromMap(it);
- if (expiration_time == QuicTime::Infinite()) {
- QUIC_CODE_COUNT(quic_time_wait_list_trim_full);
- } else {
- QUIC_CODE_COUNT(quic_time_wait_list_expire_connections);
- }
- return true;
-}
-
-void QuicTimeWaitListManager::CleanUpOldConnectionIds() {
- QuicTime now = clock_->ApproximateNow();
- QuicTime expiration = now - time_wait_period_;
-
- while (MaybeExpireOldestConnection(expiration)) {
- }
-
- SetConnectionIdCleanUpAlarm();
-}
-
-void QuicTimeWaitListManager::TrimTimeWaitListIfNeeded() {
- const int64_t kMaxConnections =
- GetQuicFlag(FLAGS_quic_time_wait_list_max_connections);
- if (kMaxConnections < 0) {
- return;
- }
- while (!connection_id_map_.empty() &&
- num_connections() >= static_cast<size_t>(kMaxConnections)) {
- MaybeExpireOldestConnection(QuicTime::Infinite());
- }
-}
-
-QuicTimeWaitListManager::ConnectionIdData::ConnectionIdData(
- int num_packets,
- QuicTime time_added,
- TimeWaitAction action,
- TimeWaitConnectionInfo info)
- : num_packets(num_packets),
- time_added(time_added),
- action(action),
- info(std::move(info)) {}
-
-QuicTimeWaitListManager::ConnectionIdData::ConnectionIdData(
- ConnectionIdData&& other) = default;
-
-QuicTimeWaitListManager::ConnectionIdData::~ConnectionIdData() = default;
-
-StatelessResetToken QuicTimeWaitListManager::GetStatelessResetToken(
- QuicConnectionId connection_id) const {
- return QuicUtils::GenerateStatelessResetToken(connection_id);
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_time_wait_list_manager.h b/chromium/net/third_party/quiche/src/quic/core/quic_time_wait_list_manager.h
deleted file mode 100644
index a0844840876..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_time_wait_list_manager.h
+++ /dev/null
@@ -1,343 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Handles packets for connection_ids in time wait state by discarding the
-// packet and sending the peers termination packets with exponential backoff.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_TIME_WAIT_LIST_MANAGER_H_
-#define QUICHE_QUIC_CORE_QUIC_TIME_WAIT_LIST_MANAGER_H_
-
-#include <cstddef>
-#include <memory>
-
-#include "absl/container/flat_hash_map.h"
-#include "quic/core/quic_blocked_writer_interface.h"
-#include "quic/core/quic_connection_id.h"
-#include "quic/core/quic_framer.h"
-#include "quic/core/quic_packet_writer.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_session.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_flags.h"
-#include "common/quiche_linked_hash_map.h"
-
-namespace quic {
-
-namespace test {
-class QuicDispatcherPeer;
-class QuicTimeWaitListManagerPeer;
-} // namespace test
-
-// TimeWaitConnectionInfo comprises information of a connection which is in the
-// time wait list.
-struct QUIC_NO_EXPORT TimeWaitConnectionInfo {
- TimeWaitConnectionInfo(
- bool ietf_quic,
- std::vector<std::unique_ptr<QuicEncryptedPacket>>* termination_packets,
- std::vector<QuicConnectionId> active_connection_ids);
- TimeWaitConnectionInfo(
- bool ietf_quic,
- std::vector<std::unique_ptr<QuicEncryptedPacket>>* termination_packets,
- std::vector<QuicConnectionId> active_connection_ids,
- QuicTime::Delta srtt);
-
- TimeWaitConnectionInfo(const TimeWaitConnectionInfo& other) = delete;
- TimeWaitConnectionInfo(TimeWaitConnectionInfo&& other) = default;
-
- ~TimeWaitConnectionInfo() = default;
-
- bool ietf_quic;
- std::vector<std::unique_ptr<QuicEncryptedPacket>> termination_packets;
- std::vector<QuicConnectionId> active_connection_ids;
- QuicTime::Delta srtt;
-};
-
-// Maintains a list of all connection_ids that have been recently closed. A
-// connection_id lives in this state for time_wait_period_. All packets received
-// for connection_ids in this state are handed over to the
-// QuicTimeWaitListManager by the QuicDispatcher. Decides whether to send a
-// public reset packet, a copy of the previously sent connection close packet,
-// or nothing to the peer which sent a packet with the connection_id in time
-// wait state. After the connection_id expires its time wait period, a new
-// connection/session will be created if a packet is received for this
-// connection_id.
-class QUIC_NO_EXPORT QuicTimeWaitListManager
- : public QuicBlockedWriterInterface {
- public:
- // Specifies what the time wait list manager should do when processing packets
- // of a time wait connection.
- enum TimeWaitAction : uint8_t {
- // Send specified termination packets, error if termination packet is
- // unavailable.
- SEND_TERMINATION_PACKETS,
- // The same as SEND_TERMINATION_PACKETS except that the corresponding
- // termination packets are provided by the connection.
- SEND_CONNECTION_CLOSE_PACKETS,
- // Send stateless reset (public reset for GQUIC).
- SEND_STATELESS_RESET,
-
- DO_NOTHING,
- };
-
- class QUIC_NO_EXPORT Visitor : public QuicSession::Visitor {
- public:
- // Called after the given connection is added to the time-wait list.
- virtual void OnConnectionAddedToTimeWaitList(
- QuicConnectionId connection_id) = 0;
- };
-
- // writer - the entity that writes to the socket. (Owned by the caller)
- // visitor - the entity that manages blocked writers. (Owned by the caller)
- // clock - provide a clock (Owned by the caller)
- // alarm_factory - used to run clean up alarms. (Owned by the caller)
- QuicTimeWaitListManager(QuicPacketWriter* writer,
- Visitor* visitor,
- const QuicClock* clock,
- QuicAlarmFactory* alarm_factory);
- QuicTimeWaitListManager(const QuicTimeWaitListManager&) = delete;
- QuicTimeWaitListManager& operator=(const QuicTimeWaitListManager&) = delete;
- ~QuicTimeWaitListManager() override;
-
- // Adds the connection IDs in info to time wait state for time_wait_period_.
- // If |info|.termination_packets are provided, copies of these packets will be
- // sent when a packet with one of these connection IDs is processed. Any
- // termination packets will be move from |info|.termination_packets and will
- // become owned by the manager. |action| specifies what the time wait list
- // manager should do when processing packets of the connection.
- virtual void AddConnectionIdToTimeWait(TimeWaitAction action,
- TimeWaitConnectionInfo info);
-
- // Returns true if the connection_id is in time wait state, false otherwise.
- // Packets received for this connection_id should not lead to creation of new
- // QuicSessions.
- bool IsConnectionIdInTimeWait(QuicConnectionId connection_id) const;
-
- // Called when a packet is received for a connection_id that is in time wait
- // state. Sends a public reset packet to the peer which sent this
- // connection_id. Sending of the public reset packet is throttled by using
- // exponential back off. QUICHE_DCHECKs for the connection_id to be in time
- // wait state. virtual to override in tests.
- // TODO(fayang): change ProcessPacket and SendPublicReset to take
- // ReceivedPacketInfo.
- virtual void ProcessPacket(
- const QuicSocketAddress& self_address,
- const QuicSocketAddress& peer_address,
- QuicConnectionId connection_id,
- PacketHeaderFormat header_format,
- size_t received_packet_length,
- std::unique_ptr<QuicPerPacketContext> packet_context);
-
- // Called by the dispatcher when the underlying socket becomes writable again,
- // since we might need to send pending public reset packets which we didn't
- // send because the underlying socket was write blocked.
- void OnBlockedWriterCanWrite() override;
-
- bool IsWriterBlocked() const override {
- return writer_ != nullptr && writer_->IsWriteBlocked();
- }
-
- // Used to delete connection_id entries that have outlived their time wait
- // period.
- void CleanUpOldConnectionIds();
-
- // If necessary, trims the oldest connections from the time-wait list until
- // the size is under the configured maximum.
- void TrimTimeWaitListIfNeeded();
-
- // The number of connections on the time-wait list.
- size_t num_connections() const { return connection_id_map_.size(); }
-
- // Sends a version negotiation packet for |server_connection_id| and
- // |client_connection_id| announcing support for |supported_versions| to
- // |peer_address| from |self_address|.
- virtual void SendVersionNegotiationPacket(
- QuicConnectionId server_connection_id,
- QuicConnectionId client_connection_id,
- bool ietf_quic,
- bool use_length_prefix,
- const ParsedQuicVersionVector& supported_versions,
- const QuicSocketAddress& self_address,
- const QuicSocketAddress& peer_address,
- std::unique_ptr<QuicPerPacketContext> packet_context);
-
- // Creates a public reset packet and sends it or queues it to be sent later.
- virtual void SendPublicReset(
- const QuicSocketAddress& self_address,
- const QuicSocketAddress& peer_address,
- QuicConnectionId connection_id,
- bool ietf_quic,
- size_t received_packet_length,
- std::unique_ptr<QuicPerPacketContext> packet_context);
-
- // Called to send |packet|.
- virtual void SendPacket(const QuicSocketAddress& self_address,
- const QuicSocketAddress& peer_address,
- const QuicEncryptedPacket& packet);
-
- // Return a non-owning pointer to the packet writer.
- QuicPacketWriter* writer() { return writer_; }
-
- protected:
- virtual std::unique_ptr<QuicEncryptedPacket> BuildPublicReset(
- const QuicPublicResetPacket& packet);
-
- virtual void GetEndpointId(std::string* /*endpoint_id*/) {}
-
- // Returns a stateless reset token which will be included in the public reset
- // packet.
- virtual StatelessResetToken GetStatelessResetToken(
- QuicConnectionId connection_id) const;
-
- // Internal structure to store pending termination packets.
- class QUIC_NO_EXPORT QueuedPacket {
- public:
- QueuedPacket(const QuicSocketAddress& self_address,
- const QuicSocketAddress& peer_address,
- std::unique_ptr<QuicEncryptedPacket> packet)
- : self_address_(self_address),
- peer_address_(peer_address),
- packet_(std::move(packet)) {}
- QueuedPacket(const QueuedPacket&) = delete;
- QueuedPacket& operator=(const QueuedPacket&) = delete;
-
- const QuicSocketAddress& self_address() const { return self_address_; }
- const QuicSocketAddress& peer_address() const { return peer_address_; }
- QuicEncryptedPacket* packet() { return packet_.get(); }
-
- private:
- // Server address on which a packet was received for a connection_id in
- // time wait state.
- const QuicSocketAddress self_address_;
- // Address of the peer to send this packet to.
- const QuicSocketAddress peer_address_;
- // The pending termination packet that is to be sent to the peer.
- std::unique_ptr<QuicEncryptedPacket> packet_;
- };
-
- // Called right after |packet| is serialized. Either sends the packet and
- // deletes it or makes pending_packets_queue_ the owner of the packet.
- // Subclasses overriding this method should call this class's base
- // implementation at the end of the override.
- // Return true if |packet| is sent, false if it is queued.
- virtual bool SendOrQueuePacket(std::unique_ptr<QueuedPacket> packet,
- const QuicPerPacketContext* packet_context);
-
- const quiche::QuicheCircularDeque<std::unique_ptr<QueuedPacket>>&
- pending_packets_queue() const {
- return pending_packets_queue_;
- }
-
- private:
- friend class test::QuicDispatcherPeer;
- friend class test::QuicTimeWaitListManagerPeer;
-
- // Decides if a packet should be sent for this connection_id based on the
- // number of received packets.
- bool ShouldSendResponse(int received_packet_count);
-
- // Sends the packet out. Returns true if the packet was successfully consumed.
- // If the writer got blocked and did not buffer the packet, we'll need to keep
- // the packet and retry sending. In case of all other errors we drop the
- // packet.
- bool WriteToWire(QueuedPacket* packet);
-
- // Register the alarm server to wake up at appropriate time.
- void SetConnectionIdCleanUpAlarm();
-
- // Removes the oldest connection from the time-wait list if it was added prior
- // to "expiration_time". To unconditionally remove the oldest connection, use
- // a QuicTime::Delta:Infinity(). This function modifies the
- // connection_id_map_. If you plan to call this function in a loop, any
- // iterators that you hold before the call to this function may be invalid
- // afterward. Returns true if the oldest connection was expired. Returns
- // false if the map is empty or the oldest connection has not expired.
- bool MaybeExpireOldestConnection(QuicTime expiration_time);
-
- // Called when a packet is received for a connection in this time wait list.
- virtual void OnPacketReceivedForKnownConnection(
- int /*num_packets*/,
- QuicTime::Delta /*delta*/,
- QuicTime::Delta /*srtt*/) const {}
-
- std::unique_ptr<QuicEncryptedPacket> BuildIetfStatelessResetPacket(
- QuicConnectionId connection_id,
- size_t received_packet_length);
-
- // A map from a recently closed connection_id to the number of packets
- // received after the termination of the connection bound to the
- // connection_id.
- struct QUIC_NO_EXPORT ConnectionIdData {
- ConnectionIdData(int num_packets,
- QuicTime time_added,
- TimeWaitAction action,
- TimeWaitConnectionInfo info);
-
- ConnectionIdData(const ConnectionIdData& other) = delete;
- ConnectionIdData(ConnectionIdData&& other);
-
- ~ConnectionIdData();
-
- int num_packets;
- QuicTime time_added;
- TimeWaitAction action;
- TimeWaitConnectionInfo info;
- };
-
- // QuicheLinkedHashMap allows lookup by ConnectionId
- // and traversal in add order.
- using ConnectionIdMap = quiche::QuicheLinkedHashMap<QuicConnectionId,
- ConnectionIdData,
- QuicConnectionIdHash>;
- // Do not use find/emplace/erase on this map directly. Use
- // FindConnectionIdDataInMap, AddConnectionIdDateToMap,
- // RemoveConnectionDataFromMap instead.
- ConnectionIdMap connection_id_map_;
-
- // TODO(haoyuewang) Consider making connection_id_map_ a map of shared pointer
- // and remove the indirect map.
- // A connection can have multiple unretired ConnectionIds when it is closed.
- // These Ids have the same ConnectionIdData entry in connection_id_map_. To
- // find the entry, look up the cannoical ConnectionId in
- // indirect_connection_id_map_ first, and look up connection_id_map_ with the
- // cannoical ConnectionId.
- absl::flat_hash_map<QuicConnectionId, QuicConnectionId, QuicConnectionIdHash>
- indirect_connection_id_map_;
-
- // Find an iterator for the given connection_id. Returns
- // connection_id_map_.end() if none found.
- ConnectionIdMap::iterator FindConnectionIdDataInMap(
- const QuicConnectionId& connection_id);
- // Inserts a ConnectionIdData entry to connection_id_map_.
- void AddConnectionIdDataToMap(const QuicConnectionId& canonical_connection_id,
- int num_packets,
- TimeWaitAction action,
- TimeWaitConnectionInfo info);
- // Removes a ConnectionIdData entry in connection_id_map_.
- void RemoveConnectionDataFromMap(ConnectionIdMap::iterator it);
-
- // Pending termination packets that need to be sent out to the peer when we
- // are given a chance to write by the dispatcher.
- quiche::QuicheCircularDeque<std::unique_ptr<QueuedPacket>>
- pending_packets_queue_;
-
- // Time period for which connection_ids should remain in time wait state.
- const QuicTime::Delta time_wait_period_;
-
- // Alarm to clean up connection_ids that have out lived their duration in
- // time wait state.
- std::unique_ptr<QuicAlarm> connection_id_clean_up_alarm_;
-
- // Clock to efficiently measure approximate time.
- const QuicClock* clock_;
-
- // Interface that writes given buffer to the socket.
- QuicPacketWriter* writer_;
-
- // Interface that manages blocked writers.
- Visitor* visitor_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_QUIC_TIME_WAIT_LIST_MANAGER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_time_wait_list_manager_test.cc b/chromium/net/third_party/quiche/src/quic/core/quic_time_wait_list_manager_test.cc
deleted file mode 100644
index fcfdbbb2c66..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_time_wait_list_manager_test.cc
+++ /dev/null
@@ -1,788 +0,0 @@
-// Copyright 2013 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 "quic/core/quic_time_wait_list_manager.h"
-
-#include <cerrno>
-#include <memory>
-#include <ostream>
-#include <utility>
-
-#include "quic/core/crypto/crypto_protocol.h"
-#include "quic/core/crypto/null_encrypter.h"
-#include "quic/core/crypto/quic_decrypter.h"
-#include "quic/core/crypto/quic_encrypter.h"
-#include "quic/core/quic_connection_id.h"
-#include "quic/core/quic_data_reader.h"
-#include "quic/core/quic_framer.h"
-#include "quic/core/quic_packet_writer.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_expect_bug.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/mock_quic_session_visitor.h"
-#include "quic/test_tools/quic_test_utils.h"
-#include "quic/test_tools/quic_time_wait_list_manager_peer.h"
-
-using testing::_;
-using testing::Args;
-using testing::Assign;
-using testing::DoAll;
-using testing::Matcher;
-using testing::NiceMock;
-using testing::Return;
-using testing::ReturnPointee;
-using testing::StrictMock;
-using testing::Truly;
-
-namespace quic {
-namespace test {
-namespace {
-
-const size_t kTestPacketSize = 100;
-
-class FramerVisitorCapturingPublicReset : public NoOpFramerVisitor {
- public:
- FramerVisitorCapturingPublicReset(QuicConnectionId connection_id)
- : connection_id_(connection_id) {}
- ~FramerVisitorCapturingPublicReset() override = default;
-
- void OnPublicResetPacket(const QuicPublicResetPacket& public_reset) override {
- public_reset_packet_ = public_reset;
- }
-
- const QuicPublicResetPacket public_reset_packet() {
- return public_reset_packet_;
- }
-
- bool IsValidStatelessResetToken(
- const StatelessResetToken& token) const override {
- return token == QuicUtils::GenerateStatelessResetToken(connection_id_);
- }
-
- void OnAuthenticatedIetfStatelessResetPacket(
- const QuicIetfStatelessResetPacket& packet) override {
- stateless_reset_packet_ = packet;
- }
-
- const QuicIetfStatelessResetPacket stateless_reset_packet() {
- return stateless_reset_packet_;
- }
-
- private:
- QuicPublicResetPacket public_reset_packet_;
- QuicIetfStatelessResetPacket stateless_reset_packet_;
- QuicConnectionId connection_id_;
-};
-
-class MockAlarmFactory;
-class MockAlarm : public QuicAlarm {
- public:
- explicit MockAlarm(QuicArenaScopedPtr<Delegate> delegate,
- int alarm_index,
- MockAlarmFactory* factory)
- : QuicAlarm(std::move(delegate)),
- alarm_index_(alarm_index),
- factory_(factory) {}
- virtual ~MockAlarm() {}
-
- void SetImpl() override;
- void CancelImpl() override;
-
- private:
- int alarm_index_;
- MockAlarmFactory* factory_;
-};
-
-class MockAlarmFactory : public QuicAlarmFactory {
- public:
- ~MockAlarmFactory() override {}
-
- // Creates a new platform-specific alarm which will be configured to notify
- // |delegate| when the alarm fires. Returns an alarm allocated on the heap.
- // Caller takes ownership of the new alarm, which will not yet be "set" to
- // fire.
- QuicAlarm* CreateAlarm(QuicAlarm::Delegate* delegate) override {
- return new MockAlarm(QuicArenaScopedPtr<QuicAlarm::Delegate>(delegate),
- alarm_index_++, this);
- }
- QuicArenaScopedPtr<QuicAlarm> CreateAlarm(
- QuicArenaScopedPtr<QuicAlarm::Delegate> delegate,
- QuicConnectionArena* arena) override {
- if (arena != nullptr) {
- return arena->New<MockAlarm>(std::move(delegate), alarm_index_++, this);
- }
- return QuicArenaScopedPtr<MockAlarm>(
- new MockAlarm(std::move(delegate), alarm_index_++, this));
- }
- MOCK_METHOD(void, OnAlarmSet, (int, QuicTime), ());
- MOCK_METHOD(void, OnAlarmCancelled, (int), ());
-
- private:
- int alarm_index_ = 0;
-};
-
-void MockAlarm::SetImpl() {
- factory_->OnAlarmSet(alarm_index_, deadline());
-}
-
-void MockAlarm::CancelImpl() {
- factory_->OnAlarmCancelled(alarm_index_);
-}
-
-class QuicTimeWaitListManagerTest : public QuicTest {
- protected:
- QuicTimeWaitListManagerTest()
- : time_wait_list_manager_(&writer_, &visitor_, &clock_, &alarm_factory_),
- connection_id_(TestConnectionId(45)),
- peer_address_(TestPeerIPAddress(), kTestPort),
- writer_is_blocked_(false) {}
-
- ~QuicTimeWaitListManagerTest() override = default;
-
- void SetUp() override {
- EXPECT_CALL(writer_, IsWriteBlocked())
- .WillRepeatedly(ReturnPointee(&writer_is_blocked_));
- }
-
- void AddConnectionId(QuicConnectionId connection_id,
- QuicTimeWaitListManager::TimeWaitAction action) {
- AddConnectionId(connection_id, QuicVersionMax(), action, nullptr);
- }
-
- void AddStatelessConnectionId(QuicConnectionId connection_id) {
- std::vector<std::unique_ptr<QuicEncryptedPacket>> termination_packets;
- termination_packets.push_back(std::unique_ptr<QuicEncryptedPacket>(
- new QuicEncryptedPacket(nullptr, 0, false)));
- time_wait_list_manager_.AddConnectionIdToTimeWait(
- QuicTimeWaitListManager::SEND_TERMINATION_PACKETS,
- TimeWaitConnectionInfo(false, &termination_packets, {connection_id}));
- }
-
- void AddConnectionId(
- QuicConnectionId connection_id,
- ParsedQuicVersion version,
- QuicTimeWaitListManager::TimeWaitAction action,
- std::vector<std::unique_ptr<QuicEncryptedPacket>>* packets) {
- time_wait_list_manager_.AddConnectionIdToTimeWait(
- action, TimeWaitConnectionInfo(version.HasIetfInvariantHeader(),
- packets, {connection_id}));
- }
-
- bool IsConnectionIdInTimeWait(QuicConnectionId connection_id) {
- return time_wait_list_manager_.IsConnectionIdInTimeWait(connection_id);
- }
-
- void ProcessPacket(QuicConnectionId connection_id) {
- time_wait_list_manager_.ProcessPacket(
- self_address_, peer_address_, connection_id, GOOGLE_QUIC_PACKET,
- kTestPacketSize, std::make_unique<QuicPerPacketContext>());
- }
-
- QuicEncryptedPacket* ConstructEncryptedPacket(
- QuicConnectionId destination_connection_id,
- QuicConnectionId source_connection_id,
- uint64_t packet_number) {
- return quic::test::ConstructEncryptedPacket(destination_connection_id,
- source_connection_id, false,
- false, packet_number, "data");
- }
-
- MockClock clock_;
- MockAlarmFactory alarm_factory_;
- NiceMock<MockPacketWriter> writer_;
- StrictMock<MockQuicSessionVisitor> visitor_;
- QuicTimeWaitListManager time_wait_list_manager_;
- QuicConnectionId connection_id_;
- QuicSocketAddress self_address_;
- QuicSocketAddress peer_address_;
- bool writer_is_blocked_;
-};
-
-bool ValidPublicResetPacketPredicate(
- QuicConnectionId expected_connection_id,
- const std::tuple<const char*, int>& packet_buffer) {
- FramerVisitorCapturingPublicReset visitor(expected_connection_id);
- QuicFramer framer(AllSupportedVersions(), QuicTime::Zero(),
- Perspective::IS_CLIENT, kQuicDefaultConnectionIdLength);
- framer.set_visitor(&visitor);
- QuicEncryptedPacket encrypted(std::get<0>(packet_buffer),
- std::get<1>(packet_buffer));
- framer.ProcessPacket(encrypted);
- QuicPublicResetPacket packet = visitor.public_reset_packet();
- bool public_reset_is_valid =
- expected_connection_id == packet.connection_id &&
- TestPeerIPAddress() == packet.client_address.host() &&
- kTestPort == packet.client_address.port();
-
- QuicIetfStatelessResetPacket stateless_reset =
- visitor.stateless_reset_packet();
-
- StatelessResetToken expected_stateless_reset_token =
- QuicUtils::GenerateStatelessResetToken(expected_connection_id);
-
- bool stateless_reset_is_valid =
- stateless_reset.stateless_reset_token == expected_stateless_reset_token;
-
- return public_reset_is_valid || stateless_reset_is_valid;
-}
-
-Matcher<const std::tuple<const char*, int>> PublicResetPacketEq(
- QuicConnectionId connection_id) {
- return Truly(
- [connection_id](const std::tuple<const char*, int> packet_buffer) {
- return ValidPublicResetPacketPredicate(connection_id, packet_buffer);
- });
-}
-
-TEST_F(QuicTimeWaitListManagerTest, CheckConnectionIdInTimeWait) {
- EXPECT_FALSE(IsConnectionIdInTimeWait(connection_id_));
- EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id_));
- AddConnectionId(connection_id_, QuicTimeWaitListManager::DO_NOTHING);
- EXPECT_EQ(1u, time_wait_list_manager_.num_connections());
- EXPECT_TRUE(IsConnectionIdInTimeWait(connection_id_));
-}
-
-TEST_F(QuicTimeWaitListManagerTest, CheckStatelessConnectionIdInTimeWait) {
- EXPECT_FALSE(IsConnectionIdInTimeWait(connection_id_));
- EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id_));
- AddStatelessConnectionId(connection_id_);
- EXPECT_EQ(1u, time_wait_list_manager_.num_connections());
- EXPECT_TRUE(IsConnectionIdInTimeWait(connection_id_));
-}
-
-TEST_F(QuicTimeWaitListManagerTest, SendVersionNegotiationPacket) {
- std::unique_ptr<QuicEncryptedPacket> packet(
- QuicFramer::BuildVersionNegotiationPacket(
- connection_id_, EmptyQuicConnectionId(), /*ietf_quic=*/false,
- /*use_length_prefix=*/false, AllSupportedVersions()));
- EXPECT_CALL(writer_, WritePacket(_, packet->length(), self_address_.host(),
- peer_address_, _))
- .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 1)));
-
- time_wait_list_manager_.SendVersionNegotiationPacket(
- connection_id_, EmptyQuicConnectionId(), /*ietf_quic=*/false,
- /*use_length_prefix=*/false, AllSupportedVersions(), self_address_,
- peer_address_, std::make_unique<QuicPerPacketContext>());
- EXPECT_EQ(0u, time_wait_list_manager_.num_connections());
-}
-
-TEST_F(QuicTimeWaitListManagerTest,
- SendIetfVersionNegotiationPacketWithoutLengthPrefix) {
- std::unique_ptr<QuicEncryptedPacket> packet(
- QuicFramer::BuildVersionNegotiationPacket(
- connection_id_, EmptyQuicConnectionId(), /*ietf_quic=*/true,
- /*use_length_prefix=*/false, AllSupportedVersions()));
- EXPECT_CALL(writer_, WritePacket(_, packet->length(), self_address_.host(),
- peer_address_, _))
- .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 1)));
-
- time_wait_list_manager_.SendVersionNegotiationPacket(
- connection_id_, EmptyQuicConnectionId(), /*ietf_quic=*/true,
- /*use_length_prefix=*/false, AllSupportedVersions(), self_address_,
- peer_address_, std::make_unique<QuicPerPacketContext>());
- EXPECT_EQ(0u, time_wait_list_manager_.num_connections());
-}
-
-TEST_F(QuicTimeWaitListManagerTest, SendIetfVersionNegotiationPacket) {
- std::unique_ptr<QuicEncryptedPacket> packet(
- QuicFramer::BuildVersionNegotiationPacket(
- connection_id_, EmptyQuicConnectionId(), /*ietf_quic=*/true,
- /*use_length_prefix=*/true, AllSupportedVersions()));
- EXPECT_CALL(writer_, WritePacket(_, packet->length(), self_address_.host(),
- peer_address_, _))
- .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 1)));
-
- time_wait_list_manager_.SendVersionNegotiationPacket(
- connection_id_, EmptyQuicConnectionId(), /*ietf_quic=*/true,
- /*use_length_prefix=*/true, AllSupportedVersions(), self_address_,
- peer_address_, std::make_unique<QuicPerPacketContext>());
- EXPECT_EQ(0u, time_wait_list_manager_.num_connections());
-}
-
-TEST_F(QuicTimeWaitListManagerTest,
- SendIetfVersionNegotiationPacketWithClientConnectionId) {
- std::unique_ptr<QuicEncryptedPacket> packet(
- QuicFramer::BuildVersionNegotiationPacket(
- connection_id_, TestConnectionId(0x33), /*ietf_quic=*/true,
- /*use_length_prefix=*/true, AllSupportedVersions()));
- EXPECT_CALL(writer_, WritePacket(_, packet->length(), self_address_.host(),
- peer_address_, _))
- .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 1)));
-
- time_wait_list_manager_.SendVersionNegotiationPacket(
- connection_id_, TestConnectionId(0x33), /*ietf_quic=*/true,
- /*use_length_prefix=*/true, AllSupportedVersions(), self_address_,
- peer_address_, std::make_unique<QuicPerPacketContext>());
- EXPECT_EQ(0u, time_wait_list_manager_.num_connections());
-}
-
-TEST_F(QuicTimeWaitListManagerTest, SendConnectionClose) {
- const size_t kConnectionCloseLength = 100;
- EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id_));
- std::vector<std::unique_ptr<QuicEncryptedPacket>> termination_packets;
- termination_packets.push_back(
- std::unique_ptr<QuicEncryptedPacket>(new QuicEncryptedPacket(
- new char[kConnectionCloseLength], kConnectionCloseLength, true)));
- AddConnectionId(connection_id_, QuicVersionMax(),
- QuicTimeWaitListManager::SEND_CONNECTION_CLOSE_PACKETS,
- &termination_packets);
- EXPECT_CALL(writer_, WritePacket(_, kConnectionCloseLength,
- self_address_.host(), peer_address_, _))
- .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 1)));
-
- ProcessPacket(connection_id_);
-}
-
-TEST_F(QuicTimeWaitListManagerTest, SendTwoConnectionCloses) {
- const size_t kConnectionCloseLength = 100;
- EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id_));
- std::vector<std::unique_ptr<QuicEncryptedPacket>> termination_packets;
- termination_packets.push_back(
- std::unique_ptr<QuicEncryptedPacket>(new QuicEncryptedPacket(
- new char[kConnectionCloseLength], kConnectionCloseLength, true)));
- termination_packets.push_back(
- std::unique_ptr<QuicEncryptedPacket>(new QuicEncryptedPacket(
- new char[kConnectionCloseLength], kConnectionCloseLength, true)));
- AddConnectionId(connection_id_, QuicVersionMax(),
- QuicTimeWaitListManager::SEND_CONNECTION_CLOSE_PACKETS,
- &termination_packets);
- EXPECT_CALL(writer_, WritePacket(_, kConnectionCloseLength,
- self_address_.host(), peer_address_, _))
- .Times(2)
- .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 1)));
-
- ProcessPacket(connection_id_);
-}
-
-TEST_F(QuicTimeWaitListManagerTest, SendPublicReset) {
- EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id_));
- AddConnectionId(connection_id_,
- QuicTimeWaitListManager::SEND_STATELESS_RESET);
- EXPECT_CALL(writer_,
- WritePacket(_, _, self_address_.host(), peer_address_, _))
- .With(Args<0, 1>(PublicResetPacketEq(connection_id_)))
- .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 0)));
-
- ProcessPacket(connection_id_);
-}
-
-TEST_F(QuicTimeWaitListManagerTest, SendPublicResetWithExponentialBackOff) {
- EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id_));
- AddConnectionId(connection_id_,
- QuicTimeWaitListManager::SEND_STATELESS_RESET);
- EXPECT_EQ(1u, time_wait_list_manager_.num_connections());
- for (int packet_number = 1; packet_number < 101; ++packet_number) {
- if ((packet_number & (packet_number - 1)) == 0) {
- EXPECT_CALL(writer_, WritePacket(_, _, _, _, _))
- .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 1)));
- }
- ProcessPacket(connection_id_);
- // Send public reset with exponential back off.
- if ((packet_number & (packet_number - 1)) == 0) {
- EXPECT_TRUE(QuicTimeWaitListManagerPeer::ShouldSendResponse(
- &time_wait_list_manager_, packet_number));
- } else {
- EXPECT_FALSE(QuicTimeWaitListManagerPeer::ShouldSendResponse(
- &time_wait_list_manager_, packet_number));
- }
- }
-}
-
-TEST_F(QuicTimeWaitListManagerTest, NoPublicResetForStatelessConnections) {
- EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id_));
- AddStatelessConnectionId(connection_id_);
-
- EXPECT_CALL(writer_,
- WritePacket(_, _, self_address_.host(), peer_address_, _))
- .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 1)));
-
- ProcessPacket(connection_id_);
-}
-
-TEST_F(QuicTimeWaitListManagerTest, CleanUpOldConnectionIds) {
- const size_t kConnectionIdCount = 100;
- const size_t kOldConnectionIdCount = 31;
-
- // Add connection_ids such that their expiry time is time_wait_period_.
- for (uint64_t conn_id = 1; conn_id <= kOldConnectionIdCount; ++conn_id) {
- QuicConnectionId connection_id = TestConnectionId(conn_id);
- EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id));
- AddConnectionId(connection_id, QuicTimeWaitListManager::DO_NOTHING);
- }
- EXPECT_EQ(kOldConnectionIdCount, time_wait_list_manager_.num_connections());
-
- // Add remaining connection_ids such that their add time is
- // 2 * time_wait_period_.
- const QuicTime::Delta time_wait_period =
- QuicTimeWaitListManagerPeer::time_wait_period(&time_wait_list_manager_);
- clock_.AdvanceTime(time_wait_period);
- for (uint64_t conn_id = kOldConnectionIdCount + 1;
- conn_id <= kConnectionIdCount; ++conn_id) {
- QuicConnectionId connection_id = TestConnectionId(conn_id);
- EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id));
- AddConnectionId(connection_id, QuicTimeWaitListManager::DO_NOTHING);
- }
- EXPECT_EQ(kConnectionIdCount, time_wait_list_manager_.num_connections());
-
- QuicTime::Delta offset = QuicTime::Delta::FromMicroseconds(39);
- // Now set the current time as time_wait_period + offset usecs.
- clock_.AdvanceTime(offset);
- // After all the old connection_ids are cleaned up, check the next alarm
- // interval.
- QuicTime next_alarm_time = clock_.Now() + time_wait_period - offset;
- EXPECT_CALL(alarm_factory_, OnAlarmSet(_, next_alarm_time));
-
- time_wait_list_manager_.CleanUpOldConnectionIds();
- for (uint64_t conn_id = 1; conn_id <= kConnectionIdCount; ++conn_id) {
- QuicConnectionId connection_id = TestConnectionId(conn_id);
- EXPECT_EQ(conn_id > kOldConnectionIdCount,
- IsConnectionIdInTimeWait(connection_id))
- << "kOldConnectionIdCount: " << kOldConnectionIdCount
- << " connection_id: " << connection_id;
- }
- EXPECT_EQ(kConnectionIdCount - kOldConnectionIdCount,
- time_wait_list_manager_.num_connections());
-}
-
-TEST_F(QuicTimeWaitListManagerTest,
- CleanUpOldConnectionIdsForMultipleConnectionIdsPerConnection) {
- connection_id_ = TestConnectionId(7);
- const size_t kConnectionCloseLength = 100;
- EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id_));
- EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(TestConnectionId(8)));
- std::vector<std::unique_ptr<QuicEncryptedPacket>> termination_packets;
- termination_packets.push_back(
- std::unique_ptr<QuicEncryptedPacket>(new QuicEncryptedPacket(
- new char[kConnectionCloseLength], kConnectionCloseLength, true)));
-
- // Add a CONNECTION_CLOSE termination packet.
- std::vector<QuicConnectionId> active_connection_ids{connection_id_,
- TestConnectionId(8)};
- time_wait_list_manager_.AddConnectionIdToTimeWait(
- QuicTimeWaitListManager::SEND_CONNECTION_CLOSE_PACKETS,
- TimeWaitConnectionInfo(/*ietf_quic=*/true, &termination_packets,
- active_connection_ids, QuicTime::Delta::Zero()));
-
- EXPECT_TRUE(
- time_wait_list_manager_.IsConnectionIdInTimeWait(TestConnectionId(7)));
- EXPECT_TRUE(
- time_wait_list_manager_.IsConnectionIdInTimeWait(TestConnectionId(8)));
-
- // Remove these IDs.
- const QuicTime::Delta time_wait_period =
- QuicTimeWaitListManagerPeer::time_wait_period(&time_wait_list_manager_);
- clock_.AdvanceTime(time_wait_period);
- time_wait_list_manager_.CleanUpOldConnectionIds();
-
- EXPECT_FALSE(
- time_wait_list_manager_.IsConnectionIdInTimeWait(TestConnectionId(7)));
- EXPECT_FALSE(
- time_wait_list_manager_.IsConnectionIdInTimeWait(TestConnectionId(8)));
-}
-
-TEST_F(QuicTimeWaitListManagerTest, SendQueuedPackets) {
- QuicConnectionId connection_id = TestConnectionId(1);
- EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id));
- AddConnectionId(connection_id, QuicTimeWaitListManager::SEND_STATELESS_RESET);
- std::unique_ptr<QuicEncryptedPacket> packet(ConstructEncryptedPacket(
- connection_id, EmptyQuicConnectionId(), /*packet_number=*/234));
- // Let first write through.
- EXPECT_CALL(writer_,
- WritePacket(_, _, self_address_.host(), peer_address_, _))
- .With(Args<0, 1>(PublicResetPacketEq(connection_id)))
- .WillOnce(Return(WriteResult(WRITE_STATUS_OK, packet->length())));
- ProcessPacket(connection_id);
-
- // write block for the next packet.
- EXPECT_CALL(writer_,
- WritePacket(_, _, self_address_.host(), peer_address_, _))
- .With(Args<0, 1>(PublicResetPacketEq(connection_id)))
- .WillOnce(DoAll(Assign(&writer_is_blocked_, true),
- Return(WriteResult(WRITE_STATUS_BLOCKED, EAGAIN))));
- EXPECT_CALL(visitor_, OnWriteBlocked(&time_wait_list_manager_));
- ProcessPacket(connection_id);
- // 3rd packet. No public reset should be sent;
- ProcessPacket(connection_id);
-
- // write packet should not be called since we are write blocked but the
- // should be queued.
- QuicConnectionId other_connection_id = TestConnectionId(2);
- EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(other_connection_id));
- AddConnectionId(other_connection_id,
- QuicTimeWaitListManager::SEND_STATELESS_RESET);
- std::unique_ptr<QuicEncryptedPacket> other_packet(ConstructEncryptedPacket(
- other_connection_id, EmptyQuicConnectionId(), /*packet_number=*/23423));
- EXPECT_CALL(writer_, WritePacket(_, _, _, _, _)).Times(0);
- EXPECT_CALL(visitor_, OnWriteBlocked(&time_wait_list_manager_));
- ProcessPacket(other_connection_id);
- EXPECT_EQ(2u, time_wait_list_manager_.num_connections());
-
- // Now expect all the write blocked public reset packets to be sent again.
- writer_is_blocked_ = false;
- EXPECT_CALL(writer_,
- WritePacket(_, _, self_address_.host(), peer_address_, _))
- .With(Args<0, 1>(PublicResetPacketEq(connection_id)))
- .WillOnce(Return(WriteResult(WRITE_STATUS_OK, packet->length())));
- EXPECT_CALL(writer_,
- WritePacket(_, _, self_address_.host(), peer_address_, _))
- .With(Args<0, 1>(PublicResetPacketEq(other_connection_id)))
- .WillOnce(Return(WriteResult(WRITE_STATUS_OK, packet->length())));
- time_wait_list_manager_.OnBlockedWriterCanWrite();
-}
-
-TEST_F(QuicTimeWaitListManagerTest, AddConnectionIdTwice) {
- // Add connection_ids such that their expiry time is time_wait_period_.
- EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id_));
- AddConnectionId(connection_id_, QuicTimeWaitListManager::DO_NOTHING);
- EXPECT_TRUE(IsConnectionIdInTimeWait(connection_id_));
- const size_t kConnectionCloseLength = 100;
- std::vector<std::unique_ptr<QuicEncryptedPacket>> termination_packets;
- termination_packets.push_back(
- std::unique_ptr<QuicEncryptedPacket>(new QuicEncryptedPacket(
- new char[kConnectionCloseLength], kConnectionCloseLength, true)));
- AddConnectionId(connection_id_, QuicVersionMax(),
- QuicTimeWaitListManager::SEND_TERMINATION_PACKETS,
- &termination_packets);
- EXPECT_TRUE(IsConnectionIdInTimeWait(connection_id_));
- EXPECT_EQ(1u, time_wait_list_manager_.num_connections());
-
- EXPECT_CALL(writer_, WritePacket(_, kConnectionCloseLength,
- self_address_.host(), peer_address_, _))
- .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 1)));
-
- ProcessPacket(connection_id_);
-
- const QuicTime::Delta time_wait_period =
- QuicTimeWaitListManagerPeer::time_wait_period(&time_wait_list_manager_);
-
- QuicTime::Delta offset = QuicTime::Delta::FromMicroseconds(39);
- clock_.AdvanceTime(offset + time_wait_period);
- // Now set the current time as time_wait_period + offset usecs.
- QuicTime next_alarm_time = clock_.Now() + time_wait_period;
- EXPECT_CALL(alarm_factory_, OnAlarmSet(_, next_alarm_time));
-
- time_wait_list_manager_.CleanUpOldConnectionIds();
- EXPECT_FALSE(IsConnectionIdInTimeWait(connection_id_));
- EXPECT_EQ(0u, time_wait_list_manager_.num_connections());
-}
-
-TEST_F(QuicTimeWaitListManagerTest, ConnectionIdsOrderedByTime) {
- // Simple randomization: the values of connection_ids are randomly swapped.
- // If the container is broken, the test will be 50% flaky.
- const uint64_t conn_id1 = QuicRandom::GetInstance()->RandUint64() % 2;
- const QuicConnectionId connection_id1 = TestConnectionId(conn_id1);
- const QuicConnectionId connection_id2 = TestConnectionId(1 - conn_id1);
-
- // 1 will hash lower than 2, but we add it later. They should come out in the
- // add order, not hash order.
- EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id1));
- AddConnectionId(connection_id1, QuicTimeWaitListManager::DO_NOTHING);
- clock_.AdvanceTime(QuicTime::Delta::FromMicroseconds(10));
- EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id2));
- AddConnectionId(connection_id2, QuicTimeWaitListManager::DO_NOTHING);
- EXPECT_EQ(2u, time_wait_list_manager_.num_connections());
-
- const QuicTime::Delta time_wait_period =
- QuicTimeWaitListManagerPeer::time_wait_period(&time_wait_list_manager_);
- clock_.AdvanceTime(time_wait_period - QuicTime::Delta::FromMicroseconds(9));
-
- EXPECT_CALL(alarm_factory_, OnAlarmSet(_, _));
-
- time_wait_list_manager_.CleanUpOldConnectionIds();
- EXPECT_FALSE(IsConnectionIdInTimeWait(connection_id1));
- EXPECT_TRUE(IsConnectionIdInTimeWait(connection_id2));
- EXPECT_EQ(1u, time_wait_list_manager_.num_connections());
-}
-
-TEST_F(QuicTimeWaitListManagerTest, MaxConnectionsTest) {
- // Basically, shut off time-based eviction.
- SetQuicFlag(FLAGS_quic_time_wait_list_seconds, 10000000000);
- SetQuicFlag(FLAGS_quic_time_wait_list_max_connections, 5);
-
- uint64_t current_conn_id = 0;
- const int64_t kMaxConnections =
- GetQuicFlag(FLAGS_quic_time_wait_list_max_connections);
- // Add exactly the maximum number of connections
- for (int64_t i = 0; i < kMaxConnections; ++i) {
- ++current_conn_id;
- QuicConnectionId current_connection_id = TestConnectionId(current_conn_id);
- EXPECT_FALSE(IsConnectionIdInTimeWait(current_connection_id));
- EXPECT_CALL(visitor_,
- OnConnectionAddedToTimeWaitList(current_connection_id));
- AddConnectionId(current_connection_id, QuicTimeWaitListManager::DO_NOTHING);
- EXPECT_EQ(current_conn_id, time_wait_list_manager_.num_connections());
- EXPECT_TRUE(IsConnectionIdInTimeWait(current_connection_id));
- }
-
- // Now keep adding. Since we're already at the max, every new connection-id
- // will evict the oldest one.
- for (int64_t i = 0; i < kMaxConnections; ++i) {
- ++current_conn_id;
- QuicConnectionId current_connection_id = TestConnectionId(current_conn_id);
- const QuicConnectionId id_to_evict =
- TestConnectionId(current_conn_id - kMaxConnections);
- EXPECT_TRUE(IsConnectionIdInTimeWait(id_to_evict));
- EXPECT_FALSE(IsConnectionIdInTimeWait(current_connection_id));
- EXPECT_CALL(visitor_,
- OnConnectionAddedToTimeWaitList(current_connection_id));
- AddConnectionId(current_connection_id, QuicTimeWaitListManager::DO_NOTHING);
- EXPECT_EQ(static_cast<size_t>(kMaxConnections),
- time_wait_list_manager_.num_connections());
- EXPECT_FALSE(IsConnectionIdInTimeWait(id_to_evict));
- EXPECT_TRUE(IsConnectionIdInTimeWait(current_connection_id));
- }
-}
-
-TEST_F(QuicTimeWaitListManagerTest, ZeroMaxConnections) {
- // Basically, shut off time-based eviction.
- SetQuicFlag(FLAGS_quic_time_wait_list_seconds, 10000000000);
- // Keep time wait list empty.
- SetQuicFlag(FLAGS_quic_time_wait_list_max_connections, 0);
-
- uint64_t current_conn_id = 0;
- // Add exactly the maximum number of connections
- for (int64_t i = 0; i < 10; ++i) {
- ++current_conn_id;
- QuicConnectionId current_connection_id = TestConnectionId(current_conn_id);
- EXPECT_FALSE(IsConnectionIdInTimeWait(current_connection_id));
- EXPECT_CALL(visitor_,
- OnConnectionAddedToTimeWaitList(current_connection_id));
- AddConnectionId(current_connection_id, QuicTimeWaitListManager::DO_NOTHING);
- // Verify time wait list always has 1 connection.
- EXPECT_EQ(1u, time_wait_list_manager_.num_connections());
- EXPECT_TRUE(IsConnectionIdInTimeWait(current_connection_id));
- }
-}
-
-// Regression test for b/116200989.
-TEST_F(QuicTimeWaitListManagerTest,
- SendStatelessResetInResponseToShortHeaders) {
- // This test mimics a scenario where an ENCRYPTION_INITIAL connection close is
- // added as termination packet for an IETF connection ID. However, a short
- // header packet is received later.
- const size_t kConnectionCloseLength = 100;
- EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id_));
- std::vector<std::unique_ptr<QuicEncryptedPacket>> termination_packets;
- termination_packets.push_back(
- std::unique_ptr<QuicEncryptedPacket>(new QuicEncryptedPacket(
- new char[kConnectionCloseLength], kConnectionCloseLength, true)));
- time_wait_list_manager_.AddConnectionIdToTimeWait(
- QuicTimeWaitListManager::SEND_TERMINATION_PACKETS,
- TimeWaitConnectionInfo(/*ietf_quic=*/true, &termination_packets,
- {connection_id_}));
-
- // Termination packet is not encrypted, instead, send stateless reset.
- EXPECT_CALL(writer_,
- WritePacket(_, _, self_address_.host(), peer_address_, _))
- .With(Args<0, 1>(PublicResetPacketEq(connection_id_)))
- .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 0)));
- // Processes IETF short header packet.
- time_wait_list_manager_.ProcessPacket(
- self_address_, peer_address_, connection_id_,
- IETF_QUIC_SHORT_HEADER_PACKET, kTestPacketSize,
- std::make_unique<QuicPerPacketContext>());
-}
-
-TEST_F(QuicTimeWaitListManagerTest,
- SendConnectionClosePacketsInResponseToShortHeaders) {
- const size_t kConnectionCloseLength = 100;
- EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id_));
- std::vector<std::unique_ptr<QuicEncryptedPacket>> termination_packets;
- termination_packets.push_back(
- std::unique_ptr<QuicEncryptedPacket>(new QuicEncryptedPacket(
- new char[kConnectionCloseLength], kConnectionCloseLength, true)));
- // Add a CONNECTION_CLOSE termination packet.
- time_wait_list_manager_.AddConnectionIdToTimeWait(
- QuicTimeWaitListManager::SEND_CONNECTION_CLOSE_PACKETS,
- TimeWaitConnectionInfo(/*ietf_quic=*/true, &termination_packets,
- {connection_id_}));
- EXPECT_CALL(writer_, WritePacket(_, kConnectionCloseLength,
- self_address_.host(), peer_address_, _))
- .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 1)));
-
- // Processes IETF short header packet.
- time_wait_list_manager_.ProcessPacket(
- self_address_, peer_address_, connection_id_,
- IETF_QUIC_SHORT_HEADER_PACKET, kTestPacketSize,
- std::make_unique<QuicPerPacketContext>());
-}
-
-TEST_F(QuicTimeWaitListManagerTest,
- SendConnectionClosePacketsForMultipleConnectionIds) {
- connection_id_ = TestConnectionId(7);
- const size_t kConnectionCloseLength = 100;
- EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id_));
- EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(TestConnectionId(8)));
- std::vector<std::unique_ptr<QuicEncryptedPacket>> termination_packets;
- termination_packets.push_back(
- std::unique_ptr<QuicEncryptedPacket>(new QuicEncryptedPacket(
- new char[kConnectionCloseLength], kConnectionCloseLength, true)));
-
- // Add a CONNECTION_CLOSE termination packet.
- std::vector<QuicConnectionId> active_connection_ids{connection_id_,
- TestConnectionId(8)};
- time_wait_list_manager_.AddConnectionIdToTimeWait(
- QuicTimeWaitListManager::SEND_CONNECTION_CLOSE_PACKETS,
- TimeWaitConnectionInfo(/*ietf_quic=*/true, &termination_packets,
- active_connection_ids, QuicTime::Delta::Zero()));
-
- EXPECT_CALL(writer_, WritePacket(_, kConnectionCloseLength,
- self_address_.host(), peer_address_, _))
- .Times(2)
- .WillRepeatedly(Return(WriteResult(WRITE_STATUS_OK, 1)));
- // Processes IETF short header packet.
- for (auto const& cid : active_connection_ids) {
- time_wait_list_manager_.ProcessPacket(
- self_address_, peer_address_, cid, IETF_QUIC_SHORT_HEADER_PACKET,
- kTestPacketSize, std::make_unique<QuicPerPacketContext>());
- }
-}
-
-// Regression test for b/184053898.
-TEST_F(QuicTimeWaitListManagerTest, DonotCrashOnNullStatelessReset) {
- // Received a packet with length <
- // QuicFramer::GetMinStatelessResetPacketLength(), and this will result in a
- // null stateless reset.
- time_wait_list_manager_.SendPublicReset(
- self_address_, peer_address_, TestConnectionId(1),
- /*ietf_quic=*/true,
- /*received_packet_length=*/
- QuicFramer::GetMinStatelessResetPacketLength() - 1,
- /*packet_context=*/nullptr);
-}
-
-TEST_F(QuicTimeWaitListManagerTest, SendOrQueueNullPacket) {
- QuicTimeWaitListManagerPeer::SendOrQueuePacket(&time_wait_list_manager_,
- nullptr, nullptr);
-}
-
-TEST_F(QuicTimeWaitListManagerTest, TooManyPendingPackets) {
- SetQuicFlag(FLAGS_quic_time_wait_list_max_pending_packets, 5);
- const size_t kNumOfUnProcessablePackets = 2048;
- EXPECT_CALL(visitor_, OnWriteBlocked(&time_wait_list_manager_))
- .Times(testing::AnyNumber());
- // Write block for the next packets.
- EXPECT_CALL(writer_,
- WritePacket(_, _, self_address_.host(), peer_address_, _))
- .With(Args<0, 1>(PublicResetPacketEq(TestConnectionId(1))))
- .WillOnce(DoAll(Assign(&writer_is_blocked_, true),
- Return(WriteResult(WRITE_STATUS_BLOCKED, EAGAIN))));
- for (size_t i = 0; i < kNumOfUnProcessablePackets; ++i) {
- time_wait_list_manager_.SendPublicReset(
- self_address_, peer_address_, TestConnectionId(1),
- /*ietf_quic=*/true,
- /*received_packet_length=*/
- QuicFramer::GetMinStatelessResetPacketLength() + 1,
- /*packet_context=*/nullptr);
- }
- // Verify pending packet queue size is limited.
- EXPECT_EQ(5u, QuicTimeWaitListManagerPeer::PendingPacketsQueueSize(
- &time_wait_list_manager_));
-}
-
-} // namespace
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_trace_visitor.cc b/chromium/net/third_party/quiche/src/quic/core/quic_trace_visitor.cc
deleted file mode 100644
index f603f583e2d..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_trace_visitor.cc
+++ /dev/null
@@ -1,350 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_trace_visitor.h"
-
-#include <string>
-
-#include "quic/core/quic_types.h"
-#include "common/quiche_endian.h"
-
-namespace quic {
-
-quic_trace::EncryptionLevel EncryptionLevelToProto(EncryptionLevel level) {
- switch (level) {
- case ENCRYPTION_INITIAL:
- return quic_trace::ENCRYPTION_INITIAL;
- case ENCRYPTION_HANDSHAKE:
- return quic_trace::ENCRYPTION_HANDSHAKE;
- case ENCRYPTION_ZERO_RTT:
- return quic_trace::ENCRYPTION_0RTT;
- case ENCRYPTION_FORWARD_SECURE:
- return quic_trace::ENCRYPTION_1RTT;
- case NUM_ENCRYPTION_LEVELS:
- QUIC_BUG(quic_bug_10284_1) << "Invalid encryption level specified";
- return quic_trace::ENCRYPTION_UNKNOWN;
- }
-}
-
-QuicTraceVisitor::QuicTraceVisitor(const QuicConnection* connection)
- : connection_(connection),
- start_time_(connection_->clock()->ApproximateNow()) {
- std::string binary_connection_id(connection->connection_id().data(),
- connection->connection_id().length());
- // We assume that the connection ID in gQUIC is equivalent to the
- // server-chosen client-selected ID.
- switch (connection->perspective()) {
- case Perspective::IS_CLIENT:
- trace_.set_destination_connection_id(binary_connection_id);
- break;
- case Perspective::IS_SERVER:
- trace_.set_source_connection_id(binary_connection_id);
- break;
- }
-}
-
-void QuicTraceVisitor::OnPacketSent(
- QuicPacketNumber packet_number,
- QuicPacketLength packet_length,
- bool /*has_crypto_handshake*/,
- TransmissionType /*transmission_type*/,
- EncryptionLevel encryption_level,
- const QuicFrames& retransmittable_frames,
- const QuicFrames& /*nonretransmittable_frames*/,
- QuicTime sent_time) {
- quic_trace::Event* event = trace_.add_events();
- event->set_event_type(quic_trace::PACKET_SENT);
- event->set_time_us(ConvertTimestampToRecordedFormat(sent_time));
- event->set_packet_number(packet_number.ToUint64());
- event->set_packet_size(packet_length);
- event->set_encryption_level(EncryptionLevelToProto(encryption_level));
-
- for (const QuicFrame& frame : retransmittable_frames) {
- switch (frame.type) {
- case STREAM_FRAME:
- case RST_STREAM_FRAME:
- case CONNECTION_CLOSE_FRAME:
- case WINDOW_UPDATE_FRAME:
- case BLOCKED_FRAME:
- case PING_FRAME:
- case HANDSHAKE_DONE_FRAME:
- case ACK_FREQUENCY_FRAME:
- PopulateFrameInfo(frame, event->add_frames());
- break;
-
- case PADDING_FRAME:
- case MTU_DISCOVERY_FRAME:
- case STOP_WAITING_FRAME:
- case ACK_FRAME:
- QUIC_BUG(quic_bug_12732_1)
- << "Frames of type are not retransmittable and are not supposed "
- "to be in retransmittable_frames";
- break;
-
- // New IETF frames, not used in current gQUIC version.
- case NEW_CONNECTION_ID_FRAME:
- case RETIRE_CONNECTION_ID_FRAME:
- case MAX_STREAMS_FRAME:
- case STREAMS_BLOCKED_FRAME:
- case PATH_RESPONSE_FRAME:
- case PATH_CHALLENGE_FRAME:
- case STOP_SENDING_FRAME:
- case MESSAGE_FRAME:
- case CRYPTO_FRAME:
- case NEW_TOKEN_FRAME:
- break;
-
- // Ignore gQUIC-specific frames.
- case GOAWAY_FRAME:
- break;
-
- case NUM_FRAME_TYPES:
- QUIC_BUG(quic_bug_10284_2) << "Unknown frame type encountered";
- break;
- }
- }
-
- // Output PCC DebugState on packet sent for analysis.
- if (connection_->sent_packet_manager()
- .GetSendAlgorithm()
- ->GetCongestionControlType() == kPCC) {
- PopulateTransportState(event->mutable_transport_state());
- }
-}
-
-void QuicTraceVisitor::PopulateFrameInfo(const QuicFrame& frame,
- quic_trace::Frame* frame_record) {
- switch (frame.type) {
- case STREAM_FRAME: {
- frame_record->set_frame_type(quic_trace::STREAM);
-
- quic_trace::StreamFrameInfo* info =
- frame_record->mutable_stream_frame_info();
- info->set_stream_id(frame.stream_frame.stream_id);
- info->set_fin(frame.stream_frame.fin);
- info->set_offset(frame.stream_frame.offset);
- info->set_length(frame.stream_frame.data_length);
- break;
- }
-
- case ACK_FRAME: {
- frame_record->set_frame_type(quic_trace::ACK);
-
- quic_trace::AckInfo* info = frame_record->mutable_ack_info();
- info->set_ack_delay_us(frame.ack_frame->ack_delay_time.ToMicroseconds());
- for (const auto& interval : frame.ack_frame->packets) {
- quic_trace::AckBlock* block = info->add_acked_packets();
- // We record intervals as [a, b], whereas the in-memory representation
- // we currently use is [a, b).
- block->set_first_packet(interval.min().ToUint64());
- block->set_last_packet(interval.max().ToUint64() - 1);
- }
- break;
- }
-
- case RST_STREAM_FRAME: {
- frame_record->set_frame_type(quic_trace::RESET_STREAM);
-
- quic_trace::ResetStreamInfo* info =
- frame_record->mutable_reset_stream_info();
- info->set_stream_id(frame.rst_stream_frame->stream_id);
- info->set_final_offset(frame.rst_stream_frame->byte_offset);
- info->set_application_error_code(frame.rst_stream_frame->error_code);
- break;
- }
-
- case CONNECTION_CLOSE_FRAME: {
- frame_record->set_frame_type(quic_trace::CONNECTION_CLOSE);
-
- quic_trace::CloseInfo* info = frame_record->mutable_close_info();
- info->set_error_code(frame.connection_close_frame->quic_error_code);
- info->set_reason_phrase(frame.connection_close_frame->error_details);
- info->set_close_type(static_cast<quic_trace::CloseType>(
- frame.connection_close_frame->close_type));
- info->set_transport_close_frame_type(
- frame.connection_close_frame->transport_close_frame_type);
- break;
- }
-
- case GOAWAY_FRAME:
- // Do not bother logging this since the frame in question is
- // gQUIC-specific.
- break;
-
- case WINDOW_UPDATE_FRAME: {
- bool is_connection = frame.window_update_frame->stream_id == 0;
- frame_record->set_frame_type(is_connection ? quic_trace::MAX_DATA
- : quic_trace::MAX_STREAM_DATA);
-
- quic_trace::FlowControlInfo* info =
- frame_record->mutable_flow_control_info();
- info->set_max_data(frame.window_update_frame->max_data);
- if (!is_connection) {
- info->set_stream_id(frame.window_update_frame->stream_id);
- }
- break;
- }
-
- case BLOCKED_FRAME: {
- bool is_connection = frame.blocked_frame->stream_id == 0;
- frame_record->set_frame_type(is_connection ? quic_trace::BLOCKED
- : quic_trace::STREAM_BLOCKED);
-
- quic_trace::FlowControlInfo* info =
- frame_record->mutable_flow_control_info();
- if (!is_connection) {
- info->set_stream_id(frame.window_update_frame->stream_id);
- }
- break;
- }
-
- case PING_FRAME:
- case MTU_DISCOVERY_FRAME:
- case HANDSHAKE_DONE_FRAME:
- frame_record->set_frame_type(quic_trace::PING);
- break;
-
- case PADDING_FRAME:
- frame_record->set_frame_type(quic_trace::PADDING);
- break;
-
- case STOP_WAITING_FRAME:
- // We're going to pretend those do not exist.
- break;
-
- // New IETF frames, not used in current gQUIC version.
- case NEW_CONNECTION_ID_FRAME:
- case RETIRE_CONNECTION_ID_FRAME:
- case MAX_STREAMS_FRAME:
- case STREAMS_BLOCKED_FRAME:
- case PATH_RESPONSE_FRAME:
- case PATH_CHALLENGE_FRAME:
- case STOP_SENDING_FRAME:
- case MESSAGE_FRAME:
- case CRYPTO_FRAME:
- case NEW_TOKEN_FRAME:
- case ACK_FREQUENCY_FRAME:
- break;
-
- case NUM_FRAME_TYPES:
- QUIC_BUG(quic_bug_10284_3) << "Unknown frame type encountered";
- break;
- }
-}
-
-void QuicTraceVisitor::OnIncomingAck(
- QuicPacketNumber /*ack_packet_number*/,
- EncryptionLevel ack_decrypted_level,
- const QuicAckFrame& ack_frame,
- QuicTime ack_receive_time,
- QuicPacketNumber /*largest_observed*/,
- bool /*rtt_updated*/,
- QuicPacketNumber /*least_unacked_sent_packet*/) {
- quic_trace::Event* event = trace_.add_events();
- event->set_time_us(ConvertTimestampToRecordedFormat(ack_receive_time));
- event->set_packet_number(connection_->GetLargestReceivedPacket().ToUint64());
- event->set_event_type(quic_trace::PACKET_RECEIVED);
- event->set_encryption_level(EncryptionLevelToProto(ack_decrypted_level));
-
- // TODO(vasilvv): consider removing this copy.
- QuicAckFrame copy_of_ack = ack_frame;
- PopulateFrameInfo(QuicFrame(&copy_of_ack), event->add_frames());
- PopulateTransportState(event->mutable_transport_state());
-}
-
-void QuicTraceVisitor::OnPacketLoss(QuicPacketNumber lost_packet_number,
- EncryptionLevel encryption_level,
- TransmissionType /*transmission_type*/,
- QuicTime detection_time) {
- quic_trace::Event* event = trace_.add_events();
- event->set_time_us(ConvertTimestampToRecordedFormat(detection_time));
- event->set_event_type(quic_trace::PACKET_LOST);
- event->set_packet_number(lost_packet_number.ToUint64());
- PopulateTransportState(event->mutable_transport_state());
- event->set_encryption_level(EncryptionLevelToProto(encryption_level));
-}
-
-void QuicTraceVisitor::OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame,
- const QuicTime& receive_time) {
- quic_trace::Event* event = trace_.add_events();
- event->set_time_us(ConvertTimestampToRecordedFormat(receive_time));
- event->set_event_type(quic_trace::PACKET_RECEIVED);
- event->set_packet_number(connection_->GetLargestReceivedPacket().ToUint64());
-
- // TODO(vasilvv): consider removing this copy.
- QuicWindowUpdateFrame copy_of_update = frame;
- PopulateFrameInfo(QuicFrame(&copy_of_update), event->add_frames());
-}
-
-void QuicTraceVisitor::OnSuccessfulVersionNegotiation(
- const ParsedQuicVersion& version) {
- uint32_t tag =
- quiche::QuicheEndian::HostToNet32(CreateQuicVersionLabel(version));
- std::string binary_tag(reinterpret_cast<const char*>(&tag), sizeof(tag));
- trace_.set_protocol_version(binary_tag);
-}
-
-void QuicTraceVisitor::OnApplicationLimited() {
- quic_trace::Event* event = trace_.add_events();
- event->set_time_us(
- ConvertTimestampToRecordedFormat(connection_->clock()->ApproximateNow()));
- event->set_event_type(quic_trace::APPLICATION_LIMITED);
-}
-
-void QuicTraceVisitor::OnAdjustNetworkParameters(QuicBandwidth bandwidth,
- QuicTime::Delta rtt,
- QuicByteCount /*old_cwnd*/,
- QuicByteCount /*new_cwnd*/) {
- quic_trace::Event* event = trace_.add_events();
- event->set_time_us(
- ConvertTimestampToRecordedFormat(connection_->clock()->ApproximateNow()));
- event->set_event_type(quic_trace::EXTERNAL_PARAMETERS);
-
- quic_trace::ExternalNetworkParameters* parameters =
- event->mutable_external_network_parameters();
- if (!bandwidth.IsZero()) {
- parameters->set_bandwidth_bps(bandwidth.ToBitsPerSecond());
- }
- if (!rtt.IsZero()) {
- parameters->set_rtt_us(rtt.ToMicroseconds());
- }
-}
-
-uint64_t QuicTraceVisitor::ConvertTimestampToRecordedFormat(
- QuicTime timestamp) {
- if (timestamp < start_time_) {
- QUIC_BUG(quic_bug_10284_4)
- << "Timestamp went back in time while recording a trace";
- return 0;
- }
-
- return (timestamp - start_time_).ToMicroseconds();
-}
-
-void QuicTraceVisitor::PopulateTransportState(
- quic_trace::TransportState* state) {
- const RttStats* rtt_stats = connection_->sent_packet_manager().GetRttStats();
- state->set_min_rtt_us(rtt_stats->min_rtt().ToMicroseconds());
- state->set_smoothed_rtt_us(rtt_stats->smoothed_rtt().ToMicroseconds());
- state->set_last_rtt_us(rtt_stats->latest_rtt().ToMicroseconds());
-
- state->set_cwnd_bytes(
- connection_->sent_packet_manager().GetCongestionWindowInBytes());
- QuicByteCount in_flight =
- connection_->sent_packet_manager().GetBytesInFlight();
- state->set_in_flight_bytes(in_flight);
- state->set_pacing_rate_bps(connection_->sent_packet_manager()
- .GetSendAlgorithm()
- ->PacingRate(in_flight)
- .ToBitsPerSecond());
-
- if (connection_->sent_packet_manager()
- .GetSendAlgorithm()
- ->GetCongestionControlType() == kPCC) {
- state->set_congestion_control_state(
- connection_->sent_packet_manager().GetSendAlgorithm()->GetDebugState());
- }
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_trace_visitor.h b/chromium/net/third_party/quiche/src/quic/core/quic_trace_visitor.h
deleted file mode 100644
index 47d543a0d7f..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_trace_visitor.h
+++ /dev/null
@@ -1,79 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_TRACE_VISITOR_H_
-#define QUICHE_QUIC_CORE_QUIC_TRACE_VISITOR_H_
-
-#include "quic/core/quic_connection.h"
-#include "quic/core/quic_types.h"
-#include "third_party/quic_trace/lib/quic_trace.pb.h"
-
-namespace quic {
-
-// Records a QUIC trace protocol buffer for a QuicConnection. It's the
-// responsibility of the user of this visitor to process or store the resulting
-// trace, which can be accessed via trace().
-class QUIC_NO_EXPORT QuicTraceVisitor : public QuicConnectionDebugVisitor {
- public:
- explicit QuicTraceVisitor(const QuicConnection* connection);
-
- void OnPacketSent(QuicPacketNumber packet_number,
- QuicPacketLength packet_length,
- bool has_crypto_handshake,
- TransmissionType transmission_type,
- EncryptionLevel encryption_level,
- const QuicFrames& retransmittable_frames,
- const QuicFrames& nonretransmittable_frames,
- QuicTime sent_time) override;
-
- void OnIncomingAck(QuicPacketNumber ack_packet_number,
- EncryptionLevel ack_decrypted_level,
- const QuicAckFrame& ack_frame,
- QuicTime ack_receive_time,
- QuicPacketNumber largest_observed,
- bool rtt_updated,
- QuicPacketNumber least_unacked_sent_packet) override;
-
- void OnPacketLoss(QuicPacketNumber lost_packet_number,
- EncryptionLevel encryption_level,
- TransmissionType transmission_type,
- QuicTime detection_time) override;
-
- void OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame,
- const QuicTime& receive_time) override;
-
- void OnSuccessfulVersionNegotiation(
- const ParsedQuicVersion& version) override;
-
- void OnApplicationLimited() override;
-
- void OnAdjustNetworkParameters(QuicBandwidth bandwidth,
- QuicTime::Delta rtt,
- QuicByteCount old_cwnd,
- QuicByteCount new_cwnd) override;
-
- // Returns a mutable pointer to the trace. The trace is owned by the
- // visitor, but can be moved using Swap() method after the connection is
- // finished.
- quic_trace::Trace* trace() { return &trace_; }
-
- private:
- // Converts QuicTime into a microsecond delta w.r.t. the beginning of the
- // connection.
- uint64_t ConvertTimestampToRecordedFormat(QuicTime timestamp);
- // Populates a quic_trace::Frame message from |frame|.
- void PopulateFrameInfo(const QuicFrame& frame,
- quic_trace::Frame* frame_record);
- // Populates a quic_trace::TransportState message from the associated
- // connection.
- void PopulateTransportState(quic_trace::TransportState* state);
-
- quic_trace::Trace trace_;
- const QuicConnection* connection_;
- const QuicTime start_time_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_QUIC_TRACE_VISITOR_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_trace_visitor_test.cc b/chromium/net/third_party/quiche/src/quic/core/quic_trace_visitor_test.cc
deleted file mode 100644
index 4deec7cfec7..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_trace_visitor_test.cc
+++ /dev/null
@@ -1,184 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_trace_visitor.h"
-
-#include "quic/core/quic_constants.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/quic_test_utils.h"
-#include "quic/test_tools/simulator/quic_endpoint.h"
-#include "quic/test_tools/simulator/simulator.h"
-#include "quic/test_tools/simulator/switch.h"
-
-namespace quic {
-namespace {
-
-const QuicByteCount kTransferSize = 1000 * kMaxOutgoingPacketSize;
-const QuicByteCount kTestStreamNumber = 3;
-const QuicTime::Delta kDelay = QuicTime::Delta::FromMilliseconds(20);
-
-// The trace for this test is generated using a simulator transfer.
-class QuicTraceVisitorTest : public QuicTest {
- public:
- QuicTraceVisitorTest() {
- QuicConnectionId connection_id = test::TestConnectionId();
- simulator::Simulator simulator;
- simulator::QuicEndpoint client(&simulator, "Client", "Server",
- Perspective::IS_CLIENT, connection_id);
- simulator::QuicEndpoint server(&simulator, "Server", "Client",
- Perspective::IS_SERVER, connection_id);
-
- const QuicBandwidth kBandwidth = QuicBandwidth::FromKBitsPerSecond(1000);
- const QuicByteCount kBdp = kBandwidth * (2 * kDelay);
-
- // Create parameters such that some loss is observed.
- simulator::Switch network_switch(&simulator, "Switch", 8, 0.5 * kBdp);
- simulator::SymmetricLink client_link(&client, network_switch.port(1),
- 2 * kBandwidth, kDelay);
- simulator::SymmetricLink server_link(&server, network_switch.port(2),
- kBandwidth, kDelay);
-
- QuicTraceVisitor visitor(client.connection());
- client.connection()->set_debug_visitor(&visitor);
-
- // Transfer about a megabyte worth of data from client to server.
- const QuicTime::Delta kDeadline =
- 3 * kBandwidth.TransferTime(kTransferSize);
- client.AddBytesToTransfer(kTransferSize);
- bool simulator_result = simulator.RunUntilOrTimeout(
- [&]() { return server.bytes_received() >= kTransferSize; }, kDeadline);
- QUICHE_CHECK(simulator_result);
-
- // Save the trace and ensure some loss was observed.
- trace_.Swap(visitor.trace());
- QUICHE_CHECK_NE(0u, client.connection()->GetStats().packets_retransmitted);
- packets_sent_ = client.connection()->GetStats().packets_sent;
- }
-
- std::vector<quic_trace::Event> AllEventsWithType(
- quic_trace::EventType event_type) {
- std::vector<quic_trace::Event> result;
- for (const auto& event : trace_.events()) {
- if (event.event_type() == event_type) {
- result.push_back(event);
- }
- }
- return result;
- }
-
- protected:
- quic_trace::Trace trace_;
- QuicPacketCount packets_sent_;
-};
-
-TEST_F(QuicTraceVisitorTest, ConnectionId) {
- char expected_cid[] = {0, 0, 0, 0, 0, 0, 0, 42};
- EXPECT_EQ(std::string(expected_cid, sizeof(expected_cid)),
- trace_.destination_connection_id());
-}
-
-TEST_F(QuicTraceVisitorTest, Version) {
- std::string version = trace_.protocol_version();
- ASSERT_EQ(4u, version.size());
- // Ensure version isn't all-zeroes.
- EXPECT_TRUE(version[0] != 0 || version[1] != 0 || version[2] != 0 ||
- version[3] != 0);
-}
-
-// Check that basic metadata about sent packets is recorded.
-TEST_F(QuicTraceVisitorTest, SentPacket) {
- auto sent_packets = AllEventsWithType(quic_trace::PACKET_SENT);
- EXPECT_EQ(packets_sent_, sent_packets.size());
- ASSERT_GT(sent_packets.size(), 0u);
-
- EXPECT_EQ(sent_packets[0].packet_size(), kDefaultMaxPacketSize);
- EXPECT_EQ(sent_packets[0].packet_number(), 1u);
-}
-
-// Ensure that every stream frame that was sent is recorded.
-TEST_F(QuicTraceVisitorTest, SentStream) {
- auto sent_packets = AllEventsWithType(quic_trace::PACKET_SENT);
-
- QuicIntervalSet<QuicStreamOffset> offsets;
- for (const quic_trace::Event& packet : sent_packets) {
- for (const quic_trace::Frame& frame : packet.frames()) {
- if (frame.frame_type() != quic_trace::STREAM) {
- continue;
- }
-
- const quic_trace::StreamFrameInfo& info = frame.stream_frame_info();
- if (info.stream_id() != kTestStreamNumber) {
- continue;
- }
-
- ASSERT_GT(info.length(), 0u);
- offsets.Add(info.offset(), info.offset() + info.length());
- }
- }
-
- ASSERT_EQ(1u, offsets.Size());
- EXPECT_EQ(0u, offsets.begin()->min());
- EXPECT_EQ(kTransferSize, offsets.rbegin()->max());
-}
-
-// Ensure that all packets are either acknowledged or lost.
-TEST_F(QuicTraceVisitorTest, AckPackets) {
- QuicIntervalSet<QuicPacketNumber> packets;
- for (const quic_trace::Event& packet : trace_.events()) {
- if (packet.event_type() == quic_trace::PACKET_RECEIVED) {
- for (const quic_trace::Frame& frame : packet.frames()) {
- if (frame.frame_type() != quic_trace::ACK) {
- continue;
- }
-
- const quic_trace::AckInfo& info = frame.ack_info();
- for (const auto& block : info.acked_packets()) {
- packets.Add(QuicPacketNumber(block.first_packet()),
- QuicPacketNumber(block.last_packet()) + 1);
- }
- }
- }
- if (packet.event_type() == quic_trace::PACKET_LOST) {
- packets.Add(QuicPacketNumber(packet.packet_number()),
- QuicPacketNumber(packet.packet_number()) + 1);
- }
- }
-
- ASSERT_EQ(1u, packets.Size());
- EXPECT_EQ(QuicPacketNumber(1u), packets.begin()->min());
- // We leave some room (20 packets) for the packets which did not receive
- // conclusive status at the end of simulation.
- EXPECT_GT(packets.rbegin()->max(), QuicPacketNumber(packets_sent_ - 20));
-}
-
-TEST_F(QuicTraceVisitorTest, TransportState) {
- auto acks = AllEventsWithType(quic_trace::PACKET_RECEIVED);
- ASSERT_EQ(1, acks[0].frames_size());
- ASSERT_EQ(quic_trace::ACK, acks[0].frames(0).frame_type());
-
- // Check that min-RTT at the end is a reasonable approximation.
- EXPECT_LE((4 * kDelay).ToMicroseconds() * 1.,
- acks.rbegin()->transport_state().min_rtt_us());
- EXPECT_GE((4 * kDelay).ToMicroseconds() * 1.25,
- acks.rbegin()->transport_state().min_rtt_us());
-}
-
-TEST_F(QuicTraceVisitorTest, EncryptionLevels) {
- for (const auto& event : trace_.events()) {
- switch (event.event_type()) {
- case quic_trace::PACKET_SENT:
- case quic_trace::PACKET_RECEIVED:
- case quic_trace::PACKET_LOST:
- ASSERT_TRUE(event.has_encryption_level());
- ASSERT_NE(event.encryption_level(), quic_trace::ENCRYPTION_UNKNOWN);
- break;
-
- default:
- break;
- }
- }
-}
-
-} // namespace
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_transmission_info.cc b/chromium/net/third_party/quiche/src/quic/core/quic_transmission_info.cc
deleted file mode 100644
index 9ec0f39be72..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_transmission_info.cc
+++ /dev/null
@@ -1,55 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_transmission_info.h"
-#include "absl/strings/str_cat.h"
-
-namespace quic {
-
-QuicTransmissionInfo::QuicTransmissionInfo()
- : sent_time(QuicTime::Zero()),
- bytes_sent(0),
- encryption_level(ENCRYPTION_INITIAL),
- transmission_type(NOT_RETRANSMISSION),
- in_flight(false),
- state(OUTSTANDING),
- has_crypto_handshake(false),
- has_ack_frequency(false) {}
-
-QuicTransmissionInfo::QuicTransmissionInfo(EncryptionLevel level,
- TransmissionType transmission_type,
- QuicTime sent_time,
- QuicPacketLength bytes_sent,
- bool has_crypto_handshake,
- bool has_ack_frequency)
- : sent_time(sent_time),
- bytes_sent(bytes_sent),
- encryption_level(level),
- transmission_type(transmission_type),
- in_flight(false),
- state(OUTSTANDING),
- has_crypto_handshake(has_crypto_handshake),
- has_ack_frequency(has_ack_frequency) {}
-
-QuicTransmissionInfo::QuicTransmissionInfo(const QuicTransmissionInfo& other) =
- default;
-
-QuicTransmissionInfo::~QuicTransmissionInfo() {}
-
-std::string QuicTransmissionInfo::DebugString() const {
- return absl::StrCat(
- "{sent_time: ", sent_time.ToDebuggingValue(),
- ", bytes_sent: ", bytes_sent,
- ", encryption_level: ", EncryptionLevelToString(encryption_level),
- ", transmission_type: ", TransmissionTypeToString(transmission_type),
- ", in_flight: ", in_flight, ", state: ", state,
- ", has_crypto_handshake: ", has_crypto_handshake,
- ", has_ack_frequency: ", has_ack_frequency,
- ", first_sent_after_loss: ", first_sent_after_loss.ToString(),
- ", largest_acked: ", largest_acked.ToString(),
- ", retransmittable_frames: ", QuicFramesToString(retransmittable_frames),
- "}");
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_transmission_info.h b/chromium/net/third_party/quiche/src/quic/core/quic_transmission_info.h
deleted file mode 100644
index bc0f5f70706..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_transmission_info.h
+++ /dev/null
@@ -1,66 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_TRANSMISSION_INFO_H_
-#define QUICHE_QUIC_CORE_QUIC_TRANSMISSION_INFO_H_
-
-#include <list>
-
-#include "quic/core/frames/quic_frame.h"
-#include "quic/core/quic_ack_listener_interface.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// Stores details of a single sent packet.
-struct QUIC_EXPORT_PRIVATE QuicTransmissionInfo {
- // Used by STL when assigning into a map.
- QuicTransmissionInfo();
-
- // Constructs a Transmission with a new all_transmissions set
- // containing |packet_number|.
- QuicTransmissionInfo(EncryptionLevel level,
- TransmissionType transmission_type,
- QuicTime sent_time,
- QuicPacketLength bytes_sent,
- bool has_crypto_handshake,
- bool has_ack_frequency);
-
- QuicTransmissionInfo(const QuicTransmissionInfo& other);
-
- ~QuicTransmissionInfo();
-
- std::string DebugString() const;
-
- QuicFrames retransmittable_frames;
- QuicTime sent_time;
- QuicPacketLength bytes_sent;
- EncryptionLevel encryption_level;
- // Reason why this packet was transmitted.
- TransmissionType transmission_type;
- // In flight packets have not been abandoned or lost.
- bool in_flight;
- // State of this packet.
- SentPacketState state;
- // True if the packet contains stream data from the crypto stream.
- bool has_crypto_handshake;
- // True if the packet contains ack frequency frame.
- bool has_ack_frequency;
- // Records the first sent packet after this packet was detected lost. Zero if
- // this packet has not been detected lost. This is used to keep lost packet
- // for another RTT (for potential spurious loss detection)
- QuicPacketNumber first_sent_after_loss;
- // The largest_acked in the ack frame, if the packet contains an ack.
- QuicPacketNumber largest_acked;
-};
-// TODO(ianswett): Add static_assert when size of this struct is reduced below
-// 64 bytes.
-// NOTE(vlovich): Existing static_assert removed because padding differences on
-// 64-bit iOS resulted in an 88-byte struct that is greater than the 84-byte
-// limit on other platforms. Removing per ianswett's request.
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_QUIC_TRANSMISSION_INFO_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_types.cc b/chromium/net/third_party/quiche/src/quic/core/quic_types.cc
deleted file mode 100644
index 70c9101b281..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_types.cc
+++ /dev/null
@@ -1,426 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_types.h"
-
-#include <cstdint>
-
-#include "absl/strings/str_cat.h"
-#include "quic/core/quic_error_codes.h"
-#include "common/print_elements.h"
-
-namespace quic {
-
-static_assert(sizeof(StatelessResetToken) == kStatelessResetTokenLength,
- "bad size");
-
-std::ostream& operator<<(std::ostream& os, const QuicConsumedData& s) {
- os << "bytes_consumed: " << s.bytes_consumed
- << " fin_consumed: " << s.fin_consumed;
- return os;
-}
-
-std::string PerspectiveToString(Perspective perspective) {
- if (perspective == Perspective::IS_SERVER) {
- return "IS_SERVER";
- }
- if (perspective == Perspective::IS_CLIENT) {
- return "IS_CLIENT";
- }
- return absl::StrCat("Unknown(", static_cast<int>(perspective), ")");
-}
-
-std::ostream& operator<<(std::ostream& os, const Perspective& perspective) {
- os << PerspectiveToString(perspective);
- return os;
-}
-
-std::string ConnectionCloseSourceToString(
- ConnectionCloseSource connection_close_source) {
- if (connection_close_source == ConnectionCloseSource::FROM_PEER) {
- return "FROM_PEER";
- }
- if (connection_close_source == ConnectionCloseSource::FROM_SELF) {
- return "FROM_SELF";
- }
- return absl::StrCat("Unknown(", static_cast<int>(connection_close_source),
- ")");
-}
-
-std::ostream& operator<<(std::ostream& os,
- const ConnectionCloseSource& connection_close_source) {
- os << ConnectionCloseSourceToString(connection_close_source);
- return os;
-}
-
-std::string ConnectionCloseBehaviorToString(
- ConnectionCloseBehavior connection_close_behavior) {
- if (connection_close_behavior == ConnectionCloseBehavior::SILENT_CLOSE) {
- return "SILENT_CLOSE";
- }
- if (connection_close_behavior ==
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET) {
- return "SEND_CONNECTION_CLOSE_PACKET";
- }
- return absl::StrCat("Unknown(", static_cast<int>(connection_close_behavior),
- ")");
-}
-
-std::ostream& operator<<(
- std::ostream& os,
- const ConnectionCloseBehavior& connection_close_behavior) {
- os << ConnectionCloseBehaviorToString(connection_close_behavior);
- return os;
-}
-
-std::ostream& operator<<(std::ostream& os, const AckedPacket& acked_packet) {
- os << "{ packet_number: " << acked_packet.packet_number
- << ", bytes_acked: " << acked_packet.bytes_acked << ", receive_timestamp: "
- << acked_packet.receive_timestamp.ToDebuggingValue() << "} ";
- return os;
-}
-
-std::ostream& operator<<(std::ostream& os, const LostPacket& lost_packet) {
- os << "{ packet_number: " << lost_packet.packet_number
- << ", bytes_lost: " << lost_packet.bytes_lost << "} ";
- return os;
-}
-
-std::string HistogramEnumString(WriteStatus enum_value) {
- switch (enum_value) {
- case WRITE_STATUS_OK:
- return "OK";
- case WRITE_STATUS_BLOCKED:
- return "BLOCKED";
- case WRITE_STATUS_BLOCKED_DATA_BUFFERED:
- return "BLOCKED_DATA_BUFFERED";
- case WRITE_STATUS_ERROR:
- return "ERROR";
- case WRITE_STATUS_MSG_TOO_BIG:
- return "MSG_TOO_BIG";
- case WRITE_STATUS_FAILED_TO_COALESCE_PACKET:
- return "WRITE_STATUS_FAILED_TO_COALESCE_PACKET";
- case WRITE_STATUS_NUM_VALUES:
- return "NUM_VALUES";
- }
- QUIC_DLOG(ERROR) << "Invalid WriteStatus value: "
- << static_cast<int16_t>(enum_value);
- return "<invalid>";
-}
-
-std::ostream& operator<<(std::ostream& os, const WriteStatus& status) {
- os << HistogramEnumString(status);
- return os;
-}
-
-std::ostream& operator<<(std::ostream& os, const WriteResult& s) {
- os << "{ status: " << s.status;
- if (s.status == WRITE_STATUS_OK) {
- os << ", bytes_written: " << s.bytes_written;
- } else {
- os << ", error_code: " << s.error_code;
- }
- os << " }";
- return os;
-}
-
-MessageResult::MessageResult(MessageStatus status, QuicMessageId message_id)
- : status(status), message_id(message_id) {}
-
-#define RETURN_STRING_LITERAL(x) \
- case x: \
- return #x;
-
-std::string QuicFrameTypeToString(QuicFrameType t) {
- switch (t) {
- RETURN_STRING_LITERAL(PADDING_FRAME)
- RETURN_STRING_LITERAL(RST_STREAM_FRAME)
- RETURN_STRING_LITERAL(CONNECTION_CLOSE_FRAME)
- RETURN_STRING_LITERAL(GOAWAY_FRAME)
- RETURN_STRING_LITERAL(WINDOW_UPDATE_FRAME)
- RETURN_STRING_LITERAL(BLOCKED_FRAME)
- RETURN_STRING_LITERAL(STOP_WAITING_FRAME)
- RETURN_STRING_LITERAL(PING_FRAME)
- RETURN_STRING_LITERAL(CRYPTO_FRAME)
- RETURN_STRING_LITERAL(HANDSHAKE_DONE_FRAME)
- RETURN_STRING_LITERAL(STREAM_FRAME)
- RETURN_STRING_LITERAL(ACK_FRAME)
- RETURN_STRING_LITERAL(MTU_DISCOVERY_FRAME)
- RETURN_STRING_LITERAL(NEW_CONNECTION_ID_FRAME)
- RETURN_STRING_LITERAL(MAX_STREAMS_FRAME)
- RETURN_STRING_LITERAL(STREAMS_BLOCKED_FRAME)
- RETURN_STRING_LITERAL(PATH_RESPONSE_FRAME)
- RETURN_STRING_LITERAL(PATH_CHALLENGE_FRAME)
- RETURN_STRING_LITERAL(STOP_SENDING_FRAME)
- RETURN_STRING_LITERAL(MESSAGE_FRAME)
- RETURN_STRING_LITERAL(NEW_TOKEN_FRAME)
- RETURN_STRING_LITERAL(RETIRE_CONNECTION_ID_FRAME)
- RETURN_STRING_LITERAL(ACK_FREQUENCY_FRAME)
- RETURN_STRING_LITERAL(NUM_FRAME_TYPES)
- }
- return absl::StrCat("Unknown(", static_cast<int>(t), ")");
-}
-
-std::ostream& operator<<(std::ostream& os, const QuicFrameType& t) {
- os << QuicFrameTypeToString(t);
- return os;
-}
-
-std::string QuicIetfFrameTypeString(QuicIetfFrameType t) {
- if (IS_IETF_STREAM_FRAME(t)) {
- return "IETF_STREAM";
- }
-
- switch (t) {
- RETURN_STRING_LITERAL(IETF_PADDING);
- RETURN_STRING_LITERAL(IETF_PING);
- RETURN_STRING_LITERAL(IETF_ACK);
- RETURN_STRING_LITERAL(IETF_ACK_ECN);
- RETURN_STRING_LITERAL(IETF_RST_STREAM);
- RETURN_STRING_LITERAL(IETF_STOP_SENDING);
- RETURN_STRING_LITERAL(IETF_CRYPTO);
- RETURN_STRING_LITERAL(IETF_NEW_TOKEN);
- RETURN_STRING_LITERAL(IETF_MAX_DATA);
- RETURN_STRING_LITERAL(IETF_MAX_STREAM_DATA);
- RETURN_STRING_LITERAL(IETF_MAX_STREAMS_BIDIRECTIONAL);
- RETURN_STRING_LITERAL(IETF_MAX_STREAMS_UNIDIRECTIONAL);
- RETURN_STRING_LITERAL(IETF_DATA_BLOCKED);
- RETURN_STRING_LITERAL(IETF_STREAM_DATA_BLOCKED);
- RETURN_STRING_LITERAL(IETF_STREAMS_BLOCKED_BIDIRECTIONAL);
- RETURN_STRING_LITERAL(IETF_STREAMS_BLOCKED_UNIDIRECTIONAL);
- RETURN_STRING_LITERAL(IETF_NEW_CONNECTION_ID);
- RETURN_STRING_LITERAL(IETF_RETIRE_CONNECTION_ID);
- RETURN_STRING_LITERAL(IETF_PATH_CHALLENGE);
- RETURN_STRING_LITERAL(IETF_PATH_RESPONSE);
- RETURN_STRING_LITERAL(IETF_CONNECTION_CLOSE);
- RETURN_STRING_LITERAL(IETF_APPLICATION_CLOSE);
- RETURN_STRING_LITERAL(IETF_EXTENSION_MESSAGE_NO_LENGTH);
- RETURN_STRING_LITERAL(IETF_EXTENSION_MESSAGE);
- RETURN_STRING_LITERAL(IETF_EXTENSION_MESSAGE_NO_LENGTH_V99);
- RETURN_STRING_LITERAL(IETF_EXTENSION_MESSAGE_V99);
- default:
- return absl::StrCat("Private value (", t, ")");
- }
-}
-std::ostream& operator<<(std::ostream& os, const QuicIetfFrameType& c) {
- os << QuicIetfFrameTypeString(c);
- return os;
-}
-
-std::string TransmissionTypeToString(TransmissionType transmission_type) {
- switch (transmission_type) {
- RETURN_STRING_LITERAL(NOT_RETRANSMISSION);
- 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:
- // Some varz rely on this behavior for statistic collection.
- if (transmission_type == LAST_TRANSMISSION_TYPE + 1) {
- return "INVALID_TRANSMISSION_TYPE";
- }
- return absl::StrCat("Unknown(", static_cast<int>(transmission_type), ")");
- }
-}
-
-std::ostream& operator<<(std::ostream& os, TransmissionType transmission_type) {
- os << TransmissionTypeToString(transmission_type);
- return os;
-}
-
-std::string PacketHeaderFormatToString(PacketHeaderFormat format) {
- switch (format) {
- RETURN_STRING_LITERAL(IETF_QUIC_LONG_HEADER_PACKET);
- RETURN_STRING_LITERAL(IETF_QUIC_SHORT_HEADER_PACKET);
- RETURN_STRING_LITERAL(GOOGLE_QUIC_PACKET);
- default:
- return absl::StrCat("Unknown (", static_cast<int>(format), ")");
- }
-}
-
-std::string QuicLongHeaderTypeToString(QuicLongHeaderType type) {
- switch (type) {
- RETURN_STRING_LITERAL(VERSION_NEGOTIATION);
- RETURN_STRING_LITERAL(INITIAL);
- RETURN_STRING_LITERAL(ZERO_RTT_PROTECTED);
- RETURN_STRING_LITERAL(HANDSHAKE);
- RETURN_STRING_LITERAL(RETRY);
- RETURN_STRING_LITERAL(INVALID_PACKET_TYPE);
- default:
- return absl::StrCat("Unknown (", static_cast<int>(type), ")");
- }
-}
-
-std::string MessageStatusToString(MessageStatus message_status) {
- switch (message_status) {
- RETURN_STRING_LITERAL(MESSAGE_STATUS_SUCCESS);
- RETURN_STRING_LITERAL(MESSAGE_STATUS_ENCRYPTION_NOT_ESTABLISHED);
- RETURN_STRING_LITERAL(MESSAGE_STATUS_UNSUPPORTED);
- RETURN_STRING_LITERAL(MESSAGE_STATUS_BLOCKED);
- RETURN_STRING_LITERAL(MESSAGE_STATUS_TOO_LARGE);
- RETURN_STRING_LITERAL(MESSAGE_STATUS_INTERNAL_ERROR);
- default:
- return absl::StrCat("Unknown(", static_cast<int>(message_status), ")");
- }
-}
-
-std::string MessageResultToString(MessageResult message_result) {
- if (message_result.status != MESSAGE_STATUS_SUCCESS) {
- return absl::StrCat("{", MessageStatusToString(message_result.status), "}");
- }
- return absl::StrCat("{MESSAGE_STATUS_SUCCESS,id=", message_result.message_id,
- "}");
-}
-
-std::ostream& operator<<(std::ostream& os, const MessageResult& mr) {
- os << MessageResultToString(mr);
- return os;
-}
-
-std::string PacketNumberSpaceToString(PacketNumberSpace packet_number_space) {
- switch (packet_number_space) {
- RETURN_STRING_LITERAL(INITIAL_DATA);
- RETURN_STRING_LITERAL(HANDSHAKE_DATA);
- RETURN_STRING_LITERAL(APPLICATION_DATA);
- default:
- return absl::StrCat("Unknown(", static_cast<int>(packet_number_space),
- ")");
- }
-}
-
-std::string SerializedPacketFateToString(SerializedPacketFate fate) {
- switch (fate) {
- RETURN_STRING_LITERAL(COALESCE);
- RETURN_STRING_LITERAL(BUFFER);
- RETURN_STRING_LITERAL(SEND_TO_WRITER);
- RETURN_STRING_LITERAL(LEGACY_VERSION_ENCAPSULATE);
- default:
- return absl::StrCat("Unknown(", static_cast<int>(fate), ")");
- }
-}
-
-std::ostream& operator<<(std::ostream& os, SerializedPacketFate fate) {
- os << SerializedPacketFateToString(fate);
- return os;
-}
-
-std::string EncryptionLevelToString(EncryptionLevel level) {
- switch (level) {
- RETURN_STRING_LITERAL(ENCRYPTION_INITIAL);
- RETURN_STRING_LITERAL(ENCRYPTION_HANDSHAKE);
- RETURN_STRING_LITERAL(ENCRYPTION_ZERO_RTT);
- RETURN_STRING_LITERAL(ENCRYPTION_FORWARD_SECURE);
- default:
- return absl::StrCat("Unknown(", static_cast<int>(level), ")");
- }
-}
-
-std::ostream& operator<<(std::ostream& os, EncryptionLevel level) {
- os << EncryptionLevelToString(level);
- return os;
-}
-
-absl::string_view ClientCertModeToString(ClientCertMode mode) {
-#define RETURN_REASON_LITERAL(x) \
- case ClientCertMode::x: \
- return #x
- switch (mode) {
- RETURN_REASON_LITERAL(kNone);
- RETURN_REASON_LITERAL(kRequest);
- RETURN_REASON_LITERAL(kRequire);
- default:
- return "<invalid>";
- }
-#undef RETURN_REASON_LITERAL
-}
-
-std::ostream& operator<<(std::ostream& os, ClientCertMode mode) {
- os << ClientCertModeToString(mode);
- return os;
-}
-
-std::string QuicConnectionCloseTypeString(QuicConnectionCloseType type) {
- switch (type) {
- RETURN_STRING_LITERAL(GOOGLE_QUIC_CONNECTION_CLOSE);
- RETURN_STRING_LITERAL(IETF_QUIC_TRANSPORT_CONNECTION_CLOSE);
- RETURN_STRING_LITERAL(IETF_QUIC_APPLICATION_CONNECTION_CLOSE);
- default:
- return absl::StrCat("Unknown(", static_cast<int>(type), ")");
- }
-}
-
-std::ostream& operator<<(std::ostream& os, const QuicConnectionCloseType type) {
- os << QuicConnectionCloseTypeString(type);
- return os;
-}
-
-std::string AddressChangeTypeToString(AddressChangeType type) {
- using IntType = typename std::underlying_type<AddressChangeType>::type;
- switch (type) {
- RETURN_STRING_LITERAL(NO_CHANGE);
- RETURN_STRING_LITERAL(PORT_CHANGE);
- RETURN_STRING_LITERAL(IPV4_SUBNET_CHANGE);
- RETURN_STRING_LITERAL(IPV4_TO_IPV4_CHANGE);
- RETURN_STRING_LITERAL(IPV4_TO_IPV6_CHANGE);
- RETURN_STRING_LITERAL(IPV6_TO_IPV4_CHANGE);
- RETURN_STRING_LITERAL(IPV6_TO_IPV6_CHANGE);
- default:
- return absl::StrCat("Unknown(", static_cast<IntType>(type), ")");
- }
-}
-
-std::ostream& operator<<(std::ostream& os, AddressChangeType type) {
- os << AddressChangeTypeToString(type);
- return os;
-}
-
-std::string KeyUpdateReasonString(KeyUpdateReason reason) {
-#define RETURN_REASON_LITERAL(x) \
- case KeyUpdateReason::x: \
- return #x
- switch (reason) {
- RETURN_REASON_LITERAL(kInvalid);
- RETURN_REASON_LITERAL(kRemote);
- RETURN_REASON_LITERAL(kLocalForTests);
- RETURN_REASON_LITERAL(kLocalForInteropRunner);
- RETURN_REASON_LITERAL(kLocalAeadConfidentialityLimit);
- RETURN_REASON_LITERAL(kLocalKeyUpdateLimitOverride);
- default:
- return absl::StrCat("Unknown(", static_cast<int>(reason), ")");
- }
-#undef RETURN_REASON_LITERAL
-}
-
-std::ostream& operator<<(std::ostream& os, const KeyUpdateReason reason) {
- os << KeyUpdateReasonString(reason);
- return os;
-}
-
-bool operator==(const ParsedClientHello& a, const ParsedClientHello& b) {
- return a.sni == b.sni && a.uaid == b.uaid && a.alpns == b.alpns &&
- a.legacy_version_encapsulation_inner_packet ==
- b.legacy_version_encapsulation_inner_packet &&
- a.retry_token == b.retry_token &&
- a.resumption_attempted == b.resumption_attempted &&
- a.early_data_attempted == b.early_data_attempted;
-}
-
-std::ostream& operator<<(std::ostream& os,
- const ParsedClientHello& parsed_chlo) {
- os << "{ sni:" << parsed_chlo.sni << ", uaid:" << parsed_chlo.uaid
- << ", alpns:" << quiche::PrintElements(parsed_chlo.alpns)
- << ", len(retry_token):" << parsed_chlo.retry_token.size()
- << ", len(inner_packet):"
- << parsed_chlo.legacy_version_encapsulation_inner_packet.size() << " }";
- return os;
-}
-
-#undef RETURN_STRING_LITERAL // undef for jumbo builds
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_types.h b/chromium/net/third_party/quiche/src/quic/core/quic_types.h
deleted file mode 100644
index a437c9ae731..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_types.h
+++ /dev/null
@@ -1,891 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_TYPES_H_
-#define QUICHE_QUIC_CORE_QUIC_TYPES_H_
-
-#include <array>
-#include <cstddef>
-#include <cstdint>
-#include <map>
-#include <ostream>
-#include <vector>
-
-#include "absl/container/inlined_vector.h"
-#include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
-#include "quic/core/quic_connection_id.h"
-#include "quic/core/quic_error_codes.h"
-#include "quic/core/quic_packet_number.h"
-#include "quic/core/quic_time.h"
-#include "quic/platform/api/quic_export.h"
-#include "quic/platform/api/quic_flags.h"
-
-namespace quic {
-
-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
-// and QuicTransmissionInfo, as that allows them to fit in cache lines and has
-// visible perfomance impact.
-using QuicStreamId = uint32_t;
-
-// Count of stream IDs. Used in MAX_STREAMS and STREAMS_BLOCKED frames.
-using QuicStreamCount = QuicStreamId;
-
-using QuicByteCount = uint64_t;
-using QuicPacketCount = uint64_t;
-using QuicPublicResetNonceProof = uint64_t;
-using QuicStreamOffset = uint64_t;
-using DiversificationNonce = std::array<char, 32>;
-using PacketTimeVector = std::vector<std::pair<QuicPacketNumber, QuicTime>>;
-
-enum : size_t { kStatelessResetTokenLength = 16 };
-using StatelessResetToken = std::array<char, kStatelessResetTokenLength>;
-
-// WebTransport session IDs are stream IDs.
-using WebTransportSessionId = uint64_t;
-// WebTransport stream reset codes are 8-bit.
-using WebTransportStreamError = uint8_t;
-// WebTransport session error codes are 32-bit.
-using WebTransportSessionError = uint32_t;
-
-enum : size_t { kQuicPathFrameBufferSize = 8 };
-using QuicPathFrameBuffer = std::array<uint8_t, kQuicPathFrameBufferSize>;
-
-// The connection id sequence number specifies the order that connection
-// ids must be used in. This is also the sequence number carried in
-// the IETF QUIC NEW_CONNECTION_ID and RETIRE_CONNECTION_ID frames.
-using QuicConnectionIdSequenceNumber = uint64_t;
-
-// A custom data that represents application-specific settings.
-// In HTTP/3 for example, it includes the encoded SETTINGS.
-using ApplicationState = std::vector<uint8_t>;
-
-// A struct for functions which consume data payloads and fins.
-struct QUIC_EXPORT_PRIVATE QuicConsumedData {
- constexpr QuicConsumedData(size_t bytes_consumed, bool fin_consumed)
- : bytes_consumed(bytes_consumed), fin_consumed(fin_consumed) {}
-
- // By default, gtest prints the raw bytes of an object. The bool data
- // member causes this object to have padding bytes, which causes the
- // default gtest object printer to read uninitialize memory. So we need
- // to teach gtest how to print this object.
- QUIC_EXPORT_PRIVATE friend std::ostream& operator<<(
- std::ostream& os, const QuicConsumedData& s);
-
- // How many bytes were consumed.
- size_t bytes_consumed;
-
- // True if an incoming fin was consumed.
- bool fin_consumed;
-};
-
-// QuicAsyncStatus enumerates the possible results of an asynchronous
-// operation.
-enum QuicAsyncStatus {
- QUIC_SUCCESS = 0,
- QUIC_FAILURE = 1,
- // QUIC_PENDING results from an operation that will occur asynchronously. When
- // the operation is complete, a callback's |Run| method will be called.
- QUIC_PENDING = 2,
-};
-
-// TODO(wtc): see if WriteStatus can be replaced by QuicAsyncStatus.
-enum WriteStatus : int16_t {
- WRITE_STATUS_OK,
- // Write is blocked, caller needs to retry.
- WRITE_STATUS_BLOCKED,
- // Write is blocked but the packet data is buffered, caller should not retry.
- WRITE_STATUS_BLOCKED_DATA_BUFFERED,
- // To make the IsWriteError(WriteStatus) function work properly:
- // - Non-errors MUST be added before WRITE_STATUS_ERROR.
- // - Errors MUST be added after WRITE_STATUS_ERROR.
- WRITE_STATUS_ERROR,
- WRITE_STATUS_MSG_TOO_BIG,
- WRITE_STATUS_FAILED_TO_COALESCE_PACKET,
- WRITE_STATUS_NUM_VALUES,
-};
-
-std::string HistogramEnumString(WriteStatus enum_value);
-QUIC_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
- const WriteStatus& status);
-
-inline std::string HistogramEnumDescription(WriteStatus /*dummy*/) {
- return "status";
-}
-
-inline bool IsWriteBlockedStatus(WriteStatus status) {
- return status == WRITE_STATUS_BLOCKED ||
- status == WRITE_STATUS_BLOCKED_DATA_BUFFERED;
-}
-
-inline bool IsWriteError(WriteStatus status) {
- return status >= WRITE_STATUS_ERROR;
-}
-
-// A struct used to return the result of write calls including either the number
-// of bytes written or the error code, depending upon the status.
-struct QUIC_EXPORT_PRIVATE WriteResult {
- constexpr WriteResult(WriteStatus status, int bytes_written_or_error_code)
- : status(status), bytes_written(bytes_written_or_error_code) {}
-
- constexpr WriteResult() : WriteResult(WRITE_STATUS_ERROR, 0) {}
-
- bool operator==(const WriteResult& other) const {
- if (status != other.status) {
- return false;
- }
- switch (status) {
- case WRITE_STATUS_OK:
- return bytes_written == other.bytes_written;
- case WRITE_STATUS_BLOCKED:
- case WRITE_STATUS_BLOCKED_DATA_BUFFERED:
- return true;
- default:
- return error_code == other.error_code;
- }
- }
-
- QUIC_EXPORT_PRIVATE friend std::ostream& operator<<(std::ostream& os,
- const WriteResult& s);
-
- WriteStatus status;
- // Number of packets dropped as a result of this write.
- // Only used by batch writers. Otherwise always 0.
- uint16_t dropped_packets = 0;
- // The delta between a packet's ideal and actual send time:
- // actual_send_time = ideal_send_time + send_time_offset
- // = (now + release_time_delay) + send_time_offset
- // Only valid if |status| is WRITE_STATUS_OK.
- QuicTime::Delta send_time_offset = QuicTime::Delta::Zero();
- // TODO(wub): In some cases, WRITE_STATUS_ERROR may set an error_code and
- // WRITE_STATUS_BLOCKED_DATA_BUFFERED may set bytes_written. This may need
- // some cleaning up so that perhaps both values can be set and valid.
- union {
- int bytes_written; // only valid when status is WRITE_STATUS_OK
- int error_code; // only valid when status is WRITE_STATUS_ERROR
- };
-};
-
-enum TransmissionType : int8_t {
- NOT_RETRANSMISSION,
- FIRST_TRANSMISSION_TYPE = NOT_RETRANSMISSION,
- HANDSHAKE_RETRANSMISSION, // Retransmits due to handshake timeouts.
- ALL_ZERO_RTT_RETRANSMISSION, // Retransmits all packets encrypted with 0-RTT
- // key.
- LOSS_RETRANSMISSION, // Retransmits due to loss detection.
- RTO_RETRANSMISSION, // Retransmits due to retransmit time out.
- TLP_RETRANSMISSION, // Tail loss probes.
- PTO_RETRANSMISSION, // Retransmission due to probe timeout.
- PROBING_RETRANSMISSION, // Retransmission in order to probe bandwidth.
- PATH_RETRANSMISSION, // Retransmission proactively due to underlying
- // network change.
- ALL_INITIAL_RETRANSMISSION, // Retransmit all packets encrypted with INITIAL
- // key.
- LAST_TRANSMISSION_TYPE = ALL_INITIAL_RETRANSMISSION,
-};
-
-QUIC_EXPORT_PRIVATE std::string TransmissionTypeToString(
- TransmissionType transmission_type);
-
-QUIC_EXPORT_PRIVATE std::ostream& operator<<(
- std::ostream& os, TransmissionType transmission_type);
-
-enum HasRetransmittableData : uint8_t {
- NO_RETRANSMITTABLE_DATA,
- HAS_RETRANSMITTABLE_DATA,
-};
-
-enum IsHandshake : uint8_t { NOT_HANDSHAKE, IS_HANDSHAKE };
-
-enum class Perspective : uint8_t { IS_SERVER, IS_CLIENT };
-
-QUIC_EXPORT_PRIVATE std::string PerspectiveToString(Perspective perspective);
-QUIC_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
- const Perspective& perspective);
-
-// Describes whether a ConnectionClose was originated by the peer.
-enum class ConnectionCloseSource { FROM_PEER, FROM_SELF };
-
-QUIC_EXPORT_PRIVATE std::string ConnectionCloseSourceToString(
- ConnectionCloseSource connection_close_source);
-QUIC_EXPORT_PRIVATE std::ostream& operator<<(
- std::ostream& os, const ConnectionCloseSource& connection_close_source);
-
-// Should a connection be closed silently or not.
-enum class ConnectionCloseBehavior {
- SILENT_CLOSE,
- SILENT_CLOSE_WITH_CONNECTION_CLOSE_PACKET_SERIALIZED,
- SEND_CONNECTION_CLOSE_PACKET
-};
-
-QUIC_EXPORT_PRIVATE std::string ConnectionCloseBehaviorToString(
- ConnectionCloseBehavior connection_close_behavior);
-QUIC_EXPORT_PRIVATE std::ostream& operator<<(
- std::ostream& os, const ConnectionCloseBehavior& connection_close_behavior);
-
-enum QuicFrameType : uint8_t {
- // Regular frame types. The values set here cannot change without the
- // introduction of a new QUIC version.
- PADDING_FRAME = 0,
- RST_STREAM_FRAME = 1,
- CONNECTION_CLOSE_FRAME = 2,
- GOAWAY_FRAME = 3,
- WINDOW_UPDATE_FRAME = 4,
- BLOCKED_FRAME = 5,
- STOP_WAITING_FRAME = 6,
- PING_FRAME = 7,
- CRYPTO_FRAME = 8,
- // TODO(b/157935330): stop hard coding this when deprecate T050.
- HANDSHAKE_DONE_FRAME = 9,
-
- // STREAM and ACK frames are special frames. They are encoded differently on
- // the wire and their values do not need to be stable.
- STREAM_FRAME,
- ACK_FRAME,
- // The path MTU discovery frame is encoded as a PING frame on the wire.
- MTU_DISCOVERY_FRAME,
-
- // These are for IETF-specific frames for which there is no mapping
- // from Google QUIC frames. These are valid/allowed if and only if IETF-
- // QUIC has been negotiated. Values are not important, they are not
- // the values that are in the packets (see QuicIetfFrameType, below).
- NEW_CONNECTION_ID_FRAME,
- MAX_STREAMS_FRAME,
- STREAMS_BLOCKED_FRAME,
- PATH_RESPONSE_FRAME,
- PATH_CHALLENGE_FRAME,
- STOP_SENDING_FRAME,
- MESSAGE_FRAME,
- NEW_TOKEN_FRAME,
- RETIRE_CONNECTION_ID_FRAME,
- ACK_FREQUENCY_FRAME,
-
- NUM_FRAME_TYPES
-};
-
-// Human-readable string suitable for logging.
-QUIC_EXPORT_PRIVATE std::string QuicFrameTypeToString(QuicFrameType t);
-QUIC_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
- const QuicFrameType& t);
-
-// Ietf frame types. These are defined in the IETF QUIC Specification.
-// Explicit values are given in the enum so that we can be sure that
-// the symbol will map to the correct stream type.
-// All types are defined here, even if we have not yet implmented the
-// quic/core/stream/.... stuff needed.
-// Note: The protocol specifies that frame types are varint-62 encoded,
-// further stating that the shortest encoding must be used. The current set of
-// frame types all have values less than 0x40 (64) so can be encoded in a single
-// byte, with the two most significant bits being 0. Thus, the following
-// enumerations are valid as both the numeric values of frame types AND their
-// encodings.
-enum QuicIetfFrameType : uint64_t {
- IETF_PADDING = 0x00,
- IETF_PING = 0x01,
- IETF_ACK = 0x02,
- IETF_ACK_ECN = 0x03,
- IETF_RST_STREAM = 0x04,
- IETF_STOP_SENDING = 0x05,
- IETF_CRYPTO = 0x06,
- IETF_NEW_TOKEN = 0x07,
- // the low-3 bits of the stream frame type value are actually flags
- // declaring what parts of the frame are/are-not present, as well as
- // some other control information. The code would then do something
- // along the lines of "if ((frame_type & 0xf8) == 0x08)" to determine
- // whether the frame is a stream frame or not, and then examine each
- // bit specifically when/as needed.
- IETF_STREAM = 0x08,
- // 0x09 through 0x0f are various flag settings of the IETF_STREAM frame.
- IETF_MAX_DATA = 0x10,
- IETF_MAX_STREAM_DATA = 0x11,
- IETF_MAX_STREAMS_BIDIRECTIONAL = 0x12,
- IETF_MAX_STREAMS_UNIDIRECTIONAL = 0x13,
- IETF_DATA_BLOCKED = 0x14,
- IETF_STREAM_DATA_BLOCKED = 0x15,
- IETF_STREAMS_BLOCKED_BIDIRECTIONAL = 0x16,
- IETF_STREAMS_BLOCKED_UNIDIRECTIONAL = 0x17,
- IETF_NEW_CONNECTION_ID = 0x18,
- IETF_RETIRE_CONNECTION_ID = 0x19,
- IETF_PATH_CHALLENGE = 0x1a,
- IETF_PATH_RESPONSE = 0x1b,
- // Both of the following are "Connection Close" frames,
- // the first signals transport-layer errors, the second application-layer
- // errors.
- IETF_CONNECTION_CLOSE = 0x1c,
- IETF_APPLICATION_CLOSE = 0x1d,
-
- IETF_HANDSHAKE_DONE = 0x1e,
-
- // The MESSAGE frame type has not yet been fully standardized.
- // QUIC versions starting with 46 and before 99 use 0x20-0x21.
- // IETF QUIC (v99) uses 0x30-0x31, see draft-pauly-quic-datagram.
- IETF_EXTENSION_MESSAGE_NO_LENGTH = 0x20,
- IETF_EXTENSION_MESSAGE = 0x21,
- IETF_EXTENSION_MESSAGE_NO_LENGTH_V99 = 0x30,
- IETF_EXTENSION_MESSAGE_V99 = 0x31,
-
- // An QUIC extension frame for sender control of acknowledgement delays
- IETF_ACK_FREQUENCY = 0xaf,
-
- // A QUIC extension frame which augments the IETF_ACK frame definition with
- // packet receive timestamps.
- // TODO(ianswett): Determine a proper value to replace this temporary value.
- IETF_ACK_RECEIVE_TIMESTAMPS = 0x22,
-};
-QUIC_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
- const QuicIetfFrameType& c);
-QUIC_EXPORT_PRIVATE std::string QuicIetfFrameTypeString(QuicIetfFrameType t);
-
-// Masks for the bits that indicate the frame is a Stream frame vs the
-// bits used as flags.
-#define IETF_STREAM_FRAME_TYPE_MASK 0xfffffffffffffff8
-#define IETF_STREAM_FRAME_FLAG_MASK 0x07
-#define IS_IETF_STREAM_FRAME(_stype_) \
- (((_stype_)&IETF_STREAM_FRAME_TYPE_MASK) == IETF_STREAM)
-
-// These are the values encoded in the low-order 3 bits of the
-// IETF_STREAMx frame type.
-#define IETF_STREAM_FRAME_FIN_BIT 0x01
-#define IETF_STREAM_FRAME_LEN_BIT 0x02
-#define IETF_STREAM_FRAME_OFF_BIT 0x04
-
-enum QuicVariableLengthIntegerLength : uint8_t {
- // Length zero means the variable length integer is not present.
- VARIABLE_LENGTH_INTEGER_LENGTH_0 = 0,
- VARIABLE_LENGTH_INTEGER_LENGTH_1 = 1,
- VARIABLE_LENGTH_INTEGER_LENGTH_2 = 2,
- VARIABLE_LENGTH_INTEGER_LENGTH_4 = 4,
- VARIABLE_LENGTH_INTEGER_LENGTH_8 = 8,
-
- // By default we write the IETF long header length using the 2-byte encoding
- // of variable length integers, even when the length is below 64, which allows
- // us to fill in the length before knowing what the length actually is.
- kQuicDefaultLongHeaderLengthLength = VARIABLE_LENGTH_INTEGER_LENGTH_2,
-};
-
-enum QuicPacketNumberLength : uint8_t {
- PACKET_1BYTE_PACKET_NUMBER = 1,
- PACKET_2BYTE_PACKET_NUMBER = 2,
- PACKET_3BYTE_PACKET_NUMBER = 3, // Used in versions 45+.
- PACKET_4BYTE_PACKET_NUMBER = 4,
- IETF_MAX_PACKET_NUMBER_LENGTH = 4,
- // TODO(b/145819870): Remove 6 and 8 when we remove Q043 since these values
- // are not representable with later versions.
- PACKET_6BYTE_PACKET_NUMBER = 6,
- PACKET_8BYTE_PACKET_NUMBER = 8
-};
-
-// Used to indicate a QuicSequenceNumberLength using two flag bits.
-enum QuicPacketNumberLengthFlags {
- PACKET_FLAGS_1BYTE_PACKET = 0, // 00
- PACKET_FLAGS_2BYTE_PACKET = 1, // 01
- PACKET_FLAGS_4BYTE_PACKET = 1 << 1, // 10
- PACKET_FLAGS_8BYTE_PACKET = 1 << 1 | 1, // 11
-};
-
-// The public flags are specified in one byte.
-enum QuicPacketPublicFlags {
- PACKET_PUBLIC_FLAGS_NONE = 0,
-
- // Bit 0: Does the packet header contains version info?
- PACKET_PUBLIC_FLAGS_VERSION = 1 << 0,
-
- // Bit 1: Is this packet a public reset packet?
- PACKET_PUBLIC_FLAGS_RST = 1 << 1,
-
- // Bit 2: indicates the header includes a nonce.
- PACKET_PUBLIC_FLAGS_NONCE = 1 << 2,
-
- // Bit 3: indicates whether a ConnectionID is included.
- PACKET_PUBLIC_FLAGS_0BYTE_CONNECTION_ID = 0,
- PACKET_PUBLIC_FLAGS_8BYTE_CONNECTION_ID = 1 << 3,
-
- // Deprecated version 32 and earlier used two bits to indicate an 8-byte
- // connection ID. We send this from the client because of some broken
- // middleboxes that are still checking this bit.
- PACKET_PUBLIC_FLAGS_8BYTE_CONNECTION_ID_OLD = 1 << 3 | 1 << 2,
-
- // Bits 4 and 5 describe the packet number length as follows:
- // --00----: 1 byte
- // --01----: 2 bytes
- // --10----: 4 bytes
- // --11----: 6 bytes
- PACKET_PUBLIC_FLAGS_1BYTE_PACKET = PACKET_FLAGS_1BYTE_PACKET << 4,
- PACKET_PUBLIC_FLAGS_2BYTE_PACKET = PACKET_FLAGS_2BYTE_PACKET << 4,
- PACKET_PUBLIC_FLAGS_4BYTE_PACKET = PACKET_FLAGS_4BYTE_PACKET << 4,
- PACKET_PUBLIC_FLAGS_6BYTE_PACKET = PACKET_FLAGS_8BYTE_PACKET << 4,
-
- // Reserved, unimplemented flags:
-
- // Bit 7: indicates the presence of a second flags byte.
- PACKET_PUBLIC_FLAGS_TWO_OR_MORE_BYTES = 1 << 7,
-
- // All bits set (bits 6 and 7 are not currently used): 00111111
- PACKET_PUBLIC_FLAGS_MAX = (1 << 6) - 1,
-};
-
-// The private flags are specified in one byte.
-enum QuicPacketPrivateFlags {
- PACKET_PRIVATE_FLAGS_NONE = 0,
-
- // Bit 0: Does this packet contain an entropy bit?
- PACKET_PRIVATE_FLAGS_ENTROPY = 1 << 0,
-
- // (bits 1-7 are not used): 00000001
- PACKET_PRIVATE_FLAGS_MAX = (1 << 1) - 1
-};
-
-// Defines for all types of congestion control algorithms that can be used in
-// QUIC. Note that this is separate from the congestion feedback type -
-// some congestion control algorithms may use the same feedback type
-// (Reno and Cubic are the classic example for that).
-enum CongestionControlType {
- kCubicBytes,
- kRenoBytes,
- kBBR,
- kPCC,
- kGoogCC,
- kBBRv2,
-};
-
-// EncryptionLevel enumerates the stages of encryption that a QUIC connection
-// progresses through. When retransmitting a packet, the encryption level needs
-// to be specified so that it is retransmitted at a level which the peer can
-// understand.
-enum EncryptionLevel : int8_t {
- ENCRYPTION_INITIAL = 0,
- ENCRYPTION_HANDSHAKE = 1,
- ENCRYPTION_ZERO_RTT = 2,
- ENCRYPTION_FORWARD_SECURE = 3,
-
- NUM_ENCRYPTION_LEVELS,
-};
-
-inline bool EncryptionLevelIsValid(EncryptionLevel level) {
- return ENCRYPTION_INITIAL <= level && level < NUM_ENCRYPTION_LEVELS;
-}
-
-QUIC_EXPORT_PRIVATE std::string EncryptionLevelToString(EncryptionLevel level);
-
-QUIC_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
- EncryptionLevel level);
-
-// Enumeration of whether a server endpoint will request a client certificate,
-// and whether that endpoint requires a valid client certificate to establish a
-// connection.
-enum class ClientCertMode : uint8_t {
- kNone, // Do not request a client certificate. Default server behavior.
- kRequest, // Request a certificate, but allow unauthenticated connections.
- kRequire, // Require clients to provide a valid certificate.
-};
-
-QUIC_EXPORT_PRIVATE absl::string_view ClientCertModeToString(
- ClientCertMode mode);
-
-QUIC_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
- ClientCertMode mode);
-
-enum AddressChangeType : uint8_t {
- // IP address and port remain unchanged.
- NO_CHANGE,
- // Port changed, but IP address remains unchanged.
- PORT_CHANGE,
- // IPv4 address changed, but within the /24 subnet (port may have changed.)
- IPV4_SUBNET_CHANGE,
- // IPv4 address changed, excluding /24 subnet change (port may have changed.)
- IPV4_TO_IPV4_CHANGE,
- // IP address change from an IPv4 to an IPv6 address (port may have changed.)
- IPV4_TO_IPV6_CHANGE,
- // IP address change from an IPv6 to an IPv4 address (port may have changed.)
- IPV6_TO_IPV4_CHANGE,
- // IP address change from an IPv6 to an IPv6 address (port may have changed.)
- IPV6_TO_IPV6_CHANGE,
-};
-
-QUIC_EXPORT_PRIVATE std::string AddressChangeTypeToString(
- AddressChangeType type);
-
-QUIC_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
- AddressChangeType type);
-
-enum StreamSendingState {
- // Sender has more data to send on this stream.
- NO_FIN,
- // Sender is done sending on this stream.
- FIN,
- // Sender is done sending on this stream and random padding needs to be
- // appended after all stream frames.
- FIN_AND_PADDING,
-};
-
-enum SentPacketState : uint8_t {
- // The packet is in flight and waiting to be acked.
- OUTSTANDING,
- FIRST_PACKET_STATE = OUTSTANDING,
- // The packet was never sent.
- NEVER_SENT,
- // The packet has been acked.
- ACKED,
- // This packet is not expected to be acked.
- UNACKABLE,
- // This packet has been delivered or unneeded.
- NEUTERED,
-
- // States below are corresponding to retransmission types in TransmissionType.
-
- // This packet has been retransmitted when retransmission timer fires in
- // HANDSHAKE mode.
- 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.
- NOT_CONTRIBUTING_RTT,
- LAST_PACKET_STATE = NOT_CONTRIBUTING_RTT,
-};
-
-enum PacketHeaderFormat : uint8_t {
- IETF_QUIC_LONG_HEADER_PACKET,
- IETF_QUIC_SHORT_HEADER_PACKET,
- GOOGLE_QUIC_PACKET,
-};
-
-QUIC_EXPORT_PRIVATE std::string PacketHeaderFormatToString(
- PacketHeaderFormat format);
-
-// Information about a newly acknowledged packet.
-struct QUIC_EXPORT_PRIVATE AckedPacket {
- constexpr AckedPacket(QuicPacketNumber packet_number,
- QuicPacketLength bytes_acked,
- QuicTime receive_timestamp)
- : packet_number(packet_number),
- bytes_acked(bytes_acked),
- receive_timestamp(receive_timestamp) {}
-
- friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
- std::ostream& os, const AckedPacket& acked_packet);
-
- QuicPacketNumber packet_number;
- // Number of bytes sent in the packet that was acknowledged.
- QuicPacketLength bytes_acked;
- // The time |packet_number| was received by the peer, according to the
- // optional timestamp the peer included in the ACK frame which acknowledged
- // |packet_number|. Zero if no timestamp was available for this packet.
- QuicTime receive_timestamp;
-};
-
-// A vector of acked packets.
-using AckedPacketVector = absl::InlinedVector<AckedPacket, 2>;
-
-// Information about a newly lost packet.
-struct QUIC_EXPORT_PRIVATE LostPacket {
- LostPacket(QuicPacketNumber packet_number, QuicPacketLength bytes_lost)
- : packet_number(packet_number), bytes_lost(bytes_lost) {}
-
- friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
- std::ostream& os, const LostPacket& lost_packet);
-
- QuicPacketNumber packet_number;
- // Number of bytes sent in the packet that was lost.
- QuicPacketLength bytes_lost;
-};
-
-// A vector of lost packets.
-using LostPacketVector = absl::InlinedVector<LostPacket, 2>;
-
-// Please note, this value cannot used directly for packet serialization.
-enum QuicLongHeaderType : uint8_t {
- VERSION_NEGOTIATION,
- INITIAL,
- ZERO_RTT_PROTECTED,
- HANDSHAKE,
- RETRY,
-
- INVALID_PACKET_TYPE,
-};
-
-QUIC_EXPORT_PRIVATE std::string QuicLongHeaderTypeToString(
- QuicLongHeaderType type);
-
-enum QuicPacketHeaderTypeFlags : uint8_t {
- // Bit 2: Key phase bit for IETF QUIC short header packets.
- FLAGS_KEY_PHASE_BIT = 1 << 2,
- // Bit 3: Google QUIC Demultiplexing bit, the short header always sets this
- // bit to 0, allowing to distinguish Google QUIC packets from short header
- // packets.
- FLAGS_DEMULTIPLEXING_BIT = 1 << 3,
- // Bits 4 and 5: Reserved bits for short header.
- FLAGS_SHORT_HEADER_RESERVED_1 = 1 << 4,
- FLAGS_SHORT_HEADER_RESERVED_2 = 1 << 5,
- // Bit 6: the 'QUIC' bit.
- FLAGS_FIXED_BIT = 1 << 6,
- // Bit 7: Indicates the header is long or short header.
- FLAGS_LONG_HEADER = 1 << 7,
-};
-
-enum MessageStatus {
- MESSAGE_STATUS_SUCCESS,
- MESSAGE_STATUS_ENCRYPTION_NOT_ESTABLISHED, // Failed to send message because
- // encryption is not established
- // yet.
- MESSAGE_STATUS_UNSUPPORTED, // Failed to send message because MESSAGE frame
- // is not supported by the connection.
- MESSAGE_STATUS_BLOCKED, // Failed to send message because connection is
- // congestion control blocked or underlying socket is
- // write blocked.
- MESSAGE_STATUS_TOO_LARGE, // Failed to send message because the message is
- // too large to fit into a single packet.
- MESSAGE_STATUS_INTERNAL_ERROR, // Failed to send message because connection
- // reaches an invalid state.
-};
-
-QUIC_EXPORT_PRIVATE std::string MessageStatusToString(
- MessageStatus message_status);
-
-// Used to return the result of SendMessage calls
-struct QUIC_EXPORT_PRIVATE MessageResult {
- MessageResult(MessageStatus status, QuicMessageId message_id);
-
- bool operator==(const MessageResult& other) const {
- return status == other.status && message_id == other.message_id;
- }
-
- QUIC_EXPORT_PRIVATE friend std::ostream& operator<<(std::ostream& os,
- const MessageResult& mr);
-
- MessageStatus status;
- // Only valid when status is MESSAGE_STATUS_SUCCESS.
- QuicMessageId message_id;
-};
-
-QUIC_EXPORT_PRIVATE std::string MessageResultToString(
- MessageResult message_result);
-
-enum WriteStreamDataResult {
- WRITE_SUCCESS,
- STREAM_MISSING, // Trying to write data of a nonexistent stream (e.g.
- // closed).
- WRITE_FAILED, // Trying to write nonexistent data of a stream
-};
-
-enum StreamType : uint8_t {
- // Bidirectional streams allow for data to be sent in both directions.
- BIDIRECTIONAL,
-
- // Unidirectional streams carry data in one direction only.
- WRITE_UNIDIRECTIONAL,
- READ_UNIDIRECTIONAL,
- // Not actually a stream type. Used only by QuicCryptoStream when it uses
- // CRYPTO frames and isn't actually a QuicStream.
- CRYPTO,
-};
-
-// A packet number space is the context in which a packet can be processed and
-// acknowledged.
-enum PacketNumberSpace : uint8_t {
- INITIAL_DATA = 0, // Only used in IETF QUIC.
- HANDSHAKE_DATA = 1,
- APPLICATION_DATA = 2,
-
- NUM_PACKET_NUMBER_SPACES,
-};
-
-QUIC_EXPORT_PRIVATE std::string PacketNumberSpaceToString(
- PacketNumberSpace packet_number_space);
-
-// Used to return the result of processing a received ACK frame.
-enum AckResult {
- PACKETS_NEWLY_ACKED,
- NO_PACKETS_NEWLY_ACKED,
- UNSENT_PACKETS_ACKED, // Peer acks unsent packets.
- UNACKABLE_PACKETS_ACKED, // Peer acks packets that are not expected to be
- // acked. For example, encryption is reestablished,
- // and all sent encrypted packets cannot be
- // decrypted by the peer. Version gets negotiated,
- // and all sent packets in the different version
- // cannot be processed by the peer.
- PACKETS_ACKED_IN_WRONG_PACKET_NUMBER_SPACE,
-};
-
-// Indicates the fate of a serialized packet in WritePacket().
-enum SerializedPacketFate : uint8_t {
- DISCARD, // Discard the packet.
- COALESCE, // Try to coalesce packet.
- BUFFER, // Buffer packet in buffered_packets_.
- SEND_TO_WRITER, // Send packet to writer.
- LEGACY_VERSION_ENCAPSULATE, // Perform Legacy Version Encapsulation on this
- // packet.
-};
-
-QUIC_EXPORT_PRIVATE std::string SerializedPacketFateToString(
- SerializedPacketFate fate);
-
-QUIC_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
- const SerializedPacketFate fate);
-
-// There are three different forms of CONNECTION_CLOSE.
-enum QuicConnectionCloseType {
- GOOGLE_QUIC_CONNECTION_CLOSE = 0,
- IETF_QUIC_TRANSPORT_CONNECTION_CLOSE = 1,
- IETF_QUIC_APPLICATION_CONNECTION_CLOSE = 2
-};
-
-QUIC_EXPORT_PRIVATE std::ostream& operator<<(
- std::ostream& os, const QuicConnectionCloseType type);
-
-QUIC_EXPORT_PRIVATE std::string QuicConnectionCloseTypeString(
- QuicConnectionCloseType type);
-
-// Indicate handshake state of a connection.
-enum HandshakeState {
- // Initial state.
- HANDSHAKE_START,
- // Only used in IETF QUIC with TLS handshake. State proceeds to
- // HANDSHAKE_PROCESSED after a packet of HANDSHAKE packet number space
- // gets successfully processed, and the initial key can be dropped.
- HANDSHAKE_PROCESSED,
- // In QUIC crypto, state proceeds to HANDSHAKE_COMPLETE if client receives
- // SHLO or server successfully processes an ENCRYPTION_FORWARD_SECURE
- // packet, such that the handshake packets can be neutered. In IETF QUIC
- // with TLS handshake, state proceeds to HANDSHAKE_COMPLETE once the client
- // has both 1-RTT send and receive keys.
- HANDSHAKE_COMPLETE,
- // Only used in IETF QUIC with TLS handshake. State proceeds to
- // HANDSHAKE_CONFIRMED if 1) a client receives HANDSHAKE_DONE frame or
- // acknowledgment for 1-RTT packet or 2) server has
- // 1-RTT send and receive keys.
- HANDSHAKE_CONFIRMED,
-};
-
-struct QUIC_NO_EXPORT NextReleaseTimeResult {
- // The ideal release time of the packet being sent.
- QuicTime release_time;
- // Whether it is allowed to send the packet before release_time.
- bool allow_burst;
-};
-
-// QuicPacketBuffer bundles a buffer and a function that releases it. Note
-// it does not assume ownership of buffer, i.e. it doesn't release the buffer on
-// destruction.
-struct QUIC_NO_EXPORT QuicPacketBuffer {
- QuicPacketBuffer() = default;
-
- QuicPacketBuffer(char* buffer,
- std::function<void(const char*)> release_buffer)
- : buffer(buffer), release_buffer(std::move(release_buffer)) {}
-
- char* buffer = nullptr;
- std::function<void(const char*)> release_buffer;
-};
-
-// QuicOwnedPacketBuffer is a QuicPacketBuffer that assumes buffer ownership.
-struct QUIC_NO_EXPORT QuicOwnedPacketBuffer : public QuicPacketBuffer {
- QuicOwnedPacketBuffer(const QuicOwnedPacketBuffer&) = delete;
- QuicOwnedPacketBuffer& operator=(const QuicOwnedPacketBuffer&) = delete;
-
- QuicOwnedPacketBuffer(char* buffer,
- std::function<void(const char*)> release_buffer)
- : QuicPacketBuffer(buffer, std::move(release_buffer)) {}
-
- QuicOwnedPacketBuffer(QuicOwnedPacketBuffer&& owned_buffer)
- : QuicPacketBuffer(std::move(owned_buffer)) {
- // |owned_buffer| does not own a buffer any more.
- owned_buffer.buffer = nullptr;
- }
-
- explicit QuicOwnedPacketBuffer(QuicPacketBuffer&& packet_buffer)
- : QuicPacketBuffer(std::move(packet_buffer)) {}
-
- ~QuicOwnedPacketBuffer() {
- if (release_buffer != nullptr && buffer != nullptr) {
- release_buffer(buffer);
- }
- }
-};
-
-// These values must remain stable as they are uploaded to UMA histograms.
-enum class KeyUpdateReason {
- kInvalid = 0,
- kRemote = 1,
- kLocalForTests = 2,
- kLocalForInteropRunner = 3,
- kLocalAeadConfidentialityLimit = 4,
- kLocalKeyUpdateLimitOverride = 5,
- kMaxValue = kLocalKeyUpdateLimitOverride,
-};
-
-QUIC_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
- const KeyUpdateReason reason);
-
-QUIC_EXPORT_PRIVATE std::string KeyUpdateReasonString(KeyUpdateReason reason);
-
-// QuicSSLConfig contains configurations to be applied on a SSL object, which
-// overrides the configurations in SSL_CTX.
-struct QUIC_NO_EXPORT QuicSSLConfig {
- // Whether TLS early data should be enabled. If not set, default to enabled.
- absl::optional<bool> early_data_enabled;
- // Whether TLS session tickets are supported. If not set, default to
- // supported.
- 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;
- // Client certificate mode for mTLS support. Only used at server side.
- ClientCertMode client_cert_mode = ClientCertMode::kNone;
-};
-
-// QuicDelayedSSLConfig contains a subset of SSL config that can be applied
-// after BoringSSL's early select certificate callback. This overwrites all SSL
-// configs applied before cert selection.
-struct QUIC_NO_EXPORT QuicDelayedSSLConfig {
- // Client certificate mode for mTLS support. Only used at server side.
- // absl::nullopt means do not change client certificate mode.
- absl::optional<ClientCertMode> client_cert_mode;
-};
-
-// ParsedClientHello contains client hello information extracted from a fully
-// received client hello.
-struct QUIC_NO_EXPORT ParsedClientHello {
- std::string sni; // QUIC crypto and TLS.
- std::string uaid; // QUIC crypto only.
- std::vector<std::string> alpns; // QUIC crypto and TLS.
- std::string legacy_version_encapsulation_inner_packet; // QUIC crypto only.
- // The unvalidated retry token from the last received packet of a potentially
- // multi-packet client hello. TLS only.
- std::string retry_token;
- bool resumption_attempted = false; // TLS only.
- bool early_data_attempted = false; // TLS only.
-};
-
-QUIC_EXPORT_PRIVATE bool operator==(const ParsedClientHello& a,
- const ParsedClientHello& b);
-
-QUIC_EXPORT_PRIVATE std::ostream& operator<<(
- std::ostream& os, const ParsedClientHello& parsed_chlo);
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_QUIC_TYPES_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_udp_socket.h b/chromium/net/third_party/quiche/src/quic/core/quic_udp_socket.h
deleted file mode 100644
index 534273c1d5f..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_udp_socket.h
+++ /dev/null
@@ -1,253 +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_CORE_QUIC_UDP_SOCKET_H_
-#define QUICHE_QUIC_CORE_QUIC_UDP_SOCKET_H_
-
-#include <cstddef>
-#include <cstdint>
-
-#include <type_traits>
-
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_ip_address.h"
-#include "quic/platform/api/quic_socket_address.h"
-
-namespace quic {
-
-#if defined(_WIN32)
-using QuicUdpSocketFd = SOCKET;
-const QuicUdpSocketFd kQuicInvalidSocketFd = INVALID_SOCKET;
-#else
-using QuicUdpSocketFd = int;
-const QuicUdpSocketFd kQuicInvalidSocketFd = -1;
-#endif
-
-const size_t kDefaultUdpPacketControlBufferSize = 512;
-
-enum class QuicUdpPacketInfoBit : uint8_t {
- DROPPED_PACKETS = 0, // Read
- V4_SELF_IP, // Read
- V6_SELF_IP, // Read
- PEER_ADDRESS, // Read & Write
- RECV_TIMESTAMP, // Read
- TTL, // Read & Write
- GOOGLE_PACKET_HEADER, // Read
- NUM_BITS,
-};
-static_assert(static_cast<size_t>(QuicUdpPacketInfoBit::NUM_BITS) <=
- BitMask64::NumBits(),
- "BitMask64 not wide enough to hold all bits.");
-
-// BufferSpan points to an unowned buffer, copying this structure only copies
-// the pointer and length, not the buffer itself.
-struct QUIC_EXPORT_PRIVATE BufferSpan {
- BufferSpan(char* buffer, size_t buffer_len)
- : buffer(buffer), buffer_len(buffer_len) {}
-
- BufferSpan() = default;
- BufferSpan(const BufferSpan& other) = default;
- BufferSpan& operator=(const BufferSpan& other) = default;
-
- char* buffer = nullptr;
- size_t buffer_len = 0;
-};
-
-// QuicUdpPacketInfo contains per-packet information used for sending and
-// receiving.
-class QUIC_EXPORT_PRIVATE QuicUdpPacketInfo {
- public:
- BitMask64 bitmask() const { return bitmask_; }
-
- void Reset() { bitmask_.ClearAll(); }
-
- bool HasValue(QuicUdpPacketInfoBit bit) const { return bitmask_.IsSet(bit); }
-
- QuicPacketCount dropped_packets() const {
- QUICHE_DCHECK(HasValue(QuicUdpPacketInfoBit::DROPPED_PACKETS));
- return dropped_packets_;
- }
-
- void SetDroppedPackets(QuicPacketCount dropped_packets) {
- dropped_packets_ = dropped_packets;
- bitmask_.Set(QuicUdpPacketInfoBit::DROPPED_PACKETS);
- }
-
- const QuicIpAddress& self_v4_ip() const {
- QUICHE_DCHECK(HasValue(QuicUdpPacketInfoBit::V4_SELF_IP));
- return self_v4_ip_;
- }
-
- void SetSelfV4Ip(QuicIpAddress self_v4_ip) {
- self_v4_ip_ = self_v4_ip;
- bitmask_.Set(QuicUdpPacketInfoBit::V4_SELF_IP);
- }
-
- const QuicIpAddress& self_v6_ip() const {
- QUICHE_DCHECK(HasValue(QuicUdpPacketInfoBit::V6_SELF_IP));
- return self_v6_ip_;
- }
-
- void SetSelfV6Ip(QuicIpAddress self_v6_ip) {
- self_v6_ip_ = self_v6_ip;
- bitmask_.Set(QuicUdpPacketInfoBit::V6_SELF_IP);
- }
-
- void SetSelfIp(QuicIpAddress self_ip) {
- if (self_ip.IsIPv4()) {
- SetSelfV4Ip(self_ip);
- } else {
- SetSelfV6Ip(self_ip);
- }
- }
-
- const QuicSocketAddress& peer_address() const {
- QUICHE_DCHECK(HasValue(QuicUdpPacketInfoBit::PEER_ADDRESS));
- return peer_address_;
- }
-
- void SetPeerAddress(QuicSocketAddress peer_address) {
- peer_address_ = peer_address;
- bitmask_.Set(QuicUdpPacketInfoBit::PEER_ADDRESS);
- }
-
- QuicWallTime receive_timestamp() const {
- QUICHE_DCHECK(HasValue(QuicUdpPacketInfoBit::RECV_TIMESTAMP));
- return receive_timestamp_;
- }
-
- void SetReceiveTimestamp(QuicWallTime receive_timestamp) {
- receive_timestamp_ = receive_timestamp;
- bitmask_.Set(QuicUdpPacketInfoBit::RECV_TIMESTAMP);
- }
-
- int ttl() const {
- QUICHE_DCHECK(HasValue(QuicUdpPacketInfoBit::TTL));
- return ttl_;
- }
-
- void SetTtl(int ttl) {
- ttl_ = ttl;
- bitmask_.Set(QuicUdpPacketInfoBit::TTL);
- }
-
- BufferSpan google_packet_headers() const {
- QUICHE_DCHECK(HasValue(QuicUdpPacketInfoBit::GOOGLE_PACKET_HEADER));
- return google_packet_headers_;
- }
-
- void SetGooglePacketHeaders(BufferSpan google_packet_headers) {
- google_packet_headers_ = google_packet_headers;
- bitmask_.Set(QuicUdpPacketInfoBit::GOOGLE_PACKET_HEADER);
- }
-
- private:
- BitMask64 bitmask_;
- QuicPacketCount dropped_packets_;
- QuicIpAddress self_v4_ip_;
- QuicIpAddress self_v6_ip_;
- QuicSocketAddress peer_address_;
- QuicWallTime receive_timestamp_ = QuicWallTime::Zero();
- int ttl_;
- BufferSpan google_packet_headers_;
-};
-
-// QuicUdpSocketApi provides a minimal set of apis for sending and receiving
-// udp packets. The low level udp socket apis differ between kernels and kernel
-// versions, the goal of QuicUdpSocketApi is to hide such differences.
-// We use non-static functions because it is easier to be mocked in tests when
-// needed.
-class QUIC_EXPORT_PRIVATE QuicUdpSocketApi {
- public:
- // Creates a non-blocking udp socket, sets the receive/send buffer and enable
- // receiving of self ip addresses on read.
- // If address_family == AF_INET6 and ipv6_only is true, receiving of IPv4 self
- // addresses is disabled. This is only necessary for IPv6 sockets on iOS - all
- // other platforms can ignore this parameter. Return kQuicInvalidSocketFd if
- // failed.
- QuicUdpSocketFd Create(int address_family,
- int receive_buffer_size,
- int send_buffer_size,
- bool ipv6_only = false);
-
- // Closes |fd|. No-op if |fd| equals to kQuicInvalidSocketFd.
- void Destroy(QuicUdpSocketFd fd);
-
- // Bind |fd| to |address|. If |address|'s port number is 0, kernel will choose
- // a random port to bind to. Caller can use QuicSocketAddress::FromSocket(fd)
- // to get the bound random port.
- bool Bind(QuicUdpSocketFd fd, QuicSocketAddress address);
-
- // Enable receiving of various per-packet information. Return true if the
- // corresponding information can be received on read.
- bool EnableDroppedPacketCount(QuicUdpSocketFd fd);
- bool EnableReceiveTimestamp(QuicUdpSocketFd fd);
- bool EnableReceiveTtlForV4(QuicUdpSocketFd fd);
- bool EnableReceiveTtlForV6(QuicUdpSocketFd fd);
-
- // Wait for |fd| to become readable, up to |timeout|.
- // Return true if |fd| is readable upon return.
- bool WaitUntilReadable(QuicUdpSocketFd fd, QuicTime::Delta timeout);
-
- struct QUIC_EXPORT_PRIVATE ReadPacketResult {
- bool ok = false;
- QuicUdpPacketInfo packet_info;
- BufferSpan packet_buffer;
- BufferSpan control_buffer;
-
- void Reset(size_t packet_buffer_length) {
- ok = false;
- packet_info.Reset();
- packet_buffer.buffer_len = packet_buffer_length;
- }
- };
- // Read a packet from |fd|:
- // packet_info_interested: Bitmask indicating what information caller wants to
- // receive into |result->packet_info|.
- // result->packet_info: Received per packet information.
- // result->packet_buffer: The packet buffer, to be filled with packet data.
- // |result->packet_buffer.buffer_len| is set to the
- // packet length on a successful return.
- // result->control_buffer: The control buffer, used by ReadPacket internally.
- // It is recommended to be
- // |kDefaultUdpPacketControlBufferSize| bytes.
- // result->ok: True iff a packet is successfully received.
- //
- // If |*result| is reused for subsequent ReadPacket() calls, caller needs to
- // call result->Reset() before each ReadPacket().
- void ReadPacket(QuicUdpSocketFd fd,
- BitMask64 packet_info_interested,
- ReadPacketResult* result);
-
- using ReadPacketResults = std::vector<ReadPacketResult>;
- // Read up to |results->size()| packets from |fd|. The meaning of each element
- // in |*results| has been documented on top of |ReadPacket|.
- // Return the number of elements populated into |*results|, note it is
- // possible for some of the populated elements to have ok=false.
- size_t ReadMultiplePackets(QuicUdpSocketFd fd,
- BitMask64 packet_info_interested,
- ReadPacketResults* results);
-
- // Write a packet to |fd|.
- // packet_buffer, packet_buffer_len: The packet buffer to write.
- // packet_info: The per packet information to set.
- WriteResult WritePacket(QuicUdpSocketFd fd,
- const char* packet_buffer,
- size_t packet_buffer_len,
- const QuicUdpPacketInfo& packet_info);
-
- protected:
- bool SetupSocket(QuicUdpSocketFd fd,
- int address_family,
- int receive_buffer_size,
- int send_buffer_size,
- bool ipv6_only);
- bool EnableReceiveSelfIpAddressForV4(QuicUdpSocketFd fd);
- bool EnableReceiveSelfIpAddressForV6(QuicUdpSocketFd fd);
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_QUIC_UDP_SOCKET_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_udp_socket_posix.cc b/chromium/net/third_party/quiche/src/quic/core/quic_udp_socket_posix.cc
deleted file mode 100644
index eef582b99f1..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_udp_socket_posix.cc
+++ /dev/null
@@ -1,639 +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 "quic/core/quic_udp_socket.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_udp_socket_platform_api.h"
-
-#include <arpa/inet.h>
-#include <fcntl.h>
-#include <netinet/in.h>
-#include <sys/select.h>
-#include <sys/socket.h>
-#include <sys/types.h>
-
-#if defined(__APPLE__) && !defined(__APPLE_USE_RFC_3542)
-#error "__APPLE_USE_RFC_3542 needs to be defined."
-#endif
-
-#if defined(__linux__)
-#include <alloca.h>
-// For SO_TIMESTAMPING.
-#include <linux/net_tstamp.h>
-#endif
-
-#if defined(__linux__) && !defined(__ANDROID__)
-#define QUIC_UDP_SOCKET_SUPPORT_TTL 1
-#endif
-
-namespace quic {
-namespace {
-
-#if defined(__linux__) && (!defined(__ANDROID_API__) || __ANDROID_API__ >= 21)
-#define QUIC_UDP_SOCKET_SUPPORT_LINUX_TIMESTAMPING 1
-// This is the structure that SO_TIMESTAMPING fills into the cmsg header.
-// It is well-defined, but does not have a definition in a public header.
-// See https://www.kernel.org/doc/Documentation/networking/timestamping.txt
-// for more information.
-struct LinuxSoTimestamping {
- // The converted system time of the timestamp.
- struct timespec systime;
- // Deprecated; serves only as padding.
- struct timespec hwtimetrans;
- // The raw hardware timestamp.
- struct timespec hwtimeraw;
-};
-const size_t kCmsgSpaceForRecvTimestamp =
- CMSG_SPACE(sizeof(LinuxSoTimestamping));
-#else
-const size_t kCmsgSpaceForRecvTimestamp = 0;
-#endif
-
-const size_t kMinCmsgSpaceForRead =
- CMSG_SPACE(sizeof(uint32_t)) // Dropped packet count
- + CMSG_SPACE(sizeof(in_pktinfo)) // V4 Self IP
- + CMSG_SPACE(sizeof(in6_pktinfo)) // V6 Self IP
- + kCmsgSpaceForRecvTimestamp + CMSG_SPACE(sizeof(int)) // TTL
- + kCmsgSpaceForGooglePacketHeader;
-
-QuicUdpSocketFd CreateNonblockingSocket(int address_family) {
-#if defined(__linux__) && defined(SOCK_NONBLOCK)
-
- // Create a nonblocking socket directly.
- int fd = socket(address_family, SOCK_DGRAM | SOCK_NONBLOCK, IPPROTO_UDP);
- if (fd < 0) {
- QUIC_LOG_FIRST_N(ERROR, 100)
- << "socket() failed with address_family=" << address_family << ": "
- << strerror(errno);
- return kQuicInvalidSocketFd;
- }
-#else
- // Create a socket and use fcntl to set it to nonblocking.
- // This implementation is used when building for iOS, OSX and old versions of
- // Linux (< 2.6.27) and old versions of Android (< API 21).
- int fd = socket(address_family, SOCK_DGRAM, IPPROTO_UDP);
- if (fd < 0) {
- QUIC_LOG_FIRST_N(ERROR, 100)
- << "socket() failed with address_family=" << address_family << ": "
- << strerror(errno);
- return kQuicInvalidSocketFd;
- }
- int current_flags = fcntl(fd, F_GETFL, 0);
- if (current_flags == -1) {
- QUIC_LOG_FIRST_N(ERROR, 100)
- << "failed to get current socket flags: " << strerror(errno);
- close(fd);
- return kQuicInvalidSocketFd;
- }
-
- int rc = fcntl(fd, F_SETFL, current_flags | O_NONBLOCK);
- if (rc == -1) {
- QUIC_LOG_FIRST_N(ERROR, 100)
- << "failed to set socket to non-blocking: " << strerror(errno);
- close(fd);
- return kQuicInvalidSocketFd;
- }
-#endif
-
- SetGoogleSocketOptions(fd);
- return fd;
-} // End CreateNonblockingSocket
-
-void SetV4SelfIpInControlMessage(const QuicIpAddress& self_address,
- cmsghdr* cmsg) {
- QUICHE_DCHECK(self_address.IsIPv4());
- in_pktinfo* pktinfo = reinterpret_cast<in_pktinfo*>(CMSG_DATA(cmsg));
- memset(pktinfo, 0, sizeof(in_pktinfo));
- pktinfo->ipi_ifindex = 0;
- std::string address_string = self_address.ToPackedString();
- memcpy(&pktinfo->ipi_spec_dst, address_string.c_str(),
- address_string.length());
-}
-
-void SetV6SelfIpInControlMessage(const QuicIpAddress& self_address,
- cmsghdr* cmsg) {
- QUICHE_DCHECK(self_address.IsIPv6());
- in6_pktinfo* pktinfo = reinterpret_cast<in6_pktinfo*>(CMSG_DATA(cmsg));
- memset(pktinfo, 0, sizeof(in6_pktinfo));
- std::string address_string = self_address.ToPackedString();
- memcpy(&pktinfo->ipi6_addr, address_string.c_str(), address_string.length());
-}
-
-void PopulatePacketInfoFromControlMessage(struct cmsghdr* cmsg,
- QuicUdpPacketInfo* packet_info,
- BitMask64 packet_info_interested) {
-#if defined(__linux__) && defined(SO_RXQ_OVFL)
- if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SO_RXQ_OVFL) {
- if (packet_info_interested.IsSet(QuicUdpPacketInfoBit::DROPPED_PACKETS)) {
- packet_info->SetDroppedPackets(
- *(reinterpret_cast<uint32_t*> CMSG_DATA(cmsg)));
- }
- return;
- }
-#endif
-
-#if defined(QUIC_UDP_SOCKET_SUPPORT_LINUX_TIMESTAMPING)
- if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SO_TIMESTAMPING) {
- if (packet_info_interested.IsSet(QuicUdpPacketInfoBit::RECV_TIMESTAMP)) {
- LinuxSoTimestamping* linux_ts =
- reinterpret_cast<LinuxSoTimestamping*>(CMSG_DATA(cmsg));
- timespec* ts = &linux_ts->systime;
- int64_t usec = (static_cast<int64_t>(ts->tv_sec) * 1000 * 1000) +
- (static_cast<int64_t>(ts->tv_nsec) / 1000);
- packet_info->SetReceiveTimestamp(
- QuicWallTime::FromUNIXMicroseconds(usec));
- }
- return;
- }
-#endif
-
- if (cmsg->cmsg_level == IPPROTO_IPV6 && cmsg->cmsg_type == IPV6_PKTINFO) {
- if (packet_info_interested.IsSet(QuicUdpPacketInfoBit::V6_SELF_IP)) {
- const in6_pktinfo* info = reinterpret_cast<in6_pktinfo*>(CMSG_DATA(cmsg));
- const char* addr_data = reinterpret_cast<const char*>(&info->ipi6_addr);
- int addr_len = sizeof(in6_addr);
- QuicIpAddress self_v6_ip;
- if (self_v6_ip.FromPackedString(addr_data, addr_len)) {
- packet_info->SetSelfV6Ip(self_v6_ip);
- } else {
- QUIC_BUG(quic_bug_10751_1) << "QuicIpAddress::FromPackedString failed";
- }
- }
- return;
- }
-
- if (cmsg->cmsg_level == IPPROTO_IP && cmsg->cmsg_type == IP_PKTINFO) {
- if (packet_info_interested.IsSet(QuicUdpPacketInfoBit::V4_SELF_IP)) {
- const in_pktinfo* info = reinterpret_cast<in_pktinfo*>(CMSG_DATA(cmsg));
- const char* addr_data = reinterpret_cast<const char*>(&info->ipi_addr);
- int addr_len = sizeof(in_addr);
- QuicIpAddress self_v4_ip;
- if (self_v4_ip.FromPackedString(addr_data, addr_len)) {
- packet_info->SetSelfV4Ip(self_v4_ip);
- } else {
- QUIC_BUG(quic_bug_10751_2) << "QuicIpAddress::FromPackedString failed";
- }
- }
- return;
- }
-
- if ((cmsg->cmsg_level == IPPROTO_IP && cmsg->cmsg_type == IP_TTL) ||
- (cmsg->cmsg_level == IPPROTO_IPV6 && cmsg->cmsg_type == IPV6_HOPLIMIT)) {
- if (packet_info_interested.IsSet(QuicUdpPacketInfoBit::TTL)) {
- packet_info->SetTtl(*(reinterpret_cast<int*>(CMSG_DATA(cmsg))));
- }
- return;
- }
-
- if (packet_info_interested.IsSet(
- QuicUdpPacketInfoBit::GOOGLE_PACKET_HEADER)) {
- BufferSpan google_packet_headers;
- if (GetGooglePacketHeadersFromControlMessage(
- cmsg, &google_packet_headers.buffer,
- &google_packet_headers.buffer_len)) {
- packet_info->SetGooglePacketHeaders(google_packet_headers);
- }
- }
-}
-
-bool NextCmsg(msghdr* hdr,
- char* control_buffer,
- size_t control_buffer_len,
- int cmsg_level,
- int cmsg_type,
- size_t data_size,
- cmsghdr** cmsg /*in, out*/) {
- // msg_controllen needs to be increased first, otherwise CMSG_NXTHDR will
- // return nullptr.
- hdr->msg_controllen += CMSG_SPACE(data_size);
- if (hdr->msg_controllen > control_buffer_len) {
- return false;
- }
-
- if ((*cmsg) == nullptr) {
- QUICHE_DCHECK_EQ(nullptr, hdr->msg_control);
- memset(control_buffer, 0, control_buffer_len);
- hdr->msg_control = control_buffer;
- (*cmsg) = CMSG_FIRSTHDR(hdr);
- } else {
- QUICHE_DCHECK_NE(nullptr, hdr->msg_control);
- (*cmsg) = CMSG_NXTHDR(hdr, (*cmsg));
- }
-
- if (nullptr == (*cmsg)) {
- return false;
- }
-
- (*cmsg)->cmsg_len = CMSG_LEN(data_size);
- (*cmsg)->cmsg_level = cmsg_level;
- (*cmsg)->cmsg_type = cmsg_type;
-
- return true;
-}
-} // namespace
-
-QuicUdpSocketFd QuicUdpSocketApi::Create(int address_family,
- int receive_buffer_size,
- int send_buffer_size,
- bool ipv6_only) {
- // QUICHE_DCHECK here so the program exits early(before reading packets) in
- // debug mode. This should have been a static_assert, however it can't be done
- // on ios/osx because CMSG_SPACE isn't a constant expression there.
- QUICHE_DCHECK_GE(kDefaultUdpPacketControlBufferSize, kMinCmsgSpaceForRead);
- QuicUdpSocketFd fd = CreateNonblockingSocket(address_family);
-
- if (fd == kQuicInvalidSocketFd) {
- return kQuicInvalidSocketFd;
- }
-
- if (!SetupSocket(fd, address_family, receive_buffer_size, send_buffer_size,
- ipv6_only)) {
- Destroy(fd);
- return kQuicInvalidSocketFd;
- }
-
- return fd;
-}
-
-bool QuicUdpSocketApi::SetupSocket(QuicUdpSocketFd fd,
- int address_family,
- int receive_buffer_size,
- int send_buffer_size,
- bool ipv6_only) {
- // Receive buffer size.
- if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &receive_buffer_size,
- sizeof(receive_buffer_size)) != 0) {
- QUIC_LOG_FIRST_N(ERROR, 100) << "Failed to set socket recv size";
- return false;
- }
-
- // Send buffer size.
- if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &send_buffer_size,
- sizeof(send_buffer_size)) != 0) {
- QUIC_LOG_FIRST_N(ERROR, 100) << "Failed to set socket send size";
- return false;
- }
-
- if (!(address_family == AF_INET6 && ipv6_only)) {
- if (!EnableReceiveSelfIpAddressForV4(fd)) {
- QUIC_LOG_FIRST_N(ERROR, 100)
- << "Failed to enable receiving of self v4 ip";
- return false;
- }
- }
-
- if (address_family == AF_INET6) {
- if (!EnableReceiveSelfIpAddressForV6(fd)) {
- QUIC_LOG_FIRST_N(ERROR, 100)
- << "Failed to enable receiving of self v6 ip";
- return false;
- }
- }
-
- return true;
-}
-
-void QuicUdpSocketApi::Destroy(QuicUdpSocketFd fd) {
- if (fd != kQuicInvalidSocketFd) {
- close(fd);
- }
-}
-
-bool QuicUdpSocketApi::Bind(QuicUdpSocketFd fd, QuicSocketAddress address) {
- sockaddr_storage addr = address.generic_address();
- int addr_len =
- address.host().IsIPv4() ? sizeof(sockaddr_in) : sizeof(sockaddr_in6);
- return 0 == bind(fd, reinterpret_cast<sockaddr*>(&addr), addr_len);
-}
-
-bool QuicUdpSocketApi::EnableDroppedPacketCount(QuicUdpSocketFd fd) {
-#if defined(__linux__) && defined(SO_RXQ_OVFL)
- int get_overflow = 1;
- return 0 == setsockopt(fd, SOL_SOCKET, SO_RXQ_OVFL, &get_overflow,
- sizeof(get_overflow));
-#else
- (void)fd;
- return false;
-#endif
-}
-
-bool QuicUdpSocketApi::EnableReceiveSelfIpAddressForV4(QuicUdpSocketFd fd) {
- int get_self_ip = 1;
- return 0 == setsockopt(fd, IPPROTO_IP, IP_PKTINFO, &get_self_ip,
- sizeof(get_self_ip));
-}
-
-bool QuicUdpSocketApi::EnableReceiveSelfIpAddressForV6(QuicUdpSocketFd fd) {
- int get_self_ip = 1;
- return 0 == setsockopt(fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, &get_self_ip,
- sizeof(get_self_ip));
-}
-
-bool QuicUdpSocketApi::EnableReceiveTimestamp(QuicUdpSocketFd fd) {
-#if defined(__linux__) && (!defined(__ANDROID_API__) || __ANDROID_API__ >= 21)
- int timestamping = SOF_TIMESTAMPING_RX_SOFTWARE | SOF_TIMESTAMPING_SOFTWARE;
- return 0 == setsockopt(fd, SOL_SOCKET, SO_TIMESTAMPING, &timestamping,
- sizeof(timestamping));
-#else
- (void)fd;
- return false;
-#endif
-}
-
-bool QuicUdpSocketApi::EnableReceiveTtlForV4(QuicUdpSocketFd fd) {
-#if defined(QUIC_UDP_SOCKET_SUPPORT_TTL)
- int get_ttl = 1;
- return 0 == setsockopt(fd, IPPROTO_IP, IP_RECVTTL, &get_ttl, sizeof(get_ttl));
-#else
- (void)fd;
- return false;
-#endif
-}
-
-bool QuicUdpSocketApi::EnableReceiveTtlForV6(QuicUdpSocketFd fd) {
-#if defined(QUIC_UDP_SOCKET_SUPPORT_TTL)
- int get_ttl = 1;
- return 0 == setsockopt(fd, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, &get_ttl,
- sizeof(get_ttl));
-#else
- (void)fd;
- return false;
-#endif
-}
-
-bool QuicUdpSocketApi::WaitUntilReadable(QuicUdpSocketFd fd,
- QuicTime::Delta timeout) {
- fd_set read_fds;
- FD_ZERO(&read_fds);
- FD_SET(fd, &read_fds);
-
- timeval select_timeout;
- select_timeout.tv_sec = timeout.ToSeconds();
- select_timeout.tv_usec = timeout.ToMicroseconds() % 1000000;
-
- return 1 == select(1 + fd, &read_fds, nullptr, nullptr, &select_timeout);
-}
-
-void QuicUdpSocketApi::ReadPacket(QuicUdpSocketFd fd,
- BitMask64 packet_info_interested,
- ReadPacketResult* result) {
- result->ok = false;
- BufferSpan& packet_buffer = result->packet_buffer;
- BufferSpan& control_buffer = result->control_buffer;
- QuicUdpPacketInfo* packet_info = &result->packet_info;
-
- QUICHE_DCHECK_GE(control_buffer.buffer_len, kMinCmsgSpaceForRead);
-
- struct iovec iov = {packet_buffer.buffer, packet_buffer.buffer_len};
- struct sockaddr_storage raw_peer_address;
-
- if (control_buffer.buffer_len > 0) {
- reinterpret_cast<struct cmsghdr*>(control_buffer.buffer)->cmsg_len =
- control_buffer.buffer_len;
- }
-
- msghdr hdr;
- hdr.msg_name = &raw_peer_address;
- hdr.msg_namelen = sizeof(raw_peer_address);
- hdr.msg_iov = &iov;
- hdr.msg_iovlen = 1;
- hdr.msg_flags = 0;
- hdr.msg_control = control_buffer.buffer;
- hdr.msg_controllen = control_buffer.buffer_len;
-
-#if defined(__linux__)
- // If MSG_TRUNC is set on Linux, recvmsg will return the real packet size even
- // if |packet_buffer| is too small to receive it.
- int flags = MSG_TRUNC;
-#else
- int flags = 0;
-#endif
-
- int bytes_read = recvmsg(fd, &hdr, flags);
- if (bytes_read < 0) {
- const int error_num = errno;
- if (error_num != EAGAIN) {
- QUIC_LOG_FIRST_N(ERROR, 100)
- << "Error reading packet: " << strerror(error_num);
- }
- return;
- }
-
- if (QUIC_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) ||
- // 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) {
- QUIC_LOG_FIRST_N(WARNING, 100)
- << "Received truncated QUIC packet: buffer size:"
- << packet_buffer.buffer_len << " packet size:" << bytes_read;
- return;
- }
-
- packet_buffer.buffer_len = bytes_read;
- if (packet_info_interested.IsSet(QuicUdpPacketInfoBit::PEER_ADDRESS)) {
- packet_info->SetPeerAddress(QuicSocketAddress(raw_peer_address));
- }
-
- if (hdr.msg_controllen > 0) {
- for (struct cmsghdr* cmsg = CMSG_FIRSTHDR(&hdr); cmsg != nullptr;
- cmsg = CMSG_NXTHDR(&hdr, cmsg)) {
- BitMask64 prior_bitmask = packet_info->bitmask();
- PopulatePacketInfoFromControlMessage(cmsg, packet_info,
- packet_info_interested);
- if (packet_info->bitmask() == prior_bitmask) {
- QUIC_DLOG(INFO) << "Ignored cmsg_level:" << cmsg->cmsg_level
- << ", cmsg_type:" << cmsg->cmsg_type;
- }
- }
- }
-
- result->ok = true;
-}
-
-size_t QuicUdpSocketApi::ReadMultiplePackets(QuicUdpSocketFd fd,
- BitMask64 packet_info_interested,
- ReadPacketResults* results) {
-#if defined(__linux__) && !defined(__ANDROID__)
- // Use recvmmsg.
- size_t hdrs_size = sizeof(mmsghdr) * results->size();
- mmsghdr* hdrs = static_cast<mmsghdr*>(alloca(hdrs_size));
- memset(hdrs, 0, hdrs_size);
-
- struct TempPerPacketData {
- iovec iov;
- sockaddr_storage raw_peer_address;
- };
- TempPerPacketData* packet_data_array = static_cast<TempPerPacketData*>(
- alloca(sizeof(TempPerPacketData) * results->size()));
-
- for (size_t i = 0; i < results->size(); ++i) {
- (*results)[i].ok = false;
-
- msghdr* hdr = &hdrs[i].msg_hdr;
- TempPerPacketData* packet_data = &packet_data_array[i];
- packet_data->iov.iov_base = (*results)[i].packet_buffer.buffer;
- packet_data->iov.iov_len = (*results)[i].packet_buffer.buffer_len;
-
- hdr->msg_name = &packet_data->raw_peer_address;
- hdr->msg_namelen = sizeof(sockaddr_storage);
- hdr->msg_iov = &packet_data->iov;
- hdr->msg_iovlen = 1;
- hdr->msg_flags = 0;
- hdr->msg_control = (*results)[i].control_buffer.buffer;
- hdr->msg_controllen = (*results)[i].control_buffer.buffer_len;
-
- QUICHE_DCHECK_GE(hdr->msg_controllen, kMinCmsgSpaceForRead);
- }
- // If MSG_TRUNC is set on Linux, recvmmsg will return the real packet size in
- // |hdrs[i].msg_len| even if packet buffer is too small to receive it.
- int packets_read = recvmmsg(fd, hdrs, results->size(), MSG_TRUNC, nullptr);
- if (packets_read <= 0) {
- const int error_num = errno;
- if (error_num != EAGAIN) {
- QUIC_LOG_FIRST_N(ERROR, 100)
- << "Error reading packets: " << strerror(error_num);
- }
- return 0;
- }
-
- for (int i = 0; i < packets_read; ++i) {
- if (hdrs[i].msg_len == 0) {
- continue;
- }
-
- msghdr& hdr = hdrs[i].msg_hdr;
- if (QUIC_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)) {
- QUIC_LOG_FIRST_N(WARNING, 100)
- << "Received truncated QUIC packet: buffer size:"
- << (*results)[i].packet_buffer.buffer_len
- << " packet size:" << hdrs[i].msg_len;
- continue;
- }
-
- (*results)[i].ok = true;
- (*results)[i].packet_buffer.buffer_len = hdrs[i].msg_len;
-
- QuicUdpPacketInfo* packet_info = &(*results)[i].packet_info;
- if (packet_info_interested.IsSet(QuicUdpPacketInfoBit::PEER_ADDRESS)) {
- packet_info->SetPeerAddress(
- QuicSocketAddress(packet_data_array[i].raw_peer_address));
- }
-
- if (hdr.msg_controllen > 0) {
- for (struct cmsghdr* cmsg = CMSG_FIRSTHDR(&hdr); cmsg != nullptr;
- cmsg = CMSG_NXTHDR(&hdr, cmsg)) {
- PopulatePacketInfoFromControlMessage(cmsg, packet_info,
- packet_info_interested);
- }
- }
- }
- return packets_read;
-#else
- size_t num_packets = 0;
- for (ReadPacketResult& result : *results) {
- result.ok = false;
- }
- for (ReadPacketResult& result : *results) {
- errno = 0;
- ReadPacket(fd, packet_info_interested, &result);
- if (!result.ok && errno == EAGAIN) {
- break;
- }
- ++num_packets;
- }
- return num_packets;
-#endif
-}
-
-WriteResult QuicUdpSocketApi::WritePacket(
- QuicUdpSocketFd fd,
- const char* packet_buffer,
- size_t packet_buffer_len,
- const QuicUdpPacketInfo& packet_info) {
- if (!packet_info.HasValue(QuicUdpPacketInfoBit::PEER_ADDRESS)) {
- return WriteResult(WRITE_STATUS_ERROR, EINVAL);
- }
-
- char control_buffer[512];
- sockaddr_storage raw_peer_address =
- packet_info.peer_address().generic_address();
- iovec iov = {const_cast<char*>(packet_buffer), packet_buffer_len};
-
- msghdr hdr;
- hdr.msg_name = &raw_peer_address;
- hdr.msg_namelen = packet_info.peer_address().host().IsIPv4()
- ? sizeof(sockaddr_in)
- : sizeof(sockaddr_in6);
- hdr.msg_iov = &iov;
- hdr.msg_iovlen = 1;
- hdr.msg_flags = 0;
- hdr.msg_control = nullptr;
- hdr.msg_controllen = 0;
-
- cmsghdr* cmsg = nullptr;
-
- // Set self IP.
- if (packet_info.HasValue(QuicUdpPacketInfoBit::V4_SELF_IP) &&
- packet_info.self_v4_ip().IsInitialized()) {
- if (!NextCmsg(&hdr, control_buffer, sizeof(control_buffer), IPPROTO_IP,
- IP_PKTINFO, sizeof(in_pktinfo), &cmsg)) {
- QUIC_LOG_FIRST_N(ERROR, 100)
- << "Not enough buffer to set self v4 ip address.";
- return WriteResult(WRITE_STATUS_ERROR, EINVAL);
- }
- SetV4SelfIpInControlMessage(packet_info.self_v4_ip(), cmsg);
- } else if (packet_info.HasValue(QuicUdpPacketInfoBit::V6_SELF_IP) &&
- packet_info.self_v6_ip().IsInitialized()) {
- if (!NextCmsg(&hdr, control_buffer, sizeof(control_buffer), IPPROTO_IPV6,
- IPV6_PKTINFO, sizeof(in6_pktinfo), &cmsg)) {
- QUIC_LOG_FIRST_N(ERROR, 100)
- << "Not enough buffer to set self v6 ip address.";
- return WriteResult(WRITE_STATUS_ERROR, EINVAL);
- }
- SetV6SelfIpInControlMessage(packet_info.self_v6_ip(), cmsg);
- }
-
-#if defined(QUIC_UDP_SOCKET_SUPPORT_TTL)
- // Set ttl.
- if (packet_info.HasValue(QuicUdpPacketInfoBit::TTL)) {
- int cmsg_level =
- packet_info.peer_address().host().IsIPv4() ? IPPROTO_IP : IPPROTO_IPV6;
- int cmsg_type =
- packet_info.peer_address().host().IsIPv4() ? IP_TTL : IPV6_HOPLIMIT;
- if (!NextCmsg(&hdr, control_buffer, sizeof(control_buffer), cmsg_level,
- cmsg_type, sizeof(int), &cmsg)) {
- QUIC_LOG_FIRST_N(ERROR, 100) << "Not enough buffer to set ttl.";
- return WriteResult(WRITE_STATUS_ERROR, EINVAL);
- }
- *reinterpret_cast<int*>(CMSG_DATA(cmsg)) = packet_info.ttl();
- }
-#endif
-
- int rc;
- do {
- rc = sendmsg(fd, &hdr, 0);
- } while (rc < 0 && errno == EINTR);
- if (rc >= 0) {
- return WriteResult(WRITE_STATUS_OK, rc);
- }
- return WriteResult((errno == EAGAIN || errno == EWOULDBLOCK)
- ? WRITE_STATUS_BLOCKED
- : WRITE_STATUS_ERROR,
- errno);
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_unacked_packet_map.cc b/chromium/net/third_party/quiche/src/quic/core/quic_unacked_packet_map.cc
deleted file mode 100644
index dada106a6a4..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_unacked_packet_map.cc
+++ /dev/null
@@ -1,658 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_unacked_packet_map.h"
-
-#include <cstddef>
-#include <limits>
-#include <type_traits>
-
-#include "absl/container/inlined_vector.h"
-#include "quic/core/quic_connection_stats.h"
-#include "quic/core/quic_packet_number.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_flag_utils.h"
-
-namespace quic {
-
-namespace {
-bool WillStreamFrameLengthSumWrapAround(QuicPacketLength lhs,
- QuicPacketLength rhs) {
- static_assert(
- std::is_unsigned<QuicPacketLength>::value,
- "This function assumes QuicPacketLength is an unsigned integer type.");
- return std::numeric_limits<QuicPacketLength>::max() - lhs < rhs;
-}
-
-enum QuicFrameTypeBitfield : uint32_t {
- kInvalidFrameBitfield = 0,
- kPaddingFrameBitfield = 1,
- kRstStreamFrameBitfield = 1 << 1,
- kConnectionCloseFrameBitfield = 1 << 2,
- kGoawayFrameBitfield = 1 << 3,
- kWindowUpdateFrameBitfield = 1 << 4,
- kBlockedFrameBitfield = 1 << 5,
- kStopWaitingFrameBitfield = 1 << 6,
- kPingFrameBitfield = 1 << 7,
- kCryptoFrameBitfield = 1 << 8,
- kHandshakeDoneFrameBitfield = 1 << 9,
- kStreamFrameBitfield = 1 << 10,
- kAckFrameBitfield = 1 << 11,
- kMtuDiscoveryFrameBitfield = 1 << 12,
- kNewConnectionIdFrameBitfield = 1 << 13,
- kMaxStreamsFrameBitfield = 1 << 14,
- kStreamsBlockedFrameBitfield = 1 << 15,
- kPathResponseFrameBitfield = 1 << 16,
- kPathChallengeFrameBitfield = 1 << 17,
- kStopSendingFrameBitfield = 1 << 18,
- kMessageFrameBitfield = 1 << 19,
- kNewTokenFrameBitfield = 1 << 20,
- kRetireConnectionIdFrameBitfield = 1 << 21,
- kAckFrequencyFrameBitfield = 1 << 22,
-};
-
-QuicFrameTypeBitfield GetFrameTypeBitfield(QuicFrameType type) {
- switch (type) {
- case PADDING_FRAME:
- return kPaddingFrameBitfield;
- case RST_STREAM_FRAME:
- return kRstStreamFrameBitfield;
- case CONNECTION_CLOSE_FRAME:
- return kConnectionCloseFrameBitfield;
- case GOAWAY_FRAME:
- return kGoawayFrameBitfield;
- case WINDOW_UPDATE_FRAME:
- return kWindowUpdateFrameBitfield;
- case BLOCKED_FRAME:
- return kBlockedFrameBitfield;
- case STOP_WAITING_FRAME:
- return kStopWaitingFrameBitfield;
- case PING_FRAME:
- return kPingFrameBitfield;
- case CRYPTO_FRAME:
- return kCryptoFrameBitfield;
- case HANDSHAKE_DONE_FRAME:
- return kHandshakeDoneFrameBitfield;
- case STREAM_FRAME:
- return kStreamFrameBitfield;
- case ACK_FRAME:
- return kAckFrameBitfield;
- case MTU_DISCOVERY_FRAME:
- return kMtuDiscoveryFrameBitfield;
- case NEW_CONNECTION_ID_FRAME:
- return kNewConnectionIdFrameBitfield;
- case MAX_STREAMS_FRAME:
- return kMaxStreamsFrameBitfield;
- case STREAMS_BLOCKED_FRAME:
- return kStreamsBlockedFrameBitfield;
- case PATH_RESPONSE_FRAME:
- return kPathResponseFrameBitfield;
- case PATH_CHALLENGE_FRAME:
- return kPathChallengeFrameBitfield;
- case STOP_SENDING_FRAME:
- return kStopSendingFrameBitfield;
- case MESSAGE_FRAME:
- return kMessageFrameBitfield;
- case NEW_TOKEN_FRAME:
- return kNewTokenFrameBitfield;
- case RETIRE_CONNECTION_ID_FRAME:
- return kRetireConnectionIdFrameBitfield;
- case ACK_FREQUENCY_FRAME:
- return kAckFrequencyFrameBitfield;
- case NUM_FRAME_TYPES:
- QUIC_BUG(quic_bug_10518_1) << "Unexpected frame type";
- return kInvalidFrameBitfield;
- }
- QUIC_BUG(quic_bug_10518_2) << "Unexpected frame type";
- return kInvalidFrameBitfield;
-}
-
-} // namespace
-
-QuicUnackedPacketMap::QuicUnackedPacketMap(Perspective perspective)
- : perspective_(perspective),
- least_unacked_(FirstSendingPacketNumber()),
- bytes_in_flight_(0),
- bytes_in_flight_per_packet_number_space_{0, 0, 0},
- packets_in_flight_(0),
- last_inflight_packet_sent_time_(QuicTime::Zero()),
- last_inflight_packets_sent_time_{{QuicTime::Zero()},
- {QuicTime::Zero()},
- {QuicTime::Zero()}},
- last_crypto_packet_sent_time_(QuicTime::Zero()),
- session_notifier_(nullptr),
- supports_multiple_packet_number_spaces_(false) {
-}
-
-QuicUnackedPacketMap::~QuicUnackedPacketMap() {
- for (QuicTransmissionInfo& transmission_info : unacked_packets_) {
- DeleteFrames(&(transmission_info.retransmittable_frames));
- }
-}
-
-void QuicUnackedPacketMap::AddSentPacket(SerializedPacket* mutable_packet,
- TransmissionType transmission_type,
- QuicTime sent_time,
- bool set_in_flight,
- bool measure_rtt) {
- const SerializedPacket& packet = *mutable_packet;
- QuicPacketNumber packet_number = packet.packet_number;
- QuicPacketLength bytes_sent = packet.encrypted_length;
- QUIC_BUG_IF(quic_bug_12645_1, largest_sent_packet_.IsInitialized() &&
- largest_sent_packet_ >= packet_number)
- << "largest_sent_packet_: " << largest_sent_packet_
- << ", packet_number: " << packet_number;
- QUICHE_DCHECK_GE(packet_number, least_unacked_ + unacked_packets_.size());
- while (least_unacked_ + unacked_packets_.size() < packet_number) {
- unacked_packets_.push_back(QuicTransmissionInfo());
- unacked_packets_.back().state = NEVER_SENT;
- }
-
- const bool has_crypto_handshake = packet.has_crypto_handshake == IS_HANDSHAKE;
- QuicTransmissionInfo info(packet.encryption_level, transmission_type,
- sent_time, bytes_sent, has_crypto_handshake,
- packet.has_ack_frequency);
- info.largest_acked = packet.largest_acked;
- largest_sent_largest_acked_.UpdateMax(packet.largest_acked);
-
- if (!measure_rtt) {
- QUIC_BUG_IF(quic_bug_12645_2, set_in_flight)
- << "Packet " << mutable_packet->packet_number << ", transmission type "
- << TransmissionTypeToString(mutable_packet->transmission_type)
- << ", retransmittable frames: "
- << QuicFramesToString(mutable_packet->retransmittable_frames)
- << ", nonretransmittable_frames: "
- << QuicFramesToString(mutable_packet->nonretransmittable_frames);
- info.state = NOT_CONTRIBUTING_RTT;
- }
-
- largest_sent_packet_ = packet_number;
- if (set_in_flight) {
- const PacketNumberSpace packet_number_space =
- GetPacketNumberSpace(info.encryption_level);
- bytes_in_flight_ += bytes_sent;
- bytes_in_flight_per_packet_number_space_[packet_number_space] += bytes_sent;
- ++packets_in_flight_;
- info.in_flight = true;
- largest_sent_retransmittable_packets_[packet_number_space] = packet_number;
- last_inflight_packet_sent_time_ = sent_time;
- last_inflight_packets_sent_time_[packet_number_space] = sent_time;
- }
- unacked_packets_.push_back(std::move(info));
- // Swap the retransmittable frames to avoid allocations.
- // TODO(ianswett): Could use emplace_back when Chromium can.
- if (has_crypto_handshake) {
- last_crypto_packet_sent_time_ = sent_time;
- }
-
- mutable_packet->retransmittable_frames.swap(
- unacked_packets_.back().retransmittable_frames);
-}
-
-void QuicUnackedPacketMap::RemoveObsoletePackets() {
- while (!unacked_packets_.empty()) {
- if (!IsPacketUseless(least_unacked_, unacked_packets_.front())) {
- break;
- }
- DeleteFrames(&unacked_packets_.front().retransmittable_frames);
- unacked_packets_.pop_front();
- ++least_unacked_;
- }
-}
-
-bool QuicUnackedPacketMap::HasRetransmittableFrames(
- QuicPacketNumber packet_number) const {
- QUICHE_DCHECK_GE(packet_number, least_unacked_);
- QUICHE_DCHECK_LT(packet_number, least_unacked_ + unacked_packets_.size());
- return HasRetransmittableFrames(
- unacked_packets_[packet_number - least_unacked_]);
-}
-
-bool QuicUnackedPacketMap::HasRetransmittableFrames(
- const QuicTransmissionInfo& info) const {
- if (!QuicUtils::IsAckable(info.state)) {
- return false;
- }
-
- for (const auto& frame : info.retransmittable_frames) {
- if (session_notifier_->IsFrameOutstanding(frame)) {
- return true;
- }
- }
- return false;
-}
-
-void QuicUnackedPacketMap::RemoveRetransmittability(
- QuicTransmissionInfo* info) {
- DeleteFrames(&info->retransmittable_frames);
- info->first_sent_after_loss.Clear();
-}
-
-void QuicUnackedPacketMap::RemoveRetransmittability(
- QuicPacketNumber packet_number) {
- QUICHE_DCHECK_GE(packet_number, least_unacked_);
- QUICHE_DCHECK_LT(packet_number, least_unacked_ + unacked_packets_.size());
- QuicTransmissionInfo* info =
- &unacked_packets_[packet_number - least_unacked_];
- RemoveRetransmittability(info);
-}
-
-void QuicUnackedPacketMap::IncreaseLargestAcked(
- QuicPacketNumber largest_acked) {
- QUICHE_DCHECK(!largest_acked_.IsInitialized() ||
- largest_acked_ <= largest_acked);
- largest_acked_ = largest_acked;
-}
-
-void QuicUnackedPacketMap::MaybeUpdateLargestAckedOfPacketNumberSpace(
- PacketNumberSpace packet_number_space,
- QuicPacketNumber packet_number) {
- largest_acked_packets_[packet_number_space].UpdateMax(packet_number);
-}
-
-bool QuicUnackedPacketMap::IsPacketUsefulForMeasuringRtt(
- QuicPacketNumber packet_number,
- const QuicTransmissionInfo& info) const {
- // Packet can be used for RTT measurement if it may yet be acked as the
- // largest observed packet by the receiver.
- return QuicUtils::IsAckable(info.state) &&
- (!largest_acked_.IsInitialized() || packet_number > largest_acked_) &&
- info.state != NOT_CONTRIBUTING_RTT;
-}
-
-bool QuicUnackedPacketMap::IsPacketUsefulForCongestionControl(
- const QuicTransmissionInfo& info) const {
- // Packet contributes to congestion control if it is considered inflight.
- return info.in_flight;
-}
-
-bool QuicUnackedPacketMap::IsPacketUsefulForRetransmittableData(
- const QuicTransmissionInfo& info) const {
- // Wait for 1 RTT before giving up on the lost packet.
- return info.first_sent_after_loss.IsInitialized() &&
- (!largest_acked_.IsInitialized() ||
- info.first_sent_after_loss > largest_acked_);
-}
-
-bool QuicUnackedPacketMap::IsPacketUseless(
- QuicPacketNumber packet_number,
- const QuicTransmissionInfo& info) const {
- return !IsPacketUsefulForMeasuringRtt(packet_number, info) &&
- !IsPacketUsefulForCongestionControl(info) &&
- !IsPacketUsefulForRetransmittableData(info);
-}
-
-bool QuicUnackedPacketMap::IsUnacked(QuicPacketNumber packet_number) const {
- if (packet_number < least_unacked_ ||
- packet_number >= least_unacked_ + unacked_packets_.size()) {
- return false;
- }
- return !IsPacketUseless(packet_number,
- unacked_packets_[packet_number - least_unacked_]);
-}
-
-void QuicUnackedPacketMap::RemoveFromInFlight(QuicTransmissionInfo* info) {
- if (info->in_flight) {
- QUIC_BUG_IF(quic_bug_12645_3, bytes_in_flight_ < info->bytes_sent);
- QUIC_BUG_IF(quic_bug_12645_4, packets_in_flight_ == 0);
- bytes_in_flight_ -= info->bytes_sent;
- --packets_in_flight_;
-
- const PacketNumberSpace packet_number_space =
- GetPacketNumberSpace(info->encryption_level);
- if (bytes_in_flight_per_packet_number_space_[packet_number_space] <
- info->bytes_sent) {
- QUIC_BUG(quic_bug_10518_3)
- << "bytes_in_flight: "
- << bytes_in_flight_per_packet_number_space_[packet_number_space]
- << " is smaller than bytes_sent: " << info->bytes_sent
- << " for packet number space: "
- << PacketNumberSpaceToString(packet_number_space);
- bytes_in_flight_per_packet_number_space_[packet_number_space] = 0;
- } else {
- bytes_in_flight_per_packet_number_space_[packet_number_space] -=
- info->bytes_sent;
- }
- if (bytes_in_flight_per_packet_number_space_[packet_number_space] == 0) {
- last_inflight_packets_sent_time_[packet_number_space] = QuicTime::Zero();
- }
-
- info->in_flight = false;
- }
-}
-
-void QuicUnackedPacketMap::RemoveFromInFlight(QuicPacketNumber packet_number) {
- QUICHE_DCHECK_GE(packet_number, least_unacked_);
- QUICHE_DCHECK_LT(packet_number, least_unacked_ + unacked_packets_.size());
- QuicTransmissionInfo* info =
- &unacked_packets_[packet_number - least_unacked_];
- RemoveFromInFlight(info);
-}
-
-absl::InlinedVector<QuicPacketNumber, 2>
-QuicUnackedPacketMap::NeuterUnencryptedPackets() {
- absl::InlinedVector<QuicPacketNumber, 2> neutered_packets;
- QuicPacketNumber packet_number = GetLeastUnacked();
- for (QuicUnackedPacketMap::iterator it = begin(); it != end();
- ++it, ++packet_number) {
- if (!it->retransmittable_frames.empty() &&
- it->encryption_level == ENCRYPTION_INITIAL) {
- QUIC_DVLOG(2) << "Neutering unencrypted packet " << packet_number;
- // Once the connection swithes to forward secure, no unencrypted packets
- // will be sent. The data has been abandoned in the cryto stream. Remove
- // it from in flight.
- RemoveFromInFlight(packet_number);
- it->state = NEUTERED;
- neutered_packets.push_back(packet_number);
- // Notify session that the data has been delivered (but do not notify
- // send algorithm).
- // TODO(b/148868195): use NotifyFramesNeutered.
- NotifyFramesAcked(*it, QuicTime::Delta::Zero(), QuicTime::Zero());
- QUICHE_DCHECK(!HasRetransmittableFrames(*it));
- }
- }
- QUICHE_DCHECK(!supports_multiple_packet_number_spaces_ ||
- last_inflight_packets_sent_time_[INITIAL_DATA] ==
- QuicTime::Zero());
- return neutered_packets;
-}
-
-absl::InlinedVector<QuicPacketNumber, 2>
-QuicUnackedPacketMap::NeuterHandshakePackets() {
- absl::InlinedVector<QuicPacketNumber, 2> neutered_packets;
- QuicPacketNumber packet_number = GetLeastUnacked();
- for (QuicUnackedPacketMap::iterator it = begin(); it != end();
- ++it, ++packet_number) {
- if (!it->retransmittable_frames.empty() &&
- GetPacketNumberSpace(it->encryption_level) == HANDSHAKE_DATA) {
- QUIC_DVLOG(2) << "Neutering handshake packet " << packet_number;
- RemoveFromInFlight(packet_number);
- // Notify session that the data has been delivered (but do not notify
- // send algorithm).
- it->state = NEUTERED;
- neutered_packets.push_back(packet_number);
- // TODO(b/148868195): use NotifyFramesNeutered.
- NotifyFramesAcked(*it, QuicTime::Delta::Zero(), QuicTime::Zero());
- }
- }
- QUICHE_DCHECK(!supports_multiple_packet_number_spaces() ||
- last_inflight_packets_sent_time_[HANDSHAKE_DATA] ==
- QuicTime::Zero());
- return neutered_packets;
-}
-
-bool QuicUnackedPacketMap::HasInFlightPackets() const {
- return bytes_in_flight_ > 0;
-}
-
-const QuicTransmissionInfo& QuicUnackedPacketMap::GetTransmissionInfo(
- QuicPacketNumber packet_number) const {
- return unacked_packets_[packet_number - least_unacked_];
-}
-
-QuicTransmissionInfo* QuicUnackedPacketMap::GetMutableTransmissionInfo(
- QuicPacketNumber packet_number) {
- return &unacked_packets_[packet_number - least_unacked_];
-}
-
-QuicTime QuicUnackedPacketMap::GetLastInFlightPacketSentTime() const {
- return last_inflight_packet_sent_time_;
-}
-
-QuicTime QuicUnackedPacketMap::GetLastCryptoPacketSentTime() const {
- return last_crypto_packet_sent_time_;
-}
-
-size_t QuicUnackedPacketMap::GetNumUnackedPacketsDebugOnly() const {
- size_t unacked_packet_count = 0;
- QuicPacketNumber packet_number = least_unacked_;
- for (auto it = begin(); it != end(); ++it, ++packet_number) {
- if (!IsPacketUseless(packet_number, *it)) {
- ++unacked_packet_count;
- }
- }
- return unacked_packet_count;
-}
-
-bool QuicUnackedPacketMap::HasMultipleInFlightPackets() const {
- if (bytes_in_flight_ > kDefaultTCPMSS) {
- return true;
- }
- size_t num_in_flight = 0;
- for (auto it = rbegin(); it != rend(); ++it) {
- if (it->in_flight) {
- ++num_in_flight;
- }
- if (num_in_flight > 1) {
- return true;
- }
- }
- return false;
-}
-
-bool QuicUnackedPacketMap::HasPendingCryptoPackets() const {
- return session_notifier_->HasUnackedCryptoData();
-}
-
-bool QuicUnackedPacketMap::HasUnackedRetransmittableFrames() const {
- for (auto it = rbegin(); it != rend(); ++it) {
- if (it->in_flight && HasRetransmittableFrames(*it)) {
- return true;
- }
- }
- return false;
-}
-
-QuicPacketNumber QuicUnackedPacketMap::GetLeastUnacked() const {
- return least_unacked_;
-}
-
-void QuicUnackedPacketMap::SetSessionNotifier(
- SessionNotifierInterface* session_notifier) {
- session_notifier_ = session_notifier;
-}
-
-bool QuicUnackedPacketMap::NotifyFramesAcked(const QuicTransmissionInfo& info,
- QuicTime::Delta ack_delay,
- QuicTime receive_timestamp) {
- if (session_notifier_ == nullptr) {
- return false;
- }
- bool new_data_acked = false;
- for (const QuicFrame& frame : info.retransmittable_frames) {
- if (session_notifier_->OnFrameAcked(frame, ack_delay, receive_timestamp)) {
- new_data_acked = true;
- }
- }
- return new_data_acked;
-}
-
-void QuicUnackedPacketMap::NotifyFramesLost(const QuicTransmissionInfo& info,
- TransmissionType /*type*/) {
- for (const QuicFrame& frame : info.retransmittable_frames) {
- session_notifier_->OnFrameLost(frame);
- }
-}
-
-void QuicUnackedPacketMap::RetransmitFrames(const QuicFrames& frames,
- TransmissionType type) {
- session_notifier_->RetransmitFrames(frames, type);
-}
-
-void QuicUnackedPacketMap::MaybeAggregateAckedStreamFrame(
- const QuicTransmissionInfo& info,
- QuicTime::Delta ack_delay,
- QuicTime receive_timestamp) {
- if (session_notifier_ == nullptr) {
- return;
- }
- for (const auto& frame : info.retransmittable_frames) {
- // Determine whether acked stream frame can be aggregated.
- const bool can_aggregate =
- frame.type == STREAM_FRAME &&
- frame.stream_frame.stream_id == aggregated_stream_frame_.stream_id &&
- frame.stream_frame.offset == aggregated_stream_frame_.offset +
- aggregated_stream_frame_.data_length &&
- // We would like to increment aggregated_stream_frame_.data_length by
- // frame.stream_frame.data_length, so we need to make sure their sum is
- // representable by QuicPacketLength, which is the type of the former.
- !WillStreamFrameLengthSumWrapAround(
- aggregated_stream_frame_.data_length,
- frame.stream_frame.data_length);
-
- if (can_aggregate) {
- // Aggregate stream frame.
- aggregated_stream_frame_.data_length += frame.stream_frame.data_length;
- aggregated_stream_frame_.fin = frame.stream_frame.fin;
- if (aggregated_stream_frame_.fin) {
- // Notify session notifier aggregated stream frame gets acked if fin is
- // acked.
- NotifyAggregatedStreamFrameAcked(ack_delay);
- }
- continue;
- }
-
- NotifyAggregatedStreamFrameAcked(ack_delay);
- if (frame.type != STREAM_FRAME || frame.stream_frame.fin) {
- session_notifier_->OnFrameAcked(frame, ack_delay, receive_timestamp);
- continue;
- }
-
- // Delay notifying session notifier stream frame gets acked in case it can
- // be aggregated with following acked ones.
- aggregated_stream_frame_.stream_id = frame.stream_frame.stream_id;
- aggregated_stream_frame_.offset = frame.stream_frame.offset;
- aggregated_stream_frame_.data_length = frame.stream_frame.data_length;
- aggregated_stream_frame_.fin = frame.stream_frame.fin;
- }
-}
-
-void QuicUnackedPacketMap::NotifyAggregatedStreamFrameAcked(
- QuicTime::Delta ack_delay) {
- if (aggregated_stream_frame_.stream_id == static_cast<QuicStreamId>(-1) ||
- session_notifier_ == nullptr) {
- // Aggregated stream frame is empty.
- return;
- }
- // Note: there is no receive_timestamp for an aggregated stream frame. The
- // frames that are aggregated may not have been received at the same time.
- session_notifier_->OnFrameAcked(QuicFrame(aggregated_stream_frame_),
- ack_delay,
- /*receive_timestamp=*/QuicTime::Zero());
- // Clear aggregated stream frame.
- aggregated_stream_frame_.stream_id = -1;
-}
-
-PacketNumberSpace QuicUnackedPacketMap::GetPacketNumberSpace(
- QuicPacketNumber packet_number) const {
- return GetPacketNumberSpace(
- GetTransmissionInfo(packet_number).encryption_level);
-}
-
-PacketNumberSpace QuicUnackedPacketMap::GetPacketNumberSpace(
- EncryptionLevel encryption_level) const {
- if (supports_multiple_packet_number_spaces_) {
- return QuicUtils::GetPacketNumberSpace(encryption_level);
- }
- if (perspective_ == Perspective::IS_CLIENT) {
- return encryption_level == ENCRYPTION_INITIAL ? HANDSHAKE_DATA
- : APPLICATION_DATA;
- }
- return encryption_level == ENCRYPTION_FORWARD_SECURE ? APPLICATION_DATA
- : HANDSHAKE_DATA;
-}
-
-QuicPacketNumber QuicUnackedPacketMap::GetLargestAckedOfPacketNumberSpace(
- PacketNumberSpace packet_number_space) const {
- if (packet_number_space >= NUM_PACKET_NUMBER_SPACES) {
- QUIC_BUG(quic_bug_10518_4)
- << "Invalid packet number space: " << packet_number_space;
- return QuicPacketNumber();
- }
- return largest_acked_packets_[packet_number_space];
-}
-
-QuicTime QuicUnackedPacketMap::GetLastInFlightPacketSentTime(
- PacketNumberSpace packet_number_space) const {
- if (packet_number_space >= NUM_PACKET_NUMBER_SPACES) {
- QUIC_BUG(quic_bug_10518_5)
- << "Invalid packet number space: " << packet_number_space;
- return QuicTime::Zero();
- }
- return last_inflight_packets_sent_time_[packet_number_space];
-}
-
-QuicPacketNumber
-QuicUnackedPacketMap::GetLargestSentRetransmittableOfPacketNumberSpace(
- PacketNumberSpace packet_number_space) const {
- if (packet_number_space >= NUM_PACKET_NUMBER_SPACES) {
- QUIC_BUG(quic_bug_10518_6)
- << "Invalid packet number space: " << packet_number_space;
- return QuicPacketNumber();
- }
- return largest_sent_retransmittable_packets_[packet_number_space];
-}
-
-const QuicTransmissionInfo*
-QuicUnackedPacketMap::GetFirstInFlightTransmissionInfo() const {
- QUICHE_DCHECK(HasInFlightPackets());
- for (auto it = begin(); it != end(); ++it) {
- if (it->in_flight) {
- return &(*it);
- }
- }
- QUICHE_DCHECK(false);
- return nullptr;
-}
-
-const QuicTransmissionInfo*
-QuicUnackedPacketMap::GetFirstInFlightTransmissionInfoOfSpace(
- PacketNumberSpace packet_number_space) const {
- // TODO(fayang): Optimize this part if arm 1st PTO with first in flight sent
- // time works.
- for (auto it = begin(); it != end(); ++it) {
- if (it->in_flight &&
- GetPacketNumberSpace(it->encryption_level) == packet_number_space) {
- return &(*it);
- }
- }
- return nullptr;
-}
-
-void QuicUnackedPacketMap::EnableMultiplePacketNumberSpacesSupport() {
- if (supports_multiple_packet_number_spaces_) {
- QUIC_BUG(quic_bug_10518_7)
- << "Multiple packet number spaces has already been enabled";
- return;
- }
- if (largest_sent_packet_.IsInitialized()) {
- QUIC_BUG(quic_bug_10518_8)
- << "Try to enable multiple packet number spaces support after any "
- "packet has been sent.";
- return;
- }
-
- supports_multiple_packet_number_spaces_ = true;
-}
-
-int32_t QuicUnackedPacketMap::GetLastPacketContent() const {
- if (empty()) {
- // Use -1 to distinguish with packets with no retransmittable frames nor
- // acks.
- return -1;
- }
- int32_t content = 0;
- const QuicTransmissionInfo& last_packet = unacked_packets_.back();
- for (const auto& frame : last_packet.retransmittable_frames) {
- content |= GetFrameTypeBitfield(frame.type);
- }
- if (last_packet.largest_acked.IsInitialized()) {
- content |= GetFrameTypeBitfield(ACK_FRAME);
- }
- return content;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_unacked_packet_map.h b/chromium/net/third_party/quiche/src/quic/core/quic_unacked_packet_map.h
deleted file mode 100644
index b8f8ffe9c87..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_unacked_packet_map.h
+++ /dev/null
@@ -1,338 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_UNACKED_PACKET_MAP_H_
-#define QUICHE_QUIC_CORE_QUIC_UNACKED_PACKET_MAP_H_
-
-#include <cstddef>
-#include <cstdint>
-
-#include "absl/container/inlined_vector.h"
-#include "absl/strings/str_cat.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_transmission_info.h"
-#include "quic/core/session_notifier_interface.h"
-#include "quic/platform/api/quic_export.h"
-#include "quic/platform/api/quic_flags.h"
-#include "common/quiche_circular_deque.h"
-
-namespace quic {
-
-namespace test {
-class QuicUnackedPacketMapPeer;
-} // namespace test
-
-// Class which tracks unacked packets for three purposes:
-// 1) Track retransmittable data, including multiple transmissions of frames.
-// 2) Track packets and bytes in flight for congestion control.
-// 3) Track sent time of packets to provide RTT measurements from acks.
-class QUIC_EXPORT_PRIVATE QuicUnackedPacketMap {
- public:
- QuicUnackedPacketMap(Perspective perspective);
- QuicUnackedPacketMap(const QuicUnackedPacketMap&) = delete;
- QuicUnackedPacketMap& operator=(const QuicUnackedPacketMap&) = delete;
- ~QuicUnackedPacketMap();
-
- // Adds |mutable_packet| to the map and marks it as sent at |sent_time|.
- // Marks the packet as in flight if |set_in_flight| is true.
- // Packets marked as in flight are expected to be marked as missing when they
- // don't arrive, indicating the need for retransmission.
- // Any retransmittible_frames in |mutable_packet| are swapped from
- // |mutable_packet| into the QuicTransmissionInfo.
- void AddSentPacket(SerializedPacket* mutable_packet,
- TransmissionType transmission_type,
- QuicTime sent_time,
- bool set_in_flight,
- bool measure_rtt);
-
- // Returns true if the packet |packet_number| is unacked.
- bool IsUnacked(QuicPacketNumber packet_number) const;
-
- // Notifies session_notifier that frames have been acked. Returns true if any
- // new data gets acked, returns false otherwise.
- bool NotifyFramesAcked(const QuicTransmissionInfo& info,
- QuicTime::Delta ack_delay,
- QuicTime receive_timestamp);
-
- // Notifies session_notifier that frames in |info| are considered as lost.
- void NotifyFramesLost(const QuicTransmissionInfo& info,
- TransmissionType type);
-
- // Notifies session_notifier to retransmit frames with |transmission_type|.
- void RetransmitFrames(const QuicFrames& frames, TransmissionType type);
-
- // Marks |info| as no longer in flight.
- void RemoveFromInFlight(QuicTransmissionInfo* info);
-
- // Marks |packet_number| as no longer in flight.
- void RemoveFromInFlight(QuicPacketNumber packet_number);
-
- // Called to neuter all unencrypted packets to ensure they do not get
- // retransmitted. Returns a vector of neutered packet numbers.
- absl::InlinedVector<QuicPacketNumber, 2> NeuterUnencryptedPackets();
-
- // Called to neuter packets in handshake packet number space to ensure they do
- // not get retransmitted. Returns a vector of neutered packet numbers.
- // TODO(fayang): Consider to combine this with NeuterUnencryptedPackets.
- absl::InlinedVector<QuicPacketNumber, 2> NeuterHandshakePackets();
-
- // Returns true if |packet_number| has retransmittable frames. This will
- // return false if all frames of this packet are either non-retransmittable or
- // have been acked.
- bool HasRetransmittableFrames(QuicPacketNumber packet_number) const;
-
- // Returns true if |info| has retransmittable frames. This will return false
- // if all frames of this packet are either non-retransmittable or have been
- // acked.
- bool HasRetransmittableFrames(const QuicTransmissionInfo& info) const;
-
- // Returns true if there are any unacked packets which have retransmittable
- // frames.
- bool HasUnackedRetransmittableFrames() const;
-
- // Returns true if there are no packets present in the unacked packet map.
- bool empty() const { return unacked_packets_.empty(); }
-
- // Returns the largest packet number that has been sent.
- QuicPacketNumber largest_sent_packet() const { return largest_sent_packet_; }
-
- QuicPacketNumber largest_sent_largest_acked() const {
- return largest_sent_largest_acked_;
- }
-
- // Returns the largest packet number that has been acked.
- QuicPacketNumber largest_acked() const { return largest_acked_; }
-
- // Returns the sum of bytes from all packets in flight.
- QuicByteCount bytes_in_flight() const { return bytes_in_flight_; }
- QuicPacketCount packets_in_flight() const { return packets_in_flight_; }
-
- // Returns the smallest packet number of a serialized packet which has not
- // been acked by the peer. If there are no unacked packets, returns 0.
- QuicPacketNumber GetLeastUnacked() const;
-
- using const_iterator =
- quiche::QuicheCircularDeque<QuicTransmissionInfo>::const_iterator;
- using const_reverse_iterator =
- quiche::QuicheCircularDeque<QuicTransmissionInfo>::const_reverse_iterator;
- using iterator = quiche::QuicheCircularDeque<QuicTransmissionInfo>::iterator;
-
- const_iterator begin() const { return unacked_packets_.begin(); }
- const_iterator end() const { return unacked_packets_.end(); }
- const_reverse_iterator rbegin() const { return unacked_packets_.rbegin(); }
- const_reverse_iterator rend() const { return unacked_packets_.rend(); }
- iterator begin() { return unacked_packets_.begin(); }
- iterator end() { return unacked_packets_.end(); }
-
- // Returns true if there are unacked packets that are in flight.
- bool HasInFlightPackets() const;
-
- // Returns the QuicTransmissionInfo associated with |packet_number|, which
- // must be unacked.
- const QuicTransmissionInfo& GetTransmissionInfo(
- QuicPacketNumber packet_number) const;
-
- // Returns mutable QuicTransmissionInfo associated with |packet_number|, which
- // must be unacked.
- QuicTransmissionInfo* GetMutableTransmissionInfo(
- QuicPacketNumber packet_number);
-
- // Returns the time that the last unacked packet was sent.
- QuicTime GetLastInFlightPacketSentTime() const;
-
- // Returns the time that the last unacked crypto packet was sent.
- QuicTime GetLastCryptoPacketSentTime() const;
-
- // Returns the number of unacked packets.
- size_t GetNumUnackedPacketsDebugOnly() const;
-
- // Returns true if there are multiple packets in flight.
- // TODO(fayang): Remove this method and use packets_in_flight_ instead.
- bool HasMultipleInFlightPackets() const;
-
- // Returns true if there are any pending crypto packets.
- bool HasPendingCryptoPackets() const;
-
- // Returns true if there is any unacked non-crypto stream data.
- bool HasUnackedStreamData() const {
- return session_notifier_->HasUnackedStreamData();
- }
-
- // Removes any retransmittable frames from this transmission or an associated
- // transmission. It removes now useless transmissions, and disconnects any
- // other packets from other transmissions.
- void RemoveRetransmittability(QuicTransmissionInfo* info);
-
- // Looks up the QuicTransmissionInfo by |packet_number| and calls
- // RemoveRetransmittability.
- void RemoveRetransmittability(QuicPacketNumber packet_number);
-
- // Increases the largest acked. Any packets less or equal to
- // |largest_acked| are discarded if they are only for the RTT purposes.
- void IncreaseLargestAcked(QuicPacketNumber largest_acked);
-
- // Called when |packet_number| gets acked. Maybe increase the largest acked of
- // |packet_number_space|.
- void MaybeUpdateLargestAckedOfPacketNumberSpace(
- PacketNumberSpace packet_number_space,
- QuicPacketNumber packet_number);
-
- // Remove any packets no longer needed for retransmission, congestion, or
- // RTT measurement purposes.
- void RemoveObsoletePackets();
-
- // Try to aggregate acked contiguous stream frames. For noncontiguous stream
- // frames or control frames, notify the session notifier they get acked
- // immediately.
- void MaybeAggregateAckedStreamFrame(const QuicTransmissionInfo& info,
- QuicTime::Delta ack_delay,
- QuicTime receive_timestamp);
-
- // Notify the session notifier of any stream data aggregated in
- // aggregated_stream_frame_. No effect if the stream frame has an invalid
- // stream id.
- void NotifyAggregatedStreamFrameAcked(QuicTime::Delta ack_delay);
-
- // Returns packet number space that |packet_number| belongs to. Please use
- // GetPacketNumberSpace(EncryptionLevel) whenever encryption level is
- // available.
- PacketNumberSpace GetPacketNumberSpace(QuicPacketNumber packet_number) const;
-
- // Returns packet number space of |encryption_level|.
- PacketNumberSpace GetPacketNumberSpace(
- EncryptionLevel encryption_level) const;
-
- // Returns largest acked packet number of |packet_number_space|.
- QuicPacketNumber GetLargestAckedOfPacketNumberSpace(
- PacketNumberSpace packet_number_space) const;
-
- // Returns largest sent retransmittable packet number of
- // |packet_number_space|.
- QuicPacketNumber GetLargestSentRetransmittableOfPacketNumberSpace(
- PacketNumberSpace packet_number_space) const;
-
- // Returns largest sent packet number of |encryption_level|.
- QuicPacketNumber GetLargestSentPacketOfPacketNumberSpace(
- EncryptionLevel encryption_level) const;
-
- // Returns last in flight packet sent time of |packet_number_space|.
- QuicTime GetLastInFlightPacketSentTime(
- PacketNumberSpace packet_number_space) const;
-
- // Returns TransmissionInfo of the first in flight packet.
- const QuicTransmissionInfo* GetFirstInFlightTransmissionInfo() const;
-
- // Returns TransmissionInfo of first in flight packet in
- // |packet_number_space|.
- const QuicTransmissionInfo* GetFirstInFlightTransmissionInfoOfSpace(
- PacketNumberSpace packet_number_space) const;
-
- void SetSessionNotifier(SessionNotifierInterface* session_notifier);
-
- void EnableMultiplePacketNumberSpacesSupport();
-
- // Returns a bitfield of retransmittable frames of last packet in
- // unacked_packets_. For example, if the packet contains STREAM_FRAME, content
- // & (1 << STREAM_FRAME) would be set. Returns max uint32_t if
- // unacked_packets_ is empty.
- int32_t GetLastPacketContent() const;
-
- Perspective perspective() const { return perspective_; }
-
- bool supports_multiple_packet_number_spaces() const {
- return supports_multiple_packet_number_spaces_;
- }
-
- void ReserveInitialCapacity(size_t initial_capacity) {
- unacked_packets_.reserve(initial_capacity);
- }
-
- std::string DebugString() const {
- return absl::StrCat(
- "{size: ", unacked_packets_.size(),
- ", least_unacked: ", least_unacked_.ToString(),
- ", largest_sent_packet: ", largest_sent_packet_.ToString(),
- ", largest_acked: ", largest_acked_.ToString(),
- ", bytes_in_flight: ", bytes_in_flight_,
- ", packets_in_flight: ", packets_in_flight_, "}");
- }
-
- private:
- friend class test::QuicUnackedPacketMapPeer;
-
- // Returns true if packet may be useful for an RTT measurement.
- bool IsPacketUsefulForMeasuringRtt(QuicPacketNumber packet_number,
- const QuicTransmissionInfo& info) const;
-
- // Returns true if packet may be useful for congestion control purposes.
- bool IsPacketUsefulForCongestionControl(
- const QuicTransmissionInfo& info) const;
-
- // Returns true if packet may be associated with retransmittable data
- // directly or through retransmissions.
- bool IsPacketUsefulForRetransmittableData(
- const QuicTransmissionInfo& info) const;
-
- // Returns true if the packet no longer has a purpose in the map.
- bool IsPacketUseless(QuicPacketNumber packet_number,
- const QuicTransmissionInfo& info) const;
-
- const Perspective perspective_;
-
- QuicPacketNumber largest_sent_packet_;
- // The largest sent packet we expect to receive an ack for per packet number
- // space.
- QuicPacketNumber
- largest_sent_retransmittable_packets_[NUM_PACKET_NUMBER_SPACES];
- // The largest sent largest_acked in an ACK frame.
- QuicPacketNumber largest_sent_largest_acked_;
- // The largest received largest_acked from an ACK frame.
- QuicPacketNumber largest_acked_;
- // The largest received largest_acked from ACK frame per packet number space.
- QuicPacketNumber largest_acked_packets_[NUM_PACKET_NUMBER_SPACES];
-
- // Newly serialized retransmittable packets are added to this map, which
- // contains owning pointers to any contained frames. If a packet is
- // retransmitted, this map will contain entries for both the old and the new
- // packet. The old packet's retransmittable frames entry will be nullptr,
- // while the new packet's entry will contain the frames to retransmit.
- // If the old packet is acked before the new packet, then the old entry will
- // be removed from the map and the new entry's retransmittable frames will be
- // set to nullptr.
- quiche::QuicheCircularDeque<QuicTransmissionInfo> unacked_packets_;
-
- // The packet at the 0th index of unacked_packets_.
- QuicPacketNumber least_unacked_;
-
- QuicByteCount bytes_in_flight_;
- // Bytes in flight per packet number space.
- QuicByteCount
- bytes_in_flight_per_packet_number_space_[NUM_PACKET_NUMBER_SPACES];
- QuicPacketCount packets_in_flight_;
-
- // Time that the last inflight packet was sent.
- QuicTime last_inflight_packet_sent_time_;
- // Time that the last in flight packet was sent per packet number space.
- QuicTime last_inflight_packets_sent_time_[NUM_PACKET_NUMBER_SPACES];
-
- // Time that the last unacked crypto packet was sent.
- QuicTime last_crypto_packet_sent_time_;
-
- // Aggregates acked stream data across multiple acked sent packets to save CPU
- // by reducing the number of calls to the session notifier.
- QuicStreamFrame aggregated_stream_frame_;
-
- // Receives notifications of frames being retransmitted or acknowledged.
- SessionNotifierInterface* session_notifier_;
-
- // If true, supports multiple packet number spaces.
- bool supports_multiple_packet_number_spaces_;
-
- // Latched value of the quic_simple_inflight_time flag.
- bool simple_inflight_time_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_QUIC_UNACKED_PACKET_MAP_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_unacked_packet_map_test.cc b/chromium/net/third_party/quiche/src/quic/core/quic_unacked_packet_map_test.cc
deleted file mode 100644
index 07efee99f27..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_unacked_packet_map_test.cc
+++ /dev/null
@@ -1,699 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_unacked_packet_map.h"
-#include <cstddef>
-#include <limits>
-
-#include "absl/base/macros.h"
-#include "quic/core/frames/quic_stream_frame.h"
-#include "quic/core/quic_packet_number.h"
-#include "quic/core/quic_transmission_info.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/quic_test_utils.h"
-#include "quic/test_tools/quic_unacked_packet_map_peer.h"
-
-using testing::_;
-using testing::Return;
-using testing::StrictMock;
-
-namespace quic {
-namespace test {
-namespace {
-
-// Default packet length.
-const uint32_t kDefaultLength = 1000;
-
-class QuicUnackedPacketMapTest : public QuicTestWithParam<Perspective> {
- protected:
- QuicUnackedPacketMapTest()
- : unacked_packets_(GetParam()),
- now_(QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(1000)) {
- unacked_packets_.SetSessionNotifier(&notifier_);
- EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(true));
- EXPECT_CALL(notifier_, OnStreamFrameRetransmitted(_))
- .Times(testing::AnyNumber());
- }
-
- ~QuicUnackedPacketMapTest() override {}
-
- SerializedPacket CreateRetransmittablePacket(uint64_t packet_number) {
- return CreateRetransmittablePacketForStream(
- packet_number, QuicUtils::GetFirstBidirectionalStreamId(
- CurrentSupportedVersions()[0].transport_version,
- Perspective::IS_CLIENT));
- }
-
- SerializedPacket CreateRetransmittablePacketForStream(
- uint64_t packet_number,
- QuicStreamId stream_id) {
- SerializedPacket packet(QuicPacketNumber(packet_number),
- PACKET_1BYTE_PACKET_NUMBER, nullptr, kDefaultLength,
- false, false);
- QuicStreamFrame frame;
- frame.stream_id = stream_id;
- packet.retransmittable_frames.push_back(QuicFrame(frame));
- return packet;
- }
-
- SerializedPacket CreateNonRetransmittablePacket(uint64_t packet_number) {
- return SerializedPacket(QuicPacketNumber(packet_number),
- PACKET_1BYTE_PACKET_NUMBER, nullptr, kDefaultLength,
- false, false);
- }
-
- void VerifyInFlightPackets(uint64_t* packets, size_t num_packets) {
- unacked_packets_.RemoveObsoletePackets();
- if (num_packets == 0) {
- EXPECT_FALSE(unacked_packets_.HasInFlightPackets());
- EXPECT_FALSE(unacked_packets_.HasMultipleInFlightPackets());
- return;
- }
- if (num_packets == 1) {
- EXPECT_TRUE(unacked_packets_.HasInFlightPackets());
- EXPECT_FALSE(unacked_packets_.HasMultipleInFlightPackets());
- ASSERT_TRUE(unacked_packets_.IsUnacked(QuicPacketNumber(packets[0])));
- EXPECT_TRUE(
- unacked_packets_.GetTransmissionInfo(QuicPacketNumber(packets[0]))
- .in_flight);
- }
- for (size_t i = 0; i < num_packets; ++i) {
- ASSERT_TRUE(unacked_packets_.IsUnacked(QuicPacketNumber(packets[i])));
- EXPECT_TRUE(
- unacked_packets_.GetTransmissionInfo(QuicPacketNumber(packets[i]))
- .in_flight);
- }
- size_t in_flight_count = 0;
- for (auto it = unacked_packets_.begin(); it != unacked_packets_.end();
- ++it) {
- if (it->in_flight) {
- ++in_flight_count;
- }
- }
- EXPECT_EQ(num_packets, in_flight_count);
- }
-
- void VerifyUnackedPackets(uint64_t* packets, size_t num_packets) {
- unacked_packets_.RemoveObsoletePackets();
- if (num_packets == 0) {
- EXPECT_TRUE(unacked_packets_.empty());
- EXPECT_FALSE(unacked_packets_.HasUnackedRetransmittableFrames());
- return;
- }
- EXPECT_FALSE(unacked_packets_.empty());
- for (size_t i = 0; i < num_packets; ++i) {
- EXPECT_TRUE(unacked_packets_.IsUnacked(QuicPacketNumber(packets[i])))
- << packets[i];
- }
- EXPECT_EQ(num_packets, unacked_packets_.GetNumUnackedPacketsDebugOnly());
- }
-
- void VerifyRetransmittablePackets(uint64_t* packets, size_t num_packets) {
- unacked_packets_.RemoveObsoletePackets();
- size_t num_retransmittable_packets = 0;
- for (auto it = unacked_packets_.begin(); it != unacked_packets_.end();
- ++it) {
- if (unacked_packets_.HasRetransmittableFrames(*it)) {
- ++num_retransmittable_packets;
- }
- }
- EXPECT_EQ(num_packets, num_retransmittable_packets);
- for (size_t i = 0; i < num_packets; ++i) {
- EXPECT_TRUE(unacked_packets_.HasRetransmittableFrames(
- QuicPacketNumber(packets[i])))
- << " packets[" << i << "]:" << packets[i];
- }
- }
-
- void UpdatePacketState(uint64_t packet_number, SentPacketState state) {
- unacked_packets_
- .GetMutableTransmissionInfo(QuicPacketNumber(packet_number))
- ->state = state;
- }
-
- void RetransmitAndSendPacket(uint64_t old_packet_number,
- uint64_t new_packet_number,
- TransmissionType transmission_type) {
- QUICHE_DCHECK(unacked_packets_.HasRetransmittableFrames(
- QuicPacketNumber(old_packet_number)));
- QuicTransmissionInfo* info = unacked_packets_.GetMutableTransmissionInfo(
- QuicPacketNumber(old_packet_number));
- QuicStreamId stream_id = QuicUtils::GetFirstBidirectionalStreamId(
- CurrentSupportedVersions()[0].transport_version,
- Perspective::IS_CLIENT);
- for (const auto& frame : info->retransmittable_frames) {
- if (frame.type == STREAM_FRAME) {
- stream_id = frame.stream_frame.stream_id;
- break;
- }
- }
- UpdatePacketState(
- old_packet_number,
- QuicUtils::RetransmissionTypeToPacketState(transmission_type));
- info->first_sent_after_loss = QuicPacketNumber(new_packet_number);
- SerializedPacket packet(
- CreateRetransmittablePacketForStream(new_packet_number, stream_id));
- unacked_packets_.AddSentPacket(&packet, transmission_type, now_, true,
- true);
- }
- QuicUnackedPacketMap unacked_packets_;
- QuicTime now_;
- StrictMock<MockSessionNotifier> notifier_;
-};
-
-INSTANTIATE_TEST_SUITE_P(Tests,
- QuicUnackedPacketMapTest,
- ::testing::ValuesIn({Perspective::IS_CLIENT,
- Perspective::IS_SERVER}),
- ::testing::PrintToStringParamName());
-
-TEST_P(QuicUnackedPacketMapTest, RttOnly) {
- // Acks are only tracked for RTT measurement purposes.
- SerializedPacket packet(CreateNonRetransmittablePacket(1));
- unacked_packets_.AddSentPacket(&packet, NOT_RETRANSMISSION, now_, false,
- true);
-
- uint64_t unacked[] = {1};
- VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked));
- VerifyInFlightPackets(nullptr, 0);
- VerifyRetransmittablePackets(nullptr, 0);
-
- unacked_packets_.IncreaseLargestAcked(QuicPacketNumber(1));
- VerifyUnackedPackets(nullptr, 0);
- VerifyInFlightPackets(nullptr, 0);
- VerifyRetransmittablePackets(nullptr, 0);
-}
-
-TEST_P(QuicUnackedPacketMapTest, RetransmittableInflightAndRtt) {
- // Simulate a retransmittable packet being sent and acked.
- SerializedPacket packet(CreateRetransmittablePacket(1));
- unacked_packets_.AddSentPacket(&packet, NOT_RETRANSMISSION, now_, true, true);
-
- uint64_t unacked[] = {1};
- VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked));
- VerifyInFlightPackets(unacked, ABSL_ARRAYSIZE(unacked));
- VerifyRetransmittablePackets(unacked, ABSL_ARRAYSIZE(unacked));
-
- unacked_packets_.RemoveRetransmittability(QuicPacketNumber(1));
- VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked));
- VerifyInFlightPackets(unacked, ABSL_ARRAYSIZE(unacked));
- VerifyRetransmittablePackets(nullptr, 0);
-
- unacked_packets_.IncreaseLargestAcked(QuicPacketNumber(1));
- VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked));
- VerifyInFlightPackets(unacked, ABSL_ARRAYSIZE(unacked));
- VerifyRetransmittablePackets(nullptr, 0);
-
- unacked_packets_.RemoveFromInFlight(QuicPacketNumber(1));
- VerifyUnackedPackets(nullptr, 0);
- VerifyInFlightPackets(nullptr, 0);
- VerifyRetransmittablePackets(nullptr, 0);
-}
-
-TEST_P(QuicUnackedPacketMapTest, StopRetransmission) {
- const QuicStreamId stream_id = 2;
- SerializedPacket packet(CreateRetransmittablePacketForStream(1, stream_id));
- unacked_packets_.AddSentPacket(&packet, NOT_RETRANSMISSION, now_, true, true);
-
- uint64_t unacked[] = {1};
- VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked));
- VerifyInFlightPackets(unacked, ABSL_ARRAYSIZE(unacked));
- uint64_t retransmittable[] = {1};
- VerifyRetransmittablePackets(retransmittable,
- ABSL_ARRAYSIZE(retransmittable));
-
- EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(false));
- VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked));
- VerifyInFlightPackets(unacked, ABSL_ARRAYSIZE(unacked));
- VerifyRetransmittablePackets(nullptr, 0);
-}
-
-TEST_P(QuicUnackedPacketMapTest, StopRetransmissionOnOtherStream) {
- const QuicStreamId stream_id = 2;
- SerializedPacket packet(CreateRetransmittablePacketForStream(1, stream_id));
- unacked_packets_.AddSentPacket(&packet, NOT_RETRANSMISSION, now_, true, true);
-
- uint64_t unacked[] = {1};
- VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked));
- VerifyInFlightPackets(unacked, ABSL_ARRAYSIZE(unacked));
- uint64_t retransmittable[] = {1};
- VerifyRetransmittablePackets(retransmittable,
- ABSL_ARRAYSIZE(retransmittable));
-
- VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked));
- VerifyInFlightPackets(unacked, ABSL_ARRAYSIZE(unacked));
- VerifyRetransmittablePackets(retransmittable,
- ABSL_ARRAYSIZE(retransmittable));
-}
-
-TEST_P(QuicUnackedPacketMapTest, StopRetransmissionAfterRetransmission) {
- const QuicStreamId stream_id = 2;
- SerializedPacket packet1(CreateRetransmittablePacketForStream(1, stream_id));
- unacked_packets_.AddSentPacket(&packet1, NOT_RETRANSMISSION, now_, true,
- true);
- RetransmitAndSendPacket(1, 2, LOSS_RETRANSMISSION);
-
- uint64_t unacked[] = {1, 2};
- VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked));
- VerifyInFlightPackets(unacked, ABSL_ARRAYSIZE(unacked));
- std::vector<uint64_t> retransmittable = {1, 2};
- VerifyRetransmittablePackets(&retransmittable[0], retransmittable.size());
-
- EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(false));
- VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked));
- VerifyInFlightPackets(unacked, ABSL_ARRAYSIZE(unacked));
- VerifyRetransmittablePackets(nullptr, 0);
-}
-
-TEST_P(QuicUnackedPacketMapTest, RetransmittedPacket) {
- // Simulate a retransmittable packet being sent, retransmitted, and the first
- // transmission being acked.
- SerializedPacket packet1(CreateRetransmittablePacket(1));
- unacked_packets_.AddSentPacket(&packet1, NOT_RETRANSMISSION, now_, true,
- true);
- RetransmitAndSendPacket(1, 2, LOSS_RETRANSMISSION);
-
- uint64_t unacked[] = {1, 2};
- VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked));
- VerifyInFlightPackets(unacked, ABSL_ARRAYSIZE(unacked));
- std::vector<uint64_t> retransmittable = {1, 2};
- VerifyRetransmittablePackets(&retransmittable[0], retransmittable.size());
-
- EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(false));
- unacked_packets_.RemoveRetransmittability(QuicPacketNumber(1));
- VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked));
- VerifyInFlightPackets(unacked, ABSL_ARRAYSIZE(unacked));
- VerifyRetransmittablePackets(nullptr, 0);
-
- unacked_packets_.IncreaseLargestAcked(QuicPacketNumber(2));
- VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked));
- VerifyInFlightPackets(unacked, ABSL_ARRAYSIZE(unacked));
- VerifyRetransmittablePackets(nullptr, 0);
-
- unacked_packets_.RemoveFromInFlight(QuicPacketNumber(2));
- uint64_t unacked2[] = {1};
- VerifyUnackedPackets(unacked2, ABSL_ARRAYSIZE(unacked2));
- VerifyInFlightPackets(unacked2, ABSL_ARRAYSIZE(unacked2));
- VerifyRetransmittablePackets(nullptr, 0);
-
- unacked_packets_.RemoveFromInFlight(QuicPacketNumber(1));
- VerifyUnackedPackets(nullptr, 0);
- VerifyInFlightPackets(nullptr, 0);
- VerifyRetransmittablePackets(nullptr, 0);
-}
-
-TEST_P(QuicUnackedPacketMapTest, RetransmitThreeTimes) {
- // Simulate a retransmittable packet being sent and retransmitted twice.
- SerializedPacket packet1(CreateRetransmittablePacket(1));
- unacked_packets_.AddSentPacket(&packet1, NOT_RETRANSMISSION, now_, true,
- true);
- SerializedPacket packet2(CreateRetransmittablePacket(2));
- unacked_packets_.AddSentPacket(&packet2, NOT_RETRANSMISSION, now_, true,
- true);
-
- uint64_t unacked[] = {1, 2};
- VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked));
- VerifyInFlightPackets(unacked, ABSL_ARRAYSIZE(unacked));
- uint64_t retransmittable[] = {1, 2};
- VerifyRetransmittablePackets(retransmittable,
- ABSL_ARRAYSIZE(retransmittable));
-
- // Early retransmit 1 as 3 and send new data as 4.
- unacked_packets_.IncreaseLargestAcked(QuicPacketNumber(2));
- unacked_packets_.RemoveFromInFlight(QuicPacketNumber(2));
- unacked_packets_.RemoveRetransmittability(QuicPacketNumber(2));
- unacked_packets_.RemoveFromInFlight(QuicPacketNumber(1));
- RetransmitAndSendPacket(1, 3, LOSS_RETRANSMISSION);
- SerializedPacket packet4(CreateRetransmittablePacket(4));
- unacked_packets_.AddSentPacket(&packet4, NOT_RETRANSMISSION, now_, true,
- true);
-
- uint64_t unacked2[] = {1, 3, 4};
- VerifyUnackedPackets(unacked2, ABSL_ARRAYSIZE(unacked2));
- uint64_t pending2[] = {3, 4};
- VerifyInFlightPackets(pending2, ABSL_ARRAYSIZE(pending2));
- std::vector<uint64_t> retransmittable2 = {1, 3, 4};
- VerifyRetransmittablePackets(&retransmittable2[0], retransmittable2.size());
-
- // Early retransmit 3 (formerly 1) as 5, and remove 1 from unacked.
- unacked_packets_.IncreaseLargestAcked(QuicPacketNumber(4));
- unacked_packets_.RemoveFromInFlight(QuicPacketNumber(4));
- unacked_packets_.RemoveRetransmittability(QuicPacketNumber(4));
- RetransmitAndSendPacket(3, 5, LOSS_RETRANSMISSION);
- SerializedPacket packet6(CreateRetransmittablePacket(6));
- unacked_packets_.AddSentPacket(&packet6, NOT_RETRANSMISSION, now_, true,
- true);
-
- std::vector<uint64_t> unacked3 = {3, 5, 6};
- std::vector<uint64_t> retransmittable3 = {3, 5, 6};
- VerifyUnackedPackets(&unacked3[0], unacked3.size());
- VerifyRetransmittablePackets(&retransmittable3[0], retransmittable3.size());
- uint64_t pending3[] = {3, 5, 6};
- VerifyInFlightPackets(pending3, ABSL_ARRAYSIZE(pending3));
-
- // Early retransmit 5 as 7 and ensure in flight packet 3 is not removed.
- unacked_packets_.IncreaseLargestAcked(QuicPacketNumber(6));
- unacked_packets_.RemoveFromInFlight(QuicPacketNumber(6));
- unacked_packets_.RemoveRetransmittability(QuicPacketNumber(6));
- RetransmitAndSendPacket(5, 7, LOSS_RETRANSMISSION);
-
- std::vector<uint64_t> unacked4 = {3, 5, 7};
- std::vector<uint64_t> retransmittable4 = {3, 5, 7};
- VerifyUnackedPackets(&unacked4[0], unacked4.size());
- VerifyRetransmittablePackets(&retransmittable4[0], retransmittable4.size());
- uint64_t pending4[] = {3, 5, 7};
- VerifyInFlightPackets(pending4, ABSL_ARRAYSIZE(pending4));
-
- // Remove the older two transmissions from in flight.
- unacked_packets_.RemoveFromInFlight(QuicPacketNumber(3));
- unacked_packets_.RemoveFromInFlight(QuicPacketNumber(5));
- uint64_t pending5[] = {7};
- VerifyInFlightPackets(pending5, ABSL_ARRAYSIZE(pending5));
-}
-
-TEST_P(QuicUnackedPacketMapTest, RetransmitFourTimes) {
- // Simulate a retransmittable packet being sent and retransmitted twice.
- SerializedPacket packet1(CreateRetransmittablePacket(1));
- unacked_packets_.AddSentPacket(&packet1, NOT_RETRANSMISSION, now_, true,
- true);
- SerializedPacket packet2(CreateRetransmittablePacket(2));
- unacked_packets_.AddSentPacket(&packet2, NOT_RETRANSMISSION, now_, true,
- true);
-
- uint64_t unacked[] = {1, 2};
- VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked));
- VerifyInFlightPackets(unacked, ABSL_ARRAYSIZE(unacked));
- uint64_t retransmittable[] = {1, 2};
- VerifyRetransmittablePackets(retransmittable,
- ABSL_ARRAYSIZE(retransmittable));
-
- // Early retransmit 1 as 3.
- unacked_packets_.IncreaseLargestAcked(QuicPacketNumber(2));
- unacked_packets_.RemoveFromInFlight(QuicPacketNumber(2));
- unacked_packets_.RemoveRetransmittability(QuicPacketNumber(2));
- unacked_packets_.RemoveFromInFlight(QuicPacketNumber(1));
- RetransmitAndSendPacket(1, 3, LOSS_RETRANSMISSION);
-
- uint64_t unacked2[] = {1, 3};
- VerifyUnackedPackets(unacked2, ABSL_ARRAYSIZE(unacked2));
- uint64_t pending2[] = {3};
- VerifyInFlightPackets(pending2, ABSL_ARRAYSIZE(pending2));
- 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);
- SerializedPacket packet5(CreateRetransmittablePacket(5));
- unacked_packets_.AddSentPacket(&packet5, NOT_RETRANSMISSION, now_, true,
- true);
-
- uint64_t unacked3[] = {1, 3, 4, 5};
- VerifyUnackedPackets(unacked3, ABSL_ARRAYSIZE(unacked3));
- uint64_t pending3[] = {3, 4, 5};
- VerifyInFlightPackets(pending3, ABSL_ARRAYSIZE(pending3));
- std::vector<uint64_t> retransmittable3 = {1, 3, 4, 5};
- VerifyRetransmittablePackets(&retransmittable3[0], retransmittable3.size());
-
- // Early retransmit 4 as 6 and ensure in flight packet 3 is removed.
- unacked_packets_.IncreaseLargestAcked(QuicPacketNumber(5));
- unacked_packets_.RemoveFromInFlight(QuicPacketNumber(5));
- unacked_packets_.RemoveRetransmittability(QuicPacketNumber(5));
- unacked_packets_.RemoveFromInFlight(QuicPacketNumber(3));
- unacked_packets_.RemoveFromInFlight(QuicPacketNumber(4));
- RetransmitAndSendPacket(4, 6, LOSS_RETRANSMISSION);
-
- std::vector<uint64_t> unacked4 = {4, 6};
- VerifyUnackedPackets(&unacked4[0], unacked4.size());
- uint64_t pending4[] = {6};
- VerifyInFlightPackets(pending4, ABSL_ARRAYSIZE(pending4));
- std::vector<uint64_t> retransmittable4 = {4, 6};
- VerifyRetransmittablePackets(&retransmittable4[0], retransmittable4.size());
-}
-
-TEST_P(QuicUnackedPacketMapTest, SendWithGap) {
- // Simulate a retransmittable packet being sent, retransmitted, and the first
- // transmission being acked.
- SerializedPacket packet1(CreateRetransmittablePacket(1));
- unacked_packets_.AddSentPacket(&packet1, NOT_RETRANSMISSION, now_, true,
- true);
- SerializedPacket packet3(CreateRetransmittablePacket(3));
- unacked_packets_.AddSentPacket(&packet3, NOT_RETRANSMISSION, now_, true,
- true);
- RetransmitAndSendPacket(3, 5, LOSS_RETRANSMISSION);
-
- EXPECT_EQ(QuicPacketNumber(1u), unacked_packets_.GetLeastUnacked());
- EXPECT_TRUE(unacked_packets_.IsUnacked(QuicPacketNumber(1)));
- EXPECT_FALSE(unacked_packets_.IsUnacked(QuicPacketNumber(2)));
- EXPECT_TRUE(unacked_packets_.IsUnacked(QuicPacketNumber(3)));
- EXPECT_FALSE(unacked_packets_.IsUnacked(QuicPacketNumber(4)));
- EXPECT_TRUE(unacked_packets_.IsUnacked(QuicPacketNumber(5)));
- EXPECT_EQ(QuicPacketNumber(5u), unacked_packets_.largest_sent_packet());
-}
-
-TEST_P(QuicUnackedPacketMapTest, AggregateContiguousAckedStreamFrames) {
- testing::InSequence s;
- EXPECT_CALL(notifier_, OnFrameAcked(_, _, _)).Times(0);
- unacked_packets_.NotifyAggregatedStreamFrameAcked(QuicTime::Delta::Zero());
-
- QuicTransmissionInfo info1;
- QuicStreamFrame stream_frame1(3, false, 0, 100);
- info1.retransmittable_frames.push_back(QuicFrame(stream_frame1));
-
- QuicTransmissionInfo info2;
- QuicStreamFrame stream_frame2(3, false, 100, 100);
- info2.retransmittable_frames.push_back(QuicFrame(stream_frame2));
-
- QuicTransmissionInfo info3;
- QuicStreamFrame stream_frame3(3, false, 200, 100);
- info3.retransmittable_frames.push_back(QuicFrame(stream_frame3));
-
- QuicTransmissionInfo info4;
- QuicStreamFrame stream_frame4(3, true, 300, 0);
- info4.retransmittable_frames.push_back(QuicFrame(stream_frame4));
-
- // Verify stream frames are aggregated.
- EXPECT_CALL(notifier_, OnFrameAcked(_, _, _)).Times(0);
- unacked_packets_.MaybeAggregateAckedStreamFrame(
- info1, QuicTime::Delta::Zero(), QuicTime::Zero());
- EXPECT_CALL(notifier_, OnFrameAcked(_, _, _)).Times(0);
- unacked_packets_.MaybeAggregateAckedStreamFrame(
- info2, QuicTime::Delta::Zero(), QuicTime::Zero());
- EXPECT_CALL(notifier_, OnFrameAcked(_, _, _)).Times(0);
- unacked_packets_.MaybeAggregateAckedStreamFrame(
- info3, QuicTime::Delta::Zero(), QuicTime::Zero());
-
- // Verify aggregated stream frame gets acked since fin is acked.
- EXPECT_CALL(notifier_, OnFrameAcked(_, _, _)).Times(1);
- unacked_packets_.MaybeAggregateAckedStreamFrame(
- info4, QuicTime::Delta::Zero(), QuicTime::Zero());
-}
-
-// Regression test for b/112930090.
-TEST_P(QuicUnackedPacketMapTest, CannotAggregateIfDataLengthOverflow) {
- QuicByteCount kMaxAggregatedDataLength =
- std::numeric_limits<decltype(QuicStreamFrame().data_length)>::max();
- QuicStreamId stream_id = 2;
-
- // acked_stream_length=512 covers the case where a frame will cause the
- // aggregated frame length to be exactly 64K.
- // acked_stream_length=1300 covers the case where a frame will cause the
- // aggregated frame length to exceed 64K.
- for (const QuicPacketLength acked_stream_length : {512, 1300}) {
- ++stream_id;
- QuicStreamOffset offset = 0;
- // Expected length of the aggregated stream frame.
- QuicByteCount aggregated_data_length = 0;
-
- while (offset < 1e6) {
- QuicTransmissionInfo info;
- QuicStreamFrame stream_frame(stream_id, false, offset,
- acked_stream_length);
- info.retransmittable_frames.push_back(QuicFrame(stream_frame));
-
- const QuicStreamFrame& aggregated_stream_frame =
- QuicUnackedPacketMapPeer::GetAggregatedStreamFrame(unacked_packets_);
- if (aggregated_stream_frame.data_length + acked_stream_length <=
- kMaxAggregatedDataLength) {
- // Verify the acked stream frame can be aggregated.
- EXPECT_CALL(notifier_, OnFrameAcked(_, _, _)).Times(0);
- unacked_packets_.MaybeAggregateAckedStreamFrame(
- info, QuicTime::Delta::Zero(), QuicTime::Zero());
- aggregated_data_length += acked_stream_length;
- testing::Mock::VerifyAndClearExpectations(&notifier_);
- } else {
- // Verify the acked stream frame cannot be aggregated because
- // data_length is overflow.
- EXPECT_CALL(notifier_, OnFrameAcked(_, _, _)).Times(1);
- unacked_packets_.MaybeAggregateAckedStreamFrame(
- info, QuicTime::Delta::Zero(), QuicTime::Zero());
- aggregated_data_length = acked_stream_length;
- testing::Mock::VerifyAndClearExpectations(&notifier_);
- }
-
- EXPECT_EQ(aggregated_data_length, aggregated_stream_frame.data_length);
- offset += acked_stream_length;
- }
-
- // Ack the last frame of the stream.
- QuicTransmissionInfo info;
- QuicStreamFrame stream_frame(stream_id, true, offset, acked_stream_length);
- info.retransmittable_frames.push_back(QuicFrame(stream_frame));
- EXPECT_CALL(notifier_, OnFrameAcked(_, _, _)).Times(1);
- unacked_packets_.MaybeAggregateAckedStreamFrame(
- info, QuicTime::Delta::Zero(), QuicTime::Zero());
- testing::Mock::VerifyAndClearExpectations(&notifier_);
- }
-}
-
-TEST_P(QuicUnackedPacketMapTest, CannotAggregateAckedControlFrames) {
- testing::InSequence s;
- QuicWindowUpdateFrame window_update(1, 5, 100);
- QuicStreamFrame stream_frame1(3, false, 0, 100);
- QuicStreamFrame stream_frame2(3, false, 100, 100);
- QuicBlockedFrame blocked(2, 5);
- QuicGoAwayFrame go_away(3, QUIC_PEER_GOING_AWAY, 5, "Going away.");
-
- QuicTransmissionInfo info1;
- info1.retransmittable_frames.push_back(QuicFrame(&window_update));
- info1.retransmittable_frames.push_back(QuicFrame(stream_frame1));
- info1.retransmittable_frames.push_back(QuicFrame(stream_frame2));
-
- QuicTransmissionInfo info2;
- info2.retransmittable_frames.push_back(QuicFrame(&blocked));
- info2.retransmittable_frames.push_back(QuicFrame(&go_away));
-
- // Verify 2 contiguous stream frames are aggregated.
- EXPECT_CALL(notifier_, OnFrameAcked(_, _, _)).Times(1);
- unacked_packets_.MaybeAggregateAckedStreamFrame(
- info1, QuicTime::Delta::Zero(), QuicTime::Zero());
- // Verify aggregated stream frame gets acked.
- EXPECT_CALL(notifier_, OnFrameAcked(_, _, _)).Times(3);
- unacked_packets_.MaybeAggregateAckedStreamFrame(
- info2, QuicTime::Delta::Zero(), QuicTime::Zero());
-
- EXPECT_CALL(notifier_, OnFrameAcked(_, _, _)).Times(0);
- unacked_packets_.NotifyAggregatedStreamFrameAcked(QuicTime::Delta::Zero());
-}
-
-TEST_P(QuicUnackedPacketMapTest, LargestSentPacketMultiplePacketNumberSpaces) {
- unacked_packets_.EnableMultiplePacketNumberSpacesSupport();
- EXPECT_FALSE(
- unacked_packets_
- .GetLargestSentRetransmittableOfPacketNumberSpace(INITIAL_DATA)
- .IsInitialized());
- // Send packet 1.
- SerializedPacket packet1(CreateRetransmittablePacket(1));
- packet1.encryption_level = ENCRYPTION_INITIAL;
- unacked_packets_.AddSentPacket(&packet1, NOT_RETRANSMISSION, now_, true,
- true);
- EXPECT_EQ(QuicPacketNumber(1u), unacked_packets_.largest_sent_packet());
- EXPECT_EQ(QuicPacketNumber(1),
- unacked_packets_.GetLargestSentRetransmittableOfPacketNumberSpace(
- INITIAL_DATA));
- EXPECT_FALSE(
- unacked_packets_
- .GetLargestSentRetransmittableOfPacketNumberSpace(HANDSHAKE_DATA)
- .IsInitialized());
- // Send packet 2.
- SerializedPacket packet2(CreateRetransmittablePacket(2));
- packet2.encryption_level = ENCRYPTION_HANDSHAKE;
- unacked_packets_.AddSentPacket(&packet2, NOT_RETRANSMISSION, now_, true,
- true);
- EXPECT_EQ(QuicPacketNumber(2u), unacked_packets_.largest_sent_packet());
- EXPECT_EQ(QuicPacketNumber(1),
- unacked_packets_.GetLargestSentRetransmittableOfPacketNumberSpace(
- INITIAL_DATA));
- EXPECT_EQ(QuicPacketNumber(2),
- unacked_packets_.GetLargestSentRetransmittableOfPacketNumberSpace(
- HANDSHAKE_DATA));
- EXPECT_FALSE(
- unacked_packets_
- .GetLargestSentRetransmittableOfPacketNumberSpace(APPLICATION_DATA)
- .IsInitialized());
- // Send packet 3.
- SerializedPacket packet3(CreateRetransmittablePacket(3));
- packet3.encryption_level = ENCRYPTION_ZERO_RTT;
- unacked_packets_.AddSentPacket(&packet3, NOT_RETRANSMISSION, now_, true,
- true);
- EXPECT_EQ(QuicPacketNumber(3u), unacked_packets_.largest_sent_packet());
- EXPECT_EQ(QuicPacketNumber(1),
- unacked_packets_.GetLargestSentRetransmittableOfPacketNumberSpace(
- INITIAL_DATA));
- EXPECT_EQ(QuicPacketNumber(2),
- unacked_packets_.GetLargestSentRetransmittableOfPacketNumberSpace(
- HANDSHAKE_DATA));
- EXPECT_EQ(QuicPacketNumber(3),
- unacked_packets_.GetLargestSentRetransmittableOfPacketNumberSpace(
- APPLICATION_DATA));
- // Verify forward secure belongs to the same packet number space as encryption
- // zero rtt.
- EXPECT_EQ(QuicPacketNumber(3),
- unacked_packets_.GetLargestSentRetransmittableOfPacketNumberSpace(
- APPLICATION_DATA));
-
- // Send packet 4.
- SerializedPacket packet4(CreateRetransmittablePacket(4));
- packet4.encryption_level = ENCRYPTION_FORWARD_SECURE;
- unacked_packets_.AddSentPacket(&packet4, NOT_RETRANSMISSION, now_, true,
- true);
- EXPECT_EQ(QuicPacketNumber(4u), unacked_packets_.largest_sent_packet());
- EXPECT_EQ(QuicPacketNumber(1),
- unacked_packets_.GetLargestSentRetransmittableOfPacketNumberSpace(
- INITIAL_DATA));
- EXPECT_EQ(QuicPacketNumber(2),
- unacked_packets_.GetLargestSentRetransmittableOfPacketNumberSpace(
- HANDSHAKE_DATA));
- EXPECT_EQ(QuicPacketNumber(4),
- unacked_packets_.GetLargestSentRetransmittableOfPacketNumberSpace(
- APPLICATION_DATA));
- // Verify forward secure belongs to the same packet number space as encryption
- // zero rtt.
- EXPECT_EQ(QuicPacketNumber(4),
- unacked_packets_.GetLargestSentRetransmittableOfPacketNumberSpace(
- APPLICATION_DATA));
- EXPECT_TRUE(unacked_packets_.GetLastPacketContent() & (1 << STREAM_FRAME));
- EXPECT_FALSE(unacked_packets_.GetLastPacketContent() & (1 << ACK_FRAME));
-}
-
-TEST_P(QuicUnackedPacketMapTest, ReserveInitialCapacityTest) {
- QuicUnackedPacketMap unacked_packets(GetParam());
- ASSERT_EQ(QuicUnackedPacketMapPeer::GetCapacity(unacked_packets), 0u);
- unacked_packets.ReserveInitialCapacity(16);
- QuicStreamId stream_id(1);
- SerializedPacket packet(CreateRetransmittablePacketForStream(1, stream_id));
- unacked_packets.AddSentPacket(&packet, TransmissionType::NOT_RETRANSMISSION,
- now_, true, true);
- ASSERT_EQ(QuicUnackedPacketMapPeer::GetCapacity(unacked_packets), 16u);
-}
-
-TEST_P(QuicUnackedPacketMapTest, DebugString) {
- EXPECT_EQ(unacked_packets_.DebugString(),
- "{size: 0, least_unacked: 1, largest_sent_packet: uninitialized, "
- "largest_acked: uninitialized, bytes_in_flight: 0, "
- "packets_in_flight: 0}");
-
- SerializedPacket packet1(CreateRetransmittablePacket(1));
- unacked_packets_.AddSentPacket(&packet1, NOT_RETRANSMISSION, now_, true,
- true);
- EXPECT_EQ(
- unacked_packets_.DebugString(),
- "{size: 1, least_unacked: 1, largest_sent_packet: 1, largest_acked: "
- "uninitialized, bytes_in_flight: 1000, packets_in_flight: 1}");
-
- SerializedPacket packet2(CreateRetransmittablePacket(2));
- unacked_packets_.AddSentPacket(&packet2, NOT_RETRANSMISSION, now_, true,
- true);
- unacked_packets_.RemoveFromInFlight(QuicPacketNumber(1));
- unacked_packets_.IncreaseLargestAcked(QuicPacketNumber(1));
- unacked_packets_.RemoveObsoletePackets();
- EXPECT_EQ(
- unacked_packets_.DebugString(),
- "{size: 1, least_unacked: 2, largest_sent_packet: 2, largest_acked: 1, "
- "bytes_in_flight: 1000, packets_in_flight: 1}");
-}
-
-} // namespace
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_utils.cc b/chromium/net/third_party/quiche/src/quic/core/quic_utils.cc
deleted file mode 100644
index 021fe248018..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_utils.cc
+++ /dev/null
@@ -1,749 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_utils.h"
-
-#include <algorithm>
-#include <cstdint>
-#include <cstring>
-#include <limits>
-#include <string>
-
-#include "absl/base/macros.h"
-#include "absl/base/optimization.h"
-#include "absl/numeric/int128.h"
-#include "absl/strings/string_view.h"
-#include "third_party/boringssl/src/include/openssl/sha.h"
-#include "quic/core/quic_connection_id.h"
-#include "quic/core/quic_constants.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_versions.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_flag_utils.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_mem_slice.h"
-#include "common/platform/api/quiche_logging.h"
-#include "common/platform/api/quiche_prefetch.h"
-#include "common/quiche_endian.h"
-
-namespace quic {
-namespace {
-
-// We know that >= GCC 4.8 and Clang have a __uint128_t intrinsic. Other
-// compilers don't necessarily, notably MSVC.
-#if defined(__x86_64__) && \
- ((defined(__GNUC__) && \
- (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8))) || \
- defined(__clang__))
-#define QUIC_UTIL_HAS_UINT128 1
-#endif
-
-#ifdef QUIC_UTIL_HAS_UINT128
-absl::uint128 IncrementalHashFast(absl::uint128 uhash, absl::string_view data) {
- // This code ends up faster than the naive implementation for 2 reasons:
- // 1. absl::uint128 is sufficiently complicated that the compiler
- // cannot transform the multiplication by kPrime into a shift-multiply-add;
- // it has go through all of the instructions for a 128-bit multiply.
- // 2. Because there are so fewer instructions (around 13), the hot loop fits
- // nicely in the instruction queue of many Intel CPUs.
- // kPrime = 309485009821345068724781371
- static const absl::uint128 kPrime =
- (static_cast<absl::uint128>(16777216) << 64) + 315;
- auto hi = absl::Uint128High64(uhash);
- auto lo = absl::Uint128Low64(uhash);
- absl::uint128 xhash = (static_cast<absl::uint128>(hi) << 64) + lo;
- const uint8_t* octets = reinterpret_cast<const uint8_t*>(data.data());
- for (size_t i = 0; i < data.length(); ++i) {
- xhash = (xhash ^ static_cast<uint32_t>(octets[i])) * kPrime;
- }
- return absl::MakeUint128(absl::Uint128High64(xhash),
- absl::Uint128Low64(xhash));
-}
-#endif
-
-#ifndef QUIC_UTIL_HAS_UINT128
-// Slow implementation of IncrementalHash. In practice, only used by Chromium.
-absl::uint128 IncrementalHashSlow(absl::uint128 hash, absl::string_view data) {
- // kPrime = 309485009821345068724781371
- static const absl::uint128 kPrime = absl::MakeUint128(16777216, 315);
- const uint8_t* octets = reinterpret_cast<const uint8_t*>(data.data());
- for (size_t i = 0; i < data.length(); ++i) {
- hash = hash ^ absl::MakeUint128(0, octets[i]);
- hash = hash * kPrime;
- }
- return hash;
-}
-#endif
-
-absl::uint128 IncrementalHash(absl::uint128 hash, absl::string_view data) {
-#ifdef QUIC_UTIL_HAS_UINT128
- return IncrementalHashFast(hash, data);
-#else
- return IncrementalHashSlow(hash, data);
-#endif
-}
-
-} // namespace
-
-// static
-uint64_t QuicUtils::FNV1a_64_Hash(absl::string_view data) {
- static const uint64_t kOffset = UINT64_C(14695981039346656037);
- static const uint64_t kPrime = UINT64_C(1099511628211);
-
- const uint8_t* octets = reinterpret_cast<const uint8_t*>(data.data());
-
- uint64_t hash = kOffset;
-
- for (size_t i = 0; i < data.length(); ++i) {
- hash = hash ^ octets[i];
- hash = hash * kPrime;
- }
-
- return hash;
-}
-
-// static
-absl::uint128 QuicUtils::FNV1a_128_Hash(absl::string_view data) {
- return FNV1a_128_Hash_Three(data, absl::string_view(), absl::string_view());
-}
-
-// static
-absl::uint128 QuicUtils::FNV1a_128_Hash_Two(absl::string_view data1,
- absl::string_view data2) {
- return FNV1a_128_Hash_Three(data1, data2, absl::string_view());
-}
-
-// static
-absl::uint128 QuicUtils::FNV1a_128_Hash_Three(absl::string_view data1,
- absl::string_view data2,
- absl::string_view data3) {
- // The two constants are defined as part of the hash algorithm.
- // see http://www.isthe.com/chongo/tech/comp/fnv/
- // kOffset = 144066263297769815596495629667062367629
- const absl::uint128 kOffset = absl::MakeUint128(
- UINT64_C(7809847782465536322), UINT64_C(7113472399480571277));
-
- absl::uint128 hash = IncrementalHash(kOffset, data1);
- if (data2.empty()) {
- return hash;
- }
-
- hash = IncrementalHash(hash, data2);
- if (data3.empty()) {
- return hash;
- }
- return IncrementalHash(hash, data3);
-}
-
-// static
-void QuicUtils::SerializeUint128Short(absl::uint128 v, uint8_t* out) {
- const uint64_t lo = absl::Uint128Low64(v);
- const uint64_t hi = absl::Uint128High64(v);
- // This assumes that the system is little-endian.
- memcpy(out, &lo, sizeof(lo));
- memcpy(out + sizeof(lo), &hi, sizeof(hi) / 2);
-}
-
-#define RETURN_STRING_LITERAL(x) \
- case x: \
- return #x;
-
-std::string QuicUtils::AddressChangeTypeToString(AddressChangeType type) {
- switch (type) {
- RETURN_STRING_LITERAL(NO_CHANGE);
- RETURN_STRING_LITERAL(PORT_CHANGE);
- RETURN_STRING_LITERAL(IPV4_SUBNET_CHANGE);
- RETURN_STRING_LITERAL(IPV4_TO_IPV6_CHANGE);
- RETURN_STRING_LITERAL(IPV6_TO_IPV4_CHANGE);
- RETURN_STRING_LITERAL(IPV6_TO_IPV6_CHANGE);
- RETURN_STRING_LITERAL(IPV4_TO_IPV4_CHANGE);
- }
- return "INVALID_ADDRESS_CHANGE_TYPE";
-}
-
-const char* QuicUtils::SentPacketStateToString(SentPacketState state) {
- switch (state) {
- RETURN_STRING_LITERAL(OUTSTANDING);
- RETURN_STRING_LITERAL(NEVER_SENT);
- RETURN_STRING_LITERAL(ACKED);
- RETURN_STRING_LITERAL(UNACKABLE);
- 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";
-}
-
-// static
-const char* QuicUtils::QuicLongHeaderTypetoString(QuicLongHeaderType type) {
- switch (type) {
- RETURN_STRING_LITERAL(VERSION_NEGOTIATION);
- RETURN_STRING_LITERAL(INITIAL);
- RETURN_STRING_LITERAL(RETRY);
- RETURN_STRING_LITERAL(HANDSHAKE);
- RETURN_STRING_LITERAL(ZERO_RTT_PROTECTED);
- default:
- return "INVALID_PACKET_TYPE";
- }
-}
-
-// static
-const char* QuicUtils::AckResultToString(AckResult result) {
- switch (result) {
- RETURN_STRING_LITERAL(PACKETS_NEWLY_ACKED);
- RETURN_STRING_LITERAL(NO_PACKETS_NEWLY_ACKED);
- RETURN_STRING_LITERAL(UNSENT_PACKETS_ACKED);
- RETURN_STRING_LITERAL(UNACKABLE_PACKETS_ACKED);
- RETURN_STRING_LITERAL(PACKETS_ACKED_IN_WRONG_PACKET_NUMBER_SPACE);
- }
- return "INVALID_ACK_RESULT";
-}
-
-// static
-AddressChangeType QuicUtils::DetermineAddressChangeType(
- const QuicSocketAddress& old_address,
- const QuicSocketAddress& new_address) {
- if (!old_address.IsInitialized() || !new_address.IsInitialized() ||
- old_address == new_address) {
- return NO_CHANGE;
- }
-
- if (old_address.host() == new_address.host()) {
- return PORT_CHANGE;
- }
-
- bool old_ip_is_ipv4 = old_address.host().IsIPv4() ? true : false;
- bool migrating_ip_is_ipv4 = new_address.host().IsIPv4() ? true : false;
- if (old_ip_is_ipv4 && !migrating_ip_is_ipv4) {
- return IPV4_TO_IPV6_CHANGE;
- }
-
- if (!old_ip_is_ipv4) {
- return migrating_ip_is_ipv4 ? IPV6_TO_IPV4_CHANGE : IPV6_TO_IPV6_CHANGE;
- }
-
- const int kSubnetMaskLength = 24;
- if (old_address.host().InSameSubnet(new_address.host(), kSubnetMaskLength)) {
- // Subnet part does not change (here, we use /24), which is considered to be
- // caused by NATs.
- return IPV4_SUBNET_CHANGE;
- }
-
- return IPV4_TO_IPV4_CHANGE;
-}
-
-// static
-void QuicUtils::CopyToBuffer(const struct iovec* iov,
- int iov_count,
- size_t iov_offset,
- size_t buffer_length,
- char* buffer) {
- int iovnum = 0;
- while (iovnum < iov_count && iov_offset >= iov[iovnum].iov_len) {
- iov_offset -= iov[iovnum].iov_len;
- ++iovnum;
- }
- QUICHE_DCHECK_LE(iovnum, iov_count);
- QUICHE_DCHECK_LE(iov_offset, iov[iovnum].iov_len);
- if (iovnum >= iov_count || buffer_length == 0) {
- return;
- }
-
- // Unroll the first iteration that handles iov_offset.
- const size_t iov_available = iov[iovnum].iov_len - iov_offset;
- size_t copy_len = std::min(buffer_length, iov_available);
-
- // Try to prefetch the next iov if there is at least one more after the
- // current. Otherwise, it looks like an irregular access that the hardware
- // prefetcher won't speculatively prefetch. Only prefetch one iov because
- // generally, the iov_offset is not 0, input iov consists of 2K buffers and
- // the output buffer is ~1.4K.
- if (copy_len == iov_available && iovnum + 1 < iov_count) {
- char* next_base = static_cast<char*>(iov[iovnum + 1].iov_base);
- // Prefetch 2 cachelines worth of data to get the prefetcher started; leave
- // it to the hardware prefetcher after that.
- quiche::QuichePrefetchT0(next_base);
- if (iov[iovnum + 1].iov_len >= 64) {
- quiche::QuichePrefetchT0(next_base + ABSL_CACHELINE_SIZE);
- }
- }
-
- const char* src = static_cast<char*>(iov[iovnum].iov_base) + iov_offset;
- while (true) {
- memcpy(buffer, src, copy_len);
- buffer_length -= copy_len;
- buffer += copy_len;
- if (buffer_length == 0 || ++iovnum >= iov_count) {
- break;
- }
- src = static_cast<char*>(iov[iovnum].iov_base);
- copy_len = std::min(buffer_length, iov[iovnum].iov_len);
- }
- QUIC_BUG_IF(quic_bug_10839_1, buffer_length > 0)
- << "Failed to copy entire length to buffer.";
-}
-
-// static
-struct iovec QuicUtils::MakeIovec(absl::string_view data) {
- struct iovec iov = {const_cast<char*>(data.data()),
- static_cast<size_t>(data.size())};
- return iov;
-}
-
-// static
-bool QuicUtils::IsAckable(SentPacketState state) {
- return state != NEVER_SENT && state != ACKED && state != UNACKABLE;
-}
-
-// static
-bool QuicUtils::IsRetransmittableFrame(QuicFrameType type) {
- switch (type) {
- case ACK_FRAME:
- case PADDING_FRAME:
- case STOP_WAITING_FRAME:
- case MTU_DISCOVERY_FRAME:
- case PATH_CHALLENGE_FRAME:
- case PATH_RESPONSE_FRAME:
- return false;
- default:
- return true;
- }
-}
-
-// static
-bool QuicUtils::IsHandshakeFrame(const QuicFrame& frame,
- QuicTransportVersion transport_version) {
- if (!QuicVersionUsesCryptoFrames(transport_version)) {
- return frame.type == STREAM_FRAME &&
- frame.stream_frame.stream_id == GetCryptoStreamId(transport_version);
- } else {
- return frame.type == CRYPTO_FRAME;
- }
-}
-
-// static
-bool QuicUtils::ContainsFrameType(const QuicFrames& frames,
- QuicFrameType type) {
- for (const QuicFrame& frame : frames) {
- if (frame.type == type) {
- return true;
- }
- }
- return false;
-}
-
-// static
-SentPacketState QuicUtils::RetransmissionTypeToPacketState(
- TransmissionType retransmission_type) {
- switch (retransmission_type) {
- case ALL_ZERO_RTT_RETRANSMISSION:
- return UNACKABLE;
- case HANDSHAKE_RETRANSMISSION:
- 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:
- return UNACKABLE;
- default:
- QUIC_BUG(quic_bug_10839_2)
- << retransmission_type << " is not a retransmission_type";
- return UNACKABLE;
- }
-}
-
-// static
-bool QuicUtils::IsIetfPacketHeader(uint8_t first_byte) {
- return (first_byte & FLAGS_LONG_HEADER) || (first_byte & FLAGS_FIXED_BIT) ||
- !(first_byte & FLAGS_DEMULTIPLEXING_BIT);
-}
-
-// static
-bool QuicUtils::IsIetfPacketShortHeader(uint8_t first_byte) {
- return IsIetfPacketHeader(first_byte) && !(first_byte & FLAGS_LONG_HEADER);
-}
-
-// static
-QuicStreamId QuicUtils::GetInvalidStreamId(QuicTransportVersion version) {
- return VersionHasIetfQuicFrames(version)
- ? std::numeric_limits<QuicStreamId>::max()
- : 0;
-}
-
-// static
-QuicStreamId QuicUtils::GetCryptoStreamId(QuicTransportVersion version) {
- QUIC_BUG_IF(quic_bug_12982_1, QuicVersionUsesCryptoFrames(version))
- << "CRYPTO data aren't in stream frames; they have no stream ID.";
- return QuicVersionUsesCryptoFrames(version) ? GetInvalidStreamId(version) : 1;
-}
-
-// static
-bool QuicUtils::IsCryptoStreamId(QuicTransportVersion version,
- QuicStreamId stream_id) {
- if (QuicVersionUsesCryptoFrames(version)) {
- return false;
- }
- return stream_id == GetCryptoStreamId(version);
-}
-
-// static
-QuicStreamId QuicUtils::GetHeadersStreamId(QuicTransportVersion version) {
- QUICHE_DCHECK(!VersionUsesHttp3(version));
- return GetFirstBidirectionalStreamId(version, Perspective::IS_CLIENT);
-}
-
-// static
-bool QuicUtils::IsClientInitiatedStreamId(QuicTransportVersion version,
- QuicStreamId id) {
- if (id == GetInvalidStreamId(version)) {
- return false;
- }
- return VersionHasIetfQuicFrames(version) ? id % 2 == 0 : id % 2 != 0;
-}
-
-// static
-bool QuicUtils::IsServerInitiatedStreamId(QuicTransportVersion version,
- QuicStreamId id) {
- if (id == GetInvalidStreamId(version)) {
- return false;
- }
- return VersionHasIetfQuicFrames(version) ? id % 2 != 0 : id % 2 == 0;
-}
-
-// static
-bool QuicUtils::IsOutgoingStreamId(ParsedQuicVersion version,
- QuicStreamId id,
- Perspective perspective) {
- // Streams are outgoing streams, iff:
- // - we are the server and the stream is server-initiated
- // - we are the client and the stream is client-initiated.
- const bool perspective_is_server = perspective == Perspective::IS_SERVER;
- const bool stream_is_server =
- QuicUtils::IsServerInitiatedStreamId(version.transport_version, id);
- return perspective_is_server == stream_is_server;
-}
-
-// static
-bool QuicUtils::IsBidirectionalStreamId(QuicStreamId id,
- ParsedQuicVersion version) {
- QUICHE_DCHECK(version.HasIetfQuicFrames());
- return id % 4 < 2;
-}
-
-// static
-StreamType QuicUtils::GetStreamType(QuicStreamId id,
- Perspective perspective,
- bool peer_initiated,
- ParsedQuicVersion version) {
- QUICHE_DCHECK(version.HasIetfQuicFrames());
- if (IsBidirectionalStreamId(id, version)) {
- return BIDIRECTIONAL;
- }
-
- if (peer_initiated) {
- if (perspective == Perspective::IS_SERVER) {
- QUICHE_DCHECK_EQ(2u, id % 4);
- } else {
- QUICHE_DCHECK_EQ(Perspective::IS_CLIENT, perspective);
- QUICHE_DCHECK_EQ(3u, id % 4);
- }
- return READ_UNIDIRECTIONAL;
- }
-
- if (perspective == Perspective::IS_SERVER) {
- QUICHE_DCHECK_EQ(3u, id % 4);
- } else {
- QUICHE_DCHECK_EQ(Perspective::IS_CLIENT, perspective);
- QUICHE_DCHECK_EQ(2u, id % 4);
- }
- return WRITE_UNIDIRECTIONAL;
-}
-
-// static
-QuicStreamId QuicUtils::StreamIdDelta(QuicTransportVersion version) {
- return VersionHasIetfQuicFrames(version) ? 4 : 2;
-}
-
-// static
-QuicStreamId QuicUtils::GetFirstBidirectionalStreamId(
- QuicTransportVersion version,
- Perspective perspective) {
- if (VersionHasIetfQuicFrames(version)) {
- return perspective == Perspective::IS_CLIENT ? 0 : 1;
- } else if (QuicVersionUsesCryptoFrames(version)) {
- return perspective == Perspective::IS_CLIENT ? 1 : 2;
- }
- return perspective == Perspective::IS_CLIENT ? 3 : 2;
-}
-
-// static
-QuicStreamId QuicUtils::GetFirstUnidirectionalStreamId(
- QuicTransportVersion version,
- Perspective perspective) {
- if (VersionHasIetfQuicFrames(version)) {
- return perspective == Perspective::IS_CLIENT ? 2 : 3;
- } else if (QuicVersionUsesCryptoFrames(version)) {
- return perspective == Perspective::IS_CLIENT ? 1 : 2;
- }
- return perspective == Perspective::IS_CLIENT ? 3 : 2;
-}
-
-// static
-QuicStreamId QuicUtils::GetMaxClientInitiatedBidirectionalStreamId(
- QuicTransportVersion version) {
- if (VersionHasIetfQuicFrames(version)) {
- // Client initiated bidirectional streams have stream IDs divisible by 4.
- return std::numeric_limits<QuicStreamId>::max() - 3;
- }
-
- // Client initiated bidirectional streams have odd stream IDs.
- return std::numeric_limits<QuicStreamId>::max();
-}
-
-// static
-QuicConnectionId QuicUtils::CreateReplacementConnectionId(
- const QuicConnectionId& connection_id) {
- return CreateReplacementConnectionId(connection_id,
- kQuicDefaultConnectionIdLength);
-}
-
-// static
-QuicConnectionId QuicUtils::CreateReplacementConnectionId(
- const QuicConnectionId& connection_id,
- uint8_t expected_connection_id_length) {
- if (expected_connection_id_length == 0) {
- return EmptyQuicConnectionId();
- }
- const uint64_t connection_id_hash64 = FNV1a_64_Hash(
- absl::string_view(connection_id.data(), connection_id.length()));
- if (expected_connection_id_length <= sizeof(uint64_t)) {
- return QuicConnectionId(
- reinterpret_cast<const char*>(&connection_id_hash64),
- expected_connection_id_length);
- }
- char new_connection_id_data[255] = {};
- const absl::uint128 connection_id_hash128 = FNV1a_128_Hash(
- absl::string_view(connection_id.data(), connection_id.length()));
- static_assert(sizeof(connection_id_hash64) + sizeof(connection_id_hash128) <=
- sizeof(new_connection_id_data),
- "bad size");
- memcpy(new_connection_id_data, &connection_id_hash64,
- sizeof(connection_id_hash64));
- memcpy(new_connection_id_data + sizeof(connection_id_hash64),
- &connection_id_hash128, sizeof(connection_id_hash128));
- return QuicConnectionId(new_connection_id_data,
- expected_connection_id_length);
-}
-
-// static
-QuicConnectionId QuicUtils::CreateRandomConnectionId() {
- return CreateRandomConnectionId(kQuicDefaultConnectionIdLength,
- QuicRandom::GetInstance());
-}
-
-// static
-QuicConnectionId QuicUtils::CreateRandomConnectionId(QuicRandom* random) {
- return CreateRandomConnectionId(kQuicDefaultConnectionIdLength, random);
-}
-// static
-QuicConnectionId QuicUtils::CreateRandomConnectionId(
- uint8_t connection_id_length) {
- return CreateRandomConnectionId(connection_id_length,
- QuicRandom::GetInstance());
-}
-
-// static
-QuicConnectionId QuicUtils::CreateRandomConnectionId(
- uint8_t connection_id_length,
- QuicRandom* random) {
- QuicConnectionId connection_id;
- connection_id.set_length(connection_id_length);
- if (connection_id.length() > 0) {
- random->RandBytes(connection_id.mutable_data(), connection_id.length());
- }
- return connection_id;
-}
-
-// static
-QuicConnectionId QuicUtils::CreateZeroConnectionId(
- QuicTransportVersion version) {
- if (!VersionAllowsVariableLengthConnectionIds(version)) {
- char connection_id_bytes[8] = {0, 0, 0, 0, 0, 0, 0, 0};
- return QuicConnectionId(static_cast<char*>(connection_id_bytes),
- ABSL_ARRAYSIZE(connection_id_bytes));
- }
- return EmptyQuicConnectionId();
-}
-
-// static
-bool QuicUtils::IsConnectionIdLengthValidForVersion(
- size_t connection_id_length,
- QuicTransportVersion transport_version) {
- // No version of QUIC can support lengths that do not fit in an uint8_t.
- if (connection_id_length >
- static_cast<size_t>(std::numeric_limits<uint8_t>::max())) {
- return false;
- }
-
- if (transport_version == QUIC_VERSION_UNSUPPORTED ||
- transport_version == QUIC_VERSION_RESERVED_FOR_NEGOTIATION) {
- // Unknown versions could allow connection ID lengths up to 255.
- return true;
- }
-
- const uint8_t connection_id_length8 =
- static_cast<uint8_t>(connection_id_length);
- // Versions that do not support variable lengths only support length 8.
- if (!VersionAllowsVariableLengthConnectionIds(transport_version)) {
- return connection_id_length8 == kQuicDefaultConnectionIdLength;
- }
- // Versions that do support variable length but do not have length-prefixed
- // connection IDs use the 4-bit connection ID length encoding which can
- // only encode values 0 and 4-18.
- if (!VersionHasLengthPrefixedConnectionIds(transport_version)) {
- return connection_id_length8 == 0 ||
- (connection_id_length8 >= 4 &&
- connection_id_length8 <= kQuicMaxConnectionId4BitLength);
- }
- return connection_id_length8 <= kQuicMaxConnectionIdWithLengthPrefixLength;
-}
-
-// static
-bool QuicUtils::IsConnectionIdValidForVersion(
- QuicConnectionId connection_id,
- QuicTransportVersion transport_version) {
- return IsConnectionIdLengthValidForVersion(connection_id.length(),
- transport_version);
-}
-
-StatelessResetToken QuicUtils::GenerateStatelessResetToken(
- QuicConnectionId connection_id) {
- static_assert(sizeof(absl::uint128) == sizeof(StatelessResetToken),
- "bad size");
- static_assert(alignof(absl::uint128) >= alignof(StatelessResetToken),
- "bad alignment");
- absl::uint128 hash = FNV1a_128_Hash(
- absl::string_view(connection_id.data(), connection_id.length()));
- return *reinterpret_cast<StatelessResetToken*>(&hash);
-}
-
-// static
-QuicStreamCount QuicUtils::GetMaxStreamCount() {
- return (kMaxQuicStreamCount >> 2) + 1;
-}
-
-// static
-PacketNumberSpace QuicUtils::GetPacketNumberSpace(
- EncryptionLevel encryption_level) {
- switch (encryption_level) {
- case ENCRYPTION_INITIAL:
- return INITIAL_DATA;
- case ENCRYPTION_HANDSHAKE:
- return HANDSHAKE_DATA;
- case ENCRYPTION_ZERO_RTT:
- case ENCRYPTION_FORWARD_SECURE:
- return APPLICATION_DATA;
- default:
- QUIC_BUG(quic_bug_10839_3)
- << "Try to get packet number space of encryption level: "
- << encryption_level;
- return NUM_PACKET_NUMBER_SPACES;
- }
-}
-
-// static
-EncryptionLevel QuicUtils::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;
- }
-}
-
-// static
-bool QuicUtils::IsProbingFrame(QuicFrameType type) {
- switch (type) {
- case PATH_CHALLENGE_FRAME:
- case PATH_RESPONSE_FRAME:
- case NEW_CONNECTION_ID_FRAME:
- case PADDING_FRAME:
- return true;
- default:
- return false;
- }
-}
-
-// static
-bool QuicUtils::IsAckElicitingFrame(QuicFrameType type) {
- switch (type) {
- case PADDING_FRAME:
- case STOP_WAITING_FRAME:
- case ACK_FRAME:
- case CONNECTION_CLOSE_FRAME:
- return false;
- default:
- return true;
- }
-}
-
-// static
-bool QuicUtils::AreStatelessResetTokensEqual(
- const StatelessResetToken& token1,
- const StatelessResetToken& token2) {
- char byte = 0;
- for (size_t i = 0; i < kStatelessResetTokenLength; i++) {
- // This avoids compiler optimizations that could make us stop comparing
- // after we find a byte that doesn't match.
- byte |= (token1[i] ^ token2[i]);
- }
- return byte == 0;
-}
-
-bool IsValidWebTransportSessionId(WebTransportSessionId id,
- ParsedQuicVersion version) {
- QUICHE_DCHECK(version.UsesHttp3());
- return (id <= std::numeric_limits<QuicStreamId>::max()) &&
- QuicUtils::IsBidirectionalStreamId(id, version) &&
- QuicUtils::IsClientInitiatedStreamId(version.transport_version, id);
-}
-
-QuicByteCount MemSliceSpanTotalSize(absl::Span<QuicMemSlice> span) {
- QuicByteCount total = 0;
- for (const QuicMemSlice& slice : span) {
- total += slice.length();
- }
- return total;
-}
-
-std::string RawSha256(absl::string_view input) {
- std::string raw_hash;
- raw_hash.resize(SHA256_DIGEST_LENGTH);
- SHA256(reinterpret_cast<const uint8_t*>(input.data()), input.size(),
- reinterpret_cast<uint8_t*>(&raw_hash[0]));
- return raw_hash;
-}
-
-#undef RETURN_STRING_LITERAL // undef for jumbo builds
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_utils.h b/chromium/net/third_party/quiche/src/quic/core/quic_utils.h
deleted file mode 100644
index 9b5c6ff6e57..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_utils.h
+++ /dev/null
@@ -1,323 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_UTILS_H_
-#define QUICHE_QUIC_CORE_QUIC_UTILS_H_
-
-#include <cstddef>
-#include <cstdint>
-#include <sstream>
-#include <string>
-#include <type_traits>
-
-#include "absl/numeric/int128.h"
-#include "absl/strings/string_view.h"
-#include "absl/types/span.h"
-#include "quic/core/crypto/quic_random.h"
-#include "quic/core/frames/quic_frame.h"
-#include "quic/core/quic_connection_id.h"
-#include "quic/core/quic_error_codes.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_versions.h"
-#include "quic/platform/api/quic_export.h"
-#include "quic/platform/api/quic_iovec.h"
-#include "quic/platform/api/quic_mem_slice.h"
-#include "quic/platform/api/quic_socket_address.h"
-
-namespace quic {
-
-class QUIC_EXPORT_PRIVATE QuicUtils {
- public:
- QuicUtils() = delete;
-
- // Returns the 64 bit FNV1a hash of the data. See
- // http://www.isthe.com/chongo/tech/comp/fnv/index.html#FNV-param
- static uint64_t FNV1a_64_Hash(absl::string_view data);
-
- // Returns the 128 bit FNV1a hash of the data. See
- // http://www.isthe.com/chongo/tech/comp/fnv/index.html#FNV-param
- static absl::uint128 FNV1a_128_Hash(absl::string_view data);
-
- // Returns the 128 bit FNV1a hash of the two sequences of data. See
- // http://www.isthe.com/chongo/tech/comp/fnv/index.html#FNV-param
- static absl::uint128 FNV1a_128_Hash_Two(absl::string_view data1,
- absl::string_view data2);
-
- // Returns the 128 bit FNV1a hash of the three sequences of data. See
- // http://www.isthe.com/chongo/tech/comp/fnv/index.html#FNV-param
- static absl::uint128 FNV1a_128_Hash_Three(absl::string_view data1,
- absl::string_view data2,
- absl::string_view data3);
-
- // SerializeUint128 writes the first 96 bits of |v| in little-endian form
- // to |out|.
- static void SerializeUint128Short(absl::uint128 v, uint8_t* out);
-
- // Returns AddressChangeType as a string.
- static std::string AddressChangeTypeToString(AddressChangeType type);
-
- // Returns SentPacketState as a char*.
- static const char* SentPacketStateToString(SentPacketState state);
-
- // Returns QuicLongHeaderType as a char*.
- static const char* QuicLongHeaderTypetoString(QuicLongHeaderType type);
-
- // Returns AckResult as a char*.
- static const char* AckResultToString(AckResult result);
-
- // Determines and returns change type of address change from |old_address| to
- // |new_address|.
- static AddressChangeType DetermineAddressChangeType(
- const QuicSocketAddress& old_address,
- const QuicSocketAddress& new_address);
-
- // Copies |buffer_length| bytes from iov starting at offset |iov_offset| into
- // buffer. |iov| must be at least iov_offset+length total length and buffer
- // must be at least |length| long.
- static void CopyToBuffer(const struct iovec* iov,
- int iov_count,
- size_t iov_offset,
- size_t buffer_length,
- char* buffer);
-
- // Creates an iovec pointing to the same data as |data|.
- static struct iovec MakeIovec(absl::string_view data);
-
- // Returns the opposite Perspective of the |perspective| passed in.
- static constexpr Perspective InvertPerspective(Perspective perspective) {
- return perspective == Perspective::IS_CLIENT ? Perspective::IS_SERVER
- : Perspective::IS_CLIENT;
- }
-
- // Returns true if a packet is ackable. A packet is unackable if it can never
- // be acked. Occurs when a packet is never sent, after it is acknowledged
- // once, or if it's a crypto packet we never expect to receive an ack for.
- static bool IsAckable(SentPacketState state);
-
- // Returns true if frame with |type| is retransmittable. A retransmittable
- // frame should be retransmitted if it is detected as lost.
- static bool IsRetransmittableFrame(QuicFrameType type);
-
- // Returns true if |frame| is a handshake frame in version |version|.
- static bool IsHandshakeFrame(const QuicFrame& frame,
- QuicTransportVersion transport_version);
-
- // Return true if any frame in |frames| is of |type|.
- static bool ContainsFrameType(const QuicFrames& frames, QuicFrameType type);
-
- // Returns packet state corresponding to |retransmission_type|.
- static SentPacketState RetransmissionTypeToPacketState(
- TransmissionType retransmission_type);
-
- // Returns true if header with |first_byte| is considered as an IETF QUIC
- // packet header. This only works on the server.
- static bool IsIetfPacketHeader(uint8_t first_byte);
-
- // Returns true if header with |first_byte| is considered as an IETF QUIC
- // short packet header.
- static bool IsIetfPacketShortHeader(uint8_t first_byte);
-
- // Returns ID to denote an invalid stream of |version|.
- static QuicStreamId GetInvalidStreamId(QuicTransportVersion version);
-
- // Returns crypto stream ID of |version|.
- static QuicStreamId GetCryptoStreamId(QuicTransportVersion version);
-
- // Returns whether |id| is the stream ID for the crypto stream. If |version|
- // is a version where crypto data doesn't go over stream frames, this function
- // will always return false.
- static bool IsCryptoStreamId(QuicTransportVersion version, QuicStreamId id);
-
- // Returns headers stream ID of |version|.
- static QuicStreamId GetHeadersStreamId(QuicTransportVersion version);
-
- // Returns true if |id| is considered as client initiated stream ID.
- static bool IsClientInitiatedStreamId(QuicTransportVersion version,
- QuicStreamId id);
-
- // Returns true if |id| is considered as server initiated stream ID.
- static bool IsServerInitiatedStreamId(QuicTransportVersion version,
- QuicStreamId id);
-
- // Returns true if the stream ID represents a stream initiated by the
- // provided perspective.
- static bool IsOutgoingStreamId(ParsedQuicVersion version,
- QuicStreamId id,
- Perspective perspective);
-
- // Returns true if |id| is considered as bidirectional stream ID. Only used in
- // v99.
- static bool IsBidirectionalStreamId(QuicStreamId id,
- ParsedQuicVersion version);
-
- // Returns stream type. Either |perspective| or |peer_initiated| would be
- // enough together with |id|. This method enforces that the three parameters
- // are consistent. Only used in v99.
- static StreamType GetStreamType(QuicStreamId id,
- Perspective perspective,
- bool peer_initiated,
- ParsedQuicVersion version);
-
- // Returns the delta between consecutive stream IDs of the same type.
- static QuicStreamId StreamIdDelta(QuicTransportVersion version);
-
- // Returns the first initiated bidirectional stream ID of |perspective|.
- static QuicStreamId GetFirstBidirectionalStreamId(
- QuicTransportVersion version,
- Perspective perspective);
-
- // Returns the first initiated unidirectional stream ID of |perspective|.
- static QuicStreamId GetFirstUnidirectionalStreamId(
- QuicTransportVersion version,
- Perspective perspective);
-
- // Returns the largest possible client initiated bidirectional stream ID.
- static QuicStreamId GetMaxClientInitiatedBidirectionalStreamId(
- QuicTransportVersion version);
-
- // Generates a connection ID of length |expected_connection_id_length|
- // derived from |connection_id|.
- // This is guaranteed to be deterministic (calling this method with two
- // connection IDs that are equal is guaranteed to produce the same result).
- static QuicConnectionId CreateReplacementConnectionId(
- const QuicConnectionId& connection_id,
- uint8_t expected_connection_id_length);
-
- // Generates a 64bit connection ID derived from |connection_id|.
- // This is guaranteed to be deterministic (calling this method with two
- // connection IDs that are equal is guaranteed to produce the same result).
- static QuicConnectionId CreateReplacementConnectionId(
- const QuicConnectionId& connection_id);
-
- // Generates a random 64bit connection ID.
- static QuicConnectionId CreateRandomConnectionId();
-
- // Generates a random 64bit connection ID using the provided QuicRandom.
- static QuicConnectionId CreateRandomConnectionId(QuicRandom* random);
-
- // Generates a random connection ID of the given length.
- static QuicConnectionId CreateRandomConnectionId(
- uint8_t connection_id_length);
-
- // Generates a random connection ID of the given length using the provided
- // QuicRandom.
- static QuicConnectionId CreateRandomConnectionId(uint8_t connection_id_length,
- QuicRandom* random);
-
- // Returns true if the connection ID length is valid for this QUIC version.
- static bool IsConnectionIdLengthValidForVersion(
- size_t connection_id_length,
- QuicTransportVersion transport_version);
-
- // Returns true if the connection ID is valid for this QUIC version.
- static bool IsConnectionIdValidForVersion(
- QuicConnectionId connection_id,
- QuicTransportVersion transport_version);
-
- // Returns a connection ID suitable for QUIC use-cases that do not need the
- // connection ID for multiplexing. If the version allows variable lengths,
- // a connection of length zero is returned, otherwise 64bits set to zero.
- static QuicConnectionId CreateZeroConnectionId(QuicTransportVersion version);
-
- // Generates a 128bit stateless reset token based on a connection ID.
- static StatelessResetToken GenerateStatelessResetToken(
- QuicConnectionId connection_id);
-
- // Determines packet number space from |encryption_level|.
- static PacketNumberSpace GetPacketNumberSpace(
- EncryptionLevel encryption_level);
-
- // Determines encryption level to send packets in |packet_number_space|.
- static EncryptionLevel GetEncryptionLevel(
- PacketNumberSpace packet_number_space);
-
- // Get the maximum value for a V99/IETF QUIC stream count. If a count
- // exceeds this value, it will result in a stream ID that exceeds the
- // implementation limit on stream ID size.
- static QuicStreamCount GetMaxStreamCount();
-
- // Return true if this frame is an IETF probing frame.
- static bool IsProbingFrame(QuicFrameType type);
-
- // Return true if the two stateless reset tokens are equal. Performs the
- // comparison in constant time.
- static bool AreStatelessResetTokensEqual(const StatelessResetToken& token1,
- const StatelessResetToken& token2);
-
- // Return ture if this frame is an ack-eliciting frame.
- static bool IsAckElicitingFrame(QuicFrameType type);
-};
-
-// Returns true if the specific ID is a valid WebTransport session ID that our
-// implementation can process.
-bool IsValidWebTransportSessionId(WebTransportSessionId id,
- ParsedQuicVersion transport_version);
-
-QuicByteCount MemSliceSpanTotalSize(absl::Span<QuicMemSlice> span);
-
-// Computes a SHA-256 hash and returns the raw bytes of the hash.
-QUIC_EXPORT_PRIVATE std::string RawSha256(absl::string_view input);
-
-template <typename Mask>
-class QUIC_EXPORT_PRIVATE BitMask {
- public:
- // explicit to prevent (incorrect) usage like "BitMask bitmask = 0;".
- template <typename... Bits>
- explicit BitMask(Bits... bits) {
- mask_ = MakeMask(bits...);
- }
-
- BitMask() = default;
- BitMask(const BitMask& other) = default;
- BitMask& operator=(const BitMask& other) = default;
-
- template <typename... Bits>
- void Set(Bits... bits) {
- mask_ |= MakeMask(bits...);
- }
-
- template <typename Bit>
- bool IsSet(Bit bit) const {
- return (MakeMask(bit) & mask_) != 0;
- }
-
- void ClearAll() { mask_ = 0; }
-
- static constexpr size_t NumBits() { return 8 * sizeof(Mask); }
-
- friend bool operator==(const BitMask& lhs, const BitMask& rhs) {
- return lhs.mask_ == rhs.mask_;
- }
-
- std::string DebugString() const {
- std::ostringstream oss;
- oss << "0x" << std::hex << mask_;
- return oss.str();
- }
-
- private:
- template <typename Bit>
- static std::enable_if_t<std::is_enum<Bit>::value, Mask> MakeMask(Bit bit) {
- using IntType = typename std::underlying_type<Bit>::type;
- return Mask(1) << static_cast<IntType>(bit);
- }
-
- template <typename Bit>
- static std::enable_if_t<!std::is_enum<Bit>::value, Mask> MakeMask(Bit bit) {
- return Mask(1) << bit;
- }
-
- template <typename Bit, typename... Bits>
- static Mask MakeMask(Bit first_bit, Bits... other_bits) {
- return MakeMask(first_bit) | MakeMask(other_bits...);
- }
-
- Mask mask_ = 0;
-};
-
-using BitMask64 = BitMask<uint64_t>;
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_QUIC_UTILS_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_utils_test.cc b/chromium/net/third_party/quiche/src/quic/core/quic_utils_test.cc
deleted file mode 100644
index a02633046e5..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_utils_test.cc
+++ /dev/null
@@ -1,404 +0,0 @@
-// Copyright (c) 2013 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 "quic/core/quic_utils.h"
-
-#include <string>
-
-#include "absl/base/macros.h"
-#include "absl/numeric/int128.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/crypto/crypto_protocol.h"
-#include "quic/core/quic_connection_id.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/quic_test_utils.h"
-
-namespace quic {
-namespace test {
-namespace {
-
-class QuicUtilsTest : public QuicTest {};
-
-TEST_F(QuicUtilsTest, DetermineAddressChangeType) {
- const std::string kIPv4String1 = "1.2.3.4";
- const std::string kIPv4String2 = "1.2.3.5";
- const std::string kIPv4String3 = "1.1.3.5";
- const std::string kIPv6String1 = "2001:700:300:1800::f";
- const std::string kIPv6String2 = "2001:700:300:1800:1:1:1:f";
- QuicSocketAddress old_address;
- QuicSocketAddress new_address;
- QuicIpAddress address;
-
- EXPECT_EQ(NO_CHANGE,
- QuicUtils::DetermineAddressChangeType(old_address, new_address));
- ASSERT_TRUE(address.FromString(kIPv4String1));
- old_address = QuicSocketAddress(address, 1234);
- EXPECT_EQ(NO_CHANGE,
- QuicUtils::DetermineAddressChangeType(old_address, new_address));
- new_address = QuicSocketAddress(address, 1234);
- EXPECT_EQ(NO_CHANGE,
- QuicUtils::DetermineAddressChangeType(old_address, new_address));
-
- new_address = QuicSocketAddress(address, 5678);
- EXPECT_EQ(PORT_CHANGE,
- QuicUtils::DetermineAddressChangeType(old_address, new_address));
- ASSERT_TRUE(address.FromString(kIPv6String1));
- old_address = QuicSocketAddress(address, 1234);
- new_address = QuicSocketAddress(address, 5678);
- EXPECT_EQ(PORT_CHANGE,
- QuicUtils::DetermineAddressChangeType(old_address, new_address));
-
- ASSERT_TRUE(address.FromString(kIPv4String1));
- old_address = QuicSocketAddress(address, 1234);
- ASSERT_TRUE(address.FromString(kIPv6String1));
- new_address = QuicSocketAddress(address, 1234);
- EXPECT_EQ(IPV4_TO_IPV6_CHANGE,
- QuicUtils::DetermineAddressChangeType(old_address, new_address));
-
- old_address = QuicSocketAddress(address, 1234);
- ASSERT_TRUE(address.FromString(kIPv4String1));
- new_address = QuicSocketAddress(address, 1234);
- EXPECT_EQ(IPV6_TO_IPV4_CHANGE,
- QuicUtils::DetermineAddressChangeType(old_address, new_address));
-
- ASSERT_TRUE(address.FromString(kIPv6String2));
- new_address = QuicSocketAddress(address, 1234);
- EXPECT_EQ(IPV6_TO_IPV6_CHANGE,
- QuicUtils::DetermineAddressChangeType(old_address, new_address));
-
- ASSERT_TRUE(address.FromString(kIPv4String1));
- old_address = QuicSocketAddress(address, 1234);
- ASSERT_TRUE(address.FromString(kIPv4String2));
- new_address = QuicSocketAddress(address, 1234);
- EXPECT_EQ(IPV4_SUBNET_CHANGE,
- QuicUtils::DetermineAddressChangeType(old_address, new_address));
- ASSERT_TRUE(address.FromString(kIPv4String3));
- new_address = QuicSocketAddress(address, 1234);
- EXPECT_EQ(IPV4_TO_IPV4_CHANGE,
- QuicUtils::DetermineAddressChangeType(old_address, new_address));
-}
-
-absl::uint128 IncrementalHashReference(const void* data, size_t len) {
- // The two constants are defined as part of the hash algorithm.
- // see http://www.isthe.com/chongo/tech/comp/fnv/
- // hash = 144066263297769815596495629667062367629
- absl::uint128 hash = absl::MakeUint128(UINT64_C(7809847782465536322),
- UINT64_C(7113472399480571277));
- // kPrime = 309485009821345068724781371
- const absl::uint128 kPrime = absl::MakeUint128(16777216, 315);
- const uint8_t* octets = reinterpret_cast<const uint8_t*>(data);
- for (size_t i = 0; i < len; ++i) {
- hash = hash ^ absl::MakeUint128(0, octets[i]);
- hash = hash * kPrime;
- }
- return hash;
-}
-
-TEST_F(QuicUtilsTest, ReferenceTest) {
- std::vector<uint8_t> data(32);
- for (size_t i = 0; i < data.size(); ++i) {
- data[i] = i % 255;
- }
- EXPECT_EQ(IncrementalHashReference(data.data(), data.size()),
- QuicUtils::FNV1a_128_Hash(absl::string_view(
- reinterpret_cast<const char*>(data.data()), data.size())));
-}
-
-TEST_F(QuicUtilsTest, IsUnackable) {
- for (size_t i = FIRST_PACKET_STATE; i <= LAST_PACKET_STATE; ++i) {
- if (i == NEVER_SENT || i == ACKED || i == UNACKABLE) {
- EXPECT_FALSE(QuicUtils::IsAckable(static_cast<SentPacketState>(i)));
- } else {
- EXPECT_TRUE(QuicUtils::IsAckable(static_cast<SentPacketState>(i)));
- }
- }
-}
-
-TEST_F(QuicUtilsTest, RetransmissionTypeToPacketState) {
- for (size_t i = FIRST_TRANSMISSION_TYPE; i <= LAST_TRANSMISSION_TYPE; ++i) {
- if (i == NOT_RETRANSMISSION) {
- continue;
- }
- SentPacketState state = QuicUtils::RetransmissionTypeToPacketState(
- static_cast<TransmissionType>(i));
- if (i == HANDSHAKE_RETRANSMISSION) {
- EXPECT_EQ(HANDSHAKE_RETRANSMITTED, state);
- } else if (i == LOSS_RETRANSMISSION) {
- 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) {
- EXPECT_EQ(UNACKABLE, state);
- } else {
- QUICHE_DCHECK(false)
- << "No corresponding packet state according to transmission type: "
- << i;
- }
- }
-}
-
-TEST_F(QuicUtilsTest, IsIetfPacketHeader) {
- // IETF QUIC short header
- uint8_t first_byte = 0;
- EXPECT_TRUE(QuicUtils::IsIetfPacketHeader(first_byte));
- EXPECT_TRUE(QuicUtils::IsIetfPacketShortHeader(first_byte));
-
- // IETF QUIC long header
- first_byte |= (FLAGS_LONG_HEADER | FLAGS_DEMULTIPLEXING_BIT);
- EXPECT_TRUE(QuicUtils::IsIetfPacketHeader(first_byte));
- EXPECT_FALSE(QuicUtils::IsIetfPacketShortHeader(first_byte));
-
- // IETF QUIC long header, version negotiation.
- first_byte = 0;
- first_byte |= FLAGS_LONG_HEADER;
- EXPECT_TRUE(QuicUtils::IsIetfPacketHeader(first_byte));
- EXPECT_FALSE(QuicUtils::IsIetfPacketShortHeader(first_byte));
-
- // GQUIC
- first_byte = 0;
- first_byte |= PACKET_PUBLIC_FLAGS_8BYTE_CONNECTION_ID;
- EXPECT_FALSE(QuicUtils::IsIetfPacketHeader(first_byte));
- EXPECT_FALSE(QuicUtils::IsIetfPacketShortHeader(first_byte));
-}
-
-TEST_F(QuicUtilsTest, ReplacementConnectionIdIsDeterministic) {
- // Verify that two equal connection IDs get the same replacement.
- QuicConnectionId connection_id64a = TestConnectionId(33);
- QuicConnectionId connection_id64b = TestConnectionId(33);
- EXPECT_EQ(connection_id64a, connection_id64b);
- EXPECT_EQ(QuicUtils::CreateReplacementConnectionId(connection_id64a),
- QuicUtils::CreateReplacementConnectionId(connection_id64b));
- QuicConnectionId connection_id72a = TestConnectionIdNineBytesLong(42);
- QuicConnectionId connection_id72b = TestConnectionIdNineBytesLong(42);
- EXPECT_EQ(connection_id72a, connection_id72b);
- EXPECT_EQ(QuicUtils::CreateReplacementConnectionId(connection_id72a),
- QuicUtils::CreateReplacementConnectionId(connection_id72b));
- // Test variant with custom length.
- EXPECT_EQ(QuicUtils::CreateReplacementConnectionId(connection_id64a, 7),
- QuicUtils::CreateReplacementConnectionId(connection_id64b, 7));
- EXPECT_EQ(QuicUtils::CreateReplacementConnectionId(connection_id64a, 9),
- QuicUtils::CreateReplacementConnectionId(connection_id64b, 9));
- EXPECT_EQ(QuicUtils::CreateReplacementConnectionId(connection_id64a, 16),
- QuicUtils::CreateReplacementConnectionId(connection_id64b, 16));
- EXPECT_EQ(QuicUtils::CreateReplacementConnectionId(connection_id72a, 7),
- QuicUtils::CreateReplacementConnectionId(connection_id72b, 7));
- EXPECT_EQ(QuicUtils::CreateReplacementConnectionId(connection_id72a, 9),
- QuicUtils::CreateReplacementConnectionId(connection_id72b, 9));
- EXPECT_EQ(QuicUtils::CreateReplacementConnectionId(connection_id72a, 16),
- QuicUtils::CreateReplacementConnectionId(connection_id72b, 16));
- EXPECT_EQ(QuicUtils::CreateReplacementConnectionId(connection_id72a, 32),
- QuicUtils::CreateReplacementConnectionId(connection_id72b, 32));
- EXPECT_EQ(QuicUtils::CreateReplacementConnectionId(connection_id72a, 255),
- QuicUtils::CreateReplacementConnectionId(connection_id72b, 255));
-}
-
-TEST_F(QuicUtilsTest, ReplacementConnectionIdLengthIsCorrect) {
- // Verify that all lengths get replaced by kQuicDefaultConnectionIdLength.
- const char connection_id_bytes[255] = {};
- for (uint8_t i = 0; i < sizeof(connection_id_bytes) - 1; ++i) {
- QuicConnectionId connection_id(connection_id_bytes, i);
- QuicConnectionId replacement_connection_id =
- QuicUtils::CreateReplacementConnectionId(connection_id);
- EXPECT_EQ(kQuicDefaultConnectionIdLength,
- replacement_connection_id.length());
- // Test variant with custom length.
- QuicConnectionId replacement_connection_id7 =
- QuicUtils::CreateReplacementConnectionId(connection_id, 7);
- EXPECT_EQ(7, replacement_connection_id7.length());
- QuicConnectionId replacement_connection_id9 =
- QuicUtils::CreateReplacementConnectionId(connection_id, 9);
- EXPECT_EQ(9, replacement_connection_id9.length());
- QuicConnectionId replacement_connection_id16 =
- QuicUtils::CreateReplacementConnectionId(connection_id, 16);
- EXPECT_EQ(16, replacement_connection_id16.length());
- QuicConnectionId replacement_connection_id32 =
- QuicUtils::CreateReplacementConnectionId(connection_id, 32);
- EXPECT_EQ(32, replacement_connection_id32.length());
- QuicConnectionId replacement_connection_id255 =
- QuicUtils::CreateReplacementConnectionId(connection_id, 255);
- EXPECT_EQ(255, replacement_connection_id255.length());
- }
-}
-
-TEST_F(QuicUtilsTest, ReplacementConnectionIdHasEntropy) {
- // Make sure all these test connection IDs have different replacements.
- for (uint64_t i = 0; i < 256; ++i) {
- QuicConnectionId connection_id_i = TestConnectionId(i);
- EXPECT_NE(connection_id_i,
- QuicUtils::CreateReplacementConnectionId(connection_id_i));
- for (uint64_t j = i + 1; j <= 256; ++j) {
- QuicConnectionId connection_id_j = TestConnectionId(j);
- EXPECT_NE(connection_id_i, connection_id_j);
- EXPECT_NE(QuicUtils::CreateReplacementConnectionId(connection_id_i),
- QuicUtils::CreateReplacementConnectionId(connection_id_j));
- // Test variant with custom length.
- EXPECT_NE(QuicUtils::CreateReplacementConnectionId(connection_id_i, 7),
- QuicUtils::CreateReplacementConnectionId(connection_id_j, 7));
- EXPECT_NE(QuicUtils::CreateReplacementConnectionId(connection_id_i, 9),
- QuicUtils::CreateReplacementConnectionId(connection_id_j, 9));
- EXPECT_NE(QuicUtils::CreateReplacementConnectionId(connection_id_i, 16),
- QuicUtils::CreateReplacementConnectionId(connection_id_j, 16));
- EXPECT_NE(QuicUtils::CreateReplacementConnectionId(connection_id_i, 32),
- QuicUtils::CreateReplacementConnectionId(connection_id_j, 32));
- EXPECT_NE(QuicUtils::CreateReplacementConnectionId(connection_id_i, 255),
- QuicUtils::CreateReplacementConnectionId(connection_id_j, 255));
- }
- }
-}
-
-TEST_F(QuicUtilsTest, RandomConnectionId) {
- MockRandom random(33);
- QuicConnectionId connection_id = QuicUtils::CreateRandomConnectionId(&random);
- EXPECT_EQ(connection_id.length(), sizeof(uint64_t));
- char connection_id_bytes[sizeof(uint64_t)];
- random.RandBytes(connection_id_bytes, ABSL_ARRAYSIZE(connection_id_bytes));
- EXPECT_EQ(connection_id,
- QuicConnectionId(static_cast<char*>(connection_id_bytes),
- ABSL_ARRAYSIZE(connection_id_bytes)));
- EXPECT_NE(connection_id, EmptyQuicConnectionId());
- EXPECT_NE(connection_id, TestConnectionId());
- EXPECT_NE(connection_id, TestConnectionId(1));
- EXPECT_NE(connection_id, TestConnectionIdNineBytesLong(1));
- EXPECT_EQ(QuicUtils::CreateRandomConnectionId().length(),
- kQuicDefaultConnectionIdLength);
-}
-
-TEST_F(QuicUtilsTest, RandomConnectionIdVariableLength) {
- MockRandom random(1337);
- const uint8_t connection_id_length = 9;
- QuicConnectionId connection_id =
- QuicUtils::CreateRandomConnectionId(connection_id_length, &random);
- EXPECT_EQ(connection_id.length(), connection_id_length);
- char connection_id_bytes[connection_id_length];
- random.RandBytes(connection_id_bytes, ABSL_ARRAYSIZE(connection_id_bytes));
- EXPECT_EQ(connection_id,
- QuicConnectionId(static_cast<char*>(connection_id_bytes),
- ABSL_ARRAYSIZE(connection_id_bytes)));
- EXPECT_NE(connection_id, EmptyQuicConnectionId());
- EXPECT_NE(connection_id, TestConnectionId());
- EXPECT_NE(connection_id, TestConnectionId(1));
- EXPECT_NE(connection_id, TestConnectionIdNineBytesLong(1));
- EXPECT_EQ(QuicUtils::CreateRandomConnectionId(connection_id_length).length(),
- connection_id_length);
-}
-
-TEST_F(QuicUtilsTest, VariableLengthConnectionId) {
- EXPECT_FALSE(VersionAllowsVariableLengthConnectionIds(QUIC_VERSION_43));
- EXPECT_TRUE(QuicUtils::IsConnectionIdValidForVersion(
- QuicUtils::CreateZeroConnectionId(QUIC_VERSION_43), QUIC_VERSION_43));
- EXPECT_TRUE(QuicUtils::IsConnectionIdValidForVersion(
- QuicUtils::CreateZeroConnectionId(QUIC_VERSION_50), QUIC_VERSION_50));
- EXPECT_NE(QuicUtils::CreateZeroConnectionId(QUIC_VERSION_43),
- EmptyQuicConnectionId());
- EXPECT_EQ(QuicUtils::CreateZeroConnectionId(QUIC_VERSION_50),
- EmptyQuicConnectionId());
- EXPECT_FALSE(QuicUtils::IsConnectionIdValidForVersion(EmptyQuicConnectionId(),
- QUIC_VERSION_43));
-}
-
-TEST_F(QuicUtilsTest, StatelessResetToken) {
- QuicConnectionId connection_id1a = test::TestConnectionId(1);
- QuicConnectionId connection_id1b = test::TestConnectionId(1);
- QuicConnectionId connection_id2 = test::TestConnectionId(2);
- StatelessResetToken token1a =
- QuicUtils::GenerateStatelessResetToken(connection_id1a);
- StatelessResetToken token1b =
- QuicUtils::GenerateStatelessResetToken(connection_id1b);
- StatelessResetToken token2 =
- QuicUtils::GenerateStatelessResetToken(connection_id2);
- EXPECT_EQ(token1a, token1b);
- EXPECT_NE(token1a, token2);
- EXPECT_TRUE(QuicUtils::AreStatelessResetTokensEqual(token1a, token1b));
- EXPECT_FALSE(QuicUtils::AreStatelessResetTokensEqual(token1a, token2));
-}
-
-enum class TestEnumClassBit : uint8_t {
- BIT_ZERO = 0,
- BIT_ONE,
- BIT_TWO,
-};
-
-enum TestEnumBit {
- TEST_BIT_0 = 0,
- TEST_BIT_1,
- TEST_BIT_2,
-};
-
-TEST(QuicBitMaskTest, EnumClass) {
- BitMask64 mask(TestEnumClassBit::BIT_ZERO, TestEnumClassBit::BIT_TWO);
- EXPECT_TRUE(mask.IsSet(TestEnumClassBit::BIT_ZERO));
- EXPECT_FALSE(mask.IsSet(TestEnumClassBit::BIT_ONE));
- EXPECT_TRUE(mask.IsSet(TestEnumClassBit::BIT_TWO));
-
- mask.ClearAll();
- EXPECT_FALSE(mask.IsSet(TestEnumClassBit::BIT_ZERO));
- EXPECT_FALSE(mask.IsSet(TestEnumClassBit::BIT_ONE));
- EXPECT_FALSE(mask.IsSet(TestEnumClassBit::BIT_TWO));
-}
-
-TEST(QuicBitMaskTest, Enum) {
- BitMask64 mask(TEST_BIT_1, TEST_BIT_2);
- EXPECT_FALSE(mask.IsSet(TEST_BIT_0));
- EXPECT_TRUE(mask.IsSet(TEST_BIT_1));
- EXPECT_TRUE(mask.IsSet(TEST_BIT_2));
-
- mask.ClearAll();
- EXPECT_FALSE(mask.IsSet(TEST_BIT_0));
- EXPECT_FALSE(mask.IsSet(TEST_BIT_1));
- EXPECT_FALSE(mask.IsSet(TEST_BIT_2));
-}
-
-TEST(QuicBitMaskTest, Integer) {
- BitMask64 mask(1, 3);
- mask.Set(3);
- mask.Set(5, 7, 9);
- EXPECT_FALSE(mask.IsSet(0));
- EXPECT_TRUE(mask.IsSet(1));
- EXPECT_FALSE(mask.IsSet(2));
- EXPECT_TRUE(mask.IsSet(3));
- EXPECT_FALSE(mask.IsSet(4));
- EXPECT_TRUE(mask.IsSet(5));
- EXPECT_FALSE(mask.IsSet(6));
- EXPECT_TRUE(mask.IsSet(7));
- EXPECT_FALSE(mask.IsSet(8));
- EXPECT_TRUE(mask.IsSet(9));
-}
-
-TEST(QuicBitMaskTest, NumBits) {
- EXPECT_EQ(64u, BitMask64::NumBits());
- EXPECT_EQ(32u, BitMask<uint32_t>::NumBits());
-}
-
-TEST(QuicBitMaskTest, Constructor) {
- BitMask64 empty_mask;
- for (size_t bit = 0; bit < empty_mask.NumBits(); ++bit) {
- EXPECT_FALSE(empty_mask.IsSet(bit));
- }
-
- BitMask64 mask(1, 3);
- BitMask64 mask2 = mask;
- BitMask64 mask3(mask2);
-
- for (size_t bit = 0; bit < mask.NumBits(); ++bit) {
- EXPECT_EQ(mask.IsSet(bit), mask2.IsSet(bit));
- EXPECT_EQ(mask.IsSet(bit), mask3.IsSet(bit));
- }
-
- EXPECT_TRUE(std::is_trivially_copyable<BitMask64>::value);
-}
-
-} // namespace
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_version_manager.cc b/chromium/net/third_party/quiche/src/quic/core/quic_version_manager.cc
deleted file mode 100644
index 13094564258..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_version_manager.cc
+++ /dev/null
@@ -1,94 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_version_manager.h"
-
-#include <algorithm>
-
-#include "absl/base/macros.h"
-#include "quic/core/quic_versions.h"
-#include "quic/platform/api/quic_flag_utils.h"
-#include "quic/platform/api/quic_flags.h"
-
-namespace quic {
-
-QuicVersionManager::QuicVersionManager(
- ParsedQuicVersionVector supported_versions)
- : allowed_supported_versions_(std::move(supported_versions)) {}
-
-QuicVersionManager::~QuicVersionManager() {}
-
-const ParsedQuicVersionVector& QuicVersionManager::GetSupportedVersions() {
- MaybeRefilterSupportedVersions();
- return filtered_supported_versions_;
-}
-
-const ParsedQuicVersionVector&
-QuicVersionManager::GetSupportedVersionsWithOnlyHttp3() {
- MaybeRefilterSupportedVersions();
- return filtered_supported_versions_with_http3_;
-}
-
-const std::vector<std::string>& QuicVersionManager::GetSupportedAlpns() {
- MaybeRefilterSupportedVersions();
- return filtered_supported_alpns_;
-}
-
-void QuicVersionManager::MaybeRefilterSupportedVersions() {
- static_assert(SupportedVersions().size() == 6u,
- "Supported versions out of sync");
- if (enable_version_2_draft_01_ !=
- GetQuicReloadableFlag(quic_enable_version_2_draft_01) ||
- disable_version_rfcv1_ !=
- GetQuicReloadableFlag(quic_disable_version_rfcv1) ||
- disable_version_draft_29_ !=
- GetQuicReloadableFlag(quic_disable_version_draft_29) ||
- disable_version_q050_ !=
- GetQuicReloadableFlag(quic_disable_version_q050) ||
- disable_version_q046_ !=
- GetQuicReloadableFlag(quic_disable_version_q046) ||
- disable_version_q043_ !=
- GetQuicReloadableFlag(quic_disable_version_q043)) {
- enable_version_2_draft_01_ =
- GetQuicReloadableFlag(quic_enable_version_2_draft_01);
- disable_version_rfcv1_ = GetQuicReloadableFlag(quic_disable_version_rfcv1);
- disable_version_draft_29_ =
- GetQuicReloadableFlag(quic_disable_version_draft_29);
- disable_version_q050_ = GetQuicReloadableFlag(quic_disable_version_q050);
- disable_version_q046_ = GetQuicReloadableFlag(quic_disable_version_q046);
- disable_version_q043_ = GetQuicReloadableFlag(quic_disable_version_q043);
-
- RefilterSupportedVersions();
- }
-}
-
-void QuicVersionManager::RefilterSupportedVersions() {
- filtered_supported_versions_ =
- FilterSupportedVersions(allowed_supported_versions_);
- filtered_supported_versions_with_http3_.clear();
- filtered_transport_versions_.clear();
- filtered_supported_alpns_.clear();
- for (const ParsedQuicVersion& version : filtered_supported_versions_) {
- auto transport_version = version.transport_version;
- if (std::find(filtered_transport_versions_.begin(),
- filtered_transport_versions_.end(),
- transport_version) == filtered_transport_versions_.end()) {
- filtered_transport_versions_.push_back(transport_version);
- }
- if (version.UsesHttp3()) {
- filtered_supported_versions_with_http3_.push_back(version);
- }
- if (std::find(filtered_supported_alpns_.begin(),
- filtered_supported_alpns_.end(),
- AlpnForVersion(version)) == filtered_supported_alpns_.end()) {
- filtered_supported_alpns_.emplace_back(AlpnForVersion(version));
- }
- }
-}
-
-void QuicVersionManager::AddCustomAlpn(const std::string& alpn) {
- filtered_supported_alpns_.push_back(alpn);
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_version_manager.h b/chromium/net/third_party/quiche/src/quic/core/quic_version_manager.h
deleted file mode 100644
index 44e134ac363..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_version_manager.h
+++ /dev/null
@@ -1,95 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_VERSION_MANAGER_H_
-#define QUICHE_QUIC_CORE_QUIC_VERSION_MANAGER_H_
-
-#include "quic/core/quic_versions.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// Used to generate filtered supported versions based on flags.
-class QUIC_EXPORT_PRIVATE QuicVersionManager {
- public:
- // |supported_versions| should be sorted in the order of preference (typically
- // highest supported version to the lowest supported version).
- explicit QuicVersionManager(ParsedQuicVersionVector supported_versions);
- virtual ~QuicVersionManager();
-
- // Returns currently supported QUIC versions. This vector has the same order
- // as the versions passed to the constructor.
- const ParsedQuicVersionVector& GetSupportedVersions();
-
- // Returns currently supported versions using HTTP/3.
- const ParsedQuicVersionVector& GetSupportedVersionsWithOnlyHttp3();
-
- // Returns the list of supported ALPNs, based on the current supported
- // versions and any custom additions by subclasses.
- const std::vector<std::string>& GetSupportedAlpns();
-
- protected:
- // If the value of any reloadable flag is different from the cached value,
- // re-filter |filtered_supported_versions_| and update the cached flag values.
- // Otherwise, does nothing.
- // TODO(dschinazi): Make private when deprecating
- // FLAGS_gfe2_restart_flag_quic_disable_old_alt_svc_format.
- void MaybeRefilterSupportedVersions();
-
- // Refilters filtered_supported_versions_.
- virtual void RefilterSupportedVersions();
-
- // RefilterSupportedVersions() must be called before calling this method.
- // TODO(dschinazi): Remove when deprecating
- // FLAGS_gfe2_restart_flag_quic_disable_old_alt_svc_format.
- const QuicTransportVersionVector& filtered_transport_versions() const {
- return filtered_transport_versions_;
- }
-
- // Subclasses may add custom ALPNs to the supported list by overriding
- // RefilterSupportedVersions() to first call
- // QuicVersionManager::RefilterSupportedVersions() then AddCustomAlpn().
- // Must not be called elsewhere.
- void AddCustomAlpn(const std::string& alpn);
-
- private:
- // Cached value of reloadable flags.
- // quic_enable_version_2_draft_01 flag
- bool enable_version_2_draft_01_ = false;
- // quic_disable_version_rfcv1 flag
- bool disable_version_rfcv1_ = true;
- // quic_disable_version_draft_29 flag
- bool disable_version_draft_29_ = true;
- // quic_disable_version_q050 flag
- bool disable_version_q050_ = true;
- // quic_disable_version_q046 flag
- bool disable_version_q046_ = true;
- // quic_disable_version_q043 flag
- bool disable_version_q043_ = true;
-
- // The list of versions that may be supported.
- const ParsedQuicVersionVector allowed_supported_versions_;
-
- // The following vectors are calculated from reloadable flags by
- // RefilterSupportedVersions(). It is performed lazily when first needed, and
- // after that, since the calculation is relatively expensive, only if the flag
- // values change.
-
- // This vector contains QUIC versions which are currently supported based on
- // flags.
- ParsedQuicVersionVector filtered_supported_versions_;
- // Currently supported versions using HTTP/3.
- ParsedQuicVersionVector filtered_supported_versions_with_http3_;
- // This vector contains the transport versions from
- // |filtered_supported_versions_|. No guarantees are made that the same
- // transport version isn't repeated.
- QuicTransportVersionVector filtered_transport_versions_;
- // Contains the list of ALPNs corresponding to filtered_supported_versions_
- // with custom ALPNs added.
- std::vector<std::string> filtered_supported_alpns_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_QUIC_VERSION_MANAGER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_version_manager_test.cc b/chromium/net/third_party/quiche/src/quic/core/quic_version_manager_test.cc
deleted file mode 100644
index da87c4a1d53..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_version_manager_test.cc
+++ /dev/null
@@ -1,87 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_version_manager.h"
-
-#include "absl/base/macros.h"
-#include "quic/core/quic_versions.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_test.h"
-
-using ::testing::ElementsAre;
-
-namespace quic {
-namespace test {
-namespace {
-
-class QuicVersionManagerTest : public QuicTest {};
-
-TEST_F(QuicVersionManagerTest, QuicVersionManager) {
- static_assert(SupportedVersions().size() == 6u,
- "Supported versions out of sync");
- for (const ParsedQuicVersion& version : AllSupportedVersions()) {
- QuicEnableVersion(version);
- }
- QuicDisableVersion(ParsedQuicVersion::V2Draft01());
- QuicDisableVersion(ParsedQuicVersion::RFCv1());
- QuicDisableVersion(ParsedQuicVersion::Draft29());
- QuicVersionManager manager(AllSupportedVersions());
-
- ParsedQuicVersionVector expected_parsed_versions;
- expected_parsed_versions.push_back(ParsedQuicVersion::Q050());
- expected_parsed_versions.push_back(ParsedQuicVersion::Q046());
- expected_parsed_versions.push_back(ParsedQuicVersion::Q043());
-
- EXPECT_EQ(expected_parsed_versions, manager.GetSupportedVersions());
-
- EXPECT_EQ(FilterSupportedVersions(AllSupportedVersions()),
- manager.GetSupportedVersions());
- EXPECT_TRUE(manager.GetSupportedVersionsWithOnlyHttp3().empty());
- EXPECT_THAT(manager.GetSupportedAlpns(),
- ElementsAre("h3-Q050", "h3-Q046", "h3-Q043"));
-
- int offset = 0;
- QuicEnableVersion(ParsedQuicVersion::Draft29());
- expected_parsed_versions.insert(expected_parsed_versions.begin(),
- ParsedQuicVersion::Draft29());
- EXPECT_EQ(expected_parsed_versions, manager.GetSupportedVersions());
- EXPECT_EQ(FilterSupportedVersions(AllSupportedVersions()),
- manager.GetSupportedVersions());
- EXPECT_EQ(1u, manager.GetSupportedVersionsWithOnlyHttp3().size());
- EXPECT_EQ(CurrentSupportedHttp3Versions(),
- manager.GetSupportedVersionsWithOnlyHttp3());
- EXPECT_THAT(manager.GetSupportedAlpns(),
- ElementsAre("h3-29", "h3-Q050", "h3-Q046", "h3-Q043"));
-
- offset++;
- QuicEnableVersion(ParsedQuicVersion::RFCv1());
- expected_parsed_versions.insert(expected_parsed_versions.begin(),
- ParsedQuicVersion::RFCv1());
- EXPECT_EQ(expected_parsed_versions, manager.GetSupportedVersions());
- EXPECT_EQ(FilterSupportedVersions(AllSupportedVersions()),
- manager.GetSupportedVersions());
- EXPECT_EQ(2u, manager.GetSupportedVersionsWithOnlyHttp3().size());
- EXPECT_EQ(CurrentSupportedHttp3Versions(),
- manager.GetSupportedVersionsWithOnlyHttp3());
- EXPECT_THAT(manager.GetSupportedAlpns(),
- ElementsAre("h3", "h3-29", "h3-Q050", "h3-Q046", "h3-Q043"));
-
- offset++;
- QuicEnableVersion(ParsedQuicVersion::V2Draft01());
- expected_parsed_versions.insert(expected_parsed_versions.begin(),
- ParsedQuicVersion::V2Draft01());
- EXPECT_EQ(expected_parsed_versions, manager.GetSupportedVersions());
- EXPECT_EQ(FilterSupportedVersions(AllSupportedVersions()),
- manager.GetSupportedVersions());
- EXPECT_EQ(3u, manager.GetSupportedVersionsWithOnlyHttp3().size());
- EXPECT_EQ(CurrentSupportedHttp3Versions(),
- manager.GetSupportedVersionsWithOnlyHttp3());
- EXPECT_THAT(
- manager.GetSupportedAlpns(),
- ElementsAre("h3", "h3-29", "h3-Q050", "h3-Q046", "h3-Q043"));
-}
-
-} // namespace
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_versions.cc b/chromium/net/third_party/quiche/src/quic/core/quic_versions.cc
deleted file mode 100644
index 21ec163807c..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_versions.cc
+++ /dev/null
@@ -1,668 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_versions.h"
-
-#include <string>
-
-#include "absl/base/macros.h"
-#include "absl/strings/numbers.h"
-#include "absl/strings/str_cat.h"
-#include "absl/strings/str_split.h"
-#include "quic/core/crypto/quic_random.h"
-#include "quic/core/quic_tag.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_flag_utils.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-#include "common/quiche_endian.h"
-#include "common/quiche_text_utils.h"
-
-namespace quic {
-namespace {
-
-QuicVersionLabel CreateRandomVersionLabelForNegotiation() {
- QuicVersionLabel result;
- if (!GetQuicFlag(FLAGS_quic_disable_version_negotiation_grease_randomness)) {
- QuicRandom::GetInstance()->RandBytes(&result, sizeof(result));
- } else {
- result = MakeVersionLabel(0xd1, 0x57, 0x38, 0x3f);
- }
- result &= 0xf0f0f0f0;
- result |= 0x0a0a0a0a;
- return result;
-}
-
-void SetVersionFlag(const ParsedQuicVersion& version, bool should_enable) {
- static_assert(SupportedVersions().size() == 6u,
- "Supported versions out of sync");
- const bool enable = should_enable;
- const bool disable = !should_enable;
- if (version == ParsedQuicVersion::V2Draft01()) {
- SetQuicReloadableFlag(quic_enable_version_2_draft_01, enable);
- } else if (version == ParsedQuicVersion::RFCv1()) {
- SetQuicReloadableFlag(quic_disable_version_rfcv1, disable);
- } else if (version == ParsedQuicVersion::Draft29()) {
- SetQuicReloadableFlag(quic_disable_version_draft_29, disable);
- } else if (version == ParsedQuicVersion::Q050()) {
- SetQuicReloadableFlag(quic_disable_version_q050, disable);
- } else if (version == ParsedQuicVersion::Q046()) {
- SetQuicReloadableFlag(quic_disable_version_q046, disable);
- } else if (version == ParsedQuicVersion::Q043()) {
- SetQuicReloadableFlag(quic_disable_version_q043, disable);
- } else {
- QUIC_BUG(quic_bug_10589_1)
- << "Cannot " << (enable ? "en" : "dis") << "able version " << version;
- }
-}
-
-} // namespace
-
-bool ParsedQuicVersion::IsKnown() const {
- QUICHE_DCHECK(ParsedQuicVersionIsValid(handshake_protocol, transport_version))
- << QuicVersionToString(transport_version) << " "
- << HandshakeProtocolToString(handshake_protocol);
- return transport_version != QUIC_VERSION_UNSUPPORTED;
-}
-
-bool ParsedQuicVersion::KnowsWhichDecrypterToUse() const {
- QUICHE_DCHECK(IsKnown());
- return transport_version > QUIC_VERSION_46;
-}
-
-bool ParsedQuicVersion::UsesInitialObfuscators() const {
- QUICHE_DCHECK(IsKnown());
- // Initial obfuscators were added in version 50.
- return transport_version > QUIC_VERSION_46;
-}
-
-bool ParsedQuicVersion::AllowsLowFlowControlLimits() const {
- QUICHE_DCHECK(IsKnown());
- // Low flow-control limits are used for all IETF versions.
- return UsesHttp3();
-}
-
-bool ParsedQuicVersion::HasHeaderProtection() const {
- QUICHE_DCHECK(IsKnown());
- // Header protection was added in version 50.
- return transport_version > QUIC_VERSION_46;
-}
-
-bool ParsedQuicVersion::SupportsRetry() const {
- QUICHE_DCHECK(IsKnown());
- // Retry was added in version 47.
- return transport_version > QUIC_VERSION_46;
-}
-
-bool ParsedQuicVersion::SendsVariableLengthPacketNumberInLongHeader() const {
- QUICHE_DCHECK(IsKnown());
- return transport_version > QUIC_VERSION_46;
-}
-
-bool ParsedQuicVersion::AllowsVariableLengthConnectionIds() const {
- QUICHE_DCHECK(IsKnown());
- return VersionAllowsVariableLengthConnectionIds(transport_version);
-}
-
-bool ParsedQuicVersion::SupportsClientConnectionIds() const {
- QUICHE_DCHECK(IsKnown());
- // Client connection IDs were added in version 49.
- return transport_version > QUIC_VERSION_46;
-}
-
-bool ParsedQuicVersion::HasLengthPrefixedConnectionIds() const {
- QUICHE_DCHECK(IsKnown());
- return VersionHasLengthPrefixedConnectionIds(transport_version);
-}
-
-bool ParsedQuicVersion::SupportsAntiAmplificationLimit() const {
- QUICHE_DCHECK(IsKnown());
- // The anti-amplification limit is used for all IETF versions.
- return UsesHttp3();
-}
-
-bool ParsedQuicVersion::CanSendCoalescedPackets() const {
- QUICHE_DCHECK(IsKnown());
- return HasLongHeaderLengths() && UsesTls();
-}
-
-bool ParsedQuicVersion::SupportsGoogleAltSvcFormat() const {
- QUICHE_DCHECK(IsKnown());
- return VersionSupportsGoogleAltSvcFormat(transport_version);
-}
-
-bool ParsedQuicVersion::HasIetfInvariantHeader() const {
- QUICHE_DCHECK(IsKnown());
- return VersionHasIetfInvariantHeader(transport_version);
-}
-
-bool ParsedQuicVersion::SupportsMessageFrames() const {
- QUICHE_DCHECK(IsKnown());
- return VersionSupportsMessageFrames(transport_version);
-}
-
-bool ParsedQuicVersion::UsesHttp3() const {
- QUICHE_DCHECK(IsKnown());
- return VersionUsesHttp3(transport_version);
-}
-
-bool ParsedQuicVersion::HasLongHeaderLengths() const {
- QUICHE_DCHECK(IsKnown());
- return QuicVersionHasLongHeaderLengths(transport_version);
-}
-
-bool ParsedQuicVersion::UsesCryptoFrames() const {
- QUICHE_DCHECK(IsKnown());
- return QuicVersionUsesCryptoFrames(transport_version);
-}
-
-bool ParsedQuicVersion::HasIetfQuicFrames() const {
- QUICHE_DCHECK(IsKnown());
- return VersionHasIetfQuicFrames(transport_version);
-}
-
-bool ParsedQuicVersion::UsesLegacyTlsExtension() const {
- QUICHE_DCHECK(IsKnown());
- return UsesTls() && transport_version <= QUIC_VERSION_IETF_DRAFT_29;
-}
-
-bool ParsedQuicVersion::UsesTls() const {
- QUICHE_DCHECK(IsKnown());
- return handshake_protocol == PROTOCOL_TLS1_3;
-}
-
-bool ParsedQuicVersion::UsesQuicCrypto() const {
- QUICHE_DCHECK(IsKnown());
- return handshake_protocol == PROTOCOL_QUIC_CRYPTO;
-}
-
-bool ParsedQuicVersion::UsesV2PacketTypes() const {
- QUICHE_DCHECK(IsKnown());
- return transport_version == QUIC_VERSION_IETF_2_DRAFT_01;
-}
-
-bool ParsedQuicVersion::AlpnDeferToRFCv1() const {
- QUICHE_DCHECK(IsKnown());
- return transport_version == QUIC_VERSION_IETF_2_DRAFT_01;
-}
-
-bool VersionHasLengthPrefixedConnectionIds(
- QuicTransportVersion transport_version) {
- QUICHE_DCHECK(transport_version != QUIC_VERSION_UNSUPPORTED);
- // Length-prefixed connection IDs were added in version 49.
- return transport_version > QUIC_VERSION_46;
-}
-
-std::ostream& operator<<(std::ostream& os, const ParsedQuicVersion& version) {
- os << ParsedQuicVersionToString(version);
- return os;
-}
-
-std::ostream& operator<<(std::ostream& os,
- const ParsedQuicVersionVector& versions) {
- os << ParsedQuicVersionVectorToString(versions);
- return os;
-}
-
-QuicVersionLabel MakeVersionLabel(uint8_t a, uint8_t b, uint8_t c, uint8_t d) {
- return MakeQuicTag(d, c, b, a);
-}
-
-std::ostream& operator<<(std::ostream& os,
- const QuicVersionLabelVector& version_labels) {
- os << QuicVersionLabelVectorToString(version_labels);
- return os;
-}
-
-std::ostream& operator<<(std::ostream& os,
- const QuicTransportVersionVector& transport_versions) {
- os << QuicTransportVersionVectorToString(transport_versions);
- return os;
-}
-
-QuicVersionLabel CreateQuicVersionLabel(ParsedQuicVersion parsed_version) {
- static_assert(SupportedVersions().size() == 6u,
- "Supported versions out of sync");
- if (parsed_version == ParsedQuicVersion::V2Draft01()) {
- return MakeVersionLabel(0x70, 0x9a, 0x50, 0xc4);
- } else if (parsed_version == ParsedQuicVersion::RFCv1()) {
- return MakeVersionLabel(0x00, 0x00, 0x00, 0x01);
- } else if (parsed_version == ParsedQuicVersion::Draft29()) {
- return MakeVersionLabel(0xff, 0x00, 0x00, 29);
- } else if (parsed_version == ParsedQuicVersion::Q050()) {
- return MakeVersionLabel('Q', '0', '5', '0');
- } else if (parsed_version == ParsedQuicVersion::Q046()) {
- return MakeVersionLabel('Q', '0', '4', '6');
- } else if (parsed_version == ParsedQuicVersion::Q043()) {
- return MakeVersionLabel('Q', '0', '4', '3');
- } else if (parsed_version == ParsedQuicVersion::ReservedForNegotiation()) {
- return CreateRandomVersionLabelForNegotiation();
- }
- QUIC_BUG(quic_bug_10589_2)
- << "Unsupported version "
- << QuicVersionToString(parsed_version.transport_version) << " "
- << HandshakeProtocolToString(parsed_version.handshake_protocol);
- return 0;
-}
-
-QuicVersionLabelVector CreateQuicVersionLabelVector(
- const ParsedQuicVersionVector& versions) {
- QuicVersionLabelVector out;
- out.reserve(versions.size());
- for (const auto& version : versions) {
- out.push_back(CreateQuicVersionLabel(version));
- }
- return out;
-}
-
-ParsedQuicVersionVector AllSupportedVersionsWithQuicCrypto() {
- ParsedQuicVersionVector versions;
- for (const ParsedQuicVersion& version : AllSupportedVersions()) {
- if (version.handshake_protocol == PROTOCOL_QUIC_CRYPTO) {
- versions.push_back(version);
- }
- }
- QUIC_BUG_IF(quic_bug_10589_3, versions.empty())
- << "No version with QUIC crypto found.";
- return versions;
-}
-
-ParsedQuicVersionVector CurrentSupportedVersionsWithQuicCrypto() {
- ParsedQuicVersionVector versions;
- for (const ParsedQuicVersion& version : CurrentSupportedVersions()) {
- if (version.handshake_protocol == PROTOCOL_QUIC_CRYPTO) {
- versions.push_back(version);
- }
- }
- QUIC_BUG_IF(quic_bug_10589_4, versions.empty())
- << "No version with QUIC crypto found.";
- return versions;
-}
-
-ParsedQuicVersionVector AllSupportedVersionsWithTls() {
- ParsedQuicVersionVector versions;
- for (const ParsedQuicVersion& version : AllSupportedVersions()) {
- if (version.UsesTls()) {
- versions.push_back(version);
- }
- }
- QUIC_BUG_IF(quic_bug_10589_5, versions.empty())
- << "No version with TLS handshake found.";
- return versions;
-}
-
-ParsedQuicVersionVector CurrentSupportedVersionsWithTls() {
- ParsedQuicVersionVector versions;
- for (const ParsedQuicVersion& version : CurrentSupportedVersions()) {
- if (version.UsesTls()) {
- versions.push_back(version);
- }
- }
- QUIC_BUG_IF(quic_bug_10589_6, versions.empty())
- << "No version with TLS handshake found.";
- return versions;
-}
-
-ParsedQuicVersionVector CurrentSupportedHttp3Versions() {
- ParsedQuicVersionVector versions;
- for (const ParsedQuicVersion& version : CurrentSupportedVersions()) {
- if (version.UsesHttp3()) {
- versions.push_back(version);
- }
- }
- QUIC_BUG_IF(no_version_uses_http3, versions.empty())
- << "No version speaking Http3 found.";
- return versions;
-}
-
-ParsedQuicVersion ParseQuicVersionLabel(QuicVersionLabel version_label) {
- for (const ParsedQuicVersion& version : AllSupportedVersions()) {
- if (version_label == CreateQuicVersionLabel(version)) {
- return version;
- }
- }
- // Reading from the client so this should not be considered an ERROR.
- QUIC_DLOG(INFO) << "Unsupported QuicVersionLabel version: "
- << QuicVersionLabelToString(version_label);
- return UnsupportedQuicVersion();
-}
-
-ParsedQuicVersionVector ParseQuicVersionLabelVector(
- const QuicVersionLabelVector& version_labels) {
- ParsedQuicVersionVector parsed_versions;
- for (const QuicVersionLabel& version_label : version_labels) {
- ParsedQuicVersion parsed_version = ParseQuicVersionLabel(version_label);
- if (parsed_version.IsKnown()) {
- parsed_versions.push_back(parsed_version);
- }
- }
- return parsed_versions;
-}
-
-ParsedQuicVersion ParseQuicVersionString(absl::string_view version_string) {
- if (version_string.empty()) {
- return UnsupportedQuicVersion();
- }
- const ParsedQuicVersionVector supported_versions = AllSupportedVersions();
- for (const ParsedQuicVersion& version : supported_versions) {
- if (version_string == ParsedQuicVersionToString(version) ||
- (version_string == AlpnForVersion(version) &&
- !version.AlpnDeferToRFCv1()) ||
- (version.handshake_protocol == PROTOCOL_QUIC_CRYPTO &&
- version_string == QuicVersionToString(version.transport_version))) {
- return version;
- }
- }
- for (const ParsedQuicVersion& version : supported_versions) {
- if (version.UsesHttp3() &&
- version_string ==
- QuicVersionLabelToString(CreateQuicVersionLabel(version))) {
- return version;
- }
- }
- int quic_version_number = 0;
- if (absl::SimpleAtoi(version_string, &quic_version_number) &&
- quic_version_number > 0) {
- QuicTransportVersion transport_version =
- static_cast<QuicTransportVersion>(quic_version_number);
- if (!ParsedQuicVersionIsValid(PROTOCOL_QUIC_CRYPTO, transport_version)) {
- return UnsupportedQuicVersion();
- }
- ParsedQuicVersion version(PROTOCOL_QUIC_CRYPTO, transport_version);
- if (std::find(supported_versions.begin(), supported_versions.end(),
- version) != supported_versions.end()) {
- return version;
- }
- return UnsupportedQuicVersion();
- }
- // Reading from the client so this should not be considered an ERROR.
- QUIC_DLOG(INFO) << "Unsupported QUIC version string: \"" << version_string
- << "\".";
- return UnsupportedQuicVersion();
-}
-
-ParsedQuicVersionVector ParseQuicVersionVectorString(
- absl::string_view versions_string) {
- ParsedQuicVersionVector versions;
- std::vector<absl::string_view> version_strings =
- absl::StrSplit(versions_string, ',');
- for (absl::string_view version_string : version_strings) {
- quiche::QuicheTextUtils::RemoveLeadingAndTrailingWhitespace(
- &version_string);
- ParsedQuicVersion version = ParseQuicVersionString(version_string);
- if (!version.IsKnown() || std::find(versions.begin(), versions.end(),
- version) != versions.end()) {
- continue;
- }
- versions.push_back(version);
- }
- return versions;
-}
-
-QuicTransportVersionVector AllSupportedTransportVersions() {
- QuicTransportVersionVector transport_versions;
- for (const ParsedQuicVersion& version : AllSupportedVersions()) {
- if (std::find(transport_versions.begin(), transport_versions.end(),
- version.transport_version) == transport_versions.end()) {
- transport_versions.push_back(version.transport_version);
- }
- }
- return transport_versions;
-}
-
-ParsedQuicVersionVector AllSupportedVersions() {
- constexpr auto supported_versions = SupportedVersions();
- return ParsedQuicVersionVector(supported_versions.begin(),
- supported_versions.end());
-}
-
-ParsedQuicVersionVector CurrentSupportedVersions() {
- return FilterSupportedVersions(AllSupportedVersions());
-}
-
-ParsedQuicVersionVector FilterSupportedVersions(
- ParsedQuicVersionVector versions) {
- static_assert(SupportedVersions().size() == 6u,
- "Supported versions out of sync");
- ParsedQuicVersionVector filtered_versions;
- filtered_versions.reserve(versions.size());
- for (const ParsedQuicVersion& version : versions) {
- if (version == ParsedQuicVersion::V2Draft01()) {
- if (GetQuicReloadableFlag(quic_enable_version_2_draft_01)) {
- filtered_versions.push_back(version);
- }
- } else if (version == ParsedQuicVersion::RFCv1()) {
- if (!GetQuicReloadableFlag(quic_disable_version_rfcv1)) {
- filtered_versions.push_back(version);
- }
- } else if (version == ParsedQuicVersion::Draft29()) {
- if (!GetQuicReloadableFlag(quic_disable_version_draft_29)) {
- filtered_versions.push_back(version);
- }
- } else if (version == ParsedQuicVersion::Q050()) {
- if (!GetQuicReloadableFlag(quic_disable_version_q050)) {
- filtered_versions.push_back(version);
- }
- } else if (version == ParsedQuicVersion::Q046()) {
- if (!GetQuicReloadableFlag(quic_disable_version_q046)) {
- filtered_versions.push_back(version);
- }
- } else if (version == ParsedQuicVersion::Q043()) {
- if (!GetQuicReloadableFlag(quic_disable_version_q043)) {
- filtered_versions.push_back(version);
- }
- } else {
- QUIC_BUG(quic_bug_10589_7)
- << "QUIC version " << version << " has no flag protection";
- filtered_versions.push_back(version);
- }
- }
- return filtered_versions;
-}
-
-ParsedQuicVersionVector ParsedVersionOfIndex(
- const ParsedQuicVersionVector& versions, int index) {
- ParsedQuicVersionVector version;
- int version_count = versions.size();
- if (index >= 0 && index < version_count) {
- version.push_back(versions[index]);
- } else {
- version.push_back(UnsupportedQuicVersion());
- }
- return version;
-}
-
-std::string QuicVersionLabelToString(QuicVersionLabel version_label) {
- return QuicTagToString(quiche::QuicheEndian::HostToNet32(version_label));
-}
-
-ParsedQuicVersion ParseQuicVersionLabelString(
- absl::string_view version_label_string) {
- const ParsedQuicVersionVector supported_versions = AllSupportedVersions();
- for (const ParsedQuicVersion& version : supported_versions) {
- if (version_label_string ==
- QuicVersionLabelToString(CreateQuicVersionLabel(version))) {
- return version;
- }
- }
- return UnsupportedQuicVersion();
-}
-
-std::string QuicVersionLabelVectorToString(
- const QuicVersionLabelVector& version_labels, const std::string& separator,
- size_t skip_after_nth_version) {
- std::string result;
- for (size_t i = 0; i < version_labels.size(); ++i) {
- if (i != 0) {
- result.append(separator);
- }
-
- if (i > skip_after_nth_version) {
- result.append("...");
- break;
- }
- result.append(QuicVersionLabelToString(version_labels[i]));
- }
- return result;
-}
-
-#define RETURN_STRING_LITERAL(x) \
- case x: \
- return #x
-
-std::string QuicVersionToString(QuicTransportVersion transport_version) {
- switch (transport_version) {
- RETURN_STRING_LITERAL(QUIC_VERSION_43);
- RETURN_STRING_LITERAL(QUIC_VERSION_46);
- RETURN_STRING_LITERAL(QUIC_VERSION_50);
- RETURN_STRING_LITERAL(QUIC_VERSION_IETF_DRAFT_29);
- RETURN_STRING_LITERAL(QUIC_VERSION_IETF_RFC_V1);
- RETURN_STRING_LITERAL(QUIC_VERSION_IETF_2_DRAFT_01);
- RETURN_STRING_LITERAL(QUIC_VERSION_UNSUPPORTED);
- RETURN_STRING_LITERAL(QUIC_VERSION_RESERVED_FOR_NEGOTIATION);
- }
- return absl::StrCat("QUIC_VERSION_UNKNOWN(",
- static_cast<int>(transport_version), ")");
-}
-
-std::string HandshakeProtocolToString(HandshakeProtocol handshake_protocol) {
- switch (handshake_protocol) {
- RETURN_STRING_LITERAL(PROTOCOL_UNSUPPORTED);
- RETURN_STRING_LITERAL(PROTOCOL_QUIC_CRYPTO);
- RETURN_STRING_LITERAL(PROTOCOL_TLS1_3);
- }
- return absl::StrCat("PROTOCOL_UNKNOWN(", static_cast<int>(handshake_protocol),
- ")");
-}
-
-std::string ParsedQuicVersionToString(ParsedQuicVersion version) {
- static_assert(SupportedVersions().size() == 6u,
- "Supported versions out of sync");
- if (version == UnsupportedQuicVersion()) {
- return "0";
- } else if (version == ParsedQuicVersion::V2Draft01()) {
- QUICHE_DCHECK(version.UsesHttp3());
- return "v2draft01";
- } else if (version == ParsedQuicVersion::RFCv1()) {
- QUICHE_DCHECK(version.UsesHttp3());
- return "RFCv1";
- } else if (version == ParsedQuicVersion::Draft29()) {
- QUICHE_DCHECK(version.UsesHttp3());
- return "draft29";
- }
-
- return QuicVersionLabelToString(CreateQuicVersionLabel(version));
-}
-
-std::string QuicTransportVersionVectorToString(
- const QuicTransportVersionVector& versions) {
- std::string result = "";
- for (size_t i = 0; i < versions.size(); ++i) {
- if (i != 0) {
- result.append(",");
- }
- result.append(QuicVersionToString(versions[i]));
- }
- return result;
-}
-
-std::string ParsedQuicVersionVectorToString(
- const ParsedQuicVersionVector& versions, const std::string& separator,
- size_t skip_after_nth_version) {
- std::string result;
- for (size_t i = 0; i < versions.size(); ++i) {
- if (i != 0) {
- result.append(separator);
- }
- if (i > skip_after_nth_version) {
- result.append("...");
- break;
- }
- result.append(ParsedQuicVersionToString(versions[i]));
- }
- return result;
-}
-
-bool VersionSupportsGoogleAltSvcFormat(QuicTransportVersion transport_version) {
- return transport_version <= QUIC_VERSION_46;
-}
-
-bool VersionAllowsVariableLengthConnectionIds(
- QuicTransportVersion transport_version) {
- QUICHE_DCHECK_NE(transport_version, QUIC_VERSION_UNSUPPORTED);
- return transport_version > QUIC_VERSION_46;
-}
-
-bool QuicVersionLabelUses4BitConnectionIdLength(
- QuicVersionLabel version_label) {
- // As we deprecate old versions, we still need the ability to send valid
- // version negotiation packets for those versions. This function keeps track
- // of the versions that ever supported the 4bit connection ID length encoding
- // that we know about. Google QUIC 43 and earlier used a different encoding,
- // and Google QUIC 49 and later use the new length prefixed encoding.
- // Similarly, only IETF drafts 11 to 21 used this encoding.
-
- // Check Q044, Q045, Q046, Q047 and Q048.
- for (uint8_t c = '4'; c <= '8'; ++c) {
- if (version_label == MakeVersionLabel('Q', '0', '4', c)) {
- return true;
- }
- }
- // Check T048.
- if (version_label == MakeVersionLabel('T', '0', '4', '8')) {
- return true;
- }
- // Check IETF draft versions in [11,21].
- for (uint8_t draft_number = 11; draft_number <= 21; ++draft_number) {
- if (version_label == MakeVersionLabel(0xff, 0x00, 0x00, draft_number)) {
- return true;
- }
- }
- return false;
-}
-
-ParsedQuicVersion UnsupportedQuicVersion() {
- return ParsedQuicVersion::Unsupported();
-}
-
-ParsedQuicVersion QuicVersionReservedForNegotiation() {
- return ParsedQuicVersion::ReservedForNegotiation();
-}
-
-ParsedQuicVersion LegacyVersionForEncapsulation() {
- return ParsedQuicVersion::Q043();
-}
-
-std::string AlpnForVersion(ParsedQuicVersion parsed_version) {
- if (parsed_version == ParsedQuicVersion::V2Draft01()) {
- return "h3";
- } else if (parsed_version == ParsedQuicVersion::RFCv1()) {
- return "h3";
- } else if (parsed_version == ParsedQuicVersion::Draft29()) {
- return "h3-29";
- }
- return "h3-" + ParsedQuicVersionToString(parsed_version);
-}
-
-void QuicVersionInitializeSupportForIetfDraft() {
- // Enable necessary flags.
- SetQuicReloadableFlag(quic_version_information, true);
-}
-
-void QuicEnableVersion(const ParsedQuicVersion& version) {
- SetVersionFlag(version, /*should_enable=*/true);
-}
-
-void QuicDisableVersion(const ParsedQuicVersion& version) {
- SetVersionFlag(version, /*should_enable=*/false);
-}
-
-bool QuicVersionIsEnabled(const ParsedQuicVersion& version) {
- ParsedQuicVersionVector current = CurrentSupportedVersions();
- return std::find(current.begin(), current.end(), version) != current.end();
-}
-
-#undef RETURN_STRING_LITERAL // undef for jumbo builds
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_versions.h b/chromium/net/third_party/quiche/src/quic/core/quic_versions.h
deleted file mode 100644
index 59bf7532f3a..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_versions.h
+++ /dev/null
@@ -1,652 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Definitions and utility functions related to handling of QUIC versions.
-//
-// QUIC versions are encoded over the wire as an opaque 32bit field. The wire
-// encoding is represented in memory as a QuicVersionLabel type (which is an
-// alias to uint32_t). Conceptual versions are represented in memory as
-// ParsedQuicVersion.
-//
-// We currently support two kinds of QUIC versions, GoogleQUIC and IETF QUIC.
-//
-// All GoogleQUIC versions use a wire encoding that matches the following regex
-// when converted to ASCII: "[QT]0\d\d" (e.g. Q050). Q or T distinguishes the
-// type of handshake used (Q for the QUIC_CRYPTO handshake, T for the QUIC+TLS
-// handshake), and the two digits at the end contain the numeric value of
-// the transport version used.
-//
-// All IETF QUIC versions use the wire encoding described in:
-// https://tools.ietf.org/html/draft-ietf-quic-transport
-
-#ifndef QUICHE_QUIC_CORE_QUIC_VERSIONS_H_
-#define QUICHE_QUIC_CORE_QUIC_VERSIONS_H_
-
-#include <cstdint>
-#include <string>
-#include <vector>
-
-#include "absl/base/macros.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_tag.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// The list of existing QUIC transport versions. Note that QUIC versions are
-// sent over the wire as an encoding of ParsedQuicVersion, which requires a
-// QUIC transport version and handshake protocol. For transport versions of the
-// form QUIC_VERSION_XX where XX is decimal, the enum numeric value is
-// guaranteed to match the name. Older deprecated transport versions are
-// documented in comments below.
-enum QuicTransportVersion {
- // Special case to indicate unknown/unsupported QUIC version.
- QUIC_VERSION_UNSUPPORTED = 0,
-
- // Version 1 was the first version of QUIC that supported versioning.
- // Version 2 decoupled versioning of non-cryptographic parameters from the
- // SCFG.
- // Version 3 moved public flags into the beginning of the packet.
- // Version 4 added support for variable-length connection IDs.
- // Version 5 made specifying FEC groups optional.
- // Version 6 introduced variable-length packet numbers.
- // Version 7 introduced a lower-overhead encoding for stream frames.
- // Version 8 made salt length equal to digest length for the RSA-PSS
- // signatures.
- // Version 9 added stream priority.
- // Version 10 redid the frame type numbering.
- // Version 11 reduced the length of null encryption authentication tag
- // from 16 to 12 bytes.
- // Version 12 made the sequence numbers in the ACK frames variable-sized.
- // Version 13 added the dedicated header stream.
- // Version 14 added byte_offset to RST_STREAM frame.
- // Version 15 added a list of packets recovered using FEC to the ACK frame.
- // Version 16 added STOP_WAITING frame.
- // Version 17 added per-stream flow control.
- // Version 18 added PING frame.
- // Version 19 added connection-level flow control
- // Version 20 allowed to set stream- and connection-level flow control windows
- // to different values.
- // Version 21 made header and crypto streams flow-controlled.
- // Version 22 added support for SCUP (server config update) messages.
- // Version 23 added timestamps into the ACK frame.
- // Version 24 added SPDY/4 header compression.
- // Version 25 added support for SPDY/4 header keys and removed error_details
- // from RST_STREAM frame.
- // Version 26 added XLCT (expected leaf certificate) tag into CHLO.
- // Version 27 added a nonce into SHLO.
- // Version 28 allowed receiver to refuse creating a requested stream.
- // Version 29 added support for QUIC_STREAM_NO_ERROR.
- // Version 30 added server-side support for certificate transparency.
- // Version 31 incorporated the hash of CHLO into the crypto proof supplied by
- // the server.
- // Version 32 removed FEC-related fields from wire format.
- // Version 33 added diversification nonces.
- // Version 34 removed entropy bits from packets and ACK frames, removed
- // private flag from packet header and changed the ACK format to
- // specify ranges of packets acknowledged rather than missing
- // ranges.
- // Version 35 allows endpoints to independently set stream limit.
- // Version 36 added support for forced head-of-line blocking experiments.
- // Version 37 added perspective into null encryption.
- // Version 38 switched to IETF padding frame format and support for NSTP (no
- // stop waiting frame) connection option.
-
- // Version 39 writes integers and floating numbers in big endian, stops acking
- // acks, sends a connection level WINDOW_UPDATE every 20 sent packets which do
- // not contain retransmittable frames.
-
- // Version 40 was an attempt to convert QUIC to IETF frame format; it was
- // never shipped due to a bug.
- // Version 41 was a bugfix for version 40. The working group changed the wire
- // format before it shipped, which caused it to be never shipped
- // and all the changes from it to be reverted. No changes from v40
- // or v41 are present in subsequent versions.
- // Version 42 allowed receiving overlapping stream data.
-
- QUIC_VERSION_43 = 43, // PRIORITY frames are sent by client and accepted by
- // server.
- // Version 44 used IETF header format from draft-ietf-quic-invariants-05.
-
- // Version 45 added MESSAGE frame.
-
- QUIC_VERSION_46 = 46, // Use IETF draft-17 header format with demultiplexing
- // bit.
- // Version 47 added variable-length QUIC server connection IDs.
- // Version 48 added CRYPTO frames for the handshake.
- // Version 49 added client connection IDs, long header lengths, and the IETF
- // header format from draft-ietf-quic-invariants-06
- QUIC_VERSION_50 = 50, // Header protection and initial obfuscators.
- // Number 51 was T051 which used draft-29 features but with GoogleQUIC frames.
- // Number 70 used to represent draft-ietf-quic-transport-25.
- // Number 71 used to represent draft-ietf-quic-transport-27.
- // Number 72 used to represent draft-ietf-quic-transport-28.
- QUIC_VERSION_IETF_DRAFT_29 = 73, // draft-ietf-quic-transport-29.
- QUIC_VERSION_IETF_RFC_V1 = 80, // RFC 9000.
- QUIC_VERSION_IETF_2_DRAFT_01 = 81, // draft-ietf-quic-v2-01.
- // Version 99 was a dumping ground for IETF QUIC changes which were not yet
- // ready for production between 2018-02 and 2020-02.
-
- // QUIC_VERSION_RESERVED_FOR_NEGOTIATION is sent over the wire as ?a?a?a?a
- // which is part of a range reserved by the IETF for version negotiation
- // testing (see the "Versions" section of draft-ietf-quic-transport).
- // This version is intentionally meant to never be supported to trigger
- // version negotiation when proposed by clients and to prevent client
- // ossification when sent by servers.
- QUIC_VERSION_RESERVED_FOR_NEGOTIATION = 999,
-};
-
-// Helper function which translates from a QuicTransportVersion to a string.
-// Returns strings corresponding to enum names (e.g. QUIC_VERSION_6).
-QUIC_EXPORT_PRIVATE std::string QuicVersionToString(
- QuicTransportVersion transport_version);
-
-// The crypto handshake protocols that can be used with QUIC.
-// We are planning on eventually deprecating PROTOCOL_QUIC_CRYPTO in favor of
-// PROTOCOL_TLS1_3.
-enum HandshakeProtocol {
- PROTOCOL_UNSUPPORTED,
- PROTOCOL_QUIC_CRYPTO,
- PROTOCOL_TLS1_3,
-};
-
-// Helper function which translates from a HandshakeProtocol to a string.
-QUIC_EXPORT_PRIVATE std::string HandshakeProtocolToString(
- HandshakeProtocol handshake_protocol);
-
-// Returns whether |transport_version| uses CRYPTO frames for the handshake
-// instead of stream 1.
-QUIC_EXPORT_PRIVATE constexpr bool QuicVersionUsesCryptoFrames(
- QuicTransportVersion transport_version) {
- // CRYPTO frames were added in version 48.
- return transport_version > QUIC_VERSION_46;
-}
-
-// Returns whether this combination of handshake protocol and transport
-// version is allowed. For example, {PROTOCOL_TLS1_3, QUIC_VERSION_43} is NOT
-// allowed as TLS requires crypto frames which v43 does not support. Note that
-// UnsupportedQuicVersion is a valid version.
-QUIC_EXPORT_PRIVATE constexpr bool ParsedQuicVersionIsValid(
- HandshakeProtocol handshake_protocol,
- QuicTransportVersion transport_version) {
- bool transport_version_is_valid = false;
- constexpr QuicTransportVersion valid_transport_versions[] = {
- QUIC_VERSION_IETF_2_DRAFT_01,
- QUIC_VERSION_IETF_RFC_V1,
- QUIC_VERSION_IETF_DRAFT_29,
- QUIC_VERSION_50,
- QUIC_VERSION_46,
- QUIC_VERSION_43,
- QUIC_VERSION_RESERVED_FOR_NEGOTIATION,
- QUIC_VERSION_UNSUPPORTED,
- };
- for (size_t i = 0; i < ABSL_ARRAYSIZE(valid_transport_versions); ++i) {
- if (transport_version == valid_transport_versions[i]) {
- transport_version_is_valid = true;
- break;
- }
- }
- if (!transport_version_is_valid) {
- return false;
- }
- switch (handshake_protocol) {
- case PROTOCOL_UNSUPPORTED:
- return transport_version == QUIC_VERSION_UNSUPPORTED;
- case PROTOCOL_QUIC_CRYPTO:
- return transport_version != QUIC_VERSION_UNSUPPORTED &&
- transport_version != QUIC_VERSION_RESERVED_FOR_NEGOTIATION &&
- transport_version != QUIC_VERSION_IETF_DRAFT_29 &&
- transport_version != QUIC_VERSION_IETF_RFC_V1 &&
- transport_version != QUIC_VERSION_IETF_2_DRAFT_01;
- case PROTOCOL_TLS1_3:
- return transport_version != QUIC_VERSION_UNSUPPORTED &&
- transport_version != QUIC_VERSION_50 &&
- QuicVersionUsesCryptoFrames(transport_version);
- }
- return false;
-}
-
-// A parsed QUIC version label which determines that handshake protocol
-// and the transport version.
-struct QUIC_EXPORT_PRIVATE ParsedQuicVersion {
- HandshakeProtocol handshake_protocol;
- QuicTransportVersion transport_version;
-
- constexpr ParsedQuicVersion(HandshakeProtocol handshake_protocol,
- QuicTransportVersion transport_version)
- : handshake_protocol(handshake_protocol),
- transport_version(transport_version) {
- QUICHE_DCHECK(
- ParsedQuicVersionIsValid(handshake_protocol, transport_version))
- << QuicVersionToString(transport_version) << " "
- << HandshakeProtocolToString(handshake_protocol);
- }
-
- constexpr ParsedQuicVersion(const ParsedQuicVersion& other)
- : ParsedQuicVersion(other.handshake_protocol, other.transport_version) {}
-
- ParsedQuicVersion& operator=(const ParsedQuicVersion& other) {
- QUICHE_DCHECK(ParsedQuicVersionIsValid(other.handshake_protocol,
- other.transport_version))
- << QuicVersionToString(other.transport_version) << " "
- << HandshakeProtocolToString(other.handshake_protocol);
- if (this != &other) {
- handshake_protocol = other.handshake_protocol;
- transport_version = other.transport_version;
- }
- return *this;
- }
-
- bool operator==(const ParsedQuicVersion& other) const {
- return handshake_protocol == other.handshake_protocol &&
- transport_version == other.transport_version;
- }
-
- bool operator!=(const ParsedQuicVersion& other) const {
- return handshake_protocol != other.handshake_protocol ||
- transport_version != other.transport_version;
- }
-
- static constexpr ParsedQuicVersion V2Draft01() {
- return ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_IETF_2_DRAFT_01);
- }
-
- static constexpr ParsedQuicVersion RFCv1() {
- return ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_IETF_RFC_V1);
- }
-
- static constexpr ParsedQuicVersion Draft29() {
- return ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_IETF_DRAFT_29);
- }
-
- static constexpr ParsedQuicVersion Q050() {
- return ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_50);
- }
-
- static constexpr ParsedQuicVersion Q046() {
- return ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_46);
- }
-
- static constexpr ParsedQuicVersion Q043() {
- return ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_43);
- }
-
- static constexpr ParsedQuicVersion Unsupported() {
- return ParsedQuicVersion(PROTOCOL_UNSUPPORTED, QUIC_VERSION_UNSUPPORTED);
- }
-
- static constexpr ParsedQuicVersion ReservedForNegotiation() {
- return ParsedQuicVersion(PROTOCOL_TLS1_3,
- QUIC_VERSION_RESERVED_FOR_NEGOTIATION);
- }
-
- // Returns whether our codebase understands this version. This should only be
- // called on valid versions, see ParsedQuicVersionIsValid. Assuming the
- // version is valid, IsKnown returns whether the version is not
- // UnsupportedQuicVersion.
- bool IsKnown() const;
-
- bool KnowsWhichDecrypterToUse() const;
-
- // Returns whether this version uses keys derived from the Connection ID for
- // ENCRYPTION_INITIAL keys (instead of NullEncrypter/NullDecrypter).
- bool UsesInitialObfuscators() const;
-
- // Indicates that this QUIC version does not have an enforced minimum value
- // for flow control values negotiated during the handshake.
- bool AllowsLowFlowControlLimits() const;
-
- // Returns whether header protection is used in this version of QUIC.
- bool HasHeaderProtection() const;
-
- // Returns whether this version supports IETF RETRY packets.
- bool SupportsRetry() const;
-
- // Returns true if this version sends variable length packet number in long
- // header.
- bool SendsVariableLengthPacketNumberInLongHeader() const;
-
- // Returns whether this version allows server connection ID lengths
- // that are not 64 bits.
- bool AllowsVariableLengthConnectionIds() const;
-
- // Returns whether this version supports client connection ID.
- bool SupportsClientConnectionIds() const;
-
- // Returns whether this version supports long header 8-bit encoded
- // connection ID lengths as described in draft-ietf-quic-invariants-06 and
- // draft-ietf-quic-transport-22.
- bool HasLengthPrefixedConnectionIds() const;
-
- // Returns whether this version supports IETF style anti-amplification limit,
- // i.e., server will send no more than FLAGS_quic_anti_amplification_factor
- // times received bytes until address can be validated.
- bool SupportsAntiAmplificationLimit() const;
-
- // Returns true if this version can send coalesced packets.
- bool CanSendCoalescedPackets() const;
-
- // Returns true if this version supports the old Google-style Alt-Svc
- // advertisement format.
- bool SupportsGoogleAltSvcFormat() const;
-
- // Returns true if |transport_version| uses IETF invariant headers.
- bool HasIetfInvariantHeader() const;
-
- // Returns true if |transport_version| supports MESSAGE frames.
- bool SupportsMessageFrames() const;
-
- // If true, HTTP/3 instead of gQUIC will be used at the HTTP layer.
- // Notable changes are:
- // * Headers stream no longer exists.
- // * PRIORITY, HEADERS are moved from headers stream to HTTP/3 control stream.
- // * PUSH_PROMISE is moved to request stream.
- // * Unidirectional streams will have their first byte as a stream type.
- // * HEADERS frames are compressed using QPACK.
- // * DATA frame has frame headers.
- // * GOAWAY is moved to HTTP layer.
- bool UsesHttp3() const;
-
- // Returns whether the transport_version supports the variable length integer
- // length field as defined by IETF QUIC draft-13 and later.
- bool HasLongHeaderLengths() const;
-
- // Returns whether |transport_version| uses CRYPTO frames for the handshake
- // instead of stream 1.
- bool UsesCryptoFrames() const;
-
- // Returns whether |transport_version| makes use of IETF QUIC
- // frames or not.
- bool HasIetfQuicFrames() const;
-
- // Returns whether this version uses the legacy TLS extension codepoint.
- bool UsesLegacyTlsExtension() const;
-
- // Returns whether this version uses PROTOCOL_TLS1_3.
- bool UsesTls() const;
-
- // Returns whether this version uses PROTOCOL_QUIC_CRYPTO.
- bool UsesQuicCrypto() const;
-
- // Returns whether this version uses the QUICv2 Long Header Packet Types.
- bool UsesV2PacketTypes() const;
-
- // Returns true if this shares ALPN codes with RFCv1, and endpoints should
- // choose RFCv1 when presented with a v1 ALPN. Note that this is false for
- // RFCv1.
- bool AlpnDeferToRFCv1() const;
-};
-
-QUIC_EXPORT_PRIVATE ParsedQuicVersion UnsupportedQuicVersion();
-
-QUIC_EXPORT_PRIVATE ParsedQuicVersion QuicVersionReservedForNegotiation();
-
-// Outer version used when encapsulating other packets using the Legacy Version
-// Encapsulation feature.
-QUIC_EXPORT_PRIVATE ParsedQuicVersion LegacyVersionForEncapsulation();
-
-QUIC_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
- const ParsedQuicVersion& version);
-
-using ParsedQuicVersionVector = std::vector<ParsedQuicVersion>;
-
-QUIC_EXPORT_PRIVATE std::ostream& operator<<(
- std::ostream& os, const ParsedQuicVersionVector& versions);
-
-// Representation of the on-the-wire QUIC version number. Will be written/read
-// to the wire in network-byte-order.
-using QuicVersionLabel = uint32_t;
-using QuicVersionLabelVector = std::vector<QuicVersionLabel>;
-
-// Constructs a version label from the 4 bytes such that the on-the-wire
-// order will be: d, c, b, a.
-QUIC_EXPORT_PRIVATE QuicVersionLabel MakeVersionLabel(uint8_t a, uint8_t b,
- uint8_t c, uint8_t d);
-
-QUIC_EXPORT_PRIVATE std::ostream& operator<<(
- std::ostream& os, const QuicVersionLabelVector& version_labels);
-
-// This vector contains all crypto handshake protocols that are supported.
-constexpr std::array<HandshakeProtocol, 2> SupportedHandshakeProtocols() {
- return {PROTOCOL_TLS1_3, PROTOCOL_QUIC_CRYPTO};
-}
-
-constexpr std::array<ParsedQuicVersion, 6> SupportedVersions() {
- return {
- ParsedQuicVersion::V2Draft01(), ParsedQuicVersion::RFCv1(),
- ParsedQuicVersion::Draft29(), ParsedQuicVersion::Q050(),
- ParsedQuicVersion::Q046(), ParsedQuicVersion::Q043(),
- };
-}
-
-using QuicTransportVersionVector = std::vector<QuicTransportVersion>;
-
-QUIC_EXPORT_PRIVATE std::ostream& operator<<(
- std::ostream& os, const QuicTransportVersionVector& transport_versions);
-
-// Returns a vector of supported QUIC versions.
-QUIC_EXPORT_PRIVATE ParsedQuicVersionVector AllSupportedVersions();
-
-// Returns a vector of supported QUIC versions, with any versions disabled by
-// flags excluded.
-QUIC_EXPORT_PRIVATE ParsedQuicVersionVector CurrentSupportedVersions();
-
-// Returns a vector of QUIC versions from |versions| which exclude any versions
-// which are disabled by flags.
-QUIC_EXPORT_PRIVATE ParsedQuicVersionVector
-FilterSupportedVersions(ParsedQuicVersionVector versions);
-
-// Returns a subset of AllSupportedVersions() with
-// handshake_protocol == PROTOCOL_QUIC_CRYPTO, in the same order.
-// Deprecated; only to be used in components that do not yet support
-// PROTOCOL_TLS1_3.
-QUIC_EXPORT_PRIVATE ParsedQuicVersionVector
-AllSupportedVersionsWithQuicCrypto();
-
-// Returns a subset of CurrentSupportedVersions() with
-// handshake_protocol == PROTOCOL_QUIC_CRYPTO, in the same order.
-QUIC_EXPORT_PRIVATE ParsedQuicVersionVector
-CurrentSupportedVersionsWithQuicCrypto();
-
-// Returns a subset of AllSupportedVersions() with
-// handshake_protocol == PROTOCOL_TLS1_3, in the same order.
-QUIC_EXPORT_PRIVATE ParsedQuicVersionVector AllSupportedVersionsWithTls();
-
-// Returns a subset of CurrentSupportedVersions() with handshake_protocol ==
-// PROTOCOL_TLS1_3.
-QUIC_EXPORT_PRIVATE ParsedQuicVersionVector CurrentSupportedVersionsWithTls();
-
-// Returns a subset of CurrentSupportedVersions() using HTTP/3 at the HTTP
-// layer.
-QUIC_EXPORT_PRIVATE ParsedQuicVersionVector CurrentSupportedHttp3Versions();
-
-// Returns QUIC version of |index| in result of |versions|. Returns
-// UnsupportedQuicVersion() if |index| is out of bounds.
-QUIC_EXPORT_PRIVATE ParsedQuicVersionVector
-ParsedVersionOfIndex(const ParsedQuicVersionVector& versions, int index);
-
-// QuicVersionLabel is written to and read from the wire, but we prefer to use
-// the more readable ParsedQuicVersion at other levels.
-// Helper function which translates from a QuicVersionLabel to a
-// ParsedQuicVersion.
-QUIC_EXPORT_PRIVATE ParsedQuicVersion
-ParseQuicVersionLabel(QuicVersionLabel version_label);
-
-// Helper function that translates from a QuicVersionLabelVector to a
-// ParsedQuicVersionVector.
-QUIC_EXPORT_PRIVATE ParsedQuicVersionVector
-ParseQuicVersionLabelVector(const QuicVersionLabelVector& version_labels);
-
-// Parses a QUIC version string such as "Q043" or "T051". Also supports parsing
-// ALPN such as "h3-29" or "h3-Q050". For PROTOCOL_QUIC_CRYPTO versions, also
-// supports parsing numbers such as "46".
-QUIC_EXPORT_PRIVATE ParsedQuicVersion
-ParseQuicVersionString(absl::string_view version_string);
-
-// Parses a comma-separated list of QUIC version strings. Supports parsing by
-// label, ALPN and numbers for PROTOCOL_QUIC_CRYPTO. Skips unknown versions.
-// For example: "h3-29,Q050,46".
-QUIC_EXPORT_PRIVATE ParsedQuicVersionVector
-ParseQuicVersionVectorString(absl::string_view versions_string);
-
-// Constructs a QuicVersionLabel from the provided ParsedQuicVersion.
-// QuicVersionLabel is written to and read from the wire, but we prefer to use
-// the more readable ParsedQuicVersion at other levels.
-// Helper function which translates from a ParsedQuicVersion to a
-// QuicVersionLabel. Returns 0 if |parsed_version| is unsupported.
-QUIC_EXPORT_PRIVATE QuicVersionLabel
-CreateQuicVersionLabel(ParsedQuicVersion parsed_version);
-
-// Constructs a QuicVersionLabelVector from the provided
-// ParsedQuicVersionVector.
-QUIC_EXPORT_PRIVATE QuicVersionLabelVector
-CreateQuicVersionLabelVector(const ParsedQuicVersionVector& versions);
-
-// Helper function which translates from a QuicVersionLabel to a string.
-QUIC_EXPORT_PRIVATE std::string QuicVersionLabelToString(
- QuicVersionLabel version_label);
-
-// Helper function which translates from a QuicVersionLabel string to a
-// ParsedQuicVersion. The version label string must be of the form returned
-// by QuicVersionLabelToString, for example, "00000001" or "Q046", but not
-// "51303433" (the hex encoding of the Q064 version label). Returns
-// the ParsedQuicVersion which matches the label or UnsupportedQuicVersion()
-// otherwise.
-QUIC_EXPORT_PRIVATE ParsedQuicVersion
-ParseQuicVersionLabelString(absl::string_view version_label_string);
-
-// Returns |separator|-separated list of string representations of
-// QuicVersionLabel values in the supplied |version_labels| vector. The values
-// after the (0-based) |skip_after_nth_version|'th are skipped.
-QUIC_EXPORT_PRIVATE std::string QuicVersionLabelVectorToString(
- const QuicVersionLabelVector& version_labels, const std::string& separator,
- size_t skip_after_nth_version);
-
-// Returns comma separated list of string representations of QuicVersionLabel
-// values in the supplied |version_labels| vector.
-QUIC_EXPORT_PRIVATE inline std::string QuicVersionLabelVectorToString(
- const QuicVersionLabelVector& version_labels) {
- return QuicVersionLabelVectorToString(version_labels, ",",
- std::numeric_limits<size_t>::max());
-}
-
-// Helper function which translates from a ParsedQuicVersion to a string.
-// Returns strings corresponding to the on-the-wire tag.
-QUIC_EXPORT_PRIVATE std::string ParsedQuicVersionToString(
- ParsedQuicVersion version);
-
-// Returns a vector of supported QUIC transport versions. DEPRECATED, use
-// AllSupportedVersions instead.
-QUIC_EXPORT_PRIVATE QuicTransportVersionVector AllSupportedTransportVersions();
-
-// Returns comma separated list of string representations of
-// QuicTransportVersion enum values in the supplied |versions| vector.
-QUIC_EXPORT_PRIVATE std::string QuicTransportVersionVectorToString(
- const QuicTransportVersionVector& versions);
-
-// Returns comma separated list of string representations of ParsedQuicVersion
-// values in the supplied |versions| vector.
-QUIC_EXPORT_PRIVATE std::string ParsedQuicVersionVectorToString(
- const ParsedQuicVersionVector& versions);
-
-// Returns |separator|-separated list of string representations of
-// ParsedQuicVersion values in the supplied |versions| vector. The values after
-// the (0-based) |skip_after_nth_version|'th are skipped.
-QUIC_EXPORT_PRIVATE std::string ParsedQuicVersionVectorToString(
- const ParsedQuicVersionVector& versions, const std::string& separator,
- size_t skip_after_nth_version);
-
-// Returns comma separated list of string representations of ParsedQuicVersion
-// values in the supplied |versions| vector.
-QUIC_EXPORT_PRIVATE inline std::string ParsedQuicVersionVectorToString(
- const ParsedQuicVersionVector& versions) {
- return ParsedQuicVersionVectorToString(versions, ",",
- std::numeric_limits<size_t>::max());
-}
-
-// Returns true if |transport_version| uses IETF invariant headers.
-QUIC_EXPORT_PRIVATE constexpr bool VersionHasIetfInvariantHeader(
- QuicTransportVersion transport_version) {
- return transport_version > QUIC_VERSION_43;
-}
-
-// Returns true if |transport_version| supports MESSAGE frames.
-QUIC_EXPORT_PRIVATE constexpr bool VersionSupportsMessageFrames(
- QuicTransportVersion transport_version) {
- // MESSAGE frames were added in version 45.
- return transport_version > QUIC_VERSION_43;
-}
-
-// If true, HTTP/3 instead of gQUIC will be used at the HTTP layer.
-// Notable changes are:
-// * Headers stream no longer exists.
-// * PRIORITY, HEADERS are moved from headers stream to HTTP/3 control stream.
-// * PUSH_PROMISE is moved to request stream.
-// * Unidirectional streams will have their first byte as a stream type.
-// * HEADERS frames are compressed using QPACK.
-// * DATA frame has frame headers.
-// * GOAWAY is moved to HTTP layer.
-QUIC_EXPORT_PRIVATE constexpr bool VersionUsesHttp3(
- QuicTransportVersion transport_version) {
- return transport_version >= QUIC_VERSION_IETF_DRAFT_29;
-}
-
-// Returns whether the transport_version supports the variable length integer
-// length field as defined by IETF QUIC draft-13 and later.
-QUIC_EXPORT_PRIVATE constexpr bool QuicVersionHasLongHeaderLengths(
- QuicTransportVersion transport_version) {
- // Long header lengths were added in version 49.
- return transport_version > QUIC_VERSION_46;
-}
-
-// Returns whether |transport_version| makes use of IETF QUIC
-// frames or not.
-QUIC_EXPORT_PRIVATE constexpr bool VersionHasIetfQuicFrames(
- QuicTransportVersion transport_version) {
- return VersionUsesHttp3(transport_version);
-}
-
-// Returns whether this version supports long header 8-bit encoded
-// connection ID lengths as described in draft-ietf-quic-invariants-06 and
-// draft-ietf-quic-transport-22.
-QUIC_EXPORT_PRIVATE bool VersionHasLengthPrefixedConnectionIds(
- QuicTransportVersion transport_version);
-
-// Returns true if this version supports the old Google-style Alt-Svc
-// advertisement format.
-QUIC_EXPORT_PRIVATE bool VersionSupportsGoogleAltSvcFormat(
- QuicTransportVersion transport_version);
-
-// Returns whether this version allows server connection ID lengths that are
-// not 64 bits.
-QUIC_EXPORT_PRIVATE bool VersionAllowsVariableLengthConnectionIds(
- QuicTransportVersion transport_version);
-
-// Returns whether this version label supports long header 4-bit encoded
-// connection ID lengths as described in draft-ietf-quic-invariants-05 and
-// draft-ietf-quic-transport-21.
-QUIC_EXPORT_PRIVATE bool QuicVersionLabelUses4BitConnectionIdLength(
- QuicVersionLabel version_label);
-
-// Returns the ALPN string to use in TLS for this version of QUIC.
-QUIC_EXPORT_PRIVATE std::string AlpnForVersion(
- ParsedQuicVersion parsed_version);
-
-// Initializes support for the provided IETF draft version by setting the
-// correct flags.
-QUIC_EXPORT_PRIVATE void QuicVersionInitializeSupportForIetfDraft();
-
-// Configures the flags required to enable support for this version of QUIC.
-QUIC_EXPORT_PRIVATE void QuicEnableVersion(const ParsedQuicVersion& version);
-
-// Configures the flags required to disable support for this version of QUIC.
-QUIC_EXPORT_PRIVATE void QuicDisableVersion(const ParsedQuicVersion& version);
-
-// Returns whether support for this version of QUIC is currently enabled.
-QUIC_EXPORT_PRIVATE bool QuicVersionIsEnabled(const ParsedQuicVersion& version);
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_QUIC_VERSIONS_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_versions_test.cc b/chromium/net/third_party/quiche/src/quic/core/quic_versions_test.cc
deleted file mode 100644
index 8d420acaf3d..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_versions_test.cc
+++ /dev/null
@@ -1,524 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_versions.h"
-
-#include "absl/base/macros.h"
-#include "quic/platform/api/quic_expect_bug.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/platform/api/quic_mock_log.h"
-#include "quic/platform/api/quic_test.h"
-
-namespace quic {
-namespace test {
-namespace {
-
-using ::testing::ElementsAre;
-using ::testing::IsEmpty;
-
-TEST(QuicVersionsTest, CreateQuicVersionLabelUnsupported) {
- EXPECT_QUIC_BUG(
- CreateQuicVersionLabel(UnsupportedQuicVersion()),
- "Unsupported version QUIC_VERSION_UNSUPPORTED PROTOCOL_UNSUPPORTED");
-}
-
-TEST(QuicVersionsTest, KnownAndValid) {
- for (const ParsedQuicVersion& version : AllSupportedVersions()) {
- EXPECT_TRUE(version.IsKnown());
- EXPECT_TRUE(ParsedQuicVersionIsValid(version.handshake_protocol,
- version.transport_version));
- }
- ParsedQuicVersion unsupported = UnsupportedQuicVersion();
- EXPECT_FALSE(unsupported.IsKnown());
- EXPECT_TRUE(ParsedQuicVersionIsValid(unsupported.handshake_protocol,
- unsupported.transport_version));
- ParsedQuicVersion reserved = QuicVersionReservedForNegotiation();
- EXPECT_TRUE(reserved.IsKnown());
- EXPECT_TRUE(ParsedQuicVersionIsValid(reserved.handshake_protocol,
- reserved.transport_version));
- // Check that invalid combinations are not valid.
- EXPECT_FALSE(ParsedQuicVersionIsValid(PROTOCOL_TLS1_3, QUIC_VERSION_43));
- EXPECT_FALSE(ParsedQuicVersionIsValid(PROTOCOL_QUIC_CRYPTO,
- QUIC_VERSION_IETF_DRAFT_29));
- // Check that deprecated versions are not valid.
- EXPECT_FALSE(ParsedQuicVersionIsValid(PROTOCOL_QUIC_CRYPTO,
- static_cast<QuicTransportVersion>(33)));
- EXPECT_FALSE(ParsedQuicVersionIsValid(PROTOCOL_QUIC_CRYPTO,
- static_cast<QuicTransportVersion>(99)));
- EXPECT_FALSE(ParsedQuicVersionIsValid(PROTOCOL_TLS1_3,
- static_cast<QuicTransportVersion>(99)));
-}
-
-TEST(QuicVersionsTest, Features) {
- ParsedQuicVersion parsed_version_q043 = ParsedQuicVersion::Q043();
- ParsedQuicVersion parsed_version_draft_29 = ParsedQuicVersion::Draft29();
-
- EXPECT_TRUE(parsed_version_q043.IsKnown());
- EXPECT_FALSE(parsed_version_q043.KnowsWhichDecrypterToUse());
- EXPECT_FALSE(parsed_version_q043.UsesInitialObfuscators());
- EXPECT_FALSE(parsed_version_q043.AllowsLowFlowControlLimits());
- EXPECT_FALSE(parsed_version_q043.HasHeaderProtection());
- EXPECT_FALSE(parsed_version_q043.SupportsRetry());
- EXPECT_FALSE(
- parsed_version_q043.SendsVariableLengthPacketNumberInLongHeader());
- EXPECT_FALSE(parsed_version_q043.AllowsVariableLengthConnectionIds());
- EXPECT_FALSE(parsed_version_q043.SupportsClientConnectionIds());
- EXPECT_FALSE(parsed_version_q043.HasLengthPrefixedConnectionIds());
- EXPECT_FALSE(parsed_version_q043.SupportsAntiAmplificationLimit());
- EXPECT_FALSE(parsed_version_q043.CanSendCoalescedPackets());
- EXPECT_TRUE(parsed_version_q043.SupportsGoogleAltSvcFormat());
- EXPECT_FALSE(parsed_version_q043.HasIetfInvariantHeader());
- EXPECT_FALSE(parsed_version_q043.SupportsMessageFrames());
- EXPECT_FALSE(parsed_version_q043.UsesHttp3());
- EXPECT_FALSE(parsed_version_q043.HasLongHeaderLengths());
- EXPECT_FALSE(parsed_version_q043.UsesCryptoFrames());
- EXPECT_FALSE(parsed_version_q043.HasIetfQuicFrames());
- EXPECT_FALSE(parsed_version_q043.UsesTls());
- EXPECT_TRUE(parsed_version_q043.UsesQuicCrypto());
-
- EXPECT_TRUE(parsed_version_draft_29.IsKnown());
- EXPECT_TRUE(parsed_version_draft_29.KnowsWhichDecrypterToUse());
- EXPECT_TRUE(parsed_version_draft_29.UsesInitialObfuscators());
- EXPECT_TRUE(parsed_version_draft_29.AllowsLowFlowControlLimits());
- EXPECT_TRUE(parsed_version_draft_29.HasHeaderProtection());
- EXPECT_TRUE(parsed_version_draft_29.SupportsRetry());
- EXPECT_TRUE(
- parsed_version_draft_29.SendsVariableLengthPacketNumberInLongHeader());
- EXPECT_TRUE(parsed_version_draft_29.AllowsVariableLengthConnectionIds());
- EXPECT_TRUE(parsed_version_draft_29.SupportsClientConnectionIds());
- EXPECT_TRUE(parsed_version_draft_29.HasLengthPrefixedConnectionIds());
- EXPECT_TRUE(parsed_version_draft_29.SupportsAntiAmplificationLimit());
- EXPECT_TRUE(parsed_version_draft_29.CanSendCoalescedPackets());
- EXPECT_FALSE(parsed_version_draft_29.SupportsGoogleAltSvcFormat());
- EXPECT_TRUE(parsed_version_draft_29.HasIetfInvariantHeader());
- EXPECT_TRUE(parsed_version_draft_29.SupportsMessageFrames());
- EXPECT_TRUE(parsed_version_draft_29.UsesHttp3());
- EXPECT_TRUE(parsed_version_draft_29.HasLongHeaderLengths());
- EXPECT_TRUE(parsed_version_draft_29.UsesCryptoFrames());
- EXPECT_TRUE(parsed_version_draft_29.HasIetfQuicFrames());
- EXPECT_TRUE(parsed_version_draft_29.UsesTls());
- EXPECT_FALSE(parsed_version_draft_29.UsesQuicCrypto());
-}
-
-TEST(QuicVersionsTest, ParseQuicVersionLabel) {
- static_assert(SupportedVersions().size() == 6u,
- "Supported versions out of sync");
- EXPECT_EQ(ParsedQuicVersion::Q043(),
- ParseQuicVersionLabel(MakeVersionLabel('Q', '0', '4', '3')));
- EXPECT_EQ(ParsedQuicVersion::Q046(),
- ParseQuicVersionLabel(MakeVersionLabel('Q', '0', '4', '6')));
- EXPECT_EQ(ParsedQuicVersion::Q050(),
- ParseQuicVersionLabel(MakeVersionLabel('Q', '0', '5', '0')));
- EXPECT_EQ(ParsedQuicVersion::Draft29(),
- ParseQuicVersionLabel(MakeVersionLabel(0xff, 0x00, 0x00, 0x1d)));
- EXPECT_EQ(ParsedQuicVersion::RFCv1(),
- ParseQuicVersionLabel(MakeVersionLabel(0x00, 0x00, 0x00, 0x01)));
- EXPECT_EQ(ParsedQuicVersion::V2Draft01(),
- ParseQuicVersionLabel(MakeVersionLabel(0x70, 0x9a, 0x50, 0xc4)));
- EXPECT_EQ((ParsedQuicVersionVector{ParsedQuicVersion::V2Draft01(),
- ParsedQuicVersion::RFCv1(),
- ParsedQuicVersion::Draft29()}),
- ParseQuicVersionLabelVector(QuicVersionLabelVector{
- MakeVersionLabel(0x70, 0x9a, 0x50, 0xc4),
- MakeVersionLabel(0x00, 0x00, 0x00, 0x01),
- MakeVersionLabel(0xaa, 0xaa, 0xaa, 0xaa),
- MakeVersionLabel(0xff, 0x00, 0x00, 0x1d)}));
-
- for (const ParsedQuicVersion& version : AllSupportedVersions()) {
- EXPECT_EQ(version, ParseQuicVersionLabel(CreateQuicVersionLabel(version)));
- }
-}
-
-TEST(QuicVersionsTest, ParseQuicVersionString) {
- static_assert(SupportedVersions().size() == 6u,
- "Supported versions out of sync");
- EXPECT_EQ(ParsedQuicVersion::Q043(), ParseQuicVersionString("Q043"));
- EXPECT_EQ(ParsedQuicVersion::Q046(),
- ParseQuicVersionString("QUIC_VERSION_46"));
- EXPECT_EQ(ParsedQuicVersion::Q046(), ParseQuicVersionString("46"));
- EXPECT_EQ(ParsedQuicVersion::Q046(), ParseQuicVersionString("Q046"));
- EXPECT_EQ(ParsedQuicVersion::Q050(), ParseQuicVersionString("Q050"));
- EXPECT_EQ(ParsedQuicVersion::Q050(), ParseQuicVersionString("50"));
- EXPECT_EQ(ParsedQuicVersion::Q050(), ParseQuicVersionString("h3-Q050"));
-
- EXPECT_EQ(UnsupportedQuicVersion(), ParseQuicVersionString(""));
- EXPECT_EQ(UnsupportedQuicVersion(), ParseQuicVersionString("Q 46"));
- EXPECT_EQ(UnsupportedQuicVersion(), ParseQuicVersionString("Q046 "));
- EXPECT_EQ(UnsupportedQuicVersion(), ParseQuicVersionString("99"));
- EXPECT_EQ(UnsupportedQuicVersion(), ParseQuicVersionString("70"));
-
- EXPECT_EQ(ParsedQuicVersion::Draft29(), ParseQuicVersionString("ff00001d"));
- EXPECT_EQ(ParsedQuicVersion::Draft29(), ParseQuicVersionString("draft29"));
- EXPECT_EQ(ParsedQuicVersion::Draft29(), ParseQuicVersionString("h3-29"));
-
- EXPECT_EQ(ParsedQuicVersion::RFCv1(), ParseQuicVersionString("00000001"));
- EXPECT_EQ(ParsedQuicVersion::RFCv1(), ParseQuicVersionString("h3"));
-
- // QUICv2 will never be the result for "h3".
-
- for (const ParsedQuicVersion& version : AllSupportedVersions()) {
- EXPECT_EQ(version,
- ParseQuicVersionString(ParsedQuicVersionToString(version)));
- EXPECT_EQ(version, ParseQuicVersionString(QuicVersionLabelToString(
- CreateQuicVersionLabel(version))));
- if (!version.AlpnDeferToRFCv1()) {
- EXPECT_EQ(version, ParseQuicVersionString(AlpnForVersion(version)));
- }
- }
-}
-
-TEST(QuicVersionsTest, ParseQuicVersionVectorString) {
- ParsedQuicVersion version_q046 = ParsedQuicVersion::Q046();
- ParsedQuicVersion version_q050 = ParsedQuicVersion::Q050();
- ParsedQuicVersion version_draft_29 = ParsedQuicVersion::Draft29();
-
- EXPECT_THAT(ParseQuicVersionVectorString(""), IsEmpty());
-
- EXPECT_THAT(ParseQuicVersionVectorString("QUIC_VERSION_50"),
- ElementsAre(version_q050));
- EXPECT_THAT(ParseQuicVersionVectorString("h3-Q050"),
- ElementsAre(version_q050));
- EXPECT_THAT(ParseQuicVersionVectorString("h3-Q050, h3-29"),
- ElementsAre(version_q050, version_draft_29));
- EXPECT_THAT(ParseQuicVersionVectorString("h3-29,h3-Q050,h3-29"),
- ElementsAre(version_draft_29, version_q050));
- EXPECT_THAT(ParseQuicVersionVectorString("h3-29,h3-Q050, h3-29"),
- ElementsAre(version_draft_29, version_q050));
- EXPECT_THAT(ParseQuicVersionVectorString("h3-29, h3-Q050"),
- ElementsAre(version_draft_29, version_q050));
- EXPECT_THAT(ParseQuicVersionVectorString("QUIC_VERSION_50,h3-29"),
- ElementsAre(version_q050, version_draft_29));
- EXPECT_THAT(ParseQuicVersionVectorString("h3-29,QUIC_VERSION_50"),
- ElementsAre(version_draft_29, version_q050));
- EXPECT_THAT(ParseQuicVersionVectorString("QUIC_VERSION_50, h3-29"),
- ElementsAre(version_q050, version_draft_29));
- EXPECT_THAT(ParseQuicVersionVectorString("h3-29, QUIC_VERSION_50"),
- ElementsAre(version_draft_29, version_q050));
- EXPECT_THAT(ParseQuicVersionVectorString("QUIC_VERSION_50,QUIC_VERSION_46"),
- ElementsAre(version_q050, version_q046));
- EXPECT_THAT(ParseQuicVersionVectorString("QUIC_VERSION_46,QUIC_VERSION_50"),
- ElementsAre(version_q046, version_q050));
-
- // Regression test for https://crbug.com/1044952.
- EXPECT_THAT(ParseQuicVersionVectorString("QUIC_VERSION_50, QUIC_VERSION_50"),
- ElementsAre(version_q050));
- EXPECT_THAT(ParseQuicVersionVectorString("h3-Q050, h3-Q050"),
- ElementsAre(version_q050));
- EXPECT_THAT(ParseQuicVersionVectorString("h3-Q050, QUIC_VERSION_50"),
- ElementsAre(version_q050));
- EXPECT_THAT(ParseQuicVersionVectorString(
- "QUIC_VERSION_50, h3-Q050, QUIC_VERSION_50, h3-Q050"),
- ElementsAre(version_q050));
- EXPECT_THAT(ParseQuicVersionVectorString("QUIC_VERSION_50, h3-29, h3-Q050"),
- ElementsAre(version_q050, version_draft_29));
-
- EXPECT_THAT(ParseQuicVersionVectorString("99"), IsEmpty());
- EXPECT_THAT(ParseQuicVersionVectorString("70"), IsEmpty());
- EXPECT_THAT(ParseQuicVersionVectorString("h3-01"), IsEmpty());
- EXPECT_THAT(ParseQuicVersionVectorString("h3-01,h3-29"),
- ElementsAre(version_draft_29));
-}
-
-// Do not use MakeVersionLabel() to generate expectations, because
-// CreateQuicVersionLabel() uses MakeVersionLabel() internally,
-// in case it has a bug.
-TEST(QuicVersionsTest, CreateQuicVersionLabel) {
- static_assert(SupportedVersions().size() == 6u,
- "Supported versions out of sync");
- EXPECT_EQ(0x51303433u, CreateQuicVersionLabel(ParsedQuicVersion::Q043()));
- EXPECT_EQ(0x51303436u, CreateQuicVersionLabel(ParsedQuicVersion::Q046()));
- EXPECT_EQ(0x51303530u, CreateQuicVersionLabel(ParsedQuicVersion::Q050()));
- EXPECT_EQ(0xff00001du, CreateQuicVersionLabel(ParsedQuicVersion::Draft29()));
- EXPECT_EQ(0x00000001u, CreateQuicVersionLabel(ParsedQuicVersion::RFCv1()));
- EXPECT_EQ(0x709a50c4u,
- CreateQuicVersionLabel(ParsedQuicVersion::V2Draft01()));
-
- // Make sure the negotiation reserved version is in the IETF reserved space.
- EXPECT_EQ(
- 0xda5a3a3au & 0x0f0f0f0f,
- CreateQuicVersionLabel(ParsedQuicVersion::ReservedForNegotiation()) &
- 0x0f0f0f0f);
-
- // Make sure that disabling randomness works.
- SetQuicFlag(FLAGS_quic_disable_version_negotiation_grease_randomness, true);
- EXPECT_EQ(0xda5a3a3au, CreateQuicVersionLabel(
- ParsedQuicVersion::ReservedForNegotiation()));
-}
-
-TEST(QuicVersionsTest, QuicVersionLabelToString) {
- static_assert(SupportedVersions().size() == 6u,
- "Supported versions out of sync");
- EXPECT_EQ("Q043", QuicVersionLabelToString(
- CreateQuicVersionLabel(ParsedQuicVersion::Q043())));
- EXPECT_EQ("Q046", QuicVersionLabelToString(
- CreateQuicVersionLabel(ParsedQuicVersion::Q046())));
- EXPECT_EQ("Q050", QuicVersionLabelToString(
- CreateQuicVersionLabel(ParsedQuicVersion::Q050())));
- EXPECT_EQ("ff00001d", QuicVersionLabelToString(CreateQuicVersionLabel(
- ParsedQuicVersion::Draft29())));
- EXPECT_EQ("00000001", QuicVersionLabelToString(CreateQuicVersionLabel(
- ParsedQuicVersion::RFCv1())));
- EXPECT_EQ("709a50c4", QuicVersionLabelToString(CreateQuicVersionLabel(
- ParsedQuicVersion::V2Draft01())));
-
- QuicVersionLabelVector version_labels = {
- MakeVersionLabel('Q', '0', '3', '5'),
- MakeVersionLabel('T', '0', '3', '8'),
- MakeVersionLabel(0xff, 0, 0, 7),
- };
-
- EXPECT_EQ("Q035", QuicVersionLabelToString(version_labels[0]));
- EXPECT_EQ("T038", QuicVersionLabelToString(version_labels[1]));
- EXPECT_EQ("ff000007", QuicVersionLabelToString(version_labels[2]));
-
- EXPECT_EQ("Q035,T038,ff000007",
- QuicVersionLabelVectorToString(version_labels));
- EXPECT_EQ("Q035:T038:ff000007",
- QuicVersionLabelVectorToString(version_labels, ":", 2));
- EXPECT_EQ("Q035|T038|...",
- QuicVersionLabelVectorToString(version_labels, "|", 1));
-
- std::ostringstream os;
- os << version_labels;
- EXPECT_EQ("Q035,T038,ff000007", os.str());
-}
-
-TEST(QuicVersionsTest, ParseQuicVersionLabelString) {
- static_assert(SupportedVersions().size() == 6u,
- "Supported versions out of sync");
- // Explicitly test known QUIC version label strings.
- EXPECT_EQ(ParsedQuicVersion::Q043(), ParseQuicVersionLabelString("Q043"));
- EXPECT_EQ(ParsedQuicVersion::Q046(), ParseQuicVersionLabelString("Q046"));
- EXPECT_EQ(ParsedQuicVersion::Q050(), ParseQuicVersionLabelString("Q050"));
- EXPECT_EQ(ParsedQuicVersion::Draft29(),
- ParseQuicVersionLabelString("ff00001d"));
- EXPECT_EQ(ParsedQuicVersion::RFCv1(),
- ParseQuicVersionLabelString("00000001"));
- EXPECT_EQ(ParsedQuicVersion::V2Draft01(),
- ParseQuicVersionLabelString("709a50c4"));
-
- // Sanity check that a variety of other serialization formats are ignored.
- EXPECT_EQ(UnsupportedQuicVersion(), ParseQuicVersionLabelString("1"));
- EXPECT_EQ(UnsupportedQuicVersion(), ParseQuicVersionLabelString("46"));
- EXPECT_EQ(UnsupportedQuicVersion(),
- ParseQuicVersionLabelString("QUIC_VERSION_46"));
- EXPECT_EQ(UnsupportedQuicVersion(), ParseQuicVersionLabelString("h3"));
- EXPECT_EQ(UnsupportedQuicVersion(), ParseQuicVersionLabelString("h3-29"));
-
- // Test round-trips between QuicVersionLabelToString and
- // ParseQuicVersionLabelString.
- for (const ParsedQuicVersion& version : AllSupportedVersions()) {
- EXPECT_EQ(version, ParseQuicVersionLabelString(QuicVersionLabelToString(
- CreateQuicVersionLabel(version))));
- }
-}
-
-TEST(QuicVersionsTest, QuicVersionToString) {
- EXPECT_EQ("QUIC_VERSION_UNSUPPORTED",
- QuicVersionToString(QUIC_VERSION_UNSUPPORTED));
-
- QuicTransportVersion single_version[] = {QUIC_VERSION_43};
- QuicTransportVersionVector versions_vector;
- for (size_t i = 0; i < ABSL_ARRAYSIZE(single_version); ++i) {
- versions_vector.push_back(single_version[i]);
- }
- EXPECT_EQ("QUIC_VERSION_43",
- QuicTransportVersionVectorToString(versions_vector));
-
- QuicTransportVersion multiple_versions[] = {QUIC_VERSION_UNSUPPORTED,
- QUIC_VERSION_43};
- versions_vector.clear();
- for (size_t i = 0; i < ABSL_ARRAYSIZE(multiple_versions); ++i) {
- versions_vector.push_back(multiple_versions[i]);
- }
- EXPECT_EQ("QUIC_VERSION_UNSUPPORTED,QUIC_VERSION_43",
- QuicTransportVersionVectorToString(versions_vector));
-
- // Make sure that all supported versions are present in QuicVersionToString.
- for (const ParsedQuicVersion& version : AllSupportedVersions()) {
- EXPECT_NE("QUIC_VERSION_UNSUPPORTED",
- QuicVersionToString(version.transport_version));
- }
-
- std::ostringstream os;
- os << versions_vector;
- EXPECT_EQ("QUIC_VERSION_UNSUPPORTED,QUIC_VERSION_43", os.str());
-}
-
-TEST(QuicVersionsTest, ParsedQuicVersionToString) {
- EXPECT_EQ("0", ParsedQuicVersionToString(ParsedQuicVersion::Unsupported()));
- EXPECT_EQ("Q043", ParsedQuicVersionToString(ParsedQuicVersion::Q043()));
- EXPECT_EQ("Q046", ParsedQuicVersionToString(ParsedQuicVersion::Q046()));
- EXPECT_EQ("Q050", ParsedQuicVersionToString(ParsedQuicVersion::Q050()));
- EXPECT_EQ("draft29", ParsedQuicVersionToString(ParsedQuicVersion::Draft29()));
- EXPECT_EQ("RFCv1", ParsedQuicVersionToString(ParsedQuicVersion::RFCv1()));
- EXPECT_EQ("v2draft01",
- ParsedQuicVersionToString(ParsedQuicVersion::V2Draft01()));
-
- ParsedQuicVersionVector versions_vector = {ParsedQuicVersion::Q043()};
- EXPECT_EQ("Q043", ParsedQuicVersionVectorToString(versions_vector));
-
- versions_vector = {ParsedQuicVersion::Unsupported(),
- ParsedQuicVersion::Q043()};
- EXPECT_EQ("0,Q043", ParsedQuicVersionVectorToString(versions_vector));
- EXPECT_EQ("0:Q043", ParsedQuicVersionVectorToString(versions_vector, ":",
- versions_vector.size()));
- EXPECT_EQ("0|...", ParsedQuicVersionVectorToString(versions_vector, "|", 0));
-
- // Make sure that all supported versions are present in
- // ParsedQuicVersionToString.
- for (const ParsedQuicVersion& version : AllSupportedVersions()) {
- EXPECT_NE("0", ParsedQuicVersionToString(version));
- }
-
- std::ostringstream os;
- os << versions_vector;
- EXPECT_EQ("0,Q043", os.str());
-}
-
-TEST(QuicVersionsTest, FilterSupportedVersionsAllVersions) {
- for (const ParsedQuicVersion& version : AllSupportedVersions()) {
- QuicEnableVersion(version);
- }
- ParsedQuicVersionVector expected_parsed_versions;
- for (const ParsedQuicVersion& version : SupportedVersions()) {
- expected_parsed_versions.push_back(version);
- }
- EXPECT_EQ(expected_parsed_versions,
- FilterSupportedVersions(AllSupportedVersions()));
- EXPECT_EQ(expected_parsed_versions, AllSupportedVersions());
-}
-
-TEST(QuicVersionsTest, FilterSupportedVersionsWithoutFirstVersion) {
- for (const ParsedQuicVersion& version : AllSupportedVersions()) {
- QuicEnableVersion(version);
- }
- QuicDisableVersion(AllSupportedVersions().front());
- ParsedQuicVersionVector expected_parsed_versions;
- for (const ParsedQuicVersion& version : SupportedVersions()) {
- expected_parsed_versions.push_back(version);
- }
- expected_parsed_versions.erase(expected_parsed_versions.begin());
- EXPECT_EQ(expected_parsed_versions,
- FilterSupportedVersions(AllSupportedVersions()));
-}
-
-TEST(QuicVersionsTest, LookUpParsedVersionByIndex) {
- ParsedQuicVersionVector all_versions = AllSupportedVersions();
- int version_count = all_versions.size();
- for (int i = -5; i <= version_count + 1; ++i) {
- ParsedQuicVersionVector index = ParsedVersionOfIndex(all_versions, i);
- if (i >= 0 && i < version_count) {
- EXPECT_EQ(all_versions[i], index[0]);
- } else {
- EXPECT_EQ(UnsupportedQuicVersion(), index[0]);
- }
- }
-}
-
-// This test may appear to be so simplistic as to be unnecessary,
-// yet a typo was made in doing the #defines and it was caught
-// only in some test far removed from here... Better safe than sorry.
-TEST(QuicVersionsTest, CheckTransportVersionNumbersForTypos) {
- static_assert(SupportedVersions().size() == 6u,
- "Supported versions out of sync");
- EXPECT_EQ(QUIC_VERSION_43, 43);
- EXPECT_EQ(QUIC_VERSION_46, 46);
- EXPECT_EQ(QUIC_VERSION_50, 50);
- EXPECT_EQ(QUIC_VERSION_IETF_DRAFT_29, 73);
- EXPECT_EQ(QUIC_VERSION_IETF_RFC_V1, 80);
- EXPECT_EQ(QUIC_VERSION_IETF_2_DRAFT_01, 81);
-}
-
-TEST(QuicVersionsTest, AlpnForVersion) {
- static_assert(SupportedVersions().size() == 6u,
- "Supported versions out of sync");
- EXPECT_EQ("h3-Q043", AlpnForVersion(ParsedQuicVersion::Q043()));
- EXPECT_EQ("h3-Q046", AlpnForVersion(ParsedQuicVersion::Q046()));
- EXPECT_EQ("h3-Q050", AlpnForVersion(ParsedQuicVersion::Q050()));
- EXPECT_EQ("h3-29", AlpnForVersion(ParsedQuicVersion::Draft29()));
- EXPECT_EQ("h3", AlpnForVersion(ParsedQuicVersion::RFCv1()));
- EXPECT_EQ("h3", AlpnForVersion(ParsedQuicVersion::V2Draft01()));
-}
-
-TEST(QuicVersionsTest, QuicVersionEnabling) {
- for (const ParsedQuicVersion& version : AllSupportedVersions()) {
- QuicFlagSaver flag_saver;
- QuicDisableVersion(version);
- EXPECT_FALSE(QuicVersionIsEnabled(version));
- QuicEnableVersion(version);
- EXPECT_TRUE(QuicVersionIsEnabled(version));
- }
-}
-
-TEST(QuicVersionsTest, ReservedForNegotiation) {
- EXPECT_EQ(QUIC_VERSION_RESERVED_FOR_NEGOTIATION,
- QuicVersionReservedForNegotiation().transport_version);
- // QUIC_VERSION_RESERVED_FOR_NEGOTIATION MUST NOT be supported.
- for (const ParsedQuicVersion& version : AllSupportedVersions()) {
- EXPECT_NE(QUIC_VERSION_RESERVED_FOR_NEGOTIATION, version.transport_version);
- }
-}
-
-TEST(QuicVersionsTest, SupportedVersionsHasCorrectList) {
- size_t index = 0;
- for (HandshakeProtocol handshake_protocol : SupportedHandshakeProtocols()) {
- for (int trans_vers = 255; trans_vers > 0; trans_vers--) {
- QuicTransportVersion transport_version =
- static_cast<QuicTransportVersion>(trans_vers);
- SCOPED_TRACE(index);
- if (ParsedQuicVersionIsValid(handshake_protocol, transport_version)) {
- ParsedQuicVersion version = SupportedVersions()[index];
- EXPECT_EQ(version,
- ParsedQuicVersion(handshake_protocol, transport_version));
- index++;
- }
- }
- }
- EXPECT_EQ(SupportedVersions().size(), index);
-}
-
-TEST(QuicVersionsTest, SupportedVersionsAllDistinct) {
- for (size_t index1 = 0; index1 < SupportedVersions().size(); ++index1) {
- ParsedQuicVersion version1 = SupportedVersions()[index1];
- for (size_t index2 = index1 + 1; index2 < SupportedVersions().size();
- ++index2) {
- ParsedQuicVersion version2 = SupportedVersions()[index2];
- EXPECT_NE(version1, version2) << version1 << " " << version2;
- EXPECT_NE(CreateQuicVersionLabel(version1),
- CreateQuicVersionLabel(version2))
- << version1 << " " << version2;
- // The one pair where ALPNs are the same.
- if ((version1 != ParsedQuicVersion::V2Draft01()) &&
- (version2 != ParsedQuicVersion::RFCv1())) {
- EXPECT_NE(AlpnForVersion(version1), AlpnForVersion(version2))
- << version1 << " " << version2;
- }
- }
- }
-}
-
-TEST(QuicVersionsTest, CurrentSupportedHttp3Versions) {
- ParsedQuicVersionVector h3_versions = CurrentSupportedHttp3Versions();
- ParsedQuicVersionVector all_current_supported_versions =
- CurrentSupportedVersions();
- for (auto& version : all_current_supported_versions) {
- bool version_is_h3 = false;
- for (auto& h3_version : h3_versions) {
- if (version == h3_version) {
- EXPECT_TRUE(version.UsesHttp3());
- version_is_h3 = true;
- break;
- }
- }
- if (!version_is_h3) {
- EXPECT_FALSE(version.UsesHttp3());
- }
- }
-}
-
-} // namespace
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_write_blocked_list.cc b/chromium/net/third_party/quiche/src/quic/core/quic_write_blocked_list.cc
deleted file mode 100644
index 084241db1e3..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_write_blocked_list.cc
+++ /dev/null
@@ -1,182 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_write_blocked_list.h"
-
-#include "quic/platform/api/quic_flag_utils.h"
-#include "quic/platform/api/quic_flags.h"
-
-namespace quic {
-
-QuicWriteBlockedList::QuicWriteBlockedList(QuicTransportVersion version)
- : priority_write_scheduler_(QuicVersionUsesCryptoFrames(version)
- ? std::numeric_limits<QuicStreamId>::max()
- : 0),
- last_priority_popped_(0) {
- memset(batch_write_stream_id_, 0, sizeof(batch_write_stream_id_));
- memset(bytes_left_for_batch_write_, 0, sizeof(bytes_left_for_batch_write_));
-}
-
-QuicWriteBlockedList::~QuicWriteBlockedList() {}
-
-bool QuicWriteBlockedList::ShouldYield(QuicStreamId id) const {
- for (const auto& stream : static_stream_collection_) {
- if (stream.id == id) {
- // Static streams should never yield to data streams, or to lower
- // priority static stream.
- return false;
- }
- if (stream.is_blocked) {
- return true; // All data streams yield to static streams.
- }
- }
-
- return priority_write_scheduler_.ShouldYield(id);
-}
-
-QuicStreamId QuicWriteBlockedList::PopFront() {
- QuicStreamId static_stream_id;
- if (static_stream_collection_.UnblockFirstBlocked(&static_stream_id)) {
- return static_stream_id;
- }
-
- const auto id_and_precedence =
- priority_write_scheduler_.PopNextReadyStreamAndPrecedence();
- const QuicStreamId id = std::get<0>(id_and_precedence);
- const spdy::SpdyPriority priority =
- std::get<1>(id_and_precedence).spdy3_priority();
-
- if (!priority_write_scheduler_.HasReadyStreams()) {
- // If no streams are blocked, don't bother latching. This stream will be
- // the first popped for its priority anyway.
- batch_write_stream_id_[priority] = 0;
- last_priority_popped_ = priority;
- } else if (batch_write_stream_id_[priority] != id) {
- // If newly latching this batch write stream, let it write 16k.
- batch_write_stream_id_[priority] = id;
- bytes_left_for_batch_write_[priority] = 16000;
- last_priority_popped_ = priority;
- }
-
- return id;
-}
-
-void QuicWriteBlockedList::RegisterStream(
- QuicStreamId stream_id,
- bool is_static_stream,
- const spdy::SpdyStreamPrecedence& precedence) {
- QUICHE_DCHECK(!priority_write_scheduler_.StreamRegistered(stream_id))
- << "stream " << stream_id << " already registered";
- QUICHE_DCHECK(precedence.is_spdy3_priority());
- if (is_static_stream) {
- static_stream_collection_.Register(stream_id);
- return;
- }
-
- priority_write_scheduler_.RegisterStream(stream_id, precedence);
-}
-
-void QuicWriteBlockedList::UnregisterStream(QuicStreamId stream_id,
- bool is_static) {
- if (is_static) {
- static_stream_collection_.Unregister(stream_id);
- return;
- }
- priority_write_scheduler_.UnregisterStream(stream_id);
-}
-
-void QuicWriteBlockedList::UpdateStreamPriority(
- QuicStreamId stream_id,
- const spdy::SpdyStreamPrecedence& new_precedence) {
- QUICHE_DCHECK(!static_stream_collection_.IsRegistered(stream_id));
- QUICHE_DCHECK(new_precedence.is_spdy3_priority());
- priority_write_scheduler_.UpdateStreamPrecedence(stream_id, new_precedence);
-}
-
-void QuicWriteBlockedList::UpdateBytesForStream(QuicStreamId stream_id,
- size_t bytes) {
- if (batch_write_stream_id_[last_priority_popped_] == stream_id) {
- // If this was the last data stream popped by PopFront, update the
- // bytes remaining in its batch write.
- bytes_left_for_batch_write_[last_priority_popped_] -=
- std::min(bytes_left_for_batch_write_[last_priority_popped_], bytes);
- }
-}
-
-void QuicWriteBlockedList::AddStream(QuicStreamId stream_id) {
- if (static_stream_collection_.SetBlocked(stream_id)) {
- return;
- }
-
- bool push_front =
- stream_id == batch_write_stream_id_[last_priority_popped_] &&
- bytes_left_for_batch_write_[last_priority_popped_] > 0;
- priority_write_scheduler_.MarkStreamReady(stream_id, push_front);
-}
-
-bool QuicWriteBlockedList::IsStreamBlocked(QuicStreamId stream_id) const {
- for (const auto& stream : static_stream_collection_) {
- if (stream.id == stream_id) {
- return stream.is_blocked;
- }
- }
-
- return priority_write_scheduler_.IsStreamReady(stream_id);
-}
-
-void QuicWriteBlockedList::StaticStreamCollection::Register(QuicStreamId id) {
- QUICHE_DCHECK(!IsRegistered(id));
- streams_.push_back({id, false});
-}
-
-bool QuicWriteBlockedList::StaticStreamCollection::IsRegistered(
- QuicStreamId id) const {
- for (const auto& stream : streams_) {
- if (stream.id == id) {
- return true;
- }
- }
- return false;
-}
-
-void QuicWriteBlockedList::StaticStreamCollection::Unregister(QuicStreamId id) {
- for (auto it = streams_.begin(); it != streams_.end(); ++it) {
- if (it->id == id) {
- if (it->is_blocked) {
- --num_blocked_;
- }
- streams_.erase(it);
- return;
- }
- }
- QUICHE_DCHECK(false) << "Erasing a non-exist stream with id " << id;
-}
-
-bool QuicWriteBlockedList::StaticStreamCollection::SetBlocked(QuicStreamId id) {
- for (auto& stream : streams_) {
- if (stream.id == id) {
- if (!stream.is_blocked) {
- stream.is_blocked = true;
- ++num_blocked_;
- }
- return true;
- }
- }
- return false;
-}
-
-bool QuicWriteBlockedList::StaticStreamCollection::UnblockFirstBlocked(
- QuicStreamId* id) {
- for (auto& stream : streams_) {
- if (stream.is_blocked) {
- --num_blocked_;
- stream.is_blocked = false;
- *id = stream.id;
- return true;
- }
- }
- return false;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_write_blocked_list.h b/chromium/net/third_party/quiche/src/quic/core/quic_write_blocked_list.h
deleted file mode 100644
index 54441e778f1..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_write_blocked_list.h
+++ /dev/null
@@ -1,143 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_WRITE_BLOCKED_LIST_H_
-#define QUICHE_QUIC_CORE_QUIC_WRITE_BLOCKED_LIST_H_
-
-#include <cstddef>
-#include <cstdint>
-#include <utility>
-
-#include "absl/container/inlined_vector.h"
-#include "http2/core/priority_write_scheduler.h"
-#include "quic/core/quic_packets.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_containers.h"
-#include "quic/platform/api/quic_export.h"
-#include "quic/platform/api/quic_flags.h"
-
-namespace quic {
-
-// Keeps tracks of the QUIC streams that have data to write, sorted by
-// priority. QUIC stream priority order is:
-// Crypto stream > Headers stream > Data streams by requested priority.
-class QUIC_EXPORT_PRIVATE QuicWriteBlockedList {
- public:
- explicit QuicWriteBlockedList(QuicTransportVersion version);
- QuicWriteBlockedList(const QuicWriteBlockedList&) = delete;
- QuicWriteBlockedList& operator=(const QuicWriteBlockedList&) = delete;
- ~QuicWriteBlockedList();
-
- bool HasWriteBlockedDataStreams() const {
- return priority_write_scheduler_.HasReadyStreams();
- }
-
- bool HasWriteBlockedSpecialStream() const {
- return static_stream_collection_.num_blocked() > 0;
- }
-
- size_t NumBlockedSpecialStreams() const {
- return static_stream_collection_.num_blocked();
- }
-
- size_t NumBlockedStreams() const {
- return NumBlockedSpecialStreams() +
- priority_write_scheduler_.NumReadyStreams();
- }
-
- bool ShouldYield(QuicStreamId id) const;
-
- spdy::SpdyPriority GetSpdyPriorityofStream(QuicStreamId id) const {
- return priority_write_scheduler_.GetStreamPrecedence(id).spdy3_priority();
- }
-
- // Pops the highest priority stream, special casing crypto and headers
- // streams. Latches the most recently popped data stream for batch writing
- // purposes.
- QuicStreamId PopFront();
-
- void RegisterStream(QuicStreamId stream_id,
- bool is_static_stream,
- const spdy::SpdyStreamPrecedence& precedence);
-
- void UnregisterStream(QuicStreamId stream_id, bool is_static);
-
- void UpdateStreamPriority(QuicStreamId stream_id,
- const spdy::SpdyStreamPrecedence& new_precedence);
-
- void UpdateBytesForStream(QuicStreamId stream_id, size_t bytes);
-
- // Pushes a stream to the back of the list for its priority level *unless* it
- // is latched for doing batched writes in which case it goes to the front of
- // the list for its priority level.
- // Headers and crypto streams are special cased to always resume first.
- void AddStream(QuicStreamId stream_id);
-
- // Returns true if stream with |stream_id| is write blocked.
- bool IsStreamBlocked(QuicStreamId stream_id) const;
-
- private:
- http2::PriorityWriteScheduler<QuicStreamId> priority_write_scheduler_;
-
- // If performing batch writes, this will be the stream ID of the stream doing
- // batch writes for this priority level. We will allow this stream to write
- // until it has written kBatchWriteSize bytes, it has no more data to write,
- // or a higher priority stream preempts.
- QuicStreamId batch_write_stream_id_[spdy::kV3LowestPriority + 1];
- // Set to kBatchWriteSize when we set a new batch_write_stream_id_ for a given
- // priority. This is decremented with each write the stream does until it is
- // done with its batch write.
- size_t bytes_left_for_batch_write_[spdy::kV3LowestPriority + 1];
- // Tracks the last priority popped for UpdateBytesForStream.
- spdy::SpdyPriority last_priority_popped_;
-
- // A StaticStreamCollection is a vector of <QuicStreamId, bool> pairs plus a
- // eagerly-computed number of blocked static streams.
- class QUIC_EXPORT_PRIVATE StaticStreamCollection {
- public:
- struct QUIC_EXPORT_PRIVATE StreamIdBlockedPair {
- QuicStreamId id;
- bool is_blocked;
- };
-
- // Optimized for the typical case of 2 static streams per session.
- using StreamsVector = absl::InlinedVector<StreamIdBlockedPair, 2>;
-
- StreamsVector::const_iterator begin() const { return streams_.cbegin(); }
-
- StreamsVector::const_iterator end() const { return streams_.cend(); }
-
- size_t num_blocked() const { return num_blocked_; }
-
- // Add |id| to the collection in unblocked state.
- void Register(QuicStreamId id);
-
- // True if |id| is in the collection, regardless of its state.
- bool IsRegistered(QuicStreamId id) const;
-
- // Remove |id| from the collection, if it is in the blocked state, reduce
- // |num_blocked_| by 1.
- void Unregister(QuicStreamId id);
-
- // Set |id| to be blocked. If |id| is not already blocked, increase
- // |num_blocked_| by 1.
- // Return true if |id| is in the collection.
- bool SetBlocked(QuicStreamId id);
-
- // Unblock the first blocked stream in the collection.
- // If no stream is blocked, return false. Otherwise return true, set *id to
- // the unblocked stream id and reduce |num_blocked_| by 1.
- bool UnblockFirstBlocked(QuicStreamId* id);
-
- private:
- size_t num_blocked_ = 0;
- StreamsVector streams_;
- };
-
- StaticStreamCollection static_stream_collection_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_QUIC_WRITE_BLOCKED_LIST_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_write_blocked_list_test.cc b/chromium/net/third_party/quiche/src/quic/core/quic_write_blocked_list_test.cc
deleted file mode 100644
index 7cf77972f66..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/quic_write_blocked_list_test.cc
+++ /dev/null
@@ -1,269 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_write_blocked_list.h"
-
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/quic_test_utils.h"
-
-using spdy::kHttp2DefaultStreamWeight;
-using spdy::kV3HighestPriority;
-using spdy::kV3LowestPriority;
-
-namespace quic {
-namespace test {
-namespace {
-
-class QuicWriteBlockedListTest : public QuicTestWithParam<bool> {
- public:
- QuicWriteBlockedListTest()
- : write_blocked_list_(AllSupportedVersions()[0].transport_version) {}
-
- protected:
- QuicWriteBlockedList write_blocked_list_;
-};
-
-TEST_F(QuicWriteBlockedListTest, PriorityOrder) {
- /*
- 0
- |
- 23
- |
- 17
- |
- 40
- */
- // Mark streams blocked in roughly reverse priority order, and
- // verify that streams are sorted.
- write_blocked_list_.RegisterStream(
- 40, false, spdy::SpdyStreamPrecedence(kV3LowestPriority));
- write_blocked_list_.RegisterStream(
- 23, false, spdy::SpdyStreamPrecedence(kV3HighestPriority));
- write_blocked_list_.RegisterStream(
- 17, false, spdy::SpdyStreamPrecedence(kV3HighestPriority));
- write_blocked_list_.RegisterStream(
- 1, true, spdy::SpdyStreamPrecedence(kV3HighestPriority));
- write_blocked_list_.RegisterStream(
- 3, true, spdy::SpdyStreamPrecedence(kV3HighestPriority));
-
- write_blocked_list_.AddStream(40);
- EXPECT_TRUE(write_blocked_list_.IsStreamBlocked(40));
- write_blocked_list_.AddStream(23);
- EXPECT_TRUE(write_blocked_list_.IsStreamBlocked(23));
- write_blocked_list_.AddStream(17);
- EXPECT_TRUE(write_blocked_list_.IsStreamBlocked(17));
- write_blocked_list_.AddStream(3);
- EXPECT_TRUE(write_blocked_list_.IsStreamBlocked(3));
- write_blocked_list_.AddStream(1);
- EXPECT_TRUE(write_blocked_list_.IsStreamBlocked(1));
-
- EXPECT_EQ(5u, write_blocked_list_.NumBlockedStreams());
- EXPECT_TRUE(write_blocked_list_.HasWriteBlockedSpecialStream());
- EXPECT_EQ(2u, write_blocked_list_.NumBlockedSpecialStreams());
- EXPECT_TRUE(write_blocked_list_.HasWriteBlockedDataStreams());
- // The Crypto stream is highest priority.
- EXPECT_EQ(1u, write_blocked_list_.PopFront());
- EXPECT_EQ(1u, write_blocked_list_.NumBlockedSpecialStreams());
- EXPECT_FALSE(write_blocked_list_.IsStreamBlocked(1));
- // Followed by the Headers stream.
- EXPECT_EQ(3u, write_blocked_list_.PopFront());
- EXPECT_EQ(0u, write_blocked_list_.NumBlockedSpecialStreams());
- EXPECT_FALSE(write_blocked_list_.IsStreamBlocked(3));
- // Streams with same priority are popped in the order they were inserted.
- EXPECT_EQ(23u, write_blocked_list_.PopFront());
- EXPECT_FALSE(write_blocked_list_.IsStreamBlocked(23));
- EXPECT_EQ(17u, write_blocked_list_.PopFront());
- EXPECT_FALSE(write_blocked_list_.IsStreamBlocked(17));
- // Low priority stream appears last.
- EXPECT_EQ(40u, write_blocked_list_.PopFront());
- EXPECT_FALSE(write_blocked_list_.IsStreamBlocked(40));
-
- EXPECT_EQ(0u, write_blocked_list_.NumBlockedStreams());
- EXPECT_FALSE(write_blocked_list_.HasWriteBlockedSpecialStream());
- EXPECT_FALSE(write_blocked_list_.HasWriteBlockedDataStreams());
-}
-
-TEST_F(QuicWriteBlockedListTest, CryptoStream) {
- write_blocked_list_.RegisterStream(
- 1, true, spdy::SpdyStreamPrecedence(kV3HighestPriority));
- write_blocked_list_.AddStream(1);
-
- EXPECT_EQ(1u, write_blocked_list_.NumBlockedStreams());
- EXPECT_TRUE(write_blocked_list_.HasWriteBlockedSpecialStream());
- EXPECT_EQ(1u, write_blocked_list_.PopFront());
- EXPECT_EQ(0u, write_blocked_list_.NumBlockedStreams());
- EXPECT_FALSE(write_blocked_list_.HasWriteBlockedSpecialStream());
-}
-
-TEST_F(QuicWriteBlockedListTest, HeadersStream) {
- write_blocked_list_.RegisterStream(
- 3, true, spdy::SpdyStreamPrecedence(kV3HighestPriority));
- write_blocked_list_.AddStream(3);
-
- EXPECT_EQ(1u, write_blocked_list_.NumBlockedStreams());
- EXPECT_TRUE(write_blocked_list_.HasWriteBlockedSpecialStream());
- EXPECT_EQ(3u, write_blocked_list_.PopFront());
- EXPECT_EQ(0u, write_blocked_list_.NumBlockedStreams());
- EXPECT_FALSE(write_blocked_list_.HasWriteBlockedSpecialStream());
-}
-
-TEST_F(QuicWriteBlockedListTest, VerifyHeadersStream) {
- write_blocked_list_.RegisterStream(
- 5, false, spdy::SpdyStreamPrecedence(kV3HighestPriority));
- write_blocked_list_.RegisterStream(
- 3, true, spdy::SpdyStreamPrecedence(kV3HighestPriority));
- write_blocked_list_.AddStream(5);
- write_blocked_list_.AddStream(3);
-
- EXPECT_EQ(2u, write_blocked_list_.NumBlockedStreams());
- EXPECT_TRUE(write_blocked_list_.HasWriteBlockedSpecialStream());
- EXPECT_TRUE(write_blocked_list_.HasWriteBlockedDataStreams());
- // In newer QUIC versions, there is a headers stream which is
- // higher priority than data streams.
- EXPECT_EQ(3u, write_blocked_list_.PopFront());
- EXPECT_EQ(5u, write_blocked_list_.PopFront());
- EXPECT_EQ(0u, write_blocked_list_.NumBlockedStreams());
- EXPECT_FALSE(write_blocked_list_.HasWriteBlockedSpecialStream());
- EXPECT_FALSE(write_blocked_list_.HasWriteBlockedDataStreams());
-}
-
-TEST_F(QuicWriteBlockedListTest, NoDuplicateEntries) {
- // Test that QuicWriteBlockedList doesn't allow duplicate entries.
- // Try to add a stream to the write blocked list multiple times at the same
- // priority.
- const QuicStreamId kBlockedId = 3 + 2;
- write_blocked_list_.RegisterStream(
- kBlockedId, false, spdy::SpdyStreamPrecedence(kV3HighestPriority));
- write_blocked_list_.AddStream(kBlockedId);
- write_blocked_list_.AddStream(kBlockedId);
- write_blocked_list_.AddStream(kBlockedId);
-
- // This should only result in one blocked stream being added.
- EXPECT_EQ(1u, write_blocked_list_.NumBlockedStreams());
- EXPECT_TRUE(write_blocked_list_.HasWriteBlockedDataStreams());
-
- // There should only be one stream to pop off the front.
- EXPECT_EQ(kBlockedId, write_blocked_list_.PopFront());
- EXPECT_EQ(0u, write_blocked_list_.NumBlockedStreams());
- EXPECT_FALSE(write_blocked_list_.HasWriteBlockedDataStreams());
-}
-
-TEST_F(QuicWriteBlockedListTest, BatchingWrites) {
- const QuicStreamId id1 = 3 + 2;
- const QuicStreamId id2 = id1 + 2;
- const QuicStreamId id3 = id2 + 2;
- write_blocked_list_.RegisterStream(
- id1, false, spdy::SpdyStreamPrecedence(kV3LowestPriority));
- write_blocked_list_.RegisterStream(
- id2, false, spdy::SpdyStreamPrecedence(kV3LowestPriority));
- write_blocked_list_.RegisterStream(
- id3, false, spdy::SpdyStreamPrecedence(kV3HighestPriority));
-
- write_blocked_list_.AddStream(id1);
- write_blocked_list_.AddStream(id2);
- EXPECT_EQ(2u, write_blocked_list_.NumBlockedStreams());
-
- // The first stream we push back should stay at the front until 16k is
- // written.
- EXPECT_EQ(id1, write_blocked_list_.PopFront());
- write_blocked_list_.UpdateBytesForStream(id1, 15999);
- write_blocked_list_.AddStream(id1);
- EXPECT_EQ(2u, write_blocked_list_.NumBlockedStreams());
- EXPECT_EQ(id1, write_blocked_list_.PopFront());
-
- // Once 16k is written the first stream will yield to the next.
- write_blocked_list_.UpdateBytesForStream(id1, 1);
- write_blocked_list_.AddStream(id1);
- EXPECT_EQ(2u, write_blocked_list_.NumBlockedStreams());
- EXPECT_EQ(id2, write_blocked_list_.PopFront());
-
- // Set the new stream to have written all but one byte.
- write_blocked_list_.UpdateBytesForStream(id2, 15999);
- write_blocked_list_.AddStream(id2);
- EXPECT_EQ(2u, write_blocked_list_.NumBlockedStreams());
-
- // Ensure higher priority streams are popped first.
- write_blocked_list_.AddStream(id3);
- EXPECT_EQ(id3, write_blocked_list_.PopFront());
-
- // Higher priority streams will always be popped first, even if using their
- // byte quota
- write_blocked_list_.UpdateBytesForStream(id3, 20000);
- write_blocked_list_.AddStream(id3);
- EXPECT_EQ(id3, write_blocked_list_.PopFront());
-
- // Once the higher priority stream is out of the way, id2 will resume its 16k
- // write, with only 1 byte remaining of its guaranteed write allocation.
- EXPECT_EQ(id2, write_blocked_list_.PopFront());
- write_blocked_list_.UpdateBytesForStream(id2, 1);
- write_blocked_list_.AddStream(id2);
- EXPECT_EQ(2u, write_blocked_list_.NumBlockedStreams());
- EXPECT_EQ(id1, write_blocked_list_.PopFront());
-}
-
-TEST_F(QuicWriteBlockedListTest, Ceding) {
- /*
- 0
- |
- 15
- |
- 16
- |
- 5
- |
- 4
- |
- 7
- */
- write_blocked_list_.RegisterStream(
- 15, false, spdy::SpdyStreamPrecedence(kV3HighestPriority));
- write_blocked_list_.RegisterStream(
- 16, false, spdy::SpdyStreamPrecedence(kV3HighestPriority));
- write_blocked_list_.RegisterStream(5, false, spdy::SpdyStreamPrecedence(5));
- write_blocked_list_.RegisterStream(4, false, spdy::SpdyStreamPrecedence(5));
- write_blocked_list_.RegisterStream(7, false, spdy::SpdyStreamPrecedence(7));
- write_blocked_list_.RegisterStream(
- 1, true, spdy::SpdyStreamPrecedence(kV3HighestPriority));
- write_blocked_list_.RegisterStream(
- 3, true, spdy::SpdyStreamPrecedence(kV3HighestPriority));
-
- // When nothing is on the list, nothing yields.
- EXPECT_FALSE(write_blocked_list_.ShouldYield(5));
-
- write_blocked_list_.AddStream(5);
- // 5 should not yield to itself.
- EXPECT_FALSE(write_blocked_list_.ShouldYield(5));
- // 4 and 7 are equal or lower priority and should yield to 5.
- EXPECT_TRUE(write_blocked_list_.ShouldYield(4));
- EXPECT_TRUE(write_blocked_list_.ShouldYield(7));
- // 15, headers and crypto should preempt 5.
- EXPECT_FALSE(write_blocked_list_.ShouldYield(15));
- EXPECT_FALSE(write_blocked_list_.ShouldYield(3));
- EXPECT_FALSE(write_blocked_list_.ShouldYield(1));
-
- // Block a high priority stream.
- write_blocked_list_.AddStream(15);
- // 16 should yield (same priority) but headers and crypto will still not.
- EXPECT_TRUE(write_blocked_list_.ShouldYield(16));
- EXPECT_FALSE(write_blocked_list_.ShouldYield(3));
- EXPECT_FALSE(write_blocked_list_.ShouldYield(1));
-
- // Block the headers stream. All streams but crypto and headers should yield.
- write_blocked_list_.AddStream(3);
- EXPECT_TRUE(write_blocked_list_.ShouldYield(16));
- EXPECT_TRUE(write_blocked_list_.ShouldYield(15));
- EXPECT_FALSE(write_blocked_list_.ShouldYield(3));
- EXPECT_FALSE(write_blocked_list_.ShouldYield(1));
-
- // Block the crypto stream. All streams but crypto should yield.
- write_blocked_list_.AddStream(1);
- EXPECT_TRUE(write_blocked_list_.ShouldYield(16));
- EXPECT_TRUE(write_blocked_list_.ShouldYield(15));
- EXPECT_TRUE(write_blocked_list_.ShouldYield(3));
- EXPECT_FALSE(write_blocked_list_.ShouldYield(1));
-}
-
-} // namespace
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/session_notifier_interface.h b/chromium/net/third_party/quiche/src/quic/core/session_notifier_interface.h
deleted file mode 100644
index fc16b63407b..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/session_notifier_interface.h
+++ /dev/null
@@ -1,47 +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_CORE_SESSION_NOTIFIER_INTERFACE_H_
-#define QUICHE_QUIC_CORE_SESSION_NOTIFIER_INTERFACE_H_
-
-#include "quic/core/frames/quic_frame.h"
-#include "quic/core/quic_time.h"
-
-namespace quic {
-
-// Pure virtual class to be notified when a packet containing a frame is acked
-// or lost.
-class QUIC_EXPORT_PRIVATE SessionNotifierInterface {
- public:
- virtual ~SessionNotifierInterface() {}
-
- // Called when |frame| is acked. Returns true if any new data gets acked,
- // returns false otherwise.
- virtual bool OnFrameAcked(const QuicFrame& frame,
- QuicTime::Delta ack_delay_time,
- QuicTime receive_timestamp) = 0;
-
- // Called when |frame| is retransmitted.
- virtual void OnStreamFrameRetransmitted(const QuicStreamFrame& frame) = 0;
-
- // Called when |frame| is considered as lost.
- virtual void OnFrameLost(const QuicFrame& frame) = 0;
-
- // Called to retransmit |frames| with transmission |type|.
- virtual void RetransmitFrames(const QuicFrames& frames,
- TransmissionType type) = 0;
-
- // Returns true if |frame| is outstanding and waiting to be acked.
- virtual bool IsFrameOutstanding(const QuicFrame& frame) const = 0;
-
- // Returns true if crypto stream is waiting for acks.
- virtual bool HasUnackedCryptoData() const = 0;
-
- // Returns true if any stream is waiting for acks.
- virtual bool HasUnackedStreamData() const = 0;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_SESSION_NOTIFIER_INTERFACE_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/stream_delegate_interface.h b/chromium/net/third_party/quiche/src/quic/core/stream_delegate_interface.h
deleted file mode 100644
index 02b195ef0c4..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/stream_delegate_interface.h
+++ /dev/null
@@ -1,58 +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_CORE_STREAM_DELEGATE_INTERFACE_H_
-#define QUICHE_QUIC_CORE_STREAM_DELEGATE_INTERFACE_H_
-
-#include <cstddef>
-#include "absl/types/optional.h"
-#include "quic/core/quic_types.h"
-#include "spdy/core/spdy_protocol.h"
-
-namespace quic {
-
-class QuicStream;
-
-// Pure virtual class to get notified when particular QuicStream events
-// occurred.
-class QUIC_EXPORT_PRIVATE StreamDelegateInterface {
- public:
- virtual ~StreamDelegateInterface() {}
-
- // Called when the stream has encountered errors that it can't handle.
- virtual void OnStreamError(QuicErrorCode error_code,
- std::string error_details) = 0;
- // Called when the stream has encountered errors that it can't handle,
- // specifying the wire error code |ietf_error| explicitly.
- virtual void OnStreamError(QuicErrorCode error_code,
- QuicIetfTransportErrorCodes ietf_error,
- std::string error_details) = 0;
- // Called when the stream needs to write data at specified |level| and
- // transmission |type|.
- virtual QuicConsumedData WritevData(QuicStreamId id, size_t write_length,
- QuicStreamOffset offset,
- StreamSendingState state,
- TransmissionType type,
- EncryptionLevel level) = 0;
- // Called to write crypto data.
- virtual size_t SendCryptoData(EncryptionLevel level,
- size_t write_length,
- QuicStreamOffset offset,
- TransmissionType type) = 0;
- // Called on stream creation.
- virtual void RegisterStreamPriority(
- QuicStreamId id,
- bool is_static,
- const spdy::SpdyStreamPrecedence& precedence) = 0;
- // Called on stream destruction to clear priority.
- virtual void UnregisterStreamPriority(QuicStreamId id, bool is_static) = 0;
- // Called by the stream on SetPriority to update priority.
- virtual void UpdateStreamPriority(
- QuicStreamId id,
- const spdy::SpdyStreamPrecedence& new_precedence) = 0;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_STREAM_DELEGATE_INTERFACE_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/tls_chlo_extractor.cc b/chromium/net/third_party/quiche/src/quic/core/tls_chlo_extractor.cc
deleted file mode 100644
index 3a2df79e80b..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/tls_chlo_extractor.cc
+++ /dev/null
@@ -1,425 +0,0 @@
-// Copyright (c) 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/tls_chlo_extractor.h"
-#include <cstring>
-#include <memory>
-
-#include "absl/strings/str_cat.h"
-#include "absl/strings/string_view.h"
-#include "third_party/boringssl/src/include/openssl/ssl.h"
-#include "quic/core/frames/quic_crypto_frame.h"
-#include "quic/core/quic_data_reader.h"
-#include "quic/core/quic_error_codes.h"
-#include "quic/core/quic_framer.h"
-#include "quic/core/quic_time.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_versions.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-
-namespace quic {
-
-namespace {
-bool HasExtension(const SSL_CLIENT_HELLO* client_hello, uint16_t extension) {
- const uint8_t* unused_extension_bytes;
- size_t unused_extension_len;
- return 1 == SSL_early_callback_ctx_extension_get(client_hello, extension,
- &unused_extension_bytes,
- &unused_extension_len);
-}
-} // namespace
-
-TlsChloExtractor::TlsChloExtractor()
- : crypto_stream_sequencer_(this),
- state_(State::kInitial),
- parsed_crypto_frame_in_this_packet_(false) {}
-
-TlsChloExtractor::TlsChloExtractor(TlsChloExtractor&& other)
- : TlsChloExtractor() {
- *this = std::move(other);
-}
-
-TlsChloExtractor& TlsChloExtractor::operator=(TlsChloExtractor&& other) {
- framer_ = std::move(other.framer_);
- if (framer_) {
- framer_->set_visitor(this);
- }
- crypto_stream_sequencer_ = std::move(other.crypto_stream_sequencer_);
- crypto_stream_sequencer_.set_stream(this);
- ssl_ = std::move(other.ssl_);
- if (ssl_) {
- std::pair<SSL_CTX*, int> shared_handles = GetSharedSslHandles();
- int ex_data_index = shared_handles.second;
- const int rv = SSL_set_ex_data(ssl_.get(), ex_data_index, this);
- QUICHE_CHECK_EQ(rv, 1) << "Internal allocation failure in SSL_set_ex_data";
- }
- state_ = other.state_;
- error_details_ = std::move(other.error_details_);
- parsed_crypto_frame_in_this_packet_ =
- other.parsed_crypto_frame_in_this_packet_;
- alpns_ = std::move(other.alpns_);
- server_name_ = std::move(other.server_name_);
- return *this;
-}
-
-void TlsChloExtractor::IngestPacket(const ParsedQuicVersion& version,
- const QuicReceivedPacket& packet) {
- if (state_ == State::kUnrecoverableFailure) {
- QUIC_DLOG(ERROR) << "Not ingesting packet after unrecoverable error";
- return;
- }
- if (version == UnsupportedQuicVersion()) {
- QUIC_DLOG(ERROR) << "Not ingesting packet with unsupported version";
- return;
- }
- if (version.handshake_protocol != PROTOCOL_TLS1_3) {
- QUIC_DLOG(ERROR) << "Not ingesting packet with non-TLS version " << version;
- return;
- }
- if (framer_) {
- // This is not the first packet we have ingested, check if version matches.
- if (!framer_->IsSupportedVersion(version)) {
- QUIC_DLOG(ERROR)
- << "Not ingesting packet with version mismatch, expected "
- << framer_->version() << ", got " << version;
- return;
- }
- } else {
- // This is the first packet we have ingested, setup parser.
- framer_ = std::make_unique<QuicFramer>(
- ParsedQuicVersionVector{version}, QuicTime::Zero(),
- Perspective::IS_SERVER, /*expected_server_connection_id_length=*/0);
- // Note that expected_server_connection_id_length only matters for short
- // headers and we explicitly drop those so we can pass any value here.
- framer_->set_visitor(this);
- }
-
- // When the framer parses |packet|, if it sees a CRYPTO frame it will call
- // OnCryptoFrame below and that will set parsed_crypto_frame_in_this_packet_
- // to true.
- parsed_crypto_frame_in_this_packet_ = false;
- const bool parse_success = framer_->ProcessPacket(packet);
- if (state_ == State::kInitial && parsed_crypto_frame_in_this_packet_) {
- // If we parsed a CRYPTO frame but didn't advance the state from initial,
- // then it means that we will need more packets to reassemble the full CHLO,
- // so we advance the state here. This can happen when the first packet
- // received is not the first one in the crypto stream. This allows us to
- // differentiate our state between single-packet CHLO and multi-packet CHLO.
- state_ = State::kParsedPartialChloFragment;
- }
-
- if (!parse_success) {
- // This could be due to the packet being non-initial for example.
- QUIC_DLOG(ERROR) << "Failed to process packet";
- return;
- }
-}
-
-// This is called when the framer parsed the unencrypted parts of the header.
-bool TlsChloExtractor::OnUnauthenticatedPublicHeader(
- const QuicPacketHeader& header) {
- if (header.form != IETF_QUIC_LONG_HEADER_PACKET) {
- QUIC_DLOG(ERROR) << "Not parsing non-long-header packet " << header;
- return false;
- }
- if (header.long_packet_type != INITIAL) {
- QUIC_DLOG(ERROR) << "Not parsing non-initial packet " << header;
- return false;
- }
- // QuicFramer is constructed without knowledge of the server's connection ID
- // so it needs to be set up here in order to decrypt the packet.
- framer_->SetInitialObfuscators(header.destination_connection_id);
- return true;
-}
-
-// This is called by the framer if it detects a change in version during
-// parsing.
-bool TlsChloExtractor::OnProtocolVersionMismatch(ParsedQuicVersion version) {
- // This should never be called because we already check versions in
- // IngestPacket.
- QUIC_BUG(quic_bug_10855_1) << "Unexpected version mismatch, expected "
- << framer_->version() << ", got " << version;
- return false;
-}
-
-// This is called by the QuicStreamSequencer if it encounters an unrecoverable
-// error that will prevent it from reassembling the crypto stream data.
-void TlsChloExtractor::OnUnrecoverableError(QuicErrorCode error,
- const std::string& details) {
- HandleUnrecoverableError(absl::StrCat(
- "Crypto stream error ", QuicErrorCodeToString(error), ": ", details));
-}
-
-void TlsChloExtractor::OnUnrecoverableError(
- QuicErrorCode error,
- QuicIetfTransportErrorCodes ietf_error,
- const std::string& details) {
- HandleUnrecoverableError(absl::StrCat(
- "Crypto stream error ", QuicErrorCodeToString(error), "(",
- QuicIetfTransportErrorCodeString(ietf_error), "): ", details));
-}
-
-// This is called by the framer if it sees a CRYPTO frame during parsing.
-bool TlsChloExtractor::OnCryptoFrame(const QuicCryptoFrame& frame) {
- if (frame.level != ENCRYPTION_INITIAL) {
- // Since we drop non-INITIAL packets in OnUnauthenticatedPublicHeader,
- // we should never receive any CRYPTO frames at other encryption levels.
- QUIC_BUG(quic_bug_10855_2) << "Parsed bad-level CRYPTO frame " << frame;
- return false;
- }
- // parsed_crypto_frame_in_this_packet_ is checked in IngestPacket to allow
- // advancing our state to track the difference between single-packet CHLO
- // and multi-packet CHLO.
- parsed_crypto_frame_in_this_packet_ = true;
- crypto_stream_sequencer_.OnCryptoFrame(frame);
- return true;
-}
-
-// Called by the QuicStreamSequencer when it receives a CRYPTO frame that
-// advances the amount of contiguous data we now have starting from offset 0.
-void TlsChloExtractor::OnDataAvailable() {
- // Lazily set up BoringSSL handle.
- SetupSslHandle();
-
- // Get data from the stream sequencer and pass it to BoringSSL.
- struct iovec iov;
- while (crypto_stream_sequencer_.GetReadableRegion(&iov)) {
- const int rv = SSL_provide_quic_data(
- ssl_.get(), ssl_encryption_initial,
- reinterpret_cast<const uint8_t*>(iov.iov_base), iov.iov_len);
- if (rv != 1) {
- HandleUnrecoverableError("SSL_provide_quic_data failed");
- return;
- }
- crypto_stream_sequencer_.MarkConsumed(iov.iov_len);
- }
-
- // Instruct BoringSSL to attempt parsing a full CHLO from the provided data.
- // We ignore the return value since we know the handshake is going to fail
- // because we explicitly cancel processing once we've parsed the CHLO.
- (void)SSL_do_handshake(ssl_.get());
-}
-
-// static
-TlsChloExtractor* TlsChloExtractor::GetInstanceFromSSL(SSL* ssl) {
- std::pair<SSL_CTX*, int> shared_handles = GetSharedSslHandles();
- int ex_data_index = shared_handles.second;
- return reinterpret_cast<TlsChloExtractor*>(
- SSL_get_ex_data(ssl, ex_data_index));
-}
-
-// static
-int TlsChloExtractor::SetReadSecretCallback(
- SSL* ssl,
- enum ssl_encryption_level_t /*level*/,
- const SSL_CIPHER* /*cipher*/,
- const uint8_t* /*secret*/,
- size_t /*secret_length*/) {
- GetInstanceFromSSL(ssl)->HandleUnexpectedCallback("SetReadSecretCallback");
- return 0;
-}
-
-// static
-int TlsChloExtractor::SetWriteSecretCallback(
- SSL* ssl,
- enum ssl_encryption_level_t /*level*/,
- const SSL_CIPHER* /*cipher*/,
- const uint8_t* /*secret*/,
- size_t /*secret_length*/) {
- GetInstanceFromSSL(ssl)->HandleUnexpectedCallback("SetWriteSecretCallback");
- return 0;
-}
-
-// static
-int TlsChloExtractor::WriteMessageCallback(
- SSL* ssl,
- enum ssl_encryption_level_t /*level*/,
- const uint8_t* /*data*/,
- size_t /*len*/) {
- GetInstanceFromSSL(ssl)->HandleUnexpectedCallback("WriteMessageCallback");
- return 0;
-}
-
-// static
-int TlsChloExtractor::FlushFlightCallback(SSL* ssl) {
- GetInstanceFromSSL(ssl)->HandleUnexpectedCallback("FlushFlightCallback");
- return 0;
-}
-
-void TlsChloExtractor::HandleUnexpectedCallback(
- const std::string& callback_name) {
- std::string error_details =
- absl::StrCat("Unexpected callback ", callback_name);
- QUIC_BUG(quic_bug_10855_3) << error_details;
- HandleUnrecoverableError(error_details);
-}
-
-// static
-int TlsChloExtractor::SendAlertCallback(SSL* ssl,
- enum ssl_encryption_level_t /*level*/,
- uint8_t desc) {
- GetInstanceFromSSL(ssl)->SendAlert(desc);
- return 0;
-}
-
-void TlsChloExtractor::SendAlert(uint8_t tls_alert_value) {
- if (tls_alert_value == SSL3_AD_HANDSHAKE_FAILURE && HasParsedFullChlo()) {
- // This is the most common scenario. Since we return an error from
- // SelectCertCallback in order to cancel further processing, BoringSSL will
- // try to send this alert to tell the client that the handshake failed.
- return;
- }
- HandleUnrecoverableError(absl::StrCat(
- "BoringSSL attempted to send alert ", static_cast<int>(tls_alert_value),
- " ", SSL_alert_desc_string_long(tls_alert_value)));
-}
-
-// static
-enum ssl_select_cert_result_t TlsChloExtractor::SelectCertCallback(
- const SSL_CLIENT_HELLO* client_hello) {
- GetInstanceFromSSL(client_hello->ssl)->HandleParsedChlo(client_hello);
- // Always return an error to cancel any further processing in BoringSSL.
- return ssl_select_cert_error;
-}
-
-// Extracts the server name and ALPN from the parsed ClientHello.
-void TlsChloExtractor::HandleParsedChlo(const SSL_CLIENT_HELLO* client_hello) {
- const char* server_name =
- SSL_get_servername(client_hello->ssl, TLSEXT_NAMETYPE_host_name);
- if (server_name) {
- server_name_ = std::string(server_name);
- }
-
- resumption_attempted_ =
- HasExtension(client_hello, TLSEXT_TYPE_pre_shared_key);
- early_data_attempted_ = HasExtension(client_hello, TLSEXT_TYPE_early_data);
-
- const uint8_t* alpn_data;
- size_t alpn_len;
- int rv = SSL_early_callback_ctx_extension_get(
- client_hello, TLSEXT_TYPE_application_layer_protocol_negotiation,
- &alpn_data, &alpn_len);
- if (rv == 1) {
- QuicDataReader alpns_reader(reinterpret_cast<const char*>(alpn_data),
- alpn_len);
- absl::string_view alpns_payload;
- if (!alpns_reader.ReadStringPiece16(&alpns_payload)) {
- HandleUnrecoverableError("Failed to read alpns_payload");
- return;
- }
- QuicDataReader alpns_payload_reader(alpns_payload);
- while (!alpns_payload_reader.IsDoneReading()) {
- absl::string_view alpn_payload;
- if (!alpns_payload_reader.ReadStringPiece8(&alpn_payload)) {
- HandleUnrecoverableError("Failed to read alpn_payload");
- return;
- }
- alpns_.emplace_back(std::string(alpn_payload));
- }
- }
-
- // Update our state now that we've parsed a full CHLO.
- if (state_ == State::kInitial) {
- state_ = State::kParsedFullSinglePacketChlo;
- } else if (state_ == State::kParsedPartialChloFragment) {
- state_ = State::kParsedFullMultiPacketChlo;
- } else {
- QUIC_BUG(quic_bug_10855_4)
- << "Unexpected state on successful parse " << StateToString(state_);
- }
-}
-
-// static
-std::pair<SSL_CTX*, int> TlsChloExtractor::GetSharedSslHandles() {
- // Use a lambda to benefit from C++11 guarantee that static variables are
- // initialized lazily in a thread-safe manner. |shared_handles| is therefore
- // guaranteed to be initialized exactly once and never destructed.
- static std::pair<SSL_CTX*, int>* shared_handles = []() {
- CRYPTO_library_init();
- SSL_CTX* ssl_ctx = SSL_CTX_new(TLS_with_buffers_method());
- SSL_CTX_set_min_proto_version(ssl_ctx, TLS1_3_VERSION);
- SSL_CTX_set_max_proto_version(ssl_ctx, TLS1_3_VERSION);
- static const SSL_QUIC_METHOD kQuicCallbacks{
- TlsChloExtractor::SetReadSecretCallback,
- TlsChloExtractor::SetWriteSecretCallback,
- TlsChloExtractor::WriteMessageCallback,
- TlsChloExtractor::FlushFlightCallback,
- TlsChloExtractor::SendAlertCallback};
- SSL_CTX_set_quic_method(ssl_ctx, &kQuicCallbacks);
- SSL_CTX_set_select_certificate_cb(ssl_ctx,
- TlsChloExtractor::SelectCertCallback);
- int ex_data_index =
- SSL_get_ex_new_index(0, nullptr, nullptr, nullptr, nullptr);
- return new std::pair<SSL_CTX*, int>(ssl_ctx, ex_data_index);
- }();
- return *shared_handles;
-}
-
-// Sets up the per-instance SSL handle needed by BoringSSL.
-void TlsChloExtractor::SetupSslHandle() {
- if (ssl_) {
- // Handles have already been set up.
- return;
- }
-
- std::pair<SSL_CTX*, int> shared_handles = GetSharedSslHandles();
- SSL_CTX* ssl_ctx = shared_handles.first;
- int ex_data_index = shared_handles.second;
-
- ssl_ = bssl::UniquePtr<SSL>(SSL_new(ssl_ctx));
- const int rv = SSL_set_ex_data(ssl_.get(), ex_data_index, this);
- QUICHE_CHECK_EQ(rv, 1) << "Internal allocation failure in SSL_set_ex_data";
- SSL_set_accept_state(ssl_.get());
-
- // Make sure we use the right TLS extension codepoint.
- int use_legacy_extension = 0;
- if (framer_->version().UsesLegacyTlsExtension()) {
- use_legacy_extension = 1;
- }
- SSL_set_quic_use_legacy_codepoint(ssl_.get(), use_legacy_extension);
-}
-
-// Called by other methods to record any unrecoverable failures they experience.
-void TlsChloExtractor::HandleUnrecoverableError(
- const std::string& error_details) {
- if (HasParsedFullChlo()) {
- // Ignore errors if we've parsed everything successfully.
- QUIC_DLOG(ERROR) << "Ignoring error: " << error_details;
- return;
- }
- QUIC_DLOG(ERROR) << "Handling error: " << error_details;
-
- state_ = State::kUnrecoverableFailure;
-
- if (error_details_.empty()) {
- error_details_ = error_details;
- } else {
- error_details_ = absl::StrCat(error_details_, "; ", error_details);
- }
-}
-
-// static
-std::string TlsChloExtractor::StateToString(State state) {
- switch (state) {
- case State::kInitial:
- return "Initial";
- case State::kParsedFullSinglePacketChlo:
- return "ParsedFullSinglePacketChlo";
- case State::kParsedFullMultiPacketChlo:
- return "ParsedFullMultiPacketChlo";
- case State::kParsedPartialChloFragment:
- return "ParsedPartialChloFragment";
- case State::kUnrecoverableFailure:
- return "UnrecoverableFailure";
- }
- return absl::StrCat("Unknown(", static_cast<int>(state), ")");
-}
-
-std::ostream& operator<<(std::ostream& os,
- const TlsChloExtractor::State& state) {
- os << TlsChloExtractor::StateToString(state);
- return os;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/tls_chlo_extractor.h b/chromium/net/third_party/quiche/src/quic/core/tls_chlo_extractor.h
deleted file mode 100644
index 29296dd8795..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/tls_chlo_extractor.h
+++ /dev/null
@@ -1,265 +0,0 @@
-// Copyright (c) 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_TLS_CHLO_EXTRACTOR_H_
-#define QUICHE_QUIC_CORE_TLS_CHLO_EXTRACTOR_H_
-
-#include <memory>
-#include <string>
-#include <vector>
-#include "third_party/boringssl/src/include/openssl/ssl.h"
-#include "quic/core/frames/quic_ack_frequency_frame.h"
-#include "quic/core/quic_framer.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_stream_sequencer.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// Utility class that allows extracting information from a QUIC-TLS Client
-// Hello. This class creates a QuicFramer to parse the packet, and implements
-// QuicFramerVisitorInterface to access the frames parsed by the QuicFramer. It
-// then uses a QuicStreamSequencer to reassemble the contents of the crypto
-// stream, and implements QuicStreamSequencer::StreamInterface to access the
-// reassembled data.
-class QUIC_NO_EXPORT TlsChloExtractor
- : public QuicFramerVisitorInterface,
- public QuicStreamSequencer::StreamInterface {
- public:
- TlsChloExtractor();
- TlsChloExtractor(const TlsChloExtractor&) = delete;
- TlsChloExtractor(TlsChloExtractor&&);
- TlsChloExtractor& operator=(const TlsChloExtractor&) = delete;
- TlsChloExtractor& operator=(TlsChloExtractor&&);
-
- enum class State : uint8_t {
- kInitial = 0,
- kParsedFullSinglePacketChlo = 1,
- kParsedFullMultiPacketChlo = 2,
- kParsedPartialChloFragment = 3,
- kUnrecoverableFailure = 4,
- };
-
- State state() const { return state_; }
- std::vector<std::string> alpns() const { return alpns_; }
- std::string server_name() const { return server_name_; }
- bool resumption_attempted() const { return resumption_attempted_; }
- bool early_data_attempted() const { return early_data_attempted_; }
-
- // Converts |state| to a human-readable string suitable for logging.
- static std::string StateToString(State state);
-
- // Ingests |packet| and attempts to parse out the CHLO.
- void IngestPacket(const ParsedQuicVersion& version,
- const QuicReceivedPacket& packet);
-
- // Returns whether the ingested packets have allowed parsing a complete CHLO.
- bool HasParsedFullChlo() const {
- return state_ == State::kParsedFullSinglePacketChlo ||
- state_ == State::kParsedFullMultiPacketChlo;
- }
-
- // Methods from QuicFramerVisitorInterface.
- void OnError(QuicFramer* /*framer*/) override {}
- bool OnProtocolVersionMismatch(ParsedQuicVersion version) override;
- void OnPacket() override {}
- void OnPublicResetPacket(const QuicPublicResetPacket& /*packet*/) override {}
- void OnVersionNegotiationPacket(
- const QuicVersionNegotiationPacket& /*packet*/) override {}
- void OnRetryPacket(QuicConnectionId /*original_connection_id*/,
- QuicConnectionId /*new_connection_id*/,
- absl::string_view /*retry_token*/,
- absl::string_view /*retry_integrity_tag*/,
- absl::string_view /*retry_without_tag*/) override {}
- bool OnUnauthenticatedPublicHeader(const QuicPacketHeader& header) override;
- bool OnUnauthenticatedHeader(const QuicPacketHeader& /*header*/) override {
- return true;
- }
- void OnDecryptedPacket(size_t /*packet_length*/,
- EncryptionLevel /*level*/) override {}
- bool OnPacketHeader(const QuicPacketHeader& /*header*/) override {
- return true;
- }
- void OnCoalescedPacket(const QuicEncryptedPacket& /*packet*/) override {}
- void OnUndecryptablePacket(const QuicEncryptedPacket& /*packet*/,
- EncryptionLevel /*decryption_level*/,
- bool /*has_decryption_key*/) override {}
- bool OnStreamFrame(const QuicStreamFrame& /*frame*/) override { return true; }
- bool OnCryptoFrame(const QuicCryptoFrame& frame) override;
- bool OnAckFrameStart(QuicPacketNumber /*largest_acked*/,
- QuicTime::Delta /*ack_delay_time*/) override {
- return true;
- }
- bool OnAckRange(QuicPacketNumber /*start*/,
- QuicPacketNumber /*end*/) override {
- return true;
- }
- bool OnAckTimestamp(QuicPacketNumber /*packet_number*/,
- QuicTime /*timestamp*/) override {
- return true;
- }
- bool OnAckFrameEnd(QuicPacketNumber /*start*/) override { return true; }
- bool OnStopWaitingFrame(const QuicStopWaitingFrame& /*frame*/) override {
- return true;
- }
- bool OnPingFrame(const QuicPingFrame& /*frame*/) override { return true; }
- bool OnRstStreamFrame(const QuicRstStreamFrame& /*frame*/) override {
- return true;
- }
- bool OnConnectionCloseFrame(
- const QuicConnectionCloseFrame& /*frame*/) override {
- return true;
- }
- bool OnNewConnectionIdFrame(
- const QuicNewConnectionIdFrame& /*frame*/) override {
- return true;
- }
- bool OnRetireConnectionIdFrame(
- const QuicRetireConnectionIdFrame& /*frame*/) override {
- return true;
- }
- bool OnNewTokenFrame(const QuicNewTokenFrame& /*frame*/) override {
- return true;
- }
- bool OnStopSendingFrame(const QuicStopSendingFrame& /*frame*/) override {
- return true;
- }
- bool OnPathChallengeFrame(const QuicPathChallengeFrame& /*frame*/) override {
- return true;
- }
- bool OnPathResponseFrame(const QuicPathResponseFrame& /*frame*/) override {
- return true;
- }
- bool OnGoAwayFrame(const QuicGoAwayFrame& /*frame*/) override { return true; }
- bool OnMaxStreamsFrame(const QuicMaxStreamsFrame& /*frame*/) override {
- return true;
- }
- bool OnStreamsBlockedFrame(
- const QuicStreamsBlockedFrame& /*frame*/) override {
- return true;
- }
- bool OnWindowUpdateFrame(const QuicWindowUpdateFrame& /*frame*/) override {
- return true;
- }
- bool OnBlockedFrame(const QuicBlockedFrame& /*frame*/) override {
- return true;
- }
- bool OnPaddingFrame(const QuicPaddingFrame& /*frame*/) override {
- return true;
- }
- bool OnMessageFrame(const QuicMessageFrame& /*frame*/) override {
- return true;
- }
- bool OnHandshakeDoneFrame(const QuicHandshakeDoneFrame& /*frame*/) override {
- return true;
- }
- bool OnAckFrequencyFrame(const QuicAckFrequencyFrame& /*frame*/) override {
- return true;
- }
- void OnPacketComplete() override {}
- bool IsValidStatelessResetToken(
- const StatelessResetToken& /*token*/) const override {
- return true;
- }
- void OnAuthenticatedIetfStatelessResetPacket(
- const QuicIetfStatelessResetPacket& /*packet*/) override {}
- void OnKeyUpdate(KeyUpdateReason /*reason*/) override {}
- void OnDecryptedFirstPacketInKeyPhase() override {}
- std::unique_ptr<QuicDecrypter> AdvanceKeysAndCreateCurrentOneRttDecrypter()
- override {
- return nullptr;
- }
- std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() override {
- return nullptr;
- }
-
- // Methods from QuicStreamSequencer::StreamInterface.
- void OnDataAvailable() override;
- void OnFinRead() override {}
- void AddBytesConsumed(QuicByteCount /*bytes*/) override {}
- void ResetWithError(QuicResetStreamError /*error*/) override {}
- void OnUnrecoverableError(QuicErrorCode error,
- const std::string& details) override;
- void OnUnrecoverableError(QuicErrorCode error,
- QuicIetfTransportErrorCodes ietf_error,
- const std::string& details) override;
- QuicStreamId id() const override { return 0; }
- ParsedQuicVersion version() const override { return framer_->version(); }
-
- private:
- // Parses the length of the CHLO message by looking at the first four bytes.
- // Returns whether we have received enough data to parse the full CHLO now.
- bool MaybeAttemptToParseChloLength();
- // Parses the full CHLO message if enough data has been received.
- void AttemptToParseFullChlo();
- // Moves to the failed state and records the error details.
- void HandleUnrecoverableError(const std::string& error_details);
- // Lazily sets up shared SSL handles if needed.
- static std::pair<SSL_CTX*, int> GetSharedSslHandles();
- // Lazily sets up the per-instance SSL handle if needed.
- void SetupSslHandle();
- // Extract the TlsChloExtractor instance from |ssl|.
- static TlsChloExtractor* GetInstanceFromSSL(SSL* ssl);
-
- // BoringSSL static TLS callbacks.
- static enum ssl_select_cert_result_t SelectCertCallback(
- const SSL_CLIENT_HELLO* client_hello);
- static int SetReadSecretCallback(SSL* ssl,
- enum ssl_encryption_level_t level,
- const SSL_CIPHER* cipher,
- const uint8_t* secret,
- size_t secret_length);
- static int SetWriteSecretCallback(SSL* ssl,
- enum ssl_encryption_level_t level,
- const SSL_CIPHER* cipher,
- const uint8_t* secret,
- size_t secret_length);
- static int WriteMessageCallback(SSL* ssl,
- enum ssl_encryption_level_t level,
- const uint8_t* data,
- size_t len);
- static int FlushFlightCallback(SSL* ssl);
- static int SendAlertCallback(SSL* ssl,
- enum ssl_encryption_level_t level,
- uint8_t desc);
-
- // Called by SelectCertCallback.
- void HandleParsedChlo(const SSL_CLIENT_HELLO* client_hello);
- // Called by callbacks that should never be called.
- void HandleUnexpectedCallback(const std::string& callback_name);
- // Called by SendAlertCallback.
- void SendAlert(uint8_t tls_alert_value);
-
- // Used to parse received packets to extract single frames.
- std::unique_ptr<QuicFramer> framer_;
- // Used to reassemble the crypto stream from received CRYPTO frames.
- QuicStreamSequencer crypto_stream_sequencer_;
- // BoringSSL handle required to parse the CHLO.
- bssl::UniquePtr<SSL> ssl_;
- // State of this TlsChloExtractor.
- State state_;
- // Detail string that can be logged in the presence of unrecoverable errors.
- std::string error_details_;
- // Whether a CRYPTO frame was parsed in this packet.
- bool parsed_crypto_frame_in_this_packet_;
- // Array of ALPNs parsed from the CHLO.
- std::vector<std::string> alpns_;
- // SNI parsed from the CHLO.
- std::string server_name_;
- // Whether resumption is attempted from the CHLO, indicated by the
- // 'pre_shared_key' TLS extension.
- bool resumption_attempted_ = false;
- // Whether early data is attempted from the CHLO, indicated by the
- // 'early_data' TLS extension.
- bool early_data_attempted_ = false;
-};
-
-// Convenience method to facilitate logging TlsChloExtractor::State.
-QUIC_NO_EXPORT std::ostream& operator<<(std::ostream& os,
- const TlsChloExtractor::State& state);
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_TLS_CHLO_EXTRACTOR_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/tls_chlo_extractor_test.cc b/chromium/net/third_party/quiche/src/quic/core/tls_chlo_extractor_test.cc
deleted file mode 100644
index 8a2ce09190f..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/tls_chlo_extractor_test.cc
+++ /dev/null
@@ -1,253 +0,0 @@
-// Copyright (c) 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/tls_chlo_extractor.h"
-
-#include <memory>
-
-#include "third_party/boringssl/src/include/openssl/ssl.h"
-#include "quic/core/http/quic_spdy_client_session.h"
-#include "quic/core/quic_connection.h"
-#include "quic/core/quic_packet_writer_wrapper.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_versions.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/crypto_test_utils.h"
-#include "quic/test_tools/first_flight.h"
-#include "quic/test_tools/quic_test_utils.h"
-#include "quic/test_tools/simple_session_cache.h"
-
-namespace quic {
-namespace test {
-namespace {
-
-using testing::_;
-using testing::AnyNumber;
-
-class TlsChloExtractorTest : public QuicTestWithParam<ParsedQuicVersion> {
- protected:
- TlsChloExtractorTest() : version_(GetParam()), server_id_(TestServerId()) {}
-
- void Initialize() { packets_ = GetFirstFlightOfPackets(version_, config_); }
- void Initialize(std::unique_ptr<QuicCryptoClientConfig> crypto_config) {
- packets_ = GetFirstFlightOfPackets(version_, config_, TestConnectionId(),
- EmptyQuicConnectionId(),
- std::move(crypto_config));
- }
-
- // Perform a full handshake in order to insert a SSL_SESSION into
- // crypto_config->session_cache(), which can be used by a TLS resumption.
- void PerformFullHandshake(QuicCryptoClientConfig* crypto_config) const {
- ASSERT_NE(crypto_config->session_cache(), nullptr);
- MockQuicConnectionHelper client_helper, server_helper;
- MockAlarmFactory alarm_factory;
- ParsedQuicVersionVector supported_versions = {version_};
- PacketSavingConnection* client_connection =
- new PacketSavingConnection(&client_helper, &alarm_factory,
- Perspective::IS_CLIENT, supported_versions);
- // Advance the time, because timers do not like uninitialized times.
- client_connection->AdvanceTime(QuicTime::Delta::FromSeconds(1));
- QuicClientPushPromiseIndex push_promise_index;
- QuicSpdyClientSession client_session(config_, supported_versions,
- client_connection, server_id_,
- crypto_config, &push_promise_index);
- client_session.Initialize();
-
- std::unique_ptr<QuicCryptoServerConfig> server_crypto_config =
- crypto_test_utils::CryptoServerConfigForTesting();
- QuicConfig server_config;
-
- EXPECT_CALL(*client_connection, SendCryptoData(_, _, _)).Times(AnyNumber());
- client_session.GetMutableCryptoStream()->CryptoConnect();
-
- crypto_test_utils::HandshakeWithFakeServer(
- &server_config, server_crypto_config.get(), &server_helper,
- &alarm_factory, client_connection,
- client_session.GetMutableCryptoStream(),
- AlpnForVersion(client_connection->version()));
-
- // For some reason, the test client can not receive the server settings and
- // the SSL_SESSION will not be inserted to client's session_cache. We create
- // a dummy settings and call SetServerApplicationStateForResumption manually
- // to ensure the SSL_SESSION is cached.
- // TODO(wub): Fix crypto_test_utils::HandshakeWithFakeServer to make sure a
- // SSL_SESSION is cached at the client, and remove the rest of the function.
- SettingsFrame server_settings;
- server_settings.values[SETTINGS_QPACK_MAX_TABLE_CAPACITY] =
- kDefaultQpackMaxDynamicTableCapacity;
- std::unique_ptr<char[]> buffer;
- uint64_t length =
- HttpEncoder::SerializeSettingsFrame(server_settings, &buffer);
- client_session.GetMutableCryptoStream()
- ->SetServerApplicationStateForResumption(
- std::make_unique<ApplicationState>(buffer.get(),
- buffer.get() + length));
- }
-
- void IngestPackets() {
- for (const std::unique_ptr<QuicReceivedPacket>& packet : packets_) {
- ReceivedPacketInfo packet_info(
- QuicSocketAddress(TestPeerIPAddress(), kTestPort),
- QuicSocketAddress(TestPeerIPAddress(), kTestPort), *packet);
- std::string detailed_error;
- absl::optional<absl::string_view> retry_token;
- const QuicErrorCode error = QuicFramer::ParsePublicHeaderDispatcher(
- *packet, /*expected_destination_connection_id_length=*/0,
- &packet_info.form, &packet_info.long_packet_type,
- &packet_info.version_flag, &packet_info.use_length_prefix,
- &packet_info.version_label, &packet_info.version,
- &packet_info.destination_connection_id,
- &packet_info.source_connection_id, &retry_token, &detailed_error);
- ASSERT_THAT(error, IsQuicNoError()) << detailed_error;
- tls_chlo_extractor_.IngestPacket(packet_info.version, packet_info.packet);
- }
- packets_.clear();
- }
-
- void ValidateChloDetails() {
- EXPECT_TRUE(tls_chlo_extractor_.HasParsedFullChlo());
- std::vector<std::string> alpns = tls_chlo_extractor_.alpns();
- ASSERT_EQ(alpns.size(), 1u);
- EXPECT_EQ(alpns[0], AlpnForVersion(version_));
- EXPECT_EQ(tls_chlo_extractor_.server_name(), TestHostname());
- }
-
- void IncreaseSizeOfChlo() {
- // Add a 2000-byte custom parameter to increase the length of the CHLO.
- constexpr auto kCustomParameterId =
- static_cast<TransportParameters::TransportParameterId>(0xff33);
- std::string kCustomParameterValue(2000, '-');
- config_.custom_transport_parameters_to_send()[kCustomParameterId] =
- kCustomParameterValue;
- }
-
- ParsedQuicVersion version_;
- QuicServerId server_id_;
- TlsChloExtractor tls_chlo_extractor_;
- QuicConfig config_;
- std::vector<std::unique_ptr<QuicReceivedPacket>> packets_;
-};
-
-INSTANTIATE_TEST_SUITE_P(TlsChloExtractorTests,
- TlsChloExtractorTest,
- ::testing::ValuesIn(AllSupportedVersionsWithTls()),
- ::testing::PrintToStringParamName());
-
-TEST_P(TlsChloExtractorTest, Simple) {
- Initialize();
- EXPECT_EQ(packets_.size(), 1u);
- IngestPackets();
- ValidateChloDetails();
- EXPECT_EQ(tls_chlo_extractor_.state(),
- TlsChloExtractor::State::kParsedFullSinglePacketChlo);
- EXPECT_FALSE(tls_chlo_extractor_.resumption_attempted());
- EXPECT_FALSE(tls_chlo_extractor_.early_data_attempted());
-}
-
-TEST_P(TlsChloExtractorTest, TlsExtentionInfo_ResumptionOnly) {
- auto crypto_client_config = std::make_unique<QuicCryptoClientConfig>(
- crypto_test_utils::ProofVerifierForTesting(),
- std::make_unique<SimpleSessionCache>());
- PerformFullHandshake(crypto_client_config.get());
-
- SSL_CTX_set_early_data_enabled(crypto_client_config->ssl_ctx(), 0);
- Initialize(std::move(crypto_client_config));
- EXPECT_GE(packets_.size(), 1u);
- IngestPackets();
- ValidateChloDetails();
- EXPECT_EQ(tls_chlo_extractor_.state(),
- TlsChloExtractor::State::kParsedFullSinglePacketChlo);
- EXPECT_TRUE(tls_chlo_extractor_.resumption_attempted());
- EXPECT_FALSE(tls_chlo_extractor_.early_data_attempted());
-}
-
-TEST_P(TlsChloExtractorTest, TlsExtentionInfo_ZeroRtt) {
- auto crypto_client_config = std::make_unique<QuicCryptoClientConfig>(
- crypto_test_utils::ProofVerifierForTesting(),
- std::make_unique<SimpleSessionCache>());
- PerformFullHandshake(crypto_client_config.get());
-
- IncreaseSizeOfChlo();
- Initialize(std::move(crypto_client_config));
- EXPECT_GE(packets_.size(), 1u);
- IngestPackets();
- ValidateChloDetails();
- EXPECT_EQ(tls_chlo_extractor_.state(),
- TlsChloExtractor::State::kParsedFullMultiPacketChlo);
- EXPECT_TRUE(tls_chlo_extractor_.resumption_attempted());
- EXPECT_TRUE(tls_chlo_extractor_.early_data_attempted());
-}
-
-TEST_P(TlsChloExtractorTest, MultiPacket) {
- IncreaseSizeOfChlo();
- Initialize();
- EXPECT_EQ(packets_.size(), 2u);
- IngestPackets();
- ValidateChloDetails();
- EXPECT_EQ(tls_chlo_extractor_.state(),
- TlsChloExtractor::State::kParsedFullMultiPacketChlo);
-}
-
-TEST_P(TlsChloExtractorTest, MultiPacketReordered) {
- IncreaseSizeOfChlo();
- Initialize();
- ASSERT_EQ(packets_.size(), 2u);
- // Artifically reorder both packets.
- std::swap(packets_[0], packets_[1]);
- IngestPackets();
- ValidateChloDetails();
- EXPECT_EQ(tls_chlo_extractor_.state(),
- TlsChloExtractor::State::kParsedFullMultiPacketChlo);
-}
-
-TEST_P(TlsChloExtractorTest, MoveAssignment) {
- Initialize();
- EXPECT_EQ(packets_.size(), 1u);
- TlsChloExtractor other_extractor;
- tls_chlo_extractor_ = std::move(other_extractor);
- IngestPackets();
- ValidateChloDetails();
- EXPECT_EQ(tls_chlo_extractor_.state(),
- TlsChloExtractor::State::kParsedFullSinglePacketChlo);
-}
-
-TEST_P(TlsChloExtractorTest, MoveAssignmentBetweenPackets) {
- IncreaseSizeOfChlo();
- Initialize();
- ASSERT_EQ(packets_.size(), 2u);
- TlsChloExtractor other_extractor;
-
- // Have |other_extractor| parse the first packet.
- ReceivedPacketInfo packet_info(
- QuicSocketAddress(TestPeerIPAddress(), kTestPort),
- QuicSocketAddress(TestPeerIPAddress(), kTestPort), *packets_[0]);
- std::string detailed_error;
- absl::optional<absl::string_view> retry_token;
- const QuicErrorCode error = QuicFramer::ParsePublicHeaderDispatcher(
- *packets_[0], /*expected_destination_connection_id_length=*/0,
- &packet_info.form, &packet_info.long_packet_type,
- &packet_info.version_flag, &packet_info.use_length_prefix,
- &packet_info.version_label, &packet_info.version,
- &packet_info.destination_connection_id, &packet_info.source_connection_id,
- &retry_token, &detailed_error);
- ASSERT_THAT(error, IsQuicNoError()) << detailed_error;
- other_extractor.IngestPacket(packet_info.version, packet_info.packet);
- // Remove the first packet from the list.
- packets_.erase(packets_.begin());
- EXPECT_EQ(packets_.size(), 1u);
-
- // Move the extractor.
- tls_chlo_extractor_ = std::move(other_extractor);
-
- // Have |tls_chlo_extractor_| parse the second packet.
- IngestPackets();
-
- ValidateChloDetails();
- EXPECT_EQ(tls_chlo_extractor_.state(),
- TlsChloExtractor::State::kParsedFullMultiPacketChlo);
-}
-
-} // namespace
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/tls_client_handshaker.cc b/chromium/net/third_party/quiche/src/quic/core/tls_client_handshaker.cc
deleted file mode 100644
index 3cd47ad04c4..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/tls_client_handshaker.cc
+++ /dev/null
@@ -1,664 +0,0 @@
-// Copyright (c) 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/tls_client_handshaker.h"
-
-#include <cstring>
-#include <string>
-
-#include "absl/strings/str_cat.h"
-#include "absl/strings/string_view.h"
-#include "third_party/boringssl/src/include/openssl/ssl.h"
-#include "quic/core/crypto/quic_crypto_client_config.h"
-#include "quic/core/crypto/quic_encrypter.h"
-#include "quic/core/crypto/transport_parameters.h"
-#include "quic/core/quic_session.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_hostname_utils.h"
-#include "common/quiche_text_utils.h"
-
-namespace quic {
-
-TlsClientHandshaker::TlsClientHandshaker(
- const QuicServerId& server_id,
- QuicCryptoStream* stream,
- QuicSession* session,
- std::unique_ptr<ProofVerifyContext> verify_context,
- QuicCryptoClientConfig* crypto_config,
- QuicCryptoClientStream::ProofHandler* proof_handler,
- bool has_application_state)
- : TlsHandshaker(stream, session),
- session_(session),
- server_id_(server_id),
- proof_verifier_(crypto_config->proof_verifier()),
- verify_context_(std::move(verify_context)),
- proof_handler_(proof_handler),
- session_cache_(crypto_config->session_cache()),
- user_agent_id_(crypto_config->user_agent_id()),
- pre_shared_key_(crypto_config->pre_shared_key()),
- crypto_negotiated_params_(new QuicCryptoNegotiatedParameters),
- has_application_state_(has_application_state),
- crypto_config_(crypto_config),
- tls_connection_(crypto_config->ssl_ctx(), this, session->GetSSLConfig()) {
- if (!GetQuicReloadableFlag(quic_tls_use_token_in_session_cache)) {
- std::string token =
- crypto_config->LookupOrCreate(server_id)->source_address_token();
- if (!token.empty()) {
- session->SetSourceAddressTokenToSend(token);
- }
- }
- if (crypto_config->tls_signature_algorithms().has_value()) {
- SSL_set1_sigalgs_list(ssl(),
- crypto_config->tls_signature_algorithms()->c_str());
- }
- if (crypto_config->proof_source() != nullptr) {
- const ClientProofSource::CertAndKey* cert_and_key =
- crypto_config->proof_source()->GetCertAndKey(server_id.host());
- if (cert_and_key != nullptr) {
- QUIC_DVLOG(1) << "Setting client cert and key for " << server_id.host();
- tls_connection_.SetCertChain(cert_and_key->chain->ToCryptoBuffers().value,
- cert_and_key->private_key.private_key());
- }
- }
-}
-
-TlsClientHandshaker::~TlsClientHandshaker() {}
-
-bool TlsClientHandshaker::CryptoConnect() {
- if (!pre_shared_key_.empty()) {
- // TODO(b/154162689) add PSK support to QUIC+TLS.
- std::string error_details =
- "QUIC client pre-shared keys not yet supported with TLS";
- QUIC_BUG(quic_bug_10576_1) << error_details;
- CloseConnection(QUIC_HANDSHAKE_FAILED, error_details);
- return false;
- }
-
- // Make sure we use the right TLS extension codepoint.
- int use_legacy_extension = 0;
- if (session()->version().UsesLegacyTlsExtension()) {
- use_legacy_extension = 1;
- }
- SSL_set_quic_use_legacy_codepoint(ssl(), use_legacy_extension);
-
- // TODO(b/193650832) Add SetFromConfig to QUIC handshakers and remove reliance
- // on session pointer.
- const bool permutes_tls_extensions = session()->permutes_tls_extensions();
- if (!permutes_tls_extensions) {
- QUIC_DLOG(INFO) << "Disabling TLS extension permutation";
- }
-#if BORINGSSL_API_VERSION >= 16
- // Ask BoringSSL to randomize the order of TLS extensions.
- SSL_set_permute_extensions(ssl(), permutes_tls_extensions);
-#endif // BORINGSSL_API_VERSION
-
- // Set the SNI to send, if any.
- SSL_set_connect_state(ssl());
- if (QUIC_DLOG_INFO_IS_ON() &&
- !QuicHostnameUtils::IsValidSNI(server_id_.host())) {
- QUIC_DLOG(INFO) << "Client configured with invalid hostname \""
- << server_id_.host() << "\", not sending as SNI";
- }
- if (!server_id_.host().empty() &&
- (QuicHostnameUtils::IsValidSNI(server_id_.host()) ||
- allow_invalid_sni_for_tests_) &&
- SSL_set_tlsext_host_name(ssl(), server_id_.host().c_str()) != 1) {
- return false;
- }
-
- if (!SetAlpn()) {
- CloseConnection(QUIC_HANDSHAKE_FAILED, "Client failed to set ALPN");
- return false;
- }
-
- // Set the Transport Parameters to send in the ClientHello
- if (!SetTransportParameters()) {
- CloseConnection(QUIC_HANDSHAKE_FAILED,
- "Client failed to set Transport Parameters");
- return false;
- }
-
- // Set a session to resume, if there is one.
- if (session_cache_) {
- cached_state_ = session_cache_->Lookup(
- server_id_, session()->GetClock()->WallNow(), SSL_get_SSL_CTX(ssl()));
- }
- if (cached_state_) {
- SSL_set_session(ssl(), cached_state_->tls_session.get());
- if (GetQuicReloadableFlag(quic_tls_use_token_in_session_cache) &&
- !cached_state_->token.empty()) {
- session()->SetSourceAddressTokenToSend(cached_state_->token);
- }
- }
-
- // Start the handshake.
- AdvanceHandshake();
- return session()->connection()->connected();
-}
-
-bool TlsClientHandshaker::PrepareZeroRttConfig(
- QuicResumptionState* cached_state) {
- std::string error_details;
- if (!cached_state->transport_params ||
- handshaker_delegate()->ProcessTransportParameters(
- *(cached_state->transport_params),
- /*is_resumption = */ true, &error_details) != QUIC_NO_ERROR) {
- QUIC_BUG(quic_bug_10576_2)
- << "Unable to parse cached transport parameters.";
- CloseConnection(QUIC_HANDSHAKE_FAILED,
- "Client failed to parse cached Transport Parameters.");
- return false;
- }
-
- session()->connection()->OnTransportParametersResumed(
- *(cached_state->transport_params));
- session()->OnConfigNegotiated();
-
- if (has_application_state_) {
- if (!cached_state->application_state ||
- !session()->ResumeApplicationState(
- cached_state->application_state.get())) {
- QUIC_BUG(quic_bug_10576_3) << "Unable to parse cached application state.";
- CloseConnection(QUIC_HANDSHAKE_FAILED,
- "Client failed to parse cached application state.");
- return false;
- }
- }
- return true;
-}
-
-static bool IsValidAlpn(const std::string& alpn_string) {
- return alpn_string.length() <= std::numeric_limits<uint8_t>::max();
-}
-
-bool TlsClientHandshaker::SetAlpn() {
- std::vector<std::string> alpns = session()->GetAlpnsToOffer();
- if (alpns.empty()) {
- if (allow_empty_alpn_for_tests_) {
- return true;
- }
-
- QUIC_BUG(quic_bug_10576_4) << "ALPN missing";
- return false;
- }
- if (!std::all_of(alpns.begin(), alpns.end(), IsValidAlpn)) {
- QUIC_BUG(quic_bug_10576_5) << "ALPN too long";
- return false;
- }
-
- // SSL_set_alpn_protos expects a sequence of one-byte-length-prefixed
- // strings.
- uint8_t alpn[1024];
- QuicDataWriter alpn_writer(sizeof(alpn), reinterpret_cast<char*>(alpn));
- bool success = true;
- for (const std::string& alpn_string : alpns) {
- success = success && alpn_writer.WriteUInt8(alpn_string.size()) &&
- alpn_writer.WriteStringPiece(alpn_string);
- }
- success =
- success && (SSL_set_alpn_protos(ssl(), alpn, alpn_writer.length()) == 0);
- if (!success) {
- QUIC_BUG(quic_bug_10576_6)
- << "Failed to set ALPN: "
- << quiche::QuicheTextUtils::HexDump(
- absl::string_view(alpn_writer.data(), alpn_writer.length()));
- return false;
- }
-
- // Enable ALPS only for versions that use HTTP/3 frames.
- for (const std::string& alpn_string : alpns) {
- for (const ParsedQuicVersion& version : session()->supported_versions()) {
- if (!version.UsesHttp3() || AlpnForVersion(version) != alpn_string) {
- continue;
- }
- if (SSL_add_application_settings(
- ssl(), reinterpret_cast<const uint8_t*>(alpn_string.data()),
- alpn_string.size(), nullptr, /* settings_len = */ 0) != 1) {
- QUIC_BUG(quic_bug_10576_7) << "Failed to enable ALPS.";
- return false;
- }
- break;
- }
- }
-
- QUIC_DLOG(INFO) << "Client using ALPN: '" << alpns[0] << "'";
- return true;
-}
-
-bool TlsClientHandshaker::SetTransportParameters() {
- TransportParameters params;
- params.perspective = Perspective::IS_CLIENT;
- params.legacy_version_information =
- TransportParameters::LegacyVersionInformation();
- params.legacy_version_information.value().version =
- CreateQuicVersionLabel(session()->supported_versions().front());
- params.version_information = TransportParameters::VersionInformation();
- const QuicVersionLabel version = CreateQuicVersionLabel(session()->version());
- params.version_information.value().chosen_version = version;
- params.version_information.value().other_versions.push_back(version);
-
- if (!handshaker_delegate()->FillTransportParameters(&params)) {
- return false;
- }
-
- // Notify QuicConnectionDebugVisitor.
- session()->connection()->OnTransportParametersSent(params);
-
- std::vector<uint8_t> param_bytes;
- return SerializeTransportParameters(session()->connection()->version(),
- params, &param_bytes) &&
- SSL_set_quic_transport_params(ssl(), param_bytes.data(),
- param_bytes.size()) == 1;
-}
-
-bool TlsClientHandshaker::ProcessTransportParameters(
- std::string* error_details) {
- received_transport_params_ = std::make_unique<TransportParameters>();
- const uint8_t* param_bytes;
- size_t param_bytes_len;
- SSL_get_peer_quic_transport_params(ssl(), &param_bytes, &param_bytes_len);
- if (param_bytes_len == 0) {
- *error_details = "Server's transport parameters are missing";
- return false;
- }
- std::string parse_error_details;
- if (!ParseTransportParameters(
- session()->connection()->version(), Perspective::IS_SERVER,
- param_bytes, param_bytes_len, received_transport_params_.get(),
- &parse_error_details)) {
- QUICHE_DCHECK(!parse_error_details.empty());
- *error_details =
- "Unable to parse server's transport parameters: " + parse_error_details;
- return false;
- }
-
- // Notify QuicConnectionDebugVisitor.
- session()->connection()->OnTransportParametersReceived(
- *received_transport_params_);
-
- if (received_transport_params_->legacy_version_information.has_value()) {
- if (received_transport_params_->legacy_version_information.value()
- .version !=
- CreateQuicVersionLabel(session()->connection()->version())) {
- *error_details = "Version mismatch detected";
- return false;
- }
- if (CryptoUtils::ValidateServerHelloVersions(
- received_transport_params_->legacy_version_information.value()
- .supported_versions,
- session()->connection()->server_supported_versions(),
- error_details) != QUIC_NO_ERROR) {
- QUICHE_DCHECK(!error_details->empty());
- return false;
- }
- }
- if (received_transport_params_->version_information.has_value()) {
- if (!CryptoUtils::ValidateChosenVersion(
- received_transport_params_->version_information.value()
- .chosen_version,
- session()->version(), error_details)) {
- QUICHE_DCHECK(!error_details->empty());
- return false;
- }
- if (!CryptoUtils::CryptoUtils::ValidateServerVersions(
- received_transport_params_->version_information.value()
- .other_versions,
- session()->version(),
- session()->client_original_supported_versions(), error_details)) {
- QUICHE_DCHECK(!error_details->empty());
- return false;
- }
- }
-
- if (handshaker_delegate()->ProcessTransportParameters(
- *received_transport_params_, /* is_resumption = */ false,
- error_details) != QUIC_NO_ERROR) {
- QUICHE_DCHECK(!error_details->empty());
- return false;
- }
-
- session()->OnConfigNegotiated();
- if (is_connection_closed()) {
- *error_details =
- "Session closed the connection when parsing negotiated config.";
- return false;
- }
- return true;
-}
-
-int TlsClientHandshaker::num_sent_client_hellos() const {
- return 0;
-}
-
-bool TlsClientHandshaker::IsResumption() const {
- QUIC_BUG_IF(quic_bug_12736_1, !one_rtt_keys_available());
- return SSL_session_reused(ssl()) == 1;
-}
-
-bool TlsClientHandshaker::EarlyDataAccepted() const {
- QUIC_BUG_IF(quic_bug_12736_2, !one_rtt_keys_available());
- return SSL_early_data_accepted(ssl()) == 1;
-}
-
-ssl_early_data_reason_t TlsClientHandshaker::EarlyDataReason() const {
- return TlsHandshaker::EarlyDataReason();
-}
-
-bool TlsClientHandshaker::ReceivedInchoateReject() const {
- QUIC_BUG_IF(quic_bug_12736_3, !one_rtt_keys_available());
- // REJ messages are a QUIC crypto feature, so TLS always returns false.
- return false;
-}
-
-int TlsClientHandshaker::num_scup_messages_received() const {
- // SCUP messages aren't sent or received when using the TLS handshake.
- return 0;
-}
-
-std::string TlsClientHandshaker::chlo_hash() const {
- return "";
-}
-
-bool TlsClientHandshaker::ExportKeyingMaterial(absl::string_view label,
- absl::string_view context,
- size_t result_len,
- std::string* result) {
- return ExportKeyingMaterialForLabel(label, context, result_len, result);
-}
-
-bool TlsClientHandshaker::encryption_established() const {
- return encryption_established_;
-}
-
-bool TlsClientHandshaker::one_rtt_keys_available() const {
- return state_ >= HANDSHAKE_COMPLETE;
-}
-
-const QuicCryptoNegotiatedParameters&
-TlsClientHandshaker::crypto_negotiated_params() const {
- return *crypto_negotiated_params_;
-}
-
-CryptoMessageParser* TlsClientHandshaker::crypto_message_parser() {
- return TlsHandshaker::crypto_message_parser();
-}
-
-HandshakeState TlsClientHandshaker::GetHandshakeState() const {
- return state_;
-}
-
-size_t TlsClientHandshaker::BufferSizeLimitForLevel(
- EncryptionLevel level) const {
- return TlsHandshaker::BufferSizeLimitForLevel(level);
-}
-
-std::unique_ptr<QuicDecrypter>
-TlsClientHandshaker::AdvanceKeysAndCreateCurrentOneRttDecrypter() {
- return TlsHandshaker::AdvanceKeysAndCreateCurrentOneRttDecrypter();
-}
-
-std::unique_ptr<QuicEncrypter>
-TlsClientHandshaker::CreateCurrentOneRttEncrypter() {
- return TlsHandshaker::CreateCurrentOneRttEncrypter();
-}
-
-void TlsClientHandshaker::OnOneRttPacketAcknowledged() {
- OnHandshakeConfirmed();
-}
-
-void TlsClientHandshaker::OnHandshakePacketSent() {
- if (initial_keys_dropped_) {
- return;
- }
- initial_keys_dropped_ = true;
- handshaker_delegate()->DiscardOldEncryptionKey(ENCRYPTION_INITIAL);
- handshaker_delegate()->DiscardOldDecryptionKey(ENCRYPTION_INITIAL);
-}
-
-void TlsClientHandshaker::OnConnectionClosed(QuicErrorCode error,
- ConnectionCloseSource source) {
- TlsHandshaker::OnConnectionClosed(error, source);
-}
-
-void TlsClientHandshaker::OnHandshakeDoneReceived() {
- if (!one_rtt_keys_available()) {
- CloseConnection(QUIC_HANDSHAKE_FAILED,
- "Unexpected handshake done received");
- return;
- }
- OnHandshakeConfirmed();
-}
-
-void TlsClientHandshaker::OnNewTokenReceived(absl::string_view token) {
- if (token.empty()) {
- return;
- }
- if (GetQuicReloadableFlag(quic_tls_use_token_in_session_cache)) {
- if (session_cache_ != nullptr) {
- session_cache_->OnNewTokenReceived(server_id_, token);
- }
- } else {
- QuicCryptoClientConfig::CachedState* cached =
- crypto_config_->LookupOrCreate(server_id_);
- cached->set_source_address_token(token);
- }
-}
-
-void TlsClientHandshaker::SetWriteSecret(
- EncryptionLevel level,
- const SSL_CIPHER* cipher,
- const std::vector<uint8_t>& write_secret) {
- if (is_connection_closed()) {
- return;
- }
- if (level == ENCRYPTION_FORWARD_SECURE || level == ENCRYPTION_ZERO_RTT) {
- encryption_established_ = true;
- }
- TlsHandshaker::SetWriteSecret(level, cipher, write_secret);
- if (level == ENCRYPTION_FORWARD_SECURE) {
- handshaker_delegate()->DiscardOldEncryptionKey(ENCRYPTION_ZERO_RTT);
- }
-}
-
-void TlsClientHandshaker::OnHandshakeConfirmed() {
- QUICHE_DCHECK(one_rtt_keys_available());
- if (state_ >= HANDSHAKE_CONFIRMED) {
- return;
- }
- state_ = HANDSHAKE_CONFIRMED;
- handshaker_delegate()->DiscardOldEncryptionKey(ENCRYPTION_HANDSHAKE);
- handshaker_delegate()->DiscardOldDecryptionKey(ENCRYPTION_HANDSHAKE);
-}
-
-QuicAsyncStatus TlsClientHandshaker::VerifyCertChain(
- const std::vector<std::string>& certs,
- std::string* error_details,
- std::unique_ptr<ProofVerifyDetails>* details,
- uint8_t* out_alert,
- std::unique_ptr<ProofVerifierCallback> callback) {
- const uint8_t* ocsp_response_raw;
- size_t ocsp_response_len;
- SSL_get0_ocsp_response(ssl(), &ocsp_response_raw, &ocsp_response_len);
- std::string ocsp_response(reinterpret_cast<const char*>(ocsp_response_raw),
- ocsp_response_len);
- const uint8_t* sct_list_raw;
- size_t sct_list_len;
- SSL_get0_signed_cert_timestamp_list(ssl(), &sct_list_raw, &sct_list_len);
- std::string sct_list(reinterpret_cast<const char*>(sct_list_raw),
- sct_list_len);
-
- return proof_verifier_->VerifyCertChain(
- server_id_.host(), server_id_.port(), certs, ocsp_response, sct_list,
- verify_context_.get(), error_details, details, out_alert,
- std::move(callback));
-}
-
-void TlsClientHandshaker::OnProofVerifyDetailsAvailable(
- const ProofVerifyDetails& verify_details) {
- proof_handler_->OnProofVerifyDetailsAvailable(verify_details);
-}
-
-void TlsClientHandshaker::FinishHandshake() {
- FillNegotiatedParams();
-
- QUICHE_CHECK(!SSL_in_early_data(ssl()));
-
- QUIC_LOG(INFO) << "Client: handshake finished";
-
- std::string error_details;
- if (!ProcessTransportParameters(&error_details)) {
- QUICHE_DCHECK(!error_details.empty());
- CloseConnection(QUIC_HANDSHAKE_FAILED, error_details);
- return;
- }
-
- const uint8_t* alpn_data = nullptr;
- unsigned alpn_length = 0;
- SSL_get0_alpn_selected(ssl(), &alpn_data, &alpn_length);
-
- if (alpn_length == 0) {
- QUIC_DLOG(ERROR) << "Client: server did not select ALPN";
- // TODO(b/130164908) this should send no_application_protocol
- // instead of QUIC_HANDSHAKE_FAILED.
- CloseConnection(QUIC_HANDSHAKE_FAILED, "Server did not select ALPN");
- return;
- }
-
- std::string received_alpn_string(reinterpret_cast<const char*>(alpn_data),
- alpn_length);
- std::vector<std::string> offered_alpns = session()->GetAlpnsToOffer();
- if (std::find(offered_alpns.begin(), offered_alpns.end(),
- received_alpn_string) == offered_alpns.end()) {
- QUIC_LOG(ERROR) << "Client: received mismatched ALPN '"
- << received_alpn_string;
- // TODO(b/130164908) this should send no_application_protocol
- // instead of QUIC_HANDSHAKE_FAILED.
- CloseConnection(QUIC_HANDSHAKE_FAILED, "Client received mismatched ALPN");
- return;
- }
- session()->OnAlpnSelected(received_alpn_string);
- QUIC_DLOG(INFO) << "Client: server selected ALPN: '" << received_alpn_string
- << "'";
-
- // Parse ALPS extension.
- const uint8_t* alps_data;
- size_t alps_length;
- SSL_get0_peer_application_settings(ssl(), &alps_data, &alps_length);
- if (alps_length > 0) {
- auto error = session()->OnAlpsData(alps_data, alps_length);
- if (error) {
- // Calling CloseConnection() is safe even in case OnAlpsData() has
- // already closed the connection.
- CloseConnection(
- QUIC_HANDSHAKE_FAILED,
- absl::StrCat("Error processing ALPS data: ", error.value()));
- return;
- }
- }
-
- state_ = HANDSHAKE_COMPLETE;
- handshaker_delegate()->OnTlsHandshakeComplete();
-}
-
-void TlsClientHandshaker::OnEnterEarlyData() {
- QUICHE_DCHECK(SSL_in_early_data(ssl()));
-
- // TODO(wub): It might be unnecessary to FillNegotiatedParams() at this time,
- // because we fill it again when handshake completes.
- FillNegotiatedParams();
-
- // If we're attempting a 0-RTT handshake, then we need to let the transport
- // and application know what state to apply to early data.
- PrepareZeroRttConfig(cached_state_.get());
-}
-
-void TlsClientHandshaker::FillNegotiatedParams() {
- const SSL_CIPHER* cipher = SSL_get_current_cipher(ssl());
- if (cipher) {
- crypto_negotiated_params_->cipher_suite =
- SSL_CIPHER_get_protocol_id(cipher);
- }
- crypto_negotiated_params_->key_exchange_group = SSL_get_curve_id(ssl());
- crypto_negotiated_params_->peer_signature_algorithm =
- SSL_get_peer_signature_algorithm(ssl());
-}
-
-void TlsClientHandshaker::ProcessPostHandshakeMessage() {
- int rv = SSL_process_quic_post_handshake(ssl());
- if (rv != 1) {
- CloseConnection(QUIC_HANDSHAKE_FAILED, "Unexpected post-handshake data");
- }
-}
-
-bool TlsClientHandshaker::ShouldCloseConnectionOnUnexpectedError(
- int ssl_error) {
- if (ssl_error != SSL_ERROR_EARLY_DATA_REJECTED) {
- return true;
- }
- HandleZeroRttReject();
- return false;
-}
-
-void TlsClientHandshaker::HandleZeroRttReject() {
- QUIC_LOG(INFO) << "0-RTT handshake attempted but was rejected by the server";
- QUICHE_DCHECK(session_cache_);
- // Disable encrytion to block outgoing data until 1-RTT keys are available.
- encryption_established_ = false;
- handshaker_delegate()->OnZeroRttRejected(EarlyDataReason());
- SSL_reset_early_data_reject(ssl());
- session_cache_->ClearEarlyData(server_id_);
- AdvanceHandshake();
-}
-
-void TlsClientHandshaker::InsertSession(bssl::UniquePtr<SSL_SESSION> session) {
- if (!received_transport_params_) {
- QUIC_BUG(quic_bug_10576_8) << "Transport parameters isn't received";
- return;
- }
- if (session_cache_ == nullptr) {
- QUIC_DVLOG(1) << "No session cache, not inserting a session";
- return;
- }
- if (has_application_state_ && !received_application_state_) {
- // Application state is not received yet. cache the sessions.
- if (cached_tls_sessions_[0] != nullptr) {
- cached_tls_sessions_[1] = std::move(cached_tls_sessions_[0]);
- }
- cached_tls_sessions_[0] = std::move(session);
- return;
- }
- session_cache_->Insert(server_id_, std::move(session),
- *received_transport_params_,
- received_application_state_.get());
-}
-
-void TlsClientHandshaker::WriteMessage(EncryptionLevel level,
- absl::string_view data) {
- if (level == ENCRYPTION_HANDSHAKE && state_ < HANDSHAKE_PROCESSED) {
- state_ = HANDSHAKE_PROCESSED;
- }
- TlsHandshaker::WriteMessage(level, data);
-}
-
-void TlsClientHandshaker::SetServerApplicationStateForResumption(
- std::unique_ptr<ApplicationState> application_state) {
- QUICHE_DCHECK(one_rtt_keys_available());
- received_application_state_ = std::move(application_state);
- // At least one tls session is cached before application state is received. So
- // insert now.
- if (session_cache_ != nullptr && cached_tls_sessions_[0] != nullptr) {
- if (cached_tls_sessions_[1] != nullptr) {
- // Insert the older session first.
- session_cache_->Insert(server_id_, std::move(cached_tls_sessions_[1]),
- *received_transport_params_,
- received_application_state_.get());
- }
- session_cache_->Insert(server_id_, std::move(cached_tls_sessions_[0]),
- *received_transport_params_,
- received_application_state_.get());
- }
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/tls_client_handshaker.h b/chromium/net/third_party/quiche/src/quic/core/tls_client_handshaker.h
deleted file mode 100644
index c7db0edd36d..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/tls_client_handshaker.h
+++ /dev/null
@@ -1,177 +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_CORE_TLS_CLIENT_HANDSHAKER_H_
-#define QUICHE_QUIC_CORE_TLS_CLIENT_HANDSHAKER_H_
-
-#include <cstdint>
-#include <memory>
-#include <string>
-
-#include "absl/strings/string_view.h"
-#include "third_party/boringssl/src/include/openssl/ssl.h"
-#include "quic/core/crypto/quic_crypto_client_config.h"
-#include "quic/core/crypto/tls_client_connection.h"
-#include "quic/core/crypto/transport_parameters.h"
-#include "quic/core/quic_crypto_client_stream.h"
-#include "quic/core/quic_crypto_stream.h"
-#include "quic/core/tls_handshaker.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// An implementation of QuicCryptoClientStream::HandshakerInterface which uses
-// TLS 1.3 for the crypto handshake protocol.
-class QUIC_EXPORT_PRIVATE TlsClientHandshaker
- : public TlsHandshaker,
- public QuicCryptoClientStream::HandshakerInterface,
- public TlsClientConnection::Delegate {
- public:
- // |crypto_config| must outlive TlsClientHandshaker.
- TlsClientHandshaker(const QuicServerId& server_id,
- QuicCryptoStream* stream,
- QuicSession* session,
- std::unique_ptr<ProofVerifyContext> verify_context,
- QuicCryptoClientConfig* crypto_config,
- QuicCryptoClientStream::ProofHandler* proof_handler,
- bool has_application_state);
- TlsClientHandshaker(const TlsClientHandshaker&) = delete;
- TlsClientHandshaker& operator=(const TlsClientHandshaker&) = delete;
-
- ~TlsClientHandshaker() override;
-
- // From QuicCryptoClientStream::HandshakerInterface
- bool CryptoConnect() override;
- int num_sent_client_hellos() const override;
- bool IsResumption() const override;
- bool EarlyDataAccepted() const override;
- ssl_early_data_reason_t EarlyDataReason() const override;
- bool ReceivedInchoateReject() const override;
- int num_scup_messages_received() const override;
- std::string chlo_hash() const override;
- bool ExportKeyingMaterial(absl::string_view label, absl::string_view context,
- size_t result_len, std::string* result) override;
-
- // From QuicCryptoClientStream::HandshakerInterface and TlsHandshaker
- bool encryption_established() const override;
- bool one_rtt_keys_available() const override;
- const QuicCryptoNegotiatedParameters& crypto_negotiated_params()
- const override;
- CryptoMessageParser* crypto_message_parser() override;
- HandshakeState GetHandshakeState() const override;
- size_t BufferSizeLimitForLevel(EncryptionLevel level) const override;
- std::unique_ptr<QuicDecrypter> AdvanceKeysAndCreateCurrentOneRttDecrypter()
- override;
- std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() override;
- void OnOneRttPacketAcknowledged() override;
- void OnHandshakePacketSent() override;
- void OnConnectionClosed(QuicErrorCode error,
- ConnectionCloseSource source) override;
- 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;
-
- // Override to drop initial keys if trying to write ENCRYPTION_HANDSHAKE data.
- void WriteMessage(EncryptionLevel level, absl::string_view data) override;
-
- void SetServerApplicationStateForResumption(
- std::unique_ptr<ApplicationState> application_state) override;
-
- void AllowEmptyAlpnForTests() { allow_empty_alpn_for_tests_ = true; }
- void AllowInvalidSNIForTests() { allow_invalid_sni_for_tests_ = true; }
-
- // Make the SSL object from BoringSSL publicly accessible.
- using TlsHandshaker::ssl;
-
- protected:
- const TlsConnection* tls_connection() const override {
- return &tls_connection_;
- }
-
- void FinishHandshake() override;
- void OnEnterEarlyData() override;
- void FillNegotiatedParams();
- void ProcessPostHandshakeMessage() override;
- bool ShouldCloseConnectionOnUnexpectedError(int ssl_error) override;
- QuicAsyncStatus VerifyCertChain(
- const std::vector<std::string>& certs,
- std::string* error_details,
- std::unique_ptr<ProofVerifyDetails>* details,
- uint8_t* out_alert,
- std::unique_ptr<ProofVerifierCallback> callback) override;
- void OnProofVerifyDetailsAvailable(
- const ProofVerifyDetails& verify_details) override;
-
- // TlsClientConnection::Delegate implementation:
- TlsConnection::Delegate* ConnectionDelegate() override { return this; }
-
- private:
- bool SetAlpn();
- bool SetTransportParameters();
- bool ProcessTransportParameters(std::string* error_details);
- void HandleZeroRttReject();
-
- // Called when server completes handshake (i.e., either handshake done is
- // received or 1-RTT packet gets acknowledged).
- void OnHandshakeConfirmed();
-
- void InsertSession(bssl::UniquePtr<SSL_SESSION> session) override;
-
- bool PrepareZeroRttConfig(QuicResumptionState* cached_state);
-
- QuicSession* session() { return session_; }
- QuicSession* session_;
-
- QuicServerId server_id_;
-
- // Objects used for verifying the server's certificate chain.
- // |proof_verifier_| is owned by the caller of TlsHandshaker's constructor.
- ProofVerifier* proof_verifier_;
- std::unique_ptr<ProofVerifyContext> verify_context_;
-
- // Unowned pointer to the proof handler which has the
- // OnProofVerifyDetailsAvailable callback to use for notifying the result of
- // certificate verification.
- QuicCryptoClientStream::ProofHandler* proof_handler_;
-
- // Used for session resumption. |session_cache_| is owned by the
- // QuicCryptoClientConfig passed into TlsClientHandshaker's constructor.
- SessionCache* session_cache_;
-
- std::string user_agent_id_;
-
- // Pre-shared key used during the handshake.
- std::string pre_shared_key_;
-
- HandshakeState state_ = HANDSHAKE_START;
- bool encryption_established_ = false;
- bool initial_keys_dropped_ = false;
- QuicReferenceCountedPointer<QuicCryptoNegotiatedParameters>
- crypto_negotiated_params_;
-
- bool allow_empty_alpn_for_tests_ = false;
- bool allow_invalid_sni_for_tests_ = false;
-
- const bool has_application_state_;
- // Contains the state for performing a resumption, if one is attempted. This
- // will always be non-null if a 0-RTT resumption is attempted.
- std::unique_ptr<QuicResumptionState> cached_state_;
-
- QuicCryptoClientConfig* crypto_config_; // Not owned.
-
- TlsClientConnection tls_connection_;
-
- // If |has_application_state_|, stores the tls session tickets before
- // application state is received. The latest one is put in the front.
- bssl::UniquePtr<SSL_SESSION> cached_tls_sessions_[2] = {};
-
- std::unique_ptr<TransportParameters> received_transport_params_ = nullptr;
- std::unique_ptr<ApplicationState> received_application_state_ = nullptr;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_TLS_CLIENT_HANDSHAKER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/tls_client_handshaker_test.cc b/chromium/net/third_party/quiche/src/quic/core/tls_client_handshaker_test.cc
deleted file mode 100644
index 4bbb4ed6d0f..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/tls_client_handshaker_test.cc
+++ /dev/null
@@ -1,712 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <memory>
-#include <string>
-#include <utility>
-
-#include "absl/base/macros.h"
-#include "quic/core/crypto/quic_decrypter.h"
-#include "quic/core/crypto/quic_encrypter.h"
-#include "quic/core/quic_error_codes.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_server_id.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_utils.h"
-#include "quic/core/quic_versions.h"
-#include "quic/platform/api/quic_expect_bug.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/crypto_test_utils.h"
-#include "quic/test_tools/quic_connection_peer.h"
-#include "quic/test_tools/quic_framer_peer.h"
-#include "quic/test_tools/quic_session_peer.h"
-#include "quic/test_tools/quic_test_utils.h"
-#include "quic/test_tools/simple_session_cache.h"
-#include "quic/tools/fake_proof_verifier.h"
-#include "common/test_tools/quiche_test_utils.h"
-
-using testing::_;
-
-namespace quic {
-namespace test {
-namespace {
-
-constexpr char kServerHostname[] = "test.example.com";
-constexpr uint16_t kServerPort = 443;
-
-// TestProofVerifier wraps ProofVerifierForTesting, except for VerifyCertChain
-// which, if TestProofVerifier is active, always returns QUIC_PENDING. (If this
-// test proof verifier is not active, it delegates VerifyCertChain to the
-// ProofVerifierForTesting.) The pending VerifyCertChain operation can be
-// completed by calling InvokePendingCallback. This allows for testing
-// asynchronous VerifyCertChain operations.
-class TestProofVerifier : public ProofVerifier {
- public:
- TestProofVerifier()
- : verifier_(crypto_test_utils::ProofVerifierForTesting()) {}
-
- QuicAsyncStatus VerifyProof(
- const std::string& hostname,
- const uint16_t port,
- const std::string& server_config,
- QuicTransportVersion quic_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 {
- return verifier_->VerifyProof(
- hostname, port, server_config, quic_version, chlo_hash, certs, cert_sct,
- signature, context, error_details, details, 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 {
- if (!active_) {
- return verifier_->VerifyCertChain(
- hostname, port, certs, ocsp_response, cert_sct, context,
- error_details, details, out_alert, std::move(callback));
- }
- pending_ops_.push_back(std::make_unique<VerifyChainPendingOp>(
- hostname, port, certs, ocsp_response, cert_sct, context, error_details,
- details, out_alert, std::move(callback), verifier_.get()));
- return QUIC_PENDING;
- }
-
- std::unique_ptr<ProofVerifyContext> CreateDefaultContext() override {
- return nullptr;
- }
-
- void Activate() { active_ = true; }
-
- size_t NumPendingCallbacks() const { return pending_ops_.size(); }
-
- void InvokePendingCallback(size_t n) {
- ASSERT_GT(NumPendingCallbacks(), n);
- pending_ops_[n]->Run();
- auto it = pending_ops_.begin() + n;
- pending_ops_.erase(it);
- }
-
- private:
- // Implementation of ProofVerifierCallback that fails if the callback is ever
- // run.
- class FailingProofVerifierCallback : public ProofVerifierCallback {
- public:
- void Run(bool /*ok*/,
- const std::string& /*error_details*/,
- std::unique_ptr<ProofVerifyDetails>* /*details*/) override {
- FAIL();
- }
- };
-
- class VerifyChainPendingOp {
- public:
- VerifyChainPendingOp(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,
- ProofVerifier* delegate)
- : hostname_(hostname),
- port_(port),
- certs_(certs),
- ocsp_response_(ocsp_response),
- cert_sct_(cert_sct),
- context_(context),
- error_details_(error_details),
- details_(details),
- out_alert_(out_alert),
- callback_(std::move(callback)),
- delegate_(delegate) {}
-
- void Run() {
- // TestProofVerifier depends on crypto_test_utils::ProofVerifierForTesting
- // running synchronously. It passes a FailingProofVerifierCallback and
- // runs the original callback after asserting that the verification ran
- // synchronously.
- QuicAsyncStatus status = delegate_->VerifyCertChain(
- hostname_, port_, certs_, ocsp_response_, cert_sct_, context_,
- error_details_, details_, out_alert_,
- std::make_unique<FailingProofVerifierCallback>());
- ASSERT_NE(status, QUIC_PENDING);
- callback_->Run(status == QUIC_SUCCESS, *error_details_, details_);
- }
-
- private:
- std::string hostname_;
- const uint16_t port_;
- std::vector<std::string> certs_;
- std::string ocsp_response_;
- 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_;
- ProofVerifier* delegate_;
- };
-
- std::unique_ptr<ProofVerifier> verifier_;
- bool active_ = false;
- std::vector<std::unique_ptr<VerifyChainPendingOp>> pending_ops_;
-};
-
-class TlsClientHandshakerTest : public QuicTestWithParam<ParsedQuicVersion> {
- public:
- TlsClientHandshakerTest()
- : supported_versions_({GetParam()}),
- server_id_(kServerHostname, kServerPort, false),
- server_compressed_certs_cache_(
- QuicCompressedCertsCache::kQuicCompressedCertsCacheSize) {
- crypto_config_ = std::make_unique<QuicCryptoClientConfig>(
- std::make_unique<TestProofVerifier>(),
- std::make_unique<test::SimpleSessionCache>());
- server_crypto_config_ = crypto_test_utils::CryptoServerConfigForTesting();
- CreateConnection();
- }
-
- void CreateSession() {
- session_ = std::make_unique<TestQuicSpdyClientSession>(
- connection_, DefaultQuicConfig(), supported_versions_, server_id_,
- crypto_config_.get());
- EXPECT_CALL(*session_, GetAlpnsToOffer())
- .WillRepeatedly(testing::Return(std::vector<std::string>(
- {AlpnForVersion(connection_->version())})));
- }
-
- void CreateConnection() {
- connection_ =
- new PacketSavingConnection(&client_helper_, &alarm_factory_,
- Perspective::IS_CLIENT, supported_versions_);
- // Advance the time, because timers do not like uninitialized times.
- connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
- CreateSession();
- }
-
- void CompleteCryptoHandshake() {
- CompleteCryptoHandshakeWithServerALPN(
- AlpnForVersion(connection_->version()));
- }
-
- void CompleteCryptoHandshakeWithServerALPN(const std::string& alpn) {
- EXPECT_CALL(*connection_, SendCryptoData(_, _, _))
- .Times(testing::AnyNumber());
- stream()->CryptoConnect();
- QuicConfig config;
- crypto_test_utils::HandshakeWithFakeServer(
- &config, server_crypto_config_.get(), &server_helper_, &alarm_factory_,
- connection_, stream(), alpn);
- }
-
- QuicCryptoClientStream* stream() {
- return session_->GetMutableCryptoStream();
- }
-
- QuicCryptoServerStreamBase* server_stream() {
- return server_session_->GetMutableCryptoStream();
- }
-
- // Initializes a fake server, and all its associated state, for testing.
- void InitializeFakeServer() {
- TestQuicSpdyServerSession* server_session = nullptr;
- CreateServerSessionForTest(
- server_id_, QuicTime::Delta::FromSeconds(100000), supported_versions_,
- &server_helper_, &alarm_factory_, server_crypto_config_.get(),
- &server_compressed_certs_cache_, &server_connection_, &server_session);
- server_session_.reset(server_session);
- std::string alpn = AlpnForVersion(connection_->version());
- EXPECT_CALL(*server_session_, SelectAlpn(_))
- .WillRepeatedly([alpn](const std::vector<absl::string_view>& alpns) {
- return std::find(alpns.cbegin(), alpns.cend(), alpn);
- });
- }
-
- MockQuicConnectionHelper server_helper_;
- MockQuicConnectionHelper client_helper_;
- MockAlarmFactory alarm_factory_;
- PacketSavingConnection* connection_;
- ParsedQuicVersionVector supported_versions_;
- std::unique_ptr<TestQuicSpdyClientSession> session_;
- QuicServerId server_id_;
- CryptoHandshakeMessage message_;
- std::unique_ptr<QuicCryptoClientConfig> crypto_config_;
-
- // Server state.
- std::unique_ptr<QuicCryptoServerConfig> server_crypto_config_;
- PacketSavingConnection* server_connection_;
- std::unique_ptr<TestQuicSpdyServerSession> server_session_;
- QuicCompressedCertsCache server_compressed_certs_cache_;
-};
-
-INSTANTIATE_TEST_SUITE_P(TlsHandshakerTests,
- TlsClientHandshakerTest,
- ::testing::ValuesIn(AllSupportedVersionsWithTls()),
- ::testing::PrintToStringParamName());
-
-TEST_P(TlsClientHandshakerTest, NotInitiallyConnected) {
- EXPECT_FALSE(stream()->encryption_established());
- EXPECT_FALSE(stream()->one_rtt_keys_available());
-}
-
-TEST_P(TlsClientHandshakerTest, ConnectedAfterHandshake) {
- CompleteCryptoHandshake();
- EXPECT_EQ(PROTOCOL_TLS1_3, stream()->handshake_protocol());
- EXPECT_TRUE(stream()->encryption_established());
- EXPECT_TRUE(stream()->one_rtt_keys_available());
- EXPECT_FALSE(stream()->IsResumption());
-}
-
-TEST_P(TlsClientHandshakerTest, ConnectionClosedOnTlsError) {
- // Have client send ClientHello.
- stream()->CryptoConnect();
- EXPECT_CALL(*connection_, CloseConnection(QUIC_HANDSHAKE_FAILED, _, _, _));
-
- // Send a zero-length ServerHello from server to client.
- char bogus_handshake_message[] = {
- // Handshake struct (RFC 8446 appendix B.3)
- 2, // HandshakeType server_hello
- 0, 0, 0, // uint24 length
- };
- stream()->crypto_message_parser()->ProcessInput(
- absl::string_view(bogus_handshake_message,
- ABSL_ARRAYSIZE(bogus_handshake_message)),
- ENCRYPTION_INITIAL);
-
- EXPECT_FALSE(stream()->one_rtt_keys_available());
-}
-
-TEST_P(TlsClientHandshakerTest, ProofVerifyDetailsAvailableAfterHandshake) {
- EXPECT_CALL(*session_, OnProofVerifyDetailsAvailable(testing::_));
- stream()->CryptoConnect();
- QuicConfig config;
- crypto_test_utils::HandshakeWithFakeServer(
- &config, server_crypto_config_.get(), &server_helper_, &alarm_factory_,
- connection_, stream(), AlpnForVersion(connection_->version()));
- EXPECT_EQ(PROTOCOL_TLS1_3, stream()->handshake_protocol());
- EXPECT_TRUE(stream()->encryption_established());
- EXPECT_TRUE(stream()->one_rtt_keys_available());
-}
-
-TEST_P(TlsClientHandshakerTest, HandshakeWithAsyncProofVerifier) {
- InitializeFakeServer();
-
- // Enable TestProofVerifier to capture call to VerifyCertChain and run it
- // asynchronously.
- TestProofVerifier* proof_verifier =
- static_cast<TestProofVerifier*>(crypto_config_->proof_verifier());
- proof_verifier->Activate();
-
- stream()->CryptoConnect();
- // Exchange handshake messages.
- std::pair<size_t, size_t> moved_message_counts =
- crypto_test_utils::AdvanceHandshake(
- connection_, stream(), 0, server_connection_, server_stream(), 0);
-
- ASSERT_EQ(proof_verifier->NumPendingCallbacks(), 1u);
- proof_verifier->InvokePendingCallback(0);
-
- // Exchange more handshake messages.
- crypto_test_utils::AdvanceHandshake(
- connection_, stream(), moved_message_counts.first, server_connection_,
- server_stream(), moved_message_counts.second);
-
- EXPECT_TRUE(stream()->encryption_established());
- EXPECT_TRUE(stream()->one_rtt_keys_available());
-}
-
-TEST_P(TlsClientHandshakerTest, Resumption) {
- // Disable 0-RTT on the server so that we're only testing 1-RTT resumption:
- SSL_CTX_set_early_data_enabled(server_crypto_config_->ssl_ctx(), false);
- // Finish establishing the first connection:
- CompleteCryptoHandshake();
-
- EXPECT_EQ(PROTOCOL_TLS1_3, stream()->handshake_protocol());
- EXPECT_TRUE(stream()->encryption_established());
- EXPECT_TRUE(stream()->one_rtt_keys_available());
- EXPECT_FALSE(stream()->IsResumption());
-
- // Create a second connection
- CreateConnection();
- CompleteCryptoHandshake();
-
- EXPECT_EQ(PROTOCOL_TLS1_3, stream()->handshake_protocol());
- EXPECT_TRUE(stream()->encryption_established());
- EXPECT_TRUE(stream()->one_rtt_keys_available());
- EXPECT_TRUE(stream()->IsResumption());
-}
-
-TEST_P(TlsClientHandshakerTest, ResumptionRejection) {
- // Disable 0-RTT on the server before the first connection so the client
- // doesn't attempt a 0-RTT resumption, only a 1-RTT resumption.
- SSL_CTX_set_early_data_enabled(server_crypto_config_->ssl_ctx(), false);
- // Finish establishing the first connection:
- CompleteCryptoHandshake();
-
- EXPECT_EQ(PROTOCOL_TLS1_3, stream()->handshake_protocol());
- EXPECT_TRUE(stream()->encryption_established());
- EXPECT_TRUE(stream()->one_rtt_keys_available());
- EXPECT_FALSE(stream()->IsResumption());
-
- // Create a second connection, but disable resumption on the server.
- SSL_CTX_set_options(server_crypto_config_->ssl_ctx(), SSL_OP_NO_TICKET);
- CreateConnection();
- CompleteCryptoHandshake();
-
- EXPECT_EQ(PROTOCOL_TLS1_3, stream()->handshake_protocol());
- EXPECT_TRUE(stream()->encryption_established());
- EXPECT_TRUE(stream()->one_rtt_keys_available());
- EXPECT_FALSE(stream()->IsResumption());
- EXPECT_FALSE(stream()->EarlyDataAccepted());
- EXPECT_EQ(stream()->EarlyDataReason(),
- ssl_early_data_unsupported_for_session);
-}
-
-TEST_P(TlsClientHandshakerTest, ZeroRttResumption) {
- // Finish establishing the first connection:
- CompleteCryptoHandshake();
-
- EXPECT_EQ(PROTOCOL_TLS1_3, stream()->handshake_protocol());
- EXPECT_TRUE(stream()->encryption_established());
- EXPECT_TRUE(stream()->one_rtt_keys_available());
- EXPECT_FALSE(stream()->IsResumption());
-
- // Create a second connection
- CreateConnection();
- // OnConfigNegotiated should be called twice - once when processing saved
- // 0-RTT transport parameters, and then again when receiving transport
- // parameters from the server.
- EXPECT_CALL(*session_, OnConfigNegotiated()).Times(2);
- EXPECT_CALL(*connection_, SendCryptoData(_, _, _))
- .Times(testing::AnyNumber());
- // Start the second handshake and confirm we have keys before receiving any
- // messages from the server.
- stream()->CryptoConnect();
- EXPECT_TRUE(stream()->encryption_established());
- EXPECT_NE(stream()->crypto_negotiated_params().cipher_suite, 0);
- EXPECT_NE(stream()->crypto_negotiated_params().key_exchange_group, 0);
- EXPECT_NE(stream()->crypto_negotiated_params().peer_signature_algorithm, 0);
- // Finish the handshake with the server.
- QuicConfig config;
- crypto_test_utils::HandshakeWithFakeServer(
- &config, server_crypto_config_.get(), &server_helper_, &alarm_factory_,
- connection_, stream(), AlpnForVersion(connection_->version()));
-
- EXPECT_EQ(PROTOCOL_TLS1_3, stream()->handshake_protocol());
- EXPECT_TRUE(stream()->encryption_established());
- EXPECT_TRUE(stream()->one_rtt_keys_available());
- EXPECT_TRUE(stream()->IsResumption());
- EXPECT_TRUE(stream()->EarlyDataAccepted());
- EXPECT_EQ(stream()->EarlyDataReason(), ssl_early_data_accepted);
-}
-
-// Regression test for b/186438140.
-TEST_P(TlsClientHandshakerTest, ZeroRttResumptionWithAyncProofVerifier) {
- // Finish establishing the first connection, so the second connection can
- // resume.
- CompleteCryptoHandshake();
-
- EXPECT_EQ(PROTOCOL_TLS1_3, stream()->handshake_protocol());
- EXPECT_TRUE(stream()->encryption_established());
- EXPECT_TRUE(stream()->one_rtt_keys_available());
- EXPECT_FALSE(stream()->IsResumption());
-
- // Create a second connection.
- CreateConnection();
- InitializeFakeServer();
- EXPECT_CALL(*session_, OnConfigNegotiated());
- EXPECT_CALL(*connection_, SendCryptoData(_, _, _))
- .Times(testing::AnyNumber());
- // Enable TestProofVerifier to capture the call to VerifyCertChain and run it
- // asynchronously.
- TestProofVerifier* proof_verifier =
- static_cast<TestProofVerifier*>(crypto_config_->proof_verifier());
- proof_verifier->Activate();
- // Start the second handshake.
- stream()->CryptoConnect();
-
- ASSERT_EQ(proof_verifier->NumPendingCallbacks(), 1u);
-
- // Advance the handshake with the server. Since cert verification has not
- // finished yet, client cannot derive HANDSHAKE and 1-RTT keys.
- crypto_test_utils::AdvanceHandshake(connection_, stream(), 0,
- server_connection_, server_stream(), 0);
-
- EXPECT_FALSE(stream()->one_rtt_keys_available());
- EXPECT_FALSE(server_stream()->one_rtt_keys_available());
-
- // Finish cert verification after receiving packets from server.
- proof_verifier->InvokePendingCallback(0);
-
- QuicFramer* framer = QuicConnectionPeer::GetFramer(connection_);
- // Verify client has derived HANDSHAKE key.
- EXPECT_NE(nullptr,
- QuicFramerPeer::GetEncrypter(framer, ENCRYPTION_HANDSHAKE));
-
- // Ideally, we should also verify that the process_undecryptable_packets_alarm
- // is set and processing the undecryptable packets can advance the handshake
- // to completion. Unfortunately, the test facilities used in this test does
- // not support queuing and processing undecryptable packets.
-}
-
-TEST_P(TlsClientHandshakerTest, ZeroRttRejection) {
- // Finish establishing the first connection:
- CompleteCryptoHandshake();
-
- EXPECT_EQ(PROTOCOL_TLS1_3, stream()->handshake_protocol());
- EXPECT_TRUE(stream()->encryption_established());
- EXPECT_TRUE(stream()->one_rtt_keys_available());
- EXPECT_FALSE(stream()->IsResumption());
-
- // Create a second connection, but disable 0-RTT on the server.
- SSL_CTX_set_early_data_enabled(server_crypto_config_->ssl_ctx(), false);
- CreateConnection();
-
- // OnConfigNegotiated should be called twice - once when processing saved
- // 0-RTT transport parameters, and then again when receiving transport
- // parameters from the server.
- EXPECT_CALL(*session_, OnConfigNegotiated()).Times(2);
-
- // 4 packets will be sent in this connection: initial handshake packet, 0-RTT
- // packet containing SETTINGS, handshake packet upon 0-RTT rejection, 0-RTT
- // packet retransmission.
- EXPECT_CALL(*connection_,
- OnPacketSent(ENCRYPTION_INITIAL, NOT_RETRANSMISSION));
- if (VersionUsesHttp3(session_->transport_version())) {
- EXPECT_CALL(*connection_,
- OnPacketSent(ENCRYPTION_ZERO_RTT, NOT_RETRANSMISSION));
- }
- EXPECT_CALL(*connection_,
- OnPacketSent(ENCRYPTION_HANDSHAKE, NOT_RETRANSMISSION));
- if (VersionUsesHttp3(session_->transport_version())) {
- // TODO(b/158027651): change transmission type to
- // ALL_ZERO_RTT_RETRANSMISSION.
- EXPECT_CALL(*connection_,
- OnPacketSent(ENCRYPTION_FORWARD_SECURE, LOSS_RETRANSMISSION));
- }
-
- CompleteCryptoHandshake();
-
- QuicFramer* framer = QuicConnectionPeer::GetFramer(connection_);
- EXPECT_EQ(nullptr, QuicFramerPeer::GetEncrypter(framer, ENCRYPTION_ZERO_RTT));
-
- EXPECT_EQ(PROTOCOL_TLS1_3, stream()->handshake_protocol());
- EXPECT_TRUE(stream()->encryption_established());
- EXPECT_TRUE(stream()->one_rtt_keys_available());
- EXPECT_TRUE(stream()->IsResumption());
- EXPECT_FALSE(stream()->EarlyDataAccepted());
- EXPECT_EQ(stream()->EarlyDataReason(), ssl_early_data_peer_declined);
-}
-
-TEST_P(TlsClientHandshakerTest, ZeroRttAndResumptionRejection) {
- // Finish establishing the first connection:
- CompleteCryptoHandshake();
-
- EXPECT_EQ(PROTOCOL_TLS1_3, stream()->handshake_protocol());
- EXPECT_TRUE(stream()->encryption_established());
- EXPECT_TRUE(stream()->one_rtt_keys_available());
- EXPECT_FALSE(stream()->IsResumption());
-
- // Create a second connection, but disable resumption on the server.
- SSL_CTX_set_options(server_crypto_config_->ssl_ctx(), SSL_OP_NO_TICKET);
- CreateConnection();
-
- // OnConfigNegotiated should be called twice - once when processing saved
- // 0-RTT transport parameters, and then again when receiving transport
- // parameters from the server.
- EXPECT_CALL(*session_, OnConfigNegotiated()).Times(2);
-
- // 4 packets will be sent in this connection: initial handshake packet, 0-RTT
- // packet containing SETTINGS, handshake packet upon 0-RTT rejection, 0-RTT
- // packet retransmission.
- EXPECT_CALL(*connection_,
- OnPacketSent(ENCRYPTION_INITIAL, NOT_RETRANSMISSION));
- if (VersionUsesHttp3(session_->transport_version())) {
- EXPECT_CALL(*connection_,
- OnPacketSent(ENCRYPTION_ZERO_RTT, NOT_RETRANSMISSION));
- }
- EXPECT_CALL(*connection_,
- OnPacketSent(ENCRYPTION_HANDSHAKE, NOT_RETRANSMISSION));
- if (VersionUsesHttp3(session_->transport_version())) {
- // TODO(b/158027651): change transmission type to
- // ALL_ZERO_RTT_RETRANSMISSION.
- EXPECT_CALL(*connection_,
- OnPacketSent(ENCRYPTION_FORWARD_SECURE, LOSS_RETRANSMISSION));
- }
-
- CompleteCryptoHandshake();
-
- QuicFramer* framer = QuicConnectionPeer::GetFramer(connection_);
- EXPECT_EQ(nullptr, QuicFramerPeer::GetEncrypter(framer, ENCRYPTION_ZERO_RTT));
-
- EXPECT_EQ(PROTOCOL_TLS1_3, stream()->handshake_protocol());
- EXPECT_TRUE(stream()->encryption_established());
- EXPECT_TRUE(stream()->one_rtt_keys_available());
- EXPECT_FALSE(stream()->IsResumption());
- EXPECT_FALSE(stream()->EarlyDataAccepted());
- EXPECT_EQ(stream()->EarlyDataReason(), ssl_early_data_session_not_resumed);
-}
-
-TEST_P(TlsClientHandshakerTest, ClientSendsNoSNI) {
- // Reconfigure client to sent an empty server hostname. The crypto config also
- // needs to be recreated to use a FakeProofVerifier since the server's cert
- // won't match the empty hostname.
- server_id_ = QuicServerId("", 443);
- crypto_config_.reset(new QuicCryptoClientConfig(
- std::make_unique<FakeProofVerifier>(), nullptr));
- CreateConnection();
- InitializeFakeServer();
-
- stream()->CryptoConnect();
- crypto_test_utils::CommunicateHandshakeMessages(
- connection_, stream(), server_connection_, server_stream());
-
- EXPECT_EQ(PROTOCOL_TLS1_3, stream()->handshake_protocol());
- EXPECT_TRUE(stream()->encryption_established());
- EXPECT_TRUE(stream()->one_rtt_keys_available());
-
- EXPECT_EQ(server_stream()->crypto_negotiated_params().sni, "");
-}
-
-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");
-}
-
-TEST_P(TlsClientHandshakerTest, ServerRequiresCustomALPN) {
- InitializeFakeServer();
- const std::string kTestAlpn = "An ALPN That Client Did Not Offer";
- EXPECT_CALL(*server_session_, SelectAlpn(_))
- .WillOnce([kTestAlpn](const std::vector<absl::string_view>& alpns) {
- return std::find(alpns.cbegin(), alpns.cend(), kTestAlpn);
- });
-
- EXPECT_CALL(*server_connection_,
- CloseConnection(QUIC_HANDSHAKE_FAILED,
- static_cast<QuicIetfTransportErrorCodes>(
- CRYPTO_ERROR_FIRST + 120),
- "TLS handshake failure (ENCRYPTION_INITIAL) 120: "
- "no application protocol",
- _));
-
- stream()->CryptoConnect();
- crypto_test_utils::AdvanceHandshake(connection_, stream(), 0,
- server_connection_, server_stream(), 0);
-
- EXPECT_FALSE(stream()->one_rtt_keys_available());
- EXPECT_FALSE(server_stream()->one_rtt_keys_available());
- EXPECT_FALSE(stream()->encryption_established());
- EXPECT_FALSE(server_stream()->encryption_established());
-}
-
-TEST_P(TlsClientHandshakerTest, ZeroRTTNotAttemptedOnALPNChange) {
- // Finish establishing the first connection:
- CompleteCryptoHandshake();
-
- EXPECT_EQ(PROTOCOL_TLS1_3, stream()->handshake_protocol());
- EXPECT_TRUE(stream()->encryption_established());
- EXPECT_TRUE(stream()->one_rtt_keys_available());
- EXPECT_FALSE(stream()->IsResumption());
-
- // Create a second connection
- CreateConnection();
- // Override the ALPN to send on the second connection.
- const std::string kTestAlpn = "Test ALPN";
- EXPECT_CALL(*session_, GetAlpnsToOffer())
- .WillRepeatedly(testing::Return(std::vector<std::string>({kTestAlpn})));
- // OnConfigNegotiated should only be called once: when transport parameters
- // are received from the server.
- EXPECT_CALL(*session_, OnConfigNegotiated()).Times(1);
-
- CompleteCryptoHandshakeWithServerALPN(kTestAlpn);
- EXPECT_EQ(PROTOCOL_TLS1_3, stream()->handshake_protocol());
- EXPECT_TRUE(stream()->encryption_established());
- EXPECT_TRUE(stream()->one_rtt_keys_available());
- EXPECT_FALSE(stream()->EarlyDataAccepted());
- EXPECT_EQ(stream()->EarlyDataReason(), ssl_early_data_alpn_mismatch);
-}
-
-TEST_P(TlsClientHandshakerTest, InvalidSNI) {
- // Test that a client will skip sending SNI if configured to send an invalid
- // hostname. In this case, the inclusion of '!' is invalid.
- server_id_ = QuicServerId("invalid!.example.com", 443);
- crypto_config_.reset(new QuicCryptoClientConfig(
- std::make_unique<FakeProofVerifier>(), nullptr));
- CreateConnection();
- InitializeFakeServer();
-
- stream()->CryptoConnect();
- crypto_test_utils::CommunicateHandshakeMessages(
- connection_, stream(), server_connection_, server_stream());
-
- EXPECT_EQ(PROTOCOL_TLS1_3, stream()->handshake_protocol());
- EXPECT_TRUE(stream()->encryption_established());
- EXPECT_TRUE(stream()->one_rtt_keys_available());
-
- EXPECT_EQ(server_stream()->crypto_negotiated_params().sni, "");
-}
-
-TEST_P(TlsClientHandshakerTest, BadTransportParams) {
- if (!connection_->version().UsesHttp3()) {
- return;
- }
- // Finish establishing the first connection:
- CompleteCryptoHandshake();
-
- // Create a second connection
- CreateConnection();
-
- stream()->CryptoConnect();
- auto* id_manager = QuicSessionPeer::ietf_streamid_manager(session_.get());
- EXPECT_EQ(kDefaultMaxStreamsPerConnection,
- id_manager->max_outgoing_bidirectional_streams());
- QuicConfig config;
- config.SetMaxBidirectionalStreamsToSend(
- config.GetMaxBidirectionalStreamsToSend() - 1);
-
- EXPECT_CALL(*connection_,
- CloseConnection(QUIC_ZERO_RTT_REJECTION_LIMIT_REDUCED, _, _))
- .WillOnce(testing::Invoke(connection_,
- &MockQuicConnection::ReallyCloseConnection));
- // Close connection will be called again in the handshaker, but this will be
- // no-op as the connection is already closed.
- EXPECT_CALL(*connection_, CloseConnection(QUIC_HANDSHAKE_FAILED, _, _));
-
- crypto_test_utils::HandshakeWithFakeServer(
- &config, server_crypto_config_.get(), &server_helper_, &alarm_factory_,
- connection_, stream(), AlpnForVersion(connection_->version()));
-}
-
-} // namespace
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/tls_handshaker.cc b/chromium/net/third_party/quiche/src/quic/core/tls_handshaker.cc
deleted file mode 100644
index 2eee1cc7559..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/tls_handshaker.cc
+++ /dev/null
@@ -1,372 +0,0 @@
-// Copyright (c) 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/tls_handshaker.h"
-
-#include "absl/base/macros.h"
-#include "absl/strings/str_cat.h"
-#include "absl/strings/string_view.h"
-#include "third_party/boringssl/src/include/openssl/crypto.h"
-#include "third_party/boringssl/src/include/openssl/ssl.h"
-#include "quic/core/quic_crypto_stream.h"
-#include "quic/core/tls_client_handshaker.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_stack_trace.h"
-
-namespace quic {
-
-#define ENDPOINT (SSL_is_server(ssl()) ? "TlsServer: " : "TlsClient: ")
-
-TlsHandshaker::ProofVerifierCallbackImpl::ProofVerifierCallbackImpl(
- TlsHandshaker* parent)
- : parent_(parent) {}
-
-TlsHandshaker::ProofVerifierCallbackImpl::~ProofVerifierCallbackImpl() {}
-
-void TlsHandshaker::ProofVerifierCallbackImpl::Run(
- bool ok, const std::string& /*error_details*/,
- std::unique_ptr<ProofVerifyDetails>* details) {
- if (parent_ == nullptr) {
- return;
- }
-
- parent_->verify_details_ = std::move(*details);
- parent_->verify_result_ = ok ? ssl_verify_ok : ssl_verify_invalid;
- parent_->set_expected_ssl_error(SSL_ERROR_WANT_READ);
- parent_->proof_verify_callback_ = nullptr;
- if (parent_->verify_details_) {
- parent_->OnProofVerifyDetailsAvailable(*parent_->verify_details_);
- }
- parent_->AdvanceHandshake();
-}
-
-void TlsHandshaker::ProofVerifierCallbackImpl::Cancel() { parent_ = nullptr; }
-
-TlsHandshaker::TlsHandshaker(QuicCryptoStream* stream, QuicSession* session)
- : stream_(stream), handshaker_delegate_(session) {}
-
-TlsHandshaker::~TlsHandshaker() {
- if (proof_verify_callback_) {
- proof_verify_callback_->Cancel();
- }
-}
-
-bool TlsHandshaker::ProcessInput(absl::string_view input,
- EncryptionLevel level) {
- if (parser_error_ != QUIC_NO_ERROR) {
- return false;
- }
- // TODO(nharper): Call SSL_quic_read_level(ssl()) and check whether the
- // encryption level BoringSSL expects matches the encryption level that we
- // just received input at. If they mismatch, should ProcessInput return true
- // or false? If data is for a future encryption level, it should be queued for
- // later?
- if (SSL_provide_quic_data(ssl(), TlsConnection::BoringEncryptionLevel(level),
- reinterpret_cast<const uint8_t*>(input.data()),
- input.size()) != 1) {
- // SSL_provide_quic_data can fail for 3 reasons:
- // - API misuse (calling it before SSL_set_custom_quic_method, which we
- // call in the TlsHandshaker c'tor)
- // - Memory exhaustion when appending data to its buffer
- // - Data provided at the wrong encryption level
- //
- // Of these, the only sensible error to handle is data provided at the wrong
- // encryption level.
- //
- // Note: the error provided below has a good-sounding enum value, although
- // it doesn't match the description as it's a QUIC Crypto specific error.
- parser_error_ = QUIC_INVALID_CRYPTO_MESSAGE_TYPE;
- parser_error_detail_ = "TLS stack failed to receive data";
- return false;
- }
- AdvanceHandshake();
- return true;
-}
-
-void TlsHandshaker::AdvanceHandshake() {
- if (is_connection_closed_) {
- return;
- }
- if (GetHandshakeState() >= HANDSHAKE_COMPLETE) {
- ProcessPostHandshakeMessage();
- return;
- }
-
- QUICHE_BUG_IF(
- quic_tls_server_async_done_no_flusher,
- SSL_is_server(ssl()) && !handshaker_delegate_->PacketFlusherAttached())
- << "is_server:" << SSL_is_server(ssl());
-
- QUIC_VLOG(1) << ENDPOINT << "Continuing handshake";
- int rv = SSL_do_handshake(ssl());
-
- // 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
- // that case. If there are no unprocessed ServerHello, the retry will return a
- // non-positive number.
- if (rv == 1 && SSL_in_early_data(ssl())) {
- OnEnterEarlyData();
- rv = SSL_do_handshake(ssl());
- QUIC_VLOG(1) << ENDPOINT
- << "SSL_do_handshake returned when entering early data. After "
- << "retry, rv=" << rv
- << ", SSL_in_early_data=" << SSL_in_early_data(ssl());
- // The retry should either
- // - Return <= 0 if the handshake is still pending, likely still in early
- // data.
- // - Return 1 if the handshake has _actually_ finished. i.e.
- // 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_) {
- QUIC_BUG(quic_handshaker_stay_in_early_data)
- << "The original and the retry of SSL_do_handshake both returned "
- "success and in early data";
- CloseConnection(QUIC_HANDSHAKE_FAILED,
- "TLS handshake failed: Still in early data after retry");
- return;
- }
- }
-
- if (rv == 1) {
- FinishHandshake();
- return;
- }
- int ssl_error = SSL_get_error(ssl(), rv);
- if (ssl_error == expected_ssl_error_) {
- return;
- }
- if (ShouldCloseConnectionOnUnexpectedError(ssl_error) &&
- !is_connection_closed_) {
- QUIC_VLOG(1) << "SSL_do_handshake failed; SSL_get_error returns "
- << ssl_error;
- ERR_print_errors_fp(stderr);
- CloseConnection(QUIC_HANDSHAKE_FAILED, "TLS handshake failed");
- }
-}
-
-void TlsHandshaker::CloseConnection(QuicErrorCode error,
- const std::string& reason_phrase) {
- QUICHE_DCHECK(!reason_phrase.empty());
- stream()->OnUnrecoverableError(error, reason_phrase);
- is_connection_closed_ = true;
-}
-
-void TlsHandshaker::CloseConnection(QuicErrorCode error,
- QuicIetfTransportErrorCodes ietf_error,
- const std::string& reason_phrase) {
- QUICHE_DCHECK(!reason_phrase.empty());
- stream()->OnUnrecoverableError(error, ietf_error, reason_phrase);
- is_connection_closed_ = true;
-}
-
-void TlsHandshaker::OnConnectionClosed(QuicErrorCode /*error*/,
- ConnectionCloseSource /*source*/) {
- is_connection_closed_ = true;
-}
-
-bool TlsHandshaker::ShouldCloseConnectionOnUnexpectedError(int /*ssl_error*/) {
- return true;
-}
-
-size_t TlsHandshaker::BufferSizeLimitForLevel(EncryptionLevel level) const {
- return SSL_quic_max_handshake_flight_len(
- ssl(), TlsConnection::BoringEncryptionLevel(level));
-}
-
-ssl_early_data_reason_t TlsHandshaker::EarlyDataReason() const {
- return SSL_get_early_data_reason(ssl());
-}
-
-const EVP_MD* TlsHandshaker::Prf(const SSL_CIPHER* cipher) {
- return EVP_get_digestbynid(SSL_CIPHER_get_prf_nid(cipher));
-}
-
-enum ssl_verify_result_t TlsHandshaker::VerifyCert(uint8_t* out_alert) {
- if (verify_result_ != ssl_verify_retry ||
- expected_ssl_error() == SSL_ERROR_WANT_CERTIFICATE_VERIFY) {
- enum ssl_verify_result_t result = verify_result_;
- verify_result_ = ssl_verify_retry;
- *out_alert = cert_verify_tls_alert_;
- return result;
- }
- const STACK_OF(CRYPTO_BUFFER)* cert_chain = SSL_get0_peer_certificates(ssl());
- if (cert_chain == nullptr) {
- *out_alert = SSL_AD_INTERNAL_ERROR;
- return ssl_verify_invalid;
- }
- // TODO(nharper): Pass the CRYPTO_BUFFERs into the QUIC stack to avoid copies.
- std::vector<std::string> certs;
- for (CRYPTO_BUFFER* cert : cert_chain) {
- certs.push_back(
- std::string(reinterpret_cast<const char*>(CRYPTO_BUFFER_data(cert)),
- CRYPTO_BUFFER_len(cert)));
- }
- QUIC_DVLOG(1) << "VerifyCert: peer cert_chain length: " << certs.size();
-
- ProofVerifierCallbackImpl* proof_verify_callback =
- new ProofVerifierCallbackImpl(this);
-
- cert_verify_tls_alert_ = *out_alert;
- QuicAsyncStatus verify_result = VerifyCertChain(
- certs, &cert_verify_error_details_, &verify_details_,
- &cert_verify_tls_alert_,
- std::unique_ptr<ProofVerifierCallback>(proof_verify_callback));
- switch (verify_result) {
- case QUIC_SUCCESS:
- if (verify_details_) {
- OnProofVerifyDetailsAvailable(*verify_details_);
- }
- return ssl_verify_ok;
- case QUIC_PENDING:
- proof_verify_callback_ = proof_verify_callback;
- set_expected_ssl_error(SSL_ERROR_WANT_CERTIFICATE_VERIFY);
- return ssl_verify_retry;
- case QUIC_FAILURE:
- default:
- *out_alert = cert_verify_tls_alert_;
- QUIC_LOG(INFO) << "Cert chain verification failed: "
- << cert_verify_error_details_;
- return ssl_verify_invalid;
- }
-}
-
-void TlsHandshaker::SetWriteSecret(EncryptionLevel level,
- const SSL_CIPHER* cipher,
- const std::vector<uint8_t>& write_secret) {
- QUIC_DVLOG(1) << ENDPOINT << "SetWriteSecret level=" << level;
- std::unique_ptr<QuicEncrypter> encrypter =
- QuicEncrypter::CreateFromCipherSuite(SSL_CIPHER_get_id(cipher));
- const EVP_MD* prf = Prf(cipher);
- CryptoUtils::SetKeyAndIV(prf, write_secret,
- handshaker_delegate_->parsed_version(),
- encrypter.get());
- std::vector<uint8_t> header_protection_key =
- CryptoUtils::GenerateHeaderProtectionKey(
- prf, write_secret, handshaker_delegate_->parsed_version(),
- encrypter->GetKeySize());
- encrypter->SetHeaderProtectionKey(
- absl::string_view(reinterpret_cast<char*>(header_protection_key.data()),
- header_protection_key.size()));
- if (level == ENCRYPTION_FORWARD_SECURE) {
- QUICHE_DCHECK(latest_write_secret_.empty());
- latest_write_secret_ = write_secret;
- one_rtt_write_header_protection_key_ = header_protection_key;
- }
- handshaker_delegate_->OnNewEncryptionKeyAvailable(level,
- std::move(encrypter));
-}
-
-bool TlsHandshaker::SetReadSecret(EncryptionLevel level,
- const SSL_CIPHER* cipher,
- const std::vector<uint8_t>& read_secret) {
- QUIC_DVLOG(1) << ENDPOINT << "SetReadSecret level=" << level;
- std::unique_ptr<QuicDecrypter> decrypter =
- QuicDecrypter::CreateFromCipherSuite(SSL_CIPHER_get_id(cipher));
- const EVP_MD* prf = Prf(cipher);
- CryptoUtils::SetKeyAndIV(prf, read_secret,
- handshaker_delegate_->parsed_version(),
- decrypter.get());
- std::vector<uint8_t> header_protection_key =
- CryptoUtils::GenerateHeaderProtectionKey(
- prf, read_secret, handshaker_delegate_->parsed_version(),
- decrypter->GetKeySize());
- decrypter->SetHeaderProtectionKey(
- absl::string_view(reinterpret_cast<char*>(header_protection_key.data()),
- header_protection_key.size()));
- if (level == ENCRYPTION_FORWARD_SECURE) {
- QUICHE_DCHECK(latest_read_secret_.empty());
- latest_read_secret_ = read_secret;
- one_rtt_read_header_protection_key_ = header_protection_key;
- }
- return handshaker_delegate_->OnNewDecryptionKeyAvailable(
- level, std::move(decrypter),
- /*set_alternative_decrypter=*/false,
- /*latch_once_used=*/false);
-}
-
-std::unique_ptr<QuicDecrypter>
-TlsHandshaker::AdvanceKeysAndCreateCurrentOneRttDecrypter() {
- if (latest_read_secret_.empty() || latest_write_secret_.empty() ||
- one_rtt_read_header_protection_key_.empty() ||
- one_rtt_write_header_protection_key_.empty()) {
- std::string error_details = "1-RTT secret(s) not set yet.";
- QUIC_BUG(quic_bug_10312_1) << error_details;
- CloseConnection(QUIC_INTERNAL_ERROR, error_details);
- return nullptr;
- }
- const SSL_CIPHER* cipher = SSL_get_current_cipher(ssl());
- const EVP_MD* prf = Prf(cipher);
- latest_read_secret_ = CryptoUtils::GenerateNextKeyPhaseSecret(
- prf, handshaker_delegate_->parsed_version(), latest_read_secret_);
- latest_write_secret_ = CryptoUtils::GenerateNextKeyPhaseSecret(
- prf, handshaker_delegate_->parsed_version(), latest_write_secret_);
-
- std::unique_ptr<QuicDecrypter> decrypter =
- QuicDecrypter::CreateFromCipherSuite(SSL_CIPHER_get_id(cipher));
- CryptoUtils::SetKeyAndIV(prf, latest_read_secret_,
- handshaker_delegate_->parsed_version(),
- decrypter.get());
- decrypter->SetHeaderProtectionKey(absl::string_view(
- reinterpret_cast<char*>(one_rtt_read_header_protection_key_.data()),
- one_rtt_read_header_protection_key_.size()));
-
- return decrypter;
-}
-
-std::unique_ptr<QuicEncrypter> TlsHandshaker::CreateCurrentOneRttEncrypter() {
- if (latest_write_secret_.empty() ||
- one_rtt_write_header_protection_key_.empty()) {
- std::string error_details = "1-RTT write secret not set yet.";
- QUIC_BUG(quic_bug_10312_2) << error_details;
- CloseConnection(QUIC_INTERNAL_ERROR, error_details);
- return nullptr;
- }
- const SSL_CIPHER* cipher = SSL_get_current_cipher(ssl());
- std::unique_ptr<QuicEncrypter> encrypter =
- QuicEncrypter::CreateFromCipherSuite(SSL_CIPHER_get_id(cipher));
- CryptoUtils::SetKeyAndIV(Prf(cipher), latest_write_secret_,
- handshaker_delegate_->parsed_version(),
- encrypter.get());
- encrypter->SetHeaderProtectionKey(absl::string_view(
- reinterpret_cast<char*>(one_rtt_write_header_protection_key_.data()),
- one_rtt_write_header_protection_key_.size()));
- return encrypter;
-}
-
-bool TlsHandshaker::ExportKeyingMaterialForLabel(absl::string_view label,
- absl::string_view context,
- size_t result_len,
- std::string* result) {
- if (result == nullptr) {
- return false;
- }
- result->resize(result_len);
- return SSL_export_keying_material(
- ssl(), reinterpret_cast<uint8_t*>(&*result->begin()), result_len,
- label.data(), label.size(),
- reinterpret_cast<const uint8_t*>(context.data()), context.size(),
- !context.empty()) == 1;
-}
-
-void TlsHandshaker::WriteMessage(EncryptionLevel level,
- absl::string_view data) {
- stream_->WriteCryptoData(level, data);
-}
-
-void TlsHandshaker::FlushFlight() {}
-
-void TlsHandshaker::SendAlert(EncryptionLevel level, uint8_t desc) {
- std::string error_details = absl::StrCat(
- "TLS handshake failure (", EncryptionLevelToString(level), ") ",
- static_cast<int>(desc), ": ", SSL_alert_desc_string_long(desc));
- QUIC_DLOG(ERROR) << error_details;
- CloseConnection(
- TlsAlertToQuicErrorCode(desc),
- static_cast<QuicIetfTransportErrorCodes>(CRYPTO_ERROR_FIRST + desc),
- error_details);
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/tls_handshaker.h b/chromium/net/third_party/quiche/src/quic/core/tls_handshaker.h
deleted file mode 100644
index 9509e814f24..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/tls_handshaker.h
+++ /dev/null
@@ -1,225 +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_CORE_TLS_HANDSHAKER_H_
-#define QUICHE_QUIC_CORE_TLS_HANDSHAKER_H_
-
-#include "absl/strings/string_view.h"
-#include "third_party/boringssl/src/include/openssl/base.h"
-#include "third_party/boringssl/src/include/openssl/ssl.h"
-#include "quic/core/crypto/crypto_handshake.h"
-#include "quic/core/crypto/crypto_message_parser.h"
-#include "quic/core/crypto/proof_verifier.h"
-#include "quic/core/crypto/quic_decrypter.h"
-#include "quic/core/crypto/quic_encrypter.h"
-#include "quic/core/crypto/tls_connection.h"
-#include "quic/core/quic_session.h"
-#include "quic/platform/api/quic_export.h"
-#include "quic/platform/api/quic_flags.h"
-
-namespace quic {
-
-class QuicCryptoStream;
-
-// Base class for TlsClientHandshaker and TlsServerHandshaker. TlsHandshaker
-// provides functionality common to both the client and server, such as moving
-// messages between the TLS stack and the QUIC crypto stream, and handling
-// derivation of secrets.
-class QUIC_EXPORT_PRIVATE TlsHandshaker : public TlsConnection::Delegate,
- public CryptoMessageParser {
- public:
- // TlsHandshaker does not take ownership of any of its arguments; they must
- // outlive the TlsHandshaker.
- TlsHandshaker(QuicCryptoStream* stream, QuicSession* session);
- TlsHandshaker(const TlsHandshaker&) = delete;
- TlsHandshaker& operator=(const TlsHandshaker&) = delete;
-
- ~TlsHandshaker() override;
-
- // From CryptoMessageParser
- bool ProcessInput(absl::string_view input, EncryptionLevel level) override;
- size_t InputBytesRemaining() const override { return 0; }
- QuicErrorCode error() const override { return parser_error_; }
- const std::string& error_detail() const override {
- return parser_error_detail_;
- }
-
- // The following methods provide implementations to subclasses of
- // TlsHandshaker which use them to implement methods of QuicCryptoStream.
- CryptoMessageParser* crypto_message_parser() { return this; }
- size_t BufferSizeLimitForLevel(EncryptionLevel level) const;
- ssl_early_data_reason_t EarlyDataReason() const;
- std::unique_ptr<QuicDecrypter> AdvanceKeysAndCreateCurrentOneRttDecrypter();
- std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter();
- virtual HandshakeState GetHandshakeState() const = 0;
- bool ExportKeyingMaterialForLabel(absl::string_view label,
- absl::string_view context,
- size_t result_len, std::string* result);
-
- protected:
- // Called when a new message is received on the crypto stream and is available
- // for the TLS stack to read.
- virtual void AdvanceHandshake();
-
- void CloseConnection(QuicErrorCode error, const std::string& reason_phrase);
- // Closes the connection, specifying the wire error code |ietf_error|
- // explicitly.
- void CloseConnection(QuicErrorCode error,
- QuicIetfTransportErrorCodes ietf_error,
- const std::string& reason_phrase);
-
- void OnConnectionClosed(QuicErrorCode error, ConnectionCloseSource source);
-
- bool is_connection_closed() const { return is_connection_closed_; }
-
- // Called when |SSL_do_handshake| returns 1, indicating that the handshake has
- // finished. Note that a handshake only finishes once, entering early data
- // does not count.
- virtual void FinishHandshake() = 0;
-
- // Called when |SSL_do_handshake| returns 1 and the connection is in early
- // data. In that case, |AdvanceHandshake| will call |OnEnterEarlyData| and
- // retry |SSL_do_handshake| once.
- virtual void OnEnterEarlyData() {
- // By default, do nothing but check the preconditions.
- QUICHE_DCHECK(SSL_in_early_data(ssl()));
- }
-
- // Called when a handshake message is received after the handshake is
- // complete.
- virtual void ProcessPostHandshakeMessage() = 0;
-
- // Called when an unexpected error code is received from |SSL_get_error|. If a
- // subclass can expect more than just a single error (as provided by
- // |set_expected_ssl_error|), it can override this method to handle that case.
- virtual bool ShouldCloseConnectionOnUnexpectedError(int ssl_error);
-
- void set_expected_ssl_error(int ssl_error) {
- expected_ssl_error_ = ssl_error;
- }
- int expected_ssl_error() const { return expected_ssl_error_; }
-
- // Called to verify a cert chain. This can be implemented as a simple wrapper
- // around ProofVerifier, which optionally gathers additional arguments to pass
- // into their VerifyCertChain method. This class retains a non-owning pointer
- // to |callback|; the callback must live until this function returns
- // QUIC_SUCCESS or QUIC_FAILURE, or until the callback is run.
- //
- // If certificate verification fails, |*out_alert| may be set to a TLS alert
- // that will be sent when closing the connection; it defaults to
- // certificate_unknown. Implementations of VerifyCertChain may retain the
- // |out_alert| pointer while performing an async operation.
- virtual QuicAsyncStatus VerifyCertChain(
- const std::vector<std::string>& certs,
- std::string* error_details,
- std::unique_ptr<ProofVerifyDetails>* details,
- uint8_t* out_alert,
- std::unique_ptr<ProofVerifierCallback> callback) = 0;
- // Called when certificate verification is completed.
- virtual void OnProofVerifyDetailsAvailable(
- const ProofVerifyDetails& verify_details) = 0;
-
- // Returns the PRF used by the cipher suite negotiated in the TLS handshake.
- const EVP_MD* Prf(const SSL_CIPHER* cipher);
-
- virtual const TlsConnection* tls_connection() const = 0;
-
- SSL* ssl() const { return tls_connection()->ssl(); }
-
- QuicCryptoStream* stream() { return stream_; }
- HandshakerDelegateInterface* handshaker_delegate() {
- return handshaker_delegate_;
- }
-
- enum ssl_verify_result_t VerifyCert(uint8_t* out_alert) override;
-
- // SetWriteSecret provides the encryption secret used to encrypt messages at
- // encryption level |level|. The secret provided here is the one from the TLS
- // 1.3 key schedule (RFC 8446 section 7.1), in particular the handshake
- // 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;
-
- // 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;
-
- // WriteMessage is called when there is |data| from the TLS stack ready for
- // the QUIC stack to write in a crypto frame. The data must be transmitted at
- // encryption level |level|.
- void WriteMessage(EncryptionLevel level, absl::string_view data) override;
-
- // FlushFlight is called to signal that the current flight of
- // messages have all been written (via calls to WriteMessage) and can be
- // flushed to the underlying transport.
- void FlushFlight() override;
-
- // SendAlert causes this TlsHandshaker to close the QUIC connection with an
- // error code corresponding to the TLS alert description |desc|.
- void SendAlert(EncryptionLevel level, uint8_t desc) override;
-
- // Informational callback from BoringSSL. Subclasses can override it to do
- // logging, tracing, etc.
- // See |SSL_CTX_set_info_callback| for the meaning of |type| and |value|.
- void InfoCallback(int /*type*/, int /*value*/) override {}
-
- private:
- // ProofVerifierCallbackImpl handles the result of an asynchronous certificate
- // verification operation.
- class QUIC_EXPORT_PRIVATE ProofVerifierCallbackImpl
- : public ProofVerifierCallback {
- public:
- explicit ProofVerifierCallbackImpl(TlsHandshaker* parent);
- ~ProofVerifierCallbackImpl() override;
-
- // ProofVerifierCallback interface.
- void Run(bool ok,
- const std::string& error_details,
- std::unique_ptr<ProofVerifyDetails>* details) override;
-
- // If called, Cancel causes the pending callback to be a no-op.
- void Cancel();
-
- private:
- // Non-owning pointer to the TlsHandshaker responsible for this callback.
- // |parent_| must be valid for the life of this callback or until |Cancel|
- // is called.
- TlsHandshaker* parent_;
- };
-
- // ProofVerifierCallback used for async certificate verification. Ownership of
- // this object is transferred to |VerifyCertChain|;
- ProofVerifierCallbackImpl* proof_verify_callback_ = nullptr;
- std::unique_ptr<ProofVerifyDetails> verify_details_;
- enum ssl_verify_result_t verify_result_ = ssl_verify_retry;
- uint8_t cert_verify_tls_alert_ = SSL_AD_CERTIFICATE_UNKNOWN;
- std::string cert_verify_error_details_;
-
- int expected_ssl_error_ = SSL_ERROR_WANT_READ;
- bool is_connection_closed_ = false;
-
- QuicCryptoStream* stream_;
- HandshakerDelegateInterface* handshaker_delegate_;
-
- QuicErrorCode parser_error_ = QUIC_NO_ERROR;
- std::string parser_error_detail_;
-
- // The most recently derived 1-RTT read and write secrets, which are updated
- // on each key update.
- std::vector<uint8_t> latest_read_secret_;
- std::vector<uint8_t> latest_write_secret_;
- // 1-RTT header protection keys, which are not changed during key update.
- std::vector<uint8_t> one_rtt_read_header_protection_key_;
- std::vector<uint8_t> one_rtt_write_header_protection_key_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_TLS_HANDSHAKER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/tls_server_handshaker.cc b/chromium/net/third_party/quiche/src/quic/core/tls_server_handshaker.cc
deleted file mode 100644
index a16e72956b1..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/tls_server_handshaker.cc
+++ /dev/null
@@ -1,1161 +0,0 @@
-// Copyright (c) 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/tls_server_handshaker.h"
-
-#include <memory>
-#include <string>
-
-#include "absl/base/macros.h"
-#include "absl/strings/str_cat.h"
-#include "absl/strings/string_view.h"
-#include "third_party/boringssl/src/include/openssl/pool.h"
-#include "third_party/boringssl/src/include/openssl/ssl.h"
-#include "quic/core/crypto/quic_crypto_server_config.h"
-#include "quic/core/crypto/transport_parameters.h"
-#include "quic/core/http/http_encoder.h"
-#include "quic/core/http/http_frames.h"
-#include "quic/core/quic_time.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_flag_utils.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_hostname_utils.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/platform/api/quic_server_stats.h"
-
-#define RECORD_LATENCY_IN_US(stat_name, latency, comment) \
- do { \
- const int64_t latency_in_us = (latency).ToMicroseconds(); \
- QUIC_DVLOG(1) << "Recording " stat_name ": " << latency_in_us; \
- QUIC_SERVER_HISTOGRAM_COUNTS(stat_name, latency_in_us, 1, 10000000, 50, \
- comment); \
- } while (0)
-
-namespace quic {
-
-namespace {
-
-// Default port for HTTP/3.
-uint16_t kDefaultPort = 443;
-
-} // namespace
-
-TlsServerHandshaker::DefaultProofSourceHandle::DefaultProofSourceHandle(
- TlsServerHandshaker* handshaker,
- ProofSource* proof_source)
- : handshaker_(handshaker), proof_source_(proof_source) {}
-
-TlsServerHandshaker::DefaultProofSourceHandle::~DefaultProofSourceHandle() {
- CloseHandle();
-}
-
-void TlsServerHandshaker::DefaultProofSourceHandle::CloseHandle() {
- QUIC_DVLOG(1) << "CloseHandle. is_signature_pending="
- << (signature_callback_ != nullptr);
- if (signature_callback_) {
- signature_callback_->Cancel();
- signature_callback_ = nullptr;
- }
-}
-
-QuicAsyncStatus
-TlsServerHandshaker::DefaultProofSourceHandle::SelectCertificate(
- const QuicSocketAddress& server_address,
- const QuicSocketAddress& client_address,
- absl::string_view /*ssl_capabilities*/,
- const std::string& hostname,
- absl::string_view /*client_hello*/,
- const std::string& /*alpn*/,
- absl::optional<std::string> /*alps*/,
- const std::vector<uint8_t>& /*quic_transport_params*/,
- const absl::optional<std::vector<uint8_t>>& /*early_data_context*/,
- const QuicSSLConfig& /*ssl_config*/) {
- if (!handshaker_ || !proof_source_) {
- QUIC_BUG(quic_bug_10341_1)
- << "SelectCertificate called on a detached handle";
- return QUIC_FAILURE;
- }
-
- bool cert_matched_sni;
- QuicReferenceCountedPointer<ProofSource::Chain> chain =
- proof_source_->GetCertChain(server_address, client_address, hostname,
- &cert_matched_sni);
-
- handshaker_->OnSelectCertificateDone(
- /*ok=*/true, /*is_sync=*/true, chain.get(),
- /*handshake_hints=*/absl::string_view(),
- /*ticket_encryption_key=*/absl::string_view(), cert_matched_sni,
- QuicDelayedSSLConfig());
- if (!handshaker_->select_cert_status().has_value()) {
- QUIC_BUG(quic_bug_12423_1)
- << "select_cert_status() has no value after a synchronous select cert";
- // Return success to continue the handshake.
- return QUIC_SUCCESS;
- }
- return handshaker_->select_cert_status().value();
-}
-
-QuicAsyncStatus TlsServerHandshaker::DefaultProofSourceHandle::ComputeSignature(
- const QuicSocketAddress& server_address,
- const QuicSocketAddress& client_address,
- const std::string& hostname,
- uint16_t signature_algorithm,
- absl::string_view in,
- size_t max_signature_size) {
- if (!handshaker_ || !proof_source_) {
- QUIC_BUG(quic_bug_10341_2)
- << "ComputeSignature called on a detached handle";
- return QUIC_FAILURE;
- }
-
- if (signature_callback_) {
- QUIC_BUG(quic_bug_10341_3) << "ComputeSignature called while pending";
- return QUIC_FAILURE;
- }
-
- signature_callback_ = new DefaultSignatureCallback(this);
- proof_source_->ComputeTlsSignature(
- server_address, client_address, hostname, signature_algorithm, in,
- std::unique_ptr<DefaultSignatureCallback>(signature_callback_));
-
- if (signature_callback_) {
- QUIC_DVLOG(1) << "ComputeTlsSignature is pending";
- signature_callback_->set_is_sync(false);
- return QUIC_PENDING;
- }
-
- bool success = handshaker_->HasValidSignature(max_signature_size);
- QUIC_DVLOG(1) << "ComputeTlsSignature completed synchronously. success:"
- << success;
- // OnComputeSignatureDone should have been called by signature_callback_->Run.
- return success ? QUIC_SUCCESS : QUIC_FAILURE;
-}
-
-TlsServerHandshaker::DecryptCallback::DecryptCallback(
- TlsServerHandshaker* handshaker)
- : handshaker_(handshaker) {}
-
-void TlsServerHandshaker::DecryptCallback::Run(std::vector<uint8_t> plaintext) {
- if (handshaker_ == nullptr) {
- // The callback was cancelled before we could run.
- return;
- }
-
- TlsServerHandshaker* handshaker = handshaker_;
- handshaker_ = nullptr;
-
- handshaker->decrypted_session_ticket_ = std::move(plaintext);
- const bool is_async =
- (handshaker->expected_ssl_error() == SSL_ERROR_PENDING_TICKET);
-
- absl::optional<QuicConnectionContextSwitcher> context_switcher;
-
- if (is_async) {
- context_switcher.emplace(handshaker->connection_context());
- }
- QUIC_TRACESTRING(
- absl::StrCat("TLS ticket decryption done. len(decrypted_ticket):",
- handshaker->decrypted_session_ticket_.size()));
-
- // DecryptCallback::Run could be called synchronously. When that happens, we
- // are currently in the middle of a call to AdvanceHandshake.
- // (AdvanceHandshake called SSL_do_handshake, which through some layers
- // called SessionTicketOpen, which called TicketCrypter::Decrypt, which
- // synchronously called this function.) In that case, the handshake will
- // continue to be processed when this function returns.
- //
- // When this callback is called asynchronously (i.e. the ticket decryption
- // is pending), TlsServerHandshaker is not actively processing handshake
- // messages. We need to have it resume processing handshake messages by
- // calling AdvanceHandshake.
- if (is_async) {
- handshaker->AdvanceHandshakeFromCallback();
- }
-
- handshaker->ticket_decryption_callback_ = nullptr;
-}
-
-void TlsServerHandshaker::DecryptCallback::Cancel() {
- QUICHE_DCHECK(handshaker_);
- handshaker_ = nullptr;
-}
-
-TlsServerHandshaker::TlsServerHandshaker(
- QuicSession* session, const QuicCryptoServerConfig* crypto_config)
- : TlsHandshaker(this, session),
- QuicCryptoServerStreamBase(session),
- proof_source_(crypto_config->proof_source()),
- pre_shared_key_(crypto_config->pre_shared_key()),
- 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();
-
- QUICHE_DCHECK_EQ(PROTOCOL_TLS1_3,
- session->connection()->version().handshake_protocol);
-
- // Configure the SSL to be a server.
- SSL_set_accept_state(ssl());
-
- // Make sure we use the right TLS extension codepoint.
- int use_legacy_extension = 0;
- if (session->version().UsesLegacyTlsExtension()) {
- use_legacy_extension = 1;
- }
- SSL_set_quic_use_legacy_codepoint(ssl(), use_legacy_extension);
-
- if (session->connection()->context()->tracer) {
- tls_connection_.EnableInfoCallback();
- }
-
- if (no_select_cert_if_disconnected_) {
- QUIC_RELOADABLE_FLAG_COUNT_N(quic_tls_no_select_cert_if_disconnected, 1, 2);
- }
-}
-
-TlsServerHandshaker::~TlsServerHandshaker() { CancelOutstandingCallbacks(); }
-
-void TlsServerHandshaker::CancelOutstandingCallbacks() {
- if (proof_source_handle_) {
- proof_source_handle_->CloseHandle();
- }
- if (ticket_decryption_callback_) {
- ticket_decryption_callback_->Cancel();
- ticket_decryption_callback_ = nullptr;
- }
-}
-
-void TlsServerHandshaker::InfoCallback(int type, int value) {
- QuicConnectionTracer* tracer =
- session()->connection()->context()->tracer.get();
-
- if (tracer == nullptr) {
- return;
- }
-
- if (type & SSL_CB_LOOP) {
- tracer->PrintString(
- absl::StrCat("SSL:ACCEPT_LOOP:", SSL_state_string_long(ssl())));
- } else if (type & SSL_CB_ALERT) {
- const char* prefix =
- (type & SSL_CB_READ) ? "SSL:READ_ALERT:" : "SSL:WRITE_ALERT:";
- tracer->PrintString(absl::StrCat(prefix, SSL_alert_type_string_long(value),
- ":", SSL_alert_desc_string_long(value)));
- } else if (type & SSL_CB_EXIT) {
- const char* prefix =
- (value == 1) ? "SSL:ACCEPT_EXIT_OK:" : "SSL:ACCEPT_EXIT_FAIL:";
- tracer->PrintString(absl::StrCat(prefix, SSL_state_string_long(ssl())));
- } else if (type & SSL_CB_HANDSHAKE_START) {
- tracer->PrintString(
- absl::StrCat("SSL:HANDSHAKE_START:", SSL_state_string_long(ssl())));
- } else if (type & SSL_CB_HANDSHAKE_DONE) {
- tracer->PrintString(
- absl::StrCat("SSL:HANDSHAKE_DONE:", SSL_state_string_long(ssl())));
- } else {
- QUIC_DLOG(INFO) << "Unknown event type " << type << ": "
- << SSL_state_string_long(ssl());
- tracer->PrintString(
- absl::StrCat("SSL:unknown:", value, ":", SSL_state_string_long(ssl())));
- }
-}
-
-std::unique_ptr<ProofSourceHandle>
-TlsServerHandshaker::MaybeCreateProofSourceHandle() {
- return std::make_unique<DefaultProofSourceHandle>(this, proof_source_);
-}
-
-bool TlsServerHandshaker::GetBase64SHA256ClientChannelID(
- std::string* /*output*/) const {
- // Channel ID is not supported when TLS is used in QUIC.
- return false;
-}
-
-void TlsServerHandshaker::SendServerConfigUpdate(
- const CachedNetworkParameters* /*cached_network_params*/) {
- // SCUP messages aren't supported when using the TLS handshake.
-}
-
-bool TlsServerHandshaker::IsZeroRtt() const {
- return SSL_early_data_accepted(ssl());
-}
-
-bool TlsServerHandshaker::IsResumption() const {
- return SSL_session_reused(ssl());
-}
-
-bool TlsServerHandshaker::ResumptionAttempted() const {
- return ticket_received_;
-}
-
-int TlsServerHandshaker::NumServerConfigUpdateMessagesSent() const {
- // SCUP messages aren't supported when using the TLS handshake.
- return 0;
-}
-
-const CachedNetworkParameters*
-TlsServerHandshaker::PreviousCachedNetworkParams() const {
- return last_received_cached_network_params_.get();
-}
-
-void TlsServerHandshaker::SetPreviousCachedNetworkParams(
- CachedNetworkParameters cached_network_params) {
- last_received_cached_network_params_ =
- std::make_unique<CachedNetworkParameters>(cached_network_params);
-}
-
-void TlsServerHandshaker::OnPacketDecrypted(EncryptionLevel level) {
- if (level == ENCRYPTION_HANDSHAKE && state_ < HANDSHAKE_PROCESSED) {
- state_ = HANDSHAKE_PROCESSED;
- handshaker_delegate()->DiscardOldEncryptionKey(ENCRYPTION_INITIAL);
- handshaker_delegate()->DiscardOldDecryptionKey(ENCRYPTION_INITIAL);
- }
-}
-
-void TlsServerHandshaker::OnHandshakeDoneReceived() {
- QUICHE_DCHECK(false);
-}
-
-void TlsServerHandshaker::OnNewTokenReceived(absl::string_view /*token*/) {
- QUICHE_DCHECK(false);
-}
-
-std::string TlsServerHandshaker::GetAddressToken(
- const CachedNetworkParameters* cached_network_params) const {
- SourceAddressTokens empty_previous_tokens;
- const QuicConnection* connection = session()->connection();
- return crypto_config_->NewSourceAddressToken(
- crypto_config_->source_address_token_boxer(), empty_previous_tokens,
- connection->effective_peer_address().host(),
- connection->random_generator(), connection->clock()->WallNow(),
- session()->add_cached_network_parameters_to_address_token()
- ? cached_network_params
- : nullptr);
-}
-
-bool TlsServerHandshaker::ValidateAddressToken(absl::string_view token) const {
- SourceAddressTokens tokens;
- HandshakeFailureReason reason = crypto_config_->ParseSourceAddressToken(
- crypto_config_->source_address_token_boxer(), token, tokens);
- if (reason != HANDSHAKE_OK) {
- QUIC_DLOG(WARNING) << "Failed to parse source address token: "
- << CryptoUtils::HandshakeFailureReasonToString(reason);
- return false;
- }
- auto cached_network_params = std::make_unique<CachedNetworkParameters>();
- reason = crypto_config_->ValidateSourceAddressTokens(
- tokens, session()->connection()->effective_peer_address().host(),
- session()->connection()->clock()->WallNow(),
- session()->add_cached_network_parameters_to_address_token()
- ? cached_network_params.get()
- : nullptr);
- if (reason != HANDSHAKE_OK) {
- QUIC_DLOG(WARNING) << "Failed to validate source address token: "
- << CryptoUtils::HandshakeFailureReasonToString(reason);
- return false;
- }
- if (session()->add_cached_network_parameters_to_address_token()) {
- last_received_cached_network_params_ = std::move(cached_network_params);
- }
- return true;
-}
-
-bool TlsServerHandshaker::ShouldSendExpectCTHeader() const {
- return false;
-}
-
-bool TlsServerHandshaker::DidCertMatchSni() const { return cert_matched_sni_; }
-
-const ProofSource::Details* TlsServerHandshaker::ProofSourceDetails() const {
- return proof_source_details_.get();
-}
-
-bool TlsServerHandshaker::ExportKeyingMaterial(absl::string_view label,
- absl::string_view context,
- size_t result_len,
- std::string* result) {
- return ExportKeyingMaterialForLabel(label, context, result_len, result);
-}
-
-void TlsServerHandshaker::OnConnectionClosed(QuicErrorCode error,
- ConnectionCloseSource source) {
- TlsHandshaker::OnConnectionClosed(error, source);
-}
-
-ssl_early_data_reason_t TlsServerHandshaker::EarlyDataReason() const {
- return TlsHandshaker::EarlyDataReason();
-}
-
-bool TlsServerHandshaker::encryption_established() const {
- return encryption_established_;
-}
-
-bool TlsServerHandshaker::one_rtt_keys_available() const {
- return state_ == HANDSHAKE_CONFIRMED;
-}
-
-const QuicCryptoNegotiatedParameters&
-TlsServerHandshaker::crypto_negotiated_params() const {
- return *crypto_negotiated_params_;
-}
-
-CryptoMessageParser* TlsServerHandshaker::crypto_message_parser() {
- return TlsHandshaker::crypto_message_parser();
-}
-
-HandshakeState TlsServerHandshaker::GetHandshakeState() const {
- return state_;
-}
-
-void TlsServerHandshaker::SetServerApplicationStateForResumption(
- std::unique_ptr<ApplicationState> state) {
- application_state_ = std::move(state);
-}
-
-size_t TlsServerHandshaker::BufferSizeLimitForLevel(
- EncryptionLevel level) const {
- return TlsHandshaker::BufferSizeLimitForLevel(level);
-}
-
-std::unique_ptr<QuicDecrypter>
-TlsServerHandshaker::AdvanceKeysAndCreateCurrentOneRttDecrypter() {
- return TlsHandshaker::AdvanceKeysAndCreateCurrentOneRttDecrypter();
-}
-
-std::unique_ptr<QuicEncrypter>
-TlsServerHandshaker::CreateCurrentOneRttEncrypter() {
- return TlsHandshaker::CreateCurrentOneRttEncrypter();
-}
-
-void TlsServerHandshaker::OverrideQuicConfigDefaults(QuicConfig* /*config*/) {}
-
-void TlsServerHandshaker::AdvanceHandshakeFromCallback() {
- QuicConnection::ScopedPacketFlusher flusher(session()->connection());
-
- AdvanceHandshake();
- if (!is_connection_closed()) {
- handshaker_delegate()->OnHandshakeCallbackDone();
- }
-}
-
-bool TlsServerHandshaker::ProcessTransportParameters(
- const SSL_CLIENT_HELLO* client_hello,
- std::string* error_details) {
- TransportParameters client_params;
- const uint8_t* client_params_bytes;
- size_t params_bytes_len;
-
- // Make sure we use the right TLS extension codepoint.
- uint16_t extension_type = TLSEXT_TYPE_quic_transport_parameters_standard;
- if (session()->version().UsesLegacyTlsExtension()) {
- extension_type = TLSEXT_TYPE_quic_transport_parameters_legacy;
- }
- // When using early select cert callback, SSL_get_peer_quic_transport_params
- // can not be used to retrieve the client's transport parameters, but we can
- // use SSL_early_callback_ctx_extension_get to do that.
- if (!SSL_early_callback_ctx_extension_get(client_hello, extension_type,
- &client_params_bytes,
- &params_bytes_len)) {
- params_bytes_len = 0;
- }
-
- if (params_bytes_len == 0) {
- *error_details = "Client's transport parameters are missing";
- return false;
- }
- std::string parse_error_details;
- if (!ParseTransportParameters(session()->connection()->version(),
- Perspective::IS_CLIENT, client_params_bytes,
- params_bytes_len, &client_params,
- &parse_error_details)) {
- QUICHE_DCHECK(!parse_error_details.empty());
- *error_details =
- "Unable to parse client's transport parameters: " + parse_error_details;
- return false;
- }
-
- // Notify QuicConnectionDebugVisitor.
- session()->connection()->OnTransportParametersReceived(client_params);
-
- if (client_params.legacy_version_information.has_value() &&
- CryptoUtils::ValidateClientHelloVersion(
- client_params.legacy_version_information.value().version,
- session()->connection()->version(), session()->supported_versions(),
- error_details) != QUIC_NO_ERROR) {
- return false;
- }
-
- if (client_params.version_information.has_value() &&
- !CryptoUtils::ValidateChosenVersion(
- client_params.version_information.value().chosen_version,
- session()->version(), error_details)) {
- QUICHE_DCHECK(!error_details->empty());
- return false;
- }
-
- if (handshaker_delegate()->ProcessTransportParameters(
- client_params, /* is_resumption = */ false, error_details) !=
- QUIC_NO_ERROR) {
- return false;
- }
-
- ProcessAdditionalTransportParameters(client_params);
-
- return true;
-}
-
-TlsServerHandshaker::SetTransportParametersResult
-TlsServerHandshaker::SetTransportParameters() {
- SetTransportParametersResult result;
- QUICHE_DCHECK(!result.success);
-
- TransportParameters server_params;
- server_params.perspective = Perspective::IS_SERVER;
- server_params.legacy_version_information =
- TransportParameters::LegacyVersionInformation();
- server_params.legacy_version_information.value().supported_versions =
- CreateQuicVersionLabelVector(session()->supported_versions());
- server_params.legacy_version_information.value().version =
- CreateQuicVersionLabel(session()->connection()->version());
- if (GetQuicReloadableFlag(quic_version_information)) {
- QUIC_RELOADABLE_FLAG_COUNT_N(quic_version_information, 1, 2);
- server_params.version_information =
- TransportParameters::VersionInformation();
- server_params.version_information.value().chosen_version =
- CreateQuicVersionLabel(session()->version());
- server_params.version_information.value().other_versions =
- CreateQuicVersionLabelVector(session()->supported_versions());
- }
-
- if (!handshaker_delegate()->FillTransportParameters(&server_params)) {
- return result;
- }
-
- // Notify QuicConnectionDebugVisitor.
- session()->connection()->OnTransportParametersSent(server_params);
-
- { // 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) ||
- SSL_set_quic_transport_params(ssl(), server_params_bytes.data(),
- server_params_bytes.size()) != 1) {
- return result;
- }
- result.quic_transport_params = std::move(server_params_bytes);
- }
-
- if (application_state_) {
- std::vector<uint8_t> early_data_context;
- if (!SerializeTransportParametersForTicket(
- server_params, *application_state_, &early_data_context)) {
- QUIC_BUG(quic_bug_10341_4)
- << "Failed to serialize Transport Parameters for ticket.";
- result.early_data_context = std::vector<uint8_t>();
- return result;
- }
- SSL_set_quic_early_data_context(ssl(), early_data_context.data(),
- early_data_context.size());
- result.early_data_context = std::move(early_data_context);
- application_state_.reset(nullptr);
- }
- result.success = true;
- return result;
-}
-
-void TlsServerHandshaker::SetWriteSecret(
- EncryptionLevel level,
- const SSL_CIPHER* cipher,
- const std::vector<uint8_t>& write_secret) {
- if (is_connection_closed()) {
- return;
- }
- if (level == ENCRYPTION_FORWARD_SECURE) {
- encryption_established_ = true;
- // Fill crypto_negotiated_params_:
- const SSL_CIPHER* cipher = SSL_get_current_cipher(ssl());
- if (cipher) {
- crypto_negotiated_params_->cipher_suite =
- SSL_CIPHER_get_protocol_id(cipher);
- }
- crypto_negotiated_params_->key_exchange_group = SSL_get_curve_id(ssl());
- }
- TlsHandshaker::SetWriteSecret(level, cipher, write_secret);
-}
-
-std::string TlsServerHandshaker::GetAcceptChValueForHostname(
- const std::string& /*hostname*/) const {
- return {};
-}
-
-void TlsServerHandshaker::FinishHandshake() {
- QUICHE_DCHECK(!SSL_in_early_data(ssl()));
-
- if (!valid_alpn_received_) {
- QUIC_DLOG(ERROR)
- << "Server: handshake finished without receiving a known ALPN";
- // TODO(b/130164908) this should send no_application_protocol
- // instead of QUIC_HANDSHAKE_FAILED.
- CloseConnection(QUIC_HANDSHAKE_FAILED,
- "Server did not receive a known ALPN");
- return;
- }
-
- ssl_early_data_reason_t reason_code = EarlyDataReason();
- QUIC_DLOG(INFO) << "Server: handshake finished. Early data reason "
- << reason_code << " ("
- << CryptoUtils::EarlyDataReasonToString(reason_code) << ")";
- state_ = HANDSHAKE_CONFIRMED;
-
- handshaker_delegate()->OnTlsHandshakeComplete();
- handshaker_delegate()->DiscardOldEncryptionKey(ENCRYPTION_HANDSHAKE);
- handshaker_delegate()->DiscardOldDecryptionKey(ENCRYPTION_HANDSHAKE);
- // ENCRYPTION_ZERO_RTT decryption key is not discarded here as "Servers MAY
- // temporarily retain 0-RTT keys to allow decrypting reordered packets
- // without requiring their contents to be retransmitted with 1-RTT keys."
- // It is expected that QuicConnection will discard the key at an
- // appropriate time.
-}
-
-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
- // the client cert if needed.
- return QUIC_SUCCESS;
-}
-
-void TlsServerHandshaker::OnProofVerifyDetailsAvailable(
- const ProofVerifyDetails& /*verify_details*/) {}
-
-ssl_private_key_result_t TlsServerHandshaker::PrivateKeySign(
- uint8_t* out,
- size_t* out_len,
- size_t max_out,
- uint16_t sig_alg,
- absl::string_view in) {
- QUICHE_DCHECK_EQ(expected_ssl_error(), SSL_ERROR_WANT_READ);
-
- QuicAsyncStatus status = proof_source_handle_->ComputeSignature(
- session()->connection()->self_address(),
- session()->connection()->peer_address(), crypto_negotiated_params_->sni,
- sig_alg, in, max_out);
- if (status == QUIC_PENDING) {
- set_expected_ssl_error(SSL_ERROR_WANT_PRIVATE_KEY_OPERATION);
- if (async_op_timer_.has_value()) {
- QUIC_CODE_COUNT(
- quic_tls_server_computing_signature_while_another_op_pending);
- }
- async_op_timer_ = QuicTimeAccumulator();
- async_op_timer_->Start(now());
- }
- return PrivateKeyComplete(out, out_len, max_out);
-}
-
-ssl_private_key_result_t TlsServerHandshaker::PrivateKeyComplete(
- uint8_t* out,
- size_t* out_len,
- size_t max_out) {
- if (expected_ssl_error() == SSL_ERROR_WANT_PRIVATE_KEY_OPERATION) {
- return ssl_private_key_retry;
- }
-
- const bool success = HasValidSignature(max_out);
- QuicConnectionStats::TlsServerOperationStats compute_signature_stats;
- compute_signature_stats.success = success;
- if (async_op_timer_.has_value()) {
- async_op_timer_->Stop(now());
- compute_signature_stats.async_latency =
- async_op_timer_->GetTotalElapsedTime();
- async_op_timer_.reset();
- RECORD_LATENCY_IN_US("tls_server_async_compute_signature_latency_us",
- compute_signature_stats.async_latency,
- "Async compute signature latency in microseconds");
- }
- connection_stats().tls_server_compute_signature_stats =
- std::move(compute_signature_stats);
-
- if (!success) {
- return ssl_private_key_failure;
- }
- *out_len = cert_verify_sig_.size();
- memcpy(out, cert_verify_sig_.data(), *out_len);
- cert_verify_sig_.clear();
- cert_verify_sig_.shrink_to_fit();
- return ssl_private_key_success;
-}
-
-void TlsServerHandshaker::OnComputeSignatureDone(
- bool ok,
- bool is_sync,
- std::string signature,
- std::unique_ptr<ProofSource::Details> details) {
- QUIC_DVLOG(1) << "OnComputeSignatureDone. ok:" << ok
- << ", is_sync:" << is_sync
- << ", len(signature):" << signature.size();
- absl::optional<QuicConnectionContextSwitcher> context_switcher;
-
- if (!is_sync) {
- context_switcher.emplace(connection_context());
- }
-
- QUIC_TRACESTRING(absl::StrCat("TLS compute signature done. ok:", ok,
- ", len(signature):", signature.size()));
-
- if (ok) {
- cert_verify_sig_ = std::move(signature);
- proof_source_details_ = std::move(details);
- }
- const int last_expected_ssl_error = expected_ssl_error();
- set_expected_ssl_error(SSL_ERROR_WANT_READ);
- if (!is_sync) {
- QUICHE_DCHECK_EQ(last_expected_ssl_error,
- SSL_ERROR_WANT_PRIVATE_KEY_OPERATION);
- AdvanceHandshakeFromCallback();
- }
-}
-
-bool TlsServerHandshaker::HasValidSignature(size_t max_signature_size) const {
- return !cert_verify_sig_.empty() &&
- cert_verify_sig_.size() <= max_signature_size;
-}
-
-size_t TlsServerHandshaker::SessionTicketMaxOverhead() {
- QUICHE_DCHECK(proof_source_->GetTicketCrypter());
- return proof_source_->GetTicketCrypter()->MaxOverhead();
-}
-
-int TlsServerHandshaker::SessionTicketSeal(uint8_t* out,
- size_t* out_len,
- size_t max_out_len,
- absl::string_view in) {
- QUICHE_DCHECK(proof_source_->GetTicketCrypter());
- std::vector<uint8_t> ticket =
- proof_source_->GetTicketCrypter()->Encrypt(in, ticket_encryption_key_);
- if (max_out_len < ticket.size()) {
- QUIC_BUG(quic_bug_12423_2)
- << "TicketCrypter returned " << ticket.size()
- << " bytes of ciphertext, which is larger than its max overhead of "
- << max_out_len;
- return 0; // failure
- }
- *out_len = ticket.size();
- memcpy(out, ticket.data(), ticket.size());
- QUIC_CODE_COUNT(quic_tls_server_handshaker_tickets_sealed);
- return 1; // success
-}
-
-ssl_ticket_aead_result_t TlsServerHandshaker::SessionTicketOpen(
- uint8_t* out,
- size_t* out_len,
- size_t max_out_len,
- absl::string_view in) {
- QUICHE_DCHECK(proof_source_->GetTicketCrypter());
-
- if (ignore_ticket_open_) {
- // SetIgnoreTicketOpen has been called. Typically this means the caller is
- // using handshake hints and expect the hints to contain ticket decryption
- // results.
- QUIC_CODE_COUNT(quic_tls_server_handshaker_tickets_ignored_1);
- return ssl_ticket_aead_ignore_ticket;
- }
-
- if (!ticket_decryption_callback_) {
- ticket_decryption_callback_ = new DecryptCallback(this);
- proof_source_->GetTicketCrypter()->Decrypt(
- in, std::unique_ptr<DecryptCallback>(ticket_decryption_callback_));
-
- // Decrypt can run the callback synchronously. In that case, the callback
- // will clear the ticket_decryption_callback_ pointer, and instead of
- // returning ssl_ticket_aead_retry, we should continue processing to
- // return the decrypted ticket.
- //
- // If the callback is not run synchronously, return ssl_ticket_aead_retry
- // and when the callback is complete this function will be run again to
- // return the result.
- if (ticket_decryption_callback_) {
- QUICHE_DCHECK(!ticket_decryption_callback_->IsDone());
- set_expected_ssl_error(SSL_ERROR_PENDING_TICKET);
- if (async_op_timer_.has_value()) {
- QUIC_CODE_COUNT(
- quic_tls_server_decrypting_ticket_while_another_op_pending);
- }
- async_op_timer_ = QuicTimeAccumulator();
- async_op_timer_->Start(now());
- }
- }
-
- // If the async ticket decryption is pending, either started by this
- // SessionTicketOpen call or one that happened earlier, return
- // ssl_ticket_aead_retry.
- if (ticket_decryption_callback_ && !ticket_decryption_callback_->IsDone()) {
- return ssl_ticket_aead_retry;
- }
-
- ssl_ticket_aead_result_t result =
- FinalizeSessionTicketOpen(out, out_len, max_out_len);
-
- QuicConnectionStats::TlsServerOperationStats decrypt_ticket_stats;
- decrypt_ticket_stats.success = (result == ssl_ticket_aead_success);
- if (async_op_timer_.has_value()) {
- async_op_timer_->Stop(now());
- decrypt_ticket_stats.async_latency = async_op_timer_->GetTotalElapsedTime();
- async_op_timer_.reset();
- RECORD_LATENCY_IN_US("tls_server_async_decrypt_ticket_latency_us",
- decrypt_ticket_stats.async_latency,
- "Async decrypt ticket latency in microseconds");
- }
- connection_stats().tls_server_decrypt_ticket_stats =
- std::move(decrypt_ticket_stats);
-
- return result;
-}
-
-ssl_ticket_aead_result_t TlsServerHandshaker::FinalizeSessionTicketOpen(
- uint8_t* out,
- size_t* out_len,
- size_t max_out_len) {
- ticket_decryption_callback_ = nullptr;
- set_expected_ssl_error(SSL_ERROR_WANT_READ);
- if (decrypted_session_ticket_.empty()) {
- QUIC_DLOG(ERROR) << "Session ticket decryption failed; ignoring ticket";
- // Ticket decryption failed. Ignore the ticket.
- QUIC_CODE_COUNT(quic_tls_server_handshaker_tickets_ignored_2);
- return ssl_ticket_aead_ignore_ticket;
- }
- if (max_out_len < decrypted_session_ticket_.size()) {
- return ssl_ticket_aead_error;
- }
- memcpy(out, decrypted_session_ticket_.data(),
- decrypted_session_ticket_.size());
- *out_len = decrypted_session_ticket_.size();
-
- QUIC_CODE_COUNT(quic_tls_server_handshaker_tickets_opened);
- return ssl_ticket_aead_success;
-}
-
-ssl_select_cert_result_t TlsServerHandshaker::EarlySelectCertCallback(
- const SSL_CLIENT_HELLO* client_hello) {
- // EarlySelectCertCallback can be called twice from BoringSSL: If the first
- // call returns ssl_select_cert_retry, when cert selection completes,
- // SSL_do_handshake will call it again.
-
- if (select_cert_status_.has_value()) {
- // This is the second call, return the result directly.
- QUIC_DVLOG(1) << "EarlySelectCertCallback called to continue handshake, "
- "returning directly. success:"
- << (select_cert_status_.value() == QUIC_SUCCESS);
- return (select_cert_status_.value() == QUIC_SUCCESS)
- ? ssl_select_cert_success
- : ssl_select_cert_error;
- }
-
- // This is the first call.
- select_cert_status_ = QUIC_PENDING;
- proof_source_handle_ = MaybeCreateProofSourceHandle();
-
- if (!pre_shared_key_.empty()) {
- // TODO(b/154162689) add PSK support to QUIC+TLS.
- QUIC_BUG(quic_bug_10341_6)
- << "QUIC server pre-shared keys not yet supported with TLS";
- return ssl_select_cert_error;
- }
-
- {
- const uint8_t* unused_extension_bytes;
- size_t unused_extension_len;
- ticket_received_ = SSL_early_callback_ctx_extension_get(
- client_hello, TLSEXT_TYPE_pre_shared_key, &unused_extension_bytes,
- &unused_extension_len);
- }
-
- // This callback is called very early by Boring SSL, most of the SSL_get_foo
- // function do not work at this point, but SSL_get_servername does.
- const char* hostname = SSL_get_servername(ssl(), TLSEXT_NAMETYPE_host_name);
- if (hostname) {
- crypto_negotiated_params_->sni =
- QuicHostnameUtils::NormalizeHostname(hostname);
- if (!ValidateHostname(hostname)) {
- return ssl_select_cert_error;
- }
- if (hostname != crypto_negotiated_params_->sni) {
- QUIC_CODE_COUNT(quic_tls_server_hostname_diff);
- QUIC_LOG_EVERY_N_SEC(WARNING, 300)
- << "Raw and normalized hostnames differ, but both are valid SNIs. "
- "raw hostname:"
- << hostname << ", normalized:" << crypto_negotiated_params_->sni;
- } else {
- QUIC_CODE_COUNT(quic_tls_server_hostname_same);
- }
- } else {
- QUIC_LOG(INFO) << "No hostname indicated in SNI";
- }
-
- std::string error_details;
- if (!ProcessTransportParameters(client_hello, &error_details)) {
- CloseConnection(QUIC_HANDSHAKE_FAILED, error_details);
- return ssl_select_cert_error;
- }
- OverrideQuicConfigDefaults(session()->config());
- session()->OnConfigNegotiated();
-
- auto set_transport_params_result = SetTransportParameters();
- if (!set_transport_params_result.success) {
- QUIC_LOG(ERROR) << "Failed to set transport parameters";
- return ssl_select_cert_error;
- }
-
- bssl::UniquePtr<uint8_t> ssl_capabilities;
- size_t ssl_capabilities_len = 0;
- absl::string_view ssl_capabilities_view;
-
- absl::optional<std::string> alps;
-
- if (CryptoUtils::GetSSLCapabilities(ssl(), &ssl_capabilities,
- &ssl_capabilities_len)) {
- ssl_capabilities_view =
- absl::string_view(reinterpret_cast<const char*>(ssl_capabilities.get()),
- ssl_capabilities_len);
- }
-
- // Enable ALPS for the session's ALPN.
- SetApplicationSettingsResult alps_result =
- SetApplicationSettings(AlpnForVersion(session()->version()));
- if (!alps_result.success) {
- return ssl_select_cert_error;
- }
- alps =
- alps_result.alps_length > 0
- ? std::string(alps_result.alps_buffer.get(), alps_result.alps_length)
- : std::string();
-
- if (no_select_cert_if_disconnected_ &&
- !session()->connection()->connected()) {
- QUIC_RELOADABLE_FLAG_COUNT_N(quic_tls_no_select_cert_if_disconnected, 2, 2);
- select_cert_status_ = QUIC_FAILURE;
- return ssl_select_cert_error;
- }
-
- const QuicAsyncStatus status = proof_source_handle_->SelectCertificate(
- session()->connection()->self_address().Normalized(),
- session()->connection()->peer_address().Normalized(),
- ssl_capabilities_view, crypto_negotiated_params_->sni,
- absl::string_view(
- reinterpret_cast<const char*>(client_hello->client_hello),
- client_hello->client_hello_len),
- AlpnForVersion(session()->version()), std::move(alps),
- set_transport_params_result.quic_transport_params,
- set_transport_params_result.early_data_context,
- tls_connection_.ssl_config());
-
- QUICHE_DCHECK_EQ(status, select_cert_status().value());
-
- if (status == QUIC_PENDING) {
- set_expected_ssl_error(SSL_ERROR_PENDING_CERTIFICATE);
- if (async_op_timer_.has_value()) {
- QUIC_CODE_COUNT(quic_tls_server_selecting_cert_while_another_op_pending);
- }
- async_op_timer_ = QuicTimeAccumulator();
- async_op_timer_->Start(now());
- return ssl_select_cert_retry;
- }
-
- if (status == QUIC_FAILURE) {
- return ssl_select_cert_error;
- }
-
- return ssl_select_cert_success;
-}
-
-void TlsServerHandshaker::OnSelectCertificateDone(
- bool ok, bool is_sync, const ProofSource::Chain* chain,
- absl::string_view handshake_hints, absl::string_view ticket_encryption_key,
- bool cert_matched_sni, QuicDelayedSSLConfig delayed_ssl_config) {
- QUIC_DVLOG(1) << "OnSelectCertificateDone. ok:" << ok
- << ", is_sync:" << is_sync
- << ", len(handshake_hints):" << handshake_hints.size()
- << ", len(ticket_encryption_key):"
- << ticket_encryption_key.size();
- absl::optional<QuicConnectionContextSwitcher> context_switcher;
- if (!is_sync) {
- context_switcher.emplace(connection_context());
- }
-
- QUIC_TRACESTRING(absl::StrCat(
- "TLS select certificate done: ok:", ok,
- ", len(handshake_hints):", handshake_hints.size(),
- ", len(ticket_encryption_key):", ticket_encryption_key.size()));
-
- 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 (ok) {
- if (chain && !chain->certs.empty()) {
- tls_connection_.SetCertChain(chain->ToCryptoBuffers().value);
- if (!handshake_hints.empty() &&
- !SSL_set_handshake_hints(
- ssl(), reinterpret_cast<const uint8_t*>(handshake_hints.data()),
- handshake_hints.size())) {
- // If |SSL_set_handshake_hints| fails, the ssl() object will remain
- // intact, it is as if we didn't call it. The handshaker will
- // continue to compute signature/decrypt ticket as normal.
- QUIC_CODE_COUNT(quic_tls_server_set_handshake_hints_failed);
- QUIC_DVLOG(1) << "SSL_set_handshake_hints failed";
- }
- select_cert_status_ = QUIC_SUCCESS;
- } else {
- QUIC_LOG(ERROR) << "No certs provided for host '"
- << crypto_negotiated_params_->sni << "', server_address:"
- << session()->connection()->self_address()
- << ", client_address:"
- << session()->connection()->peer_address();
- }
- }
-
- QuicConnectionStats::TlsServerOperationStats select_cert_stats;
- select_cert_stats.success = (select_cert_status_ == QUIC_SUCCESS);
- QUICHE_DCHECK_NE(is_sync, async_op_timer_.has_value());
- if (async_op_timer_.has_value()) {
- async_op_timer_->Stop(now());
- select_cert_stats.async_latency = async_op_timer_->GetTotalElapsedTime();
- async_op_timer_.reset();
- RECORD_LATENCY_IN_US("tls_server_async_select_cert_latency_us",
- select_cert_stats.async_latency,
- "Async select cert latency in microseconds");
- }
- connection_stats().tls_server_select_cert_stats =
- std::move(select_cert_stats);
-
- const int last_expected_ssl_error = expected_ssl_error();
- set_expected_ssl_error(SSL_ERROR_WANT_READ);
- if (!is_sync) {
- QUICHE_DCHECK_EQ(last_expected_ssl_error, SSL_ERROR_PENDING_CERTIFICATE);
- AdvanceHandshakeFromCallback();
- }
-}
-
-bool TlsServerHandshaker::WillNotCallComputeSignature() const {
- return SSL_can_release_private_key(ssl());
-}
-
-bool TlsServerHandshaker::ValidateHostname(const std::string& hostname) const {
- if (!QuicHostnameUtils::IsValidSNI(hostname)) {
- // TODO(b/151676147): Include this error string in the CONNECTION_CLOSE
- // frame.
- QUIC_LOG(ERROR) << "Invalid SNI provided: \"" << hostname << "\"";
- return false;
- }
- return true;
-}
-
-int TlsServerHandshaker::TlsExtServernameCallback(int* /*out_alert*/) {
- // SSL_TLSEXT_ERR_OK causes the server_name extension to be acked in
- // ServerHello.
- return SSL_TLSEXT_ERR_OK;
-}
-
-int TlsServerHandshaker::SelectAlpn(const uint8_t** out,
- uint8_t* out_len,
- const uint8_t* in,
- unsigned in_len) {
- // |in| contains a sequence of 1-byte-length-prefixed values.
- *out_len = 0;
- *out = nullptr;
- if (in_len == 0) {
- QUIC_DLOG(ERROR) << "No ALPN provided by client";
- return SSL_TLSEXT_ERR_NOACK;
- }
-
- CBS all_alpns;
- CBS_init(&all_alpns, in, in_len);
-
- std::vector<absl::string_view> alpns;
- while (CBS_len(&all_alpns) > 0) {
- CBS alpn;
- if (!CBS_get_u8_length_prefixed(&all_alpns, &alpn)) {
- QUIC_DLOG(ERROR) << "Failed to parse ALPN length";
- return SSL_TLSEXT_ERR_NOACK;
- }
-
- const size_t alpn_length = CBS_len(&alpn);
- if (alpn_length == 0) {
- QUIC_DLOG(ERROR) << "Received invalid zero-length ALPN";
- return SSL_TLSEXT_ERR_NOACK;
- }
-
- alpns.emplace_back(reinterpret_cast<const char*>(CBS_data(&alpn)),
- alpn_length);
- }
-
- // TODO(wub): Remove QuicSession::SelectAlpn. QuicSessions should know the
- // ALPN on construction.
- auto selected_alpn = session()->SelectAlpn(alpns);
- if (selected_alpn == alpns.end()) {
- QUIC_DLOG(ERROR) << "No known ALPN provided by client";
- return SSL_TLSEXT_ERR_NOACK;
- }
-
- session()->OnAlpnSelected(*selected_alpn);
- valid_alpn_received_ = true;
- *out_len = selected_alpn->size();
- *out = reinterpret_cast<const uint8_t*>(selected_alpn->data());
- return SSL_TLSEXT_ERR_OK;
-}
-
-TlsServerHandshaker::SetApplicationSettingsResult
-TlsServerHandshaker::SetApplicationSettings(absl::string_view alpn) {
- TlsServerHandshaker::SetApplicationSettingsResult result;
- const uint8_t* alps_data = nullptr;
-
- const std::string& hostname = crypto_negotiated_params_->sni;
- std::string accept_ch_value = GetAcceptChValueForHostname(hostname);
- std::string origin = absl::StrCat("https://", hostname);
- uint16_t port = session()->self_address().port();
- if (port != kDefaultPort) {
- // This should be rare in production, but useful for test servers.
- QUIC_CODE_COUNT(quic_server_alps_non_default_port);
- absl::StrAppend(&origin, ":", port);
- }
-
- if (!accept_ch_value.empty()) {
- AcceptChFrame frame{{{std::move(origin), std::move(accept_ch_value)}}};
- result.alps_length =
- HttpEncoder::SerializeAcceptChFrame(frame, &result.alps_buffer);
- alps_data = reinterpret_cast<const uint8_t*>(result.alps_buffer.get());
- }
-
- if (SSL_add_application_settings(
- ssl(), reinterpret_cast<const uint8_t*>(alpn.data()), alpn.size(),
- alps_data, result.alps_length) != 1) {
- QUIC_DLOG(ERROR) << "Failed to enable ALPS";
- result.success = false;
- } else {
- result.success = true;
- }
- return result;
-}
-
-SSL* TlsServerHandshaker::GetSsl() const { return ssl(); }
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/tls_server_handshaker.h b/chromium/net/third_party/quiche/src/quic/core/tls_server_handshaker.h
deleted file mode 100644
index d2f37b0eb26..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/tls_server_handshaker.h
+++ /dev/null
@@ -1,385 +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_CORE_TLS_SERVER_HANDSHAKER_H_
-#define QUICHE_QUIC_CORE_TLS_SERVER_HANDSHAKER_H_
-
-#include <string>
-
-#include "absl/strings/string_view.h"
-#include "third_party/boringssl/src/include/openssl/pool.h"
-#include "third_party/boringssl/src/include/openssl/ssl.h"
-#include "quic/core/crypto/quic_crypto_server_config.h"
-#include "quic/core/crypto/tls_server_connection.h"
-#include "quic/core/proto/cached_network_parameters_proto.h"
-#include "quic/core/quic_crypto_server_stream_base.h"
-#include "quic/core/quic_crypto_stream.h"
-#include "quic/core/quic_time_accumulator.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/tls_handshaker.h"
-#include "quic/platform/api/quic_export.h"
-#include "quic/platform/api/quic_flag_utils.h"
-#include "quic/platform/api/quic_flags.h"
-
-namespace quic {
-
-// An implementation of QuicCryptoServerStreamBase which uses
-// TLS 1.3 for the crypto handshake protocol.
-class QUIC_EXPORT_PRIVATE TlsServerHandshaker
- : public TlsHandshaker,
- public TlsServerConnection::Delegate,
- public ProofSourceHandleCallback,
- public QuicCryptoServerStreamBase {
- public:
- // |crypto_config| must outlive TlsServerHandshaker.
- TlsServerHandshaker(QuicSession* session,
- const QuicCryptoServerConfig* crypto_config);
- TlsServerHandshaker(const TlsServerHandshaker&) = delete;
- TlsServerHandshaker& operator=(const TlsServerHandshaker&) = delete;
-
- ~TlsServerHandshaker() override;
-
- // From QuicCryptoServerStreamBase
- void CancelOutstandingCallbacks() override;
- bool GetBase64SHA256ClientChannelID(std::string* output) const override;
- void SendServerConfigUpdate(
- const CachedNetworkParameters* cached_network_params) override;
- bool IsZeroRtt() const override;
- bool IsResumption() const override;
- bool ResumptionAttempted() const override;
- int NumServerConfigUpdateMessagesSent() const override;
- const CachedNetworkParameters* PreviousCachedNetworkParams() const override;
- void SetPreviousCachedNetworkParams(
- CachedNetworkParameters cached_network_params) override;
- void OnPacketDecrypted(EncryptionLevel level) override;
- void OnOneRttPacketAcknowledged() override {}
- void OnHandshakePacketSent() override {}
- void OnConnectionClosed(QuicErrorCode error,
- ConnectionCloseSource source) override;
- void OnHandshakeDoneReceived() override;
- std::string GetAddressToken(
- const CachedNetworkParameters* cached_network_params) const override;
- bool ValidateAddressToken(absl::string_view token) const override;
- void OnNewTokenReceived(absl::string_view token) override;
- bool ShouldSendExpectCTHeader() const override;
- bool DidCertMatchSni() const override;
- const ProofSource::Details* ProofSourceDetails() const override;
- bool ExportKeyingMaterial(absl::string_view label, absl::string_view context,
- size_t result_len, std::string* result) override;
- SSL* GetSsl() const override;
-
- // From QuicCryptoServerStreamBase and TlsHandshaker
- ssl_early_data_reason_t EarlyDataReason() const override;
- bool encryption_established() const override;
- bool one_rtt_keys_available() const override;
- const QuicCryptoNegotiatedParameters& crypto_negotiated_params()
- const override;
- CryptoMessageParser* crypto_message_parser() override;
- HandshakeState GetHandshakeState() const override;
- void SetServerApplicationStateForResumption(
- std::unique_ptr<ApplicationState> state) override;
- size_t BufferSizeLimitForLevel(EncryptionLevel level) const override;
- std::unique_ptr<QuicDecrypter> AdvanceKeysAndCreateCurrentOneRttDecrypter()
- override;
- std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() override;
- void SetWriteSecret(EncryptionLevel level,
- const SSL_CIPHER* cipher,
- const std::vector<uint8_t>& write_secret) override;
-
- // Called with normalized SNI hostname as |hostname|. Return value will be
- // sent in an ACCEPT_CH frame in the TLS ALPS extension, unless empty.
- virtual std::string GetAcceptChValueForHostname(
- const std::string& hostname) const;
-
- // Get the ClientCertMode that is currently in effect on this handshaker.
- ClientCertMode client_cert_mode() const {
- return tls_connection_.ssl_config().client_cert_mode;
- }
-
- protected:
- // Override for tracing.
- void InfoCallback(int type, int value) override;
-
- // Creates a proof source handle for selecting cert and computing signature.
- virtual std::unique_ptr<ProofSourceHandle> MaybeCreateProofSourceHandle();
-
- // Hook to allow the server to override parts of the QuicConfig based on SNI
- // before we generate transport parameters.
- virtual void OverrideQuicConfigDefaults(QuicConfig* config);
-
- virtual bool ValidateHostname(const std::string& hostname) const;
-
- const TlsConnection* tls_connection() const override {
- return &tls_connection_;
- }
-
- virtual void ProcessAdditionalTransportParameters(
- const TransportParameters& /*params*/) {}
-
- // Called when a potentially async operation is done and the done callback
- // needs to advance the handshake.
- void AdvanceHandshakeFromCallback();
-
- // TlsHandshaker implementation:
- void FinishHandshake() override;
- void ProcessPostHandshakeMessage() override {}
- QuicAsyncStatus VerifyCertChain(
- const std::vector<std::string>& certs,
- std::string* error_details,
- std::unique_ptr<ProofVerifyDetails>* details,
- uint8_t* out_alert,
- std::unique_ptr<ProofVerifierCallback> callback) override;
- void OnProofVerifyDetailsAvailable(
- const ProofVerifyDetails& verify_details) override;
-
- // TlsServerConnection::Delegate implementation:
- // Used to select certificates and process transport parameters.
- ssl_select_cert_result_t EarlySelectCertCallback(
- const SSL_CLIENT_HELLO* client_hello) override;
- int TlsExtServernameCallback(int* out_alert) override;
- int SelectAlpn(const uint8_t** out,
- uint8_t* out_len,
- const uint8_t* in,
- unsigned in_len) override;
- ssl_private_key_result_t PrivateKeySign(uint8_t* out,
- size_t* out_len,
- size_t max_out,
- uint16_t sig_alg,
- absl::string_view in) override;
- ssl_private_key_result_t PrivateKeyComplete(uint8_t* out,
- size_t* out_len,
- size_t max_out) override;
- size_t SessionTicketMaxOverhead() override;
- int SessionTicketSeal(uint8_t* out,
- size_t* out_len,
- size_t max_out_len,
- absl::string_view in) override;
- ssl_ticket_aead_result_t SessionTicketOpen(uint8_t* out,
- size_t* out_len,
- size_t max_out_len,
- absl::string_view in) override;
- // Called when ticket_decryption_callback_ is done to determine a final
- // decryption result.
- ssl_ticket_aead_result_t FinalizeSessionTicketOpen(uint8_t* out,
- size_t* out_len,
- size_t max_out_len);
- TlsConnection::Delegate* ConnectionDelegate() override { return this; }
-
- // The status of cert selection. nullopt means it hasn't started.
- const absl::optional<QuicAsyncStatus>& select_cert_status() const {
- return select_cert_status_;
- }
- // Whether |cert_verify_sig_| contains a valid signature.
- // NOTE: BoringSSL queries the result of a async signature operation using
- // PrivateKeyComplete(), a successful PrivateKeyComplete() will clear the
- // content of |cert_verify_sig_|, this function should not be called after
- // that.
- bool HasValidSignature(size_t max_signature_size) const;
-
- // ProofSourceHandleCallback implementation:
- void OnSelectCertificateDone(
- bool ok, bool is_sync, const ProofSource::Chain* chain,
- absl::string_view handshake_hints,
- absl::string_view ticket_encryption_key, bool cert_matched_sni,
- QuicDelayedSSLConfig delayed_ssl_config) override;
-
- void OnComputeSignatureDone(
- bool ok,
- bool is_sync,
- std::string signature,
- std::unique_ptr<ProofSource::Details> details) override;
-
- void set_encryption_established(bool encryption_established) {
- encryption_established_ = encryption_established;
- }
-
- bool WillNotCallComputeSignature() const override;
-
- void SetIgnoreTicketOpen(bool value) { ignore_ticket_open_ = value; }
-
- private:
- class QUIC_EXPORT_PRIVATE DecryptCallback
- : public ProofSource::DecryptCallback {
- public:
- explicit DecryptCallback(TlsServerHandshaker* handshaker);
- void Run(std::vector<uint8_t> plaintext) override;
-
- // If called, Cancel causes the pending callback to be a no-op.
- void Cancel();
-
- // Return true if either
- // - Cancel() has been called.
- // - Run() has been called, or is in the middle of it.
- bool IsDone() const { return handshaker_ == nullptr; }
-
- private:
- TlsServerHandshaker* handshaker_;
- };
-
- // DefaultProofSourceHandle delegates all operations to the shared proof
- // source.
- class QUIC_EXPORT_PRIVATE DefaultProofSourceHandle
- : public ProofSourceHandle {
- public:
- DefaultProofSourceHandle(TlsServerHandshaker* handshaker,
- ProofSource* proof_source);
-
- ~DefaultProofSourceHandle() override;
-
- // Close the handle. Cancel the pending signature operation, if any.
- void CloseHandle() override;
-
- // Delegates to proof_source_->GetCertChain.
- // Returns QUIC_SUCCESS or QUIC_FAILURE. Never returns QUIC_PENDING.
- QuicAsyncStatus SelectCertificate(
- const QuicSocketAddress& server_address,
- const QuicSocketAddress& client_address,
- absl::string_view ssl_capabilities,
- const std::string& hostname,
- absl::string_view client_hello,
- const std::string& alpn,
- absl::optional<std::string> alps,
- const std::vector<uint8_t>& quic_transport_params,
- const absl::optional<std::vector<uint8_t>>& early_data_context,
- const QuicSSLConfig& ssl_config) override;
-
- // Delegates to proof_source_->ComputeTlsSignature.
- // Returns QUIC_SUCCESS, QUIC_FAILURE or QUIC_PENDING.
- QuicAsyncStatus ComputeSignature(const QuicSocketAddress& server_address,
- const QuicSocketAddress& client_address,
- const std::string& hostname,
- uint16_t signature_algorithm,
- absl::string_view in,
- size_t max_signature_size) override;
-
- protected:
- ProofSourceHandleCallback* callback() override { return handshaker_; }
-
- private:
- class QUIC_EXPORT_PRIVATE DefaultSignatureCallback
- : public ProofSource::SignatureCallback {
- public:
- explicit DefaultSignatureCallback(DefaultProofSourceHandle* handle)
- : handle_(handle) {}
-
- void Run(bool ok,
- std::string signature,
- std::unique_ptr<ProofSource::Details> details) override {
- if (handle_ == nullptr) {
- // Operation has been canceled, or Run has been called.
- return;
- }
-
- DefaultProofSourceHandle* handle = handle_;
- handle_ = nullptr;
-
- handle->signature_callback_ = nullptr;
- if (handle->handshaker_ != nullptr) {
- handle->handshaker_->OnComputeSignatureDone(
- ok, is_sync_, std::move(signature), std::move(details));
- }
- }
-
- // If called, Cancel causes the pending callback to be a no-op.
- void Cancel() { handle_ = nullptr; }
-
- void set_is_sync(bool is_sync) { is_sync_ = is_sync; }
-
- private:
- DefaultProofSourceHandle* handle_;
- // Set to false if handle_->ComputeSignature returns QUIC_PENDING.
- bool is_sync_ = true;
- };
-
- // Not nullptr on construction. Set to nullptr when cancelled.
- TlsServerHandshaker* handshaker_; // Not owned.
- ProofSource* proof_source_; // Not owned.
- DefaultSignatureCallback* signature_callback_ = nullptr;
- };
-
- struct QUIC_NO_EXPORT SetTransportParametersResult {
- bool success = false;
- // Empty vector if QUIC transport params are not set successfully.
- std::vector<uint8_t> quic_transport_params;
- // absl::nullopt if there is no application state to begin with.
- // Empty vector if application state is not set successfully.
- absl::optional<std::vector<uint8_t>> early_data_context;
- };
-
- SetTransportParametersResult SetTransportParameters();
- bool ProcessTransportParameters(const SSL_CLIENT_HELLO* client_hello,
- std::string* error_details);
-
- struct QUIC_NO_EXPORT SetApplicationSettingsResult {
- bool success = false;
- std::unique_ptr<char[]> alps_buffer;
- size_t alps_length = 0;
- };
- SetApplicationSettingsResult SetApplicationSettings(absl::string_view alpn);
-
- QuicConnectionStats& connection_stats() {
- return session()->connection()->mutable_stats();
- }
- QuicTime now() const { return session()->GetClock()->Now(); }
-
- QuicConnectionContext* connection_context() {
- return session()->connection()->context();
- }
-
- std::unique_ptr<ProofSourceHandle> proof_source_handle_;
- ProofSource* proof_source_;
-
- // State to handle potentially asynchronous session ticket decryption.
- // |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;
- // |decrypted_session_ticket_| contains the decrypted session ticket after the
- // callback has run but before it is passed to BoringSSL.
- std::vector<uint8_t> decrypted_session_ticket_;
- // |ticket_received_| tracks whether we received a resumption ticket from the
- // client. It does not matter whether we were able to decrypt said ticket or
- // if we actually resumed a session with it - the presence of this ticket
- // indicates that the client attempted a resumption.
- bool ticket_received_ = false;
-
- // Force SessionTicketOpen to return ssl_ticket_aead_ignore_ticket if called.
- bool ignore_ticket_open_ = false;
-
- // nullopt means select cert hasn't started.
- absl::optional<QuicAsyncStatus> select_cert_status_;
-
- std::string cert_verify_sig_;
- std::unique_ptr<ProofSource::Details> proof_source_details_;
-
- // Count the duration of the current async operation, if any.
- absl::optional<QuicTimeAccumulator> async_op_timer_;
-
- std::unique_ptr<ApplicationState> application_state_;
-
- // Pre-shared key used during the handshake.
- std::string pre_shared_key_;
-
- // (optional) Key to use for encrypting TLS resumption tickets.
- std::string ticket_encryption_key_;
-
- HandshakeState state_ = HANDSHAKE_START;
- bool encryption_established_ = false;
- bool valid_alpn_received_ = false;
- QuicReferenceCountedPointer<QuicCryptoNegotiatedParameters>
- crypto_negotiated_params_;
- TlsServerConnection tls_connection_;
- const QuicCryptoServerConfig* crypto_config_; // Unowned.
- // The last received CachedNetworkParameters from a validated address token.
- mutable std::unique_ptr<CachedNetworkParameters>
- last_received_cached_network_params_;
-
- bool cert_matched_sni_ = false;
- const bool no_select_cert_if_disconnected_ =
- GetQuicReloadableFlag(quic_tls_no_select_cert_if_disconnected);
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_TLS_SERVER_HANDSHAKER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/tls_server_handshaker_test.cc b/chromium/net/third_party/quiche/src/quic/core/tls_server_handshaker_test.cc
deleted file mode 100644
index 01fb7ab2ee4..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/tls_server_handshaker_test.cc
+++ /dev/null
@@ -1,1080 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/tls_server_handshaker.h"
-
-#include <memory>
-#include <utility>
-#include <vector>
-
-#include "absl/base/macros.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/crypto/certificate_util.h"
-#include "quic/core/crypto/client_proof_source.h"
-#include "quic/core/crypto/proof_source.h"
-#include "quic/core/crypto/quic_random.h"
-#include "quic/core/quic_crypto_client_stream.h"
-#include "quic/core/quic_session.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_utils.h"
-#include "quic/core/quic_versions.h"
-#include "quic/core/tls_client_handshaker.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/crypto_test_utils.h"
-#include "quic/test_tools/failing_proof_source.h"
-#include "quic/test_tools/fake_proof_source.h"
-#include "quic/test_tools/fake_proof_source_handle.h"
-#include "quic/test_tools/quic_config_peer.h"
-#include "quic/test_tools/quic_test_utils.h"
-#include "quic/test_tools/simple_session_cache.h"
-#include "quic/test_tools/test_certificates.h"
-#include "quic/test_tools/test_ticket_crypter.h"
-
-namespace quic {
-class QuicConnection;
-class QuicStream;
-} // namespace quic
-
-using testing::_;
-using testing::NiceMock;
-using testing::Return;
-
-namespace quic {
-namespace test {
-
-namespace {
-
-const char kServerHostname[] = "test.example.com";
-const uint16_t kServerPort = 443;
-
-struct TestParams {
- ParsedQuicVersion version;
- bool disable_resumption;
-};
-
-// Used by ::testing::PrintToStringParamName().
-std::string PrintToString(const TestParams& p) {
- return absl::StrCat(
- ParsedQuicVersionToString(p.version), "_",
- (p.disable_resumption ? "ResumptionDisabled" : "ResumptionEnabled"));
-}
-
-// Constructs test permutations.
-std::vector<TestParams> GetTestParams() {
- std::vector<TestParams> params;
- for (const auto& version : AllSupportedVersionsWithTls()) {
- for (bool disable_resumption : {false, true}) {
- params.push_back(TestParams{version, disable_resumption});
- }
- }
- return params;
-}
-
-class TestTlsServerHandshaker : public TlsServerHandshaker {
- public:
- TestTlsServerHandshaker(QuicSession* session,
- const QuicCryptoServerConfig* crypto_config)
- : TlsServerHandshaker(session, crypto_config),
- proof_source_(crypto_config->proof_source()) {
- ON_CALL(*this, MaybeCreateProofSourceHandle())
- .WillByDefault(testing::Invoke(
- this, &TestTlsServerHandshaker::RealMaybeCreateProofSourceHandle));
-
- ON_CALL(*this, OverrideQuicConfigDefaults(_))
- .WillByDefault(testing::Invoke(
- this, &TestTlsServerHandshaker::RealOverrideQuicConfigDefaults));
- }
-
- MOCK_METHOD(std::unique_ptr<ProofSourceHandle>,
- MaybeCreateProofSourceHandle,
- (),
- (override));
-
- MOCK_METHOD(void, OverrideQuicConfigDefaults, (QuicConfig * config),
- (override));
-
- void SetupProofSourceHandle(
- FakeProofSourceHandle::Action select_cert_action,
- FakeProofSourceHandle::Action compute_signature_action,
- QuicDelayedSSLConfig dealyed_ssl_config = QuicDelayedSSLConfig()) {
- EXPECT_CALL(*this, MaybeCreateProofSourceHandle())
- .WillOnce(
- testing::Invoke([this, select_cert_action, compute_signature_action,
- dealyed_ssl_config]() {
- auto handle = std::make_unique<FakeProofSourceHandle>(
- proof_source_, this, select_cert_action,
- compute_signature_action, dealyed_ssl_config);
- fake_proof_source_handle_ = handle.get();
- return handle;
- }));
- }
-
- FakeProofSourceHandle* fake_proof_source_handle() {
- return fake_proof_source_handle_;
- }
-
- bool received_client_cert() const { return received_client_cert_; }
-
- using TlsServerHandshaker::AdvanceHandshake;
- using TlsServerHandshaker::expected_ssl_error;
-
- protected:
- QuicAsyncStatus VerifyCertChain(
- const std::vector<std::string>& certs, std::string* error_details,
- std::unique_ptr<ProofVerifyDetails>* details, uint8_t* out_alert,
- std::unique_ptr<ProofVerifierCallback> callback) override {
- received_client_cert_ = true;
- return TlsServerHandshaker::VerifyCertChain(certs, error_details, details,
- out_alert, std::move(callback));
- }
-
- private:
- std::unique_ptr<ProofSourceHandle> RealMaybeCreateProofSourceHandle() {
- return TlsServerHandshaker::MaybeCreateProofSourceHandle();
- }
-
- void RealOverrideQuicConfigDefaults(QuicConfig* config) {
- return TlsServerHandshaker::OverrideQuicConfigDefaults(config);
- }
-
- // Owned by TlsServerHandshaker.
- FakeProofSourceHandle* fake_proof_source_handle_ = nullptr;
- ProofSource* proof_source_ = nullptr;
- bool received_client_cert_ = false;
-};
-
-class TlsServerHandshakerTestSession : public TestQuicSpdyServerSession {
- public:
- using TestQuicSpdyServerSession::TestQuicSpdyServerSession;
-
- std::unique_ptr<QuicCryptoServerStreamBase> CreateQuicCryptoServerStream(
- const QuicCryptoServerConfig* crypto_config,
- QuicCompressedCertsCache* /*compressed_certs_cache*/) override {
- if (connection()->version().handshake_protocol == PROTOCOL_TLS1_3) {
- return std::make_unique<NiceMock<TestTlsServerHandshaker>>(this,
- crypto_config);
- }
-
- QUICHE_CHECK(false) << "Unsupported handshake protocol: "
- << connection()->version().handshake_protocol;
- return nullptr;
- }
-};
-
-class TlsServerHandshakerTest : public QuicTestWithParam<TestParams> {
- public:
- TlsServerHandshakerTest()
- : server_compressed_certs_cache_(
- QuicCompressedCertsCache::kQuicCompressedCertsCacheSize),
- server_id_(kServerHostname, kServerPort, false),
- supported_versions_({GetParam().version}) {
- SetQuicFlag(FLAGS_quic_disable_server_tls_resumption,
- GetParam().disable_resumption);
- client_crypto_config_ = std::make_unique<QuicCryptoClientConfig>(
- crypto_test_utils::ProofVerifierForTesting(),
- std::make_unique<test::SimpleSessionCache>());
- InitializeServerConfig();
- InitializeServer();
- InitializeFakeClient();
- }
-
- ~TlsServerHandshakerTest() override {
- // Ensure that anything that might reference |helpers_| is destroyed before
- // |helpers_| is destroyed.
- server_session_.reset();
- client_session_.reset();
- helpers_.clear();
- alarm_factories_.clear();
- }
-
- void InitializeServerConfig() {
- auto ticket_crypter = std::make_unique<TestTicketCrypter>();
- ticket_crypter_ = ticket_crypter.get();
- auto proof_source = std::make_unique<FakeProofSource>();
- proof_source_ = proof_source.get();
- proof_source_->SetTicketCrypter(std::move(ticket_crypter));
- server_crypto_config_ = std::make_unique<QuicCryptoServerConfig>(
- QuicCryptoServerConfig::TESTING, QuicRandom::GetInstance(),
- std::move(proof_source), KeyExchangeSource::Default());
- }
-
- void InitializeServerConfigWithFailingProofSource() {
- server_crypto_config_ = std::make_unique<QuicCryptoServerConfig>(
- QuicCryptoServerConfig::TESTING, QuicRandom::GetInstance(),
- std::make_unique<FailingProofSource>(), KeyExchangeSource::Default());
- }
-
- void CreateTlsServerHandshakerTestSession(MockQuicConnectionHelper* helper,
- MockAlarmFactory* alarm_factory) {
- server_connection_ = new PacketSavingConnection(
- helper, alarm_factory, Perspective::IS_SERVER,
- ParsedVersionOfIndex(supported_versions_, 0));
-
- TlsServerHandshakerTestSession* server_session =
- new TlsServerHandshakerTestSession(
- server_connection_, DefaultQuicConfig(), supported_versions_,
- server_crypto_config_.get(), &server_compressed_certs_cache_);
- server_session->set_client_cert_mode(initial_client_cert_mode_);
- server_session->Initialize();
-
- // We advance the clock initially because the default time is zero and the
- // strike register worries that we've just overflowed a uint32_t time.
- server_connection_->AdvanceTime(QuicTime::Delta::FromSeconds(100000));
-
- QUICHE_CHECK(server_session);
- server_session_.reset(server_session);
- }
-
- void InitializeServerWithFakeProofSourceHandle() {
- helpers_.push_back(std::make_unique<NiceMock<MockQuicConnectionHelper>>());
- alarm_factories_.push_back(std::make_unique<MockAlarmFactory>());
- CreateTlsServerHandshakerTestSession(helpers_.back().get(),
- alarm_factories_.back().get());
- server_handshaker_ = static_cast<NiceMock<TestTlsServerHandshaker>*>(
- server_session_->GetMutableCryptoStream());
- EXPECT_CALL(*server_session_->helper(), CanAcceptClientHello(_, _, _, _, _))
- .Times(testing::AnyNumber());
- EXPECT_CALL(*server_session_, SelectAlpn(_))
- .WillRepeatedly([this](const std::vector<absl::string_view>& alpns) {
- return std::find(
- alpns.cbegin(), alpns.cend(),
- AlpnForVersion(server_session_->connection()->version()));
- });
- crypto_test_utils::SetupCryptoServerConfigForTest(
- server_connection_->clock(), server_connection_->random_generator(),
- server_crypto_config_.get());
- }
-
- // Initializes the crypto server stream state for testing. May be
- // called multiple times.
- void InitializeServer() {
- TestQuicSpdyServerSession* server_session = nullptr;
- helpers_.push_back(std::make_unique<NiceMock<MockQuicConnectionHelper>>());
- alarm_factories_.push_back(std::make_unique<MockAlarmFactory>());
- CreateServerSessionForTest(
- server_id_, QuicTime::Delta::FromSeconds(100000), supported_versions_,
- helpers_.back().get(), alarm_factories_.back().get(),
- server_crypto_config_.get(), &server_compressed_certs_cache_,
- &server_connection_, &server_session);
- QUICHE_CHECK(server_session);
- server_session_.reset(server_session);
- server_handshaker_ = nullptr;
- EXPECT_CALL(*server_session_->helper(), CanAcceptClientHello(_, _, _, _, _))
- .Times(testing::AnyNumber());
- EXPECT_CALL(*server_session_, SelectAlpn(_))
- .WillRepeatedly([this](const std::vector<absl::string_view>& alpns) {
- return std::find(
- alpns.cbegin(), alpns.cend(),
- AlpnForVersion(server_session_->connection()->version()));
- });
- crypto_test_utils::SetupCryptoServerConfigForTest(
- server_connection_->clock(), server_connection_->random_generator(),
- server_crypto_config_.get());
- }
-
- QuicCryptoServerStreamBase* server_stream() {
- return server_session_->GetMutableCryptoStream();
- }
-
- QuicCryptoClientStream* client_stream() {
- return client_session_->GetMutableCryptoStream();
- }
-
- // Initializes a fake client, and all its associated state, for
- // testing. May be called multiple times.
- void InitializeFakeClient() {
- TestQuicSpdyClientSession* client_session = nullptr;
- helpers_.push_back(std::make_unique<NiceMock<MockQuicConnectionHelper>>());
- alarm_factories_.push_back(std::make_unique<MockAlarmFactory>());
- CreateClientSessionForTest(
- server_id_, QuicTime::Delta::FromSeconds(100000), supported_versions_,
- helpers_.back().get(), alarm_factories_.back().get(),
- client_crypto_config_.get(), &client_connection_, &client_session);
- const std::string default_alpn =
- AlpnForVersion(client_connection_->version());
- ON_CALL(*client_session, GetAlpnsToOffer())
- .WillByDefault(Return(std::vector<std::string>({default_alpn})));
- QUICHE_CHECK(client_session);
- client_session_.reset(client_session);
- moved_messages_counts_ = {0, 0};
- }
-
- void CompleteCryptoHandshake() {
- while (!client_stream()->one_rtt_keys_available() ||
- !server_stream()->one_rtt_keys_available()) {
- auto previous_moved_messages_counts = moved_messages_counts_;
- AdvanceHandshakeWithFakeClient();
- // Check that the handshake has made forward progress
- ASSERT_NE(previous_moved_messages_counts, moved_messages_counts_);
- }
- }
-
- // Performs a single round of handshake message-exchange between the
- // client and server.
- void AdvanceHandshakeWithFakeClient() {
- QUICHE_CHECK(server_connection_);
- QUICHE_CHECK(client_session_ != nullptr);
-
- EXPECT_CALL(*client_session_, OnProofValid(_)).Times(testing::AnyNumber());
- EXPECT_CALL(*client_session_, OnProofVerifyDetailsAvailable(_))
- .Times(testing::AnyNumber());
- EXPECT_CALL(*client_connection_, OnCanWrite()).Times(testing::AnyNumber());
- EXPECT_CALL(*server_connection_, OnCanWrite()).Times(testing::AnyNumber());
- // Call CryptoConnect if we haven't moved any client messages yet.
- if (moved_messages_counts_.first == 0) {
- client_stream()->CryptoConnect();
- }
- moved_messages_counts_ = crypto_test_utils::AdvanceHandshake(
- client_connection_, client_stream(), moved_messages_counts_.first,
- server_connection_, server_stream(), moved_messages_counts_.second);
- }
-
- void ExpectHandshakeSuccessful() {
- EXPECT_TRUE(client_stream()->one_rtt_keys_available());
- EXPECT_TRUE(client_stream()->encryption_established());
- EXPECT_TRUE(server_stream()->one_rtt_keys_available());
- EXPECT_TRUE(server_stream()->encryption_established());
- EXPECT_EQ(HANDSHAKE_COMPLETE, client_stream()->GetHandshakeState());
- EXPECT_EQ(HANDSHAKE_CONFIRMED, server_stream()->GetHandshakeState());
-
- const auto& client_crypto_params =
- client_stream()->crypto_negotiated_params();
- const auto& server_crypto_params =
- server_stream()->crypto_negotiated_params();
- // The TLS params should be filled in on the client.
- EXPECT_NE(0, client_crypto_params.cipher_suite);
- EXPECT_NE(0, client_crypto_params.key_exchange_group);
- EXPECT_NE(0, client_crypto_params.peer_signature_algorithm);
-
- // The cipher suite and key exchange group should match on the client and
- // server.
- EXPECT_EQ(client_crypto_params.cipher_suite,
- server_crypto_params.cipher_suite);
- EXPECT_EQ(client_crypto_params.key_exchange_group,
- server_crypto_params.key_exchange_group);
- // We don't support client certs on the server (yet), so the server
- // shouldn't have a peer signature algorithm to report.
- EXPECT_EQ(0, server_crypto_params.peer_signature_algorithm);
- }
-
- // Should only be called when using FakeProofSourceHandle.
- FakeProofSourceHandle::SelectCertArgs last_select_cert_args() const {
- QUICHE_CHECK(server_handshaker_ &&
- server_handshaker_->fake_proof_source_handle());
- QUICHE_CHECK(!server_handshaker_->fake_proof_source_handle()
- ->all_select_cert_args()
- .empty());
- return server_handshaker_->fake_proof_source_handle()
- ->all_select_cert_args()
- .back();
- }
-
- // Should only be called when using FakeProofSourceHandle.
- FakeProofSourceHandle::ComputeSignatureArgs last_compute_signature_args()
- const {
- QUICHE_CHECK(server_handshaker_ &&
- server_handshaker_->fake_proof_source_handle());
- QUICHE_CHECK(!server_handshaker_->fake_proof_source_handle()
- ->all_compute_signature_args()
- .empty());
- return server_handshaker_->fake_proof_source_handle()
- ->all_compute_signature_args()
- .back();
- }
-
- protected:
- // Setup the client to send a (self-signed) client cert to the server, if
- // requested. InitializeFakeClient() must be called after this to take effect.
- bool SetupClientCert() {
- auto client_proof_source = std::make_unique<DefaultClientProofSource>();
-
- CertificatePrivateKey client_cert_key(
- MakeKeyPairForSelfSignedCertificate());
-
- CertificateOptions options;
- options.subject = "CN=subject";
- options.serial_number = 0x12345678;
- options.validity_start = {2020, 1, 1, 0, 0, 0};
- options.validity_end = {2049, 12, 31, 0, 0, 0};
- std::string der_cert =
- CreateSelfSignedCertificate(*client_cert_key.private_key(), options);
-
- QuicReferenceCountedPointer<ClientProofSource::Chain> client_cert_chain(
- new ClientProofSource::Chain({der_cert}));
-
- if (!client_proof_source->AddCertAndKey({"*"}, client_cert_chain,
- std::move(client_cert_key))) {
- return false;
- }
-
- client_crypto_config_->set_proof_source(std::move(client_proof_source));
- return true;
- }
-
- // Every connection gets its own MockQuicConnectionHelper and
- // MockAlarmFactory, tracked separately from the server and client state so
- // their lifetimes persist through the whole test.
- std::vector<std::unique_ptr<MockQuicConnectionHelper>> helpers_;
- std::vector<std::unique_ptr<MockAlarmFactory>> alarm_factories_;
-
- // Server state.
- PacketSavingConnection* server_connection_;
- std::unique_ptr<TestQuicSpdyServerSession> server_session_;
- // Only set when initialized with InitializeServerWithFakeProofSourceHandle.
- NiceMock<TestTlsServerHandshaker>* server_handshaker_ = nullptr;
- TestTicketCrypter* ticket_crypter_; // owned by proof_source_
- FakeProofSource* proof_source_; // owned by server_crypto_config_
- std::unique_ptr<QuicCryptoServerConfig> server_crypto_config_;
- QuicCompressedCertsCache server_compressed_certs_cache_;
- QuicServerId server_id_;
- ClientCertMode initial_client_cert_mode_ = ClientCertMode::kNone;
-
- // Client state.
- PacketSavingConnection* client_connection_;
- std::unique_ptr<QuicCryptoClientConfig> client_crypto_config_;
- std::unique_ptr<TestQuicSpdyClientSession> client_session_;
-
- crypto_test_utils::FakeClientOptions client_options_;
- // How many handshake messages have been moved from client to server and
- // server to client.
- std::pair<size_t, size_t> moved_messages_counts_ = {0, 0};
-
- // Which QUIC versions the client and server support.
- ParsedQuicVersionVector supported_versions_;
-};
-
-INSTANTIATE_TEST_SUITE_P(TlsServerHandshakerTests,
- TlsServerHandshakerTest,
- ::testing::ValuesIn(GetTestParams()),
- ::testing::PrintToStringParamName());
-
-TEST_P(TlsServerHandshakerTest, NotInitiallyConected) {
- EXPECT_FALSE(server_stream()->encryption_established());
- EXPECT_FALSE(server_stream()->one_rtt_keys_available());
-}
-
-TEST_P(TlsServerHandshakerTest, ConnectedAfterTlsHandshake) {
- CompleteCryptoHandshake();
- EXPECT_EQ(PROTOCOL_TLS1_3, server_stream()->handshake_protocol());
- ExpectHandshakeSuccessful();
-}
-
-TEST_P(TlsServerHandshakerTest, HandshakeWithAsyncSelectCertSuccess) {
- InitializeServerWithFakeProofSourceHandle();
- server_handshaker_->SetupProofSourceHandle(
- /*select_cert_action=*/FakeProofSourceHandle::Action::DELEGATE_ASYNC,
- /*compute_signature_action=*/FakeProofSourceHandle::Action::
- DELEGATE_SYNC);
-
- EXPECT_CALL(*client_connection_, CloseConnection(_, _, _)).Times(0);
- EXPECT_CALL(*server_connection_, CloseConnection(_, _, _)).Times(0);
-
- // Start handshake.
- AdvanceHandshakeWithFakeClient();
-
- ASSERT_TRUE(
- server_handshaker_->fake_proof_source_handle()->HasPendingOperation());
- server_handshaker_->fake_proof_source_handle()->CompletePendingOperation();
-
- CompleteCryptoHandshake();
-
- ExpectHandshakeSuccessful();
-}
-
-TEST_P(TlsServerHandshakerTest, HandshakeWithAsyncSelectCertFailure) {
- InitializeServerWithFakeProofSourceHandle();
- server_handshaker_->SetupProofSourceHandle(
- /*select_cert_action=*/FakeProofSourceHandle::Action::FAIL_ASYNC,
- /*compute_signature_action=*/FakeProofSourceHandle::Action::
- DELEGATE_SYNC);
-
- // Start handshake.
- AdvanceHandshakeWithFakeClient();
-
- ASSERT_TRUE(
- server_handshaker_->fake_proof_source_handle()->HasPendingOperation());
- server_handshaker_->fake_proof_source_handle()->CompletePendingOperation();
-
- // Check that the server didn't send any handshake messages, because it failed
- // to handshake.
- EXPECT_EQ(moved_messages_counts_.second, 0u);
-}
-
-TEST_P(TlsServerHandshakerTest, HandshakeWithAsyncSelectCertAndSignature) {
- InitializeServerWithFakeProofSourceHandle();
- server_handshaker_->SetupProofSourceHandle(
- /*select_cert_action=*/FakeProofSourceHandle::Action::DELEGATE_ASYNC,
- /*compute_signature_action=*/FakeProofSourceHandle::Action::
- DELEGATE_ASYNC);
-
- EXPECT_CALL(*client_connection_, CloseConnection(_, _, _)).Times(0);
- EXPECT_CALL(*server_connection_, CloseConnection(_, _, _)).Times(0);
-
- // Start handshake.
- AdvanceHandshakeWithFakeClient();
-
- // A select cert operation is now pending.
- ASSERT_TRUE(
- server_handshaker_->fake_proof_source_handle()->HasPendingOperation());
- EXPECT_EQ(server_handshaker_->expected_ssl_error(),
- SSL_ERROR_PENDING_CERTIFICATE);
-
- // Complete the pending select cert. It should advance the handshake to
- // compute a signature, which will also be saved as a pending operation.
- server_handshaker_->fake_proof_source_handle()->CompletePendingOperation();
-
- // A compute signature operation is now pending.
- ASSERT_TRUE(
- server_handshaker_->fake_proof_source_handle()->HasPendingOperation());
- EXPECT_EQ(server_handshaker_->expected_ssl_error(),
- SSL_ERROR_WANT_PRIVATE_KEY_OPERATION);
-
- server_handshaker_->fake_proof_source_handle()->CompletePendingOperation();
-
- CompleteCryptoHandshake();
-
- ExpectHandshakeSuccessful();
-}
-
-TEST_P(TlsServerHandshakerTest, HandshakeWithAsyncSignature) {
- EXPECT_CALL(*client_connection_, CloseConnection(_, _, _)).Times(0);
- EXPECT_CALL(*server_connection_, CloseConnection(_, _, _)).Times(0);
- // Enable FakeProofSource to capture call to ComputeTlsSignature and run it
- // asynchronously.
- proof_source_->Activate();
-
- // Start handshake.
- AdvanceHandshakeWithFakeClient();
-
- ASSERT_EQ(proof_source_->NumPendingCallbacks(), 1);
- proof_source_->InvokePendingCallback(0);
-
- CompleteCryptoHandshake();
-
- ExpectHandshakeSuccessful();
-}
-
-TEST_P(TlsServerHandshakerTest, CancelPendingSelectCert) {
- InitializeServerWithFakeProofSourceHandle();
- server_handshaker_->SetupProofSourceHandle(
- /*select_cert_action=*/FakeProofSourceHandle::Action::DELEGATE_ASYNC,
- /*compute_signature_action=*/FakeProofSourceHandle::Action::
- DELEGATE_SYNC);
-
- EXPECT_CALL(*client_connection_, CloseConnection(_, _, _)).Times(0);
- EXPECT_CALL(*server_connection_, CloseConnection(_, _, _)).Times(0);
-
- // Start handshake.
- AdvanceHandshakeWithFakeClient();
-
- ASSERT_TRUE(
- server_handshaker_->fake_proof_source_handle()->HasPendingOperation());
- server_handshaker_->CancelOutstandingCallbacks();
- ASSERT_FALSE(
- server_handshaker_->fake_proof_source_handle()->HasPendingOperation());
- // CompletePendingOperation should be noop.
- server_handshaker_->fake_proof_source_handle()->CompletePendingOperation();
-}
-
-TEST_P(TlsServerHandshakerTest, CancelPendingSignature) {
- EXPECT_CALL(*client_connection_, CloseConnection(_, _, _)).Times(0);
- EXPECT_CALL(*server_connection_, CloseConnection(_, _, _)).Times(0);
- // Enable FakeProofSource to capture call to ComputeTlsSignature and run it
- // asynchronously.
- proof_source_->Activate();
-
- // Start handshake.
- AdvanceHandshakeWithFakeClient();
-
- ASSERT_EQ(proof_source_->NumPendingCallbacks(), 1);
- server_session_ = nullptr;
-
- proof_source_->InvokePendingCallback(0);
-}
-
-TEST_P(TlsServerHandshakerTest, ExtractSNI) {
- CompleteCryptoHandshake();
- ExpectHandshakeSuccessful();
-
- EXPECT_EQ(server_stream()->crypto_negotiated_params().sni,
- "test.example.com");
-}
-
-TEST_P(TlsServerHandshakerTest, HostnameForCertSelectionAndComputeSignature) {
- // Client uses upper case letters in hostname. It is considered valid by
- // QuicHostnameUtils::IsValidSNI, but it should be normalized for cert
- // selection.
- server_id_ = QuicServerId("tEsT.EXAMPLE.CoM", kServerPort, false);
- InitializeServerWithFakeProofSourceHandle();
- server_handshaker_->SetupProofSourceHandle(
- /*select_cert_action=*/FakeProofSourceHandle::Action::DELEGATE_SYNC,
- /*compute_signature_action=*/FakeProofSourceHandle::Action::
- DELEGATE_SYNC);
- InitializeFakeClient();
- CompleteCryptoHandshake();
- ExpectHandshakeSuccessful();
-
- EXPECT_EQ(server_stream()->crypto_negotiated_params().sni,
- "test.example.com");
-
- EXPECT_EQ(last_select_cert_args().hostname, "test.example.com");
- EXPECT_EQ(last_compute_signature_args().hostname, "test.example.com");
-}
-
-TEST_P(TlsServerHandshakerTest, SSLConfigForCertSelection) {
- InitializeServerWithFakeProofSourceHandle();
-
- // Disable early data.
- server_session_->set_early_data_enabled(false);
-
- server_handshaker_->SetupProofSourceHandle(
- /*select_cert_action=*/FakeProofSourceHandle::Action::DELEGATE_SYNC,
- /*compute_signature_action=*/FakeProofSourceHandle::Action::
- DELEGATE_SYNC);
- InitializeFakeClient();
- CompleteCryptoHandshake();
- ExpectHandshakeSuccessful();
-
- EXPECT_FALSE(last_select_cert_args().ssl_config.early_data_enabled);
-}
-
-TEST_P(TlsServerHandshakerTest, ConnectionClosedOnTlsError) {
- EXPECT_CALL(*server_connection_,
- CloseConnection(QUIC_HANDSHAKE_FAILED, _, _, _));
-
- // Send a zero-length ClientHello from client to server.
- char bogus_handshake_message[] = {
- // Handshake struct (RFC 8446 appendix B.3)
- 1, // HandshakeType client_hello
- 0, 0, 0, // uint24 length
- };
-
- // Install a packet flusher such that the packets generated by
- // |server_connection_| in response to this handshake message are more likely
- // to be coalesced and/or batched in the writer.
- //
- // This is required by TlsServerHandshaker because without the flusher, it
- // tends to generate many small, uncoalesced packets, one per
- // TlsHandshaker::WriteMessage.
- QuicConnection::ScopedPacketFlusher flusher(server_connection_);
- server_stream()->crypto_message_parser()->ProcessInput(
- absl::string_view(bogus_handshake_message,
- ABSL_ARRAYSIZE(bogus_handshake_message)),
- ENCRYPTION_INITIAL);
-
- EXPECT_FALSE(server_stream()->one_rtt_keys_available());
-}
-
-TEST_P(TlsServerHandshakerTest, ClientSendingBadALPN) {
- const std::string kTestBadClientAlpn = "bad-client-alpn";
- EXPECT_CALL(*client_session_, GetAlpnsToOffer())
- .WillOnce(Return(std::vector<std::string>({kTestBadClientAlpn})));
-
- EXPECT_CALL(*server_connection_,
- CloseConnection(QUIC_HANDSHAKE_FAILED,
- static_cast<QuicIetfTransportErrorCodes>(
- CRYPTO_ERROR_FIRST + 120),
- "TLS handshake failure (ENCRYPTION_INITIAL) 120: "
- "no application protocol",
- _));
-
- AdvanceHandshakeWithFakeClient();
-
- EXPECT_FALSE(client_stream()->one_rtt_keys_available());
- EXPECT_FALSE(client_stream()->encryption_established());
- EXPECT_FALSE(server_stream()->one_rtt_keys_available());
- EXPECT_FALSE(server_stream()->encryption_established());
-}
-
-TEST_P(TlsServerHandshakerTest, CustomALPNNegotiation) {
- EXPECT_CALL(*client_connection_, CloseConnection(_, _, _)).Times(0);
- EXPECT_CALL(*server_connection_, CloseConnection(_, _, _)).Times(0);
-
- const std::string kTestAlpn = "A Custom ALPN Value";
- const std::vector<std::string> kTestAlpns(
- {"foo", "bar", kTestAlpn, "something else"});
- EXPECT_CALL(*client_session_, GetAlpnsToOffer())
- .WillRepeatedly(Return(kTestAlpns));
- EXPECT_CALL(*server_session_, SelectAlpn(_))
- .WillOnce(
- [kTestAlpn, kTestAlpns](const std::vector<absl::string_view>& alpns) {
- EXPECT_THAT(alpns, testing::ElementsAreArray(kTestAlpns));
- return std::find(alpns.cbegin(), alpns.cend(), kTestAlpn);
- });
- EXPECT_CALL(*client_session_, OnAlpnSelected(absl::string_view(kTestAlpn)));
- EXPECT_CALL(*server_session_, OnAlpnSelected(absl::string_view(kTestAlpn)));
-
- CompleteCryptoHandshake();
- ExpectHandshakeSuccessful();
-}
-
-TEST_P(TlsServerHandshakerTest, RejectInvalidSNI) {
- server_id_ = QuicServerId("invalid!.example.com", kServerPort, false);
- InitializeFakeClient();
- static_cast<TlsClientHandshaker*>(
- QuicCryptoClientStreamPeer::GetHandshaker(client_stream()))
- ->AllowInvalidSNIForTests();
-
- // Run the handshake and expect it to fail.
- AdvanceHandshakeWithFakeClient();
- EXPECT_FALSE(server_stream()->encryption_established());
- EXPECT_FALSE(server_stream()->one_rtt_keys_available());
-}
-
-TEST_P(TlsServerHandshakerTest, Resumption) {
- // Do the first handshake
- InitializeFakeClient();
- CompleteCryptoHandshake();
- ExpectHandshakeSuccessful();
- EXPECT_FALSE(client_stream()->IsResumption());
- EXPECT_FALSE(server_stream()->IsResumption());
- EXPECT_FALSE(server_stream()->ResumptionAttempted());
-
- // Now do another handshake
- InitializeServer();
- InitializeFakeClient();
- CompleteCryptoHandshake();
- ExpectHandshakeSuccessful();
- EXPECT_NE(client_stream()->IsResumption(), GetParam().disable_resumption);
- EXPECT_NE(server_stream()->IsResumption(), GetParam().disable_resumption);
- EXPECT_NE(server_stream()->ResumptionAttempted(),
- GetParam().disable_resumption);
-}
-
-TEST_P(TlsServerHandshakerTest, ResumptionWithAsyncDecryptCallback) {
- // Do the first handshake
- InitializeFakeClient();
- CompleteCryptoHandshake();
- ExpectHandshakeSuccessful();
-
- ticket_crypter_->SetRunCallbacksAsync(true);
- // Now do another handshake
- InitializeServer();
- InitializeFakeClient();
-
- AdvanceHandshakeWithFakeClient();
- if (GetParam().disable_resumption) {
- ASSERT_EQ(ticket_crypter_->NumPendingCallbacks(), 0u);
- return;
- }
- // Test that the DecryptCallback will be run asynchronously, and then run it.
- ASSERT_EQ(ticket_crypter_->NumPendingCallbacks(), 1u);
- ticket_crypter_->RunPendingCallback(0);
-
- CompleteCryptoHandshake();
- ExpectHandshakeSuccessful();
- EXPECT_TRUE(client_stream()->IsResumption());
- EXPECT_TRUE(server_stream()->IsResumption());
- EXPECT_TRUE(server_stream()->ResumptionAttempted());
-}
-
-TEST_P(TlsServerHandshakerTest, AdvanceHandshakeDuringAsyncDecryptCallback) {
- if (GetParam().disable_resumption) {
- return;
- }
-
- // Do the first handshake
- InitializeFakeClient();
- CompleteCryptoHandshake();
- ExpectHandshakeSuccessful();
-
- ticket_crypter_->SetRunCallbacksAsync(true);
- // Now do another handshake
- InitializeServerWithFakeProofSourceHandle();
- server_handshaker_->SetupProofSourceHandle(
- /*select_cert_action=*/FakeProofSourceHandle::Action::DELEGATE_SYNC,
- /*compute_signature_action=*/FakeProofSourceHandle::Action::
- DELEGATE_SYNC);
- InitializeFakeClient();
-
- AdvanceHandshakeWithFakeClient();
-
- // Ensure an async DecryptCallback is now pending.
- ASSERT_EQ(ticket_crypter_->NumPendingCallbacks(), 1u);
-
- {
- QuicConnection::ScopedPacketFlusher flusher(server_connection_);
- server_handshaker_->AdvanceHandshake();
- }
-
- // This will delete |server_handshaker_|.
- server_session_ = nullptr;
-
- ticket_crypter_->RunPendingCallback(0); // Should not crash.
-}
-
-TEST_P(TlsServerHandshakerTest, ResumptionWithFailingDecryptCallback) {
- if (GetParam().disable_resumption) {
- return;
- }
-
- // Do the first handshake
- InitializeFakeClient();
- CompleteCryptoHandshake();
- ExpectHandshakeSuccessful();
-
- ticket_crypter_->set_fail_decrypt(true);
- // Now do another handshake
- InitializeServer();
- InitializeFakeClient();
- CompleteCryptoHandshake();
- ExpectHandshakeSuccessful();
- EXPECT_FALSE(client_stream()->IsResumption());
- EXPECT_FALSE(server_stream()->IsResumption());
- EXPECT_TRUE(server_stream()->ResumptionAttempted());
-}
-
-TEST_P(TlsServerHandshakerTest, ResumptionWithFailingAsyncDecryptCallback) {
- if (GetParam().disable_resumption) {
- return;
- }
-
- // Do the first handshake
- InitializeFakeClient();
- CompleteCryptoHandshake();
- ExpectHandshakeSuccessful();
-
- ticket_crypter_->set_fail_decrypt(true);
- ticket_crypter_->SetRunCallbacksAsync(true);
- // Now do another handshake
- InitializeServer();
- InitializeFakeClient();
-
- AdvanceHandshakeWithFakeClient();
- // Test that the DecryptCallback will be run asynchronously, and then run it.
- ASSERT_EQ(ticket_crypter_->NumPendingCallbacks(), 1u);
- ticket_crypter_->RunPendingCallback(0);
-
- CompleteCryptoHandshake();
- ExpectHandshakeSuccessful();
- EXPECT_FALSE(client_stream()->IsResumption());
- EXPECT_FALSE(server_stream()->IsResumption());
- EXPECT_TRUE(server_stream()->ResumptionAttempted());
-}
-
-TEST_P(TlsServerHandshakerTest, HandshakeFailsWithFailingProofSource) {
- InitializeServerConfigWithFailingProofSource();
- InitializeServer();
- InitializeFakeClient();
-
- // Attempt handshake.
- AdvanceHandshakeWithFakeClient();
- // Check that the server didn't send any handshake messages, because it failed
- // to handshake.
- EXPECT_EQ(moved_messages_counts_.second, 0u);
-}
-
-TEST_P(TlsServerHandshakerTest, ZeroRttResumption) {
- std::vector<uint8_t> application_state = {0, 1, 2, 3};
-
- // Do the first handshake
- server_stream()->SetServerApplicationStateForResumption(
- std::make_unique<ApplicationState>(application_state));
- InitializeFakeClient();
- CompleteCryptoHandshake();
- ExpectHandshakeSuccessful();
- EXPECT_FALSE(client_stream()->IsResumption());
- EXPECT_FALSE(server_stream()->IsZeroRtt());
-
- // Now do another handshake
- InitializeServer();
- server_stream()->SetServerApplicationStateForResumption(
- std::make_unique<ApplicationState>(application_state));
- InitializeFakeClient();
- CompleteCryptoHandshake();
- ExpectHandshakeSuccessful();
- EXPECT_NE(client_stream()->IsResumption(), GetParam().disable_resumption);
- EXPECT_NE(server_stream()->IsZeroRtt(), GetParam().disable_resumption);
-}
-
-TEST_P(TlsServerHandshakerTest, ZeroRttRejectOnApplicationStateChange) {
- std::vector<uint8_t> original_application_state = {1, 2};
- std::vector<uint8_t> new_application_state = {3, 4};
-
- // Do the first handshake
- server_stream()->SetServerApplicationStateForResumption(
- std::make_unique<ApplicationState>(original_application_state));
- InitializeFakeClient();
- CompleteCryptoHandshake();
- ExpectHandshakeSuccessful();
- EXPECT_FALSE(client_stream()->IsResumption());
- EXPECT_FALSE(server_stream()->IsZeroRtt());
-
- // Do another handshake, but change the application state
- InitializeServer();
- server_stream()->SetServerApplicationStateForResumption(
- std::make_unique<ApplicationState>(new_application_state));
- InitializeFakeClient();
- CompleteCryptoHandshake();
- ExpectHandshakeSuccessful();
- EXPECT_NE(client_stream()->IsResumption(), GetParam().disable_resumption);
- EXPECT_FALSE(server_stream()->IsZeroRtt());
-}
-
-TEST_P(TlsServerHandshakerTest, RequestClientCert) {
- ASSERT_TRUE(SetupClientCert());
- InitializeFakeClient();
-
- initial_client_cert_mode_ = ClientCertMode::kRequest;
- InitializeServerWithFakeProofSourceHandle();
- server_handshaker_->SetupProofSourceHandle(
- /*select_cert_action=*/FakeProofSourceHandle::Action::DELEGATE_SYNC,
- /*compute_signature_action=*/FakeProofSourceHandle::Action::
- DELEGATE_SYNC);
-
- 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());
- }
-}
-
-TEST_P(TlsServerHandshakerTest, RequestClientCertByDelayedSslConfig) {
- ASSERT_TRUE(SetupClientCert());
- InitializeFakeClient();
-
- QuicDelayedSSLConfig delayed_ssl_config;
- delayed_ssl_config.client_cert_mode = ClientCertMode::kRequest;
- InitializeServerWithFakeProofSourceHandle();
- server_handshaker_->SetupProofSourceHandle(
- /*select_cert_action=*/FakeProofSourceHandle::Action::DELEGATE_ASYNC,
- /*compute_signature_action=*/FakeProofSourceHandle::Action::DELEGATE_SYNC,
- delayed_ssl_config);
-
- AdvanceHandshakeWithFakeClient();
- ASSERT_TRUE(
- server_handshaker_->fake_proof_source_handle()->HasPendingOperation());
- server_handshaker_->fake_proof_source_handle()->CompletePendingOperation();
-
- 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());
- }
-}
-
-TEST_P(TlsServerHandshakerTest, RequestClientCert_NoCert) {
- initial_client_cert_mode_ = ClientCertMode::kRequest;
- InitializeServerWithFakeProofSourceHandle();
- server_handshaker_->SetupProofSourceHandle(
- /*select_cert_action=*/FakeProofSourceHandle::Action::DELEGATE_SYNC,
- /*compute_signature_action=*/FakeProofSourceHandle::Action::
- DELEGATE_SYNC);
-
- CompleteCryptoHandshake();
- ExpectHandshakeSuccessful();
- EXPECT_FALSE(server_handshaker_->received_client_cert());
-}
-
-TEST_P(TlsServerHandshakerTest, RequestAndRequireClientCert) {
- ASSERT_TRUE(SetupClientCert());
- InitializeFakeClient();
-
- initial_client_cert_mode_ = ClientCertMode::kRequire;
- InitializeServerWithFakeProofSourceHandle();
- server_handshaker_->SetupProofSourceHandle(
- /*select_cert_action=*/FakeProofSourceHandle::Action::DELEGATE_SYNC,
- /*compute_signature_action=*/FakeProofSourceHandle::Action::
- DELEGATE_SYNC);
-
- 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());
- }
-}
-
-TEST_P(TlsServerHandshakerTest, RequestAndRequireClientCertByDelayedSslConfig) {
- ASSERT_TRUE(SetupClientCert());
- InitializeFakeClient();
-
- QuicDelayedSSLConfig delayed_ssl_config;
- delayed_ssl_config.client_cert_mode = ClientCertMode::kRequire;
- InitializeServerWithFakeProofSourceHandle();
- server_handshaker_->SetupProofSourceHandle(
- /*select_cert_action=*/FakeProofSourceHandle::Action::DELEGATE_ASYNC,
- /*compute_signature_action=*/FakeProofSourceHandle::Action::DELEGATE_SYNC,
- delayed_ssl_config);
-
- AdvanceHandshakeWithFakeClient();
- ASSERT_TRUE(
- server_handshaker_->fake_proof_source_handle()->HasPendingOperation());
- server_handshaker_->fake_proof_source_handle()->CompletePendingOperation();
-
- 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());
- }
-}
-
-TEST_P(TlsServerHandshakerTest, RequestAndRequireClientCert_NoCert) {
- initial_client_cert_mode_ = ClientCertMode::kRequire;
- InitializeServerWithFakeProofSourceHandle();
- server_handshaker_->SetupProofSourceHandle(
- /*select_cert_action=*/FakeProofSourceHandle::Action::DELEGATE_SYNC,
- /*compute_signature_action=*/FakeProofSourceHandle::Action::
- DELEGATE_SYNC);
-
- if (GetQuicRestartFlag(quic_tls_server_support_client_cert)) {
- EXPECT_CALL(*server_connection_,
- CloseConnection(QUIC_TLS_CERTIFICATE_REQUIRED, _, _, _));
- }
- AdvanceHandshakeWithFakeClient();
- AdvanceHandshakeWithFakeClient();
- EXPECT_FALSE(server_handshaker_->received_client_cert());
-}
-
-TEST_P(TlsServerHandshakerTest, CloseConnectionBeforeSelectCert) {
- InitializeServerWithFakeProofSourceHandle();
- server_handshaker_->SetupProofSourceHandle(
- /*select_cert_action=*/FakeProofSourceHandle::Action::
- FAIL_SYNC_DO_NOT_CHECK_CLOSED,
- /*compute_signature_action=*/FakeProofSourceHandle::Action::
- FAIL_SYNC_DO_NOT_CHECK_CLOSED);
-
- EXPECT_CALL(*server_handshaker_, OverrideQuicConfigDefaults(_))
- .WillOnce(testing::Invoke([](QuicConfig* config) {
- QuicConfigPeer::SetReceivedMaxUnidirectionalStreams(config,
- /*max_streams=*/0);
- }));
-
- EXPECT_CALL(*server_connection_,
- CloseConnection(QUIC_ZERO_RTT_RESUMPTION_LIMIT_REDUCED, _, _))
- .WillOnce(testing::Invoke(
- [this](QuicErrorCode error, const std::string& details,
- ConnectionCloseBehavior connection_close_behavior) {
- server_connection_->ReallyCloseConnection(
- error, details, connection_close_behavior);
- ASSERT_FALSE(server_connection_->connected());
- }));
-
- AdvanceHandshakeWithFakeClient();
- if (!GetQuicReloadableFlag(quic_tls_no_select_cert_if_disconnected)) {
- // SelectCertificate is called when flag is false.
- EXPECT_FALSE(server_handshaker_->fake_proof_source_handle()
- ->all_select_cert_args()
- .empty());
- return;
- }
-
- EXPECT_TRUE(server_handshaker_->fake_proof_source_handle()
- ->all_select_cert_args()
- .empty());
-}
-
-} // namespace
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/uber_quic_stream_id_manager.cc b/chromium/net/third_party/quiche/src/quic/core/uber_quic_stream_id_manager.cc
deleted file mode 100644
index 4cf55bcd9db..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/uber_quic_stream_id_manager.cc
+++ /dev/null
@@ -1,176 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/uber_quic_stream_id_manager.h"
-
-#include "quic/core/quic_session.h"
-#include "quic/core/quic_utils.h"
-
-namespace quic {
-
-UberQuicStreamIdManager::UberQuicStreamIdManager(
- Perspective perspective,
- ParsedQuicVersion version,
- QuicStreamIdManager::DelegateInterface* delegate,
- QuicStreamCount max_open_outgoing_bidirectional_streams,
- QuicStreamCount max_open_outgoing_unidirectional_streams,
- QuicStreamCount max_open_incoming_bidirectional_streams,
- QuicStreamCount max_open_incoming_unidirectional_streams)
- : version_(version),
- bidirectional_stream_id_manager_(delegate,
- /*unidirectional=*/false,
- perspective,
- version,
- max_open_outgoing_bidirectional_streams,
- max_open_incoming_bidirectional_streams),
- unidirectional_stream_id_manager_(
- delegate,
- /*unidirectional=*/true,
- perspective,
- version,
- max_open_outgoing_unidirectional_streams,
- max_open_incoming_unidirectional_streams) {}
-
-bool UberQuicStreamIdManager::MaybeAllowNewOutgoingBidirectionalStreams(
- QuicStreamCount max_open_streams) {
- return bidirectional_stream_id_manager_.MaybeAllowNewOutgoingStreams(
- max_open_streams);
-}
-bool UberQuicStreamIdManager::MaybeAllowNewOutgoingUnidirectionalStreams(
- QuicStreamCount max_open_streams) {
- return unidirectional_stream_id_manager_.MaybeAllowNewOutgoingStreams(
- max_open_streams);
-}
-void UberQuicStreamIdManager::SetMaxOpenIncomingBidirectionalStreams(
- QuicStreamCount max_open_streams) {
- bidirectional_stream_id_manager_.SetMaxOpenIncomingStreams(max_open_streams);
-}
-void UberQuicStreamIdManager::SetMaxOpenIncomingUnidirectionalStreams(
- QuicStreamCount max_open_streams) {
- unidirectional_stream_id_manager_.SetMaxOpenIncomingStreams(max_open_streams);
-}
-
-bool UberQuicStreamIdManager::CanOpenNextOutgoingBidirectionalStream() const {
- return bidirectional_stream_id_manager_.CanOpenNextOutgoingStream();
-}
-
-bool UberQuicStreamIdManager::CanOpenNextOutgoingUnidirectionalStream() const {
- return unidirectional_stream_id_manager_.CanOpenNextOutgoingStream();
-}
-
-QuicStreamId UberQuicStreamIdManager::GetNextOutgoingBidirectionalStreamId() {
- return bidirectional_stream_id_manager_.GetNextOutgoingStreamId();
-}
-
-QuicStreamId UberQuicStreamIdManager::GetNextOutgoingUnidirectionalStreamId() {
- return unidirectional_stream_id_manager_.GetNextOutgoingStreamId();
-}
-
-bool UberQuicStreamIdManager::MaybeIncreaseLargestPeerStreamId(
- QuicStreamId id,
- std::string* error_details) {
- if (QuicUtils::IsBidirectionalStreamId(id, version_)) {
- return bidirectional_stream_id_manager_.MaybeIncreaseLargestPeerStreamId(
- id, error_details);
- }
- return unidirectional_stream_id_manager_.MaybeIncreaseLargestPeerStreamId(
- id, error_details);
-}
-
-void UberQuicStreamIdManager::OnStreamClosed(QuicStreamId id) {
- if (QuicUtils::IsBidirectionalStreamId(id, version_)) {
- bidirectional_stream_id_manager_.OnStreamClosed(id);
- return;
- }
- unidirectional_stream_id_manager_.OnStreamClosed(id);
-}
-
-bool UberQuicStreamIdManager::OnStreamsBlockedFrame(
- const QuicStreamsBlockedFrame& frame,
- std::string* error_details) {
- if (frame.unidirectional) {
- return unidirectional_stream_id_manager_.OnStreamsBlockedFrame(
- frame, error_details);
- }
- return bidirectional_stream_id_manager_.OnStreamsBlockedFrame(frame,
- error_details);
-}
-
-bool UberQuicStreamIdManager::IsAvailableStream(QuicStreamId id) const {
- if (QuicUtils::IsBidirectionalStreamId(id, version_)) {
- return bidirectional_stream_id_manager_.IsAvailableStream(id);
- }
- return unidirectional_stream_id_manager_.IsAvailableStream(id);
-}
-
-QuicStreamCount
-UberQuicStreamIdManager::GetMaxAllowdIncomingBidirectionalStreams() const {
- return bidirectional_stream_id_manager_.incoming_initial_max_open_streams();
-}
-
-QuicStreamCount
-UberQuicStreamIdManager::GetMaxAllowdIncomingUnidirectionalStreams() const {
- return unidirectional_stream_id_manager_.incoming_initial_max_open_streams();
-}
-
-QuicStreamId UberQuicStreamIdManager::GetLargestPeerCreatedStreamId(
- bool unidirectional) const {
- if (unidirectional) {
- return unidirectional_stream_id_manager_.largest_peer_created_stream_id();
- }
- return bidirectional_stream_id_manager_.largest_peer_created_stream_id();
-}
-
-QuicStreamId UberQuicStreamIdManager::next_outgoing_bidirectional_stream_id()
- const {
- return bidirectional_stream_id_manager_.next_outgoing_stream_id();
-}
-
-QuicStreamId UberQuicStreamIdManager::next_outgoing_unidirectional_stream_id()
- const {
- return unidirectional_stream_id_manager_.next_outgoing_stream_id();
-}
-
-QuicStreamCount UberQuicStreamIdManager::max_outgoing_bidirectional_streams()
- const {
- return bidirectional_stream_id_manager_.outgoing_max_streams();
-}
-
-QuicStreamCount UberQuicStreamIdManager::max_outgoing_unidirectional_streams()
- const {
- return unidirectional_stream_id_manager_.outgoing_max_streams();
-}
-
-QuicStreamCount UberQuicStreamIdManager::max_incoming_bidirectional_streams()
- const {
- return bidirectional_stream_id_manager_.incoming_actual_max_streams();
-}
-
-QuicStreamCount UberQuicStreamIdManager::max_incoming_unidirectional_streams()
- const {
- return unidirectional_stream_id_manager_.incoming_actual_max_streams();
-}
-
-QuicStreamCount
-UberQuicStreamIdManager::advertised_max_incoming_bidirectional_streams() const {
- return bidirectional_stream_id_manager_.incoming_advertised_max_streams();
-}
-
-QuicStreamCount
-UberQuicStreamIdManager::advertised_max_incoming_unidirectional_streams()
- const {
- return unidirectional_stream_id_manager_.incoming_advertised_max_streams();
-}
-
-QuicStreamCount UberQuicStreamIdManager::outgoing_bidirectional_stream_count()
- const {
- return bidirectional_stream_id_manager_.outgoing_stream_count();
-}
-
-QuicStreamCount UberQuicStreamIdManager::outgoing_unidirectional_stream_count()
- const {
- return unidirectional_stream_id_manager_.outgoing_stream_count();
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/uber_quic_stream_id_manager.h b/chromium/net/third_party/quiche/src/quic/core/uber_quic_stream_id_manager.h
deleted file mode 100644
index 67ab7a05509..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/uber_quic_stream_id_manager.h
+++ /dev/null
@@ -1,107 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_UBER_QUIC_STREAM_ID_MANAGER_H_
-#define QUICHE_QUIC_CORE_UBER_QUIC_STREAM_ID_MANAGER_H_
-
-#include "quic/core/quic_stream_id_manager.h"
-#include "quic/core/quic_types.h"
-
-namespace quic {
-
-namespace test {
-class QuicSessionPeer;
-class UberQuicStreamIdManagerPeer;
-} // namespace test
-
-class QuicSession;
-
-// This class comprises two QuicStreamIdManagers, which manage bidirectional and
-// unidirectional stream IDs, respectively.
-class QUIC_EXPORT_PRIVATE UberQuicStreamIdManager {
- public:
- UberQuicStreamIdManager(
- Perspective perspective,
- ParsedQuicVersion version,
- QuicStreamIdManager::DelegateInterface* delegate,
- QuicStreamCount max_open_outgoing_bidirectional_streams,
- QuicStreamCount max_open_outgoing_unidirectional_streams,
- QuicStreamCount max_open_incoming_bidirectional_streams,
- QuicStreamCount max_open_incoming_unidirectional_streams);
-
- // Called on |max_open_streams| outgoing streams can be created because of 1)
- // config negotiated or 2) MAX_STREAMS received. Returns true if new
- // streams can be created.
- bool MaybeAllowNewOutgoingBidirectionalStreams(
- QuicStreamCount max_open_streams);
- bool MaybeAllowNewOutgoingUnidirectionalStreams(
- QuicStreamCount max_open_streams);
-
- // Sets the limits to max_open_streams.
- void SetMaxOpenIncomingBidirectionalStreams(QuicStreamCount max_open_streams);
- void SetMaxOpenIncomingUnidirectionalStreams(
- QuicStreamCount max_open_streams);
-
- // Returns true if next outgoing bidirectional stream ID can be allocated.
- bool CanOpenNextOutgoingBidirectionalStream() const;
-
- // Returns true if next outgoing unidirectional stream ID can be allocated.
- bool CanOpenNextOutgoingUnidirectionalStream() const;
-
- // Returns the next outgoing bidirectional stream id.
- QuicStreamId GetNextOutgoingBidirectionalStreamId();
-
- // Returns the next outgoing unidirectional stream id.
- QuicStreamId GetNextOutgoingUnidirectionalStreamId();
-
- // Returns true if the incoming |id| is within the limit.
- bool MaybeIncreaseLargestPeerStreamId(QuicStreamId id,
- std::string* error_details);
-
- // Called when |id| is released.
- void OnStreamClosed(QuicStreamId id);
-
- // Called when a STREAMS_BLOCKED frame is received.
- bool OnStreamsBlockedFrame(const QuicStreamsBlockedFrame& frame,
- std::string* error_details);
-
- // Returns true if |id| is still available.
- bool IsAvailableStream(QuicStreamId id) const;
-
- QuicStreamCount GetMaxAllowdIncomingBidirectionalStreams() const;
-
- QuicStreamCount GetMaxAllowdIncomingUnidirectionalStreams() const;
-
- QuicStreamId GetLargestPeerCreatedStreamId(bool unidirectional) const;
-
- QuicStreamId next_outgoing_bidirectional_stream_id() const;
- QuicStreamId next_outgoing_unidirectional_stream_id() const;
-
- QuicStreamCount max_outgoing_bidirectional_streams() const;
- QuicStreamCount max_outgoing_unidirectional_streams() const;
-
- QuicStreamCount max_incoming_bidirectional_streams() const;
- QuicStreamCount max_incoming_unidirectional_streams() const;
-
- QuicStreamCount advertised_max_incoming_bidirectional_streams() const;
- QuicStreamCount advertised_max_incoming_unidirectional_streams() const;
-
- QuicStreamCount outgoing_bidirectional_stream_count() const;
- QuicStreamCount outgoing_unidirectional_stream_count() const;
-
- private:
- friend class test::QuicSessionPeer;
- friend class test::UberQuicStreamIdManagerPeer;
-
- ParsedQuicVersion version_;
- // Manages stream IDs of bidirectional streams.
- QuicStreamIdManager bidirectional_stream_id_manager_;
-
- // Manages stream IDs of unidirectional streams.
- QuicStreamIdManager unidirectional_stream_id_manager_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_UBER_QUIC_STREAM_ID_MANAGER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/uber_quic_stream_id_manager_test.cc b/chromium/net/third_party/quiche/src/quic/core/uber_quic_stream_id_manager_test.cc
deleted file mode 100644
index 8f2b59093df..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/uber_quic_stream_id_manager_test.cc
+++ /dev/null
@@ -1,340 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/uber_quic_stream_id_manager.h"
-
-#include "quic/core/quic_utils.h"
-#include "quic/core/quic_versions.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/quic_stream_id_manager_peer.h"
-#include "quic/test_tools/quic_test_utils.h"
-
-using testing::_;
-using testing::StrictMock;
-
-namespace quic {
-namespace test {
-namespace {
-
-struct TestParams {
- explicit TestParams(ParsedQuicVersion version, Perspective perspective)
- : version(version), perspective(perspective) {}
-
- ParsedQuicVersion version;
- Perspective perspective;
-};
-
-// Used by ::testing::PrintToStringParamName().
-std::string PrintToString(const TestParams& p) {
- return absl::StrCat(
- ParsedQuicVersionToString(p.version), "_",
- (p.perspective == Perspective::IS_CLIENT ? "client" : "server"));
-}
-
-std::vector<TestParams> GetTestParams() {
- std::vector<TestParams> params;
- for (const ParsedQuicVersion& version : AllSupportedVersions()) {
- if (!version.HasIetfQuicFrames()) {
- continue;
- }
- params.push_back(TestParams(version, Perspective::IS_CLIENT));
- params.push_back(TestParams(version, Perspective::IS_SERVER));
- }
- return params;
-}
-
-class MockDelegate : public QuicStreamIdManager::DelegateInterface {
- public:
- MOCK_METHOD(void,
- SendMaxStreams,
- (QuicStreamCount stream_count, bool unidirectional),
- (override));
-};
-
-class UberQuicStreamIdManagerTest : public QuicTestWithParam<TestParams> {
- protected:
- UberQuicStreamIdManagerTest()
- : manager_(perspective(),
- version(),
- &delegate_,
- 0,
- 0,
- kDefaultMaxStreamsPerConnection,
- kDefaultMaxStreamsPerConnection) {}
-
- QuicStreamId GetNthClientInitiatedBidirectionalId(int n) {
- return QuicUtils::GetFirstBidirectionalStreamId(transport_version(),
- Perspective::IS_CLIENT) +
- QuicUtils::StreamIdDelta(transport_version()) * n;
- }
-
- QuicStreamId GetNthClientInitiatedUnidirectionalId(int n) {
- return QuicUtils::GetFirstUnidirectionalStreamId(transport_version(),
- Perspective::IS_CLIENT) +
- QuicUtils::StreamIdDelta(transport_version()) * n;
- }
-
- QuicStreamId GetNthServerInitiatedBidirectionalId(int n) {
- return QuicUtils::GetFirstBidirectionalStreamId(transport_version(),
- Perspective::IS_SERVER) +
- QuicUtils::StreamIdDelta(transport_version()) * n;
- }
-
- QuicStreamId GetNthServerInitiatedUnidirectionalId(int n) {
- return QuicUtils::GetFirstUnidirectionalStreamId(transport_version(),
- Perspective::IS_SERVER) +
- QuicUtils::StreamIdDelta(transport_version()) * n;
- }
-
- QuicStreamId GetNthPeerInitiatedBidirectionalStreamId(int n) {
- return ((perspective() == Perspective::IS_SERVER)
- ? GetNthClientInitiatedBidirectionalId(n)
- : GetNthServerInitiatedBidirectionalId(n));
- }
- QuicStreamId GetNthPeerInitiatedUnidirectionalStreamId(int n) {
- return ((perspective() == Perspective::IS_SERVER)
- ? GetNthClientInitiatedUnidirectionalId(n)
- : GetNthServerInitiatedUnidirectionalId(n));
- }
- QuicStreamId GetNthSelfInitiatedBidirectionalStreamId(int n) {
- return ((perspective() == Perspective::IS_CLIENT)
- ? GetNthClientInitiatedBidirectionalId(n)
- : GetNthServerInitiatedBidirectionalId(n));
- }
- QuicStreamId GetNthSelfInitiatedUnidirectionalStreamId(int n) {
- return ((perspective() == Perspective::IS_CLIENT)
- ? GetNthClientInitiatedUnidirectionalId(n)
- : GetNthServerInitiatedUnidirectionalId(n));
- }
-
- QuicStreamId StreamCountToId(QuicStreamCount stream_count,
- Perspective perspective,
- bool bidirectional) {
- return ((bidirectional) ? QuicUtils::GetFirstBidirectionalStreamId(
- transport_version(), perspective)
- : QuicUtils::GetFirstUnidirectionalStreamId(
- transport_version(), perspective)) +
- ((stream_count - 1) * QuicUtils::StreamIdDelta(transport_version()));
- }
-
- ParsedQuicVersion version() { return GetParam().version; }
- QuicTransportVersion transport_version() {
- return version().transport_version;
- }
-
- Perspective perspective() { return GetParam().perspective; }
-
- testing::StrictMock<MockDelegate> delegate_;
- UberQuicStreamIdManager manager_;
-};
-
-INSTANTIATE_TEST_SUITE_P(Tests,
- UberQuicStreamIdManagerTest,
- ::testing::ValuesIn(GetTestParams()),
- ::testing::PrintToStringParamName());
-
-TEST_P(UberQuicStreamIdManagerTest, Initialization) {
- EXPECT_EQ(GetNthSelfInitiatedBidirectionalStreamId(0),
- manager_.next_outgoing_bidirectional_stream_id());
- EXPECT_EQ(GetNthSelfInitiatedUnidirectionalStreamId(0),
- manager_.next_outgoing_unidirectional_stream_id());
-}
-
-TEST_P(UberQuicStreamIdManagerTest, SetMaxOpenOutgoingStreams) {
- const size_t kNumMaxOutgoingStream = 123;
- // Set the uni- and bi- directional limits to different values to ensure
- // that they are managed separately.
- EXPECT_TRUE(manager_.MaybeAllowNewOutgoingBidirectionalStreams(
- kNumMaxOutgoingStream));
- EXPECT_TRUE(manager_.MaybeAllowNewOutgoingUnidirectionalStreams(
- kNumMaxOutgoingStream + 1));
- EXPECT_EQ(kNumMaxOutgoingStream,
- manager_.max_outgoing_bidirectional_streams());
- EXPECT_EQ(kNumMaxOutgoingStream + 1,
- manager_.max_outgoing_unidirectional_streams());
- // Check that, for each directionality, we can open the correct number of
- // streams.
- int i = kNumMaxOutgoingStream;
- while (i) {
- EXPECT_TRUE(manager_.CanOpenNextOutgoingBidirectionalStream());
- manager_.GetNextOutgoingBidirectionalStreamId();
- EXPECT_TRUE(manager_.CanOpenNextOutgoingUnidirectionalStream());
- manager_.GetNextOutgoingUnidirectionalStreamId();
- i--;
- }
- // One more unidirectional
- EXPECT_TRUE(manager_.CanOpenNextOutgoingUnidirectionalStream());
- manager_.GetNextOutgoingUnidirectionalStreamId();
-
- // Both should be exhausted...
- EXPECT_FALSE(manager_.CanOpenNextOutgoingUnidirectionalStream());
- EXPECT_FALSE(manager_.CanOpenNextOutgoingBidirectionalStream());
-}
-
-TEST_P(UberQuicStreamIdManagerTest, SetMaxOpenIncomingStreams) {
- const size_t kNumMaxIncomingStreams = 456;
- manager_.SetMaxOpenIncomingUnidirectionalStreams(kNumMaxIncomingStreams);
- // Do +1 for bidirectional to ensure that uni- and bi- get properly set.
- manager_.SetMaxOpenIncomingBidirectionalStreams(kNumMaxIncomingStreams + 1);
- EXPECT_EQ(kNumMaxIncomingStreams + 1,
- manager_.GetMaxAllowdIncomingBidirectionalStreams());
- EXPECT_EQ(kNumMaxIncomingStreams,
- manager_.GetMaxAllowdIncomingUnidirectionalStreams());
- EXPECT_EQ(manager_.max_incoming_bidirectional_streams(),
- manager_.advertised_max_incoming_bidirectional_streams());
- EXPECT_EQ(manager_.max_incoming_unidirectional_streams(),
- manager_.advertised_max_incoming_unidirectional_streams());
- // Make sure that we can create kNumMaxIncomingStreams incoming unidirectional
- // streams and kNumMaxIncomingStreams+1 incoming bidirectional streams.
- size_t i;
- for (i = 0; i < kNumMaxIncomingStreams; i++) {
- EXPECT_TRUE(manager_.MaybeIncreaseLargestPeerStreamId(
- GetNthPeerInitiatedUnidirectionalStreamId(i), nullptr));
- EXPECT_TRUE(manager_.MaybeIncreaseLargestPeerStreamId(
- GetNthPeerInitiatedBidirectionalStreamId(i), nullptr));
- }
- // Should be able to open the next bidirectional stream
- EXPECT_TRUE(manager_.MaybeIncreaseLargestPeerStreamId(
- GetNthPeerInitiatedBidirectionalStreamId(i), nullptr));
-
- // We should have exhausted the counts, the next streams should fail
- std::string error_details;
- EXPECT_FALSE(manager_.MaybeIncreaseLargestPeerStreamId(
- GetNthPeerInitiatedUnidirectionalStreamId(i), &error_details));
- EXPECT_EQ(error_details,
- absl::StrCat(
- "Stream id ", GetNthPeerInitiatedUnidirectionalStreamId(i),
- " would exceed stream count limit ", kNumMaxIncomingStreams));
- EXPECT_FALSE(manager_.MaybeIncreaseLargestPeerStreamId(
- GetNthPeerInitiatedBidirectionalStreamId(i + 1), &error_details));
- EXPECT_EQ(error_details,
- absl::StrCat("Stream id ",
- GetNthPeerInitiatedBidirectionalStreamId(i + 1),
- " would exceed stream count limit ",
- kNumMaxIncomingStreams + 1));
-}
-
-TEST_P(UberQuicStreamIdManagerTest, GetNextOutgoingStreamId) {
- EXPECT_TRUE(manager_.MaybeAllowNewOutgoingBidirectionalStreams(10));
- EXPECT_TRUE(manager_.MaybeAllowNewOutgoingUnidirectionalStreams(10));
- EXPECT_EQ(GetNthSelfInitiatedBidirectionalStreamId(0),
- manager_.GetNextOutgoingBidirectionalStreamId());
- EXPECT_EQ(GetNthSelfInitiatedBidirectionalStreamId(1),
- manager_.GetNextOutgoingBidirectionalStreamId());
- EXPECT_EQ(GetNthSelfInitiatedUnidirectionalStreamId(0),
- manager_.GetNextOutgoingUnidirectionalStreamId());
- EXPECT_EQ(GetNthSelfInitiatedUnidirectionalStreamId(1),
- manager_.GetNextOutgoingUnidirectionalStreamId());
-}
-
-TEST_P(UberQuicStreamIdManagerTest, AvailableStreams) {
- EXPECT_TRUE(manager_.MaybeIncreaseLargestPeerStreamId(
- GetNthPeerInitiatedBidirectionalStreamId(3), nullptr));
- EXPECT_TRUE(
- manager_.IsAvailableStream(GetNthPeerInitiatedBidirectionalStreamId(1)));
- EXPECT_TRUE(
- manager_.IsAvailableStream(GetNthPeerInitiatedBidirectionalStreamId(2)));
-
- EXPECT_TRUE(manager_.MaybeIncreaseLargestPeerStreamId(
- GetNthPeerInitiatedUnidirectionalStreamId(3), nullptr));
- EXPECT_TRUE(
- manager_.IsAvailableStream(GetNthPeerInitiatedUnidirectionalStreamId(1)));
- EXPECT_TRUE(
- manager_.IsAvailableStream(GetNthPeerInitiatedUnidirectionalStreamId(2)));
-}
-
-TEST_P(UberQuicStreamIdManagerTest, MaybeIncreaseLargestPeerStreamId) {
- EXPECT_TRUE(manager_.MaybeIncreaseLargestPeerStreamId(
- StreamCountToId(manager_.max_incoming_bidirectional_streams(),
- QuicUtils::InvertPerspective(perspective()),
- /* bidirectional=*/true),
- nullptr));
- EXPECT_TRUE(manager_.MaybeIncreaseLargestPeerStreamId(
- StreamCountToId(manager_.max_incoming_bidirectional_streams(),
- QuicUtils::InvertPerspective(perspective()),
- /* bidirectional=*/false),
- nullptr));
-
- std::string expected_error_details =
- perspective() == Perspective::IS_SERVER
- ? "Stream id 400 would exceed stream count limit 100"
- : "Stream id 401 would exceed stream count limit 100";
- std::string error_details;
-
- EXPECT_FALSE(manager_.MaybeIncreaseLargestPeerStreamId(
- StreamCountToId(manager_.max_incoming_bidirectional_streams() + 1,
- QuicUtils::InvertPerspective(perspective()),
- /* bidirectional=*/true),
- &error_details));
- EXPECT_EQ(expected_error_details, error_details);
- expected_error_details =
- perspective() == Perspective::IS_SERVER
- ? "Stream id 402 would exceed stream count limit 100"
- : "Stream id 403 would exceed stream count limit 100";
-
- EXPECT_FALSE(manager_.MaybeIncreaseLargestPeerStreamId(
- StreamCountToId(manager_.max_incoming_bidirectional_streams() + 1,
- QuicUtils::InvertPerspective(perspective()),
- /* bidirectional=*/false),
- &error_details));
- EXPECT_EQ(expected_error_details, error_details);
-}
-
-TEST_P(UberQuicStreamIdManagerTest, OnStreamsBlockedFrame) {
- QuicStreamCount stream_count =
- manager_.advertised_max_incoming_bidirectional_streams() - 1;
-
- QuicStreamsBlockedFrame frame(kInvalidControlFrameId, stream_count,
- /*unidirectional=*/false);
- EXPECT_CALL(delegate_,
- SendMaxStreams(manager_.max_incoming_bidirectional_streams(),
- frame.unidirectional))
- .Times(0);
- EXPECT_TRUE(manager_.OnStreamsBlockedFrame(frame, nullptr));
-
- stream_count = manager_.advertised_max_incoming_unidirectional_streams() - 1;
- frame.stream_count = stream_count;
- frame.unidirectional = true;
-
- EXPECT_CALL(delegate_,
- SendMaxStreams(manager_.max_incoming_unidirectional_streams(),
- frame.unidirectional))
- .Times(0);
- EXPECT_TRUE(manager_.OnStreamsBlockedFrame(frame, nullptr));
-}
-
-TEST_P(UberQuicStreamIdManagerTest, SetMaxOpenOutgoingStreamsPlusFrame) {
- const size_t kNumMaxOutgoingStream = 123;
- // Set the uni- and bi- directional limits to different values to ensure
- // that they are managed separately.
- EXPECT_TRUE(manager_.MaybeAllowNewOutgoingBidirectionalStreams(
- kNumMaxOutgoingStream));
- EXPECT_TRUE(manager_.MaybeAllowNewOutgoingUnidirectionalStreams(
- kNumMaxOutgoingStream + 1));
- EXPECT_EQ(kNumMaxOutgoingStream,
- manager_.max_outgoing_bidirectional_streams());
- EXPECT_EQ(kNumMaxOutgoingStream + 1,
- manager_.max_outgoing_unidirectional_streams());
- // Check that, for each directionality, we can open the correct number of
- // streams.
- int i = kNumMaxOutgoingStream;
- while (i) {
- EXPECT_TRUE(manager_.CanOpenNextOutgoingBidirectionalStream());
- manager_.GetNextOutgoingBidirectionalStreamId();
- EXPECT_TRUE(manager_.CanOpenNextOutgoingUnidirectionalStream());
- manager_.GetNextOutgoingUnidirectionalStreamId();
- i--;
- }
- // One more unidirectional
- EXPECT_TRUE(manager_.CanOpenNextOutgoingUnidirectionalStream());
- manager_.GetNextOutgoingUnidirectionalStreamId();
-
- // Both should be exhausted...
- EXPECT_FALSE(manager_.CanOpenNextOutgoingUnidirectionalStream());
- EXPECT_FALSE(manager_.CanOpenNextOutgoingBidirectionalStream());
-}
-
-} // namespace
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/uber_received_packet_manager.cc b/chromium/net/third_party/quiche/src/quic/core/uber_received_packet_manager.cc
deleted file mode 100644
index c25329c5fc8..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/uber_received_packet_manager.cc
+++ /dev/null
@@ -1,247 +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 "quic/core/uber_received_packet_manager.h"
-
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-
-namespace quic {
-
-UberReceivedPacketManager::UberReceivedPacketManager(QuicConnectionStats* stats)
- : supports_multiple_packet_number_spaces_(false) {
- for (auto& received_packet_manager : received_packet_managers_) {
- received_packet_manager.set_connection_stats(stats);
- }
-}
-
-UberReceivedPacketManager::~UberReceivedPacketManager() {}
-
-void UberReceivedPacketManager::SetFromConfig(const QuicConfig& config,
- Perspective perspective) {
- for (auto& received_packet_manager : received_packet_managers_) {
- received_packet_manager.SetFromConfig(config, perspective);
- }
-}
-
-bool UberReceivedPacketManager::IsAwaitingPacket(
- EncryptionLevel decrypted_packet_level,
- QuicPacketNumber packet_number) const {
- if (!supports_multiple_packet_number_spaces_) {
- return received_packet_managers_[0].IsAwaitingPacket(packet_number);
- }
- return received_packet_managers_[QuicUtils::GetPacketNumberSpace(
- decrypted_packet_level)]
- .IsAwaitingPacket(packet_number);
-}
-
-const QuicFrame UberReceivedPacketManager::GetUpdatedAckFrame(
- PacketNumberSpace packet_number_space,
- QuicTime approximate_now) {
- if (!supports_multiple_packet_number_spaces_) {
- return received_packet_managers_[0].GetUpdatedAckFrame(approximate_now);
- }
- return received_packet_managers_[packet_number_space].GetUpdatedAckFrame(
- approximate_now);
-}
-
-void UberReceivedPacketManager::RecordPacketReceived(
- EncryptionLevel decrypted_packet_level,
- const QuicPacketHeader& header,
- QuicTime receipt_time) {
- if (!supports_multiple_packet_number_spaces_) {
- received_packet_managers_[0].RecordPacketReceived(header, receipt_time);
- return;
- }
- received_packet_managers_[QuicUtils::GetPacketNumberSpace(
- decrypted_packet_level)]
- .RecordPacketReceived(header, receipt_time);
-}
-
-void UberReceivedPacketManager::DontWaitForPacketsBefore(
- EncryptionLevel decrypted_packet_level,
- QuicPacketNumber least_unacked) {
- if (!supports_multiple_packet_number_spaces_) {
- received_packet_managers_[0].DontWaitForPacketsBefore(least_unacked);
- return;
- }
- received_packet_managers_[QuicUtils::GetPacketNumberSpace(
- decrypted_packet_level)]
- .DontWaitForPacketsBefore(least_unacked);
-}
-
-void UberReceivedPacketManager::MaybeUpdateAckTimeout(
- bool should_last_packet_instigate_acks,
- EncryptionLevel decrypted_packet_level,
- QuicPacketNumber last_received_packet_number,
- QuicTime now,
- const RttStats* rtt_stats) {
- if (!supports_multiple_packet_number_spaces_) {
- received_packet_managers_[0].MaybeUpdateAckTimeout(
- should_last_packet_instigate_acks, last_received_packet_number, now,
- rtt_stats);
- return;
- }
- received_packet_managers_[QuicUtils::GetPacketNumberSpace(
- decrypted_packet_level)]
- .MaybeUpdateAckTimeout(should_last_packet_instigate_acks,
- last_received_packet_number, now, rtt_stats);
-}
-
-void UberReceivedPacketManager::ResetAckStates(
- EncryptionLevel encryption_level) {
- if (!supports_multiple_packet_number_spaces_) {
- received_packet_managers_[0].ResetAckStates();
- return;
- }
- received_packet_managers_[QuicUtils::GetPacketNumberSpace(encryption_level)]
- .ResetAckStates();
- if (encryption_level == ENCRYPTION_INITIAL) {
- // After one Initial ACK is sent, the others should be sent 'immediately'.
- received_packet_managers_[INITIAL_DATA].set_local_max_ack_delay(
- kAlarmGranularity);
- }
-}
-
-void UberReceivedPacketManager::EnableMultiplePacketNumberSpacesSupport(
- Perspective perspective) {
- if (supports_multiple_packet_number_spaces_) {
- QUIC_BUG(quic_bug_10495_1)
- << "Multiple packet number spaces has already been enabled";
- return;
- }
- if (received_packet_managers_[0].GetLargestObserved().IsInitialized()) {
- QUIC_BUG(quic_bug_10495_2)
- << "Try to enable multiple packet number spaces support after any "
- "packet has been received.";
- return;
- }
- // In IETF QUIC, the peer is expected to acknowledge packets in Initial and
- // Handshake packets with minimal delay.
- if (perspective == Perspective::IS_CLIENT) {
- // Delay the first server ACK, because server ACKs are padded to
- // full size and count towards the amplification limit.
- received_packet_managers_[INITIAL_DATA].set_local_max_ack_delay(
- kAlarmGranularity);
- }
- received_packet_managers_[HANDSHAKE_DATA].set_local_max_ack_delay(
- kAlarmGranularity);
-
- supports_multiple_packet_number_spaces_ = true;
-}
-
-bool UberReceivedPacketManager::IsAckFrameUpdated() const {
- if (!supports_multiple_packet_number_spaces_) {
- return received_packet_managers_[0].ack_frame_updated();
- }
- for (const auto& received_packet_manager : received_packet_managers_) {
- if (received_packet_manager.ack_frame_updated()) {
- return true;
- }
- }
- return false;
-}
-
-QuicPacketNumber UberReceivedPacketManager::GetLargestObserved(
- EncryptionLevel decrypted_packet_level) const {
- if (!supports_multiple_packet_number_spaces_) {
- return received_packet_managers_[0].GetLargestObserved();
- }
- return received_packet_managers_[QuicUtils::GetPacketNumberSpace(
- decrypted_packet_level)]
- .GetLargestObserved();
-}
-
-QuicTime UberReceivedPacketManager::GetAckTimeout(
- PacketNumberSpace packet_number_space) const {
- if (!supports_multiple_packet_number_spaces_) {
- return received_packet_managers_[0].ack_timeout();
- }
- return received_packet_managers_[packet_number_space].ack_timeout();
-}
-
-QuicTime UberReceivedPacketManager::GetEarliestAckTimeout() const {
- QuicTime ack_timeout = QuicTime::Zero();
- // Returns the earliest non-zero ack timeout.
- for (const auto& received_packet_manager : received_packet_managers_) {
- const QuicTime timeout = received_packet_manager.ack_timeout();
- if (!ack_timeout.IsInitialized()) {
- ack_timeout = timeout;
- continue;
- }
- if (timeout.IsInitialized()) {
- ack_timeout = std::min(ack_timeout, timeout);
- }
- }
- return ack_timeout;
-}
-
-bool UberReceivedPacketManager::IsAckFrameEmpty(
- PacketNumberSpace packet_number_space) const {
- if (!supports_multiple_packet_number_spaces_) {
- return received_packet_managers_[0].IsAckFrameEmpty();
- }
- return received_packet_managers_[packet_number_space].IsAckFrameEmpty();
-}
-
-QuicPacketNumber UberReceivedPacketManager::peer_least_packet_awaiting_ack()
- const {
- QUICHE_DCHECK(!supports_multiple_packet_number_spaces_);
- return received_packet_managers_[0].peer_least_packet_awaiting_ack();
-}
-
-size_t UberReceivedPacketManager::min_received_before_ack_decimation() const {
- return received_packet_managers_[0].min_received_before_ack_decimation();
-}
-
-void UberReceivedPacketManager::set_min_received_before_ack_decimation(
- size_t new_value) {
- for (auto& received_packet_manager : received_packet_managers_) {
- received_packet_manager.set_min_received_before_ack_decimation(new_value);
- }
-}
-
-void UberReceivedPacketManager::set_ack_frequency(size_t new_value) {
- for (auto& received_packet_manager : received_packet_managers_) {
- received_packet_manager.set_ack_frequency(new_value);
- }
-}
-
-const QuicAckFrame& UberReceivedPacketManager::ack_frame() const {
- QUICHE_DCHECK(!supports_multiple_packet_number_spaces_);
- return received_packet_managers_[0].ack_frame();
-}
-
-const QuicAckFrame& UberReceivedPacketManager::GetAckFrame(
- PacketNumberSpace packet_number_space) const {
- QUICHE_DCHECK(supports_multiple_packet_number_spaces_);
- return received_packet_managers_[packet_number_space].ack_frame();
-}
-
-void UberReceivedPacketManager::set_max_ack_ranges(size_t max_ack_ranges) {
- for (auto& received_packet_manager : received_packet_managers_) {
- received_packet_manager.set_max_ack_ranges(max_ack_ranges);
- }
-}
-
-void UberReceivedPacketManager::set_save_timestamps(bool save_timestamps) {
- for (auto& received_packet_manager : received_packet_managers_) {
- received_packet_manager.set_save_timestamps(
- save_timestamps, supports_multiple_packet_number_spaces_);
- }
-}
-
-void UberReceivedPacketManager::OnAckFrequencyFrame(
- const QuicAckFrequencyFrame& frame) {
- if (!supports_multiple_packet_number_spaces_) {
- QUIC_BUG(quic_bug_10495_3)
- << "Received AckFrequencyFrame when multiple packet number spaces "
- "is not supported";
- return;
- }
- received_packet_managers_[APPLICATION_DATA].OnAckFrequencyFrame(frame);
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/uber_received_packet_manager.h b/chromium/net/third_party/quiche/src/quic/core/uber_received_packet_manager.h
deleted file mode 100644
index 3dddbdaa575..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/uber_received_packet_manager.h
+++ /dev/null
@@ -1,111 +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_CORE_UBER_RECEIVED_PACKET_MANAGER_H_
-#define QUICHE_QUIC_CORE_UBER_RECEIVED_PACKET_MANAGER_H_
-
-#include "quic/core/frames/quic_ack_frequency_frame.h"
-#include "quic/core/quic_received_packet_manager.h"
-
-namespace quic {
-
-// This class comprises multiple received packet managers, one per packet number
-// space. Please note, if multiple packet number spaces is not supported, only
-// one received packet manager will be used.
-class QUIC_EXPORT_PRIVATE UberReceivedPacketManager {
- public:
- explicit UberReceivedPacketManager(QuicConnectionStats* stats);
- UberReceivedPacketManager(const UberReceivedPacketManager&) = delete;
- UberReceivedPacketManager& operator=(const UberReceivedPacketManager&) =
- delete;
- virtual ~UberReceivedPacketManager();
-
- void SetFromConfig(const QuicConfig& config, Perspective perspective);
-
- // Checks if we are still waiting for the packet with |packet_number|.
- bool IsAwaitingPacket(EncryptionLevel decrypted_packet_level,
- QuicPacketNumber packet_number) const;
-
- // Called after a packet has been successfully decrypted and its header has
- // been parsed.
- void RecordPacketReceived(EncryptionLevel decrypted_packet_level,
- const QuicPacketHeader& header,
- QuicTime receipt_time);
-
- // Retrieves a frame containing a QuicAckFrame. The ack frame must be
- // serialized before another packet is received, or it will change.
- const QuicFrame GetUpdatedAckFrame(PacketNumberSpace packet_number_space,
- QuicTime approximate_now);
-
- // Stop ACKing packets before |least_unacked|.
- void DontWaitForPacketsBefore(EncryptionLevel decrypted_packet_level,
- QuicPacketNumber least_unacked);
-
- // Called after header of last received packet has been successfully processed
- // to update ACK timeout.
- void MaybeUpdateAckTimeout(bool should_last_packet_instigate_acks,
- EncryptionLevel decrypted_packet_level,
- QuicPacketNumber last_received_packet_number,
- QuicTime now,
- const RttStats* rtt_stats);
-
- // Resets ACK related states, called after an ACK is successfully sent.
- void ResetAckStates(EncryptionLevel encryption_level);
-
- // Called to enable multiple packet number support.
- void EnableMultiplePacketNumberSpacesSupport(Perspective perspective);
-
- // Returns true if ACK frame has been updated since GetUpdatedAckFrame was
- // last called.
- bool IsAckFrameUpdated() const;
-
- // Returns the largest received packet number.
- QuicPacketNumber GetLargestObserved(
- EncryptionLevel decrypted_packet_level) const;
-
- // Returns ACK timeout of |packet_number_space|.
- QuicTime GetAckTimeout(PacketNumberSpace packet_number_space) const;
-
- // Get the earliest ack_timeout of all packet number spaces.
- QuicTime GetEarliestAckTimeout() const;
-
- // Return true if ack frame of |packet_number_space| is empty.
- bool IsAckFrameEmpty(PacketNumberSpace packet_number_space) const;
-
- QuicPacketNumber peer_least_packet_awaiting_ack() const;
-
- size_t min_received_before_ack_decimation() const;
- void set_min_received_before_ack_decimation(size_t new_value);
-
- void set_ack_frequency(size_t new_value);
-
- bool supports_multiple_packet_number_spaces() const {
- return supports_multiple_packet_number_spaces_;
- }
-
- // For logging purposes.
- const QuicAckFrame& ack_frame() const;
- const QuicAckFrame& GetAckFrame(PacketNumberSpace packet_number_space) const;
-
- void set_max_ack_ranges(size_t max_ack_ranges);
-
- void OnAckFrequencyFrame(const QuicAckFrequencyFrame& frame);
-
- void set_save_timestamps(bool save_timestamps);
-
- private:
- friend class test::QuicConnectionPeer;
- friend class test::UberReceivedPacketManagerPeer;
-
- // One received packet manager per packet number space. If
- // supports_multiple_packet_number_spaces_ is false, only the first (0 index)
- // received_packet_manager is used.
- QuicReceivedPacketManager received_packet_managers_[NUM_PACKET_NUMBER_SPACES];
-
- bool supports_multiple_packet_number_spaces_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_UBER_RECEIVED_PACKET_MANAGER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/uber_received_packet_manager_test.cc b/chromium/net/third_party/quiche/src/quic/core/uber_received_packet_manager_test.cc
deleted file mode 100644
index 77731fb2d47..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/uber_received_packet_manager_test.cc
+++ /dev/null
@@ -1,527 +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 "quic/core/uber_received_packet_manager.h"
-
-#include <utility>
-
-#include "quic/core/congestion_control/rtt_stats.h"
-#include "quic/core/crypto/crypto_protocol.h"
-#include "quic/core/quic_connection_stats.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/mock_clock.h"
-
-namespace quic {
-namespace test {
-
-class UberReceivedPacketManagerPeer {
- public:
- static void SetAckDecimationDelay(UberReceivedPacketManager* manager,
- float ack_decimation_delay) {
- for (auto& received_packet_manager : manager->received_packet_managers_) {
- received_packet_manager.ack_decimation_delay_ = ack_decimation_delay;
- }
- }
-};
-
-namespace {
-
-const bool kInstigateAck = true;
-const QuicTime::Delta kMinRttMs = QuicTime::Delta::FromMilliseconds(40);
-const QuicTime::Delta kDelayedAckTime =
- QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
-
-class UberReceivedPacketManagerTest : public QuicTest {
- protected:
- UberReceivedPacketManagerTest() {
- manager_ = std::make_unique<UberReceivedPacketManager>(&stats_);
- clock_.AdvanceTime(QuicTime::Delta::FromSeconds(1));
- rtt_stats_.UpdateRtt(kMinRttMs, QuicTime::Delta::Zero(), QuicTime::Zero());
- manager_->set_save_timestamps(true);
- }
-
- void RecordPacketReceipt(uint64_t packet_number) {
- RecordPacketReceipt(ENCRYPTION_FORWARD_SECURE, packet_number);
- }
-
- void RecordPacketReceipt(uint64_t packet_number, QuicTime receipt_time) {
- RecordPacketReceipt(ENCRYPTION_FORWARD_SECURE, packet_number, receipt_time);
- }
-
- void RecordPacketReceipt(EncryptionLevel decrypted_packet_level,
- uint64_t packet_number) {
- RecordPacketReceipt(decrypted_packet_level, packet_number,
- QuicTime::Zero());
- }
-
- void RecordPacketReceipt(EncryptionLevel decrypted_packet_level,
- uint64_t packet_number,
- QuicTime receipt_time) {
- QuicPacketHeader header;
- header.packet_number = QuicPacketNumber(packet_number);
- manager_->RecordPacketReceived(decrypted_packet_level, header,
- receipt_time);
- }
-
- bool HasPendingAck() {
- if (!manager_->supports_multiple_packet_number_spaces()) {
- return manager_->GetAckTimeout(APPLICATION_DATA).IsInitialized();
- }
- return manager_->GetEarliestAckTimeout().IsInitialized();
- }
-
- void MaybeUpdateAckTimeout(bool should_last_packet_instigate_acks,
- uint64_t last_received_packet_number) {
- MaybeUpdateAckTimeout(should_last_packet_instigate_acks,
- ENCRYPTION_FORWARD_SECURE,
- last_received_packet_number);
- }
-
- void MaybeUpdateAckTimeout(bool should_last_packet_instigate_acks,
- EncryptionLevel decrypted_packet_level,
- uint64_t last_received_packet_number) {
- manager_->MaybeUpdateAckTimeout(
- should_last_packet_instigate_acks, decrypted_packet_level,
- QuicPacketNumber(last_received_packet_number), clock_.ApproximateNow(),
- &rtt_stats_);
- }
-
- void CheckAckTimeout(QuicTime time) {
- QUICHE_DCHECK(HasPendingAck());
- if (!manager_->supports_multiple_packet_number_spaces()) {
- QUICHE_DCHECK(manager_->GetAckTimeout(APPLICATION_DATA) == time);
- if (time <= clock_.ApproximateNow()) {
- // ACK timeout expires, send an ACK.
- manager_->ResetAckStates(ENCRYPTION_FORWARD_SECURE);
- QUICHE_DCHECK(!HasPendingAck());
- }
- return;
- }
- QUICHE_DCHECK(manager_->GetEarliestAckTimeout() == time);
- // Send all expired ACKs.
- for (int8_t i = INITIAL_DATA; i < NUM_PACKET_NUMBER_SPACES; ++i) {
- const QuicTime ack_timeout =
- manager_->GetAckTimeout(static_cast<PacketNumberSpace>(i));
- if (!ack_timeout.IsInitialized() ||
- ack_timeout > clock_.ApproximateNow()) {
- continue;
- }
- manager_->ResetAckStates(
- QuicUtils::GetEncryptionLevel(static_cast<PacketNumberSpace>(i)));
- }
- }
-
- MockClock clock_;
- RttStats rtt_stats_;
- QuicConnectionStats stats_;
- std::unique_ptr<UberReceivedPacketManager> manager_;
-};
-
-TEST_F(UberReceivedPacketManagerTest, DontWaitForPacketsBefore) {
- EXPECT_TRUE(manager_->IsAckFrameEmpty(APPLICATION_DATA));
- RecordPacketReceipt(2);
- EXPECT_FALSE(manager_->IsAckFrameEmpty(APPLICATION_DATA));
- RecordPacketReceipt(7);
- EXPECT_TRUE(manager_->IsAwaitingPacket(ENCRYPTION_FORWARD_SECURE,
- QuicPacketNumber(3u)));
- EXPECT_TRUE(manager_->IsAwaitingPacket(ENCRYPTION_FORWARD_SECURE,
- QuicPacketNumber(6u)));
- manager_->DontWaitForPacketsBefore(ENCRYPTION_FORWARD_SECURE,
- QuicPacketNumber(4));
- EXPECT_FALSE(manager_->IsAwaitingPacket(ENCRYPTION_FORWARD_SECURE,
- QuicPacketNumber(3u)));
- EXPECT_TRUE(manager_->IsAwaitingPacket(ENCRYPTION_FORWARD_SECURE,
- QuicPacketNumber(6u)));
-}
-
-TEST_F(UberReceivedPacketManagerTest, GetUpdatedAckFrame) {
- QuicTime two_ms = QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(2);
- EXPECT_FALSE(manager_->IsAckFrameUpdated());
- RecordPacketReceipt(2, two_ms);
- EXPECT_TRUE(manager_->IsAckFrameUpdated());
-
- QuicFrame ack =
- manager_->GetUpdatedAckFrame(APPLICATION_DATA, QuicTime::Zero());
- manager_->ResetAckStates(ENCRYPTION_FORWARD_SECURE);
- EXPECT_FALSE(manager_->IsAckFrameUpdated());
- // When UpdateReceivedPacketInfo with a time earlier than the time of the
- // largest observed packet, make sure that the delta is 0, not negative.
- EXPECT_EQ(QuicTime::Delta::Zero(), ack.ack_frame->ack_delay_time);
- EXPECT_EQ(1u, ack.ack_frame->received_packet_times.size());
-
- QuicTime four_ms = QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(4);
- ack = manager_->GetUpdatedAckFrame(APPLICATION_DATA, four_ms);
- manager_->ResetAckStates(ENCRYPTION_FORWARD_SECURE);
- EXPECT_FALSE(manager_->IsAckFrameUpdated());
- // When UpdateReceivedPacketInfo after not having received a new packet,
- // the delta should still be accurate.
- EXPECT_EQ(QuicTime::Delta::FromMilliseconds(2),
- ack.ack_frame->ack_delay_time);
- // And received packet times won't have change.
- EXPECT_EQ(1u, ack.ack_frame->received_packet_times.size());
-
- RecordPacketReceipt(999, two_ms);
- RecordPacketReceipt(4, two_ms);
- RecordPacketReceipt(1000, two_ms);
- EXPECT_TRUE(manager_->IsAckFrameUpdated());
- ack = manager_->GetUpdatedAckFrame(APPLICATION_DATA, two_ms);
- manager_->ResetAckStates(ENCRYPTION_FORWARD_SECURE);
- EXPECT_FALSE(manager_->IsAckFrameUpdated());
- // UpdateReceivedPacketInfo should discard any times which can't be
- // expressed on the wire.
- EXPECT_EQ(2u, ack.ack_frame->received_packet_times.size());
-}
-
-TEST_F(UberReceivedPacketManagerTest, UpdateReceivedConnectionStats) {
- EXPECT_FALSE(manager_->IsAckFrameUpdated());
- RecordPacketReceipt(1);
- EXPECT_TRUE(manager_->IsAckFrameUpdated());
- RecordPacketReceipt(6);
- RecordPacketReceipt(2,
- QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(1));
-
- EXPECT_EQ(4u, stats_.max_sequence_reordering);
- EXPECT_EQ(1000, stats_.max_time_reordering_us);
- EXPECT_EQ(1u, stats_.packets_reordered);
-}
-
-TEST_F(UberReceivedPacketManagerTest, LimitAckRanges) {
- manager_->set_max_ack_ranges(10);
- EXPECT_FALSE(manager_->IsAckFrameUpdated());
- for (int i = 0; i < 100; ++i) {
- RecordPacketReceipt(1 + 2 * i);
- EXPECT_TRUE(manager_->IsAckFrameUpdated());
- manager_->GetUpdatedAckFrame(APPLICATION_DATA, QuicTime::Zero());
- EXPECT_GE(10u, manager_->ack_frame().packets.NumIntervals());
- EXPECT_EQ(QuicPacketNumber(1u + 2 * i),
- manager_->ack_frame().packets.Max());
- for (int j = 0; j < std::min(10, i + 1); ++j) {
- ASSERT_GE(i, j);
- EXPECT_TRUE(manager_->ack_frame().packets.Contains(
- QuicPacketNumber(1 + (i - j) * 2)));
- if (i > j) {
- EXPECT_FALSE(manager_->ack_frame().packets.Contains(
- QuicPacketNumber((i - j) * 2)));
- }
- }
- }
-}
-
-TEST_F(UberReceivedPacketManagerTest, IgnoreOutOfOrderTimestamps) {
- EXPECT_FALSE(manager_->IsAckFrameUpdated());
- RecordPacketReceipt(1, QuicTime::Zero());
- EXPECT_TRUE(manager_->IsAckFrameUpdated());
- EXPECT_EQ(1u, manager_->ack_frame().received_packet_times.size());
- RecordPacketReceipt(2,
- QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(1));
- EXPECT_EQ(2u, manager_->ack_frame().received_packet_times.size());
- RecordPacketReceipt(3, QuicTime::Zero());
- EXPECT_EQ(2u, manager_->ack_frame().received_packet_times.size());
-}
-
-TEST_F(UberReceivedPacketManagerTest, OutOfOrderReceiptCausesAckSent) {
- EXPECT_FALSE(HasPendingAck());
-
- RecordPacketReceipt(3, clock_.ApproximateNow());
- MaybeUpdateAckTimeout(kInstigateAck, 3);
- // Delayed ack is scheduled.
- CheckAckTimeout(clock_.ApproximateNow() + kDelayedAckTime);
-
- RecordPacketReceipt(2, clock_.ApproximateNow());
- MaybeUpdateAckTimeout(kInstigateAck, 2);
- CheckAckTimeout(clock_.ApproximateNow());
-
- RecordPacketReceipt(1, clock_.ApproximateNow());
- MaybeUpdateAckTimeout(kInstigateAck, 1);
- // Should ack immediately, since this fills the last hole.
- CheckAckTimeout(clock_.ApproximateNow());
-
- RecordPacketReceipt(4, clock_.ApproximateNow());
- MaybeUpdateAckTimeout(kInstigateAck, 4);
- // Delayed ack is scheduled.
- CheckAckTimeout(clock_.ApproximateNow() + kDelayedAckTime);
-}
-
-TEST_F(UberReceivedPacketManagerTest, OutOfOrderAckReceiptCausesNoAck) {
- EXPECT_FALSE(HasPendingAck());
-
- RecordPacketReceipt(2, clock_.ApproximateNow());
- MaybeUpdateAckTimeout(!kInstigateAck, 2);
- EXPECT_FALSE(HasPendingAck());
-
- RecordPacketReceipt(1, clock_.ApproximateNow());
- MaybeUpdateAckTimeout(!kInstigateAck, 1);
- EXPECT_FALSE(HasPendingAck());
-}
-
-TEST_F(UberReceivedPacketManagerTest, AckReceiptCausesAckSend) {
- EXPECT_FALSE(HasPendingAck());
-
- RecordPacketReceipt(1, clock_.ApproximateNow());
- MaybeUpdateAckTimeout(!kInstigateAck, 1);
- EXPECT_FALSE(HasPendingAck());
-
- RecordPacketReceipt(2, clock_.ApproximateNow());
- MaybeUpdateAckTimeout(!kInstigateAck, 2);
- EXPECT_FALSE(HasPendingAck());
-
- RecordPacketReceipt(3, clock_.ApproximateNow());
- MaybeUpdateAckTimeout(kInstigateAck, 3);
- // Delayed ack is scheduled.
- CheckAckTimeout(clock_.ApproximateNow() + kDelayedAckTime);
- clock_.AdvanceTime(kDelayedAckTime);
- CheckAckTimeout(clock_.ApproximateNow());
-
- RecordPacketReceipt(4, clock_.ApproximateNow());
- MaybeUpdateAckTimeout(!kInstigateAck, 4);
- EXPECT_FALSE(HasPendingAck());
-
- RecordPacketReceipt(5, clock_.ApproximateNow());
- MaybeUpdateAckTimeout(!kInstigateAck, 5);
- EXPECT_FALSE(HasPendingAck());
-}
-
-TEST_F(UberReceivedPacketManagerTest, AckSentEveryNthPacket) {
- EXPECT_FALSE(HasPendingAck());
- manager_->set_ack_frequency(3);
-
- // Receives packets 1 - 39.
- for (size_t i = 1; i <= 39; ++i) {
- RecordPacketReceipt(i, clock_.ApproximateNow());
- MaybeUpdateAckTimeout(kInstigateAck, i);
- if (i % 3 == 0) {
- CheckAckTimeout(clock_.ApproximateNow());
- } else {
- CheckAckTimeout(clock_.ApproximateNow() + kDelayedAckTime);
- }
- }
-}
-
-TEST_F(UberReceivedPacketManagerTest, AckDecimationReducesAcks) {
- EXPECT_FALSE(HasPendingAck());
-
- // Start ack decimation from 10th packet.
- manager_->set_min_received_before_ack_decimation(10);
-
- // Receives packets 1 - 29.
- for (size_t i = 1; i <= 29; ++i) {
- RecordPacketReceipt(i, clock_.ApproximateNow());
- MaybeUpdateAckTimeout(kInstigateAck, i);
- if (i <= 10) {
- // For packets 1-10, ack every 2 packets.
- if (i % 2 == 0) {
- CheckAckTimeout(clock_.ApproximateNow());
- } else {
- CheckAckTimeout(clock_.ApproximateNow() + kDelayedAckTime);
- }
- continue;
- }
- // ack at 20.
- if (i == 20) {
- CheckAckTimeout(clock_.ApproximateNow());
- } else {
- CheckAckTimeout(clock_.ApproximateNow() + kMinRttMs * 0.25);
- }
- }
-
- // We now receive the 30th packet, and so we send an ack.
- RecordPacketReceipt(30, clock_.ApproximateNow());
- MaybeUpdateAckTimeout(kInstigateAck, 30);
- CheckAckTimeout(clock_.ApproximateNow());
-}
-
-TEST_F(UberReceivedPacketManagerTest, SendDelayedAckDecimation) {
- EXPECT_FALSE(HasPendingAck());
- // The ack time should be based on min_rtt * 1/4, since it's less than the
- // default delayed ack time.
- QuicTime ack_time = clock_.ApproximateNow() + kMinRttMs * 0.25;
-
- // Process all the packets in order so there aren't missing packets.
- uint64_t kFirstDecimatedPacket = 101;
- for (uint64_t i = 1; i < kFirstDecimatedPacket; ++i) {
- RecordPacketReceipt(i, clock_.ApproximateNow());
- MaybeUpdateAckTimeout(kInstigateAck, i);
- if (i % 2 == 0) {
- // Ack every 2 packets by default.
- CheckAckTimeout(clock_.ApproximateNow());
- } else {
- CheckAckTimeout(clock_.ApproximateNow() + kDelayedAckTime);
- }
- }
-
- RecordPacketReceipt(kFirstDecimatedPacket, clock_.ApproximateNow());
- MaybeUpdateAckTimeout(kInstigateAck, kFirstDecimatedPacket);
- CheckAckTimeout(ack_time);
-
- // The 10th received packet causes an ack to be sent.
- for (uint64_t i = 1; i < 10; ++i) {
- RecordPacketReceipt(kFirstDecimatedPacket + i, clock_.ApproximateNow());
- MaybeUpdateAckTimeout(kInstigateAck, kFirstDecimatedPacket + i);
- }
- CheckAckTimeout(clock_.ApproximateNow());
-}
-
-TEST_F(UberReceivedPacketManagerTest,
- SendDelayedAckDecimationUnlimitedAggregation) {
- EXPECT_FALSE(HasPendingAck());
- QuicConfig config;
- QuicTagVector connection_options;
- // No limit on the number of packets received before sending an ack.
- connection_options.push_back(kAKDU);
- config.SetConnectionOptionsToSend(connection_options);
- manager_->SetFromConfig(config, Perspective::IS_CLIENT);
-
- // The ack time should be based on min_rtt/4, since it's less than the
- // default delayed ack time.
- QuicTime ack_time = clock_.ApproximateNow() + kMinRttMs * 0.25;
-
- // Process all the initial packets in order so there aren't missing packets.
- uint64_t kFirstDecimatedPacket = 101;
- for (uint64_t i = 1; i < kFirstDecimatedPacket; ++i) {
- RecordPacketReceipt(i, clock_.ApproximateNow());
- MaybeUpdateAckTimeout(kInstigateAck, i);
- if (i % 2 == 0) {
- // Ack every 2 packets by default.
- CheckAckTimeout(clock_.ApproximateNow());
- } else {
- CheckAckTimeout(clock_.ApproximateNow() + kDelayedAckTime);
- }
- }
-
- RecordPacketReceipt(kFirstDecimatedPacket, clock_.ApproximateNow());
- MaybeUpdateAckTimeout(kInstigateAck, kFirstDecimatedPacket);
- CheckAckTimeout(ack_time);
-
- // 18 packets will not cause an ack to be sent. 19 will because when
- // stop waiting frames are in use, we ack every 20 packets no matter what.
- for (int i = 1; i <= 18; ++i) {
- RecordPacketReceipt(kFirstDecimatedPacket + i, clock_.ApproximateNow());
- MaybeUpdateAckTimeout(kInstigateAck, kFirstDecimatedPacket + i);
- }
- CheckAckTimeout(ack_time);
-}
-
-TEST_F(UberReceivedPacketManagerTest, SendDelayedAckDecimationEighthRtt) {
- EXPECT_FALSE(HasPendingAck());
- UberReceivedPacketManagerPeer::SetAckDecimationDelay(manager_.get(), 0.125);
-
- // The ack time should be based on min_rtt/8, since it's less than the
- // default delayed ack time.
- QuicTime ack_time = clock_.ApproximateNow() + kMinRttMs * 0.125;
-
- // Process all the packets in order so there aren't missing packets.
- uint64_t kFirstDecimatedPacket = 101;
- for (uint64_t i = 1; i < kFirstDecimatedPacket; ++i) {
- RecordPacketReceipt(i, clock_.ApproximateNow());
- MaybeUpdateAckTimeout(kInstigateAck, i);
- if (i % 2 == 0) {
- // Ack every 2 packets by default.
- CheckAckTimeout(clock_.ApproximateNow());
- } else {
- CheckAckTimeout(clock_.ApproximateNow() + kDelayedAckTime);
- }
- }
-
- RecordPacketReceipt(kFirstDecimatedPacket, clock_.ApproximateNow());
- MaybeUpdateAckTimeout(kInstigateAck, kFirstDecimatedPacket);
- CheckAckTimeout(ack_time);
-
- // The 10th received packet causes an ack to be sent.
- for (uint64_t i = 1; i < 10; ++i) {
- RecordPacketReceipt(kFirstDecimatedPacket + i, clock_.ApproximateNow());
- MaybeUpdateAckTimeout(kInstigateAck, kFirstDecimatedPacket + i);
- }
- CheckAckTimeout(clock_.ApproximateNow());
-}
-
-TEST_F(UberReceivedPacketManagerTest,
- DontWaitForPacketsBeforeMultiplePacketNumberSpaces) {
- manager_->EnableMultiplePacketNumberSpacesSupport(Perspective::IS_CLIENT);
- EXPECT_FALSE(
- manager_->GetLargestObserved(ENCRYPTION_HANDSHAKE).IsInitialized());
- EXPECT_FALSE(
- manager_->GetLargestObserved(ENCRYPTION_FORWARD_SECURE).IsInitialized());
- RecordPacketReceipt(ENCRYPTION_HANDSHAKE, 2);
- RecordPacketReceipt(ENCRYPTION_HANDSHAKE, 4);
- RecordPacketReceipt(ENCRYPTION_FORWARD_SECURE, 3);
- RecordPacketReceipt(ENCRYPTION_FORWARD_SECURE, 7);
- EXPECT_EQ(QuicPacketNumber(4),
- manager_->GetLargestObserved(ENCRYPTION_HANDSHAKE));
- EXPECT_EQ(QuicPacketNumber(7),
- manager_->GetLargestObserved(ENCRYPTION_FORWARD_SECURE));
-
- EXPECT_TRUE(
- manager_->IsAwaitingPacket(ENCRYPTION_HANDSHAKE, QuicPacketNumber(3)));
- EXPECT_FALSE(manager_->IsAwaitingPacket(ENCRYPTION_FORWARD_SECURE,
- QuicPacketNumber(3)));
- EXPECT_TRUE(manager_->IsAwaitingPacket(ENCRYPTION_FORWARD_SECURE,
- QuicPacketNumber(4)));
-
- manager_->DontWaitForPacketsBefore(ENCRYPTION_FORWARD_SECURE,
- QuicPacketNumber(5));
- EXPECT_TRUE(
- manager_->IsAwaitingPacket(ENCRYPTION_HANDSHAKE, QuicPacketNumber(3)));
- EXPECT_FALSE(manager_->IsAwaitingPacket(ENCRYPTION_FORWARD_SECURE,
- QuicPacketNumber(4)));
-}
-
-TEST_F(UberReceivedPacketManagerTest, AckSendingDifferentPacketNumberSpaces) {
- manager_->EnableMultiplePacketNumberSpacesSupport(Perspective::IS_SERVER);
- EXPECT_FALSE(HasPendingAck());
- EXPECT_FALSE(manager_->IsAckFrameUpdated());
-
- RecordPacketReceipt(ENCRYPTION_INITIAL, 3);
- EXPECT_TRUE(manager_->IsAckFrameUpdated());
- MaybeUpdateAckTimeout(kInstigateAck, ENCRYPTION_INITIAL, 3);
- EXPECT_TRUE(HasPendingAck());
- // Delayed ack is scheduled.
- CheckAckTimeout(clock_.ApproximateNow() +
- QuicTime::Delta::FromMilliseconds(25));
- // Send delayed handshake data ACK.
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(25));
- CheckAckTimeout(clock_.ApproximateNow());
- EXPECT_FALSE(HasPendingAck());
-
- // Second delayed ack should have a shorter delay.
- RecordPacketReceipt(ENCRYPTION_INITIAL, 4);
- EXPECT_TRUE(manager_->IsAckFrameUpdated());
- MaybeUpdateAckTimeout(kInstigateAck, ENCRYPTION_INITIAL, 4);
- EXPECT_TRUE(HasPendingAck());
- // Delayed ack is scheduled.
- CheckAckTimeout(clock_.ApproximateNow() +
- QuicTime::Delta::FromMilliseconds(1));
- // Send delayed handshake data ACK.
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(1));
- CheckAckTimeout(clock_.ApproximateNow());
- EXPECT_FALSE(HasPendingAck());
-
- RecordPacketReceipt(ENCRYPTION_HANDSHAKE, 3);
- EXPECT_TRUE(manager_->IsAckFrameUpdated());
- MaybeUpdateAckTimeout(kInstigateAck, ENCRYPTION_HANDSHAKE, 3);
- EXPECT_TRUE(HasPendingAck());
- // Delayed ack is scheduled.
- CheckAckTimeout(clock_.ApproximateNow() +
- QuicTime::Delta::FromMilliseconds(1));
- // Send delayed handshake data ACK.
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(1));
- CheckAckTimeout(clock_.ApproximateNow());
- EXPECT_FALSE(HasPendingAck());
-
- RecordPacketReceipt(ENCRYPTION_FORWARD_SECURE, 3);
- MaybeUpdateAckTimeout(kInstigateAck, ENCRYPTION_FORWARD_SECURE, 3);
- EXPECT_TRUE(HasPendingAck());
- // Delayed ack is scheduled.
- CheckAckTimeout(clock_.ApproximateNow() + kDelayedAckTime);
-
- RecordPacketReceipt(ENCRYPTION_FORWARD_SECURE, 2);
- MaybeUpdateAckTimeout(kInstigateAck, ENCRYPTION_FORWARD_SECURE, 2);
- // Application data ACK should be sent immediately.
- CheckAckTimeout(clock_.ApproximateNow());
- EXPECT_FALSE(HasPendingAck());
-}
-
-} // namespace
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/web_transport_interface.h b/chromium/net/third_party/quiche/src/quic/core/web_transport_interface.h
deleted file mode 100644
index 102fd1fccef..00000000000
--- a/chromium/net/third_party/quiche/src/quic/core/web_transport_interface.h
+++ /dev/null
@@ -1,151 +0,0 @@
-// Copyright (c) 2021 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// This header contains interfaces that abstract away different backing
-// protocols for WebTransport.
-
-#ifndef QUICHE_QUIC_CORE_WEB_TRANSPORT_INTERFACE_H_
-#define QUICHE_QUIC_CORE_WEB_TRANSPORT_INTERFACE_H_
-
-#include <cstddef>
-#include <memory>
-
-#include "absl/base/attributes.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_datagram_queue.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_export.h"
-#include "spdy/core/spdy_header_block.h"
-
-namespace quic {
-
-// Visitor that gets notified about events related to a WebTransport stream.
-class QUIC_EXPORT_PRIVATE WebTransportStreamVisitor {
- public:
- virtual ~WebTransportStreamVisitor() {}
-
- // Called whenever the stream has readable data available.
- virtual void OnCanRead() = 0;
- // Called whenever the stream is not write-blocked and can accept new data.
- virtual void OnCanWrite() = 0;
-
- // Called when RESET_STREAM is received for the stream.
- virtual void OnResetStreamReceived(WebTransportStreamError error) = 0;
- // Called when STOP_SENDING is received for the stream.
- virtual void OnStopSendingReceived(WebTransportStreamError error) = 0;
- // Called when the write side of the stream is closed and all of the data sent
- // has been acknowledged ("Data Recvd" state of RFC 9000).
- virtual void OnWriteSideInDataRecvdState() = 0;
-};
-
-// A stream (either bidirectional or unidirectional) that is contained within a
-// WebTransport session.
-class QUIC_EXPORT_PRIVATE WebTransportStream {
- public:
- struct QUIC_EXPORT_PRIVATE ReadResult {
- // Number of bytes actually read.
- size_t bytes_read;
- // Whether the FIN has been received; if true, no further data will arrive
- // on the stream, and the stream object can be soon potentially garbage
- // collected.
- bool fin;
- };
-
- virtual ~WebTransportStream() {}
-
- // Reads at most |buffer_size| bytes into |buffer|.
- ABSL_MUST_USE_RESULT virtual ReadResult Read(char* buffer,
- size_t buffer_size) = 0;
- // Reads all available data and appends it to the end of |output|.
- ABSL_MUST_USE_RESULT virtual ReadResult Read(std::string* output) = 0;
- // Writes |data| into the stream. Returns true on success.
- ABSL_MUST_USE_RESULT virtual bool Write(absl::string_view data) = 0;
- // Sends the FIN on the stream. Returns true on success.
- ABSL_MUST_USE_RESULT virtual bool SendFin() = 0;
-
- // Indicates whether it is possible to write into stream right now.
- virtual bool CanWrite() const = 0;
- // Indicates the number of bytes that can be read from the stream.
- virtual size_t ReadableBytes() const = 0;
-
- // An ID that is unique within the session. Those are not exposed to the user
- // via the web API, but can be used internally for bookkeeping and
- // diagnostics.
- virtual QuicStreamId GetStreamId() const = 0;
-
- // Resets the stream with the specified error code.
- virtual void ResetWithUserCode(WebTransportStreamError error) = 0;
- virtual void ResetDueToInternalError() = 0;
- virtual void SendStopSending(WebTransportStreamError error) = 0;
- // Called when the owning object has been garbage-collected.
- virtual void MaybeResetDueToStreamObjectGone() = 0;
-
- virtual WebTransportStreamVisitor* visitor() = 0;
- virtual void SetVisitor(
- std::unique_ptr<WebTransportStreamVisitor> visitor) = 0;
-};
-
-// Visitor that gets notified about events related to a WebTransport session.
-class QUIC_EXPORT_PRIVATE WebTransportVisitor {
- public:
- virtual ~WebTransportVisitor() {}
-
- // Notifies the visitor when the session is ready to exchange application
- // data.
- virtual void OnSessionReady(const spdy::SpdyHeaderBlock& headers) = 0;
-
- // Notifies the visitor when the session has been closed.
- virtual void OnSessionClosed(WebTransportSessionError error_code,
- const std::string& error_message) = 0;
-
- // Notifies the visitor when a new stream has been received. The stream in
- // question can be retrieved using AcceptIncomingBidirectionalStream() or
- // AcceptIncomingUnidirectionalStream().
- virtual void OnIncomingBidirectionalStreamAvailable() = 0;
- virtual void OnIncomingUnidirectionalStreamAvailable() = 0;
-
- // Notifies the visitor when a new datagram has been received.
- virtual void OnDatagramReceived(absl::string_view datagram) = 0;
-
- // Notifies the visitor that a new outgoing stream can now be created.
- virtual void OnCanCreateNewOutgoingBidirectionalStream() = 0;
- virtual void OnCanCreateNewOutgoingUnidirectionalStream() = 0;
-};
-
-// An abstract interface for a WebTransport session.
-class QUIC_EXPORT_PRIVATE WebTransportSession {
- public:
- virtual ~WebTransportSession() {}
-
- // Closes the WebTransport session in question with the specified |error_code|
- // and |error_message|.
- virtual void CloseSession(WebTransportSessionError error_code,
- absl::string_view error_message) = 0;
-
- // Return the earliest incoming stream that has been received by the session
- // but has not been accepted. Returns nullptr if there are no incoming
- // streams.
- virtual WebTransportStream* AcceptIncomingBidirectionalStream() = 0;
- virtual WebTransportStream* AcceptIncomingUnidirectionalStream() = 0;
-
- // Returns true if flow control allows opening a new stream.
- virtual bool CanOpenNextOutgoingBidirectionalStream() = 0;
- virtual bool CanOpenNextOutgoingUnidirectionalStream() = 0;
- // Opens a new WebTransport stream, or returns nullptr if that is not possible
- // due to flow control.
- virtual WebTransportStream* OpenOutgoingBidirectionalStream() = 0;
- virtual WebTransportStream* OpenOutgoingUnidirectionalStream() = 0;
-
- virtual MessageStatus SendOrQueueDatagram(QuicMemSlice datagram) = 0;
- // Returns a conservative estimate of the largest datagram size that the
- // session would be able to send.
- virtual QuicByteCount GetMaxDatagramSize() const = 0;
- // Sets the largest duration that a datagram can spend in the queue before
- // being silently dropped.
- virtual void SetDatagramMaxTimeInQueue(QuicTime::Delta max_time_in_queue) = 0;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_CORE_WEB_TRANSPORT_INTERFACE_H_
diff --git a/chromium/net/third_party/quiche/src/quic/masque/README.md b/chromium/net/third_party/quiche/src/quic/masque/README.md
deleted file mode 100644
index 6bfc08ee0f8..00000000000
--- a/chromium/net/third_party/quiche/src/quic/masque/README.md
+++ /dev/null
@@ -1,4 +0,0 @@
-# MASQUE
-
-The files in this directory implement MASQUE as described in
-<https://tools.ietf.org/html/draft-schinazi-masque>.
diff --git a/chromium/net/third_party/quiche/src/quic/masque/masque_client_bin.cc b/chromium/net/third_party/quiche/src/quic/masque/masque_client_bin.cc
deleted file mode 100644
index fb6a61d5b5a..00000000000
--- a/chromium/net/third_party/quiche/src/quic/masque/masque_client_bin.cc
+++ /dev/null
@@ -1,118 +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.
-
-// This file is reponsible for the masque_client binary. It allows testing
-// our MASQUE client code by connecting to a MASQUE proxy and then sending
-// HTTP/3 requests to web servers tunnelled over that MASQUE connection.
-// e.g.: masque_client $PROXY_HOST:$PROXY_PORT $URL1 $URL2
-
-#include <memory>
-#include <string>
-
-#include "absl/strings/str_cat.h"
-#include "absl/strings/string_view.h"
-#include "url/third_party/mozilla/url_parse.h"
-#include "quic/core/quic_server_id.h"
-#include "quic/masque/masque_client_tools.h"
-#include "quic/masque/masque_encapsulated_epoll_client.h"
-#include "quic/masque/masque_epoll_client.h"
-#include "quic/masque/masque_utils.h"
-#include "quic/platform/api/quic_default_proof_providers.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_socket_address.h"
-#include "quic/platform/api/quic_system_event_loop.h"
-#include "quic/tools/fake_proof_verifier.h"
-#include "common/platform/api/quiche_command_line_flags.h"
-
-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.");
-
-namespace quic {
-
-namespace {
-
-int RunMasqueClient(int argc, char* argv[]) {
- QuicSystemEventLoop event_loop("masque_client");
- const char* usage = "Usage: masque_client [options] <url>";
-
- // The first non-flag argument is the URI template of the MASQUE server.
- // All subsequent ones are interpreted as URLs to fetch via the MASQUE server.
- // Note that the URI template expansion currently only supports string
- // replacement of {target_host} and {target_port}, not
- // {?target_host,target_port}.
- std::vector<std::string> urls =
- quiche::QuicheParseCommandLineFlags(usage, argc, argv);
- if (urls.empty()) {
- quiche::QuichePrintCommandLineFlagHelp(usage);
- return 1;
- }
-
- const bool disable_certificate_verification =
- GetQuicFlag(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.
- uri_template =
- absl::StrCat("https://", uri_template, "/{target_host}/{target_port}/");
- }
- url::Parsed parsed_uri_template;
- url::ParseStandardURL(uri_template.c_str(), uri_template.length(),
- &parsed_uri_template);
- if (!parsed_uri_template.scheme.is_nonempty() ||
- !parsed_uri_template.host.is_nonempty() ||
- !parsed_uri_template.path.is_nonempty()) {
- std::cerr << "Failed to parse MASQUE URI template \"" << urls[0] << "\""
- << std::endl;
- return 1;
- }
- std::string host = uri_template.substr(parsed_uri_template.host.begin,
- parsed_uri_template.host.len);
- std::unique_ptr<ProofVerifier> proof_verifier;
- if (disable_certificate_verification) {
- proof_verifier = std::make_unique<FakeProofVerifier>();
- } else {
- 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::cerr << "Invalid masque_mode \"" << mode_string << "\"" << std::endl;
- return 1;
- }
- std::unique_ptr<MasqueEpollClient> masque_client = MasqueEpollClient::Create(
- uri_template, masque_mode, &epoll_server, std::move(proof_verifier));
- if (masque_client == nullptr) {
- return 1;
- }
-
- std::cerr << "MASQUE is connected " << masque_client->connection_id()
- << " in " << masque_mode << " mode" << std::endl;
-
- for (size_t i = 1; i < urls.size(); ++i) {
- if (!tools::SendEncapsulatedMasqueRequest(
- masque_client.get(), &epoll_server, urls[i],
- disable_certificate_verification)) {
- return 1;
- }
- }
-
- return 0;
-}
-
-} // namespace
-
-} // namespace quic
-
-int main(int argc, char* argv[]) {
- return quic::RunMasqueClient(argc, argv);
-}
diff --git a/chromium/net/third_party/quiche/src/quic/masque/masque_client_session.cc b/chromium/net/third_party/quiche/src/quic/masque/masque_client_session.cc
deleted file mode 100644
index 884cd20bbe3..00000000000
--- a/chromium/net/third_party/quiche/src/quic/masque/masque_client_session.cc
+++ /dev/null
@@ -1,435 +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 "quic/masque/masque_client_session.h"
-
-#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 "url/url_canon.h"
-#include "quic/core/http/spdy_utils.h"
-#include "quic/core/quic_data_reader.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_socket_address.h"
-#include "quic/tools/quic_url.h"
-#include "common/platform/api/quiche_url_utils.h"
-
-namespace quic {
-
-MasqueClientSession::MasqueClientSession(
- MasqueMode masque_mode, const std::string& uri_template,
- const QuicConfig& config, const ParsedQuicVersionVector& supported_versions,
- QuicConnection* connection, const QuicServerId& server_id,
- QuicCryptoClientConfig* crypto_config,
- QuicClientPushPromiseIndex* push_promise_index, Owner* owner)
- : QuicSpdyClientSession(config, supported_versions, connection, server_id,
- 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);
-}
-
-void MasqueClientSession::OnMessageAcked(QuicMessageId message_id,
- QuicTime /*receive_timestamp*/) {
- QUIC_DVLOG(1) << "Received ack for DATAGRAM frame " << message_id;
-}
-
-void MasqueClientSession::OnMessageLost(QuicMessageId message_id) {
- QUIC_DVLOG(1) << "We believe DATAGRAM frame " << message_id << " was lost";
-}
-
-const MasqueClientSession::ConnectUdpClientState*
-MasqueClientSession::GetOrCreateConnectUdpClientState(
- const QuicSocketAddress& target_server_address,
- EncapsulatedClientSession* encapsulated_client_session) {
- for (const ConnectUdpClientState& client_state : connect_udp_client_states_) {
- if (client_state.target_server_address() == target_server_address &&
- client_state.encapsulated_client_session() ==
- encapsulated_client_session) {
- // Found existing CONNECT-UDP request.
- return &client_state;
- }
- }
- // No CONNECT-UDP request found, create a new one.
-
- url::Parsed parsed_uri_template;
- url::ParseStandardURL(uri_template_.c_str(), uri_template_.length(),
- &parsed_uri_template);
- if (!parsed_uri_template.path.is_nonempty()) {
- QUIC_BUG(bad URI template path)
- << "Cannot parse path from URI template " << uri_template_;
- return nullptr;
- }
- std::string path = uri_template_.substr(parsed_uri_template.path.begin,
- parsed_uri_template.path.len);
- if (parsed_uri_template.query.is_valid()) {
- absl::StrAppend(&path, "?",
- uri_template_.substr(parsed_uri_template.query.begin,
- parsed_uri_template.query.len));
- }
- absl::flat_hash_map<std::string, std::string> parameters;
- parameters["target_host"] = target_server_address.host().ToString();
- parameters["target_port"] = absl::StrCat(target_server_address.port());
- std::string expanded_path;
- absl::flat_hash_set<std::string> vars_found;
- bool expanded =
- quiche::ExpandURITemplate(path, parameters, &expanded_path, &vars_found);
- if (!expanded || vars_found.find("target_host") == vars_found.end() ||
- vars_found.find("target_port") == vars_found.end()) {
- QUIC_DLOG(ERROR) << "Failed to expand URI template \"" << uri_template_
- << "\" for " << target_server_address;
- return nullptr;
- }
-
- url::Component expanded_path_component(0, expanded_path.length());
- url::RawCanonOutput<1024> canonicalized_path_output;
- url::Component canonicalized_path_component;
- bool canonicalized = url::CanonicalizePath(
- expanded_path.c_str(), expanded_path_component,
- &canonicalized_path_output, &canonicalized_path_component);
- if (!canonicalized || !canonicalized_path_component.is_nonempty()) {
- QUIC_DLOG(ERROR) << "Failed to canonicalize URI template \""
- << uri_template_ << "\" for " << target_server_address;
- return nullptr;
- }
- std::string canonicalized_path(
- canonicalized_path_output.data() + canonicalized_path_component.begin,
- canonicalized_path_component.len);
-
- QuicSpdyClientStream* stream = CreateOutgoingBidirectionalStream();
- if (stream == nullptr) {
- // Stream flow control limits prevented us from opening a new stream.
- QUIC_DLOG(ERROR) << "Failed to open CONNECT-UDP stream";
- return nullptr;
- }
-
- QuicUrl url(uri_template_);
- std::string scheme = url.scheme();
- std::string authority = url.HostPort();
-
- QUIC_DLOG(INFO) << "Sending CONNECT-UDP request for " << target_server_address
- << " on stream " << stream->id() << " scheme=\"" << scheme
- << "\" authority=\"" << authority << "\" path=\""
- << canonicalized_path << "\"";
-
- // Send the request.
- spdy::Http2HeaderBlock headers;
- headers[":method"] = "CONNECT";
- headers[":protocol"] = "connect-udp";
- 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());
- }
- size_t bytes_sent =
- stream->SendRequest(std::move(headers), /*body=*/"", /*fin=*/false);
- if (bytes_sent == 0) {
- QUIC_DLOG(ERROR) << "Failed to send CONNECT-UDP request";
- return nullptr;
- }
-
- absl::optional<QuicDatagramContextId> context_id;
- connect_udp_client_states_.push_back(
- ConnectUdpClientState(stream, encapsulated_client_session, this,
- context_id, 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,
- 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) {
- QUIC_DLOG(ERROR) << "Failed to create CONNECT-UDP request";
- return;
- }
-
- MessageStatus message_status = SendHttp3Datagram(
- connect_udp->stream()->id(), connect_udp->context_id(), packet);
-
- 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,
- 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");
- auto* stream = it->stream();
- it = connect_udp_client_states_.erase(it);
- if (!stream->write_side_closed()) {
- stream->Reset(QUIC_STREAM_CANCELLED);
- }
- } else {
- ++it;
- }
- }
-}
-
-void MasqueClientSession::OnConnectionClosed(
- const QuicConnectionCloseFrame& frame, ConnectionCloseSource source) {
- QuicSpdyClientSession::OnConnectionClosed(frame, source);
- // Close all encapsulated sessions.
- for (const auto& client_state : connect_udp_client_states_) {
- client_state.encapsulated_client_session()->CloseConnection(
- QUIC_CONNECTION_CANCELLED, "Underlying MASQUE connection was closed",
- ConnectionCloseBehavior::SILENT_CLOSE);
- }
-}
-
-void MasqueClientSession::OnStreamClosed(QuicStreamId stream_id) {
- if (QuicUtils::IsBidirectionalStreamId(stream_id, version()) &&
- QuicUtils::IsClientInitiatedStreamId(transport_version(), stream_id)) {
- QuicSpdyClientStream* stream =
- reinterpret_cast<QuicSpdyClientStream*>(GetActiveStream(stream_id));
- if (stream != nullptr) {
- QUIC_DLOG(INFO) << "Stream " << stream_id
- << " closed, got response headers:"
- << stream->response_headers().DebugString();
- }
- }
- for (auto it = connect_udp_client_states_.begin();
- 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");
- auto* encapsulated_client_session = it->encapsulated_client_session();
- it = connect_udp_client_states_.erase(it);
- encapsulated_client_session->CloseConnection(
- QUIC_CONNECTION_CANCELLED,
- "Underlying MASQUE CONNECT-UDP stream was closed",
- ConnectionCloseBehavior::SILENT_CLOSE);
- } else {
- ++it;
- }
- }
-
- QuicSpdyClientSession::OnStreamClosed(stream_id);
-}
-
-bool MasqueClientSession::OnSettingsFrame(const SettingsFrame& frame) {
- QUIC_DLOG(INFO) << "Received SETTINGS: " << frame;
- if (!QuicSpdyClientSession::OnSettingsFrame(frame)) {
- QUIC_DLOG(ERROR) << "Failed to parse received settings";
- return false;
- }
- if (!SupportsH3Datagram()) {
- QUIC_DLOG(ERROR) << "Refusing to use MASQUE without HTTP/3 Datagrams";
- return false;
- }
- QUIC_DLOG(INFO) << "Using HTTP Datagram: " << http_datagram_support();
- owner_->OnSettingsReceived();
- return true;
-}
-
-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);
-}
-
-MasqueClientSession::ConnectUdpClientState::~ConnectUdpClientState() {
- if (stream() != nullptr) {
- stream()->UnregisterHttp3DatagramContextId(context_id());
- stream()->UnregisterHttp3DatagramRegistrationVisitor();
- }
-}
-
-MasqueClientSession::ConnectUdpClientState::ConnectUdpClientState(
- MasqueClientSession::ConnectUdpClientState&& other) {
- *this = std::move(other);
-}
-
-MasqueClientSession::ConnectUdpClientState&
-MasqueClientSession::ConnectUdpClientState::operator=(
- MasqueClientSession::ConnectUdpClientState&& other) {
- 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);
- }
- return *this;
-}
-
-void MasqueClientSession::ConnectUdpClientState::OnHttp3Datagram(
- QuicStreamId stream_id, absl::optional<QuicDatagramContextId> context_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();
- 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/quic/masque/masque_client_session.h b/chromium/net/third_party/quiche/src/quic/masque/masque_client_session.h
deleted file mode 100644
index f8af4afd0e9..00000000000
--- a/chromium/net/third_party/quiche/src/quic/masque/masque_client_session.h
+++ /dev/null
@@ -1,186 +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_CLIENT_SESSION_H_
-#define QUICHE_QUIC_MASQUE_MASQUE_CLIENT_SESSION_H_
-
-#include <string>
-
-#include "absl/container/flat_hash_map.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/http/quic_spdy_client_session.h"
-#include "quic/masque/masque_compression_engine.h"
-#include "quic/masque/masque_utils.h"
-#include "quic/platform/api/quic_export.h"
-#include "quic/platform/api/quic_socket_address.h"
-
-namespace quic {
-
-// QUIC client session for connection to MASQUE proxy. This session establishes
-// a connection to a MASQUE proxy and handles sending and receiving DATAGRAM
-// frames for operation of the MASQUE protocol. Multiple end-to-end encapsulated
-// sessions can then coexist inside this session. Once these are created, they
-// need to be registered with this session.
-class QUIC_NO_EXPORT MasqueClientSession : public QuicSpdyClientSession {
- public:
- // Interface meant to be implemented by the owner of the
- // MasqueClientSession instance.
- class QUIC_NO_EXPORT Owner {
- 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;
- };
- // Interface meant to be implemented by encapsulated client sessions, i.e.
- // the end-to-end QUIC client sessions that run inside MASQUE encapsulation.
- class QUIC_NO_EXPORT EncapsulatedClientSession {
- public:
- virtual ~EncapsulatedClientSession() {}
-
- // Process packet that was just decapsulated.
- virtual void ProcessPacket(absl::string_view packet,
- QuicSocketAddress target_server_address) = 0;
-
- // Close the encapsulated connection.
- virtual void CloseConnection(
- QuicErrorCode error,
- const std::string& details,
- ConnectionCloseBehavior connection_close_behavior) = 0;
- };
-
- // Takes ownership of |connection|, but not of |crypto_config| or
- // |push_promise_index| or |owner|. All pointers must be non-null. Caller
- // must ensure that |push_promise_index| and |owner| stay valid for the
- // lifetime of the newly created MasqueClientSession.
- MasqueClientSession(MasqueMode masque_mode, const std::string& uri_template,
- const QuicConfig& config,
- const ParsedQuicVersionVector& supported_versions,
- QuicConnection* connection, const QuicServerId& server_id,
- QuicCryptoClientConfig* crypto_config,
- QuicClientPushPromiseIndex* push_promise_index,
- Owner* owner);
-
- // Disallow copy and assign.
- MasqueClientSession(const MasqueClientSession&) = delete;
- 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;
- void OnConnectionClosed(const QuicConnectionCloseFrame& frame,
- ConnectionCloseSource source) override;
- void OnStreamClosed(QuicStreamId stream_id) override;
-
- // From QuicSpdySession.
- bool OnSettingsFrame(const SettingsFrame& frame) override;
-
- // Send encapsulated packet.
- void SendPacket(QuicConnectionId client_connection_id,
- QuicConnectionId server_connection_id,
- 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,
- 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:
- // |stream| and |encapsulated_client_session| must be valid for the lifetime
- // of the ConnectUdpClientState.
- explicit ConnectUdpClientState(
- QuicSpdyClientStream* stream,
- EncapsulatedClientSession* encapsulated_client_session,
- MasqueClientSession* masque_session,
- absl::optional<QuicDatagramContextId> context_id,
- const QuicSocketAddress& target_server_address);
-
- ~ConnectUdpClientState();
-
- // Disallow copy but allow move.
- ConnectUdpClientState(const ConnectUdpClientState&) = delete;
- ConnectUdpClientState(ConnectUdpClientState&&);
- ConnectUdpClientState& operator=(const ConnectUdpClientState&) = delete;
- ConnectUdpClientState& operator=(ConnectUdpClientState&&);
-
- QuicSpdyClientStream* stream() const { return stream_; }
- 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;
- }
-
- const ConnectUdpClientState* GetOrCreateConnectUdpClientState(
- const QuicSocketAddress& target_server_address,
- EncapsulatedClientSession* encapsulated_client_session);
-
- 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
-
-#endif // QUICHE_QUIC_MASQUE_MASQUE_CLIENT_SESSION_H_
diff --git a/chromium/net/third_party/quiche/src/quic/masque/masque_client_tools.cc b/chromium/net/third_party/quiche/src/quic/masque/masque_client_tools.cc
deleted file mode 100644
index 7ab9bd41d7d..00000000000
--- a/chromium/net/third_party/quiche/src/quic/masque/masque_client_tools.cc
+++ /dev/null
@@ -1,107 +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 "quic/masque/masque_client_tools.h"
-#include "quic/masque/masque_encapsulated_epoll_client.h"
-#include "quic/masque/masque_utils.h"
-#include "quic/platform/api/quic_default_proof_providers.h"
-#include "quic/tools/fake_proof_verifier.h"
-#include "quic/tools/quic_url.h"
-
-namespace quic {
-namespace tools {
-
-bool SendEncapsulatedMasqueRequest(MasqueEpollClient* masque_client,
- QuicEpollServer* epoll_server,
- std::string url_string,
- bool disable_certificate_verification) {
- const QuicUrl url(url_string, "https");
- std::unique_ptr<ProofVerifier> proof_verifier;
- if (disable_certificate_verification) {
- proof_verifier = std::make_unique<FakeProofVerifier>();
- } else {
- proof_verifier = CreateDefaultProofVerifier(url.host());
- }
-
- // Build the client, and try to connect.
- const QuicSocketAddress addr =
- LookupAddress(url.host(), absl::StrCat(url.port()));
- if (!addr.IsInitialized()) {
- QUIC_LOG(ERROR) << "Unable to resolve address: " << url.host();
- return false;
- }
- const QuicServerId server_id(url.host(), url.port());
- auto client = std::make_unique<MasqueEncapsulatedEpollClient>(
- addr, server_id, epoll_server, std::move(proof_verifier), masque_client);
-
- if (client == nullptr) {
- QUIC_LOG(ERROR) << "Failed to create MasqueEncapsulatedEpollClient for "
- << url_string;
- return false;
- }
-
- client->set_initial_max_packet_length(kMasqueMaxEncapsulatedPacketSize);
- client->set_drop_response_body(false);
- if (!client->Initialize()) {
- QUIC_LOG(ERROR) << "Failed to initialize MasqueEncapsulatedEpollClient for "
- << url_string;
- return false;
- }
-
- if (!client->Connect()) {
- QuicErrorCode error = client->session()->error();
- QUIC_LOG(ERROR) << "Failed to connect with client "
- << client->session()->connection()->client_connection_id()
- << " server " << client->session()->connection_id()
- << " to " << url.HostPort()
- << ". Error: " << QuicErrorCodeToString(error);
- return false;
- }
-
- QUIC_LOG(INFO) << "Connected client "
- << client->session()->connection()->client_connection_id()
- << " server " << client->session()->connection_id() << " for "
- << url_string;
-
- // Construct the string body from flags, if provided.
- // TODO(dschinazi) Add support for HTTP POST and non-empty bodies.
- const std::string body = "";
-
- // Construct a GET or POST request for supplied URL.
- spdy::Http2HeaderBlock header_block;
- header_block[":method"] = "GET";
- header_block[":scheme"] = url.scheme();
- header_block[":authority"] = url.HostPort();
- header_block[":path"] = url.PathParamsQuery();
-
- // Make sure to store the response, for later output.
- client->set_store_response(true);
-
- // Send the MASQUE init request.
- client->SendRequestAndWaitForResponse(header_block, body,
- /*fin=*/true);
-
- if (!client->connected()) {
- QUIC_LOG(ERROR) << "Request for " << url_string
- << " caused connection failure. Error: "
- << QuicErrorCodeToString(client->session()->error());
- return false;
- }
-
- const int response_code = client->latest_response_code();
- if (response_code < 200 || response_code >= 300) {
- QUIC_LOG(ERROR) << "Request for " << url_string
- << " failed with HTTP response code " << response_code;
- return false;
- }
-
- const std::string response_body = client->latest_response_body();
- QUIC_LOG(INFO) << "Request succeeded for " << url_string << std::endl
- << response_body;
-
- return true;
-}
-
-} // namespace tools
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/masque/masque_client_tools.h b/chromium/net/third_party/quiche/src/quic/masque/masque_client_tools.h
deleted file mode 100644
index 30727df2d3f..00000000000
--- a/chromium/net/third_party/quiche/src/quic/masque/masque_client_tools.h
+++ /dev/null
@@ -1,25 +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_CLIENT_TOOLS_H_
-#define QUICHE_QUIC_MASQUE_MASQUE_CLIENT_TOOLS_H_
-
-#include "quic/masque/masque_epoll_client.h"
-
-namespace quic {
-namespace tools {
-
-// Sends an HTTP GET request for |url_string|, proxied over the MASQUE
-// connection represented by |masque_client|. A valid and owned |epoll_server|
-// is required. |disable_certificate_verification| allows disabling verification
-// of the HTTP server's TLS certificate.
-bool SendEncapsulatedMasqueRequest(MasqueEpollClient* masque_client,
- QuicEpollServer* epoll_server,
- std::string url_string,
- bool disable_certificate_verification);
-
-} // namespace tools
-} // namespace quic
-
-#endif // QUICHE_QUIC_MASQUE_MASQUE_CLIENT_TOOLS_H_
diff --git a/chromium/net/third_party/quiche/src/quic/masque/masque_compression_engine.cc b/chromium/net/third_party/quiche/src/quic/masque/masque_compression_engine.cc
deleted file mode 100644
index 035b9f9d030..00000000000
--- a/chromium/net/third_party/quiche/src/quic/masque/masque_compression_engine.cc
+++ /dev/null
@@ -1,525 +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 "quic/masque/masque_compression_engine.h"
-
-#include <cstdint>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_buffer_allocator.h"
-#include "quic/core/quic_data_reader.h"
-#include "quic/core/quic_data_writer.h"
-#include "quic/core/quic_framer.h"
-#include "quic/core/quic_session.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_versions.h"
-#include "quic/platform/api/quic_containers.h"
-#include "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();
- }
- QuicBuffer 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(QuicMemSlice(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/quic/masque/masque_compression_engine.h b/chromium/net/third_party/quiche/src/quic/masque/masque_compression_engine.h
deleted file mode 100644
index 581b9501791..00000000000
--- a/chromium/net/third_party/quiche/src/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_PROTOCOL_H_
-#define QUICHE_QUIC_MASQUE_MASQUE_PROTOCOL_H_
-
-#include "absl/container/flat_hash_map.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/http/quic_spdy_session.h"
-#include "quic/core/quic_connection_id.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_containers.h"
-#include "quic/platform/api/quic_export.h"
-#include "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_PROTOCOL_H_
diff --git a/chromium/net/third_party/quiche/src/quic/masque/masque_dispatcher.cc b/chromium/net/third_party/quiche/src/quic/masque/masque_dispatcher.cc
deleted file mode 100644
index c14e03d8f9b..00000000000
--- a/chromium/net/third_party/quiche/src/quic/masque/masque_dispatcher.cc
+++ /dev/null
@@ -1,92 +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 "quic/masque/masque_dispatcher.h"
-#include "quic/masque/masque_server_session.h"
-
-namespace quic {
-
-MasqueDispatcher::MasqueDispatcher(
- MasqueMode masque_mode,
- const QuicConfig* config,
- const QuicCryptoServerConfig* crypto_config,
- QuicVersionManager* version_manager,
- QuicEpollServer* epoll_server,
- std::unique_ptr<QuicConnectionHelperInterface> helper,
- std::unique_ptr<QuicCryptoServerStreamBase::Helper> session_helper,
- std::unique_ptr<QuicAlarmFactory> alarm_factory,
- MasqueServerBackend* masque_server_backend,
- uint8_t expected_server_connection_id_length)
- : QuicSimpleDispatcher(config,
- crypto_config,
- version_manager,
- std::move(helper),
- std::move(session_helper),
- std::move(alarm_factory),
- masque_server_backend,
- expected_server_connection_id_length),
- masque_mode_(masque_mode),
- epoll_server_(epoll_server),
- masque_server_backend_(masque_server_backend) {}
-
-std::unique_ptr<QuicSession> MasqueDispatcher::CreateQuicSession(
- QuicConnectionId connection_id, const QuicSocketAddress& self_address,
- const QuicSocketAddress& peer_address, absl::string_view /*alpn*/,
- const ParsedQuicVersion& version,
- const ParsedClientHello& /*parsed_chlo*/) {
- // The MasqueServerSession takes ownership of |connection| below.
- QuicConnection* connection =
- new QuicConnection(connection_id, self_address, peer_address, helper(),
- alarm_factory(), writer(),
- /*owns_writer=*/false, Perspective::IS_SERVER,
- ParsedQuicVersionVector{version});
-
- auto session = std::make_unique<MasqueServerSession>(
- masque_mode_, config(), GetSupportedVersions(), connection, this, 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/quic/masque/masque_dispatcher.h b/chromium/net/third_party/quiche/src/quic/masque/masque_dispatcher.h
deleted file mode 100644
index 35c5e0f4ede..00000000000
--- a/chromium/net/third_party/quiche/src/quic/masque/masque_dispatcher.h
+++ /dev/null
@@ -1,70 +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_DISPATCHER_H_
-#define QUICHE_QUIC_MASQUE_MASQUE_DISPATCHER_H_
-
-#include "absl/container/flat_hash_map.h"
-#include "quic/masque/masque_server_backend.h"
-#include "quic/masque/masque_server_session.h"
-#include "quic/masque/masque_utils.h"
-#include "quic/platform/api/quic_epoll.h"
-#include "quic/platform/api/quic_export.h"
-#include "quic/tools/quic_simple_dispatcher.h"
-
-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 {
- public:
- explicit MasqueDispatcher(
- MasqueMode masque_mode,
- const QuicConfig* config,
- const QuicCryptoServerConfig* crypto_config,
- QuicVersionManager* version_manager,
- QuicEpollServer* epoll_server,
- std::unique_ptr<QuicConnectionHelperInterface> helper,
- std::unique_ptr<QuicCryptoServerStreamBase::Helper> session_helper,
- std::unique_ptr<QuicAlarmFactory> alarm_factory,
- MasqueServerBackend* masque_server_backend,
- uint8_t expected_server_connection_id_length);
-
- // Disallow copy and assign.
- MasqueDispatcher(const MasqueDispatcher&) = delete;
- MasqueDispatcher& operator=(const MasqueDispatcher&) = delete;
-
- // From QuicSimpleDispatcher.
- std::unique_ptr<QuicSession> CreateQuicSession(
- QuicConnectionId connection_id, const QuicSocketAddress& self_address,
- const QuicSocketAddress& peer_address, absl::string_view alpn,
- 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
-
-#endif // QUICHE_QUIC_MASQUE_MASQUE_DISPATCHER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/masque/masque_encapsulated_client_session.cc b/chromium/net/third_party/quiche/src/quic/masque/masque_encapsulated_client_session.cc
deleted file mode 100644
index 3d557c3a073..00000000000
--- a/chromium/net/third_party/quiche/src/quic/masque/masque_encapsulated_client_session.cc
+++ /dev/null
@@ -1,49 +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 "quic/masque/masque_encapsulated_client_session.h"
-
-namespace quic {
-
-MasqueEncapsulatedClientSession::MasqueEncapsulatedClientSession(
- const QuicConfig& config,
- const ParsedQuicVersionVector& supported_versions,
- QuicConnection* connection,
- const QuicServerId& server_id,
- QuicCryptoClientConfig* crypto_config,
- QuicClientPushPromiseIndex* push_promise_index,
- MasqueClientSession* masque_client_session)
- : QuicSpdyClientSession(config,
- supported_versions,
- connection,
- server_id,
- crypto_config,
- push_promise_index),
- masque_client_session_(masque_client_session) {}
-
-void MasqueEncapsulatedClientSession::ProcessPacket(
- absl::string_view packet,
- QuicSocketAddress server_address) {
- QuicTime now = connection()->clock()->ApproximateNow();
- QuicReceivedPacket received_packet(packet.data(), packet.length(), now);
- connection()->ProcessUdpPacket(connection()->self_address(), server_address,
- received_packet);
-}
-
-void MasqueEncapsulatedClientSession::CloseConnection(
- QuicErrorCode error,
- const std::string& details,
- ConnectionCloseBehavior connection_close_behavior) {
- connection()->CloseConnection(error, details, connection_close_behavior);
-}
-
-void MasqueEncapsulatedClientSession::OnConnectionClosed(
- const QuicConnectionCloseFrame& frame,
- ConnectionCloseSource source) {
- QuicSpdyClientSession::OnConnectionClosed(frame, source);
- masque_client_session_->UnregisterConnectionId(
- connection()->client_connection_id(), this);
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/masque/masque_encapsulated_client_session.h b/chromium/net/third_party/quiche/src/quic/masque/masque_encapsulated_client_session.h
deleted file mode 100644
index 09521591898..00000000000
--- a/chromium/net/third_party/quiche/src/quic/masque/masque_encapsulated_client_session.h
+++ /dev/null
@@ -1,62 +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_ENCAPSULATED_CLIENT_SESSION_H_
-#define QUICHE_QUIC_MASQUE_MASQUE_ENCAPSULATED_CLIENT_SESSION_H_
-
-#include "quic/core/http/quic_spdy_client_session.h"
-#include "quic/masque/masque_client_session.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// QUIC client session for QUIC encapsulated in MASQUE. This client session is
-// maintained end-to-end between the client and the web-server (the MASQUE
-// session does not have access to the cryptographic keys for the end-to-end
-// session), but its packets are sent encapsulated inside DATAGRAM frames in a
-// MASQUE session, as opposed to regular QUIC packets. Multiple encapsulated
-// sessions can coexist inside a MASQUE session.
-class QUIC_NO_EXPORT MasqueEncapsulatedClientSession
- : public QuicSpdyClientSession,
- public MasqueClientSession::EncapsulatedClientSession {
- public:
- // Takes ownership of |connection|, but not of |crypto_config| or
- // |push_promise_index| or |masque_client_session|. All pointers must be
- // non-null. Caller must ensure that |push_promise_index| and
- // |masque_client_session| stay valid for the lifetime of the newly created
- // MasqueEncapsulatedClientSession.
- MasqueEncapsulatedClientSession(
- const QuicConfig& config,
- const ParsedQuicVersionVector& supported_versions,
- QuicConnection* connection,
- const QuicServerId& server_id,
- QuicCryptoClientConfig* crypto_config,
- QuicClientPushPromiseIndex* push_promise_index,
- MasqueClientSession* masque_client_session);
-
- // Disallow copy and assign.
- MasqueEncapsulatedClientSession(const MasqueEncapsulatedClientSession&) =
- delete;
- MasqueEncapsulatedClientSession& operator=(
- const MasqueEncapsulatedClientSession&) = delete;
-
- // From MasqueClientSession::EncapsulatedClientSession.
- void ProcessPacket(absl::string_view packet,
- QuicSocketAddress server_address) override;
- void CloseConnection(
- QuicErrorCode error,
- const std::string& details,
- ConnectionCloseBehavior connection_close_behavior) override;
-
- // From QuicSession.
- void OnConnectionClosed(const QuicConnectionCloseFrame& frame,
- ConnectionCloseSource source) override;
-
- private:
- MasqueClientSession* masque_client_session_; // Unowned.
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_MASQUE_MASQUE_ENCAPSULATED_CLIENT_SESSION_H_
diff --git a/chromium/net/third_party/quiche/src/quic/masque/masque_encapsulated_epoll_client.cc b/chromium/net/third_party/quiche/src/quic/masque/masque_encapsulated_epoll_client.cc
deleted file mode 100644
index 8891e4a0e41..00000000000
--- a/chromium/net/third_party/quiche/src/quic/masque/masque_encapsulated_epoll_client.cc
+++ /dev/null
@@ -1,125 +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 "quic/masque/masque_encapsulated_epoll_client.h"
-#include "quic/core/quic_utils.h"
-#include "quic/masque/masque_client_session.h"
-#include "quic/masque/masque_encapsulated_client_session.h"
-#include "quic/masque/masque_epoll_client.h"
-#include "quic/masque/masque_utils.h"
-
-namespace quic {
-
-namespace {
-
-// Custom packet writer that allows getting all of a connection's outgoing
-// packets.
-class MasquePacketWriter : public QuicPacketWriter {
- public:
- explicit MasquePacketWriter(MasqueEncapsulatedEpollClient* client)
- : client_(client) {}
- WriteResult WritePacket(const char* buffer,
- size_t buf_len,
- const QuicIpAddress& /*self_address*/,
- const QuicSocketAddress& peer_address,
- PerPacketOptions* /*options*/) override {
- QUICHE_DCHECK(peer_address.IsInitialized());
- QUIC_DVLOG(1) << "MasquePacketWriter trying to write " << buf_len
- << " 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());
- return WriteResult(WRITE_STATUS_OK, buf_len);
- }
-
- bool IsWriteBlocked() const override { return false; }
-
- void SetWritable() override {}
-
- QuicByteCount GetMaxPacketSize(
- const QuicSocketAddress& /*peer_address*/) const override {
- return kMasqueMaxEncapsulatedPacketSize;
- }
-
- bool SupportsReleaseTime() const override { return false; }
-
- bool IsBatchMode() const override { return false; }
- QuicPacketBuffer GetNextWriteLocation(
- const QuicIpAddress& /*self_address*/,
- const QuicSocketAddress& /*peer_address*/) override {
- return {nullptr, nullptr};
- }
-
- WriteResult Flush() override { return WriteResult(WRITE_STATUS_OK, 0); }
-
- private:
- MasqueEncapsulatedEpollClient* client_; // Unowned.
-};
-
-// Custom network helper that allows injecting a custom packet writer in order
-// to get all of a connection's outgoing packets.
-class MasqueClientEpollNetworkHelper : public QuicClientEpollNetworkHelper {
- public:
- MasqueClientEpollNetworkHelper(QuicEpollServer* epoll_server,
- MasqueEncapsulatedEpollClient* client)
- : QuicClientEpollNetworkHelper(epoll_server, client), client_(client) {}
- QuicPacketWriter* CreateQuicPacketWriter() override {
- return new MasquePacketWriter(client_);
- }
-
- private:
- MasqueEncapsulatedEpollClient* client_; // Unowned.
-};
-
-} // namespace
-
-MasqueEncapsulatedEpollClient::MasqueEncapsulatedEpollClient(
- QuicSocketAddress server_address,
- const QuicServerId& server_id,
- QuicEpollServer* epoll_server,
- std::unique_ptr<ProofVerifier> proof_verifier,
- MasqueEpollClient* masque_client)
- : QuicClient(
- server_address,
- server_id,
- MasqueSupportedVersions(),
- MasqueEncapsulatedConfig(),
- epoll_server,
- std::make_unique<MasqueClientEpollNetworkHelper>(epoll_server, this),
- std::move(proof_verifier)),
- masque_client_(masque_client) {}
-
-MasqueEncapsulatedEpollClient::~MasqueEncapsulatedEpollClient() {
- masque_client_->masque_client_session()->UnregisterConnectionId(
- client_connection_id_, masque_encapsulated_client_session());
-}
-
-std::unique_ptr<QuicSession>
-MasqueEncapsulatedEpollClient::CreateQuicClientSession(
- const ParsedQuicVersionVector& supported_versions,
- QuicConnection* connection) {
- QUIC_DLOG(INFO) << "Creating MASQUE encapsulated session for "
- << connection->connection_id();
- return std::make_unique<MasqueEncapsulatedClientSession>(
- *config(), supported_versions, connection, server_id(), crypto_config(),
- push_promise_index(), masque_client_->masque_client_session());
-}
-
-MasqueEncapsulatedClientSession*
-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/quic/masque/masque_encapsulated_epoll_client.h b/chromium/net/third_party/quiche/src/quic/masque/masque_encapsulated_epoll_client.h
deleted file mode 100644
index 70f0732f993..00000000000
--- a/chromium/net/third_party/quiche/src/quic/masque/masque_encapsulated_epoll_client.h
+++ /dev/null
@@ -1,50 +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_ENCAPSULATED_EPOLL_CLIENT_H_
-#define QUICHE_QUIC_MASQUE_MASQUE_ENCAPSULATED_EPOLL_CLIENT_H_
-
-#include "quic/masque/masque_encapsulated_client_session.h"
-#include "quic/masque/masque_epoll_client.h"
-#include "quic/platform/api/quic_export.h"
-#include "quic/tools/quic_client.h"
-
-namespace quic {
-
-// QUIC client for QUIC encapsulated in MASQUE.
-class QUIC_NO_EXPORT MasqueEncapsulatedEpollClient : public QuicClient {
- public:
- MasqueEncapsulatedEpollClient(QuicSocketAddress server_address,
- const QuicServerId& server_id,
- QuicEpollServer* epoll_server,
- std::unique_ptr<ProofVerifier> proof_verifier,
- MasqueEpollClient* masque_client);
- ~MasqueEncapsulatedEpollClient() override;
-
- // Disallow copy and assign.
- MasqueEncapsulatedEpollClient(const MasqueEncapsulatedEpollClient&) = delete;
- MasqueEncapsulatedEpollClient& operator=(
- const MasqueEncapsulatedEpollClient&) = delete;
-
- // From QuicClient.
- std::unique_ptr<QuicSession> CreateQuicClientSession(
- const ParsedQuicVersionVector& supported_versions,
- QuicConnection* connection) override;
-
- QuicConnectionId GetClientConnectionId() override;
-
- // MASQUE client that this client is encapsulated in.
- MasqueEpollClient* masque_client() { return masque_client_; }
-
- // Client session for this client.
- MasqueEncapsulatedClientSession* masque_encapsulated_client_session();
-
- private:
- MasqueEpollClient* masque_client_; // Unowned.
- QuicConnectionId client_connection_id_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_MASQUE_MASQUE_ENCAPSULATED_EPOLL_CLIENT_H_
diff --git a/chromium/net/third_party/quiche/src/quic/masque/masque_epoll_client.cc b/chromium/net/third_party/quiche/src/quic/masque/masque_epoll_client.cc
deleted file mode 100644
index bfb4636199a..00000000000
--- a/chromium/net/third_party/quiche/src/quic/masque/masque_epoll_client.cc
+++ /dev/null
@@ -1,156 +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 "quic/masque/masque_epoll_client.h"
-
-#include <string>
-
-#include "absl/memory/memory.h"
-#include "quic/masque/masque_client_session.h"
-#include "quic/masque/masque_utils.h"
-#include "quic/tools/quic_url.h"
-
-namespace quic {
-
-MasqueEpollClient::MasqueEpollClient(
- QuicSocketAddress server_address, const QuicServerId& server_id,
- MasqueMode masque_mode, QuicEpollServer* epoll_server,
- std::unique_ptr<ProofVerifier> proof_verifier,
- const std::string& uri_template)
- : QuicClient(server_address, server_id, MasqueSupportedVersions(),
- epoll_server, std::move(proof_verifier)),
- masque_mode_(masque_mode),
- uri_template_(uri_template) {}
-
-std::unique_ptr<QuicSession> MasqueEpollClient::CreateQuicClientSession(
- const ParsedQuicVersionVector& supported_versions,
- QuicConnection* connection) {
- QUIC_DLOG(INFO) << "Creating MASQUE session for "
- << connection->connection_id();
- return std::make_unique<MasqueClientSession>(
- masque_mode_, uri_template_, *config(), supported_versions, connection,
- server_id(), crypto_config(), push_promise_index(), this);
-}
-
-MasqueClientSession* MasqueEpollClient::masque_client_session() {
- return static_cast<MasqueClientSession*>(QuicClient::session());
-}
-
-QuicConnectionId MasqueEpollClient::connection_id() {
- return masque_client_session()->connection_id();
-}
-
-std::string MasqueEpollClient::authority() const {
- QuicUrl url(uri_template_);
- return absl::StrCat(url.host(), ":", url.port());
-}
-
-// static
-std::unique_ptr<MasqueEpollClient> MasqueEpollClient::Create(
- const std::string& uri_template, MasqueMode masque_mode,
- QuicEpollServer* epoll_server,
- std::unique_ptr<ProofVerifier> proof_verifier) {
- QuicUrl url(uri_template);
- std::string host = url.host();
- uint16_t port = url.port();
- // Build the masque_client, and try to connect.
- QuicSocketAddress addr = tools::LookupAddress(host, absl::StrCat(port));
- if (!addr.IsInitialized()) {
- QUIC_LOG(ERROR) << "Unable to resolve address: " << host;
- return nullptr;
- }
- QuicServerId server_id(host, port);
- // Use absl::WrapUnique(new MasqueEpollClient(...)) instead of
- // std::make_unique<MasqueEpollClient>(...) because the constructor for
- // MasqueEpollClient is private and therefore not accessible from make_unique.
- auto masque_client = absl::WrapUnique(
- new MasqueEpollClient(addr, server_id, masque_mode, epoll_server,
- std::move(proof_verifier), uri_template));
-
- if (masque_client == nullptr) {
- QUIC_LOG(ERROR) << "Failed to create masque_client";
- return nullptr;
- }
-
- masque_client->set_initial_max_packet_length(kMasqueMaxOuterPacketSize);
- masque_client->set_drop_response_body(false);
- if (!masque_client->Initialize()) {
- QUIC_LOG(ERROR) << "Failed to initialize masque_client";
- return nullptr;
- }
- if (!masque_client->Connect()) {
- QuicErrorCode error = masque_client->session()->error();
- QUIC_LOG(ERROR) << "Failed to connect to " << host << ":" << port
- << ". Error: " << QuicErrorCodeToString(error);
- return nullptr;
- }
-
- if (!masque_client->WaitUntilSettingsReceived()) {
- QUIC_LOG(ERROR) << "Failed to receive settings";
- 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;
-}
-
-void MasqueEpollClient::OnSettingsReceived() {
- settings_received_ = true;
-}
-
-bool MasqueEpollClient::WaitUntilSettingsReceived() {
- while (connected() && !settings_received_) {
- network_helper()->RunEventLoop();
- }
- 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/quic/masque/masque_epoll_client.h b/chromium/net/third_party/quiche/src/quic/masque/masque_epoll_client.h
deleted file mode 100644
index b6e0087a6d9..00000000000
--- a/chromium/net/third_party/quiche/src/quic/masque/masque_epoll_client.h
+++ /dev/null
@@ -1,72 +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_EPOLL_CLIENT_H_
-#define QUICHE_QUIC_MASQUE_MASQUE_EPOLL_CLIENT_H_
-
-#include <string>
-
-#include "quic/masque/masque_client_session.h"
-#include "quic/masque/masque_utils.h"
-#include "quic/platform/api/quic_export.h"
-#include "quic/tools/quic_client.h"
-#include "quic/tools/quic_url.h"
-
-namespace quic {
-
-// QUIC client that implements MASQUE.
-class QUIC_NO_EXPORT MasqueEpollClient : public QuicClient,
- public MasqueClientSession::Owner {
- public:
- // Constructs a MasqueEpollClient, performs a synchronous DNS lookup.
- static std::unique_ptr<MasqueEpollClient> Create(
- const std::string& uri_template, MasqueMode masque_mode,
- QuicEpollServer* epoll_server,
- std::unique_ptr<ProofVerifier> proof_verifier);
-
- // From QuicClient.
- std::unique_ptr<QuicSession> CreateQuicClientSession(
- const ParsedQuicVersionVector& supported_versions,
- QuicConnection* connection) override;
-
- // Client session for this client.
- MasqueClientSession* masque_client_session();
-
- // Convenience accessor for the underlying connection ID.
- QuicConnectionId connection_id();
-
- // 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_; }
-
- private:
- // Constructor is private, use Create() instead.
- MasqueEpollClient(QuicSocketAddress server_address,
- const QuicServerId& server_id, MasqueMode masque_mode,
- QuicEpollServer* epoll_server,
- std::unique_ptr<ProofVerifier> proof_verifier,
- const std::string& uri_template);
-
- // Wait synchronously until we receive the peer's settings. Returns whether
- // they were received.
- bool WaitUntilSettingsReceived();
-
- std::string authority() const;
-
- // Disallow copy and assign.
- MasqueEpollClient(const MasqueEpollClient&) = delete;
- MasqueEpollClient& operator=(const MasqueEpollClient&) = delete;
-
- MasqueMode masque_mode_;
- std::string uri_template_;
- bool settings_received_ = false;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_MASQUE_MASQUE_EPOLL_CLIENT_H_
diff --git a/chromium/net/third_party/quiche/src/quic/masque/masque_epoll_server.cc b/chromium/net/third_party/quiche/src/quic/masque/masque_epoll_server.cc
deleted file mode 100644
index e8a0850f0d8..00000000000
--- a/chromium/net/third_party/quiche/src/quic/masque/masque_epoll_server.cc
+++ /dev/null
@@ -1,33 +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 "quic/masque/masque_epoll_server.h"
-#include "quic/core/quic_epoll_alarm_factory.h"
-#include "quic/masque/masque_dispatcher.h"
-#include "quic/masque/masque_utils.h"
-#include "quic/platform/api/quic_default_proof_providers.h"
-#include "quic/tools/quic_simple_crypto_server_stream_helper.h"
-
-namespace quic {
-
-MasqueEpollServer::MasqueEpollServer(MasqueMode masque_mode,
- MasqueServerBackend* masque_server_backend)
- : QuicServer(CreateDefaultProofSource(),
- masque_server_backend,
- MasqueSupportedVersions()),
- masque_mode_(masque_mode),
- masque_server_backend_(masque_server_backend) {}
-
-QuicDispatcher* MasqueEpollServer::CreateQuicDispatcher() {
- return new MasqueDispatcher(
- masque_mode_, &config(), &crypto_config(), version_manager(),
- epoll_server(),
- std::make_unique<QuicEpollConnectionHelper>(epoll_server(),
- QuicAllocator::BUFFER_POOL),
- std::make_unique<QuicSimpleCryptoServerStreamHelper>(),
- std::make_unique<QuicEpollAlarmFactory>(epoll_server()),
- masque_server_backend_, expected_server_connection_id_length());
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/masque/masque_epoll_server.h b/chromium/net/third_party/quiche/src/quic/masque/masque_epoll_server.h
deleted file mode 100644
index 88161ee37cf..00000000000
--- a/chromium/net/third_party/quiche/src/quic/masque/masque_epoll_server.h
+++ /dev/null
@@ -1,35 +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_EPOLL_SERVER_H_
-#define QUICHE_QUIC_MASQUE_MASQUE_EPOLL_SERVER_H_
-
-#include "quic/masque/masque_server_backend.h"
-#include "quic/masque/masque_utils.h"
-#include "quic/platform/api/quic_export.h"
-#include "quic/tools/quic_server.h"
-
-namespace quic {
-
-// QUIC server that implements MASQUE.
-class QUIC_NO_EXPORT MasqueEpollServer : public QuicServer {
- public:
- explicit MasqueEpollServer(MasqueMode masque_mode,
- MasqueServerBackend* masque_server_backend);
-
- // Disallow copy and assign.
- MasqueEpollServer(const MasqueEpollServer&) = delete;
- MasqueEpollServer& operator=(const MasqueEpollServer&) = delete;
-
- // From QuicServer.
- QuicDispatcher* CreateQuicDispatcher() override;
-
- private:
- MasqueMode masque_mode_;
- MasqueServerBackend* masque_server_backend_; // Unowned.
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_MASQUE_MASQUE_EPOLL_SERVER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/masque/masque_server_backend.cc b/chromium/net/third_party/quiche/src/quic/masque/masque_server_backend.cc
deleted file mode 100644
index 280ab5ee8ed..00000000000
--- a/chromium/net/third_party/quiche/src/quic/masque/masque_server_backend.cc
+++ /dev/null
@@ -1,137 +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 "quic/masque/masque_server_backend.h"
-#include "absl/strings/str_cat.h"
-#include "absl/strings/string_view.h"
-
-namespace quic {
-
-MasqueServerBackend::MasqueServerBackend(MasqueMode masque_mode,
- const std::string& server_authority,
- const std::string& cache_directory)
- : masque_mode_(masque_mode), server_authority_(server_authority) {
- if (!cache_directory.empty()) {
- QuicMemoryCacheBackend::InitializeBackend(cache_directory);
- }
-}
-
-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()) {
- // Request is missing a method.
- return false;
- }
- 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;
- }
- }
-
- if (!server_authority_.empty()) {
- auto authority_pair = request_headers.find(":authority");
- if (authority_pair == request_headers.end()) {
- // Cannot enforce missing authority.
- return false;
- }
- absl::string_view authority = authority_pair->second;
- if (server_authority_ != authority) {
- // This request does not match server_authority.
- return false;
- }
- }
-
- auto it = backend_client_states_.find(request_handler->connection_id());
- if (it == backend_client_states_.end()) {
- QUIC_LOG(ERROR) << "Could not find backend client for "
- << masque_path << request_headers.DebugString();
- return false;
- }
-
- BackendClient* backend_client = it->second.backend_client;
-
- std::unique_ptr<QuicBackendResponse> response =
- backend_client->HandleMasqueRequest(masque_path, request_headers,
- request_body, request_handler);
- if (response == nullptr) {
- QUIC_LOG(ERROR) << "Backend client did not process request for "
- << masque_path << request_headers.DebugString();
- return false;
- }
-
- QUIC_DLOG(INFO) << "Sending MASQUE response for "
- << request_headers.DebugString();
-
- request_handler->OnResponseBackendComplete(response.get());
- it->second.responses.emplace_back(std::move(response));
-
- return true;
-}
-
-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)) {
- // Request was handled as a MASQUE request.
- return;
- }
- QUIC_DLOG(INFO) << "Fetching non-MASQUE response for "
- << request_headers.DebugString();
- QuicMemoryCacheBackend::FetchResponseFromBackend(
- request_headers, request_body, request_handler);
-}
-
-void MasqueServerBackend::CloseBackendResponseStream(
- QuicSimpleServerBackend::RequestHandler* request_handler) {
- QUIC_DLOG(INFO) << "Closing response stream";
- QuicMemoryCacheBackend::CloseBackendResponseStream(request_handler);
-}
-
-void MasqueServerBackend::RegisterBackendClient(QuicConnectionId connection_id,
- BackendClient* backend_client) {
- QUIC_DLOG(INFO) << "Registering backend client for " << connection_id;
- QUIC_BUG_IF(quic_bug_12005_1, backend_client_states_.find(connection_id) !=
- backend_client_states_.end())
- << connection_id << " already in backend clients map";
- backend_client_states_[connection_id] =
- BackendClientState{backend_client, {}};
-}
-
-void MasqueServerBackend::RemoveBackendClient(QuicConnectionId connection_id) {
- QUIC_DLOG(INFO) << "Removing backend client for " << connection_id;
- backend_client_states_.erase(connection_id);
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/masque/masque_server_backend.h b/chromium/net/third_party/quiche/src/quic/masque/masque_server_backend.h
deleted file mode 100644
index 4f0e10d7421..00000000000
--- a/chromium/net/third_party/quiche/src/quic/masque/masque_server_backend.h
+++ /dev/null
@@ -1,76 +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_SERVER_BACKEND_H_
-#define QUICHE_QUIC_MASQUE_MASQUE_SERVER_BACKEND_H_
-
-#include "absl/container/flat_hash_map.h"
-#include "quic/masque/masque_utils.h"
-#include "quic/platform/api/quic_export.h"
-#include "quic/tools/quic_memory_cache_backend.h"
-
-namespace quic {
-
-// QUIC server backend that understands MASQUE requests, but otherwise answers
-// HTTP queries using an in-memory cache.
-class QUIC_NO_EXPORT MasqueServerBackend : public QuicMemoryCacheBackend {
- public:
- // Interface meant to be implemented by the owner of the MasqueServerBackend
- // instance.
- 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;
- };
-
- explicit MasqueServerBackend(MasqueMode masque_mode,
- const std::string& server_authority,
- const std::string& cache_directory);
-
- // Disallow copy and assign.
- MasqueServerBackend(const MasqueServerBackend&) = delete;
- MasqueServerBackend& operator=(const MasqueServerBackend&) = delete;
-
- // From QuicMemoryCacheBackend.
- void FetchResponseFromBackend(
- const spdy::Http2HeaderBlock& request_headers,
- const std::string& request_body,
- QuicSimpleServerBackend::RequestHandler* request_handler) override;
-
- void CloseBackendResponseStream(
- QuicSimpleServerBackend::RequestHandler* request_handler) override;
-
- // Register backend client that can handle MASQUE requests.
- void RegisterBackendClient(QuicConnectionId connection_id,
- BackendClient* backend_client);
-
- // Unregister backend client.
- void RemoveBackendClient(QuicConnectionId connection_id);
-
- private:
- // Handle MASQUE request.
- bool MaybeHandleMasqueRequest(
- const spdy::Http2HeaderBlock& request_headers,
- const std::string& request_body,
- QuicSimpleServerBackend::RequestHandler* request_handler);
-
- MasqueMode masque_mode_;
- std::string server_authority_;
-
- struct QUIC_NO_EXPORT BackendClientState {
- BackendClient* backend_client;
- std::vector<std::unique_ptr<QuicBackendResponse>> responses;
- };
- absl::
- flat_hash_map<QuicConnectionId, BackendClientState, QuicConnectionIdHash>
- backend_client_states_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_MASQUE_MASQUE_SERVER_BACKEND_H_
diff --git a/chromium/net/third_party/quiche/src/quic/masque/masque_server_bin.cc b/chromium/net/third_party/quiche/src/quic/masque/masque_server_bin.cc
deleted file mode 100644
index 666f67f5bf0..00000000000
--- a/chromium/net/third_party/quiche/src/quic/masque/masque_server_bin.cc
+++ /dev/null
@@ -1,72 +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.
-
-// This file is reponsible for the masque_server binary. It allows testing
-// our MASQUE server code by creating a MASQUE proxy that relays HTTP/3
-// requests to web servers tunnelled over MASQUE connections.
-// e.g.: masque_server
-
-#include <memory>
-
-#include "quic/masque/masque_epoll_server.h"
-#include "quic/masque/masque_server_backend.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/platform/api/quic_socket_address.h"
-#include "quic/platform/api/quic_system_event_loop.h"
-#include "common/platform/api/quiche_command_line_flags.h"
-
-DEFINE_QUICHE_COMMAND_LINE_FLAG(int32_t, port, 9661,
- "The port the MASQUE server will listen on.");
-
-DEFINE_QUICHE_COMMAND_LINE_FLAG(
- std::string, cache_dir, "",
- "Specifies the directory used during QuicHttpResponseCache "
- "construction to seed the cache. Cache directory can be "
- "generated using `wget -p --save-headers <url>`");
-
-DEFINE_QUICHE_COMMAND_LINE_FLAG(
- std::string, server_authority, "",
- "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.");
-
-int main(int argc, char* argv[]) {
- QuicSystemEventLoop event_loop("masque_server");
- const char* usage = "Usage: masque_server [options]";
- std::vector<std::string> non_option_args =
- quiche::QuicheParseCommandLineFlags(usage, argc, argv);
- if (!non_option_args.empty()) {
- quiche::QuichePrintCommandLineFlagHelp(usage);
- return 0;
- }
-
- 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::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));
-
- auto server =
- std::make_unique<quic::MasqueEpollServer>(masque_mode, backend.get());
-
- if (!server->CreateUDPSocketAndListen(quic::QuicSocketAddress(
- quic::QuicIpAddress::Any6(), GetQuicFlag(FLAGS_port)))) {
- return 1;
- }
-
- std::cerr << "Started " << masque_mode << " MASQUE server" << std::endl;
- server->HandleEventsForever();
- return 0;
-}
diff --git a/chromium/net/third_party/quiche/src/quic/masque/masque_server_session.cc b/chromium/net/third_party/quiche/src/quic/masque/masque_server_session.cc
deleted file mode 100644
index 6484d8a6cb0..00000000000
--- a/chromium/net/third_party/quiche/src/quic/masque/masque_server_session.cc
+++ /dev/null
@@ -1,628 +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 "quic/masque/masque_server_session.h"
-
-#include <netdb.h>
-
-#include <cstddef>
-#include <limits>
-
-#include "absl/strings/str_cat.h"
-#include "absl/strings/str_split.h"
-#include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
-#include "quic/core/http/spdy_utils.h"
-#include "quic/core/quic_data_reader.h"
-#include "quic/core/quic_udp_socket.h"
-#include "quic/tools/quic_url.h"
-#include "common/platform/api/quiche_url_utils.h"
-
-namespace quic {
-
-namespace {
-// RAII wrapper for QuicUdpSocketFd.
-class FdWrapper {
- public:
- // Takes ownership of |fd| and closes the file descriptor on destruction.
- explicit FdWrapper(int address_family) {
- QuicUdpSocketApi socket_api;
- fd_ =
- socket_api.Create(address_family,
- /*receive_buffer_size =*/kDefaultSocketReceiveBuffer,
- /*send_buffer_size =*/kDefaultSocketReceiveBuffer);
- }
-
- ~FdWrapper() {
- if (fd_ == kQuicInvalidSocketFd) {
- return;
- }
- QuicUdpSocketApi socket_api;
- socket_api.Destroy(fd_);
- }
-
- // Hands ownership of the file descriptor to the caller.
- QuicUdpSocketFd extract_fd() {
- QuicUdpSocketFd fd = fd_;
- fd_ = kQuicInvalidSocketFd;
- return fd;
- }
-
- // Keeps ownership of the file descriptor.
- QuicUdpSocketFd fd() { return fd_; }
-
- // Disallow copy and move.
- FdWrapper(const FdWrapper&) = delete;
- FdWrapper(FdWrapper&&) = delete;
- FdWrapper& operator=(const FdWrapper&) = delete;
- FdWrapper& operator=(FdWrapper&&) = delete;
-
- private:
- QuicUdpSocketFd fd_;
-};
-
-std::unique_ptr<QuicBackendResponse> CreateBackendErrorResponse(
- absl::string_view status, absl::string_view error_details) {
- spdy::Http2HeaderBlock response_headers;
- response_headers[":status"] = status;
- response_headers["masque-debug-info"] = error_details;
- auto response = std::make_unique<QuicBackendResponse>();
- response->set_response_type(QuicBackendResponse::REGULAR_RESPONSE);
- response->set_headers(std::move(response_headers));
- return response;
-}
-
-} // namespace
-
-MasqueServerSession::MasqueServerSession(
- MasqueMode masque_mode, const QuicConfig& config,
- const ParsedQuicVersionVector& supported_versions,
- QuicConnection* connection, QuicSession::Visitor* visitor, Visitor* owner,
- QuicEpollServer* epoll_server, QuicCryptoServerStreamBase::Helper* helper,
- const QuicCryptoServerConfig* crypto_config,
- QuicCompressedCertsCache* compressed_certs_cache,
- MasqueServerBackend* masque_server_backend)
- : QuicSimpleServerSession(config, supported_versions, connection, visitor,
- 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.
- // TODO(b/181606597) Remove this workaround once we use PMTUD.
- connection->SetMaxPacketLength(kDefaultMaxPacketSize);
-
- masque_server_backend_->RegisterBackendClient(connection_id(), this);
- 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;
-}
-
-void MasqueServerSession::OnMessageLost(QuicMessageId message_id) {
- QUIC_DVLOG(1) << "We believe DATAGRAM frame " << message_id << " was lost";
-}
-
-void MasqueServerSession::OnConnectionClosed(
- const QuicConnectionCloseFrame& frame, ConnectionCloseSource source) {
- QuicSimpleServerSession::OnConnectionClosed(frame, source);
- QUIC_DLOG(INFO) << "Closing connection for " << connection_id();
- masque_server_backend_->RemoveBackendClient(connection_id());
- // Clearing this state will close all sockets.
- connect_udp_server_states_.clear();
-}
-
-void MasqueServerSession::OnStreamClosed(QuicStreamId stream_id) {
- connect_udp_server_states_.remove_if(
- [stream_id](const ConnectUdpServerState& connect_udp) {
- return connect_udp.stream()->id() == stream_id;
- });
-
- QuicSimpleServerSession::OnStreamClosed(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;
- }
-
- QUIC_DLOG(INFO) << "MasqueServerSession handling MASQUE request";
-
- 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;
- }
- }
-
- // 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_headers(std::move(response_headers));
- response->set_body(response_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;
-}
-
-void MasqueServerSession::OnModification(QuicUdpSocketFd fd, int event_mask) {
- QUIC_DVLOG(1) << "OnModification " << fd << " event_mask " << event_mask;
-}
-
-void MasqueServerSession::OnEvent(QuicUdpSocketFd fd, QuicEpollEvent* event) {
- if ((event->in_events & EPOLLIN) == 0) {
- QUIC_DVLOG(1) << "Ignoring OnEvent fd " << fd << " event mask "
- << event->in_events;
- return;
- }
- auto it = absl::c_find_if(connect_udp_server_states_,
- [fd](const ConnectUdpServerState& connect_udp) {
- return connect_udp.fd() == fd;
- });
- if (it == connect_udp_server_states_.end()) {
- QUIC_BUG(quic_bug_10974_1) << "Got unexpected event mask "
- << event->in_events << " on unknown fd " << fd;
- return;
- }
- QuicSocketAddress expected_target_server_address =
- it->target_server_address();
- QUICHE_DCHECK(expected_target_server_address.IsInitialized());
- QUIC_DVLOG(1) << "Received readable event on fd " << fd << " (mask "
- << event->in_events << ") stream ID " << it->stream()->id()
- << " server " << expected_target_server_address;
- QuicUdpSocketApi socket_api;
- BitMask64 packet_info_interested(QuicUdpPacketInfoBit::PEER_ADDRESS);
- char packet_buffer[kMaxIncomingPacketSize];
- char control_buffer[kDefaultUdpPacketControlBufferSize];
- while (true) {
- QuicUdpSocketApi::ReadPacketResult read_result;
- read_result.packet_buffer = {packet_buffer, sizeof(packet_buffer)};
- read_result.control_buffer = {control_buffer, sizeof(control_buffer)};
- socket_api.ReadPacket(fd, packet_info_interested, &read_result);
- if (!read_result.ok) {
- // Most likely there is nothing left to read, break out of read loop.
- break;
- }
- if (!read_result.packet_info.HasValue(QuicUdpPacketInfoBit::PEER_ADDRESS)) {
- QUIC_BUG(quic_bug_10974_2)
- << "Missing peer address when reading from fd " << fd;
- continue;
- }
- if (read_result.packet_info.peer_address() !=
- expected_target_server_address) {
- QUIC_DLOG(ERROR) << "Ignoring UDP packet on fd " << fd
- << " from unexpected server address "
- << read_result.packet_info.peer_address()
- << " (expected " << expected_target_server_address
- << ")";
- continue;
- }
- if (!connection()->connected()) {
- QUIC_BUG(quic_bug_10974_3)
- << "Unexpected incoming UDP packet on fd " << fd << " from "
- << expected_target_server_address
- << " because MASQUE connection is closed";
- 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));
- 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()
- << " and got message status "
- << MessageStatusToString(message_status);
- }
-}
-
-void MasqueServerSession::OnUnregistration(QuicUdpSocketFd fd, bool replaced) {
- QUIC_DVLOG(1) << "OnUnregistration " << fd << " " << (replaced ? "" : "!")
- << " replaced";
-}
-
-void MasqueServerSession::OnShutdown(QuicEpollServer* /*eps*/,
- QuicUdpSocketFd fd) {
- QUIC_DVLOG(1) << "OnShutdown " << fd;
-}
-
-std::string MasqueServerSession::Name() const {
- return std::string("MasqueServerSession-") + connection_id().ToString();
-}
-
-bool MasqueServerSession::OnSettingsFrame(const SettingsFrame& frame) {
- QUIC_DLOG(INFO) << "Received SETTINGS: " << frame;
- if (!QuicSimpleServerSession::OnSettingsFrame(frame)) {
- return false;
- }
- if (!SupportsH3Datagram()) {
- QUIC_DLOG(ERROR) << "Refusing to use MASQUE without HTTP Datagrams";
- return false;
- }
- QUIC_DLOG(INFO) << "Using HTTP Datagram: " << http_datagram_support();
- return true;
-}
-
-MasqueServerSession::ConnectUdpServerState::ConnectUdpServerState(
- QuicSpdyStream* stream, absl::optional<QuicDatagramContextId> context_id,
- 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);
-}
-
-MasqueServerSession::ConnectUdpServerState::~ConnectUdpServerState() {
- if (stream() != nullptr) {
- if (context_registered_) {
- stream()->UnregisterHttp3DatagramContextId(context_id());
- }
- stream()->UnregisterHttp3DatagramRegistrationVisitor();
- }
- if (fd_ == kQuicInvalidSocketFd) {
- return;
- }
- QuicUdpSocketApi socket_api;
- QUIC_DLOG(INFO) << "Closing fd " << fd_;
- masque_session_->epoll_server()->UnregisterFD(fd_);
- socket_api.Destroy(fd_);
-}
-
-MasqueServerSession::ConnectUdpServerState::ConnectUdpServerState(
- MasqueServerSession::ConnectUdpServerState&& other) {
- fd_ = kQuicInvalidSocketFd;
- *this = std::move(other);
-}
-
-MasqueServerSession::ConnectUdpServerState&
-MasqueServerSession::ConnectUdpServerState::operator=(
- MasqueServerSession::ConnectUdpServerState&& other) {
- if (fd_ != kQuicInvalidSocketFd) {
- QuicUdpSocketApi socket_api;
- QUIC_DLOG(INFO) << "Closing fd " << fd_;
- masque_session_->epoll_server()->UnregisterFD(fd_);
- socket_api.Destroy(fd_);
- }
- 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);
- }
- }
- return *this;
-}
-
-void MasqueServerSession::ConnectUdpServerState::OnHttp3Datagram(
- QuicStreamId stream_id, absl::optional<QuicDatagramContextId> context_id,
- absl::string_view payload) {
- QUICHE_DCHECK_EQ(stream_id, stream()->id());
- QUICHE_DCHECK(context_id == context_id_);
- 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 "
- << 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/quic/masque/masque_server_session.h b/chromium/net/third_party/quiche/src/quic/masque/masque_server_session.h
deleted file mode 100644
index b3c327f5446..00000000000
--- a/chromium/net/third_party/quiche/src/quic/masque/masque_server_session.h
+++ /dev/null
@@ -1,156 +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_SERVER_SESSION_H_
-#define QUICHE_QUIC_MASQUE_MASQUE_SERVER_SESSION_H_
-
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_udp_socket.h"
-#include "quic/masque/masque_compression_engine.h"
-#include "quic/masque/masque_server_backend.h"
-#include "quic/masque/masque_utils.h"
-#include "quic/platform/api/quic_epoll.h"
-#include "quic/platform/api/quic_export.h"
-#include "quic/tools/quic_simple_server_session.h"
-
-namespace quic {
-
-// QUIC server session for connection to MASQUE proxy.
-class QUIC_NO_EXPORT MasqueServerSession
- : public QuicSimpleServerSession,
- 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,
- QuicEpollServer* epoll_server, QuicCryptoServerStreamBase::Helper* helper,
- const QuicCryptoServerConfig* crypto_config,
- QuicCompressedCertsCache* compressed_certs_cache,
- MasqueServerBackend* masque_server_backend);
-
- // Disallow copy and assign.
- MasqueServerSession(const MasqueServerSession&) = delete;
- 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;
- void OnConnectionClosed(const QuicConnectionCloseFrame& frame,
- ConnectionCloseSource source) override;
- void OnStreamClosed(QuicStreamId stream_id) override;
-
- // 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.
- void OnRegistration(QuicEpollServer* eps, QuicUdpSocketFd fd,
- int event_mask) override;
- void OnModification(QuicUdpSocketFd fd, int event_mask) override;
- void OnEvent(QuicUdpSocketFd fd, QuicEpollEvent* event) override;
- void OnUnregistration(QuicUdpSocketFd fd, bool replaced) override;
- 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:
- // 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);
-
- ~ConnectUdpServerState();
-
- // Disallow copy but allow move.
- ConnectUdpServerState(const ConnectUdpServerState&) = delete;
- ConnectUdpServerState(ConnectUdpServerState&&);
- ConnectUdpServerState& operator=(const ConnectUdpServerState&) = delete;
- 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_;
- }
- QuicUdpSocketFd fd() const { return fd_; }
-
- // 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;
- }
-
- 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;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_MASQUE_MASQUE_SERVER_SESSION_H_
diff --git a/chromium/net/third_party/quiche/src/quic/masque/masque_utils.cc b/chromium/net/third_party/quiche/src/quic/masque/masque_utils.cc
deleted file mode 100644
index cd196029c6b..00000000000
--- a/chromium/net/third_party/quiche/src/quic/masque/masque_utils.cc
+++ /dev/null
@@ -1,46 +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 "quic/masque/masque_utils.h"
-
-namespace quic {
-
-ParsedQuicVersionVector MasqueSupportedVersions() {
- QuicVersionInitializeSupportForIetfDraft();
- ParsedQuicVersionVector versions;
- for (const ParsedQuicVersion& version : AllSupportedVersions()) {
- // Use all versions that support IETF QUIC.
- if (version.UsesHttp3()) {
- QuicEnableVersion(version);
- versions.push_back(version);
- }
- }
- QUICHE_CHECK(!versions.empty());
- return versions;
-}
-
-QuicConfig MasqueEncapsulatedConfig() {
- QuicConfig config;
- config.SetMaxPacketSizeToSend(kMasqueMaxEncapsulatedPacketSize);
- return config;
-}
-
-std::string MasqueModeToString(MasqueMode masque_mode) {
- switch (masque_mode) {
- case MasqueMode::kInvalid:
- return "Invalid";
- case MasqueMode::kLegacy:
- return "Legacy";
- case MasqueMode::kOpen:
- return "Open";
- }
- return absl::StrCat("Unknown(", static_cast<int>(masque_mode), ")");
-}
-
-std::ostream& operator<<(std::ostream& os, const MasqueMode& masque_mode) {
- os << MasqueModeToString(masque_mode);
- return os;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/masque/masque_utils.h b/chromium/net/third_party/quiche/src/quic/masque/masque_utils.h
deleted file mode 100644
index abaeda7fa43..00000000000
--- a/chromium/net/third_party/quiche/src/quic/masque/masque_utils.h
+++ /dev/null
@@ -1,45 +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_UTILS_H_
-#define QUICHE_QUIC_MASQUE_MASQUE_UTILS_H_
-
-#include "quic/core/quic_config.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_versions.h"
-
-namespace quic {
-
-// List of QUIC versions that support MASQUE. Currently restricted to IETF QUIC.
-QUIC_NO_EXPORT ParsedQuicVersionVector MasqueSupportedVersions();
-
-// Default QuicConfig for use with MASQUE. Sets a custom max_packet_size.
-QUIC_NO_EXPORT QuicConfig MasqueEncapsulatedConfig();
-
-// Maximum packet size for encapsulated connections.
-enum : QuicByteCount {
- kMasqueMaxEncapsulatedPacketSize = 1300,
- kMasqueMaxOuterPacketSize = 1350,
-};
-
-// 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
- // this enum at a later date).
-};
-
-QUIC_NO_EXPORT std::string MasqueModeToString(MasqueMode masque_mode);
-QUIC_NO_EXPORT std::ostream& operator<<(std::ostream& os,
- const MasqueMode& masque_mode);
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_MASQUE_MASQUE_UTILS_H_
diff --git a/chromium/net/third_party/quiche/src/quic/platform/README.md b/chromium/net/third_party/quiche/src/quic/platform/README.md
deleted file mode 100644
index 6538de108cf..00000000000
--- a/chromium/net/third_party/quiche/src/quic/platform/README.md
+++ /dev/null
@@ -1,12 +0,0 @@
-# QUIC platform
-
-This platform/ directory exists in order to allow QUIC code to be built on
-numerous platforms. It contains two subdirectories:
-
-- api/ contains platform independent class definitions for fundamental data
- structures (e.g., IPAddress, SocketAddress, etc.).
-- impl/ contains platform specific implementations of these data structures.
- The content of files in impl/ will vary depending on the platform.
-
-Code in the parent quic/ directory should not depend on any platform specific
-code, other than that found in impl/.
diff --git a/chromium/net/third_party/quiche/src/quic/platform/api/README.md b/chromium/net/third_party/quiche/src/quic/platform/api/README.md
deleted file mode 100644
index 117e424d00c..00000000000
--- a/chromium/net/third_party/quiche/src/quic/platform/api/README.md
+++ /dev/null
@@ -1,72 +0,0 @@
-# QUIC platform API
-
-This directory contains the infrastructure blocks needed to support QUIC in
-certain platform. These APIs act as interaction layers between QUIC core and
-either the upper layer application (i.e. Chrome, Envoy) or the platform's own
-infrastructure (i.e. logging, test framework and system IO). QUIC core needs the
-implementations of these APIs to build and function appropriately. There is
-unidirectional dependency from QUIC core to most of the APIs here, such as
-QUIC_LOG and QuicMutex, but a few APIs also depend back on QUIC core's basic
-QUIC data types, such as QuicClock and QuicSleep.
-
-- APIs used by QUIC core:
-
- Most APIs are used by QUIC core to interact with platform infrastructure
- (i.e. QUIC_LOG) or to wrap around platform dependent data types (i.e.
- QuicThread), the dependency is:
-
-```
-application -> quic_core -> quic_platform_api
- | |
- v v
-platform_infrastructure <- quic_platform_impl
-```
-
-- APIs used by applications:
-
- Some APIs are used by applications to interact with QUIC core (i.e.
- QuicMemSlice). For such APIs, their dependency model is:
-
-```
-application -> quic_core -> quic_platform_api
- | ^
- | |
- -------------------> quic_platform_impl
- | |
- | v
- -------------------> platform_infrastructure
-```
-
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;An example for such dependency
-is QuicClock.
-
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Or
-
-```
-application -> quic_core -> quic_platform_api
- | ^
- | |
- | v
- -------------------> quic_platform_impl
- | |
- | v
- -------------------> platform_infrastructure
-```
-
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;An example for such dependency
-is QuicMemSlice.
-
-# Documentation of each API and its usage.
-
-QuicMemSlice
-: QuicMemSlice is used to wrap application data and pass to QUIC stream's
- write interface. It refers to a memory block of data which should be around
- till QuicMemSlice::Reset() is called. It's upto each platform, to implement
- it as reference counted or not.
-
-QuicClock
-: QuicClock is used by QUIC core to get current time. Its instance is created
- by applications and passed into QuicDispatcher and
- QuicConnectionHelperInterface.
-
-TODO(b/131224336) add document for other APIs
diff --git a/chromium/net/third_party/quiche/src/quic/platform/api/quic_bug_tracker.h b/chromium/net/third_party/quiche/src/quic/platform/api/quic_bug_tracker.h
deleted file mode 100644
index cffa6e52533..00000000000
--- a/chromium/net/third_party/quiche/src/quic/platform/api/quic_bug_tracker.h
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_PLATFORM_API_QUIC_BUG_TRACKER_H_
-#define QUICHE_QUIC_PLATFORM_API_QUIC_BUG_TRACKER_H_
-
-#include "common/platform/api/quiche_bug_tracker.h"
-
-#define QUIC_BUG QUICHE_BUG
-#define QUIC_BUG_IF QUICHE_BUG_IF
-#define QUIC_PEER_BUG QUICHE_PEER_BUG
-#define QUIC_PEER_BUG_IF QUICHE_PEER_BUG_IF
-
-#endif // QUICHE_QUIC_PLATFORM_API_QUIC_BUG_TRACKER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/platform/api/quic_client_stats.h b/chromium/net/third_party/quiche/src/quic/platform/api/quic_client_stats.h
deleted file mode 100644
index b780ba695c8..00000000000
--- a/chromium/net/third_party/quiche/src/quic/platform/api/quic_client_stats.h
+++ /dev/null
@@ -1,87 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_PLATFORM_API_QUIC_CLIENT_STATS_H_
-#define QUICHE_QUIC_PLATFORM_API_QUIC_CLIENT_STATS_H_
-
-#include <string>
-#include "net/quic/platform/impl/quic_client_stats_impl.h"
-
-namespace quic {
-
-//------------------------------------------------------------------------------
-// Enumeration histograms.
-//
-// Sample usage:
-// // In Chrome, these values are persisted to logs. Entries should not be
-// // renumbered and numeric values should never be reused.
-// enum class MyEnum {
-// FIRST_VALUE = 0,
-// SECOND_VALUE = 1,
-// ...
-// FINAL_VALUE = N,
-// COUNT
-// };
-// QUIC_CLIENT_HISTOGRAM_ENUM("My.Enumeration", MyEnum::SOME_VALUE,
-// MyEnum::COUNT, "Number of time $foo equals to some enum value");
-//
-// Note: The value in |sample| must be strictly less than |enum_size|.
-
-#define QUIC_CLIENT_HISTOGRAM_ENUM(name, sample, enum_size, docstring) \
- QUIC_CLIENT_HISTOGRAM_ENUM_IMPL(name, sample, enum_size, docstring)
-
-//------------------------------------------------------------------------------
-// Histogram for boolean values.
-
-// Sample usage:
-// QUIC_CLIENT_HISTOGRAM_BOOL("My.Boolean", bool,
-// "Number of times $foo is true or false");
-#define QUIC_CLIENT_HISTOGRAM_BOOL(name, sample, docstring) \
- QUIC_CLIENT_HISTOGRAM_BOOL_IMPL(name, sample, docstring)
-
-//------------------------------------------------------------------------------
-// Timing histograms. These are used for collecting timing data (generally
-// latencies).
-
-// These macros create exponentially sized histograms (lengths of the bucket
-// ranges exponentially increase as the sample range increases). The units for
-// sample and max are unspecified, but they must be the same for one histogram.
-
-// Sample usage:
-// QUIC_CLIENT_HISTOGRAM_TIMES("Very.Long.Timing.Histogram", time_delta,
-// QuicTime::Delta::FromSeconds(1), QuicTime::Delta::FromSecond(3600 *
-// 24), 100, "Time spent in doing operation.");
-#define QUIC_CLIENT_HISTOGRAM_TIMES(name, sample, min, max, bucket_count, \
- docstring) \
- QUIC_CLIENT_HISTOGRAM_TIMES_IMPL(name, sample, min, max, bucket_count, \
- docstring)
-
-//------------------------------------------------------------------------------
-// Count histograms. These are used for collecting numeric data.
-
-// These macros default to exponential histograms - i.e. the lengths of the
-// bucket ranges exponentially increase as the sample range increases.
-
-// All of these macros must be called with |name| as a runtime constant.
-
-// Any data outside the range here will be put in underflow and overflow
-// buckets. Min values should be >=1 as emitted 0s will still go into the
-// underflow bucket.
-
-// Sample usage:
-// UMA_CLIENT_HISTOGRAM_CUSTOM_COUNTS("My.Histogram", 1, 100000000, 100,
-// "Counters of hitting certian code.");
-
-#define QUIC_CLIENT_HISTOGRAM_COUNTS(name, sample, min, max, bucket_count, \
- docstring) \
- QUIC_CLIENT_HISTOGRAM_COUNTS_IMPL(name, sample, min, max, bucket_count, \
- docstring)
-
-inline void QuicClientSparseHistogram(const std::string& name, int sample) {
- QuicClientSparseHistogramImpl(name, sample);
-}
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_PLATFORM_API_QUIC_CLIENT_STATS_H_
diff --git a/chromium/net/third_party/quiche/src/quic/platform/api/quic_containers.h b/chromium/net/third_party/quiche/src/quic/platform/api/quic_containers.h
deleted file mode 100644
index 19795e71a6f..00000000000
--- a/chromium/net/third_party/quiche/src/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_platform_impl/quiche_containers_impl.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::QuicheSmallOrderedSetImpl<Key, Compare>;
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_PLATFORM_API_QUIC_CONTAINERS_H_
diff --git a/chromium/net/third_party/quiche/src/quic/platform/api/quic_default_proof_providers.h b/chromium/net/third_party/quiche/src/quic/platform/api/quic_default_proof_providers.h
deleted file mode 100644
index c6ace4162d5..00000000000
--- a/chromium/net/third_party/quiche/src/quic/platform/api/quic_default_proof_providers.h
+++ /dev/null
@@ -1,32 +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_DEFAULT_PROOF_PROVIDERS_H_
-#define QUICHE_QUIC_PLATFORM_API_QUIC_DEFAULT_PROOF_PROVIDERS_H_
-
-#include <memory>
-
-#include "quic/core/crypto/proof_source.h"
-#include "quic/core/crypto/proof_verifier.h"
-#include "net/quic/platform/impl/quic_default_proof_providers_impl.h"
-
-namespace quic {
-
-// Provides a default proof verifier that can verify a cert chain for |host|.
-// The verifier has to do a good faith attempt at verifying the certificate
-// against a reasonable root store, and not just always return success.
-inline std::unique_ptr<ProofVerifier> CreateDefaultProofVerifier(
- const std::string& host) {
- return CreateDefaultProofVerifierImpl(host);
-}
-
-// Provides a default proof source for CLI-based tools. The actual certificates
-// used in the proof source should be confifgurable via command-line flags.
-inline std::unique_ptr<ProofSource> CreateDefaultProofSource() {
- return CreateDefaultProofSourceImpl();
-}
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_PLATFORM_API_QUIC_DEFAULT_PROOF_PROVIDERS_H_
diff --git a/chromium/net/third_party/quiche/src/quic/platform/api/quic_epoll.h b/chromium/net/third_party/quiche/src/quic/platform/api/quic_epoll.h
deleted file mode 100644
index e429ef8b234..00000000000
--- a/chromium/net/third_party/quiche/src/quic/platform/api/quic_epoll.h
+++ /dev/null
@@ -1,19 +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_EPOLL_H_
-#define QUICHE_QUIC_PLATFORM_API_QUIC_EPOLL_H_
-
-#include "net/quic/platform/impl/quic_epoll_impl.h"
-
-namespace quic {
-
-using QuicEpollServer = QuicEpollServerImpl;
-using QuicEpollEvent = QuicEpollEventImpl;
-using QuicEpollAlarmBase = QuicEpollAlarmBaseImpl;
-using QuicEpollCallbackInterface = QuicEpollCallbackInterfaceImpl;
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_PLATFORM_API_QUIC_EPOLL_H_
diff --git a/chromium/net/third_party/quiche/src/quic/platform/api/quic_epoll_test_tools.h b/chromium/net/third_party/quiche/src/quic/platform/api/quic_epoll_test_tools.h
deleted file mode 100644
index a7c2ce3f287..00000000000
--- a/chromium/net/third_party/quiche/src/quic/platform/api/quic_epoll_test_tools.h
+++ /dev/null
@@ -1,12 +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_EPOLL_TEST_TOOLS_H_
-#define QUICHE_QUIC_PLATFORM_API_QUIC_EPOLL_TEST_TOOLS_H_
-
-#include "net/quic/platform/impl/quic_epoll_test_tools_impl.h"
-
-using QuicFakeEpollServer = QuicFakeEpollServerImpl;
-
-#endif // QUICHE_QUIC_PLATFORM_API_QUIC_EPOLL_TEST_TOOLS_H_
diff --git a/chromium/net/third_party/quiche/src/quic/platform/api/quic_error_code_wrappers.h b/chromium/net/third_party/quiche/src/quic/platform/api/quic_error_code_wrappers.h
deleted file mode 100644
index 733572ef653..00000000000
--- a/chromium/net/third_party/quiche/src/quic/platform/api/quic_error_code_wrappers.h
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_PLATFORM_API_QUIC_ERROR_CODE_WRAPPERS_H_
-#define QUICHE_QUIC_PLATFORM_API_QUIC_ERROR_CODE_WRAPPERS_H_
-
-#include "net/quic/platform/impl/quic_error_code_wrappers_impl.h"
-
-// TODO(vasilvv): ensure WRITE_STATUS_MSG_TOO_BIG works everywhere and remove
-// this.
-#define QUIC_EMSGSIZE QUIC_EMSGSIZE_IMPL
-
-#endif // QUICHE_QUIC_PLATFORM_API_QUIC_ERROR_CODE_WRAPPERS_H_
diff --git a/chromium/net/third_party/quiche/src/quic/platform/api/quic_expect_bug.h b/chromium/net/third_party/quiche/src/quic/platform/api/quic_expect_bug.h
deleted file mode 100644
index 936b11f59b6..00000000000
--- a/chromium/net/third_party/quiche/src/quic/platform/api/quic_expect_bug.h
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_PLATFORM_API_QUIC_EXPECT_BUG_H_
-#define QUICHE_QUIC_PLATFORM_API_QUIC_EXPECT_BUG_H_
-
-#include "net/quic/platform/impl/quic_expect_bug_impl.h"
-
-#define EXPECT_QUIC_BUG EXPECT_QUIC_BUG_IMPL
-#define EXPECT_QUIC_PEER_BUG(statement, regex) \
- EXPECT_QUIC_PEER_BUG_IMPL(statement, regex)
-
-#endif // QUICHE_QUIC_PLATFORM_API_QUIC_EXPECT_BUG_H_
diff --git a/chromium/net/third_party/quiche/src/quic/platform/api/quic_export.h b/chromium/net/third_party/quiche/src/quic/platform/api/quic_export.h
deleted file mode 100644
index b4f82aa15f4..00000000000
--- a/chromium/net/third_party/quiche/src/quic/platform/api/quic_export.h
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_PLATFORM_API_QUIC_EXPORT_H_
-#define QUICHE_QUIC_PLATFORM_API_QUIC_EXPORT_H_
-
-#include "quiche_platform_impl/quiche_export_impl.h"
-
-// QUIC_EXPORT is not meant to be used.
-#define QUIC_EXPORT QUICHE_EXPORT_IMPL
-
-// 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
-
-// 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
-
-#endif // QUICHE_QUIC_PLATFORM_API_QUIC_EXPORT_H_
diff --git a/chromium/net/third_party/quiche/src/quic/platform/api/quic_exported_stats.h b/chromium/net/third_party/quiche/src/quic/platform/api/quic_exported_stats.h
deleted file mode 100644
index 28c82ec8ce0..00000000000
--- a/chromium/net/third_party/quiche/src/quic/platform/api/quic_exported_stats.h
+++ /dev/null
@@ -1,96 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_PLATFORM_API_QUIC_EXPORTED_STATS_H_
-#define QUICHE_QUIC_PLATFORM_API_QUIC_EXPORTED_STATS_H_
-
-#include "net/quic/platform/impl/quic_client_stats_impl.h"
-#include "net/quic/platform/impl/quic_server_stats_impl.h"
-
-namespace quic {
-
-// TODO(wub): Add support for counters. Only histograms are supported for now.
-
-//------------------------------------------------------------------------------
-// Enumeration histograms.
-//
-// Sample usage:
-// // In Chrome, these values are persisted to logs. Entries should not be
-// // renumbered and numeric values should never be reused.
-// enum class MyEnum {
-// FIRST_VALUE = 0,
-// SECOND_VALUE = 1,
-// ...
-// FINAL_VALUE = N,
-// COUNT
-// };
-// QUIC_HISTOGRAM_ENUM("My.Enumeration", MyEnum::SOME_VALUE, MyEnum::COUNT,
-// "Number of time $foo equals to some enum value");
-//
-// Note: The value in |sample| must be strictly less than |enum_size|.
-
-#define QUIC_HISTOGRAM_ENUM(name, sample, enum_size, docstring) \
- do { \
- QUIC_CLIENT_HISTOGRAM_ENUM_IMPL(name, sample, enum_size, docstring); \
- QUIC_SERVER_HISTOGRAM_ENUM_IMPL(name, sample, enum_size, docstring); \
- } while (0)
-
-//------------------------------------------------------------------------------
-// Histogram for boolean values.
-
-// Sample usage:
-// QUIC_HISTOGRAM_BOOL("My.Boolean", bool,
-// "Number of times $foo is true or false");
-#define QUIC_HISTOGRAM_BOOL(name, sample, docstring) \
- do { \
- QUIC_CLIENT_HISTOGRAM_BOOL_IMPL(name, sample, docstring); \
- QUIC_SERVER_HISTOGRAM_BOOL_IMPL(name, sample, docstring); \
- } while (0)
-
-//------------------------------------------------------------------------------
-// Timing histograms. These are used for collecting timing data (generally
-// latencies).
-
-// These macros create exponentially sized histograms (lengths of the bucket
-// ranges exponentially increase as the sample range increases). The units for
-// sample and max are unspecified, but they must be the same for one histogram.
-
-// Sample usage:
-// QUIC_HISTOGRAM_TIMES("My.Timing.Histogram.InMs", time_delta,
-// QuicTime::Delta::FromSeconds(1), QuicTime::Delta::FromSecond(3600 *
-// 24), 100, "Time spent in doing operation.");
-
-#define QUIC_HISTOGRAM_TIMES(name, sample, min, max, bucket_count, docstring) \
- do { \
- QUIC_CLIENT_HISTOGRAM_TIMES_IMPL(name, sample, min, max, bucket_count, \
- docstring); \
- QUIC_SERVER_HISTOGRAM_TIMES_IMPL(name, sample, min, max, bucket_count, \
- docstring); \
- } while (0)
-
-//------------------------------------------------------------------------------
-// Count histograms. These are used for collecting numeric data.
-
-// These macros default to exponential histograms - i.e. the lengths of the
-// bucket ranges exponentially increase as the sample range increases.
-
-// All of these macros must be called with |name| as a runtime constant.
-
-// Sample usage:
-// QUIC_HISTOGRAM_COUNTS("My.Histogram",
-// sample, // Number of something in this event.
-// 1000, // Record up to 1K of something.
-// "Number of something.");
-
-#define QUIC_HISTOGRAM_COUNTS(name, sample, min, max, bucket_count, docstring) \
- do { \
- QUIC_CLIENT_HISTOGRAM_COUNTS_IMPL(name, sample, min, max, bucket_count, \
- docstring); \
- QUIC_SERVER_HISTOGRAM_COUNTS_IMPL(name, sample, min, max, bucket_count, \
- docstring); \
- } while (0)
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_PLATFORM_API_QUIC_EXPORTED_STATS_H_
diff --git a/chromium/net/third_party/quiche/src/quic/platform/api/quic_flag_utils.h b/chromium/net/third_party/quiche/src/quic/platform/api/quic_flag_utils.h
deleted file mode 100644
index 63cbb91dd4f..00000000000
--- a/chromium/net/third_party/quiche/src/quic/platform/api/quic_flag_utils.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_FLAG_UTILS_H_
-#define QUICHE_QUIC_PLATFORM_API_QUIC_FLAG_UTILS_H_
-
-#include "common/platform/api/quiche_flag_utils.h"
-
-#define QUIC_RELOADABLE_FLAG_COUNT QUICHE_RELOADABLE_FLAG_COUNT
-#define QUIC_RELOADABLE_FLAG_COUNT_N QUICHE_RELOADABLE_FLAG_COUNT_N
-
-#define QUIC_RESTART_FLAG_COUNT QUICHE_RESTART_FLAG_COUNT
-#define QUIC_RESTART_FLAG_COUNT_N QUICHE_RESTART_FLAG_COUNT_N
-
-#define QUIC_CODE_COUNT QUICHE_CODE_COUNT
-#define QUIC_CODE_COUNT_N QUICHE_CODE_COUNT_N
-
-#endif // QUICHE_QUIC_PLATFORM_API_QUIC_FLAG_UTILS_H_
diff --git a/chromium/net/third_party/quiche/src/quic/platform/api/quic_flags.h b/chromium/net/third_party/quiche/src/quic/platform/api/quic_flags.h
deleted file mode 100644
index 762e5907645..00000000000
--- a/chromium/net/third_party/quiche/src/quic/platform/api/quic_flags.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_FLAGS_H_
-#define QUICHE_QUIC_PLATFORM_API_QUIC_FLAGS_H_
-
-#include <string>
-#include <vector>
-
-#include "quiche_platform_impl/quic_flags_impl.h"
-#include "common/platform/api/quiche_flags.h"
-
-#define GetQuicReloadableFlag(flag) GetQuicheReloadableFlag(quic, flag)
-#define SetQuicReloadableFlag(flag, value) \
- SetQuicheReloadableFlag(quic, flag, value)
-#define GetQuicRestartFlag(flag) GetQuicheRestartFlag(quic, flag)
-#define SetQuicRestartFlag(flag, value) SetQuicheRestartFlag(quic, flag, value)
-#define GetQuicFlag(flag) GetQuicheFlag(flag)
-#define SetQuicFlag(flag, value) SetQuicheFlag(flag, value)
-
-#endif // QUICHE_QUIC_PLATFORM_API_QUIC_FLAGS_H_
diff --git a/chromium/net/third_party/quiche/src/quic/platform/api/quic_hostname_utils.cc b/chromium/net/third_party/quiche/src/quic/platform/api/quic_hostname_utils.cc
deleted file mode 100644
index d8d63fa17d6..00000000000
--- a/chromium/net/third_party/quiche/src/quic/platform/api/quic_hostname_utils.cc
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright (c) 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/platform/api/quic_hostname_utils.h"
-#include "absl/strings/string_view.h"
-
-namespace quic {
-
-// static
-bool QuicHostnameUtils::IsValidSNI(absl::string_view sni) {
- return QuicHostnameUtilsImpl::IsValidSNI(sni);
-}
-
-// static
-std::string QuicHostnameUtils::NormalizeHostname(absl::string_view hostname) {
- return QuicHostnameUtilsImpl::NormalizeHostname(hostname);
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/platform/api/quic_hostname_utils.h b/chromium/net/third_party/quiche/src/quic/platform/api/quic_hostname_utils.h
deleted file mode 100644
index 79158b97eb3..00000000000
--- a/chromium/net/third_party/quiche/src/quic/platform/api/quic_hostname_utils.h
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright (c) 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_PLATFORM_API_QUIC_HOSTNAME_UTILS_H_
-#define QUICHE_QUIC_PLATFORM_API_QUIC_HOSTNAME_UTILS_H_
-
-#include <string>
-
-#include "absl/strings/string_view.h"
-#include "quic/platform/api/quic_export.h"
-#include "net/quic/platform/impl/quic_hostname_utils_impl.h"
-
-namespace quic {
-
-class QUIC_EXPORT_PRIVATE QuicHostnameUtils {
- public:
- QuicHostnameUtils() = delete;
-
- // Returns true if the sni is valid, false otherwise.
- // (1) disallow IP addresses;
- // (2) check that the hostname contains valid characters only; and
- // (3) contains at least one dot.
- static bool IsValidSNI(absl::string_view sni);
-
- // Canonicalizes the specified hostname. This involves a wide variety of
- // transformations, including lowercasing, removing trailing dots and IDNA
- // conversion.
- static std::string NormalizeHostname(absl::string_view hostname);
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_PLATFORM_API_QUIC_HOSTNAME_UTILS_H_
diff --git a/chromium/net/third_party/quiche/src/quic/platform/api/quic_hostname_utils_test.cc b/chromium/net/third_party/quiche/src/quic/platform/api/quic_hostname_utils_test.cc
deleted file mode 100644
index 398f44a4a75..00000000000
--- a/chromium/net/third_party/quiche/src/quic/platform/api/quic_hostname_utils_test.cc
+++ /dev/null
@@ -1,89 +0,0 @@
-// Copyright (c) 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/platform/api/quic_hostname_utils.h"
-
-#include <string>
-
-#include "absl/base/macros.h"
-#include "quic/platform/api/quic_test.h"
-
-namespace quic {
-namespace test {
-namespace {
-
-class QuicHostnameUtilsTest : public QuicTest {};
-
-TEST_F(QuicHostnameUtilsTest, IsValidSNI) {
- // IP as SNI.
- EXPECT_FALSE(QuicHostnameUtils::IsValidSNI("192.168.0.1"));
- // SNI without any dot.
- EXPECT_TRUE(QuicHostnameUtils::IsValidSNI("somedomain"));
- // Invalid by RFC2396 but unfortunately domains of this form exist.
- EXPECT_TRUE(QuicHostnameUtils::IsValidSNI("some_domain.com"));
- // An empty string must be invalid otherwise the QUIC client will try sending
- // it.
- EXPECT_FALSE(QuicHostnameUtils::IsValidSNI(""));
-
- // Valid SNI
- EXPECT_TRUE(QuicHostnameUtils::IsValidSNI("test.google.com"));
-}
-
-TEST_F(QuicHostnameUtilsTest, NormalizeHostname) {
- // clang-format off
- struct {
- const char *input, *expected;
- } tests[] = {
- {
- "www.google.com",
- "www.google.com",
- },
- {
- "WWW.GOOGLE.COM",
- "www.google.com",
- },
- {
- "www.google.com.",
- "www.google.com",
- },
- {
- "www.google.COM.",
- "www.google.com",
- },
- {
- "www.google.com..",
- "www.google.com",
- },
- {
- "www.google.com........",
- "www.google.com",
- },
- {
- "",
- "",
- },
- {
- ".",
- "",
- },
- {
- "........",
- "",
- },
- {
- "\xe5\x85\x89.google.com",
- "xn--54q.google.com",
- },
- };
- // clang-format on
-
- for (size_t i = 0; i < ABSL_ARRAYSIZE(tests); ++i) {
- EXPECT_EQ(std::string(tests[i].expected),
- QuicHostnameUtils::NormalizeHostname(tests[i].input));
- }
-}
-
-} // namespace
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/platform/api/quic_iovec.h b/chromium/net/third_party/quiche/src/quic/platform/api/quic_iovec.h
deleted file mode 100644
index 97202cd0afd..00000000000
--- a/chromium/net/third_party/quiche/src/quic/platform/api/quic_iovec.h
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_PLATFORM_API_QUIC_IOVEC_H_
-#define QUICHE_QUIC_PLATFORM_API_QUIC_IOVEC_H_
-
-#include <cstddef>
-#include <type_traits>
-
-#include "net/quic/platform/impl/quic_iovec_impl.h"
-
-namespace quic {
-
-// The impl header has to export struct iovec, or a POSIX-compatible polyfill.
-// Below, we mostly assert that what we have is appropriate.
-static_assert(std::is_standard_layout<struct iovec>::value,
- "iovec has to be a standard-layout struct");
-
-static_assert(offsetof(struct iovec, iov_base) < sizeof(struct iovec),
- "iovec has to have iov_base");
-static_assert(offsetof(struct iovec, iov_len) < sizeof(struct iovec),
- "iovec has to have iov_len");
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_PLATFORM_API_QUIC_IOVEC_H_
diff --git a/chromium/net/third_party/quiche/src/quic/platform/api/quic_ip_address.cc b/chromium/net/third_party/quiche/src/quic/platform/api/quic_ip_address.cc
deleted file mode 100644
index b2cb649f5f9..00000000000
--- a/chromium/net/third_party/quiche/src/quic/platform/api/quic_ip_address.cc
+++ /dev/null
@@ -1,241 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/platform/api/quic_ip_address.h"
-
-#include <algorithm>
-#include <cstdint>
-#include <cstring>
-#include <string>
-
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-static int ToPlatformAddressFamily(IpAddressFamily family) {
- switch (family) {
- case IpAddressFamily::IP_V4:
- return AF_INET;
- case IpAddressFamily::IP_V6:
- return AF_INET6;
- case IpAddressFamily::IP_UNSPEC:
- return AF_UNSPEC;
- }
- QUIC_BUG(quic_bug_10126_1)
- << "Invalid IpAddressFamily " << static_cast<int32_t>(family);
- return AF_UNSPEC;
-}
-
-QuicIpAddress QuicIpAddress::Loopback4() {
- QuicIpAddress result;
- result.family_ = IpAddressFamily::IP_V4;
- result.address_.bytes[0] = 127;
- result.address_.bytes[1] = 0;
- result.address_.bytes[2] = 0;
- result.address_.bytes[3] = 1;
- return result;
-}
-
-QuicIpAddress QuicIpAddress::Loopback6() {
- QuicIpAddress result;
- result.family_ = IpAddressFamily::IP_V6;
- uint8_t* bytes = result.address_.bytes;
- memset(bytes, 0, 15);
- bytes[15] = 1;
- return result;
-}
-
-QuicIpAddress QuicIpAddress::Any4() {
- in_addr address;
- memset(&address, 0, sizeof(address));
- return QuicIpAddress(address);
-}
-
-QuicIpAddress QuicIpAddress::Any6() {
- in6_addr address;
- memset(&address, 0, sizeof(address));
- return QuicIpAddress(address);
-}
-
-QuicIpAddress::QuicIpAddress() : family_(IpAddressFamily::IP_UNSPEC) {}
-
-QuicIpAddress::QuicIpAddress(const in_addr& ipv4_address)
- : family_(IpAddressFamily::IP_V4) {
- address_.v4 = ipv4_address;
-}
-QuicIpAddress::QuicIpAddress(const in6_addr& ipv6_address)
- : family_(IpAddressFamily::IP_V6) {
- address_.v6 = ipv6_address;
-}
-
-bool operator==(QuicIpAddress lhs, QuicIpAddress rhs) {
- if (lhs.family_ != rhs.family_) {
- return false;
- }
- switch (lhs.family_) {
- case IpAddressFamily::IP_V4:
- return std::equal(lhs.address_.bytes,
- lhs.address_.bytes + QuicIpAddress::kIPv4AddressSize,
- rhs.address_.bytes);
- case IpAddressFamily::IP_V6:
- return std::equal(lhs.address_.bytes,
- lhs.address_.bytes + QuicIpAddress::kIPv6AddressSize,
- rhs.address_.bytes);
- case IpAddressFamily::IP_UNSPEC:
- return true;
- }
- QUIC_BUG(quic_bug_10126_2)
- << "Invalid IpAddressFamily " << static_cast<int32_t>(lhs.family_);
- return false;
-}
-
-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_;
-}
-
-int QuicIpAddress::AddressFamilyToInt() const {
- return ToPlatformAddressFamily(family_);
-}
-
-std::string QuicIpAddress::ToPackedString() const {
- switch (family_) {
- case IpAddressFamily::IP_V4:
- return std::string(address_.chars, sizeof(address_.v4));
- case IpAddressFamily::IP_V6:
- return std::string(address_.chars, sizeof(address_.v6));
- case IpAddressFamily::IP_UNSPEC:
- return "";
- }
- QUIC_BUG(quic_bug_10126_3)
- << "Invalid IpAddressFamily " << static_cast<int32_t>(family_);
- return "";
-}
-
-std::string QuicIpAddress::ToString() const {
- if (!IsInitialized()) {
- return "";
- }
-
- char buffer[INET6_ADDRSTRLEN] = {0};
- const char* result =
- inet_ntop(AddressFamilyToInt(), address_.bytes, buffer, sizeof(buffer));
- QUIC_BUG_IF(quic_bug_10126_4, result == nullptr)
- << "Failed to convert an IP address to string";
- return buffer;
-}
-
-static const uint8_t kMappedAddressPrefix[] = {
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
-};
-
-QuicIpAddress QuicIpAddress::Normalized() const {
- if (!IsIPv6()) {
- return *this;
- }
- if (!std::equal(std::begin(kMappedAddressPrefix),
- std::end(kMappedAddressPrefix), address_.bytes)) {
- return *this;
- }
-
- in_addr result;
- memcpy(&result, &address_.bytes[12], sizeof(result));
- return QuicIpAddress(result);
-}
-
-QuicIpAddress QuicIpAddress::DualStacked() const {
- if (!IsIPv4()) {
- return *this;
- }
-
- QuicIpAddress result;
- result.family_ = IpAddressFamily::IP_V6;
- memcpy(result.address_.bytes, kMappedAddressPrefix,
- sizeof(kMappedAddressPrefix));
- memcpy(result.address_.bytes + 12, address_.bytes, kIPv4AddressSize);
- return result;
-}
-
-bool QuicIpAddress::FromPackedString(const char* data, size_t length) {
- switch (length) {
- case kIPv4AddressSize:
- family_ = IpAddressFamily::IP_V4;
- break;
- case kIPv6AddressSize:
- family_ = IpAddressFamily::IP_V6;
- break;
- default:
- return false;
- }
- memcpy(address_.chars, data, length);
- return true;
-}
-
-bool QuicIpAddress::FromString(std::string str) {
- for (IpAddressFamily family :
- {IpAddressFamily::IP_V6, IpAddressFamily::IP_V4}) {
- int result =
- inet_pton(ToPlatformAddressFamily(family), str.c_str(), address_.bytes);
- if (result > 0) {
- family_ = family;
- return true;
- }
- }
- return false;
-}
-
-bool QuicIpAddress::IsIPv4() const {
- return family_ == IpAddressFamily::IP_V4;
-}
-
-bool QuicIpAddress::IsIPv6() const {
- return family_ == IpAddressFamily::IP_V6;
-}
-
-bool QuicIpAddress::InSameSubnet(const QuicIpAddress& other,
- int subnet_length) {
- if (!IsInitialized()) {
- QUIC_BUG(quic_bug_10126_5)
- << "Attempting to do subnet matching on undefined address";
- return false;
- }
- if ((IsIPv4() && subnet_length > 32) || (IsIPv6() && subnet_length > 128)) {
- QUIC_BUG(quic_bug_10126_6) << "Subnet mask is out of bounds";
- return false;
- }
-
- int bytes_to_check = subnet_length / 8;
- int bits_to_check = subnet_length % 8;
- const uint8_t* const lhs = address_.bytes;
- const uint8_t* const rhs = other.address_.bytes;
- if (!std::equal(lhs, lhs + bytes_to_check, rhs)) {
- return false;
- }
- if (bits_to_check == 0) {
- return true;
- }
- QUICHE_DCHECK_LT(static_cast<size_t>(bytes_to_check), sizeof(address_.bytes));
- int mask = (~0u) << (8u - bits_to_check);
- return (lhs[bytes_to_check] & mask) == (rhs[bytes_to_check] & mask);
-}
-
-in_addr QuicIpAddress::GetIPv4() const {
- QUICHE_DCHECK(IsIPv4());
- return address_.v4;
-}
-
-in6_addr QuicIpAddress::GetIPv6() const {
- QUICHE_DCHECK(IsIPv6());
- return address_.v6;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/platform/api/quic_ip_address.h b/chromium/net/third_party/quiche/src/quic/platform/api/quic_ip_address.h
deleted file mode 100644
index 26be870b11e..00000000000
--- a/chromium/net/third_party/quiche/src/quic/platform/api/quic_ip_address.h
+++ /dev/null
@@ -1,97 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_PLATFORM_API_QUIC_IP_ADDRESS_H_
-#define QUICHE_QUIC_PLATFORM_API_QUIC_IP_ADDRESS_H_
-
-#if defined(_WIN32)
-#include <winsock2.h>
-#include <ws2tcpip.h>
-#else
-#include <arpa/inet.h>
-#include <netinet/in.h>
-#include <sys/socket.h>
-#include <sys/types.h>
-#endif
-
-#include <ostream>
-#include <string>
-
-#include "quic/platform/api/quic_export.h"
-#include "quic/platform/api/quic_ip_address_family.h"
-
-namespace quic {
-
-// Represents an IP address.
-class QUIC_EXPORT_PRIVATE QuicIpAddress {
- public:
- // Sizes of IP addresses of different types, in bytes.
- enum : size_t {
- kIPv4AddressSize = 32 / 8,
- kIPv6AddressSize = 128 / 8,
- kMaxAddressSize = kIPv6AddressSize,
- };
-
- // TODO(fayang): Remove Loopback*() and use TestLoopback*() in tests.
- static QuicIpAddress Loopback4();
- static QuicIpAddress Loopback6();
- static QuicIpAddress Any4();
- static QuicIpAddress Any6();
-
- QuicIpAddress();
- QuicIpAddress(const QuicIpAddress& other) = default;
- explicit QuicIpAddress(const in_addr& ipv4_address);
- explicit QuicIpAddress(const in6_addr& ipv6_address);
- QuicIpAddress& operator=(const QuicIpAddress& other) = default;
- QuicIpAddress& operator=(QuicIpAddress&& other) = default;
- QUIC_EXPORT_PRIVATE friend bool operator==(QuicIpAddress lhs,
- QuicIpAddress rhs);
- QUIC_EXPORT_PRIVATE friend bool operator!=(QuicIpAddress lhs,
- QuicIpAddress rhs);
-
- bool IsInitialized() const;
- IpAddressFamily address_family() const;
- int AddressFamilyToInt() const;
- // Returns the address as a sequence of bytes in network-byte-order. IPv4 will
- // be 4 bytes. IPv6 will be 16 bytes.
- std::string ToPackedString() const;
- // Returns string representation of the address.
- std::string ToString() const;
- // Normalizes the address representation with respect to IPv4 addresses, i.e,
- // mapped IPv4 addresses ("::ffff:X.Y.Z.Q") are converted to pure IPv4
- // addresses. All other IPv4, IPv6, and empty values are left unchanged.
- QuicIpAddress Normalized() const;
- // Returns an address suitable for use in IPv6-aware contexts. This is the
- // opposite of NormalizeIPAddress() above. IPv4 addresses are converted into
- // their IPv4-mapped address equivalents (e.g. 192.0.2.1 becomes
- // ::ffff:192.0.2.1). IPv6 addresses are a noop (they are returned
- // unchanged).
- QuicIpAddress DualStacked() const;
- bool FromPackedString(const char* data, size_t length);
- bool FromString(std::string str);
- bool IsIPv4() const;
- bool IsIPv6() const;
- bool InSameSubnet(const QuicIpAddress& other, int subnet_length);
-
- in_addr GetIPv4() const;
- in6_addr GetIPv6() const;
-
- private:
- union {
- in_addr v4;
- in6_addr v6;
- uint8_t bytes[kMaxAddressSize];
- char chars[kMaxAddressSize];
- } address_;
- IpAddressFamily family_;
-};
-
-inline std::ostream& operator<<(std::ostream& os, const QuicIpAddress address) {
- os << address.ToString();
- return os;
-}
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_PLATFORM_API_QUIC_IP_ADDRESS_H_
diff --git a/chromium/net/third_party/quiche/src/quic/platform/api/quic_ip_address_family.h b/chromium/net/third_party/quiche/src/quic/platform/api/quic_ip_address_family.h
deleted file mode 100644
index dad2cb971b7..00000000000
--- a/chromium/net/third_party/quiche/src/quic/platform/api/quic_ip_address_family.h
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_PLATFORM_API_QUIC_IP_ADDRESS_FAMILY_H_
-#define QUICHE_QUIC_PLATFORM_API_QUIC_IP_ADDRESS_FAMILY_H_
-
-namespace quic {
-
-// IP address family type used in QUIC. This hides platform dependant IP address
-// family types.
-enum class IpAddressFamily {
- IP_V4,
- IP_V6,
- IP_UNSPEC,
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_PLATFORM_API_QUIC_IP_ADDRESS_FAMILY_H_
diff --git a/chromium/net/third_party/quiche/src/quic/platform/api/quic_ip_address_test.cc b/chromium/net/third_party/quiche/src/quic/platform/api/quic_ip_address_test.cc
deleted file mode 100644
index f0f196ff579..00000000000
--- a/chromium/net/third_party/quiche/src/quic/platform/api/quic_ip_address_test.cc
+++ /dev/null
@@ -1,141 +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 "quic/platform/api/quic_ip_address.h"
-
-#include <cstdint>
-
-#include "quic/platform/api/quic_test.h"
-
-namespace quic {
-namespace test {
-namespace {
-
-TEST(QuicIpAddressTest, IPv4) {
- QuicIpAddress ip_address;
- EXPECT_FALSE(ip_address.IsInitialized());
-
- EXPECT_TRUE(ip_address.FromString("127.0.52.223"));
- EXPECT_TRUE(ip_address.IsInitialized());
-
- EXPECT_EQ(IpAddressFamily::IP_V4, ip_address.address_family());
- EXPECT_TRUE(ip_address.IsIPv4());
- EXPECT_FALSE(ip_address.IsIPv6());
-
- EXPECT_EQ("127.0.52.223", ip_address.ToString());
- const in_addr v4_address = ip_address.GetIPv4();
- const uint8_t* const v4_address_ptr =
- reinterpret_cast<const uint8_t*>(&v4_address);
- EXPECT_EQ(127u, *(v4_address_ptr + 0));
- EXPECT_EQ(0u, *(v4_address_ptr + 1));
- EXPECT_EQ(52u, *(v4_address_ptr + 2));
- EXPECT_EQ(223u, *(v4_address_ptr + 3));
-}
-
-TEST(QuicIpAddressTest, IPv6) {
- QuicIpAddress ip_address;
- EXPECT_FALSE(ip_address.IsInitialized());
-
- EXPECT_TRUE(ip_address.FromString("fe80::1ff:fe23:4567"));
- EXPECT_TRUE(ip_address.IsInitialized());
-
- EXPECT_EQ(IpAddressFamily::IP_V6, ip_address.address_family());
- EXPECT_FALSE(ip_address.IsIPv4());
- EXPECT_TRUE(ip_address.IsIPv6());
-
- EXPECT_EQ("fe80::1ff:fe23:4567", ip_address.ToString());
- const in6_addr v6_address = ip_address.GetIPv6();
- const uint16_t* const v6_address_ptr =
- reinterpret_cast<const uint16_t*>(&v6_address);
- EXPECT_EQ(0x80feu, *(v6_address_ptr + 0));
- EXPECT_EQ(0x0000u, *(v6_address_ptr + 1));
- EXPECT_EQ(0x0000u, *(v6_address_ptr + 2));
- EXPECT_EQ(0x0000u, *(v6_address_ptr + 3));
- EXPECT_EQ(0x0000u, *(v6_address_ptr + 4));
- EXPECT_EQ(0xff01u, *(v6_address_ptr + 5));
- EXPECT_EQ(0x23feu, *(v6_address_ptr + 6));
- EXPECT_EQ(0x6745u, *(v6_address_ptr + 7));
-
- EXPECT_EQ(ip_address, ip_address.Normalized());
- EXPECT_EQ(ip_address, ip_address.DualStacked());
-}
-
-TEST(QuicIpAddressTest, FromPackedString) {
- QuicIpAddress loopback4, loopback6;
- const char loopback4_packed[] = "\x7f\0\0\x01";
- const char loopback6_packed[] = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x01";
- EXPECT_TRUE(loopback4.FromPackedString(loopback4_packed, 4));
- EXPECT_TRUE(loopback6.FromPackedString(loopback6_packed, 16));
- EXPECT_EQ(loopback4, QuicIpAddress::Loopback4());
- EXPECT_EQ(loopback6, QuicIpAddress::Loopback6());
-}
-
-TEST(QuicIpAddressTest, MappedAddress) {
- QuicIpAddress ipv4_address;
- QuicIpAddress mapped_address;
-
- EXPECT_TRUE(ipv4_address.FromString("127.0.0.1"));
- EXPECT_TRUE(mapped_address.FromString("::ffff:7f00:1"));
-
- EXPECT_EQ(mapped_address, ipv4_address.DualStacked());
- EXPECT_EQ(ipv4_address, mapped_address.Normalized());
-}
-
-TEST(QuicIpAddressTest, Subnets) {
- struct {
- const char* address1;
- const char* address2;
- int subnet_size;
- bool same_subnet;
- } test_cases[] = {
- {"127.0.0.1", "127.0.0.2", 24, true},
- {"8.8.8.8", "127.0.0.1", 24, false},
- {"8.8.8.8", "127.0.0.1", 16, false},
- {"8.8.8.8", "127.0.0.1", 8, false},
- {"8.8.8.8", "127.0.0.1", 2, false},
- {"8.8.8.8", "127.0.0.1", 1, true},
-
- {"127.0.0.1", "127.0.0.128", 24, true},
- {"127.0.0.1", "127.0.0.128", 25, false},
- {"127.0.0.1", "127.0.0.127", 25, true},
-
- {"127.0.0.1", "127.0.0.0", 30, true},
- {"127.0.0.1", "127.0.0.1", 30, true},
- {"127.0.0.1", "127.0.0.2", 30, true},
- {"127.0.0.1", "127.0.0.3", 30, true},
- {"127.0.0.1", "127.0.0.4", 30, false},
-
- {"127.0.0.1", "127.0.0.2", 31, false},
- {"127.0.0.1", "127.0.0.0", 31, true},
-
- {"::1", "fe80::1", 8, false},
- {"::1", "fe80::1", 1, false},
- {"::1", "fe80::1", 0, true},
- {"fe80::1", "fe80::2", 126, true},
- {"fe80::1", "fe80::2", 127, false},
- };
-
- for (const auto& test_case : test_cases) {
- QuicIpAddress address1, address2;
- ASSERT_TRUE(address1.FromString(test_case.address1));
- ASSERT_TRUE(address2.FromString(test_case.address2));
- EXPECT_EQ(test_case.same_subnet,
- address1.InSameSubnet(address2, test_case.subnet_size))
- << "Addresses: " << test_case.address1 << ", " << test_case.address2
- << "; subnet: /" << test_case.subnet_size;
- }
-}
-
-TEST(QuicIpAddress, LoopbackAddresses) {
- QuicIpAddress loopback4;
- QuicIpAddress loopback6;
- ASSERT_TRUE(loopback4.FromString("127.0.0.1"));
- ASSERT_TRUE(loopback6.FromString("::1"));
- EXPECT_EQ(loopback4, QuicIpAddress::Loopback4());
- EXPECT_EQ(loopback6, QuicIpAddress::Loopback6());
-}
-
-} // namespace
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/platform/api/quic_logging.h b/chromium/net/third_party/quiche/src/quic/platform/api/quic_logging.h
deleted file mode 100644
index 770d4081c20..00000000000
--- a/chromium/net/third_party/quiche/src/quic/platform/api/quic_logging.h
+++ /dev/null
@@ -1,38 +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_LOGGING_H_
-#define QUICHE_QUIC_PLATFORM_API_QUIC_LOGGING_H_
-
-#include "common/platform/api/quiche_logging.h"
-
-// Please note following QUIC_LOG are platform dependent:
-// INFO severity can be degraded (to VLOG(1) or DVLOG(1)).
-// Some platforms may not support QUIC_LOG_FIRST_N or QUIC_LOG_EVERY_N_SEC, and
-// they would simply be translated to LOG.
-
-#define QUIC_DVLOG QUICHE_DVLOG
-#define QUIC_DVLOG_IF QUICHE_DVLOG_IF
-#define QUIC_DLOG QUICHE_DLOG
-#define QUIC_DLOG_IF QUICHE_DLOG_IF
-#define QUIC_VLOG QUICHE_VLOG
-#define QUIC_LOG QUICHE_LOG
-#define QUIC_LOG_FIRST_N QUICHE_LOG_FIRST_N
-#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
-#define QUIC_LOG_INFO_IS_ON QUICHE_LOG_INFO_IS_ON
-#define QUIC_LOG_WARNING_IS_ON QUICHE_LOG_WARNING_IS_ON
-#define QUIC_LOG_ERROR_IS_ON QUICHE_LOG_ERROR_IS_ON
-
-#endif // QUICHE_QUIC_PLATFORM_API_QUIC_LOGGING_H_
diff --git a/chromium/net/third_party/quiche/src/quic/platform/api/quic_mem_slice.h b/chromium/net/third_party/quiche/src/quic/platform/api/quic_mem_slice.h
deleted file mode 100644
index adc03d45d8c..00000000000
--- a/chromium/net/third_party/quiche/src/quic/platform/api/quic_mem_slice.h
+++ /dev/null
@@ -1,92 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_PLATFORM_API_QUIC_MEM_SLICE_H_
-#define QUICHE_QUIC_PLATFORM_API_QUIC_MEM_SLICE_H_
-
-#include <memory>
-
-#include "absl/strings/string_view.h"
-#include "quic/platform/api/quic_export.h"
-#include "net/quic/platform/impl/quic_mem_slice_impl.h"
-
-/* API_DESCRIPTION
- QuicMemSlice is used to wrap application data and pass to QUIC stream's write
- interface. It refers to a memory block of data which should be around till
- QuicMemSlice::Reset() is called. It's upto each platform, to implement it as
- reference counted or not.
- API-DESCRIPTION */
-
-namespace quic {
-
-// QuicMemSlice is an internally reference counted data buffer used as the
-// source buffers for write operations. QuicMemSlice implicitly maintains a
-// reference count and will free the underlying data buffer when the reference
-// count reaches zero.
-class QUIC_EXPORT_PRIVATE QuicMemSlice {
- public:
- // Constructs a empty QuicMemSlice with no underlying data and 0 reference
- // count.
- QuicMemSlice() = default;
-
- // Constructs a QuicMemSlice that takes ownership of |buffer|. |length| must
- // not be zero. To construct an empty QuicMemSlice, use the zero-argument
- // constructor instead.
- // TODO(vasilvv): switch all users to QuicBuffer version, and make this
- // private.
- QuicMemSlice(QuicUniqueBufferPtr buffer, size_t length)
- : impl_(std::move(buffer), length) {}
-
- // Constructs a QuicMemSlice that takes ownership of |buffer|. The length of
- // the |buffer| must not be zero. To construct an empty QuicMemSlice, use the
- // zero-argument constructor instead.
- explicit QuicMemSlice(QuicBuffer buffer) : QuicMemSlice() {
- // Store the size of the buffer *before* calling buffer.Release().
- const size_t size = buffer.size();
- *this = QuicMemSlice(buffer.Release(), size);
- }
-
- // Constructs a QuicMemSlice that takes ownership of |buffer| allocated on
- // heap. |length| must not be zero.
- QuicMemSlice(std::unique_ptr<char[]> buffer, size_t length)
- : impl_(std::move(buffer), length) {}
-
- // Constructs QuicMemSlice from |impl|. It takes the reference away from
- // |impl|.
- explicit QuicMemSlice(QuicMemSliceImpl impl) : impl_(std::move(impl)) {}
-
- QuicMemSlice(const QuicMemSlice& other) = delete;
- QuicMemSlice& operator=(const QuicMemSlice& other) = delete;
-
- // Move constructors. |other| will not hold a reference to the data buffer
- // after this call completes.
- QuicMemSlice(QuicMemSlice&& other) = default;
- QuicMemSlice& operator=(QuicMemSlice&& other) = default;
-
- ~QuicMemSlice() = default;
-
- // Release the underlying reference. Further access the memory will result in
- // undefined behavior.
- void Reset() { impl_.Reset(); }
-
- // Returns a const char pointer to underlying data buffer.
- const char* data() const { return impl_.data(); }
- // Returns the length of underlying data buffer.
- size_t length() const { return impl_.length(); }
- // Returns the representation of the underlying data as a string view.
- absl::string_view AsStringView() const {
- return absl::string_view(data(), length());
- }
-
- bool empty() const { return impl_.empty(); }
-
- QuicMemSliceImpl* impl() { return &impl_; }
-
- private:
- QuicMemSliceImpl impl_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_PLATFORM_API_QUIC_MEM_SLICE_H_
diff --git a/chromium/net/third_party/quiche/src/quic/platform/api/quic_mem_slice_storage.cc b/chromium/net/third_party/quiche/src/quic/platform/api/quic_mem_slice_storage.cc
deleted file mode 100644
index 87bce7f07fc..00000000000
--- a/chromium/net/third_party/quiche/src/quic/platform/api/quic_mem_slice_storage.cc
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright 2021 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 "quic/platform/api/quic_mem_slice_storage.h"
-
-#include "quic/core/quic_utils.h"
-
-namespace quic {
-
-QuicMemSliceStorage::QuicMemSliceStorage(const struct iovec* iov, int iov_count,
- QuicBufferAllocator* allocator,
- const QuicByteCount max_slice_len) {
- if (iov == nullptr) {
- return;
- }
- QuicByteCount write_len = 0;
- for (int i = 0; i < iov_count; ++i) {
- write_len += iov[i].iov_len;
- }
- QUICHE_DCHECK_LT(0u, write_len);
-
- size_t io_offset = 0;
- while (write_len > 0) {
- size_t slice_len = std::min(write_len, max_slice_len);
- QuicBuffer buffer(allocator, slice_len);
- QuicUtils::CopyToBuffer(iov, iov_count, io_offset, slice_len,
- buffer.data());
- storage_.push_back(QuicMemSlice(std::move(buffer)));
- write_len -= slice_len;
- io_offset += slice_len;
- }
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/platform/api/quic_mem_slice_storage.h b/chromium/net/third_party/quiche/src/quic/platform/api/quic_mem_slice_storage.h
deleted file mode 100644
index 4cccee3045f..00000000000
--- a/chromium/net/third_party/quiche/src/quic/platform/api/quic_mem_slice_storage.h
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_PLATFORM_API_QUIC_MEM_SLICE_STORAGE_H_
-#define QUICHE_QUIC_PLATFORM_API_QUIC_MEM_SLICE_STORAGE_H_
-
-#include <vector>
-
-#include "absl/types/span.h"
-#include "quic/core/quic_buffer_allocator.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_export.h"
-#include "quic/platform/api/quic_iovec.h"
-#include "quic/platform/api/quic_mem_slice.h"
-
-namespace quic {
-
-// QuicMemSliceStorage is a container class that store QuicMemSlices for further
-// use cases such as turning into QuicMemSliceSpan.
-class QUIC_EXPORT_PRIVATE QuicMemSliceStorage {
- public:
- QuicMemSliceStorage(const struct iovec* iov, int iov_count,
- QuicBufferAllocator* allocator,
- const QuicByteCount max_slice_len);
-
- QuicMemSliceStorage(const QuicMemSliceStorage& other) = default;
- QuicMemSliceStorage& operator=(const QuicMemSliceStorage& other) = default;
- QuicMemSliceStorage(QuicMemSliceStorage&& other) = default;
- QuicMemSliceStorage& operator=(QuicMemSliceStorage&& other) = default;
-
- ~QuicMemSliceStorage() = default;
-
- // Return a QuicMemSliceSpan form of the storage.
- absl::Span<QuicMemSlice> ToSpan() { return absl::MakeSpan(storage_); }
-
- private:
- std::vector<QuicMemSlice> storage_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_PLATFORM_API_QUIC_MEM_SLICE_STORAGE_H_
diff --git a/chromium/net/third_party/quiche/src/quic/platform/api/quic_mem_slice_storage_test.cc b/chromium/net/third_party/quiche/src/quic/platform/api/quic_mem_slice_storage_test.cc
deleted file mode 100644
index 4bef774a0c6..00000000000
--- a/chromium/net/third_party/quiche/src/quic/platform/api/quic_mem_slice_storage_test.cc
+++ /dev/null
@@ -1,61 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/platform/api/quic_mem_slice_storage.h"
-
-#include "quic/core/quic_simple_buffer_allocator.h"
-#include "quic/platform/api/quic_test.h"
-
-namespace quic {
-namespace test {
-namespace {
-
-class QuicMemSliceStorageImplTest : public QuicTest {
- public:
- QuicMemSliceStorageImplTest() = default;
-};
-
-TEST_F(QuicMemSliceStorageImplTest, EmptyIov) {
- QuicMemSliceStorage storage(nullptr, 0, nullptr, 1024);
- EXPECT_TRUE(storage.ToSpan().empty());
-}
-
-TEST_F(QuicMemSliceStorageImplTest, SingleIov) {
- SimpleBufferAllocator allocator;
- std::string body(3, 'c');
- struct iovec iov = {const_cast<char*>(body.data()), body.length()};
- QuicMemSliceStorage storage(&iov, 1, &allocator, 1024);
- auto span = storage.ToSpan();
- EXPECT_EQ("ccc", span[0].AsStringView());
- EXPECT_NE(static_cast<const void*>(span[0].data()), body.data());
-}
-
-TEST_F(QuicMemSliceStorageImplTest, MultipleIovInSingleSlice) {
- SimpleBufferAllocator allocator;
- std::string body1(3, 'a');
- std::string body2(4, 'b');
- struct iovec iov[] = {{const_cast<char*>(body1.data()), body1.length()},
- {const_cast<char*>(body2.data()), body2.length()}};
-
- QuicMemSliceStorage storage(iov, 2, &allocator, 1024);
- auto span = storage.ToSpan();
- EXPECT_EQ("aaabbbb", span[0].AsStringView());
-}
-
-TEST_F(QuicMemSliceStorageImplTest, MultipleIovInMultipleSlice) {
- SimpleBufferAllocator allocator;
- std::string body1(4, 'a');
- std::string body2(4, 'b');
- struct iovec iov[] = {{const_cast<char*>(body1.data()), body1.length()},
- {const_cast<char*>(body2.data()), body2.length()}};
-
- QuicMemSliceStorage storage(iov, 2, &allocator, 4);
- auto span = storage.ToSpan();
- EXPECT_EQ("aaaa", span[0].AsStringView());
- EXPECT_EQ("bbbb", span[1].AsStringView());
-}
-
-} // namespace
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/platform/api/quic_mem_slice_test.cc b/chromium/net/third_party/quiche/src/quic/platform/api/quic_mem_slice_test.cc
deleted file mode 100644
index 44095dffa01..00000000000
--- a/chromium/net/third_party/quiche/src/quic/platform/api/quic_mem_slice_test.cc
+++ /dev/null
@@ -1,76 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/platform/api/quic_mem_slice.h"
-
-#include <memory>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_buffer_allocator.h"
-#include "quic/core/quic_simple_buffer_allocator.h"
-#include "quic/platform/api/quic_test.h"
-
-namespace quic {
-namespace test {
-namespace {
-
-class QuicMemSliceTest : public QuicTest {
- public:
- QuicMemSliceTest() {
- size_t length = 1024;
- slice_ = QuicMemSlice(MakeUniqueBuffer(&allocator_, length), length);
- orig_data_ = slice_.data();
- orig_length_ = slice_.length();
- }
-
- SimpleBufferAllocator allocator_;
- QuicMemSlice slice_;
- const char* orig_data_;
- size_t orig_length_;
-};
-
-TEST_F(QuicMemSliceTest, MoveConstruct) {
- QuicMemSlice moved(std::move(slice_));
- EXPECT_EQ(moved.data(), orig_data_);
- EXPECT_EQ(moved.length(), orig_length_);
- EXPECT_EQ(nullptr, slice_.data());
- EXPECT_EQ(0u, slice_.length());
- EXPECT_TRUE(slice_.empty());
-}
-
-TEST_F(QuicMemSliceTest, MoveAssign) {
- QuicMemSlice moved;
- moved = std::move(slice_);
- EXPECT_EQ(moved.data(), orig_data_);
- EXPECT_EQ(moved.length(), orig_length_);
- EXPECT_EQ(nullptr, slice_.data());
- EXPECT_EQ(0u, slice_.length());
- EXPECT_TRUE(slice_.empty());
-}
-
-TEST_F(QuicMemSliceTest, SliceAllocatedOnHeap) {
- auto buffer = std::make_unique<char[]>(128);
- char* orig_data = buffer.get();
- size_t used_length = 105;
- QuicMemSlice slice = QuicMemSlice(std::move(buffer), used_length);
- QuicMemSlice moved = std::move(slice);
- EXPECT_EQ(moved.data(), orig_data);
- EXPECT_EQ(moved.length(), used_length);
-}
-
-TEST_F(QuicMemSliceTest, SliceFromBuffer) {
- const absl::string_view kTestString =
- "RFC 9000 Release Celebration Memorial Test String";
- auto buffer = QuicBuffer::Copy(&allocator_, kTestString);
- QuicMemSlice slice(std::move(buffer));
-
- EXPECT_EQ(buffer.data(), nullptr); // NOLINT(bugprone-use-after-move)
- EXPECT_EQ(buffer.size(), 0u);
- EXPECT_EQ(slice.AsStringView(), kTestString);
- EXPECT_EQ(slice.length(), kTestString.length());
-}
-
-} // namespace
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/platform/api/quic_mock_log.h b/chromium/net/third_party/quiche/src/quic/platform/api/quic_mock_log.h
deleted file mode 100644
index d1c26931d68..00000000000
--- a/chromium/net/third_party/quiche/src/quic/platform/api/quic_mock_log.h
+++ /dev/null
@@ -1,18 +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 "net/quic/platform/impl/quic_mock_log_impl.h"
-
-using QuicMockLog = QuicMockLogImpl;
-#define CREATE_QUIC_MOCK_LOG(log) CREATE_QUIC_MOCK_LOG_IMPL(log)
-
-#define EXPECT_QUIC_LOG_CALL(log) EXPECT_QUIC_LOG_CALL_IMPL(log)
-
-#define EXPECT_QUIC_LOG_CALL_CONTAINS(log, level, content) \
- EXPECT_QUIC_LOG_CALL_CONTAINS_IMPL(log, level, content)
-
-#endif // QUICHE_QUIC_PLATFORM_API_QUIC_MOCK_LOG_H_
diff --git a/chromium/net/third_party/quiche/src/quic/platform/api/quic_mutex.cc b/chromium/net/third_party/quiche/src/quic/platform/api/quic_mutex.cc
deleted file mode 100644
index 401feb37f36..00000000000
--- a/chromium/net/third_party/quiche/src/quic/platform/api/quic_mutex.cc
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/platform/api/quic_mutex.h"
-
-namespace quic {
-
-void QuicMutex::WriterLock() {
- impl_.WriterLock();
-}
-
-void QuicMutex::WriterUnlock() {
- impl_.WriterUnlock();
-}
-
-void QuicMutex::ReaderLock() {
- impl_.ReaderLock();
-}
-
-void QuicMutex::ReaderUnlock() {
- impl_.ReaderUnlock();
-}
-
-void QuicMutex::AssertReaderHeld() const {
- impl_.AssertReaderHeld();
-}
-
-QuicReaderMutexLock::QuicReaderMutexLock(QuicMutex* lock) : lock_(lock) {
- lock->ReaderLock();
-}
-
-QuicReaderMutexLock::~QuicReaderMutexLock() {
- lock_->ReaderUnlock();
-}
-
-QuicWriterMutexLock::QuicWriterMutexLock(QuicMutex* lock) : lock_(lock) {
- lock->WriterLock();
-}
-
-QuicWriterMutexLock::~QuicWriterMutexLock() {
- lock_->WriterUnlock();
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/platform/api/quic_mutex.h b/chromium/net/third_party/quiche/src/quic/platform/api/quic_mutex.h
deleted file mode 100644
index 33f01e48fb2..00000000000
--- a/chromium/net/third_party/quiche/src/quic/platform/api/quic_mutex.h
+++ /dev/null
@@ -1,101 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_PLATFORM_API_QUIC_MUTEX_H_
-#define QUICHE_QUIC_PLATFORM_API_QUIC_MUTEX_H_
-
-// TODO(b/178613777): move into the common QUICHE platform.
-#include "quiche_platform_impl/quic_mutex_impl.h"
-
-#define QUIC_EXCLUSIVE_LOCKS_REQUIRED QUIC_EXCLUSIVE_LOCKS_REQUIRED_IMPL
-#define QUIC_GUARDED_BY QUIC_GUARDED_BY_IMPL
-#define QUIC_LOCKABLE QUIC_LOCKABLE_IMPL
-#define QUIC_LOCKS_EXCLUDED QUIC_LOCKS_EXCLUDED_IMPL
-#define QUIC_SHARED_LOCKS_REQUIRED QUIC_SHARED_LOCKS_REQUIRED_IMPL
-#define QUIC_EXCLUSIVE_LOCK_FUNCTION QUIC_EXCLUSIVE_LOCK_FUNCTION_IMPL
-#define QUIC_UNLOCK_FUNCTION QUIC_UNLOCK_FUNCTION_IMPL
-#define QUIC_SHARED_LOCK_FUNCTION QUIC_SHARED_LOCK_FUNCTION_IMPL
-#define QUIC_SCOPED_LOCKABLE QUIC_SCOPED_LOCKABLE_IMPL
-#define QUIC_ASSERT_SHARED_LOCK QUIC_ASSERT_SHARED_LOCK_IMPL
-
-namespace quic {
-
-// A class representing a non-reentrant mutex in QUIC.
-class QUIC_LOCKABLE QUIC_EXPORT_PRIVATE QuicMutex {
- public:
- QuicMutex() = default;
- QuicMutex(const QuicMutex&) = delete;
- QuicMutex& operator=(const QuicMutex&) = delete;
-
- // Block until this Mutex is free, then acquire it exclusively.
- void WriterLock() QUIC_EXCLUSIVE_LOCK_FUNCTION();
-
- // Release this Mutex. Caller must hold it exclusively.
- void WriterUnlock() QUIC_UNLOCK_FUNCTION();
-
- // Block until this Mutex is free or shared, then acquire a share of it.
- void ReaderLock() QUIC_SHARED_LOCK_FUNCTION();
-
- // Release this Mutex. Caller could hold it in shared mode.
- void ReaderUnlock() QUIC_UNLOCK_FUNCTION();
-
- // Returns immediately if current thread holds the Mutex in at least shared
- // mode. Otherwise, may report an error (typically by crashing with a
- // diagnostic), or may return immediately.
- void AssertReaderHeld() const QUIC_ASSERT_SHARED_LOCK();
-
- private:
- QuicLockImpl impl_;
-};
-
-// A helper class that acquires the given QuicMutex shared lock while the
-// QuicReaderMutexLock is in scope.
-class QUIC_SCOPED_LOCKABLE QUIC_EXPORT_PRIVATE QuicReaderMutexLock {
- public:
- explicit QuicReaderMutexLock(QuicMutex* lock) QUIC_SHARED_LOCK_FUNCTION(lock);
- QuicReaderMutexLock(const QuicReaderMutexLock&) = delete;
- QuicReaderMutexLock& operator=(const QuicReaderMutexLock&) = delete;
-
- ~QuicReaderMutexLock() QUIC_UNLOCK_FUNCTION();
-
- private:
- QuicMutex* const lock_;
-};
-
-// A helper class that acquires the given QuicMutex exclusive lock while the
-// QuicWriterMutexLock is in scope.
-class QUIC_SCOPED_LOCKABLE QUIC_EXPORT_PRIVATE QuicWriterMutexLock {
- public:
- explicit QuicWriterMutexLock(QuicMutex* lock)
- QUIC_EXCLUSIVE_LOCK_FUNCTION(lock);
- QuicWriterMutexLock(const QuicWriterMutexLock&) = delete;
- QuicWriterMutexLock& operator=(const QuicWriterMutexLock&) = delete;
-
- ~QuicWriterMutexLock() QUIC_UNLOCK_FUNCTION();
-
- private:
- QuicMutex* const lock_;
-};
-
-// A Notification allows threads to receive notification of a single occurrence
-// of a single event.
-class QUIC_EXPORT_PRIVATE QuicNotification {
- public:
- QuicNotification() = default;
- QuicNotification(const QuicNotification&) = delete;
- QuicNotification& operator=(const QuicNotification&) = delete;
-
- bool HasBeenNotified() { return impl_.HasBeenNotified(); }
-
- void Notify() { impl_.Notify(); }
-
- void WaitForNotification() { impl_.WaitForNotification(); }
-
- private:
- QuicNotificationImpl impl_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_PLATFORM_API_QUIC_MUTEX_H_
diff --git a/chromium/net/third_party/quiche/src/quic/platform/api/quic_port_utils.h b/chromium/net/third_party/quiche/src/quic/platform/api/quic_port_utils.h
deleted file mode 100644
index b1ddf6e069a..00000000000
--- a/chromium/net/third_party/quiche/src/quic/platform/api/quic_port_utils.h
+++ /dev/null
@@ -1,23 +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_PORT_UTILS_H_
-#define QUICHE_QUIC_PLATFORM_API_QUIC_PORT_UTILS_H_
-
-namespace quic {
-
-// Returns a UDP port that is currently unused. Check-fails if none are
-// available. May return 0 in which case the bind() call will cause the OS
-// to use an unused port.
-inline int QuicPickServerPortForTestsOrDie() {
- return 0;
-}
-
-// Indicates that a specified port previously returned by
-// QuicPickServerPortForTestsOrDie is no longer used.
-inline void QuicRecyclePort(int /*port*/) {}
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_PLATFORM_API_QUIC_PORT_UTILS_H_
diff --git a/chromium/net/third_party/quiche/src/quic/platform/api/quic_reference_counted.h b/chromium/net/third_party/quiche/src/quic/platform/api/quic_reference_counted.h
deleted file mode 100644
index 18f6f37f5ab..00000000000
--- a/chromium/net/third_party/quiche/src/quic/platform/api/quic_reference_counted.h
+++ /dev/null
@@ -1,162 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_PLATFORM_API_QUIC_REFERENCE_COUNTED_H_
-#define QUICHE_QUIC_PLATFORM_API_QUIC_REFERENCE_COUNTED_H_
-
-#include "net/quic/platform/impl/quic_reference_counted_impl.h"
-
-namespace quic {
-
-// Base class for explicitly reference-counted objects in QUIC.
-class QUIC_EXPORT_PRIVATE QuicReferenceCounted
- : public QuicReferenceCountedImpl {
- public:
- QuicReferenceCounted() {}
-
- protected:
- ~QuicReferenceCounted() override {}
-};
-
-// A class representing a reference counted pointer in QUIC.
-//
-// Construct or initialize QuicReferenceCountedPointer from raw pointer. Here
-// raw pointer MUST be a newly created object. Reference count of a newly
-// created object is undefined, but that will be 1 after being added to
-// QuicReferenceCountedPointer.
-// QuicReferenceCountedPointer is used as a local variable.
-// QuicReferenceCountedPointer<T> r_ptr(new T());
-// or, equivalently:
-// QuicReferenceCountedPointer<T> r_ptr;
-// T* p = new T();
-// r_ptr = T;
-//
-// QuicReferenceCountedPointer is used as a member variable:
-// MyClass::MyClass() : r_ptr(new T()) {}
-//
-// This is WRONG, since *p is not guaranteed to be newly created:
-// MyClass::MyClass(T* p) : r_ptr(p) {}
-//
-// Given an existing QuicReferenceCountedPointer, create a duplicate that has
-// its own reference on the object:
-// QuicReferenceCountedPointer<T> r_ptr_b(r_ptr_a);
-// or, equivalently:
-// QuicReferenceCountedPointer<T> r_ptr_b = r_ptr_a;
-//
-// Given an existing QuicReferenceCountedPointer, create a
-// QuicReferenceCountedPointer that adopts the reference:
-// QuicReferenceCountedPointer<T> r_ptr_b(std::move(r_ptr_a));
-// or, equivalently:
-// QuicReferenceCountedPointer<T> r_ptr_b = std::move(r_ptr_a);
-
-template <class T>
-class QUIC_NO_EXPORT QuicReferenceCountedPointer {
- public:
- QuicReferenceCountedPointer() = default;
-
- // Constructor from raw pointer |p|. This guarantees that the reference count
- // of *p is 1. This should be only called when a new object is created.
- // Calling this on an already existent object does not increase its reference
- // count.
- explicit QuicReferenceCountedPointer(T* p) : impl_(p) {}
-
- // Allows implicit conversion from nullptr.
- QuicReferenceCountedPointer(std::nullptr_t) : impl_(nullptr) {} // NOLINT
-
- // Copy and copy conversion constructors. It does not take the reference away
- // from |other| and they each end up with their own reference.
- template <typename U>
- QuicReferenceCountedPointer( // NOLINT
- const QuicReferenceCountedPointer<U>& other)
- : impl_(other.impl()) {}
- QuicReferenceCountedPointer(const QuicReferenceCountedPointer& other)
- : impl_(other.impl()) {}
-
- // Move constructors. After move, it adopts the reference from |other|.
- template <typename U>
- QuicReferenceCountedPointer(QuicReferenceCountedPointer<U>&& other) // NOLINT
- : impl_(std::move(other.impl())) {}
- QuicReferenceCountedPointer(QuicReferenceCountedPointer&& other)
- : impl_(std::move(other.impl())) {}
-
- ~QuicReferenceCountedPointer() = default;
-
- // Copy assignments.
- QuicReferenceCountedPointer& operator=(
- const QuicReferenceCountedPointer& other) {
- impl_ = other.impl();
- return *this;
- }
- template <typename U>
- QuicReferenceCountedPointer<T>& operator=(
- const QuicReferenceCountedPointer<U>& other) {
- impl_ = other.impl();
- return *this;
- }
-
- // Move assignments.
- QuicReferenceCountedPointer& operator=(QuicReferenceCountedPointer&& other) {
- impl_ = std::move(other.impl());
- return *this;
- }
- template <typename U>
- QuicReferenceCountedPointer<T>& operator=(
- QuicReferenceCountedPointer<U>&& other) {
- impl_ = std::move(other.impl());
- return *this;
- }
-
- // Accessors for the referenced object.
- // operator*() and operator->() will assert() if there is no current object.
- T& operator*() const { return *impl_; }
- T* operator->() const { return impl_.get(); }
-
- explicit operator bool() const { return static_cast<bool>(impl_); }
-
- // Assignment operator on raw pointer. Drops a reference to current pointee,
- // if any, and replaces it with |p|. This guarantees that the reference count
- // of *p is 1. This should only be used when a new object is created. Calling
- // this on an already existent object is undefined behavior.
- QuicReferenceCountedPointer<T>& operator=(T* p) {
- impl_ = p;
- return *this;
- }
-
- // Returns the raw pointer with no change in reference count.
- T* get() const { return impl_.get(); }
-
- QuicReferenceCountedPointerImpl<T>& impl() { return impl_; }
- const QuicReferenceCountedPointerImpl<T>& impl() const { return impl_; }
-
- // Comparisons against same type.
- friend bool operator==(const QuicReferenceCountedPointer& a,
- const QuicReferenceCountedPointer& b) {
- return a.get() == b.get();
- }
- friend bool operator!=(const QuicReferenceCountedPointer& a,
- const QuicReferenceCountedPointer& b) {
- return a.get() != b.get();
- }
-
- // Comparisons against nullptr.
- friend bool operator==(const QuicReferenceCountedPointer& a, std::nullptr_t) {
- return a.get() == nullptr;
- }
- friend bool operator==(std::nullptr_t, const QuicReferenceCountedPointer& b) {
- return nullptr == b.get();
- }
- friend bool operator!=(const QuicReferenceCountedPointer& a, std::nullptr_t) {
- return a.get() != nullptr;
- }
- friend bool operator!=(std::nullptr_t, const QuicReferenceCountedPointer& b) {
- return nullptr != b.get();
- }
-
- private:
- QuicReferenceCountedPointerImpl<T> impl_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_PLATFORM_API_QUIC_REFERENCE_COUNTED_H_
diff --git a/chromium/net/third_party/quiche/src/quic/platform/api/quic_reference_counted_test.cc b/chromium/net/third_party/quiche/src/quic/platform/api/quic_reference_counted_test.cc
deleted file mode 100644
index e2ea9816dee..00000000000
--- a/chromium/net/third_party/quiche/src/quic/platform/api/quic_reference_counted_test.cc
+++ /dev/null
@@ -1,173 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/platform/api/quic_reference_counted.h"
-
-#include "quic/platform/api/quic_test.h"
-
-namespace quic {
-namespace test {
-namespace {
-
-class Base : public QuicReferenceCounted {
- public:
- explicit Base(bool* destroyed) : destroyed_(destroyed) {
- *destroyed_ = false;
- }
-
- protected:
- ~Base() override { *destroyed_ = true; }
-
- private:
- bool* destroyed_;
-};
-
-class Derived : public Base {
- public:
- explicit Derived(bool* destroyed) : Base(destroyed) {}
-
- private:
- ~Derived() override {}
-};
-
-class QuicReferenceCountedTest : public QuicTest {};
-
-TEST_F(QuicReferenceCountedTest, DefaultConstructor) {
- QuicReferenceCountedPointer<Base> a;
- EXPECT_EQ(nullptr, a);
- EXPECT_EQ(nullptr, a.get());
- EXPECT_FALSE(a);
-}
-
-TEST_F(QuicReferenceCountedTest, ConstructFromRawPointer) {
- bool destroyed = false;
- {
- QuicReferenceCountedPointer<Base> a(new Base(&destroyed));
- EXPECT_FALSE(destroyed);
- }
- EXPECT_TRUE(destroyed);
-}
-
-TEST_F(QuicReferenceCountedTest, RawPointerAssignment) {
- bool destroyed = false;
- {
- QuicReferenceCountedPointer<Base> a;
- Base* rct = new Base(&destroyed);
- a = rct;
- EXPECT_FALSE(destroyed);
- }
- EXPECT_TRUE(destroyed);
-}
-
-TEST_F(QuicReferenceCountedTest, PointerCopy) {
- bool destroyed = false;
- {
- QuicReferenceCountedPointer<Base> a(new Base(&destroyed));
- {
- QuicReferenceCountedPointer<Base> b(a);
- EXPECT_EQ(a, b);
- EXPECT_FALSE(destroyed);
- }
- EXPECT_FALSE(destroyed);
- }
- EXPECT_TRUE(destroyed);
-}
-
-TEST_F(QuicReferenceCountedTest, PointerCopyAssignment) {
- bool destroyed = false;
- {
- QuicReferenceCountedPointer<Base> a(new Base(&destroyed));
- {
- QuicReferenceCountedPointer<Base> b = a;
- EXPECT_EQ(a, b);
- EXPECT_FALSE(destroyed);
- }
- EXPECT_FALSE(destroyed);
- }
- EXPECT_TRUE(destroyed);
-}
-
-TEST_F(QuicReferenceCountedTest, PointerCopyFromOtherType) {
- bool destroyed = false;
- {
- QuicReferenceCountedPointer<Derived> a(new Derived(&destroyed));
- {
- QuicReferenceCountedPointer<Base> b(a);
- EXPECT_EQ(a.get(), b.get());
- EXPECT_FALSE(destroyed);
- }
- EXPECT_FALSE(destroyed);
- }
- EXPECT_TRUE(destroyed);
-}
-
-TEST_F(QuicReferenceCountedTest, PointerCopyAssignmentFromOtherType) {
- bool destroyed = false;
- {
- QuicReferenceCountedPointer<Derived> a(new Derived(&destroyed));
- {
- QuicReferenceCountedPointer<Base> b = a;
- EXPECT_EQ(a.get(), b.get());
- EXPECT_FALSE(destroyed);
- }
- EXPECT_FALSE(destroyed);
- }
- EXPECT_TRUE(destroyed);
-}
-
-TEST_F(QuicReferenceCountedTest, PointerMove) {
- bool destroyed = false;
- QuicReferenceCountedPointer<Base> a(new Derived(&destroyed));
- EXPECT_FALSE(destroyed);
- QuicReferenceCountedPointer<Base> b(std::move(a));
- EXPECT_FALSE(destroyed);
- EXPECT_NE(nullptr, b);
- EXPECT_EQ(nullptr, a); // NOLINT
-
- b = nullptr;
- EXPECT_TRUE(destroyed);
-}
-
-TEST_F(QuicReferenceCountedTest, PointerMoveAssignment) {
- bool destroyed = false;
- QuicReferenceCountedPointer<Base> a(new Derived(&destroyed));
- EXPECT_FALSE(destroyed);
- QuicReferenceCountedPointer<Base> b = std::move(a);
- EXPECT_FALSE(destroyed);
- EXPECT_NE(nullptr, b);
- EXPECT_EQ(nullptr, a); // NOLINT
-
- b = nullptr;
- EXPECT_TRUE(destroyed);
-}
-
-TEST_F(QuicReferenceCountedTest, PointerMoveFromOtherType) {
- bool destroyed = false;
- QuicReferenceCountedPointer<Derived> a(new Derived(&destroyed));
- EXPECT_FALSE(destroyed);
- QuicReferenceCountedPointer<Base> b(std::move(a));
- EXPECT_FALSE(destroyed);
- EXPECT_NE(nullptr, b);
- EXPECT_EQ(nullptr, a); // NOLINT
-
- b = nullptr;
- EXPECT_TRUE(destroyed);
-}
-
-TEST_F(QuicReferenceCountedTest, PointerMoveAssignmentFromOtherType) {
- bool destroyed = false;
- QuicReferenceCountedPointer<Derived> a(new Derived(&destroyed));
- EXPECT_FALSE(destroyed);
- QuicReferenceCountedPointer<Base> b = std::move(a);
- EXPECT_FALSE(destroyed);
- EXPECT_NE(nullptr, b);
- EXPECT_EQ(nullptr, a); // NOLINT
-
- b = nullptr;
- EXPECT_TRUE(destroyed);
-}
-
-} // namespace
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/platform/api/quic_server_stats.h b/chromium/net/third_party/quiche/src/quic/platform/api/quic_server_stats.h
deleted file mode 100644
index 3c4223e4cf8..00000000000
--- a/chromium/net/third_party/quiche/src/quic/platform/api/quic_server_stats.h
+++ /dev/null
@@ -1,82 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_PLATFORM_API_QUIC_SERVER_STATS_H_
-#define QUICHE_QUIC_PLATFORM_API_QUIC_SERVER_STATS_H_
-
-#include "net/quic/platform/impl/quic_server_stats_impl.h"
-
-namespace quic {
-
-//------------------------------------------------------------------------------
-// Enumeration histograms.
-//
-// Sample usage:
-// // In Chrome, these values are persisted to logs. Entries should not be
-// // renumbered and numeric values should never be reused.
-// enum class MyEnum {
-// FIRST_VALUE = 0,
-// SECOND_VALUE = 1,
-// ...
-// FINAL_VALUE = N,
-// COUNT
-// };
-// QUIC_SERVER_HISTOGRAM_ENUM("My.Enumeration", MyEnum::SOME_VALUE,
-// MyEnum::COUNT, "Number of time $foo equals to some enum value");
-//
-// Note: The value in |sample| must be strictly less than |enum_size|.
-
-#define QUIC_SERVER_HISTOGRAM_ENUM(name, sample, enum_size, docstring) \
- QUIC_SERVER_HISTOGRAM_ENUM_IMPL(name, sample, enum_size, docstring)
-
-//------------------------------------------------------------------------------
-// Histogram for boolean values.
-
-// Sample usage:
-// QUIC_SERVER_HISTOGRAM_BOOL("My.Boolean", bool,
-// "Number of times $foo is true or false");
-#define QUIC_SERVER_HISTOGRAM_BOOL(name, sample, docstring) \
- QUIC_SERVER_HISTOGRAM_BOOL_IMPL(name, sample, docstring)
-
-//------------------------------------------------------------------------------
-// Timing histograms. These are used for collecting timing data (generally
-// latencies).
-
-// These macros create exponentially sized histograms (lengths of the bucket
-// ranges exponentially increase as the sample range increases). The units for
-// sample and max are unspecified, but they must be the same for one histogram.
-
-// Sample usage:
-// QUIC_SERVER_HISTOGRAM_TIMES("Very.Long.Timing.Histogram", time_delta,
-// QuicTime::Delta::FromSeconds(1), QuicTime::Delta::FromSecond(3600 *
-// 24), 100, "Time spent in doing operation.");
-#define QUIC_SERVER_HISTOGRAM_TIMES(name, sample, min, max, bucket_count, \
- docstring) \
- QUIC_SERVER_HISTOGRAM_TIMES_IMPL(name, sample, min, max, bucket_count, \
- docstring)
-
-//------------------------------------------------------------------------------
-// Count histograms. These are used for collecting numeric data.
-
-// These macros default to exponential histograms - i.e. the lengths of the
-// bucket ranges exponentially increase as the sample range increases.
-
-// All of these macros must be called with |name| as a runtime constant.
-
-// Any data outside the range here will be put in underflow and overflow
-// buckets. Min values should be >=1 as emitted 0s will still go into the
-// underflow bucket.
-
-// Sample usage:
-// QUIC_SERVER_SERVER_HISTOGRAM_CUSTOM_COUNTS("My.Histogram", 1, 100000000,
-// 100, "Counters of hitting certian code.");
-
-#define QUIC_SERVER_HISTOGRAM_COUNTS(name, sample, min, max, bucket_count, \
- docstring) \
- QUIC_SERVER_HISTOGRAM_COUNTS_IMPL(name, sample, min, max, bucket_count, \
- docstring)
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_PLATFORM_API_QUIC_SERVER_STATS_H_
diff --git a/chromium/net/third_party/quiche/src/quic/platform/api/quic_sleep.h b/chromium/net/third_party/quiche/src/quic/platform/api/quic_sleep.h
deleted file mode 100644
index 00253c3c6fc..00000000000
--- a/chromium/net/third_party/quiche/src/quic/platform/api/quic_sleep.h
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_PLATFORM_API_QUIC_SLEEP_H_
-#define QUICHE_QUIC_PLATFORM_API_QUIC_SLEEP_H_
-
-#include "quic/core/quic_time.h"
-// TODO(b/178613777): move into the common QUICHE platform.
-#include "quiche_platform_impl/quiche_sleep_impl.h"
-
-namespace quic {
-
-inline void QuicSleep(QuicTime::Delta duration) {
- QuicSleepImpl(duration);
-}
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_PLATFORM_API_QUIC_SLEEP_H_
diff --git a/chromium/net/third_party/quiche/src/quic/platform/api/quic_socket_address.cc b/chromium/net/third_party/quiche/src/quic/platform/api/quic_socket_address.cc
deleted file mode 100644
index f0b667cae53..00000000000
--- a/chromium/net/third_party/quiche/src/quic/platform/api/quic_socket_address.cc
+++ /dev/null
@@ -1,158 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/platform/api/quic_socket_address.h"
-
-#include <cstring>
-#include <limits>
-#include <string>
-
-#include "absl/strings/str_cat.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_ip_address.h"
-#include "quic/platform/api/quic_ip_address_family.h"
-
-namespace quic {
-
-namespace {
-
-uint32_t HashIP(const QuicIpAddress& ip) {
- if (ip.IsIPv4()) {
- return ip.GetIPv4().s_addr;
- }
- if (ip.IsIPv6()) {
- auto v6addr = ip.GetIPv6();
- const uint32_t* v6_as_ints =
- reinterpret_cast<const uint32_t*>(&v6addr.s6_addr);
- return v6_as_ints[0] ^ v6_as_ints[1] ^ v6_as_ints[2] ^ v6_as_ints[3];
- }
- return 0;
-}
-
-} // namespace
-
-QuicSocketAddress::QuicSocketAddress(QuicIpAddress address, uint16_t port)
- : host_(address), port_(port) {}
-
-QuicSocketAddress::QuicSocketAddress(const struct sockaddr_storage& saddr) {
- switch (saddr.ss_family) {
- case AF_INET: {
- const sockaddr_in* v4 = reinterpret_cast<const sockaddr_in*>(&saddr);
- host_ = QuicIpAddress(v4->sin_addr);
- port_ = ntohs(v4->sin_port);
- break;
- }
- case AF_INET6: {
- const sockaddr_in6* v6 = reinterpret_cast<const sockaddr_in6*>(&saddr);
- host_ = QuicIpAddress(v6->sin6_addr);
- port_ = ntohs(v6->sin6_port);
- break;
- }
- default:
- QUIC_BUG(quic_bug_10075_1)
- << "Unknown address family passed: " << saddr.ss_family;
- break;
- }
-}
-
-QuicSocketAddress::QuicSocketAddress(const sockaddr* saddr, socklen_t len) {
- sockaddr_storage storage;
- static_assert(std::numeric_limits<socklen_t>::max() >= sizeof(storage),
- "Cannot cast sizeof(storage) to socklen_t as it does not fit");
- if (len < static_cast<socklen_t>(sizeof(sockaddr)) ||
- (saddr->sa_family == AF_INET &&
- len < static_cast<socklen_t>(sizeof(sockaddr_in))) ||
- (saddr->sa_family == AF_INET6 &&
- len < static_cast<socklen_t>(sizeof(sockaddr_in6))) ||
- len > static_cast<socklen_t>(sizeof(storage))) {
- QUIC_BUG(quic_bug_10075_2) << "Socket address of invalid length provided";
- return;
- }
- memcpy(&storage, saddr, len);
- *this = QuicSocketAddress(storage);
-}
-
-bool operator==(const QuicSocketAddress& lhs, const QuicSocketAddress& rhs) {
- return lhs.host_ == rhs.host_ && lhs.port_ == rhs.port_;
-}
-
-bool operator!=(const QuicSocketAddress& lhs, const QuicSocketAddress& rhs) {
- return !(lhs == rhs);
-}
-
-bool QuicSocketAddress::IsInitialized() const {
- return host_.IsInitialized();
-}
-
-std::string QuicSocketAddress::ToString() const {
- switch (host_.address_family()) {
- case IpAddressFamily::IP_V4:
- return absl::StrCat(host_.ToString(), ":", port_);
- case IpAddressFamily::IP_V6:
- return absl::StrCat("[", host_.ToString(), "]:", port_);
- default:
- return "";
- }
-}
-
-int QuicSocketAddress::FromSocket(int fd) {
- sockaddr_storage addr;
- socklen_t addr_len = sizeof(addr);
- int result = getsockname(fd, reinterpret_cast<sockaddr*>(&addr), &addr_len);
-
- bool success = result == 0 && addr_len > 0 &&
- static_cast<size_t>(addr_len) <= sizeof(addr);
- if (success) {
- *this = QuicSocketAddress(addr);
- return 0;
- }
- return -1;
-}
-
-QuicSocketAddress QuicSocketAddress::Normalized() const {
- return QuicSocketAddress(host_.Normalized(), port_);
-}
-
-QuicIpAddress QuicSocketAddress::host() const {
- return host_;
-}
-
-uint16_t QuicSocketAddress::port() const {
- return port_;
-}
-
-sockaddr_storage QuicSocketAddress::generic_address() const {
- union {
- sockaddr_storage storage;
- sockaddr_in v4;
- sockaddr_in6 v6;
- } result;
- memset(&result.storage, 0, sizeof(result.storage));
-
- switch (host_.address_family()) {
- case IpAddressFamily::IP_V4:
- result.v4.sin_family = AF_INET;
- result.v4.sin_addr = host_.GetIPv4();
- result.v4.sin_port = htons(port_);
- break;
- case IpAddressFamily::IP_V6:
- result.v6.sin6_family = AF_INET6;
- result.v6.sin6_addr = host_.GetIPv6();
- result.v6.sin6_port = htons(port_);
- break;
- default:
- result.storage.ss_family = AF_UNSPEC;
- break;
- }
- return result.storage;
-}
-
-uint32_t QuicSocketAddress::Hash() const {
- uint32_t value = 0;
- value ^= HashIP(host_);
- value ^= port_ | (port_ << 16);
- return value;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/platform/api/quic_socket_address.h b/chromium/net/third_party/quiche/src/quic/platform/api/quic_socket_address.h
deleted file mode 100644
index df6b9b7cf83..00000000000
--- a/chromium/net/third_party/quiche/src/quic/platform/api/quic_socket_address.h
+++ /dev/null
@@ -1,63 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_PLATFORM_API_QUIC_SOCKET_ADDRESS_H_
-#define QUICHE_QUIC_PLATFORM_API_QUIC_SOCKET_ADDRESS_H_
-
-#include <string>
-
-#include "quic/platform/api/quic_export.h"
-#include "quic/platform/api/quic_ip_address.h"
-
-namespace quic {
-
-// A class representing a socket endpoint address (i.e., IP address plus a
-// port) in QUIC.
-class QUIC_EXPORT_PRIVATE QuicSocketAddress {
- public:
- QuicSocketAddress() {}
- QuicSocketAddress(QuicIpAddress address, uint16_t port);
- explicit QuicSocketAddress(const struct sockaddr_storage& saddr);
- explicit QuicSocketAddress(const sockaddr* saddr, socklen_t len);
- QuicSocketAddress(const QuicSocketAddress& other) = default;
- QuicSocketAddress& operator=(const QuicSocketAddress& other) = default;
- QuicSocketAddress& operator=(QuicSocketAddress&& other) = default;
- QUIC_EXPORT_PRIVATE friend bool operator==(const QuicSocketAddress& lhs,
- const QuicSocketAddress& rhs);
- QUIC_EXPORT_PRIVATE friend bool operator!=(const QuicSocketAddress& lhs,
- const QuicSocketAddress& rhs);
-
- bool IsInitialized() const;
- std::string ToString() const;
- int FromSocket(int fd);
- QuicSocketAddress Normalized() const;
-
- QuicIpAddress host() const;
- uint16_t port() const;
- sockaddr_storage generic_address() const;
-
- // Hashes this address to an uint32_t.
- uint32_t Hash() const;
-
- private:
- QuicIpAddress host_;
- uint16_t port_ = 0;
-};
-
-inline std::ostream& operator<<(std::ostream& os,
- const QuicSocketAddress address) {
- os << address.ToString();
- return os;
-}
-
-class QUIC_EXPORT_PRIVATE QuicSocketAddressHash {
- public:
- size_t operator()(QuicSocketAddress const& address) const noexcept {
- return address.Hash();
- }
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_PLATFORM_API_QUIC_SOCKET_ADDRESS_H_
diff --git a/chromium/net/third_party/quiche/src/quic/platform/api/quic_socket_address_test.cc b/chromium/net/third_party/quiche/src/quic/platform/api/quic_socket_address_test.cc
deleted file mode 100644
index 2282a8a5158..00000000000
--- a/chromium/net/third_party/quiche/src/quic/platform/api/quic_socket_address_test.cc
+++ /dev/null
@@ -1,133 +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 "quic/platform/api/quic_socket_address.h"
-
-#include <memory>
-#include <sstream>
-
-#include "quic/platform/api/quic_test.h"
-
-namespace quic {
-namespace {
-
-TEST(QuicSocketAddress, Uninitialized) {
- QuicSocketAddress uninitialized;
- EXPECT_FALSE(uninitialized.IsInitialized());
-}
-
-TEST(QuicSocketAddress, ExplicitConstruction) {
- QuicSocketAddress ipv4_address(QuicIpAddress::Loopback4(), 443);
- QuicSocketAddress ipv6_address(QuicIpAddress::Loopback6(), 443);
- EXPECT_TRUE(ipv4_address.IsInitialized());
- EXPECT_EQ("127.0.0.1:443", ipv4_address.ToString());
- EXPECT_EQ("[::1]:443", ipv6_address.ToString());
- EXPECT_EQ(QuicIpAddress::Loopback4(), ipv4_address.host());
- EXPECT_EQ(QuicIpAddress::Loopback6(), ipv6_address.host());
- EXPECT_EQ(443, ipv4_address.port());
-}
-
-TEST(QuicSocketAddress, OutputToStream) {
- QuicSocketAddress ipv4_address(QuicIpAddress::Loopback4(), 443);
- std::stringstream stream;
- stream << ipv4_address;
- EXPECT_EQ("127.0.0.1:443", stream.str());
-}
-
-TEST(QuicSocketAddress, FromSockaddrIPv4) {
- union {
- sockaddr_storage storage;
- sockaddr addr;
- sockaddr_in v4;
- } address;
-
- memset(&address, 0, sizeof(address));
- address.v4.sin_family = AF_INET;
- address.v4.sin_addr = QuicIpAddress::Loopback4().GetIPv4();
- address.v4.sin_port = htons(443);
- EXPECT_EQ("127.0.0.1:443",
- QuicSocketAddress(&address.addr, sizeof(address.v4)).ToString());
- EXPECT_EQ("127.0.0.1:443", QuicSocketAddress(address.storage).ToString());
-}
-
-TEST(QuicSocketAddress, FromSockaddrIPv6) {
- union {
- sockaddr_storage storage;
- sockaddr addr;
- sockaddr_in6 v6;
- } address;
-
- memset(&address, 0, sizeof(address));
- address.v6.sin6_family = AF_INET6;
- address.v6.sin6_addr = QuicIpAddress::Loopback6().GetIPv6();
- address.v6.sin6_port = htons(443);
- EXPECT_EQ("[::1]:443",
- QuicSocketAddress(&address.addr, sizeof(address.v6)).ToString());
- EXPECT_EQ("[::1]:443", QuicSocketAddress(address.storage).ToString());
-}
-
-TEST(QuicSocketAddres, ToSockaddrIPv4) {
- union {
- sockaddr_storage storage;
- sockaddr_in v4;
- } address;
-
- address.storage =
- QuicSocketAddress(QuicIpAddress::Loopback4(), 443).generic_address();
- ASSERT_EQ(AF_INET, address.v4.sin_family);
- EXPECT_EQ(QuicIpAddress::Loopback4(), QuicIpAddress(address.v4.sin_addr));
- EXPECT_EQ(htons(443), address.v4.sin_port);
-}
-
-TEST(QuicSocketAddress, Normalize) {
- QuicIpAddress dual_stacked;
- ASSERT_TRUE(dual_stacked.FromString("::ffff:127.0.0.1"));
- ASSERT_TRUE(dual_stacked.IsIPv6());
- QuicSocketAddress not_normalized(dual_stacked, 443);
- QuicSocketAddress normalized = not_normalized.Normalized();
- EXPECT_EQ("[::ffff:127.0.0.1]:443", not_normalized.ToString());
- EXPECT_EQ("127.0.0.1:443", normalized.ToString());
-}
-
-// TODO(vasilvv): either ensure this works on all platforms, or deprecate and
-// remove this API.
-#if defined(__linux__) && !defined(ANDROID)
-#include <errno.h>
-#include <sys/socket.h>
-#include <sys/types.h>
-
-TEST(QuicSocketAddress, FromSocket) {
- int fd;
- QuicSocketAddress address;
- bool bound = false;
- for (int port = 50000; port < 50400; port++) {
- fd = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
- ASSERT_GT(fd, 0);
-
- address = QuicSocketAddress(QuicIpAddress::Loopback6(), port);
- sockaddr_storage raw_address = address.generic_address();
- int bind_result = bind(fd, reinterpret_cast<const sockaddr*>(&raw_address),
- sizeof(sockaddr_in6));
-
- if (bind_result < 0 && errno == EADDRINUSE) {
- close(fd);
- continue;
- }
-
- ASSERT_EQ(0, bind_result);
- bound = true;
- break;
- }
- ASSERT_TRUE(bound);
-
- QuicSocketAddress real_address;
- ASSERT_EQ(0, real_address.FromSocket(fd));
- ASSERT_TRUE(real_address.IsInitialized());
- EXPECT_EQ(real_address, address);
- close(fd);
-}
-#endif
-
-} // namespace
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/platform/api/quic_stack_trace.h b/chromium/net/third_party/quiche/src/quic/platform/api/quic_stack_trace.h
deleted file mode 100644
index ff6c887de6b..00000000000
--- a/chromium/net/third_party/quiche/src/quic/platform/api/quic_stack_trace.h
+++ /dev/null
@@ -1,20 +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_STACK_TRACE_H_
-#define QUICHE_QUIC_PLATFORM_API_QUIC_STACK_TRACE_H_
-
-#include <string>
-
-#include "net/quic/platform/impl/quic_stack_trace_impl.h"
-
-namespace quic {
-
-inline std::string QuicStackTrace() {
- return QuicStackTraceImpl();
-}
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_PLATFORM_API_QUIC_STACK_TRACE_H_
diff --git a/chromium/net/third_party/quiche/src/quic/platform/api/quic_stream_buffer_allocator.h b/chromium/net/third_party/quiche/src/quic/platform/api/quic_stream_buffer_allocator.h
deleted file mode 100644
index ea1cc9fd5ec..00000000000
--- a/chromium/net/third_party/quiche/src/quic/platform/api/quic_stream_buffer_allocator.h
+++ /dev/null
@@ -1,16 +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 "net/quic/platform/impl/quic_stream_buffer_allocator_impl.h"
-
-namespace quic {
-
-using QuicStreamBufferAllocator = QuicStreamBufferAllocatorImpl;
-
-}
-
-#endif // QUICHE_QUIC_PLATFORM_API_QUIC_STREAM_BUFFER_ALLOCATOR_H_
diff --git a/chromium/net/third_party/quiche/src/quic/platform/api/quic_system_event_loop.h b/chromium/net/third_party/quiche/src/quic/platform/api/quic_system_event_loop.h
deleted file mode 100644
index 3103d4e0e8c..00000000000
--- a/chromium/net/third_party/quiche/src/quic/platform/api/quic_system_event_loop.h
+++ /dev/null
@@ -1,16 +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_SYSTEM_EVENT_LOOP_H_
-#define QUICHE_QUIC_PLATFORM_API_QUIC_SYSTEM_EVENT_LOOP_H_
-
-#include "net/quic/platform/impl/quic_system_event_loop_impl.h"
-
-inline void QuicRunSystemEventLoopIteration() {
- QuicRunSystemEventLoopIterationImpl();
-}
-
-using QuicSystemEventLoop = QuicSystemEventLoopImpl;
-
-#endif // QUICHE_QUIC_PLATFORM_API_QUIC_SYSTEM_EVENT_LOOP_H_
diff --git a/chromium/net/third_party/quiche/src/quic/platform/api/quic_test.h b/chromium/net/third_party/quiche/src/quic/platform/api/quic_test.h
deleted file mode 100644
index 644c25501b5..00000000000
--- a/chromium/net/third_party/quiche/src/quic/platform/api/quic_test.h
+++ /dev/null
@@ -1,31 +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_TEST_H_
-#define QUICHE_QUIC_PLATFORM_API_QUIC_TEST_H_
-
-#include "quic/platform/api/quic_logging.h"
-#include "net/quic/platform/impl/quic_test_impl.h"
-#include "common/platform/api/quiche_test.h"
-
-using QuicFlagSaver = QuicFlagSaverImpl;
-
-// Defines the base classes to be used in QUIC tests.
-using QuicTest = QuicTestImpl;
-template <class T>
-using QuicTestWithParam = QuicTestWithParamImpl<T>;
-
-// Class which needs to be instantiated in tests which use threads.
-using ScopedEnvironmentForThreads = ScopedEnvironmentForThreadsImpl;
-
-#define QUIC_TEST_DISABLED_IN_CHROME(name) \
- QUIC_TEST_DISABLED_IN_CHROME_IMPL(name)
-
-inline std::string QuicGetTestMemoryCachePath() {
- return QuicGetTestMemoryCachePathImpl();
-}
-
-#define QUIC_SLOW_TEST(test) QUIC_SLOW_TEST_IMPL(test)
-
-#endif // QUICHE_QUIC_PLATFORM_API_QUIC_TEST_H_
diff --git a/chromium/net/third_party/quiche/src/quic/platform/api/quic_test_loopback.cc b/chromium/net/third_party/quiche/src/quic/platform/api/quic_test_loopback.cc
deleted file mode 100644
index 070a68fa436..00000000000
--- a/chromium/net/third_party/quiche/src/quic/platform/api/quic_test_loopback.cc
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright (c) 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/platform/api/quic_test_loopback.h"
-
-namespace quic {
-
-IpAddressFamily AddressFamilyUnderTest() {
- return AddressFamilyUnderTestImpl();
-}
-
-QuicIpAddress TestLoopback4() {
- return TestLoopback4Impl();
-}
-
-QuicIpAddress TestLoopback6() {
- return TestLoopback6Impl();
-}
-
-QuicIpAddress TestLoopback() {
- return TestLoopbackImpl();
-}
-
-QuicIpAddress TestLoopback(int index) {
- return TestLoopbackImpl(index);
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/platform/api/quic_test_loopback.h b/chromium/net/third_party/quiche/src/quic/platform/api/quic_test_loopback.h
deleted file mode 100644
index 708e766c1e6..00000000000
--- a/chromium/net/third_party/quiche/src/quic/platform/api/quic_test_loopback.h
+++ /dev/null
@@ -1,32 +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_TEST_LOOPBACK_H_
-#define QUICHE_QUIC_PLATFORM_API_QUIC_TEST_LOOPBACK_H_
-
-#include "net/quic/platform/impl/quic_test_loopback_impl.h"
-
-namespace quic {
-
-// Returns the address family (IPv4 or IPv6) used to run test under.
-IpAddressFamily AddressFamilyUnderTest();
-
-// Returns an IPv4 loopback address.
-QuicIpAddress TestLoopback4();
-
-// Returns the only IPv6 loopback address.
-QuicIpAddress TestLoopback6();
-
-// Returns an appropriate IPv4/Ipv6 loopback address based upon whether the
-// test's environment.
-QuicIpAddress TestLoopback();
-
-// If address family under test is IPv4, returns an indexed IPv4 loopback
-// address. If address family under test is IPv6, the address returned is
-// platform-dependent.
-QuicIpAddress TestLoopback(int index);
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_PLATFORM_API_QUIC_TEST_LOOPBACK_H_
diff --git a/chromium/net/third_party/quiche/src/quic/platform/api/quic_test_output.h b/chromium/net/third_party/quiche/src/quic/platform/api/quic_test_output.h
deleted file mode 100644
index f925db65985..00000000000
--- a/chromium/net/third_party/quiche/src/quic/platform/api/quic_test_output.h
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_PLATFORM_API_QUIC_TEST_OUTPUT_H_
-#define QUICHE_QUIC_PLATFORM_API_QUIC_TEST_OUTPUT_H_
-
-#include "absl/strings/string_view.h"
-#include "net/quic/platform/impl/quic_test_output_impl.h"
-
-namespace quic {
-
-// Save |data| into ${QUIC_TEST_OUTPUT_DIR}/filename. If a file with the same
-// path already exists, overwrite it.
-inline void QuicSaveTestOutput(absl::string_view filename,
- absl::string_view data) {
- QuicSaveTestOutputImpl(filename, data);
-}
-
-// Load the content of ${QUIC_TEST_OUTPUT_DIR}/filename into |*data|.
-// Return whether it is successfully loaded.
-inline bool QuicLoadTestOutput(absl::string_view filename, std::string* data) {
- return QuicLoadTestOutputImpl(filename, data);
-}
-
-// Records a QUIC trace file(.qtr) into a directory specified by the
-// QUIC_TEST_OUTPUT_DIR environment variable. Assumes that it's called from a
-// unit test.
-//
-// The |identifier| is a human-readable identifier that will be combined with
-// the name of the unit test and a timestamp. |data| is the serialized
-// quic_trace.Trace protobuf that is being recorded into the file.
-inline void QuicRecordTrace(absl::string_view identifier,
- absl::string_view data) {
- QuicRecordTraceImpl(identifier, data);
-}
-
-} // namespace quic
-#endif // QUICHE_QUIC_PLATFORM_API_QUIC_TEST_OUTPUT_H_
diff --git a/chromium/net/third_party/quiche/src/quic/platform/api/quic_testvalue.h b/chromium/net/third_party/quiche/src/quic/platform/api/quic_testvalue.h
deleted file mode 100644
index 58bc4f4544c..00000000000
--- a/chromium/net/third_party/quiche/src/quic/platform/api/quic_testvalue.h
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_PLATFORM_API_QUIC_TESTVALUE_H_
-#define QUICHE_QUIC_PLATFORM_API_QUIC_TESTVALUE_H_
-
-#include "absl/strings/string_view.h"
-
-// TODO(b/178613777): move into the common QUICHE platform.
-#include "quiche_platform_impl/quic_testvalue_impl.h"
-
-namespace quic {
-
-// Interface allowing injection of test-specific code in production codepaths.
-// |label| is an arbitrary value identifying the location, and |var| is a
-// pointer to the value to be modified.
-//
-// Note that this method does nothing in Chromium.
-template <class T>
-void AdjustTestValue(absl::string_view label, T* var) {
- AdjustTestValueImpl(label, var);
-}
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_PLATFORM_API_QUIC_TESTVALUE_H_
diff --git a/chromium/net/third_party/quiche/src/quic/platform/api/quic_thread.h b/chromium/net/third_party/quiche/src/quic/platform/api/quic_thread.h
deleted file mode 100644
index e18263284c0..00000000000
--- a/chromium/net/third_party/quiche/src/quic/platform/api/quic_thread.h
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_PLATFORM_API_QUIC_THREAD_H_
-#define QUICHE_QUIC_PLATFORM_API_QUIC_THREAD_H_
-
-#include <string>
-
-#include "quic/platform/api/quic_export.h"
-#include "net/quic/platform/impl/quic_thread_impl.h"
-
-namespace quic {
-
-// A class representing a thread of execution in QUIC.
-class QUIC_EXPORT_PRIVATE QuicThread : public QuicThreadImpl {
- public:
- QuicThread(const std::string& string) : QuicThreadImpl(string) {}
- QuicThread(const QuicThread&) = delete;
- QuicThread& operator=(const QuicThread&) = delete;
-
- // Impl defines a virtual void Run() method which subclasses
- // must implement.
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_PLATFORM_API_QUIC_THREAD_H_
diff --git a/chromium/net/third_party/quiche/src/quic/platform/api/quic_udp_socket_platform_api.h b/chromium/net/third_party/quiche/src/quic/platform/api/quic_udp_socket_platform_api.h
deleted file mode 100644
index 10307efc298..00000000000
--- a/chromium/net/third_party/quiche/src/quic/platform/api/quic_udp_socket_platform_api.h
+++ /dev/null
@@ -1,29 +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_PLATFORM_API_QUIC_UDP_SOCKET_PLATFORM_API_H_
-#define QUICHE_QUIC_PLATFORM_API_QUIC_UDP_SOCKET_PLATFORM_API_H_
-
-#include "net/quic/platform/impl/quic_udp_socket_platform_impl.h"
-
-namespace quic {
-
-const size_t kCmsgSpaceForGooglePacketHeader =
- kCmsgSpaceForGooglePacketHeaderImpl;
-
-inline bool GetGooglePacketHeadersFromControlMessage(
- struct ::cmsghdr* cmsg,
- char** packet_headers,
- size_t* packet_headers_len) {
- return GetGooglePacketHeadersFromControlMessageImpl(cmsg, packet_headers,
- packet_headers_len);
-}
-
-inline void SetGoogleSocketOptions(int fd) {
- SetGoogleSocketOptionsImpl(fd);
-}
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_PLATFORM_API_QUIC_UDP_SOCKET_PLATFORM_API_H_
diff --git a/chromium/net/third_party/quiche/src/quic/qbone/bonnet/icmp_reachable.cc b/chromium/net/third_party/quiche/src/quic/qbone/bonnet/icmp_reachable.cc
deleted file mode 100644
index 8e39996284e..00000000000
--- a/chromium/net/third_party/quiche/src/quic/qbone/bonnet/icmp_reachable.cc
+++ /dev/null
@@ -1,212 +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 "quic/qbone/bonnet/icmp_reachable.h"
-
-#include <netinet/ip6.h>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/crypto/quic_random.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/platform/api/quic_mutex.h"
-#include "quic/qbone/platform/icmp_packet.h"
-#include "common/quiche_endian.h"
-#include "common/quiche_text_utils.h"
-
-namespace quic {
-namespace {
-
-constexpr int kEpollFlags = EPOLLIN | EPOLLET;
-constexpr size_t kMtu = 1280;
-
-constexpr size_t kIPv6AddrSize = sizeof(in6_addr);
-
-} // namespace
-
-const char kUnknownSource[] = "UNKNOWN";
-const char kNoSource[] = "N/A";
-
-IcmpReachable::IcmpReachable(QuicIpAddress source,
- QuicIpAddress destination,
- absl::Duration timeout,
- KernelInterface* kernel,
- QuicEpollServer* epoll_server,
- StatsInterface* stats)
- : timeout_(timeout),
- cb_(this),
- kernel_(kernel),
- epoll_server_(epoll_server),
- stats_(stats),
- send_fd_(0),
- recv_fd_(0) {
- src_.sin6_family = AF_INET6;
- dst_.sin6_family = AF_INET6;
-
- memcpy(&src_.sin6_addr, source.ToPackedString().data(), kIPv6AddrSize);
- memcpy(&dst_.sin6_addr, destination.ToPackedString().data(), kIPv6AddrSize);
-}
-
-IcmpReachable::~IcmpReachable() {
- if (send_fd_ > 0) {
- kernel_->close(send_fd_);
- }
- if (recv_fd_ > 0) {
- if (!epoll_server_->ShutdownCalled()) {
- epoll_server_->UnregisterFD(recv_fd_);
- }
-
- kernel_->close(recv_fd_);
- }
-}
-
-bool IcmpReachable::Init() {
- send_fd_ = kernel_->socket(PF_INET6, SOCK_RAW | SOCK_NONBLOCK, IPPROTO_RAW);
- if (send_fd_ < 0) {
- QUIC_LOG(ERROR) << "Unable to open socket: " << errno;
- return false;
- }
-
- if (kernel_->bind(send_fd_, reinterpret_cast<struct sockaddr*>(&src_),
- sizeof(sockaddr_in6)) < 0) {
- QUIC_LOG(ERROR) << "Unable to bind socket: " << errno;
- return false;
- }
-
- recv_fd_ =
- kernel_->socket(PF_INET6, SOCK_RAW | SOCK_NONBLOCK, IPPROTO_ICMPV6);
- if (recv_fd_ < 0) {
- QUIC_LOG(ERROR) << "Unable to open socket: " << errno;
- return false;
- }
-
- if (kernel_->bind(recv_fd_, reinterpret_cast<struct sockaddr*>(&src_),
- sizeof(sockaddr_in6)) < 0) {
- QUIC_LOG(ERROR) << "Unable to bind socket: " << errno;
- return false;
- }
-
- icmp6_filter filter;
- ICMP6_FILTER_SETBLOCKALL(&filter);
- ICMP6_FILTER_SETPASS(ICMP6_ECHO_REPLY, &filter);
- if (kernel_->setsockopt(recv_fd_, SOL_ICMPV6, ICMP6_FILTER, &filter,
- sizeof(filter)) < 0) {
- QUIC_LOG(ERROR) << "Unable to set ICMP6 filter.";
- return false;
- }
-
- epoll_server_->RegisterFD(recv_fd_, &cb_, kEpollFlags);
- epoll_server_->RegisterAlarm(0, this);
-
- QuicWriterMutexLock mu(&header_lock_);
- icmp_header_.icmp6_type = ICMP6_ECHO_REQUEST;
- icmp_header_.icmp6_code = 0;
-
- QuicRandom::GetInstance()->RandBytes(&icmp_header_.icmp6_id,
- sizeof(uint16_t));
-
- return true;
-}
-
-bool IcmpReachable::OnEvent(int fd) {
- char buffer[kMtu];
-
- sockaddr_in6 source_addr{};
- socklen_t source_addr_len = sizeof(source_addr);
-
- ssize_t size = kernel_->recvfrom(fd, &buffer, kMtu, 0,
- reinterpret_cast<sockaddr*>(&source_addr),
- &source_addr_len);
-
- if (size < 0) {
- if (errno != EAGAIN && errno != EWOULDBLOCK) {
- stats_->OnReadError(errno);
- }
- return false;
- }
-
- QUIC_VLOG(2) << quiche::QuicheTextUtils::HexDump(
- absl::string_view(buffer, size));
-
- auto* header = reinterpret_cast<const icmp6_hdr*>(&buffer);
- QuicWriterMutexLock mu(&header_lock_);
- if (header->icmp6_data32[0] != icmp_header_.icmp6_data32[0]) {
- QUIC_VLOG(2) << "Unexpected response. id: " << header->icmp6_id
- << " seq: " << header->icmp6_seq
- << " Expected id: " << icmp_header_.icmp6_id
- << " seq: " << icmp_header_.icmp6_seq;
- return true;
- }
- end_ = absl::Now();
- QUIC_VLOG(1) << "Received ping response in "
- << absl::ToInt64Microseconds(end_ - start_) << "us.";
-
- std::string source;
- QuicIpAddress source_ip;
- if (!source_ip.FromPackedString(
- reinterpret_cast<char*>(&source_addr.sin6_addr), sizeof(in6_addr))) {
- QUIC_LOG(WARNING) << "Unable to parse source address.";
- source = kUnknownSource;
- } else {
- source = source_ip.ToString();
- }
- stats_->OnEvent({Status::REACHABLE, end_ - start_, source});
- return true;
-}
-
-int64 /* allow-non-std-int */ IcmpReachable::OnAlarm() {
- EpollAlarm::OnAlarm();
-
- QuicWriterMutexLock mu(&header_lock_);
-
- if (end_ < start_) {
- QUIC_VLOG(1) << "Timed out on sequence: " << icmp_header_.icmp6_seq;
- stats_->OnEvent({Status::UNREACHABLE, absl::ZeroDuration(), kNoSource});
- }
-
- icmp_header_.icmp6_seq++;
- CreateIcmpPacket(src_.sin6_addr, dst_.sin6_addr, icmp_header_, "",
- [this](absl::string_view packet) {
- QUIC_VLOG(2) << quiche::QuicheTextUtils::HexDump(packet);
-
- ssize_t size = kernel_->sendto(
- send_fd_, packet.data(), packet.size(), 0,
- reinterpret_cast<struct sockaddr*>(&dst_),
- sizeof(sockaddr_in6));
-
- if (size < packet.size()) {
- stats_->OnWriteError(errno);
- }
- start_ = absl::Now();
- });
-
- return absl::ToUnixMicros(absl::Now() + timeout_);
-}
-
-absl::string_view IcmpReachable::StatusName(IcmpReachable::Status status) {
- switch (status) {
- case REACHABLE:
- return "REACHABLE";
- case UNREACHABLE:
- return "UNREACHABLE";
- default:
- return "UNKNOWN";
- }
-}
-
-void IcmpReachable::EpollCallback::OnEvent(int fd, QuicEpollEvent* event) {
- bool can_read_more = reachable_->OnEvent(fd);
- if (can_read_more) {
- event->out_ready_mask |= EPOLLIN;
- }
-}
-
-void IcmpReachable::EpollCallback::OnShutdown(QuicEpollServer* eps, int fd) {
- eps->UnregisterFD(fd);
-}
-
-std::string IcmpReachable::EpollCallback::Name() const {
- return "ICMP Reachable";
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/qbone/bonnet/icmp_reachable.h b/chromium/net/third_party/quiche/src/quic/qbone/bonnet/icmp_reachable.h
deleted file mode 100644
index 7faf873f87a..00000000000
--- a/chromium/net/third_party/quiche/src/quic/qbone/bonnet/icmp_reachable.h
+++ /dev/null
@@ -1,140 +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_QBONE_BONNET_ICMP_REACHABLE_H_
-#define QUICHE_QUIC_QBONE_BONNET_ICMP_REACHABLE_H_
-
-#include <netinet/icmp6.h>
-
-#include "absl/strings/string_view.h"
-#include "quic/platform/api/quic_ip_address.h"
-#include "quic/platform/api/quic_mutex.h"
-#include "quic/qbone/bonnet/icmp_reachable_interface.h"
-#include "quic/qbone/platform/kernel_interface.h"
-
-namespace quic {
-
-extern const char kUnknownSource[];
-extern const char kNoSource[];
-
-// IcmpReachable schedules itself with an EpollServer, periodically sending
-// ICMPv6 Echo Requests to the given |destination| on the interface that the
-// given |source| is bound to. Echo Requests are sent once every |timeout|.
-// On Echo Replies, timeouts, and I/O errors, the given |stats| object will
-// be called back with details of the event.
-class IcmpReachable : public IcmpReachableInterface {
- public:
- enum Status { REACHABLE, UNREACHABLE };
-
- struct ReachableEvent {
- Status status;
- absl::Duration response_time;
- std::string source;
- };
-
- class StatsInterface {
- public:
- StatsInterface() = default;
-
- StatsInterface(const StatsInterface&) = delete;
- StatsInterface& operator=(const StatsInterface&) = delete;
-
- StatsInterface(StatsInterface&&) = delete;
- StatsInterface& operator=(StatsInterface&&) = delete;
-
- virtual ~StatsInterface() = default;
-
- virtual void OnEvent(ReachableEvent event) = 0;
-
- virtual void OnReadError(int error) = 0;
-
- virtual void OnWriteError(int error) = 0;
- };
-
- // |source| is the IPv6 address bound to the interface that IcmpReachable will
- // send Echo Requests on.
- // |destination| is the IPv6 address of the destination of the Echo Requests.
- // |timeout| is the duration IcmpReachable will wait between Echo Requests.
- // If no Echo Response is received by the next Echo Request, it will
- // be considered a timeout.
- // |kernel| is not owned, but should outlive this instance.
- // |epoll_server| is not owned, but should outlive this instance.
- // IcmpReachable's Init() must be called from within the Epoll
- // Server's thread.
- // |stats| is not owned, but should outlive this instance. It will be called
- // back on Echo Replies, timeouts, and I/O errors.
- IcmpReachable(QuicIpAddress source,
- QuicIpAddress destination,
- absl::Duration timeout,
- KernelInterface* kernel,
- QuicEpollServer* epoll_server,
- StatsInterface* stats);
-
- ~IcmpReachable() override;
-
- // Initializes this reachability probe. Must be called from within the
- // |epoll_server|'s thread.
- bool Init() QUIC_LOCKS_EXCLUDED(header_lock_) override;
-
- int64 /* allow-non-std-int */ OnAlarm()
- QUIC_LOCKS_EXCLUDED(header_lock_) override;
-
- static absl::string_view StatusName(Status status);
-
- private:
- class EpollCallback : public QuicEpollCallbackInterface {
- public:
- explicit EpollCallback(IcmpReachable* reachable) : reachable_(reachable) {}
-
- EpollCallback(const EpollCallback&) = delete;
- EpollCallback& operator=(const EpollCallback&) = delete;
-
- EpollCallback(EpollCallback&&) = delete;
- EpollCallback& operator=(EpollCallback&&) = delete;
-
- void OnRegistration(QuicEpollServer* eps,
- int fd,
- int event_mask) override{};
-
- void OnModification(int fd, int event_mask) override{};
-
- void OnEvent(int fd, QuicEpollEvent* event) override;
-
- void OnUnregistration(int fd, bool replaced) override{};
-
- void OnShutdown(QuicEpollServer* eps, int fd) override;
-
- std::string Name() const override;
-
- private:
- IcmpReachable* reachable_;
- };
-
- bool OnEvent(int fd) QUIC_LOCKS_EXCLUDED(header_lock_);
-
- const absl::Duration timeout_;
-
- EpollCallback cb_;
-
- sockaddr_in6 src_{};
- sockaddr_in6 dst_{};
-
- KernelInterface* kernel_;
- QuicEpollServer* epoll_server_;
-
- StatsInterface* stats_;
-
- int send_fd_;
- int recv_fd_;
-
- QuicMutex header_lock_;
- icmp6_hdr icmp_header_ QUIC_GUARDED_BY(header_lock_){};
-
- absl::Time start_ = absl::InfinitePast();
- absl::Time end_ = absl::InfinitePast();
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_QBONE_BONNET_ICMP_REACHABLE_H_
diff --git a/chromium/net/third_party/quiche/src/quic/qbone/bonnet/icmp_reachable_interface.h b/chromium/net/third_party/quiche/src/quic/qbone/bonnet/icmp_reachable_interface.h
deleted file mode 100644
index f082bb67f58..00000000000
--- a/chromium/net/third_party/quiche/src/quic/qbone/bonnet/icmp_reachable_interface.h
+++ /dev/null
@@ -1,28 +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_QBONE_BONNET_ICMP_REACHABLE_INTERFACE_H_
-#define QUICHE_QUIC_QBONE_BONNET_ICMP_REACHABLE_INTERFACE_H_
-
-#include "quic/platform/api/quic_epoll.h"
-
-namespace quic {
-
-class IcmpReachableInterface : public QuicEpollAlarmBase {
- public:
- IcmpReachableInterface() = default;
-
- IcmpReachableInterface(const IcmpReachableInterface&) = delete;
- IcmpReachableInterface& operator=(const IcmpReachableInterface&) = delete;
-
- IcmpReachableInterface(IcmpReachableInterface&&) = delete;
- IcmpReachableInterface& operator=(IcmpReachableInterface&&) = delete;
-
- // Initializes this reachability probe.
- virtual bool Init() = 0;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_QBONE_BONNET_ICMP_REACHABLE_INTERFACE_H_
diff --git a/chromium/net/third_party/quiche/src/quic/qbone/bonnet/icmp_reachable_test.cc b/chromium/net/third_party/quiche/src/quic/qbone/bonnet/icmp_reachable_test.cc
deleted file mode 100644
index 221e5f665d5..00000000000
--- a/chromium/net/third_party/quiche/src/quic/qbone/bonnet/icmp_reachable_test.cc
+++ /dev/null
@@ -1,267 +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 "quic/qbone/bonnet/icmp_reachable.h"
-
-#include <netinet/ip6.h>
-
-#include "absl/container/node_hash_map.h"
-#include "quic/platform/api/quic_containers.h"
-#include "quic/platform/api/quic_epoll.h"
-#include "quic/platform/api/quic_ip_address.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/qbone/platform/mock_kernel.h"
-
-namespace quic {
-namespace {
-
-using ::testing::_;
-using ::testing::InSequence;
-using ::testing::Invoke;
-using ::testing::Return;
-using ::testing::StrictMock;
-
-constexpr char kSourceAddress[] = "fe80:1:2:3:4::1";
-constexpr char kDestinationAddress[] = "fe80:4:3:2:1::1";
-
-constexpr int kFakeWriteFd = 0;
-
-icmp6_hdr GetHeaderFromPacket(const void* buf, size_t len) {
- QUICHE_CHECK_GE(len, sizeof(ip6_hdr) + sizeof(icmp6_hdr));
-
- auto* buffer = reinterpret_cast<const char*>(buf);
- return *reinterpret_cast<const icmp6_hdr*>(&buffer[sizeof(ip6_hdr)]);
-}
-
-class StatsInterface : public IcmpReachable::StatsInterface {
- public:
- void OnEvent(IcmpReachable::ReachableEvent event) override {
- switch (event.status) {
- case IcmpReachable::REACHABLE: {
- reachable_count_++;
- break;
- }
- case IcmpReachable::UNREACHABLE: {
- unreachable_count_++;
- break;
- }
- }
- current_source_ = event.source;
- }
-
- void OnReadError(int error) override { read_errors_[error]++; }
-
- void OnWriteError(int error) override { write_errors_[error]++; }
-
- bool HasWriteErrors() { return !write_errors_.empty(); }
-
- int WriteErrorCount(int error) { return write_errors_[error]; }
-
- bool HasReadErrors() { return !read_errors_.empty(); }
-
- int ReadErrorCount(int error) { return read_errors_[error]; }
-
- int reachable_count() { return reachable_count_; }
-
- int unreachable_count() { return unreachable_count_; }
-
- std::string current_source() { return current_source_; }
-
- private:
- int reachable_count_ = 0;
- int unreachable_count_ = 0;
-
- std::string current_source_{};
-
- absl::node_hash_map<int, int> read_errors_;
- absl::node_hash_map<int, int> write_errors_;
-};
-
-class IcmpReachableTest : public QuicTest {
- public:
- IcmpReachableTest() {
- QUICHE_CHECK(source_.FromString(kSourceAddress));
- QUICHE_CHECK(destination_.FromString(kDestinationAddress));
-
- int pipe_fds[2];
- QUICHE_CHECK(pipe(pipe_fds) >= 0) << "pipe() failed";
-
- read_fd_ = pipe_fds[0];
- read_src_fd_ = pipe_fds[1];
- }
-
- void SetFdExpectations() {
- InSequence seq;
- EXPECT_CALL(kernel_, socket(_, _, _)).WillOnce(Return(kFakeWriteFd));
- EXPECT_CALL(kernel_, bind(kFakeWriteFd, _, _)).WillOnce(Return(0));
-
- EXPECT_CALL(kernel_, socket(_, _, _)).WillOnce(Return(read_fd_));
- EXPECT_CALL(kernel_, bind(read_fd_, _, _)).WillOnce(Return(0));
-
- EXPECT_CALL(kernel_, setsockopt(read_fd_, SOL_ICMPV6, ICMP6_FILTER, _, _));
-
- EXPECT_CALL(kernel_, close(read_fd_)).WillOnce(Invoke([](int fd) {
- return close(fd);
- }));
- }
-
- protected:
- QuicIpAddress source_;
- QuicIpAddress destination_;
-
- int read_fd_;
- int read_src_fd_;
-
- StrictMock<MockKernel> kernel_;
- QuicEpollServer epoll_server_;
- StatsInterface stats_;
-};
-
-TEST_F(IcmpReachableTest, SendsPings) {
- IcmpReachable reachable(source_, destination_, absl::ZeroDuration(), &kernel_,
- &epoll_server_, &stats_);
-
- SetFdExpectations();
- ASSERT_TRUE(reachable.Init());
-
- EXPECT_CALL(kernel_, sendto(kFakeWriteFd, _, _, _, _, _))
- .WillOnce(Invoke([](int sockfd, const void* buf, size_t len, int flags,
- const struct sockaddr* dest_addr, socklen_t addrlen) {
- auto icmp_header = GetHeaderFromPacket(buf, len);
- EXPECT_EQ(icmp_header.icmp6_type, ICMP6_ECHO_REQUEST);
- EXPECT_EQ(icmp_header.icmp6_seq, 1);
- return len;
- }));
-
- epoll_server_.WaitForEventsAndExecuteCallbacks();
- EXPECT_FALSE(stats_.HasWriteErrors());
-
- epoll_server_.Shutdown();
-}
-
-TEST_F(IcmpReachableTest, HandlesUnreachableEvents) {
- IcmpReachable reachable(source_, destination_, absl::ZeroDuration(), &kernel_,
- &epoll_server_, &stats_);
-
- SetFdExpectations();
- ASSERT_TRUE(reachable.Init());
-
- EXPECT_CALL(kernel_, sendto(kFakeWriteFd, _, _, _, _, _))
- .Times(2)
- .WillRepeatedly(Invoke([](int sockfd, const void* buf, size_t len,
- int flags, const struct sockaddr* dest_addr,
- socklen_t addrlen) { return len; }));
-
- epoll_server_.WaitForEventsAndExecuteCallbacks();
- EXPECT_EQ(stats_.unreachable_count(), 0);
-
- epoll_server_.WaitForEventsAndExecuteCallbacks();
- EXPECT_FALSE(stats_.HasWriteErrors());
- EXPECT_EQ(stats_.unreachable_count(), 1);
- EXPECT_EQ(stats_.current_source(), kNoSource);
-
- epoll_server_.Shutdown();
-}
-
-TEST_F(IcmpReachableTest, HandlesReachableEvents) {
- IcmpReachable reachable(source_, destination_, absl::ZeroDuration(), &kernel_,
- &epoll_server_, &stats_);
-
- SetFdExpectations();
- ASSERT_TRUE(reachable.Init());
-
- icmp6_hdr last_request_hdr{};
- EXPECT_CALL(kernel_, sendto(kFakeWriteFd, _, _, _, _, _))
- .Times(2)
- .WillRepeatedly(
- Invoke([&last_request_hdr](
- int sockfd, const void* buf, size_t len, int flags,
- const struct sockaddr* dest_addr, socklen_t addrlen) {
- last_request_hdr = GetHeaderFromPacket(buf, len);
- return len;
- }));
-
- sockaddr_in6 source_addr{};
- std::string packed_source = source_.ToPackedString();
- memcpy(&source_addr.sin6_addr, packed_source.data(), packed_source.size());
-
- EXPECT_CALL(kernel_, recvfrom(read_fd_, _, _, _, _, _))
- .WillOnce(
- Invoke([&source_addr](int sockfd, void* buf, size_t len, int flags,
- struct sockaddr* src_addr, socklen_t* addrlen) {
- *reinterpret_cast<sockaddr_in6*>(src_addr) = source_addr;
- return read(sockfd, buf, len);
- }));
-
- epoll_server_.WaitForEventsAndExecuteCallbacks();
- EXPECT_EQ(stats_.reachable_count(), 0);
-
- icmp6_hdr response = last_request_hdr;
- response.icmp6_type = ICMP6_ECHO_REPLY;
-
- write(read_src_fd_, reinterpret_cast<const void*>(&response),
- sizeof(icmp6_hdr));
-
- epoll_server_.WaitForEventsAndExecuteCallbacks();
- EXPECT_FALSE(stats_.HasReadErrors());
- EXPECT_FALSE(stats_.HasWriteErrors());
- EXPECT_EQ(stats_.reachable_count(), 1);
- EXPECT_EQ(stats_.current_source(), source_.ToString());
-
- epoll_server_.Shutdown();
-}
-
-TEST_F(IcmpReachableTest, HandlesWriteErrors) {
- IcmpReachable reachable(source_, destination_, absl::ZeroDuration(), &kernel_,
- &epoll_server_, &stats_);
-
- SetFdExpectations();
- ASSERT_TRUE(reachable.Init());
-
- EXPECT_CALL(kernel_, sendto(kFakeWriteFd, _, _, _, _, _))
- .WillOnce(Invoke([](int sockfd, const void* buf, size_t len, int flags,
- const struct sockaddr* dest_addr, socklen_t addrlen) {
- errno = EAGAIN;
- return 0;
- }));
-
- epoll_server_.WaitForEventsAndExecuteCallbacks();
- EXPECT_EQ(stats_.WriteErrorCount(EAGAIN), 1);
-
- epoll_server_.Shutdown();
-}
-
-TEST_F(IcmpReachableTest, HandlesReadErrors) {
- IcmpReachable reachable(source_, destination_, absl::ZeroDuration(), &kernel_,
- &epoll_server_, &stats_);
-
- SetFdExpectations();
- ASSERT_TRUE(reachable.Init());
-
- EXPECT_CALL(kernel_, sendto(kFakeWriteFd, _, _, _, _, _))
- .WillOnce(Invoke([](int sockfd, const void* buf, size_t len, int flags,
- const struct sockaddr* dest_addr,
- socklen_t addrlen) { return len; }));
-
- EXPECT_CALL(kernel_, recvfrom(read_fd_, _, _, _, _, _))
- .WillOnce(Invoke([](int sockfd, void* buf, size_t len, int flags,
- struct sockaddr* src_addr, socklen_t* addrlen) {
- errno = EIO;
- return -1;
- }));
-
- icmp6_hdr response{};
-
- write(read_src_fd_, reinterpret_cast<const void*>(&response),
- sizeof(icmp6_hdr));
-
- epoll_server_.WaitForEventsAndExecuteCallbacks();
- EXPECT_EQ(stats_.reachable_count(), 0);
- EXPECT_EQ(stats_.ReadErrorCount(EIO), 1);
-
- epoll_server_.Shutdown();
-}
-
-} // namespace
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/qbone/bonnet/mock_icmp_reachable.h b/chromium/net/third_party/quiche/src/quic/qbone/bonnet/mock_icmp_reachable.h
deleted file mode 100644
index 02f364c1376..00000000000
--- a/chromium/net/third_party/quiche/src/quic/qbone/bonnet/mock_icmp_reachable.h
+++ /dev/null
@@ -1,20 +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_QBONE_BONNET_MOCK_ICMP_REACHABLE_H_
-#define QUICHE_QUIC_QBONE_BONNET_MOCK_ICMP_REACHABLE_H_
-
-#include "quic/platform/api/quic_test.h"
-#include "quic/qbone/bonnet/icmp_reachable_interface.h"
-
-namespace quic {
-
-class MockIcmpReachable : public IcmpReachableInterface {
- public:
- MOCK_METHOD(bool, Init, (), (override));
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_QBONE_BONNET_MOCK_ICMP_REACHABLE_H_
diff --git a/chromium/net/third_party/quiche/src/quic/qbone/bonnet/mock_packet_exchanger_stats_interface.h b/chromium/net/third_party/quiche/src/quic/qbone/bonnet/mock_packet_exchanger_stats_interface.h
deleted file mode 100644
index c38f24de4c1..00000000000
--- a/chromium/net/third_party/quiche/src/quic/qbone/bonnet/mock_packet_exchanger_stats_interface.h
+++ /dev/null
@@ -1,27 +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_QBONE_BONNET_MOCK_PACKET_EXCHANGER_STATS_INTERFACE_H_
-#define QUICHE_QUIC_QBONE_BONNET_MOCK_PACKET_EXCHANGER_STATS_INTERFACE_H_
-
-#include "quic/platform/api/quic_test.h"
-#include "quic/qbone/bonnet/tun_device_packet_exchanger.h"
-
-namespace quic {
-
-class MockPacketExchangerStatsInterface
- : public TunDevicePacketExchanger::StatsInterface {
- public:
- MOCK_METHOD(void, OnPacketRead, (size_t), (override));
- MOCK_METHOD(void, OnPacketWritten, (size_t), (override));
- MOCK_METHOD(void, OnReadError, (std::string*), (override));
- MOCK_METHOD(void, OnWriteError, (std::string*), (override));
-
- MOCK_METHOD(int64_t, PacketsRead, (), (const, override));
- MOCK_METHOD(int64_t, PacketsWritten, (), (const, override));
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_QBONE_BONNET_MOCK_PACKET_EXCHANGER_STATS_INTERFACE_H_
diff --git a/chromium/net/third_party/quiche/src/quic/qbone/bonnet/mock_qbone_tunnel.h b/chromium/net/third_party/quiche/src/quic/qbone/bonnet/mock_qbone_tunnel.h
deleted file mode 100644
index 9fc74349e6d..00000000000
--- a/chromium/net/third_party/quiche/src/quic/qbone/bonnet/mock_qbone_tunnel.h
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright (c) 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_QBONE_BONNET_MOCK_QBONE_TUNNEL_H_
-#define QUICHE_QUIC_QBONE_BONNET_MOCK_QBONE_TUNNEL_H_
-
-#include "quic/platform/api/quic_test.h"
-#include "quic/qbone/bonnet/qbone_tunnel_interface.h"
-
-namespace quic {
-
-class MockQboneTunnel : public QboneTunnelInterface {
- public:
- MockQboneTunnel() = default;
-
- MOCK_METHOD(bool, WaitForEvents, (), (override));
-
- MOCK_METHOD(void, Wake, (), (override));
-
- MOCK_METHOD(void, ResetTunnel, (), (override));
-
- MOCK_METHOD(State, Disconnect, (), (override));
-
- MOCK_METHOD(void, OnControlRequest, (const quic::QboneClientRequest&),
- (override));
-
- MOCK_METHOD(void, OnControlError, (), (override));
-
- MOCK_METHOD(bool, AwaitConnection, ());
-
- MOCK_METHOD(std::string, StateToString, (State), (override));
-
- MOCK_METHOD(quic::QboneClient*, client, (), (override));
-
- MOCK_METHOD(State, state, ());
-
- MOCK_METHOD(std::string, HealthString, ());
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_QBONE_BONNET_MOCK_QBONE_TUNNEL_H_
diff --git a/chromium/net/third_party/quiche/src/quic/qbone/bonnet/mock_tun_device.h b/chromium/net/third_party/quiche/src/quic/qbone/bonnet/mock_tun_device.h
deleted file mode 100644
index 056346ca000..00000000000
--- a/chromium/net/third_party/quiche/src/quic/qbone/bonnet/mock_tun_device.h
+++ /dev/null
@@ -1,28 +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_QBONE_BONNET_MOCK_TUN_DEVICE_H_
-#define QUICHE_QUIC_QBONE_BONNET_MOCK_TUN_DEVICE_H_
-
-#include "quic/platform/api/quic_test.h"
-#include "quic/qbone/bonnet/tun_device_interface.h"
-
-namespace quic {
-
-class MockTunDevice : public TunDeviceInterface {
- public:
- MOCK_METHOD(bool, Init, (), (override));
-
- MOCK_METHOD(bool, Up, (), (override));
-
- MOCK_METHOD(bool, Down, (), (override));
-
- MOCK_METHOD(void, CloseDevice, (), (override));
-
- MOCK_METHOD(int, GetFileDescriptor, (), (const, override));
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_QBONE_BONNET_MOCK_TUN_DEVICE_H_
diff --git a/chromium/net/third_party/quiche/src/quic/qbone/bonnet/mock_tun_device_controller.h b/chromium/net/third_party/quiche/src/quic/qbone/bonnet/mock_tun_device_controller.h
deleted file mode 100644
index 7773111b18c..00000000000
--- a/chromium/net/third_party/quiche/src/quic/qbone/bonnet/mock_tun_device_controller.h
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright (c) 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_QBONE_BONNET_MOCK_TUN_DEVICE_CONTROLLER_H_
-#define QUICHE_QUIC_QBONE_BONNET_MOCK_TUN_DEVICE_CONTROLLER_H_
-
-#include "quic/platform/api/quic_test.h"
-#include "quic/qbone/bonnet/tun_device_controller.h"
-
-namespace quic {
-
-class MockTunDeviceController : public TunDeviceController {
- public:
- MockTunDeviceController() : TunDeviceController("", true, nullptr) {}
-
- MOCK_METHOD(bool, UpdateAddress, (const IpRange&), (override));
-
- MOCK_METHOD(bool, UpdateRoutes, (const IpRange&, const std::vector<IpRange>&),
- (override));
-
- MOCK_METHOD(QuicIpAddress, current_address, (), (override));
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_QBONE_BONNET_MOCK_TUN_DEVICE_CONTROLLER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/qbone/bonnet/qbone_tunnel_info.cc b/chromium/net/third_party/quiche/src/quic/qbone/bonnet/qbone_tunnel_info.cc
deleted file mode 100644
index 372cd2b2510..00000000000
--- a/chromium/net/third_party/quiche/src/quic/qbone/bonnet/qbone_tunnel_info.cc
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright (c) 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/qbone/bonnet/qbone_tunnel_info.h"
-
-namespace quic {
-
-QuicIpAddress QboneTunnelInfo::GetAddress() {
- QuicIpAddress no_address;
-
- NetlinkInterface::LinkInfo link_info{};
- if (!netlink_->GetLinkInfo(ifname_, &link_info)) {
- return no_address;
- }
-
- std::vector<NetlinkInterface::AddressInfo> addresses;
- if (!netlink_->GetAddresses(link_info.index, 0, &addresses, nullptr)) {
- return no_address;
- }
-
- quic::QuicIpAddress link_local_subnet;
- if (!link_local_subnet.FromString("FE80::")) {
- return no_address;
- }
-
- for (const auto& address : addresses) {
- if (address.interface_address.IsInitialized() &&
- !link_local_subnet.InSameSubnet(address.interface_address, 10)) {
- return address.interface_address;
- }
- }
-
- return no_address;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/qbone/bonnet/qbone_tunnel_info.h b/chromium/net/third_party/quiche/src/quic/qbone/bonnet/qbone_tunnel_info.h
deleted file mode 100644
index 6ca6ae8bff6..00000000000
--- a/chromium/net/third_party/quiche/src/quic/qbone/bonnet/qbone_tunnel_info.h
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright (c) 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_QBONE_BONNET_QBONE_TUNNEL_INFO_H_
-#define QUICHE_QUIC_QBONE_BONNET_QBONE_TUNNEL_INFO_H_
-
-#include "quic/platform/api/quic_ip_address.h"
-#include "quic/qbone/platform/netlink_interface.h"
-
-namespace quic {
-
-class QboneTunnelInfo {
- public:
- QboneTunnelInfo(std::string ifname, NetlinkInterface* netlink)
- : ifname_(std::move(ifname)), netlink_(netlink) {}
-
- // Returns the current QBONE tunnel address. Callers must use IsInitialized()
- // to ensure the returned address is valid.
- QuicIpAddress GetAddress();
-
- private:
- const std::string ifname_;
- NetlinkInterface* netlink_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_QBONE_BONNET_QBONE_TUNNEL_INFO_H_
diff --git a/chromium/net/third_party/quiche/src/quic/qbone/bonnet/qbone_tunnel_interface.h b/chromium/net/third_party/quiche/src/quic/qbone/bonnet/qbone_tunnel_interface.h
deleted file mode 100644
index ae19519cd9a..00000000000
--- a/chromium/net/third_party/quiche/src/quic/qbone/bonnet/qbone_tunnel_interface.h
+++ /dev/null
@@ -1,68 +0,0 @@
-// Copyright (c) 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_QBONE_BONNET_QBONE_TUNNEL_INTERFACE_H_
-#define QUICHE_QUIC_QBONE_BONNET_QBONE_TUNNEL_INTERFACE_H_
-
-#include "quic/qbone/qbone_client.h"
-
-namespace quic {
-
-// Interface for establishing bidirectional communication between a network
-// device and a QboneClient.
-class QboneTunnelInterface : public quic::QboneClientControlStream::Handler {
- public:
- QboneTunnelInterface() = default;
-
- QboneTunnelInterface(const QboneTunnelInterface&) = delete;
- QboneTunnelInterface& operator=(const QboneTunnelInterface&) = delete;
-
- QboneTunnelInterface(QboneTunnelInterface&&) = delete;
- QboneTunnelInterface& operator=(QboneTunnelInterface&&) = delete;
-
- enum State {
- UNINITIALIZED,
- IP_RANGE_REQUESTED,
- START_REQUESTED,
- STARTED,
- LAME_DUCK_REQUESTED,
- END_REQUESTED,
- ENDED,
- FAILED,
- };
-
- // Wait and handle any events which occur.
- // Returns true if there are any outstanding requests.
- virtual bool WaitForEvents() = 0;
-
- // Wakes the tunnel if it is currently in WaitForEvents.
- virtual void Wake() = 0;
-
- // Disconnect the tunnel, resetting it to an uninitialized state. This will
- // force ConnectIfNeeded to reconnect on the next epoll cycle.
- virtual void ResetTunnel() = 0;
-
- // Disconnect from the QBONE server.
- virtual State Disconnect() = 0;
-
- // Callback handling responses from the QBONE server.
- void OnControlRequest(const QboneClientRequest& request) override = 0;
-
- // Callback handling bad responses from the QBONE server. Currently, this is
- // only called when the response is unparsable.
- void OnControlError() override = 0;
-
- // Returns a string value of the given state.
- virtual std::string StateToString(State state) = 0;
-
- virtual QboneClient* client() = 0;
-
- virtual State state() = 0;
-
- virtual std::string HealthString() = 0;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_QBONE_BONNET_QBONE_TUNNEL_INTERFACE_H_
diff --git a/chromium/net/third_party/quiche/src/quic/qbone/bonnet/qbone_tunnel_silo.cc b/chromium/net/third_party/quiche/src/quic/qbone/bonnet/qbone_tunnel_silo.cc
deleted file mode 100644
index 736829ad0b5..00000000000
--- a/chromium/net/third_party/quiche/src/quic/qbone/bonnet/qbone_tunnel_silo.cc
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright (c) 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/qbone/bonnet/qbone_tunnel_silo.h"
-
-namespace quic {
-
-void QboneTunnelSilo::Run() {
- while (ShouldRun()) {
- tunnel_->WaitForEvents();
- }
-
- QUIC_LOG(INFO) << "Tunnel has disconnected in state: "
- << tunnel_->StateToString(tunnel_->Disconnect());
-}
-
-void QboneTunnelSilo::Quit() {
- QUIC_LOG(INFO) << "Quit called on QboneTunnelSilo";
- quitting_.Notify();
- tunnel_->Wake();
-}
-
-bool QboneTunnelSilo::ShouldRun() {
- bool post_init_shutdown_ready =
- only_setup_tun_ &&
- tunnel_->state() == quic::QboneTunnelInterface::STARTED;
- return !quitting_.HasBeenNotified() && !post_init_shutdown_ready;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/qbone/bonnet/qbone_tunnel_silo.h b/chromium/net/third_party/quiche/src/quic/qbone/bonnet/qbone_tunnel_silo.h
deleted file mode 100644
index cf8ce38f131..00000000000
--- a/chromium/net/third_party/quiche/src/quic/qbone/bonnet/qbone_tunnel_silo.h
+++ /dev/null
@@ -1,48 +0,0 @@
-// Copyright (c) 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_QBONE_BONNET_QBONE_TUNNEL_SILO_H_
-#define QUICHE_QUIC_QBONE_BONNET_QBONE_TUNNEL_SILO_H_
-
-#include "absl/synchronization/notification.h"
-#include "quic/platform/api/quic_thread.h"
-#include "quic/qbone/bonnet/qbone_tunnel_interface.h"
-
-namespace quic {
-
-// QboneTunnelSilo is a thread that initializes and evaluates a QboneTunnel's
-// event loop.
-class QboneTunnelSilo : public QuicThread {
- public:
- // Does not take ownership of |tunnel|
- explicit QboneTunnelSilo(QboneTunnelInterface* tunnel, bool only_setup_tun)
- : QuicThread("QboneTunnelSilo"),
- tunnel_(tunnel),
- only_setup_tun_(only_setup_tun) {}
-
- QboneTunnelSilo(const QboneTunnelSilo&) = delete;
- QboneTunnelSilo& operator=(const QboneTunnelSilo&) = delete;
-
- QboneTunnelSilo(QboneTunnelSilo&&) = delete;
- QboneTunnelSilo& operator=(QboneTunnelSilo&&) = delete;
-
- // Terminates the tunnel's event loop. This silo must still be joined.
- void Quit();
-
- protected:
- void Run() override;
-
- private:
- bool ShouldRun();
-
- QboneTunnelInterface* tunnel_;
-
- absl::Notification quitting_;
-
- const bool only_setup_tun_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_QBONE_BONNET_QBONE_TUNNEL_SILO_H_
diff --git a/chromium/net/third_party/quiche/src/quic/qbone/bonnet/qbone_tunnel_silo_test.cc b/chromium/net/third_party/quiche/src/quic/qbone/bonnet/qbone_tunnel_silo_test.cc
deleted file mode 100644
index 8327a53eacc..00000000000
--- a/chromium/net/third_party/quiche/src/quic/qbone/bonnet/qbone_tunnel_silo_test.cc
+++ /dev/null
@@ -1,78 +0,0 @@
-// Copyright (c) 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/qbone/bonnet/qbone_tunnel_silo.h"
-
-#include "absl/synchronization/notification.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/qbone/bonnet/mock_qbone_tunnel.h"
-
-namespace quic {
-namespace {
-
-using ::testing::Eq;
-using ::testing::Invoke;
-using ::testing::Return;
-
-TEST(QboneTunnelSiloTest, SiloRunsEventLoop) {
- MockQboneTunnel mock_tunnel;
-
- absl::Notification event_loop_run;
- EXPECT_CALL(mock_tunnel, WaitForEvents)
- .WillRepeatedly(Invoke([&event_loop_run]() {
- if (!event_loop_run.HasBeenNotified()) {
- event_loop_run.Notify();
- }
- return false;
- }));
-
- QboneTunnelSilo silo(&mock_tunnel, false);
- silo.Start();
-
- event_loop_run.WaitForNotification();
-
- absl::Notification client_disconnected;
- EXPECT_CALL(mock_tunnel, Disconnect)
- .WillOnce(Invoke([&client_disconnected]() {
- client_disconnected.Notify();
- return QboneTunnelInterface::ENDED;
- }));
-
- silo.Quit();
- client_disconnected.WaitForNotification();
-
- silo.Join();
-}
-
-TEST(QboneTunnelSiloTest, SiloCanShutDownAfterInit) {
- MockQboneTunnel mock_tunnel;
-
- int iteration_count = 0;
- EXPECT_CALL(mock_tunnel, WaitForEvents)
- .WillRepeatedly(Invoke([&iteration_count]() {
- iteration_count++;
- return false;
- }));
-
- EXPECT_CALL(mock_tunnel, state)
- .WillOnce(Return(QboneTunnelInterface::START_REQUESTED))
- .WillOnce(Return(QboneTunnelInterface::STARTED));
-
- absl::Notification client_disconnected;
- EXPECT_CALL(mock_tunnel, Disconnect)
- .WillOnce(Invoke([&client_disconnected]() {
- client_disconnected.Notify();
- return QboneTunnelInterface::ENDED;
- }));
-
- QboneTunnelSilo silo(&mock_tunnel, true);
- silo.Start();
-
- client_disconnected.WaitForNotification();
- silo.Join();
- EXPECT_THAT(iteration_count, Eq(1));
-}
-
-} // namespace
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/qbone/bonnet/tun_device.cc b/chromium/net/third_party/quiche/src/quic/qbone/bonnet/tun_device.cc
deleted file mode 100644
index 3768a439bec..00000000000
--- a/chromium/net/third_party/quiche/src/quic/qbone/bonnet/tun_device.cc
+++ /dev/null
@@ -1,219 +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 "quic/qbone/bonnet/tun_device.h"
-
-#include <fcntl.h>
-#include <linux/if_tun.h>
-#include <net/if.h>
-#include <sys/ioctl.h>
-#include <sys/socket.h>
-
-#include "absl/cleanup/cleanup.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/qbone/platform/kernel_interface.h"
-
-ABSL_FLAG(std::string,
- qbone_client_tun_device_path,
- "/dev/net/tun",
- "The path to the QBONE client's TUN device.");
-
-namespace quic {
-
-const int kInvalidFd = -1;
-
-TunTapDevice::TunTapDevice(const std::string& interface_name, int mtu,
- bool persist, bool setup_tun, bool is_tap,
- KernelInterface* kernel)
- : interface_name_(interface_name),
- mtu_(mtu),
- persist_(persist),
- setup_tun_(setup_tun),
- is_tap_(is_tap),
- file_descriptor_(kInvalidFd),
- kernel_(*kernel) {}
-
-TunTapDevice::~TunTapDevice() {
- if (!persist_) {
- Down();
- }
- CloseDevice();
-}
-
-bool TunTapDevice::Init() {
- if (interface_name_.empty() || interface_name_.size() >= IFNAMSIZ) {
- QUIC_BUG(quic_bug_10995_1)
- << "interface_name must be nonempty and shorter than " << IFNAMSIZ;
- return false;
- }
-
- if (!OpenDevice()) {
- return false;
- }
-
- if (!ConfigureInterface()) {
- return false;
- }
-
- return true;
-}
-
-// TODO(pengg): might be better to use netlink socket, once we have a library to
-// use
-bool TunTapDevice::Up() {
- if (!setup_tun_) {
- return true;
- }
- struct ifreq if_request;
- memset(&if_request, 0, sizeof(if_request));
- // copy does not zero-terminate the result string, but we've memset the
- // entire struct.
- interface_name_.copy(if_request.ifr_name, IFNAMSIZ);
- if_request.ifr_flags = IFF_UP;
-
- return NetdeviceIoctl(SIOCSIFFLAGS, reinterpret_cast<void*>(&if_request));
-}
-
-// TODO(pengg): might be better to use netlink socket, once we have a library to
-// use
-bool TunTapDevice::Down() {
- if (!setup_tun_) {
- return true;
- }
- struct ifreq if_request;
- memset(&if_request, 0, sizeof(if_request));
- // copy does not zero-terminate the result string, but we've memset the
- // entire struct.
- interface_name_.copy(if_request.ifr_name, IFNAMSIZ);
- if_request.ifr_flags = 0;
-
- return NetdeviceIoctl(SIOCSIFFLAGS, reinterpret_cast<void*>(&if_request));
-}
-
-int TunTapDevice::GetFileDescriptor() const { return file_descriptor_; }
-
-bool TunTapDevice::OpenDevice() {
- if (file_descriptor_ != kInvalidFd) {
- CloseDevice();
- }
-
- struct ifreq if_request;
- memset(&if_request, 0, sizeof(if_request));
- // copy does not zero-terminate the result string, but we've memset the entire
- // struct.
- interface_name_.copy(if_request.ifr_name, IFNAMSIZ);
-
- // Always set IFF_MULTI_QUEUE since a persistent device does not allow this
- // flag to be flipped when re-opening it. The only way to flip this flag is to
- // destroy the device and create a new one, but that deletes any existing
- // routing associated with the interface, which makes the meaning of the
- // 'persist' bit ambiguous.
- if_request.ifr_flags = IFF_MULTI_QUEUE | IFF_NO_PI;
- if (is_tap_) {
- if_request.ifr_flags |= IFF_TAP;
- } else {
- if_request.ifr_flags |= IFF_TUN;
- }
-
- // When the device is running with IFF_MULTI_QUEUE set, each call to open will
- // create a queue which can be used to read/write packets from/to the device.
- bool successfully_opened = false;
- auto cleanup = absl::MakeCleanup([this, &successfully_opened]() {
- if (!successfully_opened) {
- CloseDevice();
- }
- });
-
- const std::string tun_device_path =
- absl::GetFlag(FLAGS_qbone_client_tun_device_path);
- int fd = kernel_.open(tun_device_path.c_str(), O_RDWR);
- if (fd < 0) {
- QUIC_PLOG(WARNING) << "Failed to open " << tun_device_path;
- return successfully_opened;
- }
- file_descriptor_ = fd;
- if (!CheckFeatures(fd)) {
- return successfully_opened;
- }
-
- if (kernel_.ioctl(fd, TUNSETIFF, reinterpret_cast<void*>(&if_request)) != 0) {
- QUIC_PLOG(WARNING) << "Failed to TUNSETIFF on fd(" << fd << ")";
- return successfully_opened;
- }
-
- if (kernel_.ioctl(
- fd, TUNSETPERSIST,
- persist_ ? reinterpret_cast<void*>(&if_request) : nullptr) != 0) {
- QUIC_PLOG(WARNING) << "Failed to TUNSETPERSIST on fd(" << fd << ")";
- return successfully_opened;
- }
-
- successfully_opened = true;
- return successfully_opened;
-}
-
-// TODO(pengg): might be better to use netlink socket, once we have a library to
-// use
-bool TunTapDevice::ConfigureInterface() {
- if (!setup_tun_) {
- return true;
- }
-
- struct ifreq if_request;
- memset(&if_request, 0, sizeof(if_request));
- // copy does not zero-terminate the result string, but we've memset the entire
- // struct.
- interface_name_.copy(if_request.ifr_name, IFNAMSIZ);
- if_request.ifr_mtu = mtu_;
-
- if (!NetdeviceIoctl(SIOCSIFMTU, reinterpret_cast<void*>(&if_request))) {
- CloseDevice();
- return false;
- }
-
- return true;
-}
-
-bool TunTapDevice::CheckFeatures(int tun_device_fd) {
- unsigned int actual_features;
- if (kernel_.ioctl(tun_device_fd, TUNGETFEATURES, &actual_features) != 0) {
- QUIC_PLOG(WARNING) << "Failed to TUNGETFEATURES";
- return false;
- }
- unsigned int required_features = IFF_TUN | IFF_NO_PI;
- if ((required_features & actual_features) != required_features) {
- QUIC_LOG(WARNING)
- << "Required feature does not exist. required_features: 0x" << std::hex
- << required_features << " vs actual_features: 0x" << std::hex
- << actual_features;
- return false;
- }
- return true;
-}
-
-bool TunTapDevice::NetdeviceIoctl(int request, void* argp) {
- int fd = kernel_.socket(AF_INET6, SOCK_DGRAM, 0);
- if (fd < 0) {
- QUIC_PLOG(WARNING) << "Failed to create AF_INET6 socket.";
- return false;
- }
-
- if (kernel_.ioctl(fd, request, argp) != 0) {
- QUIC_PLOG(WARNING) << "Failed ioctl request: " << request;
- kernel_.close(fd);
- return false;
- }
- kernel_.close(fd);
- return true;
-}
-
-void TunTapDevice::CloseDevice() {
- if (file_descriptor_ != kInvalidFd) {
- kernel_.close(file_descriptor_);
- file_descriptor_ = kInvalidFd;
- }
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/qbone/bonnet/tun_device.h b/chromium/net/third_party/quiche/src/quic/qbone/bonnet/tun_device.h
deleted file mode 100644
index 66c06d204e6..00000000000
--- a/chromium/net/third_party/quiche/src/quic/qbone/bonnet/tun_device.h
+++ /dev/null
@@ -1,82 +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_QBONE_BONNET_TUN_DEVICE_H_
-#define QUICHE_QUIC_QBONE_BONNET_TUN_DEVICE_H_
-
-#include <string>
-#include <vector>
-
-#include "quic/qbone/bonnet/tun_device_interface.h"
-#include "quic/qbone/platform/kernel_interface.h"
-
-namespace quic {
-
-class TunTapDevice : public TunDeviceInterface {
- public:
- // This represents a tun device created in the OS kernel, which is a virtual
- // network interface that any packets sent to it can be read by a user space
- // program that owns it. The routing rule that routes packets to this
- // interface should be defined somewhere else.
- //
- // Standard read/write system calls can be used to receive/send packets
- // from/to this interface. The file descriptor is owned by this class.
- //
- // If persist is set to true, the device won't be deleted even after
- // destructing. The device will be picked up when initializing this class with
- // the same interface_name on the next time.
- //
- // Persisting the device is useful if one wants to keep the routing rules
- // since once a tun device is destroyed by the kernel, all the associated
- // routing rules go away.
- //
- // The caller should own kernel and make sure it outlives this.
- TunTapDevice(const std::string& interface_name, int mtu, bool persist,
- bool setup_tun, bool is_tap, KernelInterface* kernel);
-
- ~TunTapDevice() override;
-
- // Actually creates/reopens and configures the device.
- bool Init() override;
-
- // Marks the interface up to start receiving packets.
- bool Up() override;
-
- // Marks the interface down to stop receiving packets.
- bool Down() override;
-
- // Closes the open file descriptor for the TUN device (if one exists).
- // It is safe to reinitialize and reuse this TunTapDevice after calling
- // CloseDevice.
- void CloseDevice() override;
-
- // Gets the file descriptor that can be used to send/receive packets.
- // This returns -1 when the TUN device is in an invalid state.
- int GetFileDescriptor() const override;
-
- private:
- // Creates or reopens the tun device.
- bool OpenDevice();
-
- // Configure the interface.
- bool ConfigureInterface();
-
- // Checks if the required kernel features exists.
- bool CheckFeatures(int tun_device_fd);
-
- // Opens a socket and makes netdevice ioctl call
- bool NetdeviceIoctl(int request, void* argp);
-
- const std::string interface_name_;
- const int mtu_;
- const bool persist_;
- const bool setup_tun_;
- const bool is_tap_;
- int file_descriptor_;
- KernelInterface& kernel_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_QBONE_BONNET_TUN_DEVICE_H_
diff --git a/chromium/net/third_party/quiche/src/quic/qbone/bonnet/tun_device_controller.cc b/chromium/net/third_party/quiche/src/quic/qbone/bonnet/tun_device_controller.cc
deleted file mode 100644
index dd996c5c55b..00000000000
--- a/chromium/net/third_party/quiche/src/quic/qbone/bonnet/tun_device_controller.cc
+++ /dev/null
@@ -1,173 +0,0 @@
-// Copyright (c) 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/qbone/bonnet/tun_device_controller.h"
-
-#include <linux/rtnetlink.h>
-
-#include "absl/time/clock.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/qbone/qbone_constants.h"
-
-ABSL_FLAG(bool, qbone_tun_device_replace_default_routing_rules, true,
- "If true, will define a rule that points packets sourced from the "
- "qbone interface to the qbone table. This is unnecessary in "
- "environments with no other ipv6 route.");
-
-namespace quic {
-
-bool TunDeviceController::UpdateAddress(const IpRange& desired_range) {
- if (!setup_tun_) {
- return true;
- }
-
- NetlinkInterface::LinkInfo link_info{};
- if (!netlink_->GetLinkInfo(ifname_, &link_info)) {
- return false;
- }
-
- std::vector<NetlinkInterface::AddressInfo> addresses;
- if (!netlink_->GetAddresses(link_info.index, 0, &addresses, nullptr)) {
- return false;
- }
-
- QuicIpAddress desired_address = desired_range.FirstAddressInRange();
-
- for (const auto& address : addresses) {
- if (!netlink_->ChangeLocalAddress(
- link_info.index, NetlinkInterface::Verb::kRemove,
- address.interface_address, address.prefix_length, 0, 0, {})) {
- return false;
- }
- }
-
- bool address_updated = netlink_->ChangeLocalAddress(
- link_info.index, NetlinkInterface::Verb::kAdd, desired_address,
- desired_range.prefix_length(), IFA_F_PERMANENT | IFA_F_NODAD,
- RT_SCOPE_LINK, {});
-
- if (address_updated) {
- current_address_ = desired_address;
-
- for (const auto& cb : address_update_cbs_) {
- cb(current_address_);
- }
- }
-
- return address_updated;
-}
-
-bool TunDeviceController::UpdateRoutes(
- const IpRange& desired_range,
- const std::vector<IpRange>& desired_routes) {
- if (!setup_tun_) {
- return true;
- }
-
- NetlinkInterface::LinkInfo link_info{};
- if (!netlink_->GetLinkInfo(ifname_, &link_info)) {
- QUIC_LOG(ERROR) << "Could not get link info for interface <" << ifname_
- << ">";
- return false;
- }
-
- std::vector<NetlinkInterface::RoutingRule> routing_rules;
- if (!netlink_->GetRouteInfo(&routing_rules)) {
- QUIC_LOG(ERROR) << "Unable to get route info";
- return false;
- }
-
- for (const auto& rule : routing_rules) {
- if (rule.out_interface == link_info.index &&
- rule.table == QboneConstants::kQboneRouteTableId) {
- if (!netlink_->ChangeRoute(NetlinkInterface::Verb::kRemove,
- rule.table, rule.destination_subnet,
- rule.scope, rule.preferred_source,
- rule.out_interface)) {
- QUIC_LOG(ERROR) << "Unable to remove old route to <"
- << rule.destination_subnet.ToString() << ">";
- return false;
- }
- }
- }
-
- if (!UpdateRules(desired_range)) {
- return false;
- }
-
- QuicIpAddress desired_address = desired_range.FirstAddressInRange();
-
- std::vector<IpRange> routes(desired_routes.begin(), desired_routes.end());
- routes.emplace_back(*QboneConstants::TerminatorLocalAddressRange());
-
- for (const auto& route : routes) {
- if (!netlink_->ChangeRoute(NetlinkInterface::Verb::kReplace,
- QboneConstants::kQboneRouteTableId, route,
- RT_SCOPE_LINK, desired_address,
- link_info.index)) {
- QUIC_LOG(ERROR) << "Unable to add route <" << route.ToString() << ">";
- return false;
- }
- }
-
- return true;
-}
-
-bool TunDeviceController::UpdateRoutesWithRetries(
- const IpRange& desired_range,
- const std::vector<IpRange>& desired_routes,
- int retries) {
- while (retries-- > 0) {
- if (UpdateRoutes(desired_range, desired_routes)) {
- return true;
- }
- absl::SleepFor(absl::Milliseconds(100));
- }
- return false;
-}
-
-bool TunDeviceController::UpdateRules(IpRange desired_range) {
- if (!absl::GetFlag(FLAGS_qbone_tun_device_replace_default_routing_rules)) {
- return true;
- }
-
- std::vector<NetlinkInterface::IpRule> ip_rules;
- if (!netlink_->GetRuleInfo(&ip_rules)) {
- QUIC_LOG(ERROR) << "Unable to get rule info";
- return false;
- }
-
- for (const auto& rule : ip_rules) {
- if (rule.table == QboneConstants::kQboneRouteTableId) {
- if (!netlink_->ChangeRule(NetlinkInterface::Verb::kRemove,
- rule.table, rule.source_range)) {
- QUIC_LOG(ERROR) << "Unable to remove old rule for table <" << rule.table
- << "> from source <" << rule.source_range.ToString()
- << ">";
- return false;
- }
- }
- }
-
- if (!netlink_->ChangeRule(NetlinkInterface::Verb::kAdd,
- QboneConstants::kQboneRouteTableId,
- desired_range)) {
- QUIC_LOG(ERROR) << "Unable to add rule for <" << desired_range.ToString()
- << ">";
- return false;
- }
-
- return true;
-}
-
-QuicIpAddress TunDeviceController::current_address() {
- return current_address_;
-}
-
-void TunDeviceController::RegisterAddressUpdateCallback(
- const std::function<void(QuicIpAddress)>& cb) {
- address_update_cbs_.push_back(cb);
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/qbone/bonnet/tun_device_controller.h b/chromium/net/third_party/quiche/src/quic/qbone/bonnet/tun_device_controller.h
deleted file mode 100644
index 612e98f5222..00000000000
--- a/chromium/net/third_party/quiche/src/quic/qbone/bonnet/tun_device_controller.h
+++ /dev/null
@@ -1,74 +0,0 @@
-// Copyright (c) 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_QBONE_BONNET_TUN_DEVICE_CONTROLLER_H_
-#define QUICHE_QUIC_QBONE_BONNET_TUN_DEVICE_CONTROLLER_H_
-
-#include "quic/qbone/bonnet/tun_device.h"
-#include "quic/qbone/platform/netlink_interface.h"
-#include "quic/qbone/qbone_control.pb.h"
-#include "quic/qbone/qbone_control_stream.h"
-
-namespace quic {
-
-// TunDeviceController consumes control stream messages from a Qbone server
-// and applies the given updates to the TUN device.
-class TunDeviceController {
- public:
- // |ifname| is the interface name of the TUN device to be managed. This does
- // not take ownership of |netlink|.
- TunDeviceController(std::string ifname, bool setup_tun,
- NetlinkInterface* netlink)
- : ifname_(std::move(ifname)), setup_tun_(setup_tun), netlink_(netlink) {}
-
- TunDeviceController(const TunDeviceController&) = delete;
- TunDeviceController& operator=(const TunDeviceController&) = delete;
-
- TunDeviceController(TunDeviceController&&) = delete;
- TunDeviceController& operator=(TunDeviceController&&) = delete;
-
- virtual ~TunDeviceController() = default;
-
- // Updates the local address of the TUN device to be the first address in the
- // given |response.ip_range()|.
- virtual bool UpdateAddress(const IpRange& desired_range);
-
- // Updates the set of routes that the TUN device will provide. All current
- // routes for the tunnel that do not exist in the |response| will be removed.
- virtual bool UpdateRoutes(const IpRange& desired_range,
- const std::vector<IpRange>& desired_routes);
-
- // Same as UpdateRoutes, but will wait and retry up to the number of times
- // given by |retries| before giving up. This is an unpleasant workaround to
- // deal with older kernels that aren't always able to set a route with a
- // source address immediately after adding the address to the interface.
- //
- // TODO(b/179430548): Remove this once we've root-caused the underlying issue.
- virtual bool UpdateRoutesWithRetries(
- const IpRange& desired_range,
- const std::vector<IpRange>& desired_routes,
- int retries);
-
- virtual void RegisterAddressUpdateCallback(
- const std::function<void(QuicIpAddress)>& cb);
-
- virtual QuicIpAddress current_address();
-
- private:
- // Update the IP Rules, this should only be used by UpdateRoutes.
- bool UpdateRules(IpRange desired_range);
-
- const std::string ifname_;
- const bool setup_tun_;
-
- NetlinkInterface* netlink_;
-
- QuicIpAddress current_address_;
-
- std::vector<std::function<void(QuicIpAddress)>> address_update_cbs_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_QBONE_BONNET_TUN_DEVICE_CONTROLLER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/qbone/bonnet/tun_device_controller_test.cc b/chromium/net/third_party/quiche/src/quic/qbone/bonnet/tun_device_controller_test.cc
deleted file mode 100644
index 53e5b3c14c2..00000000000
--- a/chromium/net/third_party/quiche/src/quic/qbone/bonnet/tun_device_controller_test.cc
+++ /dev/null
@@ -1,262 +0,0 @@
-// Copyright (c) 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/qbone/bonnet/tun_device_controller.h"
-
-#include <linux/if_addr.h>
-#include <linux/rtnetlink.h>
-
-#include "absl/strings/string_view.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/qbone/platform/mock_netlink.h"
-#include "quic/qbone/qbone_constants.h"
-
-ABSL_DECLARE_FLAG(bool, qbone_tun_device_replace_default_routing_rules);
-
-namespace quic {
-namespace {
-using ::testing::Eq;
-
-constexpr int kIfindex = 42;
-constexpr char kIfname[] = "qbone0";
-
-const IpRange kIpRange = []() {
- IpRange range;
- QCHECK(range.FromString("2604:31c0:2::/64"));
- return range;
-}();
-
-constexpr char kOldAddress[] = "1.2.3.4";
-constexpr int kOldPrefixLen = 24;
-
-using ::testing::_;
-using ::testing::Invoke;
-using ::testing::Return;
-using ::testing::StrictMock;
-
-MATCHER_P(IpRangeEq, range,
- absl::StrCat("expected IpRange to equal ", range.ToString())) {
- return arg == range;
-}
-
-class TunDeviceControllerTest : public QuicTest {
- public:
- TunDeviceControllerTest()
- : controller_(kIfname, true, &netlink_),
- link_local_range_(*QboneConstants::TerminatorLocalAddressRange()) {
- controller_.RegisterAddressUpdateCallback(
- [this](QuicIpAddress address) { notified_address_ = address; });
- }
-
- protected:
- void ExpectLinkInfo(const std::string& interface_name, int ifindex) {
- EXPECT_CALL(netlink_, GetLinkInfo(interface_name, _))
- .WillOnce(
- Invoke([ifindex](absl::string_view ifname,
- NetlinkInterface::LinkInfo* link_info) {
- link_info->index = ifindex;
- return true;
- }));
- }
-
- MockNetlink netlink_;
- TunDeviceController controller_;
- QuicIpAddress notified_address_;
-
- IpRange link_local_range_;
-};
-
-TEST_F(TunDeviceControllerTest, AddressAppliedWhenNoneExisted) {
- ExpectLinkInfo(kIfname, kIfindex);
-
- EXPECT_CALL(netlink_, GetAddresses(kIfindex, _, _, _)).WillOnce(Return(true));
-
- EXPECT_CALL(netlink_,
- ChangeLocalAddress(
- kIfindex, NetlinkInterface::Verb::kAdd,
- kIpRange.FirstAddressInRange(), kIpRange.prefix_length(),
- IFA_F_PERMANENT | IFA_F_NODAD, RT_SCOPE_LINK, _))
- .WillOnce(Return(true));
-
- EXPECT_TRUE(controller_.UpdateAddress(kIpRange));
- EXPECT_THAT(notified_address_, Eq(kIpRange.FirstAddressInRange()));
-}
-
-TEST_F(TunDeviceControllerTest, OldAddressesAreRemoved) {
- ExpectLinkInfo(kIfname, kIfindex);
-
- EXPECT_CALL(netlink_, GetAddresses(kIfindex, _, _, _))
- .WillOnce(
- Invoke([](int interface_index, uint8_t unwanted_flags,
- std::vector<NetlinkInterface::AddressInfo>* addresses,
- int* num_ipv6_nodad_dadfailed_addresses) {
- NetlinkInterface::AddressInfo info{};
- info.interface_address.FromString(kOldAddress);
- info.prefix_length = kOldPrefixLen;
- addresses->emplace_back(info);
- return true;
- }));
-
- QuicIpAddress old_address;
- old_address.FromString(kOldAddress);
-
- EXPECT_CALL(netlink_, ChangeLocalAddress(
- kIfindex, NetlinkInterface::Verb::kRemove,
- old_address, kOldPrefixLen, _, _, _))
- .WillOnce(Return(true));
-
- EXPECT_CALL(netlink_,
- ChangeLocalAddress(
- kIfindex, NetlinkInterface::Verb::kAdd,
- kIpRange.FirstAddressInRange(), kIpRange.prefix_length(),
- IFA_F_PERMANENT | IFA_F_NODAD, RT_SCOPE_LINK, _))
- .WillOnce(Return(true));
-
- EXPECT_TRUE(controller_.UpdateAddress(kIpRange));
- EXPECT_THAT(notified_address_, Eq(kIpRange.FirstAddressInRange()));
-}
-
-TEST_F(TunDeviceControllerTest, UpdateRoutesRemovedOldRoutes) {
- ExpectLinkInfo(kIfname, kIfindex);
-
- const int num_matching_routes = 3;
- EXPECT_CALL(netlink_, GetRouteInfo(_))
- .WillOnce(Invoke(
- [](std::vector<NetlinkInterface::RoutingRule>* routing_rules) {
- NetlinkInterface::RoutingRule non_matching_route;
- non_matching_route.table = QboneConstants::kQboneRouteTableId;
- non_matching_route.out_interface = kIfindex + 1;
- routing_rules->push_back(non_matching_route);
-
- NetlinkInterface::RoutingRule matching_route;
- matching_route.table = QboneConstants::kQboneRouteTableId;
- matching_route.out_interface = kIfindex;
- for (int i = 0; i < num_matching_routes; i++) {
- routing_rules->push_back(matching_route);
- }
-
- NetlinkInterface::RoutingRule non_matching_table;
- non_matching_table.table =
- QboneConstants::kQboneRouteTableId + 1;
- non_matching_table.out_interface = kIfindex;
- routing_rules->push_back(non_matching_table);
- return true;
- }));
-
- EXPECT_CALL(netlink_, ChangeRoute(NetlinkInterface::Verb::kRemove,
- QboneConstants::kQboneRouteTableId, _,
- _, _, kIfindex))
- .Times(num_matching_routes)
- .WillRepeatedly(Return(true));
-
- EXPECT_CALL(netlink_, GetRuleInfo(_)).WillOnce(Return(true));
-
- EXPECT_CALL(netlink_, ChangeRule(NetlinkInterface::Verb::kAdd,
- QboneConstants::kQboneRouteTableId,
- IpRangeEq(kIpRange)))
- .WillOnce(Return(true));
-
- EXPECT_CALL(netlink_,
- ChangeRoute(NetlinkInterface::Verb::kReplace,
- QboneConstants::kQboneRouteTableId,
- IpRangeEq(link_local_range_), _, _, kIfindex))
- .WillOnce(Return(true));
-
- EXPECT_TRUE(controller_.UpdateRoutes(kIpRange, {}));
-}
-
-TEST_F(TunDeviceControllerTest, UpdateRoutesAddsNewRoutes) {
- ExpectLinkInfo(kIfname, kIfindex);
-
- EXPECT_CALL(netlink_, GetRouteInfo(_)).WillOnce(Return(true));
-
- EXPECT_CALL(netlink_, GetRuleInfo(_)).WillOnce(Return(true));
-
- EXPECT_CALL(netlink_, ChangeRoute(NetlinkInterface::Verb::kReplace,
- QboneConstants::kQboneRouteTableId,
- IpRangeEq(kIpRange), _, _, kIfindex))
- .Times(2)
- .WillRepeatedly(Return(true))
- .RetiresOnSaturation();
-
- EXPECT_CALL(netlink_, ChangeRule(NetlinkInterface::Verb::kAdd,
- QboneConstants::kQboneRouteTableId,
- IpRangeEq(kIpRange)))
- .WillOnce(Return(true));
-
- EXPECT_CALL(netlink_,
- ChangeRoute(NetlinkInterface::Verb::kReplace,
- QboneConstants::kQboneRouteTableId,
- IpRangeEq(link_local_range_), _, _, kIfindex))
- .WillOnce(Return(true));
-
- EXPECT_TRUE(controller_.UpdateRoutes(kIpRange, {kIpRange, kIpRange}));
-}
-
-TEST_F(TunDeviceControllerTest, EmptyUpdateRouteKeepsLinkLocalRoute) {
- ExpectLinkInfo(kIfname, kIfindex);
-
- EXPECT_CALL(netlink_, GetRouteInfo(_)).WillOnce(Return(true));
-
- EXPECT_CALL(netlink_, GetRuleInfo(_)).WillOnce(Return(true));
-
- EXPECT_CALL(netlink_, ChangeRule(NetlinkInterface::Verb::kAdd,
- QboneConstants::kQboneRouteTableId,
- IpRangeEq(kIpRange)))
- .WillOnce(Return(true));
-
- EXPECT_CALL(netlink_,
- ChangeRoute(NetlinkInterface::Verb::kReplace,
- QboneConstants::kQboneRouteTableId,
- IpRangeEq(link_local_range_), _, _, kIfindex))
- .WillOnce(Return(true));
-
- EXPECT_TRUE(controller_.UpdateRoutes(kIpRange, {}));
-}
-
-TEST_F(TunDeviceControllerTest, DisablingRoutingRulesSkipsRuleCreation) {
- absl::SetFlag(&FLAGS_qbone_tun_device_replace_default_routing_rules, false);
- ExpectLinkInfo(kIfname, kIfindex);
-
- EXPECT_CALL(netlink_, GetRouteInfo(_)).WillOnce(Return(true));
-
- EXPECT_CALL(netlink_, ChangeRoute(NetlinkInterface::Verb::kReplace,
- QboneConstants::kQboneRouteTableId,
- IpRangeEq(kIpRange), _, _, kIfindex))
- .Times(2)
- .WillRepeatedly(Return(true))
- .RetiresOnSaturation();
-
- EXPECT_CALL(netlink_,
- ChangeRoute(NetlinkInterface::Verb::kReplace,
- QboneConstants::kQboneRouteTableId,
- IpRangeEq(link_local_range_), _, _, kIfindex))
- .WillOnce(Return(true));
-
- EXPECT_TRUE(controller_.UpdateRoutes(kIpRange, {kIpRange, kIpRange}));
-}
-
-class DisabledTunDeviceControllerTest : public QuicTest {
- public:
- DisabledTunDeviceControllerTest()
- : controller_(kIfname, false, &netlink_),
- link_local_range_(
- *QboneConstants::TerminatorLocalAddressRange()) {}
-
- StrictMock<MockNetlink> netlink_;
- TunDeviceController controller_;
-
- IpRange link_local_range_;
-};
-
-TEST_F(DisabledTunDeviceControllerTest, UpdateRoutesIsNop) {
- EXPECT_THAT(controller_.UpdateRoutes(kIpRange, {}), Eq(true));
-}
-
-TEST_F(DisabledTunDeviceControllerTest, UpdateAddressIsNop) {
- EXPECT_THAT(controller_.UpdateAddress(kIpRange), Eq(true));
-}
-
-} // namespace
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/qbone/bonnet/tun_device_interface.h b/chromium/net/third_party/quiche/src/quic/qbone/bonnet/tun_device_interface.h
deleted file mode 100644
index e88efa97186..00000000000
--- a/chromium/net/third_party/quiche/src/quic/qbone/bonnet/tun_device_interface.h
+++ /dev/null
@@ -1,38 +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_QBONE_BONNET_TUN_DEVICE_INTERFACE_H_
-#define QUICHE_QUIC_QBONE_BONNET_TUN_DEVICE_INTERFACE_H_
-
-#include <vector>
-
-namespace quic {
-
-// An interface with methods for interacting with a TUN device.
-class TunDeviceInterface {
- public:
- virtual ~TunDeviceInterface() = default;
-
- // Actually creates/reopens and configures the device.
- virtual bool Init() = 0;
-
- // Marks the interface up to start receiving packets.
- virtual bool Up() = 0;
-
- // Marks the interface down to stop receiving packets.
- virtual bool Down() = 0;
-
- // Closes the open file descriptor for the TUN device (if one exists).
- // It is safe to reinitialize and reuse this TunTapDevice after calling
- // CloseDevice.
- virtual void CloseDevice() = 0;
-
- // Gets the file descriptor that can be used to send/receive packets.
- // This returns -1 when the TUN device is in an invalid state.
- virtual int GetFileDescriptor() const = 0;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_QBONE_BONNET_TUN_DEVICE_INTERFACE_H_
diff --git a/chromium/net/third_party/quiche/src/quic/qbone/bonnet/tun_device_packet_exchanger.cc b/chromium/net/third_party/quiche/src/quic/qbone/bonnet/tun_device_packet_exchanger.cc
deleted file mode 100644
index 3381cd2b3f4..00000000000
--- a/chromium/net/third_party/quiche/src/quic/qbone/bonnet/tun_device_packet_exchanger.cc
+++ /dev/null
@@ -1,230 +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 "quic/qbone/bonnet/tun_device_packet_exchanger.h"
-
-#include <netinet/icmp6.h>
-#include <netinet/ip6.h>
-
-#include <utility>
-
-#include "absl/strings/str_cat.h"
-#include "quic/qbone/platform/icmp_packet.h"
-#include "quic/qbone/platform/netlink_interface.h"
-#include "quic/qbone/qbone_constants.h"
-
-namespace quic {
-
-TunDevicePacketExchanger::TunDevicePacketExchanger(
- size_t mtu, KernelInterface* kernel, NetlinkInterface* netlink,
- QbonePacketExchanger::Visitor* visitor, size_t max_pending_packets,
- bool is_tap, StatsInterface* stats, absl::string_view ifname)
- : QbonePacketExchanger(visitor, max_pending_packets),
- mtu_(mtu),
- kernel_(kernel),
- netlink_(netlink),
- ifname_(ifname),
- is_tap_(is_tap),
- stats_(stats) {
- if (is_tap_) {
- mtu_ += ETH_HLEN;
- }
-}
-
-bool TunDevicePacketExchanger::WritePacket(const char* packet, size_t size,
- bool* blocked, std::string* error) {
- *blocked = false;
- if (fd_ < 0) {
- *error = absl::StrCat("Invalid file descriptor of the TUN device: ", fd_);
- stats_->OnWriteError(error);
- return false;
- }
-
- auto buffer = std::make_unique<QuicData>(packet, size);
- if (is_tap_) {
- buffer = ApplyL2Headers(*buffer);
- }
- int result = kernel_->write(fd_, buffer->data(), buffer->length());
- if (result == -1) {
- if (errno == EWOULDBLOCK || errno == EAGAIN) {
- // The tunnel is blocked. Note that this does not mean the receive buffer
- // of a TCP connection is filled. This simply means the TUN device itself
- // is blocked on handing packets to the rest part of the kernel.
- *error = absl::StrCat("Write to the TUN device was blocked: ", errno);
- *blocked = true;
- stats_->OnWriteError(error);
- }
- return false;
- }
- stats_->OnPacketWritten(result);
-
- return true;
-}
-
-std::unique_ptr<QuicData> TunDevicePacketExchanger::ReadPacket(
- bool* blocked, std::string* error) {
- *blocked = false;
- if (fd_ < 0) {
- *error = absl::StrCat("Invalid file descriptor of the TUN device: ", fd_);
- stats_->OnReadError(error);
- return nullptr;
- }
- // Reading on a TUN device returns a packet at a time. If the packet is longer
- // than the buffer, it's truncated.
- auto read_buffer = std::make_unique<char[]>(mtu_);
- int result = kernel_->read(fd_, read_buffer.get(), mtu_);
- // Note that 0 means end of file, but we're talking about a TUN device - there
- // is no end of file. Therefore 0 also indicates error.
- if (result <= 0) {
- if (errno == EAGAIN || errno == EWOULDBLOCK) {
- *error = absl::StrCat("Read from the TUN device was blocked: ", errno);
- *blocked = true;
- stats_->OnReadError(error);
- }
- return nullptr;
- }
-
- auto buffer = std::make_unique<QuicData>(read_buffer.release(), result, true);
- if (is_tap_) {
- buffer = ConsumeL2Headers(*buffer);
- }
- if (buffer) {
- stats_->OnPacketRead(buffer->length());
- }
- return buffer;
-}
-
-void TunDevicePacketExchanger::set_file_descriptor(int fd) { fd_ = fd; }
-
-const TunDevicePacketExchanger::StatsInterface*
-TunDevicePacketExchanger::stats_interface() const {
- return stats_;
-}
-
-std::unique_ptr<QuicData> TunDevicePacketExchanger::ApplyL2Headers(
- const QuicData& l3_packet) {
- if (is_tap_ && !mac_initialized_) {
- NetlinkInterface::LinkInfo link_info{};
- if (netlink_->GetLinkInfo(ifname_, &link_info)) {
- memcpy(tap_mac_, link_info.hardware_address, ETH_ALEN);
- mac_initialized_ = true;
- } else {
- QUIC_LOG_EVERY_N_SEC(ERROR, 30)
- << "Unable to get link info for: " << ifname_;
- }
- }
-
- const auto l2_packet_size = l3_packet.length() + ETH_HLEN;
- auto l2_buffer = std::make_unique<char[]>(l2_packet_size);
-
- // Populate the Ethernet header
- auto* hdr = reinterpret_cast<ethhdr*>(l2_buffer.get());
- // Set src & dst to my own address
- memcpy(hdr->h_dest, tap_mac_, ETH_ALEN);
- memcpy(hdr->h_source, tap_mac_, ETH_ALEN);
- // Assume ipv6 for now
- // TODO(b/195113643): Support additional protocols.
- hdr->h_proto = absl::ghtons(ETH_P_IPV6);
-
- // Copy the l3 packet into buffer, just after the ethernet header.
- memcpy(l2_buffer.get() + ETH_HLEN, l3_packet.data(), l3_packet.length());
-
- return std::make_unique<QuicData>(l2_buffer.release(), l2_packet_size, true);
-}
-
-std::unique_ptr<QuicData> TunDevicePacketExchanger::ConsumeL2Headers(
- const QuicData& l2_packet) {
- if (l2_packet.length() < ETH_HLEN) {
- // Packet is too short for ethernet headers. Drop it.
- return nullptr;
- }
- auto* hdr = reinterpret_cast<const ethhdr*>(l2_packet.data());
- if (hdr->h_proto != absl::ghtons(ETH_P_IPV6)) {
- return nullptr;
- }
- constexpr auto kIp6PrefixLen = ETH_HLEN + sizeof(ip6_hdr);
- constexpr auto kIcmp6PrefixLen = kIp6PrefixLen + sizeof(icmp6_hdr);
- if (l2_packet.length() < kIp6PrefixLen) {
- // Packet is too short to be ipv6. Drop it.
- return nullptr;
- }
- auto* ip_hdr = reinterpret_cast<const ip6_hdr*>(l2_packet.data() + ETH_HLEN);
- const bool is_icmp = ip_hdr->ip6_ctlun.ip6_un1.ip6_un1_nxt == IPPROTO_ICMPV6;
-
- bool is_neighbor_solicit = false;
- if (is_icmp) {
- if (l2_packet.length() < kIcmp6PrefixLen) {
- // Packet is too short to be icmp6. Drop it.
- return nullptr;
- }
- is_neighbor_solicit =
- reinterpret_cast<const icmp6_hdr*>(l2_packet.data() + kIp6PrefixLen)
- ->icmp6_type == ND_NEIGHBOR_SOLICIT;
- }
-
- if (is_neighbor_solicit) {
- // If we've received a neighbor solicitation, craft an advertisement to
- // respond with and write it back to the local interface.
- auto* icmp6_payload = l2_packet.data() + kIcmp6PrefixLen;
-
- QuicIpAddress target_address(
- *reinterpret_cast<const in6_addr*>(icmp6_payload));
- if (target_address != *QboneConstants::GatewayAddress()) {
- // Only respond to solicitations for our gateway address
- return nullptr;
- }
-
- // Neighbor Advertisement crafted per:
- // https://datatracker.ietf.org/doc/html/rfc4861#section-4.4
- //
- // Using the Target link-layer address option defined at:
- // https://datatracker.ietf.org/doc/html/rfc4861#section-4.6.1
- constexpr size_t kIcmpv6OptionSize = 8;
- const int payload_size = sizeof(in6_addr) + kIcmpv6OptionSize;
- auto payload = std::make_unique<char[]>(payload_size);
- // Place the solicited IPv6 address at the beginning of the response payload
- memcpy(payload.get(), icmp6_payload, sizeof(in6_addr));
- // Setup the Target link-layer address option:
- // 0 1 2 3
- // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- // | Type | Length | Link-Layer Address ...
- // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- int pos = sizeof(in6_addr);
- payload[pos++] = ND_OPT_TARGET_LINKADDR; // Type
- payload[pos++] = 1; // Length in units of 8 octets
- memcpy(&payload[pos], tap_mac_, ETH_ALEN); // This interfaces' MAC address
-
- // Populate the ICMPv6 header
- icmp6_hdr response_hdr{};
- response_hdr.icmp6_type = ND_NEIGHBOR_ADVERT;
- // Set the solicited bit to true
- response_hdr.icmp6_dataun.icmp6_un_data8[0] = 64;
- // Craft the full ICMPv6 packet and then ship it off to WritePacket
- // to have it frame it with L2 headers and send it back to the requesting
- // neighbor.
- CreateIcmpPacket(ip_hdr->ip6_src, ip_hdr->ip6_src, response_hdr,
- absl::string_view(payload.get(), payload_size),
- [this](absl::string_view packet) {
- bool blocked;
- std::string error;
- WritePacket(packet.data(), packet.size(), &blocked,
- &error);
- });
- // Do not forward the neighbor solicitation through the tunnel since it's
- // link-local.
- return nullptr;
- }
-
- // If this isn't a Neighbor Solicitation, remove the L2 headers and forward
- // it as though it were an L3 packet.
- const auto l3_packet_size = l2_packet.length() - ETH_HLEN;
- auto shift_buffer = std::make_unique<char[]>(l3_packet_size);
- memcpy(shift_buffer.get(), l2_packet.data() + ETH_HLEN, l3_packet_size);
-
- return std::make_unique<QuicData>(shift_buffer.release(), l3_packet_size,
- true);
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/qbone/bonnet/tun_device_packet_exchanger.h b/chromium/net/third_party/quiche/src/quic/qbone/bonnet/tun_device_packet_exchanger.h
deleted file mode 100644
index 3136b42862a..00000000000
--- a/chromium/net/third_party/quiche/src/quic/qbone/bonnet/tun_device_packet_exchanger.h
+++ /dev/null
@@ -1,88 +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_QBONE_BONNET_TUN_DEVICE_PACKET_EXCHANGER_H_
-#define QUICHE_QUIC_QBONE_BONNET_TUN_DEVICE_PACKET_EXCHANGER_H_
-
-#include <linux/if_ether.h>
-
-#include "quic/core/quic_packets.h"
-#include "quic/qbone/platform/kernel_interface.h"
-#include "quic/qbone/platform/netlink_interface.h"
-#include "quic/qbone/qbone_client_interface.h"
-#include "quic/qbone/qbone_packet_exchanger.h"
-
-namespace quic {
-
-class TunDevicePacketExchanger : public QbonePacketExchanger {
- public:
- class StatsInterface {
- public:
- StatsInterface() = default;
-
- StatsInterface(const StatsInterface&) = delete;
- StatsInterface& operator=(const StatsInterface&) = delete;
-
- StatsInterface(StatsInterface&&) = delete;
- StatsInterface& operator=(StatsInterface&&) = delete;
-
- virtual ~StatsInterface() = default;
-
- virtual void OnPacketRead(size_t count) = 0;
- virtual void OnPacketWritten(size_t count) = 0;
- virtual void OnReadError(std::string* error) = 0;
- virtual void OnWriteError(std::string* error) = 0;
-
- ABSL_MUST_USE_RESULT virtual int64_t PacketsRead() const = 0;
- ABSL_MUST_USE_RESULT virtual int64_t PacketsWritten() const = 0;
- };
-
- // |mtu| is the mtu of the TUN device.
- // |kernel| is not owned but should out live objects of this class.
- // |visitor| is not owned but should out live objects of this class.
- // |max_pending_packets| controls the number of packets to be queued should
- // the TUN device become blocked.
- // |stats| is notified about packet read/write statistics. It is not owned,
- // but should outlive objects of this class.
- TunDevicePacketExchanger(size_t mtu, KernelInterface* kernel,
- NetlinkInterface* netlink,
- QbonePacketExchanger::Visitor* visitor,
- size_t max_pending_packets, bool is_tap,
- StatsInterface* stats, absl::string_view ifname);
-
- void set_file_descriptor(int fd);
-
- ABSL_MUST_USE_RESULT const StatsInterface* stats_interface() const;
-
- private:
- // From QbonePacketExchanger.
- std::unique_ptr<QuicData> ReadPacket(bool* blocked,
- std::string* error) override;
-
- // From QbonePacketExchanger.
- bool WritePacket(const char* packet,
- size_t size,
- bool* blocked,
- std::string* error) override;
-
- std::unique_ptr<QuicData> ApplyL2Headers(const QuicData& l3_packet);
-
- std::unique_ptr<QuicData> ConsumeL2Headers(const QuicData& l2_packet);
-
- int fd_ = -1;
- size_t mtu_;
- KernelInterface* kernel_;
- NetlinkInterface* netlink_;
- const std::string ifname_;
-
- const bool is_tap_;
- uint8_t tap_mac_[ETH_ALEN]{};
- bool mac_initialized_ = false;
-
- StatsInterface* stats_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_QBONE_BONNET_TUN_DEVICE_PACKET_EXCHANGER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/qbone/bonnet/tun_device_packet_exchanger_test.cc b/chromium/net/third_party/quiche/src/quic/qbone/bonnet/tun_device_packet_exchanger_test.cc
deleted file mode 100644
index 8abf9a35fe6..00000000000
--- a/chromium/net/third_party/quiche/src/quic/qbone/bonnet/tun_device_packet_exchanger_test.cc
+++ /dev/null
@@ -1,119 +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 "quic/qbone/bonnet/tun_device_packet_exchanger.h"
-
-#include "quic/platform/api/quic_test.h"
-#include "quic/qbone/bonnet/mock_packet_exchanger_stats_interface.h"
-#include "quic/qbone/mock_qbone_client.h"
-#include "quic/qbone/platform/mock_kernel.h"
-
-namespace quic {
-namespace {
-
-const size_t kMtu = 1000;
-const size_t kMaxPendingPackets = 5;
-const int kFd = 15;
-
-using ::testing::_;
-using ::testing::Invoke;
-using ::testing::StrEq;
-using ::testing::StrictMock;
-
-class MockVisitor : public QbonePacketExchanger::Visitor {
- public:
- MOCK_METHOD(void, OnReadError, (const std::string&), (override));
- MOCK_METHOD(void, OnWriteError, (const std::string&), (override));
-};
-
-class TunDevicePacketExchangerTest : public QuicTest {
- protected:
- TunDevicePacketExchangerTest()
- : exchanger_(kMtu, &mock_kernel_, nullptr, &mock_visitor_,
- kMaxPendingPackets, false, &mock_stats_,
- absl::string_view()) {
- exchanger_.set_file_descriptor(kFd);
- }
-
- ~TunDevicePacketExchangerTest() override = default;
-
- MockKernel mock_kernel_;
- StrictMock<MockVisitor> mock_visitor_;
- StrictMock<MockQboneClient> mock_client_;
- StrictMock<MockPacketExchangerStatsInterface> mock_stats_;
- TunDevicePacketExchanger exchanger_;
-};
-
-TEST_F(TunDevicePacketExchangerTest, WritePacketReturnsFalseOnError) {
- std::string packet = "fake packet";
- EXPECT_CALL(mock_kernel_, write(kFd, _, packet.size()))
- .WillOnce(Invoke([](int fd, const void* buf, size_t count) {
- errno = ECOMM;
- return -1;
- }));
-
- EXPECT_CALL(mock_visitor_, OnWriteError(_));
- exchanger_.WritePacketToNetwork(packet.data(), packet.size());
-}
-
-TEST_F(TunDevicePacketExchangerTest,
- WritePacketReturnFalseAndBlockedOnBlockedTunnel) {
- std::string packet = "fake packet";
- EXPECT_CALL(mock_kernel_, write(kFd, _, packet.size()))
- .WillOnce(Invoke([](int fd, const void* buf, size_t count) {
- errno = EAGAIN;
- return -1;
- }));
-
- EXPECT_CALL(mock_stats_, OnWriteError(_)).Times(1);
- exchanger_.WritePacketToNetwork(packet.data(), packet.size());
-}
-
-TEST_F(TunDevicePacketExchangerTest, WritePacketReturnsTrueOnSuccessfulWrite) {
- std::string packet = "fake packet";
- EXPECT_CALL(mock_kernel_, write(kFd, _, packet.size()))
- .WillOnce(Invoke([packet](int fd, const void* buf, size_t count) {
- EXPECT_THAT(reinterpret_cast<const char*>(buf), StrEq(packet));
- return count;
- }));
-
- EXPECT_CALL(mock_stats_, OnPacketWritten(_)).Times(1);
- exchanger_.WritePacketToNetwork(packet.data(), packet.size());
-}
-
-TEST_F(TunDevicePacketExchangerTest, ReadPacketReturnsNullOnError) {
- EXPECT_CALL(mock_kernel_, read(kFd, _, kMtu))
- .WillOnce(Invoke([](int fd, void* buf, size_t count) {
- errno = ECOMM;
- return -1;
- }));
- EXPECT_CALL(mock_visitor_, OnReadError(_));
- exchanger_.ReadAndDeliverPacket(&mock_client_);
-}
-
-TEST_F(TunDevicePacketExchangerTest, ReadPacketReturnsNullOnBlockedRead) {
- EXPECT_CALL(mock_kernel_, read(kFd, _, kMtu))
- .WillOnce(Invoke([](int fd, void* buf, size_t count) {
- errno = EAGAIN;
- return -1;
- }));
- EXPECT_CALL(mock_stats_, OnReadError(_)).Times(1);
- EXPECT_FALSE(exchanger_.ReadAndDeliverPacket(&mock_client_));
-}
-
-TEST_F(TunDevicePacketExchangerTest,
- ReadPacketReturnsThePacketOnSuccessfulRead) {
- std::string packet = "fake_packet";
- EXPECT_CALL(mock_kernel_, read(kFd, _, kMtu))
- .WillOnce(Invoke([packet](int fd, void* buf, size_t count) {
- memcpy(buf, packet.data(), packet.size());
- return packet.size();
- }));
- EXPECT_CALL(mock_client_, ProcessPacketFromNetwork(StrEq(packet)));
- EXPECT_CALL(mock_stats_, OnPacketRead(_)).Times(1);
- EXPECT_TRUE(exchanger_.ReadAndDeliverPacket(&mock_client_));
-}
-
-} // namespace
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/qbone/bonnet/tun_device_test.cc b/chromium/net/third_party/quiche/src/quic/qbone/bonnet/tun_device_test.cc
deleted file mode 100644
index 18b818ccd51..00000000000
--- a/chromium/net/third_party/quiche/src/quic/qbone/bonnet/tun_device_test.cc
+++ /dev/null
@@ -1,211 +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 "quic/qbone/bonnet/tun_device.h"
-
-#include <linux/if.h>
-#include <linux/if_tun.h>
-#include <sys/ioctl.h>
-
-#include "quic/platform/api/quic_test.h"
-#include "quic/qbone/platform/mock_kernel.h"
-
-namespace quic {
-namespace {
-
-using ::testing::_;
-using ::testing::AnyNumber;
-using ::testing::Invoke;
-using ::testing::Return;
-using ::testing::StrEq;
-using ::testing::Unused;
-
-const char kDeviceName[] = "tun0";
-const int kSupportedFeatures =
- IFF_TUN | IFF_TAP | IFF_MULTI_QUEUE | IFF_ONE_QUEUE | IFF_NO_PI;
-
-// Quite a bit of EXPECT_CALL().Times(AnyNumber()).WillRepeatedly() are used to
-// make sure we can correctly set common expectations and override the
-// expectation with later call to EXPECT_CALL(). ON_CALL cannot be used here
-// since when EPXECT_CALL overrides ON_CALL, it ignores the parameter matcher
-// which results in unexpected call even if ON_CALL exists.
-class TunDeviceTest : public QuicTest {
- protected:
- void SetUp() override {
- EXPECT_CALL(mock_kernel_, socket(AF_INET6, _, _))
- .Times(AnyNumber())
- .WillRepeatedly(Invoke([this](Unused, Unused, Unused) {
- EXPECT_CALL(mock_kernel_, close(next_fd_)).WillOnce(Return(0));
- return next_fd_++;
- }));
- }
-
- // Set the expectations for calling Init().
- void SetInitExpectations(int mtu, bool persist) {
- EXPECT_CALL(mock_kernel_, open(StrEq("/dev/net/tun"), _))
- .Times(AnyNumber())
- .WillRepeatedly(Invoke([this](Unused, Unused) {
- EXPECT_CALL(mock_kernel_, close(next_fd_)).WillOnce(Return(0));
- return next_fd_++;
- }));
- EXPECT_CALL(mock_kernel_, ioctl(_, TUNGETFEATURES, _))
- .Times(AnyNumber())
- .WillRepeatedly(Invoke([](Unused, Unused, void* argp) {
- auto* actual_flags = reinterpret_cast<int*>(argp);
- *actual_flags = kSupportedFeatures;
- return 0;
- }));
- EXPECT_CALL(mock_kernel_, ioctl(_, TUNSETIFF, _))
- .Times(AnyNumber())
- .WillRepeatedly(Invoke([](Unused, Unused, void* argp) {
- auto* ifr = reinterpret_cast<struct ifreq*>(argp);
- EXPECT_EQ(IFF_TUN | IFF_MULTI_QUEUE | IFF_NO_PI, ifr->ifr_flags);
- EXPECT_THAT(ifr->ifr_name, StrEq(kDeviceName));
- return 0;
- }));
- EXPECT_CALL(mock_kernel_, ioctl(_, TUNSETPERSIST, _))
- .Times(AnyNumber())
- .WillRepeatedly(Invoke([persist](Unused, Unused, void* argp) {
- auto* ifr = reinterpret_cast<struct ifreq*>(argp);
- if (persist) {
- EXPECT_THAT(ifr->ifr_name, StrEq(kDeviceName));
- } else {
- EXPECT_EQ(nullptr, ifr);
- }
- return 0;
- }));
- EXPECT_CALL(mock_kernel_, ioctl(_, SIOCSIFMTU, _))
- .Times(AnyNumber())
- .WillRepeatedly(Invoke([mtu](Unused, Unused, void* argp) {
- auto* ifr = reinterpret_cast<struct ifreq*>(argp);
- EXPECT_EQ(mtu, ifr->ifr_mtu);
- EXPECT_THAT(ifr->ifr_name, StrEq(kDeviceName));
- return 0;
- }));
- }
-
- // Expect that Up() will be called. Force the call to fail when fail == true.
- void ExpectUp(bool fail) {
- EXPECT_CALL(mock_kernel_, ioctl(_, SIOCSIFFLAGS, _))
- .WillOnce(Invoke([fail](Unused, Unused, void* argp) {
- auto* ifr = reinterpret_cast<struct ifreq*>(argp);
- EXPECT_TRUE(ifr->ifr_flags & IFF_UP);
- EXPECT_THAT(ifr->ifr_name, StrEq(kDeviceName));
- if (fail) {
- return -1;
- } else {
- return 0;
- }
- }));
- }
-
- // Expect that Down() will be called *after* the interface is up. Force the
- // call to fail when fail == true.
- void ExpectDown(bool fail) {
- EXPECT_CALL(mock_kernel_, ioctl(_, SIOCSIFFLAGS, _))
- .WillOnce(Invoke([fail](Unused, Unused, void* argp) {
- auto* ifr = reinterpret_cast<struct ifreq*>(argp);
- EXPECT_FALSE(ifr->ifr_flags & IFF_UP);
- EXPECT_THAT(ifr->ifr_name, StrEq(kDeviceName));
- if (fail) {
- return -1;
- } else {
- return 0;
- }
- }));
- }
-
- MockKernel mock_kernel_;
- int next_fd_ = 100;
-};
-
-// A TunTapDevice can be initialized and up
-TEST_F(TunDeviceTest, BasicWorkFlow) {
- SetInitExpectations(/* mtu = */ 1500, /* persist = */ false);
- TunTapDevice tun_device(kDeviceName, 1500, false, true, false, &mock_kernel_);
- EXPECT_TRUE(tun_device.Init());
- EXPECT_GT(tun_device.GetFileDescriptor(), -1);
-
- ExpectUp(/* fail = */ false);
- EXPECT_TRUE(tun_device.Up());
- ExpectDown(/* fail = */ false);
-}
-
-TEST_F(TunDeviceTest, FailToOpenTunDevice) {
- SetInitExpectations(/* mtu = */ 1500, /* persist = */ false);
- EXPECT_CALL(mock_kernel_, open(StrEq("/dev/net/tun"), _))
- .WillOnce(Return(-1));
- TunTapDevice tun_device(kDeviceName, 1500, false, true, false, &mock_kernel_);
- EXPECT_FALSE(tun_device.Init());
- EXPECT_EQ(tun_device.GetFileDescriptor(), -1);
- ExpectDown(false);
-}
-
-TEST_F(TunDeviceTest, FailToCheckFeature) {
- SetInitExpectations(/* mtu = */ 1500, /* persist = */ false);
- EXPECT_CALL(mock_kernel_, ioctl(_, TUNGETFEATURES, _)).WillOnce(Return(-1));
- TunTapDevice tun_device(kDeviceName, 1500, false, true, false, &mock_kernel_);
- EXPECT_FALSE(tun_device.Init());
- EXPECT_EQ(tun_device.GetFileDescriptor(), -1);
- ExpectDown(false);
-}
-
-TEST_F(TunDeviceTest, TooFewFeature) {
- SetInitExpectations(/* mtu = */ 1500, /* persist = */ false);
- EXPECT_CALL(mock_kernel_, ioctl(_, TUNGETFEATURES, _))
- .WillOnce(Invoke([](Unused, Unused, void* argp) {
- int* actual_features = reinterpret_cast<int*>(argp);
- *actual_features = IFF_TUN | IFF_ONE_QUEUE;
- return 0;
- }));
- TunTapDevice tun_device(kDeviceName, 1500, false, true, false, &mock_kernel_);
- EXPECT_FALSE(tun_device.Init());
- EXPECT_EQ(tun_device.GetFileDescriptor(), -1);
- ExpectDown(false);
-}
-
-TEST_F(TunDeviceTest, FailToSetFlag) {
- SetInitExpectations(/* mtu = */ 1500, /* persist = */ true);
- EXPECT_CALL(mock_kernel_, ioctl(_, TUNSETIFF, _)).WillOnce(Return(-1));
- TunTapDevice tun_device(kDeviceName, 1500, true, true, false, &mock_kernel_);
- EXPECT_FALSE(tun_device.Init());
- EXPECT_EQ(tun_device.GetFileDescriptor(), -1);
-}
-
-TEST_F(TunDeviceTest, FailToPersistDevice) {
- SetInitExpectations(/* mtu = */ 1500, /* persist = */ true);
- EXPECT_CALL(mock_kernel_, ioctl(_, TUNSETPERSIST, _)).WillOnce(Return(-1));
- TunTapDevice tun_device(kDeviceName, 1500, true, true, false, &mock_kernel_);
- EXPECT_FALSE(tun_device.Init());
- EXPECT_EQ(tun_device.GetFileDescriptor(), -1);
-}
-
-TEST_F(TunDeviceTest, FailToOpenSocket) {
- SetInitExpectations(/* mtu = */ 1500, /* persist = */ true);
- EXPECT_CALL(mock_kernel_, socket(AF_INET6, _, _)).WillOnce(Return(-1));
- TunTapDevice tun_device(kDeviceName, 1500, true, true, false, &mock_kernel_);
- EXPECT_FALSE(tun_device.Init());
- EXPECT_EQ(tun_device.GetFileDescriptor(), -1);
-}
-
-TEST_F(TunDeviceTest, FailToSetMtu) {
- SetInitExpectations(/* mtu = */ 1500, /* persist = */ true);
- EXPECT_CALL(mock_kernel_, ioctl(_, SIOCSIFMTU, _)).WillOnce(Return(-1));
- TunTapDevice tun_device(kDeviceName, 1500, true, true, false, &mock_kernel_);
- EXPECT_FALSE(tun_device.Init());
- EXPECT_EQ(tun_device.GetFileDescriptor(), -1);
-}
-
-TEST_F(TunDeviceTest, FailToUp) {
- SetInitExpectations(/* mtu = */ 1500, /* persist = */ true);
- TunTapDevice tun_device(kDeviceName, 1500, true, true, false, &mock_kernel_);
- EXPECT_TRUE(tun_device.Init());
- EXPECT_GT(tun_device.GetFileDescriptor(), -1);
-
- ExpectUp(/* fail = */ true);
- EXPECT_FALSE(tun_device.Up());
-}
-
-} // namespace
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/qbone/mock_qbone_client.h b/chromium/net/third_party/quiche/src/quic/qbone/mock_qbone_client.h
deleted file mode 100644
index 3b84d556324..00000000000
--- a/chromium/net/third_party/quiche/src/quic/qbone/mock_qbone_client.h
+++ /dev/null
@@ -1,24 +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_QBONE_MOCK_QBONE_CLIENT_H_
-#define QUICHE_QUIC_QBONE_MOCK_QBONE_CLIENT_H_
-
-#include "absl/strings/string_view.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/qbone/qbone_client_interface.h"
-
-namespace quic {
-
-class MockQboneClient : public QboneClientInterface {
- public:
- MOCK_METHOD(void,
- ProcessPacketFromNetwork,
- (absl::string_view packet),
- (override));
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_QBONE_MOCK_QBONE_CLIENT_H_
diff --git a/chromium/net/third_party/quiche/src/quic/qbone/mock_qbone_server_session.h b/chromium/net/third_party/quiche/src/quic/qbone/mock_qbone_server_session.h
deleted file mode 100644
index 8d4f64eda24..00000000000
--- a/chromium/net/third_party/quiche/src/quic/qbone/mock_qbone_server_session.h
+++ /dev/null
@@ -1,36 +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_QBONE_MOCK_QBONE_SERVER_SESSION_H_
-#define QUICHE_QUIC_QBONE_MOCK_QBONE_SERVER_SESSION_H_
-
-#include "quic/platform/api/quic_test.h"
-#include "quic/qbone/qbone_server_session.h"
-
-namespace quic {
-
-class MockQboneServerSession : public QboneServerSession {
- public:
- explicit MockQboneServerSession(QuicConnection* connection)
- : QboneServerSession(CurrentSupportedVersions(),
- connection,
- /*owner=*/nullptr,
- /*config=*/{},
- /*quic_crypto_server_config=*/nullptr,
- /*compressed_certs_cache=*/nullptr,
- /*writer=*/nullptr,
- /*self_ip=*/QuicIpAddress::Loopback6(),
- /*client_ip=*/QuicIpAddress::Loopback6(),
- /*client_ip_subnet_length=*/0,
- /*handler=*/nullptr) {}
-
- MOCK_METHOD(bool, SendClientRequest, (const QboneClientRequest&), (override));
-
- MOCK_METHOD(void, ProcessPacketFromNetwork, (absl::string_view), (override));
- MOCK_METHOD(void, ProcessPacketFromPeer, (absl::string_view), (override));
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_QBONE_MOCK_QBONE_SERVER_SESSION_H_
diff --git a/chromium/net/third_party/quiche/src/quic/qbone/platform/icmp_packet.cc b/chromium/net/third_party/quiche/src/quic/qbone/platform/icmp_packet.cc
deleted file mode 100644
index 0acd71216bf..00000000000
--- a/chromium/net/third_party/quiche/src/quic/qbone/platform/icmp_packet.cc
+++ /dev/null
@@ -1,90 +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 "quic/qbone/platform/icmp_packet.h"
-
-#include <netinet/ip6.h>
-
-#include "absl/strings/string_view.h"
-#include "quic/qbone/platform/internet_checksum.h"
-#include "common/quiche_endian.h"
-
-namespace quic {
-namespace {
-
-constexpr size_t kIPv6AddressSize = sizeof(in6_addr);
-constexpr size_t kIPv6HeaderSize = sizeof(ip6_hdr);
-constexpr size_t kICMPv6HeaderSize = sizeof(icmp6_hdr);
-constexpr size_t kIPv6MinPacketSize = 1280;
-
-// Hop limit set to 255 to satisfy:
-// https://datatracker.ietf.org/doc/html/rfc4861#section-11.2
-constexpr size_t kIcmpTtl = 255;
-constexpr size_t kICMPv6BodyMaxSize =
- kIPv6MinPacketSize - kIPv6HeaderSize - kICMPv6HeaderSize;
-
-struct ICMPv6Packet {
- ip6_hdr ip_header;
- icmp6_hdr icmp_header;
- uint8_t body[kICMPv6BodyMaxSize];
-};
-
-// pseudo header as described in RFC 2460 Section 8.1 (excluding addresses)
-struct IPv6PseudoHeader {
- uint32_t payload_size{};
- uint8_t zeros[3] = {0, 0, 0};
- uint8_t next_header = IPPROTO_ICMPV6;
-};
-
-} // namespace
-
-void CreateIcmpPacket(in6_addr src,
- in6_addr dst,
- const icmp6_hdr& icmp_header,
- absl::string_view body,
- const std::function<void(absl::string_view)>& cb) {
- const size_t body_size = std::min(body.size(), kICMPv6BodyMaxSize);
- const size_t payload_size = kICMPv6HeaderSize + body_size;
-
- ICMPv6Packet icmp_packet{};
- // Set version to 6.
- icmp_packet.ip_header.ip6_vfc = 0x6 << 4;
- // Set the payload size, protocol and TTL.
- icmp_packet.ip_header.ip6_plen =
- quiche::QuicheEndian::HostToNet16(payload_size);
- icmp_packet.ip_header.ip6_nxt = IPPROTO_ICMPV6;
- icmp_packet.ip_header.ip6_hops = kIcmpTtl;
- // Set the source address to the specified self IP.
- icmp_packet.ip_header.ip6_src = src;
- icmp_packet.ip_header.ip6_dst = dst;
-
- icmp_packet.icmp_header = icmp_header;
- // Per RFC 4443 Section 2.3, set checksum field to 0 prior to computing it
- icmp_packet.icmp_header.icmp6_cksum = 0;
-
- IPv6PseudoHeader pseudo_header{};
- pseudo_header.payload_size = quiche::QuicheEndian::HostToNet32(payload_size);
-
- InternetChecksum checksum;
- // Pseudoheader.
- checksum.Update(icmp_packet.ip_header.ip6_src.s6_addr, kIPv6AddressSize);
- checksum.Update(icmp_packet.ip_header.ip6_dst.s6_addr, kIPv6AddressSize);
- checksum.Update(reinterpret_cast<char*>(&pseudo_header),
- sizeof(pseudo_header));
- // ICMP header.
- checksum.Update(reinterpret_cast<const char*>(&icmp_packet.icmp_header),
- sizeof(icmp_packet.icmp_header));
- // Body.
- checksum.Update(body.data(), body_size);
- icmp_packet.icmp_header.icmp6_cksum = checksum.Value();
-
- memcpy(icmp_packet.body, body.data(), body_size);
-
- const char* packet = reinterpret_cast<char*>(&icmp_packet);
- const size_t packet_size = offsetof(ICMPv6Packet, body) + body_size;
-
- cb(absl::string_view(packet, packet_size));
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/qbone/platform/icmp_packet.h b/chromium/net/third_party/quiche/src/quic/qbone/platform/icmp_packet.h
deleted file mode 100644
index f03f78b05bd..00000000000
--- a/chromium/net/third_party/quiche/src/quic/qbone/platform/icmp_packet.h
+++ /dev/null
@@ -1,29 +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_QBONE_PLATFORM_ICMP_PACKET_H_
-#define QUICHE_QUIC_QBONE_PLATFORM_ICMP_PACKET_H_
-
-#include <netinet/icmp6.h>
-#include <netinet/in.h>
-
-#include <functional>
-
-#include "absl/strings/string_view.h"
-#include "quic/platform/api/quic_ip_address.h"
-
-namespace quic {
-
-// Creates an ICMPv6 packet, returning a packed string representation of the
-// packet to |cb|. The resulting packet is given to a callback because it's
-// stack allocated inside CreateIcmpPacket.
-void CreateIcmpPacket(in6_addr src,
- in6_addr dst,
- const icmp6_hdr& icmp_header,
- absl::string_view body,
- const std::function<void(absl::string_view)>& cb);
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_QBONE_PLATFORM_ICMP_PACKET_H_
diff --git a/chromium/net/third_party/quiche/src/quic/qbone/platform/icmp_packet_test.cc b/chromium/net/third_party/quiche/src/quic/qbone/platform/icmp_packet_test.cc
deleted file mode 100644
index 1e6a2e92a77..00000000000
--- a/chromium/net/third_party/quiche/src/quic/qbone/platform/icmp_packet_test.cc
+++ /dev/null
@@ -1,128 +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 "quic/qbone/platform/icmp_packet.h"
-
-#include <netinet/ip6.h>
-
-#include <cstdint>
-
-#include "absl/strings/string_view.h"
-#include "quic/platform/api/quic_test.h"
-#include "common/quiche_text_utils.h"
-
-namespace quic {
-namespace {
-
-constexpr char kReferenceSourceAddress[] = "fe80:1:2:3:4::1";
-constexpr char kReferenceDestinationAddress[] = "fe80:4:3:2:1::1";
-
-// clang-format off
-constexpr uint8_t kReferenceICMPMessageBody[] {
- 0xd2, 0x61, 0x29, 0x5b, 0x00, 0x00, 0x00, 0x00,
- 0x0d, 0x59, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
- 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
- 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
- 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
- 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37
-};
-
-constexpr uint8_t kReferenceICMPPacket[] = {
- // START IPv6 Header
- // IPv6 with zero TOS and flow label.
- 0x60, 0x00, 0x00, 0x00,
- // Payload is 64 bytes
- 0x00, 0x40,
- // Next header is 58
- 0x3a,
- // Hop limit is 255
- 0xFF,
- // Source address of fe80:1:2:3:4::1
- 0xfe, 0x80, 0x00, 0x01, 0x00, 0x02, 0x00, 0x03,
- 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
- // Destination address of fe80:4:3:2:1::1
- 0xfe, 0x80, 0x00, 0x04, 0x00, 0x03, 0x00, 0x02,
- 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
- // END IPv6 Header
- // START ICMPv6 Header
- // Echo Request, zero code
- 0x80, 0x00,
- // Checksum
- 0xec, 0x00,
- // Identifier
- 0xcb, 0x82,
- // Sequence Number
- 0x00, 0x01,
- // END ICMPv6 Header
- // Message body
- 0xd2, 0x61, 0x29, 0x5b, 0x00, 0x00, 0x00, 0x00,
- 0x0d, 0x59, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
- 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
- 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
- 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
- 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37
-};
-// clang-format on
-
-} // namespace
-
-TEST(IcmpPacketTest, CreatedPacketMatchesReference) {
- QuicIpAddress src;
- ASSERT_TRUE(src.FromString(kReferenceSourceAddress));
- in6_addr src_addr;
- memcpy(src_addr.s6_addr, src.ToPackedString().data(), sizeof(in6_addr));
-
- QuicIpAddress dst;
- ASSERT_TRUE(dst.FromString(kReferenceDestinationAddress));
- in6_addr dst_addr;
- memcpy(dst_addr.s6_addr, dst.ToPackedString().data(), sizeof(in6_addr));
-
- icmp6_hdr icmp_header{};
- icmp_header.icmp6_type = ICMP6_ECHO_REQUEST;
- icmp_header.icmp6_id = 0x82cb;
- icmp_header.icmp6_seq = 0x0100;
-
- absl::string_view message_body = absl::string_view(
- reinterpret_cast<const char*>(kReferenceICMPMessageBody), 56);
- absl::string_view expected_packet = absl::string_view(
- reinterpret_cast<const char*>(kReferenceICMPPacket), 104);
- CreateIcmpPacket(src_addr, dst_addr, icmp_header, message_body,
- [&expected_packet](absl::string_view packet) {
- QUIC_LOG(INFO) << quiche::QuicheTextUtils::HexDump(packet);
- ASSERT_EQ(packet, expected_packet);
- });
-}
-
-TEST(IcmpPacketTest, NonZeroChecksumIsIgnored) {
- QuicIpAddress src;
- ASSERT_TRUE(src.FromString(kReferenceSourceAddress));
- in6_addr src_addr;
- memcpy(src_addr.s6_addr, src.ToPackedString().data(), sizeof(in6_addr));
-
- QuicIpAddress dst;
- ASSERT_TRUE(dst.FromString(kReferenceDestinationAddress));
- in6_addr dst_addr;
- memcpy(dst_addr.s6_addr, dst.ToPackedString().data(), sizeof(in6_addr));
-
- icmp6_hdr icmp_header{};
- icmp_header.icmp6_type = ICMP6_ECHO_REQUEST;
- icmp_header.icmp6_id = 0x82cb;
- icmp_header.icmp6_seq = 0x0100;
- // Set the checksum to a bogus value
- icmp_header.icmp6_cksum = 0x1234;
-
- absl::string_view message_body = absl::string_view(
- reinterpret_cast<const char*>(kReferenceICMPMessageBody), 56);
- absl::string_view expected_packet = absl::string_view(
- reinterpret_cast<const char*>(kReferenceICMPPacket), 104);
- CreateIcmpPacket(src_addr, dst_addr, icmp_header, message_body,
- [&expected_packet](absl::string_view packet) {
- QUIC_LOG(INFO) << quiche::QuicheTextUtils::HexDump(packet);
- ASSERT_EQ(packet, expected_packet);
- });
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/qbone/platform/internet_checksum.cc b/chromium/net/third_party/quiche/src/quic/qbone/platform/internet_checksum.cc
deleted file mode 100644
index 3290764082a..00000000000
--- a/chromium/net/third_party/quiche/src/quic/qbone/platform/internet_checksum.cc
+++ /dev/null
@@ -1,31 +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 "quic/qbone/platform/internet_checksum.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);
- }
- if (current < data + size) {
- accumulator_ += *reinterpret_cast<const uint8_t*>(current);
- }
-}
-
-void InternetChecksum::Update(const uint8_t* data, size_t size) {
- Update(reinterpret_cast<const char*>(data), size);
-}
-
-uint16_t InternetChecksum::Value() const {
- uint32_t total = accumulator_;
- while (total & 0xffff0000u) {
- total = (total >> 16u) + (total & 0xffffu);
- }
- return ~static_cast<uint16_t>(total);
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/qbone/platform/internet_checksum.h b/chromium/net/third_party/quiche/src/quic/qbone/platform/internet_checksum.h
deleted file mode 100644
index 85d24155f29..00000000000
--- a/chromium/net/third_party/quiche/src/quic/qbone/platform/internet_checksum.h
+++ /dev/null
@@ -1,32 +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_QBONE_PLATFORM_INTERNET_CHECKSUM_H_
-#define QUICHE_QUIC_QBONE_PLATFORM_INTERNET_CHECKSUM_H_
-
-#include <cstddef>
-#include <cstdint>
-
-namespace quic {
-
-// Incrementally compute an Internet header checksum as described in RFC 1071.
-class InternetChecksum {
- public:
- // Update the checksum with the specified data. Note that while the checksum
- // is commutative, the data has to be supplied in the units of two-byte words.
- // If there is an extra byte at the end, the function has to be called on it
- // last.
- void Update(const char* data, size_t size);
-
- void Update(const uint8_t* data, size_t size);
-
- uint16_t Value() const;
-
- private:
- uint32_t accumulator_ = 0;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_QBONE_PLATFORM_INTERNET_CHECKSUM_H_
diff --git a/chromium/net/third_party/quiche/src/quic/qbone/platform/internet_checksum_test.cc b/chromium/net/third_party/quiche/src/quic/qbone/platform/internet_checksum_test.cc
deleted file mode 100644
index 7da04bdcbeb..00000000000
--- a/chromium/net/third_party/quiche/src/quic/qbone/platform/internet_checksum_test.cc
+++ /dev/null
@@ -1,67 +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 "quic/qbone/platform/internet_checksum.h"
-
-#include "quic/platform/api/quic_test.h"
-
-namespace quic {
-namespace {
-
-// From the Numerical Example described in RFC 1071
-// https://tools.ietf.org/html/rfc1071#section-3
-TEST(InternetChecksumTest, MatchesRFC1071Example) {
- uint8_t data[] = {0x00, 0x01, 0xf2, 0x03, 0xf4, 0xf5, 0xf6, 0xf7};
-
- InternetChecksum checksum;
- checksum.Update(data, 8);
- uint16_t result = checksum.Value();
- auto* result_bytes = reinterpret_cast<uint8_t*>(&result);
- ASSERT_EQ(0x22, result_bytes[0]);
- ASSERT_EQ(0x0d, result_bytes[1]);
-}
-
-// Same as above, except 7 bytes. Should behave as if there was an 8th byte
-// that equals 0.
-TEST(InternetChecksumTest, MatchesRFC1071ExampleWithOddByteCount) {
- uint8_t data[] = {0x00, 0x01, 0xf2, 0x03, 0xf4, 0xf5, 0xf6};
-
- InternetChecksum checksum;
- checksum.Update(data, 7);
- uint16_t result = checksum.Value();
- auto* result_bytes = reinterpret_cast<uint8_t*>(&result);
- ASSERT_EQ(0x23, result_bytes[0]);
- ASSERT_EQ(0x04, result_bytes[1]);
-}
-
-// From the example described at:
-// http://www.cs.berkeley.edu/~kfall/EE122/lec06/tsld023.htm
-TEST(InternetChecksumTest, MatchesBerkleyExample) {
- uint8_t data[] = {0xe3, 0x4f, 0x23, 0x96, 0x44, 0x27, 0x99, 0xf3};
-
- InternetChecksum checksum;
- checksum.Update(data, 8);
- uint16_t result = checksum.Value();
- auto* result_bytes = reinterpret_cast<uint8_t*>(&result);
- ASSERT_EQ(0x1a, result_bytes[0]);
- ASSERT_EQ(0xff, result_bytes[1]);
-}
-
-TEST(InternetChecksumTest, ChecksumRequiringMultipleCarriesInLittleEndian) {
- uint8_t data[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x02, 0x00};
-
- // Data will accumulate to 0x0002FFFF
- // Summing lower and upper halves gives 0x00010001
- // Second sum of lower and upper halves gives 0x0002
- // One's complement gives 0xfffd, or [0xfd, 0xff] in network byte order
- InternetChecksum checksum;
- checksum.Update(data, 8);
- uint16_t result = checksum.Value();
- auto* result_bytes = reinterpret_cast<uint8_t*>(&result);
- EXPECT_EQ(0xfd, result_bytes[0]);
- EXPECT_EQ(0xff, result_bytes[1]);
-}
-
-} // namespace
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/qbone/platform/ip_range.cc b/chromium/net/third_party/quiche/src/quic/qbone/platform/ip_range.cc
deleted file mode 100644
index 97df5cff052..00000000000
--- a/chromium/net/third_party/quiche/src/quic/qbone/platform/ip_range.cc
+++ /dev/null
@@ -1,101 +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 "quic/qbone/platform/ip_range.h"
-
-#include "common/quiche_endian.h"
-
-namespace quic {
-
-namespace {
-
-constexpr size_t kIPv4Size = 32;
-constexpr size_t kIPv6Size = 128;
-
-QuicIpAddress TruncateToLength(const QuicIpAddress& input,
- size_t* prefix_length) {
- QuicIpAddress output;
- if (input.IsIPv4()) {
- if (*prefix_length > kIPv4Size) {
- *prefix_length = kIPv4Size;
- return input;
- }
- uint32_t raw_address =
- *reinterpret_cast<const uint32_t*>(input.ToPackedString().data());
- raw_address = quiche::QuicheEndian::NetToHost32(raw_address);
- raw_address &= ~0U << (kIPv4Size - *prefix_length);
- raw_address = quiche::QuicheEndian::HostToNet32(raw_address);
- output.FromPackedString(reinterpret_cast<const char*>(&raw_address),
- sizeof(raw_address));
- return output;
- }
- if (input.IsIPv6()) {
- if (*prefix_length > kIPv6Size) {
- *prefix_length = kIPv6Size;
- return input;
- }
- uint64_t raw_address[2];
- memcpy(raw_address, input.ToPackedString().data(), sizeof(raw_address));
- // raw_address[0] holds higher 8 bytes in big endian and raw_address[1]
- // holds lower 8 bytes. Converting each to little endian for us to mask bits
- // out.
- // The endianess between raw_address[0] and raw_address[1] is handled
- // explicitly by handling lower and higher bytes separately.
- raw_address[0] = quiche::QuicheEndian::NetToHost64(raw_address[0]);
- raw_address[1] = quiche::QuicheEndian::NetToHost64(raw_address[1]);
- if (*prefix_length <= kIPv6Size / 2) {
- raw_address[0] &= ~uint64_t{0} << (kIPv6Size / 2 - *prefix_length);
- raw_address[1] = 0;
- } else {
- raw_address[1] &= ~uint64_t{0} << (kIPv6Size - *prefix_length);
- }
- raw_address[0] = quiche::QuicheEndian::HostToNet64(raw_address[0]);
- raw_address[1] = quiche::QuicheEndian::HostToNet64(raw_address[1]);
- output.FromPackedString(reinterpret_cast<const char*>(raw_address),
- sizeof(raw_address));
- return output;
- }
- return output;
-}
-
-} // namespace
-
-IpRange::IpRange(const QuicIpAddress& prefix, size_t prefix_length)
- : prefix_(prefix), prefix_length_(prefix_length) {
- prefix_ = TruncateToLength(prefix_, &prefix_length_);
-}
-
-bool IpRange::operator==(IpRange other) const {
- return prefix_ == other.prefix_ && prefix_length_ == other.prefix_length_;
-}
-
-bool IpRange::operator!=(IpRange other) const {
- return !(*this == other);
-}
-
-bool IpRange::FromString(const std::string& range) {
- size_t slash_pos = range.find('/');
- if (slash_pos == std::string::npos) {
- return false;
- }
- QuicIpAddress prefix;
- bool success = prefix.FromString(range.substr(0, slash_pos));
- if (!success) {
- return false;
- }
- uint64_t num_processed = 0;
- size_t prefix_length = std::stoi(range.substr(slash_pos + 1), &num_processed);
- if (num_processed + 1 + slash_pos != range.length()) {
- return false;
- }
- prefix_ = TruncateToLength(prefix, &prefix_length);
- prefix_length_ = prefix_length;
- return true;
-}
-
-QuicIpAddress IpRange::FirstAddressInRange() const {
- return prefix();
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/qbone/platform/ip_range.h b/chromium/net/third_party/quiche/src/quic/qbone/platform/ip_range.h
deleted file mode 100644
index e3df295967d..00000000000
--- a/chromium/net/third_party/quiche/src/quic/qbone/platform/ip_range.h
+++ /dev/null
@@ -1,60 +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_QBONE_PLATFORM_IP_RANGE_H_
-#define QUICHE_QUIC_QBONE_PLATFORM_IP_RANGE_H_
-
-#include "absl/strings/str_cat.h"
-#include "quic/platform/api/quic_ip_address.h"
-
-namespace quic {
-
-class IpRange {
- public:
- // Default constructor to have an uninitialized IpRange.
- IpRange() : prefix_length_(0) {}
-
- // prefix will be automatically truncated to prefix_length, so that any bit
- // after prefix_length are zero.
- IpRange(const QuicIpAddress& prefix, size_t prefix_length);
-
- bool operator==(IpRange other) const;
- bool operator!=(IpRange other) const;
-
- // Parses range that looks like "10.0.0.1/8". Tailing bits will be set to zero
- // after prefix_length. Return false if the parsing failed.
- bool FromString(const std::string& range);
-
- // Returns the string representation of this object.
- std::string ToString() const {
- if (IsInitialized()) {
- return absl::StrCat(prefix_.ToString(), "/", prefix_length_);
- }
- return "(uninitialized)";
- }
-
- // Whether this object is initialized.
- bool IsInitialized() const { return prefix_.IsInitialized(); }
-
- // Returns the first available IP address in this IpRange. The resulting
- // address will be uninitialized if there is no available address.
- QuicIpAddress FirstAddressInRange() const;
-
- // The address family of this IpRange.
- IpAddressFamily address_family() const { return prefix_.address_family(); }
-
- // The subnet's prefix address.
- QuicIpAddress prefix() const { return prefix_; }
-
- // The subnet's prefix length.
- size_t prefix_length() const { return prefix_length_; }
-
- private:
- QuicIpAddress prefix_;
- size_t prefix_length_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_QBONE_PLATFORM_IP_RANGE_H_
diff --git a/chromium/net/third_party/quiche/src/quic/qbone/platform/ip_range_test.cc b/chromium/net/third_party/quiche/src/quic/qbone/platform/ip_range_test.cc
deleted file mode 100644
index 1e1b00117dc..00000000000
--- a/chromium/net/third_party/quiche/src/quic/qbone/platform/ip_range_test.cc
+++ /dev/null
@@ -1,65 +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 "quic/qbone/platform/ip_range.h"
-
-#include "quic/platform/api/quic_ip_address.h"
-#include "quic/platform/api/quic_test.h"
-
-namespace quic {
-namespace {
-
-TEST(IpRangeTest, TruncateWorksIPv4) {
- QuicIpAddress before_truncate;
- before_truncate.FromString("255.255.255.255");
- EXPECT_EQ("128.0.0.0/1", IpRange(before_truncate, 1).ToString());
- EXPECT_EQ("192.0.0.0/2", IpRange(before_truncate, 2).ToString());
- EXPECT_EQ("255.224.0.0/11", IpRange(before_truncate, 11).ToString());
- EXPECT_EQ("255.255.255.224/27", IpRange(before_truncate, 27).ToString());
- EXPECT_EQ("255.255.255.254/31", IpRange(before_truncate, 31).ToString());
- EXPECT_EQ("255.255.255.255/32", IpRange(before_truncate, 32).ToString());
- EXPECT_EQ("255.255.255.255/32", IpRange(before_truncate, 33).ToString());
-}
-
-TEST(IpRangeTest, TruncateWorksIPv6) {
- QuicIpAddress before_truncate;
- before_truncate.FromString("ffff:ffff:ffff:ffff:f903::5");
- EXPECT_EQ("fe00::/7", IpRange(before_truncate, 7).ToString());
- EXPECT_EQ("ffff:ffff:ffff::/48", IpRange(before_truncate, 48).ToString());
- EXPECT_EQ("ffff:ffff:ffff:ffff::/64",
- IpRange(before_truncate, 64).ToString());
- EXPECT_EQ("ffff:ffff:ffff:ffff:8000::/65",
- IpRange(before_truncate, 65).ToString());
- EXPECT_EQ("ffff:ffff:ffff:ffff:f903::4/127",
- IpRange(before_truncate, 127).ToString());
-}
-
-TEST(IpRangeTest, FromStringWorksIPv4) {
- IpRange range;
- ASSERT_TRUE(range.FromString("127.0.3.249/26"));
- EXPECT_EQ("127.0.3.192/26", range.ToString());
-}
-
-TEST(IpRangeTest, FromStringWorksIPv6) {
- IpRange range;
- ASSERT_TRUE(range.FromString("ff01:8f21:77f9::/33"));
- EXPECT_EQ("ff01:8f21::/33", range.ToString());
-}
-
-TEST(IpRangeTest, FirstAddressWorksIPv6) {
- IpRange range;
- ASSERT_TRUE(range.FromString("ffff:ffff::/64"));
- QuicIpAddress first_address = range.FirstAddressInRange();
- EXPECT_EQ("ffff:ffff::", first_address.ToString());
-}
-
-TEST(IpRangeTest, FirstAddressWorksIPv4) {
- IpRange range;
- ASSERT_TRUE(range.FromString("10.0.0.0/24"));
- QuicIpAddress first_address = range.FirstAddressInRange();
- EXPECT_EQ("10.0.0.0", first_address.ToString());
-}
-
-} // namespace
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/qbone/platform/kernel_interface.h b/chromium/net/third_party/quiche/src/quic/qbone/platform/kernel_interface.h
deleted file mode 100644
index c96b6e67d0d..00000000000
--- a/chromium/net/third_party/quiche/src/quic/qbone/platform/kernel_interface.h
+++ /dev/null
@@ -1,169 +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_QBONE_PLATFORM_KERNEL_INTERFACE_H_
-#define QUICHE_QUIC_QBONE_PLATFORM_KERNEL_INTERFACE_H_
-
-#include <errno.h>
-#include <fcntl.h>
-#include <sys/ioctl.h>
-#include <sys/socket.h>
-#include <sys/types.h>
-#include <unistd.h>
-#include <type_traits>
-#include <utility>
-
-namespace quic {
-
-// A wrapper for making syscalls to the kernel, so that syscalls can be
-// mocked during testing.
-class KernelInterface {
- public:
- virtual ~KernelInterface() {}
- virtual int bind(int fd, const struct sockaddr* addr, socklen_t addr_len) = 0;
- virtual int close(int fd) = 0;
- virtual int ioctl(int fd, int request, void* argp) = 0;
- virtual int open(const char* pathname, int flags) = 0;
- virtual ssize_t read(int fd, void* buf, size_t count) = 0;
- virtual ssize_t recvfrom(int sockfd,
- void* buf,
- size_t len,
- int flags,
- struct sockaddr* src_addr,
- socklen_t* addrlen) = 0;
- virtual ssize_t sendmsg(int sockfd, const struct msghdr* msg, int flags) = 0;
- virtual ssize_t sendto(int sockfd,
- const void* buf,
- size_t len,
- int flags,
- const struct sockaddr* dest_addr,
- socklen_t addrlen) = 0;
- virtual int socket(int domain, int type, int protocol) = 0;
- virtual int setsockopt(int fd,
- int level,
- int optname,
- const void* optval,
- socklen_t optlen) = 0;
- virtual ssize_t write(int fd, const void* buf, size_t count) = 0;
-};
-
-// It is unfortunate to have R here, but std::result_of cannot be used.
-template <typename F, typename R, typename... Params>
-auto SyscallRetryOnError(R r, F f, Params&&... params)
- -> decltype(f(std::forward<Params>(params)...)) {
- static_assert(
- std::is_same<decltype(f(std::forward<Params>(params)...)), R>::value,
- "Return type does not match");
- decltype(f(std::forward<Params>(params)...)) result;
- do {
- result = f(std::forward<Params>(params)...);
- } while (result == r && errno == EINTR);
- return result;
-}
-
-template <typename F, typename... Params>
-auto SyscallRetry(F f, Params&&... params)
- -> decltype(f(std::forward<Params>(params)...)) {
- return SyscallRetryOnError(-1, f, std::forward<Params>(params)...);
-}
-
-template <typename Runner>
-class ParametrizedKernel final : public KernelInterface {
- public:
- static_assert(std::is_trivially_destructible<Runner>::value,
- "Runner is used as static, must be trivially destructible");
-
- ~ParametrizedKernel() override {}
-
- int bind(int fd, const struct sockaddr* addr, socklen_t addr_len) override {
- static Runner syscall("bind");
- return syscall.Retry(&::bind, fd, addr, addr_len);
- }
- int close(int fd) override {
- static Runner syscall("close");
- return syscall.Retry(&::close, fd);
- }
- int ioctl(int fd, int request, void* argp) override {
- static Runner syscall("ioctl");
- return syscall.Retry(&::ioctl, fd, request, argp);
- }
- int open(const char* pathname, int flags) override {
- static Runner syscall("open");
- return syscall.Retry(&::open, pathname, flags);
- }
- ssize_t read(int fd, void* buf, size_t count) override {
- static Runner syscall("read");
- return syscall.Run(&::read, fd, buf, count);
- }
- ssize_t recvfrom(int sockfd,
- void* buf,
- size_t len,
- int flags,
- struct sockaddr* src_addr,
- socklen_t* addrlen) override {
- static Runner syscall("recvfrom");
- return syscall.RetryOnError(&::recvfrom, static_cast<ssize_t>(-1), sockfd,
- buf, len, flags, src_addr, addrlen);
- }
- ssize_t sendmsg(int sockfd, const struct msghdr* msg, int flags) override {
- static Runner syscall("sendmsg");
- return syscall.RetryOnError(&::sendmsg, static_cast<ssize_t>(-1), sockfd,
- msg, flags);
- }
- ssize_t sendto(int sockfd,
- const void* buf,
- size_t len,
- int flags,
- const struct sockaddr* dest_addr,
- socklen_t addrlen) override {
- static Runner syscall("sendto");
- return syscall.RetryOnError(&::sendto, static_cast<ssize_t>(-1), sockfd,
- buf, len, flags, dest_addr, addrlen);
- }
- int socket(int domain, int type, int protocol) override {
- static Runner syscall("socket");
- return syscall.Retry(&::socket, domain, type, protocol);
- }
- int setsockopt(int fd,
- int level,
- int optname,
- const void* optval,
- socklen_t optlen) override {
- static Runner syscall("setsockopt");
- return syscall.Retry(&::setsockopt, fd, level, optname, optval, optlen);
- }
- ssize_t write(int fd, const void* buf, size_t count) override {
- static Runner syscall("write");
- return syscall.Run(&::write, fd, buf, count);
- }
-};
-
-class DefaultKernelRunner {
- public:
- explicit DefaultKernelRunner(const char* name) {}
-
- template <typename F, typename R, typename... Params>
- static auto RetryOnError(F f, R r, Params&&... params)
- -> decltype(f(std::forward<Params>(params)...)) {
- return SyscallRetryOnError(r, f, std::forward<Params>(params)...);
- }
-
- template <typename F, typename... Params>
- static auto Retry(F f, Params&&... params)
- -> decltype(f(std::forward<Params>(params)...)) {
- return SyscallRetry(f, std::forward<Params>(params)...);
- }
-
- template <typename F, typename... Params>
- static auto Run(F f, Params&&... params)
- -> decltype(f(std::forward<Params>(params)...)) {
- return f(std::forward<Params>(params)...);
- }
-};
-
-using Kernel = ParametrizedKernel<DefaultKernelRunner>;
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_QBONE_PLATFORM_KERNEL_INTERFACE_H_
diff --git a/chromium/net/third_party/quiche/src/quic/qbone/platform/mock_kernel.h b/chromium/net/third_party/quiche/src/quic/qbone/platform/mock_kernel.h
deleted file mode 100644
index f014b573347..00000000000
--- a/chromium/net/third_party/quiche/src/quic/qbone/platform/mock_kernel.h
+++ /dev/null
@@ -1,53 +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_QBONE_PLATFORM_MOCK_KERNEL_H_
-#define QUICHE_QUIC_QBONE_PLATFORM_MOCK_KERNEL_H_
-
-#include "quic/platform/api/quic_test.h"
-#include "quic/qbone/platform/kernel_interface.h"
-
-namespace quic {
-
-class MockKernel : public KernelInterface {
- public:
- MockKernel() {}
-
- MOCK_METHOD(int,
- bind,
- (int fd, const struct sockaddr*, socklen_t addr_len),
- (override));
- MOCK_METHOD(int, close, (int fd), (override));
- MOCK_METHOD(int, ioctl, (int fd, int request, void*), (override));
- MOCK_METHOD(int, open, (const char*, int flags), (override));
- MOCK_METHOD(ssize_t, read, (int fd, void*, size_t count), (override));
- MOCK_METHOD(
- ssize_t,
- recvfrom,
- (int sockfd, void*, size_t len, int flags, struct sockaddr*, socklen_t*),
- (override));
- MOCK_METHOD(ssize_t,
- sendmsg,
- (int sockfd, const struct msghdr*, int flags),
- (override));
- MOCK_METHOD(ssize_t,
- sendto,
- (int sockfd,
- const void*,
- size_t len,
- int flags,
- const struct sockaddr*,
- socklen_t addrlen),
- (override));
- MOCK_METHOD(int, socket, (int domain, int type, int protocol), (override));
- MOCK_METHOD(int,
- setsockopt,
- (int, int, int, const void*, socklen_t),
- (override));
- MOCK_METHOD(ssize_t, write, (int fd, const void*, size_t count), (override));
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_QBONE_PLATFORM_MOCK_KERNEL_H_
diff --git a/chromium/net/third_party/quiche/src/quic/qbone/platform/mock_netlink.h b/chromium/net/third_party/quiche/src/quic/qbone/platform/mock_netlink.h
deleted file mode 100644
index 83077a0404f..00000000000
--- a/chromium/net/third_party/quiche/src/quic/qbone/platform/mock_netlink.h
+++ /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.
-
-#ifndef QUICHE_QUIC_QBONE_PLATFORM_MOCK_NETLINK_H_
-#define QUICHE_QUIC_QBONE_PLATFORM_MOCK_NETLINK_H_
-
-#include "quic/platform/api/quic_test.h"
-#include "quic/qbone/platform/netlink_interface.h"
-
-namespace quic {
-
-class MockNetlink : public NetlinkInterface {
- public:
- MOCK_METHOD(bool, GetLinkInfo, (const std::string&, LinkInfo*), (override));
-
- MOCK_METHOD(bool,
- GetAddresses,
- (int, uint8_t, std::vector<AddressInfo>*, int*),
- (override));
-
- MOCK_METHOD(bool,
- ChangeLocalAddress,
- (uint32_t,
- Verb,
- const QuicIpAddress&,
- uint8_t,
- uint8_t,
- uint8_t,
- const std::vector<struct rtattr*>&),
- (override));
-
- MOCK_METHOD(bool, GetRouteInfo, (std::vector<RoutingRule>*), (override));
-
- MOCK_METHOD(bool,
- ChangeRoute,
- (Verb, uint32_t, const IpRange&, uint8_t, QuicIpAddress, int32_t),
- (override));
-
- MOCK_METHOD(bool, GetRuleInfo, (std::vector<IpRule>*), (override));
-
- MOCK_METHOD(bool, ChangeRule, (Verb, uint32_t, IpRange), (override));
-
- MOCK_METHOD(bool, Send, (struct iovec*, size_t), (override));
-
- MOCK_METHOD(bool, Recv, (uint32_t, NetlinkParserInterface*), (override));
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_QBONE_PLATFORM_MOCK_NETLINK_H_
diff --git a/chromium/net/third_party/quiche/src/quic/qbone/platform/netlink.cc b/chromium/net/third_party/quiche/src/quic/qbone/platform/netlink.cc
deleted file mode 100644
index 2f4bbe27124..00000000000
--- a/chromium/net/third_party/quiche/src/quic/qbone/platform/netlink.cc
+++ /dev/null
@@ -1,837 +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 "quic/qbone/platform/netlink.h"
-
-#include <linux/fib_rules.h>
-
-#include <utility>
-
-#include "absl/base/attributes.h"
-#include "absl/strings/str_cat.h"
-#include "quic/core/crypto/quic_random.h"
-#include "quic/platform/api/quic_ip_address.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/qbone/platform/rtnetlink_message.h"
-#include "quic/qbone/qbone_constants.h"
-
-namespace quic {
-
-Netlink::Netlink(KernelInterface* kernel) : kernel_(kernel) {
- seq_ = QuicRandom::GetInstance()->RandUint64();
-}
-
-Netlink::~Netlink() {
- CloseSocket();
-}
-
-void Netlink::ResetRecvBuf(size_t size) {
- if (size != 0) {
- recvbuf_ = std::make_unique<char[]>(size);
- } else {
- recvbuf_ = nullptr;
- }
- recvbuf_length_ = size;
-}
-
-bool Netlink::OpenSocket() {
- if (socket_fd_ >= 0) {
- return true;
- }
-
- socket_fd_ = kernel_->socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
-
- if (socket_fd_ < 0) {
- QUIC_PLOG(ERROR) << "can't open netlink socket";
- return false;
- }
-
- QUIC_LOG(INFO) << "Opened a new netlink socket fd = " << socket_fd_;
-
- // bind a local address to the socket
- sockaddr_nl myaddr;
- memset(&myaddr, 0, sizeof(myaddr));
- myaddr.nl_family = AF_NETLINK;
- if (kernel_->bind(socket_fd_, reinterpret_cast<struct sockaddr*>(&myaddr),
- sizeof(myaddr)) < 0) {
- QUIC_LOG(INFO) << "can't bind address to socket";
- CloseSocket();
- return false;
- }
-
- return true;
-}
-
-void Netlink::CloseSocket() {
- if (socket_fd_ >= 0) {
- QUIC_LOG(INFO) << "Closing netlink socket fd = " << socket_fd_;
- kernel_->close(socket_fd_);
- }
- ResetRecvBuf(0);
- socket_fd_ = -1;
-}
-
-namespace {
-
-class LinkInfoParser : public NetlinkParserInterface {
- public:
- LinkInfoParser(std::string interface_name, Netlink::LinkInfo* link_info)
- : interface_name_(std::move(interface_name)), link_info_(link_info) {}
-
- void Run(struct nlmsghdr* netlink_message) override {
- if (netlink_message->nlmsg_type != RTM_NEWLINK) {
- QUIC_LOG(INFO) << absl::StrCat(
- "Unexpected nlmsg_type: ", netlink_message->nlmsg_type,
- " expected: ", RTM_NEWLINK);
- return;
- }
-
- struct ifinfomsg* interface_info =
- reinterpret_cast<struct ifinfomsg*>(NLMSG_DATA(netlink_message));
-
- // make sure interface_info is what we asked for.
- if (interface_info->ifi_family != AF_UNSPEC) {
- QUIC_LOG(INFO) << absl::StrCat(
- "Unexpected ifi_family: ", interface_info->ifi_family,
- " expected: ", AF_UNSPEC);
- return;
- }
-
- char hardware_address[kHwAddrSize];
- size_t hardware_address_length = 0;
- char broadcast_address[kHwAddrSize];
- size_t broadcast_address_length = 0;
- std::string name;
-
- // loop through the attributes
- struct rtattr* rta;
- int payload_length = IFLA_PAYLOAD(netlink_message);
- for (rta = IFLA_RTA(interface_info); RTA_OK(rta, payload_length);
- rta = RTA_NEXT(rta, payload_length)) {
- int attribute_length;
- switch (rta->rta_type) {
- case IFLA_ADDRESS: {
- attribute_length = RTA_PAYLOAD(rta);
- if (attribute_length > kHwAddrSize) {
- QUIC_VLOG(2) << "IFLA_ADDRESS too long: " << attribute_length;
- break;
- }
- memmove(hardware_address, RTA_DATA(rta), attribute_length);
- hardware_address_length = attribute_length;
- break;
- }
- case IFLA_BROADCAST: {
- attribute_length = RTA_PAYLOAD(rta);
- if (attribute_length > kHwAddrSize) {
- QUIC_VLOG(2) << "IFLA_BROADCAST too long: " << attribute_length;
- break;
- }
- memmove(broadcast_address, RTA_DATA(rta), attribute_length);
- broadcast_address_length = attribute_length;
- break;
- }
- case IFLA_IFNAME: {
- name = std::string(reinterpret_cast<char*>(RTA_DATA(rta)),
- RTA_PAYLOAD(rta));
- // The name maybe a 0 terminated c string.
- name = name.substr(0, name.find('\0'));
- break;
- }
- }
- }
-
- QUIC_VLOG(2) << "interface name: " << name
- << ", index: " << interface_info->ifi_index;
-
- if (name == interface_name_) {
- link_info_->index = interface_info->ifi_index;
- link_info_->type = interface_info->ifi_type;
- link_info_->hardware_address_length = hardware_address_length;
- if (hardware_address_length > 0) {
- memmove(&link_info_->hardware_address, hardware_address,
- hardware_address_length);
- }
- link_info_->broadcast_address_length = broadcast_address_length;
- if (broadcast_address_length > 0) {
- memmove(&link_info_->broadcast_address, broadcast_address,
- broadcast_address_length);
- }
- found_link_ = true;
- }
- }
-
- bool found_link() { return found_link_; }
-
- private:
- const std::string interface_name_;
- Netlink::LinkInfo* const link_info_;
- bool found_link_ = false;
-};
-
-} // namespace
-
-bool Netlink::GetLinkInfo(const std::string& interface_name,
- LinkInfo* link_info) {
- auto message = LinkMessage::New(RtnetlinkMessage::Operation::GET,
- NLM_F_ROOT | NLM_F_MATCH | NLM_F_REQUEST,
- seq_, getpid(), nullptr);
-
- if (!Send(message.BuildIoVec().get(), message.IoVecSize())) {
- QUIC_LOG(ERROR) << "send failed.";
- return false;
- }
-
- // Pass the parser to the receive routine. It may be called multiple times
- // since there may be multiple reply packets each with multiple reply
- // messages.
- LinkInfoParser parser(interface_name, link_info);
- if (!Recv(seq_++, &parser)) {
- QUIC_LOG(ERROR) << "recv failed.";
- return false;
- }
-
- return parser.found_link();
-}
-
-namespace {
-
-class LocalAddressParser : public NetlinkParserInterface {
- public:
- LocalAddressParser(int interface_index,
- uint8_t unwanted_flags,
- std::vector<Netlink::AddressInfo>* local_addresses,
- int* num_ipv6_nodad_dadfailed_addresses)
- : interface_index_(interface_index),
- unwanted_flags_(unwanted_flags),
- local_addresses_(local_addresses),
- num_ipv6_nodad_dadfailed_addresses_(
- num_ipv6_nodad_dadfailed_addresses) {}
-
- void Run(struct nlmsghdr* netlink_message) override {
- // each nlmsg contains a header and multiple address attributes.
- if (netlink_message->nlmsg_type != RTM_NEWADDR) {
- QUIC_LOG(INFO) << "Unexpected nlmsg_type: " << netlink_message->nlmsg_type
- << " expected: " << RTM_NEWADDR;
- return;
- }
-
- struct ifaddrmsg* interface_address =
- reinterpret_cast<struct ifaddrmsg*>(NLMSG_DATA(netlink_message));
-
- // Make sure this is for an address family we're interested in.
- if (interface_address->ifa_family != AF_INET &&
- interface_address->ifa_family != AF_INET6) {
- QUIC_VLOG(2) << absl::StrCat("uninteresting ifa family: ",
- interface_address->ifa_family);
- return;
- }
-
- // Keep track of addresses with both 'nodad' and 'dadfailed', this really
- // should't be possible and is likely a kernel bug.
- if (num_ipv6_nodad_dadfailed_addresses_ != nullptr &&
- (interface_address->ifa_flags & IFA_F_NODAD) &&
- (interface_address->ifa_flags & IFA_F_DADFAILED)) {
- ++(*num_ipv6_nodad_dadfailed_addresses_);
- }
-
- uint8_t unwanted_flags = interface_address->ifa_flags & unwanted_flags_;
- if (unwanted_flags != 0) {
- QUIC_VLOG(2) << absl::StrCat("unwanted ifa flags: ", unwanted_flags);
- return;
- }
-
- // loop through the attributes
- struct rtattr* rta;
- int payload_length = IFA_PAYLOAD(netlink_message);
- Netlink::AddressInfo address_info;
- for (rta = IFA_RTA(interface_address); RTA_OK(rta, payload_length);
- rta = RTA_NEXT(rta, payload_length)) {
- // There's quite a lot of confusion in Linux over the use of IFA_LOCAL and
- // IFA_ADDRESS (source and destination address). For broadcast links, such
- // as Ethernet, they are identical (see <linux/if_addr.h>), but the kernel
- // sometimes uses only one or the other. We'll return both so that the
- // caller can decide which to use.
- if (rta->rta_type != IFA_LOCAL && rta->rta_type != IFA_ADDRESS) {
- QUIC_VLOG(2) << "Ignoring uninteresting rta_type: " << rta->rta_type;
- continue;
- }
-
- switch (interface_address->ifa_family) {
- case AF_INET:
- ABSL_FALLTHROUGH_INTENDED;
- case AF_INET6:
- // QuicIpAddress knows how to parse ip from raw bytes as long as they
- // are in network byte order.
- if (RTA_PAYLOAD(rta) == sizeof(struct in_addr) ||
- RTA_PAYLOAD(rta) == sizeof(struct in6_addr)) {
- auto* raw_ip = reinterpret_cast<char*>(RTA_DATA(rta));
- if (rta->rta_type == IFA_LOCAL) {
- address_info.local_address.FromPackedString(raw_ip,
- RTA_PAYLOAD(rta));
- } else {
- address_info.interface_address.FromPackedString(raw_ip,
- RTA_PAYLOAD(rta));
- }
- }
- break;
- default:
- QUIC_LOG(ERROR) << absl::StrCat("Unknown address family: ",
- interface_address->ifa_family);
- }
- }
-
- QUIC_VLOG(2) << "local_address: " << address_info.local_address.ToString()
- << " interface_address: "
- << address_info.interface_address.ToString()
- << " index: " << interface_address->ifa_index;
- if (interface_address->ifa_index != interface_index_) {
- return;
- }
-
- address_info.prefix_length = interface_address->ifa_prefixlen;
- address_info.scope = interface_address->ifa_scope;
- if (address_info.local_address.IsInitialized() ||
- address_info.interface_address.IsInitialized()) {
- local_addresses_->push_back(address_info);
- }
- }
-
- private:
- const int interface_index_;
- const uint8_t unwanted_flags_;
- std::vector<Netlink::AddressInfo>* const local_addresses_;
- int* const num_ipv6_nodad_dadfailed_addresses_;
-};
-
-} // namespace
-
-bool Netlink::GetAddresses(int interface_index,
- uint8_t unwanted_flags,
- std::vector<AddressInfo>* addresses,
- int* num_ipv6_nodad_dadfailed_addresses) {
- // the message doesn't contain the index, we'll have to do the filtering while
- // parsing the reply. This is because NLM_F_MATCH, which only returns entries
- // that matches the request criteria, is not yet implemented (see man 3
- // netlink).
- auto message = AddressMessage::New(RtnetlinkMessage::Operation::GET,
- NLM_F_ROOT | NLM_F_MATCH | NLM_F_REQUEST,
- seq_, getpid(), nullptr);
-
- // the send routine returns the socket to listen on.
- if (!Send(message.BuildIoVec().get(), message.IoVecSize())) {
- QUIC_LOG(ERROR) << "send failed.";
- return false;
- }
-
- addresses->clear();
- if (num_ipv6_nodad_dadfailed_addresses != nullptr) {
- *num_ipv6_nodad_dadfailed_addresses = 0;
- }
-
- LocalAddressParser parser(interface_index, unwanted_flags, addresses,
- num_ipv6_nodad_dadfailed_addresses);
- // Pass the parser to the receive routine. It may be called multiple times
- // since there may be multiple reply packets each with multiple reply
- // messages.
- if (!Recv(seq_++, &parser)) {
- QUIC_LOG(ERROR) << "recv failed";
- return false;
- }
- return true;
-}
-
-namespace {
-
-class UnknownParser : public NetlinkParserInterface {
- public:
- void Run(struct nlmsghdr* netlink_message) override {
- QUIC_LOG(INFO) << "nlmsg reply type: " << netlink_message->nlmsg_type;
- }
-};
-
-} // namespace
-
-bool Netlink::ChangeLocalAddress(
- uint32_t interface_index,
- Verb verb,
- const QuicIpAddress& address,
- uint8_t prefix_length,
- uint8_t ifa_flags,
- uint8_t ifa_scope,
- const std::vector<struct rtattr*>& additional_attributes) {
- if (verb == Verb::kReplace) {
- return false;
- }
- auto operation = verb == Verb::kAdd ? RtnetlinkMessage::Operation::NEW
- : RtnetlinkMessage::Operation::DEL;
- uint8_t address_family;
- if (address.address_family() == IpAddressFamily::IP_V4) {
- address_family = AF_INET;
- } else if (address.address_family() == IpAddressFamily::IP_V6) {
- address_family = AF_INET6;
- } else {
- return false;
- }
-
- struct ifaddrmsg address_header = {address_family, prefix_length, ifa_flags,
- ifa_scope, interface_index};
-
- auto message = AddressMessage::New(operation, NLM_F_REQUEST | NLM_F_ACK, seq_,
- getpid(), &address_header);
-
- for (const auto& attribute : additional_attributes) {
- if (attribute->rta_type == IFA_LOCAL) {
- continue;
- }
- message.AppendAttribute(attribute->rta_type, RTA_DATA(attribute),
- RTA_PAYLOAD(attribute));
- }
-
- message.AppendAttribute(IFA_LOCAL, address.ToPackedString().c_str(),
- address.ToPackedString().size());
-
- if (!Send(message.BuildIoVec().get(), message.IoVecSize())) {
- QUIC_LOG(ERROR) << "send failed";
- return false;
- }
-
- UnknownParser parser;
- if (!Recv(seq_++, &parser)) {
- QUIC_LOG(ERROR) << "receive failed.";
- return false;
- }
- return true;
-}
-
-namespace {
-
-class RoutingRuleParser : public NetlinkParserInterface {
- public:
- explicit RoutingRuleParser(std::vector<Netlink::RoutingRule>* routing_rules)
- : routing_rules_(routing_rules) {}
-
- void Run(struct nlmsghdr* netlink_message) override {
- if (netlink_message->nlmsg_type != RTM_NEWROUTE) {
- QUIC_LOG(WARNING) << absl::StrCat(
- "Unexpected nlmsg_type: ", netlink_message->nlmsg_type,
- " expected: ", RTM_NEWROUTE);
- return;
- }
-
- auto* route = reinterpret_cast<struct rtmsg*>(NLMSG_DATA(netlink_message));
- int payload_length = RTM_PAYLOAD(netlink_message);
-
- if (route->rtm_family != AF_INET && route->rtm_family != AF_INET6) {
- QUIC_VLOG(2) << absl::StrCat("Uninteresting family: ", route->rtm_family);
- return;
- }
-
- Netlink::RoutingRule rule;
- rule.scope = route->rtm_scope;
- rule.table = route->rtm_table;
-
- struct rtattr* rta;
- for (rta = RTM_RTA(route); RTA_OK(rta, payload_length);
- rta = RTA_NEXT(rta, payload_length)) {
- switch (rta->rta_type) {
- case RTA_TABLE: {
- rule.table = *reinterpret_cast<uint32_t*>(RTA_DATA(rta));
- break;
- }
- case RTA_DST: {
- QuicIpAddress destination;
- destination.FromPackedString(reinterpret_cast<char*> RTA_DATA(rta),
- RTA_PAYLOAD(rta));
- rule.destination_subnet = IpRange(destination, route->rtm_dst_len);
- break;
- }
- case RTA_PREFSRC: {
- QuicIpAddress preferred_source;
- rule.preferred_source.FromPackedString(
- reinterpret_cast<char*> RTA_DATA(rta), RTA_PAYLOAD(rta));
- break;
- }
- case RTA_OIF: {
- rule.out_interface = *reinterpret_cast<int*>(RTA_DATA(rta));
- break;
- }
- default: {
- QUIC_VLOG(2) << absl::StrCat("Uninteresting attribute: ",
- rta->rta_type);
- }
- }
- }
- routing_rules_->push_back(rule);
- }
-
- private:
- std::vector<Netlink::RoutingRule>* routing_rules_;
-};
-
-} // namespace
-
-bool Netlink::GetRouteInfo(std::vector<Netlink::RoutingRule>* routing_rules) {
- rtmsg route_message{};
- // Only manipulate main routing table.
- route_message.rtm_table = RT_TABLE_MAIN;
-
- auto message = RouteMessage::New(RtnetlinkMessage::Operation::GET,
- NLM_F_REQUEST | NLM_F_ROOT | NLM_F_MATCH,
- seq_, getpid(), &route_message);
-
- if (!Send(message.BuildIoVec().get(), message.IoVecSize())) {
- QUIC_LOG(ERROR) << "send failed";
- return false;
- }
-
- RoutingRuleParser parser(routing_rules);
- if (!Recv(seq_++, &parser)) {
- QUIC_LOG(ERROR) << "recv failed";
- return false;
- }
-
- return true;
-}
-
-bool Netlink::ChangeRoute(Netlink::Verb verb,
- uint32_t table,
- const IpRange& destination_subnet,
- uint8_t scope,
- QuicIpAddress preferred_source,
- int32_t interface_index) {
- if (!destination_subnet.prefix().IsInitialized()) {
- return false;
- }
- if (destination_subnet.address_family() != IpAddressFamily::IP_V4 &&
- destination_subnet.address_family() != IpAddressFamily::IP_V6) {
- return false;
- }
- if (preferred_source.IsInitialized() &&
- preferred_source.address_family() !=
- destination_subnet.address_family()) {
- return false;
- }
-
- RtnetlinkMessage::Operation operation;
- uint16_t flags = NLM_F_REQUEST | NLM_F_ACK;
- switch (verb) {
- case Verb::kAdd:
- operation = RtnetlinkMessage::Operation::NEW;
- // Setting NLM_F_EXCL so that an existing entry for this subnet will fail
- // the request. NLM_F_CREATE is necessary to indicate this is trying to
- // create a new entry - simply having RTM_NEWROUTE is not enough even the
- // name suggests so.
- flags |= NLM_F_EXCL | NLM_F_CREATE;
- break;
- case Verb::kRemove:
- operation = RtnetlinkMessage::Operation::DEL;
- break;
- case Verb::kReplace:
- operation = RtnetlinkMessage::Operation::NEW;
- // Setting NLM_F_REPLACE to tell the kernel that existing entry for this
- // subnet should be replaced.
- flags |= NLM_F_REPLACE | NLM_F_CREATE;
- break;
- }
-
- struct rtmsg route_message;
- memset(&route_message, 0, sizeof(route_message));
- route_message.rtm_family =
- destination_subnet.address_family() == IpAddressFamily::IP_V4 ? AF_INET
- : AF_INET6;
- // rtm_dst_len and rtm_src_len are actually the subnet prefix lengths. Poor
- // naming.
- route_message.rtm_dst_len = destination_subnet.prefix_length();
- // 0 means no source subnet for this rule.
- route_message.rtm_src_len = 0;
- // Only program the main table. Other tables are intended for the kernel to
- // manage.
- route_message.rtm_table = RT_TABLE_MAIN;
- // Use RTPROT_UNSPEC to match all the different protocol. Rules added by
- // kernel have RTPROT_KERNEL. Rules added by the root user have RTPROT_STATIC
- // instead.
- route_message.rtm_protocol =
- verb == Verb::kRemove ? RTPROT_UNSPEC : RTPROT_STATIC;
- route_message.rtm_scope = scope;
- // Only add unicast routing rule.
- route_message.rtm_type = RTN_UNICAST;
- auto message =
- RouteMessage::New(operation, flags, seq_, getpid(), &route_message);
-
- message.AppendAttribute(RTA_TABLE, &table, sizeof(table));
-
- // RTA_OIF is the target interface for this rule.
- message.AppendAttribute(RTA_OIF, &interface_index, sizeof(interface_index));
- // The actual destination subnet must be truncated of all the tailing zeros.
- message.AppendAttribute(
- RTA_DST,
- reinterpret_cast<const void*>(
- destination_subnet.prefix().ToPackedString().c_str()),
- destination_subnet.prefix().ToPackedString().size());
- // This is the source address to use in the IP packet should this routing rule
- // is used.
- if (preferred_source.IsInitialized()) {
- auto src_str = preferred_source.ToPackedString();
- message.AppendAttribute(RTA_PREFSRC,
- reinterpret_cast<const void*>(src_str.c_str()),
- src_str.size());
- }
-
- if (verb != Verb::kRemove) {
- auto gateway_str = QboneConstants::GatewayAddress()->ToPackedString();
- message.AppendAttribute(RTA_GATEWAY,
- reinterpret_cast<const void*>(gateway_str.c_str()),
- gateway_str.size());
- }
-
- if (!Send(message.BuildIoVec().get(), message.IoVecSize())) {
- QUIC_LOG(ERROR) << "send failed";
- return false;
- }
-
- UnknownParser parser;
- if (!Recv(seq_++, &parser)) {
- QUIC_LOG(ERROR) << "receive failed.";
- return false;
- }
- return true;
-}
-
-namespace {
-
-class IpRuleParser : public NetlinkParserInterface {
- public:
- explicit IpRuleParser(std::vector<Netlink::IpRule>* ip_rules)
- : ip_rules_(ip_rules) {}
-
- void Run(struct nlmsghdr* netlink_message) override {
- if (netlink_message->nlmsg_type != RTM_NEWRULE) {
- QUIC_LOG(WARNING) << absl::StrCat(
- "Unexpected nlmsg_type: ", netlink_message->nlmsg_type,
- " expected: ", RTM_NEWRULE);
- return;
- }
-
- auto* rule = reinterpret_cast<rtmsg*>(NLMSG_DATA(netlink_message));
- int payload_length = RTM_PAYLOAD(netlink_message);
-
- if (rule->rtm_family != AF_INET6) {
- QUIC_LOG(ERROR) << absl::StrCat("Unexpected family: ", rule->rtm_family);
- return;
- }
-
- Netlink::IpRule ip_rule;
- ip_rule.table = rule->rtm_table;
-
- struct rtattr* rta;
- for (rta = RTM_RTA(rule); RTA_OK(rta, payload_length);
- rta = RTA_NEXT(rta, payload_length)) {
- switch (rta->rta_type) {
- case RTA_TABLE: {
- ip_rule.table = *reinterpret_cast<uint32_t*>(RTA_DATA(rta));
- break;
- }
- case RTA_SRC: {
- QuicIpAddress src_addr;
- src_addr.FromPackedString(reinterpret_cast<char*>(RTA_DATA(rta)),
- RTA_PAYLOAD(rta));
- IpRange src_range(src_addr, rule->rtm_src_len);
- ip_rule.source_range = src_range;
- break;
- }
- default: {
- QUIC_VLOG(2) << absl::StrCat("Uninteresting attribute: ",
- rta->rta_type);
- }
- }
- }
- ip_rules_->emplace_back(ip_rule);
- }
-
- private:
- std::vector<Netlink::IpRule>* ip_rules_;
-};
-
-} // namespace
-
-bool Netlink::GetRuleInfo(std::vector<Netlink::IpRule>* ip_rules) {
- rtmsg rule_message{};
- rule_message.rtm_family = AF_INET6;
-
- auto message = RuleMessage::New(RtnetlinkMessage::Operation::GET,
- NLM_F_REQUEST | NLM_F_DUMP, seq_, getpid(),
- &rule_message);
-
- if (!Send(message.BuildIoVec().get(), message.IoVecSize())) {
- QUIC_LOG(ERROR) << "send failed";
- return false;
- }
-
- IpRuleParser parser(ip_rules);
- if (!Recv(seq_++, &parser)) {
- QUIC_LOG(ERROR) << "receive failed.";
- return false;
- }
- return true;
-}
-
-bool Netlink::ChangeRule(Verb verb, uint32_t table, IpRange source_range) {
- RtnetlinkMessage::Operation operation;
- uint16_t flags = NLM_F_REQUEST | NLM_F_ACK;
-
- rtmsg rule_message{};
- rule_message.rtm_family = AF_INET6;
- rule_message.rtm_protocol = RTPROT_STATIC;
- rule_message.rtm_scope = RT_SCOPE_UNIVERSE;
- rule_message.rtm_table = RT_TABLE_UNSPEC;
-
- rule_message.rtm_flags |= FIB_RULE_FIND_SADDR;
-
- switch (verb) {
- case Verb::kAdd:
- if (!source_range.IsInitialized()) {
- QUIC_LOG(ERROR) << "Source range must be initialized.";
- return false;
- }
- operation = RtnetlinkMessage::Operation::NEW;
- flags |= NLM_F_EXCL | NLM_F_CREATE;
- rule_message.rtm_type = FRA_DST;
- rule_message.rtm_src_len = source_range.prefix_length();
- break;
- case Verb::kRemove:
- operation = RtnetlinkMessage::Operation::DEL;
- break;
- case Verb::kReplace:
- QUIC_LOG(ERROR) << "Unsupported verb: kReplace";
- return false;
- }
- auto message =
- RuleMessage::New(operation, flags, seq_, getpid(), &rule_message);
-
- message.AppendAttribute(RTA_TABLE, &table, sizeof(table));
-
- if (source_range.IsInitialized()) {
- std::string packed_src = source_range.prefix().ToPackedString();
- message.AppendAttribute(RTA_SRC,
- reinterpret_cast<const void*>(packed_src.c_str()),
- packed_src.size());
- }
-
- if (!Send(message.BuildIoVec().get(), message.IoVecSize())) {
- QUIC_LOG(ERROR) << "send failed";
- return false;
- }
-
- UnknownParser parser;
- if (!Recv(seq_++, &parser)) {
- QUIC_LOG(ERROR) << "receive failed.";
- return false;
- }
- return true;
-}
-
-bool Netlink::Send(struct iovec* iov, size_t iovlen) {
- if (!OpenSocket()) {
- QUIC_LOG(ERROR) << "can't open socket";
- return false;
- }
-
- // an address for communicating with the kernel netlink code
- sockaddr_nl netlink_address;
- memset(&netlink_address, 0, sizeof(netlink_address));
- netlink_address.nl_family = AF_NETLINK;
- netlink_address.nl_pid = 0; // destination is kernel
- netlink_address.nl_groups = 0; // no multicast
-
- struct msghdr msg = {
- &netlink_address, sizeof(netlink_address), iov, iovlen, nullptr, 0, 0};
-
- if (kernel_->sendmsg(socket_fd_, &msg, 0) < 0) {
- QUIC_LOG(ERROR) << "sendmsg failed";
- CloseSocket();
- return false;
- }
-
- return true;
-}
-
-bool Netlink::Recv(uint32_t seq, NetlinkParserInterface* parser) {
- sockaddr_nl netlink_address;
-
- // replies can span multiple packets
- for (;;) {
- socklen_t address_length = sizeof(netlink_address);
-
- // First, call recvfrom with buffer size of 0 and MSG_PEEK | MSG_TRUNC set
- // so that we know the size of the incoming packet before actually receiving
- // it.
- int next_packet_size = kernel_->recvfrom(
- socket_fd_, recvbuf_.get(), /* len = */ 0, MSG_PEEK | MSG_TRUNC,
- reinterpret_cast<struct sockaddr*>(&netlink_address), &address_length);
- if (next_packet_size < 0) {
- QUIC_LOG(ERROR)
- << "error recvfrom with MSG_PEEK | MSG_TRUNC to get packet length.";
- CloseSocket();
- return false;
- }
- QUIC_VLOG(3) << "netlink packet size: " << next_packet_size;
- if (next_packet_size > recvbuf_length_) {
- QUIC_VLOG(2) << "resizing recvbuf to " << next_packet_size;
- ResetRecvBuf(next_packet_size);
- }
-
- // Get the packet for real.
- memset(recvbuf_.get(), 0, recvbuf_length_);
- int len = kernel_->recvfrom(
- socket_fd_, recvbuf_.get(), recvbuf_length_, /* flags = */ 0,
- reinterpret_cast<struct sockaddr*>(&netlink_address), &address_length);
- QUIC_VLOG(3) << "recvfrom returned: " << len;
- if (len < 0) {
- QUIC_LOG(INFO) << "can't receive netlink packet";
- CloseSocket();
- return false;
- }
-
- // there may be multiple nlmsg's in each reply packet
- struct nlmsghdr* netlink_message;
- for (netlink_message = reinterpret_cast<struct nlmsghdr*>(recvbuf_.get());
- NLMSG_OK(netlink_message, len);
- netlink_message = NLMSG_NEXT(netlink_message, len)) {
- QUIC_VLOG(3) << "netlink_message->nlmsg_type = "
- << netlink_message->nlmsg_type;
- // make sure this is to us
- if (netlink_message->nlmsg_seq != seq) {
- QUIC_LOG(INFO) << "netlink_message not meant for us."
- << " seq: " << seq
- << " nlmsg_seq: " << netlink_message->nlmsg_seq;
- continue;
- }
-
- // done with this whole reply (not just this particular packet)
- if (netlink_message->nlmsg_type == NLMSG_DONE) {
- return true;
- }
- if (netlink_message->nlmsg_type == NLMSG_ERROR) {
- struct nlmsgerr* err =
- reinterpret_cast<struct nlmsgerr*>(NLMSG_DATA(netlink_message));
- if (netlink_message->nlmsg_len <
- NLMSG_LENGTH(sizeof(struct nlmsgerr))) {
- QUIC_LOG(INFO) << "netlink_message ERROR truncated";
- } else {
- // an ACK
- if (err->error == 0) {
- QUIC_VLOG(3) << "Netlink sent an ACK";
- return true;
- }
- QUIC_LOG(INFO) << "netlink_message ERROR: " << err->error;
- }
- return false;
- }
-
- parser->Run(netlink_message);
- }
- }
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/qbone/platform/netlink.h b/chromium/net/third_party/quiche/src/quic/qbone/platform/netlink.h
deleted file mode 100644
index 9a5b7d9fac1..00000000000
--- a/chromium/net/third_party/quiche/src/quic/qbone/platform/netlink.h
+++ /dev/null
@@ -1,143 +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_QBONE_PLATFORM_NETLINK_H_
-#define QUICHE_QUIC_QBONE_PLATFORM_NETLINK_H_
-
-#include <linux/netlink.h>
-#include <linux/rtnetlink.h>
-
-#include <cstdint>
-#include <functional>
-#include <memory>
-#include <string>
-#include <vector>
-
-#include "quic/platform/api/quic_ip_address.h"
-#include "quic/qbone/platform/ip_range.h"
-#include "quic/qbone/platform/kernel_interface.h"
-#include "quic/qbone/platform/netlink_interface.h"
-
-namespace quic {
-
-// A wrapper class to provide convenient methods of manipulating IP address and
-// routing table using netlink (man 7 netlink) socket. More specifically,
-// rtnetlink is used (man 7 rtnetlink).
-//
-// This class is not thread safe, but thread compatible, as long as callers can
-// make sure Send and Recv pairs are executed in sequence for a particular
-// query.
-class Netlink : public NetlinkInterface {
- public:
- explicit Netlink(KernelInterface* kernel);
- ~Netlink() override;
-
- // Gets the link information for the interface referred by the given
- // interface_name.
- //
- // This is a synchronous communication. That should not be a problem since the
- // kernel should answer immediately.
- bool GetLinkInfo(const std::string& interface_name,
- LinkInfo* link_info) override;
-
- // Gets the addresses for the given interface referred by the given
- // interface_index.
- //
- // This is a synchronous communication. This should not be a problem since the
- // kernel should answer immediately.
- bool GetAddresses(int interface_index,
- uint8_t unwanted_flags,
- std::vector<AddressInfo>* addresses,
- int* num_ipv6_nodad_dadfailed_addresses) override;
-
- // Performs the given verb that modifies local addresses on the given
- // interface_index.
- //
- // additional_attributes are RTAs (man 7 rtnelink) that will be sent together
- // with the netlink message. Note that rta_len in each RTA is used to decide
- // the length of the payload. The caller is responsible for making sure
- // payload bytes are accessible after the RTA header.
- bool ChangeLocalAddress(
- uint32_t interface_index,
- Verb verb,
- const QuicIpAddress& address,
- uint8_t prefix_length,
- uint8_t ifa_flags,
- uint8_t ifa_scope,
- const std::vector<struct rtattr*>& additional_attributes) override;
-
- // Gets the list of routing rules from the main routing table (RT_TABLE_MAIN),
- // which is programmable.
- //
- // This is a synchronous communication. This should not be a problem since the
- // kernel should answer immediately.
- bool GetRouteInfo(std::vector<RoutingRule>* routing_rules) override;
-
- // Performs the given Verb on the matching rule in the main routing table
- // (RT_TABLE_MAIN).
- //
- // preferred_source can be !IsInitialized(), in which case it will be omitted.
- //
- // For Verb::kRemove, rule matching is done by (destination_subnet, scope,
- // preferred_source, interface_index). Return true if a matching rule is
- // found. interface_index can be 0 for wilecard.
- //
- // For Verb::kAdd, rule matching is done by destination_subnet. If a rule for
- // the given destination_subnet already exists, nothing will happen and false
- // is returned.
- //
- // For Verb::kReplace, rule matching is done by destination_subnet. If no
- // matching rule is found, a new entry will be created.
- bool ChangeRoute(Netlink::Verb verb,
- uint32_t table,
- const IpRange& destination_subnet,
- uint8_t scope,
- QuicIpAddress preferred_source,
- int32_t interface_index) override;
-
- // Returns the set of all rules in the routing policy database.
- bool GetRuleInfo(std::vector<Netlink::IpRule>* ip_rules) override;
-
- // Performs the give verb on the matching rule in the routing policy database.
- // When deleting a rule, the |source_range| may be unspecified, in which case
- // the lowest priority rule from |table| will be removed. When adding a rule,
- // the |source_address| must be specified.
- bool ChangeRule(Verb verb, uint32_t table, IpRange source_range) override;
-
- // Sends a netlink message to the kernel. iov and iovlen represents an array
- // of struct iovec to be fed into sendmsg. The caller needs to make sure the
- // message conform to what's expected by NLMSG_* macros.
- //
- // This can be useful if more flexibility is needed than the provided
- // convenient methods can provide.
- bool Send(struct iovec* iov, size_t iovlen) override;
-
- // Receives a netlink message from the kernel.
- // parser will be called on the caller's stack.
- //
- // This can be useful if more flexibility is needed than the provided
- // convenient methods can provide.
- // TODO(b/69412655): vectorize this.
- bool Recv(uint32_t seq, NetlinkParserInterface* parser) override;
-
- private:
- // Reset the size of recvbuf_ to size. If size is 0, recvbuf_ will be nullptr.
- void ResetRecvBuf(size_t size);
-
- // Opens a netlink socket if not already opened.
- bool OpenSocket();
-
- // Closes the opened netlink socket. Noop if no netlink socket is opened.
- void CloseSocket();
-
- KernelInterface* kernel_;
- int socket_fd_ = -1;
- std::unique_ptr<char[]> recvbuf_ = nullptr;
- size_t recvbuf_length_ = 0;
- uint32_t seq_; // next msg sequence number
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_QBONE_PLATFORM_NETLINK_H_
diff --git a/chromium/net/third_party/quiche/src/quic/qbone/platform/netlink_interface.h b/chromium/net/third_party/quiche/src/quic/qbone/platform/netlink_interface.h
deleted file mode 100644
index 0794b1d5e4c..00000000000
--- a/chromium/net/third_party/quiche/src/quic/qbone/platform/netlink_interface.h
+++ /dev/null
@@ -1,148 +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_QBONE_PLATFORM_NETLINK_INTERFACE_H_
-#define QUICHE_QUIC_QBONE_PLATFORM_NETLINK_INTERFACE_H_
-
-#include <linux/rtnetlink.h>
-
-#include "quic/platform/api/quic_ip_address.h"
-#include "quic/qbone/platform/ip_range.h"
-
-namespace quic {
-
-constexpr int kHwAddrSize = 6;
-
-class NetlinkParserInterface {
- public:
- virtual ~NetlinkParserInterface() {}
- virtual void Run(struct nlmsghdr* netlink_message) = 0;
-};
-
-// An interface providing convenience methods for manipulating IP address and
-// routing table using netlink (man 7 netlink) socket.
-class NetlinkInterface {
- public:
- virtual ~NetlinkInterface() = default;
-
- // Link information returned from GetLinkInfo.
- struct LinkInfo {
- int index;
- uint8_t type;
- uint8_t hardware_address[kHwAddrSize];
- uint8_t broadcast_address[kHwAddrSize];
- size_t hardware_address_length; // 0 if no hardware address found
- size_t broadcast_address_length; // 0 if no broadcast address found
- };
-
- // Gets the link information for the interface referred by the given
- // interface_name.
- virtual bool GetLinkInfo(const std::string& interface_name,
- LinkInfo* link_info) = 0;
-
- // Address information reported back from GetAddresses.
- struct AddressInfo {
- QuicIpAddress local_address;
- QuicIpAddress interface_address;
- uint8_t prefix_length = 0;
- uint8_t scope = 0;
- };
-
- // Gets the addresses for the given interface referred by the given
- // interface_index.
- virtual bool GetAddresses(int interface_index,
- uint8_t unwanted_flags,
- std::vector<AddressInfo>* addresses,
- int* num_ipv6_nodad_dadfailed_addresses) = 0;
-
- enum class Verb {
- kAdd,
- kRemove,
- kReplace,
- };
-
- // Performs the given verb that modifies local addresses on the given
- // interface_index.
- //
- // additional_attributes are RTAs (man 7 rtnelink) that will be sent together
- // with the netlink message. Note that rta_len in each RTA is used to decide
- // the length of the payload. The caller is responsible for making sure
- // payload bytes are accessible after the RTA header.
- virtual bool ChangeLocalAddress(
- uint32_t interface_index,
- Verb verb,
- const QuicIpAddress& address,
- uint8_t prefix_length,
- uint8_t ifa_flags,
- uint8_t ifa_scope,
- const std::vector<struct rtattr*>& additional_attributes) = 0;
-
- // Routing rule reported back from GetRouteInfo.
- struct RoutingRule {
- uint32_t table;
- IpRange destination_subnet;
- QuicIpAddress preferred_source;
- uint8_t scope;
- int out_interface;
- };
-
- struct IpRule {
- uint32_t table;
- IpRange source_range;
- };
-
- // Gets the list of routing rules from the main routing table (RT_TABLE_MAIN),
- // which is programmable.
- virtual bool GetRouteInfo(std::vector<RoutingRule>* routing_rules) = 0;
-
- // Performs the given Verb on the matching rule in the main routing table
- // (RT_TABLE_MAIN).
- //
- // preferred_source can be !IsInitialized(), in which case it will be omitted.
- //
- // For Verb::kRemove, rule matching is done by (destination_subnet, scope,
- // preferred_source, interface_index). Return true if a matching rule is
- // found. interface_index can be 0 for wilecard.
- //
- // For Verb::kAdd, rule matching is done by destination_subnet. If a rule for
- // the given destination_subnet already exists, nothing will happen and false
- // is returned.
- //
- // For Verb::kReplace, rule matching is done by destination_subnet. If no
- // matching rule is found, a new entry will be created.
- virtual bool ChangeRoute(Verb verb,
- uint32_t table,
- const IpRange& destination_subnet,
- uint8_t scope,
- QuicIpAddress preferred_source,
- int32_t interface_index) = 0;
-
- // Returns the set of all rules in the routing policy database.
- virtual bool GetRuleInfo(std::vector<IpRule>* ip_rules) = 0;
-
- // Performs the give verb on the matching rule in the routing policy database.
- // When deleting a rule, the |source_range| may be unspecified, in which case
- // the lowest priority rule from |table| will be removed. When adding a rule,
- // the |source_address| must be specified.
- virtual bool ChangeRule(Verb verb, uint32_t table, IpRange source_range) = 0;
-
- // Sends a netlink message to the kernel. iov and iovlen represents an array
- // of struct iovec to be fed into sendmsg. The caller needs to make sure the
- // message conform to what's expected by NLMSG_* macros.
- //
- // This can be useful if more flexibility is needed than the provided
- // convenient methods can provide.
- virtual bool Send(struct iovec* iov, size_t iovlen) = 0;
-
- // Receives a netlink message from the kernel.
- // parser will be called on the caller's stack.
- //
- // This can be useful if more flexibility is needed than the provided
- // convenient methods can provide.
- virtual bool Recv(uint32_t seq, NetlinkParserInterface* parser) = 0;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_QBONE_PLATFORM_NETLINK_INTERFACE_H_
diff --git a/chromium/net/third_party/quiche/src/quic/qbone/platform/netlink_test.cc b/chromium/net/third_party/quiche/src/quic/qbone/platform/netlink_test.cc
deleted file mode 100644
index f6fe7cda9df..00000000000
--- a/chromium/net/third_party/quiche/src/quic/qbone/platform/netlink_test.cc
+++ /dev/null
@@ -1,784 +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 "quic/qbone/platform/netlink.h"
-
-#include <utility>
-
-#include "absl/container/node_hash_set.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_containers.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/qbone/platform/mock_kernel.h"
-#include "quic/qbone/qbone_constants.h"
-
-namespace quic {
-namespace {
-
-using ::testing::_;
-using ::testing::Contains;
-using ::testing::InSequence;
-using ::testing::Invoke;
-using ::testing::Return;
-using ::testing::Unused;
-
-const int kSocketFd = 101;
-
-class NetlinkTest : public QuicTest {
- protected:
- NetlinkTest() {
- ON_CALL(mock_kernel_, socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE))
- .WillByDefault(Invoke([this](Unused, Unused, Unused) {
- EXPECT_CALL(mock_kernel_, close(kSocketFd)).WillOnce(Return(0));
- return kSocketFd;
- }));
- }
-
- void ExpectNetlinkPacket(
- uint16_t type,
- uint16_t flags,
- const std::function<ssize_t(void* buf, size_t len, int seq)>&
- recv_callback,
- const std::function<void(const void* buf, size_t len)>& send_callback =
- nullptr) {
- static int seq = -1;
- InSequence s;
-
- EXPECT_CALL(mock_kernel_, sendmsg(kSocketFd, _, _))
- .WillOnce(Invoke([type, flags, send_callback](
- Unused, const struct msghdr* msg, int) {
- EXPECT_EQ(sizeof(struct sockaddr_nl), msg->msg_namelen);
- auto* nl_addr =
- reinterpret_cast<const struct sockaddr_nl*>(msg->msg_name);
- EXPECT_EQ(AF_NETLINK, nl_addr->nl_family);
- EXPECT_EQ(0, nl_addr->nl_pid);
- EXPECT_EQ(0, nl_addr->nl_groups);
-
- EXPECT_GE(msg->msg_iovlen, 1);
- EXPECT_GE(msg->msg_iov[0].iov_len, sizeof(struct nlmsghdr));
-
- std::string buf;
- for (int i = 0; i < msg->msg_iovlen; i++) {
- buf.append(
- std::string(reinterpret_cast<char*>(msg->msg_iov[i].iov_base),
- msg->msg_iov[i].iov_len));
- }
-
- auto* netlink_message =
- reinterpret_cast<const struct nlmsghdr*>(buf.c_str());
- EXPECT_EQ(type, netlink_message->nlmsg_type);
- EXPECT_EQ(flags, netlink_message->nlmsg_flags);
- EXPECT_GE(buf.size(), netlink_message->nlmsg_len);
-
- if (send_callback != nullptr) {
- send_callback(buf.c_str(), buf.size());
- }
-
- QUICHE_CHECK_EQ(seq, -1);
- seq = netlink_message->nlmsg_seq;
- return buf.size();
- }));
-
- EXPECT_CALL(mock_kernel_,
- recvfrom(kSocketFd, _, 0, MSG_PEEK | MSG_TRUNC, _, _))
- .WillOnce(Invoke([this, recv_callback](Unused, Unused, Unused, Unused,
- struct sockaddr* src_addr,
- socklen_t* addrlen) {
- auto* nl_addr = reinterpret_cast<struct sockaddr_nl*>(src_addr);
- nl_addr->nl_family = AF_NETLINK;
- nl_addr->nl_pid = 0; // from kernel
- nl_addr->nl_groups = 0; // no multicast
-
- int ret = recv_callback(reply_packet_, sizeof(reply_packet_), seq);
- QUICHE_CHECK_LE(ret, sizeof(reply_packet_));
- return ret;
- }));
-
- EXPECT_CALL(mock_kernel_, recvfrom(kSocketFd, _, _, _, _, _))
- .WillOnce(Invoke([recv_callback](Unused, void* buf, size_t len, Unused,
- struct sockaddr* src_addr,
- socklen_t* addrlen) {
- auto* nl_addr = reinterpret_cast<struct sockaddr_nl*>(src_addr);
- nl_addr->nl_family = AF_NETLINK;
- nl_addr->nl_pid = 0; // from kernel
- nl_addr->nl_groups = 0; // no multicast
-
- int ret = recv_callback(buf, len, seq);
- EXPECT_GE(len, ret);
- seq = -1;
- return ret;
- }));
- }
-
- char reply_packet_[4096];
- MockKernel mock_kernel_;
-};
-
-void AddRTA(struct nlmsghdr* netlink_message,
- uint16_t type,
- const void* data,
- size_t len) {
- auto* next_header_ptr = reinterpret_cast<char*>(netlink_message) +
- NLMSG_ALIGN(netlink_message->nlmsg_len);
-
- auto* rta = reinterpret_cast<struct rtattr*>(next_header_ptr);
- rta->rta_type = type;
- rta->rta_len = RTA_LENGTH(len);
- memcpy(RTA_DATA(rta), data, len);
-
- netlink_message->nlmsg_len =
- NLMSG_ALIGN(netlink_message->nlmsg_len) + RTA_LENGTH(len);
-}
-
-void CreateIfinfomsg(struct nlmsghdr* netlink_message,
- const std::string& interface_name,
- uint16_t type,
- int index,
- unsigned int flags,
- unsigned int change,
- uint8_t address[],
- int address_len,
- uint8_t broadcast[],
- int broadcast_len) {
- auto* interface_info =
- reinterpret_cast<struct ifinfomsg*>(NLMSG_DATA(netlink_message));
- interface_info->ifi_family = AF_UNSPEC;
- interface_info->ifi_type = type;
- interface_info->ifi_index = index;
- interface_info->ifi_flags = flags;
- interface_info->ifi_change = change;
- netlink_message->nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg));
-
- // Add address
- AddRTA(netlink_message, IFLA_ADDRESS, address, address_len);
-
- // Add broadcast address
- AddRTA(netlink_message, IFLA_BROADCAST, broadcast, broadcast_len);
-
- // Add name
- AddRTA(netlink_message, IFLA_IFNAME, interface_name.c_str(),
- interface_name.size());
-}
-
-struct nlmsghdr* CreateNetlinkMessage(void* buf, // NOLINT
- struct nlmsghdr* previous_netlink_message,
- uint16_t type,
- int seq) {
- auto* next_header_ptr = reinterpret_cast<char*>(buf);
- if (previous_netlink_message != nullptr) {
- next_header_ptr = reinterpret_cast<char*>(previous_netlink_message) +
- NLMSG_ALIGN(previous_netlink_message->nlmsg_len);
- }
- auto* netlink_message = reinterpret_cast<nlmsghdr*>(next_header_ptr);
- netlink_message->nlmsg_len = NLMSG_LENGTH(0);
- netlink_message->nlmsg_type = type;
- netlink_message->nlmsg_flags = NLM_F_MULTI;
- netlink_message->nlmsg_pid = 0; // from the kernel
- netlink_message->nlmsg_seq = seq;
-
- return netlink_message;
-}
-
-void CreateIfaddrmsg(struct nlmsghdr* nlm,
- int interface_index,
- unsigned char prefixlen,
- unsigned char flags,
- unsigned char scope,
- QuicIpAddress ip) {
- QUICHE_CHECK(ip.IsInitialized());
- unsigned char family;
- switch (ip.address_family()) {
- case IpAddressFamily::IP_V4:
- family = AF_INET;
- break;
- case IpAddressFamily::IP_V6:
- family = AF_INET6;
- break;
- default:
- QUIC_BUG(quic_bug_11034_1)
- << absl::StrCat("unexpected address family: ", ip.address_family());
- family = AF_UNSPEC;
- }
- auto* msg = reinterpret_cast<struct ifaddrmsg*>(NLMSG_DATA(nlm));
- msg->ifa_family = family;
- msg->ifa_prefixlen = prefixlen;
- msg->ifa_flags = flags;
- msg->ifa_scope = scope;
- msg->ifa_index = interface_index;
- nlm->nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg));
-
- // Add local address
- AddRTA(nlm, IFA_LOCAL, ip.ToPackedString().c_str(),
- ip.ToPackedString().size());
-}
-
-void CreateRtmsg(struct nlmsghdr* nlm,
- unsigned char family,
- unsigned char destination_length,
- unsigned char source_length,
- unsigned char tos,
- unsigned char table,
- unsigned char protocol,
- unsigned char scope,
- unsigned char type,
- unsigned int flags,
- QuicIpAddress destination,
- int interface_index) {
- auto* msg = reinterpret_cast<struct rtmsg*>(NLMSG_DATA(nlm));
- msg->rtm_family = family;
- msg->rtm_dst_len = destination_length;
- msg->rtm_src_len = source_length;
- msg->rtm_tos = tos;
- msg->rtm_table = table;
- msg->rtm_protocol = protocol;
- msg->rtm_scope = scope;
- msg->rtm_type = type;
- msg->rtm_flags = flags;
- nlm->nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
-
- // Add destination
- AddRTA(nlm, RTA_DST, destination.ToPackedString().c_str(),
- destination.ToPackedString().size());
-
- // Add egress interface
- AddRTA(nlm, RTA_OIF, &interface_index, sizeof(interface_index));
-}
-
-TEST_F(NetlinkTest, GetLinkInfoWorks) {
- auto netlink = std::make_unique<Netlink>(&mock_kernel_);
-
- uint8_t hwaddr[] = {'a', 'b', 'c', 'd', 'e', 'f'};
- uint8_t bcaddr[] = {'c', 'b', 'a', 'f', 'e', 'd'};
-
- ExpectNetlinkPacket(
- RTM_GETLINK, NLM_F_ROOT | NLM_F_MATCH | NLM_F_REQUEST,
- [&hwaddr, &bcaddr](void* buf, size_t len, int seq) {
- int ret = 0;
-
- struct nlmsghdr* netlink_message =
- CreateNetlinkMessage(buf, nullptr, RTM_NEWLINK, seq);
- CreateIfinfomsg(netlink_message, "tun0", /* type = */ 1,
- /* index = */ 7,
- /* flags = */ 0,
- /* change = */ 0xFFFFFFFF, hwaddr, 6, bcaddr, 6);
- ret += NLMSG_ALIGN(netlink_message->nlmsg_len);
-
- netlink_message =
- CreateNetlinkMessage(buf, netlink_message, NLMSG_DONE, seq);
- ret += NLMSG_ALIGN(netlink_message->nlmsg_len);
-
- return ret;
- });
-
- Netlink::LinkInfo link_info;
- EXPECT_TRUE(netlink->GetLinkInfo("tun0", &link_info));
-
- EXPECT_EQ(7, link_info.index);
- EXPECT_EQ(1, link_info.type);
-
- for (int i = 0; i < link_info.hardware_address_length; ++i) {
- EXPECT_EQ(hwaddr[i], link_info.hardware_address[i]);
- }
- for (int i = 0; i < link_info.broadcast_address_length; ++i) {
- EXPECT_EQ(bcaddr[i], link_info.broadcast_address[i]);
- }
-}
-
-TEST_F(NetlinkTest, GetAddressesWorks) {
- auto netlink = std::make_unique<Netlink>(&mock_kernel_);
-
- absl::node_hash_set<std::string> addresses = {
- QuicIpAddress::Any4().ToString(), QuicIpAddress::Any6().ToString()};
-
- ExpectNetlinkPacket(
- RTM_GETADDR, NLM_F_ROOT | NLM_F_MATCH | NLM_F_REQUEST,
- [&addresses](void* buf, size_t len, int seq) {
- int ret = 0;
-
- struct nlmsghdr* nlm = nullptr;
-
- for (const auto& address : addresses) {
- QuicIpAddress ip;
- ip.FromString(address);
- nlm = CreateNetlinkMessage(buf, nlm, RTM_NEWADDR, seq);
- CreateIfaddrmsg(nlm, /* interface_index = */ 7, /* prefixlen = */ 24,
- /* flags = */ 0, /* scope = */ RT_SCOPE_UNIVERSE, ip);
-
- ret += NLMSG_ALIGN(nlm->nlmsg_len);
- }
-
- // Create IPs with unwanted flags.
- {
- QuicIpAddress ip;
- ip.FromString("10.0.0.1");
- nlm = CreateNetlinkMessage(buf, nlm, RTM_NEWADDR, seq);
- CreateIfaddrmsg(nlm, /* interface_index = */ 7, /* prefixlen = */ 16,
- /* flags = */ IFA_F_OPTIMISTIC, /* scope = */
- RT_SCOPE_UNIVERSE, ip);
-
- ret += NLMSG_ALIGN(nlm->nlmsg_len);
-
- ip.FromString("10.0.0.2");
- nlm = CreateNetlinkMessage(buf, nlm, RTM_NEWADDR, seq);
- CreateIfaddrmsg(nlm, /* interface_index = */ 7, /* prefixlen = */ 16,
- /* flags = */ IFA_F_TENTATIVE, /* scope = */
- RT_SCOPE_UNIVERSE, ip);
-
- ret += NLMSG_ALIGN(nlm->nlmsg_len);
- }
-
- nlm = CreateNetlinkMessage(buf, nlm, NLMSG_DONE, seq);
- ret += NLMSG_ALIGN(nlm->nlmsg_len);
-
- return ret;
- });
-
- std::vector<Netlink::AddressInfo> reported_addresses;
- int num_ipv6_nodad_dadfailed_addresses = 0;
- EXPECT_TRUE(netlink->GetAddresses(7, IFA_F_TENTATIVE | IFA_F_OPTIMISTIC,
- &reported_addresses,
- &num_ipv6_nodad_dadfailed_addresses));
-
- for (const auto& reported_address : reported_addresses) {
- EXPECT_TRUE(reported_address.local_address.IsInitialized());
- EXPECT_FALSE(reported_address.interface_address.IsInitialized());
- EXPECT_THAT(addresses, Contains(reported_address.local_address.ToString()));
- addresses.erase(reported_address.local_address.ToString());
-
- EXPECT_EQ(24, reported_address.prefix_length);
- }
-
- EXPECT_TRUE(addresses.empty());
-}
-
-TEST_F(NetlinkTest, ChangeLocalAddressAdd) {
- auto netlink = std::make_unique<Netlink>(&mock_kernel_);
-
- QuicIpAddress ip = QuicIpAddress::Any6();
- ExpectNetlinkPacket(
- RTM_NEWADDR, NLM_F_ACK | NLM_F_REQUEST,
- [](void* buf, size_t len, int seq) {
- struct nlmsghdr* netlink_message =
- CreateNetlinkMessage(buf, nullptr, NLMSG_ERROR, seq);
- auto* err =
- reinterpret_cast<struct nlmsgerr*>(NLMSG_DATA(netlink_message));
- // Ack the request
- err->error = 0;
- netlink_message->nlmsg_len = NLMSG_LENGTH(sizeof(struct nlmsgerr));
- return netlink_message->nlmsg_len;
- },
- [ip](const void* buf, size_t len) {
- auto* netlink_message = reinterpret_cast<const struct nlmsghdr*>(buf);
- auto* ifa = reinterpret_cast<const struct ifaddrmsg*>(
- NLMSG_DATA(netlink_message));
- EXPECT_EQ(19, ifa->ifa_prefixlen);
- EXPECT_EQ(RT_SCOPE_UNIVERSE, ifa->ifa_scope);
- EXPECT_EQ(IFA_F_PERMANENT, ifa->ifa_flags);
- EXPECT_EQ(7, ifa->ifa_index);
- EXPECT_EQ(AF_INET6, ifa->ifa_family);
-
- const struct rtattr* rta;
- int payload_length = IFA_PAYLOAD(netlink_message);
- int num_rta = 0;
- for (rta = IFA_RTA(ifa); RTA_OK(rta, payload_length);
- rta = RTA_NEXT(rta, payload_length)) {
- switch (rta->rta_type) {
- case IFA_LOCAL: {
- EXPECT_EQ(ip.ToPackedString().size(), RTA_PAYLOAD(rta));
- const auto* raw_address =
- reinterpret_cast<const char*>(RTA_DATA(rta));
- ASSERT_EQ(sizeof(in6_addr), RTA_PAYLOAD(rta));
- QuicIpAddress address;
- address.FromPackedString(raw_address, RTA_PAYLOAD(rta));
- EXPECT_EQ(ip, address);
- break;
- }
- case IFA_CACHEINFO: {
- EXPECT_EQ(sizeof(struct ifa_cacheinfo), RTA_PAYLOAD(rta));
- const auto* cache_info =
- reinterpret_cast<const struct ifa_cacheinfo*>(RTA_DATA(rta));
- EXPECT_EQ(8, cache_info->ifa_prefered); // common_typos_disable
- EXPECT_EQ(6, cache_info->ifa_valid);
- EXPECT_EQ(4, cache_info->cstamp);
- EXPECT_EQ(2, cache_info->tstamp);
- break;
- }
- default:
- EXPECT_TRUE(false) << "Seeing rtattr that should not exist";
- }
- ++num_rta;
- }
- EXPECT_EQ(2, num_rta);
- });
-
- struct {
- struct rtattr rta;
- struct ifa_cacheinfo cache_info;
- } additional_rta;
-
- additional_rta.rta.rta_type = IFA_CACHEINFO;
- additional_rta.rta.rta_len = RTA_LENGTH(sizeof(struct ifa_cacheinfo));
- additional_rta.cache_info.ifa_prefered = 8;
- additional_rta.cache_info.ifa_valid = 6;
- additional_rta.cache_info.cstamp = 4;
- additional_rta.cache_info.tstamp = 2;
-
- EXPECT_TRUE(netlink->ChangeLocalAddress(7, Netlink::Verb::kAdd, ip, 19,
- IFA_F_PERMANENT, RT_SCOPE_UNIVERSE,
- {&additional_rta.rta}));
-}
-
-TEST_F(NetlinkTest, ChangeLocalAddressRemove) {
- auto netlink = std::make_unique<Netlink>(&mock_kernel_);
-
- QuicIpAddress ip = QuicIpAddress::Any4();
- ExpectNetlinkPacket(
- RTM_DELADDR, NLM_F_ACK | NLM_F_REQUEST,
- [](void* buf, size_t len, int seq) {
- struct nlmsghdr* netlink_message =
- CreateNetlinkMessage(buf, nullptr, NLMSG_ERROR, seq);
- auto* err =
- reinterpret_cast<struct nlmsgerr*>(NLMSG_DATA(netlink_message));
- // Ack the request
- err->error = 0;
- netlink_message->nlmsg_len = NLMSG_LENGTH(sizeof(struct nlmsgerr));
- return netlink_message->nlmsg_len;
- },
- [ip](const void* buf, size_t len) {
- auto* netlink_message = reinterpret_cast<const struct nlmsghdr*>(buf);
- auto* ifa = reinterpret_cast<const struct ifaddrmsg*>(
- NLMSG_DATA(netlink_message));
- EXPECT_EQ(32, ifa->ifa_prefixlen);
- EXPECT_EQ(RT_SCOPE_UNIVERSE, ifa->ifa_scope);
- EXPECT_EQ(0, ifa->ifa_flags);
- EXPECT_EQ(7, ifa->ifa_index);
- EXPECT_EQ(AF_INET, ifa->ifa_family);
-
- const struct rtattr* rta;
- int payload_length = IFA_PAYLOAD(netlink_message);
- int num_rta = 0;
- for (rta = IFA_RTA(ifa); RTA_OK(rta, payload_length);
- rta = RTA_NEXT(rta, payload_length)) {
- switch (rta->rta_type) {
- case IFA_LOCAL: {
- const auto* raw_address =
- reinterpret_cast<const char*>(RTA_DATA(rta));
- ASSERT_EQ(sizeof(in_addr), RTA_PAYLOAD(rta));
- QuicIpAddress address;
- address.FromPackedString(raw_address, RTA_PAYLOAD(rta));
- EXPECT_EQ(ip, address);
- break;
- }
- default:
- EXPECT_TRUE(false) << "Seeing rtattr that should not exist";
- }
- ++num_rta;
- }
- EXPECT_EQ(1, num_rta);
- });
-
- EXPECT_TRUE(netlink->ChangeLocalAddress(7, Netlink::Verb::kRemove, ip, 32, 0,
- RT_SCOPE_UNIVERSE, {}));
-}
-
-TEST_F(NetlinkTest, GetRouteInfoWorks) {
- auto netlink = std::make_unique<Netlink>(&mock_kernel_);
-
- QuicIpAddress destination;
- ASSERT_TRUE(destination.FromString("f800::2"));
- ExpectNetlinkPacket(RTM_GETROUTE, NLM_F_ROOT | NLM_F_MATCH | NLM_F_REQUEST,
- [destination](void* buf, size_t len, int seq) {
- int ret = 0;
- struct nlmsghdr* netlink_message = CreateNetlinkMessage(
- buf, nullptr, RTM_NEWROUTE, seq);
- CreateRtmsg(netlink_message, AF_INET6, 48, 0, 0,
- RT_TABLE_MAIN, RTPROT_STATIC, RT_SCOPE_LINK,
- RTN_UNICAST, 0, destination, 7);
- ret += NLMSG_ALIGN(netlink_message->nlmsg_len);
-
- netlink_message = CreateNetlinkMessage(
- buf, netlink_message, NLMSG_DONE, seq);
- ret += NLMSG_ALIGN(netlink_message->nlmsg_len);
-
- QUIC_LOG(INFO) << "ret: " << ret;
- return ret;
- });
-
- std::vector<Netlink::RoutingRule> routing_rules;
- EXPECT_TRUE(netlink->GetRouteInfo(&routing_rules));
-
- ASSERT_EQ(1, routing_rules.size());
- EXPECT_EQ(RT_SCOPE_LINK, routing_rules[0].scope);
- EXPECT_EQ(IpRange(destination, 48).ToString(),
- routing_rules[0].destination_subnet.ToString());
- EXPECT_FALSE(routing_rules[0].preferred_source.IsInitialized());
- EXPECT_EQ(7, routing_rules[0].out_interface);
-}
-
-TEST_F(NetlinkTest, ChangeRouteAdd) {
- auto netlink = std::make_unique<Netlink>(&mock_kernel_);
-
- QuicIpAddress preferred_ip;
- preferred_ip.FromString("ff80:dead:beef::1");
- IpRange subnet;
- subnet.FromString("ff80:dead:beef::/48");
- int egress_interface_index = 7;
- ExpectNetlinkPacket(
- RTM_NEWROUTE, NLM_F_ACK | NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL,
- [](void* buf, size_t len, int seq) {
- struct nlmsghdr* netlink_message =
- CreateNetlinkMessage(buf, nullptr, NLMSG_ERROR, seq);
- auto* err =
- reinterpret_cast<struct nlmsgerr*>(NLMSG_DATA(netlink_message));
- // Ack the request
- err->error = 0;
- netlink_message->nlmsg_len = NLMSG_LENGTH(sizeof(struct nlmsgerr));
- return netlink_message->nlmsg_len;
- },
- [preferred_ip, subnet, egress_interface_index](const void* buf,
- size_t len) {
- auto* netlink_message = reinterpret_cast<const struct nlmsghdr*>(buf);
- auto* rtm =
- reinterpret_cast<const struct rtmsg*>(NLMSG_DATA(netlink_message));
- EXPECT_EQ(AF_INET6, rtm->rtm_family);
- EXPECT_EQ(48, rtm->rtm_dst_len);
- EXPECT_EQ(0, rtm->rtm_src_len);
- EXPECT_EQ(RT_TABLE_MAIN, rtm->rtm_table);
- EXPECT_EQ(RTPROT_STATIC, rtm->rtm_protocol);
- EXPECT_EQ(RT_SCOPE_LINK, rtm->rtm_scope);
- EXPECT_EQ(RTN_UNICAST, rtm->rtm_type);
-
- const struct rtattr* rta;
- int payload_length = RTM_PAYLOAD(netlink_message);
- int num_rta = 0;
- for (rta = RTM_RTA(rtm); RTA_OK(rta, payload_length);
- rta = RTA_NEXT(rta, payload_length)) {
- switch (rta->rta_type) {
- case RTA_PREFSRC: {
- const auto* raw_address =
- reinterpret_cast<const char*>(RTA_DATA(rta));
- ASSERT_EQ(sizeof(struct in6_addr), RTA_PAYLOAD(rta));
- QuicIpAddress address;
- address.FromPackedString(raw_address, RTA_PAYLOAD(rta));
- EXPECT_EQ(preferred_ip, address);
- break;
- }
- case RTA_GATEWAY: {
- const auto* raw_address =
- reinterpret_cast<const char*>(RTA_DATA(rta));
- ASSERT_EQ(sizeof(struct in6_addr), RTA_PAYLOAD(rta));
- QuicIpAddress address;
- address.FromPackedString(raw_address, RTA_PAYLOAD(rta));
- EXPECT_EQ(*QboneConstants::GatewayAddress(), address);
- break;
- }
- case RTA_OIF: {
- ASSERT_EQ(sizeof(int), RTA_PAYLOAD(rta));
- const auto* interface_index =
- reinterpret_cast<const int*>(RTA_DATA(rta));
- EXPECT_EQ(egress_interface_index, *interface_index);
- break;
- }
- case RTA_DST: {
- const auto* raw_address =
- reinterpret_cast<const char*>(RTA_DATA(rta));
- ASSERT_EQ(sizeof(struct in6_addr), RTA_PAYLOAD(rta));
- QuicIpAddress address;
- address.FromPackedString(raw_address, RTA_PAYLOAD(rta));
- EXPECT_EQ(subnet.ToString(),
- IpRange(address, rtm->rtm_dst_len).ToString());
- break;
- }
- case RTA_TABLE: {
- ASSERT_EQ(*reinterpret_cast<uint32_t*>(RTA_DATA(rta)),
- QboneConstants::kQboneRouteTableId);
- break;
- }
- default:
- EXPECT_TRUE(false) << "Seeing rtattr that should not be sent";
- }
- ++num_rta;
- }
- EXPECT_EQ(5, num_rta);
- });
- EXPECT_TRUE(netlink->ChangeRoute(
- Netlink::Verb::kAdd, QboneConstants::kQboneRouteTableId, subnet,
- RT_SCOPE_LINK, preferred_ip, egress_interface_index));
-}
-
-TEST_F(NetlinkTest, ChangeRouteRemove) {
- auto netlink = std::make_unique<Netlink>(&mock_kernel_);
-
- QuicIpAddress preferred_ip;
- preferred_ip.FromString("ff80:dead:beef::1");
- IpRange subnet;
- subnet.FromString("ff80:dead:beef::/48");
- int egress_interface_index = 7;
- ExpectNetlinkPacket(
- RTM_DELROUTE, NLM_F_ACK | NLM_F_REQUEST,
- [](void* buf, size_t len, int seq) {
- struct nlmsghdr* netlink_message =
- CreateNetlinkMessage(buf, nullptr, NLMSG_ERROR, seq);
- auto* err =
- reinterpret_cast<struct nlmsgerr*>(NLMSG_DATA(netlink_message));
- // Ack the request
- err->error = 0;
- netlink_message->nlmsg_len = NLMSG_LENGTH(sizeof(struct nlmsgerr));
- return netlink_message->nlmsg_len;
- },
- [preferred_ip, subnet, egress_interface_index](const void* buf,
- size_t len) {
- auto* netlink_message = reinterpret_cast<const struct nlmsghdr*>(buf);
- auto* rtm =
- reinterpret_cast<const struct rtmsg*>(NLMSG_DATA(netlink_message));
- EXPECT_EQ(AF_INET6, rtm->rtm_family);
- EXPECT_EQ(48, rtm->rtm_dst_len);
- EXPECT_EQ(0, rtm->rtm_src_len);
- EXPECT_EQ(RT_TABLE_MAIN, rtm->rtm_table);
- EXPECT_EQ(RTPROT_UNSPEC, rtm->rtm_protocol);
- EXPECT_EQ(RT_SCOPE_LINK, rtm->rtm_scope);
- EXPECT_EQ(RTN_UNICAST, rtm->rtm_type);
-
- const struct rtattr* rta;
- int payload_length = RTM_PAYLOAD(netlink_message);
- int num_rta = 0;
- for (rta = RTM_RTA(rtm); RTA_OK(rta, payload_length);
- rta = RTA_NEXT(rta, payload_length)) {
- switch (rta->rta_type) {
- case RTA_PREFSRC: {
- const auto* raw_address =
- reinterpret_cast<const char*>(RTA_DATA(rta));
- ASSERT_EQ(sizeof(struct in6_addr), RTA_PAYLOAD(rta));
- QuicIpAddress address;
- address.FromPackedString(raw_address, RTA_PAYLOAD(rta));
- EXPECT_EQ(preferred_ip, address);
- break;
- }
- case RTA_OIF: {
- ASSERT_EQ(sizeof(int), RTA_PAYLOAD(rta));
- const auto* interface_index =
- reinterpret_cast<const int*>(RTA_DATA(rta));
- EXPECT_EQ(egress_interface_index, *interface_index);
- break;
- }
- case RTA_DST: {
- const auto* raw_address =
- reinterpret_cast<const char*>(RTA_DATA(rta));
- ASSERT_EQ(sizeof(struct in6_addr), RTA_PAYLOAD(rta));
- QuicIpAddress address;
- address.FromPackedString(raw_address, RTA_PAYLOAD(rta));
- EXPECT_EQ(subnet.ToString(),
- IpRange(address, rtm->rtm_dst_len).ToString());
- break;
- }
- case RTA_TABLE: {
- ASSERT_EQ(*reinterpret_cast<uint32_t*>(RTA_DATA(rta)),
- QboneConstants::kQboneRouteTableId);
- break;
- }
- default:
- EXPECT_TRUE(false) << "Seeing rtattr that should not be sent";
- }
- ++num_rta;
- }
- EXPECT_EQ(4, num_rta);
- });
- EXPECT_TRUE(netlink->ChangeRoute(
- Netlink::Verb::kRemove, QboneConstants::kQboneRouteTableId, subnet,
- RT_SCOPE_LINK, preferred_ip, egress_interface_index));
-}
-
-TEST_F(NetlinkTest, ChangeRouteReplace) {
- auto netlink = std::make_unique<Netlink>(&mock_kernel_);
-
- QuicIpAddress preferred_ip;
- preferred_ip.FromString("ff80:dead:beef::1");
- IpRange subnet;
- subnet.FromString("ff80:dead:beef::/48");
- int egress_interface_index = 7;
- ExpectNetlinkPacket(
- RTM_NEWROUTE, NLM_F_ACK | NLM_F_REQUEST | NLM_F_CREATE | NLM_F_REPLACE,
- [](void* buf, size_t len, int seq) {
- struct nlmsghdr* netlink_message =
- CreateNetlinkMessage(buf, nullptr, NLMSG_ERROR, seq);
- auto* err =
- reinterpret_cast<struct nlmsgerr*>(NLMSG_DATA(netlink_message));
- // Ack the request
- err->error = 0;
- netlink_message->nlmsg_len = NLMSG_LENGTH(sizeof(struct nlmsgerr));
- return netlink_message->nlmsg_len;
- },
- [preferred_ip, subnet, egress_interface_index](const void* buf,
- size_t len) {
- auto* netlink_message = reinterpret_cast<const struct nlmsghdr*>(buf);
- auto* rtm =
- reinterpret_cast<const struct rtmsg*>(NLMSG_DATA(netlink_message));
- EXPECT_EQ(AF_INET6, rtm->rtm_family);
- EXPECT_EQ(48, rtm->rtm_dst_len);
- EXPECT_EQ(0, rtm->rtm_src_len);
- EXPECT_EQ(RT_TABLE_MAIN, rtm->rtm_table);
- EXPECT_EQ(RTPROT_STATIC, rtm->rtm_protocol);
- EXPECT_EQ(RT_SCOPE_LINK, rtm->rtm_scope);
- EXPECT_EQ(RTN_UNICAST, rtm->rtm_type);
-
- const struct rtattr* rta;
- int payload_length = RTM_PAYLOAD(netlink_message);
- int num_rta = 0;
- for (rta = RTM_RTA(rtm); RTA_OK(rta, payload_length);
- rta = RTA_NEXT(rta, payload_length)) {
- switch (rta->rta_type) {
- case RTA_PREFSRC: {
- const auto* raw_address =
- reinterpret_cast<const char*>(RTA_DATA(rta));
- ASSERT_EQ(sizeof(struct in6_addr), RTA_PAYLOAD(rta));
- QuicIpAddress address;
- address.FromPackedString(raw_address, RTA_PAYLOAD(rta));
- EXPECT_EQ(preferred_ip, address);
- break;
- }
- case RTA_GATEWAY: {
- const auto* raw_address =
- reinterpret_cast<const char*>(RTA_DATA(rta));
- ASSERT_EQ(sizeof(struct in6_addr), RTA_PAYLOAD(rta));
- QuicIpAddress address;
- address.FromPackedString(raw_address, RTA_PAYLOAD(rta));
- EXPECT_EQ(*QboneConstants::GatewayAddress(), address);
- break;
- }
- case RTA_OIF: {
- ASSERT_EQ(sizeof(int), RTA_PAYLOAD(rta));
- const auto* interface_index =
- reinterpret_cast<const int*>(RTA_DATA(rta));
- EXPECT_EQ(egress_interface_index, *interface_index);
- break;
- }
- case RTA_DST: {
- const auto* raw_address =
- reinterpret_cast<const char*>(RTA_DATA(rta));
- ASSERT_EQ(sizeof(struct in6_addr), RTA_PAYLOAD(rta));
- QuicIpAddress address;
- address.FromPackedString(raw_address, RTA_PAYLOAD(rta));
- EXPECT_EQ(subnet.ToString(),
- IpRange(address, rtm->rtm_dst_len).ToString());
- break;
- }
- case RTA_TABLE: {
- ASSERT_EQ(*reinterpret_cast<uint32_t*>(RTA_DATA(rta)),
- QboneConstants::kQboneRouteTableId);
- break;
- }
- default:
- EXPECT_TRUE(false) << "Seeing rtattr that should not be sent";
- }
- ++num_rta;
- }
- EXPECT_EQ(5, num_rta);
- });
- EXPECT_TRUE(netlink->ChangeRoute(
- Netlink::Verb::kReplace, QboneConstants::kQboneRouteTableId, subnet,
- RT_SCOPE_LINK, preferred_ip, egress_interface_index));
-}
-
-} // namespace
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/qbone/platform/rtnetlink_message.cc b/chromium/net/third_party/quiche/src/quic/qbone/platform/rtnetlink_message.cc
deleted file mode 100644
index 24709e7d1c3..00000000000
--- a/chromium/net/third_party/quiche/src/quic/qbone/platform/rtnetlink_message.cc
+++ /dev/null
@@ -1,177 +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 "quic/qbone/platform/rtnetlink_message.h"
-
-#include <utility>
-
-namespace quic {
-
-RtnetlinkMessage::RtnetlinkMessage(uint16_t type,
- uint16_t flags,
- uint32_t seq,
- uint32_t pid,
- const void* payload_header,
- size_t payload_header_length) {
- auto* buf = new uint8_t[NLMSG_SPACE(payload_header_length)];
- memset(buf, 0, NLMSG_SPACE(payload_header_length));
-
- auto* message_header = reinterpret_cast<struct nlmsghdr*>(buf);
- message_header->nlmsg_len = NLMSG_LENGTH(payload_header_length);
- message_header->nlmsg_type = type;
- message_header->nlmsg_flags = flags;
- message_header->nlmsg_seq = seq;
- message_header->nlmsg_pid = pid;
-
- if (payload_header != nullptr) {
- memcpy(NLMSG_DATA(message_header), payload_header, payload_header_length);
- }
- message_.push_back({buf, NLMSG_SPACE(payload_header_length)});
-}
-
-RtnetlinkMessage::~RtnetlinkMessage() {
- for (const auto& iov : message_) {
- delete[] reinterpret_cast<uint8_t*>(iov.iov_base);
- }
-}
-
-void RtnetlinkMessage::AppendAttribute(uint16_t type,
- const void* data,
- uint16_t data_length) {
- auto* buf = new uint8_t[RTA_SPACE(data_length)];
- memset(buf, 0, RTA_SPACE(data_length));
-
- auto* rta = reinterpret_cast<struct rtattr*>(buf);
- static_assert(sizeof(uint16_t) == sizeof(rta->rta_len),
- "struct rtattr uses unsigned short, it's no longer 16bits");
- static_assert(sizeof(uint16_t) == sizeof(rta->rta_type),
- "struct rtattr uses unsigned short, it's no longer 16bits");
-
- rta->rta_len = RTA_LENGTH(data_length);
- rta->rta_type = type;
- memcpy(RTA_DATA(rta), data, data_length);
-
- message_.push_back({buf, RTA_SPACE(data_length)});
- AdjustMessageLength(rta->rta_len);
-}
-
-std::unique_ptr<struct iovec[]> RtnetlinkMessage::BuildIoVec() const {
- auto message = std::make_unique<struct iovec[]>(message_.size());
- int idx = 0;
- for (const auto& vec : message_) {
- message[idx++] = vec;
- }
- return message;
-}
-
-size_t RtnetlinkMessage::IoVecSize() const {
- return message_.size();
-}
-
-void RtnetlinkMessage::AdjustMessageLength(size_t additional_data_length) {
- MessageHeader()->nlmsg_len =
- NLMSG_ALIGN(MessageHeader()->nlmsg_len) + additional_data_length;
-}
-
-struct nlmsghdr* RtnetlinkMessage::MessageHeader() {
- return reinterpret_cast<struct nlmsghdr*>(message_[0].iov_base);
-}
-
-LinkMessage LinkMessage::New(RtnetlinkMessage::Operation request_operation,
- uint16_t flags,
- uint32_t seq,
- uint32_t pid,
- const struct ifinfomsg* interface_info_header) {
- uint16_t request_type;
- switch (request_operation) {
- case RtnetlinkMessage::Operation::NEW:
- request_type = RTM_NEWLINK;
- break;
- case RtnetlinkMessage::Operation::DEL:
- request_type = RTM_DELLINK;
- break;
- case RtnetlinkMessage::Operation::GET:
- request_type = RTM_GETLINK;
- break;
- }
- bool is_get = request_type == RTM_GETLINK;
-
- if (is_get) {
- struct rtgenmsg g = {AF_UNSPEC};
- return LinkMessage(request_type, flags, seq, pid, &g, sizeof(g));
- }
- return LinkMessage(request_type, flags, seq, pid, interface_info_header,
- sizeof(struct ifinfomsg));
-}
-
-AddressMessage AddressMessage::New(
- RtnetlinkMessage::Operation request_operation,
- uint16_t flags,
- uint32_t seq,
- uint32_t pid,
- const struct ifaddrmsg* interface_address_header) {
- uint16_t request_type;
- switch (request_operation) {
- case RtnetlinkMessage::Operation::NEW:
- request_type = RTM_NEWADDR;
- break;
- case RtnetlinkMessage::Operation::DEL:
- request_type = RTM_DELADDR;
- break;
- case RtnetlinkMessage::Operation::GET:
- request_type = RTM_GETADDR;
- break;
- }
- bool is_get = request_type == RTM_GETADDR;
-
- if (is_get) {
- struct rtgenmsg g = {AF_UNSPEC};
- return AddressMessage(request_type, flags, seq, pid, &g, sizeof(g));
- }
- return AddressMessage(request_type, flags, seq, pid, interface_address_header,
- sizeof(struct ifaddrmsg));
-}
-
-RouteMessage RouteMessage::New(RtnetlinkMessage::Operation request_operation,
- uint16_t flags,
- uint32_t seq,
- uint32_t pid,
- const struct rtmsg* route_message_header) {
- uint16_t request_type;
- switch (request_operation) {
- case RtnetlinkMessage::Operation::NEW:
- request_type = RTM_NEWROUTE;
- break;
- case RtnetlinkMessage::Operation::DEL:
- request_type = RTM_DELROUTE;
- break;
- case RtnetlinkMessage::Operation::GET:
- request_type = RTM_GETROUTE;
- break;
- }
- return RouteMessage(request_type, flags, seq, pid, route_message_header,
- sizeof(struct rtmsg));
-}
-
-RuleMessage RuleMessage::New(RtnetlinkMessage::Operation request_operation,
- uint16_t flags,
- uint32_t seq,
- uint32_t pid,
- const struct rtmsg* rule_message_header) {
- uint16_t request_type;
- switch (request_operation) {
- case RtnetlinkMessage::Operation::NEW:
- request_type = RTM_NEWRULE;
- break;
- case RtnetlinkMessage::Operation::DEL:
- request_type = RTM_DELRULE;
- break;
- case RtnetlinkMessage::Operation::GET:
- request_type = RTM_GETRULE;
- break;
- }
- return RuleMessage(request_type, flags, seq, pid, rule_message_header,
- sizeof(rtmsg));
-}
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/qbone/platform/rtnetlink_message.h b/chromium/net/third_party/quiche/src/quic/qbone/platform/rtnetlink_message.h
deleted file mode 100644
index e67da1bcaa2..00000000000
--- a/chromium/net/third_party/quiche/src/quic/qbone/platform/rtnetlink_message.h
+++ /dev/null
@@ -1,125 +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_QBONE_PLATFORM_RTNETLINK_MESSAGE_H_
-#define QUICHE_QUIC_QBONE_PLATFORM_RTNETLINK_MESSAGE_H_
-
-#include <linux/netlink.h>
-#include <linux/rtnetlink.h>
-#include <stdint.h>
-#include <sys/socket.h>
-#include <sys/uio.h>
-
-#include <memory>
-#include <vector>
-
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-// This base class is used to construct an array struct iovec that represents a
-// rtnetlink message as defined in man 7 rtnet. Padding for message header
-// alignment to conform NLMSG_* and RTA_* macros is added at the end of each
-// iovec::iov_base.
-class RtnetlinkMessage {
- public:
- virtual ~RtnetlinkMessage();
-
- enum class Operation {
- NEW,
- DEL,
- GET,
- };
-
- // Appends a struct rtattr to the message. nlmsg_len and rta_len is handled
- // properly.
- // Override this to perform check on type.
- virtual void AppendAttribute(uint16_t type,
- const void* data,
- uint16_t data_length);
-
- // Builds the array of iovec that can be fed into sendmsg directly.
- std::unique_ptr<struct iovec[]> BuildIoVec() const;
-
- // The size of the array of iovec if BuildIovec is called.
- size_t IoVecSize() const;
-
- protected:
- // Subclass should add their own message header immediately after the
- // nlmsghdr. Make this private to force the creation of such header.
- RtnetlinkMessage(uint16_t type,
- uint16_t flags,
- uint32_t seq,
- uint32_t pid,
- const void* payload_header,
- size_t payload_header_length);
-
- // Adjusts nlmsg_len in the header assuming additional_data_length is appended
- // at the end.
- void AdjustMessageLength(size_t additional_data_length);
-
- private:
- // Convenient function for accessing the nlmsghdr.
- struct nlmsghdr* MessageHeader();
-
- std::vector<struct iovec> message_;
-};
-
-// Message for manipulating link level configuration as defined in man 7
-// rtnetlink. RTM_NEWLINK, RTM_DELLINK and RTM_GETLINK are supported.
-class LinkMessage : public RtnetlinkMessage {
- public:
- static LinkMessage New(RtnetlinkMessage::Operation request_operation,
- uint16_t flags,
- uint32_t seq,
- uint32_t pid,
- const struct ifinfomsg* interface_info_header);
-
- private:
- using RtnetlinkMessage::RtnetlinkMessage;
-};
-
-// Message for manipulating address level configuration as defined in man 7
-// rtnetlink. RTM_NEWADDR, RTM_NEWADDR and RTM_GETADDR are supported.
-class AddressMessage : public RtnetlinkMessage {
- public:
- static AddressMessage New(RtnetlinkMessage::Operation request_operation,
- uint16_t flags,
- uint32_t seq,
- uint32_t pid,
- const struct ifaddrmsg* interface_address_header);
-
- private:
- using RtnetlinkMessage::RtnetlinkMessage;
-};
-
-// Message for manipulating routing table as defined in man 7 rtnetlink.
-// RTM_NEWROUTE, RTM_DELROUTE and RTM_GETROUTE are supported.
-class RouteMessage : public RtnetlinkMessage {
- public:
- static RouteMessage New(RtnetlinkMessage::Operation request_operation,
- uint16_t flags,
- uint32_t seq,
- uint32_t pid,
- const struct rtmsg* route_message_header);
-
- private:
- using RtnetlinkMessage::RtnetlinkMessage;
-};
-
-class RuleMessage : public RtnetlinkMessage {
- public:
- static RuleMessage New(RtnetlinkMessage::Operation request_operation,
- uint16_t flags,
- uint32_t seq,
- uint32_t pid,
- const struct rtmsg* rule_message_header);
-
- private:
- using RtnetlinkMessage::RtnetlinkMessage;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_QBONE_PLATFORM_RTNETLINK_MESSAGE_H_
diff --git a/chromium/net/third_party/quiche/src/quic/qbone/platform/rtnetlink_message_test.cc b/chromium/net/third_party/quiche/src/quic/qbone/platform/rtnetlink_message_test.cc
deleted file mode 100644
index f2d9d929dae..00000000000
--- a/chromium/net/third_party/quiche/src/quic/qbone/platform/rtnetlink_message_test.cc
+++ /dev/null
@@ -1,229 +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 "quic/qbone/platform/rtnetlink_message.h"
-
-#include <net/if_arp.h>
-
-#include "quic/platform/api/quic_ip_address.h"
-#include "quic/platform/api/quic_test.h"
-
-namespace quic {
-namespace {
-
-using ::testing::StrEq;
-
-TEST(RtnetlinkMessageTest, LinkMessageCanBeCreatedForGetOperation) {
- uint16_t flags = NLM_F_REQUEST | NLM_F_ROOT | NLM_F_MATCH;
- uint32_t seq = 42;
- uint32_t pid = 7;
- auto message = LinkMessage::New(RtnetlinkMessage::Operation::GET, flags, seq,
- pid, nullptr);
-
- // No rtattr appended.
- EXPECT_EQ(1, message.IoVecSize());
-
- // nlmsghdr is built properly.
- auto iov = message.BuildIoVec();
- EXPECT_EQ(NLMSG_SPACE(sizeof(struct rtgenmsg)), iov[0].iov_len);
- auto* netlink_message = reinterpret_cast<struct nlmsghdr*>(iov[0].iov_base);
- EXPECT_EQ(NLMSG_LENGTH(sizeof(struct rtgenmsg)), netlink_message->nlmsg_len);
- EXPECT_EQ(RTM_GETLINK, netlink_message->nlmsg_type);
- EXPECT_EQ(flags, netlink_message->nlmsg_flags);
- EXPECT_EQ(seq, netlink_message->nlmsg_seq);
- EXPECT_EQ(pid, netlink_message->nlmsg_pid);
-
- // We actually included rtgenmsg instead of the passed in ifinfomsg since this
- // is a GET operation.
- EXPECT_EQ(NLMSG_LENGTH(sizeof(struct rtgenmsg)), netlink_message->nlmsg_len);
-}
-
-TEST(RtnetlinkMessageTest, LinkMessageCanBeCreatedForNewOperation) {
- struct ifinfomsg interface_info_header = {AF_INET, /* pad */ 0, ARPHRD_TUNNEL,
- 3, 0, 0xffffffff};
- uint16_t flags = NLM_F_REQUEST | NLM_F_ROOT | NLM_F_MATCH;
- uint32_t seq = 42;
- uint32_t pid = 7;
- auto message = LinkMessage::New(RtnetlinkMessage::Operation::NEW, flags, seq,
- pid, &interface_info_header);
-
- std::string device_name = "device0";
- message.AppendAttribute(IFLA_IFNAME, device_name.c_str(), device_name.size());
-
- // One rtattr appended.
- EXPECT_EQ(2, message.IoVecSize());
-
- // nlmsghdr is built properly.
- auto iov = message.BuildIoVec();
- EXPECT_EQ(NLMSG_ALIGN(NLMSG_LENGTH(sizeof(struct ifinfomsg))),
- iov[0].iov_len);
- auto* netlink_message = reinterpret_cast<struct nlmsghdr*>(iov[0].iov_base);
- EXPECT_EQ(NLMSG_ALIGN(NLMSG_LENGTH(sizeof(struct ifinfomsg))) +
- RTA_LENGTH(device_name.size()),
- netlink_message->nlmsg_len);
- EXPECT_EQ(RTM_NEWLINK, netlink_message->nlmsg_type);
- EXPECT_EQ(flags, netlink_message->nlmsg_flags);
- EXPECT_EQ(seq, netlink_message->nlmsg_seq);
- EXPECT_EQ(pid, netlink_message->nlmsg_pid);
-
- // ifinfomsg is included properly.
- auto* parsed_header =
- reinterpret_cast<struct ifinfomsg*>(NLMSG_DATA(netlink_message));
- EXPECT_EQ(interface_info_header.ifi_family, parsed_header->ifi_family);
- EXPECT_EQ(interface_info_header.ifi_type, parsed_header->ifi_type);
- EXPECT_EQ(interface_info_header.ifi_index, parsed_header->ifi_index);
- EXPECT_EQ(interface_info_header.ifi_flags, parsed_header->ifi_flags);
- EXPECT_EQ(interface_info_header.ifi_change, parsed_header->ifi_change);
-
- // rtattr is handled properly.
- EXPECT_EQ(RTA_SPACE(device_name.size()), iov[1].iov_len);
- auto* rta = reinterpret_cast<struct rtattr*>(iov[1].iov_base);
- EXPECT_EQ(IFLA_IFNAME, rta->rta_type);
- EXPECT_EQ(RTA_LENGTH(device_name.size()), rta->rta_len);
- EXPECT_THAT(device_name,
- StrEq(std::string(reinterpret_cast<char*>(RTA_DATA(rta)),
- RTA_PAYLOAD(rta))));
-}
-
-TEST(RtnetlinkMessageTest, AddressMessageCanBeCreatedForGetOperation) {
- uint16_t flags = NLM_F_REQUEST | NLM_F_ROOT | NLM_F_MATCH;
- uint32_t seq = 42;
- uint32_t pid = 7;
- auto message = AddressMessage::New(RtnetlinkMessage::Operation::GET, flags,
- seq, pid, nullptr);
-
- // No rtattr appended.
- EXPECT_EQ(1, message.IoVecSize());
-
- // nlmsghdr is built properly.
- auto iov = message.BuildIoVec();
- EXPECT_EQ(NLMSG_SPACE(sizeof(struct rtgenmsg)), iov[0].iov_len);
- auto* netlink_message = reinterpret_cast<struct nlmsghdr*>(iov[0].iov_base);
- EXPECT_EQ(NLMSG_LENGTH(sizeof(struct rtgenmsg)), netlink_message->nlmsg_len);
- EXPECT_EQ(RTM_GETADDR, netlink_message->nlmsg_type);
- EXPECT_EQ(flags, netlink_message->nlmsg_flags);
- EXPECT_EQ(seq, netlink_message->nlmsg_seq);
- EXPECT_EQ(pid, netlink_message->nlmsg_pid);
-
- // We actually included rtgenmsg instead of the passed in ifinfomsg since this
- // is a GET operation.
- EXPECT_EQ(NLMSG_LENGTH(sizeof(struct rtgenmsg)), netlink_message->nlmsg_len);
-}
-
-TEST(RtnetlinkMessageTest, AddressMessageCanBeCreatedForNewOperation) {
- struct ifaddrmsg interface_address_header = {AF_INET,
- /* prefixlen */ 24,
- /* flags */ 0,
- /* scope */ RT_SCOPE_LINK,
- /* index */ 4};
- uint16_t flags = NLM_F_REQUEST | NLM_F_ROOT | NLM_F_MATCH;
- uint32_t seq = 42;
- uint32_t pid = 7;
- auto message = AddressMessage::New(RtnetlinkMessage::Operation::NEW, flags,
- seq, pid, &interface_address_header);
-
- QuicIpAddress ip;
- QUICHE_CHECK(ip.FromString("10.0.100.3"));
- message.AppendAttribute(IFA_ADDRESS, ip.ToPackedString().c_str(),
- ip.ToPackedString().size());
-
- // One rtattr is appended.
- EXPECT_EQ(2, message.IoVecSize());
-
- // nlmsghdr is built properly.
- auto iov = message.BuildIoVec();
- EXPECT_EQ(NLMSG_ALIGN(NLMSG_LENGTH(sizeof(struct ifaddrmsg))),
- iov[0].iov_len);
- auto* netlink_message = reinterpret_cast<struct nlmsghdr*>(iov[0].iov_base);
- EXPECT_EQ(NLMSG_ALIGN(NLMSG_LENGTH(sizeof(struct ifaddrmsg))) +
- RTA_LENGTH(ip.ToPackedString().size()),
- netlink_message->nlmsg_len);
- EXPECT_EQ(RTM_NEWADDR, netlink_message->nlmsg_type);
- EXPECT_EQ(flags, netlink_message->nlmsg_flags);
- EXPECT_EQ(seq, netlink_message->nlmsg_seq);
- EXPECT_EQ(pid, netlink_message->nlmsg_pid);
-
- // ifaddrmsg is included properly.
- auto* parsed_header =
- reinterpret_cast<struct ifaddrmsg*>(NLMSG_DATA(netlink_message));
- EXPECT_EQ(interface_address_header.ifa_family, parsed_header->ifa_family);
- EXPECT_EQ(interface_address_header.ifa_prefixlen,
- parsed_header->ifa_prefixlen);
- EXPECT_EQ(interface_address_header.ifa_flags, parsed_header->ifa_flags);
- EXPECT_EQ(interface_address_header.ifa_scope, parsed_header->ifa_scope);
- EXPECT_EQ(interface_address_header.ifa_index, parsed_header->ifa_index);
-
- // rtattr is handled properly.
- EXPECT_EQ(RTA_SPACE(ip.ToPackedString().size()), iov[1].iov_len);
- auto* rta = reinterpret_cast<struct rtattr*>(iov[1].iov_base);
- EXPECT_EQ(IFA_ADDRESS, rta->rta_type);
- EXPECT_EQ(RTA_LENGTH(ip.ToPackedString().size()), rta->rta_len);
- EXPECT_THAT(ip.ToPackedString(),
- StrEq(std::string(reinterpret_cast<char*>(RTA_DATA(rta)),
- RTA_PAYLOAD(rta))));
-}
-
-TEST(RtnetlinkMessageTest, RouteMessageCanBeCreatedFromNewOperation) {
- struct rtmsg route_message_header = {AF_INET6,
- /* rtm_dst_len */ 48,
- /* rtm_src_len */ 0,
- /* rtm_tos */ 0,
- /* rtm_table */ RT_TABLE_MAIN,
- /* rtm_protocol */ RTPROT_STATIC,
- /* rtm_scope */ RT_SCOPE_LINK,
- /* rtm_type */ RTN_LOCAL,
- /* rtm_flags */ 0};
- uint16_t flags = NLM_F_REQUEST | NLM_F_ROOT | NLM_F_MATCH;
- uint32_t seq = 42;
- uint32_t pid = 7;
- auto message = RouteMessage::New(RtnetlinkMessage::Operation::NEW, flags, seq,
- pid, &route_message_header);
-
- QuicIpAddress preferred_source;
- QUICHE_CHECK(preferred_source.FromString("ff80::1"));
- message.AppendAttribute(RTA_PREFSRC,
- preferred_source.ToPackedString().c_str(),
- preferred_source.ToPackedString().size());
-
- // One rtattr is appended.
- EXPECT_EQ(2, message.IoVecSize());
-
- // nlmsghdr is built properly
- auto iov = message.BuildIoVec();
- EXPECT_EQ(NLMSG_ALIGN(NLMSG_LENGTH(sizeof(struct rtmsg))), iov[0].iov_len);
- auto* netlink_message = reinterpret_cast<struct nlmsghdr*>(iov[0].iov_base);
- EXPECT_EQ(NLMSG_ALIGN(NLMSG_LENGTH(sizeof(struct rtmsg))) +
- RTA_LENGTH(preferred_source.ToPackedString().size()),
- netlink_message->nlmsg_len);
- EXPECT_EQ(RTM_NEWROUTE, netlink_message->nlmsg_type);
- EXPECT_EQ(flags, netlink_message->nlmsg_flags);
- EXPECT_EQ(seq, netlink_message->nlmsg_seq);
- EXPECT_EQ(pid, netlink_message->nlmsg_pid);
-
- // rtmsg is included properly.
- auto* parsed_header =
- reinterpret_cast<struct rtmsg*>(NLMSG_DATA(netlink_message));
- EXPECT_EQ(route_message_header.rtm_family, parsed_header->rtm_family);
- EXPECT_EQ(route_message_header.rtm_dst_len, parsed_header->rtm_dst_len);
- EXPECT_EQ(route_message_header.rtm_src_len, parsed_header->rtm_src_len);
- EXPECT_EQ(route_message_header.rtm_tos, parsed_header->rtm_tos);
- EXPECT_EQ(route_message_header.rtm_table, parsed_header->rtm_table);
- EXPECT_EQ(route_message_header.rtm_protocol, parsed_header->rtm_protocol);
- EXPECT_EQ(route_message_header.rtm_scope, parsed_header->rtm_scope);
- EXPECT_EQ(route_message_header.rtm_type, parsed_header->rtm_type);
- EXPECT_EQ(route_message_header.rtm_flags, parsed_header->rtm_flags);
-
- // rtattr is handled properly.
- EXPECT_EQ(RTA_SPACE(preferred_source.ToPackedString().size()),
- iov[1].iov_len);
- auto* rta = reinterpret_cast<struct rtattr*>(iov[1].iov_base);
- EXPECT_EQ(RTA_PREFSRC, rta->rta_type);
- EXPECT_EQ(RTA_LENGTH(preferred_source.ToPackedString().size()), rta->rta_len);
- EXPECT_THAT(preferred_source.ToPackedString(),
- StrEq(std::string(reinterpret_cast<char*>(RTA_DATA(rta)),
- RTA_PAYLOAD(rta))));
-}
-
-} // namespace
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/qbone/platform/tcp_packet.cc b/chromium/net/third_party/quiche/src/quic/qbone/platform/tcp_packet.cc
deleted file mode 100644
index f4752f25973..00000000000
--- a/chromium/net/third_party/quiche/src/quic/qbone/platform/tcp_packet.cc
+++ /dev/null
@@ -1,126 +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 "quic/qbone/platform/tcp_packet.h"
-
-#include <netinet/ip6.h>
-
-#include "absl/strings/string_view.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/qbone/platform/internet_checksum.h"
-#include "common/quiche_endian.h"
-
-namespace quic {
-namespace {
-
-constexpr size_t kIPv6AddressSize = sizeof(in6_addr);
-constexpr size_t kTcpTtl = 64;
-
-struct TCPv6Packet {
- ip6_hdr ip_header;
- tcphdr tcp_header;
-};
-
-struct TCPv6PseudoHeader {
- uint32_t payload_size{};
- uint8_t zeros[3] = {0, 0, 0};
- uint8_t next_header = IPPROTO_TCP;
-};
-
-} // namespace
-
-void CreateTcpResetPacket(absl::string_view original_packet,
- const std::function<void(absl::string_view)>& cb) {
- // By the time this method is called, original_packet should be fairly
- // strongly validated. However, it's better to be more paranoid than not, so
- // here are a bunch of very obvious checks.
- if (QUIC_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)) {
- return;
- }
- if (QUIC_PREDICT_FALSE(ip6_header->ip6_nxt != IPPROTO_TCP)) {
- return;
- }
- if (QUIC_PREDICT_FALSE(quiche::QuicheEndian::NetToHost16(
- ip6_header->ip6_plen) < sizeof(tcphdr))) {
- return;
- }
- auto* tcp_header = reinterpret_cast<const tcphdr*>(ip6_header + 1);
-
- // Now that the original packet has been confirmed to be well-formed, it's
- // time to make the TCP RST packet.
- TCPv6Packet tcp_packet{};
-
- const size_t payload_size = sizeof(tcphdr);
-
- // Set version to 6.
- tcp_packet.ip_header.ip6_vfc = 0x6 << 4;
- // Set the payload size, protocol and TTL.
- tcp_packet.ip_header.ip6_plen =
- quiche::QuicheEndian::HostToNet16(payload_size);
- tcp_packet.ip_header.ip6_nxt = IPPROTO_TCP;
- tcp_packet.ip_header.ip6_hops = kTcpTtl;
- // Since the TCP RST is impersonating the endpoint, flip the source and
- // destination addresses from the original packet.
- tcp_packet.ip_header.ip6_src = ip6_header->ip6_dst;
- tcp_packet.ip_header.ip6_dst = ip6_header->ip6_src;
-
- // The same is true about the TCP ports
- tcp_packet.tcp_header.dest = tcp_header->source;
- tcp_packet.tcp_header.source = tcp_header->dest;
-
- // There are no extensions in this header, so size is trivial
- tcp_packet.tcp_header.doff = sizeof(tcphdr) >> 2;
- // Checksum is 0 before it is computed
- tcp_packet.tcp_header.check = 0;
-
- // Per RFC 793, TCP RST comes in one of 3 flavors:
- //
- // * connection CLOSED
- // * connection in non-synchronized state (LISTEN, SYN-SENT, SYN-RECEIVED)
- // * connection in synchronized state (ESTABLISHED, FIN-WAIT-1, etc.)
- //
- // QBONE is acting like a firewall, so the RFC text of interest is the CLOSED
- // state. Note, however, that it is possible for a connection to actually be
- // in the FIN-WAIT-1 state on the remote end, but the processing logic does
- // not change.
- tcp_packet.tcp_header.rst = 1;
-
- // If the incoming segment has an ACK field, the reset takes its sequence
- // number from the ACK field of the segment,
- if (tcp_header->ack) {
- tcp_packet.tcp_header.seq = tcp_header->ack_seq;
- } else {
- // Otherwise the reset has sequence number zero and the ACK field is set to
- // the sum of the sequence number and segment length of the incoming segment
- tcp_packet.tcp_header.ack = 1;
- tcp_packet.tcp_header.seq = 0;
- tcp_packet.tcp_header.ack_seq = quiche::QuicheEndian::HostToNet32(
- quiche::QuicheEndian::NetToHost32(tcp_header->seq) + 1);
- }
-
- TCPv6PseudoHeader pseudo_header{};
- pseudo_header.payload_size = quiche::QuicheEndian::HostToNet32(payload_size);
-
- InternetChecksum checksum;
- // Pseudoheader.
- checksum.Update(tcp_packet.ip_header.ip6_src.s6_addr, kIPv6AddressSize);
- checksum.Update(tcp_packet.ip_header.ip6_dst.s6_addr, kIPv6AddressSize);
- checksum.Update(reinterpret_cast<char*>(&pseudo_header),
- sizeof(pseudo_header));
- // TCP header.
- checksum.Update(reinterpret_cast<const char*>(&tcp_packet.tcp_header),
- sizeof(tcp_packet.tcp_header));
- // There is no body.
- tcp_packet.tcp_header.check = checksum.Value();
-
- const char* packet = reinterpret_cast<char*>(&tcp_packet);
-
- cb(absl::string_view(packet, sizeof(tcp_packet)));
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/qbone/platform/tcp_packet.h b/chromium/net/third_party/quiche/src/quic/qbone/platform/tcp_packet.h
deleted file mode 100644
index 5fd7a76436e..00000000000
--- a/chromium/net/third_party/quiche/src/quic/qbone/platform/tcp_packet.h
+++ /dev/null
@@ -1,25 +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_QBONE_PLATFORM_TCP_PACKET_H_
-#define QUICHE_QUIC_QBONE_PLATFORM_TCP_PACKET_H_
-
-#include <netinet/in.h>
-#include <netinet/tcp.h>
-
-#include <functional>
-
-#include "absl/strings/string_view.h"
-#include "quic/platform/api/quic_ip_address.h"
-
-namespace quic {
-
-// Creates an TCPv6 RST packet, returning a packed string representation of the
-// packet to |cb|.
-void CreateTcpResetPacket(absl::string_view original_packet,
- const std::function<void(absl::string_view)>& cb);
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_QBONE_PLATFORM_TCP_PACKET_H_
diff --git a/chromium/net/third_party/quiche/src/quic/qbone/platform/tcp_packet_test.cc b/chromium/net/third_party/quiche/src/quic/qbone/platform/tcp_packet_test.cc
deleted file mode 100644
index 9da9cb83603..00000000000
--- a/chromium/net/third_party/quiche/src/quic/qbone/platform/tcp_packet_test.cc
+++ /dev/null
@@ -1,117 +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 "quic/qbone/platform/tcp_packet.h"
-
-#include <netinet/ip6.h>
-
-#include <cstdint>
-
-#include "absl/strings/string_view.h"
-#include "quic/platform/api/quic_test.h"
-#include "common/quiche_text_utils.h"
-
-namespace quic {
-namespace {
-
-// clang-format off
-constexpr uint8_t kReferenceTCPSYNPacket[] = {
- // START IPv6 Header
- // IPv6 with zero ToS and flow label
- 0x60, 0x00, 0x00, 0x00,
- // Payload is 40 bytes
- 0x00, 0x28,
- // Next header is TCP (6)
- 0x06,
- // Hop limit is 64
- 0x40,
- // Source address of ::1
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
- // Destination address of ::1
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
- // END IPv6 Header
- // START TCPv6 Header
- // Source port
- 0xac, 0x1e,
- // Destination port
- 0x27, 0x0f,
- // Sequence number
- 0x4b, 0x01, 0xe8, 0x99,
- // Acknowledgement Sequence number,
- 0x00, 0x00, 0x00, 0x00,
- // Offset
- 0xa0,
- // Flags
- 0x02,
- // Window
- 0xaa, 0xaa,
- // Checksum
- 0x2e, 0x21,
- // Urgent
- 0x00, 0x00,
- // END TCPv6 Header
- // Options
- 0x02, 0x04, 0xff, 0xc4, 0x04, 0x02, 0x08, 0x0a,
- 0x1b, 0xb8, 0x52, 0xa1, 0x00, 0x00, 0x00, 0x00,
- 0x01, 0x03, 0x03, 0x07,
-};
-
-constexpr uint8_t kReferenceTCPRSTPacket[] = {
- // START IPv6 Header
- // IPv6 with zero ToS and flow label
- 0x60, 0x00, 0x00, 0x00,
- // Payload is 20 bytes
- 0x00, 0x14,
- // Next header is TCP (6)
- 0x06,
- // Hop limit is 64
- 0x40,
- // Source address of ::1
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
- // Destination address of ::1
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
- // END IPv6 Header
- // START TCPv6 Header
- // Source port
- 0x27, 0x0f,
- // Destination port
- 0xac, 0x1e,
- // Sequence number
- 0x00, 0x00, 0x00, 0x00,
- // Acknowledgement Sequence number,
- 0x4b, 0x01, 0xe8, 0x9a,
- // Offset
- 0x50,
- // Flags
- 0x14,
- // Window
- 0x00, 0x00,
- // Checksum
- 0xa9, 0x05,
- // Urgent
- 0x00, 0x00,
- // END TCPv6 Header
-};
-// clang-format on
-
-} // namespace
-
-TEST(TcpPacketTest, CreatedPacketMatchesReference) {
- absl::string_view syn =
- absl::string_view(reinterpret_cast<const char*>(kReferenceTCPSYNPacket),
- sizeof(kReferenceTCPSYNPacket));
- absl::string_view expected_packet =
- absl::string_view(reinterpret_cast<const char*>(kReferenceTCPRSTPacket),
- sizeof(kReferenceTCPRSTPacket));
- CreateTcpResetPacket(syn, [&expected_packet](absl::string_view packet) {
- QUIC_LOG(INFO) << quiche::QuicheTextUtils::HexDump(packet);
- ASSERT_EQ(packet, expected_packet);
- });
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/qbone/qbone_client.cc b/chromium/net/third_party/quiche/src/quic/qbone/qbone_client.cc
deleted file mode 100644
index d0daf95c419..00000000000
--- a/chromium/net/third_party/quiche/src/quic/qbone/qbone_client.cc
+++ /dev/null
@@ -1,110 +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 "quic/qbone/qbone_client.h"
-
-#include <utility>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_epoll_alarm_factory.h"
-#include "quic/core/quic_epoll_connection_helper.h"
-#include "quic/platform/api/quic_epoll.h"
-#include "quic/platform/api/quic_exported_stats.h"
-#include "quic/platform/api/quic_testvalue.h"
-#include "quic/qbone/qbone_stream.h"
-
-namespace quic {
-namespace {
-std::unique_ptr<QuicClientBase::NetworkHelper> CreateNetworkHelper(
- QuicEpollServer* epoll_server,
- QboneClient* client) {
- std::unique_ptr<QuicClientBase::NetworkHelper> helper =
- std::make_unique<QuicClientEpollNetworkHelper>(epoll_server, client);
- quic::AdjustTestValue("QboneClient/network_helper", &helper);
- return helper;
-}
-} // namespace
-
-QboneClient::QboneClient(QuicSocketAddress server_address,
- const QuicServerId& server_id,
- const ParsedQuicVersionVector& supported_versions,
- QuicSession::Visitor* session_owner,
- const QuicConfig& config,
- QuicEpollServer* epoll_server,
- std::unique_ptr<ProofVerifier> proof_verifier,
- QbonePacketWriter* qbone_writer,
- QboneClientControlStream::Handler* qbone_handler)
- : QuicClientBase(
- server_id,
- supported_versions,
- config,
- new QuicEpollConnectionHelper(epoll_server, QuicAllocator::SIMPLE),
- new QuicEpollAlarmFactory(epoll_server),
- CreateNetworkHelper(epoll_server, this),
- std::move(proof_verifier),
- nullptr),
- qbone_writer_(qbone_writer),
- qbone_handler_(qbone_handler),
- session_owner_(session_owner) {
- set_server_address(server_address);
- crypto_config()->set_alpn("qbone");
-}
-
-QboneClient::~QboneClient() {
- ResetSession();
-}
-
-QboneClientSession* QboneClient::qbone_session() {
- return static_cast<QboneClientSession*>(QuicClientBase::session());
-}
-
-void QboneClient::ProcessPacketFromNetwork(absl::string_view packet) {
- qbone_session()->ProcessPacketFromNetwork(packet);
-}
-
-bool QboneClient::EarlyDataAccepted() {
- return qbone_session()->EarlyDataAccepted();
-}
-
-bool QboneClient::ReceivedInchoateReject() {
- return qbone_session()->ReceivedInchoateReject();
-}
-
-int QboneClient::GetNumSentClientHellosFromSession() {
- return qbone_session()->GetNumSentClientHellos();
-}
-
-int QboneClient::GetNumReceivedServerConfigUpdatesFromSession() {
- return qbone_session()->GetNumReceivedServerConfigUpdates();
-}
-
-void QboneClient::ResendSavedData() {
- // no op.
-}
-
-void QboneClient::ClearDataToResend() {
- // no op.
-}
-
-bool QboneClient::HasActiveRequests() {
- return qbone_session()->HasActiveRequests();
-}
-
-class QboneClientSessionWithConnection : public QboneClientSession {
- public:
- using QboneClientSession::QboneClientSession;
-
- ~QboneClientSessionWithConnection() override { DeleteConnection(); }
-};
-
-// Takes ownership of |connection|.
-std::unique_ptr<QuicSession> QboneClient::CreateQuicClientSession(
- const ParsedQuicVersionVector& supported_versions,
- QuicConnection* connection) {
- return std::make_unique<QboneClientSessionWithConnection>(
- connection, crypto_config(), session_owner(), *config(),
- supported_versions, server_id(), qbone_writer_, qbone_handler_);
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/qbone/qbone_client.h b/chromium/net/third_party/quiche/src/quic/qbone/qbone_client.h
deleted file mode 100644
index 7aefb25bf63..00000000000
--- a/chromium/net/third_party/quiche/src/quic/qbone/qbone_client.h
+++ /dev/null
@@ -1,78 +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_QBONE_QBONE_CLIENT_H_
-#define QUICHE_QUIC_QBONE_QBONE_CLIENT_H_
-
-#include "absl/strings/string_view.h"
-#include "quic/qbone/qbone_client_interface.h"
-#include "quic/qbone/qbone_client_session.h"
-#include "quic/qbone/qbone_packet_writer.h"
-#include "quic/tools/quic_client_base.h"
-#include "quic/tools/quic_client_epoll_network_helper.h"
-
-namespace quic {
-// A QboneClient encapsulates connecting to a server via an epoll server
-// and setting up a QBONE tunnel. See the QboneTestClient in qbone_client_test
-// for usage.
-class QboneClient : public QuicClientBase, public QboneClientInterface {
- public:
- // Note that the epoll server, QBONE writer, and handler are owned
- // by the caller.
- QboneClient(QuicSocketAddress server_address,
- const QuicServerId& server_id,
- const ParsedQuicVersionVector& supported_versions,
- QuicSession::Visitor* session_owner,
- const QuicConfig& config,
- QuicEpollServer* epoll_server,
- std::unique_ptr<ProofVerifier> proof_verifier,
- QbonePacketWriter* qbone_writer,
- QboneClientControlStream::Handler* qbone_handler);
- ~QboneClient() override;
- QboneClientSession* qbone_session();
-
- // From QboneClientInterface. Accepts a given packet from the network and
- // sends the packet down to the QBONE connection.
- void ProcessPacketFromNetwork(absl::string_view packet) override;
-
- bool EarlyDataAccepted() override;
- bool ReceivedInchoateReject() override;
-
- protected:
- int GetNumSentClientHellosFromSession() override;
- int GetNumReceivedServerConfigUpdatesFromSession() override;
-
- // This client does not resend saved data. This will be a no-op.
- void ResendSavedData() override;
-
- // This client does not resend saved data. This will be a no-op.
- void ClearDataToResend() override;
-
- // Takes ownership of |connection|.
- std::unique_ptr<QuicSession> CreateQuicClientSession(
- const ParsedQuicVersionVector& supported_versions,
- QuicConnection* connection) override;
-
- QbonePacketWriter* qbone_writer() { return qbone_writer_; }
-
- QboneClientControlStream::Handler* qbone_control_handler() {
- return qbone_handler_;
- }
-
- QuicSession::Visitor* session_owner() {
- return session_owner_;
- }
-
- bool HasActiveRequests() override;
-
- private:
- QbonePacketWriter* qbone_writer_;
- QboneClientControlStream::Handler* qbone_handler_;
-
- QuicSession::Visitor* session_owner_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_QBONE_QBONE_CLIENT_H_
diff --git a/chromium/net/third_party/quiche/src/quic/qbone/qbone_client_interface.h b/chromium/net/third_party/quiche/src/quic/qbone/qbone_client_interface.h
deleted file mode 100644
index 8b31cceb65d..00000000000
--- a/chromium/net/third_party/quiche/src/quic/qbone/qbone_client_interface.h
+++ /dev/null
@@ -1,25 +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_QBONE_QBONE_CLIENT_INTERFACE_H_
-#define QUICHE_QUIC_QBONE_QBONE_CLIENT_INTERFACE_H_
-
-#include <cstdint>
-
-#include "absl/strings/string_view.h"
-
-namespace quic {
-
-// An interface that includes methods to interact with a QBONE client.
-class QboneClientInterface {
- public:
- virtual ~QboneClientInterface() {}
- // Accepts a given packet from the network and sends the packet down to the
- // QBONE connection.
- virtual void ProcessPacketFromNetwork(absl::string_view packet) = 0;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_QBONE_QBONE_CLIENT_INTERFACE_H_
diff --git a/chromium/net/third_party/quiche/src/quic/qbone/qbone_client_session.cc b/chromium/net/third_party/quiche/src/quic/qbone/qbone_client_session.cc
deleted file mode 100644
index 87cfb2d5266..00000000000
--- a/chromium/net/third_party/quiche/src/quic/qbone/qbone_client_session.cc
+++ /dev/null
@@ -1,124 +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 "quic/qbone/qbone_client_session.h"
-
-#include <utility>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_types.h"
-#include "quic/qbone/qbone_constants.h"
-#include "common/platform/api/quiche_command_line_flags.h"
-
-DEFINE_QUICHE_COMMAND_LINE_FLAG(
- bool, qbone_client_defer_control_stream_creation, true,
- "If true, control stream in QBONE client session is created after "
- "encryption established.");
-
-namespace quic {
-
-QboneClientSession::QboneClientSession(
- QuicConnection* connection,
- QuicCryptoClientConfig* quic_crypto_client_config,
- QuicSession::Visitor* owner,
- const QuicConfig& config,
- const ParsedQuicVersionVector& supported_versions,
- const QuicServerId& server_id,
- QbonePacketWriter* writer,
- QboneClientControlStream::Handler* handler)
- : QboneSessionBase(connection, owner, config, supported_versions, writer),
- server_id_(server_id),
- quic_crypto_client_config_(quic_crypto_client_config),
- handler_(handler) {}
-
-QboneClientSession::~QboneClientSession() {}
-
-std::unique_ptr<QuicCryptoStream> QboneClientSession::CreateCryptoStream() {
- return std::make_unique<QuicCryptoClientStream>(
- server_id_, this, nullptr, quic_crypto_client_config_, this,
- /*has_application_state = */ true);
-}
-
-void QboneClientSession::CreateControlStream() {
- if (control_stream_ != nullptr) {
- return;
- }
- // Register the reserved control stream.
- QuicStreamId next_id = GetNextOutgoingBidirectionalStreamId();
- QUICHE_DCHECK_EQ(next_id,
- QboneConstants::GetControlStreamId(transport_version()));
- auto control_stream =
- std::make_unique<QboneClientControlStream>(this, handler_);
- control_stream_ = control_stream.get();
- ActivateStream(std::move(control_stream));
-}
-
-void QboneClientSession::Initialize() {
- // Initialize must be called first, as that's what generates the crypto
- // stream.
- QboneSessionBase::Initialize();
- static_cast<QuicCryptoClientStreamBase*>(GetMutableCryptoStream())
- ->CryptoConnect();
- if (!GetQuicFlag(FLAGS_qbone_client_defer_control_stream_creation)) {
- CreateControlStream();
- }
-}
-
-void QboneClientSession::SetDefaultEncryptionLevel(
- quic::EncryptionLevel level) {
- QboneSessionBase::SetDefaultEncryptionLevel(level);
- if (GetQuicFlag(FLAGS_qbone_client_defer_control_stream_creation) &&
- level == quic::ENCRYPTION_FORWARD_SECURE) {
- CreateControlStream();
- }
-}
-
-int QboneClientSession::GetNumSentClientHellos() const {
- return static_cast<const QuicCryptoClientStreamBase*>(GetCryptoStream())
- ->num_sent_client_hellos();
-}
-
-bool QboneClientSession::EarlyDataAccepted() const {
- return static_cast<const QuicCryptoClientStreamBase*>(GetCryptoStream())
- ->EarlyDataAccepted();
-}
-
-bool QboneClientSession::ReceivedInchoateReject() const {
- return static_cast<const QuicCryptoClientStreamBase*>(GetCryptoStream())
- ->ReceivedInchoateReject();
-}
-
-int QboneClientSession::GetNumReceivedServerConfigUpdates() const {
- return static_cast<const QuicCryptoClientStreamBase*>(GetCryptoStream())
- ->num_scup_messages_received();
-}
-
-bool QboneClientSession::SendServerRequest(const QboneServerRequest& request) {
- if (!control_stream_) {
- QUIC_BUG(quic_bug_11056_1)
- << "Cannot send server request before control stream is created.";
- return false;
- }
- return control_stream_->SendRequest(request);
-}
-
-void QboneClientSession::ProcessPacketFromNetwork(absl::string_view packet) {
- SendPacketToPeer(packet);
-}
-
-void QboneClientSession::ProcessPacketFromPeer(absl::string_view packet) {
- writer_->WritePacketToNetwork(packet.data(), packet.size());
-}
-
-void QboneClientSession::OnProofValid(
- const QuicCryptoClientConfig::CachedState& cached) {}
-
-void QboneClientSession::OnProofVerifyDetailsAvailable(
- const ProofVerifyDetails& verify_details) {}
-
-bool QboneClientSession::HasActiveRequests() const {
- return GetNumActiveStreams() + num_draining_streams() > 0;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/qbone/qbone_client_session.h b/chromium/net/third_party/quiche/src/quic/qbone/qbone_client_session.h
deleted file mode 100644
index 8f1b3a96e7f..00000000000
--- a/chromium/net/third_party/quiche/src/quic/qbone/qbone_client_session.h
+++ /dev/null
@@ -1,95 +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_QBONE_QBONE_CLIENT_SESSION_H_
-#define QUICHE_QUIC_QBONE_QBONE_CLIENT_SESSION_H_
-
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_crypto_client_stream.h"
-#include "quic/platform/api/quic_export.h"
-#include "quic/qbone/qbone_control.pb.h"
-#include "quic/qbone/qbone_control_stream.h"
-#include "quic/qbone/qbone_packet_writer.h"
-#include "quic/qbone/qbone_session_base.h"
-
-namespace quic {
-
-class QUIC_EXPORT_PRIVATE QboneClientSession
- : public QboneSessionBase,
- public QuicCryptoClientStream::ProofHandler {
- public:
- QboneClientSession(QuicConnection* connection,
- QuicCryptoClientConfig* quic_crypto_client_config,
- QuicSession::Visitor* owner,
- const QuicConfig& config,
- const ParsedQuicVersionVector& supported_versions,
- const QuicServerId& server_id,
- QbonePacketWriter* writer,
- QboneClientControlStream::Handler* handler);
- QboneClientSession(const QboneClientSession&) = delete;
- QboneClientSession& operator=(const QboneClientSession&) = delete;
- ~QboneClientSession() override;
-
- // QuicSession overrides. This will initiate the crypto stream.
- void Initialize() override;
- // Override to create control stream at FORWARD_SECURE encryption level.
- void SetDefaultEncryptionLevel(quic::EncryptionLevel level) override;
-
- // Returns the number of client hello messages that have been sent on the
- // crypto stream. If the handshake has completed then this is one greater
- // than the number of round-trips needed for the handshake.
- int GetNumSentClientHellos() const;
-
- // Returns true if early data (0-RTT data) was sent and the server accepted
- // it.
- bool EarlyDataAccepted() const;
-
- // Returns true if the handshake was delayed one round trip by the server
- // because the server wanted proof the client controls its source address
- // before progressing further. In Google QUIC, this would be due to an
- // inchoate REJ in the QUIC Crypto handshake; in IETF QUIC this would be due
- // to a Retry packet.
- // TODO(nharper): Consider a better name for this method.
- bool ReceivedInchoateReject() const;
-
- int GetNumReceivedServerConfigUpdates() const;
-
- bool SendServerRequest(const QboneServerRequest& request);
-
- void ProcessPacketFromNetwork(absl::string_view packet) override;
- void ProcessPacketFromPeer(absl::string_view packet) override;
-
- // Returns true if there are active requests on this session.
- bool HasActiveRequests() const;
-
- protected:
- // QboneSessionBase interface implementation.
- std::unique_ptr<QuicCryptoStream> CreateCryptoStream() override;
-
- // Instantiate QboneClientControlStream.
- void CreateControlStream();
-
- // ProofHandler interface implementation.
- void OnProofValid(const QuicCryptoClientConfig::CachedState& cached) override;
- void OnProofVerifyDetailsAvailable(
- const ProofVerifyDetails& verify_details) override;
-
- QuicServerId server_id() { return server_id_; }
- QuicCryptoClientConfig* crypto_client_config() {
- return quic_crypto_client_config_;
- }
-
- private:
- QuicServerId server_id_;
- // Config for QUIC crypto client stream, used by the client.
- QuicCryptoClientConfig* quic_crypto_client_config_;
- // Passed to the control stream.
- QboneClientControlStream::Handler* handler_;
- // The unowned control stream.
- QboneClientControlStream* control_stream_ = nullptr;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_QBONE_QBONE_CLIENT_SESSION_H_
diff --git a/chromium/net/third_party/quiche/src/quic/qbone/qbone_client_test.cc b/chromium/net/third_party/quiche/src/quic/qbone/qbone_client_test.cc
deleted file mode 100644
index 371a8b62f2e..00000000000
--- a/chromium/net/third_party/quiche/src/quic/qbone/qbone_client_test.cc
+++ /dev/null
@@ -1,285 +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.
-
-// Sets up a dispatcher and sends requests via the QboneClient.
-
-#include "quic/qbone/qbone_client.h"
-
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_alarm_factory.h"
-#include "quic/core/quic_default_packet_writer.h"
-#include "quic/core/quic_dispatcher.h"
-#include "quic/core/quic_epoll_alarm_factory.h"
-#include "quic/core/quic_epoll_connection_helper.h"
-#include "quic/core/quic_packet_reader.h"
-#include "quic/platform/api/quic_mutex.h"
-#include "quic/platform/api/quic_port_utils.h"
-#include "quic/platform/api/quic_socket_address.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/platform/api/quic_test_loopback.h"
-#include "quic/qbone/qbone_constants.h"
-#include "quic/qbone/qbone_packet_processor_test_tools.h"
-#include "quic/qbone/qbone_server_session.h"
-#include "quic/test_tools/crypto_test_utils.h"
-#include "quic/test_tools/quic_connection_peer.h"
-#include "quic/test_tools/quic_dispatcher_peer.h"
-#include "quic/test_tools/quic_server_peer.h"
-#include "quic/test_tools/server_thread.h"
-#include "quic/tools/quic_memory_cache_backend.h"
-#include "quic/tools/quic_server.h"
-
-namespace quic {
-namespace test {
-namespace {
-
-ParsedQuicVersionVector GetTestParams() {
- ParsedQuicVersionVector test_versions;
-
- // TODO(b/113130636): Make QBONE work with TLS.
- for (const auto& version : CurrentSupportedVersionsWithQuicCrypto()) {
- // QBONE requires MESSAGE frames
- if (!version.SupportsMessageFrames()) {
- continue;
- }
- test_versions.push_back(version);
- }
-
- return test_versions;
-}
-
-std::string TestPacketIn(const std::string& body) {
- return PrependIPv6HeaderForTest(body, 5);
-}
-
-std::string TestPacketOut(const std::string& body) {
- return PrependIPv6HeaderForTest(body, 4);
-}
-
-class DataSavingQbonePacketWriter : public QbonePacketWriter {
- public:
- void WritePacketToNetwork(const char* packet, size_t size) override {
- QuicWriterMutexLock lock(&mu_);
- data_.push_back(std::string(packet, size));
- }
-
- std::vector<std::string> data() {
- QuicWriterMutexLock lock(&mu_);
- return data_;
- }
-
- private:
- QuicMutex mu_;
- std::vector<std::string> data_;
-};
-
-// A subclass of a QBONE session that will own the connection passed in.
-class ConnectionOwningQboneServerSession : public QboneServerSession {
- public:
- ConnectionOwningQboneServerSession(
- const ParsedQuicVersionVector& supported_versions,
- QuicConnection* connection,
- Visitor* owner,
- const QuicConfig& config,
- const QuicCryptoServerConfig* quic_crypto_server_config,
- QuicCompressedCertsCache* compressed_certs_cache,
- QbonePacketWriter* writer)
- : QboneServerSession(supported_versions,
- connection,
- owner,
- config,
- quic_crypto_server_config,
- compressed_certs_cache,
- writer,
- TestLoopback6(),
- TestLoopback6(),
- 64,
- nullptr),
- connection_(connection) {}
-
- private:
- // Note that we don't expect the QboneServerSession or any of its parent
- // classes to do anything with the connection_ in their destructors.
- std::unique_ptr<QuicConnection> connection_;
-};
-
-class QuicQboneDispatcher : public QuicDispatcher {
- public:
- QuicQboneDispatcher(
- 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,
- QbonePacketWriter* writer)
- : QuicDispatcher(config,
- crypto_config,
- version_manager,
- std::move(helper),
- std::move(session_helper),
- std::move(alarm_factory),
- kQuicDefaultConnectionIdLength),
- writer_(writer) {}
-
- std::unique_ptr<QuicSession> CreateQuicSession(
- QuicConnectionId id, const QuicSocketAddress& self_address,
- const QuicSocketAddress& peer_address, absl::string_view alpn,
- const ParsedQuicVersion& version,
- const ParsedClientHello& /*parsed_chlo*/) override {
- QUICHE_CHECK_EQ(alpn, "qbone");
- QuicConnection* connection = new QuicConnection(
- id, self_address, peer_address, helper(), alarm_factory(), writer(),
- /* owns_writer= */ false, Perspective::IS_SERVER,
- ParsedQuicVersionVector{version});
- // The connection owning wrapper owns the connection created.
- auto session = std::make_unique<ConnectionOwningQboneServerSession>(
- GetSupportedVersions(), connection, this, config(), crypto_config(),
- compressed_certs_cache(), writer_);
- session->Initialize();
- return session;
- }
-
- private:
- QbonePacketWriter* writer_;
-};
-
-class QboneTestServer : public QuicServer {
- public:
- explicit QboneTestServer(std::unique_ptr<ProofSource> proof_source)
- : QuicServer(std::move(proof_source), &response_cache_) {}
- QuicDispatcher* CreateQuicDispatcher() override {
- QuicEpollAlarmFactory alarm_factory(epoll_server());
- return new QuicQboneDispatcher(
- &config(), &crypto_config(), version_manager(),
- std::unique_ptr<QuicEpollConnectionHelper>(
- new QuicEpollConnectionHelper(epoll_server(),
- QuicAllocator::BUFFER_POOL)),
- std::unique_ptr<QuicCryptoServerStreamBase::Helper>(
- new QboneCryptoServerStreamHelper()),
- std::unique_ptr<QuicEpollAlarmFactory>(
- new QuicEpollAlarmFactory(epoll_server())),
- &writer_);
- }
-
- std::vector<std::string> data() { return writer_.data(); }
-
- private:
- quic::QuicMemoryCacheBackend response_cache_;
- DataSavingQbonePacketWriter writer_;
-};
-
-class QboneTestClient : public QboneClient {
- public:
- QboneTestClient(QuicSocketAddress server_address,
- const QuicServerId& server_id,
- const ParsedQuicVersionVector& supported_versions,
- QuicEpollServer* epoll_server,
- std::unique_ptr<ProofVerifier> proof_verifier)
- : QboneClient(server_address,
- server_id,
- supported_versions,
- /*session_owner=*/nullptr,
- QuicConfig(),
- epoll_server,
- std::move(proof_verifier),
- &qbone_writer_,
- nullptr) {}
-
- ~QboneTestClient() override {}
-
- void SendData(const std::string& data) {
- qbone_session()->ProcessPacketFromNetwork(data);
- }
-
- void WaitForWriteToFlush() {
- while (connected() && session()->HasDataToWrite()) {
- WaitForEvents();
- }
- }
-
- // Returns true when the data size is reached or false on timeouts.
- bool WaitForDataSize(int n, QuicTime::Delta timeout) {
- const QuicClock* clock =
- quic::test::QuicConnectionPeer::GetHelper(session()->connection())
- ->GetClock();
- const QuicTime deadline = clock->Now() + timeout;
- while (data().size() < n) {
- if (clock->Now() > deadline) {
- return false;
- }
- WaitForEvents();
- }
- return true;
- }
-
- std::vector<std::string> data() { return qbone_writer_.data(); }
-
- private:
- DataSavingQbonePacketWriter qbone_writer_;
-};
-
-class QboneClientTest : public QuicTestWithParam<ParsedQuicVersion> {};
-
-INSTANTIATE_TEST_SUITE_P(Tests,
- QboneClientTest,
- ::testing::ValuesIn(GetTestParams()),
- ::testing::PrintToStringParamName());
-
-TEST_P(QboneClientTest, SendDataFromClient) {
- auto server = new QboneTestServer(crypto_test_utils::ProofSourceForTesting());
- QuicSocketAddress server_address(TestLoopback(),
- QuicPickServerPortForTestsOrDie());
- ServerThread server_thread(server, server_address);
- server_thread.Initialize();
- server_address =
- QuicSocketAddress(server_address.host(), server_thread.GetPort());
- server_thread.Start();
-
- QuicEpollServer epoll_server;
- QboneTestClient client(
- server_address,
- QuicServerId("test.example.com", server_address.port(), false),
- ParsedQuicVersionVector{GetParam()}, &epoll_server,
- crypto_test_utils::ProofVerifierForTesting());
- ASSERT_TRUE(client.Initialize());
- ASSERT_TRUE(client.Connect());
- ASSERT_TRUE(client.WaitForOneRttKeysAvailable());
- client.SendData(TestPacketIn("hello"));
- client.SendData(TestPacketIn("world"));
- client.WaitForWriteToFlush();
-
- // Wait until the server has received at least two packets, timeout after 5s.
- ASSERT_TRUE(
- server_thread.WaitUntil([&] { return server->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")));
- auto server_session = static_cast<QboneServerSession*>(
- QuicDispatcherPeer::GetFirstSessionIfAny(
- QuicServerPeer::GetDispatcher(server)));
- 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)));
-
- client.Disconnect();
- server_thread.Quit();
- server_thread.Join();
-}
-
-} // namespace
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/qbone/qbone_constants.cc b/chromium/net/third_party/quiche/src/quic/qbone/qbone_constants.cc
deleted file mode 100644
index f54ebc3edef..00000000000
--- a/chromium/net/third_party/quiche/src/quic/qbone/qbone_constants.cc
+++ /dev/null
@@ -1,45 +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 "quic/qbone/qbone_constants.h"
-
-#include "quic/core/quic_utils.h"
-
-namespace quic {
-
-constexpr char QboneConstants::kQboneAlpn[];
-const QuicByteCount QboneConstants::kMaxQbonePacketBytes;
-const uint32_t QboneConstants::kQboneRouteTableId;
-
-QuicStreamId QboneConstants::GetControlStreamId(QuicTransportVersion version) {
- return QuicUtils::GetFirstBidirectionalStreamId(version,
- Perspective::IS_CLIENT);
-}
-
-const QuicIpAddress* QboneConstants::TerminatorLocalAddress() {
- static auto* terminator_address = []() {
- auto* address = new QuicIpAddress;
- // 0x71 0x62 0x6f 0x6e 0x65 is 'qbone' in ascii.
- address->FromString("fe80::71:626f:6e65");
- return address;
- }();
- return terminator_address;
-}
-
-const IpRange* QboneConstants::TerminatorLocalAddressRange() {
- static auto* range =
- new quic::IpRange(*quic::QboneConstants::TerminatorLocalAddress(), 128);
- return range;
-}
-
-const QuicIpAddress* QboneConstants::GatewayAddress() {
- static auto* gateway_address = []() {
- auto* address = new QuicIpAddress;
- address->FromString("fe80::1");
- return address;
- }();
- return gateway_address;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/qbone/qbone_constants.h b/chromium/net/third_party/quiche/src/quic/qbone/qbone_constants.h
deleted file mode 100644
index 141bb6c00d2..00000000000
--- a/chromium/net/third_party/quiche/src/quic/qbone/qbone_constants.h
+++ /dev/null
@@ -1,35 +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_QBONE_QBONE_CONSTANTS_H_
-#define QUICHE_QUIC_QBONE_QBONE_CONSTANTS_H_
-
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_versions.h"
-#include "quic/platform/api/quic_ip_address.h"
-#include "quic/qbone/platform/ip_range.h"
-
-namespace quic {
-
-struct QboneConstants {
- // QBONE's ALPN
- static constexpr char kQboneAlpn[] = "qbone";
- // The maximum number of bytes allowed in a QBONE packet.
- static const QuicByteCount kMaxQbonePacketBytes = 2000;
- // The table id for QBONE's routing table. 'bone' in ascii.
- static const uint32_t kQboneRouteTableId = 0x626F6E65;
- // The stream ID of the control channel.
- static QuicStreamId GetControlStreamId(QuicTransportVersion version);
- // The link-local address of the Terminator
- static const QuicIpAddress* TerminatorLocalAddress();
- // The IPRange containing the TerminatorLocalAddress
- static const IpRange* TerminatorLocalAddressRange();
- // The gateway address to provide when configuring routes to the QBONE
- // interface
- static const QuicIpAddress* GatewayAddress();
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_QBONE_QBONE_CONSTANTS_H_
diff --git a/chromium/net/third_party/quiche/src/quic/qbone/qbone_control.proto b/chromium/net/third_party/quiche/src/quic/qbone/qbone_control.proto
deleted file mode 100644
index f0090d6cf8a..00000000000
--- a/chromium/net/third_party/quiche/src/quic/qbone/qbone_control.proto
+++ /dev/null
@@ -1,13 +0,0 @@
-syntax = "proto2";
-
-option optimize_for = LITE_RUNTIME;
-
-package quic;
-
-message QboneServerRequest {
- extensions 1000 to max;
-};
-
-message QboneClientRequest {
- extensions 1000 to max;
-};
diff --git a/chromium/net/third_party/quiche/src/quic/qbone/qbone_control_placeholder.proto b/chromium/net/third_party/quiche/src/quic/qbone/qbone_control_placeholder.proto
deleted file mode 100644
index d9b1a6ae035..00000000000
--- a/chromium/net/third_party/quiche/src/quic/qbone/qbone_control_placeholder.proto
+++ /dev/null
@@ -1,20 +0,0 @@
-syntax = "proto2";
-
-option optimize_for = LITE_RUNTIME;
-
-package quic;
-
-import "quic/qbone/qbone_control.proto";
-
-// These provide fields for QboneServerRequest and QboneClientRequest that are
-// used to test the control channel. Once the control channel actually has real
-// data to pass they can be removed.
-// TODO(b/62139999): Remove this file in favor of testing actual configuration.
-
-extend QboneServerRequest {
- optional string server_placeholder = 179838467;
-}
-
-extend QboneClientRequest {
- optional string client_placeholder = 179838467;
-}
diff --git a/chromium/net/third_party/quiche/src/quic/qbone/qbone_control_stream.cc b/chromium/net/third_party/quiche/src/quic/qbone/qbone_control_stream.cc
deleted file mode 100644
index 61a9afe4de9..00000000000
--- a/chromium/net/third_party/quiche/src/quic/qbone/qbone_control_stream.cc
+++ /dev/null
@@ -1,86 +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 "quic/qbone/qbone_control_stream.h"
-
-#include <cstdint>
-#include <limits>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_session.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/qbone/qbone_constants.h"
-
-namespace quic {
-
-namespace {
-static constexpr size_t kRequestSizeBytes = sizeof(uint16_t);
-} // namespace
-
-QboneControlStreamBase::QboneControlStreamBase(QuicSession* session)
- : QuicStream(
- QboneConstants::GetControlStreamId(session->transport_version()),
- session,
- /*is_static=*/true,
- BIDIRECTIONAL),
- pending_message_size_(0) {}
-
-QboneControlStreamBase::QboneControlStreamBase(quic::PendingStream* pending,
- QuicSession* session)
- : QuicStream(pending, session, /*is_static=*/true),
- pending_message_size_(0) {
- QUICHE_DCHECK_EQ(pending->id(), QboneConstants::GetControlStreamId(
- session->transport_version()));
-}
-
-void QboneControlStreamBase::OnDataAvailable() {
- sequencer()->Read(&buffer_);
- while (true) {
- if (pending_message_size_ == 0) {
- // Start of a message.
- if (buffer_.size() < kRequestSizeBytes) {
- return;
- }
- memcpy(&pending_message_size_, buffer_.data(), kRequestSizeBytes);
- buffer_.erase(0, kRequestSizeBytes);
- }
- // Continuation of a message.
- if (buffer_.size() < pending_message_size_) {
- return;
- }
- std::string tmp = buffer_.substr(0, pending_message_size_);
- buffer_.erase(0, pending_message_size_);
- pending_message_size_ = 0;
- OnMessage(tmp);
- }
-}
-
-bool QboneControlStreamBase::SendMessage(const proto2::Message& proto) {
- std::string tmp;
- if (!proto.SerializeToString(&tmp)) {
- QUIC_BUG(quic_bug_11023_1) << "Failed to serialize QboneControlRequest";
- return false;
- }
- if (tmp.size() > std::numeric_limits<uint16_t>::max()) {
- QUIC_BUG(quic_bug_11023_2)
- << "QboneControlRequest too large: " << tmp.size() << " > "
- << std::numeric_limits<uint16_t>::max();
- return false;
- }
- uint16_t size = tmp.size();
- char size_str[kRequestSizeBytes];
- memcpy(size_str, &size, kRequestSizeBytes);
- WriteOrBufferData(absl::string_view(size_str, kRequestSizeBytes), false,
- nullptr);
- WriteOrBufferData(tmp, false, nullptr);
- return true;
-}
-
-void QboneControlStreamBase::OnStreamReset(
- const QuicRstStreamFrame& /*frame*/) {
- stream_delegate()->OnStreamError(QUIC_INVALID_STREAM_ID,
- "Attempt to reset control stream");
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/qbone/qbone_control_stream.h b/chromium/net/third_party/quiche/src/quic/qbone/qbone_control_stream.h
deleted file mode 100644
index c38697dd2c6..00000000000
--- a/chromium/net/third_party/quiche/src/quic/qbone/qbone_control_stream.h
+++ /dev/null
@@ -1,82 +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_QBONE_QBONE_CONTROL_STREAM_H_
-#define QUICHE_QUIC_QBONE_QBONE_CONTROL_STREAM_H_
-
-#include "quic/core/quic_stream.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/qbone/qbone_control.pb.h"
-
-namespace quic {
-
-class QboneSessionBase;
-
-class QUIC_EXPORT_PRIVATE QboneControlStreamBase : public QuicStream {
- public:
- explicit QboneControlStreamBase(QuicSession* session);
- QboneControlStreamBase(quic::PendingStream* pending, QuicSession* session);
-
- void OnDataAvailable() override;
-
- void OnStreamReset(const QuicRstStreamFrame& frame) override;
-
- protected:
- virtual void OnMessage(const std::string& data) = 0;
- bool SendMessage(const proto2::Message& proto);
-
- private:
- uint16_t pending_message_size_;
- std::string buffer_;
-};
-
-template <class T>
-class QUIC_EXPORT_PRIVATE QboneControlHandler {
- public:
- virtual ~QboneControlHandler() { }
-
- virtual void OnControlRequest(const T& request) = 0;
- virtual void OnControlError() = 0;
-};
-
-template <class Incoming, class Outgoing>
-class QUIC_EXPORT_PRIVATE QboneControlStream : public QboneControlStreamBase {
- public:
- using Handler = QboneControlHandler<Incoming>;
-
- QboneControlStream(QuicSession* session, Handler* handler)
- : QboneControlStreamBase(session), handler_(handler) {}
- QboneControlStream(quic::PendingStream* pending, QuicSession* session,
- Handler* handler)
- : QboneControlStreamBase(pending, session), handler_(handler) {}
-
- bool SendRequest(const Outgoing& request) { return SendMessage(request); }
-
- protected:
- void OnMessage(const std::string& data) override {
- Incoming request;
- if (!request.ParseFromString(data)) {
- QUIC_LOG(ERROR) << "Failed to parse incoming request";
- if (handler_ != nullptr) {
- handler_->OnControlError();
- }
- return;
- }
- if (handler_ != nullptr) {
- handler_->OnControlRequest(request);
- }
- }
-
- private:
- Handler* handler_;
-};
-
-using QboneServerControlStream =
- QboneControlStream<QboneServerRequest, QboneClientRequest>;
-using QboneClientControlStream =
- QboneControlStream<QboneClientRequest, QboneServerRequest>;
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_QBONE_QBONE_CONTROL_STREAM_H_
diff --git a/chromium/net/third_party/quiche/src/quic/qbone/qbone_packet_exchanger.cc b/chromium/net/third_party/quiche/src/quic/qbone/qbone_packet_exchanger.cc
deleted file mode 100644
index f8acb4f6a86..00000000000
--- a/chromium/net/third_party/quiche/src/quic/qbone/qbone_packet_exchanger.cc
+++ /dev/null
@@ -1,73 +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 "quic/qbone/qbone_packet_exchanger.h"
-
-#include <utility>
-
-namespace quic {
-
-bool QbonePacketExchanger::ReadAndDeliverPacket(
- QboneClientInterface* qbone_client) {
- bool blocked = false;
- std::string error;
- std::unique_ptr<QuicData> packet = ReadPacket(&blocked, &error);
- if (packet == nullptr) {
- if (!blocked && visitor_) {
- visitor_->OnReadError(error);
- }
- return false;
- }
- qbone_client->ProcessPacketFromNetwork(packet->AsStringPiece());
- return true;
-}
-
-void QbonePacketExchanger::WritePacketToNetwork(const char* packet,
- size_t size) {
- bool blocked = false;
- std::string error;
- if (packet_queue_.empty() && !write_blocked_) {
- if (WritePacket(packet, size, &blocked, &error)) {
- return;
- }
- if (blocked) {
- write_blocked_ = true;
- } else {
- QUIC_LOG_EVERY_N_SEC(ERROR, 60) << "Packet write failed: " << error;
- if (visitor_) {
- visitor_->OnWriteError(error);
- }
- }
- }
-
- // Drop the packet on the floor if the queue if full.
- if (packet_queue_.size() >= max_pending_packets_) {
- return;
- }
-
- auto data_copy = new char[size];
- memcpy(data_copy, packet, size);
- packet_queue_.push_back(
- std::make_unique<QuicData>(data_copy, size, /* owns_buffer = */ true));
-}
-
-void QbonePacketExchanger::SetWritable() {
- write_blocked_ = false;
- while (!packet_queue_.empty()) {
- bool blocked = false;
- std::string error;
- if (WritePacket(packet_queue_.front()->data(),
- packet_queue_.front()->length(), &blocked, &error)) {
- packet_queue_.pop_front();
- } else {
- if (!blocked && visitor_) {
- visitor_->OnWriteError(error);
- }
- write_blocked_ = blocked;
- return;
- }
- }
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/qbone/qbone_packet_exchanger.h b/chromium/net/third_party/quiche/src/quic/qbone/qbone_packet_exchanger.h
deleted file mode 100644
index ad393b866b8..00000000000
--- a/chromium/net/third_party/quiche/src/quic/qbone/qbone_packet_exchanger.h
+++ /dev/null
@@ -1,80 +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_QBONE_QBONE_PACKET_EXCHANGER_H_
-#define QUICHE_QUIC_QBONE_QBONE_PACKET_EXCHANGER_H_
-
-#include "quic/core/quic_packets.h"
-#include "quic/qbone/qbone_client_interface.h"
-#include "quic/qbone/qbone_packet_writer.h"
-
-namespace quic {
-
-// Handles reading and writing on the local network and exchange packets between
-// the local network with a QBONE connection.
-class QbonePacketExchanger : public QbonePacketWriter {
- public:
- // The owner might want to receive notifications when read or write fails.
- class Visitor {
- public:
- virtual ~Visitor() {}
- virtual void OnReadError(const std::string& error) {}
- virtual void OnWriteError(const std::string& error) {}
- };
- // Does not take ownership of visitor.
- QbonePacketExchanger(Visitor* visitor, size_t max_pending_packets)
- : visitor_(visitor), max_pending_packets_(max_pending_packets) {}
-
- QbonePacketExchanger(const QbonePacketExchanger&) = delete;
- QbonePacketExchanger& operator=(const QbonePacketExchanger&) = delete;
-
- QbonePacketExchanger(QbonePacketExchanger&&) = delete;
- QbonePacketExchanger& operator=(QbonePacketExchanger&&) = delete;
-
- ~QbonePacketExchanger() = default;
-
- // Returns true if there may be more packets to read.
- // Implementations handles the actual raw read and delivers the packet to
- // qbone_client.
- bool ReadAndDeliverPacket(QboneClientInterface* qbone_client);
-
- // From QbonePacketWriter.
- // Writes a packet to the local network. If the write would be blocked, the
- // packet will be queued if the queue is smaller than max_pending_packets_.
- void WritePacketToNetwork(const char* packet, size_t size) override;
-
- // The caller signifies that the local network is no longer blocked.
- void SetWritable();
-
- private:
- // The actual implementation that reads a packet from the local network.
- // Returns the packet if one is successfully read. This might nullptr when a)
- // there is no packet to read, b) the read failed. In the former case, blocked
- // is set to true. error contains the error message.
- virtual std::unique_ptr<QuicData> ReadPacket(bool* blocked,
- std::string* error) = 0;
-
- // The actual implementation that writes a packet to the local network.
- // Returns true if the write succeeds. blocked will be set to true if the
- // write failure is caused by the local network being blocked. error contains
- // the error message.
- virtual bool WritePacket(const char* packet,
- size_t size,
- bool* blocked,
- std::string* error) = 0;
-
- std::list<std::unique_ptr<QuicData>> packet_queue_;
-
- Visitor* visitor_;
-
- // The maximum number of packets that could be queued up when writing to local
- // network is blocked.
- size_t max_pending_packets_;
-
- bool write_blocked_ = false;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_QBONE_QBONE_PACKET_EXCHANGER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/qbone/qbone_packet_exchanger_test.cc b/chromium/net/third_party/quiche/src/quic/qbone/qbone_packet_exchanger_test.cc
deleted file mode 100644
index 5db87536aba..00000000000
--- a/chromium/net/third_party/quiche/src/quic/qbone/qbone_packet_exchanger_test.cc
+++ /dev/null
@@ -1,271 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/qbone/qbone_packet_exchanger.h"
-
-#include <utility>
-
-#include "quic/platform/api/quic_test.h"
-#include "quic/qbone/mock_qbone_client.h"
-
-namespace quic {
-namespace {
-
-using ::testing::StrEq;
-using ::testing::StrictMock;
-
-const size_t kMaxPendingPackets = 2;
-
-class MockVisitor : public QbonePacketExchanger::Visitor {
- public:
- MOCK_METHOD(void, OnReadError, (const std::string&), (override));
- MOCK_METHOD(void, OnWriteError, (const std::string&), (override));
-};
-
-class FakeQbonePacketExchanger : public QbonePacketExchanger {
- public:
- using QbonePacketExchanger::QbonePacketExchanger;
-
- // Adds a packet to the end of list of packets to be returned by ReadPacket.
- // When the list is empty, ReadPacket returns nullptr to signify error as
- // defined by QbonePacketExchanger. If SetReadError is not called or called
- // with empty error string, ReadPacket sets blocked to true.
- void AddPacketToBeRead(std::unique_ptr<QuicData> packet) {
- packets_to_be_read_.push_back(std::move(packet));
- }
-
- // Sets the error to be returned by ReadPacket when the list of packets is
- // empty. If error is empty string, blocked is set by ReadPacket.
- void SetReadError(const std::string& error) { read_error_ = error; }
-
- // Force WritePacket to fail with the given status. WritePacket returns true
- // when blocked == true and error is empty.
- void ForceWriteFailure(bool blocked, const std::string& error) {
- write_blocked_ = blocked;
- write_error_ = error;
- }
-
- // Packets that have been successfully written by WritePacket.
- const std::vector<std::string>& packets_written() const {
- return packets_written_;
- }
-
- private:
- // Implements QbonePacketExchanger::ReadPacket.
- std::unique_ptr<QuicData> ReadPacket(bool* blocked,
- std::string* error) override {
- *blocked = false;
-
- if (packets_to_be_read_.empty()) {
- *blocked = read_error_.empty();
- *error = read_error_;
- return nullptr;
- }
-
- std::unique_ptr<QuicData> packet = std::move(packets_to_be_read_.front());
- packets_to_be_read_.pop_front();
- return packet;
- }
-
- // Implements QbonePacketExchanger::WritePacket.
- bool WritePacket(const char* packet,
- size_t size,
- bool* blocked,
- std::string* error) override {
- *blocked = false;
-
- if (write_blocked_ || !write_error_.empty()) {
- *blocked = write_blocked_;
- *error = write_error_;
- return false;
- }
-
- packets_written_.push_back(std::string(packet, size));
- return true;
- }
-
- std::string read_error_;
- std::list<std::unique_ptr<QuicData>> packets_to_be_read_;
-
- std::string write_error_;
- bool write_blocked_ = false;
- std::vector<std::string> packets_written_;
-};
-
-TEST(QbonePacketExchangerTest,
- ReadAndDeliverPacketDeliversPacketToQboneClient) {
- StrictMock<MockVisitor> visitor;
- FakeQbonePacketExchanger exchanger(&visitor, kMaxPendingPackets);
- StrictMock<MockQboneClient> client;
-
- std::string packet = "data";
- exchanger.AddPacketToBeRead(
- std::make_unique<QuicData>(packet.data(), packet.length()));
- EXPECT_CALL(client, ProcessPacketFromNetwork(StrEq("data")));
-
- EXPECT_TRUE(exchanger.ReadAndDeliverPacket(&client));
-}
-
-TEST(QbonePacketExchangerTest,
- ReadAndDeliverPacketNotifiesVisitorOnReadFailure) {
- MockVisitor visitor;
- FakeQbonePacketExchanger exchanger(&visitor, kMaxPendingPackets);
- MockQboneClient client;
-
- // Force read error.
- std::string io_error = "I/O error";
- exchanger.SetReadError(io_error);
- EXPECT_CALL(visitor, OnReadError(StrEq(io_error))).Times(1);
-
- EXPECT_FALSE(exchanger.ReadAndDeliverPacket(&client));
-}
-
-TEST(QbonePacketExchangerTest,
- ReadAndDeliverPacketDoesNotNotifyVisitorOnBlockedIO) {
- MockVisitor visitor;
- FakeQbonePacketExchanger exchanger(&visitor, kMaxPendingPackets);
- MockQboneClient client;
-
- // No more packets to read.
- EXPECT_FALSE(exchanger.ReadAndDeliverPacket(&client));
-}
-
-TEST(QbonePacketExchangerTest,
- WritePacketToNetworkWritesDirectlyToNetworkWhenNotBlocked) {
- MockVisitor visitor;
- FakeQbonePacketExchanger exchanger(&visitor, kMaxPendingPackets);
- MockQboneClient client;
-
- std::string packet = "data";
- exchanger.WritePacketToNetwork(packet.data(), packet.length());
-
- ASSERT_EQ(exchanger.packets_written().size(), 1);
- EXPECT_THAT(exchanger.packets_written()[0], StrEq(packet));
-}
-
-TEST(QbonePacketExchangerTest,
- WritePacketToNetworkQueuesPacketsAndProcessThemLater) {
- MockVisitor visitor;
- FakeQbonePacketExchanger exchanger(&visitor, kMaxPendingPackets);
- MockQboneClient client;
-
- // Force write to be blocked so that packets are queued.
- exchanger.ForceWriteFailure(true, "");
- std::vector<std::string> packets = {"packet0", "packet1"};
- for (int i = 0; i < packets.size(); i++) {
- exchanger.WritePacketToNetwork(packets[i].data(), packets[i].length());
- }
-
- // Nothing should have been written because of blockage.
- ASSERT_TRUE(exchanger.packets_written().empty());
-
- // Remove blockage and start proccessing queued packets.
- exchanger.ForceWriteFailure(false, "");
- exchanger.SetWritable();
-
- // Queued packets are processed.
- ASSERT_EQ(exchanger.packets_written().size(), 2);
- for (int i = 0; i < packets.size(); i++) {
- EXPECT_THAT(exchanger.packets_written()[i], StrEq(packets[i]));
- }
-}
-
-TEST(QbonePacketExchangerTest,
- SetWritableContinuesProcessingPacketIfPreviousCallBlocked) {
- MockVisitor visitor;
- FakeQbonePacketExchanger exchanger(&visitor, kMaxPendingPackets);
- MockQboneClient client;
-
- // Force write to be blocked so that packets are queued.
- exchanger.ForceWriteFailure(true, "");
- std::vector<std::string> packets = {"packet0", "packet1"};
- for (int i = 0; i < packets.size(); i++) {
- exchanger.WritePacketToNetwork(packets[i].data(), packets[i].length());
- }
-
- // Nothing should have been written because of blockage.
- ASSERT_TRUE(exchanger.packets_written().empty());
-
- // Start processing packets, but since writes are still blocked, nothing
- // should have been written.
- exchanger.SetWritable();
- ASSERT_TRUE(exchanger.packets_written().empty());
-
- // Remove blockage and start processing packets again.
- exchanger.ForceWriteFailure(false, "");
- exchanger.SetWritable();
-
- ASSERT_EQ(exchanger.packets_written().size(), 2);
- for (int i = 0; i < packets.size(); i++) {
- EXPECT_THAT(exchanger.packets_written()[i], StrEq(packets[i]));
- }
-}
-
-TEST(QbonePacketExchangerTest, WritePacketToNetworkDropsPacketIfQueueIfFull) {
- std::vector<std::string> packets = {"packet0", "packet1", "packet2"};
- size_t queue_size = packets.size() - 1;
- MockVisitor visitor;
- // exchanger has smaller queue than number of packets.
- FakeQbonePacketExchanger exchanger(&visitor, queue_size);
- MockQboneClient client;
-
- exchanger.ForceWriteFailure(true, "");
- for (int i = 0; i < packets.size(); i++) {
- exchanger.WritePacketToNetwork(packets[i].data(), packets[i].length());
- }
-
- // Blocked writes cause packets to be queued or dropped.
- ASSERT_TRUE(exchanger.packets_written().empty());
-
- exchanger.ForceWriteFailure(false, "");
- exchanger.SetWritable();
-
- ASSERT_EQ(exchanger.packets_written().size(), queue_size);
- for (int i = 0; i < queue_size; i++) {
- EXPECT_THAT(exchanger.packets_written()[i], StrEq(packets[i]));
- }
-}
-
-TEST(QbonePacketExchangerTest, WriteErrorsGetNotified) {
- MockVisitor visitor;
- FakeQbonePacketExchanger exchanger(&visitor, kMaxPendingPackets);
- MockQboneClient client;
- std::string packet = "data";
-
- // Write error is delivered to visitor during WritePacketToNetwork.
- std::string io_error = "I/O error";
- exchanger.ForceWriteFailure(false, io_error);
- EXPECT_CALL(visitor, OnWriteError(StrEq(io_error))).Times(1);
- exchanger.WritePacketToNetwork(packet.data(), packet.length());
- ASSERT_TRUE(exchanger.packets_written().empty());
-
- // Write error is delivered to visitor during SetWritable.
- exchanger.ForceWriteFailure(true, "");
- exchanger.WritePacketToNetwork(packet.data(), packet.length());
-
- std::string sys_error = "sys error";
- exchanger.ForceWriteFailure(false, sys_error);
- EXPECT_CALL(visitor, OnWriteError(StrEq(sys_error))).Times(1);
- exchanger.SetWritable();
- ASSERT_TRUE(exchanger.packets_written().empty());
-}
-
-TEST(QbonePacketExchangerTest, NullVisitorDoesntCrash) {
- FakeQbonePacketExchanger exchanger(nullptr, kMaxPendingPackets);
- MockQboneClient client;
- std::string packet = "data";
-
- // Force read error.
- std::string io_error = "I/O error";
- exchanger.SetReadError(io_error);
- EXPECT_FALSE(exchanger.ReadAndDeliverPacket(&client));
-
- // Force write error
- exchanger.ForceWriteFailure(false, io_error);
- exchanger.WritePacketToNetwork(packet.data(), packet.length());
- EXPECT_TRUE(exchanger.packets_written().empty());
-}
-
-} // namespace
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/qbone/qbone_packet_processor.cc b/chromium/net/third_party/quiche/src/quic/qbone/qbone_packet_processor.cc
deleted file mode 100644
index 6e83e760f3b..00000000000
--- a/chromium/net/third_party/quiche/src/quic/qbone/qbone_packet_processor.cc
+++ /dev/null
@@ -1,277 +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 "quic/qbone/qbone_packet_processor.h"
-
-#include <cstring>
-
-#include "absl/strings/string_view.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/qbone/platform/icmp_packet.h"
-#include "quic/qbone/platform/internet_checksum.h"
-#include "quic/qbone/platform/tcp_packet.h"
-#include "common/quiche_endian.h"
-
-namespace {
-
-constexpr size_t kIPv6AddressSize = 16;
-constexpr size_t kIPv6MinPacketSize = 1280;
-constexpr size_t kIcmpTtl = 64;
-constexpr size_t kICMPv6DestinationUnreachableDueToSourcePolicy = 5;
-
-} // namespace
-
-namespace quic {
-
-const QuicIpAddress QbonePacketProcessor::kInvalidIpAddress =
- QuicIpAddress::Any6();
-
-QbonePacketProcessor::QbonePacketProcessor(QuicIpAddress self_ip,
- QuicIpAddress client_ip,
- size_t client_ip_subnet_length,
- OutputInterface* output,
- StatsInterface* stats)
- : client_ip_(client_ip),
- output_(output),
- stats_(stats),
- filter_(new Filter) {
- memcpy(self_ip_.s6_addr, self_ip.ToPackedString().data(), kIPv6AddressSize);
- QUICHE_DCHECK_LE(client_ip_subnet_length, kIPv6AddressSize * 8);
- client_ip_subnet_length_ = client_ip_subnet_length;
-
- QUICHE_DCHECK(IpAddressFamily::IP_V6 == self_ip.address_family());
- QUICHE_DCHECK(IpAddressFamily::IP_V6 == client_ip.address_family());
- QUICHE_DCHECK(self_ip != kInvalidIpAddress);
-}
-
-QbonePacketProcessor::OutputInterface::~OutputInterface() {}
-QbonePacketProcessor::StatsInterface::~StatsInterface() {}
-QbonePacketProcessor::Filter::~Filter() {}
-
-QbonePacketProcessor::ProcessingResult
-QbonePacketProcessor::Filter::FilterPacket(Direction direction,
- absl::string_view full_packet,
- absl::string_view payload,
- icmp6_hdr* icmp_header,
- OutputInterface* output) {
- return ProcessingResult::OK;
-}
-
-void QbonePacketProcessor::ProcessPacket(std::string* packet,
- Direction direction) {
- if (QUIC_PREDICT_FALSE(!IsValid())) {
- QUIC_BUG(quic_bug_11024_1)
- << "QuicPacketProcessor is invoked in an invalid state.";
- stats_->OnPacketDroppedSilently(direction);
- return;
- }
-
- uint8_t transport_protocol;
- char* transport_data;
- icmp6_hdr icmp_header;
- memset(&icmp_header, 0, sizeof(icmp_header));
- ProcessingResult result = ProcessIPv6HeaderAndFilter(
- packet, direction, &transport_protocol, &transport_data, &icmp_header);
-
- switch (result) {
- case ProcessingResult::OK:
- switch (direction) {
- case Direction::FROM_OFF_NETWORK:
- output_->SendPacketToNetwork(*packet);
- break;
- case Direction::FROM_NETWORK:
- output_->SendPacketToClient(*packet);
- break;
- }
- stats_->OnPacketForwarded(direction);
- break;
- case ProcessingResult::SILENT_DROP:
- stats_->OnPacketDroppedSilently(direction);
- break;
- case ProcessingResult::DEFER:
- stats_->OnPacketDeferred(direction);
- break;
- case ProcessingResult::ICMP:
- SendIcmpResponse(&icmp_header, *packet, direction);
- stats_->OnPacketDroppedWithIcmp(direction);
- break;
- case ProcessingResult::ICMP_AND_TCP_RESET:
- SendIcmpResponse(&icmp_header, *packet, direction);
- stats_->OnPacketDroppedWithIcmp(direction);
- SendTcpReset(*packet, direction);
- stats_->OnPacketDroppedWithTcpReset(direction);
- break;
- case ProcessingResult::TCP_RESET:
- SendTcpReset(*packet, direction);
- stats_->OnPacketDroppedWithTcpReset(direction);
- break;
- }
-}
-
-QbonePacketProcessor::ProcessingResult
-QbonePacketProcessor::ProcessIPv6HeaderAndFilter(std::string* packet,
- Direction direction,
- uint8_t* transport_protocol,
- char** transport_data,
- icmp6_hdr* icmp_header) {
- ProcessingResult result = ProcessIPv6Header(
- packet, direction, transport_protocol, transport_data, icmp_header);
-
- if (result == ProcessingResult::OK) {
- char* packet_data = &*packet->begin();
- size_t header_size = *transport_data - packet_data;
- // Sanity-check the bounds.
- if (packet_data >= *transport_data || header_size > packet->size() ||
- header_size < kIPv6HeaderSize) {
- QUIC_BUG(quic_bug_11024_2)
- << "Invalid pointers encountered in "
- "QbonePacketProcessor::ProcessPacket. Dropping the packet";
- return ProcessingResult::SILENT_DROP;
- }
-
- result = filter_->FilterPacket(
- direction, *packet,
- absl::string_view(*transport_data, packet->size() - header_size),
- icmp_header, output_);
- }
-
- // Do not send ICMP error messages in response to ICMP errors.
- if (result == ProcessingResult::ICMP) {
- const uint8_t* header = reinterpret_cast<const uint8_t*>(packet->data());
-
- constexpr size_t kIPv6NextHeaderOffset = 6;
- constexpr size_t kIcmpMessageTypeOffset = kIPv6HeaderSize + 0;
- constexpr size_t kIcmpMessageTypeMaxError = 127;
- if (
- // Check size.
- packet->size() >= (kIPv6HeaderSize + kICMPv6HeaderSize) &&
- // Check that the packet is in fact ICMP.
- header[kIPv6NextHeaderOffset] == IPPROTO_ICMPV6 &&
- // Check that ICMP message type is an error.
- header[kIcmpMessageTypeOffset] < kIcmpMessageTypeMaxError) {
- result = ProcessingResult::SILENT_DROP;
- }
- }
-
- return result;
-}
-
-QbonePacketProcessor::ProcessingResult QbonePacketProcessor::ProcessIPv6Header(
- std::string* packet,
- Direction direction,
- uint8_t* transport_protocol,
- char** transport_data,
- icmp6_hdr* icmp_header) {
- // Check if the packet is big enough to have IPv6 header.
- if (packet->size() < kIPv6HeaderSize) {
- QUIC_DVLOG(1) << "Dropped malformed packet: IPv6 header too short";
- return ProcessingResult::SILENT_DROP;
- }
-
- // Check version field.
- ip6_hdr* header = reinterpret_cast<ip6_hdr*>(&*packet->begin());
- if (header->ip6_vfc >> 4 != 6) {
- QUIC_DVLOG(1) << "Dropped malformed packet: IP version is not IPv6";
- return ProcessingResult::SILENT_DROP;
- }
-
- // Check payload size.
- const size_t declared_payload_size =
- quiche::QuicheEndian::NetToHost16(header->ip6_plen);
- const size_t actual_payload_size = packet->size() - kIPv6HeaderSize;
- if (declared_payload_size != actual_payload_size) {
- QUIC_DVLOG(1)
- << "Dropped malformed packet: incorrect packet length specified";
- return ProcessingResult::SILENT_DROP;
- }
-
- // Check that the address of the client is in the packet.
- QuicIpAddress address_to_check;
- uint8_t address_reject_code;
- bool ip_parse_result;
- switch (direction) {
- case Direction::FROM_OFF_NETWORK:
- // Expect the source IP to match the client.
- ip_parse_result = address_to_check.FromPackedString(
- reinterpret_cast<const char*>(&header->ip6_src),
- sizeof(header->ip6_src));
- address_reject_code = kICMPv6DestinationUnreachableDueToSourcePolicy;
- break;
- case Direction::FROM_NETWORK:
- // Expect the destination IP to match the client.
- ip_parse_result = address_to_check.FromPackedString(
- reinterpret_cast<const char*>(&header->ip6_dst),
- sizeof(header->ip6_src));
- address_reject_code = ICMP6_DST_UNREACH_NOROUTE;
- break;
- }
- QUICHE_DCHECK(ip_parse_result);
- if (!client_ip_.InSameSubnet(address_to_check, client_ip_subnet_length_)) {
- QUIC_DVLOG(1)
- << "Dropped packet: source/destination address is not client's";
- icmp_header->icmp6_type = ICMP6_DST_UNREACH;
- icmp_header->icmp6_code = address_reject_code;
- return ProcessingResult::ICMP;
- }
-
- // Check and decrement TTL.
- if (header->ip6_hops <= 1) {
- icmp_header->icmp6_type = ICMP6_TIME_EXCEEDED;
- icmp_header->icmp6_code = ICMP6_TIME_EXCEED_TRANSIT;
- return ProcessingResult::ICMP;
- }
- header->ip6_hops--;
-
- // Check and extract IP headers.
- switch (header->ip6_nxt) {
- case IPPROTO_TCP:
- case IPPROTO_UDP:
- case IPPROTO_ICMPV6:
- *transport_protocol = header->ip6_nxt;
- *transport_data = (&*packet->begin()) + kIPv6HeaderSize;
- break;
- default:
- icmp_header->icmp6_type = ICMP6_PARAM_PROB;
- icmp_header->icmp6_code = ICMP6_PARAMPROB_NEXTHEADER;
- return ProcessingResult::ICMP;
- }
-
- return ProcessingResult::OK;
-}
-
-void QbonePacketProcessor::SendIcmpResponse(icmp6_hdr* icmp_header,
- absl::string_view original_packet,
- Direction original_direction) {
- in6_addr dst;
- // TODO(b/70339814): ensure this is actually a unicast address.
- memcpy(dst.s6_addr, &original_packet[8], kIPv6AddressSize);
-
- CreateIcmpPacket(self_ip_, dst, *icmp_header, original_packet,
- [this, original_direction](absl::string_view packet) {
- SendResponse(original_direction, packet);
- });
-}
-
-void QbonePacketProcessor::SendTcpReset(absl::string_view original_packet,
- Direction original_direction) {
- CreateTcpResetPacket(original_packet,
- [this, original_direction](absl::string_view packet) {
- SendResponse(original_direction, packet);
- });
-}
-
-void QbonePacketProcessor::SendResponse(Direction original_direction,
- absl::string_view packet) {
- switch (original_direction) {
- case Direction::FROM_OFF_NETWORK:
- output_->SendPacketToClient(packet);
- break;
- case Direction::FROM_NETWORK:
- output_->SendPacketToNetwork(packet);
- break;
- }
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/qbone/qbone_packet_processor.h b/chromium/net/third_party/quiche/src/quic/qbone/qbone_packet_processor.h
deleted file mode 100644
index 8c2375a288c..00000000000
--- a/chromium/net/third_party/quiche/src/quic/qbone/qbone_packet_processor.h
+++ /dev/null
@@ -1,201 +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_QBONE_QBONE_PACKET_PROCESSOR_H_
-#define QUICHE_QUIC_QBONE_QBONE_PACKET_PROCESSOR_H_
-
-#include <netinet/icmp6.h>
-#include <netinet/ip6.h>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_ip_address.h"
-
-namespace quic {
-
-enum : size_t {
- kIPv6HeaderSize = 40,
- kICMPv6HeaderSize = sizeof(icmp6_hdr),
- kTotalICMPv6HeaderSize = kIPv6HeaderSize + kICMPv6HeaderSize,
-};
-
-// QBONE packet processor accepts packets destined in either direction
-// (client-to-network or network-to-client). It inspects them and makes
-// decisions on whether they should be forwarded or dropped, replying with ICMP
-// messages as appropriate.
-class QbonePacketProcessor {
- public:
- enum class Direction {
- // Packet is going from the QBONE client into the network behind the QBONE.
- FROM_OFF_NETWORK = 0,
- // Packet is going from the network begin QBONE to the client.
- FROM_NETWORK = 1
- };
-
- enum class ProcessingResult {
- OK = 0,
- SILENT_DROP = 1,
- ICMP = 2,
- // Equivalent to |SILENT_DROP| at the moment, but indicates that the
- // downstream filter has buffered the packet and deferred its processing.
- // The packet may be emitted at a later time.
- DEFER = 3,
- // In addition to sending an ICMP message, also send a TCP RST. This option
- // requires the incoming packet to have been a valid TCP packet, as a TCP
- // RST requires information from the current connection state to be
- // well-formed.
- ICMP_AND_TCP_RESET = 4,
- // Send a TCP RST.
- TCP_RESET = 5,
- };
-
- class OutputInterface {
- public:
- virtual ~OutputInterface();
-
- virtual void SendPacketToClient(absl::string_view packet) = 0;
- virtual void SendPacketToNetwork(absl::string_view packet) = 0;
- };
-
- class StatsInterface {
- public:
- virtual ~StatsInterface();
-
- virtual void OnPacketForwarded(Direction direction) = 0;
- virtual void OnPacketDroppedSilently(Direction direction) = 0;
- virtual void OnPacketDroppedWithIcmp(Direction direction) = 0;
- virtual void OnPacketDroppedWithTcpReset(Direction direction) = 0;
- virtual void OnPacketDeferred(Direction direction) = 0;
- };
-
- // Allows to implement a custom packet filter on top of the filtering done by
- // the packet processor itself.
- class Filter {
- public:
- virtual ~Filter();
- // The main interface function. The following arguments are supplied:
- // - |direction|, to indicate direction of the packet.
- // - |full_packet|, which includes the IPv6 header and possibly the IPv6
- // options that were understood by the processor.
- // - |payload|, the contents of the IPv6 packet, i.e. a TCP, a UDP or an
- // ICMP packet.
- // - |icmp_header|, an output argument which allows the filter to specify
- // the ICMP message with which the packet is to be rejected.
- // The method is called only on packets which were already verified as valid
- // IPv6 packets.
- //
- // The implementer of this method has four options to return:
- // - OK will cause the filter to pass the packet through
- // - SILENT_DROP will cause the filter to drop the packet silently
- // - ICMP will cause the filter to drop the packet and send an ICMP
- // response.
- // - DEFER will cause the packet to be not forwarded; the filter is
- // responsible for sending (or not sending) it later using |output|.
- //
- // Note that |output| should not be used except in the DEFER case, as the
- // processor will perform the necessary writes itself.
- virtual ProcessingResult FilterPacket(Direction direction,
- absl::string_view full_packet,
- absl::string_view payload,
- icmp6_hdr* icmp_header,
- OutputInterface* output);
-
- protected:
- // Helper methods that allow to easily extract information that is required
- // for filtering from the |ipv6_header| argument. All of those assume that
- // the header is of valid size, which is true for everything passed into
- // FilterPacket().
- inline uint8_t TransportProtocolFromHeader(absl::string_view ipv6_header) {
- return ipv6_header[6];
- }
- inline QuicIpAddress SourceIpFromHeader(absl::string_view ipv6_header) {
- QuicIpAddress address;
- address.FromPackedString(&ipv6_header[8],
- QuicIpAddress::kIPv6AddressSize);
- return address;
- }
- inline QuicIpAddress DestinationIpFromHeader(
- absl::string_view ipv6_header) {
- QuicIpAddress address;
- address.FromPackedString(&ipv6_header[24],
- QuicIpAddress::kIPv6AddressSize);
- return address;
- }
- };
-
- // |self_ip| is the IP address from which the processor will originate ICMP
- // messages. |client_ip| is the expected IP address of the client, used for
- // packet validation.
- //
- // |output| and |stats| are the visitor interfaces used by the processor.
- // |output| gets notified whenever the processor decides to send a packet, and
- // |stats| gets notified about any decisions that processor makes, without a
- // reference to which packet that decision was made about.
- QbonePacketProcessor(QuicIpAddress self_ip,
- QuicIpAddress client_ip,
- size_t client_ip_subnet_length,
- OutputInterface* output,
- StatsInterface* stats);
- QbonePacketProcessor(const QbonePacketProcessor&) = delete;
- QbonePacketProcessor& operator=(const QbonePacketProcessor&) = delete;
-
- // Accepts an IPv6 packet and handles it accordingly by either forwarding it,
- // replying with an ICMP packet or silently dropping it. |packet| will be
- // modified in the process, by having the TTL field decreased.
- void ProcessPacket(std::string* packet, Direction direction);
-
- void set_filter(std::unique_ptr<Filter> filter) {
- filter_ = std::move(filter);
- }
-
- void set_client_ip(QuicIpAddress client_ip) { client_ip_ = client_ip; }
- void set_client_ip_subnet_length(size_t client_ip_subnet_length) {
- client_ip_subnet_length_ = client_ip_subnet_length;
- }
-
- static const QuicIpAddress kInvalidIpAddress;
-
- protected:
- // Processes the header and returns what should be done with the packet.
- // After that, calls an external packet filter if registered. TTL of the
- // packet may be decreased in the process.
- ProcessingResult ProcessIPv6HeaderAndFilter(std::string* packet,
- Direction direction,
- uint8_t* transport_protocol,
- char** transport_data,
- icmp6_hdr* icmp_header);
-
- void SendIcmpResponse(icmp6_hdr* icmp_header,
- absl::string_view original_packet,
- Direction original_direction);
-
- void SendTcpReset(absl::string_view original_packet,
- Direction original_direction);
-
- inline bool IsValid() const { return client_ip_ != kInvalidIpAddress; }
-
- // IP address of the server. Used to send ICMP messages.
- in6_addr self_ip_;
- // IP address range of the VPN client.
- QuicIpAddress client_ip_;
- size_t client_ip_subnet_length_;
-
- OutputInterface* output_;
- StatsInterface* stats_;
- std::unique_ptr<Filter> filter_;
-
- private:
- // Performs basic sanity and permission checks on the packet, and decreases
- // the TTL.
- ProcessingResult ProcessIPv6Header(std::string* packet,
- Direction direction,
- uint8_t* transport_protocol,
- char** transport_data,
- icmp6_hdr* icmp_header);
-
- void SendResponse(Direction original_direction, absl::string_view packet);
-};
-
-} // namespace quic
-#endif // QUICHE_QUIC_QBONE_QBONE_PACKET_PROCESSOR_H_
diff --git a/chromium/net/third_party/quiche/src/quic/qbone/qbone_packet_processor_test.cc b/chromium/net/third_party/quiche/src/quic/qbone/qbone_packet_processor_test.cc
deleted file mode 100644
index d79400c0418..00000000000
--- a/chromium/net/third_party/quiche/src/quic/qbone/qbone_packet_processor_test.cc
+++ /dev/null
@@ -1,287 +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 "quic/qbone/qbone_packet_processor.h"
-
-#include <utility>
-
-#include "absl/strings/string_view.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/qbone/qbone_packet_processor_test_tools.h"
-
-namespace quic {
-namespace {
-
-using Direction = QbonePacketProcessor::Direction;
-using ProcessingResult = QbonePacketProcessor::ProcessingResult;
-using OutputInterface = QbonePacketProcessor::OutputInterface;
-using ::testing::_;
-using ::testing::Return;
-
-// clang-format off
-static const char kReferenceClientPacketData[] = {
- // IPv6 with zero TOS and flow label.
- 0x60, 0x00, 0x00, 0x00,
- // Payload size is 8 bytes.
- 0x00, 0x08,
- // Next header is UDP
- 17,
- // TTL is 50.
- 50,
- // IP address of the sender is fd00:0:0:1::1
- 0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
- // IP address of the receiver is fd00:0:0:5::1
- 0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
- // Source port 12345
- 0x30, 0x39,
- // Destination port 443
- 0x01, 0xbb,
- // UDP content length is zero
- 0x00, 0x00,
- // Checksum is not actually checked in any of the tests, so we leave it as
- // zero
- 0x00, 0x00,
-};
-
-static const char kReferenceNetworkPacketData[] = {
- // IPv6 with zero TOS and flow label.
- 0x60, 0x00, 0x00, 0x00,
- // Payload size is 8 bytes.
- 0x00, 0x08,
- // Next header is UDP
- 17,
- // TTL is 50.
- 50,
- // IP address of the sender is fd00:0:0:5::1
- 0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
- // IP address of the receiver is fd00:0:0:1::1
- 0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
- // Source port 443
- 0x01, 0xbb,
- // Destination port 12345
- 0x30, 0x39,
- // UDP content length is zero
- 0x00, 0x00,
- // Checksum is not actually checked in any of the tests, so we leave it as
- // zero
- 0x00, 0x00,
-};
-
-static const char kReferenceClientSubnetPacketData[] = {
- // IPv6 with zero TOS and flow label.
- 0x60, 0x00, 0x00, 0x00,
- // Payload size is 8 bytes.
- 0x00, 0x08,
- // Next header is UDP
- 17,
- // TTL is 50.
- 50,
- // IP address of the sender is fd00:0:0:2::1, which is within the /62 of the
- // client.
- 0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
- // IP address of the receiver is fd00:0:0:5::1
- 0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
- // Source port 12345
- 0x30, 0x39,
- // Destination port 443
- 0x01, 0xbb,
- // UDP content length is zero
- 0x00, 0x00,
- // Checksum is not actually checked in any of the tests, so we leave it as
- // zero
- 0x00, 0x00,
-};
-
-// clang-format on
-
-static const absl::string_view kReferenceClientPacket(
- kReferenceClientPacketData,
- arraysize(kReferenceClientPacketData));
-
-static const absl::string_view kReferenceNetworkPacket(
- kReferenceNetworkPacketData,
- arraysize(kReferenceNetworkPacketData));
-
-static const absl::string_view kReferenceClientSubnetPacket(
- kReferenceClientSubnetPacketData,
- arraysize(kReferenceClientSubnetPacketData));
-
-MATCHER_P(IsIcmpMessage,
- icmp_type,
- "Checks whether the argument is an ICMP message of supplied type") {
- if (arg.size() < kTotalICMPv6HeaderSize) {
- return false;
- }
-
- return arg[40] == icmp_type;
-}
-
-class MockPacketFilter : public QbonePacketProcessor::Filter {
- public:
- MOCK_METHOD(ProcessingResult,
- FilterPacket,
- (Direction,
- absl::string_view,
- absl::string_view,
- icmp6_hdr*,
- OutputInterface*),
- (override));
-};
-
-class QbonePacketProcessorTest : public QuicTest {
- protected:
- QbonePacketProcessorTest() {
- QUICHE_CHECK(client_ip_.FromString("fd00:0:0:1::1"));
- QUICHE_CHECK(self_ip_.FromString("fd00:0:0:4::1"));
- QUICHE_CHECK(network_ip_.FromString("fd00:0:0:5::1"));
-
- processor_ = std::make_unique<QbonePacketProcessor>(
- self_ip_, client_ip_, /*client_ip_subnet_length=*/62, &output_,
- &stats_);
- }
-
- void SendPacketFromClient(absl::string_view packet) {
- std::string packet_buffer(packet.data(), packet.size());
- processor_->ProcessPacket(&packet_buffer, Direction::FROM_OFF_NETWORK);
- }
-
- void SendPacketFromNetwork(absl::string_view packet) {
- std::string packet_buffer(packet.data(), packet.size());
- processor_->ProcessPacket(&packet_buffer, Direction::FROM_NETWORK);
- }
-
- QuicIpAddress client_ip_;
- QuicIpAddress self_ip_;
- QuicIpAddress network_ip_;
-
- std::unique_ptr<QbonePacketProcessor> processor_;
- testing::StrictMock<MockPacketProcessorOutput> output_;
- testing::StrictMock<MockPacketProcessorStats> stats_;
-};
-
-TEST_F(QbonePacketProcessorTest, EmptyPacket) {
- EXPECT_CALL(stats_, OnPacketDroppedSilently(Direction::FROM_OFF_NETWORK));
- SendPacketFromClient("");
-
- EXPECT_CALL(stats_, OnPacketDroppedSilently(Direction::FROM_NETWORK));
- SendPacketFromNetwork("");
-}
-
-TEST_F(QbonePacketProcessorTest, RandomGarbage) {
- EXPECT_CALL(stats_, OnPacketDroppedSilently(Direction::FROM_OFF_NETWORK));
- SendPacketFromClient(std::string(1280, 'a'));
-
- EXPECT_CALL(stats_, OnPacketDroppedSilently(Direction::FROM_NETWORK));
- SendPacketFromNetwork(std::string(1280, 'a'));
-}
-
-TEST_F(QbonePacketProcessorTest, RandomGarbageWithCorrectLengthFields) {
- std::string packet(40, 'a');
- packet[4] = 0;
- packet[5] = 0;
-
- EXPECT_CALL(stats_, OnPacketDroppedWithIcmp(Direction::FROM_OFF_NETWORK));
- EXPECT_CALL(output_, SendPacketToClient(IsIcmpMessage(ICMP6_DST_UNREACH)));
- SendPacketFromClient(packet);
-}
-
-TEST_F(QbonePacketProcessorTest, GoodPacketFromClient) {
- EXPECT_CALL(stats_, OnPacketForwarded(Direction::FROM_OFF_NETWORK));
- EXPECT_CALL(output_, SendPacketToNetwork(_));
- SendPacketFromClient(kReferenceClientPacket);
-}
-
-TEST_F(QbonePacketProcessorTest, GoodPacketFromClientSubnet) {
- EXPECT_CALL(stats_, OnPacketForwarded(Direction::FROM_OFF_NETWORK));
- EXPECT_CALL(output_, SendPacketToNetwork(_));
- SendPacketFromClient(kReferenceClientSubnetPacket);
-}
-
-TEST_F(QbonePacketProcessorTest, GoodPacketFromNetwork) {
- EXPECT_CALL(stats_, OnPacketForwarded(Direction::FROM_NETWORK));
- EXPECT_CALL(output_, SendPacketToClient(_));
- SendPacketFromNetwork(kReferenceNetworkPacket);
-}
-
-TEST_F(QbonePacketProcessorTest, GoodPacketFromNetworkWrongDirection) {
- EXPECT_CALL(stats_, OnPacketDroppedWithIcmp(Direction::FROM_OFF_NETWORK));
- EXPECT_CALL(output_, SendPacketToClient(IsIcmpMessage(ICMP6_DST_UNREACH)));
- SendPacketFromClient(kReferenceNetworkPacket);
-}
-
-TEST_F(QbonePacketProcessorTest, TtlExpired) {
- std::string packet(kReferenceNetworkPacket);
- packet[7] = 1;
-
- EXPECT_CALL(stats_, OnPacketDroppedWithIcmp(Direction::FROM_NETWORK));
- EXPECT_CALL(output_, SendPacketToNetwork(IsIcmpMessage(ICMP6_TIME_EXCEEDED)));
- SendPacketFromNetwork(packet);
-}
-
-TEST_F(QbonePacketProcessorTest, UnknownProtocol) {
- std::string packet(kReferenceNetworkPacket);
- packet[6] = IPPROTO_SCTP;
-
- EXPECT_CALL(stats_, OnPacketDroppedWithIcmp(Direction::FROM_NETWORK));
- EXPECT_CALL(output_, SendPacketToNetwork(IsIcmpMessage(ICMP6_PARAM_PROB)));
- SendPacketFromNetwork(packet);
-}
-
-TEST_F(QbonePacketProcessorTest, FilterFromClient) {
- auto filter = std::make_unique<MockPacketFilter>();
- EXPECT_CALL(*filter, FilterPacket(_, _, _, _, _))
- .WillRepeatedly(Return(ProcessingResult::SILENT_DROP));
- processor_->set_filter(std::move(filter));
-
- EXPECT_CALL(stats_, OnPacketDroppedSilently(Direction::FROM_OFF_NETWORK));
- SendPacketFromClient(kReferenceClientPacket);
-}
-
-class TestFilter : public QbonePacketProcessor::Filter {
- public:
- TestFilter(QuicIpAddress client_ip, QuicIpAddress network_ip)
- : client_ip_(client_ip), network_ip_(network_ip) {}
- ProcessingResult FilterPacket(Direction direction,
- absl::string_view full_packet,
- absl::string_view payload,
- icmp6_hdr* icmp_header,
- OutputInterface* output) override {
- EXPECT_EQ(kIPv6HeaderSize, full_packet.size() - payload.size());
- EXPECT_EQ(IPPROTO_UDP, TransportProtocolFromHeader(full_packet));
- EXPECT_EQ(client_ip_, SourceIpFromHeader(full_packet));
- EXPECT_EQ(network_ip_, DestinationIpFromHeader(full_packet));
-
- called_++;
- return ProcessingResult::SILENT_DROP;
- }
-
- int called() const { return called_; }
-
- private:
- int called_ = 0;
-
- QuicIpAddress client_ip_;
- QuicIpAddress network_ip_;
-};
-
-// Verify that the parameters are passed correctly into the filter, and that the
-// helper functions of the filter class work.
-TEST_F(QbonePacketProcessorTest, FilterHelperFunctions) {
- auto filter_owned = std::make_unique<TestFilter>(client_ip_, network_ip_);
- TestFilter* filter = filter_owned.get();
- processor_->set_filter(std::move(filter_owned));
-
- EXPECT_CALL(stats_, OnPacketDroppedSilently(Direction::FROM_OFF_NETWORK));
- SendPacketFromClient(kReferenceClientPacket);
- ASSERT_EQ(1, filter->called());
-}
-
-} // namespace
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/qbone/qbone_packet_processor_test_tools.cc b/chromium/net/third_party/quiche/src/quic/qbone/qbone_packet_processor_test_tools.cc
deleted file mode 100644
index 5df158d87f9..00000000000
--- a/chromium/net/third_party/quiche/src/quic/qbone/qbone_packet_processor_test_tools.cc
+++ /dev/null
@@ -1,28 +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 "quic/qbone/qbone_packet_processor_test_tools.h"
-
-#include <netinet/ip6.h>
-
-namespace quic {
-
-std::string PrependIPv6HeaderForTest(const std::string& body, int hops) {
- ip6_hdr header;
- memset(&header, 0, sizeof(header));
-
- header.ip6_vfc = 6 << 4;
- header.ip6_plen = htons(body.size());
- header.ip6_nxt = IPPROTO_UDP;
- header.ip6_hops = hops;
- header.ip6_src = in6addr_loopback;
- header.ip6_dst = in6addr_loopback;
-
- std::string packet(sizeof(header) + body.size(), '\0');
- memcpy(&packet[0], &header, sizeof(header));
- memcpy(&packet[sizeof(header)], body.data(), body.size());
- return packet;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/qbone/qbone_packet_processor_test_tools.h b/chromium/net/third_party/quiche/src/quic/qbone/qbone_packet_processor_test_tools.h
deleted file mode 100644
index e26313b4f1b..00000000000
--- a/chromium/net/third_party/quiche/src/quic/qbone/qbone_packet_processor_test_tools.h
+++ /dev/null
@@ -1,52 +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_QBONE_QBONE_PACKET_PROCESSOR_TEST_TOOLS_H_
-#define QUICHE_QUIC_QBONE_QBONE_PACKET_PROCESSOR_TEST_TOOLS_H_
-
-#include "absl/strings/string_view.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/qbone/qbone_packet_processor.h"
-
-namespace quic {
-
-class MockPacketProcessorOutput : public QbonePacketProcessor::OutputInterface {
- public:
- MockPacketProcessorOutput() {}
-
- MOCK_METHOD(void, SendPacketToClient, (absl::string_view), (override));
- MOCK_METHOD(void, SendPacketToNetwork, (absl::string_view), (override));
-};
-
-class MockPacketProcessorStats : public QbonePacketProcessor::StatsInterface {
- public:
- MockPacketProcessorStats() {}
-
- MOCK_METHOD(void,
- OnPacketForwarded,
- (QbonePacketProcessor::Direction),
- (override));
- MOCK_METHOD(void,
- OnPacketDroppedSilently,
- (QbonePacketProcessor::Direction),
- (override));
- MOCK_METHOD(void,
- OnPacketDroppedWithIcmp,
- (QbonePacketProcessor::Direction),
- (override));
- MOCK_METHOD(void,
- OnPacketDroppedWithTcpReset,
- (QbonePacketProcessor::Direction),
- (override));
- MOCK_METHOD(void,
- OnPacketDeferred,
- (QbonePacketProcessor::Direction),
- (override));
-};
-
-std::string PrependIPv6HeaderForTest(const std::string& body, int hops);
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_QBONE_QBONE_PACKET_PROCESSOR_TEST_TOOLS_H_
diff --git a/chromium/net/third_party/quiche/src/quic/qbone/qbone_packet_writer.h b/chromium/net/third_party/quiche/src/quic/qbone/qbone_packet_writer.h
deleted file mode 100644
index 1ed8a46fa04..00000000000
--- a/chromium/net/third_party/quiche/src/quic/qbone/qbone_packet_writer.h
+++ /dev/null
@@ -1,24 +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_QBONE_QBONE_PACKET_WRITER_H_
-#define QUICHE_QUIC_QBONE_QBONE_PACKET_WRITER_H_
-
-#include <cstring>
-
-namespace quic {
-
-// QbonePacketWriter expects only one function to be defined,
-// WritePacketToNetwork, which is called when a packet is received via QUIC
-// and should be sent out on the network. This is the complete packet,
-// and not just a fragment.
-class QbonePacketWriter {
- public:
- virtual ~QbonePacketWriter() {}
- virtual void WritePacketToNetwork(const char* packet, size_t size) = 0;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_QBONE_QBONE_PACKET_WRITER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/qbone/qbone_server_session.cc b/chromium/net/third_party/quiche/src/quic/qbone/qbone_server_session.cc
deleted file mode 100644
index bc2d8e53a3c..00000000000
--- a/chromium/net/third_party/quiche/src/quic/qbone/qbone_server_session.cc
+++ /dev/null
@@ -1,133 +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 "quic/qbone/qbone_server_session.h"
-
-#include <string>
-#include <utility>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_connection_id.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_utils.h"
-#include "quic/qbone/qbone_constants.h"
-#include "common/platform/api/quiche_command_line_flags.h"
-
-DEFINE_QUICHE_COMMAND_LINE_FLAG(
- bool, qbone_server_defer_control_stream_creation, true,
- "If true, control stream in QBONE server session is created after "
- "encryption established.");
-
-namespace quic {
-
-bool QboneCryptoServerStreamHelper::CanAcceptClientHello(
- const CryptoHandshakeMessage& chlo,
- const QuicSocketAddress& client_address,
- const QuicSocketAddress& peer_address,
- const QuicSocketAddress& self_address,
- std::string* error_details) const {
- absl::string_view alpn;
- chlo.GetStringPiece(quic::kALPN, &alpn);
- if (alpn != QboneConstants::kQboneAlpn) {
- *error_details = "ALPN-indicated protocol is not qbone";
- return false;
- }
- return true;
-}
-
-QboneServerSession::QboneServerSession(
- const quic::ParsedQuicVersionVector& supported_versions,
- QuicConnection* connection,
- Visitor* owner,
- const QuicConfig& config,
- const QuicCryptoServerConfig* quic_crypto_server_config,
- QuicCompressedCertsCache* compressed_certs_cache,
- QbonePacketWriter* writer,
- QuicIpAddress self_ip,
- QuicIpAddress client_ip,
- size_t client_ip_subnet_length,
- QboneServerControlStream::Handler* handler)
- : QboneSessionBase(connection, owner, config, supported_versions, writer),
- processor_(self_ip, client_ip, client_ip_subnet_length, this, this),
- quic_crypto_server_config_(quic_crypto_server_config),
- compressed_certs_cache_(compressed_certs_cache),
- handler_(handler) {}
-
-QboneServerSession::~QboneServerSession() {}
-
-std::unique_ptr<QuicCryptoStream> QboneServerSession::CreateCryptoStream() {
- return CreateCryptoServerStream(quic_crypto_server_config_,
- compressed_certs_cache_, this,
- &stream_helper_);
-}
-
-void QboneServerSession::CreateControlStream() {
- if (control_stream_ != nullptr) {
- return;
- }
- // Register the reserved control stream.
- auto control_stream =
- std::make_unique<QboneServerControlStream>(this, handler_);
- control_stream_ = control_stream.get();
- ActivateStream(std::move(control_stream));
-}
-
-QuicStream* QboneServerSession::CreateControlStreamFromPendingStream(
- PendingStream* pending) {
- QUICHE_DCHECK(control_stream_ == nullptr);
- // Register the reserved control stream.
- auto control_stream =
- std::make_unique<QboneServerControlStream>(pending, this, handler_);
- control_stream_ = control_stream.get();
- ActivateStream(std::move(control_stream));
- return control_stream_;
-}
-
-void QboneServerSession::Initialize() {
- QboneSessionBase::Initialize();
- if (!GetQuicFlag(FLAGS_qbone_server_defer_control_stream_creation)) {
- CreateControlStream();
- }
-}
-
-void QboneServerSession::SetDefaultEncryptionLevel(
- quic::EncryptionLevel level) {
- QboneSessionBase::SetDefaultEncryptionLevel(level);
- if (GetQuicFlag(FLAGS_qbone_server_defer_control_stream_creation) &&
- level == quic::ENCRYPTION_FORWARD_SECURE) {
- CreateControlStream();
- }
-}
-
-bool QboneServerSession::SendClientRequest(const QboneClientRequest& request) {
- if (!control_stream_) {
- QUIC_BUG(quic_bug_11026_1)
- << "Cannot send client request before control stream is created.";
- return false;
- }
- return control_stream_->SendRequest(request);
-}
-
-void QboneServerSession::ProcessPacketFromNetwork(absl::string_view packet) {
- std::string buffer = std::string(packet);
- processor_.ProcessPacket(&buffer,
- QbonePacketProcessor::Direction::FROM_NETWORK);
-}
-
-void QboneServerSession::ProcessPacketFromPeer(absl::string_view packet) {
- std::string buffer = std::string(packet);
- processor_.ProcessPacket(&buffer,
- QbonePacketProcessor::Direction::FROM_OFF_NETWORK);
-}
-
-void QboneServerSession::SendPacketToClient(absl::string_view packet) {
- SendPacketToPeer(packet);
-}
-
-void QboneServerSession::SendPacketToNetwork(absl::string_view packet) {
- QUICHE_DCHECK(writer_ != nullptr);
- writer_->WritePacketToNetwork(packet.data(), packet.size());
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/qbone/qbone_server_session.h b/chromium/net/third_party/quiche/src/quic/qbone/qbone_server_session.h
deleted file mode 100644
index d206e4d7012..00000000000
--- a/chromium/net/third_party/quiche/src/quic/qbone/qbone_server_session.h
+++ /dev/null
@@ -1,105 +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_QBONE_QBONE_SERVER_SESSION_H_
-#define QUICHE_QUIC_QBONE_QBONE_SERVER_SESSION_H_
-
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_crypto_server_stream_base.h"
-#include "quic/core/quic_crypto_stream.h"
-#include "quic/platform/api/quic_export.h"
-#include "quic/qbone/qbone_control.pb.h"
-#include "quic/qbone/qbone_control_stream.h"
-#include "quic/qbone/qbone_packet_processor.h"
-#include "quic/qbone/qbone_packet_writer.h"
-#include "quic/qbone/qbone_session_base.h"
-
-namespace quic {
-
-// A helper class is used by the QuicCryptoServerStream.
-class QboneCryptoServerStreamHelper
- : public QuicCryptoServerStreamBase::Helper {
- public:
- // This will look for the QBONE alpn.
- bool CanAcceptClientHello(const CryptoHandshakeMessage& chlo,
- const QuicSocketAddress& client_address,
- const QuicSocketAddress& peer_address,
- const QuicSocketAddress& self_address,
- std::string* error_details) const override;
-};
-
-class QUIC_EXPORT_PRIVATE QboneServerSession
- : public QboneSessionBase,
- public QbonePacketProcessor::OutputInterface,
- public QbonePacketProcessor::StatsInterface {
- public:
- QboneServerSession(const quic::ParsedQuicVersionVector& supported_versions,
- QuicConnection* connection,
- Visitor* owner,
- const QuicConfig& config,
- const QuicCryptoServerConfig* quic_crypto_server_config,
- QuicCompressedCertsCache* compressed_certs_cache,
- QbonePacketWriter* writer,
- QuicIpAddress self_ip,
- QuicIpAddress client_ip,
- size_t client_ip_subnet_length,
- QboneServerControlStream::Handler* handler);
- QboneServerSession(const QboneServerSession&) = delete;
- QboneServerSession& operator=(const QboneServerSession&) = delete;
- ~QboneServerSession() override;
-
- void Initialize() override;
- // Override to create control stream at FORWARD_SECURE encryption level.
- void SetDefaultEncryptionLevel(quic::EncryptionLevel level) override;
-
- virtual bool SendClientRequest(const QboneClientRequest& request);
-
- void ProcessPacketFromNetwork(absl::string_view packet) override;
- void ProcessPacketFromPeer(absl::string_view packet) override;
-
- // QbonePacketProcessor::OutputInterface implementation.
- void SendPacketToClient(absl::string_view packet) override;
- void SendPacketToNetwork(absl::string_view packet) override;
-
- // QbonePacketProcessor::StatsInterface implementation.
- void OnPacketForwarded(QbonePacketProcessor::Direction direction) override {}
- void OnPacketDroppedSilently(
- QbonePacketProcessor::Direction direction) override {}
- void OnPacketDroppedWithIcmp(
- QbonePacketProcessor::Direction direction) override {}
- void OnPacketDroppedWithTcpReset(
- QbonePacketProcessor::Direction direction) override {}
- void OnPacketDeferred(QbonePacketProcessor::Direction direction) override {}
-
- protected:
- // QboneSessionBase interface implementation.
- std::unique_ptr<QuicCryptoStream> CreateCryptoStream() override;
-
- // Instantiates QboneServerControlStream.
- void CreateControlStream();
-
- // Instantiates QboneServerControlStream from the pending stream and returns a
- // pointer to it.
- QuicStream* CreateControlStreamFromPendingStream(PendingStream* pending);
-
- // The packet processor.
- QbonePacketProcessor processor_;
-
- // Config for QUIC crypto server stream, used by the server.
- const QuicCryptoServerConfig* quic_crypto_server_config_;
-
- private:
- // Used by QUIC crypto server stream to track most recently compressed certs.
- QuicCompressedCertsCache* compressed_certs_cache_;
- // This helper is needed when create QuicCryptoServerStream.
- QboneCryptoServerStreamHelper stream_helper_;
- // Passed to the control stream.
- QboneServerControlStream::Handler* handler_;
- // The unowned control stream.
- QboneServerControlStream* control_stream_ = nullptr;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_QBONE_QBONE_SERVER_SESSION_H_
diff --git a/chromium/net/third_party/quiche/src/quic/qbone/qbone_session_base.cc b/chromium/net/third_party/quiche/src/quic/qbone/qbone_session_base.cc
deleted file mode 100644
index 702f185e2e2..00000000000
--- a/chromium/net/third_party/quiche/src/quic/qbone/qbone_session_base.cc
+++ /dev/null
@@ -1,216 +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 "quic/qbone/qbone_session_base.h"
-
-#include <netinet/icmp6.h>
-#include <netinet/ip6.h>
-
-#include <utility>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_buffer_allocator.h"
-#include "quic/core/quic_data_reader.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_exported_stats.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/platform/api/quic_testvalue.h"
-#include "quic/qbone/platform/icmp_packet.h"
-#include "quic/qbone/qbone_constants.h"
-#include "common/platform/api/quiche_command_line_flags.h"
-
-DEFINE_QUICHE_COMMAND_LINE_FLAG(
- bool, qbone_close_ephemeral_frames, true,
- "If true, we'll call CloseStream even when we receive ephemeral frames.");
-
-namespace quic {
-
-#define ENDPOINT \
- (perspective() == Perspective::IS_SERVER ? "Server: " : "Client: ")
-
-QboneSessionBase::QboneSessionBase(
- QuicConnection* connection,
- Visitor* owner,
- const QuicConfig& config,
- const ParsedQuicVersionVector& supported_versions,
- QbonePacketWriter* writer)
- : QuicSession(connection,
- owner,
- config,
- supported_versions,
- /*num_expected_unidirectional_static_streams = */ 0) {
- set_writer(writer);
- const uint32_t max_streams =
- (std::numeric_limits<uint32_t>::max() / kMaxAvailableStreamsMultiplier) -
- 1;
- this->config()->SetMaxBidirectionalStreamsToSend(max_streams);
- if (VersionHasIetfQuicFrames(transport_version())) {
- this->config()->SetMaxUnidirectionalStreamsToSend(max_streams);
- }
-}
-
-QboneSessionBase::~QboneSessionBase() {}
-
-void QboneSessionBase::Initialize() {
- crypto_stream_ = CreateCryptoStream();
- QuicSession::Initialize();
-}
-
-const QuicCryptoStream* QboneSessionBase::GetCryptoStream() const {
- return crypto_stream_.get();
-}
-
-QuicCryptoStream* QboneSessionBase::GetMutableCryptoStream() {
- return crypto_stream_.get();
-}
-
-QuicStream* QboneSessionBase::CreateOutgoingStream() {
- return ActivateDataStream(
- CreateDataStream(GetNextOutgoingUnidirectionalStreamId()));
-}
-
-void QboneSessionBase::OnStreamFrame(const QuicStreamFrame& frame) {
- if (frame.offset == 0 && frame.fin && frame.data_length > 0) {
- ++num_ephemeral_packets_;
- ProcessPacketFromPeer(
- absl::string_view(frame.data_buffer, frame.data_length));
- flow_controller()->AddBytesConsumed(frame.data_length);
- // TODO(b/147817422): Add a counter for how many streams were actually
- // closed here.
- if (GetQuicFlag(FLAGS_qbone_close_ephemeral_frames)) {
- ResetStream(frame.stream_id, QUIC_STREAM_CANCELLED);
- }
- return;
- }
- QuicSession::OnStreamFrame(frame);
-}
-
-void QboneSessionBase::OnMessageReceived(absl::string_view message) {
- ++num_message_packets_;
- ProcessPacketFromPeer(message);
-}
-
-QuicStream* QboneSessionBase::CreateIncomingStream(QuicStreamId id) {
- return ActivateDataStream(CreateDataStream(id));
-}
-
-QuicStream* QboneSessionBase::CreateIncomingStream(PendingStream* /*pending*/) {
- QUIC_NOTREACHED();
- return nullptr;
-}
-
-bool QboneSessionBase::ShouldKeepConnectionAlive() const {
- // QBONE connections stay alive until they're explicitly closed.
- return true;
-}
-
-std::unique_ptr<QuicStream> QboneSessionBase::CreateDataStream(
- QuicStreamId id) {
- if (!IsEncryptionEstablished()) {
- // Encryption not active so no stream created
- return nullptr;
- }
-
- if (IsIncomingStream(id)) {
- ++num_streamed_packets_;
- return std::make_unique<QboneReadOnlyStream>(id, this);
- }
-
- return std::make_unique<QboneWriteOnlyStream>(id, this);
-}
-
-QuicStream* QboneSessionBase::ActivateDataStream(
- std::unique_ptr<QuicStream> stream) {
- // Transfer ownership of the data stream to the session via ActivateStream().
- QuicStream* raw = stream.get();
- if (stream) {
- // Make QuicSession take ownership of the stream.
- ActivateStream(std::move(stream));
- }
- return raw;
-}
-
-void QboneSessionBase::SendPacketToPeer(absl::string_view packet) {
- if (crypto_stream_ == nullptr) {
- QUIC_BUG(quic_bug_10987_1)
- << "Attempting to send packet before encryption established";
- return;
- }
-
- if (send_packets_as_messages_) {
- QuicMemSlice slice(QuicBuffer::Copy(
- connection()->helper()->GetStreamSendBufferAllocator(), packet));
- switch (SendMessage(absl::MakeSpan(&slice, 1), /*flush=*/true).status) {
- case MESSAGE_STATUS_SUCCESS:
- break;
- case MESSAGE_STATUS_TOO_LARGE: {
- if (packet.size() < sizeof(ip6_hdr)) {
- QUIC_BUG(quic_bug_10987_2)
- << "Dropped malformed packet: IPv6 header too short";
- break;
- }
- auto* header = reinterpret_cast<const ip6_hdr*>(packet.begin());
- icmp6_hdr icmp_header{};
- icmp_header.icmp6_type = ICMP6_PACKET_TOO_BIG;
- icmp_header.icmp6_mtu =
- connection()->GetGuaranteedLargestMessagePayload();
-
- CreateIcmpPacket(header->ip6_dst, header->ip6_src, icmp_header, packet,
- [this](absl::string_view icmp_packet) {
- writer_->WritePacketToNetwork(icmp_packet.data(),
- icmp_packet.size());
- });
- break;
- }
- case MESSAGE_STATUS_ENCRYPTION_NOT_ESTABLISHED:
- QUIC_BUG(quic_bug_10987_3)
- << "MESSAGE_STATUS_ENCRYPTION_NOT_ESTABLISHED";
- break;
- case MESSAGE_STATUS_UNSUPPORTED:
- QUIC_BUG(quic_bug_10987_4) << "MESSAGE_STATUS_UNSUPPORTED";
- break;
- case MESSAGE_STATUS_BLOCKED:
- QUIC_BUG(quic_bug_10987_5) << "MESSAGE_STATUS_BLOCKED";
- break;
- case MESSAGE_STATUS_INTERNAL_ERROR:
- QUIC_BUG(quic_bug_10987_6) << "MESSAGE_STATUS_INTERNAL_ERROR";
- break;
- }
- return;
- }
-
- // QBONE streams are ephemeral.
- QuicStream* stream = CreateOutgoingStream();
- if (!stream) {
- QUIC_BUG(quic_bug_10987_7) << "Failed to create an outgoing QBONE stream.";
- return;
- }
-
- QboneWriteOnlyStream* qbone_stream =
- static_cast<QboneWriteOnlyStream*>(stream);
- qbone_stream->WritePacketToQuicStream(packet);
-}
-
-uint64_t QboneSessionBase::GetNumEphemeralPackets() const {
- return num_ephemeral_packets_;
-}
-
-uint64_t QboneSessionBase::GetNumStreamedPackets() const {
- return num_streamed_packets_;
-}
-
-uint64_t QboneSessionBase::GetNumMessagePackets() const {
- return num_message_packets_;
-}
-
-uint64_t QboneSessionBase::GetNumFallbackToStream() const {
- return num_fallback_to_stream_;
-}
-
-void QboneSessionBase::set_writer(QbonePacketWriter* writer) {
- writer_ = writer;
- quic::AdjustTestValue("quic_QbonePacketWriter", &writer_);
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/qbone/qbone_session_base.h b/chromium/net/third_party/quiche/src/quic/qbone/qbone_session_base.h
deleted file mode 100644
index 6d2c1b213ac..00000000000
--- a/chromium/net/third_party/quiche/src/quic/qbone/qbone_session_base.h
+++ /dev/null
@@ -1,114 +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_QBONE_QBONE_SESSION_BASE_H_
-#define QUICHE_QUIC_QBONE_QBONE_SESSION_BASE_H_
-
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_crypto_server_stream_base.h"
-#include "quic/core/quic_crypto_stream.h"
-#include "quic/core/quic_error_codes.h"
-#include "quic/core/quic_session.h"
-#include "quic/platform/api/quic_containers.h"
-#include "quic/platform/api/quic_export.h"
-#include "quic/qbone/qbone_packet_writer.h"
-#include "quic/qbone/qbone_stream.h"
-
-namespace quic {
-
-class QUIC_EXPORT_PRIVATE QboneSessionBase : public QuicSession {
- public:
- QboneSessionBase(QuicConnection* connection,
- Visitor* owner,
- const QuicConfig& config,
- const ParsedQuicVersionVector& supported_versions,
- QbonePacketWriter* writer);
- QboneSessionBase(const QboneSessionBase&) = delete;
- QboneSessionBase& operator=(const QboneSessionBase&) = delete;
- ~QboneSessionBase() override;
-
- // Overrides from QuicSession.
- // This will ensure that the crypto session is created.
- void Initialize() override;
- // This will check if the packet is wholly contained.
- void OnStreamFrame(const QuicStreamFrame& frame) override;
- // Called whenever a MESSAGE frame is received.
- void OnMessageReceived(absl::string_view message) override;
-
- virtual void ProcessPacketFromNetwork(absl::string_view packet) = 0;
- virtual void ProcessPacketFromPeer(absl::string_view packet) = 0;
-
- // Returns the number of QBONE network packets that were received
- // that fit into a single QuicStreamFrame and elided the creation of
- // a QboneReadOnlyStream.
- uint64_t GetNumEphemeralPackets() const;
-
- // Returns the number of QBONE network packets that were via
- // multiple packets, requiring the creation of a QboneReadOnlyStream.
- uint64_t GetNumStreamedPackets() const;
-
- // Returns the number of QBONE network packets that were received using QUIC
- // MESSAGE frame.
- uint64_t GetNumMessagePackets() const;
-
- // Returns the number of times sending a MESSAGE frame failed, and the session
- // used an ephemeral stream instead.
- uint64_t GetNumFallbackToStream() const;
-
- void set_writer(QbonePacketWriter* writer);
- void set_send_packets_as_messages(bool send_packets_as_messages) {
- send_packets_as_messages_ = send_packets_as_messages;
- }
-
- protected:
- virtual std::unique_ptr<QuicCryptoStream> CreateCryptoStream() = 0;
-
- // QuicSession interface implementation.
- QuicCryptoStream* GetMutableCryptoStream() override;
- const QuicCryptoStream* GetCryptoStream() const override;
- QuicStream* CreateIncomingStream(QuicStreamId id) override;
- QuicStream* CreateIncomingStream(PendingStream* pending) override;
- bool ShouldKeepConnectionAlive() const override;
-
- bool MaybeIncreaseLargestPeerStreamId(const QuicStreamId stream_id) override {
- return true;
- }
-
- QuicStream* CreateOutgoingStream();
- std::unique_ptr<QuicStream> CreateDataStream(QuicStreamId id);
- // Activates a QuicStream. The session takes ownership of the stream, but
- // returns an unowned pointer to the stream for convenience.
- QuicStream* ActivateDataStream(std::unique_ptr<QuicStream> stream);
-
- // Accepts a given packet from the network and writes it out
- // to the QUIC stream. This will create an ephemeral stream per
- // packet. This function will return true if a stream was created
- // and the packet sent. It will return false if the stream could not
- // be created.
- void SendPacketToPeer(absl::string_view packet);
-
- 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;
-
- private:
- // Used for the crypto handshake.
- std::unique_ptr<QuicCryptoStream> crypto_stream_;
-
- // Statistics for the packets received by the session.
- uint64_t num_ephemeral_packets_ = 0;
- uint64_t num_message_packets_ = 0;
- uint64_t num_streamed_packets_ = 0;
-
- // Number of times the connection has failed to send packets as MESSAGE frame
- // and used streams as a fallback.
- uint64_t num_fallback_to_stream_ = 0;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_QBONE_QBONE_SESSION_BASE_H_
diff --git a/chromium/net/third_party/quiche/src/quic/qbone/qbone_session_test.cc b/chromium/net/third_party/quiche/src/quic/qbone/qbone_session_test.cc
deleted file mode 100644
index c3ae3be1fd1..00000000000
--- a/chromium/net/third_party/quiche/src/quic/qbone/qbone_session_test.cc
+++ /dev/null
@@ -1,643 +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 <utility>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/proto/crypto_server_config_proto.h"
-#include "quic/core/quic_alarm_factory.h"
-#include "quic/core/quic_epoll_alarm_factory.h"
-#include "quic/platform/api/quic_expect_bug.h"
-#include "quic/platform/api/quic_port_utils.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/platform/api/quic_test_loopback.h"
-#include "quic/qbone/platform/icmp_packet.h"
-#include "quic/qbone/qbone_client_session.h"
-#include "quic/qbone/qbone_constants.h"
-#include "quic/qbone/qbone_control_placeholder.pb.h"
-#include "quic/qbone/qbone_packet_processor_test_tools.h"
-#include "quic/qbone/qbone_server_session.h"
-#include "quic/test_tools/crypto_test_utils.h"
-#include "quic/test_tools/mock_clock.h"
-#include "quic/test_tools/quic_connection_peer.h"
-#include "quic/test_tools/quic_session_peer.h"
-#include "quic/test_tools/quic_test_utils.h"
-
-namespace quic {
-namespace test {
-namespace {
-
-using ::testing::_;
-using ::testing::Contains;
-using ::testing::ElementsAre;
-using ::testing::Eq;
-using ::testing::Invoke;
-using ::testing::NiceMock;
-using ::testing::Not;
-
-std::string TestPacketIn(const std::string& body) {
- return PrependIPv6HeaderForTest(body, 5);
-}
-
-std::string TestPacketOut(const std::string& body) {
- return PrependIPv6HeaderForTest(body, 4);
-}
-
-ParsedQuicVersionVector GetTestParams() {
- ParsedQuicVersionVector test_versions;
-
- // TODO(b/113130636): Make QBONE work with TLS.
- for (const auto& version : CurrentSupportedVersionsWithQuicCrypto()) {
- // QBONE requires MESSAGE frames
- if (!version.SupportsMessageFrames()) {
- continue;
- }
- test_versions.push_back(version);
- }
-
- return test_versions;
-}
-
-// Used by QuicCryptoServerConfig to provide server credentials, passes
-// everything through to ProofSourceForTesting if success is true,
-// and fails otherwise.
-class IndirectionProofSource : public ProofSource {
- public:
- explicit IndirectionProofSource(bool success) {
- if (success) {
- proof_source_ = crypto_test_utils::ProofSourceForTesting();
- }
- }
-
- // ProofSource override.
- void GetProof(const QuicSocketAddress& server_address,
- const QuicSocketAddress& client_address,
- const std::string& hostname,
- const std::string& server_config,
- QuicTransportVersion transport_version,
- absl::string_view chlo_hash,
- std::unique_ptr<Callback> callback) override {
- if (!proof_source_) {
- QuicCryptoProof proof;
- QuicReferenceCountedPointer<ProofSource::Chain> chain = GetCertChain(
- server_address, client_address, hostname, &proof.cert_matched_sni);
- callback->Run(/*ok=*/false, chain, proof, /*details=*/nullptr);
- return;
- }
- proof_source_->GetProof(server_address, client_address, hostname,
- server_config, transport_version, chlo_hash,
- std::move(callback));
- }
-
- QuicReferenceCountedPointer<Chain> GetCertChain(
- const QuicSocketAddress& server_address,
- const QuicSocketAddress& client_address, const std::string& hostname,
- bool* cert_matched_sni) override {
- if (!proof_source_) {
- return QuicReferenceCountedPointer<Chain>();
- }
- return proof_source_->GetCertChain(server_address, client_address, hostname,
- cert_matched_sni);
- }
-
- void ComputeTlsSignature(
- const QuicSocketAddress& server_address,
- const QuicSocketAddress& client_address,
- const std::string& hostname,
- uint16_t signature_algorithm,
- absl::string_view in,
- std::unique_ptr<SignatureCallback> callback) override {
- if (!proof_source_) {
- callback->Run(/*ok=*/true, "Signature", /*details=*/nullptr);
- return;
- }
- proof_source_->ComputeTlsSignature(server_address, client_address, hostname,
- signature_algorithm, in,
- std::move(callback));
- }
-
- absl::InlinedVector<uint16_t, 8> SupportedTlsSignatureAlgorithms()
- const override {
- if (!proof_source_) {
- return {};
- }
- return proof_source_->SupportedTlsSignatureAlgorithms();
- }
-
- TicketCrypter* GetTicketCrypter() override { return nullptr; }
-
- private:
- std::unique_ptr<ProofSource> proof_source_;
-};
-
-// Used by QuicCryptoClientConfig to verify server credentials, passes
-// everything through to ProofVerifierForTesting is success is true,
-// otherwise returns a canned response of QUIC_FAILURE.
-class IndirectionProofVerifier : public ProofVerifier {
- public:
- explicit IndirectionProofVerifier(bool success) {
- if (success) {
- proof_verifier_ = crypto_test_utils::ProofVerifierForTesting();
- }
- }
-
- // ProofVerifier override
- 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>* verify_details,
- std::unique_ptr<ProofVerifierCallback> callback) override {
- if (!proof_verifier_) {
- return QUIC_FAILURE;
- }
- return proof_verifier_->VerifyProof(
- hostname, port, server_config, transport_version, chlo_hash, certs,
- cert_sct, signature, context, error_details, verify_details,
- 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 {
- if (!proof_verifier_) {
- return QUIC_FAILURE;
- }
- return proof_verifier_->VerifyCertChain(
- hostname, port, certs, ocsp_response, cert_sct, context, error_details,
- details, out_alert, std::move(callback));
- }
-
- std::unique_ptr<ProofVerifyContext> CreateDefaultContext() override {
- if (!proof_verifier_) {
- return nullptr;
- }
- return proof_verifier_->CreateDefaultContext();
- }
-
- private:
- std::unique_ptr<ProofVerifier> proof_verifier_;
-};
-
-class DataSavingQbonePacketWriter : public QbonePacketWriter {
- public:
- void WritePacketToNetwork(const char* packet, size_t size) override {
- data_.push_back(std::string(packet, size));
- }
-
- const std::vector<std::string>& data() { return data_; }
-
- private:
- std::vector<std::string> data_;
-};
-
-template <class T>
-class DataSavingQboneControlHandler : public QboneControlHandler<T> {
- public:
- void OnControlRequest(const T& request) override { data_.push_back(request); }
-
- void OnControlError() override { error_ = true; }
-
- const std::vector<T>& data() { return data_; }
- bool error() { return error_; }
-
- private:
- std::vector<T> data_;
- bool error_ = false;
-};
-
-// Single-threaded scheduled task runner based on a MockClock.
-//
-// Simulates asynchronous execution on a single thread by holding scheduled
-// tasks until Run() is called. Performs no synchronization, assumes that
-// Schedule() and Run() are called on the same thread.
-class FakeTaskRunner {
- public:
- explicit FakeTaskRunner(MockQuicConnectionHelper* helper)
- : tasks_([](const TaskType& l, const TaskType& r) {
- // Items at a later time should run after items at an earlier time.
- // Priority queue comparisons should return true if l appears after r.
- return l->time() > r->time();
- }),
- helper_(helper) {}
-
- // Runs all tasks in time order. Executes tasks scheduled at
- // the same in an arbitrary order.
- void Run() {
- while (!tasks_.empty()) {
- tasks_.top()->Run();
- tasks_.pop();
- }
- }
-
- private:
- class InnerTask {
- public:
- InnerTask(std::function<void()> task, QuicTime time)
- : task_(std::move(task)), time_(time) {}
-
- void Cancel() { cancelled_ = true; }
-
- void Run() {
- if (!cancelled_) {
- task_();
- }
- }
-
- QuicTime time() const { return time_; }
-
- private:
- bool cancelled_ = false;
- std::function<void()> task_;
- QuicTime time_;
- };
-
- public:
- // Schedules a function to run immediately and advances the time.
- void Schedule(std::function<void()> task) {
- tasks_.push(std::shared_ptr<InnerTask>(
- new InnerTask(std::move(task), helper_->GetClock()->Now())));
- helper_->AdvanceTime(QuicTime::Delta::FromMilliseconds(1));
- }
-
- private:
- using TaskType = std::shared_ptr<InnerTask>;
- std::priority_queue<TaskType,
- std::vector<TaskType>,
- std::function<bool(const TaskType&, const TaskType&)>>
- tasks_;
- MockQuicConnectionHelper* helper_;
-};
-
-class QboneSessionTest : public QuicTestWithParam<ParsedQuicVersion> {
- public:
- QboneSessionTest()
- : supported_versions_({GetParam()}),
- runner_(&helper_),
- compressed_certs_cache_(100) {}
-
- ~QboneSessionTest() override {
- delete client_connection_;
- delete server_connection_;
- }
-
- const MockClock* GetClock() const {
- return static_cast<const MockClock*>(helper_.GetClock());
- }
-
- // The parameters are used to control whether the handshake will success or
- // not.
- void CreateClientAndServerSessions(bool client_handshake_success = true,
- bool server_handshake_success = true,
- bool send_qbone_alpn = true) {
- // Quic crashes if packets are sent at time 0, and the clock defaults to 0.
- helper_.AdvanceTime(QuicTime::Delta::FromMilliseconds(1000));
- alarm_factory_ = std::make_unique<QuicEpollAlarmFactory>(&epoll_server_);
- client_writer_ = std::make_unique<DataSavingQbonePacketWriter>();
- server_writer_ = std::make_unique<DataSavingQbonePacketWriter>();
- client_handler_ =
- std::make_unique<DataSavingQboneControlHandler<QboneClientRequest>>();
- server_handler_ =
- std::make_unique<DataSavingQboneControlHandler<QboneServerRequest>>();
- QuicSocketAddress server_address(TestLoopback(),
- QuicPickServerPortForTestsOrDie());
- QuicSocketAddress client_address;
- if (server_address.host().address_family() == IpAddressFamily::IP_V4) {
- client_address = QuicSocketAddress(QuicIpAddress::Any4(), 0);
- } else {
- client_address = QuicSocketAddress(QuicIpAddress::Any6(), 0);
- }
-
- {
- client_connection_ = new QuicConnection(
- TestConnectionId(), client_address, server_address, &helper_,
- alarm_factory_.get(), new NiceMock<MockPacketWriter>(), true,
- Perspective::IS_CLIENT, supported_versions_);
- client_connection_->SetSelfAddress(client_address);
- QuicConfig config;
- client_crypto_config_ = std::make_unique<QuicCryptoClientConfig>(
- std::make_unique<IndirectionProofVerifier>(client_handshake_success));
- if (send_qbone_alpn) {
- client_crypto_config_->set_alpn("qbone");
- }
- client_peer_ = std::make_unique<QboneClientSession>(
- client_connection_, client_crypto_config_.get(),
- /*owner=*/nullptr, config, supported_versions_,
- QuicServerId("test.example.com", 1234, false), client_writer_.get(),
- client_handler_.get());
- }
-
- {
- server_connection_ = new QuicConnection(
- TestConnectionId(), server_address, client_address, &helper_,
- alarm_factory_.get(), new NiceMock<MockPacketWriter>(), true,
- Perspective::IS_SERVER, supported_versions_);
- server_connection_->SetSelfAddress(server_address);
- QuicConfig config;
- server_crypto_config_ = std::make_unique<QuicCryptoServerConfig>(
- QuicCryptoServerConfig::TESTING, QuicRandom::GetInstance(),
- std::make_unique<IndirectionProofSource>(server_handshake_success),
- KeyExchangeSource::Default());
- QuicCryptoServerConfig::ConfigOptions options;
- QuicServerConfigProtobuf primary_config =
- server_crypto_config_->GenerateConfig(QuicRandom::GetInstance(),
- GetClock(), options);
- std::unique_ptr<CryptoHandshakeMessage> message(
- server_crypto_config_->AddConfig(primary_config,
- GetClock()->WallNow()));
-
- server_peer_ = std::make_unique<QboneServerSession>(
- supported_versions_, server_connection_, nullptr, config,
- server_crypto_config_.get(), &compressed_certs_cache_,
- server_writer_.get(), TestLoopback6(), TestLoopback6(), 64,
- server_handler_.get());
- }
-
- // Hook everything up!
- MockPacketWriter* client_writer = static_cast<MockPacketWriter*>(
- QuicConnectionPeer::GetWriter(client_peer_->connection()));
- ON_CALL(*client_writer, WritePacket(_, _, _, _, _))
- .WillByDefault(Invoke([this](const char* buffer, size_t buf_len,
- const QuicIpAddress& self_address,
- const QuicSocketAddress& peer_address,
- PerPacketOptions* options) {
- char* copy = new char[1024 * 1024];
- memcpy(copy, buffer, buf_len);
- runner_.Schedule([this, copy, buf_len] {
- QuicReceivedPacket packet(copy, buf_len, GetClock()->Now());
- server_peer_->ProcessUdpPacket(server_connection_->self_address(),
- client_connection_->self_address(),
- packet);
- delete[] copy;
- });
- return WriteResult(WRITE_STATUS_OK, buf_len);
- }));
- MockPacketWriter* server_writer = static_cast<MockPacketWriter*>(
- QuicConnectionPeer::GetWriter(server_peer_->connection()));
- ON_CALL(*server_writer, WritePacket(_, _, _, _, _))
- .WillByDefault(Invoke([this](const char* buffer, size_t buf_len,
- const QuicIpAddress& self_address,
- const QuicSocketAddress& peer_address,
- PerPacketOptions* options) {
- char* copy = new char[1024 * 1024];
- memcpy(copy, buffer, buf_len);
- runner_.Schedule([this, copy, buf_len] {
- QuicReceivedPacket packet(copy, buf_len, GetClock()->Now());
- client_peer_->ProcessUdpPacket(client_connection_->self_address(),
- server_connection_->self_address(),
- packet);
- delete[] copy;
- });
- return WriteResult(WRITE_STATUS_OK, buf_len);
- }));
- }
-
- void StartHandshake() {
- server_peer_->Initialize();
- client_peer_->Initialize();
- runner_.Run();
- }
-
- void ExpectICMPTooBigResponse(const std::vector<std::string>& written_packets,
- const int mtu,
- const std::string& packet) {
- auto* header = reinterpret_cast<const ip6_hdr*>(packet.data());
- icmp6_hdr icmp_header{};
- icmp_header.icmp6_type = ICMP6_PACKET_TOO_BIG;
- icmp_header.icmp6_mtu = mtu;
-
- std::string expected;
- CreateIcmpPacket(header->ip6_dst, header->ip6_src, icmp_header, packet,
- [&expected](absl::string_view icmp_packet) {
- expected = std::string(icmp_packet);
- });
-
- EXPECT_THAT(written_packets, Contains(expected));
- }
-
- // Test handshake establishment and sending/receiving of data for two
- // directions.
- void TestStreamConnection(bool use_messages) {
- ASSERT_TRUE(server_peer_->OneRttKeysAvailable());
- ASSERT_TRUE(client_peer_->OneRttKeysAvailable());
- ASSERT_TRUE(server_peer_->IsEncryptionEstablished());
- ASSERT_TRUE(client_peer_->IsEncryptionEstablished());
-
- // Create an outgoing stream from the client and say hello.
- QUIC_LOG(INFO) << "Sending client -> server";
- client_peer_->ProcessPacketFromNetwork(TestPacketIn("hello"));
- client_peer_->ProcessPacketFromNetwork(TestPacketIn("world"));
- runner_.Run();
- // The server should see the data, the client hasn't received
- // anything yet.
- EXPECT_THAT(server_writer_->data(),
- ElementsAre(TestPacketOut("hello"), TestPacketOut("world")));
- EXPECT_TRUE(client_writer_->data().empty());
- EXPECT_EQ(0u, server_peer_->GetNumActiveStreams());
- EXPECT_EQ(0u, client_peer_->GetNumActiveStreams());
-
- // Let's pretend some service responds.
- QUIC_LOG(INFO) << "Sending server -> client";
- server_peer_->ProcessPacketFromNetwork(TestPacketIn("Hello Again"));
- server_peer_->ProcessPacketFromNetwork(TestPacketIn("Again"));
- runner_.Run();
- EXPECT_THAT(server_writer_->data(),
- ElementsAre(TestPacketOut("hello"), TestPacketOut("world")));
- EXPECT_THAT(
- client_writer_->data(),
- ElementsAre(TestPacketOut("Hello Again"), TestPacketOut("Again")));
- EXPECT_EQ(0u, server_peer_->GetNumActiveStreams());
- EXPECT_EQ(0u, client_peer_->GetNumActiveStreams());
-
- // Try to send long payloads that are larger than the QUIC MTU but
- // smaller than the QBONE max size.
- // This should trigger the non-ephemeral stream code path.
- std::string long_data(
- QboneConstants::kMaxQbonePacketBytes - sizeof(ip6_hdr) - 1, 'A');
- QUIC_LOG(INFO) << "Sending server -> client long data";
- server_peer_->ProcessPacketFromNetwork(TestPacketIn(long_data));
- runner_.Run();
- if (use_messages) {
- ExpectICMPTooBigResponse(
- server_writer_->data(),
- server_peer_->connection()->GetGuaranteedLargestMessagePayload(),
- TestPacketOut(long_data));
- } else {
- EXPECT_THAT(client_writer_->data(), Contains(TestPacketOut(long_data)));
- }
- EXPECT_THAT(server_writer_->data(),
- Not(Contains(TestPacketOut(long_data))));
- EXPECT_EQ(0u, server_peer_->GetNumActiveStreams());
- EXPECT_EQ(0u, client_peer_->GetNumActiveStreams());
-
- QUIC_LOG(INFO) << "Sending client -> server long data";
- client_peer_->ProcessPacketFromNetwork(TestPacketIn(long_data));
- runner_.Run();
- if (use_messages) {
- ExpectICMPTooBigResponse(
- client_writer_->data(),
- client_peer_->connection()->GetGuaranteedLargestMessagePayload(),
- TestPacketIn(long_data));
- } else {
- EXPECT_THAT(server_writer_->data(), Contains(TestPacketOut(long_data)));
- }
- EXPECT_FALSE(client_peer_->EarlyDataAccepted());
- EXPECT_FALSE(client_peer_->ReceivedInchoateReject());
- EXPECT_THAT(client_peer_->GetNumReceivedServerConfigUpdates(), Eq(0));
-
- if (!use_messages) {
- EXPECT_THAT(client_peer_->GetNumStreamedPackets(), Eq(1));
- EXPECT_THAT(server_peer_->GetNumStreamedPackets(), Eq(1));
- }
-
- if (use_messages) {
- EXPECT_THAT(client_peer_->GetNumEphemeralPackets(), Eq(0));
- EXPECT_THAT(server_peer_->GetNumEphemeralPackets(), Eq(0));
- EXPECT_THAT(client_peer_->GetNumMessagePackets(), Eq(2));
- EXPECT_THAT(server_peer_->GetNumMessagePackets(), Eq(2));
- } else {
- EXPECT_THAT(client_peer_->GetNumEphemeralPackets(), Eq(2));
- EXPECT_THAT(server_peer_->GetNumEphemeralPackets(), Eq(2));
- EXPECT_THAT(client_peer_->GetNumMessagePackets(), Eq(0));
- EXPECT_THAT(server_peer_->GetNumMessagePackets(), Eq(0));
- }
-
- // All streams are ephemeral and should be gone.
- EXPECT_EQ(0u, server_peer_->GetNumActiveStreams());
- EXPECT_EQ(0u, client_peer_->GetNumActiveStreams());
- }
-
- // Test that client and server are not connected after handshake failure.
- void TestDisconnectAfterFailedHandshake() {
- EXPECT_FALSE(client_peer_->IsEncryptionEstablished());
- EXPECT_FALSE(client_peer_->OneRttKeysAvailable());
-
- EXPECT_FALSE(server_peer_->IsEncryptionEstablished());
- EXPECT_FALSE(server_peer_->OneRttKeysAvailable());
- }
-
- protected:
- const ParsedQuicVersionVector supported_versions_;
- QuicEpollServer epoll_server_;
- std::unique_ptr<QuicAlarmFactory> alarm_factory_;
- FakeTaskRunner runner_;
- MockQuicConnectionHelper helper_;
- QuicConnection* client_connection_;
- QuicConnection* server_connection_;
- QuicCompressedCertsCache compressed_certs_cache_;
-
- std::unique_ptr<QuicCryptoClientConfig> client_crypto_config_;
- std::unique_ptr<QuicCryptoServerConfig> server_crypto_config_;
- std::unique_ptr<DataSavingQbonePacketWriter> client_writer_;
- std::unique_ptr<DataSavingQbonePacketWriter> server_writer_;
- std::unique_ptr<DataSavingQboneControlHandler<QboneClientRequest>>
- client_handler_;
- std::unique_ptr<DataSavingQboneControlHandler<QboneServerRequest>>
- server_handler_;
-
- std::unique_ptr<QboneServerSession> server_peer_;
- std::unique_ptr<QboneClientSession> client_peer_;
-};
-
-INSTANTIATE_TEST_SUITE_P(Tests,
- QboneSessionTest,
- ::testing::ValuesIn(GetTestParams()),
- ::testing::PrintToStringParamName());
-
-TEST_P(QboneSessionTest, StreamConnection) {
- CreateClientAndServerSessions();
- client_peer_->set_send_packets_as_messages(false);
- server_peer_->set_send_packets_as_messages(false);
- StartHandshake();
- TestStreamConnection(false);
-}
-
-TEST_P(QboneSessionTest, Messages) {
- CreateClientAndServerSessions();
- client_peer_->set_send_packets_as_messages(true);
- server_peer_->set_send_packets_as_messages(true);
- StartHandshake();
- TestStreamConnection(true);
-}
-
-TEST_P(QboneSessionTest, ClientRejection) {
- CreateClientAndServerSessions(false /*client_handshake_success*/,
- true /*server_handshake_success*/,
- true /*send_qbone_alpn*/);
- StartHandshake();
- TestDisconnectAfterFailedHandshake();
-}
-
-TEST_P(QboneSessionTest, BadAlpn) {
- CreateClientAndServerSessions(true /*client_handshake_success*/,
- true /*server_handshake_success*/,
- false /*send_qbone_alpn*/);
- StartHandshake();
- TestDisconnectAfterFailedHandshake();
-}
-
-TEST_P(QboneSessionTest, ServerRejection) {
- CreateClientAndServerSessions(true /*client_handshake_success*/,
- false /*server_handshake_success*/,
- true /*send_qbone_alpn*/);
- StartHandshake();
- TestDisconnectAfterFailedHandshake();
-}
-
-// Test that data streams are not created before handshake.
-TEST_P(QboneSessionTest, CannotCreateDataStreamBeforeHandshake) {
- CreateClientAndServerSessions();
- EXPECT_QUIC_BUG(client_peer_->ProcessPacketFromNetwork(TestPacketIn("hello")),
- "Attempting to send packet before encryption established");
- EXPECT_QUIC_BUG(server_peer_->ProcessPacketFromNetwork(TestPacketIn("hello")),
- "Attempting to send packet before encryption established");
- EXPECT_EQ(0u, server_peer_->GetNumActiveStreams());
- EXPECT_EQ(0u, client_peer_->GetNumActiveStreams());
-}
-
-TEST_P(QboneSessionTest, ControlRequests) {
- CreateClientAndServerSessions();
- StartHandshake();
- EXPECT_TRUE(client_handler_->data().empty());
- EXPECT_FALSE(client_handler_->error());
- EXPECT_TRUE(server_handler_->data().empty());
- EXPECT_FALSE(server_handler_->error());
-
- QboneClientRequest client_request;
- client_request.SetExtension(client_placeholder, "hello from the server");
- EXPECT_TRUE(server_peer_->SendClientRequest(client_request));
- runner_.Run();
- ASSERT_FALSE(client_handler_->data().empty());
- EXPECT_THAT(client_handler_->data()[0].GetExtension(client_placeholder),
- Eq("hello from the server"));
- EXPECT_FALSE(client_handler_->error());
-
- QboneServerRequest server_request;
- server_request.SetExtension(server_placeholder, "hello from the client");
- EXPECT_TRUE(client_peer_->SendServerRequest(server_request));
- runner_.Run();
- ASSERT_FALSE(server_handler_->data().empty());
- EXPECT_THAT(server_handler_->data()[0].GetExtension(server_placeholder),
- Eq("hello from the client"));
- EXPECT_FALSE(server_handler_->error());
-}
-
-} // namespace
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/qbone/qbone_stream.cc b/chromium/net/third_party/quiche/src/quic/qbone/qbone_stream.cc
deleted file mode 100644
index 39012336662..00000000000
--- a/chromium/net/third_party/quiche/src/quic/qbone/qbone_stream.cc
+++ /dev/null
@@ -1,64 +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 "quic/qbone/qbone_stream.h"
-
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_data_reader.h"
-#include "quic/core/quic_data_writer.h"
-#include "quic/core/quic_types.h"
-#include "quic/qbone/qbone_constants.h"
-#include "quic/qbone/qbone_session_base.h"
-#include "common/platform/api/quiche_command_line_flags.h"
-
-DEFINE_QUICHE_COMMAND_LINE_FLAG(int, qbone_stream_ttl_secs, 3,
- "The QBONE Stream TTL in seconds.");
-
-namespace quic {
-
-QboneWriteOnlyStream::QboneWriteOnlyStream(QuicStreamId id,
- QuicSession* session)
- : 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)));
-}
-
-void QboneWriteOnlyStream::WritePacketToQuicStream(absl::string_view packet) {
- // Streams are one way and ephemeral. This function should only be
- // called once.
- WriteOrBufferData(packet, /* fin= */ true, nullptr);
-}
-
-QboneReadOnlyStream::QboneReadOnlyStream(QuicStreamId id,
- QboneSessionBase* session)
- : QuicStream(id,
- session,
- /*is_static=*/false,
- READ_UNIDIRECTIONAL),
- 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)));
-}
-
-void QboneReadOnlyStream::OnDataAvailable() {
- // Read in data and buffer it, attempt to frame to see if there's a packet.
- sequencer()->Read(&buffer_);
- if (sequencer()->IsClosed()) {
- session_->ProcessPacketFromPeer(buffer_);
- OnFinRead();
- return;
- }
- if (buffer_.size() > QboneConstants::kMaxQbonePacketBytes) {
- if (!rst_sent()) {
- Reset(QUIC_BAD_APPLICATION_PAYLOAD);
- }
- StopReading();
- }
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/qbone/qbone_stream.h b/chromium/net/third_party/quiche/src/quic/qbone/qbone_stream.h
deleted file mode 100644
index e7ea045cf48..00000000000
--- a/chromium/net/third_party/quiche/src/quic/qbone/qbone_stream.h
+++ /dev/null
@@ -1,56 +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_QBONE_QBONE_STREAM_H_
-#define QUICHE_QUIC_QBONE_QBONE_STREAM_H_
-
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_session.h"
-#include "quic/core/quic_stream.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-class QboneSessionBase;
-
-// QboneWriteOnlyStream is responsible for sending data for a single
-// packet to the other side.
-// Note that the stream will be created HalfClosed (reads will be closed).
-class QUIC_EXPORT_PRIVATE QboneWriteOnlyStream : public QuicStream {
- public:
- QboneWriteOnlyStream(QuicStreamId id, QuicSession* session);
-
- // QuicStream implementation. QBONE writers are ephemeral and don't
- // read any data.
- void OnDataAvailable() override {}
-
- // Write a network packet over the quic stream.
- void WritePacketToQuicStream(absl::string_view packet);
-};
-
-// QboneReadOnlyStream will be used if we find an incoming stream that
-// isn't fully contained. It will buffer the data when available and
-// attempt to parse it as a packet to send to the network when a FIN
-// is found.
-// Note that the stream will be created HalfClosed (writes will be closed).
-class QUIC_EXPORT_PRIVATE QboneReadOnlyStream : public QuicStream {
- public:
- QboneReadOnlyStream(QuicStreamId id, QboneSessionBase* session);
-
- ~QboneReadOnlyStream() override = default;
-
- // QuicStream overrides.
- // OnDataAvailable is called when there is data in the quic stream buffer.
- // This will copy the buffer locally and attempt to parse it to write out
- // packets to the network.
- void OnDataAvailable() override;
-
- private:
- std::string buffer_;
- QboneSessionBase* session_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_QBONE_QBONE_STREAM_H_
diff --git a/chromium/net/third_party/quiche/src/quic/qbone/qbone_stream_test.cc b/chromium/net/third_party/quiche/src/quic/qbone/qbone_stream_test.cc
deleted file mode 100644
index 8e724a4195a..00000000000
--- a/chromium/net/third_party/quiche/src/quic/qbone/qbone_stream_test.cc
+++ /dev/null
@@ -1,255 +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 "quic/qbone/qbone_stream.h"
-
-#include <utility>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/crypto/quic_random.h"
-#include "quic/core/quic_session.h"
-#include "quic/core/quic_simple_buffer_allocator.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/platform/api/quic_test_loopback.h"
-#include "quic/qbone/qbone_constants.h"
-#include "quic/qbone/qbone_session_base.h"
-#include "quic/test_tools/mock_clock.h"
-#include "quic/test_tools/quic_test_utils.h"
-#include "spdy/core/spdy_protocol.h"
-
-namespace quic {
-
-namespace {
-
-using ::testing::_;
-using ::testing::StrictMock;
-
-// MockQuicSession that does not create streams and writes data from
-// QuicStream to a string.
-class MockQuicSession : public QboneSessionBase {
- public:
- MockQuicSession(QuicConnection* connection, const QuicConfig& config)
- : QboneSessionBase(connection, nullptr /*visitor*/, config,
- CurrentSupportedVersions(), nullptr /*writer*/) {}
-
- ~MockQuicSession() override {}
-
- // Writes outgoing data from QuicStream to a string.
- QuicConsumedData WritevData(QuicStreamId id, size_t write_length,
- QuicStreamOffset offset, StreamSendingState state,
- TransmissionType type,
- EncryptionLevel level) override {
- if (!writable_) {
- return QuicConsumedData(0, false);
- }
-
- return QuicConsumedData(write_length, state != StreamSendingState::NO_FIN);
- }
-
- QboneReadOnlyStream* CreateIncomingStream(QuicStreamId id) override {
- return nullptr;
- }
-
- // Called by QuicStream when they want to close stream.
- MOCK_METHOD(void, MaybeSendRstStreamFrame,
- (QuicStreamId stream_id, QuicResetStreamError error,
- QuicStreamOffset bytes_written),
- (override));
- MOCK_METHOD(void, MaybeSendStopSendingFrame,
- (QuicStreamId stream_id, QuicResetStreamError error), (override));
-
- // Sets whether data is written to buffer, or else if this is write blocked.
- void set_writable(bool writable) { writable_ = writable; }
-
- // Tracks whether the stream is write blocked and its priority.
- void RegisterReliableStream(QuicStreamId stream_id) {
- // The priority effectively does not matter. Put all streams on the same
- // priority.
- write_blocked_streams()->RegisterStream(
- stream_id,
- /*is_static_stream=*/false,
- /* precedence= */ spdy::SpdyStreamPrecedence(3));
- }
-
- // The session take ownership of the stream.
- void ActivateReliableStream(std::unique_ptr<QuicStream> stream) {
- ActivateStream(std::move(stream));
- }
-
- std::unique_ptr<QuicCryptoStream> CreateCryptoStream() override {
- return std::make_unique<test::MockQuicCryptoStream>(this);
- }
-
- MOCK_METHOD(void, ProcessPacketFromPeer, (absl::string_view), (override));
- MOCK_METHOD(void, ProcessPacketFromNetwork, (absl::string_view), (override));
-
- private:
- // Whether data is written to write_buffer_.
- bool writable_ = true;
-};
-
-// Packet writer that does nothing. This is required for QuicConnection but
-// isn't used for writing data.
-class DummyPacketWriter : public QuicPacketWriter {
- public:
- DummyPacketWriter() {}
-
- // QuicPacketWriter overrides.
- WriteResult WritePacket(const char* buffer, size_t buf_len,
- const QuicIpAddress& self_address,
- const QuicSocketAddress& peer_address,
- PerPacketOptions* options) override {
- return WriteResult(WRITE_STATUS_ERROR, 0);
- }
-
- bool IsWriteBlocked() const override { return false; };
-
- void SetWritable() override {}
-
- QuicByteCount GetMaxPacketSize(
- const QuicSocketAddress& peer_address) const override {
- return 0;
- }
-
- bool SupportsReleaseTime() const override { return false; }
-
- bool IsBatchMode() const override { return false; }
-
- QuicPacketBuffer GetNextWriteLocation(
- const QuicIpAddress& self_address,
- const QuicSocketAddress& peer_address) override {
- return {nullptr, nullptr};
- }
-
- WriteResult Flush() override { return WriteResult(WRITE_STATUS_OK, 0); }
-};
-
-class QboneReadOnlyStreamTest : public ::testing::Test,
- public QuicConnectionHelperInterface {
- public:
- void CreateReliableQuicStream() {
- // Arbitrary values for QuicConnection.
- Perspective perspective = Perspective::IS_SERVER;
- bool owns_writer = true;
-
- alarm_factory_ = std::make_unique<test::MockAlarmFactory>();
-
- connection_.reset(new QuicConnection(
- test::TestConnectionId(0), QuicSocketAddress(TestLoopback(), 0),
- QuicSocketAddress(TestLoopback(), 0),
- this /*QuicConnectionHelperInterface*/, alarm_factory_.get(),
- new DummyPacketWriter(), owns_writer, perspective,
- ParsedVersionOfIndex(CurrentSupportedVersions(), 0)));
- clock_.AdvanceTime(QuicTime::Delta::FromSeconds(1));
- session_ = std::make_unique<StrictMock<MockQuicSession>>(connection_.get(),
- QuicConfig());
- session_->Initialize();
- stream_ = new QboneReadOnlyStream(kStreamId, session_.get());
- session_->ActivateReliableStream(
- std::unique_ptr<QboneReadOnlyStream>(stream_));
- }
-
- ~QboneReadOnlyStreamTest() override {}
-
- const QuicClock* GetClock() const override { return &clock_; }
-
- QuicRandom* GetRandomGenerator() override {
- return QuicRandom::GetInstance();
- }
-
- QuicBufferAllocator* GetStreamSendBufferAllocator() override {
- return &buffer_allocator_;
- }
-
- protected:
- // The QuicSession will take the ownership.
- QboneReadOnlyStream* stream_;
- std::unique_ptr<StrictMock<MockQuicSession>> session_;
- std::unique_ptr<QuicAlarmFactory> alarm_factory_;
- std::unique_ptr<QuicConnection> connection_;
- // Used to implement the QuicConnectionHelperInterface.
- SimpleBufferAllocator buffer_allocator_;
- MockClock clock_;
- const QuicStreamId kStreamId = QuicUtils::GetFirstUnidirectionalStreamId(
- CurrentSupportedVersions()[0].transport_version, Perspective::IS_CLIENT);
-};
-
-// Read an entire string.
-TEST_F(QboneReadOnlyStreamTest, ReadDataWhole) {
- std::string packet = "Stuff";
- CreateReliableQuicStream();
- QuicStreamFrame frame(kStreamId, true, 0, packet);
- EXPECT_CALL(*session_, ProcessPacketFromPeer("Stuff"));
- stream_->OnStreamFrame(frame);
-}
-
-// Test buffering.
-TEST_F(QboneReadOnlyStreamTest, ReadBuffered) {
- CreateReliableQuicStream();
- std::string packet = "Stuf";
- {
- QuicStreamFrame frame(kStreamId, false, 0, packet);
- stream_->OnStreamFrame(frame);
- }
- // We didn't write 5 bytes yet...
-
- packet = "f";
- EXPECT_CALL(*session_, ProcessPacketFromPeer("Stuff"));
- {
- QuicStreamFrame frame(kStreamId, true, 4, packet);
- stream_->OnStreamFrame(frame);
- }
-}
-
-TEST_F(QboneReadOnlyStreamTest, ReadOutOfOrder) {
- CreateReliableQuicStream();
- std::string packet = "f";
- {
- QuicStreamFrame frame(kStreamId, true, 4, packet);
- stream_->OnStreamFrame(frame);
- }
-
- packet = "S";
- {
- QuicStreamFrame frame(kStreamId, false, 0, packet);
- stream_->OnStreamFrame(frame);
- }
-
- packet = "tuf";
- EXPECT_CALL(*session_, ProcessPacketFromPeer("Stuff"));
- {
- QuicStreamFrame frame(kStreamId, false, 1, packet);
- stream_->OnStreamFrame(frame);
- }
-}
-
-// Test buffering too many bytes.
-TEST_F(QboneReadOnlyStreamTest, ReadBufferedTooLarge) {
- CreateReliableQuicStream();
- std::string packet = "0123456789";
- int iterations = (QboneConstants::kMaxQbonePacketBytes / packet.size()) + 2;
- EXPECT_CALL(*session_, MaybeSendStopSendingFrame(
- kStreamId, QuicResetStreamError::FromInternal(
- QUIC_BAD_APPLICATION_PAYLOAD)));
- EXPECT_CALL(
- *session_,
- MaybeSendRstStreamFrame(
- kStreamId,
- QuicResetStreamError::FromInternal(QUIC_BAD_APPLICATION_PAYLOAD), _));
- for (int i = 0; i < iterations; ++i) {
- QuicStreamFrame frame(kStreamId, i == (iterations - 1), i * packet.size(),
- packet);
- if (!stream_->reading_stopped()) {
- stream_->OnStreamFrame(frame);
- }
- }
- // We should have nothing written to the network and the stream
- // should have stopped reading.
- EXPECT_TRUE(stream_->reading_stopped());
-}
-
-} // namespace
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/quic_transport/README.md b/chromium/net/third_party/quiche/src/quic/quic_transport/README.md
deleted file mode 100644
index e2f0849da17..00000000000
--- a/chromium/net/third_party/quiche/src/quic/quic_transport/README.md
+++ /dev/null
@@ -1,7 +0,0 @@
-# QuicTransport
-
-The files in this directory implement QuicTransport protocol as described in
-<https://tools.ietf.org/html/draft-vvv-webtransport-quic>.
-
-Design doc:
-https://docs.google.com/document/d/1UgviRBnZkMUq4OKcsAJvIQFX6UCXeCbOtX_wMgwD_es/edit#
diff --git a/chromium/net/third_party/quiche/src/quic/quic_transport/quic_transport_client_session.cc b/chromium/net/third_party/quiche/src/quic/quic_transport/quic_transport_client_session.cc
deleted file mode 100644
index 1a2160b0e9d..00000000000
--- a/chromium/net/third_party/quiche/src/quic/quic_transport/quic_transport_client_session.cc
+++ /dev/null
@@ -1,267 +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 "quic/quic_transport/quic_transport_client_session.h"
-
-#include <cstdint>
-#include <limits>
-#include <memory>
-#include <string>
-#include <utility>
-
-#include "absl/strings/string_view.h"
-#include "url/gurl.h"
-#include "quic/core/quic_constants.h"
-#include "quic/core/quic_crypto_client_stream.h"
-#include "quic/core/quic_data_writer.h"
-#include "quic/core/quic_error_codes.h"
-#include "quic/core/quic_session.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_versions.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/quic_transport/quic_transport_protocol.h"
-#include "quic/quic_transport/quic_transport_stream.h"
-
-namespace quic {
-
-QuicTransportClientSession::QuicTransportClientSession(
- QuicConnection* connection,
- Visitor* owner,
- const QuicConfig& config,
- const ParsedQuicVersionVector& supported_versions,
- const GURL& url,
- QuicCryptoClientConfig* crypto_config,
- url::Origin origin,
- WebTransportVisitor* visitor,
- std::unique_ptr<QuicDatagramQueue::Observer> datagram_observer)
- : QuicSession(connection,
- owner,
- config,
- supported_versions,
- /*num_expected_unidirectional_static_streams*/ 0,
- std::move(datagram_observer)),
- url_(url),
- origin_(origin),
- visitor_(visitor) {
- for (const ParsedQuicVersion& version : supported_versions) {
- QUIC_BUG_IF(quic_bug_12035_1, version.handshake_protocol != PROTOCOL_TLS1_3)
- << "QuicTransport requires TLS 1.3 handshake";
- }
- crypto_stream_ = std::make_unique<QuicCryptoClientStream>(
- QuicServerId(url.host(), url.EffectiveIntPort()), this,
- crypto_config->proof_verifier()->CreateDefaultContext(), crypto_config,
- /*proof_handler=*/this, /*has_application_state = */ true);
-}
-
-void QuicTransportClientSession::OnAlpnSelected(absl::string_view alpn) {
- // Defense in-depth: ensure the ALPN selected is the desired one.
- if (alpn != QuicTransportAlpn()) {
- QUIC_BUG(quic_bug_10881_1)
- << "QuicTransport negotiated non-QuicTransport ALPN: " << alpn;
- connection()->CloseConnection(
- QUIC_INTERNAL_ERROR, "QuicTransport negotiated non-QuicTransport ALPN",
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
- return;
- }
-
- alpn_received_ = true;
-}
-
-QuicStream* QuicTransportClientSession::CreateIncomingStream(QuicStreamId id) {
- QUIC_DVLOG(1) << "Creating incoming QuicTransport stream " << id;
- QuicTransportStream* stream = CreateStream(id);
- if (stream->type() == BIDIRECTIONAL) {
- incoming_bidirectional_streams_.push_back(stream);
- visitor_->OnIncomingBidirectionalStreamAvailable();
- } else {
- incoming_unidirectional_streams_.push_back(stream);
- visitor_->OnIncomingUnidirectionalStreamAvailable();
- }
- return stream;
-}
-
-void QuicTransportClientSession::SetDefaultEncryptionLevel(
- EncryptionLevel level) {
- QuicSession::SetDefaultEncryptionLevel(level);
- if (level == ENCRYPTION_FORWARD_SECURE) {
- SendClientIndication();
- }
-}
-
-void QuicTransportClientSession::OnTlsHandshakeComplete() {
- QuicSession::OnTlsHandshakeComplete();
- SendClientIndication();
-}
-
-QuicTransportStream*
-QuicTransportClientSession::AcceptIncomingBidirectionalStream() {
- if (incoming_bidirectional_streams_.empty()) {
- return nullptr;
- }
- QuicTransportStream* stream = incoming_bidirectional_streams_.front();
- incoming_bidirectional_streams_.pop_front();
- return stream;
-}
-
-QuicTransportStream*
-QuicTransportClientSession::AcceptIncomingUnidirectionalStream() {
- if (incoming_unidirectional_streams_.empty()) {
- return nullptr;
- }
- QuicTransportStream* stream = incoming_unidirectional_streams_.front();
- incoming_unidirectional_streams_.pop_front();
- return stream;
-}
-
-QuicTransportStream*
-QuicTransportClientSession::OpenOutgoingBidirectionalStream() {
- if (!CanOpenNextOutgoingBidirectionalStream()) {
- QUIC_BUG(quic_bug_10881_2)
- << "Attempted to open a stream in violation of flow control";
- return nullptr;
- }
- return CreateStream(GetNextOutgoingBidirectionalStreamId());
-}
-
-QuicTransportStream*
-QuicTransportClientSession::OpenOutgoingUnidirectionalStream() {
- if (!CanOpenNextOutgoingUnidirectionalStream()) {
- QUIC_BUG(quic_bug_10881_3)
- << "Attempted to open a stream in violation of flow control";
- return nullptr;
- }
- return CreateStream(GetNextOutgoingUnidirectionalStreamId());
-}
-
-QuicTransportStream* QuicTransportClientSession::CreateStream(QuicStreamId id) {
- auto stream = std::make_unique<QuicTransportStream>(id, this, this);
- QuicTransportStream* stream_ptr = stream.get();
- ActivateStream(std::move(stream));
- return stream_ptr;
-}
-
-std::string QuicTransportClientSession::SerializeClientIndication() {
- std::string serialized_origin = origin_.Serialize();
- if (serialized_origin.size() > std::numeric_limits<uint16_t>::max()) {
- QUIC_BUG(quic_bug_10881_4) << "Client origin too long";
- connection()->CloseConnection(
- QUIC_INTERNAL_ERROR, "Client origin too long",
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
- return "";
- }
- QUIC_DLOG(INFO) << "Sending client indication with origin "
- << serialized_origin;
-
- std::string path = url_.PathForRequest();
- if (path.size() > std::numeric_limits<uint16_t>::max()) {
- connection()->CloseConnection(
- QUIC_TRANSPORT_INVALID_CLIENT_INDICATION, "Requested URL path too long",
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
- return "";
- }
-
- constexpr size_t kPrefixSize =
- sizeof(QuicTransportClientIndicationKeys) + sizeof(uint16_t);
- const size_t buffer_size =
- 2 * kPrefixSize + serialized_origin.size() + path.size();
- if (buffer_size > std::numeric_limits<uint16_t>::max()) {
- connection()->CloseConnection(
- QUIC_TRANSPORT_INVALID_CLIENT_INDICATION,
- "Client indication size limit exceeded",
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
- return "";
- }
-
- std::string buffer;
- buffer.resize(buffer_size);
- QuicDataWriter writer(buffer.size(), &buffer[0]);
- bool success =
- writer.WriteUInt16(
- static_cast<uint16_t>(QuicTransportClientIndicationKeys::kOrigin)) &&
- writer.WriteUInt16(serialized_origin.size()) &&
- writer.WriteStringPiece(serialized_origin) &&
- writer.WriteUInt16(
- static_cast<uint16_t>(QuicTransportClientIndicationKeys::kPath)) &&
- writer.WriteUInt16(path.size()) && writer.WriteStringPiece(path);
- QUIC_BUG_IF(quic_bug_10881_5, !success)
- << "Failed to serialize client indication";
- QUIC_BUG_IF(quic_bug_12035_2, writer.length() != buffer.length())
- << "Serialized client indication has length different from expected";
- return buffer;
-}
-
-void QuicTransportClientSession::SendClientIndication() {
- if (!crypto_stream_->encryption_established()) {
- QUIC_BUG(quic_bug_10881_6)
- << "Client indication may only be sent once the encryption is "
- "established.";
- connection()->CloseConnection(
- QUIC_INTERNAL_ERROR, "Attempted to send client indication unencrypted",
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
- return;
- }
- if (ready_) {
- QUIC_BUG(quic_bug_10881_7) << "Client indication may only be sent once.";
- connection()->CloseConnection(
- QUIC_INTERNAL_ERROR, "Attempted to send client indication twice",
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
- return;
- }
-
- auto client_indication_owned = std::make_unique<ClientIndication>(
- /*stream_id=*/GetNextOutgoingUnidirectionalStreamId(), this,
- /*is_static=*/false, WRITE_UNIDIRECTIONAL);
- QUIC_BUG_IF(quic_bug_12035_3,
- client_indication_owned->id() != ClientIndicationStream())
- << "Client indication stream is " << client_indication_owned->id()
- << " instead of expected " << ClientIndicationStream();
- ClientIndication* client_indication = client_indication_owned.get();
- ActivateStream(std::move(client_indication_owned));
-
- client_indication->WriteOrBufferData(SerializeClientIndication(),
- /*fin=*/true, nullptr);
- client_indication_sent_ = true;
-
- // Defense in depth: never set the ready bit unless ALPN has been confirmed.
- if (!alpn_received_) {
- QUIC_BUG(quic_bug_10881_8)
- << "ALPN confirmation missing after handshake complete";
- connection()->CloseConnection(
- QUIC_INTERNAL_ERROR,
- "ALPN confirmation missing after handshake complete",
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
- return;
- }
-
- // Don't set the ready bit if we closed the connection due to any error
- // beforehand.
- if (!connection()->connected()) {
- return;
- }
-
- ready_ = true;
- visitor_->OnSessionReady(spdy::SpdyHeaderBlock());
-}
-
-void QuicTransportClientSession::OnMessageReceived(absl::string_view message) {
- visitor_->OnDatagramReceived(message);
-}
-
-void QuicTransportClientSession::OnCanCreateNewOutgoingStream(
- bool unidirectional) {
- if (unidirectional) {
- visitor_->OnCanCreateNewOutgoingUnidirectionalStream();
- } else {
- visitor_->OnCanCreateNewOutgoingBidirectionalStream();
- }
-}
-
-void QuicTransportClientSession::OnProofValid(
- const QuicCryptoClientConfig::CachedState& /*cached*/) {}
-
-void QuicTransportClientSession::OnProofVerifyDetailsAvailable(
- const ProofVerifyDetails& /*verify_details*/) {}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/quic_transport/quic_transport_client_session.h b/chromium/net/third_party/quiche/src/quic/quic_transport/quic_transport_client_session.h
deleted file mode 100644
index 87854575bb0..00000000000
--- a/chromium/net/third_party/quiche/src/quic/quic_transport/quic_transport_client_session.h
+++ /dev/null
@@ -1,175 +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_QUIC_TRANSPORT_QUIC_TRANSPORT_SESSION_H_
-#define QUICHE_QUIC_QUIC_TRANSPORT_QUIC_TRANSPORT_SESSION_H_
-
-#include <cstdint>
-#include <memory>
-
-#include "absl/strings/string_view.h"
-#include "url/gurl.h"
-#include "url/origin.h"
-#include "quic/core/crypto/quic_crypto_client_config.h"
-#include "quic/core/quic_config.h"
-#include "quic/core/quic_connection.h"
-#include "quic/core/quic_crypto_client_stream.h"
-#include "quic/core/quic_crypto_stream.h"
-#include "quic/core/quic_datagram_queue.h"
-#include "quic/core/quic_error_codes.h"
-#include "quic/core/quic_server_id.h"
-#include "quic/core/quic_session.h"
-#include "quic/core/quic_stream.h"
-#include "quic/core/quic_versions.h"
-#include "quic/core/web_transport_interface.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_containers.h"
-#include "quic/quic_transport/quic_transport_protocol.h"
-#include "quic/quic_transport/quic_transport_session_interface.h"
-#include "quic/quic_transport/quic_transport_stream.h"
-
-namespace quic {
-
-// A client session for the QuicTransport protocol.
-class QUIC_EXPORT_PRIVATE QuicTransportClientSession
- : public QuicSession,
- public WebTransportSession,
- public QuicTransportSessionInterface,
- public QuicCryptoClientStream::ProofHandler {
- public:
- QuicTransportClientSession(
- QuicConnection* connection,
- Visitor* owner,
- const QuicConfig& config,
- const ParsedQuicVersionVector& supported_versions,
- const GURL& url,
- QuicCryptoClientConfig* crypto_config,
- url::Origin origin,
- WebTransportVisitor* visitor,
- std::unique_ptr<QuicDatagramQueue::Observer> datagram_observer);
-
- std::vector<std::string> GetAlpnsToOffer() const override {
- return std::vector<std::string>({QuicTransportAlpn()});
- }
- void OnAlpnSelected(absl::string_view alpn) override;
- bool alpn_received() const { return alpn_received_; }
-
- void CryptoConnect() { crypto_stream_->CryptoConnect(); }
-
- bool ShouldKeepConnectionAlive() const override { return true; }
-
- QuicCryptoStream* GetMutableCryptoStream() override {
- return crypto_stream_.get();
- }
- const QuicCryptoStream* GetCryptoStream() const override {
- return crypto_stream_.get();
- }
-
- // Returns true once the encryption has been established and the client
- // indication has been sent. No application data will be read or written
- // before the connection is ready. Once the connection becomes ready, this
- // method will never return false.
- bool IsSessionReady() const override { return ready_; }
-
- QuicStream* CreateIncomingStream(QuicStreamId id) override;
- QuicStream* CreateIncomingStream(PendingStream* /*pending*/) override {
- QUIC_BUG(quic_bug_10890_1)
- << "QuicTransportClientSession::CreateIncomingStream("
- "PendingStream) not implemented";
- return nullptr;
- }
-
- void SetDefaultEncryptionLevel(EncryptionLevel level) override;
- void OnTlsHandshakeComplete() override;
- void OnMessageReceived(absl::string_view message) override;
-
- // Return the earliest incoming stream that has been received by the session
- // but has not been accepted. Returns nullptr if there are no incoming
- // streams.
- QuicTransportStream* AcceptIncomingBidirectionalStream() override;
- QuicTransportStream* AcceptIncomingUnidirectionalStream() override;
-
- bool CanOpenNextOutgoingBidirectionalStream() override {
- return QuicSession::CanOpenNextOutgoingBidirectionalStream();
- }
- bool CanOpenNextOutgoingUnidirectionalStream() override {
- return QuicSession::CanOpenNextOutgoingUnidirectionalStream();
- }
- QuicTransportStream* OpenOutgoingBidirectionalStream() override;
- QuicTransportStream* OpenOutgoingUnidirectionalStream() override;
-
- MessageStatus SendOrQueueDatagram(QuicMemSlice datagram) override {
- return datagram_queue()->SendOrQueueDatagram(std::move(datagram));
- }
- void SetDatagramMaxTimeInQueue(QuicTime::Delta max_time_in_queue) override {
- datagram_queue()->SetMaxTimeInQueue(max_time_in_queue);
- }
-
- // For unit tests.
- using QuicSession::datagram_queue;
-
- // QuicCryptoClientStream::ProofHandler implementation.
- void OnProofValid(const QuicCryptoClientConfig::CachedState& cached) override;
- void OnProofVerifyDetailsAvailable(
- const ProofVerifyDetails& verify_details) override;
-
- void CloseSession(WebTransportSessionError /*error_code*/,
- absl::string_view error_message) override {
- connection()->CloseConnection(
- QUIC_NO_ERROR, std::string(error_message),
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
- }
-
- QuicByteCount GetMaxDatagramSize() const override {
- return GetGuaranteedLargestMessagePayload();
- }
-
- protected:
- class QUIC_EXPORT_PRIVATE ClientIndication : public QuicStream {
- public:
- using QuicStream::QuicStream;
-
- // This method should never be called, since the stream is client-initiated
- // unidirectional.
- void OnDataAvailable() override {
- QUIC_BUG(quic_bug_10890_2) << "Received data on a write-only stream";
- }
- };
-
- // Creates and activates a QuicTransportStream for the given ID.
- QuicTransportStream* CreateStream(QuicStreamId id);
-
- // Serializes the client indication as described in
- // https://vasilvv.github.io/webtransport/draft-vvv-webtransport-quic.html#rfc.section.3.2
- std::string SerializeClientIndication();
- // Creates the client indication stream and sends the client indication on it.
- void SendClientIndication();
-
- void OnCanCreateNewOutgoingStream(bool unidirectional) override;
-
- std::unique_ptr<QuicCryptoClientStream> crypto_stream_;
- GURL url_;
- url::Origin origin_;
- WebTransportVisitor* visitor_; // not owned
- bool client_indication_sent_ = false;
- bool alpn_received_ = false;
- bool ready_ = false;
-
- // Contains all of the streams that has been received by the session but have
- // not been processed by the application.
- // TODO(vasilvv): currently, we always send MAX_STREAMS as long as the overall
- // maximum number of streams for the connection has not been exceeded. We
- // should also limit the maximum number of streams that the consuming code
- // has not accepted to a smaller number, by checking the size of
- // |incoming_bidirectional_streams_| and |incoming_unidirectional_streams_|
- // before sending MAX_STREAMS.
- quiche::QuicheCircularDeque<QuicTransportStream*>
- incoming_bidirectional_streams_;
- quiche::QuicheCircularDeque<QuicTransportStream*>
- incoming_unidirectional_streams_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_QUIC_TRANSPORT_QUIC_TRANSPORT_SESSION_H_
diff --git a/chromium/net/third_party/quiche/src/quic/quic_transport/quic_transport_client_session_test.cc b/chromium/net/third_party/quiche/src/quic/quic_transport/quic_transport_client_session_test.cc
deleted file mode 100644
index 90c449cb746..00000000000
--- a/chromium/net/third_party/quiche/src/quic/quic_transport/quic_transport_client_session_test.cc
+++ /dev/null
@@ -1,182 +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 "quic/quic_transport/quic_transport_client_session.h"
-
-#include <memory>
-#include <utility>
-
-#include "absl/base/macros.h"
-#include "url/gurl.h"
-#include "quic/core/quic_data_writer.h"
-#include "quic/core/quic_server_id.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_expect_bug.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/crypto_test_utils.h"
-#include "quic/test_tools/quic_session_peer.h"
-#include "quic/test_tools/quic_stream_peer.h"
-#include "quic/test_tools/quic_test_utils.h"
-#include "quic/test_tools/quic_transport_test_tools.h"
-
-namespace quic {
-namespace test {
-namespace {
-
-using testing::_;
-using testing::ElementsAre;
-using testing::Eq;
-
-const char* kTestOrigin = "https://test-origin.test";
-url::Origin GetTestOrigin() {
- GURL origin_url(kTestOrigin);
- return url::Origin::Create(origin_url);
-}
-
-ParsedQuicVersionVector GetVersions() {
- return {DefaultVersionForQuicTransport()};
-}
-
-std::string DataInStream(QuicStream* stream) {
- QuicStreamSendBuffer& send_buffer = QuicStreamPeer::SendBuffer(stream);
- std::string result;
- result.resize(send_buffer.stream_offset());
- QuicDataWriter writer(result.size(), &result[0]);
- EXPECT_TRUE(
- send_buffer.WriteStreamData(0, send_buffer.stream_offset(), &writer));
- return result;
-}
-
-class QuicTransportClientSessionTest : public QuicTest {
- protected:
- QuicTransportClientSessionTest()
- : connection_(&helper_,
- &alarm_factory_,
- Perspective::IS_CLIENT,
- GetVersions()),
- crypto_config_(crypto_test_utils::ProofVerifierForTesting()) {
- QuicEnableVersion(DefaultVersionForQuicTransport());
- CreateSession(GetTestOrigin(), "");
- }
-
- void CreateSession(url::Origin origin, std::string url_suffix) {
- session_ = std::make_unique<QuicTransportClientSession>(
- &connection_, nullptr, DefaultQuicConfig(), GetVersions(),
- GURL("quic-transport://test.example.com:50000" + url_suffix),
- &crypto_config_, origin, &visitor_, /*datagram_observer=*/nullptr);
- session_->Initialize();
- crypto_stream_ = static_cast<QuicCryptoClientStream*>(
- session_->GetMutableCryptoStream());
- }
-
- void Connect() {
- session_->CryptoConnect();
- QuicConfig server_config = DefaultQuicConfig();
- std::unique_ptr<QuicCryptoServerConfig> crypto_config(
- crypto_test_utils::CryptoServerConfigForTesting());
- crypto_test_utils::HandshakeWithFakeServer(
- &server_config, crypto_config.get(), &helper_, &alarm_factory_,
- &connection_, crypto_stream_, QuicTransportAlpn());
- }
-
- MockAlarmFactory alarm_factory_;
- MockQuicConnectionHelper helper_;
-
- PacketSavingConnection connection_;
- QuicCryptoClientConfig crypto_config_;
- MockClientVisitor visitor_;
- std::unique_ptr<QuicTransportClientSession> session_;
- QuicCryptoClientStream* crypto_stream_;
-};
-
-TEST_F(QuicTransportClientSessionTest, HasValidAlpn) {
- EXPECT_THAT(session_->GetAlpnsToOffer(), ElementsAre(QuicTransportAlpn()));
-}
-
-TEST_F(QuicTransportClientSessionTest, SuccessfulConnection) {
- constexpr char kTestOriginClientIndication[] =
- "\0\0" // key (0x0000, origin)
- "\0\x18" // length
- "https://test-origin.test" // value
- "\0\x01" // key (0x0001, path)
- "\0\x01" // length
- "/"; // value
-
- EXPECT_CALL(visitor_, OnSessionReady(_));
- Connect();
- EXPECT_TRUE(session_->IsSessionReady());
-
- QuicStream* client_indication_stream;
- client_indication_stream =
- QuicSessionPeer::stream_map(session_.get())[ClientIndicationStream()]
- .get();
- ASSERT_TRUE(client_indication_stream != nullptr);
- const std::string client_indication = DataInStream(client_indication_stream);
- const std::string expected_client_indication{
- kTestOriginClientIndication,
- ABSL_ARRAYSIZE(kTestOriginClientIndication) - 1};
- EXPECT_EQ(client_indication, expected_client_indication);
-}
-
-TEST_F(QuicTransportClientSessionTest, SuccessfulConnectionWithPath) {
- constexpr char kSuffix[] = "/foo/bar?hello=world#not-sent";
- constexpr char kTestOriginClientIndication[] =
- "\0\0" // key (0x0000, origin)
- "\0\x18" // length
- "https://test-origin.test" // value
- "\0\x01" // key (0x0001, path)
- "\0\x14" // length
- "/foo/bar?hello=world"; // value
-
- CreateSession(GetTestOrigin(), kSuffix);
- Connect();
- EXPECT_TRUE(session_->IsSessionReady());
-
- QuicStream* client_indication_stream;
- client_indication_stream =
- QuicSessionPeer::stream_map(session_.get())[ClientIndicationStream()]
- .get();
- ASSERT_TRUE(client_indication_stream != nullptr);
- const std::string client_indication = DataInStream(client_indication_stream);
- const std::string expected_client_indication{
- kTestOriginClientIndication,
- ABSL_ARRAYSIZE(kTestOriginClientIndication) - 1};
- EXPECT_EQ(client_indication, expected_client_indication);
-}
-
-TEST_F(QuicTransportClientSessionTest, OriginTooLong) {
- std::string long_string(68000, 'a');
- GURL bad_origin_url{"https://" + long_string + ".example/"};
- EXPECT_TRUE(bad_origin_url.is_valid());
- CreateSession(url::Origin::Create(bad_origin_url), "");
-
- EXPECT_QUIC_BUG(Connect(), "Client origin too long");
-}
-
-TEST_F(QuicTransportClientSessionTest, ReceiveNewStreams) {
- Connect();
- ASSERT_TRUE(session_->IsSessionReady());
- ASSERT_TRUE(session_->AcceptIncomingUnidirectionalStream() == nullptr);
-
- const QuicStreamId id = GetNthServerInitiatedUnidirectionalStreamId(
- session_->transport_version(), 0);
- QuicStreamFrame frame(id, /*fin=*/false, /*offset=*/0, "test");
- EXPECT_CALL(visitor_, OnIncomingUnidirectionalStreamAvailable()).Times(1);
- session_->OnStreamFrame(frame);
-
- QuicTransportStream* stream = session_->AcceptIncomingUnidirectionalStream();
- ASSERT_TRUE(stream != nullptr);
- EXPECT_EQ(stream->ReadableBytes(), 4u);
- EXPECT_EQ(stream->id(), id);
-}
-
-TEST_F(QuicTransportClientSessionTest, ReceiveDatagram) {
- EXPECT_CALL(visitor_, OnDatagramReceived(Eq("test")));
- session_->OnMessageReceived("test");
-}
-
-} // namespace
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/quic_transport/quic_transport_integration_test.cc b/chromium/net/third_party/quiche/src/quic/quic_transport/quic_transport_integration_test.cc
deleted file mode 100644
index 7bb8479af31..00000000000
--- a/chromium/net/third_party/quiche/src/quic/quic_transport/quic_transport_integration_test.cc
+++ /dev/null
@@ -1,418 +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.
-
-// An integration test that covers interactions between QuicTransport client and
-// server sessions.
-
-#include <memory>
-#include <vector>
-
-#include "absl/strings/string_view.h"
-#include "url/gurl.h"
-#include "url/origin.h"
-#include "quic/core/crypto/quic_crypto_client_config.h"
-#include "quic/core/crypto/quic_crypto_server_config.h"
-#include "quic/core/quic_buffer_allocator.h"
-#include "quic/core/quic_connection.h"
-#include "quic/core/quic_error_codes.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_versions.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/quic_transport/quic_transport_client_session.h"
-#include "quic/quic_transport/quic_transport_server_session.h"
-#include "quic/quic_transport/quic_transport_stream.h"
-#include "quic/test_tools/crypto_test_utils.h"
-#include "quic/test_tools/quic_session_peer.h"
-#include "quic/test_tools/quic_test_utils.h"
-#include "quic/test_tools/quic_transport_test_tools.h"
-#include "quic/test_tools/simulator/link.h"
-#include "quic/test_tools/simulator/quic_endpoint_base.h"
-#include "quic/test_tools/simulator/simulator.h"
-#include "quic/test_tools/simulator/switch.h"
-#include "quic/tools/quic_transport_simple_server_session.h"
-
-namespace quic {
-namespace test {
-namespace {
-
-using simulator::QuicEndpointBase;
-using simulator::Simulator;
-using testing::_;
-using testing::Assign;
-using testing::Eq;
-
-url::Origin GetTestOrigin() {
- constexpr char kTestOrigin[] = "https://test-origin.test";
- GURL origin_url(kTestOrigin);
- return url::Origin::Create(origin_url);
-}
-
-ParsedQuicVersionVector GetVersions() {
- return {DefaultVersionForQuicTransport()};
-}
-
-class QuicTransportEndpointBase : public QuicEndpointBase {
- public:
- QuicTransportEndpointBase(Simulator* simulator,
- const std::string& name,
- const std::string& peer_name,
- Perspective perspective)
- : QuicEndpointBase(simulator, name, peer_name) {
- QuicEnableVersion(DefaultVersionForQuicTransport());
- connection_ = std::make_unique<QuicConnection>(
- TestConnectionId(0x10), simulator::GetAddressFromName(name),
- simulator::GetAddressFromName(peer_name), simulator,
- simulator->GetAlarmFactory(), &writer_,
- /*owns_writer=*/false, perspective, GetVersions());
- connection_->SetSelfAddress(simulator::GetAddressFromName(name));
- }
-};
-
-class QuicTransportClientEndpoint : public QuicTransportEndpointBase {
- public:
- QuicTransportClientEndpoint(Simulator* simulator,
- const std::string& name,
- const std::string& peer_name,
- const QuicConfig& config,
- url::Origin origin,
- const std::string& path)
- : QuicTransportEndpointBase(simulator,
- name,
- peer_name,
- Perspective::IS_CLIENT),
- crypto_config_(crypto_test_utils::ProofVerifierForTesting()),
- session_(connection_.get(),
- nullptr,
- config,
- GetVersions(),
- GURL("quic-transport://test.example.com:50000" + path),
- &crypto_config_,
- origin,
- &visitor_,
- /*datagram_observer=*/nullptr) {
- session_.Initialize();
- }
-
- QuicTransportClientSession* session() { return &session_; }
- MockClientVisitor* visitor() { return &visitor_; }
-
- private:
- QuicCryptoClientConfig crypto_config_;
- MockClientVisitor visitor_;
- QuicTransportClientSession session_;
-};
-
-class QuicTransportServerEndpoint : public QuicTransportEndpointBase {
- public:
- QuicTransportServerEndpoint(Simulator* simulator,
- const std::string& name,
- const std::string& peer_name,
- const QuicConfig& config,
- std::vector<url::Origin> accepted_origins)
- : QuicTransportEndpointBase(simulator,
- name,
- peer_name,
- Perspective::IS_SERVER),
- crypto_config_(QuicCryptoServerConfig::TESTING,
- QuicRandom::GetInstance(),
- crypto_test_utils::ProofSourceForTesting(),
- KeyExchangeSource::Default()),
- compressed_certs_cache_(
- QuicCompressedCertsCache::kQuicCompressedCertsCacheSize),
- session_(connection_.get(),
- /*owns_connection=*/false,
- nullptr,
- config,
- GetVersions(),
- &crypto_config_,
- &compressed_certs_cache_,
- accepted_origins) {
- session_.Initialize();
- }
-
- QuicTransportServerSession* session() { return &session_; }
-
- private:
- QuicCryptoServerConfig crypto_config_;
- QuicCompressedCertsCache compressed_certs_cache_;
- QuicTransportSimpleServerSession session_;
-};
-
-constexpr QuicBandwidth kClientBandwidth =
- QuicBandwidth::FromKBitsPerSecond(10000);
-constexpr QuicTime::Delta kClientPropagationDelay =
- QuicTime::Delta::FromMilliseconds(2);
-constexpr QuicBandwidth kServerBandwidth =
- QuicBandwidth::FromKBitsPerSecond(4000);
-constexpr QuicTime::Delta kServerPropagationDelay =
- QuicTime::Delta::FromMilliseconds(50);
-const QuicTime::Delta kTransferTime =
- kClientBandwidth.TransferTime(kMaxOutgoingPacketSize) +
- kServerBandwidth.TransferTime(kMaxOutgoingPacketSize);
-const QuicTime::Delta kRtt =
- (kClientPropagationDelay + kServerPropagationDelay + kTransferTime) * 2;
-const QuicByteCount kBdp = kRtt * kServerBandwidth;
-
-constexpr QuicTime::Delta kDefaultTimeout = QuicTime::Delta::FromSeconds(3);
-
-class QuicTransportIntegrationTest : public QuicTest {
- public:
- QuicTransportIntegrationTest()
- : switch_(&simulator_, "Switch", 8, 2 * kBdp) {}
-
- void CreateDefaultEndpoints(const std::string& path) {
- client_ = std::make_unique<QuicTransportClientEndpoint>(
- &simulator_, "Client", "Server", client_config_, GetTestOrigin(), path);
- server_ = std::make_unique<QuicTransportServerEndpoint>(
- &simulator_, "Server", "Client", server_config_, accepted_origins_);
- }
-
- void WireUpEndpoints() {
- client_link_ = std::make_unique<simulator::SymmetricLink>(
- client_.get(), switch_.port(1), kClientBandwidth,
- kClientPropagationDelay);
- server_link_ = std::make_unique<simulator::SymmetricLink>(
- server_.get(), switch_.port(2), kServerBandwidth,
- kServerPropagationDelay);
- }
-
- void RunHandshake() {
- client_->session()->CryptoConnect();
- bool result = simulator_.RunUntilOrTimeout(
- [this]() {
- return IsHandshakeDone(client_->session()) &&
- IsHandshakeDone(server_->session());
- },
- kDefaultTimeout);
- EXPECT_TRUE(result);
- }
-
- protected:
- template <class Session>
- static bool IsHandshakeDone(const Session* session) {
- return session->IsSessionReady() || session->error() != QUIC_NO_ERROR;
- }
-
- QuicConfig client_config_ = DefaultQuicConfig();
- QuicConfig server_config_ = DefaultQuicConfig();
-
- Simulator simulator_;
- simulator::Switch switch_;
- std::unique_ptr<simulator::SymmetricLink> client_link_;
- std::unique_ptr<simulator::SymmetricLink> server_link_;
-
- std::unique_ptr<QuicTransportClientEndpoint> client_;
- std::unique_ptr<QuicTransportServerEndpoint> server_;
-
- std::vector<url::Origin> accepted_origins_ = {GetTestOrigin()};
-};
-
-TEST_F(QuicTransportIntegrationTest, SuccessfulHandshake) {
- CreateDefaultEndpoints("/discard");
- WireUpEndpoints();
- EXPECT_CALL(*client_->visitor(), OnSessionReady(_));
- RunHandshake();
- EXPECT_TRUE(client_->session()->IsSessionReady());
- EXPECT_TRUE(server_->session()->IsSessionReady());
-}
-
-TEST_F(QuicTransportIntegrationTest, OriginMismatch) {
- accepted_origins_ = {url::Origin::Create(GURL{"https://wrong-origin.test"})};
- CreateDefaultEndpoints("/discard");
- WireUpEndpoints();
- RunHandshake();
- // Wait until the client receives CONNECTION_CLOSE.
- simulator_.RunUntilOrTimeout(
- [this]() { return !client_->session()->connection()->connected(); },
- kDefaultTimeout);
- EXPECT_TRUE(client_->session()->IsSessionReady());
- EXPECT_FALSE(server_->session()->IsSessionReady());
- EXPECT_FALSE(client_->session()->connection()->connected());
- EXPECT_FALSE(server_->session()->connection()->connected());
- EXPECT_THAT(client_->session()->error(),
- IsError(QUIC_TRANSPORT_INVALID_CLIENT_INDICATION));
- EXPECT_THAT(server_->session()->error(),
- IsError(QUIC_TRANSPORT_INVALID_CLIENT_INDICATION));
-}
-
-TEST_F(QuicTransportIntegrationTest, SendOutgoingStreams) {
- CreateDefaultEndpoints("/discard");
- WireUpEndpoints();
- RunHandshake();
-
- std::vector<QuicTransportStream*> streams;
- for (int i = 0; i < 10; i++) {
- QuicTransportStream* stream =
- client_->session()->OpenOutgoingUnidirectionalStream();
- ASSERT_TRUE(stream->Write("test"));
- streams.push_back(stream);
- }
- ASSERT_TRUE(simulator_.RunUntilOrTimeout(
- [this]() {
- return QuicSessionPeer::GetNumOpenDynamicStreams(server_->session()) ==
- 10;
- },
- kDefaultTimeout));
-
- for (QuicTransportStream* stream : streams) {
- ASSERT_TRUE(stream->SendFin());
- }
- ASSERT_TRUE(simulator_.RunUntilOrTimeout(
- [this]() {
- return QuicSessionPeer::GetNumOpenDynamicStreams(server_->session()) ==
- 0;
- },
- kDefaultTimeout));
-}
-
-TEST_F(QuicTransportIntegrationTest, EchoBidirectionalStreams) {
- CreateDefaultEndpoints("/echo");
- WireUpEndpoints();
- RunHandshake();
-
- QuicTransportStream* stream =
- client_->session()->OpenOutgoingBidirectionalStream();
- EXPECT_TRUE(stream->Write("Hello!"));
-
- ASSERT_TRUE(simulator_.RunUntilOrTimeout(
- [stream]() { return stream->ReadableBytes() == strlen("Hello!"); },
- kDefaultTimeout));
- std::string received;
- WebTransportStream::ReadResult result = stream->Read(&received);
- EXPECT_EQ(result.bytes_read, strlen("Hello!"));
- EXPECT_FALSE(result.fin);
- EXPECT_EQ(received, "Hello!");
-
- EXPECT_TRUE(stream->SendFin());
- ASSERT_TRUE(simulator_.RunUntilOrTimeout(
- [this]() {
- return QuicSessionPeer::GetNumOpenDynamicStreams(server_->session()) ==
- 0;
- },
- kDefaultTimeout));
-}
-
-TEST_F(QuicTransportIntegrationTest, EchoUnidirectionalStreams) {
- CreateDefaultEndpoints("/echo");
- WireUpEndpoints();
- RunHandshake();
-
- // Send two streams, but only send FIN on the second one.
- QuicTransportStream* stream1 =
- client_->session()->OpenOutgoingUnidirectionalStream();
- EXPECT_TRUE(stream1->Write("Stream One"));
- QuicTransportStream* stream2 =
- client_->session()->OpenOutgoingUnidirectionalStream();
- EXPECT_TRUE(stream2->Write("Stream Two"));
- EXPECT_TRUE(stream2->SendFin());
-
- // Wait until a stream is received.
- bool stream_received = false;
- EXPECT_CALL(*client_->visitor(), OnIncomingUnidirectionalStreamAvailable())
- .Times(2)
- .WillRepeatedly(Assign(&stream_received, true));
- ASSERT_TRUE(simulator_.RunUntilOrTimeout(
- [&stream_received]() { return stream_received; }, kDefaultTimeout));
-
- // Receive a reply stream and expect it to be the second one.
- QuicTransportStream* reply =
- client_->session()->AcceptIncomingUnidirectionalStream();
- ASSERT_TRUE(reply != nullptr);
- std::string buffer;
- WebTransportStream::ReadResult result = reply->Read(&buffer);
- EXPECT_GT(result.bytes_read, 0u);
- EXPECT_TRUE(result.fin);
- EXPECT_EQ(buffer, "Stream Two");
-
- // Reset reply-related variables.
- stream_received = false;
- buffer = "";
-
- // Send FIN on the first stream, and expect to receive it back.
- EXPECT_TRUE(stream1->SendFin());
- ASSERT_TRUE(simulator_.RunUntilOrTimeout(
- [&stream_received]() { return stream_received; }, kDefaultTimeout));
- reply = client_->session()->AcceptIncomingUnidirectionalStream();
- ASSERT_TRUE(reply != nullptr);
- result = reply->Read(&buffer);
- EXPECT_GT(result.bytes_read, 0u);
- EXPECT_TRUE(result.fin);
- EXPECT_EQ(buffer, "Stream One");
-}
-
-TEST_F(QuicTransportIntegrationTest, EchoDatagram) {
- CreateDefaultEndpoints("/echo");
- WireUpEndpoints();
- RunHandshake();
-
- client_->session()->SendOrQueueDatagram(MemSliceFromString("test"));
-
- bool datagram_received = false;
- EXPECT_CALL(*client_->visitor(), OnDatagramReceived(Eq("test")))
- .WillOnce(Assign(&datagram_received, true));
- ASSERT_TRUE(simulator_.RunUntilOrTimeout(
- [&datagram_received]() { return datagram_received; }, kDefaultTimeout));
-}
-
-// This test sets the datagram queue to an nearly-infinte queueing time, and
-// then sends 1000 datagrams. We expect to receive most of them back, since the
-// datagrams would be paced out by the congestion controller.
-TEST_F(QuicTransportIntegrationTest, EchoALotOfDatagrams) {
- CreateDefaultEndpoints("/echo");
- WireUpEndpoints();
- RunHandshake();
-
- // Set the datagrams to effectively never expire.
- client_->session()->SetDatagramMaxTimeInQueue(10000 * kRtt);
- for (int i = 0; i < 1000; i++) {
- client_->session()->SendOrQueueDatagram(MemSliceFromString(std::string(
- client_->session()->GetGuaranteedLargestMessagePayload(), 'a')));
- }
-
- size_t received = 0;
- EXPECT_CALL(*client_->visitor(), OnDatagramReceived(_))
- .WillRepeatedly(
- [&received](absl::string_view /*datagram*/) { received++; });
- ASSERT_TRUE(simulator_.RunUntilOrTimeout(
- [this]() { return client_->session()->datagram_queue()->empty(); },
- 3 * kServerBandwidth.TransferTime(1000 * kMaxOutgoingPacketSize)));
- // Allow extra round-trips for the final flight of datagrams to arrive back.
- simulator_.RunFor(2 * kRtt);
-
- EXPECT_GT(received, 500u);
- EXPECT_LT(received, 1000u);
-}
-
-TEST_F(QuicTransportIntegrationTest, OutgoingStreamFlowControlBlocked) {
- server_config_.SetMaxUnidirectionalStreamsToSend(4);
- CreateDefaultEndpoints("/discard");
- WireUpEndpoints();
- RunHandshake();
-
- QuicTransportStream* stream;
- // Note that since we've already used one stream for client indication, we can
- // only send three streams at once.
- for (int i = 0; i < 3; i++) {
- ASSERT_TRUE(client_->session()->CanOpenNextOutgoingUnidirectionalStream());
- stream = client_->session()->OpenOutgoingUnidirectionalStream();
- ASSERT_TRUE(stream != nullptr);
- ASSERT_TRUE(stream->SendFin());
- }
- EXPECT_FALSE(client_->session()->CanOpenNextOutgoingUnidirectionalStream());
-
- // Receiving FINs for the streams we've just opened will cause the server to
- // let us open more streams.
- bool can_create_new_stream = false;
- EXPECT_CALL(*client_->visitor(), OnCanCreateNewOutgoingUnidirectionalStream())
- .WillOnce(Assign(&can_create_new_stream, true));
- ASSERT_TRUE(simulator_.RunUntilOrTimeout(
- [&can_create_new_stream]() { return can_create_new_stream; },
- kDefaultTimeout));
- EXPECT_TRUE(client_->session()->CanOpenNextOutgoingUnidirectionalStream());
-}
-
-} // namespace
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/quic_transport/quic_transport_protocol.h b/chromium/net/third_party/quiche/src/quic/quic_transport/quic_transport_protocol.h
deleted file mode 100644
index 191d42c1400..00000000000
--- a/chromium/net/third_party/quiche/src/quic/quic_transport/quic_transport_protocol.h
+++ /dev/null
@@ -1,54 +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_QUIC_TRANSPORT_QUIC_TRANSPORT_PROTOCOL_H_
-#define QUICHE_QUIC_QUIC_TRANSPORT_QUIC_TRANSPORT_PROTOCOL_H_
-
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_versions.h"
-#include "quic/platform/api/quic_export.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-// The ALPN used by QuicTransport.
-QUIC_EXPORT_PRIVATE inline const char* QuicTransportAlpn() {
- return "wq-vvv-01";
-}
-
-// The stream ID on which the client indication is sent.
-QUIC_EXPORT_PRIVATE constexpr QuicStreamId ClientIndicationStream() {
- return 2;
-}
-
-// The maximum allowed size of the client indication.
-QUIC_EXPORT_PRIVATE constexpr QuicByteCount ClientIndicationMaxSize() {
- return 65536;
-}
-
-// The keys of the fields in the client indication.
-enum class QuicTransportClientIndicationKeys : uint16_t {
- kOrigin = 0x0000,
- kPath = 0x0001,
-};
-
-// Returns if the specified QUIC version can be used by QuicTransport.
-QUIC_EXPORT_PRIVATE constexpr bool IsVersionValidForQuicTransport(
- const ParsedQuicVersion& version) {
- return VersionSupportsMessageFrames(version.transport_version) &&
- VersionHasIetfQuicFrames(version.transport_version) &&
- version.handshake_protocol == PROTOCOL_TLS1_3;
-}
-
-// Returns default QUIC version used for QuicTransport.
-QUIC_EXPORT_PRIVATE inline ParsedQuicVersion DefaultVersionForQuicTransport() {
- constexpr ParsedQuicVersion version = ParsedQuicVersion::Draft29();
- static_assert(IsVersionValidForQuicTransport(version),
- "Default QUIC version used by QuicTransport is invalid");
- return version;
-}
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_QUIC_TRANSPORT_QUIC_TRANSPORT_PROTOCOL_H_
diff --git a/chromium/net/third_party/quiche/src/quic/quic_transport/quic_transport_server_session.cc b/chromium/net/third_party/quiche/src/quic/quic_transport/quic_transport_server_session.cc
deleted file mode 100644
index f7c8c0f949d..00000000000
--- a/chromium/net/third_party/quiche/src/quic/quic_transport/quic_transport_server_session.cc
+++ /dev/null
@@ -1,215 +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 "quic/quic_transport/quic_transport_server_session.h"
-
-#include <algorithm>
-#include <memory>
-#include <string>
-
-#include "absl/strings/str_cat.h"
-#include "absl/strings/string_view.h"
-#include "url/gurl.h"
-#include "url/url_constants.h"
-#include "quic/core/quic_error_codes.h"
-#include "quic/core/quic_stream.h"
-#include "quic/core/quic_types.h"
-#include "quic/quic_transport/quic_transport_protocol.h"
-#include "quic/quic_transport/quic_transport_stream.h"
-
-namespace quic {
-
-namespace {
-class QuicTransportServerCryptoHelper
- : public QuicCryptoServerStreamBase::Helper {
- public:
- bool CanAcceptClientHello(const CryptoHandshakeMessage& /*message*/,
- const QuicSocketAddress& /*client_address*/,
- const QuicSocketAddress& /*peer_address*/,
- const QuicSocketAddress& /*self_address*/,
- std::string* /*error_details*/) const override {
- return true;
- }
-};
-
-} // namespace
-
-QuicTransportServerSession::QuicTransportServerSession(
- QuicConnection* connection,
- Visitor* owner,
- const QuicConfig& config,
- const ParsedQuicVersionVector& supported_versions,
- const QuicCryptoServerConfig* crypto_config,
- QuicCompressedCertsCache* compressed_certs_cache,
- ServerVisitor* visitor)
- : QuicSession(connection,
- owner,
- config,
- supported_versions,
- /*num_expected_unidirectional_static_streams*/ 0),
- visitor_(visitor) {
- for (const ParsedQuicVersion& version : supported_versions) {
- QUIC_BUG_IF(quic_bug_12025_1, version.handshake_protocol != PROTOCOL_TLS1_3)
- << "QuicTransport requires TLS 1.3 handshake";
- }
-
- static QuicTransportServerCryptoHelper* helper =
- new QuicTransportServerCryptoHelper();
- crypto_stream_ = CreateCryptoServerStream(
- crypto_config, compressed_certs_cache, this, helper);
-}
-
-QuicStream* QuicTransportServerSession::CreateIncomingStream(QuicStreamId id) {
- if (id == ClientIndicationStream()) {
- auto indication = std::make_unique<ClientIndication>(this);
- ClientIndication* indication_ptr = indication.get();
- ActivateStream(std::move(indication));
- return indication_ptr;
- }
-
- auto stream = std::make_unique<QuicTransportStream>(id, this, this);
- QuicTransportStream* stream_ptr = stream.get();
- ActivateStream(std::move(stream));
- OnIncomingDataStream(stream_ptr);
- return stream_ptr;
-}
-
-QuicTransportServerSession::ClientIndication::ClientIndication(
- QuicTransportServerSession* session)
- : QuicStream(ClientIndicationStream(),
- session,
- /* is_static= */ false,
- StreamType::READ_UNIDIRECTIONAL),
- session_(session) {}
-
-void QuicTransportServerSession::ClientIndication::OnDataAvailable() {
- sequencer()->Read(&buffer_);
- if (buffer_.size() > ClientIndicationMaxSize()) {
- session_->connection()->CloseConnection(
- QUIC_TRANSPORT_INVALID_CLIENT_INDICATION,
- absl::StrCat("Client indication size exceeds ",
- ClientIndicationMaxSize(), " bytes"),
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
- return;
- }
- if (sequencer()->IsClosed()) {
- session_->ProcessClientIndication(buffer_);
- OnFinRead();
- }
-}
-
-bool QuicTransportServerSession::ClientIndicationParser::Parse() {
- bool origin_received = false;
- bool path_received = false;
- while (!reader_.IsDoneReading()) {
- uint16_t key;
- if (!reader_.ReadUInt16(&key)) {
- ParseError("Expected 16-bit key");
- return false;
- }
-
- absl::string_view value;
- if (!reader_.ReadStringPiece16(&value)) {
- ParseError(absl::StrCat("Failed to read value for key ", key));
- return false;
- }
-
- switch (static_cast<QuicTransportClientIndicationKeys>(key)) {
- case QuicTransportClientIndicationKeys::kOrigin: {
- GURL origin_url{std::string(value)};
- if (!origin_url.is_valid()) {
- Error("Unable to parse the specified origin");
- return false;
- }
-
- url::Origin origin = url::Origin::Create(origin_url);
- QUIC_DLOG(INFO) << "QuicTransport server received origin " << origin;
- if (!session_->visitor_->CheckOrigin(origin)) {
- Error("Origin check failed");
- return false;
- }
- origin_received = true;
- break;
- }
-
- case QuicTransportClientIndicationKeys::kPath: {
- if (!ProcessPath(value)) {
- return false;
- }
- path_received = true;
- break;
- }
-
- default:
- QUIC_DLOG(INFO) << "Unknown client indication key: " << key;
- break;
- }
- }
-
- if (!origin_received) {
- Error("No origin received");
- return false;
- }
- if (!path_received) {
- Error("No path received");
- return false;
- }
-
- return true;
-}
-
-bool QuicTransportServerSession::ClientIndicationParser::ProcessPath(
- absl::string_view path) {
- if (path.empty() || path[0] != '/') {
- // https://tools.ietf.org/html/draft-vvv-webtransport-quic-01#section-3.2.2
- Error("Path must begin with a '/'");
- return false;
- }
-
- // TODO(b/145674008): use the SNI value from the handshake instead of the IP
- // address.
- std::string url_text =
- absl::StrCat(url::kQuicTransportScheme, url::kStandardSchemeSeparator,
- session_->self_address().ToString(), path);
- GURL url{url_text};
- if (!url.is_valid()) {
- Error("Invalid path specified");
- return false;
- }
-
- if (!session_->visitor_->ProcessPath(url)) {
- Error("Specified path rejected");
- return false;
- }
- return true;
-}
-
-void QuicTransportServerSession::ClientIndicationParser::Error(
- const std::string& error_message) {
- session_->connection()->CloseConnection(
- QUIC_TRANSPORT_INVALID_CLIENT_INDICATION, error_message,
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
-}
-
-void QuicTransportServerSession::ClientIndicationParser::ParseError(
- absl::string_view error_message) {
- Error(absl::StrCat("Failed to parse the client indication stream: ",
- error_message, reader_.DebugString()));
-}
-
-void QuicTransportServerSession::ProcessClientIndication(
- absl::string_view indication) {
- ClientIndicationParser parser(this, indication);
- if (!parser.Parse()) {
- return;
- }
- // Don't set the ready bit if we closed the connection due to any error
- // beforehand.
- if (!connection()->connected()) {
- return;
- }
- ready_ = true;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/quic_transport/quic_transport_server_session.h b/chromium/net/third_party/quiche/src/quic/quic_transport/quic_transport_server_session.h
deleted file mode 100644
index 070cfdd5511..00000000000
--- a/chromium/net/third_party/quiche/src/quic/quic_transport/quic_transport_server_session.h
+++ /dev/null
@@ -1,122 +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_QUIC_TRANSPORT_QUIC_TRANSPORT_SERVER_SESSION_H_
-#define QUICHE_QUIC_QUIC_TRANSPORT_QUIC_TRANSPORT_SERVER_SESSION_H_
-
-#include "absl/strings/string_view.h"
-#include "url/gurl.h"
-#include "url/origin.h"
-#include "quic/core/quic_connection.h"
-#include "quic/core/quic_crypto_server_stream_base.h"
-#include "quic/core/quic_session.h"
-#include "quic/quic_transport/quic_transport_protocol.h"
-#include "quic/quic_transport/quic_transport_session_interface.h"
-#include "quic/quic_transport/quic_transport_stream.h"
-
-namespace quic {
-
-// A server session for the QuicTransport protocol.
-class QUIC_EXPORT_PRIVATE QuicTransportServerSession
- : public QuicSession,
- public QuicTransportSessionInterface {
- public:
- class QUIC_EXPORT_PRIVATE ServerVisitor {
- public:
- virtual ~ServerVisitor() {}
-
- // Allows the server to decide whether the specified origin is allowed to
- // connect to it.
- virtual bool CheckOrigin(url::Origin origin) = 0;
-
- // Indicates that the server received a path parameter from the client. The
- // path parameter is parsed, and can be retrived from url.path() and
- // url.query(). If this method returns false, the connection is closed.
- virtual bool ProcessPath(const GURL& url) = 0;
- };
-
- QuicTransportServerSession(QuicConnection* connection,
- Visitor* owner,
- const QuicConfig& config,
- const ParsedQuicVersionVector& supported_versions,
- const QuicCryptoServerConfig* crypto_config,
- QuicCompressedCertsCache* compressed_certs_cache,
- ServerVisitor* visitor);
-
- std::vector<absl::string_view>::const_iterator SelectAlpn(
- const std::vector<absl::string_view>& alpns) const override {
- return std::find(alpns.cbegin(), alpns.cend(), QuicTransportAlpn());
- }
-
- bool ShouldKeepConnectionAlive() const override { return true; }
-
- QuicCryptoServerStreamBase* GetMutableCryptoStream() override {
- return crypto_stream_.get();
- }
- const QuicCryptoServerStreamBase* GetCryptoStream() const override {
- return crypto_stream_.get();
- }
-
- // Returns true once the encryption has been established, the client
- // indication has been received and the origin has been verified. No
- // application data will be read or written before the connection is ready.
- // Once the connection becomes ready, this method will never return false.
- bool IsSessionReady() const override { return ready_; }
-
- QuicStream* CreateIncomingStream(QuicStreamId id) override;
- QuicStream* CreateIncomingStream(PendingStream* /*pending*/) override {
- QUIC_BUG(quic_bug_10884_1)
- << "QuicTransportServerSession::CreateIncomingStream("
- "PendingStream) not implemented";
- return nullptr;
- }
-
- protected:
- class QUIC_EXPORT_PRIVATE ClientIndication : public QuicStream {
- public:
- explicit ClientIndication(QuicTransportServerSession* session);
- void OnDataAvailable() override;
-
- private:
- QuicTransportServerSession* session_;
- std::string buffer_;
- };
-
- // Utility class for parsing the client indication.
- class QUIC_EXPORT_PRIVATE ClientIndicationParser {
- public:
- ClientIndicationParser(QuicTransportServerSession* session,
- absl::string_view indication)
- : session_(session), reader_(indication) {}
-
- // Parses the specified indication. Automatically closes the connection
- // with detailed error if parsing fails. Returns true on success, false on
- // failure.
- bool Parse();
-
- private:
- void Error(const std::string& error_message);
- void ParseError(absl::string_view error_message);
-
- // Processes the path portion of the client indication.
- bool ProcessPath(absl::string_view path);
-
- QuicTransportServerSession* session_;
- QuicDataReader reader_;
- };
-
- // Parses and processes the client indication as described in
- // https://vasilvv.github.io/webtransport/draft-vvv-webtransport-quic.html#rfc.section.3.2
- void ProcessClientIndication(absl::string_view indication);
-
- virtual void OnIncomingDataStream(QuicTransportStream* /*stream*/) {}
-
- std::unique_ptr<QuicCryptoServerStreamBase> crypto_stream_;
- bool ready_ = false;
- ServerVisitor* visitor_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_QUIC_TRANSPORT_QUIC_TRANSPORT_SERVER_SESSION_H_
diff --git a/chromium/net/third_party/quiche/src/quic/quic_transport/quic_transport_server_session_test.cc b/chromium/net/third_party/quiche/src/quic/quic_transport/quic_transport_server_session_test.cc
deleted file mode 100644
index 159f8864fd8..00000000000
--- a/chromium/net/third_party/quiche/src/quic/quic_transport/quic_transport_server_session_test.cc
+++ /dev/null
@@ -1,291 +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 "quic/quic_transport/quic_transport_server_session.h"
-
-#include <cstddef>
-#include <memory>
-#include <string>
-
-#include "absl/strings/string_view.h"
-#include "url/gurl.h"
-#include "url/origin.h"
-#include "quic/core/crypto/quic_compressed_certs_cache.h"
-#include "quic/core/crypto/quic_crypto_server_config.h"
-#include "quic/core/frames/quic_stream_frame.h"
-#include "quic/core/quic_data_writer.h"
-#include "quic/core/quic_versions.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/quic_transport/quic_transport_protocol.h"
-#include "quic/test_tools/crypto_test_utils.h"
-#include "quic/test_tools/quic_test_utils.h"
-#include "quic/test_tools/quic_transport_test_tools.h"
-#include "common/quiche_text_utils.h"
-
-namespace quic {
-namespace test {
-namespace {
-
-using testing::_;
-using testing::AnyNumber;
-using testing::DoAll;
-using testing::HasSubstr;
-using testing::Return;
-using testing::SaveArg;
-
-constexpr char kTestOrigin[] = "https://test-origin.test";
-constexpr char kTestOriginClientIndication[] =
- "\0\0" // key (0x0000, origin)
- "\0\x18" // length
- "https://test-origin.test" // value
- "\0\x01" // key (0x0001, path)
- "\0\x05" // length
- "/test"; // value
-const url::Origin GetTestOrigin() {
- return url::Origin::Create(GURL(kTestOrigin));
-}
-const std::string GetTestOriginClientIndication() {
- return std::string(kTestOriginClientIndication,
- sizeof(kTestOriginClientIndication) - 1);
-}
-
-ParsedQuicVersionVector GetVersions() {
- return {DefaultVersionForQuicTransport()};
-}
-
-class QuicTransportServerSessionTest : public QuicTest {
- public:
- QuicTransportServerSessionTest()
- : connection_(&helper_,
- &alarm_factory_,
- Perspective::IS_SERVER,
- GetVersions()),
- crypto_config_(QuicCryptoServerConfig::TESTING,
- QuicRandom::GetInstance(),
- crypto_test_utils::ProofSourceForTesting(),
- KeyExchangeSource::Default()),
- compressed_certs_cache_(
- QuicCompressedCertsCache::kQuicCompressedCertsCacheSize) {
- QuicEnableVersion(DefaultVersionForQuicTransport());
- connection_.AdvanceTime(QuicTime::Delta::FromSeconds(100000));
- crypto_test_utils::SetupCryptoServerConfigForTest(
- helper_.GetClock(), helper_.GetRandomGenerator(), &crypto_config_);
- session_ = std::make_unique<QuicTransportServerSession>(
- &connection_, nullptr, DefaultQuicConfig(), GetVersions(),
- &crypto_config_, &compressed_certs_cache_, &visitor_);
- session_->Initialize();
- crypto_stream_ = session_->GetMutableCryptoStream();
- ON_CALL(visitor_, ProcessPath(_))
- .WillByDefault(DoAll(SaveArg<0>(&path_), Return(true)));
- }
-
- void Connect() {
- crypto_test_utils::FakeClientOptions options;
- options.only_tls_versions = true;
- crypto_test_utils::HandshakeWithFakeClient(
- &helper_, &alarm_factory_, &connection_, crypto_stream_,
- QuicServerId("test.example.com", 443), options, QuicTransportAlpn());
- }
-
- void ReceiveIndication(absl::string_view indication) {
- QUIC_LOG(INFO) << "Receiving indication: "
- << quiche::QuicheTextUtils::HexDump(indication);
- constexpr size_t kChunkSize = 1024;
- // Shard the indication, since some of the tests cause it to not fit into a
- // single frame.
- for (size_t i = 0; i < indication.size(); i += kChunkSize) {
- QuicStreamFrame frame(ClientIndicationStream(), /*fin=*/false, i,
- indication.substr(i, i + kChunkSize));
- session_->OnStreamFrame(frame);
- }
- session_->OnStreamFrame(QuicStreamFrame(ClientIndicationStream(),
- /*fin=*/true, indication.size(),
- absl::string_view()));
- }
-
- void ReceiveIndicationWithPath(absl::string_view path) {
- constexpr char kTestOriginClientIndicationPrefix[] =
- "\0\0" // key (0x0000, origin)
- "\0\x18" // length
- "https://test-origin.test" // value
- "\0\x01"; // key (0x0001, path)
- std::string indication{kTestOriginClientIndicationPrefix,
- sizeof(kTestOriginClientIndicationPrefix) - 1};
- indication.push_back(static_cast<char>(path.size() >> 8));
- indication.push_back(static_cast<char>(path.size() & 0xff));
- indication += std::string{path};
- ReceiveIndication(indication);
- }
-
- protected:
- MockAlarmFactory alarm_factory_;
- MockQuicConnectionHelper helper_;
-
- PacketSavingConnection connection_;
- QuicCryptoServerConfig crypto_config_;
- std::unique_ptr<QuicTransportServerSession> session_;
- QuicCompressedCertsCache compressed_certs_cache_;
- testing::NiceMock<MockServerVisitor> visitor_;
- QuicCryptoServerStreamBase* crypto_stream_;
- GURL path_;
-};
-
-TEST_F(QuicTransportServerSessionTest, SuccessfulHandshake) {
- Connect();
-
- url::Origin origin;
- EXPECT_CALL(visitor_, CheckOrigin(_))
- .WillOnce(DoAll(SaveArg<0>(&origin), Return(true)));
- ReceiveIndication(GetTestOriginClientIndication());
- EXPECT_TRUE(session_->IsSessionReady());
- EXPECT_EQ(origin, GetTestOrigin());
- EXPECT_EQ(path_.path(), "/test");
-}
-
-TEST_F(QuicTransportServerSessionTest, PiecewiseClientIndication) {
- Connect();
- size_t i = 0;
- for (; i < sizeof(kTestOriginClientIndication) - 2; i++) {
- QuicStreamFrame frame(
- ClientIndicationStream(), false, i,
- absl::string_view(&kTestOriginClientIndication[i], 1));
- session_->OnStreamFrame(frame);
- }
-
- EXPECT_CALL(visitor_, CheckOrigin(_)).WillOnce(Return(true));
- QuicStreamFrame last_frame(
- ClientIndicationStream(), true, i,
- absl::string_view(&kTestOriginClientIndication[i], 1));
- session_->OnStreamFrame(last_frame);
- EXPECT_TRUE(session_->IsSessionReady());
-}
-
-TEST_F(QuicTransportServerSessionTest, OriginRejected) {
- Connect();
- EXPECT_CALL(connection_,
- CloseConnection(_, HasSubstr("Origin check failed"), _));
- EXPECT_CALL(visitor_, CheckOrigin(_)).WillOnce(Return(false));
- ReceiveIndication(GetTestOriginClientIndication());
- EXPECT_FALSE(session_->IsSessionReady());
-}
-
-std::string MakeUnknownField(absl::string_view payload) {
- std::string buffer;
- buffer.resize(payload.size() + 4);
- QuicDataWriter writer(buffer.size(), &buffer[0]);
- EXPECT_TRUE(writer.WriteUInt16(0xffff));
- EXPECT_TRUE(writer.WriteUInt16(payload.size()));
- EXPECT_TRUE(writer.WriteStringPiece(payload));
- EXPECT_EQ(writer.remaining(), 0u);
- return buffer;
-}
-
-TEST_F(QuicTransportServerSessionTest, SkipUnusedFields) {
- Connect();
- EXPECT_CALL(visitor_, CheckOrigin(_)).WillOnce(Return(true));
- ReceiveIndication(GetTestOriginClientIndication() +
- MakeUnknownField("foobar"));
- EXPECT_TRUE(session_->IsSessionReady());
-}
-
-TEST_F(QuicTransportServerSessionTest, SkipLongUnusedFields) {
- const size_t bytes =
- ClientIndicationMaxSize() - GetTestOriginClientIndication().size() - 4;
- Connect();
- EXPECT_CALL(visitor_, CheckOrigin(_)).WillOnce(Return(true));
- ReceiveIndication(GetTestOriginClientIndication() +
- MakeUnknownField(std::string(bytes, 'a')));
- EXPECT_TRUE(session_->IsSessionReady());
-}
-
-TEST_F(QuicTransportServerSessionTest, ClientIndicationTooLong) {
- Connect();
- EXPECT_CALL(
- connection_,
- CloseConnection(_, HasSubstr("Client indication size exceeds"), _))
- .Times(AnyNumber());
- ReceiveIndication(GetTestOriginClientIndication() +
- MakeUnknownField(std::string(65534, 'a')));
- EXPECT_FALSE(session_->IsSessionReady());
-}
-
-TEST_F(QuicTransportServerSessionTest, NoOrigin) {
- Connect();
- EXPECT_CALL(connection_, CloseConnection(_, HasSubstr("No origin"), _));
- ReceiveIndication(MakeUnknownField("foobar"));
- EXPECT_FALSE(session_->IsSessionReady());
-}
-
-TEST_F(QuicTransportServerSessionTest, EmptyClientIndication) {
- Connect();
- EXPECT_CALL(connection_, CloseConnection(_, HasSubstr("No origin"), _));
- ReceiveIndication("");
- EXPECT_FALSE(session_->IsSessionReady());
-}
-
-TEST_F(QuicTransportServerSessionTest, MalformedIndicationHeader) {
- Connect();
- EXPECT_CALL(connection_,
- CloseConnection(_, HasSubstr("Expected 16-bit key"), _));
- ReceiveIndication("\xff");
- EXPECT_FALSE(session_->IsSessionReady());
-}
-
-TEST_F(QuicTransportServerSessionTest, FieldTooShort) {
- Connect();
- EXPECT_CALL(
- connection_,
- CloseConnection(_, HasSubstr("Failed to read value for key 257"), _));
- ReceiveIndication("\x01\x01\x01\x01");
- EXPECT_FALSE(session_->IsSessionReady());
-}
-
-TEST_F(QuicTransportServerSessionTest, InvalidOrigin) {
- const std::string kEmptyOriginIndication(4, '\0');
- Connect();
- EXPECT_CALL(
- connection_,
- CloseConnection(_, HasSubstr("Unable to parse the specified origin"), _));
- ReceiveIndication(kEmptyOriginIndication);
- EXPECT_FALSE(session_->IsSessionReady());
-}
-
-TEST_F(QuicTransportServerSessionTest, PathWithQuery) {
- Connect();
- EXPECT_CALL(visitor_, CheckOrigin(_)).WillOnce(Return(true));
- ReceiveIndicationWithPath("/test?foo=bar");
- EXPECT_TRUE(session_->IsSessionReady());
- EXPECT_EQ(path_.path(), "/test");
- EXPECT_EQ(path_.query(), "foo=bar");
-}
-
-TEST_F(QuicTransportServerSessionTest, PathNormalization) {
- Connect();
- EXPECT_CALL(visitor_, CheckOrigin(_)).WillOnce(Return(true));
- ReceiveIndicationWithPath("/foo/../bar");
- EXPECT_TRUE(session_->IsSessionReady());
- EXPECT_EQ(path_.path(), "/bar");
-}
-
-TEST_F(QuicTransportServerSessionTest, EmptyPath) {
- Connect();
- EXPECT_CALL(visitor_, CheckOrigin(_)).WillOnce(Return(true));
- EXPECT_CALL(connection_,
- CloseConnection(_, HasSubstr("Path must begin with a '/'"), _));
- ReceiveIndicationWithPath("");
- EXPECT_FALSE(session_->IsSessionReady());
-}
-
-TEST_F(QuicTransportServerSessionTest, UnprefixedPath) {
- Connect();
- EXPECT_CALL(visitor_, CheckOrigin(_)).WillOnce(Return(true));
- EXPECT_CALL(connection_,
- CloseConnection(_, HasSubstr("Path must begin with a '/'"), _));
- ReceiveIndicationWithPath("test");
- EXPECT_FALSE(session_->IsSessionReady());
-}
-
-} // namespace
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/quic_transport/quic_transport_session_interface.h b/chromium/net/third_party/quiche/src/quic/quic_transport/quic_transport_session_interface.h
deleted file mode 100644
index d08aa6ce7c2..00000000000
--- a/chromium/net/third_party/quiche/src/quic/quic_transport/quic_transport_session_interface.h
+++ /dev/null
@@ -1,27 +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_QUIC_TRANSPORT_QUIC_TRANSPORT_SESSION_INTERFACE_H_
-#define QUICHE_QUIC_QUIC_TRANSPORT_QUIC_TRANSPORT_SESSION_INTERFACE_H_
-
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// Shared interface between QuicTransportClientSession and
-// QuicTransportServerSession.
-class QUIC_EXPORT_PRIVATE QuicTransportSessionInterface {
- public:
- virtual ~QuicTransportSessionInterface() {}
-
- // Indicates whether the client indication has been sent/received and the
- // connection is thus ready to send/receive application data. Note that the
- // expectation for this API is that once it becomes true, it will never
- // transition to false.
- virtual bool IsSessionReady() const = 0;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_QUIC_TRANSPORT_QUIC_TRANSPORT_SESSION_INTERFACE_H_
diff --git a/chromium/net/third_party/quiche/src/quic/quic_transport/quic_transport_stream.cc b/chromium/net/third_party/quiche/src/quic/quic_transport/quic_transport_stream.cc
deleted file mode 100644
index 4def1dead0f..00000000000
--- a/chromium/net/third_party/quiche/src/quic/quic_transport/quic_transport_stream.cc
+++ /dev/null
@@ -1,89 +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 "quic/quic_transport/quic_transport_stream.h"
-
-#include <sys/types.h>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_buffer_allocator.h"
-#include "quic/core/quic_error_codes.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_utils.h"
-
-namespace quic {
-
-QuicTransportStream::QuicTransportStream(
- QuicStreamId id,
- QuicSession* session,
- QuicTransportSessionInterface* session_interface)
- : QuicStream(id,
- session,
- /*is_static=*/false,
- QuicUtils::GetStreamType(id,
- session->connection()->perspective(),
- session->IsIncomingStream(id),
- session->version())),
- adapter_(session, this, sequencer()),
- session_interface_(session_interface) {}
-
-WebTransportStream::ReadResult QuicTransportStream::Read(char* buffer,
- size_t buffer_size) {
- if (!session_interface_->IsSessionReady()) {
- return ReadResult{0, false};
- }
-
- return adapter_.Read(buffer, buffer_size);
-}
-
-WebTransportStream::ReadResult QuicTransportStream::Read(std::string* output) {
- if (!session_interface_->IsSessionReady()) {
- return ReadResult{0, false};
- }
-
- return adapter_.Read(output);
-}
-
-bool QuicTransportStream::Write(absl::string_view data) {
- if (!CanWrite()) {
- return false;
- }
-
- return adapter_.Write(data);
-}
-
-bool QuicTransportStream::SendFin() {
- if (!CanWrite()) {
- return false;
- }
-
- return adapter_.SendFin();
-}
-
-bool QuicTransportStream::CanWrite() const {
- return session_interface_->IsSessionReady() && adapter_.CanWrite();
-}
-
-size_t QuicTransportStream::ReadableBytes() const {
- if (!session_interface_->IsSessionReady()) {
- return 0;
- }
-
- return adapter_.ReadableBytes();
-}
-
-void QuicTransportStream::OnDataAvailable() {
- adapter_.OnDataAvailable();
-}
-
-void QuicTransportStream::OnCanWriteNewData() {
- // Ensure the origin check has been completed, as the stream can be notified
- // about being writable before that.
- if (!CanWrite()) {
- return;
- }
- adapter_.OnCanWriteNewData();
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/quic_transport/quic_transport_stream.h b/chromium/net/third_party/quiche/src/quic/quic_transport/quic_transport_stream.h
deleted file mode 100644
index 5d574afe3c4..00000000000
--- a/chromium/net/third_party/quiche/src/quic/quic_transport/quic_transport_stream.h
+++ /dev/null
@@ -1,84 +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_QUIC_TRANSPORT_QUIC_TRANSPORT_STREAM_H_
-#define QUICHE_QUIC_QUIC_TRANSPORT_QUIC_TRANSPORT_STREAM_H_
-
-#include <cstddef>
-#include <memory>
-
-#include "absl/base/attributes.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/http/web_transport_stream_adapter.h"
-#include "quic/core/quic_session.h"
-#include "quic/core/quic_stream.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/web_transport_interface.h"
-#include "quic/quic_transport/quic_transport_session_interface.h"
-
-namespace quic {
-
-// QuicTransportStream is an extension of QuicStream that provides I/O interface
-// that is safe to use in the QuicTransport context. The interface ensures no
-// application data is processed before the client indication is processed.
-class QUIC_EXPORT_PRIVATE QuicTransportStream : public QuicStream,
- public WebTransportStream {
- public:
- QuicTransportStream(QuicStreamId id,
- QuicSession* session,
- QuicTransportSessionInterface* session_interface);
-
- // Reads at most |buffer_size| bytes into |buffer| and returns the number of
- // bytes actually read.
- ReadResult Read(char* buffer, size_t buffer_size) override;
- // Reads all available data and appends it to the end of |output|.
- ReadResult Read(std::string* output) override;
- // Writes |data| into the stream. Returns true on success.
- ABSL_MUST_USE_RESULT bool Write(absl::string_view data) override;
- // Sends the FIN on the stream. Returns true on success.
- ABSL_MUST_USE_RESULT bool SendFin() override;
-
- // Indicates whether it is possible to write into stream right now.
- bool CanWrite() const override;
- // Indicates the number of bytes that can be read from the stream.
- size_t ReadableBytes() const override;
-
- // QuicSession method implementations.
- void OnDataAvailable() override;
- void OnCanWriteNewData() override;
-
- QuicStreamId GetStreamId() const override { return id(); }
-
- void ResetWithUserCode(WebTransportStreamError /*error*/) override {
- adapter_.ResetWithUserCode(0);
- }
- void ResetDueToInternalError() override {
- adapter_.ResetDueToInternalError();
- }
- void SendStopSending(WebTransportStreamError /*error*/) override {
- adapter_.SendStopSending(0);
- }
- void MaybeResetDueToStreamObjectGone() override {
- adapter_.MaybeResetDueToStreamObjectGone();
- }
-
- WebTransportStreamVisitor* visitor() override { return adapter_.visitor(); }
- void SetVisitor(std::unique_ptr<WebTransportStreamVisitor> visitor) override {
- adapter_.SetVisitor(std::move(visitor));
- }
-
- protected:
- // Hide the methods that allow writing data without checking IsSessionReady().
- using QuicStream::WriteMemSlices;
- using QuicStream::WriteOrBufferData;
-
- void MaybeNotifyFinRead();
-
- WebTransportStreamAdapter adapter_;
- QuicTransportSessionInterface* session_interface_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_QUIC_TRANSPORT_QUIC_TRANSPORT_STREAM_H_
diff --git a/chromium/net/third_party/quiche/src/quic/quic_transport/quic_transport_stream_test.cc b/chromium/net/third_party/quiche/src/quic/quic_transport/quic_transport_stream_test.cc
deleted file mode 100644
index b93e0eb430a..00000000000
--- a/chromium/net/third_party/quiche/src/quic/quic_transport/quic_transport_stream_test.cc
+++ /dev/null
@@ -1,177 +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 "quic/quic_transport/quic_transport_stream.h"
-
-#include <memory>
-
-#include "absl/memory/memory.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/crypto/null_encrypter.h"
-#include "quic/core/frames/quic_window_update_frame.h"
-#include "quic/platform/api/quic_expect_bug.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/quic_transport/quic_transport_session_interface.h"
-#include "quic/test_tools/quic_config_peer.h"
-#include "quic/test_tools/quic_test_utils.h"
-#include "quic/test_tools/quic_transport_test_tools.h"
-
-namespace quic {
-namespace test {
-namespace {
-
-using testing::_;
-using testing::Return;
-
-ParsedQuicVersionVector GetVersions() {
- return {DefaultVersionForQuicTransport()};
-}
-
-class MockQuicTransportSessionInterface : public QuicTransportSessionInterface {
- public:
- MOCK_METHOD(bool, IsSessionReady, (), (const, override));
-};
-
-class QuicTransportStreamTest : public QuicTest {
- public:
- QuicTransportStreamTest()
- : connection_(new MockQuicConnection(&helper_,
- &alarm_factory_,
- Perspective::IS_CLIENT,
- GetVersions())),
- session_(connection_) {
- QuicEnableVersion(DefaultVersionForQuicTransport());
- session_.Initialize();
- connection_->SetEncrypter(
- ENCRYPTION_FORWARD_SECURE,
- std::make_unique<NullEncrypter>(connection_->perspective()));
- stream_ = new QuicTransportStream(0, &session_, &interface_);
- session_.ActivateStream(absl::WrapUnique(stream_));
-
- auto visitor = std::make_unique<MockStreamVisitor>();
- visitor_ = visitor.get();
- stream_->SetVisitor(std::move(visitor));
- }
-
- void ReceiveStreamData(absl::string_view data, QuicStreamOffset offset) {
- QuicStreamFrame frame(0, false, offset, data);
- stream_->OnStreamFrame(frame);
- }
-
- protected:
- MockAlarmFactory alarm_factory_;
- MockQuicConnectionHelper helper_;
-
- MockQuicConnection* connection_; // Owned by |session_|.
- MockQuicSession session_;
- MockQuicTransportSessionInterface interface_;
- QuicTransportStream* stream_; // Owned by |session_|.
- MockStreamVisitor* visitor_; // Owned by |stream_|.
-};
-
-TEST_F(QuicTransportStreamTest, NotReady) {
- EXPECT_CALL(interface_, IsSessionReady()).WillRepeatedly(Return(false));
- ReceiveStreamData("test", 0);
- EXPECT_EQ(stream_->ReadableBytes(), 0u);
- EXPECT_FALSE(stream_->CanWrite());
-}
-
-TEST_F(QuicTransportStreamTest, ReadWhenNotReady) {
- EXPECT_CALL(interface_, IsSessionReady()).WillRepeatedly(Return(false));
- ReceiveStreamData("test", 0);
- char buffer[4];
- WebTransportStream::ReadResult result = stream_->Read(buffer, sizeof(buffer));
- EXPECT_EQ(result.bytes_read, 0u);
- EXPECT_FALSE(result.fin);
-}
-
-TEST_F(QuicTransportStreamTest, WriteWhenNotReady) {
- EXPECT_CALL(interface_, IsSessionReady()).WillRepeatedly(Return(false));
- EXPECT_FALSE(stream_->Write("test"));
-}
-
-TEST_F(QuicTransportStreamTest, Ready) {
- EXPECT_CALL(interface_, IsSessionReady()).WillRepeatedly(Return(true));
- ReceiveStreamData("test", 0);
- EXPECT_EQ(stream_->ReadableBytes(), 4u);
- EXPECT_TRUE(stream_->CanWrite());
- EXPECT_TRUE(stream_->Write("test"));
-}
-
-TEST_F(QuicTransportStreamTest, ReceiveData) {
- EXPECT_CALL(interface_, IsSessionReady()).WillRepeatedly(Return(true));
- EXPECT_CALL(*visitor_, OnCanRead());
- ReceiveStreamData("test", 0);
-
- std::string buffer;
- WebTransportStream::ReadResult result = stream_->Read(&buffer);
- EXPECT_EQ(result.bytes_read, 4u);
- EXPECT_FALSE(result.fin);
- EXPECT_EQ(buffer, "test");
-}
-
-TEST_F(QuicTransportStreamTest, FinReadWithNoDataPending) {
- EXPECT_CALL(interface_, IsSessionReady()).WillRepeatedly(Return(true));
- EXPECT_CALL(*visitor_, OnCanRead());
-
- QuicStreamFrame frame(0, true, 0, "");
- stream_->OnStreamFrame(frame);
-
- std::string buffer;
- WebTransportStream::ReadResult result = stream_->Read(&buffer);
- EXPECT_EQ(result.bytes_read, 0u);
- EXPECT_TRUE(result.fin);
- EXPECT_EQ(buffer, "");
-}
-
-TEST_F(QuicTransportStreamTest, FinReadWithDataPending) {
- EXPECT_CALL(interface_, IsSessionReady()).WillRepeatedly(Return(true));
-
- EXPECT_CALL(*visitor_, OnCanRead());
- QuicStreamFrame frame(0, true, 0, "test");
- stream_->OnStreamFrame(frame);
-
- char buffer[2];
- WebTransportStream::ReadResult result = stream_->Read(buffer, sizeof(buffer));
- EXPECT_EQ(result.bytes_read, 2u);
- EXPECT_FALSE(result.fin);
- EXPECT_EQ(buffer[0], 't');
- EXPECT_EQ(buffer[1], 'e');
-
- result = stream_->Read(buffer, sizeof(buffer));
- EXPECT_EQ(result.bytes_read, 2u);
- EXPECT_TRUE(result.fin);
- EXPECT_EQ(buffer[0], 's');
- EXPECT_EQ(buffer[1], 't');
-}
-
-TEST_F(QuicTransportStreamTest, WritingTooMuchData) {
- EXPECT_CALL(interface_, IsSessionReady()).WillRepeatedly(Return(true));
- ASSERT_TRUE(stream_->CanWrite());
-
- std::string a_little_bit_of_data(128, 'A');
- std::string a_lot_of_data(GetQuicFlag(FLAGS_quic_buffered_data_threshold) * 2,
- 'a');
-
- EXPECT_TRUE(stream_->Write(a_little_bit_of_data));
- EXPECT_TRUE(stream_->Write(a_little_bit_of_data));
- EXPECT_TRUE(stream_->Write(a_little_bit_of_data));
-
- EXPECT_TRUE(stream_->Write(a_lot_of_data));
- EXPECT_FALSE(stream_->Write(a_lot_of_data));
-}
-
-TEST_F(QuicTransportStreamTest, CannotSendFinTwice) {
- EXPECT_CALL(interface_, IsSessionReady()).WillRepeatedly(Return(true));
- ASSERT_TRUE(stream_->CanWrite());
-
- EXPECT_CALL(session_, WritevData(stream_->id(), _, _, _, _, _))
- .WillOnce(Return(QuicConsumedData(0, /*fin_consumed=*/true)));
- EXPECT_TRUE(stream_->SendFin());
- EXPECT_FALSE(stream_->CanWrite());
-}
-
-} // namespace
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/quic_transport/web_transport_fingerprint_proof_verifier.cc b/chromium/net/third_party/quiche/src/quic/quic_transport/web_transport_fingerprint_proof_verifier.cc
deleted file mode 100644
index 649406a914d..00000000000
--- a/chromium/net/third_party/quiche/src/quic/quic_transport/web_transport_fingerprint_proof_verifier.cc
+++ /dev/null
@@ -1,229 +0,0 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/quic_transport/web_transport_fingerprint_proof_verifier.h"
-
-#include <cstdint>
-#include <memory>
-
-#include "absl/strings/escaping.h"
-#include "absl/strings/str_cat.h"
-#include "absl/strings/str_replace.h"
-#include "absl/strings/string_view.h"
-#include "third_party/boringssl/src/include/openssl/sha.h"
-#include "quic/core/crypto/certificate_view.h"
-#include "quic/core/quic_time.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "common/quiche_text_utils.h"
-
-namespace quic {
-namespace {
-
-constexpr size_t kFingerprintLength = SHA256_DIGEST_LENGTH * 3 - 1;
-
-// Assumes that the character is normalized to lowercase beforehand.
-bool IsNormalizedHexDigit(char c) {
- return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f');
-}
-
-void NormalizeFingerprint(CertificateFingerprint& fingerprint) {
- fingerprint.fingerprint =
- quiche::QuicheTextUtils::ToLower(fingerprint.fingerprint);
-}
-
-} // namespace
-
-constexpr char CertificateFingerprint::kSha256[];
-constexpr char WebTransportHash::kSha256[];
-
-ProofVerifyDetails* WebTransportFingerprintProofVerifier::Details::Clone()
- const {
- return new Details(*this);
-}
-
-WebTransportFingerprintProofVerifier::WebTransportFingerprintProofVerifier(
- const QuicClock* clock, int max_validity_days)
- : clock_(clock),
- max_validity_days_(max_validity_days),
- // Add an extra second to max validity to accomodate various edge cases.
- max_validity_(
- QuicTime::Delta::FromSeconds(max_validity_days * 86400 + 1)) {}
-
-bool WebTransportFingerprintProofVerifier::AddFingerprint(
- CertificateFingerprint fingerprint) {
- NormalizeFingerprint(fingerprint);
- if (fingerprint.algorithm != CertificateFingerprint::kSha256) {
- QUIC_DLOG(WARNING) << "Algorithms other than SHA-256 are not supported";
- return false;
- }
- if (fingerprint.fingerprint.size() != kFingerprintLength) {
- QUIC_DLOG(WARNING) << "Invalid fingerprint length";
- return false;
- }
- for (size_t i = 0; i < fingerprint.fingerprint.size(); i++) {
- char current = fingerprint.fingerprint[i];
- if (i % 3 == 2) {
- if (current != ':') {
- QUIC_DLOG(WARNING)
- << "Missing colon separator between the bytes of the hash";
- return false;
- }
- } else {
- if (!IsNormalizedHexDigit(current)) {
- QUIC_DLOG(WARNING) << "Fingerprint must be in hexadecimal";
- return false;
- }
- }
- }
-
- std::string normalized =
- absl::StrReplaceAll(fingerprint.fingerprint, {{":", ""}});
- hashes_.push_back(WebTransportHash{fingerprint.algorithm,
- absl::HexStringToBytes(normalized)});
- return true;
-}
-
-bool WebTransportFingerprintProofVerifier::AddFingerprint(
- WebTransportHash hash) {
- if (hash.algorithm != CertificateFingerprint::kSha256) {
- QUIC_DLOG(WARNING) << "Algorithms other than SHA-256 are not supported";
- return false;
- }
- if (hash.value.size() != SHA256_DIGEST_LENGTH) {
- QUIC_DLOG(WARNING) << "Invalid fingerprint length";
- return false;
- }
- hashes_.push_back(std::move(hash));
- return true;
-}
-
-QuicAsyncStatus WebTransportFingerprintProofVerifier::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*/) {
- *error_details =
- "QUIC crypto certificate verification is not supported in "
- "WebTransportFingerprintProofVerifier";
- QUIC_BUG(quic_bug_10879_1) << *error_details;
- *details = std::make_unique<Details>(Status::kInternalError);
- return QUIC_FAILURE;
-}
-
-QuicAsyncStatus WebTransportFingerprintProofVerifier::VerifyCertChain(
- const std::string& /*hostname*/, const uint16_t /*port*/,
- const std::vector<std::string>& certs, const std::string& /*ocsp_response*/,
- const std::string& /*cert_sct*/, const ProofVerifyContext* /*context*/,
- std::string* error_details, std::unique_ptr<ProofVerifyDetails>* details,
- uint8_t* /*out_alert*/,
- std::unique_ptr<ProofVerifierCallback> /*callback*/) {
- if (certs.empty()) {
- *details = std::make_unique<Details>(Status::kInternalError);
- *error_details = "No certificates provided";
- return QUIC_FAILURE;
- }
-
- if (!HasKnownFingerprint(certs[0])) {
- *details = std::make_unique<Details>(Status::kUnknownFingerprint);
- *error_details = "Certificate does not match any fingerprint";
- return QUIC_FAILURE;
- }
-
- std::unique_ptr<CertificateView> view =
- CertificateView::ParseSingleCertificate(certs[0]);
- if (view == nullptr) {
- *details = std::make_unique<Details>(Status::kCertificateParseFailure);
- *error_details = "Failed to parse the certificate";
- return QUIC_FAILURE;
- }
-
- if (!HasValidExpiry(*view)) {
- *details = std::make_unique<Details>(Status::kExpiryTooLong);
- *error_details =
- absl::StrCat("Certificate expiry exceeds the configured limit of ",
- max_validity_days_, " days");
- return QUIC_FAILURE;
- }
-
- if (!IsWithinValidityPeriod(*view)) {
- *details = std::make_unique<Details>(Status::kExpired);
- *error_details =
- "Certificate has expired or has validity listed in the future";
- return QUIC_FAILURE;
- }
-
- if (!IsKeyTypeAllowedByPolicy(*view)) {
- *details = std::make_unique<Details>(Status::kDisallowedKeyAlgorithm);
- *error_details =
- absl::StrCat("Certificate uses a disallowed public key type (",
- PublicKeyTypeToString(view->public_key_type()), ")");
- return QUIC_FAILURE;
- }
-
- *details = std::make_unique<Details>(Status::kValidCertificate);
- return QUIC_SUCCESS;
-}
-
-std::unique_ptr<ProofVerifyContext>
-WebTransportFingerprintProofVerifier::CreateDefaultContext() {
- return nullptr;
-}
-
-bool WebTransportFingerprintProofVerifier::HasKnownFingerprint(
- absl::string_view der_certificate) {
- // https://w3c.github.io/webtransport/#verify-a-certificate-hash
- const std::string hash = RawSha256(der_certificate);
- for (const WebTransportHash& reference : hashes_) {
- if (reference.algorithm != WebTransportHash::kSha256) {
- QUIC_BUG(quic_bug_10879_2) << "Unexpected non-SHA-256 hash";
- continue;
- }
- if (hash == reference.value) {
- return true;
- }
- }
- return false;
-}
-
-bool WebTransportFingerprintProofVerifier::HasValidExpiry(
- const CertificateView& certificate) {
- if (!certificate.validity_start().IsBefore(certificate.validity_end())) {
- return false;
- }
-
- const QuicTime::Delta duration_seconds =
- certificate.validity_end() - certificate.validity_start();
- return duration_seconds <= max_validity_;
-}
-
-bool WebTransportFingerprintProofVerifier::IsWithinValidityPeriod(
- const CertificateView& certificate) {
- QuicWallTime now = clock_->WallNow();
- return now.IsAfter(certificate.validity_start()) &&
- now.IsBefore(certificate.validity_end());
-}
-
-bool WebTransportFingerprintProofVerifier::IsKeyTypeAllowedByPolicy(
- const CertificateView& certificate) {
- switch (certificate.public_key_type()) {
- // https://github.com/w3c/webtransport/pull/375 defines P-256 as an MTI
- // algorithm, and prohibits RSA. We also allow P-384 and Ed25519.
- case PublicKeyType::kP256:
- case PublicKeyType::kP384:
- case PublicKeyType::kEd25519:
- return true;
- case PublicKeyType::kRsa:
- // TODO(b/213614428): this should be false by default.
- return true;
- default:
- return false;
- }
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/quic_transport/web_transport_fingerprint_proof_verifier.h b/chromium/net/third_party/quiche/src/quic/quic_transport/web_transport_fingerprint_proof_verifier.h
deleted file mode 100644
index 9a03c665818..00000000000
--- a/chromium/net/third_party/quiche/src/quic/quic_transport/web_transport_fingerprint_proof_verifier.h
+++ /dev/null
@@ -1,135 +0,0 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_QUIC_TRANSPORT_FINGERPRINT_PROOF_VERIFIER_H_
-#define QUICHE_QUIC_QUIC_TRANSPORT_FINGERPRINT_PROOF_VERIFIER_H_
-
-#include <vector>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/crypto/certificate_view.h"
-#include "quic/core/crypto/proof_verifier.h"
-#include "quic/core/quic_clock.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// Represents a fingerprint of an X.509 certificate in a format based on
-// https://w3c.github.io/webrtc-pc/#dom-rtcdtlsfingerprint.
-// TODO(vasilvv): remove this once all consumers of this API use
-// WebTransportHash.
-struct QUIC_EXPORT_PRIVATE CertificateFingerprint {
- static constexpr char kSha256[] = "sha-256";
-
- // An algorithm described by one of the names in
- // https://www.iana.org/assignments/hash-function-text-names/hash-function-text-names.xhtml
- std::string algorithm;
- // Hex-encoded, colon-separated fingerprint of the certificate. For example,
- // "12:3d:5b:71:8c:54:df:85:7e:bd:e3:7c:66:da:f9:db:6a:94:8f:85:cb:6e:44:7f:09:3e:05:f2:dd:d4:f7:86"
- std::string fingerprint;
-};
-
-// Represents a fingerprint of an X.509 certificate in a format based on
-// https://w3c.github.io/webtransport/#dictdef-webtransporthash.
-struct QUIC_EXPORT_PRIVATE WebTransportHash {
- static constexpr char kSha256[] = "sha-256";
-
- // An algorithm described by one of the names in
- // https://www.iana.org/assignments/hash-function-text-names/hash-function-text-names.xhtml
- std::string algorithm;
- // Raw bytes of the hash.
- std::string value;
-};
-
-// WebTransportFingerprintProofVerifier verifies the server leaf certificate
-// against a supplied list of certificate fingerprints following the procedure
-// described in the WebTransport specification. The certificate is deemed
-// trusted if it matches a fingerprint in the list, has expiry dates that are
-// not too long and has not expired. Only the leaf is checked, the rest of the
-// chain is ignored. Reference specification:
-// https://wicg.github.io/web-transport/#dom-quictransportconfiguration-server_certificate_fingerprints
-class QUIC_EXPORT_PRIVATE WebTransportFingerprintProofVerifier
- : public ProofVerifier {
- public:
- // Note: the entries in this list may be logged into a UMA histogram, and thus
- // should not be renumbered.
- enum class Status {
- kValidCertificate = 0,
- kUnknownFingerprint = 1,
- kCertificateParseFailure = 2,
- kExpiryTooLong = 3,
- kExpired = 4,
- kInternalError = 5,
- kDisallowedKeyAlgorithm = 6,
-
- kMaxValue = kDisallowedKeyAlgorithm,
- };
-
- class QUIC_EXPORT_PRIVATE Details : public ProofVerifyDetails {
- public:
- explicit Details(Status status) : status_(status) {}
- Status status() const { return status_; }
-
- ProofVerifyDetails* Clone() const override;
-
- private:
- const Status status_;
- };
-
- // |clock| is used to check if the certificate has expired. It is not owned
- // and must outlive the object. |max_validity_days| is the maximum time for
- // which the certificate is allowed to be valid.
- WebTransportFingerprintProofVerifier(const QuicClock* clock,
- int max_validity_days);
-
- // Adds a certificate fingerprint to be trusted. The fingerprints are
- // case-insensitive and are validated internally; the function returns true if
- // the validation passes.
- bool AddFingerprint(CertificateFingerprint fingerprint);
- bool AddFingerprint(WebTransportHash hash);
-
- // ProofVerifier implementation.
- 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;
- 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::unique_ptr<ProofVerifyContext> CreateDefaultContext() override;
-
- protected:
- virtual bool IsKeyTypeAllowedByPolicy(const CertificateView& certificate);
-
- private:
- bool HasKnownFingerprint(absl::string_view der_certificate);
- bool HasValidExpiry(const CertificateView& certificate);
- bool IsWithinValidityPeriod(const CertificateView& certificate);
-
- const QuicClock* clock_; // Unowned.
- const int max_validity_days_;
- const QuicTime::Delta max_validity_;
- std::vector<WebTransportHash> hashes_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_QUIC_TRANSPORT_FINGERPRINT_PROOF_VERIFIER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/quic_transport/web_transport_fingerprint_proof_verifier_test.cc b/chromium/net/third_party/quiche/src/quic/quic_transport/web_transport_fingerprint_proof_verifier_test.cc
deleted file mode 100644
index 0b73312135e..00000000000
--- a/chromium/net/third_party/quiche/src/quic/quic_transport/web_transport_fingerprint_proof_verifier_test.cc
+++ /dev/null
@@ -1,183 +0,0 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/quic_transport/web_transport_fingerprint_proof_verifier.h"
-
-#include <memory>
-
-#include "absl/strings/escaping.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/mock_clock.h"
-#include "quic/test_tools/test_certificates.h"
-
-namespace quic {
-namespace test {
-namespace {
-
-using ::testing::HasSubstr;
-
-// 2020-02-01 12:35:56 UTC
-constexpr QuicTime::Delta kValidTime = QuicTime::Delta::FromSeconds(1580560556);
-
-struct VerifyResult {
- QuicAsyncStatus status;
- WebTransportFingerprintProofVerifier::Status detailed_status;
- std::string error;
-};
-
-class WebTransportFingerprintProofVerifierTest : public QuicTest {
- public:
- WebTransportFingerprintProofVerifierTest() {
- clock_.AdvanceTime(kValidTime);
- verifier_ = std::make_unique<WebTransportFingerprintProofVerifier>(
- &clock_, /*max_validity_days=*/365);
- AddTestCertificate();
- }
-
- protected:
- VerifyResult Verify(absl::string_view certificate) {
- VerifyResult result;
- std::unique_ptr<ProofVerifyDetails> details;
- uint8_t tls_alert;
- result.status = verifier_->VerifyCertChain(
- /*hostname=*/"", /*port=*/0,
- std::vector<std::string>{std::string(certificate)},
- /*ocsp_response=*/"",
- /*cert_sct=*/"",
- /*context=*/nullptr, &result.error, &details, &tls_alert,
- /*callback=*/nullptr);
- result.detailed_status =
- static_cast<WebTransportFingerprintProofVerifier::Details*>(
- details.get())
- ->status();
- return result;
- }
-
- void AddTestCertificate() {
- EXPECT_TRUE(verifier_->AddFingerprint(WebTransportHash{
- WebTransportHash::kSha256, RawSha256(kTestCertificate)}));
- }
-
- MockClock clock_;
- std::unique_ptr<WebTransportFingerprintProofVerifier> verifier_;
-};
-
-TEST_F(WebTransportFingerprintProofVerifierTest, Sha256Fingerprint) {
- // Computed using `openssl x509 -fingerprint -sha256`.
- EXPECT_EQ(absl::BytesToHexString(RawSha256(kTestCertificate)),
- "f2e5465e2bf7ecd6f63066a5a37511734aa0eb7c4701"
- "0e86d6758ed4f4fa1b0f");
-}
-
-TEST_F(WebTransportFingerprintProofVerifierTest, SimpleFingerprint) {
- VerifyResult result = Verify(kTestCertificate);
- EXPECT_EQ(result.status, QUIC_SUCCESS);
- EXPECT_EQ(result.detailed_status,
- WebTransportFingerprintProofVerifier::Status::kValidCertificate);
-
- result = Verify(kWildcardCertificate);
- EXPECT_EQ(result.status, QUIC_FAILURE);
- EXPECT_EQ(result.detailed_status,
- WebTransportFingerprintProofVerifier::Status::kUnknownFingerprint);
-
- result = Verify("Some random text");
- EXPECT_EQ(result.status, QUIC_FAILURE);
-}
-
-TEST_F(WebTransportFingerprintProofVerifierTest, Validity) {
- // Validity periods of kTestCertificate, according to `openssl x509 -text`:
- // Not Before: Jan 30 18:13:59 2020 GMT
- // Not After : Feb 2 18:13:59 2020 GMT
-
- // 2020-01-29 19:00:00 UTC
- constexpr QuicTime::Delta kStartTime =
- QuicTime::Delta::FromSeconds(1580324400);
- clock_.Reset();
- clock_.AdvanceTime(kStartTime);
-
- VerifyResult result = Verify(kTestCertificate);
- EXPECT_EQ(result.status, QUIC_FAILURE);
- EXPECT_EQ(result.detailed_status,
- WebTransportFingerprintProofVerifier::Status::kExpired);
-
- clock_.AdvanceTime(QuicTime::Delta::FromSeconds(86400));
- result = Verify(kTestCertificate);
- EXPECT_EQ(result.status, QUIC_SUCCESS);
- EXPECT_EQ(result.detailed_status,
- WebTransportFingerprintProofVerifier::Status::kValidCertificate);
-
- clock_.AdvanceTime(QuicTime::Delta::FromSeconds(4 * 86400));
- result = Verify(kTestCertificate);
- EXPECT_EQ(result.status, QUIC_FAILURE);
- EXPECT_EQ(result.detailed_status,
- WebTransportFingerprintProofVerifier::Status::kExpired);
-}
-
-TEST_F(WebTransportFingerprintProofVerifierTest, MaxValidity) {
- verifier_ = std::make_unique<WebTransportFingerprintProofVerifier>(
- &clock_, /*max_validity_days=*/2);
- AddTestCertificate();
- VerifyResult result = Verify(kTestCertificate);
- EXPECT_EQ(result.status, QUIC_FAILURE);
- EXPECT_EQ(result.detailed_status,
- WebTransportFingerprintProofVerifier::Status::kExpiryTooLong);
- EXPECT_THAT(result.error, HasSubstr("limit of 2 days"));
-
- // kTestCertificate is valid for exactly four days.
- verifier_ = std::make_unique<WebTransportFingerprintProofVerifier>(
- &clock_, /*max_validity_days=*/4);
- AddTestCertificate();
- result = Verify(kTestCertificate);
- EXPECT_EQ(result.status, QUIC_SUCCESS);
- EXPECT_EQ(result.detailed_status,
- WebTransportFingerprintProofVerifier::Status::kValidCertificate);
-}
-
-TEST_F(WebTransportFingerprintProofVerifierTest, InvalidCertificate) {
- constexpr absl::string_view kInvalidCertificate = "Hello, world!";
- ASSERT_TRUE(verifier_->AddFingerprint(WebTransportHash{
- WebTransportHash::kSha256, RawSha256(kInvalidCertificate)}));
-
- VerifyResult result = Verify(kInvalidCertificate);
- EXPECT_EQ(result.status, QUIC_FAILURE);
- EXPECT_EQ(
- result.detailed_status,
- WebTransportFingerprintProofVerifier::Status::kCertificateParseFailure);
-}
-
-TEST_F(WebTransportFingerprintProofVerifierTest, AddCertificate) {
- // Accept all-uppercase fingerprints.
- verifier_ = std::make_unique<WebTransportFingerprintProofVerifier>(
- &clock_, /*max_validity_days=*/365);
- EXPECT_TRUE(verifier_->AddFingerprint(CertificateFingerprint{
- CertificateFingerprint::kSha256,
- "F2:E5:46:5E:2B:F7:EC:D6:F6:30:66:A5:A3:75:11:73:4A:A0:EB:"
- "7C:47:01:0E:86:D6:75:8E:D4:F4:FA:1B:0F"}));
- EXPECT_EQ(Verify(kTestCertificate).detailed_status,
- WebTransportFingerprintProofVerifier::Status::kValidCertificate);
-
- // Reject unknown hash algorithms.
- EXPECT_FALSE(verifier_->AddFingerprint(CertificateFingerprint{
- "sha-1", "00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00"}));
- // Reject invalid length.
- EXPECT_FALSE(verifier_->AddFingerprint(
- CertificateFingerprint{CertificateFingerprint::kSha256, "00:00:00:00"}));
- // Reject missing colons.
- EXPECT_FALSE(verifier_->AddFingerprint(CertificateFingerprint{
- CertificateFingerprint::kSha256,
- "00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00."
- "00.00.00.00.00.00.00.00.00.00.00.00.00"}));
- // Reject non-hex symbols.
- EXPECT_FALSE(verifier_->AddFingerprint(CertificateFingerprint{
- CertificateFingerprint::kSha256,
- "zz:zz:zz:zz:zz:zz:zz:zz:zz:zz:zz:zz:zz:zz:zz:zz:zz:zz:zz:"
- "zz:zz:zz:zz:zz:zz:zz:zz:zz:zz:zz:zz:zz"}));
-}
-
-} // namespace
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/bad_packet_writer.cc b/chromium/net/third_party/quiche/src/quic/test_tools/bad_packet_writer.cc
deleted file mode 100644
index dd164ba1de7..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/bad_packet_writer.cc
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/bad_packet_writer.h"
-
-namespace quic {
-namespace test {
-
-BadPacketWriter::BadPacketWriter(size_t packet_causing_write_error,
- int error_code)
- : packet_causing_write_error_(packet_causing_write_error),
- error_code_(error_code) {}
-
-BadPacketWriter::~BadPacketWriter() {}
-
-WriteResult BadPacketWriter::WritePacket(const char* buffer,
- size_t buf_len,
- const QuicIpAddress& self_address,
- const QuicSocketAddress& peer_address,
- PerPacketOptions* options) {
- if (error_code_ == 0 || packet_causing_write_error_ > 0) {
- if (packet_causing_write_error_ > 0) {
- --packet_causing_write_error_;
- }
- return QuicPacketWriterWrapper::WritePacket(buffer, buf_len, self_address,
- peer_address, options);
- }
- // It's time to cause write error.
- int error_code = error_code_;
- error_code_ = 0;
- return WriteResult(WRITE_STATUS_ERROR, error_code);
-}
-
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/bad_packet_writer.h b/chromium/net/third_party/quiche/src/quic/test_tools/bad_packet_writer.h
deleted file mode 100644
index b04798df2a8..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/bad_packet_writer.h
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_BAD_PACKET_WRITER_H_
-#define QUICHE_QUIC_TEST_TOOLS_BAD_PACKET_WRITER_H_
-
-#include "quic/core/quic_packet_writer_wrapper.h"
-
-namespace quic {
-
-namespace test {
-// This packet writer allows causing packet write error with specified error
-// code when writing a particular packet.
-class BadPacketWriter : public QuicPacketWriterWrapper {
- public:
- BadPacketWriter(size_t packet_causing_write_error, int error_code);
-
- ~BadPacketWriter() override;
-
- WriteResult WritePacket(const char* buffer,
- size_t buf_len,
- const QuicIpAddress& self_address,
- const QuicSocketAddress& peer_address,
- PerPacketOptions* options) override;
-
- private:
- size_t packet_causing_write_error_;
- int error_code_;
-};
-
-} // namespace test
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_TEST_TOOLS_BAD_PACKET_WRITER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/crypto_test_utils.cc b/chromium/net/third_party/quiche/src/quic/test_tools/crypto_test_utils.cc
deleted file mode 100644
index cbf4fe2aa7e..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/crypto_test_utils.cc
+++ /dev/null
@@ -1,921 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/crypto_test_utils.h"
-
-#include <algorithm>
-#include <memory>
-#include <string>
-#include <utility>
-
-#include "absl/strings/escaping.h"
-#include "absl/strings/string_view.h"
-#include "third_party/boringssl/src/include/openssl/bn.h"
-#include "third_party/boringssl/src/include/openssl/ec.h"
-#include "third_party/boringssl/src/include/openssl/ecdsa.h"
-#include "third_party/boringssl/src/include/openssl/nid.h"
-#include "third_party/boringssl/src/include/openssl/sha.h"
-#include "quic/core/crypto/channel_id.h"
-#include "quic/core/crypto/common_cert_set.h"
-#include "quic/core/crypto/crypto_handshake.h"
-#include "quic/core/crypto/quic_crypto_server_config.h"
-#include "quic/core/crypto/quic_decrypter.h"
-#include "quic/core/crypto/quic_encrypter.h"
-#include "quic/core/crypto/quic_random.h"
-#include "quic/core/proto/crypto_server_config_proto.h"
-#include "quic/core/quic_clock.h"
-#include "quic/core/quic_crypto_client_stream.h"
-#include "quic/core/quic_crypto_server_stream_base.h"
-#include "quic/core/quic_crypto_stream.h"
-#include "quic/core/quic_server_id.h"
-#include "quic/core/quic_utils.h"
-#include "quic/core/quic_versions.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/platform/api/quic_socket_address.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/quic_connection_peer.h"
-#include "quic/test_tools/quic_framer_peer.h"
-#include "quic/test_tools/quic_stream_peer.h"
-#include "quic/test_tools/quic_test_utils.h"
-#include "quic/test_tools/simple_quic_framer.h"
-#include "common/test_tools/quiche_test_utils.h"
-
-namespace quic {
-namespace test {
-
-namespace crypto_test_utils {
-
-namespace {
-
-using testing::_;
-
-// CryptoFramerVisitor is a framer visitor that records handshake messages.
-class CryptoFramerVisitor : public CryptoFramerVisitorInterface {
- public:
- CryptoFramerVisitor() : error_(false) {}
-
- void OnError(CryptoFramer* /*framer*/) override { error_ = true; }
-
- void OnHandshakeMessage(const CryptoHandshakeMessage& message) override {
- messages_.push_back(message);
- }
-
- bool error() const { return error_; }
-
- const std::vector<CryptoHandshakeMessage>& messages() const {
- return messages_;
- }
-
- private:
- bool error_;
- std::vector<CryptoHandshakeMessage> messages_;
-};
-
-// HexChar parses |c| as a hex character. If valid, it sets |*value| to the
-// value of the hex character and returns true. Otherwise it returns false.
-bool HexChar(char c, uint8_t* value) {
- if (c >= '0' && c <= '9') {
- *value = c - '0';
- return true;
- }
- if (c >= 'a' && c <= 'f') {
- *value = c - 'a' + 10;
- return true;
- }
- if (c >= 'A' && c <= 'F') {
- *value = c - 'A' + 10;
- return true;
- }
- return false;
-}
-
-} // anonymous namespace
-
-FakeClientOptions::FakeClientOptions() {}
-
-FakeClientOptions::~FakeClientOptions() {}
-
-namespace {
-// This class is used by GenerateFullCHLO() to extract SCID and STK from
-// REJ and to construct a full CHLO with these fields and given inchoate
-// CHLO.
-class FullChloGenerator {
- public:
- FullChloGenerator(
- QuicCryptoServerConfig* crypto_config,
- QuicSocketAddress server_addr,
- QuicSocketAddress client_addr,
- const QuicClock* clock,
- ParsedQuicVersion version,
- QuicReferenceCountedPointer<QuicSignedServerConfig> signed_config,
- QuicCompressedCertsCache* compressed_certs_cache,
- CryptoHandshakeMessage* out)
- : crypto_config_(crypto_config),
- server_addr_(server_addr),
- client_addr_(client_addr),
- clock_(clock),
- version_(version),
- signed_config_(signed_config),
- compressed_certs_cache_(compressed_certs_cache),
- out_(out),
- params_(new QuicCryptoNegotiatedParameters) {}
-
- class ValidateClientHelloCallback : public ValidateClientHelloResultCallback {
- public:
- explicit ValidateClientHelloCallback(FullChloGenerator* generator)
- : generator_(generator) {}
- void Run(QuicReferenceCountedPointer<
- ValidateClientHelloResultCallback::Result> result,
- std::unique_ptr<ProofSource::Details> /* details */) override {
- generator_->ValidateClientHelloDone(std::move(result));
- }
-
- private:
- FullChloGenerator* generator_;
- };
-
- std::unique_ptr<ValidateClientHelloCallback>
- GetValidateClientHelloCallback() {
- return std::make_unique<ValidateClientHelloCallback>(this);
- }
-
- private:
- void ValidateClientHelloDone(
- QuicReferenceCountedPointer<ValidateClientHelloResultCallback::Result>
- result) {
- result_ = result;
- crypto_config_->ProcessClientHello(
- result_, /*reject_only=*/false, TestConnectionId(1), server_addr_,
- client_addr_, version_, {version_}, clock_, QuicRandom::GetInstance(),
- compressed_certs_cache_, params_, signed_config_,
- /*total_framing_overhead=*/50, kDefaultMaxPacketSize,
- GetProcessClientHelloCallback());
- }
-
- class ProcessClientHelloCallback : public ProcessClientHelloResultCallback {
- public:
- explicit ProcessClientHelloCallback(FullChloGenerator* generator)
- : generator_(generator) {}
- void Run(QuicErrorCode error,
- const std::string& error_details,
- std::unique_ptr<CryptoHandshakeMessage> message,
- std::unique_ptr<DiversificationNonce> /*diversification_nonce*/,
- std::unique_ptr<ProofSource::Details> /*proof_source_details*/)
- override {
- ASSERT_TRUE(message) << QuicErrorCodeToString(error) << " "
- << error_details;
- generator_->ProcessClientHelloDone(std::move(message));
- }
-
- private:
- FullChloGenerator* generator_;
- };
-
- std::unique_ptr<ProcessClientHelloCallback> GetProcessClientHelloCallback() {
- return std::make_unique<ProcessClientHelloCallback>(this);
- }
-
- void ProcessClientHelloDone(std::unique_ptr<CryptoHandshakeMessage> rej) {
- // Verify output is a REJ.
- EXPECT_THAT(rej->tag(), testing::Eq(kREJ));
-
- QUIC_VLOG(1) << "Extract valid STK and SCID from\n" << rej->DebugString();
- absl::string_view srct;
- ASSERT_TRUE(rej->GetStringPiece(kSourceAddressTokenTag, &srct));
-
- absl::string_view scfg;
- ASSERT_TRUE(rej->GetStringPiece(kSCFG, &scfg));
- std::unique_ptr<CryptoHandshakeMessage> server_config(
- CryptoFramer::ParseMessage(scfg));
-
- absl::string_view scid;
- ASSERT_TRUE(server_config->GetStringPiece(kSCID, &scid));
-
- *out_ = result_->client_hello;
- out_->SetStringPiece(kSCID, scid);
- out_->SetStringPiece(kSourceAddressTokenTag, srct);
- uint64_t xlct = LeafCertHashForTesting();
- out_->SetValue(kXLCT, xlct);
- }
-
- protected:
- QuicCryptoServerConfig* crypto_config_;
- QuicSocketAddress server_addr_;
- QuicSocketAddress client_addr_;
- const QuicClock* clock_;
- ParsedQuicVersion version_;
- QuicReferenceCountedPointer<QuicSignedServerConfig> signed_config_;
- QuicCompressedCertsCache* compressed_certs_cache_;
- CryptoHandshakeMessage* out_;
-
- QuicReferenceCountedPointer<QuicCryptoNegotiatedParameters> params_;
- QuicReferenceCountedPointer<ValidateClientHelloResultCallback::Result>
- result_;
-};
-
-} // namespace
-
-std::unique_ptr<QuicCryptoServerConfig> CryptoServerConfigForTesting() {
- return std::make_unique<QuicCryptoServerConfig>(
- QuicCryptoServerConfig::TESTING, QuicRandom::GetInstance(),
- ProofSourceForTesting(), KeyExchangeSource::Default());
-}
-
-int HandshakeWithFakeServer(QuicConfig* server_quic_config,
- QuicCryptoServerConfig* crypto_config,
- MockQuicConnectionHelper* helper,
- MockAlarmFactory* alarm_factory,
- PacketSavingConnection* client_conn,
- QuicCryptoClientStreamBase* client,
- std::string alpn) {
- auto* server_conn = new testing::NiceMock<PacketSavingConnection>(
- helper, alarm_factory, Perspective::IS_SERVER,
- ParsedVersionOfIndex(client_conn->supported_versions(), 0));
-
- QuicCompressedCertsCache compressed_certs_cache(
- QuicCompressedCertsCache::kQuicCompressedCertsCacheSize);
- SetupCryptoServerConfigForTest(
- server_conn->clock(), server_conn->random_generator(), crypto_config);
-
- TestQuicSpdyServerSession server_session(
- server_conn, *server_quic_config, client_conn->supported_versions(),
- crypto_config, &compressed_certs_cache);
- // Call SetServerApplicationStateForResumption so that the fake server
- // supports 0-RTT in TLS.
- server_session.Initialize();
- server_session.GetMutableCryptoStream()
- ->SetServerApplicationStateForResumption(
- std::make_unique<ApplicationState>());
- EXPECT_CALL(*server_session.helper(),
- CanAcceptClientHello(testing::_, testing::_, testing::_,
- testing::_, testing::_))
- .Times(testing::AnyNumber());
- EXPECT_CALL(*server_conn, OnCanWrite()).Times(testing::AnyNumber());
- EXPECT_CALL(*client_conn, OnCanWrite()).Times(testing::AnyNumber());
- EXPECT_CALL(*server_conn, SendCryptoData(_, _, _))
- .Times(testing::AnyNumber());
- EXPECT_CALL(server_session, SelectAlpn(_))
- .WillRepeatedly([alpn](const std::vector<absl::string_view>& alpns) {
- return std::find(alpns.cbegin(), alpns.cend(), alpn);
- });
-
- // The client's handshake must have been started already.
- QUICHE_CHECK_NE(0u, client_conn->encrypted_packets_.size());
-
- CommunicateHandshakeMessages(client_conn, client, server_conn,
- server_session.GetMutableCryptoStream());
- if (client_conn->connected() && server_conn->connected()) {
- CompareClientAndServerKeys(client, server_session.GetMutableCryptoStream());
- }
-
- return client->num_sent_client_hellos();
-}
-
-int HandshakeWithFakeClient(MockQuicConnectionHelper* helper,
- MockAlarmFactory* alarm_factory,
- PacketSavingConnection* server_conn,
- QuicCryptoServerStreamBase* server,
- const QuicServerId& server_id,
- const FakeClientOptions& options,
- std::string alpn) {
- // This function does not do version negotiation; read the supported versions
- // directly from the server connection instead.
- ParsedQuicVersionVector supported_versions =
- server_conn->supported_versions();
- if (options.only_tls_versions) {
- supported_versions.erase(
- std::remove_if(supported_versions.begin(), supported_versions.end(),
- [](const ParsedQuicVersion& version) {
- return version.handshake_protocol != PROTOCOL_TLS1_3;
- }),
- supported_versions.end());
- QUICHE_CHECK(!options.only_quic_crypto_versions);
- } else if (options.only_quic_crypto_versions) {
- supported_versions.erase(
- std::remove_if(supported_versions.begin(), supported_versions.end(),
- [](const ParsedQuicVersion& version) {
- return version.handshake_protocol !=
- PROTOCOL_QUIC_CRYPTO;
- }),
- supported_versions.end());
- }
- PacketSavingConnection* client_conn = new PacketSavingConnection(
- helper, alarm_factory, Perspective::IS_CLIENT, supported_versions);
- // Advance the time, because timers do not like uninitialized times.
- client_conn->AdvanceTime(QuicTime::Delta::FromSeconds(1));
-
- QuicCryptoClientConfig crypto_config(ProofVerifierForTesting());
- TestQuicSpdyClientSession client_session(client_conn, DefaultQuicConfig(),
- supported_versions, server_id,
- &crypto_config);
-
- EXPECT_CALL(client_session, OnProofValid(testing::_))
- .Times(testing::AnyNumber());
- EXPECT_CALL(client_session, OnProofVerifyDetailsAvailable(testing::_))
- .Times(testing::AnyNumber());
- EXPECT_CALL(*client_conn, OnCanWrite()).Times(testing::AnyNumber());
- if (!alpn.empty()) {
- EXPECT_CALL(client_session, GetAlpnsToOffer())
- .WillRepeatedly(testing::Return(std::vector<std::string>({alpn})));
- } else {
- EXPECT_CALL(client_session, GetAlpnsToOffer())
- .WillRepeatedly(testing::Return(std::vector<std::string>(
- {AlpnForVersion(client_conn->version())})));
- }
- client_session.GetMutableCryptoStream()->CryptoConnect();
- QUICHE_CHECK_EQ(1u, client_conn->encrypted_packets_.size());
-
- CommunicateHandshakeMessages(client_conn,
- client_session.GetMutableCryptoStream(),
- server_conn, server);
-
- if (server->one_rtt_keys_available() && server->encryption_established()) {
- CompareClientAndServerKeys(client_session.GetMutableCryptoStream(), server);
- }
-
- return client_session.GetCryptoStream()->num_sent_client_hellos();
-}
-
-void SetupCryptoServerConfigForTest(const QuicClock* clock,
- QuicRandom* rand,
- QuicCryptoServerConfig* crypto_config) {
- QuicCryptoServerConfig::ConfigOptions options;
- options.channel_id_enabled = true;
- std::unique_ptr<CryptoHandshakeMessage> scfg =
- crypto_config->AddDefaultConfig(rand, clock, options);
-}
-
-void SendHandshakeMessageToStream(QuicCryptoStream* stream,
- const CryptoHandshakeMessage& message,
- Perspective /*perspective*/) {
- const QuicData& data = message.GetSerialized();
- QuicSession* session = QuicStreamPeer::session(stream);
- if (!QuicVersionUsesCryptoFrames(session->transport_version())) {
- QuicStreamFrame frame(
- QuicUtils::GetCryptoStreamId(session->transport_version()), false,
- stream->crypto_bytes_read(), data.AsStringPiece());
- stream->OnStreamFrame(frame);
- } else {
- EncryptionLevel level = session->connection()->last_decrypted_level();
- QuicCryptoFrame frame(level, stream->BytesReadOnLevel(level),
- data.AsStringPiece());
- stream->OnCryptoFrame(frame);
- }
-}
-
-void CommunicateHandshakeMessages(PacketSavingConnection* client_conn,
- QuicCryptoStream* client,
- PacketSavingConnection* server_conn,
- QuicCryptoStream* server) {
- size_t client_i = 0, server_i = 0;
- while (client_conn->connected() && server_conn->connected() &&
- (!client->one_rtt_keys_available() ||
- !server->one_rtt_keys_available())) {
- ASSERT_GT(client_conn->encrypted_packets_.size(), client_i);
- QUIC_LOG(INFO) << "Processing "
- << client_conn->encrypted_packets_.size() - client_i
- << " packets client->server";
- MovePackets(client_conn, &client_i, server, server_conn,
- Perspective::IS_SERVER);
-
- if (client->one_rtt_keys_available() && server->one_rtt_keys_available() &&
- server_conn->encrypted_packets_.size() == server_i) {
- break;
- }
- ASSERT_GT(server_conn->encrypted_packets_.size(), server_i);
- QUIC_LOG(INFO) << "Processing "
- << server_conn->encrypted_packets_.size() - server_i
- << " packets server->client";
- MovePackets(server_conn, &server_i, client, client_conn,
- Perspective::IS_CLIENT);
- }
-}
-
-bool CommunicateHandshakeMessagesUntil(PacketSavingConnection* client_conn,
- QuicCryptoStream* client,
- std::function<bool()> client_condition,
- PacketSavingConnection* server_conn,
- QuicCryptoStream* server,
- std::function<bool()> server_condition) {
- size_t client_next_packet_to_deliver =
- client_conn->number_of_packets_delivered_;
- size_t server_next_packet_to_deliver =
- server_conn->number_of_packets_delivered_;
- while (
- client_conn->connected() && server_conn->connected() &&
- (!client_condition() || !server_condition()) &&
- (client_conn->encrypted_packets_.size() > client_next_packet_to_deliver ||
- server_conn->encrypted_packets_.size() >
- server_next_packet_to_deliver)) {
- if (!server_condition()) {
- QUIC_LOG(INFO) << "Processing "
- << client_conn->encrypted_packets_.size() -
- client_next_packet_to_deliver
- << " packets client->server";
- MovePackets(client_conn, &client_next_packet_to_deliver, server,
- server_conn, Perspective::IS_SERVER);
- }
- if (!client_condition()) {
- QUIC_LOG(INFO) << "Processing "
- << server_conn->encrypted_packets_.size() -
- server_next_packet_to_deliver
- << " packets server->client";
- MovePackets(server_conn, &server_next_packet_to_deliver, client,
- client_conn, Perspective::IS_CLIENT);
- }
- }
- client_conn->number_of_packets_delivered_ = client_next_packet_to_deliver;
- server_conn->number_of_packets_delivered_ = server_next_packet_to_deliver;
- bool result = client_condition() && server_condition();
- if (!result) {
- QUIC_LOG(INFO) << "CommunicateHandshakeMessagesUnti failed with state: "
- "client connected? "
- << client_conn->connected() << " server connected? "
- << server_conn->connected() << " client condition met? "
- << client_condition() << " server condition met? "
- << server_condition();
- }
- return result;
-}
-
-std::pair<size_t, size_t> AdvanceHandshake(PacketSavingConnection* client_conn,
- QuicCryptoStream* client,
- size_t client_i,
- PacketSavingConnection* server_conn,
- QuicCryptoStream* server,
- size_t server_i) {
- if (client_conn->encrypted_packets_.size() != client_i) {
- QUIC_LOG(INFO) << "Processing "
- << client_conn->encrypted_packets_.size() - client_i
- << " packets client->server";
- MovePackets(client_conn, &client_i, server, server_conn,
- Perspective::IS_SERVER);
- }
-
- if (server_conn->encrypted_packets_.size() != server_i) {
- QUIC_LOG(INFO) << "Processing "
- << server_conn->encrypted_packets_.size() - server_i
- << " packets server->client";
- MovePackets(server_conn, &server_i, client, client_conn,
- Perspective::IS_CLIENT);
- }
-
- return std::make_pair(client_i, server_i);
-}
-
-std::string GetValueForTag(const CryptoHandshakeMessage& message, QuicTag tag) {
- auto it = message.tag_value_map().find(tag);
- if (it == message.tag_value_map().end()) {
- return std::string();
- }
- return it->second;
-}
-
-uint64_t LeafCertHashForTesting() {
- QuicReferenceCountedPointer<ProofSource::Chain> chain;
- QuicSocketAddress server_address(QuicIpAddress::Any4(), 42);
- QuicSocketAddress client_address(QuicIpAddress::Any4(), 43);
- QuicCryptoProof proof;
- std::unique_ptr<ProofSource> proof_source(ProofSourceForTesting());
-
- class Callback : public ProofSource::Callback {
- public:
- Callback(bool* ok, QuicReferenceCountedPointer<ProofSource::Chain>* chain)
- : ok_(ok), chain_(chain) {}
-
- void Run(bool ok,
- const QuicReferenceCountedPointer<ProofSource::Chain>& chain,
- const QuicCryptoProof& /* proof */,
- std::unique_ptr<ProofSource::Details> /* details */) override {
- *ok_ = ok;
- *chain_ = chain;
- }
-
- private:
- bool* ok_;
- QuicReferenceCountedPointer<ProofSource::Chain>* chain_;
- };
-
- // Note: relies on the callback being invoked synchronously
- bool ok = false;
- proof_source->GetProof(
- server_address, client_address, "", "",
- AllSupportedVersionsWithQuicCrypto().front().transport_version, "",
- std::unique_ptr<ProofSource::Callback>(new Callback(&ok, &chain)));
- if (!ok || chain->certs.empty()) {
- QUICHE_DCHECK(false) << "Proof generation failed";
- return 0;
- }
-
- return QuicUtils::FNV1a_64_Hash(chain->certs.at(0));
-}
-
-class MockCommonCertSets : public CommonCertSets {
- public:
- MockCommonCertSets(absl::string_view cert, uint64_t hash, uint32_t index)
- : cert_(cert), hash_(hash), index_(index) {}
-
- absl::string_view GetCommonHashes() const override {
- QUIC_BUG(quic_bug_10142_1) << "not implemented";
- return absl::string_view();
- }
-
- absl::string_view GetCert(uint64_t hash, uint32_t index) const override {
- if (hash == hash_ && index == index_) {
- return cert_;
- }
- return absl::string_view();
- }
-
- bool MatchCert(absl::string_view cert,
- absl::string_view common_set_hashes,
- uint64_t* out_hash,
- uint32_t* out_index) const override {
- if (cert != cert_) {
- return false;
- }
-
- if (common_set_hashes.size() % sizeof(uint64_t) != 0) {
- return false;
- }
- bool client_has_set = false;
- for (size_t i = 0; i < common_set_hashes.size(); i += sizeof(uint64_t)) {
- uint64_t hash;
- memcpy(&hash, common_set_hashes.data() + i, sizeof(hash));
- if (hash == hash_) {
- client_has_set = true;
- break;
- }
- }
-
- if (!client_has_set) {
- return false;
- }
-
- *out_hash = hash_;
- *out_index = index_;
- return true;
- }
-
- private:
- const std::string cert_;
- const uint64_t hash_;
- const uint32_t index_;
-};
-
-CommonCertSets* MockCommonCertSets(absl::string_view cert,
- uint64_t hash,
- uint32_t index) {
- return new class MockCommonCertSets(cert, hash, index);
-}
-
-void FillInDummyReject(CryptoHandshakeMessage* rej) {
- rej->set_tag(kREJ);
-
- // Minimum SCFG that passes config validation checks.
- // clang-format off
- unsigned char scfg[] = {
- // SCFG
- 0x53, 0x43, 0x46, 0x47,
- // num entries
- 0x01, 0x00,
- // padding
- 0x00, 0x00,
- // EXPY
- 0x45, 0x58, 0x50, 0x59,
- // EXPY end offset
- 0x08, 0x00, 0x00, 0x00,
- // Value
- '1', '2', '3', '4',
- '5', '6', '7', '8'
- };
- // clang-format on
- rej->SetValue(kSCFG, scfg);
- rej->SetStringPiece(kServerNonceTag, "SERVER_NONCE");
- int64_t ttl = 2 * 24 * 60 * 60;
- rej->SetValue(kSTTL, ttl);
- std::vector<QuicTag> reject_reasons;
- reject_reasons.push_back(CLIENT_NONCE_INVALID_FAILURE);
- rej->SetVector(kRREJ, reject_reasons);
-}
-
-namespace {
-
-#define RETURN_STRING_LITERAL(x) \
- case x: \
- return #x
-
-std::string EncryptionLevelString(EncryptionLevel level) {
- switch (level) {
- RETURN_STRING_LITERAL(ENCRYPTION_INITIAL);
- RETURN_STRING_LITERAL(ENCRYPTION_HANDSHAKE);
- RETURN_STRING_LITERAL(ENCRYPTION_ZERO_RTT);
- RETURN_STRING_LITERAL(ENCRYPTION_FORWARD_SECURE);
- default:
- return "";
- }
-}
-
-void CompareCrypters(const QuicEncrypter* encrypter,
- const QuicDecrypter* decrypter,
- std::string label) {
- if (encrypter == nullptr || decrypter == nullptr) {
- ADD_FAILURE() << "Expected non-null crypters; have " << encrypter << " and "
- << decrypter << " for " << label;
- return;
- }
- absl::string_view encrypter_key = encrypter->GetKey();
- absl::string_view encrypter_iv = encrypter->GetNoncePrefix();
- absl::string_view decrypter_key = decrypter->GetKey();
- absl::string_view decrypter_iv = decrypter->GetNoncePrefix();
- quiche::test::CompareCharArraysWithHexError(
- label + " key", encrypter_key.data(), encrypter_key.length(),
- decrypter_key.data(), decrypter_key.length());
- quiche::test::CompareCharArraysWithHexError(
- label + " iv", encrypter_iv.data(), encrypter_iv.length(),
- decrypter_iv.data(), decrypter_iv.length());
-}
-
-} // namespace
-
-void CompareClientAndServerKeys(QuicCryptoClientStreamBase* client,
- QuicCryptoServerStreamBase* server) {
- QuicFramer* client_framer = QuicConnectionPeer::GetFramer(
- QuicStreamPeer::session(client)->connection());
- QuicFramer* server_framer = QuicConnectionPeer::GetFramer(
- QuicStreamPeer::session(server)->connection());
- for (EncryptionLevel level :
- {ENCRYPTION_HANDSHAKE, ENCRYPTION_ZERO_RTT, ENCRYPTION_FORWARD_SECURE}) {
- SCOPED_TRACE(EncryptionLevelString(level));
- const QuicEncrypter* client_encrypter(
- QuicFramerPeer::GetEncrypter(client_framer, level));
- const QuicDecrypter* server_decrypter(
- QuicFramerPeer::GetDecrypter(server_framer, level));
- if (level == ENCRYPTION_FORWARD_SECURE ||
- !((level == ENCRYPTION_HANDSHAKE || level == ENCRYPTION_ZERO_RTT ||
- client_encrypter == nullptr) &&
- (level == ENCRYPTION_ZERO_RTT || server_decrypter == nullptr))) {
- CompareCrypters(client_encrypter, server_decrypter,
- "client " + EncryptionLevelString(level) + " write");
- }
- const QuicEncrypter* server_encrypter(
- QuicFramerPeer::GetEncrypter(server_framer, level));
- const QuicDecrypter* client_decrypter(
- QuicFramerPeer::GetDecrypter(client_framer, level));
- if (level == ENCRYPTION_FORWARD_SECURE ||
- !(server_encrypter == nullptr &&
- (level == ENCRYPTION_HANDSHAKE || level == ENCRYPTION_ZERO_RTT ||
- client_decrypter == nullptr))) {
- CompareCrypters(server_encrypter, client_decrypter,
- "server " + EncryptionLevelString(level) + " write");
- }
- }
-
- absl::string_view client_subkey_secret =
- client->crypto_negotiated_params().subkey_secret;
- absl::string_view server_subkey_secret =
- server->crypto_negotiated_params().subkey_secret;
- quiche::test::CompareCharArraysWithHexError(
- "subkey secret", client_subkey_secret.data(),
- client_subkey_secret.length(), server_subkey_secret.data(),
- server_subkey_secret.length());
-}
-
-QuicTag ParseTag(const char* tagstr) {
- const size_t len = strlen(tagstr);
- QUICHE_CHECK_NE(0u, len);
-
- QuicTag tag = 0;
-
- if (tagstr[0] == '#') {
- QUICHE_CHECK_EQ(static_cast<size_t>(1 + 2 * 4), len);
- tagstr++;
-
- for (size_t i = 0; i < 8; i++) {
- tag <<= 4;
-
- uint8_t v = 0;
- QUICHE_CHECK(HexChar(tagstr[i], &v));
- tag |= v;
- }
-
- return tag;
- }
-
- QUICHE_CHECK_LE(len, 4u);
- for (size_t i = 0; i < 4; i++) {
- tag >>= 8;
- if (i < len) {
- tag |= static_cast<uint32_t>(tagstr[i]) << 24;
- }
- }
-
- return tag;
-}
-
-CryptoHandshakeMessage CreateCHLO(
- std::vector<std::pair<std::string, std::string>> tags_and_values) {
- return CreateCHLO(tags_and_values, -1);
-}
-
-CryptoHandshakeMessage CreateCHLO(
- std::vector<std::pair<std::string, std::string>> tags_and_values,
- int minimum_size_bytes) {
- CryptoHandshakeMessage msg;
- msg.set_tag(MakeQuicTag('C', 'H', 'L', 'O'));
-
- if (minimum_size_bytes > 0) {
- msg.set_minimum_size(minimum_size_bytes);
- }
-
- for (const auto& tag_and_value : tags_and_values) {
- const std::string& tag = tag_and_value.first;
- const std::string& value = tag_and_value.second;
-
- const QuicTag quic_tag = ParseTag(tag.c_str());
-
- size_t value_len = value.length();
- if (value_len > 0 && value[0] == '#') {
- // This is ascii encoded hex.
- std::string hex_value =
- absl::HexStringToBytes(absl::string_view(&value[1]));
- msg.SetStringPiece(quic_tag, hex_value);
- continue;
- }
- msg.SetStringPiece(quic_tag, value);
- }
-
- // The CryptoHandshakeMessage needs to be serialized and parsed to ensure
- // that any padding is included.
- std::unique_ptr<QuicData> bytes =
- CryptoFramer::ConstructHandshakeMessage(msg);
- std::unique_ptr<CryptoHandshakeMessage> parsed(
- CryptoFramer::ParseMessage(bytes->AsStringPiece()));
- QUICHE_CHECK(parsed);
-
- return *parsed;
-}
-
-void MovePackets(PacketSavingConnection* source_conn,
- size_t* inout_packet_index,
- QuicCryptoStream* dest_stream,
- PacketSavingConnection* dest_conn,
- Perspective dest_perspective) {
- SimpleQuicFramer framer(source_conn->supported_versions(), dest_perspective);
- QuicFramerPeer::SetLastSerializedServerConnectionId(framer.framer(),
- TestConnectionId());
-
- SimpleQuicFramer null_encryption_framer(source_conn->supported_versions(),
- dest_perspective);
- QuicFramerPeer::SetLastSerializedServerConnectionId(
- null_encryption_framer.framer(), TestConnectionId());
-
- size_t index = *inout_packet_index;
- for (; index < source_conn->encrypted_packets_.size(); index++) {
- if (!dest_conn->connected()) {
- QUIC_LOG(INFO)
- << "Destination connection disconnected. Skipping packet at index "
- << index;
- continue;
- }
- // In order to properly test the code we need to perform encryption and
- // decryption so that the crypters latch when expected. The crypters are in
- // |dest_conn|, but we don't want to try and use them there. Instead we swap
- // them into |framer|, perform the decryption with them, and then swap ther
- // back.
- QuicConnectionPeer::SwapCrypters(dest_conn, framer.framer());
- QuicConnectionPeer::AddBytesReceived(
- dest_conn, source_conn->encrypted_packets_[index]->length());
- if (!framer.ProcessPacket(*source_conn->encrypted_packets_[index])) {
- // The framer will be unable to decrypt zero-rtt packets sent during
- // handshake or forward-secure packets sent after the handshake is
- // complete. Don't treat them as handshake packets.
- QuicConnectionPeer::SwapCrypters(dest_conn, framer.framer());
- continue;
- }
- QuicConnectionPeer::SwapCrypters(dest_conn, framer.framer());
-
- // Install a packet flusher such that the packets generated by |dest_conn|
- // in response to this packet are more likely to be coalesced and/or batched
- // in the writer.
- QuicConnection::ScopedPacketFlusher flusher(dest_conn);
-
- dest_conn->OnDecryptedPacket(
- source_conn->encrypted_packets_[index]->length(),
- framer.last_decrypted_level());
-
- if (dest_stream->handshake_protocol() == PROTOCOL_TLS1_3) {
- // Try to process the packet with a framer that only has the NullDecrypter
- // for decryption. If ProcessPacket succeeds, that means the packet was
- // encrypted with the NullEncrypter. With the TLS handshaker in use, no
- // packets should ever be encrypted with the NullEncrypter, instead
- // they're encrypted with an obfuscation cipher based on QUIC version and
- // connection ID.
- QUIC_LOG(INFO) << "Attempting to decrypt with NullDecrypter: "
- "expect a decryption failure on the next log line.";
- ASSERT_FALSE(null_encryption_framer.ProcessPacket(
- *source_conn->encrypted_packets_[index]))
- << "No TLS packets should be encrypted with the NullEncrypter";
- }
-
- // Since we're using QuicFramers separate from the connections to move
- // packets, the QuicConnection never gets notified about what level the last
- // packet was decrypted at. This is needed by TLS to know what encryption
- // level was used for the data it's receiving, so we plumb this information
- // from the SimpleQuicFramer back into the connection.
- dest_conn->OnDecryptedPacket(
- source_conn->encrypted_packets_[index]->length(),
- framer.last_decrypted_level());
-
- 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);
- }
- }
- for (const auto& crypto_frame : framer.crypto_frames()) {
- dest_stream->OnCryptoFrame(*crypto_frame);
- }
- if (!framer.connection_close_frames().empty() && dest_conn->connected()) {
- dest_conn->OnConnectionCloseFrame(framer.connection_close_frames()[0]);
- }
- }
- *inout_packet_index = index;
-
- QuicConnectionPeer::SetCurrentPacket(dest_conn,
- absl::string_view(nullptr, 0));
-}
-
-CryptoHandshakeMessage GenerateDefaultInchoateCHLO(
- const QuicClock* clock,
- QuicTransportVersion version,
- QuicCryptoServerConfig* crypto_config) {
- // clang-format off
- return CreateCHLO(
- {{"PDMD", "X509"},
- {"AEAD", "AESG"},
- {"KEXS", "C255"},
- {"PUBS", GenerateClientPublicValuesHex().c_str()},
- {"NONC", GenerateClientNonceHex(clock, crypto_config).c_str()},
- {"VER\0", QuicVersionLabelToString(
- CreateQuicVersionLabel(
- ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, version))).c_str()}},
- kClientHelloMinimumSize);
- // clang-format on
-}
-
-std::string GenerateClientNonceHex(const QuicClock* clock,
- QuicCryptoServerConfig* crypto_config) {
- QuicCryptoServerConfig::ConfigOptions old_config_options;
- QuicCryptoServerConfig::ConfigOptions new_config_options;
- old_config_options.id = "old-config-id";
- crypto_config->AddDefaultConfig(QuicRandom::GetInstance(), clock,
- old_config_options);
- QuicServerConfigProtobuf primary_config = crypto_config->GenerateConfig(
- QuicRandom::GetInstance(), clock, new_config_options);
- primary_config.set_primary_time(clock->WallNow().ToUNIXSeconds());
- std::unique_ptr<CryptoHandshakeMessage> msg =
- crypto_config->AddConfig(primary_config, clock->WallNow());
- absl::string_view orbit;
- QUICHE_CHECK(msg->GetStringPiece(kORBT, &orbit));
- std::string nonce;
- CryptoUtils::GenerateNonce(clock->WallNow(), QuicRandom::GetInstance(), orbit,
- &nonce);
- return ("#" + absl::BytesToHexString(nonce));
-}
-
-std::string GenerateClientPublicValuesHex() {
- char public_value[32];
- memset(public_value, 42, sizeof(public_value));
- return ("#" + absl::BytesToHexString(
- absl::string_view(public_value, sizeof(public_value))));
-}
-
-void GenerateFullCHLO(
- const CryptoHandshakeMessage& inchoate_chlo,
- QuicCryptoServerConfig* crypto_config,
- QuicSocketAddress server_addr,
- QuicSocketAddress client_addr,
- QuicTransportVersion transport_version,
- const QuicClock* clock,
- QuicReferenceCountedPointer<QuicSignedServerConfig> signed_config,
- QuicCompressedCertsCache* compressed_certs_cache,
- CryptoHandshakeMessage* out) {
- // Pass a inchoate CHLO.
- FullChloGenerator generator(
- crypto_config, server_addr, client_addr, clock,
- ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, transport_version), signed_config,
- compressed_certs_cache, out);
- crypto_config->ValidateClientHello(
- inchoate_chlo, client_addr, server_addr, transport_version, clock,
- signed_config, generator.GetValidateClientHelloCallback());
-}
-
-} // namespace crypto_test_utils
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/crypto_test_utils.h b/chromium/net/third_party/quiche/src/quic/test_tools/crypto_test_utils.h
deleted file mode 100644
index b4d772adb68..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/crypto_test_utils.h
+++ /dev/null
@@ -1,227 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_CRYPTO_TEST_UTILS_H_
-#define QUICHE_QUIC_TEST_TOOLS_CRYPTO_TEST_UTILS_H_
-
-#include <cstdarg>
-#include <cstddef>
-#include <cstdint>
-#include <utility>
-#include <vector>
-
-#include "absl/strings/string_view.h"
-#include "third_party/boringssl/src/include/openssl/evp.h"
-#include "quic/core/crypto/crypto_framer.h"
-#include "quic/core/quic_framer.h"
-#include "quic/core/quic_packets.h"
-#include "quic/test_tools/quic_test_utils.h"
-
-namespace quic {
-
-class CommonCertSets;
-class ProofSource;
-class ProofVerifier;
-class ProofVerifyContext;
-class QuicClock;
-class QuicConfig;
-class QuicCryptoClientStream;
-class QuicCryptoServerConfig;
-class QuicCryptoServerStreamBase;
-class QuicCryptoStream;
-class QuicRandom;
-class QuicServerId;
-
-namespace test {
-
-class PacketSavingConnection;
-
-namespace crypto_test_utils {
-
-// An interface for a source of callbacks. This is used for invoking
-// callbacks asynchronously.
-//
-// Call the RunPendingCallbacks method regularly to run the callbacks from
-// this source.
-class CallbackSource {
- public:
- virtual ~CallbackSource() {}
-
- // Runs pending callbacks from this source. If there is no pending
- // callback, does nothing.
- virtual void RunPendingCallbacks() = 0;
-};
-
-// FakeClientOptions bundles together a number of options for configuring
-// HandshakeWithFakeClient.
-struct FakeClientOptions {
- FakeClientOptions();
- ~FakeClientOptions();
-
- // If only_tls_versions is set, then the client will only use TLS for the
- // crypto handshake.
- bool only_tls_versions = false;
-
- // If only_quic_crypto_versions is set, then the client will only use
- // PROTOCOL_QUIC_CRYPTO for the crypto handshake.
- bool only_quic_crypto_versions = false;
-};
-
-// Returns a QuicCryptoServerConfig that is in a reasonable configuration to
-// pass into HandshakeWithFakeServer.
-std::unique_ptr<QuicCryptoServerConfig> CryptoServerConfigForTesting();
-
-// returns: the number of client hellos that the client sent.
-int HandshakeWithFakeServer(QuicConfig* server_quic_config,
- QuicCryptoServerConfig* crypto_config,
- MockQuicConnectionHelper* helper,
- MockAlarmFactory* alarm_factory,
- PacketSavingConnection* client_conn,
- QuicCryptoClientStreamBase* client,
- std::string alpn);
-
-// returns: the number of client hellos that the client sent.
-int HandshakeWithFakeClient(MockQuicConnectionHelper* helper,
- MockAlarmFactory* alarm_factory,
- PacketSavingConnection* server_conn,
- QuicCryptoServerStreamBase* server,
- const QuicServerId& server_id,
- const FakeClientOptions& options,
- std::string alpn);
-
-// SetupCryptoServerConfigForTest configures |crypto_config|
-// with sensible defaults for testing.
-void SetupCryptoServerConfigForTest(const QuicClock* clock,
- QuicRandom* rand,
- QuicCryptoServerConfig* crypto_config);
-
-// Sends the handshake message |message| to stream |stream| with the perspective
-// that the message is coming from |perspective|.
-void SendHandshakeMessageToStream(QuicCryptoStream* stream,
- const CryptoHandshakeMessage& message,
- Perspective perspective);
-
-// CommunicateHandshakeMessages moves messages from |client| to |server| and
-// back until |clients|'s handshake has completed.
-void CommunicateHandshakeMessages(PacketSavingConnection* client_conn,
- QuicCryptoStream* client,
- PacketSavingConnection* server_conn,
- QuicCryptoStream* server);
-
-// 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
-// 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);
-
-// AdvanceHandshake attempts to moves messages from |client| to |server| and
-// |server| to |client|. Returns the number of messages moved.
-std::pair<size_t, size_t> AdvanceHandshake(PacketSavingConnection* client_conn,
- QuicCryptoStream* client,
- size_t client_i,
- PacketSavingConnection* server_conn,
- QuicCryptoStream* server,
- size_t server_i);
-
-// Returns the value for the tag |tag| in the tag value map of |message|.
-std::string GetValueForTag(const CryptoHandshakeMessage& message, QuicTag tag);
-
-// Returns a new |ProofSource| that serves up test certificates.
-std::unique_ptr<ProofSource> ProofSourceForTesting();
-
-// Returns a new |ProofVerifier| that uses the QUIC testing root CA.
-std::unique_ptr<ProofVerifier> ProofVerifierForTesting();
-
-// Returns a hash of the leaf test certificate.
-uint64_t LeafCertHashForTesting();
-
-// Returns a |ProofVerifyContext| that must be used with the verifier
-// returned by |ProofVerifierForTesting|.
-std::unique_ptr<ProofVerifyContext> ProofVerifyContextForTesting();
-
-// MockCommonCertSets returns a CommonCertSets that contains a single set with
-// hash |hash|, consisting of the certificate |cert| at index |index|.
-CommonCertSets* MockCommonCertSets(absl::string_view cert,
- uint64_t hash,
- uint32_t index);
-
-// Creates a minimal dummy reject message that will pass the client-config
-// validation tests. This will include a server config, but no certs, proof
-// source address token, or server nonce.
-void FillInDummyReject(CryptoHandshakeMessage* rej);
-
-// ParseTag returns a QuicTag from parsing |tagstr|. |tagstr| may either be
-// in the format "EXMP" (i.e. ASCII format), or "#11223344" (an explicit hex
-// format). It QUICHE_CHECK fails if there's a parse error.
-QuicTag ParseTag(const char* tagstr);
-
-// Message constructs a CHLO message from a provided vector of tag/value pairs.
-// The first of each pair is the tag of a tag/value and is given as an argument
-// to |ParseTag|. The second is the value of the tag/value pair and is either a
-// hex dump, preceeded by a '#', or a raw value. If minimum_size_bytes is
-// provided then the message will be padded to this minimum size.
-//
-// CreateCHLO(
-// {{"NOCE", "#11223344"},
-// {"SNI", "www.example.com"}},
-// optional_minimum_size_bytes);
-CryptoHandshakeMessage CreateCHLO(
- std::vector<std::pair<std::string, std::string>> tags_and_values);
-CryptoHandshakeMessage CreateCHLO(
- std::vector<std::pair<std::string, std::string>> tags_and_values,
- int minimum_size_bytes);
-
-// 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.
-void MovePackets(PacketSavingConnection* source_conn,
- size_t* inout_packet_index,
- QuicCryptoStream* dest_stream,
- PacketSavingConnection* dest_conn,
- Perspective dest_perspective);
-
-// Return an inchoate CHLO with some basic tag value pairs.
-CryptoHandshakeMessage GenerateDefaultInchoateCHLO(
- const QuicClock* clock,
- QuicTransportVersion version,
- QuicCryptoServerConfig* crypto_config);
-
-// Takes a inchoate CHLO, returns a full CHLO in |out| which can pass
-// |crypto_config|'s validation.
-void GenerateFullCHLO(
- const CryptoHandshakeMessage& inchoate_chlo,
- QuicCryptoServerConfig* crypto_config,
- QuicSocketAddress server_addr,
- QuicSocketAddress client_addr,
- QuicTransportVersion transport_version,
- const QuicClock* clock,
- QuicReferenceCountedPointer<QuicSignedServerConfig> signed_config,
- QuicCompressedCertsCache* compressed_certs_cache,
- CryptoHandshakeMessage* out);
-
-void CompareClientAndServerKeys(QuicCryptoClientStreamBase* client,
- QuicCryptoServerStreamBase* server);
-
-// Return a CHLO nonce in hexadecimal.
-std::string GenerateClientNonceHex(const QuicClock* clock,
- QuicCryptoServerConfig* crypto_config);
-
-// Return a CHLO PUBS in hexadecimal.
-std::string GenerateClientPublicValuesHex();
-
-} // namespace crypto_test_utils
-
-} // namespace test
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_TEST_TOOLS_CRYPTO_TEST_UTILS_H_
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/crypto_test_utils_test.cc b/chromium/net/third_party/quiche/src/quic/test_tools/crypto_test_utils_test.cc
deleted file mode 100644
index b1f21158d91..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/crypto_test_utils_test.cc
+++ /dev/null
@@ -1,187 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/crypto_test_utils.h"
-
-#include <utility>
-
-#include "absl/strings/escaping.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/proto/crypto_server_config_proto.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/mock_clock.h"
-
-namespace quic {
-namespace test {
-
-class ShloVerifier {
- public:
- ShloVerifier(
- QuicCryptoServerConfig* crypto_config,
- QuicSocketAddress server_addr,
- QuicSocketAddress client_addr,
- const QuicClock* clock,
- QuicReferenceCountedPointer<QuicSignedServerConfig> signed_config,
- QuicCompressedCertsCache* compressed_certs_cache,
- ParsedQuicVersion version)
- : crypto_config_(crypto_config),
- server_addr_(server_addr),
- client_addr_(client_addr),
- clock_(clock),
- signed_config_(signed_config),
- compressed_certs_cache_(compressed_certs_cache),
- params_(new QuicCryptoNegotiatedParameters),
- version_(version) {}
-
- class ValidateClientHelloCallback : public ValidateClientHelloResultCallback {
- public:
- explicit ValidateClientHelloCallback(ShloVerifier* shlo_verifier)
- : shlo_verifier_(shlo_verifier) {}
- void Run(QuicReferenceCountedPointer<
- ValidateClientHelloResultCallback::Result> result,
- std::unique_ptr<ProofSource::Details> /* details */) override {
- shlo_verifier_->ValidateClientHelloDone(result);
- }
-
- private:
- ShloVerifier* shlo_verifier_;
- };
-
- std::unique_ptr<ValidateClientHelloCallback>
- GetValidateClientHelloCallback() {
- return std::make_unique<ValidateClientHelloCallback>(this);
- }
-
- private:
- void ValidateClientHelloDone(
- const QuicReferenceCountedPointer<
- ValidateClientHelloResultCallback::Result>& result) {
- result_ = result;
- crypto_config_->ProcessClientHello(
- result_, /*reject_only=*/false,
- /*connection_id=*/TestConnectionId(1), server_addr_, client_addr_,
- version_, AllSupportedVersions(), clock_, QuicRandom::GetInstance(),
- compressed_certs_cache_, params_, signed_config_,
- /*total_framing_overhead=*/50, kDefaultMaxPacketSize,
- GetProcessClientHelloCallback());
- }
-
- class ProcessClientHelloCallback : public ProcessClientHelloResultCallback {
- public:
- explicit ProcessClientHelloCallback(ShloVerifier* shlo_verifier)
- : shlo_verifier_(shlo_verifier) {}
- void Run(QuicErrorCode /*error*/,
- const std::string& /*error_details*/,
- std::unique_ptr<CryptoHandshakeMessage> message,
- std::unique_ptr<DiversificationNonce> /*diversification_nonce*/,
- std::unique_ptr<ProofSource::Details> /*proof_source_details*/)
- override {
- shlo_verifier_->ProcessClientHelloDone(std::move(message));
- }
-
- private:
- ShloVerifier* shlo_verifier_;
- };
-
- std::unique_ptr<ProcessClientHelloCallback> GetProcessClientHelloCallback() {
- return std::make_unique<ProcessClientHelloCallback>(this);
- }
-
- void ProcessClientHelloDone(std::unique_ptr<CryptoHandshakeMessage> message) {
- // Verify output is a SHLO.
- EXPECT_EQ(message->tag(), kSHLO)
- << "Fail to pass validation. Get " << message->DebugString();
- }
-
- QuicCryptoServerConfig* crypto_config_;
- QuicSocketAddress server_addr_;
- QuicSocketAddress client_addr_;
- const QuicClock* clock_;
- QuicReferenceCountedPointer<QuicSignedServerConfig> signed_config_;
- QuicCompressedCertsCache* compressed_certs_cache_;
-
- QuicReferenceCountedPointer<QuicCryptoNegotiatedParameters> params_;
- QuicReferenceCountedPointer<ValidateClientHelloResultCallback::Result>
- result_;
-
- const ParsedQuicVersion version_;
-};
-
-class CryptoTestUtilsTest : public QuicTest {};
-
-TEST_F(CryptoTestUtilsTest, TestGenerateFullCHLO) {
- MockClock clock;
- QuicCryptoServerConfig crypto_config(
- QuicCryptoServerConfig::TESTING, QuicRandom::GetInstance(),
- crypto_test_utils::ProofSourceForTesting(), KeyExchangeSource::Default());
- QuicSocketAddress server_addr(QuicIpAddress::Any4(), 5);
- QuicSocketAddress client_addr(QuicIpAddress::Loopback4(), 1);
- QuicReferenceCountedPointer<QuicSignedServerConfig> signed_config(
- new QuicSignedServerConfig);
- QuicCompressedCertsCache compressed_certs_cache(
- QuicCompressedCertsCache::kQuicCompressedCertsCacheSize);
- CryptoHandshakeMessage full_chlo;
-
- QuicCryptoServerConfig::ConfigOptions old_config_options;
- old_config_options.id = "old-config-id";
- crypto_config.AddDefaultConfig(QuicRandom::GetInstance(), &clock,
- old_config_options);
- QuicCryptoServerConfig::ConfigOptions new_config_options;
- QuicServerConfigProtobuf primary_config = crypto_config.GenerateConfig(
- QuicRandom::GetInstance(), &clock, new_config_options);
- primary_config.set_primary_time(clock.WallNow().ToUNIXSeconds());
- std::unique_ptr<CryptoHandshakeMessage> msg =
- crypto_config.AddConfig(primary_config, clock.WallNow());
- absl::string_view orbit;
- ASSERT_TRUE(msg->GetStringPiece(kORBT, &orbit));
- std::string nonce;
- CryptoUtils::GenerateNonce(clock.WallNow(), QuicRandom::GetInstance(), orbit,
- &nonce);
- std::string nonce_hex = "#" + absl::BytesToHexString(nonce);
-
- char public_value[32];
- memset(public_value, 42, sizeof(public_value));
- std::string pub_hex = "#" + absl::BytesToHexString(absl::string_view(
- public_value, sizeof(public_value)));
-
- // The methods below use a PROTOCOL_QUIC_CRYPTO version so we pick the
- // first one from the list of supported versions.
- QuicTransportVersion transport_version = QUIC_VERSION_UNSUPPORTED;
- for (const ParsedQuicVersion& version : AllSupportedVersions()) {
- if (version.handshake_protocol == PROTOCOL_QUIC_CRYPTO) {
- transport_version = version.transport_version;
- break;
- }
- }
- ASSERT_NE(QUIC_VERSION_UNSUPPORTED, transport_version);
-
- CryptoHandshakeMessage inchoate_chlo = crypto_test_utils::CreateCHLO(
- {{"PDMD", "X509"},
- {"AEAD", "AESG"},
- {"KEXS", "C255"},
- {"COPT", "SREJ"},
- {"PUBS", pub_hex},
- {"NONC", nonce_hex},
- {"VER\0",
- QuicVersionLabelToString(CreateQuicVersionLabel(
- ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, transport_version)))}},
- kClientHelloMinimumSize);
-
- crypto_test_utils::GenerateFullCHLO(inchoate_chlo, &crypto_config,
- server_addr, client_addr,
- transport_version, &clock, signed_config,
- &compressed_certs_cache, &full_chlo);
- // Verify that full_chlo can pass crypto_config's verification.
- ShloVerifier shlo_verifier(
- &crypto_config, server_addr, client_addr, &clock, signed_config,
- &compressed_certs_cache,
- ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, transport_version));
- crypto_config.ValidateClientHello(
- full_chlo, client_addr, server_addr, transport_version, &clock,
- signed_config, shlo_verifier.GetValidateClientHelloCallback());
-}
-
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/failing_proof_source.cc b/chromium/net/third_party/quiche/src/quic/test_tools/failing_proof_source.cc
deleted file mode 100644
index 1f17c8a1f35..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/failing_proof_source.cc
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright (c) 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/failing_proof_source.h"
-
-#include "absl/strings/string_view.h"
-
-namespace quic {
-namespace test {
-
-void FailingProofSource::GetProof(const QuicSocketAddress& /*server_address*/,
- const QuicSocketAddress& /*client_address*/,
- const std::string& /*hostname*/,
- const std::string& /*server_config*/,
- QuicTransportVersion /*transport_version*/,
- absl::string_view /*chlo_hash*/,
- std::unique_ptr<Callback> callback) {
- callback->Run(false, nullptr, QuicCryptoProof(), nullptr);
-}
-
-QuicReferenceCountedPointer<ProofSource::Chain>
-FailingProofSource::GetCertChain(const QuicSocketAddress& /*server_address*/,
- const QuicSocketAddress& /*client_address*/,
- const std::string& /*hostname*/,
- bool* cert_matched_sni) {
- *cert_matched_sni = false;
- return QuicReferenceCountedPointer<Chain>();
-}
-
-void FailingProofSource::ComputeTlsSignature(
- const QuicSocketAddress& /*server_address*/,
- const QuicSocketAddress& /*client_address*/,
- const std::string& /*hostname*/,
- uint16_t /*signature_algorithm*/,
- absl::string_view /*in*/,
- std::unique_ptr<SignatureCallback> callback) {
- callback->Run(false, "", nullptr);
-}
-
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/failing_proof_source.h b/chromium/net/third_party/quiche/src/quic/test_tools/failing_proof_source.h
deleted file mode 100644
index db5a19714cb..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/failing_proof_source.h
+++ /dev/null
@@ -1,48 +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_TEST_TOOLS_FAILING_PROOF_SOURCE_H_
-#define QUICHE_QUIC_TEST_TOOLS_FAILING_PROOF_SOURCE_H_
-
-#include "absl/strings/string_view.h"
-#include "quic/core/crypto/proof_source.h"
-
-namespace quic {
-namespace test {
-
-class FailingProofSource : public ProofSource {
- public:
- void GetProof(const QuicSocketAddress& server_address,
- const QuicSocketAddress& client_address,
- const std::string& hostname,
- const std::string& server_config,
- QuicTransportVersion transport_version,
- absl::string_view chlo_hash,
- std::unique_ptr<Callback> callback) override;
-
- QuicReferenceCountedPointer<Chain> GetCertChain(
- const QuicSocketAddress& server_address,
- const QuicSocketAddress& client_address, const std::string& hostname,
- bool* cert_matched_sni) override;
-
- void ComputeTlsSignature(
- const QuicSocketAddress& server_address,
- 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 {
- return {};
- }
-
- TicketCrypter* GetTicketCrypter() override { return nullptr; }
-};
-
-} // namespace test
-} // namespace quic
-
-#endif // QUICHE_QUIC_TEST_TOOLS_FAILING_PROOF_SOURCE_H_
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/fake_proof_source.cc b/chromium/net/third_party/quiche/src/quic/test_tools/fake_proof_source.cc
deleted file mode 100644
index 0f7cb194df6..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/fake_proof_source.cc
+++ /dev/null
@@ -1,158 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/fake_proof_source.h"
-
-#include <utility>
-
-#include "absl/strings/string_view.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/test_tools/crypto_test_utils.h"
-
-namespace quic {
-namespace test {
-
-FakeProofSource::FakeProofSource()
- : delegate_(crypto_test_utils::ProofSourceForTesting()) {}
-
-FakeProofSource::~FakeProofSource() {}
-
-FakeProofSource::PendingOp::~PendingOp() = default;
-
-FakeProofSource::GetProofOp::GetProofOp(
- const QuicSocketAddress& server_addr,
- const QuicSocketAddress& client_address,
- std::string hostname,
- std::string server_config,
- QuicTransportVersion transport_version,
- std::string chlo_hash,
- std::unique_ptr<ProofSource::Callback> callback,
- ProofSource* delegate)
- : server_address_(server_addr),
- client_address_(client_address),
- hostname_(std::move(hostname)),
- server_config_(std::move(server_config)),
- transport_version_(transport_version),
- chlo_hash_(std::move(chlo_hash)),
- callback_(std::move(callback)),
- delegate_(delegate) {}
-
-FakeProofSource::GetProofOp::~GetProofOp() = default;
-
-void FakeProofSource::GetProofOp::Run() {
- // Note: relies on the callback being invoked synchronously
- delegate_->GetProof(server_address_, client_address_, hostname_,
- server_config_, transport_version_, chlo_hash_,
- std::move(callback_));
-}
-
-FakeProofSource::ComputeSignatureOp::ComputeSignatureOp(
- const QuicSocketAddress& server_address,
- const QuicSocketAddress& client_address,
- std::string hostname,
- uint16_t sig_alg,
- absl::string_view in,
- std::unique_ptr<ProofSource::SignatureCallback> callback,
- ProofSource* delegate)
- : server_address_(server_address),
- client_address_(client_address),
- hostname_(std::move(hostname)),
- sig_alg_(sig_alg),
- in_(in),
- callback_(std::move(callback)),
- delegate_(delegate) {}
-
-FakeProofSource::ComputeSignatureOp::~ComputeSignatureOp() = default;
-
-void FakeProofSource::ComputeSignatureOp::Run() {
- delegate_->ComputeTlsSignature(server_address_, client_address_, hostname_,
- sig_alg_, in_, std::move(callback_));
-}
-
-void FakeProofSource::Activate() {
- active_ = true;
-}
-
-void FakeProofSource::GetProof(
- const QuicSocketAddress& server_address,
- const QuicSocketAddress& client_address,
- const std::string& hostname,
- const std::string& server_config,
- QuicTransportVersion transport_version,
- absl::string_view chlo_hash,
- std::unique_ptr<ProofSource::Callback> callback) {
- if (!active_) {
- delegate_->GetProof(server_address, client_address, hostname, server_config,
- transport_version, chlo_hash, std::move(callback));
- return;
- }
-
- pending_ops_.push_back(std::make_unique<GetProofOp>(
- server_address, client_address, hostname, server_config,
- transport_version, std::string(chlo_hash), std::move(callback),
- delegate_.get()));
-}
-
-QuicReferenceCountedPointer<ProofSource::Chain> FakeProofSource::GetCertChain(
- const QuicSocketAddress& server_address,
- const QuicSocketAddress& client_address, const std::string& hostname,
- bool* cert_matched_sni) {
- return delegate_->GetCertChain(server_address, client_address, hostname,
- cert_matched_sni);
-}
-
-void FakeProofSource::ComputeTlsSignature(
- const QuicSocketAddress& server_address,
- const QuicSocketAddress& client_address,
- const std::string& hostname,
- uint16_t signature_algorithm,
- absl::string_view in,
- std::unique_ptr<ProofSource::SignatureCallback> callback) {
- QUIC_LOG(INFO) << "FakeProofSource::ComputeTlsSignature";
- if (!active_) {
- QUIC_LOG(INFO) << "Not active - directly calling delegate";
- delegate_->ComputeTlsSignature(server_address, client_address, hostname,
- signature_algorithm, in,
- std::move(callback));
- return;
- }
-
- QUIC_LOG(INFO) << "Adding pending op";
- pending_ops_.push_back(std::make_unique<ComputeSignatureOp>(
- server_address, client_address, hostname, signature_algorithm, in,
- std::move(callback), delegate_.get()));
-}
-
-absl::InlinedVector<uint16_t, 8>
-FakeProofSource::SupportedTlsSignatureAlgorithms() const {
- return delegate_->SupportedTlsSignatureAlgorithms();
-}
-
-ProofSource::TicketCrypter* FakeProofSource::GetTicketCrypter() {
- if (ticket_crypter_) {
- return ticket_crypter_.get();
- }
- return delegate_->GetTicketCrypter();
-}
-
-void FakeProofSource::SetTicketCrypter(
- std::unique_ptr<TicketCrypter> ticket_crypter) {
- ticket_crypter_ = std::move(ticket_crypter);
-}
-
-int FakeProofSource::NumPendingCallbacks() const {
- return pending_ops_.size();
-}
-
-void FakeProofSource::InvokePendingCallback(int n) {
- QUICHE_CHECK(NumPendingCallbacks() > n);
-
- pending_ops_[n]->Run();
-
- auto it = pending_ops_.begin() + n;
- pending_ops_.erase(it);
-}
-
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/fake_proof_source.h b/chromium/net/third_party/quiche/src/quic/test_tools/fake_proof_source.h
deleted file mode 100644
index b135129c08c..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/fake_proof_source.h
+++ /dev/null
@@ -1,135 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_FAKE_PROOF_SOURCE_H_
-#define QUICHE_QUIC_TEST_TOOLS_FAKE_PROOF_SOURCE_H_
-
-#include <memory>
-#include <string>
-#include <vector>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/crypto/proof_source.h"
-
-namespace quic {
-namespace test {
-
-// Implementation of ProofSource which delegates to a ProofSourceForTesting, but
-// allows for overriding certain functionality. FakeProofSource allows
-// intercepting calls to GetProof and ComputeTlsSignature to force them to run
-// asynchronously, and allow the caller to see that the call is pending and
-// resume the operation at the caller's choosing. FakeProofSource also allows
-// the caller to replace the TicketCrypter provided by
-// FakeProofSource::GetTicketCrypter.
-class FakeProofSource : public ProofSource {
- public:
- FakeProofSource();
- ~FakeProofSource() override;
-
- // Before this object is "active", all calls to GetProof will be delegated
- // immediately. Once "active", the async ones will be intercepted. This
- // distinction is necessary to ensure that GetProof can be called without
- // interference during test case setup.
- void Activate();
-
- // ProofSource interface
- void GetProof(const QuicSocketAddress& server_address,
- const QuicSocketAddress& client_address,
- const std::string& hostname,
- const std::string& server_config,
- QuicTransportVersion transport_version,
- absl::string_view chlo_hash,
- std::unique_ptr<ProofSource::Callback> callback) override;
- QuicReferenceCountedPointer<Chain> GetCertChain(
- const QuicSocketAddress& server_address,
- const QuicSocketAddress& client_address, const std::string& hostname,
- bool* cert_matched_sni) override;
- void ComputeTlsSignature(
- const QuicSocketAddress& server_address,
- const QuicSocketAddress& client_address,
- const std::string& hostname,
- uint16_t signature_algorithm,
- absl::string_view in,
- std::unique_ptr<ProofSource::SignatureCallback> callback) override;
- absl::InlinedVector<uint16_t, 8> SupportedTlsSignatureAlgorithms()
- const override;
- TicketCrypter* GetTicketCrypter() override;
-
- // Sets the TicketCrypter to use. If nullptr, the TicketCrypter from
- // ProofSourceForTesting will be returned instead.
- void SetTicketCrypter(std::unique_ptr<TicketCrypter> ticket_crypter);
-
- // Get the number of callbacks which are pending
- int NumPendingCallbacks() const;
-
- // Invoke a pending callback. The index refers to the position in
- // pending_ops_ of the callback to be completed.
- void InvokePendingCallback(int n);
-
- private:
- std::unique_ptr<ProofSource> delegate_;
- std::unique_ptr<TicketCrypter> ticket_crypter_;
- bool active_ = false;
-
- class PendingOp {
- public:
- virtual ~PendingOp();
- virtual void Run() = 0;
- };
-
- class GetProofOp : public PendingOp {
- public:
- GetProofOp(const QuicSocketAddress& server_addr,
- const QuicSocketAddress& client_address,
- std::string hostname,
- std::string server_config,
- QuicTransportVersion transport_version,
- std::string chlo_hash,
- std::unique_ptr<ProofSource::Callback> callback,
- ProofSource* delegate);
- ~GetProofOp() override;
-
- void Run() override;
-
- private:
- QuicSocketAddress server_address_;
- QuicSocketAddress client_address_;
- std::string hostname_;
- std::string server_config_;
- QuicTransportVersion transport_version_;
- std::string chlo_hash_;
- std::unique_ptr<ProofSource::Callback> callback_;
- ProofSource* delegate_;
- };
-
- class ComputeSignatureOp : public PendingOp {
- public:
- ComputeSignatureOp(const QuicSocketAddress& server_address,
- const QuicSocketAddress& client_address,
- std::string hostname,
- uint16_t sig_alg,
- absl::string_view in,
- std::unique_ptr<ProofSource::SignatureCallback> callback,
- ProofSource* delegate);
- ~ComputeSignatureOp() override;
-
- void Run() override;
-
- private:
- QuicSocketAddress server_address_;
- QuicSocketAddress client_address_;
- std::string hostname_;
- uint16_t sig_alg_;
- std::string in_;
- std::unique_ptr<ProofSource::SignatureCallback> callback_;
- ProofSource* delegate_;
- };
-
- std::vector<std::unique_ptr<PendingOp>> pending_ops_;
-};
-
-} // namespace test
-} // namespace quic
-
-#endif // QUICHE_QUIC_TEST_TOOLS_FAKE_PROOF_SOURCE_H_
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/fake_proof_source_handle.cc b/chromium/net/third_party/quiche/src/quic/test_tools/fake_proof_source_handle.cc
deleted file mode 100644
index 0b2e06f3dfe..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/fake_proof_source_handle.cc
+++ /dev/null
@@ -1,241 +0,0 @@
-// Copyright (c) 2021 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 "quic/test_tools/fake_proof_source_handle.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-
-namespace quic {
-namespace test {
-namespace {
-
-struct QUIC_EXPORT_PRIVATE ComputeSignatureResult {
- bool ok;
- std::string signature;
- std::unique_ptr<ProofSource::Details> details;
-};
-
-class QUIC_EXPORT_PRIVATE ResultSavingSignatureCallback
- : public ProofSource::SignatureCallback {
- public:
- explicit ResultSavingSignatureCallback(
- absl::optional<ComputeSignatureResult>* result)
- : result_(result) {
- QUICHE_DCHECK(!result_->has_value());
- }
- void Run(bool ok,
- std::string signature,
- std::unique_ptr<ProofSource::Details> details) override {
- result_->emplace(
- ComputeSignatureResult{ok, std::move(signature), std::move(details)});
- }
-
- private:
- absl::optional<ComputeSignatureResult>* result_;
-};
-
-ComputeSignatureResult ComputeSignatureNow(
- ProofSource* delegate,
- const QuicSocketAddress& server_address,
- const QuicSocketAddress& client_address,
- const std::string& hostname,
- uint16_t signature_algorithm,
- absl::string_view in) {
- absl::optional<ComputeSignatureResult> result;
- delegate->ComputeTlsSignature(
- server_address, client_address, hostname, signature_algorithm, in,
- std::make_unique<ResultSavingSignatureCallback>(&result));
- QUICHE_CHECK(result.has_value())
- << "delegate->ComputeTlsSignature must computes a "
- "signature immediately";
- return std::move(result.value());
-}
-} // namespace
-
-FakeProofSourceHandle::FakeProofSourceHandle(
- ProofSource* delegate, ProofSourceHandleCallback* callback,
- Action select_cert_action, Action compute_signature_action,
- QuicDelayedSSLConfig dealyed_ssl_config)
- : delegate_(delegate),
- callback_(callback),
- select_cert_action_(select_cert_action),
- compute_signature_action_(compute_signature_action),
- dealyed_ssl_config_(dealyed_ssl_config) {}
-
-void FakeProofSourceHandle::CloseHandle() {
- select_cert_op_.reset();
- compute_signature_op_.reset();
- closed_ = true;
-}
-
-QuicAsyncStatus FakeProofSourceHandle::SelectCertificate(
- const QuicSocketAddress& server_address,
- const QuicSocketAddress& client_address,
- absl::string_view ssl_capabilities,
- const std::string& hostname,
- absl::string_view client_hello,
- const std::string& alpn,
- absl::optional<std::string> alps,
- const std::vector<uint8_t>& quic_transport_params,
- const absl::optional<std::vector<uint8_t>>& early_data_context,
- const QuicSSLConfig& ssl_config) {
- if (select_cert_action_ != Action::FAIL_SYNC_DO_NOT_CHECK_CLOSED) {
- QUICHE_CHECK(!closed_);
- }
- all_select_cert_args_.push_back(SelectCertArgs(
- server_address, client_address, ssl_capabilities, hostname, client_hello,
- alpn, alps, quic_transport_params, early_data_context, ssl_config));
-
- if (select_cert_action_ == Action::DELEGATE_ASYNC ||
- select_cert_action_ == Action::FAIL_ASYNC) {
- select_cert_op_.emplace(delegate_, callback_, select_cert_action_,
- all_select_cert_args_.back(), dealyed_ssl_config_);
- return QUIC_PENDING;
- } else if (select_cert_action_ == Action::FAIL_SYNC ||
- select_cert_action_ == Action::FAIL_SYNC_DO_NOT_CHECK_CLOSED) {
- callback()->OnSelectCertificateDone(
- /*ok=*/false,
- /*is_sync=*/true, nullptr, /*handshake_hints=*/absl::string_view(),
- /*ticket_encryption_key=*/absl::string_view(),
- /*cert_matched_sni=*/false, dealyed_ssl_config_);
- return QUIC_FAILURE;
- }
-
- QUICHE_DCHECK(select_cert_action_ == Action::DELEGATE_SYNC);
- bool cert_matched_sni;
- QuicReferenceCountedPointer<ProofSource::Chain> chain =
- delegate_->GetCertChain(server_address, client_address, hostname,
- &cert_matched_sni);
-
- bool ok = chain && !chain->certs.empty();
- callback_->OnSelectCertificateDone(
- ok, /*is_sync=*/true, chain.get(),
- /*handshake_hints=*/absl::string_view(),
- /*ticket_encryption_key=*/absl::string_view(),
- /*cert_matched_sni=*/cert_matched_sni, dealyed_ssl_config_);
- return ok ? QUIC_SUCCESS : QUIC_FAILURE;
-}
-
-QuicAsyncStatus FakeProofSourceHandle::ComputeSignature(
- const QuicSocketAddress& server_address,
- const QuicSocketAddress& client_address,
- const std::string& hostname,
- uint16_t signature_algorithm,
- absl::string_view in,
- size_t max_signature_size) {
- if (compute_signature_action_ != Action::FAIL_SYNC_DO_NOT_CHECK_CLOSED) {
- QUICHE_CHECK(!closed_);
- }
- all_compute_signature_args_.push_back(
- ComputeSignatureArgs(server_address, client_address, hostname,
- signature_algorithm, in, max_signature_size));
-
- if (compute_signature_action_ == Action::DELEGATE_ASYNC ||
- compute_signature_action_ == Action::FAIL_ASYNC) {
- compute_signature_op_.emplace(delegate_, callback_,
- compute_signature_action_,
- all_compute_signature_args_.back());
- return QUIC_PENDING;
- } else if (compute_signature_action_ == Action::FAIL_SYNC ||
- compute_signature_action_ ==
- Action::FAIL_SYNC_DO_NOT_CHECK_CLOSED) {
- callback()->OnComputeSignatureDone(/*ok=*/false, /*is_sync=*/true,
- /*signature=*/"", /*details=*/nullptr);
- return QUIC_FAILURE;
- }
-
- QUICHE_DCHECK(compute_signature_action_ == Action::DELEGATE_SYNC);
- ComputeSignatureResult result =
- ComputeSignatureNow(delegate_, server_address, client_address, hostname,
- signature_algorithm, in);
- callback_->OnComputeSignatureDone(
- result.ok, /*is_sync=*/true, result.signature, std::move(result.details));
- return result.ok ? QUIC_SUCCESS : QUIC_FAILURE;
-}
-
-ProofSourceHandleCallback* FakeProofSourceHandle::callback() {
- return callback_;
-}
-
-bool FakeProofSourceHandle::HasPendingOperation() const {
- int num_pending_operations = NumPendingOperations();
- return num_pending_operations > 0;
-}
-
-void FakeProofSourceHandle::CompletePendingOperation() {
- QUICHE_DCHECK_LE(NumPendingOperations(), 1);
-
- if (select_cert_op_.has_value()) {
- select_cert_op_->Run();
- select_cert_op_.reset();
- } else if (compute_signature_op_.has_value()) {
- compute_signature_op_->Run();
- compute_signature_op_.reset();
- }
-}
-
-int FakeProofSourceHandle::NumPendingOperations() const {
- return static_cast<int>(select_cert_op_.has_value()) +
- static_cast<int>(compute_signature_op_.has_value());
-}
-
-FakeProofSourceHandle::SelectCertOperation::SelectCertOperation(
- ProofSource* delegate, ProofSourceHandleCallback* callback, Action action,
- SelectCertArgs args, QuicDelayedSSLConfig dealyed_ssl_config)
- : PendingOperation(delegate, callback, action),
- args_(std::move(args)),
- dealyed_ssl_config_(dealyed_ssl_config) {}
-
-void FakeProofSourceHandle::SelectCertOperation::Run() {
- if (action_ == Action::FAIL_ASYNC) {
- callback_->OnSelectCertificateDone(
- /*ok=*/false,
- /*is_sync=*/false, nullptr,
- /*handshake_hints=*/absl::string_view(),
- /*ticket_encryption_key=*/absl::string_view(),
- /*cert_matched_sni=*/false, dealyed_ssl_config_);
- } else if (action_ == Action::DELEGATE_ASYNC) {
- bool cert_matched_sni;
- QuicReferenceCountedPointer<ProofSource::Chain> chain =
- delegate_->GetCertChain(args_.server_address, args_.client_address,
- args_.hostname, &cert_matched_sni);
- bool ok = chain && !chain->certs.empty();
- callback_->OnSelectCertificateDone(
- ok, /*is_sync=*/false, chain.get(),
- /*handshake_hints=*/absl::string_view(),
- /*ticket_encryption_key=*/absl::string_view(),
- /*cert_matched_sni=*/cert_matched_sni, dealyed_ssl_config_);
- } else {
- QUIC_BUG(quic_bug_10139_1)
- << "Unexpected action: " << static_cast<int>(action_);
- }
-}
-
-FakeProofSourceHandle::ComputeSignatureOperation::ComputeSignatureOperation(
- ProofSource* delegate,
- ProofSourceHandleCallback* callback,
- Action action,
- ComputeSignatureArgs args)
- : PendingOperation(delegate, callback, action), args_(std::move(args)) {}
-
-void FakeProofSourceHandle::ComputeSignatureOperation::Run() {
- if (action_ == Action::FAIL_ASYNC) {
- callback_->OnComputeSignatureDone(
- /*ok=*/false, /*is_sync=*/false,
- /*signature=*/"", /*details=*/nullptr);
- } else if (action_ == Action::DELEGATE_ASYNC) {
- ComputeSignatureResult result = ComputeSignatureNow(
- delegate_, args_.server_address, args_.client_address, args_.hostname,
- args_.signature_algorithm, args_.in);
- callback_->OnComputeSignatureDone(result.ok, /*is_sync=*/false,
- result.signature,
- std::move(result.details));
- } else {
- QUIC_BUG(quic_bug_10139_2)
- << "Unexpected action: " << static_cast<int>(action_);
- }
-}
-
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/fake_proof_source_handle.h b/chromium/net/third_party/quiche/src/quic/test_tools/fake_proof_source_handle.h
deleted file mode 100644
index bb2c60e4793..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/fake_proof_source_handle.h
+++ /dev/null
@@ -1,201 +0,0 @@
-// Copyright (c) 2021 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_FAKE_PROOF_SOURCE_HANDLE_H_
-#define QUICHE_QUIC_TEST_TOOLS_FAKE_PROOF_SOURCE_HANDLE_H_
-
-#include "quic/core/crypto/proof_source.h"
-
-namespace quic {
-namespace test {
-
-// FakeProofSourceHandle allows its behavior to be scripted for testing.
-class FakeProofSourceHandle : public ProofSourceHandle {
- public:
- // What would an operation return when it is called.
- enum class Action {
- // Delegate the operation to |delegate_| immediately.
- DELEGATE_SYNC = 0,
- // Handle the operation asynchronously. Delegate the operation to
- // |delegate_| when the caller calls CompletePendingOperation().
- DELEGATE_ASYNC,
- // Fail the operation immediately.
- FAIL_SYNC,
- // Handle the operation asynchronously. Fail the operation when the caller
- // calls CompletePendingOperation().
- FAIL_ASYNC,
- // Similar to FAIL_SYNC, but do not QUICHE_CHECK(!closed_) when invoked.
- FAIL_SYNC_DO_NOT_CHECK_CLOSED,
- };
-
- // |delegate| must do cert selection and signature synchronously.
- // |dealyed_ssl_config| is the config passed to OnSelectCertificateDone.
- FakeProofSourceHandle(
- ProofSource* delegate, ProofSourceHandleCallback* callback,
- Action select_cert_action, Action compute_signature_action,
- QuicDelayedSSLConfig dealyed_ssl_config = QuicDelayedSSLConfig());
-
- ~FakeProofSourceHandle() override = default;
-
- void CloseHandle() override;
-
- QuicAsyncStatus SelectCertificate(
- const QuicSocketAddress& server_address,
- const QuicSocketAddress& client_address,
- absl::string_view ssl_capabilities,
- const std::string& hostname,
- absl::string_view client_hello,
- const std::string& alpn,
- absl::optional<std::string> alps,
- const std::vector<uint8_t>& quic_transport_params,
- const absl::optional<std::vector<uint8_t>>& early_data_context,
- const QuicSSLConfig& ssl_config) override;
-
- QuicAsyncStatus ComputeSignature(const QuicSocketAddress& server_address,
- const QuicSocketAddress& client_address,
- const std::string& hostname,
- uint16_t signature_algorithm,
- absl::string_view in,
- size_t max_signature_size) override;
-
- ProofSourceHandleCallback* callback() override;
-
- // Whether there's a pending operation in |this|.
- bool HasPendingOperation() const;
- void CompletePendingOperation();
-
- struct SelectCertArgs {
- SelectCertArgs(QuicSocketAddress server_address,
- QuicSocketAddress client_address,
- absl::string_view ssl_capabilities,
- std::string hostname,
- absl::string_view client_hello,
- std::string alpn,
- absl::optional<std::string> alps,
- std::vector<uint8_t> quic_transport_params,
- absl::optional<std::vector<uint8_t>> early_data_context,
- QuicSSLConfig ssl_config)
- : server_address(server_address),
- client_address(client_address),
- ssl_capabilities(ssl_capabilities),
- hostname(hostname),
- client_hello(client_hello),
- alpn(alpn),
- alps(alps),
- quic_transport_params(quic_transport_params),
- early_data_context(early_data_context),
- ssl_config(ssl_config) {}
-
- QuicSocketAddress server_address;
- QuicSocketAddress client_address;
- std::string ssl_capabilities;
- std::string hostname;
- std::string client_hello;
- std::string alpn;
- absl::optional<std::string> alps;
- std::vector<uint8_t> quic_transport_params;
- absl::optional<std::vector<uint8_t>> early_data_context;
- QuicSSLConfig ssl_config;
- };
-
- struct ComputeSignatureArgs {
- ComputeSignatureArgs(QuicSocketAddress server_address,
- QuicSocketAddress client_address,
- std::string hostname,
- uint16_t signature_algorithm,
- absl::string_view in,
- size_t max_signature_size)
- : server_address(server_address),
- client_address(client_address),
- hostname(hostname),
- signature_algorithm(signature_algorithm),
- in(in),
- max_signature_size(max_signature_size) {}
-
- QuicSocketAddress server_address;
- QuicSocketAddress client_address;
- std::string hostname;
- uint16_t signature_algorithm;
- std::string in;
- size_t max_signature_size;
- };
-
- std::vector<SelectCertArgs> all_select_cert_args() const {
- return all_select_cert_args_;
- }
-
- std::vector<ComputeSignatureArgs> all_compute_signature_args() const {
- return all_compute_signature_args_;
- }
-
- private:
- class PendingOperation {
- public:
- PendingOperation(ProofSource* delegate,
- ProofSourceHandleCallback* callback,
- Action action)
- : delegate_(delegate), callback_(callback), action_(action) {}
- virtual ~PendingOperation() = default;
- virtual void Run() = 0;
-
- protected:
- ProofSource* delegate_;
- ProofSourceHandleCallback* callback_;
- Action action_;
- };
-
- class SelectCertOperation : public PendingOperation {
- public:
- SelectCertOperation(ProofSource* delegate,
- ProofSourceHandleCallback* callback, Action action,
- SelectCertArgs args,
- QuicDelayedSSLConfig dealyed_ssl_config);
-
- ~SelectCertOperation() override = default;
-
- void Run() override;
-
- private:
- const SelectCertArgs args_;
- const QuicDelayedSSLConfig dealyed_ssl_config_;
- };
-
- class ComputeSignatureOperation : public PendingOperation {
- public:
- ComputeSignatureOperation(ProofSource* delegate,
- ProofSourceHandleCallback* callback,
- Action action,
- ComputeSignatureArgs args);
-
- ~ComputeSignatureOperation() override = default;
-
- void Run() override;
-
- private:
- const ComputeSignatureArgs args_;
- };
-
- private:
- int NumPendingOperations() const;
-
- bool closed_ = false;
- ProofSource* delegate_;
- ProofSourceHandleCallback* callback_;
- // Action for the next select cert operation.
- Action select_cert_action_ = Action::DELEGATE_SYNC;
- // Action for the next compute signature operation.
- Action compute_signature_action_ = Action::DELEGATE_SYNC;
- const QuicDelayedSSLConfig dealyed_ssl_config_;
- absl::optional<SelectCertOperation> select_cert_op_;
- absl::optional<ComputeSignatureOperation> compute_signature_op_;
-
- // Save all the select cert and compute signature args for tests to inspect.
- std::vector<SelectCertArgs> all_select_cert_args_;
- std::vector<ComputeSignatureArgs> all_compute_signature_args_;
-};
-
-} // namespace test
-} // namespace quic
-
-#endif // QUICHE_QUIC_TEST_TOOLS_FAKE_PROOF_SOURCE_HANDLE_H_
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/first_flight.cc b/chromium/net/third_party/quiche/src/quic/test_tools/first_flight.cc
deleted file mode 100644
index ec0a5e358fb..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/first_flight.cc
+++ /dev/null
@@ -1,163 +0,0 @@
-// Copyright (c) 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/first_flight.h"
-
-#include <memory>
-#include <vector>
-
-#include "quic/core/crypto/quic_crypto_client_config.h"
-#include "quic/core/http/quic_client_push_promise_index.h"
-#include "quic/core/http/quic_spdy_client_session.h"
-#include "quic/core/quic_config.h"
-#include "quic/core/quic_connection.h"
-#include "quic/core/quic_connection_id.h"
-#include "quic/core/quic_packet_writer.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_versions.h"
-#include "quic/platform/api/quic_ip_address.h"
-#include "quic/platform/api/quic_socket_address.h"
-#include "quic/test_tools/crypto_test_utils.h"
-#include "quic/test_tools/quic_test_utils.h"
-
-namespace quic {
-namespace test {
-
-// Utility class that creates a custom HTTP/3 session and QUIC connection in
-// order to extract the first flight of packets it sends. This is meant to only
-// be used by GetFirstFlightOfPackets() below.
-class FirstFlightExtractor : public DelegatedPacketWriter::Delegate {
- public:
- FirstFlightExtractor(const ParsedQuicVersion& version,
- const QuicConfig& config,
- const QuicConnectionId& server_connection_id,
- const QuicConnectionId& client_connection_id,
- std::unique_ptr<QuicCryptoClientConfig> crypto_config)
- : version_(version),
- server_connection_id_(server_connection_id),
- client_connection_id_(client_connection_id),
- writer_(this),
- config_(config),
- crypto_config_(std::move(crypto_config)) {
- EXPECT_NE(version_, UnsupportedQuicVersion());
- }
-
- FirstFlightExtractor(const ParsedQuicVersion& version,
- const QuicConfig& config,
- const QuicConnectionId& server_connection_id,
- const QuicConnectionId& client_connection_id)
- : FirstFlightExtractor(
- version, config, server_connection_id, client_connection_id,
- std::make_unique<QuicCryptoClientConfig>(
- crypto_test_utils::ProofVerifierForTesting())) {}
-
- void GenerateFirstFlight() {
- crypto_config_->set_alpn(AlpnForVersion(version_));
- connection_ =
- new QuicConnection(server_connection_id_,
- /*initial_self_address=*/QuicSocketAddress(),
- QuicSocketAddress(TestPeerIPAddress(), kTestPort),
- &connection_helper_, &alarm_factory_, &writer_,
- /*owns_writer=*/false, Perspective::IS_CLIENT,
- ParsedQuicVersionVector{version_});
- connection_->set_client_connection_id(client_connection_id_);
- session_ = std::make_unique<QuicSpdyClientSession>(
- config_, ParsedQuicVersionVector{version_},
- connection_, // session_ takes ownership of connection_ here.
- TestServerId(), crypto_config_.get(), &push_promise_index_);
- session_->Initialize();
- session_->CryptoConnect();
- }
-
- void OnDelegatedPacket(const char* buffer,
- size_t buf_len,
- const QuicIpAddress& /*self_client_address*/,
- const QuicSocketAddress& /*peer_client_address*/,
- PerPacketOptions* /*options*/) override {
- packets_.emplace_back(
- QuicReceivedPacket(buffer, buf_len,
- connection_helper_.GetClock()->ApproximateNow(),
- /*owns_buffer=*/false)
- .Clone());
- }
-
- std::vector<std::unique_ptr<QuicReceivedPacket>>&& ConsumePackets() {
- return std::move(packets_);
- }
-
- private:
- ParsedQuicVersion version_;
- QuicConnectionId server_connection_id_;
- QuicConnectionId client_connection_id_;
- MockQuicConnectionHelper connection_helper_;
- MockAlarmFactory alarm_factory_;
- DelegatedPacketWriter writer_;
- QuicConfig config_;
- std::unique_ptr<QuicCryptoClientConfig> crypto_config_;
- QuicClientPushPromiseIndex push_promise_index_;
- QuicConnection* connection_; // Owned by session_.
- std::unique_ptr<QuicSpdyClientSession> session_;
- std::vector<std::unique_ptr<QuicReceivedPacket>> packets_;
-};
-
-std::vector<std::unique_ptr<QuicReceivedPacket>> GetFirstFlightOfPackets(
- const ParsedQuicVersion& version, const QuicConfig& config,
- const QuicConnectionId& server_connection_id,
- const QuicConnectionId& client_connection_id,
- std::unique_ptr<QuicCryptoClientConfig> crypto_config) {
- FirstFlightExtractor first_flight_extractor(
- version, config, server_connection_id, client_connection_id,
- std::move(crypto_config));
- first_flight_extractor.GenerateFirstFlight();
- return first_flight_extractor.ConsumePackets();
-}
-
-std::vector<std::unique_ptr<QuicReceivedPacket>> GetFirstFlightOfPackets(
- const ParsedQuicVersion& version,
- const QuicConfig& config,
- const QuicConnectionId& server_connection_id,
- const QuicConnectionId& client_connection_id) {
- FirstFlightExtractor first_flight_extractor(
- version, config, server_connection_id, client_connection_id);
- first_flight_extractor.GenerateFirstFlight();
- return first_flight_extractor.ConsumePackets();
-}
-
-std::vector<std::unique_ptr<QuicReceivedPacket>> GetFirstFlightOfPackets(
- const ParsedQuicVersion& version,
- const QuicConfig& config,
- const QuicConnectionId& server_connection_id) {
- return GetFirstFlightOfPackets(version, config, server_connection_id,
- EmptyQuicConnectionId());
-}
-
-std::vector<std::unique_ptr<QuicReceivedPacket>> GetFirstFlightOfPackets(
- const ParsedQuicVersion& version,
- const QuicConfig& config) {
- return GetFirstFlightOfPackets(version, config, TestConnectionId());
-}
-
-std::vector<std::unique_ptr<QuicReceivedPacket>> GetFirstFlightOfPackets(
- const ParsedQuicVersion& version,
- const QuicConnectionId& server_connection_id,
- const QuicConnectionId& client_connection_id) {
- return GetFirstFlightOfPackets(version, DefaultQuicConfig(),
- server_connection_id, client_connection_id);
-}
-
-std::vector<std::unique_ptr<QuicReceivedPacket>> GetFirstFlightOfPackets(
- const ParsedQuicVersion& version,
- const QuicConnectionId& server_connection_id) {
- return GetFirstFlightOfPackets(version, DefaultQuicConfig(),
- server_connection_id, EmptyQuicConnectionId());
-}
-
-std::vector<std::unique_ptr<QuicReceivedPacket>> GetFirstFlightOfPackets(
- const ParsedQuicVersion& version) {
- return GetFirstFlightOfPackets(version, DefaultQuicConfig(),
- TestConnectionId());
-}
-
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/first_flight.h b/chromium/net/third_party/quiche/src/quic/test_tools/first_flight.h
deleted file mode 100644
index 448a189440c..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/first_flight.h
+++ /dev/null
@@ -1,119 +0,0 @@
-// Copyright (c) 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_FIRST_FLIGHT_H_
-#define QUICHE_QUIC_TEST_TOOLS_FIRST_FLIGHT_H_
-
-#include <memory>
-#include <vector>
-
-#include "quic/core/crypto/quic_crypto_client_config.h"
-#include "quic/core/quic_config.h"
-#include "quic/core/quic_connection_id.h"
-#include "quic/core/quic_packet_writer.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_versions.h"
-#include "quic/platform/api/quic_ip_address.h"
-#include "quic/platform/api/quic_socket_address.h"
-
-namespace quic {
-namespace test {
-
-// Implementation of QuicPacketWriter that sends all packets to a delegate.
-class QUIC_NO_EXPORT DelegatedPacketWriter : public QuicPacketWriter {
- public:
- class QUIC_NO_EXPORT Delegate {
- public:
- virtual ~Delegate() {}
- // Note that |buffer| may be released after this call completes so overrides
- // that want to use the data after the call is complete MUST copy it.
- virtual void OnDelegatedPacket(const char* buffer,
- size_t buf_len,
- const QuicIpAddress& self_client_address,
- const QuicSocketAddress& peer_client_address,
- PerPacketOptions* options) = 0;
- };
-
- // |delegate| MUST be valid for the duration of the DelegatedPacketWriter's
- // lifetime.
- explicit DelegatedPacketWriter(Delegate* delegate) : delegate_(delegate) {
- QUICHE_CHECK_NE(delegate_, nullptr);
- }
-
- // Overrides for QuicPacketWriter.
- bool IsWriteBlocked() const override { return false; }
- void SetWritable() override {}
- QuicByteCount GetMaxPacketSize(
- const QuicSocketAddress& /*peer_address*/) const override {
- return kMaxOutgoingPacketSize;
- }
- bool SupportsReleaseTime() const override { return false; }
- bool IsBatchMode() const override { return false; }
- QuicPacketBuffer GetNextWriteLocation(
- const QuicIpAddress& /*self_address*/,
- const QuicSocketAddress& /*peer_address*/) override {
- return {nullptr, nullptr};
- }
- WriteResult Flush() override { return WriteResult(WRITE_STATUS_OK, 0); }
-
- WriteResult WritePacket(const char* buffer,
- size_t buf_len,
- const QuicIpAddress& self_client_address,
- const QuicSocketAddress& peer_client_address,
- PerPacketOptions* options) override {
- delegate_->OnDelegatedPacket(buffer, buf_len, self_client_address,
- peer_client_address, options);
- return WriteResult(WRITE_STATUS_OK, buf_len);
- }
-
- private:
- Delegate* delegate_; // Unowned.
-};
-
-// Returns an array of packets that represent the first flight of a real
-// HTTP/3 connection. In most cases, this array will only contain one packet
-// that carries the CHLO.
-std::vector<std::unique_ptr<QuicReceivedPacket>> GetFirstFlightOfPackets(
- const ParsedQuicVersion& version, const QuicConfig& config,
- const QuicConnectionId& server_connection_id,
- const QuicConnectionId& client_connection_id,
- std::unique_ptr<QuicCryptoClientConfig> crypto_config);
-
-// Below are various convenience overloads that use default values for the
-// omitted parameters:
-// |config| = DefaultQuicConfig(),
-// |server_connection_id| = TestConnectionId(),
-// |client_connection_id| = EmptyQuicConnectionId().
-// |crypto_config| =
-// QuicCryptoClientConfig(crypto_test_utils::ProofVerifierForTesting())
-std::vector<std::unique_ptr<QuicReceivedPacket>> GetFirstFlightOfPackets(
- const ParsedQuicVersion& version, const QuicConfig& config,
- const QuicConnectionId& server_connection_id,
- const QuicConnectionId& client_connection_id);
-
-std::vector<std::unique_ptr<QuicReceivedPacket>> GetFirstFlightOfPackets(
- const ParsedQuicVersion& version,
- const QuicConfig& config,
- const QuicConnectionId& server_connection_id);
-
-std::vector<std::unique_ptr<QuicReceivedPacket>> GetFirstFlightOfPackets(
- const ParsedQuicVersion& version,
- const QuicConnectionId& server_connection_id,
- const QuicConnectionId& client_connection_id);
-
-std::vector<std::unique_ptr<QuicReceivedPacket>> GetFirstFlightOfPackets(
- const ParsedQuicVersion& version,
- const QuicConnectionId& server_connection_id);
-
-std::vector<std::unique_ptr<QuicReceivedPacket>> GetFirstFlightOfPackets(
- const ParsedQuicVersion& version,
- const QuicConfig& config);
-
-std::vector<std::unique_ptr<QuicReceivedPacket>> GetFirstFlightOfPackets(
- const ParsedQuicVersion& version);
-
-} // namespace test
-} // namespace quic
-
-#endif // QUICHE_QUIC_TEST_TOOLS_FIRST_FLIGHT_H_
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/limited_mtu_test_writer.cc b/chromium/net/third_party/quiche/src/quic/test_tools/limited_mtu_test_writer.cc
deleted file mode 100644
index 5bbf7f70c2c..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/limited_mtu_test_writer.cc
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright (c) 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/limited_mtu_test_writer.h"
-
-namespace quic {
-namespace test {
-
-LimitedMtuTestWriter::LimitedMtuTestWriter(QuicByteCount mtu) : mtu_(mtu) {}
-
-LimitedMtuTestWriter::~LimitedMtuTestWriter() = default;
-
-WriteResult LimitedMtuTestWriter::WritePacket(
- const char* buffer,
- size_t buf_len,
- const QuicIpAddress& self_address,
- const QuicSocketAddress& peer_address,
- PerPacketOptions* options) {
- if (buf_len > mtu_) {
- // Drop the packet.
- return WriteResult(WRITE_STATUS_OK, buf_len);
- }
-
- return QuicPacketWriterWrapper::WritePacket(buffer, buf_len, self_address,
- peer_address, options);
-}
-
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/limited_mtu_test_writer.h b/chromium/net/third_party/quiche/src/quic/test_tools/limited_mtu_test_writer.h
deleted file mode 100644
index 08f659c6125..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/limited_mtu_test_writer.h
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright (c) 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_LIMITED_MTU_TEST_WRITER_H_
-#define QUICHE_QUIC_TEST_TOOLS_LIMITED_MTU_TEST_WRITER_H_
-
-#include "quic/core/quic_packet_writer_wrapper.h"
-#include "quic/core/quic_packets.h"
-
-namespace quic {
-namespace test {
-
-// Simulates a connection over a link with fixed MTU. Drops packets which
-// exceed the MTU and passes the rest of them as-is.
-class LimitedMtuTestWriter : public QuicPacketWriterWrapper {
- public:
- explicit LimitedMtuTestWriter(QuicByteCount mtu);
- LimitedMtuTestWriter(const LimitedMtuTestWriter&) = delete;
- LimitedMtuTestWriter& operator=(const LimitedMtuTestWriter&) = delete;
- ~LimitedMtuTestWriter() override;
-
- // Inherited from QuicPacketWriterWrapper.
- WriteResult WritePacket(const char* buffer,
- size_t buf_len,
- const QuicIpAddress& self_address,
- const QuicSocketAddress& peer_address,
- PerPacketOptions* options) override;
-
- private:
- QuicByteCount mtu_;
-};
-
-} // namespace test
-} // namespace quic
-
-#endif // QUICHE_QUIC_TEST_TOOLS_LIMITED_MTU_TEST_WRITER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/mock_clock.cc b/chromium/net/third_party/quiche/src/quic/test_tools/mock_clock.cc
deleted file mode 100644
index 15af152c6df..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/mock_clock.cc
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/mock_clock.h"
-
-namespace quic {
-
-MockClock::MockClock() : now_(QuicTime::Zero()) {}
-
-MockClock::~MockClock() {}
-
-void MockClock::AdvanceTime(QuicTime::Delta delta) {
- now_ = now_ + delta;
-}
-
-void MockClock::Reset() {
- now_ = QuicTime::Zero();
-}
-
-QuicTime MockClock::Now() const {
- return now_;
-}
-
-QuicTime MockClock::ApproximateNow() const {
- return now_;
-}
-
-QuicWallTime MockClock::WallNow() const {
- return QuicWallTime::FromUNIXSeconds((now_ - QuicTime::Zero()).ToSeconds());
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/mock_clock.h b/chromium/net/third_party/quiche/src/quic/test_tools/mock_clock.h
deleted file mode 100644
index 2ba25a25ee4..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/mock_clock.h
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_MOCK_CLOCK_H_
-#define QUICHE_QUIC_TEST_TOOLS_MOCK_CLOCK_H_
-
-#include "quic/core/quic_clock.h"
-#include "quic/core/quic_time.h"
-
-namespace quic {
-
-class MockClock : public QuicClock {
- public:
- MockClock();
- MockClock(const MockClock&) = delete;
- MockClock& operator=(const MockClock&) = delete;
- ~MockClock() override;
-
- // QuicClock implementation:
- QuicTime Now() const override;
- QuicTime ApproximateNow() const override;
- QuicWallTime WallNow() const override;
-
- // Advances the current time by |delta|, which may be negative.
- void AdvanceTime(QuicTime::Delta delta);
- // Resets time back to zero.
- void Reset();
-
- private:
- QuicTime now_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_TEST_TOOLS_MOCK_CLOCK_H_
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/mock_quic_client_promised_info.cc b/chromium/net/third_party/quiche/src/quic/test_tools/mock_quic_client_promised_info.cc
deleted file mode 100644
index 717641b868e..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/mock_quic_client_promised_info.cc
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/mock_quic_client_promised_info.h"
-
-namespace quic {
-namespace test {
-
-MockQuicClientPromisedInfo::MockQuicClientPromisedInfo(
- QuicSpdyClientSessionBase* session,
- QuicStreamId id,
- std::string url)
- : QuicClientPromisedInfo(session, id, url) {}
-
-MockQuicClientPromisedInfo::~MockQuicClientPromisedInfo() {}
-
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/mock_quic_client_promised_info.h b/chromium/net/third_party/quiche/src/quic/test_tools/mock_quic_client_promised_info.h
deleted file mode 100644
index d40a647f480..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/mock_quic_client_promised_info.h
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_MOCK_QUIC_CLIENT_PROMISED_INFO_H_
-#define QUICHE_QUIC_TEST_TOOLS_MOCK_QUIC_CLIENT_PROMISED_INFO_H_
-
-#include <string>
-
-#include "quic/core/http/quic_client_promised_info.h"
-#include "quic/core/quic_packets.h"
-#include "quic/platform/api/quic_test.h"
-
-namespace quic {
-namespace test {
-
-class MockQuicClientPromisedInfo : public QuicClientPromisedInfo {
- public:
- MockQuicClientPromisedInfo(QuicSpdyClientSessionBase* session,
- QuicStreamId id,
- std::string url);
- ~MockQuicClientPromisedInfo() override;
-
- MOCK_METHOD(QuicAsyncStatus,
- HandleClientRequest,
- (const spdy::SpdyHeaderBlock& headers,
- QuicClientPushPromiseIndex::Delegate*),
- (override));
-};
-
-} // namespace test
-} // namespace quic
-
-#endif // QUICHE_QUIC_TEST_TOOLS_MOCK_QUIC_CLIENT_PROMISED_INFO_H_
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/mock_quic_dispatcher.cc b/chromium/net/third_party/quiche/src/quic/test_tools/mock_quic_dispatcher.cc
deleted file mode 100644
index 38424901ab9..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/mock_quic_dispatcher.cc
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/mock_quic_dispatcher.h"
-
-#include "quic/test_tools/quic_test_utils.h"
-
-namespace quic {
-namespace test {
-
-MockQuicDispatcher::MockQuicDispatcher(
- 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,
- QuicSimpleServerBackend* quic_simple_server_backend)
- : QuicSimpleDispatcher(config,
- crypto_config,
- version_manager,
- std::move(helper),
- std::move(session_helper),
- std::move(alarm_factory),
- quic_simple_server_backend,
- kQuicDefaultConnectionIdLength) {}
-
-MockQuicDispatcher::~MockQuicDispatcher() {}
-
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/mock_quic_dispatcher.h b/chromium/net/third_party/quiche/src/quic/test_tools/mock_quic_dispatcher.h
deleted file mode 100644
index 7d7bec506b9..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/mock_quic_dispatcher.h
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_MOCK_QUIC_DISPATCHER_H_
-#define QUICHE_QUIC_TEST_TOOLS_MOCK_QUIC_DISPATCHER_H_
-
-#include "quic/core/crypto/quic_crypto_server_config.h"
-#include "quic/core/quic_config.h"
-#include "quic/core/quic_packets.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/tools/quic_simple_dispatcher.h"
-#include "quic/tools/quic_simple_server_backend.h"
-
-namespace quic {
-namespace test {
-
-class MockQuicDispatcher : public QuicSimpleDispatcher {
- public:
- MockQuicDispatcher(
- 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,
- QuicSimpleServerBackend* quic_simple_server_backend);
- MockQuicDispatcher(const MockQuicDispatcher&) = delete;
- MockQuicDispatcher& operator=(const MockQuicDispatcher&) = delete;
-
- ~MockQuicDispatcher() override;
-
- MOCK_METHOD(void,
- ProcessPacket,
- (const QuicSocketAddress& server_address,
- const QuicSocketAddress& client_address,
- const QuicReceivedPacket& packet),
- (override));
-};
-
-} // namespace test
-} // namespace quic
-
-#endif // QUICHE_QUIC_TEST_TOOLS_MOCK_QUIC_DISPATCHER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/mock_quic_session_visitor.cc b/chromium/net/third_party/quiche/src/quic/test_tools/mock_quic_session_visitor.cc
deleted file mode 100644
index 5c5db3e8167..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/mock_quic_session_visitor.cc
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/mock_quic_session_visitor.h"
-
-namespace quic {
-namespace test {
-
-MockQuicSessionVisitor::MockQuicSessionVisitor() = default;
-
-MockQuicSessionVisitor::~MockQuicSessionVisitor() = default;
-
-MockQuicCryptoServerStreamHelper::MockQuicCryptoServerStreamHelper() = default;
-
-MockQuicCryptoServerStreamHelper::~MockQuicCryptoServerStreamHelper() = default;
-
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/mock_quic_session_visitor.h b/chromium/net/third_party/quiche/src/quic/test_tools/mock_quic_session_visitor.h
deleted file mode 100644
index 77b176302a3..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/mock_quic_session_visitor.h
+++ /dev/null
@@ -1,74 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_MOCK_QUIC_SESSION_VISITOR_H_
-#define QUICHE_QUIC_TEST_TOOLS_MOCK_QUIC_SESSION_VISITOR_H_
-
-#include "quic/core/quic_crypto_server_stream_base.h"
-#include "quic/core/quic_time_wait_list_manager.h"
-#include "quic/platform/api/quic_test.h"
-
-namespace quic {
-namespace test {
-
-class MockQuicSessionVisitor : public QuicTimeWaitListManager::Visitor {
- public:
- MockQuicSessionVisitor();
- MockQuicSessionVisitor(const MockQuicSessionVisitor&) = delete;
- MockQuicSessionVisitor& operator=(const MockQuicSessionVisitor&) = delete;
- ~MockQuicSessionVisitor() override;
- MOCK_METHOD(void,
- OnConnectionClosed,
- (QuicConnectionId connection_id,
- QuicErrorCode error,
- const std::string& error_details,
- ConnectionCloseSource source),
- (override));
- MOCK_METHOD(void, OnWriteBlocked, (QuicBlockedWriterInterface*), (override));
- MOCK_METHOD(void,
- OnRstStreamReceived,
- (const QuicRstStreamFrame& frame),
- (override));
- MOCK_METHOD(void,
- OnStopSendingReceived,
- (const QuicStopSendingFrame& frame),
- (override));
- MOCK_METHOD(void,
- OnNewConnectionIdSent,
- (const QuicConnectionId& server_connection_id,
- const QuicConnectionId& new_connection_id),
- (override));
- MOCK_METHOD(void,
- OnConnectionIdRetired,
- (const quic::QuicConnectionId& server_connection_id),
- (override));
- MOCK_METHOD(void,
- OnConnectionAddedToTimeWaitList,
- (QuicConnectionId connection_id),
- (override));
-};
-
-class MockQuicCryptoServerStreamHelper
- : public QuicCryptoServerStreamBase::Helper {
- public:
- MockQuicCryptoServerStreamHelper();
- MockQuicCryptoServerStreamHelper(const MockQuicCryptoServerStreamHelper&) =
- delete;
- MockQuicCryptoServerStreamHelper& operator=(
- const MockQuicCryptoServerStreamHelper&) = delete;
- ~MockQuicCryptoServerStreamHelper() override;
- MOCK_METHOD(bool,
- CanAcceptClientHello,
- (const CryptoHandshakeMessage& message,
- const QuicSocketAddress& client_address,
- const QuicSocketAddress& peer_address,
- const QuicSocketAddress& self_address,
- std::string*),
- (const, override));
-};
-
-} // namespace test
-} // namespace quic
-
-#endif // QUICHE_QUIC_TEST_TOOLS_MOCK_QUIC_SESSION_VISITOR_H_
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/mock_quic_spdy_client_stream.cc b/chromium/net/third_party/quiche/src/quic/test_tools/mock_quic_spdy_client_stream.cc
deleted file mode 100644
index fdaa762b32a..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/mock_quic_spdy_client_stream.cc
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/mock_quic_spdy_client_stream.h"
-
-namespace quic {
-namespace test {
-
-MockQuicSpdyClientStream::MockQuicSpdyClientStream(
- QuicStreamId id,
- QuicSpdyClientSession* session,
- StreamType type)
- : QuicSpdyClientStream(id, session, type) {}
-
-MockQuicSpdyClientStream::~MockQuicSpdyClientStream() {}
-
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/mock_quic_spdy_client_stream.h b/chromium/net/third_party/quiche/src/quic/test_tools/mock_quic_spdy_client_stream.h
deleted file mode 100644
index 491f7009f85..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/mock_quic_spdy_client_stream.h
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_MOCK_QUIC_SPDY_CLIENT_STREAM_H_
-#define QUICHE_QUIC_TEST_TOOLS_MOCK_QUIC_SPDY_CLIENT_STREAM_H_
-
-#include "quic/core/http/quic_header_list.h"
-#include "quic/core/http/quic_spdy_client_stream.h"
-#include "quic/core/quic_packets.h"
-#include "quic/platform/api/quic_test.h"
-
-namespace quic {
-namespace test {
-
-class MockQuicSpdyClientStream : public QuicSpdyClientStream {
- public:
- MockQuicSpdyClientStream(QuicStreamId id,
- QuicSpdyClientSession* session,
- StreamType type);
- ~MockQuicSpdyClientStream() override;
-
- MOCK_METHOD(void, OnStreamFrame, (const QuicStreamFrame& frame), (override));
- MOCK_METHOD(void,
- OnPromiseHeaderList,
- (QuicStreamId promised_stream_id,
- size_t frame_len,
- const QuicHeaderList& list),
- (override));
- MOCK_METHOD(void, OnDataAvailable, (), (override));
-};
-
-} // namespace test
-} // namespace quic
-
-#endif // QUICHE_QUIC_TEST_TOOLS_MOCK_QUIC_SPDY_CLIENT_STREAM_H_
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/mock_quic_time_wait_list_manager.cc b/chromium/net/third_party/quiche/src/quic/test_tools/mock_quic_time_wait_list_manager.cc
deleted file mode 100644
index 63858c94a1a..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/mock_quic_time_wait_list_manager.cc
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/mock_quic_time_wait_list_manager.h"
-
-using testing::_;
-using testing::Invoke;
-
-namespace quic {
-namespace test {
-
-MockTimeWaitListManager::MockTimeWaitListManager(
- QuicPacketWriter* writer,
- Visitor* visitor,
- const QuicClock* clock,
- QuicAlarmFactory* alarm_factory)
- : QuicTimeWaitListManager(writer, visitor, clock, alarm_factory) {
- // Though AddConnectionIdToTimeWait is mocked, we want to retain its
- // functionality.
- EXPECT_CALL(*this, AddConnectionIdToTimeWait(_, _))
- .Times(testing::AnyNumber());
- ON_CALL(*this, AddConnectionIdToTimeWait(_, _))
- .WillByDefault(
- Invoke(this, &MockTimeWaitListManager::
- QuicTimeWaitListManager_AddConnectionIdToTimeWait));
-}
-
-MockTimeWaitListManager::~MockTimeWaitListManager() = default;
-
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/mock_quic_time_wait_list_manager.h b/chromium/net/third_party/quiche/src/quic/test_tools/mock_quic_time_wait_list_manager.h
deleted file mode 100644
index 1d3cfd51a70..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/mock_quic_time_wait_list_manager.h
+++ /dev/null
@@ -1,76 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_MOCK_QUIC_TIME_WAIT_LIST_MANAGER_H_
-#define QUICHE_QUIC_TEST_TOOLS_MOCK_QUIC_TIME_WAIT_LIST_MANAGER_H_
-
-#include "quic/core/quic_time_wait_list_manager.h"
-#include "quic/platform/api/quic_test.h"
-
-namespace quic {
-namespace test {
-
-class MockTimeWaitListManager : public QuicTimeWaitListManager {
- public:
- MockTimeWaitListManager(QuicPacketWriter* writer,
- Visitor* visitor,
- const QuicClock* clock,
- QuicAlarmFactory* alarm_factory);
- ~MockTimeWaitListManager() override;
-
- MOCK_METHOD(void, AddConnectionIdToTimeWait,
- (QuicTimeWaitListManager::TimeWaitAction action,
- quic::TimeWaitConnectionInfo info),
- (override));
-
- void QuicTimeWaitListManager_AddConnectionIdToTimeWait(
- QuicTimeWaitListManager::TimeWaitAction action,
- quic::TimeWaitConnectionInfo info) {
- QuicTimeWaitListManager::AddConnectionIdToTimeWait(action, std::move(info));
- }
-
- MOCK_METHOD(void,
- ProcessPacket,
- (const QuicSocketAddress&,
- const QuicSocketAddress&,
- QuicConnectionId,
- PacketHeaderFormat,
- size_t,
- std::unique_ptr<QuicPerPacketContext>),
- (override));
-
- MOCK_METHOD(void,
- SendVersionNegotiationPacket,
- (QuicConnectionId server_connection_id,
- QuicConnectionId client_connection_id,
- bool ietf_quic,
- bool has_length_prefix,
- const ParsedQuicVersionVector& supported_versions,
- const QuicSocketAddress& server_address,
- const QuicSocketAddress& client_address,
- std::unique_ptr<QuicPerPacketContext> packet_context),
- (override));
-
- MOCK_METHOD(void,
- SendPublicReset,
- (const QuicSocketAddress&,
- const QuicSocketAddress&,
- QuicConnectionId,
- bool,
- size_t,
- std::unique_ptr<QuicPerPacketContext>),
- (override));
-
- MOCK_METHOD(void,
- SendPacket,
- (const QuicSocketAddress&,
- const QuicSocketAddress&,
- const QuicEncryptedPacket&),
- (override));
-};
-
-} // namespace test
-} // namespace quic
-
-#endif // QUICHE_QUIC_TEST_TOOLS_MOCK_QUIC_TIME_WAIT_LIST_MANAGER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/mock_random.cc b/chromium/net/third_party/quiche/src/quic/test_tools/mock_random.cc
deleted file mode 100644
index a789cdf083b..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/mock_random.cc
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/mock_random.h"
-
-#include <string.h>
-
-namespace quic {
-namespace test {
-
-MockRandom::MockRandom() : base_(0xDEADBEEF), increment_(0) {}
-
-MockRandom::MockRandom(uint32_t base) : base_(base), increment_(0) {}
-
-void MockRandom::RandBytes(void* data, size_t len) {
- memset(data, increment_ + static_cast<uint8_t>('r'), len);
-}
-
-uint64_t MockRandom::RandUint64() {
- return base_ + increment_;
-}
-
-void MockRandom::InsecureRandBytes(void* data, size_t len) {
- RandBytes(data, len);
-}
-
-uint64_t MockRandom::InsecureRandUint64() {
- return RandUint64();
-}
-
-void MockRandom::ChangeValue() {
- increment_++;
-}
-
-void MockRandom::ResetBase(uint32_t base) {
- base_ = base;
- increment_ = 0;
-}
-
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/mock_random.h b/chromium/net/third_party/quiche/src/quic/test_tools/mock_random.h
deleted file mode 100644
index 8dba8601f37..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/mock_random.h
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_MOCK_RANDOM_H_
-#define QUICHE_QUIC_TEST_TOOLS_MOCK_RANDOM_H_
-
-#include "quic/core/crypto/quic_random.h"
-
-namespace quic {
-namespace test {
-
-class MockRandom : public QuicRandom {
- public:
- // Initializes base_ to 0xDEADBEEF.
- MockRandom();
- explicit MockRandom(uint32_t base);
- MockRandom(const MockRandom&) = delete;
- MockRandom& operator=(const MockRandom&) = delete;
-
- // QuicRandom:
- // Fills the |data| buffer with a repeating byte, initially 'r'.
- void RandBytes(void* data, size_t len) override;
- // Returns base + the current increment.
- uint64_t RandUint64() override;
-
- // InsecureRandBytes behaves equivalently to RandBytes.
- void InsecureRandBytes(void* data, size_t len) override;
- // InsecureRandUint64 behaves equivalently to RandUint64.
- uint64_t InsecureRandUint64() override;
-
- // ChangeValue increments |increment_|. This causes the value returned by
- // |RandUint64| and the byte that |RandBytes| fills with, to change.
- void ChangeValue();
-
- // Sets the base to |base| and resets increment to zero.
- void ResetBase(uint32_t base);
-
- private:
- uint32_t base_;
- uint8_t increment_;
-};
-
-} // namespace test
-} // namespace quic
-
-#endif // QUICHE_QUIC_TEST_TOOLS_MOCK_RANDOM_H_
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/packet_dropping_test_writer.cc b/chromium/net/third_party/quiche/src/quic/test_tools/packet_dropping_test_writer.cc
deleted file mode 100644
index 079b2286d40..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/packet_dropping_test_writer.cc
+++ /dev/null
@@ -1,262 +0,0 @@
-// Copyright 2013 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 "quic/test_tools/packet_dropping_test_writer.h"
-
-#include "quic/core/quic_epoll_connection_helper.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-namespace test {
-
-// Every dropped packet must be followed by this number of succesfully written
-// packets. This is to avoid flaky test failures and timeouts, for example, in
-// case both the client and the server drop every other packet (which is
-// statistically possible even if drop percentage is less than 50%).
-const int32_t kMinSuccesfulWritesAfterPacketLoss = 2;
-
-// An alarm that is scheduled if a blocked socket is simulated to indicate
-// it's writable again.
-class WriteUnblockedAlarm : public QuicAlarm::DelegateWithoutContext {
- public:
- explicit WriteUnblockedAlarm(PacketDroppingTestWriter* writer)
- : writer_(writer) {}
-
- void OnAlarm() override {
- QUIC_DLOG(INFO) << "Unblocking socket.";
- writer_->OnCanWrite();
- }
-
- private:
- PacketDroppingTestWriter* writer_;
-};
-
-// An alarm that is scheduled every time a new packet is to be written at a
-// later point.
-class DelayAlarm : public QuicAlarm::DelegateWithoutContext {
- public:
- explicit DelayAlarm(PacketDroppingTestWriter* writer) : writer_(writer) {}
-
- void OnAlarm() override {
- QuicTime new_deadline = writer_->ReleaseOldPackets();
- if (new_deadline.IsInitialized()) {
- writer_->SetDelayAlarm(new_deadline);
- }
- }
-
- private:
- PacketDroppingTestWriter* writer_;
-};
-
-PacketDroppingTestWriter::PacketDroppingTestWriter()
- : clock_(nullptr),
- cur_buffer_size_(0),
- num_calls_to_write_(0),
- // Do not require any number of successful writes before the first dropped
- // packet.
- num_consecutive_succesful_writes_(kMinSuccesfulWritesAfterPacketLoss),
- fake_packet_loss_percentage_(0),
- fake_drop_first_n_packets_(0),
- fake_blocked_socket_percentage_(0),
- fake_packet_reorder_percentage_(0),
- fake_packet_delay_(QuicTime::Delta::Zero()),
- fake_bandwidth_(QuicBandwidth::Zero()),
- buffer_size_(0) {
- uint64_t seed = QuicRandom::GetInstance()->RandUint64();
- QUIC_LOG(INFO) << "Seeding packet loss with " << seed;
- simple_random_.set_seed(seed);
-}
-
-PacketDroppingTestWriter::~PacketDroppingTestWriter() {
- if (write_unblocked_alarm_ != nullptr) {
- write_unblocked_alarm_->PermanentCancel();
- }
- if (delay_alarm_ != nullptr) {
- delay_alarm_->PermanentCancel();
- }
-}
-
-void PacketDroppingTestWriter::Initialize(
- QuicConnectionHelperInterface* helper,
- QuicAlarmFactory* alarm_factory,
- std::unique_ptr<Delegate> on_can_write) {
- clock_ = helper->GetClock();
- write_unblocked_alarm_.reset(
- alarm_factory->CreateAlarm(new WriteUnblockedAlarm(this)));
- delay_alarm_.reset(alarm_factory->CreateAlarm(new DelayAlarm(this)));
- on_can_write_ = std::move(on_can_write);
-}
-
-WriteResult PacketDroppingTestWriter::WritePacket(
- const char* buffer,
- size_t buf_len,
- const QuicIpAddress& self_address,
- const QuicSocketAddress& peer_address,
- PerPacketOptions* options) {
- ++num_calls_to_write_;
- ReleaseOldPackets();
-
- QuicWriterMutexLock lock(&config_mutex_);
- if (fake_drop_first_n_packets_ > 0 &&
- num_calls_to_write_ <=
- static_cast<uint64_t>(fake_drop_first_n_packets_)) {
- QUIC_DVLOG(1) << "Dropping first " << fake_drop_first_n_packets_
- << " packets (packet number " << num_calls_to_write_ << ")";
- num_consecutive_succesful_writes_ = 0;
- return WriteResult(WRITE_STATUS_OK, buf_len);
- }
-
- // Drop every packet at 100%, otherwise always succeed for at least
- // kMinSuccesfulWritesAfterPacketLoss packets between two dropped ones.
- if (fake_packet_loss_percentage_ == 100 ||
- (fake_packet_loss_percentage_ > 0 &&
- num_consecutive_succesful_writes_ >=
- kMinSuccesfulWritesAfterPacketLoss &&
- (simple_random_.RandUint64() % 100 <
- static_cast<uint64_t>(fake_packet_loss_percentage_)))) {
- QUIC_DVLOG(1) << "Dropping packet " << num_calls_to_write_;
- num_consecutive_succesful_writes_ = 0;
- return WriteResult(WRITE_STATUS_OK, buf_len);
- } else {
- ++num_consecutive_succesful_writes_;
- }
-
- if (fake_blocked_socket_percentage_ > 0 &&
- simple_random_.RandUint64() % 100 <
- static_cast<uint64_t>(fake_blocked_socket_percentage_)) {
- QUICHE_CHECK(on_can_write_ != nullptr);
- QUIC_DVLOG(1) << "Blocking socket for packet " << num_calls_to_write_;
- if (!write_unblocked_alarm_->IsSet()) {
- // Set the alarm to fire immediately.
- write_unblocked_alarm_->Set(clock_->ApproximateNow());
- }
-
- // Dropping this packet on retry could result in PTO timeout,
- // make sure to avoid this.
- num_consecutive_succesful_writes_ = 0;
-
- return WriteResult(WRITE_STATUS_BLOCKED, EAGAIN);
- }
-
- if (!fake_packet_delay_.IsZero() || !fake_bandwidth_.IsZero()) {
- if (buffer_size_ > 0 && buf_len + cur_buffer_size_ > buffer_size_) {
- // Drop packets which do not fit into the buffer.
- QUIC_DVLOG(1) << "Dropping packet because the buffer is full.";
- return WriteResult(WRITE_STATUS_OK, buf_len);
- }
-
- // Queue it to be sent.
- QuicTime send_time = clock_->ApproximateNow() + fake_packet_delay_;
- if (!fake_bandwidth_.IsZero()) {
- // Calculate a time the bandwidth limit would impose.
- QuicTime::Delta bandwidth_delay = QuicTime::Delta::FromMicroseconds(
- (buf_len * kNumMicrosPerSecond) / fake_bandwidth_.ToBytesPerSecond());
- send_time = delayed_packets_.empty()
- ? send_time + bandwidth_delay
- : delayed_packets_.back().send_time + bandwidth_delay;
- }
- std::unique_ptr<PerPacketOptions> delayed_options;
- if (options != nullptr) {
- delayed_options = options->Clone();
- }
- delayed_packets_.push_back(
- DelayedWrite(buffer, buf_len, self_address, peer_address,
- std::move(delayed_options), send_time));
- cur_buffer_size_ += buf_len;
-
- // Set the alarm if it's not yet set.
- if (!delay_alarm_->IsSet()) {
- delay_alarm_->Set(send_time);
- }
-
- return WriteResult(WRITE_STATUS_OK, buf_len);
- }
-
- return QuicPacketWriterWrapper::WritePacket(buffer, buf_len, self_address,
- peer_address, options);
-}
-
-bool PacketDroppingTestWriter::IsWriteBlocked() const {
- if (write_unblocked_alarm_ != nullptr && write_unblocked_alarm_->IsSet()) {
- return true;
- }
- return QuicPacketWriterWrapper::IsWriteBlocked();
-}
-
-void PacketDroppingTestWriter::SetWritable() {
- if (write_unblocked_alarm_ != nullptr && write_unblocked_alarm_->IsSet()) {
- write_unblocked_alarm_->Cancel();
- }
- QuicPacketWriterWrapper::SetWritable();
-}
-
-QuicTime PacketDroppingTestWriter::ReleaseNextPacket() {
- if (delayed_packets_.empty()) {
- return QuicTime::Zero();
- }
- QuicReaderMutexLock lock(&config_mutex_);
- auto iter = delayed_packets_.begin();
- // Determine if we should re-order.
- if (delayed_packets_.size() > 1 && fake_packet_reorder_percentage_ > 0 &&
- simple_random_.RandUint64() % 100 <
- static_cast<uint64_t>(fake_packet_reorder_percentage_)) {
- QUIC_DLOG(INFO) << "Reordering packets.";
- ++iter;
- // Swap the send times when re-ordering packets.
- delayed_packets_.begin()->send_time = iter->send_time;
- }
-
- QUIC_DVLOG(1) << "Releasing packet. " << (delayed_packets_.size() - 1)
- << " remaining.";
- // Grab the next one off the queue and send it.
- QuicPacketWriterWrapper::WritePacket(
- iter->buffer.data(), iter->buffer.length(), iter->self_address,
- iter->peer_address, iter->options.get());
- QUICHE_DCHECK_GE(cur_buffer_size_, iter->buffer.length());
- cur_buffer_size_ -= iter->buffer.length();
- delayed_packets_.erase(iter);
-
- // If there are others, find the time for the next to be sent.
- if (delayed_packets_.empty()) {
- return QuicTime::Zero();
- }
- return delayed_packets_.begin()->send_time;
-}
-
-QuicTime PacketDroppingTestWriter::ReleaseOldPackets() {
- while (!delayed_packets_.empty()) {
- QuicTime next_send_time = delayed_packets_.front().send_time;
- if (next_send_time > clock_->Now()) {
- return next_send_time;
- }
- ReleaseNextPacket();
- }
- return QuicTime::Zero();
-}
-
-void PacketDroppingTestWriter::SetDelayAlarm(QuicTime new_deadline) {
- delay_alarm_->Set(new_deadline);
-}
-
-void PacketDroppingTestWriter::OnCanWrite() {
- on_can_write_->OnCanWrite();
-}
-
-PacketDroppingTestWriter::DelayedWrite::DelayedWrite(
- const char* buffer,
- size_t buf_len,
- const QuicIpAddress& self_address,
- const QuicSocketAddress& peer_address,
- std::unique_ptr<PerPacketOptions> options,
- QuicTime send_time)
- : buffer(buffer, buf_len),
- self_address(self_address),
- peer_address(peer_address),
- options(std::move(options)),
- send_time(send_time) {}
-
-PacketDroppingTestWriter::DelayedWrite::~DelayedWrite() = default;
-
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/packet_dropping_test_writer.h b/chromium/net/third_party/quiche/src/quic/test_tools/packet_dropping_test_writer.h
deleted file mode 100644
index c15b5de01b5..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/packet_dropping_test_writer.h
+++ /dev/null
@@ -1,186 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_PACKET_DROPPING_TEST_WRITER_H_
-#define QUICHE_QUIC_TEST_TOOLS_PACKET_DROPPING_TEST_WRITER_H_
-
-#include <cstdint>
-#include <list>
-#include <memory>
-
-#include "absl/base/attributes.h"
-#include "quic/core/quic_alarm.h"
-#include "quic/core/quic_clock.h"
-#include "quic/core/quic_packet_writer_wrapper.h"
-#include "quic/test_tools/quic_test_client.h"
-#include "quic/test_tools/quic_test_utils.h"
-
-namespace quic {
-namespace test {
-
-// Simulates a connection that drops packets a configured percentage of the time
-// and has a blocked socket a configured percentage of the time. Also provides
-// the options to delay packets and reorder packets if delay is enabled.
-class PacketDroppingTestWriter : public QuicPacketWriterWrapper {
- public:
- class Delegate {
- public:
- virtual ~Delegate() {}
- virtual void OnCanWrite() = 0;
- };
-
- PacketDroppingTestWriter();
- PacketDroppingTestWriter(const PacketDroppingTestWriter&) = delete;
- PacketDroppingTestWriter& operator=(const PacketDroppingTestWriter&) = delete;
-
- ~PacketDroppingTestWriter() override;
-
- // Must be called before blocking, reordering or delaying (loss is OK). May be
- // called after connecting if the helper is not available before.
- // |on_can_write| will be triggered when fake-unblocking.
- void Initialize(QuicConnectionHelperInterface* helper,
- QuicAlarmFactory* alarm_factory,
- std::unique_ptr<Delegate> on_can_write);
-
- // QuicPacketWriter methods:
- WriteResult WritePacket(const char* buffer,
- size_t buf_len,
- const QuicIpAddress& self_address,
- const QuicSocketAddress& peer_address,
- PerPacketOptions* options) override;
-
- bool IsWriteBlocked() const override;
-
- void SetWritable() override;
-
- QuicPacketBuffer GetNextWriteLocation(
- const QuicIpAddress& /*self_address*/,
- const QuicSocketAddress& /*peer_address*/) override {
- // If the wrapped writer supports zero-copy, disable it, because it is not
- // compatible with delayed writes in this class.
- return {nullptr, nullptr};
- }
-
- // Writes out any packet which should have been sent by now
- // to the contained writer and returns the time
- // for the next delayed packet to be written.
- QuicTime ReleaseOldPackets();
-
- // Sets |delay_alarm_| to fire at |new_deadline|.
- void SetDelayAlarm(QuicTime new_deadline);
-
- void OnCanWrite();
-
- // The percent of time a packet is simulated as being lost.
- // If |fake_packet_loss_percentage| is 100, then all packages are lost.
- // Otherwise actual percentage will be lower than
- // |fake_packet_loss_percentage|, because every dropped package is followed by
- // a minimum number of successfully written packets.
- void set_fake_packet_loss_percentage(int32_t fake_packet_loss_percentage) {
- QuicWriterMutexLock lock(&config_mutex_);
- fake_packet_loss_percentage_ = fake_packet_loss_percentage;
- }
-
- // Simulate dropping the first n packets unconditionally.
- // Subsequent packets will be lost at fake_packet_loss_percentage_ if set.
- void set_fake_drop_first_n_packets(int32_t fake_drop_first_n_packets) {
- QuicWriterMutexLock lock(&config_mutex_);
- fake_drop_first_n_packets_ = fake_drop_first_n_packets;
- }
-
- // The percent of time WritePacket will block and set WriteResult's status
- // to WRITE_STATUS_BLOCKED.
- void set_fake_blocked_socket_percentage(
- int32_t fake_blocked_socket_percentage) {
- QUICHE_DCHECK(clock_);
- QuicWriterMutexLock lock(&config_mutex_);
- fake_blocked_socket_percentage_ = fake_blocked_socket_percentage;
- }
-
- // The percent of time a packet is simulated as being reordered.
- void set_fake_reorder_percentage(int32_t fake_packet_reorder_percentage) {
- QUICHE_DCHECK(clock_);
- QuicWriterMutexLock lock(&config_mutex_);
- QUICHE_DCHECK(!fake_packet_delay_.IsZero());
- fake_packet_reorder_percentage_ = fake_packet_reorder_percentage;
- }
-
- // The delay before writing this packet.
- void set_fake_packet_delay(QuicTime::Delta fake_packet_delay) {
- QUICHE_DCHECK(clock_);
- QuicWriterMutexLock lock(&config_mutex_);
- fake_packet_delay_ = fake_packet_delay;
- }
-
- // The maximum bandwidth and buffer size of the connection. When these are
- // set, packets will be delayed until a connection with that bandwidth would
- // transmit it. Once the |buffer_size| is reached, all new packets are
- // dropped.
- void set_max_bandwidth_and_buffer_size(QuicBandwidth fake_bandwidth,
- QuicByteCount buffer_size) {
- QUICHE_DCHECK(clock_);
- QuicWriterMutexLock lock(&config_mutex_);
- fake_bandwidth_ = fake_bandwidth;
- buffer_size_ = buffer_size;
- }
-
- // Useful for reproducing very flaky issues.
- ABSL_ATTRIBUTE_UNUSED void set_seed(uint64_t seed) {
- simple_random_.set_seed(seed);
- }
-
- private:
- // Writes out the next packet to the contained writer and returns the time
- // for the next delayed packet to be written.
- QuicTime ReleaseNextPacket();
-
- // A single packet which will be sent at the supplied send_time.
- struct DelayedWrite {
- public:
- DelayedWrite(const char* buffer,
- size_t buf_len,
- const QuicIpAddress& self_address,
- const QuicSocketAddress& peer_address,
- std::unique_ptr<PerPacketOptions> options,
- QuicTime send_time);
- DelayedWrite(const DelayedWrite&) = delete;
- DelayedWrite(DelayedWrite&&) = default;
- DelayedWrite& operator=(const DelayedWrite&) = delete;
- DelayedWrite& operator=(DelayedWrite&&) = default;
- ~DelayedWrite();
-
- std::string buffer;
- QuicIpAddress self_address;
- QuicSocketAddress peer_address;
- std::unique_ptr<PerPacketOptions> options;
- QuicTime send_time;
- };
-
- using DelayedPacketList = std::list<DelayedWrite>;
-
- const QuicClock* clock_;
- std::unique_ptr<QuicAlarm> write_unblocked_alarm_;
- std::unique_ptr<QuicAlarm> delay_alarm_;
- std::unique_ptr<Delegate> on_can_write_;
- SimpleRandom simple_random_;
- // Stored packets delayed by fake packet delay or bandwidth restrictions.
- DelayedPacketList delayed_packets_;
- QuicByteCount cur_buffer_size_;
- uint64_t num_calls_to_write_;
- int32_t num_consecutive_succesful_writes_;
-
- QuicMutex config_mutex_;
- int32_t fake_packet_loss_percentage_ QUIC_GUARDED_BY(config_mutex_);
- int32_t fake_drop_first_n_packets_ QUIC_GUARDED_BY(config_mutex_);
- int32_t fake_blocked_socket_percentage_ QUIC_GUARDED_BY(config_mutex_);
- int32_t fake_packet_reorder_percentage_ QUIC_GUARDED_BY(config_mutex_);
- QuicTime::Delta fake_packet_delay_ QUIC_GUARDED_BY(config_mutex_);
- QuicBandwidth fake_bandwidth_ QUIC_GUARDED_BY(config_mutex_);
- QuicByteCount buffer_size_ QUIC_GUARDED_BY(config_mutex_);
-};
-
-} // namespace test
-} // namespace quic
-
-#endif // QUICHE_QUIC_TEST_TOOLS_PACKET_DROPPING_TEST_WRITER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/packet_reordering_writer.cc b/chromium/net/third_party/quiche/src/quic/test_tools/packet_reordering_writer.cc
deleted file mode 100644
index 1b931ebbea4..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/packet_reordering_writer.cc
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright 2013 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 "quic/test_tools/packet_reordering_writer.h"
-
-namespace quic {
-namespace test {
-
-PacketReorderingWriter::PacketReorderingWriter() = default;
-
-PacketReorderingWriter::~PacketReorderingWriter() = default;
-
-WriteResult PacketReorderingWriter::WritePacket(
- const char* buffer,
- size_t buf_len,
- const QuicIpAddress& self_address,
- const QuicSocketAddress& peer_address,
- PerPacketOptions* options) {
- if (!delay_next_) {
- QUIC_VLOG(2) << "Writing a non-delayed packet";
- WriteResult wr = QuicPacketWriterWrapper::WritePacket(
- buffer, buf_len, self_address, peer_address, options);
- --num_packets_to_wait_;
- if (num_packets_to_wait_ == 0) {
- QUIC_VLOG(2) << "Writing a delayed packet";
- // It's time to write the delayed packet.
- QuicPacketWriterWrapper::WritePacket(
- delayed_data_.data(), delayed_data_.length(), delayed_self_address_,
- delayed_peer_address_, delayed_options_.get());
- }
- return wr;
- }
- // Still have packet to wait.
- QUICHE_DCHECK_LT(0u, num_packets_to_wait_)
- << "Only allow one packet to be delayed";
- delayed_data_ = std::string(buffer, buf_len);
- delayed_self_address_ = self_address;
- delayed_peer_address_ = peer_address;
- if (options != nullptr) {
- delayed_options_ = options->Clone();
- }
- delay_next_ = false;
- return WriteResult(WRITE_STATUS_OK, buf_len);
-}
-
-void PacketReorderingWriter::SetDelay(size_t num_packets_to_wait) {
- QUICHE_DCHECK_GT(num_packets_to_wait, 0u);
- num_packets_to_wait_ = num_packets_to_wait;
- delay_next_ = true;
-}
-
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/packet_reordering_writer.h b/chromium/net/third_party/quiche/src/quic/test_tools/packet_reordering_writer.h
deleted file mode 100644
index 2711a9f365a..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/packet_reordering_writer.h
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_PACKET_REORDERING_WRITER_H_
-#define QUICHE_QUIC_TEST_TOOLS_PACKET_REORDERING_WRITER_H_
-
-#include "quic/core/quic_packet_writer_wrapper.h"
-
-namespace quic {
-
-namespace test {
-
-// This packet writer allows delaying writing the next packet after
-// SetDelay(num_packets_to_wait)
-// is called and buffer this packet and write it after it writes next
-// |num_packets_to_wait| packets. It doesn't support delaying a packet while
-// there is already a packet delayed.
-class PacketReorderingWriter : public QuicPacketWriterWrapper {
- public:
- PacketReorderingWriter();
-
- ~PacketReorderingWriter() override;
-
- WriteResult WritePacket(const char* buffer,
- size_t buf_len,
- const QuicIpAddress& self_address,
- const QuicSocketAddress& peer_address,
- PerPacketOptions* options) override;
-
- void SetDelay(size_t num_packets_to_wait);
-
- private:
- bool delay_next_ = false;
- size_t num_packets_to_wait_ = 0;
- std::string delayed_data_;
- QuicIpAddress delayed_self_address_;
- QuicSocketAddress delayed_peer_address_;
- std::unique_ptr<PerPacketOptions> delayed_options_;
-};
-
-} // namespace test
-} // namespace quic
-
-#endif // QUICHE_QUIC_TEST_TOOLS_PACKET_REORDERING_WRITER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/qpack/qpack_decoder_test_utils.cc b/chromium/net/third_party/quiche/src/quic/test_tools/qpack/qpack_decoder_test_utils.cc
deleted file mode 100644
index 37f182a767e..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/qpack/qpack_decoder_test_utils.cc
+++ /dev/null
@@ -1,90 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/qpack/qpack_decoder_test_utils.h"
-
-#include <algorithm>
-#include <cstddef>
-#include <utility>
-
-#include "absl/strings/string_view.h"
-#include "quic/platform/api/quic_test.h"
-
-namespace quic {
-namespace test {
-
-void NoopEncoderStreamErrorDelegate::OnEncoderStreamError(
- QuicErrorCode /* error_code */,
- absl::string_view /*error_message*/) {}
-
-TestHeadersHandler::TestHeadersHandler()
- : decoding_completed_(false), decoding_error_detected_(false) {}
-
-void TestHeadersHandler::OnHeaderDecoded(absl::string_view name,
- absl::string_view value) {
- ASSERT_FALSE(decoding_completed_);
- ASSERT_FALSE(decoding_error_detected_);
-
- header_list_.AppendValueOrAddHeader(name, value);
-}
-
-void TestHeadersHandler::OnDecodingCompleted() {
- ASSERT_FALSE(decoding_completed_);
- ASSERT_FALSE(decoding_error_detected_);
-
- decoding_completed_ = true;
-}
-
-void TestHeadersHandler::OnDecodingErrorDetected(
- QuicErrorCode /*error_code*/, absl::string_view error_message) {
- ASSERT_FALSE(decoding_completed_);
- ASSERT_FALSE(decoding_error_detected_);
-
- decoding_error_detected_ = true;
- error_message_.assign(error_message.data(), error_message.size());
-}
-
-spdy::Http2HeaderBlock TestHeadersHandler::ReleaseHeaderList() {
- QUICHE_DCHECK(decoding_completed_);
- QUICHE_DCHECK(!decoding_error_detected_);
-
- return std::move(header_list_);
-}
-
-bool TestHeadersHandler::decoding_completed() const {
- return decoding_completed_;
-}
-
-bool TestHeadersHandler::decoding_error_detected() const {
- return decoding_error_detected_;
-}
-
-const std::string& TestHeadersHandler::error_message() const {
- QUICHE_DCHECK(decoding_error_detected_);
- return error_message_;
-}
-
-void QpackDecode(
- uint64_t maximum_dynamic_table_capacity,
- uint64_t maximum_blocked_streams,
- QpackDecoder::EncoderStreamErrorDelegate* encoder_stream_error_delegate,
- QpackStreamSenderDelegate* decoder_stream_sender_delegate,
- QpackProgressiveDecoder::HeadersHandlerInterface* handler,
- const FragmentSizeGenerator& fragment_size_generator,
- absl::string_view data) {
- QpackDecoder decoder(maximum_dynamic_table_capacity, maximum_blocked_streams,
- encoder_stream_error_delegate);
- decoder.set_qpack_stream_sender_delegate(decoder_stream_sender_delegate);
- auto progressive_decoder =
- decoder.CreateProgressiveDecoder(/* stream_id = */ 1, handler);
- while (!data.empty()) {
- size_t fragment_size = std::min(fragment_size_generator(), data.size());
- progressive_decoder->Decode(data.substr(0, fragment_size));
- data = data.substr(fragment_size);
- }
- progressive_decoder->EndHeaderBlock();
-}
-
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/qpack/qpack_decoder_test_utils.h b/chromium/net/third_party/quiche/src/quic/test_tools/qpack/qpack_decoder_test_utils.h
deleted file mode 100644
index b6bff7802c8..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/qpack/qpack_decoder_test_utils.h
+++ /dev/null
@@ -1,115 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_QPACK_QPACK_DECODER_TEST_UTILS_H_
-#define QUICHE_QUIC_TEST_TOOLS_QPACK_QPACK_DECODER_TEST_UTILS_H_
-
-#include <string>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/qpack/qpack_decoder.h"
-#include "quic/core/qpack/qpack_progressive_decoder.h"
-#include "quic/core/quic_error_codes.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/qpack/qpack_test_utils.h"
-#include "spdy/core/spdy_header_block.h"
-
-namespace quic {
-namespace test {
-
-// QpackDecoder::EncoderStreamErrorDelegate implementation that does nothing.
-class NoopEncoderStreamErrorDelegate
- : public QpackDecoder::EncoderStreamErrorDelegate {
- public:
- ~NoopEncoderStreamErrorDelegate() override = default;
-
- void OnEncoderStreamError(QuicErrorCode error_code,
- absl::string_view error_message) override;
-};
-
-// Mock QpackDecoder::EncoderStreamErrorDelegate implementation.
-class MockEncoderStreamErrorDelegate
- : public QpackDecoder::EncoderStreamErrorDelegate {
- public:
- ~MockEncoderStreamErrorDelegate() override = default;
-
- MOCK_METHOD(void,
- OnEncoderStreamError,
- (QuicErrorCode error_code, absl::string_view error_message),
- (override));
-};
-
-// HeadersHandlerInterface implementation that collects decoded headers
-// into a Http2HeaderBlock.
-class TestHeadersHandler
- : public QpackProgressiveDecoder::HeadersHandlerInterface {
- public:
- TestHeadersHandler();
- ~TestHeadersHandler() override = default;
-
- // HeadersHandlerInterface implementation:
- void OnHeaderDecoded(absl::string_view name,
- absl::string_view value) override;
- void OnDecodingCompleted() override;
- void OnDecodingErrorDetected(QuicErrorCode error_code,
- absl::string_view error_message) override;
-
- // Release decoded header list. Must only be called if decoding is complete
- // and no errors have been detected.
- spdy::Http2HeaderBlock ReleaseHeaderList();
-
- bool decoding_completed() const;
- bool decoding_error_detected() const;
- const std::string& error_message() const;
-
- private:
- spdy::Http2HeaderBlock header_list_;
- bool decoding_completed_;
- bool decoding_error_detected_;
- std::string error_message_;
-};
-
-class MockHeadersHandler
- : public QpackProgressiveDecoder::HeadersHandlerInterface {
- public:
- MockHeadersHandler() = default;
- MockHeadersHandler(const MockHeadersHandler&) = delete;
- MockHeadersHandler& operator=(const MockHeadersHandler&) = delete;
- ~MockHeadersHandler() override = default;
-
- MOCK_METHOD(void,
- OnHeaderDecoded,
- (absl::string_view name, absl::string_view value),
- (override));
- MOCK_METHOD(void, OnDecodingCompleted, (), (override));
- MOCK_METHOD(void, OnDecodingErrorDetected,
- (QuicErrorCode error_code, absl::string_view error_message),
- (override));
-};
-
-class NoOpHeadersHandler
- : public QpackProgressiveDecoder::HeadersHandlerInterface {
- public:
- ~NoOpHeadersHandler() override = default;
-
- void OnHeaderDecoded(absl::string_view /*name*/,
- absl::string_view /*value*/) override {}
- void OnDecodingCompleted() override {}
- void OnDecodingErrorDetected(QuicErrorCode /*error_code*/,
- absl::string_view /*error_message*/) override {}
-};
-
-void QpackDecode(
- uint64_t maximum_dynamic_table_capacity,
- uint64_t maximum_blocked_streams,
- QpackDecoder::EncoderStreamErrorDelegate* encoder_stream_error_delegate,
- QpackStreamSenderDelegate* decoder_stream_sender_delegate,
- QpackProgressiveDecoder::HeadersHandlerInterface* handler,
- const FragmentSizeGenerator& fragment_size_generator,
- absl::string_view data);
-
-} // namespace test
-} // namespace quic
-
-#endif // QUICHE_QUIC_TEST_TOOLS_QPACK_QPACK_DECODER_TEST_UTILS_H_
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/qpack/qpack_encoder_peer.cc b/chromium/net/third_party/quiche/src/quic/test_tools/qpack/qpack_encoder_peer.cc
deleted file mode 100644
index cc5f010c0e1..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/qpack/qpack_encoder_peer.cc
+++ /dev/null
@@ -1,30 +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 "quic/test_tools/qpack/qpack_encoder_peer.h"
-
-#include "quic/core/qpack/qpack_encoder.h"
-
-namespace quic {
-namespace test {
-
-// static
-QpackEncoderHeaderTable* QpackEncoderPeer::header_table(QpackEncoder* encoder) {
- return &encoder->header_table_;
-}
-
-// static
-uint64_t QpackEncoderPeer::maximum_blocked_streams(
- const QpackEncoder* encoder) {
- return encoder->maximum_blocked_streams_;
-}
-
-// static
-uint64_t QpackEncoderPeer::smallest_blocking_index(
- const QpackEncoder* encoder) {
- return encoder->blocking_manager_.smallest_blocking_index();
-}
-
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/qpack/qpack_encoder_peer.h b/chromium/net/third_party/quiche/src/quic/test_tools/qpack/qpack_encoder_peer.h
deleted file mode 100644
index 94a308af980..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/qpack/qpack_encoder_peer.h
+++ /dev/null
@@ -1,30 +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_TEST_TOOLS_QPACK_QPACK_ENCODER_PEER_H_
-#define QUICHE_QUIC_TEST_TOOLS_QPACK_QPACK_ENCODER_PEER_H_
-
-#include <cstdint>
-
-namespace quic {
-
-class QpackEncoder;
-class QpackEncoderHeaderTable;
-
-namespace test {
-
-class QpackEncoderPeer {
- public:
- QpackEncoderPeer() = delete;
-
- static QpackEncoderHeaderTable* header_table(QpackEncoder* encoder);
- static uint64_t maximum_blocked_streams(const QpackEncoder* encoder);
- static uint64_t smallest_blocking_index(const QpackEncoder* encoder);
-};
-
-} // namespace test
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_TEST_TOOLS_QPACK_QPACK_ENCODER_PEER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/qpack/qpack_encoder_test_utils.cc b/chromium/net/third_party/quiche/src/quic/test_tools/qpack/qpack_encoder_test_utils.cc
deleted file mode 100644
index 20be113d8d3..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/qpack/qpack_encoder_test_utils.cc
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/qpack/qpack_encoder_test_utils.h"
-
-#include "absl/strings/string_view.h"
-#include "spdy/core/hpack/hpack_encoder.h"
-
-namespace quic {
-namespace test {
-
-void NoopDecoderStreamErrorDelegate::OnDecoderStreamError(
- QuicErrorCode /*error_code*/,
- absl::string_view /*error_message*/) {}
-
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/qpack/qpack_encoder_test_utils.h b/chromium/net/third_party/quiche/src/quic/test_tools/qpack/qpack_encoder_test_utils.h
deleted file mode 100644
index ec58c3f04de..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/qpack/qpack_encoder_test_utils.h
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_QPACK_QPACK_ENCODER_TEST_UTILS_H_
-#define QUICHE_QUIC_TEST_TOOLS_QPACK_QPACK_ENCODER_TEST_UTILS_H_
-
-#include <string>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/qpack/qpack_encoder.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/qpack/qpack_test_utils.h"
-#include "spdy/core/spdy_header_block.h"
-
-namespace quic {
-namespace test {
-
-// QpackEncoder::DecoderStreamErrorDelegate implementation that does nothing.
-class NoopDecoderStreamErrorDelegate
- : public QpackEncoder::DecoderStreamErrorDelegate {
- public:
- ~NoopDecoderStreamErrorDelegate() override = default;
-
- void OnDecoderStreamError(QuicErrorCode error_code,
- absl::string_view error_message) override;
-};
-
-// Mock QpackEncoder::DecoderStreamErrorDelegate implementation.
-class MockDecoderStreamErrorDelegate
- : public QpackEncoder::DecoderStreamErrorDelegate {
- public:
- ~MockDecoderStreamErrorDelegate() override = default;
-
- MOCK_METHOD(void,
- OnDecoderStreamError,
- (QuicErrorCode error_code, absl::string_view error_message),
- (override));
-};
-
-} // namespace test
-} // namespace quic
-
-#endif // QUICHE_QUIC_TEST_TOOLS_QPACK_QPACK_ENCODER_TEST_UTILS_H_
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/qpack/qpack_offline_decoder.cc b/chromium/net/third_party/quiche/src/quic/test_tools/qpack/qpack_offline_decoder.cc
deleted file mode 100644
index a7ea1be114b..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/qpack/qpack_offline_decoder.cc
+++ /dev/null
@@ -1,336 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Decoder to test QPACK Offline Interop corpus
-//
-// See https://github.com/quicwg/base-drafts/wiki/QPACK-Offline-Interop for
-// description of test data format.
-//
-// Example usage
-//
-// cd $TEST_DATA
-// git clone https://github.com/qpackers/qifs.git
-// TEST_ENCODED_DATA=$TEST_DATA/qifs/encoded/qpack-06
-// TEST_QIF_DATA=$TEST_DATA/qifs/qifs
-// $BIN/qpack_offline_decoder \
-// $TEST_ENCODED_DATA/f5/fb-req.qifencoded.4096.100.0 \
-// $TEST_QIF_DATA/fb-req.qif
-// $TEST_ENCODED_DATA/h2o/fb-req-hq.out.512.0.1 \
-// $TEST_QIF_DATA/fb-req-hq.qif
-// $TEST_ENCODED_DATA/ls-qpack/fb-resp-hq.out.0.0.0 \
-// $TEST_QIF_DATA/fb-resp-hq.qif
-// $TEST_ENCODED_DATA/proxygen/netbsd.qif.proxygen.out.4096.0.0 \
-// $TEST_QIF_DATA/netbsd.qif
-//
-
-#include "quic/test_tools/qpack/qpack_offline_decoder.h"
-
-#include <cstdint>
-#include <string>
-#include <utility>
-
-#include "absl/strings/match.h"
-#include "absl/strings/numbers.h"
-#include "absl/strings/str_split.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/test_tools/qpack/qpack_test_utils.h"
-#include "common/platform/api/quiche_file_utils.h"
-#include "common/quiche_endian.h"
-
-namespace quic {
-
-QpackOfflineDecoder::QpackOfflineDecoder()
- : encoder_stream_error_detected_(false) {}
-
-bool QpackOfflineDecoder::DecodeAndVerifyOfflineData(
- absl::string_view input_filename,
- absl::string_view expected_headers_filename) {
- if (!ParseInputFilename(input_filename)) {
- QUIC_LOG(ERROR) << "Error parsing input filename " << input_filename;
- return false;
- }
-
- if (!DecodeHeaderBlocksFromFile(input_filename)) {
- QUIC_LOG(ERROR) << "Error decoding header blocks in " << input_filename;
- return false;
- }
-
- if (!VerifyDecodedHeaderLists(expected_headers_filename)) {
- QUIC_LOG(ERROR) << "Header lists decoded from " << input_filename
- << " to not match expected headers parsed from "
- << expected_headers_filename;
- return false;
- }
-
- return true;
-}
-
-void QpackOfflineDecoder::OnEncoderStreamError(
- QuicErrorCode error_code, absl::string_view error_message) {
- QUIC_LOG(ERROR) << "Encoder stream error: "
- << QuicErrorCodeToString(error_code) << " " << error_message;
- encoder_stream_error_detected_ = true;
-}
-
-bool QpackOfflineDecoder::ParseInputFilename(absl::string_view input_filename) {
- std::vector<absl::string_view> pieces = absl::StrSplit(input_filename, '.');
-
- if (pieces.size() < 3) {
- QUIC_LOG(ERROR) << "Not enough fields in input filename " << input_filename;
- return false;
- }
-
- auto piece_it = pieces.rbegin();
-
- // Acknowledgement mode: 1 for immediate, 0 for none.
- if (*piece_it != "0" && *piece_it != "1") {
- QUIC_LOG(ERROR)
- << "Header acknowledgement field must be 0 or 1 in input filename "
- << input_filename;
- return false;
- }
-
- ++piece_it;
-
- // Maximum allowed number of blocked streams.
- uint64_t max_blocked_streams = 0;
- if (!absl::SimpleAtoi(*piece_it, &max_blocked_streams)) {
- QUIC_LOG(ERROR) << "Error parsing part of input filename \"" << *piece_it
- << "\" as an integer.";
- return false;
- }
-
- ++piece_it;
-
- // Maximum Dynamic Table Capacity in bytes
- uint64_t maximum_dynamic_table_capacity = 0;
- if (!absl::SimpleAtoi(*piece_it, &maximum_dynamic_table_capacity)) {
- QUIC_LOG(ERROR) << "Error parsing part of input filename \"" << *piece_it
- << "\" as an integer.";
- return false;
- }
- qpack_decoder_ = std::make_unique<QpackDecoder>(
- maximum_dynamic_table_capacity, max_blocked_streams, this);
- qpack_decoder_->set_qpack_stream_sender_delegate(
- &decoder_stream_sender_delegate_);
-
- // The initial dynamic table capacity is zero according to
- // https://quicwg.org/base-drafts/draft-ietf-quic-qpack.html#eviction.
- // However, for historical reasons, offline interop encoders use
- // |maximum_dynamic_table_capacity| as initial capacity.
- qpack_decoder_->OnSetDynamicTableCapacity(maximum_dynamic_table_capacity);
-
- return true;
-}
-
-bool QpackOfflineDecoder::DecodeHeaderBlocksFromFile(
- absl::string_view input_filename) {
- // Store data in |input_data_storage|; use a absl::string_view to
- // efficiently keep track of remaining portion yet to be decoded.
- absl::optional<std::string> input_data_storage =
- quiche::ReadFileContents(input_filename);
- QUICHE_DCHECK(input_data_storage.has_value());
- absl::string_view input_data(*input_data_storage);
-
- while (!input_data.empty()) {
- // Parse stream_id and length.
- if (input_data.size() < sizeof(uint64_t) + sizeof(uint32_t)) {
- QUIC_LOG(ERROR) << "Unexpected end of input file.";
- return false;
- }
-
- uint64_t stream_id = quiche::QuicheEndian::NetToHost64(
- *reinterpret_cast<const uint64_t*>(input_data.data()));
- input_data = input_data.substr(sizeof(uint64_t));
-
- uint32_t length = quiche::QuicheEndian::NetToHost32(
- *reinterpret_cast<const uint32_t*>(input_data.data()));
- input_data = input_data.substr(sizeof(uint32_t));
-
- if (input_data.size() < length) {
- QUIC_LOG(ERROR) << "Unexpected end of input file.";
- return false;
- }
-
- // Parse data.
- absl::string_view data = input_data.substr(0, length);
- input_data = input_data.substr(length);
-
- // Process data.
- if (stream_id == 0) {
- qpack_decoder_->encoder_stream_receiver()->Decode(data);
-
- if (encoder_stream_error_detected_) {
- QUIC_LOG(ERROR) << "Error detected on encoder stream.";
- return false;
- }
- } else {
- auto headers_handler = std::make_unique<test::TestHeadersHandler>();
- auto progressive_decoder = qpack_decoder_->CreateProgressiveDecoder(
- stream_id, headers_handler.get());
-
- progressive_decoder->Decode(data);
- progressive_decoder->EndHeaderBlock();
-
- if (headers_handler->decoding_error_detected()) {
- QUIC_LOG(ERROR) << "Sync decoding error on stream " << stream_id << ": "
- << headers_handler->error_message();
- return false;
- }
-
- decoders_.push_back({std::move(headers_handler),
- std::move(progressive_decoder), stream_id});
- }
-
- // Move decoded header lists from TestHeadersHandlers and append them to
- // |decoded_header_lists_| while preserving the order in |decoders_|.
- while (!decoders_.empty() &&
- decoders_.front().headers_handler->decoding_completed()) {
- Decoder* decoder = &decoders_.front();
-
- if (decoder->headers_handler->decoding_error_detected()) {
- QUIC_LOG(ERROR) << "Async decoding error on stream "
- << decoder->stream_id << ": "
- << decoder->headers_handler->error_message();
- return false;
- }
-
- if (!decoder->headers_handler->decoding_completed()) {
- QUIC_LOG(ERROR) << "Decoding incomplete after reading entire"
- " file, on stream "
- << decoder->stream_id;
- return false;
- }
-
- decoded_header_lists_.push_back(
- decoder->headers_handler->ReleaseHeaderList());
- decoders_.pop_front();
- }
- }
-
- if (!decoders_.empty()) {
- QUICHE_DCHECK(!decoders_.front().headers_handler->decoding_completed());
-
- QUIC_LOG(ERROR) << "Blocked decoding uncomplete after reading entire"
- " file, on stream "
- << decoders_.front().stream_id;
- return false;
- }
-
- return true;
-}
-
-bool QpackOfflineDecoder::VerifyDecodedHeaderLists(
- absl::string_view expected_headers_filename) {
- // Store data in |expected_headers_data_storage|; use a
- // absl::string_view to efficiently keep track of remaining portion
- // yet to be decoded.
- absl::optional<std::string> expected_headers_data_storage =
- quiche::ReadFileContents(expected_headers_filename);
- QUICHE_DCHECK(expected_headers_data_storage.has_value());
- absl::string_view expected_headers_data(*expected_headers_data_storage);
-
- while (!decoded_header_lists_.empty()) {
- spdy::Http2HeaderBlock decoded_header_list =
- std::move(decoded_header_lists_.front());
- decoded_header_lists_.pop_front();
-
- spdy::Http2HeaderBlock expected_header_list;
- if (!ReadNextExpectedHeaderList(&expected_headers_data,
- &expected_header_list)) {
- QUIC_LOG(ERROR)
- << "Error parsing expected header list to match next decoded "
- "header list.";
- return false;
- }
-
- if (!CompareHeaderBlocks(std::move(decoded_header_list),
- std::move(expected_header_list))) {
- QUIC_LOG(ERROR) << "Decoded header does not match expected header.";
- return false;
- }
- }
-
- if (!expected_headers_data.empty()) {
- QUIC_LOG(ERROR)
- << "Not enough encoded header lists to match expected ones.";
- return false;
- }
-
- return true;
-}
-
-bool QpackOfflineDecoder::ReadNextExpectedHeaderList(
- absl::string_view* expected_headers_data,
- spdy::Http2HeaderBlock* expected_header_list) {
- while (true) {
- absl::string_view::size_type endline = expected_headers_data->find('\n');
-
- // Even last header list must be followed by an empty line.
- if (endline == absl::string_view::npos) {
- QUIC_LOG(ERROR) << "Unexpected end of expected header list file.";
- return false;
- }
-
- if (endline == 0) {
- // Empty line indicates end of header list.
- *expected_headers_data = expected_headers_data->substr(1);
- return true;
- }
-
- absl::string_view header_field = expected_headers_data->substr(0, endline);
- std::vector<absl::string_view> pieces = absl::StrSplit(header_field, '\t');
-
- if (pieces.size() != 2) {
- QUIC_LOG(ERROR) << "Header key and value must be separated by TAB.";
- return false;
- }
-
- expected_header_list->AppendValueOrAddHeader(pieces[0], pieces[1]);
-
- *expected_headers_data = expected_headers_data->substr(endline + 1);
- }
-}
-
-bool QpackOfflineDecoder::CompareHeaderBlocks(
- spdy::Http2HeaderBlock decoded_header_list,
- spdy::Http2HeaderBlock expected_header_list) {
- if (decoded_header_list == expected_header_list) {
- return true;
- }
-
- // The h2o decoder reshuffles the "content-length" header and pseudo-headers,
- // see
- // https://github.com/qpackers/qifs/blob/master/encoded/qpack-03/h2o/README.md.
- // Remove such headers one by one if they match.
- const char* kContentLength = "content-length";
- const char* kPseudoHeaderPrefix = ":";
- for (spdy::Http2HeaderBlock::iterator decoded_it =
- decoded_header_list.begin();
- decoded_it != decoded_header_list.end();) {
- const absl::string_view key = decoded_it->first;
- if (key != kContentLength && !absl::StartsWith(key, kPseudoHeaderPrefix)) {
- ++decoded_it;
- continue;
- }
- spdy::Http2HeaderBlock::iterator expected_it =
- expected_header_list.find(key);
- if (expected_it == expected_header_list.end() ||
- decoded_it->second != expected_it->second) {
- ++decoded_it;
- continue;
- }
- // SpdyHeaderBlock does not support erasing by iterator, only by key.
- ++decoded_it;
- expected_header_list.erase(key);
- // This will invalidate |key|.
- decoded_header_list.erase(key);
- }
-
- return decoded_header_list == expected_header_list;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/qpack/qpack_offline_decoder.h b/chromium/net/third_party/quiche/src/quic/test_tools/qpack/qpack_offline_decoder.h
deleted file mode 100644
index 11dec698478..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/qpack/qpack_offline_decoder.h
+++ /dev/null
@@ -1,88 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_QPACK_QPACK_OFFLINE_DECODER_H_
-#define QUICHE_QUIC_TEST_TOOLS_QPACK_QPACK_OFFLINE_DECODER_H_
-
-#include <list>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/qpack/qpack_decoder.h"
-#include "quic/core/quic_error_codes.h"
-#include "quic/test_tools/qpack/qpack_decoder_test_utils.h"
-#include "quic/test_tools/qpack/qpack_test_utils.h"
-#include "spdy/core/spdy_header_block.h"
-
-namespace quic {
-
-// A decoder to read encoded data from a file, decode it, and compare to
-// a list of expected header lists read from another file. File format is
-// described at
-// https://github.com/quicwg/base-drafts/wiki/QPACK-Offline-Interop.
-class QpackOfflineDecoder : public QpackDecoder::EncoderStreamErrorDelegate {
- public:
- QpackOfflineDecoder();
- ~QpackOfflineDecoder() override = default;
-
- // Read encoded header blocks and encoder stream data from |input_filename|
- // and decode them, read expected header lists from
- // |expected_headers_filename|, and compare decoded header lists to expected
- // ones. Returns true if there is an equal number of them and the
- // corresponding ones match, false otherwise.
- bool DecodeAndVerifyOfflineData(absl::string_view input_filename,
- absl::string_view expected_headers_filename);
-
- // QpackDecoder::EncoderStreamErrorDelegate implementation:
- void OnEncoderStreamError(QuicErrorCode error_code,
- absl::string_view error_message) override;
-
- private:
- // Data structure to hold TestHeadersHandler and QpackProgressiveDecoder until
- // decoding of a header header block (and all preceding header blocks) is
- // complete.
- struct Decoder {
- std::unique_ptr<test::TestHeadersHandler> headers_handler;
- std::unique_ptr<QpackProgressiveDecoder> progressive_decoder;
- uint64_t stream_id;
- };
-
- // Parse decoder parameters from |input_filename| and set up |qpack_decoder_|
- // accordingly.
- bool ParseInputFilename(absl::string_view input_filename);
-
- // Read encoded header blocks and encoder stream data from |input_filename|,
- // pass them to |qpack_decoder_| for decoding, and add decoded header lists to
- // |decoded_header_lists_|.
- bool DecodeHeaderBlocksFromFile(absl::string_view input_filename);
-
- // Read expected header lists from |expected_headers_filename| and verify
- // decoded header lists in |decoded_header_lists_| against them.
- bool VerifyDecodedHeaderLists(absl::string_view expected_headers_filename);
-
- // Parse next header list from |*expected_headers_data| into
- // |*expected_header_list|, removing consumed data from the beginning of
- // |*expected_headers_data|. Returns true on success, false if parsing fails.
- bool ReadNextExpectedHeaderList(absl::string_view* expected_headers_data,
- spdy::Http2HeaderBlock* expected_header_list);
-
- // Compare two header lists. Allow for different orders of certain headers as
- // described at
- // https://github.com/qpackers/qifs/blob/master/encoded/qpack-03/h2o/README.md.
- bool CompareHeaderBlocks(spdy::Http2HeaderBlock decoded_header_list,
- spdy::Http2HeaderBlock expected_header_list);
-
- bool encoder_stream_error_detected_;
- test::NoopQpackStreamSenderDelegate decoder_stream_sender_delegate_;
- std::unique_ptr<QpackDecoder> qpack_decoder_;
-
- // Objects necessary for decoding, one list element for each header block.
- std::list<Decoder> decoders_;
-
- // Decoded header lists.
- std::list<spdy::Http2HeaderBlock> decoded_header_lists_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_TEST_TOOLS_QPACK_QPACK_OFFLINE_DECODER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/qpack/qpack_test_utils.cc b/chromium/net/third_party/quiche/src/quic/test_tools/qpack/qpack_test_utils.cc
deleted file mode 100644
index a4535040df7..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/qpack/qpack_test_utils.cc
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/qpack/qpack_test_utils.h"
-
-#include <limits>
-#include "quic/platform/api/quic_bug_tracker.h"
-
-namespace quic {
-namespace test {
-
-FragmentSizeGenerator FragmentModeToFragmentSizeGenerator(
- FragmentMode fragment_mode) {
- switch (fragment_mode) {
- case FragmentMode::kSingleChunk:
- return []() { return std::numeric_limits<size_t>::max(); };
- case FragmentMode::kOctetByOctet:
- return []() { return 1; };
- }
- QUIC_BUG(quic_bug_10259_1)
- << "Unknown FragmentMode " << static_cast<int>(fragment_mode);
- return []() { return 0; };
-}
-
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/qpack/qpack_test_utils.h b/chromium/net/third_party/quiche/src/quic/test_tools/qpack/qpack_test_utils.h
deleted file mode 100644
index 2230fbec940..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/qpack/qpack_test_utils.h
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_QPACK_QPACK_TEST_UTILS_H_
-#define QUICHE_QUIC_TEST_TOOLS_QPACK_QPACK_TEST_UTILS_H_
-
-#include <cstddef>
-#include <functional>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/qpack/qpack_stream_sender_delegate.h"
-#include "quic/platform/api/quic_test.h"
-
-namespace quic {
-namespace test {
-
-// Called repeatedly to determine the size of each fragment when encoding or
-// decoding. Must return a positive value.
-using FragmentSizeGenerator = std::function<size_t()>;
-
-enum class FragmentMode {
- kSingleChunk,
- kOctetByOctet,
-};
-
-FragmentSizeGenerator FragmentModeToFragmentSizeGenerator(
- FragmentMode fragment_mode);
-
-// Mock QpackUnidirectionalStreamSenderDelegate implementation.
-class MockQpackStreamSenderDelegate : public QpackStreamSenderDelegate {
- public:
- ~MockQpackStreamSenderDelegate() override = default;
-
- MOCK_METHOD(void, WriteStreamData, (absl::string_view data), (override));
- MOCK_METHOD(uint64_t, NumBytesBuffered, (), (const, override));
-};
-
-class NoopQpackStreamSenderDelegate : public QpackStreamSenderDelegate {
- public:
- ~NoopQpackStreamSenderDelegate() override = default;
-
- void WriteStreamData(absl::string_view /*data*/) override {}
-
- uint64_t NumBytesBuffered() const override { return 0; }
-};
-
-} // namespace test
-} // namespace quic
-
-#endif // QUICHE_QUIC_TEST_TOOLS_QPACK_QPACK_TEST_UTILS_H_
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/quic_buffered_packet_store_peer.cc b/chromium/net/third_party/quiche/src/quic/test_tools/quic_buffered_packet_store_peer.cc
deleted file mode 100644
index 9b3c04097ec..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/quic_buffered_packet_store_peer.cc
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/quic_buffered_packet_store_peer.h"
-
-#include "quic/core/quic_buffered_packet_store.h"
-
-namespace quic {
-namespace test {
-
-// static
-QuicAlarm* QuicBufferedPacketStorePeer::expiration_alarm(
- QuicBufferedPacketStore* store) {
- return store->expiration_alarm_.get();
-}
-
-// static
-void QuicBufferedPacketStorePeer::set_clock(QuicBufferedPacketStore* store,
- const QuicClock* clock) {
- store->clock_ = clock;
-}
-
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/quic_buffered_packet_store_peer.h b/chromium/net/third_party/quiche/src/quic/test_tools/quic_buffered_packet_store_peer.h
deleted file mode 100644
index fddac0a940e..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/quic_buffered_packet_store_peer.h
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_QUIC_BUFFERED_PACKET_STORE_PEER_H_
-#define QUICHE_QUIC_TEST_TOOLS_QUIC_BUFFERED_PACKET_STORE_PEER_H_
-
-#include <memory>
-
-#include "quic/core/quic_alarm.h"
-#include "quic/core/quic_clock.h"
-
-namespace quic {
-
-class QuicBufferedPacketStore;
-
-namespace test {
-
-class QuicBufferedPacketStorePeer {
- public:
- QuicBufferedPacketStorePeer() = delete;
-
- static QuicAlarm* expiration_alarm(QuicBufferedPacketStore* store);
-
- static void set_clock(QuicBufferedPacketStore* store, const QuicClock* clock);
-};
-
-} // namespace test
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_TEST_TOOLS_QUIC_BUFFERED_PACKET_STORE_PEER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/quic_client_peer.cc b/chromium/net/third_party/quiche/src/quic/test_tools/quic_client_peer.cc
deleted file mode 100644
index c80a0b5e643..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/quic_client_peer.cc
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright (c) 2013 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 "quic/test_tools/quic_client_peer.h"
-
-#include "quic/tools/quic_client.h"
-
-namespace quic {
-namespace test {
-
-// static
-bool QuicClientPeer::CreateUDPSocketAndBind(QuicClient* client) {
- return client->network_helper()->CreateUDPSocketAndBind(
- client->server_address(), client->bind_to_address(),
- client->local_port());
-}
-
-// static
-void QuicClientPeer::CleanUpUDPSocket(QuicClient* client, int fd) {
- client->epoll_network_helper()->CleanUpUDPSocket(fd);
-}
-
-// static
-void QuicClientPeer::SetClientPort(QuicClient* client, int port) {
- client->epoll_network_helper()->SetClientPort(port);
-}
-
-// static
-void QuicClientPeer::SetWriter(QuicClient* client, QuicPacketWriter* writer) {
- client->set_writer(writer);
-}
-
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/quic_client_peer.h b/chromium/net/third_party/quiche/src/quic/test_tools/quic_client_peer.h
deleted file mode 100644
index 7070779f47c..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/quic_client_peer.h
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_QUIC_CLIENT_PEER_H_
-#define QUICHE_QUIC_TEST_TOOLS_QUIC_CLIENT_PEER_H_
-
-namespace quic {
-
-class QuicClient;
-class QuicPacketWriter;
-
-namespace test {
-
-class QuicClientPeer {
- public:
- QuicClientPeer() = delete;
-
- static bool CreateUDPSocketAndBind(QuicClient* client);
- static void CleanUpUDPSocket(QuicClient* client, int fd);
- static void SetClientPort(QuicClient* client, int port);
- static void SetWriter(QuicClient* client, QuicPacketWriter* writer);
-};
-
-} // namespace test
-} // namespace quic
-
-#endif // QUICHE_QUIC_TEST_TOOLS_QUIC_CLIENT_PEER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/quic_client_promised_info_peer.cc b/chromium/net/third_party/quiche/src/quic/test_tools/quic_client_promised_info_peer.cc
deleted file mode 100644
index cf14d0f2dc0..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/quic_client_promised_info_peer.cc
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/quic_client_promised_info_peer.h"
-
-namespace quic {
-namespace test {
-
-// static
-QuicAlarm* QuicClientPromisedInfoPeer::GetAlarm(
- QuicClientPromisedInfo* promised_stream) {
- return promised_stream->cleanup_alarm_.get();
-}
-
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/quic_client_promised_info_peer.h b/chromium/net/third_party/quiche/src/quic/test_tools/quic_client_promised_info_peer.h
deleted file mode 100644
index 15ae6bb8df9..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/quic_client_promised_info_peer.h
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_QUIC_CLIENT_PROMISED_INFO_PEER_H_
-#define QUICHE_QUIC_TEST_TOOLS_QUIC_CLIENT_PROMISED_INFO_PEER_H_
-
-#include "quic/core/http/quic_client_promised_info.h"
-
-namespace quic {
-namespace test {
-
-class QuicClientPromisedInfoPeer {
- public:
- QuicClientPromisedInfoPeer() = delete;
-
- static QuicAlarm* GetAlarm(QuicClientPromisedInfo* promised_stream);
-};
-} // namespace test
-} // namespace quic
-
-#endif // QUICHE_QUIC_TEST_TOOLS_QUIC_CLIENT_PROMISED_INFO_PEER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/quic_client_session_cache_peer.h b/chromium/net/third_party/quiche/src/quic/test_tools/quic_client_session_cache_peer.h
deleted file mode 100644
index 227a48de075..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/quic_client_session_cache_peer.h
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright (c) 2021 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_QUIC_CLIENT_SESSION_CACHE_PEER_H_
-#define QUICHE_QUIC_TEST_TOOLS_QUIC_CLIENT_SESSION_CACHE_PEER_H_
-
-#include "quic/core/crypto/quic_client_session_cache.h"
-
-namespace quic {
-namespace test {
-
-class QuicClientSessionCachePeer {
- public:
- static std::string GetToken(QuicClientSessionCache* cache,
- const QuicServerId& server_id) {
- auto iter = cache->cache_.Lookup(server_id);
- if (iter == cache->cache_.end()) {
- return {};
- }
- return iter->second->token;
- }
-
- static bool HasEntry(QuicClientSessionCache* cache,
- const QuicServerId& server_id) {
- return cache->cache_.Lookup(server_id) != cache->cache_.end();
- }
-};
-
-} // namespace test
-} // namespace quic
-
-#endif // QUICHE_QUIC_TEST_TOOLS_QUIC_CLIENT_SESSION_CACHE_PEER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/quic_config_peer.cc b/chromium/net/third_party/quiche/src/quic/test_tools/quic_config_peer.cc
deleted file mode 100644
index 243216bb2e1..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/quic_config_peer.cc
+++ /dev/null
@@ -1,143 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/quic_config_peer.h"
-
-#include "quic/core/quic_config.h"
-#include "quic/core/quic_connection_id.h"
-
-namespace quic {
-namespace test {
-
-// static
-void QuicConfigPeer::SetReceivedInitialStreamFlowControlWindow(
- QuicConfig* config,
- uint32_t window_bytes) {
- config->initial_stream_flow_control_window_bytes_.SetReceivedValue(
- window_bytes);
-}
-
-// static
-void QuicConfigPeer::SetReceivedInitialMaxStreamDataBytesIncomingBidirectional(
- QuicConfig* config,
- uint32_t window_bytes) {
- config->initial_max_stream_data_bytes_incoming_bidirectional_
- .SetReceivedValue(window_bytes);
-}
-
-// static
-void QuicConfigPeer::SetReceivedInitialMaxStreamDataBytesOutgoingBidirectional(
- QuicConfig* config,
- uint32_t window_bytes) {
- config->initial_max_stream_data_bytes_outgoing_bidirectional_
- .SetReceivedValue(window_bytes);
-}
-
-// static
-void QuicConfigPeer::SetReceivedInitialMaxStreamDataBytesUnidirectional(
- QuicConfig* config,
- uint32_t window_bytes) {
- config->initial_max_stream_data_bytes_unidirectional_.SetReceivedValue(
- window_bytes);
-}
-
-// static
-void QuicConfigPeer::SetReceivedInitialSessionFlowControlWindow(
- QuicConfig* config,
- uint32_t window_bytes) {
- config->initial_session_flow_control_window_bytes_.SetReceivedValue(
- window_bytes);
-}
-
-// static
-void QuicConfigPeer::SetReceivedConnectionOptions(
- QuicConfig* config,
- const QuicTagVector& options) {
- config->connection_options_.SetReceivedValues(options);
-}
-
-// static
-void QuicConfigPeer::SetReceivedBytesForConnectionId(QuicConfig* config,
- uint32_t bytes) {
- QUICHE_DCHECK(bytes == 0 || bytes == 8);
- config->bytes_for_connection_id_.SetReceivedValue(bytes);
-}
-
-// static
-void QuicConfigPeer::SetReceivedDisableConnectionMigration(QuicConfig* config) {
- config->connection_migration_disabled_.SetReceivedValue(1);
-}
-
-// static
-void QuicConfigPeer::SetReceivedMaxBidirectionalStreams(QuicConfig* config,
- uint32_t max_streams) {
- config->max_bidirectional_streams_.SetReceivedValue(max_streams);
-}
-// static
-void QuicConfigPeer::SetReceivedMaxUnidirectionalStreams(QuicConfig* config,
- uint32_t max_streams) {
- config->max_unidirectional_streams_.SetReceivedValue(max_streams);
-}
-
-// static
-void QuicConfigPeer::SetConnectionOptionsToSend(QuicConfig* config,
- const QuicTagVector& options) {
- config->SetConnectionOptionsToSend(options);
-}
-
-// static
-void QuicConfigPeer::SetReceivedStatelessResetToken(
- QuicConfig* config,
- const StatelessResetToken& token) {
- config->stateless_reset_token_.SetReceivedValue(token);
-}
-
-// static
-void QuicConfigPeer::SetReceivedMaxPacketSize(QuicConfig* config,
- uint32_t max_udp_payload_size) {
- config->max_udp_payload_size_.SetReceivedValue(max_udp_payload_size);
-}
-
-// static
-void QuicConfigPeer::SetReceivedMinAckDelayMs(QuicConfig* config,
- uint32_t min_ack_delay_ms) {
- config->min_ack_delay_ms_.SetReceivedValue(min_ack_delay_ms);
-}
-
-// static
-void QuicConfigPeer::SetNegotiated(QuicConfig* config, bool negotiated) {
- config->negotiated_ = negotiated;
-}
-
-// static
-void QuicConfigPeer::SetReceivedOriginalConnectionId(
- QuicConfig* config,
- const QuicConnectionId& original_destination_connection_id) {
- config->received_original_destination_connection_id_ =
- original_destination_connection_id;
-}
-
-// static
-void QuicConfigPeer::SetReceivedInitialSourceConnectionId(
- QuicConfig* config,
- const QuicConnectionId& initial_source_connection_id) {
- config->received_initial_source_connection_id_ = initial_source_connection_id;
-}
-
-// static
-void QuicConfigPeer::SetReceivedRetrySourceConnectionId(
- QuicConfig* config,
- const QuicConnectionId& retry_source_connection_id) {
- config->received_retry_source_connection_id_ = retry_source_connection_id;
-}
-
-// static
-void QuicConfigPeer::SetReceivedMaxDatagramFrameSize(
- QuicConfig* config,
- uint64_t max_datagram_frame_size) {
- config->max_datagram_frame_size_.SetReceivedValue(max_datagram_frame_size);
-}
-
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/quic_config_peer.h b/chromium/net/third_party/quiche/src/quic/test_tools/quic_config_peer.h
deleted file mode 100644
index 6ffc5aeef2d..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/quic_config_peer.h
+++ /dev/null
@@ -1,88 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_QUIC_CONFIG_PEER_H_
-#define QUICHE_QUIC_TEST_TOOLS_QUIC_CONFIG_PEER_H_
-
-#include "quic/core/quic_config.h"
-#include "quic/core/quic_connection_id.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_types.h"
-
-namespace quic {
-
-class QuicConfig;
-
-namespace test {
-
-class QuicConfigPeer {
- public:
- QuicConfigPeer() = delete;
-
- static void SetReceivedInitialStreamFlowControlWindow(QuicConfig* config,
- uint32_t window_bytes);
-
- static void SetReceivedInitialMaxStreamDataBytesIncomingBidirectional(
- QuicConfig* config,
- uint32_t window_bytes);
-
- static void SetReceivedInitialMaxStreamDataBytesOutgoingBidirectional(
- QuicConfig* config,
- uint32_t window_bytes);
-
- static void SetReceivedInitialMaxStreamDataBytesUnidirectional(
- QuicConfig* config,
- uint32_t window_bytes);
-
- static void SetReceivedInitialSessionFlowControlWindow(QuicConfig* config,
- uint32_t window_bytes);
-
- static void SetReceivedConnectionOptions(QuicConfig* config,
- const QuicTagVector& options);
-
- static void SetReceivedBytesForConnectionId(QuicConfig* config,
- uint32_t bytes);
-
- static void SetReceivedDisableConnectionMigration(QuicConfig* config);
-
- static void SetReceivedMaxBidirectionalStreams(QuicConfig* config,
- uint32_t max_streams);
- static void SetReceivedMaxUnidirectionalStreams(QuicConfig* config,
- uint32_t max_streams);
-
- static void SetConnectionOptionsToSend(QuicConfig* config,
- const QuicTagVector& options);
-
- static void SetReceivedStatelessResetToken(QuicConfig* config,
- const StatelessResetToken& token);
-
- static void SetReceivedMaxPacketSize(QuicConfig* config,
- uint32_t max_udp_payload_size);
-
- static void SetReceivedMinAckDelayMs(QuicConfig* config,
- uint32_t min_ack_delay_ms);
-
- static void SetNegotiated(QuicConfig* config, bool negotiated);
-
- static void SetReceivedOriginalConnectionId(
- QuicConfig* config,
- const QuicConnectionId& original_destination_connection_id);
-
- static void SetReceivedInitialSourceConnectionId(
- QuicConfig* config,
- const QuicConnectionId& initial_source_connection_id);
-
- static void SetReceivedRetrySourceConnectionId(
- QuicConfig* config,
- const QuicConnectionId& retry_source_connection_id);
-
- static void SetReceivedMaxDatagramFrameSize(QuicConfig* config,
- uint64_t max_datagram_frame_size);
-};
-
-} // namespace test
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_TEST_TOOLS_QUIC_CONFIG_PEER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/quic_connection_id_manager_peer.h b/chromium/net/third_party/quiche/src/quic/test_tools/quic_connection_id_manager_peer.h
deleted file mode 100644
index ab749ed440c..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/quic_connection_id_manager_peer.h
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_QUIC_CONNECTION_ID_MANAGER_PEER_H_
-#define QUICHE_QUIC_TEST_TOOLS_QUIC_CONNECTION_ID_MANAGER_PEER_H_
-
-#include "quic/core/quic_connection_id_manager.h"
-
-namespace quic {
-namespace test {
-
-class QuicConnectionIdManagerPeer {
- public:
- static QuicAlarm* GetRetirePeerIssuedConnectionIdAlarm(
- QuicPeerIssuedConnectionIdManager* manager) {
- return manager->retire_connection_id_alarm_.get();
- }
-
- static QuicAlarm* GetRetireSelfIssuedConnectionIdAlarm(
- QuicSelfIssuedConnectionIdManager* manager) {
- return manager->retire_connection_id_alarm_.get();
- }
-};
-
-} // namespace test
-} // namespace quic
-
-#endif // QUICHE_QUIC_TEST_TOOLS_QUIC_CONNECTION_ID_MANAGER_PEER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/quic_connection_peer.cc b/chromium/net/third_party/quiche/src/quic/test_tools/quic_connection_peer.cc
deleted file mode 100644
index 207582f738a..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/quic_connection_peer.cc
+++ /dev/null
@@ -1,539 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/quic_connection_peer.h"
-
-#include "absl/strings/string_view.h"
-#include "quic/core/congestion_control/send_algorithm_interface.h"
-#include "quic/core/quic_packet_writer.h"
-#include "quic/core/quic_received_packet_manager.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_socket_address.h"
-#include "quic/test_tools/quic_connection_id_manager_peer.h"
-#include "quic/test_tools/quic_framer_peer.h"
-#include "quic/test_tools/quic_sent_packet_manager_peer.h"
-
-namespace quic {
-namespace test {
-
-// static
-void QuicConnectionPeer::SetSendAlgorithm(
- QuicConnection* connection,
- SendAlgorithmInterface* send_algorithm) {
- GetSentPacketManager(connection)->SetSendAlgorithm(send_algorithm);
-}
-
-// static
-void QuicConnectionPeer::SetLossAlgorithm(
- QuicConnection* connection,
- LossDetectionInterface* loss_algorithm) {
- GetSentPacketManager(connection)->loss_algorithm_ = loss_algorithm;
-}
-
-// static
-void QuicConnectionPeer::PopulateStopWaitingFrame(
- QuicConnection* connection,
- QuicStopWaitingFrame* stop_waiting) {
- connection->PopulateStopWaitingFrame(stop_waiting);
-}
-
-// static
-QuicPacketCreator* QuicConnectionPeer::GetPacketCreator(
- QuicConnection* connection) {
- return &connection->packet_creator_;
-}
-
-// static
-QuicSentPacketManager* QuicConnectionPeer::GetSentPacketManager(
- QuicConnection* connection) {
- return &connection->sent_packet_manager_;
-}
-
-// static
-QuicTime::Delta QuicConnectionPeer::GetNetworkTimeout(
- QuicConnection* connection) {
- return connection->idle_network_detector_.idle_network_timeout_;
-}
-
-// static
-QuicTime::Delta QuicConnectionPeer::GetHandshakeTimeout(
- QuicConnection* connection) {
- return connection->idle_network_detector_.handshake_timeout_;
-}
-
-// static
-void QuicConnectionPeer::SetPerspective(QuicConnection* connection,
- Perspective perspective) {
- connection->perspective_ = perspective;
- QuicFramerPeer::SetPerspective(&connection->framer_, perspective);
-}
-
-// static
-void QuicConnectionPeer::SetSelfAddress(QuicConnection* connection,
- const QuicSocketAddress& self_address) {
- connection->default_path_.self_address = self_address;
-}
-
-// static
-void QuicConnectionPeer::SetPeerAddress(QuicConnection* connection,
- const QuicSocketAddress& peer_address) {
- connection->UpdatePeerAddress(peer_address);
-}
-
-// static
-void QuicConnectionPeer::SetDirectPeerAddress(
- QuicConnection* connection,
- const QuicSocketAddress& direct_peer_address) {
- connection->direct_peer_address_ = direct_peer_address;
-}
-
-// static
-void QuicConnectionPeer::SetEffectivePeerAddress(
- QuicConnection* connection,
- const QuicSocketAddress& effective_peer_address) {
- connection->default_path_.peer_address = effective_peer_address;
-}
-
-// static
-void QuicConnectionPeer::SwapCrypters(QuicConnection* connection,
- QuicFramer* framer) {
- QuicFramerPeer::SwapCrypters(framer, &connection->framer_);
-}
-
-// static
-void QuicConnectionPeer::SetCurrentPacket(QuicConnection* connection,
- absl::string_view current_packet) {
- connection->current_packet_data_ = current_packet.data();
- connection->last_size_ = current_packet.size();
-}
-
-// static
-QuicConnectionHelperInterface* QuicConnectionPeer::GetHelper(
- QuicConnection* connection) {
- return connection->helper_;
-}
-
-// static
-QuicAlarmFactory* QuicConnectionPeer::GetAlarmFactory(
- QuicConnection* connection) {
- return connection->alarm_factory_;
-}
-
-// static
-QuicFramer* QuicConnectionPeer::GetFramer(QuicConnection* connection) {
- return &connection->framer_;
-}
-
-// static
-QuicAlarm* QuicConnectionPeer::GetAckAlarm(QuicConnection* connection) {
- return connection->ack_alarm_.get();
-}
-
-// static
-QuicAlarm* QuicConnectionPeer::GetPingAlarm(QuicConnection* connection) {
- return connection->ping_alarm_.get();
-}
-
-// static
-QuicAlarm* QuicConnectionPeer::GetRetransmissionAlarm(
- QuicConnection* connection) {
- return connection->retransmission_alarm_.get();
-}
-
-// static
-QuicAlarm* QuicConnectionPeer::GetSendAlarm(QuicConnection* connection) {
- return connection->send_alarm_.get();
-}
-
-// static
-QuicAlarm* QuicConnectionPeer::GetMtuDiscoveryAlarm(
- QuicConnection* connection) {
- return connection->mtu_discovery_alarm_.get();
-}
-
-// static
-QuicAlarm* QuicConnectionPeer::GetProcessUndecryptablePacketsAlarm(
- QuicConnection* connection) {
- return connection->process_undecryptable_packets_alarm_.get();
-}
-
-// static
-QuicAlarm* QuicConnectionPeer::GetDiscardPreviousOneRttKeysAlarm(
- QuicConnection* connection) {
- return connection->discard_previous_one_rtt_keys_alarm_.get();
-}
-
-// static
-QuicAlarm* QuicConnectionPeer::GetDiscardZeroRttDecryptionKeysAlarm(
- QuicConnection* connection) {
- return connection->discard_zero_rtt_decryption_keys_alarm_.get();
-}
-
-// static
-QuicAlarm* QuicConnectionPeer::GetRetirePeerIssuedConnectionIdAlarm(
- QuicConnection* connection) {
- if (connection->peer_issued_cid_manager_ == nullptr) {
- return nullptr;
- }
- return QuicConnectionIdManagerPeer::GetRetirePeerIssuedConnectionIdAlarm(
- connection->peer_issued_cid_manager_.get());
-}
-// static
-QuicAlarm* QuicConnectionPeer::GetRetireSelfIssuedConnectionIdAlarm(
- QuicConnection* connection) {
- if (connection->self_issued_cid_manager_ == nullptr) {
- return nullptr;
- }
- return QuicConnectionIdManagerPeer::GetRetireSelfIssuedConnectionIdAlarm(
- connection->self_issued_cid_manager_.get());
-}
-
-// static
-QuicPacketWriter* QuicConnectionPeer::GetWriter(QuicConnection* connection) {
- return connection->writer_;
-}
-
-// static
-void QuicConnectionPeer::SetWriter(QuicConnection* connection,
- QuicPacketWriter* writer,
- bool owns_writer) {
- if (connection->owns_writer_) {
- delete connection->writer_;
- }
- connection->writer_ = writer;
- connection->owns_writer_ = owns_writer;
-}
-
-// static
-void QuicConnectionPeer::TearDownLocalConnectionState(
- QuicConnection* connection) {
- connection->connected_ = false;
-}
-
-// static
-QuicEncryptedPacket* QuicConnectionPeer::GetConnectionClosePacket(
- QuicConnection* connection) {
- if (connection->termination_packets_ == nullptr ||
- connection->termination_packets_->empty()) {
- return nullptr;
- }
- return (*connection->termination_packets_)[0].get();
-}
-
-// static
-QuicPacketHeader* QuicConnectionPeer::GetLastHeader(
- QuicConnection* connection) {
- return &connection->last_header_;
-}
-
-// static
-QuicConnectionStats* QuicConnectionPeer::GetStats(QuicConnection* connection) {
- return &connection->stats_;
-}
-
-// static
-QuicPacketCount QuicConnectionPeer::GetPacketsBetweenMtuProbes(
- QuicConnection* connection) {
- return connection->mtu_discoverer_.packets_between_probes();
-}
-
-// static
-void QuicConnectionPeer::ReInitializeMtuDiscoverer(
- QuicConnection* connection,
- QuicPacketCount packets_between_probes_base,
- QuicPacketNumber next_probe_at) {
- connection->mtu_discoverer_ =
- QuicConnectionMtuDiscoverer(packets_between_probes_base, next_probe_at);
-}
-
-// static
-void QuicConnectionPeer::SetAckDecimationDelay(QuicConnection* connection,
- float ack_decimation_delay) {
- for (auto& received_packet_manager :
- connection->uber_received_packet_manager_.received_packet_managers_) {
- received_packet_manager.ack_decimation_delay_ = ack_decimation_delay;
- }
-}
-
-// static
-bool QuicConnectionPeer::HasRetransmittableFrames(QuicConnection* connection,
- uint64_t packet_number) {
- return QuicSentPacketManagerPeer::HasRetransmittableFrames(
- GetSentPacketManager(connection), packet_number);
-}
-
-// static
-bool QuicConnectionPeer::GetNoStopWaitingFrames(QuicConnection* connection) {
- return connection->no_stop_waiting_frames_;
-}
-
-// static
-void QuicConnectionPeer::SetNoStopWaitingFrames(QuicConnection* connection,
- bool no_stop_waiting_frames) {
- connection->no_stop_waiting_frames_ = no_stop_waiting_frames;
-}
-
-// static
-void QuicConnectionPeer::SetMaxTrackedPackets(
- QuicConnection* connection,
- QuicPacketCount max_tracked_packets) {
- connection->max_tracked_packets_ = max_tracked_packets;
-}
-
-// static
-void QuicConnectionPeer::SetNegotiatedVersion(QuicConnection* connection) {
- connection->version_negotiated_ = true;
- if (connection->perspective() == Perspective::IS_SERVER &&
- !QuicFramerPeer::infer_packet_header_type_from_version(
- &connection->framer_)) {
- connection->framer_.InferPacketHeaderTypeFromVersion();
- }
-}
-
-// static
-void QuicConnectionPeer::SetMaxConsecutiveNumPacketsWithNoRetransmittableFrames(
- QuicConnection* connection,
- size_t new_value) {
- connection->max_consecutive_num_packets_with_no_retransmittable_frames_ =
- new_value;
-}
-
-// static
-bool QuicConnectionPeer::SupportsReleaseTime(QuicConnection* connection) {
- return connection->supports_release_time_;
-}
-
-// static
-QuicConnection::PacketContent QuicConnectionPeer::GetCurrentPacketContent(
- QuicConnection* connection) {
- return connection->current_packet_content_;
-}
-
-// 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()) {
- connection->default_path_.bytes_received_before_address_validation +=
- length;
- }
-}
-
-// static
-void QuicConnectionPeer::SetAddressValidated(QuicConnection* connection) {
- connection->default_path_.validated = true;
-}
-
-// static
-void QuicConnectionPeer::SendConnectionClosePacket(
- QuicConnection* connection,
- QuicIetfTransportErrorCodes ietf_error,
- QuicErrorCode error,
- const std::string& details) {
- connection->SendConnectionClosePacket(error, ietf_error, details);
-}
-
-// static
-size_t QuicConnectionPeer::GetNumEncryptionLevels(QuicConnection* connection) {
- size_t count = 0;
- for (EncryptionLevel level :
- {ENCRYPTION_INITIAL, ENCRYPTION_HANDSHAKE, ENCRYPTION_ZERO_RTT,
- ENCRYPTION_FORWARD_SECURE}) {
- if (connection->framer_.HasEncrypterOfEncryptionLevel(level)) {
- ++count;
- }
- }
- return count;
-}
-
-// static
-QuicNetworkBlackholeDetector& QuicConnectionPeer::GetBlackholeDetector(
- QuicConnection* connection) {
- return connection->blackhole_detector_;
-}
-
-// static
-QuicAlarm* QuicConnectionPeer::GetBlackholeDetectorAlarm(
- QuicConnection* connection) {
- return connection->blackhole_detector_.alarm_.get();
-}
-
-// static
-QuicTime QuicConnectionPeer::GetPathDegradingDeadline(
- QuicConnection* connection) {
- return connection->blackhole_detector_.path_degrading_deadline_;
-}
-
-// static
-QuicTime QuicConnectionPeer::GetBlackholeDetectionDeadline(
- QuicConnection* connection) {
- return connection->blackhole_detector_.blackhole_deadline_;
-}
-
-// static
-QuicTime QuicConnectionPeer::GetPathMtuReductionDetectionDeadline(
- QuicConnection* connection) {
- return connection->blackhole_detector_.path_mtu_reduction_deadline_;
-}
-
-// static
-QuicTime QuicConnectionPeer::GetIdleNetworkDeadline(
- QuicConnection* connection) {
- return connection->idle_network_detector_.GetIdleNetworkDeadline();
-}
-
-// static
-QuicAlarm* QuicConnectionPeer::GetIdleNetworkDetectorAlarm(
- QuicConnection* connection) {
- return connection->idle_network_detector_.alarm_.get();
-}
-
-// static
-QuicIdleNetworkDetector& QuicConnectionPeer::GetIdleNetworkDetector(
- QuicConnection* connection) {
- return connection->idle_network_detector_;
-}
-
-// static
-void QuicConnectionPeer::SetServerConnectionId(
- QuicConnection* connection,
- const QuicConnectionId& server_connection_id) {
- connection->default_path_.server_connection_id = server_connection_id;
- connection->InstallInitialCrypters(server_connection_id);
-}
-
-// static
-size_t QuicConnectionPeer::NumUndecryptablePackets(QuicConnection* connection) {
- return connection->undecryptable_packets_.size();
-}
-
-void QuicConnectionPeer::SetConnectionClose(QuicConnection* connection) {
- connection->connected_ = false;
-}
-
-// static
-void QuicConnectionPeer::SendPing(QuicConnection* connection) {
- connection->SendPingAtLevel(connection->encryption_level());
-}
-
-// static
-void QuicConnectionPeer::SetLastPacketDestinationAddress(
- QuicConnection* connection,
- const QuicSocketAddress& address) {
- connection->last_received_packet_info_.destination_address = address;
-}
-
-// static
-QuicPathValidator* QuicConnectionPeer::path_validator(
- QuicConnection* connection) {
- return &connection->path_validator_;
-}
-
-// static
-QuicByteCount QuicConnectionPeer::BytesSentOnAlternativePath(
- QuicConnection* connection) {
- return connection->alternative_path_.bytes_sent_before_address_validation;
-}
-
-// static
-QuicByteCount QuicConnectionPeer::BytesReceivedOnAlternativePath(
- QuicConnection* connection) {
- return connection->alternative_path_.bytes_received_before_address_validation;
-}
-
-// static
-QuicConnectionId QuicConnectionPeer::GetClientConnectionIdOnAlternativePath(
- const QuicConnection* connection) {
- return connection->alternative_path_.client_connection_id;
-}
-
-// static
-QuicConnectionId QuicConnectionPeer::GetServerConnectionIdOnAlternativePath(
- const QuicConnection* connection) {
- return connection->alternative_path_.server_connection_id;
-}
-
-// static
-bool QuicConnectionPeer::IsAlternativePathValidated(
- QuicConnection* connection) {
- return connection->alternative_path_.validated;
-}
-
-// static
-bool QuicConnectionPeer::IsAlternativePath(
- QuicConnection* connection,
- const QuicSocketAddress& self_address,
- const QuicSocketAddress& peer_address) {
- return connection->IsAlternativePath(self_address, peer_address);
-}
-
-// static
-QuicByteCount QuicConnectionPeer::BytesReceivedBeforeAddressValidation(
- QuicConnection* connection) {
- return connection->default_path_.bytes_received_before_address_validation;
-}
-
-// static
-void QuicConnectionPeer::ResetPeerIssuedConnectionIdManager(
- QuicConnection* connection) {
- connection->peer_issued_cid_manager_ = nullptr;
-}
-
-// static
-QuicConnection::PathState* QuicConnectionPeer::GetDefaultPath(
- QuicConnection* connection) {
- return &connection->default_path_;
-}
-
-// static
-QuicConnection::PathState* QuicConnectionPeer::GetAlternativePath(
- QuicConnection* connection) {
- return &connection->alternative_path_;
-}
-
-// static
-void QuicConnectionPeer::RetirePeerIssuedConnectionIdsNoLongerOnPath(
- QuicConnection* connection) {
- connection->RetirePeerIssuedConnectionIdsNoLongerOnPath();
-}
-
-// static
-bool QuicConnectionPeer::HasUnusedPeerIssuedConnectionId(
- const QuicConnection* connection) {
- return connection->peer_issued_cid_manager_->HasUnusedConnectionId();
-}
-
-// static
-bool QuicConnectionPeer::HasSelfIssuedConnectionIdToConsume(
- const QuicConnection* connection) {
- return connection->self_issued_cid_manager_->HasConnectionIdToConsume();
-}
-
-// static
-QuicSelfIssuedConnectionIdManager*
-QuicConnectionPeer::GetSelfIssuedConnectionIdManager(
- QuicConnection* connection) {
- return connection->self_issued_cid_manager_.get();
-}
-
-// static
-std::unique_ptr<QuicSelfIssuedConnectionIdManager>
-QuicConnectionPeer::MakeSelfIssuedConnectionIdManager(
- QuicConnection* connection) {
- return connection->MakeSelfIssuedConnectionIdManager();
-}
-
-// static
-void QuicConnectionPeer::SetLastDecryptedLevel(QuicConnection* connection,
- EncryptionLevel level) {
- connection->last_decrypted_packet_level_ = level;
-}
-
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/quic_connection_peer.h b/chromium/net/third_party/quiche/src/quic/test_tools/quic_connection_peer.h
deleted file mode 100644
index 62ed60e2bef..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/quic_connection_peer.h
+++ /dev/null
@@ -1,229 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_QUIC_CONNECTION_PEER_H_
-#define QUICHE_QUIC_TEST_TOOLS_QUIC_CONNECTION_PEER_H_
-
-#include <cstddef>
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_connection.h"
-#include "quic/core/quic_connection_id.h"
-#include "quic/core/quic_connection_stats.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_socket_address.h"
-
-namespace quic {
-
-struct QuicPacketHeader;
-class QuicAlarm;
-class QuicConnectionHelperInterface;
-class QuicConnectionVisitorInterface;
-class QuicEncryptedPacket;
-class QuicFramer;
-class QuicPacketCreator;
-class QuicPacketWriter;
-class QuicSentPacketManager;
-class SendAlgorithmInterface;
-
-namespace test {
-
-// Peer to make public a number of otherwise private QuicConnection methods.
-class QuicConnectionPeer {
- public:
- QuicConnectionPeer() = delete;
-
- static void SetSendAlgorithm(QuicConnection* connection,
- SendAlgorithmInterface* send_algorithm);
-
- static void SetLossAlgorithm(QuicConnection* connection,
- LossDetectionInterface* loss_algorithm);
-
- static void PopulateStopWaitingFrame(QuicConnection* connection,
- QuicStopWaitingFrame* stop_waiting);
-
- static QuicPacketCreator* GetPacketCreator(QuicConnection* connection);
-
- static QuicSentPacketManager* GetSentPacketManager(
- QuicConnection* connection);
-
- static QuicTime::Delta GetNetworkTimeout(QuicConnection* connection);
-
- static QuicTime::Delta GetHandshakeTimeout(QuicConnection* connection);
-
- static void SetPerspective(QuicConnection* connection,
- Perspective perspective);
-
- static void SetSelfAddress(QuicConnection* connection,
- const QuicSocketAddress& self_address);
-
- static void SetPeerAddress(QuicConnection* connection,
- const QuicSocketAddress& peer_address);
-
- static void SetDirectPeerAddress(
- QuicConnection* connection,
- const QuicSocketAddress& direct_peer_address);
-
- static void SetEffectivePeerAddress(
- QuicConnection* connection,
- const QuicSocketAddress& effective_peer_address);
-
- static void SwapCrypters(QuicConnection* connection, QuicFramer* framer);
-
- static void SetCurrentPacket(QuicConnection* connection,
- absl::string_view current_packet);
-
- static QuicConnectionHelperInterface* GetHelper(QuicConnection* connection);
-
- static QuicAlarmFactory* GetAlarmFactory(QuicConnection* connection);
-
- static QuicFramer* GetFramer(QuicConnection* connection);
-
- static QuicAlarm* GetAckAlarm(QuicConnection* connection);
- static QuicAlarm* GetPingAlarm(QuicConnection* connection);
- static QuicAlarm* GetRetransmissionAlarm(QuicConnection* connection);
- static QuicAlarm* GetSendAlarm(QuicConnection* connection);
- static QuicAlarm* GetMtuDiscoveryAlarm(QuicConnection* connection);
- static QuicAlarm* GetProcessUndecryptablePacketsAlarm(
- QuicConnection* connection);
- static QuicAlarm* GetDiscardPreviousOneRttKeysAlarm(
- QuicConnection* connection);
- static QuicAlarm* GetDiscardZeroRttDecryptionKeysAlarm(
- QuicConnection* connection);
- static QuicAlarm* GetRetirePeerIssuedConnectionIdAlarm(
- QuicConnection* connection);
- static QuicAlarm* GetRetireSelfIssuedConnectionIdAlarm(
- QuicConnection* connection);
-
- static QuicPacketWriter* GetWriter(QuicConnection* connection);
- // If |owns_writer| is true, takes ownership of |writer|.
- static void SetWriter(QuicConnection* connection,
- QuicPacketWriter* writer,
- bool owns_writer);
- static void TearDownLocalConnectionState(QuicConnection* connection);
- static QuicEncryptedPacket* GetConnectionClosePacket(
- QuicConnection* connection);
-
- static QuicPacketHeader* GetLastHeader(QuicConnection* connection);
-
- static QuicConnectionStats* GetStats(QuicConnection* connection);
-
- static QuicPacketCount GetPacketsBetweenMtuProbes(QuicConnection* connection);
-
- static void ReInitializeMtuDiscoverer(
- QuicConnection* connection,
- QuicPacketCount packets_between_probes_base,
- QuicPacketNumber next_probe_at);
- static void SetAckDecimationDelay(QuicConnection* connection,
- float ack_decimation_delay);
- static bool HasRetransmittableFrames(QuicConnection* connection,
- uint64_t packet_number);
- static bool GetNoStopWaitingFrames(QuicConnection* connection);
- static void SetNoStopWaitingFrames(QuicConnection* connection,
- bool no_stop_waiting_frames);
- static void SetMaxTrackedPackets(QuicConnection* connection,
- QuicPacketCount max_tracked_packets);
- static void SetNegotiatedVersion(QuicConnection* connection);
- static void SetMaxConsecutiveNumPacketsWithNoRetransmittableFrames(
- QuicConnection* connection,
- size_t new_value);
- 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);
-
- static void SendConnectionClosePacket(QuicConnection* connection,
- QuicIetfTransportErrorCodes ietf_error,
- QuicErrorCode error,
- const std::string& details);
-
- static size_t GetNumEncryptionLevels(QuicConnection* connection);
-
- static QuicNetworkBlackholeDetector& GetBlackholeDetector(
- QuicConnection* connection);
-
- static QuicAlarm* GetBlackholeDetectorAlarm(QuicConnection* connection);
-
- static QuicTime GetPathDegradingDeadline(QuicConnection* connection);
-
- static QuicTime GetBlackholeDetectionDeadline(QuicConnection* connection);
-
- static QuicTime GetPathMtuReductionDetectionDeadline(
- QuicConnection* connection);
-
- static QuicAlarm* GetIdleNetworkDetectorAlarm(QuicConnection* connection);
-
- static QuicTime GetIdleNetworkDeadline(QuicConnection* connection);
-
- static QuicIdleNetworkDetector& GetIdleNetworkDetector(
- QuicConnection* connection);
-
- static void SetServerConnectionId(
- QuicConnection* connection,
- const QuicConnectionId& server_connection_id);
-
- static size_t NumUndecryptablePackets(QuicConnection* connection);
-
- static void SetConnectionClose(QuicConnection* connection);
-
- static void SendPing(QuicConnection* connection);
-
- static void SetLastPacketDestinationAddress(QuicConnection* connection,
- const QuicSocketAddress& address);
-
- static QuicPathValidator* path_validator(QuicConnection* connection);
-
- static QuicByteCount BytesSentOnAlternativePath(QuicConnection* connection);
-
- static QuicByteCount BytesReceivedOnAlternativePath(
- QuicConnection* connection);
-
- static QuicConnectionId GetClientConnectionIdOnAlternativePath(
- const QuicConnection* connection);
-
- static QuicConnectionId GetServerConnectionIdOnAlternativePath(
- const QuicConnection* connection);
-
- static bool IsAlternativePath(QuicConnection* connection,
- const QuicSocketAddress& self_address,
- const QuicSocketAddress& peer_address);
-
- static bool IsAlternativePathValidated(QuicConnection* connection);
-
- static QuicByteCount BytesReceivedBeforeAddressValidation(
- QuicConnection* connection);
-
- static void ResetPeerIssuedConnectionIdManager(QuicConnection* connection);
-
- static QuicConnection::PathState* GetDefaultPath(QuicConnection* connection);
-
- static QuicConnection::PathState* GetAlternativePath(
- QuicConnection* connection);
-
- static void RetirePeerIssuedConnectionIdsNoLongerOnPath(
- QuicConnection* connection);
-
- static bool HasUnusedPeerIssuedConnectionId(const QuicConnection* connection);
-
- static bool HasSelfIssuedConnectionIdToConsume(
- const QuicConnection* connection);
-
- static QuicSelfIssuedConnectionIdManager* GetSelfIssuedConnectionIdManager(
- QuicConnection* connection);
-
- static std::unique_ptr<QuicSelfIssuedConnectionIdManager>
- MakeSelfIssuedConnectionIdManager(QuicConnection* connection);
-
- static void SetLastDecryptedLevel(QuicConnection* connection,
- EncryptionLevel level);
-};
-
-} // namespace test
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_TEST_TOOLS_QUIC_CONNECTION_PEER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/quic_crypto_server_config_peer.cc b/chromium/net/third_party/quiche/src/quic/test_tools/quic_crypto_server_config_peer.cc
deleted file mode 100644
index edf473c9d47..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/quic_crypto_server_config_peer.cc
+++ /dev/null
@@ -1,163 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/quic_crypto_server_config_peer.h"
-
-#include "absl/strings/string_view.h"
-#include "quic/test_tools/mock_clock.h"
-#include "quic/test_tools/mock_random.h"
-#include "quic/test_tools/quic_test_utils.h"
-
-namespace quic {
-namespace test {
-
-QuicReferenceCountedPointer<QuicCryptoServerConfig::Config>
-QuicCryptoServerConfigPeer::GetPrimaryConfig() {
- QuicReaderMutexLock locked(&server_config_->configs_lock_);
- return QuicReferenceCountedPointer<QuicCryptoServerConfig::Config>(
- server_config_->primary_config_);
-}
-
-QuicReferenceCountedPointer<QuicCryptoServerConfig::Config>
-QuicCryptoServerConfigPeer::GetConfig(std::string config_id) {
- QuicReaderMutexLock locked(&server_config_->configs_lock_);
- if (config_id == "<primary>") {
- return QuicReferenceCountedPointer<QuicCryptoServerConfig::Config>(
- server_config_->primary_config_);
- } else {
- return server_config_->GetConfigWithScid(config_id);
- }
-}
-
-ProofSource* QuicCryptoServerConfigPeer::GetProofSource() const {
- return server_config_->proof_source_.get();
-}
-
-void QuicCryptoServerConfigPeer::ResetProofSource(
- std::unique_ptr<ProofSource> proof_source) {
- server_config_->proof_source_ = std::move(proof_source);
-}
-
-std::string QuicCryptoServerConfigPeer::NewSourceAddressToken(
- std::string config_id,
- SourceAddressTokens previous_tokens,
- const QuicIpAddress& ip,
- QuicRandom* rand,
- QuicWallTime now,
- CachedNetworkParameters* cached_network_params) {
- return server_config_->NewSourceAddressToken(
- *GetConfig(config_id)->source_address_token_boxer, previous_tokens, ip,
- rand, now, cached_network_params);
-}
-
-HandshakeFailureReason QuicCryptoServerConfigPeer::ValidateSourceAddressTokens(
- std::string config_id,
- absl::string_view srct,
- const QuicIpAddress& ip,
- QuicWallTime now,
- CachedNetworkParameters* cached_network_params) {
- SourceAddressTokens tokens;
- HandshakeFailureReason reason = server_config_->ParseSourceAddressToken(
- *GetConfig(config_id)->source_address_token_boxer, srct, tokens);
- if (reason != HANDSHAKE_OK) {
- return reason;
- }
-
- return server_config_->ValidateSourceAddressTokens(tokens, ip, now,
- cached_network_params);
-}
-
-HandshakeFailureReason
-QuicCryptoServerConfigPeer::ValidateSingleSourceAddressToken(
- absl::string_view token,
- const QuicIpAddress& ip,
- QuicWallTime now) {
- SourceAddressTokens tokens;
- HandshakeFailureReason parse_status = server_config_->ParseSourceAddressToken(
- *GetPrimaryConfig()->source_address_token_boxer, token, tokens);
- if (HANDSHAKE_OK != parse_status) {
- return parse_status;
- }
- EXPECT_EQ(1, tokens.tokens_size());
- return server_config_->ValidateSingleSourceAddressToken(tokens.tokens(0), ip,
- now);
-}
-
-void QuicCryptoServerConfigPeer::CheckConfigs(
- std::vector<std::pair<std::string, bool>> expected_ids_and_status) {
- QuicReaderMutexLock locked(&server_config_->configs_lock_);
-
- ASSERT_EQ(expected_ids_and_status.size(), server_config_->configs_.size())
- << ConfigsDebug();
-
- for (const std::pair<
- const ServerConfigID,
- QuicReferenceCountedPointer<QuicCryptoServerConfig::Config>>& i :
- server_config_->configs_) {
- bool found = false;
- for (std::pair<ServerConfigID, bool>& j : expected_ids_and_status) {
- if (i.first == j.first && i.second->is_primary == j.second) {
- found = true;
- j.first.clear();
- break;
- }
- }
-
- ASSERT_TRUE(found) << "Failed to find match for " << i.first
- << " in configs:\n"
- << ConfigsDebug();
- }
-}
-
-// ConfigsDebug returns a std::string that contains debugging information about
-// the set of Configs loaded in |server_config_| and their status.
-std::string QuicCryptoServerConfigPeer::ConfigsDebug() {
- if (server_config_->configs_.empty()) {
- return "No Configs in QuicCryptoServerConfig";
- }
-
- std::string s;
-
- for (const auto& i : server_config_->configs_) {
- const QuicReferenceCountedPointer<QuicCryptoServerConfig::Config> config =
- i.second;
- if (config->is_primary) {
- s += "(primary) ";
- } else {
- s += " ";
- }
- s += config->id;
- s += "\n";
- }
-
- return s;
-}
-
-void QuicCryptoServerConfigPeer::SelectNewPrimaryConfig(int seconds) {
- QuicWriterMutexLock locked(&server_config_->configs_lock_);
- server_config_->SelectNewPrimaryConfig(
- QuicWallTime::FromUNIXSeconds(seconds));
-}
-
-std::string QuicCryptoServerConfigPeer::CompressChain(
- QuicCompressedCertsCache* compressed_certs_cache,
- const QuicReferenceCountedPointer<ProofSource::Chain>& chain,
- const std::string& client_common_set_hashes,
- const std::string& client_cached_cert_hashes,
- const CommonCertSets* common_sets) {
- return QuicCryptoServerConfig::CompressChain(
- compressed_certs_cache, chain, client_common_set_hashes,
- client_cached_cert_hashes, common_sets);
-}
-
-uint32_t QuicCryptoServerConfigPeer::source_address_token_future_secs() {
- return server_config_->source_address_token_future_secs_;
-}
-
-uint32_t QuicCryptoServerConfigPeer::source_address_token_lifetime_secs() {
- return server_config_->source_address_token_lifetime_secs_;
-}
-
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/quic_crypto_server_config_peer.h b/chromium/net/third_party/quiche/src/quic/test_tools/quic_crypto_server_config_peer.h
deleted file mode 100644
index 8e0e5e7df69..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/quic_crypto_server_config_peer.h
+++ /dev/null
@@ -1,95 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_QUIC_CRYPTO_SERVER_CONFIG_PEER_H_
-#define QUICHE_QUIC_TEST_TOOLS_QUIC_CRYPTO_SERVER_CONFIG_PEER_H_
-
-#include "absl/strings/string_view.h"
-#include "quic/core/crypto/quic_crypto_server_config.h"
-
-namespace quic {
-namespace test {
-
-// Peer for accessing otherwise private members of a QuicCryptoServerConfig.
-class QuicCryptoServerConfigPeer {
- public:
- explicit QuicCryptoServerConfigPeer(QuicCryptoServerConfig* server_config)
- : server_config_(server_config) {}
-
- // Returns the primary config.
- QuicReferenceCountedPointer<QuicCryptoServerConfig::Config>
- GetPrimaryConfig();
-
- // Returns the config associated with |config_id|.
- QuicReferenceCountedPointer<QuicCryptoServerConfig::Config> GetConfig(
- std::string config_id);
-
- // Returns a pointer to the ProofSource object.
- ProofSource* GetProofSource() const;
-
- // Reset the proof_source_ member.
- void ResetProofSource(std::unique_ptr<ProofSource> proof_source);
-
- // Generates a new valid source address token.
- std::string NewSourceAddressToken(
- std::string config_id,
- SourceAddressTokens previous_tokens,
- const QuicIpAddress& ip,
- QuicRandom* rand,
- QuicWallTime now,
- CachedNetworkParameters* cached_network_params);
-
- // Attempts to validate the tokens in |srct|.
- HandshakeFailureReason ValidateSourceAddressTokens(
- std::string config_id, absl::string_view srct, const QuicIpAddress& ip,
- QuicWallTime now, CachedNetworkParameters* cached_network_params);
-
- // Attempts to validate the single source address token in |token|.
- HandshakeFailureReason ValidateSingleSourceAddressToken(
- absl::string_view token,
- const QuicIpAddress& ip,
- QuicWallTime now);
-
- // CheckConfigs compares the state of the Configs in |server_config_| to the
- // description given as arguments.
- // The first of each pair is the server config ID of a Config. The second is a
- // boolean describing whether the config is the primary. For example:
- // CheckConfigs(std::vector<std::pair<ServerConfigID, bool>>()); // checks
- // that no Configs are loaded.
- //
- // // Checks that exactly three Configs are loaded with the given IDs and
- // // status.
- // CheckConfigs(
- // {{"id1", false},
- // {"id2", true},
- // {"id3", false}});
- void CheckConfigs(
- std::vector<std::pair<ServerConfigID, bool>> expected_ids_and_status);
-
- // ConfigsDebug returns a std::string that contains debugging information
- // about the set of Configs loaded in |server_config_| and their status.
- std::string ConfigsDebug()
- QUIC_SHARED_LOCKS_REQUIRED(server_config_->configs_lock_);
-
- void SelectNewPrimaryConfig(int seconds);
-
- static std::string CompressChain(
- QuicCompressedCertsCache* compressed_certs_cache,
- const QuicReferenceCountedPointer<ProofSource::Chain>& chain,
- const std::string& client_common_set_hashes,
- const std::string& client_cached_cert_hashes,
- const CommonCertSets* common_sets);
-
- uint32_t source_address_token_future_secs();
-
- uint32_t source_address_token_lifetime_secs();
-
- private:
- QuicCryptoServerConfig* server_config_;
-};
-
-} // namespace test
-} // namespace quic
-
-#endif // QUICHE_QUIC_TEST_TOOLS_QUIC_CRYPTO_SERVER_CONFIG_PEER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/quic_dispatcher_peer.cc b/chromium/net/third_party/quiche/src/quic/test_tools/quic_dispatcher_peer.cc
deleted file mode 100644
index 341d5acfc84..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/quic_dispatcher_peer.cc
+++ /dev/null
@@ -1,143 +0,0 @@
-// Copyright 2013 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 "quic/test_tools/quic_dispatcher_peer.h"
-
-#include "quic/core/quic_dispatcher.h"
-#include "quic/core/quic_packet_writer_wrapper.h"
-
-namespace quic {
-namespace test {
-
-// static
-QuicTimeWaitListManager* QuicDispatcherPeer::GetTimeWaitListManager(
- QuicDispatcher* dispatcher) {
- return dispatcher->time_wait_list_manager_.get();
-}
-
-// static
-void QuicDispatcherPeer::SetTimeWaitListManager(
- QuicDispatcher* dispatcher,
- QuicTimeWaitListManager* time_wait_list_manager) {
- dispatcher->time_wait_list_manager_.reset(time_wait_list_manager);
-}
-
-// static
-void QuicDispatcherPeer::UseWriter(QuicDispatcher* dispatcher,
- QuicPacketWriterWrapper* writer) {
- writer->set_writer(dispatcher->writer_.release());
- dispatcher->writer_.reset(writer);
-}
-
-// static
-QuicPacketWriter* QuicDispatcherPeer::GetWriter(QuicDispatcher* dispatcher) {
- return dispatcher->writer_.get();
-}
-
-// static
-QuicCompressedCertsCache* QuicDispatcherPeer::GetCache(
- QuicDispatcher* dispatcher) {
- return dispatcher->compressed_certs_cache();
-}
-
-// static
-QuicConnectionHelperInterface* QuicDispatcherPeer::GetHelper(
- QuicDispatcher* dispatcher) {
- return dispatcher->helper_.get();
-}
-
-// static
-QuicAlarmFactory* QuicDispatcherPeer::GetAlarmFactory(
- QuicDispatcher* dispatcher) {
- return dispatcher->alarm_factory_.get();
-}
-
-// static
-QuicDispatcher::WriteBlockedList* QuicDispatcherPeer::GetWriteBlockedList(
- QuicDispatcher* dispatcher) {
- return &dispatcher->write_blocked_list_;
-}
-
-// static
-QuicErrorCode QuicDispatcherPeer::GetAndClearLastError(
- QuicDispatcher* dispatcher) {
- QuicErrorCode ret = dispatcher->last_error_;
- dispatcher->last_error_ = QUIC_NO_ERROR;
- return ret;
-}
-
-// static
-QuicBufferedPacketStore* QuicDispatcherPeer::GetBufferedPackets(
- QuicDispatcher* dispatcher) {
- return &(dispatcher->buffered_packets_);
-}
-
-// static
-void QuicDispatcherPeer::set_new_sessions_allowed_per_event_loop(
- QuicDispatcher* dispatcher,
- size_t num_session_allowed) {
- dispatcher->new_sessions_allowed_per_event_loop_ = num_session_allowed;
-}
-
-// static
-void QuicDispatcherPeer::SendPublicReset(
- QuicDispatcher* dispatcher,
- const QuicSocketAddress& self_address,
- const QuicSocketAddress& peer_address,
- QuicConnectionId connection_id,
- bool ietf_quic,
- size_t received_packet_length,
- std::unique_ptr<QuicPerPacketContext> packet_context) {
- dispatcher->time_wait_list_manager()->SendPublicReset(
- self_address, peer_address, connection_id, ietf_quic,
- received_packet_length, std::move(packet_context));
-}
-
-// static
-std::unique_ptr<QuicPerPacketContext> QuicDispatcherPeer::GetPerPacketContext(
- QuicDispatcher* dispatcher) {
- return dispatcher->GetPerPacketContext();
-}
-
-// static
-void QuicDispatcherPeer::RestorePerPacketContext(
- QuicDispatcher* dispatcher,
- std::unique_ptr<QuicPerPacketContext> context) {
- dispatcher->RestorePerPacketContext(std::move(context));
-}
-
-// static
-std::string QuicDispatcherPeer::SelectAlpn(
- QuicDispatcher* dispatcher,
- const std::vector<std::string>& alpns) {
- return dispatcher->SelectAlpn(alpns);
-}
-
-// static
-QuicSession* QuicDispatcherPeer::GetFirstSessionIfAny(
- QuicDispatcher* dispatcher) {
- if (dispatcher->reference_counted_session_map_.empty()) {
- return nullptr;
- }
- return dispatcher->reference_counted_session_map_.begin()->second.get();
-}
-
-// static
-const QuicSession* QuicDispatcherPeer::FindSession(
- const QuicDispatcher* dispatcher,
- QuicConnectionId id) {
- auto it = dispatcher->reference_counted_session_map_.find(id);
- return (it == dispatcher->reference_counted_session_map_.end())
- ? nullptr
- : it->second.get();
-}
-
-// static
-QuicAlarm* QuicDispatcherPeer::GetClearResetAddressesAlarm(
- QuicDispatcher* dispatcher) {
- return dispatcher->clear_stateless_reset_addresses_alarm_.get();
-}
-
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/quic_dispatcher_peer.h b/chromium/net/third_party/quiche/src/quic/test_tools/quic_dispatcher_peer.h
deleted file mode 100644
index ec83be4f9f2..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/quic_dispatcher_peer.h
+++ /dev/null
@@ -1,86 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_QUIC_DISPATCHER_PEER_H_
-#define QUICHE_QUIC_TEST_TOOLS_QUIC_DISPATCHER_PEER_H_
-
-#include "quic/core/quic_connection_id.h"
-#include "quic/core/quic_dispatcher.h"
-
-namespace quic {
-
-class QuicPacketWriterWrapper;
-
-namespace test {
-
-class QuicDispatcherPeer {
- public:
- QuicDispatcherPeer() = delete;
-
- static QuicTimeWaitListManager* GetTimeWaitListManager(
- QuicDispatcher* dispatcher);
-
- static void SetTimeWaitListManager(
- QuicDispatcher* dispatcher,
- QuicTimeWaitListManager* time_wait_list_manager);
-
- // Injects |writer| into |dispatcher| as the shared writer.
- static void UseWriter(QuicDispatcher* dispatcher,
- QuicPacketWriterWrapper* writer);
-
- static QuicPacketWriter* GetWriter(QuicDispatcher* dispatcher);
-
- static QuicCompressedCertsCache* GetCache(QuicDispatcher* dispatcher);
-
- static QuicConnectionHelperInterface* GetHelper(QuicDispatcher* dispatcher);
-
- static QuicAlarmFactory* GetAlarmFactory(QuicDispatcher* dispatcher);
-
- static QuicDispatcher::WriteBlockedList* GetWriteBlockedList(
- QuicDispatcher* dispatcher);
-
- // Get the dispatcher's record of the last error reported to its framer
- // visitor's OnError() method. Then set that record to QUIC_NO_ERROR.
- static QuicErrorCode GetAndClearLastError(QuicDispatcher* dispatcher);
-
- static QuicBufferedPacketStore* GetBufferedPackets(
- QuicDispatcher* dispatcher);
-
- static void set_new_sessions_allowed_per_event_loop(
- QuicDispatcher* dispatcher,
- size_t num_session_allowed);
-
- static void SendPublicReset(
- QuicDispatcher* dispatcher,
- const QuicSocketAddress& self_address,
- const QuicSocketAddress& peer_address,
- QuicConnectionId connection_id,
- bool ietf_quic,
- size_t received_packet_length,
- std::unique_ptr<QuicPerPacketContext> packet_context);
-
- static std::unique_ptr<QuicPerPacketContext> GetPerPacketContext(
- QuicDispatcher* dispatcher);
-
- static void RestorePerPacketContext(QuicDispatcher* dispatcher,
- std::unique_ptr<QuicPerPacketContext>);
-
- static std::string SelectAlpn(QuicDispatcher* dispatcher,
- const std::vector<std::string>& alpns);
-
- // Get the first session in the session map. Returns nullptr if the map is
- // empty.
- static QuicSession* GetFirstSessionIfAny(QuicDispatcher* dispatcher);
-
- // Find the corresponding session if exsits.
- static const QuicSession* FindSession(const QuicDispatcher* dispatcher,
- QuicConnectionId id);
-
- static QuicAlarm* GetClearResetAddressesAlarm(QuicDispatcher* dispatcher);
-};
-
-} // namespace test
-} // namespace quic
-
-#endif // QUICHE_QUIC_TEST_TOOLS_QUIC_DISPATCHER_PEER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/quic_flow_controller_peer.cc b/chromium/net/third_party/quiche/src/quic/test_tools/quic_flow_controller_peer.cc
deleted file mode 100644
index b0c9cbc00c1..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/quic_flow_controller_peer.cc
+++ /dev/null
@@ -1,68 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/quic_flow_controller_peer.h"
-
-#include <list>
-
-#include "quic/core/quic_flow_controller.h"
-#include "quic/core/quic_packets.h"
-
-namespace quic {
-namespace test {
-
-// static
-void QuicFlowControllerPeer::SetSendWindowOffset(
- QuicFlowController* flow_controller,
- QuicStreamOffset offset) {
- flow_controller->send_window_offset_ = offset;
-}
-
-// static
-void QuicFlowControllerPeer::SetReceiveWindowOffset(
- QuicFlowController* flow_controller,
- QuicStreamOffset offset) {
- flow_controller->receive_window_offset_ = offset;
-}
-
-// static
-void QuicFlowControllerPeer::SetMaxReceiveWindow(
- QuicFlowController* flow_controller,
- QuicByteCount window_size) {
- flow_controller->receive_window_size_ = window_size;
-}
-
-// static
-QuicStreamOffset QuicFlowControllerPeer::SendWindowOffset(
- QuicFlowController* flow_controller) {
- return flow_controller->send_window_offset_;
-}
-
-// static
-QuicByteCount QuicFlowControllerPeer::SendWindowSize(
- QuicFlowController* flow_controller) {
- return flow_controller->SendWindowSize();
-}
-
-// static
-QuicStreamOffset QuicFlowControllerPeer::ReceiveWindowOffset(
- QuicFlowController* flow_controller) {
- return flow_controller->receive_window_offset_;
-}
-
-// static
-QuicByteCount QuicFlowControllerPeer::ReceiveWindowSize(
- QuicFlowController* flow_controller) {
- return flow_controller->receive_window_offset_ -
- flow_controller->highest_received_byte_offset_;
-}
-
-// static
-QuicByteCount QuicFlowControllerPeer::WindowUpdateThreshold(
- QuicFlowController* flow_controller) {
- return flow_controller->WindowUpdateThreshold();
-}
-
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/quic_flow_controller_peer.h b/chromium/net/third_party/quiche/src/quic/test_tools/quic_flow_controller_peer.h
deleted file mode 100644
index 0a956205e19..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/quic_flow_controller_peer.h
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_QUIC_FLOW_CONTROLLER_PEER_H_
-#define QUICHE_QUIC_TEST_TOOLS_QUIC_FLOW_CONTROLLER_PEER_H_
-
-#include "quic/core/quic_packets.h"
-
-namespace quic {
-
-class QuicFlowController;
-
-namespace test {
-
-class QuicFlowControllerPeer {
- public:
- QuicFlowControllerPeer() = delete;
-
- static void SetSendWindowOffset(QuicFlowController* flow_controller,
- QuicStreamOffset offset);
-
- static void SetReceiveWindowOffset(QuicFlowController* flow_controller,
- QuicStreamOffset offset);
-
- static void SetMaxReceiveWindow(QuicFlowController* flow_controller,
- QuicByteCount window_size);
-
- static QuicStreamOffset SendWindowOffset(QuicFlowController* flow_controller);
-
- static QuicByteCount SendWindowSize(QuicFlowController* flow_controller);
-
- static QuicStreamOffset ReceiveWindowOffset(
- QuicFlowController* flow_controller);
-
- static QuicByteCount ReceiveWindowSize(QuicFlowController* flow_controller);
-
- static QuicByteCount WindowUpdateThreshold(
- QuicFlowController* flow_controller);
-};
-
-} // namespace test
-} // namespace quic
-
-#endif // QUICHE_QUIC_TEST_TOOLS_QUIC_FLOW_CONTROLLER_PEER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/quic_framer_peer.cc b/chromium/net/third_party/quiche/src/quic/test_tools/quic_framer_peer.cc
deleted file mode 100644
index 8692a25c685..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/quic_framer_peer.cc
+++ /dev/null
@@ -1,129 +0,0 @@
-// Copyright (c) 2013 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 "quic/test_tools/quic_framer_peer.h"
-
-#include "quic/core/quic_framer.h"
-#include "quic/core/quic_packets.h"
-
-namespace quic {
-namespace test {
-
-// static
-uint64_t QuicFramerPeer::CalculatePacketNumberFromWire(
- QuicFramer* framer,
- QuicPacketNumberLength packet_number_length,
- QuicPacketNumber last_packet_number,
- uint64_t packet_number) {
- return framer->CalculatePacketNumberFromWire(
- packet_number_length, last_packet_number, packet_number);
-}
-
-// static
-void QuicFramerPeer::SetLastSerializedServerConnectionId(
- QuicFramer* framer,
- QuicConnectionId server_connection_id) {
- framer->last_serialized_server_connection_id_ = server_connection_id;
-}
-
-// static
-void QuicFramerPeer::SetLastSerializedClientConnectionId(
- QuicFramer* framer,
- QuicConnectionId client_connection_id) {
- framer->last_serialized_client_connection_id_ = client_connection_id;
-}
-
-// static
-void QuicFramerPeer::SetLastWrittenPacketNumberLength(
- QuicFramer* framer,
- size_t packet_number_length) {
- framer->last_written_packet_number_length_ = packet_number_length;
-}
-
-// static
-void QuicFramerPeer::SetLargestPacketNumber(QuicFramer* framer,
- QuicPacketNumber packet_number) {
- framer->largest_packet_number_ = packet_number;
-}
-
-// static
-void QuicFramerPeer::SetPerspective(QuicFramer* framer,
- Perspective perspective) {
- framer->perspective_ = perspective;
- framer->infer_packet_header_type_from_version_ =
- perspective == Perspective::IS_CLIENT;
-}
-
-// static
-void QuicFramerPeer::SwapCrypters(QuicFramer* framer1, QuicFramer* framer2) {
- for (int i = ENCRYPTION_INITIAL; i < NUM_ENCRYPTION_LEVELS; i++) {
- framer1->encrypter_[i].swap(framer2->encrypter_[i]);
- framer1->decrypter_[i].swap(framer2->decrypter_[i]);
- }
-
- EncryptionLevel framer2_level = framer2->decrypter_level_;
- framer2->decrypter_level_ = framer1->decrypter_level_;
- framer1->decrypter_level_ = framer2_level;
- framer2_level = framer2->alternative_decrypter_level_;
- framer2->alternative_decrypter_level_ = framer1->alternative_decrypter_level_;
- framer1->alternative_decrypter_level_ = framer2_level;
-
- const bool framer2_latch = framer2->alternative_decrypter_latch_;
- framer2->alternative_decrypter_latch_ = framer1->alternative_decrypter_latch_;
- framer1->alternative_decrypter_latch_ = framer2_latch;
-}
-
-// static
-QuicEncrypter* QuicFramerPeer::GetEncrypter(QuicFramer* framer,
- EncryptionLevel level) {
- return framer->encrypter_[level].get();
-}
-
-// static
-QuicDecrypter* QuicFramerPeer::GetDecrypter(QuicFramer* framer,
- EncryptionLevel level) {
- return framer->decrypter_[level].get();
-}
-
-// static
-void QuicFramerPeer::SetFirstSendingPacketNumber(QuicFramer* framer,
- uint64_t packet_number) {
- *const_cast<QuicPacketNumber*>(&framer->first_sending_packet_number_) =
- QuicPacketNumber(packet_number);
-}
-
-// static
-void QuicFramerPeer::SetExpectedServerConnectionIDLength(
- QuicFramer* framer,
- uint8_t expected_server_connection_id_length) {
- *const_cast<uint8_t*>(&framer->expected_server_connection_id_length_) =
- expected_server_connection_id_length;
-}
-
-// static
-QuicPacketNumber QuicFramerPeer::GetLargestDecryptedPacketNumber(
- QuicFramer* framer,
- PacketNumberSpace packet_number_space) {
- return framer->largest_decrypted_packet_numbers_[packet_number_space];
-}
-
-// static
-bool QuicFramerPeer::ProcessAndValidateIetfConnectionIdLength(
- QuicDataReader* reader,
- ParsedQuicVersion version,
- Perspective perspective,
- bool should_update_expected_server_connection_id_length,
- uint8_t* expected_server_connection_id_length,
- uint8_t* destination_connection_id_length,
- uint8_t* source_connection_id_length,
- std::string* detailed_error) {
- return QuicFramer::ProcessAndValidateIetfConnectionIdLength(
- reader, version, perspective,
- should_update_expected_server_connection_id_length,
- expected_server_connection_id_length, destination_connection_id_length,
- source_connection_id_length, detailed_error);
-}
-
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/quic_framer_peer.h b/chromium/net/third_party/quiche/src/quic/test_tools/quic_framer_peer.h
deleted file mode 100644
index 091a7d4bd18..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/quic_framer_peer.h
+++ /dev/null
@@ -1,78 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_QUIC_FRAMER_PEER_H_
-#define QUICHE_QUIC_TEST_TOOLS_QUIC_FRAMER_PEER_H_
-
-#include "quic/core/crypto/quic_encrypter.h"
-#include "quic/core/quic_framer.h"
-#include "quic/core/quic_packets.h"
-
-namespace quic {
-
-namespace test {
-
-class QuicFramerPeer {
- public:
- QuicFramerPeer() = delete;
-
- static uint64_t CalculatePacketNumberFromWire(
- QuicFramer* framer,
- QuicPacketNumberLength packet_number_length,
- QuicPacketNumber last_packet_number,
- uint64_t packet_number);
- static void SetLastSerializedServerConnectionId(
- QuicFramer* framer,
- QuicConnectionId server_connection_id);
- static void SetLastSerializedClientConnectionId(
- QuicFramer* framer,
- QuicConnectionId client_connection_id);
- static void SetLastWrittenPacketNumberLength(QuicFramer* framer,
- size_t packet_number_length);
- static void SetLargestPacketNumber(QuicFramer* framer,
- QuicPacketNumber packet_number);
- static void SetPerspective(QuicFramer* framer, Perspective perspective);
-
- // SwapCrypters exchanges the state of the crypters of |framer1| with
- // |framer2|.
- static void SwapCrypters(QuicFramer* framer1, QuicFramer* framer2);
-
- static QuicEncrypter* GetEncrypter(QuicFramer* framer, EncryptionLevel level);
- static QuicDecrypter* GetDecrypter(QuicFramer* framer, EncryptionLevel level);
-
- static void SetFirstSendingPacketNumber(QuicFramer* framer,
- uint64_t packet_number);
- static void SetExpectedServerConnectionIDLength(
- QuicFramer* framer,
- uint8_t expected_server_connection_id_length);
- static QuicPacketNumber GetLargestDecryptedPacketNumber(
- QuicFramer* framer,
- PacketNumberSpace packet_number_space);
-
- static bool ProcessAndValidateIetfConnectionIdLength(
- QuicDataReader* reader,
- ParsedQuicVersion version,
- Perspective perspective,
- bool should_update_expected_server_connection_id_length,
- uint8_t* expected_server_connection_id_length,
- uint8_t* destination_connection_id_length,
- uint8_t* source_connection_id_length,
- std::string* detailed_error);
-
- static void set_current_received_frame_type(
- QuicFramer* framer,
- uint64_t current_received_frame_type) {
- framer->current_received_frame_type_ = current_received_frame_type;
- }
-
- static bool infer_packet_header_type_from_version(QuicFramer* framer) {
- return framer->infer_packet_header_type_from_version_;
- }
-};
-
-} // namespace test
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_TEST_TOOLS_QUIC_FRAMER_PEER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/quic_interval_deque_peer.h b/chromium/net/third_party/quiche/src/quic/test_tools/quic_interval_deque_peer.h
deleted file mode 100644
index de336e9f04b..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/quic_interval_deque_peer.h
+++ /dev/null
@@ -1,35 +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_TEST_TOOLS_QUIC_INTERVAL_DEQUE_PEER_H_
-#define QUICHE_QUIC_TEST_TOOLS_QUIC_INTERVAL_DEQUE_PEER_H_
-
-#include "quic/core/quic_interval_deque.h"
-
-namespace quic {
-
-namespace test {
-
-class QuicIntervalDequePeer {
- public:
- template <class T, class C>
- static int32_t GetCachedIndex(QuicIntervalDeque<T, C>* interval_deque) {
- if (!interval_deque->cached_index_.has_value()) {
- return -1;
- }
- return interval_deque->cached_index_.value();
- }
-
- template <class T, class C>
- static T* GetItem(QuicIntervalDeque<T, C>* interval_deque,
- const std::size_t index) {
- return &interval_deque->container_[index];
- }
-};
-
-} // namespace test
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_TEST_TOOLS_QUIC_INTERVAL_DEQUE_PEER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/quic_mock_syscall_wrapper.cc b/chromium/net/third_party/quiche/src/quic/test_tools/quic_mock_syscall_wrapper.cc
deleted file mode 100644
index 743d5c3d672..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/quic_mock_syscall_wrapper.cc
+++ /dev/null
@@ -1,22 +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 "quic/test_tools/quic_mock_syscall_wrapper.h"
-
-using testing::_;
-using testing::Invoke;
-
-namespace quic {
-namespace test {
-
-MockQuicSyscallWrapper::MockQuicSyscallWrapper(QuicSyscallWrapper* delegate) {
- ON_CALL(*this, Sendmsg(_, _, _))
- .WillByDefault(Invoke(delegate, &QuicSyscallWrapper::Sendmsg));
-
- ON_CALL(*this, Sendmmsg(_, _, _, _))
- .WillByDefault(Invoke(delegate, &QuicSyscallWrapper::Sendmmsg));
-}
-
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/quic_mock_syscall_wrapper.h b/chromium/net/third_party/quiche/src/quic/test_tools/quic_mock_syscall_wrapper.h
deleted file mode 100644
index 681d1bcdf9b..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/quic_mock_syscall_wrapper.h
+++ /dev/null
@@ -1,37 +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_IMPL_QUIC_MOCK_SYSCALL_WRAPPER_H_
-#define QUICHE_QUIC_PLATFORM_IMPL_QUIC_MOCK_SYSCALL_WRAPPER_H_
-
-#include "quic/core/quic_syscall_wrapper.h"
-#include "quic/platform/api/quic_test.h"
-
-namespace quic {
-namespace test {
-
-class MockQuicSyscallWrapper : public QuicSyscallWrapper {
- public:
- // Create a standard mock object.
- MockQuicSyscallWrapper() = default;
-
- // Create a 'mockable' object that delegates everything to |delegate| by
- // default.
- explicit MockQuicSyscallWrapper(QuicSyscallWrapper* delegate);
-
- MOCK_METHOD(ssize_t,
- Sendmsg,
- (int sockfd, const msghdr*, int flags),
- (override));
-
- MOCK_METHOD(int,
- Sendmmsg,
- (int sockfd, mmsghdr*, unsigned int vlen, int flags),
- (override));
-};
-
-} // namespace test
-} // namespace quic
-
-#endif // QUICHE_QUIC_PLATFORM_IMPL_QUIC_MOCK_SYSCALL_WRAPPER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/quic_packet_creator_peer.cc b/chromium/net/third_party/quiche/src/quic/test_tools/quic_packet_creator_peer.cc
deleted file mode 100644
index d638959f88b..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/quic_packet_creator_peer.cc
+++ /dev/null
@@ -1,166 +0,0 @@
-// Copyright (c) 2013 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 "quic/test_tools/quic_packet_creator_peer.h"
-
-#include "quic/core/frames/quic_frame.h"
-#include "quic/core/quic_packet_creator.h"
-#include "quic/core/quic_types.h"
-
-namespace quic {
-namespace test {
-
-// static
-bool QuicPacketCreatorPeer::SendVersionInPacket(QuicPacketCreator* creator) {
- return creator->IncludeVersionInHeader();
-}
-
-// static
-void QuicPacketCreatorPeer::SetSendVersionInPacket(
- QuicPacketCreator* creator,
- bool send_version_in_packet) {
- ParsedQuicVersion version = creator->framer_->version();
- if (!VersionHasIetfQuicFrames(version.transport_version) &&
- version.handshake_protocol != PROTOCOL_TLS1_3) {
- creator->send_version_in_packet_ = send_version_in_packet;
- return;
- }
- if (!send_version_in_packet) {
- creator->packet_.encryption_level = ENCRYPTION_FORWARD_SECURE;
- return;
- }
- QUICHE_DCHECK(creator->packet_.encryption_level < ENCRYPTION_FORWARD_SECURE);
-}
-
-// static
-void QuicPacketCreatorPeer::SetPacketNumberLength(
- QuicPacketCreator* creator,
- QuicPacketNumberLength packet_number_length) {
- creator->packet_.packet_number_length = packet_number_length;
-}
-
-// static
-QuicPacketNumberLength QuicPacketCreatorPeer::GetPacketNumberLength(
- QuicPacketCreator* creator) {
- return creator->GetPacketNumberLength();
-}
-
-// static
-QuicVariableLengthIntegerLength
-QuicPacketCreatorPeer::GetRetryTokenLengthLength(QuicPacketCreator* creator) {
- return creator->GetRetryTokenLengthLength();
-}
-
-// static
-QuicVariableLengthIntegerLength QuicPacketCreatorPeer::GetLengthLength(
- QuicPacketCreator* creator) {
- return creator->GetLengthLength();
-}
-
-void QuicPacketCreatorPeer::SetPacketNumber(QuicPacketCreator* creator,
- uint64_t s) {
- QUICHE_DCHECK_NE(0u, s);
- creator->packet_.packet_number = QuicPacketNumber(s);
-}
-
-void QuicPacketCreatorPeer::SetPacketNumber(QuicPacketCreator* creator,
- QuicPacketNumber num) {
- creator->packet_.packet_number = num;
-}
-
-// static
-void QuicPacketCreatorPeer::ClearPacketNumber(QuicPacketCreator* creator) {
- creator->packet_.packet_number.Clear();
-}
-
-// static
-void QuicPacketCreatorPeer::FillPacketHeader(QuicPacketCreator* creator,
- QuicPacketHeader* header) {
- creator->FillPacketHeader(header);
-}
-
-// static
-void QuicPacketCreatorPeer::CreateStreamFrame(QuicPacketCreator* creator,
- QuicStreamId id,
- size_t data_length,
- QuicStreamOffset offset,
- bool fin,
- QuicFrame* frame) {
- creator->CreateStreamFrame(id, data_length, offset, fin, frame);
-}
-
-// static
-bool QuicPacketCreatorPeer::CreateCryptoFrame(QuicPacketCreator* creator,
- EncryptionLevel level,
- size_t write_length,
- QuicStreamOffset offset,
- QuicFrame* frame) {
- return creator->CreateCryptoFrame(level, write_length, offset, frame);
-}
-
-// static
-SerializedPacket QuicPacketCreatorPeer::SerializeAllFrames(
- QuicPacketCreator* creator,
- const QuicFrames& frames,
- char* buffer,
- size_t buffer_len) {
- QUICHE_DCHECK(creator->queued_frames_.empty());
- QUICHE_DCHECK(!frames.empty());
- for (const QuicFrame& frame : frames) {
- bool success = creator->AddFrame(frame, NOT_RETRANSMISSION);
- QUICHE_DCHECK(success);
- }
- const bool success = creator->SerializePacket(
- QuicOwnedPacketBuffer(buffer, nullptr), buffer_len);
- QUICHE_DCHECK(success);
- SerializedPacket packet = std::move(creator->packet_);
- // The caller takes ownership of the QuicEncryptedPacket.
- creator->packet_.encrypted_buffer = nullptr;
- return packet;
-}
-
-// static
-std::unique_ptr<SerializedPacket>
-QuicPacketCreatorPeer::SerializeConnectivityProbingPacket(
- QuicPacketCreator* creator) {
- return creator->SerializeConnectivityProbingPacket();
-}
-
-// static
-std::unique_ptr<SerializedPacket>
-QuicPacketCreatorPeer::SerializePathChallengeConnectivityProbingPacket(
- QuicPacketCreator* creator,
- const QuicPathFrameBuffer& payload) {
- return creator->SerializePathChallengeConnectivityProbingPacket(payload);
-}
-
-// static
-EncryptionLevel QuicPacketCreatorPeer::GetEncryptionLevel(
- QuicPacketCreator* creator) {
- return creator->packet_.encryption_level;
-}
-
-// static
-QuicFramer* QuicPacketCreatorPeer::framer(QuicPacketCreator* creator) {
- return creator->framer_;
-}
-
-// static
-std::string QuicPacketCreatorPeer::GetRetryToken(QuicPacketCreator* creator) {
- return creator->retry_token_;
-}
-
-// static
-QuicFrames& QuicPacketCreatorPeer::QueuedFrames(QuicPacketCreator* creator) {
- return creator->queued_frames_;
-}
-
-// static
-void QuicPacketCreatorPeer::SetRandom(QuicPacketCreator* creator,
- QuicRandom* random) {
- creator->random_ = random;
-}
-
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/quic_packet_creator_peer.h b/chromium/net/third_party/quiche/src/quic/test_tools/quic_packet_creator_peer.h
deleted file mode 100644
index 259191d214b..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/quic_packet_creator_peer.h
+++ /dev/null
@@ -1,72 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_QUIC_PACKET_CREATOR_PEER_H_
-#define QUICHE_QUIC_TEST_TOOLS_QUIC_PACKET_CREATOR_PEER_H_
-
-#include "quic/core/quic_packets.h"
-
-namespace quic {
-class QuicFramer;
-class QuicPacketCreator;
-class QuicRandom;
-
-namespace test {
-
-class QuicPacketCreatorPeer {
- public:
- QuicPacketCreatorPeer() = delete;
-
- static bool SendVersionInPacket(QuicPacketCreator* creator);
-
- static void SetSendVersionInPacket(QuicPacketCreator* creator,
- bool send_version_in_packet);
- static void SetPacketNumberLength(
- QuicPacketCreator* creator,
- QuicPacketNumberLength packet_number_length);
- static QuicPacketNumberLength GetPacketNumberLength(
- QuicPacketCreator* creator);
- static QuicVariableLengthIntegerLength GetRetryTokenLengthLength(
- QuicPacketCreator* creator);
- static QuicVariableLengthIntegerLength GetLengthLength(
- QuicPacketCreator* creator);
- static void SetPacketNumber(QuicPacketCreator* creator, uint64_t s);
- static void SetPacketNumber(QuicPacketCreator* creator, QuicPacketNumber num);
- static void ClearPacketNumber(QuicPacketCreator* creator);
- static void FillPacketHeader(QuicPacketCreator* creator,
- QuicPacketHeader* header);
- static void CreateStreamFrame(QuicPacketCreator* creator,
- QuicStreamId id,
- size_t data_length,
- QuicStreamOffset offset,
- bool fin,
- QuicFrame* frame);
- static bool CreateCryptoFrame(QuicPacketCreator* creator,
- EncryptionLevel level,
- size_t write_length,
- QuicStreamOffset offset,
- QuicFrame* frame);
- static SerializedPacket SerializeAllFrames(QuicPacketCreator* creator,
- const QuicFrames& frames,
- char* buffer,
- size_t buffer_len);
- static std::unique_ptr<SerializedPacket> SerializeConnectivityProbingPacket(
- QuicPacketCreator* creator);
- static std::unique_ptr<SerializedPacket>
- SerializePathChallengeConnectivityProbingPacket(
- QuicPacketCreator* creator,
- const QuicPathFrameBuffer& payload);
-
- static EncryptionLevel GetEncryptionLevel(QuicPacketCreator* creator);
- static QuicFramer* framer(QuicPacketCreator* creator);
- static std::string GetRetryToken(QuicPacketCreator* creator);
- static QuicFrames& QueuedFrames(QuicPacketCreator* creator);
- static void SetRandom(QuicPacketCreator* creator, QuicRandom* random);
-};
-
-} // namespace test
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_TEST_TOOLS_QUIC_PACKET_CREATOR_PEER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/quic_path_validator_peer.cc b/chromium/net/third_party/quiche/src/quic/test_tools/quic_path_validator_peer.cc
deleted file mode 100644
index 901ca543436..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/quic_path_validator_peer.cc
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright (c) 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/quic_path_validator_peer.h"
-
-namespace quic {
-namespace test {
-// static
-QuicAlarm* QuicPathValidatorPeer::retry_timer(QuicPathValidator* validator) {
- return validator->retry_timer_.get();
-}
-
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/quic_path_validator_peer.h b/chromium/net/third_party/quiche/src/quic/test_tools/quic_path_validator_peer.h
deleted file mode 100644
index 2495cd373d5..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/quic_path_validator_peer.h
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright (c) 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_QUIC_PATH_VALIDATOR_PEER_H_
-#define QUICHE_QUIC_TEST_TOOLS_QUIC_PATH_VALIDATOR_PEER_H_
-
-#include "quic/core/quic_path_validator.h"
-
-namespace quic {
-namespace test {
-
-class QuicPathValidatorPeer {
- public:
- static QuicAlarm* retry_timer(QuicPathValidator* validator);
-};
-
-} // namespace test
-} // namespace quic
-#endif // QUICHE_QUIC_TEST_TOOLS_QUIC_PATH_VALIDATOR_PEER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/quic_sent_packet_manager_peer.cc b/chromium/net/third_party/quiche/src/quic/test_tools/quic_sent_packet_manager_peer.cc
deleted file mode 100644
index 8689535ecff..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/quic_sent_packet_manager_peer.cc
+++ /dev/null
@@ -1,224 +0,0 @@
-// Copyright 2013 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 "quic/test_tools/quic_sent_packet_manager_peer.h"
-
-#include "quic/core/congestion_control/loss_detection_interface.h"
-#include "quic/core/congestion_control/send_algorithm_interface.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_sent_packet_manager.h"
-#include "quic/test_tools/quic_unacked_packet_map_peer.h"
-
-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(
- QuicSentPacketManager* sent_packet_manager,
- Perspective perspective) {
- QuicUnackedPacketMapPeer::SetPerspective(
- &sent_packet_manager->unacked_packets_, perspective);
-}
-
-// static
-SendAlgorithmInterface* QuicSentPacketManagerPeer::GetSendAlgorithm(
- const QuicSentPacketManager& sent_packet_manager) {
- return sent_packet_manager.send_algorithm_.get();
-}
-
-// static
-void QuicSentPacketManagerPeer::SetSendAlgorithm(
- QuicSentPacketManager* sent_packet_manager,
- SendAlgorithmInterface* send_algorithm) {
- sent_packet_manager->SetSendAlgorithm(send_algorithm);
-}
-
-// static
-const LossDetectionInterface* QuicSentPacketManagerPeer::GetLossAlgorithm(
- QuicSentPacketManager* sent_packet_manager) {
- return sent_packet_manager->loss_algorithm_;
-}
-
-// static
-void QuicSentPacketManagerPeer::SetLossAlgorithm(
- QuicSentPacketManager* sent_packet_manager,
- LossDetectionInterface* loss_detector) {
- sent_packet_manager->loss_algorithm_ = loss_detector;
-}
-
-// static
-RttStats* QuicSentPacketManagerPeer::GetRttStats(
- QuicSentPacketManager* sent_packet_manager) {
- return &sent_packet_manager->rtt_stats_;
-}
-
-// static
-bool QuicSentPacketManagerPeer::IsRetransmission(
- QuicSentPacketManager* sent_packet_manager,
- uint64_t packet_number) {
- QUICHE_DCHECK(HasRetransmittableFrames(sent_packet_manager, packet_number));
- if (!HasRetransmittableFrames(sent_packet_manager, packet_number)) {
- return false;
- }
- return sent_packet_manager->unacked_packets_
- .GetTransmissionInfo(QuicPacketNumber(packet_number))
- .transmission_type != NOT_RETRANSMISSION;
-}
-
-// static
-void QuicSentPacketManagerPeer::MarkForRetransmission(
- QuicSentPacketManager* sent_packet_manager,
- uint64_t packet_number,
- TransmissionType transmission_type) {
- sent_packet_manager->MarkForRetransmission(QuicPacketNumber(packet_number),
- transmission_type);
-}
-
-// 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;
- for (auto it = sent_packet_manager->unacked_packets_.begin();
- it != sent_packet_manager->unacked_packets_.end(); ++it) {
- if (sent_packet_manager->unacked_packets_.HasRetransmittableFrames(*it)) {
- ++num_unacked_packets;
- }
- }
- return num_unacked_packets;
-}
-
-// static
-void QuicSentPacketManagerPeer::SetConsecutiveRtoCount(
- QuicSentPacketManager* sent_packet_manager,
- size_t count) {
- sent_packet_manager->consecutive_rto_count_ = count;
-}
-
-// static
-void QuicSentPacketManagerPeer::SetConsecutiveTlpCount(
- QuicSentPacketManager* sent_packet_manager,
- size_t count) {
- sent_packet_manager->consecutive_tlp_count_ = count;
-}
-
-// static
-QuicSustainedBandwidthRecorder& QuicSentPacketManagerPeer::GetBandwidthRecorder(
- QuicSentPacketManager* sent_packet_manager) {
- return sent_packet_manager->sustained_bandwidth_recorder_;
-}
-
-// static
-bool QuicSentPacketManagerPeer::UsingPacing(
- const QuicSentPacketManager* sent_packet_manager) {
- return sent_packet_manager->using_pacing_;
-}
-
-// static
-void QuicSentPacketManagerPeer::SetUsingPacing(
- QuicSentPacketManager* sent_packet_manager,
- bool using_pacing) {
- sent_packet_manager->using_pacing_ = using_pacing;
-}
-
-// static
-bool QuicSentPacketManagerPeer::HasRetransmittableFrames(
- QuicSentPacketManager* sent_packet_manager,
- uint64_t packet_number) {
- return sent_packet_manager->unacked_packets_.HasRetransmittableFrames(
- QuicPacketNumber(packet_number));
-}
-
-// static
-QuicUnackedPacketMap* QuicSentPacketManagerPeer::GetUnackedPacketMap(
- QuicSentPacketManager* sent_packet_manager) {
- return &sent_packet_manager->unacked_packets_;
-}
-
-// static
-void QuicSentPacketManagerPeer::DisablePacerBursts(
- QuicSentPacketManager* sent_packet_manager) {
- sent_packet_manager->pacing_sender_.burst_tokens_ = 0;
- sent_packet_manager->pacing_sender_.initial_burst_size_ = 0;
-}
-
-// static
-int QuicSentPacketManagerPeer::GetPacerInitialBurstSize(
- QuicSentPacketManager* sent_packet_manager) {
- return sent_packet_manager->pacing_sender_.initial_burst_size_;
-}
-
-// static
-void QuicSentPacketManagerPeer::SetNextPacedPacketTime(
- QuicSentPacketManager* sent_packet_manager,
- QuicTime time) {
- sent_packet_manager->pacing_sender_.ideal_next_packet_send_time_ = time;
-}
-
-// static
-int QuicSentPacketManagerPeer::GetReorderingShift(
- QuicSentPacketManager* sent_packet_manager) {
- return sent_packet_manager->uber_loss_algorithm_.general_loss_algorithms_[0]
- .reordering_shift();
-}
-
-// static
-bool QuicSentPacketManagerPeer::AdaptiveReorderingThresholdEnabled(
- QuicSentPacketManager* sent_packet_manager) {
- return sent_packet_manager->uber_loss_algorithm_.general_loss_algorithms_[0]
- .use_adaptive_reordering_threshold();
-}
-
-// static
-bool QuicSentPacketManagerPeer::AdaptiveTimeThresholdEnabled(
- QuicSentPacketManager* sent_packet_manager) {
- return sent_packet_manager->uber_loss_algorithm_.general_loss_algorithms_[0]
- .use_adaptive_time_threshold();
-}
-
-// static
-bool QuicSentPacketManagerPeer::UsePacketThresholdForRuntPackets(
- QuicSentPacketManager* sent_packet_manager) {
- return sent_packet_manager->uber_loss_algorithm_.general_loss_algorithms_[0]
- .use_packet_threshold_for_runt_packets();
-}
-
-// static
-int QuicSentPacketManagerPeer::GetNumPtosForPathDegrading(
- QuicSentPacketManager* sent_packet_manager) {
- return sent_packet_manager->num_ptos_for_path_degrading_;
-}
-
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/quic_sent_packet_manager_peer.h b/chromium/net/third_party/quiche/src/quic/test_tools/quic_sent_packet_manager_peer.h
deleted file mode 100644
index ef0af1e4654..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/quic_sent_packet_manager_peer.h
+++ /dev/null
@@ -1,110 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_QUIC_SENT_PACKET_MANAGER_PEER_H_
-#define QUICHE_QUIC_TEST_TOOLS_QUIC_SENT_PACKET_MANAGER_PEER_H_
-
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_sent_packet_manager.h"
-
-namespace quic {
-
-class SendAlgorithmInterface;
-
-namespace test {
-
-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);
-
- static SendAlgorithmInterface* GetSendAlgorithm(
- const QuicSentPacketManager& sent_packet_manager);
-
- static void SetSendAlgorithm(QuicSentPacketManager* sent_packet_manager,
- SendAlgorithmInterface* send_algorithm);
-
- static const LossDetectionInterface* GetLossAlgorithm(
- QuicSentPacketManager* sent_packet_manager);
-
- static void SetLossAlgorithm(QuicSentPacketManager* sent_packet_manager,
- LossDetectionInterface* loss_detector);
-
- static RttStats* GetRttStats(QuicSentPacketManager* sent_packet_manager);
-
- // Returns true if |packet_number| is a retransmission of a packet.
- static bool IsRetransmission(QuicSentPacketManager* sent_packet_manager,
- uint64_t packet_number);
-
- static void MarkForRetransmission(QuicSentPacketManager* sent_packet_manager,
- 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,
- size_t count);
-
- static QuicSustainedBandwidthRecorder& GetBandwidthRecorder(
- QuicSentPacketManager* sent_packet_manager);
-
- static void SetUsingPacing(QuicSentPacketManager* sent_packet_manager,
- bool using_pacing);
-
- static bool UsingPacing(const QuicSentPacketManager* sent_packet_manager);
-
- static bool HasRetransmittableFrames(
- QuicSentPacketManager* sent_packet_manager,
- uint64_t packet_number);
-
- static QuicUnackedPacketMap* GetUnackedPacketMap(
- QuicSentPacketManager* sent_packet_manager);
-
- static void DisablePacerBursts(QuicSentPacketManager* sent_packet_manager);
-
- static int GetPacerInitialBurstSize(
- QuicSentPacketManager* sent_packet_manager);
-
- static void SetNextPacedPacketTime(QuicSentPacketManager* sent_packet_manager,
- QuicTime time);
-
- static int GetReorderingShift(QuicSentPacketManager* sent_packet_manager);
-
- static bool AdaptiveReorderingThresholdEnabled(
- QuicSentPacketManager* sent_packet_manager);
-
- static bool AdaptiveTimeThresholdEnabled(
- QuicSentPacketManager* sent_packet_manager);
-
- static bool UsePacketThresholdForRuntPackets(
- QuicSentPacketManager* sent_packet_manager);
-
- static int GetNumPtosForPathDegrading(
- QuicSentPacketManager* sent_packet_manager);
-};
-
-} // namespace test
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_TEST_TOOLS_QUIC_SENT_PACKET_MANAGER_PEER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/quic_server_peer.cc b/chromium/net/third_party/quiche/src/quic/test_tools/quic_server_peer.cc
deleted file mode 100644
index 925f8516772..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/quic_server_peer.cc
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright 2013 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 "quic/test_tools/quic_server_peer.h"
-
-#include "quic/core/quic_dispatcher.h"
-#include "quic/core/quic_packet_reader.h"
-#include "quic/tools/quic_server.h"
-
-namespace quic {
-namespace test {
-
-// static
-bool QuicServerPeer::SetSmallSocket(QuicServer* server) {
- int size = 1024 * 10;
- return setsockopt(server->fd_, SOL_SOCKET, SO_RCVBUF, &size, sizeof(size)) !=
- -1;
-}
-
-// static
-QuicDispatcher* QuicServerPeer::GetDispatcher(QuicServer* server) {
- return server->dispatcher_.get();
-}
-
-// static
-void QuicServerPeer::SetReader(QuicServer* server, QuicPacketReader* reader) {
- server->packet_reader_.reset(reader);
-}
-
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/quic_server_peer.h b/chromium/net/third_party/quiche/src/quic/test_tools/quic_server_peer.h
deleted file mode 100644
index 29a36d45065..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/quic_server_peer.h
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_QUIC_SERVER_PEER_H_
-#define QUICHE_QUIC_TEST_TOOLS_QUIC_SERVER_PEER_H_
-
-namespace quic {
-
-class QuicDispatcher;
-class QuicServer;
-class QuicPacketReader;
-
-namespace test {
-
-class QuicServerPeer {
- public:
- QuicServerPeer() = delete;
-
- static bool SetSmallSocket(QuicServer* server);
- static QuicDispatcher* GetDispatcher(QuicServer* server);
- static void SetReader(QuicServer* server, QuicPacketReader* reader);
-};
-
-} // namespace test
-} // namespace quic
-
-#endif // QUICHE_QUIC_TEST_TOOLS_QUIC_SERVER_PEER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/quic_server_session_base_peer.h b/chromium/net/third_party/quiche/src/quic/test_tools/quic_server_session_base_peer.h
deleted file mode 100644
index d644c8224f5..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/quic_server_session_base_peer.h
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_QUIC_SERVER_SESSION_BASE_PEER_H_
-#define QUICHE_QUIC_TEST_TOOLS_QUIC_SERVER_SESSION_BASE_PEER_H_
-
-#include "quic/core/http/quic_server_session_base.h"
-
-#include "quic/core/quic_utils.h"
-
-namespace quic {
-namespace test {
-
-class QuicServerSessionBasePeer {
- public:
- static QuicStream* GetOrCreateStream(QuicServerSessionBase* s,
- QuicStreamId id) {
- return s->GetOrCreateStream(id);
- }
- static void SetCryptoStream(QuicServerSessionBase* s,
- QuicCryptoServerStreamBase* crypto_stream) {
- s->crypto_stream_.reset(crypto_stream);
- }
- static bool IsBandwidthResumptionEnabled(QuicServerSessionBase* s) {
- return s->bandwidth_resumption_enabled_;
- }
-};
-
-} // namespace test
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_TEST_TOOLS_QUIC_SERVER_SESSION_BASE_PEER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/quic_session_peer.cc b/chromium/net/third_party/quiche/src/quic/test_tools/quic_session_peer.cc
deleted file mode 100644
index e734a794aea..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/quic_session_peer.cc
+++ /dev/null
@@ -1,250 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/quic_session_peer.h"
-
-#include "absl/container/flat_hash_map.h"
-#include "quic/core/quic_session.h"
-#include "quic/core/quic_stream.h"
-#include "quic/core/quic_utils.h"
-
-namespace quic {
-namespace test {
-
-// static
-QuicStreamId QuicSessionPeer::GetNextOutgoingBidirectionalStreamId(
- QuicSession* session) {
- return session->GetNextOutgoingBidirectionalStreamId();
-}
-
-// static
-QuicStreamId QuicSessionPeer::GetNextOutgoingUnidirectionalStreamId(
- QuicSession* session) {
- return session->GetNextOutgoingUnidirectionalStreamId();
-}
-
-// static
-void QuicSessionPeer::SetNextOutgoingBidirectionalStreamId(QuicSession* session,
- QuicStreamId id) {
- if (VersionHasIetfQuicFrames(session->transport_version())) {
- session->ietf_streamid_manager_.bidirectional_stream_id_manager_
- .next_outgoing_stream_id_ = id;
- return;
- }
- session->stream_id_manager_.next_outgoing_stream_id_ = id;
-}
-
-// static
-void QuicSessionPeer::SetMaxOpenIncomingStreams(QuicSession* session,
- uint32_t max_streams) {
- if (VersionHasIetfQuicFrames(session->transport_version())) {
- QUIC_BUG(quic_bug_10193_1)
- << "SetmaxOpenIncomingStreams deprecated for IETF QUIC";
- session->ietf_streamid_manager_.SetMaxOpenIncomingUnidirectionalStreams(
- max_streams);
- session->ietf_streamid_manager_.SetMaxOpenIncomingBidirectionalStreams(
- max_streams);
- return;
- }
- session->stream_id_manager_.set_max_open_incoming_streams(max_streams);
-}
-
-// static
-void QuicSessionPeer::SetMaxOpenIncomingBidirectionalStreams(
- QuicSession* session,
- uint32_t max_streams) {
- QUICHE_DCHECK(VersionHasIetfQuicFrames(session->transport_version()))
- << "SetmaxOpenIncomingBidirectionalStreams not supported for Google "
- "QUIC";
- session->ietf_streamid_manager_.SetMaxOpenIncomingBidirectionalStreams(
- max_streams);
-}
-// static
-void QuicSessionPeer::SetMaxOpenIncomingUnidirectionalStreams(
- QuicSession* session,
- uint32_t max_streams) {
- QUICHE_DCHECK(VersionHasIetfQuicFrames(session->transport_version()))
- << "SetmaxOpenIncomingUnidirectionalStreams not supported for Google "
- "QUIC";
- session->ietf_streamid_manager_.SetMaxOpenIncomingUnidirectionalStreams(
- max_streams);
-}
-
-// static
-void QuicSessionPeer::SetMaxOpenOutgoingStreams(QuicSession* session,
- uint32_t max_streams) {
- if (VersionHasIetfQuicFrames(session->transport_version())) {
- QUIC_BUG(quic_bug_10193_2)
- << "SetmaxOpenOutgoingStreams deprecated for IETF QUIC";
- return;
- }
- session->stream_id_manager_.set_max_open_outgoing_streams(max_streams);
-}
-
-// static
-void QuicSessionPeer::SetMaxOpenOutgoingBidirectionalStreams(
- QuicSession* session,
- uint32_t max_streams) {
- QUICHE_DCHECK(VersionHasIetfQuicFrames(session->transport_version()))
- << "SetmaxOpenOutgoingBidirectionalStreams not supported for Google "
- "QUIC";
- session->ietf_streamid_manager_.MaybeAllowNewOutgoingBidirectionalStreams(
- max_streams);
-}
-// static
-void QuicSessionPeer::SetMaxOpenOutgoingUnidirectionalStreams(
- QuicSession* session,
- uint32_t max_streams) {
- QUICHE_DCHECK(VersionHasIetfQuicFrames(session->transport_version()))
- << "SetmaxOpenOutgoingUnidirectionalStreams not supported for Google "
- "QUIC";
- session->ietf_streamid_manager_.MaybeAllowNewOutgoingUnidirectionalStreams(
- max_streams);
-}
-
-// static
-QuicCryptoStream* QuicSessionPeer::GetMutableCryptoStream(
- QuicSession* session) {
- return session->GetMutableCryptoStream();
-}
-
-// static
-QuicWriteBlockedList* QuicSessionPeer::GetWriteBlockedStreams(
- QuicSession* session) {
- return &session->write_blocked_streams_;
-}
-
-// static
-QuicStream* QuicSessionPeer::GetOrCreateStream(QuicSession* session,
- QuicStreamId stream_id) {
- return session->GetOrCreateStream(stream_id);
-}
-
-// static
-absl::flat_hash_map<QuicStreamId, QuicStreamOffset>&
-QuicSessionPeer::GetLocallyClosedStreamsHighestOffset(QuicSession* session) {
- return session->locally_closed_streams_highest_offset_;
-}
-
-// static
-QuicSession::StreamMap& QuicSessionPeer::stream_map(QuicSession* session) {
- return session->stream_map_;
-}
-
-// static
-const QuicSession::ClosedStreams& QuicSessionPeer::closed_streams(
- QuicSession* session) {
- return *session->closed_streams();
-}
-
-// static
-void QuicSessionPeer::ActivateStream(QuicSession* session,
- std::unique_ptr<QuicStream> stream) {
- return session->ActivateStream(std::move(stream));
-}
-
-// static
-bool QuicSessionPeer::IsStreamClosed(QuicSession* session, QuicStreamId id) {
- return session->IsClosedStream(id);
-}
-
-// static
-bool QuicSessionPeer::IsStreamCreated(QuicSession* session, QuicStreamId id) {
- return session->stream_map_.contains(id);
-}
-
-// static
-bool QuicSessionPeer::IsStreamAvailable(QuicSession* session, QuicStreamId id) {
- if (VersionHasIetfQuicFrames(session->transport_version())) {
- if (id % QuicUtils::StreamIdDelta(session->transport_version()) < 2) {
- return session->ietf_streamid_manager_.bidirectional_stream_id_manager_
- .available_streams_.contains(id);
- }
- return session->ietf_streamid_manager_.unidirectional_stream_id_manager_
- .available_streams_.contains(id);
- }
- return session->stream_id_manager_.available_streams_.contains(id);
-}
-
-// static
-QuicStream* QuicSessionPeer::GetStream(QuicSession* session, QuicStreamId id) {
- return session->GetStream(id);
-}
-
-// static
-bool QuicSessionPeer::IsStreamWriteBlocked(QuicSession* session,
- QuicStreamId id) {
- return session->write_blocked_streams_.IsStreamBlocked(id);
-}
-
-// static
-QuicAlarm* QuicSessionPeer::GetCleanUpClosedStreamsAlarm(QuicSession* session) {
- return session->closed_streams_clean_up_alarm_.get();
-}
-
-// static
-LegacyQuicStreamIdManager* QuicSessionPeer::GetStreamIdManager(
- QuicSession* session) {
- return &session->stream_id_manager_;
-}
-
-// static
-UberQuicStreamIdManager* QuicSessionPeer::ietf_streamid_manager(
- QuicSession* session) {
- return &session->ietf_streamid_manager_;
-}
-
-// static
-QuicStreamIdManager* QuicSessionPeer::ietf_bidirectional_stream_id_manager(
- QuicSession* session) {
- return &session->ietf_streamid_manager_.bidirectional_stream_id_manager_;
-}
-
-// static
-QuicStreamIdManager* QuicSessionPeer::ietf_unidirectional_stream_id_manager(
- QuicSession* session) {
- return &session->ietf_streamid_manager_.unidirectional_stream_id_manager_;
-}
-
-// static
-PendingStream* QuicSessionPeer::GetPendingStream(QuicSession* session,
- QuicStreamId stream_id) {
- auto it = session->pending_stream_map_.find(stream_id);
- return it == session->pending_stream_map_.end() ? nullptr : it->second.get();
-}
-
-// static
-void QuicSessionPeer::set_is_configured(QuicSession* session, bool value) {
- session->is_configured_ = value;
-}
-
-// static
-void QuicSessionPeer::SetPerspective(QuicSession* session,
- Perspective perspective) {
- session->perspective_ = perspective;
-}
-
-// static
-size_t QuicSessionPeer::GetNumOpenDynamicStreams(QuicSession* session) {
- size_t result = 0;
- for (const auto& it : session->stream_map_) {
- if (!it.second->is_static()) {
- ++result;
- }
- }
- // Exclude draining streams.
- result -= session->num_draining_streams_;
- // Add locally closed streams.
- result += session->locally_closed_streams_highest_offset_.size();
-
- return result;
-}
-
-// static
-size_t QuicSessionPeer::GetNumDrainingStreams(QuicSession* session) {
- return session->num_draining_streams_;
-}
-
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/quic_session_peer.h b/chromium/net/third_party/quiche/src/quic/test_tools/quic_session_peer.h
deleted file mode 100644
index 94f0bf53799..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/quic_session_peer.h
+++ /dev/null
@@ -1,96 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_QUIC_SESSION_PEER_H_
-#define QUICHE_QUIC_TEST_TOOLS_QUIC_SESSION_PEER_H_
-
-#include <cstdint>
-#include <map>
-#include <memory>
-
-#include "absl/container/flat_hash_map.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_session.h"
-#include "quic/core/quic_write_blocked_list.h"
-#include "quic/platform/api/quic_containers.h"
-
-namespace quic {
-
-class QuicCryptoStream;
-class QuicSession;
-class QuicStream;
-
-namespace test {
-
-class QuicSessionPeer {
- public:
- QuicSessionPeer() = delete;
-
- static QuicStreamId GetNextOutgoingBidirectionalStreamId(
- QuicSession* session);
- static QuicStreamId GetNextOutgoingUnidirectionalStreamId(
- QuicSession* session);
- static void SetNextOutgoingBidirectionalStreamId(QuicSession* session,
- QuicStreamId id);
- // Following is only for Google-QUIC, will QUIC_BUG if called for IETF
- // QUIC.
- static void SetMaxOpenIncomingStreams(QuicSession* session,
- uint32_t max_streams);
- // Following two are only for IETF-QUIC, will QUIC_BUG if called for Google
- // QUIC.
- static void SetMaxOpenIncomingBidirectionalStreams(QuicSession* session,
- uint32_t max_streams);
- static void SetMaxOpenIncomingUnidirectionalStreams(QuicSession* session,
- uint32_t max_streams);
-
- static void SetMaxOpenOutgoingStreams(QuicSession* session,
- uint32_t max_streams);
- static void SetMaxOpenOutgoingBidirectionalStreams(QuicSession* session,
- uint32_t max_streams);
- static void SetMaxOpenOutgoingUnidirectionalStreams(QuicSession* session,
- uint32_t max_streams);
-
- static QuicCryptoStream* GetMutableCryptoStream(QuicSession* session);
- static QuicWriteBlockedList* GetWriteBlockedStreams(QuicSession* session);
- static QuicStream* GetOrCreateStream(QuicSession* session,
- QuicStreamId stream_id);
- static absl::flat_hash_map<QuicStreamId, QuicStreamOffset>&
- GetLocallyClosedStreamsHighestOffset(QuicSession* session);
- static QuicSession::StreamMap& stream_map(QuicSession* session);
- static const QuicSession::ClosedStreams& closed_streams(QuicSession* session);
- static void ActivateStream(QuicSession* session,
- std::unique_ptr<QuicStream> stream);
-
- // Discern the state of a stream. Exactly one of these should be true at a
- // time for any stream id > 0 (other than the special streams 1 and 3).
- static bool IsStreamClosed(QuicSession* session, QuicStreamId id);
- static bool IsStreamCreated(QuicSession* session, QuicStreamId id);
- static bool IsStreamAvailable(QuicSession* session, QuicStreamId id);
-
- static QuicStream* GetStream(QuicSession* session, QuicStreamId id);
- static bool IsStreamWriteBlocked(QuicSession* session, QuicStreamId id);
- static QuicAlarm* GetCleanUpClosedStreamsAlarm(QuicSession* session);
- static LegacyQuicStreamIdManager* GetStreamIdManager(QuicSession* session);
- static UberQuicStreamIdManager* ietf_streamid_manager(QuicSession* session);
- static QuicStreamIdManager* ietf_bidirectional_stream_id_manager(
- QuicSession* session);
- static QuicStreamIdManager* ietf_unidirectional_stream_id_manager(
- QuicSession* session);
- static PendingStream* GetPendingStream(QuicSession* session,
- QuicStreamId stream_id);
- static void set_is_configured(QuicSession* session, bool value);
- static void SetPerspective(QuicSession* session, Perspective perspective);
- static size_t GetNumOpenDynamicStreams(QuicSession* session);
- static size_t GetNumDrainingStreams(QuicSession* session);
- static QuicStreamId GetLargestPeerCreatedStreamId(QuicSession* session,
- bool unidirectional) {
- return session->GetLargestPeerCreatedStreamId(unidirectional);
- }
-};
-
-} // namespace test
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_TEST_TOOLS_QUIC_SESSION_PEER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/quic_spdy_session_peer.cc b/chromium/net/third_party/quiche/src/quic/test_tools/quic_spdy_session_peer.cc
deleted file mode 100644
index f0f99ee989e..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/quic_spdy_session_peer.cc
+++ /dev/null
@@ -1,118 +0,0 @@
-// Copyright (c) 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/quic_spdy_session_peer.h"
-
-#include "quic/core/http/quic_spdy_session.h"
-#include "quic/core/qpack/qpack_receive_stream.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/test_tools/quic_session_peer.h"
-#include "common/platform/api/quiche_logging.h"
-
-namespace quic {
-namespace test {
-
-// static
-QuicHeadersStream* QuicSpdySessionPeer::GetHeadersStream(
- QuicSpdySession* session) {
- QUICHE_DCHECK(!VersionUsesHttp3(session->transport_version()));
- return session->headers_stream();
-}
-
-void QuicSpdySessionPeer::SetHeadersStream(QuicSpdySession* session,
- QuicHeadersStream* headers_stream) {
- QUICHE_DCHECK(!VersionUsesHttp3(session->transport_version()));
- for (auto& it : QuicSessionPeer::stream_map(session)) {
- if (it.first ==
- QuicUtils::GetHeadersStreamId(session->transport_version())) {
- it.second.reset(headers_stream);
- session->headers_stream_ = static_cast<QuicHeadersStream*>(it.second.get());
- break;
- }
- }
-}
-
-// static
-spdy::SpdyFramer* QuicSpdySessionPeer::GetSpdyFramer(QuicSpdySession* session) {
- return &session->spdy_framer_;
-}
-
-void QuicSpdySessionPeer::SetMaxInboundHeaderListSize(
- QuicSpdySession* session, size_t max_inbound_header_size) {
- session->set_max_inbound_header_list_size(max_inbound_header_size);
-}
-
-// static
-size_t QuicSpdySessionPeer::WriteHeadersOnHeadersStream(
- QuicSpdySession* session, QuicStreamId id, spdy::SpdyHeaderBlock headers,
- bool fin, const spdy::SpdyStreamPrecedence& precedence,
- QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener) {
- return session->WriteHeadersOnHeadersStream(
- id, std::move(headers), fin, precedence, std::move(ack_listener));
-}
-
-// static
-QuicStreamId QuicSpdySessionPeer::GetNextOutgoingUnidirectionalStreamId(
- QuicSpdySession* session) {
- return session->GetNextOutgoingUnidirectionalStreamId();
-}
-
-// static
-QuicReceiveControlStream* QuicSpdySessionPeer::GetReceiveControlStream(
- QuicSpdySession* session) {
- return session->receive_control_stream_;
-}
-
-// static
-QuicSendControlStream* QuicSpdySessionPeer::GetSendControlStream(
- QuicSpdySession* session) {
- return session->send_control_stream_;
-}
-
-// static
-QpackSendStream* QuicSpdySessionPeer::GetQpackDecoderSendStream(
- QuicSpdySession* session) {
- return session->qpack_decoder_send_stream_;
-}
-
-// static
-QpackSendStream* QuicSpdySessionPeer::GetQpackEncoderSendStream(
- QuicSpdySession* session) {
- return session->qpack_encoder_send_stream_;
-}
-
-// static
-QpackReceiveStream* QuicSpdySessionPeer::GetQpackDecoderReceiveStream(
- QuicSpdySession* session) {
- return session->qpack_decoder_receive_stream_;
-}
-
-// static
-QpackReceiveStream* QuicSpdySessionPeer::GetQpackEncoderReceiveStream(
- QuicSpdySession* session) {
- return session->qpack_encoder_receive_stream_;
-}
-
-// static
-void QuicSpdySessionPeer::SetHttpDatagramSupport(
- QuicSpdySession* session, HttpDatagramSupport http_datagram_support) {
- session->http_datagram_support_ = http_datagram_support;
-}
-
-// static
-HttpDatagramSupport QuicSpdySessionPeer::LocalHttpDatagramSupport(
- QuicSpdySession* session) {
- return session->LocalHttpDatagramSupport();
-}
-
-// static
-void QuicSpdySessionPeer::EnableWebTransport(QuicSpdySession* session) {
- QUICHE_DCHECK(session->WillNegotiateWebTransport());
- SetHttpDatagramSupport(session, HttpDatagramSupport::kDraft04);
- session->peer_supports_webtransport_ = true;
-}
-
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/quic_spdy_session_peer.h b/chromium/net/third_party/quiche/src/quic/test_tools/quic_spdy_session_peer.h
deleted file mode 100644
index ba28e67c0ee..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/quic_spdy_session_peer.h
+++ /dev/null
@@ -1,60 +0,0 @@
-// Copyright (c) 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_QUIC_SPDY_SESSION_PEER_H_
-#define QUICHE_QUIC_TEST_TOOLS_QUIC_SPDY_SESSION_PEER_H_
-
-#include "quic/core/http/quic_receive_control_stream.h"
-#include "quic/core/http/quic_send_control_stream.h"
-#include "quic/core/http/quic_spdy_session.h"
-#include "quic/core/qpack/qpack_receive_stream.h"
-#include "quic/core/qpack/qpack_send_stream.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_write_blocked_list.h"
-#include "spdy/core/spdy_framer.h"
-
-namespace quic {
-
-class QuicHeadersStream;
-
-namespace test {
-
-class QuicSpdySessionPeer {
- public:
- QuicSpdySessionPeer() = delete;
-
- static QuicHeadersStream* GetHeadersStream(QuicSpdySession* session);
- static void SetHeadersStream(QuicSpdySession* session,
- QuicHeadersStream* headers_stream);
- static spdy::SpdyFramer* GetSpdyFramer(QuicSpdySession* session);
- // Must be called before Initialize().
- static void SetMaxInboundHeaderListSize(QuicSpdySession* session,
- size_t max_inbound_header_size);
- static size_t WriteHeadersOnHeadersStream(
- QuicSpdySession* session, QuicStreamId id, spdy::SpdyHeaderBlock headers,
- bool fin, const spdy::SpdyStreamPrecedence& precedence,
- QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener);
- // |session| can't be nullptr.
- static QuicStreamId GetNextOutgoingUnidirectionalStreamId(
- QuicSpdySession* session);
- static QuicReceiveControlStream* GetReceiveControlStream(
- QuicSpdySession* session);
- static QuicSendControlStream* GetSendControlStream(QuicSpdySession* session);
- static QpackSendStream* GetQpackDecoderSendStream(QuicSpdySession* session);
- static QpackSendStream* GetQpackEncoderSendStream(QuicSpdySession* session);
- static QpackReceiveStream* GetQpackDecoderReceiveStream(
- QuicSpdySession* session);
- static QpackReceiveStream* GetQpackEncoderReceiveStream(
- QuicSpdySession* session);
- static void SetHttpDatagramSupport(QuicSpdySession* session,
- HttpDatagramSupport http_datagram_support);
- static HttpDatagramSupport LocalHttpDatagramSupport(QuicSpdySession* session);
- static void EnableWebTransport(QuicSpdySession* session);
-};
-
-} // namespace test
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_TEST_TOOLS_QUIC_SPDY_SESSION_PEER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/quic_spdy_stream_peer.cc b/chromium/net/third_party/quiche/src/quic/test_tools/quic_spdy_stream_peer.cc
deleted file mode 100644
index ea21081d36c..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/quic_spdy_stream_peer.cc
+++ /dev/null
@@ -1,37 +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 "quic/test_tools/quic_spdy_stream_peer.h"
-
-#include "quic/core/http/quic_spdy_stream.h"
-#include "quic/test_tools/quic_test_utils.h"
-
-namespace quic {
-namespace test {
-
-// static
-void QuicSpdyStreamPeer::set_ack_listener(
- QuicSpdyStream* stream,
- QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener) {
- stream->set_ack_listener(std::move(ack_listener));
-}
-
-// static
-const QuicIntervalSet<QuicStreamOffset>&
-QuicSpdyStreamPeer::unacked_frame_headers_offsets(QuicSpdyStream* stream) {
- return stream->unacked_frame_headers_offsets_;
-}
-
-// static
-bool QuicSpdyStreamPeer::use_datagram_contexts(QuicSpdyStream* stream) {
- return stream->use_datagram_contexts_;
-}
-
-// static
-bool QuicSpdyStreamPeer::OnHeadersFrameEnd(QuicSpdyStream* stream) {
- return stream->OnHeadersFrameEnd();
-}
-
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/quic_spdy_stream_peer.h b/chromium/net/third_party/quiche/src/quic/test_tools/quic_spdy_stream_peer.h
deleted file mode 100644
index 692cbc38c20..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/quic_spdy_stream_peer.h
+++ /dev/null
@@ -1,34 +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_TEST_TOOLS_QUIC_SPDY_STREAM_PEER_H_
-#define QUICHE_QUIC_TEST_TOOLS_QUIC_SPDY_STREAM_PEER_H_
-
-#include "quic/core/quic_ack_listener_interface.h"
-#include "quic/core/quic_interval_set.h"
-#include "quic/platform/api/quic_containers.h"
-
-namespace quic {
-
-class QpackDecodedHeadersAccumulator;
-class QuicSpdyStream;
-
-namespace test {
-
-class QuicSpdyStreamPeer {
- public:
- static void set_ack_listener(
- QuicSpdyStream* stream,
- QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener);
- static const QuicIntervalSet<QuicStreamOffset>& unacked_frame_headers_offsets(
- QuicSpdyStream* stream);
- static bool use_datagram_contexts(QuicSpdyStream* stream);
- static bool OnHeadersFrameEnd(QuicSpdyStream* stream);
-};
-
-} // namespace test
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_TEST_TOOLS_QUIC_SPDY_STREAM_PEER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/quic_stream_id_manager_peer.cc b/chromium/net/third_party/quiche/src/quic/test_tools/quic_stream_id_manager_peer.cc
deleted file mode 100644
index c8662a1e969..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/quic_stream_id_manager_peer.cc
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-#include "quic/test_tools/quic_stream_id_manager_peer.h"
-
-#include "quic/core/quic_stream_id_manager.h"
-#include "quic/core/quic_utils.h"
-#include "quic/core/uber_quic_stream_id_manager.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-namespace test {
-
-// static
-void QuicStreamIdManagerPeer::set_incoming_actual_max_streams(
- QuicStreamIdManager* stream_id_manager,
- QuicStreamCount count) {
- stream_id_manager->incoming_actual_max_streams_ = count;
-}
-
-// static
-void QuicStreamIdManagerPeer::set_outgoing_max_streams(
- QuicStreamIdManager* stream_id_manager,
- QuicStreamCount count) {
- stream_id_manager->outgoing_max_streams_ = count;
-}
-
-// static
-QuicStreamId QuicStreamIdManagerPeer::GetFirstIncomingStreamId(
- QuicStreamIdManager* stream_id_manager) {
- return stream_id_manager->GetFirstIncomingStreamId();
-}
-
-// static
-bool QuicStreamIdManagerPeer::get_unidirectional(
- QuicStreamIdManager* stream_id_manager) {
- return stream_id_manager->unidirectional_;
-}
-
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/quic_stream_id_manager_peer.h b/chromium/net/third_party/quiche/src/quic/test_tools/quic_stream_id_manager_peer.h
deleted file mode 100644
index 7c7359f935e..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/quic_stream_id_manager_peer.h
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-#ifndef QUICHE_QUIC_TEST_TOOLS_QUIC_STREAM_ID_MANAGER_PEER_H_
-#define QUICHE_QUIC_TEST_TOOLS_QUIC_STREAM_ID_MANAGER_PEER_H_
-
-#include <stddef.h>
-
-#include "quic/core/quic_types.h"
-
-namespace quic {
-
-class QuicStreamIdManager;
-class UberQuicStreamIdManager;
-
-namespace test {
-
-class QuicStreamIdManagerPeer {
- public:
- QuicStreamIdManagerPeer() = delete;
-
- static void set_incoming_actual_max_streams(
- QuicStreamIdManager* stream_id_manager,
- QuicStreamCount count);
- static void set_outgoing_max_streams(QuicStreamIdManager* stream_id_manager,
- QuicStreamCount count);
-
- static QuicStreamId GetFirstIncomingStreamId(
- QuicStreamIdManager* stream_id_manager);
-
- static bool get_unidirectional(QuicStreamIdManager* stream_id_manager);
-};
-
-} // namespace test
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_TEST_TOOLS_QUIC_SESSION_PEER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/quic_stream_peer.cc b/chromium/net/third_party/quiche/src/quic/test_tools/quic_stream_peer.cc
deleted file mode 100644
index c596d79be45..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/quic_stream_peer.cc
+++ /dev/null
@@ -1,120 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/quic_stream_peer.h"
-
-#include <list>
-
-#include "quic/core/quic_stream.h"
-#include "quic/core/quic_types.h"
-#include "quic/test_tools/quic_flow_controller_peer.h"
-#include "quic/test_tools/quic_stream_send_buffer_peer.h"
-
-namespace quic {
-namespace test {
-
-// static
-void QuicStreamPeer::SetWriteSideClosed(bool value, QuicStream* stream) {
- stream->write_side_closed_ = value;
-}
-
-// static
-void QuicStreamPeer::SetStreamBytesWritten(
- QuicStreamOffset stream_bytes_written,
- QuicStream* stream) {
- stream->send_buffer_.stream_bytes_written_ = stream_bytes_written;
- stream->send_buffer_.stream_bytes_outstanding_ = stream_bytes_written;
- QuicStreamSendBufferPeer::SetStreamOffset(&stream->send_buffer_,
- stream_bytes_written);
-}
-
-// static
-void QuicStreamPeer::SetSendWindowOffset(QuicStream* stream,
- QuicStreamOffset offset) {
- QuicFlowControllerPeer::SetSendWindowOffset(&*stream->flow_controller_,
- offset);
-}
-
-// static
-QuicByteCount QuicStreamPeer::bytes_consumed(QuicStream* stream) {
- return stream->flow_controller_->bytes_consumed();
-}
-
-// static
-void QuicStreamPeer::SetReceiveWindowOffset(QuicStream* stream,
- QuicStreamOffset offset) {
- QuicFlowControllerPeer::SetReceiveWindowOffset(&*stream->flow_controller_,
- offset);
-}
-
-// static
-void QuicStreamPeer::SetMaxReceiveWindow(QuicStream* stream,
- QuicStreamOffset size) {
- QuicFlowControllerPeer::SetMaxReceiveWindow(&*stream->flow_controller_, size);
-}
-
-// static
-QuicByteCount QuicStreamPeer::SendWindowSize(QuicStream* stream) {
- return stream->flow_controller_->SendWindowSize();
-}
-
-// static
-QuicStreamOffset QuicStreamPeer::ReceiveWindowOffset(QuicStream* stream) {
- return QuicFlowControllerPeer::ReceiveWindowOffset(
- &*stream->flow_controller_);
-}
-
-// static
-QuicByteCount QuicStreamPeer::ReceiveWindowSize(QuicStream* stream) {
- return QuicFlowControllerPeer::ReceiveWindowSize(&*stream->flow_controller_);
-}
-
-// static
-QuicStreamOffset QuicStreamPeer::SendWindowOffset(QuicStream* stream) {
- return stream->flow_controller_->send_window_offset();
-}
-
-// static
-bool QuicStreamPeer::read_side_closed(QuicStream* stream) {
- return stream->read_side_closed_;
-}
-
-// static
-void QuicStreamPeer::CloseReadSide(QuicStream* stream) {
- stream->CloseReadSide();
-}
-
-// static
-bool QuicStreamPeer::StreamContributesToConnectionFlowControl(
- QuicStream* stream) {
- return stream->stream_contributes_to_connection_flow_control_;
-}
-
-// static
-QuicStreamSequencer* QuicStreamPeer::sequencer(QuicStream* stream) {
- return &(stream->sequencer_);
-}
-
-// static
-QuicSession* QuicStreamPeer::session(QuicStream* stream) {
- return stream->session();
-}
-
-// static
-QuicStreamSendBuffer& QuicStreamPeer::SendBuffer(QuicStream* stream) {
- return stream->send_buffer_;
-}
-
-// static
-void QuicStreamPeer::SetFinReceived(QuicStream* stream) {
- stream->fin_received_ = true;
-}
-
-// static
-void QuicStreamPeer::SetFinSent(QuicStream* stream) {
- stream->fin_sent_ = true;
-}
-
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/quic_stream_peer.h b/chromium/net/third_party/quiche/src/quic/test_tools/quic_stream_peer.h
deleted file mode 100644
index 963570cc6af..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/quic_stream_peer.h
+++ /dev/null
@@ -1,55 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_QUIC_STREAM_PEER_H_
-#define QUICHE_QUIC_TEST_TOOLS_QUIC_STREAM_PEER_H_
-
-#include <cstdint>
-
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_stream_send_buffer.h"
-#include "quic/core/quic_stream_sequencer.h"
-#include "quic/core/quic_types.h"
-
-namespace quic {
-
-class QuicStream;
-class QuicSession;
-
-namespace test {
-
-class QuicStreamPeer {
- public:
- QuicStreamPeer() = delete;
-
- static void SetWriteSideClosed(bool value, QuicStream* stream);
- static void SetStreamBytesWritten(QuicStreamOffset stream_bytes_written,
- QuicStream* stream);
- static void SetSendWindowOffset(QuicStream* stream, QuicStreamOffset offset);
- static void SetReceiveWindowOffset(QuicStream* stream,
- QuicStreamOffset offset);
- static void SetMaxReceiveWindow(QuicStream* stream, QuicStreamOffset size);
- static bool read_side_closed(QuicStream* stream);
- static void CloseReadSide(QuicStream* stream);
- static QuicByteCount bytes_consumed(QuicStream* stream);
- static QuicByteCount ReceiveWindowSize(QuicStream* stream);
- static QuicByteCount SendWindowSize(QuicStream* stream);
- static QuicStreamOffset SendWindowOffset(QuicStream* stream);
- static QuicStreamOffset ReceiveWindowOffset(QuicStream* stream);
-
- static bool StreamContributesToConnectionFlowControl(QuicStream* stream);
-
- static QuicStreamSequencer* sequencer(QuicStream* stream);
- static QuicSession* session(QuicStream* stream);
- static void SetFinReceived(QuicStream* stream);
- static void SetFinSent(QuicStream* stream);
-
- static QuicStreamSendBuffer& SendBuffer(QuicStream* stream);
-};
-
-} // namespace test
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_TEST_TOOLS_QUIC_STREAM_PEER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/quic_stream_send_buffer_peer.cc b/chromium/net/third_party/quiche/src/quic/test_tools/quic_stream_send_buffer_peer.cc
deleted file mode 100644
index 528ff16fe23..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/quic_stream_send_buffer_peer.cc
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/quic_stream_send_buffer_peer.h"
-#include "quic/test_tools/quic_interval_deque_peer.h"
-
-namespace quic {
-
-namespace test {
-
-// static
-void QuicStreamSendBufferPeer::SetStreamOffset(
- QuicStreamSendBuffer* send_buffer,
- QuicStreamOffset stream_offset) {
- send_buffer->stream_offset_ = stream_offset;
-}
-
-// static
-const BufferedSlice* QuicStreamSendBufferPeer::CurrentWriteSlice(
- QuicStreamSendBuffer* send_buffer) {
- auto wi = write_index(send_buffer);
-
- if (wi == -1) {
- return nullptr;
- }
- return QuicIntervalDequePeer::GetItem(&send_buffer->interval_deque_, wi);
-}
-
-QuicStreamOffset QuicStreamSendBufferPeer::EndOffset(
- QuicStreamSendBuffer* send_buffer) {
- return send_buffer->current_end_offset_;
-}
-
-// static
-QuicByteCount QuicStreamSendBufferPeer::TotalLength(
- QuicStreamSendBuffer* send_buffer) {
- QuicByteCount length = 0;
- for (auto slice = send_buffer->interval_deque_.DataBegin();
- slice != send_buffer->interval_deque_.DataEnd(); ++slice) {
- length += slice->slice.length();
- }
- return length;
-}
-
-// static
-int32_t QuicStreamSendBufferPeer::write_index(
- QuicStreamSendBuffer* send_buffer) {
- return QuicIntervalDequePeer::GetCachedIndex(&send_buffer->interval_deque_);
-}
-
-} // namespace test
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/quic_stream_send_buffer_peer.h b/chromium/net/third_party/quiche/src/quic/test_tools/quic_stream_send_buffer_peer.h
deleted file mode 100644
index 0f234c0df37..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/quic_stream_send_buffer_peer.h
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_QUIC_STREAM_SEND_BUFFER_PEER_H_
-#define QUICHE_QUIC_TEST_TOOLS_QUIC_STREAM_SEND_BUFFER_PEER_H_
-
-#include "quic/core/quic_stream_send_buffer.h"
-
-namespace quic {
-
-namespace test {
-
-class QuicStreamSendBufferPeer {
- public:
- static void SetStreamOffset(QuicStreamSendBuffer* send_buffer,
- QuicStreamOffset stream_offset);
-
- static const BufferedSlice* CurrentWriteSlice(
- QuicStreamSendBuffer* send_buffer);
-
- static QuicStreamOffset EndOffset(QuicStreamSendBuffer* send_buffer);
-
- static QuicByteCount TotalLength(QuicStreamSendBuffer* send_buffer);
-
- static int32_t write_index(QuicStreamSendBuffer* send_buffer);
-};
-
-} // namespace test
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_TEST_TOOLS_QUIC_STREAM_SEND_BUFFER_PEER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/quic_stream_sequencer_buffer_peer.cc b/chromium/net/third_party/quiche/src/quic/test_tools/quic_stream_sequencer_buffer_peer.cc
deleted file mode 100644
index a950f0ba323..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/quic_stream_sequencer_buffer_peer.cc
+++ /dev/null
@@ -1,162 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/quic_stream_sequencer_buffer_peer.h"
-#include <cstddef>
-
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/quic_test_utils.h"
-
-using BufferBlock = quic::QuicStreamSequencerBuffer::BufferBlock;
-
-static const size_t kBlockSizeBytes =
- quic::QuicStreamSequencerBuffer::kBlockSizeBytes;
-
-namespace quic {
-namespace test {
-
-QuicStreamSequencerBufferPeer::QuicStreamSequencerBufferPeer(
- QuicStreamSequencerBuffer* buffer)
- : buffer_(buffer) {}
-
-// Read from this buffer_ into the given destination buffer_ up to the
-// size of the destination. Returns the number of bytes read. Reading from
-// an empty buffer_->returns 0.
-size_t QuicStreamSequencerBufferPeer::Read(char* dest_buffer, size_t size) {
- iovec dest;
- dest.iov_base = dest_buffer, dest.iov_len = size;
- size_t bytes_read;
- std::string error_details;
- EXPECT_THAT(buffer_->Readv(&dest, 1, &bytes_read, &error_details),
- IsQuicNoError());
- return bytes_read;
-}
-
-// If buffer is empty, the blocks_ array must be empty, which means all
-// blocks are deallocated.
-bool QuicStreamSequencerBufferPeer::CheckEmptyInvariants() {
- return !buffer_->Empty() || IsBlockArrayEmpty();
-}
-
-bool QuicStreamSequencerBufferPeer::IsBlockArrayEmpty() {
- if (buffer_->blocks_ == nullptr) {
- return true;
- }
-
- size_t count = current_blocks_count();
- for (size_t i = 0; i < count; i++) {
- if (buffer_->blocks_[i] != nullptr) {
- return false;
- }
- }
- return true;
-}
-
-bool QuicStreamSequencerBufferPeer::CheckInitialState() {
- EXPECT_TRUE(buffer_->Empty() && buffer_->total_bytes_read_ == 0 &&
- buffer_->num_bytes_buffered_ == 0);
- return CheckBufferInvariants();
-}
-
-bool QuicStreamSequencerBufferPeer::CheckBufferInvariants() {
- QuicStreamOffset data_span =
- buffer_->NextExpectedByte() - buffer_->total_bytes_read_;
- bool capacity_sane = data_span <= buffer_->max_buffer_capacity_bytes_ &&
- data_span >= buffer_->num_bytes_buffered_;
- if (!capacity_sane) {
- QUIC_LOG(ERROR) << "data span is larger than capacity.";
- QUIC_LOG(ERROR) << "total read: " << buffer_->total_bytes_read_
- << " last byte: " << buffer_->NextExpectedByte();
- }
- bool total_read_sane =
- buffer_->FirstMissingByte() >= buffer_->total_bytes_read_;
- if (!total_read_sane) {
- QUIC_LOG(ERROR) << "read across 1st gap.";
- }
- bool read_offset_sane = buffer_->ReadOffset() < kBlockSizeBytes;
- if (!capacity_sane) {
- QUIC_LOG(ERROR) << "read offset go beyond 1st block";
- }
- bool block_match_capacity =
- (buffer_->max_buffer_capacity_bytes_ <=
- buffer_->max_blocks_count_ * kBlockSizeBytes) &&
- (buffer_->max_buffer_capacity_bytes_ >
- (buffer_->max_blocks_count_ - 1) * kBlockSizeBytes);
- if (!capacity_sane) {
- QUIC_LOG(ERROR) << "block number not match capcaity.";
- }
- bool block_retired_when_empty = CheckEmptyInvariants();
- if (!block_retired_when_empty) {
- QUIC_LOG(ERROR) << "block is not retired after use.";
- }
- return capacity_sane && total_read_sane && read_offset_sane &&
- block_match_capacity && block_retired_when_empty;
-}
-
-size_t QuicStreamSequencerBufferPeer::GetInBlockOffset(
- QuicStreamOffset offset) {
- return buffer_->GetInBlockOffset(offset);
-}
-
-BufferBlock* QuicStreamSequencerBufferPeer::GetBlock(size_t index) {
- return buffer_->blocks_[index];
-}
-
-int QuicStreamSequencerBufferPeer::IntervalSize() {
- if (buffer_->bytes_received_.Empty()) {
- return 1;
- }
- int gap_size = buffer_->bytes_received_.Size() + 1;
- if (buffer_->bytes_received_.Empty()) {
- return gap_size;
- }
- if (buffer_->bytes_received_.begin()->min() == 0) {
- --gap_size;
- }
- if (buffer_->bytes_received_.rbegin()->max() ==
- std::numeric_limits<uint64_t>::max()) {
- --gap_size;
- }
- return gap_size;
-}
-
-size_t QuicStreamSequencerBufferPeer::max_buffer_capacity() {
- return buffer_->max_buffer_capacity_bytes_;
-}
-
-size_t QuicStreamSequencerBufferPeer::ReadableBytes() {
- return buffer_->ReadableBytes();
-}
-
-void QuicStreamSequencerBufferPeer::set_total_bytes_read(
- QuicStreamOffset total_bytes_read) {
- buffer_->total_bytes_read_ = total_bytes_read;
-}
-
-void QuicStreamSequencerBufferPeer::AddBytesReceived(QuicStreamOffset offset,
- QuicByteCount length) {
- buffer_->bytes_received_.Add(offset, offset + length);
-}
-
-bool QuicStreamSequencerBufferPeer::IsBufferAllocated() {
- return buffer_->blocks_ != nullptr;
-}
-
-size_t QuicStreamSequencerBufferPeer::max_blocks_count() {
- return buffer_->max_blocks_count_;
-}
-
-size_t QuicStreamSequencerBufferPeer::current_blocks_count() {
- return buffer_->current_blocks_count_;
-}
-
-const QuicIntervalSet<QuicStreamOffset>&
-QuicStreamSequencerBufferPeer::bytes_received() {
- return buffer_->bytes_received_;
-}
-
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/quic_stream_sequencer_buffer_peer.h b/chromium/net/third_party/quiche/src/quic/test_tools/quic_stream_sequencer_buffer_peer.h
deleted file mode 100644
index b07f1f50bd5..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/quic_stream_sequencer_buffer_peer.h
+++ /dev/null
@@ -1,65 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_QUIC_STREAM_SEQUENCER_BUFFER_PEER_H_
-#define QUICHE_QUIC_TEST_TOOLS_QUIC_STREAM_SEQUENCER_BUFFER_PEER_H_
-
-#include "quic/core/quic_stream_sequencer_buffer.h"
-
-namespace quic {
-
-namespace test {
-
-class QuicStreamSequencerBufferPeer {
- public:
- explicit QuicStreamSequencerBufferPeer(QuicStreamSequencerBuffer* buffer);
- QuicStreamSequencerBufferPeer(const QuicStreamSequencerBufferPeer&) = delete;
- QuicStreamSequencerBufferPeer& operator=(
- const QuicStreamSequencerBufferPeer&) = delete;
-
- // Read from this buffer_ into the given destination buffer_ up to the
- // size of the destination. Returns the number of bytes read. Reading from
- // an empty buffer_->returns 0.
- size_t Read(char* dest_buffer, size_t size);
-
- // If buffer is empty, the blocks_ array must be empty, which means all
- // blocks are deallocated.
- bool CheckEmptyInvariants();
-
- bool IsBlockArrayEmpty();
-
- bool CheckInitialState();
-
- bool CheckBufferInvariants();
-
- size_t GetInBlockOffset(QuicStreamOffset offset);
-
- QuicStreamSequencerBuffer::BufferBlock* GetBlock(size_t index);
-
- int IntervalSize();
-
- size_t max_buffer_capacity();
-
- size_t ReadableBytes();
-
- void set_total_bytes_read(QuicStreamOffset total_bytes_read);
-
- void AddBytesReceived(QuicStreamOffset offset, QuicByteCount length);
-
- bool IsBufferAllocated();
-
- size_t max_blocks_count();
-
- size_t current_blocks_count();
-
- const QuicIntervalSet<QuicStreamOffset>& bytes_received();
-
- private:
- QuicStreamSequencerBuffer* buffer_;
-};
-
-} // namespace test
-} // namespace quic
-
-#endif // QUICHE_QUIC_TEST_TOOLS_QUIC_STREAM_SEQUENCER_BUFFER_PEER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/quic_stream_sequencer_peer.cc b/chromium/net/third_party/quiche/src/quic/test_tools/quic_stream_sequencer_peer.cc
deleted file mode 100644
index 497b290c453..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/quic_stream_sequencer_peer.cc
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/quic_stream_sequencer_peer.h"
-
-#include "quic/core/quic_stream_sequencer.h"
-#include "quic/test_tools/quic_stream_sequencer_buffer_peer.h"
-
-namespace quic {
-namespace test {
-
-// static
-size_t QuicStreamSequencerPeer::GetNumBufferedBytes(
- QuicStreamSequencer* sequencer) {
- return sequencer->buffered_frames_.BytesBuffered();
-}
-
-// static
-QuicStreamOffset QuicStreamSequencerPeer::GetCloseOffset(
- QuicStreamSequencer* sequencer) {
- return sequencer->close_offset_;
-}
-
-// static
-bool QuicStreamSequencerPeer::IsUnderlyingBufferAllocated(
- QuicStreamSequencer* sequencer) {
- QuicStreamSequencerBufferPeer buffer_peer(&(sequencer->buffered_frames_));
- return buffer_peer.IsBufferAllocated();
-}
-
-// static
-void QuicStreamSequencerPeer::SetFrameBufferTotalBytesRead(
- QuicStreamSequencer* sequencer,
- QuicStreamOffset total_bytes_read) {
- QuicStreamSequencerBufferPeer buffer_peer(&(sequencer->buffered_frames_));
- buffer_peer.set_total_bytes_read(total_bytes_read);
-}
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/quic_stream_sequencer_peer.h b/chromium/net/third_party/quiche/src/quic/test_tools/quic_stream_sequencer_peer.h
deleted file mode 100644
index c36b77fd59a..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/quic_stream_sequencer_peer.h
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_QUIC_STREAM_SEQUENCER_PEER_H_
-#define QUICHE_QUIC_TEST_TOOLS_QUIC_STREAM_SEQUENCER_PEER_H_
-
-#include "quic/core/quic_packets.h"
-
-namespace quic {
-
-class QuicStreamSequencer;
-
-namespace test {
-
-class QuicStreamSequencerPeer {
- public:
- QuicStreamSequencerPeer() = delete;
-
- static size_t GetNumBufferedBytes(QuicStreamSequencer* sequencer);
-
- static QuicStreamOffset GetCloseOffset(QuicStreamSequencer* sequencer);
-
- static bool IsUnderlyingBufferAllocated(QuicStreamSequencer* sequencer);
-
- static void SetFrameBufferTotalBytesRead(QuicStreamSequencer* sequencer,
- QuicStreamOffset total_bytes_read);
-};
-
-} // namespace test
-} // namespace quic
-
-#endif // QUICHE_QUIC_TEST_TOOLS_QUIC_STREAM_SEQUENCER_PEER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/quic_sustained_bandwidth_recorder_peer.cc b/chromium/net/third_party/quiche/src/quic/test_tools/quic_sustained_bandwidth_recorder_peer.cc
deleted file mode 100644
index 86206c64b48..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/quic_sustained_bandwidth_recorder_peer.cc
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/quic_sustained_bandwidth_recorder_peer.h"
-
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_sustained_bandwidth_recorder.h"
-
-namespace quic {
-namespace test {
-
-// static
-void QuicSustainedBandwidthRecorderPeer::SetBandwidthEstimate(
- QuicSustainedBandwidthRecorder* bandwidth_recorder,
- int32_t bandwidth_estimate_kbytes_per_second) {
- bandwidth_recorder->has_estimate_ = true;
- bandwidth_recorder->bandwidth_estimate_ =
- QuicBandwidth::FromKBytesPerSecond(bandwidth_estimate_kbytes_per_second);
-}
-
-// static
-void QuicSustainedBandwidthRecorderPeer::SetMaxBandwidthEstimate(
- QuicSustainedBandwidthRecorder* bandwidth_recorder,
- int32_t max_bandwidth_estimate_kbytes_per_second,
- int32_t max_bandwidth_timestamp) {
- bandwidth_recorder->max_bandwidth_estimate_ =
- QuicBandwidth::FromKBytesPerSecond(
- max_bandwidth_estimate_kbytes_per_second);
- bandwidth_recorder->max_bandwidth_timestamp_ = max_bandwidth_timestamp;
-}
-
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/quic_sustained_bandwidth_recorder_peer.h b/chromium/net/third_party/quiche/src/quic/test_tools/quic_sustained_bandwidth_recorder_peer.h
deleted file mode 100644
index e1280353b61..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/quic_sustained_bandwidth_recorder_peer.h
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_QUIC_SUSTAINED_BANDWIDTH_RECORDER_PEER_H_
-#define QUICHE_QUIC_TEST_TOOLS_QUIC_SUSTAINED_BANDWIDTH_RECORDER_PEER_H_
-
-#include <cstdint>
-
-#include "quic/core/quic_packets.h"
-
-namespace quic {
-
-class QuicSustainedBandwidthRecorder;
-
-namespace test {
-
-class QuicSustainedBandwidthRecorderPeer {
- public:
- QuicSustainedBandwidthRecorderPeer() = delete;
-
- static void SetBandwidthEstimate(
- QuicSustainedBandwidthRecorder* bandwidth_recorder,
- int32_t bandwidth_estimate_kbytes_per_second);
-
- static void SetMaxBandwidthEstimate(
- QuicSustainedBandwidthRecorder* bandwidth_recorder,
- int32_t max_bandwidth_estimate_kbytes_per_second,
- int32_t max_bandwidth_timestamp);
-};
-
-} // namespace test
-} // namespace quic
-
-#endif // QUICHE_QUIC_TEST_TOOLS_QUIC_SUSTAINED_BANDWIDTH_RECORDER_PEER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/quic_test_backend.cc b/chromium/net/third_party/quiche/src/quic/test_tools/quic_test_backend.cc
deleted file mode 100644
index 3cfe9279a3a..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/quic_test_backend.cc
+++ /dev/null
@@ -1,123 +0,0 @@
-// Copyright (c) 2021 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 "quic/test_tools/quic_test_backend.h"
-
-#include <cstring>
-#include <memory>
-
-#include "absl/strings/str_cat.h"
-#include "absl/strings/str_split.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_buffer_allocator.h"
-#include "quic/core/quic_simple_buffer_allocator.h"
-#include "quic/core/web_transport_interface.h"
-#include "quic/platform/api/quic_mem_slice.h"
-#include "quic/test_tools/web_transport_resets_backend.h"
-#include "quic/tools/web_transport_test_visitors.h"
-
-namespace quic {
-namespace test {
-
-namespace {
-
-// SessionCloseVisitor implements the "/session-close" endpoint. If the client
-// sends a unidirectional stream of format "code message" to this endpoint, it
-// will close the session with the corresponding error code and error message.
-// For instance, sending "42 test error" will cause it to be closed with code 42
-// and message "test error".
-class SessionCloseVisitor : public WebTransportVisitor {
- public:
- SessionCloseVisitor(WebTransportSession* session) : session_(session) {}
-
- void OnSessionReady(const spdy::SpdyHeaderBlock& /*headers*/) override {}
- void OnSessionClosed(WebTransportSessionError /*error_code*/,
- const std::string& /*error_message*/) override {}
-
- void OnIncomingBidirectionalStreamAvailable() override {}
- void OnIncomingUnidirectionalStreamAvailable() override {
- WebTransportStream* stream = session_->AcceptIncomingUnidirectionalStream();
- if (stream == nullptr) {
- return;
- }
- stream->SetVisitor(
- std::make_unique<WebTransportUnidirectionalEchoReadVisitor>(
- stream, [this](const std::string& data) {
- std::pair<absl::string_view, absl::string_view> parsed =
- absl::StrSplit(data, absl::MaxSplits(' ', 1));
- WebTransportSessionError error_code = 0;
- bool success = absl::SimpleAtoi(parsed.first, &error_code);
- QUICHE_DCHECK(success) << data;
- session_->CloseSession(error_code, parsed.second);
- }));
- stream->visitor()->OnCanRead();
- }
-
- void OnDatagramReceived(absl::string_view /*datagram*/) override {}
-
- void OnCanCreateNewOutgoingBidirectionalStream() override {}
- void OnCanCreateNewOutgoingUnidirectionalStream() override {}
-
- private:
- WebTransportSession* session_; // Not owned.
-};
-
-} // namespace
-
-QuicSimpleServerBackend::WebTransportResponse
-QuicTestBackend::ProcessWebTransportRequest(
- const spdy::Http2HeaderBlock& request_headers,
- WebTransportSession* session) {
- if (!SupportsWebTransport()) {
- return QuicSimpleServerBackend::ProcessWebTransportRequest(request_headers,
- session);
- }
-
- auto path_it = request_headers.find(":path");
- if (path_it == request_headers.end()) {
- WebTransportResponse response;
- response.response_headers[":status"] = "400";
- return response;
- }
- absl::string_view path = path_it->second;
- // Match any "/echo.*" pass, e.g. "/echo_foobar"
- if (absl::StartsWith(path, "/echo")) {
- WebTransportResponse response;
- response.response_headers[":status"] = "200";
- // Add response headers if the paramer has "set-header=XXX:YYY" query.
- GURL url = GURL(absl::StrCat("https://localhost", path));
- const std::vector<std::string>& params = absl::StrSplit(url.query(), '&');
- for (const auto& param : params) {
- absl::string_view param_view = param;
- if (absl::ConsumePrefix(&param_view, "set-header=")) {
- const std::vector<absl::string_view> header_value =
- absl::StrSplit(param_view, ':');
- if (header_value.size() == 2 &&
- !absl::StartsWith(header_value[0], ":")) {
- response.response_headers[header_value[0]] = header_value[1];
- }
- }
- }
-
- response.visitor =
- std::make_unique<EchoWebTransportSessionVisitor>(session);
- return response;
- }
- if (path == "/resets") {
- return WebTransportResetsBackend(request_headers, session);
- }
- if (path == "/session-close") {
- WebTransportResponse response;
- response.response_headers[":status"] = "200";
- response.visitor = std::make_unique<SessionCloseVisitor>(session);
- return response;
- }
-
- WebTransportResponse response;
- response.response_headers[":status"] = "404";
- return response;
-}
-
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/quic_test_backend.h b/chromium/net/third_party/quiche/src/quic/test_tools/quic_test_backend.h
deleted file mode 100644
index b0c0ce2e0a7..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/quic_test_backend.h
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright (c) 2021 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_QUIC_TEST_BACKEND_H_
-#define QUICHE_QUIC_TEST_TOOLS_QUIC_TEST_BACKEND_H_
-
-#include "quic/tools/quic_memory_cache_backend.h"
-#include "common/platform/api/quiche_logging.h"
-
-namespace quic {
-namespace test {
-
-// QuicTestBackend is a QuicSimpleServer backend usable in tests. It has extra
-// WebTransport endpoints on top of what QuicMemoryCacheBackend already
-// provides.
-class QuicTestBackend : public QuicMemoryCacheBackend {
- public:
- WebTransportResponse ProcessWebTransportRequest(
- const spdy::Http2HeaderBlock& request_headers,
- WebTransportSession* session) override;
- bool SupportsWebTransport() override { return enable_webtransport_; }
-
- void set_enable_webtransport(bool enable_webtransport) {
- QUICHE_DCHECK(!enable_webtransport || enable_extended_connect_);
- 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) {
- enable_extended_connect_ = enable_extended_connect;
- }
-
- private:
- bool enable_webtransport_ = false;
- bool use_datagram_contexts_ = false;
- bool enable_extended_connect_ = true;
-};
-
-} // namespace test
-} // namespace quic
-
-#endif // QUICHE_QUIC_TEST_TOOLS_QUIC_TEST_BACKEND_H_
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/quic_test_client.cc b/chromium/net/third_party/quiche/src/quic/test_tools/quic_test_client.cc
deleted file mode 100644
index 02d890fac9e..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/quic_test_client.cc
+++ /dev/null
@@ -1,1012 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/quic_test_client.h"
-
-#include <memory>
-#include <utility>
-#include <vector>
-
-#include "absl/strings/match.h"
-#include "absl/strings/string_view.h"
-#include "third_party/boringssl/src/include/openssl/x509.h"
-#include "quic/core/crypto/proof_verifier.h"
-#include "quic/core/http/quic_spdy_client_stream.h"
-#include "quic/core/http/spdy_utils.h"
-#include "quic/core/quic_epoll_connection_helper.h"
-#include "quic/core/quic_packet_writer_wrapper.h"
-#include "quic/core/quic_server_id.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/platform/api/quic_stack_trace.h"
-#include "quic/test_tools/crypto_test_utils.h"
-#include "quic/test_tools/quic_client_peer.h"
-#include "quic/test_tools/quic_connection_peer.h"
-#include "quic/test_tools/quic_spdy_session_peer.h"
-#include "quic/test_tools/quic_spdy_stream_peer.h"
-#include "quic/test_tools/quic_test_utils.h"
-#include "quic/tools/quic_url.h"
-#include "common/quiche_text_utils.h"
-
-namespace quic {
-namespace test {
-namespace {
-
-// RecordingProofVerifier accepts any certificate chain and records the common
-// name of the leaf and then delegates the actual verification to an actual
-// verifier. If no optional verifier is provided, then VerifyProof will return
-// success.
-class RecordingProofVerifier : public ProofVerifier {
- public:
- explicit RecordingProofVerifier(std::unique_ptr<ProofVerifier> verifier)
- : verifier_(std::move(verifier)) {}
-
- // ProofVerifier interface.
- 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 {
- QuicAsyncStatus process_certs_result = ProcessCerts(certs, cert_sct);
- if (process_certs_result != QUIC_SUCCESS) {
- return process_certs_result;
- }
-
- if (!verifier_) {
- return QUIC_SUCCESS;
- }
-
- return verifier_->VerifyProof(hostname, port, server_config,
- transport_version, chlo_hash, certs, cert_sct,
- signature, context, error_details, details,
- 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 {
- return ProcessCerts(certs, cert_sct);
- }
-
- std::unique_ptr<ProofVerifyContext> CreateDefaultContext() override {
- return verifier_ != nullptr ? verifier_->CreateDefaultContext() : nullptr;
- }
-
- const std::string& common_name() const { return common_name_; }
-
- const std::string& cert_sct() const { return cert_sct_; }
-
- private:
- QuicAsyncStatus ProcessCerts(const std::vector<std::string>& certs,
- const std::string& cert_sct) {
- common_name_.clear();
- if (certs.empty()) {
- return QUIC_FAILURE;
- }
-
- // Parse the cert into an X509 structure.
- const uint8_t* data;
- data = reinterpret_cast<const uint8_t*>(certs[0].data());
- bssl::UniquePtr<X509> cert(d2i_X509(nullptr, &data, certs[0].size()));
- if (!cert.get()) {
- return QUIC_FAILURE;
- }
-
- // Extract the CN field
- X509_NAME* subject = X509_get_subject_name(cert.get());
- const int index = X509_NAME_get_index_by_NID(subject, NID_commonName, -1);
- if (index < 0) {
- return QUIC_FAILURE;
- }
- ASN1_STRING* name_data =
- X509_NAME_ENTRY_get_data(X509_NAME_get_entry(subject, index));
- if (name_data == nullptr) {
- return QUIC_FAILURE;
- }
-
- // Convert the CN to UTF8, in case the cert represents it in a different
- // format.
- unsigned char* buf = nullptr;
- const int len = ASN1_STRING_to_UTF8(&buf, name_data);
- if (len <= 0) {
- return QUIC_FAILURE;
- }
- bssl::UniquePtr<unsigned char> deleter(buf);
-
- common_name_.assign(reinterpret_cast<const char*>(buf), len);
- cert_sct_ = cert_sct;
- return QUIC_SUCCESS;
- }
-
- std::unique_ptr<ProofVerifier> verifier_;
- std::string common_name_;
- std::string cert_sct_;
-};
-} // namespace
-
-class MockableQuicClientEpollNetworkHelper
- : public QuicClientEpollNetworkHelper {
- public:
- using QuicClientEpollNetworkHelper::QuicClientEpollNetworkHelper;
- ~MockableQuicClientEpollNetworkHelper() override = default;
-
- void ProcessPacket(const QuicSocketAddress& self_address,
- const QuicSocketAddress& peer_address,
- const QuicReceivedPacket& packet) override {
- QuicClientEpollNetworkHelper::ProcessPacket(self_address, peer_address,
- packet);
- if (track_last_incoming_packet_) {
- last_incoming_packet_ = packet.Clone();
- }
- }
-
- QuicPacketWriter* CreateQuicPacketWriter() override {
- QuicPacketWriter* writer =
- QuicClientEpollNetworkHelper::CreateQuicPacketWriter();
- if (!test_writer_) {
- return writer;
- }
- test_writer_->set_writer(writer);
- return test_writer_;
- }
-
- const QuicReceivedPacket* last_incoming_packet() {
- return last_incoming_packet_.get();
- }
-
- void set_track_last_incoming_packet(bool track) {
- track_last_incoming_packet_ = track;
- }
-
- void UseWriter(QuicPacketWriterWrapper* writer) {
- QUICHE_CHECK(test_writer_ == nullptr);
- test_writer_ = writer;
- }
-
- void set_peer_address(const QuicSocketAddress& address) {
- QUICHE_CHECK(test_writer_ != nullptr);
- test_writer_->set_peer_address(address);
- }
-
- private:
- QuicPacketWriterWrapper* test_writer_ = nullptr;
- // The last incoming packet, iff |track_last_incoming_packet_| is true.
- std::unique_ptr<QuicReceivedPacket> last_incoming_packet_;
- // If true, copy each packet from ProcessPacket into |last_incoming_packet_|
- bool track_last_incoming_packet_ = false;
-};
-
-MockableQuicClient::MockableQuicClient(
- QuicSocketAddress server_address,
- const QuicServerId& server_id,
- const ParsedQuicVersionVector& supported_versions,
- QuicEpollServer* epoll_server)
- : MockableQuicClient(server_address,
- server_id,
- QuicConfig(),
- supported_versions,
- epoll_server) {}
-
-MockableQuicClient::MockableQuicClient(
- QuicSocketAddress server_address,
- const QuicServerId& server_id,
- const QuicConfig& config,
- const ParsedQuicVersionVector& supported_versions,
- QuicEpollServer* epoll_server)
- : MockableQuicClient(server_address,
- server_id,
- config,
- supported_versions,
- epoll_server,
- nullptr) {}
-
-MockableQuicClient::MockableQuicClient(
- QuicSocketAddress server_address,
- const QuicServerId& server_id,
- const QuicConfig& config,
- const ParsedQuicVersionVector& supported_versions,
- QuicEpollServer* epoll_server,
- std::unique_ptr<ProofVerifier> proof_verifier)
- : MockableQuicClient(server_address,
- server_id,
- config,
- supported_versions,
- epoll_server,
- std::move(proof_verifier),
- nullptr) {}
-
-MockableQuicClient::MockableQuicClient(
- QuicSocketAddress server_address,
- const QuicServerId& server_id,
- const QuicConfig& config,
- const ParsedQuicVersionVector& supported_versions,
- QuicEpollServer* epoll_server,
- std::unique_ptr<ProofVerifier> proof_verifier,
- std::unique_ptr<SessionCache> session_cache)
- : QuicClient(
- server_address,
- server_id,
- supported_versions,
- config,
- epoll_server,
- std::make_unique<MockableQuicClientEpollNetworkHelper>(epoll_server,
- this),
- std::make_unique<RecordingProofVerifier>(std::move(proof_verifier)),
- std::move(session_cache)),
- override_server_connection_id_(EmptyQuicConnectionId()),
- server_connection_id_overridden_(false),
- override_client_connection_id_(EmptyQuicConnectionId()),
- client_connection_id_overridden_(false) {}
-
-MockableQuicClient::~MockableQuicClient() {
- if (connected()) {
- Disconnect();
- }
-}
-
-MockableQuicClientEpollNetworkHelper*
-MockableQuicClient::mockable_network_helper() {
- return static_cast<MockableQuicClientEpollNetworkHelper*>(
- epoll_network_helper());
-}
-
-const MockableQuicClientEpollNetworkHelper*
-MockableQuicClient::mockable_network_helper() const {
- return static_cast<const MockableQuicClientEpollNetworkHelper*>(
- epoll_network_helper());
-}
-
-QuicConnectionId MockableQuicClient::GenerateNewConnectionId() {
- if (server_connection_id_overridden_) {
- return override_server_connection_id_;
- }
- if (override_server_connection_id_length_ >= 0) {
- return QuicUtils::CreateRandomConnectionId(
- override_server_connection_id_length_);
- }
- return QuicClient::GenerateNewConnectionId();
-}
-
-void MockableQuicClient::UseConnectionId(
- QuicConnectionId server_connection_id) {
- server_connection_id_overridden_ = true;
- override_server_connection_id_ = server_connection_id;
-}
-
-void MockableQuicClient::UseConnectionIdLength(
- int server_connection_id_length) {
- override_server_connection_id_length_ = server_connection_id_length;
-}
-
-QuicConnectionId MockableQuicClient::GetClientConnectionId() {
- if (client_connection_id_overridden_) {
- return override_client_connection_id_;
- }
- if (override_client_connection_id_length_ >= 0) {
- return QuicUtils::CreateRandomConnectionId(
- override_client_connection_id_length_);
- }
- return QuicClient::GetClientConnectionId();
-}
-
-void MockableQuicClient::UseClientConnectionId(
- QuicConnectionId client_connection_id) {
- client_connection_id_overridden_ = true;
- override_client_connection_id_ = client_connection_id;
-}
-
-void MockableQuicClient::UseClientConnectionIdLength(
- int client_connection_id_length) {
- override_client_connection_id_length_ = client_connection_id_length;
-}
-
-void MockableQuicClient::UseWriter(QuicPacketWriterWrapper* writer) {
- mockable_network_helper()->UseWriter(writer);
-}
-
-void MockableQuicClient::set_peer_address(const QuicSocketAddress& address) {
- mockable_network_helper()->set_peer_address(address);
- if (client_session() != nullptr) {
- client_session()->AddKnownServerAddress(address);
- }
-}
-
-const QuicReceivedPacket* MockableQuicClient::last_incoming_packet() {
- return mockable_network_helper()->last_incoming_packet();
-}
-
-void MockableQuicClient::set_track_last_incoming_packet(bool track) {
- mockable_network_helper()->set_track_last_incoming_packet(track);
-}
-
-QuicTestClient::QuicTestClient(
- QuicSocketAddress server_address,
- const std::string& server_hostname,
- const ParsedQuicVersionVector& supported_versions)
- : QuicTestClient(server_address,
- server_hostname,
- QuicConfig(),
- supported_versions) {}
-
-QuicTestClient::QuicTestClient(
- QuicSocketAddress server_address,
- const std::string& server_hostname,
- const QuicConfig& config,
- const ParsedQuicVersionVector& supported_versions)
- : client_(new MockableQuicClient(
- server_address,
- QuicServerId(server_hostname, server_address.port(), false),
- config,
- supported_versions,
- &epoll_server_)) {
- Initialize();
-}
-
-QuicTestClient::QuicTestClient(
- QuicSocketAddress server_address,
- const std::string& server_hostname,
- const QuicConfig& config,
- const ParsedQuicVersionVector& supported_versions,
- std::unique_ptr<ProofVerifier> proof_verifier)
- : client_(new MockableQuicClient(
- server_address,
- QuicServerId(server_hostname, server_address.port(), false),
- config,
- supported_versions,
- &epoll_server_,
- std::move(proof_verifier))) {
- Initialize();
-}
-
-QuicTestClient::QuicTestClient(
- QuicSocketAddress server_address,
- const std::string& server_hostname,
- const QuicConfig& config,
- const ParsedQuicVersionVector& supported_versions,
- std::unique_ptr<ProofVerifier> proof_verifier,
- std::unique_ptr<SessionCache> session_cache)
- : client_(new MockableQuicClient(
- server_address,
- QuicServerId(server_hostname, server_address.port(), false),
- config,
- supported_versions,
- &epoll_server_,
- std::move(proof_verifier),
- std::move(session_cache))) {
- Initialize();
-}
-
-QuicTestClient::QuicTestClient() = default;
-
-QuicTestClient::~QuicTestClient() {
- for (std::pair<QuicStreamId, QuicSpdyClientStream*> stream : open_streams_) {
- stream.second->set_visitor(nullptr);
- }
-}
-
-void QuicTestClient::Initialize() {
- priority_ = 3;
- connect_attempted_ = false;
- auto_reconnect_ = false;
- buffer_body_ = true;
- num_requests_ = 0;
- num_responses_ = 0;
- ClearPerConnectionState();
- // As chrome will generally do this, we want it to be the default when it's
- // not overridden.
- if (!client_->config()->HasSetBytesForConnectionIdToSend()) {
- client_->config()->SetBytesForConnectionIdToSend(0);
- }
-}
-
-void QuicTestClient::SetUserAgentID(const std::string& user_agent_id) {
- client_->SetUserAgentID(user_agent_id);
-}
-
-ssize_t QuicTestClient::SendRequest(const std::string& uri) {
- spdy::SpdyHeaderBlock headers;
- if (!PopulateHeaderBlockFromUrl(uri, &headers)) {
- return 0;
- }
- return SendMessage(headers, "");
-}
-
-ssize_t QuicTestClient::SendRequestAndRstTogether(const std::string& uri) {
- spdy::SpdyHeaderBlock headers;
- if (!PopulateHeaderBlockFromUrl(uri, &headers)) {
- return 0;
- }
-
- QuicSpdyClientSession* session = client()->client_session();
- QuicConnection::ScopedPacketFlusher flusher(session->connection());
- ssize_t ret = SendMessage(headers, "", /*fin=*/true, /*flush=*/false);
-
- QuicStreamId stream_id = GetNthClientInitiatedBidirectionalStreamId(
- session->transport_version(), 0);
- session->ResetStream(stream_id, QUIC_STREAM_CANCELLED);
- return ret;
-}
-
-void QuicTestClient::SendRequestsAndWaitForResponses(
- const std::vector<std::string>& url_list) {
- for (const std::string& url : url_list) {
- SendRequest(url);
- }
- while (client()->WaitForEvents()) {
- }
-}
-
-ssize_t QuicTestClient::GetOrCreateStreamAndSendRequest(
- const spdy::SpdyHeaderBlock* headers,
- absl::string_view body,
- bool fin,
- QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener) {
- if (headers) {
- QuicClientPushPromiseIndex::TryHandle* handle;
- QuicAsyncStatus rv =
- client()->push_promise_index()->Try(*headers, this, &handle);
- if (rv == QUIC_SUCCESS)
- return 1;
- if (rv == QUIC_PENDING) {
- // May need to retry request if asynchronous rendezvous fails.
- std::unique_ptr<spdy::SpdyHeaderBlock> new_headers(
- new spdy::SpdyHeaderBlock(headers->Clone()));
- push_promise_data_to_resend_ = std::make_unique<TestClientDataToResend>(
- std::move(new_headers), body, fin, this, std::move(ack_listener));
- return 1;
- }
- }
-
- // Maybe it's better just to overload this. it's just that we need
- // for the GetOrCreateStream function to call something else...which
- // is icky and complicated, but maybe not worse than this.
- QuicSpdyClientStream* stream = GetOrCreateStream();
- if (stream == nullptr) {
- return 0;
- }
- QuicSpdyStreamPeer::set_ack_listener(stream, ack_listener);
-
- ssize_t ret = 0;
- if (headers != nullptr) {
- spdy::SpdyHeaderBlock spdy_headers(headers->Clone());
- if (spdy_headers[":authority"].as_string().empty()) {
- spdy_headers[":authority"] = client_->server_id().host();
- }
- ret = stream->SendRequest(std::move(spdy_headers), body, fin);
- ++num_requests_;
- } else {
- stream->WriteOrBufferBody(std::string(body), fin);
- ret = body.length();
- }
- return ret;
-}
-
-ssize_t QuicTestClient::SendMessage(const spdy::SpdyHeaderBlock& headers,
- absl::string_view body) {
- return SendMessage(headers, body, /*fin=*/true);
-}
-
-ssize_t QuicTestClient::SendMessage(const spdy::SpdyHeaderBlock& headers,
- absl::string_view body,
- bool fin) {
- return SendMessage(headers, body, fin, /*flush=*/true);
-}
-
-ssize_t QuicTestClient::SendMessage(const spdy::SpdyHeaderBlock& headers,
- absl::string_view body,
- bool fin,
- bool flush) {
- // Always force creation of a stream for SendMessage.
- latest_created_stream_ = nullptr;
-
- ssize_t ret = GetOrCreateStreamAndSendRequest(&headers, body, fin, nullptr);
-
- if (flush) {
- WaitForWriteToFlush();
- }
- return ret;
-}
-
-ssize_t QuicTestClient::SendData(const std::string& data, bool last_data) {
- return SendData(data, last_data, nullptr);
-}
-
-ssize_t QuicTestClient::SendData(
- const std::string& data,
- bool last_data,
- QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener) {
- return GetOrCreateStreamAndSendRequest(nullptr, absl::string_view(data),
- last_data, std::move(ack_listener));
-}
-
-bool QuicTestClient::response_complete() const {
- return response_complete_;
-}
-
-int64_t QuicTestClient::response_body_size() const {
- return response_body_size_;
-}
-
-bool QuicTestClient::buffer_body() const {
- return buffer_body_;
-}
-
-void QuicTestClient::set_buffer_body(bool buffer_body) {
- buffer_body_ = buffer_body;
-}
-
-const std::string& QuicTestClient::response_body() const {
- return response_;
-}
-
-std::string QuicTestClient::SendCustomSynchronousRequest(
- const spdy::SpdyHeaderBlock& headers,
- const std::string& body) {
- // Clear connection state here and only track this synchronous request.
- ClearPerConnectionState();
- if (SendMessage(headers, body) == 0) {
- QUIC_DLOG(ERROR) << "Failed the request for: " << headers.DebugString();
- // Set the response_ explicitly. Otherwise response_ will contain the
- // response from the previously successful request.
- response_ = "";
- } else {
- WaitForResponse();
- }
- return response_;
-}
-
-std::string QuicTestClient::SendSynchronousRequest(const std::string& uri) {
- spdy::SpdyHeaderBlock headers;
- if (!PopulateHeaderBlockFromUrl(uri, &headers)) {
- return "";
- }
- return SendCustomSynchronousRequest(headers, "");
-}
-
-void QuicTestClient::SendConnectivityProbing() {
- QuicConnection* connection = client()->client_session()->connection();
- connection->SendConnectivityProbingPacket(connection->writer(),
- connection->peer_address());
-}
-
-void QuicTestClient::SetLatestCreatedStream(QuicSpdyClientStream* stream) {
- latest_created_stream_ = stream;
- if (latest_created_stream_ != nullptr) {
- open_streams_[stream->id()] = stream;
- stream->set_visitor(this);
- }
-}
-
-QuicSpdyClientStream* QuicTestClient::GetOrCreateStream() {
- if (!connect_attempted_ || auto_reconnect_) {
- if (!connected()) {
- Connect();
- }
- if (!connected()) {
- return nullptr;
- }
- }
- if (open_streams_.empty()) {
- ClearPerConnectionState();
- }
- if (!latest_created_stream_) {
- SetLatestCreatedStream(client_->CreateClientStream());
- if (latest_created_stream_) {
- latest_created_stream_->SetPriority(
- spdy::SpdyStreamPrecedence(priority_));
- }
- }
-
- return latest_created_stream_;
-}
-
-QuicErrorCode QuicTestClient::connection_error() const {
- return client()->connection_error();
-}
-
-const std::string& QuicTestClient::cert_common_name() const {
- return reinterpret_cast<RecordingProofVerifier*>(client_->proof_verifier())
- ->common_name();
-}
-
-const std::string& QuicTestClient::cert_sct() const {
- return reinterpret_cast<RecordingProofVerifier*>(client_->proof_verifier())
- ->cert_sct();
-}
-
-const QuicTagValueMap& QuicTestClient::GetServerConfig() const {
- QuicCryptoClientConfig* config = client_->crypto_config();
- const QuicCryptoClientConfig::CachedState* state =
- config->LookupOrCreate(client_->server_id());
- const CryptoHandshakeMessage* handshake_msg = state->GetServerConfig();
- return handshake_msg->tag_value_map();
-}
-
-bool QuicTestClient::connected() const {
- return client_->connected();
-}
-
-void QuicTestClient::Connect() {
- if (connected()) {
- QUIC_BUG(quic_bug_10133_1) << "Cannot connect already-connected client";
- return;
- }
- if (!connect_attempted_) {
- client_->Initialize();
- }
-
- // If we've been asked to override SNI, set it now
- if (override_sni_set_) {
- client_->set_server_id(
- QuicServerId(override_sni_, address().port(), false));
- }
-
- client_->Connect();
- connect_attempted_ = true;
-}
-
-void QuicTestClient::ResetConnection() {
- Disconnect();
- Connect();
-}
-
-void QuicTestClient::Disconnect() {
- ClearPerConnectionState();
- if (client_->initialized()) {
- client_->Disconnect();
- }
- connect_attempted_ = false;
-}
-
-QuicSocketAddress QuicTestClient::local_address() const {
- return client_->network_helper()->GetLatestClientAddress();
-}
-
-void QuicTestClient::ClearPerRequestState() {
- stream_error_ = QUIC_STREAM_NO_ERROR;
- response_ = "";
- response_complete_ = false;
- response_headers_complete_ = false;
- preliminary_headers_.clear();
- response_headers_.clear();
- response_trailers_.clear();
- bytes_read_ = 0;
- bytes_written_ = 0;
- response_body_size_ = 0;
-}
-
-bool QuicTestClient::HaveActiveStream() {
- return push_promise_data_to_resend_.get() || !open_streams_.empty();
-}
-
-bool QuicTestClient::WaitUntil(int timeout_ms, std::function<bool()> trigger) {
- int64_t timeout_us = timeout_ms * kNumMicrosPerMilli;
- int64_t old_timeout_us = epoll_server()->timeout_in_us_for_test();
- if (timeout_us > 0) {
- epoll_server()->set_timeout_in_us(timeout_us);
- }
- const QuicClock* clock =
- QuicConnectionPeer::GetHelper(client()->session()->connection())
- ->GetClock();
- QuicTime end_waiting_time =
- clock->Now() + QuicTime::Delta::FromMicroseconds(timeout_us);
- while (HaveActiveStream() && !(trigger && trigger()) &&
- (timeout_us < 0 || clock->Now() < end_waiting_time)) {
- client_->WaitForEvents();
- }
- ReadNextResponse();
- if (timeout_us > 0) {
- epoll_server()->set_timeout_in_us(old_timeout_us);
- }
- if (trigger && !trigger()) {
- QUIC_VLOG(1) << "Client WaitUntil returning with trigger returning false.";
- return false;
- }
- return true;
-}
-
-ssize_t QuicTestClient::Send(absl::string_view data) {
- return SendData(std::string(data), false);
-}
-
-bool QuicTestClient::response_headers_complete() const {
- for (std::pair<QuicStreamId, QuicSpdyClientStream*> stream : open_streams_) {
- if (stream.second->headers_decompressed()) {
- return true;
- }
- }
- return response_headers_complete_;
-}
-
-const spdy::SpdyHeaderBlock* QuicTestClient::response_headers() const {
- for (std::pair<QuicStreamId, QuicSpdyClientStream*> stream : open_streams_) {
- if (stream.second->headers_decompressed()) {
- response_headers_ = stream.second->response_headers().Clone();
- break;
- }
- }
- return &response_headers_;
-}
-
-const spdy::SpdyHeaderBlock* QuicTestClient::preliminary_headers() const {
- for (std::pair<QuicStreamId, QuicSpdyClientStream*> stream : open_streams_) {
- size_t bytes_read =
- stream.second->stream_bytes_read() + stream.second->header_bytes_read();
- if (bytes_read > 0) {
- preliminary_headers_ = stream.second->preliminary_headers().Clone();
- break;
- }
- }
- return &preliminary_headers_;
-}
-
-const spdy::SpdyHeaderBlock& QuicTestClient::response_trailers() const {
- return response_trailers_;
-}
-
-int64_t QuicTestClient::response_size() const {
- return bytes_read();
-}
-
-size_t QuicTestClient::bytes_read() const {
- for (std::pair<QuicStreamId, QuicSpdyClientStream*> stream : open_streams_) {
- size_t bytes_read = stream.second->total_body_bytes_read() +
- stream.second->header_bytes_read();
- if (bytes_read > 0) {
- return bytes_read;
- }
- }
- return bytes_read_;
-}
-
-size_t QuicTestClient::bytes_written() const {
- for (std::pair<QuicStreamId, QuicSpdyClientStream*> stream : open_streams_) {
- size_t bytes_written = stream.second->stream_bytes_written() +
- stream.second->header_bytes_written();
- if (bytes_written > 0) {
- return bytes_written;
- }
- }
- return bytes_written_;
-}
-
-void QuicTestClient::OnClose(QuicSpdyStream* stream) {
- if (stream == nullptr) {
- return;
- }
- // Always close the stream, regardless of whether it was the last stream
- // written.
- client()->OnClose(stream);
- ++num_responses_;
- if (open_streams_.find(stream->id()) == open_streams_.end()) {
- return;
- }
- if (latest_created_stream_ == stream) {
- latest_created_stream_ = nullptr;
- }
- QuicSpdyClientStream* client_stream =
- static_cast<QuicSpdyClientStream*>(stream);
- QuicStreamId id = client_stream->id();
- closed_stream_states_.insert(std::make_pair(
- id,
- PerStreamState(
- // Set response_complete to true iff stream is closed while connected.
- client_stream->stream_error(), connected(),
- client_stream->headers_decompressed(),
- client_stream->response_headers(),
- client_stream->preliminary_headers(),
- (buffer_body() ? client_stream->data() : ""),
- client_stream->received_trailers(),
- // Use NumBytesConsumed to avoid counting retransmitted stream frames.
- client_stream->total_body_bytes_read() +
- client_stream->header_bytes_read(),
- client_stream->stream_bytes_written() +
- client_stream->header_bytes_written(),
- client_stream->data().size())));
- open_streams_.erase(id);
-}
-
-bool QuicTestClient::CheckVary(
- const spdy::SpdyHeaderBlock& /*client_request*/,
- const spdy::SpdyHeaderBlock& /*promise_request*/,
- const spdy::SpdyHeaderBlock& /*promise_response*/) {
- return true;
-}
-
-void QuicTestClient::OnRendezvousResult(QuicSpdyStream* stream) {
- std::unique_ptr<TestClientDataToResend> data_to_resend =
- std::move(push_promise_data_to_resend_);
- SetLatestCreatedStream(static_cast<QuicSpdyClientStream*>(stream));
- if (stream) {
- stream->OnBodyAvailable();
- } else if (data_to_resend) {
- data_to_resend->Resend();
- }
-}
-
-void QuicTestClient::UseWriter(QuicPacketWriterWrapper* writer) {
- client_->UseWriter(writer);
-}
-
-void QuicTestClient::UseConnectionId(QuicConnectionId server_connection_id) {
- QUICHE_DCHECK(!connected());
- client_->UseConnectionId(server_connection_id);
-}
-
-void QuicTestClient::UseConnectionIdLength(int server_connection_id_length) {
- QUICHE_DCHECK(!connected());
- client_->UseConnectionIdLength(server_connection_id_length);
-}
-
-void QuicTestClient::UseClientConnectionId(
- QuicConnectionId client_connection_id) {
- QUICHE_DCHECK(!connected());
- client_->UseClientConnectionId(client_connection_id);
-}
-
-void QuicTestClient::UseClientConnectionIdLength(
- int client_connection_id_length) {
- QUICHE_DCHECK(!connected());
- client_->UseClientConnectionIdLength(client_connection_id_length);
-}
-
-bool QuicTestClient::MigrateSocket(const QuicIpAddress& new_host) {
- return client_->MigrateSocket(new_host);
-}
-
-bool QuicTestClient::MigrateSocketWithSpecifiedPort(
- const QuicIpAddress& new_host,
- int port) {
- client_->set_local_port(port);
- return client_->MigrateSocket(new_host);
-}
-
-QuicIpAddress QuicTestClient::bind_to_address() const {
- return client_->bind_to_address();
-}
-
-void QuicTestClient::set_bind_to_address(QuicIpAddress address) {
- client_->set_bind_to_address(address);
-}
-
-const QuicSocketAddress& QuicTestClient::address() const {
- return client_->server_address();
-}
-
-void QuicTestClient::WaitForWriteToFlush() {
- while (connected() && client()->session()->HasDataToWrite()) {
- client_->WaitForEvents();
- }
-}
-
-QuicTestClient::TestClientDataToResend::TestClientDataToResend(
- std::unique_ptr<spdy::SpdyHeaderBlock> headers,
- absl::string_view body,
- bool fin,
- QuicTestClient* test_client,
- QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener)
- : QuicClient::QuicDataToResend(std::move(headers), body, fin),
- test_client_(test_client),
- ack_listener_(std::move(ack_listener)) {}
-
-QuicTestClient::TestClientDataToResend::~TestClientDataToResend() = default;
-
-void QuicTestClient::TestClientDataToResend::Resend() {
- test_client_->GetOrCreateStreamAndSendRequest(headers_.get(), body_, fin_,
- ack_listener_);
- headers_.reset();
-}
-
-QuicTestClient::PerStreamState::PerStreamState(const PerStreamState& other)
- : stream_error(other.stream_error),
- response_complete(other.response_complete),
- response_headers_complete(other.response_headers_complete),
- response_headers(other.response_headers.Clone()),
- preliminary_headers(other.preliminary_headers.Clone()),
- response(other.response),
- response_trailers(other.response_trailers.Clone()),
- bytes_read(other.bytes_read),
- bytes_written(other.bytes_written),
- response_body_size(other.response_body_size) {}
-
-QuicTestClient::PerStreamState::PerStreamState(
- QuicRstStreamErrorCode stream_error,
- bool response_complete,
- bool response_headers_complete,
- const spdy::SpdyHeaderBlock& response_headers,
- const spdy::SpdyHeaderBlock& preliminary_headers,
- const std::string& response,
- const spdy::SpdyHeaderBlock& response_trailers,
- uint64_t bytes_read,
- uint64_t bytes_written,
- int64_t response_body_size)
- : stream_error(stream_error),
- response_complete(response_complete),
- response_headers_complete(response_headers_complete),
- response_headers(response_headers.Clone()),
- preliminary_headers(preliminary_headers.Clone()),
- response(response),
- response_trailers(response_trailers.Clone()),
- bytes_read(bytes_read),
- bytes_written(bytes_written),
- response_body_size(response_body_size) {}
-
-QuicTestClient::PerStreamState::~PerStreamState() = default;
-
-bool QuicTestClient::PopulateHeaderBlockFromUrl(
- const std::string& uri,
- spdy::SpdyHeaderBlock* headers) {
- std::string url;
- if (absl::StartsWith(uri, "https://") || absl::StartsWith(uri, "http://")) {
- url = uri;
- } else if (uri[0] == '/') {
- url = "https://" + client_->server_id().host() + uri;
- } else {
- url = "https://" + uri;
- }
- return SpdyUtils::PopulateHeaderBlockFromUrl(url, headers);
-}
-
-void QuicTestClient::ReadNextResponse() {
- if (closed_stream_states_.empty()) {
- return;
- }
-
- PerStreamState state(closed_stream_states_.front().second);
-
- stream_error_ = state.stream_error;
- response_ = state.response;
- response_complete_ = state.response_complete;
- response_headers_complete_ = state.response_headers_complete;
- preliminary_headers_ = state.preliminary_headers.Clone();
- response_headers_ = state.response_headers.Clone();
- response_trailers_ = state.response_trailers.Clone();
- bytes_read_ = state.bytes_read;
- bytes_written_ = state.bytes_written;
- response_body_size_ = state.response_body_size;
-
- closed_stream_states_.pop_front();
-}
-
-void QuicTestClient::ClearPerConnectionState() {
- ClearPerRequestState();
- open_streams_.clear();
- closed_stream_states_.clear();
- latest_created_stream_ = nullptr;
-}
-
-void QuicTestClient::WaitForDelayedAcks() {
- // kWaitDuration is a period of time that is long enough for all delayed
- // acks to be sent and received on the other end.
- const QuicTime::Delta kWaitDuration =
- 4 * QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
-
- const QuicClock* clock = client()->client_session()->connection()->clock();
-
- QuicTime wait_until = clock->ApproximateNow() + kWaitDuration;
- while (connected() && clock->ApproximateNow() < wait_until) {
- // This waits for up to 50 ms.
- client()->WaitForEvents();
- }
-}
-
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/quic_test_client.h b/chromium/net/third_party/quiche/src/quic/test_tools/quic_test_client.h
deleted file mode 100644
index db97e0265e9..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/quic_test_client.h
+++ /dev/null
@@ -1,449 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_QUIC_TEST_CLIENT_H_
-#define QUICHE_QUIC_TEST_TOOLS_QUIC_TEST_CLIENT_H_
-
-#include <cstdint>
-#include <memory>
-#include <string>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/proto/cached_network_parameters_proto.h"
-#include "quic/core/quic_framer.h"
-#include "quic/core/quic_packet_creator.h"
-#include "quic/core/quic_packets.h"
-#include "quic/platform/api/quic_epoll.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/tools/quic_client.h"
-#include "common/quiche_linked_hash_map.h"
-
-namespace quic {
-
-class ProofVerifier;
-class QuicPacketWriterWrapper;
-
-namespace test {
-
-class MockableQuicClientEpollNetworkHelper;
-
-// A quic client which allows mocking out reads and writes.
-class MockableQuicClient : public QuicClient {
- public:
- MockableQuicClient(QuicSocketAddress server_address,
- const QuicServerId& server_id,
- const ParsedQuicVersionVector& supported_versions,
- QuicEpollServer* epoll_server);
-
- MockableQuicClient(QuicSocketAddress server_address,
- const QuicServerId& server_id,
- const QuicConfig& config,
- const ParsedQuicVersionVector& supported_versions,
- QuicEpollServer* epoll_server);
-
- MockableQuicClient(QuicSocketAddress server_address,
- const QuicServerId& server_id,
- const QuicConfig& config,
- const ParsedQuicVersionVector& supported_versions,
- QuicEpollServer* epoll_server,
- std::unique_ptr<ProofVerifier> proof_verifier);
-
- MockableQuicClient(QuicSocketAddress server_address,
- const QuicServerId& server_id,
- const QuicConfig& config,
- const ParsedQuicVersionVector& supported_versions,
- QuicEpollServer* epoll_server,
- std::unique_ptr<ProofVerifier> proof_verifier,
- std::unique_ptr<SessionCache> session_cache);
- MockableQuicClient(const MockableQuicClient&) = delete;
- MockableQuicClient& operator=(const MockableQuicClient&) = delete;
-
- ~MockableQuicClient() override;
-
- QuicConnectionId GenerateNewConnectionId() override;
- void UseConnectionId(QuicConnectionId server_connection_id);
- void UseConnectionIdLength(int server_connection_id_length);
- QuicConnectionId GetClientConnectionId() override;
- void UseClientConnectionId(QuicConnectionId client_connection_id);
- void UseClientConnectionIdLength(int client_connection_id_length);
-
- void UseWriter(QuicPacketWriterWrapper* writer);
- void set_peer_address(const QuicSocketAddress& address);
- // The last incoming packet, iff |track_last_incoming_packet| is true.
- const QuicReceivedPacket* last_incoming_packet();
- // If true, copy each packet from ProcessPacket into |last_incoming_packet|
- void set_track_last_incoming_packet(bool track);
-
- // Casts the network helper to a MockableQuicClientEpollNetworkHelper.
- MockableQuicClientEpollNetworkHelper* mockable_network_helper();
- const MockableQuicClientEpollNetworkHelper* mockable_network_helper() const;
-
- private:
- // Server connection ID to use, if server_connection_id_overridden_
- QuicConnectionId override_server_connection_id_;
- bool server_connection_id_overridden_;
- int override_server_connection_id_length_ = -1;
- // Client connection ID to use, if client_connection_id_overridden_
- QuicConnectionId override_client_connection_id_;
- bool client_connection_id_overridden_;
- int override_client_connection_id_length_ = -1;
- CachedNetworkParameters cached_network_paramaters_;
-};
-
-// A toy QUIC client used for testing.
-class QuicTestClient : public QuicSpdyStream::Visitor,
- public QuicClientPushPromiseIndex::Delegate {
- public:
- QuicTestClient(QuicSocketAddress server_address,
- const std::string& server_hostname,
- const ParsedQuicVersionVector& supported_versions);
- QuicTestClient(QuicSocketAddress server_address,
- const std::string& server_hostname,
- const QuicConfig& config,
- const ParsedQuicVersionVector& supported_versions);
- QuicTestClient(QuicSocketAddress server_address,
- const std::string& server_hostname,
- const QuicConfig& config,
- const ParsedQuicVersionVector& supported_versions,
- std::unique_ptr<ProofVerifier> proof_verifier);
- QuicTestClient(QuicSocketAddress server_address,
- const std::string& server_hostname,
- const QuicConfig& config,
- const ParsedQuicVersionVector& supported_versions,
- std::unique_ptr<ProofVerifier> proof_verifier,
- std::unique_ptr<SessionCache> session_cache);
-
- ~QuicTestClient() override;
-
- // Sets the |user_agent_id| of the |client_|.
- void SetUserAgentID(const std::string& user_agent_id);
-
- // Wraps data in a quic packet and sends it.
- ssize_t SendData(const std::string& data, bool last_data);
- // As above, but |delegate| will be notified when |data| is ACKed.
- ssize_t SendData(
- const std::string& data,
- bool last_data,
- QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener);
-
- // Clears any outstanding state and sends a simple GET of 'uri' to the
- // server. Returns 0 if the request failed and no bytes were written.
- ssize_t SendRequest(const std::string& uri);
- // Send a request R and a RST_FRAME which resets R, in the same packet.
- ssize_t SendRequestAndRstTogether(const std::string& uri);
- // Sends requests for all the urls and waits for the responses. To process
- // the individual responses as they are returned, the caller should use the
- // set the response_listener on the client().
- void SendRequestsAndWaitForResponses(
- const std::vector<std::string>& url_list);
- // Sends a request containing |headers| and |body| and returns the number of
- // bytes sent (the size of the serialized request headers and body).
- ssize_t SendMessage(const spdy::SpdyHeaderBlock& headers,
- absl::string_view body);
- // Sends a request containing |headers| and |body| with the fin bit set to
- // |fin| and returns the number of bytes sent (the size of the serialized
- // request headers and body).
- ssize_t SendMessage(const spdy::SpdyHeaderBlock& headers,
- absl::string_view body,
- bool fin);
- // Sends a request containing |headers| and |body| with the fin bit set to
- // |fin| and returns the number of bytes sent (the size of the serialized
- // request headers and body). If |flush| is true, will wait for the message to
- // be flushed before returning.
- ssize_t SendMessage(const spdy::SpdyHeaderBlock& headers,
- absl::string_view body,
- bool fin,
- bool flush);
- // Sends a request containing |headers| and |body|, waits for the response,
- // and returns the response body.
- std::string SendCustomSynchronousRequest(const spdy::SpdyHeaderBlock& headers,
- const std::string& body);
- // Sends a GET request for |uri|, waits for the response, and returns the
- // response body.
- std::string SendSynchronousRequest(const std::string& uri);
- void SendConnectivityProbing();
- void Connect();
- void ResetConnection();
- void Disconnect();
- QuicSocketAddress local_address() const;
- void ClearPerRequestState();
- bool WaitUntil(int timeout_ms, std::function<bool()> trigger);
- ssize_t Send(absl::string_view data);
- bool connected() const;
- bool buffer_body() const;
- void set_buffer_body(bool buffer_body);
-
- // Getters for stream state. Please note, these getters are divided into two
- // groups. 1) returns state which only get updated once a complete response
- // is received. 2) returns state of the oldest active stream which have
- // received partial response (if any).
- // Group 1.
- const spdy::SpdyHeaderBlock& response_trailers() const;
- bool response_complete() const;
- int64_t response_body_size() const;
- const std::string& response_body() const;
- // Group 2.
- bool response_headers_complete() const;
- const spdy::SpdyHeaderBlock* response_headers() const;
- const spdy::SpdyHeaderBlock* preliminary_headers() const;
- int64_t response_size() const;
- size_t bytes_read() const;
- size_t bytes_written() const;
-
- // Returns once at least one complete response or a connection close has been
- // received from the server. If responses are received for multiple (say 2)
- // streams, next WaitForResponse will return immediately.
- void WaitForResponse() { WaitForResponseForMs(-1); }
-
- // Returns once some data is received on any open streams or at least one
- // complete response is received from the server.
- void WaitForInitialResponse() { WaitForInitialResponseForMs(-1); }
-
- // Returns once at least one complete response or a connection close has been
- // received from the server, or once the timeout expires.
- // Passing in a timeout value of -1 disables the timeout. If multiple
- // responses are received while the client is waiting, subsequent calls to
- // this function will return immediately.
- void WaitForResponseForMs(int timeout_ms) {
- WaitUntil(timeout_ms, [this]() { return !closed_stream_states_.empty(); });
- if (response_complete()) {
- QUIC_VLOG(1) << "Client received response:"
- << response_headers()->DebugString() << response_body();
- }
- }
-
- // Returns once some data is received on any open streams or at least one
- // complete response is received from the server, or once the timeout
- // expires. -1 means no timeout.
- void WaitForInitialResponseForMs(int timeout_ms) {
- WaitUntil(timeout_ms, [this]() { return response_size() != 0; });
- }
-
- // Migrate local address to <|new_host|, a random port>.
- // Return whether the migration succeeded.
- bool MigrateSocket(const QuicIpAddress& new_host);
- // Migrate local address to <|new_host|, |port|>.
- // Return whether the migration succeeded.
- bool MigrateSocketWithSpecifiedPort(const QuicIpAddress& new_host, int port);
- QuicIpAddress bind_to_address() const;
- void set_bind_to_address(QuicIpAddress address);
- const QuicSocketAddress& address() const;
-
- // From QuicSpdyStream::Visitor
- void OnClose(QuicSpdyStream* stream) override;
-
- // From QuicClientPushPromiseIndex::Delegate
- bool CheckVary(const spdy::SpdyHeaderBlock& client_request,
- const spdy::SpdyHeaderBlock& promise_request,
- const spdy::SpdyHeaderBlock& promise_response) override;
- void OnRendezvousResult(QuicSpdyStream*) override;
-
- // Configures client_ to take ownership of and use the writer.
- // Must be called before initial connect.
- void UseWriter(QuicPacketWriterWrapper* writer);
- // Configures client_ to use a specific server connection ID instead of a
- // random one.
- void UseConnectionId(QuicConnectionId server_connection_id);
- // Configures client_ to use a specific server connection ID length instead
- // of the default of kQuicDefaultConnectionIdLength.
- void UseConnectionIdLength(int server_connection_id_length);
- // Configures client_ to use a specific client connection ID instead of an
- // empty one.
- void UseClientConnectionId(QuicConnectionId client_connection_id);
- // Configures client_ to use a specific client connection ID length instead
- // of the default of zero.
- void UseClientConnectionIdLength(int client_connection_id_length);
-
- // Returns nullptr if the maximum number of streams have already been created.
- QuicSpdyClientStream* GetOrCreateStream();
-
- // Calls GetOrCreateStream(), sends the request on the stream, and
- // stores the request in case it needs to be resent. If |headers| is
- // null, only the body will be sent on the stream.
- ssize_t GetOrCreateStreamAndSendRequest(
- const spdy::SpdyHeaderBlock* headers,
- absl::string_view body,
- bool fin,
- QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener);
-
- QuicRstStreamErrorCode stream_error() { return stream_error_; }
- QuicErrorCode connection_error() const;
-
- MockableQuicClient* client() { return client_.get(); }
- const MockableQuicClient* client() const { return client_.get(); }
-
- // cert_common_name returns the common name value of the server's certificate,
- // or the empty std::string if no certificate was presented.
- const std::string& cert_common_name() const;
-
- // cert_sct returns the signed timestamp of the server's certificate,
- // or the empty std::string if no signed timestamp was presented.
- const std::string& cert_sct() const;
-
- // Get the server config map. Server config must exist.
- const QuicTagValueMap& GetServerConfig() const;
-
- void set_auto_reconnect(bool reconnect) { auto_reconnect_ = reconnect; }
-
- void set_priority(spdy::SpdyPriority priority) { priority_ = priority; }
-
- void WaitForWriteToFlush();
-
- QuicEpollServer* epoll_server() { return &epoll_server_; }
-
- size_t num_requests() const { return num_requests_; }
-
- size_t num_responses() const { return num_responses_; }
-
- void set_server_address(const QuicSocketAddress& server_address) {
- client_->set_server_address(server_address);
- }
-
- void set_peer_address(const QuicSocketAddress& address) {
- client_->set_peer_address(address);
- }
-
- // Explicitly set the SNI value for this client, overriding the default
- // behavior which extracts the SNI value from the request URL.
- void OverrideSni(const std::string& sni) {
- override_sni_set_ = true;
- override_sni_ = sni;
- }
-
- void Initialize();
-
- void set_client(MockableQuicClient* client) { client_.reset(client); }
-
- // Given |uri|, populates the fields in |headers| for a simple GET
- // request. If |uri| is a relative URL, the QuicServerId will be
- // use to specify the authority.
- bool PopulateHeaderBlockFromUrl(const std::string& uri,
- spdy::SpdyHeaderBlock* headers);
-
- // Waits for a period of time that is long enough to receive all delayed acks
- // sent by peer.
- void WaitForDelayedAcks();
-
- QuicSpdyClientStream* latest_created_stream() {
- return latest_created_stream_;
- }
-
- protected:
- QuicTestClient();
- QuicTestClient(const QuicTestClient&) = delete;
- QuicTestClient(const QuicTestClient&&) = delete;
- QuicTestClient& operator=(const QuicTestClient&) = delete;
- QuicTestClient& operator=(const QuicTestClient&&) = delete;
-
- private:
- class TestClientDataToResend : public QuicClient::QuicDataToResend {
- public:
- TestClientDataToResend(
- std::unique_ptr<spdy::SpdyHeaderBlock> headers,
- absl::string_view body,
- bool fin,
- QuicTestClient* test_client,
- QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener);
-
- ~TestClientDataToResend() override;
-
- void Resend() override;
-
- protected:
- QuicTestClient* test_client_;
- QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener_;
- };
-
- // PerStreamState of a stream is updated when it is closed.
- struct PerStreamState {
- PerStreamState(const PerStreamState& other);
- PerStreamState(QuicRstStreamErrorCode stream_error,
- bool response_complete,
- bool response_headers_complete,
- const spdy::SpdyHeaderBlock& response_headers,
- const spdy::SpdyHeaderBlock& preliminary_headers,
- const std::string& response,
- const spdy::SpdyHeaderBlock& response_trailers,
- uint64_t bytes_read,
- uint64_t bytes_written,
- int64_t response_body_size);
- ~PerStreamState();
-
- QuicRstStreamErrorCode stream_error;
- bool response_complete;
- bool response_headers_complete;
- spdy::SpdyHeaderBlock response_headers;
- spdy::SpdyHeaderBlock preliminary_headers;
- std::string response;
- spdy::SpdyHeaderBlock response_trailers;
- uint64_t bytes_read;
- uint64_t bytes_written;
- int64_t response_body_size;
- };
-
- bool HaveActiveStream();
-
- // Read oldest received response and remove it from closed_stream_states_.
- void ReadNextResponse();
-
- // Clear open_streams_, closed_stream_states_ and reset
- // latest_created_stream_.
- void ClearPerConnectionState();
-
- // Update latest_created_stream_, add |stream| to open_streams_ and starts
- // tracking its state.
- void SetLatestCreatedStream(QuicSpdyClientStream* stream);
-
- QuicEpollServer epoll_server_;
- std::unique_ptr<MockableQuicClient> client_; // The actual client
- QuicSpdyClientStream* latest_created_stream_;
- std::map<QuicStreamId, QuicSpdyClientStream*> open_streams_;
- // Received responses of closed streams.
- quiche::QuicheLinkedHashMap<QuicStreamId, PerStreamState>
- closed_stream_states_;
-
- QuicRstStreamErrorCode stream_error_;
-
- bool response_complete_;
- bool response_headers_complete_;
- mutable spdy::SpdyHeaderBlock preliminary_headers_;
- mutable spdy::SpdyHeaderBlock response_headers_;
-
- // Parsed response trailers (if present), copied from the stream in OnClose.
- spdy::SpdyHeaderBlock response_trailers_;
-
- spdy::SpdyPriority priority_;
- std::string response_;
- // bytes_read_ and bytes_written_ are updated only when stream_ is released;
- // prefer bytes_read() and bytes_written() member functions.
- uint64_t bytes_read_;
- uint64_t bytes_written_;
- // The number of HTTP body bytes received.
- int64_t response_body_size_;
- // True if we tried to connect already since the last call to Disconnect().
- bool connect_attempted_;
- // The client will auto-connect exactly once before sending data. If
- // something causes a connection reset, it will not automatically reconnect
- // unless auto_reconnect_ is true.
- bool auto_reconnect_;
- // Should we buffer the response body? Defaults to true.
- bool buffer_body_;
- // For async push promise rendezvous, validation may fail in which
- // case the request should be retried.
- std::unique_ptr<TestClientDataToResend> push_promise_data_to_resend_;
- // Number of requests/responses this client has sent/received.
- size_t num_requests_;
- size_t num_responses_;
-
- // If set, this value is used for the connection SNI, overriding the usual
- // logic which extracts the SNI from the request URL.
- bool override_sni_set_ = false;
- std::string override_sni_;
-};
-
-} // namespace test
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_TEST_TOOLS_QUIC_TEST_CLIENT_H_
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/quic_test_server.cc b/chromium/net/third_party/quiche/src/quic/test_tools/quic_test_server.cc
deleted file mode 100644
index e8aee790f23..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/quic_test_server.cc
+++ /dev/null
@@ -1,272 +0,0 @@
-// Copyright (c) 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/quic_test_server.h"
-
-#include <utility>
-
-#include "absl/memory/memory.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_epoll_alarm_factory.h"
-#include "quic/core/quic_epoll_connection_helper.h"
-#include "quic/tools/quic_simple_crypto_server_stream_helper.h"
-#include "quic/tools/quic_simple_dispatcher.h"
-#include "quic/tools/quic_simple_server_session.h"
-
-namespace quic {
-
-namespace test {
-
-class CustomStreamSession : public QuicSimpleServerSession {
- public:
- CustomStreamSession(
- const QuicConfig& config,
- const ParsedQuicVersionVector& supported_versions,
- QuicConnection* connection,
- QuicSession::Visitor* visitor,
- QuicCryptoServerStreamBase::Helper* helper,
- const QuicCryptoServerConfig* crypto_config,
- QuicCompressedCertsCache* compressed_certs_cache,
- QuicTestServer::StreamFactory* stream_factory,
- QuicTestServer::CryptoStreamFactory* crypto_stream_factory,
- QuicSimpleServerBackend* quic_simple_server_backend)
- : QuicSimpleServerSession(config,
- supported_versions,
- connection,
- visitor,
- helper,
- crypto_config,
- compressed_certs_cache,
- quic_simple_server_backend),
- stream_factory_(stream_factory),
- crypto_stream_factory_(crypto_stream_factory) {}
-
- QuicSpdyStream* CreateIncomingStream(QuicStreamId id) override {
- if (!ShouldCreateIncomingStream(id)) {
- return nullptr;
- }
- if (stream_factory_) {
- QuicSpdyStream* stream =
- stream_factory_->CreateStream(id, this, server_backend());
- ActivateStream(absl::WrapUnique(stream));
- return stream;
- }
- return QuicSimpleServerSession::CreateIncomingStream(id);
- }
-
- std::unique_ptr<QuicCryptoServerStreamBase> CreateQuicCryptoServerStream(
- const QuicCryptoServerConfig* crypto_config,
- QuicCompressedCertsCache* compressed_certs_cache) override {
- if (crypto_stream_factory_) {
- return crypto_stream_factory_->CreateCryptoStream(crypto_config, this);
- }
- return QuicSimpleServerSession::CreateQuicCryptoServerStream(
- crypto_config, compressed_certs_cache);
- }
-
- private:
- QuicTestServer::StreamFactory* stream_factory_; // Not owned.
- QuicTestServer::CryptoStreamFactory* crypto_stream_factory_; // Not owned.
-};
-
-class QuicTestDispatcher : public QuicSimpleDispatcher {
- public:
- QuicTestDispatcher(
- 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,
- QuicSimpleServerBackend* quic_simple_server_backend,
- uint8_t expected_server_connection_id_length)
- : QuicSimpleDispatcher(config,
- crypto_config,
- version_manager,
- std::move(helper),
- std::move(session_helper),
- std::move(alarm_factory),
- quic_simple_server_backend,
- expected_server_connection_id_length),
- session_factory_(nullptr),
- stream_factory_(nullptr),
- crypto_stream_factory_(nullptr) {}
-
- std::unique_ptr<QuicSession> CreateQuicSession(
- QuicConnectionId id, const QuicSocketAddress& self_address,
- const QuicSocketAddress& peer_address, absl::string_view /*alpn*/,
- const ParsedQuicVersion& version,
- const ParsedClientHello& /*parsed_chlo*/) override {
- QuicReaderMutexLock lock(&factory_lock_);
- // The QuicServerSessionBase takes ownership of |connection| below.
- QuicConnection* connection = new QuicConnection(
- id, self_address, peer_address, helper(), alarm_factory(), writer(),
- /* owns_writer= */ false, Perspective::IS_SERVER,
- ParsedQuicVersionVector{version});
-
- std::unique_ptr<QuicServerSessionBase> session;
- if (session_factory_ == nullptr && stream_factory_ == nullptr &&
- crypto_stream_factory_ == nullptr) {
- session = std::make_unique<QuicSimpleServerSession>(
- config(), GetSupportedVersions(), connection, this, session_helper(),
- crypto_config(), compressed_certs_cache(), server_backend());
- } else if (stream_factory_ != nullptr ||
- crypto_stream_factory_ != nullptr) {
- session = std::make_unique<CustomStreamSession>(
- config(), GetSupportedVersions(), connection, this, session_helper(),
- crypto_config(), compressed_certs_cache(), stream_factory_,
- crypto_stream_factory_, server_backend());
- } else {
- session = session_factory_->CreateSession(
- config(), connection, this, session_helper(), crypto_config(),
- compressed_certs_cache(), server_backend());
- }
- if (VersionUsesHttp3(version.transport_version) &&
- GetQuicReloadableFlag(quic_verify_request_headers_2)) {
- QUICHE_DCHECK(session->allow_extended_connect());
- // Do not allow extended CONNECT request if the backend doesn't support
- // it.
- session->set_allow_extended_connect(
- server_backend()->SupportsExtendedConnect());
- }
- session->Initialize();
- return session;
- }
-
- void SetSessionFactory(QuicTestServer::SessionFactory* factory) {
- QuicWriterMutexLock lock(&factory_lock_);
- QUICHE_DCHECK(session_factory_ == nullptr);
- QUICHE_DCHECK(stream_factory_ == nullptr);
- QUICHE_DCHECK(crypto_stream_factory_ == nullptr);
- session_factory_ = factory;
- }
-
- void SetStreamFactory(QuicTestServer::StreamFactory* factory) {
- QuicWriterMutexLock lock(&factory_lock_);
- QUICHE_DCHECK(session_factory_ == nullptr);
- QUICHE_DCHECK(stream_factory_ == nullptr);
- stream_factory_ = factory;
- }
-
- void SetCryptoStreamFactory(QuicTestServer::CryptoStreamFactory* factory) {
- QuicWriterMutexLock lock(&factory_lock_);
- QUICHE_DCHECK(session_factory_ == nullptr);
- QUICHE_DCHECK(crypto_stream_factory_ == nullptr);
- crypto_stream_factory_ = factory;
- }
-
- private:
- QuicMutex factory_lock_;
- QuicTestServer::SessionFactory* session_factory_; // Not owned.
- QuicTestServer::StreamFactory* stream_factory_; // Not owned.
- QuicTestServer::CryptoStreamFactory* crypto_stream_factory_; // Not owned.
-};
-
-QuicTestServer::QuicTestServer(
- std::unique_ptr<ProofSource> proof_source,
- QuicSimpleServerBackend* quic_simple_server_backend)
- : QuicServer(std::move(proof_source), quic_simple_server_backend) {}
-
-QuicTestServer::QuicTestServer(
- std::unique_ptr<ProofSource> proof_source,
- const QuicConfig& config,
- const ParsedQuicVersionVector& supported_versions,
- QuicSimpleServerBackend* quic_simple_server_backend)
- : QuicTestServer(std::move(proof_source),
- config,
- supported_versions,
- quic_simple_server_backend,
- kQuicDefaultConnectionIdLength) {}
-
-QuicTestServer::QuicTestServer(
- std::unique_ptr<ProofSource> proof_source,
- const QuicConfig& config,
- const ParsedQuicVersionVector& supported_versions,
- QuicSimpleServerBackend* quic_simple_server_backend,
- uint8_t expected_server_connection_id_length)
- : QuicServer(std::move(proof_source),
- config,
- QuicCryptoServerConfig::ConfigOptions(),
- supported_versions,
- quic_simple_server_backend,
- expected_server_connection_id_length) {}
-
-QuicDispatcher* QuicTestServer::CreateQuicDispatcher() {
- return new QuicTestDispatcher(
- &config(), &crypto_config(), version_manager(),
- std::make_unique<QuicEpollConnectionHelper>(epoll_server(),
- QuicAllocator::BUFFER_POOL),
- std::unique_ptr<QuicCryptoServerStreamBase::Helper>(
- new QuicSimpleCryptoServerStreamHelper()),
- std::make_unique<QuicEpollAlarmFactory>(epoll_server()), server_backend(),
- expected_server_connection_id_length());
-}
-
-void QuicTestServer::SetSessionFactory(SessionFactory* factory) {
- QUICHE_DCHECK(dispatcher());
- static_cast<QuicTestDispatcher*>(dispatcher())->SetSessionFactory(factory);
-}
-
-void QuicTestServer::SetSpdyStreamFactory(StreamFactory* factory) {
- static_cast<QuicTestDispatcher*>(dispatcher())->SetStreamFactory(factory);
-}
-
-void QuicTestServer::SetCryptoStreamFactory(CryptoStreamFactory* factory) {
- static_cast<QuicTestDispatcher*>(dispatcher())
- ->SetCryptoStreamFactory(factory);
-}
-
-/////////////////////////// TEST SESSIONS ///////////////////////////////
-
-ImmediateGoAwaySession::ImmediateGoAwaySession(
- const QuicConfig& config,
- QuicConnection* connection,
- QuicSession::Visitor* visitor,
- QuicCryptoServerStreamBase::Helper* helper,
- const QuicCryptoServerConfig* crypto_config,
- QuicCompressedCertsCache* compressed_certs_cache,
- QuicSimpleServerBackend* quic_simple_server_backend)
- : QuicSimpleServerSession(config,
- CurrentSupportedVersions(),
- connection,
- visitor,
- helper,
- crypto_config,
- compressed_certs_cache,
- quic_simple_server_backend) {}
-
-void ImmediateGoAwaySession::OnStreamFrame(const QuicStreamFrame& frame) {
- if (VersionUsesHttp3(transport_version())) {
- SendHttp3GoAway(QUIC_PEER_GOING_AWAY, "");
- } else {
- SendGoAway(QUIC_PEER_GOING_AWAY, "");
- }
- QuicSimpleServerSession::OnStreamFrame(frame);
-}
-
-void ImmediateGoAwaySession::OnCryptoFrame(const QuicCryptoFrame& frame) {
- // In IETF QUIC, GOAWAY lives up in HTTP/3 layer. It's sent in a QUIC stream
- // and requires encryption. Thus the sending is done in
- // OnNewEncryptionKeyAvailable().
- if (!VersionUsesHttp3(transport_version())) {
- SendGoAway(QUIC_PEER_GOING_AWAY, "");
- }
- QuicSimpleServerSession::OnCryptoFrame(frame);
-}
-
-void ImmediateGoAwaySession::OnNewEncryptionKeyAvailable(
- EncryptionLevel level,
- std::unique_ptr<QuicEncrypter> encrypter) {
- QuicSimpleServerSession::OnNewEncryptionKeyAvailable(level,
- std::move(encrypter));
- if (VersionUsesHttp3(transport_version())) {
- if (IsEncryptionEstablished() && !goaway_sent()) {
- SendHttp3GoAway(QUIC_PEER_GOING_AWAY, "");
- }
- }
-}
-
-} // namespace test
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/quic_test_server.h b/chromium/net/third_party/quiche/src/quic/test_tools/quic_test_server.h
deleted file mode 100644
index 4fd2ce66660..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/quic_test_server.h
+++ /dev/null
@@ -1,117 +0,0 @@
-// Copyright (c) 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_QUIC_TEST_SERVER_H_
-#define QUICHE_QUIC_TEST_TOOLS_QUIC_TEST_SERVER_H_
-
-#include "quic/core/quic_dispatcher.h"
-#include "quic/core/quic_session.h"
-#include "quic/tools/quic_server.h"
-#include "quic/tools/quic_simple_server_backend.h"
-#include "quic/tools/quic_simple_server_session.h"
-#include "quic/tools/quic_simple_server_stream.h"
-
-namespace quic {
-
-namespace test {
-
-// A test server which enables easy creation of custom QuicServerSessions
-//
-// Eventually this may be extended to allow custom QuicConnections etc.
-class QuicTestServer : public QuicServer {
- public:
- // Factory for creating QuicServerSessions.
- class SessionFactory {
- public:
- virtual ~SessionFactory() {}
-
- // Returns a new session owned by the caller.
- virtual std::unique_ptr<QuicServerSessionBase> CreateSession(
- const QuicConfig& config,
- QuicConnection* connection,
- QuicSession::Visitor* visitor,
- QuicCryptoServerStreamBase::Helper* helper,
- const QuicCryptoServerConfig* crypto_config,
- QuicCompressedCertsCache* compressed_certs_cache,
- QuicSimpleServerBackend* quic_simple_server_backend) = 0;
- };
-
- // Factory for creating QuicSimpleServerStreams.
- class StreamFactory {
- public:
- virtual ~StreamFactory() {}
-
- // Returns a new stream owned by the caller.
- virtual QuicSimpleServerStream* CreateStream(
- QuicStreamId id,
- QuicSpdySession* session,
- QuicSimpleServerBackend* quic_simple_server_backend) = 0;
- };
-
- class CryptoStreamFactory {
- public:
- virtual ~CryptoStreamFactory() {}
-
- // Returns a new QuicCryptoServerStreamBase owned by the caller
- virtual std::unique_ptr<QuicCryptoServerStreamBase> CreateCryptoStream(
- const QuicCryptoServerConfig* crypto_config,
- QuicServerSessionBase* session) = 0;
- };
-
- QuicTestServer(std::unique_ptr<ProofSource> proof_source,
- QuicSimpleServerBackend* quic_simple_server_backend);
- QuicTestServer(std::unique_ptr<ProofSource> proof_source,
- const QuicConfig& config,
- const ParsedQuicVersionVector& supported_versions,
- QuicSimpleServerBackend* quic_simple_server_backend);
- QuicTestServer(std::unique_ptr<ProofSource> proof_source,
- const QuicConfig& config,
- const ParsedQuicVersionVector& supported_versions,
- QuicSimpleServerBackend* quic_simple_server_backend,
- uint8_t expected_server_connection_id_length);
-
- // Create a custom dispatcher which creates custom sessions.
- QuicDispatcher* CreateQuicDispatcher() override;
-
- // Sets a custom session factory, owned by the caller, for easy custom
- // session logic. This is incompatible with setting a stream factory or a
- // crypto stream factory.
- void SetSessionFactory(SessionFactory* factory);
-
- // Sets a custom stream factory, owned by the caller, for easy custom
- // stream logic. This is incompatible with setting a session factory.
- void SetSpdyStreamFactory(StreamFactory* factory);
-
- // Sets a custom crypto stream factory, owned by the caller, for easy custom
- // crypto logic. This is incompatible with setting a session factory.
- void SetCryptoStreamFactory(CryptoStreamFactory* factory);
-};
-
-// Useful test sessions for the QuicTestServer.
-
-// Test session which sends a GOAWAY immedaitely on creation, before crypto
-// credentials have even been established.
-class ImmediateGoAwaySession : public QuicSimpleServerSession {
- public:
- ImmediateGoAwaySession(const QuicConfig& config,
- QuicConnection* connection,
- QuicSession::Visitor* visitor,
- QuicCryptoServerStreamBase::Helper* helper,
- const QuicCryptoServerConfig* crypto_config,
- QuicCompressedCertsCache* compressed_certs_cache,
- QuicSimpleServerBackend* quic_simple_server_backend);
-
- // Override to send GoAway.
- void OnStreamFrame(const QuicStreamFrame& frame) override;
- void OnCryptoFrame(const QuicCryptoFrame& frame) override;
- void OnNewEncryptionKeyAvailable(
- EncryptionLevel level,
- std::unique_ptr<QuicEncrypter> encrypter) override;
-};
-
-} // namespace test
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_TEST_TOOLS_QUIC_TEST_SERVER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/quic_test_utils.cc b/chromium/net/third_party/quiche/src/quic/test_tools/quic_test_utils.cc
deleted file mode 100644
index 11497215bf1..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/quic_test_utils.cc
+++ /dev/null
@@ -1,1617 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/quic_test_utils.h"
-
-#include <algorithm>
-#include <cstdint>
-#include <memory>
-#include <utility>
-
-#include "absl/base/macros.h"
-#include "absl/strings/string_view.h"
-#include "third_party/boringssl/src/include/openssl/chacha.h"
-#include "third_party/boringssl/src/include/openssl/sha.h"
-#include "quic/core/crypto/crypto_framer.h"
-#include "quic/core/crypto/crypto_handshake.h"
-#include "quic/core/crypto/crypto_utils.h"
-#include "quic/core/crypto/null_decrypter.h"
-#include "quic/core/crypto/null_encrypter.h"
-#include "quic/core/crypto/quic_decrypter.h"
-#include "quic/core/crypto/quic_encrypter.h"
-#include "quic/core/http/quic_spdy_client_session.h"
-#include "quic/core/quic_buffer_allocator.h"
-#include "quic/core/quic_config.h"
-#include "quic/core/quic_data_writer.h"
-#include "quic/core/quic_framer.h"
-#include "quic/core/quic_packet_creator.h"
-#include "quic/core/quic_simple_buffer_allocator.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_utils.h"
-#include "quic/core/quic_versions.h"
-#include "quic/platform/api/quic_error_code_wrappers.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/test_tools/crypto_test_utils.h"
-#include "quic/test_tools/quic_config_peer.h"
-#include "quic/test_tools/quic_connection_peer.h"
-#include "common/quiche_endian.h"
-#include "spdy/core/spdy_frame_builder.h"
-
-using testing::_;
-using testing::Invoke;
-
-namespace quic {
-namespace test {
-
-QuicConnectionId TestConnectionId() {
- // Chosen by fair dice roll.
- // Guaranteed to be random.
- return TestConnectionId(42);
-}
-
-QuicConnectionId TestConnectionId(uint64_t connection_number) {
- const uint64_t connection_id64_net =
- quiche::QuicheEndian::HostToNet64(connection_number);
- return QuicConnectionId(reinterpret_cast<const char*>(&connection_id64_net),
- sizeof(connection_id64_net));
-}
-
-QuicConnectionId TestConnectionIdNineBytesLong(uint64_t connection_number) {
- const uint64_t connection_number_net =
- quiche::QuicheEndian::HostToNet64(connection_number);
- char connection_id_bytes[9] = {};
- static_assert(
- sizeof(connection_id_bytes) == 1 + sizeof(connection_number_net),
- "bad lengths");
- memcpy(connection_id_bytes + 1, &connection_number_net,
- sizeof(connection_number_net));
- return QuicConnectionId(connection_id_bytes, sizeof(connection_id_bytes));
-}
-
-uint64_t TestConnectionIdToUInt64(QuicConnectionId connection_id) {
- QUICHE_DCHECK_EQ(connection_id.length(), kQuicDefaultConnectionIdLength);
- uint64_t connection_id64_net = 0;
- memcpy(&connection_id64_net, connection_id.data(),
- std::min<size_t>(static_cast<size_t>(connection_id.length()),
- sizeof(connection_id64_net)));
- return quiche::QuicheEndian::NetToHost64(connection_id64_net);
-}
-
-std::vector<uint8_t> CreateStatelessResetTokenForTest() {
- static constexpr uint8_t kStatelessResetTokenDataForTest[16] = {
- 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
- 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F};
- return std::vector<uint8_t>(kStatelessResetTokenDataForTest,
- kStatelessResetTokenDataForTest +
- sizeof(kStatelessResetTokenDataForTest));
-}
-
-std::string TestHostname() { return "test.example.com"; }
-
-QuicServerId TestServerId() {
- return QuicServerId(TestHostname(), kTestPort);
-}
-
-QuicAckFrame InitAckFrame(const std::vector<QuicAckBlock>& ack_blocks) {
- QUICHE_DCHECK_GT(ack_blocks.size(), 0u);
-
- QuicAckFrame ack;
- QuicPacketNumber end_of_previous_block(1);
- for (const QuicAckBlock& block : ack_blocks) {
- QUICHE_DCHECK_GE(block.start, end_of_previous_block);
- QUICHE_DCHECK_GT(block.limit, block.start);
- ack.packets.AddRange(block.start, block.limit);
- end_of_previous_block = block.limit;
- }
-
- ack.largest_acked = ack.packets.Max();
-
- return ack;
-}
-
-QuicAckFrame InitAckFrame(uint64_t largest_acked) {
- return InitAckFrame(QuicPacketNumber(largest_acked));
-}
-
-QuicAckFrame InitAckFrame(QuicPacketNumber largest_acked) {
- return InitAckFrame({{QuicPacketNumber(1), largest_acked + 1}});
-}
-
-QuicAckFrame MakeAckFrameWithAckBlocks(size_t num_ack_blocks,
- uint64_t least_unacked) {
- QuicAckFrame ack;
- ack.largest_acked = QuicPacketNumber(2 * num_ack_blocks + least_unacked);
- // Add enough received packets to get num_ack_blocks ack blocks.
- for (QuicPacketNumber i = QuicPacketNumber(2);
- i < QuicPacketNumber(2 * num_ack_blocks + 1); i += 2) {
- ack.packets.Add(i + least_unacked);
- }
- return ack;
-}
-
-QuicAckFrame MakeAckFrameWithGaps(uint64_t gap_size,
- size_t max_num_gaps,
- uint64_t largest_acked) {
- QuicAckFrame ack;
- ack.largest_acked = QuicPacketNumber(largest_acked);
- ack.packets.Add(QuicPacketNumber(largest_acked));
- for (size_t i = 0; i < max_num_gaps; ++i) {
- if (largest_acked <= gap_size) {
- break;
- }
- largest_acked -= gap_size;
- ack.packets.Add(QuicPacketNumber(largest_acked));
- }
- return ack;
-}
-
-EncryptionLevel HeaderToEncryptionLevel(const QuicPacketHeader& header) {
- if (header.form == IETF_QUIC_SHORT_HEADER_PACKET) {
- return ENCRYPTION_FORWARD_SECURE;
- } else if (header.form == IETF_QUIC_LONG_HEADER_PACKET) {
- if (header.long_packet_type == HANDSHAKE) {
- return ENCRYPTION_HANDSHAKE;
- } else if (header.long_packet_type == ZERO_RTT_PROTECTED) {
- return ENCRYPTION_ZERO_RTT;
- }
- }
- return ENCRYPTION_INITIAL;
-}
-
-std::unique_ptr<QuicPacket> BuildUnsizedDataPacket(
- QuicFramer* framer,
- const QuicPacketHeader& header,
- const QuicFrames& frames) {
- const size_t max_plaintext_size =
- framer->GetMaxPlaintextSize(kMaxOutgoingPacketSize);
- size_t packet_size = GetPacketHeaderSize(framer->transport_version(), header);
- for (size_t i = 0; i < frames.size(); ++i) {
- QUICHE_DCHECK_LE(packet_size, max_plaintext_size);
- bool first_frame = i == 0;
- bool last_frame = i == frames.size() - 1;
- const size_t frame_size = framer->GetSerializedFrameLength(
- frames[i], max_plaintext_size - packet_size, first_frame, last_frame,
- header.packet_number_length);
- QUICHE_DCHECK(frame_size);
- packet_size += frame_size;
- }
- return BuildUnsizedDataPacket(framer, header, frames, packet_size);
-}
-
-std::unique_ptr<QuicPacket> BuildUnsizedDataPacket(
- QuicFramer* framer,
- const QuicPacketHeader& header,
- const QuicFrames& frames,
- size_t packet_size) {
- char* buffer = new char[packet_size];
- EncryptionLevel level = HeaderToEncryptionLevel(header);
- size_t length =
- framer->BuildDataPacket(header, frames, buffer, packet_size, level);
-
- if (length == 0) {
- delete[] buffer;
- return nullptr;
- }
- // Re-construct the data packet with data ownership.
- return std::make_unique<QuicPacket>(
- buffer, length, /* owns_buffer */ true,
- GetIncludedDestinationConnectionIdLength(header),
- GetIncludedSourceConnectionIdLength(header), header.version_flag,
- header.nonce != nullptr, header.packet_number_length,
- header.retry_token_length_length, header.retry_token.length(),
- header.length_length);
-}
-
-std::string Sha1Hash(absl::string_view data) {
- char buffer[SHA_DIGEST_LENGTH];
- SHA1(reinterpret_cast<const uint8_t*>(data.data()), data.size(),
- reinterpret_cast<uint8_t*>(buffer));
- return std::string(buffer, ABSL_ARRAYSIZE(buffer));
-}
-
-bool ClearControlFrame(const QuicFrame& frame) {
- DeleteFrame(&const_cast<QuicFrame&>(frame));
- return true;
-}
-
-bool ClearControlFrameWithTransmissionType(const QuicFrame& frame,
- TransmissionType /*type*/) {
- return ClearControlFrame(frame);
-}
-
-uint64_t SimpleRandom::RandUint64() {
- uint64_t result;
- RandBytes(&result, sizeof(result));
- return result;
-}
-
-void SimpleRandom::RandBytes(void* data, size_t len) {
- uint8_t* data_bytes = reinterpret_cast<uint8_t*>(data);
- while (len > 0) {
- const size_t buffer_left = sizeof(buffer_) - buffer_offset_;
- const size_t to_copy = std::min(buffer_left, len);
- memcpy(data_bytes, buffer_ + buffer_offset_, to_copy);
- data_bytes += to_copy;
- buffer_offset_ += to_copy;
- len -= to_copy;
-
- if (buffer_offset_ == sizeof(buffer_)) {
- FillBuffer();
- }
- }
-}
-
-void SimpleRandom::InsecureRandBytes(void* data, size_t len) {
- RandBytes(data, len);
-}
-
-uint64_t SimpleRandom::InsecureRandUint64() {
- return RandUint64();
-}
-
-void SimpleRandom::FillBuffer() {
- uint8_t nonce[12];
- memcpy(nonce, buffer_, sizeof(nonce));
- CRYPTO_chacha_20(buffer_, buffer_, sizeof(buffer_), key_, nonce, 0);
- buffer_offset_ = 0;
-}
-
-void SimpleRandom::set_seed(uint64_t seed) {
- static_assert(sizeof(key_) == SHA256_DIGEST_LENGTH, "Key has to be 256 bits");
- SHA256(reinterpret_cast<const uint8_t*>(&seed), sizeof(seed), key_);
-
- memset(buffer_, 0, sizeof(buffer_));
- FillBuffer();
-}
-
-MockFramerVisitor::MockFramerVisitor() {
- // By default, we want to accept packets.
- ON_CALL(*this, OnProtocolVersionMismatch(_))
- .WillByDefault(testing::Return(false));
-
- // By default, we want to accept packets.
- ON_CALL(*this, OnUnauthenticatedHeader(_))
- .WillByDefault(testing::Return(true));
-
- ON_CALL(*this, OnUnauthenticatedPublicHeader(_))
- .WillByDefault(testing::Return(true));
-
- ON_CALL(*this, OnPacketHeader(_)).WillByDefault(testing::Return(true));
-
- ON_CALL(*this, OnStreamFrame(_)).WillByDefault(testing::Return(true));
-
- ON_CALL(*this, OnCryptoFrame(_)).WillByDefault(testing::Return(true));
-
- ON_CALL(*this, OnStopWaitingFrame(_)).WillByDefault(testing::Return(true));
-
- ON_CALL(*this, OnPaddingFrame(_)).WillByDefault(testing::Return(true));
-
- ON_CALL(*this, OnPingFrame(_)).WillByDefault(testing::Return(true));
-
- ON_CALL(*this, OnRstStreamFrame(_)).WillByDefault(testing::Return(true));
-
- ON_CALL(*this, OnConnectionCloseFrame(_))
- .WillByDefault(testing::Return(true));
-
- ON_CALL(*this, OnStopSendingFrame(_)).WillByDefault(testing::Return(true));
-
- ON_CALL(*this, OnPathChallengeFrame(_)).WillByDefault(testing::Return(true));
-
- ON_CALL(*this, OnPathResponseFrame(_)).WillByDefault(testing::Return(true));
-
- ON_CALL(*this, OnGoAwayFrame(_)).WillByDefault(testing::Return(true));
- ON_CALL(*this, OnMaxStreamsFrame(_)).WillByDefault(testing::Return(true));
- ON_CALL(*this, OnStreamsBlockedFrame(_)).WillByDefault(testing::Return(true));
-}
-
-MockFramerVisitor::~MockFramerVisitor() {}
-
-bool NoOpFramerVisitor::OnProtocolVersionMismatch(
- ParsedQuicVersion /*version*/) {
- return false;
-}
-
-bool NoOpFramerVisitor::OnUnauthenticatedPublicHeader(
- const QuicPacketHeader& /*header*/) {
- return true;
-}
-
-bool NoOpFramerVisitor::OnUnauthenticatedHeader(
- const QuicPacketHeader& /*header*/) {
- return true;
-}
-
-bool NoOpFramerVisitor::OnPacketHeader(const QuicPacketHeader& /*header*/) {
- return true;
-}
-
-void NoOpFramerVisitor::OnCoalescedPacket(
- const QuicEncryptedPacket& /*packet*/) {}
-
-void NoOpFramerVisitor::OnUndecryptablePacket(
- const QuicEncryptedPacket& /*packet*/,
- EncryptionLevel /*decryption_level*/,
- bool /*has_decryption_key*/) {}
-
-bool NoOpFramerVisitor::OnStreamFrame(const QuicStreamFrame& /*frame*/) {
- return true;
-}
-
-bool NoOpFramerVisitor::OnCryptoFrame(const QuicCryptoFrame& /*frame*/) {
- return true;
-}
-
-bool NoOpFramerVisitor::OnAckFrameStart(QuicPacketNumber /*largest_acked*/,
- QuicTime::Delta /*ack_delay_time*/) {
- return true;
-}
-
-bool NoOpFramerVisitor::OnAckRange(QuicPacketNumber /*start*/,
- QuicPacketNumber /*end*/) {
- return true;
-}
-
-bool NoOpFramerVisitor::OnAckTimestamp(QuicPacketNumber /*packet_number*/,
- QuicTime /*timestamp*/) {
- return true;
-}
-
-bool NoOpFramerVisitor::OnAckFrameEnd(QuicPacketNumber /*start*/) {
- return true;
-}
-
-bool NoOpFramerVisitor::OnStopWaitingFrame(
- const QuicStopWaitingFrame& /*frame*/) {
- return true;
-}
-
-bool NoOpFramerVisitor::OnPaddingFrame(const QuicPaddingFrame& /*frame*/) {
- return true;
-}
-
-bool NoOpFramerVisitor::OnPingFrame(const QuicPingFrame& /*frame*/) {
- return true;
-}
-
-bool NoOpFramerVisitor::OnRstStreamFrame(const QuicRstStreamFrame& /*frame*/) {
- return true;
-}
-
-bool NoOpFramerVisitor::OnConnectionCloseFrame(
- const QuicConnectionCloseFrame& /*frame*/) {
- return true;
-}
-
-bool NoOpFramerVisitor::OnNewConnectionIdFrame(
- const QuicNewConnectionIdFrame& /*frame*/) {
- return true;
-}
-
-bool NoOpFramerVisitor::OnRetireConnectionIdFrame(
- const QuicRetireConnectionIdFrame& /*frame*/) {
- return true;
-}
-
-bool NoOpFramerVisitor::OnNewTokenFrame(const QuicNewTokenFrame& /*frame*/) {
- return true;
-}
-
-bool NoOpFramerVisitor::OnStopSendingFrame(
- const QuicStopSendingFrame& /*frame*/) {
- return true;
-}
-
-bool NoOpFramerVisitor::OnPathChallengeFrame(
- const QuicPathChallengeFrame& /*frame*/) {
- return true;
-}
-
-bool NoOpFramerVisitor::OnPathResponseFrame(
- const QuicPathResponseFrame& /*frame*/) {
- return true;
-}
-
-bool NoOpFramerVisitor::OnGoAwayFrame(const QuicGoAwayFrame& /*frame*/) {
- return true;
-}
-
-bool NoOpFramerVisitor::OnMaxStreamsFrame(
- const QuicMaxStreamsFrame& /*frame*/) {
- return true;
-}
-
-bool NoOpFramerVisitor::OnStreamsBlockedFrame(
- const QuicStreamsBlockedFrame& /*frame*/) {
- return true;
-}
-
-bool NoOpFramerVisitor::OnWindowUpdateFrame(
- const QuicWindowUpdateFrame& /*frame*/) {
- return true;
-}
-
-bool NoOpFramerVisitor::OnBlockedFrame(const QuicBlockedFrame& /*frame*/) {
- return true;
-}
-
-bool NoOpFramerVisitor::OnMessageFrame(const QuicMessageFrame& /*frame*/) {
- return true;
-}
-
-bool NoOpFramerVisitor::OnHandshakeDoneFrame(
- const QuicHandshakeDoneFrame& /*frame*/) {
- return true;
-}
-
-bool NoOpFramerVisitor::OnAckFrequencyFrame(
- const QuicAckFrequencyFrame& /*frame*/) {
- return true;
-}
-
-bool NoOpFramerVisitor::IsValidStatelessResetToken(
- const StatelessResetToken& /*token*/) const {
- return false;
-}
-
-MockQuicConnectionVisitor::MockQuicConnectionVisitor() {}
-
-MockQuicConnectionVisitor::~MockQuicConnectionVisitor() {}
-
-MockQuicConnectionHelper::MockQuicConnectionHelper() {}
-
-MockQuicConnectionHelper::~MockQuicConnectionHelper() {}
-
-const QuicClock* MockQuicConnectionHelper::GetClock() const {
- return &clock_;
-}
-
-QuicRandom* MockQuicConnectionHelper::GetRandomGenerator() {
- return &random_generator_;
-}
-
-QuicAlarm* MockAlarmFactory::CreateAlarm(QuicAlarm::Delegate* delegate) {
- return new MockAlarmFactory::TestAlarm(
- QuicArenaScopedPtr<QuicAlarm::Delegate>(delegate));
-}
-
-QuicArenaScopedPtr<QuicAlarm> MockAlarmFactory::CreateAlarm(
- QuicArenaScopedPtr<QuicAlarm::Delegate> delegate,
- QuicConnectionArena* arena) {
- if (arena != nullptr) {
- return arena->New<TestAlarm>(std::move(delegate));
- } else {
- return QuicArenaScopedPtr<TestAlarm>(new TestAlarm(std::move(delegate)));
- }
-}
-
-QuicBufferAllocator* MockQuicConnectionHelper::GetStreamSendBufferAllocator() {
- return &buffer_allocator_;
-}
-
-void MockQuicConnectionHelper::AdvanceTime(QuicTime::Delta delta) {
- clock_.AdvanceTime(delta);
-}
-
-MockQuicConnection::MockQuicConnection(MockQuicConnectionHelper* helper,
- MockAlarmFactory* alarm_factory,
- Perspective perspective)
- : MockQuicConnection(TestConnectionId(),
- QuicSocketAddress(TestPeerIPAddress(), kTestPort),
- helper,
- alarm_factory,
- perspective,
- ParsedVersionOfIndex(CurrentSupportedVersions(), 0)) {}
-
-MockQuicConnection::MockQuicConnection(QuicSocketAddress address,
- MockQuicConnectionHelper* helper,
- MockAlarmFactory* alarm_factory,
- Perspective perspective)
- : MockQuicConnection(TestConnectionId(),
- address,
- helper,
- alarm_factory,
- perspective,
- ParsedVersionOfIndex(CurrentSupportedVersions(), 0)) {}
-
-MockQuicConnection::MockQuicConnection(QuicConnectionId connection_id,
- MockQuicConnectionHelper* helper,
- MockAlarmFactory* alarm_factory,
- Perspective perspective)
- : MockQuicConnection(connection_id,
- QuicSocketAddress(TestPeerIPAddress(), kTestPort),
- helper,
- alarm_factory,
- perspective,
- ParsedVersionOfIndex(CurrentSupportedVersions(), 0)) {}
-
-MockQuicConnection::MockQuicConnection(
- MockQuicConnectionHelper* helper,
- MockAlarmFactory* alarm_factory,
- Perspective perspective,
- const ParsedQuicVersionVector& supported_versions)
- : MockQuicConnection(TestConnectionId(),
- QuicSocketAddress(TestPeerIPAddress(), kTestPort),
- helper,
- alarm_factory,
- perspective,
- supported_versions) {}
-
-MockQuicConnection::MockQuicConnection(
- QuicConnectionId connection_id,
- QuicSocketAddress initial_peer_address,
- MockQuicConnectionHelper* helper,
- MockAlarmFactory* alarm_factory,
- Perspective perspective,
- const ParsedQuicVersionVector& supported_versions)
- : QuicConnection(
- connection_id,
- /*initial_self_address=*/QuicSocketAddress(QuicIpAddress::Any4(), 5),
- initial_peer_address,
- helper,
- alarm_factory,
- new testing::NiceMock<MockPacketWriter>(),
- /* owns_writer= */ true,
- perspective,
- supported_versions) {
- ON_CALL(*this, OnError(_))
- .WillByDefault(
- Invoke(this, &PacketSavingConnection::QuicConnection_OnError));
- ON_CALL(*this, SendCryptoData(_, _, _))
- .WillByDefault(
- Invoke(this, &MockQuicConnection::QuicConnection_SendCryptoData));
-
- SetSelfAddress(QuicSocketAddress(QuicIpAddress::Any4(), 5));
-}
-
-MockQuicConnection::~MockQuicConnection() {}
-
-void MockQuicConnection::AdvanceTime(QuicTime::Delta delta) {
- static_cast<MockQuicConnectionHelper*>(helper())->AdvanceTime(delta);
-}
-
-bool MockQuicConnection::OnProtocolVersionMismatch(
- ParsedQuicVersion /*version*/) {
- return false;
-}
-
-PacketSavingConnection::PacketSavingConnection(MockQuicConnectionHelper* helper,
- MockAlarmFactory* alarm_factory,
- Perspective perspective)
- : MockQuicConnection(helper, alarm_factory, perspective) {}
-
-PacketSavingConnection::PacketSavingConnection(
- MockQuicConnectionHelper* helper,
- MockAlarmFactory* alarm_factory,
- Perspective perspective,
- const ParsedQuicVersionVector& supported_versions)
- : MockQuicConnection(helper,
- alarm_factory,
- perspective,
- supported_versions) {}
-
-PacketSavingConnection::~PacketSavingConnection() {}
-
-void PacketSavingConnection::SendOrQueuePacket(SerializedPacket packet) {
- encrypted_packets_.push_back(std::make_unique<QuicEncryptedPacket>(
- CopyBuffer(packet), packet.encrypted_length, true));
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
- // Transfer ownership of the packet to the SentPacketManager and the
- // ack notifier to the AckNotifierManager.
- OnPacketSent(packet.encryption_level, packet.transmission_type);
- QuicConnectionPeer::GetSentPacketManager(this)->OnPacketSent(
- &packet, clock_.ApproximateNow(), NOT_RETRANSMISSION,
- HAS_RETRANSMITTABLE_DATA, true);
-}
-
-MockQuicSession::MockQuicSession(QuicConnection* connection)
- : MockQuicSession(connection, true) {}
-
-MockQuicSession::MockQuicSession(QuicConnection* connection,
- bool create_mock_crypto_stream)
- : QuicSession(connection,
- nullptr,
- DefaultQuicConfig(),
- connection->supported_versions(),
- /*num_expected_unidirectional_static_streams = */ 0) {
- if (create_mock_crypto_stream) {
- crypto_stream_ = std::make_unique<MockQuicCryptoStream>(this);
- }
- ON_CALL(*this, WritevData(_, _, _, _, _, _))
- .WillByDefault(testing::Return(QuicConsumedData(0, false)));
-}
-
-MockQuicSession::~MockQuicSession() {
- DeleteConnection();
-}
-
-QuicCryptoStream* MockQuicSession::GetMutableCryptoStream() {
- return crypto_stream_.get();
-}
-
-const QuicCryptoStream* MockQuicSession::GetCryptoStream() const {
- return crypto_stream_.get();
-}
-
-void MockQuicSession::SetCryptoStream(QuicCryptoStream* crypto_stream) {
- crypto_stream_.reset(crypto_stream);
-}
-
-QuicConsumedData MockQuicSession::ConsumeData(
- QuicStreamId id,
- size_t write_length,
- QuicStreamOffset offset,
- StreamSendingState state,
- TransmissionType /*type*/,
- absl::optional<EncryptionLevel> /*level*/) {
- if (write_length > 0) {
- auto buf = std::make_unique<char[]>(write_length);
- QuicStream* stream = GetOrCreateStream(id);
- QUICHE_DCHECK(stream);
- QuicDataWriter writer(write_length, buf.get(), quiche::HOST_BYTE_ORDER);
- stream->WriteStreamData(offset, write_length, &writer);
- } else {
- QUICHE_DCHECK(state != NO_FIN);
- }
- return QuicConsumedData(write_length, state != NO_FIN);
-}
-
-MockQuicCryptoStream::MockQuicCryptoStream(QuicSession* session)
- : QuicCryptoStream(session), params_(new QuicCryptoNegotiatedParameters) {}
-
-MockQuicCryptoStream::~MockQuicCryptoStream() {}
-
-ssl_early_data_reason_t MockQuicCryptoStream::EarlyDataReason() const {
- return ssl_early_data_unknown;
-}
-
-bool MockQuicCryptoStream::encryption_established() const {
- return false;
-}
-
-bool MockQuicCryptoStream::one_rtt_keys_available() const {
- return false;
-}
-
-const QuicCryptoNegotiatedParameters&
-MockQuicCryptoStream::crypto_negotiated_params() const {
- return *params_;
-}
-
-CryptoMessageParser* MockQuicCryptoStream::crypto_message_parser() {
- return &crypto_framer_;
-}
-
-MockQuicSpdySession::MockQuicSpdySession(QuicConnection* connection)
- : MockQuicSpdySession(connection, true) {}
-
-MockQuicSpdySession::MockQuicSpdySession(QuicConnection* connection,
- bool create_mock_crypto_stream)
- : QuicSpdySession(connection,
- nullptr,
- DefaultQuicConfig(),
- connection->supported_versions()) {
- if (create_mock_crypto_stream) {
- crypto_stream_ = std::make_unique<MockQuicCryptoStream>(this);
- }
-
- ON_CALL(*this, WritevData(_, _, _, _, _, _))
- .WillByDefault(testing::Return(QuicConsumedData(0, false)));
-
- ON_CALL(*this, SendWindowUpdate(_, _))
- .WillByDefault([this](QuicStreamId id, QuicStreamOffset byte_offset) {
- return QuicSpdySession::SendWindowUpdate(id, byte_offset);
- });
-
- ON_CALL(*this, SendBlocked(_)).WillByDefault([this](QuicStreamId id) {
- return QuicSpdySession::SendBlocked(id);
- });
-
- ON_CALL(*this, OnCongestionWindowChange(_)).WillByDefault(testing::Return());
-}
-
-MockQuicSpdySession::~MockQuicSpdySession() {
- DeleteConnection();
-}
-
-QuicCryptoStream* MockQuicSpdySession::GetMutableCryptoStream() {
- return crypto_stream_.get();
-}
-
-const QuicCryptoStream* MockQuicSpdySession::GetCryptoStream() const {
- return crypto_stream_.get();
-}
-
-void MockQuicSpdySession::SetCryptoStream(QuicCryptoStream* crypto_stream) {
- crypto_stream_.reset(crypto_stream);
-}
-
-QuicConsumedData MockQuicSpdySession::ConsumeData(
- QuicStreamId id,
- size_t write_length,
- QuicStreamOffset offset,
- StreamSendingState state,
- TransmissionType /*type*/,
- absl::optional<EncryptionLevel> /*level*/) {
- if (write_length > 0) {
- auto buf = std::make_unique<char[]>(write_length);
- QuicStream* stream = GetOrCreateStream(id);
- QUICHE_DCHECK(stream);
- QuicDataWriter writer(write_length, buf.get(), quiche::HOST_BYTE_ORDER);
- stream->WriteStreamData(offset, write_length, &writer);
- } else {
- QUICHE_DCHECK(state != NO_FIN);
- }
- return QuicConsumedData(write_length, state != NO_FIN);
-}
-
-TestQuicSpdyServerSession::TestQuicSpdyServerSession(
- QuicConnection* connection,
- const QuicConfig& config,
- const ParsedQuicVersionVector& supported_versions,
- const QuicCryptoServerConfig* crypto_config,
- QuicCompressedCertsCache* compressed_certs_cache)
- : QuicServerSessionBase(config,
- supported_versions,
- connection,
- &visitor_,
- &helper_,
- crypto_config,
- compressed_certs_cache) {
- ON_CALL(helper_, CanAcceptClientHello(_, _, _, _, _))
- .WillByDefault(testing::Return(true));
-}
-
-TestQuicSpdyServerSession::~TestQuicSpdyServerSession() {
- DeleteConnection();
-}
-
-std::unique_ptr<QuicCryptoServerStreamBase>
-TestQuicSpdyServerSession::CreateQuicCryptoServerStream(
- const QuicCryptoServerConfig* crypto_config,
- QuicCompressedCertsCache* compressed_certs_cache) {
- return CreateCryptoServerStream(crypto_config, compressed_certs_cache, this,
- &helper_);
-}
-
-QuicCryptoServerStreamBase*
-TestQuicSpdyServerSession::GetMutableCryptoStream() {
- return QuicServerSessionBase::GetMutableCryptoStream();
-}
-
-const QuicCryptoServerStreamBase* TestQuicSpdyServerSession::GetCryptoStream()
- const {
- return QuicServerSessionBase::GetCryptoStream();
-}
-
-TestQuicSpdyClientSession::TestQuicSpdyClientSession(
- QuicConnection* connection,
- const QuicConfig& config,
- const ParsedQuicVersionVector& supported_versions,
- const QuicServerId& server_id,
- QuicCryptoClientConfig* crypto_config)
- : QuicSpdyClientSessionBase(connection,
- &push_promise_index_,
- config,
- supported_versions) {
- // TODO(b/153726130): Consider adding SetServerApplicationStateForResumption
- // calls in tests and set |has_application_state| to true.
- crypto_stream_ = std::make_unique<QuicCryptoClientStream>(
- server_id, this, crypto_test_utils::ProofVerifyContextForTesting(),
- crypto_config, this, /*has_application_state = */ false);
- Initialize();
- ON_CALL(*this, OnConfigNegotiated())
- .WillByDefault(
- Invoke(this, &TestQuicSpdyClientSession::RealOnConfigNegotiated));
-}
-
-TestQuicSpdyClientSession::~TestQuicSpdyClientSession() {}
-
-bool TestQuicSpdyClientSession::IsAuthorized(const std::string& /*authority*/) {
- return true;
-}
-
-QuicCryptoClientStream* TestQuicSpdyClientSession::GetMutableCryptoStream() {
- return crypto_stream_.get();
-}
-
-const QuicCryptoClientStream* TestQuicSpdyClientSession::GetCryptoStream()
- const {
- return crypto_stream_.get();
-}
-
-void TestQuicSpdyClientSession::RealOnConfigNegotiated() {
- QuicSpdyClientSessionBase::OnConfigNegotiated();
-}
-
-TestPushPromiseDelegate::TestPushPromiseDelegate(bool match)
- : match_(match), rendezvous_fired_(false), rendezvous_stream_(nullptr) {}
-
-bool TestPushPromiseDelegate::CheckVary(
- const spdy::SpdyHeaderBlock& /*client_request*/,
- const spdy::SpdyHeaderBlock& /*promise_request*/,
- const spdy::SpdyHeaderBlock& /*promise_response*/) {
- QUIC_DVLOG(1) << "match " << match_;
- return match_;
-}
-
-void TestPushPromiseDelegate::OnRendezvousResult(QuicSpdyStream* stream) {
- rendezvous_fired_ = true;
- rendezvous_stream_ = stream;
-}
-
-MockPacketWriter::MockPacketWriter() {
- ON_CALL(*this, GetMaxPacketSize(_))
- .WillByDefault(testing::Return(kMaxOutgoingPacketSize));
- ON_CALL(*this, IsBatchMode()).WillByDefault(testing::Return(false));
- ON_CALL(*this, GetNextWriteLocation(_, _))
- .WillByDefault(testing::Return(QuicPacketBuffer()));
- ON_CALL(*this, Flush())
- .WillByDefault(testing::Return(WriteResult(WRITE_STATUS_OK, 0)));
- ON_CALL(*this, SupportsReleaseTime()).WillByDefault(testing::Return(false));
-}
-
-MockPacketWriter::~MockPacketWriter() {}
-
-MockSendAlgorithm::MockSendAlgorithm() {
- ON_CALL(*this, PacingRate(_))
- .WillByDefault(testing::Return(QuicBandwidth::Zero()));
- ON_CALL(*this, BandwidthEstimate())
- .WillByDefault(testing::Return(QuicBandwidth::Zero()));
-}
-
-MockSendAlgorithm::~MockSendAlgorithm() {}
-
-MockLossAlgorithm::MockLossAlgorithm() {}
-
-MockLossAlgorithm::~MockLossAlgorithm() {}
-
-MockAckListener::MockAckListener() {}
-
-MockAckListener::~MockAckListener() {}
-
-MockNetworkChangeVisitor::MockNetworkChangeVisitor() {}
-
-MockNetworkChangeVisitor::~MockNetworkChangeVisitor() {}
-
-QuicIpAddress TestPeerIPAddress() {
- return QuicIpAddress::Loopback4();
-}
-
-ParsedQuicVersion QuicVersionMax() {
- return AllSupportedVersions().front();
-}
-
-ParsedQuicVersion QuicVersionMin() {
- return AllSupportedVersions().back();
-}
-
-void DisableQuicVersionsWithTls() {
- for (const ParsedQuicVersion& version : AllSupportedVersionsWithTls()) {
- QuicDisableVersion(version);
- }
-}
-
-QuicEncryptedPacket* ConstructEncryptedPacket(
- QuicConnectionId destination_connection_id,
- QuicConnectionId source_connection_id,
- bool version_flag,
- bool reset_flag,
- uint64_t packet_number,
- const std::string& data) {
- return ConstructEncryptedPacket(
- destination_connection_id, source_connection_id, version_flag, reset_flag,
- packet_number, data, CONNECTION_ID_PRESENT, CONNECTION_ID_ABSENT,
- PACKET_4BYTE_PACKET_NUMBER);
-}
-
-QuicEncryptedPacket* ConstructEncryptedPacket(
- QuicConnectionId destination_connection_id,
- QuicConnectionId source_connection_id,
- bool version_flag,
- bool reset_flag,
- uint64_t packet_number,
- const std::string& data,
- QuicConnectionIdIncluded destination_connection_id_included,
- QuicConnectionIdIncluded source_connection_id_included,
- QuicPacketNumberLength packet_number_length) {
- return ConstructEncryptedPacket(
- destination_connection_id, source_connection_id, version_flag, reset_flag,
- packet_number, data, destination_connection_id_included,
- source_connection_id_included, packet_number_length, nullptr);
-}
-
-QuicEncryptedPacket* ConstructEncryptedPacket(
- QuicConnectionId destination_connection_id,
- QuicConnectionId source_connection_id,
- bool version_flag,
- bool reset_flag,
- uint64_t packet_number,
- const std::string& data,
- QuicConnectionIdIncluded destination_connection_id_included,
- QuicConnectionIdIncluded source_connection_id_included,
- QuicPacketNumberLength packet_number_length,
- ParsedQuicVersionVector* versions) {
- return ConstructEncryptedPacket(
- destination_connection_id, source_connection_id, version_flag, reset_flag,
- packet_number, data, false, destination_connection_id_included,
- source_connection_id_included, packet_number_length, versions,
- Perspective::IS_CLIENT);
-}
-
-QuicEncryptedPacket* ConstructEncryptedPacket(
- QuicConnectionId destination_connection_id,
- QuicConnectionId source_connection_id,
- bool version_flag,
- bool reset_flag,
- uint64_t packet_number,
- const std::string& data,
- bool full_padding,
- QuicConnectionIdIncluded destination_connection_id_included,
- QuicConnectionIdIncluded source_connection_id_included,
- QuicPacketNumberLength packet_number_length,
- ParsedQuicVersionVector* versions) {
- return ConstructEncryptedPacket(
- destination_connection_id, source_connection_id, version_flag, reset_flag,
- packet_number, data, full_padding, destination_connection_id_included,
- source_connection_id_included, packet_number_length, versions,
- Perspective::IS_CLIENT);
-}
-
-QuicEncryptedPacket* ConstructEncryptedPacket(
- QuicConnectionId destination_connection_id,
- QuicConnectionId source_connection_id,
- bool version_flag,
- bool reset_flag,
- uint64_t packet_number,
- const std::string& data,
- bool full_padding,
- QuicConnectionIdIncluded destination_connection_id_included,
- QuicConnectionIdIncluded source_connection_id_included,
- QuicPacketNumberLength packet_number_length,
- ParsedQuicVersionVector* versions,
- Perspective perspective) {
- QuicPacketHeader header;
- header.destination_connection_id = destination_connection_id;
- header.destination_connection_id_included =
- destination_connection_id_included;
- header.source_connection_id = source_connection_id;
- header.source_connection_id_included = source_connection_id_included;
- header.version_flag = version_flag;
- header.reset_flag = reset_flag;
- header.packet_number_length = packet_number_length;
- header.packet_number = QuicPacketNumber(packet_number);
- ParsedQuicVersionVector supported_versions = CurrentSupportedVersions();
- if (!versions) {
- versions = &supported_versions;
- }
- EXPECT_FALSE(versions->empty());
- ParsedQuicVersion version = (*versions)[0];
- if (QuicVersionHasLongHeaderLengths(version.transport_version) &&
- version_flag) {
- header.retry_token_length_length = VARIABLE_LENGTH_INTEGER_LENGTH_1;
- header.length_length = VARIABLE_LENGTH_INTEGER_LENGTH_2;
- }
-
- QuicFrames frames;
- QuicFramer framer(*versions, QuicTime::Zero(), perspective,
- kQuicDefaultConnectionIdLength);
- framer.SetInitialObfuscators(destination_connection_id);
- EncryptionLevel level =
- header.version_flag ? ENCRYPTION_INITIAL : ENCRYPTION_FORWARD_SECURE;
- if (level != ENCRYPTION_INITIAL) {
- framer.SetEncrypter(level, std::make_unique<NullEncrypter>(perspective));
- }
- if (!QuicVersionUsesCryptoFrames(version.transport_version)) {
- QuicFrame frame(
- QuicStreamFrame(QuicUtils::GetCryptoStreamId(version.transport_version),
- false, 0, absl::string_view(data)));
- frames.push_back(frame);
- } else {
- QuicFrame frame(new QuicCryptoFrame(level, 0, data));
- frames.push_back(frame);
- }
- if (full_padding) {
- frames.push_back(QuicFrame(QuicPaddingFrame(-1)));
- } else {
- // We need a minimum number of bytes of encrypted payload. This will
- // guarantee that we have at least that much. (It ignores the overhead of
- // the stream/crypto framing, so it overpads slightly.)
- size_t min_plaintext_size =
- QuicPacketCreator::MinPlaintextPacketSize(version);
- if (data.length() < min_plaintext_size) {
- size_t padding_length = min_plaintext_size - data.length();
- frames.push_back(QuicFrame(QuicPaddingFrame(padding_length)));
- }
- }
-
- std::unique_ptr<QuicPacket> packet(
- BuildUnsizedDataPacket(&framer, header, frames));
- EXPECT_TRUE(packet != nullptr);
- char* buffer = new char[kMaxOutgoingPacketSize];
- size_t encrypted_length =
- framer.EncryptPayload(level, QuicPacketNumber(packet_number), *packet,
- buffer, kMaxOutgoingPacketSize);
- EXPECT_NE(0u, encrypted_length);
- DeleteFrames(&frames);
- return new QuicEncryptedPacket(buffer, encrypted_length, true);
-}
-
-std::unique_ptr<QuicEncryptedPacket> GetUndecryptableEarlyPacket(
- const ParsedQuicVersion& version,
- const QuicConnectionId& server_connection_id) {
- QuicPacketHeader header;
- header.destination_connection_id = server_connection_id;
- header.destination_connection_id_included = CONNECTION_ID_PRESENT;
- header.source_connection_id = EmptyQuicConnectionId();
- header.source_connection_id_included = CONNECTION_ID_PRESENT;
- if (!version.SupportsClientConnectionIds()) {
- header.source_connection_id_included = CONNECTION_ID_ABSENT;
- }
- header.version_flag = true;
- header.reset_flag = false;
- header.packet_number_length = PACKET_4BYTE_PACKET_NUMBER;
- header.packet_number = QuicPacketNumber(33);
- header.long_packet_type = ZERO_RTT_PROTECTED;
- if (version.HasLongHeaderLengths()) {
- header.retry_token_length_length = VARIABLE_LENGTH_INTEGER_LENGTH_1;
- header.length_length = VARIABLE_LENGTH_INTEGER_LENGTH_2;
- }
-
- QuicFrames frames;
- frames.push_back(QuicFrame(QuicPingFrame()));
- frames.push_back(QuicFrame(QuicPaddingFrame(100)));
- QuicFramer framer({version}, QuicTime::Zero(), Perspective::IS_CLIENT,
- kQuicDefaultConnectionIdLength);
- framer.SetInitialObfuscators(server_connection_id);
-
- framer.SetEncrypter(ENCRYPTION_ZERO_RTT,
- std::make_unique<NullEncrypter>(Perspective::IS_CLIENT));
- std::unique_ptr<QuicPacket> packet(
- BuildUnsizedDataPacket(&framer, header, frames));
- EXPECT_TRUE(packet != nullptr);
- char* buffer = new char[kMaxOutgoingPacketSize];
- size_t encrypted_length =
- framer.EncryptPayload(ENCRYPTION_ZERO_RTT, header.packet_number, *packet,
- buffer, kMaxOutgoingPacketSize);
- EXPECT_NE(0u, encrypted_length);
- DeleteFrames(&frames);
- return std::make_unique<QuicEncryptedPacket>(buffer, encrypted_length,
- /*owns_buffer=*/true);
-}
-
-QuicReceivedPacket* ConstructReceivedPacket(
- const QuicEncryptedPacket& encrypted_packet,
- QuicTime receipt_time) {
- char* buffer = new char[encrypted_packet.length()];
- memcpy(buffer, encrypted_packet.data(), encrypted_packet.length());
- return new QuicReceivedPacket(buffer, encrypted_packet.length(), receipt_time,
- true);
-}
-
-QuicEncryptedPacket* ConstructMisFramedEncryptedPacket(
- QuicConnectionId destination_connection_id,
- QuicConnectionId source_connection_id,
- bool version_flag,
- bool reset_flag,
- uint64_t packet_number,
- const std::string& data,
- QuicConnectionIdIncluded destination_connection_id_included,
- QuicConnectionIdIncluded source_connection_id_included,
- QuicPacketNumberLength packet_number_length,
- ParsedQuicVersion version,
- Perspective perspective) {
- QuicPacketHeader header;
- header.destination_connection_id = destination_connection_id;
- header.destination_connection_id_included =
- destination_connection_id_included;
- header.source_connection_id = source_connection_id;
- header.source_connection_id_included = source_connection_id_included;
- header.version_flag = version_flag;
- header.reset_flag = reset_flag;
- header.packet_number_length = packet_number_length;
- header.packet_number = QuicPacketNumber(packet_number);
- if (QuicVersionHasLongHeaderLengths(version.transport_version) &&
- version_flag) {
- header.retry_token_length_length = VARIABLE_LENGTH_INTEGER_LENGTH_1;
- header.length_length = VARIABLE_LENGTH_INTEGER_LENGTH_2;
- }
- QuicFrame frame(QuicStreamFrame(1, false, 0, absl::string_view(data)));
- QuicFrames frames;
- frames.push_back(frame);
- QuicFramer framer({version}, QuicTime::Zero(), perspective,
- kQuicDefaultConnectionIdLength);
- framer.SetInitialObfuscators(destination_connection_id);
- EncryptionLevel level =
- version_flag ? ENCRYPTION_INITIAL : ENCRYPTION_FORWARD_SECURE;
- if (level != ENCRYPTION_INITIAL) {
- framer.SetEncrypter(level, std::make_unique<NullEncrypter>(perspective));
- }
- // We need a minimum of 7 bytes of encrypted payload. This will guarantee that
- // we have at least that much. (It ignores the overhead of the stream/crypto
- // framing, so it overpads slightly.)
- if (data.length() < 7) {
- size_t padding_length = 7 - data.length();
- frames.push_back(QuicFrame(QuicPaddingFrame(padding_length)));
- }
-
- std::unique_ptr<QuicPacket> packet(
- BuildUnsizedDataPacket(&framer, header, frames));
- EXPECT_TRUE(packet != nullptr);
-
- // Now set the frame type to 0x1F, which is an invalid frame type.
- reinterpret_cast<unsigned char*>(
- packet->mutable_data())[GetStartOfEncryptedData(
- framer.transport_version(),
- GetIncludedDestinationConnectionIdLength(header),
- GetIncludedSourceConnectionIdLength(header), version_flag,
- false /* no diversification nonce */, packet_number_length,
- header.retry_token_length_length, 0, header.length_length)] = 0x1F;
-
- char* buffer = new char[kMaxOutgoingPacketSize];
- size_t encrypted_length =
- framer.EncryptPayload(level, QuicPacketNumber(packet_number), *packet,
- buffer, kMaxOutgoingPacketSize);
- EXPECT_NE(0u, encrypted_length);
- return new QuicEncryptedPacket(buffer, encrypted_length, true);
-}
-
-QuicConfig DefaultQuicConfig() {
- QuicConfig config;
- config.SetInitialMaxStreamDataBytesIncomingBidirectionalToSend(
- kInitialStreamFlowControlWindowForTest);
- config.SetInitialMaxStreamDataBytesOutgoingBidirectionalToSend(
- kInitialStreamFlowControlWindowForTest);
- config.SetInitialMaxStreamDataBytesUnidirectionalToSend(
- kInitialStreamFlowControlWindowForTest);
- config.SetInitialStreamFlowControlWindowToSend(
- kInitialStreamFlowControlWindowForTest);
- config.SetInitialSessionFlowControlWindowToSend(
- kInitialSessionFlowControlWindowForTest);
- QuicConfigPeer::SetReceivedMaxBidirectionalStreams(
- &config, kDefaultMaxStreamsPerConnection);
- // Default enable NSTP.
- // This is unnecessary for versions > 44
- if (!config.HasClientSentConnectionOption(quic::kNSTP,
- quic::Perspective::IS_CLIENT)) {
- quic::QuicTagVector connection_options;
- connection_options.push_back(quic::kNSTP);
- config.SetConnectionOptionsToSend(connection_options);
- }
- return config;
-}
-
-ParsedQuicVersionVector SupportedVersions(ParsedQuicVersion version) {
- ParsedQuicVersionVector versions;
- versions.push_back(version);
- return versions;
-}
-
-MockQuicConnectionDebugVisitor::MockQuicConnectionDebugVisitor() {}
-
-MockQuicConnectionDebugVisitor::~MockQuicConnectionDebugVisitor() {}
-
-MockReceivedPacketManager::MockReceivedPacketManager(QuicConnectionStats* stats)
- : QuicReceivedPacketManager(stats) {}
-
-MockReceivedPacketManager::~MockReceivedPacketManager() {}
-
-MockPacketCreatorDelegate::MockPacketCreatorDelegate() {}
-MockPacketCreatorDelegate::~MockPacketCreatorDelegate() {}
-
-MockSessionNotifier::MockSessionNotifier() {}
-MockSessionNotifier::~MockSessionNotifier() {}
-
-// static
-QuicCryptoClientStream::HandshakerInterface*
-QuicCryptoClientStreamPeer::GetHandshaker(QuicCryptoClientStream* stream) {
- return stream->handshaker_.get();
-}
-
-void CreateClientSessionForTest(
- QuicServerId server_id,
- QuicTime::Delta connection_start_time,
- const ParsedQuicVersionVector& supported_versions,
- MockQuicConnectionHelper* helper,
- MockAlarmFactory* alarm_factory,
- QuicCryptoClientConfig* crypto_client_config,
- PacketSavingConnection** client_connection,
- TestQuicSpdyClientSession** client_session) {
- QUICHE_CHECK(crypto_client_config);
- QUICHE_CHECK(client_connection);
- QUICHE_CHECK(client_session);
- QUICHE_CHECK(!connection_start_time.IsZero())
- << "Connections must start at non-zero times, otherwise the "
- << "strike-register will be unhappy.";
-
- QuicConfig config = DefaultQuicConfig();
- *client_connection = new PacketSavingConnection(
- helper, alarm_factory, Perspective::IS_CLIENT, supported_versions);
- *client_session = new TestQuicSpdyClientSession(*client_connection, config,
- supported_versions, server_id,
- crypto_client_config);
- (*client_connection)->AdvanceTime(connection_start_time);
-}
-
-void CreateServerSessionForTest(
- QuicServerId /*server_id*/,
- QuicTime::Delta connection_start_time,
- ParsedQuicVersionVector supported_versions,
- MockQuicConnectionHelper* helper,
- MockAlarmFactory* alarm_factory,
- QuicCryptoServerConfig* server_crypto_config,
- QuicCompressedCertsCache* compressed_certs_cache,
- PacketSavingConnection** server_connection,
- TestQuicSpdyServerSession** server_session) {
- QUICHE_CHECK(server_crypto_config);
- QUICHE_CHECK(server_connection);
- QUICHE_CHECK(server_session);
- QUICHE_CHECK(!connection_start_time.IsZero())
- << "Connections must start at non-zero times, otherwise the "
- << "strike-register will be unhappy.";
-
- *server_connection =
- new PacketSavingConnection(helper, alarm_factory, Perspective::IS_SERVER,
- ParsedVersionOfIndex(supported_versions, 0));
- *server_session = new TestQuicSpdyServerSession(
- *server_connection, DefaultQuicConfig(), supported_versions,
- server_crypto_config, compressed_certs_cache);
- (*server_session)->Initialize();
-
- // We advance the clock initially because the default time is zero and the
- // strike register worries that we've just overflowed a uint32_t time.
- (*server_connection)->AdvanceTime(connection_start_time);
-}
-
-QuicStreamId GetNthClientInitiatedBidirectionalStreamId(
- QuicTransportVersion version,
- int n) {
- int num = n;
- if (!VersionUsesHttp3(version)) {
- num++;
- }
- return QuicUtils::GetFirstBidirectionalStreamId(version,
- Perspective::IS_CLIENT) +
- QuicUtils::StreamIdDelta(version) * num;
-}
-
-QuicStreamId GetNthServerInitiatedBidirectionalStreamId(
- QuicTransportVersion version,
- int n) {
- return QuicUtils::GetFirstBidirectionalStreamId(version,
- Perspective::IS_SERVER) +
- QuicUtils::StreamIdDelta(version) * n;
-}
-
-QuicStreamId GetNthServerInitiatedUnidirectionalStreamId(
- QuicTransportVersion version,
- int n) {
- return QuicUtils::GetFirstUnidirectionalStreamId(version,
- Perspective::IS_SERVER) +
- QuicUtils::StreamIdDelta(version) * n;
-}
-
-QuicStreamId GetNthClientInitiatedUnidirectionalStreamId(
- QuicTransportVersion version,
- int n) {
- return QuicUtils::GetFirstUnidirectionalStreamId(version,
- Perspective::IS_CLIENT) +
- QuicUtils::StreamIdDelta(version) * n;
-}
-
-StreamType DetermineStreamType(QuicStreamId id,
- ParsedQuicVersion version,
- Perspective perspective,
- bool is_incoming,
- StreamType default_type) {
- return version.HasIetfQuicFrames()
- ? QuicUtils::GetStreamType(id, perspective, is_incoming, version)
- : default_type;
-}
-
-QuicMemSlice MemSliceFromString(absl::string_view data) {
- if (data.empty()) {
- return QuicMemSlice();
- }
-
- static SimpleBufferAllocator* allocator = new SimpleBufferAllocator();
- return QuicMemSlice(QuicBuffer::Copy(allocator, data));
-}
-
-bool TaggingEncrypter::EncryptPacket(uint64_t /*packet_number*/,
- absl::string_view /*associated_data*/,
- absl::string_view plaintext,
- char* output,
- size_t* output_length,
- size_t max_output_length) {
- const size_t len = plaintext.size() + kTagSize;
- if (max_output_length < len) {
- return false;
- }
- // Memmove is safe for inplace encryption.
- memmove(output, plaintext.data(), plaintext.size());
- output += plaintext.size();
- memset(output, tag_, kTagSize);
- *output_length = len;
- return true;
-}
-
-bool TaggingDecrypter::DecryptPacket(uint64_t /*packet_number*/,
- absl::string_view /*associated_data*/,
- absl::string_view ciphertext,
- char* output,
- size_t* output_length,
- size_t /*max_output_length*/) {
- if (ciphertext.size() < kTagSize) {
- return false;
- }
- if (!CheckTag(ciphertext, GetTag(ciphertext))) {
- return false;
- }
- *output_length = ciphertext.size() - kTagSize;
- memcpy(output, ciphertext.data(), *output_length);
- return true;
-}
-
-bool TaggingDecrypter::CheckTag(absl::string_view ciphertext, uint8_t tag) {
- for (size_t i = ciphertext.size() - kTagSize; i < ciphertext.size(); i++) {
- if (ciphertext.data()[i] != tag) {
- return false;
- }
- }
-
- return true;
-}
-
-TestPacketWriter::TestPacketWriter(ParsedQuicVersion version,
- MockClock* clock,
- Perspective perspective)
- : version_(version),
- framer_(SupportedVersions(version_),
- QuicUtils::InvertPerspective(perspective)),
- clock_(clock) {
- QuicFramerPeer::SetLastSerializedServerConnectionId(framer_.framer(),
- TestConnectionId());
- framer_.framer()->SetInitialObfuscators(TestConnectionId());
-
- for (int i = 0; i < 128; ++i) {
- PacketBuffer* p = new PacketBuffer();
- packet_buffer_pool_.push_back(p);
- packet_buffer_pool_index_[p->buffer] = p;
- packet_buffer_free_list_.push_back(p);
- }
-}
-
-TestPacketWriter::~TestPacketWriter() {
- EXPECT_EQ(packet_buffer_pool_.size(), packet_buffer_free_list_.size())
- << packet_buffer_pool_.size() - packet_buffer_free_list_.size()
- << " out of " << packet_buffer_pool_.size()
- << " packet buffers have been leaked.";
- for (auto p : packet_buffer_pool_) {
- delete p;
- }
-}
-
-WriteResult TestPacketWriter::WritePacket(const char* buffer,
- size_t buf_len,
- const QuicIpAddress& self_address,
- const QuicSocketAddress& peer_address,
- PerPacketOptions* /*options*/) {
- last_write_source_address_ = self_address;
- last_write_peer_address_ = peer_address;
- // If the buffer is allocated from the pool, return it back to the pool.
- // Note the buffer content doesn't change.
- if (packet_buffer_pool_index_.find(const_cast<char*>(buffer)) !=
- packet_buffer_pool_index_.end()) {
- FreePacketBuffer(buffer);
- }
-
- QuicEncryptedPacket packet(buffer, buf_len);
- ++packets_write_attempts_;
-
- if (packet.length() >= sizeof(final_bytes_of_last_packet_)) {
- final_bytes_of_previous_packet_ = final_bytes_of_last_packet_;
- memcpy(&final_bytes_of_last_packet_, packet.data() + packet.length() - 4,
- sizeof(final_bytes_of_last_packet_));
- }
-
- if (use_tagging_decrypter_) {
- if (framer_.framer()->version().KnowsWhichDecrypterToUse()) {
- framer_.framer()->InstallDecrypter(ENCRYPTION_INITIAL,
- std::make_unique<TaggingDecrypter>());
- framer_.framer()->InstallDecrypter(ENCRYPTION_HANDSHAKE,
- std::make_unique<TaggingDecrypter>());
- framer_.framer()->InstallDecrypter(ENCRYPTION_ZERO_RTT,
- std::make_unique<TaggingDecrypter>());
- framer_.framer()->InstallDecrypter(ENCRYPTION_FORWARD_SECURE,
- std::make_unique<TaggingDecrypter>());
- } else {
- framer_.framer()->SetDecrypter(ENCRYPTION_INITIAL,
- std::make_unique<TaggingDecrypter>());
- }
- } else if (framer_.framer()->version().KnowsWhichDecrypterToUse()) {
- framer_.framer()->InstallDecrypter(
- ENCRYPTION_HANDSHAKE,
- std::make_unique<NullDecrypter>(framer_.framer()->perspective()));
- framer_.framer()->InstallDecrypter(
- ENCRYPTION_ZERO_RTT,
- std::make_unique<NullDecrypter>(framer_.framer()->perspective()));
- framer_.framer()->InstallDecrypter(
- ENCRYPTION_FORWARD_SECURE,
- std::make_unique<NullDecrypter>(framer_.framer()->perspective()));
- }
- EXPECT_TRUE(framer_.ProcessPacket(packet))
- << framer_.framer()->detailed_error() << " perspective "
- << framer_.framer()->perspective();
- if (block_on_next_write_) {
- write_blocked_ = true;
- block_on_next_write_ = false;
- }
- if (next_packet_too_large_) {
- next_packet_too_large_ = false;
- return WriteResult(WRITE_STATUS_ERROR, QUIC_EMSGSIZE);
- }
- if (always_get_packet_too_large_) {
- return WriteResult(WRITE_STATUS_ERROR, QUIC_EMSGSIZE);
- }
- if (IsWriteBlocked()) {
- return WriteResult(is_write_blocked_data_buffered_
- ? WRITE_STATUS_BLOCKED_DATA_BUFFERED
- : WRITE_STATUS_BLOCKED,
- 0);
- }
-
- if (ShouldWriteFail()) {
- return WriteResult(WRITE_STATUS_ERROR, write_error_code_);
- }
-
- last_packet_size_ = packet.length();
- last_packet_header_ = framer_.header();
- if (!framer_.connection_close_frames().empty()) {
- ++connection_close_packets_;
- }
- if (!write_pause_time_delta_.IsZero()) {
- clock_->AdvanceTime(write_pause_time_delta_);
- }
- if (is_batch_mode_) {
- bytes_buffered_ += last_packet_size_;
- return WriteResult(WRITE_STATUS_OK, 0);
- }
- return WriteResult(WRITE_STATUS_OK, last_packet_size_);
-}
-
-QuicPacketBuffer TestPacketWriter::GetNextWriteLocation(
- const QuicIpAddress& /*self_address*/,
- const QuicSocketAddress& /*peer_address*/) {
- return {AllocPacketBuffer(), [this](const char* p) { FreePacketBuffer(p); }};
-}
-
-WriteResult TestPacketWriter::Flush() {
- flush_attempts_++;
- if (block_on_next_flush_) {
- block_on_next_flush_ = false;
- SetWriteBlocked();
- return WriteResult(WRITE_STATUS_BLOCKED, /*errno*/ -1);
- }
- if (write_should_fail_) {
- return WriteResult(WRITE_STATUS_ERROR, /*errno*/ -1);
- }
- int bytes_flushed = bytes_buffered_;
- bytes_buffered_ = 0;
- return WriteResult(WRITE_STATUS_OK, bytes_flushed);
-}
-
-char* TestPacketWriter::AllocPacketBuffer() {
- PacketBuffer* p = packet_buffer_free_list_.front();
- EXPECT_FALSE(p->in_use);
- p->in_use = true;
- packet_buffer_free_list_.pop_front();
- return p->buffer;
-}
-
-void TestPacketWriter::FreePacketBuffer(const char* buffer) {
- auto iter = packet_buffer_pool_index_.find(const_cast<char*>(buffer));
- ASSERT_TRUE(iter != packet_buffer_pool_index_.end());
- PacketBuffer* p = iter->second;
- ASSERT_TRUE(p->in_use);
- p->in_use = false;
- packet_buffer_free_list_.push_back(p);
-}
-
-bool WriteServerVersionNegotiationProbeResponse(
- char* packet_bytes,
- size_t* packet_length_out,
- const char* source_connection_id_bytes,
- uint8_t source_connection_id_length) {
- if (packet_bytes == nullptr) {
- QUIC_BUG(quic_bug_10256_1) << "Invalid packet_bytes";
- return false;
- }
- if (packet_length_out == nullptr) {
- QUIC_BUG(quic_bug_10256_2) << "Invalid packet_length_out";
- return false;
- }
- QuicConnectionId source_connection_id(source_connection_id_bytes,
- source_connection_id_length);
- std::unique_ptr<QuicEncryptedPacket> encrypted_packet =
- QuicFramer::BuildVersionNegotiationPacket(
- source_connection_id, EmptyQuicConnectionId(),
- /*ietf_quic=*/true, /*use_length_prefix=*/true,
- ParsedQuicVersionVector{});
- if (!encrypted_packet) {
- QUIC_BUG(quic_bug_10256_3) << "Failed to create version negotiation packet";
- return false;
- }
- if (*packet_length_out < encrypted_packet->length()) {
- QUIC_BUG(quic_bug_10256_4)
- << "Invalid *packet_length_out " << *packet_length_out << " < "
- << encrypted_packet->length();
- return false;
- }
- *packet_length_out = encrypted_packet->length();
- memcpy(packet_bytes, encrypted_packet->data(), *packet_length_out);
- return true;
-}
-
-bool ParseClientVersionNegotiationProbePacket(
- const char* packet_bytes,
- size_t packet_length,
- char* destination_connection_id_bytes,
- uint8_t* destination_connection_id_length_out) {
- if (packet_bytes == nullptr) {
- QUIC_BUG(quic_bug_10256_5) << "Invalid packet_bytes";
- return false;
- }
- if (packet_length < kMinPacketSizeForVersionNegotiation ||
- packet_length > 65535) {
- QUIC_BUG(quic_bug_10256_6) << "Invalid packet_length";
- return false;
- }
- if (destination_connection_id_bytes == nullptr) {
- QUIC_BUG(quic_bug_10256_7) << "Invalid destination_connection_id_bytes";
- return false;
- }
- if (destination_connection_id_length_out == nullptr) {
- QUIC_BUG(quic_bug_10256_8)
- << "Invalid destination_connection_id_length_out";
- return false;
- }
-
- QuicEncryptedPacket encrypted_packet(packet_bytes, packet_length);
- PacketHeaderFormat format;
- QuicLongHeaderType long_packet_type;
- bool version_present, has_length_prefix;
- QuicVersionLabel version_label;
- ParsedQuicVersion parsed_version = ParsedQuicVersion::Unsupported();
- QuicConnectionId destination_connection_id, source_connection_id;
- absl::optional<absl::string_view> retry_token;
- std::string detailed_error;
- QuicErrorCode error = QuicFramer::ParsePublicHeaderDispatcher(
- encrypted_packet,
- /*expected_destination_connection_id_length=*/0, &format,
- &long_packet_type, &version_present, &has_length_prefix, &version_label,
- &parsed_version, &destination_connection_id, &source_connection_id,
- &retry_token, &detailed_error);
- if (error != QUIC_NO_ERROR) {
- QUIC_BUG(quic_bug_10256_9) << "Failed to parse packet: " << detailed_error;
- return false;
- }
- if (!version_present) {
- QUIC_BUG(quic_bug_10256_10) << "Packet is not a long header";
- return false;
- }
- if (*destination_connection_id_length_out <
- destination_connection_id.length()) {
- QUIC_BUG(quic_bug_10256_11)
- << "destination_connection_id_length_out too small";
- return false;
- }
- *destination_connection_id_length_out = destination_connection_id.length();
- memcpy(destination_connection_id_bytes, destination_connection_id.data(),
- *destination_connection_id_length_out);
- return true;
-}
-
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/quic_test_utils.h b/chromium/net/third_party/quiche/src/quic/test_tools/quic_test_utils.h
deleted file mode 100644
index d8d09796162..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/quic_test_utils.h
+++ /dev/null
@@ -1,2043 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Common utilities for Quic tests
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_QUIC_TEST_UTILS_H_
-#define QUICHE_QUIC_TEST_TOOLS_QUIC_TEST_UTILS_H_
-
-#include <cstdint>
-#include <memory>
-#include <string>
-#include <utility>
-#include <vector>
-
-#include "absl/container/flat_hash_map.h"
-#include "absl/strings/str_cat.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/congestion_control/loss_detection_interface.h"
-#include "quic/core/congestion_control/send_algorithm_interface.h"
-#include "quic/core/crypto/transport_parameters.h"
-#include "quic/core/http/quic_client_push_promise_index.h"
-#include "quic/core/http/quic_server_session_base.h"
-#include "quic/core/http/quic_spdy_session.h"
-#include "quic/core/quic_connection.h"
-#include "quic/core/quic_connection_id.h"
-#include "quic/core/quic_error_codes.h"
-#include "quic/core/quic_framer.h"
-#include "quic/core/quic_packet_writer.h"
-#include "quic/core/quic_path_validator.h"
-#include "quic/core/quic_sent_packet_manager.h"
-#include "quic/core/quic_server_id.h"
-#include "quic/core/quic_simple_buffer_allocator.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_mem_slice_storage.h"
-#include "quic/platform/api/quic_socket_address.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/mock_clock.h"
-#include "quic/test_tools/mock_quic_session_visitor.h"
-#include "quic/test_tools/mock_random.h"
-#include "quic/test_tools/quic_framer_peer.h"
-#include "quic/test_tools/simple_quic_framer.h"
-
-namespace quic {
-
-namespace test {
-
-// A generic predictable connection ID suited for testing.
-QuicConnectionId TestConnectionId();
-
-// A generic predictable connection ID suited for testing, generated from a
-// given number, such as an index.
-QuicConnectionId TestConnectionId(uint64_t connection_number);
-
-// A generic predictable connection ID suited for testing, generated from a
-// given number, such as an index. Guaranteed to be 9 bytes long.
-QuicConnectionId TestConnectionIdNineBytesLong(uint64_t connection_number);
-
-// Extracts the connection number passed to TestConnectionId().
-uint64_t TestConnectionIdToUInt64(QuicConnectionId connection_id);
-
-enum : uint16_t { kTestPort = 12345 };
-enum : uint32_t {
- kMaxDatagramFrameSizeForTest = 1333,
- kMaxPacketSizeForTest = 9001,
- kInitialStreamFlowControlWindowForTest = 1024 * 1024, // 1 MB
- kInitialSessionFlowControlWindowForTest = 1536 * 1024, // 1.5 MB
-};
-
-enum : uint64_t {
- kAckDelayExponentForTest = 10,
- kMaxAckDelayForTest = 51, // ms
- kActiveConnectionIdLimitForTest = 52,
- kMinAckDelayUsForTest = 1000
-};
-
-// Create an arbitrary stateless reset token, same across multiple calls.
-std::vector<uint8_t> CreateStatelessResetTokenForTest();
-
-// A hostname useful for testing, returns "test.example.org".
-std::string TestHostname();
-
-// A server ID useful for testing, returns test.example.org:12345.
-QuicServerId TestServerId();
-
-// Returns the test peer IP address.
-QuicIpAddress TestPeerIPAddress();
-
-// Upper limit on versions we support.
-ParsedQuicVersion QuicVersionMax();
-
-// Lower limit on versions we support.
-ParsedQuicVersion QuicVersionMin();
-
-// Disables all flags that enable QUIC versions that use TLS.
-// This is only meant as a temporary measure to prevent some broken tests
-// from running with TLS.
-void DisableQuicVersionsWithTls();
-
-// Create an encrypted packet for testing.
-// If versions == nullptr, uses &AllSupportedVersions().
-// Note that the packet is encrypted with NullEncrypter, so to decrypt the
-// constructed packet, the framer must be set to use NullDecrypter.
-QuicEncryptedPacket* ConstructEncryptedPacket(
- QuicConnectionId destination_connection_id,
- QuicConnectionId source_connection_id, bool version_flag, bool reset_flag,
- uint64_t packet_number, const std::string& data, bool full_padding,
- QuicConnectionIdIncluded destination_connection_id_included,
- QuicConnectionIdIncluded source_connection_id_included,
- QuicPacketNumberLength packet_number_length,
- ParsedQuicVersionVector* versions, Perspective perspective);
-
-QuicEncryptedPacket* ConstructEncryptedPacket(
- QuicConnectionId destination_connection_id,
- QuicConnectionId source_connection_id, bool version_flag, bool reset_flag,
- uint64_t packet_number, const std::string& data, bool full_padding,
- QuicConnectionIdIncluded destination_connection_id_included,
- QuicConnectionIdIncluded source_connection_id_included,
- QuicPacketNumberLength packet_number_length,
- ParsedQuicVersionVector* versions);
-
-// Create an encrypted packet for testing.
-// If versions == nullptr, uses &AllSupportedVersions().
-// Note that the packet is encrypted with NullEncrypter, so to decrypt the
-// constructed packet, the framer must be set to use NullDecrypter.
-QuicEncryptedPacket* ConstructEncryptedPacket(
- QuicConnectionId destination_connection_id,
- QuicConnectionId source_connection_id, bool version_flag, bool reset_flag,
- uint64_t packet_number, const std::string& data,
- QuicConnectionIdIncluded destination_connection_id_included,
- QuicConnectionIdIncluded source_connection_id_included,
- QuicPacketNumberLength packet_number_length,
- ParsedQuicVersionVector* versions);
-
-// This form assumes |versions| == nullptr.
-QuicEncryptedPacket* ConstructEncryptedPacket(
- QuicConnectionId destination_connection_id,
- QuicConnectionId source_connection_id, bool version_flag, bool reset_flag,
- uint64_t packet_number, const std::string& data,
- QuicConnectionIdIncluded destination_connection_id_included,
- QuicConnectionIdIncluded source_connection_id_included,
- QuicPacketNumberLength packet_number_length);
-
-// This form assumes |connection_id_length| == PACKET_8BYTE_CONNECTION_ID,
-// |packet_number_length| == PACKET_4BYTE_PACKET_NUMBER and
-// |versions| == nullptr.
-QuicEncryptedPacket* ConstructEncryptedPacket(
- QuicConnectionId destination_connection_id,
- QuicConnectionId source_connection_id, bool version_flag, bool reset_flag,
- uint64_t packet_number, const std::string& data);
-
-// Creates a client-to-server ZERO-RTT packet that will fail to decrypt.
-std::unique_ptr<QuicEncryptedPacket> GetUndecryptableEarlyPacket(
- const ParsedQuicVersion& version,
- const QuicConnectionId& server_connection_id);
-
-// Constructs a received packet for testing. The caller must take ownership
-// of the returned pointer.
-QuicReceivedPacket* ConstructReceivedPacket(
- const QuicEncryptedPacket& encrypted_packet, QuicTime receipt_time);
-
-// Create an encrypted packet for testing whose data portion erroneous.
-// The specific way the data portion is erroneous is not specified, but
-// it is an error that QuicFramer detects.
-// Note that the packet is encrypted with NullEncrypter, so to decrypt the
-// constructed packet, the framer must be set to use NullDecrypter.
-QuicEncryptedPacket* ConstructMisFramedEncryptedPacket(
- QuicConnectionId destination_connection_id,
- QuicConnectionId source_connection_id, bool version_flag, bool reset_flag,
- uint64_t packet_number, const std::string& data,
- QuicConnectionIdIncluded destination_connection_id_included,
- QuicConnectionIdIncluded source_connection_id_included,
- QuicPacketNumberLength packet_number_length, ParsedQuicVersion version,
- Perspective perspective);
-
-// Returns QuicConfig set to default values.
-QuicConfig DefaultQuicConfig();
-
-ParsedQuicVersionVector SupportedVersions(ParsedQuicVersion version);
-
-struct QuicAckBlock {
- QuicPacketNumber start; // Included
- QuicPacketNumber limit; // Excluded
-};
-
-// Testing convenience method to construct a QuicAckFrame with arbitrary ack
-// blocks. Each block is given by a (closed-open) range of packet numbers. e.g.:
-// InitAckFrame({{1, 10}})
-// => 1 ack block acking packet numbers 1 to 9.
-//
-// InitAckFrame({{1, 2}, {3, 4}})
-// => 2 ack blocks acking packet 1 and 3. Packet 2 is missing.
-QuicAckFrame InitAckFrame(const std::vector<QuicAckBlock>& ack_blocks);
-
-// Testing convenience method to construct a QuicAckFrame with 1 ack block which
-// covers packet number range [1, |largest_acked| + 1).
-// Equivalent to InitAckFrame({{1, largest_acked + 1}})
-QuicAckFrame InitAckFrame(uint64_t largest_acked);
-QuicAckFrame InitAckFrame(QuicPacketNumber largest_acked);
-
-// Testing convenience method to construct a QuicAckFrame with |num_ack_blocks|
-// ack blocks of width 1 packet, starting from |least_unacked| + 2.
-QuicAckFrame MakeAckFrameWithAckBlocks(size_t num_ack_blocks,
- uint64_t least_unacked);
-
-// Testing convenice method to construct a QuicAckFrame with |largest_acked|,
-// ack blocks of width 1 packet and |gap_size|.
-QuicAckFrame MakeAckFrameWithGaps(uint64_t gap_size, size_t max_num_gaps,
- uint64_t largest_acked);
-
-// Returns the encryption level that corresponds to the header type in
-// |header|. If the header is for GOOGLE_QUIC_PACKET instead of an
-// IETF-invariants packet, this function returns ENCRYPTION_INITIAL.
-EncryptionLevel HeaderToEncryptionLevel(const QuicPacketHeader& header);
-
-// Returns a QuicPacket that is owned by the caller, and
-// is populated with the fields in |header| and |frames|, or is nullptr if the
-// packet could not be created.
-std::unique_ptr<QuicPacket> BuildUnsizedDataPacket(
- QuicFramer* framer, const QuicPacketHeader& header,
- const QuicFrames& frames);
-// Returns a QuicPacket that is owned by the caller, and of size |packet_size|.
-std::unique_ptr<QuicPacket> BuildUnsizedDataPacket(
- QuicFramer* framer, const QuicPacketHeader& header,
- const QuicFrames& frames, size_t packet_size);
-
-// Compute SHA-1 hash of the supplied std::string.
-std::string Sha1Hash(absl::string_view data);
-
-// Delete |frame| and return true.
-bool ClearControlFrame(const QuicFrame& frame);
-bool ClearControlFrameWithTransmissionType(const QuicFrame& frame,
- TransmissionType type);
-
-// Simple random number generator used to compute random numbers suitable
-// for pseudo-randomly dropping packets in tests.
-class SimpleRandom : public QuicRandom {
- public:
- SimpleRandom() { set_seed(0); }
- SimpleRandom(const SimpleRandom&) = delete;
- SimpleRandom& operator=(const SimpleRandom&) = delete;
- ~SimpleRandom() override {}
-
- // Generates |len| random bytes in the |data| buffer.
- void RandBytes(void* data, size_t len) override;
- // Returns a random number in the range [0, kuint64max].
- uint64_t RandUint64() override;
-
- // InsecureRandBytes behaves equivalently to RandBytes.
- void InsecureRandBytes(void* data, size_t len) override;
- // InsecureRandUint64 behaves equivalently to RandUint64.
- uint64_t InsecureRandUint64() override;
-
- void set_seed(uint64_t seed);
-
- private:
- uint8_t buffer_[4096];
- size_t buffer_offset_ = 0;
- uint8_t key_[32];
-
- void FillBuffer();
-};
-
-class MockFramerVisitor : public QuicFramerVisitorInterface {
- public:
- MockFramerVisitor();
- MockFramerVisitor(const MockFramerVisitor&) = delete;
- MockFramerVisitor& operator=(const MockFramerVisitor&) = delete;
- ~MockFramerVisitor() override;
-
- MOCK_METHOD(void, OnError, (QuicFramer*), (override));
- // The constructor sets this up to return false by default.
- MOCK_METHOD(bool, OnProtocolVersionMismatch, (ParsedQuicVersion version),
- (override));
- MOCK_METHOD(void, OnPacket, (), (override));
- MOCK_METHOD(void, OnPublicResetPacket, (const QuicPublicResetPacket& header),
- (override));
- MOCK_METHOD(void, OnVersionNegotiationPacket,
- (const QuicVersionNegotiationPacket& packet), (override));
- MOCK_METHOD(void, OnRetryPacket,
- (QuicConnectionId original_connection_id,
- QuicConnectionId new_connection_id,
- absl::string_view retry_token,
- absl::string_view retry_integrity_tag,
- absl::string_view retry_without_tag),
- (override));
- // The constructor sets this up to return true by default.
- MOCK_METHOD(bool, OnUnauthenticatedHeader, (const QuicPacketHeader& header),
- (override));
- // The constructor sets this up to return true by default.
- MOCK_METHOD(bool, OnUnauthenticatedPublicHeader,
- (const QuicPacketHeader& header), (override));
- MOCK_METHOD(void, OnDecryptedPacket, (size_t length, EncryptionLevel level),
- (override));
- MOCK_METHOD(bool, OnPacketHeader, (const QuicPacketHeader& header),
- (override));
- MOCK_METHOD(void, OnCoalescedPacket, (const QuicEncryptedPacket& packet),
- (override));
- MOCK_METHOD(void, OnUndecryptablePacket,
- (const QuicEncryptedPacket& packet,
- EncryptionLevel decryption_level, bool has_decryption_key),
- (override));
- MOCK_METHOD(bool, OnStreamFrame, (const QuicStreamFrame& frame), (override));
- MOCK_METHOD(bool, OnCryptoFrame, (const QuicCryptoFrame& frame), (override));
- MOCK_METHOD(bool, OnAckFrameStart, (QuicPacketNumber, QuicTime::Delta),
- (override));
- MOCK_METHOD(bool, OnAckRange, (QuicPacketNumber, QuicPacketNumber),
- (override));
- MOCK_METHOD(bool, OnAckTimestamp, (QuicPacketNumber, QuicTime), (override));
- MOCK_METHOD(bool, OnAckFrameEnd, (QuicPacketNumber), (override));
- MOCK_METHOD(bool, OnStopWaitingFrame, (const QuicStopWaitingFrame& frame),
- (override));
- MOCK_METHOD(bool, OnPaddingFrame, (const QuicPaddingFrame& frame),
- (override));
- MOCK_METHOD(bool, OnPingFrame, (const QuicPingFrame& frame), (override));
- MOCK_METHOD(bool, OnRstStreamFrame, (const QuicRstStreamFrame& frame),
- (override));
- MOCK_METHOD(bool, OnConnectionCloseFrame,
- (const QuicConnectionCloseFrame& frame), (override));
- MOCK_METHOD(bool, OnNewConnectionIdFrame,
- (const QuicNewConnectionIdFrame& frame), (override));
- MOCK_METHOD(bool, OnRetireConnectionIdFrame,
- (const QuicRetireConnectionIdFrame& frame), (override));
- MOCK_METHOD(bool, OnNewTokenFrame, (const QuicNewTokenFrame& frame),
- (override));
- MOCK_METHOD(bool, OnStopSendingFrame, (const QuicStopSendingFrame& frame),
- (override));
- MOCK_METHOD(bool, OnPathChallengeFrame, (const QuicPathChallengeFrame& frame),
- (override));
- MOCK_METHOD(bool, OnPathResponseFrame, (const QuicPathResponseFrame& frame),
- (override));
- MOCK_METHOD(bool, OnGoAwayFrame, (const QuicGoAwayFrame& frame), (override));
- MOCK_METHOD(bool, OnMaxStreamsFrame, (const QuicMaxStreamsFrame& frame),
- (override));
- MOCK_METHOD(bool, OnStreamsBlockedFrame,
- (const QuicStreamsBlockedFrame& frame), (override));
- MOCK_METHOD(bool, OnWindowUpdateFrame, (const QuicWindowUpdateFrame& frame),
- (override));
- MOCK_METHOD(bool, OnBlockedFrame, (const QuicBlockedFrame& frame),
- (override));
- MOCK_METHOD(bool, OnMessageFrame, (const QuicMessageFrame& frame),
- (override));
- MOCK_METHOD(bool, OnHandshakeDoneFrame, (const QuicHandshakeDoneFrame& frame),
- (override));
- MOCK_METHOD(bool, OnAckFrequencyFrame, (const QuicAckFrequencyFrame& frame),
- (override));
- MOCK_METHOD(void, OnPacketComplete, (), (override));
- MOCK_METHOD(bool, IsValidStatelessResetToken, (const StatelessResetToken&),
- (const, override));
- MOCK_METHOD(void, OnAuthenticatedIetfStatelessResetPacket,
- (const QuicIetfStatelessResetPacket&), (override));
- MOCK_METHOD(void, OnKeyUpdate, (KeyUpdateReason), (override));
- MOCK_METHOD(void, OnDecryptedFirstPacketInKeyPhase, (), (override));
- MOCK_METHOD(std::unique_ptr<QuicDecrypter>,
- AdvanceKeysAndCreateCurrentOneRttDecrypter, (), (override));
- MOCK_METHOD(std::unique_ptr<QuicEncrypter>, CreateCurrentOneRttEncrypter, (),
- (override));
-};
-
-class NoOpFramerVisitor : public QuicFramerVisitorInterface {
- public:
- NoOpFramerVisitor() {}
- NoOpFramerVisitor(const NoOpFramerVisitor&) = delete;
- NoOpFramerVisitor& operator=(const NoOpFramerVisitor&) = delete;
-
- void OnError(QuicFramer* /*framer*/) override {}
- void OnPacket() override {}
- void OnPublicResetPacket(const QuicPublicResetPacket& /*packet*/) override {}
- void OnVersionNegotiationPacket(
- const QuicVersionNegotiationPacket& /*packet*/) override {}
- void OnRetryPacket(QuicConnectionId /*original_connection_id*/,
- QuicConnectionId /*new_connection_id*/,
- absl::string_view /*retry_token*/,
- absl::string_view /*retry_integrity_tag*/,
- absl::string_view /*retry_without_tag*/) override {}
- bool OnProtocolVersionMismatch(ParsedQuicVersion version) override;
- bool OnUnauthenticatedHeader(const QuicPacketHeader& header) override;
- bool OnUnauthenticatedPublicHeader(const QuicPacketHeader& header) override;
- void OnDecryptedPacket(size_t /*length*/,
- EncryptionLevel /*level*/) override {}
- bool OnPacketHeader(const QuicPacketHeader& header) override;
- void OnCoalescedPacket(const QuicEncryptedPacket& packet) override;
- void OnUndecryptablePacket(const QuicEncryptedPacket& packet,
- EncryptionLevel decryption_level,
- bool has_decryption_key) override;
- bool OnStreamFrame(const QuicStreamFrame& frame) override;
- bool OnCryptoFrame(const QuicCryptoFrame& frame) override;
- bool OnAckFrameStart(QuicPacketNumber largest_acked,
- QuicTime::Delta ack_delay_time) override;
- bool OnAckRange(QuicPacketNumber start, QuicPacketNumber end) override;
- bool OnAckTimestamp(QuicPacketNumber packet_number,
- QuicTime timestamp) override;
- bool OnAckFrameEnd(QuicPacketNumber start) override;
- bool OnStopWaitingFrame(const QuicStopWaitingFrame& frame) override;
- bool OnPaddingFrame(const QuicPaddingFrame& frame) override;
- bool OnPingFrame(const QuicPingFrame& frame) override;
- bool OnRstStreamFrame(const QuicRstStreamFrame& frame) override;
- bool OnConnectionCloseFrame(const QuicConnectionCloseFrame& frame) override;
- bool OnNewConnectionIdFrame(const QuicNewConnectionIdFrame& frame) override;
- bool OnRetireConnectionIdFrame(
- const QuicRetireConnectionIdFrame& frame) override;
- bool OnNewTokenFrame(const QuicNewTokenFrame& frame) override;
- bool OnStopSendingFrame(const QuicStopSendingFrame& frame) override;
- bool OnPathChallengeFrame(const QuicPathChallengeFrame& frame) override;
- bool OnPathResponseFrame(const QuicPathResponseFrame& frame) override;
- bool OnGoAwayFrame(const QuicGoAwayFrame& frame) override;
- bool OnMaxStreamsFrame(const QuicMaxStreamsFrame& frame) override;
- bool OnStreamsBlockedFrame(const QuicStreamsBlockedFrame& frame) override;
- bool OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame) override;
- bool OnBlockedFrame(const QuicBlockedFrame& frame) override;
- bool OnMessageFrame(const QuicMessageFrame& frame) override;
- bool OnHandshakeDoneFrame(const QuicHandshakeDoneFrame& frame) override;
- bool OnAckFrequencyFrame(const QuicAckFrequencyFrame& frame) override;
- void OnPacketComplete() override {}
- bool IsValidStatelessResetToken(
- const StatelessResetToken& token) const override;
- void OnAuthenticatedIetfStatelessResetPacket(
- const QuicIetfStatelessResetPacket& /*packet*/) override {}
- void OnKeyUpdate(KeyUpdateReason /*reason*/) override {}
- void OnDecryptedFirstPacketInKeyPhase() override {}
- std::unique_ptr<QuicDecrypter> AdvanceKeysAndCreateCurrentOneRttDecrypter()
- override {
- return nullptr;
- }
- std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() override {
- return nullptr;
- }
-};
-
-class MockQuicConnectionVisitor : public QuicConnectionVisitorInterface {
- public:
- MockQuicConnectionVisitor();
- MockQuicConnectionVisitor(const MockQuicConnectionVisitor&) = delete;
- MockQuicConnectionVisitor& operator=(const MockQuicConnectionVisitor&) =
- delete;
- ~MockQuicConnectionVisitor() override;
-
- MOCK_METHOD(void, OnStreamFrame, (const QuicStreamFrame& frame), (override));
- MOCK_METHOD(void, OnCryptoFrame, (const QuicCryptoFrame& frame), (override));
- MOCK_METHOD(void, OnWindowUpdateFrame, (const QuicWindowUpdateFrame& frame),
- (override));
- MOCK_METHOD(void, OnBlockedFrame, (const QuicBlockedFrame& frame),
- (override));
- MOCK_METHOD(void, OnRstStream, (const QuicRstStreamFrame& frame), (override));
- MOCK_METHOD(void, OnGoAway, (const QuicGoAwayFrame& frame), (override));
- MOCK_METHOD(void, OnMessageReceived, (absl::string_view message), (override));
- MOCK_METHOD(void, OnHandshakeDoneReceived, (), (override));
- MOCK_METHOD(void, OnNewTokenReceived, (absl::string_view token), (override));
- MOCK_METHOD(void, OnConnectionClosed,
- (const QuicConnectionCloseFrame& frame,
- ConnectionCloseSource source),
- (override));
- MOCK_METHOD(void, OnWriteBlocked, (), (override));
- MOCK_METHOD(void, OnCanWrite, (), (override));
- MOCK_METHOD(bool, SendProbingData, (), (override));
- MOCK_METHOD(bool, ValidateStatelessReset,
- (const quic::QuicSocketAddress&, const quic::QuicSocketAddress&),
- (override));
- MOCK_METHOD(void, OnCongestionWindowChange, (QuicTime now), (override));
- MOCK_METHOD(void, OnConnectionMigration, (AddressChangeType type),
- (override));
- MOCK_METHOD(void, OnPathDegrading, (), (override));
- MOCK_METHOD(void, OnForwardProgressMadeAfterPathDegrading, (), (override));
- MOCK_METHOD(bool, WillingAndAbleToWrite, (), (const, override));
- MOCK_METHOD(bool, ShouldKeepConnectionAlive, (), (const, override));
- MOCK_METHOD(std::string, GetStreamsInfoForLogging, (), (const, override));
- MOCK_METHOD(void, OnSuccessfulVersionNegotiation,
- (const ParsedQuicVersion& version), (override));
- MOCK_METHOD(void, OnPacketReceived,
- (const QuicSocketAddress& self_address,
- const QuicSocketAddress& peer_address,
- bool is_connectivity_probe),
- (override));
- MOCK_METHOD(void, OnAckNeedsRetransmittableFrame, (), (override));
- MOCK_METHOD(void, SendAckFrequency, (const QuicAckFrequencyFrame& frame),
- (override));
- MOCK_METHOD(void, SendNewConnectionId,
- (const QuicNewConnectionIdFrame& frame), (override));
- MOCK_METHOD(void, SendRetireConnectionId, (uint64_t sequence_number),
- (override));
- MOCK_METHOD(void, OnServerConnectionIdIssued,
- (const QuicConnectionId& server_connection_id), (override));
- MOCK_METHOD(void, OnServerConnectionIdRetired,
- (const QuicConnectionId& server_connection_id), (override));
- MOCK_METHOD(bool, AllowSelfAddressChange, (), (const, override));
- MOCK_METHOD(HandshakeState, GetHandshakeState, (), (const, override));
- MOCK_METHOD(bool, OnMaxStreamsFrame, (const QuicMaxStreamsFrame& frame),
- (override));
- MOCK_METHOD(bool, OnStreamsBlockedFrame,
- (const QuicStreamsBlockedFrame& frame), (override));
- MOCK_METHOD(void, OnStopSendingFrame, (const QuicStopSendingFrame& frame),
- (override));
- MOCK_METHOD(void, OnPacketDecrypted, (EncryptionLevel), (override));
- MOCK_METHOD(void, OnOneRttPacketAcknowledged, (), (override));
- MOCK_METHOD(void, OnHandshakePacketSent, (), (override));
- MOCK_METHOD(void, OnKeyUpdate, (KeyUpdateReason), (override));
- MOCK_METHOD(std::unique_ptr<QuicDecrypter>,
- AdvanceKeysAndCreateCurrentOneRttDecrypter, (), (override));
- MOCK_METHOD(std::unique_ptr<QuicEncrypter>, CreateCurrentOneRttEncrypter, (),
- (override));
- MOCK_METHOD(void, BeforeConnectionCloseSent, (), (override));
- MOCK_METHOD(bool, ValidateToken, (absl::string_view), (override));
- MOCK_METHOD(bool, MaybeSendAddressToken, (), (override));
-
- bool IsKnownServerAddress(
- const QuicSocketAddress& /*address*/) const override {
- return false;
- }
-};
-
-class MockQuicConnectionHelper : public QuicConnectionHelperInterface {
- public:
- MockQuicConnectionHelper();
- MockQuicConnectionHelper(const MockQuicConnectionHelper&) = delete;
- MockQuicConnectionHelper& operator=(const MockQuicConnectionHelper&) = delete;
- ~MockQuicConnectionHelper() override;
- const QuicClock* GetClock() const override;
- QuicRandom* GetRandomGenerator() override;
- QuicBufferAllocator* GetStreamSendBufferAllocator() override;
- void AdvanceTime(QuicTime::Delta delta);
-
- private:
- MockClock clock_;
- MockRandom random_generator_;
- SimpleBufferAllocator buffer_allocator_;
-};
-
-class MockAlarmFactory : public QuicAlarmFactory {
- public:
- QuicAlarm* CreateAlarm(QuicAlarm::Delegate* delegate) override;
- QuicArenaScopedPtr<QuicAlarm> CreateAlarm(
- QuicArenaScopedPtr<QuicAlarm::Delegate> delegate,
- QuicConnectionArena* arena) override;
-
- // No-op alarm implementation
- class TestAlarm : public QuicAlarm {
- public:
- explicit TestAlarm(QuicArenaScopedPtr<QuicAlarm::Delegate> delegate)
- : QuicAlarm(std::move(delegate)) {}
-
- void SetImpl() override {}
- void CancelImpl() override {}
-
- using QuicAlarm::Fire;
- };
-
- void FireAlarm(QuicAlarm* alarm) {
- reinterpret_cast<TestAlarm*>(alarm)->Fire();
- }
-};
-
-class TestAlarmFactory : public QuicAlarmFactory {
- public:
- class TestAlarm : public QuicAlarm {
- public:
- explicit TestAlarm(QuicArenaScopedPtr<QuicAlarm::Delegate> delegate)
- : QuicAlarm(std::move(delegate)) {}
-
- void SetImpl() override {}
- void CancelImpl() override {}
- using QuicAlarm::Fire;
- };
-
- TestAlarmFactory() {}
- TestAlarmFactory(const TestAlarmFactory&) = delete;
- TestAlarmFactory& operator=(const TestAlarmFactory&) = delete;
-
- QuicAlarm* CreateAlarm(QuicAlarm::Delegate* delegate) override {
- return new TestAlarm(QuicArenaScopedPtr<QuicAlarm::Delegate>(delegate));
- }
-
- QuicArenaScopedPtr<QuicAlarm> CreateAlarm(
- QuicArenaScopedPtr<QuicAlarm::Delegate> delegate,
- QuicConnectionArena* arena) override {
- return arena->New<TestAlarm>(std::move(delegate));
- }
-};
-
-class MockQuicConnection : public QuicConnection {
- public:
- // Uses a ConnectionId of 42 and 127.0.0.1:123.
- MockQuicConnection(MockQuicConnectionHelper* helper,
- MockAlarmFactory* alarm_factory, Perspective perspective);
-
- // Uses a ConnectionId of 42.
- MockQuicConnection(QuicSocketAddress address,
- MockQuicConnectionHelper* helper,
- MockAlarmFactory* alarm_factory, Perspective perspective);
-
- // Uses 127.0.0.1:123.
- MockQuicConnection(QuicConnectionId connection_id,
- MockQuicConnectionHelper* helper,
- MockAlarmFactory* alarm_factory, Perspective perspective);
-
- // Uses a ConnectionId of 42, and 127.0.0.1:123.
- MockQuicConnection(MockQuicConnectionHelper* helper,
- MockAlarmFactory* alarm_factory, Perspective perspective,
- const ParsedQuicVersionVector& supported_versions);
-
- MockQuicConnection(QuicConnectionId connection_id, QuicSocketAddress address,
- MockQuicConnectionHelper* helper,
- MockAlarmFactory* alarm_factory, Perspective perspective,
- const ParsedQuicVersionVector& supported_versions);
- MockQuicConnection(const MockQuicConnection&) = delete;
- MockQuicConnection& operator=(const MockQuicConnection&) = delete;
-
- ~MockQuicConnection() override;
-
- // If the constructor that uses a MockQuicConnectionHelper has been used then
- // this method
- // will advance the time of the MockClock.
- void AdvanceTime(QuicTime::Delta delta);
-
- MOCK_METHOD(void, ProcessUdpPacket,
- (const QuicSocketAddress& self_address,
- const QuicSocketAddress& peer_address,
- const QuicReceivedPacket& packet),
- (override));
- MOCK_METHOD(void, CloseConnection,
- (QuicErrorCode error, const std::string& details,
- ConnectionCloseBehavior connection_close_behavior),
- (override));
- MOCK_METHOD(void, CloseConnection,
- (QuicErrorCode error, QuicIetfTransportErrorCodes ietf_error,
- const std::string& details,
- ConnectionCloseBehavior connection_close_behavior),
- (override));
- MOCK_METHOD(void, SendConnectionClosePacket,
- (QuicErrorCode error, QuicIetfTransportErrorCodes ietf_error,
- const std::string& details),
- (override));
- MOCK_METHOD(void, OnCanWrite, (), (override));
- MOCK_METHOD(void, SendConnectivityProbingResponsePacket,
- (const QuicSocketAddress& peer_address), (override));
- MOCK_METHOD(bool, SendConnectivityProbingPacket,
- (QuicPacketWriter*, const QuicSocketAddress& peer_address),
- (override));
-
- MOCK_METHOD(void, OnSendConnectionState, (const CachedNetworkParameters&),
- (override));
- MOCK_METHOD(void, ResumeConnectionState,
- (const CachedNetworkParameters&, bool), (override));
- MOCK_METHOD(void, SetMaxPacingRate, (QuicBandwidth), (override));
-
- MOCK_METHOD(void, OnStreamReset, (QuicStreamId, QuicRstStreamErrorCode),
- (override));
- MOCK_METHOD(bool, SendControlFrame, (const QuicFrame& frame), (override));
- MOCK_METHOD(MessageStatus, SendMessage,
- (QuicMessageId, absl::Span<QuicMemSlice>, bool), (override));
- MOCK_METHOD(bool, SendPathChallenge,
- (const QuicPathFrameBuffer&, const QuicSocketAddress&,
- const QuicSocketAddress&, const QuicSocketAddress&,
- QuicPacketWriter*),
- (override));
-
- MOCK_METHOD(void, OnError, (QuicFramer*), (override));
- void QuicConnection_OnError(QuicFramer* framer) {
- QuicConnection::OnError(framer);
- }
-
- void ReallyOnCanWrite() { QuicConnection::OnCanWrite(); }
-
- void ReallyCloseConnection(
- QuicErrorCode error, const std::string& details,
- ConnectionCloseBehavior connection_close_behavior) {
- // Call the 4-param method directly instead of the 3-param method, so that
- // it doesn't invoke the virtual 4-param method causing the mock 4-param
- // method to trigger.
- QuicConnection::CloseConnection(error, NO_IETF_QUIC_ERROR, details,
- connection_close_behavior);
- }
-
- void ReallyCloseConnection4(
- QuicErrorCode error, QuicIetfTransportErrorCodes ietf_error,
- const std::string& details,
- ConnectionCloseBehavior connection_close_behavior) {
- QuicConnection::CloseConnection(error, ietf_error, details,
- connection_close_behavior);
- }
-
- void ReallySendConnectionClosePacket(QuicErrorCode error,
- QuicIetfTransportErrorCodes ietf_error,
- const std::string& details) {
- QuicConnection::SendConnectionClosePacket(error, ietf_error, details);
- }
-
- void ReallyProcessUdpPacket(const QuicSocketAddress& self_address,
- const QuicSocketAddress& peer_address,
- const QuicReceivedPacket& packet) {
- QuicConnection::ProcessUdpPacket(self_address, peer_address, packet);
- }
-
- bool OnProtocolVersionMismatch(ParsedQuicVersion version) override;
-
- bool ReallySendControlFrame(const QuicFrame& frame) {
- return QuicConnection::SendControlFrame(frame);
- }
-
- bool ReallySendConnectivityProbingPacket(
- QuicPacketWriter* probing_writer, const QuicSocketAddress& peer_address) {
- return QuicConnection::SendConnectivityProbingPacket(probing_writer,
- peer_address);
- }
-
- void ReallySendConnectivityProbingResponsePacket(
- const QuicSocketAddress& peer_address) {
- QuicConnection::SendConnectivityProbingResponsePacket(peer_address);
- }
-
- bool ReallyOnPathResponseFrame(const QuicPathResponseFrame& frame) {
- return QuicConnection::OnPathResponseFrame(frame);
- }
-
- MOCK_METHOD(bool, OnPathResponseFrame, (const QuicPathResponseFrame&),
- (override));
- MOCK_METHOD(bool, OnStopSendingFrame, (const QuicStopSendingFrame& frame),
- (override));
- MOCK_METHOD(size_t, SendCryptoData,
- (EncryptionLevel, size_t, QuicStreamOffset), (override));
- size_t QuicConnection_SendCryptoData(EncryptionLevel level,
- size_t write_length,
- QuicStreamOffset offset) {
- return QuicConnection::SendCryptoData(level, write_length, offset);
- }
-};
-
-class PacketSavingConnection : public MockQuicConnection {
- public:
- PacketSavingConnection(MockQuicConnectionHelper* helper,
- MockAlarmFactory* alarm_factory,
- Perspective perspective);
-
- PacketSavingConnection(MockQuicConnectionHelper* helper,
- MockAlarmFactory* alarm_factory,
- Perspective perspective,
- const ParsedQuicVersionVector& supported_versions);
- PacketSavingConnection(const PacketSavingConnection&) = delete;
- PacketSavingConnection& operator=(const PacketSavingConnection&) = delete;
-
- ~PacketSavingConnection() override;
-
- void SendOrQueuePacket(SerializedPacket packet) override;
-
- MOCK_METHOD(void, OnPacketSent, (EncryptionLevel, TransmissionType));
-
- std::vector<std::unique_ptr<QuicEncryptedPacket>> encrypted_packets_;
- // Number of packets in encrypted_packets that has been delivered to the peer
- // connection.
- size_t number_of_packets_delivered_ = 0;
- MockClock clock_;
-};
-
-class MockQuicSession : public QuicSession {
- public:
- // Takes ownership of |connection|.
- MockQuicSession(QuicConnection* connection, bool create_mock_crypto_stream);
-
- // Takes ownership of |connection|.
- explicit MockQuicSession(QuicConnection* connection);
- MockQuicSession(const MockQuicSession&) = delete;
- MockQuicSession& operator=(const MockQuicSession&) = delete;
- ~MockQuicSession() override;
-
- QuicCryptoStream* GetMutableCryptoStream() override;
- const QuicCryptoStream* GetCryptoStream() const override;
- void SetCryptoStream(QuicCryptoStream* crypto_stream);
-
- MOCK_METHOD(void, OnConnectionClosed,
- (const QuicConnectionCloseFrame& frame,
- ConnectionCloseSource source),
- (override));
- MOCK_METHOD(QuicStream*, CreateIncomingStream, (QuicStreamId id), (override));
- MOCK_METHOD(QuicSpdyStream*, CreateIncomingStream, (PendingStream*),
- (override));
- MOCK_METHOD(QuicConsumedData, WritevData,
- (QuicStreamId id, size_t write_length, QuicStreamOffset offset,
- StreamSendingState state, TransmissionType type,
- EncryptionLevel level),
- (override));
- MOCK_METHOD(bool, WriteControlFrame,
- (const QuicFrame& frame, TransmissionType type), (override));
- MOCK_METHOD(void, MaybeSendRstStreamFrame,
- (QuicStreamId stream_id, QuicResetStreamError error,
- QuicStreamOffset bytes_written),
- (override));
- MOCK_METHOD(void, MaybeSendStopSendingFrame,
- (QuicStreamId stream_id, QuicResetStreamError error), (override));
-
- MOCK_METHOD(bool, ShouldKeepConnectionAlive, (), (const, override));
- MOCK_METHOD(std::vector<std::string>, GetAlpnsToOffer, (), (const, override));
- MOCK_METHOD(std::vector<absl::string_view>::const_iterator, SelectAlpn,
- (const std::vector<absl::string_view>&), (const, override));
- MOCK_METHOD(void, OnAlpnSelected, (absl::string_view), (override));
-
- using QuicSession::ActivateStream;
-
- // Returns a QuicConsumedData that indicates all of |write_length| (and |fin|
- // if set) has been consumed.
- QuicConsumedData ConsumeData(QuicStreamId id, size_t write_length,
- QuicStreamOffset offset,
- StreamSendingState state, TransmissionType type,
- absl::optional<EncryptionLevel> level);
-
- void ReallyMaybeSendRstStreamFrame(QuicStreamId id,
- QuicRstStreamErrorCode error,
- QuicStreamOffset bytes_written) {
- QuicSession::MaybeSendRstStreamFrame(
- id, QuicResetStreamError::FromInternal(error), bytes_written);
- }
-
- private:
- std::unique_ptr<QuicCryptoStream> crypto_stream_;
-};
-
-class MockQuicCryptoStream : public QuicCryptoStream {
- public:
- explicit MockQuicCryptoStream(QuicSession* session);
-
- ~MockQuicCryptoStream() override;
-
- ssl_early_data_reason_t EarlyDataReason() const override;
- bool encryption_established() const override;
- bool one_rtt_keys_available() const override;
- const QuicCryptoNegotiatedParameters& crypto_negotiated_params()
- const override;
- CryptoMessageParser* crypto_message_parser() override;
- void OnPacketDecrypted(EncryptionLevel /*level*/) override {}
- void OnOneRttPacketAcknowledged() override {}
- void OnHandshakePacketSent() override {}
- void OnHandshakeDoneReceived() override {}
- void OnNewTokenReceived(absl::string_view /*token*/) override {}
- std::string GetAddressToken(
- const CachedNetworkParameters* /*cached_network_parameters*/)
- const override {
- return "";
- }
- bool ValidateAddressToken(absl::string_view /*token*/) const override {
- return true;
- }
- const CachedNetworkParameters* PreviousCachedNetworkParams() const override {
- return nullptr;
- }
- void SetPreviousCachedNetworkParams(
- CachedNetworkParameters /*cached_network_params*/) override {}
- void OnConnectionClosed(QuicErrorCode /*error*/,
- ConnectionCloseSource /*source*/) override {}
- HandshakeState GetHandshakeState() const override { return HANDSHAKE_START; }
- void SetServerApplicationStateForResumption(
- std::unique_ptr<ApplicationState> /*application_state*/) override {}
- std::unique_ptr<QuicDecrypter> AdvanceKeysAndCreateCurrentOneRttDecrypter()
- override {
- return nullptr;
- }
- std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() override {
- return nullptr;
- }
- bool ExportKeyingMaterial(absl::string_view /*label*/,
- absl::string_view /*context*/,
- size_t /*result_len*/,
- std::string* /*result*/) override {
- return false;
- }
- SSL* GetSsl() const override { return nullptr; }
-
- private:
- QuicReferenceCountedPointer<QuicCryptoNegotiatedParameters> params_;
- CryptoFramer crypto_framer_;
-};
-
-class MockQuicSpdySession : public QuicSpdySession {
- public:
- // Takes ownership of |connection|.
- explicit MockQuicSpdySession(QuicConnection* connection);
- // Takes ownership of |connection|.
- MockQuicSpdySession(QuicConnection* connection,
- bool create_mock_crypto_stream);
- MockQuicSpdySession(const MockQuicSpdySession&) = delete;
- MockQuicSpdySession& operator=(const MockQuicSpdySession&) = delete;
- ~MockQuicSpdySession() override;
-
- QuicCryptoStream* GetMutableCryptoStream() override;
- const QuicCryptoStream* GetCryptoStream() const override;
- void SetCryptoStream(QuicCryptoStream* crypto_stream);
-
- void ReallyOnConnectionClosed(const QuicConnectionCloseFrame& frame,
- ConnectionCloseSource source) {
- QuicSession::OnConnectionClosed(frame, source);
- }
-
- // From QuicSession.
- MOCK_METHOD(void, OnConnectionClosed,
- (const QuicConnectionCloseFrame& frame,
- ConnectionCloseSource source),
- (override));
- MOCK_METHOD(QuicSpdyStream*, CreateIncomingStream, (QuicStreamId id),
- (override));
- MOCK_METHOD(QuicSpdyStream*, CreateIncomingStream, (PendingStream*),
- (override));
- MOCK_METHOD(QuicSpdyStream*, CreateOutgoingBidirectionalStream, (),
- (override));
- MOCK_METHOD(QuicSpdyStream*, CreateOutgoingUnidirectionalStream, (),
- (override));
- MOCK_METHOD(bool, ShouldCreateIncomingStream, (QuicStreamId id), (override));
- MOCK_METHOD(bool, ShouldCreateOutgoingBidirectionalStream, (), (override));
- MOCK_METHOD(bool, ShouldCreateOutgoingUnidirectionalStream, (), (override));
- MOCK_METHOD(QuicConsumedData, WritevData,
- (QuicStreamId id, size_t write_length, QuicStreamOffset offset,
- StreamSendingState state, TransmissionType type,
- EncryptionLevel level),
- (override));
- MOCK_METHOD(void, MaybeSendRstStreamFrame,
- (QuicStreamId stream_id, QuicResetStreamError error,
- QuicStreamOffset bytes_written),
- (override));
- MOCK_METHOD(void, MaybeSendStopSendingFrame,
- (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, OnStreamHeadersPriority,
- (QuicStreamId stream_id,
- const spdy::SpdyStreamPrecedence& precedence),
- (override));
- MOCK_METHOD(void, OnStreamHeaderList,
- (QuicStreamId stream_id, bool fin, size_t frame_len,
- const QuicHeaderList& header_list),
- (override));
- MOCK_METHOD(void, OnPromiseHeaderList,
- (QuicStreamId stream_id, QuicStreamId promised_stream_id,
- size_t frame_len, const QuicHeaderList& header_list),
- (override));
- MOCK_METHOD(void, OnPriorityFrame,
- (QuicStreamId id, const spdy::SpdyStreamPrecedence& precedence),
- (override));
- MOCK_METHOD(void, OnCongestionWindowChange, (QuicTime now), (override));
-
- // Returns a QuicConsumedData that indicates all of |write_length| (and |fin|
- // if set) has been consumed.
- QuicConsumedData ConsumeData(QuicStreamId id, size_t write_length,
- QuicStreamOffset offset,
- StreamSendingState state, TransmissionType type,
- absl::optional<EncryptionLevel> level);
-
- using QuicSession::ActivateStream;
-
- private:
- std::unique_ptr<QuicCryptoStream> crypto_stream_;
-};
-
-class MockHttp3DebugVisitor : public Http3DebugVisitor {
- public:
- MOCK_METHOD(void, OnControlStreamCreated, (QuicStreamId), (override));
- MOCK_METHOD(void, OnQpackEncoderStreamCreated, (QuicStreamId), (override));
- MOCK_METHOD(void, OnQpackDecoderStreamCreated, (QuicStreamId), (override));
- MOCK_METHOD(void, OnPeerControlStreamCreated, (QuicStreamId), (override));
- MOCK_METHOD(void, OnPeerQpackEncoderStreamCreated, (QuicStreamId),
- (override));
- MOCK_METHOD(void, OnPeerQpackDecoderStreamCreated, (QuicStreamId),
- (override));
-
- MOCK_METHOD(void, OnSettingsFrameReceivedViaAlps, (const SettingsFrame&),
- (override));
-
- MOCK_METHOD(void, OnAcceptChFrameReceivedViaAlps, (const AcceptChFrame&),
- (override));
-
- 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&),
- (override));
-
- MOCK_METHOD(void, OnDataFrameReceived, (QuicStreamId, QuicByteCount),
- (override));
- MOCK_METHOD(void, OnHeadersFrameReceived, (QuicStreamId, QuicByteCount),
- (override));
- MOCK_METHOD(void, OnHeadersDecoded, (QuicStreamId, QuicHeaderList),
- (override));
- MOCK_METHOD(void, OnUnknownFrameReceived,
- (QuicStreamId, uint64_t, QuicByteCount), (override));
-
- MOCK_METHOD(void, OnSettingsFrameSent, (const SettingsFrame&), (override));
- MOCK_METHOD(void, OnGoAwayFrameSent, (QuicStreamId), (override));
- MOCK_METHOD(void, OnMaxPushIdFrameSent, (const MaxPushIdFrame&), (override));
- MOCK_METHOD(void, OnPriorityUpdateFrameSent, (const PriorityUpdateFrame&),
- (override));
-
- MOCK_METHOD(void, OnDataFrameSent, (QuicStreamId, QuicByteCount), (override));
- MOCK_METHOD(void, OnHeadersFrameSent,
- (QuicStreamId, const spdy::SpdyHeaderBlock&), (override));
-};
-
-class TestQuicSpdyServerSession : public QuicServerSessionBase {
- public:
- // Takes ownership of |connection|.
- TestQuicSpdyServerSession(QuicConnection* connection,
- const QuicConfig& config,
- const ParsedQuicVersionVector& supported_versions,
- const QuicCryptoServerConfig* crypto_config,
- QuicCompressedCertsCache* compressed_certs_cache);
- TestQuicSpdyServerSession(const TestQuicSpdyServerSession&) = delete;
- TestQuicSpdyServerSession& operator=(const TestQuicSpdyServerSession&) =
- delete;
- ~TestQuicSpdyServerSession() override;
-
- MOCK_METHOD(QuicSpdyStream*, CreateIncomingStream, (QuicStreamId id),
- (override));
- MOCK_METHOD(QuicSpdyStream*, CreateIncomingStream, (PendingStream*),
- (override));
- MOCK_METHOD(QuicSpdyStream*, CreateOutgoingBidirectionalStream, (),
- (override));
- MOCK_METHOD(QuicSpdyStream*, CreateOutgoingUnidirectionalStream, (),
- (override));
- MOCK_METHOD(std::vector<absl::string_view>::const_iterator, SelectAlpn,
- (const std::vector<absl::string_view>&), (const, override));
- MOCK_METHOD(void, OnAlpnSelected, (absl::string_view), (override));
- std::unique_ptr<QuicCryptoServerStreamBase> CreateQuicCryptoServerStream(
- const QuicCryptoServerConfig* crypto_config,
- QuicCompressedCertsCache* compressed_certs_cache) override;
-
- QuicCryptoServerStreamBase* GetMutableCryptoStream() override;
-
- const QuicCryptoServerStreamBase* GetCryptoStream() const override;
-
- MockQuicCryptoServerStreamHelper* helper() { return &helper_; }
-
- QuicSSLConfig GetSSLConfig() const override {
- QuicSSLConfig ssl_config = QuicServerSessionBase::GetSSLConfig();
- if (early_data_enabled_.has_value()) {
- ssl_config.early_data_enabled = *early_data_enabled_;
- }
- if (client_cert_mode_.has_value()) {
- ssl_config.client_cert_mode = *client_cert_mode_;
- }
-
- return ssl_config;
- }
-
- 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;
- }
- }
-
- private:
- MockQuicSessionVisitor visitor_;
- MockQuicCryptoServerStreamHelper helper_;
- // If not nullopt, override the early_data_enabled value from base class'
- // ssl_config.
- absl::optional<bool> early_data_enabled_;
- // If not nullopt, override the client_cert_mode value from base class'
- // ssl_config.
- absl::optional<ClientCertMode> client_cert_mode_;
-};
-
-// A test implementation of QuicClientPushPromiseIndex::Delegate.
-class TestPushPromiseDelegate : public QuicClientPushPromiseIndex::Delegate {
- public:
- // |match| sets the validation result for checking whether designated header
- // fields match for promise request and client request.
- explicit TestPushPromiseDelegate(bool match);
-
- bool CheckVary(const spdy::SpdyHeaderBlock& client_request,
- const spdy::SpdyHeaderBlock& promise_request,
- const spdy::SpdyHeaderBlock& promise_response) override;
-
- void OnRendezvousResult(QuicSpdyStream* stream) override;
-
- QuicSpdyStream* rendezvous_stream() { return rendezvous_stream_; }
- bool rendezvous_fired() { return rendezvous_fired_; }
-
- private:
- bool match_;
- bool rendezvous_fired_;
- QuicSpdyStream* rendezvous_stream_;
-};
-
-class TestQuicSpdyClientSession : public QuicSpdyClientSessionBase {
- public:
- TestQuicSpdyClientSession(QuicConnection* connection,
- const QuicConfig& config,
- const ParsedQuicVersionVector& supported_versions,
- const QuicServerId& server_id,
- QuicCryptoClientConfig* crypto_config);
- TestQuicSpdyClientSession(const TestQuicSpdyClientSession&) = delete;
- TestQuicSpdyClientSession& operator=(const TestQuicSpdyClientSession&) =
- delete;
- ~TestQuicSpdyClientSession() override;
-
- bool IsAuthorized(const std::string& authority) override;
-
- // QuicSpdyClientSessionBase
- MOCK_METHOD(void, OnProofValid,
- (const QuicCryptoClientConfig::CachedState& cached), (override));
- MOCK_METHOD(void, OnProofVerifyDetailsAvailable,
- (const ProofVerifyDetails& verify_details), (override));
-
- // TestQuicSpdyClientSession
- MOCK_METHOD(QuicSpdyStream*, CreateIncomingStream, (QuicStreamId id),
- (override));
- MOCK_METHOD(QuicSpdyStream*, CreateIncomingStream, (PendingStream*),
- (override));
- MOCK_METHOD(QuicSpdyStream*, CreateOutgoingBidirectionalStream, (),
- (override));
- MOCK_METHOD(QuicSpdyStream*, CreateOutgoingUnidirectionalStream, (),
- (override));
- MOCK_METHOD(bool, ShouldCreateIncomingStream, (QuicStreamId id), (override));
- MOCK_METHOD(bool, ShouldCreateOutgoingBidirectionalStream, (), (override));
- MOCK_METHOD(bool, ShouldCreateOutgoingUnidirectionalStream, (), (override));
- MOCK_METHOD(std::vector<std::string>, GetAlpnsToOffer, (), (const, override));
- MOCK_METHOD(void, OnAlpnSelected, (absl::string_view), (override));
- MOCK_METHOD(void, OnConfigNegotiated, (), (override));
-
- QuicCryptoClientStream* GetMutableCryptoStream() override;
- const QuicCryptoClientStream* GetCryptoStream() const override;
-
- // Override to save sent crypto handshake messages.
- void OnCryptoHandshakeMessageSent(
- const CryptoHandshakeMessage& message) override {
- sent_crypto_handshake_messages_.push_back(message);
- }
-
- const std::vector<CryptoHandshakeMessage>& sent_crypto_handshake_messages()
- const {
- return sent_crypto_handshake_messages_;
- }
-
- private:
- // Calls the parent class's OnConfigNegotiated method. Used to set the default
- // mock behavior for OnConfigNegotiated.
- void RealOnConfigNegotiated();
-
- std::unique_ptr<QuicCryptoClientStream> crypto_stream_;
- QuicClientPushPromiseIndex push_promise_index_;
- std::vector<CryptoHandshakeMessage> sent_crypto_handshake_messages_;
-};
-
-class MockPacketWriter : public QuicPacketWriter {
- public:
- MockPacketWriter();
- MockPacketWriter(const MockPacketWriter&) = delete;
- MockPacketWriter& operator=(const MockPacketWriter&) = delete;
- ~MockPacketWriter() override;
-
- MOCK_METHOD(WriteResult, WritePacket,
- (const char*, size_t buf_len, const QuicIpAddress& self_address,
- const QuicSocketAddress& peer_address, PerPacketOptions*),
- (override));
- MOCK_METHOD(bool, IsWriteBlocked, (), (const, override));
- MOCK_METHOD(void, SetWritable, (), (override));
- MOCK_METHOD(QuicByteCount, GetMaxPacketSize,
- (const QuicSocketAddress& peer_address), (const, override));
- MOCK_METHOD(bool, SupportsReleaseTime, (), (const, override));
- MOCK_METHOD(bool, IsBatchMode, (), (const, override));
- MOCK_METHOD(QuicPacketBuffer, GetNextWriteLocation,
- (const QuicIpAddress& self_address,
- const QuicSocketAddress& peer_address),
- (override));
- MOCK_METHOD(WriteResult, Flush, (), (override));
-};
-
-class MockSendAlgorithm : public SendAlgorithmInterface {
- public:
- MockSendAlgorithm();
- MockSendAlgorithm(const MockSendAlgorithm&) = delete;
- MockSendAlgorithm& operator=(const MockSendAlgorithm&) = delete;
- ~MockSendAlgorithm() override;
-
- MOCK_METHOD(void, SetFromConfig,
- (const QuicConfig& config, Perspective perspective), (override));
- MOCK_METHOD(void, ApplyConnectionOptions,
- (const QuicTagVector& connection_options), (override));
- MOCK_METHOD(void, SetInitialCongestionWindowInPackets,
- (QuicPacketCount packets), (override));
- MOCK_METHOD(void, OnCongestionEvent,
- (bool rtt_updated, QuicByteCount bytes_in_flight,
- QuicTime event_time, const AckedPacketVector& acked_packets,
- const LostPacketVector& lost_packets),
- (override));
- MOCK_METHOD(void, OnPacketSent,
- (QuicTime, QuicByteCount, QuicPacketNumber, QuicByteCount,
- HasRetransmittableData),
- (override));
- MOCK_METHOD(void, OnPacketNeutered, (QuicPacketNumber), (override));
- MOCK_METHOD(void, OnRetransmissionTimeout, (bool), (override));
- MOCK_METHOD(void, OnConnectionMigration, (), (override));
- MOCK_METHOD(bool, CanSend, (QuicByteCount), (override));
- MOCK_METHOD(QuicBandwidth, PacingRate, (QuicByteCount), (const, override));
- MOCK_METHOD(QuicBandwidth, BandwidthEstimate, (), (const, override));
- MOCK_METHOD(QuicByteCount, GetCongestionWindow, (), (const, override));
- 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));
- MOCK_METHOD(void, AdjustNetworkParameters, (const NetworkParams&),
- (override));
- MOCK_METHOD(void, OnApplicationLimited, (QuicByteCount), (override));
- MOCK_METHOD(void, PopulateConnectionStats, (QuicConnectionStats*),
- (const, override));
-};
-
-class MockLossAlgorithm : public LossDetectionInterface {
- public:
- MockLossAlgorithm();
- MockLossAlgorithm(const MockLossAlgorithm&) = delete;
- MockLossAlgorithm& operator=(const MockLossAlgorithm&) = delete;
- ~MockLossAlgorithm() override;
-
- MOCK_METHOD(void, SetFromConfig,
- (const QuicConfig& config, Perspective perspective), (override));
-
- MOCK_METHOD(DetectionStats, DetectLosses,
- (const QuicUnackedPacketMap& unacked_packets, QuicTime time,
- const RttStats& rtt_stats,
- QuicPacketNumber largest_recently_acked,
- const AckedPacketVector& packets_acked, LostPacketVector*),
- (override));
- MOCK_METHOD(QuicTime, GetLossTimeout, (), (const, override));
- MOCK_METHOD(void, SpuriousLossDetected,
- (const QuicUnackedPacketMap&, const RttStats&, QuicTime,
- QuicPacketNumber, QuicPacketNumber),
- (override));
-
- MOCK_METHOD(void, OnConfigNegotiated, (), (override));
- MOCK_METHOD(void, OnMinRttAvailable, (), (override));
- MOCK_METHOD(void, OnUserAgentIdKnown, (), (override));
- MOCK_METHOD(void, OnConnectionClosed, (), (override));
- MOCK_METHOD(void, OnReorderingDetected, (), (override));
-};
-
-class MockAckListener : public QuicAckListenerInterface {
- public:
- MockAckListener();
- MockAckListener(const MockAckListener&) = delete;
- MockAckListener& operator=(const MockAckListener&) = delete;
-
- MOCK_METHOD(void, OnPacketAcked,
- (int acked_bytes, QuicTime::Delta ack_delay_time), (override));
-
- MOCK_METHOD(void, OnPacketRetransmitted, (int retransmitted_bytes),
- (override));
-
- protected:
- // Object is ref counted.
- ~MockAckListener() override;
-};
-
-class MockNetworkChangeVisitor
- : public QuicSentPacketManager::NetworkChangeVisitor {
- public:
- MockNetworkChangeVisitor();
- MockNetworkChangeVisitor(const MockNetworkChangeVisitor&) = delete;
- MockNetworkChangeVisitor& operator=(const MockNetworkChangeVisitor&) = delete;
- ~MockNetworkChangeVisitor() override;
-
- MOCK_METHOD(void, OnCongestionChange, (), (override));
- MOCK_METHOD(void, OnPathMtuIncreased, (QuicPacketLength), (override));
-};
-
-class MockQuicConnectionDebugVisitor : public QuicConnectionDebugVisitor {
- public:
- MockQuicConnectionDebugVisitor();
- ~MockQuicConnectionDebugVisitor() override;
-
- MOCK_METHOD(void, OnPacketSent,
- (QuicPacketNumber, QuicPacketLength, bool, TransmissionType,
- EncryptionLevel, const QuicFrames&, const QuicFrames&, QuicTime),
- (override));
-
- MOCK_METHOD(void, OnCoalescedPacketSent, (const QuicCoalescedPacket&, size_t),
- (override));
-
- MOCK_METHOD(void, OnPingSent, (), (override));
-
- MOCK_METHOD(void, OnPacketReceived,
- (const QuicSocketAddress&, const QuicSocketAddress&,
- const QuicEncryptedPacket&),
- (override));
-
- MOCK_METHOD(void, OnIncorrectConnectionId, (QuicConnectionId), (override));
-
- MOCK_METHOD(void, OnProtocolVersionMismatch, (ParsedQuicVersion), (override));
-
- MOCK_METHOD(void, OnPacketHeader,
- (const QuicPacketHeader& header, QuicTime receive_time,
- EncryptionLevel level),
- (override));
-
- MOCK_METHOD(void, OnSuccessfulVersionNegotiation, (const ParsedQuicVersion&),
- (override));
-
- MOCK_METHOD(void, OnStreamFrame, (const QuicStreamFrame&), (override));
-
- MOCK_METHOD(void, OnCryptoFrame, (const QuicCryptoFrame&), (override));
-
- MOCK_METHOD(void, OnStopWaitingFrame, (const QuicStopWaitingFrame&),
- (override));
-
- MOCK_METHOD(void, OnRstStreamFrame, (const QuicRstStreamFrame&), (override));
-
- MOCK_METHOD(void, OnConnectionCloseFrame, (const QuicConnectionCloseFrame&),
- (override));
-
- MOCK_METHOD(void, OnBlockedFrame, (const QuicBlockedFrame&), (override));
-
- MOCK_METHOD(void, OnNewConnectionIdFrame, (const QuicNewConnectionIdFrame&),
- (override));
-
- MOCK_METHOD(void, OnRetireConnectionIdFrame,
- (const QuicRetireConnectionIdFrame&), (override));
-
- MOCK_METHOD(void, OnNewTokenFrame, (const QuicNewTokenFrame&), (override));
-
- MOCK_METHOD(void, OnMessageFrame, (const QuicMessageFrame&), (override));
-
- MOCK_METHOD(void, OnStopSendingFrame, (const QuicStopSendingFrame&),
- (override));
-
- MOCK_METHOD(void, OnPathChallengeFrame, (const QuicPathChallengeFrame&),
- (override));
-
- MOCK_METHOD(void, OnPathResponseFrame, (const QuicPathResponseFrame&),
- (override));
-
- MOCK_METHOD(void, OnPublicResetPacket, (const QuicPublicResetPacket&),
- (override));
-
- MOCK_METHOD(void, OnVersionNegotiationPacket,
- (const QuicVersionNegotiationPacket&), (override));
-
- MOCK_METHOD(void, OnTransportParametersSent, (const TransportParameters&),
- (override));
-
- MOCK_METHOD(void, OnTransportParametersReceived, (const TransportParameters&),
- (override));
-
- MOCK_METHOD(void, OnZeroRttRejected, (int), (override));
- MOCK_METHOD(void, OnZeroRttPacketAcked, (), (override));
-};
-
-class MockReceivedPacketManager : public QuicReceivedPacketManager {
- public:
- explicit MockReceivedPacketManager(QuicConnectionStats* stats);
- ~MockReceivedPacketManager() override;
-
- MOCK_METHOD(void, RecordPacketReceived,
- (const QuicPacketHeader& header, QuicTime receipt_time),
- (override));
- MOCK_METHOD(bool, IsMissing, (QuicPacketNumber packet_number), (override));
- MOCK_METHOD(bool, IsAwaitingPacket, (QuicPacketNumber packet_number),
- (const, override));
- MOCK_METHOD(bool, HasNewMissingPackets, (), (const, override));
- MOCK_METHOD(bool, ack_frame_updated, (), (const, override));
-};
-
-class MockPacketCreatorDelegate : public QuicPacketCreator::DelegateInterface {
- public:
- MockPacketCreatorDelegate();
- MockPacketCreatorDelegate(const MockPacketCreatorDelegate&) = delete;
- MockPacketCreatorDelegate& operator=(const MockPacketCreatorDelegate&) =
- delete;
- ~MockPacketCreatorDelegate() override;
-
- MOCK_METHOD(QuicPacketBuffer, GetPacketBuffer, (), (override));
- MOCK_METHOD(void, OnSerializedPacket, (SerializedPacket), (override));
- MOCK_METHOD(void, OnUnrecoverableError, (QuicErrorCode, const std::string&),
- (override));
- MOCK_METHOD(bool, ShouldGeneratePacket,
- (HasRetransmittableData retransmittable, IsHandshake handshake),
- (override));
- MOCK_METHOD(const QuicFrames, MaybeBundleAckOpportunistically, (),
- (override));
- MOCK_METHOD(SerializedPacketFate, GetSerializedPacketFate,
- (bool, EncryptionLevel), (override));
-};
-
-class MockSessionNotifier : public SessionNotifierInterface {
- public:
- MockSessionNotifier();
- ~MockSessionNotifier() override;
-
- MOCK_METHOD(bool, OnFrameAcked, (const QuicFrame&, QuicTime::Delta, QuicTime),
- (override));
- MOCK_METHOD(void, OnStreamFrameRetransmitted, (const QuicStreamFrame&),
- (override));
- MOCK_METHOD(void, OnFrameLost, (const QuicFrame&), (override));
- MOCK_METHOD(void, RetransmitFrames,
- (const QuicFrames&, TransmissionType type), (override));
- MOCK_METHOD(bool, IsFrameOutstanding, (const QuicFrame&), (const, override));
- MOCK_METHOD(bool, HasUnackedCryptoData, (), (const, override));
- MOCK_METHOD(bool, HasUnackedStreamData, (), (const, override));
-};
-
-class MockQuicPathValidationContext : public QuicPathValidationContext {
- public:
- MockQuicPathValidationContext(const QuicSocketAddress& self_address,
- const QuicSocketAddress& peer_address,
- const QuicSocketAddress& effective_peer_address,
- QuicPacketWriter* writer)
- : QuicPathValidationContext(self_address, peer_address,
- effective_peer_address),
- writer_(writer) {}
- QuicPacketWriter* WriterToUse() override { return writer_; }
-
- private:
- QuicPacketWriter* writer_;
-};
-
-class MockQuicPathValidationResultDelegate
- : public QuicPathValidator::ResultDelegate {
- public:
- MOCK_METHOD(void, OnPathValidationSuccess,
- (std::unique_ptr<QuicPathValidationContext>), (override));
-
- MOCK_METHOD(void, OnPathValidationFailure,
- (std::unique_ptr<QuicPathValidationContext>), (override));
-};
-
-class QuicCryptoClientStreamPeer {
- public:
- QuicCryptoClientStreamPeer() = delete;
-
- static QuicCryptoClientStream::HandshakerInterface* GetHandshaker(
- QuicCryptoClientStream* stream);
-};
-
-// Creates a client session for testing.
-//
-// server_id: The server id associated with this stream.
-// connection_start_time: The time to set for the connection clock.
-// Needed for strike-register nonce verification. The client
-// connection_start_time should be synchronized witht the server
-// start time, otherwise nonce verification will fail.
-// supported_versions: Set of QUIC versions this client supports.
-// helper: Pointer to the MockQuicConnectionHelper to use for the session.
-// crypto_client_config: Pointer to the crypto client config.
-// client_connection: Pointer reference for newly created
-// connection. This object will be owned by the
-// client_session.
-// client_session: Pointer reference for the newly created client
-// session. The new object will be owned by the caller.
-void CreateClientSessionForTest(
- QuicServerId server_id, QuicTime::Delta connection_start_time,
- const ParsedQuicVersionVector& supported_versions,
- MockQuicConnectionHelper* helper, MockAlarmFactory* alarm_factory,
- QuicCryptoClientConfig* crypto_client_config,
- PacketSavingConnection** client_connection,
- TestQuicSpdyClientSession** client_session);
-
-// Creates a server session for testing.
-//
-// server_id: The server id associated with this stream.
-// connection_start_time: The time to set for the connection clock.
-// Needed for strike-register nonce verification. The server
-// connection_start_time should be synchronized witht the client
-// start time, otherwise nonce verification will fail.
-// supported_versions: Set of QUIC versions this server supports.
-// helper: Pointer to the MockQuicConnectionHelper to use for the session.
-// server_crypto_config: Pointer to the crypto server config.
-// server_connection: Pointer reference for newly created
-// connection. This object will be owned by the
-// server_session.
-// server_session: Pointer reference for the newly created server
-// session. The new object will be owned by the caller.
-void CreateServerSessionForTest(
- QuicServerId server_id, QuicTime::Delta connection_start_time,
- ParsedQuicVersionVector supported_versions,
- MockQuicConnectionHelper* helper, MockAlarmFactory* alarm_factory,
- QuicCryptoServerConfig* server_crypto_config,
- QuicCompressedCertsCache* compressed_certs_cache,
- PacketSavingConnection** server_connection,
- TestQuicSpdyServerSession** server_session);
-
-// Verifies that the relative error of |actual| with respect to |expected| is
-// no more than |margin|.
-// Please use EXPECT_APPROX_EQ, a wrapper around this function, for better error
-// report.
-template <typename T>
-void ExpectApproxEq(T expected, T actual, float relative_margin) {
- // If |relative_margin| > 1 and T is an unsigned type, the comparison will
- // underflow.
- ASSERT_LE(relative_margin, 1);
- ASSERT_GE(relative_margin, 0);
-
- T absolute_margin = expected * relative_margin;
-
- EXPECT_GE(expected + absolute_margin, actual) << "actual value too big";
- EXPECT_LE(expected - absolute_margin, actual) << "actual value too small";
-}
-
-#define EXPECT_APPROX_EQ(expected, actual, relative_margin) \
- do { \
- SCOPED_TRACE(testing::Message() << "relative_margin:" << relative_margin); \
- quic::test::ExpectApproxEq(expected, actual, relative_margin); \
- } while (0)
-
-template <typename T>
-QuicHeaderList AsHeaderList(const T& container) {
- QuicHeaderList l;
- l.OnHeaderBlockStart();
- size_t total_size = 0;
- for (auto p : container) {
- total_size += p.first.size() + p.second.size();
- l.OnHeader(p.first, p.second);
- }
- l.OnHeaderBlockEnd(total_size, total_size);
- return l;
-}
-
-// Utility function that stores |str|'s data in |iov|.
-inline void MakeIOVector(absl::string_view str, struct iovec* iov) {
- iov->iov_base = const_cast<char*>(str.data());
- iov->iov_len = static_cast<size_t>(str.size());
-}
-
-// Helper functions for stream ids, to allow test logic to abstract over the
-// HTTP stream numbering scheme (i.e. whether one or two QUIC streams are used
-// per HTTP transaction).
-QuicStreamId GetNthClientInitiatedBidirectionalStreamId(
- QuicTransportVersion version, int n);
-QuicStreamId GetNthServerInitiatedBidirectionalStreamId(
- QuicTransportVersion version, int n);
-QuicStreamId GetNthServerInitiatedUnidirectionalStreamId(
- QuicTransportVersion version, int n);
-QuicStreamId GetNthClientInitiatedUnidirectionalStreamId(
- QuicTransportVersion version, int n);
-
-StreamType DetermineStreamType(QuicStreamId id, ParsedQuicVersion version,
- Perspective perspective, bool is_incoming,
- StreamType default_type);
-
-// Creates a MemSlice using a singleton trivial buffer allocator. Performs a
-// copy.
-QuicMemSlice MemSliceFromString(absl::string_view data);
-
-// Used to compare ReceivedPacketInfo.
-MATCHER_P(ReceivedPacketInfoEquals, info, "") {
- return info.ToString() == arg.ToString();
-}
-
-MATCHER_P(ReceivedPacketInfoConnectionIdEquals, destination_connection_id, "") {
- return arg.destination_connection_id == destination_connection_id;
-}
-
-MATCHER_P2(InRange, min, max, "") { return arg >= min && arg <= max; }
-
-// A GMock matcher that prints expected and actual QuicErrorCode strings
-// upon failure. Example usage:
-// EXPECT_THAT(stream_->connection_error(), IsError(QUIC_INTERNAL_ERROR));
-MATCHER_P(IsError, expected,
- absl::StrCat(negation ? "isn't equal to " : "is equal to ",
- QuicErrorCodeToString(expected))) {
- *result_listener << QuicErrorCodeToString(static_cast<QuicErrorCode>(arg));
- return arg == expected;
-}
-
-// Shorthand for IsError(QUIC_NO_ERROR).
-// Example usage: EXPECT_THAT(stream_->connection_error(), IsQuicNoError());
-MATCHER(IsQuicNoError,
- absl::StrCat(negation ? "isn't equal to " : "is equal to ",
- QuicErrorCodeToString(QUIC_NO_ERROR))) {
- *result_listener << QuicErrorCodeToString(arg);
- return arg == QUIC_NO_ERROR;
-}
-
-// A GMock matcher that prints expected and actual QuicRstStreamErrorCode
-// strings upon failure. Example usage:
-// EXPECT_THAT(stream_->stream_error(), IsStreamError(QUIC_INTERNAL_ERROR));
-MATCHER_P(IsStreamError, expected,
- absl::StrCat(negation ? "isn't equal to " : "is equal to ",
- QuicRstStreamErrorCodeToString(expected))) {
- *result_listener << QuicRstStreamErrorCodeToString(arg);
- return arg == expected;
-}
-
-// Shorthand for IsStreamError(QUIC_STREAM_NO_ERROR). Example usage:
-// EXPECT_THAT(stream_->stream_error(), IsQuicStreamNoError());
-MATCHER(IsQuicStreamNoError,
- absl::StrCat(negation ? "isn't equal to " : "is equal to ",
- QuicRstStreamErrorCodeToString(QUIC_STREAM_NO_ERROR))) {
- *result_listener << QuicRstStreamErrorCodeToString(arg);
- return arg == QUIC_STREAM_NO_ERROR;
-}
-
-// TaggingEncrypter appends kTagSize bytes of |tag| to the end of each message.
-class TaggingEncrypter : public QuicEncrypter {
- public:
- explicit TaggingEncrypter(uint8_t tag) : tag_(tag) {}
- TaggingEncrypter(const TaggingEncrypter&) = delete;
- TaggingEncrypter& operator=(const TaggingEncrypter&) = delete;
-
- ~TaggingEncrypter() override {}
-
- // QuicEncrypter interface.
- bool SetKey(absl::string_view /*key*/) override { return true; }
-
- bool SetNoncePrefix(absl::string_view /*nonce_prefix*/) override {
- return true;
- }
-
- bool SetIV(absl::string_view /*iv*/) override { return true; }
-
- bool SetHeaderProtectionKey(absl::string_view /*key*/) override {
- return true;
- }
-
- bool EncryptPacket(uint64_t packet_number, absl::string_view associated_data,
- absl::string_view plaintext, char* output,
- size_t* output_length, size_t max_output_length) override;
-
- std::string GenerateHeaderProtectionMask(
- absl::string_view /*sample*/) override {
- return std::string(5, 0);
- }
-
- size_t GetKeySize() const override { return 0; }
- size_t GetNoncePrefixSize() const override { return 0; }
- size_t GetIVSize() const override { return 0; }
-
- size_t GetMaxPlaintextSize(size_t ciphertext_size) const override {
- return ciphertext_size - kTagSize;
- }
-
- size_t GetCiphertextSize(size_t plaintext_size) const override {
- return plaintext_size + kTagSize;
- }
-
- QuicPacketCount GetConfidentialityLimit() const override {
- return std::numeric_limits<QuicPacketCount>::max();
- }
-
- absl::string_view GetKey() const override { return absl::string_view(); }
-
- absl::string_view GetNoncePrefix() const override {
- return absl::string_view();
- }
-
- private:
- enum {
- kTagSize = 12,
- };
-
- const uint8_t tag_;
-};
-
-// TaggingDecrypter ensures that the final kTagSize bytes of the message all
-// have the same value and then removes them.
-class TaggingDecrypter : public QuicDecrypter {
- public:
- ~TaggingDecrypter() override {}
-
- // QuicDecrypter interface
- bool SetKey(absl::string_view /*key*/) override { return true; }
-
- bool SetNoncePrefix(absl::string_view /*nonce_prefix*/) override {
- return true;
- }
-
- bool SetIV(absl::string_view /*iv*/) override { return true; }
-
- bool SetHeaderProtectionKey(absl::string_view /*key*/) override {
- return true;
- }
-
- bool SetPreliminaryKey(absl::string_view /*key*/) override {
- QUIC_BUG(quic_bug_10230_1) << "should not be called";
- return false;
- }
-
- bool SetDiversificationNonce(const DiversificationNonce& /*key*/) override {
- return true;
- }
-
- bool DecryptPacket(uint64_t packet_number, absl::string_view associated_data,
- absl::string_view ciphertext, char* output,
- size_t* output_length, size_t max_output_length) override;
-
- std::string GenerateHeaderProtectionMask(
- QuicDataReader* /*sample_reader*/) override {
- return std::string(5, 0);
- }
-
- size_t GetKeySize() const override { return 0; }
- size_t GetNoncePrefixSize() const override { return 0; }
- size_t GetIVSize() const override { return 0; }
- absl::string_view GetKey() const override { return absl::string_view(); }
- absl::string_view GetNoncePrefix() const override {
- return absl::string_view();
- }
- // Use a distinct value starting with 0xFFFFFF, which is never used by TLS.
- uint32_t cipher_id() const override { return 0xFFFFFFF0; }
- QuicPacketCount GetIntegrityLimit() const override {
- return std::numeric_limits<QuicPacketCount>::max();
- }
-
- protected:
- virtual uint8_t GetTag(absl::string_view ciphertext) {
- return ciphertext.data()[ciphertext.size() - 1];
- }
-
- private:
- enum {
- kTagSize = 12,
- };
-
- bool CheckTag(absl::string_view ciphertext, uint8_t tag);
-};
-
-// StringTaggingDecrypter ensures that the final kTagSize bytes of the message
-// match the expected value.
-class StrictTaggingDecrypter : public TaggingDecrypter {
- public:
- explicit StrictTaggingDecrypter(uint8_t tag) : tag_(tag) {}
- ~StrictTaggingDecrypter() override {}
-
- // TaggingQuicDecrypter
- uint8_t GetTag(absl::string_view /*ciphertext*/) override { return tag_; }
-
- // Use a distinct value starting with 0xFFFFFF, which is never used by TLS.
- uint32_t cipher_id() const override { return 0xFFFFFFF1; }
-
- private:
- const uint8_t tag_;
-};
-
-class TestPacketWriter : public QuicPacketWriter {
- struct PacketBuffer {
- ABSL_CACHELINE_ALIGNED char buffer[1500];
- bool in_use = false;
- };
-
- public:
- TestPacketWriter(ParsedQuicVersion version, MockClock* clock,
- Perspective perspective);
-
- TestPacketWriter(const TestPacketWriter&) = delete;
- TestPacketWriter& operator=(const TestPacketWriter&) = delete;
-
- ~TestPacketWriter() override;
-
- // QuicPacketWriter interface
- WriteResult WritePacket(const char* buffer, size_t buf_len,
- const QuicIpAddress& self_address,
- const QuicSocketAddress& peer_address,
- PerPacketOptions* options) override;
-
- bool ShouldWriteFail() { return write_should_fail_; }
-
- bool IsWriteBlocked() const override { return write_blocked_; }
-
- void SetWriteBlocked() { write_blocked_ = true; }
-
- void SetWritable() override { write_blocked_ = false; }
-
- void SetShouldWriteFail() { write_should_fail_ = true; }
-
- void SetWriteError(int error_code) { write_error_code_ = error_code; }
-
- QuicByteCount GetMaxPacketSize(
- const QuicSocketAddress& /*peer_address*/) const override {
- return max_packet_size_;
- }
-
- bool SupportsReleaseTime() const override { return supports_release_time_; }
-
- bool IsBatchMode() const override { return is_batch_mode_; }
-
- QuicPacketBuffer GetNextWriteLocation(
- const QuicIpAddress& /*self_address*/,
- const QuicSocketAddress& /*peer_address*/) override;
-
- WriteResult Flush() override;
-
- void BlockOnNextFlush() { block_on_next_flush_ = true; }
-
- void BlockOnNextWrite() { block_on_next_write_ = true; }
-
- void SimulateNextPacketTooLarge() { next_packet_too_large_ = true; }
-
- void AlwaysGetPacketTooLarge() { always_get_packet_too_large_ = true; }
-
- // Sets the amount of time that the writer should before the actual write.
- void SetWritePauseTimeDelta(QuicTime::Delta delta) {
- write_pause_time_delta_ = delta;
- }
-
- void SetBatchMode(bool new_value) { is_batch_mode_ = new_value; }
-
- const QuicPacketHeader& header() { return framer_.header(); }
-
- size_t frame_count() const { return framer_.num_frames(); }
-
- const std::vector<QuicAckFrame>& ack_frames() const {
- return framer_.ack_frames();
- }
-
- const std::vector<QuicStopWaitingFrame>& stop_waiting_frames() const {
- return framer_.stop_waiting_frames();
- }
-
- const std::vector<QuicConnectionCloseFrame>& connection_close_frames() const {
- return framer_.connection_close_frames();
- }
-
- const std::vector<QuicRstStreamFrame>& rst_stream_frames() const {
- return framer_.rst_stream_frames();
- }
-
- const std::vector<std::unique_ptr<QuicStreamFrame>>& stream_frames() const {
- return framer_.stream_frames();
- }
-
- const std::vector<std::unique_ptr<QuicCryptoFrame>>& crypto_frames() const {
- return framer_.crypto_frames();
- }
-
- const std::vector<QuicPingFrame>& ping_frames() const {
- return framer_.ping_frames();
- }
-
- const std::vector<QuicMessageFrame>& message_frames() const {
- return framer_.message_frames();
- }
-
- const std::vector<QuicWindowUpdateFrame>& window_update_frames() const {
- return framer_.window_update_frames();
- }
-
- const std::vector<QuicPaddingFrame>& padding_frames() const {
- return framer_.padding_frames();
- }
-
- const std::vector<QuicPathChallengeFrame>& path_challenge_frames() const {
- return framer_.path_challenge_frames();
- }
-
- const std::vector<QuicPathResponseFrame>& path_response_frames() const {
- return framer_.path_response_frames();
- }
-
- const QuicEncryptedPacket* coalesced_packet() const {
- return framer_.coalesced_packet();
- }
-
- size_t last_packet_size() { return last_packet_size_; }
-
- const QuicPacketHeader& last_packet_header() const {
- return last_packet_header_;
- }
-
- const QuicVersionNegotiationPacket* version_negotiation_packet() {
- return framer_.version_negotiation_packet();
- }
-
- void set_is_write_blocked_data_buffered(bool buffered) {
- is_write_blocked_data_buffered_ = buffered;
- }
-
- void set_perspective(Perspective perspective) {
- // We invert perspective here, because the framer needs to parse packets
- // we send.
- QuicFramerPeer::SetPerspective(framer_.framer(),
- QuicUtils::InvertPerspective(perspective));
- framer_.framer()->SetInitialObfuscators(TestConnectionId());
- }
-
- // final_bytes_of_last_packet_ returns the last four bytes of the previous
- // packet as a little-endian, uint32_t. This is intended to be used with a
- // TaggingEncrypter so that tests can determine which encrypter was used for
- // a given packet.
- uint32_t final_bytes_of_last_packet() { return final_bytes_of_last_packet_; }
-
- // Returns the final bytes of the second to last packet.
- uint32_t final_bytes_of_previous_packet() {
- return final_bytes_of_previous_packet_;
- }
-
- void use_tagging_decrypter() { use_tagging_decrypter_ = true; }
-
- uint32_t packets_write_attempts() const { return packets_write_attempts_; }
-
- uint32_t flush_attempts() const { return flush_attempts_; }
-
- uint32_t connection_close_packets() const {
- return connection_close_packets_;
- }
-
- void Reset() { framer_.Reset(); }
-
- void SetSupportedVersions(const ParsedQuicVersionVector& versions) {
- framer_.SetSupportedVersions(versions);
- }
-
- void set_max_packet_size(QuicByteCount max_packet_size) {
- max_packet_size_ = max_packet_size;
- }
-
- void set_supports_release_time(bool supports_release_time) {
- supports_release_time_ = supports_release_time;
- }
-
- SimpleQuicFramer* framer() { return &framer_; }
-
- const QuicIpAddress& last_write_source_address() const {
- return last_write_source_address_;
- }
-
- const QuicSocketAddress& last_write_peer_address() const {
- return last_write_peer_address_;
- }
-
- private:
- char* AllocPacketBuffer();
-
- void FreePacketBuffer(const char* buffer);
-
- ParsedQuicVersion version_;
- SimpleQuicFramer framer_;
- size_t last_packet_size_ = 0;
- QuicPacketHeader last_packet_header_;
- bool write_blocked_ = false;
- bool write_should_fail_ = false;
- bool block_on_next_flush_ = false;
- bool block_on_next_write_ = false;
- bool next_packet_too_large_ = false;
- bool always_get_packet_too_large_ = false;
- bool is_write_blocked_data_buffered_ = false;
- bool is_batch_mode_ = false;
- // Number of times Flush() was called.
- uint32_t flush_attempts_ = 0;
- // (Batch mode only) Number of bytes buffered in writer. It is used as the
- // return value of a successful Flush().
- uint32_t bytes_buffered_ = 0;
- uint32_t final_bytes_of_last_packet_ = 0;
- uint32_t final_bytes_of_previous_packet_ = 0;
- bool use_tagging_decrypter_ = false;
- uint32_t packets_write_attempts_ = 0;
- uint32_t connection_close_packets_ = 0;
- MockClock* clock_ = nullptr;
- // If non-zero, the clock will pause during WritePacket for this amount of
- // time.
- QuicTime::Delta write_pause_time_delta_ = QuicTime::Delta::Zero();
- QuicByteCount max_packet_size_ = kMaxOutgoingPacketSize;
- bool supports_release_time_ = false;
- // Used to verify writer-allocated packet buffers are properly released.
- std::vector<PacketBuffer*> packet_buffer_pool_;
- // Buffer address => Address of the owning PacketBuffer.
- absl::flat_hash_map<char*, PacketBuffer*, absl::Hash<char*>>
- packet_buffer_pool_index_;
- // Indices in packet_buffer_pool_ that are not allocated.
- std::list<PacketBuffer*> packet_buffer_free_list_;
- // The soruce/peer address passed into WritePacket().
- QuicIpAddress last_write_source_address_;
- QuicSocketAddress last_write_peer_address_;
- int write_error_code_{0};
-};
-
-// Parses a packet generated by
-// QuicFramer::WriteClientVersionNegotiationProbePacket.
-// |packet_bytes| must point to |packet_length| bytes in memory which represent
-// the packet. This method will fill in |destination_connection_id_bytes|
-// which must point to at least |*destination_connection_id_length_out| bytes in
-// memory. |*destination_connection_id_length_out| will contain the length of
-// the received destination connection ID, which on success will match the
-// contents of the destination connection ID passed in to
-// WriteClientVersionNegotiationProbePacket.
-bool ParseClientVersionNegotiationProbePacket(
- const char* packet_bytes, size_t packet_length,
- char* destination_connection_id_bytes,
- uint8_t* destination_connection_id_length_out);
-
-// Writes an array of bytes that correspond to a QUIC version negotiation packet
-// that a QUIC server would send in response to a probe created by
-// QuicFramer::WriteClientVersionNegotiationProbePacket.
-// The bytes will be written to |packet_bytes|, which must point to
-// |*packet_length_out| bytes of memory. |*packet_length_out| will contain the
-// length of the created packet. |source_connection_id_bytes| will be sent as
-// the source connection ID, and must point to |source_connection_id_length|
-// bytes of memory.
-bool WriteServerVersionNegotiationProbeResponse(
- char* packet_bytes, size_t* packet_length_out,
- const char* source_connection_id_bytes,
- uint8_t source_connection_id_length);
-
-// Implementation of Http3DatagramVisitor which saves all received datagrams.
-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;
- }
- };
- const std::vector<SavedHttp3Datagram>& received_h3_datagrams() const {
- return received_h3_datagrams_;
- }
-
- // 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)});
- }
-
- 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
-
-#endif // QUICHE_QUIC_TEST_TOOLS_QUIC_TEST_UTILS_H_
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/quic_test_utils_test.cc b/chromium/net/third_party/quiche/src/quic/test_tools/quic_test_utils_test.cc
deleted file mode 100644
index f7be77cca38..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/quic_test_utils_test.cc
+++ /dev/null
@@ -1,79 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/quic_test_utils.h"
-
-#include "quic/platform/api/quic_test.h"
-
-namespace quic {
-namespace test {
-
-class QuicTestUtilsTest : public QuicTest {};
-
-TEST_F(QuicTestUtilsTest, ConnectionId) {
- EXPECT_NE(EmptyQuicConnectionId(), TestConnectionId());
- EXPECT_NE(EmptyQuicConnectionId(), TestConnectionId(1));
- EXPECT_EQ(TestConnectionId(), TestConnectionId());
- EXPECT_EQ(TestConnectionId(33), TestConnectionId(33));
- EXPECT_NE(TestConnectionId(0xdead), TestConnectionId(0xbeef));
- EXPECT_EQ(0x1337u, TestConnectionIdToUInt64(TestConnectionId(0x1337)));
- EXPECT_NE(0xdeadu, TestConnectionIdToUInt64(TestConnectionId(0xbeef)));
-}
-
-TEST_F(QuicTestUtilsTest, BasicApproxEq) {
- EXPECT_APPROX_EQ(10, 10, 1e-6f);
- EXPECT_APPROX_EQ(1000, 1001, 0.01f);
- EXPECT_NONFATAL_FAILURE(EXPECT_APPROX_EQ(1000, 1100, 0.01f), "");
-
- EXPECT_APPROX_EQ(64, 31, 0.55f);
- EXPECT_NONFATAL_FAILURE(EXPECT_APPROX_EQ(31, 64, 0.55f), "");
-}
-
-TEST_F(QuicTestUtilsTest, QuicTimeDelta) {
- EXPECT_APPROX_EQ(QuicTime::Delta::FromMicroseconds(1000),
- QuicTime::Delta::FromMicroseconds(1003), 0.01f);
- EXPECT_NONFATAL_FAILURE(
- EXPECT_APPROX_EQ(QuicTime::Delta::FromMicroseconds(1000),
- QuicTime::Delta::FromMicroseconds(1200), 0.01f),
- "");
-}
-
-TEST_F(QuicTestUtilsTest, QuicBandwidth) {
- EXPECT_APPROX_EQ(QuicBandwidth::FromBytesPerSecond(1000),
- QuicBandwidth::FromBitsPerSecond(8005), 0.01f);
- EXPECT_NONFATAL_FAILURE(
- EXPECT_APPROX_EQ(QuicBandwidth::FromBytesPerSecond(1000),
- QuicBandwidth::FromBitsPerSecond(9005), 0.01f),
- "");
-}
-
-// Ensure that SimpleRandom does not change its output for a fixed seed.
-TEST_F(QuicTestUtilsTest, SimpleRandomStability) {
- SimpleRandom rng;
- rng.set_seed(UINT64_C(0x1234567800010001));
- EXPECT_EQ(UINT64_C(12589383305231984671), rng.RandUint64());
- EXPECT_EQ(UINT64_C(17775425089941798664), rng.RandUint64());
-}
-
-// Ensure that the output of SimpleRandom does not depend on the size of the
-// read calls.
-TEST_F(QuicTestUtilsTest, SimpleRandomChunks) {
- SimpleRandom rng;
- std::string reference(16 * 1024, '\0');
- rng.RandBytes(&reference[0], reference.size());
-
- for (size_t chunk_size : {3, 4, 7, 4096}) {
- rng.set_seed(0);
- size_t chunks = reference.size() / chunk_size;
- std::string buffer(chunks * chunk_size, '\0');
- for (size_t i = 0; i < chunks; i++) {
- rng.RandBytes(&buffer[i * chunk_size], chunk_size);
- }
- EXPECT_EQ(reference.substr(0, buffer.size()), buffer)
- << "Failed for chunk_size = " << chunk_size;
- }
-}
-
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/quic_time_wait_list_manager_peer.cc b/chromium/net/third_party/quiche/src/quic/test_tools/quic_time_wait_list_manager_peer.cc
deleted file mode 100644
index cbcd36e1550..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/quic_time_wait_list_manager_peer.cc
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/quic_time_wait_list_manager_peer.h"
-
-namespace quic {
-namespace test {
-
-bool QuicTimeWaitListManagerPeer::ShouldSendResponse(
- QuicTimeWaitListManager* manager,
- int received_packet_count) {
- return manager->ShouldSendResponse(received_packet_count);
-}
-
-QuicTime::Delta QuicTimeWaitListManagerPeer::time_wait_period(
- QuicTimeWaitListManager* manager) {
- return manager->time_wait_period_;
-}
-
-QuicAlarm* QuicTimeWaitListManagerPeer::expiration_alarm(
- QuicTimeWaitListManager* manager) {
- return manager->connection_id_clean_up_alarm_.get();
-}
-
-void QuicTimeWaitListManagerPeer::set_clock(QuicTimeWaitListManager* manager,
- const QuicClock* clock) {
- manager->clock_ = clock;
-}
-
-// static
-bool QuicTimeWaitListManagerPeer::SendOrQueuePacket(
- QuicTimeWaitListManager* manager,
- std::unique_ptr<QuicTimeWaitListManager::QueuedPacket> packet,
- const QuicPerPacketContext* packet_context) {
- return manager->SendOrQueuePacket(std::move(packet), packet_context);
-}
-
-// static
-size_t QuicTimeWaitListManagerPeer::PendingPacketsQueueSize(
- QuicTimeWaitListManager* manager) {
- return manager->pending_packets_queue_.size();
-}
-
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/quic_time_wait_list_manager_peer.h b/chromium/net/third_party/quiche/src/quic/test_tools/quic_time_wait_list_manager_peer.h
deleted file mode 100644
index a314e039591..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/quic_time_wait_list_manager_peer.h
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_QUIC_TIME_WAIT_LIST_MANAGER_PEER_H_
-#define QUICHE_QUIC_TEST_TOOLS_QUIC_TIME_WAIT_LIST_MANAGER_PEER_H_
-
-#include "quic/core/quic_time_wait_list_manager.h"
-
-namespace quic {
-namespace test {
-
-class QuicTimeWaitListManagerPeer {
- public:
- static bool ShouldSendResponse(QuicTimeWaitListManager* manager,
- int received_packet_count);
-
- static QuicTime::Delta time_wait_period(QuicTimeWaitListManager* manager);
-
- static QuicAlarm* expiration_alarm(QuicTimeWaitListManager* manager);
-
- static void set_clock(QuicTimeWaitListManager* manager,
- const QuicClock* clock);
-
- static bool SendOrQueuePacket(
- QuicTimeWaitListManager* manager,
- std::unique_ptr<QuicTimeWaitListManager::QueuedPacket> packet,
- const QuicPerPacketContext* packet_context);
-
- static size_t PendingPacketsQueueSize(QuicTimeWaitListManager* manager);
-};
-
-} // namespace test
-} // namespace quic
-
-#endif // QUICHE_QUIC_TEST_TOOLS_QUIC_TIME_WAIT_LIST_MANAGER_PEER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/quic_transport_test_tools.h b/chromium/net/third_party/quiche/src/quic/test_tools/quic_transport_test_tools.h
deleted file mode 100644
index 5babfd280cb..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/quic_transport_test_tools.h
+++ /dev/null
@@ -1,48 +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_TEST_TOOLS_QUIC_TRANSPORT_TEST_TOOLS_H_
-#define QUICHE_QUIC_TEST_TOOLS_QUIC_TRANSPORT_TEST_TOOLS_H_
-
-#include "quic/core/web_transport_interface.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/quic_transport/quic_transport_server_session.h"
-
-namespace quic {
-namespace test {
-
-class MockClientVisitor : public WebTransportVisitor {
- public:
- MOCK_METHOD(void, OnSessionReady, (const spdy::SpdyHeaderBlock&), (override));
- MOCK_METHOD(void, OnSessionClosed,
- (WebTransportSessionError, const std::string&), (override));
- MOCK_METHOD(void, OnIncomingBidirectionalStreamAvailable, (), (override));
- MOCK_METHOD(void, OnIncomingUnidirectionalStreamAvailable, (), (override));
- MOCK_METHOD(void, OnDatagramReceived, (absl::string_view), (override));
- MOCK_METHOD(void, OnCanCreateNewOutgoingBidirectionalStream, (), (override));
- MOCK_METHOD(void, OnCanCreateNewOutgoingUnidirectionalStream, (), (override));
-};
-
-class MockServerVisitor : public QuicTransportServerSession::ServerVisitor {
- public:
- MOCK_METHOD(bool, CheckOrigin, (url::Origin), (override));
- MOCK_METHOD(bool, ProcessPath, (const GURL&), (override));
-};
-
-class MockStreamVisitor : public WebTransportStreamVisitor {
- public:
- MOCK_METHOD(void, OnCanRead, (), (override));
- MOCK_METHOD(void, OnCanWrite, (), (override));
-
- MOCK_METHOD(void, OnResetStreamReceived, (WebTransportStreamError error),
- (override));
- MOCK_METHOD(void, OnStopSendingReceived, (WebTransportStreamError error),
- (override));
- MOCK_METHOD(void, OnWriteSideInDataRecvdState, (), (override));
-};
-
-} // namespace test
-} // namespace quic
-
-#endif // QUICHE_QUIC_TEST_TOOLS_QUIC_TRANSPORT_TEST_TOOLS_H_
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/quic_unacked_packet_map_peer.cc b/chromium/net/third_party/quiche/src/quic/test_tools/quic_unacked_packet_map_peer.cc
deleted file mode 100644
index 61fda95b40d..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/quic_unacked_packet_map_peer.cc
+++ /dev/null
@@ -1,30 +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 "quic/test_tools/quic_unacked_packet_map_peer.h"
-
-namespace quic {
-namespace test {
-
-// static
-const QuicStreamFrame& QuicUnackedPacketMapPeer::GetAggregatedStreamFrame(
- const QuicUnackedPacketMap& unacked_packets) {
- return unacked_packets.aggregated_stream_frame_;
-}
-
-// static
-void QuicUnackedPacketMapPeer::SetPerspective(
- QuicUnackedPacketMap* unacked_packets,
- Perspective perspective) {
- *const_cast<Perspective*>(&unacked_packets->perspective_) = perspective;
-}
-
-// static
-size_t QuicUnackedPacketMapPeer::GetCapacity(
- const QuicUnackedPacketMap& unacked_packets) {
- return unacked_packets.unacked_packets_.capacity();
-}
-
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/quic_unacked_packet_map_peer.h b/chromium/net/third_party/quiche/src/quic/test_tools/quic_unacked_packet_map_peer.h
deleted file mode 100644
index c21bcee3952..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/quic_unacked_packet_map_peer.h
+++ /dev/null
@@ -1,27 +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_TEST_TOOLS_QUIC_UNACKED_PACKET_MAP_PEER_H_
-#define QUICHE_QUIC_TEST_TOOLS_QUIC_UNACKED_PACKET_MAP_PEER_H_
-
-#include "quic/core/quic_unacked_packet_map.h"
-
-namespace quic {
-namespace test {
-
-class QuicUnackedPacketMapPeer {
- public:
- static const QuicStreamFrame& GetAggregatedStreamFrame(
- const QuicUnackedPacketMap& unacked_packets);
-
- static void SetPerspective(QuicUnackedPacketMap* unacked_packets,
- Perspective perspective);
-
- static size_t GetCapacity(const QuicUnackedPacketMap& unacked_packets);
-};
-
-} // namespace test
-} // namespace quic
-
-#endif // QUICHE_QUIC_TEST_TOOLS_QUIC_UNACKED_PACKET_MAP_PEER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/rtt_stats_peer.cc b/chromium/net/third_party/quiche/src/quic/test_tools/rtt_stats_peer.cc
deleted file mode 100644
index 79325c45ff4..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/rtt_stats_peer.cc
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/rtt_stats_peer.h"
-
-namespace quic {
-namespace test {
-
-// static
-void RttStatsPeer::SetSmoothedRtt(RttStats* rtt_stats, QuicTime::Delta rtt_ms) {
- rtt_stats->smoothed_rtt_ = rtt_ms;
-}
-
-// static
-void RttStatsPeer::SetMinRtt(RttStats* rtt_stats, QuicTime::Delta rtt_ms) {
- rtt_stats->min_rtt_ = rtt_ms;
-}
-
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/rtt_stats_peer.h b/chromium/net/third_party/quiche/src/quic/test_tools/rtt_stats_peer.h
deleted file mode 100644
index bd06ecc5c5b..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/rtt_stats_peer.h
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_RTT_STATS_PEER_H_
-#define QUICHE_QUIC_TEST_TOOLS_RTT_STATS_PEER_H_
-
-#include "quic/core/congestion_control/rtt_stats.h"
-#include "quic/core/quic_time.h"
-
-namespace quic {
-namespace test {
-
-class RttStatsPeer {
- public:
- RttStatsPeer() = delete;
-
- static void SetSmoothedRtt(RttStats* rtt_stats, QuicTime::Delta rtt_ms);
-
- static void SetMinRtt(RttStats* rtt_stats, QuicTime::Delta rtt_ms);
-};
-
-} // namespace test
-} // namespace quic
-
-#endif // QUICHE_QUIC_TEST_TOOLS_RTT_STATS_PEER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/send_algorithm_test_result.proto b/chromium/net/third_party/quiche/src/quic/test_tools/send_algorithm_test_result.proto
deleted file mode 100644
index a836c474ba0..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/send_algorithm_test_result.proto
+++ /dev/null
@@ -1,15 +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.
-
-syntax = "proto2";
-
-option optimize_for = LITE_RUNTIME;
-
-package quic;
-
-message SendAlgorithmTestResult {
- optional string test_name = 1;
- optional uint64 random_seed = 2;
- optional int64 simulated_duration_micros = 3;
-}
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/send_algorithm_test_utils.cc b/chromium/net/third_party/quiche/src/quic/test_tools/send_algorithm_test_utils.cc
deleted file mode 100644
index 074028ac792..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/send_algorithm_test_utils.cc
+++ /dev/null
@@ -1,61 +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 "quic/test_tools/send_algorithm_test_utils.h"
-
-#include "absl/strings/str_cat.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/platform/api/quic_test_output.h"
-
-namespace quic {
-namespace test {
-
-bool LoadSendAlgorithmTestResult(SendAlgorithmTestResult* result) {
- std::string test_result_file_content;
- if (!QuicLoadTestOutput(GetSendAlgorithmTestResultFilename(),
- &test_result_file_content)) {
- return false;
- }
- return result->ParseFromString(test_result_file_content);
-}
-
-void RecordSendAlgorithmTestResult(uint64_t random_seed,
- int64_t simulated_duration_micros) {
- SendAlgorithmTestResult result;
- result.set_test_name(GetFullSendAlgorithmTestName());
- result.set_random_seed(random_seed);
- result.set_simulated_duration_micros(simulated_duration_micros);
-
- QuicSaveTestOutput(GetSendAlgorithmTestResultFilename(),
- result.SerializeAsString());
-}
-
-void CompareSendAlgorithmTestResult(int64_t actual_simulated_duration_micros) {
- SendAlgorithmTestResult expected;
- ASSERT_TRUE(LoadSendAlgorithmTestResult(&expected));
- QUIC_LOG(INFO) << "Loaded expected test result: "
- << expected.ShortDebugString();
-
- EXPECT_GE(expected.simulated_duration_micros(),
- actual_simulated_duration_micros);
-}
-
-std::string GetFullSendAlgorithmTestName() {
- const auto* test_info =
- ::testing::UnitTest::GetInstance()->current_test_info();
- const std::string type_param =
- test_info->type_param() ? test_info->type_param() : "";
- const std::string value_param =
- test_info->value_param() ? test_info->value_param() : "";
- return absl::StrCat(test_info->test_suite_name(), ".", test_info->name(), "_",
- type_param, "_", value_param);
-}
-
-std::string GetSendAlgorithmTestResultFilename() {
- return GetFullSendAlgorithmTestName() + ".test_result";
-}
-
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/send_algorithm_test_utils.h b/chromium/net/third_party/quiche/src/quic/test_tools/send_algorithm_test_utils.h
deleted file mode 100644
index 430e42aa068..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/send_algorithm_test_utils.h
+++ /dev/null
@@ -1,29 +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_TEST_TOOLS_SEND_ALGORITHM_TEST_UTILS_H_
-#define QUICHE_QUIC_TEST_TOOLS_SEND_ALGORITHM_TEST_UTILS_H_
-
-#include "quic/test_tools/send_algorithm_test_result.pb.h"
-
-namespace quic {
-namespace test {
-
-bool LoadSendAlgorithmTestResult(SendAlgorithmTestResult* result);
-
-void RecordSendAlgorithmTestResult(uint64_t random_seed,
- int64_t simulated_duration_micros);
-
-// Load the expected test result with LoadSendAlgorithmTestResult(), and compare
-// it with the actual results provided in the arguments.
-void CompareSendAlgorithmTestResult(int64_t actual_simulated_duration_micros);
-
-std::string GetFullSendAlgorithmTestName();
-
-std::string GetSendAlgorithmTestResultFilename();
-
-} // namespace test
-} // namespace quic
-
-#endif // QUICHE_QUIC_TEST_TOOLS_SEND_ALGORITHM_TEST_UTILS_H_
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/server_thread.cc b/chromium/net/third_party/quiche/src/quic/test_tools/server_thread.cc
deleted file mode 100644
index f931567793e..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/server_thread.cc
+++ /dev/null
@@ -1,141 +0,0 @@
-// Copyright 2013 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 "quic/test_tools/server_thread.h"
-
-#include "quic/core/quic_dispatcher.h"
-#include "quic/platform/api/quic_containers.h"
-#include "quic/test_tools/crypto_test_utils.h"
-#include "quic/test_tools/quic_dispatcher_peer.h"
-#include "quic/test_tools/quic_server_peer.h"
-
-namespace quic {
-namespace test {
-
-ServerThread::ServerThread(QuicServer* server, const QuicSocketAddress& address)
- : QuicThread("server_thread"),
- server_(server),
- clock_(server->epoll_server()),
- address_(address),
- port_(0),
- initialized_(false) {}
-
-ServerThread::~ServerThread() = default;
-
-void ServerThread::Initialize() {
- if (initialized_) {
- return;
- }
-
- server_->CreateUDPSocketAndListen(address_);
-
- QuicWriterMutexLock lock(&port_lock_);
- port_ = server_->port();
-
- initialized_ = true;
-}
-
-void ServerThread::Run() {
- if (!initialized_) {
- Initialize();
- }
-
- while (!quit_.HasBeenNotified()) {
- if (pause_.HasBeenNotified() && !resume_.HasBeenNotified()) {
- paused_.Notify();
- resume_.WaitForNotification();
- }
- server_->WaitForEvents();
- ExecuteScheduledActions();
- MaybeNotifyOfHandshakeConfirmation();
- }
-
- server_->Shutdown();
-}
-
-int ServerThread::GetPort() {
- QuicReaderMutexLock lock(&port_lock_);
- int rc = port_;
- return rc;
-}
-
-void ServerThread::Schedule(std::function<void()> action) {
- QUICHE_DCHECK(!quit_.HasBeenNotified());
- QuicWriterMutexLock lock(&scheduled_actions_lock_);
- scheduled_actions_.push_back(std::move(action));
-}
-
-void ServerThread::WaitForCryptoHandshakeConfirmed() {
- confirmed_.WaitForNotification();
-}
-
-bool ServerThread::WaitUntil(std::function<bool()> termination_predicate,
- QuicTime::Delta timeout) {
- const QuicTime deadline = clock_.Now() + timeout;
- while (clock_.Now() < deadline) {
- QuicNotification done_checking;
- bool should_terminate = false;
- Schedule([&] {
- should_terminate = termination_predicate();
- done_checking.Notify();
- });
- done_checking.WaitForNotification();
- if (should_terminate) {
- return true;
- }
- }
- return false;
-}
-
-void ServerThread::Pause() {
- QUICHE_DCHECK(!pause_.HasBeenNotified());
- pause_.Notify();
- paused_.WaitForNotification();
-}
-
-void ServerThread::Resume() {
- QUICHE_DCHECK(!resume_.HasBeenNotified());
- QUICHE_DCHECK(pause_.HasBeenNotified());
- resume_.Notify();
-}
-
-void ServerThread::Quit() {
- if (pause_.HasBeenNotified() && !resume_.HasBeenNotified()) {
- resume_.Notify();
- }
- if (!quit_.HasBeenNotified()) {
- quit_.Notify();
- }
-}
-
-void ServerThread::MaybeNotifyOfHandshakeConfirmation() {
- if (confirmed_.HasBeenNotified()) {
- // Only notify once.
- return;
- }
- QuicDispatcher* dispatcher = QuicServerPeer::GetDispatcher(server());
- if (dispatcher->NumSessions() == 0) {
- // Wait for a session to be created.
- return;
- }
- QuicSession* session = QuicDispatcherPeer::GetFirstSessionIfAny(dispatcher);
- if (session->OneRttKeysAvailable()) {
- confirmed_.Notify();
- }
-}
-
-void ServerThread::ExecuteScheduledActions() {
- quiche::QuicheCircularDeque<std::function<void()>> actions;
- {
- QuicWriterMutexLock lock(&scheduled_actions_lock_);
- actions.swap(scheduled_actions_);
- }
- while (!actions.empty()) {
- actions.front()();
- actions.pop_front();
- }
-}
-
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/server_thread.h b/chromium/net/third_party/quiche/src/quic/test_tools/server_thread.h
deleted file mode 100644
index 81d0bf2a5f5..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/server_thread.h
+++ /dev/null
@@ -1,96 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_SERVER_THREAD_H_
-#define QUICHE_QUIC_TEST_TOOLS_SERVER_THREAD_H_
-
-#include <memory>
-
-#include "quic/core/quic_config.h"
-#include "quic/platform/api/quic_containers.h"
-#include "quic/platform/api/quic_mutex.h"
-#include "quic/platform/api/quic_socket_address.h"
-#include "quic/platform/api/quic_thread.h"
-#include "quic/tools/quic_server.h"
-
-namespace quic {
-namespace test {
-
-// Simple wrapper class to run QuicServer in a dedicated thread.
-class ServerThread : public QuicThread {
- public:
- ServerThread(QuicServer* server, const QuicSocketAddress& address);
- ServerThread(const ServerThread&) = delete;
- ServerThread& operator=(const ServerThread&) = delete;
-
- ~ServerThread() override;
-
- // Prepares the server, but does not start accepting connections. Useful for
- // injecting mocks.
- void Initialize();
-
- // Runs the event loop. Will initialize if necessary.
- void Run() override;
-
- // Schedules the given action for execution in the event loop.
- void Schedule(std::function<void()> action);
-
- // Waits for the handshake to be confirmed for the first session created.
- void WaitForCryptoHandshakeConfirmed();
-
- // Wait until |termination_predicate| returns true in server thread, or
- // reached |timeout|. Must be called from an external thread.
- // Return whether the function returned after |termination_predicate| become
- // true.
- bool WaitUntil(std::function<bool()> termination_predicate,
- QuicTime::Delta timeout);
-
- // Pauses execution of the server until Resume() is called. May only be
- // called once.
- void Pause();
-
- // Resumes execution of the server after Pause() has been called. May only
- // be called once.
- void Resume();
-
- // Stops the server from executing and shuts it down, destroying all
- // server objects.
- void Quit();
-
- // Returns the underlying server. Care must be taken to avoid data races
- // when accessing the server. It is always safe to access the server
- // after calling Pause() and before calling Resume().
- QuicServer* server() { return server_.get(); }
-
- // Returns the port that the server is listening on.
- int GetPort();
-
- private:
- void MaybeNotifyOfHandshakeConfirmation();
- void ExecuteScheduledActions();
-
- QuicNotification
- confirmed_; // Notified when the first handshake is confirmed.
- QuicNotification pause_; // Notified when the server should pause.
- QuicNotification paused_; // Notitied when the server has paused
- QuicNotification resume_; // Notified when the server should resume.
- QuicNotification quit_; // Notified when the server should quit.
-
- std::unique_ptr<QuicServer> server_;
- QuicEpollClock clock_;
- QuicSocketAddress address_;
- mutable QuicMutex port_lock_;
- int port_ QUIC_GUARDED_BY(port_lock_);
-
- bool initialized_;
-
- QuicMutex scheduled_actions_lock_;
- quiche::QuicheCircularDeque<std::function<void()>> scheduled_actions_
- QUIC_GUARDED_BY(scheduled_actions_lock_);
-};
-
-} // namespace test
-} // namespace quic
-
-#endif // QUICHE_QUIC_TEST_TOOLS_SERVER_THREAD_H_
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/simple_data_producer.cc b/chromium/net/third_party/quiche/src/quic/test_tools/simple_data_producer.cc
deleted file mode 100644
index 413a840e32c..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/simple_data_producer.cc
+++ /dev/null
@@ -1,72 +0,0 @@
-// Copyright (c) 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/simple_data_producer.h"
-
-#include <utility>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_data_writer.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_flags.h"
-
-namespace quic {
-
-namespace test {
-
-SimpleDataProducer::SimpleDataProducer() {}
-
-SimpleDataProducer::~SimpleDataProducer() {}
-
-void SimpleDataProducer::SaveStreamData(QuicStreamId id,
- const struct iovec* iov,
- int iov_count,
- size_t iov_offset,
- QuicByteCount data_length) {
- if (data_length == 0) {
- return;
- }
- if (!send_buffer_map_.contains(id)) {
- send_buffer_map_[id] = std::make_unique<QuicStreamSendBuffer>(&allocator_);
- }
- send_buffer_map_[id]->SaveStreamData(iov, iov_count, iov_offset, data_length);
-}
-
-void SimpleDataProducer::SaveCryptoData(EncryptionLevel level,
- QuicStreamOffset offset,
- absl::string_view data) {
- auto key = std::make_pair(level, offset);
- crypto_buffer_map_[key] = data;
-}
-
-WriteStreamDataResult SimpleDataProducer::WriteStreamData(
- QuicStreamId id,
- QuicStreamOffset offset,
- QuicByteCount data_length,
- QuicDataWriter* writer) {
- auto iter = send_buffer_map_.find(id);
- if (iter == send_buffer_map_.end()) {
- return STREAM_MISSING;
- }
- if (iter->second->WriteStreamData(offset, data_length, writer)) {
- return WRITE_SUCCESS;
- }
- return WRITE_FAILED;
-}
-
-bool SimpleDataProducer::WriteCryptoData(EncryptionLevel level,
- QuicStreamOffset offset,
- QuicByteCount data_length,
- QuicDataWriter* writer) {
- auto it = crypto_buffer_map_.find(std::make_pair(level, offset));
- if (it == crypto_buffer_map_.end() || it->second.length() < data_length) {
- return false;
- }
- return writer->WriteStringPiece(
- absl::string_view(it->second.data(), data_length));
-}
-
-} // namespace test
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/simple_data_producer.h b/chromium/net/third_party/quiche/src/quic/test_tools/simple_data_producer.h
deleted file mode 100644
index 8111c1cc09f..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/simple_data_producer.h
+++ /dev/null
@@ -1,83 +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_TEST_TOOLS_SIMPLE_DATA_PRODUCER_H_
-#define QUICHE_QUIC_TEST_TOOLS_SIMPLE_DATA_PRODUCER_H_
-
-#include "absl/container/flat_hash_map.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_simple_buffer_allocator.h"
-#include "quic/core/quic_stream_frame_data_producer.h"
-#include "quic/core/quic_stream_send_buffer.h"
-#include "quic/platform/api/quic_containers.h"
-
-namespace quic {
-
-namespace test {
-
-// A simple data producer which copies stream data into a map from stream
-// id to send buffer.
-class SimpleDataProducer : public QuicStreamFrameDataProducer {
- public:
- SimpleDataProducer();
- ~SimpleDataProducer() override;
-
- // Saves data to be provided when WriteStreamData is called. Data of length
- // |data_length| is buffered to be provided for stream |id|. Multiple calls to
- // SaveStreamData for the same stream ID append to the buffer for that stream.
- // The data to be buffered is provided in |iov_count| iovec structs, with
- // |iov| pointing to the first, and |iov_offset| indicating how many bytes
- // into the iovec structs the data starts.
- void SaveStreamData(QuicStreamId id,
- const struct iovec* iov,
- int iov_count,
- size_t iov_offset,
- QuicByteCount data_length);
-
- void SaveCryptoData(EncryptionLevel level,
- QuicStreamOffset offset,
- absl::string_view data);
-
- // QuicStreamFrameDataProducer
- WriteStreamDataResult WriteStreamData(QuicStreamId id,
- QuicStreamOffset offset,
- QuicByteCount data_length,
- QuicDataWriter* writer) override;
- bool WriteCryptoData(EncryptionLevel level,
- QuicStreamOffset offset,
- QuicByteCount data_length,
- QuicDataWriter* writer) override;
-
- private:
- using SendBufferMap =
- absl::flat_hash_map<QuicStreamId, std::unique_ptr<QuicStreamSendBuffer>>;
-
- using CryptoBufferMap =
- absl::flat_hash_map<std::pair<EncryptionLevel, QuicStreamOffset>,
- absl::string_view>;
-
- SimpleBufferAllocator allocator_;
-
- SendBufferMap send_buffer_map_;
-
- // |crypto_buffer_map_| stores data provided by SaveCryptoData to later write
- // in WriteCryptoData. The level and data passed into SaveCryptoData are used
- // as the key to identify the data when WriteCryptoData is called.
- // WriteCryptoData will only succeed if there is data in the map for the
- // provided level and offset, and the data in the map matches the data_length
- // passed into WriteCryptoData.
- //
- // Unlike SaveStreamData/WriteStreamData which uses a map of
- // QuicStreamSendBuffers (for each stream ID), this map provides data for
- // specific offsets. Using a QuicStreamSendBuffer requires that all data
- // before an offset exist, whereas this allows providing data that exists at
- // arbitrary offsets for testing.
- CryptoBufferMap crypto_buffer_map_;
-};
-
-} // namespace test
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_TEST_TOOLS_SIMPLE_DATA_PRODUCER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/simple_quic_framer.cc b/chromium/net/third_party/quiche/src/quic/test_tools/simple_quic_framer.cc
deleted file mode 100644
index 92363ec8eea..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/simple_quic_framer.cc
+++ /dev/null
@@ -1,444 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/simple_quic_framer.h"
-
-#include <memory>
-#include <utility>
-
-#include "absl/memory/memory.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/crypto/quic_decrypter.h"
-#include "quic/core/crypto/quic_encrypter.h"
-#include "quic/core/quic_types.h"
-
-namespace quic {
-namespace test {
-
-class SimpleFramerVisitor : public QuicFramerVisitorInterface {
- public:
- SimpleFramerVisitor() : error_(QUIC_NO_ERROR) {}
- SimpleFramerVisitor(const SimpleFramerVisitor&) = delete;
- SimpleFramerVisitor& operator=(const SimpleFramerVisitor&) = delete;
-
- ~SimpleFramerVisitor() override {}
-
- void OnError(QuicFramer* framer) override { error_ = framer->error(); }
-
- bool OnProtocolVersionMismatch(ParsedQuicVersion /*version*/) override {
- return false;
- }
-
- void OnPacket() override {}
- void OnPublicResetPacket(const QuicPublicResetPacket& packet) override {
- public_reset_packet_ = std::make_unique<QuicPublicResetPacket>((packet));
- }
- void OnVersionNegotiationPacket(
- const QuicVersionNegotiationPacket& packet) override {
- version_negotiation_packet_ =
- std::make_unique<QuicVersionNegotiationPacket>((packet));
- }
-
- void OnRetryPacket(QuicConnectionId /*original_connection_id*/,
- QuicConnectionId /*new_connection_id*/,
- absl::string_view /*retry_token*/,
- absl::string_view /*retry_integrity_tag*/,
- absl::string_view /*retry_without_tag*/) override {}
-
- bool OnUnauthenticatedPublicHeader(
- const QuicPacketHeader& /*header*/) override {
- return true;
- }
- bool OnUnauthenticatedHeader(const QuicPacketHeader& /*header*/) override {
- return true;
- }
- void OnDecryptedPacket(size_t /*length*/, EncryptionLevel level) override {
- last_decrypted_level_ = level;
- }
- bool OnPacketHeader(const QuicPacketHeader& header) override {
- has_header_ = true;
- header_ = header;
- return true;
- }
-
- void OnCoalescedPacket(const QuicEncryptedPacket& packet) override {
- coalesced_packet_ = packet.Clone();
- }
-
- void OnUndecryptablePacket(const QuicEncryptedPacket& /*packet*/,
- EncryptionLevel /*decryption_level*/,
- bool /*has_decryption_key*/) override {}
-
- bool OnStreamFrame(const QuicStreamFrame& frame) override {
- // Save a copy of the data so it is valid after the packet is processed.
- std::string* string_data =
- new std::string(frame.data_buffer, frame.data_length);
- stream_data_.push_back(absl::WrapUnique(string_data));
- // TODO(ianswett): A pointer isn't necessary with emplace_back.
- stream_frames_.push_back(std::make_unique<QuicStreamFrame>(
- frame.stream_id, frame.fin, frame.offset,
- absl::string_view(*string_data)));
- return true;
- }
-
- bool OnCryptoFrame(const QuicCryptoFrame& frame) override {
- // Save a copy of the data so it is valid after the packet is processed.
- std::string* string_data =
- new std::string(frame.data_buffer, frame.data_length);
- crypto_data_.push_back(absl::WrapUnique(string_data));
- crypto_frames_.push_back(std::make_unique<QuicCryptoFrame>(
- frame.level, frame.offset, absl::string_view(*string_data)));
- return true;
- }
-
- bool OnAckFrameStart(QuicPacketNumber largest_acked,
- QuicTime::Delta ack_delay_time) override {
- QuicAckFrame ack_frame;
- ack_frame.largest_acked = largest_acked;
- ack_frame.ack_delay_time = ack_delay_time;
- ack_frames_.push_back(ack_frame);
- return true;
- }
-
- bool OnAckRange(QuicPacketNumber start, QuicPacketNumber end) override {
- QUICHE_DCHECK(!ack_frames_.empty());
- ack_frames_[ack_frames_.size() - 1].packets.AddRange(start, end);
- return true;
- }
-
- bool OnAckTimestamp(QuicPacketNumber /*packet_number*/,
- QuicTime /*timestamp*/) override {
- return true;
- }
-
- bool OnAckFrameEnd(QuicPacketNumber /*start*/) override { return true; }
-
- bool OnStopWaitingFrame(const QuicStopWaitingFrame& frame) override {
- stop_waiting_frames_.push_back(frame);
- return true;
- }
-
- bool OnPaddingFrame(const QuicPaddingFrame& frame) override {
- padding_frames_.push_back(frame);
- return true;
- }
-
- bool OnPingFrame(const QuicPingFrame& frame) override {
- ping_frames_.push_back(frame);
- return true;
- }
-
- bool OnRstStreamFrame(const QuicRstStreamFrame& frame) override {
- rst_stream_frames_.push_back(frame);
- return true;
- }
-
- bool OnConnectionCloseFrame(const QuicConnectionCloseFrame& frame) override {
- connection_close_frames_.push_back(frame);
- return true;
- }
-
- bool OnNewConnectionIdFrame(const QuicNewConnectionIdFrame& frame) override {
- new_connection_id_frames_.push_back(frame);
- return true;
- }
-
- bool OnRetireConnectionIdFrame(
- const QuicRetireConnectionIdFrame& frame) override {
- retire_connection_id_frames_.push_back(frame);
- return true;
- }
-
- bool OnNewTokenFrame(const QuicNewTokenFrame& frame) override {
- new_token_frames_.push_back(frame);
- return true;
- }
-
- bool OnStopSendingFrame(const QuicStopSendingFrame& frame) override {
- stop_sending_frames_.push_back(frame);
- return true;
- }
-
- bool OnPathChallengeFrame(const QuicPathChallengeFrame& frame) override {
- path_challenge_frames_.push_back(frame);
- return true;
- }
-
- bool OnPathResponseFrame(const QuicPathResponseFrame& frame) override {
- path_response_frames_.push_back(frame);
- return true;
- }
-
- bool OnGoAwayFrame(const QuicGoAwayFrame& frame) override {
- goaway_frames_.push_back(frame);
- return true;
- }
- bool OnMaxStreamsFrame(const QuicMaxStreamsFrame& frame) override {
- max_streams_frames_.push_back(frame);
- return true;
- }
-
- bool OnStreamsBlockedFrame(const QuicStreamsBlockedFrame& frame) override {
- streams_blocked_frames_.push_back(frame);
- return true;
- }
-
- bool OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame) override {
- window_update_frames_.push_back(frame);
- return true;
- }
-
- bool OnBlockedFrame(const QuicBlockedFrame& frame) override {
- blocked_frames_.push_back(frame);
- return true;
- }
-
- bool OnMessageFrame(const QuicMessageFrame& frame) override {
- message_frames_.emplace_back(frame.data, frame.message_length);
- return true;
- }
-
- bool OnHandshakeDoneFrame(const QuicHandshakeDoneFrame& frame) override {
- handshake_done_frames_.push_back(frame);
- return true;
- }
-
- bool OnAckFrequencyFrame(const QuicAckFrequencyFrame& frame) override {
- ack_frequency_frames_.push_back(frame);
- return true;
- }
-
- void OnPacketComplete() override {}
-
- bool IsValidStatelessResetToken(
- const StatelessResetToken& /*token*/) const override {
- return false;
- }
-
- void OnAuthenticatedIetfStatelessResetPacket(
- const QuicIetfStatelessResetPacket& packet) override {
- stateless_reset_packet_ =
- std::make_unique<QuicIetfStatelessResetPacket>(packet);
- }
-
- void OnKeyUpdate(KeyUpdateReason /*reason*/) override {}
- void OnDecryptedFirstPacketInKeyPhase() override {}
- std::unique_ptr<QuicDecrypter> AdvanceKeysAndCreateCurrentOneRttDecrypter()
- override {
- return nullptr;
- }
- std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() override {
- return nullptr;
- }
-
- const QuicPacketHeader& header() const { return header_; }
- const std::vector<QuicAckFrame>& ack_frames() const { return ack_frames_; }
- const std::vector<QuicConnectionCloseFrame>& connection_close_frames() const {
- return connection_close_frames_;
- }
-
- const std::vector<QuicGoAwayFrame>& goaway_frames() const {
- return goaway_frames_;
- }
- const std::vector<QuicMaxStreamsFrame>& max_streams_frames() const {
- return max_streams_frames_;
- }
- const std::vector<QuicStreamsBlockedFrame>& streams_blocked_frames() const {
- return streams_blocked_frames_;
- }
- const std::vector<QuicRstStreamFrame>& rst_stream_frames() const {
- return rst_stream_frames_;
- }
- const std::vector<std::unique_ptr<QuicStreamFrame>>& stream_frames() const {
- return stream_frames_;
- }
- const std::vector<std::unique_ptr<QuicCryptoFrame>>& crypto_frames() const {
- return crypto_frames_;
- }
- const std::vector<QuicStopWaitingFrame>& stop_waiting_frames() const {
- return stop_waiting_frames_;
- }
- const std::vector<QuicPingFrame>& ping_frames() const { return ping_frames_; }
- const std::vector<QuicMessageFrame>& message_frames() const {
- return message_frames_;
- }
- const std::vector<QuicWindowUpdateFrame>& window_update_frames() const {
- return window_update_frames_;
- }
- const std::vector<QuicPaddingFrame>& padding_frames() const {
- return padding_frames_;
- }
- const std::vector<QuicPathChallengeFrame>& path_challenge_frames() const {
- return path_challenge_frames_;
- }
- const std::vector<QuicPathResponseFrame>& path_response_frames() const {
- return path_response_frames_;
- }
- const QuicVersionNegotiationPacket* version_negotiation_packet() const {
- return version_negotiation_packet_.get();
- }
- EncryptionLevel last_decrypted_level() const { return last_decrypted_level_; }
- const QuicEncryptedPacket* coalesced_packet() const {
- return coalesced_packet_.get();
- }
-
- private:
- QuicErrorCode error_;
- bool has_header_;
- QuicPacketHeader header_;
- std::unique_ptr<QuicVersionNegotiationPacket> version_negotiation_packet_;
- std::unique_ptr<QuicPublicResetPacket> public_reset_packet_;
- std::unique_ptr<QuicIetfStatelessResetPacket> stateless_reset_packet_;
- std::vector<QuicAckFrame> ack_frames_;
- std::vector<QuicStopWaitingFrame> stop_waiting_frames_;
- std::vector<QuicPaddingFrame> padding_frames_;
- std::vector<QuicPingFrame> ping_frames_;
- std::vector<std::unique_ptr<QuicStreamFrame>> stream_frames_;
- std::vector<std::unique_ptr<QuicCryptoFrame>> crypto_frames_;
- std::vector<QuicRstStreamFrame> rst_stream_frames_;
- std::vector<QuicGoAwayFrame> goaway_frames_;
- std::vector<QuicStreamsBlockedFrame> streams_blocked_frames_;
- std::vector<QuicMaxStreamsFrame> max_streams_frames_;
- std::vector<QuicConnectionCloseFrame> connection_close_frames_;
- std::vector<QuicStopSendingFrame> stop_sending_frames_;
- std::vector<QuicPathChallengeFrame> path_challenge_frames_;
- std::vector<QuicPathResponseFrame> path_response_frames_;
- std::vector<QuicWindowUpdateFrame> window_update_frames_;
- std::vector<QuicBlockedFrame> blocked_frames_;
- std::vector<QuicNewConnectionIdFrame> new_connection_id_frames_;
- std::vector<QuicRetireConnectionIdFrame> retire_connection_id_frames_;
- std::vector<QuicNewTokenFrame> new_token_frames_;
- std::vector<QuicMessageFrame> message_frames_;
- std::vector<QuicHandshakeDoneFrame> handshake_done_frames_;
- std::vector<QuicAckFrequencyFrame> ack_frequency_frames_;
- std::vector<std::unique_ptr<std::string>> stream_data_;
- std::vector<std::unique_ptr<std::string>> crypto_data_;
- EncryptionLevel last_decrypted_level_;
- std::unique_ptr<QuicEncryptedPacket> coalesced_packet_;
-};
-
-SimpleQuicFramer::SimpleQuicFramer()
- : framer_(AllSupportedVersions(),
- QuicTime::Zero(),
- Perspective::IS_SERVER,
- kQuicDefaultConnectionIdLength) {}
-
-SimpleQuicFramer::SimpleQuicFramer(
- const ParsedQuicVersionVector& supported_versions)
- : framer_(supported_versions,
- QuicTime::Zero(),
- Perspective::IS_SERVER,
- kQuicDefaultConnectionIdLength) {}
-
-SimpleQuicFramer::SimpleQuicFramer(
- const ParsedQuicVersionVector& supported_versions,
- Perspective perspective)
- : framer_(supported_versions,
- QuicTime::Zero(),
- perspective,
- kQuicDefaultConnectionIdLength) {}
-
-SimpleQuicFramer::~SimpleQuicFramer() {}
-
-bool SimpleQuicFramer::ProcessPacket(const QuicEncryptedPacket& packet) {
- visitor_ = std::make_unique<SimpleFramerVisitor>();
- framer_.set_visitor(visitor_.get());
- return framer_.ProcessPacket(packet);
-}
-
-void SimpleQuicFramer::Reset() {
- visitor_ = std::make_unique<SimpleFramerVisitor>();
-}
-
-const QuicPacketHeader& SimpleQuicFramer::header() const {
- return visitor_->header();
-}
-
-const QuicVersionNegotiationPacket*
-SimpleQuicFramer::version_negotiation_packet() const {
- return visitor_->version_negotiation_packet();
-}
-
-EncryptionLevel SimpleQuicFramer::last_decrypted_level() const {
- return visitor_->last_decrypted_level();
-}
-
-QuicFramer* SimpleQuicFramer::framer() {
- return &framer_;
-}
-
-size_t SimpleQuicFramer::num_frames() const {
- return ack_frames().size() + goaway_frames().size() +
- rst_stream_frames().size() + stop_waiting_frames().size() +
- path_challenge_frames().size() + path_response_frames().size() +
- stream_frames().size() + ping_frames().size() +
- connection_close_frames().size() + padding_frames().size() +
- crypto_frames().size();
-}
-
-const std::vector<QuicAckFrame>& SimpleQuicFramer::ack_frames() const {
- return visitor_->ack_frames();
-}
-
-const std::vector<QuicStopWaitingFrame>& SimpleQuicFramer::stop_waiting_frames()
- const {
- return visitor_->stop_waiting_frames();
-}
-
-const std::vector<QuicPathChallengeFrame>&
-SimpleQuicFramer::path_challenge_frames() const {
- return visitor_->path_challenge_frames();
-}
-const std::vector<QuicPathResponseFrame>&
-SimpleQuicFramer::path_response_frames() const {
- return visitor_->path_response_frames();
-}
-
-const std::vector<QuicPingFrame>& SimpleQuicFramer::ping_frames() const {
- return visitor_->ping_frames();
-}
-
-const std::vector<QuicMessageFrame>& SimpleQuicFramer::message_frames() const {
- return visitor_->message_frames();
-}
-
-const std::vector<QuicWindowUpdateFrame>&
-SimpleQuicFramer::window_update_frames() const {
- return visitor_->window_update_frames();
-}
-
-const std::vector<std::unique_ptr<QuicStreamFrame>>&
-SimpleQuicFramer::stream_frames() const {
- return visitor_->stream_frames();
-}
-
-const std::vector<std::unique_ptr<QuicCryptoFrame>>&
-SimpleQuicFramer::crypto_frames() const {
- return visitor_->crypto_frames();
-}
-
-const std::vector<QuicRstStreamFrame>& SimpleQuicFramer::rst_stream_frames()
- const {
- return visitor_->rst_stream_frames();
-}
-
-const std::vector<QuicGoAwayFrame>& SimpleQuicFramer::goaway_frames() const {
- return visitor_->goaway_frames();
-}
-
-const std::vector<QuicConnectionCloseFrame>&
-SimpleQuicFramer::connection_close_frames() const {
- return visitor_->connection_close_frames();
-}
-
-const std::vector<QuicPaddingFrame>& SimpleQuicFramer::padding_frames() const {
- return visitor_->padding_frames();
-}
-
-const QuicEncryptedPacket* SimpleQuicFramer::coalesced_packet() const {
- return visitor_->coalesced_packet();
-}
-
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/simple_quic_framer.h b/chromium/net/third_party/quiche/src/quic/test_tools/simple_quic_framer.h
deleted file mode 100644
index 6801dfe6c04..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/simple_quic_framer.h
+++ /dev/null
@@ -1,70 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_SIMPLE_QUIC_FRAMER_H_
-#define QUICHE_QUIC_TEST_TOOLS_SIMPLE_QUIC_FRAMER_H_
-
-#include <memory>
-#include <vector>
-
-#include "quic/core/quic_framer.h"
-#include "quic/core/quic_packets.h"
-
-namespace quic {
-
-struct QuicAckFrame;
-
-namespace test {
-
-class SimpleFramerVisitor;
-
-// Peer to make public a number of otherwise private QuicFramer methods.
-class SimpleQuicFramer {
- public:
- SimpleQuicFramer();
- explicit SimpleQuicFramer(const ParsedQuicVersionVector& supported_versions);
- SimpleQuicFramer(const ParsedQuicVersionVector& supported_versions,
- Perspective perspective);
- SimpleQuicFramer(const SimpleQuicFramer&) = delete;
- SimpleQuicFramer& operator=(const SimpleQuicFramer&) = delete;
- ~SimpleQuicFramer();
-
- bool ProcessPacket(const QuicEncryptedPacket& packet);
- void Reset();
-
- const QuicPacketHeader& header() const;
- size_t num_frames() const;
- const std::vector<QuicAckFrame>& ack_frames() const;
- const std::vector<QuicConnectionCloseFrame>& connection_close_frames() const;
- const std::vector<QuicStopWaitingFrame>& stop_waiting_frames() const;
- const std::vector<QuicPathChallengeFrame>& path_challenge_frames() const;
- const std::vector<QuicPathResponseFrame>& path_response_frames() const;
- const std::vector<QuicPingFrame>& ping_frames() const;
- const std::vector<QuicMessageFrame>& message_frames() const;
- const std::vector<QuicWindowUpdateFrame>& window_update_frames() const;
- const std::vector<QuicGoAwayFrame>& goaway_frames() const;
- const std::vector<QuicRstStreamFrame>& rst_stream_frames() const;
- const std::vector<std::unique_ptr<QuicStreamFrame>>& stream_frames() const;
- const std::vector<std::unique_ptr<QuicCryptoFrame>>& crypto_frames() const;
- const std::vector<QuicPaddingFrame>& padding_frames() const;
- const QuicVersionNegotiationPacket* version_negotiation_packet() const;
- EncryptionLevel last_decrypted_level() const;
- const QuicEncryptedPacket* coalesced_packet() const;
-
- QuicFramer* framer();
-
- void SetSupportedVersions(const ParsedQuicVersionVector& versions) {
- framer_.SetSupportedVersions(versions);
- }
-
- private:
- QuicFramer framer_;
- std::unique_ptr<SimpleFramerVisitor> visitor_;
-};
-
-} // namespace test
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_TEST_TOOLS_SIMPLE_QUIC_FRAMER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/simple_session_cache.cc b/chromium/net/third_party/quiche/src/quic/test_tools/simple_session_cache.cc
deleted file mode 100644
index b9c0436e6fa..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/simple_session_cache.cc
+++ /dev/null
@@ -1,76 +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 "quic/test_tools/simple_session_cache.h"
-#include <memory>
-#include "quic/core/crypto/quic_crypto_client_config.h"
-
-namespace quic {
-namespace test {
-
-void SimpleSessionCache::Insert(const QuicServerId& server_id,
- bssl::UniquePtr<SSL_SESSION> session,
- const TransportParameters& params,
- const ApplicationState* application_state) {
- auto it = cache_entries_.find(server_id);
- if (it == cache_entries_.end()) {
- it = cache_entries_.insert(std::make_pair(server_id, Entry())).first;
- }
- if (session != nullptr) {
- it->second.session = std::move(session);
- }
- if (application_state != nullptr) {
- it->second.application_state =
- std::make_unique<ApplicationState>(*application_state);
- }
- it->second.params = std::make_unique<TransportParameters>(params);
-}
-
-std::unique_ptr<QuicResumptionState> SimpleSessionCache::Lookup(
- const QuicServerId& server_id, QuicWallTime /*now*/,
- const SSL_CTX* /*ctx*/) {
- auto it = cache_entries_.find(server_id);
- if (it == cache_entries_.end()) {
- return nullptr;
- }
-
- if (!it->second.session) {
- cache_entries_.erase(it);
- return nullptr;
- }
-
- auto state = std::make_unique<QuicResumptionState>();
- state->tls_session = std::move(it->second.session);
- if (it->second.application_state != nullptr) {
- state->application_state =
- std::make_unique<ApplicationState>(*it->second.application_state);
- }
- state->transport_params =
- std::make_unique<TransportParameters>(*it->second.params);
- state->token = it->second.token;
- return state;
-}
-
-void SimpleSessionCache::ClearEarlyData(const QuicServerId& /*server_id*/) {
- // The simple session cache only stores 1 SSL ticket per entry, so no need to
- // do anything here.
-}
-
-void SimpleSessionCache::OnNewTokenReceived(const QuicServerId& server_id,
- absl::string_view token) {
- auto it = cache_entries_.find(server_id);
- if (it == cache_entries_.end()) {
- return;
- }
- it->second.token = std::string(token);
-}
-
-void SimpleSessionCache::RemoveExpiredEntries(QuicWallTime /*now*/) {
- // The simple session cache does not support removing expired entries.
-}
-
-void SimpleSessionCache::Clear() { cache_entries_.clear(); }
-
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/simple_session_cache.h b/chromium/net/third_party/quiche/src/quic/test_tools/simple_session_cache.h
deleted file mode 100644
index 6b4111e77a0..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/simple_session_cache.h
+++ /dev/null
@@ -1,52 +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_TEST_TOOLS_SIMPLE_SESSION_CACHE_H_
-#define QUICHE_QUIC_TEST_TOOLS_SIMPLE_SESSION_CACHE_H_
-
-#include <memory>
-#include "quic/core/crypto/quic_crypto_client_config.h"
-#include "quic/core/crypto/transport_parameters.h"
-
-namespace quic {
-namespace test {
-
-// SimpleSessionCache provides a simple implementation of SessionCache that
-// stores only one QuicResumptionState per QuicServerId. No limit is placed on
-// the total number of entries in the cache. When Lookup is called, if a cache
-// entry exists for the provided QuicServerId, the entry will be removed from
-// the cached when it is returned.
-// TODO(fayang): Remove SimpleSessionCache by using QuicClientSessionCache.
-class SimpleSessionCache : public SessionCache {
- public:
- SimpleSessionCache() = default;
- ~SimpleSessionCache() override = default;
-
- void Insert(const QuicServerId& server_id,
- bssl::UniquePtr<SSL_SESSION> session,
- const TransportParameters& params,
- const ApplicationState* application_state) override;
- std::unique_ptr<QuicResumptionState> Lookup(const QuicServerId& server_id,
- QuicWallTime now,
- const SSL_CTX* ctx) override;
- void ClearEarlyData(const QuicServerId& server_id) override;
- void OnNewTokenReceived(const QuicServerId& server_id,
- absl::string_view token) override;
- void RemoveExpiredEntries(QuicWallTime now) override;
- void Clear() override;
-
- private:
- struct Entry {
- bssl::UniquePtr<SSL_SESSION> session;
- std::unique_ptr<TransportParameters> params;
- std::unique_ptr<ApplicationState> application_state;
- std::string token;
- };
- std::map<QuicServerId, Entry> cache_entries_;
-};
-
-} // namespace test
-} // namespace quic
-
-#endif // QUICHE_QUIC_TEST_TOOLS_SIMPLE_SESSION_CACHE_H_
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/simple_session_notifier.cc b/chromium/net/third_party/quiche/src/quic/test_tools/simple_session_notifier.cc
deleted file mode 100644
index ce498ca2d95..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/simple_session_notifier.cc
+++ /dev/null
@@ -1,764 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/simple_session_notifier.h"
-
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/test_tools/quic_test_utils.h"
-
-namespace quic {
-
-namespace test {
-
-SimpleSessionNotifier::SimpleSessionNotifier(QuicConnection* connection)
- : last_control_frame_id_(kInvalidControlFrameId),
- least_unacked_(1),
- least_unsent_(1),
- connection_(connection) {}
-
-SimpleSessionNotifier::~SimpleSessionNotifier() {
- while (!control_frames_.empty()) {
- DeleteFrame(&control_frames_.front());
- control_frames_.pop_front();
- }
-}
-
-SimpleSessionNotifier::StreamState::StreamState()
- : bytes_total(0),
- bytes_sent(0),
- fin_buffered(false),
- fin_sent(false),
- fin_outstanding(false),
- fin_lost(false) {}
-
-SimpleSessionNotifier::StreamState::~StreamState() {}
-
-QuicConsumedData SimpleSessionNotifier::WriteOrBufferData(
- QuicStreamId id,
- QuicByteCount data_length,
- StreamSendingState state) {
- if (!stream_map_.contains(id)) {
- stream_map_[id] = StreamState();
- }
- StreamState& stream_state = stream_map_.find(id)->second;
- const bool had_buffered_data =
- HasBufferedStreamData() || HasBufferedControlFrames();
- QuicStreamOffset offset = stream_state.bytes_sent;
- QUIC_DVLOG(1) << "WriteOrBuffer stream_id: " << id << " [" << offset << ", "
- << offset + data_length << "), fin: " << (state != NO_FIN);
- stream_state.bytes_total += data_length;
- stream_state.fin_buffered = state != NO_FIN;
- if (had_buffered_data) {
- QUIC_DLOG(WARNING) << "Connection is write blocked";
- return {0, false};
- }
- const size_t length = stream_state.bytes_total - stream_state.bytes_sent;
- connection_->SetTransmissionType(NOT_RETRANSMISSION);
- QuicConsumedData consumed =
- connection_->SendStreamData(id, length, stream_state.bytes_sent,
- stream_state.fin_buffered ? FIN : NO_FIN);
- QUIC_DVLOG(1) << "consumed: " << consumed;
- OnStreamDataConsumed(id, stream_state.bytes_sent, consumed.bytes_consumed,
- consumed.fin_consumed);
- return consumed;
-}
-
-void SimpleSessionNotifier::OnStreamDataConsumed(QuicStreamId id,
- QuicStreamOffset offset,
- QuicByteCount data_length,
- bool fin) {
- StreamState& state = stream_map_.find(id)->second;
- if (QuicUtils::IsCryptoStreamId(connection_->transport_version(), id) &&
- data_length > 0) {
- crypto_bytes_transferred_[connection_->encryption_level()].Add(
- offset, offset + data_length);
- }
- state.bytes_sent += data_length;
- state.fin_sent = fin;
- state.fin_outstanding = fin;
-}
-
-size_t SimpleSessionNotifier::WriteCryptoData(EncryptionLevel level,
- QuicByteCount data_length,
- QuicStreamOffset offset) {
- crypto_state_[level].bytes_total += data_length;
- size_t bytes_written =
- connection_->SendCryptoData(level, data_length, offset);
- crypto_state_[level].bytes_sent += bytes_written;
- crypto_bytes_transferred_[level].Add(offset, offset + bytes_written);
- return bytes_written;
-}
-
-void SimpleSessionNotifier::WriteOrBufferRstStream(
- QuicStreamId id,
- QuicRstStreamErrorCode error,
- QuicStreamOffset bytes_written) {
- QUIC_DVLOG(1) << "Writing RST_STREAM_FRAME";
- const bool had_buffered_data =
- HasBufferedStreamData() || HasBufferedControlFrames();
- control_frames_.emplace_back((QuicFrame(new QuicRstStreamFrame(
- ++last_control_frame_id_, id, error, bytes_written))));
- if (error != QUIC_STREAM_NO_ERROR) {
- // Delete stream to avoid retransmissions.
- stream_map_.erase(id);
- }
- if (had_buffered_data) {
- QUIC_DLOG(WARNING) << "Connection is write blocked";
- return;
- }
- WriteBufferedControlFrames();
-}
-
-void SimpleSessionNotifier::WriteOrBufferWindowUpate(
- QuicStreamId id, QuicStreamOffset byte_offset) {
- QUIC_DVLOG(1) << "Writing WINDOW_UPDATE";
- const bool had_buffered_data =
- HasBufferedStreamData() || HasBufferedControlFrames();
- QuicControlFrameId control_frame_id = ++last_control_frame_id_;
- control_frames_.emplace_back((
- QuicFrame(new QuicWindowUpdateFrame(control_frame_id, id, byte_offset))));
- if (had_buffered_data) {
- QUIC_DLOG(WARNING) << "Connection is write blocked";
- return;
- }
- WriteBufferedControlFrames();
-}
-
-void SimpleSessionNotifier::WriteOrBufferPing() {
- QUIC_DVLOG(1) << "Writing PING_FRAME";
- const bool had_buffered_data =
- HasBufferedStreamData() || HasBufferedControlFrames();
- control_frames_.emplace_back(
- (QuicFrame(QuicPingFrame(++last_control_frame_id_))));
- if (had_buffered_data) {
- QUIC_DLOG(WARNING) << "Connection is write blocked";
- return;
- }
- WriteBufferedControlFrames();
-}
-
-void SimpleSessionNotifier::WriteOrBufferAckFrequency(
- const QuicAckFrequencyFrame& ack_frequency_frame) {
- QUIC_DVLOG(1) << "Writing ACK_FREQUENCY";
- const bool had_buffered_data =
- HasBufferedStreamData() || HasBufferedControlFrames();
- QuicControlFrameId control_frame_id = ++last_control_frame_id_;
- control_frames_.emplace_back((
- QuicFrame(new QuicAckFrequencyFrame(control_frame_id,
- /*sequence_number=*/control_frame_id,
- ack_frequency_frame.packet_tolerance,
- ack_frequency_frame.max_ack_delay))));
- if (had_buffered_data) {
- QUIC_DLOG(WARNING) << "Connection is write blocked";
- return;
- }
- WriteBufferedControlFrames();
-}
-
-void SimpleSessionNotifier::NeuterUnencryptedData() {
- if (QuicVersionUsesCryptoFrames(connection_->transport_version())) {
- for (const auto& interval : crypto_bytes_transferred_[ENCRYPTION_INITIAL]) {
- QuicCryptoFrame crypto_frame(ENCRYPTION_INITIAL, interval.min(),
- interval.max() - interval.min());
- OnFrameAcked(QuicFrame(&crypto_frame), QuicTime::Delta::Zero(),
- QuicTime::Zero());
- }
- return;
- }
- for (const auto& interval : crypto_bytes_transferred_[ENCRYPTION_INITIAL]) {
- QuicStreamFrame stream_frame(
- QuicUtils::GetCryptoStreamId(connection_->transport_version()), false,
- interval.min(), interval.max() - interval.min());
- OnFrameAcked(QuicFrame(stream_frame), QuicTime::Delta::Zero(),
- QuicTime::Zero());
- }
-}
-
-void SimpleSessionNotifier::OnCanWrite() {
- if (connection_->framer().is_processing_packet()) {
- // Do not write data in the middle of packet processing because rest
- // frames in the packet may change the data to write. For example, lost
- // data could be acknowledged. Also, connection is going to emit
- // OnCanWrite signal post packet processing.
- QUIC_BUG(simple_notifier_write_mid_packet_processing)
- << "Try to write mid packet processing.";
- return;
- }
- if (!RetransmitLostCryptoData() || !RetransmitLostControlFrames() ||
- !RetransmitLostStreamData()) {
- return;
- }
- if (!WriteBufferedCryptoData() || !WriteBufferedControlFrames()) {
- return;
- }
- // Write new data.
- for (const auto& pair : stream_map_) {
- const auto& state = pair.second;
- if (!StreamHasBufferedData(pair.first)) {
- continue;
- }
-
- const size_t length = state.bytes_total - state.bytes_sent;
- const bool can_bundle_fin =
- state.fin_buffered && (state.bytes_sent + length == state.bytes_total);
- connection_->SetTransmissionType(NOT_RETRANSMISSION);
- QuicConsumedData consumed = connection_->SendStreamData(
- pair.first, length, state.bytes_sent, can_bundle_fin ? FIN : NO_FIN);
- QUIC_DVLOG(1) << "Tries to write stream_id: " << pair.first << " ["
- << state.bytes_sent << ", " << state.bytes_sent + length
- << "), fin: " << can_bundle_fin
- << ", and consumed: " << consumed;
- OnStreamDataConsumed(pair.first, state.bytes_sent, consumed.bytes_consumed,
- consumed.fin_consumed);
- if (length != consumed.bytes_consumed ||
- (can_bundle_fin && !consumed.fin_consumed)) {
- break;
- }
- }
-}
-
-void SimpleSessionNotifier::OnStreamReset(QuicStreamId id,
- QuicRstStreamErrorCode error) {
- if (error != QUIC_STREAM_NO_ERROR) {
- // Delete stream to avoid retransmissions.
- stream_map_.erase(id);
- }
-}
-
-bool SimpleSessionNotifier::WillingToWrite() const {
- QUIC_DVLOG(1) << "has_buffered_control_frames: " << HasBufferedControlFrames()
- << " as_lost_control_frames: " << !lost_control_frames_.empty()
- << " has_buffered_stream_data: " << HasBufferedStreamData()
- << " has_lost_stream_data: " << HasLostStreamData();
- return HasBufferedControlFrames() || !lost_control_frames_.empty() ||
- HasBufferedStreamData() || HasLostStreamData();
-}
-
-QuicByteCount SimpleSessionNotifier::StreamBytesSent() const {
- QuicByteCount bytes_sent = 0;
- for (const auto& pair : stream_map_) {
- const auto& state = pair.second;
- bytes_sent += state.bytes_sent;
- }
- return bytes_sent;
-}
-
-QuicByteCount SimpleSessionNotifier::StreamBytesToSend() const {
- QuicByteCount bytes_to_send = 0;
- for (const auto& pair : stream_map_) {
- const auto& state = pair.second;
- bytes_to_send += (state.bytes_total - state.bytes_sent);
- }
- return bytes_to_send;
-}
-
-bool SimpleSessionNotifier::OnFrameAcked(const QuicFrame& frame,
- QuicTime::Delta /*ack_delay_time*/,
- QuicTime /*receive_timestamp*/) {
- QUIC_DVLOG(1) << "Acking " << frame;
- if (frame.type == CRYPTO_FRAME) {
- StreamState* state = &crypto_state_[frame.crypto_frame->level];
- QuicStreamOffset offset = frame.crypto_frame->offset;
- QuicByteCount data_length = frame.crypto_frame->data_length;
- QuicIntervalSet<QuicStreamOffset> newly_acked(offset, offset + data_length);
- newly_acked.Difference(state->bytes_acked);
- if (newly_acked.Empty()) {
- return false;
- }
- state->bytes_acked.Add(offset, offset + data_length);
- state->pending_retransmissions.Difference(offset, offset + data_length);
- return true;
- }
- if (frame.type != STREAM_FRAME) {
- return OnControlFrameAcked(frame);
- }
- if (!stream_map_.contains(frame.stream_frame.stream_id)) {
- return false;
- }
- auto* state = &stream_map_.find(frame.stream_frame.stream_id)->second;
- QuicStreamOffset offset = frame.stream_frame.offset;
- QuicByteCount data_length = frame.stream_frame.data_length;
- QuicIntervalSet<QuicStreamOffset> newly_acked(offset, offset + data_length);
- newly_acked.Difference(state->bytes_acked);
- const bool fin_newly_acked = frame.stream_frame.fin && state->fin_outstanding;
- if (newly_acked.Empty() && !fin_newly_acked) {
- return false;
- }
- state->bytes_acked.Add(offset, offset + data_length);
- if (fin_newly_acked) {
- state->fin_outstanding = false;
- state->fin_lost = false;
- }
- state->pending_retransmissions.Difference(offset, offset + data_length);
- return true;
-}
-
-void SimpleSessionNotifier::OnFrameLost(const QuicFrame& frame) {
- QUIC_DVLOG(1) << "Losting " << frame;
- if (frame.type == CRYPTO_FRAME) {
- StreamState* state = &crypto_state_[frame.crypto_frame->level];
- QuicStreamOffset offset = frame.crypto_frame->offset;
- QuicByteCount data_length = frame.crypto_frame->data_length;
- QuicIntervalSet<QuicStreamOffset> bytes_lost(offset, offset + data_length);
- bytes_lost.Difference(state->bytes_acked);
- if (bytes_lost.Empty()) {
- return;
- }
- for (const auto& lost : bytes_lost) {
- state->pending_retransmissions.Add(lost.min(), lost.max());
- }
- return;
- }
- if (frame.type != STREAM_FRAME) {
- OnControlFrameLost(frame);
- return;
- }
- if (!stream_map_.contains(frame.stream_frame.stream_id)) {
- return;
- }
- auto* state = &stream_map_.find(frame.stream_frame.stream_id)->second;
- QuicStreamOffset offset = frame.stream_frame.offset;
- QuicByteCount data_length = frame.stream_frame.data_length;
- QuicIntervalSet<QuicStreamOffset> bytes_lost(offset, offset + data_length);
- bytes_lost.Difference(state->bytes_acked);
- const bool fin_lost = state->fin_outstanding && frame.stream_frame.fin;
- if (bytes_lost.Empty() && !fin_lost) {
- return;
- }
- for (const auto& lost : bytes_lost) {
- state->pending_retransmissions.Add(lost.min(), lost.max());
- }
- state->fin_lost = fin_lost;
-}
-
-void SimpleSessionNotifier::RetransmitFrames(const QuicFrames& frames,
- TransmissionType type) {
- QuicConnection::ScopedPacketFlusher retransmission_flusher(connection_);
- connection_->SetTransmissionType(type);
- for (const QuicFrame& frame : frames) {
- if (frame.type == CRYPTO_FRAME) {
- const StreamState& state = crypto_state_[frame.crypto_frame->level];
- const EncryptionLevel current_encryption_level =
- connection_->encryption_level();
- QuicIntervalSet<QuicStreamOffset> retransmission(
- frame.crypto_frame->offset,
- frame.crypto_frame->offset + frame.crypto_frame->data_length);
- retransmission.Difference(state.bytes_acked);
- for (const auto& interval : retransmission) {
- QuicStreamOffset offset = interval.min();
- QuicByteCount length = interval.max() - interval.min();
- connection_->SetDefaultEncryptionLevel(frame.crypto_frame->level);
- size_t consumed = connection_->SendCryptoData(frame.crypto_frame->level,
- length, offset);
- if (consumed < length) {
- break;
- }
- }
- connection_->SetDefaultEncryptionLevel(current_encryption_level);
- }
- if (frame.type != STREAM_FRAME) {
- if (GetControlFrameId(frame) == kInvalidControlFrameId) {
- continue;
- }
- QuicFrame copy = CopyRetransmittableControlFrame(frame);
- if (!connection_->SendControlFrame(copy)) {
- // Connection is write blocked.
- DeleteFrame(&copy);
- return;
- }
- continue;
- }
- if (!stream_map_.contains(frame.stream_frame.stream_id)) {
- continue;
- }
- const auto& state = stream_map_.find(frame.stream_frame.stream_id)->second;
- QuicIntervalSet<QuicStreamOffset> retransmission(
- frame.stream_frame.offset,
- frame.stream_frame.offset + frame.stream_frame.data_length);
- EncryptionLevel retransmission_encryption_level =
- connection_->encryption_level();
- EncryptionLevel current_encryption_level = connection_->encryption_level();
- if (QuicUtils::IsCryptoStreamId(connection_->transport_version(),
- frame.stream_frame.stream_id)) {
- for (size_t i = 0; i < NUM_ENCRYPTION_LEVELS; ++i) {
- if (retransmission.Intersects(crypto_bytes_transferred_[i])) {
- retransmission_encryption_level = static_cast<EncryptionLevel>(i);
- retransmission.Intersection(crypto_bytes_transferred_[i]);
- break;
- }
- }
- }
- retransmission.Difference(state.bytes_acked);
- bool retransmit_fin = frame.stream_frame.fin && state.fin_outstanding;
- QuicConsumedData consumed(0, false);
- for (const auto& interval : retransmission) {
- QuicStreamOffset retransmission_offset = interval.min();
- QuicByteCount retransmission_length = interval.max() - interval.min();
- const bool can_bundle_fin =
- retransmit_fin &&
- (retransmission_offset + retransmission_length == state.bytes_sent);
- if (QuicUtils::IsCryptoStreamId(connection_->transport_version(),
- frame.stream_frame.stream_id)) {
- // Set appropriate encryption level for crypto stream.
- connection_->SetDefaultEncryptionLevel(retransmission_encryption_level);
- }
- consumed = connection_->SendStreamData(
- frame.stream_frame.stream_id, retransmission_length,
- retransmission_offset, can_bundle_fin ? FIN : NO_FIN);
- QUIC_DVLOG(1) << "stream " << frame.stream_frame.stream_id
- << " is forced to retransmit stream data ["
- << retransmission_offset << ", "
- << retransmission_offset + retransmission_length
- << ") and fin: " << can_bundle_fin
- << ", consumed: " << consumed;
- if (can_bundle_fin) {
- retransmit_fin = !consumed.fin_consumed;
- }
- if (QuicUtils::IsCryptoStreamId(connection_->transport_version(),
- frame.stream_frame.stream_id)) {
- // Restore encryption level.
- connection_->SetDefaultEncryptionLevel(current_encryption_level);
- }
- if (consumed.bytes_consumed < retransmission_length ||
- (can_bundle_fin && !consumed.fin_consumed)) {
- // Connection is write blocked.
- return;
- }
- }
- if (retransmit_fin) {
- QUIC_DVLOG(1) << "stream " << frame.stream_frame.stream_id
- << " retransmits fin only frame.";
- consumed = connection_->SendStreamData(frame.stream_frame.stream_id, 0,
- state.bytes_sent, FIN);
- }
- }
-}
-
-bool SimpleSessionNotifier::IsFrameOutstanding(const QuicFrame& frame) const {
- if (frame.type == CRYPTO_FRAME) {
- QuicStreamOffset offset = frame.crypto_frame->offset;
- QuicByteCount data_length = frame.crypto_frame->data_length;
- bool ret = data_length > 0 &&
- !crypto_state_[frame.crypto_frame->level].bytes_acked.Contains(
- offset, offset + data_length);
- return ret;
- }
- if (frame.type != STREAM_FRAME) {
- return IsControlFrameOutstanding(frame);
- }
- if (!stream_map_.contains(frame.stream_frame.stream_id)) {
- return false;
- }
- const auto& state = stream_map_.find(frame.stream_frame.stream_id)->second;
- QuicStreamOffset offset = frame.stream_frame.offset;
- QuicByteCount data_length = frame.stream_frame.data_length;
- return (data_length > 0 &&
- !state.bytes_acked.Contains(offset, offset + data_length)) ||
- (frame.stream_frame.fin && state.fin_outstanding);
-}
-
-bool SimpleSessionNotifier::HasUnackedCryptoData() const {
- if (QuicVersionUsesCryptoFrames(connection_->transport_version())) {
- for (size_t i = 0; i < NUM_ENCRYPTION_LEVELS; ++i) {
- const StreamState& state = crypto_state_[i];
- if (state.bytes_total > state.bytes_sent) {
- return true;
- }
- QuicIntervalSet<QuicStreamOffset> bytes_to_ack(0, state.bytes_total);
- bytes_to_ack.Difference(state.bytes_acked);
- if (!bytes_to_ack.Empty()) {
- return true;
- }
- }
- return false;
- }
- if (!stream_map_.contains(
- QuicUtils::GetCryptoStreamId(connection_->transport_version()))) {
- return false;
- }
- const auto& state =
- stream_map_
- .find(QuicUtils::GetCryptoStreamId(connection_->transport_version()))
- ->second;
- if (state.bytes_total > state.bytes_sent) {
- return true;
- }
- QuicIntervalSet<QuicStreamOffset> bytes_to_ack(0, state.bytes_total);
- bytes_to_ack.Difference(state.bytes_acked);
- return !bytes_to_ack.Empty();
-}
-
-bool SimpleSessionNotifier::HasUnackedStreamData() const {
- for (const auto& it : stream_map_) {
- if (StreamIsWaitingForAcks(it.first))
- return true;
- }
- return false;
-}
-
-bool SimpleSessionNotifier::OnControlFrameAcked(const QuicFrame& frame) {
- QuicControlFrameId id = GetControlFrameId(frame);
- if (id == kInvalidControlFrameId) {
- return false;
- }
- QUICHE_DCHECK(id < least_unacked_ + control_frames_.size());
- if (id < least_unacked_ ||
- GetControlFrameId(control_frames_.at(id - least_unacked_)) ==
- kInvalidControlFrameId) {
- return false;
- }
- SetControlFrameId(kInvalidControlFrameId,
- &control_frames_.at(id - least_unacked_));
- lost_control_frames_.erase(id);
- while (!control_frames_.empty() &&
- GetControlFrameId(control_frames_.front()) == kInvalidControlFrameId) {
- DeleteFrame(&control_frames_.front());
- control_frames_.pop_front();
- ++least_unacked_;
- }
- return true;
-}
-
-void SimpleSessionNotifier::OnControlFrameLost(const QuicFrame& frame) {
- QuicControlFrameId id = GetControlFrameId(frame);
- if (id == kInvalidControlFrameId) {
- return;
- }
- QUICHE_DCHECK(id < least_unacked_ + control_frames_.size());
- if (id < least_unacked_ ||
- GetControlFrameId(control_frames_.at(id - least_unacked_)) ==
- kInvalidControlFrameId) {
- return;
- }
- if (!lost_control_frames_.contains(id)) {
- lost_control_frames_[id] = true;
- }
-}
-
-bool SimpleSessionNotifier::IsControlFrameOutstanding(
- const QuicFrame& frame) const {
- QuicControlFrameId id = GetControlFrameId(frame);
- if (id == kInvalidControlFrameId) {
- return false;
- }
- return id < least_unacked_ + control_frames_.size() && id >= least_unacked_ &&
- GetControlFrameId(control_frames_.at(id - least_unacked_)) !=
- kInvalidControlFrameId;
-}
-
-bool SimpleSessionNotifier::RetransmitLostControlFrames() {
- while (!lost_control_frames_.empty()) {
- QuicFrame pending = control_frames_.at(lost_control_frames_.begin()->first -
- least_unacked_);
- QuicFrame copy = CopyRetransmittableControlFrame(pending);
- connection_->SetTransmissionType(LOSS_RETRANSMISSION);
- if (!connection_->SendControlFrame(copy)) {
- // Connection is write blocked.
- DeleteFrame(&copy);
- break;
- }
- lost_control_frames_.pop_front();
- }
- return lost_control_frames_.empty();
-}
-
-bool SimpleSessionNotifier::RetransmitLostCryptoData() {
- if (QuicVersionUsesCryptoFrames(connection_->transport_version())) {
- for (EncryptionLevel level :
- {ENCRYPTION_INITIAL, ENCRYPTION_HANDSHAKE, ENCRYPTION_ZERO_RTT,
- ENCRYPTION_FORWARD_SECURE}) {
- auto& state = crypto_state_[level];
- while (!state.pending_retransmissions.Empty()) {
- connection_->SetTransmissionType(HANDSHAKE_RETRANSMISSION);
- EncryptionLevel current_encryption_level =
- connection_->encryption_level();
- connection_->SetDefaultEncryptionLevel(level);
- QuicIntervalSet<QuicStreamOffset> retransmission(
- state.pending_retransmissions.begin()->min(),
- state.pending_retransmissions.begin()->max());
- retransmission.Intersection(crypto_bytes_transferred_[level]);
- QuicStreamOffset retransmission_offset = retransmission.begin()->min();
- QuicByteCount retransmission_length =
- retransmission.begin()->max() - retransmission.begin()->min();
- size_t bytes_consumed = connection_->SendCryptoData(
- level, retransmission_length, retransmission_offset);
- // Restore encryption level.
- connection_->SetDefaultEncryptionLevel(current_encryption_level);
- state.pending_retransmissions.Difference(
- retransmission_offset, retransmission_offset + bytes_consumed);
- if (bytes_consumed < retransmission_length) {
- return false;
- }
- }
- }
- return true;
- }
- if (!stream_map_.contains(
- QuicUtils::GetCryptoStreamId(connection_->transport_version()))) {
- return true;
- }
- auto& state =
- stream_map_
- .find(QuicUtils::GetCryptoStreamId(connection_->transport_version()))
- ->second;
- while (!state.pending_retransmissions.Empty()) {
- connection_->SetTransmissionType(HANDSHAKE_RETRANSMISSION);
- QuicIntervalSet<QuicStreamOffset> retransmission(
- state.pending_retransmissions.begin()->min(),
- state.pending_retransmissions.begin()->max());
- EncryptionLevel retransmission_encryption_level = ENCRYPTION_INITIAL;
- for (size_t i = 0; i < NUM_ENCRYPTION_LEVELS; ++i) {
- if (retransmission.Intersects(crypto_bytes_transferred_[i])) {
- retransmission_encryption_level = static_cast<EncryptionLevel>(i);
- retransmission.Intersection(crypto_bytes_transferred_[i]);
- break;
- }
- }
- QuicStreamOffset retransmission_offset = retransmission.begin()->min();
- QuicByteCount retransmission_length =
- retransmission.begin()->max() - retransmission.begin()->min();
- EncryptionLevel current_encryption_level = connection_->encryption_level();
- // Set appropriate encryption level.
- connection_->SetDefaultEncryptionLevel(retransmission_encryption_level);
- QuicConsumedData consumed = connection_->SendStreamData(
- QuicUtils::GetCryptoStreamId(connection_->transport_version()),
- retransmission_length, retransmission_offset, NO_FIN);
- // Restore encryption level.
- connection_->SetDefaultEncryptionLevel(current_encryption_level);
- state.pending_retransmissions.Difference(
- retransmission_offset, retransmission_offset + consumed.bytes_consumed);
- if (consumed.bytes_consumed < retransmission_length) {
- break;
- }
- }
- return state.pending_retransmissions.Empty();
-}
-
-bool SimpleSessionNotifier::RetransmitLostStreamData() {
- for (auto& pair : stream_map_) {
- StreamState& state = pair.second;
- QuicConsumedData consumed(0, false);
- while (!state.pending_retransmissions.Empty() || state.fin_lost) {
- connection_->SetTransmissionType(LOSS_RETRANSMISSION);
- if (state.pending_retransmissions.Empty()) {
- QUIC_DVLOG(1) << "stream " << pair.first
- << " retransmits fin only frame.";
- consumed =
- connection_->SendStreamData(pair.first, 0, state.bytes_sent, FIN);
- state.fin_lost = !consumed.fin_consumed;
- if (state.fin_lost) {
- QUIC_DLOG(INFO) << "Connection is write blocked";
- return false;
- }
- } else {
- QuicStreamOffset offset = state.pending_retransmissions.begin()->min();
- QuicByteCount length = state.pending_retransmissions.begin()->max() -
- state.pending_retransmissions.begin()->min();
- const bool can_bundle_fin =
- state.fin_lost && (offset + length == state.bytes_sent);
- consumed = connection_->SendStreamData(pair.first, length, offset,
- can_bundle_fin ? FIN : NO_FIN);
- QUIC_DVLOG(1) << "stream " << pair.first
- << " tries to retransmit stream data [" << offset << ", "
- << offset + length << ") and fin: " << can_bundle_fin
- << ", consumed: " << consumed;
- state.pending_retransmissions.Difference(
- offset, offset + consumed.bytes_consumed);
- if (consumed.fin_consumed) {
- state.fin_lost = false;
- }
- if (length > consumed.bytes_consumed ||
- (can_bundle_fin && !consumed.fin_consumed)) {
- QUIC_DVLOG(1) << "Connection is write blocked";
- break;
- }
- }
- }
- }
- return !HasLostStreamData();
-}
-
-bool SimpleSessionNotifier::WriteBufferedCryptoData() {
- for (size_t i = 0; i < NUM_ENCRYPTION_LEVELS; ++i) {
- const StreamState& state = crypto_state_[i];
- QuicIntervalSet<QuicStreamOffset> buffered_crypto_data(0,
- state.bytes_total);
- buffered_crypto_data.Difference(crypto_bytes_transferred_[i]);
- for (const auto& interval : buffered_crypto_data) {
- size_t bytes_written = connection_->SendCryptoData(
- static_cast<EncryptionLevel>(i), interval.Length(), interval.min());
- crypto_state_[i].bytes_sent += bytes_written;
- crypto_bytes_transferred_[i].Add(interval.min(),
- interval.min() + bytes_written);
- if (bytes_written < interval.Length()) {
- return false;
- }
- }
- }
- return true;
-}
-
-bool SimpleSessionNotifier::WriteBufferedControlFrames() {
- while (HasBufferedControlFrames()) {
- QuicFrame frame_to_send =
- control_frames_.at(least_unsent_ - least_unacked_);
- QuicFrame copy = CopyRetransmittableControlFrame(frame_to_send);
- connection_->SetTransmissionType(NOT_RETRANSMISSION);
- if (!connection_->SendControlFrame(copy)) {
- // Connection is write blocked.
- DeleteFrame(&copy);
- break;
- }
- ++least_unsent_;
- }
- return !HasBufferedControlFrames();
-}
-
-bool SimpleSessionNotifier::HasBufferedControlFrames() const {
- return least_unsent_ < least_unacked_ + control_frames_.size();
-}
-
-bool SimpleSessionNotifier::HasBufferedStreamData() const {
- for (const auto& pair : stream_map_) {
- const auto& state = pair.second;
- if (state.bytes_total > state.bytes_sent ||
- (state.fin_buffered && !state.fin_sent)) {
- return true;
- }
- }
- return false;
-}
-
-bool SimpleSessionNotifier::StreamIsWaitingForAcks(QuicStreamId id) const {
- if (!stream_map_.contains(id)) {
- return false;
- }
- const StreamState& state = stream_map_.find(id)->second;
- return !state.bytes_acked.Contains(0, state.bytes_sent) ||
- state.fin_outstanding;
-}
-
-bool SimpleSessionNotifier::StreamHasBufferedData(QuicStreamId id) const {
- if (!stream_map_.contains(id)) {
- return false;
- }
- const StreamState& state = stream_map_.find(id)->second;
- return state.bytes_total > state.bytes_sent ||
- (state.fin_buffered && !state.fin_sent);
-}
-
-bool SimpleSessionNotifier::HasLostStreamData() const {
- for (const auto& pair : stream_map_) {
- const auto& state = pair.second;
- if (!state.pending_retransmissions.Empty() || state.fin_lost) {
- return true;
- }
- }
- return false;
-}
-
-} // namespace test
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/simple_session_notifier.h b/chromium/net/third_party/quiche/src/quic/test_tools/simple_session_notifier.h
deleted file mode 100644
index 5712884fcd2..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/simple_session_notifier.h
+++ /dev/null
@@ -1,170 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_SIMPLE_SESSION_NOTIFIER_H_
-#define QUICHE_QUIC_TEST_TOOLS_SIMPLE_SESSION_NOTIFIER_H_
-
-#include "absl/container/flat_hash_map.h"
-#include "quic/core/quic_interval_set.h"
-#include "quic/core/session_notifier_interface.h"
-#include "quic/platform/api/quic_test.h"
-#include "common/quiche_circular_deque.h"
-#include "common/quiche_linked_hash_map.h"
-
-namespace quic {
-
-class QuicConnection;
-
-namespace test {
-
-// SimpleSessionNotifier implements the basic functionalities of a session, and
-// it manages stream data and control frames.
-class SimpleSessionNotifier : public SessionNotifierInterface {
- public:
- explicit SimpleSessionNotifier(QuicConnection* connection);
- ~SimpleSessionNotifier() override;
-
- // Tries to write stream data and returns data consumed.
- QuicConsumedData WriteOrBufferData(QuicStreamId id,
- QuicByteCount data_length,
- StreamSendingState state);
-
- // Tries to write RST_STREAM_FRAME.
- void WriteOrBufferRstStream(QuicStreamId id,
- QuicRstStreamErrorCode error,
- QuicStreamOffset bytes_written);
-
- // Tries to write WINDOW_UPDATE.
- void WriteOrBufferWindowUpate(QuicStreamId id, QuicStreamOffset byte_offset);
-
- // Tries to write PING.
- void WriteOrBufferPing();
-
- // Tries to write ACK_FREQUENCY.
- void WriteOrBufferAckFrequency(
- const QuicAckFrequencyFrame& ack_frequency_frame);
-
- // Tries to write CRYPTO data and returns the number of bytes written.
- size_t WriteCryptoData(EncryptionLevel level,
- QuicByteCount data_length,
- QuicStreamOffset offset);
-
- // Neuters unencrypted data of crypto stream.
- void NeuterUnencryptedData();
-
- // Called when connection_ becomes writable.
- void OnCanWrite();
-
- // Called to reset stream.
- void OnStreamReset(QuicStreamId id, QuicRstStreamErrorCode error);
-
- // Returns true if there are 1) unsent control frames and stream data, or 2)
- // lost control frames and stream data.
- bool WillingToWrite() const;
-
- // Number of sent stream bytes. Please note, this does not count
- // retransmissions.
- QuicByteCount StreamBytesSent() const;
-
- // Number of stream bytes waiting to be sent for the first time.
- QuicByteCount StreamBytesToSend() const;
-
- // Returns true if there is any stream data waiting to be sent for the first
- // time.
- bool HasBufferedStreamData() const;
-
- // Returns true if stream |id| has any outstanding data.
- bool StreamIsWaitingForAcks(QuicStreamId id) const;
-
- // SessionNotifierInterface methods:
- bool OnFrameAcked(const QuicFrame& frame,
- QuicTime::Delta ack_delay_time,
- QuicTime receive_timestamp) override;
- void OnStreamFrameRetransmitted(const QuicStreamFrame& /*frame*/) override {}
- void OnFrameLost(const QuicFrame& frame) override;
- void RetransmitFrames(const QuicFrames& frames,
- TransmissionType type) override;
- bool IsFrameOutstanding(const QuicFrame& frame) const override;
- bool HasUnackedCryptoData() const override;
- bool HasUnackedStreamData() const override;
- bool HasLostStreamData() const;
-
- private:
- struct StreamState {
- StreamState();
- ~StreamState();
-
- // Total number of bytes.
- QuicByteCount bytes_total;
- // Number of sent bytes.
- QuicByteCount bytes_sent;
- // Record of acked offsets.
- QuicIntervalSet<QuicStreamOffset> bytes_acked;
- // Data considered as lost and needs to be retransmitted.
- QuicIntervalSet<QuicStreamOffset> pending_retransmissions;
-
- bool fin_buffered;
- bool fin_sent;
- bool fin_outstanding;
- bool fin_lost;
- };
-
- friend std::ostream& operator<<(std::ostream& os, const StreamState& s);
-
- using StreamMap = absl::flat_hash_map<QuicStreamId, StreamState>;
-
- void OnStreamDataConsumed(QuicStreamId id,
- QuicStreamOffset offset,
- QuicByteCount data_length,
- bool fin);
-
- bool OnControlFrameAcked(const QuicFrame& frame);
-
- void OnControlFrameLost(const QuicFrame& frame);
-
- bool RetransmitLostControlFrames();
-
- bool RetransmitLostCryptoData();
-
- bool RetransmitLostStreamData();
-
- bool WriteBufferedControlFrames();
-
- bool WriteBufferedCryptoData();
-
- bool IsControlFrameOutstanding(const QuicFrame& frame) const;
-
- bool HasBufferedControlFrames() const;
-
- bool StreamHasBufferedData(QuicStreamId id) const;
-
- quiche::QuicheCircularDeque<QuicFrame> control_frames_;
-
- quiche::QuicheLinkedHashMap<QuicControlFrameId, bool> lost_control_frames_;
-
- // Id of latest saved control frame. 0 if no control frame has been saved.
- QuicControlFrameId last_control_frame_id_;
-
- // The control frame at the 0th index of control_frames_.
- QuicControlFrameId least_unacked_;
-
- // ID of the least unsent control frame.
- QuicControlFrameId least_unsent_;
-
- StreamMap stream_map_;
-
- // Transferred crypto bytes according to encryption levels.
- QuicIntervalSet<QuicStreamOffset>
- crypto_bytes_transferred_[NUM_ENCRYPTION_LEVELS];
-
- StreamState crypto_state_[NUM_ENCRYPTION_LEVELS];
-
- QuicConnection* connection_;
-};
-
-} // namespace test
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_TEST_TOOLS_SIMPLE_SESSION_NOTIFIER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/simple_session_notifier_test.cc b/chromium/net/third_party/quiche/src/quic/test_tools/simple_session_notifier_test.cc
deleted file mode 100644
index a88cb804b46..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/simple_session_notifier_test.cc
+++ /dev/null
@@ -1,367 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/simple_session_notifier.h"
-
-#include <utility>
-
-#include "quic/core/crypto/null_encrypter.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/quic_connection_peer.h"
-#include "quic/test_tools/quic_test_utils.h"
-#include "quic/test_tools/simple_data_producer.h"
-
-using testing::_;
-using testing::InSequence;
-using testing::Return;
-using testing::StrictMock;
-
-namespace quic {
-namespace test {
-namespace {
-
-class MockQuicConnectionWithSendStreamData : public MockQuicConnection {
- public:
- MockQuicConnectionWithSendStreamData(MockQuicConnectionHelper* helper,
- MockAlarmFactory* alarm_factory,
- Perspective perspective)
- : MockQuicConnection(helper, alarm_factory, perspective) {}
-
- MOCK_METHOD(QuicConsumedData,
- SendStreamData,
- (QuicStreamId id,
- size_t write_length,
- QuicStreamOffset offset,
- StreamSendingState state),
- (override));
-};
-
-class SimpleSessionNotifierTest : public QuicTest {
- public:
- SimpleSessionNotifierTest()
- : connection_(&helper_, &alarm_factory_, Perspective::IS_CLIENT),
- notifier_(&connection_) {
- connection_.set_visitor(&visitor_);
- connection_.SetSessionNotifier(&notifier_);
- EXPECT_FALSE(notifier_.WillingToWrite());
- EXPECT_EQ(0u, notifier_.StreamBytesSent());
- EXPECT_FALSE(notifier_.HasBufferedStreamData());
- }
-
- bool ControlFrameConsumed(const QuicFrame& frame) {
- DeleteFrame(&const_cast<QuicFrame&>(frame));
- return true;
- }
-
- MockQuicConnectionHelper helper_;
- MockAlarmFactory alarm_factory_;
- MockQuicConnectionVisitor visitor_;
- StrictMock<MockQuicConnectionWithSendStreamData> connection_;
- SimpleSessionNotifier notifier_;
-};
-
-TEST_F(SimpleSessionNotifierTest, WriteOrBufferData) {
- InSequence s;
- EXPECT_CALL(connection_, SendStreamData(3, 1024, 0, NO_FIN))
- .WillOnce(Return(QuicConsumedData(1024, false)));
- notifier_.WriteOrBufferData(3, 1024, NO_FIN);
- EXPECT_EQ(0u, notifier_.StreamBytesToSend());
- EXPECT_CALL(connection_, SendStreamData(5, 512, 0, NO_FIN))
- .WillOnce(Return(QuicConsumedData(512, false)));
- notifier_.WriteOrBufferData(5, 512, NO_FIN);
- EXPECT_FALSE(notifier_.WillingToWrite());
- // Connection is blocked.
- EXPECT_CALL(connection_, SendStreamData(5, 512, 512, FIN))
- .WillOnce(Return(QuicConsumedData(256, false)));
- notifier_.WriteOrBufferData(5, 512, FIN);
- EXPECT_TRUE(notifier_.WillingToWrite());
- EXPECT_EQ(1792u, notifier_.StreamBytesSent());
- EXPECT_EQ(256u, notifier_.StreamBytesToSend());
- EXPECT_TRUE(notifier_.HasBufferedStreamData());
-
- // New data cannot be sent as connection is blocked.
- EXPECT_CALL(connection_, SendStreamData(7, 1024, 0, FIN)).Times(0);
- notifier_.WriteOrBufferData(7, 1024, FIN);
- EXPECT_EQ(1792u, notifier_.StreamBytesSent());
-}
-
-TEST_F(SimpleSessionNotifierTest, WriteOrBufferRstStream) {
- InSequence s;
- EXPECT_CALL(connection_, SendStreamData(5, 1024, 0, FIN))
- .WillOnce(Return(QuicConsumedData(1024, true)));
- notifier_.WriteOrBufferData(5, 1024, FIN);
- EXPECT_TRUE(notifier_.StreamIsWaitingForAcks(5));
- EXPECT_TRUE(notifier_.HasUnackedStreamData());
-
- // Reset stream 5 with no error.
- EXPECT_CALL(connection_, SendControlFrame(_))
- .WillRepeatedly(
- Invoke(this, &SimpleSessionNotifierTest::ControlFrameConsumed));
- notifier_.WriteOrBufferRstStream(5, QUIC_STREAM_NO_ERROR, 1024);
- // Verify stream 5 is waiting for acks.
- EXPECT_TRUE(notifier_.StreamIsWaitingForAcks(5));
- EXPECT_TRUE(notifier_.HasUnackedStreamData());
-
- // Reset stream 5 with error.
- notifier_.WriteOrBufferRstStream(5, QUIC_ERROR_PROCESSING_STREAM, 1024);
- EXPECT_FALSE(notifier_.StreamIsWaitingForAcks(5));
- EXPECT_FALSE(notifier_.HasUnackedStreamData());
-}
-
-TEST_F(SimpleSessionNotifierTest, WriteOrBufferPing) {
- InSequence s;
- // Write ping when connection is not write blocked.
- EXPECT_CALL(connection_, SendControlFrame(_))
- .WillRepeatedly(
- Invoke(this, &SimpleSessionNotifierTest::ControlFrameConsumed));
- notifier_.WriteOrBufferPing();
- EXPECT_EQ(0u, notifier_.StreamBytesToSend());
- EXPECT_FALSE(notifier_.WillingToWrite());
-
- // Write stream data and cause the connection to be write blocked.
- EXPECT_CALL(connection_, SendStreamData(3, 1024, 0, NO_FIN))
- .WillOnce(Return(QuicConsumedData(1024, false)));
- notifier_.WriteOrBufferData(3, 1024, NO_FIN);
- EXPECT_EQ(0u, notifier_.StreamBytesToSend());
- EXPECT_CALL(connection_, SendStreamData(5, 512, 0, NO_FIN))
- .WillOnce(Return(QuicConsumedData(256, false)));
- notifier_.WriteOrBufferData(5, 512, NO_FIN);
- EXPECT_TRUE(notifier_.WillingToWrite());
-
- // Connection is blocked.
- EXPECT_CALL(connection_, SendControlFrame(_)).Times(0);
- notifier_.WriteOrBufferPing();
-}
-
-TEST_F(SimpleSessionNotifierTest, NeuterUnencryptedData) {
- if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
- // This test writes crypto data through crypto streams. It won't work when
- // crypto frames are used instead.
- return;
- }
- InSequence s;
- // Send crypto data [0, 1024) in ENCRYPTION_INITIAL.
- connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
- EXPECT_CALL(connection_, SendStreamData(QuicUtils::GetCryptoStreamId(
- connection_.transport_version()),
- 1024, 0, NO_FIN))
- .WillOnce(Return(QuicConsumedData(1024, false)));
- notifier_.WriteOrBufferData(
- QuicUtils::GetCryptoStreamId(connection_.transport_version()), 1024,
- NO_FIN);
- // Send crypto data [1024, 2048) in ENCRYPTION_ZERO_RTT.
- connection_.SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
- EXPECT_CALL(connection_, SendStreamData(QuicUtils::GetCryptoStreamId(
- connection_.transport_version()),
- 1024, 1024, NO_FIN))
- .WillOnce(Return(QuicConsumedData(1024, false)));
- notifier_.WriteOrBufferData(
- QuicUtils::GetCryptoStreamId(connection_.transport_version()), 1024,
- NO_FIN);
- // Ack [1024, 2048).
- QuicStreamFrame stream_frame(
- QuicUtils::GetCryptoStreamId(connection_.transport_version()), false,
- 1024, 1024);
- notifier_.OnFrameAcked(QuicFrame(stream_frame), QuicTime::Delta::Zero(),
- QuicTime::Zero());
- EXPECT_TRUE(notifier_.StreamIsWaitingForAcks(
- QuicUtils::GetCryptoStreamId(connection_.transport_version())));
- EXPECT_TRUE(notifier_.HasUnackedStreamData());
-
- // Neuters unencrypted data.
- notifier_.NeuterUnencryptedData();
- EXPECT_FALSE(notifier_.StreamIsWaitingForAcks(
- QuicUtils::GetCryptoStreamId(connection_.transport_version())));
- EXPECT_FALSE(notifier_.HasUnackedStreamData());
-}
-
-TEST_F(SimpleSessionNotifierTest, OnCanWrite) {
- if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
- // This test writes crypto data through crypto streams. It won't work when
- // crypto frames are used instead.
- return;
- }
- InSequence s;
- // Send crypto data [0, 1024) in ENCRYPTION_INITIAL.
- connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
- EXPECT_CALL(connection_, SendStreamData(QuicUtils::GetCryptoStreamId(
- connection_.transport_version()),
- 1024, 0, NO_FIN))
- .WillOnce(Return(QuicConsumedData(1024, false)));
- notifier_.WriteOrBufferData(
- QuicUtils::GetCryptoStreamId(connection_.transport_version()), 1024,
- NO_FIN);
-
- // Send crypto data [1024, 2048) in ENCRYPTION_ZERO_RTT.
- connection_.SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
- EXPECT_CALL(connection_, SendStreamData(QuicUtils::GetCryptoStreamId(
- connection_.transport_version()),
- 1024, 1024, NO_FIN))
- .WillOnce(Return(QuicConsumedData(1024, false)));
- notifier_.WriteOrBufferData(
- QuicUtils::GetCryptoStreamId(connection_.transport_version()), 1024,
- NO_FIN);
- // Send stream 3 [0, 1024) and connection is blocked.
- EXPECT_CALL(connection_, SendStreamData(3, 1024, 0, FIN))
- .WillOnce(Return(QuicConsumedData(512, false)));
- notifier_.WriteOrBufferData(3, 1024, FIN);
- // Send stream 5 [0, 1024).
- EXPECT_CALL(connection_, SendStreamData(5, _, _, _)).Times(0);
- notifier_.WriteOrBufferData(5, 1024, NO_FIN);
- // Reset stream 5 with error.
- EXPECT_CALL(connection_, SendControlFrame(_)).Times(0);
- notifier_.WriteOrBufferRstStream(5, QUIC_ERROR_PROCESSING_STREAM, 1024);
-
- // Lost crypto data [500, 1500) and stream 3 [0, 512).
- QuicStreamFrame frame1(
- QuicUtils::GetCryptoStreamId(connection_.transport_version()), false, 500,
- 1000);
- QuicStreamFrame frame2(3, false, 0, 512);
- notifier_.OnFrameLost(QuicFrame(frame1));
- notifier_.OnFrameLost(QuicFrame(frame2));
-
- // Connection becomes writable.
- // Lost crypto data gets retransmitted as [500, 1024) and [1024, 1500), as
- // they are in different encryption levels.
- EXPECT_CALL(connection_, SendStreamData(QuicUtils::GetCryptoStreamId(
- connection_.transport_version()),
- 524, 500, NO_FIN))
- .WillOnce(Return(QuicConsumedData(524, false)));
- EXPECT_CALL(connection_, SendStreamData(QuicUtils::GetCryptoStreamId(
- connection_.transport_version()),
- 476, 1024, NO_FIN))
- .WillOnce(Return(QuicConsumedData(476, false)));
- // Lost stream 3 data gets retransmitted.
- EXPECT_CALL(connection_, SendStreamData(3, 512, 0, NO_FIN))
- .WillOnce(Return(QuicConsumedData(512, false)));
- // Buffered control frames get sent.
- EXPECT_CALL(connection_, SendControlFrame(_))
- .WillOnce(Invoke(this, &SimpleSessionNotifierTest::ControlFrameConsumed));
- // Buffered stream 3 data [512, 1024) gets sent.
- EXPECT_CALL(connection_, SendStreamData(3, 512, 512, FIN))
- .WillOnce(Return(QuicConsumedData(512, true)));
- notifier_.OnCanWrite();
- EXPECT_FALSE(notifier_.WillingToWrite());
-}
-
-TEST_F(SimpleSessionNotifierTest, OnCanWriteCryptoFrames) {
- if (!QuicVersionUsesCryptoFrames(connection_.transport_version())) {
- return;
- }
- SimpleDataProducer producer;
- connection_.SetDataProducer(&producer);
- InSequence s;
- // Send crypto data [0, 1024) in ENCRYPTION_INITIAL.
- connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
- EXPECT_CALL(connection_, SendCryptoData(ENCRYPTION_INITIAL, 1024, 0))
- .WillOnce(Invoke(&connection_,
- &MockQuicConnection::QuicConnection_SendCryptoData));
- EXPECT_CALL(connection_, CloseConnection(QUIC_PACKET_WRITE_ERROR, _, _));
- std::string crypto_data1(1024, 'a');
- producer.SaveCryptoData(ENCRYPTION_INITIAL, 0, crypto_data1);
- std::string crypto_data2(524, 'a');
- producer.SaveCryptoData(ENCRYPTION_INITIAL, 500, crypto_data2);
- notifier_.WriteCryptoData(ENCRYPTION_INITIAL, 1024, 0);
- // Send crypto data [1024, 2048) in ENCRYPTION_ZERO_RTT.
- connection_.SetEncrypter(ENCRYPTION_ZERO_RTT, std::make_unique<NullEncrypter>(
- Perspective::IS_CLIENT));
- connection_.SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
- EXPECT_CALL(connection_, SendCryptoData(ENCRYPTION_ZERO_RTT, 1024, 0))
- .WillOnce(Invoke(&connection_,
- &MockQuicConnection::QuicConnection_SendCryptoData));
- std::string crypto_data3(1024, 'a');
- producer.SaveCryptoData(ENCRYPTION_ZERO_RTT, 0, crypto_data3);
- notifier_.WriteCryptoData(ENCRYPTION_ZERO_RTT, 1024, 0);
- // Send stream 3 [0, 1024) and connection is blocked.
- EXPECT_CALL(connection_, SendStreamData(3, 1024, 0, FIN))
- .WillOnce(Return(QuicConsumedData(512, false)));
- notifier_.WriteOrBufferData(3, 1024, FIN);
- // Send stream 5 [0, 1024).
- EXPECT_CALL(connection_, SendStreamData(5, _, _, _)).Times(0);
- notifier_.WriteOrBufferData(5, 1024, NO_FIN);
- // Reset stream 5 with error.
- EXPECT_CALL(connection_, SendControlFrame(_)).Times(0);
- notifier_.WriteOrBufferRstStream(5, QUIC_ERROR_PROCESSING_STREAM, 1024);
-
- // Lost crypto data [500, 1500) and stream 3 [0, 512).
- QuicCryptoFrame crypto_frame1(ENCRYPTION_INITIAL, 500, 524);
- QuicCryptoFrame crypto_frame2(ENCRYPTION_ZERO_RTT, 0, 476);
- QuicStreamFrame stream3_frame(3, false, 0, 512);
- notifier_.OnFrameLost(QuicFrame(&crypto_frame1));
- notifier_.OnFrameLost(QuicFrame(&crypto_frame2));
- notifier_.OnFrameLost(QuicFrame(stream3_frame));
-
- // Connection becomes writable.
- // Lost crypto data gets retransmitted as [500, 1024) and [1024, 1500), as
- // they are in different encryption levels.
- EXPECT_CALL(connection_, SendCryptoData(ENCRYPTION_INITIAL, 524, 500))
- .WillOnce(Invoke(&connection_,
- &MockQuicConnection::QuicConnection_SendCryptoData));
- EXPECT_CALL(connection_, SendCryptoData(ENCRYPTION_ZERO_RTT, 476, 0))
- .WillOnce(Invoke(&connection_,
- &MockQuicConnection::QuicConnection_SendCryptoData));
- // Lost stream 3 data gets retransmitted.
- EXPECT_CALL(connection_, SendStreamData(3, 512, 0, NO_FIN))
- .WillOnce(Return(QuicConsumedData(512, false)));
- // Buffered control frames get sent.
- EXPECT_CALL(connection_, SendControlFrame(_))
- .WillOnce(Invoke(this, &SimpleSessionNotifierTest::ControlFrameConsumed));
- // Buffered stream 3 data [512, 1024) gets sent.
- EXPECT_CALL(connection_, SendStreamData(3, 512, 512, FIN))
- .WillOnce(Return(QuicConsumedData(512, true)));
- notifier_.OnCanWrite();
- EXPECT_FALSE(notifier_.WillingToWrite());
-}
-
-TEST_F(SimpleSessionNotifierTest, RetransmitFrames) {
- InSequence s;
- // Send stream 3 data [0, 10) and fin.
- EXPECT_CALL(connection_, SendStreamData(3, 10, 0, FIN))
- .WillOnce(Return(QuicConsumedData(10, true)));
- notifier_.WriteOrBufferData(3, 10, FIN);
- QuicStreamFrame frame1(3, true, 0, 10);
- // Send stream 5 [0, 10) and fin.
- EXPECT_CALL(connection_, SendStreamData(5, 10, 0, FIN))
- .WillOnce(Return(QuicConsumedData(10, true)));
- notifier_.WriteOrBufferData(5, 10, FIN);
- QuicStreamFrame frame2(5, true, 0, 10);
- // Reset stream 5 with no error.
- EXPECT_CALL(connection_, SendControlFrame(_))
- .WillOnce(Invoke(this, &SimpleSessionNotifierTest::ControlFrameConsumed));
- notifier_.WriteOrBufferRstStream(5, QUIC_STREAM_NO_ERROR, 10);
-
- // Ack stream 3 [3, 7), and stream 5 [8, 10).
- QuicStreamFrame ack_frame1(3, false, 3, 4);
- QuicStreamFrame ack_frame2(5, false, 8, 2);
- notifier_.OnFrameAcked(QuicFrame(ack_frame1), QuicTime::Delta::Zero(),
- QuicTime::Zero());
- notifier_.OnFrameAcked(QuicFrame(ack_frame2), QuicTime::Delta::Zero(),
- QuicTime::Zero());
- EXPECT_FALSE(notifier_.WillingToWrite());
-
- // Force to send.
- QuicRstStreamFrame rst_stream(1, 5, QUIC_STREAM_NO_ERROR, 10);
- QuicFrames frames;
- frames.push_back(QuicFrame(frame2));
- frames.push_back(QuicFrame(&rst_stream));
- frames.push_back(QuicFrame(frame1));
- // stream 5 data [0, 8), fin only are retransmitted.
- EXPECT_CALL(connection_, SendStreamData(5, 8, 0, NO_FIN))
- .WillOnce(Return(QuicConsumedData(8, false)));
- EXPECT_CALL(connection_, SendStreamData(5, 0, 10, FIN))
- .WillOnce(Return(QuicConsumedData(0, true)));
- // rst_stream is retransmitted.
- EXPECT_CALL(connection_, SendControlFrame(_))
- .WillOnce(Invoke(this, &SimpleSessionNotifierTest::ControlFrameConsumed));
- // 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);
- EXPECT_FALSE(notifier_.WillingToWrite());
-}
-
-} // namespace
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/simulator/README.md b/chromium/net/third_party/quiche/src/quic/test_tools/simulator/README.md
deleted file mode 100644
index 8582962adee..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/simulator/README.md
+++ /dev/null
@@ -1,99 +0,0 @@
-# QUIC network simulator
-
-This directory contains a discrete event network simulator which QUIC code uses
-for testing congestion control and other transmission control code that requires
-a network simulation for tests on QuicConnection level of abstraction.
-
-## Actors
-
-The core of the simulator is the Simulator class, which maintains a virtual
-clock and an event queue. Any object in a simulation that needs to schedule
-events has to subclass Actor. Subclassing Actor involves:
-
-1. Calling the `Actor::Actor(Simulator*, std::string)` constructor to establish
- the name of the object and the simulator it is associated with.
-2. Calling `Schedule(QuicTime)` to schedule the time at which `Act()` method is
- called. `Schedule` will only cause the object to be rescheduled if the time
- for which it is currently scheduled is later than the new time.
-3. Implementing `Act()` method with the relevant logic. The actor will be
- removed from the event queue right before `Act()` is called.
-
-Here is a simple example of an object that outputs simulation time into the log
-every 100 ms.
-
-```c++
-class LogClock : public Actor {
- public:
- LogClock(Simulator* simulator, std::string name) : Actor(simulator, name) {
- Schedule(clock_->Now());
- }
- ~LogClock() override {}
-
- void Act() override {
- QUIC_LOG(INFO) << "The current time is "
- << clock_->Now().ToDebuggingValue();
- Schedule(clock_->Now() + QuicTime::Delta::FromMilliseconds(100));
- }
-};
-```
-
-A QuicAlarm object can be used to schedule events in the simulation using
-`Simulator::GetAlarmFactory()`.
-
-## Ports
-
-The simulated network transfers packets, which are modelled as an instance of
-struct `Packet`. A packet consists of source and destination address (which are
-just plain strings), a transmission timestamp and the UDP-layer payload.
-
-The simulation uses the push model: any object that wishes to transfer a packet
-to another component in the simulation has to explicitly do it itself. Any
-object that can accept a packet is called a *port*. There are two types of
-ports: unconstrained ports, which can always accept packets, and constrained
-ports, which signal when they can accept a new packet.
-
-An endpoint is an object that is connected to the network and can both receive
-and send packets. In our model, the endpoint always receives packets as an
-unconstrained port (*RX port*), and always writes packets to a constrained port
-(*TX port*).
-
-## Links
-
-The `SymmetricLink` class models a symmetric duplex links with finite bandwidth
-and propagation delay. It consists of a pair of identical `OneWayLink`s, which
-accept packets as a constrained port (where constrain comes from the finiteness
-of bandwidth) and outputs them into an unconstrained port. Two endpoints
-connected via a `SymmetricLink` look like this:
-
-```none
- Endpoint A Endpoint B
-+-----------+ SymmetricLink +-----------+
-| | +------------------------------+ | |
-| +---------+ | +------------------------+ | +---------+ |
-| | RX port <-----| OneWayLink *<-----| TX port | |
-| +---------+ | +------------------------+ | +---------+ |
-| | | | | |
-| +---------+ | +------------------------+ | +---------+ |
-| | TX port |----->* OneWayLink |-----> RX port | |
-| +---------+ | +------------------------+ | +---------+ |
-| | +------------------------------+ | |
-+-----------+ +-----------+
-
- ( -->* denotes constrained port)
-```
-
-In most common scenario, one of the endpoints is going to be a QUIC endpoint,
-and another is going to be a switch port.
-
-## Other objects
-
-Besides `SymmetricLink`, the simulator provides the following objects:
-
-* `Queue` allows to convert a constrained port into an unconstrained one by
- buffering packets upon arrival. The queue has a finite size, and once the
- queue is full, the packets are silently dropped.
-* `Switch` simulates a multi-port learning switch with a fixed queue for each
- output port.
-* `QuicEndpoint` allows QuicConnection to be run over the simulated network.
-* `QuicEndpointMultiplexer` allows multiple connections to share the same
- network endpoint.
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/simulator/actor.cc b/chromium/net/third_party/quiche/src/quic/test_tools/simulator/actor.cc
deleted file mode 100644
index acb548c8e8b..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/simulator/actor.cc
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/simulator/actor.h"
-#include "quic/test_tools/simulator/simulator.h"
-
-namespace quic {
-namespace simulator {
-
-Actor::Actor(Simulator* simulator, std::string name)
- : simulator_(simulator),
- clock_(simulator->GetClock()),
- name_(std::move(name)) {
- simulator_->AddActor(this);
-}
-
-Actor::~Actor() {
- simulator_->RemoveActor(this);
-}
-
-void Actor::Schedule(QuicTime next_tick) {
- simulator_->Schedule(this, next_tick);
-}
-
-void Actor::Unschedule() {
- simulator_->Unschedule(this);
-}
-
-} // namespace simulator
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/simulator/actor.h b/chromium/net/third_party/quiche/src/quic/test_tools/simulator/actor.h
deleted file mode 100644
index a333399a3ce..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/simulator/actor.h
+++ /dev/null
@@ -1,66 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_SIMULATOR_ACTOR_H_
-#define QUICHE_QUIC_TEST_TOOLS_SIMULATOR_ACTOR_H_
-
-#include <string>
-
-#include "quic/core/quic_clock.h"
-#include "quic/core/quic_time.h"
-
-namespace quic {
-namespace simulator {
-
-class Simulator;
-
-// Actor is the base class for all participants of the simulation which can
-// schedule events to be triggered at the specified time. Every actor has a
-// name assigned to it, which can be used for debugging and addressing purposes.
-//
-// The Actor object is scheduled as follows:
-// 1. Every Actor object appears at most once in the event queue, for one
-// specific time.
-// 2. Actor is scheduled by calling Schedule() method.
-// 3. If Schedule() method is called with multiple different times specified,
-// Act() method will be called at the earliest time specified.
-// 4. Before Act() is called, the Actor is removed from the event queue. Act()
-// will not be called again unless Schedule() is called.
-class Actor {
- public:
- Actor(Simulator* simulator, std::string name);
- virtual ~Actor();
-
- // Trigger all the events the actor can potentially handle at this point.
- // Before Act() is called, the actor is removed from the event queue, and has
- // to schedule the next call manually.
- virtual void Act() = 0;
-
- inline std::string name() const { return name_; }
- inline Simulator* simulator() const { return simulator_; }
-
- protected:
- // Calls Schedule() on the associated simulator.
- void Schedule(QuicTime next_tick);
-
- // Calls Unschedule() on the associated simulator.
- void Unschedule();
-
- Simulator* simulator_;
- const QuicClock* clock_;
- std::string name_;
-
- private:
- // Since the Actor object registers itself with a simulator using a pointer to
- // itself, do not allow it to be moved.
- Actor(Actor&&) = delete;
- Actor(const Actor&) = delete;
- Actor& operator=(const Actor&) = delete;
- Actor& operator=(Actor&&) = delete;
-};
-
-} // namespace simulator
-} // namespace quic
-
-#endif // QUICHE_QUIC_TEST_TOOLS_SIMULATOR_ACTOR_H_
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/simulator/alarm_factory.cc b/chromium/net/third_party/quiche/src/quic/test_tools/simulator/alarm_factory.cc
deleted file mode 100644
index 86ee49e5f3d..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/simulator/alarm_factory.cc
+++ /dev/null
@@ -1,81 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/simulator/alarm_factory.h"
-
-#include "absl/strings/str_format.h"
-#include "quic/core/quic_alarm.h"
-
-namespace quic {
-namespace simulator {
-
-// Alarm is an implementation of QuicAlarm which can schedule alarms in the
-// simulation timeline.
-class Alarm : public QuicAlarm {
- public:
- Alarm(Simulator* simulator,
- std::string name,
- QuicArenaScopedPtr<QuicAlarm::Delegate> delegate)
- : QuicAlarm(std::move(delegate)), adapter_(simulator, name, this) {}
- ~Alarm() override {}
-
- void SetImpl() override {
- QUICHE_DCHECK(deadline().IsInitialized());
- adapter_.Set(deadline());
- }
-
- void CancelImpl() override { adapter_.Cancel(); }
-
- private:
- // An adapter class triggering a QuicAlarm using a simulation time system.
- // An adapter is required here because neither Actor nor QuicAlarm are pure
- // interfaces.
- class Adapter : public Actor {
- public:
- Adapter(Simulator* simulator, std::string name, Alarm* parent)
- : Actor(simulator, name), parent_(parent) {}
- ~Adapter() override {}
-
- void Set(QuicTime time) { Schedule(std::max(time, clock_->Now())); }
- void Cancel() { Unschedule(); }
-
- void Act() override {
- QUICHE_DCHECK(clock_->Now() >= parent_->deadline());
- parent_->Fire();
- }
-
- private:
- Alarm* parent_;
- };
- Adapter adapter_;
-};
-
-AlarmFactory::AlarmFactory(Simulator* simulator, std::string name)
- : simulator_(simulator), name_(std::move(name)), counter_(0) {}
-
-AlarmFactory::~AlarmFactory() {}
-
-std::string AlarmFactory::GetNewAlarmName() {
- ++counter_;
- return absl::StrFormat("%s (alarm %i)", name_, counter_);
-}
-
-QuicAlarm* AlarmFactory::CreateAlarm(QuicAlarm::Delegate* delegate) {
- return new Alarm(simulator_, GetNewAlarmName(),
- QuicArenaScopedPtr<QuicAlarm::Delegate>(delegate));
-}
-
-QuicArenaScopedPtr<QuicAlarm> AlarmFactory::CreateAlarm(
- QuicArenaScopedPtr<QuicAlarm::Delegate> delegate,
- QuicConnectionArena* arena) {
- if (arena != nullptr) {
- return arena->New<Alarm>(simulator_, GetNewAlarmName(),
- std::move(delegate));
- }
- return QuicArenaScopedPtr<QuicAlarm>(
- new Alarm(simulator_, GetNewAlarmName(), std::move(delegate)));
-}
-
-} // namespace simulator
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/simulator/alarm_factory.h b/chromium/net/third_party/quiche/src/quic/test_tools/simulator/alarm_factory.h
deleted file mode 100644
index a9fdd33304d..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/simulator/alarm_factory.h
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_SIMULATOR_ALARM_FACTORY_H_
-#define QUICHE_QUIC_TEST_TOOLS_SIMULATOR_ALARM_FACTORY_H_
-
-#include "quic/core/quic_alarm_factory.h"
-#include "quic/test_tools/simulator/actor.h"
-
-namespace quic {
-namespace simulator {
-
-// AlarmFactory allows to schedule QuicAlarms using the simulation event queue.
-class AlarmFactory : public QuicAlarmFactory {
- public:
- AlarmFactory(Simulator* simulator, std::string name);
- AlarmFactory(const AlarmFactory&) = delete;
- AlarmFactory& operator=(const AlarmFactory&) = delete;
- ~AlarmFactory() override;
-
- QuicAlarm* CreateAlarm(QuicAlarm::Delegate* delegate) override;
- QuicArenaScopedPtr<QuicAlarm> CreateAlarm(
- QuicArenaScopedPtr<QuicAlarm::Delegate> delegate,
- QuicConnectionArena* arena) override;
-
- private:
- // Automatically generate a name for a new alarm.
- std::string GetNewAlarmName();
-
- Simulator* simulator_;
- std::string name_;
- int counter_;
-};
-
-} // namespace simulator
-} // namespace quic
-
-#endif // QUICHE_QUIC_TEST_TOOLS_SIMULATOR_ALARM_FACTORY_H_
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/simulator/link.cc b/chromium/net/third_party/quiche/src/quic/test_tools/simulator/link.cc
deleted file mode 100644
index 6d435978bc6..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/simulator/link.cc
+++ /dev/null
@@ -1,127 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/simulator/link.h"
-
-#include "absl/strings/str_cat.h"
-#include "absl/strings/str_format.h"
-#include "quic/test_tools/simulator/simulator.h"
-
-namespace quic {
-namespace simulator {
-
-// Parameters for random noise delay.
-const uint64_t kMaxRandomDelayUs = 10;
-
-OneWayLink::OneWayLink(Simulator* simulator,
- std::string name,
- UnconstrainedPortInterface* sink,
- QuicBandwidth bandwidth,
- QuicTime::Delta propagation_delay)
- : Actor(simulator, name),
- sink_(sink),
- bandwidth_(bandwidth),
- propagation_delay_(propagation_delay),
- next_write_at_(QuicTime::Zero()) {}
-
-OneWayLink::~OneWayLink() {}
-
-OneWayLink::QueuedPacket::QueuedPacket(std::unique_ptr<Packet> packet,
- QuicTime dequeue_time)
- : packet(std::move(packet)), dequeue_time(dequeue_time) {}
-
-OneWayLink::QueuedPacket::QueuedPacket(QueuedPacket&& other) = default;
-
-OneWayLink::QueuedPacket::~QueuedPacket() {}
-
-void OneWayLink::AcceptPacket(std::unique_ptr<Packet> packet) {
- QUICHE_DCHECK(TimeUntilAvailable().IsZero());
- QuicTime::Delta transfer_time = bandwidth_.TransferTime(packet->size);
- next_write_at_ = clock_->Now() + transfer_time;
-
- packets_in_transit_.emplace_back(
- std::move(packet),
- // Ensure that packets are delivered in order.
- std::max(
- next_write_at_ + propagation_delay_ + GetRandomDelay(transfer_time),
- packets_in_transit_.empty()
- ? QuicTime::Zero()
- : packets_in_transit_.back().dequeue_time));
- ScheduleNextPacketDeparture();
-}
-
-QuicTime::Delta OneWayLink::TimeUntilAvailable() {
- const QuicTime now = clock_->Now();
- if (next_write_at_ <= now) {
- return QuicTime::Delta::Zero();
- }
-
- return next_write_at_ - now;
-}
-
-void OneWayLink::Act() {
- QUICHE_DCHECK(!packets_in_transit_.empty());
- QUICHE_DCHECK(packets_in_transit_.front().dequeue_time >= clock_->Now());
-
- sink_->AcceptPacket(std::move(packets_in_transit_.front().packet));
- packets_in_transit_.pop_front();
-
- ScheduleNextPacketDeparture();
-}
-
-void OneWayLink::ScheduleNextPacketDeparture() {
- if (packets_in_transit_.empty()) {
- return;
- }
-
- Schedule(packets_in_transit_.front().dequeue_time);
-}
-
-QuicTime::Delta OneWayLink::GetRandomDelay(QuicTime::Delta transfer_time) {
- if (!simulator_->enable_random_delays()) {
- return QuicTime::Delta::Zero();
- }
-
- QuicTime::Delta delta = QuicTime::Delta::FromMicroseconds(
- simulator_->GetRandomGenerator()->RandUint64() % (kMaxRandomDelayUs + 1));
- // Have an upper bound on the delay to ensure packets do not go out of order.
- delta = std::min(delta, transfer_time * 0.5);
- return delta;
-}
-
-SymmetricLink::SymmetricLink(Simulator* simulator,
- std::string name,
- UnconstrainedPortInterface* sink_a,
- UnconstrainedPortInterface* sink_b,
- QuicBandwidth bandwidth,
- QuicTime::Delta propagation_delay)
- : a_to_b_link_(simulator,
- absl::StrCat(name, " (A-to-B)"),
- sink_b,
- bandwidth,
- propagation_delay),
- b_to_a_link_(simulator,
- absl::StrCat(name, " (B-to-A)"),
- sink_a,
- bandwidth,
- propagation_delay) {}
-
-SymmetricLink::SymmetricLink(Endpoint* endpoint_a,
- Endpoint* endpoint_b,
- QuicBandwidth bandwidth,
- QuicTime::Delta propagation_delay)
- : SymmetricLink(endpoint_a->simulator(),
- absl::StrFormat("Link [%s]<->[%s]",
- endpoint_a->name(),
- endpoint_b->name()),
- endpoint_a->GetRxPort(),
- endpoint_b->GetRxPort(),
- bandwidth,
- propagation_delay) {
- endpoint_a->SetTxPort(&a_to_b_link_);
- endpoint_b->SetTxPort(&b_to_a_link_);
-}
-
-} // namespace simulator
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/simulator/link.h b/chromium/net/third_party/quiche/src/quic/test_tools/simulator/link.h
deleted file mode 100644
index 5d723859e0c..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/simulator/link.h
+++ /dev/null
@@ -1,103 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_SIMULATOR_LINK_H_
-#define QUICHE_QUIC_TEST_TOOLS_SIMULATOR_LINK_H_
-
-#include <utility>
-
-#include "quic/core/crypto/quic_random.h"
-#include "quic/core/quic_bandwidth.h"
-#include "quic/test_tools/simulator/actor.h"
-#include "quic/test_tools/simulator/port.h"
-#include "common/quiche_circular_deque.h"
-
-namespace quic {
-namespace simulator {
-
-// A reliable simplex link between two endpoints with constrained bandwidth. A
-// few microseconds of random delay are added for every packet to avoid
-// synchronization issues.
-class OneWayLink : public Actor, public ConstrainedPortInterface {
- public:
- OneWayLink(Simulator* simulator,
- std::string name,
- UnconstrainedPortInterface* sink,
- QuicBandwidth bandwidth,
- QuicTime::Delta propagation_delay);
- OneWayLink(const OneWayLink&) = delete;
- OneWayLink& operator=(const OneWayLink&) = delete;
- ~OneWayLink() override;
-
- void AcceptPacket(std::unique_ptr<Packet> packet) override;
- QuicTime::Delta TimeUntilAvailable() override;
- void Act() override;
-
- inline QuicBandwidth bandwidth() const { return bandwidth_; }
- inline void set_bandwidth(QuicBandwidth new_bandwidth) {
- bandwidth_ = new_bandwidth;
- }
-
- protected:
- // Get the value of a random delay imposed on each packet. By default, this
- // is a short random delay in order to avoid artifical synchronization
- // artifacts during the simulation. Subclasses may override this behavior
- // (for example, to provide a random component of delay).
- virtual QuicTime::Delta GetRandomDelay(QuicTime::Delta transfer_time);
-
- private:
- struct QueuedPacket {
- std::unique_ptr<Packet> packet;
- QuicTime dequeue_time;
-
- QueuedPacket(std::unique_ptr<Packet> packet, QuicTime dequeue_time);
- QueuedPacket(QueuedPacket&& other);
- ~QueuedPacket();
- };
-
- // Schedule the next packet to be egressed out of the link if there are
- // packets on the link.
- void ScheduleNextPacketDeparture();
-
- UnconstrainedPortInterface* sink_;
- quiche::QuicheCircularDeque<QueuedPacket> packets_in_transit_;
-
- QuicBandwidth bandwidth_;
- const QuicTime::Delta propagation_delay_;
-
- QuicTime next_write_at_;
-};
-
-// A full-duplex link between two endpoints, functionally equivalent to two
-// OneWayLink objects tied together.
-class SymmetricLink {
- public:
- SymmetricLink(Simulator* simulator,
- std::string name,
- UnconstrainedPortInterface* sink_a,
- UnconstrainedPortInterface* sink_b,
- QuicBandwidth bandwidth,
- QuicTime::Delta propagation_delay);
- SymmetricLink(Endpoint* endpoint_a,
- Endpoint* endpoint_b,
- QuicBandwidth bandwidth,
- QuicTime::Delta propagation_delay);
- SymmetricLink(const SymmetricLink&) = delete;
- SymmetricLink& operator=(const SymmetricLink&) = delete;
-
- inline QuicBandwidth bandwidth() { return a_to_b_link_.bandwidth(); }
- inline void set_bandwidth(QuicBandwidth new_bandwidth) {
- a_to_b_link_.set_bandwidth(new_bandwidth);
- b_to_a_link_.set_bandwidth(new_bandwidth);
- }
-
- private:
- OneWayLink a_to_b_link_;
- OneWayLink b_to_a_link_;
-};
-
-} // namespace simulator
-} // namespace quic
-
-#endif // QUICHE_QUIC_TEST_TOOLS_SIMULATOR_LINK_H_
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/simulator/packet_filter.cc b/chromium/net/third_party/quiche/src/quic/test_tools/simulator/packet_filter.cc
deleted file mode 100644
index 0cbb1f0d8a3..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/simulator/packet_filter.cc
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/simulator/packet_filter.h"
-
-namespace quic {
-namespace simulator {
-
-PacketFilter::PacketFilter(Simulator* simulator,
- std::string name,
- Endpoint* input)
- : Endpoint(simulator, name), input_(input) {
- input_->SetTxPort(this);
-}
-
-PacketFilter::~PacketFilter() {}
-
-void PacketFilter::AcceptPacket(std::unique_ptr<Packet> packet) {
- if (FilterPacket(*packet)) {
- output_tx_port_->AcceptPacket(std::move(packet));
- }
-}
-
-QuicTime::Delta PacketFilter::TimeUntilAvailable() {
- return output_tx_port_->TimeUntilAvailable();
-}
-
-void PacketFilter::Act() {}
-
-UnconstrainedPortInterface* PacketFilter::GetRxPort() {
- return input_->GetRxPort();
-}
-
-void PacketFilter::SetTxPort(ConstrainedPortInterface* port) {
- output_tx_port_ = port;
-}
-
-} // namespace simulator
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/simulator/packet_filter.h b/chromium/net/third_party/quiche/src/quic/test_tools/simulator/packet_filter.h
deleted file mode 100644
index d7443533f3c..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/simulator/packet_filter.h
+++ /dev/null
@@ -1,75 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_SIMULATOR_PACKET_FILTER_H_
-#define QUICHE_QUIC_TEST_TOOLS_SIMULATOR_PACKET_FILTER_H_
-
-#include "quic/test_tools/simulator/port.h"
-
-namespace quic {
-namespace simulator {
-
-// Packet filter allows subclasses to filter out the packets that enter the
-// input port and exit the output port. Packets in the other direction are
-// always passed through.
-//
-// The filter wraps around the input endpoint, and exposes the resulting
-// filtered endpoint via the output() method. For example, if initially there
-// are two endpoints, A and B, connected via a symmetric link:
-//
-// QuicEndpoint endpoint_a;
-// QuicEndpoint endpoint_b;
-//
-// [...]
-//
-// SymmetricLink a_b_link(&endpoint_a, &endpoint_b, ...);
-//
-// and the goal is to filter the traffic from A to B, then the new invocation
-// would be as follows:
-//
-// PacketFilter filter(&simulator, "A-to-B packet filter", endpoint_a);
-// SymmetricLink a_b_link(&filter, &endpoint_b, ...);
-//
-// Note that the filter drops the packet instanteneously, without it ever
-// reaching the output wire. This means that in a direct endpoint-to-endpoint
-// scenario, whenever the packet is dropped, the link would become immediately
-// available for the next packet.
-class PacketFilter : public Endpoint, public ConstrainedPortInterface {
- public:
- // Initialize the filter by wrapping around |input|. Does not take the
- // ownership of |input|.
- PacketFilter(Simulator* simulator, std::string name, Endpoint* input);
- PacketFilter(const PacketFilter&) = delete;
- PacketFilter& operator=(const PacketFilter&) = delete;
- ~PacketFilter() override;
-
- // Implementation of ConstrainedPortInterface.
- void AcceptPacket(std::unique_ptr<Packet> packet) override;
- QuicTime::Delta TimeUntilAvailable() override;
-
- // Implementation of Endpoint interface methods.
- UnconstrainedPortInterface* GetRxPort() override;
- void SetTxPort(ConstrainedPortInterface* port) override;
-
- // Implementation of Actor interface methods.
- void Act() override;
-
- protected:
- // Returns true if the packet should be passed through, and false if it should
- // be dropped. The function is called once per packet, in the order that the
- // packets arrive, so it is safe for the function to alter the internal state
- // of the filter.
- virtual bool FilterPacket(const Packet& packet) = 0;
-
- private:
- // The port onto which the filtered packets are egressed.
- ConstrainedPortInterface* output_tx_port_;
-
- // The original network endpoint wrapped by the class.
- Endpoint* input_;
-};
-
-} // namespace simulator
-} // namespace quic
-#endif // QUICHE_QUIC_TEST_TOOLS_SIMULATOR_PACKET_FILTER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/simulator/port.cc b/chromium/net/third_party/quiche/src/quic/test_tools/simulator/port.cc
deleted file mode 100644
index 7aa4df325fb..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/simulator/port.cc
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/simulator/port.h"
-
-namespace quic {
-namespace simulator {
-
-Packet::Packet()
- : source(), destination(), tx_timestamp(QuicTime::Zero()), size(0) {}
-
-Packet::~Packet() {}
-
-Packet::Packet(const Packet& packet) = default;
-
-Endpoint::Endpoint(Simulator* simulator, std::string name)
- : Actor(simulator, name) {}
-
-} // namespace simulator
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/simulator/port.h b/chromium/net/third_party/quiche/src/quic/test_tools/simulator/port.h
deleted file mode 100644
index 772b2d5745b..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/simulator/port.h
+++ /dev/null
@@ -1,66 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_SIMULATOR_PORT_H_
-#define QUICHE_QUIC_TEST_TOOLS_SIMULATOR_PORT_H_
-
-#include <string>
-#include <utility>
-
-#include "quic/core/quic_packets.h"
-#include "quic/test_tools/simulator/actor.h"
-
-namespace quic {
-namespace simulator {
-
-struct Packet {
- Packet();
- ~Packet();
- Packet(const Packet& packet);
-
- std::string source;
- std::string destination;
- QuicTime tx_timestamp;
-
- std::string contents;
- QuicByteCount size;
-};
-
-// An interface for anything that accepts packets at arbitrary rate.
-class UnconstrainedPortInterface {
- public:
- virtual ~UnconstrainedPortInterface() {}
- virtual void AcceptPacket(std::unique_ptr<Packet> packet) = 0;
-};
-
-// An interface for any device that accepts packets at a specific rate.
-// Typically one would use a Queue object in order to write into a constrained
-// port.
-class ConstrainedPortInterface {
- public:
- virtual ~ConstrainedPortInterface() {}
-
- // Accept a packet for a port. TimeUntilAvailable() must be zero before this
- // method is called.
- virtual void AcceptPacket(std::unique_ptr<Packet> packet) = 0;
-
- // Time until write for the next port is available. Cannot be infinite.
- virtual QuicTime::Delta TimeUntilAvailable() = 0;
-};
-
-// A convenience class for any network endpoints, i.e. the objects which can
-// both accept and send packets.
-class Endpoint : public Actor {
- public:
- virtual UnconstrainedPortInterface* GetRxPort() = 0;
- virtual void SetTxPort(ConstrainedPortInterface* port) = 0;
-
- protected:
- Endpoint(Simulator* simulator, std::string name);
-};
-
-} // namespace simulator
-} // namespace quic
-
-#endif // QUICHE_QUIC_TEST_TOOLS_SIMULATOR_PORT_H_
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/simulator/queue.cc b/chromium/net/third_party/quiche/src/quic/test_tools/simulator/queue.cc
deleted file mode 100644
index c7e23cd0711..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/simulator/queue.cc
+++ /dev/null
@@ -1,129 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/simulator/queue.h"
-
-#include "quic/platform/api/quic_logging.h"
-#include "quic/test_tools/simulator/simulator.h"
-
-namespace quic {
-namespace simulator {
-
-Queue::ListenerInterface::~ListenerInterface() {}
-
-Queue::Queue(Simulator* simulator, std::string name, QuicByteCount capacity)
- : Actor(simulator, name),
- capacity_(capacity),
- bytes_queued_(0),
- aggregation_threshold_(0),
- aggregation_timeout_(QuicTime::Delta::Infinite()),
- current_bundle_(0),
- current_bundle_bytes_(0),
- tx_port_(nullptr),
- listener_(nullptr) {
- aggregation_timeout_alarm_.reset(simulator_->GetAlarmFactory()->CreateAlarm(
- new AggregationAlarmDelegate(this)));
-}
-
-Queue::~Queue() { aggregation_timeout_alarm_->PermanentCancel(); }
-
-void Queue::set_tx_port(ConstrainedPortInterface* port) {
- tx_port_ = port;
-}
-
-void Queue::AcceptPacket(std::unique_ptr<Packet> packet) {
- if (packet->size + bytes_queued_ > capacity_) {
- QUIC_DVLOG(1) << "Queue [" << name() << "] has received a packet from ["
- << packet->source << "] to [" << packet->destination
- << "] which is over capacity. Dropping it.";
- QUIC_DVLOG(1) << "Queue size: " << bytes_queued_ << " out of " << capacity_
- << ". Packet size: " << packet->size;
- return;
- }
-
- bytes_queued_ += packet->size;
- queue_.emplace_back(std::move(packet), current_bundle_);
-
- if (IsAggregationEnabled()) {
- current_bundle_bytes_ += queue_.front().packet->size;
- if (!aggregation_timeout_alarm_->IsSet()) {
- aggregation_timeout_alarm_->Set(clock_->Now() + aggregation_timeout_);
- }
- if (current_bundle_bytes_ >= aggregation_threshold_) {
- NextBundle();
- }
- }
-
- ScheduleNextPacketDequeue();
-}
-
-void Queue::Act() {
- QUICHE_DCHECK(!queue_.empty());
- if (tx_port_->TimeUntilAvailable().IsZero()) {
- QUICHE_DCHECK(bytes_queued_ >= queue_.front().packet->size);
- bytes_queued_ -= queue_.front().packet->size;
-
- tx_port_->AcceptPacket(std::move(queue_.front().packet));
- queue_.pop_front();
- if (listener_ != nullptr) {
- listener_->OnPacketDequeued();
- }
- }
-
- ScheduleNextPacketDequeue();
-}
-
-void Queue::EnableAggregation(QuicByteCount aggregation_threshold,
- QuicTime::Delta aggregation_timeout) {
- QUICHE_DCHECK_EQ(bytes_queued_, 0u);
- QUICHE_DCHECK_GT(aggregation_threshold, 0u);
- QUICHE_DCHECK(!aggregation_timeout.IsZero());
- QUICHE_DCHECK(!aggregation_timeout.IsInfinite());
-
- aggregation_threshold_ = aggregation_threshold;
- aggregation_timeout_ = aggregation_timeout;
-}
-
-Queue::AggregationAlarmDelegate::AggregationAlarmDelegate(Queue* queue)
- : queue_(queue) {}
-
-void Queue::AggregationAlarmDelegate::OnAlarm() {
- queue_->NextBundle();
- queue_->ScheduleNextPacketDequeue();
-}
-
-Queue::EnqueuedPacket::EnqueuedPacket(std::unique_ptr<Packet> packet,
- AggregationBundleNumber bundle)
- : packet(std::move(packet)), bundle(bundle) {}
-
-Queue::EnqueuedPacket::EnqueuedPacket(EnqueuedPacket&& other) = default;
-
-Queue::EnqueuedPacket::~EnqueuedPacket() = default;
-
-void Queue::NextBundle() {
- current_bundle_++;
- current_bundle_bytes_ = 0;
- aggregation_timeout_alarm_->Cancel();
-}
-
-void Queue::ScheduleNextPacketDequeue() {
- if (queue_.empty()) {
- QUICHE_DCHECK_EQ(bytes_queued_, 0u);
- return;
- }
-
- if (IsAggregationEnabled() && queue_.front().bundle == current_bundle_) {
- return;
- }
-
- QuicTime::Delta time_until_available = QuicTime::Delta::Zero();
- if (tx_port_) {
- time_until_available = tx_port_->TimeUntilAvailable();
- }
-
- Schedule(clock_->Now() + time_until_available);
-}
-
-} // namespace simulator
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/simulator/queue.h b/chromium/net/third_party/quiche/src/quic/test_tools/simulator/queue.h
deleted file mode 100644
index dd810e7e2f5..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/simulator/queue.h
+++ /dev/null
@@ -1,121 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_SIMULATOR_QUEUE_H_
-#define QUICHE_QUIC_TEST_TOOLS_SIMULATOR_QUEUE_H_
-
-#include "quic/core/quic_alarm.h"
-#include "quic/test_tools/simulator/link.h"
-#include "common/quiche_circular_deque.h"
-
-namespace quic {
-namespace simulator {
-
-// A finitely sized queue which egresses packets onto a constrained link. The
-// capacity of the queue is measured in bytes as opposed to packets.
-class Queue : public Actor, public UnconstrainedPortInterface {
- public:
- class ListenerInterface {
- public:
- virtual ~ListenerInterface();
-
- // Called whenever a packet is removed from the queue.
- virtual void OnPacketDequeued() = 0;
- };
-
- Queue(Simulator* simulator, std::string name, QuicByteCount capacity);
- Queue(const Queue&) = delete;
- Queue& operator=(const Queue&) = delete;
- ~Queue() override;
-
- void set_tx_port(ConstrainedPortInterface* port);
-
- void AcceptPacket(std::unique_ptr<Packet> packet) override;
-
- void Act() override;
-
- inline QuicByteCount capacity() const { return capacity_; }
- inline QuicByteCount bytes_queued() const { return bytes_queued_; }
- inline QuicPacketCount packets_queued() const { return queue_.size(); }
-
- inline void set_listener_interface(ListenerInterface* listener) {
- listener_ = listener;
- }
-
- // Enables packet aggregation on the queue. Packet aggregation makes the
- // queue bundle packets up until they reach certain size. When the
- // aggregation is enabled, the packets are not dequeued until the total size
- // of packets in the queue reaches |aggregation_threshold|. The packets are
- // automatically flushed from the queue if the oldest packet has been in it
- // for |aggregation_timeout|.
- //
- // This method may only be called when the queue is empty. Once enabled,
- // aggregation cannot be disabled.
- void EnableAggregation(QuicByteCount aggregation_threshold,
- QuicTime::Delta aggregation_timeout);
-
- private:
- using AggregationBundleNumber = uint64_t;
-
- // In order to implement packet aggregation, each packet is tagged with a
- // bundle number. The queue keeps a bundle counter, and whenever a bundle is
- // ready, it increments the number of the current bundle. Only the packets
- // outside of the current bundle are allowed to leave the queue.
- struct EnqueuedPacket {
- EnqueuedPacket(std::unique_ptr<Packet> packet,
- AggregationBundleNumber bundle);
- EnqueuedPacket(EnqueuedPacket&& other);
- ~EnqueuedPacket();
-
- std::unique_ptr<Packet> packet;
- AggregationBundleNumber bundle;
- };
-
- // Alarm handler for aggregation timeout.
- class AggregationAlarmDelegate : public QuicAlarm::DelegateWithoutContext {
- public:
- explicit AggregationAlarmDelegate(Queue* queue);
-
- void OnAlarm() override;
-
- private:
- Queue* queue_;
- };
-
- inline bool IsAggregationEnabled() const {
- return aggregation_threshold_ > 0;
- }
-
- // Increment the bundle counter and reset the bundle state. This causes all
- // packets currently in the bundle to be flushed onto the link.
- void NextBundle();
-
- void ScheduleNextPacketDequeue();
-
- const QuicByteCount capacity_;
- QuicByteCount bytes_queued_;
-
- QuicByteCount aggregation_threshold_;
- QuicTime::Delta aggregation_timeout_;
- // The number of the current aggregation bundle. Monotonically increasing.
- // All packets in the previous bundles are allowed to leave the queue, and
- // none of the packets in the current one are.
- AggregationBundleNumber current_bundle_;
- // Size of the current bundle. Whenever it exceeds |aggregation_threshold_|,
- // the next bundle is created.
- QuicByteCount current_bundle_bytes_;
- // Alarm responsible for flushing the current bundle upon timeout. Set when
- // the first packet in the bundle is enqueued.
- std::unique_ptr<QuicAlarm> aggregation_timeout_alarm_;
-
- ConstrainedPortInterface* tx_port_;
- quiche::QuicheCircularDeque<EnqueuedPacket> queue_;
-
- ListenerInterface* listener_;
-};
-
-} // namespace simulator
-} // namespace quic
-
-#endif // QUICHE_QUIC_TEST_TOOLS_SIMULATOR_QUEUE_H_
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/simulator/quic_endpoint.cc b/chromium/net/third_party/quiche/src/quic/test_tools/simulator/quic_endpoint.cc
deleted file mode 100644
index fd5c5b7a4a4..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/simulator/quic_endpoint.cc
+++ /dev/null
@@ -1,258 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/simulator/quic_endpoint.h"
-
-#include <memory>
-#include <utility>
-
-#include "quic/core/crypto/crypto_handshake_message.h"
-#include "quic/core/crypto/crypto_protocol.h"
-#include "quic/core/quic_data_writer.h"
-#include "quic/platform/api/quic_test_output.h"
-#include "quic/test_tools/quic_config_peer.h"
-#include "quic/test_tools/quic_connection_peer.h"
-#include "quic/test_tools/quic_test_utils.h"
-#include "quic/test_tools/simulator/simulator.h"
-
-namespace quic {
-namespace simulator {
-
-const QuicStreamId kDataStream = 3;
-const QuicByteCount kWriteChunkSize = 128 * 1024;
-const char kStreamDataContents = 'Q';
-
-QuicEndpoint::QuicEndpoint(Simulator* simulator,
- std::string name,
- std::string peer_name,
- Perspective perspective,
- QuicConnectionId connection_id)
- : QuicEndpointBase(simulator, name, peer_name),
- bytes_to_transfer_(0),
- bytes_transferred_(0),
- wrong_data_received_(false),
- notifier_(nullptr) {
- connection_ = std::make_unique<QuicConnection>(
- connection_id, GetAddressFromName(name), GetAddressFromName(peer_name),
- simulator, simulator->GetAlarmFactory(), &writer_, false, perspective,
- ParsedVersionOfIndex(CurrentSupportedVersions(), 0));
- connection_->set_visitor(this);
- connection_->SetEncrypter(ENCRYPTION_FORWARD_SECURE,
- std::make_unique<NullEncrypter>(perspective));
- connection_->SetEncrypter(ENCRYPTION_INITIAL, nullptr);
- if (connection_->version().KnowsWhichDecrypterToUse()) {
- connection_->InstallDecrypter(ENCRYPTION_FORWARD_SECURE,
- std::make_unique<NullDecrypter>(perspective));
- connection_->RemoveDecrypter(ENCRYPTION_INITIAL);
- } else {
- connection_->SetDecrypter(ENCRYPTION_FORWARD_SECURE,
- std::make_unique<NullDecrypter>(perspective));
- }
- connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
- connection_->OnHandshakeComplete();
- if (perspective == Perspective::IS_SERVER) {
- // Skip version negotiation.
- test::QuicConnectionPeer::SetNegotiatedVersion(connection_.get());
- }
- test::QuicConnectionPeer::SetAddressValidated(connection_.get());
- connection_->SetDataProducer(&producer_);
- connection_->SetSessionNotifier(this);
- notifier_ = std::make_unique<test::SimpleSessionNotifier>(connection_.get());
-
- // Configure the connection as if it received a handshake. This is important
- // primarily because
- // - this enables pacing, and
- // - this sets the non-handshake timeouts.
- std::string error;
- CryptoHandshakeMessage peer_hello;
- peer_hello.SetValue(kICSL,
- static_cast<uint32_t>(kMaximumIdleTimeoutSecs - 1));
- peer_hello.SetValue(kMIBS,
- static_cast<uint32_t>(kDefaultMaxStreamsPerConnection));
- QuicConfig config;
- QuicErrorCode error_code = config.ProcessPeerHello(
- peer_hello, perspective == Perspective::IS_CLIENT ? SERVER : CLIENT,
- &error);
- QUICHE_DCHECK_EQ(error_code, QUIC_NO_ERROR)
- << "Configuration failed: " << error;
- if (connection_->version().UsesTls()) {
- if (connection_->perspective() == Perspective::IS_CLIENT) {
- test::QuicConfigPeer::SetReceivedOriginalConnectionId(
- &config, connection_->connection_id());
- test::QuicConfigPeer::SetReceivedInitialSourceConnectionId(
- &config, connection_->connection_id());
- } else {
- test::QuicConfigPeer::SetReceivedInitialSourceConnectionId(
- &config, connection_->client_connection_id());
- }
- }
- connection_->SetFromConfig(config);
- connection_->DisableMtuDiscovery();
-}
-
-QuicByteCount QuicEndpoint::bytes_received() const {
- QuicByteCount total = 0;
- for (auto& interval : offsets_received_) {
- total += interval.max() - interval.min();
- }
- return total;
-}
-
-QuicByteCount QuicEndpoint::bytes_to_transfer() const {
- if (notifier_ != nullptr) {
- return notifier_->StreamBytesToSend();
- }
- return bytes_to_transfer_;
-}
-
-QuicByteCount QuicEndpoint::bytes_transferred() const {
- if (notifier_ != nullptr) {
- return notifier_->StreamBytesSent();
- }
- return bytes_transferred_;
-}
-
-void QuicEndpoint::AddBytesToTransfer(QuicByteCount bytes) {
- if (notifier_ != nullptr) {
- if (notifier_->HasBufferedStreamData()) {
- Schedule(clock_->Now());
- }
- notifier_->WriteOrBufferData(kDataStream, bytes, NO_FIN);
- return;
- }
-
- if (bytes_to_transfer_ > 0) {
- Schedule(clock_->Now());
- }
-
- bytes_to_transfer_ += bytes;
- WriteStreamData();
-}
-
-void QuicEndpoint::OnStreamFrame(const QuicStreamFrame& frame) {
- // Verify that the data received always matches the expected.
- QUICHE_DCHECK(frame.stream_id == kDataStream);
- for (size_t i = 0; i < frame.data_length; i++) {
- if (frame.data_buffer[i] != kStreamDataContents) {
- wrong_data_received_ = true;
- }
- }
- offsets_received_.Add(frame.offset, frame.offset + frame.data_length);
- // Sanity check against very pathological connections.
- QUICHE_DCHECK_LE(offsets_received_.Size(), 1000u);
-}
-
-void QuicEndpoint::OnCryptoFrame(const QuicCryptoFrame& /*frame*/) {}
-
-void QuicEndpoint::OnCanWrite() {
- if (notifier_ != nullptr) {
- notifier_->OnCanWrite();
- return;
- }
- 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();
- }
- return bytes_to_transfer_ != 0;
-}
-bool QuicEndpoint::ShouldKeepConnectionAlive() const {
- return true;
-}
-
-bool QuicEndpoint::AllowSelfAddressChange() const {
- return false;
-}
-
-bool QuicEndpoint::OnFrameAcked(const QuicFrame& frame,
- QuicTime::Delta ack_delay_time,
- QuicTime receive_timestamp) {
- if (notifier_ != nullptr) {
- return notifier_->OnFrameAcked(frame, ack_delay_time, receive_timestamp);
- }
- return false;
-}
-
-void QuicEndpoint::OnFrameLost(const QuicFrame& frame) {
- QUICHE_DCHECK(notifier_);
- notifier_->OnFrameLost(frame);
-}
-
-void QuicEndpoint::RetransmitFrames(const QuicFrames& frames,
- TransmissionType type) {
- QUICHE_DCHECK(notifier_);
- notifier_->RetransmitFrames(frames, type);
-}
-
-bool QuicEndpoint::IsFrameOutstanding(const QuicFrame& frame) const {
- QUICHE_DCHECK(notifier_);
- return notifier_->IsFrameOutstanding(frame);
-}
-
-bool QuicEndpoint::HasUnackedCryptoData() const {
- return false;
-}
-
-bool QuicEndpoint::HasUnackedStreamData() const {
- if (notifier_ != nullptr) {
- return notifier_->HasUnackedStreamData();
- }
- return false;
-}
-
-HandshakeState QuicEndpoint::GetHandshakeState() const {
- return HANDSHAKE_COMPLETE;
-}
-
-WriteStreamDataResult QuicEndpoint::DataProducer::WriteStreamData(
- QuicStreamId /*id*/,
- QuicStreamOffset /*offset*/,
- QuicByteCount data_length,
- QuicDataWriter* writer) {
- writer->WriteRepeatedByte(kStreamDataContents, data_length);
- return WRITE_SUCCESS;
-}
-
-bool QuicEndpoint::DataProducer::WriteCryptoData(EncryptionLevel /*level*/,
- QuicStreamOffset /*offset*/,
- QuicByteCount /*data_length*/,
- QuicDataWriter* /*writer*/) {
- QUIC_BUG(quic_bug_10157_1)
- << "QuicEndpoint::DataProducer::WriteCryptoData is unimplemented";
- return false;
-}
-
-void QuicEndpoint::WriteStreamData() {
- // Instantiate a flusher which would normally be here due to QuicSession.
- QuicConnection::ScopedPacketFlusher flusher(connection_.get());
-
- while (bytes_to_transfer_ > 0) {
- // Transfer data in chunks of size at most |kWriteChunkSize|.
- const size_t transmission_size =
- std::min(kWriteChunkSize, bytes_to_transfer_);
-
- QuicConsumedData consumed_data = connection_->SendStreamData(
- kDataStream, transmission_size, bytes_transferred_, NO_FIN);
-
- QUICHE_DCHECK(consumed_data.bytes_consumed <= transmission_size);
- bytes_transferred_ += consumed_data.bytes_consumed;
- bytes_to_transfer_ -= consumed_data.bytes_consumed;
- if (consumed_data.bytes_consumed != transmission_size) {
- return;
- }
- }
-}
-
-} // namespace simulator
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/simulator/quic_endpoint.h b/chromium/net/third_party/quiche/src/quic/test_tools/simulator/quic_endpoint.h
deleted file mode 100644
index 3e445dc941d..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/simulator/quic_endpoint.h
+++ /dev/null
@@ -1,179 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_SIMULATOR_QUIC_ENDPOINT_H_
-#define QUICHE_QUIC_TEST_TOOLS_SIMULATOR_QUIC_ENDPOINT_H_
-
-#include "absl/strings/string_view.h"
-#include "quic/core/crypto/null_decrypter.h"
-#include "quic/core/crypto/null_encrypter.h"
-#include "quic/core/quic_connection.h"
-#include "quic/core/quic_default_packet_writer.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_stream_frame_data_producer.h"
-#include "quic/core/quic_trace_visitor.h"
-#include "quic/platform/api/quic_containers.h"
-#include "quic/test_tools/simple_session_notifier.h"
-#include "quic/test_tools/simulator/link.h"
-#include "quic/test_tools/simulator/queue.h"
-#include "quic/test_tools/simulator/quic_endpoint_base.h"
-
-namespace quic {
-namespace simulator {
-
-// A QUIC connection endpoint. Wraps around QuicConnection. In order to
-// initiate a transfer, the caller has to call AddBytesToTransfer(). The data
-// transferred is always the same and is always transferred on a single stream.
-// The endpoint receives all packets addressed to it, and verifies that the data
-// received is what it's supposed to be.
-class QuicEndpoint : public QuicEndpointBase,
- public QuicConnectionVisitorInterface,
- public SessionNotifierInterface {
- public:
- QuicEndpoint(Simulator* simulator,
- std::string name,
- std::string peer_name,
- Perspective perspective,
- QuicConnectionId connection_id);
-
- QuicByteCount bytes_to_transfer() const;
- QuicByteCount bytes_transferred() const;
- QuicByteCount bytes_received() const;
- inline bool wrong_data_received() const { return wrong_data_received_; }
-
- // Send |bytes| bytes. Initiates the transfer if one is not already in
- // progress.
- void AddBytesToTransfer(QuicByteCount bytes);
-
- // Begin QuicConnectionVisitorInterface implementation.
- void OnStreamFrame(const QuicStreamFrame& frame) override;
- void OnCryptoFrame(const QuicCryptoFrame& frame) override;
- void OnCanWrite() override;
- bool SendProbingData() override;
- bool ValidateStatelessReset(
- const quic::QuicSocketAddress& /*self_address*/,
- const quic::QuicSocketAddress& /*peer_address*/) override {
- return true;
- }
- bool WillingAndAbleToWrite() const override;
- bool ShouldKeepConnectionAlive() const override;
-
- std::string GetStreamsInfoForLogging() const override { return ""; }
- void OnWindowUpdateFrame(const QuicWindowUpdateFrame& /*frame*/) override {}
- void OnBlockedFrame(const QuicBlockedFrame& /*frame*/) override {}
- void OnRstStream(const QuicRstStreamFrame& /*frame*/) override {}
- void OnGoAway(const QuicGoAwayFrame& /*frame*/) override {}
- void OnMessageReceived(absl::string_view /*message*/) override {}
- void OnHandshakeDoneReceived() override {}
- void OnNewTokenReceived(absl::string_view /*token*/) override {}
- void OnConnectionClosed(const QuicConnectionCloseFrame& /*frame*/,
- ConnectionCloseSource /*source*/) override {}
- void OnWriteBlocked() override {}
- void OnSuccessfulVersionNegotiation(
- const ParsedQuicVersion& /*version*/) override {}
- void OnPacketReceived(const QuicSocketAddress& /*self_address*/,
- const QuicSocketAddress& /*peer_address*/,
- bool /*is_connectivity_probe*/) override {}
- void OnCongestionWindowChange(QuicTime /*now*/) override {}
- void OnConnectionMigration(AddressChangeType /*type*/) override {}
- void OnPathDegrading() override {}
- void OnForwardProgressMadeAfterPathDegrading() override {}
- void OnAckNeedsRetransmittableFrame() override {}
- void SendAckFrequency(const QuicAckFrequencyFrame& /*frame*/) override {}
- void SendNewConnectionId(const QuicNewConnectionIdFrame& /*frame*/) override {
- }
- void SendRetireConnectionId(uint64_t /*sequence_number*/) override {}
- void OnServerConnectionIdIssued(
- const QuicConnectionId& /*server_connection_id*/) override {}
- void OnServerConnectionIdRetired(
- const QuicConnectionId& /*server_connection_id*/) override {}
- bool AllowSelfAddressChange() const override;
- HandshakeState GetHandshakeState() const override;
- bool OnMaxStreamsFrame(const QuicMaxStreamsFrame& /*frame*/) override {
- return true;
- }
- bool OnStreamsBlockedFrame(
- const QuicStreamsBlockedFrame& /*frame*/) override {
- return true;
- }
- void OnStopSendingFrame(const QuicStopSendingFrame& /*frame*/) override {}
- void OnPacketDecrypted(EncryptionLevel /*level*/) override {}
- void OnOneRttPacketAcknowledged() override {}
- void OnHandshakePacketSent() override {}
- void OnKeyUpdate(KeyUpdateReason /*reason*/) override {}
- std::unique_ptr<QuicDecrypter> AdvanceKeysAndCreateCurrentOneRttDecrypter()
- override {
- return nullptr;
- }
- std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() override {
- return nullptr;
- }
- void BeforeConnectionCloseSent() override {}
- bool ValidateToken(absl::string_view /*token*/) override { return true; }
- bool MaybeSendAddressToken() override { return false; }
- bool IsKnownServerAddress(
- const QuicSocketAddress& /*address*/) const override {
- return false;
- }
-
- // End QuicConnectionVisitorInterface implementation.
-
- // Begin SessionNotifierInterface methods:
- bool OnFrameAcked(const QuicFrame& frame,
- QuicTime::Delta ack_delay_time,
- QuicTime receive_timestamp) override;
- void OnStreamFrameRetransmitted(const QuicStreamFrame& /*frame*/) override {}
- void OnFrameLost(const QuicFrame& frame) override;
- void RetransmitFrames(const QuicFrames& frames,
- TransmissionType type) override;
- bool IsFrameOutstanding(const QuicFrame& frame) const override;
- bool HasUnackedCryptoData() const override;
- bool HasUnackedStreamData() const override;
- // End SessionNotifierInterface implementation.
-
- private:
- // The producer outputs the repetition of the same byte. That sequence is
- // verified by the receiver.
- class DataProducer : public QuicStreamFrameDataProducer {
- public:
- WriteStreamDataResult WriteStreamData(QuicStreamId id,
- QuicStreamOffset offset,
- QuicByteCount data_length,
- QuicDataWriter* writer) override;
- bool WriteCryptoData(EncryptionLevel level,
- QuicStreamOffset offset,
- QuicByteCount data_length,
- QuicDataWriter* writer) override;
- };
-
- std::unique_ptr<QuicConnection> CreateConnection(
- Simulator* simulator,
- std::string name,
- std::string peer_name,
- Perspective perspective,
- QuicConnectionId connection_id);
-
- // Write stream data until |bytes_to_transfer_| is zero or the connection is
- // write-blocked.
- void WriteStreamData();
-
- DataProducer producer_;
-
- QuicByteCount bytes_to_transfer_;
- QuicByteCount bytes_transferred_;
-
- // Set to true if the endpoint receives stream data different from what it
- // expects.
- bool wrong_data_received_;
-
- // Record of received offsets in the data stream.
- QuicIntervalSet<QuicStreamOffset> offsets_received_;
-
- std::unique_ptr<test::SimpleSessionNotifier> notifier_;
-};
-
-} // namespace simulator
-} // namespace quic
-
-#endif // QUICHE_QUIC_TEST_TOOLS_SIMULATOR_QUIC_ENDPOINT_H_
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/simulator/quic_endpoint_base.cc b/chromium/net/third_party/quiche/src/quic/test_tools/simulator/quic_endpoint_base.cc
deleted file mode 100644
index b4882b8ebc6..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/simulator/quic_endpoint_base.cc
+++ /dev/null
@@ -1,220 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/simulator/quic_endpoint_base.h"
-
-#include <memory>
-#include <utility>
-
-#include "absl/strings/str_cat.h"
-#include "quic/core/crypto/crypto_handshake_message.h"
-#include "quic/core/crypto/crypto_protocol.h"
-#include "quic/core/quic_connection.h"
-#include "quic/core/quic_data_writer.h"
-#include "quic/platform/api/quic_test_output.h"
-#include "quic/test_tools/quic_connection_peer.h"
-#include "quic/test_tools/quic_test_utils.h"
-#include "quic/test_tools/simulator/simulator.h"
-
-namespace quic {
-namespace simulator {
-
-// Takes a SHA-1 hash of the name and converts it into five 32-bit integers.
-static std::vector<uint32_t> HashNameIntoFive32BitIntegers(std::string name) {
- const std::string hash = test::Sha1Hash(name);
-
- std::vector<uint32_t> output;
- uint32_t current_number = 0;
- for (size_t i = 0; i < hash.size(); i++) {
- current_number = (current_number << 8) + hash[i];
- if (i % 4 == 3) {
- output.push_back(i);
- current_number = 0;
- }
- }
-
- return output;
-}
-
-QuicSocketAddress GetAddressFromName(std::string name) {
- const std::vector<uint32_t> hash = HashNameIntoFive32BitIntegers(name);
-
- // Generate a random port between 1025 and 65535.
- const uint16_t port = 1025 + hash[0] % (65535 - 1025 + 1);
-
- // Generate a random 10.x.x.x address, where x is between 1 and 254.
- std::string ip_address{"\xa\0\0\0", 4};
- for (size_t i = 1; i < 4; i++) {
- ip_address[i] = 1 + hash[i] % 254;
- }
- QuicIpAddress host;
- host.FromPackedString(ip_address.c_str(), ip_address.length());
- return QuicSocketAddress(host, port);
-}
-
-QuicEndpointBase::QuicEndpointBase(Simulator* simulator,
- std::string name,
- std::string peer_name)
- : Endpoint(simulator, name),
- peer_name_(peer_name),
- writer_(this),
- nic_tx_queue_(simulator,
- absl::StrCat(name, " (TX Queue)"),
- kMaxOutgoingPacketSize * kTxQueueSize),
- connection_(nullptr),
- write_blocked_count_(0),
- drop_next_packet_(false) {
- nic_tx_queue_.set_listener_interface(this);
-}
-
-QuicEndpointBase::~QuicEndpointBase() {
- if (trace_visitor_ != nullptr) {
- const char* perspective_prefix =
- connection_->perspective() == Perspective::IS_CLIENT ? "C" : "S";
-
- std::string identifier = absl::StrCat(
- perspective_prefix, connection_->connection_id().ToString());
- QuicRecordTrace(identifier, trace_visitor_->trace()->SerializeAsString());
- }
-}
-
-void QuicEndpointBase::DropNextIncomingPacket() {
- drop_next_packet_ = true;
-}
-
-void QuicEndpointBase::RecordTrace() {
- trace_visitor_ = std::make_unique<QuicTraceVisitor>(connection_.get());
- connection_->set_debug_visitor(trace_visitor_.get());
-}
-
-void QuicEndpointBase::AcceptPacket(std::unique_ptr<Packet> packet) {
- if (packet->destination != name_) {
- return;
- }
- if (drop_next_packet_) {
- drop_next_packet_ = false;
- return;
- }
-
- QuicReceivedPacket received_packet(packet->contents.data(),
- packet->contents.size(), clock_->Now());
- connection_->ProcessUdpPacket(connection_->self_address(),
- connection_->peer_address(), received_packet);
-}
-
-UnconstrainedPortInterface* QuicEndpointBase::GetRxPort() {
- return this;
-}
-
-void QuicEndpointBase::SetTxPort(ConstrainedPortInterface* port) {
- // Any egress done by the endpoint is actually handled by a queue on an NIC.
- nic_tx_queue_.set_tx_port(port);
-}
-
-void QuicEndpointBase::OnPacketDequeued() {
- if (writer_.IsWriteBlocked() &&
- (nic_tx_queue_.capacity() - nic_tx_queue_.bytes_queued()) >=
- kMaxOutgoingPacketSize) {
- writer_.SetWritable();
- connection_->OnCanWrite();
- }
-}
-
-QuicEndpointBase::Writer::Writer(QuicEndpointBase* endpoint)
- : endpoint_(endpoint), is_blocked_(false) {}
-
-QuicEndpointBase::Writer::~Writer() {}
-
-WriteResult QuicEndpointBase::Writer::WritePacket(
- const char* buffer,
- size_t buf_len,
- const QuicIpAddress& /*self_address*/,
- const QuicSocketAddress& /*peer_address*/,
- PerPacketOptions* options) {
- QUICHE_DCHECK(!IsWriteBlocked());
- QUICHE_DCHECK(options == nullptr);
- QUICHE_DCHECK(buf_len <= kMaxOutgoingPacketSize);
-
- // Instead of losing a packet, become write-blocked when the egress queue is
- // full.
- if (endpoint_->nic_tx_queue_.packets_queued() > kTxQueueSize) {
- is_blocked_ = true;
- endpoint_->write_blocked_count_++;
- return WriteResult(WRITE_STATUS_BLOCKED, 0);
- }
-
- auto packet = std::make_unique<Packet>();
- packet->source = endpoint_->name();
- packet->destination = endpoint_->peer_name_;
- packet->tx_timestamp = endpoint_->clock_->Now();
-
- packet->contents = std::string(buffer, buf_len);
- packet->size = buf_len;
-
- endpoint_->nic_tx_queue_.AcceptPacket(std::move(packet));
-
- return WriteResult(WRITE_STATUS_OK, buf_len);
-}
-
-bool QuicEndpointBase::Writer::IsWriteBlocked() const {
- return is_blocked_;
-}
-
-void QuicEndpointBase::Writer::SetWritable() {
- is_blocked_ = false;
-}
-
-QuicByteCount QuicEndpointBase::Writer::GetMaxPacketSize(
- const QuicSocketAddress& /*peer_address*/) const {
- return kMaxOutgoingPacketSize;
-}
-
-bool QuicEndpointBase::Writer::SupportsReleaseTime() const {
- return false;
-}
-
-bool QuicEndpointBase::Writer::IsBatchMode() const {
- return false;
-}
-
-QuicPacketBuffer QuicEndpointBase::Writer::GetNextWriteLocation(
- const QuicIpAddress& /*self_address*/,
- const QuicSocketAddress& /*peer_address*/) {
- return {nullptr, nullptr};
-}
-
-WriteResult QuicEndpointBase::Writer::Flush() {
- return WriteResult(WRITE_STATUS_OK, 0);
-}
-
-QuicEndpointMultiplexer::QuicEndpointMultiplexer(
- std::string name,
- const std::vector<QuicEndpointBase*>& endpoints)
- : Endpoint((*endpoints.begin())->simulator(), name) {
- for (QuicEndpointBase* endpoint : endpoints) {
- mapping_.insert(std::make_pair(endpoint->name(), endpoint));
- }
-}
-
-QuicEndpointMultiplexer::~QuicEndpointMultiplexer() {}
-
-void QuicEndpointMultiplexer::AcceptPacket(std::unique_ptr<Packet> packet) {
- auto key_value_pair_it = mapping_.find(packet->destination);
- if (key_value_pair_it == mapping_.end()) {
- return;
- }
-
- key_value_pair_it->second->GetRxPort()->AcceptPacket(std::move(packet));
-}
-UnconstrainedPortInterface* QuicEndpointMultiplexer::GetRxPort() {
- return this;
-}
-void QuicEndpointMultiplexer::SetTxPort(ConstrainedPortInterface* port) {
- for (auto& key_value_pair : mapping_) {
- key_value_pair.second->SetTxPort(port);
- }
-}
-
-} // namespace simulator
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/simulator/quic_endpoint_base.h b/chromium/net/third_party/quiche/src/quic/test_tools/simulator/quic_endpoint_base.h
deleted file mode 100644
index 81b09f1d03e..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/simulator/quic_endpoint_base.h
+++ /dev/null
@@ -1,160 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_SIMULATOR_QUIC_ENDPOINT_BASE_H_
-#define QUICHE_QUIC_TEST_TOOLS_SIMULATOR_QUIC_ENDPOINT_BASE_H_
-
-#include <memory>
-
-#include "absl/container/flat_hash_map.h"
-#include "quic/core/crypto/null_decrypter.h"
-#include "quic/core/crypto/null_encrypter.h"
-#include "quic/core/quic_connection.h"
-#include "quic/core/quic_default_packet_writer.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_stream_frame_data_producer.h"
-#include "quic/core/quic_trace_visitor.h"
-#include "quic/platform/api/quic_containers.h"
-#include "quic/test_tools/simple_session_notifier.h"
-#include "quic/test_tools/simulator/link.h"
-#include "quic/test_tools/simulator/queue.h"
-
-namespace quic {
-namespace simulator {
-
-// Size of the TX queue used by the kernel/NIC. 1000 is the Linux
-// kernel default.
-const QuicByteCount kTxQueueSize = 1000;
-
-// Generate a random local network host-port tuple based on the name of the
-// endpoint.
-QuicSocketAddress GetAddressFromName(std::string name);
-
-// A QUIC connection endpoint. If the specific data transmitted does not matter
-// (e.g. for congestion control purposes), QuicEndpoint is the subclass that
-// transmits dummy data. If the actual semantics of the connection matter,
-// subclassing QuicEndpointBase is required.
-class QuicEndpointBase : public Endpoint,
- public UnconstrainedPortInterface,
- public Queue::ListenerInterface {
- public:
- // Does not create the connection; the subclass has to create connection by
- // itself.
- QuicEndpointBase(Simulator* simulator,
- std::string name,
- std::string peer_name);
- ~QuicEndpointBase() override;
-
- inline QuicConnection* connection() { return connection_.get(); }
- inline size_t write_blocked_count() { return write_blocked_count_; }
-
- // Drop the next packet upon receipt.
- void DropNextIncomingPacket();
-
- // UnconstrainedPortInterface method. Called whenever the endpoint receives a
- // packet.
- void AcceptPacket(std::unique_ptr<Packet> packet) override;
-
- // Enables logging of the connection trace at the end of the unit test.
- void RecordTrace();
-
- // Begin Endpoint implementation.
- UnconstrainedPortInterface* GetRxPort() override;
- void SetTxPort(ConstrainedPortInterface* port) override;
- // End Endpoint implementation.
-
- // Actor method.
- void Act() override {}
-
- // Queue::ListenerInterface method.
- void OnPacketDequeued() override;
-
- protected:
- // A Writer object that writes into the |nic_tx_queue_|.
- class Writer : public QuicPacketWriter {
- public:
- explicit Writer(QuicEndpointBase* endpoint);
- ~Writer() override;
-
- WriteResult WritePacket(const char* buffer,
- size_t buf_len,
- const QuicIpAddress& self_address,
- const QuicSocketAddress& peer_address,
- PerPacketOptions* options) override;
- bool IsWriteBlocked() const override;
- void SetWritable() override;
- QuicByteCount GetMaxPacketSize(
- const QuicSocketAddress& peer_address) const override;
- bool SupportsReleaseTime() const override;
- bool IsBatchMode() const override;
- QuicPacketBuffer GetNextWriteLocation(
- const QuicIpAddress& self_address,
- const QuicSocketAddress& peer_address) override;
- WriteResult Flush() override;
-
- private:
- QuicEndpointBase* endpoint_;
-
- bool is_blocked_;
- };
-
- // The producer outputs the repetition of the same byte. That sequence is
- // verified by the receiver.
- class DataProducer : public QuicStreamFrameDataProducer {
- public:
- WriteStreamDataResult WriteStreamData(QuicStreamId id,
- QuicStreamOffset offset,
- QuicByteCount data_length,
- QuicDataWriter* writer) override;
- bool WriteCryptoData(EncryptionLevel level,
- QuicStreamOffset offset,
- QuicByteCount data_length,
- QuicDataWriter* writer) override;
- };
-
- std::string peer_name_;
-
- Writer writer_;
- // The queue for the outgoing packets. In reality, this might be either on
- // the network card, or in the kernel, but for concreteness we assume it's on
- // the network card.
- Queue nic_tx_queue_;
- // Created by the subclass.
- std::unique_ptr<QuicConnection> connection_;
-
- // Counts the number of times the writer became write-blocked.
- size_t write_blocked_count_;
-
- // If true, drop the next packet when receiving it.
- bool drop_next_packet_;
-
- std::unique_ptr<QuicTraceVisitor> trace_visitor_;
-};
-
-// Multiplexes multiple connections at the same host on the network.
-class QuicEndpointMultiplexer : public Endpoint,
- public UnconstrainedPortInterface {
- public:
- QuicEndpointMultiplexer(std::string name,
- const std::vector<QuicEndpointBase*>& endpoints);
- ~QuicEndpointMultiplexer() override;
-
- // Receives a packet and passes it to the specified endpoint if that endpoint
- // is one of the endpoints being multiplexed, otherwise ignores the packet.
- void AcceptPacket(std::unique_ptr<Packet> packet) override;
- UnconstrainedPortInterface* GetRxPort() override;
-
- // Sets the egress port for all the endpoints being multiplexed.
- void SetTxPort(ConstrainedPortInterface* port) override;
-
- void Act() override {}
-
- private:
- absl::flat_hash_map<std::string, QuicEndpointBase*> mapping_;
-};
-
-} // namespace simulator
-} // namespace quic
-
-#endif // QUICHE_QUIC_TEST_TOOLS_SIMULATOR_QUIC_ENDPOINT_BASE_H_
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/simulator/quic_endpoint_test.cc b/chromium/net/third_party/quiche/src/quic/test_tools/simulator/quic_endpoint_test.cc
deleted file mode 100644
index 69b2682dfc0..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/simulator/quic_endpoint_test.cc
+++ /dev/null
@@ -1,208 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/simulator/quic_endpoint.h"
-
-#include <utility>
-
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/quic_connection_peer.h"
-#include "quic/test_tools/quic_test_utils.h"
-#include "quic/test_tools/simulator/simulator.h"
-#include "quic/test_tools/simulator/switch.h"
-
-using ::testing::_;
-using ::testing::NiceMock;
-using ::testing::Return;
-
-namespace quic {
-namespace simulator {
-
-const QuicBandwidth kDefaultBandwidth =
- QuicBandwidth::FromKBitsPerSecond(10 * 1000);
-const QuicTime::Delta kDefaultPropagationDelay =
- QuicTime::Delta::FromMilliseconds(20);
-const QuicByteCount kDefaultBdp = kDefaultBandwidth * kDefaultPropagationDelay;
-
-// A simple test harness where all hosts are connected to a switch with
-// identical links.
-class QuicEndpointTest : public QuicTest {
- public:
- QuicEndpointTest()
- : simulator_(), switch_(&simulator_, "Switch", 8, kDefaultBdp * 2) {}
-
- protected:
- Simulator simulator_;
- Switch switch_;
-
- std::unique_ptr<SymmetricLink> Link(Endpoint* a, Endpoint* b) {
- return std::make_unique<SymmetricLink>(a, b, kDefaultBandwidth,
- kDefaultPropagationDelay);
- }
-
- std::unique_ptr<SymmetricLink> CustomLink(Endpoint* a,
- Endpoint* b,
- uint64_t extra_rtt_ms) {
- return std::make_unique<SymmetricLink>(
- a, b, kDefaultBandwidth,
- kDefaultPropagationDelay +
- QuicTime::Delta::FromMilliseconds(extra_rtt_ms));
- }
-};
-
-// Test transmission from one host to another.
-TEST_F(QuicEndpointTest, OneWayTransmission) {
- QuicEndpoint endpoint_a(&simulator_, "Endpoint A", "Endpoint B",
- Perspective::IS_CLIENT, test::TestConnectionId(42));
- QuicEndpoint endpoint_b(&simulator_, "Endpoint B", "Endpoint A",
- Perspective::IS_SERVER, test::TestConnectionId(42));
- auto link_a = Link(&endpoint_a, switch_.port(1));
- auto link_b = Link(&endpoint_b, switch_.port(2));
-
- // First transmit a small, packet-size chunk of data.
- endpoint_a.AddBytesToTransfer(600);
- QuicTime end_time =
- simulator_.GetClock()->Now() + QuicTime::Delta::FromMilliseconds(1000);
- simulator_.RunUntil(
- [this, end_time]() { return simulator_.GetClock()->Now() >= end_time; });
-
- EXPECT_EQ(600u, endpoint_a.bytes_transferred());
- ASSERT_EQ(600u, endpoint_b.bytes_received());
- EXPECT_FALSE(endpoint_a.wrong_data_received());
- EXPECT_FALSE(endpoint_b.wrong_data_received());
-
- // After a small chunk succeeds, try to transfer 2 MiB.
- endpoint_a.AddBytesToTransfer(2 * 1024 * 1024);
- end_time = simulator_.GetClock()->Now() + QuicTime::Delta::FromSeconds(5);
- simulator_.RunUntil(
- [this, end_time]() { return simulator_.GetClock()->Now() >= end_time; });
-
- const QuicByteCount total_bytes_transferred = 600 + 2 * 1024 * 1024;
- EXPECT_EQ(total_bytes_transferred, endpoint_a.bytes_transferred());
- EXPECT_EQ(total_bytes_transferred, endpoint_b.bytes_received());
- EXPECT_EQ(0u, endpoint_a.write_blocked_count());
- EXPECT_FALSE(endpoint_a.wrong_data_received());
- EXPECT_FALSE(endpoint_b.wrong_data_received());
-}
-
-// Test the situation in which the writer becomes write-blocked.
-TEST_F(QuicEndpointTest, WriteBlocked) {
- QuicEndpoint endpoint_a(&simulator_, "Endpoint A", "Endpoint B",
- Perspective::IS_CLIENT, test::TestConnectionId(42));
- QuicEndpoint endpoint_b(&simulator_, "Endpoint B", "Endpoint A",
- Perspective::IS_SERVER, test::TestConnectionId(42));
- auto link_a = Link(&endpoint_a, switch_.port(1));
- auto link_b = Link(&endpoint_b, switch_.port(2));
-
- // Will be owned by the sent packet manager.
- auto* sender = new NiceMock<test::MockSendAlgorithm>();
- EXPECT_CALL(*sender, CanSend(_)).WillRepeatedly(Return(true));
- EXPECT_CALL(*sender, PacingRate(_))
- .WillRepeatedly(Return(10 * kDefaultBandwidth));
- EXPECT_CALL(*sender, BandwidthEstimate())
- .WillRepeatedly(Return(10 * kDefaultBandwidth));
- EXPECT_CALL(*sender, GetCongestionWindow())
- .WillRepeatedly(Return(kMaxOutgoingPacketSize *
- GetQuicFlag(FLAGS_quic_max_congestion_window)));
- test::QuicConnectionPeer::SetSendAlgorithm(endpoint_a.connection(), sender);
-
- // First transmit a small, packet-size chunk of data.
- QuicByteCount bytes_to_transfer = 3 * 1024 * 1024;
- endpoint_a.AddBytesToTransfer(bytes_to_transfer);
- QuicTime end_time =
- simulator_.GetClock()->Now() + QuicTime::Delta::FromSeconds(30);
- simulator_.RunUntil([this, &endpoint_b, bytes_to_transfer, end_time]() {
- return endpoint_b.bytes_received() == bytes_to_transfer ||
- simulator_.GetClock()->Now() >= end_time;
- });
-
- EXPECT_EQ(bytes_to_transfer, endpoint_a.bytes_transferred());
- EXPECT_EQ(bytes_to_transfer, endpoint_b.bytes_received());
- EXPECT_GT(endpoint_a.write_blocked_count(), 0u);
- EXPECT_FALSE(endpoint_a.wrong_data_received());
- EXPECT_FALSE(endpoint_b.wrong_data_received());
-}
-
-// Test transmission of 1 MiB of data between two hosts simultaneously in both
-// directions.
-TEST_F(QuicEndpointTest, TwoWayTransmission) {
- QuicEndpoint endpoint_a(&simulator_, "Endpoint A", "Endpoint B",
- Perspective::IS_CLIENT, test::TestConnectionId(42));
- QuicEndpoint endpoint_b(&simulator_, "Endpoint B", "Endpoint A",
- Perspective::IS_SERVER, test::TestConnectionId(42));
- auto link_a = Link(&endpoint_a, switch_.port(1));
- auto link_b = Link(&endpoint_b, switch_.port(2));
-
- endpoint_a.RecordTrace();
- endpoint_b.RecordTrace();
-
- endpoint_a.AddBytesToTransfer(1024 * 1024);
- endpoint_b.AddBytesToTransfer(1024 * 1024);
- QuicTime end_time =
- simulator_.GetClock()->Now() + QuicTime::Delta::FromSeconds(5);
- simulator_.RunUntil(
- [this, end_time]() { return simulator_.GetClock()->Now() >= end_time; });
-
- EXPECT_EQ(1024u * 1024u, endpoint_a.bytes_transferred());
- EXPECT_EQ(1024u * 1024u, endpoint_b.bytes_transferred());
- EXPECT_EQ(1024u * 1024u, endpoint_a.bytes_received());
- EXPECT_EQ(1024u * 1024u, endpoint_b.bytes_received());
- EXPECT_FALSE(endpoint_a.wrong_data_received());
- EXPECT_FALSE(endpoint_b.wrong_data_received());
-}
-
-// Simulate three hosts trying to send data to a fourth one simultaneously.
-TEST_F(QuicEndpointTest, Competition) {
- auto endpoint_a = std::make_unique<QuicEndpoint>(
- &simulator_, "Endpoint A", "Endpoint D (A)", Perspective::IS_CLIENT,
- test::TestConnectionId(42));
- auto endpoint_b = std::make_unique<QuicEndpoint>(
- &simulator_, "Endpoint B", "Endpoint D (B)", Perspective::IS_CLIENT,
- test::TestConnectionId(43));
- auto endpoint_c = std::make_unique<QuicEndpoint>(
- &simulator_, "Endpoint C", "Endpoint D (C)", Perspective::IS_CLIENT,
- test::TestConnectionId(44));
- auto endpoint_d_a = std::make_unique<QuicEndpoint>(
- &simulator_, "Endpoint D (A)", "Endpoint A", Perspective::IS_SERVER,
- test::TestConnectionId(42));
- auto endpoint_d_b = std::make_unique<QuicEndpoint>(
- &simulator_, "Endpoint D (B)", "Endpoint B", Perspective::IS_SERVER,
- test::TestConnectionId(43));
- auto endpoint_d_c = std::make_unique<QuicEndpoint>(
- &simulator_, "Endpoint D (C)", "Endpoint C", Perspective::IS_SERVER,
- test::TestConnectionId(44));
- QuicEndpointMultiplexer endpoint_d(
- "Endpoint D",
- {endpoint_d_a.get(), endpoint_d_b.get(), endpoint_d_c.get()});
-
- // Create links with slightly different RTTs in order to avoid pathological
- // side-effects of packets entering the queue at the exactly same time.
- auto link_a = CustomLink(endpoint_a.get(), switch_.port(1), 0);
- auto link_b = CustomLink(endpoint_b.get(), switch_.port(2), 1);
- auto link_c = CustomLink(endpoint_c.get(), switch_.port(3), 2);
- auto link_d = Link(&endpoint_d, switch_.port(4));
-
- endpoint_a->AddBytesToTransfer(2 * 1024 * 1024);
- endpoint_b->AddBytesToTransfer(2 * 1024 * 1024);
- endpoint_c->AddBytesToTransfer(2 * 1024 * 1024);
- QuicTime end_time =
- simulator_.GetClock()->Now() + QuicTime::Delta::FromSeconds(12);
- simulator_.RunUntil(
- [this, end_time]() { return simulator_.GetClock()->Now() >= end_time; });
-
- for (QuicEndpoint* endpoint :
- {endpoint_a.get(), endpoint_b.get(), endpoint_c.get()}) {
- EXPECT_EQ(2u * 1024u * 1024u, endpoint->bytes_transferred());
- EXPECT_GE(endpoint->connection()->GetStats().packets_lost, 0u);
- }
- for (QuicEndpoint* endpoint :
- {endpoint_d_a.get(), endpoint_d_b.get(), endpoint_d_c.get()}) {
- EXPECT_EQ(2u * 1024u * 1024u, endpoint->bytes_received());
- EXPECT_FALSE(endpoint->wrong_data_received());
- }
-}
-
-} // namespace simulator
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/simulator/simulator.cc b/chromium/net/third_party/quiche/src/quic/test_tools/simulator/simulator.cc
deleted file mode 100644
index a9835e85d0a..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/simulator/simulator.cc
+++ /dev/null
@@ -1,170 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/simulator/simulator.h"
-
-#include "quic/core/crypto/quic_random.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-namespace simulator {
-
-Simulator::Simulator() : Simulator(nullptr) {}
-
-Simulator::Simulator(QuicRandom* random_generator)
- : random_generator_(random_generator),
- alarm_factory_(this, "Default Alarm Manager"),
- run_for_should_stop_(false),
- enable_random_delays_(false) {
- run_for_alarm_.reset(
- alarm_factory_.CreateAlarm(new RunForDelegate(&run_for_should_stop_)));
-}
-
-Simulator::~Simulator() {
- // Ensure that Actor under run_for_alarm_ is removed before Simulator data
- // structures are destructed.
- run_for_alarm_.reset();
-}
-
-Simulator::Clock::Clock() : now_(kStartTime) {}
-
-QuicTime Simulator::Clock::ApproximateNow() const {
- return now_;
-}
-
-QuicTime Simulator::Clock::Now() const {
- return now_;
-}
-
-QuicWallTime Simulator::Clock::WallNow() const {
- return QuicWallTime::FromUNIXMicroseconds(
- (now_ - QuicTime::Zero()).ToMicroseconds());
-}
-
-void Simulator::AddActor(Actor* actor) {
- auto emplace_times_result =
- scheduled_times_.insert(std::make_pair(actor, QuicTime::Infinite()));
- auto emplace_names_result = actor_names_.insert(actor->name());
-
- // Ensure that the object was actually placed into the map.
- QUICHE_DCHECK(emplace_times_result.second);
- QUICHE_DCHECK(emplace_names_result.second);
-}
-
-void Simulator::RemoveActor(Actor* actor) {
- auto scheduled_time_it = scheduled_times_.find(actor);
- auto actor_names_it = actor_names_.find(actor->name());
- QUICHE_DCHECK(scheduled_time_it != scheduled_times_.end());
- QUICHE_DCHECK(actor_names_it != actor_names_.end());
-
- QuicTime scheduled_time = scheduled_time_it->second;
- if (scheduled_time != QuicTime::Infinite()) {
- Unschedule(actor);
- }
-
- scheduled_times_.erase(scheduled_time_it);
- actor_names_.erase(actor_names_it);
-}
-
-void Simulator::Schedule(Actor* actor, QuicTime new_time) {
- auto scheduled_time_it = scheduled_times_.find(actor);
- QUICHE_DCHECK(scheduled_time_it != scheduled_times_.end());
- QuicTime scheduled_time = scheduled_time_it->second;
-
- if (scheduled_time <= new_time) {
- return;
- }
-
- if (scheduled_time != QuicTime::Infinite()) {
- Unschedule(actor);
- }
-
- scheduled_time_it->second = new_time;
- schedule_.insert(std::make_pair(new_time, actor));
-}
-
-void Simulator::Unschedule(Actor* actor) {
- auto scheduled_time_it = scheduled_times_.find(actor);
- QUICHE_DCHECK(scheduled_time_it != scheduled_times_.end());
- QuicTime scheduled_time = scheduled_time_it->second;
-
- QUICHE_DCHECK(scheduled_time != QuicTime::Infinite());
- auto range = schedule_.equal_range(scheduled_time);
- for (auto it = range.first; it != range.second; ++it) {
- if (it->second == actor) {
- schedule_.erase(it);
- scheduled_time_it->second = QuicTime::Infinite();
- return;
- }
- }
- QUICHE_DCHECK(false);
-}
-
-const QuicClock* Simulator::GetClock() const {
- return &clock_;
-}
-
-QuicRandom* Simulator::GetRandomGenerator() {
- if (random_generator_ == nullptr) {
- random_generator_ = QuicRandom::GetInstance();
- }
-
- return random_generator_;
-}
-
-QuicBufferAllocator* Simulator::GetStreamSendBufferAllocator() {
- return &buffer_allocator_;
-}
-
-QuicAlarmFactory* Simulator::GetAlarmFactory() {
- return &alarm_factory_;
-}
-
-Simulator::RunForDelegate::RunForDelegate(bool* run_for_should_stop)
- : run_for_should_stop_(run_for_should_stop) {}
-
-void Simulator::RunForDelegate::OnAlarm() {
- *run_for_should_stop_ = true;
-}
-
-void Simulator::RunFor(QuicTime::Delta time_span) {
- QUICHE_DCHECK(!run_for_alarm_->IsSet());
-
- // RunFor() ensures that the simulation stops at the exact time specified by
- // scheduling an alarm at that point and using that alarm to abort the
- // simulation. An alarm is necessary because otherwise it is possible that
- // nothing is scheduled at |end_time|, so the simulation will either go
- // further than requested or stop before reaching |end_time|.
- const QuicTime end_time = clock_.Now() + time_span;
- run_for_alarm_->Set(end_time);
- run_for_should_stop_ = false;
- bool simulation_result = RunUntil([this]() { return run_for_should_stop_; });
-
- QUICHE_DCHECK(simulation_result);
- QUICHE_DCHECK(clock_.Now() == end_time);
-}
-
-void Simulator::HandleNextScheduledActor() {
- const auto current_event_it = schedule_.begin();
- QuicTime event_time = current_event_it->first;
- Actor* actor = current_event_it->second;
- QUIC_DVLOG(3) << "At t = " << event_time.ToDebuggingValue() << ", calling "
- << actor->name();
-
- Unschedule(actor);
-
- if (clock_.Now() > event_time) {
- QUIC_BUG(quic_bug_10150_1)
- << "Error: event registered by [" << actor->name()
- << "] requires travelling back in time. Current time: "
- << clock_.Now().ToDebuggingValue()
- << ", scheduled time: " << event_time.ToDebuggingValue();
- }
- clock_.now_ = event_time;
-
- actor->Act();
-}
-
-} // namespace simulator
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/simulator/simulator.h b/chromium/net/third_party/quiche/src/quic/test_tools/simulator/simulator.h
deleted file mode 100644
index b4298f53e50..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/simulator/simulator.h
+++ /dev/null
@@ -1,169 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_SIMULATOR_SIMULATOR_H_
-#define QUICHE_QUIC_TEST_TOOLS_SIMULATOR_SIMULATOR_H_
-
-#include <map>
-
-#include "absl/container/flat_hash_map.h"
-#include "absl/container/flat_hash_set.h"
-#include "quic/core/quic_connection.h"
-#include "quic/core/quic_simple_buffer_allocator.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_containers.h"
-#include "quic/test_tools/simulator/actor.h"
-#include "quic/test_tools/simulator/alarm_factory.h"
-
-namespace quic {
-namespace simulator {
-
-// Simulator is responsible for scheduling actors in the simulation and
-// providing basic utility interfaces (clock, alarms, RNG and others).
-class Simulator : public QuicConnectionHelperInterface {
- public:
- Simulator();
- explicit Simulator(QuicRandom* random_generator);
- Simulator(const Simulator&) = delete;
- Simulator& operator=(const Simulator&) = delete;
- ~Simulator() override;
-
- // Schedule the specified actor. This method will ensure that |actor| is
- // called at |new_time| at latest. If Schedule() is called multiple times
- // before the Actor is called, Act() is called exactly once, at the earliest
- // time requested, and the Actor has to reschedule itself manually for the
- // subsequent times if they are still necessary.
- void Schedule(Actor* actor, QuicTime new_time);
-
- // Remove the specified actor from the schedule.
- void Unschedule(Actor* actor);
-
- // Begin QuicConnectionHelperInterface implementation.
- const QuicClock* GetClock() const override;
- QuicRandom* GetRandomGenerator() override;
- QuicBufferAllocator* GetStreamSendBufferAllocator() override;
- // End QuicConnectionHelperInterface implementation.
-
- QuicAlarmFactory* GetAlarmFactory();
-
- inline void set_random_generator(QuicRandom* random) {
- random_generator_ = random;
- }
-
- inline bool enable_random_delays() const { return enable_random_delays_; }
-
- // Run the simulation until either no actors are scheduled or
- // |termination_predicate| returns true. Returns true if terminated due to
- // predicate, and false otherwise.
- template <class TerminationPredicate>
- bool RunUntil(TerminationPredicate termination_predicate);
-
- // Same as RunUntil, except this function also accepts a |deadline|, and will
- // return false if the deadline is exceeded.
- template <class TerminationPredicate>
- bool RunUntilOrTimeout(TerminationPredicate termination_predicate,
- QuicTime::Delta deadline);
-
- // Runs the simulation for exactly the specified |time_span|.
- void RunFor(QuicTime::Delta time_span);
-
- private:
- friend class Actor;
-
- class Clock : public QuicClock {
- public:
- // Do not start at zero as certain code can treat zero as an invalid
- // timestamp.
- const QuicTime kStartTime =
- QuicTime::Zero() + QuicTime::Delta::FromMicroseconds(1);
-
- Clock();
-
- QuicTime ApproximateNow() const override;
- QuicTime Now() const override;
- QuicWallTime WallNow() const override;
-
- QuicTime now_;
- };
-
- // The delegate used for RunFor().
- class RunForDelegate : public QuicAlarm::DelegateWithoutContext {
- public:
- explicit RunForDelegate(bool* run_for_should_stop);
- void OnAlarm() override;
-
- private:
- // Pointer to |run_for_should_stop_| in the parent simulator.
- bool* run_for_should_stop_;
- };
-
- // Register an actor with the simulator. Invoked by Actor constructor.
- void AddActor(Actor* actor);
-
- // Unregister an actor with the simulator. Invoked by Actor destructor.
- void RemoveActor(Actor* actor);
-
- // Finds the next scheduled actor, advances time to the schedule time and
- // notifies the actor.
- void HandleNextScheduledActor();
-
- Clock clock_;
- QuicRandom* random_generator_;
- SimpleBufferAllocator buffer_allocator_;
- AlarmFactory alarm_factory_;
-
- // Alarm for RunFor() method.
- std::unique_ptr<QuicAlarm> run_for_alarm_;
- // Flag used to stop simulations ran via RunFor().
- bool run_for_should_stop_;
-
- // Indicates whether the simulator should add random delays on the links in
- // order to avoid synchronization issues.
- bool enable_random_delays_;
-
- // Schedule of when the actors will be executed via an Act() call. The
- // schedule is subject to the following invariants:
- // - An actor cannot be scheduled for a later time than it's currently in the
- // schedule.
- // - An actor is removed from schedule either immediately before Act() is
- // called or by explicitly calling Unschedule().
- // - Each Actor appears in the map at most once.
- std::multimap<QuicTime, Actor*> schedule_;
- // For each actor, maintain the time it is scheduled at. The value for
- // unscheduled actors is QuicTime::Infinite().
- absl::flat_hash_map<Actor*, QuicTime> scheduled_times_;
- absl::flat_hash_set<std::string> actor_names_;
-};
-
-template <class TerminationPredicate>
-bool Simulator::RunUntil(TerminationPredicate termination_predicate) {
- bool predicate_value = false;
- while (true) {
- predicate_value = termination_predicate();
- if (predicate_value || schedule_.empty()) {
- break;
- }
- HandleNextScheduledActor();
- }
- return predicate_value;
-}
-
-template <class TerminationPredicate>
-bool Simulator::RunUntilOrTimeout(TerminationPredicate termination_predicate,
- QuicTime::Delta timeout) {
- QuicTime end_time = clock_.Now() + timeout;
- bool return_value = RunUntil([end_time, &termination_predicate, this]() {
- return termination_predicate() || clock_.Now() >= end_time;
- });
-
- if (clock_.Now() >= end_time) {
- return false;
- }
- return return_value;
-}
-
-} // namespace simulator
-} // namespace quic
-
-#endif // QUICHE_QUIC_TEST_TOOLS_SIMULATOR_SIMULATOR_H_
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/simulator/simulator_test.cc b/chromium/net/third_party/quiche/src/quic/test_tools/simulator/simulator_test.cc
deleted file mode 100644
index fe841703cf4..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/simulator/simulator_test.cc
+++ /dev/null
@@ -1,832 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/simulator/simulator.h"
-
-#include <utility>
-
-#include "absl/container/node_hash_map.h"
-#include "quic/platform/api/quic_containers.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/quic_test_utils.h"
-#include "quic/test_tools/simulator/alarm_factory.h"
-#include "quic/test_tools/simulator/link.h"
-#include "quic/test_tools/simulator/packet_filter.h"
-#include "quic/test_tools/simulator/queue.h"
-#include "quic/test_tools/simulator/switch.h"
-#include "quic/test_tools/simulator/traffic_policer.h"
-
-using testing::_;
-using testing::Return;
-using testing::StrictMock;
-
-namespace quic {
-namespace simulator {
-
-// A simple counter that increments its value by 1 every specified period.
-class Counter : public Actor {
- public:
- Counter(Simulator* simulator, std::string name, QuicTime::Delta period)
- : Actor(simulator, name), value_(-1), period_(period) {
- Schedule(clock_->Now());
- }
- ~Counter() override {}
-
- inline int get_value() const { return value_; }
-
- void Act() override {
- ++value_;
- QUIC_DVLOG(1) << name_ << " has value " << value_ << " at time "
- << clock_->Now().ToDebuggingValue();
- Schedule(clock_->Now() + period_);
- }
-
- private:
- int value_;
- QuicTime::Delta period_;
-};
-
-class SimulatorTest : public QuicTest {};
-
-// Test that the basic event handling works, and that Actors can be created and
-// destroyed mid-simulation.
-TEST_F(SimulatorTest, Counters) {
- Simulator simulator;
- for (int i = 0; i < 2; ++i) {
- Counter fast_counter(&simulator, "fast_counter",
- QuicTime::Delta::FromSeconds(3));
- Counter slow_counter(&simulator, "slow_counter",
- QuicTime::Delta::FromSeconds(10));
-
- simulator.RunUntil(
- [&slow_counter]() { return slow_counter.get_value() >= 10; });
-
- EXPECT_EQ(10, slow_counter.get_value());
- EXPECT_EQ(10 * 10 / 3, fast_counter.get_value());
- }
-}
-
-// A port which counts the number of packets received on it, both total and
-// per-destination.
-class CounterPort : public UnconstrainedPortInterface {
- public:
- CounterPort() { Reset(); }
- ~CounterPort() override {}
-
- inline QuicByteCount bytes() const { return bytes_; }
- inline QuicPacketCount packets() const { return packets_; }
-
- void AcceptPacket(std::unique_ptr<Packet> packet) override {
- bytes_ += packet->size;
- packets_ += 1;
-
- per_destination_packet_counter_[packet->destination] += 1;
- }
-
- void Reset() {
- bytes_ = 0;
- packets_ = 0;
- per_destination_packet_counter_.clear();
- }
-
- QuicPacketCount CountPacketsForDestination(std::string destination) const {
- auto result_it = per_destination_packet_counter_.find(destination);
- if (result_it == per_destination_packet_counter_.cend()) {
- return 0;
- }
- return result_it->second;
- }
-
- private:
- QuicByteCount bytes_;
- QuicPacketCount packets_;
-
- absl::node_hash_map<std::string, QuicPacketCount>
- per_destination_packet_counter_;
-};
-
-// Sends the packet to the specified destination at the uplink rate. Provides a
-// CounterPort as an Rx interface.
-class LinkSaturator : public Endpoint {
- public:
- LinkSaturator(Simulator* simulator,
- std::string name,
- QuicByteCount packet_size,
- std::string destination)
- : Endpoint(simulator, name),
- packet_size_(packet_size),
- destination_(std::move(destination)),
- bytes_transmitted_(0),
- packets_transmitted_(0) {
- Schedule(clock_->Now());
- }
-
- void Act() override {
- if (tx_port_->TimeUntilAvailable().IsZero()) {
- auto packet = std::make_unique<Packet>();
- packet->source = name_;
- packet->destination = destination_;
- packet->tx_timestamp = clock_->Now();
- packet->size = packet_size_;
-
- tx_port_->AcceptPacket(std::move(packet));
-
- bytes_transmitted_ += packet_size_;
- packets_transmitted_ += 1;
- }
-
- Schedule(clock_->Now() + tx_port_->TimeUntilAvailable());
- }
-
- UnconstrainedPortInterface* GetRxPort() override {
- return static_cast<UnconstrainedPortInterface*>(&rx_port_);
- }
-
- void SetTxPort(ConstrainedPortInterface* port) override { tx_port_ = port; }
-
- CounterPort* counter() { return &rx_port_; }
-
- inline QuicByteCount bytes_transmitted() const { return bytes_transmitted_; }
- inline QuicPacketCount packets_transmitted() const {
- return packets_transmitted_;
- }
-
- void Pause() { Unschedule(); }
- void Resume() { Schedule(clock_->Now()); }
-
- private:
- QuicByteCount packet_size_;
- std::string destination_;
-
- ConstrainedPortInterface* tx_port_;
- CounterPort rx_port_;
-
- QuicByteCount bytes_transmitted_;
- QuicPacketCount packets_transmitted_;
-};
-
-// Saturate a symmetric link and verify that the number of packets sent and
-// received is correct.
-TEST_F(SimulatorTest, DirectLinkSaturation) {
- Simulator simulator;
- LinkSaturator saturator_a(&simulator, "Saturator A", 1000, "Saturator B");
- LinkSaturator saturator_b(&simulator, "Saturator B", 100, "Saturator A");
- SymmetricLink link(&saturator_a, &saturator_b,
- QuicBandwidth::FromKBytesPerSecond(1000),
- QuicTime::Delta::FromMilliseconds(100) +
- QuicTime::Delta::FromMicroseconds(1));
-
- const QuicTime start_time = simulator.GetClock()->Now();
- const QuicTime after_first_50_ms =
- start_time + QuicTime::Delta::FromMilliseconds(50);
- simulator.RunUntil([&simulator, after_first_50_ms]() {
- return simulator.GetClock()->Now() >= after_first_50_ms;
- });
- EXPECT_LE(1000u * 50u, saturator_a.bytes_transmitted());
- EXPECT_GE(1000u * 51u, saturator_a.bytes_transmitted());
- EXPECT_LE(1000u * 50u, saturator_b.bytes_transmitted());
- EXPECT_GE(1000u * 51u, saturator_b.bytes_transmitted());
- EXPECT_LE(50u, saturator_a.packets_transmitted());
- EXPECT_GE(51u, saturator_a.packets_transmitted());
- EXPECT_LE(500u, saturator_b.packets_transmitted());
- EXPECT_GE(501u, saturator_b.packets_transmitted());
- EXPECT_EQ(0u, saturator_a.counter()->bytes());
- EXPECT_EQ(0u, saturator_b.counter()->bytes());
-
- simulator.RunUntil([&saturator_a, &saturator_b]() {
- if (saturator_a.counter()->packets() > 1000 ||
- saturator_b.counter()->packets() > 100) {
- ADD_FAILURE() << "The simulation did not arrive at the expected "
- "termination contidition. Saturator A counter: "
- << saturator_a.counter()->packets()
- << ", saturator B counter: "
- << saturator_b.counter()->packets();
- return true;
- }
-
- return saturator_a.counter()->packets() == 1000 &&
- saturator_b.counter()->packets() == 100;
- });
- EXPECT_EQ(201u, saturator_a.packets_transmitted());
- EXPECT_EQ(2001u, saturator_b.packets_transmitted());
- EXPECT_EQ(201u * 1000, saturator_a.bytes_transmitted());
- EXPECT_EQ(2001u * 100, saturator_b.bytes_transmitted());
-
- EXPECT_EQ(1000u,
- saturator_a.counter()->CountPacketsForDestination("Saturator A"));
- EXPECT_EQ(100u,
- saturator_b.counter()->CountPacketsForDestination("Saturator B"));
- EXPECT_EQ(0u,
- saturator_a.counter()->CountPacketsForDestination("Saturator B"));
- EXPECT_EQ(0u,
- saturator_b.counter()->CountPacketsForDestination("Saturator A"));
-
- const QuicTime end_time = simulator.GetClock()->Now();
- const QuicBandwidth observed_bandwidth = QuicBandwidth::FromBytesAndTimeDelta(
- saturator_a.bytes_transmitted(), end_time - start_time);
- EXPECT_APPROX_EQ(link.bandwidth(), observed_bandwidth, 0.01f);
-}
-
-// Accepts packets and stores them internally.
-class PacketAcceptor : public ConstrainedPortInterface {
- public:
- void AcceptPacket(std::unique_ptr<Packet> packet) override {
- packets_.emplace_back(std::move(packet));
- }
-
- QuicTime::Delta TimeUntilAvailable() override {
- return QuicTime::Delta::Zero();
- }
-
- std::vector<std::unique_ptr<Packet>>* packets() { return &packets_; }
-
- private:
- std::vector<std::unique_ptr<Packet>> packets_;
-};
-
-// Ensure the queue behaves correctly with accepting packets.
-TEST_F(SimulatorTest, Queue) {
- Simulator simulator;
- Queue queue(&simulator, "Queue", 1000);
- PacketAcceptor acceptor;
- queue.set_tx_port(&acceptor);
-
- EXPECT_EQ(0u, queue.bytes_queued());
- EXPECT_EQ(0u, queue.packets_queued());
- EXPECT_EQ(0u, acceptor.packets()->size());
-
- auto first_packet = std::make_unique<Packet>();
- first_packet->size = 600;
- queue.AcceptPacket(std::move(first_packet));
- EXPECT_EQ(600u, queue.bytes_queued());
- EXPECT_EQ(1u, queue.packets_queued());
- EXPECT_EQ(0u, acceptor.packets()->size());
-
- // The second packet does not fit and is dropped.
- auto second_packet = std::make_unique<Packet>();
- second_packet->size = 500;
- queue.AcceptPacket(std::move(second_packet));
- EXPECT_EQ(600u, queue.bytes_queued());
- EXPECT_EQ(1u, queue.packets_queued());
- EXPECT_EQ(0u, acceptor.packets()->size());
-
- auto third_packet = std::make_unique<Packet>();
- third_packet->size = 400;
- queue.AcceptPacket(std::move(third_packet));
- EXPECT_EQ(1000u, queue.bytes_queued());
- EXPECT_EQ(2u, queue.packets_queued());
- EXPECT_EQ(0u, acceptor.packets()->size());
-
- // Run until there is nothing scheduled, so that the queue can deplete.
- simulator.RunUntil([]() { return false; });
- EXPECT_EQ(0u, queue.bytes_queued());
- EXPECT_EQ(0u, queue.packets_queued());
- ASSERT_EQ(2u, acceptor.packets()->size());
- EXPECT_EQ(600u, acceptor.packets()->at(0)->size);
- EXPECT_EQ(400u, acceptor.packets()->at(1)->size);
-}
-
-// Simulate a situation where the bottleneck link is 10 times slower than the
-// uplink, and they are separated by a queue.
-TEST_F(SimulatorTest, QueueBottleneck) {
- const QuicBandwidth local_bandwidth =
- QuicBandwidth::FromKBytesPerSecond(1000);
- const QuicBandwidth bottleneck_bandwidth = 0.1f * local_bandwidth;
- const QuicTime::Delta local_propagation_delay =
- QuicTime::Delta::FromMilliseconds(1);
- const QuicTime::Delta bottleneck_propagation_delay =
- QuicTime::Delta::FromMilliseconds(20);
- const QuicByteCount bdp =
- bottleneck_bandwidth *
- (local_propagation_delay + bottleneck_propagation_delay);
-
- Simulator simulator;
- LinkSaturator saturator(&simulator, "Saturator", 1000, "Counter");
- ASSERT_GE(bdp, 1000u);
- Queue queue(&simulator, "Queue", bdp);
- CounterPort counter;
-
- OneWayLink local_link(&simulator, "Local link", &queue, local_bandwidth,
- local_propagation_delay);
- OneWayLink bottleneck_link(&simulator, "Bottleneck link", &counter,
- bottleneck_bandwidth,
- bottleneck_propagation_delay);
- saturator.SetTxPort(&local_link);
- queue.set_tx_port(&bottleneck_link);
-
- static const QuicPacketCount packets_received = 1000;
- simulator.RunUntil(
- [&counter]() { return counter.packets() == packets_received; });
- const double loss_ratio = 1 - static_cast<double>(packets_received) /
- saturator.packets_transmitted();
- EXPECT_NEAR(loss_ratio, 0.9, 0.001);
-}
-
-// Verify that the queue of exactly one packet allows the transmission to
-// actually go through.
-TEST_F(SimulatorTest, OnePacketQueue) {
- const QuicBandwidth local_bandwidth =
- QuicBandwidth::FromKBytesPerSecond(1000);
- const QuicBandwidth bottleneck_bandwidth = 0.1f * local_bandwidth;
- const QuicTime::Delta local_propagation_delay =
- QuicTime::Delta::FromMilliseconds(1);
- const QuicTime::Delta bottleneck_propagation_delay =
- QuicTime::Delta::FromMilliseconds(20);
-
- Simulator simulator;
- LinkSaturator saturator(&simulator, "Saturator", 1000, "Counter");
- Queue queue(&simulator, "Queue", 1000);
- CounterPort counter;
-
- OneWayLink local_link(&simulator, "Local link", &queue, local_bandwidth,
- local_propagation_delay);
- OneWayLink bottleneck_link(&simulator, "Bottleneck link", &counter,
- bottleneck_bandwidth,
- bottleneck_propagation_delay);
- saturator.SetTxPort(&local_link);
- queue.set_tx_port(&bottleneck_link);
-
- static const QuicPacketCount packets_received = 10;
- // The deadline here is to prevent this tests from looping infinitely in case
- // the packets never reach the receiver.
- const QuicTime deadline =
- simulator.GetClock()->Now() + QuicTime::Delta::FromSeconds(10);
- simulator.RunUntil([&simulator, &counter, deadline]() {
- return counter.packets() == packets_received ||
- simulator.GetClock()->Now() > deadline;
- });
- ASSERT_EQ(packets_received, counter.packets());
-}
-
-// Simulate a network where three endpoints are connected to a switch and they
-// are sending traffic in circle (1 -> 2, 2 -> 3, 3 -> 1).
-TEST_F(SimulatorTest, SwitchedNetwork) {
- const QuicBandwidth bandwidth = QuicBandwidth::FromBytesPerSecond(10000);
- const QuicTime::Delta base_propagation_delay =
- QuicTime::Delta::FromMilliseconds(50);
-
- Simulator simulator;
- LinkSaturator saturator1(&simulator, "Saturator 1", 1000, "Saturator 2");
- LinkSaturator saturator2(&simulator, "Saturator 2", 1000, "Saturator 3");
- LinkSaturator saturator3(&simulator, "Saturator 3", 1000, "Saturator 1");
- Switch network_switch(&simulator, "Switch", 8,
- bandwidth * base_propagation_delay * 10);
-
- // For determinicity, make it so that the first packet will arrive from
- // Saturator 1, then from Saturator 2, and then from Saturator 3.
- SymmetricLink link1(&saturator1, network_switch.port(1), bandwidth,
- base_propagation_delay);
- SymmetricLink link2(&saturator2, network_switch.port(2), bandwidth,
- base_propagation_delay * 2);
- SymmetricLink link3(&saturator3, network_switch.port(3), bandwidth,
- base_propagation_delay * 3);
-
- const QuicTime start_time = simulator.GetClock()->Now();
- static const QuicPacketCount bytes_received = 64 * 1000;
- simulator.RunUntil([&saturator1]() {
- return saturator1.counter()->bytes() >= bytes_received;
- });
- const QuicTime end_time = simulator.GetClock()->Now();
-
- const QuicBandwidth observed_bandwidth = QuicBandwidth::FromBytesAndTimeDelta(
- bytes_received, end_time - start_time);
- const double bandwidth_ratio =
- static_cast<double>(observed_bandwidth.ToBitsPerSecond()) /
- bandwidth.ToBitsPerSecond();
- EXPECT_NEAR(1, bandwidth_ratio, 0.1);
-
- const double normalized_received_packets_for_saturator_2 =
- static_cast<double>(saturator2.counter()->packets()) /
- saturator1.counter()->packets();
- const double normalized_received_packets_for_saturator_3 =
- static_cast<double>(saturator3.counter()->packets()) /
- saturator1.counter()->packets();
- EXPECT_NEAR(1, normalized_received_packets_for_saturator_2, 0.1);
- EXPECT_NEAR(1, normalized_received_packets_for_saturator_3, 0.1);
-
- // Since Saturator 1 has its packet arrive first into the switch, switch will
- // always know how to route traffic to it.
- EXPECT_EQ(0u,
- saturator2.counter()->CountPacketsForDestination("Saturator 1"));
- EXPECT_EQ(0u,
- saturator3.counter()->CountPacketsForDestination("Saturator 1"));
-
- // Packets from the other saturators will be broadcast at least once.
- EXPECT_EQ(1u,
- saturator1.counter()->CountPacketsForDestination("Saturator 2"));
- EXPECT_EQ(1u,
- saturator3.counter()->CountPacketsForDestination("Saturator 2"));
- EXPECT_EQ(1u,
- saturator1.counter()->CountPacketsForDestination("Saturator 3"));
- EXPECT_EQ(1u,
- saturator2.counter()->CountPacketsForDestination("Saturator 3"));
-}
-
-// Toggle an alarm on and off at the specified interval. Assumes that alarm is
-// initially set and unsets it almost immediately after the object is
-// instantiated.
-class AlarmToggler : public Actor {
- public:
- AlarmToggler(Simulator* simulator,
- std::string name,
- QuicAlarm* alarm,
- QuicTime::Delta interval)
- : Actor(simulator, name),
- alarm_(alarm),
- interval_(interval),
- deadline_(alarm->deadline()),
- times_set_(0),
- times_cancelled_(0) {
- EXPECT_TRUE(alarm->IsSet());
- EXPECT_GE(alarm->deadline(), clock_->Now());
- Schedule(clock_->Now());
- }
-
- void Act() override {
- if (deadline_ <= clock_->Now()) {
- return;
- }
-
- if (alarm_->IsSet()) {
- alarm_->Cancel();
- times_cancelled_++;
- } else {
- alarm_->Set(deadline_);
- times_set_++;
- }
-
- Schedule(clock_->Now() + interval_);
- }
-
- inline int times_set() { return times_set_; }
- inline int times_cancelled() { return times_cancelled_; }
-
- private:
- QuicAlarm* alarm_;
- QuicTime::Delta interval_;
- QuicTime deadline_;
-
- // Counts the number of times the alarm was set.
- int times_set_;
- // Counts the number of times the alarm was cancelled.
- int times_cancelled_;
-};
-
-// Counts the number of times an alarm has fired.
-class CounterDelegate : public QuicAlarm::DelegateWithoutContext {
- public:
- explicit CounterDelegate(size_t* counter) : counter_(counter) {}
-
- void OnAlarm() override { *counter_ += 1; }
-
- private:
- size_t* counter_;
-};
-
-// Verifies that the alarms work correctly, even when they are repeatedly
-// toggled.
-TEST_F(SimulatorTest, Alarms) {
- Simulator simulator;
- QuicAlarmFactory* alarm_factory = simulator.GetAlarmFactory();
-
- size_t fast_alarm_counter = 0;
- size_t slow_alarm_counter = 0;
- std::unique_ptr<QuicAlarm> alarm_fast(
- alarm_factory->CreateAlarm(new CounterDelegate(&fast_alarm_counter)));
- std::unique_ptr<QuicAlarm> alarm_slow(
- alarm_factory->CreateAlarm(new CounterDelegate(&slow_alarm_counter)));
-
- const QuicTime start_time = simulator.GetClock()->Now();
- alarm_fast->Set(start_time + QuicTime::Delta::FromMilliseconds(100));
- alarm_slow->Set(start_time + QuicTime::Delta::FromMilliseconds(750));
- AlarmToggler toggler(&simulator, "Toggler", alarm_slow.get(),
- QuicTime::Delta::FromMilliseconds(100));
-
- const QuicTime end_time =
- start_time + QuicTime::Delta::FromMilliseconds(1000);
- EXPECT_FALSE(simulator.RunUntil([&simulator, end_time]() {
- return simulator.GetClock()->Now() >= end_time;
- }));
- EXPECT_EQ(1u, slow_alarm_counter);
- EXPECT_EQ(1u, fast_alarm_counter);
-
- EXPECT_EQ(4, toggler.times_set());
- EXPECT_EQ(4, toggler.times_cancelled());
-}
-
-// Verifies that a cancelled alarm is never fired.
-TEST_F(SimulatorTest, AlarmCancelling) {
- Simulator simulator;
- QuicAlarmFactory* alarm_factory = simulator.GetAlarmFactory();
-
- size_t alarm_counter = 0;
- std::unique_ptr<QuicAlarm> alarm(
- alarm_factory->CreateAlarm(new CounterDelegate(&alarm_counter)));
-
- const QuicTime start_time = simulator.GetClock()->Now();
- const QuicTime alarm_at = start_time + QuicTime::Delta::FromMilliseconds(300);
- const QuicTime end_time = start_time + QuicTime::Delta::FromMilliseconds(400);
-
- alarm->Set(alarm_at);
- alarm->Cancel();
- EXPECT_FALSE(alarm->IsSet());
-
- EXPECT_FALSE(simulator.RunUntil([&simulator, end_time]() {
- return simulator.GetClock()->Now() >= end_time;
- }));
-
- EXPECT_FALSE(alarm->IsSet());
- EXPECT_EQ(0u, alarm_counter);
-}
-
-// Verifies that alarms can be scheduled into the past.
-TEST_F(SimulatorTest, AlarmInPast) {
- Simulator simulator;
- QuicAlarmFactory* alarm_factory = simulator.GetAlarmFactory();
-
- size_t alarm_counter = 0;
- std::unique_ptr<QuicAlarm> alarm(
- alarm_factory->CreateAlarm(new CounterDelegate(&alarm_counter)));
-
- const QuicTime start_time = simulator.GetClock()->Now();
- simulator.RunFor(QuicTime::Delta::FromMilliseconds(400));
-
- alarm->Set(start_time);
- simulator.RunFor(QuicTime::Delta::FromMilliseconds(1));
- EXPECT_FALSE(alarm->IsSet());
- EXPECT_EQ(1u, alarm_counter);
-}
-
-// Tests Simulator::RunUntilOrTimeout() interface.
-TEST_F(SimulatorTest, RunUntilOrTimeout) {
- Simulator simulator;
- bool simulation_result;
-
- // Count the number of seconds since the beginning of the simulation.
- Counter counter(&simulator, "counter", QuicTime::Delta::FromSeconds(1));
-
- // Ensure that the counter reaches the value of 10 given a 20 second deadline.
- simulation_result = simulator.RunUntilOrTimeout(
- [&counter]() { return counter.get_value() == 10; },
- QuicTime::Delta::FromSeconds(20));
- ASSERT_TRUE(simulation_result);
-
- // Ensure that the counter will not reach the value of 100 given that the
- // starting value is 10 and the deadline is 20 seconds.
- simulation_result = simulator.RunUntilOrTimeout(
- [&counter]() { return counter.get_value() == 100; },
- QuicTime::Delta::FromSeconds(20));
- ASSERT_FALSE(simulation_result);
-}
-
-// Tests Simulator::RunFor() interface.
-TEST_F(SimulatorTest, RunFor) {
- Simulator simulator;
-
- Counter counter(&simulator, "counter", QuicTime::Delta::FromSeconds(3));
-
- simulator.RunFor(QuicTime::Delta::FromSeconds(100));
-
- EXPECT_EQ(33, counter.get_value());
-}
-
-class MockPacketFilter : public PacketFilter {
- public:
- MockPacketFilter(Simulator* simulator, std::string name, Endpoint* endpoint)
- : PacketFilter(simulator, name, endpoint) {}
- MOCK_METHOD(bool, FilterPacket, (const Packet&), (override));
-};
-
-// Set up two trivial packet filters, one allowing any packets, and one dropping
-// all of them.
-TEST_F(SimulatorTest, PacketFilter) {
- const QuicBandwidth bandwidth =
- QuicBandwidth::FromBytesPerSecond(1024 * 1024);
- const QuicTime::Delta base_propagation_delay =
- QuicTime::Delta::FromMilliseconds(5);
-
- Simulator simulator;
- LinkSaturator saturator_a(&simulator, "Saturator A", 1000, "Saturator B");
- LinkSaturator saturator_b(&simulator, "Saturator B", 1000, "Saturator A");
-
- // Attach packets to the switch to create a delay between the point at which
- // the packet is generated and the point at which it is filtered. Note that
- // if the saturators were connected directly, the link would be always
- // available for the endpoint which has all of its packets dropped, resulting
- // in saturator looping infinitely.
- Switch network_switch(&simulator, "Switch", 8,
- bandwidth * base_propagation_delay * 10);
- StrictMock<MockPacketFilter> a_to_b_filter(&simulator, "A -> B filter",
- network_switch.port(1));
- StrictMock<MockPacketFilter> b_to_a_filter(&simulator, "B -> A filter",
- network_switch.port(2));
- SymmetricLink link_a(&a_to_b_filter, &saturator_b, bandwidth,
- base_propagation_delay);
- SymmetricLink link_b(&b_to_a_filter, &saturator_a, bandwidth,
- base_propagation_delay);
-
- // Allow packets from A to B, but not from B to A.
- EXPECT_CALL(a_to_b_filter, FilterPacket(_)).WillRepeatedly(Return(true));
- EXPECT_CALL(b_to_a_filter, FilterPacket(_)).WillRepeatedly(Return(false));
-
- // Run the simulation for a while, and expect that only B will receive any
- // packets.
- simulator.RunFor(QuicTime::Delta::FromSeconds(10));
- EXPECT_GE(saturator_b.counter()->packets(), 1u);
- EXPECT_EQ(saturator_a.counter()->packets(), 0u);
-}
-
-// Set up a traffic policer in one direction that throttles at 25% of link
-// bandwidth, and put two link saturators at each endpoint.
-TEST_F(SimulatorTest, TrafficPolicer) {
- const QuicBandwidth bandwidth =
- QuicBandwidth::FromBytesPerSecond(1024 * 1024);
- const QuicTime::Delta base_propagation_delay =
- QuicTime::Delta::FromMilliseconds(5);
- const QuicTime::Delta timeout = QuicTime::Delta::FromSeconds(10);
-
- Simulator simulator;
- LinkSaturator saturator1(&simulator, "Saturator 1", 1000, "Saturator 2");
- LinkSaturator saturator2(&simulator, "Saturator 2", 1000, "Saturator 1");
- Switch network_switch(&simulator, "Switch", 8,
- bandwidth * base_propagation_delay * 10);
-
- static const QuicByteCount initial_burst = 1000 * 10;
- static const QuicByteCount max_bucket_size = 1000 * 100;
- static const QuicBandwidth target_bandwidth = bandwidth * 0.25;
- TrafficPolicer policer(&simulator, "Policer", initial_burst, max_bucket_size,
- target_bandwidth, network_switch.port(2));
-
- SymmetricLink link1(&saturator1, network_switch.port(1), bandwidth,
- base_propagation_delay);
- SymmetricLink link2(&saturator2, &policer, bandwidth, base_propagation_delay);
-
- // Ensure the initial burst passes without being dropped at all.
- bool simulator_result = simulator.RunUntilOrTimeout(
- [&saturator1]() {
- return saturator1.bytes_transmitted() == initial_burst;
- },
- timeout);
- ASSERT_TRUE(simulator_result);
- saturator1.Pause();
- simulator_result = simulator.RunUntilOrTimeout(
- [&saturator2]() {
- return saturator2.counter()->bytes() == initial_burst;
- },
- timeout);
- ASSERT_TRUE(simulator_result);
- saturator1.Resume();
-
- // Run for some time so that the initial burst is not visible.
- const QuicTime::Delta simulation_time = QuicTime::Delta::FromSeconds(10);
- simulator.RunFor(simulation_time);
-
- // Ensure we've transmitted the amount of data we expected.
- for (auto* saturator : {&saturator1, &saturator2}) {
- EXPECT_APPROX_EQ(bandwidth * simulation_time,
- saturator->bytes_transmitted(), 0.01f);
- }
-
- // Check that only one direction is throttled.
- EXPECT_APPROX_EQ(saturator1.bytes_transmitted() / 4,
- saturator2.counter()->bytes(), 0.1f);
- EXPECT_APPROX_EQ(saturator2.bytes_transmitted(),
- saturator1.counter()->bytes(), 0.1f);
-}
-
-// Ensure that a larger burst is allowed when the policed saturator exits
-// quiescence.
-TEST_F(SimulatorTest, TrafficPolicerBurst) {
- const QuicBandwidth bandwidth =
- QuicBandwidth::FromBytesPerSecond(1024 * 1024);
- const QuicTime::Delta base_propagation_delay =
- QuicTime::Delta::FromMilliseconds(5);
- const QuicTime::Delta timeout = QuicTime::Delta::FromSeconds(10);
-
- Simulator simulator;
- LinkSaturator saturator1(&simulator, "Saturator 1", 1000, "Saturator 2");
- LinkSaturator saturator2(&simulator, "Saturator 2", 1000, "Saturator 1");
- Switch network_switch(&simulator, "Switch", 8,
- bandwidth * base_propagation_delay * 10);
-
- const QuicByteCount initial_burst = 1000 * 10;
- const QuicByteCount max_bucket_size = 1000 * 100;
- const QuicBandwidth target_bandwidth = bandwidth * 0.25;
- TrafficPolicer policer(&simulator, "Policer", initial_burst, max_bucket_size,
- target_bandwidth, network_switch.port(2));
-
- SymmetricLink link1(&saturator1, network_switch.port(1), bandwidth,
- base_propagation_delay);
- SymmetricLink link2(&saturator2, &policer, bandwidth, base_propagation_delay);
-
- // Ensure at least one packet is sent on each side.
- bool simulator_result = simulator.RunUntilOrTimeout(
- [&saturator1, &saturator2]() {
- return saturator1.packets_transmitted() > 0 &&
- saturator2.packets_transmitted() > 0;
- },
- timeout);
- ASSERT_TRUE(simulator_result);
-
- // Wait until the bucket fills up.
- saturator1.Pause();
- saturator2.Pause();
- simulator.RunFor(1.5f * target_bandwidth.TransferTime(max_bucket_size));
-
- // Send a burst.
- saturator1.Resume();
- simulator.RunFor(bandwidth.TransferTime(max_bucket_size));
- saturator1.Pause();
- simulator.RunFor(2 * base_propagation_delay);
-
- // Expect the burst to pass without losses.
- EXPECT_APPROX_EQ(saturator1.bytes_transmitted(),
- saturator2.counter()->bytes(), 0.1f);
-
- // Expect subsequent traffic to be policed.
- saturator1.Resume();
- simulator.RunFor(QuicTime::Delta::FromSeconds(10));
- EXPECT_APPROX_EQ(saturator1.bytes_transmitted() / 4,
- saturator2.counter()->bytes(), 0.1f);
-}
-
-// Test that the packet aggregation support in queues work.
-TEST_F(SimulatorTest, PacketAggregation) {
- // Model network where the delays are dominated by transfer delay.
- const QuicBandwidth bandwidth = QuicBandwidth::FromBytesPerSecond(1000);
- const QuicTime::Delta base_propagation_delay =
- QuicTime::Delta::FromMicroseconds(1);
- const QuicByteCount aggregation_threshold = 1000;
- const QuicTime::Delta aggregation_timeout = QuicTime::Delta::FromSeconds(30);
-
- Simulator simulator;
- LinkSaturator saturator1(&simulator, "Saturator 1", 10, "Saturator 2");
- LinkSaturator saturator2(&simulator, "Saturator 2", 10, "Saturator 1");
- Switch network_switch(&simulator, "Switch", 8, 10 * aggregation_threshold);
-
- // Make links with asymmetric propagation delay so that Saturator 2 only
- // receives packets addressed to it.
- SymmetricLink link1(&saturator1, network_switch.port(1), bandwidth,
- base_propagation_delay);
- SymmetricLink link2(&saturator2, network_switch.port(2), bandwidth,
- 2 * base_propagation_delay);
-
- // Enable aggregation in 1 -> 2 direction.
- Queue* queue = network_switch.port_queue(2);
- queue->EnableAggregation(aggregation_threshold, aggregation_timeout);
-
- // Enable aggregation in 2 -> 1 direction in a way that all packets are larger
- // than the threshold, so that aggregation is effectively a no-op.
- network_switch.port_queue(1)->EnableAggregation(5, aggregation_timeout);
-
- // Fill up the aggregation buffer up to 90% (900 bytes).
- simulator.RunFor(0.9 * bandwidth.TransferTime(aggregation_threshold));
- EXPECT_EQ(0u, saturator2.counter()->bytes());
-
- // Stop sending, ensure that given a timespan much shorter than timeout, the
- // packets remain in the queue.
- saturator1.Pause();
- saturator2.Pause();
- simulator.RunFor(QuicTime::Delta::FromSeconds(10));
- EXPECT_EQ(0u, saturator2.counter()->bytes());
- EXPECT_EQ(900u, queue->bytes_queued());
-
- // Ensure that all packets have reached the saturator not affected by
- // aggregation. Here, 10 extra bytes account for a misrouted packet in the
- // beginning.
- EXPECT_EQ(910u, saturator1.counter()->bytes());
-
- // Send 500 more bytes. Since the aggregation threshold is 1000 bytes, and
- // queue already has 900 bytes, 1000 bytes will be send and 400 will be in the
- // queue.
- saturator1.Resume();
- simulator.RunFor(0.5 * bandwidth.TransferTime(aggregation_threshold));
- saturator1.Pause();
- simulator.RunFor(QuicTime::Delta::FromSeconds(10));
- EXPECT_EQ(1000u, saturator2.counter()->bytes());
- EXPECT_EQ(400u, queue->bytes_queued());
-
- // Actually time out, and cause all of the data to be received.
- simulator.RunFor(aggregation_timeout);
- EXPECT_EQ(1400u, saturator2.counter()->bytes());
- EXPECT_EQ(0u, queue->bytes_queued());
-
- // Run saturator for a longer time, to ensure that the logic to cancel and
- // reset alarms works correctly.
- saturator1.Resume();
- simulator.RunFor(5.5 * bandwidth.TransferTime(aggregation_threshold));
- saturator1.Pause();
- simulator.RunFor(QuicTime::Delta::FromSeconds(10));
- EXPECT_EQ(6400u, saturator2.counter()->bytes());
- EXPECT_EQ(500u, queue->bytes_queued());
-
- // Time out again.
- simulator.RunFor(aggregation_timeout);
- EXPECT_EQ(6900u, saturator2.counter()->bytes());
- EXPECT_EQ(0u, queue->bytes_queued());
-}
-
-} // namespace simulator
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/simulator/switch.cc b/chromium/net/third_party/quiche/src/quic/test_tools/simulator/switch.cc
deleted file mode 100644
index 3a8ee583fbd..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/simulator/switch.cc
+++ /dev/null
@@ -1,83 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <cinttypes>
-#include <utility>
-
-#include "absl/strings/str_cat.h"
-#include "quic/test_tools/simulator/switch.h"
-
-namespace quic {
-namespace simulator {
-
-Switch::Switch(Simulator* simulator,
- std::string name,
- SwitchPortNumber port_count,
- QuicByteCount queue_capacity) {
- for (size_t port_number = 1; port_number <= port_count; port_number++) {
- ports_.emplace_back(simulator,
- absl::StrCat(name, " (port ", port_number, ")"), this,
- port_number, queue_capacity);
- }
-}
-
-Switch::~Switch() {}
-
-Switch::Port::Port(Simulator* simulator,
- std::string name,
- Switch* parent,
- SwitchPortNumber port_number,
- QuicByteCount queue_capacity)
- : Endpoint(simulator, name),
- parent_(parent),
- port_number_(port_number),
- connected_(false),
- queue_(simulator, absl::StrCat(name, " (queue)"), queue_capacity) {}
-
-void Switch::Port::AcceptPacket(std::unique_ptr<Packet> packet) {
- parent_->DispatchPacket(port_number_, std::move(packet));
-}
-
-void Switch::Port::EnqueuePacket(std::unique_ptr<Packet> packet) {
- queue_.AcceptPacket(std::move(packet));
-}
-
-UnconstrainedPortInterface* Switch::Port::GetRxPort() {
- return this;
-}
-
-void Switch::Port::SetTxPort(ConstrainedPortInterface* port) {
- queue_.set_tx_port(port);
- connected_ = true;
-}
-
-void Switch::Port::Act() {}
-
-void Switch::DispatchPacket(SwitchPortNumber port_number,
- std::unique_ptr<Packet> packet) {
- Port* source_port = &ports_[port_number - 1];
- const auto source_mapping_it = switching_table_.find(packet->source);
- if (source_mapping_it == switching_table_.end()) {
- switching_table_.insert(std::make_pair(packet->source, source_port));
- }
-
- const auto destination_mapping_it =
- switching_table_.find(packet->destination);
- if (destination_mapping_it != switching_table_.end()) {
- destination_mapping_it->second->EnqueuePacket(std::move(packet));
- return;
- }
-
- // If no mapping is available yet, broadcast the packet to all ports
- // different from the source.
- for (Port& egress_port : ports_) {
- if (!egress_port.connected()) {
- continue;
- }
- egress_port.EnqueuePacket(std::make_unique<Packet>(*packet));
- }
-}
-
-} // namespace simulator
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/simulator/switch.h b/chromium/net/third_party/quiche/src/quic/test_tools/simulator/switch.h
deleted file mode 100644
index eebb47cba03..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/simulator/switch.h
+++ /dev/null
@@ -1,90 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_SIMULATOR_SWITCH_H_
-#define QUICHE_QUIC_TEST_TOOLS_SIMULATOR_SWITCH_H_
-
-#include <deque>
-
-#include "absl/container/flat_hash_map.h"
-#include "quic/platform/api/quic_containers.h"
-#include "quic/test_tools/simulator/queue.h"
-
-namespace quic {
-namespace simulator {
-
-using SwitchPortNumber = size_t;
-
-// Simulates a network switch with simple persistent learning scheme and queues
-// on every output port.
-class Switch {
- public:
- Switch(Simulator* simulator,
- std::string name,
- SwitchPortNumber port_count,
- QuicByteCount queue_capacity);
- Switch(const Switch&) = delete;
- Switch& operator=(const Switch&) = delete;
- ~Switch();
-
- // Returns Endpoint associated with the port under number |port_number|. Just
- // like on most real switches, port numbering starts with 1.
- inline Endpoint* port(SwitchPortNumber port_number) {
- QUICHE_DCHECK_NE(port_number, 0u);
- return &ports_[port_number - 1];
- }
-
- inline Queue* port_queue(SwitchPortNumber port_number) {
- return ports_[port_number - 1].queue();
- }
-
- private:
- class Port : public Endpoint, public UnconstrainedPortInterface {
- public:
- Port(Simulator* simulator,
- std::string name,
- Switch* parent,
- SwitchPortNumber port_number,
- QuicByteCount queue_capacity);
- Port(Port&&) = delete;
- Port(const Port&) = delete;
- Port& operator=(const Port&) = delete;
- ~Port() override {}
-
- // Accepts packet to be routed into the switch.
- void AcceptPacket(std::unique_ptr<Packet> packet) override;
- // Enqueue packet to be routed out of the switch.
- void EnqueuePacket(std::unique_ptr<Packet> packet);
-
- UnconstrainedPortInterface* GetRxPort() override;
- void SetTxPort(ConstrainedPortInterface* port) override;
-
- void Act() override;
-
- inline bool connected() const { return connected_; }
- inline Queue* queue() { return &queue_; }
-
- private:
- Switch* parent_;
- SwitchPortNumber port_number_;
- bool connected_;
-
- Queue queue_;
- };
-
- // Sends the packet to the appropriate port, or to all ports if the
- // appropriate port is not known.
- void DispatchPacket(SwitchPortNumber port_number,
- std::unique_ptr<Packet> packet);
-
- // This cannot be a quiche::QuicheCircularDeque since pointers into this are
- // assumed to be stable.
- std::deque<Port> ports_;
- absl::flat_hash_map<std::string, Port*> switching_table_;
-};
-
-} // namespace simulator
-} // namespace quic
-
-#endif // QUICHE_QUIC_TEST_TOOLS_SIMULATOR_SWITCH_H_
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/simulator/traffic_policer.cc b/chromium/net/third_party/quiche/src/quic/test_tools/simulator/traffic_policer.cc
deleted file mode 100644
index be62669d383..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/simulator/traffic_policer.cc
+++ /dev/null
@@ -1,60 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/simulator/traffic_policer.h"
-
-#include <algorithm>
-
-namespace quic {
-namespace simulator {
-
-TrafficPolicer::TrafficPolicer(Simulator* simulator,
- std::string name,
- QuicByteCount initial_bucket_size,
- QuicByteCount max_bucket_size,
- QuicBandwidth target_bandwidth,
- Endpoint* input)
- : PacketFilter(simulator, name, input),
- initial_bucket_size_(initial_bucket_size),
- max_bucket_size_(max_bucket_size),
- target_bandwidth_(target_bandwidth),
- last_refill_time_(clock_->Now()) {}
-
-TrafficPolicer::~TrafficPolicer() {}
-
-void TrafficPolicer::Refill() {
- QuicTime::Delta time_passed = clock_->Now() - last_refill_time_;
- QuicByteCount refill_size = time_passed * target_bandwidth_;
-
- for (auto& bucket : token_buckets_) {
- bucket.second = std::min(bucket.second + refill_size, max_bucket_size_);
- }
-
- last_refill_time_ = clock_->Now();
-}
-
-bool TrafficPolicer::FilterPacket(const Packet& packet) {
- // Refill existing buckets.
- Refill();
-
- // Create a new bucket if one does not exist.
- if (token_buckets_.count(packet.destination) == 0) {
- token_buckets_.insert(
- std::make_pair(packet.destination, initial_bucket_size_));
- }
-
- auto bucket = token_buckets_.find(packet.destination);
- QUICHE_DCHECK(bucket != token_buckets_.end());
-
- // Silently drop the packet on the floor if out of tokens
- if (bucket->second < packet.size) {
- return false;
- }
-
- bucket->second -= packet.size;
- return true;
-}
-
-} // namespace simulator
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/simulator/traffic_policer.h b/chromium/net/third_party/quiche/src/quic/test_tools/simulator/traffic_policer.h
deleted file mode 100644
index bba2b83d118..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/simulator/traffic_policer.h
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_SIMULATOR_TRAFFIC_POLICER_H_
-#define QUICHE_QUIC_TEST_TOOLS_SIMULATOR_TRAFFIC_POLICER_H_
-
-#include "absl/container/flat_hash_map.h"
-#include "quic/test_tools/simulator/packet_filter.h"
-#include "quic/test_tools/simulator/port.h"
-
-namespace quic {
-namespace simulator {
-
-// Traffic policer uses a token bucket to limit the bandwidth of the traffic
-// passing through. It wraps around an input port and exposes an output port.
-// Only the traffic from input to the output is policed, so in case when
-// bidirectional policing is desired, two policers have to be used. The flows
-// are hashed by the destination only.
-class TrafficPolicer : public PacketFilter {
- public:
- TrafficPolicer(Simulator* simulator,
- std::string name,
- QuicByteCount initial_bucket_size,
- QuicByteCount max_bucket_size,
- QuicBandwidth target_bandwidth,
- Endpoint* input);
- TrafficPolicer(const TrafficPolicer&) = delete;
- TrafficPolicer& operator=(const TrafficPolicer&) = delete;
- ~TrafficPolicer() override;
-
- protected:
- bool FilterPacket(const Packet& packet) override;
-
- private:
- // Refill the token buckets with all the tokens that have been granted since
- // |last_refill_time_|.
- void Refill();
-
- QuicByteCount initial_bucket_size_;
- QuicByteCount max_bucket_size_;
- QuicBandwidth target_bandwidth_;
-
- // The time at which the token buckets were last refilled.
- QuicTime last_refill_time_;
-
- // Maps each destination to the number of tokens it has left.
- absl::flat_hash_map<std::string, QuicByteCount> token_buckets_;
-};
-
-} // namespace simulator
-} // namespace quic
-
-#endif // QUICHE_QUIC_TEST_TOOLS_SIMULATOR_TRAFFIC_POLICER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/test_certificates.cc b/chromium/net/third_party/quiche/src/quic/test_tools/test_certificates.cc
deleted file mode 100644
index 91949914452..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/test_certificates.cc
+++ /dev/null
@@ -1,734 +0,0 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/test_certificates.h"
-
-namespace quic {
-namespace test {
-
-// A test certificate generated by //net/tools/quic/certs/generate-certs.sh.
-ABSL_CONST_INIT const char kTestCertificateRaw[] = {
- '\x30', '\x82', '\x03', '\xb4', '\x30', '\x82', '\x02', '\x9c', '\xa0',
- '\x03', '\x02', '\x01', '\x02', '\x02', '\x01', '\x01', '\x30', '\x0d',
- '\x06', '\x09', '\x2a', '\x86', '\x48', '\x86', '\xf7', '\x0d', '\x01',
- '\x01', '\x0b', '\x05', '\x00', '\x30', '\x1e', '\x31', '\x1c', '\x30',
- '\x1a', '\x06', '\x03', '\x55', '\x04', '\x03', '\x0c', '\x13', '\x51',
- '\x55', '\x49', '\x43', '\x20', '\x53', '\x65', '\x72', '\x76', '\x65',
- '\x72', '\x20', '\x52', '\x6f', '\x6f', '\x74', '\x20', '\x43', '\x41',
- '\x30', '\x1e', '\x17', '\x0d', '\x32', '\x30', '\x30', '\x31', '\x33',
- '\x30', '\x31', '\x38', '\x31', '\x33', '\x35', '\x39', '\x5a', '\x17',
- '\x0d', '\x32', '\x30', '\x30', '\x32', '\x30', '\x32', '\x31', '\x38',
- '\x31', '\x33', '\x35', '\x39', '\x5a', '\x30', '\x64', '\x31', '\x0b',
- '\x30', '\x09', '\x06', '\x03', '\x55', '\x04', '\x06', '\x13', '\x02',
- '\x55', '\x53', '\x31', '\x13', '\x30', '\x11', '\x06', '\x03', '\x55',
- '\x04', '\x08', '\x0c', '\x0a', '\x43', '\x61', '\x6c', '\x69', '\x66',
- '\x6f', '\x72', '\x6e', '\x69', '\x61', '\x31', '\x16', '\x30', '\x14',
- '\x06', '\x03', '\x55', '\x04', '\x07', '\x0c', '\x0d', '\x4d', '\x6f',
- '\x75', '\x6e', '\x74', '\x61', '\x69', '\x6e', '\x20', '\x56', '\x69',
- '\x65', '\x77', '\x31', '\x14', '\x30', '\x12', '\x06', '\x03', '\x55',
- '\x04', '\x0a', '\x0c', '\x0b', '\x51', '\x55', '\x49', '\x43', '\x20',
- '\x53', '\x65', '\x72', '\x76', '\x65', '\x72', '\x31', '\x12', '\x30',
- '\x10', '\x06', '\x03', '\x55', '\x04', '\x03', '\x0c', '\x09', '\x31',
- '\x32', '\x37', '\x2e', '\x30', '\x2e', '\x30', '\x2e', '\x31', '\x30',
- '\x82', '\x01', '\x22', '\x30', '\x0d', '\x06', '\x09', '\x2a', '\x86',
- '\x48', '\x86', '\xf7', '\x0d', '\x01', '\x01', '\x01', '\x05', '\x00',
- '\x03', '\x82', '\x01', '\x0f', '\x00', '\x30', '\x82', '\x01', '\x0a',
- '\x02', '\x82', '\x01', '\x01', '\x00', '\xc5', '\xe2', '\x51', '\x6d',
- '\x3f', '\xd6', '\x28', '\xf2', '\xad', '\x34', '\x73', '\x87', '\x64',
- '\xca', '\x33', '\x19', '\x33', '\xb7', '\x75', '\x91', '\xab', '\x31',
- '\x19', '\x2b', '\xe3', '\xa4', '\x26', '\x09', '\x29', '\x8b', '\x2d',
- '\xf7', '\x52', '\x75', '\xa7', '\x55', '\x15', '\xf0', '\x11', '\xc7',
- '\xc2', '\xc4', '\xed', '\x18', '\x1b', '\x33', '\x0b', '\x71', '\x32',
- '\xe6', '\x35', '\x89', '\xcd', '\x2d', '\x5a', '\x05', '\x57', '\x4e',
- '\xc2', '\x78', '\x75', '\x65', '\x72', '\x2d', '\x8a', '\x17', '\x83',
- '\xd6', '\x32', '\x90', '\x85', '\xf8', '\x22', '\xe2', '\x65', '\xa9',
- '\xe0', '\xa0', '\xfe', '\x19', '\xb2', '\x39', '\x2d', '\x14', '\x03',
- '\x10', '\x2f', '\xcc', '\x8b', '\x5e', '\xaa', '\x25', '\x27', '\x0d',
- '\xa3', '\x37', '\x10', '\x0c', '\x17', '\xec', '\xf0', '\x8b', '\xc5',
- '\x6b', '\xed', '\x6b', '\x5e', '\xb2', '\xe2', '\x35', '\x3e', '\x46',
- '\x3b', '\xf7', '\xf6', '\x59', '\xb1', '\xe0', '\x16', '\xa6', '\xfb',
- '\x03', '\xbf', '\x84', '\x4f', '\xce', '\x64', '\x15', '\x0d', '\x59',
- '\x99', '\xa6', '\xf0', '\x7f', '\x8a', '\x33', '\x4b', '\xbb', '\x0b',
- '\xb8', '\xf2', '\xd1', '\x27', '\x90', '\x8f', '\x38', '\xf8', '\x5a',
- '\x41', '\x82', '\x07', '\x9b', '\x0d', '\xd9', '\x52', '\xe0', '\x70',
- '\xff', '\xde', '\xda', '\xd8', '\x25', '\x4e', '\x2f', '\x2d', '\x9f',
- '\xaf', '\x92', '\x63', '\xc7', '\x42', '\xb4', '\xdc', '\x16', '\x95',
- '\x23', '\x05', '\x02', '\x6b', '\xb0', '\xe8', '\xc5', '\xfe', '\x15',
- '\x9a', '\xe8', '\x7d', '\x2f', '\xdc', '\x43', '\xf4', '\x70', '\x91',
- '\x1a', '\x93', '\xbe', '\x71', '\xaf', '\x85', '\x84', '\xdb', '\xcf',
- '\x6b', '\x5c', '\x80', '\xb2', '\xd3', '\xf3', '\x42', '\x6e', '\x24',
- '\xec', '\x2a', '\x62', '\x99', '\xc6', '\x3c', '\xe5', '\x32', '\xe5',
- '\x72', '\x37', '\x30', '\x9b', '\x0b', '\xe4', '\x06', '\xb4', '\x64',
- '\x26', '\x95', '\x59', '\xba', '\xf1', '\x53', '\x83', '\x3d', '\x99',
- '\x6d', '\xf0', '\x80', '\xe2', '\xdb', '\x6b', '\x34', '\x52', '\x06',
- '\x77', '\x3c', '\x73', '\xbe', '\xc6', '\xe3', '\xce', '\xb2', '\x11',
- '\x02', '\x03', '\x01', '\x00', '\x01', '\xa3', '\x81', '\xb6', '\x30',
- '\x81', '\xb3', '\x30', '\x0c', '\x06', '\x03', '\x55', '\x1d', '\x13',
- '\x01', '\x01', '\xff', '\x04', '\x02', '\x30', '\x00', '\x30', '\x1d',
- '\x06', '\x03', '\x55', '\x1d', '\x0e', '\x04', '\x16', '\x04', '\x14',
- '\xc8', '\x54', '\x28', '\xf6', '\xd2', '\xd5', '\x12', '\x35', '\x89',
- '\x15', '\x75', '\xb8', '\xbf', '\xdd', '\xfb', '\x4a', '\xfc', '\x6c',
- '\x89', '\xde', '\x30', '\x1f', '\x06', '\x03', '\x55', '\x1d', '\x23',
- '\x04', '\x18', '\x30', '\x16', '\x80', '\x14', '\x50', '\xe4', '\x1d',
- '\xc3', '\x1a', '\xfb', '\xfd', '\x38', '\xdd', '\xa2', '\x05', '\xfd',
- '\xc8', '\xfa', '\x57', '\x0a', '\xc1', '\x06', '\x0f', '\xae', '\x30',
- '\x1d', '\x06', '\x03', '\x55', '\x1d', '\x25', '\x04', '\x16', '\x30',
- '\x14', '\x06', '\x08', '\x2b', '\x06', '\x01', '\x05', '\x05', '\x07',
- '\x03', '\x01', '\x06', '\x08', '\x2b', '\x06', '\x01', '\x05', '\x05',
- '\x07', '\x03', '\x02', '\x30', '\x44', '\x06', '\x03', '\x55', '\x1d',
- '\x11', '\x04', '\x3d', '\x30', '\x3b', '\x82', '\x0f', '\x77', '\x77',
- '\x77', '\x2e', '\x65', '\x78', '\x61', '\x6d', '\x70', '\x6c', '\x65',
- '\x2e', '\x6f', '\x72', '\x67', '\x82', '\x10', '\x6d', '\x61', '\x69',
- '\x6c', '\x2e', '\x65', '\x78', '\x61', '\x6d', '\x70', '\x6c', '\x65',
- '\x2e', '\x6f', '\x72', '\x67', '\x82', '\x10', '\x6d', '\x61', '\x69',
- '\x6c', '\x2e', '\x65', '\x78', '\x61', '\x6d', '\x70', '\x6c', '\x65',
- '\x2e', '\x63', '\x6f', '\x6d', '\x87', '\x04', '\x7f', '\x00', '\x00',
- '\x01', '\x30', '\x0d', '\x06', '\x09', '\x2a', '\x86', '\x48', '\x86',
- '\xf7', '\x0d', '\x01', '\x01', '\x0b', '\x05', '\x00', '\x03', '\x82',
- '\x01', '\x01', '\x00', '\x45', '\x41', '\x7a', '\x68', '\xe0', '\xa7',
- '\x59', '\xa1', '\x62', '\x54', '\x73', '\x74', '\x14', '\x4f', '\xde',
- '\x9c', '\x51', '\xac', '\x25', '\x97', '\x70', '\xf7', '\x09', '\x51',
- '\x39', '\x72', '\x39', '\x3c', '\xd0', '\x31', '\xe1', '\xc3', '\x02',
- '\x91', '\x14', '\x4d', '\x8f', '\x1d', '\x31', '\xab', '\x98', '\x7e',
- '\xe6', '\xbb', '\xab', '\x6a', '\xd9', '\xc5', '\x86', '\xaa', '\x4e',
- '\x6a', '\x48', '\xe9', '\xf8', '\xd7', '\xb3', '\x1d', '\xa0', '\xc5',
- '\xe6', '\xbf', '\x4c', '\x5a', '\x9b', '\xb5', '\x78', '\x01', '\xa3',
- '\x39', '\x7b', '\x5f', '\xbc', '\xb8', '\xa7', '\xc2', '\x71', '\xb0',
- '\x7b', '\xdd', '\xa1', '\x87', '\xa6', '\x54', '\x9c', '\xf6', '\x59',
- '\x81', '\xb1', '\x2c', '\xde', '\xc5', '\x8a', '\xa2', '\x06', '\x89',
- '\xb5', '\xc1', '\x7a', '\xbe', '\x0c', '\x9f', '\x3d', '\xde', '\x81',
- '\x48', '\x53', '\x71', '\x7b', '\x8d', '\xc7', '\xea', '\x87', '\xd7',
- '\xd1', '\xda', '\x94', '\xb4', '\xc5', '\xac', '\x1e', '\x83', '\xa3',
- '\x42', '\x7d', '\xe6', '\xab', '\x3f', '\xd6', '\x1c', '\xd6', '\x65',
- '\xc3', '\x60', '\xe9', '\x76', '\x54', '\x79', '\x3f', '\xeb', '\x65',
- '\x85', '\x4f', '\x60', '\x7d', '\xbb', '\x96', '\x03', '\x54', '\x2e',
- '\xd0', '\x1b', '\xe2', '\x6c', '\x2d', '\x91', '\xae', '\x33', '\x9c',
- '\x04', '\xc4', '\x44', '\x0a', '\x7d', '\x5f', '\xbb', '\x80', '\xa2',
- '\x01', '\xbc', '\x90', '\x81', '\xa5', '\xdc', '\x4a', '\xc8', '\x77',
- '\xc9', '\x8d', '\x34', '\x17', '\xe6', '\x2a', '\x7d', '\x02', '\x1e',
- '\x32', '\x3f', '\x7d', '\xd7', '\x0c', '\x80', '\x5b', '\xc6', '\x94',
- '\x6a', '\x42', '\x36', '\x05', '\x9f', '\x9e', '\xc5', '\x85', '\x9f',
- '\x60', '\xe3', '\x72', '\x73', '\x34', '\x39', '\x44', '\x75', '\x55',
- '\x60', '\x24', '\x7a', '\x8b', '\x09', '\x74', '\x84', '\x72', '\xfd',
- '\x91', '\x68', '\x93', '\x57', '\x9e', '\x70', '\x46', '\x4d', '\xe4',
- '\x30', '\x84', '\x5f', '\x20', '\x07', '\xad', '\xfd', '\x86', '\x32',
- '\xd3', '\xfb', '\xba', '\xaf', '\xd9', '\x61', '\x14', '\x3c', '\xe0',
- '\xa1', '\xa9', '\x51', '\x51', '\x0f', '\xad', '\x60'};
-
-ABSL_CONST_INIT const absl::string_view kTestCertificate(
- kTestCertificateRaw,
- sizeof(kTestCertificateRaw));
-
-ABSL_CONST_INIT const char kTestCertificatePem[] =
- R"(Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number: 1 (0x1)
- Signature Algorithm: sha256WithRSAEncryption
- Issuer: CN=QUIC Server Root CA
- Validity
- Not Before: Jan 30 18:13:59 2020 GMT
- Not After : Feb 2 18:13:59 2020 GMT
- Subject: C=US, ST=California, L=Mountain View, O=QUIC Server, CN=127.0.0.1
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- RSA Public-Key: (2048 bit)
- Modulus:
- 00:c5:e2:51:6d:3f:d6:28:f2:ad:34:73:87:64:ca:
- 33:19:33:b7:75:91:ab:31:19:2b:e3:a4:26:09:29:
- 8b:2d:f7:52:75:a7:55:15:f0:11:c7:c2:c4:ed:18:
- 1b:33:0b:71:32:e6:35:89:cd:2d:5a:05:57:4e:c2:
- 78:75:65:72:2d:8a:17:83:d6:32:90:85:f8:22:e2:
- 65:a9:e0:a0:fe:19:b2:39:2d:14:03:10:2f:cc:8b:
- 5e:aa:25:27:0d:a3:37:10:0c:17:ec:f0:8b:c5:6b:
- ed:6b:5e:b2:e2:35:3e:46:3b:f7:f6:59:b1:e0:16:
- a6:fb:03:bf:84:4f:ce:64:15:0d:59:99:a6:f0:7f:
- 8a:33:4b:bb:0b:b8:f2:d1:27:90:8f:38:f8:5a:41:
- 82:07:9b:0d:d9:52:e0:70:ff:de:da:d8:25:4e:2f:
- 2d:9f:af:92:63:c7:42:b4:dc:16:95:23:05:02:6b:
- b0:e8:c5:fe:15:9a:e8:7d:2f:dc:43:f4:70:91:1a:
- 93:be:71:af:85:84:db:cf:6b:5c:80:b2:d3:f3:42:
- 6e:24:ec:2a:62:99:c6:3c:e5:32:e5:72:37:30:9b:
- 0b:e4:06:b4:64:26:95:59:ba:f1:53:83:3d:99:6d:
- f0:80:e2:db:6b:34:52:06:77:3c:73:be:c6:e3:ce:
- b2:11
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Basic Constraints: critical
- CA:FALSE
- X509v3 Subject Key Identifier:
- C8:54:28:F6:D2:D5:12:35:89:15:75:B8:BF:DD:FB:4A:FC:6C:89:DE
- X509v3 Authority Key Identifier:
- keyid:50:E4:1D:C3:1A:FB:FD:38:DD:A2:05:FD:C8:FA:57:0A:C1:06:0F:AE
-
- X509v3 Extended Key Usage:
- TLS Web Server Authentication, TLS Web Client Authentication
- X509v3 Subject Alternative Name:
- DNS:www.example.org, DNS:mail.example.org, DNS:mail.example.com, IP Address:127.0.0.1
- Signature Algorithm: sha256WithRSAEncryption
- 45:41:7a:68:e0:a7:59:a1:62:54:73:74:14:4f:de:9c:51:ac:
- 25:97:70:f7:09:51:39:72:39:3c:d0:31:e1:c3:02:91:14:4d:
- 8f:1d:31:ab:98:7e:e6:bb:ab:6a:d9:c5:86:aa:4e:6a:48:e9:
- f8:d7:b3:1d:a0:c5:e6:bf:4c:5a:9b:b5:78:01:a3:39:7b:5f:
- bc:b8:a7:c2:71:b0:7b:dd:a1:87:a6:54:9c:f6:59:81:b1:2c:
- de:c5:8a:a2:06:89:b5:c1:7a:be:0c:9f:3d:de:81:48:53:71:
- 7b:8d:c7:ea:87:d7:d1:da:94:b4:c5:ac:1e:83:a3:42:7d:e6:
- ab:3f:d6:1c:d6:65:c3:60:e9:76:54:79:3f:eb:65:85:4f:60:
- 7d:bb:96:03:54:2e:d0:1b:e2:6c:2d:91:ae:33:9c:04:c4:44:
- 0a:7d:5f:bb:80:a2:01:bc:90:81:a5:dc:4a:c8:77:c9:8d:34:
- 17:e6:2a:7d:02:1e:32:3f:7d:d7:0c:80:5b:c6:94:6a:42:36:
- 05:9f:9e:c5:85:9f:60:e3:72:73:34:39:44:75:55:60:24:7a:
- 8b:09:74:84:72:fd:91:68:93:57:9e:70:46:4d:e4:30:84:5f:
- 20:07:ad:fd:86:32:d3:fb:ba:af:d9:61:14:3c:e0:a1:a9:51:
- 51:0f:ad:60
------BEGIN CERTIFICATE-----
-MIIDtDCCApygAwIBAgIBATANBgkqhkiG9w0BAQsFADAeMRwwGgYDVQQDDBNRVUlD
-IFNlcnZlciBSb290IENBMB4XDTIwMDEzMDE4MTM1OVoXDTIwMDIwMjE4MTM1OVow
-ZDELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExFjAUBgNVBAcMDU1v
-dW50YWluIFZpZXcxFDASBgNVBAoMC1FVSUMgU2VydmVyMRIwEAYDVQQDDAkxMjcu
-MC4wLjEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDF4lFtP9Yo8q00
-c4dkyjMZM7d1kasxGSvjpCYJKYst91J1p1UV8BHHwsTtGBszC3Ey5jWJzS1aBVdO
-wnh1ZXItiheD1jKQhfgi4mWp4KD+GbI5LRQDEC/Mi16qJScNozcQDBfs8IvFa+1r
-XrLiNT5GO/f2WbHgFqb7A7+ET85kFQ1Zmabwf4ozS7sLuPLRJ5CPOPhaQYIHmw3Z
-UuBw/97a2CVOLy2fr5Jjx0K03BaVIwUCa7Doxf4Vmuh9L9xD9HCRGpO+ca+FhNvP
-a1yAstPzQm4k7CpimcY85TLlcjcwmwvkBrRkJpVZuvFTgz2ZbfCA4ttrNFIGdzxz
-vsbjzrIRAgMBAAGjgbYwgbMwDAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQUyFQo9tLV
-EjWJFXW4v937Svxsid4wHwYDVR0jBBgwFoAUUOQdwxr7/TjdogX9yPpXCsEGD64w
-HQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMEQGA1UdEQQ9MDuCD3d3dy5l
-eGFtcGxlLm9yZ4IQbWFpbC5leGFtcGxlLm9yZ4IQbWFpbC5leGFtcGxlLmNvbYcE
-fwAAATANBgkqhkiG9w0BAQsFAAOCAQEARUF6aOCnWaFiVHN0FE/enFGsJZdw9wlR
-OXI5PNAx4cMCkRRNjx0xq5h+5ruratnFhqpOakjp+NezHaDF5r9MWpu1eAGjOXtf
-vLinwnGwe92hh6ZUnPZZgbEs3sWKogaJtcF6vgyfPd6BSFNxe43H6ofX0dqUtMWs
-HoOjQn3mqz/WHNZlw2DpdlR5P+tlhU9gfbuWA1Qu0BvibC2RrjOcBMRECn1fu4Ci
-AbyQgaXcSsh3yY00F+YqfQIeMj991wyAW8aUakI2BZ+exYWfYONyczQ5RHVVYCR6
-iwl0hHL9kWiTV55wRk3kMIRfIAet/YYy0/u6r9lhFDzgoalRUQ+tYA==
------END CERTIFICATE-----)";
-
-// Same leaf as above, but with an intermediary attached.
-ABSL_CONST_INIT const char kTestCertificateChainPem[] =
- R"(-----BEGIN CERTIFICATE-----
-MIIDtDCCApygAwIBAgIBATANBgkqhkiG9w0BAQsFADAeMRwwGgYDVQQDDBNRVUlD
-IFNlcnZlciBSb290IENBMB4XDTIwMDEzMDE4MTM1OVoXDTIwMDIwMjE4MTM1OVow
-ZDELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExFjAUBgNVBAcMDU1v
-dW50YWluIFZpZXcxFDASBgNVBAoMC1FVSUMgU2VydmVyMRIwEAYDVQQDDAkxMjcu
-MC4wLjEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDF4lFtP9Yo8q00
-c4dkyjMZM7d1kasxGSvjpCYJKYst91J1p1UV8BHHwsTtGBszC3Ey5jWJzS1aBVdO
-wnh1ZXItiheD1jKQhfgi4mWp4KD+GbI5LRQDEC/Mi16qJScNozcQDBfs8IvFa+1r
-XrLiNT5GO/f2WbHgFqb7A7+ET85kFQ1Zmabwf4ozS7sLuPLRJ5CPOPhaQYIHmw3Z
-UuBw/97a2CVOLy2fr5Jjx0K03BaVIwUCa7Doxf4Vmuh9L9xD9HCRGpO+ca+FhNvP
-a1yAstPzQm4k7CpimcY85TLlcjcwmwvkBrRkJpVZuvFTgz2ZbfCA4ttrNFIGdzxz
-vsbjzrIRAgMBAAGjgbYwgbMwDAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQUyFQo9tLV
-EjWJFXW4v937Svxsid4wHwYDVR0jBBgwFoAUUOQdwxr7/TjdogX9yPpXCsEGD64w
-HQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMEQGA1UdEQQ9MDuCD3d3dy5l
-eGFtcGxlLm9yZ4IQbWFpbC5leGFtcGxlLm9yZ4IQbWFpbC5leGFtcGxlLmNvbYcE
-fwAAATANBgkqhkiG9w0BAQsFAAOCAQEARUF6aOCnWaFiVHN0FE/enFGsJZdw9wlR
-OXI5PNAx4cMCkRRNjx0xq5h+5ruratnFhqpOakjp+NezHaDF5r9MWpu1eAGjOXtf
-vLinwnGwe92hh6ZUnPZZgbEs3sWKogaJtcF6vgyfPd6BSFNxe43H6ofX0dqUtMWs
-HoOjQn3mqz/WHNZlw2DpdlR5P+tlhU9gfbuWA1Qu0BvibC2RrjOcBMRECn1fu4Ci
-AbyQgaXcSsh3yY00F+YqfQIeMj991wyAW8aUakI2BZ+exYWfYONyczQ5RHVVYCR6
-iwl0hHL9kWiTV55wRk3kMIRfIAet/YYy0/u6r9lhFDzgoalRUQ+tYA==
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIDDDCCAfSgAwIBAgIUfVS7RH+aVGqZhrjyuyD4qCnTS+MwDQYJKoZIhvcNAQEL
-BQAwHjEcMBoGA1UEAwwTUVVJQyBTZXJ2ZXIgUm9vdCBDQTAeFw0yMDAxMzAxODEz
-NTlaFw0yMDAyMDIxODEzNTlaMB4xHDAaBgNVBAMME1FVSUMgU2VydmVyIFJvb3Qg
-Q0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCc3k0GGpCBf6jXHxia
-QM4ntB6pWkT+NbaZUNHb1SkG2Cp9dN5dEKOXiqOi9306j4WNWTq/q0Ku9lCPPPFs
-JTIVC3tKY8Nbiczw+mohgW4rwLgpAP5rjjVzTxSFpDWZlgkH54HpqLjJFVl4Fklg
-vzSj+rYfqP+ueesi7z7KwPwzd30jjsJlpr2rlkZkidWT5vRTD3uYhNOW7IIT0lRP
-MDTwdxTEU5unyxESAsZyckNuJDeNF0y1Aw5Xiw/Bww+CyRH+tX6OUcWNtA+ZSDU8
-oVH5m4rxYK/DaHAZrA672/ywvUcPQaNaRxsAWRVjhktgyGPT3pjqiHDCN8+42uhH
-SgrbAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFFDkHcMa+/04
-3aIF/cj6VwrBBg+uMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAQEA
-iX+tn1Zfxx4M5YqZlPgXFB219agrJP2vM0fzW0E4zqDvA2ALaQN+lwdnFueN3tDk
-3IJvxd2W5k1Qh7LqWFUbBghDAP43XffW/yNy0+nuR2n3nRYdNStSMrGQm7oywhBd
-5jQl0GQUyYf1jcbD76HA5JraBjEXnQyJe6gJYHiRiMaMURWyzcngOPv5w3XBzIe3
-sRM0Rk/TTZP1Qx7fDY3ikFe1w9LzAMGbKDTKfc1+F0GZByJ3pdWakUNXZvtGFhIF
-hTXMooR/wD7an6gtnXD8ixCh7bP0TyPiBhNsUb12WrvSEAm/UyciQbQlR7P+K0Z7
-Cmn1Mj4hQ+pT0t+pw/DMOw==
------END CERTIFICATE-----)";
-
-ABSL_CONST_INIT const char kTestCertWithUnknownSanTypePem[] =
- R"(-----BEGIN CERTIFICATE-----
-MIIEYTCCA0mgAwIBAgIJAILStmLgUUcVMA0GCSqGSIb3DQEBCwUAMHYxCzAJBgNV
-BAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQHDA1TYW4gRnJhbmNp
-c2NvMQ0wCwYDVQQKDARMeWZ0MRkwFwYDVQQLDBBMeWZ0IEVuZ2luZWVyaW5nMRAw
-DgYDVQQDDAdUZXN0IENBMB4XDTE4MTIxNzIwMTgwMFoXDTIwMTIxNjIwMTgwMFow
-gaYxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQHDA1T
-YW4gRnJhbmNpc2NvMQ0wCwYDVQQKDARMeWZ0MRkwFwYDVQQLDBBMeWZ0IEVuZ2lu
-ZWVyaW5nMRowGAYDVQQDDBFUZXN0IEJhY2tlbmQgVGVhbTEkMCIGCSqGSIb3DQEJ
-ARYVYmFja2VuZC10ZWFtQGx5ZnQuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
-MIIBCgKCAQEAuvPdQdmwZongPAgQho/Vipd3PZWrQ6BKxIb4l/RvqtVP321IUTLs
-4vVwpXoYJ+12L+XOO3jCInszs53tHjFpTI1GE8/sasmgR6LRr2krwSoVRHPqUoc9
-tzkDG1SzKP2TRTi1MTI3FO+TnLFahntO9Zstxhv1Epz5GZ/xQLE0/LLoRYzcynL/
-iflk18iL1KM8i0Hy4cKjclOaUdnh2nh753iJfxCSb5wJfx4FH1qverYHHT6FopYR
-V40Cg0yYXcYo8yNwrg+EBY8QAT2JOMDokXNKbZpmVKiBlh0QYMX6BBiW249v3sYl
-3Ve+fZvCkle3W0xP0xJw8PdX0NRbvGOrBQIDAQABo4HAMIG9MAwGA1UdEwEB/wQC
-MAAwCwYDVR0PBAQDAgXgMB0GA1UdJQQWMBQGCCsGAQUFBwMCBggrBgEFBQcDATBB
-BgNVHREEOjA4hh5zcGlmZmU6Ly9seWZ0LmNvbS9iYWNrZW5kLXRlYW2CCGx5ZnQu
-Y29tggx3d3cubHlmdC5jb20wHQYDVR0OBBYEFLHmMm0DV9jCHJSWVRwyPYpBw62r
-MB8GA1UdIwQYMBaAFBQz1vaSbPuePL++7GTMqLAMtk3kMA0GCSqGSIb3DQEBCwUA
-A4IBAQAwx3/M2o00W8GlQ3OT4y/hQGb5K2aytxx8QeSmJaaZTJbvaHhe0x3/fLgq
-uWrW3WEWFtwasilySjOrFOtB9UNmJmNOHSJD3Bslbv5htRaWnoFPCXdwZtVMdoTq
-IHIQqLoos/xj3kVD5sJSYySrveMeKaeUILTkb5ZubSivye1X2yiJLR7AtuwuiMio
-CdIOqhn6xJqYhT7z0IhdKpLNPk4w1tBZSKOXqzrXS4uoJgTC67hWslWWZ2VC6IvZ
-FmKuuGZamCCj6F1QF2IjMVM8evl84hEnN0ajdkA/QWnil9kcWvBm15Ho+oTvvJ7s
-M8MD3RDSq/90FSiME4vbyNEyTmj0
------END CERTIFICATE-----)";
-
-ABSL_CONST_INIT const char kTestCertificatePrivateKeyRaw[] = {
- '\x30', '\x82', '\x04', '\xbc', '\x02', '\x01', '\x00', '\x30', '\x0d',
- '\x06', '\x09', '\x2a', '\x86', '\x48', '\x86', '\xf7', '\x0d', '\x01',
- '\x01', '\x01', '\x05', '\x00', '\x04', '\x82', '\x04', '\xa6', '\x30',
- '\x82', '\x04', '\xa2', '\x02', '\x01', '\x00', '\x02', '\x82', '\x01',
- '\x01', '\x00', '\xc5', '\xe2', '\x51', '\x6d', '\x3f', '\xd6', '\x28',
- '\xf2', '\xad', '\x34', '\x73', '\x87', '\x64', '\xca', '\x33', '\x19',
- '\x33', '\xb7', '\x75', '\x91', '\xab', '\x31', '\x19', '\x2b', '\xe3',
- '\xa4', '\x26', '\x09', '\x29', '\x8b', '\x2d', '\xf7', '\x52', '\x75',
- '\xa7', '\x55', '\x15', '\xf0', '\x11', '\xc7', '\xc2', '\xc4', '\xed',
- '\x18', '\x1b', '\x33', '\x0b', '\x71', '\x32', '\xe6', '\x35', '\x89',
- '\xcd', '\x2d', '\x5a', '\x05', '\x57', '\x4e', '\xc2', '\x78', '\x75',
- '\x65', '\x72', '\x2d', '\x8a', '\x17', '\x83', '\xd6', '\x32', '\x90',
- '\x85', '\xf8', '\x22', '\xe2', '\x65', '\xa9', '\xe0', '\xa0', '\xfe',
- '\x19', '\xb2', '\x39', '\x2d', '\x14', '\x03', '\x10', '\x2f', '\xcc',
- '\x8b', '\x5e', '\xaa', '\x25', '\x27', '\x0d', '\xa3', '\x37', '\x10',
- '\x0c', '\x17', '\xec', '\xf0', '\x8b', '\xc5', '\x6b', '\xed', '\x6b',
- '\x5e', '\xb2', '\xe2', '\x35', '\x3e', '\x46', '\x3b', '\xf7', '\xf6',
- '\x59', '\xb1', '\xe0', '\x16', '\xa6', '\xfb', '\x03', '\xbf', '\x84',
- '\x4f', '\xce', '\x64', '\x15', '\x0d', '\x59', '\x99', '\xa6', '\xf0',
- '\x7f', '\x8a', '\x33', '\x4b', '\xbb', '\x0b', '\xb8', '\xf2', '\xd1',
- '\x27', '\x90', '\x8f', '\x38', '\xf8', '\x5a', '\x41', '\x82', '\x07',
- '\x9b', '\x0d', '\xd9', '\x52', '\xe0', '\x70', '\xff', '\xde', '\xda',
- '\xd8', '\x25', '\x4e', '\x2f', '\x2d', '\x9f', '\xaf', '\x92', '\x63',
- '\xc7', '\x42', '\xb4', '\xdc', '\x16', '\x95', '\x23', '\x05', '\x02',
- '\x6b', '\xb0', '\xe8', '\xc5', '\xfe', '\x15', '\x9a', '\xe8', '\x7d',
- '\x2f', '\xdc', '\x43', '\xf4', '\x70', '\x91', '\x1a', '\x93', '\xbe',
- '\x71', '\xaf', '\x85', '\x84', '\xdb', '\xcf', '\x6b', '\x5c', '\x80',
- '\xb2', '\xd3', '\xf3', '\x42', '\x6e', '\x24', '\xec', '\x2a', '\x62',
- '\x99', '\xc6', '\x3c', '\xe5', '\x32', '\xe5', '\x72', '\x37', '\x30',
- '\x9b', '\x0b', '\xe4', '\x06', '\xb4', '\x64', '\x26', '\x95', '\x59',
- '\xba', '\xf1', '\x53', '\x83', '\x3d', '\x99', '\x6d', '\xf0', '\x80',
- '\xe2', '\xdb', '\x6b', '\x34', '\x52', '\x06', '\x77', '\x3c', '\x73',
- '\xbe', '\xc6', '\xe3', '\xce', '\xb2', '\x11', '\x02', '\x03', '\x01',
- '\x00', '\x01', '\x02', '\x82', '\x01', '\x00', '\x39', '\x75', '\xac',
- '\x1b', '\x43', '\x0c', '\x16', '\xbb', '\xd0', '\xdb', '\x88', '\x28',
- '\x6a', '\x75', '\xe4', '\x3c', '\x8f', '\x2d', '\xd8', '\x6f', '\xc1',
- '\xfb', '\xf1', '\xc9', '\x32', '\xc2', '\xb9', '\x60', '\xb3', '\xb5',
- '\x7c', '\x55', '\x72', '\x96', '\x43', '\x4e', '\x8b', '\x9e', '\x38',
- '\x2b', '\x7f', '\x3c', '\xdb', '\x73', '\xc2', '\x82', '\x21', '\xf2',
- '\x6e', '\xcb', '\x36', '\x04', '\x9b', '\x95', '\x6d', '\xac', '\x5b',
- '\x5b', '\xbd', '\x50', '\x69', '\x16', '\x59', '\xff', '\x2b', '\x38',
- '\x04', '\xca', '\x2f', '\xc8', '\x93', '\x7e', '\x27', '\xf3', '\x01',
- '\x7e', '\x40', '\x81', '\xbf', '\x07', '\x0b', '\x1f', '\x5b', '\x1d',
- '\x92', '\x7e', '\x22', '\xc3', '\x0c', '\x3d', '\x22', '\xbe', '\xc3',
- '\x06', '\x4c', '\xbc', '\x72', '\x66', '\x70', '\x94', '\x16', '\x8d',
- '\x1f', '\x78', '\x65', '\x6a', '\x66', '\x07', '\x1f', '\x74', '\x42',
- '\x6e', '\xf6', '\x7e', '\xdc', '\x03', '\xd3', '\x88', '\xb4', '\x4b',
- '\x2c', '\x5c', '\x3c', '\x42', '\x59', '\x42', '\x1f', '\x01', '\x13',
- '\x31', '\xc5', '\x22', '\xe7', '\x6a', '\x96', '\xf2', '\xfb', '\x66',
- '\xfe', '\xc8', '\xa1', '\x7e', '\x24', '\x96', '\x5f', '\x02', '\xee',
- '\x38', '\x21', '\xa5', '\x14', '\xd2', '\xa6', '\x35', '\x70', '\x6c',
- '\x8d', '\xa6', '\xd8', '\x2a', '\xd2', '\x45', '\x31', '\x5f', '\x67',
- '\x9e', '\x35', '\x57', '\x6a', '\xc4', '\x15', '\xe7', '\xba', '\x60',
- '\x2f', '\x8e', '\x52', '\x4e', '\xfc', '\x6f', '\xa0', '\x08', '\x91',
- '\x31', '\x71', '\x06', '\x68', '\x19', '\x48', '\xc7', '\x81', '\x0d',
- '\x5e', '\x52', '\x93', '\x57', '\xcc', '\xfe', '\x46', '\xac', '\xa9',
- '\x4f', '\xe2', '\x96', '\x4f', '\xaf', '\x12', '\xfb', '\xc2', '\x4b',
- '\xc4', '\x8d', '\x3b', '\xb0', '\x38', '\xe4', '\xbb', '\x8d', '\x19',
- '\x81', '\xe4', '\x74', '\x63', '\x9c', '\x8d', '\xaa', '\x84', '\x82',
- '\x91', '\xdf', '\xdc', '\x45', '\xf0', '\x39', '\xb2', '\xb4', '\xac',
- '\x45', '\xda', '\x3f', '\x30', '\x4d', '\x46', '\xb1', '\xe1', '\xb2',
- '\x9d', '\xdf', '\xd8', '\xc4', '\xa2', '\xef', '\xe9', '\x1a', '\x97',
- '\x79', '\x02', '\x81', '\x81', '\x00', '\xe5', '\x23', '\xb8', '\xd7',
- '\x09', '\x54', '\x54', '\x3b', '\xb6', '\x78', '\x78', '\x67', '\x57',
- '\x65', '\xc5', '\xd4', '\x74', '\xaf', '\x05', '\x4f', '\xb5', '\xc8',
- '\x8c', '\x1b', '\xd1', '\x9a', '\x2c', '\xd6', '\xe4', '\x68', '\xd1',
- '\xaf', '\x3d', '\x72', '\x42', '\x50', '\xc8', '\xdd', '\xb1', '\xee',
- '\x77', '\x52', '\xb8', '\xb1', '\x31', '\xbe', '\xf0', '\x74', '\x78',
- '\x42', '\x59', '\xea', '\x13', '\x8b', '\x82', '\x00', '\x54', '\x22',
- '\xd2', '\x0a', '\x24', '\xb0', '\x1f', '\x1e', '\x76', '\x27', '\xae',
- '\x63', '\xc6', '\x6b', '\x59', '\x28', '\x1d', '\xa0', '\x9f', '\x42',
- '\x30', '\xf1', '\xe3', '\x59', '\x1c', '\x4f', '\x31', '\x49', '\xff',
- '\x45', '\x7e', '\x6b', '\xef', '\xe9', '\x6f', '\xde', '\xaf', '\x1e',
- '\x04', '\x96', '\x61', '\x4e', '\x9f', '\x58', '\xf5', '\x0d', '\x64',
- '\x08', '\x48', '\x0a', '\xae', '\xac', '\xe4', '\x76', '\x91', '\xdd',
- '\x6e', '\x33', '\x97', '\xc5', '\x96', '\xda', '\xff', '\xbc', '\x42',
- '\x5b', '\x71', '\xb5', '\x76', '\xae', '\x01', '\xb3', '\x02', '\x81',
- '\x81', '\x00', '\xdd', '\x14', '\xa5', '\x6c', '\x89', '\x2b', '\x80',
- '\x78', '\xf6', '\xc3', '\x80', '\x4d', '\x53', '\x54', '\xb3', '\x2b',
- '\x40', '\xce', '\x98', '\x16', '\xa0', '\xbf', '\x72', '\xf1', '\xe3',
- '\xdc', '\xe9', '\x0b', '\x45', '\x23', '\x86', '\x38', '\x4c', '\x29',
- '\xf1', '\xa0', '\xe0', '\x2c', '\xfa', '\x86', '\x3f', '\x01', '\x90',
- '\xc5', '\x1b', '\x96', '\x10', '\x44', '\x84', '\xfb', '\xec', '\x3c',
- '\x74', '\x6c', '\x0d', '\xcc', '\xc3', '\xcd', '\x1b', '\x28', '\x12',
- '\xaa', '\xb4', '\x67', '\x80', '\xc8', '\xd9', '\x1b', '\x7d', '\xe7',
- '\x54', '\x39', '\x03', '\x6d', '\xba', '\xaa', '\x6f', '\xf7', '\x93',
- '\x1f', '\x94', '\x76', '\xd6', '\xab', '\x9b', '\xda', '\x3d', '\x89',
- '\x37', '\x83', '\xfe', '\x72', '\x2a', '\xbb', '\x6f', '\x36', '\xc5',
- '\xe0', '\xae', '\x65', '\xf9', '\xbb', '\xc6', '\xe2', '\x98', '\x0f',
- '\xbd', '\xf6', '\x22', '\xf8', '\x35', '\x5b', '\x99', '\xe6', '\xff',
- '\x6d', '\x6e', '\xb2', '\x92', '\x93', '\x64', '\x25', '\xc1', '\xe8',
- '\x9c', '\x6b', '\x73', '\x2b', '\x02', '\x81', '\x80', '\x13', '\x30',
- '\x1a', '\x9a', '\x67', '\x3d', '\x98', '\x90', '\x27', '\x87', '\x8f',
- '\x0d', '\x98', '\x53', '\xfd', '\x6c', '\xfd', '\x18', '\x6a', '\xe9',
- '\x71', '\xdf', '\x89', '\x5c', '\x0b', '\x01', '\x4e', '\x1f', '\xf0',
- '\xa0', '\x96', '\x6e', '\x86', '\x46', '\xbb', '\x26', '\xe8', '\xab',
- '\x27', '\xeb', '\x40', '\x32', '\xbd', '\x24', '\x99', '\x75', '\xd3',
- '\xcc', '\xed', '\x05', '\x21', '\x62', '\x68', '\xa0', '\x96', '\x12',
- '\x50', '\xf9', '\x59', '\x7d', '\x5f', '\xf5', '\x1f', '\xa5', '\xfd',
- '\x5e', '\xf5', '\x4b', '\x85', '\xa2', '\x17', '\xa5', '\x34', '\x55',
- '\xef', '\x00', '\x2b', '\xf9', '\x15', '\x80', '\xb0', '\xce', '\x30',
- '\xe2', '\x71', '\x6d', '\xf0', '\x58', '\x39', '\x8e', '\xe2', '\xbf',
- '\x53', '\x0a', '\xc0', '\x77', '\x97', '\x4e', '\x6e', '\x29', '\x94',
- '\xdb', '\xba', '\x34', '\xb7', '\x53', '\xad', '\xac', '\xec', '\xb4',
- '\xc1', '\x22', '\x39', '\xc8', '\x38', '\x3d', '\x63', '\x94', '\x93',
- '\x35', '\xc0', '\x98', '\xc7', '\xbc', '\xda', '\x63', '\x57', '\xe1',
- '\x02', '\x81', '\x80', '\x51', '\x71', '\x7c', '\xab', '\x6a', '\x30',
- '\xe3', '\x68', '\x2c', '\x87', '\xc2', '\xe9', '\x39', '\x8c', '\x97',
- '\x60', '\x94', '\xc4', '\x46', '\xd4', '\xf7', '\x2c', '\xf0', '\x1c',
- '\x5a', '\x34', '\x14', '\x89', '\xf9', '\x53', '\x67', '\xeb', '\xaf',
- '\x6b', '\x38', '\x3f', '\x6a', '\xb6', '\x47', '\x28', '\x53', '\x67',
- '\xb1', '\x3c', '\x5b', '\xb8', '\x41', '\x8f', '\xec', '\x69', '\x9e',
- '\x12', '\x7b', '\x55', '\x1f', '\x14', '\x53', '\x01', '\x69', '\x42',
- '\xae', '\xf5', '\xc1', '\xf5', '\xeb', '\x44', '\x92', '\x6e', '\x85',
- '\x48', '\x46', '\x07', '\xa6', '\xd2', '\xb2', '\x94', '\x7d', '\x20',
- '\xf8', '\x4b', '\x06', '\xf7', '\x6c', '\x87', '\xd5', '\xa7', '\x65',
- '\x49', '\xfa', '\x70', '\x9e', '\xb8', '\xd2', '\x33', '\x30', '\x7a',
- '\x3e', '\x15', '\x52', '\x49', '\xf0', '\xe1', '\x13', '\x18', '\x80',
- '\xaa', '\x33', '\xf1', '\xcb', '\xda', '\x22', '\x55', '\xf7', '\x71',
- '\x58', '\xa1', '\xa8', '\xc9', '\x12', '\x24', '\x48', '\x1d', '\x7c',
- '\xbc', '\xc3', '\x7a', '\xf5', '\xf7', '\x02', '\x81', '\x80', '\x41',
- '\x7c', '\xae', '\x6e', '\x48', '\x3f', '\xb5', '\x0b', '\x99', '\xaa',
- '\xc5', '\xea', '\x81', '\xad', '\x84', '\x6b', '\x29', '\x78', '\x4b',
- '\x18', '\xdb', '\x0e', '\xd3', '\x3e', '\x60', '\x8b', '\xef', '\x65',
- '\x4d', '\x58', '\x25', '\x3a', '\x08', '\xb5', '\x21', '\xb6', '\x61',
- '\x0c', '\xfa', '\xf0', '\x69', '\x78', '\x4e', '\x68', '\x36', '\xdb',
- '\x41', '\x4b', '\x50', '\xd8', '\xd3', '\x8e', '\x3d', '\x74', '\x80',
- '\x8e', '\xa0', '\xe6', '\xda', '\xec', '\x70', '\x89', '\x77', '\xb2',
- '\x9d', '\xd6', '\x6e', '\x0a', '\xc4', '\xbd', '\xf6', '\x9a', '\x07',
- '\x15', '\xba', '\x55', '\x9f', '\xd4', '\x4d', '\x3a', '\x0f', '\x51',
- '\x12', '\xa4', '\xd9', '\xc2', '\x98', '\x76', '\xc5', '\xb7', '\x29',
- '\x40', '\xca', '\xf4', '\xbb', '\x74', '\x2d', '\x71', '\x03', '\x4d',
- '\xe7', '\x05', '\x75', '\xc0', '\x8d', '\x96', '\x7e', '\x59', '\xa1',
- '\x8b', '\x3b', '\xa3', '\x2b', '\xa5', '\xa3', '\xc8', '\xf7', '\xd3',
- '\x3e', '\x6b', '\x2e', '\xfa', '\x4f', '\x4d', '\xe6', '\xbe', '\xd3',
- '\x59'};
-
-ABSL_CONST_INIT const absl::string_view kTestCertificatePrivateKey(
- kTestCertificatePrivateKeyRaw,
- sizeof(kTestCertificatePrivateKeyRaw));
-
-ABSL_CONST_INIT const char kTestCertificatePrivateKeyPem[] =
- R"(-----BEGIN PRIVATE KEY-----
-MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDF4lFtP9Yo8q00
-c4dkyjMZM7d1kasxGSvjpCYJKYst91J1p1UV8BHHwsTtGBszC3Ey5jWJzS1aBVdO
-wnh1ZXItiheD1jKQhfgi4mWp4KD+GbI5LRQDEC/Mi16qJScNozcQDBfs8IvFa+1r
-XrLiNT5GO/f2WbHgFqb7A7+ET85kFQ1Zmabwf4ozS7sLuPLRJ5CPOPhaQYIHmw3Z
-UuBw/97a2CVOLy2fr5Jjx0K03BaVIwUCa7Doxf4Vmuh9L9xD9HCRGpO+ca+FhNvP
-a1yAstPzQm4k7CpimcY85TLlcjcwmwvkBrRkJpVZuvFTgz2ZbfCA4ttrNFIGdzxz
-vsbjzrIRAgMBAAECggEAOXWsG0MMFrvQ24goanXkPI8t2G/B+/HJMsK5YLO1fFVy
-lkNOi544K38823PCgiHybss2BJuVbaxbW71QaRZZ/ys4BMovyJN+J/MBfkCBvwcL
-H1sdkn4iwww9Ir7DBky8cmZwlBaNH3hlamYHH3RCbvZ+3APTiLRLLFw8QllCHwET
-McUi52qW8vtm/sihfiSWXwLuOCGlFNKmNXBsjabYKtJFMV9nnjVXasQV57pgL45S
-TvxvoAiRMXEGaBlIx4ENXlKTV8z+RqypT+KWT68S+8JLxI07sDjku40ZgeR0Y5yN
-qoSCkd/cRfA5srSsRdo/ME1GseGynd/YxKLv6RqXeQKBgQDlI7jXCVRUO7Z4eGdX
-ZcXUdK8FT7XIjBvRmizW5GjRrz1yQlDI3bHud1K4sTG+8HR4QlnqE4uCAFQi0gok
-sB8edieuY8ZrWSgdoJ9CMPHjWRxPMUn/RX5r7+lv3q8eBJZhTp9Y9Q1kCEgKrqzk
-dpHdbjOXxZba/7xCW3G1dq4BswKBgQDdFKVsiSuAePbDgE1TVLMrQM6YFqC/cvHj
-3OkLRSOGOEwp8aDgLPqGPwGQxRuWEESE++w8dGwNzMPNGygSqrRngMjZG33nVDkD
-bbqqb/eTH5R21qub2j2JN4P+ciq7bzbF4K5l+bvG4pgPvfYi+DVbmeb/bW6ykpNk
-JcHonGtzKwKBgBMwGppnPZiQJ4ePDZhT/Wz9GGrpcd+JXAsBTh/woJZuhka7Juir
-J+tAMr0kmXXTzO0FIWJooJYSUPlZfV/1H6X9XvVLhaIXpTRV7wAr+RWAsM4w4nFt
-8Fg5juK/UwrAd5dObimU27o0t1OtrOy0wSI5yDg9Y5STNcCYx7zaY1fhAoGAUXF8
-q2ow42gsh8LpOYyXYJTERtT3LPAcWjQUiflTZ+uvazg/arZHKFNnsTxbuEGP7Gme
-EntVHxRTAWlCrvXB9etEkm6FSEYHptKylH0g+EsG92yH1adlSfpwnrjSMzB6PhVS
-SfDhExiAqjPxy9oiVfdxWKGoyRIkSB18vMN69fcCgYBBfK5uSD+1C5mqxeqBrYRr
-KXhLGNsO0z5gi+9lTVglOgi1IbZhDPrwaXhOaDbbQUtQ2NOOPXSAjqDm2uxwiXey
-ndZuCsS99poHFbpVn9RNOg9REqTZwph2xbcpQMr0u3QtcQNN5wV1wI2Wflmhizuj
-K6WjyPfTPmsu+k9N5r7TWQ==
------END PRIVATE KEY-----)";
-
-// The legacy version was manually generated from the one above using der2ascii.
-ABSL_CONST_INIT const char kTestCertificatePrivateKeyLegacyPem[] =
- R"(-----BEGIN RSA PRIVATE KEY-----
-MIIEogIBAAKCAQEAxeJRbT/WKPKtNHOHZMozGTO3dZGrMRkr46QmCSmLLfdSdadVFfARx8LE7Rgb
-MwtxMuY1ic0tWgVXTsJ4dWVyLYoXg9YykIX4IuJlqeCg/hmyOS0UAxAvzIteqiUnDaM3EAwX7PCL
-xWvta16y4jU+Rjv39lmx4Bam+wO/hE/OZBUNWZmm8H+KM0u7C7jy0SeQjzj4WkGCB5sN2VLgcP/e
-2tglTi8tn6+SY8dCtNwWlSMFAmuw6MX+FZrofS/cQ/RwkRqTvnGvhYTbz2tcgLLT80JuJOwqYpnG
-POUy5XI3MJsL5Aa0ZCaVWbrxU4M9mW3wgOLbazRSBnc8c77G486yEQIDAQABAoIBADl1rBtDDBa7
-0NuIKGp15DyPLdhvwfvxyTLCuWCztXxVcpZDToueOCt/PNtzwoIh8m7LNgSblW2sW1u9UGkWWf8r
-OATKL8iTfifzAX5Agb8HCx9bHZJ+IsMMPSK+wwZMvHJmcJQWjR94ZWpmBx90Qm72ftwD04i0Syxc
-PEJZQh8BEzHFIudqlvL7Zv7IoX4kll8C7jghpRTSpjVwbI2m2CrSRTFfZ541V2rEFee6YC+OUk78
-b6AIkTFxBmgZSMeBDV5Sk1fM/kasqU/ilk+vEvvCS8SNO7A45LuNGYHkdGOcjaqEgpHf3EXwObK0
-rEXaPzBNRrHhsp3f2MSi7+kal3kCgYEA5SO41wlUVDu2eHhnV2XF1HSvBU+1yIwb0Zos1uRo0a89
-ckJQyN2x7ndSuLExvvB0eEJZ6hOLggBUItIKJLAfHnYnrmPGa1koHaCfQjDx41kcTzFJ/0V+a+/p
-b96vHgSWYU6fWPUNZAhICq6s5HaR3W4zl8WW2v+8QltxtXauAbMCgYEA3RSlbIkrgHj2w4BNU1Sz
-K0DOmBagv3Lx49zpC0UjhjhMKfGg4Cz6hj8BkMUblhBEhPvsPHRsDczDzRsoEqq0Z4DI2Rt951Q5
-A226qm/3kx+Udtarm9o9iTeD/nIqu282xeCuZfm7xuKYD732Ivg1W5nm/21uspKTZCXB6JxrcysC
-gYATMBqaZz2YkCeHjw2YU/1s/Rhq6XHfiVwLAU4f8KCWboZGuyboqyfrQDK9JJl108ztBSFiaKCW
-ElD5WX1f9R+l/V71S4WiF6U0Ve8AK/kVgLDOMOJxbfBYOY7iv1MKwHeXTm4plNu6NLdTrazstMEi
-Ocg4PWOUkzXAmMe82mNX4QKBgFFxfKtqMONoLIfC6TmMl2CUxEbU9yzwHFo0FIn5U2frr2s4P2q2
-RyhTZ7E8W7hBj+xpnhJ7VR8UUwFpQq71wfXrRJJuhUhGB6bSspR9IPhLBvdsh9WnZUn6cJ640jMw
-ej4VUknw4RMYgKoz8cvaIlX3cVihqMkSJEgdfLzDevX3AoGAQXyubkg/tQuZqsXqga2Eayl4Sxjb
-DtM+YIvvZU1YJToItSG2YQz68Gl4Tmg220FLUNjTjj10gI6g5trscIl3sp3WbgrEvfaaBxW6VZ/U
-TToPURKk2cKYdsW3KUDK9Lt0LXEDTecFdcCNln5ZoYs7oyulo8j30z5rLvpPTea+01k=
------END RSA PRIVATE KEY-----)";
-
-ABSL_CONST_INIT const char kWildcardCertificateRaw[] = {
- '\x30', '\x82', '\x03', '\x5f', '\x30', '\x82', '\x02', '\x47', '\xa0',
- '\x03', '\x02', '\x01', '\x02', '\x02', '\x14', '\x36', '\x1d', '\xe3',
- '\xd2', '\x39', '\x35', '\x20', '\xb1', '\xae', '\x18', '\xdd', '\x71',
- '\xc9', '\x5b', '\x4a', '\x17', '\xbe', '\x00', '\xb4', '\x15', '\x30',
- '\x0d', '\x06', '\x09', '\x2a', '\x86', '\x48', '\x86', '\xf7', '\x0d',
- '\x01', '\x01', '\x0b', '\x05', '\x00', '\x30', '\x24', '\x31', '\x0b',
- '\x30', '\x09', '\x06', '\x03', '\x55', '\x04', '\x06', '\x13', '\x02',
- '\x55', '\x53', '\x31', '\x15', '\x30', '\x13', '\x06', '\x03', '\x55',
- '\x04', '\x03', '\x0c', '\x0c', '\x77', '\x77', '\x77', '\x2e', '\x66',
- '\x6f', '\x6f', '\x2e', '\x74', '\x65', '\x73', '\x74', '\x30', '\x1e',
- '\x17', '\x0d', '\x32', '\x30', '\x30', '\x34', '\x32', '\x31', '\x30',
- '\x32', '\x31', '\x38', '\x34', '\x35', '\x5a', '\x17', '\x0d', '\x32',
- '\x31', '\x30', '\x34', '\x32', '\x31', '\x30', '\x32', '\x31', '\x38',
- '\x34', '\x35', '\x5a', '\x30', '\x24', '\x31', '\x0b', '\x30', '\x09',
- '\x06', '\x03', '\x55', '\x04', '\x06', '\x13', '\x02', '\x55', '\x53',
- '\x31', '\x15', '\x30', '\x13', '\x06', '\x03', '\x55', '\x04', '\x03',
- '\x0c', '\x0c', '\x77', '\x77', '\x77', '\x2e', '\x66', '\x6f', '\x6f',
- '\x2e', '\x74', '\x65', '\x73', '\x74', '\x30', '\x82', '\x01', '\x22',
- '\x30', '\x0d', '\x06', '\x09', '\x2a', '\x86', '\x48', '\x86', '\xf7',
- '\x0d', '\x01', '\x01', '\x01', '\x05', '\x00', '\x03', '\x82', '\x01',
- '\x0f', '\x00', '\x30', '\x82', '\x01', '\x0a', '\x02', '\x82', '\x01',
- '\x01', '\x00', '\xcc', '\xd5', '\x5d', '\xa0', '\x4a', '\x03', '\x9d',
- '\x89', '\xa2', '\xae', '\x7a', '\x59', '\x15', '\xf7', '\x27', '\x67',
- '\x49', '\xa4', '\xc1', '\x87', '\xcd', '\x9c', '\x02', '\x9e', '\xb9',
- '\x2f', '\xd1', '\xa1', '\x0d', '\x57', '\xff', '\xd6', '\xc0', '\x6a',
- '\x7b', '\xaa', '\x52', '\xb2', '\x6e', '\xa6', '\x12', '\x34', '\xcf',
- '\xdc', '\xd3', '\x1e', '\x32', '\xc1', '\x8d', '\x42', '\xa3', '\x0b',
- '\xd6', '\xaf', '\xe9', '\x37', '\x42', '\xf8', '\x78', '\xdc', '\xcb',
- '\x2d', '\x0e', '\x42', '\x5a', '\xe2', '\xbf', '\xd2', '\xe4', '\x9c',
- '\xb4', '\x34', '\x38', '\x97', '\x5e', '\x4d', '\x5e', '\x8a', '\x0b',
- '\xd8', '\x42', '\x11', '\x88', '\x19', '\xa2', '\x23', '\x4b', '\xec',
- '\x3b', '\x0a', '\xc9', '\x67', '\x49', '\x2c', '\x8e', '\x1c', '\x5e',
- '\x7f', '\x42', '\xe7', '\x73', '\x0b', '\x86', '\x68', '\xf0', '\xaa',
- '\x3f', '\x1e', '\x17', '\x3e', '\x29', '\xc4', '\x57', '\x6e', '\x34',
- '\x78', '\xaf', '\x15', '\x03', '\x39', '\x32', '\x27', '\x80', '\x76',
- '\xb1', '\xda', '\x08', '\xe5', '\x4d', '\x3f', '\x4c', '\xfc', '\x1e',
- '\x23', '\x5a', '\xb3', '\xd4', '\x99', '\xdc', '\x5c', '\x2b', '\xf1',
- '\xa8', '\xe3', '\x02', '\x0a', '\xc8', '\x4d', '\x63', '\x27', '\xb9',
- '\x0d', '\x6c', '\xc2', '\x34', '\x82', '\x82', '\x5d', '\x56', '\xa8',
- '\x93', '\x44', '\x8b', '\xf4', '\x8b', '\xf0', '\x63', '\xe5', '\x23',
- '\x7f', '\x8d', '\x5f', '\x3a', '\x4a', '\xa5', '\x50', '\xb9', '\xc6',
- '\x5c', '\xe6', '\x33', '\xe3', '\xfc', '\xc8', '\x96', '\x88', '\x88',
- '\xe9', '\x53', '\xaf', '\x0d', '\xbb', '\x80', '\x9c', '\xbb', '\xed',
- '\x4d', '\x06', '\xfa', '\xe9', '\x7c', '\x25', '\x1c', '\x59', '\xee',
- '\x19', '\xcc', '\xa9', '\x7c', '\x1d', '\x86', '\xd9', '\x95', '\x78',
- '\x2d', '\x3a', '\x95', '\x49', '\x11', '\x45', '\xfa', '\xd6', '\xef',
- '\xd5', '\x07', '\x1c', '\x23', '\xeb', '\xad', '\xd3', '\x3b', '\x95',
- '\xcf', '\x53', '\xa3', '\x47', '\xa9', '\xa7', '\x90', '\xde', '\x34',
- '\xa4', '\xbb', '\x05', '\xdc', '\x54', '\x87', '\x97', '\x30', '\xea',
- '\x25', '\xf0', '\xfd', '\xba', '\xa1', '\x1b', '\x02', '\x03', '\x01',
- '\x00', '\x01', '\xa3', '\x81', '\x88', '\x30', '\x81', '\x85', '\x30',
- '\x1d', '\x06', '\x03', '\x55', '\x1d', '\x0e', '\x04', '\x16', '\x04',
- '\x14', '\x09', '\xfb', '\x77', '\xbb', '\xc8', '\x8f', '\xd6', '\xa4',
- '\xf0', '\x74', '\xb2', '\x90', '\x46', '\x0a', '\x8d', '\x09', '\x4b',
- '\x89', '\x2e', '\x41', '\x30', '\x1f', '\x06', '\x03', '\x55', '\x1d',
- '\x23', '\x04', '\x18', '\x30', '\x16', '\x80', '\x14', '\x09', '\xfb',
- '\x77', '\xbb', '\xc8', '\x8f', '\xd6', '\xa4', '\xf0', '\x74', '\xb2',
- '\x90', '\x46', '\x0a', '\x8d', '\x09', '\x4b', '\x89', '\x2e', '\x41',
- '\x30', '\x0f', '\x06', '\x03', '\x55', '\x1d', '\x13', '\x01', '\x01',
- '\xff', '\x04', '\x05', '\x30', '\x03', '\x01', '\x01', '\xff', '\x30',
- '\x32', '\x06', '\x03', '\x55', '\x1d', '\x11', '\x04', '\x2b', '\x30',
- '\x29', '\x82', '\x08', '\x66', '\x6f', '\x6f', '\x2e', '\x74', '\x65',
- '\x73', '\x74', '\x82', '\x0c', '\x77', '\x77', '\x77', '\x2e', '\x66',
- '\x6f', '\x6f', '\x2e', '\x74', '\x65', '\x73', '\x74', '\x82', '\x0f',
- '\x2a', '\x2e', '\x77', '\x69', '\x6c', '\x64', '\x63', '\x61', '\x72',
- '\x64', '\x2e', '\x74', '\x65', '\x73', '\x74', '\x30', '\x0d', '\x06',
- '\x09', '\x2a', '\x86', '\x48', '\x86', '\xf7', '\x0d', '\x01', '\x01',
- '\x0b', '\x05', '\x00', '\x03', '\x82', '\x01', '\x01', '\x00', '\x93',
- '\xbc', '\x33', '\x4c', '\xa4', '\xdf', '\xdc', '\xed', '\x4b', '\x4d',
- '\x5e', '\xdb', '\xdd', '\x4a', '\xb7', '\xbc', '\x50', '\x1f', '\xca',
- '\x66', '\x4d', '\x28', '\x96', '\x42', '\x4e', '\x84', '\x44', '\x80',
- '\x25', '\x17', '\x2c', '\x05', '\x93', '\xe0', '\x2a', '\x29', '\xef',
- '\xe4', '\x26', '\x19', '\x63', '\xdf', '\xb2', '\x72', '\xb1', '\x82',
- '\x7e', '\x5f', '\xce', '\x82', '\x41', '\xad', '\x96', '\x78', '\x94',
- '\xa8', '\x21', '\xee', '\xf2', '\x4a', '\xf5', '\x41', '\xa8', '\xfb',
- '\xe0', '\xe1', '\x22', '\x89', '\xf1', '\x40', '\x85', '\x86', '\x53',
- '\x61', '\x57', '\x0f', '\x31', '\xae', '\x0c', '\xc3', '\x8d', '\xe8',
- '\x29', '\xac', '\xe0', '\x03', '\x2d', '\x69', '\x44', '\x3d', '\xd6',
- '\x3b', '\x2b', '\x0f', '\xb3', '\xf5', '\x83', '\x1b', '\x4e', '\x65',
- '\x60', '\x6b', '\xa2', '\x01', '\x03', '\x1e', '\x98', '\xca', '\xca',
- '\x32', '\xd4', '\x5b', '\xde', '\x45', '\xe2', '\x35', '\xd2', '\x54',
- '\x1a', '\x2a', '\x38', '\xa7', '\x42', '\xa0', '\xf3', '\xef', '\x28',
- '\xe3', '\x6e', '\x23', '\x77', '\x07', '\xd5', '\xef', '\xfd', '\x30',
- '\xd6', '\x31', '\xfa', '\xf2', '\x94', '\x95', '\x2f', '\x03', '\x7a',
- '\x43', '\xe0', '\xb3', '\x82', '\xca', '\x7e', '\xb4', '\x00', '\xc9',
- '\x08', '\x15', '\x7b', '\x2e', '\x51', '\xec', '\xab', '\x68', '\xca',
- '\xc2', '\xca', '\x44', '\xe1', '\xbe', '\xe4', '\x06', '\x98', '\x87',
- '\x9b', '\x58', '\xbc', '\xf1', '\xea', '\x55', '\xf6', '\x64', '\x92',
- '\xe6', '\x73', '\xc9', '\xf6', '\xc5', '\x7a', '\x90', '\x42', '\x83',
- '\x39', '\x9e', '\xd0', '\xca', '\x85', '\x6c', '\x53', '\x99', '\x64',
- '\xbb', '\x49', '\xdc', '\xae', '\x1c', '\xe5', '\x00', '\x65', '\x13',
- '\xdd', '\xdc', '\xde', '\x3f', '\xf9', '\x14', '\x91', '\x0d', '\xe6',
- '\xba', '\xc1', '\x7d', '\x5f', '\xd5', '\x6d', '\xe8', '\x65', '\x9c',
- '\xfb', '\xda', '\x82', '\xf7', '\x4d', '\x45', '\x81', '\x8c', '\x54',
- '\xec', '\x50', '\xbb', '\x14', '\xe9', '\x06', '\xda', '\x76', '\xb3',
- '\xf0', '\xb7', '\xbb', '\x58', '\x4c', '\x8f', '\x6a', '\x5d', '\x8e',
- '\x93', '\x5f', '\x35'};
-
-ABSL_CONST_INIT const absl::string_view kWildcardCertificate(
- kWildcardCertificateRaw,
- sizeof(kWildcardCertificateRaw));
-
-ABSL_CONST_INIT const char kWildcardCertificatePrivateKeyRaw[] = {
- '\x30', '\x82', '\x04', '\xbe', '\x02', '\x01', '\x00', '\x30', '\x0d',
- '\x06', '\x09', '\x2a', '\x86', '\x48', '\x86', '\xf7', '\x0d', '\x01',
- '\x01', '\x01', '\x05', '\x00', '\x04', '\x82', '\x04', '\xa8', '\x30',
- '\x82', '\x04', '\xa4', '\x02', '\x01', '\x00', '\x02', '\x82', '\x01',
- '\x01', '\x00', '\xcc', '\xd5', '\x5d', '\xa0', '\x4a', '\x03', '\x9d',
- '\x89', '\xa2', '\xae', '\x7a', '\x59', '\x15', '\xf7', '\x27', '\x67',
- '\x49', '\xa4', '\xc1', '\x87', '\xcd', '\x9c', '\x02', '\x9e', '\xb9',
- '\x2f', '\xd1', '\xa1', '\x0d', '\x57', '\xff', '\xd6', '\xc0', '\x6a',
- '\x7b', '\xaa', '\x52', '\xb2', '\x6e', '\xa6', '\x12', '\x34', '\xcf',
- '\xdc', '\xd3', '\x1e', '\x32', '\xc1', '\x8d', '\x42', '\xa3', '\x0b',
- '\xd6', '\xaf', '\xe9', '\x37', '\x42', '\xf8', '\x78', '\xdc', '\xcb',
- '\x2d', '\x0e', '\x42', '\x5a', '\xe2', '\xbf', '\xd2', '\xe4', '\x9c',
- '\xb4', '\x34', '\x38', '\x97', '\x5e', '\x4d', '\x5e', '\x8a', '\x0b',
- '\xd8', '\x42', '\x11', '\x88', '\x19', '\xa2', '\x23', '\x4b', '\xec',
- '\x3b', '\x0a', '\xc9', '\x67', '\x49', '\x2c', '\x8e', '\x1c', '\x5e',
- '\x7f', '\x42', '\xe7', '\x73', '\x0b', '\x86', '\x68', '\xf0', '\xaa',
- '\x3f', '\x1e', '\x17', '\x3e', '\x29', '\xc4', '\x57', '\x6e', '\x34',
- '\x78', '\xaf', '\x15', '\x03', '\x39', '\x32', '\x27', '\x80', '\x76',
- '\xb1', '\xda', '\x08', '\xe5', '\x4d', '\x3f', '\x4c', '\xfc', '\x1e',
- '\x23', '\x5a', '\xb3', '\xd4', '\x99', '\xdc', '\x5c', '\x2b', '\xf1',
- '\xa8', '\xe3', '\x02', '\x0a', '\xc8', '\x4d', '\x63', '\x27', '\xb9',
- '\x0d', '\x6c', '\xc2', '\x34', '\x82', '\x82', '\x5d', '\x56', '\xa8',
- '\x93', '\x44', '\x8b', '\xf4', '\x8b', '\xf0', '\x63', '\xe5', '\x23',
- '\x7f', '\x8d', '\x5f', '\x3a', '\x4a', '\xa5', '\x50', '\xb9', '\xc6',
- '\x5c', '\xe6', '\x33', '\xe3', '\xfc', '\xc8', '\x96', '\x88', '\x88',
- '\xe9', '\x53', '\xaf', '\x0d', '\xbb', '\x80', '\x9c', '\xbb', '\xed',
- '\x4d', '\x06', '\xfa', '\xe9', '\x7c', '\x25', '\x1c', '\x59', '\xee',
- '\x19', '\xcc', '\xa9', '\x7c', '\x1d', '\x86', '\xd9', '\x95', '\x78',
- '\x2d', '\x3a', '\x95', '\x49', '\x11', '\x45', '\xfa', '\xd6', '\xef',
- '\xd5', '\x07', '\x1c', '\x23', '\xeb', '\xad', '\xd3', '\x3b', '\x95',
- '\xcf', '\x53', '\xa3', '\x47', '\xa9', '\xa7', '\x90', '\xde', '\x34',
- '\xa4', '\xbb', '\x05', '\xdc', '\x54', '\x87', '\x97', '\x30', '\xea',
- '\x25', '\xf0', '\xfd', '\xba', '\xa1', '\x1b', '\x02', '\x03', '\x01',
- '\x00', '\x01', '\x02', '\x82', '\x01', '\x01', '\x00', '\xa3', '\xb3',
- '\x01', '\x98', '\x50', '\x8e', '\x83', '\x20', '\xb4', '\x3a', '\xec',
- '\xdc', '\xb5', '\x89', '\x48', '\x9c', '\x6b', '\x66', '\x98', '\xa4',
- '\x87', '\xd5', '\xde', '\xe2', '\x2a', '\xed', '\xe4', '\x82', '\xe9',
- '\xbf', '\x22', '\x5f', '\xe6', '\x77', '\x33', '\x4d', '\xf3', '\xb9',
- '\x56', '\x64', '\xb2', '\xb8', '\x32', '\x47', '\x31', '\x12', '\x39',
- '\x4e', '\x26', '\x2e', '\xd3', '\x4f', '\x6a', '\xcc', '\x3b', '\x7e',
- '\x46', '\xaf', '\x7d', '\x28', '\x37', '\xd8', '\x52', '\x45', '\x05',
- '\x8d', '\xa1', '\xf0', '\x51', '\x74', '\x4b', '\x30', '\x50', '\xe9',
- '\xe8', '\x1b', '\xbd', '\x2a', '\x66', '\x3c', '\xf6', '\xd0', '\x3c',
- '\x0d', '\x00', '\x5f', '\x65', '\x15', '\xee', '\x39', '\xb8', '\xac',
- '\x2a', '\xf6', '\xc8', '\xbc', '\x33', '\x69', '\x51', '\x76', '\xd7',
- '\xa2', '\xa6', '\x50', '\xc7', '\xc5', '\xc7', '\x9b', '\xac', '\xc7',
- '\xa9', '\x69', '\x98', '\xd6', '\x22', '\x69', '\x30', '\xc3', '\x82',
- '\x47', '\xfb', '\xa5', '\x46', '\x2d', '\x96', '\x05', '\xc2', '\x84',
- '\xd1', '\x1d', '\xd5', '\xa7', '\x5c', '\xdb', '\x6d', '\x35', '\x7b',
- '\x1b', '\x80', '\xe4', '\x42', '\x1f', '\x4d', '\x68', '\x2e', '\xbc',
- '\x58', '\xb6', '\x7c', '\x7e', '\xc5', '\x07', '\xe1', '\xf5', '\x30',
- '\xa9', '\x8f', '\x14', '\x76', '\xad', '\xe2', '\xdf', '\xaf', '\xd3',
- '\xf1', '\xba', '\xd5', '\x98', '\xf3', '\x5e', '\x30', '\x79', '\xcb',
- '\xe7', '\x7a', '\x83', '\xba', '\xf7', '\x71', '\xb0', '\xb2', '\xd1',
- '\xf4', '\x34', '\x5b', '\xe1', '\xe8', '\x60', '\x39', '\x96', '\x12',
- '\xdc', '\xb4', '\x0d', '\xf9', '\x8d', '\x8c', '\xd8', '\xbb', '\xb7',
- '\xd2', '\x1b', '\x83', '\x10', '\xbd', '\x86', '\xef', '\x5c', '\x6c',
- '\xe3', '\xb1', '\x96', '\x7f', '\xab', '\x58', '\xce', '\x87', '\xc9',
- '\x48', '\x69', '\xbb', '\xb1', '\xec', '\xa4', '\x3a', '\x06', '\xa3',
- '\x33', '\xad', '\x7a', '\xe5', '\x88', '\x6d', '\x32', '\x67', '\x1c',
- '\x03', '\xda', '\x9d', '\x3c', '\x73', '\xe0', '\xd7', '\x6c', '\x00',
- '\xe4', '\x8d', '\x7d', '\xf2', '\xac', '\xa5', '\xb8', '\x35', '\xb9',
- '\xac', '\x81', '\x02', '\x81', '\x81', '\x00', '\xe8', '\xd5', '\x5b',
- '\xd0', '\x4f', '\x7c', '\xfc', '\x4b', '\xe6', '\xe8', '\x3c', '\x4c',
- '\x24', '\xce', '\x68', '\x73', '\x3b', '\x4b', '\xa0', '\xfb', '\x79',
- '\xa5', '\x72', '\x1d', '\x77', '\xb2', '\xdf', '\x2b', '\x0a', '\x11',
- '\x28', '\xe8', '\x02', '\x7f', '\x26', '\x40', '\x34', '\x8f', '\x78',
- '\x18', '\xad', '\xf4', '\x11', '\x78', '\x45', '\x9f', '\x66', '\x4e',
- '\x78', '\x71', '\x60', '\x40', '\xeb', '\x64', '\x28', '\x06', '\xae',
- '\x9b', '\x32', '\x73', '\xb5', '\xe1', '\x7e', '\x3c', '\x07', '\x31',
- '\x8d', '\x82', '\xed', '\x6a', '\xe6', '\x1e', '\x65', '\x9e', '\x81',
- '\x29', '\x08', '\x56', '\x17', '\x4b', '\x31', '\xc3', '\xf5', '\x27',
- '\xef', '\xb8', '\xda', '\x58', '\xff', '\x36', '\x47', '\x12', '\xb0',
- '\xef', '\x14', '\x20', '\x5c', '\x48', '\xb3', '\x84', '\x0d', '\x64',
- '\x22', '\x3e', '\xfe', '\x94', '\x17', '\x6c', '\x45', '\xe7', '\x3f',
- '\x4c', '\x90', '\x67', '\x13', '\x1a', '\xa8', '\xbc', '\x5b', '\xd0',
- '\xc1', '\x8a', '\xa9', '\x42', '\xbe', '\xe4', '\x0e', '\x59', '\x02',
- '\x81', '\x81', '\x00', '\xe1', '\x36', '\xcd', '\x86', '\x1e', '\xcb',
- '\x8b', '\x68', '\x65', '\x6b', '\x42', '\xec', '\x50', '\x29', '\xa0',
- '\xab', '\x3a', '\xe5', '\x6f', '\xe1', '\x13', '\xe8', '\xa3', '\x6b',
- '\x7c', '\x2b', '\xd3', '\x69', '\x89', '\x47', '\x07', '\x39', '\xb2',
- '\x0f', '\x03', '\x4e', '\x6f', '\x28', '\x94', '\x1d', '\x1f', '\x22',
- '\x47', '\xf9', '\x95', '\xff', '\x3e', '\xa4', '\x26', '\x38', '\x07',
- '\x5b', '\xdd', '\xef', '\x0a', '\xa5', '\xe8', '\x99', '\xad', '\x91',
- '\x68', '\x83', '\xf2', '\xf5', '\xa5', '\x3d', '\x21', '\x88', '\xa5',
- '\x6a', '\x39', '\x3b', '\xca', '\x4c', '\xc9', '\xd1', '\x9a', '\x74',
- '\xb2', '\xe3', '\x73', '\x5d', '\xfe', '\xbd', '\x05', '\x1b', '\x9a',
- '\x13', '\x98', '\x39', '\x93', '\xf3', '\x88', '\x55', '\x61', '\x85',
- '\x7a', '\x53', '\x5a', '\xd9', '\x2c', '\xdb', '\x15', '\x69', '\xa6',
- '\x31', '\x09', '\xbb', '\xd1', '\xe8', '\x6e', '\x8c', '\x47', '\x77',
- '\x1e', '\x9b', '\xbe', '\xb7', '\x57', '\xd4', '\xaa', '\xd5', '\x92',
- '\xa1', '\xd5', '\x55', '\x04', '\x93', '\x02', '\x81', '\x80', '\x06',
- '\x84', '\x01', '\xff', '\xc0', '\x59', '\xb5', '\x0d', '\xc2', '\xb6',
- '\x79', '\x09', '\x80', '\x76', '\x2e', '\x42', '\x1b', '\x44', '\xb0',
- '\x8a', '\x99', '\x0a', '\xe2', '\x38', '\xa4', '\xe2', '\xe2', '\x8f',
- '\xe7', '\xc6', '\x37', '\x28', '\xd6', '\xf9', '\x0b', '\xee', '\xfc',
- '\x09', '\x8f', '\xc8', '\xd1', '\x05', '\x65', '\x7f', '\xc2', '\x23',
- '\x05', '\xcf', '\xe8', '\x5a', '\xf3', '\xe0', '\x9d', '\x35', '\xbe',
- '\x51', '\x01', '\x8d', '\xe2', '\x49', '\x8e', '\xab', '\x72', '\xc6',
- '\xe7', '\x44', '\xa1', '\xbb', '\x2a', '\x3d', '\xb5', '\x96', '\xe0',
- '\x2d', '\x21', '\x5c', '\x2e', '\x99', '\x8a', '\x29', '\x56', '\x89',
- '\x2f', '\x51', '\x20', '\xca', '\x41', '\x82', '\x00', '\x12', '\x5a',
- '\xc6', '\xd1', '\x20', '\xbf', '\xa5', '\x70', '\x2f', '\xb0', '\xa6',
- '\x5f', '\x61', '\x8f', '\xfb', '\xc7', '\x50', '\x09', '\x9f', '\xc4',
- '\x0d', '\x06', '\x9e', '\x73', '\xe4', '\x0e', '\x8a', '\xce', '\x72',
- '\x06', '\xf7', '\xbe', '\x92', '\xcc', '\xcd', '\xcb', '\x5d', '\xc2',
- '\x71', '\x02', '\x81', '\x80', '\x26', '\xf3', '\xba', '\x92', '\x52',
- '\xeb', '\x33', '\x7e', '\x67', '\xe4', '\x28', '\x5c', '\x04', '\xf5',
- '\x5e', '\x33', '\x9f', '\x69', '\x25', '\x73', '\x91', '\x64', '\xf0',
- '\x36', '\xdb', '\xf0', '\x1c', '\x8d', '\xa9', '\x4f', '\x9e', '\xa1',
- '\x4c', '\xf9', '\xa9', '\xc1', '\xbc', '\x1a', '\x11', '\x9c', '\x03',
- '\xd1', '\x83', '\x0f', '\x58', '\xf1', '\x1f', '\x9d', '\x76', '\x7a',
- '\xc4', '\x53', '\x10', '\x4c', '\x92', '\xd3', '\xe5', '\x2a', '\x07',
- '\x4a', '\x1a', '\x00', '\x90', '\x5a', '\x0a', '\x2d', '\x4b', '\x8a',
- '\x7d', '\xc9', '\xa4', '\x82', '\x81', '\xd7', '\xcc', '\x24', '\x33',
- '\x89', '\xb1', '\x93', '\x03', '\x56', '\x23', '\x83', '\xff', '\xc9',
- '\x29', '\x59', '\xf0', '\x3f', '\x2d', '\x26', '\xb6', '\xd2', '\xc5',
- '\x9e', '\x37', '\x6d', '\x09', '\x4e', '\x7c', '\xa2', '\x9b', '\xce',
- '\x7d', '\x0f', '\x08', '\x36', '\xf2', '\xf4', '\x37', '\x82', '\x8d',
- '\xad', '\xbd', '\x9e', '\x84', '\x5a', '\xe3', '\x97', '\x05', '\xc1',
- '\x10', '\xae', '\x6a', '\xde', '\x5c', '\x7f', '\x02', '\x81', '\x81',
- '\x00', '\x9b', '\x8e', '\xa4', '\x2b', '\xcf', '\xb6', '\x30', '\x1c',
- '\xb5', '\x82', '\x50', '\x08', '\xc0', '\x0b', '\x57', '\xf4', '\x2d',
- '\x82', '\x39', '\x11', '\x1b', '\x02', '\xe6', '\xbe', '\x14', '\x26',
- '\x77', '\xd7', '\x26', '\x1f', '\x0d', '\x92', '\xc6', '\x67', '\xa0',
- '\x01', '\x6c', '\xd9', '\x7a', '\xdf', '\xc3', '\x3d', '\x50', '\x8d',
- '\x43', '\xef', '\x95', '\x50', '\x72', '\x25', '\x06', '\x28', '\x7a',
- '\x7e', '\x99', '\xea', '\x4d', '\xe8', '\x87', '\xe5', '\xca', '\x71',
- '\x36', '\x8a', '\xce', '\x18', '\x55', '\xe4', '\x87', '\x39', '\x3d',
- '\xea', '\x9a', '\x22', '\x99', '\x1a', '\xab', '\xe3', '\x6f', '\x48',
- '\x78', '\x49', '\x8f', '\xf6', '\xfa', '\xb1', '\xb8', '\x68', '\xae',
- '\xc3', '\x47', '\x1d', '\x8f', '\x1d', '\x11', '\xa1', '\x06', '\xf5',
- '\xc0', '\x0d', '\xcf', '\x7b', '\x33', '\xfe', '\x0c', '\x69', '\xca',
- '\x46', '\xfe', '\x2c', '\xac', '\xd8', '\x4d', '\x02', '\x79', '\xfe',
- '\x47', '\xca', '\x21', '\x30', '\x65', '\xa4', '\xe5', '\xaa', '\x4e',
- '\x9c', '\xbc', '\xa5'};
-
-ABSL_CONST_INIT const absl::string_view kWildcardCertificatePrivateKey(
- kWildcardCertificatePrivateKeyRaw,
- sizeof(kWildcardCertificatePrivateKeyRaw));
-
-ABSL_CONST_INIT const char kTestEcPrivateKeyLegacyPem[] =
- R"(-----BEGIN EC PARAMETERS-----
-BggqhkjOPQMBBw==
------END EC PARAMETERS-----
------BEGIN EC PRIVATE KEY-----
-MHcCAQEEIMdjXX0hg399DlccZuYFXPKq+dMGduXWmQYClDYJNDGroAoGCCqGSM49
-AwEHoUQDQgAENCuPQTywFI8hbsGo68AeN1KVWmd09buzlu/2CAtsJcNoECUmpVXH
-4dwvWMv6zWn9RJ5EzI72R/5FVcO485s5MQ==
------END EC PRIVATE KEY-----)";
-
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/test_certificates.h b/chromium/net/third_party/quiche/src/quic/test_tools/test_certificates.h
deleted file mode 100644
index 6a7eba768f1..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/test_certificates.h
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_TEST_CERTIFICATES_H_
-#define QUICHE_QUIC_TEST_TOOLS_TEST_CERTIFICATES_H_
-
-#include "absl/base/attributes.h"
-#include "absl/strings/string_view.h"
-
-namespace quic {
-namespace test {
-
-// A test certificate generated by //net/tools/quic/certs/generate-certs.sh.
-ABSL_CONST_INIT extern const absl::string_view kTestCertificate;
-
-// PEM-encoded version of |kTestCertificate|.
-ABSL_CONST_INIT extern const char kTestCertificatePem[];
-
-// |kTestCertificatePem| with a PEM-encoded root appended to the end.
-ABSL_CONST_INIT extern const char kTestCertificateChainPem[];
-
-// PEM-encoded certificate that contains a subjectAltName with an
-// unknown/unsupported type.
-ABSL_CONST_INIT extern const char kTestCertWithUnknownSanTypePem[];
-
-// DER-encoded private key for |kTestCertificate|.
-ABSL_CONST_INIT extern const absl::string_view kTestCertificatePrivateKey;
-
-// PEM-encoded version of |kTestCertificatePrivateKey|.
-ABSL_CONST_INIT extern const char kTestCertificatePrivateKeyPem[];
-
-// The legacy PEM-encoded version of |kTestCertificatePrivateKey| manually
-// generated from the one above using der2ascii.
-ABSL_CONST_INIT extern const char kTestCertificatePrivateKeyLegacyPem[];
-
-// Another DER-encoded test certificate, valid for foo.test, www.foo.test and
-// *.wildcard.test.
-ABSL_CONST_INIT extern const absl::string_view kWildcardCertificate;
-
-// DER-encoded private key for |kWildcardCertificate|.
-ABSL_CONST_INIT extern const absl::string_view kWildcardCertificatePrivateKey;
-
-// PEM-encoded P-256 private key using legacy OpenSSL encoding.
-ABSL_CONST_INIT extern const char kTestEcPrivateKeyLegacyPem[];
-
-} // namespace test
-} // namespace quic
-
-#endif // QUICHE_QUIC_TEST_TOOLS_TEST_CERTIFICATES_H_
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/test_ticket_crypter.cc b/chromium/net/third_party/quiche/src/quic/test_tools/test_ticket_crypter.cc
deleted file mode 100644
index be9021a7baa..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/test_ticket_crypter.cc
+++ /dev/null
@@ -1,83 +0,0 @@
-// Copyright (c) 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/test_ticket_crypter.h"
-
-#include <cstring>
-
-#include "absl/base/macros.h"
-#include "quic/core/crypto/quic_random.h"
-
-namespace quic {
-namespace test {
-
-namespace {
-
-// A TicketCrypter implementation is supposed to encrypt and decrypt session
-// tickets. However, the only requirement that is needed of a test
-// implementation is that calling Decrypt(Encrypt(input), callback) results in
-// callback being called with input. (The output of Encrypt must also not exceed
-// the overhead specified by MaxOverhead.) This test implementation encrypts
-// tickets by prepending kTicketPrefix to generate the ciphertext. The decrypt
-// function checks that the prefix is present and strips it; otherwise it
-// returns an empty vector to signal failure.
-constexpr char kTicketPrefix[] = "TEST TICKET";
-
-} // namespace
-
-TestTicketCrypter::TestTicketCrypter()
- : ticket_prefix_(ABSL_ARRAYSIZE(kTicketPrefix) + 16) {
- memcpy(ticket_prefix_.data(), kTicketPrefix, ABSL_ARRAYSIZE(kTicketPrefix));
- QuicRandom::GetInstance()->RandBytes(
- ticket_prefix_.data() + ABSL_ARRAYSIZE(kTicketPrefix), 16);
-}
-
-size_t TestTicketCrypter::MaxOverhead() {
- return ticket_prefix_.size();
-}
-
-std::vector<uint8_t> TestTicketCrypter::Encrypt(
- absl::string_view in, absl::string_view /* encryption_key */) {
- size_t prefix_len = ticket_prefix_.size();
- std::vector<uint8_t> out(prefix_len + in.size());
- memcpy(out.data(), ticket_prefix_.data(), prefix_len);
- memcpy(out.data() + prefix_len, in.data(), in.size());
- return out;
-}
-
-std::vector<uint8_t> TestTicketCrypter::Decrypt(absl::string_view in) {
- size_t prefix_len = ticket_prefix_.size();
- if (fail_decrypt_ || in.size() < prefix_len ||
- memcmp(ticket_prefix_.data(), in.data(), prefix_len) != 0) {
- return std::vector<uint8_t>();
- }
- return std::vector<uint8_t>(in.begin() + prefix_len, in.end());
-}
-
-void TestTicketCrypter::Decrypt(
- absl::string_view in,
- std::unique_ptr<ProofSource::DecryptCallback> callback) {
- auto decrypted_ticket = Decrypt(in);
- if (run_async_) {
- pending_callbacks_.push_back({std::move(callback), decrypted_ticket});
- } else {
- callback->Run(decrypted_ticket);
- }
-}
-
-void TestTicketCrypter::SetRunCallbacksAsync(bool run_async) {
- run_async_ = run_async;
-}
-
-size_t TestTicketCrypter::NumPendingCallbacks() {
- return pending_callbacks_.size();
-}
-
-void TestTicketCrypter::RunPendingCallback(size_t n) {
- const PendingCallback& callback = pending_callbacks_[n];
- callback.callback->Run(callback.decrypted_ticket);
-}
-
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/test_ticket_crypter.h b/chromium/net/third_party/quiche/src/quic/test_tools/test_ticket_crypter.h
deleted file mode 100644
index 0300998fa37..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/test_ticket_crypter.h
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright (c) 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_TEST_TICKET_CRYPTER_H_
-#define QUICHE_QUIC_TEST_TOOLS_TEST_TICKET_CRYPTER_H_
-
-#include "quic/core/crypto/proof_source.h"
-
-namespace quic {
-namespace test {
-
-// Provides a simple implementation of ProofSource::TicketCrypter for testing.
-// THIS IMPLEMENTATION IS NOT SECURE. It is only intended for testing purposes.
-class TestTicketCrypter : public ProofSource::TicketCrypter {
- public:
- TestTicketCrypter();
- ~TestTicketCrypter() override = default;
-
- // TicketCrypter interface
- size_t MaxOverhead() override;
- std::vector<uint8_t> Encrypt(absl::string_view in,
- absl::string_view encryption_key) override;
- void Decrypt(absl::string_view in,
- std::unique_ptr<ProofSource::DecryptCallback> callback) override;
-
- void SetRunCallbacksAsync(bool run_async);
- size_t NumPendingCallbacks();
- void RunPendingCallback(size_t n);
-
- // Allows configuring this TestTicketCrypter to fail decryption.
- void set_fail_decrypt(bool fail_decrypt) { fail_decrypt_ = fail_decrypt; }
-
- private:
- // Performs the Decrypt operation synchronously.
- std::vector<uint8_t> Decrypt(absl::string_view in);
-
- struct PendingCallback {
- std::unique_ptr<ProofSource::DecryptCallback> callback;
- std::vector<uint8_t> decrypted_ticket;
- };
-
- bool fail_decrypt_ = false;
- bool run_async_ = false;
- std::vector<PendingCallback> pending_callbacks_;
- std::vector<uint8_t> ticket_prefix_;
-};
-
-} // namespace test
-} // namespace quic
-
-#endif // QUICHE_QUIC_TEST_TOOLS_TEST_TICKET_CRYPTER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/web_transport_resets_backend.cc b/chromium/net/third_party/quiche/src/quic/test_tools/web_transport_resets_backend.cc
deleted file mode 100644
index 512619fee0a..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/web_transport_resets_backend.cc
+++ /dev/null
@@ -1,113 +0,0 @@
-// Copyright (c) 2021 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 "quic/test_tools/web_transport_resets_backend.h"
-
-#include <memory>
-
-#include "quic/core/web_transport_interface.h"
-#include "quic/tools/web_transport_test_visitors.h"
-#include "common/quiche_circular_deque.h"
-
-namespace quic {
-namespace test {
-
-namespace {
-
-class ResetsVisitor;
-
-class BidirectionalEchoVisitorWithLogging
- : public WebTransportBidirectionalEchoVisitor {
- public:
- BidirectionalEchoVisitorWithLogging(WebTransportStream* stream,
- ResetsVisitor* session_visitor)
- : WebTransportBidirectionalEchoVisitor(stream),
- session_visitor_(session_visitor) {}
-
- void OnResetStreamReceived(WebTransportStreamError error) override;
- void OnStopSendingReceived(WebTransportStreamError error) override;
-
- private:
- ResetsVisitor* session_visitor_; // Not owned.
-};
-
-class ResetsVisitor : public WebTransportVisitor {
- public:
- ResetsVisitor(WebTransportSession* session) : session_(session) {}
-
- void OnSessionReady(const spdy::SpdyHeaderBlock& /*headers*/) override {}
- void OnSessionClosed(WebTransportSessionError /*error_code*/,
- const std::string& /*error_message*/) override {}
-
- void OnIncomingBidirectionalStreamAvailable() override {
- while (true) {
- WebTransportStream* stream =
- session_->AcceptIncomingBidirectionalStream();
- if (stream == nullptr) {
- return;
- }
- stream->SetVisitor(
- std::make_unique<BidirectionalEchoVisitorWithLogging>(stream, this));
- stream->visitor()->OnCanRead();
- }
- }
- void OnIncomingUnidirectionalStreamAvailable() override {}
-
- void OnDatagramReceived(absl::string_view /*datagram*/) override {}
-
- void OnCanCreateNewOutgoingBidirectionalStream() override {}
- void OnCanCreateNewOutgoingUnidirectionalStream() override {
- MaybeSendLogsBack();
- }
-
- void Log(std::string line) {
- log_.push_back(std::move(line));
- MaybeSendLogsBack();
- }
-
- private:
- void MaybeSendLogsBack() {
- while (!log_.empty() &&
- session_->CanOpenNextOutgoingUnidirectionalStream()) {
- WebTransportStream* stream = session_->OpenOutgoingUnidirectionalStream();
- stream->SetVisitor(
- std::make_unique<WebTransportUnidirectionalEchoWriteVisitor>(
- stream, log_.front()));
- log_.pop_front();
- stream->visitor()->OnCanWrite();
- }
- }
-
- WebTransportSession* session_; // Not owned.
- quiche::QuicheCircularDeque<std::string> log_;
-};
-
-void BidirectionalEchoVisitorWithLogging::OnResetStreamReceived(
- WebTransportStreamError error) {
- session_visitor_->Log(absl::StrCat("Received reset for stream ",
- stream()->GetStreamId(),
- " with error code ", error));
- WebTransportBidirectionalEchoVisitor::OnResetStreamReceived(error);
-}
-void BidirectionalEchoVisitorWithLogging::OnStopSendingReceived(
- WebTransportStreamError error) {
- session_visitor_->Log(absl::StrCat("Received stop sending for stream ",
- stream()->GetStreamId(),
- " with error code ", error));
- WebTransportBidirectionalEchoVisitor::OnStopSendingReceived(error);
-}
-
-} // namespace
-
-QuicSimpleServerBackend::WebTransportResponse WebTransportResetsBackend(
- const spdy::Http2HeaderBlock& /*request_headers*/,
- WebTransportSession* session) {
- QuicSimpleServerBackend::WebTransportResponse response;
- response.response_headers[":status"] = "200";
- response.visitor = std::make_unique<ResetsVisitor>(session);
- return response;
-}
-
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/web_transport_resets_backend.h b/chromium/net/third_party/quiche/src/quic/test_tools/web_transport_resets_backend.h
deleted file mode 100644
index dda06be521f..00000000000
--- a/chromium/net/third_party/quiche/src/quic/test_tools/web_transport_resets_backend.h
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright (c) 2021 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_WEB_TRANSPORT_RESETS_BACKEND_H_
-#define QUICHE_QUIC_TEST_TOOLS_WEB_TRANSPORT_RESETS_BACKEND_H_
-
-#include "quic/test_tools/quic_test_backend.h"
-
-namespace quic {
-namespace test {
-
-// A backend for testing RESET_STREAM/STOP_SENDING behavior. Provides
-// bidirectional echo streams; whenever one of those receives RESET_STREAM or
-// STOP_SENDING, a log message is sent as a unidirectional stream.
-QuicSimpleServerBackend::WebTransportResponse WebTransportResetsBackend(
- const spdy::Http2HeaderBlock& request_headers,
- WebTransportSession* session);
-
-} // namespace test
-} // namespace quic
-
-#endif // QUICHE_QUIC_TEST_TOOLS_WEB_TRANSPORT_RESETS_BACKEND_H_
diff --git a/chromium/net/third_party/quiche/src/quic/tools/fake_proof_verifier.h b/chromium/net/third_party/quiche/src/quic/tools/fake_proof_verifier.h
deleted file mode 100644
index a8e5eb8b149..00000000000
--- a/chromium/net/third_party/quiche/src/quic/tools/fake_proof_verifier.h
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TOOLS_FAKE_PROOF_VERIFIER_H_
-#define QUICHE_QUIC_TOOLS_FAKE_PROOF_VERIFIER_H_
-
-#include "absl/strings/string_view.h"
-#include "quic/core/crypto/proof_verifier.h"
-
-namespace quic {
-
-// ProofVerifier implementation which always returns success.
-class FakeProofVerifier : public ProofVerifier {
- public:
- ~FakeProofVerifier() override {}
- QuicAsyncStatus VerifyProof(
- const std::string& /*hostname*/,
- const uint16_t /*port*/,
- const std::string& /*server_config*/,
- QuicTransportVersion /*quic_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 {
- return QUIC_SUCCESS;
- }
- 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 {
- return QUIC_SUCCESS;
- }
- std::unique_ptr<ProofVerifyContext> CreateDefaultContext() override {
- return nullptr;
- }
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_TOOLS_FAKE_PROOF_VERIFIER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/tools/quic_backend_response.cc b/chromium/net/third_party/quiche/src/quic/tools/quic_backend_response.cc
deleted file mode 100644
index f6177e0f292..00000000000
--- a/chromium/net/third_party/quiche/src/quic/tools/quic_backend_response.cc
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/tools/quic_backend_response.h"
-
-namespace quic {
-
-QuicBackendResponse::ServerPushInfo::ServerPushInfo(
- QuicUrl request_url,
- spdy::Http2HeaderBlock headers,
- spdy::SpdyPriority priority,
- std::string body)
- : request_url(request_url),
- headers(std::move(headers)),
- priority(priority),
- body(body) {}
-
-QuicBackendResponse::ServerPushInfo::ServerPushInfo(const ServerPushInfo& other)
- : request_url(other.request_url),
- headers(other.headers.Clone()),
- priority(other.priority),
- body(other.body) {}
-
-QuicBackendResponse::QuicBackendResponse() : response_type_(REGULAR_RESPONSE) {}
-
-QuicBackendResponse::~QuicBackendResponse() = default;
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/tools/quic_backend_response.h b/chromium/net/third_party/quiche/src/quic/tools/quic_backend_response.h
deleted file mode 100644
index 64d7ade08f8..00000000000
--- a/chromium/net/third_party/quiche/src/quic/tools/quic_backend_response.h
+++ /dev/null
@@ -1,92 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TOOLS_QUIC_BACKEND_RESPONSE_H_
-#define QUICHE_QUIC_TOOLS_QUIC_BACKEND_RESPONSE_H_
-
-#include "absl/strings/string_view.h"
-#include "quic/tools/quic_url.h"
-#include "spdy/core/spdy_protocol.h"
-
-namespace quic {
-
-// Container for HTTP response header/body pairs
-// fetched by the QuicSimpleServerBackend
-class QuicBackendResponse {
- public:
- // A ServerPushInfo contains path of the push request and everything needed in
- // comprising a response for the push request.
- // TODO(b/171463363): Remove.
- struct ServerPushInfo {
- ServerPushInfo(QuicUrl request_url,
- spdy::Http2HeaderBlock headers,
- spdy::SpdyPriority priority,
- std::string body);
- ServerPushInfo(const ServerPushInfo& other);
-
- QuicUrl request_url;
- spdy::Http2HeaderBlock headers;
- spdy::SpdyPriority priority;
- std::string body;
- };
-
- enum SpecialResponseType {
- REGULAR_RESPONSE, // Send the headers and body like a server should.
- CLOSE_CONNECTION, // Close the connection (sending the close packet).
- IGNORE_REQUEST, // Do nothing, expect the client to time out.
- BACKEND_ERR_RESPONSE, // There was an error fetching the response from
- // the backend, for example as a TCP connection
- // error.
- INCOMPLETE_RESPONSE, // The server will act as if there is a non-empty
- // trailer but it will not be sent, as a result, FIN
- // will not be sent too.
- GENERATE_BYTES // Sends a response with a length equal to the number
- // of bytes in the URL path.
- };
- QuicBackendResponse();
-
- QuicBackendResponse(const QuicBackendResponse& other) = delete;
- QuicBackendResponse& operator=(const QuicBackendResponse& other) = delete;
-
- ~QuicBackendResponse();
-
- const std::vector<spdy::Http2HeaderBlock>& early_hints() const {
- return early_hints_;
- }
- SpecialResponseType response_type() const { return response_type_; }
- const spdy::Http2HeaderBlock& headers() const { return headers_; }
- const spdy::Http2HeaderBlock& trailers() const { return trailers_; }
- const absl::string_view body() const { return absl::string_view(body_); }
-
- void AddEarlyHints(const spdy::Http2HeaderBlock& headers) {
- spdy::Http2HeaderBlock hints = headers.Clone();
- hints[":status"] = "103";
- early_hints_.push_back(std::move(hints));
- }
-
- void set_response_type(SpecialResponseType response_type) {
- response_type_ = response_type;
- }
-
- void set_headers(spdy::Http2HeaderBlock headers) {
- headers_ = std::move(headers);
- }
- void set_trailers(spdy::Http2HeaderBlock trailers) {
- trailers_ = std::move(trailers);
- }
- void set_body(absl::string_view body) {
- body_.assign(body.data(), body.size());
- }
-
- private:
- std::vector<spdy::Http2HeaderBlock> early_hints_;
- SpecialResponseType response_type_;
- spdy::Http2HeaderBlock headers_;
- spdy::Http2HeaderBlock trailers_;
- std::string body_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_TOOLS_QUIC_BACKEND_RESPONSE_H_
diff --git a/chromium/net/third_party/quiche/src/quic/tools/quic_client.cc b/chromium/net/third_party/quiche/src/quic/tools/quic_client.cc
deleted file mode 100644
index cfc435ed62f..00000000000
--- a/chromium/net/third_party/quiche/src/quic/tools/quic_client.cc
+++ /dev/null
@@ -1,179 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/tools/quic_client.h"
-
-#include <errno.h>
-#include <netdb.h>
-#include <netinet/in.h>
-#include <string.h>
-#include <sys/epoll.h>
-#include <sys/socket.h>
-#include <sys/types.h>
-
-#include <utility>
-
-#include "quic/core/crypto/quic_random.h"
-#include "quic/core/http/spdy_utils.h"
-#include "quic/core/quic_connection.h"
-#include "quic/core/quic_data_reader.h"
-#include "quic/core/quic_epoll_alarm_factory.h"
-#include "quic/core/quic_epoll_connection_helper.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_server_id.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/platform/api/quic_socket_address.h"
-#include "quic/tools/quic_simple_client_session.h"
-
-namespace quic {
-
-namespace tools {
-
-QuicSocketAddress LookupAddress(int address_family_for_lookup,
- std::string host,
- std::string port) {
- addrinfo hint;
- memset(&hint, 0, sizeof(hint));
- hint.ai_family = address_family_for_lookup;
- hint.ai_protocol = IPPROTO_UDP;
-
- addrinfo* info_list = nullptr;
- int result = getaddrinfo(host.c_str(), port.c_str(), &hint, &info_list);
- if (result != 0) {
- QUIC_LOG(ERROR) << "Failed to look up " << host << ": "
- << gai_strerror(result);
- return QuicSocketAddress();
- }
-
- QUICHE_CHECK(info_list != nullptr);
- std::unique_ptr<addrinfo, void (*)(addrinfo*)> info_list_owned(info_list,
- freeaddrinfo);
- return QuicSocketAddress(info_list->ai_addr, info_list->ai_addrlen);
-}
-
-} // namespace tools
-
-QuicClient::QuicClient(QuicSocketAddress server_address,
- const QuicServerId& server_id,
- const ParsedQuicVersionVector& supported_versions,
- QuicEpollServer* epoll_server,
- std::unique_ptr<ProofVerifier> proof_verifier)
- : QuicClient(
- server_address,
- server_id,
- supported_versions,
- QuicConfig(),
- epoll_server,
- std::make_unique<QuicClientEpollNetworkHelper>(epoll_server, this),
- std::move(proof_verifier),
- nullptr) {}
-
-QuicClient::QuicClient(QuicSocketAddress server_address,
- const QuicServerId& server_id,
- const ParsedQuicVersionVector& supported_versions,
- QuicEpollServer* epoll_server,
- std::unique_ptr<ProofVerifier> proof_verifier,
- std::unique_ptr<SessionCache> session_cache)
- : QuicClient(
- server_address,
- server_id,
- supported_versions,
- QuicConfig(),
- epoll_server,
- std::make_unique<QuicClientEpollNetworkHelper>(epoll_server, this),
- std::move(proof_verifier),
- std::move(session_cache)) {}
-
-QuicClient::QuicClient(QuicSocketAddress server_address,
- const QuicServerId& server_id,
- const ParsedQuicVersionVector& supported_versions,
- const QuicConfig& config,
- QuicEpollServer* epoll_server,
- std::unique_ptr<ProofVerifier> proof_verifier,
- std::unique_ptr<SessionCache> session_cache)
- : QuicClient(
- server_address,
- server_id,
- supported_versions,
- config,
- epoll_server,
- std::make_unique<QuicClientEpollNetworkHelper>(epoll_server, this),
- std::move(proof_verifier),
- std::move(session_cache)) {}
-
-QuicClient::QuicClient(
- QuicSocketAddress server_address,
- const QuicServerId& server_id,
- const ParsedQuicVersionVector& supported_versions,
- QuicEpollServer* epoll_server,
- std::unique_ptr<QuicClientEpollNetworkHelper> network_helper,
- std::unique_ptr<ProofVerifier> proof_verifier)
- : QuicClient(server_address,
- server_id,
- supported_versions,
- QuicConfig(),
- epoll_server,
- std::move(network_helper),
- std::move(proof_verifier),
- nullptr) {}
-
-QuicClient::QuicClient(
- QuicSocketAddress server_address,
- const QuicServerId& server_id,
- const ParsedQuicVersionVector& supported_versions,
- const QuicConfig& config,
- QuicEpollServer* epoll_server,
- std::unique_ptr<QuicClientEpollNetworkHelper> network_helper,
- std::unique_ptr<ProofVerifier> proof_verifier)
- : QuicClient(server_address,
- server_id,
- supported_versions,
- config,
- epoll_server,
- std::move(network_helper),
- std::move(proof_verifier),
- nullptr) {}
-
-QuicClient::QuicClient(
- QuicSocketAddress server_address,
- const QuicServerId& server_id,
- const ParsedQuicVersionVector& supported_versions,
- const QuicConfig& config,
- QuicEpollServer* epoll_server,
- std::unique_ptr<QuicClientEpollNetworkHelper> network_helper,
- std::unique_ptr<ProofVerifier> proof_verifier,
- std::unique_ptr<SessionCache> session_cache)
- : QuicSpdyClientBase(
- server_id,
- supported_versions,
- config,
- new QuicEpollConnectionHelper(epoll_server, QuicAllocator::SIMPLE),
- new QuicEpollAlarmFactory(epoll_server),
- std::move(network_helper),
- std::move(proof_verifier),
- std::move(session_cache)) {
- set_server_address(server_address);
-}
-
-QuicClient::~QuicClient() = default;
-
-std::unique_ptr<QuicSession> QuicClient::CreateQuicClientSession(
- const ParsedQuicVersionVector& supported_versions,
- 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());
-}
-
-QuicClientEpollNetworkHelper* QuicClient::epoll_network_helper() {
- return static_cast<QuicClientEpollNetworkHelper*>(network_helper());
-}
-
-const QuicClientEpollNetworkHelper* QuicClient::epoll_network_helper() const {
- return static_cast<const QuicClientEpollNetworkHelper*>(network_helper());
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/tools/quic_client.h b/chromium/net/third_party/quiche/src/quic/tools/quic_client.h
deleted file mode 100644
index cc6ec3738a5..00000000000
--- a/chromium/net/third_party/quiche/src/quic/tools/quic_client.h
+++ /dev/null
@@ -1,108 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// A toy client, which connects to a specified port and sends QUIC
-// request to that endpoint.
-
-#ifndef QUICHE_QUIC_TOOLS_QUIC_CLIENT_H_
-#define QUICHE_QUIC_TOOLS_QUIC_CLIENT_H_
-
-#include <cstdint>
-#include <memory>
-#include <string>
-
-#include "quic/core/http/quic_client_push_promise_index.h"
-#include "quic/core/http/quic_spdy_client_session.h"
-#include "quic/core/quic_config.h"
-#include "quic/core/quic_packet_reader.h"
-#include "quic/platform/api/quic_containers.h"
-#include "quic/platform/api/quic_epoll.h"
-#include "quic/tools/quic_client_epoll_network_helper.h"
-#include "quic/tools/quic_spdy_client_base.h"
-
-namespace quic {
-
-class QuicServerId;
-
-namespace test {
-class QuicClientPeer;
-} // namespace test
-
-namespace tools {
-
-QuicSocketAddress LookupAddress(int address_family_for_lookup,
- std::string host,
- std::string port);
-
-inline QuicSocketAddress LookupAddress(std::string host, std::string port) {
- return LookupAddress(0, host, port);
-}
-
-} // namespace tools
-
-class QuicClient : public QuicSpdyClientBase {
- public:
- // These will create their own QuicClientEpollNetworkHelper.
- QuicClient(QuicSocketAddress server_address,
- const QuicServerId& server_id,
- const ParsedQuicVersionVector& supported_versions,
- QuicEpollServer* epoll_server,
- std::unique_ptr<ProofVerifier> proof_verifier);
- QuicClient(QuicSocketAddress server_address,
- const QuicServerId& server_id,
- const ParsedQuicVersionVector& supported_versions,
- QuicEpollServer* epoll_server,
- std::unique_ptr<ProofVerifier> proof_verifier,
- std::unique_ptr<SessionCache> session_cache);
- QuicClient(QuicSocketAddress server_address,
- const QuicServerId& server_id,
- const ParsedQuicVersionVector& supported_versions,
- const QuicConfig& config,
- QuicEpollServer* epoll_server,
- std::unique_ptr<ProofVerifier> proof_verifier,
- std::unique_ptr<SessionCache> session_cache);
- // This will take ownership of a passed in network primitive.
- QuicClient(QuicSocketAddress server_address,
- const QuicServerId& server_id,
- const ParsedQuicVersionVector& supported_versions,
- QuicEpollServer* epoll_server,
- std::unique_ptr<QuicClientEpollNetworkHelper> network_helper,
- std::unique_ptr<ProofVerifier> proof_verifier);
- QuicClient(QuicSocketAddress server_address,
- const QuicServerId& server_id,
- const ParsedQuicVersionVector& supported_versions,
- const QuicConfig& config,
- QuicEpollServer* epoll_server,
- std::unique_ptr<QuicClientEpollNetworkHelper> network_helper,
- std::unique_ptr<ProofVerifier> proof_verifier);
- QuicClient(QuicSocketAddress server_address,
- const QuicServerId& server_id,
- const ParsedQuicVersionVector& supported_versions,
- const QuicConfig& config,
- QuicEpollServer* epoll_server,
- std::unique_ptr<QuicClientEpollNetworkHelper> network_helper,
- std::unique_ptr<ProofVerifier> proof_verifier,
- std::unique_ptr<SessionCache> session_cache);
- QuicClient(const QuicClient&) = delete;
- QuicClient& operator=(const QuicClient&) = delete;
-
- ~QuicClient() override;
-
- std::unique_ptr<QuicSession> CreateQuicClientSession(
- const ParsedQuicVersionVector& supported_versions,
- QuicConnection* connection) override;
-
- // Exposed for the quic client test.
- int GetLatestFD() const { return epoll_network_helper()->GetLatestFD(); }
-
- QuicClientEpollNetworkHelper* epoll_network_helper();
- const QuicClientEpollNetworkHelper* epoll_network_helper() const;
-
- private:
- friend class test::QuicClientPeer;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_TOOLS_QUIC_CLIENT_H_
diff --git a/chromium/net/third_party/quiche/src/quic/tools/quic_client_base.cc b/chromium/net/third_party/quiche/src/quic/tools/quic_client_base.cc
deleted file mode 100644
index e11e25bcdff..00000000000
--- a/chromium/net/third_party/quiche/src/quic/tools/quic_client_base.cc
+++ /dev/null
@@ -1,514 +0,0 @@
-// Copyright (c) 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/tools/quic_client_base.h"
-
-#include <algorithm>
-#include <memory>
-
-#include "quic/core/crypto/quic_random.h"
-#include "quic/core/http/spdy_utils.h"
-#include "quic/core/quic_packet_writer.h"
-#include "quic/core/quic_path_validator.h"
-#include "quic/core/quic_server_id.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-// A path context which owns the writer.
-class QUIC_EXPORT_PRIVATE PathMigrationContext
- : public QuicPathValidationContext {
- public:
- PathMigrationContext(std::unique_ptr<QuicPacketWriter> writer,
- const QuicSocketAddress& self_address,
- const QuicSocketAddress& peer_address)
- : QuicPathValidationContext(self_address, peer_address),
- alternative_writer_(std::move(writer)) {}
-
- QuicPacketWriter* WriterToUse() override { return alternative_writer_.get(); }
-
- QuicPacketWriter* ReleaseWriter() { return alternative_writer_.release(); }
-
- private:
- std::unique_ptr<QuicPacketWriter> alternative_writer_;
-};
-
-// Implements the basic feature of a result delegate for path validation for
-// connection migration. If the validation succeeds, migrate to the alternative
-// path. Otherwise, stay on the current path.
-class QuicClientSocketMigrationValidationResultDelegate
- : public QuicPathValidator::ResultDelegate {
- public:
- QuicClientSocketMigrationValidationResultDelegate(QuicClientBase* client)
- : QuicPathValidator::ResultDelegate(), client_(client) {}
-
- // QuicPathValidator::ResultDelegate
- // Overridden to start migration and takes the ownership of the writer in the
- // context.
- void OnPathValidationSuccess(
- std::unique_ptr<QuicPathValidationContext> context) override {
- QUIC_DLOG(INFO) << "Successfully validated path from " << *context
- << ". Migrate to it now.";
- auto migration_context = std::unique_ptr<PathMigrationContext>(
- static_cast<PathMigrationContext*>(context.release()));
- client_->session()->MigratePath(
- migration_context->self_address(), migration_context->peer_address(),
- migration_context->WriterToUse(), /*owns_writer=*/false);
- QUICHE_DCHECK(migration_context->WriterToUse() != nullptr);
- // Hand the ownership of the alternative writer to the client.
- client_->set_writer(migration_context->ReleaseWriter());
- }
-
- void OnPathValidationFailure(
- std::unique_ptr<QuicPathValidationContext> context) override {
- QUIC_LOG(WARNING) << "Fail to validate path " << *context
- << ", stop migrating.";
- client_->session()->connection()->OnPathValidationFailureAtClient();
- }
-
- private:
- QuicClientBase* client_;
-};
-
-QuicClientBase::NetworkHelper::~NetworkHelper() = default;
-
-QuicClientBase::QuicClientBase(
- const QuicServerId& server_id,
- const ParsedQuicVersionVector& supported_versions,
- const QuicConfig& config,
- QuicConnectionHelperInterface* helper,
- QuicAlarmFactory* alarm_factory,
- std::unique_ptr<NetworkHelper> network_helper,
- std::unique_ptr<ProofVerifier> proof_verifier,
- std::unique_ptr<SessionCache> session_cache)
- : server_id_(server_id),
- initialized_(false),
- local_port_(0),
- config_(config),
- crypto_config_(std::move(proof_verifier), std::move(session_cache)),
- helper_(helper),
- alarm_factory_(alarm_factory),
- supported_versions_(supported_versions),
- initial_max_packet_length_(0),
- num_sent_client_hellos_(0),
- connection_error_(QUIC_NO_ERROR),
- connected_or_attempting_connect_(false),
- network_helper_(std::move(network_helper)),
- connection_debug_visitor_(nullptr),
- server_connection_id_length_(kQuicDefaultConnectionIdLength),
- client_connection_id_length_(0) {}
-
-QuicClientBase::~QuicClientBase() = default;
-
-bool QuicClientBase::Initialize() {
- num_sent_client_hellos_ = 0;
- connection_error_ = QUIC_NO_ERROR;
- connected_or_attempting_connect_ = false;
-
- // If an initial flow control window has not explicitly been set, then use the
- // same values that Chrome uses.
- const uint32_t kSessionMaxRecvWindowSize = 15 * 1024 * 1024; // 15 MB
- const uint32_t kStreamMaxRecvWindowSize = 6 * 1024 * 1024; // 6 MB
- if (config()->GetInitialStreamFlowControlWindowToSend() ==
- kDefaultFlowControlSendWindow) {
- config()->SetInitialStreamFlowControlWindowToSend(kStreamMaxRecvWindowSize);
- }
- if (config()->GetInitialSessionFlowControlWindowToSend() ==
- kDefaultFlowControlSendWindow) {
- config()->SetInitialSessionFlowControlWindowToSend(
- kSessionMaxRecvWindowSize);
- }
-
- if (!network_helper_->CreateUDPSocketAndBind(server_address_,
- bind_to_address_, local_port_)) {
- return false;
- }
-
- initialized_ = true;
- return true;
-}
-
-bool QuicClientBase::Connect() {
- // Attempt multiple connects until the maximum number of client hellos have
- // been sent.
- int num_attempts = 0;
- while (!connected() &&
- num_attempts <= QuicCryptoClientStream::kMaxClientHellos) {
- StartConnect();
- while (EncryptionBeingEstablished()) {
- WaitForEvents();
- }
- ParsedQuicVersion version = UnsupportedQuicVersion();
- if (session() != nullptr && !CanReconnectWithDifferentVersion(&version)) {
- // We've successfully created a session but we're not connected, and we
- // cannot reconnect with a different version. Give up trying.
- break;
- }
- num_attempts++;
- }
- if (session() == nullptr) {
- QUIC_BUG(quic_bug_10906_1) << "Missing session after Connect";
- return false;
- }
- return session()->connection()->connected();
-}
-
-void QuicClientBase::StartConnect() {
- QUICHE_DCHECK(initialized_);
- QUICHE_DCHECK(!connected());
- QuicPacketWriter* writer = network_helper_->CreateQuicPacketWriter();
- ParsedQuicVersion mutual_version = UnsupportedQuicVersion();
- const bool can_reconnect_with_different_version =
- CanReconnectWithDifferentVersion(&mutual_version);
- if (connected_or_attempting_connect()) {
- // Clear queued up data if client can not try to connect with a different
- // version.
- if (!can_reconnect_with_different_version) {
- ClearDataToResend();
- }
- // Before we destroy the last session and create a new one, gather its stats
- // and update the stats for the overall connection.
- UpdateStats();
- }
-
- const quic::ParsedQuicVersionVector client_supported_versions =
- can_reconnect_with_different_version
- ? ParsedQuicVersionVector{mutual_version}
- : supported_versions();
-
- session_ = CreateQuicClientSession(
- client_supported_versions,
- new QuicConnection(GetNextConnectionId(), QuicSocketAddress(),
- server_address(), helper(), alarm_factory(), writer,
- /* owns_writer= */ false, Perspective::IS_CLIENT,
- client_supported_versions));
- if (can_reconnect_with_different_version) {
- session()->set_client_original_supported_versions(supported_versions());
- }
- if (connection_debug_visitor_ != nullptr) {
- session()->connection()->set_debug_visitor(connection_debug_visitor_);
- }
- session()->connection()->set_client_connection_id(GetClientConnectionId());
- if (initial_max_packet_length_ != 0) {
- session()->connection()->SetMaxPacketLength(initial_max_packet_length_);
- }
- // Reset |writer()| after |session()| so that the old writer outlives the old
- // session.
- set_writer(writer);
- InitializeSession();
- if (can_reconnect_with_different_version) {
- // This is a reconnect using server supported |mutual_version|.
- session()->connection()->SetVersionNegotiated();
- }
- set_connected_or_attempting_connect(true);
-}
-
-void QuicClientBase::InitializeSession() {
- session()->Initialize();
-}
-
-void QuicClientBase::Disconnect() {
- QUICHE_DCHECK(initialized_);
-
- initialized_ = false;
- if (connected()) {
- session()->connection()->CloseConnection(
- QUIC_PEER_GOING_AWAY, "Client disconnecting",
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
- }
-
- ClearDataToResend();
-
- network_helper_->CleanUpAllUDPSockets();
-}
-
-ProofVerifier* QuicClientBase::proof_verifier() const {
- return crypto_config_.proof_verifier();
-}
-
-bool QuicClientBase::EncryptionBeingEstablished() {
- return !session_->IsEncryptionEstablished() &&
- session_->connection()->connected();
-}
-
-bool QuicClientBase::WaitForEvents() {
- if (!connected()) {
- QUIC_BUG(quic_bug_10906_2)
- << "Cannot call WaitForEvents on non-connected client";
- return false;
- }
-
- network_helper_->RunEventLoop();
-
- QUICHE_DCHECK(session() != nullptr);
- ParsedQuicVersion version = UnsupportedQuicVersion();
- if (!connected() && CanReconnectWithDifferentVersion(&version)) {
- QUIC_DLOG(INFO) << "Can reconnect with version: " << version
- << ", attempting to reconnect.";
-
- Connect();
- }
-
- return HasActiveRequests();
-}
-
-bool QuicClientBase::MigrateSocket(const QuicIpAddress& new_host) {
- return MigrateSocketWithSpecifiedPort(new_host, local_port_);
-}
-
-bool QuicClientBase::MigrateSocketWithSpecifiedPort(
- const QuicIpAddress& new_host,
- int port) {
- if (!connected()) {
- QUICHE_DVLOG(1)
- << "MigrateSocketWithSpecifiedPort failed as connection has closed";
- return false;
- }
-
- network_helper_->CleanUpAllUDPSockets();
- std::unique_ptr<QuicPacketWriter> writer =
- CreateWriterForNewNetwork(new_host, port);
- if (writer == nullptr) {
- QUICHE_DVLOG(1)
- << "MigrateSocketWithSpecifiedPort failed from writer creation";
- return false;
- }
- if (!session()->MigratePath(network_helper_->GetLatestClientAddress(),
- session()->connection()->peer_address(),
- writer.get(), false)) {
- QUICHE_DVLOG(1)
- << "MigrateSocketWithSpecifiedPort failed from session()->MigratePath";
- return false;
- }
- set_writer(writer.release());
- return true;
-}
-
-bool QuicClientBase::ValidateAndMigrateSocket(const QuicIpAddress& new_host) {
- QUICHE_DCHECK(VersionHasIetfQuicFrames(
- session_->connection()->version().transport_version) &&
- session_->connection()->use_path_validator());
- if (!connected()) {
- return false;
- }
-
- std::unique_ptr<QuicPacketWriter> writer =
- CreateWriterForNewNetwork(new_host, local_port_);
- if (writer == nullptr) {
- return false;
- }
- // Asynchronously start migration.
- session_->ValidatePath(
- std::make_unique<PathMigrationContext>(
- std::move(writer), network_helper_->GetLatestClientAddress(),
- session_->peer_address()),
- std::make_unique<QuicClientSocketMigrationValidationResultDelegate>(
- this));
- return true;
-}
-
-std::unique_ptr<QuicPacketWriter> QuicClientBase::CreateWriterForNewNetwork(
- const QuicIpAddress& new_host,
- int port) {
- set_bind_to_address(new_host);
- set_local_port(port);
- if (!network_helper_->CreateUDPSocketAndBind(server_address_,
- bind_to_address_, port)) {
- return nullptr;
- }
-
- QuicPacketWriter* writer = network_helper_->CreateQuicPacketWriter();
- QUIC_LOG_IF(WARNING, writer == writer_.get())
- << "The new writer is wrapped in the same wrapper as the old one, thus "
- "appearing to have the same address as the old one.";
- return std::unique_ptr<QuicPacketWriter>(writer);
-}
-
-bool QuicClientBase::ChangeEphemeralPort() {
- auto current_host = network_helper_->GetLatestClientAddress().host();
- return MigrateSocketWithSpecifiedPort(current_host, 0 /*any ephemeral port*/);
-}
-
-QuicSession* QuicClientBase::session() {
- return session_.get();
-}
-
-const QuicSession* QuicClientBase::session() const {
- return session_.get();
-}
-
-QuicClientBase::NetworkHelper* QuicClientBase::network_helper() {
- return network_helper_.get();
-}
-
-const QuicClientBase::NetworkHelper* QuicClientBase::network_helper() const {
- return network_helper_.get();
-}
-
-void QuicClientBase::WaitForStreamToClose(QuicStreamId id) {
- if (!connected()) {
- QUIC_BUG(quic_bug_10906_3)
- << "Cannot WaitForStreamToClose on non-connected client";
- return;
- }
-
- while (connected() && !session_->IsClosedStream(id)) {
- WaitForEvents();
- }
-}
-
-bool QuicClientBase::WaitForOneRttKeysAvailable() {
- if (!connected()) {
- QUIC_BUG(quic_bug_10906_4)
- << "Cannot WaitForOneRttKeysAvailable on non-connected client";
- return false;
- }
-
- while (connected() && !session_->OneRttKeysAvailable()) {
- WaitForEvents();
- }
-
- // If the handshake fails due to a timeout, the connection will be closed.
- QUIC_LOG_IF(ERROR, !connected()) << "Handshake with server failed.";
- return connected();
-}
-
-bool QuicClientBase::WaitForHandshakeConfirmed() {
- if (!session_->connection()->version().UsesTls()) {
- return WaitForOneRttKeysAvailable();
- }
- // Otherwise, wait for receipt of HANDSHAKE_DONE frame.
- while (connected() && session_->GetHandshakeState() < HANDSHAKE_CONFIRMED) {
- WaitForEvents();
- }
-
- // If the handshake fails due to a timeout, the connection will be closed.
- QUIC_LOG_IF(ERROR, !connected()) << "Handshake with server failed.";
- return connected();
-}
-
-bool QuicClientBase::connected() const {
- return session_.get() && session_->connection() &&
- session_->connection()->connected();
-}
-
-bool QuicClientBase::goaway_received() const {
- return session_ != nullptr && session_->transport_goaway_received();
-}
-
-int QuicClientBase::GetNumSentClientHellos() {
- // If we are not actively attempting to connect, the session object
- // corresponds to the previous connection and should not be used.
- const int current_session_hellos = !connected_or_attempting_connect_
- ? 0
- : GetNumSentClientHellosFromSession();
- return num_sent_client_hellos_ + current_session_hellos;
-}
-
-void QuicClientBase::UpdateStats() {
- num_sent_client_hellos_ += GetNumSentClientHellosFromSession();
-}
-
-int QuicClientBase::GetNumReceivedServerConfigUpdates() {
- // If we are not actively attempting to connect, the session object
- // corresponds to the previous connection and should not be used.
- return !connected_or_attempting_connect_
- ? 0
- : GetNumReceivedServerConfigUpdatesFromSession();
-}
-
-QuicErrorCode QuicClientBase::connection_error() const {
- // Return the high-level error if there was one. Otherwise, return the
- // connection error from the last session.
- if (connection_error_ != QUIC_NO_ERROR) {
- return connection_error_;
- }
- if (session_ == nullptr) {
- return QUIC_NO_ERROR;
- }
- return session_->error();
-}
-
-QuicConnectionId QuicClientBase::GetNextConnectionId() {
- return GenerateNewConnectionId();
-}
-
-QuicConnectionId QuicClientBase::GenerateNewConnectionId() {
- return QuicUtils::CreateRandomConnectionId(server_connection_id_length_);
-}
-
-QuicConnectionId QuicClientBase::GetClientConnectionId() {
- return QuicUtils::CreateRandomConnectionId(client_connection_id_length_);
-}
-
-bool QuicClientBase::CanReconnectWithDifferentVersion(
- ParsedQuicVersion* version) const {
- if (session_ == nullptr || session_->connection() == nullptr ||
- session_->error() != QUIC_INVALID_VERSION) {
- return false;
- }
-
- const auto& server_supported_versions =
- session_->connection()->server_supported_versions();
- if (server_supported_versions.empty()) {
- return false;
- }
-
- for (const auto& client_version : supported_versions_) {
- if (std::find(server_supported_versions.begin(),
- server_supported_versions.end(),
- client_version) != server_supported_versions.end()) {
- *version = client_version;
- return true;
- }
- }
- return false;
-}
-
-bool QuicClientBase::HasPendingPathValidation() {
- return session()->HasPendingPathValidation();
-}
-
-class ValidationResultDelegate : public QuicPathValidator::ResultDelegate {
- public:
- ValidationResultDelegate(QuicClientBase* client)
- : QuicPathValidator::ResultDelegate(), client_(client) {}
-
- void OnPathValidationSuccess(
- std::unique_ptr<QuicPathValidationContext> context) override {
- QUIC_DLOG(INFO) << "Successfully validated path from " << *context;
- client_->AddValidatedPath(std::move(context));
- }
- void OnPathValidationFailure(
- std::unique_ptr<QuicPathValidationContext> context) override {
- QUIC_LOG(WARNING) << "Fail to validate path " << *context
- << ", stop migrating.";
- client_->session()->connection()->OnPathValidationFailureAtClient();
- }
-
- private:
- QuicClientBase* client_;
-};
-
-void QuicClientBase::ValidateNewNetwork(const QuicIpAddress& host) {
- std::unique_ptr<QuicPacketWriter> writer =
- CreateWriterForNewNetwork(host, local_port_);
- auto result_delegate = std::make_unique<ValidationResultDelegate>(this);
- if (writer == nullptr) {
- result_delegate->OnPathValidationFailure(
- std::make_unique<PathMigrationContext>(
- nullptr, network_helper_->GetLatestClientAddress(),
- session_->peer_address()));
- return;
- }
- session()->ValidatePath(
- std::make_unique<PathMigrationContext>(
- std::move(writer), network_helper_->GetLatestClientAddress(),
- session_->peer_address()),
- std::move(result_delegate));
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/tools/quic_client_base.h b/chromium/net/third_party/quiche/src/quic/tools/quic_client_base.h
deleted file mode 100644
index 51e3433d90a..00000000000
--- a/chromium/net/third_party/quiche/src/quic/tools/quic_client_base.h
+++ /dev/null
@@ -1,408 +0,0 @@
-// Copyright (c) 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// A base class for the toy client, which connects to a specified port and sends
-// QUIC request to that endpoint.
-
-#ifndef QUICHE_QUIC_TOOLS_QUIC_CLIENT_BASE_H_
-#define QUICHE_QUIC_TOOLS_QUIC_CLIENT_BASE_H_
-
-#include <memory>
-#include <string>
-
-#include "absl/base/attributes.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/crypto/crypto_handshake.h"
-#include "quic/core/http/quic_client_push_promise_index.h"
-#include "quic/core/http/quic_spdy_client_session.h"
-#include "quic/core/http/quic_spdy_client_stream.h"
-#include "quic/core/quic_config.h"
-#include "quic/platform/api/quic_socket_address.h"
-
-namespace quic {
-
-class ProofVerifier;
-class QuicServerId;
-class SessionCache;
-
-// QuicClientBase handles establishing a connection to the passed in
-// server id, including ensuring that it supports the passed in versions
-// and config.
-// Subclasses derived from this class are responsible for creating the
-// actual QuicSession instance, as well as defining functions that
-// create and run the underlying network transport.
-class QuicClientBase {
- public:
- // An interface to various network events that the QuicClient will need to
- // interact with.
- class NetworkHelper {
- public:
- virtual ~NetworkHelper();
-
- // Runs one iteration of the event loop.
- virtual void RunEventLoop() = 0;
-
- // Used during initialization: creates the UDP socket FD, sets socket
- // options, and binds the socket to our address.
- virtual bool CreateUDPSocketAndBind(QuicSocketAddress server_address,
- QuicIpAddress bind_to_address,
- int bind_to_port) = 0;
-
- // Unregister and close all open UDP sockets.
- virtual void CleanUpAllUDPSockets() = 0;
-
- // If the client has at least one UDP socket, return address of the latest
- // created one. Otherwise, return an empty socket address.
- virtual QuicSocketAddress GetLatestClientAddress() const = 0;
-
- // Creates a packet writer to be used for the next connection.
- virtual QuicPacketWriter* CreateQuicPacketWriter() = 0;
- };
-
- QuicClientBase(const QuicServerId& server_id,
- const ParsedQuicVersionVector& supported_versions,
- const QuicConfig& config,
- QuicConnectionHelperInterface* helper,
- QuicAlarmFactory* alarm_factory,
- std::unique_ptr<NetworkHelper> network_helper,
- std::unique_ptr<ProofVerifier> proof_verifier,
- std::unique_ptr<SessionCache> session_cache);
- QuicClientBase(const QuicClientBase&) = delete;
- QuicClientBase& operator=(const QuicClientBase&) = delete;
-
- virtual ~QuicClientBase();
-
- // Initializes the client to create a connection. Should be called exactly
- // once before calling StartConnect or Connect. Returns true if the
- // initialization succeeds, false otherwise.
- virtual bool Initialize();
-
- // "Connect" to the QUIC server, including performing synchronous crypto
- // handshake.
- bool Connect();
-
- // Start the crypto handshake. This can be done in place of the synchronous
- // Connect(), but callers are responsible for making sure the crypto handshake
- // completes.
- void StartConnect();
-
- // Calls session()->Initialize(). Subclasses may override this if any extra
- // initialization needs to be done. Subclasses should expect that session()
- // is non-null and valid.
- virtual void InitializeSession();
-
- // Disconnects from the QUIC server.
- void Disconnect();
-
- // Returns true if the crypto handshake has yet to establish encryption.
- // Returns false if encryption is active (even if the server hasn't confirmed
- // the handshake) or if the connection has been closed.
- bool EncryptionBeingEstablished();
-
- // Wait for events until the stream with the given ID is closed.
- void WaitForStreamToClose(QuicStreamId id);
-
- // Wait for 1-RTT keys become available.
- // Returns true once 1-RTT keys are available, false otherwise.
- ABSL_MUST_USE_RESULT bool WaitForOneRttKeysAvailable();
-
- // Wait for handshake state proceeds to HANDSHAKE_CONFIRMED.
- // In QUIC crypto, this does the same as WaitForOneRttKeysAvailable, while in
- // TLS, this waits for HANDSHAKE_DONE frame is received.
- ABSL_MUST_USE_RESULT bool WaitForHandshakeConfirmed();
-
- // Wait up to 50ms, and handle any events which occur.
- // Returns true if there are any outstanding requests.
- bool WaitForEvents();
-
- // Migrate to a new socket (new_host) during an active connection.
- bool MigrateSocket(const QuicIpAddress& new_host);
-
- // Migrate to a new socket (new_host, port) during an active connection.
- bool MigrateSocketWithSpecifiedPort(const QuicIpAddress& new_host, int port);
-
- // Validate the new socket and migrate to it if the validation succeeds.
- // Otherwise stay on the current socket. Return true if the validation has
- // started.
- bool ValidateAndMigrateSocket(const QuicIpAddress& new_host);
-
- // Open a new socket to change to a new ephemeral port.
- bool ChangeEphemeralPort();
-
- QuicSession* session();
- const QuicSession* session() const;
-
- bool connected() const;
- virtual bool goaway_received() const;
-
- const QuicServerId& server_id() const { return server_id_; }
-
- // This should only be set before the initial Connect()
- void set_server_id(const QuicServerId& server_id) { server_id_ = server_id; }
-
- void SetUserAgentID(const std::string& user_agent_id) {
- crypto_config_.set_user_agent_id(user_agent_id);
- }
-
- void SetTlsSignatureAlgorithms(std::string signature_algorithms) {
- crypto_config_.set_tls_signature_algorithms(
- std::move(signature_algorithms));
- }
-
- const ParsedQuicVersionVector& supported_versions() const {
- return supported_versions_;
- }
-
- void SetSupportedVersions(const ParsedQuicVersionVector& versions) {
- supported_versions_ = versions;
- }
-
- QuicConfig* config() { return &config_; }
-
- QuicCryptoClientConfig* crypto_config() { return &crypto_config_; }
-
- // Change the initial maximum packet size of the connection. Has to be called
- // before Connect()/StartConnect() in order to have any effect.
- void set_initial_max_packet_length(QuicByteCount initial_max_packet_length) {
- initial_max_packet_length_ = initial_max_packet_length;
- }
-
- // The number of client hellos sent.
- int GetNumSentClientHellos();
-
- // Returns true if early data (0-RTT data) was sent and the server accepted
- // it.
- virtual bool EarlyDataAccepted() = 0;
-
- // Returns true if the handshake was delayed one round trip by the server
- // because the server wanted proof the client controls its source address
- // before progressing further. In Google QUIC, this would be due to an
- // inchoate REJ in the QUIC Crypto handshake; in IETF QUIC this would be due
- // to a Retry packet.
- // TODO(nharper): Consider a better name for this method.
- virtual bool ReceivedInchoateReject() = 0;
-
- // Gather the stats for the last session and update the stats for the overall
- // connection.
- void UpdateStats();
-
- // The number of server config updates received.
- int GetNumReceivedServerConfigUpdates();
-
- // Returns any errors that occurred at the connection-level.
- QuicErrorCode connection_error() const;
- void set_connection_error(QuicErrorCode connection_error) {
- connection_error_ = connection_error;
- }
-
- bool connected_or_attempting_connect() const {
- return connected_or_attempting_connect_;
- }
- void set_connected_or_attempting_connect(
- bool connected_or_attempting_connect) {
- connected_or_attempting_connect_ = connected_or_attempting_connect;
- }
-
- QuicPacketWriter* writer() { return writer_.get(); }
- void set_writer(QuicPacketWriter* writer) {
- if (writer_.get() != writer) {
- writer_.reset(writer);
- }
- }
-
- void reset_writer() { writer_.reset(); }
-
- ProofVerifier* proof_verifier() const;
-
- void set_bind_to_address(QuicIpAddress address) {
- bind_to_address_ = address;
- }
-
- QuicIpAddress bind_to_address() const { return bind_to_address_; }
-
- void set_local_port(int local_port) { local_port_ = local_port; }
-
- int local_port() const { return local_port_; }
-
- const QuicSocketAddress& server_address() const { return server_address_; }
-
- void set_server_address(const QuicSocketAddress& server_address) {
- server_address_ = server_address;
- }
-
- QuicConnectionHelperInterface* helper() { return helper_.get(); }
-
- NetworkHelper* network_helper();
- const NetworkHelper* network_helper() const;
-
- bool initialized() const { return initialized_; }
-
- void SetPreSharedKey(absl::string_view key) {
- crypto_config_.set_pre_shared_key(key);
- }
-
- void set_connection_debug_visitor(
- QuicConnectionDebugVisitor* connection_debug_visitor) {
- connection_debug_visitor_ = connection_debug_visitor;
- }
-
- void set_server_connection_id_length(uint8_t server_connection_id_length) {
- server_connection_id_length_ = server_connection_id_length;
- }
-
- void set_client_connection_id_length(uint8_t client_connection_id_length) {
- client_connection_id_length_ = client_connection_id_length;
- }
-
- bool HasPendingPathValidation();
-
- void ValidateNewNetwork(const QuicIpAddress& host);
-
- void AddValidatedPath(std::unique_ptr<QuicPathValidationContext> context) {
- validated_paths_.push_back(std::move(context));
- }
-
- const std::vector<std::unique_ptr<QuicPathValidationContext>>&
- validated_paths() const {
- return validated_paths_;
- }
-
- protected:
- // TODO(rch): Move GetNumSentClientHellosFromSession and
- // GetNumReceivedServerConfigUpdatesFromSession into a new/better
- // QuicSpdyClientSession class. The current inherits dependencies from
- // Spdy. When that happens this class and all its subclasses should
- // work with QuicSpdyClientSession instead of QuicSession.
- // That will obviate the need for the pure virtual functions below.
-
- // Extract the number of sent client hellos from the session.
- virtual int GetNumSentClientHellosFromSession() = 0;
-
- // The number of server config updates received.
- virtual int GetNumReceivedServerConfigUpdatesFromSession() = 0;
-
- // If this client supports buffering data, resend it.
- virtual void ResendSavedData() = 0;
-
- // If this client supports buffering data, clear it.
- virtual void ClearDataToResend() = 0;
-
- // Takes ownership of |connection|. If you override this function,
- // you probably want to call ResetSession() in your destructor.
- // TODO(rch): Change the connection parameter to take in a
- // std::unique_ptr<QuicConnection> instead.
- virtual std::unique_ptr<QuicSession> CreateQuicClientSession(
- const ParsedQuicVersionVector& supported_versions,
- QuicConnection* connection) = 0;
-
- // Generates the next ConnectionId for |server_id_|. By default, if the
- // cached server config contains a server-designated ID, that ID will be
- // returned. Otherwise, the next random ID will be returned.
- QuicConnectionId GetNextConnectionId();
-
- // Generates a new, random connection ID (as opposed to a server-designated
- // connection ID).
- virtual QuicConnectionId GenerateNewConnectionId();
-
- // Returns the client connection ID to use.
- virtual QuicConnectionId GetClientConnectionId();
-
- QuicAlarmFactory* alarm_factory() { return alarm_factory_.get(); }
-
- // Subclasses may need to explicitly clear the session on destruction
- // if they create it with objects that will be destroyed before this is.
- // You probably want to call this if you override CreateQuicSpdyClientSession.
- void ResetSession() { session_.reset(); }
-
- // Returns true if the corresponding of this client has active requests.
- virtual bool HasActiveRequests() = 0;
-
- private:
- // Returns true and set |version| if client can reconnect with a different
- // version.
- bool CanReconnectWithDifferentVersion(ParsedQuicVersion* version) const;
-
- std::unique_ptr<QuicPacketWriter> CreateWriterForNewNetwork(
- const QuicIpAddress& new_host,
- int port);
-
- // |server_id_| is a tuple (hostname, port, is_https) of the server.
- QuicServerId server_id_;
-
- // Tracks if the client is initialized to connect.
- bool initialized_;
-
- // Address of the server.
- QuicSocketAddress server_address_;
-
- // If initialized, the address to bind to.
- QuicIpAddress bind_to_address_;
-
- // Local port to bind to. Initialize to 0.
- int local_port_;
-
- // config_ and crypto_config_ contain configuration and cached state about
- // servers.
- QuicConfig config_;
- QuicCryptoClientConfig crypto_config_;
-
- // Helper to be used by created connections. Must outlive |session_|.
- std::unique_ptr<QuicConnectionHelperInterface> helper_;
-
- // Alarm factory to be used by created connections. Must outlive |session_|.
- std::unique_ptr<QuicAlarmFactory> alarm_factory_;
-
- // Writer used to actually send packets to the wire. Must outlive |session_|.
- std::unique_ptr<QuicPacketWriter> writer_;
-
- // Session which manages streams.
- std::unique_ptr<QuicSession> session_;
-
- // This vector contains QUIC versions which we currently support.
- // This should be ordered such that the highest supported version is the first
- // element, with subsequent elements in descending order (versions can be
- // skipped as necessary). We will always pick supported_versions_[0] as the
- // initial version to use.
- ParsedQuicVersionVector supported_versions_;
-
- // The initial value of maximum packet size of the connection. If set to
- // zero, the default is used.
- QuicByteCount initial_max_packet_length_;
-
- // The number of hellos sent during the current/latest connection.
- int num_sent_client_hellos_;
-
- // Used to store any errors that occurred with the overall connection (as
- // opposed to that associated with the last session object).
- QuicErrorCode connection_error_;
-
- // True when the client is attempting to connect. Set to false between a call
- // to Disconnect() and the subsequent call to StartConnect(). When
- // connected_or_attempting_connect_ is false, the session object corresponds
- // to the previous client-level connection.
- bool connected_or_attempting_connect_;
-
- // The network helper used to create sockets and manage the event loop.
- // Not owned by this class.
- std::unique_ptr<NetworkHelper> network_helper_;
-
- // The debug visitor set on the connection right after it is constructed.
- // Not owned, must be valid for the lifetime of the QuicClientBase instance.
- QuicConnectionDebugVisitor* connection_debug_visitor_;
-
- // GenerateNewConnectionId creates a random connection ID of this length.
- // Defaults to 8.
- uint8_t server_connection_id_length_;
-
- // GetClientConnectionId creates a random connection ID of this length.
- // Defaults to 0.
- uint8_t client_connection_id_length_;
-
- // Stores validated paths.
- std::vector<std::unique_ptr<QuicPathValidationContext>> validated_paths_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_TOOLS_QUIC_CLIENT_BASE_H_
diff --git a/chromium/net/third_party/quiche/src/quic/tools/quic_client_bin.cc b/chromium/net/third_party/quiche/src/quic/tools/quic_client_bin.cc
deleted file mode 100644
index deeddddbd9d..00000000000
--- a/chromium/net/third_party/quiche/src/quic/tools/quic_client_bin.cc
+++ /dev/null
@@ -1,67 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// A binary wrapper for QuicClient.
-// Connects to a host using QUIC, sends a request to the provided URL, and
-// displays the response.
-//
-// Some usage examples:
-//
-// Standard request/response:
-// quic_client www.google.com
-// quic_client www.google.com --quiet
-// quic_client www.google.com --port=443
-//
-// Use a specific version:
-// quic_client www.google.com --quic_version=23
-//
-// Send a POST instead of a GET:
-// quic_client www.google.com --body="this is a POST body"
-//
-// Append additional headers to the request:
-// quic_client www.google.com --headers="header-a: 1234; header-b: 5678"
-//
-// Connect to a host different to the URL being requested:
-// quic_client mail.google.com --host=www.google.com
-//
-// Connect to a specific IP:
-// IP=`dig www.google.com +short | head -1`
-// quic_client www.google.com --host=${IP}
-//
-// Send repeated requests and change ephemeral port between requests
-// quic_client www.google.com --num_requests=10
-//
-// Try to connect to a host which does not speak QUIC:
-// quic_client www.example.com
-//
-// This tool is available as a built binary at:
-// /google/data/ro/teams/quic/tools/quic_client
-// After submitting changes to this file, you will need to follow the
-// instructions at go/quic_client_binary_update
-
-#include <iostream>
-#include <memory>
-#include <string>
-
-#include "quic/platform/api/quic_system_event_loop.h"
-#include "quic/tools/quic_epoll_client_factory.h"
-#include "quic/tools/quic_toy_client.h"
-#include "common/platform/api/quiche_command_line_flags.h"
-
-int main(int argc, char* argv[]) {
- QuicSystemEventLoop event_loop("quic_client");
- const char* usage = "Usage: quic_client [options] <url>";
-
- // All non-flag arguments should be interpreted as URLs to fetch.
- std::vector<std::string> urls =
- quiche::QuicheParseCommandLineFlags(usage, argc, argv);
- if (urls.size() != 1) {
- quiche::QuichePrintCommandLineFlagHelp(usage);
- exit(0);
- }
-
- quic::QuicEpollClientFactory factory;
- quic::QuicToyClient client(&factory);
- return client.SendRequestsAndPrintResponses(urls);
-}
diff --git a/chromium/net/third_party/quiche/src/quic/tools/quic_client_epoll_network_helper.cc b/chromium/net/third_party/quiche/src/quic/tools/quic_client_epoll_network_helper.cc
deleted file mode 100644
index 9dcc2b35213..00000000000
--- a/chromium/net/third_party/quiche/src/quic/tools/quic_client_epoll_network_helper.cc
+++ /dev/null
@@ -1,227 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/tools/quic_client_epoll_network_helper.h"
-
-#include <errno.h>
-#include <netinet/in.h>
-#include <string.h>
-#include <sys/epoll.h>
-#include <sys/socket.h>
-#include <unistd.h>
-
-#include "quic/core/crypto/quic_random.h"
-#include "quic/core/http/spdy_utils.h"
-#include "quic/core/quic_connection.h"
-#include "quic/core/quic_data_reader.h"
-#include "quic/core/quic_epoll_alarm_factory.h"
-#include "quic/core/quic_epoll_connection_helper.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_server_id.h"
-#include "quic/core/quic_udp_socket.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/platform/api/quic_system_event_loop.h"
-
-namespace quic {
-
-namespace {
-const int kEpollFlags = EPOLLIN | EPOLLOUT | EPOLLET;
-} // namespace
-
-QuicClientEpollNetworkHelper::QuicClientEpollNetworkHelper(
- QuicEpollServer* epoll_server,
- QuicClientBase* client)
- : epoll_server_(epoll_server),
- packets_dropped_(0),
- overflow_supported_(false),
- packet_reader_(new QuicPacketReader()),
- client_(client),
- max_reads_per_epoll_loop_(std::numeric_limits<int>::max()) {}
-
-QuicClientEpollNetworkHelper::~QuicClientEpollNetworkHelper() {
- if (client_->connected()) {
- client_->session()->connection()->CloseConnection(
- QUIC_PEER_GOING_AWAY, "Client being torn down",
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
- }
-
- CleanUpAllUDPSockets();
-}
-
-std::string QuicClientEpollNetworkHelper::Name() const {
- return "QuicClientEpollNetworkHelper";
-}
-
-bool QuicClientEpollNetworkHelper::CreateUDPSocketAndBind(
- QuicSocketAddress server_address,
- QuicIpAddress bind_to_address,
- int bind_to_port) {
- epoll_server_->set_timeout_in_us(50 * 1000);
-
- int fd = CreateUDPSocket(server_address, &overflow_supported_);
- if (fd < 0) {
- return false;
- }
-
- QuicSocketAddress client_address;
- if (bind_to_address.IsInitialized()) {
- client_address = QuicSocketAddress(bind_to_address, client_->local_port());
- } else if (server_address.host().address_family() == IpAddressFamily::IP_V4) {
- client_address = QuicSocketAddress(QuicIpAddress::Any4(), bind_to_port);
- } else {
- client_address = QuicSocketAddress(QuicIpAddress::Any6(), bind_to_port);
- }
-
- // Some platforms expect that the addrlen given to bind() exactly matches the
- // size of the associated protocol family's sockaddr struct.
- // TODO(b/179430548): Revert this when affected platforms are updated to
- // to support binding with an addrelen of sizeof(sockaddr_storage)
- socklen_t addrlen;
- switch (client_address.host().address_family()) {
- case IpAddressFamily::IP_V4:
- addrlen = sizeof(sockaddr_in);
- break;
- case IpAddressFamily::IP_V6:
- addrlen = sizeof(sockaddr_in6);
- break;
- case IpAddressFamily::IP_UNSPEC:
- addrlen = 0;
- break;
- }
-
- sockaddr_storage addr = client_address.generic_address();
- int rc = bind(fd, reinterpret_cast<sockaddr*>(&addr), addrlen);
- if (rc < 0) {
- QUIC_LOG(ERROR) << "Bind failed: " << strerror(errno)
- << " bind_to_address:" << bind_to_address
- << ", bind_to_port:" << bind_to_port
- << ", client_address:" << client_address;
- return false;
- }
-
- if (client_address.FromSocket(fd) != 0) {
- QUIC_LOG(ERROR) << "Unable to get self address. Error: "
- << strerror(errno);
- }
-
- fd_address_map_[fd] = client_address;
- epoll_server_->RegisterFD(fd, this, kEpollFlags);
- return true;
-}
-
-void QuicClientEpollNetworkHelper::CleanUpUDPSocket(int fd) {
- CleanUpUDPSocketImpl(fd);
- fd_address_map_.erase(fd);
-}
-
-void QuicClientEpollNetworkHelper::CleanUpAllUDPSockets() {
- for (std::pair<int, QuicSocketAddress> fd_address : fd_address_map_) {
- CleanUpUDPSocketImpl(fd_address.first);
- }
- fd_address_map_.clear();
-}
-
-void QuicClientEpollNetworkHelper::CleanUpUDPSocketImpl(int fd) {
- if (fd > -1) {
- epoll_server_->UnregisterFD(fd);
- int rc = close(fd);
- QUICHE_DCHECK_EQ(0, rc);
- }
-}
-
-void QuicClientEpollNetworkHelper::RunEventLoop() {
- QuicRunSystemEventLoopIteration();
- epoll_server_->WaitForEventsAndExecuteCallbacks();
-}
-
-void QuicClientEpollNetworkHelper::OnRegistration(QuicEpollServer* /*eps*/,
- int /*fd*/,
- int /*event_mask*/) {}
-void QuicClientEpollNetworkHelper::OnModification(int /*fd*/,
- int /*event_mask*/) {}
-void QuicClientEpollNetworkHelper::OnUnregistration(int /*fd*/,
- bool /*replaced*/) {}
-void QuicClientEpollNetworkHelper::OnShutdown(QuicEpollServer* /*eps*/,
- int /*fd*/) {}
-
-void QuicClientEpollNetworkHelper::OnEvent(int fd, QuicEpollEvent* event) {
- if (event->in_events & EPOLLIN) {
- QUIC_DVLOG(1) << "Read packets on EPOLLIN";
- int times_to_read = max_reads_per_epoll_loop_;
- bool more_to_read = true;
- QuicPacketCount packets_dropped = 0;
- while (client_->connected() && more_to_read && times_to_read > 0) {
- more_to_read = packet_reader_->ReadAndDispatchPackets(
- fd, GetLatestClientAddress().port(), *client_->helper()->GetClock(),
- this, overflow_supported_ ? &packets_dropped : nullptr);
- --times_to_read;
- }
- if (packets_dropped_ < packets_dropped) {
- QUIC_LOG(ERROR)
- << packets_dropped - packets_dropped_
- << " more packets are dropped in the socket receive buffer.";
- packets_dropped_ = packets_dropped;
- }
- if (client_->connected() && more_to_read) {
- event->out_ready_mask |= EPOLLIN;
- }
- }
- if (client_->connected() && (event->in_events & EPOLLOUT)) {
- client_->writer()->SetWritable();
- client_->session()->connection()->OnCanWrite();
- }
- if (event->in_events & EPOLLERR) {
- QUIC_DLOG(INFO) << "Epollerr";
- }
-}
-
-QuicPacketWriter* QuicClientEpollNetworkHelper::CreateQuicPacketWriter() {
- return new QuicDefaultPacketWriter(GetLatestFD());
-}
-
-void QuicClientEpollNetworkHelper::SetClientPort(int port) {
- fd_address_map_.back().second =
- QuicSocketAddress(GetLatestClientAddress().host(), port);
-}
-
-QuicSocketAddress QuicClientEpollNetworkHelper::GetLatestClientAddress() const {
- if (fd_address_map_.empty()) {
- return QuicSocketAddress();
- }
-
- return fd_address_map_.back().second;
-}
-
-int QuicClientEpollNetworkHelper::GetLatestFD() const {
- if (fd_address_map_.empty()) {
- return -1;
- }
-
- return fd_address_map_.back().first;
-}
-
-void QuicClientEpollNetworkHelper::ProcessPacket(
- const QuicSocketAddress& self_address,
- const QuicSocketAddress& peer_address,
- const QuicReceivedPacket& packet) {
- client_->session()->ProcessUdpPacket(self_address, peer_address, packet);
-}
-
-int QuicClientEpollNetworkHelper::CreateUDPSocket(
- QuicSocketAddress server_address,
- bool* overflow_supported) {
- QuicUdpSocketApi api;
- int fd = api.Create(server_address.host().AddressFamilyToInt(),
- /*receive_buffer_size =*/kDefaultSocketReceiveBuffer,
- /*send_buffer_size =*/kDefaultSocketReceiveBuffer);
- if (fd < 0) {
- return fd;
- }
-
- *overflow_supported = api.EnableDroppedPacketCount(fd);
- api.EnableReceiveTimestamp(fd);
- return fd;
-}
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/tools/quic_client_epoll_network_helper.h b/chromium/net/third_party/quiche/src/quic/tools/quic_client_epoll_network_helper.h
deleted file mode 100644
index bb8a898384c..00000000000
--- a/chromium/net/third_party/quiche/src/quic/tools/quic_client_epoll_network_helper.h
+++ /dev/null
@@ -1,135 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// An implementation of the QuicClientBase::NetworkHelper
-// that is based off the epoll server.
-
-#ifndef QUICHE_QUIC_TOOLS_QUIC_CLIENT_EPOLL_NETWORK_HELPER_H_
-#define QUICHE_QUIC_TOOLS_QUIC_CLIENT_EPOLL_NETWORK_HELPER_H_
-
-#include <cstdint>
-#include <memory>
-#include <string>
-
-#include "quic/core/http/quic_client_push_promise_index.h"
-#include "quic/core/quic_config.h"
-#include "quic/core/quic_packet_reader.h"
-#include "quic/platform/api/quic_epoll.h"
-#include "quic/tools/quic_client_base.h"
-#include "common/quiche_linked_hash_map.h"
-
-namespace quic {
-
-namespace test {
-class QuicClientPeer;
-} // namespace test
-
-// An implementation of the QuicClientBase::NetworkHelper based off
-// the epoll server.
-class QuicClientEpollNetworkHelper : public QuicClientBase::NetworkHelper,
- public QuicEpollCallbackInterface,
- public ProcessPacketInterface {
- public:
- // Create a quic client, which will have events managed by an externally owned
- // EpollServer.
- QuicClientEpollNetworkHelper(QuicEpollServer* epoll_server,
- QuicClientBase* client);
- QuicClientEpollNetworkHelper(const QuicClientEpollNetworkHelper&) = delete;
- QuicClientEpollNetworkHelper& operator=(const QuicClientEpollNetworkHelper&) =
- delete;
-
- ~QuicClientEpollNetworkHelper() override;
-
- // Return a name describing the class for use in debug/error reporting.
- std::string Name() const override;
-
- // From EpollCallbackInterface
- void OnRegistration(QuicEpollServer* eps, int fd, int event_mask) override;
- void OnModification(int fd, int event_mask) override;
- void OnEvent(int fd, QuicEpollEvent* event) override;
- // |fd_| can be unregistered without the client being disconnected. This
- // happens in b3m QuicProber where we unregister |fd_| to feed in events to
- // the client from the SelectServer.
- void OnUnregistration(int fd, bool replaced) override;
- void OnShutdown(QuicEpollServer* eps, int fd) override;
-
- // From ProcessPacketInterface. This will be called for each received
- // packet.
- void ProcessPacket(const QuicSocketAddress& self_address,
- const QuicSocketAddress& peer_address,
- const QuicReceivedPacket& packet) override;
-
- // From NetworkHelper.
- void RunEventLoop() override;
- bool CreateUDPSocketAndBind(QuicSocketAddress server_address,
- QuicIpAddress bind_to_address,
- int bind_to_port) override;
- void CleanUpAllUDPSockets() override;
- QuicSocketAddress GetLatestClientAddress() const override;
- QuicPacketWriter* CreateQuicPacketWriter() override;
-
- // Accessors provided for convenience, not part of any interface.
-
- QuicEpollServer* epoll_server() { return epoll_server_; }
-
- const quiche::QuicheLinkedHashMap<int, QuicSocketAddress>& fd_address_map()
- const {
- return fd_address_map_;
- }
-
- // If the client has at least one UDP socket, return the latest created one.
- // Otherwise, return -1.
- int GetLatestFD() const;
-
- // Create socket for connection to |server_address| with default socket
- // options.
- // Return fd index.
- virtual int CreateUDPSocket(QuicSocketAddress server_address,
- bool* overflow_supported);
-
- QuicClientBase* client() { return client_; }
-
- void set_max_reads_per_epoll_loop(int num_reads) {
- max_reads_per_epoll_loop_ = num_reads;
- }
- // If |fd| is an open UDP socket, unregister and close it. Otherwise, do
- // nothing.
- void CleanUpUDPSocket(int fd);
-
- private:
- friend class test::QuicClientPeer;
-
- // Used for testing.
- void SetClientPort(int port);
-
- // Actually clean up |fd|.
- void CleanUpUDPSocketImpl(int fd);
-
- // Listens for events on the client socket.
- QuicEpollServer* epoll_server_;
-
- // Map mapping created UDP sockets to their addresses. By using linked hash
- // map, the order of socket creation can be recorded.
- quiche::QuicheLinkedHashMap<int, QuicSocketAddress> fd_address_map_;
-
- // If overflow_supported_ is true, this will be the number of packets dropped
- // during the lifetime of the server.
- QuicPacketCount packets_dropped_;
-
- // True if the kernel supports SO_RXQ_OVFL, the number of packets dropped
- // because the socket would otherwise overflow.
- bool overflow_supported_;
-
- // Point to a QuicPacketReader object on the heap. The reader allocates more
- // space than allowed on the stack.
- std::unique_ptr<QuicPacketReader> packet_reader_;
-
- QuicClientBase* client_;
-
- int max_reads_per_epoll_loop_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_TOOLS_QUIC_CLIENT_EPOLL_NETWORK_HELPER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/tools/quic_client_interop_test_bin.cc b/chromium/net/third_party/quiche/src/quic/tools/quic_client_interop_test_bin.cc
deleted file mode 100644
index 6c14cc3e308..00000000000
--- a/chromium/net/third_party/quiche/src/quic/tools/quic_client_interop_test_bin.cc
+++ /dev/null
@@ -1,467 +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 <iostream>
-#include <memory>
-#include <string>
-#include <utility>
-
-#include "absl/strings/str_cat.h"
-#include "quic/core/crypto/quic_client_session_cache.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_versions.h"
-#include "quic/platform/api/quic_epoll.h"
-#include "quic/platform/api/quic_system_event_loop.h"
-#include "net/quic/platform/impl/quic_epoll_clock.h"
-#include "quic/test_tools/quic_connection_peer.h"
-#include "quic/test_tools/quic_session_peer.h"
-#include "quic/tools/fake_proof_verifier.h"
-#include "quic/tools/quic_client.h"
-#include "quic/tools/quic_url.h"
-#include "common/platform/api/quiche_command_line_flags.h"
-
-DEFINE_QUICHE_COMMAND_LINE_FLAG(std::string, host, "",
- "The IP or hostname to connect to.");
-
-DEFINE_QUICHE_COMMAND_LINE_FLAG(
- std::string, quic_version, "",
- "The QUIC version to use. Defaults to most recent IETF QUIC version.");
-
-DEFINE_QUICHE_COMMAND_LINE_FLAG(int32_t, port, 0, "The port to connect to.");
-
-namespace quic {
-
-enum class Feature {
- // First row of features ("table stakes")
- // A version negotiation response is elicited and acted on.
- kVersionNegotiation,
- // The handshake completes successfully.
- kHandshake,
- // Stream data is being exchanged and ACK'ed.
- kStreamData,
- // The connection close procedcure completes with a zero error code.
- kConnectionClose,
- // The connection was established using TLS resumption.
- kResumption,
- // 0-RTT data is being sent and acted on.
- kZeroRtt,
- // A RETRY packet was successfully processed.
- kRetry,
- // A handshake using a ClientHello that spans multiple packets completed
- // successfully.
- kQuantum,
-
- // Second row of features (anything else protocol-related)
- // We switched to a different port and the server migrated to it.
- kRebinding,
- // One endpoint can update keys and its peer responds correctly.
- kKeyUpdate,
-
- // Third row of features (H3 tests)
- // An H3 transaction succeeded.
- kHttp3,
- // One or both endpoints insert entries into dynamic table and subsequenly
- // reference them from header blocks.
- kDynamicEntryReferenced,
-};
-
-char MatrixLetter(Feature f) {
- switch (f) {
- case Feature::kVersionNegotiation:
- return 'V';
- case Feature::kHandshake:
- return 'H';
- case Feature::kStreamData:
- return 'D';
- case Feature::kConnectionClose:
- return 'C';
- case Feature::kResumption:
- return 'R';
- case Feature::kZeroRtt:
- return 'Z';
- case Feature::kRetry:
- return 'S';
- case Feature::kQuantum:
- return 'Q';
- case Feature::kRebinding:
- return 'B';
- case Feature::kKeyUpdate:
- return 'U';
- case Feature::kHttp3:
- return '3';
- case Feature::kDynamicEntryReferenced:
- return 'd';
- }
-}
-
-class QuicClientInteropRunner : QuicConnectionDebugVisitor {
- public:
- QuicClientInteropRunner() {}
-
- void InsertFeature(Feature feature) { features_.insert(feature); }
-
- std::set<Feature> features() const { return features_; }
-
- // Attempts a resumption using |client| by disconnecting and reconnecting. If
- // resumption is successful, |features_| is modified to add
- // Feature::kResumption to it, otherwise it is left unmodified.
- void AttemptResumption(QuicClient* client, const std::string& authority);
-
- void AttemptRequest(QuicSocketAddress addr,
- std::string authority,
- QuicServerId server_id,
- ParsedQuicVersion version,
- bool test_version_negotiation,
- bool attempt_rebind,
- bool attempt_multi_packet_chlo,
- bool attempt_key_update);
-
- // Constructs a SpdyHeaderBlock containing the pseudo-headers needed to make a
- // GET request to "/" on the hostname |authority|.
- spdy::Http2HeaderBlock ConstructHeaderBlock(const std::string& authority);
-
- // Sends an HTTP request represented by |header_block| using |client|.
- void SendRequest(QuicClient* client,
- const spdy::Http2HeaderBlock& header_block);
-
- void OnConnectionCloseFrame(const QuicConnectionCloseFrame& frame) override {
- switch (frame.close_type) {
- case GOOGLE_QUIC_CONNECTION_CLOSE:
- QUIC_LOG(ERROR) << "Received unexpected GoogleQUIC connection close";
- break;
- case IETF_QUIC_TRANSPORT_CONNECTION_CLOSE:
- if (frame.wire_error_code == NO_IETF_QUIC_ERROR) {
- InsertFeature(Feature::kConnectionClose);
- } else {
- QUIC_LOG(ERROR) << "Received transport connection close "
- << QuicIetfTransportErrorCodeString(
- static_cast<QuicIetfTransportErrorCodes>(
- frame.wire_error_code));
- }
- break;
- case IETF_QUIC_APPLICATION_CONNECTION_CLOSE:
- if (frame.wire_error_code == 0) {
- InsertFeature(Feature::kConnectionClose);
- } else {
- QUIC_LOG(ERROR) << "Received application connection close "
- << frame.wire_error_code;
- }
- break;
- }
- }
-
- void OnVersionNegotiationPacket(
- const QuicVersionNegotiationPacket& /*packet*/) override {
- InsertFeature(Feature::kVersionNegotiation);
- }
-
- private:
- std::set<Feature> features_;
-};
-
-void QuicClientInteropRunner::AttemptResumption(QuicClient* client,
- const std::string& authority) {
- client->Disconnect();
- if (!client->Initialize()) {
- QUIC_LOG(ERROR) << "Failed to reinitialize client";
- return;
- }
- if (!client->Connect()) {
- return;
- }
-
- bool zero_rtt_attempt = !client->session()->OneRttKeysAvailable();
-
- spdy::Http2HeaderBlock header_block = ConstructHeaderBlock(authority);
- SendRequest(client, header_block);
-
- if (!client->session()->OneRttKeysAvailable()) {
- return;
- }
-
- if (static_cast<QuicCryptoClientStream*>(
- test::QuicSessionPeer::GetMutableCryptoStream(client->session()))
- ->IsResumption()) {
- InsertFeature(Feature::kResumption);
- }
- if (static_cast<QuicCryptoClientStream*>(
- test::QuicSessionPeer::GetMutableCryptoStream(client->session()))
- ->EarlyDataAccepted() &&
- zero_rtt_attempt && client->latest_response_code() != -1) {
- InsertFeature(Feature::kZeroRtt);
- }
-}
-
-void QuicClientInteropRunner::AttemptRequest(QuicSocketAddress addr,
- std::string authority,
- QuicServerId server_id,
- ParsedQuicVersion version,
- bool test_version_negotiation,
- bool attempt_rebind,
- bool attempt_multi_packet_chlo,
- bool attempt_key_update) {
- ParsedQuicVersionVector versions = {version};
- if (test_version_negotiation) {
- versions.insert(versions.begin(), QuicVersionReservedForNegotiation());
- }
-
- auto proof_verifier = std::make_unique<FakeProofVerifier>();
- auto session_cache = std::make_unique<QuicClientSessionCache>();
- QuicEpollServer epoll_server;
- QuicEpollClock epoll_clock(&epoll_server);
- QuicConfig config;
- QuicTime::Delta timeout = QuicTime::Delta::FromSeconds(20);
- config.SetIdleNetworkTimeout(timeout);
- if (attempt_multi_packet_chlo) {
- // Make the ClientHello span multiple packets by adding a custom transport
- // parameter.
- constexpr auto kCustomParameter =
- static_cast<TransportParameters::TransportParameterId>(0x173E);
- std::string custom_value(2000, '?');
- config.custom_transport_parameters_to_send()[kCustomParameter] =
- custom_value;
- }
- auto client = std::make_unique<QuicClient>(
- addr, server_id, versions, config, &epoll_server,
- std::move(proof_verifier), std::move(session_cache));
- client->set_connection_debug_visitor(this);
- if (!client->Initialize()) {
- QUIC_LOG(ERROR) << "Failed to initialize client";
- return;
- }
- const bool connect_result = client->Connect();
- QuicConnection* connection = client->session()->connection();
- if (connection == nullptr) {
- QUIC_LOG(ERROR) << "No QuicConnection object";
- return;
- }
- QuicConnectionStats client_stats = connection->GetStats();
- if (client_stats.retry_packet_processed) {
- InsertFeature(Feature::kRetry);
- }
- if (test_version_negotiation && connection->version() == version) {
- InsertFeature(Feature::kVersionNegotiation);
- }
- if (test_version_negotiation && !connect_result) {
- // Failed to negotiate version, retry without version negotiation.
- AttemptRequest(addr, authority, server_id, version,
- /*test_version_negotiation=*/false, attempt_rebind,
- attempt_multi_packet_chlo, attempt_key_update);
- return;
- }
- if (!client->session()->OneRttKeysAvailable()) {
- if (attempt_multi_packet_chlo) {
- // Failed to handshake with multi-packet client hello, retry without it.
- AttemptRequest(addr, authority, server_id, version,
- test_version_negotiation, attempt_rebind,
- /*attempt_multi_packet_chlo=*/false, attempt_key_update);
- return;
- }
- return;
- }
- InsertFeature(Feature::kHandshake);
- if (attempt_multi_packet_chlo) {
- InsertFeature(Feature::kQuantum);
- }
-
- spdy::Http2HeaderBlock header_block = ConstructHeaderBlock(authority);
- SendRequest(client.get(), header_block);
-
- if (!client->connected()) {
- return;
- }
-
- if (client->latest_response_code() != -1) {
- InsertFeature(Feature::kHttp3);
-
- if (client->client_session()->dynamic_table_entry_referenced()) {
- InsertFeature(Feature::kDynamicEntryReferenced);
- }
-
- if (attempt_rebind) {
- // Now make a second request after switching to a different client port.
- if (client->ChangeEphemeralPort()) {
- client->SendRequestAndWaitForResponse(header_block, "", /*fin=*/true);
- if (!client->connected()) {
- // Rebinding does not work, retry without attempting it.
- AttemptRequest(addr, authority, server_id, version,
- test_version_negotiation, /*attempt_rebind=*/false,
- attempt_multi_packet_chlo, attempt_key_update);
- return;
- }
- InsertFeature(Feature::kRebinding);
-
- if (client->client_session()->dynamic_table_entry_referenced()) {
- InsertFeature(Feature::kDynamicEntryReferenced);
- }
- } else {
- QUIC_LOG(ERROR) << "Failed to change ephemeral port";
- }
- }
-
- if (attempt_key_update) {
- if (connection->IsKeyUpdateAllowed()) {
- if (connection->InitiateKeyUpdate(
- KeyUpdateReason::kLocalForInteropRunner)) {
- client->SendRequestAndWaitForResponse(header_block, "", /*fin=*/true);
- if (!client->connected()) {
- // Key update does not work, retry without attempting it.
- AttemptRequest(addr, authority, server_id, version,
- test_version_negotiation, attempt_rebind,
- attempt_multi_packet_chlo,
- /*attempt_key_update=*/false);
- return;
- }
- InsertFeature(Feature::kKeyUpdate);
- } else {
- QUIC_LOG(ERROR) << "Failed to initiate key update";
- }
- } else {
- QUIC_LOG(ERROR) << "Key update not allowed";
- }
- }
- }
-
- if (connection->connected()) {
- connection->CloseConnection(
- QUIC_NO_ERROR, "Graceful close",
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
- InsertFeature(Feature::kConnectionClose);
- }
-
- AttemptResumption(client.get(), authority);
-}
-
-spdy::Http2HeaderBlock QuicClientInteropRunner::ConstructHeaderBlock(
- const std::string& authority) {
- // Construct and send a request.
- spdy::Http2HeaderBlock header_block;
- header_block[":method"] = "GET";
- header_block[":scheme"] = "https";
- header_block[":authority"] = authority;
- header_block[":path"] = "/";
- return header_block;
-}
-
-void QuicClientInteropRunner::SendRequest(
- QuicClient* client,
- const spdy::Http2HeaderBlock& header_block) {
- client->set_store_response(true);
- client->SendRequestAndWaitForResponse(header_block, "", /*fin=*/true);
-
- QuicConnection* connection = client->session()->connection();
- if (connection == nullptr) {
- QUIC_LOG(ERROR) << "No QuicConnection object";
- return;
- }
- QuicConnectionStats client_stats = connection->GetStats();
- QuicSentPacketManager* sent_packet_manager =
- test::QuicConnectionPeer::GetSentPacketManager(connection);
- const bool received_forward_secure_ack =
- sent_packet_manager != nullptr &&
- sent_packet_manager->GetLargestAckedPacket(ENCRYPTION_FORWARD_SECURE)
- .IsInitialized();
- if (client_stats.stream_bytes_received > 0 && received_forward_secure_ack) {
- InsertFeature(Feature::kStreamData);
- }
-}
-
-std::set<Feature> ServerSupport(std::string dns_host,
- std::string url_host,
- int port,
- ParsedQuicVersion version) {
- std::cout << "Attempting interop with version " << version << std::endl;
-
- // Build the client, and try to connect.
- QuicSocketAddress addr = tools::LookupAddress(dns_host, absl::StrCat(port));
- if (!addr.IsInitialized()) {
- QUIC_LOG(ERROR) << "Failed to resolve " << dns_host;
- return std::set<Feature>();
- }
- QuicServerId server_id(url_host, port, false);
- std::string authority = absl::StrCat(url_host, ":", port);
-
- QuicClientInteropRunner runner;
-
- runner.AttemptRequest(addr, authority, server_id, version,
- /*test_version_negotiation=*/true,
- /*attempt_rebind=*/true,
- /*attempt_multi_packet_chlo=*/true,
- /*attempt_key_update=*/true);
-
- return runner.features();
-}
-
-} // namespace quic
-
-int main(int argc, char* argv[]) {
- QuicSystemEventLoop event_loop("quic_client");
- const char* usage = "Usage: quic_client_interop_test [options] [url]";
-
- std::vector<std::string> args =
- quiche::QuicheParseCommandLineFlags(usage, argc, argv);
- if (args.size() > 1) {
- quiche::QuichePrintCommandLineFlagHelp(usage);
- exit(1);
- }
- std::string dns_host = GetQuicFlag(FLAGS_host);
- std::string url_host = "";
- int port = GetQuicFlag(FLAGS_port);
-
- if (!args.empty()) {
- quic::QuicUrl url(args[0], "https");
- url_host = url.host();
- if (dns_host.empty()) {
- dns_host = url_host;
- }
- if (port == 0) {
- port = url.port();
- }
- }
- if (port == 0) {
- port = 443;
- }
- if (dns_host.empty()) {
- quiche::QuichePrintCommandLineFlagHelp(usage);
- exit(1);
- }
- if (url_host.empty()) {
- url_host = dns_host;
- }
-
- // Pick QUIC version to use.
- quic::QuicVersionInitializeSupportForIetfDraft();
- quic::ParsedQuicVersion version = quic::UnsupportedQuicVersion();
- std::string quic_version_string = GetQuicFlag(FLAGS_quic_version);
- if (!quic_version_string.empty()) {
- version = quic::ParseQuicVersionString(quic_version_string);
- } else {
- for (const quic::ParsedQuicVersion& vers : quic::AllSupportedVersions()) {
- // Use the most recent IETF QUIC version.
- if (vers.HasIetfQuicFrames() && vers.UsesHttp3() && vers.UsesTls()) {
- version = vers;
- break;
- }
- }
- }
- QUICHE_CHECK(version.IsKnown());
- QuicEnableVersion(version);
-
- auto supported_features =
- quic::ServerSupport(dns_host, url_host, port, version);
- std::cout << "Results for " << url_host << ":" << port << std::endl;
- int current_row = 1;
- for (auto feature : supported_features) {
- if (current_row < 2 && feature >= quic::Feature::kRebinding) {
- std::cout << std::endl;
- current_row = 2;
- }
- if (current_row < 3 && feature >= quic::Feature::kHttp3) {
- std::cout << std::endl;
- current_row = 3;
- }
- std::cout << MatrixLetter(feature);
- }
- std::cout << std::endl;
-}
diff --git a/chromium/net/third_party/quiche/src/quic/tools/quic_client_test.cc b/chromium/net/third_party/quiche/src/quic/tools/quic_client_test.cc
deleted file mode 100644
index d932a7b533a..00000000000
--- a/chromium/net/third_party/quiche/src/quic/tools/quic_client_test.cc
+++ /dev/null
@@ -1,129 +0,0 @@
-// Copyright (c) 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/tools/quic_client.h"
-
-#include <dirent.h>
-#include <sys/types.h>
-
-#include <memory>
-#include <utility>
-
-#include "absl/strings/match.h"
-#include "absl/strings/string_view.h"
-#include "quic/platform/api/quic_epoll.h"
-#include "quic/platform/api/quic_port_utils.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/platform/api/quic_test_loopback.h"
-#include "quic/test_tools/crypto_test_utils.h"
-#include "quic/test_tools/quic_client_peer.h"
-#include "common/quiche_text_utils.h"
-
-namespace quic {
-namespace test {
-namespace {
-
-const char* kPathToFds = "/proc/self/fd";
-
-std::string ReadLink(const std::string& path) {
- std::string result(PATH_MAX, '\0');
- ssize_t result_size = readlink(path.c_str(), &result[0], result.size());
- QUICHE_CHECK(result_size > 0 &&
- static_cast<size_t>(result_size) < result.size());
- result.resize(result_size);
- return result;
-}
-
-// Counts the number of open sockets for the current process.
-size_t NumOpenSocketFDs() {
- size_t socket_count = 0;
- dirent* file;
- std::unique_ptr<DIR, int (*)(DIR*)> fd_directory(opendir(kPathToFds),
- closedir);
- while ((file = readdir(fd_directory.get())) != nullptr) {
- absl::string_view name(file->d_name);
- if (name == "." || name == "..") {
- continue;
- }
-
- std::string fd_path = ReadLink(absl::StrCat(kPathToFds, "/", name));
- if (absl::StartsWith(fd_path, "socket:")) {
- socket_count++;
- }
- }
- return socket_count;
-}
-
-class QuicClientTest : public QuicTest {
- public:
- QuicClientTest() {
- // Creates and destroys a single client first which may open persistent
- // sockets when initializing platform dependencies like certificate
- // verifier. Future creation of addtional clients will deterministically
- // open one socket per client.
- CreateAndInitializeQuicClient();
- }
-
- // Creates a new QuicClient and Initializes it on an unused port.
- // Caller is responsible for deletion.
- std::unique_ptr<QuicClient> CreateAndInitializeQuicClient() {
- uint16_t port = QuicPickServerPortForTestsOrDie();
- QuicSocketAddress server_address(QuicSocketAddress(TestLoopback(), port));
- QuicServerId server_id("hostname", server_address.port(), false);
- ParsedQuicVersionVector versions = AllSupportedVersions();
- auto client = std::make_unique<QuicClient>(
- server_address, server_id, versions, &epoll_server_,
- crypto_test_utils::ProofVerifierForTesting());
- EXPECT_TRUE(client->Initialize());
- return client;
- }
-
- private:
- QuicEpollServer epoll_server_;
-};
-
-TEST_F(QuicClientTest, DoNotLeakSocketFDs) {
- // Make sure that the QuicClient doesn't leak socket FDs. Doing so could cause
- // port exhaustion in long running processes which repeatedly create clients.
-
- // Record the initial number of FDs.
- size_t number_of_open_fds = NumOpenSocketFDs();
-
- // Create a number of clients, initialize them, and verify this has resulted
- // in additional FDs being opened.
- const int kNumClients = 50;
- for (int i = 0; i < kNumClients; ++i) {
- EXPECT_EQ(number_of_open_fds, NumOpenSocketFDs());
- std::unique_ptr<QuicClient> client(CreateAndInitializeQuicClient());
- // Initializing the client will create a new FD.
- EXPECT_EQ(number_of_open_fds + 1, NumOpenSocketFDs());
- }
-
- // The FDs created by the QuicClients should now be closed.
- EXPECT_EQ(number_of_open_fds, NumOpenSocketFDs());
-}
-
-TEST_F(QuicClientTest, CreateAndCleanUpUDPSockets) {
- size_t number_of_open_fds = NumOpenSocketFDs();
-
- std::unique_ptr<QuicClient> client(CreateAndInitializeQuicClient());
- // Creating and initializing a client will result in one socket being opened.
- EXPECT_EQ(number_of_open_fds + 1, NumOpenSocketFDs());
-
- // Create more UDP sockets.
- EXPECT_TRUE(QuicClientPeer::CreateUDPSocketAndBind(client.get()));
- EXPECT_EQ(number_of_open_fds + 2, NumOpenSocketFDs());
- EXPECT_TRUE(QuicClientPeer::CreateUDPSocketAndBind(client.get()));
- EXPECT_EQ(number_of_open_fds + 3, NumOpenSocketFDs());
-
- // Clean up UDP sockets.
- QuicClientPeer::CleanUpUDPSocket(client.get(), client->GetLatestFD());
- EXPECT_EQ(number_of_open_fds + 2, NumOpenSocketFDs());
- QuicClientPeer::CleanUpUDPSocket(client.get(), client->GetLatestFD());
- EXPECT_EQ(number_of_open_fds + 1, NumOpenSocketFDs());
-}
-
-} // namespace
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/tools/quic_epoll_client_factory.cc b/chromium/net/third_party/quiche/src/quic/tools/quic_epoll_client_factory.cc
deleted file mode 100644
index 1fff089445b..00000000000
--- a/chromium/net/third_party/quiche/src/quic/tools/quic_epoll_client_factory.cc
+++ /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.
-
-#include "quic/tools/quic_epoll_client_factory.h"
-
-#include <netdb.h>
-#include <sys/socket.h>
-#include <sys/types.h>
-
-#include <utility>
-
-#include "absl/strings/str_cat.h"
-#include "quic/core/quic_server_id.h"
-#include "quic/platform/api/quic_socket_address.h"
-#include "quic/tools/quic_client.h"
-
-namespace quic {
-
-std::unique_ptr<QuicSpdyClientBase> QuicEpollClientFactory::CreateClient(
- std::string host_for_handshake,
- std::string host_for_lookup,
- int address_family_for_lookup,
- uint16_t port,
- ParsedQuicVersionVector versions,
- const QuicConfig& config,
- std::unique_ptr<ProofVerifier> verifier,
- std::unique_ptr<SessionCache> session_cache) {
- QuicSocketAddress addr = tools::LookupAddress(
- address_family_for_lookup, host_for_lookup, absl::StrCat(port));
- if (!addr.IsInitialized()) {
- QUIC_LOG(ERROR) << "Unable to resolve address: " << host_for_lookup;
- return nullptr;
- }
- QuicServerId server_id(host_for_handshake, port, false);
- return std::make_unique<QuicClient>(addr, server_id, versions, config,
- &epoll_server_, std::move(verifier),
- std::move(session_cache));
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/tools/quic_epoll_client_factory.h b/chromium/net/third_party/quiche/src/quic/tools/quic_epoll_client_factory.h
deleted file mode 100644
index 9e78b473619..00000000000
--- a/chromium/net/third_party/quiche/src/quic/tools/quic_epoll_client_factory.h
+++ /dev/null
@@ -1,32 +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_EPOLL_CLIENT_FACTORY_H_
-#define QUICHE_QUIC_TOOLS_EPOLL_CLIENT_FACTORY_H_
-
-#include "quic/platform/api/quic_epoll.h"
-#include "quic/tools/quic_toy_client.h"
-
-namespace quic {
-
-// Factory creating QuicClient instances.
-class QuicEpollClientFactory : public QuicToyClient::ClientFactory {
- public:
- std::unique_ptr<QuicSpdyClientBase> CreateClient(
- std::string host_for_handshake,
- std::string host_for_lookup,
- int address_family_for_lookup,
- uint16_t port,
- ParsedQuicVersionVector versions,
- const QuicConfig& config,
- std::unique_ptr<ProofVerifier> verifier,
- std::unique_ptr<SessionCache> session_cache) override;
-
- private:
- QuicEpollServer epoll_server_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_TOOLS_EPOLL_CLIENT_FACTORY_H_
diff --git a/chromium/net/third_party/quiche/src/quic/tools/quic_epoll_server_factory.cc b/chromium/net/third_party/quiche/src/quic/tools/quic_epoll_server_factory.cc
deleted file mode 100644
index 98c60ae09e1..00000000000
--- a/chromium/net/third_party/quiche/src/quic/tools/quic_epoll_server_factory.cc
+++ /dev/null
@@ -1,21 +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 "quic/tools/quic_epoll_server_factory.h"
-
-#include <utility>
-
-#include "quic/tools/quic_server.h"
-
-namespace quic {
-
-std::unique_ptr<quic::QuicSpdyServerBase> QuicEpollServerFactory::CreateServer(
- quic::QuicSimpleServerBackend* backend,
- std::unique_ptr<quic::ProofSource> proof_source,
- const quic::ParsedQuicVersionVector& supported_versions) {
- return std::make_unique<quic::QuicServer>(std::move(proof_source), backend,
- supported_versions);
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/tools/quic_epoll_server_factory.h b/chromium/net/third_party/quiche/src/quic/tools/quic_epoll_server_factory.h
deleted file mode 100644
index 7fc61fb7094..00000000000
--- a/chromium/net/third_party/quiche/src/quic/tools/quic_epoll_server_factory.h
+++ /dev/null
@@ -1,27 +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_EPOLL_SERVER_FACTORY_H_
-#define QUICHE_QUIC_TOOLS_EPOLL_SERVER_FACTORY_H_
-
-#include "quic/platform/api/quic_epoll.h"
-#include "quic/tools/quic_toy_server.h"
-
-namespace quic {
-
-// Factory creating QuicServer instances.
-class QuicEpollServerFactory : public QuicToyServer::ServerFactory {
- public:
- std::unique_ptr<QuicSpdyServerBase> CreateServer(
- QuicSimpleServerBackend* backend,
- std::unique_ptr<ProofSource> proof_source,
- const quic::ParsedQuicVersionVector& supported_versions) override;
-
- private:
- QuicEpollServer epoll_server_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_TOOLS_EPOLL_SERVER_FACTORY_H_
diff --git a/chromium/net/third_party/quiche/src/quic/tools/quic_memory_cache_backend.cc b/chromium/net/third_party/quiche/src/quic/tools/quic_memory_cache_backend.cc
deleted file mode 100644
index 19ac29a1deb..00000000000
--- a/chromium/net/third_party/quiche/src/quic/tools/quic_memory_cache_backend.cc
+++ /dev/null
@@ -1,496 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/tools/quic_memory_cache_backend.h"
-
-#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 "quic/core/http/spdy_utils.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/tools/web_transport_test_visitors.h"
-#include "common/platform/api/quiche_file_utils.h"
-#include "common/quiche_text_utils.h"
-
-using spdy::Http2HeaderBlock;
-using spdy::kV3LowestPriority;
-
-namespace quic {
-
-QuicMemoryCacheBackend::ResourceFile::ResourceFile(const std::string& file_name)
- : file_name_(file_name) {}
-
-QuicMemoryCacheBackend::ResourceFile::~ResourceFile() = default;
-
-void QuicMemoryCacheBackend::ResourceFile::Read() {
- absl::optional<std::string> maybe_file_contents =
- quiche::ReadFileContents(file_name_);
- if (!maybe_file_contents) {
- QUIC_LOG(DFATAL) << "Failed to read file for the memory cache backend: "
- << file_name_;
- return;
- }
- file_contents_ = *maybe_file_contents;
-
- // First read the headers.
- size_t start = 0;
- while (start < file_contents_.length()) {
- size_t pos = file_contents_.find('\n', start);
- if (pos == std::string::npos) {
- QUIC_LOG(DFATAL) << "Headers invalid or empty, ignoring: " << file_name_;
- return;
- }
- size_t len = pos - start;
- // Support both dos and unix line endings for convenience.
- if (file_contents_[pos - 1] == '\r') {
- len -= 1;
- }
- absl::string_view line(file_contents_.data() + start, len);
- start = pos + 1;
- // Headers end with an empty line.
- if (line.empty()) {
- break;
- }
- // Extract the status from the HTTP first line.
- if (line.substr(0, 4) == "HTTP") {
- pos = line.find(' ');
- if (pos == std::string::npos) {
- QUIC_LOG(DFATAL) << "Headers invalid or empty, ignoring: "
- << file_name_;
- return;
- }
- spdy_headers_[":status"] = line.substr(pos + 1, 3);
- continue;
- }
- // Headers are "key: value".
- pos = line.find(": ");
- if (pos == std::string::npos) {
- QUIC_LOG(DFATAL) << "Headers invalid or empty, ignoring: " << file_name_;
- return;
- }
- spdy_headers_.AppendValueOrAddHeader(
- quiche::QuicheTextUtils::ToLower(line.substr(0, pos)),
- line.substr(pos + 2));
- }
-
- // The connection header is prohibited in HTTP/2.
- spdy_headers_.erase("connection");
-
- // Override the URL with the X-Original-Url header, if present.
- auto it = spdy_headers_.find("x-original-url");
- if (it != spdy_headers_.end()) {
- x_original_url_ = it->second;
- HandleXOriginalUrl();
- }
-
- // X-Push-URL header is a relatively quick way to support sever push
- // in the toy server. A production server should use link=preload
- // stuff as described in https://w3c.github.io/preload/.
- it = spdy_headers_.find("x-push-url");
- if (it != spdy_headers_.end()) {
- absl::string_view push_urls = it->second;
- size_t start = 0;
- while (start < push_urls.length()) {
- size_t pos = push_urls.find('\0', start);
- if (pos == std::string::npos) {
- push_urls_.push_back(absl::string_view(push_urls.data() + start,
- push_urls.length() - start));
- break;
- }
- push_urls_.push_back(absl::string_view(push_urls.data() + start, pos));
- start += pos + 1;
- }
- }
-
- body_ = absl::string_view(file_contents_.data() + start,
- file_contents_.size() - start);
-}
-
-void QuicMemoryCacheBackend::ResourceFile::SetHostPathFromBase(
- absl::string_view base) {
- QUICHE_DCHECK(base[0] != '/') << base;
- size_t path_start = base.find_first_of('/');
- if (path_start == absl::string_view::npos) {
- host_ = std::string(base);
- path_ = "";
- return;
- }
-
- host_ = std::string(base.substr(0, path_start));
- size_t query_start = base.find_first_of(',');
- if (query_start > 0) {
- path_ = std::string(base.substr(path_start, query_start - 1));
- } else {
- path_ = std::string(base.substr(path_start));
- }
-}
-
-absl::string_view QuicMemoryCacheBackend::ResourceFile::RemoveScheme(
- absl::string_view url) {
- if (absl::StartsWith(url, "https://")) {
- url.remove_prefix(8);
- } else if (absl::StartsWith(url, "http://")) {
- url.remove_prefix(7);
- }
- return url;
-}
-
-void QuicMemoryCacheBackend::ResourceFile::HandleXOriginalUrl() {
- absl::string_view url(x_original_url_);
- SetHostPathFromBase(RemoveScheme(url));
-}
-
-const QuicBackendResponse* QuicMemoryCacheBackend::GetResponse(
- absl::string_view host, absl::string_view path) const {
- QuicWriterMutexLock lock(&response_mutex_);
-
- auto it = responses_.find(GetKey(host, path));
- if (it == responses_.end()) {
- uint64_t ignored = 0;
- if (generate_bytes_response_) {
- if (absl::SimpleAtoi(absl::string_view(path.data() + 1, path.size() - 1),
- &ignored)) {
- // The actual parsed length is ignored here and will be recomputed
- // by the caller.
- return generate_bytes_response_.get();
- }
- }
- QUIC_DVLOG(1) << "Get response for resource failed: host " << host
- << " path " << path;
- if (default_response_) {
- return default_response_.get();
- }
- return nullptr;
- }
- return it->second.get();
-}
-
-using ServerPushInfo = QuicBackendResponse::ServerPushInfo;
-using SpecialResponseType = QuicBackendResponse::SpecialResponseType;
-
-void QuicMemoryCacheBackend::AddSimpleResponse(absl::string_view host,
- absl::string_view path,
- int response_code,
- absl::string_view body) {
- Http2HeaderBlock response_headers;
- response_headers[":status"] = absl::StrCat(response_code);
- response_headers["content-length"] = absl::StrCat(body.length());
- AddResponse(host, path, std::move(response_headers), body);
-}
-
-void QuicMemoryCacheBackend::AddSimpleResponseWithServerPushResources(
- absl::string_view host, absl::string_view path, int response_code,
- absl::string_view body, std::list<ServerPushInfo> push_resources) {
- AddSimpleResponse(host, path, response_code, body);
- MaybeAddServerPushResources(host, path, push_resources);
-}
-
-void QuicMemoryCacheBackend::AddDefaultResponse(QuicBackendResponse* response) {
- QuicWriterMutexLock lock(&response_mutex_);
- default_response_.reset(response);
-}
-
-void QuicMemoryCacheBackend::AddResponse(absl::string_view host,
- absl::string_view path,
- Http2HeaderBlock response_headers,
- absl::string_view response_body) {
- AddResponseImpl(host, path, QuicBackendResponse::REGULAR_RESPONSE,
- std::move(response_headers), response_body,
- Http2HeaderBlock(), std::vector<spdy::Http2HeaderBlock>());
-}
-
-void QuicMemoryCacheBackend::AddResponse(absl::string_view host,
- absl::string_view path,
- Http2HeaderBlock response_headers,
- absl::string_view response_body,
- Http2HeaderBlock response_trailers) {
- AddResponseImpl(host, path, QuicBackendResponse::REGULAR_RESPONSE,
- std::move(response_headers), response_body,
- std::move(response_trailers),
- std::vector<spdy::Http2HeaderBlock>());
-}
-
-void QuicMemoryCacheBackend::AddResponseWithEarlyHints(
- absl::string_view host, absl::string_view path,
- spdy::Http2HeaderBlock response_headers, absl::string_view response_body,
- const std::vector<spdy::Http2HeaderBlock>& early_hints) {
- AddResponseImpl(host, path, QuicBackendResponse::REGULAR_RESPONSE,
- std::move(response_headers), response_body,
- Http2HeaderBlock(), early_hints);
-}
-
-void QuicMemoryCacheBackend::AddSpecialResponse(
- absl::string_view host, absl::string_view path,
- SpecialResponseType response_type) {
- AddResponseImpl(host, path, response_type, Http2HeaderBlock(), "",
- Http2HeaderBlock(), std::vector<spdy::Http2HeaderBlock>());
-}
-
-void QuicMemoryCacheBackend::AddSpecialResponse(
- absl::string_view host, absl::string_view path,
- spdy::Http2HeaderBlock response_headers, absl::string_view response_body,
- SpecialResponseType response_type) {
- AddResponseImpl(host, path, response_type, std::move(response_headers),
- response_body, Http2HeaderBlock(),
- std::vector<spdy::Http2HeaderBlock>());
-}
-
-QuicMemoryCacheBackend::QuicMemoryCacheBackend() : cache_initialized_(false) {}
-
-bool QuicMemoryCacheBackend::InitializeBackend(
- const std::string& cache_directory) {
- if (cache_directory.empty()) {
- QUIC_BUG(quic_bug_10932_1) << "cache_directory must not be empty.";
- return false;
- }
- QUIC_LOG(INFO)
- << "Attempting to initialize QuicMemoryCacheBackend from directory: "
- << cache_directory;
- std::vector<std::string> files;
- if (!quiche::EnumerateDirectoryRecursively(cache_directory, files)) {
- QUIC_BUG(QuicMemoryCacheBackend unreadable directory)
- << "Can't read QuicMemoryCacheBackend directory: " << cache_directory;
- return false;
- }
- std::list<std::unique_ptr<ResourceFile>> resource_files;
- for (const auto& filename : files) {
- std::unique_ptr<ResourceFile> resource_file(new ResourceFile(filename));
-
- // Tease apart filename into host and path.
- std::string base(resource_file->file_name());
- // Transform windows path separators to URL path separators.
- for (size_t i = 0; i < base.length(); ++i) {
- if (base[i] == '\\') {
- base[i] = '/';
- }
- }
- base.erase(0, cache_directory.length());
- if (base[0] == '/') {
- base.erase(0, 1);
- }
-
- resource_file->SetHostPathFromBase(base);
- resource_file->Read();
-
- AddResponse(resource_file->host(), resource_file->path(),
- resource_file->spdy_headers().Clone(), resource_file->body());
-
- resource_files.push_back(std::move(resource_file));
- }
-
- for (const auto& resource_file : resource_files) {
- std::list<ServerPushInfo> push_resources;
- for (const auto& push_url : resource_file->push_urls()) {
- QuicUrl url(push_url);
- const QuicBackendResponse* response = GetResponse(url.host(), url.path());
- if (!response) {
- QUIC_BUG(quic_bug_10932_2)
- << "Push URL '" << push_url << "' not found.";
- return false;
- }
- push_resources.push_back(ServerPushInfo(url, response->headers().Clone(),
- kV3LowestPriority,
- (std::string(response->body()))));
- }
- MaybeAddServerPushResources(resource_file->host(), resource_file->path(),
- push_resources);
- }
-
- cache_initialized_ = true;
- return true;
-}
-
-void QuicMemoryCacheBackend::GenerateDynamicResponses() {
- QuicWriterMutexLock lock(&response_mutex_);
- // Add a generate bytes response.
- spdy::Http2HeaderBlock response_headers;
- response_headers[":status"] = "200";
- generate_bytes_response_ = std::make_unique<QuicBackendResponse>();
- generate_bytes_response_->set_headers(std::move(response_headers));
- generate_bytes_response_->set_response_type(
- QuicBackendResponse::GENERATE_BYTES);
-}
-
-void QuicMemoryCacheBackend::EnableWebTransport() {
- enable_webtransport_ = true;
-}
-
-bool QuicMemoryCacheBackend::IsBackendInitialized() const {
- return cache_initialized_;
-}
-
-void QuicMemoryCacheBackend::FetchResponseFromBackend(
- const Http2HeaderBlock& request_headers,
- const std::string& /*request_body*/,
- QuicSimpleServerBackend::RequestHandler* quic_stream) {
- const QuicBackendResponse* quic_response = nullptr;
- // Find response in cache. If not found, send error response.
- auto authority = request_headers.find(":authority");
- auto path = request_headers.find(":path");
- if (authority != request_headers.end() && path != request_headers.end()) {
- quic_response = GetResponse(authority->second, path->second);
- }
-
- std::string request_url;
- if (authority != request_headers.end()) {
- request_url = std::string(authority->second);
- }
- if (path != request_headers.end()) {
- request_url += std::string(path->second);
- }
- QUIC_DVLOG(1)
- << "Fetching QUIC response from backend in-memory cache for url "
- << request_url;
- quic_stream->OnResponseBackendComplete(quic_response);
-}
-
-// The memory cache does not have a per-stream handler
-void QuicMemoryCacheBackend::CloseBackendResponseStream(
- QuicSimpleServerBackend::RequestHandler* /*quic_stream*/) {}
-
-std::list<ServerPushInfo> QuicMemoryCacheBackend::GetServerPushResources(
- std::string request_url) {
- QuicWriterMutexLock lock(&response_mutex_);
-
- std::list<ServerPushInfo> resources;
- auto resource_range = server_push_resources_.equal_range(request_url);
- for (auto it = resource_range.first; it != resource_range.second; ++it) {
- resources.push_back(it->second);
- }
- QUIC_DVLOG(1) << "Found " << resources.size() << " push resources for "
- << request_url;
- return resources;
-}
-
-QuicMemoryCacheBackend::WebTransportResponse
-QuicMemoryCacheBackend::ProcessWebTransportRequest(
- const spdy::Http2HeaderBlock& request_headers,
- WebTransportSession* session) {
- if (!SupportsWebTransport()) {
- return QuicSimpleServerBackend::ProcessWebTransportRequest(request_headers,
- session);
- }
-
- auto path_it = request_headers.find(":path");
- if (path_it == request_headers.end()) {
- WebTransportResponse response;
- response.response_headers[":status"] = "400";
- return response;
- }
- absl::string_view path = path_it->second;
- if (path == "/echo") {
- WebTransportResponse response;
- response.response_headers[":status"] = "200";
- response.visitor =
- std::make_unique<EchoWebTransportSessionVisitor>(session);
- return response;
- }
-
- WebTransportResponse response;
- response.response_headers[":status"] = "404";
- return response;
-}
-
-QuicMemoryCacheBackend::~QuicMemoryCacheBackend() {
- {
- QuicWriterMutexLock lock(&response_mutex_);
- responses_.clear();
- }
-}
-
-void QuicMemoryCacheBackend::AddResponseImpl(
- absl::string_view host, absl::string_view path,
- SpecialResponseType response_type, Http2HeaderBlock response_headers,
- absl::string_view response_body, Http2HeaderBlock response_trailers,
- const std::vector<spdy::Http2HeaderBlock>& early_hints) {
- QuicWriterMutexLock lock(&response_mutex_);
-
- QUICHE_DCHECK(!host.empty())
- << "Host must be populated, e.g. \"www.google.com\"";
- std::string key = GetKey(host, path);
- if (responses_.contains(key)) {
- QUIC_BUG(quic_bug_10932_3)
- << "Response for '" << key << "' already exists!";
- return;
- }
- auto new_response = std::make_unique<QuicBackendResponse>();
- new_response->set_response_type(response_type);
- new_response->set_headers(std::move(response_headers));
- new_response->set_body(response_body);
- new_response->set_trailers(std::move(response_trailers));
- for (auto& headers : early_hints) {
- new_response->AddEarlyHints(headers);
- }
- QUIC_DVLOG(1) << "Add response with key " << key;
- responses_[key] = std::move(new_response);
-}
-
-std::string QuicMemoryCacheBackend::GetKey(absl::string_view host,
- absl::string_view path) const {
- std::string host_string = std::string(host);
- size_t port = host_string.find(':');
- if (port != std::string::npos)
- host_string = std::string(host_string.c_str(), port);
- return host_string + std::string(path);
-}
-
-void QuicMemoryCacheBackend::MaybeAddServerPushResources(
- absl::string_view request_host, absl::string_view request_path,
- std::list<ServerPushInfo> push_resources) {
- std::string request_url = GetKey(request_host, request_path);
-
- for (const auto& push_resource : push_resources) {
- if (PushResourceExistsInCache(request_url, push_resource)) {
- continue;
- }
-
- QUIC_DVLOG(1) << "Add request-resource association: request url "
- << request_url << " push url "
- << push_resource.request_url.ToString()
- << " response headers "
- << push_resource.headers.DebugString();
- {
- QuicWriterMutexLock lock(&response_mutex_);
- server_push_resources_.insert(std::make_pair(request_url, push_resource));
- }
- std::string host = push_resource.request_url.host();
- if (host.empty()) {
- host = std::string(request_host);
- }
- std::string path = push_resource.request_url.path();
- bool found_existing_response = false;
- {
- QuicWriterMutexLock lock(&response_mutex_);
- found_existing_response = responses_.contains(GetKey(host, path));
- }
- if (!found_existing_response) {
- // Add a server push response to responses map, if it is not in the map.
- absl::string_view body = push_resource.body;
- QUIC_DVLOG(1) << "Add response for push resource: host " << host
- << " path " << path;
- AddResponse(host, path, push_resource.headers.Clone(), body);
- }
- }
-}
-
-bool QuicMemoryCacheBackend::PushResourceExistsInCache(
- std::string original_request_url, ServerPushInfo resource) {
- QuicWriterMutexLock lock(&response_mutex_);
- auto resource_range =
- server_push_resources_.equal_range(original_request_url);
- for (auto it = resource_range.first; it != resource_range.second; ++it) {
- ServerPushInfo push_resource = it->second;
- if (push_resource.request_url.ToString() ==
- resource.request_url.ToString()) {
- return true;
- }
- }
- return false;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/tools/quic_memory_cache_backend.h b/chromium/net/third_party/quiche/src/quic/tools/quic_memory_cache_backend.h
deleted file mode 100644
index 72c57843d60..00000000000
--- a/chromium/net/third_party/quiche/src/quic/tools/quic_memory_cache_backend.h
+++ /dev/null
@@ -1,217 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TOOLS_QUIC_MEMORY_CACHE_BACKEND_H_
-#define QUICHE_QUIC_TOOLS_QUIC_MEMORY_CACHE_BACKEND_H_
-
-#include <list>
-#include <map>
-#include <memory>
-#include <vector>
-
-#include "absl/container/flat_hash_map.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/http/spdy_utils.h"
-#include "quic/platform/api/quic_containers.h"
-#include "quic/platform/api/quic_mutex.h"
-#include "quic/tools/quic_backend_response.h"
-#include "quic/tools/quic_simple_server_backend.h"
-#include "quic/tools/quic_url.h"
-#include "spdy/core/spdy_framer.h"
-
-namespace quic {
-
-// In-memory cache for HTTP responses.
-// Reads from disk cache generated by:
-// `wget -p --save_headers <url>`
-class QuicMemoryCacheBackend : public QuicSimpleServerBackend {
- public:
- // Class to manage loading a resource file into memory. There are
- // two uses: called by InitializeBackend to load resources
- // from files, and recursively called when said resources specify
- // server push associations.
- class ResourceFile {
- public:
- explicit ResourceFile(const std::string& file_name);
- ResourceFile(const ResourceFile&) = delete;
- ResourceFile& operator=(const ResourceFile&) = delete;
- virtual ~ResourceFile();
-
- void Read();
-
- // |base| is |file_name_| with |cache_directory| prefix stripped.
- void SetHostPathFromBase(absl::string_view base);
-
- const std::string& file_name() { return file_name_; }
-
- absl::string_view host() { return host_; }
-
- absl::string_view path() { return path_; }
-
- const spdy::Http2HeaderBlock& spdy_headers() { return spdy_headers_; }
-
- absl::string_view body() { return body_; }
-
- const std::vector<absl::string_view>& push_urls() { return push_urls_; }
-
- private:
- void HandleXOriginalUrl();
- absl::string_view RemoveScheme(absl::string_view url);
-
- std::string file_name_;
- std::string file_contents_;
- absl::string_view body_;
- spdy::Http2HeaderBlock spdy_headers_;
- absl::string_view x_original_url_;
- std::vector<absl::string_view> push_urls_;
- std::string host_;
- std::string path_;
- };
-
- QuicMemoryCacheBackend();
- QuicMemoryCacheBackend(const QuicMemoryCacheBackend&) = delete;
- QuicMemoryCacheBackend& operator=(const QuicMemoryCacheBackend&) = delete;
- ~QuicMemoryCacheBackend() override;
-
- // Retrieve a response from this cache for a given host and path..
- // If no appropriate response exists, nullptr is returned.
- const QuicBackendResponse* GetResponse(absl::string_view host,
- absl::string_view path) const;
-
- // Adds a simple response to the cache. The response headers will
- // only contain the "content-length" header with the length of |body|.
- void AddSimpleResponse(absl::string_view host,
- absl::string_view path,
- int response_code,
- absl::string_view body);
-
- // Add a simple response to the cache as AddSimpleResponse() does, and add
- // some server push resources(resource path, corresponding response status and
- // path) associated with it.
- // Push resource implicitly come from the same host.
- // TODO(b/171463363): Remove.
- void AddSimpleResponseWithServerPushResources(
- absl::string_view host,
- absl::string_view path,
- int response_code,
- absl::string_view body,
- std::list<QuicBackendResponse::ServerPushInfo> push_resources);
-
- // Add a response to the cache.
- void AddResponse(absl::string_view host,
- absl::string_view path,
- spdy::Http2HeaderBlock response_headers,
- absl::string_view response_body);
-
- // Add a response, with trailers, to the cache.
- void AddResponse(absl::string_view host,
- absl::string_view path,
- spdy::Http2HeaderBlock response_headers,
- absl::string_view response_body,
- spdy::Http2HeaderBlock response_trailers);
-
- // Add a response, with 103 Early Hints, to the cache.
- void AddResponseWithEarlyHints(
- absl::string_view host,
- absl::string_view path,
- spdy::Http2HeaderBlock response_headers,
- absl::string_view response_body,
- const std::vector<spdy::Http2HeaderBlock>& early_hints);
-
- // Simulate a special behavior at a particular path.
- void AddSpecialResponse(
- absl::string_view host,
- absl::string_view path,
- QuicBackendResponse::SpecialResponseType response_type);
-
- void AddSpecialResponse(
- absl::string_view host,
- absl::string_view path,
- spdy::Http2HeaderBlock response_headers,
- absl::string_view response_body,
- QuicBackendResponse::SpecialResponseType response_type);
-
- // Sets a default response in case of cache misses. Takes ownership of
- // 'response'.
- void AddDefaultResponse(QuicBackendResponse* response);
-
- // Once called, URLs which have a numeric path will send a dynamically
- // generated response of that many bytes.
- void GenerateDynamicResponses();
-
- void EnableWebTransport();
-
- // Find all the server push resources associated with |request_url|.
- // TODO(b/171463363): Remove.
- std::list<QuicBackendResponse::ServerPushInfo> GetServerPushResources(
- std::string request_url);
-
- // Implements the functions for interface QuicSimpleServerBackend
- // |cache_cirectory| can be generated using `wget -p --save-headers <url>`.
- bool InitializeBackend(const std::string& cache_directory) override;
- bool IsBackendInitialized() const override;
- void FetchResponseFromBackend(
- const spdy::Http2HeaderBlock& request_headers,
- const std::string& request_body,
- QuicSimpleServerBackend::RequestHandler* quic_stream) override;
- void CloseBackendResponseStream(
- QuicSimpleServerBackend::RequestHandler* quic_stream) override;
- WebTransportResponse ProcessWebTransportRequest(
- const spdy::Http2HeaderBlock& request_headers,
- WebTransportSession* session) override;
- bool SupportsWebTransport() override { return enable_webtransport_; }
-
- private:
- void AddResponseImpl(absl::string_view host,
- absl::string_view path,
- QuicBackendResponse::SpecialResponseType response_type,
- spdy::Http2HeaderBlock response_headers,
- absl::string_view response_body,
- spdy::Http2HeaderBlock response_trailers,
- const std::vector<spdy::Http2HeaderBlock>& early_hints);
-
- std::string GetKey(absl::string_view host, absl::string_view path) const;
-
- // Add some server push urls with given responses for specified
- // request if these push resources are not associated with this request yet.
- // TODO(b/171463363): Remove.
- void MaybeAddServerPushResources(
- absl::string_view request_host,
- absl::string_view request_path,
- std::list<QuicBackendResponse::ServerPushInfo> push_resources);
-
- // Check if push resource(push_host/push_path) associated with given request
- // url already exists in server push map.
- // TODO(b/171463363): Remove.
- bool PushResourceExistsInCache(std::string original_request_url,
- QuicBackendResponse::ServerPushInfo resource);
-
- // Cached responses.
- absl::flat_hash_map<std::string, std::unique_ptr<QuicBackendResponse>>
- responses_ QUIC_GUARDED_BY(response_mutex_);
-
- // The default response for cache misses, if set.
- std::unique_ptr<QuicBackendResponse> default_response_
- QUIC_GUARDED_BY(response_mutex_);
-
- // The generate bytes response, if set.
- std::unique_ptr<QuicBackendResponse> generate_bytes_response_
- QUIC_GUARDED_BY(response_mutex_);
-
- // A map from request URL to associated server push responses (if any).
- // TODO(b/171463363): Remove.
- std::multimap<std::string, QuicBackendResponse::ServerPushInfo>
- server_push_resources_ QUIC_GUARDED_BY(response_mutex_);
-
- // Protects against concurrent access from test threads setting responses, and
- // server threads accessing those responses.
- mutable QuicMutex response_mutex_;
- bool cache_initialized_;
-
- bool enable_webtransport_ = false;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_TOOLS_QUIC_MEMORY_CACHE_BACKEND_H_
diff --git a/chromium/net/third_party/quiche/src/quic/tools/quic_memory_cache_backend_test.cc b/chromium/net/third_party/quiche/src/quic/tools/quic_memory_cache_backend_test.cc
deleted file mode 100644
index 79dac6bf539..00000000000
--- a/chromium/net/third_party/quiche/src/quic/tools/quic_memory_cache_backend_test.cc
+++ /dev/null
@@ -1,291 +0,0 @@
-// Copyright 2013 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 "quic/tools/quic_memory_cache_backend.h"
-
-#include <vector>
-
-#include "absl/strings/match.h"
-#include "absl/strings/str_cat.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/tools/quic_backend_response.h"
-#include "common/platform/api/quiche_file_utils.h"
-
-namespace quic {
-namespace test {
-
-namespace {
-using Response = QuicBackendResponse;
-using ServerPushInfo = QuicBackendResponse::ServerPushInfo;
-} // namespace
-
-class QuicMemoryCacheBackendTest : public QuicTest {
- protected:
- void CreateRequest(std::string host, std::string path,
- spdy::Http2HeaderBlock* headers) {
- (*headers)[":method"] = "GET";
- (*headers)[":path"] = path;
- (*headers)[":authority"] = host;
- (*headers)[":scheme"] = "https";
- }
-
- std::string CacheDirectory() { return QuicGetTestMemoryCachePath(); }
-
- QuicMemoryCacheBackend cache_;
-};
-
-TEST_F(QuicMemoryCacheBackendTest, GetResponseNoMatch) {
- const Response* response =
- cache_.GetResponse("mail.google.com", "/index.html");
- ASSERT_FALSE(response);
-}
-
-TEST_F(QuicMemoryCacheBackendTest, AddSimpleResponseGetResponse) {
- std::string response_body("hello response");
- cache_.AddSimpleResponse("www.google.com", "/", 200, response_body);
-
- spdy::Http2HeaderBlock request_headers;
- CreateRequest("www.google.com", "/", &request_headers);
- const Response* response = cache_.GetResponse("www.google.com", "/");
- ASSERT_TRUE(response);
- ASSERT_TRUE(response->headers().contains(":status"));
- EXPECT_EQ("200", response->headers().find(":status")->second);
- EXPECT_EQ(response_body.size(), response->body().length());
-}
-
-TEST_F(QuicMemoryCacheBackendTest, AddResponse) {
- const std::string kRequestHost = "www.foo.com";
- const std::string kRequestPath = "/";
- const std::string kResponseBody("hello response");
-
- spdy::Http2HeaderBlock response_headers;
- response_headers[":status"] = "200";
- response_headers["content-length"] = absl::StrCat(kResponseBody.size());
-
- spdy::Http2HeaderBlock response_trailers;
- response_trailers["key-1"] = "value-1";
- response_trailers["key-2"] = "value-2";
- response_trailers["key-3"] = "value-3";
-
- cache_.AddResponse(kRequestHost, "/", response_headers.Clone(), kResponseBody,
- response_trailers.Clone());
-
- const Response* response = cache_.GetResponse(kRequestHost, kRequestPath);
- EXPECT_EQ(response->headers(), response_headers);
- EXPECT_EQ(response->body(), kResponseBody);
- EXPECT_EQ(response->trailers(), response_trailers);
-}
-
-// TODO(crbug.com/1249712) This test is failing on iOS.
-#if defined(OS_IOS)
-#define MAYBE_ReadsCacheDir DISABLED_ReadsCacheDir
-#else
-#define MAYBE_ReadsCacheDir ReadsCacheDir
-#endif
-TEST_F(QuicMemoryCacheBackendTest, MAYBE_ReadsCacheDir) {
- cache_.InitializeBackend(CacheDirectory());
- const Response* response =
- cache_.GetResponse("test.example.com", "/index.html");
- ASSERT_TRUE(response);
- ASSERT_TRUE(response->headers().contains(":status"));
- EXPECT_EQ("200", response->headers().find(":status")->second);
- // Connection headers are not valid in HTTP/2.
- EXPECT_FALSE(response->headers().contains("connection"));
- EXPECT_LT(0U, response->body().length());
-}
-
-// 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
-#endif
-TEST_F(QuicMemoryCacheBackendTest, MAYBE_UsesOriginalUrl) {
- cache_.InitializeBackend(CacheDirectory());
- const Response* response =
- cache_.GetResponse("test.example.com", "/site_map.html");
- ASSERT_TRUE(response);
- ASSERT_TRUE(response->headers().contains(":status"));
- EXPECT_EQ("200", response->headers().find(":status")->second);
- // Connection headers are not valid in HTTP/2.
- EXPECT_FALSE(response->headers().contains("connection"));
- EXPECT_LT(0U, response->body().length());
-}
-
-// TODO(crbug.com/1249712) This test is failing on iOS.
-#if defined(OS_IOS)
-#define MAYBE_UsesOriginalUrlOnly DISABLED_UsesOriginalUrlOnly
-#else
-#define MAYBE_UsesOriginalUrlOnly UsesOriginalUrlOnly
-#endif
-TEST_F(QuicMemoryCacheBackendTest, MAYBE_UsesOriginalUrlOnly) {
- // Tests that if the URL cannot be inferred correctly from the path
- // because the directory does not include the hostname, that the
- // X-Original-Url header's value will be used.
- std::string dir;
- std::string path = "map.html";
- std::vector<std::string> files;
- ASSERT_TRUE(quiche::EnumerateDirectoryRecursively(CacheDirectory(), files));
- for (const std::string& file : files) {
- if (absl::EndsWithIgnoreCase(file, "map.html")) {
- dir = file;
- dir.erase(dir.length() - path.length() - 1);
- break;
- }
- }
- ASSERT_NE("", dir);
-
- cache_.InitializeBackend(dir);
- const Response* response =
- cache_.GetResponse("test.example.com", "/site_map.html");
- ASSERT_TRUE(response);
- ASSERT_TRUE(response->headers().contains(":status"));
- EXPECT_EQ("200", response->headers().find(":status")->second);
- // Connection headers are not valid in HTTP/2.
- EXPECT_FALSE(response->headers().contains("connection"));
- EXPECT_LT(0U, response->body().length());
-}
-
-TEST_F(QuicMemoryCacheBackendTest, DefaultResponse) {
- // Verify GetResponse returns nullptr when no default is set.
- const Response* response = cache_.GetResponse("www.google.com", "/");
- ASSERT_FALSE(response);
-
- // Add a default response.
- spdy::Http2HeaderBlock response_headers;
- response_headers[":status"] = "200";
- response_headers["content-length"] = "0";
- Response* default_response = new Response;
- default_response->set_headers(std::move(response_headers));
- cache_.AddDefaultResponse(default_response);
-
- // Now we should get the default response for the original request.
- response = cache_.GetResponse("www.google.com", "/");
- ASSERT_TRUE(response);
- ASSERT_TRUE(response->headers().contains(":status"));
- EXPECT_EQ("200", response->headers().find(":status")->second);
-
- // Now add a set response for / and make sure it is returned
- cache_.AddSimpleResponse("www.google.com", "/", 302, "");
- response = cache_.GetResponse("www.google.com", "/");
- ASSERT_TRUE(response);
- ASSERT_TRUE(response->headers().contains(":status"));
- EXPECT_EQ("302", response->headers().find(":status")->second);
-
- // We should get the default response for other requests.
- response = cache_.GetResponse("www.google.com", "/asd");
- ASSERT_TRUE(response);
- ASSERT_TRUE(response->headers().contains(":status"));
- EXPECT_EQ("200", response->headers().find(":status")->second);
-}
-
-TEST_F(QuicMemoryCacheBackendTest, AddSimpleResponseWithServerPushResources) {
- std::string request_host = "www.foo.com";
- std::string response_body("hello response");
- const size_t kNumResources = 5;
- int NumResources = 5;
- std::list<ServerPushInfo> push_resources;
- std::string scheme = "http";
- for (int i = 0; i < NumResources; ++i) {
- std::string path = absl::StrCat("/server_push_src", i);
- std::string url = scheme + "://" + request_host + path;
- QuicUrl resource_url(url);
- std::string body =
- absl::StrCat("This is server push response body for ", path);
- spdy::Http2HeaderBlock response_headers;
- response_headers[":status"] = "200";
- response_headers["content-length"] = absl::StrCat(body.size());
- push_resources.push_back(
- ServerPushInfo(resource_url, response_headers.Clone(), i, body));
- }
-
- cache_.AddSimpleResponseWithServerPushResources(
- request_host, "/", 200, response_body, push_resources);
-
- std::string request_url = request_host + "/";
- std::list<ServerPushInfo> resources =
- cache_.GetServerPushResources(request_url);
- ASSERT_EQ(kNumResources, resources.size());
- for (const auto& push_resource : push_resources) {
- ServerPushInfo resource = resources.front();
- EXPECT_EQ(resource.request_url.ToString(),
- push_resource.request_url.ToString());
- EXPECT_EQ(resource.priority, push_resource.priority);
- resources.pop_front();
- }
-}
-
-TEST_F(QuicMemoryCacheBackendTest, GetServerPushResourcesAndPushResponses) {
- std::string request_host = "www.foo.com";
- std::string response_body("hello response");
- const size_t kNumResources = 4;
- int NumResources = 4;
- std::string scheme = "http";
- std::string push_response_status[kNumResources] = {"200", "200", "301",
- "404"};
- std::list<ServerPushInfo> push_resources;
- for (int i = 0; i < NumResources; ++i) {
- std::string path = absl::StrCat("/server_push_src", i);
- std::string url = scheme + "://" + request_host + path;
- QuicUrl resource_url(url);
- std::string body = "This is server push response body for " + path;
- spdy::Http2HeaderBlock response_headers;
- response_headers[":status"] = push_response_status[i];
- response_headers["content-length"] = absl::StrCat(body.size());
- push_resources.push_back(
- ServerPushInfo(resource_url, response_headers.Clone(), i, body));
- }
- cache_.AddSimpleResponseWithServerPushResources(
- request_host, "/", 200, response_body, push_resources);
- std::string request_url = request_host + "/";
- std::list<ServerPushInfo> resources =
- cache_.GetServerPushResources(request_url);
- ASSERT_EQ(kNumResources, resources.size());
- int i = 0;
- for (const auto& push_resource : push_resources) {
- QuicUrl url = resources.front().request_url;
- std::string host = url.host();
- std::string path = url.path();
- const Response* response = cache_.GetResponse(host, path);
- ASSERT_TRUE(response);
- ASSERT_TRUE(response->headers().contains(":status"));
- EXPECT_EQ(push_response_status[i++],
- response->headers().find(":status")->second);
- EXPECT_EQ(push_resource.body, response->body());
- resources.pop_front();
- }
-}
-
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/tools/quic_packet_printer_bin.cc b/chromium/net/third_party/quiche/src/quic/tools/quic_packet_printer_bin.cc
deleted file mode 100644
index 8ffae272ffe..00000000000
--- a/chromium/net/third_party/quiche/src/quic/tools/quic_packet_printer_bin.cc
+++ /dev/null
@@ -1,283 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// clang-format off
-
-// Dumps out the decryptable contents of a QUIC packet in a human-readable way.
-// If the packet is null encrypted, this will dump full packet contents.
-// Otherwise it will dump the header, and fail with an error that the
-// packet is undecryptable.
-//
-// Usage: quic_packet_printer server|client <hex dump of packet>
-//
-// Example input:
-// quic_packet_printer server 0c6b810308320f24c004a939a38a2e3fd6ca589917f200400201b80b0100501c0700060003023d0000001c00556e656e637279707465642073747265616d2064617461207365656e
-//
-// Example output:
-// OnPacket
-// OnUnauthenticatedPublicHeader
-// OnUnauthenticatedHeader: { connection_id: 13845207862000976235, connection_id_length:8, packet_number_length:1, multipath_flag: 0, reset_flag: 0, version_flag: 0, path_id: , packet_number: 4 }
-// OnDecryptedPacket
-// OnPacketHeader
-// OnAckFrame: largest_observed: 1 ack_delay_time: 3000 missing_packets: [ ] is_truncated: 0 received_packets: [ 1 at 466016 ]
-// OnStopWaitingFrame
-// OnConnectionCloseFrame: error_code { 61 } error_details { Unencrypted stream data seen }
-
-// clang-format on
-
-#include <iostream>
-
-#include "absl/strings/escaping.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_framer.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_flags.h"
-#include "common/platform/api/quiche_command_line_flags.h"
-#include "common/quiche_text_utils.h"
-
-DEFINE_QUICHE_COMMAND_LINE_FLAG(std::string, quic_version, "",
- "If set, specify the QUIC version to use.");
-
-namespace quic {
-
-class QuicPacketPrinter : public QuicFramerVisitorInterface {
- public:
- explicit QuicPacketPrinter(QuicFramer* framer) : framer_(framer) {}
-
- void OnError(QuicFramer* framer) override {
- std::cerr << "OnError: " << QuicErrorCodeToString(framer->error())
- << " detail: " << framer->detailed_error() << "\n";
- }
- bool OnProtocolVersionMismatch(ParsedQuicVersion received_version) override {
- framer_->set_version(received_version);
- std::cerr << "OnProtocolVersionMismatch: "
- << ParsedQuicVersionToString(received_version) << "\n";
- return true;
- }
- void OnPacket() override { std::cerr << "OnPacket\n"; }
- void OnPublicResetPacket(const QuicPublicResetPacket& /*packet*/) override {
- std::cerr << "OnPublicResetPacket\n";
- }
- void OnVersionNegotiationPacket(
- const QuicVersionNegotiationPacket& /*packet*/) override {
- std::cerr << "OnVersionNegotiationPacket\n";
- }
- void OnRetryPacket(QuicConnectionId /*original_connection_id*/,
- QuicConnectionId /*new_connection_id*/,
- absl::string_view /*retry_token*/,
- absl::string_view /*retry_integrity_tag*/,
- absl::string_view /*retry_without_tag*/) override {
- std::cerr << "OnRetryPacket\n";
- }
- bool OnUnauthenticatedPublicHeader(
- const QuicPacketHeader& /*header*/) override {
- std::cerr << "OnUnauthenticatedPublicHeader\n";
- return true;
- }
- bool OnUnauthenticatedHeader(const QuicPacketHeader& header) override {
- std::cerr << "OnUnauthenticatedHeader: " << header;
- return true;
- }
- void OnDecryptedPacket(size_t /*length*/, EncryptionLevel level) override {
- // This only currently supports "decrypting" null encrypted packets.
- QUICHE_DCHECK_EQ(ENCRYPTION_INITIAL, level);
- std::cerr << "OnDecryptedPacket\n";
- }
- bool OnPacketHeader(const QuicPacketHeader& /*header*/) override {
- std::cerr << "OnPacketHeader\n";
- return true;
- }
- void OnCoalescedPacket(const QuicEncryptedPacket& /*packet*/) override {
- std::cerr << "OnCoalescedPacket\n";
- }
- void OnUndecryptablePacket(const QuicEncryptedPacket& /*packet*/,
- EncryptionLevel /*decryption_level*/,
- bool /*has_decryption_key*/) override {
- std::cerr << "OnUndecryptablePacket\n";
- }
- bool OnStreamFrame(const QuicStreamFrame& frame) override {
- std::cerr << "OnStreamFrame: " << frame;
- std::cerr << " data: { "
- << absl::BytesToHexString(
- absl::string_view(frame.data_buffer, frame.data_length))
- << " }\n";
- return true;
- }
- bool OnCryptoFrame(const QuicCryptoFrame& frame) override {
- std::cerr << "OnCryptoFrame: " << frame;
- std::cerr << " data: { "
- << absl::BytesToHexString(
- absl::string_view(frame.data_buffer, frame.data_length))
- << " }\n";
- return true;
- }
- bool OnAckFrameStart(QuicPacketNumber largest_acked,
- QuicTime::Delta /*ack_delay_time*/) override {
- std::cerr << "OnAckFrameStart, largest_acked: " << largest_acked;
- return true;
- }
- bool OnAckRange(QuicPacketNumber start, QuicPacketNumber end) override {
- std::cerr << "OnAckRange: [" << start << ", " << end << ")";
- return true;
- }
- bool OnAckTimestamp(QuicPacketNumber packet_number,
- QuicTime timestamp) override {
- std::cerr << "OnAckTimestamp: [" << packet_number << ", "
- << timestamp.ToDebuggingValue() << ")";
- return true;
- }
- bool OnAckFrameEnd(QuicPacketNumber start) override {
- std::cerr << "OnAckFrameEnd, start: " << start;
- return true;
- }
- bool OnStopWaitingFrame(const QuicStopWaitingFrame& frame) override {
- std::cerr << "OnStopWaitingFrame: " << frame;
- return true;
- }
- bool OnPaddingFrame(const QuicPaddingFrame& frame) override {
- std::cerr << "OnPaddingFrame: " << frame;
- return true;
- }
- bool OnPingFrame(const QuicPingFrame& frame) override {
- std::cerr << "OnPingFrame: " << frame;
- return true;
- }
- bool OnRstStreamFrame(const QuicRstStreamFrame& frame) override {
- std::cerr << "OnRstStreamFrame: " << frame;
- return true;
- }
- bool OnConnectionCloseFrame(const QuicConnectionCloseFrame& frame) override {
- // The frame printout will indicate whether it's a Google QUIC
- // CONNECTION_CLOSE, IETF QUIC CONNECTION_CLOSE/Transport, or IETF QUIC
- // CONNECTION_CLOSE/Application frame.
- std::cerr << "OnConnectionCloseFrame: " << frame;
- return true;
- }
- bool OnNewConnectionIdFrame(const QuicNewConnectionIdFrame& frame) override {
- std::cerr << "OnNewConnectionIdFrame: " << frame;
- return true;
- }
- bool OnRetireConnectionIdFrame(
- const QuicRetireConnectionIdFrame& frame) override {
- std::cerr << "OnRetireConnectionIdFrame: " << frame;
- return true;
- }
- bool OnNewTokenFrame(const QuicNewTokenFrame& frame) override {
- std::cerr << "OnNewTokenFrame: " << frame;
- return true;
- }
- bool OnStopSendingFrame(const QuicStopSendingFrame& frame) override {
- std::cerr << "OnStopSendingFrame: " << frame;
- return true;
- }
- bool OnPathChallengeFrame(const QuicPathChallengeFrame& frame) override {
- std::cerr << "OnPathChallengeFrame: " << frame;
- return true;
- }
- bool OnPathResponseFrame(const QuicPathResponseFrame& frame) override {
- std::cerr << "OnPathResponseFrame: " << frame;
- return true;
- }
- bool OnGoAwayFrame(const QuicGoAwayFrame& frame) override {
- std::cerr << "OnGoAwayFrame: " << frame;
- return true;
- }
- bool OnMaxStreamsFrame(const QuicMaxStreamsFrame& frame) override {
- std::cerr << "OnMaxStreamsFrame: " << frame;
- return true;
- }
- bool OnStreamsBlockedFrame(const QuicStreamsBlockedFrame& frame) override {
- std::cerr << "OnStreamsBlockedFrame: " << frame;
- return true;
- }
- bool OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame) override {
- std::cerr << "OnWindowUpdateFrame: " << frame;
- return true;
- }
- bool OnBlockedFrame(const QuicBlockedFrame& frame) override {
- std::cerr << "OnBlockedFrame: " << frame;
- return true;
- }
- bool OnMessageFrame(const QuicMessageFrame& frame) override {
- std::cerr << "OnMessageFrame: " << frame;
- return true;
- }
- bool OnHandshakeDoneFrame(const QuicHandshakeDoneFrame& frame) override {
- std::cerr << "OnHandshakeDoneFrame: " << frame;
- return true;
- }
- bool OnAckFrequencyFrame(const QuicAckFrequencyFrame& frame) override {
- std::cerr << "OnAckFrequencyFrame: " << frame;
- return true;
- }
- void OnPacketComplete() override { std::cerr << "OnPacketComplete\n"; }
- bool IsValidStatelessResetToken(
- const StatelessResetToken& /*token*/) const override {
- std::cerr << "IsValidStatelessResetToken\n";
- return false;
- }
- void OnAuthenticatedIetfStatelessResetPacket(
- const QuicIetfStatelessResetPacket& /*packet*/) override {
- std::cerr << "OnAuthenticatedIetfStatelessResetPacket\n";
- }
- void OnKeyUpdate(KeyUpdateReason reason) override {
- std::cerr << "OnKeyUpdate: " << reason << "\n";
- }
- void OnDecryptedFirstPacketInKeyPhase() override {
- std::cerr << "OnDecryptedFirstPacketInKeyPhase\n";
- }
- std::unique_ptr<QuicDecrypter> AdvanceKeysAndCreateCurrentOneRttDecrypter()
- override {
- std::cerr << "AdvanceKeysAndCreateCurrentOneRttDecrypter\n";
- return nullptr;
- }
- std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() override {
- std::cerr << "CreateCurrentOneRttEncrypter\n";
- return nullptr;
- }
-
- private:
- QuicFramer* framer_; // Unowned.
-};
-
-} // namespace quic
-
-int main(int argc, char* argv[]) {
- const char* usage = "Usage: quic_packet_printer client|server <hex>";
- std::vector<std::string> args =
- quiche::QuicheParseCommandLineFlags(usage, argc, argv);
-
- if (args.size() < 2) {
- quiche::QuichePrintCommandLineFlagHelp(usage);
- return 1;
- }
-
- std::string perspective_string = args[0];
- quic::Perspective perspective;
- if (perspective_string == "client") {
- perspective = quic::Perspective::IS_CLIENT;
- } else if (perspective_string == "server") {
- perspective = quic::Perspective::IS_SERVER;
- } else {
- std::cerr << "Invalid perspective" << std::endl;
- quiche::QuichePrintCommandLineFlagHelp(usage);
- return 1;
- }
- std::string hex = absl::HexStringToBytes(args[1]);
- quic::ParsedQuicVersionVector versions = quic::AllSupportedVersions();
- // Fake a time since we're not actually generating acks.
- quic::QuicTime start(quic::QuicTime::Zero());
- quic::QuicFramer framer(versions, start, perspective,
- quic::kQuicDefaultConnectionIdLength);
- const quic::ParsedQuicVersion& version =
- quic::ParseQuicVersionString(GetQuicFlag(FLAGS_quic_version));
- if (version != quic::ParsedQuicVersion::Unsupported()) {
- framer.set_version(version);
- }
- quic::QuicPacketPrinter visitor(&framer);
- framer.set_visitor(&visitor);
- quic::QuicEncryptedPacket encrypted(hex.c_str(), hex.length());
- return framer.ProcessPacket(encrypted);
-}
diff --git a/chromium/net/third_party/quiche/src/quic/tools/quic_reject_reason_decoder_bin.cc b/chromium/net/third_party/quiche/src/quic/tools/quic_reject_reason_decoder_bin.cc
deleted file mode 100644
index ed83d278b7d..00000000000
--- a/chromium/net/third_party/quiche/src/quic/tools/quic_reject_reason_decoder_bin.cc
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Decodes the packet HandshakeFailureReason from the chromium histogram
-// Net.QuicClientHelloRejectReasons
-
-#include <iostream>
-
-#include "absl/strings/numbers.h"
-#include "quic/core/crypto/crypto_handshake.h"
-#include "quic/core/crypto/crypto_utils.h"
-#include "quic/platform/api/quic_flags.h"
-#include "common/platform/api/quiche_command_line_flags.h"
-#include "common/quiche_text_utils.h"
-
-using quic::CryptoUtils;
-using quic::HandshakeFailureReason;
-using quic::MAX_FAILURE_REASON;
-
-int main(int argc, char* argv[]) {
- const char* usage = "Usage: quic_reject_reason_decoder <packed_reason>";
- std::vector<std::string> args =
- quiche::QuicheParseCommandLineFlags(usage, argc, argv);
-
- if (args.size() != 1) {
- std::cerr << usage << std::endl;
- return 1;
- }
-
- uint32_t packed_error = 0;
- if (!absl::SimpleAtoi(args[0], &packed_error)) {
- std::cerr << "Unable to parse: " << args[0] << "\n";
- return 2;
- }
-
- for (int i = 1; i < MAX_FAILURE_REASON; ++i) {
- if ((packed_error & (1 << (i - 1))) == 0) {
- continue;
- }
- HandshakeFailureReason reason = static_cast<HandshakeFailureReason>(i);
- std::cout << CryptoUtils::HandshakeFailureReasonToString(reason) << "\n";
- }
- return 0;
-}
diff --git a/chromium/net/third_party/quiche/src/quic/tools/quic_server.cc b/chromium/net/third_party/quiche/src/quic/tools/quic_server.cc
deleted file mode 100644
index fe10d12a389..00000000000
--- a/chromium/net/third_party/quiche/src/quic/tools/quic_server.cc
+++ /dev/null
@@ -1,221 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/tools/quic_server.h"
-
-#include <errno.h>
-#include <features.h>
-#include <netinet/in.h>
-#include <string.h>
-#include <sys/epoll.h>
-#include <sys/socket.h>
-
-#include <cstdint>
-#include <memory>
-
-#include "quic/core/crypto/crypto_handshake.h"
-#include "quic/core/crypto/quic_random.h"
-#include "quic/core/quic_clock.h"
-#include "quic/core/quic_crypto_stream.h"
-#include "quic/core/quic_data_reader.h"
-#include "quic/core/quic_default_packet_writer.h"
-#include "quic/core/quic_dispatcher.h"
-#include "quic/core/quic_epoll_alarm_factory.h"
-#include "quic/core/quic_epoll_connection_helper.h"
-#include "quic/core/quic_packet_reader.h"
-#include "quic/core/quic_packets.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-#include "net/quic/platform/impl/quic_epoll_clock.h"
-#include "quic/tools/quic_simple_crypto_server_stream_helper.h"
-#include "quic/tools/quic_simple_dispatcher.h"
-#include "quic/tools/quic_simple_server_backend.h"
-
-namespace quic {
-
-namespace {
-
-const int kEpollFlags = EPOLLIN | EPOLLOUT | EPOLLET;
-const char kSourceAddressTokenSecret[] = "secret";
-
-} // namespace
-
-const size_t kNumSessionsToCreatePerSocketEvent = 16;
-
-QuicServer::QuicServer(std::unique_ptr<ProofSource> proof_source,
- QuicSimpleServerBackend* quic_simple_server_backend)
- : QuicServer(std::move(proof_source),
- quic_simple_server_backend,
- AllSupportedVersions()) {}
-
-QuicServer::QuicServer(std::unique_ptr<ProofSource> proof_source,
- QuicSimpleServerBackend* quic_simple_server_backend,
- const ParsedQuicVersionVector& supported_versions)
- : QuicServer(std::move(proof_source),
- QuicConfig(),
- QuicCryptoServerConfig::ConfigOptions(),
- supported_versions,
- quic_simple_server_backend,
- kQuicDefaultConnectionIdLength) {}
-
-QuicServer::QuicServer(
- std::unique_ptr<ProofSource> proof_source,
- const QuicConfig& config,
- const QuicCryptoServerConfig::ConfigOptions& crypto_config_options,
- const ParsedQuicVersionVector& supported_versions,
- QuicSimpleServerBackend* quic_simple_server_backend,
- uint8_t expected_server_connection_id_length)
- : port_(0),
- fd_(-1),
- packets_dropped_(0),
- overflow_supported_(false),
- silent_close_(false),
- config_(config),
- crypto_config_(kSourceAddressTokenSecret,
- QuicRandom::GetInstance(),
- std::move(proof_source),
- KeyExchangeSource::Default()),
- crypto_config_options_(crypto_config_options),
- version_manager_(supported_versions),
- packet_reader_(new QuicPacketReader()),
- quic_simple_server_backend_(quic_simple_server_backend),
- expected_server_connection_id_length_(
- expected_server_connection_id_length) {
- QUICHE_DCHECK(quic_simple_server_backend_);
- Initialize();
-}
-
-void QuicServer::Initialize() {
- // If an initial flow control window has not explicitly been set, then use a
- // sensible value for a server: 1 MB for session, 64 KB for each stream.
- const uint32_t kInitialSessionFlowControlWindow = 1 * 1024 * 1024; // 1 MB
- const uint32_t kInitialStreamFlowControlWindow = 64 * 1024; // 64 KB
- if (config_.GetInitialStreamFlowControlWindowToSend() ==
- kDefaultFlowControlSendWindow) {
- config_.SetInitialStreamFlowControlWindowToSend(
- kInitialStreamFlowControlWindow);
- }
- if (config_.GetInitialSessionFlowControlWindowToSend() ==
- kDefaultFlowControlSendWindow) {
- config_.SetInitialSessionFlowControlWindowToSend(
- kInitialSessionFlowControlWindow);
- }
-
- epoll_server_.set_timeout_in_us(50 * 1000);
-
- QuicEpollClock clock(&epoll_server_);
-
- std::unique_ptr<CryptoHandshakeMessage> scfg(crypto_config_.AddDefaultConfig(
- QuicRandom::GetInstance(), &clock, crypto_config_options_));
-}
-
-QuicServer::~QuicServer() = default;
-
-bool QuicServer::CreateUDPSocketAndListen(const QuicSocketAddress& address) {
- QuicUdpSocketApi socket_api;
- fd_ = socket_api.Create(address.host().AddressFamilyToInt(),
- /*receive_buffer_size =*/kDefaultSocketReceiveBuffer,
- /*send_buffer_size =*/kDefaultSocketReceiveBuffer);
- if (fd_ == kQuicInvalidSocketFd) {
- QUIC_LOG(ERROR) << "CreateSocket() failed: " << strerror(errno);
- return false;
- }
-
- overflow_supported_ = socket_api.EnableDroppedPacketCount(fd_);
- socket_api.EnableReceiveTimestamp(fd_);
-
- sockaddr_storage addr = address.generic_address();
- int rc = bind(fd_, reinterpret_cast<sockaddr*>(&addr), sizeof(addr));
- if (rc < 0) {
- QUIC_LOG(ERROR) << "Bind failed: " << strerror(errno);
- return false;
- }
- QUIC_LOG(INFO) << "Listening on " << address.ToString();
- port_ = address.port();
- if (port_ == 0) {
- QuicSocketAddress address;
- if (address.FromSocket(fd_) != 0) {
- QUIC_LOG(ERROR) << "Unable to get self address. Error: "
- << strerror(errno);
- }
- port_ = address.port();
- }
-
- epoll_server_.RegisterFD(fd_, this, kEpollFlags);
- dispatcher_.reset(CreateQuicDispatcher());
- dispatcher_->InitializeWithWriter(CreateWriter(fd_));
-
- return true;
-}
-
-QuicPacketWriter* QuicServer::CreateWriter(int fd) {
- return new QuicDefaultPacketWriter(fd);
-}
-
-QuicDispatcher* QuicServer::CreateQuicDispatcher() {
- QuicEpollAlarmFactory alarm_factory(&epoll_server_);
- return new QuicSimpleDispatcher(
- &config_, &crypto_config_, &version_manager_,
- std::unique_ptr<QuicEpollConnectionHelper>(new QuicEpollConnectionHelper(
- &epoll_server_, QuicAllocator::BUFFER_POOL)),
- std::unique_ptr<QuicCryptoServerStreamBase::Helper>(
- new QuicSimpleCryptoServerStreamHelper()),
- std::unique_ptr<QuicEpollAlarmFactory>(
- new QuicEpollAlarmFactory(&epoll_server_)),
- quic_simple_server_backend_, expected_server_connection_id_length_);
-}
-
-void QuicServer::HandleEventsForever() {
- while (true) {
- WaitForEvents();
- }
-}
-
-void QuicServer::WaitForEvents() {
- epoll_server_.WaitForEventsAndExecuteCallbacks();
-}
-
-void QuicServer::Shutdown() {
- if (!silent_close_) {
- // Before we shut down the epoll server, give all active sessions a chance
- // to notify clients that they're closing.
- dispatcher_->Shutdown();
- }
-
- epoll_server_.Shutdown();
-
- close(fd_);
- fd_ = -1;
-}
-
-void QuicServer::OnEvent(int fd, QuicEpollEvent* event) {
- QUICHE_DCHECK_EQ(fd, fd_);
- event->out_ready_mask = 0;
-
- if (event->in_events & EPOLLIN) {
- QUIC_DVLOG(1) << "EPOLLIN";
-
- dispatcher_->ProcessBufferedChlos(kNumSessionsToCreatePerSocketEvent);
-
- bool more_to_read = true;
- while (more_to_read) {
- more_to_read = packet_reader_->ReadAndDispatchPackets(
- fd_, port_, QuicEpollClock(&epoll_server_), dispatcher_.get(),
- overflow_supported_ ? &packets_dropped_ : nullptr);
- }
-
- if (dispatcher_->HasChlosBuffered()) {
- // Register EPOLLIN event to consume buffered CHLO(s).
- event->out_ready_mask |= EPOLLIN;
- }
- }
- if (event->in_events & EPOLLOUT) {
- dispatcher_->OnCanWrite();
- if (dispatcher_->HasPendingWrites()) {
- event->out_ready_mask |= EPOLLOUT;
- }
- }
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/tools/quic_server.h b/chromium/net/third_party/quiche/src/quic/tools/quic_server.h
deleted file mode 100644
index 931ac64ec46..00000000000
--- a/chromium/net/third_party/quiche/src/quic/tools/quic_server.h
+++ /dev/null
@@ -1,171 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// A toy server, which listens on a specified address for QUIC traffic and
-// handles incoming responses.
-//
-// Note that this server is intended to verify correctness of the client and is
-// in no way expected to be performant.
-
-#ifndef QUICHE_QUIC_TOOLS_QUIC_SERVER_H_
-#define QUICHE_QUIC_TOOLS_QUIC_SERVER_H_
-
-#include <memory>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/crypto/quic_crypto_server_config.h"
-#include "quic/core/quic_config.h"
-#include "quic/core/quic_epoll_connection_helper.h"
-#include "quic/core/quic_framer.h"
-#include "quic/core/quic_packet_writer.h"
-#include "quic/core/quic_udp_socket.h"
-#include "quic/core/quic_version_manager.h"
-#include "quic/platform/api/quic_epoll.h"
-#include "quic/platform/api/quic_socket_address.h"
-#include "quic/tools/quic_simple_server_backend.h"
-#include "quic/tools/quic_spdy_server_base.h"
-
-namespace quic {
-
-namespace test {
-class QuicServerPeer;
-} // namespace test
-
-class QuicDispatcher;
-class QuicPacketReader;
-
-class QuicServer : public QuicSpdyServerBase,
- public QuicEpollCallbackInterface {
- public:
- QuicServer(std::unique_ptr<ProofSource> proof_source,
- QuicSimpleServerBackend* quic_simple_server_backend);
- QuicServer(std::unique_ptr<ProofSource> proof_source,
- QuicSimpleServerBackend* quic_simple_server_backend,
- const ParsedQuicVersionVector& supported_versions);
- QuicServer(std::unique_ptr<ProofSource> proof_source,
- const QuicConfig& config,
- const QuicCryptoServerConfig::ConfigOptions& crypto_config_options,
- const ParsedQuicVersionVector& supported_versions,
- QuicSimpleServerBackend* quic_simple_server_backend,
- uint8_t expected_server_connection_id_length);
- QuicServer(const QuicServer&) = delete;
- QuicServer& operator=(const QuicServer&) = delete;
-
- ~QuicServer() override;
-
- std::string Name() const override { return "QuicServer"; }
-
- // Start listening on the specified address.
- bool CreateUDPSocketAndListen(const QuicSocketAddress& address) override;
- // Handles all events. Does not return.
- void HandleEventsForever() override;
-
- // Wait up to 50ms, and handle any events which occur.
- void WaitForEvents();
-
- // Server deletion is imminent. Start cleaning up the epoll server.
- virtual void Shutdown();
-
- // From EpollCallbackInterface
- void OnRegistration(QuicEpollServer* /*eps*/,
- int /*fd*/,
- int /*event_mask*/) override {}
- void OnModification(int /*fd*/, int /*event_mask*/) override {}
- void OnEvent(int /*fd*/, QuicEpollEvent* /*event*/) override;
- void OnUnregistration(int /*fd*/, bool /*replaced*/) override {}
-
- void OnShutdown(QuicEpollServer* /*eps*/, int /*fd*/) override {}
-
- void SetChloMultiplier(size_t multiplier) {
- crypto_config_.set_chlo_multiplier(multiplier);
- }
-
- void SetPreSharedKey(absl::string_view key) {
- crypto_config_.set_pre_shared_key(key);
- }
-
- bool overflow_supported() { return overflow_supported_; }
-
- QuicPacketCount packets_dropped() { return packets_dropped_; }
-
- int port() { return port_; }
-
- QuicEpollServer* epoll_server() { return &epoll_server_; }
-
- protected:
- virtual QuicPacketWriter* CreateWriter(int fd);
-
- virtual QuicDispatcher* CreateQuicDispatcher();
-
- const QuicConfig& config() const { return config_; }
- const QuicCryptoServerConfig& crypto_config() const { return crypto_config_; }
-
- QuicDispatcher* dispatcher() { return dispatcher_.get(); }
-
- QuicVersionManager* version_manager() { return &version_manager_; }
-
- QuicSimpleServerBackend* server_backend() {
- return quic_simple_server_backend_;
- }
-
- void set_silent_close(bool value) { silent_close_ = value; }
-
- uint8_t expected_server_connection_id_length() {
- return expected_server_connection_id_length_;
- }
-
- private:
- friend class quic::test::QuicServerPeer;
-
- // Initialize the internal state of the server.
- void Initialize();
-
- // Accepts data from the framer and demuxes clients to sessions.
- std::unique_ptr<QuicDispatcher> dispatcher_;
- // Frames incoming packets and hands them to the dispatcher.
- QuicEpollServer epoll_server_;
-
- // The port the server is listening on.
- int port_;
-
- // Listening connection. Also used for outbound client communication.
- QuicUdpSocketFd fd_;
-
- // If overflow_supported_ is true this will be the number of packets dropped
- // during the lifetime of the server. This may overflow if enough packets
- // are dropped.
- QuicPacketCount packets_dropped_;
-
- // True if the kernel supports SO_RXQ_OVFL, the number of packets dropped
- // because the socket would otherwise overflow.
- bool overflow_supported_;
-
- // If true, do not call Shutdown on the dispatcher. Connections will close
- // without sending a final connection close.
- bool silent_close_;
-
- // config_ contains non-crypto parameters that are negotiated in the crypto
- // handshake.
- QuicConfig config_;
- // crypto_config_ contains crypto parameters for the handshake.
- QuicCryptoServerConfig crypto_config_;
- // crypto_config_options_ contains crypto parameters for the handshake.
- QuicCryptoServerConfig::ConfigOptions crypto_config_options_;
-
- // Used to generate current supported versions.
- QuicVersionManager version_manager_;
-
- // Point to a QuicPacketReader object on the heap. The reader allocates more
- // space than allowed on the stack.
- std::unique_ptr<QuicPacketReader> packet_reader_;
-
- QuicSimpleServerBackend* quic_simple_server_backend_; // unowned.
-
- // Connection ID length expected to be read on incoming IETF short headers.
- uint8_t expected_server_connection_id_length_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_TOOLS_QUIC_SERVER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/tools/quic_server_bin.cc b/chromium/net/third_party/quiche/src/quic/tools/quic_server_bin.cc
deleted file mode 100644
index 5d3ed7202f4..00000000000
--- a/chromium/net/third_party/quiche/src/quic/tools/quic_server_bin.cc
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// A binary wrapper for QuicServer. It listens forever on --port
-// (default 6121) until it's killed or ctrl-cd to death.
-
-#include <vector>
-
-#include "quic/core/quic_versions.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_system_event_loop.h"
-#include "quic/tools/quic_epoll_server_factory.h"
-#include "quic/tools/quic_toy_server.h"
-#include "common/platform/api/quiche_command_line_flags.h"
-
-int main(int argc, char* argv[]) {
- QuicSystemEventLoop event_loop("quic_server");
- const char* usage = "Usage: quic_server [options]";
- std::vector<std::string> non_option_args =
- quiche::QuicheParseCommandLineFlags(usage, argc, argv);
- if (!non_option_args.empty()) {
- quiche::QuichePrintCommandLineFlagHelp(usage);
- exit(0);
- }
-
- quic::QuicToyServer::MemoryCacheBackendFactory backend_factory;
- quic::QuicEpollServerFactory server_factory;
- quic::QuicToyServer server(&backend_factory, &server_factory);
- return server.Start();
-}
diff --git a/chromium/net/third_party/quiche/src/quic/tools/quic_server_test.cc b/chromium/net/third_party/quiche/src/quic/tools/quic_server_test.cc
deleted file mode 100644
index 80ab7f798a1..00000000000
--- a/chromium/net/third_party/quiche/src/quic/tools/quic_server_test.cc
+++ /dev/null
@@ -1,214 +0,0 @@
-// Copyright 2013 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 "quic/tools/quic_server.h"
-
-#include "absl/base/macros.h"
-#include "quic/core/crypto/quic_random.h"
-#include "quic/core/quic_epoll_alarm_factory.h"
-#include "quic/core/quic_epoll_connection_helper.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/platform/api/quic_port_utils.h"
-#include "quic/platform/api/quic_socket_address.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/platform/api/quic_test_loopback.h"
-#include "quic/test_tools/crypto_test_utils.h"
-#include "quic/test_tools/mock_quic_dispatcher.h"
-#include "quic/test_tools/quic_server_peer.h"
-#include "quic/tools/quic_memory_cache_backend.h"
-#include "quic/tools/quic_simple_crypto_server_stream_helper.h"
-
-namespace quic {
-namespace test {
-
-using ::testing::_;
-
-namespace {
-
-class MockQuicSimpleDispatcher : public QuicSimpleDispatcher {
- public:
- MockQuicSimpleDispatcher(
- 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,
- QuicSimpleServerBackend* quic_simple_server_backend)
- : QuicSimpleDispatcher(config,
- crypto_config,
- version_manager,
- std::move(helper),
- std::move(session_helper),
- std::move(alarm_factory),
- quic_simple_server_backend,
- kQuicDefaultConnectionIdLength) {}
- ~MockQuicSimpleDispatcher() override = default;
-
- MOCK_METHOD(void, OnCanWrite, (), (override));
- MOCK_METHOD(bool, HasPendingWrites, (), (const, override));
- MOCK_METHOD(bool, HasChlosBuffered, (), (const, override));
- MOCK_METHOD(void, ProcessBufferedChlos, (size_t), (override));
-};
-
-class TestQuicServer : public QuicServer {
- public:
- TestQuicServer()
- : QuicServer(crypto_test_utils::ProofSourceForTesting(),
- &quic_simple_server_backend_) {}
-
- ~TestQuicServer() override = default;
-
- MockQuicSimpleDispatcher* mock_dispatcher() { return mock_dispatcher_; }
-
- protected:
- QuicDispatcher* CreateQuicDispatcher() override {
- mock_dispatcher_ = new MockQuicSimpleDispatcher(
- &config(), &crypto_config(), version_manager(),
- std::unique_ptr<QuicEpollConnectionHelper>(
- new QuicEpollConnectionHelper(epoll_server(),
- QuicAllocator::BUFFER_POOL)),
- std::unique_ptr<QuicCryptoServerStreamBase::Helper>(
- new QuicSimpleCryptoServerStreamHelper()),
- std::unique_ptr<QuicEpollAlarmFactory>(
- new QuicEpollAlarmFactory(epoll_server())),
- &quic_simple_server_backend_);
- return mock_dispatcher_;
- }
-
- MockQuicSimpleDispatcher* mock_dispatcher_ = nullptr;
- QuicMemoryCacheBackend quic_simple_server_backend_;
-};
-
-class QuicServerEpollInTest : public QuicTest {
- public:
- QuicServerEpollInTest()
- : port_(QuicPickServerPortForTestsOrDie()),
- server_address_(TestLoopback(), port_) {}
-
- void StartListening() {
- server_.CreateUDPSocketAndListen(server_address_);
- server_address_ = QuicSocketAddress(server_address_.host(), server_.port());
-
- ASSERT_TRUE(QuicServerPeer::SetSmallSocket(&server_));
-
- if (!server_.overflow_supported()) {
- QUIC_LOG(WARNING) << "Overflow not supported. Not testing.";
- return;
- }
- }
-
- protected:
- int port_;
- QuicSocketAddress server_address_;
- TestQuicServer server_;
-};
-
-// Tests that if dispatcher has CHLOs waiting for connection creation, EPOLLIN
-// event should try to create connections for them. And set epoll mask with
-// EPOLLIN if there are still CHLOs remaining at the end of epoll event.
-TEST_F(QuicServerEpollInTest, ProcessBufferedCHLOsOnEpollin) {
- // Given an EPOLLIN event, try to create session for buffered CHLOs. In first
- // event, dispatcher can't create session for all of CHLOs. So listener should
- // register another EPOLLIN event by itself. Even without new packet arrival,
- // the rest CHLOs should be process in next epoll event.
- StartListening();
- bool more_chlos = true;
- MockQuicSimpleDispatcher* dispatcher_ = server_.mock_dispatcher();
- QUICHE_DCHECK(dispatcher_ != nullptr);
- EXPECT_CALL(*dispatcher_, OnCanWrite()).Times(testing::AnyNumber());
- EXPECT_CALL(*dispatcher_, ProcessBufferedChlos(_)).Times(2);
- EXPECT_CALL(*dispatcher_, HasPendingWrites()).Times(testing::AnyNumber());
- // Expect there are still CHLOs buffered after 1st event. But not any more
- // after 2nd event.
- EXPECT_CALL(*dispatcher_, HasChlosBuffered())
- .WillOnce(testing::Return(true))
- .WillOnce(
- DoAll(testing::Assign(&more_chlos, false), testing::Return(false)));
-
- // Send a packet to trigger epoll event.
- int fd = socket(
- AddressFamilyUnderTest() == IpAddressFamily::IP_V4 ? AF_INET : AF_INET6,
- SOCK_DGRAM | SOCK_NONBLOCK, IPPROTO_UDP);
- ASSERT_LT(0, fd);
-
- char buf[1024];
- memset(buf, 0, ABSL_ARRAYSIZE(buf));
- sockaddr_storage storage = server_address_.generic_address();
- int rc = sendto(fd, buf, ABSL_ARRAYSIZE(buf), 0,
- reinterpret_cast<sockaddr*>(&storage), sizeof(storage));
- if (rc < 0) {
- QUIC_DLOG(INFO) << errno << " " << strerror(errno);
- }
-
- while (more_chlos) {
- server_.WaitForEvents();
- }
-}
-
-class QuicServerDispatchPacketTest : public QuicTest {
- public:
- QuicServerDispatchPacketTest()
- : crypto_config_("blah",
- QuicRandom::GetInstance(),
- crypto_test_utils::ProofSourceForTesting(),
- KeyExchangeSource::Default()),
- version_manager_(AllSupportedVersions()),
- dispatcher_(
- &config_,
- &crypto_config_,
- &version_manager_,
- std::unique_ptr<QuicEpollConnectionHelper>(
- new QuicEpollConnectionHelper(&eps_,
- QuicAllocator::BUFFER_POOL)),
- std::unique_ptr<QuicCryptoServerStreamBase::Helper>(
- new QuicSimpleCryptoServerStreamHelper()),
- std::unique_ptr<QuicEpollAlarmFactory>(
- new QuicEpollAlarmFactory(&eps_)),
- &quic_simple_server_backend_) {
- dispatcher_.InitializeWithWriter(new QuicDefaultPacketWriter(1234));
- }
-
- void DispatchPacket(const QuicReceivedPacket& packet) {
- QuicSocketAddress client_addr, server_addr;
- dispatcher_.ProcessPacket(server_addr, client_addr, packet);
- }
-
- protected:
- QuicConfig config_;
- QuicCryptoServerConfig crypto_config_;
- QuicVersionManager version_manager_;
- QuicEpollServer eps_;
- QuicMemoryCacheBackend quic_simple_server_backend_;
- MockQuicDispatcher dispatcher_;
-};
-
-TEST_F(QuicServerDispatchPacketTest, DispatchPacket) {
- // clang-format off
- unsigned char valid_packet[] = {
- // public flags (8 byte connection_id)
- 0x3C,
- // connection_id
- 0x10, 0x32, 0x54, 0x76,
- 0x98, 0xBA, 0xDC, 0xFE,
- // packet number
- 0xBC, 0x9A, 0x78, 0x56,
- 0x34, 0x12,
- // private flags
- 0x00
- };
- // clang-format on
- QuicReceivedPacket encrypted_valid_packet(
- reinterpret_cast<char*>(valid_packet), ABSL_ARRAYSIZE(valid_packet),
- QuicTime::Zero(), false);
-
- EXPECT_CALL(dispatcher_, ProcessPacket(_, _, _)).Times(1);
- DispatchPacket(encrypted_valid_packet);
-}
-
-} // namespace
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/tools/quic_simple_client_session.cc b/chromium/net/third_party/quiche/src/quic/tools/quic_simple_client_session.cc
deleted file mode 100644
index 2e709195113..00000000000
--- a/chromium/net/third_party/quiche/src/quic/tools/quic_simple_client_session.cc
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/tools/quic_simple_client_session.h"
-
-#include <utility>
-
-namespace quic {
-
-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)
- : QuicSimpleClientSession(config, supported_versions, connection, server_id,
- crypto_config, push_promise_index,
- drop_response_body,
- /*enable_web_transport=*/false,
- /*use_datagram_contexts=*/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)
- : 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) {}
-
-std::unique_ptr<QuicSpdyClientStream>
-QuicSimpleClientSession::CreateClientStream() {
- return std::make_unique<QuicSimpleClientStream>(
- GetNextOutgoingBidirectionalStreamId(), this, BIDIRECTIONAL,
- drop_response_body_);
-}
-
-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;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/tools/quic_simple_client_session.h b/chromium/net/third_party/quiche/src/quic/tools/quic_simple_client_session.h
deleted file mode 100644
index 6371448061a..00000000000
--- a/chromium/net/third_party/quiche/src/quic/tools/quic_simple_client_session.h
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TOOLS_QUIC_SIMPLE_CLIENT_SESSION_H_
-#define QUICHE_QUIC_TOOLS_QUIC_SIMPLE_CLIENT_SESSION_H_
-
-#include "quic/core/http/quic_spdy_client_session.h"
-#include "quic/tools/quic_simple_client_stream.h"
-
-namespace quic {
-
-class QuicSimpleClientSession : public QuicSpdyClientSession {
- public:
- 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);
- 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);
-
- 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
-
-#endif // QUICHE_QUIC_TOOLS_QUIC_SIMPLE_CLIENT_SESSION_H_
diff --git a/chromium/net/third_party/quiche/src/quic/tools/quic_simple_client_stream.cc b/chromium/net/third_party/quiche/src/quic/tools/quic_simple_client_stream.cc
deleted file mode 100644
index 21145e1e2c7..00000000000
--- a/chromium/net/third_party/quiche/src/quic/tools/quic_simple_client_stream.cc
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/tools/quic_simple_client_stream.h"
-
-namespace quic {
-
-void QuicSimpleClientStream::OnBodyAvailable() {
- if (!drop_response_body_) {
- QuicSpdyClientStream::OnBodyAvailable();
- return;
- }
-
- while (HasBytesToRead()) {
- struct iovec iov;
- if (GetReadableRegions(&iov, 1) == 0) {
- break;
- }
- MarkConsumed(iov.iov_len);
- }
- if (sequencer()->IsClosed()) {
- OnFinRead();
- } else {
- sequencer()->SetUnblocked();
- }
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/tools/quic_simple_client_stream.h b/chromium/net/third_party/quiche/src/quic/tools/quic_simple_client_stream.h
deleted file mode 100644
index 471bdfb7553..00000000000
--- a/chromium/net/third_party/quiche/src/quic/tools/quic_simple_client_stream.h
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TOOLS_QUIC_SIMPLE_CLIENT_STREAM_H_
-#define QUICHE_QUIC_TOOLS_QUIC_SIMPLE_CLIENT_STREAM_H_
-
-#include "quic/core/http/quic_spdy_client_stream.h"
-
-namespace quic {
-
-class QuicSimpleClientStream : public QuicSpdyClientStream {
- public:
- QuicSimpleClientStream(QuicStreamId id,
- QuicSpdyClientSession* session,
- StreamType type,
- bool drop_response_body)
- : QuicSpdyClientStream(id, session, type),
- drop_response_body_(drop_response_body) {}
- void OnBodyAvailable() override;
-
- private:
- const bool drop_response_body_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_TOOLS_QUIC_SIMPLE_CLIENT_STREAM_H_
diff --git a/chromium/net/third_party/quiche/src/quic/tools/quic_simple_crypto_server_stream_helper.cc b/chromium/net/third_party/quiche/src/quic/tools/quic_simple_crypto_server_stream_helper.cc
deleted file mode 100644
index 5c39d20e97b..00000000000
--- a/chromium/net/third_party/quiche/src/quic/tools/quic_simple_crypto_server_stream_helper.cc
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/tools/quic_simple_crypto_server_stream_helper.h"
-
-#include "quic/core/quic_utils.h"
-
-namespace quic {
-
-QuicSimpleCryptoServerStreamHelper::QuicSimpleCryptoServerStreamHelper() =
- default;
-
-QuicSimpleCryptoServerStreamHelper::~QuicSimpleCryptoServerStreamHelper() =
- default;
-
-bool QuicSimpleCryptoServerStreamHelper::CanAcceptClientHello(
- const CryptoHandshakeMessage& /*message*/,
- const QuicSocketAddress& /*client_address*/,
- const QuicSocketAddress& /*peer_address*/,
- const QuicSocketAddress& /*self_address*/,
- std::string* /*error_details*/) const {
- return true;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/tools/quic_simple_crypto_server_stream_helper.h b/chromium/net/third_party/quiche/src/quic/tools/quic_simple_crypto_server_stream_helper.h
deleted file mode 100644
index 1fccfc0d447..00000000000
--- a/chromium/net/third_party/quiche/src/quic/tools/quic_simple_crypto_server_stream_helper.h
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TOOLS_QUIC_SIMPLE_CRYPTO_SERVER_STREAM_HELPER_H_
-#define QUICHE_QUIC_TOOLS_QUIC_SIMPLE_CRYPTO_SERVER_STREAM_HELPER_H_
-
-#include "quic/core/crypto/quic_random.h"
-#include "quic/core/quic_crypto_server_stream_base.h"
-
-namespace quic {
-
-// Simple helper for server crypto streams which generates a new random
-// connection ID for rejects.
-class QuicSimpleCryptoServerStreamHelper
- : public QuicCryptoServerStreamBase::Helper {
- public:
- QuicSimpleCryptoServerStreamHelper();
-
- ~QuicSimpleCryptoServerStreamHelper() override;
-
- bool CanAcceptClientHello(const CryptoHandshakeMessage& message,
- const QuicSocketAddress& client_address,
- const QuicSocketAddress& peer_address,
- const QuicSocketAddress& self_address,
- std::string* error_details) const override;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_TOOLS_QUIC_SIMPLE_CRYPTO_SERVER_STREAM_HELPER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/tools/quic_simple_dispatcher.cc b/chromium/net/third_party/quiche/src/quic/tools/quic_simple_dispatcher.cc
deleted file mode 100644
index 7864ce77e07..00000000000
--- a/chromium/net/third_party/quiche/src/quic/tools/quic_simple_dispatcher.cc
+++ /dev/null
@@ -1,70 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/tools/quic_simple_dispatcher.h"
-
-#include "absl/strings/string_view.h"
-#include "quic/tools/quic_simple_server_session.h"
-
-namespace quic {
-
-QuicSimpleDispatcher::QuicSimpleDispatcher(
- 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,
- QuicSimpleServerBackend* quic_simple_server_backend,
- uint8_t expected_server_connection_id_length)
- : QuicDispatcher(config,
- crypto_config,
- version_manager,
- std::move(helper),
- std::move(session_helper),
- std::move(alarm_factory),
- expected_server_connection_id_length),
- quic_simple_server_backend_(quic_simple_server_backend) {}
-
-QuicSimpleDispatcher::~QuicSimpleDispatcher() = default;
-
-int QuicSimpleDispatcher::GetRstErrorCount(
- QuicRstStreamErrorCode error_code) const {
- auto it = rst_error_map_.find(error_code);
- if (it == rst_error_map_.end()) {
- return 0;
- }
- return it->second;
-}
-
-void QuicSimpleDispatcher::OnRstStreamReceived(
- const QuicRstStreamFrame& frame) {
- auto it = rst_error_map_.find(frame.error_code);
- if (it == rst_error_map_.end()) {
- rst_error_map_.insert(std::make_pair(frame.error_code, 1));
- } else {
- it->second++;
- }
-}
-
-std::unique_ptr<QuicSession> QuicSimpleDispatcher::CreateQuicSession(
- QuicConnectionId connection_id, const QuicSocketAddress& self_address,
- const QuicSocketAddress& peer_address, absl::string_view /*alpn*/,
- const ParsedQuicVersion& version,
- const ParsedClientHello& /*parsed_chlo*/) {
- // The QuicServerSessionBase takes ownership of |connection| below.
- QuicConnection* connection =
- new QuicConnection(connection_id, self_address, peer_address, helper(),
- alarm_factory(), writer(),
- /* owns_writer= */ false, Perspective::IS_SERVER,
- ParsedQuicVersionVector{version});
-
- auto session = std::make_unique<QuicSimpleServerSession>(
- config(), GetSupportedVersions(), connection, this, session_helper(),
- crypto_config(), compressed_certs_cache(), quic_simple_server_backend_);
- session->Initialize();
- return session;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/tools/quic_simple_dispatcher.h b/chromium/net/third_party/quiche/src/quic/tools/quic_simple_dispatcher.h
deleted file mode 100644
index ce9d680d1ae..00000000000
--- a/chromium/net/third_party/quiche/src/quic/tools/quic_simple_dispatcher.h
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TOOLS_QUIC_SIMPLE_DISPATCHER_H_
-#define QUICHE_QUIC_TOOLS_QUIC_SIMPLE_DISPATCHER_H_
-
-#include "absl/strings/string_view.h"
-#include "quic/core/http/quic_server_session_base.h"
-#include "quic/core/quic_dispatcher.h"
-#include "quic/tools/quic_simple_server_backend.h"
-
-namespace quic {
-
-class QuicSimpleDispatcher : public QuicDispatcher {
- public:
- QuicSimpleDispatcher(
- 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,
- QuicSimpleServerBackend* quic_simple_server_backend,
- uint8_t expected_server_connection_id_length);
-
- ~QuicSimpleDispatcher() override;
-
- int GetRstErrorCount(QuicRstStreamErrorCode rst_error_code) const;
-
- void OnRstStreamReceived(const QuicRstStreamFrame& frame) override;
-
- protected:
- std::unique_ptr<QuicSession> CreateQuicSession(
- QuicConnectionId connection_id, const QuicSocketAddress& self_address,
- const QuicSocketAddress& peer_address, absl::string_view alpn,
- const ParsedQuicVersion& version,
- const ParsedClientHello& parsed_chlo) override;
-
- QuicSimpleServerBackend* server_backend() {
- return quic_simple_server_backend_;
- }
-
- private:
- QuicSimpleServerBackend* quic_simple_server_backend_; // Unowned.
-
- // The map of the reset error code with its counter.
- std::map<QuicRstStreamErrorCode, int> rst_error_map_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_TOOLS_QUIC_SIMPLE_DISPATCHER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/tools/quic_simple_server_backend.h b/chromium/net/third_party/quiche/src/quic/tools/quic_simple_server_backend.h
deleted file mode 100644
index 25204aca8f5..00000000000
--- a/chromium/net/third_party/quiche/src/quic/tools/quic_simple_server_backend.h
+++ /dev/null
@@ -1,76 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TOOLS_QUIC_SIMPLE_SERVER_BACKEND_H_
-#define QUICHE_QUIC_TOOLS_QUIC_SIMPLE_SERVER_BACKEND_H_
-
-#include <memory>
-
-#include "quic/core/quic_types.h"
-#include "quic/core/web_transport_interface.h"
-#include "quic/tools/quic_backend_response.h"
-#include "spdy/core/spdy_header_block.h"
-
-namespace quic {
-
-// This interface implements the functionality to fetch a response
-// from the backend (such as cache, http-proxy etc) to serve
-// requests received by a Quic Server
-class QuicSimpleServerBackend {
- public:
- // This interface implements the methods
- // called by the QuicSimpleServerBackend implementation
- // to process the request in the backend
- class RequestHandler {
- public:
- virtual ~RequestHandler() {}
-
- virtual QuicConnectionId connection_id() const = 0;
- virtual QuicStreamId stream_id() const = 0;
- virtual std::string peer_host() const = 0;
- // Called when the response is ready at the backend and can be send back to
- // the QUIC client.
- virtual void OnResponseBackendComplete(
- const QuicBackendResponse* response) = 0;
- };
-
- struct WebTransportResponse {
- spdy::Http2HeaderBlock response_headers;
- std::unique_ptr<WebTransportVisitor> visitor;
- };
-
- virtual ~QuicSimpleServerBackend() = default;
- // This method initializes the backend instance to fetch responses
- // from a backend server, in-memory cache etc.
- virtual bool InitializeBackend(const std::string& backend_url) = 0;
- // Returns true if the backend has been successfully initialized
- // and could be used to fetch HTTP requests
- 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.
- // If the response has to be fetched over the network, the function
- // asynchronously calls |request_handler| with the HTTP response.
- virtual void FetchResponseFromBackend(
- const spdy::Http2HeaderBlock& request_headers,
- const std::string& request_body,
- RequestHandler* request_handler) = 0;
- // Clears the state of the backend instance
- virtual void CloseBackendResponseStream(RequestHandler* request_handler) = 0;
-
- virtual WebTransportResponse ProcessWebTransportRequest(
- const spdy::Http2HeaderBlock& /*request_headers*/,
- WebTransportSession* /*session*/) {
- WebTransportResponse response;
- response.response_headers[":status"] = "400";
- return response;
- }
- virtual bool SupportsWebTransport() { return false; }
- virtual bool UsesDatagramContexts() { return false; }
- virtual bool SupportsExtendedConnect() { return true; }
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_TOOLS_QUIC_SIMPLE_SERVER_BACKEND_H_
diff --git a/chromium/net/third_party/quiche/src/quic/tools/quic_simple_server_session.cc b/chromium/net/third_party/quiche/src/quic/tools/quic_simple_server_session.cc
deleted file mode 100644
index d1e9a73e635..00000000000
--- a/chromium/net/third_party/quiche/src/quic/tools/quic_simple_server_session.cc
+++ /dev/null
@@ -1,225 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/tools/quic_simple_server_session.h"
-
-#include <utility>
-
-#include "absl/memory/memory.h"
-#include "quic/core/http/quic_server_initiated_spdy_stream.h"
-#include "quic/core/http/quic_spdy_session.h"
-#include "quic/core/quic_connection.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/tools/quic_simple_server_stream.h"
-
-namespace quic {
-
-QuicSimpleServerSession::QuicSimpleServerSession(
- const QuicConfig& config, const ParsedQuicVersionVector& supported_versions,
- QuicConnection* connection, QuicSession::Visitor* visitor,
- QuicCryptoServerStreamBase::Helper* helper,
- const QuicCryptoServerConfig* crypto_config,
- QuicCompressedCertsCache* compressed_certs_cache,
- QuicSimpleServerBackend* quic_simple_server_backend)
- : QuicServerSessionBase(config, supported_versions, connection, visitor,
- helper, crypto_config, compressed_certs_cache),
- highest_promised_stream_id_(
- QuicUtils::GetInvalidStreamId(connection->transport_version())),
- quic_simple_server_backend_(quic_simple_server_backend) {
- QUICHE_DCHECK(quic_simple_server_backend_);
-}
-
-QuicSimpleServerSession::~QuicSimpleServerSession() { DeleteConnection(); }
-
-std::unique_ptr<QuicCryptoServerStreamBase>
-QuicSimpleServerSession::CreateQuicCryptoServerStream(
- const QuicCryptoServerConfig* crypto_config,
- QuicCompressedCertsCache* compressed_certs_cache) {
- return CreateCryptoServerStream(crypto_config, compressed_certs_cache, this,
- stream_helper());
-}
-
-void QuicSimpleServerSession::OnStreamFrame(const QuicStreamFrame& frame) {
- if (!IsIncomingStream(frame.stream_id) && !WillNegotiateWebTransport()) {
- QUIC_LOG(WARNING) << "Client shouldn't send data on server push stream";
- connection()->CloseConnection(
- QUIC_INVALID_STREAM_ID, "Client sent data on server push stream",
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
- return;
- }
- QuicSpdySession::OnStreamFrame(frame);
-}
-
-QuicSpdyStream* QuicSimpleServerSession::CreateIncomingStream(QuicStreamId id) {
- if (!ShouldCreateIncomingStream(id)) {
- return nullptr;
- }
-
- QuicSpdyStream* stream = new QuicSimpleServerStream(
- id, this, BIDIRECTIONAL, quic_simple_server_backend_);
- ActivateStream(absl::WrapUnique(stream));
- return stream;
-}
-
-QuicSpdyStream* QuicSimpleServerSession::CreateIncomingStream(
- PendingStream* pending) {
- QuicSpdyStream* stream =
- new QuicSimpleServerStream(pending, this, quic_simple_server_backend_);
- ActivateStream(absl::WrapUnique(stream));
- return stream;
-}
-
-QuicSpdyStream* QuicSimpleServerSession::CreateOutgoingBidirectionalStream() {
- if (!WillNegotiateWebTransport()) {
- QUIC_BUG(QuicSimpleServerSession CreateOutgoingBidirectionalStream without
- WebTransport support)
- << "QuicSimpleServerSession::CreateOutgoingBidirectionalStream called "
- "in a session without WebTransport support.";
- return nullptr;
- }
- if (!ShouldCreateOutgoingBidirectionalStream()) {
- return nullptr;
- }
-
- QuicServerInitiatedSpdyStream* stream = new QuicServerInitiatedSpdyStream(
- GetNextOutgoingBidirectionalStreamId(), this, BIDIRECTIONAL);
- ActivateStream(absl::WrapUnique(stream));
- return stream;
-}
-
-QuicSimpleServerStream*
-QuicSimpleServerSession::CreateOutgoingUnidirectionalStream() {
- if (!ShouldCreateOutgoingUnidirectionalStream()) {
- return nullptr;
- }
-
- QuicSimpleServerStream* stream = new QuicSimpleServerStream(
- GetNextOutgoingUnidirectionalStreamId(), this, WRITE_UNIDIRECTIONAL,
- quic_simple_server_backend_);
- ActivateStream(absl::WrapUnique(stream));
- return stream;
-}
-
-void QuicSimpleServerSession::HandleFrameOnNonexistentOutgoingStream(
- QuicStreamId stream_id) {
- // If this stream is a promised but not created stream (stream_id within the
- // range of next_outgoing_stream_id_ and highes_promised_stream_id_),
- // connection shouldn't be closed.
- // Otherwise behave in the same way as base class.
- if (highest_promised_stream_id_ ==
- QuicUtils::GetInvalidStreamId(transport_version()) ||
- stream_id > highest_promised_stream_id_) {
- QuicSession::HandleFrameOnNonexistentOutgoingStream(stream_id);
- }
-}
-
-void QuicSimpleServerSession::HandleRstOnValidNonexistentStream(
- const QuicRstStreamFrame& frame) {
- QuicSession::HandleRstOnValidNonexistentStream(frame);
- if (!IsClosedStream(frame.stream_id)) {
- // If a nonexistent stream is not a closed stream and still valid, it must
- // be a locally preserved stream. Resetting this kind of stream means
- // cancelling the promised server push.
- // Since PromisedStreamInfo are queued in sequence, the corresponding
- // index for it in promised_streams_ can be calculated.
- QuicStreamId next_stream_id = next_outgoing_unidirectional_stream_id();
- if ((!version().HasIetfQuicFrames() ||
- !QuicUtils::IsBidirectionalStreamId(frame.stream_id, version())) &&
- frame.stream_id >= next_stream_id) {
- size_t index = (frame.stream_id - next_stream_id) /
- QuicUtils::StreamIdDelta(transport_version());
- if (index <= promised_streams_.size()) {
- promised_streams_[index].is_cancelled = true;
- }
- }
- control_frame_manager().WriteOrBufferRstStream(
- frame.stream_id,
- QuicResetStreamError::FromInternal(QUIC_RST_ACKNOWLEDGEMENT), 0);
- connection()->OnStreamReset(frame.stream_id, QUIC_RST_ACKNOWLEDGEMENT);
- }
-}
-
-spdy::Http2HeaderBlock QuicSimpleServerSession::SynthesizePushRequestHeaders(
- std::string request_url, QuicBackendResponse::ServerPushInfo resource,
- const spdy::Http2HeaderBlock& original_request_headers) {
- QuicUrl push_request_url = resource.request_url;
-
- spdy::Http2HeaderBlock spdy_headers = original_request_headers.Clone();
- // :authority could be different from original request.
- spdy_headers[":authority"] = push_request_url.host();
- spdy_headers[":path"] = push_request_url.path();
- // Push request always use GET.
- spdy_headers[":method"] = "GET";
- spdy_headers["referer"] = request_url;
- spdy_headers[":scheme"] = push_request_url.scheme();
- // It is not possible to push a response to a request that includes a request
- // body.
- spdy_headers["content-length"] = "0";
- // Remove "host" field as push request is a directly generated HTTP2 request
- // which should use ":authority" instead of "host".
- spdy_headers.erase("host");
- return spdy_headers;
-}
-
-void QuicSimpleServerSession::SendPushPromise(QuicStreamId original_stream_id,
- QuicStreamId promised_stream_id,
- spdy::Http2HeaderBlock headers) {
- QUIC_DLOG(INFO) << "stream " << original_stream_id
- << " send PUSH_PROMISE for promised stream "
- << promised_stream_id;
- WritePushPromise(original_stream_id, promised_stream_id, std::move(headers));
-}
-
-void QuicSimpleServerSession::HandlePromisedPushRequests() {
- while (!promised_streams_.empty() &&
- ShouldCreateOutgoingUnidirectionalStream()) {
- PromisedStreamInfo& promised_info = promised_streams_.front();
- QUICHE_DCHECK_EQ(next_outgoing_unidirectional_stream_id(),
- promised_info.stream_id);
-
- if (promised_info.is_cancelled) {
- // This stream has been reset by client. Skip this stream id.
- promised_streams_.pop_front();
- GetNextOutgoingUnidirectionalStreamId();
- return;
- }
-
- QuicSimpleServerStream* promised_stream =
- static_cast<QuicSimpleServerStream*>(
- CreateOutgoingUnidirectionalStream());
- QUICHE_DCHECK_NE(promised_stream, nullptr);
- QUICHE_DCHECK_EQ(promised_info.stream_id, promised_stream->id());
- QUIC_DLOG(INFO) << "created server push stream " << promised_stream->id();
-
- promised_stream->SetPriority(promised_info.precedence);
-
- spdy::Http2HeaderBlock request_headers(
- std::move(promised_info.request_headers));
-
- promised_streams_.pop_front();
- promised_stream->PushResponse(std::move(request_headers));
- }
-}
-
-void QuicSimpleServerSession::OnCanCreateNewOutgoingStream(
- bool unidirectional) {
- QuicSpdySession::OnCanCreateNewOutgoingStream(unidirectional);
- if (unidirectional) {
- HandlePromisedPushRequests();
- }
-}
-
-void QuicSimpleServerSession::MaybeInitializeHttp3UnidirectionalStreams() {
- size_t previous_static_stream_count = num_static_streams();
- QuicSpdySession::MaybeInitializeHttp3UnidirectionalStreams();
- size_t current_static_stream_count = num_static_streams();
- QUICHE_DCHECK_GE(current_static_stream_count, previous_static_stream_count);
- highest_promised_stream_id_ +=
- QuicUtils::StreamIdDelta(transport_version()) *
- (current_static_stream_count - previous_static_stream_count);
-}
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/tools/quic_simple_server_session.h b/chromium/net/third_party/quiche/src/quic/tools/quic_simple_server_session.h
deleted file mode 100644
index 393a2d8d63d..00000000000
--- a/chromium/net/third_party/quiche/src/quic/tools/quic_simple_server_session.h
+++ /dev/null
@@ -1,160 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// A toy server specific QuicSession subclass.
-
-#ifndef QUICHE_QUIC_TOOLS_QUIC_SIMPLE_SERVER_SESSION_H_
-#define QUICHE_QUIC_TOOLS_QUIC_SIMPLE_SERVER_SESSION_H_
-
-#include <stdint.h>
-
-#include <list>
-#include <memory>
-#include <set>
-#include <string>
-#include <utility>
-#include <vector>
-
-#include "quic/core/http/quic_server_session_base.h"
-#include "quic/core/http/quic_spdy_session.h"
-#include "quic/core/quic_crypto_server_stream_base.h"
-#include "quic/core/quic_packets.h"
-#include "quic/platform/api/quic_containers.h"
-#include "quic/tools/quic_backend_response.h"
-#include "quic/tools/quic_simple_server_backend.h"
-#include "quic/tools/quic_simple_server_stream.h"
-
-namespace quic {
-
-namespace test {
-class QuicSimpleServerSessionPeer;
-} // namespace test
-
-class QuicSimpleServerSession : public QuicServerSessionBase {
- public:
- // A PromisedStreamInfo is an element of the queue to store promised
- // stream which hasn't been created yet. It keeps a mapping between promised
- // stream id with its priority and the headers sent out in PUSH_PROMISE.
- struct PromisedStreamInfo {
- public:
- PromisedStreamInfo(spdy::Http2HeaderBlock request_headers,
- QuicStreamId stream_id,
- const spdy::SpdyStreamPrecedence& precedence)
- : request_headers(std::move(request_headers)),
- stream_id(stream_id),
- precedence(precedence),
- is_cancelled(false) {}
- spdy::Http2HeaderBlock request_headers;
- QuicStreamId stream_id;
- spdy::SpdyStreamPrecedence precedence;
- bool is_cancelled;
- };
-
- // Takes ownership of |connection|.
- QuicSimpleServerSession(const QuicConfig& config,
- const ParsedQuicVersionVector& supported_versions,
- QuicConnection* connection,
- QuicSession::Visitor* visitor,
- QuicCryptoServerStreamBase::Helper* helper,
- const QuicCryptoServerConfig* crypto_config,
- QuicCompressedCertsCache* compressed_certs_cache,
- QuicSimpleServerBackend* quic_simple_server_backend);
- QuicSimpleServerSession(const QuicSimpleServerSession&) = delete;
- QuicSimpleServerSession& operator=(const QuicSimpleServerSession&) = delete;
-
- ~QuicSimpleServerSession() override;
-
- // Override base class to detact client sending data on server push stream.
- void OnStreamFrame(const QuicStreamFrame& frame) override;
-
- void OnCanCreateNewOutgoingStream(bool unidirectional) override;
-
- bool ShouldNegotiateDatagramContexts() override {
- return quic_simple_server_backend_->UsesDatagramContexts();
- }
-
- protected:
- // QuicSession methods:
- QuicSpdyStream* CreateIncomingStream(QuicStreamId id) override;
- QuicSpdyStream* CreateIncomingStream(PendingStream* pending) override;
- QuicSpdyStream* CreateOutgoingBidirectionalStream() override;
- QuicSimpleServerStream* CreateOutgoingUnidirectionalStream() override;
- // Override to return true for locally preserved server push stream.
- void HandleFrameOnNonexistentOutgoingStream(QuicStreamId stream_id) override;
- // Override to handle reseting locally preserved streams.
- void HandleRstOnValidNonexistentStream(
- const QuicRstStreamFrame& frame) override;
-
- // QuicServerSessionBaseMethod:
- std::unique_ptr<QuicCryptoServerStreamBase> CreateQuicCryptoServerStream(
- const QuicCryptoServerConfig* crypto_config,
- QuicCompressedCertsCache* compressed_certs_cache) override;
-
- QuicSimpleServerBackend* server_backend() {
- return quic_simple_server_backend_;
- }
-
- void MaybeInitializeHttp3UnidirectionalStreams() override;
-
- bool ShouldNegotiateWebTransport() override {
- return quic_simple_server_backend_->SupportsWebTransport();
- }
- HttpDatagramSupport LocalHttpDatagramSupport() override {
- if (ShouldNegotiateWebTransport()) {
- return HttpDatagramSupport::kDraft00And04;
- }
- return QuicServerSessionBase::LocalHttpDatagramSupport();
- }
-
- private:
- friend class test::QuicSimpleServerSessionPeer;
-
- // Create a server push headers block by copying request's headers block.
- // But replace or add these pseudo-headers as they are specific to each
- // request:
- // :authority, :path, :method, :scheme, referer.
- // Copying the rest headers ensures they are the same as the original
- // request, especially cookies.
- spdy::Http2HeaderBlock SynthesizePushRequestHeaders(
- std::string request_url,
- QuicBackendResponse::ServerPushInfo resource,
- const spdy::Http2HeaderBlock& original_request_headers);
-
- // Send PUSH_PROMISE frame on headers stream.
- void SendPushPromise(QuicStreamId original_stream_id,
- QuicStreamId promised_stream_id,
- spdy::Http2HeaderBlock headers);
-
- // Fetch response from cache for request headers enqueued into
- // promised_headers_and_streams_ and send them on dedicated stream until
- // reaches max_open_stream_ limit.
- // Called when return value of GetNumOpenOutgoingStreams() changes:
- // CloseStreamInner();
- // StreamDraining();
- // Note that updateFlowControlOnFinalReceivedByteOffset() won't change the
- // return value becasue all push streams are impossible to become locally
- // closed. Since a locally preserved stream becomes remotely closed after
- // HandlePromisedPushRequests() starts to process it, and if it is reset
- // locally afterwards, it will be immediately become closed and never get into
- // locally_closed_stream_highest_offset_. So all the streams in this map
- // are not outgoing streams.
- void HandlePromisedPushRequests();
-
- // Keep track of the highest stream id which has been sent in PUSH_PROMISE.
- QuicStreamId highest_promised_stream_id_;
-
- // Promised streams which hasn't been created yet because of max_open_stream_
- // limit. New element is added to the end of the queue.
- // Since outgoing stream is created in sequence, stream_id of each element in
- // the queue also increases by 2 from previous one's. The front element's
- // stream_id is always next_outgoing_stream_id_, and the last one is always
- // highest_promised_stream_id_.
- quiche::QuicheCircularDeque<PromisedStreamInfo> promised_streams_;
-
- QuicSimpleServerBackend* quic_simple_server_backend_; // Not owned.
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_TOOLS_QUIC_SIMPLE_SERVER_SESSION_H_
diff --git a/chromium/net/third_party/quiche/src/quic/tools/quic_simple_server_session_test.cc b/chromium/net/third_party/quiche/src/quic/tools/quic_simple_server_session_test.cc
deleted file mode 100644
index 9cc7bfda17c..00000000000
--- a/chromium/net/third_party/quiche/src/quic/tools/quic_simple_server_session_test.cc
+++ /dev/null
@@ -1,595 +0,0 @@
-// Copyright 2013 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 "quic/tools/quic_simple_server_session.h"
-
-#include <algorithm>
-#include <memory>
-#include <utility>
-
-#include "absl/strings/str_cat.h"
-#include "quic/core/crypto/null_encrypter.h"
-#include "quic/core/crypto/quic_crypto_server_config.h"
-#include "quic/core/crypto/quic_random.h"
-#include "quic/core/http/http_encoder.h"
-#include "quic/core/proto/cached_network_parameters_proto.h"
-#include "quic/core/quic_connection.h"
-#include "quic/core/quic_crypto_server_stream.h"
-#include "quic/core/quic_utils.h"
-#include "quic/core/quic_versions.h"
-#include "quic/core/tls_server_handshaker.h"
-#include "quic/platform/api/quic_containers.h"
-#include "quic/platform/api/quic_expect_bug.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_socket_address.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/crypto_test_utils.h"
-#include "quic/test_tools/mock_quic_session_visitor.h"
-#include "quic/test_tools/quic_config_peer.h"
-#include "quic/test_tools/quic_connection_peer.h"
-#include "quic/test_tools/quic_sent_packet_manager_peer.h"
-#include "quic/test_tools/quic_session_peer.h"
-#include "quic/test_tools/quic_spdy_session_peer.h"
-#include "quic/test_tools/quic_stream_peer.h"
-#include "quic/test_tools/quic_sustained_bandwidth_recorder_peer.h"
-#include "quic/test_tools/quic_test_utils.h"
-#include "quic/tools/quic_backend_response.h"
-#include "quic/tools/quic_memory_cache_backend.h"
-#include "quic/tools/quic_simple_server_stream.h"
-
-using testing::_;
-using testing::AtLeast;
-using testing::InSequence;
-using testing::Invoke;
-using testing::Return;
-using testing::StrictMock;
-
-namespace quic {
-namespace test {
-namespace {
-
-// Data to be sent on a request stream. In Google QUIC, this is interpreted as
-// DATA payload (there is no framing on request streams). In IETF QUIC, this is
-// interpreted as HEADERS frame (type 0x1) with payload length 122 ('z'). Since
-// no payload is included, QPACK decoder will not be invoked.
-const char* const kStreamData = "\1z";
-
-} // namespace
-
-class QuicSimpleServerSessionPeer {
- public:
- static void SetCryptoStream(QuicSimpleServerSession* s,
- QuicCryptoServerStreamBase* crypto_stream) {
- s->crypto_stream_.reset(crypto_stream);
- }
-
- static QuicSpdyStream* CreateIncomingStream(QuicSimpleServerSession* s,
- QuicStreamId id) {
- return s->CreateIncomingStream(id);
- }
-
- static QuicSimpleServerStream* CreateOutgoingUnidirectionalStream(
- QuicSimpleServerSession* s) {
- return s->CreateOutgoingUnidirectionalStream();
- }
-};
-
-namespace {
-
-const size_t kMaxStreamsForTest = 10;
-
-class MockQuicCryptoServerStream : public QuicCryptoServerStream {
- public:
- explicit MockQuicCryptoServerStream(
- const QuicCryptoServerConfig* crypto_config,
- QuicCompressedCertsCache* compressed_certs_cache,
- QuicSession* session,
- QuicCryptoServerStreamBase::Helper* helper)
- : QuicCryptoServerStream(crypto_config,
- compressed_certs_cache,
- session,
- helper) {}
- MockQuicCryptoServerStream(const MockQuicCryptoServerStream&) = delete;
- MockQuicCryptoServerStream& operator=(const MockQuicCryptoServerStream&) =
- delete;
- ~MockQuicCryptoServerStream() override {}
-
- MOCK_METHOD(void,
- SendServerConfigUpdate,
- (const CachedNetworkParameters*),
- (override));
-
- bool encryption_established() const override { return true; }
-};
-
-class MockTlsServerHandshaker : public TlsServerHandshaker {
- public:
- explicit MockTlsServerHandshaker(QuicSession* session,
- const QuicCryptoServerConfig* crypto_config)
- : TlsServerHandshaker(session, crypto_config) {}
- MockTlsServerHandshaker(const MockTlsServerHandshaker&) = delete;
- MockTlsServerHandshaker& operator=(const MockTlsServerHandshaker&) = delete;
- ~MockTlsServerHandshaker() override {}
-
- MOCK_METHOD(void,
- SendServerConfigUpdate,
- (const CachedNetworkParameters*),
- (override));
-
- bool encryption_established() const override { return true; }
-};
-
-QuicCryptoServerStreamBase* CreateMockCryptoServerStream(
- const QuicCryptoServerConfig* crypto_config,
- QuicCompressedCertsCache* compressed_certs_cache,
- QuicSession* session,
- QuicCryptoServerStreamBase::Helper* helper) {
- switch (session->connection()->version().handshake_protocol) {
- case PROTOCOL_QUIC_CRYPTO:
- return new MockQuicCryptoServerStream(
- crypto_config, compressed_certs_cache, session, helper);
- case PROTOCOL_TLS1_3:
- return new MockTlsServerHandshaker(session, crypto_config);
- case PROTOCOL_UNSUPPORTED:
- break;
- }
- QUIC_BUG(quic_bug_10933_1)
- << "Unknown handshake protocol: "
- << static_cast<int>(session->connection()->version().handshake_protocol);
- return nullptr;
-}
-
-class MockQuicConnectionWithSendStreamData : public MockQuicConnection {
- public:
- MockQuicConnectionWithSendStreamData(
- MockQuicConnectionHelper* helper,
- MockAlarmFactory* alarm_factory,
- Perspective perspective,
- const ParsedQuicVersionVector& supported_versions)
- : MockQuicConnection(helper,
- alarm_factory,
- perspective,
- supported_versions) {
- auto consume_all_data = [](QuicStreamId /*id*/, size_t write_length,
- QuicStreamOffset /*offset*/,
- StreamSendingState state) {
- return QuicConsumedData(write_length, state != NO_FIN);
- };
- ON_CALL(*this, SendStreamData(_, _, _, _))
- .WillByDefault(Invoke(consume_all_data));
- }
-
- MOCK_METHOD(QuicConsumedData,
- SendStreamData,
- (QuicStreamId id,
- size_t write_length,
- QuicStreamOffset offset,
- StreamSendingState state),
- (override));
-};
-
-class MockQuicSimpleServerSession : public QuicSimpleServerSession {
- public:
- MockQuicSimpleServerSession(
- const QuicConfig& config,
- QuicConnection* connection,
- QuicSession::Visitor* visitor,
- QuicCryptoServerStreamBase::Helper* helper,
- const QuicCryptoServerConfig* crypto_config,
- QuicCompressedCertsCache* compressed_certs_cache,
- QuicSimpleServerBackend* quic_simple_server_backend)
- : QuicSimpleServerSession(config,
- CurrentSupportedVersions(),
- connection,
- visitor,
- helper,
- crypto_config,
- compressed_certs_cache,
- quic_simple_server_backend) {}
- // Methods taking non-copyable types like Http2HeaderBlock by value cannot be
- // mocked directly.
- void WritePushPromise(QuicStreamId original_stream_id,
- QuicStreamId promised_stream_id,
- spdy::Http2HeaderBlock headers) override {
- return WritePushPromiseMock(original_stream_id, promised_stream_id,
- headers);
- }
- MOCK_METHOD(void,
- WritePushPromiseMock,
- (QuicStreamId original_stream_id,
- QuicStreamId promised_stream_id,
- const spdy::Http2HeaderBlock& headers),
- ());
-
- MOCK_METHOD(void, SendBlocked, (QuicStreamId), (override));
- MOCK_METHOD(bool,
- WriteControlFrame,
- (const QuicFrame& frame, TransmissionType type),
- (override));
-};
-
-class QuicSimpleServerSessionTest
- : public QuicTestWithParam<ParsedQuicVersion> {
- public:
- // The function ensures that A) the MAX_STREAMS frames get properly deleted
- // (since the test uses a 'did we leak memory' check ... if we just lose the
- // frame, the test fails) and B) returns true (instead of the default, false)
- // which ensures that the rest of the system thinks that the frame actually
- // was transmitted.
- bool ClearMaxStreamsControlFrame(const QuicFrame& frame) {
- if (frame.type == MAX_STREAMS_FRAME) {
- DeleteFrame(&const_cast<QuicFrame&>(frame));
- return true;
- }
- return false;
- }
-
- protected:
- QuicSimpleServerSessionTest()
- : crypto_config_(QuicCryptoServerConfig::TESTING,
- QuicRandom::GetInstance(),
- crypto_test_utils::ProofSourceForTesting(),
- KeyExchangeSource::Default()),
- compressed_certs_cache_(
- QuicCompressedCertsCache::kQuicCompressedCertsCacheSize) {
- config_.SetMaxBidirectionalStreamsToSend(kMaxStreamsForTest);
- QuicConfigPeer::SetReceivedMaxBidirectionalStreams(&config_,
- kMaxStreamsForTest);
- config_.SetMaxUnidirectionalStreamsToSend(kMaxStreamsForTest);
-
- config_.SetInitialStreamFlowControlWindowToSend(
- kInitialStreamFlowControlWindowForTest);
- config_.SetInitialMaxStreamDataBytesIncomingBidirectionalToSend(
- kInitialStreamFlowControlWindowForTest);
- config_.SetInitialMaxStreamDataBytesOutgoingBidirectionalToSend(
- kInitialStreamFlowControlWindowForTest);
- config_.SetInitialMaxStreamDataBytesUnidirectionalToSend(
- kInitialStreamFlowControlWindowForTest);
- config_.SetInitialSessionFlowControlWindowToSend(
- kInitialSessionFlowControlWindowForTest);
- if (VersionUsesHttp3(transport_version())) {
- QuicConfigPeer::SetReceivedMaxUnidirectionalStreams(
- &config_, kMaxStreamsForTest + 3);
- } else {
- QuicConfigPeer::SetReceivedMaxUnidirectionalStreams(&config_,
- kMaxStreamsForTest);
- }
-
- ParsedQuicVersionVector supported_versions = SupportedVersions(version());
- connection_ = new StrictMock<MockQuicConnectionWithSendStreamData>(
- &helper_, &alarm_factory_, Perspective::IS_SERVER, supported_versions);
- connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
- connection_->SetEncrypter(
- ENCRYPTION_FORWARD_SECURE,
- std::make_unique<NullEncrypter>(connection_->perspective()));
- session_ = std::make_unique<MockQuicSimpleServerSession>(
- config_, connection_, &owner_, &stream_helper_, &crypto_config_,
- &compressed_certs_cache_, &memory_cache_backend_);
- MockClock clock;
- handshake_message_ = crypto_config_.AddDefaultConfig(
- QuicRandom::GetInstance(), &clock,
- QuicCryptoServerConfig::ConfigOptions());
- session_->Initialize();
-
- if (VersionHasIetfQuicFrames(transport_version())) {
- EXPECT_CALL(*session_, WriteControlFrame(_, _))
- .WillRepeatedly(Invoke(&ClearControlFrameWithTransmissionType));
- }
- session_->OnConfigNegotiated();
- }
-
- QuicStreamId GetNthClientInitiatedBidirectionalId(int n) {
- return GetNthClientInitiatedBidirectionalStreamId(transport_version(), n);
- }
-
- QuicStreamId GetNthServerInitiatedUnidirectionalId(int n) {
- return quic::test::GetNthServerInitiatedUnidirectionalStreamId(
- transport_version(), n);
- }
-
- ParsedQuicVersion version() const { return GetParam(); }
-
- QuicTransportVersion transport_version() const {
- return version().transport_version;
- }
-
- void InjectStopSending(QuicStreamId stream_id,
- QuicRstStreamErrorCode rst_stream_code) {
- // Create and inject a STOP_SENDING frame. In GOOGLE QUIC, receiving a
- // RST_STREAM frame causes a two-way close. For IETF QUIC, RST_STREAM causes
- // a one-way close.
- if (!VersionHasIetfQuicFrames(transport_version())) {
- // Only needed for version 99/IETF QUIC.
- return;
- }
- EXPECT_CALL(owner_, OnStopSendingReceived(_)).Times(1);
- QuicStopSendingFrame stop_sending(kInvalidControlFrameId, stream_id,
- rst_stream_code);
- // Expect the RESET_STREAM that is generated in response to receiving a
- // STOP_SENDING.
- EXPECT_CALL(*connection_, OnStreamReset(stream_id, rst_stream_code));
- session_->OnStopSendingFrame(stop_sending);
- }
-
- StrictMock<MockQuicSessionVisitor> owner_;
- StrictMock<MockQuicCryptoServerStreamHelper> stream_helper_;
- MockQuicConnectionHelper helper_;
- MockAlarmFactory alarm_factory_;
- StrictMock<MockQuicConnectionWithSendStreamData>* connection_;
- QuicConfig config_;
- QuicCryptoServerConfig crypto_config_;
- QuicCompressedCertsCache compressed_certs_cache_;
- QuicMemoryCacheBackend memory_cache_backend_;
- std::unique_ptr<MockQuicSimpleServerSession> session_;
- std::unique_ptr<CryptoHandshakeMessage> handshake_message_;
-};
-
-INSTANTIATE_TEST_SUITE_P(Tests,
- QuicSimpleServerSessionTest,
- ::testing::ValuesIn(AllSupportedVersions()),
- ::testing::PrintToStringParamName());
-
-TEST_P(QuicSimpleServerSessionTest, CloseStreamDueToReset) {
- // Send some data open a stream, then reset it.
- QuicStreamFrame data1(GetNthClientInitiatedBidirectionalId(0), false, 0,
- kStreamData);
- session_->OnStreamFrame(data1);
- EXPECT_EQ(1u, QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()));
-
- // Receive a reset (and send a RST in response).
- QuicRstStreamFrame rst1(kInvalidControlFrameId,
- GetNthClientInitiatedBidirectionalId(0),
- QUIC_ERROR_PROCESSING_STREAM, 0);
- EXPECT_CALL(owner_, OnRstStreamReceived(_)).Times(1);
- EXPECT_CALL(*session_, WriteControlFrame(_, _));
-
- if (!VersionHasIetfQuicFrames(transport_version())) {
- // For version 99, this is covered in InjectStopSending()
- EXPECT_CALL(*connection_,
- OnStreamReset(GetNthClientInitiatedBidirectionalId(0),
- QUIC_RST_ACKNOWLEDGEMENT));
- }
- session_->OnRstStream(rst1);
- // Create and inject a STOP_SENDING frame. In GOOGLE QUIC, receiving a
- // RST_STREAM frame causes a two-way close. For IETF QUIC, RST_STREAM causes
- // a one-way close.
- InjectStopSending(GetNthClientInitiatedBidirectionalId(0),
- QUIC_ERROR_PROCESSING_STREAM);
- EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()));
-
- // Send the same two bytes of payload in a new packet.
- session_->OnStreamFrame(data1);
-
- // The stream should not be re-opened.
- EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()));
- EXPECT_TRUE(connection_->connected());
-}
-
-TEST_P(QuicSimpleServerSessionTest, NeverOpenStreamDueToReset) {
- // Send a reset (and expect the peer to send a RST in response).
- QuicRstStreamFrame rst1(kInvalidControlFrameId,
- GetNthClientInitiatedBidirectionalId(0),
- QUIC_ERROR_PROCESSING_STREAM, 0);
- EXPECT_CALL(owner_, OnRstStreamReceived(_)).Times(1);
- if (!VersionHasIetfQuicFrames(transport_version())) {
- EXPECT_CALL(*session_, WriteControlFrame(_, _));
- // For version 99, this is covered in InjectStopSending()
- EXPECT_CALL(*connection_,
- OnStreamReset(GetNthClientInitiatedBidirectionalId(0),
- QUIC_RST_ACKNOWLEDGEMENT));
- }
- session_->OnRstStream(rst1);
- // Create and inject a STOP_SENDING frame. In GOOGLE QUIC, receiving a
- // RST_STREAM frame causes a two-way close. For IETF QUIC, RST_STREAM causes
- // a one-way close.
- InjectStopSending(GetNthClientInitiatedBidirectionalId(0),
- QUIC_ERROR_PROCESSING_STREAM);
-
- EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()));
-
- QuicStreamFrame data1(GetNthClientInitiatedBidirectionalId(0), false, 0,
- kStreamData);
- session_->OnStreamFrame(data1);
-
- // The stream should never be opened, now that the reset is received.
- EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()));
- EXPECT_TRUE(connection_->connected());
-}
-
-TEST_P(QuicSimpleServerSessionTest, AcceptClosedStream) {
- // Send some data to open two streams.
- QuicStreamFrame frame1(GetNthClientInitiatedBidirectionalId(0), false, 0,
- kStreamData);
- QuicStreamFrame frame2(GetNthClientInitiatedBidirectionalId(1), false, 0,
- kStreamData);
- session_->OnStreamFrame(frame1);
- session_->OnStreamFrame(frame2);
- EXPECT_EQ(2u, QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()));
-
- // Send a reset (and expect the peer to send a RST in response).
- QuicRstStreamFrame rst(kInvalidControlFrameId,
- GetNthClientInitiatedBidirectionalId(0),
- QUIC_ERROR_PROCESSING_STREAM, 0);
- EXPECT_CALL(owner_, OnRstStreamReceived(_)).Times(1);
- if (!VersionHasIetfQuicFrames(transport_version())) {
- EXPECT_CALL(*session_, WriteControlFrame(_, _));
- // For version 99, this is covered in InjectStopSending()
- EXPECT_CALL(*connection_,
- OnStreamReset(GetNthClientInitiatedBidirectionalId(0),
- QUIC_RST_ACKNOWLEDGEMENT));
- }
- session_->OnRstStream(rst);
- // Create and inject a STOP_SENDING frame. In GOOGLE QUIC, receiving a
- // RST_STREAM frame causes a two-way close. For IETF QUIC, RST_STREAM causes
- // a one-way close.
- InjectStopSending(GetNthClientInitiatedBidirectionalId(0),
- QUIC_ERROR_PROCESSING_STREAM);
-
- // If we were tracking, we'd probably want to reject this because it's data
- // past the reset point of stream 3. As it's a closed stream we just drop the
- // data on the floor, but accept the packet because it has data for stream 5.
- QuicStreamFrame frame3(GetNthClientInitiatedBidirectionalId(0), false, 2,
- kStreamData);
- QuicStreamFrame frame4(GetNthClientInitiatedBidirectionalId(1), false, 2,
- kStreamData);
- session_->OnStreamFrame(frame3);
- session_->OnStreamFrame(frame4);
- // The stream should never be opened, now that the reset is received.
- EXPECT_EQ(1u, QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()));
- EXPECT_TRUE(connection_->connected());
-}
-
-TEST_P(QuicSimpleServerSessionTest, CreateIncomingStreamDisconnected) {
- // EXPECT_QUIC_BUG tests are expensive so only run one instance of them.
- if (version() != AllSupportedVersions()[0]) {
- return;
- }
-
- // Tests that incoming stream creation fails when connection is not connected.
- size_t initial_num_open_stream =
- QuicSessionPeer::GetNumOpenDynamicStreams(session_.get());
- QuicConnectionPeer::TearDownLocalConnectionState(connection_);
- EXPECT_QUIC_BUG(QuicSimpleServerSessionPeer::CreateIncomingStream(
- session_.get(), GetNthClientInitiatedBidirectionalId(0)),
- "ShouldCreateIncomingStream called when disconnected");
- EXPECT_EQ(initial_num_open_stream,
- QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()));
-}
-
-TEST_P(QuicSimpleServerSessionTest, CreateIncomingStream) {
- QuicSpdyStream* stream = QuicSimpleServerSessionPeer::CreateIncomingStream(
- session_.get(), GetNthClientInitiatedBidirectionalId(0));
- EXPECT_NE(nullptr, stream);
- EXPECT_EQ(GetNthClientInitiatedBidirectionalId(0), stream->id());
-}
-
-TEST_P(QuicSimpleServerSessionTest, CreateOutgoingDynamicStreamDisconnected) {
- // EXPECT_QUIC_BUG tests are expensive so only run one instance of them.
- if (version() != AllSupportedVersions()[0]) {
- return;
- }
-
- // Tests that outgoing stream creation fails when connection is not connected.
- size_t initial_num_open_stream =
- QuicSessionPeer::GetNumOpenDynamicStreams(session_.get());
- QuicConnectionPeer::TearDownLocalConnectionState(connection_);
- EXPECT_QUIC_BUG(
- QuicSimpleServerSessionPeer::CreateOutgoingUnidirectionalStream(
- session_.get()),
- "ShouldCreateOutgoingUnidirectionalStream called when disconnected");
-
- EXPECT_EQ(initial_num_open_stream,
- QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()));
-}
-
-TEST_P(QuicSimpleServerSessionTest, CreateOutgoingDynamicStreamUnencrypted) {
- // EXPECT_QUIC_BUG tests are expensive so only run one instance of them.
- if (version() != AllSupportedVersions()[0]) {
- return;
- }
-
- // Tests that outgoing stream creation fails when encryption has not yet been
- // established.
- size_t initial_num_open_stream =
- QuicSessionPeer::GetNumOpenDynamicStreams(session_.get());
- EXPECT_QUIC_BUG(
- QuicSimpleServerSessionPeer::CreateOutgoingUnidirectionalStream(
- session_.get()),
- "Encryption not established so no outgoing stream created.");
- EXPECT_EQ(initial_num_open_stream,
- QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()));
-}
-
-TEST_P(QuicSimpleServerSessionTest, CreateOutgoingDynamicStreamUptoLimit) {
- // Tests that outgoing stream creation should not be affected by existing
- // incoming stream and vice-versa. But when reaching the limit of max outgoing
- // stream allowed, creation should fail.
-
- // Receive some data to initiate a incoming stream which should not effect
- // creating outgoing streams.
- QuicStreamFrame data1(GetNthClientInitiatedBidirectionalId(0), false, 0,
- kStreamData);
- session_->OnStreamFrame(data1);
- EXPECT_EQ(1u, QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()));
- EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()) -
- /*incoming=*/1);
-
- if (!VersionUsesHttp3(transport_version())) {
- session_->UnregisterStreamPriority(
- QuicUtils::GetHeadersStreamId(transport_version()),
- /*is_static=*/true);
- }
- // Assume encryption already established.
- QuicSimpleServerSessionPeer::SetCryptoStream(session_.get(), nullptr);
- QuicCryptoServerStreamBase* crypto_stream =
- CreateMockCryptoServerStream(&crypto_config_, &compressed_certs_cache_,
- session_.get(), &stream_helper_);
- QuicSimpleServerSessionPeer::SetCryptoStream(session_.get(), crypto_stream);
- if (!VersionUsesHttp3(transport_version())) {
- session_->RegisterStreamPriority(
- QuicUtils::GetHeadersStreamId(transport_version()),
- /*is_static=*/true,
- spdy::SpdyStreamPrecedence(QuicStream::kDefaultPriority));
- }
-
- // Create push streams till reaching the upper limit of allowed open streams.
- for (size_t i = 0; i < kMaxStreamsForTest; ++i) {
- QuicSpdyStream* created_stream =
- QuicSimpleServerSessionPeer::CreateOutgoingUnidirectionalStream(
- session_.get());
- if (VersionUsesHttp3(transport_version())) {
- EXPECT_EQ(GetNthServerInitiatedUnidirectionalId(i + 3),
- created_stream->id());
- } else {
- EXPECT_EQ(GetNthServerInitiatedUnidirectionalId(i), created_stream->id());
- }
- EXPECT_EQ(i + 1, QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()) -
- /*incoming=*/1);
- }
-
- // Continuing creating push stream would fail.
- EXPECT_EQ(nullptr,
- QuicSimpleServerSessionPeer::CreateOutgoingUnidirectionalStream(
- session_.get()));
- EXPECT_EQ(kMaxStreamsForTest,
- QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()) -
- /*incoming=*/1);
-
- // Create peer initiated stream should have no problem.
- QuicStreamFrame data2(GetNthClientInitiatedBidirectionalId(1), false, 0,
- kStreamData);
- session_->OnStreamFrame(data2);
- EXPECT_EQ(2u, QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()) -
- /*outcoming=*/kMaxStreamsForTest);
-}
-
-TEST_P(QuicSimpleServerSessionTest, OnStreamFrameWithEvenStreamId) {
- QuicStreamFrame frame(GetNthServerInitiatedUnidirectionalId(0), false, 0,
- kStreamData);
- EXPECT_CALL(*connection_,
- CloseConnection(QUIC_INVALID_STREAM_ID,
- "Client sent data on server push stream", _));
- session_->OnStreamFrame(frame);
-}
-
-// Tests that calling GetOrCreateStream() on an outgoing stream not promised yet
-// should result close connection.
-TEST_P(QuicSimpleServerSessionTest, GetEvenIncomingError) {
- const size_t initial_num_open_stream =
- QuicSessionPeer::GetNumOpenDynamicStreams(session_.get());
- const QuicErrorCode expected_error = VersionUsesHttp3(transport_version())
- ? QUIC_HTTP_STREAM_WRONG_DIRECTION
- : QUIC_INVALID_STREAM_ID;
- EXPECT_CALL(*connection_, CloseConnection(expected_error,
- "Data for nonexistent stream", _));
- EXPECT_EQ(nullptr,
- QuicSessionPeer::GetOrCreateStream(
- session_.get(), GetNthServerInitiatedUnidirectionalId(3)));
- EXPECT_EQ(initial_num_open_stream,
- QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()));
-}
-
-} // namespace
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/tools/quic_simple_server_stream.cc b/chromium/net/third_party/quiche/src/quic/tools/quic_simple_server_stream.cc
deleted file mode 100644
index 0ea0e50ae6a..00000000000
--- a/chromium/net/third_party/quiche/src/quic/tools/quic_simple_server_stream.cc
+++ /dev/null
@@ -1,429 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/tools/quic_simple_server_stream.h"
-
-#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 "quic/core/http/quic_spdy_stream.h"
-#include "quic/core/http/spdy_utils.h"
-#include "quic/core/http/web_transport_http3.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/tools/quic_simple_server_session.h"
-#include "spdy/core/spdy_protocol.h"
-
-using spdy::Http2HeaderBlock;
-
-namespace quic {
-
-QuicSimpleServerStream::QuicSimpleServerStream(
- QuicStreamId id,
- QuicSpdySession* session,
- StreamType type,
- QuicSimpleServerBackend* quic_simple_server_backend)
- : QuicSpdyServerStreamBase(id, session, type),
- content_length_(-1),
- generate_bytes_length_(0),
- quic_simple_server_backend_(quic_simple_server_backend) {
- QUICHE_DCHECK(quic_simple_server_backend_);
-}
-
-QuicSimpleServerStream::QuicSimpleServerStream(
- PendingStream* pending, QuicSpdySession* session,
- QuicSimpleServerBackend* quic_simple_server_backend)
- : QuicSpdyServerStreamBase(pending, session),
- content_length_(-1),
- generate_bytes_length_(0),
- quic_simple_server_backend_(quic_simple_server_backend) {
- QUICHE_DCHECK(quic_simple_server_backend_);
-}
-
-QuicSimpleServerStream::~QuicSimpleServerStream() {
- quic_simple_server_backend_->CloseBackendResponseStream(this);
-}
-
-void QuicSimpleServerStream::OnInitialHeadersComplete(
- bool fin,
- size_t frame_len,
- const QuicHeaderList& header_list) {
- QuicSpdyStream::OnInitialHeadersComplete(fin, frame_len, header_list);
- // QuicSpdyStream::OnInitialHeadersComplete() may have already sent error
- // response.
- if (!response_sent_ &&
- !SpdyUtils::CopyAndValidateHeaders(header_list, &content_length_,
- &request_headers_)) {
- QUIC_DVLOG(1) << "Invalid headers";
- 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();
- }
- }
-}
-
-void QuicSimpleServerStream::OnTrailingHeadersComplete(
- bool /*fin*/,
- size_t /*frame_len*/,
- const QuicHeaderList& /*header_list*/) {
- QUIC_BUG(quic_bug_10962_1) << "Server does not support receiving Trailers.";
- SendErrorResponse();
-}
-
-void QuicSimpleServerStream::OnBodyAvailable() {
- while (HasBytesToRead()) {
- struct iovec iov;
- if (GetReadableRegions(&iov, 1) == 0) {
- // No more data to read.
- break;
- }
- QUIC_DVLOG(1) << "Stream " << id() << " processed " << iov.iov_len
- << " bytes.";
- body_.append(static_cast<char*>(iov.iov_base), iov.iov_len);
-
- if (content_length_ >= 0 &&
- body_.size() > static_cast<uint64_t>(content_length_)) {
- QUIC_DVLOG(1) << "Body size (" << body_.size() << ") > content length ("
- << content_length_ << ").";
- SendErrorResponse();
- return;
- }
- MarkConsumed(iov.iov_len);
- }
- if (!sequencer()->IsClosed()) {
- sequencer()->SetUnblocked();
- return;
- }
-
- // If the sequencer is closed, then all the body, including the fin, has been
- // consumed.
- OnFinRead();
-
- if (write_side_closed() || fin_buffered()) {
- return;
- }
-
- SendResponse();
-}
-
-void QuicSimpleServerStream::PushResponse(
- Http2HeaderBlock push_request_headers) {
- if (QuicUtils::IsClientInitiatedStreamId(session()->transport_version(),
- id())) {
- QUIC_BUG(quic_bug_10962_2)
- << "Client initiated stream shouldn't be used as promised stream.";
- return;
- }
- // Change the stream state to emulate a client request.
- request_headers_ = std::move(push_request_headers);
- content_length_ = 0;
- QUIC_DVLOG(1) << "Stream " << id()
- << " ready to receive server push response.";
- QUICHE_DCHECK(reading_stopped());
-
- // Directly send response based on the emulated request_headers_.
- SendResponse();
-}
-
-void QuicSimpleServerStream::SendResponse() {
- if (request_headers_.empty()) {
- QUIC_DVLOG(1) << "Request headers empty.";
- SendErrorResponse();
- return;
- }
-
- if (content_length_ > 0 &&
- static_cast<uint64_t>(content_length_) != body_.size()) {
- QUIC_DVLOG(1) << "Content length (" << content_length_ << ") != body size ("
- << body_.size() << ").";
- SendErrorResponse();
- return;
- }
-
- if (!request_headers_.contains(":authority")) {
- QUIC_DVLOG(1) << "Request headers do not contain :authority.";
- SendErrorResponse();
- return;
- }
-
- 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;
- }
- }
-
- if (quic_simple_server_backend_ == nullptr) {
- QUIC_DVLOG(1) << "Backend is missing.";
- 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;
- }
-
- // Fetch the response from the backend interface and wait for callback once
- // response is ready
- quic_simple_server_backend_->FetchResponseFromBackend(request_headers_, body_,
- this);
-}
-
-QuicConnectionId QuicSimpleServerStream::connection_id() const {
- return spdy_session()->connection_id();
-}
-
-QuicStreamId QuicSimpleServerStream::stream_id() const {
- return id();
-}
-
-std::string QuicSimpleServerStream::peer_host() const {
- return spdy_session()->peer_address().host().ToString();
-}
-
-void QuicSimpleServerStream::OnResponseBackendComplete(
- const QuicBackendResponse* response) {
- if (response == nullptr) {
- QUIC_DVLOG(1) << "Response not found in cache.";
- SendNotFoundResponse();
- return;
- }
-
- // Send Early Hints first.
- for (const auto& headers : response->early_hints()) {
- QUIC_DVLOG(1) << "Stream " << id() << " sending an Early Hints response: "
- << headers.DebugString();
- WriteHeaders(headers.Clone(), false, nullptr);
- }
-
- if (response->response_type() == QuicBackendResponse::CLOSE_CONNECTION) {
- QUIC_DVLOG(1) << "Special response: closing connection.";
- OnUnrecoverableError(QUIC_NO_ERROR, "Toy server forcing close");
- return;
- }
-
- if (response->response_type() == QuicBackendResponse::IGNORE_REQUEST) {
- QUIC_DVLOG(1) << "Special response: ignoring request.";
- return;
- }
-
- if (response->response_type() == QuicBackendResponse::BACKEND_ERR_RESPONSE) {
- QUIC_DVLOG(1) << "Quic Proxy: Backend connection error.";
- /*502 Bad Gateway
- The server was acting as a gateway or proxy and received an
- invalid response from the upstream server.*/
- SendErrorResponse(502);
- return;
- }
-
- // Examing response status, if it was not pure integer as typical h2
- // response status, send error response. Notice that
- // QuicHttpResponseCache push urls are strictly authority + path only,
- // scheme is not included (see |QuicHttpResponseCache::GetKey()|).
- std::string request_url = request_headers_[":authority"].as_string() +
- request_headers_[":path"].as_string();
- int response_code;
- const Http2HeaderBlock& response_headers = response->headers();
- if (!ParseHeaderStatusCode(response_headers, &response_code)) {
- auto status = response_headers.find(":status");
- if (status == response_headers.end()) {
- QUIC_LOG(WARNING)
- << ":status not present in response from cache for request "
- << request_url;
- } else {
- QUIC_LOG(WARNING) << "Illegal (non-integer) response :status from cache: "
- << status->second << " for request " << request_url;
- }
- SendErrorResponse();
- return;
- }
-
- if (QuicUtils::IsServerInitiatedStreamId(session()->transport_version(),
- id())) {
- // A server initiated stream is only used for a server push response,
- // and only 200 and 30X response codes are supported for server push.
- // This behavior mirrors the HTTP/2 implementation.
- bool is_redirection = response_code / 100 == 3;
- if (response_code != 200 && !is_redirection) {
- QUIC_LOG(WARNING) << "Response to server push request " << request_url
- << " result in response code " << response_code;
- Reset(QUIC_STREAM_CANCELLED);
- return;
- }
- }
-
- if (response->response_type() == QuicBackendResponse::INCOMPLETE_RESPONSE) {
- QUIC_DVLOG(1)
- << "Stream " << id()
- << " sending an incomplete response, i.e. no trailer, no fin.";
- SendIncompleteResponse(response->headers().Clone(), response->body());
- return;
- }
-
- if (response->response_type() == QuicBackendResponse::GENERATE_BYTES) {
- QUIC_DVLOG(1) << "Stream " << id() << " sending a generate bytes response.";
- std::string path = request_headers_[":path"].as_string().substr(1);
- if (!absl::SimpleAtoi(path, &generate_bytes_length_)) {
- QUIC_LOG(ERROR) << "Path is not a number.";
- SendNotFoundResponse();
- return;
- }
- Http2HeaderBlock headers = response->headers().Clone();
- headers["content-length"] = absl::StrCat(generate_bytes_length_);
-
- WriteHeaders(std::move(headers), false, nullptr);
- QUICHE_DCHECK(!response_sent_);
- response_sent_ = true;
-
- WriteGeneratedBytes();
-
- return;
- }
-
- QUIC_DVLOG(1) << "Stream " << id() << " sending response.";
- SendHeadersAndBodyAndTrailers(response->headers().Clone(), response->body(),
- response->trailers().Clone());
-}
-
-void QuicSimpleServerStream::OnCanWrite() {
- QuicSpdyStream::OnCanWrite();
- WriteGeneratedBytes();
-}
-
-void QuicSimpleServerStream::WriteGeneratedBytes() {
- static size_t kChunkSize = 1024;
- while (!HasBufferedData() && generate_bytes_length_ > 0) {
- size_t len = std::min<size_t>(kChunkSize, generate_bytes_length_);
- std::string data(len, 'a');
- generate_bytes_length_ -= len;
- bool fin = generate_bytes_length_ == 0;
- WriteOrBufferBody(data, fin);
- }
-}
-
-void QuicSimpleServerStream::SendNotFoundResponse() {
- QUIC_DVLOG(1) << "Stream " << id() << " sending not found response.";
- Http2HeaderBlock headers;
- headers[":status"] = "404";
- headers["content-length"] = absl::StrCat(strlen(kNotFoundResponseBody));
- SendHeadersAndBody(std::move(headers), kNotFoundResponseBody);
-}
-
-void QuicSimpleServerStream::SendErrorResponse() {
- SendErrorResponse(0);
-}
-
-void QuicSimpleServerStream::SendErrorResponse(int resp_code) {
- QUIC_DVLOG(1) << "Stream " << id() << " sending error response.";
- if (!reading_stopped()) {
- StopReading();
- }
- Http2HeaderBlock headers;
- if (resp_code <= 0) {
- headers[":status"] = "500";
- } else {
- headers[":status"] = absl::StrCat(resp_code);
- }
- headers["content-length"] = absl::StrCat(strlen(kErrorResponseBody));
- SendHeadersAndBody(std::move(headers), kErrorResponseBody);
-}
-
-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;
-
- QUIC_DLOG(INFO) << "Stream " << id()
- << " writing body (fin = false) with size: " << body.size();
- if (!body.empty()) {
- WriteOrBufferBody(body, /*fin=*/false);
- }
-}
-
-void QuicSimpleServerStream::SendHeadersAndBody(
- Http2HeaderBlock response_headers,
- absl::string_view body) {
- SendHeadersAndBodyAndTrailers(std::move(response_headers), body,
- Http2HeaderBlock());
-}
-
-void QuicSimpleServerStream::SendHeadersAndBodyAndTrailers(
- 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;
- }
-
- // Send the body, with a FIN if there's no trailers to send.
- send_fin = response_trailers.empty();
- QUIC_DLOG(INFO) << "Stream " << id() << " writing body (fin = " << send_fin
- << ") with size: " << body.size();
- if (!body.empty() || send_fin) {
- WriteOrBufferBody(body, send_fin);
- }
- if (send_fin) {
- // Nothing else to send.
- return;
- }
-
- // Send the trailers. A FIN is always sent with trailers.
- QUIC_DLOG(INFO) << "Stream " << id() << " writing trailers (fin = true): "
- << response_trailers.DebugString();
- WriteTrailers(std::move(response_trailers), nullptr);
-}
-
-void QuicSimpleServerStream::OnInvalidHeaders() {
- QUIC_DVLOG(1) << "Invalid headers";
- SendErrorResponse(400);
-}
-
-const char* const QuicSimpleServerStream::kErrorResponseBody = "bad";
-const char* const QuicSimpleServerStream::kNotFoundResponseBody =
- "file not found";
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/tools/quic_simple_server_stream.h b/chromium/net/third_party/quiche/src/quic/tools/quic_simple_server_stream.h
deleted file mode 100644
index cd04bd70e7e..00000000000
--- a/chromium/net/third_party/quiche/src/quic/tools/quic_simple_server_stream.h
+++ /dev/null
@@ -1,109 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TOOLS_QUIC_SIMPLE_SERVER_STREAM_H_
-#define QUICHE_QUIC_TOOLS_QUIC_SIMPLE_SERVER_STREAM_H_
-
-#include "absl/strings/string_view.h"
-#include "quic/core/http/quic_spdy_server_stream_base.h"
-#include "quic/core/quic_packets.h"
-#include "quic/tools/quic_backend_response.h"
-#include "quic/tools/quic_simple_server_backend.h"
-#include "spdy/core/spdy_framer.h"
-
-namespace quic {
-
-// All this does right now is aggregate data, and on fin, send an HTTP
-// response.
-class QuicSimpleServerStream : public QuicSpdyServerStreamBase,
- public QuicSimpleServerBackend::RequestHandler {
- public:
- QuicSimpleServerStream(QuicStreamId id,
- QuicSpdySession* session,
- StreamType type,
- QuicSimpleServerBackend* quic_simple_server_backend);
- QuicSimpleServerStream(PendingStream* pending,
- QuicSpdySession* session,
- QuicSimpleServerBackend* quic_simple_server_backend);
- QuicSimpleServerStream(const QuicSimpleServerStream&) = delete;
- QuicSimpleServerStream& operator=(const QuicSimpleServerStream&) = delete;
- ~QuicSimpleServerStream() override;
-
- // QuicSpdyStream
- void OnInitialHeadersComplete(bool fin,
- size_t frame_len,
- const QuicHeaderList& header_list) override;
- void OnTrailingHeadersComplete(bool fin,
- size_t frame_len,
- const QuicHeaderList& header_list) override;
- void OnCanWrite() override;
-
- // QuicStream implementation called by the sequencer when there is
- // data (or a FIN) to be read.
- void OnBodyAvailable() override;
-
- void OnInvalidHeaders() override;
-
- // Make this stream start from as if it just finished parsing an incoming
- // request whose headers are equivalent to |push_request_headers|.
- // Doing so will trigger this toy stream to fetch response and send it back.
- virtual void PushResponse(spdy::Http2HeaderBlock push_request_headers);
-
- // The response body of error responses.
- static const char* const kErrorResponseBody;
- static const char* const kNotFoundResponseBody;
-
- // Implements QuicSimpleServerBackend::RequestHandler callbacks
- QuicConnectionId connection_id() const override;
- QuicStreamId stream_id() const override;
- std::string peer_host() const override;
- void OnResponseBackendComplete(const QuicBackendResponse* response) override;
-
- protected:
- // Sends a basic 200 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
- // for the body.
- virtual void SendErrorResponse();
- virtual void SendErrorResponse(int resp_code);
-
- // Sends a basic 404 response using SendHeaders for the headers and WriteData
- // 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);
-
- void SendHeadersAndBody(spdy::Http2HeaderBlock response_headers,
- absl::string_view body);
- void SendHeadersAndBodyAndTrailers(spdy::Http2HeaderBlock response_headers,
- absl::string_view body,
- spdy::Http2HeaderBlock response_trailers);
-
- spdy::Http2HeaderBlock* request_headers() { return &request_headers_; }
-
- const std::string& body() { return body_; }
-
- // Writes the body bytes for the GENERATE_BYTES response type.
- void WriteGeneratedBytes();
-
- // The parsed headers received from the client.
- spdy::Http2HeaderBlock request_headers_;
- int64_t content_length_;
- std::string body_;
-
- private:
- uint64_t generate_bytes_length_;
- // Whether response headers have already been sent.
- bool response_sent_ = false;
-
- QuicSimpleServerBackend* quic_simple_server_backend_; // Not owned.
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_TOOLS_QUIC_SIMPLE_SERVER_STREAM_H_
diff --git a/chromium/net/third_party/quiche/src/quic/tools/quic_simple_server_stream_test.cc b/chromium/net/third_party/quiche/src/quic/tools/quic_simple_server_stream_test.cc
deleted file mode 100644
index b75246f0ea5..00000000000
--- a/chromium/net/third_party/quiche/src/quic/tools/quic_simple_server_stream_test.cc
+++ /dev/null
@@ -1,789 +0,0 @@
-// Copyright (c) 2013 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 "quic/tools/quic_simple_server_stream.h"
-
-#include <list>
-#include <memory>
-#include <utility>
-
-#include "absl/base/macros.h"
-#include "absl/memory/memory.h"
-#include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
-#include "quic/core/crypto/null_encrypter.h"
-#include "quic/core/http/http_encoder.h"
-#include "quic/core/http/spdy_utils.h"
-#include "quic/core/quic_error_codes.h"
-#include "quic/core/quic_simple_buffer_allocator.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_expect_bug.h"
-#include "quic/platform/api/quic_socket_address.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/crypto_test_utils.h"
-#include "quic/test_tools/quic_config_peer.h"
-#include "quic/test_tools/quic_connection_peer.h"
-#include "quic/test_tools/quic_session_peer.h"
-#include "quic/test_tools/quic_spdy_session_peer.h"
-#include "quic/test_tools/quic_stream_peer.h"
-#include "quic/test_tools/quic_test_utils.h"
-#include "quic/tools/quic_backend_response.h"
-#include "quic/tools/quic_memory_cache_backend.h"
-#include "quic/tools/quic_simple_server_session.h"
-
-using testing::_;
-using testing::AnyNumber;
-using testing::InSequence;
-using testing::Invoke;
-using testing::StrictMock;
-
-namespace quic {
-namespace test {
-
-const size_t kFakeFrameLen = 60;
-const size_t kErrorLength = strlen(QuicSimpleServerStream::kErrorResponseBody);
-const size_t kDataFrameHeaderLength = 2;
-
-class TestStream : public QuicSimpleServerStream {
- public:
- TestStream(QuicStreamId stream_id, QuicSpdySession* session, StreamType type,
- QuicSimpleServerBackend* quic_simple_server_backend)
- : QuicSimpleServerStream(stream_id, session, type,
- quic_simple_server_backend) {}
-
- ~TestStream() override = default;
-
- MOCK_METHOD(void, WriteHeadersMock, (bool fin), ());
- MOCK_METHOD(void, WriteEarlyHintsHeadersMock, (bool fin), ());
-
- size_t WriteHeaders(spdy::Http2HeaderBlock header_block, bool fin,
- QuicReferenceCountedPointer<QuicAckListenerInterface>
- /*ack_listener*/) override {
- if (header_block[":status"] == "103") {
- WriteEarlyHintsHeadersMock(fin);
- } else {
- WriteHeadersMock(fin);
- }
- return 0;
- }
-
- // Expose protected QuicSimpleServerStream methods.
- void DoSendResponse() { SendResponse(); }
- void DoSendErrorResponse() { QuicSimpleServerStream::SendErrorResponse(); }
-
- spdy::Http2HeaderBlock* mutable_headers() { return &request_headers_; }
- void set_body(std::string body) { body_ = std::move(body); }
- const std::string& body() const { return body_; }
- int content_length() const { return content_length_; }
- bool send_response_was_called() const { return send_response_was_called_; }
- bool send_error_response_was_called() const {
- return send_error_response_was_called_;
- }
-
- absl::string_view GetHeader(absl::string_view key) const {
- auto it = request_headers_.find(key);
- QUICHE_DCHECK(it != request_headers_.end());
- return it->second;
- }
-
- protected:
- void SendResponse() override {
- send_response_was_called_ = true;
- QuicSimpleServerStream::SendResponse();
- }
-
- void SendErrorResponse(int resp_code) override {
- send_error_response_was_called_ = true;
- QuicSimpleServerStream::SendErrorResponse(resp_code);
- }
-
- private:
- bool send_response_was_called_ = false;
- bool send_error_response_was_called_ = false;
-};
-
-namespace {
-
-class MockQuicSimpleServerSession : public QuicSimpleServerSession {
- public:
- const size_t kMaxStreamsForTest = 100;
-
- MockQuicSimpleServerSession(
- QuicConnection* connection, MockQuicSessionVisitor* owner,
- MockQuicCryptoServerStreamHelper* helper,
- QuicCryptoServerConfig* crypto_config,
- QuicCompressedCertsCache* compressed_certs_cache,
- QuicSimpleServerBackend* quic_simple_server_backend)
- : QuicSimpleServerSession(DefaultQuicConfig(), CurrentSupportedVersions(),
- connection, owner, helper, crypto_config,
- compressed_certs_cache,
- quic_simple_server_backend) {
- if (VersionHasIetfQuicFrames(connection->transport_version())) {
- QuicSessionPeer::SetMaxOpenIncomingUnidirectionalStreams(
- this, kMaxStreamsForTest);
- QuicSessionPeer::SetMaxOpenIncomingBidirectionalStreams(
- this, kMaxStreamsForTest);
- } else {
- QuicSessionPeer::SetMaxOpenIncomingStreams(this, kMaxStreamsForTest);
- QuicSessionPeer::SetMaxOpenOutgoingStreams(this, kMaxStreamsForTest);
- }
- ON_CALL(*this, WritevData(_, _, _, _, _, _))
- .WillByDefault(Invoke(this, &MockQuicSimpleServerSession::ConsumeData));
- }
-
- MockQuicSimpleServerSession(const MockQuicSimpleServerSession&) = delete;
- MockQuicSimpleServerSession& operator=(const MockQuicSimpleServerSession&) =
- delete;
- ~MockQuicSimpleServerSession() override = default;
-
- MOCK_METHOD(void, OnConnectionClosed,
- (const QuicConnectionCloseFrame& frame,
- ConnectionCloseSource source),
- (override));
- MOCK_METHOD(QuicSpdyStream*, CreateIncomingStream, (QuicStreamId id),
- (override));
- MOCK_METHOD(QuicConsumedData, WritevData,
- (QuicStreamId id, size_t write_length, QuicStreamOffset offset,
- StreamSendingState state, TransmissionType type,
- EncryptionLevel level),
- (override));
- MOCK_METHOD(void, OnStreamHeaderList,
- (QuicStreamId stream_id, bool fin, size_t frame_len,
- const QuicHeaderList& header_list),
- (override));
- MOCK_METHOD(void, OnStreamHeadersPriority,
- (QuicStreamId stream_id,
- const spdy::SpdyStreamPrecedence& precedence),
- (override));
- MOCK_METHOD(void, MaybeSendRstStreamFrame,
- (QuicStreamId stream_id, QuicResetStreamError error,
- QuicStreamOffset bytes_written),
- (override));
- MOCK_METHOD(void, MaybeSendStopSendingFrame,
- (QuicStreamId stream_id, QuicResetStreamError error), (override));
-
- using QuicSession::ActivateStream;
-
- QuicConsumedData ConsumeData(QuicStreamId id, size_t write_length,
- QuicStreamOffset offset,
- StreamSendingState state,
- TransmissionType /*type*/,
- absl::optional<EncryptionLevel> /*level*/) {
- if (write_length > 0) {
- auto buf = std::make_unique<char[]>(write_length);
- QuicStream* stream = GetOrCreateStream(id);
- QUICHE_DCHECK(stream);
- QuicDataWriter writer(write_length, buf.get(), quiche::HOST_BYTE_ORDER);
- stream->WriteStreamData(offset, write_length, &writer);
- } else {
- QUICHE_DCHECK(state != NO_FIN);
- }
- return QuicConsumedData(write_length, state != NO_FIN);
- }
-
- spdy::Http2HeaderBlock original_request_headers_;
-};
-
-class QuicSimpleServerStreamTest : public QuicTestWithParam<ParsedQuicVersion> {
- public:
- QuicSimpleServerStreamTest()
- : connection_(new StrictMock<MockQuicConnection>(
- &helper_, &alarm_factory_, Perspective::IS_SERVER,
- SupportedVersions(GetParam()))),
- crypto_config_(new QuicCryptoServerConfig(
- QuicCryptoServerConfig::TESTING, QuicRandom::GetInstance(),
- crypto_test_utils::ProofSourceForTesting(),
- KeyExchangeSource::Default())),
- compressed_certs_cache_(
- QuicCompressedCertsCache::kQuicCompressedCertsCacheSize),
- session_(connection_, &session_owner_, &session_helper_,
- crypto_config_.get(), &compressed_certs_cache_,
- &memory_cache_backend_),
- quic_response_(new QuicBackendResponse),
- body_("hello world") {
- connection_->set_visitor(&session_);
- header_list_.OnHeaderBlockStart();
- header_list_.OnHeader(":authority", "www.google.com");
- header_list_.OnHeader(":path", "/");
- header_list_.OnHeader(":method", "POST");
- header_list_.OnHeader(":scheme", "https");
- header_list_.OnHeader("content-length", "11");
-
- header_list_.OnHeaderBlockEnd(128, 128);
-
- // New streams rely on having the peer's flow control receive window
- // negotiated in the config.
- session_.config()->SetInitialStreamFlowControlWindowToSend(
- kInitialStreamFlowControlWindowForTest);
- session_.config()->SetInitialSessionFlowControlWindowToSend(
- kInitialSessionFlowControlWindowForTest);
- session_.Initialize();
- connection_->SetEncrypter(
- quic::ENCRYPTION_FORWARD_SECURE,
- std::make_unique<quic::NullEncrypter>(connection_->perspective()));
- if (connection_->version().SupportsAntiAmplificationLimit()) {
- QuicConnectionPeer::SetAddressValidated(connection_);
- }
- stream_ = new StrictMock<TestStream>(
- GetNthClientInitiatedBidirectionalStreamId(
- connection_->transport_version(), 0),
- &session_, BIDIRECTIONAL, &memory_cache_backend_);
- // Register stream_ in dynamic_stream_map_ and pass ownership to session_.
- session_.ActivateStream(absl::WrapUnique(stream_));
- QuicConfigPeer::SetReceivedInitialSessionFlowControlWindow(
- session_.config(), kMinimumFlowControlSendWindow);
- QuicConfigPeer::SetReceivedInitialMaxStreamDataBytesUnidirectional(
- session_.config(), kMinimumFlowControlSendWindow);
- QuicConfigPeer::SetReceivedInitialMaxStreamDataBytesIncomingBidirectional(
- session_.config(), kMinimumFlowControlSendWindow);
- QuicConfigPeer::SetReceivedInitialMaxStreamDataBytesOutgoingBidirectional(
- session_.config(), kMinimumFlowControlSendWindow);
- QuicConfigPeer::SetReceivedMaxUnidirectionalStreams(session_.config(), 10);
- session_.OnConfigNegotiated();
- connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
- }
-
- const std::string& StreamBody() { return stream_->body(); }
-
- std::string StreamHeadersValue(const std::string& key) {
- return (*stream_->mutable_headers())[key].as_string();
- }
-
- bool UsesHttp3() const {
- return VersionUsesHttp3(connection_->transport_version());
- }
-
- spdy::Http2HeaderBlock response_headers_;
- MockQuicConnectionHelper helper_;
- MockAlarmFactory alarm_factory_;
- StrictMock<MockQuicConnection>* connection_;
- StrictMock<MockQuicSessionVisitor> session_owner_;
- StrictMock<MockQuicCryptoServerStreamHelper> session_helper_;
- std::unique_ptr<QuicCryptoServerConfig> crypto_config_;
- QuicCompressedCertsCache compressed_certs_cache_;
- QuicMemoryCacheBackend memory_cache_backend_;
- StrictMock<MockQuicSimpleServerSession> session_;
- StrictMock<TestStream>* stream_; // Owned by session_.
- std::unique_ptr<QuicBackendResponse> quic_response_;
- std::string body_;
- QuicHeaderList header_list_;
-};
-
-INSTANTIATE_TEST_SUITE_P(Tests, QuicSimpleServerStreamTest,
- ::testing::ValuesIn(AllSupportedVersions()),
- ::testing::PrintToStringParamName());
-
-TEST_P(QuicSimpleServerStreamTest, TestFraming) {
- EXPECT_CALL(session_, WritevData(_, _, _, _, _, _))
- .WillRepeatedly(
- Invoke(&session_, &MockQuicSimpleServerSession::ConsumeData));
- stream_->OnStreamHeaderList(false, kFakeFrameLen, header_list_);
- QuicBuffer header = HttpEncoder::SerializeDataFrameHeader(
- body_.length(), SimpleBufferAllocator::Get());
- std::string data =
- UsesHttp3() ? absl::StrCat(header.AsStringView(), body_) : body_;
- stream_->OnStreamFrame(
- QuicStreamFrame(stream_->id(), /*fin=*/false, /*offset=*/0, data));
- EXPECT_EQ("11", StreamHeadersValue("content-length"));
- EXPECT_EQ("/", StreamHeadersValue(":path"));
- EXPECT_EQ("POST", StreamHeadersValue(":method"));
- EXPECT_EQ(body_, StreamBody());
-}
-
-TEST_P(QuicSimpleServerStreamTest, TestFramingOnePacket) {
- EXPECT_CALL(session_, WritevData(_, _, _, _, _, _))
- .WillRepeatedly(
- Invoke(&session_, &MockQuicSimpleServerSession::ConsumeData));
-
- stream_->OnStreamHeaderList(false, kFakeFrameLen, header_list_);
- QuicBuffer header = HttpEncoder::SerializeDataFrameHeader(
- body_.length(), SimpleBufferAllocator::Get());
- std::string data =
- UsesHttp3() ? absl::StrCat(header.AsStringView(), body_) : body_;
- stream_->OnStreamFrame(
- QuicStreamFrame(stream_->id(), /*fin=*/false, /*offset=*/0, data));
- EXPECT_EQ("11", StreamHeadersValue("content-length"));
- EXPECT_EQ("/", StreamHeadersValue(":path"));
- EXPECT_EQ("POST", StreamHeadersValue(":method"));
- EXPECT_EQ(body_, StreamBody());
-}
-
-TEST_P(QuicSimpleServerStreamTest, SendQuicRstStreamNoErrorInStopReading) {
- EXPECT_CALL(session_, WritevData(_, _, _, _, _, _))
- .WillRepeatedly(
- Invoke(&session_, &MockQuicSimpleServerSession::ConsumeData));
-
- EXPECT_FALSE(stream_->fin_received());
- EXPECT_FALSE(stream_->rst_received());
-
- QuicStreamPeer::SetFinSent(stream_);
- stream_->CloseWriteSide();
-
- if (session_.version().UsesHttp3()) {
- EXPECT_CALL(session_,
- MaybeSendStopSendingFrame(_, QuicResetStreamError::FromInternal(
- QUIC_STREAM_NO_ERROR)))
- .Times(1);
- } else {
- EXPECT_CALL(
- session_,
- MaybeSendRstStreamFrame(
- _, QuicResetStreamError::FromInternal(QUIC_STREAM_NO_ERROR), _))
- .Times(1);
- }
- stream_->StopReading();
-}
-
-TEST_P(QuicSimpleServerStreamTest, TestFramingExtraData) {
- InSequence seq;
- std::string large_body = "hello world!!!!!!";
-
- // We'll automatically write out an error (headers + body)
- EXPECT_CALL(*stream_, WriteHeadersMock(false));
- if (UsesHttp3()) {
- EXPECT_CALL(session_,
- WritevData(_, kDataFrameHeaderLength, _, NO_FIN, _, _));
- }
- EXPECT_CALL(session_, WritevData(_, kErrorLength, _, FIN, _, _));
-
- stream_->OnStreamHeaderList(false, kFakeFrameLen, header_list_);
- QuicBuffer header = HttpEncoder::SerializeDataFrameHeader(
- body_.length(), SimpleBufferAllocator::Get());
- std::string data =
- UsesHttp3() ? absl::StrCat(header.AsStringView(), body_) : body_;
-
- stream_->OnStreamFrame(
- QuicStreamFrame(stream_->id(), /*fin=*/false, /*offset=*/0, data));
- // Content length is still 11. This will register as an error and we won't
- // accept the bytes.
- header = HttpEncoder::SerializeDataFrameHeader(large_body.length(),
- SimpleBufferAllocator::Get());
- std::string data2 = UsesHttp3()
- ? absl::StrCat(header.AsStringView(), large_body)
- : large_body;
- stream_->OnStreamFrame(
- QuicStreamFrame(stream_->id(), /*fin=*/true, data.size(), data2));
- EXPECT_EQ("11", StreamHeadersValue("content-length"));
- EXPECT_EQ("/", StreamHeadersValue(":path"));
- EXPECT_EQ("POST", StreamHeadersValue(":method"));
-}
-
-TEST_P(QuicSimpleServerStreamTest, SendResponseWithIllegalResponseStatus) {
- // Send an illegal response with response status not supported by HTTP/2.
- spdy::Http2HeaderBlock* request_headers = stream_->mutable_headers();
- (*request_headers)[":path"] = "/bar";
- (*request_headers)[":authority"] = "www.google.com";
- (*request_headers)[":method"] = "GET";
-
- // HTTP/2 only supports integer responsecode, so "200 OK" is illegal.
- response_headers_[":status"] = "200 OK";
- response_headers_["content-length"] = "5";
- std::string body = "Yummm";
- QuicBuffer header = HttpEncoder::SerializeDataFrameHeader(
- body.length(), SimpleBufferAllocator::Get());
-
- memory_cache_backend_.AddResponse("www.google.com", "/bar",
- std::move(response_headers_), body);
-
- QuicStreamPeer::SetFinReceived(stream_);
-
- InSequence s;
- EXPECT_CALL(*stream_, WriteHeadersMock(false));
- if (UsesHttp3()) {
- EXPECT_CALL(session_, WritevData(_, header.size(), _, NO_FIN, _, _));
- }
- EXPECT_CALL(session_, WritevData(_, kErrorLength, _, FIN, _, _));
-
- stream_->DoSendResponse();
- EXPECT_FALSE(QuicStreamPeer::read_side_closed(stream_));
- EXPECT_TRUE(stream_->write_side_closed());
-}
-
-TEST_P(QuicSimpleServerStreamTest, SendResponseWithIllegalResponseStatus2) {
- // Send an illegal response with response status not supported by HTTP/2.
- spdy::Http2HeaderBlock* request_headers = stream_->mutable_headers();
- (*request_headers)[":path"] = "/bar";
- (*request_headers)[":authority"] = "www.google.com";
- (*request_headers)[":method"] = "GET";
-
- // HTTP/2 only supports 3-digit-integer, so "+200" is illegal.
- response_headers_[":status"] = "+200";
- response_headers_["content-length"] = "5";
- std::string body = "Yummm";
-
- QuicBuffer header = HttpEncoder::SerializeDataFrameHeader(
- body.length(), SimpleBufferAllocator::Get());
-
- memory_cache_backend_.AddResponse("www.google.com", "/bar",
- std::move(response_headers_), body);
-
- QuicStreamPeer::SetFinReceived(stream_);
-
- InSequence s;
- EXPECT_CALL(*stream_, WriteHeadersMock(false));
- if (UsesHttp3()) {
- EXPECT_CALL(session_, WritevData(_, header.size(), _, NO_FIN, _, _));
- }
- EXPECT_CALL(session_, WritevData(_, kErrorLength, _, FIN, _, _));
-
- stream_->DoSendResponse();
- EXPECT_FALSE(QuicStreamPeer::read_side_closed(stream_));
- EXPECT_TRUE(stream_->write_side_closed());
-}
-
-TEST_P(QuicSimpleServerStreamTest, SendPushResponseWith404Response) {
- // Create a new promised stream with even id().
- auto promised_stream = new StrictMock<TestStream>(
- GetNthServerInitiatedUnidirectionalStreamId(
- connection_->transport_version(), 3),
- &session_, WRITE_UNIDIRECTIONAL, &memory_cache_backend_);
- session_.ActivateStream(absl::WrapUnique(promised_stream));
-
- // Send a push response with response status 404, which will be regarded as
- // invalid server push response.
- spdy::Http2HeaderBlock* request_headers = promised_stream->mutable_headers();
- (*request_headers)[":path"] = "/bar";
- (*request_headers)[":authority"] = "www.google.com";
- (*request_headers)[":method"] = "GET";
-
- response_headers_[":status"] = "404";
- response_headers_["content-length"] = "8";
- std::string body = "NotFound";
-
- memory_cache_backend_.AddResponse("www.google.com", "/bar",
- std::move(response_headers_), body);
-
- InSequence s;
- if (session_.version().UsesHttp3()) {
- EXPECT_CALL(session_,
- MaybeSendStopSendingFrame(
- promised_stream->id(),
- QuicResetStreamError::FromInternal(QUIC_STREAM_CANCELLED)));
- }
- EXPECT_CALL(
- session_,
- MaybeSendRstStreamFrame(
- promised_stream->id(),
- QuicResetStreamError::FromInternal(QUIC_STREAM_CANCELLED), 0));
-
- promised_stream->DoSendResponse();
-}
-
-TEST_P(QuicSimpleServerStreamTest, SendResponseWithValidHeaders) {
- // Add a request and response with valid headers.
- spdy::Http2HeaderBlock* request_headers = stream_->mutable_headers();
- (*request_headers)[":path"] = "/bar";
- (*request_headers)[":authority"] = "www.google.com";
- (*request_headers)[":method"] = "GET";
-
- response_headers_[":status"] = "200";
- response_headers_["content-length"] = "5";
- std::string body = "Yummm";
-
- QuicBuffer header = HttpEncoder::SerializeDataFrameHeader(
- body.length(), SimpleBufferAllocator::Get());
-
- memory_cache_backend_.AddResponse("www.google.com", "/bar",
- std::move(response_headers_), body);
- QuicStreamPeer::SetFinReceived(stream_);
-
- InSequence s;
- EXPECT_CALL(*stream_, WriteHeadersMock(false));
- if (UsesHttp3()) {
- EXPECT_CALL(session_, WritevData(_, header.size(), _, NO_FIN, _, _));
- }
- EXPECT_CALL(session_, WritevData(_, body.length(), _, FIN, _, _));
-
- stream_->DoSendResponse();
- EXPECT_FALSE(QuicStreamPeer::read_side_closed(stream_));
- EXPECT_TRUE(stream_->write_side_closed());
-}
-
-TEST_P(QuicSimpleServerStreamTest, SendResponseWithEarlyHints) {
- std::string host = "www.google.com";
- std::string request_path = "/foo";
- std::string body = "Yummm";
-
- // Add a request and response with early hints.
- spdy::Http2HeaderBlock* request_headers = stream_->mutable_headers();
- (*request_headers)[":path"] = request_path;
- (*request_headers)[":authority"] = host;
- (*request_headers)[":method"] = "GET";
-
- QuicBuffer header = HttpEncoder::SerializeDataFrameHeader(
- body.length(), SimpleBufferAllocator::Get());
- std::vector<spdy::Http2HeaderBlock> early_hints;
- // Add two Early Hints.
- const size_t kNumEarlyHintsResponses = 2;
- for (size_t i = 0; i < kNumEarlyHintsResponses; ++i) {
- spdy::Http2HeaderBlock hints;
- hints["link"] = "</image.png>; rel=preload; as=image";
- early_hints.push_back(std::move(hints));
- }
-
- response_headers_[":status"] = "200";
- response_headers_["content-length"] = "5";
- memory_cache_backend_.AddResponseWithEarlyHints(
- host, request_path, std::move(response_headers_), body, early_hints);
- QuicStreamPeer::SetFinReceived(stream_);
-
- InSequence s;
- for (size_t i = 0; i < kNumEarlyHintsResponses; ++i) {
- EXPECT_CALL(*stream_, WriteEarlyHintsHeadersMock(false));
- }
- EXPECT_CALL(*stream_, WriteHeadersMock(false));
- if (UsesHttp3()) {
- EXPECT_CALL(session_, WritevData(_, header.size(), _, NO_FIN, _, _));
- }
- EXPECT_CALL(session_, WritevData(_, body.length(), _, FIN, _, _));
-
- stream_->DoSendResponse();
- EXPECT_FALSE(QuicStreamPeer::read_side_closed(stream_));
- EXPECT_TRUE(stream_->write_side_closed());
-}
-
-TEST_P(QuicSimpleServerStreamTest, PushResponseOnClientInitiatedStream) {
- // EXPECT_QUIC_BUG tests are expensive so only run one instance of them.
- if (GetParam() != AllSupportedVersions()[0]) {
- return;
- }
-
- // Calling PushResponse() on a client initialted stream is never supposed to
- // happen.
- EXPECT_QUIC_BUG(stream_->PushResponse(spdy::Http2HeaderBlock()),
- "Client initiated stream"
- " shouldn't be used as promised stream.");
-}
-
-TEST_P(QuicSimpleServerStreamTest, PushResponseOnServerInitiatedStream) {
- // Tests that PushResponse() should take the given headers as request headers
- // and fetch response from cache, and send it out.
-
- // Create a stream with even stream id and test against this stream.
- const QuicStreamId kServerInitiatedStreamId =
- GetNthServerInitiatedUnidirectionalStreamId(
- connection_->transport_version(), 3);
- // Create a server initiated stream and pass it to session_.
- auto server_initiated_stream =
- new StrictMock<TestStream>(kServerInitiatedStreamId, &session_,
- WRITE_UNIDIRECTIONAL, &memory_cache_backend_);
- session_.ActivateStream(absl::WrapUnique(server_initiated_stream));
-
- const std::string kHost = "www.foo.com";
- const std::string kPath = "/bar";
- spdy::Http2HeaderBlock headers;
- headers[":path"] = kPath;
- headers[":authority"] = kHost;
- headers[":method"] = "GET";
-
- response_headers_[":status"] = "200";
- response_headers_["content-length"] = "5";
- const std::string kBody = "Hello";
- QuicBuffer header = HttpEncoder::SerializeDataFrameHeader(
- body_.length(), SimpleBufferAllocator::Get());
- memory_cache_backend_.AddResponse(kHost, kPath, std::move(response_headers_),
- kBody);
-
- // Call PushResponse() should trigger stream to fetch response from cache
- // and send it back.
- InSequence s;
- EXPECT_CALL(*server_initiated_stream, WriteHeadersMock(false));
-
- if (UsesHttp3()) {
- EXPECT_CALL(session_, WritevData(kServerInitiatedStreamId, header.size(), _,
- NO_FIN, _, _));
- }
- EXPECT_CALL(session_,
- WritevData(kServerInitiatedStreamId, kBody.size(), _, FIN, _, _));
- server_initiated_stream->PushResponse(std::move(headers));
- EXPECT_EQ(kPath, server_initiated_stream->GetHeader(":path"));
- EXPECT_EQ("GET", server_initiated_stream->GetHeader(":method"));
-}
-
-TEST_P(QuicSimpleServerStreamTest, TestSendErrorResponse) {
- QuicStreamPeer::SetFinReceived(stream_);
-
- InSequence s;
- EXPECT_CALL(*stream_, WriteHeadersMock(false));
- if (UsesHttp3()) {
- EXPECT_CALL(session_,
- WritevData(_, kDataFrameHeaderLength, _, NO_FIN, _, _));
- }
- EXPECT_CALL(session_, WritevData(_, kErrorLength, _, FIN, _, _));
-
- stream_->DoSendErrorResponse();
- EXPECT_FALSE(QuicStreamPeer::read_side_closed(stream_));
- EXPECT_TRUE(stream_->write_side_closed());
-}
-
-TEST_P(QuicSimpleServerStreamTest, InvalidMultipleContentLength) {
- spdy::Http2HeaderBlock request_headers;
- // \000 is a way to write the null byte when followed by a literal digit.
- header_list_.OnHeader("content-length", absl::string_view("11\00012", 5));
-
- EXPECT_CALL(*stream_, WriteHeadersMock(false));
- EXPECT_CALL(session_, WritevData(_, _, _, _, _, _))
- .WillRepeatedly(
- Invoke(&session_, &MockQuicSimpleServerSession::ConsumeData));
- stream_->OnStreamHeaderList(true, kFakeFrameLen, header_list_);
-
- EXPECT_TRUE(QuicStreamPeer::read_side_closed(stream_));
- EXPECT_TRUE(stream_->reading_stopped());
- EXPECT_TRUE(stream_->write_side_closed());
-}
-
-TEST_P(QuicSimpleServerStreamTest, InvalidLeadingNullContentLength) {
- spdy::Http2HeaderBlock request_headers;
- // \000 is a way to write the null byte when followed by a literal digit.
- header_list_.OnHeader("content-length", absl::string_view("\00012", 3));
-
- EXPECT_CALL(*stream_, WriteHeadersMock(false));
- EXPECT_CALL(session_, WritevData(_, _, _, _, _, _))
- .WillRepeatedly(
- Invoke(&session_, &MockQuicSimpleServerSession::ConsumeData));
- stream_->OnStreamHeaderList(true, kFakeFrameLen, header_list_);
-
- EXPECT_TRUE(QuicStreamPeer::read_side_closed(stream_));
- EXPECT_TRUE(stream_->reading_stopped());
- EXPECT_TRUE(stream_->write_side_closed());
-}
-
-TEST_P(QuicSimpleServerStreamTest, ValidMultipleContentLength) {
- spdy::Http2HeaderBlock request_headers;
- // \000 is a way to write the null byte when followed by a literal digit.
- header_list_.OnHeader("content-length", absl::string_view("11\00011", 5));
-
- stream_->OnStreamHeaderList(false, kFakeFrameLen, header_list_);
-
- EXPECT_EQ(11, stream_->content_length());
- EXPECT_FALSE(QuicStreamPeer::read_side_closed(stream_));
- EXPECT_FALSE(stream_->reading_stopped());
- EXPECT_FALSE(stream_->write_side_closed());
-}
-
-TEST_P(QuicSimpleServerStreamTest,
- DoNotSendQuicRstStreamNoErrorWithRstReceived) {
- EXPECT_FALSE(stream_->reading_stopped());
-
- if (VersionUsesHttp3(connection_->transport_version())) {
- // Unidirectional stream type and then a Stream Cancellation instruction is
- // sent on the QPACK decoder stream. Ignore these writes without any
- // assumption on their number or size.
- auto* qpack_decoder_stream =
- QuicSpdySessionPeer::GetQpackDecoderSendStream(&session_);
- EXPECT_CALL(session_, WritevData(qpack_decoder_stream->id(), _, _, _, _, _))
- .Times(AnyNumber());
- }
-
- EXPECT_CALL(
- session_,
- MaybeSendRstStreamFrame(
- _,
- session_.version().UsesHttp3()
- ? QuicResetStreamError::FromInternal(QUIC_STREAM_CANCELLED)
- : QuicResetStreamError::FromInternal(QUIC_RST_ACKNOWLEDGEMENT),
- _))
- .Times(1);
- QuicRstStreamFrame rst_frame(kInvalidControlFrameId, stream_->id(),
- QUIC_STREAM_CANCELLED, 1234);
- stream_->OnStreamReset(rst_frame);
- if (VersionHasIetfQuicFrames(connection_->transport_version())) {
- EXPECT_CALL(session_owner_, OnStopSendingReceived(_));
- // Create and inject a STOP SENDING frame to complete the close
- // of the stream. This is only needed for version 99/IETF QUIC.
- QuicStopSendingFrame stop_sending(kInvalidControlFrameId, stream_->id(),
- QUIC_STREAM_CANCELLED);
- session_.OnStopSendingFrame(stop_sending);
- }
- EXPECT_TRUE(stream_->reading_stopped());
- EXPECT_TRUE(stream_->write_side_closed());
-}
-
-TEST_P(QuicSimpleServerStreamTest, InvalidHeadersWithFin) {
- char arr[] = {
- 0x3a, 0x68, 0x6f, 0x73, // :hos
- 0x74, 0x00, 0x00, 0x00, // t...
- 0x00, 0x00, 0x00, 0x00, // ....
- 0x07, 0x3a, 0x6d, 0x65, // .:me
- 0x74, 0x68, 0x6f, 0x64, // thod
- 0x00, 0x00, 0x00, 0x03, // ....
- 0x47, 0x45, 0x54, 0x00, // GET.
- 0x00, 0x00, 0x05, 0x3a, // ...:
- 0x70, 0x61, 0x74, 0x68, // path
- 0x00, 0x00, 0x00, 0x04, // ....
- 0x2f, 0x66, 0x6f, 0x6f, // /foo
- 0x00, 0x00, 0x00, 0x07, // ....
- 0x3a, 0x73, 0x63, 0x68, // :sch
- 0x65, 0x6d, 0x65, 0x00, // eme.
- 0x00, 0x00, 0x00, 0x00, // ....
- 0x00, 0x00, 0x08, 0x3a, // ...:
- 0x76, 0x65, 0x72, 0x73, // vers
- '\x96', 0x6f, 0x6e, 0x00, // <i(69)>on.
- 0x00, 0x00, 0x08, 0x48, // ...H
- 0x54, 0x54, 0x50, 0x2f, // TTP/
- 0x31, 0x2e, 0x31, // 1.1
- };
- absl::string_view data(arr, ABSL_ARRAYSIZE(arr));
- QuicStreamFrame frame(stream_->id(), true, 0, data);
- // Verify that we don't crash when we get a invalid headers in stream frame.
- stream_->OnStreamFrame(frame);
-}
-
-TEST_P(QuicSimpleServerStreamTest, ConnectSendsResponseBeforeFinReceived) {
- EXPECT_CALL(session_, WritevData(_, _, _, _, _, _))
- .WillRepeatedly(
- Invoke(&session_, &MockQuicSimpleServerSession::ConsumeData));
- 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);
- QuicBuffer header = HttpEncoder::SerializeDataFrameHeader(
- body_.length(), SimpleBufferAllocator::Get());
- std::string data =
- UsesHttp3() ? absl::StrCat(header.AsStringView(), body_) : body_;
- 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());
- EXPECT_FALSE(stream_->send_error_response_was_called());
-}
-
-TEST_P(QuicSimpleServerStreamTest, ConnectWithInvalidHeader) {
- EXPECT_CALL(session_, WritevData(_, _, _, _, _, _))
- .WillRepeatedly(
- Invoke(&session_, &MockQuicSimpleServerSession::ConsumeData));
- QuicHeaderList header_list;
- header_list.OnHeaderBlockStart();
- header_list.OnHeader(":authority", "www.google.com:4433");
- header_list.OnHeader(":method", "CONNECT");
- // QUIC requires lower-case header names.
- header_list.OnHeader("InVaLiD-HeAdEr", "Well that's just wrong!");
- header_list.OnHeaderBlockEnd(128, 128);
-
- if (UsesHttp3()) {
- EXPECT_CALL(session_,
- MaybeSendStopSendingFrame(_, QuicResetStreamError::FromInternal(
- QUIC_STREAM_NO_ERROR)))
- .Times(1);
- } else {
- EXPECT_CALL(
- session_,
- MaybeSendRstStreamFrame(
- _, QuicResetStreamError::FromInternal(QUIC_STREAM_NO_ERROR), _))
- .Times(1);
- }
- EXPECT_CALL(*stream_, WriteHeadersMock(/*fin=*/false));
- stream_->OnStreamHeaderList(/*fin=*/false, kFakeFrameLen, header_list);
- EXPECT_FALSE(stream_->send_response_was_called());
- EXPECT_TRUE(stream_->send_error_response_was_called());
-}
-
-} // namespace
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/tools/quic_spdy_client_base.cc b/chromium/net/third_party/quiche/src/quic/tools/quic_spdy_client_base.cc
deleted file mode 100644
index 464fa70fda7..00000000000
--- a/chromium/net/third_party/quiche/src/quic/tools/quic_spdy_client_base.cc
+++ /dev/null
@@ -1,296 +0,0 @@
-// Copyright (c) 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/tools/quic_spdy_client_base.h"
-
-#include <utility>
-
-#include "absl/strings/numbers.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/crypto/quic_random.h"
-#include "quic/core/http/spdy_utils.h"
-#include "quic/core/quic_server_id.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-#include "common/quiche_text_utils.h"
-
-using spdy::Http2HeaderBlock;
-
-namespace quic {
-
-void QuicSpdyClientBase::ClientQuicDataToResend::Resend() {
- client_->SendRequest(*headers_, body_, fin_);
- headers_ = nullptr;
-}
-
-QuicSpdyClientBase::QuicDataToResend::QuicDataToResend(
- std::unique_ptr<Http2HeaderBlock> headers,
- absl::string_view body,
- bool fin)
- : headers_(std::move(headers)), body_(body), fin_(fin) {}
-
-QuicSpdyClientBase::QuicDataToResend::~QuicDataToResend() = default;
-
-QuicSpdyClientBase::QuicSpdyClientBase(
- const QuicServerId& server_id,
- const ParsedQuicVersionVector& supported_versions,
- const QuicConfig& config,
- QuicConnectionHelperInterface* helper,
- QuicAlarmFactory* alarm_factory,
- std::unique_ptr<NetworkHelper> network_helper,
- std::unique_ptr<ProofVerifier> proof_verifier,
- std::unique_ptr<SessionCache> session_cache)
- : QuicClientBase(server_id,
- supported_versions,
- config,
- helper,
- alarm_factory,
- std::move(network_helper),
- std::move(proof_verifier),
- std::move(session_cache)),
- store_response_(false),
- latest_response_code_(-1) {}
-
-QuicSpdyClientBase::~QuicSpdyClientBase() {
- // We own the push promise index. We need to explicitly kill
- // the session before the push promise index goes out of scope.
- ResetSession();
-}
-
-QuicSpdyClientSession* QuicSpdyClientBase::client_session() {
- return static_cast<QuicSpdyClientSession*>(QuicClientBase::session());
-}
-
-const QuicSpdyClientSession* QuicSpdyClientBase::client_session() const {
- return static_cast<const QuicSpdyClientSession*>(QuicClientBase::session());
-}
-
-void QuicSpdyClientBase::InitializeSession() {
- if (max_inbound_header_list_size_ > 0) {
- client_session()->set_max_inbound_header_list_size(
- max_inbound_header_list_size_);
- }
- client_session()->Initialize();
- client_session()->CryptoConnect();
-}
-
-void QuicSpdyClientBase::OnClose(QuicSpdyStream* stream) {
- QUICHE_DCHECK(stream != nullptr);
- QuicSpdyClientStream* client_stream =
- static_cast<QuicSpdyClientStream*>(stream);
-
- const Http2HeaderBlock& response_headers = client_stream->response_headers();
- if (response_listener_ != nullptr) {
- response_listener_->OnCompleteResponse(stream->id(), response_headers,
- client_stream->data());
- }
-
- // Store response headers and body.
- if (store_response_) {
- auto status = response_headers.find(":status");
- if (status == response_headers.end()) {
- QUIC_LOG(ERROR) << "Missing :status response header";
- } else if (!absl::SimpleAtoi(status->second, &latest_response_code_)) {
- QUIC_LOG(ERROR) << "Invalid :status response header: " << status->second;
- }
- latest_response_headers_ = response_headers.DebugString();
- preliminary_response_headers_ =
- client_stream->preliminary_headers().DebugString();
- latest_response_header_block_ = response_headers.Clone();
- latest_response_body_ = client_stream->data();
- latest_response_trailers_ =
- client_stream->received_trailers().DebugString();
- }
-}
-
-std::unique_ptr<QuicSession> QuicSpdyClientBase::CreateQuicClientSession(
- const quic::ParsedQuicVersionVector& supported_versions,
- QuicConnection* connection) {
- return std::make_unique<QuicSpdyClientSession>(
- *config(), supported_versions, connection, server_id(), crypto_config(),
- &push_promise_index_);
-}
-
-void QuicSpdyClientBase::SendRequest(const Http2HeaderBlock& headers,
- absl::string_view body,
- bool fin) {
- if (GetQuicFlag(FLAGS_quic_client_convert_http_header_name_to_lowercase)) {
- QUIC_CODE_COUNT(quic_client_convert_http_header_name_to_lowercase);
- Http2HeaderBlock sanitized_headers;
- for (const auto& p : headers) {
- sanitized_headers[quiche::QuicheTextUtils::ToLower(p.first)] = p.second;
- }
-
- SendRequestInternal(std::move(sanitized_headers), body, fin);
- } else {
- SendRequestInternal(headers.Clone(), body, fin);
- }
-}
-
-void QuicSpdyClientBase::SendRequestInternal(Http2HeaderBlock sanitized_headers,
- absl::string_view body,
- bool fin) {
- QuicClientPushPromiseIndex::TryHandle* handle;
- QuicAsyncStatus rv =
- push_promise_index()->Try(sanitized_headers, this, &handle);
- if (rv == QUIC_SUCCESS)
- return;
-
- if (rv == QUIC_PENDING) {
- // May need to retry request if asynchronous rendezvous fails.
- AddPromiseDataToResend(sanitized_headers, body, fin);
- return;
- }
-
- QuicSpdyClientStream* stream = CreateClientStream();
- if (stream == nullptr) {
- QUIC_BUG(quic_bug_10949_1) << "stream creation failed!";
- return;
- }
- stream->SendRequest(std::move(sanitized_headers), body, fin);
-}
-
-void QuicSpdyClientBase::SendRequestAndWaitForResponse(
- const Http2HeaderBlock& headers,
- absl::string_view body,
- bool fin) {
- SendRequest(headers, body, fin);
- while (WaitForEvents()) {
- }
-}
-
-void QuicSpdyClientBase::SendRequestsAndWaitForResponse(
- const std::vector<std::string>& url_list) {
- for (size_t i = 0; i < url_list.size(); ++i) {
- Http2HeaderBlock headers;
- if (!SpdyUtils::PopulateHeaderBlockFromUrl(url_list[i], &headers)) {
- QUIC_BUG(quic_bug_10949_2) << "Unable to create request";
- continue;
- }
- SendRequest(headers, "", true);
- }
- while (WaitForEvents()) {
- }
-}
-
-QuicSpdyClientStream* QuicSpdyClientBase::CreateClientStream() {
- if (!connected()) {
- return nullptr;
- }
- if (VersionHasIetfQuicFrames(client_session()->transport_version())) {
- // Process MAX_STREAMS from peer or wait for liveness testing succeeds.
- while (!client_session()->CanOpenNextOutgoingBidirectionalStream()) {
- network_helper()->RunEventLoop();
- }
- }
- auto* stream = static_cast<QuicSpdyClientStream*>(
- client_session()->CreateOutgoingBidirectionalStream());
- if (stream) {
- stream->set_visitor(this);
- }
- return stream;
-}
-
-bool QuicSpdyClientBase::goaway_received() const {
- return client_session() && client_session()->goaway_received();
-}
-
-bool QuicSpdyClientBase::EarlyDataAccepted() {
- return client_session()->EarlyDataAccepted();
-}
-
-bool QuicSpdyClientBase::ReceivedInchoateReject() {
- return client_session()->ReceivedInchoateReject();
-}
-
-int QuicSpdyClientBase::GetNumSentClientHellosFromSession() {
- return client_session()->GetNumSentClientHellos();
-}
-
-int QuicSpdyClientBase::GetNumReceivedServerConfigUpdatesFromSession() {
- return client_session()->GetNumReceivedServerConfigUpdates();
-}
-
-void QuicSpdyClientBase::MaybeAddQuicDataToResend(
- std::unique_ptr<QuicDataToResend> data_to_resend) {
- data_to_resend_on_connect_.push_back(std::move(data_to_resend));
-}
-
-void QuicSpdyClientBase::ClearDataToResend() {
- data_to_resend_on_connect_.clear();
-}
-
-void QuicSpdyClientBase::ResendSavedData() {
- // Calling Resend will re-enqueue the data, so swap out
- // data_to_resend_on_connect_ before iterating.
- std::vector<std::unique_ptr<QuicDataToResend>> old_data;
- old_data.swap(data_to_resend_on_connect_);
- for (const auto& data : old_data) {
- data->Resend();
- }
-}
-
-void QuicSpdyClientBase::AddPromiseDataToResend(const Http2HeaderBlock& headers,
- absl::string_view body,
- bool fin) {
- std::unique_ptr<Http2HeaderBlock> new_headers(
- new Http2HeaderBlock(headers.Clone()));
- push_promise_data_to_resend_.reset(
- new ClientQuicDataToResend(std::move(new_headers), body, fin, this));
-}
-
-bool QuicSpdyClientBase::CheckVary(
- const Http2HeaderBlock& /*client_request*/,
- const Http2HeaderBlock& /*promise_request*/,
- const Http2HeaderBlock& /*promise_response*/) {
- return true;
-}
-
-void QuicSpdyClientBase::OnRendezvousResult(QuicSpdyStream* stream) {
- std::unique_ptr<ClientQuicDataToResend> data_to_resend =
- std::move(push_promise_data_to_resend_);
- if (stream) {
- stream->set_visitor(this);
- stream->OnBodyAvailable();
- } else if (data_to_resend) {
- data_to_resend->Resend();
- }
-}
-
-int QuicSpdyClientBase::latest_response_code() const {
- QUIC_BUG_IF(quic_bug_10949_3, !store_response_) << "Response not stored!";
- return latest_response_code_;
-}
-
-const std::string& QuicSpdyClientBase::latest_response_headers() const {
- QUIC_BUG_IF(quic_bug_10949_4, !store_response_) << "Response not stored!";
- return latest_response_headers_;
-}
-
-const std::string& QuicSpdyClientBase::preliminary_response_headers() const {
- QUIC_BUG_IF(quic_bug_10949_5, !store_response_) << "Response not stored!";
- return preliminary_response_headers_;
-}
-
-const Http2HeaderBlock& QuicSpdyClientBase::latest_response_header_block()
- const {
- QUIC_BUG_IF(quic_bug_10949_6, !store_response_) << "Response not stored!";
- return latest_response_header_block_;
-}
-
-const std::string& QuicSpdyClientBase::latest_response_body() const {
- QUIC_BUG_IF(quic_bug_10949_7, !store_response_) << "Response not stored!";
- return latest_response_body_;
-}
-
-const std::string& QuicSpdyClientBase::latest_response_trailers() const {
- QUIC_BUG_IF(quic_bug_10949_8, !store_response_) << "Response not stored!";
- return latest_response_trailers_;
-}
-
-bool QuicSpdyClientBase::HasActiveRequests() {
- return client_session()->HasActiveRequestStreams();
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/tools/quic_spdy_client_base.h b/chromium/net/third_party/quiche/src/quic/tools/quic_spdy_client_base.h
deleted file mode 100644
index 3e4172536b6..00000000000
--- a/chromium/net/third_party/quiche/src/quic/tools/quic_spdy_client_base.h
+++ /dev/null
@@ -1,243 +0,0 @@
-// Copyright (c) 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// A base class for the toy client, which connects to a specified port and sends
-// QUIC request to that endpoint.
-
-#ifndef QUICHE_QUIC_TOOLS_QUIC_SPDY_CLIENT_BASE_H_
-#define QUICHE_QUIC_TOOLS_QUIC_SPDY_CLIENT_BASE_H_
-
-#include <string>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/crypto/crypto_handshake.h"
-#include "quic/core/http/quic_client_push_promise_index.h"
-#include "quic/core/http/quic_spdy_client_session.h"
-#include "quic/core/http/quic_spdy_client_stream.h"
-#include "quic/core/quic_config.h"
-#include "quic/platform/api/quic_socket_address.h"
-#include "quic/tools/quic_client_base.h"
-
-namespace quic {
-
-class ProofVerifier;
-class QuicServerId;
-class SessionCache;
-
-class QuicSpdyClientBase : public QuicClientBase,
- public QuicClientPushPromiseIndex::Delegate,
- public QuicSpdyStream::Visitor {
- public:
- // A ResponseListener is notified when a complete response is received.
- class ResponseListener {
- public:
- ResponseListener() {}
- virtual ~ResponseListener() {}
- virtual void OnCompleteResponse(
- QuicStreamId id,
- const spdy::Http2HeaderBlock& response_headers,
- const std::string& response_body) = 0;
- };
-
- // A piece of data that can be sent multiple times. For example, it can be a
- // HTTP request that is resent after a connect=>version negotiation=>reconnect
- // sequence.
- class QuicDataToResend {
- public:
- // |headers| may be null, since it's possible to send data without headers.
- QuicDataToResend(std::unique_ptr<spdy::Http2HeaderBlock> headers,
- absl::string_view body,
- bool fin);
- QuicDataToResend(const QuicDataToResend&) = delete;
- QuicDataToResend& operator=(const QuicDataToResend&) = delete;
-
- virtual ~QuicDataToResend();
-
- // Must be overridden by specific classes with the actual method for
- // re-sending data.
- virtual void Resend() = 0;
-
- protected:
- std::unique_ptr<spdy::Http2HeaderBlock> headers_;
- absl::string_view body_;
- bool fin_;
- };
-
- QuicSpdyClientBase(const QuicServerId& server_id,
- const ParsedQuicVersionVector& supported_versions,
- const QuicConfig& config,
- QuicConnectionHelperInterface* helper,
- QuicAlarmFactory* alarm_factory,
- std::unique_ptr<NetworkHelper> network_helper,
- std::unique_ptr<ProofVerifier> proof_verifier,
- std::unique_ptr<SessionCache> session_cache);
- QuicSpdyClientBase(const QuicSpdyClientBase&) = delete;
- QuicSpdyClientBase& operator=(const QuicSpdyClientBase&) = delete;
-
- ~QuicSpdyClientBase() override;
-
- // QuicSpdyStream::Visitor
- void OnClose(QuicSpdyStream* stream) override;
-
- // A spdy session has to call CryptoConnect on top of the regular
- // initialization.
- void InitializeSession() override;
-
- // Sends an HTTP request and does not wait for response before returning.
- void SendRequest(const spdy::Http2HeaderBlock& headers,
- absl::string_view body,
- bool fin);
-
- // Sends an HTTP request and waits for response before returning.
- void SendRequestAndWaitForResponse(const spdy::Http2HeaderBlock& headers,
- absl::string_view body,
- bool fin);
-
- // Sends a request simple GET for each URL in |url_list|, and then waits for
- // each to complete.
- void SendRequestsAndWaitForResponse(const std::vector<std::string>& url_list);
-
- // Returns a newly created QuicSpdyClientStream.
- QuicSpdyClientStream* CreateClientStream();
-
- // Returns a the session used for this client downcasted to a
- // QuicSpdyClientSession.
- QuicSpdyClientSession* client_session();
- const QuicSpdyClientSession* client_session() const;
-
- QuicClientPushPromiseIndex* push_promise_index() {
- return &push_promise_index_;
- }
-
- bool CheckVary(const spdy::Http2HeaderBlock& client_request,
- const spdy::Http2HeaderBlock& promise_request,
- const spdy::Http2HeaderBlock& promise_response) override;
- void OnRendezvousResult(QuicSpdyStream*) override;
-
- // If the crypto handshake has not yet been confirmed, adds the data to the
- // queue of data to resend if the client receives a stateless reject.
- // Otherwise, deletes the data.
- void MaybeAddQuicDataToResend(
- std::unique_ptr<QuicDataToResend> data_to_resend);
-
- void set_store_response(bool val) { store_response_ = val; }
-
- int latest_response_code() const;
- const std::string& latest_response_headers() const;
- const std::string& preliminary_response_headers() const;
- const spdy::Http2HeaderBlock& latest_response_header_block() const;
- const std::string& latest_response_body() const;
- const std::string& latest_response_trailers() const;
-
- void set_response_listener(std::unique_ptr<ResponseListener> listener) {
- response_listener_ = std::move(listener);
- }
-
- void set_drop_response_body(bool drop_response_body) {
- drop_response_body_ = drop_response_body;
- }
- bool drop_response_body() const { return drop_response_body_; }
-
- void set_enable_web_transport(bool enable_web_transport) {
- enable_web_transport_ = enable_web_transport;
- }
- bool enable_web_transport() const { return enable_web_transport_; }
-
- void set_use_datagram_contexts(bool use_datagram_contexts) {
- use_datagram_contexts_ = use_datagram_contexts;
- }
- bool use_datagram_contexts() const { return use_datagram_contexts_; }
-
- // QuicClientBase methods.
- bool goaway_received() const override;
- bool EarlyDataAccepted() override;
- bool ReceivedInchoateReject() override;
-
- void set_max_inbound_header_list_size(size_t size) {
- max_inbound_header_list_size_ = size;
- }
-
- protected:
- int GetNumSentClientHellosFromSession() override;
- int GetNumReceivedServerConfigUpdatesFromSession() override;
-
- // Takes ownership of |connection|.
- std::unique_ptr<QuicSession> CreateQuicClientSession(
- const quic::ParsedQuicVersionVector& supported_versions,
- QuicConnection* connection) override;
-
- void ClearDataToResend() override;
-
- void ResendSavedData() override;
-
- void AddPromiseDataToResend(const spdy::Http2HeaderBlock& headers,
- absl::string_view body,
- bool fin);
- bool HasActiveRequests() override;
-
- private:
- // Specific QuicClient class for storing data to resend.
- class ClientQuicDataToResend : public QuicDataToResend {
- public:
- ClientQuicDataToResend(std::unique_ptr<spdy::Http2HeaderBlock> headers,
- absl::string_view body,
- bool fin,
- QuicSpdyClientBase* client)
- : QuicDataToResend(std::move(headers), body, fin), client_(client) {
- QUICHE_DCHECK(headers_);
- QUICHE_DCHECK(client);
- }
-
- ClientQuicDataToResend(const ClientQuicDataToResend&) = delete;
- ClientQuicDataToResend& operator=(const ClientQuicDataToResend&) = delete;
- ~ClientQuicDataToResend() override {}
-
- void Resend() override;
-
- private:
- QuicSpdyClientBase* client_;
- };
-
- void SendRequestInternal(spdy::Http2HeaderBlock sanitized_headers,
- absl::string_view body,
- bool fin);
-
- // Index of pending promised streams. Must outlive |session_|.
- QuicClientPushPromiseIndex push_promise_index_;
-
- // If true, store the latest response code, headers, and body.
- bool store_response_;
- // HTTP response code from most recent response.
- int latest_response_code_;
- // HTTP/2 headers from most recent response.
- std::string latest_response_headers_;
- // preliminary 100 Continue HTTP/2 headers from most recent response, if any.
- std::string preliminary_response_headers_;
- // HTTP/2 headers from most recent response.
- spdy::Http2HeaderBlock latest_response_header_block_;
- // Body of most recent response.
- std::string latest_response_body_;
- // HTTP/2 trailers from most recent response.
- std::string latest_response_trailers_;
-
- // Listens for full responses.
- std::unique_ptr<ResponseListener> response_listener_;
-
- // Keeps track of any data that must be resent upon a subsequent successful
- // connection, in case the client receives a stateless reject.
- std::vector<std::unique_ptr<QuicDataToResend>> data_to_resend_on_connect_;
-
- std::unique_ptr<ClientQuicDataToResend> push_promise_data_to_resend_;
-
- bool drop_response_body_ = false;
- bool enable_web_transport_ = false;
- bool use_datagram_contexts_ = false;
- // If not zero, used to set client's max inbound header size before session
- // initialize.
- size_t max_inbound_header_list_size_ = 0;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_TOOLS_QUIC_SPDY_CLIENT_BASE_H_
diff --git a/chromium/net/third_party/quiche/src/quic/tools/quic_spdy_server_base.h b/chromium/net/third_party/quiche/src/quic/tools/quic_spdy_server_base.h
deleted file mode 100644
index c84398fe13d..00000000000
--- a/chromium/net/third_party/quiche/src/quic/tools/quic_spdy_server_base.h
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// A toy server, which connects to a specified port and sends QUIC
-// requests to that endpoint.
-
-#ifndef QUICHE_QUIC_TOOLS_QUIC_SPDY_SERVER_BASE_H_
-#define QUICHE_QUIC_TOOLS_QUIC_SPDY_SERVER_BASE_H_
-
-#include "quic/platform/api/quic_socket_address.h"
-
-namespace quic {
-
-// Base class for service instances to be used with QuicToyServer.
-class QuicSpdyServerBase {
- public:
- virtual ~QuicSpdyServerBase() = default;
-
- // Creates a UDP socket and listens on |address|. Returns true on success
- // and false otherwise.
- virtual bool CreateUDPSocketAndListen(const QuicSocketAddress& address) = 0;
-
- // Handles incoming requests. Does not return.
- virtual void HandleEventsForever() = 0;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_TOOLS_QUIC_SPDY_SERVER_BASE_H_
diff --git a/chromium/net/third_party/quiche/src/quic/tools/quic_tcp_like_trace_converter.cc b/chromium/net/third_party/quiche/src/quic/tools/quic_tcp_like_trace_converter.cc
deleted file mode 100644
index 22e873185b6..00000000000
--- a/chromium/net/third_party/quiche/src/quic/tools/quic_tcp_like_trace_converter.cc
+++ /dev/null
@@ -1,126 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/tools/quic_tcp_like_trace_converter.h"
-
-#include "quic/core/quic_constants.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-
-namespace quic {
-
-QuicTcpLikeTraceConverter::QuicTcpLikeTraceConverter()
- : largest_observed_control_frame_id_(kInvalidControlFrameId),
- connection_offset_(0) {}
-
-QuicTcpLikeTraceConverter::StreamOffsetSegment::StreamOffsetSegment()
- : connection_offset(0) {}
-
-QuicTcpLikeTraceConverter::StreamOffsetSegment::StreamOffsetSegment(
- QuicStreamOffset stream_offset,
- uint64_t connection_offset,
- QuicByteCount data_length)
- : stream_data(stream_offset, stream_offset + data_length),
- connection_offset(connection_offset) {}
-
-QuicTcpLikeTraceConverter::StreamInfo::StreamInfo() : fin(false) {}
-
-QuicIntervalSet<uint64_t> QuicTcpLikeTraceConverter::OnCryptoFrameSent(
- EncryptionLevel level,
- QuicStreamOffset offset,
- QuicByteCount data_length) {
- if (level >= NUM_ENCRYPTION_LEVELS) {
- QUIC_BUG(quic_bug_10907_1) << "Invalid encryption level";
- return {};
- }
- return OnFrameSent(offset, data_length, /*fin=*/false,
- &crypto_frames_info_[level]);
-}
-
-QuicIntervalSet<uint64_t> QuicTcpLikeTraceConverter::OnStreamFrameSent(
- QuicStreamId stream_id,
- QuicStreamOffset offset,
- QuicByteCount data_length,
- bool fin) {
- return OnFrameSent(
- offset, data_length, fin,
- &streams_info_.emplace(stream_id, StreamInfo()).first->second);
-}
-
-QuicIntervalSet<uint64_t> QuicTcpLikeTraceConverter::OnFrameSent(
- QuicStreamOffset offset,
- QuicByteCount data_length,
- bool fin,
- StreamInfo* info) {
- QuicIntervalSet<uint64_t> connection_offsets;
- if (fin) {
- // Stream fin consumes a connection offset.
- ++data_length;
- }
- // Get connection offsets of retransmission data in this frame.
- for (const auto& segment : info->segments) {
- QuicInterval<QuicStreamOffset> retransmission(offset, offset + data_length);
- retransmission.IntersectWith(segment.stream_data);
- if (retransmission.Empty()) {
- continue;
- }
- const uint64_t connection_offset = segment.connection_offset +
- retransmission.min() -
- segment.stream_data.min();
- connection_offsets.Add(connection_offset,
- connection_offset + retransmission.Length());
- }
-
- if (info->fin) {
- return connection_offsets;
- }
-
- // Get connection offsets of new data in this frame.
- QuicStreamOffset least_unsent_offset =
- info->segments.empty() ? 0 : info->segments.back().stream_data.max();
- if (least_unsent_offset >= offset + data_length) {
- return connection_offsets;
- }
- // Ignore out-of-order stream data so that as connection offset increases,
- // stream offset increases.
- QuicStreamOffset new_data_offset = std::max(least_unsent_offset, offset);
- QuicByteCount new_data_length = offset + data_length - new_data_offset;
- connection_offsets.Add(connection_offset_,
- connection_offset_ + new_data_length);
- if (!info->segments.empty() && new_data_offset == least_unsent_offset &&
- connection_offset_ == info->segments.back().connection_offset +
- info->segments.back().stream_data.Length()) {
- // Extend the last segment if both stream and connection offsets are
- // contiguous.
- info->segments.back().stream_data.SetMax(new_data_offset + new_data_length);
- } else {
- info->segments.emplace_back(new_data_offset, connection_offset_,
- new_data_length);
- }
- info->fin = fin;
- connection_offset_ += new_data_length;
-
- return connection_offsets;
-}
-
-QuicInterval<uint64_t> QuicTcpLikeTraceConverter::OnControlFrameSent(
- QuicControlFrameId control_frame_id,
- QuicByteCount control_frame_length) {
- if (control_frame_id > largest_observed_control_frame_id_) {
- // New control frame.
- QuicInterval<uint64_t> connection_offset = QuicInterval<uint64_t>(
- connection_offset_, connection_offset_ + control_frame_length);
- connection_offset_ += control_frame_length;
- control_frames_info_[control_frame_id] = connection_offset;
- largest_observed_control_frame_id_ = control_frame_id;
- return connection_offset;
- }
- const auto iter = control_frames_info_.find(control_frame_id);
- if (iter == control_frames_info_.end()) {
- // Ignore out of order control frames.
- return {};
- }
- return iter->second;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/tools/quic_tcp_like_trace_converter.h b/chromium/net/third_party/quiche/src/quic/tools/quic_tcp_like_trace_converter.h
deleted file mode 100644
index b90d4553dd5..00000000000
--- a/chromium/net/third_party/quiche/src/quic/tools/quic_tcp_like_trace_converter.h
+++ /dev/null
@@ -1,88 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TOOLS_QUIC_TCP_LIKE_TRACE_CONVERTER_H_
-#define QUICHE_QUIC_TOOLS_QUIC_TCP_LIKE_TRACE_CONVERTER_H_
-
-#include <vector>
-
-#include "absl/container/flat_hash_map.h"
-#include "quic/core/frames/quic_stream_frame.h"
-#include "quic/core/quic_interval.h"
-#include "quic/core/quic_interval_set.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_containers.h"
-
-namespace quic {
-
-// This converter converts sent QUIC frames to connection byte offset (just like
-// TCP byte sequence number).
-class QuicTcpLikeTraceConverter {
- public:
- // StreamOffsetSegment stores a stream offset range which has contiguous
- // connection offset.
- struct StreamOffsetSegment {
- StreamOffsetSegment();
- StreamOffsetSegment(QuicStreamOffset stream_offset,
- uint64_t connection_offset,
- QuicByteCount data_length);
-
- QuicInterval<QuicStreamOffset> stream_data;
- uint64_t connection_offset;
- };
-
- QuicTcpLikeTraceConverter();
- QuicTcpLikeTraceConverter(const QuicTcpLikeTraceConverter& other) = delete;
- QuicTcpLikeTraceConverter(QuicTcpLikeTraceConverter&& other) = delete;
-
- ~QuicTcpLikeTraceConverter() {}
-
- // Called when a crypto frame is sent. Returns the corresponding connection
- // offsets.
- QuicIntervalSet<uint64_t> OnCryptoFrameSent(EncryptionLevel level,
- QuicStreamOffset offset,
- QuicByteCount data_length);
-
- // Called when a stream frame is sent. Returns the corresponding connection
- // offsets.
- QuicIntervalSet<uint64_t> OnStreamFrameSent(QuicStreamId stream_id,
- QuicStreamOffset offset,
- QuicByteCount data_length,
- bool fin);
-
- // Called when a control frame is sent. Returns the corresponding connection
- // offsets.
- QuicInterval<uint64_t> OnControlFrameSent(QuicControlFrameId control_frame_id,
- QuicByteCount control_frame_length);
-
- private:
- struct StreamInfo {
- StreamInfo();
-
- // Stores contiguous connection offset pieces.
- std::vector<StreamOffsetSegment> segments;
- // Indicates whether fin has been sent.
- bool fin;
- };
-
- // Called when frame with |offset|, |data_length| and |fin| has been sent.
- // Update |info| and returns connection offsets.
- QuicIntervalSet<uint64_t> OnFrameSent(QuicStreamOffset offset,
- QuicByteCount data_length,
- bool fin,
- StreamInfo* info);
-
- StreamInfo crypto_frames_info_[NUM_ENCRYPTION_LEVELS];
- absl::flat_hash_map<QuicStreamId, StreamInfo> streams_info_;
- absl::flat_hash_map<QuicControlFrameId, QuicInterval<uint64_t>>
- control_frames_info_;
-
- QuicControlFrameId largest_observed_control_frame_id_;
-
- uint64_t connection_offset_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_TOOLS_QUIC_TCP_LIKE_TRACE_CONVERTER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/tools/quic_tcp_like_trace_converter_test.cc b/chromium/net/third_party/quiche/src/quic/tools/quic_tcp_like_trace_converter_test.cc
deleted file mode 100644
index 97edd4d445f..00000000000
--- a/chromium/net/third_party/quiche/src/quic/tools/quic_tcp_like_trace_converter_test.cc
+++ /dev/null
@@ -1,124 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/tools/quic_tcp_like_trace_converter.h"
-
-#include "quic/platform/api/quic_test.h"
-
-namespace quic {
-namespace test {
-namespace {
-
-TEST(QuicTcpLikeTraceConverterTest, BasicTest) {
- QuicTcpLikeTraceConverter converter;
-
- EXPECT_EQ(QuicIntervalSet<uint64_t>(0, 100),
- converter.OnStreamFrameSent(1, 0, 100, false));
- EXPECT_EQ(QuicIntervalSet<uint64_t>(100, 200),
- converter.OnStreamFrameSent(3, 0, 100, false));
- EXPECT_EQ(QuicIntervalSet<uint64_t>(200, 300),
- converter.OnStreamFrameSent(3, 100, 100, false));
- EXPECT_EQ(QuicInterval<uint64_t>(300, 450),
- converter.OnControlFrameSent(2, 150));
- EXPECT_EQ(QuicIntervalSet<uint64_t>(450, 550),
- converter.OnStreamFrameSent(1, 100, 100, false));
- EXPECT_EQ(QuicInterval<uint64_t>(550, 650),
- converter.OnControlFrameSent(3, 100));
- EXPECT_EQ(QuicIntervalSet<uint64_t>(650, 850),
- converter.OnStreamFrameSent(3, 200, 200, false));
- EXPECT_EQ(QuicInterval<uint64_t>(850, 1050),
- converter.OnControlFrameSent(4, 200));
- EXPECT_EQ(QuicIntervalSet<uint64_t>(1050, 1100),
- converter.OnStreamFrameSent(1, 200, 50, false));
- EXPECT_EQ(QuicIntervalSet<uint64_t>(1100, 1150),
- converter.OnStreamFrameSent(1, 250, 50, false));
- EXPECT_EQ(QuicIntervalSet<uint64_t>(1150, 1350),
- converter.OnStreamFrameSent(3, 400, 200, false));
-
- // Stream 1 retransmits [50, 300) and sends new data [300, 350) in the same
- // frame.
- QuicIntervalSet<uint64_t> expected;
- expected.Add(50, 100);
- expected.Add(450, 550);
- expected.Add(1050, 1150);
- expected.Add(1350, 1401);
- EXPECT_EQ(expected, converter.OnStreamFrameSent(1, 50, 300, true));
-
- expected.Clear();
- // Stream 3 retransmits [150, 500).
- expected.Add(250, 300);
- expected.Add(650, 850);
- expected.Add(1150, 1250);
- EXPECT_EQ(expected, converter.OnStreamFrameSent(3, 150, 350, false));
-
- // Stream 3 retransmits [300, 600) and sends new data [600, 800) in the same
- // frame.
- expected.Clear();
- expected.Add(750, 850);
- expected.Add(1150, 1350);
- expected.Add(1401, 1602);
- EXPECT_EQ(expected, converter.OnStreamFrameSent(3, 300, 500, true));
-
- // Stream 3 retransmits fin only frame.
- expected.Clear();
- expected.Add(1601, 1602);
- EXPECT_EQ(expected, converter.OnStreamFrameSent(3, 800, 0, true));
-
- QuicInterval<uint64_t> expected2;
- // Ignore out of order control frames.
- EXPECT_EQ(expected2, converter.OnControlFrameSent(1, 100));
-
- // Ignore passed in length for retransmitted frame.
- expected2 = {300, 450};
- EXPECT_EQ(expected2, converter.OnControlFrameSent(2, 200));
-
- expected2 = {1602, 1702};
- EXPECT_EQ(expected2, converter.OnControlFrameSent(10, 100));
-}
-
-TEST(QuicTcpLikeTraceConverterTest, FuzzerTest) {
- QuicTcpLikeTraceConverter converter;
- // Stream does not start from offset 0.
- EXPECT_EQ(QuicIntervalSet<uint64_t>(0, 100),
- converter.OnStreamFrameSent(1, 100, 100, false));
- EXPECT_EQ(QuicIntervalSet<uint64_t>(100, 300),
- converter.OnStreamFrameSent(3, 200, 200, false));
- // Stream does not send data contiguously.
- EXPECT_EQ(QuicIntervalSet<uint64_t>(300, 400),
- converter.OnStreamFrameSent(1, 300, 100, false));
-
- // Stream fills existing holes.
- QuicIntervalSet<uint64_t> expected;
- expected.Add(0, 100);
- expected.Add(300, 501);
- EXPECT_EQ(expected, converter.OnStreamFrameSent(1, 0, 500, true));
-
- // Stream sends frame after fin.
- EXPECT_EQ(expected, converter.OnStreamFrameSent(1, 50, 600, false));
-}
-
-TEST(QuicTcpLikeTraceConverterTest, OnCryptoFrameSent) {
- QuicTcpLikeTraceConverter converter;
-
- EXPECT_EQ(QuicIntervalSet<uint64_t>(0, 100),
- converter.OnCryptoFrameSent(ENCRYPTION_INITIAL, 0, 100));
- EXPECT_EQ(QuicIntervalSet<uint64_t>(100, 200),
- converter.OnStreamFrameSent(1, 0, 100, false));
- EXPECT_EQ(QuicIntervalSet<uint64_t>(200, 300),
- converter.OnStreamFrameSent(1, 100, 100, false));
- EXPECT_EQ(QuicIntervalSet<uint64_t>(300, 400),
- converter.OnCryptoFrameSent(ENCRYPTION_HANDSHAKE, 0, 100));
- EXPECT_EQ(QuicIntervalSet<uint64_t>(400, 500),
- converter.OnCryptoFrameSent(ENCRYPTION_HANDSHAKE, 100, 100));
-
- // Verify crypto frame retransmission works as intended.
- EXPECT_EQ(QuicIntervalSet<uint64_t>(0, 100),
- converter.OnCryptoFrameSent(ENCRYPTION_INITIAL, 0, 100));
- EXPECT_EQ(QuicIntervalSet<uint64_t>(400, 500),
- converter.OnCryptoFrameSent(ENCRYPTION_HANDSHAKE, 100, 100));
-}
-
-} // namespace
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/tools/quic_toy_client.cc b/chromium/net/third_party/quiche/src/quic/tools/quic_toy_client.cc
deleted file mode 100644
index 7b6b760a6bb..00000000000
--- a/chromium/net/third_party/quiche/src/quic/tools/quic_toy_client.cc
+++ /dev/null
@@ -1,502 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// A binary wrapper for QuicClient.
-// Connects to a host using QUIC, sends a request to the provided URL, and
-// displays the response.
-//
-// Some usage examples:
-//
-// Standard request/response:
-// quic_client www.google.com
-// quic_client www.google.com --quiet
-// quic_client www.google.com --port=443
-//
-// Use a specific version:
-// quic_client www.google.com --quic_version=23
-//
-// Send a POST instead of a GET:
-// quic_client www.google.com --body="this is a POST body"
-//
-// Append additional headers to the request:
-// quic_client www.google.com --headers="Header-A: 1234; Header-B: 5678"
-//
-// Connect to a host different to the URL being requested:
-// quic_client mail.google.com --host=www.google.com
-//
-// Connect to a specific IP:
-// IP=`dig www.google.com +short | head -1`
-// quic_client www.google.com --host=${IP}
-//
-// Send repeated requests and change ephemeral port between requests
-// quic_client www.google.com --num_requests=10
-//
-// Try to connect to a host which does not speak QUIC:
-// quic_client www.example.com
-//
-// This tool is available as a built binary at:
-// /google/data/ro/teams/quic/tools/quic_client
-// After submitting changes to this file, you will need to follow the
-// instructions at go/quic_client_binary_update
-
-#include "quic/tools/quic_toy_client.h"
-
-#include <fstream>
-#include <iostream>
-#include <memory>
-#include <string>
-#include <utility>
-#include <vector>
-
-#include "absl/strings/escaping.h"
-#include "absl/strings/str_split.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/crypto/quic_client_session_cache.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_server_id.h"
-#include "quic/core/quic_utils.h"
-#include "quic/core/quic_versions.h"
-#include "quic/platform/api/quic_default_proof_providers.h"
-#include "quic/platform/api/quic_ip_address.h"
-#include "quic/platform/api/quic_socket_address.h"
-#include "quic/platform/api/quic_system_event_loop.h"
-#include "quic/tools/fake_proof_verifier.h"
-#include "quic/tools/quic_url.h"
-#include "common/platform/api/quiche_command_line_flags.h"
-#include "common/quiche_text_utils.h"
-
-namespace {
-
-using quiche::QuicheTextUtils;
-
-} // namespace
-
-DEFINE_QUICHE_COMMAND_LINE_FLAG(
- std::string, host, "",
- "The IP or hostname to connect to. If not provided, the host "
- "will be derived from the provided URL.");
-
-DEFINE_QUICHE_COMMAND_LINE_FLAG(int32_t, port, 0, "The port to connect to.");
-
-DEFINE_QUICHE_COMMAND_LINE_FLAG(std::string, ip_version_for_host_lookup, "",
- "Only used if host address lookup is needed. "
- "4=ipv4; 6=ipv6; otherwise=don't care.");
-
-DEFINE_QUICHE_COMMAND_LINE_FLAG(std::string, body, "",
- "If set, send a POST with this body.");
-
-DEFINE_QUICHE_COMMAND_LINE_FLAG(
- std::string, body_hex, "",
- "If set, contents are converted from hex to ascii, before "
- "sending as body of a POST. e.g. --body_hex=\"68656c6c6f\"");
-
-DEFINE_QUICHE_COMMAND_LINE_FLAG(
- std::string, headers, "",
- "A semicolon separated list of key:value pairs to "
- "add to request headers.");
-
-DEFINE_QUICHE_COMMAND_LINE_FLAG(bool, quiet, false,
- "Set to true for a quieter output experience.");
-
-DEFINE_QUICHE_COMMAND_LINE_FLAG(
- std::string, quic_version, "",
- "QUIC version to speak, e.g. 21. If not set, then all available "
- "versions are offered in the handshake. Also supports wire versions "
- "such as Q043 or T099.");
-
-DEFINE_QUICHE_COMMAND_LINE_FLAG(
- std::string, connection_options, "",
- "Connection options as ASCII tags separated by commas, "
- "e.g. \"ABCD,EFGH\"");
-
-DEFINE_QUICHE_COMMAND_LINE_FLAG(
- std::string, client_connection_options, "",
- "Client connection options as ASCII tags separated by commas, "
- "e.g. \"ABCD,EFGH\"");
-
-DEFINE_QUICHE_COMMAND_LINE_FLAG(bool, quic_ietf_draft, false,
- "Use the IETF draft version. This also enables "
- "required internal QUIC flags.");
-
-DEFINE_QUICHE_COMMAND_LINE_FLAG(
- bool, version_mismatch_ok, false,
- "If true, a version mismatch in the handshake is not considered a "
- "failure. Useful for probing a server to determine if it speaks "
- "any version of QUIC.");
-
-DEFINE_QUICHE_COMMAND_LINE_FLAG(
- bool, force_version_negotiation, false,
- "If true, start by proposing a version that is reserved for version "
- "negotiation.");
-
-DEFINE_QUICHE_COMMAND_LINE_FLAG(
- bool, multi_packet_chlo, false,
- "If true, add a transport parameter to make the ClientHello span two "
- "packets. Only works with QUIC+TLS.");
-
-DEFINE_QUICHE_COMMAND_LINE_FLAG(
- bool, redirect_is_success, true,
- "If true, an HTTP response code of 3xx is considered to be a "
- "successful response, otherwise a failure.");
-
-DEFINE_QUICHE_COMMAND_LINE_FLAG(int32_t, initial_mtu, 0,
- "Initial MTU of the connection.");
-
-DEFINE_QUICHE_COMMAND_LINE_FLAG(
- int32_t, num_requests, 1,
- "How many sequential requests to make on a single connection.");
-
-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, default_client_cert, "",
- "The path to the file containing PEM-encoded client default certificate to "
- "be sent to the server, if server requested client certs.");
-
-DEFINE_QUICHE_COMMAND_LINE_FLAG(
- std::string, default_client_cert_key, "",
- "The path to the file containing PEM-encoded private key of the client's "
- "default certificate for signing, if server requested client certs.");
-
-DEFINE_QUICHE_COMMAND_LINE_FLAG(
- bool, drop_response_body, false,
- "If true, drop response body immediately after it is received.");
-
-DEFINE_QUICHE_COMMAND_LINE_FLAG(
- bool, disable_port_changes, false,
- "If true, do not change local port after each request.");
-
-DEFINE_QUICHE_COMMAND_LINE_FLAG(bool, one_connection_per_request, false,
- "If true, close the connection after each "
- "request. This allows testing 0-RTT.");
-
-DEFINE_QUICHE_COMMAND_LINE_FLAG(int32_t, server_connection_id_length, -1,
- "Length of the server connection ID used.");
-
-DEFINE_QUICHE_COMMAND_LINE_FLAG(int32_t, client_connection_id_length, -1,
- "Length of the client connection ID used.");
-
-DEFINE_QUICHE_COMMAND_LINE_FLAG(int32_t, max_time_before_crypto_handshake_ms,
- 10000,
- "Max time to wait before handshake completes.");
-
-DEFINE_QUICHE_COMMAND_LINE_FLAG(
- int32_t, max_inbound_header_list_size, 128 * 1024,
- "Max inbound header list size. 0 means default.");
-
-namespace quic {
-namespace {
-
-// Creates a ClientProofSource which only contains a default client certificate.
-// Return nullptr for failure.
-std::unique_ptr<ClientProofSource> CreateTestClientProofSource(
- absl::string_view default_client_cert_file,
- absl::string_view default_client_cert_key_file) {
- std::ifstream cert_stream(std::string{default_client_cert_file},
- std::ios::binary);
- std::vector<std::string> certs =
- CertificateView::LoadPemFromStream(&cert_stream);
- if (certs.empty()) {
- std::cerr << "Failed to load client certs." << std::endl;
- return nullptr;
- }
-
- std::ifstream key_stream(std::string{default_client_cert_key_file},
- std::ios::binary);
- std::unique_ptr<CertificatePrivateKey> private_key =
- CertificatePrivateKey::LoadPemFromStream(&key_stream);
- if (private_key == nullptr) {
- std::cerr << "Failed to load client cert key." << std::endl;
- return nullptr;
- }
-
- auto proof_source = std::make_unique<DefaultClientProofSource>();
- proof_source->AddCertAndKey(
- {"*"},
- QuicReferenceCountedPointer<ClientProofSource::Chain>(
- new ClientProofSource::Chain(certs)),
- std::move(*private_key));
-
- return proof_source;
-}
-
-} // namespace
-
-QuicToyClient::QuicToyClient(ClientFactory* client_factory)
- : client_factory_(client_factory) {}
-
-int QuicToyClient::SendRequestsAndPrintResponses(
- std::vector<std::string> urls) {
- QuicUrl url(urls[0], "https");
- std::string host = GetQuicFlag(FLAGS_host);
- if (host.empty()) {
- host = url.host();
- }
- int port = GetQuicFlag(FLAGS_port);
- if (port == 0) {
- port = url.port();
- }
-
- quic::ParsedQuicVersionVector versions = quic::CurrentSupportedVersions();
-
- if (GetQuicFlag(FLAGS_quic_ietf_draft)) {
- quic::QuicVersionInitializeSupportForIetfDraft();
- versions = {};
- for (const ParsedQuicVersion& version : AllSupportedVersions()) {
- if (version.HasIetfQuicFrames() &&
- version.handshake_protocol == quic::PROTOCOL_TLS1_3) {
- versions.push_back(version);
- }
- }
- }
-
- std::string quic_version_string = GetQuicFlag(FLAGS_quic_version);
- if (!quic_version_string.empty()) {
- versions = quic::ParseQuicVersionVectorString(quic_version_string);
- }
-
- if (versions.empty()) {
- std::cerr << "No known version selected." << std::endl;
- return 1;
- }
-
- for (const quic::ParsedQuicVersion& version : versions) {
- quic::QuicEnableVersion(version);
- }
-
- if (GetQuicFlag(FLAGS_force_version_negotiation)) {
- versions.insert(versions.begin(),
- quic::QuicVersionReservedForNegotiation());
- }
-
- const int32_t num_requests(GetQuicFlag(FLAGS_num_requests));
- std::unique_ptr<quic::ProofVerifier> proof_verifier;
- if (GetQuicFlag(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)) {
- session_cache = std::make_unique<QuicClientSessionCache>();
- }
-
- QuicConfig config;
- std::string connection_options_string = GetQuicFlag(FLAGS_connection_options);
- if (!connection_options_string.empty()) {
- config.SetConnectionOptionsToSend(
- ParseQuicTagVector(connection_options_string));
- }
- std::string client_connection_options_string =
- GetQuicFlag(FLAGS_client_connection_options);
- if (!client_connection_options_string.empty()) {
- config.SetClientConnectionOptions(
- ParseQuicTagVector(client_connection_options_string));
- }
- if (GetQuicFlag(FLAGS_multi_packet_chlo)) {
- // Make the ClientHello span multiple packets by adding a custom transport
- // parameter.
- constexpr auto kCustomParameter =
- static_cast<TransportParameters::TransportParameterId>(0x173E);
- std::string custom_value(2000, '?');
- config.custom_transport_parameters_to_send()[kCustomParameter] =
- custom_value;
- }
- config.set_max_time_before_crypto_handshake(QuicTime::Delta::FromMilliseconds(
- GetQuicFlag(FLAGS_max_time_before_crypto_handshake_ms)));
-
- int address_family_for_lookup = AF_UNSPEC;
- if (GetQuicFlag(FLAGS_ip_version_for_host_lookup) == "4") {
- address_family_for_lookup = AF_INET;
- } else if (GetQuicFlag(FLAGS_ip_version_for_host_lookup) == "6") {
- address_family_for_lookup = AF_INET6;
- }
-
- // Build the client, and try to connect.
- std::unique_ptr<QuicSpdyClientBase> client = client_factory_->CreateClient(
- url.host(), host, address_family_for_lookup, port, versions, config,
- std::move(proof_verifier), std::move(session_cache));
-
- if (client == nullptr) {
- std::cerr << "Failed to create client." << std::endl;
- return 1;
- }
-
- if (!GetQuicFlag(FLAGS_default_client_cert).empty() &&
- !GetQuicFlag(FLAGS_default_client_cert_key).empty()) {
- std::unique_ptr<ClientProofSource> proof_source =
- CreateTestClientProofSource(GetQuicFlag(FLAGS_default_client_cert),
- GetQuicFlag(FLAGS_default_client_cert_key));
- if (proof_source == nullptr) {
- std::cerr << "Failed to create client proof source." << std::endl;
- return 1;
- }
- client->crypto_config()->set_proof_source(std::move(proof_source));
- }
-
- int32_t initial_mtu = GetQuicFlag(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));
- const int32_t server_connection_id_length =
- GetQuicFlag(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);
- 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);
- if (max_inbound_header_list_size > 0) {
- client->set_max_inbound_header_list_size(max_inbound_header_list_size);
- }
- if (!client->Initialize()) {
- std::cerr << "Failed to initialize client." << std::endl;
- return 1;
- }
- if (!client->Connect()) {
- quic::QuicErrorCode error = client->session()->error();
- if (error == quic::QUIC_INVALID_VERSION) {
- std::cerr << "Failed to negotiate version with " << host << ":" << port
- << ". " << 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;
- }
- std::cerr << "Failed to connect to " << host << ":" << port << ". "
- << quic::QuicErrorCodeToString(error) << " "
- << client->session()->error_details() << std::endl;
- return 1;
- }
- 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())
- << "Only set one of --body and --body_hex.";
- body = absl::HexStringToBytes(GetQuicFlag(FLAGS_body_hex));
- }
-
- // Construct a GET or POST request for supplied URL.
- spdy::Http2HeaderBlock header_block;
- header_block[":method"] = body.empty() ? "GET" : "POST";
- header_block[":scheme"] = url.scheme();
- header_block[":authority"] = url.HostPort();
- header_block[":path"] = url.PathParamsQuery();
-
- // Append any additional headers supplied on the command line.
- const std::string headers = GetQuicFlag(FLAGS_headers);
- for (absl::string_view sp : absl::StrSplit(headers, ';')) {
- QuicheTextUtils::RemoveLeadingAndTrailingWhitespace(&sp);
- if (sp.empty()) {
- continue;
- }
- std::vector<absl::string_view> kv =
- absl::StrSplit(sp, absl::MaxSplits(':', 1));
- QuicheTextUtils::RemoveLeadingAndTrailingWhitespace(&kv[0]);
- QuicheTextUtils::RemoveLeadingAndTrailingWhitespace(&kv[1]);
- header_block[kv[0]] = kv[1];
- }
-
- // Make sure to store the response, for later output.
- client->set_store_response(true);
-
- for (int i = 0; i < num_requests; ++i) {
- // Send the request.
- client->SendRequestAndWaitForResponse(header_block, body, /*fin=*/true);
-
- // Print request and response details.
- if (!GetQuicFlag(FLAGS_quiet)) {
- std::cout << "Request:" << std::endl;
- std::cout << "headers:" << header_block.DebugString();
- if (!GetQuicFlag(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)))
- << std::endl;
- } else {
- std::cout << "body: " << body << std::endl;
- }
- std::cout << std::endl;
-
- if (!client->preliminary_response_headers().empty()) {
- std::cout << "Preliminary response headers: "
- << client->preliminary_response_headers() << std::endl;
- std::cout << std::endl;
- }
-
- std::cout << "Response:" << std::endl;
- std::cout << "headers: " << client->latest_response_headers()
- << std::endl;
- std::string response_body = client->latest_response_body();
- if (!GetQuicFlag(FLAGS_body_hex).empty()) {
- // Assume response is binary data.
- std::cout << "body:\n"
- << QuicheTextUtils::HexDump(response_body) << std::endl;
- } else {
- std::cout << "body: " << response_body << std::endl;
- }
- std::cout << "trailers: " << client->latest_response_trailers()
- << std::endl;
- }
-
- if (!client->connected()) {
- std::cerr << "Request caused connection failure. Error: "
- << quic::QuicErrorCodeToString(client->session()->error())
- << std::endl;
- return 1;
- }
-
- int response_code = client->latest_response_code();
- 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)) {
- std::cout << "Request succeeded (redirect " << response_code << ")."
- << std::endl;
- } else {
- std::cout << "Request failed (redirect " << response_code << ")."
- << std::endl;
- return 1;
- }
- } else {
- std::cout << "Request failed (" << response_code << ")." << std::endl;
- return 1;
- }
-
- if (i + 1 < num_requests) { // There are more requests to perform.
- if (GetQuicFlag(FLAGS_one_connection_per_request)) {
- std::cout << "Disconnecting client between requests." << std::endl;
- client->Disconnect();
- if (!client->Initialize()) {
- std::cerr << "Failed to reinitialize client between requests."
- << std::endl;
- return 1;
- }
- if (!client->Connect()) {
- std::cerr << "Failed to reconnect client between requests."
- << std::endl;
- return 1;
- }
- } else if (!GetQuicFlag(FLAGS_disable_port_changes)) {
- // Change the ephemeral port.
- if (!client->ChangeEphemeralPort()) {
- std::cerr << "Failed to change ephemeral port." << std::endl;
- return 1;
- }
- }
- }
- }
-
- return 0;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/tools/quic_toy_client.h b/chromium/net/third_party/quiche/src/quic/tools/quic_toy_client.h
deleted file mode 100644
index 81b3733c46f..00000000000
--- a/chromium/net/third_party/quiche/src/quic/tools/quic_toy_client.h
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// A toy client, which connects to a specified port and sends QUIC
-// requests to that endpoint.
-
-#ifndef QUICHE_QUIC_TOOLS_QUIC_TOY_CLIENT_H_
-#define QUICHE_QUIC_TOOLS_QUIC_TOY_CLIENT_H_
-
-#include "quic/tools/quic_spdy_client_base.h"
-
-namespace quic {
-
-class QuicToyClient {
- public:
- class ClientFactory {
- public:
- virtual ~ClientFactory() = default;
-
- // Creates a new client configured to connect to |host_for_lookup:port|
- // supporting |versions|, using |host_for_handshake| for handshake and
- // |verifier| to verify proofs.
- virtual std::unique_ptr<QuicSpdyClientBase> CreateClient(
- std::string host_for_handshake,
- std::string host_for_lookup,
- // AF_INET, AF_INET6, or AF_UNSPEC(=don't care).
- int address_family_for_lookup,
- uint16_t port,
- ParsedQuicVersionVector versions,
- const QuicConfig& config,
- std::unique_ptr<ProofVerifier> verifier,
- std::unique_ptr<SessionCache> session_cache) = 0;
- };
-
- // Constructs a new toy client that will use |client_factory| to create the
- // actual QuicSpdyClientBase instance.
- QuicToyClient(ClientFactory* client_factory);
-
- // Connects to the QUIC server based on the various flags defined in the
- // .cc file, sends requests and prints the responses. Returns 0 on success
- // and non-zero otherwise.
- int SendRequestsAndPrintResponses(std::vector<std::string> urls);
-
- private:
- ClientFactory* client_factory_; // Unowned.
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_TOOLS_QUIC_TOY_CLIENT_H_
diff --git a/chromium/net/third_party/quiche/src/quic/tools/quic_toy_server.cc b/chromium/net/third_party/quiche/src/quic/tools/quic_toy_server.cc
deleted file mode 100644
index cdbe9b3bce9..00000000000
--- a/chromium/net/third_party/quiche/src/quic/tools/quic_toy_server.cc
+++ /dev/null
@@ -1,103 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/tools/quic_toy_server.h"
-
-#include <utility>
-#include <vector>
-
-#include "quic/core/quic_versions.h"
-#include "quic/platform/api/quic_default_proof_providers.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_socket_address.h"
-#include "quic/tools/quic_memory_cache_backend.h"
-#include "common/platform/api/quiche_command_line_flags.h"
-
-DEFINE_QUICHE_COMMAND_LINE_FLAG(int32_t, port, 6121,
- "The port the quic server will listen on.");
-
-DEFINE_QUICHE_COMMAND_LINE_FLAG(
- std::string, quic_response_cache_dir, "",
- "Specifies the directory used during QuicHttpResponseCache "
- "construction to seed the cache. Cache directory can be "
- "generated using `wget -p --save-headers <url>`");
-
-DEFINE_QUICHE_COMMAND_LINE_FLAG(
- bool, generate_dynamic_responses, false,
- "If true, then URLs which have a numeric path will send a dynamically "
- "generated response of that many bytes.");
-
-DEFINE_QUICHE_COMMAND_LINE_FLAG(bool, quic_ietf_draft, false,
- "Only enable IETF draft versions. This also "
- "enables required internal QUIC flags.");
-
-DEFINE_QUICHE_COMMAND_LINE_FLAG(
- std::string, quic_versions, "",
- "QUIC versions to enable, e.g. \"h3-25,h3-27\". If not set, then all "
- "available versions are enabled.");
-
-DEFINE_QUICHE_COMMAND_LINE_FLAG(bool, enable_webtransport, false,
- "If true, WebTransport support is enabled.");
-
-namespace quic {
-
-std::unique_ptr<quic::QuicSimpleServerBackend>
-QuicToyServer::MemoryCacheBackendFactory::CreateBackend() {
- auto memory_cache_backend = std::make_unique<QuicMemoryCacheBackend>();
- if (GetQuicFlag(FLAGS_generate_dynamic_responses)) {
- memory_cache_backend->GenerateDynamicResponses();
- }
- if (!GetQuicFlag(FLAGS_quic_response_cache_dir).empty()) {
- memory_cache_backend->InitializeBackend(
- GetQuicFlag(FLAGS_quic_response_cache_dir));
- }
- if (GetQuicFlag(FLAGS_enable_webtransport)) {
- memory_cache_backend->EnableWebTransport();
- }
- return memory_cache_backend;
-}
-
-QuicToyServer::QuicToyServer(BackendFactory* backend_factory,
- ServerFactory* server_factory)
- : backend_factory_(backend_factory), server_factory_(server_factory) {}
-
-int QuicToyServer::Start() {
- ParsedQuicVersionVector supported_versions;
- if (GetQuicFlag(FLAGS_quic_ietf_draft)) {
- QuicVersionInitializeSupportForIetfDraft();
- for (const ParsedQuicVersion& version : AllSupportedVersions()) {
- // Add all versions that supports IETF QUIC.
- if (version.HasIetfQuicFrames() &&
- version.handshake_protocol == quic::PROTOCOL_TLS1_3) {
- supported_versions.push_back(version);
- }
- }
- } else {
- supported_versions = AllSupportedVersions();
- }
- std::string versions_string = GetQuicFlag(FLAGS_quic_versions);
- if (!versions_string.empty()) {
- supported_versions = ParseQuicVersionVectorString(versions_string);
- }
- if (supported_versions.empty()) {
- return 1;
- }
- for (const auto& version : supported_versions) {
- QuicEnableVersion(version);
- }
- auto proof_source = quic::CreateDefaultProofSource();
- auto backend = backend_factory_->CreateBackend();
- auto server = server_factory_->CreateServer(
- backend.get(), std::move(proof_source), supported_versions);
-
- if (!server->CreateUDPSocketAndListen(quic::QuicSocketAddress(
- quic::QuicIpAddress::Any6(), GetQuicFlag(FLAGS_port)))) {
- return 1;
- }
-
- server->HandleEventsForever();
- return 0;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/tools/quic_toy_server.h b/chromium/net/third_party/quiche/src/quic/tools/quic_toy_server.h
deleted file mode 100644
index 94e28eed477..00000000000
--- a/chromium/net/third_party/quiche/src/quic/tools/quic_toy_server.h
+++ /dev/null
@@ -1,63 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TOOLS_QUIC_TOY_SERVER_H_
-#define QUICHE_QUIC_TOOLS_QUIC_TOY_SERVER_H_
-
-#include "quic/core/crypto/proof_source.h"
-#include "quic/tools/quic_simple_server_backend.h"
-#include "quic/tools/quic_spdy_server_base.h"
-
-namespace quic {
-
-// A binary wrapper for QuicServer. It listens forever on --port
-// (default 6121) until it's killed or ctrl-cd to death.
-class QuicToyServer {
- public:
- // A factory for creating QuicSpdyServerBase instances.
- class ServerFactory {
- public:
- virtual ~ServerFactory() = default;
-
- // Creates a QuicSpdyServerBase instance using |backend| for generating
- // responses, and |proof_source| for certificates.
- virtual std::unique_ptr<QuicSpdyServerBase> CreateServer(
- QuicSimpleServerBackend* backend,
- std::unique_ptr<ProofSource> proof_source,
- const ParsedQuicVersionVector& supported_versions) = 0;
- };
-
- // A facotry for creating QuicSimpleServerBackend instances.
- class BackendFactory {
- public:
- virtual ~BackendFactory() = default;
-
- // Creates a new backend.
- virtual std::unique_ptr<QuicSimpleServerBackend> CreateBackend() = 0;
- };
-
- // A factory for creating QuicMemoryCacheBackend instances, configured
- // to load files from disk, if necessary.
- class MemoryCacheBackendFactory : public BackendFactory {
- public:
- std::unique_ptr<quic::QuicSimpleServerBackend> CreateBackend() override;
- };
-
- // Constructs a new toy server that will use |server_factory| to create the
- // actual QuicSpdyServerBase instance.
- QuicToyServer(BackendFactory* backend_factory, ServerFactory* server_factory);
-
- // Connects to the QUIC server based on the various flags defined in the
- // .cc file, listends for requests and sends the responses. Returns 1 on
- // failure and does not return otherwise.
- int Start();
-
- private:
- BackendFactory* backend_factory_; // Unowned.
- ServerFactory* server_factory_; // Unowned.
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_TOOLS_QUIC_TOY_SERVER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/tools/quic_transport_simple_server_dispatcher.cc b/chromium/net/third_party/quiche/src/quic/tools/quic_transport_simple_server_dispatcher.cc
deleted file mode 100644
index b767434eda3..00000000000
--- a/chromium/net/third_party/quiche/src/quic/tools/quic_transport_simple_server_dispatcher.cc
+++ /dev/null
@@ -1,56 +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 "quic/tools/quic_transport_simple_server_dispatcher.h"
-
-#include <memory>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_connection.h"
-#include "quic/core/quic_dispatcher.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_versions.h"
-#include "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/quic/tools/quic_transport_simple_server_dispatcher.h b/chromium/net/third_party/quiche/src/quic/tools/quic_transport_simple_server_dispatcher.h
deleted file mode 100644
index d8761f60d86..00000000000
--- a/chromium/net/third_party/quiche/src/quic/tools/quic_transport_simple_server_dispatcher.h
+++ /dev/null
@@ -1,42 +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 "quic/core/quic_dispatcher.h"
-#include "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/quic/tools/quic_transport_simple_server_session.cc b/chromium/net/third_party/quiche/src/quic/tools/quic_transport_simple_server_session.cc
deleted file mode 100644
index bc7ef192860..00000000000
--- a/chromium/net/third_party/quiche/src/quic/tools/quic_transport_simple_server_session.cc
+++ /dev/null
@@ -1,177 +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 "quic/tools/quic_transport_simple_server_session.h"
-
-#include <memory>
-
-#include "url/gurl.h"
-#include "url/origin.h"
-#include "quic/core/quic_buffer_allocator.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_versions.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/quic_transport/quic_transport_protocol.h"
-#include "quic/quic_transport/quic_transport_stream.h"
-#include "quic/tools/web_transport_test_visitors.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;
- }
- QuicUniqueBufferPtr buffer = MakeUniqueBuffer(
- connection()->helper()->GetStreamSendBufferAllocator(), message.size());
- memcpy(buffer.get(), message.data(), message.size());
- datagram_queue()->SendOrQueueDatagram(
- QuicMemSlice(std::move(buffer), message.size()));
-}
-
-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/quic/tools/quic_transport_simple_server_session.h b/chromium/net/third_party/quiche/src/quic/tools/quic_transport_simple_server_session.h
deleted file mode 100644
index a51eab66952..00000000000
--- a/chromium/net/third_party/quiche/src/quic/tools/quic_transport_simple_server_session.h
+++ /dev/null
@@ -1,81 +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 "quic/core/quic_types.h"
-#include "quic/core/quic_versions.h"
-#include "quic/platform/api/quic_containers.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/quic_transport/quic_transport_server_session.h"
-#include "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/quic/tools/quic_url.cc b/chromium/net/third_party/quiche/src/quic/tools/quic_url.cc
deleted file mode 100644
index 53b9ab0ab60..00000000000
--- a/chromium/net/third_party/quiche/src/quic/tools/quic_url.cc
+++ /dev/null
@@ -1,101 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/tools/quic_url.h"
-
-#include "absl/strings/str_cat.h"
-#include "absl/strings/string_view.h"
-
-namespace quic {
-
-static constexpr size_t kMaxHostNameLength = 256;
-
-QuicUrl::QuicUrl(absl::string_view url) : url_(static_cast<std::string>(url)) {}
-
-QuicUrl::QuicUrl(absl::string_view url, absl::string_view default_scheme)
- : QuicUrl(url) {
- if (url_.has_scheme()) {
- return;
- }
-
- url_ = GURL(absl::StrCat(default_scheme, "://", url));
-}
-
-std::string QuicUrl::ToString() const {
- if (IsValid()) {
- return url_.spec();
- }
- return "";
-}
-
-bool QuicUrl::IsValid() const {
- if (!url_.is_valid() || !url_.has_scheme()) {
- return false;
- }
-
- if (url_.has_host() && url_.host().length() > kMaxHostNameLength) {
- return false;
- }
-
- return true;
-}
-
-std::string QuicUrl::HostPort() const {
- if (!IsValid() || !url_.has_host()) {
- return "";
- }
-
- std::string host = url_.host();
- int port = url_.IntPort();
- if (port == url::PORT_UNSPECIFIED) {
- return host;
- }
- return absl::StrCat(host, ":", port);
-}
-
-std::string QuicUrl::PathParamsQuery() const {
- if (!IsValid() || !url_.has_path()) {
- return "/";
- }
-
- return url_.PathForRequest();
-}
-
-std::string QuicUrl::scheme() const {
- if (!IsValid()) {
- return "";
- }
-
- return url_.scheme();
-}
-
-std::string QuicUrl::host() const {
- if (!IsValid()) {
- return "";
- }
-
- return url_.HostNoBrackets();
-}
-
-std::string QuicUrl::path() const {
- if (!IsValid()) {
- return "";
- }
-
- return url_.path();
-}
-
-uint16_t QuicUrl::port() const {
- if (!IsValid()) {
- return 0;
- }
-
- int port = url_.EffectiveIntPort();
- if (port == url::PORT_UNSPECIFIED) {
- return 0;
- }
- return port;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/tools/quic_url.h b/chromium/net/third_party/quiche/src/quic/tools/quic_url.h
deleted file mode 100644
index bc2ec99cd24..00000000000
--- a/chromium/net/third_party/quiche/src/quic/tools/quic_url.h
+++ /dev/null
@@ -1,61 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TOOLS_QUIC_URL_H_
-#define QUICHE_QUIC_TOOLS_QUIC_URL_H_
-
-#include <string>
-
-#include "absl/strings/string_view.h"
-#include "url/gurl.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// A utility class that wraps GURL.
-class QuicUrl {
- public:
- // Constructs an empty QuicUrl.
- QuicUrl() = default;
-
- // Constructs a QuicUrl from the url string |url|.
- //
- // NOTE: If |url| doesn't have a scheme, it will have an empty scheme
- // field. If that's not what you want, use the QuicUrlImpl(url,
- // default_scheme) form below.
- explicit QuicUrl(absl::string_view url);
-
- // Constructs a QuicUrlImpl from |url|, assuming that the scheme for the URL
- // is |default_scheme| if there is no scheme specified in |url|.
- QuicUrl(absl::string_view url, absl::string_view default_scheme);
-
- // Returns false if the URL is not valid.
- bool IsValid() const;
-
- // Returns full text of the QuicUrl if it is valid. Return empty string
- // otherwise.
- std::string ToString() const;
-
- // Returns host:port.
- // If the host is empty, it will return an empty string.
- // If the host is an IPv6 address, it will be bracketed.
- // If port is not present or is equal to default_port of scheme (e.g., port
- // 80 for HTTP), it won't be returned.
- std::string HostPort() const;
-
- // Returns a string assembles path, parameters and query.
- std::string PathParamsQuery() const;
-
- std::string scheme() const;
- std::string host() const;
- std::string path() const;
- uint16_t port() const;
-
- private:
- GURL url_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_TOOLS_QUIC_URL_H_
diff --git a/chromium/net/third_party/quiche/src/quic/tools/quic_url_test.cc b/chromium/net/third_party/quiche/src/quic/tools/quic_url_test.cc
deleted file mode 100644
index ccb7aea0ebd..00000000000
--- a/chromium/net/third_party/quiche/src/quic/tools/quic_url_test.cc
+++ /dev/null
@@ -1,156 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/tools/quic_url.h"
-
-#include <string>
-
-#include "quic/platform/api/quic_test.h"
-
-namespace quic {
-namespace test {
-namespace {
-
-class QuicUrlTest : public QuicTest {};
-
-TEST_F(QuicUrlTest, Basic) {
- // No scheme specified.
- std::string url_str = "www.example.com";
- QuicUrl url(url_str);
- EXPECT_FALSE(url.IsValid());
-
- // scheme is HTTP.
- url_str = "http://www.example.com";
- url = QuicUrl(url_str);
- EXPECT_TRUE(url.IsValid());
- EXPECT_EQ("http://www.example.com/", url.ToString());
- EXPECT_EQ("http", url.scheme());
- EXPECT_EQ("www.example.com", url.HostPort());
- EXPECT_EQ("/", url.PathParamsQuery());
- EXPECT_EQ(80u, url.port());
-
- // scheme is HTTPS.
- url_str = "https://www.example.com:12345/path/to/resource?a=1&campaign=2";
- url = QuicUrl(url_str);
- EXPECT_TRUE(url.IsValid());
- EXPECT_EQ("https://www.example.com:12345/path/to/resource?a=1&campaign=2",
- url.ToString());
- EXPECT_EQ("https", url.scheme());
- EXPECT_EQ("www.example.com:12345", url.HostPort());
- EXPECT_EQ("/path/to/resource?a=1&campaign=2", url.PathParamsQuery());
- EXPECT_EQ(12345u, url.port());
-
- // scheme is FTP.
- url_str = "ftp://www.example.com";
- url = QuicUrl(url_str);
- EXPECT_TRUE(url.IsValid());
- EXPECT_EQ("ftp://www.example.com/", url.ToString());
- EXPECT_EQ("ftp", url.scheme());
- EXPECT_EQ("www.example.com", url.HostPort());
- EXPECT_EQ("/", url.PathParamsQuery());
- EXPECT_EQ(21u, url.port());
-}
-
-TEST_F(QuicUrlTest, DefaultScheme) {
- // Default scheme to HTTP.
- std::string url_str = "www.example.com";
- QuicUrl url(url_str, "http");
- EXPECT_EQ("http://www.example.com/", url.ToString());
- EXPECT_EQ("http", url.scheme());
-
- // URL already has a scheme specified.
- url_str = "http://www.example.com";
- url = QuicUrl(url_str, "https");
- EXPECT_EQ("http://www.example.com/", url.ToString());
- EXPECT_EQ("http", url.scheme());
-
- // Default scheme to FTP.
- url_str = "www.example.com";
- url = QuicUrl(url_str, "ftp");
- EXPECT_EQ("ftp://www.example.com/", url.ToString());
- EXPECT_EQ("ftp", url.scheme());
-}
-
-TEST_F(QuicUrlTest, IsValid) {
- std::string url_str =
- "ftp://www.example.com:12345/path/to/resource?a=1&campaign=2";
- EXPECT_TRUE(QuicUrl(url_str).IsValid());
-
- // Invalid characters in host name.
- url_str = "https://www%.example.com:12345/path/to/resource?a=1&campaign=2";
- EXPECT_FALSE(QuicUrl(url_str).IsValid());
-
- // Invalid characters in scheme.
- url_str = "%http://www.example.com:12345/path/to/resource?a=1&campaign=2";
- EXPECT_FALSE(QuicUrl(url_str).IsValid());
-
- // Host name too long.
- std::string host(1024, 'a');
- url_str = "https://" + host;
- EXPECT_FALSE(QuicUrl(url_str).IsValid());
-
- // Invalid port number.
- url_str = "https://www..example.com:123456/path/to/resource?a=1&campaign=2";
- EXPECT_FALSE(QuicUrl(url_str).IsValid());
-}
-
-TEST_F(QuicUrlTest, HostPort) {
- std::string url_str = "http://www.example.com/";
- QuicUrl url(url_str);
- EXPECT_EQ("www.example.com", url.HostPort());
- EXPECT_EQ("www.example.com", url.host());
- EXPECT_EQ(80u, url.port());
-
- url_str = "http://www.example.com:80/";
- url = QuicUrl(url_str);
- EXPECT_EQ("www.example.com", url.HostPort());
- EXPECT_EQ("www.example.com", url.host());
- EXPECT_EQ(80u, url.port());
-
- url_str = "http://www.example.com:81/";
- url = QuicUrl(url_str);
- EXPECT_EQ("www.example.com:81", url.HostPort());
- EXPECT_EQ("www.example.com", url.host());
- EXPECT_EQ(81u, url.port());
-
- url_str = "https://192.168.1.1:443/";
- url = QuicUrl(url_str);
- EXPECT_EQ("192.168.1.1", url.HostPort());
- EXPECT_EQ("192.168.1.1", url.host());
- EXPECT_EQ(443u, url.port());
-
- url_str = "http://[2001::1]:80/";
- url = QuicUrl(url_str);
- EXPECT_EQ("[2001::1]", url.HostPort());
- EXPECT_EQ("2001::1", url.host());
- EXPECT_EQ(80u, url.port());
-
- url_str = "http://[2001::1]:81/";
- url = QuicUrl(url_str);
- EXPECT_EQ("[2001::1]:81", url.HostPort());
- EXPECT_EQ("2001::1", url.host());
- EXPECT_EQ(81u, url.port());
-}
-
-TEST_F(QuicUrlTest, PathParamsQuery) {
- std::string url_str =
- "https://www.example.com:12345/path/to/resource?a=1&campaign=2";
- QuicUrl url(url_str);
- EXPECT_EQ("/path/to/resource?a=1&campaign=2", url.PathParamsQuery());
- EXPECT_EQ("/path/to/resource", url.path());
-
- url_str = "https://www.example.com/?";
- url = QuicUrl(url_str);
- EXPECT_EQ("/?", url.PathParamsQuery());
- EXPECT_EQ("/", url.path());
-
- url_str = "https://www.example.com/";
- url = QuicUrl(url_str);
- EXPECT_EQ("/", url.PathParamsQuery());
- EXPECT_EQ("/", url.path());
-}
-
-} // namespace
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/tools/simple_ticket_crypter.cc b/chromium/net/third_party/quiche/src/quic/tools/simple_ticket_crypter.cc
deleted file mode 100644
index 149adda20ff..00000000000
--- a/chromium/net/third_party/quiche/src/quic/tools/simple_ticket_crypter.cc
+++ /dev/null
@@ -1,112 +0,0 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/tools/simple_ticket_crypter.h"
-
-#include "third_party/boringssl/src/include/openssl/aead.h"
-#include "third_party/boringssl/src/include/openssl/rand.h"
-
-namespace quic {
-
-namespace {
-
-constexpr QuicTime::Delta kTicketKeyLifetime =
- QuicTime::Delta::FromSeconds(60 * 60 * 24 * 7);
-
-// The format of an encrypted ticket is 1 byte for the key epoch, followed by
-// 16 bytes of IV, followed by the output from the AES-GCM Seal operation. The
-// seal operation has an overhead of 16 bytes for its auth tag.
-constexpr size_t kEpochSize = 1;
-constexpr size_t kIVSize = 16;
-constexpr size_t kAuthTagSize = 16;
-
-// Offsets into the ciphertext to make message parsing easier.
-constexpr size_t kIVOffset = kEpochSize;
-constexpr size_t kMessageOffset = kIVOffset + kIVSize;
-
-} // namespace
-
-SimpleTicketCrypter::SimpleTicketCrypter(QuicClock* clock) : clock_(clock) {
- RAND_bytes(&key_epoch_, 1);
- current_key_ = NewKey();
-}
-
-SimpleTicketCrypter::~SimpleTicketCrypter() = default;
-
-size_t SimpleTicketCrypter::MaxOverhead() {
- return kEpochSize + kIVSize + kAuthTagSize;
-}
-
-std::vector<uint8_t> SimpleTicketCrypter::Encrypt(
- absl::string_view in, absl::string_view encryption_key) {
- // This class is only used in Chromium, in which the |encryption_key| argument
- // will never be populated and an internally-cached key should be used for
- // encrypting tickets.
- QUICHE_DCHECK(encryption_key.empty());
- MaybeRotateKeys();
- std::vector<uint8_t> out(in.size() + MaxOverhead());
- out[0] = key_epoch_;
- RAND_bytes(out.data() + kIVOffset, kIVSize);
- size_t out_len;
- const EVP_AEAD_CTX* ctx = current_key_->aead_ctx.get();
- if (!EVP_AEAD_CTX_seal(ctx, out.data() + kMessageOffset, &out_len,
- out.size() - kMessageOffset, out.data() + kIVOffset,
- kIVSize, reinterpret_cast<const uint8_t*>(in.data()),
- in.size(), nullptr, 0)) {
- return std::vector<uint8_t>();
- }
- out.resize(out_len + kMessageOffset);
- return out;
-}
-
-std::vector<uint8_t> SimpleTicketCrypter::Decrypt(absl::string_view in) {
- MaybeRotateKeys();
- if (in.size() < kMessageOffset) {
- return std::vector<uint8_t>();
- }
- const uint8_t* input = reinterpret_cast<const uint8_t*>(in.data());
- std::vector<uint8_t> out(in.size() - kMessageOffset);
- size_t out_len;
- const EVP_AEAD_CTX* ctx = current_key_->aead_ctx.get();
- if (input[0] != key_epoch_) {
- if (input[0] == static_cast<uint8_t>(key_epoch_ - 1) && previous_key_) {
- ctx = previous_key_->aead_ctx.get();
- } else {
- return std::vector<uint8_t>();
- }
- }
- if (!EVP_AEAD_CTX_open(ctx, out.data(), &out_len, out.size(),
- input + kIVOffset, kIVSize, input + kMessageOffset,
- in.size() - kMessageOffset, nullptr, 0)) {
- return std::vector<uint8_t>();
- }
- out.resize(out_len);
- return out;
-}
-
-void SimpleTicketCrypter::Decrypt(
- absl::string_view in,
- std::unique_ptr<quic::ProofSource::DecryptCallback> callback) {
- callback->Run(Decrypt(in));
-}
-
-void SimpleTicketCrypter::MaybeRotateKeys() {
- QuicTime now = clock_->ApproximateNow();
- if (current_key_->expiration < now) {
- previous_key_ = std::move(current_key_);
- current_key_ = NewKey();
- key_epoch_++;
- }
-}
-
-std::unique_ptr<SimpleTicketCrypter::Key> SimpleTicketCrypter::NewKey() {
- auto key = std::make_unique<SimpleTicketCrypter::Key>();
- RAND_bytes(key->key, kKeySize);
- EVP_AEAD_CTX_init(key->aead_ctx.get(), EVP_aead_aes_128_gcm(), key->key,
- kKeySize, EVP_AEAD_DEFAULT_TAG_LENGTH, nullptr);
- key->expiration = clock_->ApproximateNow() + kTicketKeyLifetime;
- return key;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/tools/simple_ticket_crypter.h b/chromium/net/third_party/quiche/src/quic/tools/simple_ticket_crypter.h
deleted file mode 100644
index 052bc5872a3..00000000000
--- a/chromium/net/third_party/quiche/src/quic/tools/simple_ticket_crypter.h
+++ /dev/null
@@ -1,56 +0,0 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TOOLS_SIMPLE_TICKET_CRYPTER_H_
-#define QUICHE_QUIC_TOOLS_SIMPLE_TICKET_CRYPTER_H_
-
-#include "third_party/boringssl/src/include/openssl/aead.h"
-#include "quic/core/crypto/proof_source.h"
-#include "quic/core/quic_clock.h"
-#include "quic/core/quic_time.h"
-
-namespace quic {
-
-// SimpleTicketCrypter implements the QUIC ProofSource::TicketCrypter interface.
-// It generates a random key at startup and every 7 days it rotates the key,
-// keeping track of the previous key used to facilitate decrypting older
-// tickets. This implementation is not suitable for server setups where multiple
-// servers need to share keys.
-class QUIC_NO_EXPORT SimpleTicketCrypter
- : public quic::ProofSource::TicketCrypter {
- public:
- explicit SimpleTicketCrypter(QuicClock* clock);
- ~SimpleTicketCrypter() override;
-
- size_t MaxOverhead() override;
- std::vector<uint8_t> Encrypt(absl::string_view in,
- absl::string_view encryption_key) override;
- void Decrypt(
- absl::string_view in,
- std::unique_ptr<quic::ProofSource::DecryptCallback> callback) override;
-
- private:
- std::vector<uint8_t> Decrypt(absl::string_view in);
-
- void MaybeRotateKeys();
-
- static constexpr size_t kKeySize = 16;
-
- struct Key {
- uint8_t key[kKeySize];
- bssl::ScopedEVP_AEAD_CTX aead_ctx;
- QuicTime expiration = QuicTime::Zero();
- };
-
- std::unique_ptr<Key> NewKey();
-
- std::unique_ptr<Key> current_key_;
- std::unique_ptr<Key> previous_key_;
- uint8_t key_epoch_ = 0;
- QuicClock* clock_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_TOOLS_SIMPLE_TICKET_CRYPTER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/tools/simple_ticket_crypter_test.cc b/chromium/net/third_party/quiche/src/quic/tools/simple_ticket_crypter_test.cc
deleted file mode 100644
index be71018de23..00000000000
--- a/chromium/net/third_party/quiche/src/quic/tools/simple_ticket_crypter_test.cc
+++ /dev/null
@@ -1,111 +0,0 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/tools/simple_ticket_crypter.h"
-
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/mock_clock.h"
-
-namespace quic {
-namespace test {
-
-namespace {
-
-constexpr QuicTime::Delta kOneDay = QuicTime::Delta::FromSeconds(60 * 60 * 24);
-
-} // namespace
-
-class DecryptCallback : public quic::ProofSource::DecryptCallback {
- public:
- explicit DecryptCallback(std::vector<uint8_t>* out) : out_(out) {}
-
- void Run(std::vector<uint8_t> plaintext) override { *out_ = plaintext; }
-
- private:
- std::vector<uint8_t>* out_;
-};
-
-absl::string_view StringPiece(const std::vector<uint8_t>& in) {
- return absl::string_view(reinterpret_cast<const char*>(in.data()), in.size());
-}
-
-class SimpleTicketCrypterTest : public QuicTest {
- public:
- SimpleTicketCrypterTest() : ticket_crypter_(&mock_clock_) {}
-
- protected:
- MockClock mock_clock_;
- SimpleTicketCrypter ticket_crypter_;
-};
-
-TEST_F(SimpleTicketCrypterTest, EncryptDecrypt) {
- std::vector<uint8_t> plaintext = {1, 2, 3, 4, 5};
- std::vector<uint8_t> ciphertext =
- ticket_crypter_.Encrypt(StringPiece(plaintext), {});
- EXPECT_NE(plaintext, ciphertext);
-
- std::vector<uint8_t> out_plaintext;
- ticket_crypter_.Decrypt(StringPiece(ciphertext),
- std::make_unique<DecryptCallback>(&out_plaintext));
- EXPECT_EQ(out_plaintext, plaintext);
-}
-
-TEST_F(SimpleTicketCrypterTest, CiphertextsDiffer) {
- std::vector<uint8_t> plaintext = {1, 2, 3, 4, 5};
- std::vector<uint8_t> ciphertext1 =
- ticket_crypter_.Encrypt(StringPiece(plaintext), {});
- std::vector<uint8_t> ciphertext2 =
- ticket_crypter_.Encrypt(StringPiece(plaintext), {});
- EXPECT_NE(ciphertext1, ciphertext2);
-}
-
-TEST_F(SimpleTicketCrypterTest, DecryptionFailureWithModifiedCiphertext) {
- std::vector<uint8_t> plaintext = {1, 2, 3, 4, 5};
- std::vector<uint8_t> ciphertext =
- ticket_crypter_.Encrypt(StringPiece(plaintext), {});
- EXPECT_NE(plaintext, ciphertext);
-
- // Check that a bit flip in any byte will cause a decryption failure.
- for (size_t i = 0; i < ciphertext.size(); i++) {
- SCOPED_TRACE(i);
- std::vector<uint8_t> munged_ciphertext = ciphertext;
- munged_ciphertext[i] ^= 1;
- std::vector<uint8_t> out_plaintext;
- ticket_crypter_.Decrypt(StringPiece(munged_ciphertext),
- std::make_unique<DecryptCallback>(&out_plaintext));
- EXPECT_TRUE(out_plaintext.empty());
- }
-}
-
-TEST_F(SimpleTicketCrypterTest, DecryptionFailureWithEmptyCiphertext) {
- std::vector<uint8_t> out_plaintext;
- ticket_crypter_.Decrypt(absl::string_view(),
- std::make_unique<DecryptCallback>(&out_plaintext));
- EXPECT_TRUE(out_plaintext.empty());
-}
-
-TEST_F(SimpleTicketCrypterTest, KeyRotation) {
- std::vector<uint8_t> plaintext = {1, 2, 3};
- std::vector<uint8_t> ciphertext =
- ticket_crypter_.Encrypt(StringPiece(plaintext), {});
- EXPECT_FALSE(ciphertext.empty());
-
- // Advance the clock 8 days, so the key used for |ciphertext| is now the
- // previous key. Check that decryption still works.
- mock_clock_.AdvanceTime(kOneDay * 8);
- std::vector<uint8_t> out_plaintext;
- ticket_crypter_.Decrypt(StringPiece(ciphertext),
- std::make_unique<DecryptCallback>(&out_plaintext));
- EXPECT_EQ(out_plaintext, plaintext);
-
- // Advance the clock 8 more days. Now the original key should be expired and
- // decryption should fail.
- mock_clock_.AdvanceTime(kOneDay * 8);
- ticket_crypter_.Decrypt(StringPiece(ciphertext),
- std::make_unique<DecryptCallback>(&out_plaintext));
- EXPECT_TRUE(out_plaintext.empty());
-}
-
-} // namespace test
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/tools/web_transport_test_visitors.h b/chromium/net/third_party/quiche/src/quic/tools/web_transport_test_visitors.h
deleted file mode 100644
index b1f22469e12..00000000000
--- a/chromium/net/third_party/quiche/src/quic/tools/web_transport_test_visitors.h
+++ /dev/null
@@ -1,263 +0,0 @@
-// Copyright (c) 2021 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_WEB_TRANSPORT_TEST_VISITORS_H_
-#define QUICHE_QUIC_TOOLS_WEB_TRANSPORT_TEST_VISITORS_H_
-
-#include <string>
-
-#include "quic/core/quic_simple_buffer_allocator.h"
-#include "quic/core/web_transport_interface.h"
-#include "quic/platform/api/quic_logging.h"
-#include "common/quiche_circular_deque.h"
-
-namespace quic {
-
-// Discards any incoming data.
-class WebTransportDiscardVisitor : public WebTransportStreamVisitor {
- public:
- WebTransportDiscardVisitor(WebTransportStream* stream) : stream_(stream) {}
-
- void OnCanRead() override {
- std::string buffer;
- WebTransportStream::ReadResult result = stream_->Read(&buffer);
- QUIC_DVLOG(2) << "Read " << result.bytes_read
- << " bytes from WebTransport stream "
- << stream_->GetStreamId() << ", fin: " << result.fin;
- }
-
- void OnCanWrite() override {}
-
- void OnResetStreamReceived(WebTransportStreamError /*error*/) override {}
- void OnStopSendingReceived(WebTransportStreamError /*error*/) override {}
- void OnWriteSideInDataRecvdState() override {}
-
- private:
- WebTransportStream* stream_;
-};
-
-// Echoes any incoming data back on the same stream.
-class WebTransportBidirectionalEchoVisitor : public WebTransportStreamVisitor {
- public:
- WebTransportBidirectionalEchoVisitor(WebTransportStream* stream)
- : stream_(stream) {}
-
- void OnCanRead() override {
- WebTransportStream::ReadResult result = stream_->Read(&buffer_);
- QUIC_DVLOG(1) << "Attempted reading on WebTransport bidirectional stream "
- << stream_->GetStreamId()
- << ", bytes read: " << result.bytes_read;
- if (result.fin) {
- send_fin_ = true;
- }
- OnCanWrite();
- }
-
- void OnCanWrite() override {
- if (stop_sending_received_) {
- return;
- }
-
- if (!buffer_.empty()) {
- bool success = stream_->Write(buffer_);
- QUIC_DVLOG(1) << "Attempted writing on WebTransport bidirectional stream "
- << stream_->GetStreamId()
- << ", success: " << (success ? "yes" : "no");
- if (!success) {
- return;
- }
-
- buffer_ = "";
- }
-
- if (send_fin_) {
- bool success = stream_->SendFin();
- QUICHE_DCHECK(success);
- }
- }
-
- void OnResetStreamReceived(WebTransportStreamError /*error*/) override {
- // Send FIN in response to a stream reset. We want to test that we can
- // operate one side of the stream cleanly while the other is reset, thus
- // replying with a FIN rather than a RESET_STREAM is more appropriate here.
- send_fin_ = true;
- OnCanWrite();
- }
- void OnStopSendingReceived(WebTransportStreamError /*error*/) override {
- stop_sending_received_ = true;
- }
- void OnWriteSideInDataRecvdState() override {}
-
- protected:
- WebTransportStream* stream() { return stream_; }
-
- private:
- WebTransportStream* stream_;
- std::string buffer_;
- bool send_fin_ = false;
- bool stop_sending_received_ = false;
-};
-
-// Buffers all of the data and calls |callback| with the entirety of the stream
-// data.
-class WebTransportUnidirectionalEchoReadVisitor
- : public WebTransportStreamVisitor {
- public:
- using Callback = std::function<void(const std::string&)>;
-
- WebTransportUnidirectionalEchoReadVisitor(WebTransportStream* stream,
- Callback callback)
- : stream_(stream), callback_(std::move(callback)) {}
-
- void OnCanRead() override {
- WebTransportStream::ReadResult result = stream_->Read(&buffer_);
- QUIC_DVLOG(1) << "Attempted reading on WebTransport unidirectional stream "
- << stream_->GetStreamId()
- << ", bytes read: " << result.bytes_read;
- if (result.fin) {
- QUIC_DVLOG(1) << "Finished receiving data on a WebTransport stream "
- << stream_->GetStreamId() << ", queueing up the echo";
- callback_(buffer_);
- }
- }
-
- void OnCanWrite() override { QUIC_NOTREACHED(); }
-
- void OnResetStreamReceived(WebTransportStreamError /*error*/) override {}
- void OnStopSendingReceived(WebTransportStreamError /*error*/) override {}
- void OnWriteSideInDataRecvdState() override {}
-
- private:
- WebTransportStream* stream_;
- std::string buffer_;
- Callback callback_;
-};
-
-// Sends supplied data.
-class WebTransportUnidirectionalEchoWriteVisitor
- : public WebTransportStreamVisitor {
- public:
- WebTransportUnidirectionalEchoWriteVisitor(WebTransportStream* stream,
- const std::string& data)
- : stream_(stream), data_(data) {}
-
- void OnCanRead() override { QUIC_NOTREACHED(); }
- void OnCanWrite() override {
- if (data_.empty()) {
- return;
- }
- if (!stream_->Write(data_)) {
- return;
- }
- data_ = "";
- bool fin_sent = stream_->SendFin();
- QUICHE_DVLOG(1)
- << "WebTransportUnidirectionalEchoWriteVisitor finished sending data.";
- QUICHE_DCHECK(fin_sent);
- }
-
- void OnResetStreamReceived(WebTransportStreamError /*error*/) override {}
- void OnStopSendingReceived(WebTransportStreamError /*error*/) override {}
- void OnWriteSideInDataRecvdState() override {}
-
- private:
- WebTransportStream* stream_;
- std::string data_;
-};
-
-// A session visitor which sets unidirectional or bidirectional stream visitors
-// to echo.
-class EchoWebTransportSessionVisitor : public WebTransportVisitor {
- public:
- EchoWebTransportSessionVisitor(WebTransportSession* session)
- : session_(session) {}
-
- void OnSessionReady(const spdy::SpdyHeaderBlock&) override {
- if (session_->CanOpenNextOutgoingBidirectionalStream()) {
- OnCanCreateNewOutgoingBidirectionalStream();
- }
- }
-
- void OnSessionClosed(WebTransportSessionError /*error_code*/,
- const std::string& /*error_message*/) override {}
-
- void OnIncomingBidirectionalStreamAvailable() override {
- while (true) {
- WebTransportStream* stream =
- session_->AcceptIncomingBidirectionalStream();
- if (stream == nullptr) {
- return;
- }
- QUIC_DVLOG(1)
- << "EchoWebTransportSessionVisitor received a bidirectional stream "
- << stream->GetStreamId();
- stream->SetVisitor(
- std::make_unique<WebTransportBidirectionalEchoVisitor>(stream));
- stream->visitor()->OnCanRead();
- }
- }
-
- void OnIncomingUnidirectionalStreamAvailable() override {
- while (true) {
- WebTransportStream* stream =
- session_->AcceptIncomingUnidirectionalStream();
- if (stream == nullptr) {
- return;
- }
- QUIC_DVLOG(1)
- << "EchoWebTransportSessionVisitor received a unidirectional stream";
- stream->SetVisitor(
- std::make_unique<WebTransportUnidirectionalEchoReadVisitor>(
- stream, [this](const std::string& data) {
- streams_to_echo_back_.push_back(data);
- TrySendingUnidirectionalStreams();
- }));
- stream->visitor()->OnCanRead();
- }
- }
-
- void OnDatagramReceived(absl::string_view datagram) override {
- auto buffer = MakeUniqueBuffer(&allocator_, datagram.size());
- memcpy(buffer.get(), datagram.data(), datagram.size());
- QuicMemSlice slice(std::move(buffer), datagram.size());
- session_->SendOrQueueDatagram(std::move(slice));
- }
-
- void OnCanCreateNewOutgoingBidirectionalStream() override {
- if (!echo_stream_opened_) {
- WebTransportStream* stream = session_->OpenOutgoingBidirectionalStream();
- stream->SetVisitor(
- std::make_unique<WebTransportBidirectionalEchoVisitor>(stream));
- echo_stream_opened_ = true;
- }
- }
- void OnCanCreateNewOutgoingUnidirectionalStream() override {
- TrySendingUnidirectionalStreams();
- }
-
- void TrySendingUnidirectionalStreams() {
- while (!streams_to_echo_back_.empty() &&
- session_->CanOpenNextOutgoingUnidirectionalStream()) {
- QUIC_DVLOG(1)
- << "EchoWebTransportServer echoed a unidirectional stream back";
- WebTransportStream* stream = session_->OpenOutgoingUnidirectionalStream();
- stream->SetVisitor(
- std::make_unique<WebTransportUnidirectionalEchoWriteVisitor>(
- stream, streams_to_echo_back_.front()));
- streams_to_echo_back_.pop_front();
- stream->visitor()->OnCanWrite();
- }
- }
-
- private:
- WebTransportSession* session_;
- SimpleBufferAllocator allocator_;
- bool echo_stream_opened_ = false;
-
- quiche::QuicheCircularDeque<std::string> streams_to_echo_back_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_TOOLS_WEB_TRANSPORT_TEST_VISITORS_H_